diff --git a/.codespell/exclude-file.txt b/.codespell/exclude-file.txt index 08e1a2b9059..7e6bad4bf0b 100644 --- a/.codespell/exclude-file.txt +++ b/.codespell/exclude-file.txt @@ -8,3 +8,4 @@ i1Qb$TE"rl ZEN = "the zen of python beautiful is better than ugly explicit is better than implicit simple is better than complex complex is better than complicated flat is better than nested sparse is better than dense readability counts special cases arent special enough to break the rules although practicality beats purity errors should never pass silently unless explicitly silenced in the face of ambiguity refuse the temptation to guess there should be one and preferably only one obvious way to do it although that way may not be obvious at first unless youre dutch now is better than never although never is often better than right now if the implementation is hard to explain its a bad idea if the implementation is easy to explain it may be a good idea namespaces are one honking great idea lets do more of those" "arent", "youre", +USB_MANUFACTURER = "Wee Noise Makers" diff --git a/.codespell/ignore-words.txt b/.codespell/ignore-words.txt index fc8feaca978..48bee0f30ba 100644 --- a/.codespell/ignore-words.txt +++ b/.codespell/ignore-words.txt @@ -26,3 +26,4 @@ ftbfs straightaway ftbs ftb +curren diff --git a/.devcontainer/common_tools.sh b/.devcontainer/common_tools.sh index 14cf76c3fe2..1231b8e4f4b 100755 --- a/.devcontainer/common_tools.sh +++ b/.devcontainer/common_tools.sh @@ -9,12 +9,19 @@ # ----------------------------------------------------------------------------- REPO_ROOT="/workspaces/circuitpython" +CMAKE_VERSION="3.31.12" echo -e "[common_tools.sh] starting install" cd "$REPO_ROOT" # --- repositories and tools ------------------------------------------------ +echo -e "[common_tools.sh] installing CMAKE $CMAKE_VERSION" +wget -q https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/cmake-$CMAKE_VERSION-linux-$(arch).sh +chmod +x cmake-$CMAKE_VERSION-linux-$(arch).sh +sudo ./cmake-$CMAKE_VERSION-linux-$(arch).sh --prefix=/usr/local --skip-license +rm cmake-$CMAKE_VERSION-linux-$(arch).sh + echo -e "[common_tools.sh] adding pybricks/ppa" sudo add-apt-repository -y ppa:pybricks/ppa echo -e "[common_tools.sh] installing uncrustify and mtools" diff --git a/.devcontainer/cortex-m-toolchain.sh b/.devcontainer/cortex-m-toolchain.sh index de1ccde6274..56be006544f 100755 --- a/.devcontainer/cortex-m-toolchain.sh +++ b/.devcontainer/cortex-m-toolchain.sh @@ -14,10 +14,10 @@ echo -e "[cortex-m-toolchain.sh] downloading and installing gcc-arm-non-eabi too cd /workspaces wget -qO gcc-arm-none-eabi.tar.xz \ - https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-eabi.tar.xz + https://developer.arm.com/-/media/Files/downloads/gnu/15.2.rel1/binrel/arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi.tar.xz tar -xJf gcc-arm-none-eabi.tar.xz -ln -s arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi gcc-arm-none-eabi +ln -s arm-gnu-toolchain-15.2.rel1-x86_64-arm-none-eabi gcc-arm-none-eabi rm -f gcc-arm-none-eabi.tar.xz echo -e "[cortex-m-toolchain.sh] update PATH in environment" diff --git a/.gitattributes b/.gitattributes index 38bba729fc1..d226cebf5d8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -27,4 +27,5 @@ # These should also not be modified by git. tests/basics/string_cr_conversion.py -text tests/basics/string_crlf_conversion.py -text +tests/micropython/test_normalize_newlines.py.exp -text # CIRCUITPY-CHANGE: remove non-CircuitPython tests diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index c81bf63123d..8617ce3f03f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,5 +1,5 @@ name: 🐞 Bug Report -description: Create a bug report to help us improve +description: Create a bug report to help us improve CircuitPython labels: - bug body: @@ -7,14 +7,14 @@ body: attributes: value: >- Thanks for testing out CircuitPython! Now that you have encountered a - bug... you can file a report for it. + bug, you can file a report for it. - type: textarea id: firmware attributes: - label: CircuitPython version + label: CircuitPython version and board name description: >- - Include the version of CircuitPython you're running. You can see it in - the `boot_out.txt` file, as well as in the `REPL`. + Include the version of CircuitPython you're running and the name of the board you're using. + You can find this information in the `boot_out.txt` file, as well as in the REPL. placeholder: Adafruit CircuitPython 6.2.0 on 2021-03-01; Raspberry Pi Pico with rp2040 render: python validations: @@ -23,7 +23,7 @@ body: id: code attributes: label: Code/REPL - description: This is automatically rendered as Python, so no need for backticks. + description: Code here is automatically rendered as Python, so you don't need to include backticks. placeholder: | import busio, bitbangio i2c = bitbangio.I2C(board.GP1, board.GP0) diff --git a/.github/actions/deps/external/action.yml b/.github/actions/deps/external/action.yml index 68626dde50f..15a3aeb5084 100644 --- a/.github/actions/deps/external/action.yml +++ b/.github/actions/deps/external/action.yml @@ -22,11 +22,11 @@ runs: if: >- inputs.port != 'none' && inputs.port != 'litex' && - inputs.port != 'espressif' + inputs.port != 'espressif' && + inputs.port != 'zephyr-cp' uses: carlosperate/arm-none-eabi-gcc-action@v1 with: - # When changing this update what Windows grabs too! - release: '13.2.Rel1' + release: '15.2.Rel1' # espressif - name: Get espressif toolchain @@ -51,10 +51,20 @@ runs: # common - name: Cache python dependencies - if: inputs.port != 'espressif' + if: inputs.port != 'espressif' && inputs.port != 'zephyr-cp' uses: ./.github/actions/deps/python with: action: ${{ inputs.action }} + - name: Set ESP-IDF constraints path + if: inputs.port == 'espressif' + run: python3 -u tools/ci_set_idf_constraint.py + shell: bash + - name: Install python dependencies - run: pip install -r requirements-dev.txt + run: | + if [ -n "${IDF_CONSTRAINT_FILE:-}" ] && [ -f "$IDF_CONSTRAINT_FILE" ]; then + pip install -c "$IDF_CONSTRAINT_FILE" -r requirements-dev.txt + else + pip install -r requirements-dev.txt + fi shell: bash diff --git a/.github/actions/deps/ports/action.yml b/.github/actions/deps/ports/action.yml index 2412c475c01..6f91ea62cec 100644 --- a/.github/actions/deps/ports/action.yml +++ b/.github/actions/deps/ports/action.yml @@ -4,33 +4,29 @@ inputs: board: required: true type: string - -outputs: port: - value: ${{ steps.board-to-port.outputs.port }} + required: true + type: string runs: using: composite steps: - - name: Board to port - id: board-to-port - run: | - PORT=$(find ports/*/boards/ -type d -name ${{ inputs.board }} | sed 's/^ports\///g;s/\/boards.*//g') - if [ -z $PORT ]; then (exit 1); else echo >> $GITHUB_OUTPUT "port=$PORT"; fi - shell: bash - - name: Set up broadcom - if: steps.board-to-port.outputs.port == 'broadcom' + if: inputs.port == 'broadcom' uses: ./.github/actions/deps/ports/broadcom - name: Set up espressif - if: steps.board-to-port.outputs.port == 'espressif' + if: inputs.port == 'espressif' uses: ./.github/actions/deps/ports/espressif - name: Set up litex - if: steps.board-to-port.outputs.port == 'litex' + if: inputs.port == 'litex' uses: ./.github/actions/deps/ports/litex - name: Set up nordic - if: steps.board-to-port.outputs.port == 'nordic' + if: inputs.port == 'nordic' uses: ./.github/actions/deps/ports/nordic + + - name: Set up Zephyr + if: inputs.port == 'zephyr-cp' + uses: ./.github/actions/deps/ports/zephyr-cp diff --git a/.github/actions/deps/ports/broadcom/action.yml b/.github/actions/deps/ports/broadcom/action.yml index 99f53064b3f..fc375aa10f7 100644 --- a/.github/actions/deps/ports/broadcom/action.yml +++ b/.github/actions/deps/ports/broadcom/action.yml @@ -5,8 +5,8 @@ runs: steps: - name: Get broadcom toolchain run: | - wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz - sudo tar -C /usr --strip-components=1 -xaf gcc-arm-10.3-2021.07-x86_64-aarch64-none-elf.tar.xz + wget --no-verbose https://adafruit-circuit-python.s3.amazonaws.com/arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-elf.tar.xz + sudo tar -C /usr --strip-components=1 -xaf arm-gnu-toolchain-15.2.rel1-x86_64-aarch64-none-elf.tar.xz sudo apt-get update sudo apt-get install -y mtools shell: bash diff --git a/.github/actions/deps/ports/espressif/action.yml b/.github/actions/deps/ports/espressif/action.yml index 122940bb95a..321a0fb2b30 100644 --- a/.github/actions/deps/ports/espressif/action.yml +++ b/.github/actions/deps/ports/espressif/action.yml @@ -7,6 +7,7 @@ runs: run: | echo >> $GITHUB_ENV "IDF_PATH=$GITHUB_WORKSPACE/ports/espressif/esp-idf" echo >> $GITHUB_ENV "IDF_TOOLS_PATH=$GITHUB_WORKSPACE/.idf_tools" + echo >> $GITHUB_ENV "ESP_ROM_ELF_DIR=$GITHUB_WORKSPACE/.idf_tools" shell: bash - name: Get IDF commit @@ -18,7 +19,7 @@ runs: shell: bash - name: Cache IDF submodules - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: | .git/modules/ports/espressif/esp-idf @@ -26,7 +27,7 @@ runs: key: submodules-idf-${{ steps.idf-commit.outputs.commit }} - name: Cache IDF tools - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ${{ env.IDF_TOOLS_PATH }} key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-idf-${{ steps.idf-commit.outputs.commit }} diff --git a/.github/actions/deps/ports/nordic/action.yml b/.github/actions/deps/ports/nordic/action.yml index 5f08b17ca7a..96754be9507 100644 --- a/.github/actions/deps/ports/nordic/action.yml +++ b/.github/actions/deps/ports/nordic/action.yml @@ -5,7 +5,7 @@ runs: steps: - name: Get nrfutil 7+ run: | - wget https://developer.nordicsemi.com/.pc-tools/nrfutil/x64-linux/nrfutil + wget https://files.nordicsemi.com/artifactory/swtools/external/nrfutil/executables/x86_64-unknown-linux-gnu/nrfutil chmod +x nrfutil ./nrfutil install nrf5sdk-tools mkdir -p $HOME/.local/bin diff --git a/.github/actions/deps/ports/zephyr-cp/action.yml b/.github/actions/deps/ports/zephyr-cp/action.yml new file mode 100644 index 00000000000..4475132e185 --- /dev/null +++ b/.github/actions/deps/ports/zephyr-cp/action.yml @@ -0,0 +1,31 @@ +name: Fetch Zephyr port deps + +runs: + using: composite + steps: + - name: Get Linux build dependencies + if: runner.os == 'Linux' + run: | + echo "--- cpu model ---" + grep "model name" /proc/cpuinfo | head -1 + sudo dpkg --add-architecture i386 + sudo apt-get update + sudo apt-get install -y libusb-1.0-0-dev libudev-dev pkg-config mtools + # We have to hold python3 so the following install works. See https://github.com/actions/runner-images/issues/13803 + sudo apt-mark hold python3 + sudo apt-get install -y libsdl2-dev:i386 libsdl2-image-dev:i386 + echo "PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}" >> $GITHUB_ENV + shell: bash + - name: Setup Zephyr project + uses: zephyrproject-rtos/action-zephyr-setup@v1 + with: + app-path: zephyr-config + base-path: ports/zephyr-cp + toolchains: arm-zephyr-eabi + - name: Export cmake info + run: west zephyr-export + shell: bash + working-directory: ports/zephyr-cp + - name: Install Zephyr protobuf dependency + run: pip install protobuf==6.33.5 + shell: bash diff --git a/.github/actions/deps/python/action.yml b/.github/actions/deps/python/action.yml index da59b87b17a..bc8b578c147 100644 --- a/.github/actions/deps/python/action.yml +++ b/.github/actions/deps/python/action.yml @@ -16,7 +16,7 @@ runs: - name: Cache python dependencies id: cache-python-deps if: inputs.action == 'cache' - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: .cp_tools key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }} @@ -24,7 +24,7 @@ runs: - name: Restore python dependencies id: restore-python-deps if: inputs.action == 'restore' - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: .cp_tools key: ${{ runner.os }}-${{ env.pythonLocation }}-tools-cp-${{ hashFiles('requirements-dev.txt') }} diff --git a/.github/actions/deps/submodules/action.yml b/.github/actions/deps/submodules/action.yml index 6878c5e7e5d..5ec57b594c0 100644 --- a/.github/actions/deps/submodules/action.yml +++ b/.github/actions/deps/submodules/action.yml @@ -22,7 +22,7 @@ inputs: - restore version: - description: 'Whether to generate CP version' + description: 'Whether to fetch tags to identify CP version' required: false default: false type: boolean @@ -48,7 +48,7 @@ runs: - name: Cache submodules if: ${{ inputs.action == 'cache' }} - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}" key: submodules-common-${{ hashFiles('submodule_status') }} @@ -56,7 +56,7 @@ runs: - name: Restore submodules if: ${{ inputs.action == 'restore' }} - uses: actions/cache/restore@v4 + uses: actions/cache/restore@v5 with: path: ".git/modules/\n${{ join(fromJSON(steps.create-submodule-status.outputs.submodules), '\n') }}" key: submodules-common-${{ hashFiles('submodule_status') }} @@ -80,7 +80,7 @@ runs: git fetch --no-recurse-submodules --shallow-since="2021-07-01" origin $GITHUB_SHA git repack -d echo "::endgroup::" - CP_VERSION=$(tools/describe) + CP_VERSION=$(python py/version.py) echo "$CP_VERSION" echo "CP_VERSION=$CP_VERSION" >> $GITHUB_ENV echo "cp-version=$CP_VERSION" >> $GITHUB_OUTPUT diff --git a/.github/actions/mpy_cross/action.yml b/.github/actions/mpy_cross/action.yml index 8839f790915..469b8b0763e 100644 --- a/.github/actions/mpy_cross/action.yml +++ b/.github/actions/mpy_cross/action.yml @@ -16,7 +16,7 @@ runs: id: download-mpy-cross if: inputs.download == 'true' continue-on-error: true - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: mpy-cross path: mpy-cross/build @@ -36,7 +36,7 @@ runs: - name: Upload mpy-cross if: inputs.download == 'false' || steps.download-mpy-cross.outcome == 'failure' continue-on-error: true - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: mpy-cross path: mpy-cross/build/mpy-cross diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000000..21f1e4e630a --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,10 @@ +Thanks for submitting a pull request to CircuitPython! Remove these instructions before submitting. + + See https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github for detailed instructions. + +- Consider whether to submit this PR against `main` or against (if it exists) the branch for the current stable release or an upcoming minor release. The branch will be named `i.j.x`, for example, `9.2.x`. Bug fixes and minor enhancements can be submitted against the stable release branch, and will be merged to `main` regularly. +- Create your own fork of `circuitpython` and create a branch for your changes. +- Use `pre-commit` to check your commits before submitting. See https://learn.adafruit.com/contribute-to-circuitpython-with-git-and-github/check-your-code. +- Test your changes and tell us how you tested. + +--- diff --git a/.github/workflows/build-board-custom.yml b/.github/workflows/build-board-custom.yml index e479540be63..c17e1b13f97 100644 --- a/.github/workflows/build-board-custom.yml +++ b/.github/workflows/build-board-custom.yml @@ -36,40 +36,55 @@ run-name: ${{ inputs.board }}-${{ inputs.language }}-${{ inputs.version }}${{ in jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Set up repository run: | git clone --filter=tree:0 https://github.com/adafruit/circuitpython.git $GITHUB_WORKSPACE - name: Checkout head / tag + env: + TAG: ${{ inputs.version == 'latest' && 'HEAD' || inputs.version }} run: | - git checkout ${{ inputs.version == 'latest' && 'HEAD' || inputs.version }} + git checkout "$TAG" - name: fork compatibility if: github.repository_owner != 'adafruit' + env: + REPO: ${{ github.repository }} run: | - git remote add fork https://github.com/${{github.repository}}.git + git remote add fork "https://github.com/$REPO.git" git fetch fork --filter=tree:0 - name: branch compatibility if: inputs.branch != 'main' && inputs.version == 'latest' && github.repository_owner == 'adafruit' + env: + BRANCH: ${{ inputs.branch }} run: | - git checkout ${{inputs.branch}} + git checkout "$BRANCH" - name: branch compatibility (fork) if: inputs.branch != '' && inputs.version == 'latest' && github.repository_owner != 'adafruit' + env: + BRANCH: ${{ inputs.branch }} run: | - git checkout -b fork-branch fork/${{inputs.branch}} + git checkout -b fork-branch "fork/$BRANCH" - name: Set up identifier if: inputs.debug || inputs.flags != '' run: | > custom-build && git add custom-build - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x + - name: Board to port + id: board-to-port + run: | + PORT=$(python tools/board_to_port.py "${{ inputs.board }}") + echo "port=$PORT" >> $GITHUB_OUTPUT + shell: bash - name: Set up port id: set-up-port uses: ./.github/actions/deps/ports with: board: ${{ inputs.board }} + port: ${{ steps.board-to-port.outputs.port }} - name: Set up submodules id: set-up-submodules uses: ./.github/actions/deps/submodules @@ -80,7 +95,7 @@ jobs: uses: ./.github/actions/deps/external with: action: cache - port: ${{ steps.set-up-port.outputs.port }} + port: ${{ steps.board-to-port.outputs.port }} - name: Set up mpy-cross if: steps.set-up-submodules.outputs.frozen == 'True' uses: ./.github/actions/mpy_cross @@ -89,7 +104,7 @@ jobs: download: false - name: Versions run: | - tools/describe + python py/version.py gcc --version python3 --version cmake --version || true @@ -101,10 +116,15 @@ jobs: riscv64-unknown-elf-gcc --version || true mkfs.fat --version || true - name: Build board - run: make -j4 ${{ inputs.flags }} BOARD=${{ inputs.board }} DEBUG=${{ inputs.debug && '1' || '0' }} TRANSLATION=${{ inputs.language }} - working-directory: ports/${{ steps.set-up-port.outputs.port }} + env: + TRANSLATION: ${{ inputs.language }} + BOARD: ${{ inputs.board }} + FLAGS: ${{ inputs.flags }} + DEBUG: ${{ inputs.debug && '1' || '0' }} + run: make -j4 $FLAGS BOARD="$BOARD" DEBUG=$DEBUG TRANSLATION="$TRANSLATION" + working-directory: ports/${{ steps.board-to-port.outputs.port }} - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: ${{ inputs.board }}-${{ inputs.language }}-${{ inputs.version }}${{ inputs.flags != '' && '-custom' || '' }}${{ inputs.debug && '-debug' || '' }} - path: ports/${{ steps.set-up-port.outputs.port }}/build-${{ inputs.board }}/firmware.* + path: ports/${{ steps.board-to-port.outputs.port }}/build-${{ inputs.board }}/firmware.* diff --git a/.github/workflows/build-boards.yml b/.github/workflows/build-boards.yml index 07f36282079..6fbc5b6a08f 100644 --- a/.github/workflows/build-boards.yml +++ b/.github/workflows/build-boards.yml @@ -9,6 +9,9 @@ on: cp-version: required: true type: string + port: + required: true + type: string secrets: AWS_ACCESS_KEY_ID: required: false @@ -17,7 +20,7 @@ on: jobs: board: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 env: CP_VERSION: ${{ inputs.cp-version }} strategy: @@ -26,14 +29,15 @@ jobs: board: ${{ fromJSON(inputs.boards) }} steps: - name: Set up repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: false show-progress: false fetch-depth: 1 + persist-credentials: false - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x @@ -42,6 +46,7 @@ jobs: uses: ./.github/actions/deps/ports with: board: ${{ matrix.board }} + port: ${{ inputs.port }} - name: Set up submodules id: set-up-submodules @@ -50,7 +55,7 @@ jobs: - name: Set up external uses: ./.github/actions/deps/external with: - port: ${{ steps.set-up-port.outputs.port }} + port: ${{ inputs.port }} - name: Set up mpy-cross if: steps.set-up-submodules.outputs.frozen == 'True' uses: ./.github/actions/mpy_cross @@ -82,7 +87,7 @@ jobs: HEAD_COMMIT_MESSAGE: ${{ github.event.head_commit.message }} - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: ${{ matrix.board }} path: bin/${{ matrix.board }} diff --git a/.github/workflows/build-mpy-cross.yml b/.github/workflows/build-mpy-cross.yml index 26226d84e6a..9e5c1cdfc4a 100644 --- a/.github/workflows/build-mpy-cross.yml +++ b/.github/workflows/build-mpy-cross.yml @@ -14,7 +14,7 @@ on: jobs: build: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -28,13 +28,14 @@ jobs: OS_static-raspbian: linux-raspbian steps: - name: Set up repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: false show-progress: false fetch-depth: 1 + persist-credentials: false - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x - name: Set up submodules @@ -57,12 +58,15 @@ jobs: run: make -C mpy-cross -j4 -f Makefile.${{ matrix.mpy-cross }} - name: Set output + env: + EX: ${{ env[format('EX_{0}', matrix.mpy-cross)] || matrix.mpy-cross }} + OS: ${{ env[format('OS_{0}', matrix.mpy-cross)] }}" run: | - echo >> $GITHUB_ENV "EX=${{ env[format('EX_{0}', matrix.mpy-cross)] || matrix.mpy-cross }}" - echo >> $GITHUB_ENV "OS=${{ env[format('OS_{0}', matrix.mpy-cross)] }}" + echo >> $GITHUB_ENV "EX=$EX" + echo >> $GITHUB_ENV "OS=$OS" - name: Upload artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: mpy-cross.${{ env.EX }} path: mpy-cross/build-${{ matrix.mpy-cross }}/mpy-cross.${{ env.EX }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f9026830bb0..47b19a8fa7b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,9 @@ name: Build CI on: push: + branches: + - main + - '*.x' pull_request: release: types: [published] @@ -16,11 +19,10 @@ concurrency: jobs: scheduler: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 outputs: docs: ${{ steps.set-matrix.outputs.docs }} ports: ${{ steps.set-matrix.outputs.ports }} - windows: ${{ steps.set-matrix.outputs.windows }} cp-version: ${{ steps.set-up-submodules.outputs.version }} steps: - name: Dump GitHub context @@ -28,13 +30,14 @@ jobs: env: GITHUB_CONTEXT: ${{ toJson(github) }} - name: Set up repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: false show-progress: false fetch-depth: 1 + persist-credentials: false - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x - name: Duplicate USB VID/PID check @@ -66,7 +69,9 @@ jobs: EXCLUDE_COMMIT: ${{ github.event.pull_request.head.sha }} - name: Set head sha (pull) if: github.event_name == 'pull_request' - run: echo "HEAD_SHA=${{ github.event.pull_request.head.sha }}" >> $GITHUB_ENV + env: + HEAD_SHA: ${{ github.event.pull_request.head.sha }} + run: echo "HEAD_SHA=$HEAD_SHA" >> $GITHUB_ENV - name: Set base sha (pull) if: github.event_name == 'pull_request' run: git cat-file -e $SHA && echo "BASE_SHA=$SHA" >> $GITHUB_ENV || true @@ -74,7 +79,9 @@ jobs: SHA: ${{ steps.get-last-commit-with-checks.outputs.commit_sha || github.event.pull_request.base.sha }} - name: Set head sha (push) if: github.event_name == 'push' - run: echo "HEAD_SHA=${{ github.event.after }}" >> $GITHUB_ENV + env: + SHA: ${{ github.event.after }} + run: echo "HEAD_SHA=$SHA" >> $GITHUB_ENV - name: Set base sha (push) if: github.event_name == 'push' run: git cat-file -e $SHA && echo "BASE_SHA=$SHA" >> $GITHUB_ENV || true @@ -102,20 +109,21 @@ jobs: cp-version: ${{ needs.scheduler.outputs.cp-version }} mpy-cross-mac: - runs-on: macos-12 + runs-on: macos-latest needs: scheduler if: needs.scheduler.outputs.ports != '{}' env: CP_VERSION: ${{ needs.scheduler.outputs.cp-version }} steps: - name: Set up repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: false show-progress: false fetch-depth: 1 + persist-credentials: false - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x - name: Set up submodules @@ -125,57 +133,45 @@ jobs: gcc --version python3 --version msgfmt --version - - name: Build mpy-cross - run: make -C mpy-cross -j4 - - uses: actions/upload-artifact@v4 - with: - name: mpy-cross-macos-x64 - path: mpy-cross/build/mpy-cross - name: Build mpy-cross (arm64) run: make -C mpy-cross -j4 -f Makefile.m1 V=2 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: mpy-cross-macos-arm64 path: mpy-cross/build-arm64/mpy-cross-arm64 - - name: Make universal binary - run: lipo -create -output mpy-cross-macos-universal mpy-cross/build/mpy-cross mpy-cross/build-arm64/mpy-cross-arm64 - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: mpy-cross-macos-universal - path: mpy-cross-macos-universal - name: Upload to S3 if: >- (github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository_owner == 'adafruit') || (github.event_name == 'release' && (github.event.action == 'published' || github.event.action == 'rerequested')) run: | - [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross-macos-universal s3://adafruit-circuit-python/bin/mpy-cross/macos/mpy-cross-macos-${{ env.CP_VERSION }}-universal --no-progress --region us-east-1 - [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/build-arm64/mpy-cross-arm64 s3://adafruit-circuit-python/bin/mpy-cross/macos/mpy-cross-macos-${{ env.CP_VERSION }}-arm64 --no-progress --region us-east-1 - [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/build/mpy-cross s3://adafruit-circuit-python/bin/mpy-cross/macos/mpy-cross-macos-${{ env.CP_VERSION }}-x64 --no-progress --region us-east-1 + [ -z "$AWS_ACCESS_KEY_ID" ] || aws s3 cp mpy-cross/build-arm64/mpy-cross-arm64 s3://adafruit-circuit-python/bin/mpy-cross/macos/mpy-cross-macos-"${CP_VERSION}"-arm64 --no-progress --region us-east-1 env: AWS_PAGER: '' AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} docs: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: scheduler if: needs.scheduler.outputs.docs == 'True' env: CP_VERSION: ${{ needs.scheduler.outputs.cp-version }} steps: - name: Set up repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: false show-progress: false fetch-depth: 1 + persist-credentials: false - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x - name: Set up submodules uses: ./.github/actions/deps/submodules + with: + version: true - name: Install dependencies run: | sudo apt-get update @@ -183,20 +179,20 @@ jobs: pip install -r requirements-doc.txt - name: Build and Validate Stubs run: make check-stubs -j4 - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: stubs path: circuitpython-stubs/dist/* - name: Test Documentation Build (HTML) - run: sphinx-build -E -W -b html -D version=${{ env.CP_VERSION }} -D release=${{ env.CP_VERSION }} . _build/html - - uses: actions/upload-artifact@v4 + run: sphinx-build -E -W -b html -D version="$CP_VERSION" -D release="$CP_VERSION" . _build/html + - uses: actions/upload-artifact@v7 with: name: docs-html path: _build/html - name: Test Documentation Build (LaTeX/PDF) run: | make latexpdf - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 with: name: docs-latexpdf path: _build/latex @@ -217,78 +213,6 @@ jobs: [ -z "$TWINE_USERNAME" ] || echo "Uploading dev release to PyPi" [ -z "$TWINE_USERNAME" ] || twine upload circuitpython-stubs/dist/* - windows: - runs-on: windows-2022 - needs: scheduler - if: needs.scheduler.outputs.windows == 'True' - env: - CP_VERSION: ${{ needs.scheduler.outputs.cp-version }} - defaults: - run: - # We define a custom shell script here, although `msys2.cmd` does neither exist nor is it available in the PATH yet - shell: msys2 {0} - steps: - # We want to change the configuration of the git command that actions/checkout will be using - # (since it is not possible to set autocrlf through the action yet, see actions/checkout#226). - - run: git config --global core.autocrlf input - shell: bash - - name: Check python coding (cmd) - run: python -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))" - shell: cmd - # We use a JS Action, which calls the system terminal or other custom terminals directly, if required - - uses: msys2/setup-msys2@v2 - with: - install: base-devel git wget unzip gcc python-pip - # The goal of this was to test how things worked when the default file encoding (locale.getpreferedencoding()) - # was not UTF-8. However, msys2 python does use utf-8 as the preferred file encoding, and using actions/setup-python - # python3.8 gave a broken build, so we're not really testing what we wanted to test. - # However, commandline length limits are being tested so that does some good. - - name: Check python coding (msys2) - run: | - locale -v - which python; python --version - python -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))" - which python3; python3 --version - python3 -c "import sys, locale; print(sys.getdefaultencoding(), locale.getpreferredencoding(False))" - - name: Install dependencies - run: | - wget --no-verbose -O gcc-arm.zip https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-mingw-w64-i686-arm-none-eabi.zip - unzip -q -d /tmp gcc-arm.zip - tar -C /tmp/arm-gnu-toolchain* -cf - . | tar -C /usr/local -xf - - # We could use a venv instead, but that requires entering the venv on each run step - # that runs in its own shell. There are some actions that help with that, but not for msys2 - # that I can find. (dhalbert) - pip install --break-system-packages wheel - # requirements-dev.txt doesn't install on windows. (with msys2 python) - # instead, pick a subset for what we want to do - pip install --break-system-packages cascadetoml jinja2 typer click intelhex - # check that installed packages work....? - which python; python --version; python -c "import cascadetoml" - which python3; python3 --version; python3 -c "import cascadetoml" - - name: Set up repository - uses: actions/checkout@v4 - with: - submodules: false - show-progress: false - fetch-depth: 1 - - name: Set up submodules - uses: ./.github/actions/deps/submodules - - name: build mpy-cross - run: make -j4 -C mpy-cross - - name: build rp2040 - run: make -j4 -C ports/raspberrypi BOARD=adafruit_feather_rp2040 TRANSLATION=de_DE - - name: build samd21 - run: make -j4 -C ports/atmel-samd BOARD=feather_m0_express TRANSLATION=zh_Latn_pinyin - - name: build samd51 - run: make -j4 -C ports/atmel-samd BOARD=feather_m4_express TRANSLATION=es - - name: build nordic - run: make -j4 -C ports/nordic BOARD=feather_nrf52840_express TRANSLATION=fr - - name: build stm - run: make -j4 -C ports/stm BOARD=feather_stm32f405_express TRANSLATION=pt_BR - # I gave up trying to do esp builds on windows when I saw - # ERROR: Platform MINGW64_NT-10.0-17763-x86_64 appears to be unsupported - # https://github.com/espressif/esp-idf/issues/7062 - ports: needs: [scheduler, mpy-cross, tests] if: needs.scheduler.outputs.ports != '{}' @@ -301,3 +225,4 @@ jobs: with: boards: ${{ toJSON(fromJSON(needs.scheduler.outputs.ports)[matrix.port]) }} cp-version: ${{ needs.scheduler.outputs.cp-version }} + port: ${{ matrix.port }} diff --git a/.github/workflows/bundle_cron.yml b/.github/workflows/bundle_cron.yml new file mode 100644 index 00000000000..eefffaaa5b9 --- /dev/null +++ b/.github/workflows/bundle_cron.yml @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2019 Michael Schroeder +# +# SPDX-License-Identifier: MIT + +name: Update Bundles + +on: + schedule: + - cron: 0 5 * * * + workflow_dispatch: + +jobs: + check-repo-owner: + # This job is so the entire workflow will end successfully and give some + # output to explain why it hasn't run on a non-Adafruit fork. + runs-on: ubuntu-latest + steps: + - name: repository + env: + OWNER_IS_ADAFRUIT: ${{ startswith(github.repository, 'adafruit/') }} + run: | + echo "This workflow will only run if Adafruit is the repository owner." + echo "Repository owner is Adafruit: $OWNER_IS_ADAFRUIT" + update-bundles: + runs-on: ubuntu-latest + # Only run the build on Adafruit's repository. Forks won't have the secrets. + # It's necessary to do this here, since 'schedule' events cannot (currently) + # be limited (they run on all forks' default branches). + if: startswith(github.repository, 'adafruit/') + steps: + - name: Set up Python 3.12 + uses: actions/setup-python@v6 + with: + python-version: 3.12 + - name: Load contributor cache + uses: actions/cache@v5 + with: + key: "contributor-cache" + path: "contributors.json" + - name: Versions + run: | + python3 --version + - uses: actions/checkout@v6 + with: + repository: 'adafruit/adabot' + submodules: true + - name: Install deps + run: | + pip install -r requirements.txt + - name: Run adabot.circuitpython_bundle + env: + ADABOT_EMAIL: ${{ secrets.ADABOT_EMAIL }} + ADABOT_GITHUB_USER: ${{ secrets.ADABOT_GITHUB_USER }} + ADABOT_GITHUB_ACCESS_TOKEN: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }} + BIGQUERY_PRIVATE_KEY: ${{ secrets.BIGQUERY_PRIVATE_KEY }} + BIGQUERY_CLIENT_EMAIL: ${{ secrets.BIGQUERY_CLIENT_EMAIL }} + run: | + python3 -u -m adabot.circuitpython_bundle diff --git a/.github/workflows/create-website-pr.yml b/.github/workflows/create-website-pr.yml index 050d1d39414..559a41e67e7 100644 --- a/.github/workflows/create-website-pr.yml +++ b/.github/workflows/create-website-pr.yml @@ -10,20 +10,21 @@ on: jobs: website: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Dump GitHub context run: echo "$GITHUB_CONTEXT" env: GITHUB_CONTEXT: ${{ toJson(github) }} - name: Set up repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: false show-progress: false fetch-depth: 1 + persist-credentials: false - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x - name: Set up submodules diff --git a/.github/workflows/learn_cron.yml b/.github/workflows/learn_cron.yml new file mode 100644 index 00000000000..135089bfd5e --- /dev/null +++ b/.github/workflows/learn_cron.yml @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2021 Jeff Epler for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +name: Tag Learning System Guides + +on: + schedule: + - cron: 0 5 * * * + +jobs: + check-repo-owner: + # This job is so the entire workflow will end successfully and give some + # output to explain why it hasn't run on a non-Adafruit fork. + runs-on: ubuntu-latest + if: ${{ (github.repository_owner != 'adafruit') }} + steps: + - run: | + echo "This workflow is only intended to run in the adafruit fork" + + update-learn: + runs-on: ubuntu-latest + # Only run the build if the access token has been configured. This will be + # the case on Adafruit's repository. It's necessary to do this here, since + # 'schedule' events cannot (currently) be limited (they run on all forks' + # default branches). + if: ${{ (github.repository_owner == 'adafruit') }} + steps: + - uses: actions/checkout@v6 + with: + repository: ${{ github.repository_owner }}/Adafruit_Learning_System_Guides + token: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }} + - name: Tag a release + env: + ADABOT_EMAIL: ${{ secrets.ADABOT_EMAIL }} + run: | + git config --global user.name adabot + git config --global user.email "$ADABOT_EMAIL" + TAG_NAME=`date +%Y%m%d` + git tag $TAG_NAME + git push origin $TAG_NAME diff --git a/.github/workflows/notify-on-issue-label.yml b/.github/workflows/notify-on-issue-label.yml index da1ac0a18e2..2465851e35b 100644 --- a/.github/workflows/notify-on-issue-label.yml +++ b/.github/workflows/notify-on-issue-label.yml @@ -10,7 +10,7 @@ jobs: permissions: issues: write steps: - - uses: tekktrik/issue-labeled-ping@v1 + - uses: tekktrik/issue-labeled-ping@v3 with: github-token: ${{ secrets.GITHUB_TOKEN }} user: v923z diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index ceeba5900d6..21ae984e468 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -14,16 +14,17 @@ concurrency: jobs: pre-commit: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - name: Set up repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: submodules: false show-progress: false fetch-depth: 1 + persist-credentials: false - name: Set up python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.x - name: Set up submodules @@ -41,7 +42,7 @@ jobs: run: git diff > ~/pre-commit.patch - name: Upload patch if: failure() - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v7 with: name: patch path: ~/pre-commit.patch diff --git a/.github/workflows/reports_cron.yml b/.github/workflows/reports_cron.yml new file mode 100644 index 00000000000..476ead95d25 --- /dev/null +++ b/.github/workflows/reports_cron.yml @@ -0,0 +1,91 @@ +# SPDX-FileCopyrightText: 2019 Michael Schroeder +# +# SPDX-License-Identifier: MIT + +name: Run Daily Reports + +on: + schedule: + # The actor (github.actor) that runs the cron job may be the user who created the cron job + # initially. It does not appear to be settable via a secret or environment variable. + - cron: 15 5 * * * + workflow_dispatch: + + +jobs: + check-repo-owner: + # This job is so the entire workflow will end successfully and give some + # output to explain why it hasn't run on a non-Adafruit fork. + runs-on: ubuntu-latest + steps: + - name: repository + env: + OWNER_IS_ADAFRUIT: ${{ startswith(github.repository, 'adafruit/') }} + run: | + echo "This workflow will only run if Adafruit is the repository owner." + echo "Repository owner is Adafruit: $OWNER_IS_ADAFRUIT" + run-reports: + runs-on: ubuntu-latest + # Only run the build on Adafruit's repository. Forks won't have the secrets. + # It's necessary to do this here, since 'schedule' events cannot (currently) + # be limited (they run on all forks' default branches). + if: startswith(github.repository, 'adafruit/') + env: + ADABOT_GITHUB_USER: ${{ secrets.ADABOT_GITHUB_USER }} + ADABOT_GITHUB_ACCESS_TOKEN: ${{ secrets.ADABOT_GITHUB_ACCESS_TOKEN }} + RTD_TOKEN: ${{ secrets.RTD_TOKEN }} + BIGQUERY_PRIVATE_KEY: ${{ secrets.BIGQUERY_PRIVATE_KEY }} + BIGQUERY_CLIENT_EMAIL: ${{ secrets.BIGQUERY_CLIENT_EMAIL }} + steps: + - name: Set up Python 3.11 + uses: actions/setup-python@v6 + with: + python-version: 3.11 + - name: Versions + run: | + python3 --version + - uses: actions/checkout@v6 + with: + repository: 'adafruit/adabot' + submodules: true + - name: Install deps + run: | + pip install -r requirements.txt + - name: Make Directory For Report Files + run: mkdir -p bin/adabot + - name: Set Date Variable + id: today + run: | + echo date=$( + date +%Y%m%d + ) >> $GITHUB_OUTPUT + - name: Run adabot.circuitpython_libraries + env: + # LIB_CHECK_CP_FILE is for circuitpython_libraries.py output + LIB_CHECK_CP_FILE: bin/adabot/circuitpython_library_report_${{ steps.today.outputs.date }}.txt + run: | + python3 -u -m adabot.circuitpython_libraries -o $LIB_CHECK_CP_FILE + continue-on-error: true + - name: Run adabot.circuitpython_library_download_stats + env: + # LIB_DL_STATS_FILE is for future Bundle and PyPi download stats script + LIB_DL_STATS_FILE: bin/adabot/library_download_stats_${{ steps.today.outputs.date }}.txt + run: | + python3 -u -m adabot.circuitpython_library_download_stats -o $LIB_DL_STATS_FILE + continue-on-error: true + - name: Run adabot.arduino_libraries + env: + # LIB_CHECK_ARD_FILE is for arduino_libraries.py output + LIB_CHECK_ARD_FILE: bin/adabot/arduino_library_report_${{ steps.today.outputs.date }}.txt + run: | + python3 -u -m adabot.arduino_libraries -o $LIB_CHECK_ARD_FILE + continue-on-error: true + - name: Check For Files + run: | + ls bin/adabot + - name: Upload Reports To AWS S3 + if: ${{ github.event_name != 'workflow_dispatch' }} + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + run: "[ -z \"$AWS_ACCESS_KEY_ID\" ] || aws s3 cp bin/adabot/ s3://adafruit-circuit-python/adabot/bin/reports/ --recursive --no-progress --region us-east-1" diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 80bfc72bd98..5bb3aaee736 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -23,46 +23,81 @@ jobs: TEST_native: --emit native TEST_native_mpy: --via-mpy --emit native -d basics float micropython steps: - - name: Set up repository - uses: actions/checkout@v4 - with: - submodules: false - show-progress: false - fetch-depth: 1 - - name: Set up python - uses: actions/setup-python@v5 - with: - python-version: 3.12 - - name: Set up submodules - uses: ./.github/actions/deps/submodules - with: - target: tests - - name: Set up external - if: matrix.test == 'all' - uses: ./.github/actions/deps/external - - name: Set up mpy-cross - uses: ./.github/actions/mpy_cross - with: - cp-version: ${{ inputs.cp-version }} - - name: Build unix port - run: make -C ports/unix VARIANT=coverage -j4 - - name: Run tests - run: ./run-tests.py -j4 ${{ env[format('TEST_{0}', matrix.test)] }} - working-directory: tests - - name: Print failure info - run: ./run-tests.py -j4 --print-failures - if: failure() - working-directory: tests - # Not working after MicroPython v1.23 merge. - # - name: Build native modules - # if: matrix.test == 'all' - # run: | - # make -C examples/natmod/features1 - # make -C examples/natmod/features2 - # make -C examples/natmod/heapq - # make -C examples/natmod/random - # make -C examples/natmod/re - # - name: Test native modules - # if: matrix.test == 'all' - # run: ./run-natmodtests.py extmod/{heapq*,random*,re*}.py - # working-directory: tests + - name: Set up repository + uses: actions/checkout@v6 + with: + submodules: false + show-progress: false + fetch-depth: 1 + - name: Set up python + uses: actions/setup-python@v6 + with: + python-version: 3.12 + - name: Set up submodules + uses: ./.github/actions/deps/submodules + with: + target: tests + - name: Set up external + if: matrix.test == 'all' + uses: ./.github/actions/deps/external + - name: Set up mpy-cross + uses: ./.github/actions/mpy_cross + with: + cp-version: ${{ inputs.cp-version }} + - name: Build unix port + run: make -C ports/unix VARIANT=coverage -j4 + - name: Run tests + run: ./run-tests.py -j4 ${{ env[format('TEST_{0}', matrix.test)] }} + working-directory: tests + - name: Print failure info + run: ./run-tests.py -j4 --print-failures + if: failure() + working-directory: tests + - name: Build native modules + if: matrix.test == 'all' + run: | + make -C examples/natmod/features1 + make -C examples/natmod/features2 + make -C examples/natmod/heapq + make -C examples/natmod/random + make -C examples/natmod/re + - name: Test native modules + if: matrix.test == 'all' + run: ./run-natmodtests.py extmod/{heapq*,random*,re*}.py + working-directory: tests + + zephyr: + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + env: + CP_VERSION: ${{ inputs.cp-version }} + steps: + - name: Set up repository + uses: actions/checkout@v6 + with: + submodules: false + show-progress: false + fetch-depth: 1 + - name: Set up python + uses: actions/setup-python@v6 + with: + python-version: 3.13 + - name: Set up Zephyr + uses: ./.github/actions/deps/ports/zephyr-cp + - name: Set up submodules + id: set-up-submodules + uses: ./.github/actions/deps/submodules + with: + target: zephyr-cp + - name: Set up external + uses: ./.github/actions/deps/external + - name: Build native sim target + run: make -C ports/zephyr-cp -j2 BOARD=native_native_sim + - name: Build bsim + run: make -j 2 everything + working-directory: ports/zephyr-cp/tools/bsim + - name: Build native_nrf5340bsim + run: make -C ports/zephyr-cp -j2 BOARD=native_nrf5340bsim + - name: Run Zephyr tests + run: make -C ports/zephyr-cp test diff --git a/.gitignore b/.gitignore index 9679ed5e0e2..ca6872387dd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ *.o *.a !atmel-samd/asf/**/*.a +!ports/espressif/microros-lib/**/*.a *.elf *.bin !*.toml.bin @@ -38,10 +39,12 @@ bin/ circuitpython-stubs/ test-stubs/ build-*/ +docs/genrst/ -# Test failure outputs +# Test failure outputs and intermediate artifacts ###################### tests/results/* +tests/ports/unix/ffi_lib.so # Python cache files ###################### @@ -52,6 +55,9 @@ __pycache__/ ###################### GNUmakefile user.props +user_pre_mpconfigport.mk +user_post_mpconfigport.mk +user_post_circuitpy_defns.mk # Sphinx output ############### @@ -75,6 +81,7 @@ TAGS #################### *~ +# MacOS desktop metadata files *.DS_Store **/*.DS_Store *.icloud @@ -97,3 +104,16 @@ TAGS # clangd cache ############## .cache + +**/CLAUDE.local.md +.claude + +# windsurf rules +.windsurfrules + +# git-review-web outputs +.review + +# Zephyr trace files +**/channel0_0 +**/*.perfetto-trace diff --git a/.gitmodules b/.gitmodules index cf0e554e26b..f241a4c7eae 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,7 +7,7 @@ url = https://github.com/micropython/axtls.git [submodule "lib/libffi"] path = lib/libffi - url = https://github.com/atgreen/libffi + url = https://github.com/libffi/libffi [submodule "lib/berkeley-db-1.xx"] path = lib/berkeley-db-1.xx url = https://github.com/micropython/berkeley-db-1.xx @@ -143,10 +143,11 @@ [submodule "ports/espressif/esp-idf"] path = ports/espressif/esp-idf url = https://github.com/adafruit/esp-idf.git - branch = circuitpython-v5.3.1 + branch = circuitpython-v5.5.1 [submodule "ports/espressif/esp-protocols"] path = ports/espressif/esp-protocols - url = https://github.com/espressif/esp-protocols.git + url = https://github.com/adafruit/esp-protocols.git + branch = circuitpython [submodule "ports/espressif/esp-camera"] path = ports/espressif/esp-camera url = https://github.com/adafruit/esp32-camera.git @@ -172,6 +173,7 @@ [submodule "ports/raspberrypi/sdk"] path = ports/raspberrypi/sdk url = https://github.com/raspberrypi/pico-sdk.git + branch = force_inline_critical_section_2.1.1 [submodule "data/nvm.toml"] path = data/nvm.toml url = https://github.com/adafruit/nvm.toml.git @@ -311,10 +313,10 @@ [submodule "ports/raspberrypi/lib/lwip"] path = ports/raspberrypi/lib/lwip url = https://github.com/adafruit/lwip.git - branch = circuitpython8 + branch = circuitpython9 [submodule "lib/mbedtls"] path = lib/mbedtls - url = https://github.com/ARMmbed/mbedtls.git + url = https://github.com/Mbed-TLS/mbedtls.git [submodule "frozen/Adafruit_CircuitPython_UC8151D"] path = frozen/Adafruit_CircuitPython_UC8151D url = https://github.com/adafruit/Adafruit_CircuitPython_UC8151D @@ -345,6 +347,7 @@ [submodule "ports/raspberrypi/lib/Pico-PIO-USB"] path = ports/raspberrypi/lib/Pico-PIO-USB url = https://github.com/sekigon-gonnoc/Pico-PIO-USB.git + branch = main [submodule "lib/micropython-lib"] path = lib/micropython-lib url = https://github.com/micropython/micropython-lib.git @@ -406,3 +409,15 @@ [submodule "frozen/Adafruit_CircuitPython_Wiznet5k"] path = frozen/Adafruit_CircuitPython_Wiznet5k url = https://github.com/adafruit/Adafruit_CircuitPython_Wiznet5k +[submodule "ports/analog/msdk"] + path = ports/analog/msdk + url = https://github.com/analogdevicesinc/msdk.git +[submodule "ports/espressif/microros-lib"] + path = ports/espressif/microros-lib + url = https://github.com/hierophect/microros-lib.git +[submodule "frozen/Adafruit_CircuitPython_OPT4048"] + path = frozen/Adafruit_CircuitPython_OPT4048 + url = https://github.com/adafruit/Adafruit_CircuitPython_OPT4048.git +[submodule "frozen/CircuitPython_edupico2_paj7620"] + path = frozen/CircuitPython_edupico2_paj7620 + url = https://github.com/CytronTechnologies/CircuitPython_edupico2_paj7620.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 226bbdea628..c39faf99f00 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,19 +4,33 @@ # CIRCUITPY-CHANGE: CircuitPython-specific. +# Note that by default, pre-commit hooks do not look inside submodules. +# So you don't need to exclude submodules explicitly here. + repos: -- repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.0.1 + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v6.0.0 hooks: - - id: check-yaml - - id: end-of-file-fixer - exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|ports/raspberrypi/sdk|lib/tinyusb)' - - id: trailing-whitespace - exclude: '^(tests/.*\.exp|tests/cmdline/.*|tests/.*/data/.*|lib/mbedtls_errors/generate_errors.diff|ports/raspberrypi/sdk|lib/tinyusb)' -- repo: https://github.com/codespell-project/codespell - rev: v2.2.4 + - id: check-yaml + - id: end-of-file-fixer + exclude: | + (?x)^( + tests/.*\.exp| + tests/cmdline/.*| + tests/.*/data/.* + ) + - id: trailing-whitespace + exclude: | + (?x)^( + tests/.*\.exp| + tests/cmdline/.*| + tests/.*/data/.*| + lib/mbedtls_errors/generate_errors.diff + ) + - repo: https://github.com/codespell-project/codespell + rev: v2.4.1 hooks: - - id: codespell + - id: codespell args: [-w] exclude: | (?x)^( @@ -25,23 +39,30 @@ repos: tests/unicode/data/utf-8_invalid.txt| tests/extmod/data/qr.pgm| tests/basics/bytearray_byte_operations.py| - ports/raspberrypi/sdk + ports/zephyr-cp/cptools/compat2driver.py ) -- repo: local + - repo: local hooks: - - id: translations + - id: translations name: Translations entry: sh -c "if ! make check-translate; then make translate; fi" types: [c] pass_filenames: false language: system - - id: formatting + - id: formatting name: Formatting - entry: python3 tools/codeformat.py - types_or: [c, python] - language: system - exclude: | - (?x)^( - lib/tinyusb| - ports/raspberrypi/sdk - ) + entry: python3 tools/codeformat.py -v -c + language: python + - repo: https://github.com/astral-sh/ruff-pre-commit + # Ruff version. + rev: v0.15.7 + hooks: + # Run the linter. + - id: ruff + args: [ --fix ] + # Run the formatter. + - id: ruff-format + - repo: https://github.com/tox-dev/pyproject-fmt + rev: "v2.21.0" + hooks: + - id: pyproject-fmt diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000000..e7d2fdbbe8c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,4 @@ +- Capture CircuitPython output by finding the matching device in `/dev/serial/by-id` +- You can mount the CIRCUITPY drive by doing `udisksctl mount -b /dev/disk/by-label/CIRCUITPY` and access it via `/run/media//CIRCUITPY`. +- `circup` is a command line tool to install libraries and examples to CIRCUITPY. +- When connecting to serial devices on Linux use /dev/serial/by-id. These will be more stable than /dev/ttyACM*. diff --git a/BUILDING.md b/BUILDING.md index 34cd544d736..6778965bed0 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -64,6 +64,52 @@ If you aren't sure what boards exist, have a peek in the boards subdirectory of If you have a fast computer with many cores, consider adding `-j` to your build flags, such as `-j17` on a 6-core 12-thread machine. +## Configuration + +Ports and boards are preconfigured, thus make knows how to build a specific +board. Power users can change the configuration of a specific board or port, +either by passing compile-time options to make, or by creating appropriate +make include files. + +The configuration system is hierarchical. A higher level will typically only +set an option that a lower level hasn't configured: + +* board configuration: `mpconfigport.mk` +* pre-port user configuration: `user_pre_mpconfigport.mk` +* port configuration: `mpconfigport.mk` +* post-port user configuration: `user_post_mpconfigport.mk` +* global configuration: `py/circuitpython_mpconfig.mk` + +The board configuration is within the board-directory, e.g. +`ports/raspberrypi/boards/raspberry_pi_pico/`, the port configuration is +in the port-directory, e.g. `ports/raspberrypi/`. + +Editing these configuration files is the way to go if you want to change +the default behavior and ultimately create a pull-request. Otherwise, +changes should go into one of the user configuration files. + +User specific configurations are optional and should be maintained out of +tree. Passing `-I directory` tells make where to search for the additional +configuration files. E.g. to speed up boots by removing the wait-time for +the save-mode button press, you would: + +* create a directory: `mkdir -p ~/my_cp_config` +* create the config file: `echo 'CIRCUITPY_SKIP_SAFE_MODE_WAIT=0' > ~/my_cp_config/user_pre_mpconfigport.mk` +* run make with: `make -I ~/my_cp_config BOARD=raspberry_pi_pico` + +Besides the `user*mpconfigport.mk` files, there is another optional file +named `user_post_circuitpy_defns.mk`. This file is included at the end +and can be used to tweak compiler-definitions that are not covered by +one of the compile time options `CIRCUITPY_*`. + +Example: to create a build for the Pico2-W with an integrated saves-partition, +you would create a `user_post_circuitpy_defns.mk` with the following content: + + $(info ===> processing user_post_circuitpy_defns.mk) + ifeq (${BOARD},raspberry_pi_pico2_w) + CFLAGS += -DCIRCUITPY_SAVES_PARTITION_SIZE=1048576 + endif + ## Testing If you are working on changes to the core language, you might find it useful to run the test suite. diff --git a/LICENSE b/LICENSE index a9ba6ea5926..90d19f757b2 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2023 Damien P. George +Copyright (c) 2013-2025 Damien P. George Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -22,8 +22,6 @@ THE SOFTWARE. -------------------------------------------------------------------------------- -# CIRCUITPY-CHANGE: - Unless specified otherwise (see below), the above license and copyright applies to all files derived from MicroPython in this repository. diff --git a/LICENSE_MicroPython b/LICENSE_MicroPython index 469ae192739..1fad9b4134e 100644 --- a/LICENSE_MicroPython +++ b/LICENSE_MicroPython @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2024 Damien P. George +Copyright (c) 2013-2025 Damien P. George Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile b/Makefile index 30966918c36..3fc38581f9b 100644 --- a/Makefile +++ b/Makefile @@ -40,20 +40,30 @@ ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(BASEOPTS) # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(BASEOPTS) -TRANSLATE_SOURCES = extmod lib main.c ports/atmel-samd ports/cxd56 ports/espressif ports/mimxrt10xx ports/nordic ports/raspberrypi ports/stm py shared-bindings shared-module supervisor +TRANSLATE_SOURCES = extmod lib main.c ports/atmel-samd ports/analog ports/cxd56 ports/espressif ports/mimxrt10xx ports/nordic ports/raspberrypi ports/renode ports/stm ports/zephyr-cp py shared-bindings shared-module supervisor # Paths to exclude from TRANSLATE_SOURCES # Each must be preceded by "-path"; if any wildcards, enclose in quotes. # Separate by "-o" (Find's "or" operand) TRANSLATE_SOURCES_EXC = -path "ports/*/build-*" \ -o -path "ports/*/build" \ + -o -path ports/analog/msdk \ -o -path ports/atmel-samd/asf4 \ -o -path ports/cxd56/spresense-exported-sdk \ + -o -path ports/espressif/esp-camera \ -o -path ports/espressif/esp-idf \ + -o -path ports/espressif/esp-protocols \ -o -path ports/mimxrt10xx/sdk \ + -o -path ports/nordic/bluetooth \ + -o -path ports/nordic/nrfx \ + -o -path ports/raspberrypi/lib \ -o -path ports/raspberrypi/sdk \ + -o -path ports/stm/peripherals \ -o -path ports/stm/st_driver \ - -o -path lib/tinyusb \ - -o -path lib/lwip \ + -o -path ports/zephyr-cp/bootloader \ + -o -path ports/zephyr-cp/modules \ + -o -path ports/zephyr-cp/tools \ + -o -path ports/zephyr-cp/zephyr \ + -o -path lib \ -o -path extmod/ulab/circuitpython \ -o -path extmod/ulab/micropython \ @@ -226,8 +236,8 @@ pseudoxml: .PHONY: all-source all-source: -TRANSLATE_CHECK_SUBMODULES=if ! [ -f extmod/ulab/README.md ]; then python tools/ci_fetch_deps.py translate; fi -TRANSLATE_COMMAND=find $(TRANSLATE_SOURCES) -type d \( $(TRANSLATE_SOURCES_EXC) \) -prune -o -type f \( -iname "*.c" -o -iname "*.h" \) -print | (LC_ALL=C sort) | xgettext -x locale/synthetic.pot -f- -L C -s --add-location=file --keyword=MP_ERROR_TEXT -o - | sed -e '/"POT-Creation-Date: /d' +TRANSLATE_CHECK_SUBMODULES=if ! [ -f extmod/ulab/README.md ]; then $(PYTHON) tools/ci_fetch_deps.py translate; fi +TRANSLATE_COMMAND=find $(TRANSLATE_SOURCES) -type d \( $(TRANSLATE_SOURCES_EXC) \) -prune -o -type f \( -iname "*.c" -o -iname "*.h" \) -print | (LC_ALL=C sort) | xgettext -x locale/synthetic.pot -f- -L C --sort-by-file --add-location=file --keyword=MP_ERROR_TEXT -o - | sed -e '/"POT-Creation-Date: /d' locale/circuitpython.pot: all-source $(TRANSLATE_CHECK_SUBMODULES) $(TRANSLATE_COMMAND) > $@ @@ -245,7 +255,7 @@ translate: locale/circuitpython.pot # needed we preserve a rule to do it. .PHONY: msgmerge msgmerge: - for po in $(shell ls locale/*.po); do msgmerge -U $$po -s --no-fuzzy-matching --add-location=file locale/circuitpython.pot; done + for po in $(shell ls locale/*.po); do msgmerge -U $$po --sort-by-file --no-fuzzy-matching --add-location=file locale/circuitpython.pot; done merge-translate: git merge HEAD 1>&2 2> /dev/null; test $$? -eq 128 @@ -261,21 +271,21 @@ check-translate: .PHONY: stubs stubs: - @rm -rf circuitpython-stubs - @mkdir circuitpython-stubs - @$(PYTHON) tools/extract_pyi.py shared-bindings/ $(STUBDIR) - @$(PYTHON) tools/extract_pyi.py extmod/ulab/code/ $(STUBDIR)/ulab - @$(PYTHON) tools/extract_pyi.py ports/atmel-samd/bindings $(STUBDIR) - @$(PYTHON) tools/extract_pyi.py ports/espressif/bindings $(STUBDIR) - @$(PYTHON) tools/extract_pyi.py ports/raspberrypi/bindings $(STUBDIR) - @cp setup.py-stubs circuitpython-stubs/setup.py - @cp README.rst-stubs circuitpython-stubs/README.rst - @cp MANIFEST.in-stubs circuitpython-stubs/MANIFEST.in - @$(PYTHON) tools/board_stubs/build_board_specific_stubs/board_stub_builder.py - @cp -r tools/board_stubs/circuitpython_setboard circuitpython-stubs/circuitpython_setboard - @$(PYTHON) -m build circuitpython-stubs - @touch circuitpython-stubs/board/__init__.py - @touch circuitpython-stubs/board_definitions/__init__.py + rm -rf circuitpython-stubs + mkdir circuitpython-stubs + $(PYTHON) tools/extract_pyi.py shared-bindings/ $(STUBDIR) + $(PYTHON) tools/extract_pyi.py extmod/ulab/code/ $(STUBDIR)/ulab + for d in ports/*/bindings; do \ + $(PYTHON) tools/extract_pyi.py "$$d" $(STUBDIR); done + sed -e "s,__version__,`python -msetuptools_scm`," < setup.py-stubs > circuitpython-stubs/setup.py + cp README.rst-stubs circuitpython-stubs/README.rst + cp MANIFEST.in-stubs circuitpython-stubs/MANIFEST.in + cp -r stubs/* circuitpython-stubs + $(PYTHON) tools/board_stubs/build_board_specific_stubs/board_stub_builder.py + cp -r tools/board_stubs/circuitpython_setboard circuitpython-stubs/circuitpython_setboard + $(PYTHON) -m build circuitpython-stubs + touch circuitpython-stubs/board/__init__.py + touch circuitpython-stubs/board_definitions/__init__.py .PHONY: check-stubs check-stubs: stubs @@ -289,6 +299,9 @@ update-frozen-libraries: one-of-each: samd21 litex mimxrt10xx nordic stm +analog: + $(MAKE) -C ports/analog/ BOARD=apard32690 + samd21: $(MAKE) -C ports/atmel-samd BOARD=trinket_m0 @@ -362,5 +375,6 @@ coverage-fresh: make -j -C ports/unix VARIANT=coverage .PHONY: run-tests +# If TESTS="abc.py def.py" is specified as an arg, run only those tests. Otherwise, run all tests. run-tests: - cd tests; MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py + cd tests; MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py $(TESTS) diff --git a/README.rst b/README.rst index 6ef0d35333e..89c7d9229d8 100644 --- a/README.rst +++ b/README.rst @@ -136,6 +136,9 @@ Behavior - Adds a safe mode that does not run user code after a hard crash or brown out. This makes it possible to fix code that causes nasty crashes by making it available through mass storage after the crash. A reset (the button) is needed after it's fixed to get back into normal mode. +- A 1 second delay is added to the boot process during which time the status LED will flash, and + resetting the device or pressing the boot button will force the device into safe mode. This delay + can be removed by a compile time option (``CIRCUITPY_SKIP_SAFE_MODE_WAIT``). - Safe mode may be handled programmatically by providing a ``safemode.py``. ``safemode.py`` is run if the board has reset due to entering safe mode, unless the safe mode initiated by the user by pressing button(s). @@ -223,7 +226,7 @@ Ports Ports include the code unique to a microcontroller line. -The following ports are available: ``atmel-samd``, ``cxd56``, ``espressif``, ``litex``, ``mimxrt10xx``, ``nordic``, ``raspberrypi``, ``renode``, ``silabs`` (``efr32``), ``stm``, ``unix``. +The following ports are available: ``atmel-samd``, ``cxd56``, ``espressif``, ``litex``, ``mimxrt10xx``, ``nordic``, ``raspberrypi``, ``renode``, ``silabs`` (``efr32``), ``stm``, ``unix``, and ``zephyr-cp``. However, not all ports are fully functional. Some have limited functionality and known serious bugs. For details, refer to the **Port status** section in the `latest release `__ notes. diff --git a/conf.py b/conf.py index 7120fa3f00a..e2a8cbbd82f 100644 --- a/conf.py +++ b/conf.py @@ -32,17 +32,15 @@ from sphinx import addnodes from sphinx.ext import intersphinx -tools_describe = str(pathlib.Path(__file__).parent / "tools/describe") - # 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. -sys.path.insert(0, os.path.abspath('docs')) -sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath("docs")) +sys.path.insert(0, os.path.abspath(".")) import shared_bindings_matrix -master_doc = 'docs/index' +master_doc = "docs/index" # Grab the JSON values to use while building the module support matrix # in 'shared-bindings/index.rst' @@ -50,7 +48,7 @@ # The stubs must be built before we calculate the shared bindings matrix subprocess.check_output(["make", "stubs"]) -#modules_support_matrix = shared_bindings_matrix.support_matrix_excluded_boards() +# modules_support_matrix = shared_bindings_matrix.support_matrix_excluded_boards() modules_support_matrix = shared_bindings_matrix.support_matrix_by_board() modules_support_matrix_reverse = defaultdict(list) for board, matrix_info in modules_support_matrix.items(): @@ -58,55 +56,65 @@ modules_support_matrix_reverse[module].append(board) modules_support_matrix_reverse = dict( - (module, sorted(boards)) - for module, boards in modules_support_matrix_reverse.items() + (module, sorted(boards)) for module, boards in modules_support_matrix_reverse.items() ) html_context = { - 'support_matrix': modules_support_matrix, - 'support_matrix_reverse': modules_support_matrix_reverse + "support_matrix": modules_support_matrix, + "support_matrix_reverse": modules_support_matrix_reverse, } # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -needs_sphinx = '1.3' +needs_sphinx = "1.3" # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', + "sphinx.ext.autodoc", + "sphinx.ext.doctest", "sphinxcontrib.jquery", - 'sphinxcontrib.rsvgconverter', - 'sphinx.ext.intersphinx', - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx_search.extension', - 'rstjinja', - 'myst_parser', + "sphinxcontrib.rsvgconverter", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", + "sphinx.ext.coverage", + "sphinx_search.extension", + "rstjinja", + "myst_parser", ] # Add any paths that contain templates here, relative to this directory. -templates_path = ['templates', "docs/templates"] +templates_path = ["templates", "docs/templates"] # The suffix of source filenames. source_suffix = { - '.rst': 'restructuredtext', - '.md': 'markdown', + ".rst": "restructuredtext", + ".md": "markdown", } -extensions.append('autoapi.extension') +extensions.append("autoapi.extension") -autoapi_type = 'python' +autoapi_type = "python" # Uncomment this if debugging autoapi autoapi_keep_files = True -autoapi_dirs = [os.path.join('circuitpython-stubs', x) for x in os.listdir('circuitpython-stubs') if os.path.exists(os.path.join("circuitpython-stubs", x, "__init__.pyi"))] +autoapi_dirs = [ + os.path.join("circuitpython-stubs", x) + for x in os.listdir("circuitpython-stubs") + if os.path.exists(os.path.join("circuitpython-stubs", x, "__init__.pyi")) +] print("autoapi_dirs", autoapi_dirs) autoapi_add_toctree_entry = False -autoapi_options = ['members', 'undoc-members', 'private-members', 'show-inheritance', 'special-members', 'show-module-summary'] -autoapi_template_dir = 'docs/autoapi/templates' +autoapi_options = [ + "members", + "undoc-members", + "private-members", + "show-inheritance", + "special-members", + "show-module-summary", +] +autoapi_template_dir = "docs/autoapi/templates" autoapi_python_class_content = "both" autoapi_python_use_implicit_namespaces = True autoapi_root = "shared-bindings" @@ -117,23 +125,25 @@ # See https://github.com/sphinx-doc/sphinx/issues/12300 suppress_warnings = ["config.cache"] + def autoapi_prepare_jinja_env(jinja_env): - jinja_env.globals['support_matrix_reverse'] = modules_support_matrix_reverse + jinja_env.globals["support_matrix_reverse"] = modules_support_matrix_reverse + -redirects_file = 'docs/redirects.txt' +redirects_file = "docs/redirects.txt" # The encoding of source files. -#source_encoding = 'utf-8-sig' +# source_encoding = 'utf-8-sig' # The master toctree document. -#master_doc = 'index' +# master_doc = 'index' # Get current date (execution) for copyright year current_date = time.localtime() # General information about the project. -project = 'Adafruit CircuitPython' -copyright = f'2014-{current_date.tm_year}, MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)' +project = "Adafruit CircuitPython" +copyright = f"2014-{current_date.tm_year}, MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)" # These are overwritten on ReadTheDocs. # The version info for the project you're documenting, acts as replacement for @@ -145,15 +155,11 @@ def autoapi_prepare_jinja_env(jinja_env): final_version = "" git_describe = subprocess.run( - [tools_describe], - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - encoding="utf-8" + ["python", "py/version.py"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding="utf-8" ) if git_describe.returncode == 0: git_version = re.search( - r"^\d(?:\.\d){0,2}(?:\-(?:alpha|beta|rc)\.\d+){0,1}", - str(git_describe.stdout) + r"^\d(?:\.\d){0,2}(?:\-(?:alpha|beta|rc)\.\d+){0,1}", str(git_describe.stdout) ) if git_version: final_version = git_version[0] @@ -164,107 +170,58 @@ def autoapi_prepare_jinja_env(jinja_env): # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -#language = None +# language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: -#today = '' +# today = '' # Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' +# today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. -exclude_patterns = ["**/build*", - ".git", - ".github", - ".env", - ".venv", - ".direnv", - ".devcontainer/Readme.md", - "circuitpython-stubs", - "data", - "docs/autoapi", - "docs/README.md", - "drivers", - "examples", - "extmod", - "frozen", - "lib", - "main.c", - "mpy-cross", - "ports/*/*.c", - "ports/*/*.h", - "ports/*/boards", - "ports/*/common-hal", - "ports/*/supervisor", - "ports/atmel-samd/asf4", - "ports/atmel-samd/asf4_conf", - "ports/atmel-samd/external_flash", - "ports/atmel-samd/freetouch", - "ports/atmel-samd/peripherals", - "ports/atmel-samd/QTouch", - "ports/atmel-samd/tools", - "ports/broadcom/firmware", - "ports/broadcom/peripherals", - "ports/cxd56/mkspk", - "ports/cxd56/spresense-exported-sdk", - "ports/espressif/certificates", - "ports/espressif/esp-idf", - "ports/espressif/esp-camera", - "ports/espressif/esp-protocols", - "ports/espressif/.idf_tools", - "ports/espressif/peripherals", - "ports/litex/hw", - "ports/minimal", - "ports/mimxrt10xx/peripherals", - "ports/mimxrt10xx/sdk", - "ports/nordic/device", - "ports/nordic/bluetooth", - "ports/nordic/modules", - "ports/nordic/nrfx", - "ports/nordic/peripherals", - "ports/nordic/usb", - "ports/raspberrypi/sdk", - "ports/raspberrypi/lib", - "ports/silabs/gecko_sdk", - "ports/silabs/tools", - "ports/stm/st_driver", - "ports/stm/packages", - "ports/stm/peripherals", - "ports/stm/ref", - "py", - "shared/*", - "shared-bindings/util.*", - "shared-module", - "supervisor", - "tests", - "test-stubs", - "tools", - "circuitpython-stubs/README.rst"] +include_patterns = [ + # Top directory documentation + "*.rst", + "*.md", + # Docs inherited from microypython (but not templates or README.md, see below) + "docs/**", + # Module documentation + "shared-bindings/**", + "ports/*/bindings/**", + # Port READMEs in various formats + "ports/*/README*", +] +exclude_patterns = [ + "docs/autoapi/templates/**", + "docs/README.md", + "AGENTS.md", + "**/AGENTS.md", +] # The reST default role (used for this markup: `text`) to use for all # documents. -default_role = 'any' +default_role = "any" # If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True +# add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). -#add_module_names = True +# add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. -#show_authors = False +# show_authors = False # The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' +pygments_style = "sphinx" # A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] +# modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False +# keep_warnings = False # Global include files. Sphinx docs suggest using rst_epilog in preference # of rst_prolog, so we follow. Absolute paths below mean "from the base @@ -276,138 +233,141 @@ def autoapi_prepare_jinja_env(jinja_env): # -- Options for HTML output ---------------------------------------------- import sphinx_rtd_theme -html_theme = 'sphinx_rtd_theme' -html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.'] + +html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +# html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = ['.'] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". -#html_title = None +# html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None +# html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = '../../logo/trans-logo.png' +# html_logo = '../../logo/trans-logo.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -html_favicon = 'docs/static/favicon.ico' +html_favicon = "docs/static/favicon.ico" # 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 = ['docs/static'] +html_static_path = ["docs/static"] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. -#html_extra_path = [] +# html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. -html_last_updated_fmt = '%d %b %Y' +html_last_updated_fmt = "%d %b %Y" # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. -#html_use_smartypants = True +# html_use_smartypants = True # Custom sidebar templates, maps document names to template names. -#html_sidebars = {} +# html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. -#html_additional_pages = {"index": "topindex.html"} +# html_additional_pages = {"index": "topindex.html"} # If false, no module index is generated. -#html_domain_indices = True +# html_domain_indices = True # If false, no index is generated. -#html_use_index = True +# html_use_index = True # If true, the index is split into individual pages for each letter. -#html_split_index = False +# html_split_index = False # If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True +# html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True +# html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True +# html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. -#html_use_opensearch = '' +# html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None +# html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'CircuitPythondoc' +htmlhelp_basename = "CircuitPythondoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -# Include 3 levels of headers in PDF ToC -'preamble': r''' + # The paper size ('letterpaper' or 'a4paper'). + #'papersize': 'letterpaper', + # The font size ('10pt', '11pt' or '12pt'). + #'pointsize': '10pt', + # Additional stuff for the LaTeX preamble. + #'preamble': '', + # Include 3 levels of headers in PDF ToC + "preamble": r""" \setcounter{tocdepth}{2} \hbadness=99999 \hfuzz=20pt \usepackage{pdflscape} -''', +""", } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ("docs/pdf", 'CircuitPython.tex', 'CircuitPython Documentation', - 'CircuitPython Contributors', 'manual'), - # Uncomment this if you want to build a PDF of the board -> module support matrix. - # ("shared-bindings/support_matrix", 'SupportMatrix.tex', 'Board Support Matrix', - # 'CircuitPython Contributors', 'manual'), + ( + "docs/pdf", + "CircuitPython.tex", + "CircuitPython Documentation", + "CircuitPython Contributors", + "manual", + ), + # Uncomment this if you want to build a PDF of the board -> module support matrix. + # ("shared-bindings/support_matrix", 'SupportMatrix.tex', 'Board Support Matrix', + # 'CircuitPython Contributors', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +# latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -#latex_use_parts = False +# latex_use_parts = False # If true, show page references after internal links. -#latex_show_pagerefs = False +# latex_show_pagerefs = False # If true, show URL addresses after external links. -#latex_show_urls = False +# latex_show_urls = False # Documents to append as an appendix to all manuals. -#latex_appendices = [] +# latex_appendices = [] # If false, no module index is generated. -#latex_domain_indices = True +# latex_domain_indices = True # -- Options for manual page output --------------------------------------- @@ -415,12 +375,11 @@ def autoapi_prepare_jinja_env(jinja_env): # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - ('index', 'CircuitPython', 'CircuitPython Documentation', - ['CircuitPython contributors'], 1), + ("index", "CircuitPython", "CircuitPython Documentation", ["CircuitPython contributors"], 1), ] # If true, show URL addresses after external links. -#man_show_urls = False +# man_show_urls = False # -- Options for Texinfo output ------------------------------------------- @@ -429,29 +388,40 @@ def autoapi_prepare_jinja_env(jinja_env): # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'CircuitPython', 'CircuitPython Documentation', - 'CircuitPython contributors', 'CircuitPython', 'Python for Microcontrollers.', - 'Miscellaneous'), + ( + master_doc, + "CircuitPython", + "CircuitPython Documentation", + "CircuitPython contributors", + "CircuitPython", + "Python for Microcontrollers.", + "Miscellaneous", + ), ] # Documents to append as an appendix to all manuals. -#texinfo_appendices = [] +# texinfo_appendices = [] # If false, no module index is generated. -#texinfo_domain_indices = True +# texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' +# texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False +# texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {"python": ('https://docs.python.org/3/', None), - "register": ('https://circuitpython.readthedocs.io/projects/register/en/latest/', None), - "mcp2515": ('https://circuitpython.readthedocs.io/projects/mcp2515/en/latest/', None), - "typing": ('https://circuitpython.readthedocs.io/projects/adafruit-circuitpython-typing/en/latest/', None)} +intersphinx_mapping = { + "python": ("https://docs.python.org/3/", None), + "register": ("https://circuitpython.readthedocs.io/projects/register/en/latest/", None), + "mcp2515": ("https://circuitpython.readthedocs.io/projects/mcp2515/en/latest/", None), + "typing": ( + "https://circuitpython.readthedocs.io/projects/adafruit-circuitpython-typing/en/latest/", + None, + ), +} # Adapted from sphinxcontrib-redirects from sphinx.builders import html as builders @@ -469,20 +439,21 @@ def generate_redirects(app): return if not isinstance(app.builder, builders.StandaloneHTMLBuilder): - logging.warn("The 'sphinxcontib-redirects' plugin is only supported " - "by the 'html' builder and subclasses. Skipping...") - logging.warn(f"Builder is {app.builder.name} ({type(app.builder)})") + logging.warning( + "The 'sphinxcontib-redirects' plugin is only supported " + "by the 'html' builder and subclasses. Skipping..." + ) + logging.warning(f"Builder is {app.builder.name} ({type(app.builder)})") return with open(path) as redirects: for line in redirects.readlines(): - from_path, to_path = line.rstrip().split(' ') + from_path, to_path = line.rstrip().split(" ") logging.debug("Redirecting '%s' to '%s'" % (from_path, to_path)) from_path = os.path.splitext(from_path)[0] + ".html" - to_path_prefix = '..%s' % os.path.sep * ( - len(from_path.split(os.path.sep)) - 1) + to_path_prefix = "..%s" % os.path.sep * (len(from_path.split(os.path.sep)) - 1) to_path = to_path_prefix + to_path redirected_filename = os.path.join(app.builder.outdir, from_path) @@ -490,8 +461,9 @@ def generate_redirects(app): if not os.path.exists(redirected_directory): os.makedirs(redirected_directory) - with open(redirected_filename, 'w') as f: - f.write(TEMPLATE % urllib.parse.quote(to_path, '#/')) + with open(redirected_filename, "w") as f: + f.write(TEMPLATE % urllib.parse.quote(to_path, "#/")) + def adafruit_typing_workaround(app, env, node, contnode): # Sphinx marks a requesting node that uses circuitpython-typing @@ -547,7 +519,7 @@ def setup(app): app.add_css_file("customstyle.css") app.add_css_file("filter.css") app.add_js_file("filter.js") - app.add_config_value('redirects_file', 'redirects', 'env') - app.connect('builder-inited', generate_redirects) - app.connect('missing-reference', adafruit_typing_workaround) + app.add_config_value("redirects_file", "redirects", "env") + app.connect("builder-inited", generate_redirects) + app.connect("missing-reference", adafruit_typing_workaround) app.add_transform(CoreModuleTransform) diff --git a/data/nvm.toml b/data/nvm.toml index 6b678f15e37..a2a0c03c221 160000 --- a/data/nvm.toml +++ b/data/nvm.toml @@ -1 +1 @@ -Subproject commit 6b678f15e378edce820f2ffdef3286b3e55449e7 +Subproject commit a2a0c03c221a9bc37992147b5d4ad785a6e467fe diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c index fac7eb9f5fd..aaff47f42a6 100644 --- a/devices/ble_hci/common-hal/_bleio/Adapter.c +++ b/devices/ble_hci/common-hal/_bleio/Adapter.c @@ -29,7 +29,7 @@ #include "shared-bindings/_bleio/ScanEntry.h" #include "shared-bindings/time/__init__.h" -#if CIRCUITPY_OS_GETENV +#if CIRCUITPY_SETTINGS_TOML #include "shared-bindings/os/__init__.h" #endif @@ -259,9 +259,11 @@ static void _adapter_set_name(bleio_adapter_obj_t *self, mp_obj_str_t *name_obj) // Get various values and limits set by the adapter. // Set event mask. static void bleio_adapter_hci_init(bleio_adapter_obj_t *self) { + self->name = NULL; + mp_int_t name_len = 0; - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_SETTINGS_TOML mp_obj_t name = common_hal_os_getenv("CIRCUITPY_BLE_NAME", mp_const_none); if (name != mp_const_none) { mp_arg_validate_type_string(name, MP_QSTR_CIRCUITPY_BLE_NAME); @@ -950,7 +952,6 @@ void bleio_adapter_reset(bleio_adapter_obj_t *adapter) { } connection->connection_obj = mp_const_none; } - } void bleio_adapter_background(bleio_adapter_obj_t *adapter) { diff --git a/devices/ble_hci/common-hal/_bleio/Characteristic.c b/devices/ble_hci/common-hal/_bleio/Characteristic.c index a33b8ff4784..49b66d38e72 100644 --- a/devices/ble_hci/common-hal/_bleio/Characteristic.c +++ b/devices/ble_hci/common-hal/_bleio/Characteristic.c @@ -180,7 +180,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, } const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); - common_hal_bleio_check_connected(conn_handle); + bleio_check_connected(conn_handle); uint16_t cccd_value = (notify ? CCCD_NOTIFY : 0) | diff --git a/devices/ble_hci/common-hal/_bleio/Connection.h b/devices/ble_hci/common-hal/_bleio/Connection.h index 04edb104ddc..02a000501bf 100644 --- a/devices/ble_hci/common-hal/_bleio/Connection.h +++ b/devices/ble_hci/common-hal/_bleio/Connection.h @@ -61,6 +61,7 @@ typedef struct { uint8_t disconnect_reason; } bleio_connection_obj_t; +void bleio_check_connected(uint16_t conn_handle); uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self); mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *connection); bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle); diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c index 97626205a62..771a1509f39 100644 --- a/devices/ble_hci/common-hal/_bleio/PacketBuffer.c +++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.c @@ -247,3 +247,7 @@ void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { ringbuf_deinit(&self->ringbuf); } } + +bool common_hal_bleio_packet_buffer_connected(bleio_packet_buffer_obj_t *self) { + return !common_hal_bleio_packet_buffer_deinited(self) && self->conn_handle != BLE_CONN_HANDLE_INVALID; +} diff --git a/devices/ble_hci/common-hal/_bleio/PacketBuffer.h b/devices/ble_hci/common-hal/_bleio/PacketBuffer.h index 563f365d21b..4e001339fe3 100644 --- a/devices/ble_hci/common-hal/_bleio/PacketBuffer.h +++ b/devices/ble_hci/common-hal/_bleio/PacketBuffer.h @@ -28,4 +28,7 @@ typedef struct { bool packet_queued; } bleio_packet_buffer_obj_t; +// Unused, but needed for _common_hal_bleio_packet_buffer_construct() +typedef void *ble_event_handler_t; + void bleio_packet_buffer_update(bleio_packet_buffer_obj_t *self, mp_buffer_info_t *bufinfo); diff --git a/devices/ble_hci/common-hal/_bleio/__init__.c b/devices/ble_hci/common-hal/_bleio/__init__.c index 9663e706998..bfe39888753 100644 --- a/devices/ble_hci/common-hal/_bleio/__init__.c +++ b/devices/ble_hci/common-hal/_bleio/__init__.c @@ -30,7 +30,7 @@ bool vm_used_ble; // switch (sec_status) { // case BLE_GAP_SEC_STATUS_UNSPECIFIED: -// mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unspecified issue. Can be that the pairing prompt on the other device was declined or ignored.")); +// mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unspecified issue. The pairing request on the other device may have been declined or ignored.")); // return; // default: // mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unknown security error: 0x%04x"), sec_status); @@ -40,13 +40,13 @@ bool vm_used_ble; void common_hal_bleio_init(void) { } -void bleio_user_reset() { +void bleio_user_reset(void) { // HCI doesn't support the BLE workflow so just do a full reset. bleio_reset(); } // Turn off BLE on a reset or reload. -void bleio_reset() { +void bleio_reset(void) { // Create a UUID object for all CCCD's. cccd_uuid.base.type = &bleio_uuid_type; common_hal_bleio_uuid_construct(&cccd_uuid, BLE_UUID_CCCD, NULL); @@ -84,7 +84,7 @@ bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void) { return &common_hal_bleio_adapter_obj; } -void common_hal_bleio_check_connected(uint16_t conn_handle) { +void bleio_check_connected(uint16_t conn_handle) { if (conn_handle == BLE_CONN_HANDLE_INVALID) { mp_raise_ConnectionError(MP_ERROR_TEXT("Not connected")); } diff --git a/devices/ble_hci/common-hal/_bleio/att.c b/devices/ble_hci/common-hal/_bleio/att.c index 930b4793161..7e4a43aee97 100644 --- a/devices/ble_hci/common-hal/_bleio/att.c +++ b/devices/ble_hci/common-hal/_bleio/att.c @@ -136,6 +136,8 @@ static void send_error(uint16_t conn_handle, uint8_t opcode, uint16_t handle, ui .code = BT_ATT_OP_ERROR_RSP, }, { .request = opcode, + .handle = handle, + .error = code, }}; hci_send_acl_pkt(conn_handle, BT_L2CAP_CID_ATT, sizeof(rsp), (uint8_t *)&rsp); diff --git a/docs/environment.rst b/docs/environment.rst index ccfa9ff4863..4bf89bf774a 100644 --- a/docs/environment.rst +++ b/docs/environment.rst @@ -1,70 +1,91 @@ Environment Variables ===================== -CircuitPython 8.0.0 introduces support for environment variables. Environment -variables are commonly used to store "secrets" such as Wi-Fi passwords and API -keys. This method *does not* make them secure. It only separates them from the -code. +CircuitPython provides support for environment variables. These values +can be examined by user code, and are also used as settings by CircuitPython during startup. -CircuitPython uses a file called ``settings.toml`` at the drive root (no -folder) as the environment. User code can access the values from the file -using `os.getenv()`. It is recommended to save any values used repeatedly in a -variable because `os.getenv()` will parse the ``settings.toml`` file contents -on every access. +CircuitPython looks for a file called ``settings.toml`` at the **CIRCUITPY** drive root +to find the values of environment variables, +The file format is a subset of the `TOML config file language `__. -CircuitPython only supports a subset of the full toml specification, see below -for more details. The subset is very "Python-like", which is a key reason we -selected the format. +User code can access the values from the file using either `os.getenv()` or `supervisor.get_setting()` +The value returned by `os.getenv()` is always a string, but `supervisor.get_setting()` +will parse a value into a Python object: a string, an integer, a float, or a boolean. -Due to technical limitations it probably also accepts some files that are -not valid TOML files; bugs of this nature are subject to change (i.e., be -fixed) without the usual deprecation period for incompatible changes. +Both `os.getenv()` and `supervisor.get_setting()` +read and parse the ``settings.toml`` file on every access. +It will save time to copy any values you use repeatedly into variables. -File format example: +Environment variables are sometimes used to store "secrets" such as Wi-Fi passwords and API +keys. The ``settings.toml`` file *does not* make the secrets secure. It only separates them from the +code. -.. code-block:: +CircuitPython supports only a subset of the full TOML specification; see below for more details. +The subset is very "Python-like", which is a key reason the format was selected. +To make the code simpler, the implementation accepts some files that are +not valid TOML, but do not depend on this. - str_key="Hello world" # with trailing comment - int_key = 7 - unicode_key="œuvre" - unicode_key2="\\u0153uvre" # same as above - unicode_key3="\\U00000153uvre" # same as above - escape_codes="supported, including \\r\\n\\"\\\\" - # comment - [subtable] - subvalue="cannot retrieve this using getenv" +The full TOML specification provides for tables labeled with table names in brackets, like +``[table_name]``. +CircuitPython does not support this and ignores any explicit inline TOML tables. +Here is an example ``settings.toml`` file. +Entries consist of a key and value, separated by an ``=`` sign. +Upper and lower case may both be used in the key name. -Details of the toml language subset +.. code-block:: + + # Comment. + CIRCUITPY_WIFI_PASSWORD = "mypassword" + GREETING="Hello world" # trailing comments are ok + REPEAT_COUNT = 7 # an integer + CIRCUITPY_SDCARD_USB = false # a boolean + delay = 0.75 # a float + FRENCH="œuvre" # unicode can be used + FRENCH2="\u0153uvre" # same unicode string, using a 16-bit escape code + FRENCH3="\U00000153uvre" # same unicode string, using a 32-bit escape code + STRING_WITH_ESCAPE_CODES="supported, including \r \n \" \\" + +Details of the TOML language subset ----------------------------------- -* The content is required to be in UTF-8 encoding -* The supported data types are string and integer -* Only basic strings are supported, not triple-quoted strings -* Only integers supported by strtol. (no 0o, no 0b, no underscores 1_000, 011 - is 9, not 11) -* Only bare keys are supported +* The content must be in UTF-8 encoding +* The supported data types are strings, integers, floats, and booleans. +* Whitespace is allowed. +* Only basic strings are supported, not triple-quoted strings. +* Only integers supported by ``strtol()`` can be parsed: + no ``0o``, no ``0b``, no underscores ``1_000``, ``011`` is 9, not 11. +* Only bare keys are supported. * Duplicate keys are not diagnosed. -* Comments are supported -* Only values from the "root table" can be retrieved -* due to technical limitations, the content of multi-line - strings can erroneously be parsed as a value. +* Comments are allowed. +* Only values from the "root table" can be retrieved. + CircuitPython behavior ---------------------- -CircuitPython will also read the environment to configure its behavior. Other -keys are ignored by CircuitPython. Here are the keys it uses: +On startup, CircuitPython looks for for certain key/value pairs to use as configuration values. +Some values are read only once, after a hard reset, and others are read on each reload (ctrl-D in the REPL). +If you edit ``settings.toml`` and a reload doesn't read your changes, +then try a hard reset (a power cycle or pressing the reset button). +You can also include any other key/value pairs in the file for use with your own code. -Core CircuitPython keys -^^^^^^^^^^^^^^^^^^^^^^^ +Keys that affect CircuitPython behavior +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +CIRCUITPY_BLE_NAME (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If supplied, sets the BLE name the board advertises as, including for the BLE workflow. +Otherwise, defaults to ``CIRCUITPYxxxx``, where ``xxxx`` varies per board. + +CIRCUITPY_BLE_WORKFLOW (boolean) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If ``false``, disable the BLE workflow. Defaults to ``true``. If ``false``, +changing ``supervisor.runtime.ble_workflow`` has no effect. -CIRCUITPY_BLE_NAME -~~~~~~~~~~~~~~~~~~ -Default BLE name the board advertises as, including for the BLE workflow. -CIRCUITPY_HEAP_START_SIZE -~~~~~~~~~~~~~~~~~~~~~~~~~ +CIRCUITPY_HEAP_START_SIZE (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sets the initial size of the python heap, allocated from the outer heap. Must be a multiple of 4. The default is currently 8192. The python heap will grow by doubling and redoubling this initial size until it cannot fit in the outer heap. @@ -72,50 +93,172 @@ Larger values will reserve more RAM for python use and prevent the supervisor an from large allocations of their own. Smaller values will likely grow sooner than large start sizes. -CIRCUITPY_PYSTACK_SIZE -~~~~~~~~~~~~~~~~~~~~~~ +CIRCUITPY_PYSTACK_SIZE (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sets the size of the python stack. Must be a multiple of 4. The default value is currently 1536. Increasing the stack reduces the size of the heap available to python code. Used to avoid "Pystack exhausted" errors when the code can't be reworked to avoid it. -CIRCUITPY_WEB_API_PASSWORD -~~~~~~~~~~~~~~~~~~~~~~~~~~ +CIRCUITPY_WEB_API_PASSWORD (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Password required to make modifications to the board from the Web Workflow. +If the password is not specified, the Web Workflow is not enabled. -CIRCUITPY_WEB_API_PORT -~~~~~~~~~~~~~~~~~~~~~~ -TCP port number used for the web HTTP API. Defaults to 80 when omitted. +CIRCUITPY_WEB_API_PORT (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +TCP port number used for the Web Workflow HTTP API. Defaults to 80 when omitted. -CIRCUITPY_WEB_INSTANCE_NAME -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Name the board advertises as for the WEB workflow. Defaults to human readable board name if omitted. +CIRCUITPY_WEB_INSTANCE_NAME (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Human-friendly name the board advertises over mDNS for the Web Workflow. +Defaults to the human-readable board name if omitted. +This is not the hostname. + +CIRCUITPY_WIFI_SSID (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CIRCUITPY_WIFI_PASSWORD (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If these values are supplied, connects automatically to a local WiFi network +with the specified SSID and password before ``boot.py`` and/or ``code.py`` are run. -CIRCUITPY_WIFI_PASSWORD -~~~~~~~~~~~~~~~~~~~~~~~ -Wi-Fi password used to auto connect to CIRCUITPY_WIFI_SSID. +CIRCUITPY_WIFI_HOSTNAME (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If supplied, sets the initial ``wifi.radio.hostname`` to the given value. +Otherwise, the default value is ``cpy--``, +with some shortening for length if necessary. +If the supplied value is an invalid hostname or is too long, it is ignored. -CIRCUITPY_WIFI_SSID -~~~~~~~~~~~~~~~~~~~ -Wi-Fi SSID to auto-connect to even if user code is not running. +CIRCUITPY_SDCARD_USB (boolean) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Present a mounted SD card as a USB MSC device. If the board has default pins for an SD card socket, +the card is mounted automatically on startup. +Only one card can be presented. +Defaults to ``true``. +SD card presentation can slow down board startup, +so set this to ``false`` if you don't need this feature. -Additional board specific keys + +Additional board-specific keys ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -`MaTouch ESP32-S3 Parallel TFT with Touch 7“ `_ +CIRCUITPY_DISPLAY_WIDTH (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(Sunton, MaTouch boards) -CIRCUITPY_DISPLAY_WIDTH -~~~~~~~~~~~~~~~~~~~~~~~ Selects the correct screen resolution (1024x600 or 800x640) for the particular board variant. If the CIRCUITPY_DISPLAY_WIDTH parameter is set to a value of 1024 the display is initialized during power up at 1024x600 otherwise the display will be initialized at a resolution of 800x480. +`MaTouch ESP32-S3 Parallel TFT with Touch 7“ `_ `Sunton ESP32-2432S028 `_ +`Sunton ESP32-2432S024C `_ -CIRCUITPY_DISPLAY_ROTATION -~~~~~~~~~~~~~~~~~~~~~~~~~~ +CIRCUITPY_DISPLAY_ROTATION (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Selects the correct screen rotation (0, 90, 180 or 270) for the particular board variant. If the CIRCUITPY_DISPLAY_ROTATION parameter is set the display will be initialized during power up with the selected rotation, otherwise the display will be initialized with a rotation of 0. Attempting to initialize the screen with a rotation other than 0, 90, 180 or 270 is not supported and will result in an unexpected screen rotation. + +`Sunton ESP32-8048S050 `_ +`Adafruit Feather RP2350 `_ +`Adafruit Metro RP2350 `_ + +CIRCUITPY_DISPLAY_FREQUENCY (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Allows the entry of a display frequency used during the "dotclock" framebuffer construction. +If a valid frequency is not defined the board will initialize the framebuffer with a +frequency of 12500000hz (12.5Mhz). The value should be entered as an integer in hertz +i.e. CIRCUITPY_DISPLAY_FREQUENCY=16000000 will override the default value with a 16Mhz +display frequency. + +`Sunton ESP32-8048S050 `_ + + +CIRCUITPY_PICODVI_ENABLE (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Whether to configure the display at board initialization time, one of the following: + +.. code-block:: + + CIRCUITPY_PICODVI_ENABLE="detect" # when EDID EEPROM is detected (default) + CIRCUITPY_PICODVI_ENABLE="always" + CIRCUITPY_PICODVI_ENABLE="never" + +A display configured in this manner is available at ``supervisor.runtime.display`` +until it is released by ``displayio.release_displays()``. It does not appear at +``board.DISPLAY``. + +`Adafruit Feather RP2350 `_ +`Adafruit Metro RP2350 `_ + +CIRCUITPY_DISPLAY_WIDTH (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CIRCUITPY_DISPLAY_HEIGHT (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +CIRCUITPY_DISPLAY_COLOR_DEPTH (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(RP2350 boards with DVI or HSTX connector) + +Selects the desired resolution and color depth. + +Supported resolutions are: + * 640x480 with color depth 1, 2, 4 or 8 bits per pixel + * 320x240 with pixel doubling and color depth 8, 16, or 32 bits per pixel + * 360x200 with pixel doubling and color depth 8, 16, or 32 bits per pixel + +See :py:class:`picodvi.Framebuffer` for more details. + +The default value, if unspecified, is 360x200 16 bits per pixel if the connected +display is 1920x1080 or a multiple of it, otherwise 320x240 with 16 bits per pixel. + +If height is unspecified, it is set from the width. For example, a width of 640 +implies a height of 480. + +Example: Configure the display to 640x480 black and white (1 bit per pixel): + +.. code-block:: + + CIRCUITPY_DISPLAY_WIDTH=640 + CIRCUITPY_DISPLAY_COLOR_DEPTH=1 + +`Adafruit Feather RP2350 `_ +`Adafruit Metro RP2350 `_ + +CIRCUITPY_SAFEMODE_DELAY (float) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Wait for the specified amount of time, in seconds, for the user to press the reset button +to initiate safe mode after a hard reset. +The status LED blinks during this time. +If not specified, use the default delay, which is one second. + +CIRCUITPY_TERMINAL_SCALE (integer) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Allows the entry of a display scaling factor used during the terminalio console construction. +The entered scaling factor only affects the terminalio console and has no impact on +the UART, Web Workflow, BLE Workflow, etc consoles. + +This feature is not enabled on boards that the CIRCUITPY_SETTINGS_TOML (or CIRCUITPY_FULL_BUILD) +flag has been set to 0. Currently this is primarily boards with limited flash including some +of the Atmel_samd boards based on the SAMD21/M0 microprocessor. + +CIRCUITPY_TERMINAL_FONT (string) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Specifies a custom font file path to use for the terminalio console instead of the default +``/fonts/terminal.lvfontbin``. This allows users to create and use custom fonts for the +CircuitPython console. + +This feature requires both CIRCUITPY_SETTINGS_TOML and CIRCUITPY_LVFONTIO to be enabled. + +Example: + +.. code-block:: + + CIRCUITPY_TERMINAL_FONT="/fonts/myfont.lvfontbin" + +`boards that the terminalio core module is available on `_ diff --git a/docs/library/array.rst b/docs/library/array.rst index a7a3b5952e1..63b86a806c3 100644 --- a/docs/library/array.rst +++ b/docs/library/array.rst @@ -19,6 +19,10 @@ Classes array are given by an `iterable`. If it is not provided, an empty array is created. + In addition to the methods below, array objects also implement the buffer + protocol. This means the contents of the entire array can be accessed as raw + bytes via a `memoryview` or other interfaces which use this protocol. + .. method:: append(val) Append new element ``val`` to the end of array, growing it. diff --git a/docs/library/binascii.rst b/docs/library/binascii.rst index 1eba46652d7..0797692b020 100644 --- a/docs/library/binascii.rst +++ b/docs/library/binascii.rst @@ -39,6 +39,6 @@ Functions .. function:: crc32(data, value=0, /) - Compute CRC-32, the 32-bit checksum of the bytes in *data* starting with an + Compute CRC-32, the 32-bit checksum of the bytes in ``data`` starting with an initial CRC of *value*. The default initial CRC is 0. The algorithm is consistent with the ZIP file checksum. diff --git a/docs/library/builtins.rst b/docs/library/builtins.rst index 6003c23fb13..148c1513f3d 100644 --- a/docs/library/builtins.rst +++ b/docs/library/builtins.rst @@ -31,6 +31,8 @@ Functions and types .. class:: bytearray() + |see_cpython| `python:bytearray`. + .. class:: bytes() |see_cpython| `python:bytes`. @@ -86,15 +88,9 @@ Functions and types .. class:: int() - .. classmethod:: from_bytes(bytes, byteorder) - - In CircuitPython, the ``byteorder`` parameter must be positional (this is - compatible with CPython). - - .. method:: to_bytes(size, byteorder) + .. classmethod:: from_bytes(bytes, byteorder="big", *, signed=False) - In CircuitPython, the ``byteorder`` parameter must be positional (this is - compatible with CPython). + .. method:: to_bytes(length=1, byteorder="big", *, signed=False) .. function:: isinstance() diff --git a/docs/library/collections.rst b/docs/library/collections.rst index b006a97dcaf..c3ec763d20e 100644 --- a/docs/library/collections.rst +++ b/docs/library/collections.rst @@ -109,3 +109,19 @@ Classes a 2 w 5 b 3 + + .. method:: OrderedDict.popitem() + + Remove and return a (key, value) pair from the dictionary. + Pairs are returned in LIFO order. + + .. admonition:: Difference to CPython + :class: attention + + ``OrderedDict.popitem()`` does not support the ``last=False`` argument and + will always remove and return the last item if present. + + A workaround for this is to use ``pop()`` to remove the first item:: + + first_key = next(iter(d)) + d.pop(first_key) diff --git a/docs/library/errno.rst b/docs/library/errno.rst index 61970291df5..10ecd4d2c79 100644 --- a/docs/library/errno.rst +++ b/docs/library/errno.rst @@ -7,7 +7,7 @@ |see_cpython_module| :mod:`python:errno`. This module provides access to symbolic error codes for `OSError` exception. -The codes available may vary per CircuitPython build. +Some codes are not available on the smallest CircuitPython builds, such as SAMD21, for space reasons. Constants --------- diff --git a/docs/library/index.rst b/docs/library/index.rst index 18b2530a9b5..4e763e8a27e 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -33,8 +33,8 @@ These libraries are not currently enabled in any CircuitPython build, but may be json.rst platform.rst re.rst - sys.rst select.rst + sys.rst Omitted ``string`` functions ---------------------------- @@ -54,4 +54,4 @@ the following libraries. .. toctree:: :maxdepth: 1 - micropython.rst + ../../shared-bindings/micropython/index.rst diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst deleted file mode 100644 index 166192de3a3..00000000000 --- a/docs/library/micropython.rst +++ /dev/null @@ -1,28 +0,0 @@ -:mod:`micropython` -- MicroPython extensions and internals -========================================================== - -.. module:: micropython - :synopsis: access and control MicroPython internals - -Functions ---------- - -.. function:: const(expr) - - Used to declare that the expression is a constant so that the compiler can - optimise it. The use of this function should be as follows:: - - from micropython import const - - CONST_X = const(123) - CONST_Y = const(2 * CONST_X + 1) - - Constants declared this way are still accessible as global variables from - outside the module they are declared in. On the other hand, if a constant - begins with an underscore then it is hidden, it is not available as a global - variable, and does not take up any memory during execution. - - This `const` function is recognised directly by the MicroPython parser and is - provided as part of the :mod:`micropython` module mainly so that scripts can be - written which run under both CPython and MicroPython, by following the above - pattern. diff --git a/docs/library/platform.rst b/docs/library/platform.rst index c091477d84c..c19ef0f5df5 100644 --- a/docs/library/platform.rst +++ b/docs/library/platform.rst @@ -36,3 +36,11 @@ Functions Returns a tuple of strings *(lib, version)*, where *lib* is the name of the libc that MicroPython is linked to, and *version* the corresponding version of this libc. + +.. function:: processor() + + Returns a string with a detailed name of the processor, if one is available. + If no name for the processor is known, it will return an empty string + instead. + + This is currently available only on RISC-V targets (both 32 and 64 bits). diff --git a/docs/library/re.rst b/docs/library/re.rst index 19b15d2d2c2..b8aeefd90cf 100644 --- a/docs/library/re.rst +++ b/docs/library/re.rst @@ -154,8 +154,8 @@ Regex objects Compiled regular expression. Instances of this class are created using `re.compile()`. -.. method:: regex.match(string) - regex.search(string) +.. method:: regex.match(string, [pos, [endpos]]) + regex.search(string, [pos, [endpos]]) regex.sub(replace, string, count=0, flags=0, /) Similar to the module-level functions :meth:`match`, :meth:`search` @@ -163,6 +163,16 @@ Compiled regular expression. Instances of this class are created using Using methods is (much) more efficient if the same regex is applied to multiple strings. + The optional second parameter *pos* gives an index in the string where the + search is to start; it defaults to ``0``. This is not completely equivalent + to slicing the string; the ``'^'`` pattern character matches at the real + beginning of the string and at positions just after a newline, but not + necessarily at the index where the search is to start. + + The optional parameter *endpos* limits how far the string will be searched; + it will be as if the string is *endpos* characters long, so only the + characters from *pos* to ``endpos - 1`` will be searched for a match. + .. method:: regex.split(string, max_split=-1, /) Split a *string* using regex. If *max_split* is given, it specifies diff --git a/docs/library/sys.rst b/docs/library/sys.rst index 8def36a2b07..c9c687df359 100644 --- a/docs/library/sys.rst +++ b/docs/library/sys.rst @@ -12,17 +12,9 @@ Functions .. function:: exit(retval=0, /) Terminate current program with a given exit code. Underlyingly, this - function raise as `SystemExit` exception. If an argument is given, its + function raises a `SystemExit` exception. If an argument is given, its value given as an argument to `SystemExit`. -.. function:: print_exception(exc, file=sys.stdout, /) - - This function is deprecated and will be removed starting in - CircuitPython 10.x, `traceback.print_exception()` should be used instead. - - Print exception with a traceback to a file-like object *file* (or - `sys.stdout` by default). - .. admonition:: Difference to CPython :class: attention @@ -52,6 +44,8 @@ Constants * *version* - tuple (major, minor, micro), e.g. (1, 7, 0) * *_machine* - string describing the underlying machine * *_mpy* - supported mpy file-format version (optional attribute) + * *_build* - string that can help identify the configuration that + MicroPython was built with This object is the recommended way to distinguish CircuitPython from other Python implementations (note that it still may not exist in the very @@ -116,15 +110,15 @@ Constants .. data:: stderr - Standard error ``stream``. + Standard error `stream`. .. data:: stdin - Standard input ``stream``. + Standard input `stream`. .. data:: stdout - Standard output ``stream``. + Standard output `stream`. .. data:: version diff --git a/docs/porting.rst b/docs/porting.rst index f4ed2ab4cc8..9cb28b7e5d4 100644 --- a/docs/porting.rst +++ b/docs/porting.rst @@ -72,6 +72,7 @@ as a natural "TODO" list. An example minimal build list is shown below: CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_I2CTARGET = 0 + CIRCUITPY_SPITARGET = 0 # Requires SPI, PulseIO (stub ok): CIRCUITPY_DISPLAYIO = 0 diff --git a/docs/redirects.txt b/docs/redirects.txt index 1016d0bd70b..b2d4b5621fb 100644 --- a/docs/redirects.txt +++ b/docs/redirects.txt @@ -1,4 +1,5 @@ index.rst README.html +docs/library/micropython.rst shared-bindings/micropython shared-bindings//__init__.rst shared-bindings// shared-bindings/_bleio/Adapter.rst shared-bindings/_bleio/#_bleio.Adapter shared-bindings/_bleio/Address.rst shared-bindings/_bleio/#_bleio.Address diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 9e9330de4cc..391dc307d23 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -186,6 +186,13 @@ Glossary Most MicroPython boards make a REPL available over a UART, and this is typically accessible on a host PC via USB. + small integer + MicroPython optimises the internal representation of integers such that + "small" values do not take up space on the heap, and calculations with + them do not require heap allocation. On most 32-bit ports, this + corresponds to values in the interval ``-2**30 <= x < 2**30``, but this + should be considered an implementation detail and not relied upon. + stream Also known as a "file-like object". A Python object which provides sequential read-write access to the underlying data. A stream object diff --git a/docs/rstjinja.py b/docs/rstjinja.py index 7d5fff5c6c3..ab940dc7134 100644 --- a/docs/rstjinja.py +++ b/docs/rstjinja.py @@ -3,11 +3,13 @@ import re + def render_with_jinja(docname, source): - if re.search('^\s*.. jinja$', source[0], re.M): + if re.search(r"^\s*.. jinja$", source[0], re.M): return True return False + def rstjinja(app, docname, source): """ Render our pages as a jinja template for fancy templating goodness. @@ -24,18 +26,19 @@ def rstjinja(app, docname, source): print(f"rendering {docname} as jinja templates") if app.builder.format == "html": - rendered = app.builder.templates.render_string( - src, app.config.html_context - ) + rendered = app.builder.templates.render_string(src, app.config.html_context) else: from sphinx.util.template import BaseRenderer + renderer = BaseRenderer() - rendered = renderer.render_string( - src, - app.config.html_context - ) + rendered = renderer.render_string(src, app.config.html_context) source[0] = rendered + def setup(app): app.connect("source-read", rstjinja) + return { + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/docs/shared_bindings_matrix.py b/docs/shared_bindings_matrix.py index f4b430111eb..2f9eb796788 100644 --- a/docs/shared_bindings_matrix.py +++ b/docs/shared_bindings_matrix.py @@ -26,11 +26,12 @@ import pathlib import re import subprocess - +import tomllib from concurrent.futures import ThreadPoolExecutor SUPPORTED_PORTS = [ + "analog", "atmel-samd", "broadcom", "cxd56", @@ -42,6 +43,7 @@ "renode", "silabs", "stm", + "zephyr-cp", ] ALIASES_BY_BOARD = { @@ -56,8 +58,7 @@ ALIASES_BRAND_NAMES = { "circuitplayground_express_4h": "Adafruit Circuit Playground Express 4-H", - "circuitplayground_express_digikey_pycon2019": - "Circuit Playground Express Digi-Key PyCon 2019", + "circuitplayground_express_digikey_pycon2019": "Circuit Playground Express Digi-Key PyCon 2019", "edgebadge": "Adafruit EdgeBadge", "pyportal_pynt": "Adafruit PyPortal Pynt", "gemma_m0_pycon2018": "Adafruit Gemma M0 PyCon 2018", @@ -65,6 +66,8 @@ ADDITIONAL_MODULES = { "_asyncio": "MICROPY_PY_ASYNCIO", + "_bleio (native)": "CIRCUITPY_BLEIO_NATIVE", + "_bleio (HCI co-processor)": "CIRCUITPY_BLEIO_HCI", "_eve": "CIRCUITPY__EVE", "adafruit_bus_device": "CIRCUITPY_BUSDEVICE", "adafruit_pixelbuf": "CIRCUITPY_PIXELBUF", @@ -81,8 +84,9 @@ "keypad.Keys": "CIRCUITPY_KEYPAD_KEYS", "keypad.ShiftRegisterKeys": "CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS", "keypad_demux.DemuxKeyMatrix": "CIRCUITPY_KEYPAD_DEMUX", - "os.getenv": "CIRCUITPY_OS_GETENV", + "os.getenv": "CIRCUITPY_SETTINGS_TOML", "select": "MICROPY_PY_SELECT_SELECT", + "supervisor.get_setting": "CIRCUITPY_SETTINGS_TOML", "sys": "CIRCUITPY_SYS", "terminalio": "CIRCUITPY_DISPLAYIO", "usb": "CIRCUITPY_PYUSB", @@ -117,8 +121,12 @@ def get_bindings(): bindings_modules = [] for d in get_circuitpython_root_dir().glob("ports/*/bindings"): bindings_modules.extend(module.name for module in d.iterdir() if d.is_dir()) - return shared_bindings_modules + bindings_modules + MODULES_NOT_IN_BINDINGS + \ - list(ADDITIONAL_MODULES.keys()) + return ( + shared_bindings_modules + + bindings_modules + + MODULES_NOT_IN_BINDINGS + + list(ADDITIONAL_MODULES.keys()) + ) def get_board_mapping(): @@ -129,14 +137,21 @@ def get_board_mapping(): boards = {} for port in SUPPORTED_PORTS: board_path = root_dir / "ports" / port / "boards" - for board_path in os.scandir(board_path): + # Zephyr port has vendor specific subdirectories to match zephyr (and + # clean up the boards folder.) + g = "*/*" if port == "zephyr-cp" else "*" + for board_path in board_path.glob(g): if board_path.is_dir(): board_id = board_path.name + if port == "zephyr-cp": + vendor = board_path.parent.name + board_id = f"{vendor}_{board_id}" aliases = ALIASES_BY_BOARD.get(board_path.name, []) boards[board_id] = { "port": port, "download_count": 0, "aliases": aliases, + "directory": board_path, } for alias in aliases: boards[alias] = { @@ -144,6 +159,7 @@ def get_board_mapping(): "download_count": 0, "alias": True, "aliases": [], + "directory": board_path, } return boards @@ -178,16 +194,25 @@ def get_settings_from_makefile(port_dir, board_name): This list must explicitly include any setting queried by tools/ci_set_matrix.py. """ - if os.getenv('NO_BINDINGS_MATRIX'): - return { - 'CIRCUITPY_BUILD_EXTENSIONS': '.bin' - } + if os.getenv("NO_BINDINGS_MATRIX"): + return {"CIRCUITPY_BUILD_EXTENSIONS": ".bin"} contents = subprocess.run( - ["make", "-C", port_dir, "-f", "Makefile", f"BOARD={board_name}", - "print-CFLAGS", "print-CIRCUITPY_BUILD_EXTENSIONS", - "print-FROZEN_MPY_DIRS", "print-SRC_PATTERNS", - "print-SRC_SUPERVISOR"], + [ + "make", + # Don't let make run in parallel; it can mix up the output from the various "print-" targets. + "-j1", + "-C", + port_dir, + "-f", + "Makefile", + f"BOARD={board_name}", + "print-CFLAGS", + "print-CIRCUITPY_BUILD_EXTENSIONS", + "print-FROZEN_MPY_DIRS", + "print-SRC_PATTERNS", + "print-SRC_SUPERVISOR", + ], encoding="utf-8", errors="replace", stdout=subprocess.PIPE, @@ -203,8 +228,8 @@ def get_settings_from_makefile(port_dir, board_name): settings = {} for line in contents.stdout.split("\n"): - if line.startswith('CFLAGS ='): - for m in re.findall(r'-D([A-Z][A-Z0-9_]*)=(\d+)', line): + if line.startswith("CFLAGS ="): + for m in re.findall(r"-D([A-Z][A-Z0-9_]*)=(\d+)", line): settings[m[0]] = m[1] elif m := re.match(r"^([A-Z][A-Z0-9_]*) = (.*)$", line): settings[m.group(1)] = m.group(2) @@ -249,11 +274,13 @@ def get_repository_url(directory): repository_urls[directory] = path return path + def remove_prefix(s, prefix): if not s.startswith(prefix): raise ValueError(f"{s=} does not start with {prefix=}") return s.removeprefix(prefix) + def frozen_modules_from_dirs(frozen_mpy_dirs, withurl): """ Go through the list of frozen directories and extract the python modules. @@ -265,7 +292,7 @@ def frozen_modules_from_dirs(frozen_mpy_dirs, withurl): """ frozen_modules = [] for frozen_path in filter(lambda x: x, frozen_mpy_dirs.split(" ")): - frozen_path = remove_prefix(frozen_path, '../../') + frozen_path = remove_prefix(frozen_path, "../../") source_dir = get_circuitpython_root_dir() / frozen_path url_repository = get_repository_url(source_dir) for sub in source_dir.glob("*"): @@ -294,67 +321,72 @@ def lookup_setting(settings, key, default=""): return value -def all_ports_all_boards(ports=SUPPORTED_PORTS): - for port in ports: - port_dir = get_circuitpython_root_dir() / "ports" / port - for entry in (port_dir / "boards").iterdir(): - if not entry.is_dir(): - continue - yield (port, entry) - - -def support_matrix_by_board(use_branded_name=True, withurl=True, - add_port=False, add_chips=False, - add_pins=False, add_branded_name=False): +def support_matrix_by_board( + use_branded_name=True, + withurl=True, + add_port=False, + add_chips=False, + add_pins=False, + add_branded_name=False, +): """Compiles a list of the available core modules available for each board. """ base = build_module_map() def support_matrix(arg): - port, entry = arg - port_dir = get_circuitpython_root_dir() / "ports" / port - settings = get_settings_from_makefile(str(port_dir), entry.name) + board_id, board_info = arg + port = board_info["port"] + board_directory = board_info["directory"] + port_dir = board_directory.parent.parent + if port != "zephyr-cp": + settings = get_settings_from_makefile(str(port_dir), board_directory.name) + autogen_board_info = None + else: + circuitpython_toml_fn = board_directory / "circuitpython.toml" + with circuitpython_toml_fn.open("rb") as f: + settings = tomllib.load(f) + + autogen_board_info_fn = board_directory / "autogen_board_info.toml" + with autogen_board_info_fn.open("rb") as f: + autogen_board_info = tomllib.load(f) if use_branded_name or add_branded_name: - with open(entry / "mpconfigboard.h") as get_name: - board_contents = get_name.read() - board_name_re = re.search( - r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)", board_contents - ) - if board_name_re: - branded_name = board_name_re.group(1).strip('"') - if '"' in branded_name: # sometimes the closing " is not at line end - branded_name = branded_name[:branded_name.index('"')] - board_name = branded_name + if autogen_board_info: + branded_name = autogen_board_info["name"] + else: + with open(board_directory / "mpconfigboard.h") as get_name: + board_contents = get_name.read() + board_name_re = re.search(r"(?<=MICROPY_HW_BOARD_NAME)\s+(.+)", board_contents) + if board_name_re: + branded_name = board_name_re.group(1).strip('"') + if '"' in branded_name: # sometimes the closing " is not at line end + branded_name = branded_name[: branded_name.index('"')] + board_name = branded_name if use_branded_name: board_name = branded_name else: - board_name = entry.name + board_name = board_id if add_chips: - with open(entry / "mpconfigboard.h") as get_name: + with open(board_directory / "mpconfigboard.h") as get_name: board_contents = get_name.read() - mcu_re = re.search( - r'(?<=MICROPY_HW_MCU_NAME)\s+(.+)', board_contents - ) + mcu_re = re.search(r"(?<=MICROPY_HW_MCU_NAME)\s+(.+)", board_contents) if mcu_re: mcu = mcu_re.group(1).strip('"') if '"' in mcu: # in case the closing " is not at line end - mcu = mcu[:mcu.index('"')] + mcu = mcu[: mcu.index('"')] else: mcu = "" - with open(entry / "mpconfigboard.mk") as get_name: + with open(board_directory / "mpconfigboard.mk") as get_name: board_contents = get_name.read() - flash_re = re.search( - r'(?<=EXTERNAL_FLASH_DEVICES)\s+=\s+(.+)', board_contents - ) + flash_re = re.search(r"(?<=EXTERNAL_FLASH_DEVICES)\s+=\s+(.+)", board_contents) if flash_re: # deal with the variability in the way multiple flash chips # are denoted. We want them to end up as a quoted, # comma separated string - flash = flash_re.group(1).replace('"','') + flash = flash_re.group(1).replace('"', "") flash = f'"{flash}"' else: flash = "" @@ -362,7 +394,7 @@ def support_matrix(arg): if add_pins: pins = [] try: - with open(entry / "pins.c") as get_name: + with open(board_directory / "pins.c") as get_name: pin_lines = get_name.readlines() except FileNotFoundError: # silabs boards have no pins.c pass @@ -375,35 +407,38 @@ def support_matrix(arg): pins.append((board_pin, chip_pin)) board_modules = [] - for module in base: - key = base[module]["key"] - if int(lookup_setting(settings, key, "0")): - board_modules.append(base[module]["name"]) + if autogen_board_info: + autogen_modules = autogen_board_info["modules"] + for k in autogen_modules: + if autogen_modules[k]: + board_modules.append(k) + else: + for module in base: + key = base[module]["key"] + if int(lookup_setting(settings, key, "0")): + board_modules.append(base[module]["name"]) board_modules.sort() if "CIRCUITPY_BUILD_EXTENSIONS" in settings: - board_extensions = [ - extension.strip() - for extension in settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",") - ] + board_extensions = settings["CIRCUITPY_BUILD_EXTENSIONS"] + if isinstance(board_extensions, str): + board_extensions = [extension.strip() for extension in board_extensions.split(",")] else: raise OSError(f"Board extensions undefined: {board_name}.") frozen_modules = [] if "FROZEN_MPY_DIRS" in settings: - frozen_modules = frozen_modules_from_dirs( - settings["FROZEN_MPY_DIRS"], withurl - ) + frozen_modules = frozen_modules_from_dirs(settings["FROZEN_MPY_DIRS"], withurl) if frozen_modules: frozen_modules.sort() # generate alias boards too board_info = { - "modules": board_modules, - "frozen_libraries": frozen_modules, - "extensions": board_extensions, - } + "modules": board_modules, + "frozen_libraries": frozen_modules, + "extensions": board_extensions, + } if add_branded_name: board_info["branded_name"] = branded_name if add_port: @@ -413,14 +448,9 @@ def support_matrix(arg): board_info["flash"] = flash if add_pins: board_info["pins"] = pins - board_matrix = [ - ( - board_name, - board_info - ) - ] - if entry.name in ALIASES_BY_BOARD: - for alias in ALIASES_BY_BOARD[entry.name]: + board_matrix = [(board_name, board_info)] + if board_id in ALIASES_BY_BOARD: + for alias in ALIASES_BY_BOARD[board_id]: if use_branded_name: if alias in ALIASES_BRAND_NAMES: alias = ALIASES_BRAND_NAMES[alias] @@ -430,7 +460,7 @@ def support_matrix(arg): "modules": board_modules, "frozen_libraries": frozen_modules, "extensions": board_extensions, - } + } if add_branded_name: board_info["branded_name"] = branded_name if add_port: @@ -440,22 +470,20 @@ def support_matrix(arg): board_info["flash"] = flash if add_pins: board_info["pins"] = pins - board_matrix.append( - ( - alias, - board_info - ) - ) + board_matrix.append((alias, board_info)) return board_matrix # this is now a list of (board,modules) + board_mapping = get_board_mapping() + real_boards = [] + for board in board_mapping: + if not board_mapping[board].get("alias", False): + real_boards.append((board, board_mapping[board])) executor = ThreadPoolExecutor(max_workers=os.cpu_count()) - mapped_exec = executor.map(support_matrix, all_ports_all_boards()) + mapped_exec = executor.map(support_matrix, real_boards) # flatmap with comprehensions boards = dict( - sorted( - [board for matrix in mapped_exec for board in matrix], key=lambda x: x[0] - ) + sorted([board for matrix in mapped_exec for board in matrix], key=lambda x: x[0]) ) return boards diff --git a/docs/supported_ports.rst b/docs/supported_ports.rst index 69eaa5ef148..ca36999f423 100644 --- a/docs/supported_ports.rst +++ b/docs/supported_ports.rst @@ -12,6 +12,7 @@ Additional testing is limited. .. toctree:: :maxdepth: 2 + ../ports/analog/README ../ports/atmel-samd/README ../ports/broadcom/README ../ports/cxd56/README @@ -24,3 +25,4 @@ Additional testing is limited. ../ports/silabs/README ../ports/stm/README ../ports/unix/README + ../ports/zephyr-cp/README diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index 7fad2aac181..d505ff09ef0 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -7,22 +7,22 @@ variety of errors that can happen, what they mean and how to fix them. File system issues ------------------ -If your host computer starts complaining that your ``CIRCUITPY`` drive is corrupted +If your host computer starts complaining that your **CIRCUITPY** drive is corrupted or files cannot be overwritten or deleted, then you will have to erase it completely. -When CircuitPython restarts it will create a fresh empty ``CIRCUITPY`` filesystem. +When CircuitPython restarts it will create a fresh empty **CIRCUITPY** filesystem. -Corruption often happens on Windows when the ``CIRCUITPY`` disk is not safely ejected +Corruption often happens on Windows when the **CIRCUITPY** disk is not safely ejected before being reset by the button or being disconnected from USB. This can also happen on Linux and Mac OSX but it's less likely. -.. caution:: To erase and re-create ``CIRCUITPY`` (for example, to correct a corrupted filesystem), +.. caution:: To erase and re-create **CIRCUITPY** (for example, to correct a corrupted filesystem), follow one of the procedures below. It's important to note that **any files stored on the** - ``CIRCUITPY`` **drive will be erased. Back up your code if possible before continuing!** + **CIRCUITPY** **drive will be erased. Back up your code if possible before continuing!** REPL Erase Method ^^^^^^^^^^^^^^^^^ This is the recommended method of erasing your board. If you are having trouble accessing the -``CIRCUITPY`` drive or the REPL, consider first putting your board into +**CIRCUITPY** drive or the REPL, consider first putting your board into `safe mode `_. **To erase any board if you have access to the REPL:** @@ -30,7 +30,7 @@ This is the recommended method of erasing your board. If you are having trouble #. Connect to the CircuitPython REPL using a terminal program. #. Type ``import storage`` into the REPL. #. Then, type ``storage.erase_filesystem()`` into the REPL. -#. The ``CIRCUITPY`` drive will be erased and the board will restart with an empty ``CIRCUITPY`` drive. +#. The **CIRCUITPY** drive will be erased and the board will restart with an empty **CIRCUITPY** drive. Erase File Method ^^^^^^^^^^^^^^^^^ diff --git a/docs/workflows.md b/docs/workflows.md index 727cc5401ca..ad676d5678e 100644 --- a/docs/workflows.md +++ b/docs/workflows.md @@ -4,11 +4,11 @@ Workflows are the process used to 1) manipulate files on the CircuitPython devic with the serial connection to CircuitPython. The serial connection is usually used to access the REPL. -Starting with CircuitPython 3.x we moved to a USB-only workflow. Prior to that, we used the serial -connection alone to do the whole workflow. In CircuitPython 7.x, a BLE workflow was added with the -advantage of working with mobile devices. CircuitPython 8.x added a web workflow that works over the -local network (usually Wi-Fi) and a web browser. Other clients can also use the Web REST API. Boards -should clearly document which workflows are supported. +CircuitPython started with a USB mass storage device workflow for filesystem operations. +CircuitPython 7.x added a BLE workflow with the advantage of working with mobile devices. +CircuitPython 8.x added a web workflow that works over the +local network (usually Wi-Fi) and a web browser. +Other clients can also use the Web REST API. Boards should clearly document which workflows are supported. Code for workflows lives in `supervisor/shared`. @@ -19,39 +19,78 @@ The workflow APIs are documented here. These USB interfaces are enabled by default on boards with USB support. They are usable once the device has been plugged into a host. -### CIRCUITPY drive +### Mass Storage CircuitPython exposes a standard mass storage (MSC) interface to enable file manipulation over a -standard interface. This interface works underneath the file system at the block level so using it -excludes other types of workflows from manipulating the file system at the same time. +standard interface. The board appears as a USB drive. This interface works underneath the file system at +the block level so using it excludes other types of workflows from manipulating the file system at +the same time. + +CircuitPython 10.x adds multiple Logical Units (LUNs) to the mass storage interface. This allows for +multiple drives to be accessed and ejected independently. + +#### CIRCUITPY drive +The CIRCUITPY drive is the main drive that CircuitPython presents. It is writable by the host by default +and read-only to CircuitPython. `storage.remount()` can be used to remount the drive to +CircuitPython as read-write. + +#### CPSAVES drive +The board may also expose a CPSAVES drive. (This is based on the `CIRCUITPY_SAVES_PARTITION_SIZE` +setting in `mpconfigboard.h`.) It is a portion of the main flash that is writable by CircuitPython +by default. The CPSAVES drive becomes visible to the attached host computer after a few seconds. +By default it is read-only to the host, but `storage.remount()` can be used to remount the drive +as read-write to the host + +#### SD card drive +A few boards auomatically mount an SD card, if present, to the `/sd` mount point. +Boards that do this have `DEFAULT_SD` settings in`mpconfigboard.h` which allow detecting the +presence of an SD card, and fixed pin settings for the SD card socket. +The mounted SD card is writable from CircuitPython by default and read-only to the host. +`storage.remount()` can be used to remount the drive to the host as read-write. + +If `CIRCUITPY_SDCARD_USB` in settings.toml is `true` (the default), +an SD card mounted in user code at `/sd` will become visible on the attached host computer +after a few seconds, as an additional drive besides CIRCUITPY and (if present) CPSAVES. +It will present with the volume label on the SD card. +Depending on the host operating system settings, the drive may or may not be +auto-mounted on the host. +Host writes to drives mounted by user code will not trigger a reload. ### CDC serial -CircuitPython exposes one CDC USB interface for CircuitPython serial. This is a standard serial -USB interface. +CircuitPython exposes a standard serial CDC USB interface for the CircuitPython REPL. +Setting the CDC's baudrate 1200 and disconnecting will reboot the board into a bootloader. +This technique was first used by Arduino boards and the Arduino IDE to trigger a reset into bootloader. -TODO: Document how it designates itself from the user CDC. +A second CDC interface is optionally available for binary data transfer (see `usb_cdc`). -Setting baudrate 1200 and disconnecting will reboot into a bootloader. (Used by Arduino to trigger -a reset into bootloader.) ## BLE -The BLE workflow is enabled for Nordic boards. By default, to prevent malicious access, it is disabled. -To connect to the BLE workflow, press the reset button while the status led blinks blue quickly -after the safe mode blinks. The board will restart and broadcast the file transfer service UUID -(`0xfebb`) along with the board's [Creation IDs](https://github.com/creationid/creators). This -public broadcast is done at a lower transmit level so the devices must be closer. On connection, the -device will need to pair and bond. Once bonded, the device will broadcast whenever disconnected -using a rotating key rather than a static one. Non-bonded devices won't be able to resolve it. After -connection, the central device can discover two default services. One for file transfer and one for -CircuitPython specifically that includes serial characteristics. +The BLE workflow provides file transfer and REPL access over BLE. +It can be controlled by setting `CIRCUITPY_BLE_WORKFLOW` to be `true` or `false`. +in `settings.toml`. The default is `true`. + +To prevent malicious access, even if `CIRCUITPY_BLE_WORKFLOW=true`, +the user must initiate a bonded connection with the host. +To bond, press the reset button when the status led blinks blue quickly after reset, +after the safe mode blinks. +The board will restart and advertise the file transfer service UUID (`0xfebb`) +along with the board's [Creation ID](https://github.com/creationid/creators). +This public advertisement is done at a lower transmit level so the devices must be closer. +On connection, the device will need to pair and bond. +Once bonded, the device will advertise whenever disconnected, +using a rotating key rather than a static one. +Non-bonded devices won't be able to resolve it. + +After connection, will discover two default services: one is for file transfer and +the other provides version information and a serial connection to the CircuitPython REPL. To change the default BLE advertising name without (or before) running user code, the desired name -can be put in the `settings.toml` file. The key is `CIRCUITPY_BLE_NAME`. It's limited to approximately -30 characters depending on the port's settings and will be truncated if longer. +can be put in the `settings.toml` using the `CIRCUITPY_BLE_NAME` key. The name is limited to approximately +30 characters, depending on the port, and will be truncated if longer. ### File Transfer API -CircuitPython uses [an open File Transfer API](https://github.com/adafruit/Adafruit_CircuitPython_BLE_File_Transfer) +The file transfer service provides [an open File Transfer API](https://github.com/adafruit/Adafruit_CircuitPython_BLE_File_Transfer) to enable file system access. ### CircuitPython Service @@ -61,22 +100,22 @@ replaced by the four specific digits below. The service itself is `0001`. #### TX - `0002` / RX - `0003` -These characteristic work just like the Nordic Uart Service (NUS) but have different UUIDs to prevent -conflicts with user created NUS services. +The TX and RX characteristics for the CircuitPython service work just like the Nordic Uart Service (NUS) +but have different UUIDs to prevent conflicts with user-created NUS services. #### Version - `0100` -Read-only characteristic that returns the UTF-8 encoded version string. +The Version characteristic is read-only and returns the UTF-8 encoded version string. ## Web If the keys `CIRCUITPY_WIFI_SSID` and `CIRCUITPY_WIFI_PASSWORD` are set in `settings.toml`, CircuitPython will automatically connect to the given Wi-Fi network on boot and upon reload. -If `CIRCUITPY_WEB_API_PASSWORD` is set, MDNS and the http server for the web workflow will also start. +If `CIRCUITPY_WEB_API_PASSWORD` is set, MDNS and the HTTP server for the web workflow will also start. -The webserver is on port 80 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables MDNS. +The webserver is on port 80 unless overridden by `CIRCUITPY_WEB_API_PORT`. It also enables mDNS. The name of the board as advertised to the network can be overridden by `CIRCUITPY_WEB_INSTANCE_NAME`. -Here is an example `/settings.toml`: +Here is an example `settings.toml`: ```bash # To auto-connect to Wi-Fi @@ -223,7 +262,7 @@ curl -v -u :passw0rd -X PUT -L --location-trusted http://circuitpython.local/fs/ ``` ##### Move -Moves the directory at the given path to ``X-Destination``. Also known as rename. +Moves the directory at the given path to `X-Destination`. Also known as rename. The custom `X-Destination` header stores the destination path of the directory. @@ -309,7 +348,7 @@ curl -v -u :passw0rd -L --location-trusted http://circuitpython.local/fs/lib/hel ##### Move -Moves the file at the given path to the ``X-Destination``. Also known as rename. +Moves the file at the given path to the `X-Destination`. Also known as rename. The custom `X-Destination` header stores the destination path of the file. diff --git a/examples/natmod/README.md b/examples/natmod/README.md index 0cc4010ef42..ca6b887d034 100644 --- a/examples/natmod/README.md +++ b/examples/natmod/README.md @@ -1,12 +1,12 @@ # Dynamic Native Modules Dynamic Native Modules are .mpy files that contain native machine code from a -language other than Python. For more info see [the documentation] -(https://docs.micropython.org/en/latest/develop/natmod.html). +language other than Python. For more info see [the +documentation](https://docs.micropython.org/en/latest/develop/natmod.html). -This should not be confused with [User C Modules] -(https://docs.micropython.org/en/latest/develop/cmodules.html) which are a -mechanism to add additional out-of-tree modules into the firmware build. +This should not be confused with [User C +Modules](https://docs.micropython.org/en/latest/develop/cmodules.html) which are +a mechanism to add additional out-of-tree modules into the firmware build. ## Examples @@ -65,7 +65,7 @@ your system package manager or installed from PyPI in a virtual environment with `pip`. Each example provides a Makefile. You should specify the `ARCH` argument to -make (one of x86, x64, armv6m, armv7m, xtensa, xtensawin): +make (one of x86, x64, armv6m, armv7m, xtensa, xtensawin, rv32imc): ``` $ cd features0 diff --git a/examples/natmod/btree/Makefile b/examples/natmod/btree/Makefile new file mode 100644 index 00000000000..ff130d61b37 --- /dev/null +++ b/examples/natmod/btree/Makefile @@ -0,0 +1,38 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in btree so it can coexist) +MOD = btree_$(ARCH) + +# Source files (.c or .py) +SRC = btree_c.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) +ARCH = x64 + +BTREE_DIR = $(MPY_DIR)/lib/berkeley-db-1.xx +BERKELEY_DB_CONFIG_FILE ?= \"extmod/berkeley-db/berkeley_db_config_port.h\" +CFLAGS += -I$(BTREE_DIR)/include +CFLAGS += -DBERKELEY_DB_CONFIG_FILE=$(BERKELEY_DB_CONFIG_FILE) +CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter + +SRC += $(addprefix $(realpath $(BTREE_DIR))/,\ + btree/bt_close.c \ + btree/bt_conv.c \ + btree/bt_delete.c \ + btree/bt_get.c \ + btree/bt_open.c \ + btree/bt_overflow.c \ + btree/bt_page.c \ + btree/bt_put.c \ + btree/bt_search.c \ + btree/bt_seq.c \ + btree/bt_split.c \ + btree/bt_utils.c \ + mpool/mpool.c \ + ) + +include $(MPY_DIR)/py/dynruntime.mk + +# btree needs gnu99 defined +CFLAGS += -std=gnu99 diff --git a/examples/natmod/btree/btree_c.c b/examples/natmod/btree/btree_c.c new file mode 100644 index 00000000000..4f494817e7b --- /dev/null +++ b/examples/natmod/btree/btree_c.c @@ -0,0 +1,171 @@ +#define MICROPY_PY_BTREE (1) + +#include "py/dynruntime.h" + +#include + +#if !defined(__linux__) +void *memcpy(void *dst, const void *src, size_t n) { + return mp_fun_table.memmove_(dst, src, n); +} +void *memset(void *s, int c, size_t n) { + return mp_fun_table.memset_(s, c, n); +} +#endif + +void *memmove(void *dest, const void *src, size_t n) { + return mp_fun_table.memmove_(dest, src, n); +} + +void *malloc(size_t n) { + void *ptr = m_malloc(n); + return ptr; +} +void *realloc(void *ptr, size_t n) { + mp_printf(&mp_plat_print, "UNDEF %d\n", __LINE__); + return NULL; +} +void *calloc(size_t n, size_t m) { + void *ptr = m_malloc(n * m); + // memory already cleared by conservative GC + return ptr; +} + +void free(void *ptr) { + m_free(ptr); +} + +void abort_(void) { + nlr_raise(mp_obj_new_exception(mp_load_global(MP_QSTR_RuntimeError))); +} + +int puts(const char *s) { + return mp_printf(&mp_plat_print, "%s\n", s); +} + +int native_errno; +#if defined(__linux__) +int *__errno_location (void) +#else +int *__errno (void) +#endif +{ + return &native_errno; +} + +ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { + mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); + mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); + if (out_sz == MP_STREAM_ERROR) { + return -1; + } else { + return out_sz; + } +} + +ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { + mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); + mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); + if (out_sz == MP_STREAM_ERROR) { + return -1; + } else { + return out_sz; + } +} + +off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { + const mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); + struct mp_stream_seek_t seek_s; + seek_s.offset = offset; + seek_s.whence = whence; + mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_SEEK, (mp_uint_t)(uintptr_t)&seek_s, &native_errno); + if (res == MP_STREAM_ERROR) { + return -1; + } + return seek_s.offset; +} + +int mp_stream_posix_fsync(void *stream) { + mp_obj_base_t* o = stream; + const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol); + mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno); + if (res == MP_STREAM_ERROR) { + return -1; + } + return res; +} + +mp_obj_full_type_t btree_type; +mp_getiter_iternext_custom_t btree_getiter_iternext; + +#include "extmod/modbtree.c" + +mp_map_elem_t btree_locals_dict_table[8]; +static MP_DEFINE_CONST_DICT(btree_locals_dict, btree_locals_dict_table); + +static mp_obj_t btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + // The allowed_args array must have its qstr's populated at runtime. + enum { ARG_flags, ARG_cachesize, ARG_pagesize, ARG_minkeypage }; + mp_arg_t allowed_args[] = { + { MP_QSTR_, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + allowed_args[0].qst = MP_QSTR_flags; + allowed_args[1].qst = MP_QSTR_cachesize; + allowed_args[2].qst = MP_QSTR_pagesize; + allowed_args[3].qst = MP_QSTR_minkeypage; + + // Make sure we got a stream object + mp_get_stream_raise(pos_args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + BTREEINFO openinfo = {0}; + openinfo.flags = args[ARG_flags].u_int; + openinfo.cachesize = args[ARG_cachesize].u_int; + openinfo.psize = args[ARG_pagesize].u_int; + openinfo.minkeypage = args[ARG_minkeypage].u_int; + DB *db = __bt_open(MP_OBJ_TO_PTR(pos_args[0]), &btree_stream_fvtable, &openinfo, 0); + if (db == NULL) { + mp_raise_OSError(native_errno); + } + + return MP_OBJ_FROM_PTR(btree_new(db, pos_args[0])); +} +static MP_DEFINE_CONST_FUN_OBJ_KW(btree_open_obj, 1, btree_open); + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + btree_getiter_iternext.getiter = btree_getiter; + btree_getiter_iternext.iternext = btree_iternext; + + btree_type.base.type = (void*)&mp_fun_table.type_type; + btree_type.flags = MP_TYPE_FLAG_ITER_IS_CUSTOM; + btree_type.name = MP_QSTR_btree; + MP_OBJ_TYPE_SET_SLOT(&btree_type, print, btree_print, 0); + MP_OBJ_TYPE_SET_SLOT(&btree_type, iter, &btree_getiter_iternext, 1); + MP_OBJ_TYPE_SET_SLOT(&btree_type, binary_op, btree_binary_op, 2); + MP_OBJ_TYPE_SET_SLOT(&btree_type, subscr, btree_subscr, 3); + btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) }; + btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) }; + btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) }; + btree_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_put), MP_OBJ_FROM_PTR(&btree_put_obj) }; + btree_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_seq), MP_OBJ_FROM_PTR(&btree_seq_obj) }; + btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) }; + btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) }; + btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) }; + MP_OBJ_TYPE_SET_SLOT(&btree_type, locals_dict, (void*)&btree_locals_dict, 4); + + mp_store_global(MP_QSTR_open, MP_OBJ_FROM_PTR(&btree_open_obj)); + mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL)); + mp_store_global(MP_QSTR_DESC, MP_OBJ_NEW_SMALL_INT(FLAG_DESC)); + + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/deflate/Makefile b/examples/natmod/deflate/Makefile index 86ef29b6324..504130d5723 100644 --- a/examples/natmod/deflate/Makefile +++ b/examples/natmod/deflate/Makefile @@ -7,7 +7,7 @@ MOD = deflate_$(ARCH) # Source files (.c or .py) SRC = deflate.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/features0/Makefile b/examples/natmod/features0/Makefile index 57490df90ab..9bc4bbf23b8 100644 --- a/examples/natmod/features0/Makefile +++ b/examples/natmod/features0/Makefile @@ -7,7 +7,7 @@ MOD = features0 # Source files (.c or .py) SRC = features0.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 # Include to get the rules for compiling and linking the module diff --git a/examples/natmod/features1/Makefile b/examples/natmod/features1/Makefile index 010640daf97..49040511020 100644 --- a/examples/natmod/features1/Makefile +++ b/examples/natmod/features1/Makefile @@ -7,7 +7,7 @@ MOD = features1 # Source files (.c or .py) SRC = features1.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 # Include to get the rules for compiling and linking the module diff --git a/examples/natmod/features2/Makefile b/examples/natmod/features2/Makefile index 4fd23c6879d..5ddb74087b7 100644 --- a/examples/natmod/features2/Makefile +++ b/examples/natmod/features2/Makefile @@ -10,5 +10,8 @@ SRC = main.c prod.c test.py # Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) ARCH = x64 +# Link with libm.a and libgcc.a from the toolchain +LINK_RUNTIME = 1 + # Include to get the rules for compiling and linking the module include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/features2/main.c b/examples/natmod/features2/main.c index 22961aa494f..5ce8e7b0130 100644 --- a/examples/natmod/features2/main.c +++ b/examples/natmod/features2/main.c @@ -1,5 +1,6 @@ /* This example demonstrates the following features in a native module: - using floats + - calling math functions from libm.a - defining additional code in Python (see test.py) - have extra C code in a separate file (see prod.c) */ @@ -10,6 +11,9 @@ // Include the header for auxiliary C code for this module #include "prod.h" +// Include standard library header +#include + // Automatically detect if this module should include double-precision code. // If double precision is supported by the target architecture then it can // be used in native module regardless of what float setting the target @@ -41,6 +45,12 @@ static mp_obj_t add_d(mp_obj_t x, mp_obj_t y) { static MP_DEFINE_CONST_FUN_OBJ_2(add_d_obj, add_d); #endif +// A function that uses libm +static mp_obj_t call_round(mp_obj_t x) { + return mp_obj_new_float_from_f(roundf(mp_obj_get_float_to_f(x))); +} +static MP_DEFINE_CONST_FUN_OBJ_1(round_obj, call_round); + // A function that computes the product of floats in an array. // This function uses the most general C argument interface, which is more difficult // to use but has access to the globals dict of the module via self->globals. @@ -74,6 +84,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a #if USE_DOUBLE mp_store_global(MP_QSTR_add_d, MP_OBJ_FROM_PTR(&add_d_obj)); #endif + mp_store_global(MP_QSTR_round, MP_OBJ_FROM_PTR(&round_obj)); // The productf function uses the most general C argument interface mp_store_global(MP_QSTR_productf, MP_DYNRUNTIME_MAKE_FUNCTION(productf)); diff --git a/examples/natmod/features3/Makefile b/examples/natmod/features3/Makefile index 4a5f71b8f25..3573f41caca 100644 --- a/examples/natmod/features3/Makefile +++ b/examples/natmod/features3/Makefile @@ -7,7 +7,7 @@ MOD = features3 # Source files (.c or .py) SRC = features3.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 # Include to get the rules for compiling and linking the module diff --git a/examples/natmod/features4/Makefile b/examples/natmod/features4/Makefile index f76a31a7cc1..34fc3a7ef7b 100644 --- a/examples/natmod/features4/Makefile +++ b/examples/natmod/features4/Makefile @@ -7,7 +7,7 @@ MOD = features4 # Source files (.c or .py) SRC = features4.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 # Include to get the rules for compiling and linking the module diff --git a/examples/natmod/framebuf/Makefile b/examples/natmod/framebuf/Makefile new file mode 100644 index 00000000000..2e2b8159754 --- /dev/null +++ b/examples/natmod/framebuf/Makefile @@ -0,0 +1,13 @@ +# Location of top-level MicroPython directory +MPY_DIR = ../../.. + +# Name of module (different to built-in framebuf so it can coexist) +MOD = framebuf_$(ARCH) + +# Source files (.c or .py) +SRC = framebuf.c + +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +ARCH = x64 + +include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/framebuf/framebuf.c b/examples/natmod/framebuf/framebuf.c new file mode 100644 index 00000000000..1ba702e33d9 --- /dev/null +++ b/examples/natmod/framebuf/framebuf.c @@ -0,0 +1,51 @@ +#define MICROPY_PY_ARRAY (1) +#define MICROPY_PY_FRAMEBUF (1) + +#include "py/dynruntime.h" + +#if !defined(__linux__) +void *memset(void *s, int c, size_t n) { + return mp_fun_table.memset_(s, c, n); +} +#endif + +mp_obj_full_type_t mp_type_framebuf; + +#include "extmod/modframebuf.c" + +mp_map_elem_t framebuf_locals_dict_table[12]; +static MP_DEFINE_CONST_DICT(framebuf_locals_dict, framebuf_locals_dict_table); + +mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) { + MP_DYNRUNTIME_INIT_ENTRY + + mp_type_framebuf.base.type = (void*)&mp_type_type; + mp_type_framebuf.name = MP_QSTR_FrameBuffer; + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, make_new, framebuf_make_new, 0); + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, buffer, framebuf_get_buffer, 1); + framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; + framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; + framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; + framebuf_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_hline), MP_OBJ_FROM_PTR(&framebuf_hline_obj) }; + framebuf_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_vline), MP_OBJ_FROM_PTR(&framebuf_vline_obj) }; + framebuf_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_rect), MP_OBJ_FROM_PTR(&framebuf_rect_obj) }; + framebuf_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_line), MP_OBJ_FROM_PTR(&framebuf_line_obj) }; + framebuf_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_ellipse), MP_OBJ_FROM_PTR(&framebuf_ellipse_obj) }; + framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_poly), MP_OBJ_FROM_PTR(&framebuf_poly_obj) }; + framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; + framebuf_locals_dict_table[10] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; + framebuf_locals_dict_table[11] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; + MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, locals_dict, (void*)&framebuf_locals_dict, 2); + + mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); + mp_store_global(MP_QSTR_MVLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); + mp_store_global(MP_QSTR_MONO_VLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MVLSB)); + mp_store_global(MP_QSTR_RGB565, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_RGB565)); + mp_store_global(MP_QSTR_GS2_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS2_HMSB)); + mp_store_global(MP_QSTR_GS4_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS4_HMSB)); + mp_store_global(MP_QSTR_GS8, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_GS8)); + mp_store_global(MP_QSTR_MONO_HLSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHLSB)); + mp_store_global(MP_QSTR_MONO_HMSB, MP_OBJ_NEW_SMALL_INT(FRAMEBUF_MHMSB)); + + MP_DYNRUNTIME_INIT_EXIT +} diff --git a/examples/natmod/heapq/Makefile b/examples/natmod/heapq/Makefile index af45b472da1..61e2fc8fcc0 100644 --- a/examples/natmod/heapq/Makefile +++ b/examples/natmod/heapq/Makefile @@ -7,7 +7,7 @@ MOD = heapq_$(ARCH) # Source files (.c or .py) SRC = heapq.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/random/Makefile b/examples/natmod/random/Makefile index 5c50227b15f..8abdb66dc87 100644 --- a/examples/natmod/random/Makefile +++ b/examples/natmod/random/Makefile @@ -7,7 +7,7 @@ MOD = random_$(ARCH) # Source files (.c or .py) SRC = random.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/re/Makefile b/examples/natmod/re/Makefile index 1ba54011065..56b08b98868 100644 --- a/examples/natmod/re/Makefile +++ b/examples/natmod/re/Makefile @@ -7,7 +7,7 @@ MOD = re_$(ARCH) # Source files (.c or .py) SRC = re.c -# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin) +# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin, rv32imc) ARCH = x64 include $(MPY_DIR)/py/dynruntime.mk diff --git a/examples/natmod/re/re.c b/examples/natmod/re/re.c index 7ae72a578f4..c0279ee7e81 100644 --- a/examples/natmod/re/re.c +++ b/examples/natmod/re/re.c @@ -4,14 +4,27 @@ #define MICROPY_PY_RE_MATCH_SPAN_START_END (1) #define MICROPY_PY_RE_SUB (0) // requires vstr interface +#if defined __has_builtin +#if __has_builtin(__builtin_alloca) +#define alloca __builtin_alloca +#endif +#endif + +#if !defined(alloca) +#if defined(_PICOLIBC__) && !defined(HAVE_BUILTIN_ALLOCA) +#define alloca(n) m_malloc(n) +#else #include +#endif +#endif + #include "py/dynruntime.h" #define STACK_LIMIT (2048) const char *stack_top; -void mp_stack_check(void) { +void mp_cstack_check(void) { // Assumes descending stack on target volatile char dummy; if (stack_top - &dummy >= STACK_LIMIT) { diff --git a/examples/usercmodule/cexample/examplemodule.c b/examples/usercmodule/cexample/examplemodule.c deleted file mode 100644 index 2988fbd565f..00000000000 --- a/examples/usercmodule/cexample/examplemodule.c +++ /dev/null @@ -1,90 +0,0 @@ -// Include MicroPython API. -#include "py/runtime.h" - -// Used to get the time in the Timer class example. -#include "py/mphal.h" - -// This is the function which will be called from Python as cexample.add_ints(a, b). -static mp_obj_t example_add_ints(mp_obj_t a_obj, mp_obj_t b_obj) { - // Extract the ints from the micropython input objects. - int a = mp_obj_get_int(a_obj); - int b = mp_obj_get_int(b_obj); - - // Calculate the addition and convert to MicroPython object. - return mp_obj_new_int(a + b); -} -// Define a Python reference to the function above. -static MP_DEFINE_CONST_FUN_OBJ_2(example_add_ints_obj, example_add_ints); - -// This structure represents Timer instance objects. -typedef struct _example_Timer_obj_t { - // All objects start with the base. - mp_obj_base_t base; - // Everything below can be thought of as instance attributes, but they - // cannot be accessed by MicroPython code directly. In this example we - // store the time at which the object was created. - mp_uint_t start_time; -} example_Timer_obj_t; - -// This is the Timer.time() method. After creating a Timer object, this -// can be called to get the time elapsed since creating the Timer. -static mp_obj_t example_Timer_time(mp_obj_t self_in) { - // The first argument is self. It is cast to the *example_Timer_obj_t - // type so we can read its attributes. - example_Timer_obj_t *self = MP_OBJ_TO_PTR(self_in); - - // Get the elapsed time and return it as a MicroPython integer. - mp_uint_t elapsed = mp_hal_ticks_ms() - self->start_time; - return mp_obj_new_int_from_uint(elapsed); -} -static MP_DEFINE_CONST_FUN_OBJ_1(example_Timer_time_obj, example_Timer_time); - -// This represents Timer.__new__ and Timer.__init__, which is called when -// the user instantiates a Timer object. -static mp_obj_t example_Timer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - // Allocates the new object and sets the type. - example_Timer_obj_t *self = mp_obj_malloc(example_Timer_obj_t, type); - - // Initializes the time for this Timer instance. - self->start_time = mp_hal_ticks_ms(); - - // The make_new function always returns self. - return MP_OBJ_FROM_PTR(self); -} - -// This collects all methods and other static class attributes of the Timer. -// The table structure is similar to the module table, as detailed below. -static const mp_rom_map_elem_t example_Timer_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&example_Timer_time_obj) }, -}; -static MP_DEFINE_CONST_DICT(example_Timer_locals_dict, example_Timer_locals_dict_table); - -// This defines the type(Timer) object. -MP_DEFINE_CONST_OBJ_TYPE( - example_type_Timer, - MP_QSTR_Timer, - MP_TYPE_FLAG_NONE, - make_new, example_Timer_make_new, - locals_dict, &example_Timer_locals_dict - ); - -// Define all attributes of the module. -// Table entries are key/value pairs of the attribute name (a string) -// and the MicroPython object reference. -// All identifiers and strings are written as MP_QSTR_xxx and will be -// optimized to word-sized integers by the build system (interned strings). -static const mp_rom_map_elem_t example_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cexample) }, - { MP_ROM_QSTR(MP_QSTR_add_ints), MP_ROM_PTR(&example_add_ints_obj) }, - { MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&example_type_Timer) }, -}; -static MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table); - -// Define module object. -const mp_obj_module_t example_user_cmodule = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&example_module_globals, -}; - -// Register the module to make it available in Python. -MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule); diff --git a/examples/usercmodule/cexample/micropython.cmake b/examples/usercmodule/cexample/micropython.cmake deleted file mode 100644 index ba076a16b24..00000000000 --- a/examples/usercmodule/cexample/micropython.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# Create an INTERFACE library for our C module. -add_library(usermod_cexample INTERFACE) - -# Add our source files to the lib -target_sources(usermod_cexample INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/examplemodule.c -) - -# Add the current directory as an include directory. -target_include_directories(usermod_cexample INTERFACE - ${CMAKE_CURRENT_LIST_DIR} -) - -# Link our INTERFACE library to the usermod target. -target_link_libraries(usermod INTERFACE usermod_cexample) diff --git a/examples/usercmodule/cexample/micropython.mk b/examples/usercmodule/cexample/micropython.mk deleted file mode 100644 index d6801dac0ba..00000000000 --- a/examples/usercmodule/cexample/micropython.mk +++ /dev/null @@ -1,8 +0,0 @@ -CEXAMPLE_MOD_DIR := $(USERMOD_DIR) - -# Add all C files to SRC_USERMOD. -SRC_USERMOD += $(CEXAMPLE_MOD_DIR)/examplemodule.c - -# We can add our module folder to include paths if needed -# This is not actually needed in this example. -CFLAGS_USERMOD += -I$(CEXAMPLE_MOD_DIR) diff --git a/examples/usercmodule/cppexample/example.cpp b/examples/usercmodule/cppexample/example.cpp deleted file mode 100644 index 2df832baa76..00000000000 --- a/examples/usercmodule/cppexample/example.cpp +++ /dev/null @@ -1,24 +0,0 @@ -extern "C" { -#include -#include - -// Here we implement the function using C++ code, but since it's -// declaration has to be compatible with C everything goes in extern "C" scope. -mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj) { - // The following no-ops are just here to verify the static assertions used in - // the public API all compile with C++. - MP_STATIC_ASSERT_STR_ARRAY_COMPATIBLE; - if (mp_obj_is_type(a_obj, &mp_type_BaseException)) { - } - - // Prove we have (at least) C++11 features. - const auto a = mp_obj_get_int(a_obj); - const auto b = mp_obj_get_int(b_obj); - const auto sum = [&]() { - return mp_obj_new_int(a + b); - } (); - // Prove we're being scanned for QSTRs. - mp_obj_t tup[] = {sum, MP_ROM_QSTR(MP_QSTR_hellocpp)}; - return mp_obj_new_tuple(2, tup); -} -} diff --git a/examples/usercmodule/cppexample/examplemodule.c b/examples/usercmodule/cppexample/examplemodule.c deleted file mode 100644 index 5d4637b8978..00000000000 --- a/examples/usercmodule/cppexample/examplemodule.c +++ /dev/null @@ -1,25 +0,0 @@ -#include - -// Define a Python reference to the function we'll make available. -// See example.cpp for the definition. -static MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc); - -// Define all attributes of the module. -// Table entries are key/value pairs of the attribute name (a string) -// and the MicroPython object reference. -// All identifiers and strings are written as MP_QSTR_xxx and will be -// optimized to word-sized integers by the build system (interned strings). -static const mp_rom_map_elem_t cppexample_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cppexample) }, - { MP_ROM_QSTR(MP_QSTR_cppfunc), MP_ROM_PTR(&cppfunc_obj) }, -}; -static MP_DEFINE_CONST_DICT(cppexample_module_globals, cppexample_module_globals_table); - -// Define module object. -const mp_obj_module_t cppexample_user_cmodule = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&cppexample_module_globals, -}; - -// Register the module to make it available in Python. -MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule); diff --git a/examples/usercmodule/cppexample/examplemodule.h b/examples/usercmodule/cppexample/examplemodule.h deleted file mode 100644 index d89384a6300..00000000000 --- a/examples/usercmodule/cppexample/examplemodule.h +++ /dev/null @@ -1,5 +0,0 @@ -// Include MicroPython API. -#include "py/runtime.h" - -// Declare the function we'll make available in Python as cppexample.cppfunc(). -extern mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj); diff --git a/examples/usercmodule/cppexample/micropython.cmake b/examples/usercmodule/cppexample/micropython.cmake deleted file mode 100644 index 6da972c94e3..00000000000 --- a/examples/usercmodule/cppexample/micropython.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# Create an INTERFACE library for our CPP module. -add_library(usermod_cppexample INTERFACE) - -# Add our source files to the library. -target_sources(usermod_cppexample INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/example.cpp - ${CMAKE_CURRENT_LIST_DIR}/examplemodule.c -) - -# Add the current directory as an include directory. -target_include_directories(usermod_cppexample INTERFACE - ${CMAKE_CURRENT_LIST_DIR} -) - -# Link our INTERFACE library to the usermod target. -target_link_libraries(usermod INTERFACE usermod_cppexample) diff --git a/examples/usercmodule/cppexample/micropython.mk b/examples/usercmodule/cppexample/micropython.mk deleted file mode 100644 index 0071d4fcc72..00000000000 --- a/examples/usercmodule/cppexample/micropython.mk +++ /dev/null @@ -1,12 +0,0 @@ -CPPEXAMPLE_MOD_DIR := $(USERMOD_DIR) - -# Add our source files to the respective variables. -SRC_USERMOD += $(CPPEXAMPLE_MOD_DIR)/examplemodule.c -SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/example.cpp - -# Add our module directory to the include path. -CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) -CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR) -std=c++11 - -# We use C++ features so have to link against the standard library. -LDFLAGS_USERMOD += -lstdc++ diff --git a/examples/usercmodule/micropython.cmake b/examples/usercmodule/micropython.cmake deleted file mode 100644 index b9802401fa9..00000000000 --- a/examples/usercmodule/micropython.cmake +++ /dev/null @@ -1,10 +0,0 @@ -# This top-level micropython.cmake is responsible for listing -# the individual modules we want to include. -# Paths are absolute, and ${CMAKE_CURRENT_LIST_DIR} can be -# used to prefix subdirectories. - -# Add the C example. -include(${CMAKE_CURRENT_LIST_DIR}/cexample/micropython.cmake) - -# Add the CPP example. -include(${CMAKE_CURRENT_LIST_DIR}/cppexample/micropython.cmake) diff --git a/examples/usercmodule/subpackage/README.md b/examples/usercmodule/subpackage/README.md deleted file mode 100644 index c7f2ee53a24..00000000000 --- a/examples/usercmodule/subpackage/README.md +++ /dev/null @@ -1 +0,0 @@ -This is an example of a user C module that includes subpackages. diff --git a/examples/usercmodule/subpackage/micropython.cmake b/examples/usercmodule/subpackage/micropython.cmake deleted file mode 100644 index a51e7a80613..00000000000 --- a/examples/usercmodule/subpackage/micropython.cmake +++ /dev/null @@ -1,19 +0,0 @@ -# Create an INTERFACE library for our C module. -add_library(usermod_subpackage_example INTERFACE) - -# Add our source files to the lib -target_sources(usermod_subpackage_example INTERFACE - ${CMAKE_CURRENT_LIST_DIR}/examplemodule.c -) - -# Add the current directory as an include directory. -target_include_directories(usermod_subpackage_example INTERFACE - ${CMAKE_CURRENT_LIST_DIR} -) - -target_compile_definitions(usermod_subpackage_example INTERFACE - MICROPY_MODULE_BUILTIN_SUBPACKAGES=1 -) - -# Link our INTERFACE library to the usermod target. -target_link_libraries(usermod INTERFACE usermod_subpackage_example) diff --git a/examples/usercmodule/subpackage/micropython.mk b/examples/usercmodule/subpackage/micropython.mk deleted file mode 100644 index 99ebf13ec19..00000000000 --- a/examples/usercmodule/subpackage/micropython.mk +++ /dev/null @@ -1,10 +0,0 @@ -SUBPACKAGE_EXAMPLE_MOD_DIR := $(USERMOD_DIR) - -# Add all C files to SRC_USERMOD. -SRC_USERMOD += $(SUBPACKAGE_EXAMPLE_MOD_DIR)/modexamplepackage.c - -# We can add our module folder to include paths if needed -# This is not actually needed in this example. -CFLAGS_USERMOD += -I$(SUBPACKAGE_EXAMPLE_MOD_DIR) -DMICROPY_MODULE_BUILTIN_SUBPACKAGES=1 - -QSTR_DEFS += $(SUBPACKAGE_EXAMPLE_MOD_DIR)/qstrdefsexamplepackage.h diff --git a/examples/usercmodule/subpackage/modexamplepackage.c b/examples/usercmodule/subpackage/modexamplepackage.c deleted file mode 100644 index d68d0528398..00000000000 --- a/examples/usercmodule/subpackage/modexamplepackage.c +++ /dev/null @@ -1,84 +0,0 @@ -// Include MicroPython API. -#include "py/runtime.h" - -// Define example_package.foo.bar.f() -static mp_obj_t example_package_foo_bar_f(void) { - mp_printf(&mp_plat_print, "example_package.foo.bar.f\n"); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_0(example_package_foo_bar_f_obj, example_package_foo_bar_f); - -// Define all attributes of the second-level sub-package (example_package.foo.bar). -static const mp_rom_map_elem_t example_package_foo_bar_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example_package_dot_foo_dot_bar) }, - { MP_ROM_QSTR(MP_QSTR_f), MP_ROM_PTR(&example_package_foo_bar_f_obj) }, -}; -static MP_DEFINE_CONST_DICT(example_package_foo_bar_globals, example_package_foo_bar_globals_table); - -// Define example_package.foo.bar module object. -const mp_obj_module_t example_package_foo_bar_user_cmodule = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&example_package_foo_bar_globals, -}; - -// Define example_package.foo.f() -static mp_obj_t example_package_foo_f(void) { - mp_printf(&mp_plat_print, "example_package.foo.f\n"); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_0(example_package_foo_f_obj, example_package_foo_f); - -// Define all attributes of the first-level sub-package (example_package.foo). -static const mp_rom_map_elem_t example_package_foo_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example_package_dot_foo) }, - { MP_ROM_QSTR(MP_QSTR_bar), MP_ROM_PTR(&example_package_foo_bar_user_cmodule) }, - { MP_ROM_QSTR(MP_QSTR_f), MP_ROM_PTR(&example_package_foo_f_obj) }, -}; -static MP_DEFINE_CONST_DICT(example_package_foo_globals, example_package_foo_globals_table); - -// Define example_package.foo module object. -const mp_obj_module_t example_package_foo_user_cmodule = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&example_package_foo_globals, -}; - -// Define example_package.f() -static mp_obj_t example_package_f(void) { - mp_printf(&mp_plat_print, "example_package.f\n"); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_0(example_package_f_obj, example_package_f); - -static mp_obj_t example_package___init__(void) { - if (!MP_STATE_VM(example_package_initialised)) { - // __init__ for builtins is called each time the module is imported, - // so ensure that initialisation only happens once. - MP_STATE_VM(example_package_initialised) = true; - mp_printf(&mp_plat_print, "example_package.__init__\n"); - } - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_0(example_package___init___obj, example_package___init__); - -// The "initialised" state is stored on mp_state so that it is cleared on soft -// reset. -MP_REGISTER_ROOT_POINTER(int example_package_initialised); - -// Define all attributes of the top-level package (example_package). -static const mp_rom_map_elem_t example_package_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example_package) }, - { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&example_package___init___obj) }, - { MP_ROM_QSTR(MP_QSTR_foo), MP_ROM_PTR(&example_package_foo_user_cmodule) }, - { MP_ROM_QSTR(MP_QSTR_f), MP_ROM_PTR(&example_package_f_obj) }, -}; -static MP_DEFINE_CONST_DICT(example_package_globals, example_package_globals_table); - -// Define module object. -const mp_obj_module_t example_package_user_cmodule = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t *)&example_package_globals, -}; - -// Register the module to make it available in Python. -// Note: subpackages should not be registered with MP_REGISTER_MODULE. -MP_REGISTER_MODULE(MP_QSTR_example_package, example_package_user_cmodule); diff --git a/examples/usercmodule/subpackage/qstrdefsexamplepackage.h b/examples/usercmodule/subpackage/qstrdefsexamplepackage.h deleted file mode 100644 index 057ec5279d0..00000000000 --- a/examples/usercmodule/subpackage/qstrdefsexamplepackage.h +++ /dev/null @@ -1,2 +0,0 @@ -Q(example_package.foo) -Q(example_package.foo.bar) diff --git a/extmod/extmod.mk b/extmod/extmod.mk index b81b44af376..5b2772e4e2a 100644 --- a/extmod/extmod.mk +++ b/extmod/extmod.mk @@ -24,7 +24,6 @@ SRC_EXTMOD_C += \ extmod/vfs_posix.c \ extmod/vfs_posix_file.c \ extmod/vfs_reader.c \ - extmod/virtpin.c \ shared/libc/abort_.c \ shared/libc/printf.c \ @@ -129,6 +128,7 @@ SRC_LIB_LIBM_DBL_SQRT_HW_C += lib/libm_dbl/thumb_vfp_sqrt.c # Too many warnings in libm_dbl, disable for now. $(BUILD)/lib/libm_dbl/%.o: CFLAGS += -Wno-double-promotion -Wno-float-conversion +$(BUILD)/lib/libm_dbl/__rem_pio2_large.o: CFLAGS += -Wno-maybe-uninitialized ################################################################################ # VFS FAT FS @@ -162,7 +162,7 @@ endif ifeq ($(MICROPY_VFS_LFS2),1) CFLAGS_EXTMOD += -DMICROPY_VFS_LFS2=1 -CFLAGS_THIRDPARTY += -DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT +CFLAGS_THIRDPARTY += -DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT -DLFS2_DEFINES=extmod/littlefs-include/lfs2_defines.h SRC_THIRDPARTY_C += $(addprefix $(LITTLEFS_DIR)/,\ lfs2.c \ lfs2_util.c \ @@ -203,6 +203,10 @@ MBEDTLS_CONFIG_FILE ?= \"mbedtls/mbedtls_config_port.h\" GIT_SUBMODULES += $(MBEDTLS_DIR) CFLAGS_EXTMOD += -DMBEDTLS_CONFIG_FILE=$(MBEDTLS_CONFIG_FILE) CFLAGS_EXTMOD += -DMICROPY_SSL_MBEDTLS=1 -I$(TOP)/$(MBEDTLS_DIR)/include +ifeq ($(MICROPY_PY_SSL_ECDSA_SIGN_ALT),1) +CFLAGS_EXTMOD += -DMICROPY_PY_SSL_ECDSA_SIGN_ALT=1 +LDFLAGS_EXTMOD += -Wl,--wrap=mbedtls_ecdsa_write_signature +endif SRC_THIRDPARTY_C += lib/mbedtls_errors/mp_mbedtls_errors.c SRC_THIRDPARTY_C += $(addprefix $(MBEDTLS_DIR)/library/,\ aes.c \ @@ -248,6 +252,7 @@ SRC_THIRDPARTY_C += $(addprefix $(MBEDTLS_DIR)/library/,\ pkcs12.c \ pkcs5.c \ pkparse.c \ + pk_ecc.c \ pk_wrap.c \ pkwrite.c \ platform.c \ @@ -294,6 +299,8 @@ $(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS += -Wno-address SRC_THIRDPARTY_C += shared/netutils/netutils.c SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\ apps/mdns/mdns.c \ + apps/mdns/mdns_domain.c \ + apps/mdns/mdns_out.c \ core/def.c \ core/dns.c \ core/inet_chksum.c \ @@ -311,6 +318,7 @@ SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\ core/tcp_out.c \ core/timeouts.c \ core/udp.c \ + core/ipv4/acd.c \ core/ipv4/autoip.c \ core/ipv4/dhcp.c \ core/ipv4/etharp.c \ @@ -329,6 +337,32 @@ SRC_THIRDPARTY_C += $(addprefix $(LWIP_DIR)/,\ core/ipv6/mld6.c \ core/ipv6/nd6.c \ netif/ethernet.c \ + netif/ppp/auth.c \ + netif/ppp/ccp.c \ + netif/ppp/chap-md5.c \ + netif/ppp/chap_ms.c \ + netif/ppp/chap-new.c \ + netif/ppp/demand.c \ + netif/ppp/eap.c \ + netif/ppp/ecp.c \ + netif/ppp/eui64.c \ + netif/ppp/fsm.c \ + netif/ppp/ipcp.c \ + netif/ppp/ipv6cp.c \ + netif/ppp/lcp.c \ + netif/ppp/magic.c \ + netif/ppp/mppe.c \ + netif/ppp/multilink.c \ + netif/ppp/polarssl/md5.c \ + netif/ppp/pppapi.c \ + netif/ppp/ppp.c \ + netif/ppp/pppcrypt.c \ + netif/ppp/pppoe.c \ + netif/ppp/pppol2tp.c \ + netif/ppp/pppos.c \ + netif/ppp/upap.c \ + netif/ppp/utils.c \ + netif/ppp/vj.c \ ) ifeq ($(MICROPY_PY_LWIP_LOOPBACK),1) CFLAGS_EXTMOD += -DLWIP_NETIF_LOOPBACK=1 @@ -377,15 +411,14 @@ CYW43_DIR = lib/cyw43-driver GIT_SUBMODULES += $(CYW43_DIR) CFLAGS_EXTMOD += -DMICROPY_PY_NETWORK_CYW43=1 SRC_THIRDPARTY_C += $(addprefix $(CYW43_DIR)/src/,\ + cyw43_bthci_uart.c \ cyw43_ctrl.c \ cyw43_lwip.c \ cyw43_ll.c \ cyw43_sdio.c \ + cyw43_spi.c \ cyw43_stats.c \ ) -ifeq ($(MICROPY_PY_BLUETOOTH),1) -DRIVERS_SRC_C += drivers/cyw43/cywbt.c -endif $(BUILD)/$(CYW43_DIR)/src/cyw43_%.o: CFLAGS += -std=c11 endif # MICROPY_PY_NETWORK_CYW43 @@ -428,7 +461,7 @@ ESP_HOSTED_SRC_C = $(addprefix $(ESP_HOSTED_DIR)/,\ ) ifeq ($(MICROPY_PY_BLUETOOTH),1) -ESP_HOSTED_SRC_C += $(ESP_HOSTED_DIR)/esp_hosted_bthci.c +ESP_HOSTED_SRC_C += $(ESP_HOSTED_DIR)/esp_hosted_bthci_uart.c endif # Include the protobuf-c support functions @@ -489,6 +522,7 @@ ifeq ($(MICROPY_PY_OPENAMP),1) OPENAMP_DIR = lib/open-amp LIBMETAL_DIR = lib/libmetal GIT_SUBMODULES += $(LIBMETAL_DIR) $(OPENAMP_DIR) +MICROPY_PY_OPENAMP_MODE ?= 0 include $(TOP)/extmod/libmetal/libmetal.mk INC += -I$(TOP)/$(OPENAMP_DIR) @@ -498,12 +532,21 @@ ifeq ($(MICROPY_PY_OPENAMP_REMOTEPROC),1) CFLAGS += -DMICROPY_PY_OPENAMP_REMOTEPROC=1 endif +ifeq ($(MICROPY_PY_OPENAMP_MODE),0) +CFLAGS += -DMICROPY_PY_OPENAMP_HOST=1 +CFLAGS_THIRDPARTY += -DVIRTIO_DRIVER_ONLY +else ifeq ($(MICROPY_PY_OPENAMP_MODE),1) +CFLAGS += -DMICROPY_PY_OPENAMP_DEVICE=1 +CFLAGS_THIRDPARTY += -DVIRTIO_DEVICE_ONLY +else +$(error Invalid Open-AMP mode specified: $(MICROPY_PY_OPENAMP_MODE)) +endif + CFLAGS_THIRDPARTY += \ -I$(BUILD)/openamp \ -I$(TOP)/$(OPENAMP_DIR) \ -I$(TOP)/$(OPENAMP_DIR)/lib/include/ \ -DMETAL_INTERNAL \ - -DVIRTIO_DRIVER_ONLY \ -DNO_ATOMIC_64_SUPPORT \ -DRPMSG_BUFFER_SIZE=512 \ @@ -533,6 +576,6 @@ $(BUILD)/$(OPENAMP_DIR)/lib/virtio_mmio/virtio_mmio_drv.o: CFLAGS += -Wno-unused # We need to have generated libmetal before compiling OpenAMP. $(addprefix $(BUILD)/, $(SRC_OPENAMP_C:.c=.o)): $(BUILD)/openamp/metal/config.h -SRC_THIRDPARTY_C += $(SRC_LIBMETAL_C) $(SRC_OPENAMP_C) +SRC_THIRDPARTY_C += $(SRC_OPENAMP_C) $(SRC_LIBMETAL_C:$(BUILD)/%=%) endif # MICROPY_PY_OPENAMP diff --git a/extmod/lwip-include/arch/cc.h b/extmod/lwip-include/arch/cc.h deleted file mode 100644 index 400dc6ec75d..00000000000 --- a/extmod/lwip-include/arch/cc.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_ARCH_CC_H -#define MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_ARCH_CC_H - -#include - -// Generate lwip's internal types from stdint - -typedef uint8_t u8_t; -typedef int8_t s8_t; -typedef uint16_t u16_t; -typedef int16_t s16_t; -typedef uint32_t u32_t; -typedef int32_t s32_t; - -typedef u32_t mem_ptr_t; - -#define U16_F "hu" -#define S16_F "hd" -#define X16_F "hx" -#define U32_F "u" -#define S32_F "d" -#define X32_F "x" - -#define X8_F "02x" -#define SZT_F "u" - -#define BYTE_ORDER LITTLE_ENDIAN - -#define LWIP_CHKSUM_ALGORITHM 2 - -#include -#define LWIP_PLATFORM_DIAG(x) -#define LWIP_PLATFORM_ASSERT(x) { assert(1); } - -//#define PACK_STRUCT_FIELD(x) x __attribute__((packed)) -#define PACK_STRUCT_FIELD(x) x -#define PACK_STRUCT_STRUCT __attribute__((packed)) -#define PACK_STRUCT_BEGIN -#define PACK_STRUCT_END - -#endif // MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_ARCH_CC_H diff --git a/extmod/lwip-include/arch/perf.h b/extmod/lwip-include/arch/perf.h deleted file mode 100644 index d310fc339f1..00000000000 --- a/extmod/lwip-include/arch/perf.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_ARCH_PERF_H -#define MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_ARCH_PERF_H - -#define PERF_START /* null definition */ -#define PERF_STOP(x) /* null definition */ - -#endif // MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_ARCH_PERF_H diff --git a/extmod/lwip-include/lwipopts.h b/extmod/lwip-include/lwipopts.h deleted file mode 100644 index 584decfe85f..00000000000 --- a/extmod/lwip-include/lwipopts.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_LWIPOPTS_H -#define MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_LWIPOPTS_H - -#include -#include -#include - -// We're running without an OS for this port. We don't provide any services except light protection. -#define NO_SYS 1 - -#define SYS_LIGHTWEIGHT_PROT 1 -#include -typedef uint32_t sys_prot_t; - -#define TCP_LISTEN_BACKLOG 1 - -// We'll put these into a proper ifdef once somebody implements an ethernet driver -#define LWIP_ARP 0 -#define LWIP_ETHERNET 0 - -#define LWIP_DNS 1 - -#define LWIP_NETCONN 0 -#define LWIP_SOCKET 0 - -// CIRCUITPY-CHANGE: #if instead of #ifdef -#if MICROPY_PY_LWIP_SLIP -#define LWIP_HAVE_SLIPIF 1 -#endif - -// For now, we can simply define this as a macro for the timer code. But this function isn't -// universal and other ports will need to do something else. It may be necessary to move -// things like this into a port-provided header file. -#define sys_now mp_hal_ticks_ms - -#endif // MICROPY_INCLUDED_EXTMOD_LWIP_INCLUDE_LWIPOPTS_H diff --git a/extmod/modasyncio.c b/extmod/modasyncio.c index 4672f6940c1..f73d32baf6d 100644 --- a/extmod/modasyncio.c +++ b/extmod/modasyncio.c @@ -58,6 +58,9 @@ typedef struct _mp_obj_task_t { typedef struct _mp_obj_task_queue_t { mp_obj_base_t base; mp_obj_task_t *heap; + #if MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK + mp_obj_t push_callback; + #endif } mp_obj_task_queue_t; static const mp_obj_type_t task_queue_type; @@ -105,9 +108,16 @@ static int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) { static mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { (void)args; - mp_arg_check_num(n_args, n_kw, 0, 0, false); + mp_arg_check_num(n_args, n_kw, 0, MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK ? 1 : 0, false); mp_obj_task_queue_t *self = mp_obj_malloc(mp_obj_task_queue_t, type); self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt); + #if MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK + if (n_args == 1) { + self->push_callback = args[0]; + } else { + self->push_callback = MP_OBJ_NULL; + } + #endif return MP_OBJ_FROM_PTR(self); } @@ -132,6 +142,11 @@ static mp_obj_t task_queue_push(size_t n_args, const mp_obj_t *args) { task->ph_key = args[2]; } self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, TASK_PAIRHEAP(self->heap), TASK_PAIRHEAP(task)); + #if MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK + if (self->push_callback != MP_OBJ_NULL) { + mp_call_function_1(self->push_callback, MP_OBJ_NEW_SMALL_INT(0)); + } + #endif return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_obj, 2, 3, task_queue_push); @@ -160,11 +175,6 @@ static const mp_rom_map_elem_t task_queue_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_push), MP_ROM_PTR(&task_queue_push_obj) }, { MP_ROM_QSTR(MP_QSTR_pop), MP_ROM_PTR(&task_queue_pop_obj) }, { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) }, - - // CIRCUITPY-CHANGE: Remove these in CircuitPython 10.0.0 - { MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_obj) }, - { MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_obj) }, - { MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_obj) }, }; static MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table); diff --git a/extmod/moddeflate.c b/extmod/moddeflate.c index c0c3bb26a8b..920b898b2cc 100644 --- a/extmod/moddeflate.c +++ b/extmod/moddeflate.c @@ -142,7 +142,7 @@ static bool deflateio_init_read(mp_obj_deflateio_t *self) { } } - size_t window_len = 1 << wbits; + size_t window_len = (size_t)1 << wbits; self->read->window = m_new(uint8_t, window_len); uzlib_uncompress_init(&self->read->decomp, self->read->window, window_len); @@ -168,16 +168,20 @@ static bool deflateio_init_write(mp_obj_deflateio_t *self) { const mp_stream_p_t *stream = mp_get_stream_raise(self->stream, MP_STREAM_OP_WRITE); - self->write = m_new_obj(mp_obj_deflateio_write_t); - self->write->input_len = 0; - int wbits = self->window_bits; if (wbits == 0) { // Same default wbits for all formats. wbits = DEFLATEIO_DEFAULT_WBITS; } + + // Allocate the large window before allocating the mp_obj_deflateio_write_t, in case the + // window allocation fails the mp_obj_deflateio_t object will remain in a consistent state. size_t window_len = 1 << wbits; - self->write->window = m_new(uint8_t, window_len); + uint8_t *window = m_new(uint8_t, window_len); + + self->write = m_new_obj(mp_obj_deflateio_write_t); + self->write->window = window; + self->write->input_len = 0; uzlib_lz77_init(&self->write->lz77, self->write->window, window_len); self->write->lz77.dest_write_data = self; diff --git a/extmod/modjson.c b/extmod/modjson.c index 67da36f0ccf..77f4a336aa8 100644 --- a/extmod/modjson.c +++ b/extmod/modjson.c @@ -227,7 +227,8 @@ static mp_obj_t _mod_json_load(mp_obj_t stream_obj, bool return_first_json) { for (;;) { cont: if (S_END(s)) { - break; + // Input finished abruptly in the middle of a composite entity. + goto fail; } mp_obj_t next = MP_OBJ_NULL; bool enter = false; diff --git a/extmod/modos.c b/extmod/modos.c index 7f1e31fba77..69fdc3fac0a 100644 --- a/extmod/modos.c +++ b/extmod/modos.c @@ -153,9 +153,6 @@ static const mp_rom_map_elem_t os_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_putenv), MP_ROM_PTR(&mp_os_putenv_obj) }, { MP_ROM_QSTR(MP_QSTR_unsetenv), MP_ROM_PTR(&mp_os_unsetenv_obj) }, #endif - #if MICROPY_PY_OS_SEP - { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) }, - #endif #if MICROPY_PY_OS_SYNC { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&mp_os_sync_obj) }, #endif @@ -170,16 +167,19 @@ static const mp_rom_map_elem_t os_module_globals_table[] = { #endif #if MICROPY_VFS + { MP_ROM_QSTR(MP_QSTR_sep), MP_ROM_QSTR(MP_QSTR__slash_) }, { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&mp_vfs_chdir_obj) }, { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&mp_vfs_getcwd_obj) }, { MP_ROM_QSTR(MP_QSTR_listdir), MP_ROM_PTR(&mp_vfs_listdir_obj) }, + #if MICROPY_VFS_WRITABLE { MP_ROM_QSTR(MP_QSTR_mkdir), MP_ROM_PTR(&mp_vfs_mkdir_obj) }, { MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&mp_vfs_remove_obj) }, { MP_ROM_QSTR(MP_QSTR_rename), MP_ROM_PTR(&mp_vfs_rename_obj) }, { MP_ROM_QSTR(MP_QSTR_rmdir), MP_ROM_PTR(&mp_vfs_rmdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove + #endif { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&mp_vfs_stat_obj) }, { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&mp_vfs_statvfs_obj) }, - { MP_ROM_QSTR(MP_QSTR_unlink), MP_ROM_PTR(&mp_vfs_remove_obj) }, // unlink aliases to remove #endif // The following are MicroPython extensions. diff --git a/extmod/modplatform.c b/extmod/modplatform.c index c6d4d31b97e..e1f5476c3b3 100644 --- a/extmod/modplatform.c +++ b/extmod/modplatform.c @@ -61,11 +61,49 @@ static mp_obj_t platform_libc_ver(size_t n_args, const mp_obj_t *pos_args, mp_ma } static MP_DEFINE_CONST_FUN_OBJ_KW(platform_libc_ver_obj, 0, platform_libc_ver); +#ifdef __riscv +static mp_obj_t platform_processor(void) { + #if (__riscv_xlen <= 64) && !defined(__linux__) + uintptr_t misa_csr = 0; + + // Load the MISA CSR directly. + __asm volatile ( + "csrr %0, misa \n" + : "+r" (misa_csr) + : + : + ); + + char processor_buffer[31] = { // "RV32"/"RV64" + up to 26 chars. + #if (__riscv_xlen < 64) + "RV32" + #else + "RV64" + #endif + }; + mp_uint_t offset = 4; + for (mp_uint_t bit = 0; bit < 26; bit++) { + if (misa_csr & (1U << bit)) { + processor_buffer[offset++] = 'A' + bit; + } + } + + return mp_obj_new_str(processor_buffer, offset); + #else + return MP_OBJ_NEW_QSTR(MP_QSTR_); + #endif +} +static MP_DEFINE_CONST_FUN_OBJ_0(platform_processor_obj, platform_processor); +#endif + static const mp_rom_map_elem_t modplatform_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_platform) }, { MP_ROM_QSTR(MP_QSTR_platform), MP_ROM_PTR(&platform_platform_obj) }, { MP_ROM_QSTR(MP_QSTR_python_compiler), MP_ROM_PTR(&platform_python_compiler_obj) }, { MP_ROM_QSTR(MP_QSTR_libc_ver), MP_ROM_PTR(&platform_libc_ver_obj) }, + #ifdef __riscv + { MP_ROM_QSTR(MP_QSTR_processor), MP_ROM_PTR(&platform_processor_obj) }, + #endif }; static MP_DEFINE_CONST_DICT(modplatform_globals, modplatform_globals_table); diff --git a/extmod/modplatform.h b/extmod/modplatform.h index 56a50e53c54..a155f071cba 100644 --- a/extmod/modplatform.h +++ b/extmod/modplatform.h @@ -36,7 +36,11 @@ // See: https://sourceforge.net/p/predef/wiki/Home/ #if defined(__ARM_ARCH) +#if defined(__ARM_ARCH_ISA_A64) +#define MICROPY_PLATFORM_ARCH "aarch64" +#else #define MICROPY_PLATFORM_ARCH "arm" +#endif #elif defined(__x86_64__) || defined(_M_X64) #define MICROPY_PLATFORM_ARCH "x86_64" #elif defined(__i386__) || defined(_M_IX86) @@ -44,12 +48,22 @@ #elif defined(__xtensa__) #define MICROPY_PLATFORM_ARCH "xtensa" #elif defined(__riscv) +#if __riscv_xlen == 64 +#define MICROPY_PLATFORM_ARCH "riscv64" +#else #define MICROPY_PLATFORM_ARCH "riscv" +#endif #else #define MICROPY_PLATFORM_ARCH "" #endif -#if defined(__GNUC__) +#if defined(__clang__) +#define MICROPY_PLATFORM_COMPILER \ + "Clang " \ + MP_STRINGIFY(__clang_major__) "." \ + MP_STRINGIFY(__clang_minor__) "." \ + MP_STRINGIFY(__clang_patchlevel__) +#elif defined(__GNUC__) #define MICROPY_PLATFORM_COMPILER \ "GCC " \ MP_STRINGIFY(__GNUC__) "." \ @@ -83,12 +97,20 @@ #elif defined(__NEWLIB__) #define MICROPY_PLATFORM_LIBC_LIB "newlib" #define MICROPY_PLATFORM_LIBC_VER _NEWLIB_VERSION +#elif defined(_PICOLIBC__) +#define MICROPY_PLATFORM_LIBC_LIB "picolibc" +#define MICROPY_PLATFORM_LIBC_VER _PICOLIBC_VERSION +#elif defined(__ANDROID__) +#define MICROPY_PLATFORM_LIBC_LIB "bionic" +#define MICROPY_PLATFORM_LIBC_VER MP_STRINGIFY(__ANDROID_API__) #else #define MICROPY_PLATFORM_LIBC_LIB "" #define MICROPY_PLATFORM_LIBC_VER "" #endif -#if defined(__linux) +#if defined(__ANDROID__) +#define MICROPY_PLATFORM_SYSTEM "Android" +#elif defined(__linux) #define MICROPY_PLATFORM_SYSTEM "Linux" #elif defined(__unix__) #define MICROPY_PLATFORM_SYSTEM "Unix" diff --git a/extmod/modre.c b/extmod/modre.c index a7e784a6ac9..36fff1d1dc6 100644 --- a/extmod/modre.c +++ b/extmod/modre.c @@ -31,7 +31,7 @@ #include "py/runtime.h" #include "py/binary.h" #include "py/objstr.h" -#include "py/stackctrl.h" +#include "py/cstack.h" #if MICROPY_PY_BUILTINS_STR_UNICODE #include "py/unicode.h" @@ -39,7 +39,7 @@ #if MICROPY_PY_RE -#define re1_5_stack_chk() MP_STACK_CHECK() +#define re1_5_stack_chk() mp_cstack_check() #include "lib/re1.5/re1.5.h" @@ -194,11 +194,13 @@ static void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t mp_printf(print, "", self); } -static mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { - (void)n_args; +// Note: this function can't be named re_exec because it may clash with system headers, eg on FreeBSD +static mp_obj_t re_exec_helper(bool is_anchored, uint n_args, const mp_obj_t *args) { mp_obj_re_t *self; + bool was_compiled = false; if (mp_obj_is_type(args[0], (mp_obj_type_t *)&re_type)) { self = MP_OBJ_TO_PTR(args[0]); + was_compiled = true; } else { self = MP_OBJ_TO_PTR(mod_re_compile(1, args)); } @@ -206,37 +208,28 @@ static mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { size_t len; subj.begin_line = subj.begin = mp_obj_str_get_data(args[1], &len); subj.end = subj.begin + len; - // CIRCUITPY-CHANGE - #if MICROPY_PY_RE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME) - - if (n_args > 2) { - const mp_obj_type_t *self_type = mp_obj_get_type(args[1]); - mp_int_t str_len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(args[1])); - const byte *begin = (const byte *)subj.begin; - int pos = mp_obj_get_int(args[2]); - if (pos >= str_len) { - return mp_const_none; - } - if (pos < 0) { - pos = 0; + if (was_compiled && n_args > 2) { + // Arg #2 is starting-pos + mp_int_t startpos = mp_obj_get_int(args[2]); + if (startpos > (mp_int_t)len) { + startpos = len; + } else if (startpos < 0) { + startpos = 0; } - const byte *pos_ptr = str_index_to_ptr(self_type, begin, len, MP_OBJ_NEW_SMALL_INT(pos), true); - - const byte *endpos_ptr = (const byte *)subj.end; + subj.begin += startpos; if (n_args > 3) { - int endpos = mp_obj_get_int(args[3]); - if (endpos <= pos) { - return mp_const_none; + // Arg #3 is ending-pos + mp_int_t endpos = mp_obj_get_int(args[3]); + if (endpos > (mp_int_t)len) { + endpos = len; + } else if (endpos < startpos) { + endpos = startpos; } - // Will cap to length - endpos_ptr = str_index_to_ptr(self_type, begin, len, args[3], true); + subj.end = subj.begin_line + endpos; } - - subj.begin = (const char *)pos_ptr; - subj.end = (const char *)endpos_ptr; } - #endif + int caps_num = (self->re.sub + 1) * 2; mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, caps, char *, caps_num); // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char @@ -254,12 +247,12 @@ static mp_obj_t re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) { } static mp_obj_t re_match(size_t n_args, const mp_obj_t *args) { - return re_exec(true, n_args, args); + return re_exec_helper(true, n_args, args); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_match_obj, 2, 4, re_match); static mp_obj_t re_search(size_t n_args, const mp_obj_t *args) { - return re_exec(false, n_args, args); + return re_exec_helper(false, n_args, args); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_search_obj, 2, 4, re_search); @@ -457,6 +450,9 @@ static mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { const char *re_str = mp_obj_str_get_str(args[0]); int size = re1_5_sizecode(re_str); if (size == -1) { + #if MICROPY_ERROR_REPORTING >= MICROPY_ERROR_REPORTING_NORMAL + mp_raise_ValueError(MP_ERROR_TEXT("regex too complex")); + #endif goto error; } mp_obj_re_t *o = mp_obj_malloc_var(mp_obj_re_t, re.insts, char, size, (mp_obj_type_t *)&re_type); @@ -469,6 +465,7 @@ static mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) { int error = re1_5_compilecode(&o->re, re_str); if (error != 0) { error: + // CIRCUITPY-CHANGE: capitalized mp_raise_ValueError(MP_ERROR_TEXT("Error in regex")); } #if MICROPY_PY_RE_DEBUG diff --git a/extmod/modtime.c b/extmod/modtime.c index deb4bb4c9ac..ee898828a4a 100644 --- a/extmod/modtime.c +++ b/extmod/modtime.c @@ -53,26 +53,26 @@ // - weekday is 0-6 for Mon-Sun // - yearday is 1-366 static mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { + timeutils_struct_time_t tm; if (n_args == 0 || args[0] == mp_const_none) { // Get current date and time. - return mp_time_localtime_get(); + mp_time_localtime_get(&tm); } else { // Convert given seconds to tuple. - mp_int_t seconds = mp_obj_get_int(args[0]); - timeutils_struct_time_t tm; + mp_timestamp_t seconds = timeutils_obj_get_timestamp(args[0]); timeutils_seconds_since_epoch_to_struct_time(seconds, &tm); - mp_obj_t tuple[8] = { - tuple[0] = mp_obj_new_int(tm.tm_year), - tuple[1] = mp_obj_new_int(tm.tm_mon), - tuple[2] = mp_obj_new_int(tm.tm_mday), - tuple[3] = mp_obj_new_int(tm.tm_hour), - tuple[4] = mp_obj_new_int(tm.tm_min), - tuple[5] = mp_obj_new_int(tm.tm_sec), - tuple[6] = mp_obj_new_int(tm.tm_wday), - tuple[7] = mp_obj_new_int(tm.tm_yday), - }; - return mp_obj_new_tuple(8, tuple); } + mp_obj_t tuple[8] = { + mp_obj_new_int(tm.tm_year), + mp_obj_new_int(tm.tm_mon), + mp_obj_new_int(tm.tm_mday), + mp_obj_new_int(tm.tm_hour), + mp_obj_new_int(tm.tm_min), + mp_obj_new_int(tm.tm_sec), + mp_obj_new_int(tm.tm_wday), + mp_obj_new_int(tm.tm_yday), + }; + return mp_obj_new_tuple(8, tuple); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_time_localtime_obj, 0, 1, time_localtime); @@ -90,7 +90,7 @@ static mp_obj_t time_mktime(mp_obj_t tuple) { mp_raise_TypeError(MP_ERROR_TEXT("mktime needs a tuple of length 8 or 9")); } - return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]), + return timeutils_obj_from_timestamp(timeutils_mktime(mp_obj_get_int(elem[0]), mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]), mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5]))); } diff --git a/extmod/vfs.c b/extmod/vfs.c index e7230e5ca03..c4156990bcc 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -42,11 +42,15 @@ #include "extmod/vfs_lfs.h" #endif -// CIRCUITPY-CHANGE: handle undefined without a warning -#if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX +#if MICROPY_VFS_POSIX #include "extmod/vfs_posix.h" #endif + +#if CIRCUITPY_SDCARDIO +#include "shared-module/sdcardio/__init__.h" +#endif + // For mp_vfs_proxy_call, the maximum number of additional args that can be passed. // A fixed maximum size is used to avoid the need for a costly variable array. #define PROXY_MAX_ARGS (2) @@ -67,6 +71,10 @@ mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out) { // path is "" or "/" so return virtual root return MP_VFS_ROOT; } + // CIRCUITPY-CHANGE: Try and automount the SD card. + #if CIRCUITPY_SDCARDIO + automount_sd_card(); + #endif for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) { size_t len = vfs->len - 1; if (len == 0) { @@ -93,7 +101,7 @@ mp_vfs_mount_t *mp_vfs_lookup_path(const char *path, const char **path_out) { return MP_STATE_VM(vfs_cur); } -// Version of mp_vfs_lookup_path that takes and returns uPy string objects. +// Version of mp_vfs_lookup_path that takes and returns MicroPython string objects. static mp_vfs_mount_t *lookup_path(mp_obj_t path_in, mp_obj_t *path_out) { const char *path = mp_obj_str_get_str(path_in); const char *p_out; @@ -140,7 +148,7 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) { } // delegate to vfs.stat() method - mp_obj_t path_o = mp_obj_new_str(path_out, strlen(path_out)); + mp_obj_t path_o = mp_obj_new_str_from_cstr(path_out); mp_obj_t stat; nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { @@ -203,22 +211,36 @@ static mp_obj_t mp_vfs_autodetect(mp_obj_t bdev_obj) { } mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_readonly, ARG_mkfs }; + if (n_args == 0) { + // zero-args, output a table of all current mountpoints + mp_obj_t mount_list = mp_obj_new_list(0, NULL); + mp_vfs_mount_t *vfsp = MP_STATE_VM(vfs_mount_table); + while (vfsp != NULL) { + mp_obj_t items[] = { vfsp->obj, mp_obj_new_str(vfsp->str, vfsp->len) }; + mp_obj_list_append(mount_list, mp_obj_new_tuple(MP_ARRAY_SIZE(items), items)); + vfsp = vfsp->next; + } + return mount_list; + } + + enum { ARG_fsobj, ARG_mount_point, ARG_readonly, ARG_mkfs }; static const mp_arg_t allowed_args[] = { + { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_readonly, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_FALSE} }, { MP_QSTR_mkfs, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_FALSE} }, }; // parse args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 2, pos_args + 2, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); // get the mount point size_t mnt_len; - const char *mnt_str = mp_obj_str_get_data(pos_args[1], &mnt_len); + const char *mnt_str = mp_obj_str_get_data(args[ARG_mount_point].u_obj, &mnt_len); // see if we need to auto-detect and create the filesystem - mp_obj_t vfs_obj = pos_args[0]; + mp_obj_t vfs_obj = args[ARG_fsobj].u_obj; mp_obj_t dest[2]; mp_load_method_maybe(vfs_obj, MP_QSTR_mount, dest); if (dest[0] == MP_OBJ_NULL) { @@ -235,11 +257,13 @@ mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args vfs->next = NULL; // call the underlying object to do any mounting operation - mp_vfs_proxy_call(vfs, MP_QSTR_mount, 2, (mp_obj_t *)&args); + mp_arg_val_t *proxy_args = &args[ARG_readonly]; + size_t proxy_args_len = MP_ARRAY_SIZE(args) - ARG_readonly; + mp_vfs_proxy_call(vfs, MP_QSTR_mount, proxy_args_len, (mp_obj_t *)proxy_args); // check that the destination mount point is unused const char *path_out; - mp_vfs_mount_t *existing_mount = mp_vfs_lookup_path(mp_obj_str_get_str(pos_args[1]), &path_out); + mp_vfs_mount_t *existing_mount = mp_vfs_lookup_path(mp_obj_str_get_str(args[ARG_mount_point].u_obj), &path_out); if (existing_mount != MP_VFS_NONE && existing_mount != MP_VFS_ROOT) { if (vfs->len != 1 && existing_mount->len == 1) { // if root dir is mounted, still allow to mount something within a subdir of root @@ -263,7 +287,7 @@ mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_KW(mp_vfs_mount_obj, 2, mp_vfs_mount); +MP_DEFINE_CONST_FUN_OBJ_KW(mp_vfs_mount_obj, 0, mp_vfs_mount); mp_obj_t mp_vfs_umount(mp_obj_t mnt_in) { // remove vfs from the mount table @@ -274,7 +298,7 @@ mp_obj_t mp_vfs_umount(mp_obj_t mnt_in) { mnt_str = mp_obj_str_get_data(mnt_in, &mnt_len); } for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) { - if ((mnt_str != NULL && !memcmp(mnt_str, (*vfsp)->str, mnt_len + 1)) || (*vfsp)->obj == mnt_in) { + if ((mnt_str != NULL && mnt_len == (*vfsp)->len && !memcmp(mnt_str, (*vfsp)->str, mnt_len)) || (*vfsp)->obj == mnt_in) { vfs = *vfsp; *vfsp = (*vfsp)->next; break; @@ -311,8 +335,7 @@ mp_obj_t mp_vfs_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // CIRCUITPY-CHANGE: handle undefined without a warning - #if defined(MICROPY_VFS_POSIX) && MICROPY_VFS_POSIX + #if MICROPY_VFS_POSIX // If the file is an integer then delegate straight to the POSIX handler if (mp_obj_is_small_int(args[ARG_file].u_obj)) { return mp_vfs_posix_file_open(&mp_type_vfs_posix_textio, args[ARG_file].u_obj, args[ARG_mode].u_obj); @@ -367,8 +390,18 @@ mp_obj_t mp_vfs_getcwd(void) { } MP_DEFINE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj, mp_vfs_getcwd); -// CIRCUITPY-CHANGE: accessible from shared-module/os/__init__.c -mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) { +typedef struct _mp_vfs_ilistdir_it_t { + mp_obj_base_t base; + mp_fun_1_t iternext; + union { + mp_vfs_mount_t *vfs; + mp_obj_t iter; + } cur; + bool is_str; + bool is_iter; +} mp_vfs_ilistdir_it_t; + +static mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in) { mp_vfs_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in); if (self->is_iter) { // continue delegating to root dir @@ -435,6 +468,8 @@ mp_obj_t mp_vfs_listdir(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_vfs_listdir_obj, 0, 1, mp_vfs_listdir); +#if MICROPY_VFS_WRITABLE + mp_obj_t mp_vfs_mkdir(mp_obj_t path_in) { // CIRCUITPY-CHANGE: initialize mp_obj_t path_out = mp_const_none; @@ -472,6 +507,8 @@ mp_obj_t mp_vfs_rmdir(mp_obj_t path_in) { } MP_DEFINE_CONST_FUN_OBJ_1(mp_vfs_rmdir_obj, mp_vfs_rmdir); +#endif // MICROPY_VFS_WRITABLE + mp_obj_t mp_vfs_stat(mp_obj_t path_in) { mp_obj_t path_out; mp_vfs_mount_t *vfs = lookup_path(path_in, &path_out); @@ -541,6 +578,32 @@ int mp_vfs_mount_and_chdir_protected(mp_obj_t bdev, mp_obj_t mount_point) { return ret; } +#if MICROPY_VFS_ROM && MICROPY_VFS_ROM_IOCTL + +int mp_vfs_mount_romfs_protected(void) { + int ret; + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(MP_VFS_ROM_IOCTL_GET_SEGMENT), MP_OBJ_NEW_SMALL_INT(0) }; + mp_obj_t rom = mp_vfs_rom_ioctl(2, args); + mp_obj_t romfs = mp_call_function_1(MP_OBJ_FROM_PTR(&mp_type_vfs_rom), rom); + mp_obj_t mount_point = MP_OBJ_NEW_QSTR(MP_QSTR__slash_rom); + mp_call_function_2(MP_OBJ_FROM_PTR(&mp_vfs_mount_obj), romfs, mount_point); + #if MICROPY_PY_SYS_PATH_ARGV_DEFAULTS + // Add "/rom" and "/rom/lib" to `sys.path`. + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_rom)); + mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_rom_slash_lib)); + #endif + ret = 0; // success + nlr_pop(); + } else { + ret = -MP_EIO; + } + return ret; +} + +#endif + MP_REGISTER_ROOT_POINTER(struct _mp_vfs_mount_t *vfs_cur); MP_REGISTER_ROOT_POINTER(struct _mp_vfs_mount_t *vfs_mount_table); diff --git a/extmod/vfs.h b/extmod/vfs.h index c6c471d476c..699232e56cd 100644 --- a/extmod/vfs.h +++ b/extmod/vfs.h @@ -52,6 +52,8 @@ #define MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED (0x0020) // Bit set when something has claimed the right to mutate the blockdev. #define MP_BLOCKDEV_FLAG_LOCKED (0x0040) +// Ignore write protections. Used to override other flags temporarily. +#define MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION (0x0080) // constants for block protocol ioctl #define MP_BLOCKDEV_IOCTL_INIT (1) @@ -61,6 +63,13 @@ #define MP_BLOCKDEV_IOCTL_BLOCK_SIZE (5) #define MP_BLOCKDEV_IOCTL_BLOCK_ERASE (6) +// Constants for vfs.rom_ioctl() function. +#define MP_VFS_ROM_IOCTL_GET_NUMBER_OF_SEGMENTS (1) // rom_ioctl(1) +#define MP_VFS_ROM_IOCTL_GET_SEGMENT (2) // rom_ioctl(2, ) +#define MP_VFS_ROM_IOCTL_WRITE_PREPARE (3) // rom_ioctl(3, , ) +#define MP_VFS_ROM_IOCTL_WRITE (4) // rom_ioctl(4, , , ) +#define MP_VFS_ROM_IOCTL_WRITE_COMPLETE (5) // rom_ioctl(5, ) + // At the moment the VFS protocol just has import_stat, but could be extended to other methods typedef struct _mp_vfs_proto_t { // CIRCUITPY-CHANGE @@ -71,6 +80,10 @@ typedef struct _mp_vfs_proto_t { typedef struct _mp_vfs_blockdev_t { uint16_t flags; size_t block_size; + #if CIRCUITPY_SAVES_PARTITION_SIZE > 0 + size_t offset; + int size; + #endif mp_obj_t readblocks[5]; mp_obj_t writeblocks[5]; // new protocol uses just ioctl, old uses sync (optional) and count @@ -90,19 +103,6 @@ typedef struct _mp_vfs_mount_t { struct _mp_vfs_mount_t *next; } mp_vfs_mount_t; -// CIRCUITPY-CHANGE: allow outside use of ilistdir_it_iternext -typedef struct _mp_vfs_ilistdir_it_t { - mp_obj_base_t base; - mp_fun_1_t iternext; - union { - mp_vfs_mount_t *vfs; - mp_obj_t iter; - } cur; - bool is_str; - bool is_iter; -} mp_vfs_ilistdir_it_t; - -mp_obj_t mp_vfs_ilistdir_it_iternext(mp_obj_t self_in); void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev); int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, uint8_t *buf); int mp_vfs_blockdev_read_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t block_off, size_t len, uint8_t *buf); @@ -119,14 +119,19 @@ mp_obj_t mp_vfs_chdir(mp_obj_t path_in); mp_obj_t mp_vfs_getcwd(void); mp_obj_t mp_vfs_ilistdir(size_t n_args, const mp_obj_t *args); mp_obj_t mp_vfs_listdir(size_t n_args, const mp_obj_t *args); +#if MICROPY_VFS_WRITABLE mp_obj_t mp_vfs_mkdir(mp_obj_t path_in); mp_obj_t mp_vfs_remove(mp_obj_t path_in); mp_obj_t mp_vfs_rename(mp_obj_t old_path_in, mp_obj_t new_path_in); mp_obj_t mp_vfs_rmdir(mp_obj_t path_in); +#endif mp_obj_t mp_vfs_stat(mp_obj_t path_in); mp_obj_t mp_vfs_statvfs(mp_obj_t path_in); int mp_vfs_mount_and_chdir_protected(mp_obj_t bdev, mp_obj_t mount_point); +#if MICROPY_VFS_ROM && MICROPY_VFS_ROM_IOCTL +int mp_vfs_mount_romfs_protected(void); +#endif MP_DECLARE_CONST_FUN_OBJ_KW(mp_vfs_mount_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_umount_obj); @@ -135,11 +140,21 @@ MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_chdir_obj); MP_DECLARE_CONST_FUN_OBJ_0(mp_vfs_getcwd_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_vfs_ilistdir_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_vfs_listdir_obj); +#if MICROPY_VFS_WRITABLE MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_mkdir_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_remove_obj); MP_DECLARE_CONST_FUN_OBJ_2(mp_vfs_rename_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_rmdir_obj); +#endif MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_stat_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_vfs_statvfs_obj); +#if MICROPY_VFS_ROM_IOCTL +// When MICROPY_VFS_ROM_IOCTL is enabled a port must define the following function. +// This is a generic interface to allow querying and modifying the user-accessible, +// read-only memory area of a device, if it is configured with such an area. +// Supported ioctl commands are given by MP_VFS_ROM_IOCTL_xxx. +mp_obj_t mp_vfs_rom_ioctl(size_t n_args, const mp_obj_t *args); +#endif + #endif // MICROPY_INCLUDED_EXTMOD_VFS_H diff --git a/extmod/vfs_blockdev.c b/extmod/vfs_blockdev.c index eda5cecc147..74d1262364e 100644 --- a/extmod/vfs_blockdev.c +++ b/extmod/vfs_blockdev.c @@ -63,7 +63,16 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) { #endif #if CIRCUITPY_SDIOIO if (mp_obj_get_type(bdev) == &sdioio_SDCard_type) { - // TODO: Enable native blockdev for SDIO too. + self->flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL; + self->readblocks[0] = mp_const_none; + self->readblocks[1] = bdev; + self->readblocks[2] = (mp_obj_t)sdioio_sdcard_readblocks; // native version + self->writeblocks[0] = mp_const_none; + self->writeblocks[1] = bdev; + self->writeblocks[2] = (mp_obj_t)sdioio_sdcard_writeblocks; // native version + self->u.ioctl[0] = mp_const_none; + self->u.ioctl[1] = bdev; + self->u.ioctl[2] = (mp_obj_t)sdioio_sdcard_ioctl; // native version } #endif if (self->u.ioctl[0] != MP_OBJ_NULL) { @@ -76,6 +85,34 @@ void mp_vfs_blockdev_init(mp_vfs_blockdev_t *self, mp_obj_t bdev) { } } +// Helper function to minimise code size of read/write functions +// note the n_args argument is moved to the end for further code size reduction (args keep same position in caller and callee). +static int mp_vfs_blockdev_call_rw(mp_obj_t *args, size_t block_num, size_t block_off, size_t len, void *buf, size_t n_args) { + mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, buf}; + args[2] = MP_OBJ_NEW_SMALL_INT(block_num); + args[3] = MP_OBJ_FROM_PTR(&ar); + args[4] = MP_OBJ_NEW_SMALL_INT(block_off); // ignored for n_args == 2 + mp_obj_t ret = mp_call_method_n_kw(n_args, 0, args); + + if (ret == mp_const_none) { + return 0; + } else { + // Some block devices return a bool indicating success, so + // convert those to an errno integer code. + if (ret == mp_const_true) { + return 0; + } else if (ret == mp_const_false) { + return -MP_EIO; + } + // Block device functions are expected to return 0 on success + // and negative integer on errors. Check for positive integer + // results as some callers (i.e. littlefs) will produce corrupt + // results from these. + int i = mp_obj_get_int(ret); + return i > 0 ? (-MP_EINVAL) : i; + } +} + int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, uint8_t *buf) { if (self->flags & MP_BLOCKDEV_FLAG_NATIVE) { // CIRCUITPY-CHANGE: Pass the blockdev object into native readblocks so @@ -83,26 +120,12 @@ int mp_vfs_blockdev_read(mp_vfs_blockdev_t *self, size_t block_num, size_t num_b mp_uint_t (*f)(mp_obj_t self, uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->readblocks[2]; return f(self->readblocks[1], buf, block_num, num_blocks); } else { - mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, buf}; - self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num); - self->readblocks[3] = MP_OBJ_FROM_PTR(&ar); - mp_call_method_n_kw(2, 0, self->readblocks); - // TODO handle error return - return 0; + return mp_vfs_blockdev_call_rw(self->readblocks, block_num, 0, num_blocks * self->block_size, buf, 2); } } int mp_vfs_blockdev_read_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t block_off, size_t len, uint8_t *buf) { - mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, buf}; - self->readblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num); - self->readblocks[3] = MP_OBJ_FROM_PTR(&ar); - self->readblocks[4] = MP_OBJ_NEW_SMALL_INT(block_off); - mp_obj_t ret = mp_call_method_n_kw(3, 0, self->readblocks); - if (ret == mp_const_none) { - return 0; - } else { - return MP_OBJ_SMALL_INT_VALUE(ret); - } + return mp_vfs_blockdev_call_rw(self->readblocks, block_num, block_off, len, buf, 3); } int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_blocks, const uint8_t *buf) { @@ -117,12 +140,7 @@ int mp_vfs_blockdev_write(mp_vfs_blockdev_t *self, size_t block_num, size_t num_ mp_uint_t (*f)(mp_obj_t self, const uint8_t *, uint32_t, uint32_t) = (void *)(uintptr_t)self->writeblocks[2]; return f(self->writeblocks[1], buf, block_num, num_blocks); } else { - mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, num_blocks *self->block_size, (void *)buf}; - self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num); - self->writeblocks[3] = MP_OBJ_FROM_PTR(&ar); - mp_call_method_n_kw(2, 0, self->writeblocks); - // TODO handle error return - return 0; + return mp_vfs_blockdev_call_rw(self->writeblocks, block_num, 0, num_blocks * self->block_size, (void *)buf, 2); } } @@ -131,17 +149,7 @@ int mp_vfs_blockdev_write_ext(mp_vfs_blockdev_t *self, size_t block_num, size_t // read-only block device return -MP_EROFS; } - - mp_obj_array_t ar = {{&mp_type_bytearray}, BYTEARRAY_TYPECODE, 0, len, (void *)buf}; - self->writeblocks[2] = MP_OBJ_NEW_SMALL_INT(block_num); - self->writeblocks[3] = MP_OBJ_FROM_PTR(&ar); - self->writeblocks[4] = MP_OBJ_NEW_SMALL_INT(block_off); - mp_obj_t ret = mp_call_method_n_kw(3, 0, self->writeblocks); - if (ret == mp_const_none) { - return 0; - } else { - return MP_OBJ_SMALL_INT_VALUE(ret); - } + return mp_vfs_blockdev_call_rw(self->writeblocks, block_num, block_off, len, (void *)buf, 3); } mp_obj_t mp_vfs_blockdev_ioctl(mp_vfs_blockdev_t *self, uintptr_t cmd, uintptr_t arg) { diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c index 85541d3cf01..95ed79eb18b 100644 --- a/extmod/vfs_fat.c +++ b/extmod/vfs_fat.c @@ -38,6 +38,7 @@ // CIRCUITPY-CHANGE: extra includes #include +#include "py/gc.h" #include "py/obj.h" #include "py/objproperty.h" #include "py/runtime.h" @@ -57,7 +58,7 @@ // CIRCUITPY-CHANGE // Factoring this common call saves about 90 bytes. -static NORETURN void mp_raise_OSError_fresult(FRESULT res) { +static MP_NORETURN void mp_raise_OSError_fresult(FRESULT res) { mp_raise_OSError(fresult_to_errno_table[res]); } @@ -133,6 +134,11 @@ static mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) { mp_raise_OSError_fresult(res); } + // set the filesystem label if it's configured + #ifdef MICROPY_HW_FLASH_FS_LABEL + f_setlabel(&vfs->fatfs, MICROPY_HW_FLASH_FS_LABEL); + #endif + return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_mkfs_fun_obj, fat_vfs_mkfs); @@ -163,7 +169,7 @@ static mp_obj_t mp_vfs_fat_ilistdir_it_iternext(mp_obj_t self_in) { // make 4-tuple with info about this entry mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL)); if (self->is_str) { - t->items[0] = mp_obj_new_str(fn, strlen(fn)); + t->items[0] = mp_obj_new_str_from_cstr(fn); } else { t->items[0] = mp_obj_new_bytes((const byte *)fn, strlen(fn)); } @@ -322,7 +328,7 @@ static mp_obj_t fat_vfs_getcwd(mp_obj_t vfs_in) { // CIRCUITPY-CHANGE mp_raise_OSError_fresult(res); } - return mp_obj_new_str(buf, strlen(buf)); + return mp_obj_new_str_from_cstr(buf); } static MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getcwd_obj, fat_vfs_getcwd); @@ -342,7 +348,10 @@ static mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) { FRESULT res = f_stat(&self->fatfs, path, &fno); if (res != FR_OK) { // CIRCUITPY-CHANGE - mp_raise_OSError_fresult(res); + if (gc_alloc_possible()) { + mp_raise_OSError_fresult(res); + } + return mp_const_none; } } @@ -418,13 +427,10 @@ static MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_statvfs_obj, fat_vfs_statvfs); static mp_obj_t vfs_fat_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs) { fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in); - // Read-only device indicated by writeblocks[0] == MP_OBJ_NULL. - // User can specify read-only device by: - // 1. readonly=True keyword argument - // 2. nonexistent writeblocks method (then writeblocks[0] == MP_OBJ_NULL already) - if (mp_obj_is_true(readonly)) { - self->blockdev.writeblocks[0] = MP_OBJ_NULL; - } + // CIRCUITPY-CHANGE: Use MP_BLOCKDEV_FLAG_USB_WRITABLE instead of writeblocks[0] =/!= MP_OBJ_NULL + // to specify read-write. + // If readonly to Python, it's writable by USB and vice versa. + filesystem_set_writable_by_usb(self, mp_obj_is_true(readonly)); // check if we need to make the filesystem FRESULT res = (self->blockdev.flags & MP_BLOCKDEV_FLAG_NO_FILESYSTEM) ? FR_NO_FILESYSTEM : FR_OK; @@ -484,12 +490,9 @@ static mp_obj_t vfs_fat_getreadonly(mp_obj_t self_in) { return mp_obj_new_bool(!filesystem_is_writable_by_python(self)); } static MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getreadonly_obj, vfs_fat_getreadonly); -static const mp_obj_property_t fat_vfs_readonly_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&fat_vfs_getreadonly_obj, - MP_ROM_NONE, - MP_ROM_NONE}, -}; + +static MP_PROPERTY_GETTER(fat_vfs_readonly_obj, + (mp_obj_t)&fat_vfs_getreadonly_obj); #if MICROPY_FATFS_USE_LABEL static mp_obj_t vfs_fat_getlabel(mp_obj_t self_in) { @@ -517,12 +520,10 @@ static mp_obj_t vfs_fat_setlabel(mp_obj_t self_in, mp_obj_t label_in) { return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_setlabel_obj, vfs_fat_setlabel); -static const mp_obj_property_t fat_vfs_label_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&fat_vfs_getlabel_obj, - (mp_obj_t)&fat_vfs_setlabel_obj, - MP_ROM_NONE}, -}; + +static MP_PROPERTY_GETSET(fat_vfs_label_obj, + (mp_obj_t)&fat_vfs_getlabel_obj, + (mp_obj_t)&fat_vfs_setlabel_obj); #endif static const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = { diff --git a/extmod/vfs_fat_diskio.c b/extmod/vfs_fat_diskio.c index 6f500104d1e..591da07eb56 100644 --- a/extmod/vfs_fat_diskio.c +++ b/extmod/vfs_fat_diskio.c @@ -43,6 +43,9 @@ #include "lib/oofatfs/diskio.h" #include "extmod/vfs_fat.h" +// CIRCUITPY-CHANGE +#include "supervisor/filesystem.h" + typedef void *bdev_t; static fs_user_mount_t *disk_get_device(void *bdev) { return (fs_user_mount_t *)bdev; @@ -153,7 +156,8 @@ DRESULT disk_ioctl( if (ret != mp_const_none && MP_OBJ_SMALL_INT_VALUE(ret) != 0) { // error initialising stat = STA_NOINIT; - } else if (vfs->blockdev.writeblocks[0] == MP_OBJ_NULL) { + // CIRCUITPY-CHANGE: writability from Python check + } else if (!filesystem_is_writable_by_python(vfs)) { stat = STA_PROTECT; } else { stat = 0; diff --git a/extmod/vfs_lfsx.c b/extmod/vfs_lfsx.c index 19da4417e6d..bbdd21cfb91 100644 --- a/extmod/vfs_lfsx.c +++ b/extmod/vfs_lfsx.c @@ -104,6 +104,12 @@ static void MP_VFS_LFSx(init_config)(MP_OBJ_VFS_LFSx * self, mp_obj_t bdev, size config->read_buffer = m_new(uint8_t, config->cache_size); config->prog_buffer = m_new(uint8_t, config->cache_size); config->lookahead_buffer = m_new(uint8_t, config->lookahead_size); + #ifdef LFS2_MULTIVERSION + // This can be set to override the on-disk lfs version. + // eg. for compat with lfs2 < v2.6 add the following to make: + // CFLAGS += '-DLFS2_MULTIVERSION=0x00020000' + config->disk_version = LFS2_MULTIVERSION; + #endif #endif } @@ -192,7 +198,7 @@ static mp_obj_t MP_VFS_LFSx(ilistdir_it_iternext)(mp_obj_t self_in) { // make 4-tuple with info about this entry mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL)); if (self->is_str) { - t->items[0] = mp_obj_new_str(info.name, strlen(info.name)); + t->items[0] = mp_obj_new_str_from_cstr(info.name); } else { t->items[0] = mp_obj_new_bytes((const byte *)info.name, strlen(info.name)); } @@ -300,7 +306,7 @@ static mp_obj_t MP_VFS_LFSx(chdir)(mp_obj_t self_in, mp_obj_t path_in) { struct LFSx_API (info) info; int ret = LFSx_API(stat)(&self->lfs, path, &info); if (ret < 0 || info.type != LFSx_MACRO(_TYPE_DIR)) { - mp_raise_OSError(-MP_ENOENT); + mp_raise_OSError(MP_ENOENT); } } @@ -378,7 +384,7 @@ static mp_obj_t MP_VFS_LFSx(stat)(mp_obj_t self_in, mp_obj_t path_in) { mp_raise_OSError(-ret); } - mp_uint_t mtime = 0; + mp_timestamp_t mtime = 0; #if LFS_BUILD_VERSION == 2 uint8_t mtime_buf[8]; lfs2_ssize_t sz = lfs2_getattr(&self->lfs, path, LFS_ATTR_MTIME, &mtime_buf, sizeof(mtime_buf)); @@ -400,9 +406,9 @@ static mp_obj_t MP_VFS_LFSx(stat)(mp_obj_t self_in, mp_obj_t path_in) { t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid t->items[6] = mp_obj_new_int_from_uint(info.size); // st_size - t->items[7] = mp_obj_new_int_from_uint(mtime); // st_atime - t->items[8] = mp_obj_new_int_from_uint(mtime); // st_mtime - t->items[9] = mp_obj_new_int_from_uint(mtime); // st_ctime + t->items[7] = timeutils_obj_from_timestamp(mtime); // st_atime + t->items[8] = timeutils_obj_from_timestamp(mtime); // st_mtime + t->items[9] = timeutils_obj_from_timestamp(mtime); // st_ctime return MP_OBJ_FROM_PTR(t); } diff --git a/extmod/vfs_lfsx_file.c b/extmod/vfs_lfsx_file.c index ab5cce50088..56daa53e068 100644 --- a/extmod/vfs_lfsx_file.c +++ b/extmod/vfs_lfsx_file.c @@ -90,9 +90,9 @@ mp_obj_t MP_VFS_LFSx(file_open)(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mod } #if LFS_BUILD_VERSION == 1 - MP_OBJ_VFS_LFSx_FILE *o = mp_obj_malloc_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, uint8_t, self->lfs.cfg->prog_size, type); + MP_OBJ_VFS_LFSx_FILE *o = mp_obj_malloc_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, file_buffer, uint8_t, self->lfs.cfg->prog_size, type); #else - MP_OBJ_VFS_LFSx_FILE *o = mp_obj_malloc_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, uint8_t, self->lfs.cfg->cache_size, type); + MP_OBJ_VFS_LFSx_FILE *o = mp_obj_malloc_var_with_finaliser(MP_OBJ_VFS_LFSx_FILE, file_buffer, uint8_t, self->lfs.cfg->cache_size, type); #endif o->vfs = self; #if !MICROPY_GC_CONSERVATIVE_CLEAR diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c index ed4c06e3673..27f833e802f 100644 --- a/extmod/vfs_posix.c +++ b/extmod/vfs_posix.c @@ -137,7 +137,7 @@ static mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, siz vstr_add_char(&vfs->root, '/'); } vfs->root_len = vfs->root.len; - vfs->readonly = false; + vfs->readonly = !MICROPY_VFS_POSIX_WRITABLE; return MP_OBJ_FROM_PTR(vfs); } @@ -160,10 +160,21 @@ static mp_obj_t vfs_posix_umount(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_umount_obj, vfs_posix_umount); +static inline bool vfs_posix_is_readonly(mp_obj_vfs_posix_t *self) { + return !MICROPY_VFS_POSIX_WRITABLE || self->readonly; +} + +static void vfs_posix_require_writable(mp_obj_t self_in) { + mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); + if (vfs_posix_is_readonly(self)) { + mp_raise_OSError(MP_EROFS); + } +} + static mp_obj_t vfs_posix_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in) { mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); const char *mode = mp_obj_str_get_str(mode_in); - if (self->readonly + if (vfs_posix_is_readonly(self) && (strchr(mode, 'w') != NULL || strchr(mode, 'a') != NULL || strchr(mode, '+') != NULL)) { mp_raise_OSError(MP_EROFS); } @@ -194,7 +205,7 @@ static mp_obj_t vfs_posix_getcwd(mp_obj_t self_in) { } #endif } - return mp_obj_new_str(ret, strlen(ret)); + return mp_obj_new_str_from_cstr(ret); } static MP_DEFINE_CONST_FUN_OBJ_1(vfs_posix_getcwd_obj, vfs_posix_getcwd); @@ -234,7 +245,7 @@ static mp_obj_t vfs_posix_ilistdir_it_iternext(mp_obj_t self_in) { mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); if (self->is_str) { - t->items[0] = mp_obj_new_str(fn, strlen(fn)); + t->items[0] = mp_obj_new_str_from_cstr(fn); } else { t->items[0] = mp_obj_new_bytes((const byte *)fn, strlen(fn)); } @@ -303,6 +314,7 @@ typedef struct _mp_obj_listdir_t { } mp_obj_listdir_t; static mp_obj_t vfs_posix_mkdir(mp_obj_t self_in, mp_obj_t path_in) { + vfs_posix_require_writable(self_in); mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); const char *path = vfs_posix_get_path_str(self, path_in); MP_THREAD_GIL_EXIT(); @@ -320,11 +332,13 @@ static mp_obj_t vfs_posix_mkdir(mp_obj_t self_in, mp_obj_t path_in) { static MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_mkdir_obj, vfs_posix_mkdir); static mp_obj_t vfs_posix_remove(mp_obj_t self_in, mp_obj_t path_in) { + vfs_posix_require_writable(self_in); return vfs_posix_fun1_helper(self_in, path_in, unlink); } static MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_remove_obj, vfs_posix_remove); static mp_obj_t vfs_posix_rename(mp_obj_t self_in, mp_obj_t old_path_in, mp_obj_t new_path_in) { + vfs_posix_require_writable(self_in); mp_obj_vfs_posix_t *self = MP_OBJ_TO_PTR(self_in); const char *old_path = vfs_posix_get_path_str(self, old_path_in); const char *new_path = vfs_posix_get_path_str(self, new_path_in); @@ -339,6 +353,7 @@ static mp_obj_t vfs_posix_rename(mp_obj_t self_in, mp_obj_t old_path_in, mp_obj_ static MP_DEFINE_CONST_FUN_OBJ_3(vfs_posix_rename_obj, vfs_posix_rename); static mp_obj_t vfs_posix_rmdir(mp_obj_t self_in, mp_obj_t path_in) { + vfs_posix_require_writable(self_in); return vfs_posix_fun1_helper(self_in, path_in, rmdir); } static MP_DEFINE_CONST_FUN_OBJ_2(vfs_posix_rmdir_obj, vfs_posix_rmdir); diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c index bc06bc74db1..501550cb502 100644 --- a/extmod/vfs_posix_file.c +++ b/extmod/vfs_posix_file.c @@ -160,12 +160,27 @@ static mp_uint_t vfs_posix_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_ #if defined(__APPLE__) #define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == ENOTSUP) #elif defined(_MSC_VER) + // In debug builds fsync (i.e. _commit on windows) will generate a debug report via _ASSERTE when + // called with non-redirected stdin/stdout/stderr (i.e. _isatty) handles because FlushFileBuffers, + // which it calls internally, will fail since console output is not buffered. + // In release builds it also fails, but merely returns an error which is handled appropriately below. + // The check for the handle being stdin/stdout/stderr is added explicitly because according to + // the documentation _isatty is also true for serial ports for instance. + #ifdef _DEBUG + if ((o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO) && _isatty(o->fd)) { + return 0; + } + #endif #define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL || err == EBADF) #else #define VFS_POSIX_STREAM_STDIO_ERR_CATCH (err == EINVAL) #endif MP_HAL_RETRY_SYSCALL(ret, fsync(o->fd), { if (VFS_POSIX_STREAM_STDIO_ERR_CATCH + // Note: comparing fd against the standard FILENOs is technically not correct, for example: + // sys.stderr.close() in Python code results in close(STDERR_FILENO) here, but because + // open() uses the next available file descriptor, opening an arbitrary file with + // fd = open('/some/file') means that fd becomes STDERR_FILENO. && (o->fd == STDIN_FILENO || o->fd == STDOUT_FILENO || o->fd == STDERR_FILENO)) { return 0; } diff --git a/extmod/vfs_reader.c b/extmod/vfs_reader.c index 80d0fa6344a..6c36770295b 100644 --- a/extmod/vfs_reader.c +++ b/extmod/vfs_reader.c @@ -83,8 +83,19 @@ void mp_reader_new_file(mp_reader_t *reader, qstr filename) { }; mp_obj_t file = mp_vfs_open(MP_ARRAY_SIZE(args), &args[0], (mp_map_t *)&mp_const_empty_map); - const mp_stream_p_t *stream_p = mp_get_stream(file); + const mp_stream_p_t *stream_p = mp_get_stream_raise(file, MP_STREAM_OP_READ); int errcode = 0; + + #if MICROPY_VFS_ROM + // Check if the stream can be memory mapped. + mp_buffer_info_t bufinfo; + if (mp_get_buffer(file, &bufinfo, MP_BUFFER_READ)) { + mp_reader_new_mem(reader, bufinfo.buf, bufinfo.len, MP_READER_IS_ROM); + return; + } + #endif + + // Determine how big the input buffer should be, if the stream requests a certain size or not. mp_uint_t bufsize = stream_p->ioctl(file, MP_STREAM_GET_BUFFER_SIZE, 0, &errcode); if (bufsize == MP_STREAM_ERROR || bufsize == 0) { // bufsize == 0 is included here to support mpremote v1.21 and older where mount file ioctl @@ -94,6 +105,7 @@ void mp_reader_new_file(mp_reader_t *reader, qstr filename) { bufsize = MIN(MICROPY_READER_VFS_MAX_BUFFER_SIZE, MAX(MICROPY_READER_VFS_MIN_BUFFER_SIZE, bufsize)); } + // Create the reader. mp_reader_vfs_t *rf = m_new_obj_var(mp_reader_vfs_t, buf, byte, bufsize); rf->file = file; rf->bufsize = bufsize; diff --git a/extmod/vfs_rom.c b/extmod/vfs_rom.c new file mode 100644 index 00000000000..7d814cb9805 --- /dev/null +++ b/extmod/vfs_rom.c @@ -0,0 +1,471 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Damien P. George + * + * 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. + */ + +// ROMFS filesystem format +// ======================= +// +// ROMFS is a flexible and extensible filesystem format designed to represent a +// directory hierarchy with files, where those files are read-only and their data +// can be memory mapped. +// +// Concepts: +// - varuint: An unsigned integer that is encoded in a variable number of bytes. It is +// stored big-endian with the high bit of the byte set if there are following bytes. +// - record: A variable sized element with a type. It is stored as two varuint's and then +// a payload. The first varuint is the record kind and the second varuint is the +// payload length (which may be zero bytes long). +// +// A ROMFS filesystem is a record with record kind 0x14a6b1, chosen so the encoded value +// is 0xd2-0xcd-0x31 which is "RM1" with the first two bytes having their high bit set. +// If the ROMFS record's payload is non-empty then it contains records. +// +// Record types: +// - 0 = unused, can be used to detect corruption of the filesystem. +// - 1 = padding/comments, can contain any data in their payload. +// - 2 = verbatim data, used to store file data. +// - 3 = indirect data, pointer to offset within the ROMFS payload. +// - 4 = a directory: payload contains a varuint which is the length of the directory +// name in bytes, then the name, then optional nested records for the contents +// of the directory (including optional metadata). +// - 5 = a file: payload contains a varuint which is the length of the filename in bytes +// then the name, then optional nested records. +// +// Remarks: +// - A varuint can be padded if needed by prepending with one or more 0x80 bytes. This +// padding does not change any semantics. +// - The size of the ROMFS record (including kind and length and payload) must be a +// multiple of 2 (because it's not possible to add a padding record of one byte). +// - File data can be optionally aligned using padding records and/or indirect data +// records. +// - There is no limit to the size of directory/file names or file data. +// +// Unknown record types must be skipped over. They may in the future add optional +// features, while still retaining backwards compatibility. Such features may be: +// - Alignment requirements of the ROMFS record. +// - Timestamps on directories/files. +// - A precomputed hash of a file, or other metadata. +// - An optimised lookup table indexing the directory hierarchy. + +#include + +#include "py/bc.h" +#include "py/runtime.h" +#include "py/mperrno.h" +#include "extmod/vfs.h" +#include "extmod/vfs_rom.h" + +#if MICROPY_VFS_ROM + +#define ROMFS_SIZE_MIN (4) +#define ROMFS_HEADER_BYTE0 (0x80 | 'R') +#define ROMFS_HEADER_BYTE1 (0x80 | 'M') +#define ROMFS_HEADER_BYTE2 (0x00 | '1') + +// Values for `record_kind_t`. +#define ROMFS_RECORD_KIND_UNUSED (0) +#define ROMFS_RECORD_KIND_PADDING (1) +#define ROMFS_RECORD_KIND_DATA_VERBATIM (2) +#define ROMFS_RECORD_KIND_DATA_POINTER (3) +#define ROMFS_RECORD_KIND_DIRECTORY (4) +#define ROMFS_RECORD_KIND_FILE (5) +#define ROMFS_RECORD_KIND_FILESYSTEM (0x14a6b1) + +typedef mp_uint_t record_kind_t; + +struct _mp_obj_vfs_rom_t { + mp_obj_base_t base; + mp_obj_t memory; + const uint8_t *filesystem; + const uint8_t *filesystem_end; +}; + +// Returns 0 for success, -1 for failure. +static int mp_decode_uint_checked(const uint8_t **ptr, const uint8_t *ptr_max, mp_uint_t *value_out) { + mp_uint_t unum = 0; + byte val; + const uint8_t *p = *ptr; + do { + if (p >= ptr_max) { + return -1; + } + val = *p++; + unum = (unum << 7) | (val & 0x7f); + } while ((val & 0x80) != 0); + *ptr = p; + *value_out = unum; + return 0; +} + +static record_kind_t extract_record(const uint8_t **fs, const uint8_t **fs_next, const uint8_t *fs_max) { + mp_uint_t record_kind; + if (mp_decode_uint_checked(fs, fs_max, &record_kind) != 0) { + return ROMFS_RECORD_KIND_UNUSED; + } + mp_uint_t record_len; + if (mp_decode_uint_checked(fs, fs_max, &record_len) != 0) { + return ROMFS_RECORD_KIND_UNUSED; + } + *fs_next = *fs + record_len; + return record_kind; +} + +// Returns 0 for success, a negative integer for failure. +static int extract_data(mp_obj_vfs_rom_t *self, const uint8_t *fs, const uint8_t *fs_top, size_t *size_out, const uint8_t **data_out) { + while (fs < fs_top) { + const uint8_t *fs_next; + record_kind_t record_kind = extract_record(&fs, &fs_next, fs_top); + if (record_kind == ROMFS_RECORD_KIND_UNUSED) { + // Corrupt filesystem. + break; + } else if (record_kind == ROMFS_RECORD_KIND_DATA_VERBATIM) { + // Verbatim data. + if (size_out != NULL) { + *size_out = fs_next - fs; + *data_out = fs; + } + return 0; + } else if (record_kind == ROMFS_RECORD_KIND_DATA_POINTER) { + // Pointer to data. + mp_uint_t size; + if (mp_decode_uint_checked(&fs, fs_next, &size) != 0) { + break; + } + mp_uint_t offset; + if (mp_decode_uint_checked(&fs, fs_next, &offset) != 0) { + break; + } + if (size_out != NULL) { + *size_out = size; + *data_out = self->filesystem + offset; + } + return 0; + } else { + // Skip this record. + fs = fs_next; + } + } + return -MP_EIO; +} + +// Searches for `path` in the filesystem. +// `path` must be null-terminated. +mp_import_stat_t mp_vfs_rom_search_filesystem(mp_obj_vfs_rom_t *self, const char *path, size_t *size_out, const uint8_t **data_out) { + const uint8_t *fs = self->filesystem; + const uint8_t *fs_top = self->filesystem_end; + size_t path_len = strlen(path); + if (*path == '/') { + // An optional slash at the start of the path enters the top-level filesystem. + ++path; + --path_len; + } + while (path_len > 0 && fs < fs_top) { + const uint8_t *fs_next; + record_kind_t record_kind = extract_record(&fs, &fs_next, fs_top); + if (record_kind == ROMFS_RECORD_KIND_UNUSED) { + // Corrupt filesystem. + return MP_IMPORT_STAT_NO_EXIST; + } else if (record_kind == ROMFS_RECORD_KIND_DIRECTORY || record_kind == ROMFS_RECORD_KIND_FILE) { + // A directory or file record. + mp_uint_t name_len; + if (mp_decode_uint_checked(&fs, fs_next, &name_len) != 0) { + // Corrupt filesystem. + return MP_IMPORT_STAT_NO_EXIST; + } + if ((name_len == path_len + || (name_len < path_len && path[name_len] == '/')) + && memcmp(path, fs, name_len) == 0) { + // Name matches, so enter this record. + fs += name_len; + fs_top = fs_next; + path += name_len; + path_len -= name_len; + if (record_kind == ROMFS_RECORD_KIND_DIRECTORY) { + // Continue searching in this directory. + if (*path == '/') { + ++path; + --path_len; + } + } else { + // Return this file. + if (path_len != 0) { + return MP_IMPORT_STAT_NO_EXIST; + } + if (extract_data(self, fs, fs_top, size_out, data_out) != 0) { + // Corrupt filesystem. + return MP_IMPORT_STAT_NO_EXIST; + } + return MP_IMPORT_STAT_FILE; + } + } else { + // Skip this directory/file record. + fs = fs_next; + } + } else { + // Skip this record. + fs = fs_next; + } + } + if (path_len == 0) { + if (size_out != NULL) { + *size_out = fs_top - fs; + *data_out = fs; + } + return MP_IMPORT_STAT_DIR; + } + return MP_IMPORT_STAT_NO_EXIST; +} + +static mp_obj_t vfs_rom_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, 1, false); + + mp_obj_vfs_rom_t *self = m_new_obj(mp_obj_vfs_rom_t); + self->base.type = type; + self->memory = args[0]; + + // Get the ROMFS memory region. + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(self->memory, &bufinfo, MP_BUFFER_READ); + if (bufinfo.len < ROMFS_SIZE_MIN) { + mp_raise_OSError(MP_ENODEV); + } + self->filesystem = bufinfo.buf; + + // Verify it is a ROMFS. + if (!(self->filesystem[0] == ROMFS_HEADER_BYTE0 + && self->filesystem[1] == ROMFS_HEADER_BYTE1 + && self->filesystem[2] == ROMFS_HEADER_BYTE2)) { + mp_raise_OSError(MP_ENODEV); + } + + // The ROMFS is a record itself, so enter into it and compute its limit. + record_kind_t record_kind = extract_record(&self->filesystem, &self->filesystem_end, self->filesystem + bufinfo.len); + if (record_kind != ROMFS_RECORD_KIND_FILESYSTEM) { + mp_raise_OSError(MP_ENODEV); + } + + // Check the filesystem is within the limits of the input buffer. + if (self->filesystem_end > (const uint8_t *)bufinfo.buf + bufinfo.len) { + mp_raise_OSError(MP_ENODEV); + } + + return MP_OBJ_FROM_PTR(self); +} + +static mp_obj_t vfs_rom_mount(mp_obj_t self_in, mp_obj_t readonly, mp_obj_t mkfs) { + (void)self_in; + (void)readonly; + if (mp_obj_is_true(mkfs)) { + mp_raise_OSError(MP_EPERM); + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_3(vfs_rom_mount_obj, vfs_rom_mount); + +// mp_vfs_rom_file_open is implemented in vfs_rom_file.c. +static MP_DEFINE_CONST_FUN_OBJ_3(vfs_rom_open_obj, mp_vfs_rom_file_open); + +static mp_obj_t vfs_rom_chdir(mp_obj_t self_in, mp_obj_t path_in) { + mp_obj_vfs_rom_t *self = MP_OBJ_TO_PTR(self_in); + const char *path = mp_vfs_rom_get_path_str(self, path_in); + if (path[0] == '/' && path[1] == '\0') { + // Allow chdir to the root of the filesystem. + } else { + // Don't allow chdir to any subdirectory (not currently implemented). + mp_raise_OSError(MP_EOPNOTSUPP); + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_2(vfs_rom_chdir_obj, vfs_rom_chdir); + +static mp_obj_t vfs_rom_getcwd(mp_obj_t self_in) { + (void)self_in; + // The current directory is always the root of the ROMFS. + return MP_OBJ_NEW_QSTR(MP_QSTR_); +} +static MP_DEFINE_CONST_FUN_OBJ_1(vfs_rom_getcwd_obj, vfs_rom_getcwd); + +typedef struct _vfs_rom_ilistdir_it_t { + mp_obj_base_t base; + mp_fun_1_t iternext; + mp_obj_vfs_rom_t *vfs_rom; + bool is_str; + const uint8_t *index; + const uint8_t *index_top; +} vfs_rom_ilistdir_it_t; + +static mp_obj_t vfs_rom_ilistdir_it_iternext(mp_obj_t self_in) { + vfs_rom_ilistdir_it_t *self = MP_OBJ_TO_PTR(self_in); + + while (self->index < self->index_top) { + const uint8_t *index_next; + record_kind_t record_kind = extract_record(&self->index, &index_next, self->index_top); + uint32_t type; + mp_uint_t name_len; + size_t data_len; + if (record_kind == ROMFS_RECORD_KIND_UNUSED) { + // Corrupt filesystem. + self->index = self->index_top; + break; + } else if (record_kind == ROMFS_RECORD_KIND_DIRECTORY || record_kind == ROMFS_RECORD_KIND_FILE) { + // A directory or file record. + if (mp_decode_uint_checked(&self->index, index_next, &name_len) != 0) { + // Corrupt filesystem. + self->index = self->index_top; + break; + } + if (record_kind == ROMFS_RECORD_KIND_DIRECTORY) { + // A directory. + type = MP_S_IFDIR; + data_len = index_next - self->index - name_len; + } else { + // A file. + type = MP_S_IFREG; + const uint8_t *data_value; + if (extract_data(self->vfs_rom, self->index + name_len, index_next, &data_len, &data_value) != 0) { + // Corrupt filesystem. + break; + } + } + } else { + // Skip this record. + self->index = index_next; + continue; + } + + const uint8_t *name_str = self->index; + self->index = index_next; + + // Make 4-tuple with info about this entry: (name, attr, inode, size) + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(4, NULL)); + + if (self->is_str) { + t->items[0] = mp_obj_new_str((const char *)name_str, name_len); + } else { + t->items[0] = mp_obj_new_bytes(name_str, name_len); + } + + t->items[1] = MP_OBJ_NEW_SMALL_INT(type); + t->items[2] = MP_OBJ_NEW_SMALL_INT(0); + t->items[3] = mp_obj_new_int(data_len); + + return MP_OBJ_FROM_PTR(t); + } + + return MP_OBJ_STOP_ITERATION; +} + +static mp_obj_t vfs_rom_ilistdir(mp_obj_t self_in, mp_obj_t path_in) { + mp_obj_vfs_rom_t *self = MP_OBJ_TO_PTR(self_in); + vfs_rom_ilistdir_it_t *iter = m_new_obj(vfs_rom_ilistdir_it_t); + iter->base.type = &mp_type_polymorph_iter; + iter->iternext = vfs_rom_ilistdir_it_iternext; + iter->vfs_rom = self; + iter->is_str = mp_obj_get_type(path_in) == &mp_type_str; + const char *path = mp_vfs_rom_get_path_str(self, path_in); + size_t size; + if (mp_vfs_rom_search_filesystem(self, path, &size, &iter->index) != MP_IMPORT_STAT_DIR) { + mp_raise_OSError(MP_ENOENT); + } + iter->index_top = iter->index + size; + return MP_OBJ_FROM_PTR(iter); +} +static MP_DEFINE_CONST_FUN_OBJ_2(vfs_rom_ilistdir_obj, vfs_rom_ilistdir); + +static mp_obj_t vfs_rom_stat(mp_obj_t self_in, mp_obj_t path_in) { + mp_obj_vfs_rom_t *self = MP_OBJ_TO_PTR(self_in); + const char *path = mp_vfs_rom_get_path_str(self, path_in); + size_t file_size; + const uint8_t *file_data; + mp_import_stat_t stat = mp_vfs_rom_search_filesystem(self, path, &file_size, &file_data); + if (stat == MP_IMPORT_STAT_NO_EXIST) { + mp_raise_OSError(MP_ENOENT); + } + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); + t->items[0] = MP_OBJ_NEW_SMALL_INT(stat == MP_IMPORT_STAT_FILE ? MP_S_IFREG : MP_S_IFDIR); // st_mode + t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino + t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev + t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // st_nlink + t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid + t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid + t->items[6] = MP_OBJ_NEW_SMALL_INT(file_size); // st_size + t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // st_atime + t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // st_mtime + t->items[9] = MP_OBJ_NEW_SMALL_INT(0); // st_ctime + return MP_OBJ_FROM_PTR(t); +} +static MP_DEFINE_CONST_FUN_OBJ_2(vfs_rom_stat_obj, vfs_rom_stat); + +static mp_obj_t vfs_rom_statvfs(mp_obj_t self_in, mp_obj_t path_in) { + mp_obj_vfs_rom_t *self = MP_OBJ_TO_PTR(self_in); + (void)path_in; + size_t filesystem_len = self->filesystem_end - self->filesystem; + mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); + t->items[0] = MP_OBJ_NEW_SMALL_INT(1); // f_bsize + t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // f_frsize + t->items[2] = mp_obj_new_int_from_uint(filesystem_len); // f_blocks + t->items[3] = MP_OBJ_NEW_SMALL_INT(0); // f_bfree + t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // f_bavail + t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // f_files + t->items[6] = MP_OBJ_NEW_SMALL_INT(0); // f_ffree + t->items[7] = MP_OBJ_NEW_SMALL_INT(0); // f_favail + t->items[8] = MP_OBJ_NEW_SMALL_INT(0); // f_flags + t->items[9] = MP_OBJ_NEW_SMALL_INT(32767); // f_namemax + return MP_OBJ_FROM_PTR(t); +} +static MP_DEFINE_CONST_FUN_OBJ_2(vfs_rom_statvfs_obj, vfs_rom_statvfs); + +static const mp_rom_map_elem_t vfs_rom_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&vfs_rom_mount_obj) }, + { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&vfs_rom_open_obj) }, + + { MP_ROM_QSTR(MP_QSTR_chdir), MP_ROM_PTR(&vfs_rom_chdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_getcwd), MP_ROM_PTR(&vfs_rom_getcwd_obj) }, + { MP_ROM_QSTR(MP_QSTR_ilistdir), MP_ROM_PTR(&vfs_rom_ilistdir_obj) }, + { MP_ROM_QSTR(MP_QSTR_stat), MP_ROM_PTR(&vfs_rom_stat_obj) }, + { MP_ROM_QSTR(MP_QSTR_statvfs), MP_ROM_PTR(&vfs_rom_statvfs_obj) }, +}; +static MP_DEFINE_CONST_DICT(vfs_rom_locals_dict, vfs_rom_locals_dict_table); + +static mp_import_stat_t mp_vfs_rom_import_stat(void *self_in, const char *path) { + mp_obj_vfs_rom_t *self = MP_OBJ_TO_PTR(self_in); + return mp_vfs_rom_search_filesystem(self, path, NULL, NULL); +} + +static const mp_vfs_proto_t vfs_rom_proto = { + .import_stat = mp_vfs_rom_import_stat, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_rom, + MP_QSTR_VfsRom, + MP_TYPE_FLAG_NONE, + make_new, vfs_rom_make_new, + protocol, &vfs_rom_proto, + locals_dict, &vfs_rom_locals_dict + ); + +#endif // MICROPY_VFS_ROM diff --git a/extmod/vfs_rom.h b/extmod/vfs_rom.h new file mode 100644 index 00000000000..d8e2b911ba0 --- /dev/null +++ b/extmod/vfs_rom.h @@ -0,0 +1,47 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_EXTMOD_VFS_ROM_H +#define MICROPY_INCLUDED_EXTMOD_VFS_ROM_H + +#include "py/builtin.h" +#include "py/obj.h" + +#if MICROPY_VFS_ROM + +typedef struct _mp_obj_vfs_rom_t mp_obj_vfs_rom_t; + +extern const mp_obj_type_t mp_type_vfs_rom; + +static inline const char *mp_vfs_rom_get_path_str(mp_obj_vfs_rom_t *self, mp_obj_t path) { + return mp_obj_str_get_str(path); +} + +mp_import_stat_t mp_vfs_rom_search_filesystem(mp_obj_vfs_rom_t *self, const char *path, size_t *size_out, const uint8_t **data_out); +mp_obj_t mp_vfs_rom_file_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in); + +#endif // MICROPY_VFS_ROM + +#endif // MICROPY_INCLUDED_EXTMOD_VFS_ROM_H diff --git a/extmod/vfs_rom_file.c b/extmod/vfs_rom_file.c new file mode 100644 index 00000000000..57aca8c5dc7 --- /dev/null +++ b/extmod/vfs_rom_file.c @@ -0,0 +1,180 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2022 Damien P. George + * + * 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. + */ + +#include + +#include "py/reader.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "extmod/vfs_rom.h" + +#if MICROPY_VFS_ROM + +typedef struct _mp_obj_vfs_rom_file_t { + mp_obj_base_t base; + size_t file_size; + size_t file_offset; + const uint8_t *file_data; +} mp_obj_vfs_rom_file_t; + +static const mp_obj_type_t mp_type_vfs_rom_fileio; +static const mp_obj_type_t mp_type_vfs_rom_textio; + +mp_obj_t mp_vfs_rom_file_open(mp_obj_t self_in, mp_obj_t path_in, mp_obj_t mode_in) { + mp_obj_vfs_rom_t *self = MP_OBJ_TO_PTR(self_in); + + const char *mode_s = mp_obj_str_get_str(mode_in); + const mp_obj_type_t *type = &mp_type_vfs_rom_textio; + while (*mode_s) { + switch (*mode_s++) { + case 'r': + break; + case 'w': + case 'a': + case '+': + mp_raise_OSError(MP_EROFS); + case 'b': + type = &mp_type_vfs_rom_fileio; + break; + case 't': + type = &mp_type_vfs_rom_textio; + break; + } + } + + mp_obj_vfs_rom_file_t *o = m_new_obj(mp_obj_vfs_rom_file_t); + o->base.type = type; + o->file_offset = 0; + + const char *path = mp_vfs_rom_get_path_str(self, path_in); + mp_import_stat_t stat = mp_vfs_rom_search_filesystem(self, path, &o->file_size, &o->file_data); + if (stat == MP_IMPORT_STAT_NO_EXIST) { + mp_raise_OSError(MP_ENOENT); + } else if (stat == MP_IMPORT_STAT_DIR) { + mp_raise_OSError(MP_EISDIR); + } + + return MP_OBJ_FROM_PTR(o); +} + +static mp_int_t vfs_rom_file_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + mp_obj_vfs_rom_file_t *self = MP_OBJ_TO_PTR(self_in); + if (flags == MP_BUFFER_READ) { + bufinfo->buf = (void *)self->file_data; + bufinfo->len = self->file_size; + bufinfo->typecode = 'B'; + return 0; + } else { + // Can't write to a ROM file. + return 1; + } +} + +static mp_uint_t vfs_rom_file_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *errcode) { + mp_obj_vfs_rom_file_t *self = MP_OBJ_TO_PTR(o_in); + size_t remain = self->file_size - self->file_offset; + if (size > remain) { + size = remain; + } + memcpy(buf, self->file_data + self->file_offset, size); + self->file_offset += size; + return size; +} + +static mp_uint_t vfs_rom_file_ioctl(mp_obj_t o_in, mp_uint_t request, uintptr_t arg, int *errcode) { + mp_obj_vfs_rom_file_t *self = MP_OBJ_TO_PTR(o_in); + + switch (request) { + case MP_STREAM_SEEK: { + struct mp_stream_seek_t *s = (struct mp_stream_seek_t *)arg; + if (s->whence == 0) { // SEEK_SET + self->file_offset = (size_t)s->offset; + } else if (s->whence == 1) { // SEEK_CUR + self->file_offset += s->offset; + } else { // SEEK_END + self->file_offset = self->file_size + s->offset; + } + if (self->file_offset > self->file_size) { + if (s->offset < 0) { + // Seek to before the start of the file. + *errcode = MP_EINVAL; + return MP_STREAM_ERROR; + } + self->file_offset = self->file_size; + } + s->offset = self->file_offset; + return 0; + } + case MP_STREAM_CLOSE: + return 0; + default: + *errcode = MP_EINVAL; + return MP_STREAM_ERROR; + } +} + +static const mp_rom_map_elem_t vfs_rom_rawfile_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj) }, + { MP_ROM_QSTR(MP_QSTR_seek), MP_ROM_PTR(&mp_stream_seek_obj) }, + { MP_ROM_QSTR(MP_QSTR_tell), MP_ROM_PTR(&mp_stream_tell_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mp_stream___exit___obj) }, +}; +static MP_DEFINE_CONST_DICT(vfs_rom_rawfile_locals_dict, vfs_rom_rawfile_locals_dict_table); + +static const mp_stream_p_t vfs_rom_fileio_stream_p = { + .read = vfs_rom_file_read, + .ioctl = vfs_rom_file_ioctl, +}; + +static MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_rom_fileio, + MP_QSTR_FileIO, + MP_TYPE_FLAG_ITER_IS_STREAM, + buffer, vfs_rom_file_get_buffer, + protocol, &vfs_rom_fileio_stream_p, + locals_dict, &vfs_rom_rawfile_locals_dict + ); + +static const mp_stream_p_t vfs_rom_textio_stream_p = { + .read = vfs_rom_file_read, + .ioctl = vfs_rom_file_ioctl, + .is_text = true, +}; + +static MP_DEFINE_CONST_OBJ_TYPE( + mp_type_vfs_rom_textio, + MP_QSTR_TextIOWrapper, + MP_TYPE_FLAG_ITER_IS_STREAM, + protocol, &vfs_rom_textio_stream_p, + locals_dict, &vfs_rom_rawfile_locals_dict + ); + +#endif // MICROPY_VFS_ROM diff --git a/extmod/virtpin.c b/extmod/virtpin.c deleted file mode 100644 index cd0b9f92f83..00000000000 --- a/extmod/virtpin.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Paul Sokolovsky - * - * 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. - */ - -#include "extmod/virtpin.h" - -int mp_virtual_pin_read(mp_obj_t pin) { - mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin); - mp_pin_p_t *pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol); - return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL); -} - -void mp_virtual_pin_write(mp_obj_t pin, int value) { - mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin); - mp_pin_p_t *pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol); - pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL); -} diff --git a/extmod/virtpin.h b/extmod/virtpin.h deleted file mode 100644 index 81094f21cf1..00000000000 --- a/extmod/virtpin.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Paul Sokolovsky - * - * 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. - */ -#ifndef MICROPY_INCLUDED_EXTMOD_VIRTPIN_H -#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H - -#include "py/obj.h" -// CIRCUITPY-CHANGE -#include "py/proto.h" - -#define MP_PIN_READ (1) -#define MP_PIN_WRITE (2) -#define MP_PIN_INPUT (3) -#define MP_PIN_OUTPUT (4) - -// Pin protocol -typedef struct _mp_pin_p_t { - // CIRCUITPY-CHANGE - MP_PROTOCOL_HEAD - mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode); -} mp_pin_p_t; - -int mp_virtual_pin_read(mp_obj_t pin); -void mp_virtual_pin_write(mp_obj_t pin, int value); - -// If a port exposes a Pin object, it's constructor should be like this -mp_obj_t mp_pin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args); - -#endif // MICROPY_INCLUDED_EXTMOD_VIRTPIN_H diff --git a/frozen/Adafruit_CircuitPython_AHTx0 b/frozen/Adafruit_CircuitPython_AHTx0 index d6e60adfae2..3dd249f5695 160000 --- a/frozen/Adafruit_CircuitPython_AHTx0 +++ b/frozen/Adafruit_CircuitPython_AHTx0 @@ -1 +1 @@ -Subproject commit d6e60adfae22a8d2bf94c2e207c4a4e9f0bfc7f8 +Subproject commit 3dd249f56957d1927dee6e6e31742039c6699cef diff --git a/frozen/Adafruit_CircuitPython_APDS9960 b/frozen/Adafruit_CircuitPython_APDS9960 index ebccbd6e8c9..75a7b1abef0 160000 --- a/frozen/Adafruit_CircuitPython_APDS9960 +++ b/frozen/Adafruit_CircuitPython_APDS9960 @@ -1 +1 @@ -Subproject commit ebccbd6e8c927905d62bd0cc5832109920d413b2 +Subproject commit 75a7b1abef02342a7cdead30271ce168243bf1fa diff --git a/frozen/Adafruit_CircuitPython_BLE b/frozen/Adafruit_CircuitPython_BLE index 9f2da7ce2ad..82ada04a0f4 160000 --- a/frozen/Adafruit_CircuitPython_BLE +++ b/frozen/Adafruit_CircuitPython_BLE @@ -1 +1 @@ -Subproject commit 9f2da7ce2ad6116ea97e1980bb55f0fed4774856 +Subproject commit 82ada04a0f4019de00d103256621f73b80151a0d diff --git a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center index 7f549880392..7c081325944 160000 --- a/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center +++ b/frozen/Adafruit_CircuitPython_BLE_Apple_Notification_Center @@ -1 +1 @@ -Subproject commit 7f5498803921b61168fe108b386653fa0a930ad1 +Subproject commit 7c08132594453a021812f45e86a2972d6945672e diff --git a/frozen/Adafruit_CircuitPython_Bitmap_Font b/frozen/Adafruit_CircuitPython_Bitmap_Font index 735d8167df6..fe0cdfd5501 160000 --- a/frozen/Adafruit_CircuitPython_Bitmap_Font +++ b/frozen/Adafruit_CircuitPython_Bitmap_Font @@ -1 +1 @@ -Subproject commit 735d8167df6bffcda71b5338e7c6df0268a39b7e +Subproject commit fe0cdfd5501070f5ca47b3e66dfd15e62c54011e diff --git a/frozen/Adafruit_CircuitPython_BusDevice b/frozen/Adafruit_CircuitPython_BusDevice index 88250a1e29a..686728c7b11 160000 --- a/frozen/Adafruit_CircuitPython_BusDevice +++ b/frozen/Adafruit_CircuitPython_BusDevice @@ -1 +1 @@ -Subproject commit 88250a1e29a806dfc2a9dd9045bb0591a1178cca +Subproject commit 686728c7b11eb0b7ffb62691b68ccead413e7cc5 diff --git a/frozen/Adafruit_CircuitPython_CircuitPlayground b/frozen/Adafruit_CircuitPython_CircuitPlayground index 9c25878e0b7..852e7206e5e 160000 --- a/frozen/Adafruit_CircuitPython_CircuitPlayground +++ b/frozen/Adafruit_CircuitPython_CircuitPlayground @@ -1 +1 @@ -Subproject commit 9c25878e0b7bf2ad2085190a3d8be78579006667 +Subproject commit 852e7206e5ed26ec3929a25bc8331b0951fee20e diff --git a/frozen/Adafruit_CircuitPython_ConnectionManager b/frozen/Adafruit_CircuitPython_ConnectionManager index 67d649b363c..69542345f3d 160000 --- a/frozen/Adafruit_CircuitPython_ConnectionManager +++ b/frozen/Adafruit_CircuitPython_ConnectionManager @@ -1 +1 @@ -Subproject commit 67d649b363cc3464b7959652a32cb62662ee60c3 +Subproject commit 69542345f3dc6f9060eb5d78d5dcd4e636bf66b9 diff --git a/frozen/Adafruit_CircuitPython_Crickit b/frozen/Adafruit_CircuitPython_Crickit index 9aadbbd6e3c..aa213ba6f89 160000 --- a/frozen/Adafruit_CircuitPython_Crickit +++ b/frozen/Adafruit_CircuitPython_Crickit @@ -1 +1 @@ -Subproject commit 9aadbbd6e3cad460cbe49bf3c73792df66bf9fe5 +Subproject commit aa213ba6f897cdeb45ce4e961f44f862e3832c03 diff --git a/frozen/Adafruit_CircuitPython_DRV2605 b/frozen/Adafruit_CircuitPython_DRV2605 index 90e9f430222..2b8443ff94a 160000 --- a/frozen/Adafruit_CircuitPython_DRV2605 +++ b/frozen/Adafruit_CircuitPython_DRV2605 @@ -1 +1 @@ -Subproject commit 90e9f4302225e9111afd394e5dcb174e96847b28 +Subproject commit 2b8443ff94a179a027efd9f62d905c398f4f7b43 diff --git a/frozen/Adafruit_CircuitPython_DS3231 b/frozen/Adafruit_CircuitPython_DS3231 index 7b99df2081e..5dc331cd999 160000 --- a/frozen/Adafruit_CircuitPython_DS3231 +++ b/frozen/Adafruit_CircuitPython_DS3231 @@ -1 +1 @@ -Subproject commit 7b99df2081e7b700d052ad9b455d41cbba43c302 +Subproject commit 5dc331cd99930dd209c63f77256764c2b41016f2 diff --git a/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 b/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 index 40d7b8eb7a7..45520b642df 160000 --- a/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 +++ b/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 @@ -1 +1 @@ -Subproject commit 40d7b8eb7a7d8fc91a62414d4f764dd48283d86d +Subproject commit 45520b642df77b1718befb24e5e6853b1172792f diff --git a/frozen/Adafruit_CircuitPython_Display_Shapes b/frozen/Adafruit_CircuitPython_Display_Shapes index 2742ae5025b..7f0466c1d3a 160000 --- a/frozen/Adafruit_CircuitPython_Display_Shapes +++ b/frozen/Adafruit_CircuitPython_Display_Shapes @@ -1 +1 @@ -Subproject commit 2742ae5025b0a9bcc853a8b89b293f8e46331498 +Subproject commit 7f0466c1d3ac344bb8ef282d09c5eb8c1a521d72 diff --git a/frozen/Adafruit_CircuitPython_Display_Text b/frozen/Adafruit_CircuitPython_Display_Text index 535317831ff..eae352b0970 160000 --- a/frozen/Adafruit_CircuitPython_Display_Text +++ b/frozen/Adafruit_CircuitPython_Display_Text @@ -1 +1 @@ -Subproject commit 535317831ffa667180902595daa666be153989eb +Subproject commit eae352b09700e57b78507aace7ff682cb1beff5a diff --git a/frozen/Adafruit_CircuitPython_DotStar b/frozen/Adafruit_CircuitPython_DotStar index 1945d1aa9c5..d08e231d5f9 160000 --- a/frozen/Adafruit_CircuitPython_DotStar +++ b/frozen/Adafruit_CircuitPython_DotStar @@ -1 +1 @@ -Subproject commit 1945d1aa9c5232287c490fbb6d637c92d866ed01 +Subproject commit d08e231d5f95566a09f2a0c08cb647703882262d diff --git a/frozen/Adafruit_CircuitPython_ESP32SPI b/frozen/Adafruit_CircuitPython_ESP32SPI index e7e129aa6d9..b0e2124a175 160000 --- a/frozen/Adafruit_CircuitPython_ESP32SPI +++ b/frozen/Adafruit_CircuitPython_ESP32SPI @@ -1 +1 @@ -Subproject commit e7e129aa6d9fec4e0844ec195c184073c8a1f5d3 +Subproject commit b0e2124a175f421bb07ac5cc72b81f6209966a3b diff --git a/frozen/Adafruit_CircuitPython_FakeRequests b/frozen/Adafruit_CircuitPython_FakeRequests index 248d7b14134..130a3d7fcfb 160000 --- a/frozen/Adafruit_CircuitPython_FakeRequests +++ b/frozen/Adafruit_CircuitPython_FakeRequests @@ -1 +1 @@ -Subproject commit 248d7b14134915883b4693fddf74bb77cca2ffd1 +Subproject commit 130a3d7fcfbba67bb86232f22ca08ba862873947 diff --git a/frozen/Adafruit_CircuitPython_FocalTouch b/frozen/Adafruit_CircuitPython_FocalTouch index 6d3d6887217..2070d7853cd 160000 --- a/frozen/Adafruit_CircuitPython_FocalTouch +++ b/frozen/Adafruit_CircuitPython_FocalTouch @@ -1 +1 @@ -Subproject commit 6d3d68872179b3a2b681779dd1e73db92b9b8f5e +Subproject commit 2070d7853cd1fe81381e02f4bc0af1bb145cb69e diff --git a/frozen/Adafruit_CircuitPython_HID b/frozen/Adafruit_CircuitPython_HID index be6db4658d2..693baa60eb6 160000 --- a/frozen/Adafruit_CircuitPython_HID +++ b/frozen/Adafruit_CircuitPython_HID @@ -1 +1 @@ -Subproject commit be6db4658d26902b6d5191d16de658adb92d018a +Subproject commit 693baa60eb684bb53379d98c6a036f56b8010666 diff --git a/frozen/Adafruit_CircuitPython_HTTPServer b/frozen/Adafruit_CircuitPython_HTTPServer index 9b16e16f5b1..c1d964fe7bf 160000 --- a/frozen/Adafruit_CircuitPython_HTTPServer +++ b/frozen/Adafruit_CircuitPython_HTTPServer @@ -1 +1 @@ -Subproject commit 9b16e16f5b1c1a346fb57ffcd0c6db9538a20803 +Subproject commit c1d964fe7bf8734f7a858e798583d0f1304ae1c1 diff --git a/frozen/Adafruit_CircuitPython_IRRemote b/frozen/Adafruit_CircuitPython_IRRemote index c4daaa7521a..bb14c81e07a 160000 --- a/frozen/Adafruit_CircuitPython_IRRemote +++ b/frozen/Adafruit_CircuitPython_IRRemote @@ -1 +1 @@ -Subproject commit c4daaa7521a491f7045cf10007764e95e4e2c265 +Subproject commit bb14c81e07aa798b36a53923059b5ab8a914915b diff --git a/frozen/Adafruit_CircuitPython_IS31FL3731 b/frozen/Adafruit_CircuitPython_IS31FL3731 index 9f1202c3c68..3becc08e451 160000 --- a/frozen/Adafruit_CircuitPython_IS31FL3731 +++ b/frozen/Adafruit_CircuitPython_IS31FL3731 @@ -1 +1 @@ -Subproject commit 9f1202c3c6879c62d70058b0f43f21ef51c2ebe6 +Subproject commit 3becc08e451eeb2b6678a3d17547f5b0922e4660 diff --git a/frozen/Adafruit_CircuitPython_ImageLoad b/frozen/Adafruit_CircuitPython_ImageLoad index 72a7a4a0f6b..11855997455 160000 --- a/frozen/Adafruit_CircuitPython_ImageLoad +++ b/frozen/Adafruit_CircuitPython_ImageLoad @@ -1 +1 @@ -Subproject commit 72a7a4a0f6bb99cd0ab50d21988dea6d2321bf72 +Subproject commit 11855997455465bc93670e2a3f92e73bc9f7caee diff --git a/frozen/Adafruit_CircuitPython_LC709203F b/frozen/Adafruit_CircuitPython_LC709203F index 2809e03a16b..bcbb0cfead8 160000 --- a/frozen/Adafruit_CircuitPython_LC709203F +++ b/frozen/Adafruit_CircuitPython_LC709203F @@ -1 +1 @@ -Subproject commit 2809e03a16b53e0a131c37d4dbe2140d7412c402 +Subproject commit bcbb0cfead8650a61357a167bc47058f05fba159 diff --git a/frozen/Adafruit_CircuitPython_LED_Animation b/frozen/Adafruit_CircuitPython_LED_Animation index 576a094602b..38a3c7844b4 160000 --- a/frozen/Adafruit_CircuitPython_LED_Animation +++ b/frozen/Adafruit_CircuitPython_LED_Animation @@ -1 +1 @@ -Subproject commit 576a094602b099a1f211f126f68ff3cb07d32a05 +Subproject commit 38a3c7844b4c59235fac46ee01e20caf872dad43 diff --git a/frozen/Adafruit_CircuitPython_LIS3DH b/frozen/Adafruit_CircuitPython_LIS3DH index 8591697e54f..cd40b482a09 160000 --- a/frozen/Adafruit_CircuitPython_LIS3DH +++ b/frozen/Adafruit_CircuitPython_LIS3DH @@ -1 +1 @@ -Subproject commit 8591697e54f04711f2ed309753ddf4b334b05114 +Subproject commit cd40b482a098a62ecce1b4c62a1f1930be984e16 diff --git a/frozen/Adafruit_CircuitPython_LSM6DS b/frozen/Adafruit_CircuitPython_LSM6DS index c4d6b88c5d5..cdfc14a687a 160000 --- a/frozen/Adafruit_CircuitPython_LSM6DS +++ b/frozen/Adafruit_CircuitPython_LSM6DS @@ -1 +1 @@ -Subproject commit c4d6b88c5d537e0ba6b430987ccb2020475dc2e5 +Subproject commit cdfc14a687a138aa0f2c6abab061bfc1bfafa561 diff --git a/frozen/Adafruit_CircuitPython_MIDI b/frozen/Adafruit_CircuitPython_MIDI index 36f8d5ab01d..6f5d6812474 160000 --- a/frozen/Adafruit_CircuitPython_MIDI +++ b/frozen/Adafruit_CircuitPython_MIDI @@ -1 +1 @@ -Subproject commit 36f8d5ab01dc82f41b6779683bd32130ad798848 +Subproject commit 6f5d6812474a0460e9418278ea7da1e2269d2c0d diff --git a/frozen/Adafruit_CircuitPython_MPU6050 b/frozen/Adafruit_CircuitPython_MPU6050 index 58a9a05c0c4..d30ee1fa5f4 160000 --- a/frozen/Adafruit_CircuitPython_MPU6050 +++ b/frozen/Adafruit_CircuitPython_MPU6050 @@ -1 +1 @@ -Subproject commit 58a9a05c0c4ada11ea9f18c953f62eab97b94c17 +Subproject commit d30ee1fa5f49b62b4df382ea5310a77fa39d6bd9 diff --git a/frozen/Adafruit_CircuitPython_Motor b/frozen/Adafruit_CircuitPython_Motor index 0c598f67c46..20ebf51fe0d 160000 --- a/frozen/Adafruit_CircuitPython_Motor +++ b/frozen/Adafruit_CircuitPython_Motor @@ -1 +1 @@ -Subproject commit 0c598f67c4688f0108b9671c2834ef343032906b +Subproject commit 20ebf51fe0d2bb48b1780c3c9bd74c16c73bc02e diff --git a/frozen/Adafruit_CircuitPython_NeoPixel b/frozen/Adafruit_CircuitPython_NeoPixel index 310621f3283..aa82c0724cc 160000 --- a/frozen/Adafruit_CircuitPython_NeoPixel +++ b/frozen/Adafruit_CircuitPython_NeoPixel @@ -1 +1 @@ -Subproject commit 310621f32839b73f892b227650c5d002a310e7c5 +Subproject commit aa82c0724ccb68fbd94605c9f4f09b19c5d2919d diff --git a/frozen/Adafruit_CircuitPython_OPT4048 b/frozen/Adafruit_CircuitPython_OPT4048 new file mode 160000 index 00000000000..97e63d8cd24 --- /dev/null +++ b/frozen/Adafruit_CircuitPython_OPT4048 @@ -0,0 +1 @@ +Subproject commit 97e63d8cd2425248c0aee323c3d8a6422404eaa5 diff --git a/frozen/Adafruit_CircuitPython_PCF8563 b/frozen/Adafruit_CircuitPython_PCF8563 index cadd1790454..c4ca8d355b7 160000 --- a/frozen/Adafruit_CircuitPython_PCF8563 +++ b/frozen/Adafruit_CircuitPython_PCF8563 @@ -1 +1 @@ -Subproject commit cadd17904543d43c5ef19206ed8471b3476f119c +Subproject commit c4ca8d355b79179b44716544577925442a801bc0 diff --git a/frozen/Adafruit_CircuitPython_Pixel_Framebuf b/frozen/Adafruit_CircuitPython_Pixel_Framebuf index b09586b52dc..ffd3e8a6926 160000 --- a/frozen/Adafruit_CircuitPython_Pixel_Framebuf +++ b/frozen/Adafruit_CircuitPython_Pixel_Framebuf @@ -1 +1 @@ -Subproject commit b09586b52dcfd51e8730a126899b4128df258a8c +Subproject commit ffd3e8a692676d076a2fa3f725e3a8ea63441139 diff --git a/frozen/Adafruit_CircuitPython_PortalBase b/frozen/Adafruit_CircuitPython_PortalBase index e23cc47d97a..fc4aeea36ae 160000 --- a/frozen/Adafruit_CircuitPython_PortalBase +++ b/frozen/Adafruit_CircuitPython_PortalBase @@ -1 +1 @@ -Subproject commit e23cc47d97a97a3dc65b951c0bfc085668c8d1b1 +Subproject commit fc4aeea36ae462463eb1317b66e0f772c439b28a diff --git a/frozen/Adafruit_CircuitPython_ProgressBar b/frozen/Adafruit_CircuitPython_ProgressBar index ac96488c8ca..e720f6ff61a 160000 --- a/frozen/Adafruit_CircuitPython_ProgressBar +++ b/frozen/Adafruit_CircuitPython_ProgressBar @@ -1 +1 @@ -Subproject commit ac96488c8caaeb18eaed7a83289f81380eba2978 +Subproject commit e720f6ff61aa41485a5611d8df3f7fa25fe8fb79 diff --git a/frozen/Adafruit_CircuitPython_RFM69 b/frozen/Adafruit_CircuitPython_RFM69 index 5e050c4596f..2f8a38c3cae 160000 --- a/frozen/Adafruit_CircuitPython_RFM69 +++ b/frozen/Adafruit_CircuitPython_RFM69 @@ -1 +1 @@ -Subproject commit 5e050c4596fd639d91fbd63ae99617b75485c7af +Subproject commit 2f8a38c3cae772aa73216499dd40fde695878566 diff --git a/frozen/Adafruit_CircuitPython_RFM9x b/frozen/Adafruit_CircuitPython_RFM9x index c5c3d629d42..b2a843ddff2 160000 --- a/frozen/Adafruit_CircuitPython_RFM9x +++ b/frozen/Adafruit_CircuitPython_RFM9x @@ -1 +1 @@ -Subproject commit c5c3d629d42dc56bc34d892306582947385cf133 +Subproject commit b2a843ddff22cec5a2b6ee79ba0c52e17cbf9dd2 diff --git a/frozen/Adafruit_CircuitPython_Register b/frozen/Adafruit_CircuitPython_Register index d37349183b8..e168e97a2c9 160000 --- a/frozen/Adafruit_CircuitPython_Register +++ b/frozen/Adafruit_CircuitPython_Register @@ -1 +1 @@ -Subproject commit d37349183b82cd7d05af57a77eb3765e17e7be3f +Subproject commit e168e97a2c9713ec0f82cb6171461873dfffd46d diff --git a/frozen/Adafruit_CircuitPython_Requests b/frozen/Adafruit_CircuitPython_Requests index 6c56de79fb4..82a656aa807 160000 --- a/frozen/Adafruit_CircuitPython_Requests +++ b/frozen/Adafruit_CircuitPython_Requests @@ -1 +1 @@ -Subproject commit 6c56de79fb49ef16164148b68a63336d82b69f7a +Subproject commit 82a656aa80797ae8c526b69061b9e75728d377c9 diff --git a/frozen/Adafruit_CircuitPython_SD b/frozen/Adafruit_CircuitPython_SD index 8688597c753..e85d264ad6e 160000 --- a/frozen/Adafruit_CircuitPython_SD +++ b/frozen/Adafruit_CircuitPython_SD @@ -1 +1 @@ -Subproject commit 8688597c753b76beb8a834daef592294ffba216c +Subproject commit e85d264ad6eaa286333fd3dbbf7a95b9ea7f0af3 diff --git a/frozen/Adafruit_CircuitPython_SHT4x b/frozen/Adafruit_CircuitPython_SHT4x index a727b08bc70..c29695027b1 160000 --- a/frozen/Adafruit_CircuitPython_SHT4x +++ b/frozen/Adafruit_CircuitPython_SHT4x @@ -1 +1 @@ -Subproject commit a727b08bc7046a997d5f10e8b59a81bbe0f54da2 +Subproject commit c29695027b1d5f5140b570f31c91ace373f45843 diff --git a/frozen/Adafruit_CircuitPython_SSD1306 b/frozen/Adafruit_CircuitPython_SSD1306 index a990c874389..f8fa41a320f 160000 --- a/frozen/Adafruit_CircuitPython_SSD1306 +++ b/frozen/Adafruit_CircuitPython_SSD1306 @@ -1 +1 @@ -Subproject commit a990c874389b6fd27636b21f9b831fc91781e925 +Subproject commit f8fa41a320f0bb29be6f37d340e69eba16b7a311 diff --git a/frozen/Adafruit_CircuitPython_SSD1680 b/frozen/Adafruit_CircuitPython_SSD1680 index 5417f6225fb..f17e62d2466 160000 --- a/frozen/Adafruit_CircuitPython_SSD1680 +++ b/frozen/Adafruit_CircuitPython_SSD1680 @@ -1 +1 @@ -Subproject commit 5417f6225fb0573853972852ebdfa3aa080fed93 +Subproject commit f17e62d246656b3f956232c368bc05d966988d9a diff --git a/frozen/Adafruit_CircuitPython_ST7789 b/frozen/Adafruit_CircuitPython_ST7789 index fd4c53e6b0e..24a0feec2b2 160000 --- a/frozen/Adafruit_CircuitPython_ST7789 +++ b/frozen/Adafruit_CircuitPython_ST7789 @@ -1 +1 @@ -Subproject commit fd4c53e6b0ed4805362362837aa7dd71ae7fe1da +Subproject commit 24a0feec2b24517c9f606f5063b6b48db4ce370e diff --git a/frozen/Adafruit_CircuitPython_SimpleIO b/frozen/Adafruit_CircuitPython_SimpleIO index 967a12a68c4..5762bd0ec13 160000 --- a/frozen/Adafruit_CircuitPython_SimpleIO +++ b/frozen/Adafruit_CircuitPython_SimpleIO @@ -1 +1 @@ -Subproject commit 967a12a68c4b82048cb5efe99847408215188561 +Subproject commit 5762bd0ec1309f9ef489633ed8bcc17d1bc7f560 diff --git a/frozen/Adafruit_CircuitPython_SimpleMath b/frozen/Adafruit_CircuitPython_SimpleMath index 4bb3eb41501..3653b67541b 160000 --- a/frozen/Adafruit_CircuitPython_SimpleMath +++ b/frozen/Adafruit_CircuitPython_SimpleMath @@ -1 +1 @@ -Subproject commit 4bb3eb415019cb7c143dd6c467289e20409af788 +Subproject commit 3653b67541b7dbf0fbaaa65628c25cc6900dea87 diff --git a/frozen/Adafruit_CircuitPython_Thermistor b/frozen/Adafruit_CircuitPython_Thermistor index 09034b0fe52..86b15255613 160000 --- a/frozen/Adafruit_CircuitPython_Thermistor +++ b/frozen/Adafruit_CircuitPython_Thermistor @@ -1 +1 @@ -Subproject commit 09034b0fe5221faf8c2c01042e97a9d6334a1680 +Subproject commit 86b152556138624979cad2df3210cadc38b5b344 diff --git a/frozen/Adafruit_CircuitPython_Ticks b/frozen/Adafruit_CircuitPython_Ticks index 527d90e91fa..0b27bc3dad3 160000 --- a/frozen/Adafruit_CircuitPython_Ticks +++ b/frozen/Adafruit_CircuitPython_Ticks @@ -1 +1 @@ -Subproject commit 527d90e91fa70d08399291229bdcb2e9a6605a6a +Subproject commit 0b27bc3dad368b2cd6f18cb4faba3fcb41d54477 diff --git a/frozen/Adafruit_CircuitPython_UC8151D b/frozen/Adafruit_CircuitPython_UC8151D index a74fbafaecc..9a37fc43eeb 160000 --- a/frozen/Adafruit_CircuitPython_UC8151D +++ b/frozen/Adafruit_CircuitPython_UC8151D @@ -1 +1 @@ -Subproject commit a74fbafaecc5e44b462ef5ee2538e6a3ebf676e8 +Subproject commit 9a37fc43eeb277f698614e8d657c4104a75a44aa diff --git a/frozen/Adafruit_CircuitPython_Wave b/frozen/Adafruit_CircuitPython_Wave index 71f20ac457b..b2dd41fa0e3 160000 --- a/frozen/Adafruit_CircuitPython_Wave +++ b/frozen/Adafruit_CircuitPython_Wave @@ -1 +1 @@ -Subproject commit 71f20ac457ba73d462c9851ce0d7c3c466efa3c3 +Subproject commit b2dd41fa0e3757c187a4693147eb7d83a84b5119 diff --git a/frozen/Adafruit_CircuitPython_Wiznet5k b/frozen/Adafruit_CircuitPython_Wiznet5k index 6abacdf3326..f01275e34ad 160000 --- a/frozen/Adafruit_CircuitPython_Wiznet5k +++ b/frozen/Adafruit_CircuitPython_Wiznet5k @@ -1 +1 @@ -Subproject commit 6abacdf332602afb35fce0e68763c1b47e0c0297 +Subproject commit f01275e34ad2e5f7ddd9d074e963a8359011a297 diff --git a/frozen/Adafruit_CircuitPython_asyncio b/frozen/Adafruit_CircuitPython_asyncio index 2ea2b06c7dc..705ae0cbda8 160000 --- a/frozen/Adafruit_CircuitPython_asyncio +++ b/frozen/Adafruit_CircuitPython_asyncio @@ -1 +1 @@ -Subproject commit 2ea2b06c7dcc41538790cc4cef5bc3e709b80762 +Subproject commit 705ae0cbda87c4bb4d82fb81aa8fb718b5a4b385 diff --git a/frozen/Adafruit_CircuitPython_framebuf b/frozen/Adafruit_CircuitPython_framebuf index dd4c4e92781..6f6c89891de 160000 --- a/frozen/Adafruit_CircuitPython_framebuf +++ b/frozen/Adafruit_CircuitPython_framebuf @@ -1 +1 @@ -Subproject commit dd4c4e927819f51ff1b1aa45ff11750581628d79 +Subproject commit 6f6c89891de7d96c43028c4fdff5765763dffe16 diff --git a/frozen/Adafruit_CircuitPython_seesaw b/frozen/Adafruit_CircuitPython_seesaw index 3109848de6c..13ba8ba2a2c 160000 --- a/frozen/Adafruit_CircuitPython_seesaw +++ b/frozen/Adafruit_CircuitPython_seesaw @@ -1 +1 @@ -Subproject commit 3109848de6c7de1755ac2ccdcfc58460b7cc09bf +Subproject commit 13ba8ba2a2cecb9df5a41390f991ce6c0cd76e14 diff --git a/frozen/CircuitPython_edupico2_paj7620 b/frozen/CircuitPython_edupico2_paj7620 new file mode 160000 index 00000000000..16a4d784724 --- /dev/null +++ b/frozen/CircuitPython_edupico2_paj7620 @@ -0,0 +1 @@ +Subproject commit 16a4d784724992862cffd594aeed8c627ecc18b3 diff --git a/frozen/circuitpython-stage b/frozen/circuitpython-stage index 25e35a8620b..7b71363acb6 160000 --- a/frozen/circuitpython-stage +++ b/frozen/circuitpython-stage @@ -1 +1 @@ -Subproject commit 25e35a8620bfab08ff4ec30bf89667dca0b05fcf +Subproject commit 7b71363acb67cb1b254b12607f35280cfb4ad6c1 diff --git a/frozen/pew-pewpew-lcd b/frozen/pew-pewpew-lcd index 5ef39129207..56ed57038f2 160000 --- a/frozen/pew-pewpew-lcd +++ b/frozen/pew-pewpew-lcd @@ -1 +1 @@ -Subproject commit 5ef39129207d5b9ad52b839f934ccdd0a8a7ed8a +Subproject commit 56ed57038f2b64d108786d53996e41f63986eebf diff --git a/lib/AnimatedGIF/gif.c b/lib/AnimatedGIF/gif.c index 0822b608c18..316fc1ab749 100644 --- a/lib/AnimatedGIF/gif.c +++ b/lib/AnimatedGIF/gif.c @@ -23,7 +23,7 @@ // #include "AnimatedGIF_circuitpy.h" -#ifdef HAL_ESP32_HAL_H_ +#ifndef memcpy_P #define memcpy_P memcpy #endif diff --git a/lib/berkeley-db-1.xx b/lib/berkeley-db-1.xx index 85373b548f1..0f3bb6947c2 160000 --- a/lib/berkeley-db-1.xx +++ b/lib/berkeley-db-1.xx @@ -1 +1 @@ -Subproject commit 85373b548f1fb0119a463582570b44189dfb09ae +Subproject commit 0f3bb6947c2f57233916dccd7bb425d7bf86e5a6 diff --git a/lib/certificates b/lib/certificates index ad28d2ee548..d7c6385f671 160000 --- a/lib/certificates +++ b/lib/certificates @@ -1 +1 @@ -Subproject commit ad28d2ee548bd55033f0a88df6f8902589c365a6 +Subproject commit d7c6385f671665820ea2d307b0a94f9e61ef6f91 diff --git a/lib/libffi b/lib/libffi index e9de7e35f23..3d0ce1e6fcf 160000 --- a/lib/libffi +++ b/lib/libffi @@ -1 +1 @@ -Subproject commit e9de7e35f2339598b16cbb375f9992643ed81209 +Subproject commit 3d0ce1e6fcf19f853894862abcbac0ae78a7be60 diff --git a/lib/libm/libm.h b/lib/libm/libm.h index f782249e534..75a2a775f89 100644 --- a/lib/libm/libm.h +++ b/lib/libm/libm.h @@ -19,7 +19,15 @@ #include #include +// CIRCUITPY-CHANGE: prevent undefined warnings +#ifndef FLT_EVAL_METHOD #define FLT_EVAL_METHOD 0 +#endif + +// These lines verify that FLT_EVAL_METHOD==0, MicroPython's libm requires this. +// If compilation fails here then check the host compiler's FLT_EVAL_METHOD. +typedef float float_t; +typedef double double_t; #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ diff --git a/lib/libm/wf_lgamma.c b/lib/libm/wf_lgamma.c index bcf3705420e..7580d2f74e5 100644 --- a/lib/libm/wf_lgamma.c +++ b/lib/libm/wf_lgamma.c @@ -24,7 +24,9 @@ */ #include "fdlibm.h" +#ifndef _IEEE_LIBM #define _IEEE_LIBM 1 +#endif #ifdef __STDC__ float lgammaf(float x) diff --git a/lib/libm/wf_tgamma.c b/lib/libm/wf_tgamma.c index 3ff05f331d0..1a6c74ca11d 100644 --- a/lib/libm/wf_tgamma.c +++ b/lib/libm/wf_tgamma.c @@ -24,7 +24,9 @@ #include "math.h" #include "fdlibm.h" +#ifndef _IEEE_LIBM #define _IEEE_LIBM 1 +#endif #ifdef __STDC__ float tgammaf(float x) diff --git a/lib/libm_dbl/libm.h b/lib/libm_dbl/libm.h index dc0b431a448..fa49ad1cddd 100644 --- a/lib/libm_dbl/libm.h +++ b/lib/libm_dbl/libm.h @@ -15,7 +15,10 @@ #include #include -#define FLT_EVAL_METHOD 0 +// These lines verify that FLT_EVAL_METHOD==0, MicroPython's libm requires this. +// If compilation fails here then check the host compiler's FLT_EVAL_METHOD. +typedef float float_t; +typedef double double_t; #define FORCE_EVAL(x) do { \ if (sizeof(x) == sizeof(float)) { \ @@ -86,7 +89,9 @@ do { \ (d) = __u.f; \ } while (0) +#if !defined(DBL_EPSILON) #define DBL_EPSILON 2.22044604925031308085e-16 +#endif int __rem_pio2(double, double*); int __rem_pio2_large(double*, double*, int, int, int); diff --git a/lib/libm_dbl/rint.c b/lib/libm_dbl/rint.c index fbba390e7d7..b85dec8f246 100644 --- a/lib/libm_dbl/rint.c +++ b/lib/libm_dbl/rint.c @@ -2,7 +2,7 @@ #include #include -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 +#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 || FLT_EVAL_METHOD==16 #define EPS DBL_EPSILON #elif FLT_EVAL_METHOD==2 #define EPS LDBL_EPSILON diff --git a/lib/littlefs/lfs1.c b/lib/littlefs/lfs1.c index 6a3fd670012..ec18dc47025 100644 --- a/lib/littlefs/lfs1.c +++ b/lib/littlefs/lfs1.c @@ -2141,7 +2141,7 @@ int lfs1_format(lfs1_t *lfs1, const struct lfs1_config *cfg) { .d.elen = sizeof(superblock.d) - sizeof(superblock.d.magic) - 4, .d.nlen = sizeof(superblock.d.magic), .d.version = LFS1_DISK_VERSION, - .d.magic = {"littlefs"}, + .d.magic = {'l', 'i', 't', 't', 'l', 'e', 'f', 's'}, .d.block_size = lfs1->cfg->block_size, .d.block_count = lfs1->cfg->block_count, .d.root = {lfs1->root[0], lfs1->root[1]}, diff --git a/lib/littlefs/lfs2.c b/lib/littlefs/lfs2.c index 613213669c8..8d18b7d1105 100644 --- a/lib/littlefs/lfs2.c +++ b/lib/littlefs/lfs2.c @@ -93,6 +93,7 @@ static int lfs2_bd_read(lfs2_t *lfs2, // bypass cache? diff = lfs2_aligndown(diff, lfs2->cfg->read_size); int err = lfs2->cfg->read(lfs2->cfg, block, off, data, diff); + LFS2_ASSERT(err <= 0); if (err) { return err; } @@ -282,6 +283,21 @@ static int lfs2_bd_erase(lfs2_t *lfs2, lfs2_block_t block) { /// Small type-level utilities /// + +// some operations on paths +static inline lfs2_size_t lfs2_path_namelen(const char *path) { + return strcspn(path, "/"); +} + +static inline bool lfs2_path_islast(const char *path) { + lfs2_size_t namelen = lfs2_path_namelen(path); + return path[namelen + strspn(path + namelen, "/")] == '\0'; +} + +static inline bool lfs2_path_isdir(const char *path) { + return path[lfs2_path_namelen(path)] != '\0'; +} + // operations on block pairs static inline void lfs2_pair_swap(lfs2_block_t pair[2]) { lfs2_block_t t = pair[0]; @@ -389,18 +405,15 @@ struct lfs2_diskoff { // operations on global state static inline void lfs2_gstate_xor(lfs2_gstate_t *a, const lfs2_gstate_t *b) { - for (int i = 0; i < 3; i++) { - ((uint32_t*)a)[i] ^= ((const uint32_t*)b)[i]; - } + a->tag ^= b->tag; + a->pair[0] ^= b->pair[0]; + a->pair[1] ^= b->pair[1]; } static inline bool lfs2_gstate_iszero(const lfs2_gstate_t *a) { - for (int i = 0; i < 3; i++) { - if (((uint32_t*)a)[i] != 0) { - return false; - } - } - return true; + return a->tag == 0 + && a->pair[0] == 0 + && a->pair[1] == 0; } #ifndef LFS2_READONLY @@ -550,9 +563,9 @@ static int lfs2_dir_compact(lfs2_t *lfs2, lfs2_mdir_t *source, uint16_t begin, uint16_t end); static lfs2_ssize_t lfs2_file_flushedwrite(lfs2_t *lfs2, lfs2_file_t *file, const void *buffer, lfs2_size_t size); -static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, +static lfs2_ssize_t lfs2_file_write_(lfs2_t *lfs2, lfs2_file_t *file, const void *buffer, lfs2_size_t size); -static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file); +static int lfs2_file_sync_(lfs2_t *lfs2, lfs2_file_t *file); static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file); static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file); @@ -574,65 +587,72 @@ static int lfs21_traverse(lfs2_t *lfs2, int (*cb)(void*, lfs2_block_t), void *data); #endif -static int lfs2_dir_rawrewind(lfs2_t *lfs2, lfs2_dir_t *dir); +static int lfs2_dir_rewind_(lfs2_t *lfs2, lfs2_dir_t *dir); static lfs2_ssize_t lfs2_file_flushedread(lfs2_t *lfs2, lfs2_file_t *file, void *buffer, lfs2_size_t size); -static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, +static lfs2_ssize_t lfs2_file_read_(lfs2_t *lfs2, lfs2_file_t *file, void *buffer, lfs2_size_t size); -static int lfs2_file_rawclose(lfs2_t *lfs2, lfs2_file_t *file); -static lfs2_soff_t lfs2_file_rawsize(lfs2_t *lfs2, lfs2_file_t *file); +static int lfs2_file_close_(lfs2_t *lfs2, lfs2_file_t *file); +static lfs2_soff_t lfs2_file_size_(lfs2_t *lfs2, lfs2_file_t *file); -static lfs2_ssize_t lfs2_fs_rawsize(lfs2_t *lfs2); -static int lfs2_fs_rawtraverse(lfs2_t *lfs2, +static lfs2_ssize_t lfs2_fs_size_(lfs2_t *lfs2); +static int lfs2_fs_traverse_(lfs2_t *lfs2, int (*cb)(void *data, lfs2_block_t block), void *data, bool includeorphans); static int lfs2_deinit(lfs2_t *lfs2); -static int lfs2_rawunmount(lfs2_t *lfs2); +static int lfs2_unmount_(lfs2_t *lfs2); /// Block allocator /// + +// allocations should call this when all allocated blocks are committed to +// the filesystem +// +// after a checkpoint, the block allocator may realloc any untracked blocks +static void lfs2_alloc_ckpoint(lfs2_t *lfs2) { + lfs2->lookahead.ckpoint = lfs2->block_count; +} + +// drop the lookahead buffer, this is done during mounting and failed +// traversals in order to avoid invalid lookahead state +static void lfs2_alloc_drop(lfs2_t *lfs2) { + lfs2->lookahead.size = 0; + lfs2->lookahead.next = 0; + lfs2_alloc_ckpoint(lfs2); +} + #ifndef LFS2_READONLY static int lfs2_alloc_lookahead(void *p, lfs2_block_t block) { lfs2_t *lfs2 = (lfs2_t*)p; - lfs2_block_t off = ((block - lfs2->free.off) + lfs2_block_t off = ((block - lfs2->lookahead.start) + lfs2->block_count) % lfs2->block_count; - if (off < lfs2->free.size) { - lfs2->free.buffer[off / 32] |= 1U << (off % 32); + if (off < lfs2->lookahead.size) { + lfs2->lookahead.buffer[off / 8] |= 1U << (off % 8); } return 0; } #endif -// indicate allocated blocks have been committed into the filesystem, this -// is to prevent blocks from being garbage collected in the middle of a -// commit operation -static void lfs2_alloc_ack(lfs2_t *lfs2) { - lfs2->free.ack = lfs2->block_count; -} - -// drop the lookahead buffer, this is done during mounting and failed -// traversals in order to avoid invalid lookahead state -static void lfs2_alloc_drop(lfs2_t *lfs2) { - lfs2->free.size = 0; - lfs2->free.i = 0; - lfs2_alloc_ack(lfs2); -} - #ifndef LFS2_READONLY -static int lfs2_fs_rawgc(lfs2_t *lfs2) { - // Move free offset at the first unused block (lfs2->free.i) - // lfs2->free.i is equal lfs2->free.size when all blocks are used - lfs2->free.off = (lfs2->free.off + lfs2->free.i) % lfs2->block_count; - lfs2->free.size = lfs2_min(8*lfs2->cfg->lookahead_size, lfs2->free.ack); - lfs2->free.i = 0; +static int lfs2_alloc_scan(lfs2_t *lfs2) { + // move lookahead buffer to the first unused block + // + // note we limit the lookahead buffer to at most the amount of blocks + // checkpointed, this prevents the math in lfs2_alloc from underflowing + lfs2->lookahead.start = (lfs2->lookahead.start + lfs2->lookahead.next) + % lfs2->block_count; + lfs2->lookahead.next = 0; + lfs2->lookahead.size = lfs2_min( + 8*lfs2->cfg->lookahead_size, + lfs2->lookahead.ckpoint); // find mask of free blocks from tree - memset(lfs2->free.buffer, 0, lfs2->cfg->lookahead_size); - int err = lfs2_fs_rawtraverse(lfs2, lfs2_alloc_lookahead, lfs2, true); + memset(lfs2->lookahead.buffer, 0, lfs2->cfg->lookahead_size); + int err = lfs2_fs_traverse_(lfs2, lfs2_alloc_lookahead, lfs2, true); if (err) { lfs2_alloc_drop(lfs2); return err; @@ -645,36 +665,49 @@ static int lfs2_fs_rawgc(lfs2_t *lfs2) { #ifndef LFS2_READONLY static int lfs2_alloc(lfs2_t *lfs2, lfs2_block_t *block) { while (true) { - while (lfs2->free.i != lfs2->free.size) { - lfs2_block_t off = lfs2->free.i; - lfs2->free.i += 1; - lfs2->free.ack -= 1; - - if (!(lfs2->free.buffer[off / 32] & (1U << (off % 32)))) { + // scan our lookahead buffer for free blocks + while (lfs2->lookahead.next < lfs2->lookahead.size) { + if (!(lfs2->lookahead.buffer[lfs2->lookahead.next / 8] + & (1U << (lfs2->lookahead.next % 8)))) { // found a free block - *block = (lfs2->free.off + off) % lfs2->block_count; - - // eagerly find next off so an alloc ack can - // discredit old lookahead blocks - while (lfs2->free.i != lfs2->free.size && - (lfs2->free.buffer[lfs2->free.i / 32] - & (1U << (lfs2->free.i % 32)))) { - lfs2->free.i += 1; - lfs2->free.ack -= 1; + *block = (lfs2->lookahead.start + lfs2->lookahead.next) + % lfs2->block_count; + + // eagerly find next free block to maximize how many blocks + // lfs2_alloc_ckpoint makes available for scanning + while (true) { + lfs2->lookahead.next += 1; + lfs2->lookahead.ckpoint -= 1; + + if (lfs2->lookahead.next >= lfs2->lookahead.size + || !(lfs2->lookahead.buffer[lfs2->lookahead.next / 8] + & (1U << (lfs2->lookahead.next % 8)))) { + return 0; + } } - - return 0; } + + lfs2->lookahead.next += 1; + lfs2->lookahead.ckpoint -= 1; } - // check if we have looked at all blocks since last ack - if (lfs2->free.ack == 0) { - LFS2_ERROR("No more free space %"PRIu32, - lfs2->free.i + lfs2->free.off); + // In order to keep our block allocator from spinning forever when our + // filesystem is full, we mark points where there are no in-flight + // allocations with a checkpoint before starting a set of allocations. + // + // If we've looked at all blocks since the last checkpoint, we report + // the filesystem as out of storage. + // + if (lfs2->lookahead.ckpoint <= 0) { + LFS2_ERROR("No more free space 0x%"PRIx32, + (lfs2->lookahead.start + lfs2->lookahead.next) + % lfs2->block_count); return LFS2_ERR_NOSPC; } - int err = lfs2_fs_rawgc(lfs2); + // No blocks in our lookahead buffer, we need to scan the filesystem for + // unused blocks in the next lookahead window. + int err = lfs2_alloc_scan(lfs2); if(err) { return err; } @@ -690,11 +723,14 @@ static lfs2_stag_t lfs2_dir_getslice(lfs2_t *lfs2, const lfs2_mdir_t *dir, lfs2_tag_t ntag = dir->etag; lfs2_stag_t gdiff = 0; + // synthetic moves if (lfs2_gstate_hasmovehere(&lfs2->gdisk, dir->pair) && - lfs2_tag_id(gmask) != 0 && - lfs2_tag_id(lfs2->gdisk.tag) <= lfs2_tag_id(gtag)) { - // synthetic moves - gdiff -= LFS2_MKTAG(0, 1, 0); + lfs2_tag_id(gmask) != 0) { + if (lfs2_tag_id(lfs2->gdisk.tag) == lfs2_tag_id(gtag)) { + return LFS2_ERR_NOENT; + } else if (lfs2_tag_id(lfs2->gdisk.tag) < lfs2_tag_id(gtag)) { + gdiff -= LFS2_MKTAG(0, 1, 0); + } } // iterate over dir block backwards (for faster lookups) @@ -704,6 +740,7 @@ static lfs2_stag_t lfs2_dir_getslice(lfs2_t *lfs2, const lfs2_mdir_t *dir, int err = lfs2_bd_read(lfs2, NULL, &lfs2->rcache, sizeof(ntag), dir->pair[0], off, &ntag, sizeof(ntag)); + LFS2_ASSERT(err <= 0); if (err) { return err; } @@ -732,6 +769,7 @@ static lfs2_stag_t lfs2_dir_getslice(lfs2_t *lfs2, const lfs2_mdir_t *dir, err = lfs2_bd_read(lfs2, NULL, &lfs2->rcache, diff, dir->pair[0], off+sizeof(tag)+goff, gbuffer, diff); + LFS2_ASSERT(err <= 0); if (err) { return err; } @@ -793,9 +831,6 @@ static int lfs2_dir_getread(lfs2_t *lfs2, const lfs2_mdir_t *dir, size -= diff; continue; } - - // rcache takes priority - diff = lfs2_min(diff, rcache->off-off); } // load to cache, first condition can no longer fail @@ -1247,6 +1282,7 @@ static lfs2_stag_t lfs2_dir_fetchmatch(lfs2_t *lfs2, if (err == LFS2_ERR_CORRUPT) { break; } + return err; } lfs2_fcrc_fromle32(&fcrc); @@ -1438,32 +1474,46 @@ static int lfs2_dir_find_match(void *data, return LFS2_CMP_EQ; } +// lfs2_dir_find tries to set path and id even if file is not found +// +// returns: +// - 0 if file is found +// - LFS2_ERR_NOENT if file or parent is not found +// - LFS2_ERR_NOTDIR if parent is not a dir static lfs2_stag_t lfs2_dir_find(lfs2_t *lfs2, lfs2_mdir_t *dir, const char **path, uint16_t *id) { // we reduce path to a single name if we can find it const char *name = *path; - if (id) { - *id = 0x3ff; - } // default to root dir lfs2_stag_t tag = LFS2_MKTAG(LFS2_TYPE_DIR, 0x3ff, 0); dir->tail[0] = lfs2->root[0]; dir->tail[1] = lfs2->root[1]; + // empty paths are not allowed + if (*name == '\0') { + return LFS2_ERR_INVAL; + } + while (true) { nextname: - // skip slashes - name += strspn(name, "/"); + // skip slashes if we're a directory + if (lfs2_tag_type3(tag) == LFS2_TYPE_DIR) { + name += strspn(name, "/"); + } lfs2_size_t namelen = strcspn(name, "/"); - // skip '.' and root '..' - if ((namelen == 1 && memcmp(name, ".", 1) == 0) || - (namelen == 2 && memcmp(name, "..", 2) == 0)) { + // skip '.' + if (namelen == 1 && memcmp(name, ".", 1) == 0) { name += namelen; goto nextname; } + // error on unmatched '..', trying to go above root? + if (namelen == 2 && memcmp(name, "..", 2) == 0) { + return LFS2_ERR_INVAL; + } + // skip if matched by '..' in name const char *suffix = name + namelen; lfs2_size_t sufflen; @@ -1475,7 +1525,9 @@ static lfs2_stag_t lfs2_dir_find(lfs2_t *lfs2, lfs2_mdir_t *dir, break; } - if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) { + if (sufflen == 1 && memcmp(suffix, ".", 1) == 0) { + // noop + } else if (sufflen == 2 && memcmp(suffix, "..", 2) == 0) { depth -= 1; if (depth == 0) { name = suffix + sufflen; @@ -1489,14 +1541,14 @@ static lfs2_stag_t lfs2_dir_find(lfs2_t *lfs2, lfs2_mdir_t *dir, } // found path - if (name[0] == '\0') { + if (*name == '\0') { return tag; } // update what we've found so far *path = name; - // only continue if we hit a directory + // only continue if we're a directory if (lfs2_tag_type3(tag) != LFS2_TYPE_DIR) { return LFS2_ERR_NOTDIR; } @@ -1516,8 +1568,7 @@ static lfs2_stag_t lfs2_dir_find(lfs2_t *lfs2, lfs2_mdir_t *dir, tag = lfs2_dir_fetchmatch(lfs2, dir, dir->tail, LFS2_MKTAG(0x780, 0, 0), LFS2_MKTAG(LFS2_TYPE_NAME, 0, namelen), - // are we last name? - (strchr(name, '/') == NULL) ? id : NULL, + id, lfs2_dir_find_match, &(struct lfs2_dir_find_match){ lfs2, name, namelen}); if (tag < 0) { @@ -2105,13 +2156,14 @@ static int lfs2_dir_splittingcompact(lfs2_t *lfs2, lfs2_mdir_t *dir, // And we cap at half a block to avoid degenerate cases with // nearly-full metadata blocks. // + lfs2_size_t metadata_max = (lfs2->cfg->metadata_max) + ? lfs2->cfg->metadata_max + : lfs2->cfg->block_size; if (end - split < 0xff && size <= lfs2_min( - lfs2->cfg->block_size - 40, + metadata_max - 40, lfs2_alignup( - (lfs2->cfg->metadata_max - ? lfs2->cfg->metadata_max - : lfs2->cfg->block_size)/2, + metadata_max/2, lfs2->cfg->prog_size))) { break; } @@ -2146,14 +2198,16 @@ static int lfs2_dir_splittingcompact(lfs2_t *lfs2, lfs2_mdir_t *dir, && lfs2_pair_cmp(dir->pair, (const lfs2_block_t[2]){0, 1}) == 0) { // oh no! we're writing too much to the superblock, // should we expand? - lfs2_ssize_t size = lfs2_fs_rawsize(lfs2); + lfs2_ssize_t size = lfs2_fs_size_(lfs2); if (size < 0) { return size; } - // do we have extra space? littlefs can't reclaim this space - // by itself, so expand cautiously - if ((lfs2_size_t)size < lfs2->block_count/2) { + // littlefs cannot reclaim expanded superblocks, so expand cautiously + // + // if our filesystem is more than ~88% full, don't expand, this is + // somewhat arbitrary + if (lfs2->block_count - size > lfs2->block_count/8) { LFS2_DEBUG("Expanding superblock at rev %"PRIu32, dir->rev); int err = lfs2_dir_split(lfs2, dir, attrs, attrcount, source, begin, end); @@ -2166,7 +2220,8 @@ static int lfs2_dir_splittingcompact(lfs2_t *lfs2, lfs2_mdir_t *dir, // we can do, we'll error later if we've become frozen LFS2_WARN("Unable to expand superblock"); } else { - end = begin; + // duplicate the superblock entry into the new superblock + end = 1; } } } @@ -2213,7 +2268,7 @@ static int lfs2_dir_relocatingcommit(lfs2_t *lfs2, lfs2_mdir_t *dir, } } - if (dir->erased) { + if (dir->erased && dir->count < 0xff) { // try to commit struct lfs2_commit commit = { .block = dir->pair[0], @@ -2312,7 +2367,8 @@ fixmlist:; if (d->m.pair != pair) { for (int i = 0; i < attrcount; i++) { if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && - d->id == lfs2_tag_id(attrs[i].tag)) { + d->id == lfs2_tag_id(attrs[i].tag) && + d->type != LFS2_TYPE_DIR) { d->m.pair[0] = LFS2_BLOCK_NULL; d->m.pair[1] = LFS2_BLOCK_NULL; } else if (lfs2_tag_type3(attrs[i].tag) == LFS2_TYPE_DELETE && @@ -2333,7 +2389,9 @@ fixmlist:; while (d->id >= d->m.count && d->m.split) { // we split and id is on tail now - d->id -= d->m.count; + if (lfs2_pair_cmp(d->m.tail, lfs2->root) != 0) { + d->id -= d->m.count; + } int err = lfs2_dir_fetch(lfs2, &d->m, d->m.tail); if (err) { return err; @@ -2499,7 +2557,7 @@ static int lfs2_dir_orphaningcommit(lfs2_t *lfs2, lfs2_mdir_t *dir, if (err != LFS2_ERR_NOENT) { if (lfs2_gstate_hasorphans(&lfs2->gstate)) { // next step, clean up orphans - err = lfs2_fs_preporphans(lfs2, -hasparent); + err = lfs2_fs_preporphans(lfs2, -(int8_t)hasparent); if (err) { return err; } @@ -2564,7 +2622,7 @@ static int lfs2_dir_commit(lfs2_t *lfs2, lfs2_mdir_t *dir, /// Top level directory operations /// #ifndef LFS2_READONLY -static int lfs2_rawmkdir(lfs2_t *lfs2, const char *path) { +static int lfs2_mkdir_(lfs2_t *lfs2, const char *path) { // deorphan if we haven't yet, needed at most once after poweron int err = lfs2_fs_forceconsistency(lfs2); if (err) { @@ -2575,18 +2633,18 @@ static int lfs2_rawmkdir(lfs2_t *lfs2, const char *path) { cwd.next = lfs2->mlist; uint16_t id; err = lfs2_dir_find(lfs2, &cwd.m, &path, &id); - if (!(err == LFS2_ERR_NOENT && id != 0x3ff)) { + if (!(err == LFS2_ERR_NOENT && lfs2_path_islast(path))) { return (err < 0) ? err : LFS2_ERR_EXIST; } // check that name fits - lfs2_size_t nlen = strlen(path); + lfs2_size_t nlen = lfs2_path_namelen(path); if (nlen > lfs2->name_max) { return LFS2_ERR_NAMETOOLONG; } // build up new directory - lfs2_alloc_ack(lfs2); + lfs2_alloc_ckpoint(lfs2); lfs2_mdir_t dir; err = lfs2_dir_alloc(lfs2, &dir); if (err) { @@ -2660,7 +2718,7 @@ static int lfs2_rawmkdir(lfs2_t *lfs2, const char *path) { } #endif -static int lfs2_dir_rawopen(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { +static int lfs2_dir_open_(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { lfs2_stag_t tag = lfs2_dir_find(lfs2, &dir->m, &path, NULL); if (tag < 0) { return tag; @@ -2704,14 +2762,14 @@ static int lfs2_dir_rawopen(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { return 0; } -static int lfs2_dir_rawclose(lfs2_t *lfs2, lfs2_dir_t *dir) { +static int lfs2_dir_close_(lfs2_t *lfs2, lfs2_dir_t *dir) { // remove from list of mdirs lfs2_mlist_remove(lfs2, (struct lfs2_mlist *)dir); return 0; } -static int lfs2_dir_rawread(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { +static int lfs2_dir_read_(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { memset(info, 0, sizeof(*info)); // special offset for '.' and '..' @@ -2756,9 +2814,9 @@ static int lfs2_dir_rawread(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *inf return true; } -static int lfs2_dir_rawseek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { +static int lfs2_dir_seek_(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { // simply walk from head dir - int err = lfs2_dir_rawrewind(lfs2, dir); + int err = lfs2_dir_rewind_(lfs2, dir); if (err) { return err; } @@ -2793,12 +2851,12 @@ static int lfs2_dir_rawseek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { return 0; } -static lfs2_soff_t lfs2_dir_rawtell(lfs2_t *lfs2, lfs2_dir_t *dir) { +static lfs2_soff_t lfs2_dir_tell_(lfs2_t *lfs2, lfs2_dir_t *dir) { (void)lfs2; return dir->pos; } -static int lfs2_dir_rawrewind(lfs2_t *lfs2, lfs2_dir_t *dir) { +static int lfs2_dir_rewind_(lfs2_t *lfs2, lfs2_dir_t *dir) { // reload the head dir int err = lfs2_dir_fetch(lfs2, &dir->m, dir->head); if (err) { @@ -3004,7 +3062,7 @@ static int lfs2_ctz_traverse(lfs2_t *lfs2, /// Top level file operations /// -static int lfs2_file_rawopencfg(lfs2_t *lfs2, lfs2_file_t *file, +static int lfs2_file_opencfg_(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags, const struct lfs2_file_config *cfg) { #ifndef LFS2_READONLY @@ -3029,7 +3087,7 @@ static int lfs2_file_rawopencfg(lfs2_t *lfs2, lfs2_file_t *file, // allocate entry for file if it doesn't exist lfs2_stag_t tag = lfs2_dir_find(lfs2, &file->m, &path, &file->id); - if (tag < 0 && !(tag == LFS2_ERR_NOENT && file->id != 0x3ff)) { + if (tag < 0 && !(tag == LFS2_ERR_NOENT && lfs2_path_islast(path))) { err = tag; goto cleanup; } @@ -3049,8 +3107,14 @@ static int lfs2_file_rawopencfg(lfs2_t *lfs2, lfs2_file_t *file, goto cleanup; } + // don't allow trailing slashes + if (lfs2_path_isdir(path)) { + err = LFS2_ERR_NOTDIR; + goto cleanup; + } + // check that name fits - lfs2_size_t nlen = strlen(path); + lfs2_size_t nlen = lfs2_path_namelen(path); if (nlen > lfs2->name_max) { err = LFS2_ERR_NAMETOOLONG; goto cleanup; @@ -3166,22 +3230,22 @@ static int lfs2_file_rawopencfg(lfs2_t *lfs2, lfs2_file_t *file, #ifndef LFS2_READONLY file->flags |= LFS2_F_ERRED; #endif - lfs2_file_rawclose(lfs2, file); + lfs2_file_close_(lfs2, file); return err; } #ifndef LFS2_NO_MALLOC -static int lfs2_file_rawopen(lfs2_t *lfs2, lfs2_file_t *file, +static int lfs2_file_open_(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags) { static const struct lfs2_file_config defaults = {0}; - int err = lfs2_file_rawopencfg(lfs2, file, path, flags, &defaults); + int err = lfs2_file_opencfg_(lfs2, file, path, flags, &defaults); return err; } #endif -static int lfs2_file_rawclose(lfs2_t *lfs2, lfs2_file_t *file) { +static int lfs2_file_close_(lfs2_t *lfs2, lfs2_file_t *file) { #ifndef LFS2_READONLY - int err = lfs2_file_rawsync(lfs2, file); + int err = lfs2_file_sync_(lfs2, file); #else int err = 0; #endif @@ -3272,7 +3336,7 @@ static int lfs2_file_relocate(lfs2_t *lfs2, lfs2_file_t *file) { #ifndef LFS2_READONLY static int lfs2_file_outline(lfs2_t *lfs2, lfs2_file_t *file) { file->off = file->pos; - lfs2_alloc_ack(lfs2); + lfs2_alloc_ckpoint(lfs2); int err = lfs2_file_relocate(lfs2, file); if (err) { return err; @@ -3364,7 +3428,7 @@ static int lfs2_file_flush(lfs2_t *lfs2, lfs2_file_t *file) { } #ifndef LFS2_READONLY -static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file) { +static int lfs2_file_sync_(lfs2_t *lfs2, lfs2_file_t *file) { if (file->flags & LFS2_F_ERRED) { // it's not safe to do anything if our file errored return 0; @@ -3379,6 +3443,15 @@ static int lfs2_file_rawsync(lfs2_t *lfs2, lfs2_file_t *file) { if ((file->flags & LFS2_F_DIRTY) && !lfs2_pair_isnull(file->m.pair)) { + // before we commit metadata, we need sync the disk to make sure + // data writes don't complete after metadata writes + if (!(file->flags & LFS2_F_INLINE)) { + err = lfs2_bd_sync(lfs2, &lfs2->pcache, &lfs2->rcache, false); + if (err) { + return err; + } + } + // update dir entry uint16_t type; const void *buffer; @@ -3477,7 +3550,7 @@ static lfs2_ssize_t lfs2_file_flushedread(lfs2_t *lfs2, lfs2_file_t *file, return size; } -static lfs2_ssize_t lfs2_file_rawread(lfs2_t *lfs2, lfs2_file_t *file, +static lfs2_ssize_t lfs2_file_read_(lfs2_t *lfs2, lfs2_file_t *file, void *buffer, lfs2_size_t size) { LFS2_ASSERT((file->flags & LFS2_O_RDONLY) == LFS2_O_RDONLY); @@ -3502,11 +3575,7 @@ static lfs2_ssize_t lfs2_file_flushedwrite(lfs2_t *lfs2, lfs2_file_t *file, lfs2_size_t nsize = size; if ((file->flags & LFS2_F_INLINE) && - lfs2_max(file->pos+nsize, file->ctz.size) > - lfs2_min(0x3fe, lfs2_min( - lfs2->cfg->cache_size, - (lfs2->cfg->metadata_max ? - lfs2->cfg->metadata_max : lfs2->cfg->block_size) / 8))) { + lfs2_max(file->pos+nsize, file->ctz.size) > lfs2->inline_max) { // inline file doesn't fit anymore int err = lfs2_file_outline(lfs2, file); if (err) { @@ -3535,7 +3604,7 @@ static lfs2_ssize_t lfs2_file_flushedwrite(lfs2_t *lfs2, lfs2_file_t *file, } // extend file with new blocks - lfs2_alloc_ack(lfs2); + lfs2_alloc_ckpoint(lfs2); int err = lfs2_ctz_extend(lfs2, &file->cache, &lfs2->rcache, file->block, file->pos, &file->block, &file->off); @@ -3578,13 +3647,13 @@ static lfs2_ssize_t lfs2_file_flushedwrite(lfs2_t *lfs2, lfs2_file_t *file, data += diff; nsize -= diff; - lfs2_alloc_ack(lfs2); + lfs2_alloc_ckpoint(lfs2); } return size; } -static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, +static lfs2_ssize_t lfs2_file_write_(lfs2_t *lfs2, lfs2_file_t *file, const void *buffer, lfs2_size_t size) { LFS2_ASSERT((file->flags & LFS2_O_WRONLY) == LFS2_O_WRONLY); @@ -3628,25 +3697,19 @@ static lfs2_ssize_t lfs2_file_rawwrite(lfs2_t *lfs2, lfs2_file_t *file, } #endif -static lfs2_soff_t lfs2_file_rawseek(lfs2_t *lfs2, lfs2_file_t *file, +static lfs2_soff_t lfs2_file_seek_(lfs2_t *lfs2, lfs2_file_t *file, lfs2_soff_t off, int whence) { // find new pos + // + // fortunately for us, littlefs is limited to 31-bit file sizes, so we + // don't have to worry too much about integer overflow lfs2_off_t npos = file->pos; if (whence == LFS2_SEEK_SET) { npos = off; } else if (whence == LFS2_SEEK_CUR) { - if ((lfs2_soff_t)file->pos + off < 0) { - return LFS2_ERR_INVAL; - } else { - npos = file->pos + off; - } + npos = file->pos + (lfs2_off_t)off; } else if (whence == LFS2_SEEK_END) { - lfs2_soff_t res = lfs2_file_rawsize(lfs2, file) + off; - if (res < 0) { - return LFS2_ERR_INVAL; - } else { - npos = res; - } + npos = (lfs2_off_t)lfs2_file_size_(lfs2, file) + (lfs2_off_t)off; } if (npos > lfs2->file_max) { @@ -3661,13 +3724,8 @@ static lfs2_soff_t lfs2_file_rawseek(lfs2_t *lfs2, lfs2_file_t *file, // if we're only reading and our new offset is still in the file's cache // we can avoid flushing and needing to reread the data - if ( -#ifndef LFS2_READONLY - !(file->flags & LFS2_F_WRITING) -#else - true -#endif - ) { + if ((file->flags & LFS2_F_READING) + && file->off != lfs2->cfg->block_size) { int oindex = lfs2_ctz_index(lfs2, &(lfs2_off_t){file->pos}); lfs2_off_t noff = npos; int nindex = lfs2_ctz_index(lfs2, &noff); @@ -3692,7 +3750,7 @@ static lfs2_soff_t lfs2_file_rawseek(lfs2_t *lfs2, lfs2_file_t *file, } #ifndef LFS2_READONLY -static int lfs2_file_rawtruncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { +static int lfs2_file_truncate_(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { LFS2_ASSERT((file->flags & LFS2_O_WRONLY) == LFS2_O_WRONLY); if (size > LFS2_FILE_MAX) { @@ -3700,15 +3758,12 @@ static int lfs2_file_rawtruncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t siz } lfs2_off_t pos = file->pos; - lfs2_off_t oldsize = lfs2_file_rawsize(lfs2, file); + lfs2_off_t oldsize = lfs2_file_size_(lfs2, file); if (size < oldsize) { // revert to inline file? - if (size <= lfs2_min(0x3fe, lfs2_min( - lfs2->cfg->cache_size, - (lfs2->cfg->metadata_max ? - lfs2->cfg->metadata_max : lfs2->cfg->block_size) / 8))) { + if (size <= lfs2->inline_max) { // flush+seek to head - lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, 0, LFS2_SEEK_SET); + lfs2_soff_t res = lfs2_file_seek_(lfs2, file, 0, LFS2_SEEK_SET); if (res < 0) { return (int)res; } @@ -3753,14 +3808,14 @@ static int lfs2_file_rawtruncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t siz } } else if (size > oldsize) { // flush+seek if not already at end - lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, 0, LFS2_SEEK_END); + lfs2_soff_t res = lfs2_file_seek_(lfs2, file, 0, LFS2_SEEK_END); if (res < 0) { return (int)res; } // fill with zeros while (file->pos < size) { - res = lfs2_file_rawwrite(lfs2, file, &(uint8_t){0}, 1); + res = lfs2_file_write_(lfs2, file, &(uint8_t){0}, 1); if (res < 0) { return (int)res; } @@ -3768,7 +3823,7 @@ static int lfs2_file_rawtruncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t siz } // restore pos - lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, pos, LFS2_SEEK_SET); + lfs2_soff_t res = lfs2_file_seek_(lfs2, file, pos, LFS2_SEEK_SET); if (res < 0) { return (int)res; } @@ -3777,13 +3832,13 @@ static int lfs2_file_rawtruncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t siz } #endif -static lfs2_soff_t lfs2_file_rawtell(lfs2_t *lfs2, lfs2_file_t *file) { +static lfs2_soff_t lfs2_file_tell_(lfs2_t *lfs2, lfs2_file_t *file) { (void)lfs2; return file->pos; } -static int lfs2_file_rawrewind(lfs2_t *lfs2, lfs2_file_t *file) { - lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, 0, LFS2_SEEK_SET); +static int lfs2_file_rewind_(lfs2_t *lfs2, lfs2_file_t *file) { + lfs2_soff_t res = lfs2_file_seek_(lfs2, file, 0, LFS2_SEEK_SET); if (res < 0) { return (int)res; } @@ -3791,7 +3846,7 @@ static int lfs2_file_rawrewind(lfs2_t *lfs2, lfs2_file_t *file) { return 0; } -static lfs2_soff_t lfs2_file_rawsize(lfs2_t *lfs2, lfs2_file_t *file) { +static lfs2_soff_t lfs2_file_size_(lfs2_t *lfs2, lfs2_file_t *file) { (void)lfs2; #ifndef LFS2_READONLY @@ -3805,18 +3860,24 @@ static lfs2_soff_t lfs2_file_rawsize(lfs2_t *lfs2, lfs2_file_t *file) { /// General fs operations /// -static int lfs2_rawstat(lfs2_t *lfs2, const char *path, struct lfs2_info *info) { +static int lfs2_stat_(lfs2_t *lfs2, const char *path, struct lfs2_info *info) { lfs2_mdir_t cwd; lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); if (tag < 0) { return (int)tag; } + // only allow trailing slashes on dirs + if (strchr(path, '/') != NULL + && lfs2_tag_type3(tag) != LFS2_TYPE_DIR) { + return LFS2_ERR_NOTDIR; + } + return lfs2_dir_getinfo(lfs2, &cwd, lfs2_tag_id(tag), info); } #ifndef LFS2_READONLY -static int lfs2_rawremove(lfs2_t *lfs2, const char *path) { +static int lfs2_remove_(lfs2_t *lfs2, const char *path) { // deorphan if we haven't yet, needed at most once after poweron int err = lfs2_fs_forceconsistency(lfs2); if (err) { @@ -3872,7 +3933,9 @@ static int lfs2_rawremove(lfs2_t *lfs2, const char *path) { } lfs2->mlist = dir.next; - if (lfs2_tag_type3(tag) == LFS2_TYPE_DIR) { + if (lfs2_gstate_hasorphans(&lfs2->gstate)) { + LFS2_ASSERT(lfs2_tag_type3(tag) == LFS2_TYPE_DIR); + // fix orphan err = lfs2_fs_preporphans(lfs2, -1); if (err) { @@ -3895,7 +3958,7 @@ static int lfs2_rawremove(lfs2_t *lfs2, const char *path) { #endif #ifndef LFS2_READONLY -static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { +static int lfs2_rename_(lfs2_t *lfs2, const char *oldpath, const char *newpath) { // deorphan if we haven't yet, needed at most once after poweron int err = lfs2_fs_forceconsistency(lfs2); if (err) { @@ -3914,7 +3977,7 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath uint16_t newid; lfs2_stag_t prevtag = lfs2_dir_find(lfs2, &newcwd, &newpath, &newid); if ((prevtag < 0 || lfs2_tag_id(prevtag) == 0x3ff) && - !(prevtag == LFS2_ERR_NOENT && newid != 0x3ff)) { + !(prevtag == LFS2_ERR_NOENT && lfs2_path_islast(newpath))) { return (prevtag < 0) ? (int)prevtag : LFS2_ERR_INVAL; } @@ -3925,8 +3988,14 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath struct lfs2_mlist prevdir; prevdir.next = lfs2->mlist; if (prevtag == LFS2_ERR_NOENT) { + // if we're a file, don't allow trailing slashes + if (lfs2_path_isdir(newpath) + && lfs2_tag_type3(oldtag) != LFS2_TYPE_DIR) { + return LFS2_ERR_NOTDIR; + } + // check that name fits - lfs2_size_t nlen = strlen(newpath); + lfs2_size_t nlen = lfs2_path_namelen(newpath); if (nlen > lfs2->name_max) { return LFS2_ERR_NAMETOOLONG; } @@ -3938,7 +4007,9 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath newoldid += 1; } } else if (lfs2_tag_type3(prevtag) != lfs2_tag_type3(oldtag)) { - return LFS2_ERR_ISDIR; + return (lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) + ? LFS2_ERR_ISDIR + : LFS2_ERR_NOTDIR; } else if (samepair && newid == newoldid) { // we're renaming to ourselves?? return 0; @@ -3984,7 +4055,8 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath {LFS2_MKTAG_IF(prevtag != LFS2_ERR_NOENT, LFS2_TYPE_DELETE, newid, 0), NULL}, {LFS2_MKTAG(LFS2_TYPE_CREATE, newid, 0), NULL}, - {LFS2_MKTAG(lfs2_tag_type3(oldtag), newid, strlen(newpath)), newpath}, + {LFS2_MKTAG(lfs2_tag_type3(oldtag), + newid, lfs2_path_namelen(newpath)), newpath}, {LFS2_MKTAG(LFS2_FROM_MOVE, newid, lfs2_tag_id(oldtag)), &oldcwd}, {LFS2_MKTAG_IF(samepair, LFS2_TYPE_DELETE, newoldid, 0), NULL})); @@ -4007,8 +4079,10 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath } lfs2->mlist = prevdir.next; - if (prevtag != LFS2_ERR_NOENT - && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR) { + if (lfs2_gstate_hasorphans(&lfs2->gstate)) { + LFS2_ASSERT(prevtag != LFS2_ERR_NOENT + && lfs2_tag_type3(prevtag) == LFS2_TYPE_DIR); + // fix orphan err = lfs2_fs_preporphans(lfs2, -1); if (err) { @@ -4030,7 +4104,7 @@ static int lfs2_rawrename(lfs2_t *lfs2, const char *oldpath, const char *newpath } #endif -static lfs2_ssize_t lfs2_rawgetattr(lfs2_t *lfs2, const char *path, +static lfs2_ssize_t lfs2_getattr_(lfs2_t *lfs2, const char *path, uint8_t type, void *buffer, lfs2_size_t size) { lfs2_mdir_t cwd; lfs2_stag_t tag = lfs2_dir_find(lfs2, &cwd, &path, NULL); @@ -4088,7 +4162,7 @@ static int lfs2_commitattr(lfs2_t *lfs2, const char *path, #endif #ifndef LFS2_READONLY -static int lfs2_rawsetattr(lfs2_t *lfs2, const char *path, +static int lfs2_setattr_(lfs2_t *lfs2, const char *path, uint8_t type, const void *buffer, lfs2_size_t size) { if (size > lfs2->attr_max) { return LFS2_ERR_NOSPC; @@ -4099,13 +4173,28 @@ static int lfs2_rawsetattr(lfs2_t *lfs2, const char *path, #endif #ifndef LFS2_READONLY -static int lfs2_rawremoveattr(lfs2_t *lfs2, const char *path, uint8_t type) { +static int lfs2_removeattr_(lfs2_t *lfs2, const char *path, uint8_t type) { return lfs2_commitattr(lfs2, path, type, NULL, 0x3ff); } #endif /// Filesystem operations /// + +// compile time checks, see lfs2.h for why these limits exist +#if LFS2_NAME_MAX > 1022 +#error "Invalid LFS2_NAME_MAX, must be <= 1022" +#endif + +#if LFS2_FILE_MAX > 2147483647 +#error "Invalid LFS2_FILE_MAX, must be <= 2147483647" +#endif + +#if LFS2_ATTR_MAX > 1022 +#error "Invalid LFS2_ATTR_MAX, must be <= 1022" +#endif + +// common filesystem initialization static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs2->cfg = cfg; lfs2->block_count = cfg->block_count; // May be 0 @@ -4126,6 +4215,14 @@ static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { // which littlefs currently does not support LFS2_ASSERT((bool)0x80000000); + // check that the required io functions are provided + LFS2_ASSERT(lfs2->cfg->read != NULL); +#ifndef LFS2_READONLY + LFS2_ASSERT(lfs2->cfg->prog != NULL); + LFS2_ASSERT(lfs2->cfg->erase != NULL); + LFS2_ASSERT(lfs2->cfg->sync != NULL); +#endif + // validate that the lfs2-cfg sizes were initiated properly before // performing any arithmetic logics with them LFS2_ASSERT(lfs2->cfg->read_size != 0); @@ -4153,6 +4250,23 @@ static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { // wear-leveling. LFS2_ASSERT(lfs2->cfg->block_cycles != 0); + // check that compact_thresh makes sense + // + // metadata can't be compacted below block_size/2, and metadata can't + // exceed a block_size + LFS2_ASSERT(lfs2->cfg->compact_thresh == 0 + || lfs2->cfg->compact_thresh >= lfs2->cfg->block_size/2); + LFS2_ASSERT(lfs2->cfg->compact_thresh == (lfs2_size_t)-1 + || lfs2->cfg->compact_thresh <= lfs2->cfg->block_size); + + // check that metadata_max is a multiple of read_size and prog_size, + // and a factor of the block_size + LFS2_ASSERT(!lfs2->cfg->metadata_max + || lfs2->cfg->metadata_max % lfs2->cfg->read_size == 0); + LFS2_ASSERT(!lfs2->cfg->metadata_max + || lfs2->cfg->metadata_max % lfs2->cfg->prog_size == 0); + LFS2_ASSERT(!lfs2->cfg->metadata_max + || lfs2->cfg->block_size % lfs2->cfg->metadata_max == 0); // setup read cache if (lfs2->cfg->read_buffer) { @@ -4180,15 +4294,14 @@ static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { lfs2_cache_zero(lfs2, &lfs2->rcache); lfs2_cache_zero(lfs2, &lfs2->pcache); - // setup lookahead, must be multiple of 64-bits, 32-bit aligned + // setup lookahead buffer, note mount finishes initializing this after + // we establish a decent pseudo-random seed LFS2_ASSERT(lfs2->cfg->lookahead_size > 0); - LFS2_ASSERT(lfs2->cfg->lookahead_size % 8 == 0 && - (uintptr_t)lfs2->cfg->lookahead_buffer % 4 == 0); if (lfs2->cfg->lookahead_buffer) { - lfs2->free.buffer = lfs2->cfg->lookahead_buffer; + lfs2->lookahead.buffer = lfs2->cfg->lookahead_buffer; } else { - lfs2->free.buffer = lfs2_malloc(lfs2->cfg->lookahead_size); - if (!lfs2->free.buffer) { + lfs2->lookahead.buffer = lfs2_malloc(lfs2->cfg->lookahead_size); + if (!lfs2->lookahead.buffer) { err = LFS2_ERR_NOMEM; goto cleanup; } @@ -4215,6 +4328,27 @@ static int lfs2_init(lfs2_t *lfs2, const struct lfs2_config *cfg) { LFS2_ASSERT(lfs2->cfg->metadata_max <= lfs2->cfg->block_size); + LFS2_ASSERT(lfs2->cfg->inline_max == (lfs2_size_t)-1 + || lfs2->cfg->inline_max <= lfs2->cfg->cache_size); + LFS2_ASSERT(lfs2->cfg->inline_max == (lfs2_size_t)-1 + || lfs2->cfg->inline_max <= lfs2->attr_max); + LFS2_ASSERT(lfs2->cfg->inline_max == (lfs2_size_t)-1 + || lfs2->cfg->inline_max <= ((lfs2->cfg->metadata_max) + ? lfs2->cfg->metadata_max + : lfs2->cfg->block_size)/8); + lfs2->inline_max = lfs2->cfg->inline_max; + if (lfs2->inline_max == (lfs2_size_t)-1) { + lfs2->inline_max = 0; + } else if (lfs2->inline_max == 0) { + lfs2->inline_max = lfs2_min( + lfs2->cfg->cache_size, + lfs2_min( + lfs2->attr_max, + ((lfs2->cfg->metadata_max) + ? lfs2->cfg->metadata_max + : lfs2->cfg->block_size)/8)); + } + // setup default state lfs2->root[0] = LFS2_BLOCK_NULL; lfs2->root[1] = LFS2_BLOCK_NULL; @@ -4245,7 +4379,7 @@ static int lfs2_deinit(lfs2_t *lfs2) { } if (!lfs2->cfg->lookahead_buffer) { - lfs2_free(lfs2->free.buffer); + lfs2_free(lfs2->lookahead.buffer); } return 0; @@ -4254,7 +4388,7 @@ static int lfs2_deinit(lfs2_t *lfs2) { #ifndef LFS2_READONLY -static int lfs2_rawformat(lfs2_t *lfs2, const struct lfs2_config *cfg) { +static int lfs2_format_(lfs2_t *lfs2, const struct lfs2_config *cfg) { int err = 0; { err = lfs2_init(lfs2, cfg); @@ -4265,12 +4399,12 @@ static int lfs2_rawformat(lfs2_t *lfs2, const struct lfs2_config *cfg) { LFS2_ASSERT(cfg->block_count != 0); // create free lookahead - memset(lfs2->free.buffer, 0, lfs2->cfg->lookahead_size); - lfs2->free.off = 0; - lfs2->free.size = lfs2_min(8*lfs2->cfg->lookahead_size, + memset(lfs2->lookahead.buffer, 0, lfs2->cfg->lookahead_size); + lfs2->lookahead.start = 0; + lfs2->lookahead.size = lfs2_min(8*lfs2->cfg->lookahead_size, lfs2->block_count); - lfs2->free.i = 0; - lfs2_alloc_ack(lfs2); + lfs2->lookahead.next = 0; + lfs2_alloc_ckpoint(lfs2); // create root dir lfs2_mdir_t root; @@ -4321,7 +4455,31 @@ static int lfs2_rawformat(lfs2_t *lfs2, const struct lfs2_config *cfg) { } #endif -static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { +struct lfs2_tortoise_t { + lfs2_block_t pair[2]; + lfs2_size_t i; + lfs2_size_t period; +}; + +static int lfs2_tortoise_detectcycles( + const lfs2_mdir_t *dir, struct lfs2_tortoise_t *tortoise) { + // detect cycles with Brent's algorithm + if (lfs2_pair_issync(dir->tail, tortoise->pair)) { + LFS2_WARN("Cycle detected in tail list"); + return LFS2_ERR_CORRUPT; + } + if (tortoise->i == tortoise->period) { + tortoise->pair[0] = dir->tail[0]; + tortoise->pair[1] = dir->tail[1]; + tortoise->i = 0; + tortoise->period *= 2; + } + tortoise->i += 1; + + return LFS2_ERR_OK; +} + +static int lfs2_mount_(lfs2_t *lfs2, const struct lfs2_config *cfg) { int err = lfs2_init(lfs2, cfg); if (err) { return err; @@ -4329,23 +4487,16 @@ static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { // scan directory blocks for superblock and any global updates lfs2_mdir_t dir = {.tail = {0, 1}}; - lfs2_block_t tortoise[2] = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}; - lfs2_size_t tortoise_i = 1; - lfs2_size_t tortoise_period = 1; + struct lfs2_tortoise_t tortoise = { + .pair = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}, + .i = 1, + .period = 1, + }; while (!lfs2_pair_isnull(dir.tail)) { - // detect cycles with Brent's algorithm - if (lfs2_pair_issync(dir.tail, tortoise)) { - LFS2_WARN("Cycle detected in tail list"); - err = LFS2_ERR_CORRUPT; + err = lfs2_tortoise_detectcycles(&dir, &tortoise); + if (err < 0) { goto cleanup; } - if (tortoise_i == tortoise_period) { - tortoise[0] = dir.tail[0]; - tortoise[1] = dir.tail[1]; - tortoise_i = 0; - tortoise_period *= 2; - } - tortoise_i += 1; // fetch next block in tail list lfs2_stag_t tag = lfs2_dir_fetchmatch(lfs2, &dir, dir.tail, @@ -4394,6 +4545,7 @@ static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { // found older minor version? set an in-device only bit in the // gstate so we know we need to rewrite the superblock before // the first write + bool needssuperblock = false; if (minor_version < lfs2_fs_disk_version_minor(lfs2)) { LFS2_DEBUG("Found older minor version " "v%"PRIu16".%"PRIu16" < v%"PRIu16".%"PRIu16, @@ -4401,10 +4553,11 @@ static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { minor_version, lfs2_fs_disk_version_major(lfs2), lfs2_fs_disk_version_minor(lfs2)); - // note this bit is reserved on disk, so fetching more gstate - // will not interfere here - lfs2_fs_prepsuperblock(lfs2, true); + needssuperblock = true; } + // note this bit is reserved on disk, so fetching more gstate + // will not interfere here + lfs2_fs_prepsuperblock(lfs2, needssuperblock); // check superblock configuration if (superblock.name_max) { @@ -4438,6 +4591,9 @@ static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { } lfs2->attr_max = superblock.attr_max; + + // we also need to update inline_max in case attr_max changed + lfs2->inline_max = lfs2_min(lfs2->inline_max, lfs2->attr_max); } // this is where we get the block_count from disk if block_count=0 @@ -4478,23 +4634,23 @@ static int lfs2_rawmount(lfs2_t *lfs2, const struct lfs2_config *cfg) { // setup free lookahead, to distribute allocations uniformly across // boots, we start the allocator at a random location - lfs2->free.off = lfs2->seed % lfs2->block_count; + lfs2->lookahead.start = lfs2->seed % lfs2->block_count; lfs2_alloc_drop(lfs2); return 0; cleanup: - lfs2_rawunmount(lfs2); + lfs2_unmount_(lfs2); return err; } -static int lfs2_rawunmount(lfs2_t *lfs2) { +static int lfs2_unmount_(lfs2_t *lfs2) { return lfs2_deinit(lfs2); } /// Filesystem filesystem operations /// -static int lfs2_fs_rawstat(lfs2_t *lfs2, struct lfs2_fsinfo *fsinfo) { +static int lfs2_fs_stat_(lfs2_t *lfs2, struct lfs2_fsinfo *fsinfo) { // if the superblock is up-to-date, we must be on the most recent // minor version of littlefs if (!lfs2_gstate_needssuperblock(&lfs2->gstate)) { @@ -4534,7 +4690,7 @@ static int lfs2_fs_rawstat(lfs2_t *lfs2, struct lfs2_fsinfo *fsinfo) { return 0; } -int lfs2_fs_rawtraverse(lfs2_t *lfs2, +int lfs2_fs_traverse_(lfs2_t *lfs2, int (*cb)(void *data, lfs2_block_t block), void *data, bool includeorphans) { // iterate over metadata pairs @@ -4553,22 +4709,17 @@ int lfs2_fs_rawtraverse(lfs2_t *lfs2, } #endif - lfs2_block_t tortoise[2] = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}; - lfs2_size_t tortoise_i = 1; - lfs2_size_t tortoise_period = 1; + struct lfs2_tortoise_t tortoise = { + .pair = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}, + .i = 1, + .period = 1, + }; + int err = LFS2_ERR_OK; while (!lfs2_pair_isnull(dir.tail)) { - // detect cycles with Brent's algorithm - if (lfs2_pair_issync(dir.tail, tortoise)) { - LFS2_WARN("Cycle detected in tail list"); + err = lfs2_tortoise_detectcycles(&dir, &tortoise); + if (err < 0) { return LFS2_ERR_CORRUPT; } - if (tortoise_i == tortoise_period) { - tortoise[0] = dir.tail[0]; - tortoise[1] = dir.tail[1]; - tortoise_i = 0; - tortoise_period *= 2; - } - tortoise_i += 1; for (int i = 0; i < 2; i++) { int err = cb(data, dir.tail[i]); @@ -4647,22 +4798,17 @@ static int lfs2_fs_pred(lfs2_t *lfs2, // iterate over all directory directory entries pdir->tail[0] = 0; pdir->tail[1] = 1; - lfs2_block_t tortoise[2] = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}; - lfs2_size_t tortoise_i = 1; - lfs2_size_t tortoise_period = 1; + struct lfs2_tortoise_t tortoise = { + .pair = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}, + .i = 1, + .period = 1, + }; + int err = LFS2_ERR_OK; while (!lfs2_pair_isnull(pdir->tail)) { - // detect cycles with Brent's algorithm - if (lfs2_pair_issync(pdir->tail, tortoise)) { - LFS2_WARN("Cycle detected in tail list"); + err = lfs2_tortoise_detectcycles(pdir, &tortoise); + if (err < 0) { return LFS2_ERR_CORRUPT; } - if (tortoise_i == tortoise_period) { - tortoise[0] = pdir->tail[0]; - tortoise[1] = pdir->tail[1]; - tortoise_i = 0; - tortoise_period *= 2; - } - tortoise_i += 1; if (lfs2_pair_cmp(pdir->tail, pair) == 0) { return 0; @@ -4712,22 +4858,17 @@ static lfs2_stag_t lfs2_fs_parent(lfs2_t *lfs2, const lfs2_block_t pair[2], // use fetchmatch with callback to find pairs parent->tail[0] = 0; parent->tail[1] = 1; - lfs2_block_t tortoise[2] = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}; - lfs2_size_t tortoise_i = 1; - lfs2_size_t tortoise_period = 1; + struct lfs2_tortoise_t tortoise = { + .pair = {LFS2_BLOCK_NULL, LFS2_BLOCK_NULL}, + .i = 1, + .period = 1, + }; + int err = LFS2_ERR_OK; while (!lfs2_pair_isnull(parent->tail)) { - // detect cycles with Brent's algorithm - if (lfs2_pair_issync(parent->tail, tortoise)) { - LFS2_WARN("Cycle detected in tail list"); - return LFS2_ERR_CORRUPT; - } - if (tortoise_i == tortoise_period) { - tortoise[0] = parent->tail[0]; - tortoise[1] = parent->tail[1]; - tortoise_i = 0; - tortoise_period *= 2; + err = lfs2_tortoise_detectcycles(parent, &tortoise); + if (err < 0) { + return err; } - tortoise_i += 1; lfs2_stag_t tag = lfs2_dir_fetchmatch(lfs2, parent, parent->tail, LFS2_MKTAG(0x7ff, 0, 0x3ff), @@ -4999,7 +5140,7 @@ static int lfs2_fs_forceconsistency(lfs2_t *lfs2) { #endif #ifndef LFS2_READONLY -static int lfs2_fs_rawmkconsistent(lfs2_t *lfs2) { +static int lfs2_fs_mkconsistent_(lfs2_t *lfs2) { // lfs2_fs_forceconsistency does most of the work here int err = lfs2_fs_forceconsistency(lfs2); if (err) { @@ -5035,9 +5176,9 @@ static int lfs2_fs_size_count(void *p, lfs2_block_t block) { return 0; } -static lfs2_ssize_t lfs2_fs_rawsize(lfs2_t *lfs2) { +static lfs2_ssize_t lfs2_fs_size_(lfs2_t *lfs2) { lfs2_size_t size = 0; - int err = lfs2_fs_rawtraverse(lfs2, lfs2_fs_size_count, &size, false); + int err = lfs2_fs_traverse_(lfs2, lfs2_fs_size_count, &size, false); if (err) { return err; } @@ -5045,41 +5186,118 @@ static lfs2_ssize_t lfs2_fs_rawsize(lfs2_t *lfs2) { return size; } +// explicit garbage collection #ifndef LFS2_READONLY -static int lfs2_fs_rawgrow(lfs2_t *lfs2, lfs2_size_t block_count) { - // shrinking is not supported - LFS2_ASSERT(block_count >= lfs2->block_count); +static int lfs2_fs_gc_(lfs2_t *lfs2) { + // force consistency, even if we're not necessarily going to write, + // because this function is supposed to take care of janitorial work + // isn't it? + int err = lfs2_fs_forceconsistency(lfs2); + if (err) { + return err; + } - if (block_count > lfs2->block_count) { - lfs2->block_count = block_count; + // try to compact metadata pairs, note we can't really accomplish + // anything if compact_thresh doesn't at least leave a prog_size + // available + if (lfs2->cfg->compact_thresh + < lfs2->cfg->block_size - lfs2->cfg->prog_size) { + // iterate over all mdirs + lfs2_mdir_t mdir = {.tail = {0, 1}}; + while (!lfs2_pair_isnull(mdir.tail)) { + err = lfs2_dir_fetch(lfs2, &mdir, mdir.tail); + if (err) { + return err; + } - // fetch the root - lfs2_mdir_t root; - int err = lfs2_dir_fetch(lfs2, &root, lfs2->root); + // not erased? exceeds our compaction threshold? + if (!mdir.erased || ((lfs2->cfg->compact_thresh == 0) + ? mdir.off > lfs2->cfg->block_size - lfs2->cfg->block_size/8 + : mdir.off > lfs2->cfg->compact_thresh)) { + // the easiest way to trigger a compaction is to mark + // the mdir as unerased and add an empty commit + mdir.erased = false; + err = lfs2_dir_commit(lfs2, &mdir, NULL, 0); + if (err) { + return err; + } + } + } + } + + // try to populate the lookahead buffer, unless it's already full + if (lfs2->lookahead.size < lfs2_min( + 8 * lfs2->cfg->lookahead_size, + lfs2->block_count)) { + err = lfs2_alloc_scan(lfs2); if (err) { return err; } + } - // update the superblock - lfs2_superblock_t superblock; - lfs2_stag_t tag = lfs2_dir_get(lfs2, &root, LFS2_MKTAG(0x7ff, 0x3ff, 0), - LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), - &superblock); - if (tag < 0) { - return tag; - } - lfs2_superblock_fromle32(&superblock); + return 0; +} +#endif - superblock.block_count = lfs2->block_count; +#ifndef LFS2_READONLY +#ifdef LFS2_SHRINKNONRELOCATING +static int lfs2_shrink_checkblock(void *data, lfs2_block_t block) { + lfs2_size_t threshold = *((lfs2_size_t*)data); + if (block >= threshold) { + return LFS2_ERR_NOTEMPTY; + } + return 0; +} +#endif - lfs2_superblock_tole32(&superblock); - err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS( - {tag, &superblock})); +static int lfs2_fs_grow_(lfs2_t *lfs2, lfs2_size_t block_count) { + int err; + + if (block_count == lfs2->block_count) { + return 0; + } + + +#ifndef LFS2_SHRINKNONRELOCATING + // shrinking is not supported + LFS2_ASSERT(block_count >= lfs2->block_count); +#endif +#ifdef LFS2_SHRINKNONRELOCATING + if (block_count < lfs2->block_count) { + err = lfs2_fs_traverse_(lfs2, lfs2_shrink_checkblock, &block_count, true); if (err) { return err; } } +#endif + + lfs2->block_count = block_count; + // fetch the root + lfs2_mdir_t root; + err = lfs2_dir_fetch(lfs2, &root, lfs2->root); + if (err) { + return err; + } + + // update the superblock + lfs2_superblock_t superblock; + lfs2_stag_t tag = lfs2_dir_get(lfs2, &root, LFS2_MKTAG(0x7ff, 0x3ff, 0), + LFS2_MKTAG(LFS2_TYPE_INLINESTRUCT, 0, sizeof(superblock)), + &superblock); + if (tag < 0) { + return tag; + } + lfs2_superblock_fromle32(&superblock); + + superblock.block_count = lfs2->block_count; + + lfs2_superblock_tole32(&superblock); + err = lfs2_dir_commit(lfs2, &root, LFS2_MKATTRS( + {tag, &superblock})); + if (err) { + return err; + } return 0; } #endif @@ -5451,10 +5669,10 @@ static int lfs21_mount(lfs2_t *lfs2, struct lfs21 *lfs21, lfs2->lfs21->root[1] = LFS2_BLOCK_NULL; // setup free lookahead - lfs2->free.off = 0; - lfs2->free.size = 0; - lfs2->free.i = 0; - lfs2_alloc_ack(lfs2); + lfs2->lookahead.start = 0; + lfs2->lookahead.size = 0; + lfs2->lookahead.next = 0; + lfs2_alloc_ckpoint(lfs2); // load superblock lfs21_dir_t dir; @@ -5505,7 +5723,7 @@ static int lfs21_unmount(lfs2_t *lfs2) { } /// v1 migration /// -static int lfs2_rawmigrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { +static int lfs2_migrate_(lfs2_t *lfs2, const struct lfs2_config *cfg) { struct lfs21 lfs21; // Indeterminate filesystem size not allowed for migration. @@ -5759,7 +5977,7 @@ int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *cfg) { ".read=%p, .prog=%p, .erase=%p, .sync=%p, " ".read_size=%"PRIu32", .prog_size=%"PRIu32", " ".block_size=%"PRIu32", .block_count=%"PRIu32", " - ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".block_cycles=%"PRId32", .cache_size=%"PRIu32", " ".lookahead_size=%"PRIu32", .read_buffer=%p, " ".prog_buffer=%p, .lookahead_buffer=%p, " ".name_max=%"PRIu32", .file_max=%"PRIu32", " @@ -5772,7 +5990,7 @@ int lfs2_format(lfs2_t *lfs2, const struct lfs2_config *cfg) { cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, cfg->name_max, cfg->file_max, cfg->attr_max); - err = lfs2_rawformat(lfs2, cfg); + err = lfs2_format_(lfs2, cfg); LFS2_TRACE("lfs2_format -> %d", err); LFS2_UNLOCK(cfg); @@ -5789,7 +6007,7 @@ int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *cfg) { ".read=%p, .prog=%p, .erase=%p, .sync=%p, " ".read_size=%"PRIu32", .prog_size=%"PRIu32", " ".block_size=%"PRIu32", .block_count=%"PRIu32", " - ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".block_cycles=%"PRId32", .cache_size=%"PRIu32", " ".lookahead_size=%"PRIu32", .read_buffer=%p, " ".prog_buffer=%p, .lookahead_buffer=%p, " ".name_max=%"PRIu32", .file_max=%"PRIu32", " @@ -5802,7 +6020,7 @@ int lfs2_mount(lfs2_t *lfs2, const struct lfs2_config *cfg) { cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, cfg->name_max, cfg->file_max, cfg->attr_max); - err = lfs2_rawmount(lfs2, cfg); + err = lfs2_mount_(lfs2, cfg); LFS2_TRACE("lfs2_mount -> %d", err); LFS2_UNLOCK(cfg); @@ -5816,7 +6034,7 @@ int lfs2_unmount(lfs2_t *lfs2) { } LFS2_TRACE("lfs2_unmount(%p)", (void*)lfs2); - err = lfs2_rawunmount(lfs2); + err = lfs2_unmount_(lfs2); LFS2_TRACE("lfs2_unmount -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5831,7 +6049,7 @@ int lfs2_remove(lfs2_t *lfs2, const char *path) { } LFS2_TRACE("lfs2_remove(%p, \"%s\")", (void*)lfs2, path); - err = lfs2_rawremove(lfs2, path); + err = lfs2_remove_(lfs2, path); LFS2_TRACE("lfs2_remove -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5847,7 +6065,7 @@ int lfs2_rename(lfs2_t *lfs2, const char *oldpath, const char *newpath) { } LFS2_TRACE("lfs2_rename(%p, \"%s\", \"%s\")", (void*)lfs2, oldpath, newpath); - err = lfs2_rawrename(lfs2, oldpath, newpath); + err = lfs2_rename_(lfs2, oldpath, newpath); LFS2_TRACE("lfs2_rename -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5862,7 +6080,7 @@ int lfs2_stat(lfs2_t *lfs2, const char *path, struct lfs2_info *info) { } LFS2_TRACE("lfs2_stat(%p, \"%s\", %p)", (void*)lfs2, path, (void*)info); - err = lfs2_rawstat(lfs2, path, info); + err = lfs2_stat_(lfs2, path, info); LFS2_TRACE("lfs2_stat -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5878,7 +6096,7 @@ lfs2_ssize_t lfs2_getattr(lfs2_t *lfs2, const char *path, LFS2_TRACE("lfs2_getattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", (void*)lfs2, path, type, buffer, size); - lfs2_ssize_t res = lfs2_rawgetattr(lfs2, path, type, buffer, size); + lfs2_ssize_t res = lfs2_getattr_(lfs2, path, type, buffer, size); LFS2_TRACE("lfs2_getattr -> %"PRId32, res); LFS2_UNLOCK(lfs2->cfg); @@ -5895,7 +6113,7 @@ int lfs2_setattr(lfs2_t *lfs2, const char *path, LFS2_TRACE("lfs2_setattr(%p, \"%s\", %"PRIu8", %p, %"PRIu32")", (void*)lfs2, path, type, buffer, size); - err = lfs2_rawsetattr(lfs2, path, type, buffer, size); + err = lfs2_setattr_(lfs2, path, type, buffer, size); LFS2_TRACE("lfs2_setattr -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5911,7 +6129,7 @@ int lfs2_removeattr(lfs2_t *lfs2, const char *path, uint8_t type) { } LFS2_TRACE("lfs2_removeattr(%p, \"%s\", %"PRIu8")", (void*)lfs2, path, type); - err = lfs2_rawremoveattr(lfs2, path, type); + err = lfs2_removeattr_(lfs2, path, type); LFS2_TRACE("lfs2_removeattr -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5926,10 +6144,10 @@ int lfs2_file_open(lfs2_t *lfs2, lfs2_file_t *file, const char *path, int flags) return err; } LFS2_TRACE("lfs2_file_open(%p, %p, \"%s\", %x)", - (void*)lfs2, (void*)file, path, flags); + (void*)lfs2, (void*)file, path, (unsigned)flags); LFS2_ASSERT(!lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - err = lfs2_file_rawopen(lfs2, file, path, flags); + err = lfs2_file_open_(lfs2, file, path, flags); LFS2_TRACE("lfs2_file_open -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5946,11 +6164,11 @@ int lfs2_file_opencfg(lfs2_t *lfs2, lfs2_file_t *file, } LFS2_TRACE("lfs2_file_opencfg(%p, %p, \"%s\", %x, %p {" ".buffer=%p, .attrs=%p, .attr_count=%"PRIu32"})", - (void*)lfs2, (void*)file, path, flags, + (void*)lfs2, (void*)file, path, (unsigned)flags, (void*)cfg, cfg->buffer, (void*)cfg->attrs, cfg->attr_count); LFS2_ASSERT(!lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - err = lfs2_file_rawopencfg(lfs2, file, path, flags, cfg); + err = lfs2_file_opencfg_(lfs2, file, path, flags, cfg); LFS2_TRACE("lfs2_file_opencfg -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5965,7 +6183,7 @@ int lfs2_file_close(lfs2_t *lfs2, lfs2_file_t *file) { LFS2_TRACE("lfs2_file_close(%p, %p)", (void*)lfs2, (void*)file); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - err = lfs2_file_rawclose(lfs2, file); + err = lfs2_file_close_(lfs2, file); LFS2_TRACE("lfs2_file_close -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5981,7 +6199,7 @@ int lfs2_file_sync(lfs2_t *lfs2, lfs2_file_t *file) { LFS2_TRACE("lfs2_file_sync(%p, %p)", (void*)lfs2, (void*)file); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - err = lfs2_file_rawsync(lfs2, file); + err = lfs2_file_sync_(lfs2, file); LFS2_TRACE("lfs2_file_sync -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -5999,7 +6217,7 @@ lfs2_ssize_t lfs2_file_read(lfs2_t *lfs2, lfs2_file_t *file, (void*)lfs2, (void*)file, buffer, size); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - lfs2_ssize_t res = lfs2_file_rawread(lfs2, file, buffer, size); + lfs2_ssize_t res = lfs2_file_read_(lfs2, file, buffer, size); LFS2_TRACE("lfs2_file_read -> %"PRId32, res); LFS2_UNLOCK(lfs2->cfg); @@ -6017,7 +6235,7 @@ lfs2_ssize_t lfs2_file_write(lfs2_t *lfs2, lfs2_file_t *file, (void*)lfs2, (void*)file, buffer, size); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - lfs2_ssize_t res = lfs2_file_rawwrite(lfs2, file, buffer, size); + lfs2_ssize_t res = lfs2_file_write_(lfs2, file, buffer, size); LFS2_TRACE("lfs2_file_write -> %"PRId32, res); LFS2_UNLOCK(lfs2->cfg); @@ -6035,7 +6253,7 @@ lfs2_soff_t lfs2_file_seek(lfs2_t *lfs2, lfs2_file_t *file, (void*)lfs2, (void*)file, off, whence); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - lfs2_soff_t res = lfs2_file_rawseek(lfs2, file, off, whence); + lfs2_soff_t res = lfs2_file_seek_(lfs2, file, off, whence); LFS2_TRACE("lfs2_file_seek -> %"PRId32, res); LFS2_UNLOCK(lfs2->cfg); @@ -6052,7 +6270,7 @@ int lfs2_file_truncate(lfs2_t *lfs2, lfs2_file_t *file, lfs2_off_t size) { (void*)lfs2, (void*)file, size); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - err = lfs2_file_rawtruncate(lfs2, file, size); + err = lfs2_file_truncate_(lfs2, file, size); LFS2_TRACE("lfs2_file_truncate -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6068,7 +6286,7 @@ lfs2_soff_t lfs2_file_tell(lfs2_t *lfs2, lfs2_file_t *file) { LFS2_TRACE("lfs2_file_tell(%p, %p)", (void*)lfs2, (void*)file); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - lfs2_soff_t res = lfs2_file_rawtell(lfs2, file); + lfs2_soff_t res = lfs2_file_tell_(lfs2, file); LFS2_TRACE("lfs2_file_tell -> %"PRId32, res); LFS2_UNLOCK(lfs2->cfg); @@ -6082,7 +6300,7 @@ int lfs2_file_rewind(lfs2_t *lfs2, lfs2_file_t *file) { } LFS2_TRACE("lfs2_file_rewind(%p, %p)", (void*)lfs2, (void*)file); - err = lfs2_file_rawrewind(lfs2, file); + err = lfs2_file_rewind_(lfs2, file); LFS2_TRACE("lfs2_file_rewind -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6097,9 +6315,9 @@ lfs2_soff_t lfs2_file_size(lfs2_t *lfs2, lfs2_file_t *file) { LFS2_TRACE("lfs2_file_size(%p, %p)", (void*)lfs2, (void*)file); LFS2_ASSERT(lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)file)); - lfs2_soff_t res = lfs2_file_rawsize(lfs2, file); + lfs2_soff_t res = lfs2_file_size_(lfs2, file); - LFS2_TRACE("lfs2_file_size -> %"PRId32, res); + LFS2_TRACE("lfs2_file_size -> %"PRIu32, res); LFS2_UNLOCK(lfs2->cfg); return res; } @@ -6112,7 +6330,7 @@ int lfs2_mkdir(lfs2_t *lfs2, const char *path) { } LFS2_TRACE("lfs2_mkdir(%p, \"%s\")", (void*)lfs2, path); - err = lfs2_rawmkdir(lfs2, path); + err = lfs2_mkdir_(lfs2, path); LFS2_TRACE("lfs2_mkdir -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6128,7 +6346,7 @@ int lfs2_dir_open(lfs2_t *lfs2, lfs2_dir_t *dir, const char *path) { LFS2_TRACE("lfs2_dir_open(%p, %p, \"%s\")", (void*)lfs2, (void*)dir, path); LFS2_ASSERT(!lfs2_mlist_isopen(lfs2->mlist, (struct lfs2_mlist*)dir)); - err = lfs2_dir_rawopen(lfs2, dir, path); + err = lfs2_dir_open_(lfs2, dir, path); LFS2_TRACE("lfs2_dir_open -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6142,7 +6360,7 @@ int lfs2_dir_close(lfs2_t *lfs2, lfs2_dir_t *dir) { } LFS2_TRACE("lfs2_dir_close(%p, %p)", (void*)lfs2, (void*)dir); - err = lfs2_dir_rawclose(lfs2, dir); + err = lfs2_dir_close_(lfs2, dir); LFS2_TRACE("lfs2_dir_close -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6157,7 +6375,7 @@ int lfs2_dir_read(lfs2_t *lfs2, lfs2_dir_t *dir, struct lfs2_info *info) { LFS2_TRACE("lfs2_dir_read(%p, %p, %p)", (void*)lfs2, (void*)dir, (void*)info); - err = lfs2_dir_rawread(lfs2, dir, info); + err = lfs2_dir_read_(lfs2, dir, info); LFS2_TRACE("lfs2_dir_read -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6172,7 +6390,7 @@ int lfs2_dir_seek(lfs2_t *lfs2, lfs2_dir_t *dir, lfs2_off_t off) { LFS2_TRACE("lfs2_dir_seek(%p, %p, %"PRIu32")", (void*)lfs2, (void*)dir, off); - err = lfs2_dir_rawseek(lfs2, dir, off); + err = lfs2_dir_seek_(lfs2, dir, off); LFS2_TRACE("lfs2_dir_seek -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6186,7 +6404,7 @@ lfs2_soff_t lfs2_dir_tell(lfs2_t *lfs2, lfs2_dir_t *dir) { } LFS2_TRACE("lfs2_dir_tell(%p, %p)", (void*)lfs2, (void*)dir); - lfs2_soff_t res = lfs2_dir_rawtell(lfs2, dir); + lfs2_soff_t res = lfs2_dir_tell_(lfs2, dir); LFS2_TRACE("lfs2_dir_tell -> %"PRId32, res); LFS2_UNLOCK(lfs2->cfg); @@ -6200,7 +6418,7 @@ int lfs2_dir_rewind(lfs2_t *lfs2, lfs2_dir_t *dir) { } LFS2_TRACE("lfs2_dir_rewind(%p, %p)", (void*)lfs2, (void*)dir); - err = lfs2_dir_rawrewind(lfs2, dir); + err = lfs2_dir_rewind_(lfs2, dir); LFS2_TRACE("lfs2_dir_rewind -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6214,7 +6432,7 @@ int lfs2_fs_stat(lfs2_t *lfs2, struct lfs2_fsinfo *fsinfo) { } LFS2_TRACE("lfs2_fs_stat(%p, %p)", (void*)lfs2, (void*)fsinfo); - err = lfs2_fs_rawstat(lfs2, fsinfo); + err = lfs2_fs_stat_(lfs2, fsinfo); LFS2_TRACE("lfs2_fs_stat -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6228,7 +6446,7 @@ lfs2_ssize_t lfs2_fs_size(lfs2_t *lfs2) { } LFS2_TRACE("lfs2_fs_size(%p)", (void*)lfs2); - lfs2_ssize_t res = lfs2_fs_rawsize(lfs2); + lfs2_ssize_t res = lfs2_fs_size_(lfs2); LFS2_TRACE("lfs2_fs_size -> %"PRId32, res); LFS2_UNLOCK(lfs2->cfg); @@ -6243,7 +6461,7 @@ int lfs2_fs_traverse(lfs2_t *lfs2, int (*cb)(void *, lfs2_block_t), void *data) LFS2_TRACE("lfs2_fs_traverse(%p, %p, %p)", (void*)lfs2, (void*)(uintptr_t)cb, data); - err = lfs2_fs_rawtraverse(lfs2, cb, data, true); + err = lfs2_fs_traverse_(lfs2, cb, data, true); LFS2_TRACE("lfs2_fs_traverse -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6251,32 +6469,32 @@ int lfs2_fs_traverse(lfs2_t *lfs2, int (*cb)(void *, lfs2_block_t), void *data) } #ifndef LFS2_READONLY -int lfs2_fs_gc(lfs2_t *lfs2) { +int lfs2_fs_mkconsistent(lfs2_t *lfs2) { int err = LFS2_LOCK(lfs2->cfg); if (err) { return err; } - LFS2_TRACE("lfs2_fs_gc(%p)", (void*)lfs2); + LFS2_TRACE("lfs2_fs_mkconsistent(%p)", (void*)lfs2); - err = lfs2_fs_rawgc(lfs2); + err = lfs2_fs_mkconsistent_(lfs2); - LFS2_TRACE("lfs2_fs_gc -> %d", err); + LFS2_TRACE("lfs2_fs_mkconsistent -> %d", err); LFS2_UNLOCK(lfs2->cfg); return err; } #endif #ifndef LFS2_READONLY -int lfs2_fs_mkconsistent(lfs2_t *lfs2) { +int lfs2_fs_gc(lfs2_t *lfs2) { int err = LFS2_LOCK(lfs2->cfg); if (err) { return err; } - LFS2_TRACE("lfs2_fs_mkconsistent(%p)", (void*)lfs2); + LFS2_TRACE("lfs2_fs_gc(%p)", (void*)lfs2); - err = lfs2_fs_rawmkconsistent(lfs2); + err = lfs2_fs_gc_(lfs2); - LFS2_TRACE("lfs2_fs_mkconsistent -> %d", err); + LFS2_TRACE("lfs2_fs_gc -> %d", err); LFS2_UNLOCK(lfs2->cfg); return err; } @@ -6290,7 +6508,7 @@ int lfs2_fs_grow(lfs2_t *lfs2, lfs2_size_t block_count) { } LFS2_TRACE("lfs2_fs_grow(%p, %"PRIu32")", (void*)lfs2, block_count); - err = lfs2_fs_rawgrow(lfs2, block_count); + err = lfs2_fs_grow_(lfs2, block_count); LFS2_TRACE("lfs2_fs_grow -> %d", err); LFS2_UNLOCK(lfs2->cfg); @@ -6308,7 +6526,7 @@ int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { ".read=%p, .prog=%p, .erase=%p, .sync=%p, " ".read_size=%"PRIu32", .prog_size=%"PRIu32", " ".block_size=%"PRIu32", .block_count=%"PRIu32", " - ".block_cycles=%"PRIu32", .cache_size=%"PRIu32", " + ".block_cycles=%"PRId32", .cache_size=%"PRIu32", " ".lookahead_size=%"PRIu32", .read_buffer=%p, " ".prog_buffer=%p, .lookahead_buffer=%p, " ".name_max=%"PRIu32", .file_max=%"PRIu32", " @@ -6321,7 +6539,7 @@ int lfs2_migrate(lfs2_t *lfs2, const struct lfs2_config *cfg) { cfg->read_buffer, cfg->prog_buffer, cfg->lookahead_buffer, cfg->name_max, cfg->file_max, cfg->attr_max); - err = lfs2_rawmigrate(lfs2, cfg); + err = lfs2_migrate_(lfs2, cfg); LFS2_TRACE("lfs2_migrate -> %d", err); LFS2_UNLOCK(cfg); diff --git a/lib/littlefs/lfs2.h b/lib/littlefs/lfs2.h index 559ccebac92..aee0619e932 100644 --- a/lib/littlefs/lfs2.h +++ b/lib/littlefs/lfs2.h @@ -21,7 +21,7 @@ extern "C" // Software library version // Major (top-nibble), incremented on backwards incompatible changes // Minor (bottom-nibble), incremented on feature additions -#define LFS2_VERSION 0x00020008 +#define LFS2_VERSION 0x0002000b #define LFS2_VERSION_MAJOR (0xffff & (LFS2_VERSION >> 16)) #define LFS2_VERSION_MINOR (0xffff & (LFS2_VERSION >> 0)) @@ -52,16 +52,15 @@ typedef uint32_t lfs2_block_t; #endif // Maximum size of a file in bytes, may be redefined to limit to support other -// drivers. Limited on disk to <= 4294967296. However, above 2147483647 the -// functions lfs2_file_seek, lfs2_file_size, and lfs2_file_tell will return -// incorrect values due to using signed integers. Stored in superblock and -// must be respected by other littlefs drivers. +// drivers. Limited on disk to <= 2147483647. Stored in superblock and must be +// respected by other littlefs drivers. #ifndef LFS2_FILE_MAX #define LFS2_FILE_MAX 2147483647 #endif // Maximum size of custom attributes in bytes, may be redefined, but there is -// no real benefit to using a smaller LFS2_ATTR_MAX. Limited to <= 1022. +// no real benefit to using a smaller LFS2_ATTR_MAX. Limited to <= 1022. Stored +// in superblock and must be respected by other littlefs drivers. #ifndef LFS2_ATTR_MAX #define LFS2_ATTR_MAX 1022 #endif @@ -205,7 +204,8 @@ struct lfs2_config { // program sizes. lfs2_size_t block_size; - // Number of erasable blocks on the device. + // Number of erasable blocks on the device. Defaults to block_count stored + // on disk when zero. lfs2_size_t block_count; // Number of erase cycles before littlefs evicts metadata logs and moves @@ -226,9 +226,20 @@ struct lfs2_config { // Size of the lookahead buffer in bytes. A larger lookahead buffer // increases the number of blocks found during an allocation pass. The // lookahead buffer is stored as a compact bitmap, so each byte of RAM - // can track 8 blocks. Must be a multiple of 8. + // can track 8 blocks. lfs2_size_t lookahead_size; + // Threshold for metadata compaction during lfs2_fs_gc in bytes. Metadata + // pairs that exceed this threshold will be compacted during lfs2_fs_gc. + // Defaults to ~88% block_size when zero, though the default may change + // in the future. + // + // Note this only affects lfs2_fs_gc. Normal compactions still only occur + // when full. + // + // Set to -1 to disable metadata compaction during lfs2_fs_gc. + lfs2_size_t compact_thresh; + // Optional statically allocated read buffer. Must be cache_size. // By default lfs2_malloc is used to allocate this buffer. void *read_buffer; @@ -237,25 +248,24 @@ struct lfs2_config { // By default lfs2_malloc is used to allocate this buffer. void *prog_buffer; - // Optional statically allocated lookahead buffer. Must be lookahead_size - // and aligned to a 32-bit boundary. By default lfs2_malloc is used to - // allocate this buffer. + // Optional statically allocated lookahead buffer. Must be lookahead_size. + // By default lfs2_malloc is used to allocate this buffer. void *lookahead_buffer; // Optional upper limit on length of file names in bytes. No downside for // larger names except the size of the info struct which is controlled by - // the LFS2_NAME_MAX define. Defaults to LFS2_NAME_MAX when zero. Stored in - // superblock and must be respected by other littlefs drivers. + // the LFS2_NAME_MAX define. Defaults to LFS2_NAME_MAX or name_max stored on + // disk when zero. lfs2_size_t name_max; // Optional upper limit on files in bytes. No downside for larger files - // but must be <= LFS2_FILE_MAX. Defaults to LFS2_FILE_MAX when zero. Stored - // in superblock and must be respected by other littlefs drivers. + // but must be <= LFS2_FILE_MAX. Defaults to LFS2_FILE_MAX or file_max stored + // on disk when zero. lfs2_size_t file_max; // Optional upper limit on custom attributes in bytes. No downside for // larger attributes size but must be <= LFS2_ATTR_MAX. Defaults to - // LFS2_ATTR_MAX when zero. + // LFS2_ATTR_MAX or attr_max stored on disk when zero. lfs2_size_t attr_max; // Optional upper limit on total space given to metadata pairs in bytes. On @@ -264,6 +274,15 @@ struct lfs2_config { // Defaults to block_size when zero. lfs2_size_t metadata_max; + // Optional upper limit on inlined files in bytes. Inlined files live in + // metadata and decrease storage requirements, but may be limited to + // improve metadata-related performance. Must be <= cache_size, <= + // attr_max, and <= block_size/8. Defaults to the largest possible + // inline_max when zero. + // + // Set to -1 to disable inlined files. + lfs2_size_t inline_max; + #ifdef LFS2_MULTIVERSION // On-disk version to use when writing in the form of 16-bit major version // + 16-bit minor version. This limiting metadata to what is supported by @@ -430,19 +449,20 @@ typedef struct lfs2 { lfs2_gstate_t gdisk; lfs2_gstate_t gdelta; - struct lfs2_free { - lfs2_block_t off; + struct lfs2_lookahead { + lfs2_block_t start; lfs2_block_t size; - lfs2_block_t i; - lfs2_block_t ack; - uint32_t *buffer; - } free; + lfs2_block_t next; + lfs2_block_t ckpoint; + uint8_t *buffer; + } lookahead; const struct lfs2_config *cfg; lfs2_size_t block_count; lfs2_size_t name_max; lfs2_size_t file_max; lfs2_size_t attr_max; + lfs2_size_t inline_max; #ifdef LFS2_MIGRATE struct lfs21 *lfs21; @@ -712,18 +732,6 @@ lfs2_ssize_t lfs2_fs_size(lfs2_t *lfs2); // Returns a negative error code on failure. int lfs2_fs_traverse(lfs2_t *lfs2, int (*cb)(void*, lfs2_block_t), void *data); -// Attempt to proactively find free blocks -// -// Calling this function is not required, but may allowing the offloading of -// the expensive block allocation scan to a less time-critical code path. -// -// Note: littlefs currently does not persist any found free blocks to disk. -// This may change in the future. -// -// Returns a negative error code on failure. Finding no free blocks is -// not an error. -int lfs2_fs_gc(lfs2_t *lfs2); - #ifndef LFS2_READONLY // Attempt to make the filesystem consistent and ready for writing // @@ -736,11 +744,33 @@ int lfs2_fs_gc(lfs2_t *lfs2); int lfs2_fs_mkconsistent(lfs2_t *lfs2); #endif +#ifndef LFS2_READONLY +// Attempt any janitorial work +// +// This currently: +// 1. Calls mkconsistent if not already consistent +// 2. Compacts metadata > compact_thresh +// 3. Populates the block allocator +// +// Though additional janitorial work may be added in the future. +// +// Calling this function is not required, but may allow the offloading of +// expensive janitorial work to a less time-critical code path. +// +// Returns a negative error code on failure. Accomplishing nothing is not +// an error. +int lfs2_fs_gc(lfs2_t *lfs2); +#endif + #ifndef LFS2_READONLY // Grows the filesystem to a new size, updating the superblock with the new // block count. // -// Note: This is irreversible. +// If LFS2_SHRINKNONRELOCATING is defined, this function will also accept +// block_counts smaller than the current configuration, after checking +// that none of the blocks that are being removed are in use. +// Note that littlefs's pseudorandom block allocation means that +// this is very unlikely to work in the general case. // // Returns a negative error code on failure. int lfs2_fs_grow(lfs2_t *lfs2, lfs2_size_t block_count); diff --git a/lib/littlefs/lfs2_util.c b/lib/littlefs/lfs2_util.c index c9850e78869..4fe7e5340ce 100644 --- a/lib/littlefs/lfs2_util.c +++ b/lib/littlefs/lfs2_util.c @@ -11,6 +11,8 @@ #ifndef LFS2_CONFIG +// If user provides their own CRC impl we don't need this +#ifndef LFS2_CRC // Software CRC implementation with small lookup table uint32_t lfs2_crc(uint32_t crc, const void *buffer, size_t size) { static const uint32_t rtable[16] = { @@ -29,6 +31,7 @@ uint32_t lfs2_crc(uint32_t crc, const void *buffer, size_t size) { return crc; } +#endif #endif diff --git a/lib/littlefs/lfs2_util.h b/lib/littlefs/lfs2_util.h index dd2cbcc106d..12c82a630b0 100644 --- a/lib/littlefs/lfs2_util.h +++ b/lib/littlefs/lfs2_util.h @@ -8,6 +8,9 @@ #ifndef LFS2_UTIL_H #define LFS2_UTIL_H +#define LFS2_STRINGIZE(x) LFS2_STRINGIZE2(x) +#define LFS2_STRINGIZE2(x) #x + // Users can override lfs2_util.h with their own configuration by defining // LFS2_CONFIG as a header file to include (-DLFS2_CONFIG=lfs2_config.h). // @@ -15,11 +18,26 @@ // provided by the config file. To start, I would suggest copying lfs2_util.h // and modifying as needed. #ifdef LFS2_CONFIG -#define LFS2_STRINGIZE(x) LFS2_STRINGIZE2(x) -#define LFS2_STRINGIZE2(x) #x #include LFS2_STRINGIZE(LFS2_CONFIG) #else +// Alternatively, users can provide a header file which defines +// macros and other things consumed by littlefs. +// +// For example, provide my_defines.h, which contains +// something like: +// +// #include +// extern void *my_malloc(size_t sz); +// #define LFS2_MALLOC(sz) my_malloc(sz) +// +// And build littlefs with the header by defining LFS2_DEFINES. +// (-DLFS2_DEFINES=my_defines.h) + +#ifdef LFS2_DEFINES +#include LFS2_STRINGIZE(LFS2_DEFINES) +#endif + // System includes #include #include @@ -177,10 +195,10 @@ static inline uint32_t lfs2_fromle32(uint32_t a) { (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) return __builtin_bswap32(a); #else - return (((uint8_t*)&a)[0] << 0) | - (((uint8_t*)&a)[1] << 8) | - (((uint8_t*)&a)[2] << 16) | - (((uint8_t*)&a)[3] << 24); + return ((uint32_t)((uint8_t*)&a)[0] << 0) | + ((uint32_t)((uint8_t*)&a)[1] << 8) | + ((uint32_t)((uint8_t*)&a)[2] << 16) | + ((uint32_t)((uint8_t*)&a)[3] << 24); #endif } @@ -200,10 +218,10 @@ static inline uint32_t lfs2_frombe32(uint32_t a) { (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) return a; #else - return (((uint8_t*)&a)[0] << 24) | - (((uint8_t*)&a)[1] << 16) | - (((uint8_t*)&a)[2] << 8) | - (((uint8_t*)&a)[3] << 0); + return ((uint32_t)((uint8_t*)&a)[0] << 24) | + ((uint32_t)((uint8_t*)&a)[1] << 16) | + ((uint32_t)((uint8_t*)&a)[2] << 8) | + ((uint32_t)((uint8_t*)&a)[3] << 0); #endif } @@ -212,12 +230,22 @@ static inline uint32_t lfs2_tobe32(uint32_t a) { } // Calculate CRC-32 with polynomial = 0x04c11db7 +#ifdef LFS2_CRC +static inline uint32_t lfs2_crc(uint32_t crc, const void *buffer, size_t size) { + return LFS2_CRC(crc, buffer, size); +} +#else uint32_t lfs2_crc(uint32_t crc, const void *buffer, size_t size); +#endif // Allocate memory, only used if buffers are not provided to littlefs -// Note, memory must be 64-bit aligned +// +// littlefs current has no alignment requirements, as it only allocates +// byte-level buffers. static inline void *lfs2_malloc(size_t size) { -#ifndef LFS2_NO_MALLOC +#if defined(LFS2_MALLOC) + return LFS2_MALLOC(size); +#elif !defined(LFS2_NO_MALLOC) return malloc(size); #else (void)size; @@ -227,7 +255,9 @@ static inline void *lfs2_malloc(size_t size) { // Deallocate memory, only used if buffers are not provided to littlefs static inline void lfs2_free(void *p) { -#ifndef LFS2_NO_MALLOC +#if defined(LFS2_FREE) + LFS2_FREE(p); +#elif !defined(LFS2_NO_MALLOC) free(p); #else (void)p; diff --git a/lib/mbedtls b/lib/mbedtls index 981743de6fc..ece41aa84d7 160000 --- a/lib/mbedtls +++ b/lib/mbedtls @@ -1 +1 @@ -Subproject commit 981743de6fcdbe672e482b6fd724d31d0a0d2476 +Subproject commit ece41aa84d7879d7e55c59e955a5884b541f7f3b diff --git a/lib/mbedtls_config/crt_bundle.c b/lib/mbedtls_config/crt_bundle.c index b0994e22ab9..01bb497f655 100644 --- a/lib/mbedtls_config/crt_bundle.c +++ b/lib/mbedtls_config/crt_bundle.c @@ -41,8 +41,8 @@ static mbedtls_x509_crt s_dummy_crt; #define LOGD(tag, fmt, ...) do {} while (0) #endif -extern const uint8_t x509_crt_imported_bundle_bin_start[] asm ("_binary_x509_crt_bundle_start"); -extern const uint8_t x509_crt_imported_bundle_bin_end[] asm ("_binary_x509_crt_bundle_end"); +extern const uint8_t x509_crt_imported_bundle_bin_start[] __asm__ ("_binary_x509_crt_bundle_start"); +extern const uint8_t x509_crt_imported_bundle_bin_end[] __asm__ ("_binary_x509_crt_bundle_end"); typedef struct crt_bundle_t { @@ -56,10 +56,6 @@ static crt_bundle_t s_crt_bundle; static int crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_buf, size_t pub_key_len); -#if MBEDTLS_VERSION_MAJOR < 3 -#define MBEDTLS_PRIVATE(x) x -#endif - static int crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_buf, size_t pub_key_len) { int ret = 0; mbedtls_x509_crt parent; @@ -74,13 +70,6 @@ static int crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_b } - // Fast check to avoid expensive computations when not necessary - if (!mbedtls_pk_can_do(&parent.pk, child->MBEDTLS_PRIVATE(sig_pk))) { - LOGE(TAG, "Simple compare failed"); - ret = -1; - goto cleanup; - } - md_info = mbedtls_md_info_from_type(child->MBEDTLS_PRIVATE(sig_md)); if ((ret = mbedtls_md(md_info, child->tbs.p, child->tbs.len, hash)) != 0) { LOGE(TAG, "Internal mbedTLS error %X", ret); @@ -88,10 +77,9 @@ static int crt_check_signature(mbedtls_x509_crt *child, const uint8_t *pub_key_b } if ((ret = mbedtls_pk_verify_ext( - child->MBEDTLS_PRIVATE(sig_pk), child->MBEDTLS_PRIVATE(sig_opts), &parent.pk, + child->MBEDTLS_PRIVATE(sig_pk), &parent.pk, child->MBEDTLS_PRIVATE(sig_md), hash, mbedtls_md_get_size(md_info), child->MBEDTLS_PRIVATE(sig).p, child->MBEDTLS_PRIVATE(sig).len)) != 0) { - LOGE(TAG, "PK verify failed with error %X", ret); goto cleanup; } diff --git a/lib/mbedtls_config/hashlib_psa_port.c b/lib/mbedtls_config/hashlib_psa_port.c new file mode 100644 index 00000000000..88a3b96adba --- /dev/null +++ b/lib/mbedtls_config/hashlib_psa_port.c @@ -0,0 +1,32 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Platform glue for ports that build the PSA crypto core for hashlib but not for ssl. +// The ssl equivalent is mbedtls_port.c; the two are mutually exclusive, because +// CIRCUITPY_HASHLIB_MBEDTLS_ONLY means hashlib without ssl. + +#include + +#if CIRCUITPY_HASHLIB_MBEDTLS_ONLY + +#include "psa/crypto.h" + +#include "shared-bindings/os/__init__.h" + +// Required by MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. psa_crypto_init() initializes the RNG +// subsystem even in a build that only ever hashes, so this has to exist. +psa_status_t mbedtls_psa_external_get_random( + mbedtls_psa_external_random_context_t *context, + uint8_t *output, size_t output_size, size_t *output_length) { + (void)context; + if (!common_hal_os_urandom(output, output_size)) { + return PSA_ERROR_INSUFFICIENT_ENTROPY; + } + *output_length = output_size; + return PSA_SUCCESS; +} + +#endif diff --git a/lib/mbedtls_config/mbedtls_config.h b/lib/mbedtls_config/mbedtls_config.h index 3791924a13c..062ad11ff17 100644 --- a/lib/mbedtls_config/mbedtls_config.h +++ b/lib/mbedtls_config/mbedtls_config.h @@ -1,128 +1,102 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018-2019 Damien P. George - * - * 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. - */ -#ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H -#define MICROPY_INCLUDED_MBEDTLS_CONFIG_H - -// If you want to debug MBEDTLS uncomment the following and -// Pass 3 to mbedtls_debug_set_threshold in socket_new +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018-2019 Damien P. George +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// mbedtls TLS and X.509 configuration, selected with MBEDTLS_CONFIG_FILE. +// +// As of mbedtls 4.0 this file covers only TLS and X.509. Everything cryptographic -- +// algorithms, key types, the platform hooks and the RNG -- is configured in +// tf_psa_crypto_config.h next to this file, and selected with +// TF_PSA_CRYPTO_CONFIG_FILE. + +#pragma once + +// If you want to debug mbedtls, uncomment the following. SSLSocket.c raises the debug +// threshold to 4 when it is set. // #define MBEDTLS_DEBUG_C -// Set mbedtls configuration -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_DEPRECATED_REMOVED -#define MBEDTLS_ENTROPY_HARDWARE_ALT -#define MBEDTLS_AES_ROM_TABLES -#define MBEDTLS_CIPHER_MODE_CBC -#define MBEDTLS_ECP_DP_SECP192R1_ENABLED -#define MBEDTLS_ECP_DP_SECP224R1_ENABLED -#define MBEDTLS_ECP_DP_SECP256R1_ENABLED -#define MBEDTLS_ECP_DP_SECP384R1_ENABLED -#define MBEDTLS_ECP_DP_SECP521R1_ENABLED -#define MBEDTLS_ECP_DP_SECP192K1_ENABLED -#define MBEDTLS_ECP_DP_SECP224K1_ENABLED -#define MBEDTLS_ECP_DP_SECP256K1_ENABLED -#define MBEDTLS_ECP_DP_BP256R1_ENABLED -#define MBEDTLS_ECP_DP_BP384R1_ENABLED -#define MBEDTLS_ECP_DP_BP512R1_ENABLED -#define MBEDTLS_ECP_DP_CURVE25519_ENABLED -#define MBEDTLS_ECP_NIST_OPTIM -#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED -#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED -#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED -#define MBEDTLS_NO_PLATFORM_ENTROPY -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_SHA256_SMALLER -#define MBEDTLS_SSL_PROTO_TLS1 -#define MBEDTLS_SSL_PROTO_TLS1_1 +// Protocol versions + +// TLS 1.0 and 1.1 were removed in mbedtls 3.0, and were obsolete long before that. +// +// TLS 1.3 is available in 4.x but is turned off, to match espressif +// It also cost 25648 bytes on Pico W, which has only ~50 KB of firmware +// space left. Enabling it here would also require enabling +// MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED, and PSA_WANT_ALG_HKDF* in +// tf_psa_crypto_config.h for the 1.3 key schedule. #define MBEDTLS_SSL_PROTO_TLS1_2 + +// DTLS is deliberately off: common_hal_ssl_sslcontext_wrap_socket() rejects anything +// that is not SOCKETPOOL_SOCK_STREAM, so it could never be reached. + +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_TLS_C + +// Key exchanges. Without at least one of these there are no TLS 1.2 ciphersuites at +// all, the ClientHello offers nothing, and the server answers with a fatal +// handshake_failure alert. These two are what espressif enables +// (CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_{RSA,ECDSA}) and cover the public web. The PSK +// and ECJPAKE exchanges that 4.x also still offers are not reachable from the ssl +// module, and the static-RSA and DHE exchanges the mbedtls 2.28 config enabled are +// gone from 4.x upstream. +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +// Extensions + #define MBEDTLS_SSL_SERVER_NAME_INDICATION +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#define MBEDTLS_SSL_ENCRYPT_THEN_MAC +#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET + +// Buffers -// Use a smaller output buffer to reduce size of SSL context +// Accept a full-size record inbound, since we do not control what the peer sends, +// but use a smaller outbound buffer to reduce the SSL context size. #define MBEDTLS_SSL_MAX_CONTENT_LEN (16384) #define MBEDTLS_SSL_IN_CONTENT_LEN (MBEDTLS_SSL_MAX_CONTENT_LEN) #define MBEDTLS_SSL_OUT_CONTENT_LEN (4096) -// Enable mbedtls modules -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#define MBEDTLS_BASE64_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_ECDH_C -#define MBEDTLS_ECDSA_C -#define MBEDTLS_ECP_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_ERROR_C -#define MBEDTLS_GCM_C -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_OID_C -#define MBEDTLS_PKCS5_C -#define MBEDTLS_PEM_PARSE_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C -#define MBEDTLS_SSL_CLI_C -#define MBEDTLS_SSL_SRV_C -#define MBEDTLS_SSL_TLS_C -#define MBEDTLS_TLS_DEFAULT_ALLOW_SHA1_IN_KEY_EXCHANGE -#define MBEDTLS_X509_CRT_PARSE_C +// X.509 + #define MBEDTLS_X509_USE_C -#define MBEDTLS_HAVE_TIME -#define MBEDTLS_DHM_C // needed by DHE_PSK -#undef MBEDTLS_HAVE_TIME_DATE - -// Memory allocation hooks -#include -#include -void *m_tracked_calloc(size_t nmemb, size_t size); -void m_tracked_free(void *ptr); -#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc -#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free -#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf - -// Time hook -#include -time_t rp2_rtctime_seconds(time_t *timer); -#define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds - -#include "mbedtls/check_config.h" - -#endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_RSASSA_PSS_SUPPORT + +// MBEDTLS_HAVE_TIME_DATE is deliberately left off, so certificate notBefore/notAfter +// are not checked (see the BADCERT_EXPIRED/BADCERT_FUTURE tests in x509_crt.c, which +// are compiled out without it). CircuitPython does not know the wall clock time unless +// the program sets it explicitly, which often does not happen; with an unset clock, +// checking the dates would reject valid certificates rather than catch expired ones. +// espressif does not set CONFIG_MBEDTLS_HAVE_TIME_DATE either. +// +// Nothing else we enable consumes time -- no session tickets, no context +// serialization, no DTLS, no TLS 1.3 -- so MBEDTLS_HAVE_TIME is off as well, and +// mbedtls_port.c needs neither a wall clock nor mbedtls_ms_time(). + +// Error strings + +// SSLSocket.c keys off MBEDTLS_ERROR_C to decide whether to put a message on the +// OSError it raises. mbedtls's own error.c is not built; lib/mbedtls_errors supplies +// a smaller mbedtls_strerror() instead. +#define MBEDTLS_ERROR_C + +// Sanity checks +// +// mbedtls's own mbedtls_check_config.h only validates the prerequisites of options +// that are enabled, so it says nothing when a whole category is missing. This is where +// TF_PSA_CRYPTO_CONFIG_FILE replacing psa/crypto_config.h rather than overlaying it +// bites: every default we rely on has to be restated here, and forgetting one produces +// a build that compiles and links but cannot complete a handshake. +#if !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#error "No MBEDTLS_KEY_EXCHANGE_* enabled: ciphersuite_definitions[] would be empty, " \ + "so the ClientHello would offer nothing and every TLS 1.2 handshake would fail." +#endif diff --git a/lib/mbedtls_config/mbedtls_config_port.h b/lib/mbedtls_config/mbedtls_config_port.h deleted file mode 100644 index 1752d946529..00000000000 --- a/lib/mbedtls_config/mbedtls_config_port.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018-2019 Damien P. George - * - * 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. - */ -#ifndef MICROPY_INCLUDED_MBEDTLS_CONFIG_H -#define MICROPY_INCLUDED_MBEDTLS_CONFIG_H - -// If you want to debug MBEDTLS uncomment the following and -// Pass 3 to mbedtls_debug_set_threshold in socket_new -// #define MBEDTLS_DEBUG_C - -// Set mbedtls configuration -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_PLATFORM_MEMORY -#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -#define MBEDTLS_DEPRECATED_REMOVED -#define MBEDTLS_ENTROPY_HARDWARE_ALT - -// Enable mbedtls modules -#define MBEDTLS_MD_C -#define MBEDTLS_MD5_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA256_C -#define MBEDTLS_SHA512_C -#undef MBEDTLS_HAVE_TIME_DATE - -<<<<<<<< HEAD:lib/mbedtls_config/mbedtls_config_hashlib.h -// Memory allocation hooks -#include -#include -void *m_tracked_calloc(size_t nmemb, size_t size); -void m_tracked_free(void *ptr); -#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc -#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free -#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf -======== -// Time hook -#include -time_t rp2_rtctime_seconds(time_t *timer); -#define MBEDTLS_PLATFORM_TIME_MACRO rp2_rtctime_seconds -#define MBEDTLS_PLATFORM_MS_TIME_ALT mbedtls_ms_time ->>>>>>>> v1.23.0:lib/mbedtls_config/mbedtls_config_port.h - -#include "mbedtls/check_config.h" - -#endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/lib/mbedtls_config/mbedtls_port.c b/lib/mbedtls_config/mbedtls_port.c index 73929c85e81..cc29145e803 100644 --- a/lib/mbedtls_config/mbedtls_port.c +++ b/lib/mbedtls_config/mbedtls_port.c @@ -1,54 +1,29 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2019 Damien P. George - * - * 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. - */ -#include +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018-2019 Damien P. George +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries + +#include "py/mpconfig.h" #if CIRCUITPY_SSL_MBEDTLS -#include "mbedtls_config.h" -#include "mbedtls/entropy_poll.h" +#include "psa/crypto.h" -#include "hardware/rtc.h" -#include "shared/timeutils/timeutils.h" #include "shared-bindings/os/__init__.h" -#include "hardware/rtc.h" -#include "shared/timeutils/timeutils.h" - -extern uint8_t rosc_random_u8(size_t cycles); - -int mbedtls_hardware_poll(void *data, unsigned char *output, size_t len, size_t *olen) { - *olen = len; - common_hal_os_urandom(data, len); - return 0; -} - -time_t rp2_rtctime_seconds(time_t *timer) { - datetime_t t; - rtc_get_datetime(&t); - return timeutils_seconds_since_epoch(t.year, t.month, t.day, t.hour, t.min, t.sec); +// The RNG behind MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. mbedtls asks for randomness through +// this instead of seeding its own entropy accumulator and CTR-DRBG, so the port's TRNG +// is the only source. `context` is unused; mbedtls initializes it to 0 and we keep no +// state of our own. +psa_status_t mbedtls_psa_external_get_random( + mbedtls_psa_external_random_context_t *context, + uint8_t *output, size_t output_size, size_t *output_length) { + (void)context; + if (!common_hal_os_urandom(output, output_size)) { + return PSA_ERROR_INSUFFICIENT_ENTROPY; + } + *output_length = output_size; + return PSA_SUCCESS; } #endif diff --git a/lib/mbedtls_config/tf_psa_crypto_config.h b/lib/mbedtls_config/tf_psa_crypto_config.h new file mode 100644 index 00000000000..72e69ba5f63 --- /dev/null +++ b/lib/mbedtls_config/tf_psa_crypto_config.h @@ -0,0 +1,133 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018-2019 Damien P. George +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// TF-PSA-Crypto configuration, selected with TF_PSA_CRYPTO_CONFIG_FILE. +// +// mbedtls 4.0 split its configuration in two: MBEDTLS_CONFIG_FILE now covers only +// TLS and X.509 (see mbedtls_config.h next to this file), and everything +// cryptographic moved here. Algorithms and key types are requested with PSA_WANT_* +// rather than the old MBEDTLS__C module switches; the builtin implementations +// they need are derived from those by tf-psa-crypto's own config_adjust headers. + +#pragma once + +// Platform integration /////////////////////////////////////////////////////// + +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +#define MBEDTLS_DEPRECATED_REMOVED + +// Memory allocation hooks, so mbedtls allocations are tracked like the rest of the +// VM's. +#include +#include +void *m_tracked_calloc(size_t nmemb, size_t size); +void m_tracked_free(void *ptr); +#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc +#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf + +// Randomness ///////////////////////////////////////////////////////////////// + +// Take randomness straight from the port's TRNG rather than seeding mbedtls's own +// entropy accumulator and CTR-DRBG. mbedtls 4.x dropped MBEDTLS_ENTROPY_HARDWARE_ALT, +// which is how this was wired before, and going direct also keeps entropy.c and +// ctr_drbg.c out of the build. mbedtls_psa_external_get_random() is in +// mbedtls_port.c. +#define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + +// Size/speed tradeoffs /////////////////////////////////////////////////////// + +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_SHA256_SMALLER +#define MBEDTLS_ECP_NIST_OPTIM + +// Hashes ///////////////////////////////////////////////////////////////////// + +// SHA-1 is still needed to parse certificates that sign with it, and is what +// hashlib exposes as "sha1". +#define PSA_WANT_ALG_SHA_1 +#define PSA_WANT_ALG_SHA_224 +#define PSA_WANT_ALG_SHA_256 +#define PSA_WANT_ALG_SHA_384 +#define PSA_WANT_ALG_SHA_512 +#define PSA_WANT_ALG_HMAC +#define PSA_WANT_KEY_TYPE_HMAC + +// Key derivation ///////////////////////////////////////////////////////////// + +// The TLS 1.2 key schedule. HKDF is deliberately absent: it is the TLS 1.3 key +// schedule, and mbedtls_config.h enables TLS 1.2 only. +#define PSA_WANT_ALG_TLS12_PRF +#define PSA_WANT_ALG_TLS12_PSK_TO_MS +#define PSA_WANT_KEY_TYPE_DERIVE +#define PSA_WANT_KEY_TYPE_RAW_DATA + +// Bulk ciphers /////////////////////////////////////////////////////////////// + +#define PSA_WANT_KEY_TYPE_AES +#define PSA_WANT_ALG_GCM +#define PSA_WANT_ALG_CCM +#define PSA_WANT_ALG_CBC_NO_PADDING +#define PSA_WANT_ALG_CBC_PKCS7 +#define PSA_WANT_ALG_ECB_NO_PADDING + +// RP2 has no AES accelerator, so ChaCha20-Poly1305 is 40-70% faster than AES-GCM here, +// measured over HTTPS on Pico W and Pico 2 W. mbedtls offers it ahead of AES-GCM, and +// real-world CDNs do negotiate it. Costs about 6 kB. espressif leaves it off, since +// ESP32 has AES hardware. +#define PSA_WANT_KEY_TYPE_CHACHA20 +#define PSA_WANT_ALG_CHACHA20_POLY1305 + +// Public key ///////////////////////////////////////////////////////////////// + +#define PSA_WANT_ALG_RSA_PKCS1V15_CRYPT +#define PSA_WANT_ALG_RSA_PKCS1V15_SIGN +#define PSA_WANT_ALG_RSA_PSS +#define PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_BASIC +#define PSA_WANT_KEY_TYPE_RSA_KEY_PAIR_IMPORT + +#define PSA_WANT_ALG_ECDH +#define PSA_WANT_ALG_ECDSA +#define PSA_WANT_ALG_DETERMINISTIC_ECDSA +#define PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT +// An ECDHE handshake generates an ephemeral key pair, sends its public part, then +// runs the key agreement, so it needs GENERATE, EXPORT and DERIVE as well as the two +// above. Without them psa_generate_key() fails and the TLS 1.2 client reports +// MBEDTLS_ERR_SSL_HW_ACCEL_FAILED -- a legacy name that in 4.x just means a PSA call +// failed. See ssl_tls12_client.c. +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT +#define PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE + +// P-256 and P-384 cover essentially every public CA. Curve25519 is here for x25519 +// ECDHE, which servers commonly prefer (RFC 8422). Deliberately absent: +// - P-521: no public CA issues from it, and it cost 5792 bytes on Pico W. +// - Brainpool and secp256k1: unused on the public web. espressif enables secp256k1 +// only because ESP-IDF defaults it on. +// The 192- and 224-bit curves the mbedtls 2.28 config enabled are gone from 4.x +// upstream; there is no PSA_WANT_ECC_SECP_R1_192/_224 to select. +#define PSA_WANT_ECC_SECP_R1_256 +#define PSA_WANT_ECC_SECP_R1_384 +#define PSA_WANT_ECC_MONTGOMERY_255 + +// Key and certificate parsing //////////////////////////////////////////////// + +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_MD_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_PKCS5_C +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C diff --git a/lib/mbedtls_config/tf_psa_crypto_config_hashlib.h b/lib/mbedtls_config/tf_psa_crypto_config_hashlib.h new file mode 100644 index 00000000000..0dbf9b13542 --- /dev/null +++ b/lib/mbedtls_config/tf_psa_crypto_config_hashlib.h @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018-2019 Damien P. George +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// TF-PSA-Crypto configuration for ports that want hashlib but not ssl, selected with +// TF_PSA_CRYPTO_CONFIG_FILE when CIRCUITPY_HASHLIB_MBEDTLS_ONLY is set. +// +// Only the crypto config is needed here: nothing on this path includes +// mbedtls/build_info.h, so no TLS/X.509 configuration is required. +// +// The PSA core is enabled so that hashlib can use the same psa_hash_*() interface on +// every port. It also means PSA_WANT_* behaves as documented: tf-psa-crypto/build_info.h +// only derives the builtin implementations from PSA_WANT_* when MBEDTLS_PSA_CRYPTO_C is +// set, so without it PSA_WANT_ALG_SHA_256 would silently select nothing. + +#pragma once + +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +#define MBEDTLS_DEPRECATED_REMOVED + +#undef MBEDTLS_HAVE_TIME +#undef MBEDTLS_HAVE_TIME_DATE + +// The digests hashlib exposes. +#define PSA_WANT_ALG_SHA_1 +#define PSA_WANT_ALG_SHA_256 + +// psa_crypto_init() initializes the RNG subsystem even in a build that only hashes, so +// a random generator has to be available. Take it straight from the port TRNG, which +// keeps entropy.c and ctr_drbg.c out of the build; see hashlib_psa_port.c. +#define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + +#define MBEDTLS_SHA256_SMALLER + +// Memory allocation hooks +#include +#include +void *m_tracked_calloc(size_t nmemb, size_t size); +void m_tracked_free(void *ptr); +#define MBEDTLS_PLATFORM_STD_CALLOC m_tracked_calloc +#define MBEDTLS_PLATFORM_STD_FREE m_tracked_free +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf diff --git a/lib/mbedtls_errors/do-mp.sh b/lib/mbedtls_errors/do-mp.sh index 5c6b9711794..3713b0087a7 100755 --- a/lib/mbedtls_errors/do-mp.sh +++ b/lib/mbedtls_errors/do-mp.sh @@ -1,4 +1,15 @@ #! /bin/bash -e # Generate mp_mbedtls_errors.c for inclusion in ports that use $MPY/lib/mbedtls +# +# As of mbedtls 4.0 the error #defines live in two trees: TLS and X.509 in +# mbedtls/include/mbedtls, and the legacy crypto modules in tf-psa-crypto, so +# generate_errors.pl now takes the crypto include directory as well. patch -o mp_generate_errors.pl ../mbedtls/scripts/generate_errors.pl -#if defined(MBEDTLS_AES_C) -#include "mbedtls/aes.h" +#if defined(MBEDTLS_NET_C) +#include "mbedtls/net_sockets.h" #endif -#if defined(MBEDTLS_ARC4_C) -#include "mbedtls/arc4.h" +#if defined(MBEDTLS_PKCS7_C) +#include "mbedtls/pkcs7.h" #endif -#if defined(MBEDTLS_ARIA_C) -#include "mbedtls/aria.h" +#if defined(MBEDTLS_SSL_TLS_C) +#include "mbedtls/ssl.h" #endif -#if defined(MBEDTLS_ASN1_PARSE_C) -#include "mbedtls/asn1.h" +#if defined(MBEDTLS_X509_USE_C) || \ + defined(MBEDTLS_X509_CREATE_C) +#include "mbedtls/x509.h" #endif -#if defined(MBEDTLS_BASE64_C) -#include "mbedtls/base64.h" +#if defined(MBEDTLS_AES_C) +#include "mbedtls/private/aes.h" #endif -#if defined(MBEDTLS_BIGNUM_C) -#include "mbedtls/bignum.h" +#if defined(MBEDTLS_ARIA_C) +#include "mbedtls/private/aria.h" #endif -#if defined(MBEDTLS_BLOWFISH_C) -#include "mbedtls/blowfish.h" +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/private/bignum.h" #endif #if defined(MBEDTLS_CAMELLIA_C) -#include "mbedtls/camellia.h" -#endif - -#if defined(MBEDTLS_CCM_C) -#include "mbedtls/ccm.h" -#endif - -#if defined(MBEDTLS_CHACHA20_C) -#include "mbedtls/chacha20.h" +#include "mbedtls/private/camellia.h" #endif #if defined(MBEDTLS_CHACHAPOLY_C) -#include "mbedtls/chachapoly.h" +#include "mbedtls/private/chachapoly.h" #endif #if defined(MBEDTLS_CIPHER_C) -#include "mbedtls/cipher.h" -#endif - -#if defined(MBEDTLS_CMAC_C) -#include "mbedtls/cmac.h" +#include "mbedtls/private/cipher.h" #endif #if defined(MBEDTLS_CTR_DRBG_C) -#include "mbedtls/ctr_drbg.h" -#endif - -#if defined(MBEDTLS_DES_C) -#include "mbedtls/des.h" -#endif - -#if defined(MBEDTLS_DHM_C) -#include "mbedtls/dhm.h" +#include "mbedtls/private/ctr_drbg.h" #endif #if defined(MBEDTLS_ECP_C) -#include "mbedtls/ecp.h" +#include "mbedtls/private/ecp.h" #endif #if defined(MBEDTLS_ENTROPY_C) -#include "mbedtls/entropy.h" -#endif - -#if defined(MBEDTLS_ERROR_C) -#include "mbedtls/error.h" -#endif - -#if defined(MBEDTLS_GCM_C) -#include "mbedtls/gcm.h" -#endif - -#if defined(MBEDTLS_HKDF_C) -#include "mbedtls/hkdf.h" +#include "mbedtls/private/entropy.h" #endif #if defined(MBEDTLS_HMAC_DRBG_C) -#include "mbedtls/hmac_drbg.h" -#endif - -#if defined(MBEDTLS_MD_C) -#include "mbedtls/md.h" -#endif - -#if defined(MBEDTLS_MD2_C) -#include "mbedtls/md2.h" -#endif - -#if defined(MBEDTLS_MD4_C) -#include "mbedtls/md4.h" -#endif - -#if defined(MBEDTLS_MD5_C) -#include "mbedtls/md5.h" -#endif - -#if defined(MBEDTLS_NET_C) -#include "mbedtls/net_sockets.h" -#endif - -#if defined(MBEDTLS_OID_C) -#include "mbedtls/oid.h" -#endif - -#if defined(MBEDTLS_PADLOCK_C) -#if defined(MBEDTLS_PADLOCK_FILE) -#include MBEDTLS_PADLOCK_FILE -#else -#include "mbedtls/padlock.h" -#endif -#endif - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) -#include "mbedtls/pem.h" -#endif - -#if defined(MBEDTLS_PK_C) -#include "mbedtls/pk.h" -#endif - -#if defined(MBEDTLS_PKCS12_C) -#include "mbedtls/pkcs12.h" +#include "mbedtls/private/hmac_drbg.h" #endif #if defined(MBEDTLS_PKCS5_C) -#include "mbedtls/pkcs5.h" -#endif - -#if defined(MBEDTLS_PLATFORM_C) -#include "mbedtls/platform.h" -#endif - -#if defined(MBEDTLS_POLY1305_C) -#include "mbedtls/poly1305.h" -#endif - -#if defined(MBEDTLS_RIPEMD160_C) -#include "mbedtls/ripemd160.h" +#include "mbedtls/private/pkcs5.h" #endif #if defined(MBEDTLS_RSA_C) -#include "mbedtls/rsa.h" -#endif - -#if defined(MBEDTLS_SHA1_C) -#include "mbedtls/sha1.h" -#endif - -#if defined(MBEDTLS_SHA256_C) -#include "mbedtls/sha256.h" -#endif - -#if defined(MBEDTLS_SHA512_C) -#include "mbedtls/sha512.h" -#endif - -#if defined(MBEDTLS_SSL_TLS_C) -#include "mbedtls/ssl.h" -#endif - -#if defined(MBEDTLS_THREADING_C) -#include "mbedtls/threading.h" -#endif - -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) -#include "mbedtls/x509.h" -#endif - -#if defined(MBEDTLS_XTEA_C) -#include "mbedtls/xtea.h" +#include "mbedtls/private/rsa.h" #endif @@ -231,197 +112,44 @@ struct ssl_errs { // Table of high level error codes static const struct ssl_errs mbedtls_high_level_error_tab[] = { // BEGIN generated code -#if defined(MBEDTLS_CIPHER_C) - { -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE), "CIPHER_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA), "CIPHER_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED), "CIPHER_ALLOC_FAILED" }, - { -(MBEDTLS_ERR_CIPHER_INVALID_PADDING), "CIPHER_INVALID_PADDING" }, - { -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED), "CIPHER_FULL_BLOCK_EXPECTED" }, - { -(MBEDTLS_ERR_CIPHER_AUTH_FAILED), "CIPHER_AUTH_FAILED" }, - { -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT), "CIPHER_INVALID_CONTEXT" }, -#if defined(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_CIPHER_HW_ACCEL_FAILED), "CIPHER_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_CIPHER_C */ - -#if defined(MBEDTLS_DHM_C) - { -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA), "DHM_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED), "DHM_READ_PARAMS_FAILED" }, - { -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED), "DHM_MAKE_PARAMS_FAILED" }, - { -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED), "DHM_READ_PUBLIC_FAILED" }, - { -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED), "DHM_MAKE_PUBLIC_FAILED" }, - { -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED), "DHM_CALC_SECRET_FAILED" }, - { -(MBEDTLS_ERR_DHM_INVALID_FORMAT), "DHM_INVALID_FORMAT" }, - { -(MBEDTLS_ERR_DHM_ALLOC_FAILED), "DHM_ALLOC_FAILED" }, - { -(MBEDTLS_ERR_DHM_FILE_IO_ERROR), "DHM_FILE_IO_ERROR" }, - { -(MBEDTLS_ERR_DHM_HW_ACCEL_FAILED), "DHM_HW_ACCEL_FAILED" }, - { -(MBEDTLS_ERR_DHM_SET_GROUP_FAILED), "DHM_SET_GROUP_FAILED" }, -#endif /* MBEDTLS_DHM_C */ - -#if defined(MBEDTLS_ECP_C) - { -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA), "ECP_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL), "ECP_BUFFER_TOO_SMALL" }, - { -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE), "ECP_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_ECP_VERIFY_FAILED), "ECP_VERIFY_FAILED" }, - { -(MBEDTLS_ERR_ECP_ALLOC_FAILED), "ECP_ALLOC_FAILED" }, - { -(MBEDTLS_ERR_ECP_RANDOM_FAILED), "ECP_RANDOM_FAILED" }, - { -(MBEDTLS_ERR_ECP_INVALID_KEY), "ECP_INVALID_KEY" }, - { -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH), "ECP_SIG_LEN_MISMATCH" }, -#if defined(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_ECP_HW_ACCEL_FAILED), "ECP_HW_ACCEL_FAILED" }, -#endif - { -(MBEDTLS_ERR_ECP_IN_PROGRESS), "ECP_IN_PROGRESS" }, -#endif /* MBEDTLS_ECP_C */ - -#if defined(MBEDTLS_MD_C) - { -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE), "MD_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_MD_BAD_INPUT_DATA), "MD_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_MD_ALLOC_FAILED), "MD_ALLOC_FAILED" }, - { -(MBEDTLS_ERR_MD_FILE_IO_ERROR), "MD_FILE_IO_ERROR" }, -#if defined(MBEDTLS_ERR_MD_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_MD_HW_ACCEL_FAILED), "MD_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_MD_C */ - -#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) - { -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT), "PEM_NO_HEADER_FOOTER_PRESENT" }, - { -(MBEDTLS_ERR_PEM_INVALID_DATA), "PEM_INVALID_DATA" }, - { -(MBEDTLS_ERR_PEM_ALLOC_FAILED), "PEM_ALLOC_FAILED" }, - { -(MBEDTLS_ERR_PEM_INVALID_ENC_IV), "PEM_INVALID_ENC_IV" }, - { -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG), "PEM_UNKNOWN_ENC_ALG" }, - { -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED), "PEM_PASSWORD_REQUIRED" }, - { -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH), "PEM_PASSWORD_MISMATCH" }, - { -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE), "PEM_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA), "PEM_BAD_INPUT_DATA" }, -#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ - -#if defined(MBEDTLS_PK_C) - { -(MBEDTLS_ERR_PK_ALLOC_FAILED), "PK_ALLOC_FAILED" }, - { -(MBEDTLS_ERR_PK_TYPE_MISMATCH), "PK_TYPE_MISMATCH" }, - { -(MBEDTLS_ERR_PK_BAD_INPUT_DATA), "PK_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_PK_FILE_IO_ERROR), "PK_FILE_IO_ERROR" }, - { -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION), "PK_KEY_INVALID_VERSION" }, - { -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT), "PK_KEY_INVALID_FORMAT" }, - { -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG), "PK_UNKNOWN_PK_ALG" }, - { -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED), "PK_PASSWORD_REQUIRED" }, - { -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH), "PK_PASSWORD_MISMATCH" }, - { -(MBEDTLS_ERR_PK_INVALID_PUBKEY), "PK_INVALID_PUBKEY" }, - { -(MBEDTLS_ERR_PK_INVALID_ALG), "PK_INVALID_ALG" }, - { -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE), "PK_UNKNOWN_NAMED_CURVE" }, - { -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE), "PK_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH), "PK_SIG_LEN_MISMATCH" }, -#if defined(MBEDTLS_ERR_PK_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_PK_HW_ACCEL_FAILED), "PK_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_PK_C */ - -#if defined(MBEDTLS_PKCS12_C) - { -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA), "PKCS12_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE), "PKCS12_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT), "PKCS12_PBE_INVALID_FORMAT" }, - { -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH), "PKCS12_PASSWORD_MISMATCH" }, -#endif /* MBEDTLS_PKCS12_C */ - -#if defined(MBEDTLS_PKCS5_C) - { -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA), "PKCS5_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT), "PKCS5_INVALID_FORMAT" }, - { -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE), "PKCS5_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH), "PKCS5_PASSWORD_MISMATCH" }, -#endif /* MBEDTLS_PKCS5_C */ - -#if defined(MBEDTLS_RSA_C) - { -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA), "RSA_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_RSA_INVALID_PADDING), "RSA_INVALID_PADDING" }, - { -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED), "RSA_KEY_GEN_FAILED" }, - { -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED), "RSA_KEY_CHECK_FAILED" }, - { -(MBEDTLS_ERR_RSA_PUBLIC_FAILED), "RSA_PUBLIC_FAILED" }, - { -(MBEDTLS_ERR_RSA_PRIVATE_FAILED), "RSA_PRIVATE_FAILED" }, - { -(MBEDTLS_ERR_RSA_VERIFY_FAILED), "RSA_VERIFY_FAILED" }, - { -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE), "RSA_OUTPUT_TOO_LARGE" }, - { -(MBEDTLS_ERR_RSA_RNG_FAILED), "RSA_RNG_FAILED" }, -#if defined(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION) - { -(MBEDTLS_ERR_RSA_UNSUPPORTED_OPERATION), "RSA_UNSUPPORTED_OPERATION" }, -#endif -#if defined(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_RSA_HW_ACCEL_FAILED), "RSA_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_PKCS7_C) + { -(MBEDTLS_ERR_PKCS7_INVALID_FORMAT), "PKCS7_INVALID_FORMAT" }, + { -(MBEDTLS_ERR_PKCS7_FEATURE_UNAVAILABLE), "PKCS7_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_PKCS7_INVALID_VERSION), "PKCS7_INVALID_VERSION" }, + { -(MBEDTLS_ERR_PKCS7_INVALID_CONTENT_INFO), "PKCS7_INVALID_CONTENT_INFO" }, + { -(MBEDTLS_ERR_PKCS7_INVALID_ALG), "PKCS7_INVALID_ALG" }, + { -(MBEDTLS_ERR_PKCS7_INVALID_CERT), "PKCS7_INVALID_CERT" }, + { -(MBEDTLS_ERR_PKCS7_INVALID_SIGNATURE), "PKCS7_INVALID_SIGNATURE" }, + { -(MBEDTLS_ERR_PKCS7_INVALID_SIGNER_INFO), "PKCS7_INVALID_SIGNER_INFO" }, + { -(MBEDTLS_ERR_PKCS7_CERT_DATE_INVALID), "PKCS7_CERT_DATE_INVALID" }, +#endif /* MBEDTLS_PKCS7_C */ #if defined(MBEDTLS_SSL_TLS_C) + { -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS), "SSL_CRYPTO_IN_PROGRESS" }, { -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE), "SSL_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA), "SSL_BAD_INPUT_DATA" }, { -(MBEDTLS_ERR_SSL_INVALID_MAC), "SSL_INVALID_MAC" }, { -(MBEDTLS_ERR_SSL_INVALID_RECORD), "SSL_INVALID_RECORD" }, { -(MBEDTLS_ERR_SSL_CONN_EOF), "SSL_CONN_EOF" }, -#if defined(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) - { -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER), "SSL_UNKNOWN_CIPHER" }, -#endif -#if defined(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) - { -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN), "SSL_NO_CIPHER_CHOSEN" }, -#endif + { -(MBEDTLS_ERR_SSL_DECODE_ERROR), "SSL_DECODE_ERROR" }, { -(MBEDTLS_ERR_SSL_NO_RNG), "SSL_NO_RNG" }, { -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE), "SSL_NO_CLIENT_CERTIFICATE" }, -#if defined(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) - { -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE), "SSL_CERTIFICATE_TOO_LARGE" }, -#endif -#if defined(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) - { -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED), "SSL_CERTIFICATE_REQUIRED" }, -#endif + { -(MBEDTLS_ERR_SSL_UNSUPPORTED_EXTENSION), "SSL_UNSUPPORTED_EXTENSION" }, + { -(MBEDTLS_ERR_SSL_NO_APPLICATION_PROTOCOL), "SSL_NO_APPLICATION_PROTOCOL" }, { -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED), "SSL_PRIVATE_KEY_REQUIRED" }, { -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED), "SSL_CA_CHAIN_REQUIRED" }, { -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE), "SSL_UNEXPECTED_MESSAGE" }, -#if defined(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) - { -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED), "SSL_PEER_VERIFY_FAILED" }, -#endif + { -(MBEDTLS_ERR_SSL_UNRECOGNIZED_NAME), "SSL_UNRECOGNIZED_NAME" }, { -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY), "SSL_PEER_CLOSE_NOTIFY" }, -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) - { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO), "SSL_BAD_HS_CLIENT_HELLO" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) - { -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO), "SSL_BAD_HS_SERVER_HELLO" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) - { -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE), "SSL_BAD_HS_CERTIFICATE" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) - { -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST), "SSL_BAD_HS_CERTIFICATE_REQUEST" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) - { -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE), "SSL_BAD_HS_SERVER_KEY_EXCHANGE" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) - { -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE), "SSL_BAD_HS_SERVER_HELLO_DONE" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) - { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) - { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) - { -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS), "SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) - { -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY), "SSL_BAD_HS_CERTIFICATE_VERIFY" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) - { -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC), "SSL_BAD_HS_CHANGE_CIPHER_SPEC" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) - { -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED), "SSL_BAD_HS_FINISHED" }, -#endif - { -(MBEDTLS_ERR_SSL_ALLOC_FAILED), "SSL_ALLOC_FAILED" }, + { -(MBEDTLS_ERR_SSL_BAD_CERTIFICATE), "SSL_BAD_CERTIFICATE" }, + { -(MBEDTLS_ERR_SSL_RECEIVED_NEW_SESSION_TICKET), "SSL_RECEIVED_NEW_SESSION_TICKET" }, + { -(MBEDTLS_ERR_SSL_CANNOT_READ_EARLY_DATA), "SSL_CANNOT_READ_EARLY_DATA" }, + { -(MBEDTLS_ERR_SSL_RECEIVED_EARLY_DATA), "SSL_RECEIVED_EARLY_DATA" }, + { -(MBEDTLS_ERR_SSL_CANNOT_WRITE_EARLY_DATA), "SSL_CANNOT_WRITE_EARLY_DATA" }, + { -(MBEDTLS_ERR_SSL_CACHE_ENTRY_NOT_FOUND), "SSL_CACHE_ENTRY_NOT_FOUND" }, { -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED), "SSL_HW_ACCEL_FAILED" }, { -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH), "SSL_HW_ACCEL_FALLTHROUGH" }, -#if defined(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) - { -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED), "SSL_COMPRESSION_FAILED" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) - { -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION), "SSL_BAD_HS_PROTOCOL_VERSION" }, -#endif -#if defined(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) - { -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET), "SSL_BAD_HS_NEW_SESSION_TICKET" }, -#endif + { -(MBEDTLS_ERR_SSL_BAD_PROTOCOL_VERSION), "SSL_BAD_PROTOCOL_VERSION" }, + { -(MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE), "SSL_HANDSHAKE_FAILURE" }, { -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED), "SSL_SESSION_TICKET_EXPIRED" }, { -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH), "SSL_PK_TYPE_MISMATCH" }, { -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY), "SSL_UNKNOWN_IDENTITY" }, @@ -429,29 +157,24 @@ static const struct ssl_errs mbedtls_high_level_error_tab[] = { { -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING), "SSL_COUNTER_WRAPPING" }, { -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO), "SSL_WAITING_SERVER_HELLO_RENEGO" }, { -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED), "SSL_HELLO_VERIFY_REQUIRED" }, - { -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL), "SSL_BUFFER_TOO_SMALL" }, -#if defined(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) - { -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE), "SSL_NO_USABLE_CIPHERSUITE" }, -#endif { -(MBEDTLS_ERR_SSL_WANT_READ), "SSL_WANT_READ" }, { -(MBEDTLS_ERR_SSL_WANT_WRITE), "SSL_WANT_WRITE" }, { -(MBEDTLS_ERR_SSL_TIMEOUT), "SSL_TIMEOUT" }, { -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT), "SSL_CLIENT_RECONNECT" }, { -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD), "SSL_UNEXPECTED_RECORD" }, { -(MBEDTLS_ERR_SSL_NON_FATAL), "SSL_NON_FATAL" }, -#if defined(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) - { -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH), "SSL_INVALID_VERIFY_HASH" }, -#endif + { -(MBEDTLS_ERR_SSL_ILLEGAL_PARAMETER), "SSL_ILLEGAL_PARAMETER" }, { -(MBEDTLS_ERR_SSL_CONTINUE_PROCESSING), "SSL_CONTINUE_PROCESSING" }, { -(MBEDTLS_ERR_SSL_ASYNC_IN_PROGRESS), "SSL_ASYNC_IN_PROGRESS" }, { -(MBEDTLS_ERR_SSL_EARLY_MESSAGE), "SSL_EARLY_MESSAGE" }, { -(MBEDTLS_ERR_SSL_UNEXPECTED_CID), "SSL_UNEXPECTED_CID" }, { -(MBEDTLS_ERR_SSL_VERSION_MISMATCH), "SSL_VERSION_MISMATCH" }, - { -(MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS), "SSL_CRYPTO_IN_PROGRESS" }, { -(MBEDTLS_ERR_SSL_BAD_CONFIG), "SSL_BAD_CONFIG" }, + { -(MBEDTLS_ERR_SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME), "SSL_CERTIFICATE_VERIFICATION_WITHOUT_HOSTNAME" }, #endif /* MBEDTLS_SSL_TLS_C */ -#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) +#if defined(MBEDTLS_X509_USE_C) || \ + defined(MBEDTLS_X509_CREATE_C) { -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE), "X509_FEATURE_UNAVAILABLE" }, { -(MBEDTLS_ERR_X509_UNKNOWN_OID), "X509_UNKNOWN_OID" }, { -(MBEDTLS_ERR_X509_INVALID_FORMAT), "X509_INVALID_FORMAT" }, @@ -468,11 +191,34 @@ static const struct ssl_errs mbedtls_high_level_error_tab[] = { { -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED), "X509_CERT_VERIFY_FAILED" }, { -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT), "X509_CERT_UNKNOWN_FORMAT" }, { -(MBEDTLS_ERR_X509_BAD_INPUT_DATA), "X509_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_X509_ALLOC_FAILED), "X509_ALLOC_FAILED" }, { -(MBEDTLS_ERR_X509_FILE_IO_ERROR), "X509_FILE_IO_ERROR" }, - { -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL), "X509_BUFFER_TOO_SMALL" }, { -(MBEDTLS_ERR_X509_FATAL_ERROR), "X509_FATAL_ERROR" }, -#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ +#endif /* MBEDTLS_X509_USE_C || + MBEDTLS_X509_CREATE_C */ + +#if defined(MBEDTLS_CIPHER_C) + { -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE), "CIPHER_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED), "CIPHER_FULL_BLOCK_EXPECTED" }, + { -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT), "CIPHER_INVALID_CONTEXT" }, +#endif /* MBEDTLS_CIPHER_C */ + +#if defined(MBEDTLS_ECP_C) + { -(MBEDTLS_ERR_ECP_INVALID_KEY), "ECP_INVALID_KEY" }, +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_PKCS5_C) + { -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT), "PKCS5_INVALID_FORMAT" }, + { -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE), "PKCS5_FEATURE_UNAVAILABLE" }, + { -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH), "PKCS5_PASSWORD_MISMATCH" }, +#endif /* MBEDTLS_PKCS5_C */ + +#if defined(MBEDTLS_RSA_C) + { -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED), "RSA_KEY_GEN_FAILED" }, + { -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED), "RSA_KEY_CHECK_FAILED" }, + { -(MBEDTLS_ERR_RSA_PUBLIC_FAILED), "RSA_PUBLIC_FAILED" }, + { -(MBEDTLS_ERR_RSA_PRIVATE_FAILED), "RSA_PRIVATE_FAILED" }, + { -(MBEDTLS_ERR_RSA_RNG_FAILED), "RSA_RNG_FAILED" }, +#endif /* MBEDTLS_RSA_C */ // END generated code }; @@ -480,98 +226,46 @@ static const struct ssl_errs mbedtls_low_level_error_tab[] = { // Low level error codes // // BEGIN generated code +#if defined(MBEDTLS_NET_C) + { -(MBEDTLS_ERR_NET_SOCKET_FAILED), "NET_SOCKET_FAILED" }, + { -(MBEDTLS_ERR_NET_CONNECT_FAILED), "NET_CONNECT_FAILED" }, + { -(MBEDTLS_ERR_NET_BIND_FAILED), "NET_BIND_FAILED" }, + { -(MBEDTLS_ERR_NET_LISTEN_FAILED), "NET_LISTEN_FAILED" }, + { -(MBEDTLS_ERR_NET_ACCEPT_FAILED), "NET_ACCEPT_FAILED" }, + { -(MBEDTLS_ERR_NET_RECV_FAILED), "NET_RECV_FAILED" }, + { -(MBEDTLS_ERR_NET_SEND_FAILED), "NET_SEND_FAILED" }, + { -(MBEDTLS_ERR_NET_CONN_RESET), "NET_CONN_RESET" }, + { -(MBEDTLS_ERR_NET_UNKNOWN_HOST), "NET_UNKNOWN_HOST" }, + { -(MBEDTLS_ERR_NET_INVALID_CONTEXT), "NET_INVALID_CONTEXT" }, + { -(MBEDTLS_ERR_NET_POLL_FAILED), "NET_POLL_FAILED" }, + { -(MBEDTLS_ERR_NET_BAD_INPUT_DATA), "NET_BAD_INPUT_DATA" }, +#endif /* MBEDTLS_NET_C */ + #if defined(MBEDTLS_AES_C) { -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH), "AES_INVALID_KEY_LENGTH" }, { -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH), "AES_INVALID_INPUT_LENGTH" }, - { -(MBEDTLS_ERR_AES_BAD_INPUT_DATA), "AES_BAD_INPUT_DATA" }, -#if defined(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE) - { -(MBEDTLS_ERR_AES_FEATURE_UNAVAILABLE), "AES_FEATURE_UNAVAILABLE" }, -#endif -#if defined(MBEDTLS_ERR_AES_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_AES_HW_ACCEL_FAILED), "AES_HW_ACCEL_FAILED" }, -#endif #endif /* MBEDTLS_AES_C */ -#if defined(MBEDTLS_ARC4_C) - { -(MBEDTLS_ERR_ARC4_HW_ACCEL_FAILED), "ARC4_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_ARC4_C */ - #if defined(MBEDTLS_ARIA_C) - { -(MBEDTLS_ERR_ARIA_BAD_INPUT_DATA), "ARIA_BAD_INPUT_DATA" }, { -(MBEDTLS_ERR_ARIA_INVALID_INPUT_LENGTH), "ARIA_INVALID_INPUT_LENGTH" }, -#if defined(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE) - { -(MBEDTLS_ERR_ARIA_FEATURE_UNAVAILABLE), "ARIA_FEATURE_UNAVAILABLE" }, -#endif -#if defined(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_ARIA_HW_ACCEL_FAILED), "ARIA_HW_ACCEL_FAILED" }, -#endif #endif /* MBEDTLS_ARIA_C */ -#if defined(MBEDTLS_ASN1_PARSE_C) - { -(MBEDTLS_ERR_ASN1_OUT_OF_DATA), "ASN1_OUT_OF_DATA" }, - { -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG), "ASN1_UNEXPECTED_TAG" }, - { -(MBEDTLS_ERR_ASN1_INVALID_LENGTH), "ASN1_INVALID_LENGTH" }, - { -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH), "ASN1_LENGTH_MISMATCH" }, - { -(MBEDTLS_ERR_ASN1_INVALID_DATA), "ASN1_INVALID_DATA" }, - { -(MBEDTLS_ERR_ASN1_ALLOC_FAILED), "ASN1_ALLOC_FAILED" }, - { -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL), "ASN1_BUF_TOO_SMALL" }, -#endif /* MBEDTLS_ASN1_PARSE_C */ - -#if defined(MBEDTLS_BASE64_C) - { -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL), "BASE64_BUFFER_TOO_SMALL" }, - { -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER), "BASE64_INVALID_CHARACTER" }, -#endif /* MBEDTLS_BASE64_C */ - #if defined(MBEDTLS_BIGNUM_C) { -(MBEDTLS_ERR_MPI_FILE_IO_ERROR), "MPI_FILE_IO_ERROR" }, - { -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA), "MPI_BAD_INPUT_DATA" }, { -(MBEDTLS_ERR_MPI_INVALID_CHARACTER), "MPI_INVALID_CHARACTER" }, - { -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL), "MPI_BUFFER_TOO_SMALL" }, { -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE), "MPI_NEGATIVE_VALUE" }, { -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO), "MPI_DIVISION_BY_ZERO" }, { -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE), "MPI_NOT_ACCEPTABLE" }, - { -(MBEDTLS_ERR_MPI_ALLOC_FAILED), "MPI_ALLOC_FAILED" }, #endif /* MBEDTLS_BIGNUM_C */ -#if defined(MBEDTLS_BLOWFISH_C) - { -(MBEDTLS_ERR_BLOWFISH_BAD_INPUT_DATA), "BLOWFISH_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH), "BLOWFISH_INVALID_INPUT_LENGTH" }, - { -(MBEDTLS_ERR_BLOWFISH_HW_ACCEL_FAILED), "BLOWFISH_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_BLOWFISH_C */ - #if defined(MBEDTLS_CAMELLIA_C) - { -(MBEDTLS_ERR_CAMELLIA_BAD_INPUT_DATA), "CAMELLIA_BAD_INPUT_DATA" }, { -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH), "CAMELLIA_INVALID_INPUT_LENGTH" }, - { -(MBEDTLS_ERR_CAMELLIA_HW_ACCEL_FAILED), "CAMELLIA_HW_ACCEL_FAILED" }, #endif /* MBEDTLS_CAMELLIA_C */ -#if defined(MBEDTLS_CCM_C) - { -(MBEDTLS_ERR_CCM_BAD_INPUT), "CCM_BAD_INPUT" }, - { -(MBEDTLS_ERR_CCM_AUTH_FAILED), "CCM_AUTH_FAILED" }, -#if defined(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_CCM_HW_ACCEL_FAILED), "CCM_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_CCM_C */ - -#if defined(MBEDTLS_CHACHA20_C) - { -(MBEDTLS_ERR_CHACHA20_BAD_INPUT_DATA), "CHACHA20_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_CHACHA20_FEATURE_UNAVAILABLE), "CHACHA20_FEATURE_UNAVAILABLE" }, -#if defined(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_CHACHA20_HW_ACCEL_FAILED), "CHACHA20_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_CHACHA20_C */ - #if defined(MBEDTLS_CHACHAPOLY_C) { -(MBEDTLS_ERR_CHACHAPOLY_BAD_STATE), "CHACHAPOLY_BAD_STATE" }, - { -(MBEDTLS_ERR_CHACHAPOLY_AUTH_FAILED), "CHACHAPOLY_AUTH_FAILED" }, #endif /* MBEDTLS_CHACHAPOLY_C */ -#if defined(MBEDTLS_CMAC_C) -#if defined(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_CMAC_HW_ACCEL_FAILED), "CMAC_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_CMAC_C */ - #if defined(MBEDTLS_CTR_DRBG_C) { -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED), "CTR_DRBG_ENTROPY_SOURCE_FAILED" }, { -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG), "CTR_DRBG_REQUEST_TOO_BIG" }, @@ -579,128 +273,19 @@ static const struct ssl_errs mbedtls_low_level_error_tab[] = { { -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR), "CTR_DRBG_FILE_IO_ERROR" }, #endif /* MBEDTLS_CTR_DRBG_C */ -#if defined(MBEDTLS_DES_C) - { -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH), "DES_INVALID_INPUT_LENGTH" }, - { -(MBEDTLS_ERR_DES_HW_ACCEL_FAILED), "DES_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_DES_C */ - #if defined(MBEDTLS_ENTROPY_C) - { -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED), "ENTROPY_SOURCE_FAILED" }, { -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES), "ENTROPY_MAX_SOURCES" }, { -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED), "ENTROPY_NO_SOURCES_DEFINED" }, { -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE), "ENTROPY_NO_STRONG_SOURCE" }, { -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR), "ENTROPY_FILE_IO_ERROR" }, #endif /* MBEDTLS_ENTROPY_C */ -#if defined(MBEDTLS_ERROR_C) - { -(MBEDTLS_ERR_ERROR_GENERIC_ERROR), "ERROR_GENERIC_ERROR" }, - { -(MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED), "ERROR_CORRUPTION_DETECTED" }, -#endif /* MBEDTLS_ERROR_C */ - -#if defined(MBEDTLS_GCM_C) - { -(MBEDTLS_ERR_GCM_AUTH_FAILED), "GCM_AUTH_FAILED" }, -#if defined(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_GCM_HW_ACCEL_FAILED), "GCM_HW_ACCEL_FAILED" }, -#endif - { -(MBEDTLS_ERR_GCM_BAD_INPUT), "GCM_BAD_INPUT" }, -#endif /* MBEDTLS_GCM_C */ - -#if defined(MBEDTLS_HKDF_C) - { -(MBEDTLS_ERR_HKDF_BAD_INPUT_DATA), "HKDF_BAD_INPUT_DATA" }, -#endif /* MBEDTLS_HKDF_C */ - #if defined(MBEDTLS_HMAC_DRBG_C) { -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG), "HMAC_DRBG_REQUEST_TOO_BIG" }, { -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG), "HMAC_DRBG_INPUT_TOO_BIG" }, { -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR), "HMAC_DRBG_FILE_IO_ERROR" }, { -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED), "HMAC_DRBG_ENTROPY_SOURCE_FAILED" }, #endif /* MBEDTLS_HMAC_DRBG_C */ - -#if defined(MBEDTLS_MD2_C) - { -(MBEDTLS_ERR_MD2_HW_ACCEL_FAILED), "MD2_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_MD2_C */ - -#if defined(MBEDTLS_MD4_C) - { -(MBEDTLS_ERR_MD4_HW_ACCEL_FAILED), "MD4_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_MD4_C */ - -#if defined(MBEDTLS_MD5_C) -#if defined(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_MD5_HW_ACCEL_FAILED), "MD5_HW_ACCEL_FAILED" }, -#endif -#endif /* MBEDTLS_MD5_C */ - -#if defined(MBEDTLS_NET_C) - { -(MBEDTLS_ERR_NET_SOCKET_FAILED), "NET_SOCKET_FAILED" }, - { -(MBEDTLS_ERR_NET_CONNECT_FAILED), "NET_CONNECT_FAILED" }, - { -(MBEDTLS_ERR_NET_BIND_FAILED), "NET_BIND_FAILED" }, - { -(MBEDTLS_ERR_NET_LISTEN_FAILED), "NET_LISTEN_FAILED" }, - { -(MBEDTLS_ERR_NET_ACCEPT_FAILED), "NET_ACCEPT_FAILED" }, - { -(MBEDTLS_ERR_NET_RECV_FAILED), "NET_RECV_FAILED" }, - { -(MBEDTLS_ERR_NET_SEND_FAILED), "NET_SEND_FAILED" }, - { -(MBEDTLS_ERR_NET_CONN_RESET), "NET_CONN_RESET" }, - { -(MBEDTLS_ERR_NET_UNKNOWN_HOST), "NET_UNKNOWN_HOST" }, - { -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL), "NET_BUFFER_TOO_SMALL" }, - { -(MBEDTLS_ERR_NET_INVALID_CONTEXT), "NET_INVALID_CONTEXT" }, - { -(MBEDTLS_ERR_NET_POLL_FAILED), "NET_POLL_FAILED" }, - { -(MBEDTLS_ERR_NET_BAD_INPUT_DATA), "NET_BAD_INPUT_DATA" }, -#endif /* MBEDTLS_NET_C */ - -#if defined(MBEDTLS_OID_C) - { -(MBEDTLS_ERR_OID_NOT_FOUND), "OID_NOT_FOUND" }, - { -(MBEDTLS_ERR_OID_BUF_TOO_SMALL), "OID_BUF_TOO_SMALL" }, -#endif /* MBEDTLS_OID_C */ - -#if defined(MBEDTLS_PADLOCK_C) - { -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED), "PADLOCK_DATA_MISALIGNED" }, -#endif /* MBEDTLS_PADLOCK_C */ - -#if defined(MBEDTLS_PLATFORM_C) - { -(MBEDTLS_ERR_PLATFORM_HW_ACCEL_FAILED), "PLATFORM_HW_ACCEL_FAILED" }, - { -(MBEDTLS_ERR_PLATFORM_FEATURE_UNSUPPORTED), "PLATFORM_FEATURE_UNSUPPORTED" }, -#endif /* MBEDTLS_PLATFORM_C */ - -#if defined(MBEDTLS_POLY1305_C) - { -(MBEDTLS_ERR_POLY1305_BAD_INPUT_DATA), "POLY1305_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_POLY1305_FEATURE_UNAVAILABLE), "POLY1305_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_POLY1305_HW_ACCEL_FAILED), "POLY1305_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_POLY1305_C */ - -#if defined(MBEDTLS_RIPEMD160_C) - { -(MBEDTLS_ERR_RIPEMD160_HW_ACCEL_FAILED), "RIPEMD160_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_RIPEMD160_C */ - -#if defined(MBEDTLS_SHA1_C) -#if defined(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_SHA1_HW_ACCEL_FAILED), "SHA1_HW_ACCEL_FAILED" }, -#endif - { -(MBEDTLS_ERR_SHA1_BAD_INPUT_DATA), "SHA1_BAD_INPUT_DATA" }, -#endif /* MBEDTLS_SHA1_C */ - -#if defined(MBEDTLS_SHA256_C) -#if defined(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_SHA256_HW_ACCEL_FAILED), "SHA256_HW_ACCEL_FAILED" }, -#endif - { -(MBEDTLS_ERR_SHA256_BAD_INPUT_DATA), "SHA256_BAD_INPUT_DATA" }, -#endif /* MBEDTLS_SHA256_C */ - -#if defined(MBEDTLS_SHA512_C) -#if defined(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED) - { -(MBEDTLS_ERR_SHA512_HW_ACCEL_FAILED), "SHA512_HW_ACCEL_FAILED" }, -#endif - { -(MBEDTLS_ERR_SHA512_BAD_INPUT_DATA), "SHA512_BAD_INPUT_DATA" }, -#endif /* MBEDTLS_SHA512_C */ - -#if defined(MBEDTLS_THREADING_C) - { -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE), "THREADING_FEATURE_UNAVAILABLE" }, - { -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA), "THREADING_BAD_INPUT_DATA" }, - { -(MBEDTLS_ERR_THREADING_MUTEX_ERROR), "THREADING_MUTEX_ERROR" }, -#endif /* MBEDTLS_THREADING_C */ - -#if defined(MBEDTLS_XTEA_C) - { -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH), "XTEA_INVALID_INPUT_LENGTH" }, - { -(MBEDTLS_ERR_XTEA_HW_ACCEL_FAILED), "XTEA_HW_ACCEL_FAILED" }, -#endif /* MBEDTLS_XTEA_C */ // END generated code }; diff --git a/lib/micropython-lib b/lib/micropython-lib index 50ed36fbeb9..6ae440a8a14 160000 --- a/lib/micropython-lib +++ b/lib/micropython-lib @@ -1 +1 @@ -Subproject commit 50ed36fbeb919753bcc26ce13a8cffd7691d06ef +Subproject commit 6ae440a8a144233e6e703f6759b7e7a0afaa37a4 diff --git a/lib/protomatter b/lib/protomatter index 0bd9873153a..425b6c7f887 160000 --- a/lib/protomatter +++ b/lib/protomatter @@ -1 +1 @@ -Subproject commit 0bd9873153ab0a91d6737c392622159a4515a2e5 +Subproject commit 425b6c7f887cca5d24d768d8c80c74ba7eb88dc6 diff --git a/lib/tinytest/README b/lib/tinytest/README deleted file mode 100644 index 28165d8bc79..00000000000 --- a/lib/tinytest/README +++ /dev/null @@ -1,17 +0,0 @@ -Tinytest is a tiny little test framework written in C by Nick Mathewson. - -It is distributed under the 3-clause BSD license. You can use it in -your own programs so long as you follow the license's conditions. - -It's been tested on Windows, Mac, and many of the free Unixes. - -It knows how to fork before running certain tests, and it makes -text-mode output in a format I like. - -For info on how to use it, check out tinytest_demo.c. - -You can get the latest version using Git, by pulling from - git://github.com/nmathewson/tinytest.git - -Patches are welcome. Patches that turn this from tinytest to hugetest -will not be applied. If you want a huge test framework, use CUnit. diff --git a/lib/tinytest/tinytest.c b/lib/tinytest/tinytest.c deleted file mode 100644 index 1a5030ae3c5..00000000000 --- a/lib/tinytest/tinytest.c +++ /dev/null @@ -1,473 +0,0 @@ -/* tinytest.c -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifdef TINYTEST_LOCAL -#include "tinytest_local.h" -#endif - -#include -#include -#include -#include - -#ifndef NO_FORKING - -#ifdef _WIN32 -#include -#else -#include -#include -#include -#endif - -#if defined(__APPLE__) && defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) -#if (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060 && \ - __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1070) -/* Workaround for a stupid bug in OSX 10.6 */ -#define FORK_BREAKS_GCOV -#include -#endif -#endif - -#endif /* !NO_FORKING */ - -#ifndef __GNUC__ -#define __attribute__(x) -#endif - -#include "tinytest.h" -#include "tinytest_macros.h" - -#define LONGEST_TEST_NAME 16384 - -static int in_tinytest_main = 0; /**< true if we're in tinytest_main().*/ -static int n_ok = 0; /**< Number of tests that have passed */ -static int n_bad = 0; /**< Number of tests that have failed. */ -static int n_skipped = 0; /**< Number of tests that have been skipped. */ - -static int opt_forked = 0; /**< True iff we're called from inside a win32 fork*/ -static int opt_nofork = 0; /**< Suppress calls to fork() for debugging. */ -static int opt_verbosity = 1; /**< -==quiet,0==terse,1==normal,2==verbose */ -const char *verbosity_flag = ""; - -const struct testlist_alias_t *cfg_aliases=NULL; - -enum outcome { SKIP=2, OK=1, FAIL=0 }; -static enum outcome cur_test_outcome = 0; -const char *cur_test_prefix = NULL; /**< prefix of the current test group */ -/** Name of the current test, if we haven't logged is yet. Used for --quiet */ -const char *cur_test_name = NULL; - -#ifdef _WIN32 -/* Copy of argv[0] for win32. */ -static char commandname[MAX_PATH+1]; -#endif - -static void usage(struct testgroup_t *groups, int list_groups) - __attribute__((noreturn)); -static int process_test_option(struct testgroup_t *groups, const char *test); - -static enum outcome -testcase_run_bare_(const struct testcase_t *testcase) -{ - void *env = NULL; - int outcome; - if (testcase->setup) { - env = testcase->setup->setup_fn(testcase); - if (!env) - return FAIL; - else if (env == (void*)TT_SKIP) - return SKIP; - } - - cur_test_outcome = OK; - testcase->fn(env); - outcome = cur_test_outcome; - - if (testcase->setup) { - if (testcase->setup->cleanup_fn(testcase, env) == 0) - outcome = FAIL; - } - - return outcome; -} - -#define MAGIC_EXITCODE 42 - -#ifndef NO_FORKING - -static enum outcome -testcase_run_forked_(const struct testgroup_t *group, - const struct testcase_t *testcase) -{ -#ifdef _WIN32 - /* Fork? On Win32? How primitive! We'll do what the smart kids do: - we'll invoke our own exe (whose name we recall from the command - line) with a command line that tells it to run just the test we - want, and this time without forking. - - (No, threads aren't an option. The whole point of forking is to - share no state between tests.) - */ - int ok; - char buffer[LONGEST_TEST_NAME+256]; - STARTUPINFOA si; - PROCESS_INFORMATION info; - DWORD exitcode; - - if (!in_tinytest_main) { - printf("\nERROR. On Windows, testcase_run_forked_ must be" - " called from within tinytest_main.\n"); - abort(); - } - if (opt_verbosity>0) - printf("[forking] "); - - snprintf(buffer, sizeof(buffer), "%s --RUNNING-FORKED %s %s%s", - commandname, verbosity_flag, group->prefix, testcase->name); - - memset(&si, 0, sizeof(si)); - memset(&info, 0, sizeof(info)); - si.cb = sizeof(si); - - ok = CreateProcessA(commandname, buffer, NULL, NULL, 0, - 0, NULL, NULL, &si, &info); - if (!ok) { - printf("CreateProcess failed!\n"); - return 0; - } - WaitForSingleObject(info.hProcess, INFINITE); - GetExitCodeProcess(info.hProcess, &exitcode); - CloseHandle(info.hProcess); - CloseHandle(info.hThread); - if (exitcode == 0) - return OK; - else if (exitcode == MAGIC_EXITCODE) - return SKIP; - else - return FAIL; -#else - int outcome_pipe[2]; - pid_t pid; - (void)group; - - if (pipe(outcome_pipe)) - perror("opening pipe"); - - if (opt_verbosity>0) - printf("[forking] "); - pid = fork(); -#ifdef FORK_BREAKS_GCOV - vproc_transaction_begin(0); -#endif - if (!pid) { - /* child. */ - int test_r, write_r; - char b[1]; - close(outcome_pipe[0]); - test_r = testcase_run_bare_(testcase); - assert(0<=(int)test_r && (int)test_r<=2); - b[0] = "NYS"[test_r]; - write_r = (int)write(outcome_pipe[1], b, 1); - if (write_r != 1) { - perror("write outcome to pipe"); - exit(1); - } - exit(0); - return FAIL; /* unreachable */ - } else { - /* parent */ - int status, r; - char b[1]; - /* Close this now, so that if the other side closes it, - * our read fails. */ - close(outcome_pipe[1]); - r = (int)read(outcome_pipe[0], b, 1); - if (r == 0) { - printf("[Lost connection!] "); - return 0; - } else if (r != 1) { - perror("read outcome from pipe"); - } - waitpid(pid, &status, 0); - close(outcome_pipe[0]); - return b[0]=='Y' ? OK : (b[0]=='S' ? SKIP : FAIL); - } -#endif -} - -#endif /* !NO_FORKING */ - -int -testcase_run_one(const struct testgroup_t *group, - const struct testcase_t *testcase) -{ - enum outcome outcome; - - if (testcase->flags & (TT_SKIP|TT_OFF_BY_DEFAULT)) { - if (opt_verbosity>0) - printf("%s%s: %s\n", - group->prefix, testcase->name, - (testcase->flags & TT_SKIP) ? "SKIPPED" : "DISABLED"); - ++n_skipped; - return SKIP; - } - - if (opt_verbosity>0 && !opt_forked) { - printf("%s%s: ", group->prefix, testcase->name); - } else { - if (opt_verbosity==0) printf("."); - cur_test_prefix = group->prefix; - cur_test_name = testcase->name; - } - -#ifndef NO_FORKING - if ((testcase->flags & TT_FORK) && !(opt_forked||opt_nofork)) { - outcome = testcase_run_forked_(group, testcase); - } else { -#else - { -#endif - outcome = testcase_run_bare_(testcase); - } - - if (outcome == OK) { - ++n_ok; - if (opt_verbosity>0 && !opt_forked) - puts(opt_verbosity==1?"OK":""); - } else if (outcome == SKIP) { - ++n_skipped; - if (opt_verbosity>0 && !opt_forked) - puts("SKIPPED"); - } else { - ++n_bad; - if (!opt_forked) - printf("\n [%s FAILED]\n", testcase->name); - } - - if (opt_forked) { - exit(outcome==OK ? 0 : (outcome==SKIP?MAGIC_EXITCODE : 1)); - return 1; /* unreachable */ - } else { - return (int)outcome; - } -} - -int -tinytest_set_flag_(struct testgroup_t *groups, const char *arg, int set, unsigned long flag) -{ - int i, j; - size_t length = LONGEST_TEST_NAME; - char fullname[LONGEST_TEST_NAME]; - int found=0; - if (strstr(arg, "..")) - length = strstr(arg,"..")-arg; - for (i=0; groups[i].prefix; ++i) { - for (j=0; groups[i].cases[j].name; ++j) { - struct testcase_t *testcase = &groups[i].cases[j]; - snprintf(fullname, sizeof(fullname), "%s%s", - groups[i].prefix, testcase->name); - if (!flag) { /* Hack! */ - printf(" %s", fullname); - if (testcase->flags & TT_OFF_BY_DEFAULT) - puts(" (Off by default)"); - else if (testcase->flags & TT_SKIP) - puts(" (DISABLED)"); - else - puts(""); - } - if (!strncmp(fullname, arg, length)) { - if (set) - testcase->flags |= flag; - else - testcase->flags &= ~flag; - ++found; - } - } - } - return found; -} - -static void -usage(struct testgroup_t *groups, int list_groups) -{ - puts("Options are: [--verbose|--quiet|--terse] [--no-fork]"); - puts(" Specify tests by name, or using a prefix ending with '..'"); - puts(" To skip a test, prefix its name with a colon."); - puts(" To enable a disabled test, prefix its name with a plus."); - puts(" Use --list-tests for a list of tests."); - if (list_groups) { - puts("Known tests are:"); - tinytest_set_flag_(groups, "..", 1, 0); - } - exit(0); -} - -static int -process_test_alias(struct testgroup_t *groups, const char *test) -{ - int i, j, n, r; - for (i=0; cfg_aliases && cfg_aliases[i].name; ++i) { - if (!strcmp(cfg_aliases[i].name, test)) { - n = 0; - for (j = 0; cfg_aliases[i].tests[j]; ++j) { - r = process_test_option(groups, cfg_aliases[i].tests[j]); - if (r<0) - return -1; - n += r; - } - return n; - } - } - printf("No such test alias as @%s!",test); - return -1; -} - -static int -process_test_option(struct testgroup_t *groups, const char *test) -{ - int flag = TT_ENABLED_; - int n = 0; - if (test[0] == '@') { - return process_test_alias(groups, test + 1); - } else if (test[0] == ':') { - ++test; - flag = TT_SKIP; - } else if (test[0] == '+') { - ++test; - ++n; - if (!tinytest_set_flag_(groups, test, 0, TT_OFF_BY_DEFAULT)) { - printf("No such test as %s!\n", test); - return -1; - } - } else { - ++n; - } - if (!tinytest_set_flag_(groups, test, 1, flag)) { - printf("No such test as %s!\n", test); - return -1; - } - return n; -} - -void -tinytest_set_aliases(const struct testlist_alias_t *aliases) -{ - cfg_aliases = aliases; -} - -int -tinytest_main(int c, const char **v, struct testgroup_t *groups) -{ - int i, j, n=0; - -#ifdef _WIN32 - const char *sp = strrchr(v[0], '.'); - const char *extension = ""; - if (!sp || stricmp(sp, ".exe")) - extension = ".exe"; /* Add an exe so CreateProcess will work */ - snprintf(commandname, sizeof(commandname), "%s%s", v[0], extension); - commandname[MAX_PATH]='\0'; -#endif - for (i=1; i= 1) - printf("%d tests ok. (%d skipped)\n", n_ok, n_skipped); - - return (n_bad == 0) ? 0 : 1; -} - -int -tinytest_get_verbosity_(void) -{ - return opt_verbosity; -} - -void -tinytest_set_test_failed_(void) -{ - if (opt_verbosity <= 0 && cur_test_name) { - if (opt_verbosity==0) puts(""); - printf("%s%s: ", cur_test_prefix, cur_test_name); - cur_test_name = NULL; - } - cur_test_outcome = 0; -} - -void -tinytest_set_test_skipped_(void) -{ - if (cur_test_outcome==OK) - cur_test_outcome = SKIP; -} diff --git a/lib/tinytest/tinytest.h b/lib/tinytest/tinytest.h deleted file mode 100644 index dff440e3190..00000000000 --- a/lib/tinytest/tinytest.h +++ /dev/null @@ -1,98 +0,0 @@ -/* tinytest.h -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYTEST_H_INCLUDED_ -#define TINYTEST_H_INCLUDED_ - -/** Flag for a test that needs to run in a subprocess. */ -#define TT_FORK (1<<0) -/** Runtime flag for a test we've decided to skip. */ -#define TT_SKIP (1<<1) -/** Internal runtime flag for a test we've decided to run. */ -#define TT_ENABLED_ (1<<2) -/** Flag for a test that's off by default. */ -#define TT_OFF_BY_DEFAULT (1<<3) -/** If you add your own flags, make them start at this point. */ -#define TT_FIRST_USER_FLAG (1<<4) - -typedef void (*testcase_fn)(void *); - -struct testcase_t; - -/** Functions to initialize/teardown a structure for a testcase. */ -struct testcase_setup_t { - /** Return a new structure for use by a given testcase. */ - void *(*setup_fn)(const struct testcase_t *); - /** Clean/free a structure from setup_fn. Return 1 if ok, 0 on err. */ - int (*cleanup_fn)(const struct testcase_t *, void *); -}; - -/** A single test-case that you can run. */ -struct testcase_t { - const char *name; /**< An identifier for this case. */ - testcase_fn fn; /**< The function to run to implement this case. */ - unsigned long flags; /**< Bitfield of TT_* flags. */ - const struct testcase_setup_t *setup; /**< Optional setup/cleanup fns*/ - void *setup_data; /**< Extra data usable by setup function */ -}; -#define END_OF_TESTCASES { NULL, NULL, 0, NULL, NULL } - -/** A group of tests that are selectable together. */ -struct testgroup_t { - const char *prefix; /**< Prefix to prepend to testnames. */ - struct testcase_t *cases; /** Array, ending with END_OF_TESTCASES */ -}; -#define END_OF_GROUPS { NULL, NULL} - -struct testlist_alias_t { - const char *name; - const char **tests; -}; -#define END_OF_ALIASES { NULL, NULL } - -/** Implementation: called from a test to indicate failure, before logging. */ -void tinytest_set_test_failed_(void); -/** Implementation: called from a test to indicate that we're skipping. */ -void tinytest_set_test_skipped_(void); -/** Implementation: return 0 for quiet, 1 for normal, 2 for loud. */ -int tinytest_get_verbosity_(void); -/** Implementation: Set a flag on tests matching a name; returns number - * of tests that matched. */ -int tinytest_set_flag_(struct testgroup_t *, const char *, int set, unsigned long); - -/** Set all tests in 'groups' matching the name 'named' to be skipped. */ -#define tinytest_skip(groups, named) \ - tinytest_set_flag_(groups, named, 1, TT_SKIP) - -/** Run a single testcase in a single group. */ -int testcase_run_one(const struct testgroup_t *,const struct testcase_t *); - -void tinytest_set_aliases(const struct testlist_alias_t *aliases); - -/** Run a set of testcases from an END_OF_GROUPS-terminated array of groups, - as selected from the command line. */ -int tinytest_main(int argc, const char **argv, struct testgroup_t *groups); - -#endif diff --git a/lib/tinytest/tinytest_macros.h b/lib/tinytest/tinytest_macros.h deleted file mode 100644 index 9ff69b1d506..00000000000 --- a/lib/tinytest/tinytest_macros.h +++ /dev/null @@ -1,184 +0,0 @@ -/* tinytest_macros.h -- Copyright 2009-2012 Nick Mathewson - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYTEST_MACROS_H_INCLUDED_ -#define TINYTEST_MACROS_H_INCLUDED_ - -/* Helpers for defining statement-like macros */ -#define TT_STMT_BEGIN do { -#define TT_STMT_END } while (0) - -/* Redefine this if your test functions want to abort with something besides - * "goto end;" */ -#ifndef TT_EXIT_TEST_FUNCTION -#define TT_EXIT_TEST_FUNCTION TT_STMT_BEGIN goto end; TT_STMT_END -#endif - -/* Redefine this if you want to note success/failure in some different way. */ -#ifndef TT_DECLARE -#define TT_DECLARE(prefix, args) \ - TT_STMT_BEGIN \ - printf("\n %s %s:%d: ",prefix,__FILE__,__LINE__); \ - printf args ; \ - TT_STMT_END -#endif - -/* Announce a failure. Args are parenthesized printf args. */ -#define TT_GRIPE(args) TT_DECLARE("FAIL", args) - -/* Announce a non-failure if we're verbose. */ -#define TT_BLATHER(args) \ - TT_STMT_BEGIN \ - if (tinytest_get_verbosity_()>1) TT_DECLARE(" OK", args); \ - TT_STMT_END - -#define TT_DIE(args) \ - TT_STMT_BEGIN \ - tinytest_set_test_failed_(); \ - TT_GRIPE(args); \ - TT_EXIT_TEST_FUNCTION; \ - TT_STMT_END - -#define TT_FAIL(args) \ - TT_STMT_BEGIN \ - tinytest_set_test_failed_(); \ - TT_GRIPE(args); \ - TT_STMT_END - -/* Fail and abort the current test for the reason in msg */ -#define tt_abort_printf(msg) TT_DIE(msg) -#define tt_abort_perror(op) TT_DIE(("%s: %s [%d]",(op),strerror(errno), errno)) -#define tt_abort_msg(msg) TT_DIE(("%s", msg)) -#define tt_abort() TT_DIE(("%s", "(Failed.)")) - -/* Fail but do not abort the current test for the reason in msg. */ -#define tt_failprint_f(msg) TT_FAIL(msg) -#define tt_fail_perror(op) TT_FAIL(("%s: %s [%d]",(op),strerror(errno), errno)) -#define tt_fail_msg(msg) TT_FAIL(("%s", msg)) -#define tt_fail() TT_FAIL(("%s", "(Failed.)")) - -/* End the current test, and indicate we are skipping it. */ -#define tt_skip() \ - TT_STMT_BEGIN \ - tinytest_set_test_skipped_(); \ - TT_EXIT_TEST_FUNCTION; \ - TT_STMT_END - -#define tt_want_(b, msg, fail) \ - TT_STMT_BEGIN \ - if (!(b)) { \ - tinytest_set_test_failed_(); \ - TT_GRIPE(("%s",msg)); \ - fail; \ - } else { \ - TT_BLATHER(("%s",msg)); \ - } \ - TT_STMT_END - -/* Assert b, but do not stop the test if b fails. Log msg on failure. */ -#define tt_want_msg(b, msg) \ - tt_want_(b, msg, ); - -/* Assert b and stop the test if b fails. Log msg on failure. */ -#define tt_assert_msg(b, msg) \ - tt_want_(b, msg, TT_EXIT_TEST_FUNCTION); - -/* Assert b, but do not stop the test if b fails. */ -#define tt_want(b) tt_want_msg( (b), "want("#b")") -/* Assert b, and stop the test if b fails. */ -#define tt_assert(b) tt_assert_msg((b), "assert("#b")") - -#define tt_assert_test_fmt_type(a,b,str_test,type,test,printf_type,printf_fmt, \ - setup_block,cleanup_block,die_on_fail) \ - TT_STMT_BEGIN \ - type val1_ = (type)(a); \ - type val2_ = (type)(b); \ - int tt_status_ = (test); \ - if (!tt_status_ || tinytest_get_verbosity_()>1) { \ - printf_type print_; \ - printf_type print1_; \ - printf_type print2_; \ - type value_ = val1_; \ - setup_block; \ - print1_ = print_; \ - value_ = val2_; \ - setup_block; \ - print2_ = print_; \ - TT_DECLARE(tt_status_?" OK":"FAIL", \ - ("assert(%s): "printf_fmt" vs "printf_fmt, \ - str_test, print1_, print2_)); \ - print_ = print1_; \ - cleanup_block; \ - print_ = print2_; \ - cleanup_block; \ - if (!tt_status_) { \ - tinytest_set_test_failed_(); \ - die_on_fail ; \ - } \ - } \ - TT_STMT_END - -#define tt_assert_test_type(a,b,str_test,type,test,fmt,die_on_fail) \ - tt_assert_test_fmt_type(a,b,str_test,type,test,type,fmt, \ - {print_=value_;},{},die_on_fail) - -/* Helper: assert that a op b, when cast to type. Format the values with - * printf format fmt on failure. */ -#define tt_assert_op_type(a,op,b,type,fmt) \ - tt_assert_test_type(a,b,#a" "#op" "#b,type,(val1_ op val2_),fmt, \ - TT_EXIT_TEST_FUNCTION) - -#define tt_int_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_), \ - "%ld",TT_EXIT_TEST_FUNCTION) - -#define tt_uint_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ - (val1_ op val2_),"%lu",TT_EXIT_TEST_FUNCTION) - -#define tt_ptr_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,void*, \ - (val1_ op val2_),"%p",TT_EXIT_TEST_FUNCTION) - -#define tt_str_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \ - (strcmp(val1_,val2_) op 0),"<%s>",TT_EXIT_TEST_FUNCTION) - -#define tt_want_int_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,long,(val1_ op val2_),"%ld",(void)0) - -#define tt_want_uint_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,unsigned long, \ - (val1_ op val2_),"%lu",(void)0) - -#define tt_want_ptr_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,void*, \ - (val1_ op val2_),"%p",(void)0) - -#define tt_want_str_op(a,op,b) \ - tt_assert_test_type(a,b,#a" "#op" "#b,const char *, \ - (strcmp(val1_,val2_) op 0),"<%s>",(void)0) - -#endif diff --git a/lib/tinyusb b/lib/tinyusb index 5217cee5de4..5453ed09f19 160000 --- a/lib/tinyusb +++ b/lib/tinyusb @@ -1 +1 @@ -Subproject commit 5217cee5de4cd555018da90f9f1bcc87fb1c1d3a +Subproject commit 5453ed09f19af010b6a361562d967cfa30aaadc6 diff --git a/locale/ID.po b/locale/ID.po index 1eeba013506..ca862a97147 100644 --- a/locale/ID.po +++ b/locale/ID.po @@ -6,15 +6,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-16 15:03+0000\n" -"Last-Translator: Scott Shawcroft \n" +"PO-Revision-Date: 2026-02-13 15:09+0000\n" +"Last-Translator: Arif Budiman \n" "Language-Team: LANGUAGE \n" "Language: ID\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.2\n" +"X-Generator: Weblate 5.16-dev\n" #: main.c msgid "" @@ -29,6 +29,8 @@ msgid "" "\n" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"Kode dihentikan karena pemuatan ulang otomatis. Akan segera dimuat ulang.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -36,18 +38,25 @@ msgid "" "Please file an issue with your program at github.com/adafruit/circuitpython/" "issues." msgstr "" +"\n" +"Silakan laporkan masalah dengan program Anda di github.com/adafruit/" +"sirkuitpython/issues." #: supervisor/shared/safe_mode.c msgid "" "\n" "Press reset to exit safe mode.\n" msgstr "" +"\n" +"Tekan reset untuk keluar dari mode aman.\n" #: supervisor/shared/safe_mode.c msgid "" "\n" "You are in safe mode because:\n" msgstr "" +"\n" +"Anda berada dalam mode aman karena:\n" #: py/obj.c msgid " File \"%q\"" @@ -67,7 +76,7 @@ msgstr " tidak ketemu.\n" #: main.c msgid " output:\n" -msgstr "output:\n" +msgstr " output:\n" #: py/objstr.c #, c-format @@ -85,17 +94,17 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "%q dan %q berisi pin duplikat" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" -msgstr "" +msgstr "%q dan %q harus berbeda" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "%q and %q must share a clock unit" -msgstr "" +msgstr "%q dan %q harus berbagi unit jam" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "%q cannot be changed once mode is set to %q" -msgstr "" +msgstr "%q tidak dapat diubah setelah mode diatur ke %q" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -105,9 +114,13 @@ msgstr "%q berisi pin duplikat" msgid "%q failure: %d" msgstr "%q gagal: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q dalam %q harus bertipe %q atau %q, bukan %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" -msgstr "" +msgstr "%q dalam %q harus bertipe %q, bukan %q" #: ports/espressif/common-hal/espulp/ULP.c #: ports/mimxrt10xx/common-hal/audiobusio/__init__.c @@ -131,19 +144,19 @@ msgstr "indeks %q harus bilangan bulat, bukan %s" #: shared-module/bitbangio/SPI.c msgid "%q init failed" -msgstr "" +msgstr "%q inisiasi gagal" #: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c msgid "%q is %q" -msgstr "" +msgstr "%q adalah %q" #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "%q is read-only for this board" -msgstr "" +msgstr "%q hanya dapat dibaca untuk papan ini" #: py/argcheck.c shared-bindings/usb_hid/Device.c msgid "%q length must be %d" -msgstr "" +msgstr "%q panjangnya harus %d" #: py/argcheck.c msgid "%q length must be %d-%d" @@ -151,19 +164,19 @@ msgstr "%q panjang harus %d-%d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "%q panjangnya harus <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" +msgstr "%q panjangnya harus >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" -msgstr "" +msgstr "%q dipindahkan dari %q ke %q" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q harusnya %d" #: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/displayio/Bitmap.c @@ -175,7 +188,7 @@ msgstr "%q harus %d-%d" #: shared-bindings/busdisplay/BusDisplay.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "%q harus 1 ketika %q bernilai Benar" #: py/argcheck.c shared-bindings/gifio/GifWriter.c #: shared-module/gifio/OnDiskGif.c @@ -184,7 +197,7 @@ msgstr "%q harus <= %d" #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "%q must be <= %u" -msgstr "" +msgstr "%q harus <= %u" #: py/argcheck.c msgid "%q must be >= %d" @@ -192,43 +205,45 @@ msgstr "%q harus >= %d" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "" +msgstr "%q harus berupa bytearray atau array bertipe 'H' atau 'B'" #: shared-bindings/audiocore/RawSample.c msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -msgstr "" +msgstr "%q harus berupa bytearray atau array bertipe 'h', 'H', 'b', atau 'B'" #: shared-bindings/warnings/__init__.c msgid "%q must be a subclass of %q" -msgstr "" +msgstr "%q harus menjadi subkelas dari %q" #: ports/espressif/common-hal/analogbufio/BufferedIn.c msgid "%q must be array of type 'H'" -msgstr "" +msgstr "%q harus berupa array bertipe 'H'" #: shared-module/synthio/__init__.c msgid "%q must be array of type 'h'" -msgstr "" +msgstr "%q harus berupa array bertipe 'h'" #: shared-bindings/audiobusio/PDMIn.c msgid "%q must be multiple of 8." -msgstr "" +msgstr "%q harus kelipatan 8." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" -msgstr "" +msgstr "%q harus bertipe %q atau %q, bukan %q" #: shared-bindings/jpegio/JpegDecoder.c msgid "%q must be of type %q, %q, or %q, not %q" -msgstr "" +msgstr "%q harus bertipe %q, %q, atau %q, bukan %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" -msgstr "" +msgstr "%q harus dari tipe %q, bukan %q" #: ports/atmel-samd/common-hal/busio/UART.c msgid "%q must be power of 2" @@ -236,7 +251,7 @@ msgstr "%q harus pangkat 2" #: shared-bindings/wifi/Monitor.c msgid "%q out of bounds" -msgstr "" +msgstr "%q di luar batas" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c #: ports/cxd56/common-hal/pulseio/PulseIn.c @@ -249,15 +264,15 @@ msgstr "%q di luar jangkauan" #: py/objmodule.c py/runtime.c msgid "%q renamed %q" -msgstr "" +msgstr "%q berganti nama menjadi %q" #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" -msgstr "" +msgstr "%q step tidak boleh nol" #: shared-module/bitbangio/I2C.c msgid "%q too long" -msgstr "" +msgstr "%q terlalu panjang" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -265,31 +280,32 @@ msgstr "%q() mengambil posisi argumen %d tapi %d yang diberikan" #: shared-module/jpegio/JpegDecoder.c msgid "%q() without %q()" -msgstr "" +msgstr "%q() tanpa %q()" #: shared-bindings/usb_hid/Device.c msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, dan %q semuanya harus memiliki panjang yang sama" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" -msgstr "" +msgstr "%q=%q" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "%q[%u] shifts in more bits than pin count" -msgstr "" +msgstr "%q[%u] berpindah lebih banyak bit daripada jumlah pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "%q[%u] shifts out more bits than pin count" -msgstr "" +msgstr "%q[%u] menggeser lebih banyak bit daripada jumlah pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "%q[%u] uses extra pin" -msgstr "" +msgstr "%q[%u] menggunakan pin tambahan" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "%q[%u] waits on input outside of count" -msgstr "" +msgstr "%q[%u] menunggu input di luar hitungan" #: ports/espressif/common-hal/espidf/__init__.c #, c-format @@ -305,7 +321,7 @@ msgid "'%q' object does not support '%q'" msgstr "Objek '%q' tidak mendukung '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "Objek '%q' bukan merupakan iterator" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -313,7 +329,7 @@ msgid "'%q' object is not callable" msgstr "Objek '%q' tidak dapat dipanggil" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "Objek '%q' tidak dapat diulang" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -364,17 +380,17 @@ msgstr "'%s' integer %d tidak berada dalam jangkauan %d..%d" #: py/emitinlinethumb.c #, c-format msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" -msgstr "" +msgstr "'%s' Integer 0x%x tidak cocok dengan mask 0x%x" #: py/obj.c #, c-format msgid "'%s' object doesn't support item assignment" -msgstr "" +msgstr "Objek '%s' tidak mendukung penetapan item" #: py/obj.c #, c-format msgid "'%s' object doesn't support item deletion" -msgstr "" +msgstr "Objek '%s' tidak mendukung penghapusan item" #: py/runtime.c msgid "'%s' object has no attribute '%q'" @@ -383,7 +399,7 @@ msgstr "Objek '%s' tidak memiliki atribut '%q'" #: py/obj.c #, c-format msgid "'%s' object isn't subscriptable" -msgstr "" +msgstr "Objek '%s' tidak dapat dijadikan subskrip" #: py/objstr.c msgid "'=' alignment not allowed in string format specifier" @@ -403,7 +419,7 @@ msgstr "'await' diluar fungsi" #: py/compile.c msgid "'break'/'continue' outside loop" -msgstr "" +msgstr "'break'/'continue' di luar loop" #: py/compile.c msgid "'data' requires at least 2 arguments" @@ -419,7 +435,7 @@ msgstr "'label' membutuhkan 1 argumen" #: py/emitnative.c msgid "'not' not implemented" -msgstr "" +msgstr "'not' tidak diimplementasikan" #: py/compile.c msgid "'return' outside function" @@ -435,7 +451,7 @@ msgstr "'yield' diluar fungsi" #: py/compile.c msgid "* arg after **" -msgstr "" +msgstr "* arg setelah **" #: py/compile.c msgid "*x must be assignment target" @@ -449,7 +465,7 @@ msgstr ", dalam %q\n" #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid ".show(x) removed. Use .root_group = x" -msgstr "" +msgstr ".show(x) dihapus. Gunakan .root_group = x" #: py/objcomplex.c msgid "0.0 to a complex power" @@ -461,7 +477,7 @@ msgstr "pow() 3-arg tidak didukung" #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "AP could not be started" -msgstr "" +msgstr "AP tidak dapat dimulai" #: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format @@ -472,15 +488,15 @@ msgstr "Alamat harus sepanjang %d byte" #: ports/nordic/common-hal/memorymap/AddressRange.c #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Address range not allowed" -msgstr "" +msgstr "Rentang alamat tidak diizinkan" #: shared-bindings/memorymap/AddressRange.c msgid "Address range wraps around" -msgstr "" +msgstr "Rentang alamat melingkar" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" -msgstr "" +msgstr "Semua peripheral CAN sedang digunakan" #: ports/espressif/common-hal/busio/I2C.c #: ports/espressif/common-hal/i2ctarget/I2CTarget.c @@ -506,11 +522,11 @@ msgstr "Semua perangkat UART sedang digunakan" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c msgid "All channels in use" -msgstr "" +msgstr "Semua saluran sedang digunakan" #: ports/raspberrypi/common-hal/usb_host/Port.c msgid "All dma channels in use" -msgstr "" +msgstr "Semua saluran dma sedang digunakan" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "All event channels in use" @@ -521,7 +537,7 @@ msgstr "Semua channel event sedang digunakan" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/usb_host/Port.c msgid "All state machines in use" -msgstr "" +msgstr "Semua mesin status yang digunakan" #: ports/atmel-samd/audio_dma.c msgid "All sync event channels in use" @@ -540,7 +556,6 @@ msgstr "Semua timer untuk pin ini sedang digunakan" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Semua timer sedang digunakan" @@ -551,28 +566,33 @@ msgstr "Sudah disebarkan." #: ports/atmel-samd/common-hal/canio/Listener.c msgid "Already have all-matches listener" -msgstr "" +msgstr "Sudah memiliki listener semua-kecocokan" + +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Sudah dalam proses" #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c #: shared-module/memorymonitor/AllocationSize.c msgid "Already running" -msgstr "" +msgstr "Sudah berjalan" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" -msgstr "" +msgstr "Sudah memindai jaringan wifi" #: shared-module/os/getenv.c #, c-format msgid "An error occurred while retrieving '%s':\n" -msgstr "" +msgstr "Terjadi kesalahan saat mengambil '%s':\n" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Another PWMAudioOut is already active" -msgstr "" +msgstr "PWMAudioOut lainnya sudah aktif" #: ports/atmel-samd/common-hal/pulseio/PulseOut.c #: ports/cxd56/common-hal/pulseio/PulseOut.c @@ -588,22 +608,31 @@ msgstr "Array harus mengandung halfwords (ketik 'H')" msgid "Array values should be single bytes." msgstr "Nilai array harus berupa byte tunggal." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "Transfer SPI async sedang berlangsung pada bus ini, terus menunggu." + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" -msgstr "" +msgstr "Mencoba mengalokasikan %d blok" #: ports/raspberrypi/audio_dma.c msgid "Audio conversion not implemented" -msgstr "" +msgstr "Konversi audio belum diimplementasikan" + +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Kesalahan sumber audio" #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" -msgstr "" +msgstr "AuthMode.OPEN tidak digunakan dengan kata sandi" #: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c msgid "Authentication failure" -msgstr "" +msgstr "Kegagalan otentikasi" #: main.c msgid "Auto-reload is off.\n" @@ -619,7 +648,7 @@ msgstr "" #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" -msgstr "" +msgstr "Baudrate tidak didukung oleh periferal" #: shared-module/busdisplay/BusDisplay.c #: shared-module/framebufferio/FramebufferDisplay.c @@ -628,19 +657,19 @@ msgstr "Di bawah frame rate minimum" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must be sequential GPIO pins" -msgstr "" +msgstr "Jam bit dan pemilihan kata harus berupa pin GPIO berurutan" #: shared-bindings/bitmaptools/__init__.c msgid "Bitmap size and bits per value must match" -msgstr "" +msgstr "Ukuran bitmap dan bit per nilai harus cocok" #: supervisor/shared/safe_mode.c msgid "Boot device must be first (interface #0)." -msgstr "" +msgstr "Perangkat boot harus menjadi yang pertama (interface #0)." #: ports/mimxrt10xx/common-hal/busio/UART.c msgid "Both RX and TX required for flow control" -msgstr "" +msgstr "RX dan TX diperlukan untuk kontrol aliran" #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c @@ -654,7 +683,7 @@ msgstr "Buffer + offset terlalu kecil %d %d %d" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Buffer elements must be 4 bytes long or less" -msgstr "" +msgstr "Elemen buffer harus berukuran panjang 4 byte atau kurang" #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Buffer is not a bytearray." @@ -672,7 +701,7 @@ msgstr "Panjang buffer %d terlalu besar. Itu harus kurang dari %d" #: shared-module/sdcardio/SDCard.c #, c-format msgid "Buffer must be a multiple of %d bytes" -msgstr "" +msgstr "Buffer harus kelipatan %d byte" #: shared-bindings/_bleio/PacketBuffer.c #, c-format @@ -684,7 +713,7 @@ msgstr "Buffer terlalu pendek untuk %d byte" #: shared-bindings/framebufferio/FramebufferDisplay.c #: shared-bindings/struct/__init__.c shared-module/struct/__init__.c msgid "Buffer too small" -msgstr "" +msgstr "Buffer terlalu kecil" #: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c #: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c @@ -704,11 +733,11 @@ msgstr "Blok CBC harus merupakan kelipatan 16 byte" #: supervisor/shared/safe_mode.c msgid "CIRCUITPY drive could not be found or created." -msgstr "" +msgstr "Drive CIRCUITPY tidak bisa ditemukan atau dibuat." #: ports/espressif/common-hal/espidf/__init__.c msgid "CRC or checksum was invalid" -msgstr "" +msgstr "CRC atau checksum tidak valid" #: py/objtype.c msgid "Call super().__init__() before accessing native object." @@ -716,19 +745,29 @@ msgstr "Panggil super().__init__() sebelum mengakses objek asli." #: ports/cxd56/common-hal/camera/Camera.c msgid "Camera init" -msgstr "" +msgstr "Inisialisasi kamera" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on RTC IO from deep sleep." msgstr "" +"Hanya dapat mengaktifkan alarm pada RTC IO dari mode tidur dalam (deep " +"sleep)." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" +"Hanya dapat mengaktifkan alarm pada satu pin rendah sementara pin lainnya " +"dalam keadaan tinggi dari mode tidur dalam (deep sleep)." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on two low pins from deep sleep." msgstr "" +"Hanya dapat mengaktifkan alarm pada dua pin rendah dari mode tidur dalam " +"(deep sleep)." + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "Tidak dapat membuat AudioOut karena kanal berkelanjutan sudah terbuka" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c @@ -739,11 +778,11 @@ msgstr "Tidak dapat mengatur CCCD pada Karakteristik lokal" #: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c #: shared-bindings/usb_video/__init__.c msgid "Cannot change USB devices now" -msgstr "" +msgstr "Tidak dapat mengganti perangkat USB saat ini" #: shared-bindings/_bleio/Adapter.c msgid "Cannot create a new Adapter; use _bleio.adapter;" -msgstr "" +msgstr "Tidak dapat membuat Adapter baru; gunakan _bleio.adapter;" #: shared-bindings/displayio/Bitmap.c #: shared-bindings/memorymonitor/AllocationSize.c @@ -770,15 +809,15 @@ msgstr "" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." -msgstr "" +msgstr "Tidak dapat menarik pin input saja." #: shared-bindings/audiobusio/PDMIn.c msgid "Cannot record to a file" msgstr "Tidak dapat merekam ke file" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "" +msgid "Cannot remount path when visible via USB." +msgstr "Tidak dapat me-remount jalur ketika terlihat melalui USB." #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -793,13 +832,17 @@ msgstr "Tidak dapat menentukan RTS atau CTS dalam mode RS485" msgid "Cannot subclass slice" msgstr "Tidak dapat membuat subkelas dari irisan" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "Tidak dapat menggunakan GPIO0..15 bersamaan dengan GPIO32..47" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" -msgstr "" +msgstr "Tidak dapat bangun di tepi pin, hanya level" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." -msgstr "" +msgstr "Tidak dapat bergerak di tepi pin. Hanya level." #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" @@ -822,15 +865,19 @@ msgstr "" #: shared-bindings/bitmaptools/__init__.c msgid "Coordinate arrays have different lengths" -msgstr "" +msgstr "Deretan koordinat memiliki panjang yang berbeda" #: shared-bindings/bitmaptools/__init__.c msgid "Coordinate arrays types have different sizes" -msgstr "" +msgstr "Tipe array koordinat memiliki ukuran yang berbeda" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "Tidak dapat mempublikasikan ke topik ROS" #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" -msgstr "" +msgstr "Tidak dapat mengatur alamat" #: ports/stm/common-hal/busio/UART.c msgid "Could not start interrupt, RX busy" @@ -840,6 +887,11 @@ msgstr "Tidak dapat memulai interupsi, RX sibuk" msgid "Couldn't allocate decoder" msgstr "Tidak dapat mengalokasikan dekoder" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "Kegagalan ROS kritis selama soft reboot, reset diperlukan: %d" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Terjadi kesalahan saat menginisialisasi kanal DAC" @@ -857,18 +909,14 @@ msgstr "DAC sudah digunakan" msgid "Data 0 pin must be byte aligned" msgstr "Data 0 pin harus byte disejajarkan" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Potongan data harus mengikuti fmt chunk" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" -msgstr "" +msgstr "Kesalahan format data (mungkin data rusak)" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Data not supported with directed advertising" -msgstr "" +msgstr "Data tidak didukung dengan iklan terarah" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c @@ -878,6 +926,8 @@ msgstr "Data terlalu besar untuk paket advertisment" #: ports/stm/common-hal/alarm/pin/PinAlarm.c msgid "Deep sleep pins must use a rising edge with pulldown" msgstr "" +"Pin tidur dalam (deep sleep) harus menggunakan tepi naik dengan penarik ke " +"bawah (pulldown)." #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." @@ -885,7 +935,7 @@ msgstr "Kapasitas tujuan lebih kecil dari destination_length." #: shared-module/jpegio/JpegDecoder.c msgid "Device error or wrong termination of input stream" -msgstr "" +msgstr "Kesalahan perangkat atau penghentian aliran input yang salah" #: ports/nordic/common-hal/audiobusio/I2SOut.c msgid "Device in use" @@ -904,7 +954,7 @@ msgstr "Rotasi tampilan harus dalam kelipatan 90 derajat" #: main.c msgid "Done" -msgstr "" +msgstr "Selesai" #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." @@ -912,7 +962,7 @@ msgstr "Mode kendara tidak digunakan saat arah input." #: py/obj.c msgid "During handling of the above exception, another exception occurred:" -msgstr "" +msgstr "Selama penanganan pengecualian di atas, pengecualian lain terjadi:" #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" @@ -921,7 +971,7 @@ msgstr "ECB hanya beroperasi pada 16 byte di satu waktu" #: ports/espressif/common-hal/busio/SPI.c #: ports/espressif/common-hal/canio/CAN.c msgid "ESP-IDF memory allocation failed" -msgstr "" +msgstr "Alokasi memori ESP-IDF gagal" #: extmod/modre.c msgid "Error in regex" @@ -929,11 +979,11 @@ msgstr "Error pada regex" #: supervisor/shared/safe_mode.c msgid "Error in safemode.py." -msgstr "" +msgstr "Kesalahan dalam safemode.py." #: shared-bindings/alarm/__init__.c msgid "Expected a kind of %q" -msgstr "" +msgstr "Diharapkan semacam %q" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c @@ -946,7 +996,7 @@ msgstr "FFT didefinisikan hanya untuk ndarrays" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "FFT is implemented for linear arrays only" -msgstr "" +msgstr "FFT diimplementasikan hanya untuk array linier" #: shared-bindings/ps2io/Ps2.c msgid "Failed sending command." @@ -959,28 +1009,30 @@ msgstr "Gagal memperoleh mutex, err 0x%04x" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Failed to add service TXT record" -msgstr "" +msgstr "Gagal menambahkan record TXT layanan" #: shared-bindings/mdns/Server.c msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" +"Gagal menambahkan record TXT layanan; ditemukan non-string atau bytes dalam " +"txt_records" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" -msgstr "" +msgstr "Gagal mengalokasikan buffer %q" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" -msgstr "" +msgstr "Gagal mengalokasikan memori Wifi" #: ports/espressif/common-hal/wifi/ScannedNetworks.c msgid "Failed to allocate wifi scan memory" -msgstr "" +msgstr "Gagal mengalokasikan memori pemindaian wifi" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Failed to buffer the sample" -msgstr "" +msgstr "Gagal membuffer sampel" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c @@ -991,15 +1043,47 @@ msgstr "Gagal terhubung: kesalahan internal" msgid "Failed to connect: timeout" msgstr "Gagal terhubung: habis waktu" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "Gagal membuat kanal berkelanjutan: argumen tidak valid" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "Gagal membuat kanal berkelanjutan: status tidak valid" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Gagal membuat kanal berkelanjutan: tidak ada memori" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Gagal membuat kanal berkelanjutan: tidak ditemukan" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Gagal mengaktifkan berkelanjutan" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Gagal mengurai file MP3" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Gagal mendaftarkan callback event berkelanjutan" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Gagal melepaskan mutex, err 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "Gagal menetapkan hostname" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Gagal memulai audio async" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Gagal menulis flash internal." @@ -1008,44 +1092,47 @@ msgstr "Gagal menulis flash internal." msgid "File exists" msgstr "File sudah ada" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" -msgstr "" +msgstr "File tidak ditemukan" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" -msgstr "" +msgstr "Filter terlalu kompleks" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is duplicate" -msgstr "" +msgstr "Firmware adalah duplikat" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is invalid" -msgstr "" +msgstr "Firmware tidak valid" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is too big" -msgstr "" +msgstr "Firmware terlalu besar" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" -msgstr "" +msgstr "Untuk colorspace L8, bitmap input harus memiliki 8 bit per piksel" #: shared-bindings/bitmaptools/__init__.c msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" -msgstr "" +msgstr "Untuk colorspace RGB, bitmap input harus memiliki 16 bit per piksel" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" -msgstr "" +msgstr "Format tidak didukung" #: ports/mimxrt10xx/common-hal/microcontroller/Processor.c msgid "" "Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" +"Frekuensi harus 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 atau 1008 Mhz" #: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c #: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c @@ -1054,11 +1141,11 @@ msgstr "Fungsinya membutuhkan kunci" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" -msgstr "" +msgstr "Inisialisasi GNSS" #: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" -msgstr "" +msgstr "Kegagalan Umum" #: shared-bindings/framebufferio/FramebufferDisplay.c #: shared-module/busdisplay/BusDisplay.c @@ -1068,7 +1155,7 @@ msgstr "Grup sudah digunakan" #: supervisor/shared/safe_mode.c msgid "Hard fault: memory access or instruction error." -msgstr "" +msgstr "Hard fault: kesalahan akses memori atau instruksi." #: ports/mimxrt10xx/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c @@ -1079,7 +1166,7 @@ msgstr "Perangkat keras sedang digunakan, coba pin alternatif" #: supervisor/shared/safe_mode.c msgid "Heap allocation when VM not running." -msgstr "" +msgstr "Alokasi heap ketika VM tidak berjalan." #: extmod/vfs_posix_file.c py/objstringio.c msgid "I/O operation on closed file" @@ -1087,16 +1174,16 @@ msgstr "operasi I/O pada file tertutup" #: ports/stm/common-hal/busio/I2C.c msgid "I2C init error" -msgstr "" +msgstr "Kesalahan inisialisasi I2C" #: ports/raspberrypi/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "I2C peripheral in use" -msgstr "" +msgstr "Periferal I2C sedang digunakan" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "In-buffer elements must be <= 4 bytes long" -msgstr "" +msgstr "Elemen in-buffer harus <= 4 byte panjangnya" #: shared-bindings/_pew/PewPew.c msgid "Incorrect buffer size" @@ -1104,24 +1191,25 @@ msgstr "Ukuran penyangga salah" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Init program size invalid" -msgstr "" +msgstr "Ukuran program inisialisasi tidak valid" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Initial set pin direction conflicts with initial out pin direction" -msgstr "" +msgstr "Arah pin set awal berkonflik dengan arah pin out awal" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Initial set pin state conflicts with initial out pin state" -msgstr "" +msgstr "Status pin set awal berkonflik dengan status pin out awal" #: shared-bindings/bitops/__init__.c #, c-format msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" msgstr "" +"Panjang buffer input (%d) harus merupakan kelipatan dari jumlah strand (%d)" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" -msgstr "" +msgstr "Input memakan waktu terlalu lama" #: py/moderrno.c msgid "Input/output error" @@ -1139,19 +1227,20 @@ msgstr "Enkripsi tidak cukup" #: shared-module/jpegio/JpegDecoder.c msgid "Insufficient memory pool for the image" -msgstr "" +msgstr "Pool memori tidak mencukupi untuk gambar" #: shared-module/jpegio/JpegDecoder.c msgid "Insufficient stream input buffer" -msgstr "" +msgstr "Buffer input stream tidak mencukupi" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" -msgstr "" +msgstr "Interface harus dimulai" #: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c msgid "Internal audio buffer too small" -msgstr "" +msgstr "Buffer audio internal terlalu kecil" #: ports/stm/common-hal/busio/UART.c msgid "Internal define error" @@ -1159,7 +1248,7 @@ msgstr "Kesalahan definisi internal" #: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c msgid "Internal error" -msgstr "" +msgstr "Kesalahan internal" #: shared-module/rgbmatrix/RGBMatrix.c #, c-format @@ -1177,19 +1266,19 @@ msgstr "Kesalahan internal #%d" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-bindings/pwmio/PWMOut.c msgid "Internal resource(s) in use" -msgstr "" +msgstr "Sumber daya internal sedang digunakan" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." -msgstr "" +msgstr "Timer watchdog internal kedaluwarsa." #: supervisor/shared/safe_mode.c msgid "Interrupt error." -msgstr "" +msgstr "Kesalahan interrupt." #: shared-module/jpegio/JpegDecoder.c msgid "Interrupted by output function" -msgstr "" +msgstr "Diinterupsi oleh fungsi output" #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c @@ -1201,14 +1290,16 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" -msgstr "" +msgstr "%q tidak valid" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-module/aurora_epaper/aurora_framebuffer.c msgid "Invalid %q and %q" -msgstr "" +msgstr "%q dan %q tidak valid" #: ports/atmel-samd/common-hal/microcontroller/Pin.c #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c @@ -1224,15 +1315,19 @@ msgstr "Nilai Unit ADC tidak valid" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid BLE parameter" -msgstr "" +msgstr "Parameter BLE tidak valid" #: shared-bindings/wifi/Radio.c msgid "Invalid BSSID" -msgstr "" +msgstr "BSSID tidak valid" #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" -msgstr "" +msgstr "Alamat MAC tidak valid" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "ID domain ROS tidak valid" #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" @@ -1245,16 +1340,16 @@ msgstr "Bit per nilai tidak valid" #: shared-module/os/getenv.c #, c-format msgid "Invalid byte %.*s" -msgstr "" +msgstr "Byte tidak valid %.*s" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "Invalid data_pins[%d]" -msgstr "" +msgstr "data_pins[%d] tidak valid" #: shared-module/msgpack/__init__.c msgid "Invalid format" -msgstr "" +msgstr "Format tidak valid" #: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" @@ -1262,27 +1357,29 @@ msgstr "Ukuran potongan format tidak valid" #: shared-bindings/wifi/Radio.c msgid "Invalid hex password" -msgstr "" +msgstr "Password hex tidak valid" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" -msgstr "" +msgstr "Alamat MAC multicast tidak valid" #: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" -msgstr "" +msgstr "Ukuran tidak valid" #: shared-module/ssl/SSLSocket.c msgid "Invalid socket for TLS" -msgstr "" +msgstr "Socket tidak valid untuk TLS" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" -msgstr "" +msgstr "Status tidak valid" #: shared-module/os/getenv.c msgid "Invalid unicode escape" -msgstr "" +msgstr "Escape unicode tidak valid" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" @@ -1290,11 +1387,11 @@ msgstr "Panjang kunci harus 16, 24, atau 32 byte" #: shared-module/os/getenv.c msgid "Key not found" -msgstr "" +msgstr "Kunci tidak ditemukan" #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" -msgstr "" +msgstr "Pemetaan LED harus sesuai dengan ukuran display" #: py/compile.c msgid "LHS of keyword arg must be an id" @@ -1302,77 +1399,84 @@ msgstr "LHS dari keyword arg harus menjadi sebuah id" #: shared-module/displayio/Group.c msgid "Layer already in a group" -msgstr "" +msgstr "Layer sudah ada dalam grup" #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass" -msgstr "" +msgstr "Layer harus merupakan subclass Group atau TileGrid" #: shared-bindings/audiocore/RawSample.c msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" +"Panjang %q harus merupakan kelipatan genap dari channel_count * type_size" #: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" -msgstr "" +msgstr "Alamat MAC tidak valid" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/espressif/common-hal/_bleio/Descriptor.c msgid "MITM security not supported" -msgstr "" +msgstr "Keamanan MITM tidak didukung" + +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "Kesalahan Clock MMC/SDIO %x" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" -msgstr "" +msgstr "Mapping harus berupa tuple" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" -msgstr "" +msgstr "Ukuran data tidak cocok" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched swap flag" -msgstr "" +msgstr "Flag swap tidak cocok" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing first_in_pin. %q[%u] reads pin(s)" -msgstr "" +msgstr "first_in_pin tidak ada. %q[%u] membaca pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" -msgstr "" +msgstr "first_in_pin tidak ada. %q[%u] melakukan shift in dari pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing first_in_pin. %q[%u] waits based on pin" -msgstr "" +msgstr "first_in_pin tidak ada. %q[%u] menunggu berdasarkan pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" -msgstr "" +msgstr "first_out_pin tidak ada. %q[%u] melakukan shift out ke pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing first_out_pin. %q[%u] writes pin(s)" -msgstr "" +msgstr "first_out_pin tidak ada. %q[%u] menulis pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing first_set_pin. %q[%u] sets pin(s)" -msgstr "" +msgstr "first_set_pin tidak ada. %q[%u] menetapkan pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing jmp_pin. %q[%u] jumps on pin" -msgstr "" +msgstr "jmp_pin tidak ada. %q[%u] melompat pada pin" #: shared-module/storage/__init__.c msgid "Mount point directory missing" -msgstr "" +msgstr "Direktori titik mount tidak ada" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Harus berupa subclass %q." #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c msgid "Must provide 5/6/5 RGB pins" -msgstr "" +msgstr "Harus menyediakan pin RGB 5/6/5" #: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c msgid "Must provide MISO or MOSI pin" @@ -1385,23 +1489,23 @@ msgstr "Harus menggunakan kelipatan 6 pin rgb, bukan %d" #: supervisor/shared/safe_mode.c msgid "NLR jump failed. Likely memory corruption." -msgstr "" +msgstr "Lompatan NLR gagal. Kemungkinan korupsi memori." #: ports/espressif/common-hal/nvm/ByteArray.c msgid "NVS Error" -msgstr "" +msgstr "Kesalahan NVS" #: shared-bindings/socketpool/SocketPool.c msgid "Name or service not known" -msgstr "" +msgstr "Nama atau layanan tidak diketahui" #: shared-bindings/displayio/TileGrid.c msgid "New bitmap must be same size as old bitmap" -msgstr "" +msgstr "Bitmap baru harus berukuran sama dengan bitmap lama" #: ports/espressif/common-hal/_bleio/__init__.c msgid "Nimble out of memory" -msgstr "" +msgstr "Nimble kehabisan memori" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/SPI.c @@ -1436,26 +1540,26 @@ msgstr "tidak ada channel DMA ditemukan" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA pacing timer found" -msgstr "" +msgstr "Tidak ditemukan timer pacing DMA" #: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c #, c-format msgid "No I2C device at address: 0x%x" -msgstr "" +msgstr "Tidak ada perangkat I2C pada alamat: 0x%x" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "" +msgstr "Tidak ada IP" #: ports/atmel-samd/common-hal/microcontroller/__init__.c #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "No bootloader present" -msgstr "" +msgstr "Tidak ada bootloader" #: shared-module/usb/core/Device.c msgid "No configuration set" -msgstr "" +msgstr "Tidak ada konfigurasi yang ditetapkan" #: shared-bindings/_bleio/PacketBuffer.c msgid "No connection: length cannot be determined" @@ -1477,11 +1581,11 @@ msgstr "Tidak ada perangkat keras acak yang tersedia" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "No in in program" -msgstr "" +msgstr "Tidak ada in dalam program" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "No in or out in program" -msgstr "" +msgstr "Tidak ada in atau out dalam program" #: py/objint.c shared-bindings/time/__init__.c msgid "No long integer support" @@ -1489,30 +1593,34 @@ msgstr "Tidak ada dukungan bilangan bulat yang panjang" #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" -msgstr "" +msgstr "Tidak ada jaringan dengan ssid tersebut" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "No out in program" -msgstr "" +msgstr "Tidak ada out dalam program" #: ports/atmel-samd/common-hal/busio/I2C.c #: ports/espressif/common-hal/busio/I2C.c #: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/busio/I2C.c msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "" +msgstr "Tidak ditemukan pull up pada SDA atau SCL; periksa pengkabelan Anda" #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" msgstr "Tidak ada pull-down pada pin; 1Mohm direkomendasikan" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "Tidak ada pullup pada pin; 1Mohm direkomendasikan" + #: py/moderrno.c msgid "No space left on device" msgstr "Tidak ada ruang yang tersisa di perangkat" #: py/moderrno.c msgid "No such device" -msgstr "" +msgstr "Perangkat tidak ada" #: py/moderrno.c msgid "No such file/directory" @@ -1524,15 +1632,15 @@ msgstr "Penghitung waktu tidak tersedia" #: shared-module/usb/core/Device.c msgid "No usb host port initialized" -msgstr "" +msgstr "Tidak ada port host usb yang diinisialisasi" #: ports/nordic/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" -msgstr "" +msgstr "Firmware sistem Nordic kehabisan memori" #: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c msgid "Not a valid IP string" -msgstr "" +msgstr "Bukan string IP yang valid" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c @@ -1553,7 +1661,7 @@ msgstr "" #: ports/espressif/common-hal/sdioio/SDCard.c #, c-format msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +msgstr "Jumlah data_pins harus %d atau %d, bukan %d" #: shared-bindings/util.c msgid "" @@ -1567,17 +1675,17 @@ msgstr "Parity ganjil tidak didukung" #: supervisor/shared/bluetooth/bluetooth.c msgid "Off" -msgstr "" +msgstr "Mati" #: supervisor/shared/bluetooth/bluetooth.c msgid "Ok" -msgstr "" +msgstr "Ok" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c #, c-format msgid "Only 8 or 16 bit mono with %dx oversampling supported." -msgstr "" +msgstr "Hanya mono 8 atau 16 bit dengan oversampling %dx yang didukung." #: ports/espressif/common-hal/wifi/__init__.c #: ports/raspberrypi/common-hal/wifi/__init__.c @@ -1598,60 +1706,51 @@ msgstr "" #: shared-bindings/_bleio/Adapter.c msgid "Only connectable advertisements can be directed" -msgstr "" +msgstr "Hanya advertisement yang dapat terhubung yang dapat diarahkan" #: ports/stm/common-hal/alarm/pin/PinAlarm.c msgid "Only edge detection is available on this hardware" -msgstr "" +msgstr "Hanya deteksi tepi yang tersedia pada perangkat keras ini" #: shared-bindings/ipaddress/__init__.c msgid "Only int or string supported for ip" -msgstr "" - -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Hanya monokrom, 4bpp atau 8bpp yang diindeks, dan 16bpp atau lebih yang " -"didukung: %d bpp diberikan" +msgstr "Hanya int atau string yang didukung untuk ip" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." -msgstr "" +msgstr "Hanya satu %q yang dapat ditetapkan dalam deep sleep." #: ports/espressif/common-hal/espulp/ULPAlarm.c msgid "Only one %q can be set." -msgstr "" +msgstr "Hanya satu %q yang dapat ditetapkan." #: ports/espressif/common-hal/i2ctarget/I2CTarget.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c msgid "Only one address is allowed" -msgstr "" +msgstr "Hanya satu alamat yang diperbolehkan" #: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c #: ports/nordic/common-hal/alarm/time/TimeAlarm.c #: ports/stm/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set" -msgstr "" +msgstr "Hanya satu alarm alarm.time yang dapat ditetapkan" #: ports/espressif/common-hal/alarm/time/TimeAlarm.c #: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set." -msgstr "" +msgstr "Hanya satu alarm alarm.time yang dapat ditetapkan." #: shared-module/displayio/ColorConverter.c msgid "Only one color can be transparent at a time" -msgstr "" +msgstr "Hanya satu warna yang dapat transparan pada satu waktu" #: py/moderrno.c msgid "Operation not permitted" -msgstr "" +msgstr "Operasi tidak diizinkan" #: ports/espressif/common-hal/espidf/__init__.c msgid "Operation or feature not supported" -msgstr "" +msgstr "Operasi atau fitur tidak didukung" #: ports/espressif/common-hal/espidf/__init__.c msgid "Operation timed out" @@ -1659,7 +1758,7 @@ msgstr "Waktu habis" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Out of MDNS service slots" -msgstr "" +msgstr "Kehabisan slot layanan MDNS" #: ports/espressif/common-hal/espidf/__init__.c msgid "Out of memory" @@ -1667,28 +1766,33 @@ msgstr "Kehabisan memori" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Kehabisan socket" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Out-buffer elements must be <= 4 bytes long" -msgstr "" +msgstr "Elemen out-buffer harus <= 4 byte panjangnya" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "PWM restart" -msgstr "" +msgstr "Restart PWM" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice already in use" -msgstr "" +msgstr "Slice PWM sudah digunakan" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice channel A already in use" -msgstr "" +msgstr "Channel A slice PWM sudah digunakan" + +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "Buffer paket untuk transfer SPI harus memiliki panjang yang sama." #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" -msgstr "" +msgstr "Kesalahan parameter" #: ports/espressif/common-hal/audiobusio/__init__.c msgid "Peripheral in use" @@ -1700,7 +1804,7 @@ msgstr "Izin ditolak" #: ports/stm/common-hal/alarm/pin/PinAlarm.c msgid "Pin cannot wake from Deep Sleep" -msgstr "" +msgstr "Pin tidak dapat membangunkan dari Deep Sleep" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Pin count too large" @@ -1709,15 +1813,15 @@ msgstr "Jumlah pin terlalu besar" #: ports/stm/common-hal/alarm/pin/PinAlarm.c #: ports/stm/common-hal/pulseio/PulseIn.c msgid "Pin interrupt already in use" -msgstr "" +msgstr "Pin interupsi sudah digunakan" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c msgid "Pin is input only" -msgstr "" +msgstr "Pin hanya input" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "Pin must be on PWM Channel B" -msgstr "" +msgstr "Pin harus berada di Saluran PWM B" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format @@ -1736,15 +1840,15 @@ msgstr "Pin harus berurutan" #: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c msgid "Pins must be sequential GPIO pins" -msgstr "" +msgstr "Pin harus merupakan pin GPIO yang berurutan" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Pins must share PWM slice" -msgstr "" +msgstr "Pin harus berbagi potongan PWM" #: shared-module/usb/core/Device.c msgid "Pipe error" -msgstr "" +msgstr "Kesalahan pipe" #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" @@ -1752,11 +1856,11 @@ msgstr "Tambahkan module apapun pada filesystem\n" #: shared-module/vectorio/Polygon.c msgid "Polygon needs at least 3 points" -msgstr "" +msgstr "Poligon membutuhkan setidaknya 3 poin" #: supervisor/shared/safe_mode.c msgid "Power dipped. Make sure you are providing enough power." -msgstr "" +msgstr "Daya menurun. Pastikan Anda menyediakan daya yang cukup." #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" @@ -1770,23 +1874,27 @@ msgstr "" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" -msgstr "" +msgstr "Berpura-pura deep sleep sampai alarm, CTRL-C atau penulisan file.\n" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does IN without loading ISR" -msgstr "" +msgstr "Program melakukan IN tanpa memuat ISR" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does OUT without loading OSR" -msgstr "" +msgstr "Program melakukan OUT tanpa memuat OSR" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Program size invalid" -msgstr "" +msgstr "Ukuran program tidak valid" #: ports/espressif/common-hal/espulp/ULP.c msgid "Program too long" -msgstr "" +msgstr "Program terlalu lama" + +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "Publisher hanya dapat dibuat dari node induk" #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." @@ -1794,11 +1902,11 @@ msgstr "Pull tidak digunakan saat arah output." #: ports/raspberrypi/common-hal/countio/Counter.c msgid "RISE_AND_FALL not available on this chip" -msgstr "" +msgstr "RISE_AND_FALL tidak tersedia pada chip ini" #: shared-module/displayio/OnDiskBitmap.c msgid "RLE-compressed BMP not supported" -msgstr "" +msgstr "BMP-terkompresi RLE tidak didukung" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" @@ -1808,10 +1916,30 @@ msgstr "Kesalahan DeInit RNG" msgid "RNG Init Error" msgstr "Kesalahan Init RNG" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" -msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "ROS gagal diinisialisasi. Apakah agen terhubung?" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "Kegagalan pengaturan internal ROS" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "Kegagalan alokator memori ROS" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "Node ROS gagal diinisialisasi" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "Topik ROS gagal diinisialisasi" + +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1839,11 +1967,11 @@ msgstr "sistem file (filesystem) bersifat Read-only" #: ports/espressif/common-hal/espidf/__init__.c msgid "Received response was invalid" -msgstr "" +msgstr "Respon yang diterima tidak valid" #: supervisor/shared/bluetooth/bluetooth.c msgid "Reconnecting" -msgstr "" +msgstr "Menghubungkan kembali" #: shared-bindings/epaperdisplay/EPaperDisplay.c msgid "Refresh too soon" @@ -1851,7 +1979,7 @@ msgstr "Segarkan terlalu cepat" #: shared-bindings/canio/RemoteTransmissionRequest.c msgid "RemoteTransmissionRequests limited to 8 bytes" -msgstr "" +msgstr "RemoteTransmissionRequests dibatasi hingga 8 byte" #: shared-bindings/aesio/aes.c msgid "Requested AES mode is unsupported" @@ -1859,7 +1987,7 @@ msgstr "Mode AES yang diminta tidak didukung" #: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" -msgstr "" +msgstr "Sumber yang diminta tidak ditemukan" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "Right channel unsupported" @@ -1867,57 +1995,56 @@ msgstr "Channel Kanan tidak didukung" #: shared-module/jpegio/JpegDecoder.c msgid "Right format but not supported" -msgstr "" +msgstr "Format benar tapi tidak didukung" #: main.c msgid "Running in safe mode! Not running saved code.\n" msgstr "" "Berjalan di mode aman(safe mode)! Tidak menjalankan kode yang disimpan.\n" -"Berjalan di mode aman(safe mode)! tidak menjalankan kode yang tersimpan.\n" #: shared-module/sdcardio/SDCard.c msgid "SD card CSD format not supported" -msgstr "" +msgstr "Kartu SD Format CSD tidak didukung" #: ports/cxd56/common-hal/sdioio/SDCard.c msgid "SDCard init" -msgstr "" +msgstr "Inisialisasi SDCard" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO GetCardInfo Error %d" -msgstr "" +msgstr "Kesalahan GetCardInfo SDIO %d" #: ports/espressif/common-hal/sdioio/SDCard.c #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO Init Error %x" -msgstr "" +msgstr "Kesalahan Init SDIO %x" #: ports/espressif/common-hal/busio/SPI.c msgid "SPI configuration failed" -msgstr "" +msgstr "Konfigurasi SPI gagal" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" -msgstr "" +msgstr "Kesalahan inisialisasi SPI" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" -msgstr "" +msgstr "Periferal SPI sedang digunakan" #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" -msgstr "" +msgstr "Inisialisasi ulang SPI" #: shared-bindings/is31fl3741/FrameBuffer.c msgid "Scale dimensions must divide by 3" -msgstr "" +msgstr "Skala dimensi harus dibagi 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Scan already in progress. Stop with stop_scan." -msgstr "" +msgstr "Pemindaian sedang berjalan. Hentikan dengan stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -1926,11 +2053,11 @@ msgstr "Serializer sedang digunakan" #: shared-bindings/ssl/SSLContext.c msgid "Server side context cannot have hostname" -msgstr "" +msgstr "Context server tidak mendukung hostname" #: ports/cxd56/common-hal/camera/Camera.c msgid "Size not supported" -msgstr "" +msgstr "Ukuran tidak didukung" #: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c #: shared-bindings/nvm/ByteArray.c @@ -1941,13 +2068,15 @@ msgstr "Potongan dan nilai panjangnya berbeda." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Potongan tidak didukung" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" -msgstr "" +msgstr "SocketPool hanya dapat digunakan dengan wifi.radio" #: shared-bindings/aesio/aes.c msgid "Source and destination buffers must be the same length" @@ -1955,19 +2084,19 @@ msgstr "Buffer sumber dan tujuan harus memiliki panjang yang sama" #: shared-bindings/paralleldisplaybus/ParallelBus.c msgid "Specify exactly one of data0 or data_pins" -msgstr "" +msgstr "Pilih hanya satu antara data0 atau data_pins" #: supervisor/shared/safe_mode.c msgid "Stack overflow. Increase stack size." -msgstr "" +msgstr "Stack overflow. Tambahkan ukuran stack." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" -msgstr "" +msgstr "Berikan salah satu dari monotonic_time atau epoch_time" #: shared-bindings/gnss/GNSS.c msgid "System entry must be gnss.SatelliteSystem" -msgstr "" +msgstr "Entri sistem harus berupa gnss.SatelliteSystem" #: ports/stm/common-hal/microcontroller/Processor.c msgid "Temperature read timed out" @@ -1975,51 +2104,44 @@ msgstr "Waktu baca suhu habis" #: supervisor/shared/safe_mode.c msgid "The `microcontroller` module was used to boot into safe mode." -msgstr "" +msgstr "Modul `microcontroller` digunakan untuk boot ke mode aman." #: py/obj.c msgid "The above exception was the direct cause of the following exception:" msgstr "" +"Pengecualian di atas adalah penyebab langsung dari pengecualian berikut:" #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" -msgstr "" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Sampel bits_per_sampel tidak cocok dengan mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Jumlah saluran sampel tidak cocok dengan mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "Tingkat sampel dari sampel tidak cocok dengan mixer" +msgstr "Panjang rgb_pins harus 6, 12, 18, 24, atau 30" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "signedness dari sampel tidak cocok dengan mixer" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "Sampel punya %q yang tidak cocok" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." -msgstr "" +msgstr "Kesalahan fatal pada firmware pihak ketiga." #: shared-module/imagecapture/ParallelImageCapture.c msgid "This microcontroller does not support continuous capture." -msgstr "" +msgstr "Mikrokontroler ini tidak mendukung penangkapan berkelanjutan." #: shared-module/paralleldisplaybus/ParallelBus.c msgid "" "This microcontroller only supports data0=, not data_pins=, because it " "requires contiguous pins." msgstr "" +"Mikrokontroler ini hanya mendukung data0=, bukan data_pins=, karena " +"membutuhkan pin yang berurutan." #: shared-bindings/displayio/TileGrid.c msgid "Tile height must exactly divide bitmap height" msgstr "Tinggi tile harus persis membagi tinggi bitmap" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Indeks ubin di luar batas" @@ -2027,31 +2149,38 @@ msgstr "Indeks ubin di luar batas" msgid "Tile width must exactly divide bitmap width" msgstr "Lebar ubin harus persis membagi lebar bitmap" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "TilePaletteMapper hanya dapat diikat ke TileGrid sekali" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." -msgstr "" +msgstr "Waktu sudah berlalu." #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c #, c-format msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" +"Waktu tunggu terlalu lama: Panjang maksimum waktu tunggu adalah %d detik" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" -msgstr "" +msgstr "Sampel memiliki terlalu banyak saluran" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample." -msgstr "Terlalu banyak channel dalam sampel" +msgstr "Terlalu banyak channel dalam sampel." #: ports/espressif/common-hal/_bleio/Characteristic.c msgid "Too many descriptors" -msgstr "" +msgstr "Terlalu banyak deskriptor" #: shared-module/displayio/__init__.c msgid "Too many display busses; forgot displayio.release_displays() ?" msgstr "" +"Terlalu banyak jalur tampilan; mungkin kamu lupa untuk panggil displayio." +"release_displays()?" #: shared-module/displayio/__init__.c msgid "Too many displays" @@ -2060,12 +2189,12 @@ msgstr "Terlalu banyak tampilan" #: ports/espressif/common-hal/_bleio/PacketBuffer.c #: ports/nordic/common-hal/_bleio/PacketBuffer.c msgid "Total data to write is larger than %q" -msgstr "" +msgstr "Total data yang akan ditulis lebih besar dari %q" #: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c #: ports/stm/common-hal/alarm/touch/TouchAlarm.c msgid "Touch alarms not available" -msgstr "" +msgstr "Alarm sentuh tidak tersedia" #: py/obj.c msgid "Traceback (most recent call last):\n" @@ -2073,44 +2202,44 @@ msgstr "Traceback (bagian terakhir dari panggilan terkini):\n" #: ports/stm/common-hal/busio/UART.c msgid "UART de-init" -msgstr "" +msgstr "De-inisialisasi UART" #: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c #: ports/stm/common-hal/busio/UART.c msgid "UART init" -msgstr "" +msgstr "Inisialisasi UART" #: ports/raspberrypi/common-hal/busio/UART.c msgid "UART peripheral in use" -msgstr "" +msgstr "Periferal UART sedang digunakan" #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" -msgstr "" +msgstr "Inisialisasi ulang UART" #: ports/stm/common-hal/busio/UART.c msgid "UART write" -msgstr "" +msgstr "Penulisan UART" #: main.c msgid "UID:" -msgstr "" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" -msgstr "" +msgstr "USB sibuk" #: supervisor/shared/safe_mode.c msgid "USB devices need more endpoints than are available." -msgstr "" +msgstr "Perangkat USB butuh lebih banyak endpoint daripada yang tersedia." #: supervisor/shared/safe_mode.c msgid "USB devices specify too many interface names." -msgstr "" +msgstr "Perangkat USB menggunakan terlalu banyak nama antarmuka." #: shared-module/usb_hid/Device.c msgid "USB error" -msgstr "" +msgstr "Kesalahan USB" #: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" @@ -2126,7 +2255,7 @@ msgstr "Nilai UUID bukan str, int atau byte buffer" #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Unable to access unaligned IO register" -msgstr "" +msgstr "Tidak dapat mengakses register IO yang tidak teratur" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -2137,11 +2266,11 @@ msgstr "Tidak dapat mengalokasikan buffer untuk signed conversion" #: supervisor/shared/safe_mode.c msgid "Unable to allocate to the heap." -msgstr "" +msgstr "Tidak dapat mengalokasikan ke heap." #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" -msgstr "" +msgstr "Tidak dapat membuat kunci" #: shared-module/i2cdisplaybus/I2CDisplayBus.c #: shared-module/is31fl3741/IS31FL3741.c @@ -2157,10 +2286,14 @@ msgstr "Tidak dapat memulai parser" msgid "Unable to read color palette data" msgstr "Tidak dapat membaca data palet warna" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "Tidak dapat mengirim Pesan CAN: semua buffer pesan Tx sibuk" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" -msgstr "" +msgstr "Tidak dapat memulai kueri mDNS" #: shared-bindings/nvm/ByteArray.c msgid "Unable to write to nvm." @@ -2168,11 +2301,11 @@ msgstr "Tidak dapat menulis ke nvm." #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Unable to write to read-only memory" -msgstr "" +msgstr "Tidak dapat menulis ke memori hanya-baca" #: shared-bindings/alarm/SleepMemory.c msgid "Unable to write to sleep_memory." -msgstr "" +msgstr "Tidak dapat menulis ke sleep_memory." #: ports/nordic/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" @@ -2181,23 +2314,23 @@ msgstr "Tipe urf nrfx tak sesuai" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown BLE error at %s:%d: %d" -msgstr "" +msgstr "Kesalahan BLE tidak diketahui di %s:%d: %d" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown BLE error: %d" -msgstr "" +msgstr "Kesalahan BLE tidak diketahui: %d" #: ports/espressif/common-hal/max3421e/Max3421E.c #: ports/raspberrypi/common-hal/wifi/__init__.c #, c-format msgid "Unknown error code %d" -msgstr "" +msgstr "Kode kesalahan tidak diketahui %d" #: shared-bindings/wifi/Radio.c #, c-format msgid "Unknown failure %d" -msgstr "" +msgstr "Kegagalan tidak diketahui %d" #: ports/nordic/common-hal/_bleio/__init__.c #, c-format @@ -2217,23 +2350,23 @@ msgstr "Kesalahan keamanan tidak dikenal: 0x%04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error at %s:%d: %d" -msgstr "" +msgstr "Kesalahan firmware sistem tidak dikenal di %s:%d: %d" #: ports/nordic/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %04x" -msgstr "" +msgstr "Kesalahan firmware sistem tidak diketahui: %04x" #: ports/espressif/common-hal/_bleio/__init__.c #, c-format msgid "Unknown system firmware error: %d" -msgstr "" +msgstr "Kesalahan firmware sistem tidak diketahui: %d" #: shared-bindings/adafruit_pixelbuf/PixelBuf.c #: shared-module/_pixelmap/PixelMap.c #, c-format msgid "Unmatched number of items on RHS (expected %d, got %d)." -msgstr "Jumlah item pada RHS tidak cocok (diharapkan %d, didapatkan %d)." +msgstr "Jumlah item pada RHS tidak cocok (diharapkan %d, didapatkan %d)." #: ports/nordic/common-hal/_bleio/__init__.c msgid "" @@ -2245,28 +2378,25 @@ msgstr "" #: shared-bindings/bitmaptools/__init__.c msgid "Unsupported colorspace" -msgstr "" +msgstr "Colorspace tidak didukung" #: shared-module/displayio/bus_core.c msgid "Unsupported display bus type" msgstr "Tipe bus tampilan tidak didukung" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Format tidak didukung" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" -msgstr "" +msgstr "Algoritma hash tidak didukung" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" -msgstr "" +msgstr "Jenis soket tidak didukung" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update failed" -msgstr "" +msgstr "Pembaruan gagal" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c @@ -2282,7 +2412,7 @@ msgstr "Panjang nilai > max_length" #: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" -msgstr "" +msgstr "Versi tidak valid" #: ports/stm/common-hal/microcontroller/Processor.c msgid "Voltage read timed out" @@ -2295,6 +2425,7 @@ msgstr "PERINGATAN: Nama file kode anda mempunyai dua ekstensi\n" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" +"WatchDogTimer tidak dapat dideinisialisasi setelah mode diatur ke RESET" #: py/builtinhelp.c #, c-format @@ -2305,18 +2436,25 @@ msgid "" "\n" "To list built-in modules type `help(\"modules\")`.\n" msgstr "" +"Selamat datang di Adafruit CircuitPython %s!\n" +"\n" +"Kunjungi circuitpython.org untuk informasi lebih lanjut.\n" +"\n" +"Untuk membuat daftar modul bawaan, ketik `help(\"modules\")`.\n" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " -msgstr "" +msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "WiFi tidak diaktifkan" #: main.c msgid "Woken up by alarm.\n" -msgstr "" +msgstr "Dibangunkan oleh alarm.\n" #: ports/espressif/common-hal/_bleio/PacketBuffer.c #: ports/nordic/common-hal/_bleio/PacketBuffer.c @@ -2328,63 +2466,65 @@ msgstr "Menulis tidak didukung pada Karakteristik" #: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h #: ports/atmel-samd/boards/meowmeow/mpconfigboard.h msgid "You pressed both buttons at start up." -msgstr "" +msgstr "Anda menekan kedua tombol saat memulai." #: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." -msgstr "" +msgstr "Anda menekan tombol A saat memulai." #: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h msgid "You pressed button DOWN at start up." -msgstr "" +msgstr "Anda menekan tombol DOWN saat memulai." #: supervisor/shared/safe_mode.c msgid "You pressed the BOOT button at start up" -msgstr "" +msgstr "Anda menekan tombol BOOT saat memulai" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." -msgstr "" +msgstr "Anda menekan tombol BOOT saat memulai." #: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h msgid "You pressed the GPIO0 button at start up." -msgstr "" +msgstr "Anda menekan tombol GPIO0 saat memulai." #: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h msgid "You pressed the Rec button at start up." -msgstr "" +msgstr "Anda menekan tombol Rec saat memulai." #: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h msgid "You pressed the SW38 button at start up." -msgstr "" +msgstr "Anda menekan tombol SW38 saat memulai." #: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h #: ports/espressif/boards/vidi_x/mpconfigboard.h msgid "You pressed the VOLUME button at start up." -msgstr "" +msgstr "Anda menekan tombol VOLUME saat memulai." #: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h #: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h #: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h #: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h msgid "You pressed the central button at start up." -msgstr "" +msgstr "Anda menekan tombol tengah saat memulai." #: ports/nordic/boards/aramcon2_badge/mpconfigboard.h msgid "You pressed the left button at start up." -msgstr "" +msgstr "Anda menekan tombol kiri saat memulai." #: supervisor/shared/safe_mode.c msgid "You pressed the reset button during boot." -msgstr "" +msgstr "Anda menekan tombol reset saat memulai." #: supervisor/shared/micropython.c msgid "[truncated due to length]" -msgstr "" +msgstr "[terpotong karena kepanjangan]" #: py/objtype.c msgid "__init__() should return None" @@ -2393,7 +2533,7 @@ msgstr "__init __() harus mengembalikan None" #: py/objtype.c #, c-format msgid "__init__() should return None, not '%s'" -msgstr "" +msgstr "__init__() harus mengembalikan None, bukan '%s'" #: py/objobject.c msgid "__new__ arg must be a user-type" @@ -2407,13 +2547,17 @@ msgstr "sebuah objek menyerupai byte (bytes-like) dibutuhkan" msgid "addresses is empty" msgstr "alamatnya kosong" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "sudah diputar" + #: py/compile.c msgid "annotation must be an identifier" -msgstr "" +msgstr "anotasi harus merupakan pengidentifikasi" #: extmod/ulab/code/numpy/create.c msgid "arange: cannot compute length" -msgstr "" +msgstr "arange: tidak dapat menghitung panjang" #: py/modbuiltins.c msgid "arg is an empty sequence" @@ -2421,7 +2565,7 @@ msgstr "arg berisi urutan kosong" #: py/objobject.c msgid "arg must be user-type" -msgstr "" +msgstr "arg harus bertipe user-type" #: extmod/ulab/code/numpy/numerical.c msgid "argsort argument must be an ndarray" @@ -2429,15 +2573,15 @@ msgstr "Argumen argsort harus berupa ndarray" #: extmod/ulab/code/numpy/numerical.c msgid "argsort is not implemented for flattened arrays" -msgstr "" +msgstr "argsort tidak diimplementasikan untuk array yang diratakan" #: extmod/ulab/code/numpy/random/random.c msgid "argument must be None, an integer or a tuple of integers" -msgstr "" +msgstr "argumen harus None, integer atau tuple integer" #: py/compile.c msgid "argument name reused" -msgstr "" +msgstr "nama argumen digunakan kembali" #: py/argcheck.c shared-bindings/_stage/__init__.c #: shared-bindings/digitalio/DigitalInOut.c @@ -2450,15 +2594,15 @@ msgstr "argumen harus berupa ndarrays" #: extmod/ulab/code/ndarray.c msgid "array and index length must be equal" -msgstr "" +msgstr "panjang array dan indeks harus sama" #: extmod/ulab/code/numpy/io/io.c msgid "array has too many dimensions" -msgstr "" +msgstr "array memiliki terlalu banyak dimensi" #: extmod/ulab/code/ndarray.c msgid "array is too big" -msgstr "" +msgstr "array terlalu besar" #: py/objarray.c shared-bindings/alarm/SleepMemory.c #: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c @@ -2467,15 +2611,15 @@ msgstr "diperlukan array/byte di sisi kanan" #: py/asmxtensa.c msgid "asm overflow" -msgstr "" +msgstr "asm overflow" #: py/compile.c msgid "async for/with outside async function" -msgstr "" +msgstr "async for/with di luar fungsi async" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get (arg)min/(arg)max of empty sequence" -msgstr "" +msgstr "percobaan untuk mendapatkan (arg)min/(arg)max dari urutan kosong" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get argmin/argmax of an empty sequence" @@ -2483,23 +2627,27 @@ msgstr "berusaha mendapatkan argmin/argmax dari urutan kosong" #: py/objstr.c msgid "attributes not supported" -msgstr "" +msgstr "atribut tidak didukung" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "format audio tidak didukung" #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" -msgstr "" +msgstr "axis berada di luar batas" #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c msgid "axis must be None, or an integer" -msgstr "" +msgstr "axis harus None, atau integer" #: extmod/ulab/code/numpy/numerical.c msgid "axis too long" -msgstr "" +msgstr "axis terlalu panjang" #: shared-bindings/bitmaptools/__init__.c msgid "background value out of range of target" -msgstr "" +msgstr "nilai latar belakang di luar jangkauan target" #: py/builtinevex.c msgid "bad compile mode" @@ -2511,7 +2659,7 @@ msgstr "specifier salah konversi" #: py/objstr.c msgid "bad format string" -msgstr "" +msgstr "string format salah" #: py/binary.c py/objarray.c msgid "bad typecode" @@ -2519,35 +2667,48 @@ msgstr "typecode buruk" #: py/emitnative.c msgid "binary op %q not implemented" -msgstr "" +msgstr "operasi biner %q tidak diimplementasikan" + +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth harus 8, 16, 24, atau 32." #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" -msgstr "" +msgstr "ukuran dan kedalaman bitmap harus cocok" #: shared-bindings/bitmaptools/__init__.c msgid "bitmap sizes must match" -msgstr "" +msgstr "ukuran bitmap harus cocok" #: extmod/modrandom.c msgid "bits must be 32 or less" -msgstr "" +msgstr "bit harus 32 atau kurang" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample harus 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" -msgstr "" +msgstr "bits_per_sample harus 8 atau 16" #: py/emitinlinethumb.c msgid "branch not in range" -msgstr "" +msgstr "branch tidak dalam jangkauan" #: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c msgid "buffer is smaller than requested size" -msgstr "" +msgstr "buffer lebih kecil dari ukuran yang diminta" #: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" -msgstr "" +msgstr "ukuran buffer harus kelipatan dari ukuran elemen" #: shared-module/struct/__init__.c msgid "buffer size must match format" @@ -2555,27 +2716,27 @@ msgstr "ukuran buffer harus sesuai dengan format" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c msgid "buffer slices must be of equal length" -msgstr "" +msgstr "potongan buffer harus memiliki panjang yang sama" #: py/modstruct.c shared-module/struct/__init__.c msgid "buffer too small" -msgstr "" +msgstr "buffer terlalu kecil" #: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c msgid "buffer too small for requested bytes" -msgstr "" +msgstr "buffer terlalu kecil untuk byte yang diminta" #: py/emitbc.c msgid "bytecode overflow" -msgstr "" +msgstr "bytecode overflow" #: py/objarray.c msgid "bytes length not a multiple of item size" -msgstr "" +msgstr "panjang bytes bukan kelipatan dari ukuran item" #: py/objstr.c msgid "bytes value out of range" -msgstr "" +msgstr "nilai bytes di luar jangkauan" #: ports/atmel-samd/bindings/samd/Clock.c msgid "calibration is out of range" @@ -2588,7 +2749,7 @@ msgstr "kalibrasi adalah read only" #: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c #: shared-module/vectorio/Rectangle.c msgid "can only have one parent" -msgstr "" +msgstr "hanya dapat memiliki satu induk" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" @@ -2596,15 +2757,15 @@ msgstr "hanya mampu memiliki hingga 4 parameter untuk Thumb assembly" #: py/emitinlinextensa.c msgid "can only have up to 4 parameters to Xtensa assembly" -msgstr "" +msgstr "hanya dapat memiliki hingga 4 parameter untuk assembly Xtensa" #: extmod/ulab/code/ndarray.c msgid "can only specify one unknown dimension" -msgstr "" +msgstr "hanya dapat menentukan satu dimensi yang tidak diketahui" #: py/objtype.c msgid "can't add special method to already-subclassed class" -msgstr "" +msgstr "tidak dapat menambahkan metode khusus ke kelas yang sudah di-subclass" #: py/compile.c msgid "can't assign to expression" @@ -2612,50 +2773,50 @@ msgstr "tidak dapat menetapkan ke ekspresi" #: extmod/modasyncio.c msgid "can't cancel self" -msgstr "" +msgstr "tidak dapat membatalkan diri sendiri" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" -msgstr "" +msgstr "tidak dapat mengonversi %q ke %q" #: py/obj.c #, c-format msgid "can't convert %s to complex" -msgstr "" +msgstr "tidak dapat mengonversi %s ke complex" #: py/obj.c #, c-format msgid "can't convert %s to float" -msgstr "" +msgstr "tidak dapat mengonversi %s ke float" #: py/objint.c py/runtime.c #, c-format msgid "can't convert %s to int" -msgstr "" +msgstr "tidak dapat mengonversi %s ke int" #: py/objstr.c msgid "can't convert '%q' object to %q implicitly" -msgstr "" +msgstr "tidak dapat mengonversi objek '%q' ke %q secara implisit" #: extmod/ulab/code/numpy/vector.c msgid "can't convert complex to float" -msgstr "" +msgstr "tidak dapat mengonversi complex ke float" #: py/obj.c msgid "can't convert to complex" -msgstr "" +msgstr "tidak dapat mengonversi ke complex" #: py/obj.c msgid "can't convert to float" -msgstr "" +msgstr "tidak dapat mengonversi ke float" #: py/runtime.c msgid "can't convert to int" -msgstr "" +msgstr "tidak dapat mengonversi ke int" #: py/objstr.c msgid "can't convert to str implicitly" -msgstr "" +msgstr "tidak dapat mengonversi ke str secara implisit" #: py/compile.c msgid "can't declare nonlocal in outer code" @@ -2667,93 +2828,95 @@ msgstr "tidak bisa menghapus ekspresi" #: py/emitnative.c msgid "can't do binary op between '%q' and '%q'" -msgstr "" +msgstr "tidak dapat melakukan operasi biner antara '%q' dan '%q'" #: py/emitnative.c msgid "can't do unary op of '%q'" -msgstr "" +msgstr "tidak dapat melakukan operasi unary dari '%q'" #: py/emitnative.c msgid "can't implicitly convert '%q' to 'bool'" -msgstr "" +msgstr "tidak dapat mengonversi '%q' ke 'bool' secara implisit" #: py/runtime.c msgid "can't import name %q" -msgstr "" +msgstr "tidak dapat mengimpor nama %q" #: py/emitnative.c msgid "can't load from '%q'" -msgstr "" +msgstr "tidak dapat memuat dari '%q'" #: py/emitnative.c msgid "can't load with '%q' index" -msgstr "" +msgstr "tidak dapat memuat dengan indeks '%q'" #: py/builtinimport.c msgid "can't perform relative import" -msgstr "" +msgstr "tidak dapat melakukan impor relatif" #: py/objgenerator.c msgid "can't send non-None value to a just-started generator" -msgstr "" +msgstr "tidak dapat mengirim nilai non-None ke generator yang baru dimulai" #: shared-module/sdcardio/SDCard.c msgid "can't set 512 block size" -msgstr "" +msgstr "tidak dapat mengatur ukuran blok 512" #: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" -msgstr "" +msgstr "tidak dapat mengatur atribut" #: py/runtime.c msgid "can't set attribute '%q'" -msgstr "" +msgstr "tidak dapat mengatur atribut '%q'" #: py/emitnative.c msgid "can't store '%q'" -msgstr "" +msgstr "tidak dapat menyimpan '%q'" #: py/emitnative.c msgid "can't store to '%q'" -msgstr "" +msgstr "tidak dapat menyimpan ke '%q'" #: py/emitnative.c msgid "can't store with '%q' index" -msgstr "" +msgstr "tidak dapat menyimpan dengan indeks '%q'" #: py/objstr.c msgid "" "can't switch from automatic field numbering to manual field specification" msgstr "" +"tidak dapat beralih dari penomoran field otomatis ke spesifikasi field manual" #: py/objstr.c msgid "" "can't switch from manual field specification to automatic field numbering" msgstr "" +"tidak dapat beralih dari spesifikasi field manual ke penomoran field otomatis" #: py/objcomplex.c msgid "can't truncate-divide a complex number" -msgstr "" +msgstr "tidak dapat truncate-divide bilangan complex" #: extmod/modasyncio.c msgid "can't wait" -msgstr "" +msgstr "tidak dapat menunggu" #: extmod/ulab/code/ndarray.c msgid "cannot assign new shape" -msgstr "" +msgstr "tidak dapat menetapkan bentuk baru" #: extmod/ulab/code/ndarray_operators.c msgid "cannot cast output with casting rule" -msgstr "" +msgstr "tidak dapat melakukan cast output dengan aturan casting" #: extmod/ulab/code/ndarray.c msgid "cannot convert complex to dtype" -msgstr "" +msgstr "tidak dapat mengonversi complex ke dtype" #: extmod/ulab/code/ndarray.c msgid "cannot convert complex type" -msgstr "" +msgstr "tidak dapat mengonversi tipe complex" #: py/objtype.c msgid "cannot create '%q' instances" @@ -2761,71 +2924,71 @@ msgstr "" #: py/objtype.c msgid "cannot create instance" -msgstr "" +msgstr "tidak dapat membuat instance" #: extmod/ulab/code/ndarray.c msgid "cannot delete array elements" -msgstr "" +msgstr "tidak dapat menghapus elemen array" #: extmod/ulab/code/ndarray.c msgid "cannot reshape array" -msgstr "" +msgstr "tidak dapat membentuk ulang array" #: py/emitnative.c msgid "casting" -msgstr "" +msgstr "casting" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "channel re-init" -msgstr "" +msgstr "inisialisasi ulang channel" #: shared-bindings/_stage/Text.c msgid "chars buffer too small" -msgstr "" +msgstr "buffer chars terlalu kecil" #: py/modbuiltins.c msgid "chr() arg not in range(0x110000)" -msgstr "" +msgstr "argumen chr() tidak dalam rentang(0x110000)" #: py/modbuiltins.c msgid "chr() arg not in range(256)" -msgstr "" +msgstr "argumen chr() tidak dalam rentang(256)" #: shared-bindings/bitmaptools/__init__.c msgid "clip point must be (x,y) tuple" -msgstr "" +msgstr "clip point harus berupa tuple (x,y)" #: shared-bindings/msgpack/ExtType.c msgid "code outside range 0~127" -msgstr "" +msgstr "kode di luar rentang 0~127" #: shared-bindings/displayio/Palette.c msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "" +msgstr "buffer warna harus 3 byte (RGB) atau 4 byte (RGB + pad byte)" #: shared-bindings/displayio/Palette.c msgid "color buffer must be a buffer, tuple, list, or int" -msgstr "" +msgstr "buffer warna harus berupa buffer, tuple, list, atau int" #: shared-bindings/displayio/Palette.c msgid "color buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "" +msgstr "buffer warna harus berupa bytearray atau array bertipe 'b' atau 'B'" #: shared-bindings/displayio/Palette.c msgid "color must be between 0x000000 and 0xffffff" -msgstr "" +msgstr "warna harus antara 0x000000 dan 0xffffff" #: py/emitnative.c msgid "comparison of int and uint" -msgstr "" +msgstr "perbandingan int dan uint" #: py/objcomplex.c msgid "complex divide by zero" -msgstr "" +msgstr "pembagian complex dengan nol" #: py/objfloat.c py/parsenum.c msgid "complex values not supported" -msgstr "" +msgstr "nilai complex tidak didukung" #: extmod/modzlib.c msgid "compression header" @@ -2833,56 +2996,56 @@ msgstr "kompresi header" #: py/emitnative.c msgid "conversion to object" -msgstr "" +msgstr "konversi ke objek" #: extmod/ulab/code/numpy/filter.c msgid "convolve arguments must be linear arrays" -msgstr "" +msgstr "argumen convolve harus berupa array linear" #: extmod/ulab/code/numpy/filter.c msgid "convolve arguments must be ndarrays" -msgstr "" +msgstr "argumen convolve harus berupa ndarray" #: extmod/ulab/code/numpy/filter.c msgid "convolve arguments must not be empty" -msgstr "" +msgstr "argumen convolve tidak boleh kosong" #: extmod/ulab/code/numpy/io/io.c msgid "corrupted file" -msgstr "" +msgstr "file rusak" #: extmod/ulab/code/numpy/poly.c msgid "could not invert Vandermonde matrix" -msgstr "" +msgstr "tidak dapat membalik matriks Vandermonde" #: shared-module/sdcardio/SDCard.c msgid "couldn't determine SD card version" -msgstr "" +msgstr "tidak dapat menentukan versi kartu SD" #: extmod/ulab/code/numpy/numerical.c msgid "cross is defined for 1D arrays of length 3" -msgstr "" +msgstr "cross didefinisikan untuk array 1D dengan panjang 3" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "data must be iterable" -msgstr "" +msgstr "data harus dapat diiterasi" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "data must be of equal length" -msgstr "" +msgstr "data harus memiliki panjang yang sama" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format msgid "data pin #%d in use" -msgstr "" +msgstr "pin data #%d sedang digunakan" #: extmod/ulab/code/ndarray.c msgid "data type not understood" -msgstr "" +msgstr "tipe data tidak dipahami" #: py/parsenum.c msgid "decimal numbers not supported" -msgstr "" +msgstr "angka desimal tidak didukung" #: py/compile.c msgid "default 'except' must be last" @@ -2890,60 +3053,62 @@ msgstr "'except' standar harus terakhir" #: shared-bindings/msgpack/__init__.c msgid "default is not a function" -msgstr "" +msgstr "default bukan fungsi" #: shared-bindings/audiobusio/PDMIn.c msgid "" "destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" +"buffer tujuan harus berupa bytearray atau array bertipe 'B' untuk bit_depth " +"= 8" #: shared-bindings/audiobusio/PDMIn.c msgid "destination buffer must be an array of type 'H' for bit_depth = 16" -msgstr "" +msgstr "buffer tujuan harus berupa array bertipe 'H' untuk bit_depth = 16" #: py/objdict.c msgid "dict update sequence has wrong length" -msgstr "" +msgstr "urutan pembaruan dict memiliki panjang yang salah" #: extmod/ulab/code/numpy/numerical.c msgid "diff argument must be an ndarray" -msgstr "" +msgstr "argumen diff harus berupa ndarray" #: extmod/ulab/code/numpy/numerical.c msgid "differentiation order out of range" -msgstr "" +msgstr "urutan diferensiasi di luar jangkauan" #: extmod/ulab/code/numpy/transform.c msgid "dimensions do not match" -msgstr "" +msgstr "dimensi tidak cocok" #: py/emitnative.c msgid "div/mod not implemented for uint" -msgstr "" +msgstr "div/mod tidak diimplementasikan untuk uint" #: extmod/ulab/code/numpy/create.c msgid "divide by zero" -msgstr "" +msgstr "pembagian dengan nol" #: py/runtime.c msgid "division by zero" -msgstr "" +msgstr "pembagian dengan nol" #: extmod/ulab/code/numpy/vector.c msgid "dtype must be float, or complex" -msgstr "" +msgstr "dtype harus float, atau complex" #: extmod/ulab/code/ndarray_operators.c msgid "dtype of int32 is not supported" -msgstr "" +msgstr "dtype int32 tidak didukung" #: py/objdeque.c msgid "empty" -msgstr "" +msgstr "kosong" #: extmod/ulab/code/numpy/io/io.c msgid "empty file" -msgstr "" +msgstr "file kosong" #: extmod/modasyncio.c extmod/modheapq.c msgid "empty heap" @@ -2951,19 +3116,19 @@ msgstr "heap kosong" #: py/objstr.c msgid "empty separator" -msgstr "" +msgstr "pemisah kosong" #: shared-bindings/random/__init__.c msgid "empty sequence" -msgstr "" +msgstr "urutan kosong" #: py/objstr.c msgid "end of format while looking for conversion specifier" -msgstr "" +msgstr "akhir format saat mencari spesifier konversi" #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" -msgstr "" +msgstr "epoch_time tidak didukung pada board ini" #: ports/nordic/common-hal/busio/UART.c #, c-format @@ -2972,19 +3137,19 @@ msgstr "error = 0x%08lX" #: py/runtime.c msgid "exceptions must derive from BaseException" -msgstr "" +msgstr "exception harus diturunkan dari BaseException" #: py/objstr.c msgid "expected ':' after format specifier" -msgstr "" +msgstr "mengharapkan ':' setelah spesifier format" #: py/obj.c msgid "expected tuple/list" -msgstr "" +msgstr "mengharapkan tuple/list" #: py/modthread.c msgid "expecting a dict for keyword args" -msgstr "" +msgstr "mengharapkan dict untuk argumen keyword" #: py/compile.c msgid "expecting an assembler instruction" @@ -3000,7 +3165,7 @@ msgstr "key:value diharapkan untuk dict" #: shared-bindings/msgpack/__init__.c msgid "ext_hook is not a function" -msgstr "" +msgstr "ext_hook bukan fungsi" #: py/argcheck.c msgid "extra keyword arguments given" @@ -3014,11 +3179,11 @@ msgstr "argumen posisi ekstra telah diberikan" #: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c #: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c msgid "file must be a file opened in byte mode" -msgstr "" +msgstr "file harus berupa file yang dibuka dalam mode byte" #: shared-bindings/traceback/__init__.c msgid "file write is not available" -msgstr "" +msgstr "penulisan file tidak tersedia" #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" @@ -3026,63 +3191,63 @@ msgstr "" #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" -msgstr "" +msgstr "argumen pertama harus dapat dipanggil" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "first argument must be a function" -msgstr "" +msgstr "argumen pertama harus berupa fungsi" #: extmod/ulab/code/numpy/create.c msgid "first argument must be a tuple of ndarrays" -msgstr "" +msgstr "argumen pertama harus berupa tuple ndarray" #: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c msgid "first argument must be an ndarray" -msgstr "" +msgstr "argumen pertama harus berupa ndarray" #: py/objtype.c msgid "first argument to super() must be type" -msgstr "" +msgstr "argumen pertama untuk super() harus bertipe type" #: extmod/ulab/code/scipy/linalg/linalg.c msgid "first two arguments must be ndarrays" -msgstr "" +msgstr "dua argumen pertama harus berupa ndarray" #: extmod/ulab/code/ndarray.c msgid "flattening order must be either 'C', or 'F'" -msgstr "" +msgstr "urutan perataan harus 'C', atau 'F'" #: extmod/ulab/code/numpy/numerical.c msgid "flip argument must be an ndarray" -msgstr "" +msgstr "argumen flip harus berupa ndarray" #: py/objint.c msgid "float too big" -msgstr "" +msgstr "float terlalu besar" #: py/nativeglue.c msgid "float unsupported" -msgstr "" +msgstr "float tidak didukung" #: shared-bindings/_stage/Text.c msgid "font must be 2048 bytes long" -msgstr "" +msgstr "font harus sepanjang 2048 byte" #: extmod/moddeflate.c msgid "format" -msgstr "" +msgstr "format" #: py/objstr.c -msgid "format requires a dict" -msgstr "" +msgid "format needs a dict" +msgstr "format memerlukan dict" #: py/objdeque.c msgid "full" -msgstr "" +msgstr "penuh" #: py/argcheck.c msgid "function doesn't take keyword arguments" -msgstr "" +msgstr "fungsi tidak menerima argumen keyword" #: py/argcheck.c #, c-format @@ -3095,15 +3260,15 @@ msgstr "fungsi mendapatkan nilai ganda untuk argumen '%q'" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "function has the same sign at the ends of interval" -msgstr "" +msgstr "fungsi memiliki tanda yang sama pada ujung interval" #: extmod/ulab/code/ndarray.c msgid "function is defined for ndarrays only" -msgstr "" +msgstr "fungsi didefinisikan hanya untuk ndarray" #: extmod/ulab/code/numpy/carray/carray.c msgid "function is implemented for ndarrays only" -msgstr "" +msgstr "fungsi diimplementasikan hanya untuk ndarray" #: py/argcheck.c #, c-format @@ -3131,23 +3296,23 @@ msgstr "fungsi mengambil posisi argumen %d tapi %d yang diberikan" #: py/objgenerator.c msgid "generator already executing" -msgstr "" +msgstr "generator sudah berjalan" #: py/objgenerator.c msgid "generator ignored GeneratorExit" -msgstr "" +msgstr "generator mengabaikan GeneratorExit" #: py/objgenerator.c py/runtime.c msgid "generator raised StopIteration" -msgstr "" +msgstr "generator memunculkan StopIteration" #: shared-bindings/_stage/Layer.c msgid "graphic must be 2048 bytes long" -msgstr "" +msgstr "grafik harus sepanjang 2048 byte" #: extmod/modhashlib.c msgid "hash is final" -msgstr "" +msgstr "hash bersifat final" #: extmod/modheapq.c msgid "heap must be a list" @@ -3163,23 +3328,23 @@ msgstr "identifier didefinisi ulang sebagai nonlocal" #: py/compile.c msgid "import * not at module level" -msgstr "" +msgstr "import * tidak pada tingkat modul" #: py/persistentcode.c msgid "incompatible .mpy arch" -msgstr "" +msgstr "arsitektur .mpy tidak kompatibel" #: py/persistentcode.c msgid "incompatible .mpy file" -msgstr "" +msgstr "file .mpy tidak kompatibel" #: py/objstr.c msgid "incomplete format" -msgstr "" +msgstr "format tidak lengkap" #: py/objstr.c msgid "incomplete format key" -msgstr "" +msgstr "kunci format tidak lengkap" #: extmod/modbinascii.c msgid "incorrect padding" @@ -3187,11 +3352,11 @@ msgstr "lapisan (padding) tidak benar" #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c msgid "index is out of bounds" -msgstr "" +msgstr "indeks berada di luar batas" #: shared-bindings/_pixelmap/PixelMap.c msgid "index must be tuple or int" -msgstr "" +msgstr "indeks harus berupa tuple atau int" #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c #: ports/espressif/common-hal/pulseio/PulseIn.c @@ -3201,23 +3366,19 @@ msgstr "index keluar dari jangkauan" #: py/obj.c msgid "indices must be integers" -msgstr "" +msgstr "indeks harus berupa integer" #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" -msgstr "" - -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "" +msgstr "indeks harus berupa integer, slice, atau list Boolean" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" -msgstr "" +msgstr "nilai awal harus dapat diiterasi" #: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c msgid "initial_value length is wrong" -msgstr "" +msgstr "panjang initial_value salah" #: py/compile.c msgid "inline assembler must be a function" @@ -3225,98 +3386,98 @@ msgstr "inline assembler harus sebuah fungsi" #: extmod/ulab/code/numpy/vector.c msgid "input and output dimensions differ" -msgstr "" +msgstr "dimensi input dan output berbeda" #: extmod/ulab/code/numpy/vector.c msgid "input and output shapes differ" -msgstr "" +msgstr "bentuk input dan output berbeda" #: extmod/ulab/code/numpy/create.c msgid "input argument must be an integer, a tuple, or a list" -msgstr "" +msgstr "argumen input harus berupa integer, tuple, atau list" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "input array length must be power of 2" -msgstr "" +msgstr "panjang array input harus pangkat 2" #: extmod/ulab/code/numpy/create.c msgid "input arrays are not compatible" -msgstr "" +msgstr "array input tidak kompatibel" #: extmod/ulab/code/numpy/poly.c msgid "input data must be an iterable" -msgstr "" +msgstr "data input harus dapat diiterasi" #: extmod/ulab/code/numpy/vector.c msgid "input dtype must be float or complex" -msgstr "" +msgstr "dtype input harus float atau complex" #: extmod/ulab/code/numpy/poly.c msgid "input is not iterable" -msgstr "" +msgstr "input tidak dapat diiterasi" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "input matrix is asymmetric" -msgstr "" +msgstr "matriks input asimetris" #: extmod/ulab/code/numpy/linalg/linalg.c #: extmod/ulab/code/scipy/linalg/linalg.c msgid "input matrix is singular" -msgstr "" +msgstr "matriks input singular" #: extmod/ulab/code/numpy/create.c msgid "input must be 1- or 2-d" -msgstr "" +msgstr "input harus 1- atau 2-d" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be a 1D ndarray" -msgstr "" +msgstr "input harus berupa ndarray 1D" #: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c msgid "input must be a dense ndarray" -msgstr "" +msgstr "input harus berupa ndarray padat" #: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c msgid "input must be an ndarray" -msgstr "" +msgstr "input harus berupa ndarray" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be an ndarray, or a scalar" -msgstr "" +msgstr "input harus berupa ndarray, atau skalar" #: extmod/ulab/code/scipy/signal/signal.c msgid "input must be one-dimensional" -msgstr "" +msgstr "input harus satu dimensi" #: extmod/ulab/code/ulab_tools.c msgid "input must be square matrix" -msgstr "" +msgstr "input harus berupa matriks persegi" #: extmod/ulab/code/numpy/numerical.c msgid "input must be tuple, list, range, or ndarray" -msgstr "" +msgstr "input harus berupa tuple, list, range, atau ndarray" #: extmod/ulab/code/numpy/poly.c msgid "input vectors must be of equal length" -msgstr "" +msgstr "vektor input harus memiliki panjang yang sama" #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" -msgstr "" +msgstr "interp didefinisikan untuk iterable 1D dengan panjang yang sama" #: shared-bindings/_bleio/Adapter.c #, c-format msgid "interval must be in range %s-%s" -msgstr "" +msgstr "interval harus dalam rentang %s-%s" #: py/compile.c msgid "invalid arch" -msgstr "" +msgstr "arsitektur tidak valid" #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" -msgstr "" +msgstr "bits_per_pixel %d tidak valid, harus 1, 2, 4, 8, 16, 24, atau 32" #: shared-module/ssl/SSLSocket.c msgid "invalid cert" @@ -3325,24 +3486,24 @@ msgstr "cert tidak valid" #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element size %d for bits_per_pixel %d\n" -msgstr "" +msgstr "element size %d tidak valid untuk bits_per_pixel %d\n" #: shared-bindings/bitmaptools/__init__.c #, c-format msgid "invalid element_size %d, must be, 1, 2, or 4" -msgstr "" +msgstr "element_size %d tidak valid, harus 1, 2, atau 4" #: shared-bindings/traceback/__init__.c msgid "invalid exception" -msgstr "" +msgstr "exception tidak valid" #: py/objstr.c msgid "invalid format specifier" -msgstr "" +msgstr "spesifier format tidak valid" #: shared-bindings/wifi/Radio.c msgid "invalid hostname" -msgstr "" +msgstr "hostname tidak valid" #: shared-module/ssl/SSLSocket.c msgid "invalid key" @@ -3354,11 +3515,11 @@ msgstr "micropython decorator tidak valid" #: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" -msgstr "" +msgstr "pengaturan tidak valid" #: shared-bindings/random/__init__.c msgid "invalid step" -msgstr "" +msgstr "step tidak valid" #: py/compile.c py/parse.c msgid "invalid syntax" @@ -3366,146 +3527,144 @@ msgstr "syntax tidak valid" #: py/parsenum.c msgid "invalid syntax for integer" -msgstr "" +msgstr "sintaks tidak valid untuk integer" #: py/parsenum.c #, c-format msgid "invalid syntax for integer with base %d" -msgstr "" +msgstr "sintaks tidak valid untuk integer dengan basis %d" #: py/parsenum.c msgid "invalid syntax for number" -msgstr "" +msgstr "sintaks tidak valid untuk angka" #: py/objtype.c msgid "issubclass() arg 1 must be a class" -msgstr "" +msgstr "argumen 1 issubclass() harus berupa class" #: py/objtype.c msgid "issubclass() arg 2 must be a class or a tuple of classes" -msgstr "" +msgstr "argumen 2 issubclass() harus berupa class atau tuple class" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "iterations did not converge" -msgstr "" +msgstr "iterasi tidak konvergen" #: py/objstr.c msgid "join expects a list of str/bytes objects consistent with self object" -msgstr "" +msgstr "join mengharapkan list objek str/bytes yang konsisten dengan objek self" #: py/argcheck.c msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" +"argumen keyword tidak diimplementasikan - gunakan argumen normal sebagai " +"gantinya" #: py/emitinlinethumb.c py/emitinlinextensa.c msgid "label '%q' not defined" -msgstr "" +msgstr "label '%q' tidak didefinisikan" #: py/compile.c msgid "label redefined" msgstr "label didefinis ulang" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "" - #: py/objarray.c msgid "lhs and rhs should be compatible" -msgstr "" +msgstr "lhs dan rhs harus kompatibel" #: py/emitnative.c msgid "local '%q' has type '%q' but source is '%q'" -msgstr "" +msgstr "lokal '%q' memiliki tipe '%q' tetapi sumber adalah '%q'" #: py/emitnative.c msgid "local '%q' used before type known" -msgstr "" +msgstr "lokal '%q' digunakan sebelum tipe diketahui" #: py/vm.c msgid "local variable referenced before assignment" -msgstr "" +msgstr "variabel lokal direferensikan sebelum penetapan" #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" -msgstr "" +msgstr "mode loopback + silent tidak didukung oleh periferal" #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS already initialized" -msgstr "" +msgstr "mDNS sudah diinisialisasi" #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "mDNS only works with built-in WiFi" -msgstr "" +msgstr "mDNS hanya bekerja dengan WiFi bawaan" #: py/parse.c msgid "malformed f-string" -msgstr "" +msgstr "f-string salah bentuk" #: shared-bindings/_stage/Layer.c msgid "map buffer too small" -msgstr "" +msgstr "buffer peta terlalu kecil" #: py/modmath.c shared-bindings/math/__init__.c msgid "math domain error" -msgstr "" +msgstr "kesalahan domain matematika" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "matrix is not positive definite" -msgstr "" +msgstr "matriks tidak definit positif" #: ports/espressif/common-hal/_bleio/Descriptor.c #: ports/nordic/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Descriptor.c #, c-format msgid "max_length must be 0-%d when fixed_length is %s" -msgstr "" +msgstr "max_length harus 0-%d ketika fixed_length adalah %s" #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c msgid "maximum number of dimensions is " -msgstr "" +msgstr "jumlah maksimum dimensi adalah " #: py/runtime.c msgid "maximum recursion depth exceeded" -msgstr "" +msgstr "kedalaman rekursi maksimum terlampaui" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "maxiter must be > 0" -msgstr "" +msgstr "maxiter harus > 0" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "maxiter should be > 0" -msgstr "" +msgstr "maxiter harus > 0" #: extmod/ulab/code/numpy/numerical.c msgid "median argument must be an ndarray" -msgstr "" +msgstr "argumen median harus berupa ndarray" #: py/runtime.c #, c-format msgid "memory allocation failed, allocating %u bytes" -msgstr "" +msgstr "alokasi memori gagal, mengalokasikan %u byte" #: py/runtime.c msgid "memory allocation failed, heap is locked" -msgstr "" +msgstr "alokasi memori gagal, heap terkunci" #: py/objarray.c msgid "memoryview offset too large" -msgstr "" +msgstr "offset memoryview terlalu besar" #: py/objarray.c msgid "memoryview: length is not a multiple of itemsize" -msgstr "" +msgstr "memoryview: panjang bukan kelipatan dari itemsize" #: extmod/modtime.c msgid "mktime needs a tuple of length 8 or 9" -msgstr "" +msgstr "mktime memerlukan tuple dengan panjang 8 atau 9" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "mode must be complete, or reduced" -msgstr "" +msgstr "mode harus complete, atau reduced" #: py/builtinimport.c msgid "module not found" @@ -3513,11 +3672,11 @@ msgstr "modul tidak ditemukan" #: ports/espressif/common-hal/wifi/Monitor.c msgid "monitor init failed" -msgstr "" +msgstr "inisialisasi monitor gagal" #: extmod/ulab/code/numpy/poly.c msgid "more degrees of freedom than data points" -msgstr "" +msgstr "lebih banyak derajat kebebasan daripada titik data" #: py/compile.c msgid "multiple *x in assignment" @@ -3525,76 +3684,76 @@ msgstr "perkalian *x dalam assignment" #: py/objtype.c msgid "multiple bases have instance lay-out conflict" -msgstr "" +msgstr "beberapa basis memiliki konflik tata letak instance" #: py/objtype.c msgid "multiple inheritance not supported" -msgstr "" +msgstr "pewarisan berganda tidak didukung" #: py/emitnative.c msgid "must raise an object" -msgstr "" +msgstr "harus memunculkan objek" #: py/modbuiltins.c msgid "must use keyword argument for key function" -msgstr "" +msgstr "harus menggunakan argumen keyword untuk fungsi kunci" #: py/runtime.c -msgid "name '%q' is not defined" -msgstr "" +msgid "name '%q' isn't defined" +msgstr "nama '%q' tidak didefinisikan" #: py/runtime.c msgid "name not defined" -msgstr "" +msgstr "nama tidak didefinisikan" #: py/qstr.c msgid "name too long" -msgstr "" +msgstr "nama terlalu panjang" #: py/persistentcode.c msgid "native code in .mpy unsupported" -msgstr "" +msgstr "kode native dalam .mpy tidak didukung" #: py/asmthumb.c msgid "native method too big" -msgstr "" +msgstr "metode native terlalu besar" #: py/emitnative.c msgid "native yield" -msgstr "" +msgstr "yield native" #: extmod/ulab/code/ndarray.c msgid "ndarray length overflows" -msgstr "" +msgstr "panjang ndarray meluap" #: py/runtime.c #, c-format msgid "need more than %d values to unpack" -msgstr "" +msgstr "memerlukan lebih dari %d nilai untuk membongkar" #: py/modmath.c msgid "negative factorial" -msgstr "" +msgstr "faktorial negatif" #: py/objint_longlong.c py/objint_mpz.c py/runtime.c msgid "negative power with no float support" -msgstr "" +msgstr "pangkat negatif tanpa dukungan float" #: py/objint_mpz.c py/runtime.c msgid "negative shift count" -msgstr "" +msgstr "jumlah shift negatif" #: shared-bindings/_pixelmap/PixelMap.c msgid "nested index must be int" -msgstr "" +msgstr "indeks bersarang harus int" #: shared-module/sdcardio/SDCard.c msgid "no SD card" -msgstr "" +msgstr "tidak ada kartu SD" #: py/vm.c msgid "no active exception to reraise" -msgstr "" +msgstr "tidak ada exception aktif untuk dimunculkan kembali" #: py/compile.c msgid "no binding for nonlocal found" @@ -3602,11 +3761,11 @@ msgstr "tidak ada ikatan/bind pada temuan nonlocal" #: shared-module/msgpack/__init__.c msgid "no default packer" -msgstr "" +msgstr "tidak ada packer default" #: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c msgid "no default seed" -msgstr "" +msgstr "tidak ada seed default" #: py/builtinimport.c msgid "no module named '%q'" @@ -3614,16 +3773,16 @@ msgstr "tidak ada modul yang bernama '%q'" #: shared-module/sdcardio/SDCard.c msgid "no response from SD card" -msgstr "" +msgstr "tidak ada respons dari kartu SD" #: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" -msgstr "" +msgstr "atribut tidak ada" #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nordic/common-hal/_bleio/Connection.c msgid "non-UUID found in service_uuids_whitelist" -msgstr "" +msgstr "non-UUID ditemukan dalam service_uuids_whitelist" #: py/compile.c msgid "non-default argument follows default argument" @@ -3635,19 +3794,19 @@ msgstr "digit non-hex ditemukan" #: ports/nordic/common-hal/_bleio/Adapter.c msgid "non-zero timeout must be > 0.01" -msgstr "" +msgstr "timeout non-nol harus > 0.01" #: shared-bindings/_bleio/Adapter.c msgid "non-zero timeout must be >= interval" -msgstr "" +msgstr "timeout non-nol harus >= interval" #: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" -msgstr "" +msgstr "bukan UUID 128-bit" #: py/parse.c msgid "not a constant" -msgstr "" +msgstr "bukan konstanta" #: py/objstr.c msgid "not all arguments converted during string formatting" @@ -3659,65 +3818,65 @@ msgstr "" #: extmod/ulab/code/numpy/carray/carray_tools.c msgid "not implemented for complex dtype" -msgstr "" +msgstr "tidak diimplementasikan untuk dtype complex" #: extmod/ulab/code/numpy/bitwise.c msgid "not supported for input types" -msgstr "" +msgstr "tidak didukung untuk tipe input" #: extmod/ulab/code/numpy/create.c msgid "number of points must be at least 2" -msgstr "" +msgstr "jumlah titik harus setidaknya 2" #: py/builtinhelp.c msgid "object " -msgstr "" +msgstr "objek " #: py/obj.c #, c-format msgid "object '%s' isn't a tuple or list" -msgstr "" +msgstr "objek '%s' bukan tuple atau list" #: py/obj.c msgid "object doesn't support item assignment" -msgstr "" +msgstr "objek tidak mendukung penetapan item" #: py/obj.c msgid "object doesn't support item deletion" -msgstr "" +msgstr "objek tidak mendukung penghapusan item" #: py/obj.c msgid "object has no len" -msgstr "" +msgstr "objek tidak memiliki len" #: py/obj.c msgid "object isn't subscriptable" -msgstr "" +msgstr "objek tidak dapat disubskripsikan" #: py/runtime.c msgid "object not an iterator" -msgstr "" +msgstr "objek bukan iterator" #: py/objtype.c py/runtime.c msgid "object not callable" -msgstr "" +msgstr "objek tidak dapat dipanggil" #: py/sequence.c shared-bindings/displayio/Group.c msgid "object not in sequence" -msgstr "" +msgstr "objek tidak dalam urutan" #: py/runtime.c msgid "object not iterable" -msgstr "" +msgstr "objek tidak dapat diiterasi" #: py/obj.c #, c-format msgid "object of type '%s' has no len()" -msgstr "" +msgstr "objek bertipe '%s' tidak memiliki len()" #: py/obj.c msgid "object with buffer protocol required" -msgstr "" +msgstr "objek dengan protokol buffer diperlukan" #: py/objstr.c msgid "odd-length string" @@ -3725,146 +3884,146 @@ msgstr "panjang data string memiliki keganjilan (odd-length)" #: supervisor/shared/web_workflow/web_workflow.c msgid "off" -msgstr "" +msgstr "mati" #: extmod/ulab/code/utils/utils.c msgid "offset is too large" -msgstr "" +msgstr "offset terlalu besar" #: shared-bindings/dualbank/__init__.c msgid "offset must be >= 0" -msgstr "" +msgstr "offset harus >= 0" #: extmod/ulab/code/numpy/create.c msgid "offset must be non-negative and no greater than buffer length" -msgstr "" +msgstr "offset harus non-negatif dan tidak lebih besar dari panjang buffer" #: ports/nordic/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only bit_depth=16 is supported" -msgstr "" +msgstr "hanya bit_depth=16 yang didukung" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only mono is supported" -msgstr "" +msgstr "hanya mono yang didukung" #: extmod/ulab/code/numpy/create.c msgid "only ndarrays can be concatenated" -msgstr "" +msgstr "hanya ndarray yang dapat digabungkan" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only oversample=64 is supported" -msgstr "" +msgstr "hanya oversample=64 yang didukung" #: ports/nordic/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only sample_rate=16000 is supported" -msgstr "" +msgstr "hanya sample_rate=16000 yang didukung" #: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c #: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c #: shared-bindings/nvm/ByteArray.c msgid "only slices with step=1 (aka None) are supported" -msgstr "" +msgstr "hanya slice dengan step=1 (alias None) yang didukung" #: py/vm.c msgid "opcode" -msgstr "" +msgstr "opcode" #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c #: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c msgid "operands could not be broadcast together" -msgstr "" +msgstr "operan tidak dapat di-broadcast bersama" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "operation is defined for 2D arrays only" -msgstr "" +msgstr "operasi didefinisikan hanya untuk array 2D" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "operation is defined for ndarrays only" -msgstr "" +msgstr "operasi didefinisikan hanya untuk ndarray" #: extmod/ulab/code/ndarray.c msgid "operation is implemented for 1D Boolean arrays only" -msgstr "" +msgstr "operasi diimplementasikan hanya untuk array Boolean 1D" #: extmod/ulab/code/numpy/numerical.c msgid "operation is not implemented on ndarrays" -msgstr "" +msgstr "operasi tidak diimplementasikan pada ndarray" #: extmod/ulab/code/ndarray.c msgid "operation is not supported for given type" -msgstr "" +msgstr "operasi tidak didukung untuk tipe yang diberikan" #: extmod/ulab/code/ndarray_operators.c msgid "operation not supported for the input types" -msgstr "" +msgstr "operasi tidak didukung untuk tipe input" #: py/modbuiltins.c msgid "ord expects a character" -msgstr "" +msgstr "ord mengharapkan karakter" #: py/modbuiltins.c #, c-format msgid "ord() expected a character, but string of length %d found" -msgstr "" +msgstr "ord() mengharapkan karakter, tetapi string dengan panjang %d ditemukan" #: extmod/ulab/code/utils/utils.c msgid "out array is too small" -msgstr "" +msgstr "array out terlalu kecil" #: extmod/ulab/code/numpy/random/random.c msgid "out has wrong type" -msgstr "" +msgstr "out memiliki tipe yang salah" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for complex dtype" -msgstr "" +msgstr "keyword out tidak didukung untuk dtype complex" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for function" -msgstr "" +msgstr "keyword out tidak didukung untuk fungsi" #: extmod/ulab/code/utils/utils.c msgid "out must be a float dense array" -msgstr "" +msgstr "out harus berupa array padat float" #: extmod/ulab/code/numpy/vector.c msgid "out must be an ndarray" -msgstr "" +msgstr "out harus berupa ndarray" #: extmod/ulab/code/numpy/vector.c msgid "out must be of float dtype" -msgstr "" +msgstr "out harus bertipe dtype float" #: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" -msgstr "" +msgstr "di luar jangkauan target" #: extmod/ulab/code/numpy/random/random.c msgid "output array has wrong type" -msgstr "" +msgstr "array output memiliki tipe yang salah" #: extmod/ulab/code/numpy/random/random.c msgid "output array must be contiguous" -msgstr "" +msgstr "array output harus berdekatan" #: py/objint_mpz.c msgid "overflow converting long int to machine word" -msgstr "" +msgstr "overflow saat mengonversi long int ke machine word" #: py/modstruct.c #, c-format msgid "pack expected %d items for packing (got %d)" -msgstr "" +msgstr "pack mengharapkan %d item untuk packing (mendapat %d)" #: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c msgid "palette must be 32 bytes long" -msgstr "" +msgstr "palet harus sepanjang 32 byte" #: py/emitinlinextensa.c msgid "parameters must be registers in sequence a2 to a5" -msgstr "" +msgstr "parameter harus berupa register dalam urutan a2 hingga a5" #: py/emitinlinethumb.c msgid "parameters must be registers in sequence r0 to r3" @@ -3872,7 +4031,7 @@ msgstr "parameter harus menjadi register dalam urutan r0 sampai r3" #: extmod/vfs_posix_file.c msgid "poll on file not available on win32" -msgstr "" +msgstr "poll pada file tidak tersedia di win32" #: ports/espressif/common-hal/pulseio/PulseIn.c msgid "pop from an empty PulseIn" @@ -3885,31 +4044,31 @@ msgstr "Muncul dari PulseIn yang kosong" #: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c #: shared-bindings/ps2io/Ps2.c msgid "pop from empty %q" -msgstr "" +msgstr "pop dari %q kosong" #: shared-bindings/socketpool/Socket.c msgid "port must be >= 0" -msgstr "" +msgstr "port harus >= 0" #: py/compile.c msgid "positional arg after **" -msgstr "" +msgstr "argumen posisional setelah **" #: py/compile.c msgid "positional arg after keyword arg" -msgstr "" +msgstr "argumen posisional setelah argumen keyword" #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" -msgstr "" +msgstr "argumen ketiga pow() tidak boleh 0" #: py/objint_mpz.c msgid "pow() with 3 arguments requires integers" -msgstr "" +msgstr "pow() dengan 3 argumen memerlukan integer" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" -msgstr "" +msgstr "mask pull berkonflik dengan mask arah" #: py/parse.c msgid "raw f-strings are not supported" @@ -3917,20 +4076,20 @@ msgstr "" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "real and imaginary parts must be of equal length" -msgstr "" +msgstr "bagian real dan imajiner harus memiliki panjang yang sama" #: py/builtinimport.c msgid "relative import" -msgstr "relative import" +msgstr "impor relatif" #: py/obj.c #, c-format msgid "requested length %d but object has length %d" -msgstr "" +msgstr "panjang yang diminta %d tetapi objek memiliki panjang %d" #: extmod/ulab/code/ndarray_operators.c msgid "results cannot be cast to specified type" -msgstr "" +msgstr "hasil tidak dapat di-cast ke tipe yang ditentukan" #: py/compile.c msgid "return annotation must be an identifier" @@ -3938,25 +4097,29 @@ msgstr "anotasi return harus sebuah identifier" #: py/emitnative.c msgid "return expected '%q' but got '%q'" -msgstr "" +msgstr "return mengharapkan '%q' tetapi mendapat '%q'" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "rgb_pins[%d] duplicates another pin assignment" -msgstr "" +msgstr "rgb_pins[%d] menduplikasi penetapan pin lain" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "rgb_pins[%d] is not on the same port as clock" -msgstr "" +msgstr "rgb_pins[%d] tidak pada port yang sama dengan clock" #: extmod/ulab/code/numpy/numerical.c msgid "roll argument must be an ndarray" -msgstr "" +msgstr "argumen roll harus berupa ndarray" #: py/objstr.c msgid "rsplit(None,n)" -msgstr "" +msgstr "rsplit(None,n)" + +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed harus true" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c @@ -3965,7 +4128,7 @@ msgstr "nilai sampling keluar dari jangkauan" #: py/modmicropython.c msgid "schedule queue full" -msgstr "" +msgstr "antrian jadwal penuh" #: py/builtinimport.c msgid "script compilation not supported" @@ -3973,43 +4136,43 @@ msgstr "kompilasi script tidak didukung" #: py/nativeglue.c msgid "set unsupported" -msgstr "" +msgstr "set tidak didukung" #: extmod/ulab/code/numpy/random/random.c msgid "shape must be None, and integer or a tuple of integers" -msgstr "" +msgstr "shape harus None, dan integer atau tuple integer" #: extmod/ulab/code/ndarray.c msgid "shape must be integer or tuple of integers" -msgstr "" +msgstr "shape harus integer atau tuple integer" #: shared-module/msgpack/__init__.c msgid "short read" -msgstr "" +msgstr "pembacaan pendek" #: py/objstr.c msgid "sign not allowed in string format specifier" -msgstr "" +msgstr "tanda tidak diperbolehkan dalam spesifier format string" #: py/objstr.c msgid "sign not allowed with integer format specifier 'c'" -msgstr "" +msgstr "tanda tidak diperbolehkan dengan spesifier format integer 'c'" #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" -msgstr "" +msgstr "size didefinisikan hanya untuk ndarray" #: extmod/ulab/code/numpy/random/random.c msgid "size must match out.shape when used together" -msgstr "" +msgstr "size harus cocok dengan out.shape ketika digunakan bersama" #: py/nativeglue.c msgid "slice unsupported" -msgstr "" +msgstr "slice tidak didukung" #: py/objint.c py/sequence.c msgid "small int overflow" -msgstr "" +msgstr "overflow int kecil" #: main.c msgid "soft reboot\n" @@ -4017,39 +4180,39 @@ msgstr "memulai ulang software(soft reboot)\n" #: extmod/ulab/code/numpy/numerical.c msgid "sort argument must be an ndarray" -msgstr "" +msgstr "argumen sort harus berupa ndarray" #: extmod/ulab/code/scipy/signal/signal.c msgid "sos array must be of shape (n_section, 6)" -msgstr "" +msgstr "array sos harus berbentuk (n_section, 6)" #: extmod/ulab/code/scipy/signal/signal.c msgid "sos[:, 3] should be all ones" -msgstr "" +msgstr "sos[:, 3] harus semuanya satu" #: extmod/ulab/code/scipy/signal/signal.c msgid "sosfilt requires iterable arguments" -msgstr "" +msgstr "sosfilt memerlukan argumen yang dapat diiterasi" #: shared-bindings/bitmaptools/__init__.c msgid "source palette too large" -msgstr "" +msgstr "palet sumber terlalu besar" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 2 or 65536" -msgstr "" +msgstr "source_bitmap harus memiliki value_count 2 atau 65536" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 65536" -msgstr "" +msgstr "source_bitmap harus memiliki value_count 65536" #: shared-bindings/bitmaptools/__init__.c msgid "source_bitmap must have value_count of 8" -msgstr "" +msgstr "source_bitmap harus memiliki value_count 8" #: extmod/modre.c msgid "splitting with sub-captures" -msgstr "" +msgstr "pemisahan dengan sub-capture" #: py/objstr.c msgid "start/end indices" @@ -4057,28 +4220,28 @@ msgstr "" #: shared-bindings/random/__init__.c msgid "stop not reachable from start" -msgstr "" +msgstr "stop tidak dapat dijangkau dari start" #: py/stream.c shared-bindings/getpass/__init__.c msgid "stream operation not supported" -msgstr "" +msgstr "operasi stream tidak didukung" #: py/objarray.c py/objstr.c msgid "string argument without an encoding" -msgstr "" +msgstr "argumen string tanpa encoding" #: py/objstrunicode.c msgid "string index out of range" -msgstr "" +msgstr "indeks string di luar jangkauan" #: py/objstrunicode.c #, c-format msgid "string indices must be integers, not %s" -msgstr "" +msgstr "indeks string harus integer, bukan %s" #: py/objarray.c py/objstr.c msgid "substring not found" -msgstr "" +msgstr "substring tidak ditemukan" #: py/compile.c msgid "super() can't find self" @@ -4090,115 +4253,115 @@ msgstr "sintaksis error pada JSON" #: extmod/modtime.c msgid "ticks interval overflow" -msgstr "" +msgstr "overflow interval tick" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "timeout duration exceeded the maximum supported value" -msgstr "" +msgstr "durasi timeout melebihi nilai maksimum yang didukung" #: ports/nordic/common-hal/_bleio/Adapter.c msgid "timeout must be < 655.35 secs" -msgstr "" +msgstr "timeout harus < 655.35 detik" #: ports/raspberrypi/common-hal/floppyio/__init__.c msgid "timeout waiting for flux" -msgstr "" +msgstr "timeout menunggu flux" #: ports/raspberrypi/common-hal/floppyio/__init__.c #: shared-module/floppyio/__init__.c msgid "timeout waiting for index pulse" -msgstr "" +msgstr "timeout menunggu pulsa indeks" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" -msgstr "" +msgstr "timeout menunggu kartu v1" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v2 card" -msgstr "" +msgstr "timeout menunggu kartu v2" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "timer re-init" -msgstr "" +msgstr "inisialisasi ulang timer" #: shared-bindings/time/__init__.c msgid "timestamp out of range for platform time_t" -msgstr "" +msgstr "timestamp di luar jangkauan untuk time_t platform" #: extmod/ulab/code/ndarray.c msgid "tobytes can be invoked for dense arrays only" -msgstr "" +msgstr "tobytes hanya dapat dipanggil untuk array padat" #: py/compile.c msgid "too many args" -msgstr "" +msgstr "terlalu banyak argumen" #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" -msgstr "" +msgstr "terlalu banyak dimensi" #: extmod/ulab/code/ndarray.c msgid "too many indices" -msgstr "" +msgstr "terlalu banyak indeks" #: py/asmthumb.c msgid "too many locals for native method" -msgstr "" +msgstr "terlalu banyak lokal untuk metode native" #: py/runtime.c #, c-format msgid "too many values to unpack (expected %d)" -msgstr "" +msgstr "terlalu banyak nilai untuk dibongkar (diharapkan %d)" #: extmod/ulab/code/numpy/approx.c msgid "trapz is defined for 1D arrays of equal length" -msgstr "" +msgstr "trapz didefinisikan untuk array 1D dengan panjang yang sama" #: extmod/ulab/code/numpy/approx.c msgid "trapz is defined for 1D iterables" -msgstr "" +msgstr "trapz didefinisikan untuk iterable 1D" #: py/obj.c msgid "tuple/list has wrong length" -msgstr "" +msgstr "tuple/list memiliki panjang yang salah" #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_driver_install returned esp-idf error #%d" -msgstr "" +msgstr "twai_driver_install mengembalikan kesalahan esp-idf #%d" #: ports/espressif/common-hal/canio/CAN.c #, c-format msgid "twai_start returned esp-idf error #%d" -msgstr "" +msgstr "twai_start mengembalikan kesalahan esp-idf #%d" #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" msgstr "tx dan rx keduanya tidak boleh kosong" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" -msgstr "" +msgid "type '%q' isn't an acceptable base type" +msgstr "tipe '%q' bukan tipe basis yang dapat diterima" #: py/objtype.c -msgid "type is not an acceptable base type" -msgstr "" +msgid "type isn't an acceptable base type" +msgstr "tipe bukan tipe basis yang dapat diterima" #: py/runtime.c msgid "type object '%q' has no attribute '%q'" -msgstr "" +msgstr "objek tipe '%q' tidak memiliki atribut '%q'" #: py/objtype.c msgid "type takes 1 or 3 arguments" -msgstr "" +msgstr "type memerlukan 1 atau 3 argumen" #: py/objint_longlong.c msgid "ulonglong too large" -msgstr "" +msgstr "ulonglong terlalu besar" #: py/parse.c msgid "unexpected indent" -msgstr "" +msgstr "indentasi tak terduga" #: py/bc.c msgid "unexpected keyword argument" @@ -4211,20 +4374,20 @@ msgstr "keyword argumen '%q' tidak diharapkan" #: py/lexer.c msgid "unicode name escapes" -msgstr "" +msgstr "escape nama unicode" #: py/parse.c msgid "unindent doesn't match any outer indent level" -msgstr "" +msgstr "unindent tidak cocok dengan tingkat indentasi luar mana pun" #: py/objstr.c #, c-format msgid "unknown conversion specifier %c" -msgstr "" +msgstr "spesifier konversi tidak dikenal %c" #: py/objstr.c msgid "unknown format code '%c' for object of type '%q'" -msgstr "" +msgstr "kode format tidak dikenal '%c' untuk objek bertipe '%q'" #: py/compile.c msgid "unknown type" @@ -4232,103 +4395,102 @@ msgstr "tipe tidak diketahui" #: py/compile.c msgid "unknown type '%q'" -msgstr "" +msgstr "tipe tidak dikenal '%q'" #: py/objstr.c #, c-format msgid "unmatched '%c' in format" -msgstr "" +msgstr "'%c' tidak cocok dalam format" #: py/objtype.c py/runtime.c msgid "unreadable attribute" -msgstr "" +msgstr "atribut tidak dapat dibaca" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" -msgstr "" +msgstr "tipe %q tidak didukung" #: py/emitinlinethumb.c #, c-format msgid "unsupported Thumb instruction '%s' with %d arguments" -msgstr "" +msgstr "instruksi Thumb tidak didukung '%s' dengan %d argumen" #: py/emitinlinextensa.c #, c-format msgid "unsupported Xtensa instruction '%s' with %d arguments" -msgstr "" +msgstr "instruksi Xtensa tidak didukung '%s' dengan %d argumen" #: shared-module/bitmapfilter/__init__.c msgid "unsupported bitmap depth" -msgstr "" +msgstr "kedalaman bitmap tidak didukung" #: shared-module/gifio/GifWriter.c msgid "unsupported colorspace for GifWriter" -msgstr "" +msgstr "colorspace tidak didukung untuk GifWriter" #: shared-bindings/bitmaptools/__init__.c msgid "unsupported colorspace for dither" -msgstr "" +msgstr "colorspace tidak didukung untuk dither" #: py/objstr.c #, c-format msgid "unsupported format character '%c' (0x%x) at index %d" -msgstr "" +msgstr "karakter format tidak didukung '%c' (0x%x) pada indeks %d" #: py/runtime.c msgid "unsupported type for %q: '%s'" -msgstr "" +msgstr "tipe tidak didukung untuk %q: '%s'" #: py/runtime.c msgid "unsupported type for operator" -msgstr "" +msgstr "tipe tidak didukung untuk operator" #: py/runtime.c msgid "unsupported types for %q: '%q', '%q'" -msgstr "" +msgstr "tipe tidak didukung untuk %q: '%q', '%q'" #: extmod/ulab/code/numpy/io/io.c msgid "usecols is too high" -msgstr "" +msgstr "usecols terlalu tinggi" #: extmod/ulab/code/numpy/io/io.c msgid "usecols keyword must be specified" -msgstr "" +msgstr "keyword usecols harus ditentukan" #: py/objint.c #, c-format msgid "value must fit in %d byte(s)" -msgstr "" +msgstr "nilai harus muat dalam %d byte" #: shared-bindings/bitmaptools/__init__.c msgid "value out of range of target" -msgstr "" +msgstr "nilai di luar jangkauan target" #: extmod/moddeflate.c msgid "wbits" -msgstr "" +msgstr "wbit" #: shared-bindings/bitmapfilter/__init__.c msgid "" "weights must be a sequence with an odd square number of elements (usually 9 " "or 25)" msgstr "" +"weights harus berupa urutan dengan jumlah persegi ganjil elemen (biasanya 9 " +"atau 25)" #: shared-bindings/bitmapfilter/__init__.c msgid "weights must be an object of type %q, %q, %q, or %q, not %q " -msgstr "" +msgstr "weights harus berupa objek bertipe %q, %q, %q, atau %q, bukan %q " #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" -msgstr "" - -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "wifi tidak diaktifkan" +msgstr "lebar harus lebih besar dari nol" #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" -msgstr "" +msgstr "wifi.Monitor tidak tersedia" #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" @@ -4344,11 +4506,11 @@ msgstr "sumbu yang ditentukan salah" #: extmod/ulab/code/numpy/io/io.c msgid "wrong dtype" -msgstr "" +msgstr "dtype salah" #: extmod/ulab/code/numpy/transform.c msgid "wrong index type" -msgstr "" +msgstr "tipe indeks salah" #: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c #: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c @@ -4358,11 +4520,11 @@ msgstr "tipe input salah" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of condition array" -msgstr "" +msgstr "panjang array kondisi salah" #: extmod/ulab/code/numpy/transform.c msgid "wrong length of index array" -msgstr "" +msgstr "panjang array indeks salah" #: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c msgid "wrong number of arguments" @@ -4388,6 +4550,44 @@ msgstr "zi harus berjenis float" msgid "zi must be of shape (n_section, 2)" msgstr "Zi harus berbentuk (n_section, 2)" +#~ msgid "Unsupported format" +#~ msgstr "Format tidak didukung" + +#~ msgid "Wifi is not enabled" +#~ msgstr "Wifi tidak diaktifkan" + +#~ msgid "wifi is not enabled" +#~ msgstr "wifi tidak diaktifkan" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "Tidak dapat memasang kembali '/' saat terlihat melalui USB." + +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q harus berupa objek %q, %q, atau %q" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Potongan data harus mengikuti fmt chunk" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Hanya monokrom, 4bpp atau 8bpp yang diindeks, dan 16bpp atau lebih yang " +#~ "didukung: %d bpp diberikan" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "Sampel bits_per_sampel tidak cocok dengan mixer" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "Jumlah saluran sampel tidak cocok dengan mixer" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "Tingkat sampel dari sampel tidak cocok dengan mixer" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "signedness dari sampel tidak cocok dengan mixer" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Panjang buffer harus kelipatan 512" @@ -4559,13 +4759,13 @@ msgstr "Zi harus berbentuk (n_section, 2)" #~ msgid "'%s' object does not support item deletion" #~ msgstr "Objek '%s' tidak mendukung penghapusan item" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "Objek '%s' bukan iterator" #~ msgid "'%s' object is not callable" #~ msgstr "Objek '%s' tidak dapat dipanggil" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "'%s' objek tidak dapat diulang" #~ msgid "'%s' object is not subscriptable" @@ -5375,7 +5575,7 @@ msgstr "Zi harus berbentuk (n_section, 2)" #~ msgid "frequency can only be either 80Mhz or 160MHz" #~ msgstr "frekuensi hanya bisa didefinisikan 80Mhz atau 160Mhz" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "fungsi tidak dapat mengambil argumen keyword" #~ msgid "impossible baudrate" @@ -5430,7 +5630,7 @@ msgstr "Zi harus berbentuk (n_section, 2)" #~ msgid "name must be a string" #~ msgstr "keyword harus berupa string" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "nama digunakan kembali untuk argumen" #~ msgid "non-keyword arg after */**" diff --git a/locale/circuitpython.pot b/locale/circuitpython.pot index 0b19dce9c42..130bb695683 100644 --- a/locale/circuitpython.pot +++ b/locale/circuitpython.pot @@ -16,1653 +16,1906 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: main.c -msgid "" -"\n" -"Code done running.\n" +#: extmod/modasyncio.c extmod/modheapq.c +msgid "empty heap" msgstr "" -#: main.c -msgid "" -"\n" -"Code stopped by auto-reload. Reloading soon.\n" +#: extmod/modasyncio.c +msgid "can't cancel self" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Please file an issue with your program at github.com/adafruit/circuitpython/" -"issues." +#: extmod/modasyncio.c +msgid "can't wait" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Press reset to exit safe mode.\n" +#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c +msgid "a bytes-like object is required" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"You are in safe mode because:\n" +#: extmod/modbinascii.c +msgid "incorrect padding" msgstr "" -#: py/obj.c -msgid " File \"%q\"" +#: extmod/moddeflate.c +msgid "format" msgstr "" -#: py/obj.c -msgid " File \"%q\", line %d" +#: extmod/moddeflate.c +msgid "wbits" msgstr "" -#: py/builtinhelp.c -msgid " is of type %q\n" +#: extmod/modhashlib.c +msgid "hash is final" msgstr "" -#: main.c -msgid " not found.\n" +#: extmod/modheapq.c +msgid "heap must be a list" msgstr "" -#: main.c -msgid " output:\n" +#: extmod/modjson.c +msgid "syntax error in JSON" msgstr "" -#: py/objstr.c -#, c-format -msgid "%%c requires int or char" +#: extmod/modrandom.c +msgid "bits must be 32 or less" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c +msgid "no default seed" msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q and %q contain duplicate pins" +#: extmod/modre.c +msgid "splitting with sub-captures" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "%q and %q must be different" +#: extmod/modre.c +msgid "regex too complex" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "%q and %q must share a clock unit" +#: extmod/modre.c +msgid "Error in regex" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "%q cannot be changed once mode is set to %q" +#: extmod/modtime.c +msgid "mktime needs a tuple of length 8 or 9" msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q contains duplicate pins" +#: extmod/modtime.c +msgid "ticks interval overflow" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -msgid "%q failure: %d" +#: extmod/modzlib.c +msgid "compression header" msgstr "" -#: py/argcheck.c -msgid "%q in %q must be of type %q, not %q" +#: extmod/ulab/code/ndarray.c +msgid "data type not understood" msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/usb_host/Port.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c -msgid "%q in use" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" msgstr "" -#: py/objstr.c -msgid "%q index out of range" +#: extmod/ulab/code/ndarray.c +msgid "ndarray length overflows" msgstr "" -#: py/obj.c -msgid "%q indices must be integers, not %s" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex type" msgstr "" -#: shared-module/bitbangio/SPI.c -msgid "%q init failed" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c +msgid "too many dimensions" msgstr "" -#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c -msgid "%q is %q" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c +msgid "index is out of bounds" msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "%q is read-only for this board" +#: extmod/ulab/code/ndarray.c +msgid "indices must be integers, slices, or Boolean lists" msgstr "" -#: py/argcheck.c shared-bindings/usb_hid/Device.c -msgid "%q length must be %d" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c +msgid "operands could not be broadcast together" msgstr "" -#: py/argcheck.c -msgid "%q length must be %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "array and index length must be equal" msgstr "" -#: py/argcheck.c -msgid "%q length must be <= %d" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex to dtype" msgstr "" -#: py/argcheck.c -msgid "%q length must be >= %d" +#: extmod/ulab/code/ndarray.c +msgid "operation is implemented for 1D Boolean arrays only" msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c -msgid "%q moved from %q to %q" +#: extmod/ulab/code/ndarray.c +msgid "too many indices" msgstr "" -#: py/argcheck.c -msgid "%q must be %d" +#: extmod/ulab/code/ndarray.c +msgid "cannot delete array elements" msgstr "" -#: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "%q must be %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "flattening order must be either 'C', or 'F'" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -msgid "%q must be 1 when %q is True" +#: extmod/ulab/code/ndarray.c +msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: py/argcheck.c shared-bindings/gifio/GifWriter.c -#: shared-module/gifio/OnDiskGif.c -msgid "%q must be <= %d" +#: extmod/ulab/code/ndarray.c +msgid "operation is not supported for given type" msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "%q must be <= %u" +#: extmod/ulab/code/ndarray.c +msgid "shape must be integer or tuple of integers" msgstr "" -#: py/argcheck.c -msgid "%q must be >= %d" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c +msgid "maximum number of dimensions is " msgstr "" -#: shared-bindings/analogbufio/BufferedIn.c -msgid "%q must be a bytearray or array of type 'H' or 'B'" +#: extmod/ulab/code/ndarray.c +msgid "can only specify one unknown dimension" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +#: extmod/ulab/code/ndarray.c +msgid "cannot reshape array" msgstr "" -#: shared-bindings/warnings/__init__.c -msgid "%q must be a subclass of %q" +#: extmod/ulab/code/ndarray.c +msgid "cannot assign new shape" msgstr "" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -msgid "%q must be array of type 'H'" +#: extmod/ulab/code/ndarray.c +msgid "function is defined for ndarrays only" msgstr "" -#: shared-module/synthio/__init__.c -msgid "%q must be array of type 'h'" +#: extmod/ulab/code/ndarray_operators.c +msgid "operation not supported for the input types" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "%q must be multiple of 8." +#: extmod/ulab/code/ndarray_operators.c +msgid "dtype of int32 is not supported" msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c -#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c -#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c -#: shared-module/synthio/Synthesizer.c -msgid "%q must be of type %q or %q, not %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "cannot cast output with casting rule" msgstr "" -#: shared-bindings/jpegio/JpegDecoder.c -msgid "%q must be of type %q, %q, or %q, not %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "results cannot be cast to specified type" msgstr "" -#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c -#: shared-module/synthio/__init__.c -msgid "%q must be of type %q, not %q" +#: extmod/ulab/code/numpy/approx.c +msgid "interp is defined for 1D iterables of equal length" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -msgid "%q must be power of 2" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D iterables" msgstr "" -#: shared-bindings/wifi/Monitor.c -msgid "%q out of bounds" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c -#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c -msgid "%q out of range" +#: extmod/ulab/code/numpy/bitwise.c +msgid "not supported for input types" msgstr "" -#: py/objmodule.c py/runtime.c -msgid "%q renamed %q" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "function is implemented for ndarrays only" msgstr "" -#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c -msgid "%q step cannot be zero" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be an ndarray, or a scalar" msgstr "" -#: shared-module/bitbangio/I2C.c -msgid "%q too long" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be a 1D ndarray" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "%q() takes %d positional arguments but %d were given" +#: extmod/ulab/code/numpy/carray/carray_tools.c +msgid "not implemented for complex dtype" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "%q() without %q()" +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c +#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c +#: extmod/ulab/code/numpy/vector.c +msgid "wrong input type" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q, %q, and %q must all be the same length" +#: extmod/ulab/code/numpy/create.c +msgid "input argument must be an integer, a tuple, or a list" msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c -msgid "%q=%q" +#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c +msgid "wrong number of arguments" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts in more bits than pin count" +#: extmod/ulab/code/numpy/create.c py/objint_longlong.c py/objint_mpz.c +msgid "divide by zero" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts out more bits than pin count" +#: extmod/ulab/code/numpy/create.c +msgid "arange: cannot compute length" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] uses extra pin" +#: extmod/ulab/code/numpy/create.c +msgid "first argument must be a tuple of ndarrays" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] waits on input outside of count" +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -#, c-format -msgid "%s error 0x%x" +#: extmod/ulab/code/numpy/create.c +msgid "wrong axis specified" msgstr "" -#: py/argcheck.c -msgid "'%q' argument required" +#: extmod/ulab/code/numpy/create.c +msgid "input arrays are not compatible" msgstr "" -#: py/proto.c -msgid "'%q' object does not support '%q'" +#: extmod/ulab/code/numpy/create.c +msgid "input must be 1- or 2-d" msgstr "" -#: py/runtime.c -msgid "'%q' object is not an iterator" +#: extmod/ulab/code/numpy/create.c +msgid "number of points must be at least 2" msgstr "" -#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c -msgid "'%q' object is not callable" +#: extmod/ulab/code/numpy/create.c +msgid "offset must be non-negative and no greater than buffer length" msgstr "" -#: py/runtime.c -msgid "'%q' object is not iterable" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer size must be a multiple of element size" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a label" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer is smaller than requested size" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a register" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is defined for ndarrays only" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects a special register" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is implemented for linear arrays only" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an FPU register" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "input array length must be power of 2" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an address of the form [a, b]" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "real and imaginary parts must be of equal length" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects an integer" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be ndarrays" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects at most r%d" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be linear arrays" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects {r0, r1, ...}" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must not be empty" msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "'%s' integer %d isn't within range %d..%d" +#: extmod/ulab/code/numpy/io/io.c +msgid "corrupted file" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" +#: extmod/ulab/code/numpy/io/io.c +msgid "wrong dtype" msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item assignment" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols keyword must be specified" msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item deletion" +#: extmod/ulab/code/numpy/io/io.c +msgid "empty file" msgstr "" -#: py/runtime.c -msgid "'%s' object has no attribute '%q'" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols is too high" msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object isn't subscriptable" +#: extmod/ulab/code/numpy/io/io.c +msgid "array has too many dimensions" msgstr "" -#: py/objstr.c -msgid "'=' alignment not allowed in string format specifier" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "input matrix is asymmetric" msgstr "" -#: shared-module/struct/__init__.c -msgid "'S' and 'O' are not supported format types" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "matrix is not positive definite" msgstr "" -#: py/compile.c -msgid "'align' requires 1 argument" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "iterations did not converge" msgstr "" -#: py/compile.c -msgid "'await' outside function" +#: extmod/ulab/code/numpy/linalg/linalg.c +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "input matrix is singular" msgstr "" -#: py/compile.c -msgid "'break'/'continue' outside loop" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for ndarrays only" msgstr "" -#: py/compile.c -msgid "'data' requires at least 2 arguments" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for 2D arrays only" msgstr "" -#: py/compile.c -msgid "'data' requires integer arguments" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "mode must be complete, or reduced" msgstr "" -#: py/compile.c -msgid "'label' requires 1 argument" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" msgstr "" -#: py/emitnative.c -msgid "'not' not implemented" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get (arg)min/(arg)max of empty sequence" msgstr "" -#: py/compile.c -msgid "'return' outside function" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +msgid "axis must be None, or an integer" msgstr "" -#: py/compile.c -msgid "'yield from' inside async function" +#: extmod/ulab/code/numpy/numerical.c +msgid "operation is not implemented on ndarrays" msgstr "" -#: py/compile.c -msgid "'yield' outside function" +#: extmod/ulab/code/numpy/numerical.c +msgid "input must be tuple, list, range, or ndarray" msgstr "" -#: py/compile.c -msgid "* arg after **" +#: extmod/ulab/code/numpy/numerical.c +msgid "sort argument must be an ndarray" msgstr "" -#: py/compile.c -msgid "*x must be assignment target" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort argument must be an ndarray" msgstr "" -#: py/obj.c -msgid ", in %q\n" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort is not implemented for flattened arrays" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid ".show(x) removed. Use .root_group = x" +#: extmod/ulab/code/numpy/numerical.c +msgid "axis too long" msgstr "" -#: py/objcomplex.c -msgid "0.0 to a complex power" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c +msgid "arguments must be ndarrays" msgstr "" -#: py/modbuiltins.c -msgid "3-arg pow() not supported" +#: extmod/ulab/code/numpy/numerical.c +msgid "cross is defined for 1D arrays of length 3" msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "AP could not be started" +#: extmod/ulab/code/numpy/numerical.c +msgid "diff argument must be an ndarray" msgstr "" -#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, c-format -msgid "Address must be %d bytes long" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" -#: ports/espressif/common-hal/memorymap/AddressRange.c -#: ports/nordic/common-hal/memorymap/AddressRange.c -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Address range not allowed" +#: extmod/ulab/code/numpy/numerical.c +msgid "differentiation order out of range" msgstr "" -#: shared-bindings/memorymap/AddressRange.c -msgid "Address range wraps around" +#: extmod/ulab/code/numpy/numerical.c +msgid "flip argument must be an ndarray" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "All CAN peripherals are in use" +#: extmod/ulab/code/numpy/numerical.c +msgid "wrong axis index" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/nordic/common-hal/busio/I2C.c -msgid "All I2C peripherals are in use" +#: extmod/ulab/code/numpy/numerical.c +msgid "median argument must be an ndarray" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "All RX FIFOs in use" +#: extmod/ulab/code/numpy/numerical.c +msgid "roll argument must be an ndarray" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c -msgid "All SPI peripherals are in use" +#: extmod/ulab/code/numpy/poly.c +msgid "input data must be an iterable" msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c -msgid "All UART peripherals are in use" +#: extmod/ulab/code/numpy/poly.c +msgid "more degrees of freedom than data points" msgstr "" -#: ports/nordic/common-hal/countio/Counter.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c -msgid "All channels in use" +#: extmod/ulab/code/numpy/poly.c +msgid "input vectors must be of equal length" msgstr "" -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All dma channels in use" +#: extmod/ulab/code/numpy/poly.c +msgid "could not invert Vandermonde matrix" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "All event channels in use" +#: extmod/ulab/code/numpy/poly.c +msgid "input is not iterable" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All state machines in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "argument must be None, an integer or a tuple of integers" msgstr "" -#: ports/atmel-samd/audio_dma.c -msgid "All sync event channels in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "shape must be None, and integer or a tuple of integers" msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -msgid "All timers for this pin are in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "out has wrong type" msgstr "" -#: ports/atmel-samd/common-hal/_pew/PewPew.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/peripherals/nrf/timers.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c -msgid "All timers in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array has wrong type" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Already advertising." +#: extmod/ulab/code/numpy/random/random.c +msgid "size must match out.shape when used together" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -msgid "Already have all-matches listener" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array must be contiguous" msgstr "" -#: ports/espressif/bindings/espnow/ESPNow.c -#: ports/espressif/common-hal/espulp/ULP.c -#: shared-module/memorymonitor/AllocationAlarm.c -#: shared-module/memorymonitor/AllocationSize.c -msgid "Already running" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of condition array" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Already scanning for wifi networks" +#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c +msgid "first argument must be an ndarray" msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "An error occurred while retrieving '%s':\n" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong index type" msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Another PWMAudioOut is already active" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of index array" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -msgid "Another send is already active" +#: extmod/ulab/code/numpy/transform.c +msgid "dimensions do not match" msgstr "" -#: shared-bindings/pulseio/PulseOut.c -msgid "Array must contain halfwords (type 'H')" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be an ndarray" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Array values should be single bytes." +#: extmod/ulab/code/numpy/vector.c +msgid "out must be of float dtype" msgstr "" -#: shared-module/memorymonitor/AllocationAlarm.c -#, c-format -msgid "Attempt to allocate %d blocks" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output dimensions differ" msgstr "" -#: ports/raspberrypi/audio_dma.c -msgid "Audio conversion not implemented" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output shapes differ" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "AuthMode.OPEN is not used with password" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for function" msgstr "" -#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c -msgid "Authentication failure" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for complex dtype" msgstr "" -#: main.c -msgid "Auto-reload is off.\n" +#: extmod/ulab/code/numpy/vector.c +msgid "dtype must be float, or complex" msgstr "" -#: main.c -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" +#: extmod/ulab/code/numpy/vector.c +msgid "can't convert complex to float" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "Baudrate not supported by peripheral" +#: extmod/ulab/code/numpy/vector.c +msgid "input dtype must be float or complex" msgstr "" -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Below minimum frame rate" +#: extmod/ulab/code/numpy/vector.c +msgid "first argument must be a callable" msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Bit clock and word select must be sequential GPIO pins" +#: extmod/ulab/code/numpy/vector.c +msgid "wrong output type" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Bitmap size and bits per value must match" +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "first two arguments must be ndarrays" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Boot device must be first (interface #0)." +#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c +msgid "input must be a dense ndarray" msgstr "" -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Both RX and TX required for flow control" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "first argument must be a function" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Brightness not adjustable" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "function has the same sign at the ends of interval" msgstr "" -#: shared-bindings/_bleio/UUID.c -#, c-format -msgid "Buffer + offset too small %d %d %d" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter should be > 0" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Buffer elements must be 4 bytes long or less" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter must be > 0" msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Buffer is not a bytearray." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be iterable" msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, c-format -msgid "Buffer length %d too big. It must be less than %d" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "initial values must be iterable" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -#: ports/cxd56/common-hal/sdioio/SDCard.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c -#: shared-module/sdcardio/SDCard.c -#, c-format -msgid "Buffer must be a multiple of %d bytes" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be of equal length" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -#, c-format -msgid "Buffer too short by %d bytes" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sosfilt requires iterable arguments" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c -msgid "Buffer too small" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "input must be one-dimensional" msgstr "" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, c-format -msgid "Bus pin %d is already in use" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be an ndarray" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "Byte buffer must be 16 bytes." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of shape (n_section, 2)" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "CBC blocks must be multiples of 16 bytes" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of float type" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CIRCUITPY drive could not be found or created." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos array must be of shape (n_section, 6)" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "CRC or checksum was invalid" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos[:, 3] should be all ones" msgstr "" -#: py/objtype.c -msgid "Call super().__init__() before accessing native object." +#: extmod/ulab/code/ulab_tools.c +msgid "axis is out of bounds" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Camera init" +#: extmod/ulab/code/ulab_tools.c +msgid "size is defined for ndarrays only" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on RTC IO from deep sleep." +#: extmod/ulab/code/ulab_tools.c +msgid "input must be square matrix" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on one low pin while others alarm high from deep sleep." +#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c +msgid "input must be an ndarray" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on two low pins from deep sleep." +#: extmod/ulab/code/utils/utils.c +msgid "out must be a float dense array" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "Can't set CCCD on local Characteristic" +#: extmod/ulab/code/utils/utils.c +msgid "offset is too large" msgstr "" -#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c -#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c -#: shared-bindings/usb_video/__init__.c -msgid "Cannot change USB devices now" +#: extmod/ulab/code/utils/utils.c +msgid "out array is too small" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot create a new Adapter; use _bleio.adapter;" +#: extmod/vfs_fat.c py/moderrno.c +msgid "Read-only filesystem" msgstr "" -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Cannot delete values" +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" msgstr "" -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c -#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c -#: ports/nordic/common-hal/digitalio/DigitalInOut.c -#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c -msgid "Cannot get pull while in output mode" +#: extmod/vfs_posix_file.c +msgid "poll on file not available on win32" msgstr "" -#: ports/nordic/common-hal/microcontroller/Processor.c -msgid "Cannot get temperature" +#: main.c +msgid "Done" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot have scan responses for extended, connectable advertisements." +#: main.c +msgid " output:\n" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot pull on input-only pin." +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Cannot record to a file" +#: main.c +msgid "Auto-reload is off.\n" msgstr "" -#: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." +#: main.c +msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Cannot set value when direction is input." +#: main.c +msgid " not found.\n" msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Cannot specify RTS or CTS in RS485 mode" +#: main.c +msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: py/objslice.c -msgid "Cannot subclass slice" +#: main.c +msgid "" +"\n" +"Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: ports/nordic/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge, only level" +#: main.c +msgid "" +"\n" +"Code done running.\n" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge. Only level." +#: main.c +msgid "Woken up by alarm.\n" msgstr "" -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "CharacteristicBuffer writing not provided" +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +#: main.c +msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +msgstr "" + +#: main.c +msgid "UID:" +msgstr "" + +#: main.c +msgid "soft reboot\n" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c +#: ports/stm/common-hal/audioio/AudioOut.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c +#: shared-module/busdisplay/BusDisplay.c shared-module/ssl/SSLContext.c +msgid "%q init failed" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c +#: shared-bindings/bitmaptools/__init__.c shared-bindings/canio/Match.c +#: shared-bindings/time/__init__.c +msgid "%q out of range" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid state" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Both RX and TX required for flow control" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c +msgid "Failed to allocate %q buffer" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c +#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/microcontroller/Processor.c +#: ports/espressif/common-hal/mipidsi/Display.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +#: ports/raspberrypi/bindings/picodvi/Framebuffer.c +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c +msgid "Invalid %q" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + +#: ports/atmel-samd/audio_dma.c +msgid "All sync event channels in use" +msgstr "" + +#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "" + +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/atmel-samd/common-hal/_pew/PewPew.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "All timers in use" +msgstr "" + +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: ports/atmel-samd/common-hal/countio/Counter.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/max3421e/Max3421E.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +msgid "Internal resource(s) in use" +msgstr "" + +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c #: supervisor/shared/safe_mode.c -msgid "CircuitPython core code crashed hard. Whoops!\n" +msgid "Unknown reason." +msgstr "" + +#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +#: ports/nordic/common-hal/alarm/time/TimeAlarm.c +#: ports/stm/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "No DAC on chip" msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Clock unit in use" +msgid "%q and %q must share a clock unit" msgstr "" -#: shared-bindings/_bleio/Connection.c -msgid "" -"Connection has been disconnected and can no longer be used. Create a new " -"connection." +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays have different lengths" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays types have different sizes" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Could not set address" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "Could not start interrupt, RX busy" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "No DMA channel found" msgstr "" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Couldn't allocate decoder" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Unable to allocate buffers for signed conversion" msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Channel Init Error" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +#, c-format +msgid "Only 8 or 16 bit mono with %dx oversampling supported." msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Device Init Error" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "DAC already in use" msgstr "" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/I2C.c +#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/busio/I2C.c +msgid "No pull up found on SDA or SCL; check your wiring" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "%q must be power of 2" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c +#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c +#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c +#: shared-bindings/paralleldisplaybus/ParallelBus.c +#: shared-bindings/qspibus/QSPIBus.c shared-module/bitbangio/SPI.c +msgid "No %q pin" +msgstr "" + +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +#: ports/nordic/common-hal/digitalio/DigitalInOut.c +#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_pins[%d]" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c +#: shared-bindings/microcontroller/Pin.c +msgid "Invalid %q pin" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +#: ports/cxd56/common-hal/microcontroller/__init__.c +#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c +msgid "No bootloader present" +msgstr "" + #: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c #: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c msgid "Data 0 pin must be byte aligned" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Data format error (may be broken data)" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/pulseio/PulseIn.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c +#: shared-bindings/ps2io/Ps2.c +msgid "pop from empty %q" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data not supported with directed advertising" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "Input taking too long" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data too large for advertisement packet" +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Deep sleep pins must use a rising edge with pulldown" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "%q failure: %d" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Destination capacity is smaller than destination_length." +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/cxd56/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c +#: shared-module/sdcardio/SDCard.c +#, c-format +msgid "Buffer must be a multiple of %d bytes" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Device error or wrong termination of input stream" +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." msgstr "" -#: ports/nordic/common-hal/audiobusio/I2SOut.c -msgid "Device in use" +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/stm/common-hal/busio/UART.c +msgid "UART init" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display must have a 16 bit colorspace." +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Camera init" +msgstr "" + +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Size not supported" msgstr "" +#: ports/cxd56/common-hal/camera/Camera.c #: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display rotation must be in 90 degree increments" +#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c +msgid "Buffer too small" msgstr "" -#: main.c -msgid "Done" +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c +msgid "Format not supported" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Drive mode not used when direction is input." +#: ports/cxd56/common-hal/gnss/GNSS.c +msgid "GNSS init" msgstr "" -#: py/obj.c -msgid "During handling of the above exception, another exception occurred:" +#: ports/cxd56/common-hal/sdioio/SDCard.c +msgid "SDCard init" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "ECB only operates on 16 bytes at a time" +#: ports/espressif/bindings/espnow/ESPNow.c +#: ports/espressif/common-hal/espulp/ULP.c +#: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize.c +msgid "Already running" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/canio/CAN.c -msgid "ESP-IDF memory allocation failed" +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c +msgid "%q is %q" msgstr "" -#: extmod/modre.c -msgid "Error in regex" +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Error in safemode.py." +#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h +#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h +msgid "You pressed the BOOT button at start up." msgstr "" -#: shared-bindings/alarm/__init__.c -msgid "Expected a kind of %q" +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Extended advertisements with scan response not supported." +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is defined for ndarrays only" +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +#: ports/espressif/boards/vidi_x/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is implemented for linear arrays only" +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." msgstr "" -#: shared-bindings/ps2io/Ps2.c -msgid "Failed sending command." +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to acquire mutex, err 0x%04x" +#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h +msgid "You pressed button DOWN at start up." msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Failed to add service TXT record" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Update failed" msgstr "" -#: shared-bindings/mdns/Server.c -msgid "" -"Failed to add service TXT record; non-string or bytes found in txt_records" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Scan already in progress. Stop with stop_scan." msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "Failed to allocate %q buffer" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: internal error" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to allocate Wifi memory" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data too large for advertisement packet" msgstr "" -#: ports/espressif/common-hal/wifi/ScannedNetworks.c -msgid "Failed to allocate wifi scan memory" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Already advertising." msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Failed to buffer the sample" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Extended advertisements with scan response not supported." msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: internal error" +msgid "Data not supported with directed advertising" msgstr "" +#: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: timeout" +#, c-format +msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Failed to parse MP3 file" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +msgid "MITM security not supported" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +msgid "Too many descriptors" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Connection.c +#: ports/nordic/common-hal/_bleio/Connection.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" -#: ports/nordic/sd_mutex.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c #, c-format -msgid "Failed to release mutex, err 0x%04x" +msgid "max_length must be 0-%d when fixed_length is %s" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Failed to write internal flash." +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Writes not supported on Characteristic" msgstr "" -#: py/moderrno.c -msgid "File exists" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Total data to write is larger than %q" msgstr "" -#: shared-module/os/getenv.c -msgid "File not found" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Nimble out of memory" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "Filters too complex" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid BLE parameter" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is duplicate" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#: ports/zephyr-cp/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "Not connected" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is invalid" +#: ports/espressif/common-hal/_bleio/__init__.c +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Already in progress" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is too big" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error at %s:%d: %d" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %d" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient authentication" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Format not supported" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient encryption" msgstr "" -#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c -msgid "" -"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error at %s:%d: %d" msgstr "" -#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c -#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c -msgid "Function requires lock" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error: %d" msgstr "" -#: ports/cxd56/common-hal/gnss/GNSS.c -msgid "GNSS init" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge. Only level." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Generic Failure" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot pull on input-only pin." msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Group already used" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on two low pins from deep sleep." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Hard fault: memory access or instruction error." +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c -#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c -#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c -msgid "Hardware in use, try alternative pins" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on RTC IO from deep sleep." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Heap allocation when VM not running." +#: ports/espressif/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set." msgstr "" -#: extmod/vfs_posix_file.c py/objstringio.c -msgid "I/O operation on closed file" +#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/stm/common-hal/busio/I2C.c -msgid "I2C init error" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: ports/raspberrypi/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "I2C peripheral in use" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +#: shared-bindings/audioi2sin/I2SIn.c +msgid "%q must be 8, 16, 24, or 32" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "In-buffer elements must be <= 4 bytes long" +#: ports/espressif/common-hal/audiobusio/__init__.c +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +msgid "Peripheral in use" msgstr "" -#: shared-bindings/_pew/PewPew.c -msgid "Incorrect buffer size" +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 8 or 16" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Init program size invalid" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin direction conflicts with initial out pin direction" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin state conflicts with initial out pin state" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" msgstr "" -#: shared-bindings/bitops/__init__.c -#, c-format -msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -msgid "Input taking too long" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" msgstr "" -#: py/moderrno.c -msgid "Input/output error" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient authentication" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient encryption" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient memory pool for the image" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient stream input buffer" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Interface must be started" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/nordic/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" msgstr "" -#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c -msgid "Internal audio buffer too small" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c +msgid "Unable to create lock" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "Internal define error" +#: ports/espressif/common-hal/busio/SPI.c +msgid "SPI configuration failed" msgstr "" -#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c -msgid "Internal error" +#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Internal error #%d" +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/canio/CAN.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "ESP-IDF memory allocation failed" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: ports/atmel-samd/common-hal/countio/Counter.c -#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c -#: ports/atmel-samd/common-hal/max3421e/Max3421E.c -#: ports/atmel-samd/common-hal/ps2io/Ps2.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-bindings/pwmio/PWMOut.c -msgid "Internal resource(s) in use" +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Cannot specify RTS or CTS in RS485 mode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Internal watchdog timer expired." +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "RS485 inversion specified when not in RS485 mode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Interrupt error." +#: ports/espressif/common-hal/canio/CAN.c +msgid "Baudrate not supported by peripheral" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Interrupted by output function" +#: ports/espressif/common-hal/canio/CAN.c +msgid "All CAN peripherals are in use" msgstr "" -#: ports/espressif/common-hal/_bleio/Service.c -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/espressif/common-hal/microcontroller/Processor.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c -#: ports/raspberrypi/bindings/picodvi/Framebuffer.c -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q" +#: ports/espressif/common-hal/canio/CAN.c +msgid "loopback + silent mode not supported by peripheral" msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q and %q" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_driver_install returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c -#: shared-bindings/microcontroller/Pin.c -msgid "Invalid %q pin" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/stm/common-hal/analogio/AnalogIn.c -msgid "Invalid ADC Unit value" +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +msgid "Must provide 5/6/5 RGB pins" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Invalid BLE parameter" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is duplicate" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid BSSID" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid MAC address" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c -msgid "Invalid argument" +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c +msgid "no such attribute" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Invalid bits per value" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "Invalid byte %.*s" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Generic Failure" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c -#, c-format -msgid "Invalid data_pins[%d]" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Out of memory" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "Invalid format" +#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c +msgid "Invalid argument" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Invalid size" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Requested resource not found" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid hex password" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Invalid multicast MAC address" +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "Operation timed out" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid size" +msgid "Received response was invalid" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "Invalid socket for TLS" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "CRC or checksum was invalid" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid state" +msgid "Version was invalid" msgstr "" -#: shared-module/os/getenv.c -msgid "Invalid unicode escape" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "MAC address was invalid" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Key must be 16, 24, or 32 bytes long" +#: ports/espressif/common-hal/espidf/__init__.c +#, c-format +msgid "%s error 0x%x" msgstr "" -#: shared-module/os/getenv.c -msgid "Key not found" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" msgstr "" -#: shared-module/is31fl3741/FrameBuffer.c -msgid "LED mappings must match display size" +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/mipidsi/Bus.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/usb_host/Port.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c +msgid "%q in use" msgstr "" -#: py/compile.c -msgid "LHS of keyword arg must be an id" +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer already in a group" +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "Only one address is allowed" msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer must be a Group or TileGrid subclass" +#: ports/espressif/common-hal/max3421e/Max3421E.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "Length of %q must be an even multiple of channel_count * type_size" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS only works with built-in WiFi" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "MAC address was invalid" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS already initialized" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/espressif/common-hal/_bleio/Descriptor.c -msgid "MITM security not supported" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Unable to start mDNS query" msgstr "" -#: shared-bindings/is31fl3741/IS31FL3741.c -msgid "Mapping must be a tuple" +#: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nordic/common-hal/memorymap/AddressRange.c +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched data size" +#: ports/espressif/common-hal/nvm/ByteArray.c +msgid "NVS Error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched swap flag" +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d or %d, not %d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] reads pin(s)" +#: ports/espressif/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] waits based on pin" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-bindings/pwmio/PWMOut.c +#: supervisor/shared/settings.c +msgid "Internal error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] writes pin(s)" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_set_pin. %q[%u] sets pin(s)" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing jmp_pin. %q[%u] jumps on pin" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" msgstr "" -#: shared-module/storage/__init__.c -msgid "Mount point directory missing" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c -msgid "Must be a %q subclass." +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" msgstr "" -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -msgid "Must provide 5/6/5 RGB pins" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c -msgid "Must provide MISO or MOSI pin" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "Must use a multiple of 6 rgb pins, not %d" +msgid "SDIO Init Error 0x%02x" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "NLR jump failed. Likely memory corruption." +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Unsupported socket type" msgstr "" -#: ports/espressif/common-hal/nvm/ByteArray.c -msgid "NVS Error" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Out of sockets" msgstr "" -#: shared-bindings/socketpool/SocketPool.c -msgid "Name or service not known" +#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "New bitmap must be same size as old bitmap" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +msgid "%q must be <= %u" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -msgid "Nimble out of memory" +#: ports/espressif/common-hal/wifi/Monitor.c +msgid "monitor init failed" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c -#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c -#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c -#: shared-bindings/paralleldisplaybus/ParallelBus.c -#: shared-module/bitbangio/SPI.c -msgid "No %q pin" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Interface must be started" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "No CCCD for this Characteristic" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Invalid multicast MAC address" msgstr "" -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "No DAC on chip" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Already scanning for wifi networks" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA channel found" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA pacing timer found" +#: ports/espressif/common-hal/wifi/ScannedNetworks.c +msgid "Failed to allocate wifi scan memory" msgstr "" -#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c -#, c-format -msgid "No I2C device at address: 0x%x" +#: ports/espressif/common-hal/wifi/__init__.c +msgid "Failed to allocate Wifi memory" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "No IP" +#: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +msgid "Only IPv4 addresses supported" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/__init__.c -#: ports/cxd56/common-hal/microcontroller/__init__.c -#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c -msgid "No bootloader present" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/busio/SPI.c +msgid "Must provide MISO or MOSI pin" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No configuration set" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c +#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c +#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c +msgid "Hardware in use, try alternative pins" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -msgid "No connection: length cannot be determined" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" msgstr "" -#: shared-bindings/board/__init__.c -msgid "No default %q bus" +#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c +msgid "" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -msgid "No free GCLKs" +#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" -#: shared-bindings/os/__init__.c -msgid "No hardware random available" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "timeout must be < 655.35 secs" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in in program" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "non-zero timeout must be > 0.01" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in or out in program" +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: timeout" msgstr "" -#: py/objint.c shared-bindings/time/__init__.c -msgid "No long integer support" +#: ports/nordic/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "No network with that ssid" +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Nordic system firmware out of memory" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No out in program" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %04x" msgstr "" -#: ports/atmel-samd/common-hal/busio/I2C.c -#: ports/espressif/common-hal/busio/I2C.c -#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/busio/I2C.c -msgid "No pull up found on SDA or SCL; check your wiring" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown gatt error: 0x%04x" msgstr "" -#: shared-module/touchio/TouchIn.c -msgid "No pulldown on pin; 1Mohm recommended" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +msgid "" +"Unspecified issue. The pairing request on the other device may have been " +"declined or ignored." msgstr "" -#: py/moderrno.c -msgid "No space left on device" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#, c-format +msgid "Unknown security error: 0x%04x" msgstr "" -#: py/moderrno.c -msgid "No such device" +#: ports/nordic/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge, only level" msgstr "" -#: py/moderrno.c -msgid "No such file/directory" +#: ports/nordic/common-hal/audiobusio/I2SOut.c +msgid "Device in use" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "No timer available" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No usb host port initialized" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Nordic system firmware out of memory" +#: ports/nordic/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" msgstr "" -#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string" +#: ports/nordic/common-hal/busio/UART.c +msgid "Odd parity is not supported" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "Not connected" +#: ports/nordic/common-hal/countio/Counter.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +msgid "All channels in use" msgstr "" -#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c -#: shared-bindings/audiopwmio/PWMAudioOut.c -msgid "Not playing" +#: ports/nordic/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Not supported JPEG standard" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#, c-format -msgid "Number of data_pins must be %d or %d, not %d" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/util.c -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "%q cannot be changed once mode is set to %q" msgstr "" -#: ports/nordic/common-hal/busio/UART.c -msgid "Odd parity is not supported" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Off" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Ok" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -#, c-format -msgid "Only 8 or 16 bit mono with %dx oversampling supported." +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c +#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c +#: shared-module/synthio/Synthesizer.c +msgid "%q must be of type %q or %q, not %q" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -msgid "Only IPv4 addresses supported" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Program size invalid" msgstr "" -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Only IPv4 sockets supported" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Init program size invalid" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only Windows format, uncompressed BMP supported: given header size is %d" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Buffer elements must be 4 bytes long or less" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Only connectable advertisements can be directed" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched data size" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Only edge detection is available on this hardware" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Out-buffer elements must be <= 4 bytes long" msgstr "" -#: shared-bindings/ipaddress/__init__.c -msgid "Only int or string supported for ip" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "In-buffer elements must be <= 4 bytes long" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/I2C.c +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/I2C.c +#: shared-bindings/busio/SPI.c +msgid "Function requires lock" msgstr "" -#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one %q can be set in deep sleep." +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" msgstr "" -#: ports/espressif/common-hal/espulp/ULPAlarm.c -msgid "Only one %q can be set." +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c +#: ports/stm/common-hal/alarm/touch/TouchAlarm.c +msgid "Touch alarms not available" msgstr "" -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "Only one address is allowed" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" msgstr "" -#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c -#: ports/nordic/common-hal/alarm/time/TimeAlarm.c -#: ports/stm/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "Bit clock and word select must be sequential GPIO pins" msgstr "" -#: ports/espressif/common-hal/alarm/time/TimeAlarm.c -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set." +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Too many channels in sample." msgstr "" -#: shared-module/displayio/ColorConverter.c -msgid "Only one color can be transparent at a time" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Audio source error" msgstr "" -#: py/moderrno.c -msgid "Operation not permitted" +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 16, 24, or 32" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation or feature not supported" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation timed out" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Out of MDNS service slots" +#: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "I2C peripheral in use" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Out of memory" +#: ports/raspberrypi/common-hal/busio/SPI.c +msgid "SPI peripheral in use" msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Out of sockets" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Out-buffer elements must be <= 4 bytes long" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "Pin must be on PWM Channel B" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "PWM restart" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "RISE_AND_FALL not available on this chip" msgstr "" #: ports/raspberrypi/common-hal/countio/Counter.c @@ -1673,85 +1926,102 @@ msgstr "" msgid "PWM slice channel A already in use" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Parameter error" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All state machines in use" msgstr "" -#: ports/espressif/common-hal/audiobusio/__init__.c -msgid "Peripheral in use" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +msgid "timeout waiting for flux" msgstr "" -#: py/moderrno.c -msgid "Permission denied" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: shared-module/floppyio/__init__.c +msgid "timeout waiting for index pulse" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Pin cannot wake from Deep Sleep" +#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +msgid "Pins must be sequential" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Pin count too large" +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +msgid "Invalid %q and %q" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -#: ports/stm/common-hal/pulseio/PulseIn.c -msgid "Pin interrupt already in use" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Failed to add service TXT record" msgstr "" -#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -msgid "Pin is input only" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "Pin must be on PWM Channel B" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to access unaligned IO register" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"Pinout uses %d bytes per element, which consumes more than the ideal %d " -"bytes. If this cannot be avoided, pass allow_inefficient=True to the " -"constructor" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to write to read-only memory" msgstr "" -#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c -msgid "Pins must be sequential" +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +msgid "All timers for this pin are in use" msgstr "" #: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c msgid "Pins must be sequential GPIO pins" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Pins must share PWM slice" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Pin count too large" msgstr "" -#: shared-module/usb/core/Device.c -msgid "Pipe error" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing jmp_pin. %q[%u] jumps on pin" msgstr "" -#: py/builtinhelp.c -msgid "Plus any modules on the filesystem\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] uses extra pin" msgstr "" -#: shared-module/vectorio/Polygon.c -msgid "Polygon needs at least 3 points" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] waits based on pin" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Power dipped. Make sure you are providing enough power." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] waits on input outside of count" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Prefix buffer must be on the heap" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" msgstr "" -#: main.c -msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts in more bits than pin count" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts out more bits than pin count" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_set_pin. %q[%u] sets pin(s)" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] writes pin(s)" msgstr "" -#: main.c -msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] reads pin(s)" msgstr "" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -1762,2606 +2032,2635 @@ msgstr "" msgid "Program does OUT without loading OSR" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Program size invalid" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin state conflicts with initial out pin state" msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -msgid "Program too long" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin direction conflicts with initial out pin direction" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Pull not used when direction is output." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "pull masks conflict with direction masks" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "RISE_AND_FALL not available on this chip" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No out in program" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "RLE-compressed BMP not supported" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in in program" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG DeInit Error" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in or out in program" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG Init Error" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched swap flag" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d, not %d" msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "RS485 inversion specified when not in RS485 mode" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +msgid "Data pins must be consecutive" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c -msgid "RTC is not supported on this board" +#: ports/raspberrypi/common-hal/socketpool/Socket.c +msgid "Only IPv4 sockets supported" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "Random number generation error" +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All dma channels in use" msgstr "" -#: shared-bindings/_bleio/__init__.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c -#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c -msgid "Read-only" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" msgstr "" -#: extmod/vfs_fat.c py/moderrno.c -msgid "Read-only filesystem" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Received response was invalid" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "AP could not be started" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Reconnecting" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Only edge detection is available on this hardware" msgstr "" -#: shared-bindings/epaperdisplay/EPaperDisplay.c -msgid "Refresh too soon" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +#: ports/stm/common-hal/pulseio/PulseIn.c +msgid "Pin interrupt already in use" msgstr "" -#: shared-bindings/canio/RemoteTransmissionRequest.c -msgid "RemoteTransmissionRequests limited to 8 bytes" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Pin cannot wake from Deep Sleep" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Requested AES mode is unsupported" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Deep sleep pins must use a rising edge with pulldown" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Requested resource not found" +#: ports/stm/common-hal/analogio/AnalogIn.c +msgid "Invalid ADC Unit value" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "Right channel unsupported" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Device Init Error" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Right format but not supported" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Channel Init Error" msgstr "" -#: main.c -msgid "Running in safe mode! Not running saved code.\n" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "SD card CSD format not supported" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" msgstr "" -#: ports/cxd56/common-hal/sdioio/SDCard.c -msgid "SDCard init" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Another PWMAudioOut is already active" msgstr "" -#: ports/stm/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c #, c-format -msgid "SDIO GetCardInfo Error %d" +msgid "Buffer length %d too big. It must be less than %d" msgstr "" -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO Init Error %x" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Failed to buffer the sample" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c -msgid "SPI configuration failed" +#: ports/stm/common-hal/busio/I2C.c +msgid "I2C init error" msgstr "" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" msgstr "" -#: ports/raspberrypi/common-hal/busio/SPI.c -msgid "SPI peripheral in use" -msgstr "" - #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "Scale dimensions must divide by 3" +#: ports/stm/common-hal/busio/UART.c +msgid "Internal define error" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Scan already in progress. Stop with stop_scan." +#: ports/stm/common-hal/busio/UART.c +msgid "Could not start interrupt, RX busy" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -msgid "Serializer in use" +#: ports/stm/common-hal/busio/UART.c +msgid "UART write" msgstr "" -#: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname" +#: ports/stm/common-hal/busio/UART.c +msgid "UART de-init" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Size not supported" +#: ports/stm/common-hal/busio/UART.c +msgid "UART re-init" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Slice and value different lengths." +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Temperature read timed out" msgstr "" -#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/TileGrid.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Slices not supported" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Voltage read timed out" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c -#: ports/raspberrypi/common-hal/socketpool/SocketPool.c -msgid "SocketPool can only be used with wifi.radio" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG Init Error" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Source and destination buffers must be the same length" +#: ports/stm/common-hal/os/__init__.c +msgid "Random number generation error" msgstr "" -#: shared-bindings/paralleldisplaybus/ParallelBus.c -msgid "Specify exactly one of data0 or data_pins" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG DeInit Error" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Stack overflow. Increase stack size." +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "timer re-init" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Supply one of monotonic_time or epoch_time" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "channel re-init" msgstr "" -#: shared-bindings/gnss/GNSS.c -msgid "System entry must be gnss.SatelliteSystem" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "PWM restart" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Temperature read timed out" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "The `microcontroller` module was used to boot into safe mode." +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "SDIO GetCardInfo Error %d" msgstr "" -#: py/obj.c -msgid "The above exception was the direct cause of the following exception:" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid ".show(x) removed. Use .root_group = x" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Brightness not adjustable" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c py/argcheck.c +#: shared-bindings/busdisplay/BusDisplay.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "%q must be %d-%d" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Group already used" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Invalid advertising data" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" +#: ports/zephyr-cp/common-hal/audiobusio/I2SOut.c +#: ports/zephyr-cp/common-hal/busio/I2C.c +#: ports/zephyr-cp/common-hal/busio/SPI.c +#: ports/zephyr-cp/common-hal/busio/UART.c +msgid "Use device tree to define %q devices" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Third-party firmware fatal error." +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork" msgstr "" -#: shared-module/imagecapture/ParallelImageCapture.c -msgid "This microcontroller does not support continuous capture." +#: ports/zephyr-cp/common-hal/usb_hid/Device.c shared-module/usb_hid/Device.c +msgid "USB error" msgstr "" -#: shared-module/paralleldisplaybus/ParallelBus.c -msgid "" -"This microcontroller only supports data0=, not data_pins=, because it " -"requires contiguous pins." +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile height must exactly divide bitmap height" +#: ports/zephyr-cp/common-hal/zephyr_display/Display.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Below minimum frame rate" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c -msgid "Tile index out of bounds" +#: py/argcheck.c +msgid "function doesn't take keyword arguments" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile width must exactly divide bitmap width" +#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c +#: shared-bindings/time/__init__.c +#, c-format +msgid "function takes %d positional arguments but %d were given" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Time is in the past." +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c +#: py/argcheck.c #, c-format -msgid "Timeout is too long: Maximum timeout length is %d seconds" +msgid "function expected at most %d arguments, got %d" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample" +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c +msgid "unexpected keyword argument '%q'" msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample." +#: py/argcheck.c +msgid "extra keyword arguments given" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -msgid "Too many descriptors" +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c +msgid "argument num/types mismatch" msgstr "" -#: shared-module/displayio/__init__.c -msgid "Too many display busses; forgot displayio.release_displays() ?" +#: py/argcheck.c +msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" -#: shared-module/displayio/__init__.c -msgid "Too many displays" +#: py/argcheck.c +msgid "%q must be %d" msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than %q" +#: py/argcheck.c +msgid "%q must be >= %d" msgstr "" -#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c -#: ports/stm/common-hal/alarm/touch/TouchAlarm.c -msgid "Touch alarms not available" +#: py/argcheck.c shared-bindings/gifio/GifWriter.c +#: shared-module/gifio/OnDiskGif.c +msgid "%q must be <= %d" msgstr "" -#: py/obj.c -msgid "Traceback (most recent call last):\n" +#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c +#: shared-module/synthio/__init__.c +msgid "%q must be of type %q, not %q" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART de-init" +#: py/argcheck.c +msgid "%q length must be %d-%d" msgstr "" -#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c -#: ports/stm/common-hal/busio/UART.c -msgid "UART init" +#: py/argcheck.c +msgid "%q length must be >= %d" msgstr "" -#: ports/raspberrypi/common-hal/busio/UART.c -msgid "UART peripheral in use" +#: py/argcheck.c +msgid "%q length must be <= %d" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART re-init" +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART write" +#: py/argcheck.c shared-module/audiofilters/Filter.c +msgid "%q in %q must be of type %q, not %q" msgstr "" -#: main.c -msgid "UID:" +#: py/asmthumb.c +msgid "too many locals for native method" msgstr "" -#: shared-module/usb_hid/Device.c -msgid "USB busy" +#: py/asmxtensa.c +msgid "ERROR: xtensa %q out of range" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "USB devices need more endpoints than are available." +#: py/asmxtensa.c +msgid "ERROR: %q %q not word-aligned" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "USB devices specify too many interface names." +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" msgstr "" -#: shared-module/usb_hid/Device.c -msgid "USB error" +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID integer value must be 0-0xffff" +#: py/bc.c +msgid "unexpected keyword argument" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID value is not str, int or byte buffer" +#: py/bc.c +msgid "function missing required keyword argument '%q'" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to access unaligned IO register" +#: py/bc.c +msgid "function missing keyword-only argument" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Unable to allocate buffers for signed conversion" +#: py/binary.c py/objarray.c +msgid "bad typecode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Unable to allocate to the heap." +#: py/builtinevex.c +msgid "bad compile mode" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "Unable to create lock" +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" msgstr "" -#: shared-module/i2cdisplaybus/I2CDisplayBus.c -#: shared-module/is31fl3741/IS31FL3741.c -#, c-format -msgid "Unable to find I2C Display at %x" +#: py/builtinhelp.c +msgid "object " msgstr "" -#: py/parse.c -msgid "Unable to init parser" +#: py/builtinhelp.c +msgid " is of type %q\n" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "Unable to read color palette data" +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Visit circuitpython.org for more information.\n" +"\n" +"To list built-in modules type `help(\"modules\")`.\n" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Unable to start mDNS query" +#: py/builtinimport.c +msgid "script compilation not supported" msgstr "" -#: shared-bindings/nvm/ByteArray.c -msgid "Unable to write to nvm." +#: py/builtinimport.c +msgid "can't perform relative import" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to write to read-only memory" +#: py/builtinimport.c +msgid "module not found" msgstr "" -#: shared-bindings/alarm/SleepMemory.c -msgid "Unable to write to sleep_memory." +#: py/builtinimport.c +msgid "no module named '%q'" msgstr "" -#: ports/nordic/common-hal/_bleio/UUID.c -msgid "Unexpected nrfx uuid type" +#: py/builtinimport.c +msgid "relative import" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error at %s:%d: %d" +#: py/compile.c +msgid "can't assign to expression" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error: %d" +#: py/compile.c +msgid "multiple *x in assignment" msgstr "" -#: ports/espressif/common-hal/max3421e/Max3421E.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unknown error code %d" +#: py/compile.c +msgid "non-default argument follows default argument" msgstr "" -#: shared-bindings/wifi/Radio.c -#, c-format -msgid "Unknown failure %d" +#: py/compile.c +msgid "invalid micropython decorator" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown gatt error: 0x%04x" +#: py/compile.c +msgid "invalid arch" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: supervisor/shared/safe_mode.c -msgid "Unknown reason." +#: py/compile.c +msgid "can't delete expression" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown security error: 0x%04x" +#: py/compile.c +msgid "'break'/'continue' outside loop" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error at %s:%d: %d" +#: py/compile.c +msgid "'return' outside function" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %04x" +#: py/compile.c +msgid "import * not at module level" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %d" +#: py/compile.c +msgid "identifier redefined as global" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -#: shared-module/_pixelmap/PixelMap.c -#, c-format -msgid "Unmatched number of items on RHS (expected %d, got %d)." +#: py/compile.c +msgid "no binding for nonlocal found" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "" -"Unspecified issue. Can be that the pairing prompt on the other device was " -"declined or ignored." +#: py/compile.c +msgid "identifier redefined as nonlocal" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Unsupported colorspace" +#: py/compile.c +msgid "can't declare nonlocal in outer code" msgstr "" -#: shared-module/displayio/bus_core.c -msgid "Unsupported display bus type" +#: py/compile.c +msgid "default 'except' must be last" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" +#: py/compile.c +msgid "async for/with outside async function" msgstr "" -#: shared-bindings/hashlib/__init__.c -msgid "Unsupported hash algorithm" +#: py/compile.c +msgid "*x must be assignment target" msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -msgid "Unsupported socket type" +#: py/compile.c +msgid "super() can't find self" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Update failed" +#: py/compile.c +msgid "* arg after **" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length != required fixed length" +#: py/compile.c +msgid "too many args" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length > max_length" +#: py/compile.c +msgid "LHS of keyword arg must be an id" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Version was invalid" +#: py/compile.c +msgid "positional arg after **" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Voltage read timed out" +#: py/compile.c +msgid "positional arg after keyword arg" msgstr "" -#: main.c -msgid "WARNING: Your code filename has two extensions\n" +#: py/compile.c py/parse.c +msgid "invalid syntax" msgstr "" - -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" + +#: py/compile.c +msgid "expecting key:value for dict" msgstr "" -#: py/builtinhelp.c -#, c-format -msgid "" -"Welcome to Adafruit CircuitPython %s!\n" -"\n" -"Visit circuitpython.org for more information.\n" -"\n" -"To list built-in modules type `help(\"modules\")`.\n" +#: py/compile.c +msgid "expecting just a value for set" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "Wi-Fi: " +#: py/compile.c +msgid "'yield' outside function" msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" +#: py/compile.c +msgid "'yield from' inside async function" msgstr "" -#: main.c -msgid "Woken up by alarm.\n" +#: py/compile.c +msgid "'await' outside function" msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Writes not supported on Characteristic" +#: py/compile.c +msgid "unknown type '%q'" msgstr "" -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "You pressed both buttons at start up." +#: py/compile.c +msgid "annotation must be an identifier" msgstr "" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h -msgid "You pressed button A at start up." +#: py/compile.c +msgid "argument name reused" msgstr "" -#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h -msgid "You pressed button DOWN at start up." +#: py/compile.c +msgid "inline assembler must be a function" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up" +#: py/compile.c +msgid "unknown type" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h -#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h -msgid "You pressed the BOOT button at start up." +#: py/compile.c +msgid "return annotation must be an identifier" msgstr "" -#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h -msgid "You pressed the GPIO0 button at start up." +#: py/compile.c +msgid "expecting an assembler instruction" msgstr "" -#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h -msgid "You pressed the Rec button at start up." +#: py/compile.c +msgid "'label' requires 1 argument" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "You pressed the SW38 button at start up." +#: py/compile.c +msgid "label redefined" msgstr "" -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -#: ports/espressif/boards/vidi_x/mpconfigboard.h -msgid "You pressed the VOLUME button at start up." +#: py/compile.c +msgid "'align' requires 1 argument" msgstr "" -#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h -msgid "You pressed the central button at start up." +#: py/compile.c +msgid "'data' requires at least 2 arguments" msgstr "" -#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h -msgid "You pressed the left button at start up." +#: py/compile.c +msgid "'data' requires integer arguments" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the reset button during boot." +#: py/compile.c +msgid "cannot emit native code for this architecture" msgstr "" -#: supervisor/shared/micropython.c -msgid "[truncated due to length]" +#: py/emitbc.c +msgid "bytecode overflow" msgstr "" -#: py/objtype.c -msgid "__init__() should return None" +#: py/emitinlinerv32.c +msgid "can only have up to 4 parameters for RV32 assembly" msgstr "" -#: py/objtype.c -#, c-format -msgid "__init__() should return None, not '%s'" +#: py/emitinlinerv32.c +msgid "parameters must be registers in sequence a0 to a3" msgstr "" -#: py/objobject.c -msgid "__new__ arg must be a user-type" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: expecting %q" msgstr "" -#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c -msgid "a bytes-like object is required" +#: py/emitinlinerv32.c +msgid "opcode '%q': expecting %d arguments" msgstr "" -#: shared-bindings/i2ctarget/I2CTarget.c -msgid "addresses is empty" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: out of range" msgstr "" -#: py/compile.c -msgid "annotation must be an identifier" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: unknown register" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "arange: cannot compute length" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: undefined label '%q'" msgstr "" -#: py/modbuiltins.c -msgid "arg is an empty sequence" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: must not be zero" msgstr "" -#: py/objobject.c -msgid "arg must be user-type" +#: py/emitinlinerv32.c +msgid "invalid RV32 instruction '%q'" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort argument must be an ndarray" +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort is not implemented for flattened arrays" +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "argument must be None, an integer or a tuple of integers" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" msgstr "" -#: py/compile.c -msgid "argument name reused" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" msgstr "" -#: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c -msgid "argument num/types mismatch" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c -msgid "arguments must be ndarrays" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array and index length must be equal" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "array has too many dimensions" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array is too big" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" msgstr "" -#: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c -msgid "array/bytes required on right side" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" msgstr "" -#: py/asmxtensa.c -msgid "asm overflow" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" msgstr "" -#: py/compile.c -msgid "async for/with outside async function" +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get (arg)min/(arg)max of empty sequence" +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get argmin/argmax of an empty sequence" +#: py/emitinlinethumb.c +msgid "branch not in range" msgstr "" -#: py/objstr.c -msgid "attributes not supported" +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "axis is out of bounds" +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -msgid "axis must be None, or an integer" +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d isn't within range %d..%d" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "axis too long" +#: py/emitinlinextensa.c +#, c-format +msgid "%d is not a multiple of %d" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "background value out of range of target" +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" msgstr "" -#: py/builtinevex.c -msgid "bad compile mode" +#: py/emitnative.c +msgid "conversion to object" msgstr "" -#: py/objstr.c -msgid "bad conversion specifier" +#: py/emitnative.c +msgid "local '%q' used before type known" msgstr "" -#: py/objstr.c -msgid "bad format string" +#: py/emitnative.c +msgid "can't load from '%q'" msgstr "" -#: py/binary.c py/objarray.c -msgid "bad typecode" +#: py/emitnative.c +msgid "can't load with '%q' index" msgstr "" #: py/emitnative.c -msgid "binary op %q not implemented" +msgid "local '%q' has type '%q' but source is '%q'" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "bitmap size and depth must match" +#: py/emitnative.c +msgid "can't store '%q'" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "bitmap sizes must match" +#: py/emitnative.c +msgid "can't store to '%q'" msgstr "" -#: extmod/modrandom.c -msgid "bits must be 32 or less" +#: py/emitnative.c +msgid "can't store with '%q' index" msgstr "" -#: shared-bindings/audiomixer/Mixer.c -msgid "bits_per_sample must be 8 or 16" +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" msgstr "" -#: py/emitinlinethumb.c -msgid "branch not in range" +#: py/emitnative.c +msgid "'not' not implemented" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer is smaller than requested size" +#: py/emitnative.c +msgid "can't do unary op of '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer size must be a multiple of element size" +#: py/emitnative.c +msgid "div/mod not implemented for uint" msgstr "" -#: shared-module/struct/__init__.c -msgid "buffer size must match format" +#: py/emitnative.c +msgid "comparison of int and uint" msgstr "" -#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c -msgid "buffer slices must be of equal length" +#: py/emitnative.c +msgid "binary op %q not implemented" msgstr "" -#: py/modstruct.c shared-module/struct/__init__.c -msgid "buffer too small" +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "buffer too small for requested bytes" +#: py/emitnative.c +msgid "casting" msgstr "" -#: py/emitbc.c -msgid "bytecode overflow" +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" msgstr "" -#: py/objarray.c -msgid "bytes length not a multiple of item size" +#: py/emitnative.c +msgid "must raise an object" msgstr "" -#: py/objstr.c -msgid "bytes value out of range" +#: py/emitnative.c +msgid "native yield" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is out of range" +#: py/lexer.c +msgid "unicode name escapes" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is read only" +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" msgstr "" -#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c -#: shared-module/vectorio/Rectangle.c -msgid "can only have one parent" +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" msgstr "" -#: py/emitinlinethumb.c -msgid "can only have up to 4 parameters to Thumb assembly" +#: py/modbuiltins.c +msgid "arg is an empty sequence" msgstr "" -#: py/emitinlinextensa.c -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/modbuiltins.c +msgid "ord expects a character" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "can only specify one unknown dimension" +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" msgstr "" -#: py/objtype.c -msgid "can't add special method to already-subclassed class" +#: py/modbuiltins.c +msgid "3-arg pow() not supported" msgstr "" -#: py/compile.c -msgid "can't assign to expression" +#: py/modbuiltins.c +msgid "must use keyword argument for key function" msgstr "" -#: extmod/modasyncio.c -msgid "can't cancel self" +#: py/moderrno.c +msgid "Operation not permitted" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c -msgid "can't convert %q to %q" +#: py/moderrno.c +msgid "No such file/directory" msgstr "" -#: py/obj.c -#, c-format -msgid "can't convert %s to complex" +#: py/moderrno.c +msgid "Input/output error" msgstr "" -#: py/obj.c -#, c-format -msgid "can't convert %s to float" +#: py/moderrno.c +msgid "Permission denied" msgstr "" -#: py/objint.c py/runtime.c -#, c-format -msgid "can't convert %s to int" +#: py/moderrno.c +msgid "File exists" msgstr "" -#: py/objstr.c -msgid "can't convert '%q' object to %q implicitly" +#: py/moderrno.c +msgid "No such device" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "can't convert complex to float" +#: py/moderrno.c +msgid "No space left on device" msgstr "" -#: py/obj.c -msgid "can't convert to complex" +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" msgstr "" -#: py/obj.c -msgid "can't convert to float" +#: py/modmath.c +msgid "negative factorial" msgstr "" -#: py/runtime.c -msgid "can't convert to int" +#: py/modmicropython.c +msgid "schedule queue full" msgstr "" -#: py/objstr.c -msgid "can't convert to str implicitly" +#: py/modstruct.c shared-module/struct/__init__.c +msgid "buffer too small" msgstr "" -#: py/compile.c -msgid "can't declare nonlocal in outer code" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" msgstr "" -#: py/compile.c -msgid "can't delete expression" +#: py/modthread.c +msgid "expecting a dict for keyword args" msgstr "" -#: py/emitnative.c -msgid "can't do binary op between '%q' and '%q'" +#: py/nativeglue.c +msgid "set unsupported" msgstr "" -#: py/emitnative.c -msgid "can't do unary op of '%q'" +#: py/nativeglue.c +msgid "slice unsupported" msgstr "" -#: py/emitnative.c -msgid "can't implicitly convert '%q' to 'bool'" +#: py/nativeglue.c +msgid "float unsupported" msgstr "" -#: py/runtime.c -msgid "can't import name %q" +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c +msgid "can't convert %q to %q" msgstr "" -#: py/emitnative.c -msgid "can't load from '%q'" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" msgstr "" -#: py/emitnative.c -msgid "can't load with '%q' index" +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: py/builtinimport.c -msgid "can't perform relative import" +#: py/obj.c +msgid " File \"%q\", line %d" msgstr "" -#: py/objgenerator.c -msgid "can't send non-None value to a just-started generator" +#: py/obj.c +msgid " File \"%q\"" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "can't set 512 block size" +#: py/obj.c +msgid ", in %q\n" msgstr "" -#: py/objexcept.c py/objnamedtuple.c -msgid "can't set attribute" +#: py/obj.c +msgid "Traceback (most recent call last):\n" msgstr "" -#: py/runtime.c -msgid "can't set attribute '%q'" +#: py/obj.c +msgid "can't convert to float" msgstr "" -#: py/emitnative.c -msgid "can't store '%q'" +#: py/obj.c +#, c-format +msgid "can't convert %s to float" msgstr "" -#: py/emitnative.c -msgid "can't store to '%q'" +#: py/obj.c +msgid "can't convert to complex" msgstr "" -#: py/emitnative.c -msgid "can't store with '%q' index" +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from automatic field numbering to manual field specification" +#: py/obj.c +msgid "expected tuple/list" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from manual field specification to automatic field numbering" +#: py/obj.c +#, c-format +msgid "object '%s' isn't a tuple or list" msgstr "" -#: py/objcomplex.c -msgid "can't truncate-divide a complex number" +#: py/obj.c +msgid "tuple/list has wrong length" msgstr "" -#: extmod/modasyncio.c -msgid "can't wait" +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot assign new shape" +#: py/obj.c +msgid "indices must be integers" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "cannot cast output with casting rule" +#: py/obj.c +msgid "%q indices must be integers, not %s" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex to dtype" +#: py/obj.c +msgid "object has no len" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex type" +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" msgstr "" -#: py/objtype.c -msgid "cannot create '%q' instances" +#: py/obj.c +msgid "object doesn't support item deletion" msgstr "" -#: py/objtype.c -msgid "cannot create instance" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item deletion" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot delete array elements" +#: py/obj.c +msgid "object isn't subscriptable" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot reshape array" +#: py/obj.c +#, c-format +msgid "'%s' object isn't subscriptable" msgstr "" -#: py/emitnative.c -msgid "casting" +#: py/obj.c +msgid "object doesn't support item assignment" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "channel re-init" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item assignment" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "chars buffer too small" +#: py/obj.c +msgid "object with buffer protocol required" msgstr "" -#: py/modbuiltins.c -msgid "chr() arg not in range(0x110000)" +#: py/objarray.c +msgid "bytes length not a multiple of item size" msgstr "" -#: py/modbuiltins.c -msgid "chr() arg not in range(256)" +#: py/objarray.c py/objstr.c +msgid "string argument without an encoding" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "clip point must be (x,y) tuple" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" msgstr "" -#: shared-bindings/msgpack/ExtType.c -msgid "code outside range 0~127" +#: py/objarray.c py/objstr.c +msgid "substring not found" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a buffer, tuple, list, or int" +#: py/objarray.c +msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color must be between 0x000000 and 0xffffff" +#: py/objarray.c +msgid "memoryview offset too large" msgstr "" -#: py/emitnative.c -msgid "comparison of int and uint" +#: py/objcomplex.c +msgid "can't truncate-divide a complex number" msgstr "" #: py/objcomplex.c msgid "complex divide by zero" msgstr "" -#: py/objfloat.c py/parsenum.c -msgid "complex values not supported" +#: py/objcomplex.c +msgid "0.0 to a complex power" msgstr "" -#: extmod/modzlib.c -msgid "compression header" +#: py/objdeque.c +msgid "full" msgstr "" -#: py/emitnative.c -msgid "conversion to object" +#: py/objdeque.c +msgid "empty" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be linear arrays" +#: py/objdict.c +msgid "dict update sequence has wrong length" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be ndarrays" +#: py/objexcept.c py/objnamedtuple.c +msgid "can't set attribute" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must not be empty" +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "corrupted file" +#: py/objgenerator.c +msgid "generator already executing" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "could not invert Vandermonde matrix" +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "couldn't determine SD card version" +#: py/objgenerator.c py/runtime.c +msgid "generator raised StopIteration" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "cross is defined for 1D arrays of length 3" +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be iterable" +#: py/objint.c py/runtime.c +#, c-format +msgid "can't convert %s to int" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be of equal length" +#: py/objint.c +msgid "float too big" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: py/objint.c #, c-format -msgid "data pin #%d in use" +msgid "value must fit in %d byte(s)" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "data type not understood" +#: py/objint.c shared-bindings/time/__init__.c +msgid "No long integer support" msgstr "" -#: py/parsenum.c -msgid "decimal numbers not supported" +#: py/objint.c py/sequence.c +msgid "small int overflow" msgstr "" -#: py/compile.c -msgid "default 'except' must be last" +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c +msgid "%q=%q" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "default is not a function" +#: py/objint_longlong.c py/parsenum.c +msgid "result overflows long long storage" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative shift count" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" msgstr "" -#: py/objdict.c -msgid "dict update sequence has wrong length" +#: py/objint_longlong.c py/objint_mpz.c +msgid "overflow converting long int to machine word" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "diff argument must be an ndarray" +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "differentiation order out of range" +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "dimensions do not match" +#: py/objobject.c +msgid "__new__ arg must be a user-type" msgstr "" -#: py/emitnative.c -msgid "div/mod not implemented for uint" +#: py/objobject.c +msgid "arg must be user-type" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "divide by zero" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" -#: py/runtime.c -msgid "division by zero" +#: py/objslice.c +msgid "Cannot subclass slice" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "dtype must be float, or complex" +#: py/objstr.c +msgid "bytes value out of range" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "dtype of int32 is not supported" +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" msgstr "" -#: py/objdeque.c -msgid "empty" +#: py/objstr.c +msgid "empty separator" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "empty file" +#: py/objstr.c +msgid "rsplit(None,n)" msgstr "" -#: extmod/modasyncio.c extmod/modheapq.c -msgid "empty heap" +#: py/objstr.c +msgid "bad format string" msgstr "" #: py/objstr.c -msgid "empty separator" +#, c-format +msgid "unmatched '%c' in format" msgstr "" -#: shared-bindings/random/__init__.c -msgid "empty sequence" +#: py/objstr.c +msgid "bad conversion specifier" msgstr "" #: py/objstr.c msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "epoch_time not supported on this board" -msgstr "" - -#: ports/nordic/common-hal/busio/UART.c +#: py/objstr.c #, c-format -msgid "error = 0x%08lX" +msgid "unknown conversion specifier %c" msgstr "" -#: py/runtime.c -msgid "exceptions must derive from BaseException" +#: py/objstr.c +msgid "expected ':' after format specifier" msgstr "" #: py/objstr.c -msgid "expected ':' after format specifier" +msgid "" +"can't switch from automatic field numbering to manual field specification" msgstr "" -#: py/obj.c -msgid "expected tuple/list" +#: py/objstr.c +msgid "%q index out of range" msgstr "" -#: py/modthread.c -msgid "expecting a dict for keyword args" +#: py/objstr.c +msgid "attributes not supported" msgstr "" -#: py/compile.c -msgid "expecting an assembler instruction" +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" msgstr "" -#: py/compile.c -msgid "expecting just a value for set" +#: py/objstr.c +msgid "invalid format specifier" msgstr "" -#: py/compile.c -msgid "expecting key:value for dict" +#: py/objstr.c +msgid "sign not allowed in string format specifier" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "ext_hook is not a function" +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/argcheck.c -msgid "extra keyword arguments given" +#: py/objstr.c +msgid "unknown format code '%c' for object of type '%q'" msgstr "" -#: py/argcheck.c -msgid "extra positional arguments given" +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" msgstr "" -#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c -#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c -msgid "file must be a file opened in byte mode" +#: py/objstr.c +msgid "format needs a dict" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "file write is not available" +#: py/objstr.c +msgid "incomplete format key" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" +#: py/objstr.c +msgid "incomplete format" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "first argument must be a callable" +#: py/objstr.c +msgid "format string needs more arguments" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "first argument must be a function" +#: py/objstr.c +#, c-format +msgid "%%c needs int or char" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "first argument must be a tuple of ndarrays" +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" msgstr "" -#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c -msgid "first argument must be an ndarray" +#: py/objstr.c +msgid "format string didn't convert all arguments" msgstr "" -#: py/objtype.c -msgid "first argument to super() must be type" +#: py/objstr.c +msgid "non-hex digit" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "first two arguments must be ndarrays" +#: py/objstr.c +msgid "can't convert to str implicitly" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "flattening order must be either 'C', or 'F'" +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "flip argument must be an ndarray" +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" msgstr "" -#: py/objint.c -msgid "float too big" +#: py/objstrunicode.c +msgid "string index out of range" msgstr "" -#: py/nativeglue.c -msgid "float unsupported" +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." msgstr "" -#: shared-bindings/_stage/Text.c -msgid "font must be 2048 bytes long" +#: py/objtype.c +msgid "__init__() should return None" msgstr "" -#: extmod/moddeflate.c -msgid "format" +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" msgstr "" -#: py/objstr.c -msgid "format requires a dict" +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" msgstr "" -#: py/objdeque.c -msgid "full" +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "" + +#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c +msgid "'%q' object isn't callable" msgstr "" -#: py/argcheck.c -msgid "function doesn't take keyword arguments" +#: py/objtype.c +msgid "type takes 1 or 3 arguments" msgstr "" -#: py/argcheck.c -#, c-format -msgid "function expected at most %d arguments, got %d" +#: py/objtype.c +msgid "can't create instance" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "function got multiple values for argument '%q'" +#: py/objtype.c +msgid "can't create '%q' instances" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "function has the same sign at the ends of interval" +#: py/objtype.c +msgid "can't add special method to already-subclassed class" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "function is defined for ndarrays only" +#: py/objtype.c +msgid "type isn't an acceptable base type" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "function is implemented for ndarrays only" +#: py/objtype.c +msgid "type '%q' isn't an acceptable base type" msgstr "" -#: py/argcheck.c -#, c-format -msgid "function missing %d required positional arguments" +#: py/objtype.c +msgid "multiple inheritance not supported" msgstr "" -#: py/bc.c -msgid "function missing keyword-only argument" +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/bc.c -msgid "function missing required keyword argument '%q'" +#: py/objtype.c +msgid "first argument to super() must be type" msgstr "" -#: py/bc.c -#, c-format -msgid "function missing required positional argument #%d" +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c -#: shared-bindings/time/__init__.c -#, c-format -msgid "function takes %d positional arguments but %d were given" +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" msgstr "" -#: py/objgenerator.c -msgid "generator already executing" +#: py/parse.c +msgid "not a constant" msgstr "" -#: py/objgenerator.c -msgid "generator ignored GeneratorExit" +#: py/parse.c +msgid "Unable to init parser" msgstr "" -#: py/objgenerator.c py/runtime.c -msgid "generator raised StopIteration" +#: py/parse.c +msgid "unexpected indent" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "graphic must be 2048 bytes long" +#: py/parse.c +msgid "unindent doesn't match any outer indent level" msgstr "" -#: extmod/modhashlib.c -msgid "hash is final" +#: py/parse.c +msgid "malformed f-string" msgstr "" -#: extmod/modheapq.c -msgid "heap must be a list" +#: py/parsenum.c +msgid "invalid syntax for integer" msgstr "" -#: py/compile.c -msgid "identifier redefined as global" +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" msgstr "" -#: py/compile.c -msgid "identifier redefined as nonlocal" +#: py/parsenum.c +msgid "invalid syntax for number" msgstr "" -#: py/compile.c -msgid "import * not at module level" +#: py/parsenum.c +msgid "decimal numbers not supported" msgstr "" #: py/persistentcode.c -msgid "incompatible .mpy arch" +msgid "incompatible .mpy file" msgstr "" #: py/persistentcode.c -msgid "incompatible .mpy file" +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" msgstr "" -#: py/objstr.c -msgid "incomplete format" +#: py/persistentcode.c +msgid "native code in .mpy unsupported" msgstr "" -#: py/objstr.c -msgid "incomplete format key" +#: py/persistentcode.c +msgid "incompatible .mpy arch" msgstr "" -#: extmod/modbinascii.c -msgid "incorrect padding" +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "'%q' object does not support '%q'" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c -msgid "index is out of bounds" +#: py/qstr.c +msgid "name too long" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "index must be tuple or int" +#: py/runtime.c +msgid "name not defined" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: py/runtime.c +msgid "name '%q' isn't defined" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: py/runtime.c +msgid "unsupported type for operator" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "indices must be integers, slices, or Boolean lists" +#: py/runtime.c +msgid "unsupported type for %q: '%s'" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" +#: py/runtime.c +msgid "unsupported types for %q: '%q', '%q'" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "initial values must be iterable" +#: py/runtime.c +msgid "wrong number of values to unpack" msgstr "" -#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c -msgid "initial_value length is wrong" +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" msgstr "" -#: py/compile.c -msgid "inline assembler must be a function" +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output dimensions differ" +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output shapes differ" +#: py/runtime.c +msgid "module '%q' has no attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input argument must be an integer, a tuple, or a list" +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "input array length must be power of 2" +#: py/runtime.c +msgid "can't set attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input arrays are not compatible" +#: py/runtime.c +msgid "object not iterable" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input data must be an iterable" +#: py/runtime.c +msgid "'%q' object isn't iterable" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input dtype must be float or complex" +#: py/runtime.c +msgid "object not an iterator" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input is not iterable" +#: py/runtime.c +msgid "'%q' object isn't an iterator" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "input matrix is asymmetric" +#: py/runtime.c +msgid "exceptions must derive from BaseException" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "input matrix is singular" +#: py/runtime.c +msgid "can't import name %q" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input must be 1- or 2-d" +#: py/runtime.c +msgid "memory allocation failed, heap is locked" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be a 1D ndarray" +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c -msgid "input must be a dense ndarray" +#: py/runtime.c +msgid "can't convert to int" msgstr "" -#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c -msgid "input must be an ndarray" +#: py/runtime.c +msgid "division by zero" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be an ndarray, or a scalar" +#: py/runtime.c +msgid "maximum recursion depth exceeded" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "input must be one-dimensional" +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "input must be square matrix" +#: py/stream.c shared-bindings/getpass/__init__.c +msgid "stream operation not supported" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "input must be tuple, list, range, or ndarray" +#: py/vm.c +msgid "local variable referenced before assignment" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input vectors must be of equal length" +#: py/vm.c +msgid "no active exception to reraise" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "interp is defined for 1D iterables of equal length" +#: py/vm.c +msgid "opcode" msgstr "" #: shared-bindings/_bleio/Adapter.c -#, c-format -msgid "interval must be in range %s-%s" +msgid "Cannot create a new Adapter; use _bleio.adapter;" msgstr "" -#: py/compile.c -msgid "invalid arch" +#: shared-bindings/_bleio/Adapter.c +msgid "Could not set address" msgstr "" -#: shared-bindings/bitmaptools/__init__.c +#: shared-bindings/_bleio/Adapter.c #, c-format -msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +msgid "interval must be in range %s-%s" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid cert" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot have scan responses for extended, connectable advertisements." msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element size %d for bits_per_pixel %d\n" +#: shared-bindings/_bleio/Adapter.c +msgid "Only connectable advertisements can be directed" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element_size %d, must be, 1, 2, or 4" +#: shared-bindings/_bleio/Adapter.c +msgid "non-zero timeout must be >= interval" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "invalid exception" +#: shared-bindings/_bleio/Adapter.c +msgid "window must be <= interval" msgstr "" -#: py/objstr.c -msgid "invalid format specifier" +#: shared-bindings/_bleio/Adapter.c +msgid "Prefix buffer must be on the heap" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "invalid hostname" +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid key" +#: shared-bindings/_bleio/Connection.c +msgid "" +"Connection has been disconnected and can no longer be used. Create a new " +"connection." +msgstr "" + +#: shared-bindings/_bleio/PacketBuffer.c +#, c-format +msgid "Buffer too short by %d bytes" msgstr "" -#: py/compile.c -msgid "invalid micropython decorator" +#: shared-bindings/_bleio/PacketBuffer.c +msgid "No connection: length cannot be determined" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c -msgid "invalid setting" +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: shared-bindings/random/__init__.c -msgid "invalid step" +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: py/compile.c py/parse.c -msgid "invalid syntax" +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" msgstr "" -#: py/parsenum.c -msgid "invalid syntax for integer" +#: shared-bindings/_bleio/__init__.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c +#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c +msgid "Read-only" msgstr "" -#: py/parsenum.c -#, c-format -msgid "invalid syntax for integer with base %d" +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" msgstr "" -#: py/parsenum.c -msgid "invalid syntax for number" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 1 must be a class" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 2 must be a class or a tuple of classes" +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "iterations did not converge" +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" msgstr "" -#: py/objstr.c -msgid "join expects a list of str/bytes objects consistent with self object" +#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +msgid "Pin is input only" msgstr "" -#: py/argcheck.c -msgid "keyword argument(s) not implemented - use normal args instead" +#: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -msgid "label '%q' not defined" +#: shared-bindings/aesio/aes.c +msgid "Key must be 16, 24, or 32 bytes long" msgstr "" -#: py/compile.c -msgid "label redefined" +#: shared-bindings/aesio/aes.c +msgid "Requested AES mode is unsupported" msgstr "" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" +#: shared-bindings/aesio/aes.c +msgid "Source and destination buffers must be the same length" msgstr "" -#: py/objarray.c -msgid "lhs and rhs should be compatible" +#: shared-bindings/aesio/aes.c +msgid "ECB only operates on 16 bytes at a time" msgstr "" -#: py/emitnative.c -msgid "local '%q' has type '%q' but source is '%q'" +#: shared-bindings/aesio/aes.c +msgid "CBC blocks must be multiples of 16 bytes" msgstr "" -#: py/emitnative.c -msgid "local '%q' used before type known" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." msgstr "" -#: py/vm.c -msgid "local variable referenced before assignment" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "loopback + silent mode not supported by peripheral" +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS already initialized" +#: shared-bindings/alarm/__init__.c +msgid "Expected a kind of %q" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS only works with built-in WiFi" +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" msgstr "" -#: py/parse.c -msgid "malformed f-string" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "map buffer too small" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" msgstr "" -#: py/modmath.c shared-bindings/math/__init__.c -msgid "math domain error" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "matrix is not positive definite" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: ports/espressif/common-hal/_bleio/Descriptor.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -#, c-format -msgid "max_length must be 0-%d when fixed_length is %s" +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c shared-bindings/mcp4822/MCP4822.c +#: shared-bindings/usb_audio/USBMicrophone.c +msgid "Not playing" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c -msgid "maximum number of dimensions is " +#: shared-bindings/audiobusio/PDMIn.c +msgid "%q must be multiple of 8." msgstr "" -#: py/runtime.c -msgid "maximum recursion depth exceeded" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Cannot record to a file" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter must be > 0" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Destination capacity is smaller than destination_length." msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter should be > 0" +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "median argument must be an ndarray" +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: py/runtime.c -#, c-format -msgid "memory allocation failed, allocating %u bytes" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/runtime.c -msgid "memory allocation failed, heap is locked" +#: shared-bindings/audiocore/RawSample.c +msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" -#: py/objarray.c -msgid "memoryview offset too large" +#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c +msgid "file must be a file opened in byte mode" msgstr "" -#: py/objarray.c -msgid "memoryview: length is not a multiple of itemsize" +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/Flanger.c +#: shared-bindings/audiodelays/GranularPitchShift.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c +#: shared-bindings/audiomixer/Mixer.c +msgid "bits_per_sample must be 8 or 16" msgstr "" -#: extmod/modtime.c -msgid "mktime needs a tuple of length 8 or 9" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "mode must be complete, or reduced" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" msgstr "" -#: py/builtinimport.c -msgid "module not found" +#: shared-bindings/audioi2sin/I2SIn.c +#, c-format +msgid "invalid destination buffer, must be an array of type: %c" msgstr "" -#: ports/espressif/common-hal/wifi/Monitor.c -msgid "monitor init failed" +#: shared-bindings/audioio/AudioOut.c +msgid "%q and %q must be different" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "more degrees of freedom than data points" +#: shared-bindings/bitmapfilter/__init__.c +msgid "" +"weights must be a sequence with an odd square number of elements (usually 9 " +"or 25)" msgstr "" -#: py/compile.c -msgid "multiple *x in assignment" +#: shared-bindings/bitmapfilter/__init__.c +msgid "weights must be an object of type %q, %q, %q, or %q, not %q " msgstr "" -#: py/objtype.c -msgid "multiple bases have instance lay-out conflict" +#: shared-bindings/bitmaptools/__init__.c +msgid "clip point must be (x,y) tuple" msgstr "" -#: py/objtype.c -msgid "multiple inheritance not supported" +#: shared-bindings/bitmaptools/__init__.c +msgid "source palette too large" msgstr "" -#: py/emitnative.c -msgid "must raise an object" +#: shared-bindings/bitmaptools/__init__.c +msgid "Bitmap size and bits per value must match" msgstr "" -#: py/modbuiltins.c -msgid "must use keyword argument for key function" +#: shared-bindings/bitmaptools/__init__.c +msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" -#: py/runtime.c -msgid "name '%q' is not defined" +#: shared-bindings/bitmaptools/__init__.c +msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -#: py/runtime.c -msgid "name not defined" +#: shared-bindings/bitmaptools/__init__.c +msgid "Unsupported colorspace" msgstr "" -#: py/qstr.c -msgid "name too long" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap size must match the other bitmaps" msgstr "" -#: py/persistentcode.c -msgid "native code in .mpy unsupported" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap must have 8 bits per pixel" msgstr "" -#: py/asmthumb.c -msgid "native method too big" +#: shared-bindings/bitmaptools/__init__.c +msgid "out of range of target" msgstr "" -#: py/emitnative.c -msgid "native yield" +#: shared-bindings/bitmaptools/__init__.c +msgid "value out of range of target" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "ndarray length overflows" +#: shared-bindings/bitmaptools/__init__.c +msgid "background value out of range of target" msgstr "" -#: py/runtime.c -#, c-format -msgid "need more than %d values to unpack" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" msgstr "" -#: py/modmath.c -msgid "negative factorial" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" msgstr "" -#: py/objint_longlong.c py/objint_mpz.c py/runtime.c -msgid "negative power with no float support" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" -#: py/objint_mpz.c py/runtime.c -msgid "negative shift count" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element size %d for bits_per_pixel %d\n" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "nested index must be int" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no SD card" +#: shared-bindings/bitmaptools/__init__.c +msgid "bitmap sizes must match" msgstr "" -#: py/vm.c -msgid "no active exception to reraise" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 2 or 65536" msgstr "" -#: py/compile.c -msgid "no binding for nonlocal found" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 65536" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "no default packer" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 8" msgstr "" -#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c -msgid "no default seed" +#: shared-bindings/bitmaptools/__init__.c +msgid "unsupported colorspace for dither" msgstr "" -#: py/builtinimport.c -msgid "no module named '%q'" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no response from SD card" +#: shared-bindings/board/__init__.c +msgid "No default %q bus" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c -msgid "no such attribute" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c +msgid "Display rotation must be in 90 degree increments" msgstr "" -#: ports/espressif/common-hal/_bleio/Connection.c -#: ports/nordic/common-hal/_bleio/Connection.c -msgid "non-UUID found in service_uuids_whitelist" +#: shared-bindings/busdisplay/BusDisplay.c +msgid "%q must be 1 when %q is True" msgstr "" -#: py/compile.c -msgid "non-default argument follows default argument" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Display must have a 16 bit colorspace." msgstr "" -#: py/objstr.c -msgid "non-hex digit found" +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c +msgid "tx and rx cannot both be None" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "non-zero timeout must be > 0.01" +#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "non-zero timeout must be >= interval" +#: shared-bindings/canio/RemoteTransmissionRequest.c +msgid "RemoteTransmissionRequests limited to 8 bytes" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "not a 128-bit UUID" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Cannot set value when direction is input." msgstr "" -#: py/parse.c -msgid "not a constant" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Drive mode not used when direction is input." msgstr "" -#: py/objstr.c -msgid "not all arguments converted during string formatting" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Pull not used when direction is output." msgstr "" -#: py/objstr.c -msgid "not enough arguments for format string" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" msgstr "" -#: extmod/ulab/code/numpy/carray/carray_tools.c -msgid "not implemented for complex dtype" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" msgstr "" -#: extmod/ulab/code/numpy/bitwise.c -msgid "not supported for input types" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "number of points must be at least 2" +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" msgstr "" -#: py/builtinhelp.c -msgid "object " +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +msgid "Slices not supported" msgstr "" -#: py/obj.c -#, c-format -msgid "object '%s' isn't a tuple or list" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: py/obj.c -msgid "object doesn't support item assignment" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: py/obj.c -msgid "object doesn't support item deletion" +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: py/obj.c -msgid "object has no len" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer, tuple, list, or int" msgstr "" -#: py/obj.c -msgid "object isn't subscriptable" +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c +msgid "unsupported %q type" msgstr "" -#: py/runtime.c -msgid "object not an iterator" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" msgstr "" -#: py/objtype.c py/runtime.c -msgid "object not callable" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" msgstr "" -#: py/sequence.c shared-bindings/displayio/Group.c -msgid "object not in sequence" +#: shared-bindings/displayio/TileGrid.c +msgid "New bitmap must be same size as old bitmap" msgstr "" -#: py/runtime.c -msgid "object not iterable" +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" msgstr "" -#: py/obj.c -#, c-format -msgid "object of type '%s' has no len()" +#: shared-bindings/dualbank/__init__.c +msgid "offset must be >= 0" msgstr "" -#: py/obj.c -msgid "object with buffer protocol required" +#: shared-bindings/epaperdisplay/EPaperDisplay.c +msgid "Refresh too soon" msgstr "" -#: py/objstr.c -msgid "odd-length string" +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Buffer is not a bytearray." msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "off" +#: shared-bindings/gnss/GNSS.c +msgid "System entry must be gnss.SatelliteSystem" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "offset is too large" +#: shared-bindings/hashlib/__init__.c +msgid "Unsupported hash algorithm" msgstr "" -#: shared-bindings/dualbank/__init__.c -msgid "offset must be >= 0" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "offset must be non-negative and no greater than buffer length" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only bit_depth=16 is supported" +#: shared-bindings/i2ctarget/I2CTarget.c +msgid "addresses is empty" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only mono is supported" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "only ndarrays can be concatenated" +#: shared-bindings/ipaddress/IPv4Address.c +#, c-format +msgid "Address must be %d bytes long" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only oversample=64 is supported" +#: shared-bindings/ipaddress/__init__.c +msgid "Only int or string supported for ip" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only sample_rate=16000 is supported" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "width must be greater than zero" msgstr "" -#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "only slices with step=1 (aka None) are supported" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "Scale dimensions must divide by 3" msgstr "" -#: py/vm.c -msgid "opcode" +#: shared-bindings/is31fl3741/IS31FL3741.c +msgid "Mapping must be a tuple" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c -msgid "operands could not be broadcast together" +#: shared-bindings/jpegio/JpegDecoder.c +msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for 2D arrays only" +#: shared-bindings/mdns/Server.c +msgid "" +"Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for ndarrays only" +#: shared-bindings/memorymap/AddressRange.c +msgid "Address range wraps around" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is implemented for 1D Boolean arrays only" +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "operation is not implemented on ndarrays" +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is not supported for given type" +#: shared-bindings/msgpack/ExtType.c +msgid "code outside range 0~127" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "operation not supported for the input types" +#: shared-bindings/msgpack/__init__.c +msgid "default is not a function" msgstr "" -#: py/modbuiltins.c -msgid "ord expects a character" +#: shared-bindings/msgpack/__init__.c +msgid "ext_hook is not a function" msgstr "" -#: py/modbuiltins.c -#, c-format -msgid "ord() expected a character, but string of length %d found" +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out array is too small" +#: shared-bindings/os/__init__.c +msgid "No hardware random available" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "out has wrong type" +#: shared-bindings/paralleldisplaybus/ParallelBus.c +msgid "Specify exactly one of data0 or data_pins" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for complex dtype" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for function" +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out must be a float dense array" +#: shared-bindings/pwmio/PWMOut.c +msgid "Conflicting settings for shared resource" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be an ndarray" +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be of float dtype" +#: shared-bindings/random/__init__.c +msgid "invalid step" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "out of range of target" +#: shared-bindings/random/__init__.c +msgid "empty sequence" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array has wrong type" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array must be contiguous" +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: py/objint_mpz.c -msgid "overflow converting long int to machine word" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" msgstr "" -#: py/modstruct.c +#: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format -msgid "pack expected %d items for packing (got %d)" +msgid "rgb_pins[%d] duplicates another pin assignment" msgstr "" -#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c -msgid "palette must be 32 bytes long" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" msgstr "" -#: py/emitinlinextensa.c -msgid "parameters must be registers in sequence a2 to a5" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" -#: py/emitinlinethumb.c -msgid "parameters must be registers in sequence r0 to r3" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" -#: extmod/vfs_posix_file.c -msgid "poll on file not available on win32" +#: shared-bindings/socketpool/Socket.c +msgid "port must be >= 0" msgstr "" -#: ports/espressif/common-hal/pulseio/PulseIn.c -msgid "pop from an empty PulseIn" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "buffer too small for requested bytes" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/pulseio/PulseIn.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c -#: shared-bindings/ps2io/Ps2.c -msgid "pop from empty %q" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" msgstr "" -#: shared-bindings/socketpool/Socket.c -msgid "port must be >= 0" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." msgstr "" -#: py/compile.c -msgid "positional arg after **" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" msgstr "" -#: py/compile.c -msgid "positional arg after keyword arg" +#: shared-bindings/storage/__init__.c shared-bindings/usb_audio/__init__.c +#: shared-bindings/usb_cdc/__init__.c shared-bindings/usb_hid/__init__.c +#: shared-bindings/usb_midi/__init__.c shared-bindings/usb_video/__init__.c +msgid "Cannot change USB devices now" msgstr "" -#: py/objint_mpz.c -msgid "pow() 3rd argument cannot be 0" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c +msgid "File not found" msgstr "" -#: py/objint_mpz.c -msgid "pow() with 3 arguments requires integers" +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "pull masks conflict with direction masks" +#: shared-bindings/traceback/__init__.c +msgid "Supply both or neither of %q and %q" msgstr "" -#: py/parse.c -msgid "raw f-strings are not supported" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "real and imaginary parts must be of equal length" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" msgstr "" -#: py/builtinimport.c -msgid "relative import" +#: shared-bindings/usb_audio/USBSpeaker.c +msgid "destination must be an array of type 'h'" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" +#: shared-bindings/usb_audio/__init__.c +msgid "At least one of microphone and speaker must be enabled" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "results cannot be cast to specified type" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/compile.c -msgid "return annotation must be an identifier" +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." msgstr "" -#: py/emitnative.c -msgid "return expected '%q' but got '%q'" +#: shared-bindings/warnings/__init__.c +msgid "%q must be a subclass of %q" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] duplicates another pin assignment" +#: shared-bindings/wifi/Monitor.c +msgid "%q out of bounds" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] is not on the same port as clock" +#: shared-bindings/wifi/Radio.c +msgid "Invalid hex password" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "roll argument must be an ndarray" +#: shared-bindings/wifi/Radio.c +msgid "invalid hostname" msgstr "" -#: py/objstr.c -msgid "rsplit(None,n)" +#: shared-bindings/wifi/Radio.c +msgid "Invalid MAC address" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -msgid "sampling rate out of range" +#: shared-bindings/wifi/Radio.c +msgid "AuthMode.OPEN is not used with password" msgstr "" -#: py/modmicropython.c -msgid "schedule queue full" +#: shared-bindings/wifi/Radio.c +msgid "Invalid BSSID" msgstr "" -#: py/builtinimport.c -msgid "script compilation not supported" +#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c +msgid "Authentication failure" msgstr "" -#: py/nativeglue.c -msgid "set unsupported" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "shape must be None, and integer or a tuple of integers" +#: shared-bindings/wifi/Radio.c +#, c-format +msgid "Unknown failure %d" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "shape must be integer or tuple of integers" +#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#, c-format +msgid "No I2C device at address: 0x%x" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "short read" +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" msgstr "" -#: py/objstr.c -msgid "sign not allowed in string format specifier" +#: shared-module/audiocore/__init__.c shared-module/usb_audio/USBMicrophone.c +msgid "The sample's %q does not match" msgstr "" -#: py/objstr.c -msgid "sign not allowed with integer format specifier 'c'" +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "size is defined for ndarrays only" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Only 8/16-bit mono/stereo is supported" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "size must match out.shape when used together" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "buffer_size too small for source" msgstr "" -#: py/nativeglue.c -msgid "slice unsupported" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Couldn't allocate decoder" msgstr "" -#: py/objint.c py/sequence.c -msgid "small int overflow" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Failed to parse MP3 file" msgstr "" -#: main.c -msgid "soft reboot\n" +#: shared-module/bitbangio/I2C.c +msgid "%q too long" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "sort argument must be an ndarray" +#: shared-module/bitmapfilter/__init__.c +msgid "bitmap size and depth must match" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos array must be of shape (n_section, 6)" +#: shared-module/bitmapfilter/__init__.c +msgid "unsupported bitmap depth" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos[:, 3] should be all ones" +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sosfilt requires iterable arguments" +#: shared-module/displayio/ColorConverter.c +msgid "Only one color can be transparent at a time" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source palette too large" +#: shared-module/displayio/Group.c +msgid "Layer already in a group" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 2 or 65536" +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 65536" +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 8" +#: shared-module/displayio/OnDiskBitmap.c +msgid "RLE-compressed BMP not supported" msgstr "" -#: extmod/modre.c -msgid "splitting with sub-captures" +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" msgstr "" -#: py/objstr.c -msgid "start/end indices" +#: shared-module/displayio/__init__.c +msgid "Too many displays" msgstr "" -#: shared-bindings/random/__init__.c -msgid "stop not reachable from start" +#: shared-module/displayio/__init__.c +msgid "Too many display busses; forgot displayio.release_displays() ?" msgstr "" -#: py/stream.c shared-bindings/getpass/__init__.c -msgid "stream operation not supported" +#: shared-module/displayio/bus_core.c +msgid "Unsupported display bus type" msgstr "" -#: py/objarray.c py/objstr.c -msgid "string argument without an encoding" +#: shared-module/gifio/GifWriter.c +msgid "unsupported colorspace for GifWriter" msgstr "" -#: py/objstrunicode.c -msgid "string index out of range" +#: shared-module/i2cdisplaybus/I2CDisplayBus.c +#: shared-module/is31fl3741/IS31FL3741.c +#, c-format +msgid "Unable to find I2C Display at %x" msgstr "" -#: py/objstrunicode.c -#, c-format -msgid "string indices must be integers, not %s" +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" msgstr "" -#: py/objarray.c py/objstr.c -msgid "substring not found" +#: shared-module/imagecapture/ParallelImageCapture.c +msgid "This microcontroller does not support continuous capture." msgstr "" -#: py/compile.c -msgid "super() can't find self" +#: shared-module/is31fl3741/FrameBuffer.c +msgid "LED mappings must match display size" msgstr "" -#: extmod/modjson.c -msgid "syntax error in JSON" +#: shared-module/jpegio/JpegDecoder.c +msgid "Interrupted by output function" msgstr "" -#: extmod/modtime.c -msgid "ticks interval overflow" +#: shared-module/jpegio/JpegDecoder.c +msgid "Device error or wrong termination of input stream" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "timeout duration exceeded the maximum supported value" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient memory pool for the image" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "timeout must be < 655.35 secs" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient stream input buffer" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -msgid "timeout waiting for flux" +#: shared-module/jpegio/JpegDecoder.c +msgid "Parameter error" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: shared-module/floppyio/__init__.c -msgid "timeout waiting for index pulse" +#: shared-module/jpegio/JpegDecoder.c +msgid "Data format error (may be broken data)" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v1 card" +#: shared-module/jpegio/JpegDecoder.c +msgid "Right format but not supported" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v2 card" +#: shared-module/jpegio/JpegDecoder.c +msgid "Unsupported JPEG (may be progressive)" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "timer re-init" +#: shared-module/jpegio/JpegDecoder.c +msgid "%q() without %q()" msgstr "" -#: shared-bindings/time/__init__.c -msgid "timestamp out of range for platform time_t" +#: shared-module/memorymonitor/AllocationAlarm.c +#, c-format +msgid "Attempt to allocate %d blocks" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "tobytes can be invoked for dense arrays only" +#: shared-module/msgpack/__init__.c +msgid "short read" msgstr "" -#: py/compile.c -msgid "too many args" +#: shared-module/msgpack/__init__.c +msgid "no default packer" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c -msgid "too many dimensions" +#: shared-module/msgpack/__init__.c supervisor/shared/settings.c +msgid "Invalid format" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "too many indices" +#: shared-module/paralleldisplaybus/ParallelBus.c +msgid "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." msgstr "" -#: py/asmthumb.c -msgid "too many locals for native method" +#: shared-module/rgbmatrix/RGBMatrix.c +msgid "No timer available" msgstr "" -#: py/runtime.c +#: shared-module/rgbmatrix/RGBMatrix.c #, c-format -msgid "too many values to unpack (expected %d)" -msgstr "" - -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D arrays of equal length" +msgid "Internal error #%d" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D iterables" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v1 card" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v2 card" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_driver_install returned esp-idf error #%d" +#: shared-module/sdcardio/SDCard.c +msgid "no SD card" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_start returned esp-idf error #%d" +#: shared-module/sdcardio/SDCard.c +msgid "couldn't determine SD card version" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c -msgid "tx and rx cannot both be None" +#: shared-module/sdcardio/SDCard.c +msgid "no response from SD card" msgstr "" -#: py/objtype.c -msgid "type '%q' is not an acceptable base type" +#: shared-module/sdcardio/SDCard.c +msgid "SD card CSD format not supported" msgstr "" -#: py/objtype.c -msgid "type is not an acceptable base type" +#: shared-module/sdcardio/SDCard.c +msgid "can't set 512 block size" msgstr "" -#: py/runtime.c -msgid "type object '%q' has no attribute '%q'" +#: shared-module/ssl/SSLSocket.c +msgid "Invalid socket for TLS" msgstr "" -#: py/objtype.c -msgid "type takes 1 or 3 arguments" +#: shared-module/ssl/SSLSocket.c +msgid "invalid key" msgstr "" -#: py/objint_longlong.c -msgid "ulonglong too large" +#: shared-module/ssl/SSLSocket.c +msgid "invalid cert" msgstr "" -#: py/parse.c -msgid "unexpected indent" +#: shared-module/storage/__init__.c +msgid "Mount point directory missing" msgstr "" -#: py/bc.c -msgid "unexpected keyword argument" +#: shared-module/storage/__init__.c +msgid "Cannot remount path when visible via USB." msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c -#: shared-bindings/traceback/__init__.c -msgid "unexpected keyword argument '%q'" +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" msgstr "" -#: py/lexer.c -msgid "unicode name escapes" +#: shared-module/struct/__init__.c +msgid "buffer size must match format" msgstr "" -#: py/parse.c -msgid "unindent doesn't match any outer indent level" +#: shared-module/synthio/__init__.c +msgid "%q must be array of type 'h'" msgstr "" -#: py/objstr.c -#, c-format -msgid "unknown conversion specifier %c" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" msgstr "" -#: py/objstr.c -msgid "unknown format code '%c' for object of type '%q'" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" msgstr "" -#: py/compile.c -msgid "unknown type" +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" msgstr "" -#: py/compile.c -msgid "unknown type '%q'" +#: shared-module/usb/core/Device.c +msgid "No usb host port initialized" msgstr "" -#: py/objstr.c -#, c-format -msgid "unmatched '%c' in format" +#: shared-module/usb/core/Device.c +msgid "Pipe error" msgstr "" -#: py/objtype.c py/runtime.c -msgid "unreadable attribute" +#: shared-module/usb/core/Device.c +msgid "No configuration set" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -msgid "unsupported %q type" +#: shared-module/usb_hid/Device.c +msgid "USB busy" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" +#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Rectangle.c +msgid "can only have one parent" msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" +#: shared-module/vectorio/Polygon.c +msgid "Polygon needs at least 3 points" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "unsupported bitmap depth" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" -#: shared-module/gifio/GifWriter.c -msgid "unsupported colorspace for GifWriter" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "unsupported colorspace for dither" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" msgstr "" -#: py/objstr.c -#, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" -#: py/runtime.c -msgid "unsupported type for %q: '%s'" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" -#: py/runtime.c -msgid "unsupported type for operator" +#: supervisor/shared/safe_mode.c +msgid "Power dipped. Make sure you are providing enough power." msgstr "" -#: py/runtime.c -msgid "unsupported types for %q: '%q', '%q'" +#: supervisor/shared/safe_mode.c +msgid "You pressed the BOOT button at start up" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols is too high" +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols keyword must be specified" +#: supervisor/shared/safe_mode.c +msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: py/objint.c -#, c-format -msgid "value must fit in %d byte(s)" +#: supervisor/shared/safe_mode.c +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "value out of range of target" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: extmod/moddeflate.c -msgid "wbits" +#: supervisor/shared/safe_mode.c +msgid "Stack overflow. Increase stack size." msgstr "" -#: shared-bindings/bitmapfilter/__init__.c -msgid "" -"weights must be a sequence with an odd square number of elements (usually 9 " -"or 25)" +#: supervisor/shared/safe_mode.c +msgid "USB devices need more endpoints than are available." msgstr "" -#: shared-bindings/bitmapfilter/__init__.c -msgid "weights must be an object of type %q, %q, %q, or %q, not %q " +#: supervisor/shared/safe_mode.c +msgid "USB devices specify too many interface names." msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "width must be greater than zero" +#: supervisor/shared/safe_mode.c +msgid "Boot device must be first (interface #0)." msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" +#: supervisor/shared/safe_mode.c +msgid "Internal watchdog timer expired." msgstr "" -#: ports/raspberrypi/common-hal/wifi/Monitor.c -msgid "wifi.Monitor not available" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "window must be <= interval" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "wrong axis index" +#: supervisor/shared/safe_mode.c +msgid "Failed to write internal flash." msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "wrong axis specified" +#: supervisor/shared/safe_mode.c +msgid "Hard fault: memory access or instruction error." msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "wrong dtype" +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong index type" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." msgstr "" -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c -#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c -#: extmod/ulab/code/numpy/vector.c -msgid "wrong input type" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate to the heap." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of condition array" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of index array" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Please file an issue with your program at github.com/adafruit/circuitpython/" +"issues." msgstr "" -#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c -msgid "wrong number of arguments" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" msgstr "" -#: py/runtime.c -msgid "wrong number of values to unpack" +#: supervisor/shared/settings.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "wrong output type" +#: supervisor/shared/settings.c +msgid "Invalid unicode escape" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be an ndarray" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "Wi-Fi: " msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of float type" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "off" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of shape (n_section, 2)" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "No IP" msgstr "" diff --git a/locale/cs.po b/locale/cs.po index 0eaacb14461..a3432ce8d7f 100644 --- a/locale/cs.po +++ b/locale/cs.po @@ -6,1138 +6,1273 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-16 15:03+0000\n" -"Last-Translator: Scott Shawcroft \n" +"PO-Revision-Date: 2025-06-30 16:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: LANGUAGE \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" -"X-Generator: Weblate 5.2\n" +"Plural-Forms: nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);\n" +"X-Generator: Weblate 5.13-dev\n" -#: main.c -msgid "" -"\n" -"Code done running.\n" +#: extmod/modasyncio.c extmod/modheapq.c +msgid "empty heap" msgstr "" -"\n" -"Běh programu byl dokončen.\n" -#: main.c -msgid "" -"\n" -"Code stopped by auto-reload. Reloading soon.\n" +#: extmod/modasyncio.c +msgid "can't cancel self" +msgstr "nelze zrušit sám sebe" + +#: extmod/modasyncio.c +msgid "can't wait" +msgstr "nelze čekat" + +#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c +msgid "a bytes-like object is required" msgstr "" -"\n" -"Kód byl zastaven kvůli automatickému načtení. K načtení dojde brzy.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Please file an issue with your program at github.com/adafruit/circuitpython/" -"issues." +#: extmod/modbinascii.c +msgid "incorrect padding" msgstr "" -"\n" -"Prosím, založte issue s vaším programem na github.com/adafruit/circuitpython/" -"issues." -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Press reset to exit safe mode.\n" +#: extmod/moddeflate.c +msgid "format" msgstr "" -"\n" -"Stiskněte reset pro ukončení nouzového režimu.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"You are in safe mode because:\n" +#: extmod/moddeflate.c +msgid "wbits" msgstr "" -"\n" -"Jste v bezpečnostním režimu z důvodu:\n" -#: py/obj.c -msgid " File \"%q\"" -msgstr " Soubor \"%q\"" +#: extmod/modhashlib.c +msgid "hash is final" +msgstr "hash je konečný" -#: py/obj.c -msgid " File \"%q\", line %d" -msgstr " Soubor \"%q\", řádek %d" +#: extmod/modheapq.c +msgid "heap must be a list" +msgstr "" -#: py/builtinhelp.c -msgid " is of type %q\n" -msgstr " je typu %q\n" +#: extmod/modjson.c +msgid "syntax error in JSON" +msgstr "" -#: main.c -msgid " not found.\n" -msgstr " nenalezen\n" +#: extmod/modrandom.c +msgid "bits must be 32 or less" +msgstr "počet bitů nesmí přesáhnout 32" -#: main.c -msgid " output:\n" -msgstr " výstup:\n" +#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c +msgid "no default seed" +msgstr "" -#: py/objstr.c -#, c-format -msgid "%%c requires int or char" -msgstr "%%c vyžaduje int nebo char" +#: extmod/modre.c +msgid "splitting with sub-captures" +msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" -msgstr "%d adresní pin, %d rgb pin a %d dlaždice indikuje výšku %d, ne %d" +#: extmod/modre.c +msgid "regex too complex" +msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q and %q contain duplicate pins" -msgstr "%q a %q obsahují duplicitní piny" +#: extmod/modre.c +msgid "Error in regex" +msgstr "Chyba v regulárním výrazu" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "%q and %q must be different" -msgstr "%q a %q musí být rozdílné" +#: extmod/modtime.c +msgid "mktime needs a tuple of length 8 or 9" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "%q and %q must share a clock unit" +#: extmod/modtime.c +msgid "ticks interval overflow" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "%q cannot be changed once mode is set to %q" +#: extmod/modzlib.c +msgid "compression header" msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q contains duplicate pins" -msgstr "%q obsahuje duplicitní piny" +#: extmod/ulab/code/ndarray.c +msgid "data type not understood" +msgstr "datový typ nebyl rozpoznán" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -msgid "%q failure: %d" -msgstr "%q: selhání %d" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "pole je příliš velké" -#: py/argcheck.c -msgid "%q in %q must be of type %q, not %q" -msgstr "%q v %q musí být typu %q, ne %q" +#: extmod/ulab/code/ndarray.c +msgid "ndarray length overflows" +msgstr "délka ndarray přetekla" -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/usb_host/Port.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c -msgid "%q in use" -msgstr "%q se právě používá" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex type" +msgstr "nelze převést typ complex" -#: py/objstr.c -msgid "%q index out of range" -msgstr "Index %q je mimo rozsah" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c +msgid "too many dimensions" +msgstr "příliš mnoho dimenzí" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "Indexy %q musí být celá čísla, nikoli %s" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c +msgid "index is out of bounds" +msgstr "" -#: shared-module/bitbangio/SPI.c -msgid "%q init failed" -msgstr "Inicializace %q selhala" +#: extmod/ulab/code/ndarray.c +msgid "indices must be integers, slices, or Boolean lists" +msgstr "" -#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c -msgid "%q is %q" -msgstr "%q je %q" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c +msgid "operands could not be broadcast together" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "%q is read-only for this board" -msgstr "%q je pouze u této desky pouze pro čtení" +#: extmod/ulab/code/ndarray.c +msgid "array and index length must be equal" +msgstr "Pole a index musí mít stejnou délku" -#: py/argcheck.c shared-bindings/usb_hid/Device.c -msgid "%q length must be %d" -msgstr "Délka %q musí být %d" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex to dtype" +msgstr "nelze převést complex na dtype" -#: py/argcheck.c -msgid "%q length must be %d-%d" -msgstr "%q délka musí být %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "operation is implemented for 1D Boolean arrays only" +msgstr "operace je immplementována pouze pro 1D boolean pole" -#: py/argcheck.c -msgid "%q length must be <= %d" -msgstr "Délka %q musí být <= %d" +#: extmod/ulab/code/ndarray.c +msgid "too many indices" +msgstr "" -#: py/argcheck.c -msgid "%q length must be >= %d" -msgstr "Délka %q musí být >= %d" +#: extmod/ulab/code/ndarray.c +msgid "cannot delete array elements" +msgstr "nelze smazat prvky pole" -#: py/modsys.c py/objmodule.c py/runtime.c -msgid "%q moved from %q to %q" +#: extmod/ulab/code/ndarray.c +msgid "flattening order must be either 'C', or 'F'" msgstr "" -#: py/argcheck.c -msgid "%q must be %d" -msgstr "%q musí být %d" +#: extmod/ulab/code/ndarray.c +msgid "tobytes can be invoked for dense arrays only" +msgstr "" -#: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "%q must be %d-%d" -msgstr "%q musí být %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "operation is not supported for given type" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -msgid "%q must be 1 when %q is True" -msgstr "%q musí být 1, pokud %q je True" +#: extmod/ulab/code/ndarray.c +msgid "shape must be integer or tuple of integers" +msgstr "tvar musí být integer nebo tuple integerů" -#: py/argcheck.c shared-bindings/gifio/GifWriter.c -#: shared-module/gifio/OnDiskGif.c -msgid "%q must be <= %d" -msgstr "%q musí být <= %d" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c +msgid "maximum number of dimensions is " +msgstr "maximální počet dimenzí je " -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "%q must be <= %u" -msgstr "%q musí být <= %u" +#: extmod/ulab/code/ndarray.c +msgid "can only specify one unknown dimension" +msgstr "" -#: py/argcheck.c -msgid "%q must be >= %d" -msgstr "%q musí být >= %d" +#: extmod/ulab/code/ndarray.c +msgid "cannot reshape array" +msgstr "nelze změnit rozměry pole" -#: shared-bindings/analogbufio/BufferedIn.c -msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "%q musí být bytearray nebo pole typu 'H' nebo 'B'" +#: extmod/ulab/code/ndarray.c +msgid "cannot assign new shape" +msgstr "nelze přiřadit nový tvar" -#: shared-bindings/audiocore/RawSample.c -msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -msgstr "%q musí být bytearray nebo pole typu 'h', 'H', 'b', nebo 'B'" +#: extmod/ulab/code/ndarray.c +msgid "function is defined for ndarrays only" +msgstr "funkce je definována pouze pro ndarraye" -#: shared-bindings/warnings/__init__.c -msgid "%q must be a subclass of %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "operation not supported for the input types" msgstr "" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -msgid "%q must be array of type 'H'" -msgstr "%q musí být pole typu 'H V" +#: extmod/ulab/code/ndarray_operators.c +msgid "dtype of int32 is not supported" +msgstr "" -#: shared-module/synthio/__init__.c -msgid "%q must be array of type 'h'" -msgstr "%q musí být pole typu 'h'" +#: extmod/ulab/code/ndarray_operators.c +msgid "cannot cast output with casting rule" +msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "%q must be multiple of 8." +#: extmod/ulab/code/ndarray_operators.c +msgid "results cannot be cast to specified type" msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c -#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c -#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c -#: shared-module/synthio/Synthesizer.c -msgid "%q must be of type %q or %q, not %q" -msgstr "%q musí být typu %q nebo %q, ne %q" +#: extmod/ulab/code/numpy/approx.c +msgid "interp is defined for 1D iterables of equal length" +msgstr "" -#: shared-bindings/jpegio/JpegDecoder.c -msgid "%q must be of type %q, %q, or %q, not %q" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D iterables" msgstr "" -#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c -#: shared-module/synthio/__init__.c -msgid "%q must be of type %q, not %q" -msgstr "%q musí být typu %q, ne %q" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D arrays of equal length" +msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -msgid "%q must be power of 2" -msgstr "%q musí být mocnina 2" +#: extmod/ulab/code/numpy/bitwise.c +msgid "not supported for input types" +msgstr "není podporováno pro vstupní typy" -#: shared-bindings/wifi/Monitor.c -msgid "%q out of bounds" -msgstr "%q je mimo hranice" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "function is implemented for ndarrays only" +msgstr "funkce je implementována jen pro ndarraye" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c -#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c -msgid "%q out of range" -msgstr "%q je mimo rozsah" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be an ndarray, or a scalar" +msgstr "vstup musí být ndarray nebo scalar" -#: py/objmodule.c py/runtime.c -msgid "%q renamed %q" -msgstr "" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be a 1D ndarray" +msgstr "vstup musí být 1D ndarray" -#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c -msgid "%q step cannot be zero" -msgstr "%q krok nemůže být nula" +#: extmod/ulab/code/numpy/carray/carray_tools.c +msgid "not implemented for complex dtype" +msgstr "není implementováno pro komplexní dtype" -#: shared-module/bitbangio/I2C.c -msgid "%q too long" +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c +#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c +#: extmod/ulab/code/numpy/vector.c +msgid "wrong input type" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "%q() takes %d positional arguments but %d were given" -msgstr "%q() vyžaduje %d pozičních argumentů, ale pouze %d jich bylo zadáno" +#: extmod/ulab/code/numpy/create.c +msgid "input argument must be an integer, a tuple, or a list" +msgstr "vstupní argument musí být integer, tuple nebo list" -#: shared-module/jpegio/JpegDecoder.c -msgid "%q() without %q()" +#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c +msgid "wrong number of arguments" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q, %q, and %q must all be the same length" -msgstr "%q, %q, a %q musí mít všechny shodnou délku" - -#: py/objint.c shared-bindings/storage/__init__.c -msgid "%q=%q" -msgstr "%q=%q" +#: extmod/ulab/code/numpy/create.c py/objint_longlong.c py/objint_mpz.c +msgid "divide by zero" +msgstr "dělení nulou" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts in more bits than pin count" -msgstr "%q[%u] posouvá dovnitř o více bitů než je počet pinů" +#: extmod/ulab/code/numpy/create.c +msgid "arange: cannot compute length" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts out more bits than pin count" -msgstr "%q[%u] posouvá ven o více bitů než je počet pinů" +#: extmod/ulab/code/numpy/create.c +msgid "first argument must be a tuple of ndarrays" +msgstr "první argument musí být tuple nebo ndarray" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] uses extra pin" -msgstr "%q[%u] používá extra pin" +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "pouze ndarraye mohou být spojeny" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] waits on input outside of count" -msgstr "%q[%u] čeká na vstup mimo rozsah" +#: extmod/ulab/code/numpy/create.c +msgid "wrong axis specified" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -#, c-format -msgid "%s error 0x%x" -msgstr "%s chyba 0x%x" +#: extmod/ulab/code/numpy/create.c +msgid "input arrays are not compatible" +msgstr "vstupní pole nejsou kompatibilní" -#: py/argcheck.c -msgid "'%q' argument required" -msgstr "Je vyžadován argument '%q'" +#: extmod/ulab/code/numpy/create.c +msgid "input must be 1- or 2-d" +msgstr "vstup musí být 1- nebo 2-d" -#: py/proto.c -msgid "'%q' object does not support '%q'" -msgstr "Objekt '%q' nepodporuje '%q'" +#: extmod/ulab/code/numpy/create.c +msgid "number of points must be at least 2" +msgstr "" -#: py/runtime.c -msgid "'%q' object is not an iterator" -msgstr "Objekt '%q' není iterátor" +#: extmod/ulab/code/numpy/create.c +msgid "offset must be non-negative and no greater than buffer length" +msgstr "" -#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c -msgid "'%q' object is not callable" -msgstr "Objekt '%q' nelze zavolat" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer size must be a multiple of element size" +msgstr "velikost bufferu musí být násobkem velikosti elementu" -#: py/runtime.c -msgid "'%q' object is not iterable" -msgstr "Objekt '%q' není iterovatelný" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer is smaller than requested size" +msgstr "buffer je menší než požadovaná velikost" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a label" -msgstr "'%s' očekává label" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is defined for ndarrays only" +msgstr "FFT lze použít pouze pro ndarrays" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a register" -msgstr "'%s' očekává registr" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is implemented for linear arrays only" +msgstr "FFT je implementován pouze pro lineární pole" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects a special register" -msgstr "'%s' očekává speciální registr" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "input array length must be power of 2" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an FPU register" -msgstr "'%s' očekává registr FPU" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "real and imaginary parts must be of equal length" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s' očekává adresu ve formátu [a, b]" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be ndarrays" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects an integer" -msgstr "'%s' očekává integer (celé číslo)" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be linear arrays" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects at most r%d" -msgstr "'%s' očekává nanejvýš r%d" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must not be empty" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' očekává {r0, r1, ...}" +#: extmod/ulab/code/numpy/io/io.c +msgid "corrupted file" +msgstr "poškozený soubor" -#: py/emitinlinextensa.c -#, c-format -msgid "'%s' integer %d isn't within range %d..%d" -msgstr "'%s' integer %d není v rozsahu %d..%d" +#: extmod/ulab/code/numpy/io/io.c +msgid "wrong dtype" +msgstr "špatný dtype" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" -msgstr "'%s' integer 0x%x nepatří do masky 0x%x" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols keyword must be specified" +msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item assignment" -msgstr "'%s' objekt nepodporuje přiřazení položky" +#: extmod/ulab/code/numpy/io/io.c +msgid "empty file" +msgstr "prázdný soubor" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item deletion" -msgstr "'%s' objekt nepodporuje smazání položky" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols is too high" +msgstr "" -#: py/runtime.c -msgid "'%s' object has no attribute '%q'" -msgstr "'%s' objekt nemá žádný atribut '%q'" +#: extmod/ulab/code/numpy/io/io.c +msgid "array has too many dimensions" +msgstr "pole má příliš mnoho dimenzí" -#: py/obj.c -#, c-format -msgid "'%s' object isn't subscriptable" -msgstr "'%s' objekt není vložitelný" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "input matrix is asymmetric" +msgstr "" -#: py/objstr.c -msgid "'=' alignment not allowed in string format specifier" -msgstr "Specifikátor zarovnání '=' není ve formátovacím řetězci povolen" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "matrix is not positive definite" +msgstr "" -#: shared-module/struct/__init__.c -msgid "'S' and 'O' are not supported format types" -msgstr "'S' a 'O' nejsou podporované typy formátů" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "iterations did not converge" +msgstr "" -#: py/compile.c -msgid "'align' requires 1 argument" -msgstr "'align' vyžaduje 1 argument" +#: extmod/ulab/code/numpy/linalg/linalg.c +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "input matrix is singular" +msgstr "" -#: py/compile.c -msgid "'await' outside function" -msgstr "'await' je volán mimo funkci" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for ndarrays only" +msgstr "operace je definována pouze pro ndarray pole" -#: py/compile.c -msgid "'break'/'continue' outside loop" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for 2D arrays only" +msgstr "operace je definována pouze pro 2D pole" + +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "mode must be complete, or reduced" msgstr "" -#: py/compile.c -msgid "'data' requires at least 2 arguments" -msgstr "'data' vyžaduje nejméně 2 argumenty" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" -#: py/compile.c -msgid "'data' requires integer arguments" -msgstr "'data' vyžaduje celočíselné argumenty" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get (arg)min/(arg)max of empty sequence" +msgstr "pokus o získání (arg)min/(arg)max z prázdné sekvence" -#: py/compile.c -msgid "'label' requires 1 argument" -msgstr "'label' vyžaduje 1 argument" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +msgid "axis must be None, or an integer" +msgstr "osa musí být None nebo integer" -#: py/emitnative.c -msgid "'not' not implemented" +#: extmod/ulab/code/numpy/numerical.c +msgid "operation is not implemented on ndarrays" msgstr "" -#: py/compile.c -msgid "'return' outside function" -msgstr "'return' je volán mimo funkci" +#: extmod/ulab/code/numpy/numerical.c +msgid "input must be tuple, list, range, or ndarray" +msgstr "" -#: py/compile.c -msgid "'yield from' inside async function" -msgstr "'yield from' volán uvnitř funkce async" +#: extmod/ulab/code/numpy/numerical.c +msgid "sort argument must be an ndarray" +msgstr "" -#: py/compile.c -msgid "'yield' outside function" -msgstr "'yield' je volán mimo funkci" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort argument must be an ndarray" +msgstr "" -#: py/compile.c -msgid "* arg after **" -msgstr "* arg po **" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort is not implemented for flattened arrays" +msgstr "argsort není implementován pro zploštěná pole" -#: py/compile.c -msgid "*x must be assignment target" -msgstr "∗x musí být cíl přiřazení" +#: extmod/ulab/code/numpy/numerical.c +msgid "axis too long" +msgstr "osa je příliš dlouhá" -#: py/obj.c -msgid ", in %q\n" -msgstr ", v% q\n" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c +msgid "arguments must be ndarrays" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid ".show(x) removed. Use .root_group = x" +#: extmod/ulab/code/numpy/numerical.c +msgid "cross is defined for 1D arrays of length 3" msgstr "" -#: py/objcomplex.c -msgid "0.0 to a complex power" -msgstr "0.0 na komplexní mocninu" +#: extmod/ulab/code/numpy/numerical.c +msgid "diff argument must be an ndarray" +msgstr "" -#: py/modbuiltins.c -msgid "3-arg pow() not supported" -msgstr "pow() nepodporuje 3 argumenty" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "AP could not be started" -msgstr "AP nemohl být spuštěn" +#: extmod/ulab/code/numpy/numerical.c +msgid "differentiation order out of range" +msgstr "" -#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, c-format -msgid "Address must be %d bytes long" -msgstr "Adresa musí být %d bajtů dlouhá" +#: extmod/ulab/code/numpy/numerical.c +msgid "flip argument must be an ndarray" +msgstr "" -#: ports/espressif/common-hal/memorymap/AddressRange.c -#: ports/nordic/common-hal/memorymap/AddressRange.c -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Address range not allowed" -msgstr "Adresní rozsah není povolen" +#: extmod/ulab/code/numpy/numerical.c +msgid "wrong axis index" +msgstr "" -#: shared-bindings/memorymap/AddressRange.c -msgid "Address range wraps around" -msgstr "Adresní rozsah se překlápí přes maximální možnou adresu" +#: extmod/ulab/code/numpy/numerical.c +msgid "median argument must be an ndarray" +msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "All CAN peripherals are in use" -msgstr "Všechny CAN periferie jsou používány" +#: extmod/ulab/code/numpy/numerical.c +msgid "roll argument must be an ndarray" +msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/nordic/common-hal/busio/I2C.c -msgid "All I2C peripherals are in use" -msgstr "Všechny I2C periferie jsou používány" +#: extmod/ulab/code/numpy/poly.c +msgid "input data must be an iterable" +msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "All RX FIFOs in use" -msgstr "Všechny RX FIFO jsou používány" +#: extmod/ulab/code/numpy/poly.c +msgid "more degrees of freedom than data points" +msgstr "" -#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c -msgid "All SPI peripherals are in use" -msgstr "Všechny SPI periferie jsou používány" +#: extmod/ulab/code/numpy/poly.c +msgid "input vectors must be of equal length" +msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c -msgid "All UART peripherals are in use" -msgstr "Všechny UART periferie jsou používány" +#: extmod/ulab/code/numpy/poly.c +msgid "could not invert Vandermonde matrix" +msgstr "" -#: ports/nordic/common-hal/countio/Counter.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c -msgid "All channels in use" -msgstr "Všechny kanály jsou používány" +#: extmod/ulab/code/numpy/poly.c +msgid "input is not iterable" +msgstr "vstup není iterovatelný" -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All dma channels in use" -msgstr "Všechny DMA kanály jsou používány" +#: extmod/ulab/code/numpy/random/random.c +msgid "argument must be None, an integer or a tuple of integers" +msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "All event channels in use" -msgstr "Všechny kanály událostí jsou již používány" +#: extmod/ulab/code/numpy/random/random.c +msgid "shape must be None, and integer or a tuple of integers" +msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All state machines in use" -msgstr "Všechny stavové automaty jsou používány" +#: extmod/ulab/code/numpy/random/random.c +msgid "out has wrong type" +msgstr "" -#: ports/atmel-samd/audio_dma.c -msgid "All sync event channels in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array has wrong type" msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -msgid "All timers for this pin are in use" -msgstr "Všechny časovače pro tento pin jsou používány" +#: extmod/ulab/code/numpy/random/random.c +msgid "size must match out.shape when used together" +msgstr "" -#: ports/atmel-samd/common-hal/_pew/PewPew.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/peripherals/nrf/timers.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c -msgid "All timers in use" -msgstr "Všechny časovače jsou používány" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array must be contiguous" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Already advertising." -msgstr "Již propagujeme." +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of condition array" +msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -msgid "Already have all-matches listener" -msgstr "Již existuje posluchač pro všechny zprávy" +#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c +msgid "first argument must be an ndarray" +msgstr "" -#: ports/espressif/bindings/espnow/ESPNow.c -#: ports/espressif/common-hal/espulp/ULP.c -#: shared-module/memorymonitor/AllocationAlarm.c -#: shared-module/memorymonitor/AllocationSize.c -msgid "Already running" -msgstr "Již běží" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong index type" +msgstr "špatný typ indexu" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Already scanning for wifi networks" -msgstr "Již skenuje wifi sítě" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of index array" +msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "An error occurred while retrieving '%s':\n" -msgstr "Došlo k chybě při načítání '%s'\n" +#: extmod/ulab/code/numpy/transform.c +msgid "dimensions do not match" +msgstr "dimenze nesouhlasí" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Another PWMAudioOut is already active" -msgstr "Jiný PWMAudioOut je již aktivní" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be an ndarray" +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -msgid "Another send is already active" -msgstr "Další odesílání je již aktivní" - -#: shared-bindings/pulseio/PulseOut.c -msgid "Array must contain halfwords (type 'H')" -msgstr "Pole musí obsahovat poloviční slova (typ „H“)" - -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Array values should be single bytes." -msgstr "Hodnoty pole by měly být jednoduché bajty." - -#: shared-module/memorymonitor/AllocationAlarm.c -#, c-format -msgid "Attempt to allocate %d blocks" -msgstr "Pokus o alokování %d bloků" - -#: ports/raspberrypi/audio_dma.c -msgid "Audio conversion not implemented" -msgstr "Konverze audia není implementována" - -#: shared-bindings/wifi/Radio.c -msgid "AuthMode.OPEN is not used with password" -msgstr "AuthMode.OPEN nepoužívá heslo" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be of float dtype" +msgstr "" -#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c -msgid "Authentication failure" -msgstr "Autentizace selhala" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output dimensions differ" +msgstr "dimenze vstupu a výstupu se liší" -#: main.c -msgid "Auto-reload is off.\n" -msgstr "Automatické načtení je vypnuto.\n" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output shapes differ" +msgstr "vstupní a výstupní tvar je růzmý" -#: main.c -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for function" msgstr "" -"Automatické opětovné načtení je zapnuto. Jednoduše uložte soubory přes USB a " -"spusťte je, nebo vypněte REPL.\n" - -#: ports/espressif/common-hal/canio/CAN.c -msgid "Baudrate not supported by peripheral" -msgstr "Baudrate není podporován periférií" - -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Below minimum frame rate" -msgstr "Pod minimální obnovovací frekvencí" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Bit clock and word select must be sequential GPIO pins" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for complex dtype" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Bitmap size and bits per value must match" -msgstr "Velikost bitmapy a počet bitů na hodnotu se musí shodovat" +#: extmod/ulab/code/numpy/vector.c +msgid "dtype must be float, or complex" +msgstr "dtype musí být float nebo complex" -#: supervisor/shared/safe_mode.c -msgid "Boot device must be first (interface #0)." -msgstr "Bootovací zařízení musí být první (rozhraní #0)." +#: extmod/ulab/code/numpy/vector.c +msgid "can't convert complex to float" +msgstr "nelze převést complex na float" -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Both RX and TX required for flow control" -msgstr "RX a TX jsou vyžadovány pro kontrolu toku" +#: extmod/ulab/code/numpy/vector.c +msgid "input dtype must be float or complex" +msgstr "vstupní dtype musí být float nebo complex" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Brightness not adjustable" -msgstr "Jas není nastavitelný" +#: extmod/ulab/code/numpy/vector.c +msgid "first argument must be a callable" +msgstr "První argument musí být zavolatelný" -#: shared-bindings/_bleio/UUID.c -#, c-format -msgid "Buffer + offset too small %d %d %d" -msgstr "Vyrovnávací paměť + offset je příliš malý %d %d %d" +#: extmod/ulab/code/numpy/vector.c +msgid "wrong output type" +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Buffer elements must be 4 bytes long or less" -msgstr "Prvky bufferu musí být 4 bajty dlouhé nebo méně" +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "first two arguments must be ndarrays" +msgstr "první dva argumenty musí být ndarray" -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Buffer is not a bytearray." -msgstr "Buffer není bytearray." +#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c +msgid "input must be a dense ndarray" +msgstr "vstup musí být hustý ndarray" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, c-format -msgid "Buffer length %d too big. It must be less than %d" -msgstr "Délka vyrovnávací paměti %d je příliš velká. Musí být menší než %d" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "first argument must be a function" +msgstr "první argument musí být funkce" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -#: ports/cxd56/common-hal/sdioio/SDCard.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c -#: shared-module/sdcardio/SDCard.c -#, c-format -msgid "Buffer must be a multiple of %d bytes" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "function has the same sign at the ends of interval" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -#, c-format -msgid "Buffer too short by %d bytes" -msgstr "Buffer je příliš krátký o %d bajtů" - -#: ports/cxd56/common-hal/camera/Camera.c -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c -msgid "Buffer too small" -msgstr "Buffer příliš malý" - -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, c-format -msgid "Bus pin %d is already in use" -msgstr "Sběrnicový pin %d je již používán" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter should be > 0" +msgstr "maxiter by měl být > 0" -#: shared-bindings/_bleio/UUID.c -msgid "Byte buffer must be 16 bytes." -msgstr "Buffer musí být dlouhý 16 bajtů." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter must be > 0" +msgstr "maxiter musí být > 0" -#: shared-bindings/aesio/aes.c -msgid "CBC blocks must be multiples of 16 bytes" -msgstr "Bloky CBC musí být násobky 16 bajtů" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be iterable" +msgstr "data musí být iterovatelná" -#: supervisor/shared/safe_mode.c -msgid "CIRCUITPY drive could not be found or created." -msgstr "Disk CIRCUITPY nelze nalézt nebo vytvořit." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "initial values must be iterable" +msgstr "výchozí hodnoty musí být iterovatelné" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "CRC or checksum was invalid" -msgstr "CRC nebo kontrolní součet byl neplatný" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be of equal length" +msgstr "data musí mít stejnou délku" -#: py/objtype.c -msgid "Call super().__init__() before accessing native object." -msgstr "Volání super().__init__() před přístupem k nativnímu objektu." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sosfilt requires iterable arguments" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Camera init" -msgstr "Inizializace kamery" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "input must be one-dimensional" +msgstr "vstup musí být jednorozměrný" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on RTC IO from deep sleep." -msgstr "Alarm z IO RTC je možné generovat pouze z hlubokého spánku." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be an ndarray" +msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on one low pin while others alarm high from deep sleep." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of shape (n_section, 2)" msgstr "" -"Lze nastavit alarm na jednom pinu ve stavu low při hlubokém spánku, ostatní " -"musí být ve stavu high." -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on two low pins from deep sleep." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of float type" msgstr "" -"Lze nastavit alarm na maximálně dvou pinech ve stavu low při hlubokém spánku." -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "Can't set CCCD on local Characteristic" -msgstr "Nelze nastavit CCCD na místní charakteristiku" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos array must be of shape (n_section, 6)" +msgstr "" -#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c -#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c -#: shared-bindings/usb_video/__init__.c -msgid "Cannot change USB devices now" -msgstr "Nelze změnit USB zařízení" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos[:, 3] should be all ones" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot create a new Adapter; use _bleio.adapter;" -msgstr "Není možné vytvořit nový adaptér; použití _bleio.adapter;" +#: extmod/ulab/code/ulab_tools.c +msgid "axis is out of bounds" +msgstr "osa je mimo rozsah" -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Cannot delete values" -msgstr "Nelze odstranit hodnoty" +#: extmod/ulab/code/ulab_tools.c +msgid "size is defined for ndarrays only" +msgstr "" -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c -#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c -#: ports/nordic/common-hal/digitalio/DigitalInOut.c -#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c -msgid "Cannot get pull while in output mode" -msgstr "Nelze získat ve výstupním režimu" +#: extmod/ulab/code/ulab_tools.c +msgid "input must be square matrix" +msgstr "" -#: ports/nordic/common-hal/microcontroller/Processor.c -msgid "Cannot get temperature" -msgstr "Nelze získat teplotu (°C)" +#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c +msgid "input must be an ndarray" +msgstr "vstup musí být ndarray" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot have scan responses for extended, connectable advertisements." +#: extmod/ulab/code/utils/utils.c +msgid "out must be a float dense array" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot pull on input-only pin." -msgstr "Nelze aktivovat pull rezistor na pinu, který je pouze pro vstup." +#: extmod/ulab/code/utils/utils.c +msgid "offset is too large" +msgstr "offset je příliš velký" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Cannot record to a file" -msgstr "Nelze nahrávat do souboru" +#: extmod/ulab/code/utils/utils.c +msgid "out array is too small" +msgstr "výstupní pole je příliš malé" -#: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "Není možné znovu připojit '/', pokud je viditelné pomocí USB." +#: extmod/vfs_fat.c py/moderrno.c +msgid "Read-only filesystem" +msgstr "Filesystém pouze pro čtení" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Cannot set value when direction is input." -msgstr "Nelze nastavit hodnotu, když směr je vstup." +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "I/O operace nad zavřeným souborem" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "Nelze určit RTS nebo CTS v režimu RS485" - -#: py/objslice.c -msgid "Cannot subclass slice" -msgstr "Nelze použít řez podtřídy" - -#: ports/nordic/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge, only level" -msgstr "Nelze probudit hranou na pinu, pouze úrovní" - -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge. Only level." -msgstr "Nelze probudit hranou na pinu. Pouze úrovní." - -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "CharacteristicBuffer writing not provided" -msgstr "CharacteristicBuffer psaní není poskytováno" +#: extmod/vfs_posix_file.c +msgid "poll on file not available on win32" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "Jádro kódu CircuitPython tvrdě havarovalo. Jejda!\n" +#: main.c +msgid "Done" +msgstr "Hotovo" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Clock unit in use" -msgstr "Jednotka hodin je používána" +#: main.c +msgid " output:\n" +msgstr " výstup:\n" -#: shared-bindings/_bleio/Connection.c +#: main.c msgid "" -"Connection has been disconnected and can no longer be used. Create a new " -"connection." -msgstr "" -"Připojení bylo odpojeno a nelze jej dále používat. Vytvořte nové připojení." - -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays have different lengths" -msgstr "Pole souřadnic mají různé délky" - -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays types have different sizes" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" msgstr "" +"Automatické opětovné načtení je zapnuto. Jednoduše uložte soubory přes USB a " +"spusťte je, nebo vypněte REPL.\n" -#: shared-bindings/_bleio/Adapter.c -msgid "Could not set address" -msgstr "Není možné nastavit adresu" - -#: ports/stm/common-hal/busio/UART.c -msgid "Could not start interrupt, RX busy" -msgstr "Nelze začít přerušení, RX je zaneprázdněn" +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Automatické načtení je vypnuto.\n" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Couldn't allocate decoder" -msgstr "Dekodér nelze přiřadit" +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Běh v nouzovém režimu! Uložený kód není zpracováván.\n" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Channel Init Error" -msgstr "Chyba inicializace kanálu DAC" +#: main.c +msgid " not found.\n" +msgstr " nenalezen\n" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Device Init Error" -msgstr "Chyba inicializace zařízení DAC" +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "UPOZORNĚNÍ: Název souboru vašeho kódu má dvě koncovky\n" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "DAC already in use" -msgstr "DAC se již používá" +#: main.c +msgid "" +"\n" +"Code stopped by auto-reload. Reloading soon.\n" +msgstr "" +"\n" +"Kód byl zastaven kvůli automatickému načtení. K načtení dojde brzy.\n" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -msgid "Data 0 pin must be byte aligned" -msgstr "Datový pin 0 musí být zarovnán na bajty" +#: main.c +msgid "" +"\n" +"Code done running.\n" +msgstr "" +"\n" +"Běh programu byl dokončen.\n" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Datový blok musí následovat fmt blok" +#: main.c +msgid "Woken up by alarm.\n" +msgstr "Probuzen alarmem.\n" -#: shared-module/jpegio/JpegDecoder.c -msgid "Data format error (may be broken data)" +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +"Zmáčkněte jakoukoli klávesu pro spuštění REPLu. Použijte CTRL-D pro opětovné " +"načtení.\n" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data not supported with directed advertising" -msgstr "Data nejsou podporována s cíleným oznamováním" +#: main.c +msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +msgstr "Předstírám hluboký spánek do alarmu, CTRL-C nebo zápisu souboru.\n" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data too large for advertisement packet" -msgstr "Data jsou příliš velká pro propagovaný paket" +#: main.c +msgid "UID:" +msgstr "UID:" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Deep sleep pins must use a rising edge with pulldown" +#: main.c +msgid "soft reboot\n" msgstr "" -"Piny pro hluboký spánek musí používat náběžnou hranu s pulldown rezistorem" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Destination capacity is smaller than destination_length." -msgstr "Cílová kapacita je menší než destination_length." +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c +#: ports/stm/common-hal/audioio/AudioOut.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c +#: shared-module/busdisplay/BusDisplay.c shared-module/ssl/SSLContext.c +msgid "%q init failed" +msgstr "Inicializace %q selhala" -#: shared-module/jpegio/JpegDecoder.c -msgid "Device error or wrong termination of input stream" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" msgstr "" -#: ports/nordic/common-hal/audiobusio/I2SOut.c -msgid "Device in use" -msgstr "Zařízení je používáno" +#: ports/analog/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c +#: shared-bindings/bitmaptools/__init__.c shared-bindings/canio/Match.c +#: shared-bindings/time/__init__.c +msgid "%q out of range" +msgstr "%q je mimo rozsah" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display must have a 16 bit colorspace." -msgstr "Displej musí mít 16bitový barevný prostor." +#: ports/analog/common-hal/busio/SPI.c +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid state" +msgstr "Chybný stav" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display rotation must be in 90 degree increments" -msgstr "Otočení displeje musí být po 90 stupních" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" -#: main.c -msgid "Done" -msgstr "Hotovo" +#: ports/analog/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "RS485" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Drive mode not used when direction is input." +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" msgstr "" -#: py/obj.c -msgid "During handling of the above exception, another exception occurred:" -msgstr "Při zpracování uvedené výjimky nastala další výjimka:" +#: ports/analog/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Both RX and TX required for flow control" +msgstr "RX a TX jsou vyžadovány pro kontrolu toku" -#: shared-bindings/aesio/aes.c -msgid "ECB only operates on 16 bytes at a time" -msgstr "ECB operuje najednou pouze 16 bajtů" +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c +msgid "Failed to allocate %q buffer" +msgstr "Chyba alokace %q bufferu" -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/canio/CAN.c -msgid "ESP-IDF memory allocation failed" -msgstr "ESP-IDF alokace paměti selhala" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" -#: extmod/modre.c -msgid "Error in regex" -msgstr "Chyba v regulárním výrazu" +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Error in safemode.py." -msgstr "Chyba v safemode.py." +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "Všechny UART periferie jsou používány" -#: shared-bindings/alarm/__init__.c -msgid "Expected a kind of %q" -msgstr "Očekáván typ %q" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c +#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/microcontroller/Processor.c +#: ports/espressif/common-hal/mipidsi/Display.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +#: ports/raspberrypi/bindings/picodvi/Framebuffer.c +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c +msgid "Invalid %q" +msgstr "Špatný %s" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Extended advertisements with scan response not supported." +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is defined for ndarrays only" -msgstr "FFT lze použít pouze pro ndarrays" - -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is implemented for linear arrays only" -msgstr "FFT je implementován pouze pro lineární pole" - -#: shared-bindings/ps2io/Ps2.c -msgid "Failed sending command." -msgstr "Nepodařilo se odeslat příkaz." +#: ports/atmel-samd/audio_dma.c +msgid "All sync event channels in use" +msgstr "" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to acquire mutex, err 0x%04x" -msgstr "Nepodařilo se získat mutex, err 0x%04x" +#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "Interní audio buffer je příliš malý" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Failed to add service TXT record" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" msgstr "" -#: shared-bindings/mdns/Server.c -msgid "" -"Failed to add service TXT record; non-string or bytes found in txt_records" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "Failed to allocate %q buffer" -msgstr "Chyba alokace %q bufferu" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "Při spuštění jsi stiskl obě tlačítka." -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to allocate Wifi memory" -msgstr "Chyba alokace paměti WiFi" +#: ports/atmel-samd/common-hal/_pew/PewPew.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "All timers in use" +msgstr "Všechny časovače jsou používány" -#: ports/espressif/common-hal/wifi/ScannedNetworks.c -msgid "Failed to allocate wifi scan memory" -msgstr "Nepodařilo se alokovat paměť pro wifi scan" +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: ports/atmel-samd/common-hal/countio/Counter.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/max3421e/Max3421E.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +msgid "Internal resource(s) in use" +msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Failed to buffer the sample" -msgstr "Nepodařilo se nabufferovat sample" +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: supervisor/shared/safe_mode.c +msgid "Unknown reason." +msgstr "Neznámý důvod." -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: internal error" -msgstr "Připojení se nezdařilo: interní chyba" +#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +#: ports/nordic/common-hal/alarm/time/TimeAlarm.c +#: ports/stm/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set" +msgstr "Lze nastavit pouze jeden alarm typu alarm.time" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: timeout" -msgstr "Nepodařilo se připojit: časový limit" +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "No DAC on chip" +msgstr "Žádný DAC na čipu" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Failed to parse MP3 file" -msgstr "Soubor MP3 se nepodařilo analyzovat" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "%q and %q must share a clock unit" +msgstr "" -#: ports/nordic/sd_mutex.c +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Jednotka hodin je používána" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Žádné volné GCLK" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample" +msgstr "V samplu je příliš mnoho kanálů" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "No DMA channel found" +msgstr "Nebyl nalezen žádný kanál DMA" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c #, c-format -msgid "Failed to release mutex, err 0x%04x" -msgstr "Nepodařilo se uvolnit mutex, err 0x%04x" +msgid "Only 8 or 16 bit mono with %dx oversampling supported." +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Failed to write internal flash." -msgstr "Nepodařilo se zapsat do interní paměti." +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "" -#: py/moderrno.c -msgid "File exists" -msgstr "soubor existuje" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC se již používá" -#: shared-module/os/getenv.c -msgid "File not found" -msgstr "Soubor nenalezen" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Pravý kanál nepodporován" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Všechny kanály událostí jsou již používány" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/I2C.c +#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/busio/I2C.c +msgid "No pull up found on SDA or SCL; check your wiring" +msgstr "SDA nebo SCL zřejmě nemá pull up; zkontroluj zapojení" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "%q must be power of 2" +msgstr "%q musí být mocnina 2" + +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c +#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c +#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c +#: shared-bindings/paralleldisplaybus/ParallelBus.c +#: shared-bindings/qspibus/QSPIBus.c shared-module/bitbangio/SPI.c +msgid "No %q pin" +msgstr "Žádný %q pin" + +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "Všechny RX FIFO jsou používány" + +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "Již existuje posluchač pro všechny zprávy" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Filtry jsou příliš komplexní" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is duplicate" -msgstr "Firmware je duplicitní" +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +#: ports/nordic/common-hal/digitalio/DigitalInOut.c +#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Nelze získat ve výstupním režimu" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is invalid" -msgstr "Firmware není validní" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_pins[%d]" +msgstr "Chybný data_pin[%d]" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is too big" -msgstr "Firmware je příliš velký" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "datový pin #%d je používán" -#: shared-bindings/bitmaptools/__init__.c -msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" -msgstr "Pro barevný prostor L8 musí mít vstupní bitmapa 8 bitů na pixel" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c +#: shared-bindings/microcontroller/Pin.c +msgid "Invalid %q pin" +msgstr "Neplatný pin %q" -#: shared-bindings/bitmaptools/__init__.c -msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" -msgstr "Pro barevný prostor RGB musí mít vstupní bitmapa 16 bitů na pixel" +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +#: ports/cxd56/common-hal/microcontroller/__init__.c +#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c +msgid "No bootloader present" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Format not supported" -msgstr "Formát není podporován" +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "Datový pin 0 musí být zarovnán na bajty" -#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c -msgid "" -"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "Sběrnicový pin %d je již používán" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/pulseio/PulseIn.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c +#: shared-bindings/ps2io/Ps2.c +msgid "pop from empty %q" +msgstr "pop z prázdného %q" + +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "Input taking too long" +msgstr "Vstup trval příliš dlouho" + +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Další odesílání je již aktivní" + +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "%q failure: %d" +msgstr "%q: selhání %d" + +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/cxd56/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c +#: shared-module/sdcardio/SDCard.c +#, c-format +msgid "Buffer must be a multiple of %d bytes" msgstr "" -"Frekvence musí být 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 nebo 1008 " -"Mhz" -#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c -#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c -msgid "Function requires lock" -msgstr "Funkce vyžaduje zámek" +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" + +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/stm/common-hal/busio/UART.c +msgid "UART init" +msgstr "Inicializace UART" + +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Camera init" +msgstr "Inizializace kamery" + +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Size not supported" +msgstr "Velikost není podporována" + +#: ports/cxd56/common-hal/camera/Camera.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c +msgid "Buffer too small" +msgstr "Buffer příliš malý" + +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c +msgid "Format not supported" +msgstr "Formát není podporován" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" msgstr "Inicializace GNSS" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Generic Failure" -msgstr "Základní chyba" +#: ports/cxd56/common-hal/sdioio/SDCard.c +msgid "SDCard init" +msgstr "Inicializace SD karty" -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Group already used" -msgstr "Skupina již byla použita" +#: ports/espressif/bindings/espnow/ESPNow.c +#: ports/espressif/common-hal/espulp/ULP.c +#: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize.c +msgid "Already running" +msgstr "Již běží" -#: supervisor/shared/safe_mode.c -msgid "Hard fault: memory access or instruction error." -msgstr "Fatální chyba: přístup k paměti nebo chyba instrukce." +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q je %q" -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c -#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c -#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c -msgid "Hardware in use, try alternative pins" -msgstr "Hardware je používán, zkuste alternativní piny" +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "Při spuštění jsi stiskl tlačítko SW38." -#: supervisor/shared/safe_mode.c -msgid "Heap allocation when VM not running." -msgstr "Alokace heapu při neběžícím VM." +#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h +#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h +msgid "You pressed the BOOT button at start up." +msgstr "" + +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "Při spuštění jsi stiskl tlačítko na pinu GPIO0." + +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "Při spuštění jsi stiskl tlačítko Rec." + +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +#: ports/espressif/boards/vidi_x/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "Při spuštění jsi stiskl tlačítko VOLUME." + +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "Při spuštění jsi stiskl středové tlačítko." + +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "Při spuštění jsi stiskl tlačítko A." + +#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h +msgid "You pressed button DOWN at start up." +msgstr "Při spuštění jsi stiskl tlačítko DOWN." + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Update failed" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Scan již probíhá. Lze zastavit pomocí stop_scan." + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: internal error" +msgstr "Připojení se nezdařilo: interní chyba" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data too large for advertisement packet" +msgstr "Data jsou příliš velká pro propagovaný paket" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Already advertising." +msgstr "Již propagujeme." + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Extended advertisements with scan response not supported." +msgstr "" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data not supported with directed advertising" +msgstr "Data nejsou podporována s cíleným oznamováním" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#, c-format +msgid "Timeout is too long: Maximum timeout length is %d seconds" +msgstr "Časový limit je příliš dlouhý: maximální limit je %d vteřin" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +msgid "MITM security not supported" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" -#: extmod/vfs_posix_file.c py/objstringio.c -msgid "I/O operation on closed file" -msgstr "I/O operace nad zavřeným souborem" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" -#: ports/stm/common-hal/busio/I2C.c -msgid "I2C init error" -msgstr "Chyba inicializace I2C" +#: ports/espressif/common-hal/_bleio/Characteristic.c +msgid "Too many descriptors" +msgstr "" -#: ports/raspberrypi/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "I2C peripheral in use" -msgstr "Periférie I2C je používána" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "Žádné CCCD pro tuto charakteristiku" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "In-buffer elements must be <= 4 bytes long" -msgstr "Elementy v bufferu musí být <= 4 bajty" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "Nelze nastavit CCCD na místní charakteristiku" -#: shared-bindings/_pew/PewPew.c -msgid "Incorrect buffer size" -msgstr "Nesprávná velikost vyrovnávací paměti" +#: ports/espressif/common-hal/_bleio/Connection.c +#: ports/nordic/common-hal/_bleio/Connection.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Init program size invalid" -msgstr "Velikost init programu není správná" +#: ports/espressif/common-hal/_bleio/Descriptor.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin direction conflicts with initial out pin direction" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Writes not supported on Characteristic" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin state conflicts with initial out pin state" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Total data to write is larger than %q" +msgstr "Velikost dat k zápisu je větší než %q" + +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Nimble out of memory" msgstr "" -#: shared-bindings/bitops/__init__.c -#, c-format -msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid BLE parameter" +msgstr "Chybný BLE parametr" + +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#: ports/zephyr-cp/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "Not connected" +msgstr "Nepřipojený" + +#: ports/espressif/common-hal/_bleio/__init__.c +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Already in progress" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -msgid "Input taking too long" -msgstr "Vstup trval příliš dlouho" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error at %s:%d: %d" +msgstr "Neznámá chyba firmwaru na %s:%d: %d" -#: py/moderrno.c -msgid "Input/output error" -msgstr "Chyba vstupu/výstupu" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %d" +msgstr "Neznámá chyba firmwaru: %d" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c @@ -1149,544 +1284,652 @@ msgstr "Nedostatečná autentizace" msgid "Insufficient encryption" msgstr "Nedostatečné šifrování" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient memory pool for the image" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error at %s:%d: %d" +msgstr "Neznámá chyba BLE na %s:%d: %d" + +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error: %d" +msgstr "Neznámá chyba BLE: %d" + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge. Only level." +msgstr "Nelze probudit hranou na pinu. Pouze úrovní." + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot pull on input-only pin." +msgstr "Nelze aktivovat pull rezistor na pinu, který je pouze pro vstup." + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on two low pins from deep sleep." msgstr "" +"Lze nastavit alarm na maximálně dvou pinech ve stavu low při hlubokém spánku." -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient stream input buffer" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" +"Lze nastavit alarm na jednom pinu ve stavu low při hlubokém spánku, ostatní " +"musí být ve stavu high." -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Interface must be started" -msgstr "Rozhraní musí být nastartováno" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on RTC IO from deep sleep." +msgstr "Alarm z IO RTC je možné generovat pouze z hlubokého spánku." -#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c -msgid "Internal audio buffer too small" -msgstr "Interní audio buffer je příliš malý" +#: ports/espressif/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set." +msgstr "Může být nastaven pouze jeden alarm typu alarm.time." -#: ports/stm/common-hal/busio/UART.c -msgid "Internal define error" +#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c +msgid "Only one %q can be set in deep sleep." +msgstr "Pouze jeden %q lze nastavit v hlubokém spánku." + +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q musí být pole typu 'H V" + +#: ports/espressif/common-hal/audiobusio/PDMIn.c +#: shared-bindings/audioi2sin/I2SIn.c +msgid "%q must be 8, 16, 24, or 32" msgstr "" -#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c -msgid "Internal error" -msgstr "Interní chyba" +#: ports/espressif/common-hal/audiobusio/__init__.c +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +msgid "Peripheral in use" +msgstr "Periférie je používána" -#: shared-module/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Internal error #%d" -msgstr "Vnitřní chyba #%d" +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 8 or 16" +msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: ports/atmel-samd/common-hal/countio/Counter.c -#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c -#: ports/atmel-samd/common-hal/max3421e/Max3421E.c -#: ports/atmel-samd/common-hal/ps2io/Ps2.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-bindings/pwmio/PWMOut.c -msgid "Internal resource(s) in use" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Internal watchdog timer expired." -msgstr "Interní watchdog timer expiroval." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Interrupt error." -msgstr "Chyba přerušení." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Interrupted by output function" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" msgstr "" -#: ports/espressif/common-hal/_bleio/Service.c -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/espressif/common-hal/microcontroller/Processor.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c -#: ports/raspberrypi/bindings/picodvi/Framebuffer.c -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q" -msgstr "Špatný %s" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q and %q" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c -#: shared-bindings/microcontroller/Pin.c -msgid "Invalid %q pin" -msgstr "Neplatný pin %q" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" -#: ports/stm/common-hal/analogio/AnalogIn.c -msgid "Invalid ADC Unit value" -msgstr "Neplatná hodnota jednotky ADC" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Invalid BLE parameter" -msgstr "Chybný BLE parametr" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid BSSID" -msgstr "Chybné BSSID" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid MAC address" -msgstr "Chybná MAC adresa" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/nordic/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Všechny I2C periferie jsou používány" -#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c -msgid "Invalid argument" -msgstr "Neplatný argument" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c +msgid "Unable to create lock" +msgstr "Není možné vytvořit zámek" + +#: ports/espressif/common-hal/busio/SPI.c +msgid "SPI configuration failed" +msgstr "Konfigurace SPI selhala" + +#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Všechny SPI periferie jsou používány" + +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/canio/CAN.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "ESP-IDF memory allocation failed" +msgstr "ESP-IDF alokace paměti selhala" + +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Cannot specify RTS or CTS in RS485 mode" +msgstr "Nelze určit RTS nebo CTS v režimu RS485" + +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "RS485 inversion specified when not in RS485 mode" +msgstr "" + +#: ports/espressif/common-hal/canio/CAN.c +msgid "Baudrate not supported by peripheral" +msgstr "Baudrate není podporován periférií" + +#: ports/espressif/common-hal/canio/CAN.c +msgid "All CAN peripherals are in use" +msgstr "Všechny CAN periferie jsou používány" -#: shared-module/displayio/Bitmap.c -msgid "Invalid bits per value" +#: ports/espressif/common-hal/canio/CAN.c +msgid "loopback + silent mode not supported by peripheral" msgstr "" -#: shared-module/os/getenv.c +#: ports/espressif/common-hal/canio/CAN.c #, c-format -msgid "Invalid byte %.*s" -msgstr "Špatný byte %.*s" +msgid "twai_driver_install returned esp-idf error #%d" +msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: ports/espressif/common-hal/canio/CAN.c #, c-format -msgid "Invalid data_pins[%d]" -msgstr "Chybný data_pin[%d]" +msgid "twai_start returned esp-idf error #%d" +msgstr "" -#: shared-module/msgpack/__init__.c -msgid "Invalid format" -msgstr "Špatný formát" +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +msgid "Must provide 5/6/5 RGB pins" +msgstr "Je třeba poskytnout 5/6/5 RGB piny" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" -msgstr "Neplatná velikost bloku" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is duplicate" +msgstr "Firmware je duplicitní" -#: shared-bindings/wifi/Radio.c -msgid "Invalid hex password" -msgstr "Špatné heslo v hex" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "Firmware není validní" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Invalid multicast MAC address" -msgstr "Chybná multicastová MAC adresa" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "Firmware je příliš velký" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid size" -msgstr "Chybná velikost" +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c +msgid "no such attribute" +msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "Invalid socket for TLS" -msgstr "Chybný soket pro TLS" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "neplatné nastavení" #: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid state" -msgstr "Chybný stav" +msgid "Generic Failure" +msgstr "Základní chyba" -#: shared-module/os/getenv.c -msgid "Invalid unicode escape" -msgstr "Neplatná unicode escape sekvence" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Out of memory" +msgstr "Došla paměť" -#: shared-bindings/aesio/aes.c -msgid "Key must be 16, 24, or 32 bytes long" -msgstr "Klíč musí být dlouhý 16, 24 nebo 32 bajtů" +#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c +msgid "Invalid argument" +msgstr "Neplatný argument" -#: shared-module/os/getenv.c -msgid "Key not found" -msgstr "Klíč nenalezen" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Invalid size" +msgstr "Chybná velikost" -#: shared-module/is31fl3741/FrameBuffer.c -msgid "LED mappings must match display size" -msgstr "Mapování LED musí korespondovat s velikostí displeje" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Requested resource not found" +msgstr "Požadovaný zdroj nebyl nalezen" -#: py/compile.c -msgid "LHS of keyword arg must be an id" -msgstr "" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Operation or feature not supported" +msgstr "Operace nebo funkce není podporována" -#: shared-module/displayio/Group.c -msgid "Layer already in a group" -msgstr "Vrstva již v groupě je" +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "Operation timed out" +msgstr "Časový limit operace vypršel" -#: shared-module/displayio/Group.c -msgid "Layer must be a Group or TileGrid subclass" -msgstr "Vrstva musí být Group nebo TileGrid" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Received response was invalid" +msgstr "Přijatá odpověď nebyla validní" -#: shared-bindings/audiocore/RawSample.c -msgid "Length of %q must be an even multiple of channel_count * type_size" -msgstr "" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "CRC or checksum was invalid" +msgstr "CRC nebo kontrolní součet byl neplatný" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Version was invalid" +msgstr "Verze byla neplatná" #: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" msgstr "MAC adresa byla chybná" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/espressif/common-hal/_bleio/Descriptor.c -msgid "MITM security not supported" -msgstr "" +#: ports/espressif/common-hal/espidf/__init__.c +#, c-format +msgid "%s error 0x%x" +msgstr "%s chyba 0x%x" -#: shared-bindings/is31fl3741/IS31FL3741.c -msgid "Mapping must be a tuple" -msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "Program je příliš dlouhý" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/mipidsi/Bus.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/usb_host/Port.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched data size" -msgstr "Nekorespondující velikost dat" +#: ports/raspberrypi/common-hal/usb_host/Port.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c +msgid "%q in use" +msgstr "%q se právě používá" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched swap flag" -msgstr "Nekorespondující swap flag" +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "Lze nastavit pouze jeden %q ." -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] reads pin(s)" -msgstr "Chybí first_in_pin. %q[%u] čte z pinu(ů)" +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "Only one address is allowed" +msgstr "Je povolena pouze jedna adresa" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" -msgstr "Chybí first_in_pin. %q[%u] posunuje z pinu(ů)" +#: ports/espressif/common-hal/max3421e/Max3421E.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Neznámý chybový kód %d" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] waits based on pin" -msgstr "Chybí first_in_pin. %q[%u] čeká na základě pinu" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS only works with built-in WiFi" +msgstr "mDNS pracuje pouze s vestavěnou WiFi" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" -msgstr "Chybí first_out_pin. %q[%u] posunuje do pinu(ů)" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS already initialized" +msgstr "mDNS je již inicializováno" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] writes pin(s)" -msgstr "Chybí first_out_pin. %q[%u] zapisuje do pinu(ů)" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Unable to start mDNS query" +msgstr "Nepodařilo se začít mDNS dotaz" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_set_pin. %q[%u] sets pin(s)" -msgstr "Chybí first_set_pin. %q[%u] nastavuje pin(y)" +#: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nordic/common-hal/memorymap/AddressRange.c +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Adresní rozsah není povolen" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing jmp_pin. %q[%u] jumps on pin" -msgstr "Chybí jmp_pin. %q[%u] skáče na pin" +#: ports/espressif/common-hal/nvm/ByteArray.c +msgid "NVS Error" +msgstr "Chyba NVS" -#: shared-module/storage/__init__.c -msgid "Mount point directory missing" +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d or %d, not %d" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c -msgid "Must be a %q subclass." -msgstr "Musí být podtřída %q." - -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -msgid "Must provide 5/6/5 RGB pins" -msgstr "Je třeba poskytnout 5/6/5 RGB piny" - -#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c -msgid "Must provide MISO or MOSI pin" -msgstr "Musí poskytnout pin MISO nebo MOSI" - -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Must use a multiple of 6 rgb pins, not %d" -msgstr "Je nutné použít několik kolíků 6 rgb, nikoli %d" +#: ports/espressif/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "NLR jump failed. Likely memory corruption." -msgstr "NLR skok selhal. Pravděpodobně poškozením paměti." +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" -#: ports/espressif/common-hal/nvm/ByteArray.c -msgid "NVS Error" -msgstr "Chyba NVS" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-bindings/pwmio/PWMOut.c +#: supervisor/shared/settings.c +msgid "Internal error" +msgstr "Interní chyba" -#: shared-bindings/socketpool/SocketPool.c -msgid "Name or service not known" -msgstr "Jméno nebo služba není známa" +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "New bitmap must be same size as old bitmap" -msgstr "Nová bitmapa musí mít stejnou velikost jako původní bitmapa" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -msgid "Nimble out of memory" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c -#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c -#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c -#: shared-bindings/paralleldisplaybus/ParallelBus.c -#: shared-module/bitbangio/SPI.c -msgid "No %q pin" -msgstr "Žádný %q pin" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "No CCCD for this Characteristic" -msgstr "Žádné CCCD pro tuto charakteristiku" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "No DAC on chip" -msgstr "Žádný DAC na čipu" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA channel found" -msgstr "Nebyl nalezen žádný kanál DMA" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA pacing timer found" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" msgstr "" -#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "No I2C device at address: 0x%x" -msgstr "Žádné I2C zařízení na adrese: 0x%x" - -#: supervisor/shared/web_workflow/web_workflow.c -msgid "No IP" -msgstr "Není IP" +msgid "SDIO Init Error 0x%02x" +msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/__init__.c -#: ports/cxd56/common-hal/microcontroller/__init__.c -#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c -msgid "No bootloader present" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Unsupported socket type" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No configuration set" -msgstr "Konfigurace není nastavena" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Out of sockets" +msgstr "Došly sockety" -#: shared-bindings/_bleio/PacketBuffer.c -msgid "No connection: length cannot be determined" -msgstr "Žádné připojení: nelze určit délku" +#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio" +msgstr "SocketPool je možné použít pouze s wifi.radio" -#: shared-bindings/board/__init__.c -msgid "No default %q bus" -msgstr "Žádná výchozí sběrnice %q" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +msgid "%q must be <= %u" +msgstr "%q musí být <= %u" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -msgid "No free GCLKs" -msgstr "Žádné volné GCLK" +#: ports/espressif/common-hal/wifi/Monitor.c +msgid "monitor init failed" +msgstr "" -#: shared-bindings/os/__init__.c -msgid "No hardware random available" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Interface must be started" +msgstr "Rozhraní musí být nastartováno" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Invalid multicast MAC address" +msgstr "Chybná multicastová MAC adresa" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Already scanning for wifi networks" +msgstr "Již skenuje wifi sítě" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in in program" -msgstr "V programu není vstup" +#: ports/espressif/common-hal/wifi/ScannedNetworks.c +msgid "Failed to allocate wifi scan memory" +msgstr "Nepodařilo se alokovat paměť pro wifi scan" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in or out in program" -msgstr "V programu není vstup nebo výstup" +#: ports/espressif/common-hal/wifi/__init__.c +msgid "Failed to allocate Wifi memory" +msgstr "Chyba alokace paměti WiFi" -#: py/objint.c shared-bindings/time/__init__.c -msgid "No long integer support" -msgstr "Není podpora long integer" +#: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +msgid "Only IPv4 addresses supported" +msgstr "Pouze IPv4 adresy podporovány" -#: shared-bindings/wifi/Radio.c -msgid "No network with that ssid" -msgstr "Žádná síť s takovým SSID" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/busio/SPI.c +msgid "Must provide MISO or MOSI pin" +msgstr "Musí poskytnout pin MISO nebo MOSI" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No out in program" -msgstr "V programu není výstup" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c +#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c +#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c +msgid "Hardware in use, try alternative pins" +msgstr "Hardware je používán, zkuste alternativní piny" -#: ports/atmel-samd/common-hal/busio/I2C.c -#: ports/espressif/common-hal/busio/I2C.c -#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/busio/I2C.c -msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "SDA nebo SCL zřejmě nemá pull up; zkontroluj zapojení" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" -#: shared-module/touchio/TouchIn.c -msgid "No pulldown on pin; 1Mohm recommended" -msgstr "Žádný pulldown na pinu; doporučeno 1Mohm" +#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c +msgid "" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +msgstr "" +"Frekvence musí být 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 nebo 1008 " +"Mhz" -#: py/moderrno.c -msgid "No space left on device" -msgstr "Na zařízení nezůstal žádný prostor" +#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "Při spuštění jsi stiskl tlačítko doleva." -#: py/moderrno.c -msgid "No such device" -msgstr "Žádné takové zařízení" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "timeout must be < 655.35 secs" +msgstr "timeout musí být < 655.35 s" -#: py/moderrno.c -msgid "No such file/directory" -msgstr "Žádný takový soubor / adresář" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "non-zero timeout must be > 0.01" +msgstr "nenulový timeout musí být > 0.01" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "No timer available" -msgstr "Není k dispozici žádný časovač" +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: timeout" +msgstr "Nepodařilo se připojit: časový limit" -#: shared-module/usb/core/Device.c -msgid "No usb host port initialized" -msgstr "Žádný USB host port není inicializován" +#: ports/nordic/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "" #: ports/nordic/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" msgstr "Nordic system firmware - nedostatek paměti" -#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string" -msgstr "Nevalidní IP string" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %04x" +msgstr "Neznámá chyba firmwaru: %04x" -#: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "Not connected" -msgstr "Nepřipojený" +#, c-format +msgid "Unknown gatt error: 0x%04x" +msgstr "" -#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c -#: shared-bindings/audiopwmio/PWMAudioOut.c -msgid "Not playing" -msgstr "Nehraje" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +msgid "" +"Unspecified issue. The pairing request on the other device may have been " +"declined or ignored." +msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Not supported JPEG standard" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#, c-format +msgid "Unknown security error: 0x%04x" +msgstr "Neznámá bezpečnostní chyba: 0x%04x" + +#: ports/nordic/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge, only level" +msgstr "Nelze probudit hranou na pinu, pouze úrovní" + +#: ports/nordic/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +msgstr "Zařízení je používáno" + +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" msgstr "" -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" + +#: ports/nordic/common-hal/busio/UART.c #, c-format -msgid "Number of data_pins must be %d or %d, not %d" +msgid "error = 0x%08lX" msgstr "" -#: shared-bindings/util.c -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." +#: ports/nordic/common-hal/busio/UART.c +msgid "Odd parity is not supported" msgstr "" -"Objekt byl deinicializován a nelze jej dále používat. Vytvořte nový objekt." -#: ports/nordic/common-hal/busio/UART.c -msgid "Odd parity is not supported" +#: ports/nordic/common-hal/countio/Counter.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +msgid "All channels in use" +msgstr "Všechny kanály jsou používány" + +#: ports/nordic/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "Nelze získat teplotu (°C)" + +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" +msgstr "WatchDogTimer nelze deaktivovat v režimu RESET" + +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "timeout duration exceeded the maximum supported value" +msgstr "timeout překročil maximální podporovanou hodnotu" + +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "%q cannot be changed once mode is set to %q" +msgstr "" + +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Nepodařilo se získat mutex, err 0x%04x" + +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Nepodařilo se uvolnit mutex, err 0x%04x" + +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "Konverze audia není implementována" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c +#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c +#: shared-module/synthio/Synthesizer.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q musí být typu %q nebo %q, ne %q" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Program size invalid" +msgstr "Velikost programu je nesprávná" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Init program size invalid" +msgstr "Velikost init programu není správná" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Buffer elements must be 4 bytes long or less" +msgstr "Prvky bufferu musí být 4 bajty dlouhé nebo méně" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched data size" +msgstr "Nekorespondující velikost dat" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Out-buffer elements must be <= 4 bytes long" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Off" -msgstr "Vypnuto" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "In-buffer elements must be <= 4 bytes long" +msgstr "Elementy v bufferu musí být <= 4 bajty" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Ok" -msgstr "Ok" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/I2C.c +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/I2C.c +#: shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "Funkce vyžaduje zámek" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -#, c-format -msgid "Only 8 or 16 bit mono with %dx oversampling supported." +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -msgid "Only IPv4 addresses supported" -msgstr "Pouze IPv4 adresy podporovány" - -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Only IPv4 sockets supported" -msgstr "Pouze IPv4 sokety podporovány" +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c +#: ports/stm/common-hal/alarm/touch/TouchAlarm.c +msgid "Touch alarms not available" +msgstr "Touch alarmy nejsou dostupné" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only Windows format, uncompressed BMP supported: given header size is %d" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Only connectable advertisements can be directed" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "Bit clock and word select must be sequential GPIO pins" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Only edge detection is available on this hardware" -msgstr "Na tomto hardware je dostupná pouze detekce hrany" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Too many channels in sample." +msgstr "" -#: shared-bindings/ipaddress/__init__.c -msgid "Only int or string supported for ip" -msgstr "Pro IP je podporován pouze int nebo string" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Audio source error" +msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 16, 24, or 32" msgstr "" -"Podporovány jsou pouze černobílé, indexované 4 bpp nebo 8 bpp a 16 bpp nebo " -"vyšší BMP: bitmapa má %d bpp" -#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one %q can be set in deep sleep." -msgstr "Pouze jeden %q lze nastavit v hlubokém spánku." +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" -#: ports/espressif/common-hal/espulp/ULPAlarm.c -msgid "Only one %q can be set." -msgstr "Lze nastavit pouze jeden %q ." +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "" -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "Only one address is allowed" -msgstr "Je povolena pouze jedna adresa" - -#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c -#: ports/nordic/common-hal/alarm/time/TimeAlarm.c -#: ports/stm/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set" -msgstr "Lze nastavit pouze jeden alarm typu alarm.time" - -#: ports/espressif/common-hal/alarm/time/TimeAlarm.c -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set." -msgstr "Může být nastaven pouze jeden alarm typu alarm.time." - -#: shared-module/displayio/ColorConverter.c -msgid "Only one color can be transparent at a time" -msgstr "Pouze jedna barva může být nastavena jako transparentní" - -#: py/moderrno.c -msgid "Operation not permitted" -msgstr "Operace není povolena" - -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation or feature not supported" -msgstr "Operace nebo funkce není podporována" - -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation timed out" -msgstr "Časový limit operace vypršel" - -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Out of MDNS service slots" -msgstr "Došly mDNS sloty" +msgid "I2C peripheral in use" +msgstr "Periférie I2C je používána" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Out of memory" -msgstr "Došla paměť" +#: ports/raspberrypi/common-hal/busio/SPI.c +msgid "SPI peripheral in use" +msgstr "SPI periferie je používána" -#: ports/espressif/common-hal/socketpool/Socket.c -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Out of sockets" -msgstr "Došly sockety" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "UART periférie je používána" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Out-buffer elements must be <= 4 bytes long" -msgstr "" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "Pin must be on PWM Channel B" +msgstr "Pin musí být na PWM kanálu B" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "PWM restart" -msgstr "Restart PWM" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "RISE_AND_FALL not available on this chip" +msgstr "RISE_AND_FALL není na tomto čipu k dispozici" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice already in use" @@ -1696,88 +1939,103 @@ msgstr "PWM kanál je již využíván" msgid "PWM slice channel A already in use" msgstr "PWM kanál A je již využíván" -#: shared-module/jpegio/JpegDecoder.c -msgid "Parameter error" -msgstr "" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All state machines in use" +msgstr "Všechny stavové automaty jsou používány" -#: ports/espressif/common-hal/audiobusio/__init__.c -msgid "Peripheral in use" -msgstr "Periférie je používána" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +msgid "timeout waiting for flux" +msgstr "" -#: py/moderrno.c -msgid "Permission denied" -msgstr "Přístup odepřen" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: shared-module/floppyio/__init__.c +msgid "timeout waiting for index pulse" +msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Pin cannot wake from Deep Sleep" -msgstr "Z Deep Sleep nelze probudit pinem" +#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +msgid "Pins must be sequential" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Pin count too large" -msgstr "Počet pinů je příliš velký" +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +msgid "Invalid %q and %q" +msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -#: ports/stm/common-hal/pulseio/PulseIn.c -msgid "Pin interrupt already in use" -msgstr "Přerušení od pinu je již používáno" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Failed to add service TXT record" +msgstr "" -#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -msgid "Pin is input only" -msgstr "Pin je pouze vstupní" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "Došly mDNS sloty" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "Pin must be on PWM Channel B" -msgstr "Pin musí být na PWM kanálu B" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to access unaligned IO register" +msgstr "Nelze přistupovat k nezarovnanému IO registru" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"Pinout uses %d bytes per element, which consumes more than the ideal %d " -"bytes. If this cannot be avoided, pass allow_inefficient=True to the " -"constructor" -msgstr "" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to write to read-only memory" +msgstr "Není možné zapisovat do paměti jen pro čtení" -#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c -msgid "Pins must be sequential" -msgstr "" +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +msgid "All timers for this pin are in use" +msgstr "Všechny časovače pro tento pin jsou používány" #: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c msgid "Pins must be sequential GPIO pins" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Pins must share PWM slice" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Pin count too large" +msgstr "Počet pinů je příliš velký" -#: shared-module/usb/core/Device.c -msgid "Pipe error" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing jmp_pin. %q[%u] jumps on pin" +msgstr "Chybí jmp_pin. %q[%u] skáče na pin" -#: py/builtinhelp.c -msgid "Plus any modules on the filesystem\n" -msgstr "Plus všechny moduly na filesystému\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] uses extra pin" +msgstr "%q[%u] používá extra pin" -#: shared-module/vectorio/Polygon.c -msgid "Polygon needs at least 3 points" -msgstr "Polygon potřebuje nejméně 3 body" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] waits based on pin" +msgstr "Chybí first_in_pin. %q[%u] čeká na základě pinu" -#: supervisor/shared/safe_mode.c -msgid "Power dipped. Make sure you are providing enough power." -msgstr "Pokles napájení. Zkontroluj, zda je k dispozici dostatečné napájení." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] waits on input outside of count" +msgstr "%q[%u] čeká na vstup mimo rozsah" -#: shared-bindings/_bleio/Adapter.c -msgid "Prefix buffer must be on the heap" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +msgstr "Chybí first_in_pin. %q[%u] posunuje z pinu(ů)" -#: main.c -msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" -msgstr "" -"Zmáčkněte jakoukoli klávesu pro spuštění REPLu. Použijte CTRL-D pro opětovné " -"načtení.\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts in more bits than pin count" +msgstr "%q[%u] posouvá dovnitř o více bitů než je počet pinů" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +msgstr "Chybí first_out_pin. %q[%u] posunuje do pinu(ů)" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts out more bits than pin count" +msgstr "%q[%u] posouvá ven o více bitů než je počet pinů" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_set_pin. %q[%u] sets pin(s)" +msgstr "Chybí first_set_pin. %q[%u] nastavuje pin(y)" -#: main.c -msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" -msgstr "Předstírám hluboký spánek do alarmu, CTRL-C nebo zápisu souboru.\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] writes pin(s)" +msgstr "Chybí first_out_pin. %q[%u] zapisuje do pinu(ů)" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] reads pin(s)" +msgstr "Chybí first_in_pin. %q[%u] čte z pinu(ů)" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Program does IN without loading ISR" @@ -1787,2337 +2045,2419 @@ msgstr "Program provedl IN bez načtení ISR" msgid "Program does OUT without loading OSR" msgstr "Program provedl OUT bez načtení OSR" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Program size invalid" -msgstr "Velikost programu je nesprávná" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin state conflicts with initial out pin state" +msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -msgid "Program too long" -msgstr "Program je příliš dlouhý" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin direction conflicts with initial out pin direction" +msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Pull not used when direction is output." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "pull masks conflict with direction masks" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "RISE_AND_FALL not available on this chip" -msgstr "RISE_AND_FALL není na tomto čipu k dispozici" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No out in program" +msgstr "V programu není výstup" -#: shared-module/displayio/OnDiskBitmap.c -msgid "RLE-compressed BMP not supported" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in in program" +msgstr "V programu není vstup" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG DeInit Error" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in or out in program" +msgstr "V programu není vstup nebo výstup" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG Init Error" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched swap flag" +msgstr "Nekorespondující swap flag" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" -msgstr "RS485" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d, not %d" +msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "RS485 inversion specified when not in RS485 mode" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +msgid "Data pins must be consecutive" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c -msgid "RTC is not supported on this board" -msgstr "RTC není na této desce podporován" +#: ports/raspberrypi/common-hal/socketpool/Socket.c +msgid "Only IPv4 sockets supported" +msgstr "Pouze IPv4 sokety podporovány" -#: ports/stm/common-hal/os/__init__.c -msgid "Random number generation error" -msgstr "Chyba generování náhodných čísel" +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All dma channels in use" +msgstr "Všechny DMA kanály jsou používány" -#: shared-bindings/_bleio/__init__.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c -#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c -msgid "Read-only" -msgstr "Pouze pro čtení" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "wifi.Monitor není dostupný" -#: extmod/vfs_fat.c py/moderrno.c -msgid "Read-only filesystem" -msgstr "Filesystém pouze pro čtení" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q je pouze u této desky pouze pro čtení" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Received response was invalid" -msgstr "Přijatá odpověď nebyla validní" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "AP could not be started" +msgstr "AP nemohl být spuštěn" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Reconnecting" -msgstr "Opětovné připojování" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Only edge detection is available on this hardware" +msgstr "Na tomto hardware je dostupná pouze detekce hrany" -#: shared-bindings/epaperdisplay/EPaperDisplay.c -msgid "Refresh too soon" -msgstr "Pokus o obnovení příliš brzo" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +#: ports/stm/common-hal/pulseio/PulseIn.c +msgid "Pin interrupt already in use" +msgstr "Přerušení od pinu je již používáno" -#: shared-bindings/canio/RemoteTransmissionRequest.c -msgid "RemoteTransmissionRequests limited to 8 bytes" -msgstr "RemoteTransmissionRequests je limitován na 8 bajtů" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Pin cannot wake from Deep Sleep" +msgstr "Z Deep Sleep nelze probudit pinem" -#: shared-bindings/aesio/aes.c -msgid "Requested AES mode is unsupported" -msgstr "Požadovaný režim AES je nepodporovaný" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Deep sleep pins must use a rising edge with pulldown" +msgstr "" +"Piny pro hluboký spánek musí používat náběžnou hranu s pulldown rezistorem" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Requested resource not found" -msgstr "Požadovaný zdroj nebyl nalezen" +#: ports/stm/common-hal/analogio/AnalogIn.c +msgid "Invalid ADC Unit value" +msgstr "Neplatná hodnota jednotky ADC" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "Right channel unsupported" -msgstr "Pravý kanál nepodporován" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Device Init Error" +msgstr "Chyba inicializace zařízení DAC" -#: shared-module/jpegio/JpegDecoder.c -msgid "Right format but not supported" -msgstr "" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Channel Init Error" +msgstr "Chyba inicializace kanálu DAC" -#: main.c -msgid "Running in safe mode! Not running saved code.\n" -msgstr "Běh v nouzovém režimu! Uložený kód není zpracováván.\n" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "je podporováno pouze mono" -#: shared-module/sdcardio/SDCard.c -msgid "SD card CSD format not supported" -msgstr "CSD formát SD karty není podporován" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "je podporován pouze oversampling 64" -#: ports/cxd56/common-hal/sdioio/SDCard.c -msgid "SDCard init" -msgstr "Inicializace SD karty" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Another PWMAudioOut is already active" +msgstr "Jiný PWMAudioOut je již aktivní" -#: ports/stm/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c #, c-format -msgid "SDIO GetCardInfo Error %d" -msgstr "SDIO GetCardInfo chyba %d" +msgid "Buffer length %d too big. It must be less than %d" +msgstr "Délka vyrovnávací paměti %d je příliš velká. Musí být menší než %d" -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO Init Error %x" -msgstr "" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Failed to buffer the sample" +msgstr "Nepodařilo se nabufferovat sample" -#: ports/espressif/common-hal/busio/SPI.c -msgid "SPI configuration failed" -msgstr "Konfigurace SPI selhala" +#: ports/stm/common-hal/busio/I2C.c +msgid "I2C init error" +msgstr "Chyba inicializace I2C" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" msgstr "Chyba inicializace SPI" -#: ports/raspberrypi/common-hal/busio/SPI.c -msgid "SPI peripheral in use" -msgstr "SPI periferie je používána" - #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" msgstr "Opětovná inicializace SPI" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "Scale dimensions must divide by 3" +#: ports/stm/common-hal/busio/UART.c +msgid "Internal define error" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Scan already in progress. Stop with stop_scan." -msgstr "Scan již probíhá. Lze zastavit pomocí stop_scan." +#: ports/stm/common-hal/busio/UART.c +msgid "Could not start interrupt, RX busy" +msgstr "Nelze začít přerušení, RX je zaneprázdněn" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -msgid "Serializer in use" -msgstr "" +#: ports/stm/common-hal/busio/UART.c +msgid "UART write" +msgstr "Zápis na UART" -#: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname" -msgstr "" +#: ports/stm/common-hal/busio/UART.c +msgid "UART de-init" +msgstr "De-inicializace UART" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Size not supported" -msgstr "Velikost není podporována" +#: ports/stm/common-hal/busio/UART.c +msgid "UART re-init" +msgstr "Opětovná inicializace UART" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Slice and value different lengths." -msgstr "" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Temperature read timed out" +msgstr "Čas pro čtení teploty vypršel" -#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/TileGrid.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Slices not supported" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Voltage read timed out" +msgstr "Časový limit čtení napětí vypršel" + +#: ports/stm/common-hal/os/__init__.c +msgid "RNG Init Error" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c -#: ports/raspberrypi/common-hal/socketpool/SocketPool.c -msgid "SocketPool can only be used with wifi.radio" -msgstr "SocketPool je možné použít pouze s wifi.radio" +#: ports/stm/common-hal/os/__init__.c +msgid "Random number generation error" +msgstr "Chyba generování náhodných čísel" -#: shared-bindings/aesio/aes.c -msgid "Source and destination buffers must be the same length" -msgstr "Zdrojové a cílové buffery musí být stejné délky" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG DeInit Error" +msgstr "" -#: shared-bindings/paralleldisplaybus/ParallelBus.c -msgid "Specify exactly one of data0 or data_pins" -msgstr "Specifikuj přesně jeden z data0 nebo data_pins" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "timer re-init" +msgstr "opětovný init timeru" -#: supervisor/shared/safe_mode.c -msgid "Stack overflow. Increase stack size." -msgstr "" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "channel re-init" +msgstr "opětovná inicializace kanálu" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Supply one of monotonic_time or epoch_time" -msgstr "Musíš definovat monotonic_time nebo epoch_time" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "PWM restart" +msgstr "Restart PWM" -#: shared-bindings/gnss/GNSS.c -msgid "System entry must be gnss.SatelliteSystem" -msgstr "Parametr \"system\" musí být gnss.SatelliteSystem" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Temperature read timed out" -msgstr "Čas pro čtení teploty vypršel" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "SDIO GetCardInfo Error %d" +msgstr "SDIO GetCardInfo chyba %d" -#: supervisor/shared/safe_mode.c -msgid "The `microcontroller` module was used to boot into safe mode." -msgstr "Modul `microcontroller` byl použit pro spuštění do nouzového režimu." +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid ".show(x) removed. Use .root_group = x" +msgstr "" -#: py/obj.c -msgid "The above exception was the direct cause of the following exception:" -msgstr "Výše uvedená výjimka byla přímá příčina následující výjimky:" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Brightness not adjustable" +msgstr "Jas není nastavitelný" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c py/argcheck.c +#: shared-bindings/busdisplay/BusDisplay.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c #: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" -msgstr "Počet prvků rgb_pin musí být 6, 12, 18, 24, nebo 30" +msgid "%q must be %d-%d" +msgstr "%q musí být %d-%d" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Group already used" +msgstr "Skupina již byla použita" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Invalid advertising data" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" +#: ports/zephyr-cp/common-hal/audiobusio/I2SOut.c +#: ports/zephyr-cp/common-hal/busio/I2C.c +#: ports/zephyr-cp/common-hal/busio/SPI.c +#: ports/zephyr-cp/common-hal/busio/UART.c +msgid "Use device tree to define %q devices" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Third-party firmware fatal error." -msgstr "Fatální chyby firmware třetí strany." - -#: shared-module/imagecapture/ParallelImageCapture.c -msgid "This microcontroller does not support continuous capture." -msgstr "Tento mikrokontrolér nepodporuje kontinuální snímání." +#: ports/zephyr-cp/common-hal/usb_hid/Device.c shared-module/usb_hid/Device.c +msgid "USB error" +msgstr "Chyba USB" -#: shared-module/paralleldisplaybus/ParallelBus.c -msgid "" -"This microcontroller only supports data0=, not data_pins=, because it " -"requires contiguous pins." +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile height must exactly divide bitmap height" -msgstr "" +#: ports/zephyr-cp/common-hal/zephyr_display/Display.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Below minimum frame rate" +msgstr "Pod minimální obnovovací frekvencí" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c -msgid "Tile index out of bounds" +#: py/argcheck.c +msgid "function doesn't take keyword arguments" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile width must exactly divide bitmap width" +#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c +#: shared-bindings/time/__init__.c +#, c-format +msgid "function takes %d positional arguments but %d were given" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Time is in the past." -msgstr "Čas je v minulosti." +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "funkci chybí %d povinné poziční argumenty" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c +#: py/argcheck.c #, c-format -msgid "Timeout is too long: Maximum timeout length is %d seconds" -msgstr "Časový limit je příliš dlouhý: maximální limit je %d vteřin" +msgid "function expected at most %d arguments, got %d" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample" -msgstr "V samplu je příliš mnoho kanálů" +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "Je vyžadován argument '%q'" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample." +#: py/argcheck.c +msgid "extra positional arguments given" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -msgid "Too many descriptors" +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c +msgid "unexpected keyword argument '%q'" msgstr "" -#: shared-module/displayio/__init__.c -msgid "Too many display busses; forgot displayio.release_displays() ?" +#: py/argcheck.c +msgid "extra keyword arguments given" msgstr "" -"Příliš mnoho sběrnic displaye; nezapomněl si na displayio.release_displays()?" - -#: shared-module/displayio/__init__.c -msgid "Too many displays" -msgstr "Příliš mnoho displejů" - -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than %q" -msgstr "Velikost dat k zápisu je větší než %q" - -#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c -#: ports/stm/common-hal/alarm/touch/TouchAlarm.c -msgid "Touch alarms not available" -msgstr "Touch alarmy nejsou dostupné" -#: py/obj.c -msgid "Traceback (most recent call last):\n" +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c +msgid "argument num/types mismatch" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART de-init" -msgstr "De-inicializace UART" +#: py/argcheck.c +msgid "keyword argument(s) not implemented - use normal args instead" +msgstr "" -#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c -#: ports/stm/common-hal/busio/UART.c -msgid "UART init" -msgstr "Inicializace UART" +#: py/argcheck.c +msgid "%q must be %d" +msgstr "%q musí být %d" -#: ports/raspberrypi/common-hal/busio/UART.c -msgid "UART peripheral in use" -msgstr "UART periférie je používána" +#: py/argcheck.c +msgid "%q must be >= %d" +msgstr "%q musí být >= %d" -#: ports/stm/common-hal/busio/UART.c -msgid "UART re-init" -msgstr "Opětovná inicializace UART" +#: py/argcheck.c shared-bindings/gifio/GifWriter.c +#: shared-module/gifio/OnDiskGif.c +msgid "%q must be <= %d" +msgstr "%q musí být <= %d" -#: ports/stm/common-hal/busio/UART.c -msgid "UART write" -msgstr "Zápis na UART" +#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c +#: shared-module/synthio/__init__.c +msgid "%q must be of type %q, not %q" +msgstr "%q musí být typu %q, ne %q" -#: main.c -msgid "UID:" -msgstr "UID:" +#: py/argcheck.c +msgid "%q length must be %d-%d" +msgstr "%q délka musí být %d-%d" -#: shared-module/usb_hid/Device.c -msgid "USB busy" -msgstr "USB zaneprázdněno" +#: py/argcheck.c +msgid "%q length must be >= %d" +msgstr "Délka %q musí být >= %d" -#: supervisor/shared/safe_mode.c -msgid "USB devices need more endpoints than are available." -msgstr "USB zařízení potřebují více endpointů než je k dispozici." +#: py/argcheck.c +msgid "%q length must be <= %d" +msgstr "Délka %q musí být <= %d" -#: supervisor/shared/safe_mode.c -msgid "USB devices specify too many interface names." -msgstr "USB zařízení používají příliš mnoho názvů rozhraní." +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" +msgstr "Délka %q musí být %d" -#: shared-module/usb_hid/Device.c -msgid "USB error" -msgstr "Chyba USB" +#: py/argcheck.c shared-module/audiofilters/Filter.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q v %q musí být typu %q, ne %q" -#: shared-bindings/_bleio/UUID.c -msgid "UUID integer value must be 0-0xffff" -msgstr "UUID integer musí být 0-0xffff" +#: py/asmthumb.c +msgid "too many locals for native method" +msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" -msgstr "UUID řetězec neodpovídá 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +#: py/asmxtensa.c +msgid "ERROR: xtensa %q out of range" +msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID value is not str, int or byte buffer" -msgstr "Hodnota UUID není str, int ani byte buffer" +#: py/asmxtensa.c +msgid "ERROR: %q %q not word-aligned" +msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to access unaligned IO register" -msgstr "Nelze přistupovat k nezarovnanému IO registru" +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() vyžaduje %d pozičních argumentů, ale pouze %d jich bylo zadáno" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Unable to allocate buffers for signed conversion" +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Unable to allocate to the heap." +#: py/bc.c +msgid "unexpected keyword argument" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "Unable to create lock" -msgstr "Není možné vytvořit zámek" - -#: shared-module/i2cdisplaybus/I2CDisplayBus.c -#: shared-module/is31fl3741/IS31FL3741.c +#: py/bc.c #, c-format -msgid "Unable to find I2C Display at %x" -msgstr "I2C display nenalezen na %x" +msgid "function missing required positional argument #%d" +msgstr "funkci chybí požadovaný argument na pozici #%d" -#: py/parse.c -msgid "Unable to init parser" -msgstr "" +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "funkci chybí argument specifikovaný klíčovým slovem" -#: shared-module/displayio/OnDiskBitmap.c -msgid "Unable to read color palette data" -msgstr "Nelze číst data palety barev" +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "funkci chybí argument pouze pro klíčové slovo" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Unable to start mDNS query" -msgstr "Nepodařilo se začít mDNS dotaz" +#: py/binary.c py/objarray.c +msgid "bad typecode" +msgstr "" -#: shared-bindings/nvm/ByteArray.c -msgid "Unable to write to nvm." -msgstr "Není možné zapisovat do nvm." +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "" + +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "Plus všechny moduly na filesystému\n" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to write to read-only memory" -msgstr "Není možné zapisovat do paměti jen pro čtení" +#: py/builtinhelp.c +msgid "object " +msgstr "objekt " -#: shared-bindings/alarm/SleepMemory.c -msgid "Unable to write to sleep_memory." -msgstr "Nelze zapsat do sleep_memory." +#: py/builtinhelp.c +msgid " is of type %q\n" +msgstr " je typu %q\n" -#: ports/nordic/common-hal/_bleio/UUID.c -msgid "Unexpected nrfx uuid type" +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Visit circuitpython.org for more information.\n" +"\n" +"To list built-in modules type `help(\"modules\")`.\n" msgstr "" +"Vítejte v Adafruit CircuitPython %s!\n" +"\n" +"Pro více informací navštivte circuitpython.org.\n" +"\n" +"Seznam vestavěných modulů můžete vypsat pomocí `help(\"modules\")`.\n" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error at %s:%d: %d" -msgstr "Neznámá chyba BLE na %s:%d: %d" +#: py/builtinimport.c +msgid "script compilation not supported" +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error: %d" -msgstr "Neznámá chyba BLE: %d" +#: py/builtinimport.c +msgid "can't perform relative import" +msgstr "nelze provést relativní import" -#: ports/espressif/common-hal/max3421e/Max3421E.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unknown error code %d" -msgstr "Neznámý chybový kód %d" +#: py/builtinimport.c +msgid "module not found" +msgstr "" -#: shared-bindings/wifi/Radio.c -#, c-format -msgid "Unknown failure %d" -msgstr "Neznámé selhání %d" +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown gatt error: 0x%04x" +#: py/builtinimport.c +msgid "relative import" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: supervisor/shared/safe_mode.c -msgid "Unknown reason." -msgstr "Neznámý důvod." +#: py/compile.c +msgid "can't assign to expression" +msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown security error: 0x%04x" -msgstr "Neznámá bezpečnostní chyba: 0x%04x" +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error at %s:%d: %d" -msgstr "Neznámá chyba firmwaru na %s:%d: %d" +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %04x" -msgstr "Neznámá chyba firmwaru: %04x" +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %d" -msgstr "Neznámá chyba firmwaru: %d" +#: py/compile.c +msgid "invalid arch" +msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -#: shared-module/_pixelmap/PixelMap.c -#, c-format -msgid "Unmatched number of items on RHS (expected %d, got %d)." +#: py/compile.c +msgid "can't delete expression" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "" -"Unspecified issue. Can be that the pairing prompt on the other device was " -"declined or ignored." +#: py/compile.c +msgid "'break'/'continue' outside loop" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Unsupported colorspace" -msgstr "Nepodporovaný barevný prostor" +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' je volán mimo funkci" -#: shared-module/displayio/bus_core.c -msgid "Unsupported display bus type" -msgstr "Nepodporovaná sběrnice dispalye" +#: py/compile.c +msgid "import * not at module level" +msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Nepodporovaný formát" +#: py/compile.c +msgid "identifier redefined as global" +msgstr "" -#: shared-bindings/hashlib/__init__.c -msgid "Unsupported hash algorithm" -msgstr "Nepodporovaný hash algoritmus" +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -msgid "Unsupported socket type" +#: py/compile.c +msgid "identifier redefined as nonlocal" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Update failed" +#: py/compile.c +msgid "can't declare nonlocal in outer code" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length != required fixed length" +#: py/compile.c +msgid "default 'except' must be last" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length > max_length" +#: py/compile.c +msgid "async for/with outside async function" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Version was invalid" -msgstr "Verze byla neplatná" +#: py/compile.c +msgid "*x must be assignment target" +msgstr "∗x musí být cíl přiřazení" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Voltage read timed out" -msgstr "Časový limit čtení napětí vypršel" +#: py/compile.c +msgid "super() can't find self" +msgstr "" -#: main.c -msgid "WARNING: Your code filename has two extensions\n" -msgstr "UPOZORNĚNÍ: Název souboru vašeho kódu má dvě koncovky\n" +#: py/compile.c +msgid "* arg after **" +msgstr "* arg po **" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" -msgstr "WatchDogTimer nelze deaktivovat v režimu RESET" +#: py/compile.c +msgid "too many args" +msgstr "příliš mnoho argumentů" -#: py/builtinhelp.c -#, c-format -msgid "" -"Welcome to Adafruit CircuitPython %s!\n" -"\n" -"Visit circuitpython.org for more information.\n" -"\n" -"To list built-in modules type `help(\"modules\")`.\n" +#: py/compile.c +msgid "LHS of keyword arg must be an id" msgstr "" -"Vítejte v Adafruit CircuitPython %s!\n" -"\n" -"Pro více informací navštivte circuitpython.org.\n" -"\n" -"Seznam vestavěných modulů můžete vypsat pomocí `help(\"modules\")`.\n" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "Wi-Fi: " -msgstr "Wi-Fi: " +#: py/compile.c +msgid "positional arg after **" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "Wifi není povoleno" +#: py/compile.c +msgid "positional arg after keyword arg" +msgstr "" -#: main.c -msgid "Woken up by alarm.\n" -msgstr "Probuzen alarmem.\n" +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Writes not supported on Characteristic" +#: py/compile.c +msgid "expecting key:value for dict" msgstr "" -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "You pressed both buttons at start up." -msgstr "Při spuštění jsi stiskl obě tlačítka." +#: py/compile.c +msgid "expecting just a value for set" +msgstr "" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h -msgid "You pressed button A at start up." -msgstr "Při spuštění jsi stiskl tlačítko A." +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' je volán mimo funkci" -#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h -msgid "You pressed button DOWN at start up." -msgstr "Při spuštění jsi stiskl tlačítko DOWN." +#: py/compile.c +msgid "'yield from' inside async function" +msgstr "'yield from' volán uvnitř funkce async" -#: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up" -msgstr "Při spuštění jsi stiskl tlačítko BOOT" +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' je volán mimo funkci" -#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h -#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h -msgid "You pressed the BOOT button at start up." +#: py/compile.c +msgid "unknown type '%q'" +msgstr "neznámý typ '%q'" + +#: py/compile.c +msgid "annotation must be an identifier" +msgstr "anotace musí být identifikátor" + +#: py/compile.c +msgid "argument name reused" +msgstr "jméno argumentu znovupoužito" + +#: py/compile.c +msgid "inline assembler must be a function" msgstr "" -#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h -msgid "You pressed the GPIO0 button at start up." -msgstr "Při spuštění jsi stiskl tlačítko na pinu GPIO0." +#: py/compile.c +msgid "unknown type" +msgstr "neznámý typ" -#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h -msgid "You pressed the Rec button at start up." -msgstr "Při spuštění jsi stiskl tlačítko Rec." +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "You pressed the SW38 button at start up." -msgstr "Při spuštění jsi stiskl tlačítko SW38." +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "" -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -#: ports/espressif/boards/vidi_x/mpconfigboard.h -msgid "You pressed the VOLUME button at start up." -msgstr "Při spuštění jsi stiskl tlačítko VOLUME." +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' vyžaduje 1 argument" -#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h -msgid "You pressed the central button at start up." -msgstr "Při spuštění jsi stiskl středové tlačítko." +#: py/compile.c +msgid "label redefined" +msgstr "" -#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h -msgid "You pressed the left button at start up." -msgstr "Při spuštění jsi stiskl tlačítko doleva." +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' vyžaduje 1 argument" -#: supervisor/shared/safe_mode.c -msgid "You pressed the reset button during boot." -msgstr "Při spuštění jsi stiskl tlačítko reset." +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' vyžaduje nejméně 2 argumenty" -#: supervisor/shared/micropython.c -msgid "[truncated due to length]" -msgstr "[zkráceno kvůli délce]" +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' vyžaduje celočíselné argumenty" -#: py/objtype.c -msgid "__init__() should return None" +#: py/compile.c +msgid "cannot emit native code for this architecture" msgstr "" -#: py/objtype.c -#, c-format -msgid "__init__() should return None, not '%s'" +#: py/emitbc.c +msgid "bytecode overflow" +msgstr "přetečení bytecode" + +#: py/emitinlinerv32.c +msgid "can only have up to 4 parameters for RV32 assembly" msgstr "" -#: py/objobject.c -msgid "__new__ arg must be a user-type" +#: py/emitinlinerv32.c +msgid "parameters must be registers in sequence a0 to a3" msgstr "" -#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c -msgid "a bytes-like object is required" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: expecting %q" msgstr "" -#: shared-bindings/i2ctarget/I2CTarget.c -msgid "addresses is empty" +#: py/emitinlinerv32.c +msgid "opcode '%q': expecting %d arguments" msgstr "" -#: py/compile.c -msgid "annotation must be an identifier" -msgstr "anotace musí být identifikátor" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: out of range" +msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "arange: cannot compute length" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: unknown register" msgstr "" -#: py/modbuiltins.c -msgid "arg is an empty sequence" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: undefined label '%q'" msgstr "" -#: py/objobject.c -msgid "arg must be user-type" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: must not be zero" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort argument must be an ndarray" +#: py/emitinlinerv32.c +msgid "invalid RV32 instruction '%q'" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort is not implemented for flattened arrays" -msgstr "argsort není implementován pro zploštěná pole" +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "argument must be None, an integer or a tuple of integers" +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: py/compile.c -msgid "argument name reused" -msgstr "jméno argumentu znovupoužito" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' očekává nanejvýš r%d" -#: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c -msgid "argument num/types mismatch" -msgstr "" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' očekává registr" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c -msgid "arguments must be ndarrays" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' očekává speciální registr" -#: extmod/ulab/code/ndarray.c -msgid "array and index length must be equal" -msgstr "Pole a index musí mít stejnou délku" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' očekává registr FPU" -#: extmod/ulab/code/numpy/io/io.c -msgid "array has too many dimensions" -msgstr "pole má příliš mnoho dimenzí" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' očekává {r0, r1, ...}" -#: extmod/ulab/code/ndarray.c -msgid "array is too big" -msgstr "pole je příliš velké" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' očekává integer (celé číslo)" -#: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c -msgid "array/bytes required on right side" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" +msgstr "'%s' integer 0x%x nepatří do masky 0x%x" -#: py/asmxtensa.c -msgid "asm overflow" -msgstr "přetečení v asm" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' očekává adresu ve formátu [a, b]" -#: py/compile.c -msgid "async for/with outside async function" -msgstr "" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' očekává label" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get (arg)min/(arg)max of empty sequence" -msgstr "pokus o získání (arg)min/(arg)max z prázdné sekvence" +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get argmin/argmax of an empty sequence" +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" -#: py/objstr.c -msgid "attributes not supported" +#: py/emitinlinethumb.c +msgid "branch not in range" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "axis is out of bounds" -msgstr "osa je mimo rozsah" +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -msgid "axis must be None, or an integer" -msgstr "osa musí být None nebo integer" +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "axis too long" -msgstr "osa je příliš dlouhá" +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d isn't within range %d..%d" +msgstr "'%s' integer %d není v rozsahu %d..%d" -#: shared-bindings/bitmaptools/__init__.c -msgid "background value out of range of target" +#: py/emitinlinextensa.c +#, c-format +msgid "%d is not a multiple of %d" msgstr "" -#: py/builtinevex.c -msgid "bad compile mode" +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" msgstr "" -#: py/objstr.c -msgid "bad conversion specifier" +#: py/emitnative.c +msgid "conversion to object" msgstr "" -#: py/objstr.c -msgid "bad format string" +#: py/emitnative.c +msgid "local '%q' used before type known" msgstr "" -#: py/binary.c py/objarray.c -msgid "bad typecode" +#: py/emitnative.c +msgid "can't load from '%q'" msgstr "" #: py/emitnative.c -msgid "binary op %q not implemented" +msgid "can't load with '%q' index" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "bitmap size and depth must match" +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "bitmap sizes must match" -msgstr "velikosti bitmapy musí odpovídat" - -#: extmod/modrandom.c -msgid "bits must be 32 or less" -msgstr "počet bitů nesmí přesáhnout 32" - -#: shared-bindings/audiomixer/Mixer.c -msgid "bits_per_sample must be 8 or 16" +#: py/emitnative.c +msgid "can't store '%q'" msgstr "" -#: py/emitinlinethumb.c -msgid "branch not in range" +#: py/emitnative.c +msgid "can't store to '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer is smaller than requested size" -msgstr "buffer je menší než požadovaná velikost" - -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer size must be a multiple of element size" -msgstr "velikost bufferu musí být násobkem velikosti elementu" - -#: shared-module/struct/__init__.c -msgid "buffer size must match format" +#: py/emitnative.c +msgid "can't store with '%q' index" msgstr "" -#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c -msgid "buffer slices must be of equal length" +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" msgstr "" -#: py/modstruct.c shared-module/struct/__init__.c -msgid "buffer too small" +#: py/emitnative.c +msgid "'not' not implemented" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "buffer too small for requested bytes" -msgstr "buffer je příliš malý pro počet požadovaných bajtů" +#: py/emitnative.c +msgid "can't do unary op of '%q'" +msgstr "" -#: py/emitbc.c -msgid "bytecode overflow" -msgstr "přetečení bytecode" +#: py/emitnative.c +msgid "div/mod not implemented for uint" +msgstr "div/mod nejsou implementované pro uint" -#: py/objarray.c -msgid "bytes length not a multiple of item size" -msgstr "Počet bajtů není násobkem velikosti prvku" +#: py/emitnative.c +msgid "comparison of int and uint" +msgstr "porovnání int a uint" -#: py/objstr.c -msgid "bytes value out of range" +#: py/emitnative.c +msgid "binary op %q not implemented" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is out of range" +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is read only" +#: py/emitnative.c +msgid "casting" msgstr "" -#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c -#: shared-module/vectorio/Rectangle.c -msgid "can only have one parent" -msgstr "může mít pouze jednoho rodiče" +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "" -#: py/emitinlinethumb.c -msgid "can only have up to 4 parameters to Thumb assembly" +#: py/emitnative.c +msgid "must raise an object" msgstr "" -#: py/emitinlinextensa.c -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitnative.c +msgid "native yield" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "can only specify one unknown dimension" +#: py/lexer.c +msgid "unicode name escapes" msgstr "" -#: py/objtype.c -msgid "can't add special method to already-subclassed class" +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" msgstr "" -#: py/compile.c -msgid "can't assign to expression" +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" msgstr "" -#: extmod/modasyncio.c -msgid "can't cancel self" -msgstr "nelze zrušit sám sebe" +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c -msgid "can't convert %q to %q" -msgstr "není možné převést %q na %q" +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "" -#: py/obj.c +#: py/modbuiltins.c #, c-format -msgid "can't convert %s to complex" -msgstr "nelze převést %s na complex" +msgid "ord() expected a character, but string of length %d found" +msgstr "" -#: py/obj.c -#, c-format -msgid "can't convert %s to float" -msgstr "nelze převést %s na float" +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "pow() nepodporuje 3 argumenty" -#: py/objint.c py/runtime.c -#, c-format -msgid "can't convert %s to int" +#: py/modbuiltins.c +msgid "must use keyword argument for key function" msgstr "" -#: py/objstr.c -msgid "can't convert '%q' object to %q implicitly" -msgstr "" +#: py/moderrno.c +msgid "Operation not permitted" +msgstr "Operace není povolena" -#: extmod/ulab/code/numpy/vector.c -msgid "can't convert complex to float" -msgstr "nelze převést complex na float" +#: py/moderrno.c +msgid "No such file/directory" +msgstr "Žádný takový soubor / adresář" -#: py/obj.c -msgid "can't convert to complex" -msgstr "nelze převést na complex" +#: py/moderrno.c +msgid "Input/output error" +msgstr "Chyba vstupu/výstupu" -#: py/obj.c -msgid "can't convert to float" -msgstr "nelze převést na float" +#: py/moderrno.c +msgid "Permission denied" +msgstr "Přístup odepřen" -#: py/runtime.c -msgid "can't convert to int" -msgstr "nelze převést na int" +#: py/moderrno.c +msgid "File exists" +msgstr "soubor existuje" -#: py/objstr.c -msgid "can't convert to str implicitly" -msgstr "" +#: py/moderrno.c +msgid "No such device" +msgstr "Žádné takové zařízení" -#: py/compile.c -msgid "can't declare nonlocal in outer code" -msgstr "" +#: py/moderrno.c +msgid "No space left on device" +msgstr "Na zařízení nezůstal žádný prostor" -#: py/compile.c -msgid "can't delete expression" +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" msgstr "" -#: py/emitnative.c -msgid "can't do binary op between '%q' and '%q'" -msgstr "" +#: py/modmath.c +msgid "negative factorial" +msgstr "záporný faktoriál" -#: py/emitnative.c -msgid "can't do unary op of '%q'" +#: py/modmicropython.c +msgid "schedule queue full" msgstr "" -#: py/emitnative.c -msgid "can't implicitly convert '%q' to 'bool'" +#: py/modstruct.c shared-module/struct/__init__.c +msgid "buffer too small" msgstr "" -#: py/runtime.c -msgid "can't import name %q" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" msgstr "" -#: py/emitnative.c -msgid "can't load from '%q'" +#: py/modthread.c +msgid "expecting a dict for keyword args" msgstr "" -#: py/emitnative.c -msgid "can't load with '%q' index" +#: py/nativeglue.c +msgid "set unsupported" +msgstr "set neoodporován" + +#: py/nativeglue.c +msgid "slice unsupported" msgstr "" -#: py/builtinimport.c -msgid "can't perform relative import" -msgstr "nelze provést relativní import" +#: py/nativeglue.c +msgid "float unsupported" +msgstr "float není podporován" -#: py/objgenerator.c -msgid "can't send non-None value to a just-started generator" -msgstr "" +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c +msgid "can't convert %q to %q" +msgstr "není možné převést %q na %q" -#: shared-module/sdcardio/SDCard.c -msgid "can't set 512 block size" -msgstr "nelze nastavit velikost bloku 512" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "Při zpracování uvedené výjimky nastala další výjimka:" -#: py/objexcept.c py/objnamedtuple.c -msgid "can't set attribute" -msgstr "" +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" +msgstr "Výše uvedená výjimka byla přímá příčina následující výjimky:" -#: py/runtime.c -msgid "can't set attribute '%q'" -msgstr "nelze nastavit atribut '%q'" +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Soubor \"%q\", řádek %d" -#: py/emitnative.c -msgid "can't store '%q'" -msgstr "" +#: py/obj.c +msgid " File \"%q\"" +msgstr " Soubor \"%q\"" -#: py/emitnative.c -msgid "can't store to '%q'" -msgstr "" +#: py/obj.c +msgid ", in %q\n" +msgstr ", v% q\n" -#: py/emitnative.c -msgid "can't store with '%q' index" +#: py/obj.c +msgid "Traceback (most recent call last):\n" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from automatic field numbering to manual field specification" -msgstr "" +#: py/obj.c +msgid "can't convert to float" +msgstr "nelze převést na float" -#: py/objstr.c -msgid "" -"can't switch from manual field specification to automatic field numbering" +#: py/obj.c +#, c-format +msgid "can't convert %s to float" +msgstr "nelze převést %s na float" + +#: py/obj.c +msgid "can't convert to complex" +msgstr "nelze převést na complex" + +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "nelze převést %s na complex" + +#: py/obj.c +msgid "expected tuple/list" msgstr "" -#: py/objcomplex.c -msgid "can't truncate-divide a complex number" +#: py/obj.c +#, c-format +msgid "object '%s' isn't a tuple or list" +msgstr "objekt '%s' není tuple or nebo list" + +#: py/obj.c +msgid "tuple/list has wrong length" +msgstr "tuple/list má špatnou délku" + +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" msgstr "" -#: extmod/modasyncio.c -msgid "can't wait" -msgstr "nelze čekat" +#: py/obj.c +msgid "indices must be integers" +msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot assign new shape" -msgstr "nelze přiřadit nový tvar" +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "Indexy %q musí být celá čísla, nikoli %s" -#: extmod/ulab/code/ndarray_operators.c -msgid "cannot cast output with casting rule" +#: py/obj.c +msgid "object has no len" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex to dtype" -msgstr "nelze převést complex na dtype" - -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex type" -msgstr "nelze převést typ complex" +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "objekt typu '%s' nemá len()" -#: py/objtype.c -msgid "cannot create '%q' instances" +#: py/obj.c +msgid "object doesn't support item deletion" msgstr "" -#: py/objtype.c -msgid "cannot create instance" -msgstr "" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item deletion" +msgstr "'%s' objekt nepodporuje smazání položky" -#: extmod/ulab/code/ndarray.c -msgid "cannot delete array elements" -msgstr "nelze smazat prvky pole" +#: py/obj.c +msgid "object isn't subscriptable" +msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot reshape array" -msgstr "nelze změnit rozměry pole" +#: py/obj.c +#, c-format +msgid "'%s' object isn't subscriptable" +msgstr "'%s' objekt není vložitelný" -#: py/emitnative.c -msgid "casting" +#: py/obj.c +msgid "object doesn't support item assignment" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "channel re-init" -msgstr "opětovná inicializace kanálu" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item assignment" +msgstr "'%s' objekt nepodporuje přiřazení položky" -#: shared-bindings/_stage/Text.c -msgid "chars buffer too small" +#: py/obj.c +msgid "object with buffer protocol required" msgstr "" -#: py/modbuiltins.c -msgid "chr() arg not in range(0x110000)" -msgstr "" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "Počet bajtů není násobkem velikosti prvku" -#: py/modbuiltins.c -msgid "chr() arg not in range(256)" +#: py/objarray.c py/objstr.c +msgid "string argument without an encoding" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "clip point must be (x,y) tuple" -msgstr "" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "memoryview: délka není násobkem velikosti položky" -#: shared-bindings/msgpack/ExtType.c -msgid "code outside range 0~127" -msgstr "kód mimo rozsah 0~127" +#: py/objarray.c py/objstr.c +msgid "substring not found" +msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a buffer, tuple, list, or int" +#: py/objarray.c +msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color must be between 0x000000 and 0xffffff" +#: py/objarray.c +msgid "memoryview offset too large" msgstr "" -#: py/emitnative.c -msgid "comparison of int and uint" -msgstr "porovnání int a uint" +#: py/objcomplex.c +msgid "can't truncate-divide a complex number" +msgstr "" #: py/objcomplex.c msgid "complex divide by zero" msgstr "" -#: py/objfloat.c py/parsenum.c -msgid "complex values not supported" -msgstr "" +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 na komplexní mocninu" -#: extmod/modzlib.c -msgid "compression header" +#: py/objdeque.c +msgid "full" msgstr "" -#: py/emitnative.c -msgid "conversion to object" +#: py/objdeque.c +msgid "empty" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be linear arrays" +#: py/objdict.c +msgid "dict update sequence has wrong length" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be ndarrays" +#: py/objexcept.c py/objnamedtuple.c +msgid "can't set attribute" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must not be empty" +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "corrupted file" -msgstr "poškozený soubor" +#: py/objgenerator.c +msgid "generator already executing" +msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "could not invert Vandermonde matrix" +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "couldn't determine SD card version" -msgstr "nelze zjistit verzi SD karty" +#: py/objgenerator.c py/runtime.c +msgid "generator raised StopIteration" +msgstr "generátor způsobil StopIteration" -#: extmod/ulab/code/numpy/numerical.c -msgid "cross is defined for 1D arrays of length 3" +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be iterable" -msgstr "data musí být iterovatelná" +#: py/objint.c py/runtime.c +#, c-format +msgid "can't convert %s to int" +msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be of equal length" -msgstr "data musí mít stejnou délku" +#: py/objint.c +msgid "float too big" +msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: py/objint.c #, c-format -msgid "data pin #%d in use" -msgstr "datový pin #%d je používán" +msgid "value must fit in %d byte(s)" +msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "data type not understood" -msgstr "datový typ nebyl rozpoznán" +#: py/objint.c shared-bindings/time/__init__.c +msgid "No long integer support" +msgstr "Není podpora long integer" -#: py/parsenum.c -msgid "decimal numbers not supported" +#: py/objint.c py/sequence.c +msgid "small int overflow" msgstr "" -#: py/compile.c -msgid "default 'except' must be last" +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c +msgid "%q=%q" +msgstr "%q=%q" + +#: py/objint_longlong.c py/parsenum.c +msgid "result overflows long long storage" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "default is not a function" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative shift count" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +#: py/objint_longlong.c py/objint_mpz.c +msgid "overflow converting long int to machine word" msgstr "" -#: py/objdict.c -msgid "dict update sequence has wrong length" +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "diff argument must be an ndarray" +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "differentiation order out of range" +#: py/objobject.c +msgid "__new__ arg must be a user-type" msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "dimensions do not match" -msgstr "dimenze nesouhlasí" +#: py/objobject.c +msgid "arg must be user-type" +msgstr "" -#: py/emitnative.c -msgid "div/mod not implemented for uint" -msgstr "div/mod nejsou implementované pro uint" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "%q krok nemůže být nula" -#: extmod/ulab/code/numpy/create.c -msgid "divide by zero" -msgstr "dělení nulou" +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Nelze použít řez podtřídy" -#: py/runtime.c -msgid "division by zero" +#: py/objstr.c +msgid "bytes value out of range" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "dtype must be float, or complex" -msgstr "dtype musí být float nebo complex" - -#: extmod/ulab/code/ndarray_operators.c -msgid "dtype of int32 is not supported" +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" msgstr "" -#: py/objdeque.c -msgid "empty" +#: py/objstr.c +msgid "empty separator" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "empty file" -msgstr "prázdný soubor" +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "rsplit(None,n)" -#: extmod/modasyncio.c extmod/modheapq.c -msgid "empty heap" +#: py/objstr.c +msgid "bad format string" msgstr "" #: py/objstr.c -msgid "empty separator" -msgstr "" +#, c-format +msgid "unmatched '%c' in format" +msgstr "neshoduje se '%c' ve formátu" -#: shared-bindings/random/__init__.c -msgid "empty sequence" +#: py/objstr.c +msgid "bad conversion specifier" msgstr "" #: py/objstr.c msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "epoch_time not supported on this board" -msgstr "epoch_time není podporován na této desce" - -#: ports/nordic/common-hal/busio/UART.c +#: py/objstr.c #, c-format -msgid "error = 0x%08lX" -msgstr "" - -#: py/runtime.c -msgid "exceptions must derive from BaseException" +msgid "unknown conversion specifier %c" msgstr "" #: py/objstr.c msgid "expected ':' after format specifier" msgstr "" -#: py/obj.c -msgid "expected tuple/list" +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" msgstr "" -#: py/modthread.c -msgid "expecting a dict for keyword args" -msgstr "" +#: py/objstr.c +msgid "%q index out of range" +msgstr "Index %q je mimo rozsah" -#: py/compile.c -msgid "expecting an assembler instruction" +#: py/objstr.c +msgid "attributes not supported" msgstr "" -#: py/compile.c -msgid "expecting just a value for set" +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" msgstr "" -#: py/compile.c -msgid "expecting key:value for dict" +#: py/objstr.c +msgid "invalid format specifier" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "ext_hook is not a function" +#: py/objstr.c +msgid "sign not allowed in string format specifier" msgstr "" -#: py/argcheck.c -msgid "extra keyword arguments given" +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/argcheck.c -msgid "extra positional arguments given" +#: py/objstr.c +msgid "unknown format code '%c' for object of type '%q'" msgstr "" -#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c -#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c -msgid "file must be a file opened in byte mode" +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "Specifikátor zarovnání '=' není ve formátovacím řetězci povolen" + +#: py/objstr.c +msgid "format needs a dict" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "file write is not available" -msgstr "zápis do souboru není dostupný" +#: py/objstr.c +msgid "incomplete format key" +msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" +#: py/objstr.c +msgid "incomplete format" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "first argument must be a callable" -msgstr "První argument musí být zavolatelný" +#: py/objstr.c +msgid "format string needs more arguments" +msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "first argument must be a function" -msgstr "první argument musí být funkce" +#: py/objstr.c +#, c-format +msgid "%%c needs int or char" +msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "first argument must be a tuple of ndarrays" -msgstr "první argument musí být tuple nebo ndarray" +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "" -#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c -msgid "first argument must be an ndarray" +#: py/objstr.c +msgid "format string didn't convert all arguments" msgstr "" -#: py/objtype.c -msgid "first argument to super() must be type" +#: py/objstr.c +msgid "non-hex digit" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "first two arguments must be ndarrays" -msgstr "první dva argumenty musí být ndarray" +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "flattening order must be either 'C', or 'F'" +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "flip argument must be an ndarray" +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" msgstr "" -#: py/objint.c -msgid "float too big" +#: py/objstrunicode.c +msgid "string index out of range" msgstr "" -#: py/nativeglue.c -msgid "float unsupported" -msgstr "float není podporován" +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "Volání super().__init__() před přístupem k nativnímu objektu." -#: shared-bindings/_stage/Text.c -msgid "font must be 2048 bytes long" +#: py/objtype.c +msgid "__init__() should return None" msgstr "" -#: extmod/moddeflate.c -msgid "format" +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" msgstr "" -#: py/objstr.c -msgid "format requires a dict" +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" msgstr "" -#: py/objdeque.c -msgid "full" +#: py/objtype.c py/runtime.c +msgid "object not callable" msgstr "" -#: py/argcheck.c -msgid "function doesn't take keyword arguments" +#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c +msgid "'%q' object isn't callable" msgstr "" -#: py/argcheck.c -#, c-format -msgid "function expected at most %d arguments, got %d" +#: py/objtype.c +msgid "type takes 1 or 3 arguments" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "function got multiple values for argument '%q'" +#: py/objtype.c +msgid "can't create instance" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "function has the same sign at the ends of interval" +#: py/objtype.c +msgid "can't create '%q' instances" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "function is defined for ndarrays only" -msgstr "funkce je definována pouze pro ndarraye" - -#: extmod/ulab/code/numpy/carray/carray.c -msgid "function is implemented for ndarrays only" -msgstr "funkce je implementována jen pro ndarraye" +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" -#: py/argcheck.c -#, c-format -msgid "function missing %d required positional arguments" -msgstr "funkci chybí %d povinné poziční argumenty" +#: py/objtype.c +msgid "type isn't an acceptable base type" +msgstr "" -#: py/bc.c -msgid "function missing keyword-only argument" -msgstr "funkci chybí argument pouze pro klíčové slovo" +#: py/objtype.c +msgid "type '%q' isn't an acceptable base type" +msgstr "" -#: py/bc.c -msgid "function missing required keyword argument '%q'" -msgstr "funkci chybí argument specifikovaný klíčovým slovem" +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "" -#: py/bc.c -#, c-format -msgid "function missing required positional argument #%d" -msgstr "funkci chybí požadovaný argument na pozici #%d" +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c -#: shared-bindings/time/__init__.c -#, c-format -msgid "function takes %d positional arguments but %d were given" +#: py/objtype.c +msgid "first argument to super() must be type" msgstr "" -#: py/objgenerator.c -msgid "generator already executing" +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/objgenerator.c -msgid "generator ignored GeneratorExit" +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" msgstr "" -#: py/objgenerator.c py/runtime.c -msgid "generator raised StopIteration" -msgstr "generátor způsobil StopIteration" +#: py/parse.c +msgid "not a constant" +msgstr "není konstanta" -#: shared-bindings/_stage/Layer.c -msgid "graphic must be 2048 bytes long" +#: py/parse.c +msgid "Unable to init parser" msgstr "" -#: extmod/modhashlib.c -msgid "hash is final" -msgstr "hash je konečný" +#: py/parse.c +msgid "unexpected indent" +msgstr "neočekávané odsazení" -#: extmod/modheapq.c -msgid "heap must be a list" +#: py/parse.c +msgid "unindent doesn't match any outer indent level" msgstr "" -#: py/compile.c -msgid "identifier redefined as global" +#: py/parse.c +msgid "malformed f-string" msgstr "" -#: py/compile.c -msgid "identifier redefined as nonlocal" +#: py/parsenum.c +msgid "invalid syntax for integer" msgstr "" -#: py/compile.c -msgid "import * not at module level" +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" msgstr "" -#: py/persistentcode.c -msgid "incompatible .mpy arch" -msgstr "nekopmatibilní architektura .mpy" +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "" + +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "" #: py/persistentcode.c msgid "incompatible .mpy file" msgstr "nekompatibilní .mpy soubor" -#: py/objstr.c -msgid "incomplete format" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" msgstr "" -#: py/objstr.c -msgid "incomplete format key" +#: py/persistentcode.c +msgid "native code in .mpy unsupported" msgstr "" -#: extmod/modbinascii.c -msgid "incorrect padding" +#: py/persistentcode.c +msgid "incompatible .mpy arch" +msgstr "nekopmatibilní architektura .mpy" + +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "'%q' object does not support '%q'" +msgstr "Objekt '%q' nepodporuje '%q'" + +#: py/qstr.c +msgid "name too long" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c -msgid "index is out of bounds" +#: py/runtime.c +msgid "name not defined" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "index must be tuple or int" -msgstr "index musí být tuple nebo int" +#: py/runtime.c +msgid "name '%q' isn't defined" +msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: py/runtime.c +msgid "unsupported type for operator" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: py/runtime.c +msgid "unsupported type for %q: '%s'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "indices must be integers, slices, or Boolean lists" +#: py/runtime.c +msgid "unsupported types for %q: '%q', '%q'" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "inicializace I2C" +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "initial values must be iterable" -msgstr "výchozí hodnoty musí být iterovatelné" +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" +msgstr "" -#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c -msgid "initial_value length is wrong" -msgstr "délka initial_value je chybná" +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" +msgstr "" -#: py/compile.c -msgid "inline assembler must be a function" +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output dimensions differ" -msgstr "dimenze vstupu a výstupu se liší" +#: py/runtime.c +msgid "module '%q' has no attribute '%q'" +msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output shapes differ" -msgstr "vstupní a výstupní tvar je růzmý" +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' objekt nemá žádný atribut '%q'" -#: extmod/ulab/code/numpy/create.c -msgid "input argument must be an integer, a tuple, or a list" -msgstr "vstupní argument musí být integer, tuple nebo list" +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "nelze nastavit atribut '%q'" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "input array length must be power of 2" +#: py/runtime.c +msgid "object not iterable" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input arrays are not compatible" -msgstr "vstupní pole nejsou kompatibilní" +#: py/runtime.c +msgid "'%q' object isn't iterable" +msgstr "Objekt '%q' není iterovatelný" -#: extmod/ulab/code/numpy/poly.c -msgid "input data must be an iterable" +#: py/runtime.c +msgid "object not an iterator" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input dtype must be float or complex" -msgstr "vstupní dtype musí být float nebo complex" - -#: extmod/ulab/code/numpy/poly.c -msgid "input is not iterable" -msgstr "vstup není iterovatelný" +#: py/runtime.c +msgid "'%q' object isn't an iterator" +msgstr "Objekt '%q' není iterátor" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "input matrix is asymmetric" +#: py/runtime.c +msgid "exceptions must derive from BaseException" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "input matrix is singular" +#: py/runtime.c +msgid "can't import name %q" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input must be 1- or 2-d" -msgstr "vstup musí být 1- nebo 2-d" - -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be a 1D ndarray" -msgstr "vstup musí být 1D ndarray" - -#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c -msgid "input must be a dense ndarray" -msgstr "vstup musí být hustý ndarray" - -#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c -msgid "input must be an ndarray" -msgstr "vstup musí být ndarray" +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be an ndarray, or a scalar" -msgstr "vstup musí být ndarray nebo scalar" +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "input must be one-dimensional" -msgstr "vstup musí být jednorozměrný" +#: py/runtime.c +msgid "can't convert to int" +msgstr "nelze převést na int" -#: extmod/ulab/code/ulab_tools.c -msgid "input must be square matrix" +#: py/runtime.c +msgid "division by zero" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "input must be tuple, list, range, or ndarray" +#: py/runtime.c +msgid "maximum recursion depth exceeded" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input vectors must be of equal length" +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "interp is defined for 1D iterables of equal length" +#: py/stream.c shared-bindings/getpass/__init__.c +msgid "stream operation not supported" msgstr "" -#: shared-bindings/_bleio/Adapter.c -#, c-format -msgid "interval must be in range %s-%s" +#: py/vm.c +msgid "local variable referenced before assignment" msgstr "" -#: py/compile.c -msgid "invalid arch" +#: py/vm.c +msgid "no active exception to reraise" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" -msgstr "chybné bits_per_pixel %d, musí být 1, 2, 4, 8, 16, 24, or 32" +#: py/vm.c +msgid "opcode" +msgstr "opcode" -#: shared-module/ssl/SSLSocket.c -msgid "invalid cert" -msgstr "špatný certifikár" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot create a new Adapter; use _bleio.adapter;" +msgstr "Není možné vytvořit nový adaptér; použití _bleio.adapter;" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element size %d for bits_per_pixel %d\n" -msgstr "" +#: shared-bindings/_bleio/Adapter.c +msgid "Could not set address" +msgstr "Není možné nastavit adresu" -#: shared-bindings/bitmaptools/__init__.c +#: shared-bindings/_bleio/Adapter.c #, c-format -msgid "invalid element_size %d, must be, 1, 2, or 4" -msgstr "chybná element_size %d, musí být 1, 2, nebo 4" - -#: shared-bindings/traceback/__init__.c -msgid "invalid exception" -msgstr "špatná výjimka" - -#: py/objstr.c -msgid "invalid format specifier" +msgid "interval must be in range %s-%s" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "invalid hostname" -msgstr "špatný hostname" - -#: shared-module/ssl/SSLSocket.c -msgid "invalid key" -msgstr "špatný klíč" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot have scan responses for extended, connectable advertisements." +msgstr "" -#: py/compile.c -msgid "invalid micropython decorator" +#: shared-bindings/_bleio/Adapter.c +msgid "Only connectable advertisements can be directed" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c -msgid "invalid setting" -msgstr "neplatné nastavení" +#: shared-bindings/_bleio/Adapter.c +msgid "non-zero timeout must be >= interval" +msgstr "nenulový timeout musí být >= interval" -#: shared-bindings/random/__init__.c -msgid "invalid step" +#: shared-bindings/_bleio/Adapter.c +msgid "window must be <= interval" msgstr "" -#: py/compile.c py/parse.c -msgid "invalid syntax" +#: shared-bindings/_bleio/Adapter.c +msgid "Prefix buffer must be on the heap" msgstr "" -#: py/parsenum.c -msgid "invalid syntax for integer" +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "CharacteristicBuffer psaní není poskytováno" + +#: shared-bindings/_bleio/Connection.c +msgid "" +"Connection has been disconnected and can no longer be used. Create a new " +"connection." msgstr "" +"Připojení bylo odpojeno a nelze jej dále používat. Vytvořte nové připojení." -#: py/parsenum.c +#: shared-bindings/_bleio/PacketBuffer.c #, c-format -msgid "invalid syntax for integer with base %d" -msgstr "" +msgid "Buffer too short by %d bytes" +msgstr "Buffer je příliš krátký o %d bajtů" -#: py/parsenum.c -msgid "invalid syntax for number" -msgstr "" +#: shared-bindings/_bleio/PacketBuffer.c +msgid "No connection: length cannot be determined" +msgstr "Žádné připojení: nelze určit délku" -#: py/objtype.c -msgid "issubclass() arg 1 must be a class" -msgstr "" +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "UUID řetězec neodpovídá 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" -#: py/objtype.c -msgid "issubclass() arg 2 must be a class or a tuple of classes" -msgstr "" +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "Hodnota UUID není str, int ani byte buffer" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "iterations did not converge" +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" msgstr "" -#: py/objstr.c -msgid "join expects a list of str/bytes objects consistent with self object" -msgstr "" +#: shared-bindings/_bleio/__init__.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c +#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c +msgid "Read-only" +msgstr "Pouze pro čtení" -#: py/argcheck.c -msgid "keyword argument(s) not implemented - use normal args instead" -msgstr "" +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "Nesprávná velikost vyrovnávací paměti" -#: py/emitinlinethumb.c py/emitinlinextensa.c -msgid "label '%q' not defined" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" msgstr "" -#: py/compile.c -msgid "label redefined" -msgstr "" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "index musí být tuple nebo int" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" msgstr "" -#: py/objarray.c -msgid "lhs and rhs should be compatible" +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" msgstr "" -#: py/emitnative.c -msgid "local '%q' has type '%q' but source is '%q'" -msgstr "" +#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +msgid "Pin is input only" +msgstr "Pin je pouze vstupní" -#: py/emitnative.c -msgid "local '%q' used before type known" +#: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" -#: py/vm.c -msgid "local variable referenced before assignment" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "Key must be 16, 24, or 32 bytes long" +msgstr "Klíč musí být dlouhý 16, 24 nebo 32 bajtů" -#: ports/espressif/common-hal/canio/CAN.c -msgid "loopback + silent mode not supported by peripheral" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "Requested AES mode is unsupported" +msgstr "Požadovaný režim AES je nepodporovaný" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS already initialized" -msgstr "mDNS je již inicializováno" +#: shared-bindings/aesio/aes.c +msgid "Source and destination buffers must be the same length" +msgstr "Zdrojové a cílové buffery musí být stejné délky" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS only works with built-in WiFi" -msgstr "mDNS pracuje pouze s vestavěnou WiFi" +#: shared-bindings/aesio/aes.c +msgid "ECB only operates on 16 bytes at a time" +msgstr "ECB operuje najednou pouze 16 bajtů" -#: py/parse.c -msgid "malformed f-string" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "CBC blocks must be multiples of 16 bytes" +msgstr "Bloky CBC musí být násobky 16 bajtů" -#: shared-bindings/_stage/Layer.c -msgid "map buffer too small" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." msgstr "" -#: py/modmath.c shared-bindings/math/__init__.c -msgid "math domain error" -msgstr "" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Hodnoty pole by měly být jednoduché bajty." -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "matrix is not positive definite" -msgstr "" +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." +msgstr "Nelze zapsat do sleep_memory." -#: ports/espressif/common-hal/_bleio/Descriptor.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -#, c-format -msgid "max_length must be 0-%d when fixed_length is %s" -msgstr "" +#: shared-bindings/alarm/__init__.c +msgid "Expected a kind of %q" +msgstr "Očekáván typ %q" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c -msgid "maximum number of dimensions is " -msgstr "maximální počet dimenzí je " +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "RTC není na této desce podporován" -#: py/runtime.c -msgid "maximum recursion depth exceeded" -msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" +msgstr "Musíš definovat monotonic_time nebo epoch_time" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter must be > 0" -msgstr "maxiter musí být > 0" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" +msgstr "epoch_time není podporován na této desce" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter should be > 0" -msgstr "maxiter by měl být > 0" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." +msgstr "Čas je v minulosti." -#: extmod/ulab/code/numpy/numerical.c -msgid "median argument must be an ndarray" -msgstr "" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q musí být bytearray nebo pole typu 'H' nebo 'B'" -#: py/runtime.c -#, c-format -msgid "memory allocation failed, allocating %u bytes" -msgstr "" +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c shared-bindings/mcp4822/MCP4822.c +#: shared-bindings/usb_audio/USBMicrophone.c +msgid "Not playing" +msgstr "Nehraje" -#: py/runtime.c -msgid "memory allocation failed, heap is locked" +#: shared-bindings/audiobusio/PDMIn.c +msgid "%q must be multiple of 8." msgstr "" -#: py/objarray.c -msgid "memoryview offset too large" -msgstr "" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Cannot record to a file" +msgstr "Nelze nahrávat do souboru" -#: py/objarray.c -msgid "memoryview: length is not a multiple of itemsize" -msgstr "memoryview: délka není násobkem velikosti položky" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "Cílová kapacita je menší než destination_length." -#: extmod/modtime.c -msgid "mktime needs a tuple of length 8 or 9" +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "mode must be complete, or reduced" +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: py/builtinimport.c -msgid "module not found" -msgstr "" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q musí být bytearray nebo pole typu 'h', 'H', 'b', nebo 'B'" -#: ports/espressif/common-hal/wifi/Monitor.c -msgid "monitor init failed" +#: shared-bindings/audiocore/RawSample.c +msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "more degrees of freedom than data points" +#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c +msgid "file must be a file opened in byte mode" msgstr "" -#: py/compile.c -msgid "multiple *x in assignment" +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/Flanger.c +#: shared-bindings/audiodelays/GranularPitchShift.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c +#: shared-bindings/audiomixer/Mixer.c +msgid "bits_per_sample must be 8 or 16" msgstr "" -#: py/objtype.c -msgid "multiple bases have instance lay-out conflict" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" msgstr "" -#: py/objtype.c -msgid "multiple inheritance not supported" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" msgstr "" -#: py/emitnative.c -msgid "must raise an object" +#: shared-bindings/audioi2sin/I2SIn.c +#, c-format +msgid "invalid destination buffer, must be an array of type: %c" msgstr "" -#: py/modbuiltins.c -msgid "must use keyword argument for key function" -msgstr "" +#: shared-bindings/audioio/AudioOut.c +msgid "%q and %q must be different" +msgstr "%q a %q musí být rozdílné" -#: py/runtime.c -msgid "name '%q' is not defined" +#: shared-bindings/bitmapfilter/__init__.c +msgid "" +"weights must be a sequence with an odd square number of elements (usually 9 " +"or 25)" msgstr "" -#: py/runtime.c -msgid "name not defined" +#: shared-bindings/bitmapfilter/__init__.c +msgid "weights must be an object of type %q, %q, %q, or %q, not %q " msgstr "" -#: py/qstr.c -msgid "name too long" +#: shared-bindings/bitmaptools/__init__.c +msgid "clip point must be (x,y) tuple" msgstr "" -#: py/persistentcode.c -msgid "native code in .mpy unsupported" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "source palette too large" +msgstr "zdrojová paleta je příliš velká" -#: py/asmthumb.c -msgid "native method too big" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Bitmap size and bits per value must match" +msgstr "Velikost bitmapy a počet bitů na hodnotu se musí shodovat" -#: py/emitnative.c -msgid "native yield" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" +msgstr "Pro barevný prostor L8 musí mít vstupní bitmapa 8 bitů na pixel" -#: extmod/ulab/code/ndarray.c -msgid "ndarray length overflows" -msgstr "délka ndarray přetekla" +#: shared-bindings/bitmaptools/__init__.c +msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" +msgstr "Pro barevný prostor RGB musí mít vstupní bitmapa 16 bitů na pixel" -#: py/runtime.c -#, c-format -msgid "need more than %d values to unpack" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Unsupported colorspace" +msgstr "Nepodporovaný barevný prostor" -#: py/modmath.c -msgid "negative factorial" -msgstr "záporný faktoriál" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap size must match the other bitmaps" +msgstr "" -#: py/objint_longlong.c py/objint_mpz.c py/runtime.c -msgid "negative power with no float support" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap must have 8 bits per pixel" msgstr "" -#: py/objint_mpz.c py/runtime.c -msgid "negative shift count" +#: shared-bindings/bitmaptools/__init__.c +msgid "out of range of target" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "nested index must be int" +#: shared-bindings/bitmaptools/__init__.c +msgid "value out of range of target" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no SD card" -msgstr "není vložena SD karta" +#: shared-bindings/bitmaptools/__init__.c +msgid "background value out of range of target" +msgstr "" -#: py/vm.c -msgid "no active exception to reraise" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" msgstr "" -#: py/compile.c -msgid "no binding for nonlocal found" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "Pole souřadnic mají různé délky" + +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element_size %d, must be, 1, 2, or 4" +msgstr "chybná element_size %d, musí být 1, 2, nebo 4" + +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element size %d for bits_per_pixel %d\n" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "no default packer" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +msgstr "chybné bits_per_pixel %d, musí být 1, 2, 4, 8, 16, 24, or 32" -#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c -msgid "no default seed" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "bitmap sizes must match" +msgstr "velikosti bitmapy musí odpovídat" -#: py/builtinimport.c -msgid "no module named '%q'" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 2 or 65536" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no response from SD card" -msgstr "žádná odpověď z SD karty" - -#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c -msgid "no such attribute" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 65536" msgstr "" -#: ports/espressif/common-hal/_bleio/Connection.c -#: ports/nordic/common-hal/_bleio/Connection.c -msgid "non-UUID found in service_uuids_whitelist" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 8" msgstr "" -#: py/compile.c -msgid "non-default argument follows default argument" +#: shared-bindings/bitmaptools/__init__.c +msgid "unsupported colorspace for dither" msgstr "" -#: py/objstr.c -msgid "non-hex digit found" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "non-zero timeout must be > 0.01" -msgstr "nenulový timeout musí být > 0.01" +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Žádná výchozí sběrnice %q" -#: shared-bindings/_bleio/Adapter.c -msgid "non-zero timeout must be >= interval" -msgstr "nenulový timeout musí být >= interval" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c +msgid "Display rotation must be in 90 degree increments" +msgstr "Otočení displeje musí být po 90 stupních" -#: shared-bindings/_bleio/UUID.c -msgid "not a 128-bit UUID" -msgstr "" +#: shared-bindings/busdisplay/BusDisplay.c +msgid "%q must be 1 when %q is True" +msgstr "%q musí být 1, pokud %q je True" -#: py/parse.c -msgid "not a constant" -msgstr "není konstanta" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Display must have a 16 bit colorspace." +msgstr "Displej musí mít 16bitový barevný prostor." -#: py/objstr.c -msgid "not all arguments converted during string formatting" +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c +msgid "tx and rx cannot both be None" msgstr "" -#: py/objstr.c -msgid "not enough arguments for format string" -msgstr "" +#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "Musí být podtřída %q." -#: extmod/ulab/code/numpy/carray/carray_tools.c -msgid "not implemented for complex dtype" -msgstr "není implementováno pro komplexní dtype" +#: shared-bindings/canio/RemoteTransmissionRequest.c +msgid "RemoteTransmissionRequests limited to 8 bytes" +msgstr "RemoteTransmissionRequests je limitován na 8 bajtů" -#: extmod/ulab/code/numpy/bitwise.c -msgid "not supported for input types" -msgstr "není podporováno pro vstupní typy" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Cannot set value when direction is input." +msgstr "Nelze nastavit hodnotu, když směr je vstup." -#: extmod/ulab/code/numpy/create.c -msgid "number of points must be at least 2" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Drive mode not used when direction is input." msgstr "" -#: py/builtinhelp.c -msgid "object " -msgstr "objekt " - -#: py/obj.c -#, c-format -msgid "object '%s' isn't a tuple or list" -msgstr "objekt '%s' není tuple or nebo list" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Pull not used when direction is output." +msgstr "" -#: py/obj.c -msgid "object doesn't support item assignment" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" msgstr "" -#: py/obj.c -msgid "object doesn't support item deletion" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" msgstr "" -#: py/obj.c -msgid "object has no len" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" msgstr "" -#: py/obj.c -msgid "object isn't subscriptable" +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Nelze odstranit hodnoty" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +msgid "Slices not supported" msgstr "" -#: py/runtime.c -msgid "object not an iterator" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: py/objtype.c py/runtime.c -msgid "object not callable" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: py/sequence.c shared-bindings/displayio/Group.c -msgid "object not in sequence" +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: py/runtime.c -msgid "object not iterable" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer, tuple, list, or int" msgstr "" -#: py/obj.c -#, c-format -msgid "object of type '%s' has no len()" -msgstr "objekt typu '%s' nemá len()" +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c +msgid "unsupported %q type" +msgstr "nepodporovaný typ% q" -#: py/obj.c -msgid "object with buffer protocol required" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" msgstr "" -#: py/objstr.c -msgid "odd-length string" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "off" -msgstr "vypnuto" +#: shared-bindings/displayio/TileGrid.c +msgid "New bitmap must be same size as old bitmap" +msgstr "Nová bitmapa musí mít stejnou velikost jako původní bitmapa" -#: extmod/ulab/code/utils/utils.c -msgid "offset is too large" -msgstr "offset je příliš velký" +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "" #: shared-bindings/dualbank/__init__.c msgid "offset must be >= 0" msgstr "offset musí být >= 0" -#: extmod/ulab/code/numpy/create.c -msgid "offset must be non-negative and no greater than buffer length" -msgstr "" - -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only bit_depth=16 is supported" -msgstr "" +#: shared-bindings/epaperdisplay/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "Pokus o obnovení příliš brzo" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only mono is supported" -msgstr "je podporováno pouze mono" +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Buffer is not a bytearray." +msgstr "Buffer není bytearray." -#: extmod/ulab/code/numpy/create.c -msgid "only ndarrays can be concatenated" -msgstr "pouze ndarraye mohou být spojeny" +#: shared-bindings/gnss/GNSS.c +msgid "System entry must be gnss.SatelliteSystem" +msgstr "Parametr \"system\" musí být gnss.SatelliteSystem" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only oversample=64 is supported" -msgstr "je podporován pouze oversampling 64" +#: shared-bindings/hashlib/__init__.c +msgid "Unsupported hash algorithm" +msgstr "Nepodporovaný hash algoritmus" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only sample_rate=16000 is supported" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" msgstr "" -#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "only slices with step=1 (aka None) are supported" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" msgstr "" -#: py/vm.c -msgid "opcode" -msgstr "opcode" - -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c -msgid "operands could not be broadcast together" +#: shared-bindings/i2ctarget/I2CTarget.c +msgid "addresses is empty" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for 2D arrays only" -msgstr "operace je definována pouze pro 2D pole" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "Nevalidní IP string" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for ndarrays only" -msgstr "operace je definována pouze pro ndarray pole" +#: shared-bindings/ipaddress/IPv4Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "Adresa musí být %d bajtů dlouhá" -#: extmod/ulab/code/ndarray.c -msgid "operation is implemented for 1D Boolean arrays only" -msgstr "operace je immplementována pouze pro 1D boolean pole" +#: shared-bindings/ipaddress/__init__.c +msgid "Only int or string supported for ip" +msgstr "Pro IP je podporován pouze int nebo string" -#: extmod/ulab/code/numpy/numerical.c -msgid "operation is not implemented on ndarrays" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "width must be greater than zero" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is not supported for given type" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "Scale dimensions must divide by 3" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "operation not supported for the input types" +#: shared-bindings/is31fl3741/IS31FL3741.c +msgid "Mapping must be a tuple" msgstr "" -#: py/modbuiltins.c -msgid "ord expects a character" +#: shared-bindings/jpegio/JpegDecoder.c +msgid "%q must be of type %q, %q, or %q, not %q" +msgstr "" + +#: shared-bindings/mdns/Server.c +msgid "" +"Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: py/modbuiltins.c -#, c-format -msgid "ord() expected a character, but string of length %d found" -msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Address range wraps around" +msgstr "Adresní rozsah se překlápí přes maximální možnou adresu" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" +msgstr "%q obsahuje duplicitní piny" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" +msgstr "%q a %q obsahují duplicitní piny" -#: extmod/ulab/code/utils/utils.c -msgid "out array is too small" -msgstr "výstupní pole je příliš malé" +#: shared-bindings/msgpack/ExtType.c +msgid "code outside range 0~127" +msgstr "kód mimo rozsah 0~127" -#: extmod/ulab/code/numpy/random/random.c -msgid "out has wrong type" +#: shared-bindings/msgpack/__init__.c +msgid "default is not a function" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for complex dtype" +#: shared-bindings/msgpack/__init__.c +msgid "ext_hook is not a function" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for function" -msgstr "" +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Není možné zapisovat do nvm." -#: extmod/ulab/code/utils/utils.c -msgid "out must be a float dense array" +#: shared-bindings/os/__init__.c +msgid "No hardware random available" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be an ndarray" -msgstr "" +#: shared-bindings/paralleldisplaybus/ParallelBus.c +msgid "Specify exactly one of data0 or data_pins" +msgstr "Specifikuj přesně jeden z data0 nebo data_pins" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be of float dtype" -msgstr "" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "Nepodařilo se odeslat příkaz." -#: shared-bindings/bitmaptools/__init__.c -msgid "out of range of target" -msgstr "" +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Pole musí obsahovat poloviční slova (typ „H“)" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array has wrong type" +#: shared-bindings/pwmio/PWMOut.c +msgid "Conflicting settings for shared resource" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array must be contiguous" +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" msgstr "" -#: py/objint_mpz.c -msgid "overflow converting long int to machine word" +#: shared-bindings/random/__init__.c +msgid "invalid step" msgstr "" -#: py/modstruct.c -#, c-format -msgid "pack expected %d items for packing (got %d)" +#: shared-bindings/random/__init__.c +msgid "empty sequence" msgstr "" -#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c -msgid "palette must be 32 bytes long" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" msgstr "" -#: py/emitinlinextensa.c -msgid "parameters must be registers in sequence a2 to a5" -msgstr "" +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" +msgstr "Počet prvků rgb_pin musí být 6, 12, 18, 24, nebo 30" -#: py/emitinlinethumb.c -msgid "parameters must be registers in sequence r0 to r3" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" msgstr "" -#: extmod/vfs_posix_file.c -msgid "poll on file not available on win32" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" msgstr "" -#: ports/espressif/common-hal/pulseio/PulseIn.c -msgid "pop from an empty PulseIn" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/pulseio/PulseIn.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c -#: shared-bindings/ps2io/Ps2.c -msgid "pop from empty %q" -msgstr "pop z prázdného %q" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "Je nutné použít několik kolíků 6 rgb, nikoli %d" + +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +msgstr "%d adresní pin, %d rgb pin a %d dlaždice indikuje výšku %d, ne %d" #: shared-bindings/socketpool/Socket.c msgid "port must be >= 0" msgstr "port musí být >= 0" -#: py/compile.c -msgid "positional arg after **" -msgstr "" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "buffer too small for requested bytes" +msgstr "buffer je příliš malý pro počet požadovaných bajtů" -#: py/compile.c -msgid "positional arg after keyword arg" -msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "Jméno nebo služba není známa" -#: py/objint_mpz.c -msgid "pow() 3rd argument cannot be 0" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." msgstr "" -#: py/objint_mpz.c -msgid "pow() with 3 arguments requires integers" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "pull masks conflict with direction masks" -msgstr "" +#: shared-bindings/storage/__init__.c shared-bindings/usb_audio/__init__.c +#: shared-bindings/usb_cdc/__init__.c shared-bindings/usb_hid/__init__.c +#: shared-bindings/usb_midi/__init__.c shared-bindings/usb_video/__init__.c +msgid "Cannot change USB devices now" +msgstr "Nelze změnit USB zařízení" -#: py/parse.c -msgid "raw f-strings are not supported" -msgstr "surové f-stringy nesjou podporované" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c +msgid "File not found" +msgstr "Soubor nenalezen" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "real and imaginary parts must be of equal length" +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" msgstr "" -#: py/builtinimport.c -msgid "relative import" +#: shared-bindings/traceback/__init__.c +msgid "Supply both or neither of %q and %q" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" -msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "zápis do souboru není dostupný" -#: extmod/ulab/code/ndarray_operators.c -msgid "results cannot be cast to specified type" -msgstr "" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "špatná výjimka" -#: py/compile.c -msgid "return annotation must be an identifier" +#: shared-bindings/usb_audio/USBSpeaker.c +msgid "destination must be an array of type 'h'" msgstr "" -#: py/emitnative.c -msgid "return expected '%q' but got '%q'" +#: shared-bindings/usb_audio/__init__.c +msgid "At least one of microphone and speaker must be enabled" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] duplicates another pin assignment" -msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "%q, %q, a %q musí mít všechny shodnou délku" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] is not on the same port as clock" +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +"Objekt byl deinicializován a nelze jej dále používat. Vytvořte nový objekt." -#: extmod/ulab/code/numpy/numerical.c -msgid "roll argument must be an ndarray" +#: shared-bindings/warnings/__init__.c +msgid "%q must be a subclass of %q" msgstr "" -#: py/objstr.c -msgid "rsplit(None,n)" -msgstr "" +#: shared-bindings/wifi/Monitor.c +msgid "%q out of bounds" +msgstr "%q je mimo hranice" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -msgid "sampling rate out of range" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Invalid hex password" +msgstr "Špatné heslo v hex" -#: py/modmicropython.c -msgid "schedule queue full" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "invalid hostname" +msgstr "špatný hostname" -#: py/builtinimport.c -msgid "script compilation not supported" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Invalid MAC address" +msgstr "Chybná MAC adresa" -#: py/nativeglue.c -msgid "set unsupported" -msgstr "set neoodporován" +#: shared-bindings/wifi/Radio.c +msgid "AuthMode.OPEN is not used with password" +msgstr "AuthMode.OPEN nepoužívá heslo" -#: extmod/ulab/code/numpy/random/random.c -msgid "shape must be None, and integer or a tuple of integers" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Invalid BSSID" +msgstr "Chybné BSSID" -#: extmod/ulab/code/ndarray.c -msgid "shape must be integer or tuple of integers" -msgstr "tvar musí být integer nebo tuple integerů" +#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c +msgid "Authentication failure" +msgstr "Autentizace selhala" -#: shared-module/msgpack/__init__.c -msgid "short read" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "Žádná síť s takovým SSID" + +#: shared-bindings/wifi/Radio.c +#, c-format +msgid "Unknown failure %d" +msgstr "Neznámé selhání %d" + +#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#, c-format +msgid "No I2C device at address: 0x%x" +msgstr "Žádné I2C zařízení na adrese: 0x%x" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Neplatná velikost bloku" + +#: shared-module/audiocore/__init__.c shared-module/usb_audio/USBMicrophone.c +msgid "The sample's %q does not match" msgstr "" -#: py/objstr.c -msgid "sign not allowed in string format specifier" +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" msgstr "" -#: py/objstr.c -msgid "sign not allowed with integer format specifier 'c'" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Only 8/16-bit mono/stereo is supported" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "size is defined for ndarrays only" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "buffer_size too small for source" +msgstr "" + +#: shared-module/audiomp3/MP3Decoder.c +msgid "Couldn't allocate decoder" +msgstr "Dekodér nelze přiřadit" + +#: shared-module/audiomp3/MP3Decoder.c +msgid "Failed to parse MP3 file" +msgstr "Soubor MP3 se nepodařilo analyzovat" + +#: shared-module/bitbangio/I2C.c +msgid "%q too long" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "size must match out.shape when used together" +#: shared-module/bitmapfilter/__init__.c +msgid "bitmap size and depth must match" msgstr "" -#: py/nativeglue.c -msgid "slice unsupported" +#: shared-module/bitmapfilter/__init__.c +msgid "unsupported bitmap depth" msgstr "" -#: py/objint.c py/sequence.c -msgid "small int overflow" +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" msgstr "" -#: main.c -msgid "soft reboot\n" -msgstr "" +#: shared-module/displayio/ColorConverter.c +msgid "Only one color can be transparent at a time" +msgstr "Pouze jedna barva může být nastavena jako transparentní" -#: extmod/ulab/code/numpy/numerical.c -msgid "sort argument must be an ndarray" -msgstr "" +#: shared-module/displayio/Group.c +msgid "Layer already in a group" +msgstr "Vrstva již v groupě je" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos array must be of shape (n_section, 6)" -msgstr "" +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass" +msgstr "Vrstva musí být Group nebo TileGrid" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos[:, 3] should be all ones" +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sosfilt requires iterable arguments" +#: shared-module/displayio/OnDiskBitmap.c +msgid "RLE-compressed BMP not supported" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source palette too large" -msgstr "zdrojová paleta je příliš velká" +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "Nelze číst data palety barev" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 2 or 65536" -msgstr "" +#: shared-module/displayio/__init__.c +msgid "Too many displays" +msgstr "Příliš mnoho displejů" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 65536" +#: shared-module/displayio/__init__.c +msgid "Too many display busses; forgot displayio.release_displays() ?" msgstr "" +"Příliš mnoho sběrnic displaye; nezapomněl si na displayio.release_displays()?" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 8" -msgstr "" +#: shared-module/displayio/bus_core.c +msgid "Unsupported display bus type" +msgstr "Nepodporovaná sběrnice dispalye" -#: extmod/modre.c -msgid "splitting with sub-captures" +#: shared-module/gifio/GifWriter.c +msgid "unsupported colorspace for GifWriter" msgstr "" -#: py/objstr.c -msgid "start/end indices" +#: shared-module/i2cdisplaybus/I2CDisplayBus.c +#: shared-module/is31fl3741/IS31FL3741.c +#, c-format +msgid "Unable to find I2C Display at %x" +msgstr "I2C display nenalezen na %x" + +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" msgstr "" -#: shared-bindings/random/__init__.c -msgid "stop not reachable from start" +#: shared-module/imagecapture/ParallelImageCapture.c +msgid "This microcontroller does not support continuous capture." +msgstr "Tento mikrokontrolér nepodporuje kontinuální snímání." + +#: shared-module/is31fl3741/FrameBuffer.c +msgid "LED mappings must match display size" +msgstr "Mapování LED musí korespondovat s velikostí displeje" + +#: shared-module/jpegio/JpegDecoder.c +msgid "Interrupted by output function" msgstr "" -#: py/stream.c shared-bindings/getpass/__init__.c -msgid "stream operation not supported" +#: shared-module/jpegio/JpegDecoder.c +msgid "Device error or wrong termination of input stream" msgstr "" -#: py/objarray.c py/objstr.c -msgid "string argument without an encoding" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient memory pool for the image" msgstr "" -#: py/objstrunicode.c -msgid "string index out of range" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient stream input buffer" msgstr "" -#: py/objstrunicode.c -#, c-format -msgid "string indices must be integers, not %s" +#: shared-module/jpegio/JpegDecoder.c +msgid "Parameter error" msgstr "" -#: py/objarray.c py/objstr.c -msgid "substring not found" +#: shared-module/jpegio/JpegDecoder.c +msgid "Data format error (may be broken data)" msgstr "" -#: py/compile.c -msgid "super() can't find self" +#: shared-module/jpegio/JpegDecoder.c +msgid "Right format but not supported" msgstr "" -#: extmod/modjson.c -msgid "syntax error in JSON" +#: shared-module/jpegio/JpegDecoder.c +msgid "Unsupported JPEG (may be progressive)" msgstr "" -#: extmod/modtime.c -msgid "ticks interval overflow" +#: shared-module/jpegio/JpegDecoder.c +msgid "%q() without %q()" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "timeout duration exceeded the maximum supported value" -msgstr "timeout překročil maximální podporovanou hodnotu" +#: shared-module/memorymonitor/AllocationAlarm.c +#, c-format +msgid "Attempt to allocate %d blocks" +msgstr "Pokus o alokování %d bloků" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "timeout must be < 655.35 secs" -msgstr "timeout musí být < 655.35 s" +#: shared-module/msgpack/__init__.c +msgid "short read" +msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -msgid "timeout waiting for flux" +#: shared-module/msgpack/__init__.c +msgid "no default packer" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: shared-module/floppyio/__init__.c -msgid "timeout waiting for index pulse" +#: shared-module/msgpack/__init__.c supervisor/shared/settings.c +msgid "Invalid format" +msgstr "Špatný formát" + +#: shared-module/paralleldisplaybus/ParallelBus.c +msgid "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." msgstr "" +#: shared-module/rgbmatrix/RGBMatrix.c +msgid "No timer available" +msgstr "Není k dispozici žádný časovač" + +#: shared-module/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Internal error #%d" +msgstr "Vnitřní chyba #%d" + #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" msgstr "" @@ -4126,276 +4466,289 @@ msgstr "" msgid "timeout waiting for v2 card" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "timer re-init" -msgstr "opětovný init timeru" +#: shared-module/sdcardio/SDCard.c +msgid "no SD card" +msgstr "není vložena SD karta" -#: shared-bindings/time/__init__.c -msgid "timestamp out of range for platform time_t" -msgstr "" +#: shared-module/sdcardio/SDCard.c +msgid "couldn't determine SD card version" +msgstr "nelze zjistit verzi SD karty" -#: extmod/ulab/code/ndarray.c -msgid "tobytes can be invoked for dense arrays only" -msgstr "" +#: shared-module/sdcardio/SDCard.c +msgid "no response from SD card" +msgstr "žádná odpověď z SD karty" -#: py/compile.c -msgid "too many args" -msgstr "příliš mnoho argumentů" +#: shared-module/sdcardio/SDCard.c +msgid "SD card CSD format not supported" +msgstr "CSD formát SD karty není podporován" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c -msgid "too many dimensions" -msgstr "příliš mnoho dimenzí" +#: shared-module/sdcardio/SDCard.c +msgid "can't set 512 block size" +msgstr "nelze nastavit velikost bloku 512" -#: extmod/ulab/code/ndarray.c -msgid "too many indices" -msgstr "" +#: shared-module/ssl/SSLSocket.c +msgid "Invalid socket for TLS" +msgstr "Chybný soket pro TLS" -#: py/asmthumb.c -msgid "too many locals for native method" -msgstr "" +#: shared-module/ssl/SSLSocket.c +msgid "invalid key" +msgstr "špatný klíč" -#: py/runtime.c -#, c-format -msgid "too many values to unpack (expected %d)" -msgstr "" +#: shared-module/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "špatný certifikár" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D arrays of equal length" +#: shared-module/storage/__init__.c +msgid "Mount point directory missing" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D iterables" +#: shared-module/storage/__init__.c +msgid "Cannot remount path when visible via USB." msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "tuple/list má špatnou délku" +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' a 'O' nejsou podporované typy formátů" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_driver_install returned esp-idf error #%d" +#: shared-module/struct/__init__.c +msgid "buffer size must match format" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_start returned esp-idf error #%d" -msgstr "" +#: shared-module/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q musí být pole typu 'h'" -#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c -msgid "tx and rx cannot both be None" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" msgstr "" -#: py/objtype.c -msgid "type '%q' is not an acceptable base type" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" msgstr "" -#: py/objtype.c -msgid "type is not an acceptable base type" -msgstr "" +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "Žádný pulldown na pinu; doporučeno 1Mohm" -#: py/runtime.c -msgid "type object '%q' has no attribute '%q'" -msgstr "" +#: shared-module/usb/core/Device.c +msgid "No usb host port initialized" +msgstr "Žádný USB host port není inicializován" -#: py/objtype.c -msgid "type takes 1 or 3 arguments" +#: shared-module/usb/core/Device.c +msgid "Pipe error" msgstr "" -#: py/objint_longlong.c -msgid "ulonglong too large" -msgstr "" +#: shared-module/usb/core/Device.c +msgid "No configuration set" +msgstr "Konfigurace není nastavena" + +#: shared-module/usb_hid/Device.c +msgid "USB busy" +msgstr "USB zaneprázdněno" + +#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Rectangle.c +msgid "can only have one parent" +msgstr "může mít pouze jednoho rodiče" -#: py/parse.c -msgid "unexpected indent" -msgstr "neočekávané odsazení" +#: shared-module/vectorio/Polygon.c +msgid "Polygon needs at least 3 points" +msgstr "Polygon potřebuje nejméně 3 body" -#: py/bc.c -msgid "unexpected keyword argument" -msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "Opětovné připojování" -#: py/argcheck.c py/bc.c py/objnamedtuple.c -#: shared-bindings/traceback/__init__.c -msgid "unexpected keyword argument '%q'" -msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "Ok" -#: py/lexer.c -msgid "unicode name escapes" -msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Vypnuto" -#: py/parse.c -msgid "unindent doesn't match any outer indent level" -msgstr "" +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[zkráceno kvůli délce]" -#: py/objstr.c -#, c-format -msgid "unknown conversion specifier %c" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" +"\n" +"Jste v bezpečnostním režimu z důvodu:\n" -#: py/objstr.c -msgid "unknown format code '%c' for object of type '%q'" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Power dipped. Make sure you are providing enough power." +msgstr "Pokles napájení. Zkontroluj, zda je k dispozici dostatečné napájení." -#: py/compile.c -msgid "unknown type" -msgstr "neznámý typ" +#: supervisor/shared/safe_mode.c +msgid "You pressed the BOOT button at start up" +msgstr "Při spuštění jsi stiskl tlačítko BOOT" -#: py/compile.c -msgid "unknown type '%q'" -msgstr "neznámý typ '%q'" +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." +msgstr "Při spuštění jsi stiskl tlačítko reset." -#: py/objstr.c -#, c-format -msgid "unmatched '%c' in format" -msgstr "neshoduje se '%c' ve formátu" +#: supervisor/shared/safe_mode.c +msgid "CIRCUITPY drive could not be found or created." +msgstr "Disk CIRCUITPY nelze nalézt nebo vytvořit." -#: py/objtype.c py/runtime.c -msgid "unreadable attribute" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "The `microcontroller` module was used to boot into safe mode." +msgstr "Modul `microcontroller` byl použit pro spuštění do nouzového režimu." -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -msgid "unsupported %q type" -msgstr "nepodporovaný typ% q" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "Chyba v safemode.py." -#: py/emitinlinethumb.c -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" +#: supervisor/shared/safe_mode.c +msgid "Stack overflow. Increase stack size." msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "USB devices need more endpoints than are available." +msgstr "USB zařízení potřebují více endpointů než je k dispozici." -#: shared-module/bitmapfilter/__init__.c -msgid "unsupported bitmap depth" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "USB devices specify too many interface names." +msgstr "USB zařízení používají příliš mnoho názvů rozhraní." -#: shared-module/gifio/GifWriter.c -msgid "unsupported colorspace for GifWriter" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Boot device must be first (interface #0)." +msgstr "Bootovací zařízení musí být první (rozhraní #0)." -#: shared-bindings/bitmaptools/__init__.c -msgid "unsupported colorspace for dither" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Internal watchdog timer expired." +msgstr "Interní watchdog timer expiroval." -#: py/objstr.c -#, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython core code crashed hard. Whoops!\n" +msgstr "Jádro kódu CircuitPython tvrdě havarovalo. Jejda!\n" -#: py/runtime.c -msgid "unsupported type for %q: '%s'" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "Alokace heapu při neběžícím VM." -#: py/runtime.c -msgid "unsupported type for operator" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Failed to write internal flash." +msgstr "Nepodařilo se zapsat do interní paměti." -#: py/runtime.c -msgid "unsupported types for %q: '%q', '%q'" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Hard fault: memory access or instruction error." +msgstr "Fatální chyba: přístup k paměti nebo chyba instrukce." -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols is too high" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Chyba přerušení." -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols keyword must be specified" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "NLR skok selhal. Pravděpodobně poškozením paměti." -#: py/objint.c -#, c-format -msgid "value must fit in %d byte(s)" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate to the heap." msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "value out of range of target" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "Fatální chyby firmware třetí strany." -#: extmod/moddeflate.c -msgid "wbits" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Please file an issue with your program at github.com/adafruit/circuitpython/" +"issues." msgstr "" +"\n" +"Prosím, založte issue s vaším programem na github.com/adafruit/circuitpython/" +"issues." -#: shared-bindings/bitmapfilter/__init__.c +#: supervisor/shared/safe_mode.c msgid "" -"weights must be a sequence with an odd square number of elements (usually 9 " -"or 25)" +"\n" +"Press reset to exit safe mode.\n" msgstr "" +"\n" +"Stiskněte reset pro ukončení nouzového režimu.\n" -#: shared-bindings/bitmapfilter/__init__.c -msgid "weights must be an object of type %q, %q, %q, or %q, not %q " -msgstr "" +#: supervisor/shared/settings.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "Došlo k chybě při načítání '%s'\n" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "width must be greater than zero" -msgstr "" +#: supervisor/shared/settings.c +msgid "Invalid unicode escape" +msgstr "Neplatná unicode escape sekvence" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "Wi-Fi: " +msgstr "Wi-Fi: " -#: ports/raspberrypi/common-hal/wifi/Monitor.c -msgid "wifi.Monitor not available" -msgstr "wifi.Monitor není dostupný" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "off" +msgstr "vypnuto" -#: shared-bindings/_bleio/Adapter.c -msgid "window must be <= interval" -msgstr "" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "No IP" +msgstr "Není IP" -#: extmod/ulab/code/numpy/numerical.c -msgid "wrong axis index" -msgstr "" +#~ msgid "asm overflow" +#~ msgstr "přetečení v asm" -#: extmod/ulab/code/numpy/create.c -msgid "wrong axis specified" -msgstr "" +#, c-format +#~ msgid "Buffer + offset too small %d %d %d" +#~ msgstr "Vyrovnávací paměť + offset je příliš malý %d %d %d" -#: extmod/ulab/code/numpy/io/io.c -msgid "wrong dtype" -msgstr "špatný dtype" +#~ msgid "Byte buffer must be 16 bytes." +#~ msgstr "Buffer musí být dlouhý 16 bajtů." -#: extmod/ulab/code/numpy/transform.c -msgid "wrong index type" -msgstr "špatný typ indexu" +#~ msgid "UUID integer value must be 0-0xffff" +#~ msgstr "UUID integer musí být 0-0xffff" -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c -#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c -#: extmod/ulab/code/numpy/vector.c -msgid "wrong input type" -msgstr "" +#~ msgid "initial_value length is wrong" +#~ msgstr "délka initial_value je chybná" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of condition array" -msgstr "" +#, c-format +#~ msgid "Invalid byte %.*s" +#~ msgstr "Špatný byte %.*s" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of index array" -msgstr "" +#~ msgid "Key not found" +#~ msgstr "Klíč nenalezen" -#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c -msgid "wrong number of arguments" -msgstr "" +#, c-format +#~ msgid "%%c requires int or char" +#~ msgstr "%%c vyžaduje int nebo char" -#: py/runtime.c -msgid "wrong number of values to unpack" -msgstr "" +#~ msgid "'%q' object is not callable" +#~ msgstr "Objekt '%q' nelze zavolat" -#: extmod/ulab/code/numpy/vector.c -msgid "wrong output type" -msgstr "" +#~ msgid "raw f-strings are not supported" +#~ msgstr "surové f-stringy nesjou podporované" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be an ndarray" -msgstr "" +#~ msgid "Unsupported format" +#~ msgstr "Nepodporovaný formát" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of float type" -msgstr "" +#~ msgid "Wifi is not enabled" +#~ msgstr "Wifi není povoleno" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of shape (n_section, 2)" -msgstr "" +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "Není možné znovu připojit '/', pokud je viditelné pomocí USB." + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Datový blok musí následovat fmt blok" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Podporovány jsou pouze černobílé, indexované 4 bpp nebo 8 bpp a 16 bpp " +#~ "nebo vyšší BMP: bitmapa má %d bpp" + +#~ msgid "init I2C" +#~ msgstr "inicializace I2C" #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Délka vyrovnávací paměti musí být násobkem 512" @@ -4596,7 +4949,7 @@ msgstr "" #~ msgid "'continue' outside loop" #~ msgstr "'continue' je volán mimo cyklus" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "Objekt 'coroutine' není iterátor" #~ msgid "64 bit types" @@ -4656,8 +5009,8 @@ msgstr "" #~ msgstr "IV musí být dlouhé %d bajtů" #~ msgid "" -#~ "Incompatible .mpy file. Please update all .mpy files. See http://adafru." -#~ "it/mpy-update for more info." +#~ "Incompatible .mpy file. Please update all .mpy files. See http://" +#~ "adafru.it/mpy-update for more info." #~ msgstr "" #~ "Nekompatibilní soubor .mpy. Aktualizujte prosím všechny soubory .mpy. " #~ "Další informace naleznete na adrese http://adafru.it/mpy-update." diff --git a/locale/de_DE.po b/locale/de_DE.po index 9f44b23c905..1ac8df55314 100644 --- a/locale/de_DE.po +++ b/locale/de_DE.po @@ -6,14 +6,14 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2024-06-18 19:09+0000\n" -"Last-Translator: Xfox20 <136956349+Xfox20@users.noreply.github.com>\n" +"PO-Revision-Date: 2025-06-29 13:01+0000\n" +"Last-Translator: MAE \n" "Language: de_DE\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.6-dev\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" @@ -94,7 +94,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "%q und %q enthalten doppelte Pins" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q und %q müssen unterschiedlich sein" @@ -115,7 +115,11 @@ msgstr "%q enthält doppelte Pins" msgid "%q failure: %d" msgstr "%q Fehler: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q in %q muss vom Typ %q oder %q sein, nicht %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q in %q muss von Typ %q sein, nicht %q" @@ -167,7 +171,7 @@ msgstr "%q länge muss kleiner oder gleich %d sein" msgid "%q length must be >= %d" msgstr "%q länge muss größer oder gleich %d sein" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "%q von %q nach %q versetzt" @@ -228,6 +232,7 @@ msgstr "%q muss ein Vielfaches von 8 sein." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q muss von Typ %q oder %q sein, nicht %q" @@ -237,6 +242,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "%q muss vom Typ %q, %q oder %q sein, und nicht %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q muss von Typ %q sein, nicht %q" @@ -283,7 +289,8 @@ msgstr "%q() ohne %q()" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q und %q müssen alle die gleiche Länge haben" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -297,7 +304,7 @@ msgstr "%q[%u] schiebt mehr Bits raus als Pins vorhanden sind" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "%q[%u] uses extra pin" -msgstr "" +msgstr "%q[%u] verwendet zusätzlichen Pin" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "%q[%u] waits on input outside of count" @@ -317,7 +324,7 @@ msgid "'%q' object does not support '%q'" msgstr "'%q' Objekt unterstützt '%q' nicht" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "'%q' Objekt ist kein Iterator" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -325,7 +332,7 @@ msgid "'%q' object is not callable" msgstr "'%q' Objekt ist kein callable" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "'%q' Objekt ist nicht iterierbar" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -415,7 +422,7 @@ msgstr "'await' außerhalb einer Funktion" #: py/compile.c msgid "'break'/'continue' outside loop" -msgstr "'break'/'continue' ausserhalb einer Schleife" +msgstr "'break'/'continue' außerhalb der Schleife" #: py/compile.c msgid "'data' requires at least 2 arguments" @@ -431,7 +438,7 @@ msgstr "'label' erfordert genau ein Argument" #: py/emitnative.c msgid "'not' not implemented" -msgstr "" +msgstr "'not' nicht implementiert" #: py/compile.c msgid "'return' outside function" @@ -488,7 +495,7 @@ msgstr "Adressbereich nicht erlaubt" #: shared-bindings/memorymap/AddressRange.c msgid "Address range wraps around" -msgstr "" +msgstr "Der Adressbereich umfasst folgende Bereiche" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" @@ -552,7 +559,6 @@ msgstr "Alle Timer für diesen Pin werden bereits benutzt" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Alle Timer werden benutzt" @@ -565,6 +571,10 @@ msgstr "Bereits am Anbieten (advertising)." msgid "Already have all-matches listener" msgstr "All-Matchers-Listener bereits vorhanden" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Bereits in Arbeit" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -574,6 +584,7 @@ msgstr "Läuft bereits" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Sucht bereits nach Wifi-Netzwerken" @@ -600,6 +611,10 @@ msgstr "Array muss Halbwörter enthalten (type 'H')" msgid "Array values should be single bytes." msgstr "Array-Werte sollten aus Einzelbytes bestehen." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "Asynchroner SPI-Transfer auf diesem Bus im Gange, warten Sie weiter." + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -609,6 +624,11 @@ msgstr "Versuche %d Blöcke zu allokieren" msgid "Audio conversion not implemented" msgstr "Audio-Konvertierung nicht implementiert" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Audioquellenfehler" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN wird mit Passwort nicht verwendet" @@ -640,7 +660,7 @@ msgstr "Unterhalb der minimalen Frame Rate" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must be sequential GPIO pins" -msgstr "" +msgstr "Bittakt und Wortauswahl müssen aufeinanderfolgende GPIO-Pins sein" #: shared-bindings/bitmaptools/__init__.c msgid "Bitmap size and bits per value must match" @@ -684,7 +704,7 @@ msgstr "Die Pufferlänge %d ist zu groß. Sie muss kleiner als %d sein" #: shared-module/sdcardio/SDCard.c #, c-format msgid "Buffer must be a multiple of %d bytes" -msgstr "" +msgstr "Puffer muss ein Vielfaches von %d Bytes sein" #: shared-bindings/_bleio/PacketBuffer.c #, c-format @@ -744,6 +764,12 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "Kann nur auf zwei Pins Alarm als low aus Deep Sleep auslösen." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" +"AudioOut kann nicht erstellt werden, da ein kontinuierlicher Kanal bereits " +"geöffnet ist" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -790,8 +816,9 @@ msgid "Cannot record to a file" msgstr "Aufnahme in eine Datei nicht möglich" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "'/' kann nicht wiedereingehängt werden, wenn per USB sichtbar." +msgid "Cannot remount path when visible via USB." +msgstr "" +"Der Pfad kann nicht neu gemountet werden, wenn er über USB sichtbar ist." #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -806,6 +833,10 @@ msgstr "RTS oder CTS können im RS485-Modus nicht angegeben werden" msgid "Cannot subclass slice" msgstr "Slice kann keine sub-klasse sein" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "GPIO0..15 kann nicht zusammen mit GPIO32..47 verwendet werden" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "Kann nicht durch Flanke an Pin geweckt werden, sondern nur durch Pegel" @@ -842,6 +873,10 @@ msgstr "Koordinaten-Arrays haben unterschiedliche Längen" msgid "Coordinate arrays types have different sizes" msgstr "Typen der Koordinaten-Arrays haben unterschiedliche Längen" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "Kann nicht im ROS-Thema veröffentlicht werden" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "Konnte Adresse nicht setzen" @@ -854,6 +889,11 @@ msgstr "Interrupt konnte nicht gestartet werden, RX beschäftigt" msgid "Couldn't allocate decoder" msgstr "Decoder konnte nicht zugeordnet werden" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "Kritischer ROS-Fehler beim Soft-Reboot, Reset erforderlich: %d" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC-Kanal-Initialisierungsfehler" @@ -871,10 +911,6 @@ msgstr "DAC wird schon benutzt" msgid "Data 0 pin must be byte aligned" msgstr "Data 0 pin muss am Byte ausgerichtet sein" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Dem fmt Block muss ein Datenblock folgen" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "Datenformatfehler (Möglicherweise beschädigte Daten)" @@ -899,7 +935,7 @@ msgstr "Die Zielkapazität ist kleiner als destination_length." #: shared-module/jpegio/JpegDecoder.c msgid "Device error or wrong termination of input stream" -msgstr "" +msgstr "Gerätefehler oder falsche Terminierung des Eingangsstroms" #: ports/nordic/common-hal/audiobusio/I2SOut.c msgid "Device in use" @@ -976,12 +1012,14 @@ msgstr "Mutex konnte nicht akquiriert werden. Status: 0x%04x" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Failed to add service TXT record" -msgstr "" +msgstr "Fehler beim Hinzufügen des TXT-Diensteintrags" #: shared-bindings/mdns/Server.c msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" +"Fehler beim Hinzufügen des TXT-Diensteintrags; Nicht-Zeichenfolge oder Bytes " +"in txt_records gefunden" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" @@ -1008,15 +1046,49 @@ msgstr "Verbindung fehlgeschlagen: interner Fehler" msgid "Failed to connect: timeout" msgstr "Verbindung nicht erfolgreich: timeout" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" +"Kontinuierliche Kanäle konnten nicht erstellt werden: ungültiges Argument" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" +"Kontinuierliche Kanäle konnten nicht erstellt werden: ungültiger Status" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Kontinuierliche Kanäle konnten nicht erstellt werden: kein Speicher" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Kontinuierliche Kanäle konnten nicht erstellt werden: nicht gefunden" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Kontinuierliche Aktivierung fehlgeschlagen" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "MP3-Datei konnte nicht analysiert werden" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Rückruf für kontinuierliche Ereignisse konnte nicht registriert werden" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Mutex konnte nicht freigegeben werden. Status: 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "Hostname konnte nicht gesetzt werden" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Start von asynchronem Audio fehlgeschlagen" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Interner Flash konnte nicht geschrieben werden." @@ -1025,12 +1097,14 @@ msgstr "Interner Flash konnte nicht geschrieben werden." msgid "File exists" msgstr "Datei existiert" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "Datei nicht gefunden" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Filter zu komplex" @@ -1055,7 +1129,7 @@ msgstr "Für den L8-Farbraum muss die Eingabe-Bitmap 8 Bit pro Pixel aufweisen" msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "Für RGB-Farbräume muss die Eingabe-Bitmap 16 Bit pro Pixel haben" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "Format nicht unterstützt" @@ -1087,7 +1161,7 @@ msgstr "Gruppe schon benutzt" #: supervisor/shared/safe_mode.c msgid "Hard fault: memory access or instruction error." -msgstr "" +msgstr "Harter Fehler: Speicherzugriff- oder Anweisungsfehler." #: ports/mimxrt10xx/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c @@ -1166,9 +1240,10 @@ msgstr "Unzureichender Speicherpool für das Bild" #: shared-module/jpegio/JpegDecoder.c msgid "Insufficient stream input buffer" -msgstr "" +msgstr "Unzureichender Stream-Eingabepuffer" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "Schnittstelle muss gestartet sein" @@ -1224,14 +1299,16 @@ msgstr "Unterbrochen durch Ausgabefunktion" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "Ungültiger %q" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-module/aurora_epaper/aurora_framebuffer.c msgid "Invalid %q and %q" -msgstr "" +msgstr "Ungültiges %q und %q" #: ports/atmel-samd/common-hal/microcontroller/Pin.c #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c @@ -1257,6 +1334,10 @@ msgstr "Ungültige BSSID" msgid "Invalid MAC address" msgstr "Ungültige MAC-Adresse" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "Ungültige ROS-Domain ID" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Ungültiges Argument" @@ -1288,6 +1369,7 @@ msgid "Invalid hex password" msgstr "Ungültiges Hex-Passwort" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Ungültige Multicast-MAC-Adresse" @@ -1300,6 +1382,7 @@ msgid "Invalid socket for TLS" msgstr "Ungültiges Socket für TLS" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "Ungültiger Zustand" @@ -1334,6 +1417,8 @@ msgstr "Ebene muss eine Gruppe oder eine TileGrid Subklasse sein" #: shared-bindings/audiocore/RawSample.c msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" +"Die Länge von %q muss ein gerades Vielfaches von channel_count * type_size " +"sein" #: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" @@ -1342,7 +1427,12 @@ msgstr "MAC Adresse war ungültig" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/espressif/common-hal/_bleio/Descriptor.c msgid "MITM security not supported" -msgstr "" +msgstr "MITM-Sicherheit wird nicht unterstützt" + +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "MMC/SDIO-Taktfehler %x" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" @@ -1387,9 +1477,10 @@ msgstr "jmp_pin fehlt. %q[%u] springt basierend auf dem Pin" #: shared-module/storage/__init__.c msgid "Mount point directory missing" -msgstr "" +msgstr "Einhängepunktverzeichnis fehlt" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Muss eine %q Unterklasse sein." @@ -1529,6 +1620,10 @@ msgstr "Kein Pull-up gefunden an SDA oder SCL; Verkabelung prüfen" msgid "No pulldown on pin; 1Mohm recommended" msgstr "Kein Pulldown-Widerstand am Pin; 1 MOhm wird vorgeschlagen" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "Kein Pullup-Widerstand am Pin; 1Mohm wird vorgeschlagen" + #: py/moderrno.c msgid "No space left on device" msgstr "Kein Speicherplatz mehr verfügbar auf dem Gerät" @@ -1547,7 +1642,7 @@ msgstr "Kein Timer verfügbar" #: shared-module/usb/core/Device.c msgid "No usb host port initialized" -msgstr "" +msgstr "Kein USB-Host-Port initialisiert" #: ports/nordic/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" @@ -1576,7 +1671,7 @@ msgstr "Nicht unterstützter JPEG-Standard" #: ports/espressif/common-hal/sdioio/SDCard.c #, c-format msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +msgstr "Die Anzahl der data_pins muss %d oder %d sein, nicht %d" #: shared-bindings/util.c msgid "" @@ -1632,15 +1727,6 @@ msgstr "Nur Edge Detection ist für diese Hardware verfügbar" msgid "Only int or string supported for ip" msgstr "Nur Int oder String werden unterstützt für IP" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Nur monochrome, indizierte 4bpp oder 8bpp, und 16bpp oder größere BMPs " -"unterstützt: %d bpp wurden gegeben" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "Nur ein %q kann im Deep-Sleep gesetzt werden." @@ -1691,6 +1777,7 @@ msgstr "Kein Speicher mehr verfügbar" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Keine Sockets mehr verfügbar" @@ -1710,6 +1797,11 @@ msgstr "PWM-Stück wird bereits verwendet" msgid "PWM slice channel A already in use" msgstr "PWM-Stück-Kanal A wird bereits verwendet" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" +"Die Paketpuffer für eine SPI-Übertragung müssen die gleiche Länge haben." + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "Parameter-Fehler" @@ -1768,7 +1860,7 @@ msgstr "Pins muss ein geteiltes PWM-Stück sein" #: shared-module/usb/core/Device.c msgid "Pipe error" -msgstr "" +msgstr "Pipe-Fehler" #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" @@ -1815,6 +1907,10 @@ msgstr "Programm-Größe ist ungültig" msgid "Program too long" msgstr "Programm zu lang" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "Herausgeber können nur aus einem übergeordneten Knoten erstellt werden" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull wird nicht verwendet, wenn die Richtung output ist." @@ -1835,6 +1931,26 @@ msgstr "RNG DeInit-Fehler" msgid "RNG Init Error" msgstr "RNG-Init-Fehler" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "ROS konnte nicht initialisiert werden. Ist der Agent verbunden?" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "ROS interner Setup-Fehler" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "ROS-Speicherzuweisungsfehler" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "ROS-Knoten konnte nicht initialisiert werden" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "ROS-Thema konnte nicht initialisiert werden" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1917,7 +2033,7 @@ msgstr "SDIO GetCardInfo-Fehler %d" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO Init Error %x" -msgstr "" +msgstr "SDIO-Init-Fehler %x" #: ports/espressif/common-hal/busio/SPI.c msgid "SPI configuration failed" @@ -1966,11 +2082,13 @@ msgstr "Slice und Wert (value) haben unterschiedliche Längen." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Slices werden nicht unterstützt" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool kann nur mit wifi.radio verwendet werden" @@ -1984,7 +2102,7 @@ msgstr "Gib genau einen von data0 oder data_pins an" #: supervisor/shared/safe_mode.c msgid "Stack overflow. Increase stack size." -msgstr "" +msgstr "Stapelüberlauf. Stapelgröße erhöhen." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2013,22 +2131,9 @@ msgstr "" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "Die Länge von rgb_pins muss 6, 12, 18, 24 oder 30 betragen" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" -"Das bits_per_sample des Samples stimmt nicht mit dem des Mixers überein" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Die Kanalanzahl des Samples stimmt nicht mit der des Mischers überein" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "Die Abtastrate der Probe stimmt nicht mit der des Mischers überein" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "Der Vorzeichentyp des Samples stimmt nicht mit dem des Mixers überein" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "Der %q-Wert der Probe stimmt nicht überein" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2050,7 +2155,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "Die Kachelhöhe muss die Bitmaphöhe genau teilen" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Kachelindex außerhalb der Grenzen" @@ -2058,6 +2165,10 @@ msgstr "Kachelindex außerhalb der Grenzen" msgid "Tile width must exactly divide bitmap width" msgstr "Die Kachelbreite muss die Bitmap-Breite genau teilen" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "TilePaletteMapper darf nur einmal an ein TileGrid gebunden werden" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "Zeit liegt in der Vergangenheit." @@ -2079,7 +2190,7 @@ msgstr "Zu viele Kanäle im sample." #: ports/espressif/common-hal/_bleio/Characteristic.c msgid "Too many descriptors" -msgstr "" +msgstr "Zu viele Deskriptoren" #: shared-module/displayio/__init__.c msgid "Too many display busses; forgot displayio.release_displays() ?" @@ -2158,7 +2269,7 @@ msgstr "Der UUID-Wert ist kein str-, int- oder Byte-Puffer" #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Unable to access unaligned IO register" -msgstr "" +msgstr "Zugriff auf nicht ausgerichtetes EA-Register nicht möglich" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -2169,7 +2280,7 @@ msgstr "Konnte keine Buffer für Vorzeichenumwandlung allozieren" #: supervisor/shared/safe_mode.c msgid "Unable to allocate to the heap." -msgstr "" +msgstr "Die Zuweisung zum Heap ist nicht möglich." #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" @@ -2189,6 +2300,12 @@ msgstr "Parser konnte nicht gestartet werden" msgid "Unable to read color palette data" msgstr "Konnte Farbpalettendaten nicht lesen" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" +"CAN-Nachricht kann nicht gesendet werden: alle Sende-Nachrichtenpuffer sind " +"belegt" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2285,22 +2402,19 @@ msgstr "Nicht unterstützter Farbraum" msgid "Unsupported display bus type" msgstr "Nicht unterstützter display bus type" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Nicht unterstütztes Format" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "Hash Algorithmus wird nicht unterstützt" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" -msgstr "" +msgstr "Nicht unterstützter Sockeltyp" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update failed" -msgstr "" +msgstr "Aktualisierung fehlgeschlagen" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c @@ -2352,9 +2466,11 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "WLAN ist nicht aktiviert" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "WiFi ist nicht aktiviert" #: main.c msgid "Woken up by alarm.\n" @@ -2376,6 +2492,7 @@ msgstr "Beide Knöpfe wurden beim Starten gedrückt." #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "Knopf A wurde beim Starten gedrückt." @@ -2389,6 +2506,7 @@ msgstr "Der BOOT-Knopf wurde beim Starten gedrückt" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "Der BOOT-Knopf wurde beim Starten gedrückt." @@ -2449,6 +2567,10 @@ msgstr "ein Byte-ähnliches Objekt ist erforderlich" msgid "addresses is empty" msgstr "addresses ist leer" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "spielt bereits" + #: py/compile.c msgid "annotation must be an identifier" msgstr "Die Annotation muss ein Bezeichner sein" @@ -2476,6 +2598,7 @@ msgstr "argsort ist für flattened Arrays nicht implementiert" #: extmod/ulab/code/numpy/random/random.c msgid "argument must be None, an integer or a tuple of integers" msgstr "" +"Das Argument muss None, eine Ganzzahl oder ein Tupel von Ganzzahlen sein" #: py/compile.c msgid "argument name reused" @@ -2509,7 +2632,7 @@ msgstr "Array/Bytes auf der rechten Seite erforderlich" #: py/asmxtensa.c msgid "asm overflow" -msgstr "" +msgstr "ASM-Überlauf" #: py/compile.c msgid "async for/with outside async function" @@ -2527,6 +2650,10 @@ msgstr "Versuch, argmin/argmax einer leeren Sequenz zu ermitteln" msgid "attributes not supported" msgstr "Attribute werden nicht unterstützt" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "Audioformat wird nicht unterstützt" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "Achse außerhalb des Wertebereichs" @@ -2563,6 +2690,10 @@ msgstr "Falscher Typcode" msgid "binary op %q not implemented" msgstr "Der binäre Operator %q ist nicht implementiert" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth muss 8, 16, 24 oder 32 sein." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "Bitmap-Größen und -Tiefe müssen übereinstimmen" @@ -2575,6 +2706,15 @@ msgstr "Bitmap-Größen müssen übereinstimmen" msgid "bits must be 32 or less" msgstr "bits müssen 32 oder kleiner sein" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample muss 16 sein" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "Es müssen 8 oder 16 bits_per_sample sein" @@ -2609,7 +2749,7 @@ msgstr "Der Puffer ist zu klein für die angefragten Bytes" #: py/emitbc.c msgid "bytecode overflow" -msgstr "" +msgstr "Bytecode-Überlauf" #: py/objarray.c msgid "bytes length not a multiple of item size" @@ -2658,7 +2798,7 @@ msgstr "kann keinem Ausdruck zuweisen" msgid "can't cancel self" msgstr "kann self nicht abbrechen" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "kann %q nicht zu %q konvertieren" @@ -2715,7 +2855,7 @@ msgstr "Eine binäre Operation zwischen '%q' und '%q' ist nicht möglich" #: py/emitnative.c msgid "can't do unary op of '%q'" -msgstr "" +msgstr "kann keine unäre Operation von '%q' durchführen" #: py/emitnative.c msgid "can't implicitly convert '%q' to 'bool'" @@ -2783,7 +2923,7 @@ msgstr "" #: py/objcomplex.c msgid "can't truncate-divide a complex number" -msgstr "" +msgstr "kann eine komplexe Zahl nicht kürzen und dividieren" #: extmod/modasyncio.c msgid "can't wait" @@ -3127,7 +3267,7 @@ msgid "format" msgstr "Format" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "Format erfordert ein Wörterbuch (dict)" #: py/objdeque.c @@ -3223,7 +3363,7 @@ msgstr "import * nicht auf Modulebene" #: py/persistentcode.c msgid "incompatible .mpy arch" -msgstr "" +msgstr "inkompatible .mpy-Architektur" #: py/persistentcode.c msgid "incompatible .mpy file" @@ -3263,10 +3403,6 @@ msgstr "Indizes müssen Integer sein" msgid "indices must be integers, slices, or Boolean lists" msgstr "Indizes müssen Integer, Slices oder Boolesche Listen sein" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "initialisiere I2C" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "Ausgangswerte müssen iterierbar sein" @@ -3367,7 +3503,7 @@ msgstr "Das Intervall muss im Bereich %s-%s sein" #: py/compile.c msgid "invalid arch" -msgstr "" +msgstr "ungültige Architektur" #: shared-bindings/bitmaptools/__init__.c #, c-format @@ -3454,6 +3590,8 @@ msgstr "" #: py/argcheck.c msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" +"Schlüsselwortargument(e) nicht umgesetzt - nutze stattdessen normale " +"Argumente" #: py/emitinlinethumb.c py/emitinlinextensa.c msgid "label '%q' not defined" @@ -3463,10 +3601,6 @@ msgstr "Label '%q' nicht definiert" msgid "label redefined" msgstr "Label neu definiert" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "Der Pegel muss zwischen 0 und 1 liegen" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs und rhs sollten kompatibel sein" @@ -3600,7 +3734,7 @@ msgid "must use keyword argument for key function" msgstr "muss Schlüsselwortargument für key function verwenden" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "Name '%q' ist nirgends definiert worden (Schreibweise kontrollieren)" #: py/runtime.c @@ -3609,7 +3743,7 @@ msgstr "Dieser Name ist nirgends definiert worden (Schreibweise kontrollieren)" #: py/qstr.c msgid "name too long" -msgstr "" +msgstr "Name zu lang" #: py/persistentcode.c msgid "native code in .mpy unsupported" @@ -3881,7 +4015,7 @@ msgstr "Ausgabe-Array ist zu klein" #: extmod/ulab/code/numpy/random/random.c msgid "out has wrong type" -msgstr "" +msgstr "Ausgabe hat den falschen Typ" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for complex dtype" @@ -3909,11 +4043,11 @@ msgstr "Außerhalb des Bereichs des Ziels" #: extmod/ulab/code/numpy/random/random.c msgid "output array has wrong type" -msgstr "" +msgstr "Ausgabe-Array hat einen falschen Typ" #: extmod/ulab/code/numpy/random/random.c msgid "output array must be contiguous" -msgstr "" +msgstr "Ausgabe-Array muss zusammenhängend sein" #: py/objint_mpz.c msgid "overflow converting long int to machine word" @@ -3959,11 +4093,11 @@ msgstr "Port muss >= 0 sein" #: py/compile.c msgid "positional arg after **" -msgstr "" +msgstr "Positionsargument nach **" #: py/compile.c msgid "positional arg after keyword arg" -msgstr "" +msgstr "Positionsargument nach Schlüsselwortargument" #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" @@ -4024,6 +4158,10 @@ msgstr "Roll-Argument muss ein ndarray sein" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed muss wahr sein" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4043,7 +4181,7 @@ msgstr "nicht unterstützt" #: extmod/ulab/code/numpy/random/random.c msgid "shape must be None, and integer or a tuple of integers" -msgstr "" +msgstr "Form muss Keine, eine Ganzzahl oder ein Tupel von Ganzenahlen sein" #: extmod/ulab/code/ndarray.c msgid "shape must be integer or tuple of integers" @@ -4067,7 +4205,7 @@ msgstr "Größe ist nur für ndarrays definiert" #: extmod/ulab/code/numpy/random/random.c msgid "size must match out.shape when used together" -msgstr "" +msgstr "size muss bei gemeinsamer Verwendung mit out.shape übereinstimmen" #: py/nativeglue.c msgid "slice unsupported" @@ -4115,7 +4253,7 @@ msgstr "source_bitmap muss value_count von 8 haben" #: extmod/modre.c msgid "splitting with sub-captures" -msgstr "" +msgstr "Aufteilung mit Untererfassungen" #: py/objstr.c msgid "start/end indices" @@ -4156,7 +4294,7 @@ msgstr "Syntaxfehler in JSON" #: extmod/modtime.c msgid "ticks interval overflow" -msgstr "" +msgstr "Ticks Intervallüberlauf" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "timeout duration exceeded the maximum supported value" @@ -4168,12 +4306,12 @@ msgstr "timeout muss kleiner als 655.35 Sekunden sein" #: ports/raspberrypi/common-hal/floppyio/__init__.c msgid "timeout waiting for flux" -msgstr "" +msgstr "Zeitüberschreitung beim Warten auf Fluss" #: ports/raspberrypi/common-hal/floppyio/__init__.c #: shared-module/floppyio/__init__.c msgid "timeout waiting for index pulse" -msgstr "" +msgstr "Zeitüberschreitung beim Warten auf Indeximpuls" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" @@ -4243,11 +4381,11 @@ msgid "tx and rx cannot both be None" msgstr "tx und rx können nicht beide None sein" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "Typ '%q' ist kein akzeptierter Basis-Typ" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "Typ ist kein akzeptierter Basis-Typ" #: py/runtime.c @@ -4311,7 +4449,9 @@ msgstr "'%c' in Format konnte nicht zugeordnet werden" msgid "unreadable attribute" msgstr "nicht lesbares Attribut" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Nicht unterstützter %q-Typ" @@ -4391,11 +4531,6 @@ msgstr "Gewichte müssen ein Objekt des Typs %q, %q, %q, or %q, not %q sein " msgid "width must be greater than zero" msgstr "Breite muss größer als 0 sein" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "wifi ist nicht aktiviert" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "wifi.Monitor nicht verfügbar" @@ -4458,6 +4593,53 @@ msgstr "zi muss eine Gleitkommazahl sein" msgid "zi must be of shape (n_section, 2)" msgstr "zi muss die Form (n_section, 2) haben" +#~ msgid "Unsupported format" +#~ msgstr "Nicht unterstütztes Format" + +#~ msgid "Wifi is not enabled" +#~ msgstr "WLAN ist nicht aktiviert" + +#~ msgid "wifi is not enabled" +#~ msgstr "wifi ist nicht aktiviert" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "'/' kann nicht wiedereingehängt werden, wenn per USB sichtbar." + +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q muss ein %q Objekt, %q, oder %q sein" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Dem fmt Block muss ein Datenblock folgen" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Nur monochrome, indizierte 4bpp oder 8bpp, und 16bpp oder größere BMPs " +#~ "unterstützt: %d bpp wurden gegeben" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "Der Pegel muss zwischen 0 und 1 liegen" + +#~ msgid "init I2C" +#~ msgstr "initialisiere I2C" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "" +#~ "Das bits_per_sample des Samples stimmt nicht mit dem des Mixers überein" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "" +#~ "Die Kanalanzahl des Samples stimmt nicht mit der des Mischers überein" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "Die Abtastrate der Probe stimmt nicht mit der des Mischers überein" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "" +#~ "Der Vorzeichentyp des Samples stimmt nicht mit dem des Mixers überein" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Die Pufferlänge muss ein vielfaches von 512 sein" @@ -4760,13 +4942,13 @@ msgstr "zi muss die Form (n_section, 2) haben" #~ msgid "'%s' object does not support item deletion" #~ msgstr "'%s' Objekt unterstützt das Löschen von Elementen nicht" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "'%s' Objekt ist kein Iterator" #~ msgid "'%s' object is not callable" #~ msgstr "'%s' object ist nicht aufrufbar" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "'%s' Objekt nicht iterierbar" #~ msgid "'%s' object is not subscriptable" @@ -4785,7 +4967,7 @@ msgstr "zi muss die Form (n_section, 2) haben" #~ msgid "'continue' outside loop" #~ msgstr "'continue' außerhalb einer Schleife" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "'coroutine' Objekt ist kein Iterator" #~ msgid "(x,y) integers required" @@ -6155,7 +6337,7 @@ msgstr "zi muss die Form (n_section, 2) haben" #~ msgid "frequency is read-only for this board" #~ msgstr "Frequenz ist für dieses Board schreibgeschützt" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "Funktion akzeptiert keine Schlüsselwort-Argumente" #~ msgid "function is implemented for scalars and ndarrays only" @@ -6269,7 +6451,7 @@ msgstr "zi muss die Form (n_section, 2) haben" #~ msgid "name must be a string" #~ msgstr "name muss ein String sein" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "Name für Argumente wiederverwendet" #~ msgid "no available NIC" diff --git a/locale/el.po b/locale/el.po index e3c643d7342..6598505448c 100644 --- a/locale/el.po +++ b/locale/el.po @@ -8,4392 +8,4717 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-12-04 01:08+0000\n" -"Last-Translator: Bill Sideris \n" +"PO-Revision-Date: 2025-06-29 13:02+0000\n" +"Last-Translator: MAE \n" "Language-Team: none\n" "Language: el\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.3-dev\n" +"X-Generator: Weblate 5.13-dev\n" -#: main.c -msgid "" -"\n" -"Code done running.\n" +#: extmod/modasyncio.c extmod/modheapq.c +msgid "empty heap" msgstr "" -"\n" -"Η εκτέλεση του κώδικα ολοκληρώθηκε.\n" -#: main.c -msgid "" -"\n" -"Code stopped by auto-reload. Reloading soon.\n" +#: extmod/modasyncio.c +msgid "can't cancel self" msgstr "" -"\n" -"Ο κώδικας σταμάτησε λόγω της αυτόματης επαναφόρτωσης. Η επαναφόρτωση θα " -"γίνει σύντομα.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Please file an issue with your program at github.com/adafruit/circuitpython/" -"issues." +#: extmod/modasyncio.c +msgid "can't wait" msgstr "" -"\n" -"Παρακαλώ δημιουργήστε ένα πρόβλημα με το πρόγραμμά σας στο github.com/" -"adafruit/circuitpython/issues." -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Press reset to exit safe mode.\n" +#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c +msgid "a bytes-like object is required" msgstr "" -"\n" -"Πατήστε reset για να βγείτε από την ασφαλή λειτουργία.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"You are in safe mode because:\n" +#: extmod/modbinascii.c +msgid "incorrect padding" msgstr "" -"\n" -"Είσαστε τε ασφαλή λειτουργία διότι:\n" -#: py/obj.c -msgid " File \"%q\"" -msgstr " Αρχείο \"%q\"" +#: extmod/moddeflate.c +msgid "format" +msgstr "" -#: py/obj.c -msgid " File \"%q\", line %d" -msgstr " Αρχείο \"%q\", γραμμή %d" +#: extmod/moddeflate.c +msgid "wbits" +msgstr "" -#: py/builtinhelp.c -msgid " is of type %q\n" -msgstr " είναι τύπου %q\n" +#: extmod/modhashlib.c +msgid "hash is final" +msgstr "" -#: main.c -msgid " not found.\n" -msgstr " δεν βρέθηκε.\n" +#: extmod/modheapq.c +msgid "heap must be a list" +msgstr "" -#: main.c -msgid " output:\n" -msgstr " έξοδος:\n" +#: extmod/modjson.c +msgid "syntax error in JSON" +msgstr "" -#: py/objstr.c -#, c-format -msgid "%%c requires int or char" -msgstr "%%c απαιτεί ακέραιο ή χαρακτήρα" +#: extmod/modrandom.c +msgid "bits must be 32 or less" +msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c +msgid "no default seed" msgstr "" -"%d pin διεύθυνσης, %d rgb ping και %d πλακίδια αναδεικνύουν ύψος %d, όχι %d" -#: shared-bindings/microcontroller/Pin.c -msgid "%q and %q contain duplicate pins" -msgstr "%q και %q περιέχουν διπλότυπα pins" +#: extmod/modre.c +msgid "splitting with sub-captures" +msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "%q and %q must be different" -msgstr "%q και %q πρεπει να είναι διαφορετικά" +#: extmod/modre.c +msgid "regex too complex" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "%q and %q must share a clock unit" +#: extmod/modre.c +msgid "Error in regex" +msgstr "Σφάλμα σε regex" + +#: extmod/modtime.c +msgid "mktime needs a tuple of length 8 or 9" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "%q cannot be changed once mode is set to %q" +#: extmod/modtime.c +msgid "ticks interval overflow" msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q contains duplicate pins" -msgstr "%q περιέχει διπλότυπα pins" +#: extmod/modzlib.c +msgid "compression header" +msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -msgid "%q failure: %d" -msgstr "%q αποτυχία: %d" +#: extmod/ulab/code/ndarray.c +msgid "data type not understood" +msgstr "" -#: py/argcheck.c -msgid "%q in %q must be of type %q, not %q" -msgstr "%q στο %q πρέπει να είναι τύπου %q, όχι %q" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/usb_host/Port.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c -msgid "%q in use" -msgstr "%q είναι σε χρήση" +#: extmod/ulab/code/ndarray.c +msgid "ndarray length overflows" +msgstr "" -#: py/objstr.c -msgid "%q index out of range" -msgstr "%q δείκτης εκτός εμβέλειας" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex type" +msgstr "" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q δείκτες πρέπει να είναι ακέραιοι, όχι %s" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c +msgid "too many dimensions" +msgstr "" -#: shared-module/bitbangio/SPI.c -msgid "%q init failed" -msgstr "%q εκκίνηση απέτυχε" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c +msgid "index is out of bounds" +msgstr "" -#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c -msgid "%q is %q" -msgstr "%q είναι %q" +#: extmod/ulab/code/ndarray.c +msgid "indices must be integers, slices, or Boolean lists" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "%q is read-only for this board" -msgstr "%q είναι μόνο για ανάγνωση για αυτήν την πλακέτα" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c +msgid "operands could not be broadcast together" +msgstr "" -#: py/argcheck.c shared-bindings/usb_hid/Device.c -msgid "%q length must be %d" -msgstr "%q μήκος πρέπει να είναι %d" +#: extmod/ulab/code/ndarray.c +msgid "array and index length must be equal" +msgstr "" -#: py/argcheck.c -msgid "%q length must be %d-%d" -msgstr "%q μήκος πρέπει να είναι %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex to dtype" +msgstr "" -#: py/argcheck.c -msgid "%q length must be <= %d" -msgstr "%q μήκος πρέπει να είναι <= %d" +#: extmod/ulab/code/ndarray.c +msgid "operation is implemented for 1D Boolean arrays only" +msgstr "" -#: py/argcheck.c -msgid "%q length must be >= %d" -msgstr "%q μήκος πρέπει να είναι >= %d" +#: extmod/ulab/code/ndarray.c +msgid "too many indices" +msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c -msgid "%q moved from %q to %q" -msgstr "%q μετακινήθηκε από το %q στο %q" +#: extmod/ulab/code/ndarray.c +msgid "cannot delete array elements" +msgstr "" -#: py/argcheck.c -msgid "%q must be %d" -msgstr "%q πρέπει να είναι %d" +#: extmod/ulab/code/ndarray.c +msgid "flattening order must be either 'C', or 'F'" +msgstr "" -#: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "%q must be %d-%d" -msgstr "%q πρέπει να είναι %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "tobytes can be invoked for dense arrays only" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -msgid "%q must be 1 when %q is True" -msgstr "%q πρέπει να είναι 1 όταν %q είναι True" +#: extmod/ulab/code/ndarray.c +msgid "operation is not supported for given type" +msgstr "" -#: py/argcheck.c shared-bindings/gifio/GifWriter.c -#: shared-module/gifio/OnDiskGif.c -msgid "%q must be <= %d" -msgstr "%q πρέπει να είναι <= %d" +#: extmod/ulab/code/ndarray.c +msgid "shape must be integer or tuple of integers" +msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "%q must be <= %u" -msgstr "%q πρέπει να είναι <= %u" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c +msgid "maximum number of dimensions is " +msgstr "" -#: py/argcheck.c -msgid "%q must be >= %d" -msgstr "%q πρέπει να είναι >= %d" +#: extmod/ulab/code/ndarray.c +msgid "can only specify one unknown dimension" +msgstr "" -#: shared-bindings/analogbufio/BufferedIn.c -msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "%q πρέπει να είναι bytearray ή array τύπου 'H' ή 'B'" +#: extmod/ulab/code/ndarray.c +msgid "cannot reshape array" +msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -msgstr "%q πρέπει να είναι bytearray ή array τύπου 'h', 'H', 'b', ή 'B'" +#: extmod/ulab/code/ndarray.c +msgid "cannot assign new shape" +msgstr "" -#: shared-bindings/warnings/__init__.c -msgid "%q must be a subclass of %q" -msgstr "%q πρέπει να είναι υποκλάση του %q" +#: extmod/ulab/code/ndarray.c +msgid "function is defined for ndarrays only" +msgstr "" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -msgid "%q must be array of type 'H'" -msgstr "%q πρέπει να είναι πίνακας τύπου 'H'" +#: extmod/ulab/code/ndarray_operators.c +msgid "operation not supported for the input types" +msgstr "" -#: shared-module/synthio/__init__.c -msgid "%q must be array of type 'h'" -msgstr "%q πρέπει να είναι λίστα τύπου 'h'" +#: extmod/ulab/code/ndarray_operators.c +msgid "dtype of int32 is not supported" +msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "%q must be multiple of 8." +#: extmod/ulab/code/ndarray_operators.c +msgid "cannot cast output with casting rule" msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c -#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c -#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c -#: shared-module/synthio/Synthesizer.c -msgid "%q must be of type %q or %q, not %q" -msgstr "%q πρέπει να είναι τύπου %q ή %q, όχι %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "results cannot be cast to specified type" +msgstr "" -#: shared-bindings/jpegio/JpegDecoder.c -msgid "%q must be of type %q, %q, or %q, not %q" +#: extmod/ulab/code/numpy/approx.c +msgid "interp is defined for 1D iterables of equal length" msgstr "" -#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c -#: shared-module/synthio/__init__.c -msgid "%q must be of type %q, not %q" -msgstr "%q πρέπει να είναι τύπου %q, όχι %q" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D iterables" +msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -msgid "%q must be power of 2" -msgstr "%q πρέπει να είναι δύναμη του 2" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D arrays of equal length" +msgstr "" -#: shared-bindings/wifi/Monitor.c -msgid "%q out of bounds" -msgstr "%q εκτός ορίων" +#: extmod/ulab/code/numpy/bitwise.c +msgid "not supported for input types" +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c -#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c -msgid "%q out of range" -msgstr "%q εκτός εμβέλειας" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "function is implemented for ndarrays only" +msgstr "" -#: py/objmodule.c py/runtime.c -msgid "%q renamed %q" -msgstr "%q μεταονομάστηκε σε %q" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be an ndarray, or a scalar" +msgstr "" -#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c -msgid "%q step cannot be zero" -msgstr "%q βήμα δεν μπορεί να είναι μηδέν" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be a 1D ndarray" +msgstr "" -#: shared-module/bitbangio/I2C.c -msgid "%q too long" +#: extmod/ulab/code/numpy/carray/carray_tools.c +msgid "not implemented for complex dtype" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "%q() takes %d positional arguments but %d were given" -msgstr "%q() παίρνει %d ορίσματα θέσεως αλλά %d δόθηκαν" +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c +#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c +#: extmod/ulab/code/numpy/vector.c +msgid "wrong input type" +msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "%q() without %q()" +#: extmod/ulab/code/numpy/create.c +msgid "input argument must be an integer, a tuple, or a list" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q, %q, and %q must all be the same length" -msgstr "%q, %q, και %q πρέπει να είναι όλα του ιδίου μήκους" +#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c +msgid "wrong number of arguments" +msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c -msgid "%q=%q" -msgstr "%q=%q" +#: extmod/ulab/code/numpy/create.c py/objint_longlong.c py/objint_mpz.c +msgid "divide by zero" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts in more bits than pin count" -msgstr "%q[%u] μετατοπίζει σε περισσότερα bits από αριθμό pin" +#: extmod/ulab/code/numpy/create.c +msgid "arange: cannot compute length" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts out more bits than pin count" -msgstr "%q[%u] μετατοπίζει από περισσότερα bits από αριθμό pin" +#: extmod/ulab/code/numpy/create.c +msgid "first argument must be a tuple of ndarrays" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] uses extra pin" -msgstr "%q[%u] χρησιμοποιεί παραπάνω pin" +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] waits on input outside of count" +#: extmod/ulab/code/numpy/create.c +msgid "wrong axis specified" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -#, c-format -msgid "%s error 0x%x" -msgstr "%s σφάλμα 0x%x" +#: extmod/ulab/code/numpy/create.c +msgid "input arrays are not compatible" +msgstr "" -#: py/argcheck.c -msgid "'%q' argument required" -msgstr "'%q' όρισμα απαιτείται" +#: extmod/ulab/code/numpy/create.c +msgid "input must be 1- or 2-d" +msgstr "" -#: py/proto.c -msgid "'%q' object does not support '%q'" -msgstr "'%q' αντικείμενο δεν υποστηρίζει '%q'" +#: extmod/ulab/code/numpy/create.c +msgid "number of points must be at least 2" +msgstr "" -#: py/runtime.c -msgid "'%q' object is not an iterator" -msgstr "'%q' αντικείμενο δεν είναι επαναλήπτης" +#: extmod/ulab/code/numpy/create.c +msgid "offset must be non-negative and no greater than buffer length" +msgstr "" -#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c -msgid "'%q' object is not callable" -msgstr "'%q' αντικείμενο δεν καλείται" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer size must be a multiple of element size" +msgstr "" -#: py/runtime.c -msgid "'%q' object is not iterable" -msgstr "'%q' αντικείμενο δεν είναι επαναληπτικό" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer is smaller than requested size" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a label" -msgstr "'%s' περιμένει μια ετικέτα" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is defined for ndarrays only" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a register" -msgstr "'%s' περιμένει έναν καταχωρητή" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is implemented for linear arrays only" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects a special register" -msgstr "'%s' περιμένει έναν ειδικό καταχωρητή" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "input array length must be power of 2" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an FPU register" -msgstr "'%s' περιμένει έναν FPU καταχωρητή" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "real and imaginary parts must be of equal length" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s' περιμένει μια διεύθυνση της μορφής [a, b]" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be ndarrays" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects an integer" -msgstr "'%s' περιμένει έναν ακέραιο" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be linear arrays" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects at most r%d" -msgstr "'%s' περιμένει το πολύ r%d" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must not be empty" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' περιμένει {r0, r1, ...}" +#: extmod/ulab/code/numpy/io/io.c +msgid "corrupted file" +msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "'%s' integer %d isn't within range %d..%d" -msgstr "'%s' ακέραιος %d δεν είναι μέσα στο επιτρεπτό εύρος %d..%d" +#: extmod/ulab/code/numpy/io/io.c +msgid "wrong dtype" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" -msgstr "'%s' ακέραιος 0x%x δεν χωράει στην μάσκα 0x%x" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols keyword must be specified" +msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item assignment" -msgstr "'%s' αντικείμενο δεν υποστηρίζει ορισμό πράγματος" +#: extmod/ulab/code/numpy/io/io.c +msgid "empty file" +msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item deletion" -msgstr "'%s' αντικείμενο δεν υποστηρίζει διαγραφή πράγματος" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols is too high" +msgstr "" -#: py/runtime.c -msgid "'%s' object has no attribute '%q'" -msgstr "'%s' αντικείμενο δεν έχει γνώρισμα '%q'" +#: extmod/ulab/code/numpy/io/io.c +msgid "array has too many dimensions" +msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object isn't subscriptable" -msgstr "'%s' αντικείμενο δεν είναι subscriptable" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "input matrix is asymmetric" +msgstr "" -#: py/objstr.c -msgid "'=' alignment not allowed in string format specifier" -msgstr "Ευθυγράμμιση του '=' δεν επιτρέπεται εντός προσδιοριστή string format" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "matrix is not positive definite" +msgstr "" -#: shared-module/struct/__init__.c -msgid "'S' and 'O' are not supported format types" -msgstr "'S' και 'O' δεν είναι υποστηριζόμενοι τύποι format" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "iterations did not converge" +msgstr "" -#: py/compile.c -msgid "'align' requires 1 argument" -msgstr "'align' απαιτεί τουλάχιστον ένα όρισμα" - -#: py/compile.c -msgid "'await' outside function" -msgstr "'await' εκτός συνάρτησης" - -#: py/compile.c -msgid "'break'/'continue' outside loop" -msgstr "'break'/'continue' εκτός επανάληψης" - -#: py/compile.c -msgid "'data' requires at least 2 arguments" -msgstr "'data' απαιτεί τουλάχιστον 2 παραμέτρους" - -#: py/compile.c -msgid "'data' requires integer arguments" -msgstr "'data' απαιτεί ακέραιες παραμέτρους" - -#: py/compile.c -msgid "'label' requires 1 argument" -msgstr "'label' απαιτεί ένα όρισμα" - -#: py/emitnative.c -msgid "'not' not implemented" +#: extmod/ulab/code/numpy/linalg/linalg.c +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "input matrix is singular" msgstr "" -#: py/compile.c -msgid "'return' outside function" -msgstr "'return' εκτός συνάρτησης" - -#: py/compile.c -msgid "'yield from' inside async function" -msgstr "'yield from' εκτός ασύνχρονης συνάρτησης" - -#: py/compile.c -msgid "'yield' outside function" -msgstr "'yield' εκτός συνάρτησης" - -#: py/compile.c -msgid "* arg after **" -msgstr "* όρισμα μετά **" - -#: py/compile.c -msgid "*x must be assignment target" -msgstr "*x πρέπει να είναι στόχος ανάθεσης" - -#: py/obj.c -msgid ", in %q\n" -msgstr ", στο %q\n" - -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid ".show(x) removed. Use .root_group = x" -msgstr ".show(x) αφαιρέθηκε. Χρησιμοποιήστε το .root_group = x" - -#: py/objcomplex.c -msgid "0.0 to a complex power" -msgstr "0.0 σε μία σύνθετη δύναμη" - -#: py/modbuiltins.c -msgid "3-arg pow() not supported" -msgstr "pow() με 3 παραμέτρους δεν υποστηρίζεται" - -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "AP could not be started" -msgstr "AP δεν μπόρεσε να εκκινηθεί" - -#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, c-format -msgid "Address must be %d bytes long" -msgstr "Η διεύθυνση πρέπει να είναι %d bytes μεγάλη" - -#: ports/espressif/common-hal/memorymap/AddressRange.c -#: ports/nordic/common-hal/memorymap/AddressRange.c -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Address range not allowed" -msgstr "Εμβέλεια διευθύνσεων δεν επιτρέπεται" - -#: shared-bindings/memorymap/AddressRange.c -msgid "Address range wraps around" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for ndarrays only" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "All CAN peripherals are in use" -msgstr "Όλα τα περιφεριακά CAN είναι σε χρήση" - -#: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/nordic/common-hal/busio/I2C.c -msgid "All I2C peripherals are in use" -msgstr "Όλα τα I2C περιφεριακά ειναι σε χρήση" - -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "All RX FIFOs in use" -msgstr "Όλα τα RX FIFOs είναι σε χρήση" - -#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c -msgid "All SPI peripherals are in use" -msgstr "Όλα τα SPI περιφεριακά είναι σε χρήση" - -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c -msgid "All UART peripherals are in use" -msgstr "Όλα τα UART περιφεριακά ειναι σε χρήση" - -#: ports/nordic/common-hal/countio/Counter.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c -msgid "All channels in use" -msgstr "Όλα τα κανάλια είναι σε χρήση" - -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All dma channels in use" -msgstr "Όλα τα κανάλια dma είναι σε χρήση" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "All event channels in use" -msgstr "Όλα τα κανάλια συμβάντων είναι σε χρήση" - -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All state machines in use" -msgstr "Όλες οι μηχανές κατάστασης είναι σε χρήση" - -#: ports/atmel-samd/audio_dma.c -msgid "All sync event channels in use" -msgstr "Όλα τα κανάλια συμβάντων συγχρονισμού είναι σε χρήση" - -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -msgid "All timers for this pin are in use" -msgstr "Όλοι οι χρονιστές για αυτό το pin χρησιμοποιούνται ήδη" - -#: ports/atmel-samd/common-hal/_pew/PewPew.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/peripherals/nrf/timers.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c -msgid "All timers in use" -msgstr "Όλοι οι χρονιστές βρίσκονται σε χρήση" - -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Already advertising." -msgstr "Ήδη διαφημίζουμε." - -#: ports/atmel-samd/common-hal/canio/Listener.c -msgid "Already have all-matches listener" -msgstr "Ύπάρχει ήδη all-matches ακροατής" - -#: ports/espressif/bindings/espnow/ESPNow.c -#: ports/espressif/common-hal/espulp/ULP.c -#: shared-module/memorymonitor/AllocationAlarm.c -#: shared-module/memorymonitor/AllocationSize.c -msgid "Already running" -msgstr "Τρέχει ήδη" - -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Already scanning for wifi networks" -msgstr "Ήδη γίνεται σάρωση για δίκτυα wifi" - -#: shared-module/os/getenv.c -#, c-format -msgid "An error occurred while retrieving '%s':\n" -msgstr "Παρουσιάστηκε σφάλμα κατά την ανάκτηση '%s':\n" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for 2D arrays only" +msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Another PWMAudioOut is already active" -msgstr "Και άλλο PWMAudioOut είναι σε χρήση" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "mode must be complete, or reduced" +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -msgid "Another send is already active" -msgstr "Άλλη αποστολή είναι ήδη ενεργή" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" -#: shared-bindings/pulseio/PulseOut.c -msgid "Array must contain halfwords (type 'H')" -msgstr "H παράταξη πρέπει να περιέχει halfwords (τύπου 'H')" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get (arg)min/(arg)max of empty sequence" +msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Array values should be single bytes." -msgstr "Η τιμές της παράταξη πρέπει να είναι μονά bytes." +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +msgid "axis must be None, or an integer" +msgstr "" -#: shared-module/memorymonitor/AllocationAlarm.c -#, c-format -msgid "Attempt to allocate %d blocks" -msgstr "Προσπάθεια να δεσμευτούν %d blocks" +#: extmod/ulab/code/numpy/numerical.c +msgid "operation is not implemented on ndarrays" +msgstr "" -#: ports/raspberrypi/audio_dma.c -msgid "Audio conversion not implemented" -msgstr "Η μετατροπή ήχου δεν υποστηρίζεται" +#: extmod/ulab/code/numpy/numerical.c +msgid "input must be tuple, list, range, or ndarray" +msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "AuthMode.OPEN is not used with password" -msgstr "AuthMode.OPEN δεν μπορεί να χρησιμοποιηθεί με κωδικό" +#: extmod/ulab/code/numpy/numerical.c +msgid "sort argument must be an ndarray" +msgstr "" -#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c -msgid "Authentication failure" -msgstr "Αποτυχία αυθεντικοποίησης" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort argument must be an ndarray" +msgstr "" -#: main.c -msgid "Auto-reload is off.\n" -msgstr "Η αυτόματη επαναφόρτωση είναι απενεργοποιημένη.\n" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort is not implemented for flattened arrays" +msgstr "" -#: main.c -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" +#: extmod/ulab/code/numpy/numerical.c +msgid "axis too long" msgstr "" -"Η αυτόματη επαναφόρτωση είναι ενεργή. Αποθηκεύστε αρχεία μέσω USB για να " -"τρέξετε ή ανοίξτε το REPL για απενεργοποίηση.\n" -#: ports/espressif/common-hal/canio/CAN.c -msgid "Baudrate not supported by peripheral" -msgstr "Baudrate δεν υποστηρίζεται από την περιφεριακή συσκευή" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c +msgid "arguments must be ndarrays" +msgstr "" -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Below minimum frame rate" -msgstr "Χαμηλότερο από το ελάχιστο frame rate" +#: extmod/ulab/code/numpy/numerical.c +msgid "cross is defined for 1D arrays of length 3" +msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Bit clock and word select must be sequential GPIO pins" -msgstr "Ρολόι bit και ορισμού λέξης πρέπει να είναι διαδοχικά GPIO pins" +#: extmod/ulab/code/numpy/numerical.c +msgid "diff argument must be an ndarray" +msgstr "" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c -msgid "Bitmap size and bits per value must match" -msgstr "Το μέγεθος του bitmap και τα bits ανα τιμή πρέπει να ταιριάζουν" +msgid "index out of range" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Boot device must be first (interface #0)." -msgstr "Η συσκευή εκκίνησης πρέπει να επιλεχθεί πρώτα (διεπαφή #0)." +#: extmod/ulab/code/numpy/numerical.c +msgid "differentiation order out of range" +msgstr "" -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Both RX and TX required for flow control" -msgstr "Και RX και TX απαιτούνται για έλεγχο flow" +#: extmod/ulab/code/numpy/numerical.c +msgid "flip argument must be an ndarray" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Brightness not adjustable" -msgstr "H φωτεινότητα δεν μπορεί να προσαρμοστεί" +#: extmod/ulab/code/numpy/numerical.c +msgid "wrong axis index" +msgstr "" -#: shared-bindings/_bleio/UUID.c -#, c-format -msgid "Buffer + offset too small %d %d %d" -msgstr "Buffer + offset είναι πολύ μικρά %d %d %d" +#: extmod/ulab/code/numpy/numerical.c +msgid "median argument must be an ndarray" +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Buffer elements must be 4 bytes long or less" -msgstr "Στοιχεία του buffer πρέπει να είναι το πολύ 4 bytes" +#: extmod/ulab/code/numpy/numerical.c +msgid "roll argument must be an ndarray" +msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Buffer is not a bytearray." -msgstr "Το buffer δεν είναι ένα bytearray." +#: extmod/ulab/code/numpy/poly.c +msgid "input data must be an iterable" +msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, c-format -msgid "Buffer length %d too big. It must be less than %d" -msgstr "Το μήκος buffer %d είναι πολύ μεγάλο. Πρέπει ν α είναι λιγότερο απο %d" +#: extmod/ulab/code/numpy/poly.c +msgid "more degrees of freedom than data points" +msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -#: ports/cxd56/common-hal/sdioio/SDCard.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c -#: shared-module/sdcardio/SDCard.c -#, c-format -msgid "Buffer must be a multiple of %d bytes" +#: extmod/ulab/code/numpy/poly.c +msgid "input vectors must be of equal length" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -#, c-format -msgid "Buffer too short by %d bytes" -msgstr "Buffer πολύ μικρό κατα %d bytes" +#: extmod/ulab/code/numpy/poly.c +msgid "could not invert Vandermonde matrix" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c -msgid "Buffer too small" -msgstr "Buffer πολύ μικρός" +#: extmod/ulab/code/numpy/poly.c +msgid "input is not iterable" +msgstr "" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, c-format -msgid "Bus pin %d is already in use" -msgstr "Bus pin %d είναι ήδη σε χρήση" +#: extmod/ulab/code/numpy/random/random.c +msgid "argument must be None, an integer or a tuple of integers" +msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "Byte buffer must be 16 bytes." -msgstr "Byte buffer πρέπει να είναι 16 bytes." +#: extmod/ulab/code/numpy/random/random.c +msgid "shape must be None, and integer or a tuple of integers" +msgstr "" -#: shared-bindings/aesio/aes.c -msgid "CBC blocks must be multiples of 16 bytes" -msgstr "CBC blocks πρέπει να είναι πολλαπλάσια του 16 bytes" +#: extmod/ulab/code/numpy/random/random.c +msgid "out has wrong type" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CIRCUITPY drive could not be found or created." -msgstr "Ο CIRCUITPY δίσκος δεν μπόρεσε να βρεθεί ή να δημιουργηθεί." +#: extmod/ulab/code/numpy/random/random.c +msgid "output array has wrong type" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "CRC or checksum was invalid" -msgstr "CRC ή checksum ήταν άκυρο" +#: extmod/ulab/code/numpy/random/random.c +msgid "size must match out.shape when used together" +msgstr "" -#: py/objtype.c -msgid "Call super().__init__() before accessing native object." -msgstr "Κλήση super().__init__() πρίν την πρόσβαση του τοπικού αντικειμένου." +#: extmod/ulab/code/numpy/random/random.c +msgid "output array must be contiguous" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Camera init" -msgstr "Εκκίνηση κάμερας" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of condition array" +msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on RTC IO from deep sleep." -msgstr "Μόνο IO alarm ή RTC επιτρέπονται από βαθύ ύπνο." +#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c +msgid "first argument must be an ndarray" +msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on one low pin while others alarm high from deep sleep." +#: extmod/ulab/code/numpy/transform.c +msgid "wrong index type" msgstr "" -"Μόνο ένα alarm από low pin ενώ τα άλλα alarm θα είναι απο high σε βαθύ ύπνο." -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on two low pins from deep sleep." -msgstr "Μπορεί να γίνει alarm μόνο σε δύο low pins σε βαθύ ύπνο." +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of index array" +msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "Can't set CCCD on local Characteristic" -msgstr "Δεν μπορεί να οριστεί CCCD σε τοπικό Characteristic" +#: extmod/ulab/code/numpy/transform.c +msgid "dimensions do not match" +msgstr "" -#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c -#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c -#: shared-bindings/usb_video/__init__.c -msgid "Cannot change USB devices now" -msgstr "Δεν μπορούν να αλλάξουν οι USB συσκευές τώρα" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be an ndarray" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot create a new Adapter; use _bleio.adapter;" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be of float dtype" msgstr "" -"Δεν μπορεί να δημιουργηθεί νέο Adapter; χρησιμοποιείστε _bleio.adapter;" -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Cannot delete values" -msgstr "Δεν μπορούν να διαγραφούν οι τιμές" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output dimensions differ" +msgstr "" -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c -#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c -#: ports/nordic/common-hal/digitalio/DigitalInOut.c -#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c -msgid "Cannot get pull while in output mode" -msgstr "Δεν γίνεται να διαβαστεί το pull όσο είναι σε output mode" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output shapes differ" +msgstr "" -#: ports/nordic/common-hal/microcontroller/Processor.c -msgid "Cannot get temperature" -msgstr "Δεν μπορεί να διαβαστεί η θερμοκρασία" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for function" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot have scan responses for extended, connectable advertisements." +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for complex dtype" msgstr "" -"Δεν μπορούμε να έχουμε απαντήσεις scan για εκτεταμένες, συνδεόμενες " -"διαφημήσεις." -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot pull on input-only pin." -msgstr "Δεν γίνεται pull σε pin μόνο για εισόδο." +#: extmod/ulab/code/numpy/vector.c +msgid "dtype must be float, or complex" +msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Cannot record to a file" -msgstr "Δεν μπορεί να γίνει καταγραφή σε αρχείο" +#: extmod/ulab/code/numpy/vector.c +msgid "can't convert complex to float" +msgstr "" -#: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "Δεν μπορεί να γίνει remount του '/' όταν είναι ορατό μέσω USB." +#: extmod/ulab/code/numpy/vector.c +msgid "input dtype must be float or complex" +msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Cannot set value when direction is input." -msgstr "Δεν μπορεί να οριστεί τιμή οταν η κατεύθυνση είναι input." +#: extmod/ulab/code/numpy/vector.c +msgid "first argument must be a callable" +msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "Δεν μπορεί να οριστεί RTS ή CTS σε RS485 mode" +#: extmod/ulab/code/numpy/vector.c +msgid "wrong output type" +msgstr "" -#: py/objslice.c -msgid "Cannot subclass slice" -msgstr "Δεν γίνεται υποκατηγορία ενός slice" +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "first two arguments must be ndarrays" +msgstr "" -#: ports/nordic/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge, only level" -msgstr "Δεν γίνεται αφύπνηση σε pin edge, αλλά μόνο σε level" +#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c +msgid "input must be a dense ndarray" +msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge. Only level." -msgstr "Δεν μπορεί να γίνει αφύπνηση σε pin edge. Μόνο level." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "first argument must be a function" +msgstr "" -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "CharacteristicBuffer writing not provided" -msgstr "Δεν υποστηρίζονται εγγραφές στο CharacteristicBuffer" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "function has the same sign at the ends of interval" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "Ο πυρήνας της CircuitPython κατέρευσε. Οουπς!\n" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter should be > 0" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Clock unit in use" -msgstr "Μονάδα ρολογιού ήδη σε χρήση" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter must be > 0" +msgstr "" -#: shared-bindings/_bleio/Connection.c -msgid "" -"Connection has been disconnected and can no longer be used. Create a new " -"connection." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be iterable" msgstr "" -"Έχει γίνει αποσύνδεση και αυτή η συνδεση δεν μπορεί να χρησιμοποιηθεί. " -"Δημιουργήστε μια νέα σύνδεση." -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays have different lengths" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "initial values must be iterable" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays types have different sizes" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be of equal length" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Could not set address" -msgstr "Δεν μπόρεσε να ρυθμιστεί η διεύθυνση" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sosfilt requires iterable arguments" +msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "Could not start interrupt, RX busy" -msgstr "Δεν μπόρεσε να εκκινηθεί το interrupt, RX κατειλημμένο" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "input must be one-dimensional" +msgstr "" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Couldn't allocate decoder" -msgstr "Δεν μπόρεσε να δεσμευτεί decoder" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be an ndarray" +msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Channel Init Error" -msgstr "Σφάλμα εκκίνησης καναλιού DAC" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of shape (n_section, 2)" +msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Device Init Error" -msgstr "Σφάλμα εκκίνησης συσκευής DAC" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of float type" +msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "DAC already in use" -msgstr "DAC είναι ήδη σε χρήση" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos array must be of shape (n_section, 6)" +msgstr "" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -msgid "Data 0 pin must be byte aligned" -msgstr "Το Data 0 pin πρέπει να είναι byte aligned" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos[:, 3] should be all ones" +msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Το data chunk πρέπει να ακολουθεί το fmt chunk" +#: extmod/ulab/code/ulab_tools.c +msgid "axis is out of bounds" +msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Data format error (may be broken data)" +#: extmod/ulab/code/ulab_tools.c +msgid "size is defined for ndarrays only" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data not supported with directed advertising" -msgstr "Δεν υποστηρίζονται δεδομένα με κατευθυνόμενη διαφήμιση" +#: extmod/ulab/code/ulab_tools.c +msgid "input must be square matrix" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data too large for advertisement packet" -msgstr "Τα δεδομένα είναι πολύ μεγάλα για πακέτο διαφημίσεων" +#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c +msgid "input must be an ndarray" +msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Deep sleep pins must use a rising edge with pulldown" -msgstr "Τα pins βαθύ ύπνου πρέπει να χρησιμοποιούν rising edge με pulldown" +#: extmod/ulab/code/utils/utils.c +msgid "out must be a float dense array" +msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Destination capacity is smaller than destination_length." +#: extmod/ulab/code/utils/utils.c +msgid "offset is too large" msgstr "" -"Το μέγεθος προορισμού πρέπει να είναι μικρότερο από το destination_length." -#: shared-module/jpegio/JpegDecoder.c -msgid "Device error or wrong termination of input stream" +#: extmod/ulab/code/utils/utils.c +msgid "out array is too small" msgstr "" -#: ports/nordic/common-hal/audiobusio/I2SOut.c -msgid "Device in use" -msgstr "Συσκευή σε χρήση" +#: extmod/vfs_fat.c py/moderrno.c +msgid "Read-only filesystem" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#, fuzzy -msgid "Display must have a 16 bit colorspace." -msgstr "Η οθόνη πρέπει να έχει 16 bit χρωματική ευκρίνεια." +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display rotation must be in 90 degree increments" -msgstr "Η περιστροφή της οθόνη πρέπει να γίνεται σε βήματα 90 μοιρών" +#: extmod/vfs_posix_file.c +msgid "poll on file not available on win32" +msgstr "" #: main.c msgid "Done" msgstr "Ολοκληρώθηκε" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Drive mode not used when direction is input." -msgstr "Ο τρόπος οδήγησης δεν χρησιμοποιείται όταν η κατεύθυνση είναι είσοδος." +#: main.c +msgid " output:\n" +msgstr " έξοδος:\n" -#: py/obj.c -msgid "During handling of the above exception, another exception occurred:" +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" msgstr "" -"Κατά την αντιμετώπιση της παραπάνω εξαίρεσης, ακόμα μία εξαίρεση συνέβη:" +"Η αυτόματη επαναφόρτωση είναι ενεργή. Αποθηκεύστε αρχεία μέσω USB για να " +"τρέξετε ή ανοίξτε το REPL για απενεργοποίηση.\n" -#: shared-bindings/aesio/aes.c -msgid "ECB only operates on 16 bytes at a time" -msgstr "ECB δουλεύει μόνο σε 16 bytes κάθε φορά" +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Η αυτόματη επαναφόρτωση είναι απενεργοποιημένη.\n" -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/canio/CAN.c -msgid "ESP-IDF memory allocation failed" -msgstr "ESP-IDF δέσμευση μνήμης απέτυχε" +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "" -#: extmod/modre.c -msgid "Error in regex" -msgstr "Σφάλμα σε regex" +#: main.c +msgid " not found.\n" +msgstr " δεν βρέθηκε.\n" -#: supervisor/shared/safe_mode.c -msgid "Error in safemode.py." -msgstr "Σφάλμα στο safemode.py." +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "" -#: shared-bindings/alarm/__init__.c -msgid "Expected a kind of %q" +#: main.c +msgid "" +"\n" +"Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"Ο κώδικας σταμάτησε λόγω της αυτόματης επαναφόρτωσης. Η επαναφόρτωση θα " +"γίνει σύντομα.\n" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Extended advertisements with scan response not supported." +#: main.c +msgid "" +"\n" +"Code done running.\n" msgstr "" +"\n" +"Η εκτέλεση του κώδικα ολοκληρώθηκε.\n" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is defined for ndarrays only" +#: main.c +msgid "Woken up by alarm.\n" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is implemented for linear arrays only" +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +"Πατήστε οποιοδήποτε πλήκτρο για να μπείτε στο REPL. Πατήστε CTRL-D για " +"επαναφόρτωση.\n" -#: shared-bindings/ps2io/Ps2.c -msgid "Failed sending command." +#: main.c +msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +msgstr "Προσποίηση βαθύ ύπνου μεχρι γεγονότος, CTRL-C ή εγγραφή αρχείου.\n" + +#: main.c +msgid "UID:" msgstr "" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to acquire mutex, err 0x%04x" +#: main.c +msgid "soft reboot\n" msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Failed to add service TXT record" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c +#: ports/stm/common-hal/audioio/AudioOut.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c +#: shared-module/busdisplay/BusDisplay.c shared-module/ssl/SSLContext.c +msgid "%q init failed" +msgstr "%q εκκίνηση απέτυχε" + +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" msgstr "" -#: shared-bindings/mdns/Server.c -msgid "" -"Failed to add service TXT record; non-string or bytes found in txt_records" +#: ports/analog/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c +#: shared-bindings/bitmaptools/__init__.c shared-bindings/canio/Match.c +#: shared-bindings/time/__init__.c +msgid "%q out of range" +msgstr "%q εκτός εμβέλειας" + +#: ports/analog/common-hal/busio/SPI.c +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid state" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "RS485" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Both RX and TX required for flow control" +msgstr "Και RX και TX απαιτούνται για έλεγχο flow" + +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to allocate Wifi memory" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" msgstr "" -#: ports/espressif/common-hal/wifi/ScannedNetworks.c -msgid "Failed to allocate wifi scan memory" +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Failed to buffer the sample" +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "Όλα τα UART περιφεριακά ειναι σε χρήση" + +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c +#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/microcontroller/Processor.c +#: ports/espressif/common-hal/mipidsi/Display.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +#: ports/raspberrypi/bindings/picodvi/Framebuffer.c +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c +msgid "Invalid %q" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: internal error" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: timeout" +#: ports/atmel-samd/audio_dma.c +msgid "All sync event channels in use" +msgstr "Όλα τα κανάλια συμβάντων συγχρονισμού είναι σε χρήση" + +#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" msgstr "" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Failed to parse MP3 file" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" msgstr "" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to release mutex, err 0x%04x" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "" + +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/atmel-samd/common-hal/_pew/PewPew.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "All timers in use" +msgstr "Όλοι οι χρονιστές βρίσκονται σε χρήση" + +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: ports/atmel-samd/common-hal/countio/Counter.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/max3421e/Max3421E.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +msgid "Internal resource(s) in use" msgstr "" +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c #: supervisor/shared/safe_mode.c -msgid "Failed to write internal flash." +msgid "Unknown reason." msgstr "" -#: py/moderrno.c -msgid "File exists" +#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +#: ports/nordic/common-hal/alarm/time/TimeAlarm.c +#: ports/stm/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set" msgstr "" -#: shared-module/os/getenv.c -msgid "File not found" +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "No DAC on chip" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "Filters too complex" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "%q and %q must share a clock unit" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is duplicate" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is invalid" -msgstr "" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Μονάδα ρολογιού ήδη σε χρήση" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is too big" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "No DMA channel found" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Format not supported" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Unable to allocate buffers for signed conversion" msgstr "" -#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c -msgid "" -"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +#, c-format +msgid "Only 8 or 16 bit mono with %dx oversampling supported." msgstr "" -#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c -#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c -msgid "Function requires lock" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" msgstr "" -#: ports/cxd56/common-hal/gnss/GNSS.c -msgid "GNSS init" -msgstr "" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC είναι ήδη σε χρήση" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Generic Failure" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Group already used" -msgstr "" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Όλα τα κανάλια συμβάντων είναι σε χρήση" -#: supervisor/shared/safe_mode.c -msgid "Hard fault: memory access or instruction error." +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/I2C.c +#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/busio/I2C.c +msgid "No pull up found on SDA or SCL; check your wiring" msgstr "" +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "%q must be power of 2" +msgstr "%q πρέπει να είναι δύναμη του 2" + +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c -#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c -#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c -msgid "Hardware in use, try alternative pins" +#: ports/mimxrt10xx/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c +#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c +#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c +#: shared-bindings/paralleldisplaybus/ParallelBus.c +#: shared-bindings/qspibus/QSPIBus.c shared-module/bitbangio/SPI.c +msgid "No %q pin" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Heap allocation when VM not running." -msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "Όλα τα RX FIFOs είναι σε χρήση" -#: extmod/vfs_posix_file.c py/objstringio.c -msgid "I/O operation on closed file" -msgstr "" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "Ύπάρχει ήδη all-matches ακροατής" -#: ports/stm/common-hal/busio/I2C.c -msgid "I2C init error" +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "Filters too complex" msgstr "" -#: ports/raspberrypi/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "I2C peripheral in use" -msgstr "" +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +#: ports/nordic/common-hal/digitalio/DigitalInOut.c +#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Δεν γίνεται να διαβαστεί το pull όσο είναι σε output mode" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "In-buffer elements must be <= 4 bytes long" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_pins[%d]" msgstr "" -#: shared-bindings/_pew/PewPew.c -msgid "Incorrect buffer size" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Init program size invalid" +#: ports/atmel-samd/common-hal/microcontroller/Pin.c +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c +#: shared-bindings/microcontroller/Pin.c +msgid "Invalid %q pin" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin direction conflicts with initial out pin direction" +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +#: ports/cxd56/common-hal/microcontroller/__init__.c +#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c +msgid "No bootloader present" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin state conflicts with initial out pin state" -msgstr "" +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "Το Data 0 pin πρέπει να είναι byte aligned" -#: shared-bindings/bitops/__init__.c +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c #, c-format -msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" -msgstr "" +msgid "Bus pin %d is already in use" +msgstr "Bus pin %d είναι ήδη σε χρήση" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c -msgid "Input taking too long" -msgstr "" - -#: py/moderrno.c -msgid "Input/output error" -msgstr "" - -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient authentication" +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/pulseio/PulseIn.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c +#: shared-bindings/ps2io/Ps2.c +msgid "pop from empty %q" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient encryption" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "Input taking too long" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient memory pool for the image" -msgstr "" +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Άλλη αποστολή είναι ήδη ενεργή" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient stream input buffer" -msgstr "" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "%q failure: %d" +msgstr "%q αποτυχία: %d" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Interface must be started" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/cxd56/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c +#: shared-module/sdcardio/SDCard.c +#, c-format +msgid "Buffer must be a multiple of %d bytes" msgstr "" -#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c -msgid "Internal audio buffer too small" +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." msgstr "" +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c #: ports/stm/common-hal/busio/UART.c -msgid "Internal define error" +msgid "UART init" msgstr "" -#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c -msgid "Internal error" -msgstr "" +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Camera init" +msgstr "Εκκίνηση κάμερας" -#: shared-module/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Internal error #%d" +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Size not supported" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: ports/atmel-samd/common-hal/countio/Counter.c -#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c -#: ports/atmel-samd/common-hal/max3421e/Max3421E.c -#: ports/atmel-samd/common-hal/ps2io/Ps2.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-bindings/pwmio/PWMOut.c -msgid "Internal resource(s) in use" -msgstr "" +#: ports/cxd56/common-hal/camera/Camera.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c +msgid "Buffer too small" +msgstr "Buffer πολύ μικρός" -#: supervisor/shared/safe_mode.c -msgid "Internal watchdog timer expired." +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c +msgid "Format not supported" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Interrupt error." +#: ports/cxd56/common-hal/gnss/GNSS.c +msgid "GNSS init" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Interrupted by output function" +#: ports/cxd56/common-hal/sdioio/SDCard.c +msgid "SDCard init" msgstr "" -#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c -#: ports/espressif/common-hal/microcontroller/Processor.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c -#: ports/raspberrypi/bindings/picodvi/Framebuffer.c -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q" -msgstr "" +#: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize.c +msgid "Already running" +msgstr "Τρέχει ήδη" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q and %q" -msgstr "" +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q είναι %q" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c -#: shared-bindings/microcontroller/Pin.c -msgid "Invalid %q pin" +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." msgstr "" -#: ports/stm/common-hal/analogio/AnalogIn.c -msgid "Invalid ADC Unit value" +#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h +#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h +msgid "You pressed the BOOT button at start up." msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Invalid BLE parameter" +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid BSSID" +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid MAC address" +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +#: ports/espressif/boards/vidi_x/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c -msgid "Invalid argument" +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Invalid bits per value" +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "Invalid byte %.*s" +#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h +msgid "You pressed button DOWN at start up." msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c -#, c-format -msgid "Invalid data_pins[%d]" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Update failed" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "Invalid format" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Scan already in progress. Stop with stop_scan." msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: internal error" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid hex password" -msgstr "" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data too large for advertisement packet" +msgstr "Τα δεδομένα είναι πολύ μεγάλα για πακέτο διαφημίσεων" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Invalid multicast MAC address" -msgstr "" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Already advertising." +msgstr "Ήδη διαφημίζουμε." -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid size" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Extended advertisements with scan response not supported." msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "Invalid socket for TLS" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data not supported with directed advertising" +msgstr "Δεν υποστηρίζονται δεδομένα με κατευθυνόμενη διαφήμιση" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#, c-format +msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid state" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +msgid "MITM security not supported" msgstr "" -#: shared-module/os/getenv.c -msgid "Invalid unicode escape" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Key must be 16, 24, or 32 bytes long" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" msgstr "" -#: shared-module/os/getenv.c -msgid "Key not found" +#: ports/espressif/common-hal/_bleio/Characteristic.c +msgid "Too many descriptors" msgstr "" -#: shared-module/is31fl3741/FrameBuffer.c -msgid "LED mappings must match display size" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" msgstr "" -#: py/compile.c -msgid "LHS of keyword arg must be an id" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "Δεν μπορεί να οριστεί CCCD σε τοπικό Characteristic" + +#: ports/espressif/common-hal/_bleio/Connection.c +#: ports/nordic/common-hal/_bleio/Connection.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer already in a group" +#: ports/espressif/common-hal/_bleio/Descriptor.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer must be a Group or TileGrid subclass" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Writes not supported on Characteristic" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "Length of %q must be an even multiple of channel_count * type_size" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Total data to write is larger than %q" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "MAC address was invalid" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Nimble out of memory" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/espressif/common-hal/_bleio/Descriptor.c -msgid "MITM security not supported" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid BLE parameter" msgstr "" -#: shared-bindings/is31fl3741/IS31FL3741.c -msgid "Mapping must be a tuple" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#: ports/zephyr-cp/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "Not connected" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched data size" +#: ports/espressif/common-hal/_bleio/__init__.c +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Already in progress" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched swap flag" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error at %s:%d: %d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] reads pin(s)" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient authentication" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] waits based on pin" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient encryption" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error at %s:%d: %d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] writes pin(s)" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error: %d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_set_pin. %q[%u] sets pin(s)" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge. Only level." +msgstr "Δεν μπορεί να γίνει αφύπνηση σε pin edge. Μόνο level." + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot pull on input-only pin." +msgstr "Δεν γίνεται pull σε pin μόνο για εισόδο." + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on two low pins from deep sleep." +msgstr "Μπορεί να γίνει alarm μόνο σε δύο low pins σε βαθύ ύπνο." + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" +"Μόνο ένα alarm από low pin ενώ τα άλλα alarm θα είναι απο high σε βαθύ ύπνο." -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing jmp_pin. %q[%u] jumps on pin" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on RTC IO from deep sleep." +msgstr "Μόνο IO alarm ή RTC επιτρέπονται από βαθύ ύπνο." + +#: ports/espressif/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set." msgstr "" -#: shared-module/storage/__init__.c -msgid "Mount point directory missing" +#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c +msgid "Only one %q can be set in deep sleep." msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c -msgid "Must be a %q subclass." +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q πρέπει να είναι πίνακας τύπου 'H'" + +#: ports/espressif/common-hal/audiobusio/PDMIn.c +#: shared-bindings/audioi2sin/I2SIn.c +msgid "%q must be 8, 16, 24, or 32" msgstr "" -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -msgid "Must provide 5/6/5 RGB pins" +#: ports/espressif/common-hal/audiobusio/__init__.c +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +msgid "Peripheral in use" msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c -msgid "Must provide MISO or MOSI pin" +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 8 or 16" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Must use a multiple of 6 rgb pins, not %d" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "NLR jump failed. Likely memory corruption." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" msgstr "" -#: ports/espressif/common-hal/nvm/ByteArray.c -msgid "NVS Error" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" msgstr "" -#: shared-bindings/socketpool/SocketPool.c -msgid "Name or service not known" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "New bitmap must be same size as old bitmap" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -msgid "Nimble out of memory" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c -#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c -#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c -#: shared-bindings/paralleldisplaybus/ParallelBus.c -#: shared-module/bitbangio/SPI.c -msgid "No %q pin" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "No CCCD for this Characteristic" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" msgstr "" -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "No DAC on chip" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA channel found" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA pacing timer found" -msgstr "" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/nordic/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Όλα τα I2C περιφεριακά ειναι σε χρήση" -#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c -#, c-format -msgid "No I2C device at address: 0x%x" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c +msgid "Unable to create lock" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "No IP" +#: ports/espressif/common-hal/busio/SPI.c +msgid "SPI configuration failed" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/__init__.c -#: ports/cxd56/common-hal/microcontroller/__init__.c -#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c -msgid "No bootloader present" -msgstr "" +#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Όλα τα SPI περιφεριακά είναι σε χρήση" -#: shared-module/usb/core/Device.c -msgid "No configuration set" -msgstr "" +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/canio/CAN.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "ESP-IDF memory allocation failed" +msgstr "ESP-IDF δέσμευση μνήμης απέτυχε" -#: shared-bindings/_bleio/PacketBuffer.c -msgid "No connection: length cannot be determined" -msgstr "" +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Cannot specify RTS or CTS in RS485 mode" +msgstr "Δεν μπορεί να οριστεί RTS ή CTS σε RS485 mode" -#: shared-bindings/board/__init__.c -msgid "No default %q bus" +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "RS485 inversion specified when not in RS485 mode" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -msgid "No free GCLKs" +#: ports/espressif/common-hal/canio/CAN.c +msgid "Baudrate not supported by peripheral" +msgstr "Baudrate δεν υποστηρίζεται από την περιφεριακή συσκευή" + +#: ports/espressif/common-hal/canio/CAN.c +msgid "All CAN peripherals are in use" +msgstr "Όλα τα περιφεριακά CAN είναι σε χρήση" + +#: ports/espressif/common-hal/canio/CAN.c +msgid "loopback + silent mode not supported by peripheral" msgstr "" -#: shared-bindings/os/__init__.c -msgid "No hardware random available" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_driver_install returned esp-idf error #%d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in in program" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in or out in program" +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +msgid "Must provide 5/6/5 RGB pins" msgstr "" -#: py/objint.c shared-bindings/time/__init__.c -msgid "No long integer support" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is duplicate" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "No network with that ssid" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No out in program" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" -#: ports/atmel-samd/common-hal/busio/I2C.c -#: ports/espressif/common-hal/busio/I2C.c -#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/busio/I2C.c -msgid "No pull up found on SDA or SCL; check your wiring" +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c +msgid "no such attribute" msgstr "" -#: shared-module/touchio/TouchIn.c -msgid "No pulldown on pin; 1Mohm recommended" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" msgstr "" -#: py/moderrno.c -msgid "No space left on device" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Generic Failure" msgstr "" -#: py/moderrno.c -msgid "No such device" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Out of memory" msgstr "" -#: py/moderrno.c -msgid "No such file/directory" +#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c +msgid "Invalid argument" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "No timer available" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Invalid size" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No usb host port initialized" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Requested resource not found" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Nordic system firmware out of memory" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Operation or feature not supported" msgstr "" -#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string" +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "Operation timed out" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "Not connected" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Received response was invalid" msgstr "" -#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c -#: shared-bindings/audiopwmio/PWMAudioOut.c -msgid "Not playing" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "CRC or checksum was invalid" +msgstr "CRC ή checksum ήταν άκυρο" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Version was invalid" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Not supported JPEG standard" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "MAC address was invalid" msgstr "" -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format -msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +msgid "%s error 0x%x" +msgstr "%s σφάλμα 0x%x" -#: shared-bindings/util.c -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" msgstr "" -#: ports/nordic/common-hal/busio/UART.c -msgid "Odd parity is not supported" -msgstr "" +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/mipidsi/Bus.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/usb_host/Port.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c +msgid "%q in use" +msgstr "%q είναι σε χρήση" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Off" +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Ok" +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "Only one address is allowed" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +#: ports/espressif/common-hal/max3421e/Max3421E.c +#: ports/raspberrypi/common-hal/wifi/__init__.c #, c-format -msgid "Only 8 or 16 bit mono with %dx oversampling supported." +msgid "Unknown error code %d" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -msgid "Only IPv4 addresses supported" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS only works with built-in WiFi" msgstr "" -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Only IPv4 sockets supported" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS already initialized" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only Windows format, uncompressed BMP supported: given header size is %d" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Unable to start mDNS query" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Only connectable advertisements can be directed" +#: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nordic/common-hal/memorymap/AddressRange.c +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Εμβέλεια διευθύνσεων δεν επιτρέπεται" + +#: ports/espressif/common-hal/nvm/ByteArray.c +msgid "NVS Error" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Only edge detection is available on this hardware" +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d or %d, not %d" msgstr "" -#: shared-bindings/ipaddress/__init__.c -msgid "Only int or string supported for ip" +#: ports/espressif/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" msgstr "" -#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one %q can be set in deep sleep." +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-bindings/pwmio/PWMOut.c +#: supervisor/shared/settings.c +msgid "Internal error" msgstr "" -#: ports/espressif/common-hal/espulp/ULPAlarm.c -msgid "Only one %q can be set." +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" msgstr "" -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "Only one address is allowed" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" msgstr "" -#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c -#: ports/nordic/common-hal/alarm/time/TimeAlarm.c -#: ports/stm/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" msgstr "" -#: ports/espressif/common-hal/alarm/time/TimeAlarm.c -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set." +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" msgstr "" -#: shared-module/displayio/ColorConverter.c -msgid "Only one color can be transparent at a time" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" msgstr "" -#: py/moderrno.c -msgid "Operation not permitted" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation or feature not supported" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation timed out" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Out of MDNS service slots" +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "SDIO Init Error 0x%02x" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Out of memory" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Unsupported socket type" msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Out-buffer elements must be <= 4 bytes long" +#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "PWM restart" -msgstr "" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +msgid "%q must be <= %u" +msgstr "%q πρέπει να είναι <= %u" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "PWM slice already in use" +#: ports/espressif/common-hal/wifi/Monitor.c +msgid "monitor init failed" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "PWM slice channel A already in use" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Interface must be started" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Parameter error" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Invalid multicast MAC address" msgstr "" -#: ports/espressif/common-hal/audiobusio/__init__.c -msgid "Peripheral in use" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Already scanning for wifi networks" +msgstr "Ήδη γίνεται σάρωση για δίκτυα wifi" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" -#: py/moderrno.c -msgid "Permission denied" +#: ports/espressif/common-hal/wifi/ScannedNetworks.c +msgid "Failed to allocate wifi scan memory" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Pin cannot wake from Deep Sleep" +#: ports/espressif/common-hal/wifi/__init__.c +msgid "Failed to allocate Wifi memory" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Pin count too large" +#: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +msgid "Only IPv4 addresses supported" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -#: ports/stm/common-hal/pulseio/PulseIn.c -msgid "Pin interrupt already in use" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/busio/SPI.c +msgid "Must provide MISO or MOSI pin" msgstr "" -#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -msgid "Pin is input only" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c +#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c +#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c +msgid "Hardware in use, try alternative pins" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "Pin must be on PWM Channel B" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format +#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c msgid "" -"Pinout uses %d bytes per element, which consumes more than the ideal %d " -"bytes. If this cannot be avoided, pass allow_inefficient=True to the " -"constructor" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" -#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c -msgid "Pins must be sequential" +#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" -#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c -msgid "Pins must be sequential GPIO pins" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "timeout must be < 655.35 secs" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Pins must share PWM slice" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "non-zero timeout must be > 0.01" msgstr "" -#: shared-module/usb/core/Device.c -msgid "Pipe error" +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: timeout" msgstr "" -#: py/builtinhelp.c -msgid "Plus any modules on the filesystem\n" +#: ports/nordic/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" msgstr "" -#: shared-module/vectorio/Polygon.c -msgid "Polygon needs at least 3 points" +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Nordic system firmware out of memory" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Power dipped. Make sure you are providing enough power." +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %04x" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Prefix buffer must be on the heap" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown gatt error: 0x%04x" msgstr "" -#: main.c -msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +msgid "" +"Unspecified issue. The pairing request on the other device may have been " +"declined or ignored." msgstr "" -"Πατήστε οποιοδήποτε πλήκτρο για να μπείτε στο REPL. Πατήστε CTRL-D για " -"επαναφόρτωση.\n" - -#: main.c -msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" -msgstr "Προσποίηση βαθύ ύπνου μεχρι γεγονότος, CTRL-C ή εγγραφή αρχείου.\n" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does IN without loading ISR" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#, c-format +msgid "Unknown security error: 0x%04x" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does OUT without loading OSR" -msgstr "" +#: ports/nordic/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge, only level" +msgstr "Δεν γίνεται αφύπνηση σε pin edge, αλλά μόνο σε level" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Program size invalid" -msgstr "" +#: ports/nordic/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +msgstr "Συσκευή σε χρήση" -#: ports/espressif/common-hal/espulp/ULP.c -msgid "Program too long" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Pull not used when direction is output." +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "RISE_AND_FALL not available on this chip" +#: ports/nordic/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "RLE-compressed BMP not supported" +#: ports/nordic/common-hal/busio/UART.c +msgid "Odd parity is not supported" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG DeInit Error" -msgstr "" +#: ports/nordic/common-hal/countio/Counter.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +msgid "All channels in use" +msgstr "Όλα τα κανάλια είναι σε χρήση" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG Init Error" -msgstr "" +#: ports/nordic/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "Δεν μπορεί να διαβαστεί η θερμοκρασία" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "RS485 inversion specified when not in RS485 mode" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c -msgid "RTC is not supported on this board" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "%q cannot be changed once mode is set to %q" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "Random number generation error" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: shared-bindings/_bleio/__init__.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c -#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c -msgid "Read-only" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" msgstr "" -#: extmod/vfs_fat.c py/moderrno.c -msgid "Read-only filesystem" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "Η μετατροπή ήχου δεν υποστηρίζεται" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c +#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c +#: shared-module/synthio/Synthesizer.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q πρέπει να είναι τύπου %q ή %q, όχι %q" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Program size invalid" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Received response was invalid" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Init program size invalid" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Reconnecting" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Buffer elements must be 4 bytes long or less" +msgstr "Στοιχεία του buffer πρέπει να είναι το πολύ 4 bytes" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched data size" msgstr "" -#: shared-bindings/epaperdisplay/EPaperDisplay.c -msgid "Refresh too soon" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Out-buffer elements must be <= 4 bytes long" msgstr "" -#: shared-bindings/canio/RemoteTransmissionRequest.c -msgid "RemoteTransmissionRequests limited to 8 bytes" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "In-buffer elements must be <= 4 bytes long" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Requested AES mode is unsupported" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/I2C.c +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/I2C.c +#: shared-bindings/busio/SPI.c +msgid "Function requires lock" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Requested resource not found" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "Right channel unsupported" +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c +#: ports/stm/common-hal/alarm/touch/TouchAlarm.c +msgid "Touch alarms not available" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Right format but not supported" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" msgstr "" -#: main.c -msgid "Running in safe mode! Not running saved code.\n" -msgstr "" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "Bit clock and word select must be sequential GPIO pins" +msgstr "Ρολόι bit και ορισμού λέξης πρέπει να είναι διαδοχικά GPIO pins" -#: shared-module/sdcardio/SDCard.c -msgid "SD card CSD format not supported" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Too many channels in sample." msgstr "" -#: ports/cxd56/common-hal/sdioio/SDCard.c -msgid "SDCard init" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Audio source error" msgstr "" -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO GetCardInfo Error %d" +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 16, 24, or 32" msgstr "" -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO Init Error %x" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c -msgid "SPI configuration failed" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" msgstr "" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI init error" +#: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "I2C peripheral in use" msgstr "" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI re-init" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "Scale dimensions must divide by 3" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "Pin must be on PWM Channel B" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Scan already in progress. Stop with stop_scan." +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "RISE_AND_FALL not available on this chip" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -msgid "Serializer in use" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice already in use" msgstr "" -#: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice channel A already in use" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Size not supported" -msgstr "" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All state machines in use" +msgstr "Όλες οι μηχανές κατάστασης είναι σε χρήση" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Slice and value different lengths." +#: ports/raspberrypi/common-hal/floppyio/__init__.c +msgid "timeout waiting for flux" msgstr "" -#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/TileGrid.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Slices not supported" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: shared-module/floppyio/__init__.c +msgid "timeout waiting for index pulse" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c -#: ports/raspberrypi/common-hal/socketpool/SocketPool.c -msgid "SocketPool can only be used with wifi.radio" +#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +msgid "Pins must be sequential" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Source and destination buffers must be the same length" +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +msgid "Invalid %q and %q" msgstr "" -#: shared-bindings/paralleldisplaybus/ParallelBus.c -msgid "Specify exactly one of data0 or data_pins" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Failed to add service TXT record" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Stack overflow. Increase stack size." +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Supply one of monotonic_time or epoch_time" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to access unaligned IO register" msgstr "" -#: shared-bindings/gnss/GNSS.c -msgid "System entry must be gnss.SatelliteSystem" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to write to read-only memory" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Temperature read timed out" -msgstr "" +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +msgid "All timers for this pin are in use" +msgstr "Όλοι οι χρονιστές για αυτό το pin χρησιμοποιούνται ήδη" -#: supervisor/shared/safe_mode.c -msgid "The `microcontroller` module was used to boot into safe mode." +#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c +msgid "Pins must be sequential GPIO pins" msgstr "" -#: py/obj.c -msgid "The above exception was the direct cause of the following exception:" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Pin count too large" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing jmp_pin. %q[%u] jumps on pin" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] uses extra pin" +msgstr "%q[%u] χρησιμοποιεί παραπάνω pin" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] waits based on pin" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] waits on input outside of count" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Third-party firmware fatal error." -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts in more bits than pin count" +msgstr "%q[%u] μετατοπίζει σε περισσότερα bits από αριθμό pin" -#: shared-module/imagecapture/ParallelImageCapture.c -msgid "This microcontroller does not support continuous capture." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" msgstr "" -#: shared-module/paralleldisplaybus/ParallelBus.c -msgid "" -"This microcontroller only supports data0=, not data_pins=, because it " -"requires contiguous pins." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts out more bits than pin count" +msgstr "%q[%u] μετατοπίζει από περισσότερα bits από αριθμό pin" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_set_pin. %q[%u] sets pin(s)" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile height must exactly divide bitmap height" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] writes pin(s)" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c -msgid "Tile index out of bounds" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] reads pin(s)" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile width must exactly divide bitmap width" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does IN without loading ISR" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Time is in the past." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does OUT without loading OSR" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -#, c-format -msgid "Timeout is too long: Maximum timeout length is %d seconds" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin state conflicts with initial out pin state" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin direction conflicts with initial out pin direction" msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "pull masks conflict with direction masks" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -msgid "Too many descriptors" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No out in program" msgstr "" -#: shared-module/displayio/__init__.c -msgid "Too many display busses; forgot displayio.release_displays() ?" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in in program" msgstr "" -#: shared-module/displayio/__init__.c -msgid "Too many displays" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in or out in program" msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than %q" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched swap flag" msgstr "" -#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c -#: ports/stm/common-hal/alarm/touch/TouchAlarm.c -msgid "Touch alarms not available" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d, not %d" msgstr "" -#: py/obj.c -msgid "Traceback (most recent call last):\n" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +msgid "Data pins must be consecutive" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART de-init" +#: ports/raspberrypi/common-hal/socketpool/Socket.c +msgid "Only IPv4 sockets supported" msgstr "" -#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c -#: ports/stm/common-hal/busio/UART.c -msgid "UART init" +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All dma channels in use" +msgstr "Όλα τα κανάλια dma είναι σε χρήση" + +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" msgstr "" -#: ports/raspberrypi/common-hal/busio/UART.c -msgid "UART peripheral in use" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q είναι μόνο για ανάγνωση για αυτήν την πλακέτα" + +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "AP could not be started" +msgstr "AP δεν μπόρεσε να εκκινηθεί" + +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Only edge detection is available on this hardware" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART re-init" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +#: ports/stm/common-hal/pulseio/PulseIn.c +msgid "Pin interrupt already in use" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART write" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Pin cannot wake from Deep Sleep" msgstr "" -#: main.c -msgid "UID:" -msgstr "" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Deep sleep pins must use a rising edge with pulldown" +msgstr "Τα pins βαθύ ύπνου πρέπει να χρησιμοποιούν rising edge με pulldown" -#: shared-module/usb_hid/Device.c -msgid "USB busy" +#: ports/stm/common-hal/analogio/AnalogIn.c +msgid "Invalid ADC Unit value" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "USB devices need more endpoints than are available." -msgstr "" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Device Init Error" +msgstr "Σφάλμα εκκίνησης συσκευής DAC" -#: supervisor/shared/safe_mode.c -msgid "USB devices specify too many interface names." -msgstr "" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Channel Init Error" +msgstr "Σφάλμα εκκίνησης καναλιού DAC" -#: shared-module/usb_hid/Device.c -msgid "USB error" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID integer value must be 0-0xffff" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" -msgstr "" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Another PWMAudioOut is already active" +msgstr "Και άλλο PWMAudioOut είναι σε χρήση" -#: shared-bindings/_bleio/UUID.c -msgid "UUID value is not str, int or byte buffer" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "Το μήκος buffer %d είναι πολύ μεγάλο. Πρέπει ν α είναι λιγότερο απο %d" + +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Failed to buffer the sample" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to access unaligned IO register" +#: ports/stm/common-hal/busio/I2C.c +msgid "I2C init error" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Unable to allocate buffers for signed conversion" +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI init error" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Unable to allocate to the heap." +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI re-init" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "Unable to create lock" +#: ports/stm/common-hal/busio/UART.c +msgid "Internal define error" msgstr "" -#: shared-module/i2cdisplaybus/I2CDisplayBus.c -#: shared-module/is31fl3741/IS31FL3741.c -#, c-format -msgid "Unable to find I2C Display at %x" +#: ports/stm/common-hal/busio/UART.c +msgid "Could not start interrupt, RX busy" +msgstr "Δεν μπόρεσε να εκκινηθεί το interrupt, RX κατειλημμένο" + +#: ports/stm/common-hal/busio/UART.c +msgid "UART write" msgstr "" -#: py/parse.c -msgid "Unable to init parser" +#: ports/stm/common-hal/busio/UART.c +msgid "UART de-init" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "Unable to read color palette data" +#: ports/stm/common-hal/busio/UART.c +msgid "UART re-init" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Unable to start mDNS query" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Temperature read timed out" msgstr "" -#: shared-bindings/nvm/ByteArray.c -msgid "Unable to write to nvm." +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Voltage read timed out" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to write to read-only memory" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG Init Error" msgstr "" -#: shared-bindings/alarm/SleepMemory.c -msgid "Unable to write to sleep_memory." +#: ports/stm/common-hal/os/__init__.c +msgid "Random number generation error" msgstr "" -#: ports/nordic/common-hal/_bleio/UUID.c -msgid "Unexpected nrfx uuid type" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG DeInit Error" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error at %s:%d: %d" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "timer re-init" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error: %d" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "channel re-init" msgstr "" -#: ports/espressif/common-hal/max3421e/Max3421E.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unknown error code %d" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "PWM restart" msgstr "" -#: shared-bindings/wifi/Radio.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "Unknown failure %d" +msgid "MMC/SDIO Clock Error %x" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "Unknown gatt error: 0x%04x" +msgid "SDIO GetCardInfo Error %d" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: supervisor/shared/safe_mode.c -msgid "Unknown reason." -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid ".show(x) removed. Use .root_group = x" +msgstr ".show(x) αφαιρέθηκε. Χρησιμοποιήστε το .root_group = x" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown security error: 0x%04x" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Brightness not adjustable" +msgstr "H φωτεινότητα δεν μπορεί να προσαρμοστεί" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error at %s:%d: %d" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c py/argcheck.c +#: shared-bindings/busdisplay/BusDisplay.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "%q must be %d-%d" +msgstr "%q πρέπει να είναι %d-%d" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %04x" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Group already used" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %d" +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Invalid advertising data" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -#: shared-module/_pixelmap/PixelMap.c -#, c-format -msgid "Unmatched number of items on RHS (expected %d, got %d)." +#: ports/zephyr-cp/common-hal/audiobusio/I2SOut.c +#: ports/zephyr-cp/common-hal/busio/I2C.c +#: ports/zephyr-cp/common-hal/busio/SPI.c +#: ports/zephyr-cp/common-hal/busio/UART.c +msgid "Use device tree to define %q devices" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "" -"Unspecified issue. Can be that the pairing prompt on the other device was " -"declined or ignored." +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Unsupported colorspace" +#: ports/zephyr-cp/common-hal/usb_hid/Device.c shared-module/usb_hid/Device.c +msgid "USB error" msgstr "" -#: shared-module/displayio/bus_core.c -msgid "Unsupported display bus type" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "" +#: ports/zephyr-cp/common-hal/zephyr_display/Display.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Below minimum frame rate" +msgstr "Χαμηλότερο από το ελάχιστο frame rate" -#: shared-bindings/hashlib/__init__.c -msgid "Unsupported hash algorithm" +#: py/argcheck.c +msgid "function doesn't take keyword arguments" msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -msgid "Unsupported socket type" +#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c +#: shared-bindings/time/__init__.c +#, c-format +msgid "function takes %d positional arguments but %d were given" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Update failed" +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length != required fixed length" +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length > max_length" -msgstr "" +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' όρισμα απαιτείται" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Version was invalid" +#: py/argcheck.c +msgid "extra positional arguments given" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Voltage read timed out" +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c +msgid "unexpected keyword argument '%q'" msgstr "" -#: main.c -msgid "WARNING: Your code filename has two extensions\n" +#: py/argcheck.c +msgid "extra keyword arguments given" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c +msgid "argument num/types mismatch" msgstr "" -#: py/builtinhelp.c -#, c-format -msgid "" -"Welcome to Adafruit CircuitPython %s!\n" -"\n" -"Visit circuitpython.org for more information.\n" -"\n" -"To list built-in modules type `help(\"modules\")`.\n" +#: py/argcheck.c +msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "Wi-Fi: " -msgstr "" +#: py/argcheck.c +msgid "%q must be %d" +msgstr "%q πρέπει να είναι %d" + +#: py/argcheck.c +msgid "%q must be >= %d" +msgstr "%q πρέπει να είναι >= %d" + +#: py/argcheck.c shared-bindings/gifio/GifWriter.c +#: shared-module/gifio/OnDiskGif.c +msgid "%q must be <= %d" +msgstr "%q πρέπει να είναι <= %d" + +#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c +#: shared-module/synthio/__init__.c +msgid "%q must be of type %q, not %q" +msgstr "%q πρέπει να είναι τύπου %q, όχι %q" + +#: py/argcheck.c +msgid "%q length must be %d-%d" +msgstr "%q μήκος πρέπει να είναι %d-%d" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "" +#: py/argcheck.c +msgid "%q length must be >= %d" +msgstr "%q μήκος πρέπει να είναι >= %d" -#: main.c -msgid "Woken up by alarm.\n" -msgstr "" +#: py/argcheck.c +msgid "%q length must be <= %d" +msgstr "%q μήκος πρέπει να είναι <= %d" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Writes not supported on Characteristic" -msgstr "" +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" +msgstr "%q μήκος πρέπει να είναι %d" -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "You pressed both buttons at start up." -msgstr "" +#: py/argcheck.c shared-module/audiofilters/Filter.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q στο %q πρέπει να είναι τύπου %q, όχι %q" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h -msgid "You pressed button A at start up." +#: py/asmthumb.c +msgid "too many locals for native method" msgstr "" -#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h -msgid "You pressed button DOWN at start up." +#: py/asmxtensa.c +msgid "ERROR: xtensa %q out of range" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up" +#: py/asmxtensa.c +msgid "ERROR: %q %q not word-aligned" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h -#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h -msgid "You pressed the BOOT button at start up." -msgstr "" +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() παίρνει %d ορίσματα θέσεως αλλά %d δόθηκαν" -#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h -msgid "You pressed the GPIO0 button at start up." +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" msgstr "" -#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h -msgid "You pressed the Rec button at start up." +#: py/bc.c +msgid "unexpected keyword argument" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "You pressed the SW38 button at start up." +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" msgstr "" -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -#: ports/espressif/boards/vidi_x/mpconfigboard.h -msgid "You pressed the VOLUME button at start up." +#: py/bc.c +msgid "function missing required keyword argument '%q'" msgstr "" -#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h -msgid "You pressed the central button at start up." +#: py/bc.c +msgid "function missing keyword-only argument" msgstr "" -#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h -msgid "You pressed the left button at start up." +#: py/binary.c py/objarray.c +msgid "bad typecode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the reset button during boot." +#: py/builtinevex.c +msgid "bad compile mode" msgstr "" -#: supervisor/shared/micropython.c -msgid "[truncated due to length]" +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" msgstr "" -#: py/objtype.c -msgid "__init__() should return None" +#: py/builtinhelp.c +msgid "object " msgstr "" -#: py/objtype.c +#: py/builtinhelp.c +msgid " is of type %q\n" +msgstr " είναι τύπου %q\n" + +#: py/builtinhelp.c #, c-format -msgid "__init__() should return None, not '%s'" +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Visit circuitpython.org for more information.\n" +"\n" +"To list built-in modules type `help(\"modules\")`.\n" msgstr "" -#: py/objobject.c -msgid "__new__ arg must be a user-type" +#: py/builtinimport.c +msgid "script compilation not supported" msgstr "" -#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c -msgid "a bytes-like object is required" +#: py/builtinimport.c +msgid "can't perform relative import" msgstr "" -#: shared-bindings/i2ctarget/I2CTarget.c -msgid "addresses is empty" +#: py/builtinimport.c +msgid "module not found" msgstr "" -#: py/compile.c -msgid "annotation must be an identifier" +#: py/builtinimport.c +msgid "no module named '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "arange: cannot compute length" +#: py/builtinimport.c +msgid "relative import" msgstr "" -#: py/modbuiltins.c -msgid "arg is an empty sequence" +#: py/compile.c +msgid "can't assign to expression" msgstr "" -#: py/objobject.c -msgid "arg must be user-type" +#: py/compile.c +msgid "multiple *x in assignment" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort argument must be an ndarray" +#: py/compile.c +msgid "non-default argument follows default argument" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort is not implemented for flattened arrays" +#: py/compile.c +msgid "invalid micropython decorator" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "argument must be None, an integer or a tuple of integers" +#: py/compile.c +msgid "invalid arch" msgstr "" #: py/compile.c -msgid "argument name reused" +msgid "can't delete expression" msgstr "" -#: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c -msgid "argument num/types mismatch" -msgstr "" +#: py/compile.c +msgid "'break'/'continue' outside loop" +msgstr "'break'/'continue' εκτός επανάληψης" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c -msgid "arguments must be ndarrays" +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' εκτός συνάρτησης" + +#: py/compile.c +msgid "import * not at module level" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array and index length must be equal" +#: py/compile.c +msgid "identifier redefined as global" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "array has too many dimensions" +#: py/compile.c +msgid "no binding for nonlocal found" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array is too big" +#: py/compile.c +msgid "identifier redefined as nonlocal" msgstr "" -#: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c -msgid "array/bytes required on right side" +#: py/compile.c +msgid "can't declare nonlocal in outer code" msgstr "" -#: py/asmxtensa.c -msgid "asm overflow" +#: py/compile.c +msgid "default 'except' must be last" msgstr "" #: py/compile.c msgid "async for/with outside async function" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get (arg)min/(arg)max of empty sequence" -msgstr "" +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x πρέπει να είναι στόχος ανάθεσης" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get argmin/argmax of an empty sequence" +#: py/compile.c +msgid "super() can't find self" msgstr "" -#: py/objstr.c -msgid "attributes not supported" -msgstr "" +#: py/compile.c +msgid "* arg after **" +msgstr "* όρισμα μετά **" -#: extmod/ulab/code/ulab_tools.c -msgid "axis is out of bounds" +#: py/compile.c +msgid "too many args" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -msgid "axis must be None, or an integer" +#: py/compile.c +msgid "LHS of keyword arg must be an id" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "axis too long" +#: py/compile.c +msgid "positional arg after **" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "background value out of range of target" +#: py/compile.c +msgid "positional arg after keyword arg" msgstr "" -#: py/builtinevex.c -msgid "bad compile mode" +#: py/compile.c py/parse.c +msgid "invalid syntax" msgstr "" -#: py/objstr.c -msgid "bad conversion specifier" +#: py/compile.c +msgid "expecting key:value for dict" msgstr "" -#: py/objstr.c -msgid "bad format string" +#: py/compile.c +msgid "expecting just a value for set" msgstr "" -#: py/binary.c py/objarray.c -msgid "bad typecode" -msgstr "" +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' εκτός συνάρτησης" -#: py/emitnative.c -msgid "binary op %q not implemented" -msgstr "" +#: py/compile.c +msgid "'yield from' inside async function" +msgstr "'yield from' εκτός ασύνχρονης συνάρτησης" -#: shared-module/bitmapfilter/__init__.c -msgid "bitmap size and depth must match" -msgstr "" +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' εκτός συνάρτησης" -#: shared-bindings/bitmaptools/__init__.c -msgid "bitmap sizes must match" +#: py/compile.c +msgid "unknown type '%q'" msgstr "" -#: extmod/modrandom.c -msgid "bits must be 32 or less" +#: py/compile.c +msgid "annotation must be an identifier" msgstr "" -#: shared-bindings/audiomixer/Mixer.c -msgid "bits_per_sample must be 8 or 16" +#: py/compile.c +msgid "argument name reused" msgstr "" -#: py/emitinlinethumb.c -msgid "branch not in range" +#: py/compile.c +msgid "inline assembler must be a function" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer is smaller than requested size" +#: py/compile.c +msgid "unknown type" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer size must be a multiple of element size" +#: py/compile.c +msgid "return annotation must be an identifier" msgstr "" -#: shared-module/struct/__init__.c -msgid "buffer size must match format" +#: py/compile.c +msgid "expecting an assembler instruction" msgstr "" -#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c -msgid "buffer slices must be of equal length" -msgstr "" +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' απαιτεί ένα όρισμα" -#: py/modstruct.c shared-module/struct/__init__.c -msgid "buffer too small" +#: py/compile.c +msgid "label redefined" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "buffer too small for requested bytes" +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' απαιτεί τουλάχιστον ένα όρισμα" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' απαιτεί τουλάχιστον 2 παραμέτρους" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' απαιτεί ακέραιες παραμέτρους" + +#: py/compile.c +msgid "cannot emit native code for this architecture" msgstr "" #: py/emitbc.c msgid "bytecode overflow" msgstr "" -#: py/objarray.c -msgid "bytes length not a multiple of item size" +#: py/emitinlinerv32.c +msgid "can only have up to 4 parameters for RV32 assembly" msgstr "" -#: py/objstr.c -msgid "bytes value out of range" +#: py/emitinlinerv32.c +msgid "parameters must be registers in sequence a0 to a3" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is out of range" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: expecting %q" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is read only" +#: py/emitinlinerv32.c +msgid "opcode '%q': expecting %d arguments" msgstr "" -#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c -#: shared-module/vectorio/Rectangle.c -msgid "can only have one parent" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: out of range" msgstr "" -#: py/emitinlinethumb.c -msgid "can only have up to 4 parameters to Thumb assembly" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: unknown register" msgstr "" -#: py/emitinlinextensa.c -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: undefined label '%q'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "can only specify one unknown dimension" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: must not be zero" msgstr "" -#: py/objtype.c -msgid "can't add special method to already-subclassed class" +#: py/emitinlinerv32.c +msgid "invalid RV32 instruction '%q'" msgstr "" -#: py/compile.c -msgid "can't assign to expression" +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: extmod/modasyncio.c -msgid "can't cancel self" +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c -msgid "can't convert %q to %q" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' περιμένει το πολύ r%d" -#: py/obj.c +#: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format -msgid "can't convert %s to complex" -msgstr "" +msgid "'%s' expects a register" +msgstr "'%s' περιμένει έναν καταχωρητή" -#: py/obj.c +#: py/emitinlinethumb.c #, c-format -msgid "can't convert %s to float" -msgstr "" +msgid "'%s' expects a special register" +msgstr "'%s' περιμένει έναν ειδικό καταχωρητή" -#: py/objint.c py/runtime.c +#: py/emitinlinethumb.c #, c-format -msgid "can't convert %s to int" -msgstr "" +msgid "'%s' expects an FPU register" +msgstr "'%s' περιμένει έναν FPU καταχωρητή" -#: py/objstr.c -msgid "can't convert '%q' object to %q implicitly" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' περιμένει {r0, r1, ...}" -#: extmod/ulab/code/numpy/vector.c -msgid "can't convert complex to float" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' περιμένει έναν ακέραιο" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" +msgstr "'%s' ακέραιος 0x%x δεν χωράει στην μάσκα 0x%x" + +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' περιμένει μια διεύθυνση της μορφής [a, b]" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' περιμένει μια ετικέτα" + +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" msgstr "" -#: py/obj.c -msgid "can't convert to complex" +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" -#: py/obj.c -msgid "can't convert to float" +#: py/emitinlinethumb.c +msgid "branch not in range" msgstr "" -#: py/runtime.c -msgid "can't convert to int" +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/objstr.c -msgid "can't convert to str implicitly" +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" msgstr "" -#: py/compile.c -msgid "can't declare nonlocal in outer code" +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d isn't within range %d..%d" +msgstr "'%s' ακέραιος %d δεν είναι μέσα στο επιτρεπτό εύρος %d..%d" + +#: py/emitinlinextensa.c +#, c-format +msgid "%d is not a multiple of %d" msgstr "" -#: py/compile.c -msgid "can't delete expression" +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" msgstr "" #: py/emitnative.c -msgid "can't do binary op between '%q' and '%q'" +msgid "conversion to object" msgstr "" #: py/emitnative.c -msgid "can't do unary op of '%q'" +msgid "local '%q' used before type known" msgstr "" #: py/emitnative.c -msgid "can't implicitly convert '%q' to 'bool'" +msgid "can't load from '%q'" msgstr "" -#: py/runtime.c -msgid "can't import name %q" +#: py/emitnative.c +msgid "can't load with '%q' index" msgstr "" #: py/emitnative.c -msgid "can't load from '%q'" +msgid "local '%q' has type '%q' but source is '%q'" msgstr "" #: py/emitnative.c -msgid "can't load with '%q' index" +msgid "can't store '%q'" msgstr "" -#: py/builtinimport.c -msgid "can't perform relative import" +#: py/emitnative.c +msgid "can't store to '%q'" msgstr "" -#: py/objgenerator.c -msgid "can't send non-None value to a just-started generator" +#: py/emitnative.c +msgid "can't store with '%q' index" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "can't set 512 block size" +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" msgstr "" -#: py/objexcept.c py/objnamedtuple.c -msgid "can't set attribute" +#: py/emitnative.c +msgid "'not' not implemented" msgstr "" -#: py/runtime.c -msgid "can't set attribute '%q'" +#: py/emitnative.c +msgid "can't do unary op of '%q'" msgstr "" #: py/emitnative.c -msgid "can't store '%q'" +msgid "div/mod not implemented for uint" msgstr "" #: py/emitnative.c -msgid "can't store to '%q'" +msgid "comparison of int and uint" msgstr "" #: py/emitnative.c -msgid "can't store with '%q' index" +msgid "binary op %q not implemented" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from automatic field numbering to manual field specification" +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from manual field specification to automatic field numbering" +#: py/emitnative.c +msgid "casting" msgstr "" -#: py/objcomplex.c -msgid "can't truncate-divide a complex number" +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" msgstr "" -#: extmod/modasyncio.c -msgid "can't wait" +#: py/emitnative.c +msgid "must raise an object" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot assign new shape" +#: py/emitnative.c +msgid "native yield" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "cannot cast output with casting rule" +#: py/lexer.c +msgid "unicode name escapes" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex to dtype" +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex type" +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" msgstr "" -#: py/objtype.c -msgid "cannot create '%q' instances" +#: py/modbuiltins.c +msgid "arg is an empty sequence" msgstr "" -#: py/objtype.c -msgid "cannot create instance" +#: py/modbuiltins.c +msgid "ord expects a character" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot delete array elements" +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot reshape array" -msgstr "" +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "pow() με 3 παραμέτρους δεν υποστηρίζεται" -#: py/emitnative.c -msgid "casting" +#: py/modbuiltins.c +msgid "must use keyword argument for key function" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "channel re-init" +#: py/moderrno.c +msgid "Operation not permitted" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "chars buffer too small" +#: py/moderrno.c +msgid "No such file/directory" msgstr "" -#: py/modbuiltins.c -msgid "chr() arg not in range(0x110000)" +#: py/moderrno.c +msgid "Input/output error" msgstr "" -#: py/modbuiltins.c -msgid "chr() arg not in range(256)" +#: py/moderrno.c +msgid "Permission denied" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "clip point must be (x,y) tuple" +#: py/moderrno.c +msgid "File exists" msgstr "" -#: shared-bindings/msgpack/ExtType.c -msgid "code outside range 0~127" +#: py/moderrno.c +msgid "No such device" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +#: py/moderrno.c +msgid "No space left on device" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a buffer, tuple, list, or int" +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +#: py/modmath.c +msgid "negative factorial" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color must be between 0x000000 and 0xffffff" +#: py/modmicropython.c +msgid "schedule queue full" msgstr "" -#: py/emitnative.c -msgid "comparison of int and uint" +#: py/modstruct.c shared-module/struct/__init__.c +msgid "buffer too small" msgstr "" -#: py/objcomplex.c -msgid "complex divide by zero" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" msgstr "" -#: py/objfloat.c py/parsenum.c -msgid "complex values not supported" +#: py/modthread.c +msgid "expecting a dict for keyword args" msgstr "" -#: extmod/modzlib.c -msgid "compression header" +#: py/nativeglue.c +msgid "set unsupported" msgstr "" -#: py/emitnative.c -msgid "conversion to object" +#: py/nativeglue.c +msgid "slice unsupported" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be linear arrays" +#: py/nativeglue.c +msgid "float unsupported" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be ndarrays" +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c +msgid "can't convert %q to %q" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must not be empty" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" msgstr "" +"Κατά την αντιμετώπιση της παραπάνω εξαίρεσης, ακόμα μία εξαίρεση συνέβη:" -#: extmod/ulab/code/numpy/io/io.c -msgid "corrupted file" +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "could not invert Vandermonde matrix" -msgstr "" +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Αρχείο \"%q\", γραμμή %d" -#: shared-module/sdcardio/SDCard.c -msgid "couldn't determine SD card version" +#: py/obj.c +msgid " File \"%q\"" +msgstr " Αρχείο \"%q\"" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", στο %q\n" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "cross is defined for 1D arrays of length 3" +#: py/obj.c +msgid "can't convert to float" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be iterable" +#: py/obj.c +#, c-format +msgid "can't convert %s to float" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be of equal length" +#: py/obj.c +msgid "can't convert to complex" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: py/obj.c #, c-format -msgid "data pin #%d in use" +msgid "can't convert %s to complex" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "data type not understood" +#: py/obj.c +msgid "expected tuple/list" msgstr "" -#: py/parsenum.c -msgid "decimal numbers not supported" +#: py/obj.c +#, c-format +msgid "object '%s' isn't a tuple or list" msgstr "" -#: py/compile.c -msgid "default 'except' must be last" +#: py/obj.c +msgid "tuple/list has wrong length" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "default is not a function" +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +#: py/obj.c +msgid "indices must be integers" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q δείκτες πρέπει να είναι ακέραιοι, όχι %s" + +#: py/obj.c +msgid "object has no len" msgstr "" -#: py/objdict.c -msgid "dict update sequence has wrong length" +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "diff argument must be an ndarray" +#: py/obj.c +msgid "object doesn't support item deletion" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "differentiation order out of range" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item deletion" +msgstr "'%s' αντικείμενο δεν υποστηρίζει διαγραφή πράγματος" + +#: py/obj.c +msgid "object isn't subscriptable" msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "dimensions do not match" +#: py/obj.c +#, c-format +msgid "'%s' object isn't subscriptable" +msgstr "'%s' αντικείμενο δεν είναι subscriptable" + +#: py/obj.c +msgid "object doesn't support item assignment" msgstr "" -#: py/emitnative.c -msgid "div/mod not implemented for uint" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item assignment" +msgstr "'%s' αντικείμενο δεν υποστηρίζει ορισμό πράγματος" + +#: py/obj.c +msgid "object with buffer protocol required" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "divide by zero" +#: py/objarray.c +msgid "bytes length not a multiple of item size" msgstr "" -#: py/runtime.c -msgid "division by zero" +#: py/objarray.c py/objstr.c +msgid "string argument without an encoding" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "dtype must be float, or complex" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "dtype of int32 is not supported" +#: py/objarray.c py/objstr.c +msgid "substring not found" msgstr "" -#: py/objdeque.c -msgid "empty" +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "empty file" +#: py/objarray.c +msgid "lhs and rhs should be compatible" msgstr "" -#: extmod/modasyncio.c extmod/modheapq.c -msgid "empty heap" +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" msgstr "" -#: py/objstr.c -msgid "empty separator" +#: py/objarray.c +msgid "memoryview offset too large" msgstr "" -#: shared-bindings/random/__init__.c -msgid "empty sequence" +#: py/objcomplex.c +msgid "can't truncate-divide a complex number" msgstr "" -#: py/objstr.c -msgid "end of format while looking for conversion specifier" +#: py/objcomplex.c +msgid "complex divide by zero" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "epoch_time not supported on this board" +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 σε μία σύνθετη δύναμη" + +#: py/objdeque.c +msgid "full" msgstr "" -#: ports/nordic/common-hal/busio/UART.c -#, c-format -msgid "error = 0x%08lX" +#: py/objdeque.c +msgid "empty" msgstr "" -#: py/runtime.c -msgid "exceptions must derive from BaseException" +#: py/objdict.c +msgid "dict update sequence has wrong length" msgstr "" -#: py/objstr.c -msgid "expected ':' after format specifier" +#: py/objexcept.c py/objnamedtuple.c +msgid "can't set attribute" msgstr "" -#: py/obj.c -msgid "expected tuple/list" +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" msgstr "" -#: py/modthread.c -msgid "expecting a dict for keyword args" +#: py/objgenerator.c +msgid "generator already executing" msgstr "" -#: py/compile.c -msgid "expecting an assembler instruction" +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" msgstr "" -#: py/compile.c -msgid "expecting just a value for set" +#: py/objgenerator.c py/runtime.c +msgid "generator raised StopIteration" msgstr "" -#: py/compile.c -msgid "expecting key:value for dict" +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "ext_hook is not a function" +#: py/objint.c py/runtime.c +#, c-format +msgid "can't convert %s to int" msgstr "" -#: py/argcheck.c -msgid "extra keyword arguments given" +#: py/objint.c +msgid "float too big" msgstr "" -#: py/argcheck.c -msgid "extra positional arguments given" +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" msgstr "" -#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c -#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c -msgid "file must be a file opened in byte mode" +#: py/objint.c shared-bindings/time/__init__.c +msgid "No long integer support" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "file write is not available" +#: py/objint.c py/sequence.c +msgid "small int overflow" msgstr "" +#: py/objint.c shared-bindings/_bleio/Connection.c #: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" +msgid "%q=%q" +msgstr "%q=%q" + +#: py/objint_longlong.c py/parsenum.c +msgid "result overflows long long storage" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "first argument must be a callable" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative shift count" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "first argument must be a function" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "first argument must be a tuple of ndarrays" +#: py/objint_longlong.c py/objint_mpz.c +msgid "overflow converting long int to machine word" msgstr "" -#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c -msgid "first argument must be an ndarray" +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" msgstr "" -#: py/objtype.c -msgid "first argument to super() must be type" +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "first two arguments must be ndarrays" +#: py/objobject.c +msgid "__new__ arg must be a user-type" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "flattening order must be either 'C', or 'F'" +#: py/objobject.c +msgid "arg must be user-type" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "flip argument must be an ndarray" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "%q βήμα δεν μπορεί να είναι μηδέν" + +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Δεν γίνεται υποκατηγορία ενός slice" + +#: py/objstr.c +msgid "bytes value out of range" msgstr "" -#: py/objint.c -msgid "float too big" +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" msgstr "" -#: py/nativeglue.c -msgid "float unsupported" +#: py/objstr.c +msgid "empty separator" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "font must be 2048 bytes long" +#: py/objstr.c +msgid "rsplit(None,n)" msgstr "" -#: extmod/moddeflate.c -msgid "format" +#: py/objstr.c +msgid "bad format string" msgstr "" #: py/objstr.c -msgid "format requires a dict" +#, c-format +msgid "unmatched '%c' in format" msgstr "" -#: py/objdeque.c -msgid "full" +#: py/objstr.c +msgid "bad conversion specifier" msgstr "" -#: py/argcheck.c -msgid "function doesn't take keyword arguments" +#: py/objstr.c +msgid "end of format while looking for conversion specifier" msgstr "" -#: py/argcheck.c +#: py/objstr.c #, c-format -msgid "function expected at most %d arguments, got %d" +msgid "unknown conversion specifier %c" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "function got multiple values for argument '%q'" +#: py/objstr.c +msgid "expected ':' after format specifier" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "function has the same sign at the ends of interval" +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "function is defined for ndarrays only" +#: py/objstr.c +msgid "%q index out of range" +msgstr "%q δείκτης εκτός εμβέλειας" + +#: py/objstr.c +msgid "attributes not supported" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "function is implemented for ndarrays only" +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" msgstr "" -#: py/argcheck.c -#, c-format -msgid "function missing %d required positional arguments" +#: py/objstr.c +msgid "invalid format specifier" msgstr "" -#: py/bc.c -msgid "function missing keyword-only argument" +#: py/objstr.c +msgid "sign not allowed in string format specifier" msgstr "" -#: py/bc.c -msgid "function missing required keyword argument '%q'" +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/bc.c -#, c-format -msgid "function missing required positional argument #%d" +#: py/objstr.c +msgid "unknown format code '%c' for object of type '%q'" msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c -#: shared-bindings/time/__init__.c -#, c-format -msgid "function takes %d positional arguments but %d were given" +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "Ευθυγράμμιση του '=' δεν επιτρέπεται εντός προσδιοριστή string format" + +#: py/objstr.c +msgid "format needs a dict" msgstr "" -#: py/objgenerator.c -msgid "generator already executing" +#: py/objstr.c +msgid "incomplete format key" msgstr "" -#: py/objgenerator.c -msgid "generator ignored GeneratorExit" +#: py/objstr.c +msgid "incomplete format" msgstr "" -#: py/objgenerator.c py/runtime.c -msgid "generator raised StopIteration" +#: py/objstr.c +msgid "format string needs more arguments" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "graphic must be 2048 bytes long" +#: py/objstr.c +#, c-format +msgid "%%c needs int or char" msgstr "" -#: extmod/modhashlib.c -msgid "hash is final" +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" msgstr "" -#: extmod/modheapq.c -msgid "heap must be a list" +#: py/objstr.c +msgid "format string didn't convert all arguments" msgstr "" -#: py/compile.c -msgid "identifier redefined as global" +#: py/objstr.c +msgid "non-hex digit" msgstr "" -#: py/compile.c -msgid "identifier redefined as nonlocal" +#: py/objstr.c +msgid "can't convert to str implicitly" msgstr "" -#: py/compile.c -msgid "import * not at module level" +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" msgstr "" -#: py/persistentcode.c -msgid "incompatible .mpy arch" +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" msgstr "" -#: py/persistentcode.c -msgid "incompatible .mpy file" +#: py/objstrunicode.c +msgid "string index out of range" msgstr "" -#: py/objstr.c -msgid "incomplete format" +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "Κλήση super().__init__() πρίν την πρόσβαση του τοπικού αντικειμένου." + +#: py/objtype.c +msgid "__init__() should return None" msgstr "" -#: py/objstr.c -msgid "incomplete format key" +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" msgstr "" -#: extmod/modbinascii.c -msgid "incorrect padding" +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c -msgid "index is out of bounds" +#: py/objtype.c py/runtime.c +msgid "object not callable" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "index must be tuple or int" +#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c +msgid "'%q' object isn't callable" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: py/objtype.c +msgid "type takes 1 or 3 arguments" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: py/objtype.c +msgid "can't create instance" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "indices must be integers, slices, or Boolean lists" +#: py/objtype.c +msgid "can't create '%q' instances" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" +#: py/objtype.c +msgid "can't add special method to already-subclassed class" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "initial values must be iterable" +#: py/objtype.c +msgid "type isn't an acceptable base type" msgstr "" -#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c -msgid "initial_value length is wrong" +#: py/objtype.c +msgid "type '%q' isn't an acceptable base type" msgstr "" -#: py/compile.c -msgid "inline assembler must be a function" +#: py/objtype.c +msgid "multiple inheritance not supported" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output dimensions differ" +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output shapes differ" +#: py/objtype.c +msgid "first argument to super() must be type" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input argument must be an integer, a tuple, or a list" +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "input array length must be power of 2" +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input arrays are not compatible" +#: py/parse.c +msgid "not a constant" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input data must be an iterable" +#: py/parse.c +msgid "Unable to init parser" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input dtype must be float or complex" +#: py/parse.c +msgid "unexpected indent" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input is not iterable" +#: py/parse.c +msgid "unindent doesn't match any outer indent level" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "input matrix is asymmetric" +#: py/parse.c +msgid "malformed f-string" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "input matrix is singular" +#: py/parsenum.c +msgid "invalid syntax for integer" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input must be 1- or 2-d" +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be a 1D ndarray" +#: py/parsenum.c +msgid "invalid syntax for number" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c -msgid "input must be a dense ndarray" +#: py/parsenum.c +msgid "decimal numbers not supported" msgstr "" -#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c -msgid "input must be an ndarray" +#: py/persistentcode.c +msgid "incompatible .mpy file" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be an ndarray, or a scalar" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "input must be one-dimensional" +#: py/persistentcode.c +msgid "native code in .mpy unsupported" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "input must be square matrix" +#: py/persistentcode.c +msgid "incompatible .mpy arch" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "input must be tuple, list, range, or ndarray" +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "'%q' object does not support '%q'" +msgstr "'%q' αντικείμενο δεν υποστηρίζει '%q'" + +#: py/qstr.c +msgid "name too long" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input vectors must be of equal length" +#: py/runtime.c +msgid "name not defined" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "interp is defined for 1D iterables of equal length" +#: py/runtime.c +msgid "name '%q' isn't defined" msgstr "" -#: shared-bindings/_bleio/Adapter.c -#, c-format -msgid "interval must be in range %s-%s" +#: py/runtime.c +msgid "unsupported type for operator" msgstr "" -#: py/compile.c -msgid "invalid arch" +#: py/runtime.c +msgid "unsupported type for %q: '%s'" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +#: py/runtime.c +msgid "unsupported types for %q: '%q', '%q'" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid cert" +#: py/runtime.c +msgid "wrong number of values to unpack" msgstr "" -#: shared-bindings/bitmaptools/__init__.c +#: py/runtime.c #, c-format -msgid "invalid element size %d for bits_per_pixel %d\n" +msgid "need more than %d values to unpack" msgstr "" -#: shared-bindings/bitmaptools/__init__.c +#: py/runtime.c #, c-format -msgid "invalid element_size %d, must be, 1, 2, or 4" +msgid "too many values to unpack (expected %d)" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "invalid exception" +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objstr.c -msgid "invalid format specifier" +#: py/runtime.c +msgid "module '%q' has no attribute '%q'" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "invalid hostname" -msgstr "" +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' αντικείμενο δεν έχει γνώρισμα '%q'" -#: shared-module/ssl/SSLSocket.c -msgid "invalid key" +#: py/runtime.c +msgid "can't set attribute '%q'" msgstr "" -#: py/compile.c -msgid "invalid micropython decorator" +#: py/runtime.c +msgid "object not iterable" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c -msgid "invalid setting" +#: py/runtime.c +msgid "'%q' object isn't iterable" +msgstr "'%q' αντικείμενο δεν είναι επαναληπτικό" + +#: py/runtime.c +msgid "object not an iterator" msgstr "" -#: shared-bindings/random/__init__.c -msgid "invalid step" +#: py/runtime.c +msgid "'%q' object isn't an iterator" +msgstr "'%q' αντικείμενο δεν είναι επαναλήπτης" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" msgstr "" -#: py/compile.c py/parse.c -msgid "invalid syntax" +#: py/runtime.c +msgid "can't import name %q" msgstr "" -#: py/parsenum.c -msgid "invalid syntax for integer" +#: py/runtime.c +msgid "memory allocation failed, heap is locked" msgstr "" -#: py/parsenum.c +#: py/runtime.c #, c-format -msgid "invalid syntax for integer with base %d" +msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: py/parsenum.c -msgid "invalid syntax for number" +#: py/runtime.c +msgid "can't convert to int" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 1 must be a class" +#: py/runtime.c +msgid "division by zero" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 2 must be a class or a tuple of classes" +#: py/runtime.c +msgid "maximum recursion depth exceeded" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "iterations did not converge" +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" msgstr "" -#: py/objstr.c -msgid "join expects a list of str/bytes objects consistent with self object" +#: py/stream.c shared-bindings/getpass/__init__.c +msgid "stream operation not supported" msgstr "" -#: py/argcheck.c -msgid "keyword argument(s) not implemented - use normal args instead" +#: py/vm.c +msgid "local variable referenced before assignment" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -msgid "label '%q' not defined" +#: py/vm.c +msgid "no active exception to reraise" msgstr "" -#: py/compile.c -msgid "label redefined" +#: py/vm.c +msgid "opcode" msgstr "" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot create a new Adapter; use _bleio.adapter;" msgstr "" +"Δεν μπορεί να δημιουργηθεί νέο Adapter; χρησιμοποιείστε _bleio.adapter;" -#: py/objarray.c -msgid "lhs and rhs should be compatible" +#: shared-bindings/_bleio/Adapter.c +msgid "Could not set address" +msgstr "Δεν μπόρεσε να ρυθμιστεί η διεύθυνση" + +#: shared-bindings/_bleio/Adapter.c +#, c-format +msgid "interval must be in range %s-%s" msgstr "" -#: py/emitnative.c -msgid "local '%q' has type '%q' but source is '%q'" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot have scan responses for extended, connectable advertisements." msgstr "" +"Δεν μπορούμε να έχουμε απαντήσεις scan για εκτεταμένες, συνδεόμενες " +"διαφημήσεις." -#: py/emitnative.c -msgid "local '%q' used before type known" +#: shared-bindings/_bleio/Adapter.c +msgid "Only connectable advertisements can be directed" msgstr "" -#: py/vm.c -msgid "local variable referenced before assignment" +#: shared-bindings/_bleio/Adapter.c +msgid "non-zero timeout must be >= interval" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "loopback + silent mode not supported by peripheral" +#: shared-bindings/_bleio/Adapter.c +msgid "window must be <= interval" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS already initialized" +#: shared-bindings/_bleio/Adapter.c +msgid "Prefix buffer must be on the heap" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS only works with built-in WiFi" +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "Δεν υποστηρίζονται εγγραφές στο CharacteristicBuffer" + +#: shared-bindings/_bleio/Connection.c +msgid "" +"Connection has been disconnected and can no longer be used. Create a new " +"connection." msgstr "" +"Έχει γίνει αποσύνδεση και αυτή η συνδεση δεν μπορεί να χρησιμοποιηθεί. " +"Δημιουργήστε μια νέα σύνδεση." -#: py/parse.c -msgid "malformed f-string" +#: shared-bindings/_bleio/PacketBuffer.c +#, c-format +msgid "Buffer too short by %d bytes" +msgstr "Buffer πολύ μικρό κατα %d bytes" + +#: shared-bindings/_bleio/PacketBuffer.c +msgid "No connection: length cannot be determined" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "map buffer too small" +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: py/modmath.c shared-bindings/math/__init__.c -msgid "math domain error" +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "matrix is not positive definite" +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" msgstr "" -#: ports/espressif/common-hal/_bleio/Descriptor.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -#, c-format -msgid "max_length must be 0-%d when fixed_length is %s" +#: shared-bindings/_bleio/__init__.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c +#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c +msgid "Read-only" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c -msgid "maximum number of dimensions is " +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "" + +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" msgstr "" -#: py/runtime.c -msgid "maximum recursion depth exceeded" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter must be > 0" +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter should be > 0" +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "median argument must be an ndarray" +#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +msgid "Pin is input only" msgstr "" -#: py/runtime.c +#: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format -msgid "memory allocation failed, allocating %u bytes" +msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" -#: py/runtime.c -msgid "memory allocation failed, heap is locked" +#: shared-bindings/aesio/aes.c +msgid "Key must be 16, 24, or 32 bytes long" msgstr "" -#: py/objarray.c -msgid "memoryview offset too large" +#: shared-bindings/aesio/aes.c +msgid "Requested AES mode is unsupported" msgstr "" -#: py/objarray.c -msgid "memoryview: length is not a multiple of itemsize" +#: shared-bindings/aesio/aes.c +msgid "Source and destination buffers must be the same length" msgstr "" -#: extmod/modtime.c -msgid "mktime needs a tuple of length 8 or 9" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "ECB only operates on 16 bytes at a time" +msgstr "ECB δουλεύει μόνο σε 16 bytes κάθε φορά" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "mode must be complete, or reduced" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "CBC blocks must be multiples of 16 bytes" +msgstr "CBC blocks πρέπει να είναι πολλαπλάσια του 16 bytes" -#: py/builtinimport.c -msgid "module not found" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." msgstr "" -#: ports/espressif/common-hal/wifi/Monitor.c -msgid "monitor init failed" -msgstr "" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Η τιμές της παράταξη πρέπει να είναι μονά bytes." -#: extmod/ulab/code/numpy/poly.c -msgid "more degrees of freedom than data points" +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." msgstr "" -#: py/compile.c -msgid "multiple *x in assignment" +#: shared-bindings/alarm/__init__.c +msgid "Expected a kind of %q" msgstr "" -#: py/objtype.c -msgid "multiple bases have instance lay-out conflict" +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" msgstr "" -#: py/objtype.c -msgid "multiple inheritance not supported" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" msgstr "" -#: py/emitnative.c -msgid "must raise an object" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" msgstr "" -#: py/modbuiltins.c -msgid "must use keyword argument for key function" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." msgstr "" -#: py/runtime.c -msgid "name '%q' is not defined" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q πρέπει να είναι bytearray ή array τύπου 'H' ή 'B'" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c shared-bindings/mcp4822/MCP4822.c +#: shared-bindings/usb_audio/USBMicrophone.c +msgid "Not playing" msgstr "" -#: py/runtime.c -msgid "name not defined" +#: shared-bindings/audiobusio/PDMIn.c +msgid "%q must be multiple of 8." msgstr "" -#: py/qstr.c -msgid "name too long" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Cannot record to a file" +msgstr "Δεν μπορεί να γίνει καταγραφή σε αρχείο" + +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Destination capacity is smaller than destination_length." msgstr "" +"Το μέγεθος προορισμού πρέπει να είναι μικρότερο από το destination_length." -#: py/persistentcode.c -msgid "native code in .mpy unsupported" +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: py/asmthumb.c -msgid "native method too big" +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: py/emitnative.c -msgid "native yield" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q πρέπει να είναι bytearray ή array τύπου 'h', 'H', 'b', ή 'B'" + +#: shared-bindings/audiocore/RawSample.c +msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "ndarray length overflows" +#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c +msgid "file must be a file opened in byte mode" msgstr "" -#: py/runtime.c -#, c-format -msgid "need more than %d values to unpack" +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/Flanger.c +#: shared-bindings/audiodelays/GranularPitchShift.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c +#: shared-bindings/audiomixer/Mixer.c +msgid "bits_per_sample must be 8 or 16" msgstr "" -#: py/modmath.c -msgid "negative factorial" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" msgstr "" -#: py/objint_longlong.c py/objint_mpz.c py/runtime.c -msgid "negative power with no float support" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" msgstr "" -#: py/objint_mpz.c py/runtime.c -msgid "negative shift count" +#: shared-bindings/audioi2sin/I2SIn.c +#, c-format +msgid "invalid destination buffer, must be an array of type: %c" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "nested index must be int" +#: shared-bindings/audioio/AudioOut.c +msgid "%q and %q must be different" +msgstr "%q και %q πρεπει να είναι διαφορετικά" + +#: shared-bindings/bitmapfilter/__init__.c +msgid "" +"weights must be a sequence with an odd square number of elements (usually 9 " +"or 25)" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no SD card" +#: shared-bindings/bitmapfilter/__init__.c +msgid "weights must be an object of type %q, %q, %q, or %q, not %q " msgstr "" -#: py/vm.c -msgid "no active exception to reraise" +#: shared-bindings/bitmaptools/__init__.c +msgid "clip point must be (x,y) tuple" msgstr "" -#: py/compile.c -msgid "no binding for nonlocal found" +#: shared-bindings/bitmaptools/__init__.c +msgid "source palette too large" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "no default packer" +#: shared-bindings/bitmaptools/__init__.c +msgid "Bitmap size and bits per value must match" +msgstr "Το μέγεθος του bitmap και τα bits ανα τιμή πρέπει να ταιριάζουν" + +#: shared-bindings/bitmaptools/__init__.c +msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" -#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c -msgid "no default seed" +#: shared-bindings/bitmaptools/__init__.c +msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -#: py/builtinimport.c -msgid "no module named '%q'" +#: shared-bindings/bitmaptools/__init__.c +msgid "Unsupported colorspace" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no response from SD card" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap size must match the other bitmaps" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c -msgid "no such attribute" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap must have 8 bits per pixel" msgstr "" -#: ports/espressif/common-hal/_bleio/Connection.c -#: ports/nordic/common-hal/_bleio/Connection.c -msgid "non-UUID found in service_uuids_whitelist" +#: shared-bindings/bitmaptools/__init__.c +msgid "out of range of target" msgstr "" -#: py/compile.c -msgid "non-default argument follows default argument" +#: shared-bindings/bitmaptools/__init__.c +msgid "value out of range of target" msgstr "" -#: py/objstr.c -msgid "non-hex digit found" +#: shared-bindings/bitmaptools/__init__.c +msgid "background value out of range of target" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "non-zero timeout must be > 0.01" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "non-zero timeout must be >= interval" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "not a 128-bit UUID" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" -#: py/parse.c -msgid "not a constant" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element size %d for bits_per_pixel %d\n" msgstr "" -#: py/objstr.c -msgid "not all arguments converted during string formatting" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" -#: py/objstr.c -msgid "not enough arguments for format string" +#: shared-bindings/bitmaptools/__init__.c +msgid "bitmap sizes must match" msgstr "" -#: extmod/ulab/code/numpy/carray/carray_tools.c -msgid "not implemented for complex dtype" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 2 or 65536" msgstr "" -#: extmod/ulab/code/numpy/bitwise.c -msgid "not supported for input types" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 65536" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "number of points must be at least 2" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 8" msgstr "" -#: py/builtinhelp.c -msgid "object " +#: shared-bindings/bitmaptools/__init__.c +msgid "unsupported colorspace for dither" msgstr "" -#: py/obj.c +#: shared-bindings/bitops/__init__.c #, c-format -msgid "object '%s' isn't a tuple or list" +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" msgstr "" -#: py/obj.c -msgid "object doesn't support item assignment" +#: shared-bindings/board/__init__.c +msgid "No default %q bus" msgstr "" -#: py/obj.c -msgid "object doesn't support item deletion" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c +msgid "Display rotation must be in 90 degree increments" +msgstr "Η περιστροφή της οθόνη πρέπει να γίνεται σε βήματα 90 μοιρών" + +#: shared-bindings/busdisplay/BusDisplay.c +msgid "%q must be 1 when %q is True" +msgstr "%q πρέπει να είναι 1 όταν %q είναι True" + +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#, fuzzy +msgid "Display must have a 16 bit colorspace." +msgstr "Η οθόνη πρέπει να έχει 16 bit χρωματική ευκρίνεια." + +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c +msgid "tx and rx cannot both be None" msgstr "" -#: py/obj.c -msgid "object has no len" +#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." msgstr "" -#: py/obj.c -msgid "object isn't subscriptable" +#: shared-bindings/canio/RemoteTransmissionRequest.c +msgid "RemoteTransmissionRequests limited to 8 bytes" msgstr "" -#: py/runtime.c -msgid "object not an iterator" -msgstr "" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Cannot set value when direction is input." +msgstr "Δεν μπορεί να οριστεί τιμή οταν η κατεύθυνση είναι input." -#: py/objtype.c py/runtime.c -msgid "object not callable" -msgstr "" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Drive mode not used when direction is input." +msgstr "Ο τρόπος οδήγησης δεν χρησιμοποιείται όταν η κατεύθυνση είναι είσοδος." -#: py/sequence.c shared-bindings/displayio/Group.c -msgid "object not in sequence" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Pull not used when direction is output." msgstr "" -#: py/runtime.c -msgid "object not iterable" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" msgstr "" -#: py/obj.c -#, c-format -msgid "object of type '%s' has no len()" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" msgstr "" -#: py/obj.c -msgid "object with buffer protocol required" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" msgstr "" -#: py/objstr.c -msgid "odd-length string" -msgstr "" +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Δεν μπορούν να διαγραφούν οι τιμές" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "off" +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +msgid "Slices not supported" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "offset is too large" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: shared-bindings/dualbank/__init__.c -msgid "offset must be >= 0" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "offset must be non-negative and no greater than buffer length" +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only bit_depth=16 is supported" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer, tuple, list, or int" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only mono is supported" +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c +msgid "unsupported %q type" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "only ndarrays can be concatenated" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only oversample=64 is supported" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only sample_rate=16000 is supported" +#: shared-bindings/displayio/TileGrid.c +msgid "New bitmap must be same size as old bitmap" msgstr "" -#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "only slices with step=1 (aka None) are supported" +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" msgstr "" -#: py/vm.c -msgid "opcode" +#: shared-bindings/dualbank/__init__.c +msgid "offset must be >= 0" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c -msgid "operands could not be broadcast together" +#: shared-bindings/epaperdisplay/EPaperDisplay.c +msgid "Refresh too soon" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for 2D arrays only" -msgstr "" +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Buffer is not a bytearray." +msgstr "Το buffer δεν είναι ένα bytearray." -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for ndarrays only" +#: shared-bindings/gnss/GNSS.c +msgid "System entry must be gnss.SatelliteSystem" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is implemented for 1D Boolean arrays only" +#: shared-bindings/hashlib/__init__.c +msgid "Unsupported hash algorithm" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "operation is not implemented on ndarrays" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is not supported for given type" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "operation not supported for the input types" +#: shared-bindings/i2ctarget/I2CTarget.c +msgid "addresses is empty" msgstr "" -#: py/modbuiltins.c -msgid "ord expects a character" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" msgstr "" -#: py/modbuiltins.c +#: shared-bindings/ipaddress/IPv4Address.c #, c-format -msgid "ord() expected a character, but string of length %d found" -msgstr "" +msgid "Address must be %d bytes long" +msgstr "Η διεύθυνση πρέπει να είναι %d bytes μεγάλη" -#: extmod/ulab/code/utils/utils.c -msgid "out array is too small" +#: shared-bindings/ipaddress/__init__.c +msgid "Only int or string supported for ip" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "out has wrong type" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "width must be greater than zero" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for complex dtype" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "Scale dimensions must divide by 3" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for function" +#: shared-bindings/is31fl3741/IS31FL3741.c +msgid "Mapping must be a tuple" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out must be a float dense array" +#: shared-bindings/jpegio/JpegDecoder.c +msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be an ndarray" +#: shared-bindings/mdns/Server.c +msgid "" +"Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be of float dtype" +#: shared-bindings/memorymap/AddressRange.c +msgid "Address range wraps around" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "out of range of target" -msgstr "" +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" +msgstr "%q περιέχει διπλότυπα pins" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array has wrong type" -msgstr "" +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" +msgstr "%q και %q περιέχουν διπλότυπα pins" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array must be contiguous" +#: shared-bindings/msgpack/ExtType.c +msgid "code outside range 0~127" msgstr "" -#: py/objint_mpz.c -msgid "overflow converting long int to machine word" +#: shared-bindings/msgpack/__init__.c +msgid "default is not a function" msgstr "" -#: py/modstruct.c -#, c-format -msgid "pack expected %d items for packing (got %d)" +#: shared-bindings/msgpack/__init__.c +msgid "ext_hook is not a function" msgstr "" -#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c -msgid "palette must be 32 bytes long" +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." msgstr "" -#: py/emitinlinextensa.c -msgid "parameters must be registers in sequence a2 to a5" +#: shared-bindings/os/__init__.c +msgid "No hardware random available" msgstr "" -#: py/emitinlinethumb.c -msgid "parameters must be registers in sequence r0 to r3" +#: shared-bindings/paralleldisplaybus/ParallelBus.c +msgid "Specify exactly one of data0 or data_pins" msgstr "" -#: extmod/vfs_posix_file.c -msgid "poll on file not available on win32" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." msgstr "" -#: ports/espressif/common-hal/pulseio/PulseIn.c -msgid "pop from an empty PulseIn" -msgstr "" +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "H παράταξη πρέπει να περιέχει halfwords (τύπου 'H')" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/pulseio/PulseIn.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c -#: shared-bindings/ps2io/Ps2.c -msgid "pop from empty %q" +#: shared-bindings/pwmio/PWMOut.c +msgid "Conflicting settings for shared resource" msgstr "" -#: shared-bindings/socketpool/Socket.c -msgid "port must be >= 0" +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" msgstr "" -#: py/compile.c -msgid "positional arg after **" +#: shared-bindings/random/__init__.c +msgid "invalid step" msgstr "" -#: py/compile.c -msgid "positional arg after keyword arg" +#: shared-bindings/random/__init__.c +msgid "empty sequence" msgstr "" -#: py/objint_mpz.c -msgid "pow() 3rd argument cannot be 0" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" msgstr "" -#: py/objint_mpz.c -msgid "pow() with 3 arguments requires integers" +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "pull masks conflict with direction masks" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" msgstr "" -#: py/parse.c -msgid "raw f-strings are not supported" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "real and imaginary parts must be of equal length" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" msgstr "" -#: py/builtinimport.c -msgid "relative import" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" -#: py/obj.c +#: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format -msgid "requested length %d but object has length %d" +msgid "" +"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +"%d pin διεύθυνσης, %d rgb ping και %d πλακίδια αναδεικνύουν ύψος %d, όχι %d" -#: extmod/ulab/code/ndarray_operators.c -msgid "results cannot be cast to specified type" +#: shared-bindings/socketpool/Socket.c +msgid "port must be >= 0" msgstr "" -#: py/compile.c -msgid "return annotation must be an identifier" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "buffer too small for requested bytes" msgstr "" -#: py/emitnative.c -msgid "return expected '%q' but got '%q'" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] duplicates another pin assignment" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] is not on the same port as clock" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "roll argument must be an ndarray" -msgstr "" +#: shared-bindings/storage/__init__.c shared-bindings/usb_audio/__init__.c +#: shared-bindings/usb_cdc/__init__.c shared-bindings/usb_hid/__init__.c +#: shared-bindings/usb_midi/__init__.c shared-bindings/usb_video/__init__.c +msgid "Cannot change USB devices now" +msgstr "Δεν μπορούν να αλλάξουν οι USB συσκευές τώρα" -#: py/objstr.c -msgid "rsplit(None,n)" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c +msgid "File not found" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -msgid "sampling rate out of range" +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" msgstr "" -#: py/modmicropython.c -msgid "schedule queue full" +#: shared-bindings/traceback/__init__.c +msgid "Supply both or neither of %q and %q" msgstr "" -#: py/builtinimport.c -msgid "script compilation not supported" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" msgstr "" -#: py/nativeglue.c -msgid "set unsupported" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "shape must be None, and integer or a tuple of integers" +#: shared-bindings/usb_audio/USBSpeaker.c +msgid "destination must be an array of type 'h'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "shape must be integer or tuple of integers" +#: shared-bindings/usb_audio/__init__.c +msgid "At least one of microphone and speaker must be enabled" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "short read" -msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "%q, %q, και %q πρέπει να είναι όλα του ιδίου μήκους" -#: py/objstr.c -msgid "sign not allowed in string format specifier" +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." msgstr "" -#: py/objstr.c -msgid "sign not allowed with integer format specifier 'c'" +#: shared-bindings/warnings/__init__.c +msgid "%q must be a subclass of %q" +msgstr "%q πρέπει να είναι υποκλάση του %q" + +#: shared-bindings/wifi/Monitor.c +msgid "%q out of bounds" +msgstr "%q εκτός ορίων" + +#: shared-bindings/wifi/Radio.c +msgid "Invalid hex password" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "size is defined for ndarrays only" +#: shared-bindings/wifi/Radio.c +msgid "invalid hostname" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "size must match out.shape when used together" +#: shared-bindings/wifi/Radio.c +msgid "Invalid MAC address" msgstr "" -#: py/nativeglue.c -msgid "slice unsupported" +#: shared-bindings/wifi/Radio.c +msgid "AuthMode.OPEN is not used with password" +msgstr "AuthMode.OPEN δεν μπορεί να χρησιμοποιηθεί με κωδικό" + +#: shared-bindings/wifi/Radio.c +msgid "Invalid BSSID" msgstr "" -#: py/objint.c py/sequence.c -msgid "small int overflow" +#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c +msgid "Authentication failure" +msgstr "Αποτυχία αυθεντικοποίησης" + +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" msgstr "" -#: main.c -msgid "soft reboot\n" +#: shared-bindings/wifi/Radio.c +#, c-format +msgid "Unknown failure %d" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "sort argument must be an ndarray" +#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#, c-format +msgid "No I2C device at address: 0x%x" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos array must be of shape (n_section, 6)" +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos[:, 3] should be all ones" +#: shared-module/audiocore/__init__.c shared-module/usb_audio/USBMicrophone.c +msgid "The sample's %q does not match" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sosfilt requires iterable arguments" +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source palette too large" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Only 8/16-bit mono/stereo is supported" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 2 or 65536" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "buffer_size too small for source" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 65536" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Couldn't allocate decoder" +msgstr "Δεν μπόρεσε να δεσμευτεί decoder" + +#: shared-module/audiomp3/MP3Decoder.c +msgid "Failed to parse MP3 file" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 8" +#: shared-module/bitbangio/I2C.c +msgid "%q too long" msgstr "" -#: extmod/modre.c -msgid "splitting with sub-captures" +#: shared-module/bitmapfilter/__init__.c +msgid "bitmap size and depth must match" msgstr "" -#: py/objstr.c -msgid "start/end indices" +#: shared-module/bitmapfilter/__init__.c +msgid "unsupported bitmap depth" msgstr "" -#: shared-bindings/random/__init__.c -msgid "stop not reachable from start" +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" msgstr "" -#: py/stream.c shared-bindings/getpass/__init__.c -msgid "stream operation not supported" +#: shared-module/displayio/ColorConverter.c +msgid "Only one color can be transparent at a time" msgstr "" -#: py/objarray.c py/objstr.c -msgid "string argument without an encoding" +#: shared-module/displayio/Group.c +msgid "Layer already in a group" msgstr "" -#: py/objstrunicode.c -msgid "string index out of range" +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: py/objstrunicode.c +#: shared-module/displayio/OnDiskBitmap.c #, c-format -msgid "string indices must be integers, not %s" +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" msgstr "" -#: py/objarray.c py/objstr.c -msgid "substring not found" +#: shared-module/displayio/OnDiskBitmap.c +msgid "RLE-compressed BMP not supported" msgstr "" -#: py/compile.c -msgid "super() can't find self" +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" msgstr "" -#: extmod/modjson.c -msgid "syntax error in JSON" +#: shared-module/displayio/__init__.c +msgid "Too many displays" msgstr "" -#: extmod/modtime.c -msgid "ticks interval overflow" +#: shared-module/displayio/__init__.c +msgid "Too many display busses; forgot displayio.release_displays() ?" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "timeout duration exceeded the maximum supported value" +#: shared-module/displayio/bus_core.c +msgid "Unsupported display bus type" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "timeout must be < 655.35 secs" +#: shared-module/gifio/GifWriter.c +msgid "unsupported colorspace for GifWriter" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -msgid "timeout waiting for flux" +#: shared-module/i2cdisplaybus/I2CDisplayBus.c +#: shared-module/is31fl3741/IS31FL3741.c +#, c-format +msgid "Unable to find I2C Display at %x" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: shared-module/floppyio/__init__.c -msgid "timeout waiting for index pulse" +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v1 card" +#: shared-module/imagecapture/ParallelImageCapture.c +msgid "This microcontroller does not support continuous capture." msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v2 card" +#: shared-module/is31fl3741/FrameBuffer.c +msgid "LED mappings must match display size" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "timer re-init" +#: shared-module/jpegio/JpegDecoder.c +msgid "Interrupted by output function" msgstr "" -#: shared-bindings/time/__init__.c -msgid "timestamp out of range for platform time_t" +#: shared-module/jpegio/JpegDecoder.c +msgid "Device error or wrong termination of input stream" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "tobytes can be invoked for dense arrays only" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient memory pool for the image" msgstr "" -#: py/compile.c -msgid "too many args" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient stream input buffer" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c -msgid "too many dimensions" +#: shared-module/jpegio/JpegDecoder.c +msgid "Parameter error" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "too many indices" +#: shared-module/jpegio/JpegDecoder.c +msgid "Data format error (may be broken data)" msgstr "" -#: py/asmthumb.c -msgid "too many locals for native method" +#: shared-module/jpegio/JpegDecoder.c +msgid "Right format but not supported" msgstr "" -#: py/runtime.c -#, c-format -msgid "too many values to unpack (expected %d)" +#: shared-module/jpegio/JpegDecoder.c +msgid "Unsupported JPEG (may be progressive)" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D arrays of equal length" +#: shared-module/jpegio/JpegDecoder.c +msgid "%q() without %q()" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D iterables" -msgstr "" +#: shared-module/memorymonitor/AllocationAlarm.c +#, c-format +msgid "Attempt to allocate %d blocks" +msgstr "Προσπάθεια να δεσμευτούν %d blocks" -#: py/obj.c -msgid "tuple/list has wrong length" +#: shared-module/msgpack/__init__.c +msgid "short read" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_driver_install returned esp-idf error #%d" +#: shared-module/msgpack/__init__.c +msgid "no default packer" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_start returned esp-idf error #%d" +#: shared-module/msgpack/__init__.c supervisor/shared/settings.c +msgid "Invalid format" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c -msgid "tx and rx cannot both be None" +#: shared-module/paralleldisplaybus/ParallelBus.c +msgid "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." msgstr "" -#: py/objtype.c -msgid "type '%q' is not an acceptable base type" +#: shared-module/rgbmatrix/RGBMatrix.c +msgid "No timer available" msgstr "" -#: py/objtype.c -msgid "type is not an acceptable base type" +#: shared-module/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Internal error #%d" msgstr "" -#: py/runtime.c -msgid "type object '%q' has no attribute '%q'" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v1 card" msgstr "" -#: py/objtype.c -msgid "type takes 1 or 3 arguments" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v2 card" msgstr "" -#: py/objint_longlong.c -msgid "ulonglong too large" +#: shared-module/sdcardio/SDCard.c +msgid "no SD card" msgstr "" -#: py/parse.c -msgid "unexpected indent" +#: shared-module/sdcardio/SDCard.c +msgid "couldn't determine SD card version" msgstr "" -#: py/bc.c -msgid "unexpected keyword argument" +#: shared-module/sdcardio/SDCard.c +msgid "no response from SD card" msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c -#: shared-bindings/traceback/__init__.c -msgid "unexpected keyword argument '%q'" +#: shared-module/sdcardio/SDCard.c +msgid "SD card CSD format not supported" msgstr "" -#: py/lexer.c -msgid "unicode name escapes" +#: shared-module/sdcardio/SDCard.c +msgid "can't set 512 block size" msgstr "" -#: py/parse.c -msgid "unindent doesn't match any outer indent level" +#: shared-module/ssl/SSLSocket.c +msgid "Invalid socket for TLS" msgstr "" -#: py/objstr.c -#, c-format -msgid "unknown conversion specifier %c" +#: shared-module/ssl/SSLSocket.c +msgid "invalid key" msgstr "" -#: py/objstr.c -msgid "unknown format code '%c' for object of type '%q'" +#: shared-module/ssl/SSLSocket.c +msgid "invalid cert" msgstr "" -#: py/compile.c -msgid "unknown type" +#: shared-module/storage/__init__.c +msgid "Mount point directory missing" msgstr "" -#: py/compile.c -msgid "unknown type '%q'" +#: shared-module/storage/__init__.c +msgid "Cannot remount path when visible via USB." msgstr "" -#: py/objstr.c -#, c-format -msgid "unmatched '%c' in format" -msgstr "" +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' και 'O' δεν είναι υποστηριζόμενοι τύποι format" -#: py/objtype.c py/runtime.c -msgid "unreadable attribute" +#: shared-module/struct/__init__.c +msgid "buffer size must match format" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -msgid "unsupported %q type" +#: shared-module/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q πρέπει να είναι λίστα τύπου 'h'" + +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "unsupported bitmap depth" +#: shared-module/usb/core/Device.c +msgid "No usb host port initialized" msgstr "" -#: shared-module/gifio/GifWriter.c -msgid "unsupported colorspace for GifWriter" +#: shared-module/usb/core/Device.c +msgid "Pipe error" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "unsupported colorspace for dither" +#: shared-module/usb/core/Device.c +msgid "No configuration set" msgstr "" -#: py/objstr.c -#, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" +#: shared-module/usb_hid/Device.c +msgid "USB busy" msgstr "" -#: py/runtime.c -msgid "unsupported type for %q: '%s'" +#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Rectangle.c +msgid "can only have one parent" msgstr "" -#: py/runtime.c -msgid "unsupported type for operator" +#: shared-module/vectorio/Polygon.c +msgid "Polygon needs at least 3 points" msgstr "" -#: py/runtime.c -msgid "unsupported types for %q: '%q', '%q'" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols is too high" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols keyword must be specified" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" msgstr "" -#: py/objint.c -#, c-format -msgid "value must fit in %d byte(s)" +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "value out of range of target" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" +"\n" +"Είσαστε τε ασφαλή λειτουργία διότι:\n" -#: extmod/moddeflate.c -msgid "wbits" +#: supervisor/shared/safe_mode.c +msgid "Power dipped. Make sure you are providing enough power." msgstr "" -#: shared-bindings/bitmapfilter/__init__.c -msgid "" -"weights must be a sequence with an odd square number of elements (usually 9 " -"or 25)" +#: supervisor/shared/safe_mode.c +msgid "You pressed the BOOT button at start up" msgstr "" -#: shared-bindings/bitmapfilter/__init__.c -msgid "weights must be an object of type %q, %q, %q, or %q, not %q " +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "width must be greater than zero" +#: supervisor/shared/safe_mode.c +msgid "CIRCUITPY drive could not be found or created." +msgstr "Ο CIRCUITPY δίσκος δεν μπόρεσε να βρεθεί ή να δημιουργηθεί." + +#: supervisor/shared/safe_mode.c +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "Σφάλμα στο safemode.py." + +#: supervisor/shared/safe_mode.c +msgid "Stack overflow. Increase stack size." msgstr "" -#: ports/raspberrypi/common-hal/wifi/Monitor.c -msgid "wifi.Monitor not available" +#: supervisor/shared/safe_mode.c +msgid "USB devices need more endpoints than are available." msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "window must be <= interval" +#: supervisor/shared/safe_mode.c +msgid "USB devices specify too many interface names." msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "wrong axis index" +#: supervisor/shared/safe_mode.c +msgid "Boot device must be first (interface #0)." +msgstr "Η συσκευή εκκίνησης πρέπει να επιλεχθεί πρώτα (διεπαφή #0)." + +#: supervisor/shared/safe_mode.c +msgid "Internal watchdog timer expired." msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "wrong axis specified" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython core code crashed hard. Whoops!\n" +msgstr "Ο πυρήνας της CircuitPython κατέρευσε. Οουπς!\n" + +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "wrong dtype" +#: supervisor/shared/safe_mode.c +msgid "Failed to write internal flash." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong index type" +#: supervisor/shared/safe_mode.c +msgid "Hard fault: memory access or instruction error." msgstr "" -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c -#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c -#: extmod/ulab/code/numpy/vector.c -msgid "wrong input type" +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of condition array" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of index array" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate to the heap." msgstr "" -#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c -msgid "wrong number of arguments" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." msgstr "" -#: py/runtime.c -msgid "wrong number of values to unpack" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Please file an issue with your program at github.com/adafruit/circuitpython/" +"issues." msgstr "" +"\n" +"Παρακαλώ δημιουργήστε ένα πρόβλημα με το πρόγραμμά σας στο github.com/" +"adafruit/circuitpython/issues." -#: extmod/ulab/code/numpy/vector.c -msgid "wrong output type" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" msgstr "" +"\n" +"Πατήστε reset για να βγείτε από την ασφαλή λειτουργία.\n" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be an ndarray" +#: supervisor/shared/settings.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "Παρουσιάστηκε σφάλμα κατά την ανάκτηση '%s':\n" + +#: supervisor/shared/settings.c +msgid "Invalid unicode escape" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of float type" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "Wi-Fi: " +msgstr "Wi-Fi: " + +#: supervisor/shared/web_workflow/web_workflow.c +msgid "off" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of shape (n_section, 2)" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "No IP" msgstr "" +#~ msgid "%q renamed %q" +#~ msgstr "%q μεταονομάστηκε σε %q" + +#, c-format +#~ msgid "Buffer + offset too small %d %d %d" +#~ msgstr "Buffer + offset είναι πολύ μικρά %d %d %d" + +#~ msgid "Byte buffer must be 16 bytes." +#~ msgstr "Byte buffer πρέπει να είναι 16 bytes." + +#~ msgid "%q moved from %q to %q" +#~ msgstr "%q μετακινήθηκε από το %q στο %q" + +#, c-format +#~ msgid "%%c requires int or char" +#~ msgstr "%%c απαιτεί ακέραιο ή χαρακτήρα" + +#~ msgid "'%q' object is not callable" +#~ msgstr "'%q' αντικείμενο δεν καλείται" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "Δεν μπορεί να γίνει remount του '/' όταν είναι ορατό μέσω USB." + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Το data chunk πρέπει να ακολουθεί το fmt chunk" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Το μήκος buffer πρέπει να είναι πολλαπλάσιο του 512" @@ -4508,7 +4833,7 @@ msgstr "" #~ msgid "'continue' outside loop" #~ msgstr "'continue' εκτός επανάληψης" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "" #~ "'coroutine' αντικείμενο δεν μπορεί να χρησιμοποιηθεί σαν επαναλήπτης" diff --git a/locale/en_GB.po b/locale/en_GB.po index ee7f399232d..29380c91c80 100644 --- a/locale/en_GB.po +++ b/locale/en_GB.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-09-23 03:16+0000\n" +"PO-Revision-Date: 2026-04-30 11:09+0000\n" "Last-Translator: Andi Chandler \n" "Language-Team: none\n" "Language: en_GB\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.8-dev\n" +"X-Generator: Weblate 5.17.1\n" #: main.c msgid "" @@ -95,7 +95,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "%q and %q contain duplicate pins" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q and %q must be different" @@ -115,7 +115,11 @@ msgstr "%q contains duplicate pins" msgid "%q failure: %d" msgstr "%q failure: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q in %q must be of type %q or %q, not %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q in %q must be of type %q, not %q" @@ -167,7 +171,7 @@ msgstr "%q length must be <= %d" msgid "%q length must be >= %d" msgstr "%q length must be >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "%q moved from %q to %q" @@ -227,6 +231,7 @@ msgstr "%q must be multiple of 8." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q must be of type %q or %q, not %q" @@ -236,6 +241,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "%q must be of type %q, %q, or %q, not %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q must be of type %q, not %q" @@ -281,7 +287,8 @@ msgstr "%q() without %q()" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, and %q must all be the same length" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -315,16 +322,16 @@ msgid "'%q' object does not support '%q'" msgstr "'%q' object does not support '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" -msgstr "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" +msgstr "'%q' object isn't an iterator" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c msgid "'%q' object is not callable" msgstr "'%q' object is not callable" #: py/runtime.c -msgid "'%q' object is not iterable" -msgstr "'%q' object is not iterable" +msgid "'%q' object isn't iterable" +msgstr "'%q' object isn't iterable" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format @@ -520,7 +527,7 @@ msgstr "All channels in use" #: ports/raspberrypi/common-hal/usb_host/Port.c msgid "All dma channels in use" -msgstr "All DMA channels in use" +msgstr "All dma channels in use" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "All event channels in use" @@ -550,7 +557,6 @@ msgstr "All timers for this pin are in use" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "All timers in use" @@ -563,6 +569,10 @@ msgstr "Already advertising." msgid "Already have all-matches listener" msgstr "Already have all-matches listener" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Already in progress" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -572,6 +582,7 @@ msgstr "Already running" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Already scanning for WiFi networks" @@ -598,6 +609,10 @@ msgstr "Array must contain halfwords (type 'H')" msgid "Array values should be single bytes." msgstr "Array values should be single bytes." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "Async SPI transfer in progress on this bus, keep awaiting." + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -607,6 +622,11 @@ msgstr "Attempt to allocate %d blocks" msgid "Audio conversion not implemented" msgstr "Audio conversion not implemented" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Audio source error" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN is not used with password" @@ -740,6 +760,10 @@ msgstr "Can only alarm on one low pin while others alarm high from deep sleep." msgid "Can only alarm on two low pins from deep sleep." msgstr "Can only alarm on two low pins from deep sleep." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "Can't construct AudioOut because continuous channel already open" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -785,8 +809,8 @@ msgid "Cannot record to a file" msgstr "Cannot record to a file" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "Cannot remount '/' when visible via USB." +msgid "Cannot remount path when visible via USB." +msgstr "Cannot remount path when visible via USB." #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -801,6 +825,10 @@ msgstr "Cannot specify RTS or CTS in RS485 mode" msgid "Cannot subclass slice" msgstr "Cannot subclass slice" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "Cannot use GPIO0..15 together with GPIO32..47" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "Cannot wake on pin edge, only level" @@ -837,6 +865,10 @@ msgstr "Coordinate arrays have different lengths" msgid "Coordinate arrays types have different sizes" msgstr "Coordinate arrays types have different sizes" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "Could not publish to ROS topic" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "Could not set address" @@ -849,6 +881,11 @@ msgstr "Could not start interrupt, RX busy" msgid "Couldn't allocate decoder" msgstr "Couldn't allocate decoder" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "Critical ROS failure during soft reboot, reset required: %d" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC channel init error" @@ -866,10 +903,6 @@ msgstr "DAC already in use" msgid "Data 0 pin must be byte aligned" msgstr "Data 0 pin must be byte aligned" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Data chunk must follow fmt chunk" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "Data format error (may be broken data)" @@ -1001,15 +1034,47 @@ msgstr "Failed to connect: internal error" msgid "Failed to connect: timeout" msgstr "Failed to connect: timeout" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "Failed to create continuous channels: invalid arg" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "Failed to create continuous channels: invalid state" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Failed to create continuous channels: no mem" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Failed to create continuous channels: not found" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Failed to enable continuous" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Failed to parse MP3 file" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Failed to register continuous events callback" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Failed to release mutex, err 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "Failed to set hostname" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Failed to start async audio" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Failed to write internal flash." @@ -1018,12 +1083,14 @@ msgstr "Failed to write internal flash." msgid "File exists" msgstr "File exists" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "File not found" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Filters too complex" @@ -1048,7 +1115,7 @@ msgstr "For L8 colourspace, input bitmap must have 8 bits per pixel" msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "For RGB colourspaces, input bitmap must have 16 bits per pixel" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "Format not supported" @@ -1157,6 +1224,7 @@ msgid "Insufficient stream input buffer" msgstr "Insufficient stream input buffer" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "Interface must be started" @@ -1212,7 +1280,9 @@ msgstr "Interrupted by output function" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "Invalid %q" @@ -1245,6 +1315,10 @@ msgstr "Invalid BSSID" msgid "Invalid MAC address" msgstr "Invalid MAC address" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "Invalid ROS domain ID" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Invalid argument" @@ -1276,6 +1350,7 @@ msgid "Invalid hex password" msgstr "Invalid hex password" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Invalid multicast MAC address" @@ -1288,6 +1363,7 @@ msgid "Invalid socket for TLS" msgstr "Invalid socket for TLS" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "Invalid state" @@ -1332,6 +1408,11 @@ msgstr "MAC address was invalid" msgid "MITM security not supported" msgstr "MITM security is not supported" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "MMC/SDIO Clock Error %x" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "Mapping must be a tuple" @@ -1377,7 +1458,8 @@ msgstr "Missing jmp_pin. %q[%u] jumps on pin" msgid "Mount point directory missing" msgstr "Mount point directory missing" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Must be a %q subclass." @@ -1517,6 +1599,10 @@ msgstr "No pull up found on SDA or SCL; check your wiring" msgid "No pulldown on pin; 1Mohm recommended" msgstr "No pulldown on pin; 1Mohm recommended" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "No pullup on pin; 1Mohm recommended" + #: py/moderrno.c msgid "No space left on device" msgstr "No space left on device" @@ -1618,15 +1704,6 @@ msgstr "Only edge detection is available on this hardware" msgid "Only int or string supported for ip" msgstr "Only int or string supported for ip" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "Only one %q can be set in deep sleep." @@ -1677,6 +1754,7 @@ msgstr "Out of memory" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Out of sockets" @@ -1696,6 +1774,10 @@ msgstr "PWM slice already in use" msgid "PWM slice channel A already in use" msgstr "PWM slice channel A already in use" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "Packet buffers for an SPI transfer must have the same length." + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "Parameter error" @@ -1796,6 +1878,10 @@ msgstr "Program size invalid" msgid "Program too long" msgstr "Program too long" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "Publishers can only be created from a parent node" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull not used when direction is output." @@ -1816,6 +1902,26 @@ msgstr "RNG deinit Error" msgid "RNG Init Error" msgstr "RNG init Error" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "ROS failed to initialise. Is agent connected?" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "ROS internal setup failure" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "ROS memory allocator failure" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "ROS node failed to initialise" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "ROS topic failed to initialise" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1947,11 +2053,13 @@ msgstr "Slice and value different lengths." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Slices not supported" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool can only be used with wifi.radio" @@ -1991,21 +2099,9 @@ msgstr "The above exception was the direct cause of the following exception:" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "The length of rgb_pins must be 6, 12, 18, 24, or 30" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "The sample's bits_per_sample does not match the mixer's" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "The sample's channel count does not match the mixer's" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "The sample's sample rate does not match the mixer's" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "The sample's signedness does not match the mixer's" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "The sample's %q does not match" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2027,7 +2123,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "Tile height must exactly divide bitmap height" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Tile index out of bounds" @@ -2035,6 +2133,10 @@ msgstr "Tile index out of bounds" msgid "Tile width must exactly divide bitmap width" msgstr "Tile width must exactly divide bitmap width" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "TilePaletteMapper may only be bound to a TileGrid once" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "Time is in the past." @@ -2165,6 +2267,10 @@ msgstr "Unable to init parser" msgid "Unable to read color palette data" msgstr "Unable to read colour palette data" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "Unable to send CAN Message: all Tx message buffers are busy" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2259,15 +2365,12 @@ msgstr "Unsupported colourspace" msgid "Unsupported display bus type" msgstr "Unsupported display bus type" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Unsupported format" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "Unsupported hash algorithm" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "Unsupported socket type" @@ -2323,9 +2426,11 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "Wifi is not enabled" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "WiFi is not enabled" #: main.c msgid "Woken up by alarm.\n" @@ -2347,6 +2452,7 @@ msgstr "You pressed both buttons at start up." #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "You pressed button A at start up." @@ -2360,6 +2466,7 @@ msgstr "You pressed the BOOT button at start up" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "You pressed the BOOT button at start up." @@ -2420,6 +2527,10 @@ msgstr "a bytes-like object is required" msgid "addresses is empty" msgstr "addresses is empty" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "already playing" + #: py/compile.c msgid "annotation must be an identifier" msgstr "annotation must be an identifier" @@ -2498,6 +2609,10 @@ msgstr "attempt to get argmin/argmax of an empty sequence" msgid "attributes not supported" msgstr "attributes not supported" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "audio format not supported" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "axis is out of bounds" @@ -2534,6 +2649,10 @@ msgstr "bad typecode" msgid "binary op %q not implemented" msgstr "binary op %q not implemented" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth must be 8, 16, 24, or 32." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "bitmap size and depth must match" @@ -2546,6 +2665,15 @@ msgstr "bitmap sizes must match" msgid "bits must be 32 or less" msgstr "bits must be 32 or less" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample must be 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample must be 8 or 16" @@ -2627,7 +2755,7 @@ msgstr "Can't assign to expression" msgid "can't cancel self" msgstr "can't cancel self" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "Can't convert %q to %q" @@ -3089,8 +3217,8 @@ msgid "format" msgstr "format" #: py/objstr.c -msgid "format requires a dict" -msgstr "format requires a dict" +msgid "format needs a dict" +msgstr "format needs a dict" #: py/objdeque.c msgid "full" @@ -3223,10 +3351,6 @@ msgstr "indices must be integers" msgid "indices must be integers, slices, or Boolean lists" msgstr "indices must be integers, slices, or Boolean lists" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "init I2C" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "initial values must be iterable" @@ -3421,10 +3545,6 @@ msgstr "label '%q' not defined" msgid "label redefined" msgstr "label redefined" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "level must be between 0 and 1" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs and rhs should be compatible" @@ -3556,8 +3676,8 @@ msgid "must use keyword argument for key function" msgstr "must use keyword argument for key function" #: py/runtime.c -msgid "name '%q' is not defined" -msgstr "name '%q' is not defined" +msgid "name '%q' isn't defined" +msgstr "name '%q' isn't defined" #: py/runtime.c msgid "name not defined" @@ -3974,6 +4094,10 @@ msgstr "roll argument must be an ndarray" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed must be true" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4193,12 +4317,12 @@ msgid "tx and rx cannot both be None" msgstr "tx and rx cannot both be None" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" -msgstr "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" +msgstr "type '%q' isn't an acceptable base type" #: py/objtype.c -msgid "type is not an acceptable base type" -msgstr "type is not an acceptable base type" +msgid "type isn't an acceptable base type" +msgstr "type isn't an acceptable base type" #: py/runtime.c msgid "type object '%q' has no attribute '%q'" @@ -4259,7 +4383,9 @@ msgstr "unmatched '%c' in format" msgid "unreadable attribute" msgstr "unreadable attribute" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "unsupported %q type" @@ -4339,11 +4465,6 @@ msgstr "weights must be an object of type %q, %q, %q, or %q, not %q " msgid "width must be greater than zero" msgstr "width must be greater than zero" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "WiFi is not enabled" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "wifi.Monitor not available" @@ -4406,6 +4527,50 @@ msgstr "zi must be of float type" msgid "zi must be of shape (n_section, 2)" msgstr "zi must be of shape (n_section, 2)" +#~ msgid "Unsupported format" +#~ msgstr "Unsupported format" + +#~ msgid "Wifi is not enabled" +#~ msgstr "Wifi is not enabled" + +#~ msgid "wifi is not enabled" +#~ msgstr "WiFi is not enabled" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "Cannot remount '/' when visible via USB." + +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q must be a %q object, %q, or %q" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Data chunk must follow fmt chunk" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "level must be between 0 and 1" + +#~ msgid "init I2C" +#~ msgstr "init I2C" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "The sample's bits_per_sample does not match the mixer's" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "The sample's channel count does not match the mixer's" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "The sample's sample rate does not match the mixer's" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "The sample's signedness does not match the mixer's" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Buffer length must be a multiple of 512" @@ -4680,8 +4845,8 @@ msgstr "zi must be of shape (n_section, 2)" #~ msgid "'continue' outside loop" #~ msgstr "'continue' outside loop" -#~ msgid "'coroutine' object is not an iterator" -#~ msgstr "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" +#~ msgstr "'coroutine' object isn't an iterator" #~ msgid "(x,y) integers required" #~ msgstr "(x,y) integers required" @@ -5551,8 +5716,8 @@ msgstr "zi must be of shape (n_section, 2)" #~ msgid "first argument must be an iterable" #~ msgstr "first argument must be an iterable" -#~ msgid "function does not take keyword arguments" -#~ msgstr "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" +#~ msgstr "function doesn't take keyword arguments" #~ msgid "incompatible native .mpy architecture" #~ msgstr "incompatible native .mpy architecture" @@ -5617,8 +5782,8 @@ msgstr "zi must be of shape (n_section, 2)" #~ msgid "maximum number of dimensions is 4" #~ msgstr "maximum number of dimensions is 4" -#~ msgid "name reused for argument" -#~ msgstr "name reused for argument" +#~ msgid "argument name reused" +#~ msgstr "argument name reused" #~ msgid "no available NIC" #~ msgstr "no available NIC" diff --git a/locale/en_US.po b/locale/en_US.po index e9344480c76..f621d0aa19a 100644 --- a/locale/en_US.po +++ b/locale/en_US.po @@ -274,7 +274,7 @@ msgid "'%q' object does not support '%q'" msgstr "" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -282,7 +282,7 @@ msgid "'%q' object is not callable" msgstr "" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -3068,7 +3068,7 @@ msgid "format" msgstr "" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "" #: py/objdeque.c @@ -3538,7 +3538,7 @@ msgid "must use keyword argument for key function" msgstr "" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "" #: py/runtime.c @@ -4166,11 +4166,11 @@ msgid "tx and rx cannot both be None" msgstr "" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "" #: py/runtime.c diff --git a/locale/en_x_pirate.po b/locale/en_x_pirate.po index f7b682d5626..17cac9cb0fb 100644 --- a/locale/en_x_pirate.po +++ b/locale/en_x_pirate.po @@ -274,7 +274,7 @@ msgid "'%q' object does not support '%q'" msgstr "" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -282,7 +282,7 @@ msgid "'%q' object is not callable" msgstr "" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -3070,7 +3070,7 @@ msgid "format" msgstr "" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "" #: py/objdeque.c @@ -3540,7 +3540,7 @@ msgid "must use keyword argument for key function" msgstr "" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "" #: py/runtime.c @@ -4168,11 +4168,11 @@ msgid "tx and rx cannot both be None" msgstr "" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "" #: py/runtime.c diff --git a/locale/es.po b/locale/es.po index 2eea525f412..87589c2c28b 100644 --- a/locale/es.po +++ b/locale/es.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-16 15:03+0000\n" -"Last-Translator: RubenD \n" +"PO-Revision-Date: 2026-05-06 18:11+0000\n" +"Last-Translator: Francisco Serrador \n" "Language-Team: \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.2\n" +"X-Generator: Weblate 5.17.1\n" #: main.c msgid "" @@ -97,17 +97,17 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "%q y %q contienen pines duplicados" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q y %q deben ser diferentes" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "%q and %q must share a clock unit" -msgstr "" +msgstr "%q y %q deben compartir la misma unidad de tiempo" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "%q cannot be changed once mode is set to %q" -msgstr "" +msgstr "no se puede cambiar %q una vez que se establece el modo a %q" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -117,7 +117,11 @@ msgstr "%q contiene pines duplicados" msgid "%q failure: %d" msgstr "%q fallo: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q en %q debe ser de tipo %q o %q, no %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q en %q debe ser del tipo %q, no %q" @@ -169,9 +173,9 @@ msgstr "%q longitud debe ser <= %d" msgid "%q length must be >= %d" msgstr "%q longitud debe ser >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" -msgstr "" +msgstr "%q movido de %q a %q" #: py/argcheck.c msgid "%q must be %d" @@ -196,7 +200,7 @@ msgstr "%q debe ser <= %d" #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "%q must be <= %u" -msgstr "" +msgstr "%q debe ser <= %u" #: py/argcheck.c msgid "%q must be >= %d" @@ -212,7 +216,7 @@ msgstr "%q debe ser un bytearray o array de tipo 'h', 'H', 'b', o 'B'" #: shared-bindings/warnings/__init__.c msgid "%q must be a subclass of %q" -msgstr "" +msgstr "%q debe ser una subclase de %q" #: ports/espressif/common-hal/analogbufio/BufferedIn.c msgid "%q must be array of type 'H'" @@ -224,20 +228,22 @@ msgstr "%q debe ser una matriz de tipo 'h'" #: shared-bindings/audiobusio/PDMIn.c msgid "%q must be multiple of 8." -msgstr "" +msgstr "%q debe ser múltiplo de 8." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q debe ser del tipo %q o %q, y no %q" #: shared-bindings/jpegio/JpegDecoder.c msgid "%q must be of type %q, %q, or %q, not %q" -msgstr "" +msgstr "%q debe ser de tipo %q, %q, o %q, no %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q debe ser del tipo %q, y no %q" @@ -261,7 +267,7 @@ msgstr "%q fuera de rango" #: py/objmodule.c py/runtime.c msgid "%q renamed %q" -msgstr "" +msgstr "%q renombrado %q" #: py/objrange.c py/objslice.c shared-bindings/random/__init__.c msgid "%q step cannot be zero" @@ -269,7 +275,7 @@ msgstr "%q paso no puede ser cero" #: shared-module/bitbangio/I2C.c msgid "%q too long" -msgstr "" +msgstr "%q demasiado largo" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -277,13 +283,14 @@ msgstr "%q() toma %d argumentos posicionales pero %d fueron dados" #: shared-module/jpegio/JpegDecoder.c msgid "%q() without %q()" -msgstr "" +msgstr "%q() sin %q()" #: shared-bindings/usb_hid/Device.c msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, y %q deben tener la misma longitud" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -317,7 +324,7 @@ msgid "'%q' object does not support '%q'" msgstr "objeto '%q' no tiene capacidad '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "objeto '%q' no es un iterador" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -325,7 +332,7 @@ msgid "'%q' object is not callable" msgstr "objeto '%q' no es llamable" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "objeto '%q' no es iterable" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -415,7 +422,7 @@ msgstr "'await' fuera de la función" #: py/compile.c msgid "'break'/'continue' outside loop" -msgstr "" +msgstr "'break'/'continue' fuera del bucle" #: py/compile.c msgid "'data' requires at least 2 arguments" @@ -431,7 +438,7 @@ msgstr "'label' requiere 1 argumento" #: py/emitnative.c msgid "'not' not implemented" -msgstr "" +msgstr "'not' no implementado" #: py/compile.c msgid "'return' outside function" @@ -461,7 +468,7 @@ msgstr ", en %q\n" #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid ".show(x) removed. Use .root_group = x" -msgstr "" +msgstr ".show(x) eliminado. Utiliza .root_group = x" #: py/objcomplex.c msgid "0.0 to a complex power" @@ -473,7 +480,7 @@ msgstr "pow() con 3 argumentos no soportado" #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "AP could not be started" -msgstr "" +msgstr "No se pudo iniciar el Punto de Acceso" #: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format @@ -488,7 +495,7 @@ msgstr "Rango de dirección no permitido" #: shared-bindings/memorymap/AddressRange.c msgid "Address range wraps around" -msgstr "" +msgstr "Rango de direcciones cubre alrededor" #: ports/espressif/common-hal/canio/CAN.c msgid "All CAN peripherals are in use" @@ -554,7 +561,6 @@ msgstr "Todos los timers para este pin están en uso" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Todos los timers en uso" @@ -567,6 +573,10 @@ msgstr "Ya se encuentra publicando." msgid "Already have all-matches listener" msgstr "Ya se tiene un escucha de todas las coincidencias" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Ya esta en progreso" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -576,6 +586,7 @@ msgstr "Ya está en ejecución" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Ya se están buscando redes wifi" @@ -602,6 +613,11 @@ msgstr "El array debe contener medias palabras (escriba 'H')" msgid "Array values should be single bytes." msgstr "Valores del array deben ser bytes individuales." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" +"Transferencia SPI asíncrona en curso en este canal, manténgase esperando." + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -611,6 +627,11 @@ msgstr "Tratando de localizar %d bloques" msgid "Audio conversion not implemented" msgstr "Conversión de audio no está implementada" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Error de fuente de audio" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN no se usa con contraseña" @@ -642,7 +663,7 @@ msgstr "Por debajo de la tasa mínima de refrescamiento" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c msgid "Bit clock and word select must be sequential GPIO pins" -msgstr "" +msgstr "Reloj de bit y selección de palabra deben ser pines secuenciales GPIO" #: shared-bindings/bitmaptools/__init__.c msgid "Bitmap size and bits per value must match" @@ -687,7 +708,7 @@ msgstr "" #: shared-module/sdcardio/SDCard.c #, c-format msgid "Buffer must be a multiple of %d bytes" -msgstr "" +msgstr "El búfer debe ser múltiplo de %d bytes" #: shared-bindings/_bleio/PacketBuffer.c #, c-format @@ -747,6 +768,10 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "Solo puede alerta en dos low pines viniendo de deep sleep." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "No se puede construir AudioOut porque ya hay un canal continuo abierto" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -794,8 +819,8 @@ msgid "Cannot record to a file" msgstr "No se puede grabar en un archivo" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "No se puede remountar '/' cuanto se es visible vía USB." +msgid "Cannot remount path when visible via USB." +msgstr "No se puede volver a montar path mientras es visible a través de USB." #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -810,6 +835,10 @@ msgstr "No se puede especificar RTS o CTS en modo RS485" msgid "Cannot subclass slice" msgstr "No se puede manejar la partición en una subclase" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "No se puede utilizar GPIO0..15 junto con GPIO32..47" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "No puede ser despertado en transición de pin, only nivel" @@ -846,6 +875,10 @@ msgstr "Las matrices de coordenadas tienen diferentes longitudes" msgid "Coordinate arrays types have different sizes" msgstr "Las matrices de coordenadas tienen diferentes tamaños" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "No se pudo publicar al tema ROS" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "No se puede definir la dirección" @@ -858,6 +891,11 @@ msgstr "No se pudo iniciar la interrupción, RX ocupado" msgid "Couldn't allocate decoder" msgstr "No se pudo encontrar el decodificador" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "Fallo ROS critico durante reinicio suave, se requiere reiniciar: %d" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Error de inicio del canal DAC" @@ -875,13 +913,9 @@ msgstr "DAC ya está siendo utilizado" msgid "Data 0 pin must be byte aligned" msgstr "El pin Data 0 debe estar alineado a bytes" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Trozo de datos debe seguir fmt chunk" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" -msgstr "" +msgstr "Error de formato de datos (pueden ser datos incompletos)" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c @@ -904,7 +938,7 @@ msgstr "Capacidad de destino es mas pequeña que destination_length." #: shared-module/jpegio/JpegDecoder.c msgid "Device error or wrong termination of input stream" -msgstr "" +msgstr "Error de dispositivo o terminación errónea del flujo de entrada" #: ports/nordic/common-hal/audiobusio/I2SOut.c msgid "Device in use" @@ -978,12 +1012,14 @@ msgstr "No se puede adquirir el mutex, error 0x%04x" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Failed to add service TXT record" -msgstr "" +msgstr "Fallo al adicionar el servicio en el registro TXT" #: shared-bindings/mdns/Server.c msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" +"Fallo al adicionar el servicio en el registro TXT; fueron encontrados " +"elementos diferentes a cadena de caracteres o bytes en txt_records" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" @@ -1010,15 +1046,47 @@ msgstr "Error al conectar: error interno" msgid "Failed to connect: timeout" msgstr "Error al conectar: tiempo de espera agotado" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "Error al crear canales continuos: argumento no válido" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "Error al crear canales continuos: estado no válido" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Error al crear canales continuos: Sin memoria" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Error al crear canales continuos: no encontrado" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Ha fallado al habilitar continuo" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Error al analizar el archivo MP3" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Error al registrar la devolución de llamada de eventos continuos" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "No se puede liberar el mutex, err 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "Fallo al establecer el nombre de host" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Error al iniciar audio asíncrono" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Error al escribir el flash interno." @@ -1027,12 +1095,14 @@ msgstr "Error al escribir el flash interno." msgid "File exists" msgstr "El archivo ya existe" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "Archivo no encontrado" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Filtros muy complejos" @@ -1060,7 +1130,7 @@ msgstr "" "Para espacios de colores RGB, el bitmap de entrada debe tener 16 bits por " "pixel" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "Sin capacidades para el formato" @@ -1156,7 +1226,7 @@ msgstr "La entrada está durando mucho tiempo" #: py/moderrno.c msgid "Input/output error" -msgstr "error Input/output" +msgstr "Error input/output" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c @@ -1170,13 +1240,14 @@ msgstr "Cifrado insuficiente" #: shared-module/jpegio/JpegDecoder.c msgid "Insufficient memory pool for the image" -msgstr "" +msgstr "Reserva de memoria insuficiente para la imagen" #: shared-module/jpegio/JpegDecoder.c msgid "Insufficient stream input buffer" -msgstr "" +msgstr "Búfer de flujo de entrada insuficiente" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "La interfaz debe ser iniciada" @@ -1208,7 +1279,7 @@ msgstr "Error interno #%d" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-bindings/pwmio/PWMOut.c msgid "Internal resource(s) in use" -msgstr "" +msgstr "Recurso(s) interno(s) en uso" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." @@ -1220,7 +1291,7 @@ msgstr "Error de interrupción." #: shared-module/jpegio/JpegDecoder.c msgid "Interrupted by output function" -msgstr "" +msgstr "Interrumpido por resultado de función" #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c @@ -1232,14 +1303,16 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "%q inválido" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-module/aurora_epaper/aurora_framebuffer.c msgid "Invalid %q and %q" -msgstr "" +msgstr "%q y %q no válidos" #: ports/atmel-samd/common-hal/microcontroller/Pin.c #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c @@ -1265,6 +1338,10 @@ msgstr "BSSID inválido" msgid "Invalid MAC address" msgstr "Dirección MAC inválida" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "ID de dominio ROS invalido" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -1276,7 +1353,7 @@ msgstr "Inválido bits por valor" #: shared-module/os/getenv.c #, c-format msgid "Invalid byte %.*s" -msgstr "byte %.*s Inválido" +msgstr "Byte %.*s no válido" #: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format @@ -1296,6 +1373,7 @@ msgid "Invalid hex password" msgstr "Contraseña hexadecimal no válida" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Dirección MAC de multidifusión inválida" @@ -1305,9 +1383,10 @@ msgstr "Tamaño incorrecto" #: shared-module/ssl/SSLSocket.c msgid "Invalid socket for TLS" -msgstr "socket invalido para TLS" +msgstr "Socket invalido para TLS" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "Estado invalido" @@ -1342,6 +1421,7 @@ msgstr "El Layer debe ser un grupo o una subclase de TileGrid" #: shared-bindings/audiocore/RawSample.c msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" +"La longitud de %q debe ser un múltiplo par de channel_count * type_size" #: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" @@ -1350,7 +1430,12 @@ msgstr "La dirección MAC es incorrecta" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/espressif/common-hal/_bleio/Descriptor.c msgid "MITM security not supported" -msgstr "" +msgstr "Seguridad MITM no compatible" + +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "Error de Reloj MMC/SDIO %x" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" @@ -1395,15 +1480,16 @@ msgstr "Falta jmp_pin. %q[%u] salta en pin" #: shared-module/storage/__init__.c msgid "Mount point directory missing" -msgstr "" +msgstr "Falta el directorio de punto de montaje" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Debe de ser una subclase de %q." #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c msgid "Must provide 5/6/5 RGB pins" -msgstr "" +msgstr "Debe proporcionar los pines RGB 5/6/5" #: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c msgid "Must provide MISO or MOSI pin" @@ -1467,7 +1553,7 @@ msgstr "No se encontró el canal DMA" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA pacing timer found" -msgstr "timer por establecedor de paso DMA no encontrado" +msgstr "Temporizador DMA no encontrado" #: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c #, c-format @@ -1482,7 +1568,7 @@ msgstr "No IP" #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "No bootloader present" -msgstr "" +msgstr "Ningún bootloader presente" #: shared-module/usb/core/Device.c msgid "No configuration set" @@ -1537,6 +1623,10 @@ msgstr "No se encontró pull up en SDA or SCL; verifique su cableado" msgid "No pulldown on pin; 1Mohm recommended" msgstr "No hay pulldown en el pin; 1Mohm recomendado" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "Sin pullup en el pin; 1Mohm recomendado" + #: py/moderrno.c msgid "No space left on device" msgstr "No queda espacio en el dispositivo" @@ -1578,13 +1668,13 @@ msgstr "No reproduciendo" #: shared-module/jpegio/JpegDecoder.c msgid "Not supported JPEG standard" -msgstr "" +msgstr "Estándar JPEG no compatible" #: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c #: ports/espressif/common-hal/sdioio/SDCard.c #, c-format msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +msgstr "El número de data_pins debe ser %d o %d, no %d" #: shared-bindings/util.c msgid "" @@ -1609,7 +1699,7 @@ msgstr "Ok" #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c #, c-format msgid "Only 8 or 16 bit mono with %dx oversampling supported." -msgstr "" +msgstr "Solamente 8 o 16 bit mono con %dx oversampling soportado." #: ports/espressif/common-hal/wifi/__init__.c #: ports/raspberrypi/common-hal/wifi/__init__.c @@ -1640,15 +1730,6 @@ msgstr "Este hardware solo tiene capacidad para detección de borde" msgid "Only int or string supported for ip" msgstr "Solamente int or string son permitados para una ip" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Solo se admiten BMP monocromáticos, indexados de 4 bpp u 8 bpp y 16 bpp o " -"más: %d bpp proporcionados" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "Solamente un %q puede ser establecido en deep sleep." @@ -1699,6 +1780,7 @@ msgstr "Memoria agotada" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Se acabaron los enchufes" @@ -1718,9 +1800,14 @@ msgstr "Segmento PWM ya esta en uso" msgid "PWM slice channel A already in use" msgstr "Segmento del PWM canal A ya esta en uso" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" +"Búferes de paquetes para transferencia SPI deben de ser de igual longitud." + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" -msgstr "" +msgstr "Error de parámetro" #: ports/espressif/common-hal/audiobusio/__init__.c msgid "Peripheral in use" @@ -1822,6 +1909,10 @@ msgstr "El tamaño del programa no es correcto" msgid "Program too long" msgstr "El programa es demasiado grande" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "Las publicadores solo pueden ser creadas desde un nodo antecesor" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull no se usa cuando la dirección es output." @@ -1832,7 +1923,7 @@ msgstr "RISE_AND_FALL no esta disponible para este chip" #: shared-module/displayio/OnDiskBitmap.c msgid "RLE-compressed BMP not supported" -msgstr "" +msgstr "BMP RLE-comprimidos no estan soportados" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" @@ -1842,6 +1933,26 @@ msgstr "Error de desinicialización de RNG" msgid "RNG Init Error" msgstr "Error de inicialización de RNG" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "Fallo al inicializar ROS, El agente esta conectado?" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "Fallo interno de instalación ROS" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "Fallo de asignación de memoria ROS" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "Fallo al inicializar nodo ROS" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "Fallo al inicializar Tema ROS" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1901,7 +2012,7 @@ msgstr "Canal derecho no soportado" #: shared-module/jpegio/JpegDecoder.c msgid "Right format but not supported" -msgstr "" +msgstr "Formato correcto pero no compatible" #: main.c msgid "Running in safe mode! Not running saved code.\n" @@ -1925,7 +2036,7 @@ msgstr "Error SDIO GetCardInfo %d" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO Init Error %x" -msgstr "" +msgstr "Error de inicio de SDIO %x" #: ports/espressif/common-hal/busio/SPI.c msgid "SPI configuration failed" @@ -1974,11 +2085,13 @@ msgstr "Slice y value tienen tamaños diferentes." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Rebanadas no soportadas" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool solo se puede usar con wifi.radio" @@ -1992,7 +2105,7 @@ msgstr "Especifique exactamente uno de data0 or data_pins" #: supervisor/shared/safe_mode.c msgid "Stack overflow. Increase stack size." -msgstr "" +msgstr "Desbordamiento de pila. Aumenta el tamaño de pila." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2019,21 +2132,9 @@ msgstr "La excepción fue la causa directa de la excepción siguiente:" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "La longitud de rgb_pins debe ser 6, 12, 18, 24, o 30" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Los bits_per_sample del sample no igualan a los del mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "La cuenta de canales del sample no iguala a las del mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "El sample rate del sample no iguala al del mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "El signo del sample no iguala al del mixer" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "El %q de la muestra no concuerda" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2055,7 +2156,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "La altura del Tile debe dividir exacto la altura del bitmap" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Índice de mosaico fuera de límites" @@ -2063,6 +2166,10 @@ msgstr "Índice de mosaico fuera de límites" msgid "Tile width must exactly divide bitmap width" msgstr "Ancho del Tile debe dividir exactamente el ancho de mapa de bits" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "TilePaletteMapper solo puede vincularse una vez a un TileGrid" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "Tiempo suministrado esta en el pasado." @@ -2085,7 +2192,7 @@ msgstr "Demasiados canales en sample." #: ports/espressif/common-hal/_bleio/Characteristic.c msgid "Too many descriptors" -msgstr "" +msgstr "Demasiados descriptores" #: shared-module/displayio/__init__.c msgid "Too many display busses; forgot displayio.release_displays() ?" @@ -2165,7 +2272,7 @@ msgstr "UUID valor no es un str, int o byte buffer" #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Unable to access unaligned IO register" -msgstr "" +msgstr "Incapaz de acceder al registro no alineado de IO" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -2176,7 +2283,7 @@ msgstr "No se pudieron asignar buffers para la conversión con signo" #: supervisor/shared/safe_mode.c msgid "Unable to allocate to the heap." -msgstr "" +msgstr "Imposible de asignar al heap." #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" @@ -2196,6 +2303,12 @@ msgstr "Incapaz de inicializar el parser" msgid "Unable to read color palette data" msgstr "No se pudo leer los datos de la paleta de colores" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" +"No se puede enviar mensaje CAN todos los búferes de mensajes Tx están " +"ocupados" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2207,7 +2320,7 @@ msgstr "Imposible escribir en nvm." #: ports/raspberrypi/common-hal/memorymap/AddressRange.c msgid "Unable to write to read-only memory" -msgstr "" +msgstr "Incapaz de escribir en memoria de solo lectura" #: shared-bindings/alarm/SleepMemory.c msgid "Unable to write to sleep_memory." @@ -2290,22 +2403,19 @@ msgstr "Espacio de color no sportado" msgid "Unsupported display bus type" msgstr "Sin capacidad de bus tipo display" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Formato no soportado" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "Algoritmo hash no soportado" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" -msgstr "" +msgstr "Tipo de socket no compatible" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update failed" -msgstr "" +msgstr "Actualización fallida" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c @@ -2355,9 +2465,11 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "Wifi no esta activado" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "WiFi no está habilitado" #: main.c msgid "Woken up by alarm.\n" @@ -2379,12 +2491,13 @@ msgstr "Usted presionó ambos botones al iniciar." #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "Usted presionó el botón A al iniciar." #: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h msgid "You pressed button DOWN at start up." -msgstr "" +msgstr "Usted presionó el botón DOWN en el arranque." #: supervisor/shared/safe_mode.c msgid "You pressed the BOOT button at start up" @@ -2392,8 +2505,9 @@ msgstr "Usted presionó el botón BOOT al iniciar" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." -msgstr "" +msgstr "Usted presionó el botón BOOT en el arranque." #: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h msgid "You pressed the GPIO0 button at start up." @@ -2452,6 +2566,10 @@ msgstr "se requiere un objeto bytes-like" msgid "addresses is empty" msgstr "addresses esta vacío" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "Ya se está reproduciendo" + #: py/compile.c msgid "annotation must be an identifier" msgstr "la anotación debe ser un identificador" @@ -2470,15 +2588,15 @@ msgstr "arg debe ser tipo-user" #: extmod/ulab/code/numpy/numerical.c msgid "argsort argument must be an ndarray" -msgstr "El argumento para argsort debe ser un ndarray" +msgstr "el argumento para argsort debe ser un ndarray" #: extmod/ulab/code/numpy/numerical.c msgid "argsort is not implemented for flattened arrays" -msgstr "El argot no está implementado para arrays aplanados" +msgstr "argsort no está implementado para arrays aplanados" #: extmod/ulab/code/numpy/random/random.c msgid "argument must be None, an integer or a tuple of integers" -msgstr "" +msgstr "el argumento debe ser None, un entero o una tupla de enteros" #: py/compile.c msgid "argument name reused" @@ -2495,11 +2613,11 @@ msgstr "argumentos deben ser ndarrays" #: extmod/ulab/code/ndarray.c msgid "array and index length must be equal" -msgstr "Longitud del array e índice tienen que ser iguales" +msgstr "las longitudes del array e índice deben ser iguales" #: extmod/ulab/code/numpy/io/io.c msgid "array has too many dimensions" -msgstr "La matriz tiene demasiadas dimensiones" +msgstr "la matriz tiene demasiadas dimensiones" #: extmod/ulab/code/ndarray.c msgid "array is too big" @@ -2516,11 +2634,11 @@ msgstr "desborde de asm" #: py/compile.c msgid "async for/with outside async function" -msgstr "" +msgstr "async for/with fuera de función async" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get (arg)min/(arg)max of empty sequence" -msgstr "Intendo de obteber (arg)min/(arg)max de secuencia vacía" +msgstr "intento de obtener (arg)min/(arg)max de secuencia vacía" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get argmin/argmax of an empty sequence" @@ -2528,23 +2646,27 @@ msgstr "intento de obtener argmin/argmax de una secuencia vacía" #: py/objstr.c msgid "attributes not supported" -msgstr "" +msgstr "atributos no compatibles" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "Formato de audio no compatible" #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" -msgstr "Eje está fuera de sus límites" +msgstr "eje está fuera de sus límites" #: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c msgid "axis must be None, or an integer" -msgstr "Eje tiene que ser None, o un entero" +msgstr "eje debe ser None, o un entero" #: extmod/ulab/code/numpy/numerical.c msgid "axis too long" -msgstr "Eje demasiado largo" +msgstr "eje demasiado largo" #: shared-bindings/bitmaptools/__init__.c msgid "background value out of range of target" -msgstr "El valor del fondo esta fuera del rango del objectivo" +msgstr "el valor del fondo esta fuera del rango del objetivo" #: py/builtinevex.c msgid "bad compile mode" @@ -2566,18 +2688,31 @@ msgstr "typecode erroneo" msgid "binary op %q not implemented" msgstr "operacion binaria %q no implementada" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth debe ser de 8, 16, 24, or 32." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" -msgstr "" +msgstr "el tamaño y profundidad del mapa de bits deben coincidir" #: shared-bindings/bitmaptools/__init__.c msgid "bitmap sizes must match" -msgstr "Los tamaños de los bitmap deben coincidir" +msgstr "los tamaños de los bitmap deben coincidir" #: extmod/modrandom.c msgid "bits must be 32 or less" msgstr "los bits deben ser 32 o menos" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample debe ser 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample debe ser 8 ó 16" @@ -2588,11 +2723,11 @@ msgstr "la rama no está dentro del rango" #: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c msgid "buffer is smaller than requested size" -msgstr "El buffer es mas pequeño que el requerido" +msgstr "el búfer es más pequeño que el tamaño solicitado" #: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c msgid "buffer size must be a multiple of element size" -msgstr "El tamaño del buffer debe ser un múltiplo del tamaño del elemento" +msgstr "el tamaño del búfer debe ser un múltiplo del tamaño del elemento" #: shared-module/struct/__init__.c msgid "buffer size must match format" @@ -2600,7 +2735,7 @@ msgstr "el tamaño del buffer debe de coincidir con el formato" #: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c msgid "buffer slices must be of equal length" -msgstr "Las secciones del buffer necesitan tener longitud igual" +msgstr "las secciones del búfer deben tener la misma longitud" #: py/modstruct.c shared-module/struct/__init__.c msgid "buffer too small" @@ -2659,7 +2794,7 @@ msgstr "no se puede asignar a la expresión" msgid "can't cancel self" msgstr "no se puede cancelar a si mismo" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "no puede convertir %q a %q" @@ -2716,7 +2851,7 @@ msgstr "no se puede hacer una operacion binaria entre '%q' y '%q'" #: py/emitnative.c msgid "can't do unary op of '%q'" -msgstr "" +msgstr "no puede ser unary op de '%q'" #: py/emitnative.c msgid "can't implicitly convert '%q' to 'bool'" @@ -2724,7 +2859,7 @@ msgstr "no se puede convertir implícitamente '%q' a 'bool'" #: py/runtime.c msgid "can't import name %q" -msgstr "" +msgstr "no se puede importar el nombre %q" #: py/emitnative.c msgid "can't load from '%q'" @@ -2783,7 +2918,7 @@ msgstr "" #: py/objcomplex.c msgid "can't truncate-divide a complex number" -msgstr "" +msgstr "no puede truncar-rendondear un numéro complejo" #: extmod/modasyncio.c msgid "can't wait" @@ -2795,7 +2930,7 @@ msgstr "no se puede asignar una nueva forma" #: extmod/ulab/code/ndarray_operators.c msgid "cannot cast output with casting rule" -msgstr "No se puede realizar cast de la salida sin una regla de cast" +msgstr "no se puede realizar cast de la salida sin una regla de cast" #: extmod/ulab/code/ndarray.c msgid "cannot convert complex to dtype" @@ -2835,15 +2970,15 @@ msgstr "chars buffer es demasiado pequeño" #: py/modbuiltins.c msgid "chr() arg not in range(0x110000)" -msgstr "El argumento de chr() esta fuera de rango(0x110000)" +msgstr "argumento chr() está fuera de rango(0x110000)" #: py/modbuiltins.c msgid "chr() arg not in range(256)" -msgstr "El argumento de chr() no esta en el rango(256)" +msgstr "argumento chr() no está en el rango(256)" #: shared-bindings/bitmaptools/__init__.c msgid "clip point must be (x,y) tuple" -msgstr "El punto de recorte debe ser una tupla (x, y)" +msgstr "el punto de recorte debe ser una tupla (x, y)" #: shared-bindings/msgpack/ExtType.c msgid "code outside range 0~127" @@ -2871,7 +3006,7 @@ msgstr "comparación entre int y uint" #: py/objcomplex.c msgid "complex divide by zero" -msgstr "" +msgstr "división compleja entre cero" #: py/objfloat.c py/parsenum.c msgid "complex values not supported" @@ -2899,7 +3034,7 @@ msgstr "los argumentos para convolve no deben estar vacíos" #: extmod/ulab/code/numpy/io/io.c msgid "corrupted file" -msgstr "Archivo corrompido" +msgstr "archivo corrompido" #: extmod/ulab/code/numpy/poly.c msgid "could not invert Vandermonde matrix" @@ -2911,7 +3046,7 @@ msgstr "no se pudo determinar la versión de la tarjeta SD" #: extmod/ulab/code/numpy/numerical.c msgid "cross is defined for 1D arrays of length 3" -msgstr "Cruce está definido para un array 1D de longitud 3" +msgstr "cruce está definido para un array 1D de longitud 3" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "data must be iterable" @@ -2959,11 +3094,11 @@ msgstr "la secuencia de actualizacion del dict tiene una longitud incorrecta" #: extmod/ulab/code/numpy/numerical.c msgid "diff argument must be an ndarray" -msgstr "El argumento diff debe ser un ndarray" +msgstr "el argumento diff debe ser un ndarray" #: extmod/ulab/code/numpy/numerical.c msgid "differentiation order out of range" -msgstr "Orden de diferenciación fuera de rango" +msgstr "órden de diferenciación fuera de rango" #: extmod/ulab/code/numpy/transform.c msgid "dimensions do not match" @@ -2987,7 +3122,7 @@ msgstr "dtype debe ser float, o complex" #: extmod/ulab/code/ndarray_operators.c msgid "dtype of int32 is not supported" -msgstr "" +msgstr "dtype de int32 no compatible" #: py/objdeque.c msgid "empty" @@ -3086,7 +3221,7 @@ msgstr "el primer argumento debe ser una función" #: extmod/ulab/code/numpy/create.c msgid "first argument must be a tuple of ndarrays" -msgstr "Primer argumento tiene que ser una tupla de ndarrays" +msgstr "el primer argumento debe ser una tupla de ndarrays" #: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c msgid "first argument must be an ndarray" @@ -3122,10 +3257,10 @@ msgstr "font debe ser 2048 bytes de largo" #: extmod/moddeflate.c msgid "format" -msgstr "" +msgstr "formato" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "format requiere un dict" #: py/objdeque.c @@ -3151,7 +3286,7 @@ msgstr "la función tiene el mismo signo a extremos del intervalo" #: extmod/ulab/code/ndarray.c msgid "function is defined for ndarrays only" -msgstr "Función solo definida para ndarrays" +msgstr "función solo definida para ndarrays" #: extmod/ulab/code/numpy/carray/carray.c msgid "function is implemented for ndarrays only" @@ -3259,10 +3394,6 @@ msgstr "indices deben ser enteros" msgid "indices must be integers, slices, or Boolean lists" msgstr "los índices deben ser enteros, particiones o listas de booleanos" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "inicializacion I2C" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "los valores iniciales deben permitir iteración" @@ -3293,7 +3424,7 @@ msgstr "el tamaño del arreglo de entrada debe ser potencia de 2" #: extmod/ulab/code/numpy/create.c msgid "input arrays are not compatible" -msgstr "Arrays de entrada no son compactibles" +msgstr "matrices de entrada no son compatibles" #: extmod/ulab/code/numpy/poly.c msgid "input data must be an iterable" @@ -3326,11 +3457,11 @@ msgstr "entrada debe ser un ndarray de 1D" #: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c msgid "input must be a dense ndarray" -msgstr "Entrada tiene que ser un ndarray denso" +msgstr "la entrada debe ser un ndarray denso" #: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c msgid "input must be an ndarray" -msgstr "Entrada tiene que ser un ndarray" +msgstr "la entrada debe ser un ndarray" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be an ndarray, or a scalar" @@ -3338,7 +3469,7 @@ msgstr "entrada debe ser una ndarray o un escalar" #: extmod/ulab/code/scipy/signal/signal.c msgid "input must be one-dimensional" -msgstr "Entrada tiene que ser unidimensional" +msgstr "la entrada debe ser unidimensional" #: extmod/ulab/code/ulab_tools.c msgid "input must be square matrix" @@ -3363,7 +3494,7 @@ msgstr "el intervalo debe ser der rango %s-%s" #: py/compile.c msgid "invalid arch" -msgstr "" +msgstr "arco no válido" #: shared-bindings/bitmaptools/__init__.c #, c-format @@ -3449,6 +3580,8 @@ msgstr "" #: py/argcheck.c msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" +"argumento(s) de palabras clave no implementado - en su lugar utiliza " +"argumentos normales" #: py/emitinlinethumb.c py/emitinlinextensa.c msgid "label '%q' not defined" @@ -3458,10 +3591,6 @@ msgstr "etiqueta '%q' no definida" msgid "label redefined" msgstr "etiqueta redefinida" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "el nivel debe ser entre 0 y 1" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs y rhs deben ser compatibles" @@ -3480,7 +3609,7 @@ msgstr "variable local referenciada antes de la asignación" #: ports/espressif/common-hal/canio/CAN.c msgid "loopback + silent mode not supported by peripheral" -msgstr "Loopback + modo silencioso no están soportados por periférico" +msgstr "bucle de retorno + modo silencioso no admitidos por periférico" #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c @@ -3546,7 +3675,7 @@ msgstr "la asignación de memoria falló, el heap está bloqueado" #: py/objarray.c msgid "memoryview offset too large" -msgstr "" +msgstr "memory offset es demasiado grande" #: py/objarray.c msgid "memoryview: length is not a multiple of itemsize" @@ -3555,7 +3684,7 @@ msgstr "" #: extmod/modtime.c msgid "mktime needs a tuple of length 8 or 9" -msgstr "" +msgstr "mktime requiere una tupla de longitud 8 o 9" #: extmod/ulab/code/numpy/linalg/linalg.c msgid "mode must be complete, or reduced" @@ -3594,7 +3723,7 @@ msgid "must use keyword argument for key function" msgstr "debe utilizar argumento de palabra clave para la función clave" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "name '%q' no esta definido" #: py/runtime.c @@ -3603,11 +3732,11 @@ msgstr "name no definido" #: py/qstr.c msgid "name too long" -msgstr "" +msgstr "nombre demasiado largo" #: py/persistentcode.c msgid "native code in .mpy unsupported" -msgstr "" +msgstr "código nativo .mpy no compatible" #: py/asmthumb.c msgid "native method too big" @@ -3853,7 +3982,7 @@ msgstr "la operación no es compatible para un tipo dado" #: extmod/ulab/code/ndarray_operators.c msgid "operation not supported for the input types" -msgstr "" +msgstr "operación no soportada para los tipos de entrada" #: py/modbuiltins.c msgid "ord expects a character" @@ -3866,11 +3995,11 @@ msgstr "ord() espera un carácter, pero encontró un string de longitud %d" #: extmod/ulab/code/utils/utils.c msgid "out array is too small" -msgstr "La matriz de salida es demasiado pequeña" +msgstr "la matriz de salida es demasiado pequeña" #: extmod/ulab/code/numpy/random/random.c msgid "out has wrong type" -msgstr "" +msgstr "tipo de salida incorrecto" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for complex dtype" @@ -3898,11 +4027,11 @@ msgstr "fuera de rango del objetivo" #: extmod/ulab/code/numpy/random/random.c msgid "output array has wrong type" -msgstr "" +msgstr "matriz de salida tiene el tipo erróneo" #: extmod/ulab/code/numpy/random/random.c msgid "output array must be contiguous" -msgstr "" +msgstr "matriz de salida debe ser contiguo" #: py/objint_mpz.c msgid "overflow converting long int to machine word" @@ -4007,12 +4136,16 @@ msgstr "rgb_pins[%d] no está en el mismo puerto que el reloj" #: extmod/ulab/code/numpy/numerical.c msgid "roll argument must be an ndarray" -msgstr "Argumento enrolado tiene que ser un ndarray" +msgstr "argumento enrolado tiene que ser un ndarray" #: py/objstr.c msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed debe ser true" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4032,7 +4165,7 @@ msgstr "sin capacidades para el conjunto" #: extmod/ulab/code/numpy/random/random.c msgid "shape must be None, and integer or a tuple of integers" -msgstr "" +msgstr "shape debe ser None, un entero o una tupla de enteros" #: extmod/ulab/code/ndarray.c msgid "shape must be integer or tuple of integers" @@ -4056,7 +4189,7 @@ msgstr "el tamaño se define solo para ndarrays" #: extmod/ulab/code/numpy/random/random.c msgid "size must match out.shape when used together" -msgstr "" +msgstr "out.shape y el tamaño deben coincidir cuando se usan juntos" #: py/nativeglue.c msgid "slice unsupported" @@ -4104,7 +4237,7 @@ msgstr "source_bitmap debe tener value_count de 8" #: extmod/modre.c msgid "splitting with sub-captures" -msgstr "" +msgstr "dividiendo con sub-capturas" #: py/objstr.c msgid "start/end indices" @@ -4120,7 +4253,7 @@ msgstr "operación stream no soportada" #: py/objarray.c py/objstr.c msgid "string argument without an encoding" -msgstr "" +msgstr "argumento de cadena de texto sin codificación" #: py/objstrunicode.c msgid "string index out of range" @@ -4145,7 +4278,7 @@ msgstr "error de sintaxis en JSON" #: extmod/modtime.c msgid "ticks interval overflow" -msgstr "" +msgstr "desbordamiento de intervalo de ticks" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "timeout duration exceeded the maximum supported value" @@ -4158,12 +4291,12 @@ msgstr "timeout debe ser < 655.35 segundos" #: ports/raspberrypi/common-hal/floppyio/__init__.c msgid "timeout waiting for flux" -msgstr "" +msgstr "tiempo límite esperando por el flujo" #: ports/raspberrypi/common-hal/floppyio/__init__.c #: shared-module/floppyio/__init__.c msgid "timeout waiting for index pulse" -msgstr "" +msgstr "tiempo límite esperando por el pulso índice" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" @@ -4230,14 +4363,14 @@ msgstr "twai_start devolvió esp-idf error #%d" #: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c msgid "tx and rx cannot both be None" -msgstr "Ambos tx y rx no pueden ser None" +msgstr "ambos tx y rx no pueden ser None" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "type '%q' no es un tipo de base aceptable" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "type no es un tipo de base aceptable" #: py/runtime.c @@ -4299,7 +4432,9 @@ msgstr "no coteja '%c' en formato" msgid "unreadable attribute" msgstr "atributo no legible" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo de %q no soportado" @@ -4315,7 +4450,7 @@ msgstr "instrucción Xtensa '%s' con %d argumentos no soportada" #: shared-module/bitmapfilter/__init__.c msgid "unsupported bitmap depth" -msgstr "" +msgstr "profundidad de mapa de bits no compatible" #: shared-module/gifio/GifWriter.c msgid "unsupported colorspace for GifWriter" @@ -4361,27 +4496,24 @@ msgstr "valor fuera de alcance al blanco" #: extmod/moddeflate.c msgid "wbits" -msgstr "" +msgstr "wbits" #: shared-bindings/bitmapfilter/__init__.c msgid "" "weights must be a sequence with an odd square number of elements (usually 9 " "or 25)" msgstr "" +"los pesos deben ser una secuencia con una raíz cuadrada impar de elementos " +"(usualmente 9 o 25)" #: shared-bindings/bitmapfilter/__init__.c msgid "weights must be an object of type %q, %q, %q, or %q, not %q " -msgstr "" +msgstr "los pesos deben ser un tipo de objetos %q, %q, %q, or %q, y no %q. " #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "el ancho debe ser mayor que cero" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "wifi no esta habilitado" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "wifi.Monitor no esta disponible" @@ -4444,6 +4576,50 @@ msgstr "zi debe ser de tipo flotante" msgid "zi must be of shape (n_section, 2)" msgstr "zi debe ser una forma (n_section,2)" +#~ msgid "Unsupported format" +#~ msgstr "Formato no soportado" + +#~ msgid "Wifi is not enabled" +#~ msgstr "Wifi no esta activado" + +#~ msgid "wifi is not enabled" +#~ msgstr "wifi no esta habilitado" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "No se puede remountar '/' cuanto se es visible vía USB." + +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q tiene que ser un %q objeto, %q, o %q" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Trozo de datos debe seguir fmt chunk" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Solo se admiten BMP monocromáticos, indexados de 4 bpp u 8 bpp y 16 bpp o " +#~ "más: %d bpp proporcionados" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "el nivel debe ser entre 0 y 1" + +#~ msgid "init I2C" +#~ msgstr "inicializacion I2C" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "Los bits_per_sample del sample no igualan a los del mixer" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "La cuenta de canales del sample no iguala a las del mixer" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "El sample rate del sample no iguala al del mixer" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "El signo del sample no iguala al del mixer" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "El tamaño del buffer debe ser múltiplo de 512" @@ -4755,13 +4931,13 @@ msgstr "zi debe ser una forma (n_section,2)" #~ msgid "'%s' object does not support item deletion" #~ msgstr "objeto '%s' no soporta la eliminación de elementos" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "objeto '%s' no es un iterator" #~ msgid "'%s' object is not callable" #~ msgstr "objeto '%s' no puede ser llamado" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "objeto '%s' no es iterable" #~ msgid "'%s' object is not subscriptable" @@ -4779,7 +4955,7 @@ msgstr "zi debe ser una forma (n_section,2)" #~ msgid "'continue' outside loop" #~ msgstr "'continue' fuera de un bucle" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "el objeto 'coroutine' no es un iterador" #~ msgid "64 bit types" @@ -6239,7 +6415,7 @@ msgstr "zi debe ser una forma (n_section,2)" #~ msgid "frequency can only be either 80Mhz or 160MHz" #~ msgstr "la frecuencia solo puede ser 80MHz ó 160MHz" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "la función no tiene argumentos por palabra clave" #~ msgid "function is implemented for scalars and ndarrays only" @@ -6363,7 +6539,7 @@ msgstr "zi debe ser una forma (n_section,2)" #~ msgid "name must be a string" #~ msgstr "name debe de ser un string" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "name reusado para argumento" #~ msgid "no available NIC" diff --git a/locale/fil.po b/locale/fil.po index 23de4867284..27d949a0615 100644 --- a/locale/fil.po +++ b/locale/fil.po @@ -6,8 +6,8 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-16 15:03+0000\n" -"Last-Translator: Jeff Epler \n" +"PO-Revision-Date: 2025-06-30 16:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: fil\n" "Language: fil\n" "MIME-Version: 1.0\n" @@ -15,13 +15,15 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1 && n != 2 && n != 3 && (n % 10 == 4 " "|| n % 10 == 6 || n % 10 == 9);\n" -"X-Generator: Weblate 5.2\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" "\n" "Code done running.\n" msgstr "" +"\n" +"Code ay tapos na sa pagtakbo\n" #: main.c msgid "" @@ -83,7 +85,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "" @@ -103,7 +105,11 @@ msgstr "" msgid "%q failure: %d" msgstr "" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "" @@ -155,7 +161,7 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "" @@ -215,6 +221,7 @@ msgstr "" #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "" @@ -224,6 +231,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "" @@ -270,7 +278,8 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" @@ -304,7 +313,7 @@ msgid "'%q' object does not support '%q'" msgstr "" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -312,7 +321,7 @@ msgid "'%q' object is not callable" msgstr "" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -463,9 +472,9 @@ msgid "AP could not be started" msgstr "" #: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, fuzzy, c-format +#, c-format msgid "Address must be %d bytes long" -msgstr "ang palette ay dapat 32 bytes ang haba" +msgstr "Dapat na %d bytes ang haba ng address" #: ports/espressif/common-hal/memorymap/AddressRange.c #: ports/nordic/common-hal/memorymap/AddressRange.c @@ -540,7 +549,6 @@ msgstr "Lahat ng timers para sa pin na ito ay ginagamit" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Lahat ng timer ginagamit" @@ -553,6 +561,10 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -562,6 +574,7 @@ msgstr "" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" @@ -588,6 +601,10 @@ msgstr "May halfwords (type 'H') dapat ang array" msgid "Array values should be single bytes." msgstr "Array values ay dapat single bytes." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -597,6 +614,11 @@ msgstr "" msgid "Audio conversion not implemented" msgstr "" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -690,14 +712,13 @@ msgstr "" #: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c #: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c #: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, fuzzy, c-format +#, c-format msgid "Bus pin %d is already in use" -msgstr "Ginagamit na ang DAC" +msgstr "Ginagamit na ang bus pin %d" #: shared-bindings/_bleio/UUID.c -#, fuzzy msgid "Byte buffer must be 16 bytes." -msgstr "buffer ay dapat bytes-like object" +msgstr "Ang byte buffer ay dapat na 16 byte." #: shared-bindings/aesio/aes.c msgid "CBC blocks must be multiples of 16 bytes" @@ -731,6 +752,10 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -777,7 +802,7 @@ msgid "Cannot record to a file" msgstr "Hindi ma-record sa isang file" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." +msgid "Cannot remount path when visible via USB." msgstr "" #: shared-bindings/digitalio/DigitalInOut.c @@ -793,6 +818,10 @@ msgstr "" msgid "Cannot subclass slice" msgstr "Hindi magawa ang sublcass slice" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "" @@ -827,6 +856,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "" @@ -839,6 +872,11 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -857,10 +895,6 @@ msgstr "Ginagamit na ang DAC" msgid "Data 0 pin must be byte aligned" msgstr "graphic ay dapat 2048 bytes ang haba" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Dapat sunurin ng Data chunk ang fmt chunk" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "" @@ -955,9 +989,9 @@ msgid "Failed sending command." msgstr "" #: ports/nordic/sd_mutex.c -#, fuzzy, c-format +#, c-format msgid "Failed to acquire mutex, err 0x%04x" -msgstr "Nabigo sa pag kuha ng mutex, status: 0x%08lX" +msgstr "Nabigong makuha ang mutex, err 0x%04x" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Failed to add service TXT record" @@ -993,14 +1027,46 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" + #: ports/nordic/sd_mutex.c -#, fuzzy, c-format +#, c-format msgid "Failed to release mutex, err 0x%04x" -msgstr "Nabigo sa pagrelease ng mutex, status: 0x%08lX" +msgstr "Nabigong ilabas ang mutex, err 0x%04x" + +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." @@ -1010,12 +1076,14 @@ msgstr "" msgid "File exists" msgstr "Mayroong file" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "" @@ -1040,7 +1108,7 @@ msgstr "" msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "" @@ -1148,6 +1216,7 @@ msgid "Insufficient stream input buffer" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "" @@ -1203,7 +1272,9 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "" @@ -1236,6 +1307,10 @@ msgstr "" msgid "Invalid MAC address" msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Maling argumento" @@ -1267,6 +1342,7 @@ msgid "Invalid hex password" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" @@ -1279,6 +1355,7 @@ msgid "Invalid socket for TLS" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "" @@ -1323,6 +1400,11 @@ msgstr "" msgid "MITM security not supported" msgstr "" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "" @@ -1368,7 +1450,8 @@ msgstr "" msgid "Mount point directory missing" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1508,6 +1591,10 @@ msgstr "" msgid "No pulldown on pin; 1Mohm recommended" msgstr "" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "" + #: py/moderrno.c msgid "No space left on device" msgstr "" @@ -1610,13 +1697,6 @@ msgstr "" msgid "Only int or string supported for ip" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "" @@ -1667,6 +1747,7 @@ msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1686,6 +1767,10 @@ msgstr "" msgid "PWM slice channel A already in use" msgstr "" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "" @@ -1762,6 +1847,8 @@ msgstr "" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +"Pindutin ang kahit anong key para pumasok sa REPL. Gamitin ang CTRL-D para " +"mag-reload\n" #: main.c msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" @@ -1783,30 +1870,54 @@ msgstr "" msgid "Program too long" msgstr "" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull hindi ginagamit kapag ang direksyon ay output." #: ports/raspberrypi/common-hal/countio/Counter.c msgid "RISE_AND_FALL not available on this chip" -msgstr "" +msgstr "RISE_AND_FALL ay hindi pwede sa chip na ito" #: shared-module/displayio/OnDiskBitmap.c msgid "RLE-compressed BMP not supported" -msgstr "" +msgstr "RLE-compressed BMP ay hindi suportado" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" -msgstr "" +msgstr "Error sa RNG DeInit" #: ports/stm/common-hal/os/__init__.c msgid "RNG Init Error" +msgstr "Error sa RNG Init" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" msgstr "" #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1838,11 +1949,11 @@ msgstr "" #: supervisor/shared/bluetooth/bluetooth.c msgid "Reconnecting" -msgstr "" +msgstr "Kumokonekta" #: shared-bindings/epaperdisplay/EPaperDisplay.c msgid "Refresh too soon" -msgstr "" +msgstr "sobrang aga mag-refresh" #: shared-bindings/canio/RemoteTransmissionRequest.c msgid "RemoteTransmissionRequests limited to 8 bytes" @@ -1854,7 +1965,7 @@ msgstr "" #: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" -msgstr "" +msgstr "Hiniling na resource ay hindi nakita" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "Right channel unsupported" @@ -1870,81 +1981,83 @@ msgstr "Tumatakbo sa safe mode! Hindi tumatakbo ang nai-save na code.\n" #: shared-module/sdcardio/SDCard.c msgid "SD card CSD format not supported" -msgstr "" +msgstr "SD card CSD na format ay hindi suportado" #: ports/cxd56/common-hal/sdioio/SDCard.c msgid "SDCard init" -msgstr "" +msgstr "pag-init ng SDCard" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO GetCardInfo Error %d" -msgstr "" +msgstr "Error ng SDIO GetCardInfo %d" #: ports/espressif/common-hal/sdioio/SDCard.c #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO Init Error %x" -msgstr "" +msgstr "Error sa pag-init ng SDIO %x" #: ports/espressif/common-hal/busio/SPI.c msgid "SPI configuration failed" -msgstr "" +msgstr "Nabigo sa SPI configuration" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" -msgstr "" +msgstr "error sa pag-init ng SPI" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" -msgstr "" +msgstr "SPI peripheral ay ginagamit" #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" -msgstr "" +msgstr "pag re-init ng SPI" #: shared-bindings/is31fl3741/FrameBuffer.c msgid "Scale dimensions must divide by 3" -msgstr "" +msgstr "Scale dimensions ay kailangan i-divide sa 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Scan already in progress. Stop with stop_scan." -msgstr "" +msgstr "Scan ay kasalukuyang ginagawa. Patigilin gamit ang stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c msgid "Serializer in use" -msgstr "Serializer ginagamit" +msgstr "Serializer ay ginagamit" #: shared-bindings/ssl/SSLContext.c msgid "Server side context cannot have hostname" -msgstr "" +msgstr "Server side context ay hindi pwede magkaroon ng hostname" #: ports/cxd56/common-hal/camera/Camera.c msgid "Size not supported" -msgstr "" +msgstr "Size ay hindi suportado" #: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c #: shared-bindings/nvm/ByteArray.c msgid "Slice and value different lengths." -msgstr "Slice at value iba't ibang haba." +msgstr "Slice at value ay iba iba ang haba." #: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Hindi suportado ang Slices" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" -msgstr "" +msgstr "SocketPool ay pwede lang gamitin sa wifi.radio" #: shared-bindings/aesio/aes.c msgid "Source and destination buffers must be the same length" -msgstr "" +msgstr "Ang pinagmulan at patutunguhan ng buffer ay dapat na pareho ang haba" #: shared-bindings/paralleldisplaybus/ParallelBus.c msgid "Specify exactly one of data0 or data_pins" @@ -1978,21 +2091,9 @@ msgstr "" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Ang bits_per_sample ng sample ay hindi tugma sa mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Ang channel count ng sample ay hindi tugma sa mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "Ang sample rate ng sample ay hindi tugma sa mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "Ang signedness ng sample hindi tugma sa mixer" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2012,7 +2113,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "" @@ -2020,6 +2123,10 @@ msgstr "" msgid "Tile width must exactly divide bitmap width" msgstr "" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "" @@ -2150,6 +2257,10 @@ msgstr "Hindi ma-init ang parser" msgid "Unable to read color palette data" msgstr "" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2244,15 +2355,12 @@ msgstr "" msgid "Unsupported display bus type" msgstr "Hindi supportadong tipo ng bitmap" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Hindi supportadong format" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "" @@ -2301,10 +2409,12 @@ msgstr "" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " -msgstr "" +msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" #: main.c @@ -2327,6 +2437,7 @@ msgstr "" #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "" @@ -2340,6 +2451,7 @@ msgstr "" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "" @@ -2400,6 +2512,10 @@ msgstr "a bytes-like object ay kailangan" msgid "addresses is empty" msgstr "walang laman ang address" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "" + #: py/compile.c msgid "annotation must be an identifier" msgstr "" @@ -2478,6 +2594,10 @@ msgstr "" msgid "attributes not supported" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "" @@ -2514,6 +2634,10 @@ msgstr "masamang typecode" msgid "binary op %q not implemented" msgstr "binary op %q hindi implemented" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "" + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "" @@ -2526,6 +2650,15 @@ msgstr "" msgid "bits must be 32 or less" msgstr "" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample ay dapat 8 o 16" @@ -2609,7 +2742,7 @@ msgstr "hindi ma i-assign sa expression" msgid "can't cancel self" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" @@ -2621,7 +2754,7 @@ msgstr "hindi ma-convert %s sa complex" #: py/obj.c #, c-format msgid "can't convert %s to float" -msgstr "hindi ma-convert %s sa int" +msgstr "hindi ma-convert %s sa float" #: py/objint.c py/runtime.c #, c-format @@ -2772,7 +2905,7 @@ msgstr "" #: py/emitnative.c msgid "casting" -msgstr "casting" +msgstr "paghahagis" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "channel re-init" @@ -3076,7 +3209,7 @@ msgid "format" msgstr "" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "kailangan ng format ng dict" #: py/objdeque.c @@ -3211,10 +3344,6 @@ msgstr "ang mga indeks ay dapat na integer" msgid "indices must be integers, slices, or Boolean lists" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "" @@ -3411,10 +3540,6 @@ msgstr "label '%d' kailangan na i-define" msgid "label redefined" msgstr "ang label ay na-define ulit" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs at rhs ay dapat magkasundo" @@ -3546,7 +3671,7 @@ msgid "must use keyword argument for key function" msgstr "dapat gumamit ng keyword argument para sa key function" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "name '%q' ay hindi defined" #: py/runtime.c @@ -3927,7 +4052,7 @@ msgstr "" #: py/builtinimport.c msgid "relative import" -msgstr "relative import" +msgstr "kamag-anak na import" #: py/obj.c #, c-format @@ -3964,6 +4089,10 @@ msgstr "" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4015,7 +4144,7 @@ msgstr "" #: py/objint.c py/sequence.c msgid "small int overflow" -msgstr "small int overflow" +msgstr "maliit na int overflow" #: main.c msgid "soft reboot\n" @@ -4183,11 +4312,11 @@ msgid "tx and rx cannot both be None" msgstr "tx at rx hindi pwedeng parehas na None" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "hindi maari ang type na '%q' para sa base type" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "hindi puede ang type para sa base type" #: py/runtime.c @@ -4249,7 +4378,9 @@ msgstr "" msgid "unreadable attribute" msgstr "hindi mabasa ang attribute" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "Hindi supportadong tipo ng %q" @@ -4327,11 +4458,6 @@ msgstr "" msgid "width must be greater than zero" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "" @@ -4394,6 +4520,24 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Unsupported format" +#~ msgstr "Hindi supportadong format" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Dapat sunurin ng Data chunk ang fmt chunk" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "Ang bits_per_sample ng sample ay hindi tugma sa mixer" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "Ang channel count ng sample ay hindi tugma sa mixer" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "Ang sample rate ng sample ay hindi tugma sa mixer" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "Ang signedness ng sample hindi tugma sa mixer" + #~ msgid "struct: index out of range" #~ msgstr "struct: index hindi maabot" @@ -4488,13 +4632,13 @@ msgstr "" #~ msgid "'%s' object does not support item deletion" #~ msgstr "'%s' object ay hindi sumusuporta sa pagtanggal ng item" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "'%s' object ay hindi iterator" #~ msgid "'%s' object is not callable" #~ msgstr "'%s' object hindi matatawag" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "'%s' object ay hindi ma i-iterable" #~ msgid "'%s' object is not subscriptable" @@ -5165,7 +5309,7 @@ msgstr "" #~ msgid "frequency can only be either 80Mhz or 160MHz" #~ msgstr "ang frequency ay dapat 80Mhz or 160MHz lamang" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "ang function ay hindi kumukuha ng mga argumento ng keyword" #~ msgid "impossible baudrate" @@ -5235,7 +5379,7 @@ msgstr "" #~ msgid "name must be a string" #~ msgstr "ang keywords dapat strings" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "name muling ginamit para sa argument" #~ msgid "no available NIC" diff --git a/locale/fr.po b/locale/fr.po index 5fb845d7896..f871c669f93 100644 --- a/locale/fr.po +++ b/locale/fr.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: 0.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-20 16:56+0000\n" -"Last-Translator: jessyjones \n" +"PO-Revision-Date: 2025-08-03 08:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.2\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" @@ -32,8 +32,7 @@ msgid "" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" "\n" -"Le code a été arrêté par l'actualisation automatique. Rechargement " -"prochain.\n" +"Code arreté par rehargement auto. Rechargement imminent.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -42,8 +41,7 @@ msgid "" "issues." msgstr "" "\n" -"Merci de créer un incident avec votre programme sur github.com/adafruit/" -"circuitpython/issues." +"Veuillez créer un incident sur github.com/adafruit/circuitpython/issues." #: supervisor/shared/safe_mode.c msgid "" @@ -51,7 +49,7 @@ msgid "" "Press reset to exit safe mode.\n" msgstr "" "\n" -"Appuyer sur reset pour sortir du mode sûr.\n" +"Appuyer sur reset pour sortir du mode sans échec.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -59,7 +57,7 @@ msgid "" "You are in safe mode because:\n" msgstr "" "\n" -"Le mode sûr est actif pour cette raison:\n" +"Le mode sans échec est actif pour cette raison:\n" #: py/obj.c msgid " File \"%q\"" @@ -91,24 +89,24 @@ msgstr "%%c nécessite un chiffre entier 'int' ou un caractère 'char'" msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" -"%d broches d'adresse, %d broches RGB et %d pour tile indique une hauteur de " -"%d, et non %d" +"%d broches d'adresse, %d broches RGB et %d pour 'tiles' indique une hauteur " +"de %d, et non %d" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" msgstr "%q et %q contiennent des broches en double" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q et %q doivent être différents" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "%q and %q must share a clock unit" -msgstr "" +msgstr "%q et %q doivent partager une unité d'horloge" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "%q cannot be changed once mode is set to %q" -msgstr "" +msgstr "%q ne peut être modifié lorsque le mode est configuré à %q" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -118,7 +116,11 @@ msgstr "%q contient des broches en double" msgid "%q failure: %d" msgstr "Échec de %q : %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q dans %q doit être du type %q ou %q, pas %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q dans %q doit être de type %q, pas %q" @@ -170,7 +172,7 @@ msgstr "La longueur de %q doit être <= %d" msgid "%q length must be >= %d" msgstr "La longueur de %q doit être >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "% déplacé de %q à %q" @@ -225,20 +227,22 @@ msgstr "%q doit être un array de type 'h'" #: shared-bindings/audiobusio/PDMIn.c msgid "%q must be multiple of 8." -msgstr "" +msgstr "%q doit être un multiple de 8." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q doit être de type %q ou %q, pas %q" #: shared-bindings/jpegio/JpegDecoder.c msgid "%q must be of type %q, %q, or %q, not %q" -msgstr "" +msgstr "%q doit être de type %q, %q ou %q, pas %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q doit être de type %q, pas %q" @@ -270,7 +274,7 @@ msgstr "le pas ne peut être zéro dans %q" #: shared-module/bitbangio/I2C.c msgid "%q too long" -msgstr "" +msgstr "%q trop long" #: py/bc.c py/objnamedtuple.c msgid "%q() takes %d positional arguments but %d were given" @@ -278,13 +282,14 @@ msgstr "%q() prend %d paramètres de position mais %d ont été donnés" #: shared-module/jpegio/JpegDecoder.c msgid "%q() without %q()" -msgstr "" +msgstr "%q() sans %q()" #: shared-bindings/usb_hid/Device.c msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, et %q doivent tous être de la même longueur" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -320,7 +325,7 @@ msgid "'%q' object does not support '%q'" msgstr "l'objet '%q' ne supporte pas '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "l'objet '%q' n'est pas un itérateur" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -328,7 +333,7 @@ msgid "'%q' object is not callable" msgstr "l'objet '%q' ne peut pas être appelé" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "l'objet '%q' n'est pas itérable" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -426,7 +431,7 @@ msgstr "'data' nécessite au moins 2 paramètres" #: py/compile.c msgid "'data' requires integer arguments" -msgstr "'data' nécessite des paramètre de chiffres entiers" +msgstr "'data' nécessite des paramètre de types entiers" #: py/compile.c msgid "'label' requires 1 argument" @@ -434,7 +439,7 @@ msgstr "'label' nécessite 1 paramètre" #: py/emitnative.c msgid "'not' not implemented" -msgstr "" +msgstr "'not' n'est pas implémenté" #: py/compile.c msgid "'return' outside function" @@ -463,9 +468,8 @@ msgstr ", dans %q\n" #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c -#, fuzzy msgid ".show(x) removed. Use .root_group = x" -msgstr ".show(x) n'est plus disponible. Merci d'utiliser .root_group = x" +msgstr ".show(x) retiré. Utilisez .root_group = x" #: py/objcomplex.c msgid "0.0 to a complex power" @@ -477,7 +481,7 @@ msgstr "pow() non supporté avec 3 paramètres" #: ports/raspberrypi/common-hal/wifi/Radio.c msgid "AP could not be started" -msgstr "Le point d'accès n'a pas pu être démarré" +msgstr "Le point d'accès AP n'a pas pu être démarré" #: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c #, c-format @@ -508,7 +512,7 @@ msgstr "Tous les périphériques I2C sont utilisés" #: ports/espressif/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "All RX FIFOs in use" -msgstr "Tout les RX FIFOs sont utilisé" +msgstr "Tout les RX FIFOs sont utilisés" #: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c msgid "All SPI peripherals are in use" @@ -526,7 +530,7 @@ msgstr "Tout les canaux sont utilisés" #: ports/raspberrypi/common-hal/usb_host/Port.c msgid "All dma channels in use" -msgstr "Toutes les canals DMA sont utilisées" +msgstr "Tout les canaux DMA sont utilisés" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "All event channels in use" @@ -556,7 +560,6 @@ msgstr "Tous les minuteurs pour cette broche sont utilisés" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Tous les minuteurs sont utilisés" @@ -569,6 +572,10 @@ msgstr "S'annonce déjà." msgid "Already have all-matches listener" msgstr "Il y a déjà un auditeur all-matches" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Déjà en cours" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -578,8 +585,9 @@ msgstr "Déjà en cours d'exécution" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" -msgstr "Déjà à la recherche des réseaux wifi" +msgstr "Déjà à la recherche des réseaux WiFi" #: shared-module/os/getenv.c #, c-format @@ -602,7 +610,11 @@ msgstr "L'array doit contenir des demi-mots (type 'H')" #: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c #: shared-bindings/nvm/ByteArray.c msgid "Array values should be single bytes." -msgstr "Les valeurs de l'array doivent être des octets singuliers." +msgstr "Les valeurs du tableau doivent être constituées d'un seul octet." + +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "Transfert Async SPI sur ce bus en cours, patientez." #: shared-module/memorymonitor/AllocationAlarm.c #, c-format @@ -613,6 +625,11 @@ msgstr "Tentative d'allocation de %d blocs" msgid "Audio conversion not implemented" msgstr "La conversion audio n'est pas implémentée" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Erreur source audio" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN n'est pas utilisé avec un mot de passe" @@ -630,8 +647,8 @@ msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -"Auto-chargement activé. Copiez ou sauvegardez les fichiers via USB pour les " -"lancer ou démarrez le REPL pour le désactiver.\n" +"Auto-chargement activé. Sauvegardez les fichiers via USB pour les lancer ou " +"démarrez le REPL pour le désactiver.\n" #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" @@ -688,7 +705,7 @@ msgstr "La longueur du tampon %d est trop grande. Il doit être inférieur à %d #: shared-module/sdcardio/SDCard.c #, c-format msgid "Buffer must be a multiple of %d bytes" -msgstr "" +msgstr "Tampon doit être un multiple de %d octets" #: shared-bindings/_bleio/PacketBuffer.c #, c-format @@ -700,7 +717,7 @@ msgstr "Tampon trop court de %d octets" #: shared-bindings/framebufferio/FramebufferDisplay.c #: shared-bindings/struct/__init__.c shared-module/struct/__init__.c msgid "Buffer too small" -msgstr "Tampon trop court" +msgstr "Tampon trop petit" #: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c #: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c @@ -741,19 +758,24 @@ msgstr "L'alarme ne peut être que sur TRC IO depuis un sommeil profond." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" -"L'alarme peut seulement être sur une broche basse tandis que d'autres " -"alarment sont sur des broches hautes depuis le sommeil profond." +"Ne peut déclencher l'alarme que sur une broche en état bas tandis que les " +"autres déclenchent l'alarme sur une broche à l'état haut à partir du sommeil " +"profond." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Can only alarm on two low pins from deep sleep." msgstr "" -"L'alarme peut seulement être sur deux broches basses depuis le sommeil " -"profond." +"Peut uniquement déclencher une alarme à partir de deux broches configurées " +"en niveau bas depuis le mode de sommeil profond." + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "Impossible de construire AudioOut , le canal est déja ouvert" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" -msgstr "Impossible de définir CCCD sur une caractéristique locale" +msgstr "Impossible de définir BLE CCCD sur une caractéristique locale" #: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c #: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c @@ -764,7 +786,8 @@ msgstr "Impossible de changer de périphérique USB maintenant" #: shared-bindings/_bleio/Adapter.c msgid "Cannot create a new Adapter; use _bleio.adapter;" msgstr "" -"Un nouveau Adapter ne peut être créé ; Adapter; utilisez _bleio.adapter;" +"Impossible de créer un nouvel adaptateur ; utilisez l'adaptateur existant " +"via _bleio.adapter. ;" #: shared-bindings/displayio/Bitmap.c #: shared-bindings/memorymonitor/AllocationSize.c @@ -777,7 +800,8 @@ msgstr "Impossible de supprimer les valeurs" #: ports/nordic/common-hal/digitalio/DigitalInOut.c #: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c msgid "Cannot get pull while in output mode" -msgstr "Ne peut être tiré ('pull') en mode sortie ('output')" +msgstr "" +"Une GPIO ne peut être en mode ('pull') si déja en mode de sortie ('output')" #: ports/nordic/common-hal/microcontroller/Processor.c msgid "Cannot get temperature" @@ -786,25 +810,25 @@ msgstr "Impossible de lire la température" #: shared-bindings/_bleio/Adapter.c msgid "Cannot have scan responses for extended, connectable advertisements." msgstr "" -"Impossible d'avoir des réponses d'analyse pour les publicités étendues et " -"connectables." +"Les publicités BLE étendues et connectables ne peuvent pas inclure de " +"réponses au scan." #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot pull on input-only pin." -msgstr "Ne peut tirer ('pull') sur une broche d'entrée ('input') seule." +msgstr "Ne peut tirer ('pull') sur une broche d'entrée ('input') ." #: shared-bindings/audiobusio/PDMIn.c msgid "Cannot record to a file" msgstr "Impossible d'enregistrer vers un fichier" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "Ne peut démonter '/' quand est visible par USB." +msgid "Cannot remount path when visible via USB." +msgstr "" +"Impossible de remonter le chemin d'accès lorsqu'il est visible via USB." #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." -msgstr "" -"Impossible d'affecter une valeur quand la direction est entrante ('input')." +msgstr "Impossible d'affecter une valeur quand le GPIO est entrant ('input')." #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -813,18 +837,21 @@ msgstr "Impossible de spécifier RTS ou CTS en mode RS485" #: py/objslice.c msgid "Cannot subclass slice" -msgstr "On ne peut faire de sous-classes de tranches" +msgstr "On ne peut faire des tranches de sous-classes" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "" +"Impossible d'utiliser en même temps les GPIO 0 à 15 et les GPIO 32 à 45" #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "" -"Impossible de réveiller via une bordure d'une broche, seulement via un niveau" +"Impossible de réveiller par une broche , seulement via un changement d'état" #: ports/espressif/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge. Only level." -msgstr "" -"Impossible de réveiller via une bordure d'une broche. Seulement via un " -"niveau." +msgstr "Impossible de réveiller via une broche. Seulement via un niveau." #: shared-bindings/_bleio/CharacteristicBuffer.c msgid "CharacteristicBuffer writing not provided" @@ -832,11 +859,11 @@ msgstr "Ecriture sur 'CharacteristicBuffer' non fournie" #: supervisor/shared/safe_mode.c msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "Le code principal de CircuitPython s'est complètement planté. Oups !\n" +msgstr "Le noyau CircuitPython est planté !\n" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Clock unit in use" -msgstr "Horloge en cours d'utilisation" +msgstr "Horloge en fonction" #: shared-bindings/_bleio/Connection.c msgid "" @@ -852,27 +879,36 @@ msgstr "Les tableaux de coordonnées sont de longueur différentes" #: shared-bindings/bitmaptools/__init__.c msgid "Coordinate arrays types have different sizes" -msgstr "Les types des matrices de coordonnées sont de longueur différentes" +msgstr "Les types des tableaux de coordonnées sont de longueur différentes" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "Ne peut publier sur le Topic ROS" #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" -msgstr "Impossible de définir l'adresse" +msgstr "Ne peux définir l'adresse" #: ports/stm/common-hal/busio/UART.c msgid "Could not start interrupt, RX busy" -msgstr "Impossible de démarrer l'interruption, RX occupé" +msgstr "Ne peux lancer l'interruption, RX occupé" #: shared-module/audiomp3/MP3Decoder.c msgid "Couldn't allocate decoder" -msgstr "Impossible d'allouer le décodeur" +msgstr "Ne peux allouer le décodeur" + +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "Erreur critique lors du reboot à chaud, reset requis: %d" #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" -msgstr "Erreur d'initialisation du canal DAC" +msgstr "Erreur init du canal DAC" #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Device Init Error" -msgstr "Erreur d'initialisation du périphérique DAC" +msgstr "Erreur init périphérique DAC" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "DAC already in use" @@ -883,36 +919,33 @@ msgstr "DAC déjà utilisé" msgid "Data 0 pin must be byte aligned" msgstr "La broche 'Data 0' doit être aligné sur l'octet" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Un bloc de données doit suivre un bloc fmt" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" -msgstr "" +msgstr "Erreur de format de données (endommagées)" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Data not supported with directed advertising" -msgstr "Les données ne sont pas supportées avec les annonces directes" +msgstr "Données non supportées avec les annonces directes" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Data too large for advertisement packet" -msgstr "Données trop volumineuses pour un paquet d'avertissement" +msgstr "Données trop grandes pour un paquet d'avertissement" #: ports/stm/common-hal/alarm/pin/PinAlarm.c msgid "Deep sleep pins must use a rising edge with pulldown" msgstr "" -"Les broches de sommeil profond doivent utiliser un montant avec un pulldown" +"Les broches de sommeil profond doivent utiliser un front montant avec " +"pulldown" #: shared-bindings/audiobusio/PDMIn.c msgid "Destination capacity is smaller than destination_length." -msgstr "La capacité de destination est plus petite que 'destination_length'." +msgstr "La capacité de destination est inférieure à 'destination_length'." #: shared-module/jpegio/JpegDecoder.c msgid "Device error or wrong termination of input stream" -msgstr "" +msgstr "Erreur de l'appareil ou terminaison incorrecte du flux d'entrée" #: ports/nordic/common-hal/audiobusio/I2SOut.c msgid "Device in use" @@ -921,13 +954,13 @@ msgstr "Appareil utilisé" #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display must have a 16 bit colorspace." -msgstr "L'affichage doit avoir un espace colorimétrique de 16 bits." +msgstr "L'affichage requier un espace colorimétrique de 16 bits." #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c msgid "Display rotation must be in 90 degree increments" -msgstr "La rotation d'affichage doit se faire par incréments de 90 degrés" +msgstr "La rotation d'affichage se fait par incréments de 90 degrés" #: main.c msgid "Done" @@ -935,12 +968,11 @@ msgstr "Terminé" #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." -msgstr "" -"Le mode Drive n'est pas utilisé quand la direction est entrante ('input')." +msgstr "Le mode Drive n'est pas utilisé en entrant ('input')." #: py/obj.c msgid "During handling of the above exception, another exception occurred:" -msgstr "Pendant la gestion de cette exception, un autre s'est produite:" +msgstr "Durant la gestion de cette exception, une autre s'est produite:" #: shared-bindings/aesio/aes.c msgid "ECB only operates on 16 bytes at a time" @@ -971,7 +1003,7 @@ msgstr "" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "FFT is defined for ndarrays only" -msgstr "La FFT est définie uniquement pour les ndarrays" +msgstr "La FFT n'est définie que pour les ndarrays" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "FFT is implemented for linear arrays only" @@ -979,7 +1011,7 @@ msgstr "FFT n'est implémenté que pour les arrays linéaires" #: shared-bindings/ps2io/Ps2.c msgid "Failed sending command." -msgstr "Échec de l'envoi de la commande." +msgstr "Échec envoi de la commande." #: ports/nordic/sd_mutex.c #, c-format @@ -994,8 +1026,8 @@ msgstr "Echec de l'ajout de l'enregistrement TXT" msgid "" "Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -"Echec de l'ajout de l'enregistrement TXT; caractères non-octets ni texte " -"trouvés dans txt_records" +"Echec d'enregistrement TXT; caractères mal formatés type string ou octets " +"dans txt_records" #: shared-module/rgbmatrix/RGBMatrix.c msgid "Failed to allocate %q buffer" @@ -1003,33 +1035,65 @@ msgstr "Échec d'allocation du tampon %q" #: ports/espressif/common-hal/wifi/__init__.c msgid "Failed to allocate Wifi memory" -msgstr "Impossible d'allouer la mémoire pour Wifi" +msgstr "Echec allocation mémoire pour Wifi" #: ports/espressif/common-hal/wifi/ScannedNetworks.c msgid "Failed to allocate wifi scan memory" -msgstr "Impossible d'allouer la mémoire pour le scan wifi" +msgstr "Scan wifi: échec allocation mémoire" #: ports/stm/common-hal/audiopwmio/PWMAudioOut.c msgid "Failed to buffer the sample" -msgstr "Échec du tamponage de l'échantillon" +msgstr "Échec du tampon de l'échantillon" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Failed to connect: internal error" -msgstr "Impossible de se connecter : erreur interne" +msgstr "Connection impossible: erreur interne" #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Failed to connect: timeout" -msgstr "Impossible de se connecter: délai dépassé" +msgstr "Connection impossible: délai dépassé" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "Échec de la création de canaux continus : argument invalide" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "Échec de la création de canaux continus : état invalide" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Échec de la création de canaux continus : pas de mémoire" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Échec de la création de canaux continus : introuvable" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Impossible d'activer les canaux continus" #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" -msgstr "Impossible d'analyser le fichier MP3" +msgstr "Echec de parcours du fichier MP3" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Impossible d'enregistrer les 'events callback' des canaux continus" #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" -msgstr "Impossible de libérer mutex, err 0x%04x" +msgstr "Écchec de liberaton du mutex, err 0x%04x" + +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "hostname impossible à initialiser" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Impossible de lancer async audio" #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." @@ -1039,41 +1103,43 @@ msgstr "Échec de l'écriture vers flash interne." msgid "File exists" msgstr "Le fichier existe" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "Fichier non trouvé" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Filtres trop complexe" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is duplicate" -msgstr "Le logiciel est identique" +msgstr "Le Firmware est identique" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is invalid" -msgstr "Logiciel invalide" +msgstr "Firmware invalide" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is too big" -msgstr "Logiciel trop volumineux" +msgstr "Firmware trop grand" #: shared-bindings/bitmaptools/__init__.c msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" -"Avec l'espace de couleur L8, l'image d'entrée doit avoir 8 bits par pixel" +"Pour l'espace de couleur L8, l'image bitmap doit avoir 8 bits par pixel" #: shared-bindings/bitmaptools/__init__.c msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -"Avec l'espace de couleur RVB, l'image d'entrée doit avoir 16 bits par pixel" +"Pour l'espace de couleur RVB, l'image d'entrée doit avoir 16 bits par pixel" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" -msgstr "Format non pris en charge" +msgstr "Format non supporté" #: ports/mimxrt10xx/common-hal/microcontroller/Processor.c msgid "" @@ -1085,7 +1151,7 @@ msgstr "" #: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c #: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c msgid "Function requires lock" -msgstr "La fonction nécessite un verrou ('lock')" +msgstr "La fonction requier un verrou ('lock')" #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" @@ -1139,13 +1205,13 @@ msgstr "Taille de tampon incorrecte" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Init program size invalid" -msgstr "Taille du programme d'initialisation non valide" +msgstr "Taille du programme d'initialisation invalide" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Initial set pin direction conflicts with initial out pin direction" msgstr "" -"Direction initiale de \"set pin\" est en conflit avec la direction initiale " -"de \"out pin\"" +"Direction initiale de \"set pin\" est en conflit avec la direction de \"out " +"pin\"" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Initial set pin state conflicts with initial out pin state" @@ -1156,8 +1222,7 @@ msgstr "" #, c-format msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" msgstr "" -"La taille (%d) du tampon d'entrée doit être un multiple du nombre (%d) de " -"brins" +"La taille (%d) du tampon d'entrée doit être au modulo du nombre (%d) de brins" #: ports/atmel-samd/common-hal/pulseio/PulseIn.c msgid "Input taking too long" @@ -1179,13 +1244,14 @@ msgstr "Chiffrement insuffisant" #: shared-module/jpegio/JpegDecoder.c msgid "Insufficient memory pool for the image" -msgstr "" +msgstr "Le pool de mémoire est insuffisant pour l'image" #: shared-module/jpegio/JpegDecoder.c msgid "Insufficient stream input buffer" -msgstr "" +msgstr "Tampon de flux d'entrée insuffisant" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "L'interface doit être lancée" @@ -1217,7 +1283,7 @@ msgstr "Erreur interne #%d" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-bindings/pwmio/PWMOut.c msgid "Internal resource(s) in use" -msgstr "" +msgstr "Ressource(s) interne(s) en utilisation" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." @@ -1229,7 +1295,7 @@ msgstr "Erreur d'interruption." #: shared-module/jpegio/JpegDecoder.c msgid "Interrupted by output function" -msgstr "" +msgstr "Interrompu par la fonction de sortie" #: ports/espressif/common-hal/_bleio/Service.c #: ports/espressif/common-hal/espulp/ULP.c @@ -1241,14 +1307,16 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "%q invalide" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-module/aurora_epaper/aurora_framebuffer.c msgid "Invalid %q and %q" -msgstr "" +msgstr "%q et %q invalides" #: ports/atmel-samd/common-hal/microcontroller/Pin.c #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c @@ -1259,7 +1327,7 @@ msgstr "Broche invalide pour '%q'" #: ports/stm/common-hal/analogio/AnalogIn.c msgid "Invalid ADC Unit value" -msgstr "Valeur d'unité ADC non valide" +msgstr "Unité invalide pour l'ADC" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c @@ -1274,13 +1342,17 @@ msgstr "BSSID invalide" msgid "Invalid MAC address" msgstr "Adresse MAC invalide" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "ROS domain ID invalide" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Paramètre invalide" #: shared-module/displayio/Bitmap.c msgid "Invalid bits per value" -msgstr "Bits par valeur invalides" +msgstr "Bits invalides par valeur" #: shared-module/os/getenv.c #, c-format @@ -1298,15 +1370,16 @@ msgstr "Format invalide" #: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" -msgstr "Taille de bloc de formatage invalide" +msgstr "Formatage de bloc invalide" #: shared-bindings/wifi/Radio.c msgid "Invalid hex password" -msgstr "Mot de passe hexadécimal invalide" +msgstr "Mot de passe hexa invalide" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" -msgstr "Adresse MAC multicast invalide" +msgstr "MAC address multicast invalide" #: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" @@ -1314,9 +1387,10 @@ msgstr "Taille invalide" #: shared-module/ssl/SSLSocket.c msgid "Invalid socket for TLS" -msgstr "Socket non valide pour TLS" +msgstr "Socket invalide pour TLS" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "État invalide" @@ -1346,20 +1420,25 @@ msgstr "Ce calque est déjà dans un groupe" #: shared-module/displayio/Group.c msgid "Layer must be a Group or TileGrid subclass" -msgstr "Le calque doit être une sous-classe de Group ou TileGrid" +msgstr "La couche doit être une sous-classe de Group ou TileGrid" #: shared-bindings/audiocore/RawSample.c msgid "Length of %q must be an even multiple of channel_count * type_size" -msgstr "" +msgstr "Longueur de %q doit être un multiple pair de channel_count * type_size" #: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" -msgstr "Adresse physique (MAC) invalide" +msgstr "MAC Address invalide" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/espressif/common-hal/_bleio/Descriptor.c msgid "MITM security not supported" -msgstr "" +msgstr "Sécurité MITM n'est pas supportée" + +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "Erreur d'horloge MMC/SDIO %x" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" @@ -1368,7 +1447,7 @@ msgstr "Le mapping doit être un tuple" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched data size" -msgstr "La taille des données ne correspond pas" +msgstr "Non correspondance de la taille des données" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Mismatched swap flag" @@ -1408,32 +1487,33 @@ msgstr "" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "Missing jmp_pin. %q[%u] jumps on pin" -msgstr "" +msgstr "Manque jmp_pin. %q[%u] passe à la broche suivante" #: shared-module/storage/__init__.c msgid "Mount point directory missing" -msgstr "" +msgstr "Point de montage manquant" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Doit être une sous-classe de %q." #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c msgid "Must provide 5/6/5 RGB pins" -msgstr "5/6/5 broches RGB doivent être fournies" +msgstr "broches RGB 5/6/5 requises" #: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c msgid "Must provide MISO or MOSI pin" -msgstr "Doit fournir une broche MISO ou MOSI" +msgstr "Fournir broches MISO ou MOSI" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "Must use a multiple of 6 rgb pins, not %d" -msgstr "Doit utiliser un multiple de 6 broches RVB, pas %d" +msgstr "Demande un multiple de 6 broches RVB, pas %d" #: supervisor/shared/safe_mode.c msgid "NLR jump failed. Likely memory corruption." -msgstr "Saut NLR échoué. Corruption de mémoire probable." +msgstr "Echec saut NLR . Mémoire probablement corompue." #: ports/espressif/common-hal/nvm/ByteArray.c msgid "NVS Error" @@ -1445,12 +1525,11 @@ msgstr "Nom ou service inconnu" #: shared-bindings/displayio/TileGrid.c msgid "New bitmap must be same size as old bitmap" -msgstr "La taille du nouveau bitmap doit être la même que l'ancien" +msgstr "La taille du nouveau bitmap doit être indentique à l'ancien" #: ports/espressif/common-hal/_bleio/__init__.c -#, fuzzy msgid "Nimble out of memory" -msgstr "Nimble n'a plus de mémoire" +msgstr "Mémoire nimble épuisée" #: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/SPI.c @@ -1481,30 +1560,30 @@ msgstr "Pas de DAC sur la puce" #: ports/raspberrypi/common-hal/audiobusio/I2SOut.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA channel found" -msgstr "Aucun canal DMA trouvé" +msgstr "Pas de canal DMA trouvé" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "No DMA pacing timer found" -msgstr "Aucun minuteur de rythme DMA trouvé" +msgstr "Aucun temporisateur de régulation DMA trouvé" #: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c #, c-format msgid "No I2C device at address: 0x%x" -msgstr "Aucun périphérique I2S à l'adresse : 0x%x" +msgstr "Pas de périphérique I2S à l'adresse : 0x%x" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "Aucune IP" +msgstr "Pas d' IP" #: ports/atmel-samd/common-hal/microcontroller/__init__.c #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "No bootloader present" -msgstr "" +msgstr "Aucun bootloader présent" #: shared-module/usb/core/Device.c msgid "No configuration set" -msgstr "Pas de configuration définie" +msgstr "Aucune configuration" #: shared-bindings/_bleio/PacketBuffer.c msgid "No connection: length cannot be determined" @@ -1518,23 +1597,23 @@ msgstr "Pas de bus %q par défaut" #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/atmel-samd/common-hal/touchio/TouchIn.c msgid "No free GCLKs" -msgstr "Pas de GCLK libre" +msgstr "Aucun GCLK libre" #: shared-bindings/os/__init__.c msgid "No hardware random available" -msgstr "Aucunes source de valeurs aléatoire matérielle disponible" +msgstr "Aucune source matérielle de valeurs aléatoires disponible" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "No in in program" -msgstr "Programme n'a pas de \"in\"" +msgstr "Programme sans \"in\"" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "No in or out in program" -msgstr "Programme n'a aucun \"in\" ni \"out\"" +msgstr "Programme sans \"in\" ni \"out\"" #: py/objint.c shared-bindings/time/__init__.c msgid "No long integer support" -msgstr "Pas de support pour chiffre entier long" +msgstr "Pas de support pour les entiers longs" #: shared-bindings/wifi/Radio.c msgid "No network with that ssid" @@ -1553,15 +1632,19 @@ msgstr "Aucun pull up trouvé sur SDA ou SCL; vérifiez votre câblage" #: shared-module/touchio/TouchIn.c msgid "No pulldown on pin; 1Mohm recommended" -msgstr "Pas de pulldown sur la broche ; 1Mohm recommandé" +msgstr "Pas de pulldown sur la broche ; 1Mohm requis" + +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "Pas de pullup sur la broche ; 1Mohm recommandé" #: py/moderrno.c msgid "No space left on device" -msgstr "Aucun espace libre sur le dispositif" +msgstr "Plus d'espace libre sur le dispositif" #: py/moderrno.c msgid "No such device" -msgstr "Aucun périphérique correspondant" +msgstr "Périphérique introuvable" #: py/moderrno.c msgid "No such file/directory" @@ -1577,7 +1660,7 @@ msgstr "Pas de port usb hôte initialisé" #: ports/nordic/common-hal/_bleio/__init__.c msgid "Nordic system firmware out of memory" -msgstr "Logiciel système Nordic n'a plus de mémoire" +msgstr "Firmware Nordic : mémoire insuffisante" #: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c msgid "Not a valid IP string" @@ -1596,20 +1679,18 @@ msgstr "Ne joue pas" #: shared-module/jpegio/JpegDecoder.c msgid "Not supported JPEG standard" -msgstr "" +msgstr "Standard JPEG non supporté" #: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c #: ports/espressif/common-hal/sdioio/SDCard.c #, c-format msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +msgstr "Nombre de data_pins doit être %d ou %d, pas %d" #: shared-bindings/util.c msgid "" "Object has been deinitialized and can no longer be used. Create a new object." -msgstr "" -"L'objet a été dés-initialisé et ne peut plus être utilisé. Créez un nouvel " -"objet." +msgstr "Objet désinitialisé et inutilisable. Créez-en un nouveau." #: ports/nordic/common-hal/busio/UART.c msgid "Odd parity is not supported" @@ -1628,23 +1709,24 @@ msgstr "OK" #, c-format msgid "Only 8 or 16 bit mono with %dx oversampling supported." msgstr "" +"Seuls 8 ou 16 bits mono avec suréchantillonnage %dx sont pris en charge." #: ports/espressif/common-hal/wifi/__init__.c #: ports/raspberrypi/common-hal/wifi/__init__.c msgid "Only IPv4 addresses supported" -msgstr "Seulement les adresses IPv4 sont supportées" +msgstr "Seules les IPv4 sont supportées" #: ports/raspberrypi/common-hal/socketpool/Socket.c msgid "Only IPv4 sockets supported" -msgstr "Seulement les sockets IPv4 sont supportés" +msgstr "Seuls les sockets IPv4 sont supportés" #: shared-module/displayio/OnDiskBitmap.c #, c-format msgid "" "Only Windows format, uncompressed BMP supported: given header size is %d" msgstr "" -"Seulement le format BMP Windows, non compressé est supporté : la taille de " -"l'entête fournie est %d" +"Seul le format BMP Windows, non compressé est supporté : taille de l'entête " +"fournie est %d" #: shared-bindings/_bleio/Adapter.c msgid "Only connectable advertisements can be directed" @@ -1656,20 +1738,11 @@ msgstr "Seule la détection des bords est disponible sur ce matériel" #: shared-bindings/ipaddress/__init__.c msgid "Only int or string supported for ip" -msgstr "Seulement les int et string sont supportés pour une adresse IP" - -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Seulement les BMP monochromes, 4 bpp ou 8 bpp, ou 16 bpp et plus sont " -"supportés: %d bpp fournis" +msgstr "Seul les types entiers et string sont utilisés pour une adresse IP" #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." -msgstr "Une seul %q autorisée en sommeil profond." +msgstr "Une seul %q est autorisée en sommeil profond." #: ports/espressif/common-hal/espulp/ULPAlarm.c msgid "Only one %q can be set." @@ -1684,12 +1757,12 @@ msgstr "Seulement une adresse est autorisée" #: ports/nordic/common-hal/alarm/time/TimeAlarm.c #: ports/stm/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set" -msgstr "Seule une alarme alarm.time peut être définie" +msgstr "Une seule alarm.time peut être définie" #: ports/espressif/common-hal/alarm/time/TimeAlarm.c #: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c msgid "Only one alarm.time alarm can be set." -msgstr "Seulement une alarme alarm.time peut être réglée." +msgstr "Une seule alarm.time peut être réglée." #: shared-module/displayio/ColorConverter.c msgid "Only one color can be transparent at a time" @@ -1717,8 +1790,9 @@ msgstr "Mémoire insuffisante" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" -msgstr "Plus de sockets" +msgstr "Plus de sockets disponibles" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c msgid "Out-buffer elements must be <= 4 bytes long" @@ -1736,9 +1810,13 @@ msgstr "PWM slice déja utilisée" msgid "PWM slice channel A already in use" msgstr "Canal A de PWM slice est utilisé" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "Les packets du buffer SPI transfert doivent être de la même taille." + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" -msgstr "" +msgstr "Erreur de paramètre" #: ports/espressif/common-hal/audiobusio/__init__.c msgid "Peripheral in use" @@ -1763,7 +1841,7 @@ msgstr "L'interruption de cette broche est déjà utilisée" #: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c msgid "Pin is input only" -msgstr "La broche est entrée uniquement" +msgstr "La broche est en entrée uniquement" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "Pin must be on PWM Channel B" @@ -1776,17 +1854,16 @@ msgid "" "bytes. If this cannot be avoided, pass allow_inefficient=True to the " "constructor" msgstr "" -"Le brochage utilise %d octets par élément, ce qui consomme plus que le %d " -"octets idéal. Si cela ne peut pas être évité, transmettez allow_inefficient " -"= True au constructeur" +"Le brochage utilise %d octets par élément, ce qui dépasse le seuil de %d " +"octets. Si cela est inévitable, passez allow_inefficient=True au constructeur" #: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c msgid "Pins must be sequential" -msgstr "Les broches doivent être séquentielles" +msgstr "Les broches doivent être consécutives" #: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c msgid "Pins must be sequential GPIO pins" -msgstr "Les broches doivent être des broches GPIO à la suite" +msgstr "Les broches doivent être des broches GPIO consécutives" #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c msgid "Pins must share PWM slice" @@ -1794,23 +1871,23 @@ msgstr "Les broches doivent partager la tranche PWM" #: shared-module/usb/core/Device.c msgid "Pipe error" -msgstr "Erreur de transfert" +msgstr "Erreur de canal" #: py/builtinhelp.c msgid "Plus any modules on the filesystem\n" -msgstr "Ainsi que tout autres modules présents sur le système de fichiers\n" +msgstr "Plus tout autres modules présents sur le système de fichiers\n" #: shared-module/vectorio/Polygon.c msgid "Polygon needs at least 3 points" -msgstr "Polygon a besoin d'au moins 3 points" +msgstr "Un polygone a besoin d'au moins 3 points" #: supervisor/shared/safe_mode.c msgid "Power dipped. Make sure you are providing enough power." -msgstr "Chute de puissance. Assurez-vous de fournir suffisament de puissance." +msgstr "Chute de puissance. Assurez-vous de fournir assez de puissance." #: shared-bindings/_bleio/Adapter.c msgid "Prefix buffer must be on the heap" -msgstr "Le tampon de préfixe doit être sur la pile" +msgstr "Le tampon de préfixe doit être sur le tas" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" @@ -1840,9 +1917,14 @@ msgstr "Taille du programme invalide" msgid "Program too long" msgstr "Programme trop long" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "Les Publishers ne peuvent être créés qu'à partir du nœud parent" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." -msgstr "Le tirage 'pull' n'est pas utilisé quand la direction est 'output'." +msgstr "" +"L'attribut \"pull\" n'est pas utilisé quand la direction est \"output\"." #: ports/raspberrypi/common-hal/countio/Counter.c msgid "RISE_AND_FALL not available on this chip" @@ -1850,7 +1932,7 @@ msgstr "RISE_AND_FALL n'est pas disponible sur cette puce" #: shared-module/displayio/OnDiskBitmap.c msgid "RLE-compressed BMP not supported" -msgstr "" +msgstr "BMP avec compression RLE non supporté" #: ports/stm/common-hal/os/__init__.c msgid "RNG DeInit Error" @@ -1860,6 +1942,26 @@ msgstr "Erreur de désinitialisation du RNG" msgid "RNG Init Error" msgstr "Erreur d'initialisation du RNG" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "L'agent est-il connecté? ROS échoue son initialisation" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "ROS échec de configuration interne" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "Erreur d'allocation mémoire ROS" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "ROS node échoue a s'initialiser" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "Le topic ROS échoue à s'initialiser" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1903,7 +2005,7 @@ msgstr "Rafraîchissement trop tôt" #: shared-bindings/canio/RemoteTransmissionRequest.c msgid "RemoteTransmissionRequests limited to 8 bytes" -msgstr "RemoteTransmissionRequests limité à 8 octets" +msgstr "Le RemoteTransmissionRequests est limité à 8 octets" #: shared-bindings/aesio/aes.c msgid "Requested AES mode is unsupported" @@ -1911,7 +2013,7 @@ msgstr "Le mode AES demandé n'est pas supporté" #: ports/espressif/common-hal/espidf/__init__.c msgid "Requested resource not found" -msgstr "Resource demandée non trouvée" +msgstr "Ressource demandée non trouvée" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "Right channel unsupported" @@ -1919,11 +2021,11 @@ msgstr "Canal droit non supporté" #: shared-module/jpegio/JpegDecoder.c msgid "Right format but not supported" -msgstr "" +msgstr "Format correct mais non supporté" #: main.c msgid "Running in safe mode! Not running saved code.\n" -msgstr "Mode sans-échec ! Le code sauvegardé n'est pas éxecuté.\n" +msgstr "Mode sans échec ! Le code sauvegardé n'est pas éxecuté.\n" #: shared-module/sdcardio/SDCard.c msgid "SD card CSD format not supported" @@ -1942,7 +2044,7 @@ msgstr "Erreur de SDIO GetCardInfo %d" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO Init Error %x" -msgstr "" +msgstr "Erreur d'initialisation SDIO %x" #: ports/espressif/common-hal/busio/SPI.c msgid "SPI configuration failed" @@ -1962,12 +2064,12 @@ msgstr "Ré-initialisation du SPI" #: shared-bindings/is31fl3741/FrameBuffer.c msgid "Scale dimensions must divide by 3" -msgstr "La dimension d'échelle doit être un multiple de 3" +msgstr "Les dimensions de l'échelle doivent être un multiple de 3" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c msgid "Scan already in progress. Stop with stop_scan." -msgstr "Scan déjà en cours. Arrêtez-le avec stop_scan." +msgstr "Scan en cours. Arrêtez-le avec stop_scan." #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -1976,7 +2078,7 @@ msgstr "Sérialiseur en cours d'utilisation" #: shared-bindings/ssl/SSLContext.c msgid "Server side context cannot have hostname" -msgstr "Un contexte niveau serveur ne peut avoir de hostname" +msgstr "Un contexte serveur ne peut pas posséder de nom d'hôte" #: ports/cxd56/common-hal/camera/Camera.c msgid "Size not supported" @@ -1991,11 +2093,13 @@ msgstr "Tranche et valeur de tailles différentes." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Tranches non supportées" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool ne s'utilise qu'avec wifi.radio" @@ -2009,11 +2113,11 @@ msgstr "Spécifiez une unique broche parmi data0 ou data_pins" #: supervisor/shared/safe_mode.c msgid "Stack overflow. Increase stack size." -msgstr "" +msgstr "Débordement de pile. Augmentez la taille de pile." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" -msgstr "Fournissez l'un de monotonic_time ou epoch_time" +msgstr "Fournir l'un des éléments : monotonic_time ou epoch_time" #: shared-bindings/gnss/GNSS.c msgid "System entry must be gnss.SatelliteSystem" @@ -2025,7 +2129,8 @@ msgstr "Délais de lecture de température dépassée" #: supervisor/shared/safe_mode.c msgid "The `microcontroller` module was used to boot into safe mode." -msgstr "Le module microcontroller a été utilisé pour démarrer en mode sûr." +msgstr "" +"Le module microcontroller a été utilisé pour démarrer en mode sans échec." #: py/obj.c msgid "The above exception was the direct cause of the following exception:" @@ -2035,22 +2140,9 @@ msgstr "L'exception précédente est la cause directe de l'exception suivante:" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "La taille de rgb_pins doit être 6, 12, 18, 24 ou 30" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" -"Le 'bits_per_sample' de l'échantillon ne correspond pas à celui du mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Le canal de l'échantillon ne correspond pas à celui du mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "L'échantillonage de l'échantillon ne correspond pas à celui du mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "Le %q de l'échantillon ne concorde pas" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2072,7 +2164,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "La hauteur de la tuile doit diviser exactement la hauteur de l'image" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Index des tuiles hors limites" @@ -2080,6 +2174,10 @@ msgstr "Index des tuiles hors limites" msgid "Tile width must exactly divide bitmap width" msgstr "La largeur de la tuile doit diviser exactement la largeur de l'image" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "TilePaletteMapper ne peut être lié à un TileGrid qu'une seule fois" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "L'heure est dans le passé." @@ -2088,7 +2186,7 @@ msgstr "L'heure est dans le passé." #: ports/nordic/common-hal/_bleio/Adapter.c #, c-format msgid "Timeout is too long: Maximum timeout length is %d seconds" -msgstr "Le délai est trop long : le délai maximal est de %d secondes" +msgstr "Délai trop long : le délai maximal est de %d secondes" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "Too many channels in sample" @@ -2100,7 +2198,7 @@ msgstr "Trop de canaux dans l'échantillon." #: ports/espressif/common-hal/_bleio/Characteristic.c msgid "Too many descriptors" -msgstr "" +msgstr "Trop de descripteurs" #: shared-module/displayio/__init__.c msgid "Too many display busses; forgot displayio.release_displays() ?" @@ -2155,11 +2253,13 @@ msgstr "L'USB est occupé" #: supervisor/shared/safe_mode.c msgid "USB devices need more endpoints than are available." -msgstr "Les appareils USB nécessitent plus de connexions que disponibles." +msgstr "" +"Les périphériques USB nécessitent plus de points de terminaison que ceux " +"disponibles." #: supervisor/shared/safe_mode.c msgid "USB devices specify too many interface names." -msgstr "Les appareils USB spécifient trop de noms d'interface." +msgstr "Les appareils USB donnent trop de noms d'interface." #: shared-module/usb_hid/Device.c msgid "USB error" @@ -2193,7 +2293,7 @@ msgstr "Impossible d'allouer des tampons pour une conversion signée" #: supervisor/shared/safe_mode.c msgid "Unable to allocate to the heap." -msgstr "" +msgstr "Impossible d'allouer sur le tas." #: ports/espressif/common-hal/busio/I2C.c msgid "Unable to create lock" @@ -2213,6 +2313,10 @@ msgstr "Impossible d'initialiser le parser" msgid "Unable to read color palette data" msgstr "Impossible de lire les données de la palette de couleurs" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "Echec envoit message CAN:tous les buffer TX sont occupés" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2308,22 +2412,19 @@ msgstr "Espace de couleur non supporté" msgid "Unsupported display bus type" msgstr "Type de bus d'affichage non supporté" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Format non pris en charge" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "Algorithme de hachage non supporté" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" -msgstr "" +msgstr "Type de socket non supporté" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update failed" -msgstr "" +msgstr "Échec de mise à jour" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c @@ -2339,7 +2440,7 @@ msgstr "Longueur de la valeur > max_length" #: ports/espressif/common-hal/espidf/__init__.c msgid "Version was invalid" -msgstr "Version est invalide" +msgstr "La version est invalide" #: ports/stm/common-hal/microcontroller/Processor.c msgid "Voltage read timed out" @@ -2351,9 +2452,7 @@ msgstr "ATTENTION : le nom de fichier de votre code a deux extensions\n" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" -msgstr "" -"WatchDogTimer ne peut pas être dés-initialisé une fois que le mode est réglé " -"sur RESET" +msgstr "Le WatchDogTimer ne peut pas être réinitialisé une fois en mode RESET" #: py/builtinhelp.c #, c-format @@ -2374,9 +2473,11 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi : " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "Le wifi n'est pas activé" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "Le WiFi n'est pas activé" #: main.c msgid "Woken up by alarm.\n" @@ -2392,14 +2493,15 @@ msgstr "Écritures non supporté vers les Characteristic" #: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h #: ports/atmel-samd/boards/meowmeow/mpconfigboard.h msgid "You pressed both buttons at start up." -msgstr "Vous avez appuyé les deux boutons au démarrage." +msgstr "Vous avez appuyé sur les deux boutons au démarrage." #: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." -msgstr "Vous avez appuyé le bouton A au démarrage." +msgstr "Vous avez appuyé sur le bouton A au démarrage." #: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h msgid "You pressed button DOWN at start up." @@ -2407,16 +2509,17 @@ msgstr "Vous avez appuyé sur le bouton DOWN au démarrage." #: supervisor/shared/safe_mode.c msgid "You pressed the BOOT button at start up" -msgstr "Vous avez appuyé le bouton BOOT au démarrage" +msgstr "Vous avez appuyé sur le bouton BOOT au démarrage" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." -msgstr "" +msgstr "Vous avez appuyé sur le bouton BOOT au démarrage." #: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h msgid "You pressed the GPIO0 button at start up." -msgstr "Vous avez appuyé le bouton GPIO0 au démarrage." +msgstr "Vous avez appuyé sur le bouton GPIO0 au démarrage." #: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h msgid "You pressed the Rec button at start up." @@ -2424,7 +2527,7 @@ msgstr "Vous avez appuyé sur le bouton Rec au démarrage." #: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h msgid "You pressed the SW38 button at start up." -msgstr "Vous avez appuyé le bouton SW38 au démarrage." +msgstr "Vous avez appuyé sur le bouton SW38 au démarrage." #: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h #: ports/espressif/boards/vidi_x/mpconfigboard.h @@ -2436,15 +2539,15 @@ msgstr "Vous avez appuyé le bouton VOLUME au démarrage." #: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h #: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h msgid "You pressed the central button at start up." -msgstr "Vous avez appuyé le bouton central au démarrage." +msgstr "Vous avez appuyé sur le bouton central au démarrage." #: ports/nordic/boards/aramcon2_badge/mpconfigboard.h msgid "You pressed the left button at start up." -msgstr "Vous avez appuyé le bouton gauche au démarrage." +msgstr "Vous avez appuyé sur le bouton gauche au démarrage." #: supervisor/shared/safe_mode.c msgid "You pressed the reset button during boot." -msgstr "Vous avez appuyé le bouton reset au démarrage." +msgstr "Vous avez appuyé sur le bouton reset au démarrage." #: supervisor/shared/micropython.c msgid "[truncated due to length]" @@ -2471,9 +2574,13 @@ msgstr "un objet 'bytes-like' est requis" msgid "addresses is empty" msgstr "adresses vides" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "en cours de lecture" + #: py/compile.c msgid "annotation must be an identifier" -msgstr "l'annotation doit être un identificateur" +msgstr "l'annotation doit être un indentifiant" #: extmod/ulab/code/numpy/create.c msgid "arange: cannot compute length" @@ -2498,6 +2605,7 @@ msgstr "argsort n'est pas implémenté pour les arrays aplatis" #: extmod/ulab/code/numpy/random/random.c msgid "argument must be None, an integer or a tuple of integers" msgstr "" +"Le paramètre doit être None, un nombre entier ou un tuple de nombres entiers" #: py/compile.c msgid "argument name reused" @@ -2518,11 +2626,11 @@ msgstr "la taille de l'array et de l'index doivent être égaux" #: extmod/ulab/code/numpy/io/io.c msgid "array has too many dimensions" -msgstr "la tableau à trop de dimensions" +msgstr "le tableau à trop de dimensions" #: extmod/ulab/code/ndarray.c msgid "array is too big" -msgstr "array trop grand" +msgstr "Tableau trop grand" #: py/objarray.c shared-bindings/alarm/SleepMemory.c #: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c @@ -2531,7 +2639,7 @@ msgstr "matrice/octets requis à la droite" #: py/asmxtensa.c msgid "asm overflow" -msgstr "débordement asm" +msgstr "Débordement asm" #: py/compile.c msgid "async for/with outside async function" @@ -2543,12 +2651,16 @@ msgstr "tentative d'obtenir (arg)min/(arg)max d'une séquence vide" #: extmod/ulab/code/numpy/numerical.c msgid "attempt to get argmin/argmax of an empty sequence" -msgstr "tenter d'obtenir argmin / argmax d'une séquence vide" +msgstr "Tentative d'obtention argmin / argmax d'une séquence vide" #: py/objstr.c msgid "attributes not supported" msgstr "attributs non pris en charge" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "format audio incomptatible" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "axis est hors limites" @@ -2563,11 +2675,11 @@ msgstr "axis trop long" #: shared-bindings/bitmaptools/__init__.c msgid "background value out of range of target" -msgstr "la valeur du fond est hors de l'intervalle de la cible" +msgstr "Valeur d'arrière-plan hors de la plage cible" #: py/builtinevex.c msgid "bad compile mode" -msgstr "mauvais mode de compilation" +msgstr "Mauvais mode de compilation" #: py/objstr.c msgid "bad conversion specifier" @@ -2585,9 +2697,13 @@ msgstr "mauvais code type" msgid "binary op %q not implemented" msgstr "opération binaire '%q' non implémentée" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth doit être 8, 16, 24 ou 32." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" -msgstr "" +msgstr "taille et profondeur du bitmap doivent correspondre" #: shared-bindings/bitmaptools/__init__.c msgid "bitmap sizes must match" @@ -2597,9 +2713,18 @@ msgstr "les tailles des images doivent correspondre" msgid "bits must be 32 or less" msgstr "les bits doivent être 32 ou moins" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample doit être de 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" -msgstr "'bits_per_sample' doivent être 8 ou 16" +msgstr "bits_per_sample doivent être 8 ou 16" #: py/emitinlinethumb.c msgid "branch not in range" @@ -2631,7 +2756,7 @@ msgstr "tampon trop petit pour le nombre d'octets demandé" #: py/emitbc.c msgid "bytecode overflow" -msgstr "" +msgstr "débordement du bytecode" #: py/objarray.c msgid "bytes length not a multiple of item size" @@ -2679,7 +2804,7 @@ msgstr "ne peut pas assigner à une expression" msgid "can't cancel self" msgstr "ne peut pas s'annuler soi-même" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "impossible de convertir %q en %q" @@ -2736,7 +2861,7 @@ msgstr "opération binaire impossible entre '%q' et '%q'" #: py/emitnative.c msgid "can't do unary op of '%q'" -msgstr "" +msgstr "impossible d'effectuer l'opération unaire de '%q'" #: py/emitnative.c msgid "can't implicitly convert '%q' to 'bool'" @@ -2756,7 +2881,7 @@ msgstr "impossible de charger avec l'indice '%q'" #: py/builtinimport.c msgid "can't perform relative import" -msgstr "ne peut importer relativement" +msgstr "ne peut faire un import relatif" #: py/objgenerator.c msgid "can't send non-None value to a just-started generator" @@ -2766,7 +2891,7 @@ msgstr "" #: shared-module/sdcardio/SDCard.c msgid "can't set 512 block size" -msgstr "impossible de définir une taille de bloc de 512" +msgstr "Impossible de définir la taille de bloc à 512" #: py/objexcept.c py/objnamedtuple.c msgid "can't set attribute" @@ -2808,7 +2933,7 @@ msgstr "un nombre complexe ne peut pas être tronqué/divisé" #: extmod/modasyncio.c msgid "can't wait" -msgstr "impossible de mettre en attente" +msgstr "Impossible d'attendre" #: extmod/ulab/code/ndarray.c msgid "cannot assign new shape" @@ -2840,7 +2965,7 @@ msgstr "les éléments de la matrice ne peut être supprimés" #: extmod/ulab/code/ndarray.c msgid "cannot reshape array" -msgstr "" +msgstr "Impossible de transformer le tableau" #: py/emitnative.c msgid "casting" @@ -2996,7 +3121,7 @@ msgstr "les dimensions ne correspondent pas" #: py/emitnative.c msgid "div/mod not implemented for uint" -msgstr "div/mod ne sont pas implémentés pour uint" +msgstr "div/Mod non implémenté pour uint" #: extmod/ulab/code/numpy/create.c msgid "divide by zero" @@ -3008,11 +3133,11 @@ msgstr "division par zéro" #: extmod/ulab/code/numpy/vector.c msgid "dtype must be float, or complex" -msgstr "le dtype doit être un flottant, ou un complexe" +msgstr "le dtype doit être de type flottant ou complexe" #: extmod/ulab/code/ndarray_operators.c msgid "dtype of int32 is not supported" -msgstr "dtype de int32 non pris en charge" +msgstr "dtype en int32 non supporté" #: py/objdeque.c msgid "empty" @@ -3036,11 +3161,12 @@ msgstr "séquence vide" #: py/objstr.c msgid "end of format while looking for conversion specifier" -msgstr "fin de format en cherchant une spécification de conversion" +msgstr "" +"fin du format atteinte lors de la recherche du spécificateur de conversion" #: shared-bindings/alarm/time/TimeAlarm.c msgid "epoch_time not supported on this board" -msgstr "epoch_time n'est pas supporté sur ce panneau" +msgstr "epoch_time n'est pas supporté sur cet plateforme" #: ports/nordic/common-hal/busio/UART.c #, c-format @@ -3057,7 +3183,7 @@ msgstr "':' attendu après la spécification de format" #: py/obj.c msgid "expected tuple/list" -msgstr "un tuple ou une liste est attendu" +msgstr "demande un tuple ou une liste" #: py/modthread.c msgid "expecting a dict for keyword args" @@ -3069,11 +3195,11 @@ msgstr "une instruction assembleur est attendue" #: py/compile.c msgid "expecting just a value for set" -msgstr "une simple valeur est attendue pour l'ensemble 'set'" +msgstr "au moins une valeur requise pour un 'set'" #: py/compile.c msgid "expecting key:value for dict" -msgstr "couple clef:valeur attendu pour un dictionnaire 'dict'" +msgstr "couple clef:valeur requis pour un dictionnaire 'dict'" #: shared-bindings/msgpack/__init__.c msgid "ext_hook is not a function" @@ -3095,11 +3221,11 @@ msgstr "le fichier doit être un fichier ouvert en mode 'byte'" #: shared-bindings/traceback/__init__.c msgid "file write is not available" -msgstr "l'écriture de fichier n'est pas disponible" +msgstr "écriture de fichier indisponible" #: shared-bindings/storage/__init__.c msgid "filesystem must provide mount method" -msgstr "le system de fichier doit fournir une méthode 'mount'" +msgstr "le system de fichier requier une méthode 'mount'" #: extmod/ulab/code/numpy/vector.c msgid "first argument must be a callable" @@ -3123,7 +3249,7 @@ msgstr "le premier argument de super() doit être un type" #: extmod/ulab/code/scipy/linalg/linalg.c msgid "first two arguments must be ndarrays" -msgstr "les deux premiers paramètres doivent être des ndarrays" +msgstr "les deux premiers arguments doivent être des ndarrays" #: extmod/ulab/code/ndarray.c msgid "flattening order must be either 'C', or 'F'" @@ -3135,23 +3261,23 @@ msgstr "le paramêtre flip doit être un ndarray" #: py/objint.c msgid "float too big" -msgstr "nombre à virgule flottante trop grand" +msgstr "nombre flottant trop grand" #: py/nativeglue.c msgid "float unsupported" -msgstr "valeures flotantes non supportées" +msgstr "flottant non supporté" #: shared-bindings/_stage/Text.c msgid "font must be 2048 bytes long" -msgstr "la police doit être longue de 2048 octets" +msgstr "la police doit être de 2048 octets" #: extmod/moddeflate.c msgid "format" msgstr "format" #: py/objstr.c -msgid "format requires a dict" -msgstr "le format nécessite un dict" +msgid "format needs a dict" +msgstr "le format requier un dict" #: py/objdeque.c msgid "full" @@ -3176,7 +3302,7 @@ msgstr "la fonction a le même signe aux extrémités de l'intervalle" #: extmod/ulab/code/ndarray.c msgid "function is defined for ndarrays only" -msgstr "fonction définie que pour les ndarrays" +msgstr "la fonction n'est définie que pour les ndarrays" #: extmod/ulab/code/numpy/carray/carray.c msgid "function is implemented for ndarrays only" @@ -3208,7 +3334,7 @@ msgstr "la fonction prend %d argument(s) positionnels mais %d ont été donné(s #: py/objgenerator.c msgid "generator already executing" -msgstr "générateur déjà en cours d'exécution" +msgstr "générateur déjà en exécution" #: py/objgenerator.c msgid "generator ignored GeneratorExit" @@ -3216,7 +3342,7 @@ msgstr "le générateur a ignoré GeneratorExit" #: py/objgenerator.c py/runtime.c msgid "generator raised StopIteration" -msgstr "générateur (generator) à surlevé StopIteration" +msgstr "le générateur a levé l'exception StopIteration" #: shared-bindings/_stage/Layer.c msgid "graphic must be 2048 bytes long" @@ -3224,7 +3350,7 @@ msgstr "graphic doit être long de 2048 octets" #: extmod/modhashlib.c msgid "hash is final" -msgstr "hash est final" +msgstr "le hachage est final" #: extmod/modheapq.c msgid "heap must be a list" @@ -3240,7 +3366,7 @@ msgstr "identifiant redéfini comme nonlocal" #: py/compile.c msgid "import * not at module level" -msgstr "import * n'est pas au niveau du module" +msgstr "import * non au niveau du module" #: py/persistentcode.c msgid "incompatible .mpy arch" @@ -3283,11 +3409,7 @@ msgstr "les indices doivent être des entiers" #: extmod/ulab/code/ndarray.c msgid "indices must be integers, slices, or Boolean lists" msgstr "" -"les indices doivent être des entiers, des tranches ou des listes booléennes" - -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "initialisation I2C" +"les indices doivent être des entiers, des tranches, des listes booléennes" #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" @@ -3303,16 +3425,15 @@ msgstr "l'assembleur doit être une fonction" #: extmod/ulab/code/numpy/vector.c msgid "input and output dimensions differ" -msgstr "les dimensions de sortie et d'entrée sont différentes" +msgstr "les dimensions d'entrée et de sortie diffèrent" #: extmod/ulab/code/numpy/vector.c msgid "input and output shapes differ" -msgstr "les formes d'entrée et de sortie sont différentes" +msgstr "Les dimensions d'entrée et de sortie diffèrent" #: extmod/ulab/code/numpy/create.c msgid "input argument must be an integer, a tuple, or a list" -msgstr "" -"le paramètre entrant doit être un nombre entier, un tuple, ou une liste" +msgstr "le paramètre entrant doit être un nombre entier, un tuple, une liste" #: extmod/ulab/code/numpy/fft/fft_tools.c msgid "input array length must be power of 2" @@ -3361,7 +3482,7 @@ msgstr "l'entrée doit être un ndarray" #: extmod/ulab/code/numpy/carray/carray.c msgid "input must be an ndarray, or a scalar" -msgstr "l'entrée doit être un ndarray, ou un scalaire" +msgstr "l'entrée doit être un ndarray, un scalaire" #: extmod/ulab/code/scipy/signal/signal.c msgid "input must be one-dimensional" @@ -3373,11 +3494,11 @@ msgstr "l'entrée doit être une matrice carrée" #: extmod/ulab/code/numpy/numerical.c msgid "input must be tuple, list, range, or ndarray" -msgstr "l'entrée 'input' doit être tuple, list, range ou ndarray" +msgstr "l'entrée 'input' doit être un tuple, list, range, ndarray" #: extmod/ulab/code/numpy/poly.c msgid "input vectors must be of equal length" -msgstr "les vecteurs d'entrée doivent être de longueur égale" +msgstr "les vecteurs d'entrée doivent être de même longueur" #: extmod/ulab/code/numpy/approx.c msgid "interp is defined for 1D iterables of equal length" @@ -3390,7 +3511,7 @@ msgstr "interval doit être dans la portée %s-%s" #: py/compile.c msgid "invalid arch" -msgstr "" +msgstr "arch invalide" #: shared-bindings/bitmaptools/__init__.c #, c-format @@ -3430,7 +3551,7 @@ msgstr "clé invalide" #: py/compile.c msgid "invalid micropython decorator" -msgstr "décorateur micropython invalide" +msgstr "décorateur Micropython invalide" #: ports/espressif/common-hal/espcamera/Camera.c msgid "invalid setting" @@ -3438,7 +3559,7 @@ msgstr "réglage invalide" #: shared-bindings/random/__init__.c msgid "invalid step" -msgstr "pas invalide" +msgstr "étape invalide" #: py/compile.c py/parse.c msgid "invalid syntax" @@ -3446,7 +3567,7 @@ msgstr "syntaxe invalide" #: py/parsenum.c msgid "invalid syntax for integer" -msgstr "syntaxe invalide pour un entier" +msgstr "Syntaxe entier invalide" #: py/parsenum.c #, c-format @@ -3473,12 +3594,13 @@ msgstr "les itérations n'ont pas convergé" #: py/objstr.c msgid "join expects a list of str/bytes objects consistent with self object" -msgstr "" -"'join' s'attend à une liste d'objets str/bytes cohérents avec l'objet self" +msgstr "'join' attend une liste d'objets str/bytes cohérents avec l'objet self" #: py/argcheck.c msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" +"argument(s) de mot-clé non implémenté(s) - utilisez des arguments normaux à " +"la place" #: py/emitinlinethumb.c py/emitinlinextensa.c msgid "label '%q' not defined" @@ -3488,10 +3610,6 @@ msgstr "label '%q' non supporté" msgid "label redefined" msgstr "étiquette redéfinie" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "le niveau doit être compris entre 0 et 1" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "les parties gauches et droites doivent être compatibles" @@ -3502,7 +3620,7 @@ msgstr "la variable locale '%q' a le type '%q' mais la source est '%q'" #: py/emitnative.c msgid "local '%q' used before type known" -msgstr "variable locale '%q' utilisée avant d'en connaitre le type" +msgstr "variable locale '%q' utilisée avant que le type soit connu" #: py/vm.c msgid "local variable referenced before assignment" @@ -3528,7 +3646,7 @@ msgstr "f-string mal formé" #: shared-bindings/_stage/Layer.c msgid "map buffer too small" -msgstr "tampon trop petit" +msgstr "tampon de la matrice trop petit" #: py/modmath.c shared-bindings/math/__init__.c msgid "math domain error" @@ -3576,7 +3694,7 @@ msgstr "l'allocation de mémoire a échoué, le tas est vérrouillé" #: py/objarray.c msgid "memoryview offset too large" -msgstr "" +msgstr "décalage memoryview trop large" #: py/objarray.c msgid "memoryview: length is not a multiple of itemsize" @@ -3623,7 +3741,7 @@ msgid "must use keyword argument for key function" msgstr "doit utiliser un argument nommé pour une fonction key" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "nom '%q' non défini" #: py/runtime.c @@ -3632,7 +3750,7 @@ msgstr "nom non défini" #: py/qstr.c msgid "name too long" -msgstr "" +msgstr "nom trop long" #: py/persistentcode.c msgid "native code in .mpy unsupported" @@ -3677,7 +3795,7 @@ msgstr "pas de carte SD" #: py/vm.c msgid "no active exception to reraise" -msgstr "aucune exception active à relever" +msgstr "aucune exception active à lever à nouveau" #: py/compile.c msgid "no binding for nonlocal found" @@ -3685,11 +3803,11 @@ msgstr "pas de lien trouvé pour nonlocal" #: shared-module/msgpack/__init__.c msgid "no default packer" -msgstr "aucun emballeur par défault" +msgstr "pas de 'packer' par défaut" #: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c msgid "no default seed" -msgstr "aucun seed par défaut" +msgstr "pas de 'seed' par défaut" #: py/builtinimport.c msgid "no module named '%q'" @@ -3697,11 +3815,11 @@ msgstr "pas de module '%q'" #: shared-module/sdcardio/SDCard.c msgid "no response from SD card" -msgstr "pas de réponse de la carte SD" +msgstr "la carte SD ne réponds pas" #: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c msgid "no such attribute" -msgstr "pas de tel attribut" +msgstr "aucun attribut" #: ports/espressif/common-hal/_bleio/Connection.c #: ports/nordic/common-hal/_bleio/Connection.c @@ -3715,15 +3833,15 @@ msgstr "" #: py/objstr.c msgid "non-hex digit found" -msgstr "chiffre non-héxadécimale trouvé" +msgstr "chiffre non-héxa trouvé" #: ports/nordic/common-hal/_bleio/Adapter.c msgid "non-zero timeout must be > 0.01" -msgstr "le délai non-zéro doit être > 0.01" +msgstr "le dépassement de délai non-zéro doit être > 0.01" #: shared-bindings/_bleio/Adapter.c msgid "non-zero timeout must be >= interval" -msgstr "le délai non-zéro doit être >= interval" +msgstr "le dépassement de délai non-zéro doit être >= interval" #: shared-bindings/_bleio/UUID.c msgid "not a 128-bit UUID" @@ -3748,24 +3866,24 @@ msgstr "n'est pas implémenté pour les dtype complexes" #: extmod/ulab/code/numpy/bitwise.c msgid "not supported for input types" -msgstr "non pris en charge pour types d'entrée" +msgstr "non supporté pour les types d'entrée" #: extmod/ulab/code/numpy/create.c msgid "number of points must be at least 2" -msgstr "le nombre de points doit être d'au moins 2" +msgstr "au moins 2 points" #: py/builtinhelp.c msgid "object " -msgstr "objet " +msgstr "objet . " #: py/obj.c #, c-format msgid "object '%s' isn't a tuple or list" -msgstr "l'objet '%s' n'est pas un tuple ou une liste" +msgstr "l'objet '%s' n'est pas un tuple, une liste" #: py/obj.c msgid "object doesn't support item assignment" -msgstr "les objets ne supportent pas l'assignation des éléments" +msgstr "l'objet ne supporte pas l'assignation d'élément" #: py/obj.c msgid "object doesn't support item deletion" @@ -3773,7 +3891,7 @@ msgstr "l'objet ne supporte pas la suppression d'éléments" #: py/obj.c msgid "object has no len" -msgstr "l'objet n'a pas de 'len'" +msgstr "l'objet n'a pas de longeur 'len'" #: py/obj.c msgid "object isn't subscriptable" @@ -3798,11 +3916,11 @@ msgstr "objet non itérable" #: py/obj.c #, c-format msgid "object of type '%s' has no len()" -msgstr "l'objet de type '%s' n'a pas de len()" +msgstr "l'objet de type '%s' n'a pas de longeur len()" #: py/obj.c msgid "object with buffer protocol required" -msgstr "un objet avec un protocole de tampon est nécessaire" +msgstr "un objet avec un protocole de buffer est requis" #: py/objstr.c msgid "odd-length string" @@ -3814,16 +3932,15 @@ msgstr "inactif" #: extmod/ulab/code/utils/utils.c msgid "offset is too large" -msgstr "offset est trop large" +msgstr "l'offset est trop large" #: shared-bindings/dualbank/__init__.c msgid "offset must be >= 0" -msgstr "offset doit être >= 0" +msgstr "l'offset doit être >= 0" #: extmod/ulab/code/numpy/create.c msgid "offset must be non-negative and no greater than buffer length" -msgstr "" -"offset ne doit pas être négatif, et pas plus grand que la taille du tampon" +msgstr "l'offset peu être négatif, et plus grand que la taille du tampon" #: ports/nordic/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c @@ -3840,7 +3957,7 @@ msgstr "seuls les ndarrays peuvent être concaténés" #: ports/stm/common-hal/audiobusio/PDMIn.c msgid "only oversample=64 is supported" -msgstr "seul oversample=64 supporté" +msgstr "seul oversample=64 est supporté" #: ports/nordic/common-hal/audiobusio/PDMIn.c #: ports/stm/common-hal/audiobusio/PDMIn.c @@ -3855,7 +3972,7 @@ msgstr "seules les tranches avec 'step=1' (cad None) sont supportées" #: py/vm.c msgid "opcode" -msgstr "opcode" +msgstr "" #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c #: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c @@ -3898,31 +4015,31 @@ msgstr "" #: extmod/ulab/code/utils/utils.c msgid "out array is too small" -msgstr "matrice de sortie est trop petite" +msgstr "la matrice de sortie est trop petite" #: extmod/ulab/code/numpy/random/random.c msgid "out has wrong type" -msgstr "" +msgstr "la sortie est de type incorrect" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for complex dtype" -msgstr "mot clé out non pris en charge pour dtype complexe" +msgstr "mot clé 'out' non pris en charge pour 'dtype' complexe" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for function" -msgstr "mot clé out non pris en charge pour function" +msgstr "mot clé 'out 'non pris en charge pour 'function'" #: extmod/ulab/code/utils/utils.c msgid "out must be a float dense array" -msgstr "la matrice sortante doit être de type float" +msgstr "la matrice sortante doit être de type floattant" #: extmod/ulab/code/numpy/vector.c msgid "out must be an ndarray" -msgstr "out doit être un ndarray" +msgstr "'out' doit être un ndarray" #: extmod/ulab/code/numpy/vector.c msgid "out must be of float dtype" -msgstr "out doit être de dtype float" +msgstr "'out' doit être de dtype float" #: shared-bindings/bitmaptools/__init__.c msgid "out of range of target" @@ -3930,11 +4047,11 @@ msgstr "hors de l'intervalle de la cible" #: extmod/ulab/code/numpy/random/random.c msgid "output array has wrong type" -msgstr "" +msgstr "tableau de sortie est de type incorrect" #: extmod/ulab/code/numpy/random/random.c msgid "output array must be contiguous" -msgstr "" +msgstr "tableau de sortie doit être contiguë" #: py/objint_mpz.c msgid "overflow converting long int to machine word" @@ -3959,7 +4076,7 @@ msgstr "les paramètres doivent être des registres dans la séquence r0 à r3" #: extmod/vfs_posix_file.c msgid "poll on file not available on win32" -msgstr "le polling sur un fichier n'est pas disponible sous win32" +msgstr "Le 'polling' sur un fichier est indisponible sous Win32" #: ports/espressif/common-hal/pulseio/PulseIn.c msgid "pop from an empty PulseIn" @@ -3980,11 +4097,11 @@ msgstr "port doit être >= 0" #: py/compile.c msgid "positional arg after **" -msgstr "" +msgstr "paramètre de positionaprès **" #: py/compile.c msgid "positional arg after keyword arg" -msgstr "" +msgstr "argument de position après un argument mot clé" #: py/objint_mpz.c msgid "pow() 3rd argument cannot be 0" @@ -3996,7 +4113,7 @@ msgstr "pow() avec 3 arguments nécessite des entiers" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c msgid "pull masks conflict with direction masks" -msgstr "masque pull est en conflit avec les masques de direction" +msgstr "le masque pull est en conflit avec les masques de direction" #: py/parse.c msgid "raw f-strings are not supported" @@ -4030,7 +4147,7 @@ msgstr "return attendait '%q' mais a reçu '%q'" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format msgid "rgb_pins[%d] duplicates another pin assignment" -msgstr "rgb_pins[%d] duplique une autre affectation de broches" +msgstr "rgb_pins[%d] duplique une autre assignation de pin" #: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format @@ -4045,6 +4162,10 @@ msgstr "paramêtre roll doit être un ndarray" msgid "rsplit(None,n)" msgstr "rsplit(None, n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed doit être vrai" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4052,7 +4173,7 @@ msgstr "taux d'échantillonage hors intervalle" #: py/modmicropython.c msgid "schedule queue full" -msgstr "file de schédule pleine" +msgstr "file d'attente 'schedule ' de planification pleine" #: py/builtinimport.c msgid "script compilation not supported" @@ -4064,7 +4185,7 @@ msgstr "set non-supporté" #: extmod/ulab/code/numpy/random/random.c msgid "shape must be None, and integer or a tuple of integers" -msgstr "" +msgstr "la forme doit être None, un entier ou un tuple d'entier" #: extmod/ulab/code/ndarray.c msgid "shape must be integer or tuple of integers" @@ -4072,23 +4193,23 @@ msgstr "la forme doit être un entier ou un tuple d'entiers" #: shared-module/msgpack/__init__.c msgid "short read" -msgstr "donnée trop petite" +msgstr "lecture incomplète" #: py/objstr.c msgid "sign not allowed in string format specifier" -msgstr "signe non autorisé dans les spéc. de formats de chaînes de caractères" +msgstr "signe non autorisé dans le spécificateur de format de chaîne" #: py/objstr.c msgid "sign not allowed with integer format specifier 'c'" -msgstr "signe non autorisé avec la spéc. de format d'entier 'c'" +msgstr "signe non autorisé avec le spécificateur de format d'entier 'c'" #: extmod/ulab/code/ulab_tools.c msgid "size is defined for ndarrays only" -msgstr "la taille n'est définie que pour les ndarrays" +msgstr "la taille est définie uniquement pour les ndarrays" #: extmod/ulab/code/numpy/random/random.c msgid "size must match out.shape when used together" -msgstr "" +msgstr "taille doit correspondre à out.shape lorsqu'employés ensemble" #: py/nativeglue.c msgid "slice unsupported" @@ -4096,7 +4217,7 @@ msgstr "slice non-supporté" #: py/objint.c py/sequence.c msgid "small int overflow" -msgstr "dépassement de capacité d'un entier court" +msgstr "dépassement d'un petit entier" #: main.c msgid "soft reboot\n" @@ -4108,7 +4229,7 @@ msgstr "le paramètre de «sort» doit être un ndarray" #: extmod/ulab/code/scipy/signal/signal.c msgid "sos array must be of shape (n_section, 6)" -msgstr "la matrice sos doit être de forme (n_section, 6)" +msgstr "la matrice 'sos' doit être de forme (n_section, 6)" #: extmod/ulab/code/scipy/signal/signal.c msgid "sos[:, 3] should be all ones" @@ -4136,7 +4257,7 @@ msgstr "source_bitmap doit avoir une value_count de 8" #: extmod/modre.c msgid "splitting with sub-captures" -msgstr "" +msgstr "scission avec sous-captures" #: py/objstr.c msgid "start/end indices" @@ -4156,7 +4277,7 @@ msgstr "arguments de type chaine de caractères sans encodage" #: py/objstrunicode.c msgid "string index out of range" -msgstr "index de chaîne hors gamme" +msgstr "indice de chaîne hors limites" #: py/objstrunicode.c #, c-format @@ -4189,20 +4310,20 @@ msgstr "le délai (timeout) doit être < 655.35 secondes" #: ports/raspberrypi/common-hal/floppyio/__init__.c msgid "timeout waiting for flux" -msgstr "" +msgstr "délai d'expiration en attente du flux" #: ports/raspberrypi/common-hal/floppyio/__init__.c #: shared-module/floppyio/__init__.c msgid "timeout waiting for index pulse" -msgstr "" +msgstr "délai d'expiration en attente de l'index de pulsation" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" -msgstr "délai d'expiration dépassé en attendant une carte v1" +msgstr "délai d'attente dépassé pour la carte v1" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v2 card" -msgstr "délai d'expiration dépassé en attendant une carte v2" +msgstr "délai d'attente dépassé pour la carte v2" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "timer re-init" @@ -4214,11 +4335,11 @@ msgstr "timestamp hors intervalle pour le 'time_t' de la plateforme" #: extmod/ulab/code/ndarray.c msgid "tobytes can be invoked for dense arrays only" -msgstr "tobytes ne peut être appelée que pour des matrices dense" +msgstr "'tobytes' ne peut être appelée que pour des matrices dense" #: py/compile.c msgid "too many args" -msgstr "args trop nombreux" +msgstr "argsuments trop nombreux" #: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c msgid "too many dimensions" @@ -4230,7 +4351,7 @@ msgstr "trop d'indices" #: py/asmthumb.c msgid "too many locals for native method" -msgstr "trop de locals pour une méthode native" +msgstr "trop de 'locals' pour une méthode native" #: py/runtime.c #, c-format @@ -4264,11 +4385,11 @@ msgid "tx and rx cannot both be None" msgstr "tx et rx ne peuvent être 'None' tous les deux" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "le type '%q' n'est pas un type de base accepté" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "le type n'est pas un type de base accepté" #: py/runtime.c @@ -4294,7 +4415,7 @@ msgstr "paramètre nommé inattendu" #: py/argcheck.c py/bc.c py/objnamedtuple.c #: shared-bindings/traceback/__init__.c msgid "unexpected keyword argument '%q'" -msgstr "paramètre nommé '%q' inattendu" +msgstr "mot clé nommé '%q' inattendu" #: py/lexer.c msgid "unicode name escapes" @@ -4302,7 +4423,7 @@ msgstr "échappements de nom unicode" #: py/parse.c msgid "unindent doesn't match any outer indent level" -msgstr "unindent ne correspond pas au niveau d'indentation parent" +msgstr "'unindent' ne correspond pas au niveau d'indentation parent" #: py/objstr.c #, c-format @@ -4330,7 +4451,9 @@ msgstr "'%c' sans correspondance dans le format" msgid "unreadable attribute" msgstr "attribut illisible" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "type %q non pris on charge" @@ -4346,7 +4469,7 @@ msgstr "instruction Xtensa '%s' non supportée avec %d paramètres" #: shared-module/bitmapfilter/__init__.c msgid "unsupported bitmap depth" -msgstr "" +msgstr "profondeur de bitmap non supportée" #: shared-module/gifio/GifWriter.c msgid "unsupported colorspace for GifWriter" @@ -4399,27 +4522,24 @@ msgid "" "weights must be a sequence with an odd square number of elements (usually 9 " "or 25)" msgstr "" +"le poids requier une séquence de nombre carré impair d'éléments " +"(habituellement 9 ou 25)" #: shared-bindings/bitmapfilter/__init__.c msgid "weights must be an object of type %q, %q, %q, or %q, not %q " -msgstr "" +msgstr "le poids requier un objet de type %q, %q, %q ou %q, pas %q. " #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" -msgstr "width doit être plus que zero" - -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "wifi n'est pas activé" +msgstr "width doit être plus grand que zero" #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" -msgstr "wifi.Monitor non disponible" +msgstr "wifi.Monitor indisponible" #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" -msgstr "la fenêtre (window) doit être <= intervalle (interval)" +msgstr "la fenêtre (window) doit être <= à l'intervalle (interval)" #: extmod/ulab/code/numpy/numerical.c msgid "wrong axis index" @@ -4427,7 +4547,7 @@ msgstr "index d'axe incorrecte" #: extmod/ulab/code/numpy/create.c msgid "wrong axis specified" -msgstr "axe incorrecte spécifiée" +msgstr "axe spécifiée incorrect" #: extmod/ulab/code/numpy/io/io.c msgid "wrong dtype" @@ -4475,6 +4595,54 @@ msgstr "zi doit être de type float" msgid "zi must be of shape (n_section, 2)" msgstr "zi doit être de forme (n_section, 2)" +#~ msgid "Unsupported format" +#~ msgstr "Format non pris en charge" + +#~ msgid "Wifi is not enabled" +#~ msgstr "Le WiFi n'est pas activé" + +#~ msgid "wifi is not enabled" +#~ msgstr "le WiFi est inactif" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "" +#~ "Ne peut démonter '/' la racine du système de fichier quand elle est déja " +#~ "vue par le port USB." + +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q doit être un objet %q, %q ou %q" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Un bloc de données doit suivre un bloc fmt" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Seul les BMP monochromes, 4 bpp ou 8 bpp, ou 16 bpp et plus sont " +#~ "supportés: %d bpp fournis" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "le niveau doit être compris entre 0 et 1" + +#~ msgid "init I2C" +#~ msgstr "initialisation I2C" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "" +#~ "Le 'bits_per_sample' de l'échantillon ne correspond pas à celui du mixer" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "Le canal de l'échantillon ne correspond pas à celui du mixer" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "" +#~ "L'échantillonage de l'échantillon ne correspond pas à celui du mixer" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "Le signe de l'échantillon ne correspond pas à celui du mixer" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "La longueur de la mémoire tampon doit être un multiple de 512" @@ -4790,13 +4958,13 @@ msgstr "zi doit être de forme (n_section, 2)" #~ msgid "'%s' object does not support item deletion" #~ msgstr "l'objet '%s' ne supporte pas la suppression d'éléments" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "l'objet '%s' n'est pas un itérateur" #~ msgid "'%s' object is not callable" #~ msgstr "l'objet '%s' n'est pas appelable" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "l'objet '%s' n'est pas itérable" #~ msgid "'%s' object is not subscriptable" @@ -4814,7 +4982,7 @@ msgstr "zi doit être de forme (n_section, 2)" #~ msgid "'continue' outside loop" #~ msgstr "'continue' dehors d'une boucle" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "L'objet \"coroutine\" n'est pas un itérateur" #~ msgid "(x,y) integers required" @@ -6303,7 +6471,7 @@ msgstr "zi doit être de forme (n_section, 2)" #~ msgid "frequency is read-only for this board" #~ msgstr "la fréquence est en lecture seule pour cette carte" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "la fonction ne prend pas d'arguments nommés" #~ msgid "function is implemented for scalars and ndarrays only" @@ -6432,7 +6600,7 @@ msgstr "zi doit être de forme (n_section, 2)" #~ msgid "name must be a string" #~ msgstr "les noms doivent être des chaînes de caractère" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "nom réutilisé comme paramètre" #~ msgid "no available NIC" diff --git a/locale/hi.po b/locale/hi.po index bfdd57279d8..3eb187fcf8e 100644 --- a/locale/hi.po +++ b/locale/hi.po @@ -8,1663 +8,1916 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-16 15:03+0000\n" -"Last-Translator: Anonymous \n" +"PO-Revision-Date: 2025-06-29 13:02+0000\n" +"Last-Translator: MAE \n" "Language-Team: none\n" "Language: hi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.2\n" +"X-Generator: Weblate 5.13-dev\n" -#: main.c -msgid "" -"\n" -"Code done running.\n" +#: extmod/modasyncio.c extmod/modheapq.c +msgid "empty heap" msgstr "" -#: main.c -msgid "" -"\n" -"Code stopped by auto-reload. Reloading soon.\n" +#: extmod/modasyncio.c +msgid "can't cancel self" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Please file an issue with your program at github.com/adafruit/circuitpython/" -"issues." +#: extmod/modasyncio.c +msgid "can't wait" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Press reset to exit safe mode.\n" +#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c +msgid "a bytes-like object is required" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"You are in safe mode because:\n" +#: extmod/modbinascii.c +msgid "incorrect padding" msgstr "" -#: py/obj.c -msgid " File \"%q\"" +#: extmod/moddeflate.c +msgid "format" msgstr "" -#: py/obj.c -msgid " File \"%q\", line %d" +#: extmod/moddeflate.c +msgid "wbits" msgstr "" -#: py/builtinhelp.c -msgid " is of type %q\n" +#: extmod/modhashlib.c +msgid "hash is final" msgstr "" -#: main.c -msgid " not found.\n" +#: extmod/modheapq.c +msgid "heap must be a list" msgstr "" -#: main.c -msgid " output:\n" +#: extmod/modjson.c +msgid "syntax error in JSON" msgstr "" -#: py/objstr.c -#, c-format -msgid "%%c requires int or char" +#: extmod/modrandom.c +msgid "bits must be 32 or less" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c +msgid "no default seed" msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q and %q contain duplicate pins" +#: extmod/modre.c +msgid "splitting with sub-captures" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "%q and %q must be different" +#: extmod/modre.c +msgid "regex too complex" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "%q and %q must share a clock unit" +#: extmod/modre.c +msgid "Error in regex" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "%q cannot be changed once mode is set to %q" +#: extmod/modtime.c +msgid "mktime needs a tuple of length 8 or 9" msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q contains duplicate pins" +#: extmod/modtime.c +msgid "ticks interval overflow" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -msgid "%q failure: %d" +#: extmod/modzlib.c +msgid "compression header" msgstr "" -#: py/argcheck.c -msgid "%q in %q must be of type %q, not %q" +#: extmod/ulab/code/ndarray.c +msgid "data type not understood" msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/usb_host/Port.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c -msgid "%q in use" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" msgstr "" -#: py/objstr.c -msgid "%q index out of range" +#: extmod/ulab/code/ndarray.c +msgid "ndarray length overflows" msgstr "" -#: py/obj.c -msgid "%q indices must be integers, not %s" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex type" msgstr "" -#: shared-module/bitbangio/SPI.c -msgid "%q init failed" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c +msgid "too many dimensions" msgstr "" -#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c -msgid "%q is %q" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c +msgid "index is out of bounds" msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "%q is read-only for this board" +#: extmod/ulab/code/ndarray.c +msgid "indices must be integers, slices, or Boolean lists" msgstr "" -#: py/argcheck.c shared-bindings/usb_hid/Device.c -msgid "%q length must be %d" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c +msgid "operands could not be broadcast together" msgstr "" -#: py/argcheck.c -msgid "%q length must be %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "array and index length must be equal" msgstr "" -#: py/argcheck.c -msgid "%q length must be <= %d" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex to dtype" msgstr "" -#: py/argcheck.c -msgid "%q length must be >= %d" +#: extmod/ulab/code/ndarray.c +msgid "operation is implemented for 1D Boolean arrays only" msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c -msgid "%q moved from %q to %q" +#: extmod/ulab/code/ndarray.c +msgid "too many indices" msgstr "" -#: py/argcheck.c -msgid "%q must be %d" +#: extmod/ulab/code/ndarray.c +msgid "cannot delete array elements" msgstr "" -#: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "%q must be %d-%d" +#: extmod/ulab/code/ndarray.c +msgid "flattening order must be either 'C', or 'F'" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -msgid "%q must be 1 when %q is True" +#: extmod/ulab/code/ndarray.c +msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: py/argcheck.c shared-bindings/gifio/GifWriter.c -#: shared-module/gifio/OnDiskGif.c -msgid "%q must be <= %d" +#: extmod/ulab/code/ndarray.c +msgid "operation is not supported for given type" msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "%q must be <= %u" +#: extmod/ulab/code/ndarray.c +msgid "shape must be integer or tuple of integers" msgstr "" -#: py/argcheck.c -msgid "%q must be >= %d" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c +msgid "maximum number of dimensions is " msgstr "" -#: shared-bindings/analogbufio/BufferedIn.c -msgid "%q must be a bytearray or array of type 'H' or 'B'" +#: extmod/ulab/code/ndarray.c +msgid "can only specify one unknown dimension" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +#: extmod/ulab/code/ndarray.c +msgid "cannot reshape array" msgstr "" -#: shared-bindings/warnings/__init__.c -msgid "%q must be a subclass of %q" +#: extmod/ulab/code/ndarray.c +msgid "cannot assign new shape" msgstr "" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -msgid "%q must be array of type 'H'" +#: extmod/ulab/code/ndarray.c +msgid "function is defined for ndarrays only" msgstr "" -#: shared-module/synthio/__init__.c -msgid "%q must be array of type 'h'" +#: extmod/ulab/code/ndarray_operators.c +msgid "operation not supported for the input types" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "%q must be multiple of 8." +#: extmod/ulab/code/ndarray_operators.c +msgid "dtype of int32 is not supported" msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c -#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c -#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c -#: shared-module/synthio/Synthesizer.c -msgid "%q must be of type %q or %q, not %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "cannot cast output with casting rule" msgstr "" -#: shared-bindings/jpegio/JpegDecoder.c -msgid "%q must be of type %q, %q, or %q, not %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "results cannot be cast to specified type" msgstr "" -#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c -#: shared-module/synthio/__init__.c -msgid "%q must be of type %q, not %q" +#: extmod/ulab/code/numpy/approx.c +msgid "interp is defined for 1D iterables of equal length" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -msgid "%q must be power of 2" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D iterables" msgstr "" -#: shared-bindings/wifi/Monitor.c -msgid "%q out of bounds" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D arrays of equal length" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c -#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c -msgid "%q out of range" +#: extmod/ulab/code/numpy/bitwise.c +msgid "not supported for input types" msgstr "" -#: py/objmodule.c py/runtime.c -msgid "%q renamed %q" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "function is implemented for ndarrays only" msgstr "" -#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c -msgid "%q step cannot be zero" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be an ndarray, or a scalar" msgstr "" -#: shared-module/bitbangio/I2C.c -msgid "%q too long" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be a 1D ndarray" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "%q() takes %d positional arguments but %d were given" +#: extmod/ulab/code/numpy/carray/carray_tools.c +msgid "not implemented for complex dtype" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "%q() without %q()" +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c +#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c +#: extmod/ulab/code/numpy/vector.c +msgid "wrong input type" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q, %q, and %q must all be the same length" +#: extmod/ulab/code/numpy/create.c +msgid "input argument must be an integer, a tuple, or a list" msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c -msgid "%q=%q" +#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c +msgid "wrong number of arguments" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts in more bits than pin count" +#: extmod/ulab/code/numpy/create.c py/objint_longlong.c py/objint_mpz.c +msgid "divide by zero" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts out more bits than pin count" +#: extmod/ulab/code/numpy/create.c +msgid "arange: cannot compute length" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] uses extra pin" +#: extmod/ulab/code/numpy/create.c +msgid "first argument must be a tuple of ndarrays" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] waits on input outside of count" +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -#, c-format -msgid "%s error 0x%x" +#: extmod/ulab/code/numpy/create.c +msgid "wrong axis specified" msgstr "" -#: py/argcheck.c -msgid "'%q' argument required" +#: extmod/ulab/code/numpy/create.c +msgid "input arrays are not compatible" msgstr "" -#: py/proto.c -msgid "'%q' object does not support '%q'" +#: extmod/ulab/code/numpy/create.c +msgid "input must be 1- or 2-d" msgstr "" -#: py/runtime.c -msgid "'%q' object is not an iterator" +#: extmod/ulab/code/numpy/create.c +msgid "number of points must be at least 2" msgstr "" -#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c -msgid "'%q' object is not callable" +#: extmod/ulab/code/numpy/create.c +msgid "offset must be non-negative and no greater than buffer length" msgstr "" -#: py/runtime.c -msgid "'%q' object is not iterable" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer size must be a multiple of element size" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a label" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer is smaller than requested size" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a register" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is defined for ndarrays only" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects a special register" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is implemented for linear arrays only" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an FPU register" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "input array length must be power of 2" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an address of the form [a, b]" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "real and imaginary parts must be of equal length" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects an integer" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be ndarrays" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects at most r%d" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be linear arrays" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects {r0, r1, ...}" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must not be empty" msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "'%s' integer %d isn't within range %d..%d" +#: extmod/ulab/code/numpy/io/io.c +msgid "corrupted file" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" +#: extmod/ulab/code/numpy/io/io.c +msgid "wrong dtype" msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item assignment" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols keyword must be specified" msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item deletion" +#: extmod/ulab/code/numpy/io/io.c +msgid "empty file" msgstr "" -#: py/runtime.c -msgid "'%s' object has no attribute '%q'" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols is too high" msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object isn't subscriptable" +#: extmod/ulab/code/numpy/io/io.c +msgid "array has too many dimensions" msgstr "" -#: py/objstr.c -msgid "'=' alignment not allowed in string format specifier" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "input matrix is asymmetric" msgstr "" -#: shared-module/struct/__init__.c -msgid "'S' and 'O' are not supported format types" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "matrix is not positive definite" msgstr "" -#: py/compile.c -msgid "'align' requires 1 argument" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "iterations did not converge" msgstr "" -#: py/compile.c -msgid "'await' outside function" +#: extmod/ulab/code/numpy/linalg/linalg.c +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "input matrix is singular" msgstr "" -#: py/compile.c -msgid "'break'/'continue' outside loop" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for ndarrays only" msgstr "" -#: py/compile.c -msgid "'data' requires at least 2 arguments" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for 2D arrays only" msgstr "" -#: py/compile.c -msgid "'data' requires integer arguments" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "mode must be complete, or reduced" msgstr "" -#: py/compile.c -msgid "'label' requires 1 argument" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" msgstr "" -#: py/emitnative.c -msgid "'not' not implemented" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get (arg)min/(arg)max of empty sequence" msgstr "" -#: py/compile.c -msgid "'return' outside function" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +msgid "axis must be None, or an integer" msgstr "" -#: py/compile.c -msgid "'yield from' inside async function" +#: extmod/ulab/code/numpy/numerical.c +msgid "operation is not implemented on ndarrays" msgstr "" -#: py/compile.c -msgid "'yield' outside function" +#: extmod/ulab/code/numpy/numerical.c +msgid "input must be tuple, list, range, or ndarray" msgstr "" -#: py/compile.c -msgid "* arg after **" +#: extmod/ulab/code/numpy/numerical.c +msgid "sort argument must be an ndarray" msgstr "" -#: py/compile.c -msgid "*x must be assignment target" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort argument must be an ndarray" msgstr "" -#: py/obj.c -msgid ", in %q\n" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort is not implemented for flattened arrays" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid ".show(x) removed. Use .root_group = x" +#: extmod/ulab/code/numpy/numerical.c +msgid "axis too long" msgstr "" -#: py/objcomplex.c -msgid "0.0 to a complex power" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c +msgid "arguments must be ndarrays" msgstr "" -#: py/modbuiltins.c -msgid "3-arg pow() not supported" +#: extmod/ulab/code/numpy/numerical.c +msgid "cross is defined for 1D arrays of length 3" msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "AP could not be started" +#: extmod/ulab/code/numpy/numerical.c +msgid "diff argument must be an ndarray" msgstr "" -#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, c-format -msgid "Address must be %d bytes long" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" -#: ports/espressif/common-hal/memorymap/AddressRange.c -#: ports/nordic/common-hal/memorymap/AddressRange.c -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Address range not allowed" +#: extmod/ulab/code/numpy/numerical.c +msgid "differentiation order out of range" msgstr "" -#: shared-bindings/memorymap/AddressRange.c -msgid "Address range wraps around" +#: extmod/ulab/code/numpy/numerical.c +msgid "flip argument must be an ndarray" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "All CAN peripherals are in use" +#: extmod/ulab/code/numpy/numerical.c +msgid "wrong axis index" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/nordic/common-hal/busio/I2C.c -msgid "All I2C peripherals are in use" +#: extmod/ulab/code/numpy/numerical.c +msgid "median argument must be an ndarray" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "All RX FIFOs in use" +#: extmod/ulab/code/numpy/numerical.c +msgid "roll argument must be an ndarray" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c -msgid "All SPI peripherals are in use" +#: extmod/ulab/code/numpy/poly.c +msgid "input data must be an iterable" msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c -msgid "All UART peripherals are in use" +#: extmod/ulab/code/numpy/poly.c +msgid "more degrees of freedom than data points" msgstr "" -#: ports/nordic/common-hal/countio/Counter.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c -msgid "All channels in use" +#: extmod/ulab/code/numpy/poly.c +msgid "input vectors must be of equal length" msgstr "" -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All dma channels in use" +#: extmod/ulab/code/numpy/poly.c +msgid "could not invert Vandermonde matrix" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "All event channels in use" +#: extmod/ulab/code/numpy/poly.c +msgid "input is not iterable" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All state machines in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "argument must be None, an integer or a tuple of integers" msgstr "" -#: ports/atmel-samd/audio_dma.c -msgid "All sync event channels in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "shape must be None, and integer or a tuple of integers" msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -msgid "All timers for this pin are in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "out has wrong type" msgstr "" -#: ports/atmel-samd/common-hal/_pew/PewPew.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/peripherals/nrf/timers.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c -msgid "All timers in use" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array has wrong type" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Already advertising." +#: extmod/ulab/code/numpy/random/random.c +msgid "size must match out.shape when used together" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -msgid "Already have all-matches listener" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array must be contiguous" msgstr "" -#: ports/espressif/bindings/espnow/ESPNow.c -#: ports/espressif/common-hal/espulp/ULP.c -#: shared-module/memorymonitor/AllocationAlarm.c -#: shared-module/memorymonitor/AllocationSize.c -msgid "Already running" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of condition array" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Already scanning for wifi networks" +#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c +msgid "first argument must be an ndarray" msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "An error occurred while retrieving '%s':\n" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong index type" msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Another PWMAudioOut is already active" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of index array" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -msgid "Another send is already active" +#: extmod/ulab/code/numpy/transform.c +msgid "dimensions do not match" msgstr "" -#: shared-bindings/pulseio/PulseOut.c -msgid "Array must contain halfwords (type 'H')" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be an ndarray" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Array values should be single bytes." +#: extmod/ulab/code/numpy/vector.c +msgid "out must be of float dtype" msgstr "" -#: shared-module/memorymonitor/AllocationAlarm.c -#, c-format -msgid "Attempt to allocate %d blocks" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output dimensions differ" msgstr "" -#: ports/raspberrypi/audio_dma.c -msgid "Audio conversion not implemented" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output shapes differ" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "AuthMode.OPEN is not used with password" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for function" msgstr "" -#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c -msgid "Authentication failure" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for complex dtype" msgstr "" -#: main.c -msgid "Auto-reload is off.\n" +#: extmod/ulab/code/numpy/vector.c +msgid "dtype must be float, or complex" msgstr "" -#: main.c -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" +#: extmod/ulab/code/numpy/vector.c +msgid "can't convert complex to float" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "Baudrate not supported by peripheral" +#: extmod/ulab/code/numpy/vector.c +msgid "input dtype must be float or complex" msgstr "" -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Below minimum frame rate" +#: extmod/ulab/code/numpy/vector.c +msgid "first argument must be a callable" msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Bit clock and word select must be sequential GPIO pins" +#: extmod/ulab/code/numpy/vector.c +msgid "wrong output type" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Bitmap size and bits per value must match" +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "first two arguments must be ndarrays" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Boot device must be first (interface #0)." +#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c +msgid "input must be a dense ndarray" msgstr "" -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Both RX and TX required for flow control" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "first argument must be a function" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Brightness not adjustable" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "function has the same sign at the ends of interval" msgstr "" -#: shared-bindings/_bleio/UUID.c -#, c-format -msgid "Buffer + offset too small %d %d %d" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter should be > 0" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Buffer elements must be 4 bytes long or less" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter must be > 0" msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Buffer is not a bytearray." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be iterable" msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, c-format -msgid "Buffer length %d too big. It must be less than %d" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "initial values must be iterable" msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -#: ports/cxd56/common-hal/sdioio/SDCard.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c -#: shared-module/sdcardio/SDCard.c -#, c-format -msgid "Buffer must be a multiple of %d bytes" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be of equal length" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -#, c-format -msgid "Buffer too short by %d bytes" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sosfilt requires iterable arguments" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c -msgid "Buffer too small" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "input must be one-dimensional" msgstr "" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, c-format -msgid "Bus pin %d is already in use" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be an ndarray" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "Byte buffer must be 16 bytes." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of shape (n_section, 2)" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "CBC blocks must be multiples of 16 bytes" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of float type" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CIRCUITPY drive could not be found or created." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos array must be of shape (n_section, 6)" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "CRC or checksum was invalid" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos[:, 3] should be all ones" msgstr "" -#: py/objtype.c -msgid "Call super().__init__() before accessing native object." +#: extmod/ulab/code/ulab_tools.c +msgid "axis is out of bounds" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Camera init" +#: extmod/ulab/code/ulab_tools.c +msgid "size is defined for ndarrays only" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on RTC IO from deep sleep." +#: extmod/ulab/code/ulab_tools.c +msgid "input must be square matrix" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on one low pin while others alarm high from deep sleep." +#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c +msgid "input must be an ndarray" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on two low pins from deep sleep." +#: extmod/ulab/code/utils/utils.c +msgid "out must be a float dense array" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "Can't set CCCD on local Characteristic" +#: extmod/ulab/code/utils/utils.c +msgid "offset is too large" msgstr "" -#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c -#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c -#: shared-bindings/usb_video/__init__.c -msgid "Cannot change USB devices now" +#: extmod/ulab/code/utils/utils.c +msgid "out array is too small" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot create a new Adapter; use _bleio.adapter;" +#: extmod/vfs_fat.c py/moderrno.c +msgid "Read-only filesystem" msgstr "" -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Cannot delete values" +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" msgstr "" -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c -#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c -#: ports/nordic/common-hal/digitalio/DigitalInOut.c -#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c -msgid "Cannot get pull while in output mode" +#: extmod/vfs_posix_file.c +msgid "poll on file not available on win32" msgstr "" -#: ports/nordic/common-hal/microcontroller/Processor.c -msgid "Cannot get temperature" +#: main.c +msgid "Done" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot have scan responses for extended, connectable advertisements." +#: main.c +msgid " output:\n" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot pull on input-only pin." +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Cannot record to a file" +#: main.c +msgid "Auto-reload is off.\n" msgstr "" -#: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." +#: main.c +msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Cannot set value when direction is input." +#: main.c +msgid " not found.\n" msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Cannot specify RTS or CTS in RS485 mode" +#: main.c +msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: py/objslice.c -msgid "Cannot subclass slice" +#: main.c +msgid "" +"\n" +"Code stopped by auto-reload. Reloading soon.\n" msgstr "" -#: ports/nordic/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge, only level" +#: main.c +msgid "" +"\n" +"Code done running.\n" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge. Only level." +#: main.c +msgid "Woken up by alarm.\n" msgstr "" -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "CharacteristicBuffer writing not provided" +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +#: main.c +msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +msgstr "" + +#: main.c +msgid "UID:" +msgstr "UID:" + +#: main.c +msgid "soft reboot\n" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c +#: ports/stm/common-hal/audioio/AudioOut.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c +#: shared-module/busdisplay/BusDisplay.c shared-module/ssl/SSLContext.c +msgid "%q init failed" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c +#: shared-bindings/bitmaptools/__init__.c shared-bindings/canio/Match.c +#: shared-bindings/time/__init__.c +msgid "%q out of range" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid state" +msgstr "" + +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "RS485" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Both RX and TX required for flow control" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c +msgid "Failed to allocate %q buffer" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c +#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/microcontroller/Processor.c +#: ports/espressif/common-hal/mipidsi/Display.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +#: ports/raspberrypi/bindings/picodvi/Framebuffer.c +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c +msgid "Invalid %q" +msgstr "" + +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" + +#: ports/atmel-samd/audio_dma.c +msgid "All sync event channels in use" +msgstr "" + +#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "" + +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/atmel-samd/common-hal/_pew/PewPew.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "All timers in use" +msgstr "" + +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: ports/atmel-samd/common-hal/countio/Counter.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/max3421e/Max3421E.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +msgid "Internal resource(s) in use" +msgstr "" + +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c #: supervisor/shared/safe_mode.c -msgid "CircuitPython core code crashed hard. Whoops!\n" +msgid "Unknown reason." +msgstr "" + +#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +#: ports/nordic/common-hal/alarm/time/TimeAlarm.c +#: ports/stm/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set" +msgstr "" + +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "No DAC on chip" msgstr "" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Clock unit in use" +msgid "%q and %q must share a clock unit" msgstr "" -#: shared-bindings/_bleio/Connection.c -msgid "" -"Connection has been disconnected and can no longer be used. Create a new " -"connection." +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays have different lengths" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays types have different sizes" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Could not set address" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "Could not start interrupt, RX busy" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "No DMA channel found" msgstr "" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Couldn't allocate decoder" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Unable to allocate buffers for signed conversion" msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Channel Init Error" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +#, c-format +msgid "Only 8 or 16 bit mono with %dx oversampling supported." msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Device Init Error" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" msgstr "" #: ports/atmel-samd/common-hal/audioio/AudioOut.c msgid "DAC already in use" msgstr "" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/I2C.c +#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/busio/I2C.c +msgid "No pull up found on SDA or SCL; check your wiring" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "%q must be power of 2" +msgstr "" + +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c +#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c +#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c +#: shared-bindings/paralleldisplaybus/ParallelBus.c +#: shared-bindings/qspibus/QSPIBus.c shared-module/bitbangio/SPI.c +msgid "No %q pin" +msgstr "" + +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "" + +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "" + +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "" + +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +#: ports/nordic/common-hal/digitalio/DigitalInOut.c +#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_pins[%d]" +msgstr "" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c +#: shared-bindings/microcontroller/Pin.c +msgid "Invalid %q pin" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +#: ports/cxd56/common-hal/microcontroller/__init__.c +#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c +msgid "No bootloader present" +msgstr "" + #: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c #: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c msgid "Data 0 pin must be byte aligned" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Data format error (may be broken data)" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/pulseio/PulseIn.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c +#: shared-bindings/ps2io/Ps2.c +msgid "pop from empty %q" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data not supported with directed advertising" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "Input taking too long" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data too large for advertisement packet" +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Deep sleep pins must use a rising edge with pulldown" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "%q failure: %d" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Destination capacity is smaller than destination_length." +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/cxd56/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c +#: shared-module/sdcardio/SDCard.c +#, c-format +msgid "Buffer must be a multiple of %d bytes" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Device error or wrong termination of input stream" +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." msgstr "" -#: ports/nordic/common-hal/audiobusio/I2SOut.c -msgid "Device in use" +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/stm/common-hal/busio/UART.c +msgid "UART init" msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display must have a 16 bit colorspace." +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Camera init" +msgstr "" + +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Size not supported" msgstr "" +#: ports/cxd56/common-hal/camera/Camera.c #: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c #: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display rotation must be in 90 degree increments" +#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c +msgid "Buffer too small" msgstr "" -#: main.c -msgid "Done" +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c +msgid "Format not supported" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Drive mode not used when direction is input." +#: ports/cxd56/common-hal/gnss/GNSS.c +msgid "GNSS init" msgstr "" -#: py/obj.c -msgid "During handling of the above exception, another exception occurred:" +#: ports/cxd56/common-hal/sdioio/SDCard.c +msgid "SDCard init" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "ECB only operates on 16 bytes at a time" +#: ports/espressif/bindings/espnow/ESPNow.c +#: ports/espressif/common-hal/espulp/ULP.c +#: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize.c +msgid "Already running" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/canio/CAN.c -msgid "ESP-IDF memory allocation failed" +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c +msgid "%q is %q" msgstr "" -#: extmod/modre.c -msgid "Error in regex" +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Error in safemode.py." +#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h +#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h +msgid "You pressed the BOOT button at start up." msgstr "" -#: shared-bindings/alarm/__init__.c -msgid "Expected a kind of %q" +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Extended advertisements with scan response not supported." +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is defined for ndarrays only" +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +#: ports/espressif/boards/vidi_x/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is implemented for linear arrays only" +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." msgstr "" -#: shared-bindings/ps2io/Ps2.c -msgid "Failed sending command." +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to acquire mutex, err 0x%04x" +#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h +msgid "You pressed button DOWN at start up." msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Failed to add service TXT record" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Update failed" msgstr "" -#: shared-bindings/mdns/Server.c -msgid "" -"Failed to add service TXT record; non-string or bytes found in txt_records" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Scan already in progress. Stop with stop_scan." msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "Failed to allocate %q buffer" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: internal error" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to allocate Wifi memory" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data too large for advertisement packet" msgstr "" -#: ports/espressif/common-hal/wifi/ScannedNetworks.c -msgid "Failed to allocate wifi scan memory" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Already advertising." msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Failed to buffer the sample" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Extended advertisements with scan response not supported." msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: internal error" +msgid "Data not supported with directed advertising" msgstr "" +#: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: timeout" +#, c-format +msgid "Timeout is too long: Maximum timeout length is %d seconds" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +msgid "MITM security not supported" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +msgid "Too many descriptors" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "" + +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" msgstr "" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Failed to parse MP3 file" +#: ports/espressif/common-hal/_bleio/Connection.c +#: ports/nordic/common-hal/_bleio/Connection.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" -#: ports/nordic/sd_mutex.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c #, c-format -msgid "Failed to release mutex, err 0x%04x" +msgid "max_length must be 0-%d when fixed_length is %s" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Failed to write internal flash." +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Writes not supported on Characteristic" msgstr "" -#: py/moderrno.c -msgid "File exists" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Total data to write is larger than %q" msgstr "" -#: shared-module/os/getenv.c -msgid "File not found" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Nimble out of memory" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "Filters too complex" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid BLE parameter" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is duplicate" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#: ports/zephyr-cp/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "Not connected" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is invalid" +#: ports/espressif/common-hal/_bleio/__init__.c +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Already in progress" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is too big" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error at %s:%d: %d" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %d" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient authentication" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Format not supported" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient encryption" msgstr "" -#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c -msgid "" -"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error at %s:%d: %d" msgstr "" -#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c -#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c -msgid "Function requires lock" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error: %d" msgstr "" -#: ports/cxd56/common-hal/gnss/GNSS.c -msgid "GNSS init" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge. Only level." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Generic Failure" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot pull on input-only pin." msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Group already used" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on two low pins from deep sleep." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Hard fault: memory access or instruction error." +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c -#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c -#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c -msgid "Hardware in use, try alternative pins" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on RTC IO from deep sleep." msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Heap allocation when VM not running." +#: ports/espressif/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set." msgstr "" -#: extmod/vfs_posix_file.c py/objstringio.c -msgid "I/O operation on closed file" +#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/stm/common-hal/busio/I2C.c -msgid "I2C init error" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" msgstr "" -#: ports/raspberrypi/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "I2C peripheral in use" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +#: shared-bindings/audioi2sin/I2SIn.c +msgid "%q must be 8, 16, 24, or 32" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "In-buffer elements must be <= 4 bytes long" +#: ports/espressif/common-hal/audiobusio/__init__.c +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +msgid "Peripheral in use" msgstr "" -#: shared-bindings/_pew/PewPew.c -msgid "Incorrect buffer size" +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 8 or 16" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Init program size invalid" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin direction conflicts with initial out pin direction" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin state conflicts with initial out pin state" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" msgstr "" -#: shared-bindings/bitops/__init__.c -#, c-format -msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -msgid "Input taking too long" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" msgstr "" -#: py/moderrno.c -msgid "Input/output error" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient authentication" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient encryption" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient memory pool for the image" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient stream input buffer" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Interface must be started" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/nordic/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" msgstr "" -#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c -msgid "Internal audio buffer too small" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c +msgid "Unable to create lock" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "Internal define error" +#: ports/espressif/common-hal/busio/SPI.c +msgid "SPI configuration failed" msgstr "" -#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c -msgid "Internal error" +#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Internal error #%d" +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/canio/CAN.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "ESP-IDF memory allocation failed" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: ports/atmel-samd/common-hal/countio/Counter.c -#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c -#: ports/atmel-samd/common-hal/max3421e/Max3421E.c -#: ports/atmel-samd/common-hal/ps2io/Ps2.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-bindings/pwmio/PWMOut.c -msgid "Internal resource(s) in use" +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Cannot specify RTS or CTS in RS485 mode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Internal watchdog timer expired." +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "RS485 inversion specified when not in RS485 mode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Interrupt error." +#: ports/espressif/common-hal/canio/CAN.c +msgid "Baudrate not supported by peripheral" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Interrupted by output function" +#: ports/espressif/common-hal/canio/CAN.c +msgid "All CAN peripherals are in use" msgstr "" -#: ports/espressif/common-hal/_bleio/Service.c -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/espressif/common-hal/microcontroller/Processor.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c -#: ports/raspberrypi/bindings/picodvi/Framebuffer.c -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q" +#: ports/espressif/common-hal/canio/CAN.c +msgid "loopback + silent mode not supported by peripheral" msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q and %q" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_driver_install returned esp-idf error #%d" +msgstr "" + +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c -#: shared-bindings/microcontroller/Pin.c -msgid "Invalid %q pin" +msgid "Must provide 5/6/5 RGB pins" msgstr "" -#: ports/stm/common-hal/analogio/AnalogIn.c -msgid "Invalid ADC Unit value" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is duplicate" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Invalid BLE parameter" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid BSSID" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid MAC address" +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c +msgid "no such attribute" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c -msgid "Invalid argument" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Invalid bits per value" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Generic Failure" msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "Invalid byte %.*s" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Out of memory" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c -#, c-format -msgid "Invalid data_pins[%d]" +#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c +msgid "Invalid argument" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "Invalid format" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Invalid size" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Requested resource not found" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid hex password" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Operation or feature not supported" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Invalid multicast MAC address" +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "Operation timed out" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid size" +msgid "Received response was invalid" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "Invalid socket for TLS" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "CRC or checksum was invalid" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid state" +msgid "Version was invalid" msgstr "" -#: shared-module/os/getenv.c -msgid "Invalid unicode escape" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "MAC address was invalid" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Key must be 16, 24, or 32 bytes long" +#: ports/espressif/common-hal/espidf/__init__.c +#, c-format +msgid "%s error 0x%x" msgstr "" -#: shared-module/os/getenv.c -msgid "Key not found" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" msgstr "" -#: shared-module/is31fl3741/FrameBuffer.c -msgid "LED mappings must match display size" +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/mipidsi/Bus.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/usb_host/Port.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c +msgid "%q in use" msgstr "" -#: py/compile.c -msgid "LHS of keyword arg must be an id" +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer already in a group" +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "Only one address is allowed" msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer must be a Group or TileGrid subclass" +#: ports/espressif/common-hal/max3421e/Max3421E.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "Length of %q must be an even multiple of channel_count * type_size" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS only works with built-in WiFi" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "MAC address was invalid" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS already initialized" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/espressif/common-hal/_bleio/Descriptor.c -msgid "MITM security not supported" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Unable to start mDNS query" msgstr "" -#: shared-bindings/is31fl3741/IS31FL3741.c -msgid "Mapping must be a tuple" +#: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nordic/common-hal/memorymap/AddressRange.c +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched data size" +#: ports/espressif/common-hal/nvm/ByteArray.c +msgid "NVS Error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched swap flag" +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d or %d, not %d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] reads pin(s)" +#: ports/espressif/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] waits based on pin" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-bindings/pwmio/PWMOut.c +#: supervisor/shared/settings.c +msgid "Internal error" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] writes pin(s)" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_set_pin. %q[%u] sets pin(s)" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing jmp_pin. %q[%u] jumps on pin" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" msgstr "" -#: shared-module/storage/__init__.c -msgid "Mount point directory missing" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c -msgid "Must be a %q subclass." +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" msgstr "" -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -msgid "Must provide 5/6/5 RGB pins" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c -msgid "Must provide MISO or MOSI pin" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "Must use a multiple of 6 rgb pins, not %d" +msgid "SDIO Init Error 0x%02x" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "NLR jump failed. Likely memory corruption." +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Unsupported socket type" msgstr "" -#: ports/espressif/common-hal/nvm/ByteArray.c -msgid "NVS Error" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Out of sockets" msgstr "" -#: shared-bindings/socketpool/SocketPool.c -msgid "Name or service not known" +#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "New bitmap must be same size as old bitmap" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +msgid "%q must be <= %u" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -msgid "Nimble out of memory" +#: ports/espressif/common-hal/wifi/Monitor.c +msgid "monitor init failed" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c -#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c -#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c -#: shared-bindings/paralleldisplaybus/ParallelBus.c -#: shared-module/bitbangio/SPI.c -msgid "No %q pin" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Interface must be started" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "No CCCD for this Characteristic" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Invalid multicast MAC address" msgstr "" -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "No DAC on chip" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Already scanning for wifi networks" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA channel found" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA pacing timer found" +#: ports/espressif/common-hal/wifi/ScannedNetworks.c +msgid "Failed to allocate wifi scan memory" msgstr "" -#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c -#, c-format -msgid "No I2C device at address: 0x%x" +#: ports/espressif/common-hal/wifi/__init__.c +msgid "Failed to allocate Wifi memory" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "No IP" +#: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +msgid "Only IPv4 addresses supported" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/__init__.c -#: ports/cxd56/common-hal/microcontroller/__init__.c -#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c -msgid "No bootloader present" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/busio/SPI.c +msgid "Must provide MISO or MOSI pin" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No configuration set" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c +#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c +#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c +msgid "Hardware in use, try alternative pins" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -msgid "No connection: length cannot be determined" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" msgstr "" -#: shared-bindings/board/__init__.c -msgid "No default %q bus" +#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c +msgid "" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -msgid "No free GCLKs" +#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" -#: shared-bindings/os/__init__.c -msgid "No hardware random available" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "timeout must be < 655.35 secs" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in in program" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "non-zero timeout must be > 0.01" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in or out in program" +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: timeout" msgstr "" -#: py/objint.c shared-bindings/time/__init__.c -msgid "No long integer support" +#: ports/nordic/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "No network with that ssid" +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Nordic system firmware out of memory" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No out in program" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %04x" msgstr "" -#: ports/atmel-samd/common-hal/busio/I2C.c -#: ports/espressif/common-hal/busio/I2C.c -#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/busio/I2C.c -msgid "No pull up found on SDA or SCL; check your wiring" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown gatt error: 0x%04x" msgstr "" -#: shared-module/touchio/TouchIn.c -msgid "No pulldown on pin; 1Mohm recommended" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +msgid "" +"Unspecified issue. The pairing request on the other device may have been " +"declined or ignored." msgstr "" -#: py/moderrno.c -msgid "No space left on device" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#, c-format +msgid "Unknown security error: 0x%04x" msgstr "" -#: py/moderrno.c -msgid "No such device" +#: ports/nordic/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge, only level" msgstr "" -#: py/moderrno.c -msgid "No such file/directory" +#: ports/nordic/common-hal/audiobusio/I2SOut.c +msgid "Device in use" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "No timer available" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No usb host port initialized" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Nordic system firmware out of memory" +#: ports/nordic/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" msgstr "" -#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string" +#: ports/nordic/common-hal/busio/UART.c +msgid "Odd parity is not supported" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "Not connected" +#: ports/nordic/common-hal/countio/Counter.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +msgid "All channels in use" msgstr "" -#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c -#: shared-bindings/audiopwmio/PWMAudioOut.c -msgid "Not playing" +#: ports/nordic/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Not supported JPEG standard" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#, c-format -msgid "Number of data_pins must be %d or %d, not %d" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: shared-bindings/util.c -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "%q cannot be changed once mode is set to %q" msgstr "" -#: ports/nordic/common-hal/busio/UART.c -msgid "Odd parity is not supported" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Off" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Ok" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -#, c-format -msgid "Only 8 or 16 bit mono with %dx oversampling supported." +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c +#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c +#: shared-module/synthio/Synthesizer.c +msgid "%q must be of type %q or %q, not %q" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -msgid "Only IPv4 addresses supported" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Program size invalid" msgstr "" -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Only IPv4 sockets supported" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Init program size invalid" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only Windows format, uncompressed BMP supported: given header size is %d" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Buffer elements must be 4 bytes long or less" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Only connectable advertisements can be directed" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched data size" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Only edge detection is available on this hardware" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Out-buffer elements must be <= 4 bytes long" msgstr "" -#: shared-bindings/ipaddress/__init__.c -msgid "Only int or string supported for ip" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "In-buffer elements must be <= 4 bytes long" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/I2C.c +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/I2C.c +#: shared-bindings/busio/SPI.c +msgid "Function requires lock" msgstr "" -#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one %q can be set in deep sleep." +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" msgstr "" -#: ports/espressif/common-hal/espulp/ULPAlarm.c -msgid "Only one %q can be set." +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c +#: ports/stm/common-hal/alarm/touch/TouchAlarm.c +msgid "Touch alarms not available" msgstr "" -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "Only one address is allowed" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" msgstr "" -#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c -#: ports/nordic/common-hal/alarm/time/TimeAlarm.c -#: ports/stm/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "Bit clock and word select must be sequential GPIO pins" msgstr "" -#: ports/espressif/common-hal/alarm/time/TimeAlarm.c -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set." +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Too many channels in sample." msgstr "" -#: shared-module/displayio/ColorConverter.c -msgid "Only one color can be transparent at a time" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Audio source error" msgstr "" -#: py/moderrno.c -msgid "Operation not permitted" +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 16, 24, or 32" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation or feature not supported" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation timed out" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Out of MDNS service slots" +#: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "I2C peripheral in use" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Out of memory" +#: ports/raspberrypi/common-hal/busio/SPI.c +msgid "SPI peripheral in use" msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Out of sockets" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Out-buffer elements must be <= 4 bytes long" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "Pin must be on PWM Channel B" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "PWM restart" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "RISE_AND_FALL not available on this chip" msgstr "" #: ports/raspberrypi/common-hal/countio/Counter.c @@ -1675,85 +1928,102 @@ msgstr "" msgid "PWM slice channel A already in use" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Parameter error" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All state machines in use" msgstr "" -#: ports/espressif/common-hal/audiobusio/__init__.c -msgid "Peripheral in use" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +msgid "timeout waiting for flux" msgstr "" -#: py/moderrno.c -msgid "Permission denied" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: shared-module/floppyio/__init__.c +msgid "timeout waiting for index pulse" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Pin cannot wake from Deep Sleep" +#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +msgid "Pins must be sequential" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Pin count too large" +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +msgid "Invalid %q and %q" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -#: ports/stm/common-hal/pulseio/PulseIn.c -msgid "Pin interrupt already in use" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Failed to add service TXT record" msgstr "" -#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -msgid "Pin is input only" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "Pin must be on PWM Channel B" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to access unaligned IO register" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"Pinout uses %d bytes per element, which consumes more than the ideal %d " -"bytes. If this cannot be avoided, pass allow_inefficient=True to the " -"constructor" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to write to read-only memory" msgstr "" -#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c -msgid "Pins must be sequential" +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +msgid "All timers for this pin are in use" msgstr "" #: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c msgid "Pins must be sequential GPIO pins" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Pins must share PWM slice" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Pin count too large" msgstr "" -#: shared-module/usb/core/Device.c -msgid "Pipe error" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing jmp_pin. %q[%u] jumps on pin" msgstr "" -#: py/builtinhelp.c -msgid "Plus any modules on the filesystem\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] uses extra pin" msgstr "" -#: shared-module/vectorio/Polygon.c -msgid "Polygon needs at least 3 points" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] waits based on pin" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Power dipped. Make sure you are providing enough power." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] waits on input outside of count" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Prefix buffer must be on the heap" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts in more bits than pin count" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts out more bits than pin count" +msgstr "" + +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_set_pin. %q[%u] sets pin(s)" msgstr "" -#: main.c -msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] writes pin(s)" msgstr "" -#: main.c -msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] reads pin(s)" msgstr "" #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -1764,2606 +2034,2635 @@ msgstr "" msgid "Program does OUT without loading OSR" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Program size invalid" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin state conflicts with initial out pin state" msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -msgid "Program too long" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin direction conflicts with initial out pin direction" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Pull not used when direction is output." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "pull masks conflict with direction masks" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "RISE_AND_FALL not available on this chip" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No out in program" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "RLE-compressed BMP not supported" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in in program" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG DeInit Error" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in or out in program" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG Init Error" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched swap flag" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d, not %d" msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "RS485 inversion specified when not in RS485 mode" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +msgid "Data pins must be consecutive" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c -msgid "RTC is not supported on this board" +#: ports/raspberrypi/common-hal/socketpool/Socket.c +msgid "Only IPv4 sockets supported" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "Random number generation error" +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All dma channels in use" msgstr "" -#: shared-bindings/_bleio/__init__.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c -#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c -msgid "Read-only" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" msgstr "" -#: extmod/vfs_fat.c py/moderrno.c -msgid "Read-only filesystem" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Received response was invalid" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "AP could not be started" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Reconnecting" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Only edge detection is available on this hardware" msgstr "" -#: shared-bindings/epaperdisplay/EPaperDisplay.c -msgid "Refresh too soon" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +#: ports/stm/common-hal/pulseio/PulseIn.c +msgid "Pin interrupt already in use" msgstr "" -#: shared-bindings/canio/RemoteTransmissionRequest.c -msgid "RemoteTransmissionRequests limited to 8 bytes" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Pin cannot wake from Deep Sleep" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Requested AES mode is unsupported" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Deep sleep pins must use a rising edge with pulldown" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Requested resource not found" +#: ports/stm/common-hal/analogio/AnalogIn.c +msgid "Invalid ADC Unit value" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "Right channel unsupported" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Device Init Error" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Right format but not supported" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Channel Init Error" msgstr "" -#: main.c -msgid "Running in safe mode! Not running saved code.\n" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "SD card CSD format not supported" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" msgstr "" -#: ports/cxd56/common-hal/sdioio/SDCard.c -msgid "SDCard init" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Another PWMAudioOut is already active" msgstr "" -#: ports/stm/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c #, c-format -msgid "SDIO GetCardInfo Error %d" +msgid "Buffer length %d too big. It must be less than %d" msgstr "" -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO Init Error %x" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Failed to buffer the sample" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c -msgid "SPI configuration failed" +#: ports/stm/common-hal/busio/I2C.c +msgid "I2C init error" msgstr "" #: ports/stm/common-hal/busio/SPI.c msgid "SPI init error" msgstr "" -#: ports/raspberrypi/common-hal/busio/SPI.c -msgid "SPI peripheral in use" -msgstr "" - #: ports/stm/common-hal/busio/SPI.c msgid "SPI re-init" msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "Scale dimensions must divide by 3" +#: ports/stm/common-hal/busio/UART.c +msgid "Internal define error" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Scan already in progress. Stop with stop_scan." +#: ports/stm/common-hal/busio/UART.c +msgid "Could not start interrupt, RX busy" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -msgid "Serializer in use" +#: ports/stm/common-hal/busio/UART.c +msgid "UART write" msgstr "" -#: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname" +#: ports/stm/common-hal/busio/UART.c +msgid "UART de-init" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Size not supported" +#: ports/stm/common-hal/busio/UART.c +msgid "UART re-init" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Slice and value different lengths." +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Temperature read timed out" msgstr "" -#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/TileGrid.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Slices not supported" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Voltage read timed out" msgstr "" -#: ports/espressif/common-hal/socketpool/SocketPool.c -#: ports/raspberrypi/common-hal/socketpool/SocketPool.c -msgid "SocketPool can only be used with wifi.radio" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG Init Error" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Source and destination buffers must be the same length" +#: ports/stm/common-hal/os/__init__.c +msgid "Random number generation error" msgstr "" -#: shared-bindings/paralleldisplaybus/ParallelBus.c -msgid "Specify exactly one of data0 or data_pins" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG DeInit Error" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Stack overflow. Increase stack size." +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "timer re-init" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Supply one of monotonic_time or epoch_time" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "channel re-init" msgstr "" -#: shared-bindings/gnss/GNSS.c -msgid "System entry must be gnss.SatelliteSystem" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "PWM restart" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Temperature read timed out" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "The `microcontroller` module was used to boot into safe mode." +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "SDIO GetCardInfo Error %d" msgstr "" -#: py/obj.c -msgid "The above exception was the direct cause of the following exception:" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid ".show(x) removed. Use .root_group = x" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Brightness not adjustable" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c py/argcheck.c +#: shared-bindings/busdisplay/BusDisplay.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "%q must be %d-%d" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Group already used" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Invalid advertising data" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" +#: ports/zephyr-cp/common-hal/audiobusio/I2SOut.c +#: ports/zephyr-cp/common-hal/busio/I2C.c +#: ports/zephyr-cp/common-hal/busio/SPI.c +#: ports/zephyr-cp/common-hal/busio/UART.c +msgid "Use device tree to define %q devices" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Third-party firmware fatal error." +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork" msgstr "" -#: shared-module/imagecapture/ParallelImageCapture.c -msgid "This microcontroller does not support continuous capture." +#: ports/zephyr-cp/common-hal/usb_hid/Device.c shared-module/usb_hid/Device.c +msgid "USB error" msgstr "" -#: shared-module/paralleldisplaybus/ParallelBus.c -msgid "" -"This microcontroller only supports data0=, not data_pins=, because it " -"requires contiguous pins." +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile height must exactly divide bitmap height" +#: ports/zephyr-cp/common-hal/zephyr_display/Display.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Below minimum frame rate" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c -msgid "Tile index out of bounds" +#: py/argcheck.c +msgid "function doesn't take keyword arguments" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile width must exactly divide bitmap width" +#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c +#: shared-bindings/time/__init__.c +#, c-format +msgid "function takes %d positional arguments but %d were given" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Time is in the past." +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c +#: py/argcheck.c #, c-format -msgid "Timeout is too long: Maximum timeout length is %d seconds" +msgid "function expected at most %d arguments, got %d" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample" +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "" + +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "" + +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c +msgid "unexpected keyword argument '%q'" msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample." +#: py/argcheck.c +msgid "extra keyword arguments given" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -msgid "Too many descriptors" +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c +msgid "argument num/types mismatch" msgstr "" -#: shared-module/displayio/__init__.c -msgid "Too many display busses; forgot displayio.release_displays() ?" +#: py/argcheck.c +msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" -#: shared-module/displayio/__init__.c -msgid "Too many displays" +#: py/argcheck.c +msgid "%q must be %d" msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than %q" +#: py/argcheck.c +msgid "%q must be >= %d" msgstr "" -#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c -#: ports/stm/common-hal/alarm/touch/TouchAlarm.c -msgid "Touch alarms not available" +#: py/argcheck.c shared-bindings/gifio/GifWriter.c +#: shared-module/gifio/OnDiskGif.c +msgid "%q must be <= %d" msgstr "" -#: py/obj.c -msgid "Traceback (most recent call last):\n" +#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c +#: shared-module/synthio/__init__.c +msgid "%q must be of type %q, not %q" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART de-init" +#: py/argcheck.c +msgid "%q length must be %d-%d" msgstr "" -#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c -#: ports/stm/common-hal/busio/UART.c -msgid "UART init" +#: py/argcheck.c +msgid "%q length must be >= %d" msgstr "" -#: ports/raspberrypi/common-hal/busio/UART.c -msgid "UART peripheral in use" +#: py/argcheck.c +msgid "%q length must be <= %d" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART re-init" +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART write" +#: py/argcheck.c shared-module/audiofilters/Filter.c +msgid "%q in %q must be of type %q, not %q" msgstr "" -#: main.c -msgid "UID:" +#: py/asmthumb.c +msgid "too many locals for native method" msgstr "" -#: shared-module/usb_hid/Device.c -msgid "USB busy" +#: py/asmxtensa.c +msgid "ERROR: xtensa %q out of range" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "USB devices need more endpoints than are available." +#: py/asmxtensa.c +msgid "ERROR: %q %q not word-aligned" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "USB devices specify too many interface names." +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" msgstr "" -#: shared-module/usb_hid/Device.c -msgid "USB error" +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID integer value must be 0-0xffff" +#: py/bc.c +msgid "unexpected keyword argument" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID value is not str, int or byte buffer" +#: py/bc.c +msgid "function missing required keyword argument '%q'" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to access unaligned IO register" +#: py/bc.c +msgid "function missing keyword-only argument" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Unable to allocate buffers for signed conversion" +#: py/binary.c py/objarray.c +msgid "bad typecode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Unable to allocate to the heap." +#: py/builtinevex.c +msgid "bad compile mode" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "Unable to create lock" +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" msgstr "" -#: shared-module/i2cdisplaybus/I2CDisplayBus.c -#: shared-module/is31fl3741/IS31FL3741.c -#, c-format -msgid "Unable to find I2C Display at %x" +#: py/builtinhelp.c +msgid "object " msgstr "" -#: py/parse.c -msgid "Unable to init parser" +#: py/builtinhelp.c +msgid " is of type %q\n" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "Unable to read color palette data" +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Visit circuitpython.org for more information.\n" +"\n" +"To list built-in modules type `help(\"modules\")`.\n" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Unable to start mDNS query" +#: py/builtinimport.c +msgid "script compilation not supported" msgstr "" -#: shared-bindings/nvm/ByteArray.c -msgid "Unable to write to nvm." +#: py/builtinimport.c +msgid "can't perform relative import" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to write to read-only memory" +#: py/builtinimport.c +msgid "module not found" msgstr "" -#: shared-bindings/alarm/SleepMemory.c -msgid "Unable to write to sleep_memory." +#: py/builtinimport.c +msgid "no module named '%q'" msgstr "" -#: ports/nordic/common-hal/_bleio/UUID.c -msgid "Unexpected nrfx uuid type" +#: py/builtinimport.c +msgid "relative import" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error at %s:%d: %d" +#: py/compile.c +msgid "can't assign to expression" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error: %d" +#: py/compile.c +msgid "multiple *x in assignment" msgstr "" -#: ports/espressif/common-hal/max3421e/Max3421E.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unknown error code %d" +#: py/compile.c +msgid "non-default argument follows default argument" msgstr "" -#: shared-bindings/wifi/Radio.c -#, c-format -msgid "Unknown failure %d" +#: py/compile.c +msgid "invalid micropython decorator" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown gatt error: 0x%04x" +#: py/compile.c +msgid "invalid arch" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: supervisor/shared/safe_mode.c -msgid "Unknown reason." +#: py/compile.c +msgid "can't delete expression" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown security error: 0x%04x" +#: py/compile.c +msgid "'break'/'continue' outside loop" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error at %s:%d: %d" +#: py/compile.c +msgid "'return' outside function" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %04x" +#: py/compile.c +msgid "import * not at module level" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %d" +#: py/compile.c +msgid "identifier redefined as global" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -#: shared-module/_pixelmap/PixelMap.c -#, c-format -msgid "Unmatched number of items on RHS (expected %d, got %d)." +#: py/compile.c +msgid "no binding for nonlocal found" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "" -"Unspecified issue. Can be that the pairing prompt on the other device was " -"declined or ignored." +#: py/compile.c +msgid "identifier redefined as nonlocal" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Unsupported colorspace" +#: py/compile.c +msgid "can't declare nonlocal in outer code" msgstr "" -#: shared-module/displayio/bus_core.c -msgid "Unsupported display bus type" +#: py/compile.c +msgid "default 'except' must be last" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" +#: py/compile.c +msgid "async for/with outside async function" msgstr "" -#: shared-bindings/hashlib/__init__.c -msgid "Unsupported hash algorithm" +#: py/compile.c +msgid "*x must be assignment target" msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -msgid "Unsupported socket type" +#: py/compile.c +msgid "super() can't find self" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Update failed" +#: py/compile.c +msgid "* arg after **" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length != required fixed length" +#: py/compile.c +msgid "too many args" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length > max_length" +#: py/compile.c +msgid "LHS of keyword arg must be an id" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Version was invalid" +#: py/compile.c +msgid "positional arg after **" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Voltage read timed out" +#: py/compile.c +msgid "positional arg after keyword arg" msgstr "" -#: main.c -msgid "WARNING: Your code filename has two extensions\n" +#: py/compile.c py/parse.c +msgid "invalid syntax" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" +#: py/compile.c +msgid "expecting key:value for dict" msgstr "" -#: py/builtinhelp.c -#, c-format -msgid "" -"Welcome to Adafruit CircuitPython %s!\n" -"\n" -"Visit circuitpython.org for more information.\n" -"\n" -"To list built-in modules type `help(\"modules\")`.\n" +#: py/compile.c +msgid "expecting just a value for set" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "Wi-Fi: " +#: py/compile.c +msgid "'yield' outside function" msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" +#: py/compile.c +msgid "'yield from' inside async function" msgstr "" -#: main.c -msgid "Woken up by alarm.\n" +#: py/compile.c +msgid "'await' outside function" msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Writes not supported on Characteristic" +#: py/compile.c +msgid "unknown type '%q'" msgstr "" -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "You pressed both buttons at start up." +#: py/compile.c +msgid "annotation must be an identifier" msgstr "" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h -msgid "You pressed button A at start up." +#: py/compile.c +msgid "argument name reused" msgstr "" -#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h -msgid "You pressed button DOWN at start up." +#: py/compile.c +msgid "inline assembler must be a function" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up" +#: py/compile.c +msgid "unknown type" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h -#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h -msgid "You pressed the BOOT button at start up." +#: py/compile.c +msgid "return annotation must be an identifier" msgstr "" -#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h -msgid "You pressed the GPIO0 button at start up." +#: py/compile.c +msgid "expecting an assembler instruction" msgstr "" -#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h -msgid "You pressed the Rec button at start up." +#: py/compile.c +msgid "'label' requires 1 argument" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "You pressed the SW38 button at start up." +#: py/compile.c +msgid "label redefined" msgstr "" -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -#: ports/espressif/boards/vidi_x/mpconfigboard.h -msgid "You pressed the VOLUME button at start up." +#: py/compile.c +msgid "'align' requires 1 argument" msgstr "" -#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h -msgid "You pressed the central button at start up." +#: py/compile.c +msgid "'data' requires at least 2 arguments" msgstr "" -#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h -msgid "You pressed the left button at start up." +#: py/compile.c +msgid "'data' requires integer arguments" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the reset button during boot." +#: py/compile.c +msgid "cannot emit native code for this architecture" msgstr "" -#: supervisor/shared/micropython.c -msgid "[truncated due to length]" +#: py/emitbc.c +msgid "bytecode overflow" msgstr "" -#: py/objtype.c -msgid "__init__() should return None" +#: py/emitinlinerv32.c +msgid "can only have up to 4 parameters for RV32 assembly" msgstr "" -#: py/objtype.c -#, c-format -msgid "__init__() should return None, not '%s'" +#: py/emitinlinerv32.c +msgid "parameters must be registers in sequence a0 to a3" msgstr "" -#: py/objobject.c -msgid "__new__ arg must be a user-type" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: expecting %q" msgstr "" -#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c -msgid "a bytes-like object is required" +#: py/emitinlinerv32.c +msgid "opcode '%q': expecting %d arguments" msgstr "" -#: shared-bindings/i2ctarget/I2CTarget.c -msgid "addresses is empty" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: out of range" msgstr "" -#: py/compile.c -msgid "annotation must be an identifier" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: unknown register" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "arange: cannot compute length" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: undefined label '%q'" msgstr "" -#: py/modbuiltins.c -msgid "arg is an empty sequence" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: must not be zero" msgstr "" -#: py/objobject.c -msgid "arg must be user-type" +#: py/emitinlinerv32.c +msgid "invalid RV32 instruction '%q'" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort argument must be an ndarray" +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort is not implemented for flattened arrays" +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "argument must be None, an integer or a tuple of integers" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" msgstr "" -#: py/compile.c -msgid "argument name reused" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" msgstr "" -#: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c -msgid "argument num/types mismatch" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c -msgid "arguments must be ndarrays" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array and index length must be equal" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "array has too many dimensions" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array is too big" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" msgstr "" -#: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c -msgid "array/bytes required on right side" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" msgstr "" -#: py/asmxtensa.c -msgid "asm overflow" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" msgstr "" -#: py/compile.c -msgid "async for/with outside async function" +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get (arg)min/(arg)max of empty sequence" +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get argmin/argmax of an empty sequence" +#: py/emitinlinethumb.c +msgid "branch not in range" msgstr "" -#: py/objstr.c -msgid "attributes not supported" +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "axis is out of bounds" +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -msgid "axis must be None, or an integer" +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d isn't within range %d..%d" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "axis too long" +#: py/emitinlinextensa.c +#, c-format +msgid "%d is not a multiple of %d" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "background value out of range of target" +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" msgstr "" -#: py/builtinevex.c -msgid "bad compile mode" +#: py/emitnative.c +msgid "conversion to object" msgstr "" -#: py/objstr.c -msgid "bad conversion specifier" +#: py/emitnative.c +msgid "local '%q' used before type known" msgstr "" -#: py/objstr.c -msgid "bad format string" +#: py/emitnative.c +msgid "can't load from '%q'" msgstr "" -#: py/binary.c py/objarray.c -msgid "bad typecode" +#: py/emitnative.c +msgid "can't load with '%q' index" msgstr "" #: py/emitnative.c -msgid "binary op %q not implemented" +msgid "local '%q' has type '%q' but source is '%q'" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "bitmap size and depth must match" +#: py/emitnative.c +msgid "can't store '%q'" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "bitmap sizes must match" +#: py/emitnative.c +msgid "can't store to '%q'" msgstr "" -#: extmod/modrandom.c -msgid "bits must be 32 or less" +#: py/emitnative.c +msgid "can't store with '%q' index" msgstr "" -#: shared-bindings/audiomixer/Mixer.c -msgid "bits_per_sample must be 8 or 16" +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" msgstr "" -#: py/emitinlinethumb.c -msgid "branch not in range" +#: py/emitnative.c +msgid "'not' not implemented" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer is smaller than requested size" +#: py/emitnative.c +msgid "can't do unary op of '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer size must be a multiple of element size" +#: py/emitnative.c +msgid "div/mod not implemented for uint" msgstr "" -#: shared-module/struct/__init__.c -msgid "buffer size must match format" +#: py/emitnative.c +msgid "comparison of int and uint" msgstr "" -#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c -msgid "buffer slices must be of equal length" +#: py/emitnative.c +msgid "binary op %q not implemented" msgstr "" - -#: py/modstruct.c shared-module/struct/__init__.c -msgid "buffer too small" + +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "buffer too small for requested bytes" +#: py/emitnative.c +msgid "casting" msgstr "" -#: py/emitbc.c -msgid "bytecode overflow" +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" msgstr "" -#: py/objarray.c -msgid "bytes length not a multiple of item size" +#: py/emitnative.c +msgid "must raise an object" msgstr "" -#: py/objstr.c -msgid "bytes value out of range" +#: py/emitnative.c +msgid "native yield" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is out of range" +#: py/lexer.c +msgid "unicode name escapes" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is read only" +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" msgstr "" -#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c -#: shared-module/vectorio/Rectangle.c -msgid "can only have one parent" +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" msgstr "" -#: py/emitinlinethumb.c -msgid "can only have up to 4 parameters to Thumb assembly" +#: py/modbuiltins.c +msgid "arg is an empty sequence" msgstr "" -#: py/emitinlinextensa.c -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/modbuiltins.c +msgid "ord expects a character" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "can only specify one unknown dimension" +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" msgstr "" -#: py/objtype.c -msgid "can't add special method to already-subclassed class" +#: py/modbuiltins.c +msgid "3-arg pow() not supported" msgstr "" -#: py/compile.c -msgid "can't assign to expression" +#: py/modbuiltins.c +msgid "must use keyword argument for key function" msgstr "" -#: extmod/modasyncio.c -msgid "can't cancel self" +#: py/moderrno.c +msgid "Operation not permitted" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c -msgid "can't convert %q to %q" +#: py/moderrno.c +msgid "No such file/directory" msgstr "" -#: py/obj.c -#, c-format -msgid "can't convert %s to complex" +#: py/moderrno.c +msgid "Input/output error" msgstr "" -#: py/obj.c -#, c-format -msgid "can't convert %s to float" +#: py/moderrno.c +msgid "Permission denied" msgstr "" -#: py/objint.c py/runtime.c -#, c-format -msgid "can't convert %s to int" +#: py/moderrno.c +msgid "File exists" msgstr "" -#: py/objstr.c -msgid "can't convert '%q' object to %q implicitly" +#: py/moderrno.c +msgid "No such device" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "can't convert complex to float" +#: py/moderrno.c +msgid "No space left on device" msgstr "" -#: py/obj.c -msgid "can't convert to complex" +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" msgstr "" -#: py/obj.c -msgid "can't convert to float" +#: py/modmath.c +msgid "negative factorial" msgstr "" -#: py/runtime.c -msgid "can't convert to int" +#: py/modmicropython.c +msgid "schedule queue full" msgstr "" -#: py/objstr.c -msgid "can't convert to str implicitly" +#: py/modstruct.c shared-module/struct/__init__.c +msgid "buffer too small" msgstr "" -#: py/compile.c -msgid "can't declare nonlocal in outer code" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" msgstr "" -#: py/compile.c -msgid "can't delete expression" +#: py/modthread.c +msgid "expecting a dict for keyword args" msgstr "" -#: py/emitnative.c -msgid "can't do binary op between '%q' and '%q'" +#: py/nativeglue.c +msgid "set unsupported" msgstr "" -#: py/emitnative.c -msgid "can't do unary op of '%q'" +#: py/nativeglue.c +msgid "slice unsupported" msgstr "" -#: py/emitnative.c -msgid "can't implicitly convert '%q' to 'bool'" +#: py/nativeglue.c +msgid "float unsupported" msgstr "" -#: py/runtime.c -msgid "can't import name %q" +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c +msgid "can't convert %q to %q" msgstr "" -#: py/emitnative.c -msgid "can't load from '%q'" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" msgstr "" -#: py/emitnative.c -msgid "can't load with '%q' index" +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: py/builtinimport.c -msgid "can't perform relative import" +#: py/obj.c +msgid " File \"%q\", line %d" msgstr "" -#: py/objgenerator.c -msgid "can't send non-None value to a just-started generator" +#: py/obj.c +msgid " File \"%q\"" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "can't set 512 block size" +#: py/obj.c +msgid ", in %q\n" msgstr "" -#: py/objexcept.c py/objnamedtuple.c -msgid "can't set attribute" +#: py/obj.c +msgid "Traceback (most recent call last):\n" msgstr "" -#: py/runtime.c -msgid "can't set attribute '%q'" +#: py/obj.c +msgid "can't convert to float" msgstr "" -#: py/emitnative.c -msgid "can't store '%q'" +#: py/obj.c +#, c-format +msgid "can't convert %s to float" msgstr "" -#: py/emitnative.c -msgid "can't store to '%q'" +#: py/obj.c +msgid "can't convert to complex" msgstr "" -#: py/emitnative.c -msgid "can't store with '%q' index" +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from automatic field numbering to manual field specification" +#: py/obj.c +msgid "expected tuple/list" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from manual field specification to automatic field numbering" +#: py/obj.c +#, c-format +msgid "object '%s' isn't a tuple or list" msgstr "" -#: py/objcomplex.c -msgid "can't truncate-divide a complex number" +#: py/obj.c +msgid "tuple/list has wrong length" msgstr "" -#: extmod/modasyncio.c -msgid "can't wait" +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot assign new shape" +#: py/obj.c +msgid "indices must be integers" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "cannot cast output with casting rule" +#: py/obj.c +msgid "%q indices must be integers, not %s" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex to dtype" +#: py/obj.c +msgid "object has no len" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex type" +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" msgstr "" -#: py/objtype.c -msgid "cannot create '%q' instances" +#: py/obj.c +msgid "object doesn't support item deletion" msgstr "" -#: py/objtype.c -msgid "cannot create instance" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item deletion" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot delete array elements" +#: py/obj.c +msgid "object isn't subscriptable" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot reshape array" +#: py/obj.c +#, c-format +msgid "'%s' object isn't subscriptable" msgstr "" -#: py/emitnative.c -msgid "casting" +#: py/obj.c +msgid "object doesn't support item assignment" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "channel re-init" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item assignment" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "chars buffer too small" +#: py/obj.c +msgid "object with buffer protocol required" msgstr "" -#: py/modbuiltins.c -msgid "chr() arg not in range(0x110000)" +#: py/objarray.c +msgid "bytes length not a multiple of item size" msgstr "" -#: py/modbuiltins.c -msgid "chr() arg not in range(256)" +#: py/objarray.c py/objstr.c +msgid "string argument without an encoding" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "clip point must be (x,y) tuple" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" msgstr "" -#: shared-bindings/msgpack/ExtType.c -msgid "code outside range 0~127" +#: py/objarray.c py/objstr.c +msgid "substring not found" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a buffer, tuple, list, or int" +#: py/objarray.c +msgid "lhs and rhs should be compatible" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color must be between 0x000000 and 0xffffff" +#: py/objarray.c +msgid "memoryview offset too large" msgstr "" -#: py/emitnative.c -msgid "comparison of int and uint" +#: py/objcomplex.c +msgid "can't truncate-divide a complex number" msgstr "" #: py/objcomplex.c msgid "complex divide by zero" msgstr "" -#: py/objfloat.c py/parsenum.c -msgid "complex values not supported" +#: py/objcomplex.c +msgid "0.0 to a complex power" msgstr "" -#: extmod/modzlib.c -msgid "compression header" +#: py/objdeque.c +msgid "full" msgstr "" -#: py/emitnative.c -msgid "conversion to object" +#: py/objdeque.c +msgid "empty" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be linear arrays" +#: py/objdict.c +msgid "dict update sequence has wrong length" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be ndarrays" +#: py/objexcept.c py/objnamedtuple.c +msgid "can't set attribute" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must not be empty" +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "corrupted file" +#: py/objgenerator.c +msgid "generator already executing" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "could not invert Vandermonde matrix" +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "couldn't determine SD card version" +#: py/objgenerator.c py/runtime.c +msgid "generator raised StopIteration" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "cross is defined for 1D arrays of length 3" +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be iterable" +#: py/objint.c py/runtime.c +#, c-format +msgid "can't convert %s to int" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be of equal length" +#: py/objint.c +msgid "float too big" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: py/objint.c #, c-format -msgid "data pin #%d in use" +msgid "value must fit in %d byte(s)" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "data type not understood" +#: py/objint.c shared-bindings/time/__init__.c +msgid "No long integer support" msgstr "" -#: py/parsenum.c -msgid "decimal numbers not supported" +#: py/objint.c py/sequence.c +msgid "small int overflow" msgstr "" -#: py/compile.c -msgid "default 'except' must be last" +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c +msgid "%q=%q" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "default is not a function" +#: py/objint_longlong.c py/parsenum.c +msgid "result overflows long long storage" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative shift count" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" msgstr "" -#: py/objdict.c -msgid "dict update sequence has wrong length" +#: py/objint_longlong.c py/objint_mpz.c +msgid "overflow converting long int to machine word" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "diff argument must be an ndarray" +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "differentiation order out of range" +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "dimensions do not match" +#: py/objobject.c +msgid "__new__ arg must be a user-type" msgstr "" -#: py/emitnative.c -msgid "div/mod not implemented for uint" +#: py/objobject.c +msgid "arg must be user-type" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "divide by zero" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" msgstr "" -#: py/runtime.c -msgid "division by zero" +#: py/objslice.c +msgid "Cannot subclass slice" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "dtype must be float, or complex" +#: py/objstr.c +msgid "bytes value out of range" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "dtype of int32 is not supported" +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" msgstr "" -#: py/objdeque.c -msgid "empty" +#: py/objstr.c +msgid "empty separator" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "empty file" +#: py/objstr.c +msgid "rsplit(None,n)" msgstr "" -#: extmod/modasyncio.c extmod/modheapq.c -msgid "empty heap" +#: py/objstr.c +msgid "bad format string" msgstr "" #: py/objstr.c -msgid "empty separator" +#, c-format +msgid "unmatched '%c' in format" msgstr "" -#: shared-bindings/random/__init__.c -msgid "empty sequence" +#: py/objstr.c +msgid "bad conversion specifier" msgstr "" #: py/objstr.c msgid "end of format while looking for conversion specifier" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "epoch_time not supported on this board" +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" msgstr "" -#: ports/nordic/common-hal/busio/UART.c -#, c-format -msgid "error = 0x%08lX" +#: py/objstr.c +msgid "expected ':' after format specifier" msgstr "" -#: py/runtime.c -msgid "exceptions must derive from BaseException" +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" msgstr "" #: py/objstr.c -msgid "expected ':' after format specifier" +msgid "%q index out of range" msgstr "" -#: py/obj.c -msgid "expected tuple/list" +#: py/objstr.c +msgid "attributes not supported" msgstr "" -#: py/modthread.c -msgid "expecting a dict for keyword args" +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" msgstr "" -#: py/compile.c -msgid "expecting an assembler instruction" +#: py/objstr.c +msgid "invalid format specifier" msgstr "" -#: py/compile.c -msgid "expecting just a value for set" +#: py/objstr.c +msgid "sign not allowed in string format specifier" msgstr "" -#: py/compile.c -msgid "expecting key:value for dict" +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "ext_hook is not a function" +#: py/objstr.c +msgid "unknown format code '%c' for object of type '%q'" msgstr "" -#: py/argcheck.c -msgid "extra keyword arguments given" +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" msgstr "" -#: py/argcheck.c -msgid "extra positional arguments given" +#: py/objstr.c +msgid "format needs a dict" msgstr "" -#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c -#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c -msgid "file must be a file opened in byte mode" +#: py/objstr.c +msgid "incomplete format key" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "file write is not available" +#: py/objstr.c +msgid "incomplete format" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" +#: py/objstr.c +msgid "format string needs more arguments" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "first argument must be a callable" +#: py/objstr.c +#, c-format +msgid "%%c needs int or char" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "first argument must be a function" +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "first argument must be a tuple of ndarrays" +#: py/objstr.c +msgid "format string didn't convert all arguments" msgstr "" -#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c -msgid "first argument must be an ndarray" +#: py/objstr.c +msgid "non-hex digit" msgstr "" -#: py/objtype.c -msgid "first argument to super() must be type" +#: py/objstr.c +msgid "can't convert to str implicitly" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "first two arguments must be ndarrays" +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "flattening order must be either 'C', or 'F'" +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "flip argument must be an ndarray" +#: py/objstrunicode.c +msgid "string index out of range" msgstr "" -#: py/objint.c -msgid "float too big" +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." msgstr "" -#: py/nativeglue.c -msgid "float unsupported" +#: py/objtype.c +msgid "__init__() should return None" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "font must be 2048 bytes long" +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" msgstr "" -#: extmod/moddeflate.c -msgid "format" +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" msgstr "" -#: py/objstr.c -msgid "format requires a dict" +#: py/objtype.c py/runtime.c +msgid "object not callable" msgstr "" -#: py/objdeque.c -msgid "full" +#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c +msgid "'%q' object isn't callable" msgstr "" -#: py/argcheck.c -msgid "function doesn't take keyword arguments" +#: py/objtype.c +msgid "type takes 1 or 3 arguments" msgstr "" -#: py/argcheck.c -#, c-format -msgid "function expected at most %d arguments, got %d" +#: py/objtype.c +msgid "can't create instance" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "function got multiple values for argument '%q'" +#: py/objtype.c +msgid "can't create '%q' instances" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "function has the same sign at the ends of interval" +#: py/objtype.c +msgid "can't add special method to already-subclassed class" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "function is defined for ndarrays only" +#: py/objtype.c +msgid "type isn't an acceptable base type" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "function is implemented for ndarrays only" +#: py/objtype.c +msgid "type '%q' isn't an acceptable base type" msgstr "" -#: py/argcheck.c -#, c-format -msgid "function missing %d required positional arguments" +#: py/objtype.c +msgid "multiple inheritance not supported" msgstr "" -#: py/bc.c -msgid "function missing keyword-only argument" +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" msgstr "" -#: py/bc.c -msgid "function missing required keyword argument '%q'" +#: py/objtype.c +msgid "first argument to super() must be type" msgstr "" -#: py/bc.c -#, c-format -msgid "function missing required positional argument #%d" +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c -#: shared-bindings/time/__init__.c -#, c-format -msgid "function takes %d positional arguments but %d were given" +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" msgstr "" -#: py/objgenerator.c -msgid "generator already executing" +#: py/parse.c +msgid "not a constant" msgstr "" -#: py/objgenerator.c -msgid "generator ignored GeneratorExit" +#: py/parse.c +msgid "Unable to init parser" msgstr "" -#: py/objgenerator.c py/runtime.c -msgid "generator raised StopIteration" +#: py/parse.c +msgid "unexpected indent" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "graphic must be 2048 bytes long" +#: py/parse.c +msgid "unindent doesn't match any outer indent level" msgstr "" -#: extmod/modhashlib.c -msgid "hash is final" +#: py/parse.c +msgid "malformed f-string" msgstr "" -#: extmod/modheapq.c -msgid "heap must be a list" +#: py/parsenum.c +msgid "invalid syntax for integer" msgstr "" -#: py/compile.c -msgid "identifier redefined as global" +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" msgstr "" -#: py/compile.c -msgid "identifier redefined as nonlocal" +#: py/parsenum.c +msgid "invalid syntax for number" msgstr "" -#: py/compile.c -msgid "import * not at module level" +#: py/parsenum.c +msgid "decimal numbers not supported" msgstr "" #: py/persistentcode.c -msgid "incompatible .mpy arch" +msgid "incompatible .mpy file" msgstr "" #: py/persistentcode.c -msgid "incompatible .mpy file" +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" msgstr "" -#: py/objstr.c -msgid "incomplete format" +#: py/persistentcode.c +msgid "native code in .mpy unsupported" msgstr "" -#: py/objstr.c -msgid "incomplete format key" +#: py/persistentcode.c +msgid "incompatible .mpy arch" msgstr "" -#: extmod/modbinascii.c -msgid "incorrect padding" +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "'%q' object does not support '%q'" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c -msgid "index is out of bounds" +#: py/qstr.c +msgid "name too long" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "index must be tuple or int" +#: py/runtime.c +msgid "name not defined" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: py/runtime.c +msgid "name '%q' isn't defined" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: py/runtime.c +msgid "unsupported type for operator" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "indices must be integers, slices, or Boolean lists" +#: py/runtime.c +msgid "unsupported type for %q: '%s'" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" +#: py/runtime.c +msgid "unsupported types for %q: '%q', '%q'" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "initial values must be iterable" +#: py/runtime.c +msgid "wrong number of values to unpack" msgstr "" -#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c -msgid "initial_value length is wrong" +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" msgstr "" -#: py/compile.c -msgid "inline assembler must be a function" +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output dimensions differ" +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output shapes differ" +#: py/runtime.c +msgid "module '%q' has no attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input argument must be an integer, a tuple, or a list" +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "input array length must be power of 2" +#: py/runtime.c +msgid "can't set attribute '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input arrays are not compatible" +#: py/runtime.c +msgid "object not iterable" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input data must be an iterable" +#: py/runtime.c +msgid "'%q' object isn't iterable" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input dtype must be float or complex" +#: py/runtime.c +msgid "object not an iterator" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input is not iterable" +#: py/runtime.c +msgid "'%q' object isn't an iterator" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "input matrix is asymmetric" +#: py/runtime.c +msgid "exceptions must derive from BaseException" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "input matrix is singular" +#: py/runtime.c +msgid "can't import name %q" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input must be 1- or 2-d" +#: py/runtime.c +msgid "memory allocation failed, heap is locked" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be a 1D ndarray" +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c -msgid "input must be a dense ndarray" +#: py/runtime.c +msgid "can't convert to int" msgstr "" -#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c -msgid "input must be an ndarray" +#: py/runtime.c +msgid "division by zero" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be an ndarray, or a scalar" +#: py/runtime.c +msgid "maximum recursion depth exceeded" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "input must be one-dimensional" +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "input must be square matrix" +#: py/stream.c shared-bindings/getpass/__init__.c +msgid "stream operation not supported" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "input must be tuple, list, range, or ndarray" +#: py/vm.c +msgid "local variable referenced before assignment" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input vectors must be of equal length" +#: py/vm.c +msgid "no active exception to reraise" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "interp is defined for 1D iterables of equal length" +#: py/vm.c +msgid "opcode" msgstr "" #: shared-bindings/_bleio/Adapter.c -#, c-format -msgid "interval must be in range %s-%s" +msgid "Cannot create a new Adapter; use _bleio.adapter;" msgstr "" -#: py/compile.c -msgid "invalid arch" +#: shared-bindings/_bleio/Adapter.c +msgid "Could not set address" msgstr "" -#: shared-bindings/bitmaptools/__init__.c +#: shared-bindings/_bleio/Adapter.c #, c-format -msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +msgid "interval must be in range %s-%s" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid cert" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot have scan responses for extended, connectable advertisements." msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element size %d for bits_per_pixel %d\n" +#: shared-bindings/_bleio/Adapter.c +msgid "Only connectable advertisements can be directed" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element_size %d, must be, 1, 2, or 4" +#: shared-bindings/_bleio/Adapter.c +msgid "non-zero timeout must be >= interval" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "invalid exception" +#: shared-bindings/_bleio/Adapter.c +msgid "window must be <= interval" msgstr "" -#: py/objstr.c -msgid "invalid format specifier" +#: shared-bindings/_bleio/Adapter.c +msgid "Prefix buffer must be on the heap" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "invalid hostname" +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid key" +#: shared-bindings/_bleio/Connection.c +msgid "" +"Connection has been disconnected and can no longer be used. Create a new " +"connection." msgstr "" -#: py/compile.c -msgid "invalid micropython decorator" +#: shared-bindings/_bleio/PacketBuffer.c +#, c-format +msgid "Buffer too short by %d bytes" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c -msgid "invalid setting" +#: shared-bindings/_bleio/PacketBuffer.c +msgid "No connection: length cannot be determined" msgstr "" -#: shared-bindings/random/__init__.c -msgid "invalid step" +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" msgstr "" -#: py/compile.c py/parse.c -msgid "invalid syntax" +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" msgstr "" -#: py/parsenum.c -msgid "invalid syntax for integer" +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" msgstr "" -#: py/parsenum.c -#, c-format -msgid "invalid syntax for integer with base %d" +#: shared-bindings/_bleio/__init__.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c +#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c +msgid "Read-only" msgstr "" -#: py/parsenum.c -msgid "invalid syntax for number" +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 1 must be a class" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 2 must be a class or a tuple of classes" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "iterations did not converge" +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" msgstr "" -#: py/objstr.c -msgid "join expects a list of str/bytes objects consistent with self object" +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" msgstr "" -#: py/argcheck.c -msgid "keyword argument(s) not implemented - use normal args instead" +#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +msgid "Pin is input only" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -msgid "label '%q' not defined" +#: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" -#: py/compile.c -msgid "label redefined" +#: shared-bindings/aesio/aes.c +msgid "Key must be 16, 24, or 32 bytes long" msgstr "" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" +#: shared-bindings/aesio/aes.c +msgid "Requested AES mode is unsupported" msgstr "" -#: py/objarray.c -msgid "lhs and rhs should be compatible" +#: shared-bindings/aesio/aes.c +msgid "Source and destination buffers must be the same length" msgstr "" -#: py/emitnative.c -msgid "local '%q' has type '%q' but source is '%q'" +#: shared-bindings/aesio/aes.c +msgid "ECB only operates on 16 bytes at a time" msgstr "" -#: py/emitnative.c -msgid "local '%q' used before type known" +#: shared-bindings/aesio/aes.c +msgid "CBC blocks must be multiples of 16 bytes" msgstr "" -#: py/vm.c -msgid "local variable referenced before assignment" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "loopback + silent mode not supported by peripheral" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS already initialized" +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS only works with built-in WiFi" +#: shared-bindings/alarm/__init__.c +msgid "Expected a kind of %q" msgstr "" -#: py/parse.c -msgid "malformed f-string" +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "map buffer too small" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" msgstr "" -#: py/modmath.c shared-bindings/math/__init__.c -msgid "math domain error" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "matrix is not positive definite" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." msgstr "" -#: ports/espressif/common-hal/_bleio/Descriptor.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -#, c-format -msgid "max_length must be 0-%d when fixed_length is %s" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c -msgid "maximum number of dimensions is " +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c shared-bindings/mcp4822/MCP4822.c +#: shared-bindings/usb_audio/USBMicrophone.c +msgid "Not playing" msgstr "" -#: py/runtime.c -msgid "maximum recursion depth exceeded" +#: shared-bindings/audiobusio/PDMIn.c +msgid "%q must be multiple of 8." msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter must be > 0" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Cannot record to a file" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter should be > 0" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Destination capacity is smaller than destination_length." msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "median argument must be an ndarray" +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: py/runtime.c -#, c-format -msgid "memory allocation failed, allocating %u bytes" +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: py/runtime.c -msgid "memory allocation failed, heap is locked" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" msgstr "" -#: py/objarray.c -msgid "memoryview offset too large" +#: shared-bindings/audiocore/RawSample.c +msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" -#: py/objarray.c -msgid "memoryview: length is not a multiple of itemsize" +#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c +msgid "file must be a file opened in byte mode" msgstr "" -#: extmod/modtime.c -msgid "mktime needs a tuple of length 8 or 9" +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/Flanger.c +#: shared-bindings/audiodelays/GranularPitchShift.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c +#: shared-bindings/audiomixer/Mixer.c +msgid "bits_per_sample must be 8 or 16" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "mode must be complete, or reduced" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" msgstr "" -#: py/builtinimport.c -msgid "module not found" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" msgstr "" -#: ports/espressif/common-hal/wifi/Monitor.c -msgid "monitor init failed" +#: shared-bindings/audioi2sin/I2SIn.c +#, c-format +msgid "invalid destination buffer, must be an array of type: %c" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "more degrees of freedom than data points" +#: shared-bindings/audioio/AudioOut.c +msgid "%q and %q must be different" msgstr "" -#: py/compile.c -msgid "multiple *x in assignment" +#: shared-bindings/bitmapfilter/__init__.c +msgid "" +"weights must be a sequence with an odd square number of elements (usually 9 " +"or 25)" msgstr "" -#: py/objtype.c -msgid "multiple bases have instance lay-out conflict" +#: shared-bindings/bitmapfilter/__init__.c +msgid "weights must be an object of type %q, %q, %q, or %q, not %q " msgstr "" -#: py/objtype.c -msgid "multiple inheritance not supported" +#: shared-bindings/bitmaptools/__init__.c +msgid "clip point must be (x,y) tuple" msgstr "" -#: py/emitnative.c -msgid "must raise an object" +#: shared-bindings/bitmaptools/__init__.c +msgid "source palette too large" msgstr "" -#: py/modbuiltins.c -msgid "must use keyword argument for key function" +#: shared-bindings/bitmaptools/__init__.c +msgid "Bitmap size and bits per value must match" msgstr "" -#: py/runtime.c -msgid "name '%q' is not defined" +#: shared-bindings/bitmaptools/__init__.c +msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" -#: py/runtime.c -msgid "name not defined" +#: shared-bindings/bitmaptools/__init__.c +msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -#: py/qstr.c -msgid "name too long" +#: shared-bindings/bitmaptools/__init__.c +msgid "Unsupported colorspace" msgstr "" -#: py/persistentcode.c -msgid "native code in .mpy unsupported" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap size must match the other bitmaps" msgstr "" -#: py/asmthumb.c -msgid "native method too big" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap must have 8 bits per pixel" msgstr "" -#: py/emitnative.c -msgid "native yield" +#: shared-bindings/bitmaptools/__init__.c +msgid "out of range of target" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "ndarray length overflows" +#: shared-bindings/bitmaptools/__init__.c +msgid "value out of range of target" msgstr "" -#: py/runtime.c -#, c-format -msgid "need more than %d values to unpack" +#: shared-bindings/bitmaptools/__init__.c +msgid "background value out of range of target" msgstr "" -#: py/modmath.c -msgid "negative factorial" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" msgstr "" -#: py/objint_longlong.c py/objint_mpz.c py/runtime.c -msgid "negative power with no float support" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" msgstr "" -#: py/objint_mpz.c py/runtime.c -msgid "negative shift count" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "nested index must be int" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element size %d for bits_per_pixel %d\n" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no SD card" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" -#: py/vm.c -msgid "no active exception to reraise" +#: shared-bindings/bitmaptools/__init__.c +msgid "bitmap sizes must match" msgstr "" -#: py/compile.c -msgid "no binding for nonlocal found" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 2 or 65536" msgstr "" - -#: shared-module/msgpack/__init__.c -msgid "no default packer" + +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 65536" msgstr "" -#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c -msgid "no default seed" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 8" msgstr "" -#: py/builtinimport.c -msgid "no module named '%q'" +#: shared-bindings/bitmaptools/__init__.c +msgid "unsupported colorspace for dither" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no response from SD card" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c -msgid "no such attribute" +#: shared-bindings/board/__init__.c +msgid "No default %q bus" msgstr "" -#: ports/espressif/common-hal/_bleio/Connection.c -#: ports/nordic/common-hal/_bleio/Connection.c -msgid "non-UUID found in service_uuids_whitelist" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c +msgid "Display rotation must be in 90 degree increments" msgstr "" -#: py/compile.c -msgid "non-default argument follows default argument" +#: shared-bindings/busdisplay/BusDisplay.c +msgid "%q must be 1 when %q is True" msgstr "" -#: py/objstr.c -msgid "non-hex digit found" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Display must have a 16 bit colorspace." msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "non-zero timeout must be > 0.01" +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c +msgid "tx and rx cannot both be None" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "non-zero timeout must be >= interval" +#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "not a 128-bit UUID" +#: shared-bindings/canio/RemoteTransmissionRequest.c +msgid "RemoteTransmissionRequests limited to 8 bytes" msgstr "" -#: py/parse.c -msgid "not a constant" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Cannot set value when direction is input." msgstr "" -#: py/objstr.c -msgid "not all arguments converted during string formatting" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Drive mode not used when direction is input." msgstr "" -#: py/objstr.c -msgid "not enough arguments for format string" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Pull not used when direction is output." msgstr "" -#: extmod/ulab/code/numpy/carray/carray_tools.c -msgid "not implemented for complex dtype" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" msgstr "" -#: extmod/ulab/code/numpy/bitwise.c -msgid "not supported for input types" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "number of points must be at least 2" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" msgstr "" -#: py/builtinhelp.c -msgid "object " +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" msgstr "" -#: py/obj.c -#, c-format -msgid "object '%s' isn't a tuple or list" +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +msgid "Slices not supported" msgstr "" -#: py/obj.c -msgid "object doesn't support item assignment" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: py/obj.c -msgid "object doesn't support item deletion" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: py/obj.c -msgid "object has no len" +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: py/obj.c -msgid "object isn't subscriptable" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer, tuple, list, or int" msgstr "" -#: py/runtime.c -msgid "object not an iterator" +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c +msgid "unsupported %q type" msgstr "" -#: py/objtype.c py/runtime.c -msgid "object not callable" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" msgstr "" -#: py/sequence.c shared-bindings/displayio/Group.c -msgid "object not in sequence" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" msgstr "" -#: py/runtime.c -msgid "object not iterable" +#: shared-bindings/displayio/TileGrid.c +msgid "New bitmap must be same size as old bitmap" msgstr "" -#: py/obj.c -#, c-format -msgid "object of type '%s' has no len()" +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" msgstr "" -#: py/obj.c -msgid "object with buffer protocol required" +#: shared-bindings/dualbank/__init__.c +msgid "offset must be >= 0" msgstr "" -#: py/objstr.c -msgid "odd-length string" +#: shared-bindings/epaperdisplay/EPaperDisplay.c +msgid "Refresh too soon" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "off" +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Buffer is not a bytearray." msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "offset is too large" +#: shared-bindings/gnss/GNSS.c +msgid "System entry must be gnss.SatelliteSystem" msgstr "" -#: shared-bindings/dualbank/__init__.c -msgid "offset must be >= 0" +#: shared-bindings/hashlib/__init__.c +msgid "Unsupported hash algorithm" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "offset must be non-negative and no greater than buffer length" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only bit_depth=16 is supported" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only mono is supported" +#: shared-bindings/i2ctarget/I2CTarget.c +msgid "addresses is empty" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "only ndarrays can be concatenated" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only oversample=64 is supported" +#: shared-bindings/ipaddress/IPv4Address.c +#, c-format +msgid "Address must be %d bytes long" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only sample_rate=16000 is supported" +#: shared-bindings/ipaddress/__init__.c +msgid "Only int or string supported for ip" msgstr "" -#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "only slices with step=1 (aka None) are supported" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "width must be greater than zero" msgstr "" -#: py/vm.c -msgid "opcode" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "Scale dimensions must divide by 3" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c -msgid "operands could not be broadcast together" +#: shared-bindings/is31fl3741/IS31FL3741.c +msgid "Mapping must be a tuple" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for 2D arrays only" +#: shared-bindings/jpegio/JpegDecoder.c +msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for ndarrays only" +#: shared-bindings/mdns/Server.c +msgid "" +"Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is implemented for 1D Boolean arrays only" +#: shared-bindings/memorymap/AddressRange.c +msgid "Address range wraps around" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "operation is not implemented on ndarrays" +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is not supported for given type" +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "operation not supported for the input types" +#: shared-bindings/msgpack/ExtType.c +msgid "code outside range 0~127" msgstr "" -#: py/modbuiltins.c -msgid "ord expects a character" +#: shared-bindings/msgpack/__init__.c +msgid "default is not a function" msgstr "" -#: py/modbuiltins.c -#, c-format -msgid "ord() expected a character, but string of length %d found" +#: shared-bindings/msgpack/__init__.c +msgid "ext_hook is not a function" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out array is too small" +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "out has wrong type" +#: shared-bindings/os/__init__.c +msgid "No hardware random available" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for complex dtype" +#: shared-bindings/paralleldisplaybus/ParallelBus.c +msgid "Specify exactly one of data0 or data_pins" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for function" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out must be a float dense array" +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be an ndarray" +#: shared-bindings/pwmio/PWMOut.c +msgid "Conflicting settings for shared resource" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be of float dtype" +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "out of range of target" +#: shared-bindings/random/__init__.c +msgid "invalid step" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array has wrong type" +#: shared-bindings/random/__init__.c +msgid "empty sequence" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array must be contiguous" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" msgstr "" -#: py/objint_mpz.c -msgid "overflow converting long int to machine word" +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: py/modstruct.c +#: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format -msgid "pack expected %d items for packing (got %d)" +msgid "rgb_pins[%d] is not on the same port as clock" msgstr "" -#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c -msgid "palette must be 32 bytes long" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" msgstr "" -#: py/emitinlinextensa.c -msgid "parameters must be registers in sequence a2 to a5" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" msgstr "" -#: py/emitinlinethumb.c -msgid "parameters must be registers in sequence r0 to r3" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" -#: extmod/vfs_posix_file.c -msgid "poll on file not available on win32" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" -#: ports/espressif/common-hal/pulseio/PulseIn.c -msgid "pop from an empty PulseIn" +#: shared-bindings/socketpool/Socket.c +msgid "port must be >= 0" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/pulseio/PulseIn.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c -#: shared-bindings/ps2io/Ps2.c -msgid "pop from empty %q" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "buffer too small for requested bytes" msgstr "" -#: shared-bindings/socketpool/Socket.c -msgid "port must be >= 0" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" msgstr "" -#: py/compile.c -msgid "positional arg after **" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." msgstr "" -#: py/compile.c -msgid "positional arg after keyword arg" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" msgstr "" -#: py/objint_mpz.c -msgid "pow() 3rd argument cannot be 0" +#: shared-bindings/storage/__init__.c shared-bindings/usb_audio/__init__.c +#: shared-bindings/usb_cdc/__init__.c shared-bindings/usb_hid/__init__.c +#: shared-bindings/usb_midi/__init__.c shared-bindings/usb_video/__init__.c +msgid "Cannot change USB devices now" msgstr "" -#: py/objint_mpz.c -msgid "pow() with 3 arguments requires integers" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c +msgid "File not found" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "pull masks conflict with direction masks" +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" msgstr "" -#: py/parse.c -msgid "raw f-strings are not supported" +#: shared-bindings/traceback/__init__.c +msgid "Supply both or neither of %q and %q" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "real and imaginary parts must be of equal length" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" msgstr "" -#: py/builtinimport.c -msgid "relative import" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" +#: shared-bindings/usb_audio/USBSpeaker.c +msgid "destination must be an array of type 'h'" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "results cannot be cast to specified type" +#: shared-bindings/usb_audio/__init__.c +msgid "At least one of microphone and speaker must be enabled" msgstr "" -#: py/compile.c -msgid "return annotation must be an identifier" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/emitnative.c -msgid "return expected '%q' but got '%q'" +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] duplicates another pin assignment" +#: shared-bindings/warnings/__init__.c +msgid "%q must be a subclass of %q" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] is not on the same port as clock" +#: shared-bindings/wifi/Monitor.c +msgid "%q out of bounds" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "roll argument must be an ndarray" +#: shared-bindings/wifi/Radio.c +msgid "Invalid hex password" msgstr "" -#: py/objstr.c -msgid "rsplit(None,n)" +#: shared-bindings/wifi/Radio.c +msgid "invalid hostname" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -msgid "sampling rate out of range" +#: shared-bindings/wifi/Radio.c +msgid "Invalid MAC address" msgstr "" -#: py/modmicropython.c -msgid "schedule queue full" +#: shared-bindings/wifi/Radio.c +msgid "AuthMode.OPEN is not used with password" msgstr "" -#: py/builtinimport.c -msgid "script compilation not supported" +#: shared-bindings/wifi/Radio.c +msgid "Invalid BSSID" msgstr "" -#: py/nativeglue.c -msgid "set unsupported" +#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c +msgid "Authentication failure" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "shape must be None, and integer or a tuple of integers" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "shape must be integer or tuple of integers" +#: shared-bindings/wifi/Radio.c +#, c-format +msgid "Unknown failure %d" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "short read" +#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#, c-format +msgid "No I2C device at address: 0x%x" msgstr "" -#: py/objstr.c -msgid "sign not allowed in string format specifier" +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" msgstr "" -#: py/objstr.c -msgid "sign not allowed with integer format specifier 'c'" +#: shared-module/audiocore/__init__.c shared-module/usb_audio/USBMicrophone.c +msgid "The sample's %q does not match" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "size is defined for ndarrays only" +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "size must match out.shape when used together" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Only 8/16-bit mono/stereo is supported" msgstr "" -#: py/nativeglue.c -msgid "slice unsupported" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "buffer_size too small for source" msgstr "" -#: py/objint.c py/sequence.c -msgid "small int overflow" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Couldn't allocate decoder" msgstr "" -#: main.c -msgid "soft reboot\n" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Failed to parse MP3 file" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "sort argument must be an ndarray" +#: shared-module/bitbangio/I2C.c +msgid "%q too long" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos array must be of shape (n_section, 6)" +#: shared-module/bitmapfilter/__init__.c +msgid "bitmap size and depth must match" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos[:, 3] should be all ones" +#: shared-module/bitmapfilter/__init__.c +msgid "unsupported bitmap depth" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sosfilt requires iterable arguments" +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source palette too large" +#: shared-module/displayio/ColorConverter.c +msgid "Only one color can be transparent at a time" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 2 or 65536" +#: shared-module/displayio/Group.c +msgid "Layer already in a group" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 65536" +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 8" +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" msgstr "" -#: extmod/modre.c -msgid "splitting with sub-captures" +#: shared-module/displayio/OnDiskBitmap.c +msgid "RLE-compressed BMP not supported" msgstr "" -#: py/objstr.c -msgid "start/end indices" +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" msgstr "" -#: shared-bindings/random/__init__.c -msgid "stop not reachable from start" +#: shared-module/displayio/__init__.c +msgid "Too many displays" msgstr "" -#: py/stream.c shared-bindings/getpass/__init__.c -msgid "stream operation not supported" +#: shared-module/displayio/__init__.c +msgid "Too many display busses; forgot displayio.release_displays() ?" msgstr "" -#: py/objarray.c py/objstr.c -msgid "string argument without an encoding" +#: shared-module/displayio/bus_core.c +msgid "Unsupported display bus type" msgstr "" -#: py/objstrunicode.c -msgid "string index out of range" +#: shared-module/gifio/GifWriter.c +msgid "unsupported colorspace for GifWriter" msgstr "" -#: py/objstrunicode.c +#: shared-module/i2cdisplaybus/I2CDisplayBus.c +#: shared-module/is31fl3741/IS31FL3741.c #, c-format -msgid "string indices must be integers, not %s" +msgid "Unable to find I2C Display at %x" msgstr "" -#: py/objarray.c py/objstr.c -msgid "substring not found" +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" msgstr "" -#: py/compile.c -msgid "super() can't find self" +#: shared-module/imagecapture/ParallelImageCapture.c +msgid "This microcontroller does not support continuous capture." msgstr "" -#: extmod/modjson.c -msgid "syntax error in JSON" +#: shared-module/is31fl3741/FrameBuffer.c +msgid "LED mappings must match display size" msgstr "" -#: extmod/modtime.c -msgid "ticks interval overflow" +#: shared-module/jpegio/JpegDecoder.c +msgid "Interrupted by output function" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "timeout duration exceeded the maximum supported value" +#: shared-module/jpegio/JpegDecoder.c +msgid "Device error or wrong termination of input stream" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "timeout must be < 655.35 secs" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient memory pool for the image" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -msgid "timeout waiting for flux" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient stream input buffer" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: shared-module/floppyio/__init__.c -msgid "timeout waiting for index pulse" +#: shared-module/jpegio/JpegDecoder.c +msgid "Parameter error" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v1 card" +#: shared-module/jpegio/JpegDecoder.c +msgid "Data format error (may be broken data)" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v2 card" +#: shared-module/jpegio/JpegDecoder.c +msgid "Right format but not supported" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "timer re-init" +#: shared-module/jpegio/JpegDecoder.c +msgid "Unsupported JPEG (may be progressive)" msgstr "" -#: shared-bindings/time/__init__.c -msgid "timestamp out of range for platform time_t" +#: shared-module/jpegio/JpegDecoder.c +msgid "%q() without %q()" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "tobytes can be invoked for dense arrays only" +#: shared-module/memorymonitor/AllocationAlarm.c +#, c-format +msgid "Attempt to allocate %d blocks" msgstr "" -#: py/compile.c -msgid "too many args" +#: shared-module/msgpack/__init__.c +msgid "short read" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c -msgid "too many dimensions" +#: shared-module/msgpack/__init__.c +msgid "no default packer" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "too many indices" +#: shared-module/msgpack/__init__.c supervisor/shared/settings.c +msgid "Invalid format" msgstr "" -#: py/asmthumb.c -msgid "too many locals for native method" +#: shared-module/paralleldisplaybus/ParallelBus.c +msgid "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." msgstr "" -#: py/runtime.c -#, c-format -msgid "too many values to unpack (expected %d)" +#: shared-module/rgbmatrix/RGBMatrix.c +msgid "No timer available" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D arrays of equal length" +#: shared-module/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Internal error #%d" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D iterables" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v1 card" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v2 card" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_driver_install returned esp-idf error #%d" +#: shared-module/sdcardio/SDCard.c +msgid "no SD card" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_start returned esp-idf error #%d" +#: shared-module/sdcardio/SDCard.c +msgid "couldn't determine SD card version" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c -msgid "tx and rx cannot both be None" +#: shared-module/sdcardio/SDCard.c +msgid "no response from SD card" msgstr "" -#: py/objtype.c -msgid "type '%q' is not an acceptable base type" +#: shared-module/sdcardio/SDCard.c +msgid "SD card CSD format not supported" msgstr "" -#: py/objtype.c -msgid "type is not an acceptable base type" +#: shared-module/sdcardio/SDCard.c +msgid "can't set 512 block size" msgstr "" -#: py/runtime.c -msgid "type object '%q' has no attribute '%q'" +#: shared-module/ssl/SSLSocket.c +msgid "Invalid socket for TLS" msgstr "" -#: py/objtype.c -msgid "type takes 1 or 3 arguments" +#: shared-module/ssl/SSLSocket.c +msgid "invalid key" msgstr "" -#: py/objint_longlong.c -msgid "ulonglong too large" +#: shared-module/ssl/SSLSocket.c +msgid "invalid cert" msgstr "" -#: py/parse.c -msgid "unexpected indent" +#: shared-module/storage/__init__.c +msgid "Mount point directory missing" msgstr "" -#: py/bc.c -msgid "unexpected keyword argument" +#: shared-module/storage/__init__.c +msgid "Cannot remount path when visible via USB." msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c -#: shared-bindings/traceback/__init__.c -msgid "unexpected keyword argument '%q'" +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" msgstr "" -#: py/lexer.c -msgid "unicode name escapes" +#: shared-module/struct/__init__.c +msgid "buffer size must match format" msgstr "" -#: py/parse.c -msgid "unindent doesn't match any outer indent level" +#: shared-module/synthio/__init__.c +msgid "%q must be array of type 'h'" msgstr "" -#: py/objstr.c -#, c-format -msgid "unknown conversion specifier %c" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" msgstr "" -#: py/objstr.c -msgid "unknown format code '%c' for object of type '%q'" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" msgstr "" -#: py/compile.c -msgid "unknown type" +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" msgstr "" -#: py/compile.c -msgid "unknown type '%q'" +#: shared-module/usb/core/Device.c +msgid "No usb host port initialized" msgstr "" -#: py/objstr.c -#, c-format -msgid "unmatched '%c' in format" +#: shared-module/usb/core/Device.c +msgid "Pipe error" msgstr "" -#: py/objtype.c py/runtime.c -msgid "unreadable attribute" +#: shared-module/usb/core/Device.c +msgid "No configuration set" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -msgid "unsupported %q type" +#: shared-module/usb_hid/Device.c +msgid "USB busy" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" +#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Rectangle.c +msgid "can only have one parent" msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" +#: shared-module/vectorio/Polygon.c +msgid "Polygon needs at least 3 points" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "unsupported bitmap depth" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" -#: shared-module/gifio/GifWriter.c -msgid "unsupported colorspace for GifWriter" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "unsupported colorspace for dither" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" msgstr "" -#: py/objstr.c -#, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" -#: py/runtime.c -msgid "unsupported type for %q: '%s'" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" -#: py/runtime.c -msgid "unsupported type for operator" +#: supervisor/shared/safe_mode.c +msgid "Power dipped. Make sure you are providing enough power." msgstr "" -#: py/runtime.c -msgid "unsupported types for %q: '%q', '%q'" +#: supervisor/shared/safe_mode.c +msgid "You pressed the BOOT button at start up" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols is too high" +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols keyword must be specified" +#: supervisor/shared/safe_mode.c +msgid "CIRCUITPY drive could not be found or created." msgstr "" -#: py/objint.c -#, c-format -msgid "value must fit in %d byte(s)" +#: supervisor/shared/safe_mode.c +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "value out of range of target" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: extmod/moddeflate.c -msgid "wbits" +#: supervisor/shared/safe_mode.c +msgid "Stack overflow. Increase stack size." msgstr "" -#: shared-bindings/bitmapfilter/__init__.c -msgid "" -"weights must be a sequence with an odd square number of elements (usually 9 " -"or 25)" +#: supervisor/shared/safe_mode.c +msgid "USB devices need more endpoints than are available." msgstr "" -#: shared-bindings/bitmapfilter/__init__.c -msgid "weights must be an object of type %q, %q, %q, or %q, not %q " +#: supervisor/shared/safe_mode.c +msgid "USB devices specify too many interface names." msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "width must be greater than zero" +#: supervisor/shared/safe_mode.c +msgid "Boot device must be first (interface #0)." msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" +#: supervisor/shared/safe_mode.c +msgid "Internal watchdog timer expired." msgstr "" -#: ports/raspberrypi/common-hal/wifi/Monitor.c -msgid "wifi.Monitor not available" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython core code crashed hard. Whoops!\n" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "window must be <= interval" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "wrong axis index" +#: supervisor/shared/safe_mode.c +msgid "Failed to write internal flash." msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "wrong axis specified" +#: supervisor/shared/safe_mode.c +msgid "Hard fault: memory access or instruction error." msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "wrong dtype" +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong index type" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." msgstr "" -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c -#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c -#: extmod/ulab/code/numpy/vector.c -msgid "wrong input type" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate to the heap." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of condition array" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of index array" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Please file an issue with your program at github.com/adafruit/circuitpython/" +"issues." msgstr "" -#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c -msgid "wrong number of arguments" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" msgstr "" -#: py/runtime.c -msgid "wrong number of values to unpack" +#: supervisor/shared/settings.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "wrong output type" +#: supervisor/shared/settings.c +msgid "Invalid unicode escape" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be an ndarray" -msgstr "" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "Wi-Fi: " +msgstr "Wi-Fi: " -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of float type" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "off" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of shape (n_section, 2)" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "No IP" msgstr "" diff --git a/locale/it_IT.po b/locale/it_IT.po index be0e57c188a..87e7f0e343d 100644 --- a/locale/it_IT.po +++ b/locale/it_IT.po @@ -7,15 +7,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-12-06 22:06+0000\n" -"Last-Translator: deepserket \n" +"PO-Revision-Date: 2025-06-30 16:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: \n" "Language: it_IT\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.3-dev\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" @@ -86,7 +86,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "" @@ -106,7 +106,11 @@ msgstr "" msgid "%q failure: %d" msgstr "%q fallito: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "" @@ -158,7 +162,7 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "" @@ -218,6 +222,7 @@ msgstr "" #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "" @@ -227,6 +232,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "" @@ -272,7 +278,8 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" @@ -306,7 +313,7 @@ msgid "'%q' object does not support '%q'" msgstr "L'oggetto '%q' non supporta '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "L'oggetto '%q' non è un iteratore" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -314,7 +321,7 @@ msgid "'%q' object is not callable" msgstr "L'oggetto '%q' non è richiamabile" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "L'oggetto '%q' non è iterabile" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -542,7 +549,6 @@ msgstr "Tutti i timer per questo pin sono in uso" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Tutti i timer utilizzati" @@ -555,6 +561,10 @@ msgstr "" msgid "Already have all-matches listener" msgstr "Già in possesso di tutti i listener abbinati" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -564,6 +574,7 @@ msgstr "Già in funzione" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Già in ricerca di collegamenti WiFi" @@ -590,6 +601,10 @@ msgstr "Array deve avere mezzoparole (typo 'H')" msgid "Array values should be single bytes." msgstr "I valori dell'Array dovrebbero essere bytes singoli." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -599,6 +614,11 @@ msgstr "Provo ad allocare %d blocchi" msgid "Audio conversion not implemented" msgstr "" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -732,6 +752,10 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -778,12 +802,12 @@ msgid "Cannot record to a file" msgstr "Impossibile registrare in un file" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." +msgid "Cannot remount path when visible via USB." msgstr "" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." -msgstr "non si può impostare un valore quando direzione è input" +msgstr "non si può impostare un valore quando direzione è input." #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -794,6 +818,10 @@ msgstr "" msgid "Cannot subclass slice" msgstr "Impossibile subclasare slice" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "" @@ -828,6 +856,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "" @@ -840,6 +872,11 @@ msgstr "" msgid "Couldn't allocate decoder" msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "" @@ -858,10 +895,6 @@ msgstr "DAC già in uso" msgid "Data 0 pin must be byte aligned" msgstr "graphic deve essere lunga 2048 byte" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "" @@ -873,9 +906,8 @@ msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/nordic/common-hal/_bleio/Adapter.c -#, fuzzy msgid "Data too large for advertisement packet" -msgstr "Impossibile inserire dati nel pacchetto di advertisement." +msgstr "Impossibile inserire dati nel pacchetto di advertisement" #: ports/stm/common-hal/alarm/pin/PinAlarm.c msgid "Deep sleep pins must use a rising edge with pulldown" @@ -957,7 +989,7 @@ msgstr "" #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to acquire mutex, err 0x%04x" -msgstr "Impossibile acquisire il mutex, err 0x%04x" +msgstr "Impossibile acquisire il mutex, err 0x%04x" #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Failed to add service TXT record" @@ -993,14 +1025,46 @@ msgstr "" msgid "Failed to connect: timeout" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" -msgstr "Impossibile rilasciare il mutex, err 0x%04x" +msgstr "Impossibile rilasciare il mutex, err 0x%04x" + +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." @@ -1010,12 +1074,14 @@ msgstr "" msgid "File exists" msgstr "File esistente" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "" @@ -1040,7 +1106,7 @@ msgstr "" msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "" @@ -1148,6 +1214,7 @@ msgid "Insufficient stream input buffer" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "" @@ -1203,7 +1270,9 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "" @@ -1236,6 +1305,10 @@ msgstr "" msgid "Invalid MAC address" msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Argomento non valido" @@ -1267,6 +1340,7 @@ msgid "Invalid hex password" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" @@ -1279,6 +1353,7 @@ msgid "Invalid socket for TLS" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "" @@ -1323,6 +1398,11 @@ msgstr "" msgid "MITM security not supported" msgstr "" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "" @@ -1368,7 +1448,8 @@ msgstr "" msgid "Mount point directory missing" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "" @@ -1508,6 +1589,10 @@ msgstr "" msgid "No pulldown on pin; 1Mohm recommended" msgstr "" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "" + #: py/moderrno.c msgid "No space left on device" msgstr "Non che spazio sul dispositivo" @@ -1611,13 +1696,6 @@ msgstr "" msgid "Only int or string supported for ip" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "" @@ -1668,6 +1746,7 @@ msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1687,6 +1766,10 @@ msgstr "" msgid "PWM slice channel A already in use" msgstr "" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "" @@ -1745,9 +1828,8 @@ msgid "Pipe error" msgstr "" #: py/builtinhelp.c -#, fuzzy msgid "Plus any modules on the filesystem\n" -msgstr "Imposssibile rimontare il filesystem" +msgstr "Imposssibile rimontare il filesystem\n" #: shared-module/vectorio/Polygon.c msgid "Polygon needs at least 3 points" @@ -1785,6 +1867,10 @@ msgstr "" msgid "Program too long" msgstr "" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "" @@ -1805,10 +1891,30 @@ msgstr "" msgid "RNG Init Error" msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1936,11 +2042,13 @@ msgstr "" #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Slice non supportate" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1980,20 +2088,8 @@ msgstr "" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" msgstr "" #: supervisor/shared/safe_mode.c @@ -2014,7 +2110,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "" @@ -2022,6 +2120,10 @@ msgstr "" msgid "Tile width must exactly divide bitmap width" msgstr "" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "" @@ -2089,7 +2191,7 @@ msgstr "" #: main.c msgid "UID:" -msgstr "" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2152,6 +2254,10 @@ msgstr "Inizilizzazione del parser non possibile" msgid "Unable to read color palette data" msgstr "" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2246,15 +2352,12 @@ msgstr "" msgid "Unsupported display bus type" msgstr "tipo di bitmap non supportato" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Formato non supportato" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "" @@ -2303,10 +2406,12 @@ msgstr "" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " -msgstr "" +msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" #: main.c @@ -2329,6 +2434,7 @@ msgstr "" #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "" @@ -2342,6 +2448,7 @@ msgstr "" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "" @@ -2402,6 +2509,10 @@ msgstr "un oggetto byte-like è richiesto" msgid "addresses is empty" msgstr "gli indirizzi sono vuoti" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "" + #: py/compile.c msgid "annotation must be an identifier" msgstr "" @@ -2480,6 +2591,10 @@ msgstr "" msgid "attributes not supported" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "" @@ -2516,6 +2631,10 @@ msgstr "" msgid "binary op %q not implemented" msgstr "operazione binaria %q non implementata" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "" + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "" @@ -2528,6 +2647,15 @@ msgstr "" msgid "bits must be 32 or less" msgstr "" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c #, fuzzy msgid "bits_per_sample must be 8 or 16" @@ -2613,7 +2741,7 @@ msgstr "impossibile assegnare all'espressione" msgid "can't cancel self" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "" @@ -3077,7 +3205,7 @@ msgid "format" msgstr "" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "la formattazione richiede un dict" #: py/objdeque.c @@ -3212,10 +3340,6 @@ msgstr "gli indici devono essere interi" msgid "indices must be integers, slices, or Boolean lists" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "" @@ -3413,10 +3537,6 @@ msgstr "etichetta '%q' non definita" msgid "label redefined" msgstr "etichetta ridefinita" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs e rhs devono essere compatibili" @@ -3548,7 +3668,7 @@ msgid "must use keyword argument for key function" msgstr "" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "nome '%q'non definito" #: py/runtime.c @@ -3970,6 +4090,10 @@ msgstr "" msgid "rsplit(None,n)" msgstr "" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4021,7 +4145,7 @@ msgstr "" #: py/objint.c py/sequence.c msgid "small int overflow" -msgstr "small int overflow" +msgstr "piccolo int overflow" #: main.c msgid "soft reboot\n" @@ -4189,11 +4313,11 @@ msgid "tx and rx cannot both be None" msgstr "tx e rx non possono essere entrambi None" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "il tipo '%q' non è un tipo di base accettabile" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "il tipo non è un tipo di base accettabile" #: py/runtime.c @@ -4255,7 +4379,9 @@ msgstr "" msgid "unreadable attribute" msgstr "attributo non leggibile" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo di %q non supportato" @@ -4333,11 +4459,6 @@ msgstr "" msgid "width must be greater than zero" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "" @@ -4400,6 +4521,9 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Unsupported format" +#~ msgstr "Formato non supportato" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "La lunghezza del buffer deve essere un multiplo di 512" @@ -4553,13 +4677,13 @@ msgstr "" #~ msgid "'%s' object does not support item deletion" #~ msgstr "oggeto '%s' non supporta eliminamento di item" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "l'oggetto '%s' non è un iteratore" #~ msgid "'%s' object is not callable" #~ msgstr "oggeto '%s' non è chiamabile" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "l'oggetto '%s' non è iterabile" #~ msgid "'%s' object is not subscriptable" @@ -4575,7 +4699,7 @@ msgstr "" #~ msgid "'continue' outside loop" #~ msgstr "'continue' fuori del ciclo" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "L'oggetto 'coroutine' non è un iteratore" #~ msgid "64 bit types" @@ -5238,7 +5362,7 @@ msgstr "" #~ msgid "frequency can only be either 80Mhz or 160MHz" #~ msgstr "la frequenza può essere o 80Mhz o 160Mhz" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "la funzione non prende argomenti nominati" #~ msgid "impossible baudrate" @@ -5305,7 +5429,7 @@ msgstr "" #~ msgid "name must be a string" #~ msgstr "argomenti nominati devono essere stringhe" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "nome riutilizzato come argomento" #, fuzzy diff --git a/locale/ja.po b/locale/ja.po index d8cf41e228d..6e625e94a87 100644 --- a/locale/ja.po +++ b/locale/ja.po @@ -8,15 +8,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2024-01-22 14:03+0000\n" -"Last-Translator: Nemoto \n" +"PO-Revision-Date: 2025-06-30 16:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: none\n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.4-dev\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" @@ -95,7 +95,7 @@ msgstr "%dアドレスピン、%dRGBピン、%dタイルは%dの高さを指示 msgid "%q and %q contain duplicate pins" msgstr "%q と %q に重複するピンがあります" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%qと%qが必ず異なるのは必要" @@ -115,7 +115,11 @@ msgstr "%q に重複するピンがあります" msgid "%q failure: %d" msgstr "%q 失敗: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q 内の %q は %q 型である必要があり、 %q 型は使用できません" @@ -167,7 +171,7 @@ msgstr "%q の長さは <= %d である必要があります" msgid "%q length must be >= %d" msgstr "%q の長さは >= %d である必要があります" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "%q は %q から %q へ移動しました" @@ -223,11 +227,12 @@ msgstr "%q は 'h' 型の array である必要があります" #: shared-bindings/audiobusio/PDMIn.c msgid "%q must be multiple of 8." -msgstr "%q は 8 の倍数である必要があります" +msgstr "%q は 8 の倍数である必要があります." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q は %q 型か %q 型である必要があります、 %q 型は使用できません" @@ -238,6 +243,7 @@ msgstr "" "%q は %q 型や %q 型または %q 型である必要があります、 %q 型は使用できません" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q は %q 型である必要があります、 %q 型は使用できません" @@ -283,7 +289,8 @@ msgstr "%q() に %q() がありません" msgid "%q, %q, and %q must all be the same length" msgstr "%q と %q および %q はすべて同じ長さである必要があります" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -317,7 +324,7 @@ msgid "'%q' object does not support '%q'" msgstr "'%q' オブジェクトは '%q' に対応していません" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "オブジェクト'%q'はイテレータではありません" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -325,7 +332,7 @@ msgid "'%q' object is not callable" msgstr "オブジェクト'%q'は呼び出し可能ではありません" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "オブジェクト'%q'はイテレート可能ではありません" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -552,7 +559,6 @@ msgstr "このピン用の全てのタイマが使用中" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "全てのタイマーが使用中" @@ -565,6 +571,10 @@ msgstr "すでにアドバータイズ中" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -574,6 +584,7 @@ msgstr "すでに実行中" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" @@ -600,6 +611,10 @@ msgstr "array のタイプは16ビット ('H') でなければなりません" msgid "Array values should be single bytes." msgstr "Arrayの各値は1バイトでなければなりません" +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -609,6 +624,11 @@ msgstr "%d個のブロックの確保を試みました" msgid "Audio conversion not implemented" msgstr "" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -744,6 +764,10 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -789,7 +813,7 @@ msgid "Cannot record to a file" msgstr "ファイルへ記録できません" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." +msgid "Cannot remount path when visible via USB." msgstr "" #: shared-bindings/digitalio/DigitalInOut.c @@ -805,6 +829,10 @@ msgstr "RS485モードにRTSまたはCTSを指定できません" msgid "Cannot subclass slice" msgstr "sliceをサブクラス化することはできません" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "" @@ -839,6 +867,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "アドレスをセットできません" @@ -851,6 +883,11 @@ msgstr "割り込みをスタートできません。RXビジー" msgid "Couldn't allocate decoder" msgstr "デコーダを確保できません" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DACチャネル初期化エラー" @@ -868,10 +905,6 @@ msgstr "DACはすでに使用中" msgid "Data 0 pin must be byte aligned" msgstr "Data 0 ピンは、バイト整列されていなければなりません" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "fmtチャンクの後にdataチャンクが続かなければなりません" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "" @@ -1002,15 +1035,47 @@ msgstr "接続失敗: 内部エラー" msgid "Failed to connect: timeout" msgstr "接続失敗: タイムアウト" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "MP3ファイルのパーズに失敗" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "ミューテックスの開放に失敗。エラー 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "内部フラッシュ書き込みに失敗" @@ -1019,12 +1084,14 @@ msgstr "内部フラッシュ書き込みに失敗" msgid "File exists" msgstr "ファイルが存在します" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "" @@ -1049,7 +1116,7 @@ msgstr "" msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "非対応の形式" @@ -1157,6 +1224,7 @@ msgid "Insufficient stream input buffer" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "" @@ -1212,7 +1280,9 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "不正な %q" @@ -1245,6 +1315,10 @@ msgstr "不正なBSSID" msgid "Invalid MAC address" msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "不正な引数" @@ -1276,6 +1350,7 @@ msgid "Invalid hex password" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" @@ -1288,6 +1363,7 @@ msgid "Invalid socket for TLS" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "" @@ -1332,6 +1408,11 @@ msgstr "" msgid "MITM security not supported" msgstr "" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "" @@ -1377,7 +1458,8 @@ msgstr "" msgid "Mount point directory missing" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "%q のサブクラスでなければなりません" @@ -1517,6 +1599,10 @@ msgstr "" msgid "No pulldown on pin; 1Mohm recommended" msgstr "ピンにプルダウンがありません。1Mオーム推奨" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "" + #: py/moderrno.c msgid "No space left on device" msgstr "デバイスに空き容量が残っていません" @@ -1618,13 +1704,6 @@ msgstr "" msgid "Only int or string supported for ip" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "" @@ -1675,6 +1754,7 @@ msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1694,6 +1774,10 @@ msgstr "" msgid "PWM slice channel A already in use" msgstr "" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "" @@ -1794,6 +1878,10 @@ msgstr "" msgid "Program too long" msgstr "" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "方向がoutputのときpullは使われません" @@ -1814,10 +1902,30 @@ msgstr "RNG解体エラー" msgid "RNG Init Error" msgstr "乱数生成器の初期化エラー" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1945,11 +2053,13 @@ msgstr "スライスと値の長さが一致しません" #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "スライスは対応していません" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1989,22 +2099,10 @@ msgstr "" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "サンプルのbits_per_sampleがミキサーのそれと一致しません" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "サンプルレートがサンプルとミキサーで一致しません" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "符号の有無がサンプルとミキサーで一致しません" - #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." msgstr "" @@ -2023,7 +2121,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "タイルの高さはビットマップの高さを割り切れる値でなければなりません" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "タイルのインデクスが範囲外" @@ -2031,6 +2131,10 @@ msgstr "タイルのインデクスが範囲外" msgid "Tile width must exactly divide bitmap width" msgstr "タイルの幅はビットマップの幅を割り切れる値でなければなりません" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "" @@ -2162,6 +2266,10 @@ msgstr "パーザを初期化できません" msgid "Unable to read color palette data" msgstr "カラーパレットデータを読み込めません" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2254,15 +2362,12 @@ msgstr "" msgid "Unsupported display bus type" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "非対応の形式" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "" @@ -2313,8 +2418,10 @@ msgstr "" msgid "Wi-Fi: " msgstr "" +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" #: main.c @@ -2337,6 +2444,7 @@ msgstr "" #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "" @@ -2350,6 +2458,7 @@ msgstr "" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "" @@ -2410,6 +2519,10 @@ msgstr "bytes-likeオブジェクトが必要" msgid "addresses is empty" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "" + #: py/compile.c msgid "annotation must be an identifier" msgstr "" @@ -2488,6 +2601,10 @@ msgstr "" msgid "attributes not supported" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "" @@ -2524,6 +2641,10 @@ msgstr "不正なtypecode" msgid "binary op %q not implemented" msgstr "" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "" + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "" @@ -2536,6 +2657,15 @@ msgstr "" msgid "bits must be 32 or less" msgstr "" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sampleは8または16でなければなりません" @@ -2617,7 +2747,7 @@ msgstr "式には代入できません" msgid "can't cancel self" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "%qを%qに変換できません" @@ -3080,7 +3210,7 @@ msgid "format" msgstr "" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "formatにはdictが必要" #: py/objdeque.c @@ -3215,10 +3345,6 @@ msgid "indices must be integers, slices, or Boolean lists" msgstr "" "インデクスは、整数、スライス、boolのリストのいずれかでなければなりません" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "" @@ -3413,10 +3539,6 @@ msgstr "ラベル'%q'は定義されていません" msgid "label redefined" msgstr "ラベルの再定義" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "levelは0から1の間でなければなりません" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "左辺と右辺が互換でなければなりません" @@ -3548,7 +3670,7 @@ msgid "must use keyword argument for key function" msgstr "" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "名前 '%q' は定義されていません" #: py/runtime.c @@ -3966,6 +4088,10 @@ msgstr "" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4185,11 +4311,11 @@ msgid "tx and rx cannot both be None" msgstr "txとrxを両方ともNoneにできません" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "型'%q'はベース型として使えません" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "この型はベース型にできません" #: py/runtime.c @@ -4251,7 +4377,9 @@ msgstr "" msgid "unreadable attribute" msgstr "読み込み不可能な属性" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "非対応の型 %q" @@ -4329,11 +4457,6 @@ msgstr "" msgid "width must be greater than zero" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "" @@ -4396,6 +4519,24 @@ msgstr "ziはfloat値でなければなりません" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Unsupported format" +#~ msgstr "非対応の形式" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "fmtチャンクの後にdataチャンクが続かなければなりません" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "levelは0から1の間でなければなりません" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "サンプルのbits_per_sampleがミキサーのそれと一致しません" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "サンプルレートがサンプルとミキサーで一致しません" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "符号の有無がサンプルとミキサーで一致しません" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "バッファ長は512の倍数でなければなりません" @@ -4545,7 +4686,7 @@ msgstr "" #~ msgid "'continue' outside loop" #~ msgstr "ループ外でのcontinue" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "'coroutine' オブジェクトはイテレータではありません" #~ msgid "Address type out of range" @@ -5145,7 +5286,7 @@ msgstr "" #~ msgid "n must be between 0, and 9" #~ msgstr "nは0から9まで" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "引数で名前が再利用されています" #~ msgid "no available NIC" diff --git a/locale/ko.po b/locale/ko.po index b7e43a9267f..0ff994e2e18 100644 --- a/locale/ko.po +++ b/locale/ko.po @@ -7,1601 +7,1585 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-12-23 14:56+0000\n" -"Last-Translator: 오수아 \n" +"PO-Revision-Date: 2025-06-30 16:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: LANGUAGE \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.4-dev\n" +"X-Generator: Weblate 5.13-dev\n" -#: main.c -msgid "" -"\n" -"Code done running.\n" +#: extmod/modasyncio.c extmod/modheapq.c +msgid "empty heap" msgstr "" -"\n" -"코드 실행 완료.\n" -#: main.c -msgid "" -"\n" -"Code stopped by auto-reload. Reloading soon.\n" +#: extmod/modasyncio.c +msgid "can't cancel self" msgstr "" -"\n" -"자동 업로드에 의해 코드가 중지되었습니다. 곧 다시 로드됩니다.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Please file an issue with your program at github.com/adafruit/circuitpython/" -"issues." +#: extmod/modasyncio.c +msgid "can't wait" msgstr "" -"\n" -"github.com/adafruit/circuitpython/issues 에\n" -"프로그램 오류를 제출하세요." -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Press reset to exit safe mode.\n" +#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c +msgid "a bytes-like object is required" msgstr "" -"\n" -"재설정을 눌러 안전 모드를 종료합니다.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"You are in safe mode because:\n" +#: extmod/modbinascii.c +msgid "incorrect padding" msgstr "" -"\n" -"안전 모드에 있는 이유는 다음과 같습니다:\n" - -#: py/obj.c -msgid " File \"%q\"" -msgstr " 파일 \"%q\"" - -#: py/obj.c -msgid " File \"%q\", line %d" -msgstr " 파일 \"%q\", 라인 %d" -#: py/builtinhelp.c -msgid " is of type %q\n" -msgstr " %q 유형입니다\n" +#: extmod/moddeflate.c +msgid "format" +msgstr "" -#: main.c -msgid " not found.\n" -msgstr " 찾을 수 없습니다.\n" +#: extmod/moddeflate.c +msgid "wbits" +msgstr "" -#: main.c -msgid " output:\n" -msgstr " 산출:\n" +#: extmod/modhashlib.c +msgid "hash is final" +msgstr "" -#: py/objstr.c -#, c-format -msgid "%%c requires int or char" -msgstr "%%c 전수(int)또는 캐릭터(char)필요합니다" +#: extmod/modheapq.c +msgid "heap must be a list" +msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +#: extmod/modjson.c +msgid "syntax error in JSON" msgstr "" -"%d 주소 핀들, %d rgb 핀들과 %d 타일 들은 높이가 %d임을 나타낸다, %d가 아니라" -#: shared-bindings/microcontroller/Pin.c -msgid "%q and %q contain duplicate pins" -msgstr "%q 및 %q에 중복된 핀이 포함" +#: extmod/modrandom.c +msgid "bits must be 32 or less" +msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "%q and %q must be different" -msgstr "%q와 %q는 달라야 합니다" +#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c +msgid "no default seed" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "%q and %q must share a clock unit" +#: extmod/modre.c +msgid "splitting with sub-captures" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "%q cannot be changed once mode is set to %q" +#: extmod/modre.c +msgid "regex too complex" msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q contains duplicate pins" -msgstr "%q에 중복된 핀이 포함" +#: extmod/modre.c +msgid "Error in regex" +msgstr "Regex에 오류가 있습니다." -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -msgid "%q failure: %d" -msgstr "%q 실패: %d" +#: extmod/modtime.c +msgid "mktime needs a tuple of length 8 or 9" +msgstr "" -#: py/argcheck.c -msgid "%q in %q must be of type %q, not %q" -msgstr "%q의 %q는 %q가 아니라 %q 유형이어야 합니다" +#: extmod/modtime.c +msgid "ticks interval overflow" +msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/usb_host/Port.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c -msgid "%q in use" -msgstr "%q 사용 중입니다" +#: extmod/modzlib.c +msgid "compression header" +msgstr "" -#: py/objstr.c -msgid "%q index out of range" -msgstr "%q 인덱스 범위를 벗어났습니다" +#: extmod/ulab/code/ndarray.c +msgid "data type not understood" +msgstr "" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" -#: shared-module/bitbangio/SPI.c -msgid "%q init failed" -msgstr "%q 초기화 실패" +#: extmod/ulab/code/ndarray.c +msgid "ndarray length overflows" +msgstr "" -#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c -msgid "%q is %q" -msgstr "%q는 %q입니다" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex type" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "%q is read-only for this board" -msgstr "%q는 이 보드에 대한 읽기 전용입니다" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c +msgid "too many dimensions" +msgstr "" -#: py/argcheck.c shared-bindings/usb_hid/Device.c -msgid "%q length must be %d" -msgstr "%q 길이는 %d이어야 합니다" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c +msgid "index is out of bounds" +msgstr "" -#: py/argcheck.c -msgid "%q length must be %d-%d" -msgstr "%q 길이는 %d - %d이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "indices must be integers, slices, or Boolean lists" +msgstr "" -#: py/argcheck.c -msgid "%q length must be <= %d" -msgstr "%q 길이는 <= %d>여야 합니다" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c +msgid "operands could not be broadcast together" +msgstr "" -#: py/argcheck.c -msgid "%q length must be >= %d" -msgstr "%q 길이는 >= %d이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "array and index length must be equal" +msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c -#, fuzzy -msgid "%q moved from %q to %q" -msgstr "%q가 %q에서 %q로 이동했습니다" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex to dtype" +msgstr "" -#: py/argcheck.c -msgid "%q must be %d" -msgstr "%q는 %d이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "operation is implemented for 1D Boolean arrays only" +msgstr "" -#: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "%q must be %d-%d" -msgstr "%q는 %d-%d이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "too many indices" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -msgid "%q must be 1 when %q is True" -msgstr "%q가 참일 때 %q는 1이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "cannot delete array elements" +msgstr "" -#: py/argcheck.c shared-bindings/gifio/GifWriter.c -#: shared-module/gifio/OnDiskGif.c -#, fuzzy -msgid "%q must be <= %d" -msgstr "%q 는 <= %d 여야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "flattening order must be either 'C', or 'F'" +msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -#, fuzzy -msgid "%q must be <= %u" -msgstr "%q 는 <= %u 여야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "tobytes can be invoked for dense arrays only" +msgstr "" -#: py/argcheck.c -#, fuzzy -msgid "%q must be >= %d" -msgstr "%q 는 >= %d 여야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "operation is not supported for given type" +msgstr "" -#: shared-bindings/analogbufio/BufferedIn.c -msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "%q는 'H' 또는 'B' 타입의 바이트 배열 또는 배열이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "shape must be integer or tuple of integers" +msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -msgstr "%q는 h, H, b 또는 B 유형의 바이트 배열 또는 배열이어야 합니다" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c +msgid "maximum number of dimensions is " +msgstr "" -#: shared-bindings/warnings/__init__.c -msgid "%q must be a subclass of %q" -msgstr "%q는 %q의 하위 클래스여야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "can only specify one unknown dimension" +msgstr "" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -#, fuzzy -msgid "%q must be array of type 'H'" -msgstr "%q는 'H' 유형의 배열이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "cannot reshape array" +msgstr "" -#: shared-module/synthio/__init__.c -#, fuzzy -msgid "%q must be array of type 'h'" -msgstr "%q는 'h' 유형의 배열이어야 합니다" +#: extmod/ulab/code/ndarray.c +msgid "cannot assign new shape" +msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "%q must be multiple of 8." +#: extmod/ulab/code/ndarray.c +msgid "function is defined for ndarrays only" msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c -#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c -#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c -#: shared-module/synthio/Synthesizer.c -msgid "%q must be of type %q or %q, not %q" -msgstr "%q는 %q가 아닌 %q 또는 %q 유형이어야 합니다" +#: extmod/ulab/code/ndarray_operators.c +msgid "operation not supported for the input types" +msgstr "" -#: shared-bindings/jpegio/JpegDecoder.c -msgid "%q must be of type %q, %q, or %q, not %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "dtype of int32 is not supported" msgstr "" -#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c -#: shared-module/synthio/__init__.c -msgid "%q must be of type %q, not %q" -msgstr "%q는 %q가 아니라 %q 유형이어야 합니다" +#: extmod/ulab/code/ndarray_operators.c +msgid "cannot cast output with casting rule" +msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -msgid "%q must be power of 2" -msgstr "%q는 2의 거듭제곱이어야 합니다" +#: extmod/ulab/code/ndarray_operators.c +msgid "results cannot be cast to specified type" +msgstr "" -#: shared-bindings/wifi/Monitor.c -#, fuzzy -msgid "%q out of bounds" -msgstr "%q가 경계를 벗어남" +#: extmod/ulab/code/numpy/approx.c +msgid "interp is defined for 1D iterables of equal length" +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c -#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c -#, fuzzy -msgid "%q out of range" -msgstr "%q가 범위를 벗어남" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D iterables" +msgstr "" -#: py/objmodule.c py/runtime.c -msgid "%q renamed %q" -msgstr "%q가 %q로 이름이 변경되었습니다" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D arrays of equal length" +msgstr "" -#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c -#, fuzzy -msgid "%q step cannot be zero" -msgstr "%q 단계는 0일 수 없습니다" +#: extmod/ulab/code/numpy/bitwise.c +msgid "not supported for input types" +msgstr "" -#: shared-module/bitbangio/I2C.c -msgid "%q too long" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "function is implemented for ndarrays only" msgstr "" -#: py/bc.c py/objnamedtuple.c -#, fuzzy -msgid "%q() takes %d positional arguments but %d were given" -msgstr "%q()는 %d 위치 인수를 사용하지만 %d이(가) 주어졌습니다" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be an ndarray, or a scalar" +msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "%q() without %q()" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be a 1D ndarray" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q, %q, and %q must all be the same length" -msgstr "%q, %q 및 %q의 길이는 모두 같아야 합니다" +#: extmod/ulab/code/numpy/carray/carray_tools.c +msgid "not implemented for complex dtype" +msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c -msgid "%q=%q" -msgstr "%q=%q" +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c +#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c +#: extmod/ulab/code/numpy/vector.c +msgid "wrong input type" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, fuzzy -msgid "%q[%u] shifts in more bits than pin count" -msgstr "%q[%u]가 핀 수보다 더 많은 비트로 이동했습니다" +#: extmod/ulab/code/numpy/create.c +msgid "input argument must be an integer, a tuple, or a list" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, fuzzy -msgid "%q[%u] shifts out more bits than pin count" -msgstr "%q[%u]이(가) 핀 수보다 많은 비트를 전송합니다" +#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c +msgid "wrong number of arguments" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] uses extra pin" -msgstr "%q[%u]에서 추가 핀 사용" +#: extmod/ulab/code/numpy/create.c py/objint_longlong.c py/objint_mpz.c +msgid "divide by zero" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] waits on input outside of count" -msgstr "%q[%u]이(가) 카운트 외부의 입력을 대기합니다" +#: extmod/ulab/code/numpy/create.c +msgid "arange: cannot compute length" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -#, fuzzy, c-format -msgid "%s error 0x%x" -msgstr "%s 오류 0x%x" +#: extmod/ulab/code/numpy/create.c +msgid "first argument must be a tuple of ndarrays" +msgstr "" -#: py/argcheck.c -msgid "'%q' argument required" -msgstr "'%q' 인수가 필요합니다" +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" -#: py/proto.c -msgid "'%q' object does not support '%q'" -msgstr "'%q' 개체가 '%q'를 지원하지 않습니다" +#: extmod/ulab/code/numpy/create.c +msgid "wrong axis specified" +msgstr "" -#: py/runtime.c -msgid "'%q' object is not an iterator" -msgstr "'%q' 개체가 iterator가 아닙니다" +#: extmod/ulab/code/numpy/create.c +msgid "input arrays are not compatible" +msgstr "" -#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c -msgid "'%q' object is not callable" -msgstr "'%q' 개체를 호출할 수 없습니다" +#: extmod/ulab/code/numpy/create.c +msgid "input must be 1- or 2-d" +msgstr "" -#: py/runtime.c -msgid "'%q' object is not iterable" -msgstr "'%q' 개체를 사용할 수 없습니다" +#: extmod/ulab/code/numpy/create.c +msgid "number of points must be at least 2" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a label" -msgstr "'%s' 에는 라벨이 필요합니다" +#: extmod/ulab/code/numpy/create.c +msgid "offset must be non-negative and no greater than buffer length" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a register" -msgstr "'%s' 에는 레지스터가 필요합니다" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer size must be a multiple of element size" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects a special register" -msgstr "'%s' 에는 특별한 레지스터가 필요합니다" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer is smaller than requested size" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an FPU register" -msgstr "'%s' 에는 FPU레지스터가 필요합니다" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is defined for ndarrays only" +msgstr "FFT는 ndarrays에 대해서만 정의됩니다" -#: py/emitinlinethumb.c -#, fuzzy, c-format -msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s' 에는 [a, b] 형식의 주소가 필요합니다" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is implemented for linear arrays only" +msgstr "FFT는 선형 배열에 대해서만 구현됩니다" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects an integer" -msgstr "'%s' 는 정수 여야합니다" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "input array length must be power of 2" +msgstr "" -#: py/emitinlinethumb.c -#, fuzzy, c-format -msgid "'%s' expects at most r%d" -msgstr "'%s'는 최대 r%d를 필요로 합니다" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "real and imaginary parts must be of equal length" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' {r0, r1, ...}은 을 기대합니다" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be ndarrays" +msgstr "" -#: py/emitinlinextensa.c -#, fuzzy, c-format -msgid "'%s' integer %d isn't within range %d..%d" -msgstr "'%s' 정수 %d가 %d..%d 범위 내에 있지 않습니다" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be linear arrays" +msgstr "" -#: py/emitinlinethumb.c -#, fuzzy, c-format -msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" -msgstr "'%s' 정수 0x%x 이 마스크 0x%x에 맞지 않습니다" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must not be empty" +msgstr "" -#: py/obj.c -#, fuzzy, c-format -msgid "'%s' object doesn't support item assignment" -msgstr "'%s' 개체가 항목 할당을 지원하지 않습니다" +#: extmod/ulab/code/numpy/io/io.c +msgid "corrupted file" +msgstr "" -#: py/obj.c -#, fuzzy, c-format -msgid "'%s' object doesn't support item deletion" -msgstr "'%s' 개체가 항목 삭제를 지원하지 않습니다" +#: extmod/ulab/code/numpy/io/io.c +msgid "wrong dtype" +msgstr "" -#: py/runtime.c -#, fuzzy -msgid "'%s' object has no attribute '%q'" -msgstr "'%s' 개체에 '%q' 특성이 없습니다" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols keyword must be specified" +msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object isn't subscriptable" -msgstr "'%s' 개체를 subscriptable 할 수 없습니다" +#: extmod/ulab/code/numpy/io/io.c +msgid "empty file" +msgstr "" -#: py/objstr.c -#, fuzzy -msgid "'=' alignment not allowed in string format specifier" -msgstr "'=' 문자열 형식 지정자에서 정렬이 허용되지 않습니다" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols is too high" +msgstr "" -#: shared-module/struct/__init__.c -msgid "'S' and 'O' are not supported format types" -msgstr "'S' 및 'O'는 지원되지 않는 형식 유형입니다" +#: extmod/ulab/code/numpy/io/io.c +msgid "array has too many dimensions" +msgstr "" -#: py/compile.c -msgid "'align' requires 1 argument" -msgstr "'align' 에는 1 개의 독립변수가 필요합니다" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "input matrix is asymmetric" +msgstr "" -#: py/compile.c -msgid "'await' outside function" -msgstr "'await' 는 펑크션 외부에 있습니다" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "matrix is not positive definite" +msgstr "" -#: py/compile.c -msgid "'break'/'continue' outside loop" -msgstr "'break'/'continue' 외부 루프" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "iterations did not converge" +msgstr "" -#: py/compile.c -msgid "'data' requires at least 2 arguments" -msgstr "'data' 에는 >=2 개의 독립변수가 필요합니다" +#: extmod/ulab/code/numpy/linalg/linalg.c +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "input matrix is singular" +msgstr "" -#: py/compile.c -#, fuzzy -msgid "'data' requires integer arguments" -msgstr "'data' 에는 정수 인수가 필요합니다" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for ndarrays only" +msgstr "" -#: py/compile.c -msgid "'label' requires 1 argument" -msgstr "'label' 에는 1 개의 독립변수가 필요합니다" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for 2D arrays only" +msgstr "" -#: py/emitnative.c -msgid "'not' not implemented" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "mode must be complete, or reduced" msgstr "" -#: py/compile.c -msgid "'return' outside function" -msgstr "'return' 는 함수 외부에 존재합니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" +msgstr "" -#: py/compile.c -#, fuzzy -msgid "'yield from' inside async function" -msgstr "비동기 함수 내 'yield from'" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get (arg)min/(arg)max of empty sequence" +msgstr "" -#: py/compile.c -msgid "'yield' outside function" -msgstr "'yield' 는 함수 외부에 존재합니다" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +msgid "axis must be None, or an integer" +msgstr "" -#: py/compile.c -#, fuzzy -msgid "* arg after **" -msgstr "* 인수 뒤에 **" +#: extmod/ulab/code/numpy/numerical.c +msgid "operation is not implemented on ndarrays" +msgstr "" -#: py/compile.c -#, fuzzy -msgid "*x must be assignment target" -msgstr "*x는 할당 대상이어야 합니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "input must be tuple, list, range, or ndarray" +msgstr "" -#: py/obj.c -msgid ", in %q\n" -msgstr ", 에서 %q\n" +#: extmod/ulab/code/numpy/numerical.c +msgid "sort argument must be an ndarray" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#, fuzzy -msgid ".show(x) removed. Use .root_group = x" -msgstr ".show(x)가 제거되었습니다. .root_group = x를 사용합니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort argument must be an ndarray" +msgstr "" -#: py/objcomplex.c -msgid "0.0 to a complex power" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort is not implemented for flattened arrays" msgstr "" -#: py/modbuiltins.c -msgid "3-arg pow() not supported" -msgstr "pow() 는 3개의 인수를 지원하지 않습니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "axis too long" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "AP could not be started" -msgstr "AP를 시작할 수 없습니다" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c +msgid "arguments must be ndarrays" +msgstr "" -#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, c-format -msgid "Address must be %d bytes long" -msgstr "주소 길이는 % d 바이트 여야합니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "cross is defined for 1D arrays of length 3" +msgstr "" -#: ports/espressif/common-hal/memorymap/AddressRange.c -#: ports/nordic/common-hal/memorymap/AddressRange.c -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Address range not allowed" -msgstr "주소 범위가 허용되지 않습니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "diff argument must be an ndarray" +msgstr "" -#: shared-bindings/memorymap/AddressRange.c -msgid "Address range wraps around" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, fuzzy -msgid "All CAN peripherals are in use" -msgstr "모든 CAN 주변 기기가 사용 중입니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "differentiation order out of range" +msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/nordic/common-hal/busio/I2C.c -msgid "All I2C peripherals are in use" -msgstr "사용 중인 모든 I2C주변 기기" +#: extmod/ulab/code/numpy/numerical.c +msgid "flip argument must be an ndarray" +msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -#, fuzzy -msgid "All RX FIFOs in use" -msgstr "모든 RX FIFOs가 사용 중입니다" +#: extmod/ulab/code/numpy/numerical.c +msgid "wrong axis index" +msgstr "" -#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c -msgid "All SPI peripherals are in use" -msgstr "사용중인 모든 SPI주변 기기" +#: extmod/ulab/code/numpy/numerical.c +msgid "median argument must be an ndarray" +msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c -msgid "All UART peripherals are in use" -msgstr "사용중인 모든 UART주변 기기" +#: extmod/ulab/code/numpy/numerical.c +msgid "roll argument must be an ndarray" +msgstr "" -#: ports/nordic/common-hal/countio/Counter.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c -msgid "All channels in use" -msgstr "모든 채널이 사용중입니다" +#: extmod/ulab/code/numpy/poly.c +msgid "input data must be an iterable" +msgstr "" -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All dma channels in use" -msgstr "모든 dma채널이 사용 중입니다" +#: extmod/ulab/code/numpy/poly.c +msgid "more degrees of freedom than data points" +msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#, fuzzy -msgid "All event channels in use" -msgstr "모든 이벤트 채널이 사용 중입니다" +#: extmod/ulab/code/numpy/poly.c +msgid "input vectors must be of equal length" +msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#, fuzzy -msgid "All state machines in use" -msgstr "모든 상태 머신이 사용 중입니다" +#: extmod/ulab/code/numpy/poly.c +msgid "could not invert Vandermonde matrix" +msgstr "" -#: ports/atmel-samd/audio_dma.c -#, fuzzy -msgid "All sync event channels in use" -msgstr "모든 동기화 이벤트 채널이 사용 중입니다" +#: extmod/ulab/code/numpy/poly.c +msgid "input is not iterable" +msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -msgid "All timers for this pin are in use" -msgstr "핀의 모든 타이머가 사용 중입니다" +#: extmod/ulab/code/numpy/random/random.c +msgid "argument must be None, an integer or a tuple of integers" +msgstr "" -#: ports/atmel-samd/common-hal/_pew/PewPew.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/peripherals/nrf/timers.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c -msgid "All timers in use" -msgstr "모든 타이머가 사용 중입니다" +#: extmod/ulab/code/numpy/random/random.c +msgid "shape must be None, and integer or a tuple of integers" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -#, fuzzy -msgid "Already advertising." -msgstr "이미 광고 중입니다." +#: extmod/ulab/code/numpy/random/random.c +msgid "out has wrong type" +msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#, fuzzy -msgid "Already have all-matches listener" -msgstr "이미 모든 일치 리스너가 있습니다" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array has wrong type" +msgstr "" -#: ports/espressif/bindings/espnow/ESPNow.c -#: ports/espressif/common-hal/espulp/ULP.c -#: shared-module/memorymonitor/AllocationAlarm.c -#: shared-module/memorymonitor/AllocationSize.c -msgid "Already running" -msgstr "이미 실행 중입니다" +#: extmod/ulab/code/numpy/random/random.c +msgid "size must match out.shape when used together" +msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -#, fuzzy -msgid "Already scanning for wifi networks" -msgstr "이미 wifi 네트워크를 찾고 있습니다" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array must be contiguous" +msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "An error occurred while retrieving '%s':\n" -msgstr "%s'을(를) 검색하는 동안 오류가 발생했습니다:\n" - -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, fuzzy -msgid "Another PWMAudioOut is already active" -msgstr "다른 PWMaudioOut이 이미 활성화되어 있습니다" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of condition array" +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -msgid "Another send is already active" -msgstr "다른 전송이 이미 활성화되었습니다" +#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c +msgid "first argument must be an ndarray" +msgstr "" -#: shared-bindings/pulseio/PulseOut.c -msgid "Array must contain halfwords (type 'H')" -msgstr "배열은 하프워드(유형 'H')가 포함되어야 합니다" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong index type" +msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -#, fuzzy -msgid "Array values should be single bytes." -msgstr "배열 값은 1바이트 여야합니다." +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of index array" +msgstr "" -#: shared-module/memorymonitor/AllocationAlarm.c -#, c-format -msgid "Attempt to allocate %d blocks" -msgstr "%d 블록 할당 시도" +#: extmod/ulab/code/numpy/transform.c +msgid "dimensions do not match" +msgstr "" -#: ports/raspberrypi/audio_dma.c -msgid "Audio conversion not implemented" -msgstr "오디오 변환이 구현되지 않음" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be an ndarray" +msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "AuthMode.OPEN is not used with password" -msgstr "AuthMode.OPEN은 암호와 함께 사용되지 않습니다" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be of float dtype" +msgstr "" -#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c -msgid "Authentication failure" -msgstr "인증 실패" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output dimensions differ" +msgstr "" -#: main.c -msgid "Auto-reload is off.\n" -msgstr "자동 재 장전이 꺼져 있습니다\n" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output shapes differ" +msgstr "" -#: main.c -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for function" msgstr "" -"자동 새로 고침이 켜져 있습니다. USB를 통해 파일을 저장하여 실행하십시오. 비활" -"성화하려면 REPL을 입력하십시오.\n" -#: ports/espressif/common-hal/canio/CAN.c -msgid "Baudrate not supported by peripheral" -msgstr "주변 기기에서 전송 속도가 지원되지 않습니다" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for complex dtype" +msgstr "" -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Below minimum frame rate" -msgstr "최소 프레임 속도 미만" +#: extmod/ulab/code/numpy/vector.c +msgid "dtype must be float, or complex" +msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Bit clock and word select must be sequential GPIO pins" -msgstr "비트 클럭 및 워드 선택은 순차적 GPIO 핀이어야 합니다" +#: extmod/ulab/code/numpy/vector.c +msgid "can't convert complex to float" +msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Bitmap size and bits per value must match" -msgstr "비트맵 크기와 값 당 비트가 일치해야 합니다" +#: extmod/ulab/code/numpy/vector.c +msgid "input dtype must be float or complex" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Boot device must be first (interface #0)." -msgstr "부팅 장치는 첫 번째(인터페이스 #0)여야 합니다." +#: extmod/ulab/code/numpy/vector.c +msgid "first argument must be a callable" +msgstr "" -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Both RX and TX required for flow control" -msgstr "플로우 제어에 RX와 TX가 모두 필요합니다" +#: extmod/ulab/code/numpy/vector.c +msgid "wrong output type" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Brightness not adjustable" -msgstr "밝기를 조절할 수 없습니다" +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "first two arguments must be ndarrays" +msgstr "" -#: shared-bindings/_bleio/UUID.c -#, c-format -msgid "Buffer + offset too small %d %d %d" -msgstr "Buffer + offset이 너무 작습니다 %d %d %d" +#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c +msgid "input must be a dense ndarray" +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Buffer elements must be 4 bytes long or less" -msgstr "버퍼 요소는 4바이트 이하여야 합니다" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "first argument must be a function" +msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Buffer is not a bytearray." -msgstr "버퍼는 바이트 배열이 아닙니다." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "function has the same sign at the ends of interval" +msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, c-format -msgid "Buffer length %d too big. It must be less than %d" -msgstr "버퍼 길이 %d가 너무 큽니다. 그것은 %d보다 작아야 합니다" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter should be > 0" +msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -#: ports/cxd56/common-hal/sdioio/SDCard.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c -#: shared-module/sdcardio/SDCard.c -#, c-format -msgid "Buffer must be a multiple of %d bytes" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter must be > 0" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -#, c-format -msgid "Buffer too short by %d bytes" -msgstr "버퍼가 %d 바이트로 너무 짧습니다" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be iterable" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c -msgid "Buffer too small" -msgstr "버퍼가 너무 작습니다" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "initial values must be iterable" +msgstr "" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, c-format -msgid "Bus pin %d is already in use" -msgstr "Bus 핀 %d은 이미 사용 중입니다" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be of equal length" +msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "Byte buffer must be 16 bytes." -msgstr "잘못된 크기의 버퍼. 16 바이트 여야합니다." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sosfilt requires iterable arguments" +msgstr "" -#: shared-bindings/aesio/aes.c -msgid "CBC blocks must be multiples of 16 bytes" -msgstr "CBC 블록은 16 바이트의 배수여야 합니다" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "input must be one-dimensional" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CIRCUITPY drive could not be found or created." -msgstr "CIRCUITPY 드라이브를 찾거나 만들 수 없습니다." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be an ndarray" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "CRC or checksum was invalid" -msgstr "CRC 또는 checksum이 잘못되었습니다" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of shape (n_section, 2)" +msgstr "" -#: py/objtype.c -msgid "Call super().__init__() before accessing native object." -msgstr "네이티브 개체에 액세스하기 전에 super().__init__()를 호출하십시오." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of float type" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -#, fuzzy -msgid "Camera init" -msgstr "카메라 초기화" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos array must be of shape (n_section, 6)" +msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on RTC IO from deep sleep." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos[:, 3] should be all ones" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on one low pin while others alarm high from deep sleep." +#: extmod/ulab/code/ulab_tools.c +msgid "axis is out of bounds" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on two low pins from deep sleep." +#: extmod/ulab/code/ulab_tools.c +msgid "size is defined for ndarrays only" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "Can't set CCCD on local Characteristic" -msgstr "로컬 특성에 CCCD를 설정할 수 없습니다" +#: extmod/ulab/code/ulab_tools.c +msgid "input must be square matrix" +msgstr "" -#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c -#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c -#: shared-bindings/usb_video/__init__.c -msgid "Cannot change USB devices now" -msgstr "현재 USB 디바이스를 변경할 수 없습니다" +#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c +msgid "input must be an ndarray" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot create a new Adapter; use _bleio.adapter;" -msgstr "_bleio.adapter를 사용해서; 새로운 Adapter를 만들 수 없습니다;" +#: extmod/ulab/code/utils/utils.c +msgid "out must be a float dense array" +msgstr "" -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Cannot delete values" -msgstr "값을 삭제할 수 없습니다" +#: extmod/ulab/code/utils/utils.c +msgid "offset is too large" +msgstr "" -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c -#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c -#: ports/nordic/common-hal/digitalio/DigitalInOut.c -#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c -msgid "Cannot get pull while in output mode" -msgstr "출력 모드에서는 끌어올 수 없습니다" +#: extmod/ulab/code/utils/utils.c +msgid "out array is too small" +msgstr "" -#: ports/nordic/common-hal/microcontroller/Processor.c -msgid "Cannot get temperature" -msgstr "온도 데이터를 수신 할 수 없습니다" - -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot have scan responses for extended, connectable advertisements." -msgstr "확장되고 연결 가능한 광고에 대한 검색 응답을 가질 수 없습니다." - -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot pull on input-only pin." -msgstr "입력 전용 핀을 끌어올 수 없습니다." +#: extmod/vfs_fat.c py/moderrno.c +msgid "Read-only filesystem" +msgstr "읽기 전용 파일 시스템" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Cannot record to a file" -msgstr "파일에 녹음 할 수 없습니다" +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "닫힌 파일에서 I/O 작업" -#: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "USB를 통해 표시될 때 '/'은 다시 마운트할 수 없습니다." +#: extmod/vfs_posix_file.c +msgid "poll on file not available on win32" +msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Cannot set value when direction is input." -msgstr "방향이 입력되면 값을 설정할 수 없습니다." +#: main.c +msgid "Done" +msgstr "완료" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "RS485 모드에서는 RTS 또는 CTS를 지정할 수 없습니다" +#: main.c +msgid " output:\n" +msgstr " 산출:\n" -#: py/objslice.c -msgid "Cannot subclass slice" +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" msgstr "" +"자동 새로 고침이 켜져 있습니다. USB를 통해 파일을 저장하여 실행하십시오. 비활" +"성화하려면 REPL을 입력하십시오.\n" -#: ports/nordic/common-hal/alarm/pin/PinAlarm.c -#, fuzzy -msgid "Cannot wake on pin edge, only level" -msgstr "핀의 에지에서 깨울 수 없고, 레벨에서만 깨울 수 있습니다" - -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -#, fuzzy -msgid "Cannot wake on pin edge. Only level." -msgstr "핀의 에지에서는 깨울 수 없습니다. 레벨에서만 깨울 수 있습니다." +#: main.c +msgid "Auto-reload is off.\n" +msgstr "자동 재 장전이 꺼져 있습니다\n" -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "CharacteristicBuffer writing not provided" -msgstr "CharacteristicBuffer 쓰기는 제공되지 않습니다" +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "CircuitPython 핵심 코드가 심하게 충돌했습니다. 앗!\n" +#: main.c +msgid " not found.\n" +msgstr " 찾을 수 없습니다.\n" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Clock unit in use" -msgstr "시계 장치가 사용 중입니다" +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "" -#: shared-bindings/_bleio/Connection.c +#: main.c msgid "" -"Connection has been disconnected and can no longer be used. Create a new " -"connection." -msgstr "연결이 끊어져 더 이상 사용할 수 없습니다. 새로운 연결을 만드십시오." +"\n" +"Code stopped by auto-reload. Reloading soon.\n" +msgstr "" +"\n" +"자동 업로드에 의해 코드가 중지되었습니다. 곧 다시 로드됩니다.\n" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays have different lengths" -msgstr "좌표 배열의 길이가 다릅니다" +#: main.c +msgid "" +"\n" +"Code done running.\n" +msgstr "" +"\n" +"코드 실행 완료.\n" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays types have different sizes" -msgstr "좌표 배열 유형은 크기가 다릅니다" +#: main.c +msgid "Woken up by alarm.\n" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Could not set address" -msgstr "주소를 설정할 수 없습니다" +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" +msgstr "아무 키나 눌러 REPL을 입력한다. 다시 로드할땐 CTRL-D를 사용한다.\n" -#: ports/stm/common-hal/busio/UART.c -msgid "Could not start interrupt, RX busy" -msgstr "인터럽트를 시작할 수 없습니다, RX가 사용 중입니다" +#: main.c +msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +msgstr "알람, CTRL-C 또는 파일을 작성하기 전까지 딥 슬립을 하는 척합니다\n" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Couldn't allocate decoder" -msgstr "디코더를 할당할 수 없습니다" +#: main.c +msgid "UID:" +msgstr "UID:" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Channel Init Error" -msgstr "DAC 채널 초기화 오류" +#: main.c +msgid "soft reboot\n" +msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Device Init Error" -msgstr "DAC 장치 초기화 오류" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c +#: ports/stm/common-hal/audioio/AudioOut.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c +#: shared-module/busdisplay/BusDisplay.c shared-module/ssl/SSLContext.c +msgid "%q init failed" +msgstr "%q 초기화 실패" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "DAC already in use" -msgstr "DAC가 현재 사용 중입니다" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -msgid "Data 0 pin must be byte aligned" -msgstr "데이터 0 핀은 바이트 정렬되어야 합니다" +#: ports/analog/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c +#: shared-bindings/bitmaptools/__init__.c shared-bindings/canio/Match.c +#: shared-bindings/time/__init__.c +#, fuzzy +msgid "%q out of range" +msgstr "%q가 범위를 벗어남" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "데이터 청크는 fmt 청크를 따라야 합니다" +#: ports/analog/common-hal/busio/SPI.c +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid state" +msgstr "잘못된 상태" -#: shared-module/jpegio/JpegDecoder.c -msgid "Data format error (may be broken data)" -msgstr "데이터 형식 오류(손상된 데이터일 수 있습니다)" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data not supported with directed advertising" -msgstr "직접 광고에서는 데이터가 지원되지 않습니다" +#: ports/analog/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "RS485" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data too large for advertisement packet" -msgstr "광고 (브로드 캐스트) 패킷에 대한 데이터가 너무 큽니다" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -#, fuzzy -msgid "Deep sleep pins must use a rising edge with pulldown" -msgstr "딥 슬립 핀은 풀다운이 있는 상승 에지를 사용해야 합니다" +#: ports/analog/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Both RX and TX required for flow control" +msgstr "플로우 제어에 RX와 TX가 모두 필요합니다" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Destination capacity is smaller than destination_length." -msgstr "대상 용량이 destination_length보다 작습니다." +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c +msgid "Failed to allocate %q buffer" +msgstr "%q 버퍼 할당에 실패했습니다" -#: shared-module/jpegio/JpegDecoder.c -msgid "Device error or wrong termination of input stream" -msgstr "장치 오류 또는 입력 스트림의 잘못된 종료" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" -#: ports/nordic/common-hal/audiobusio/I2SOut.c -msgid "Device in use" -msgstr "사용 중인 장치" +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display must have a 16 bit colorspace." -msgstr "디스플레이는 16 비트 색 공간을 가져야 합니다." +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "사용중인 모든 UART주변 기기" -#: shared-bindings/busdisplay/BusDisplay.c +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c +#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/microcontroller/Processor.c +#: ports/espressif/common-hal/mipidsi/Display.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +#: ports/raspberrypi/bindings/picodvi/Framebuffer.c +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display rotation must be in 90 degree increments" -msgstr "디스플레이 회전은 90도씩 증가해야 합니다" +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c +msgid "Invalid %q" +msgstr "잘못된 %q" -#: main.c -msgid "Done" -msgstr "완료" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Drive mode not used when direction is input." -msgstr "방향을 입력할 때 드라이브 모드는 사용되지 않습니다." +#: ports/atmel-samd/audio_dma.c +#, fuzzy +msgid "All sync event channels in use" +msgstr "모든 동기화 이벤트 채널이 사용 중입니다" -#: py/obj.c -msgid "During handling of the above exception, another exception occurred:" -msgstr "위 예외를 처리하는 동안, 또 다른 예외가 발생하였습니다:" +#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "내부 오디오 버퍼가 너무 작습니다" -#: shared-bindings/aesio/aes.c -msgid "ECB only operates on 16 bytes at a time" -msgstr "ECB는 한 번에 16 바이트에서만 작동합니다" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "" -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/canio/CAN.c -msgid "ESP-IDF memory allocation failed" -msgstr "ESP-IDF 메모리 할당에 실패하였습니다" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "" -#: extmod/modre.c -msgid "Error in regex" -msgstr "Regex에 오류가 있습니다." +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "" + +#: ports/atmel-samd/common-hal/_pew/PewPew.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "All timers in use" +msgstr "모든 타이머가 사용 중입니다" +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: ports/atmel-samd/common-hal/countio/Counter.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/max3421e/Max3421E.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +msgid "Internal resource(s) in use" +msgstr "" + +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c #: supervisor/shared/safe_mode.c -msgid "Error in safemode.py." -msgstr "safemode.py에 오류가 있습니다." +msgid "Unknown reason." +msgstr "" -#: shared-bindings/alarm/__init__.c -msgid "Expected a kind of %q" -msgstr "%q 유형이 필요합니다" +#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +#: ports/nordic/common-hal/alarm/time/TimeAlarm.c +#: ports/stm/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -#, fuzzy -msgid "Extended advertisements with scan response not supported." -msgstr "검색 응답이 있는 확장 광고는 지원되지 않습니다." +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "No DAC on chip" +msgstr "칩에 DAC가 없습니다" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is defined for ndarrays only" -msgstr "FFT는 ndarrays에 대해서만 정의됩니다" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "%q and %q must share a clock unit" +msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is implemented for linear arrays only" -msgstr "FFT는 선형 배열에 대해서만 구현됩니다" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "" -#: shared-bindings/ps2io/Ps2.c -msgid "Failed sending command." -msgstr "명령을 보내는 것에 실패했습니다." +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "시계 장치가 사용 중입니다" -#: ports/nordic/sd_mutex.c +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "무료 GCLKs가 없습니다" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "No DMA channel found" +msgstr "DMA 채널을 찾을 수 없습니다" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c #, c-format -msgid "Failed to acquire mutex, err 0x%04x" -msgstr "뮤텍스 획득에 실패했습니다, 오류 0x%04x" +msgid "Only 8 or 16 bit mono with %dx oversampling supported." +msgstr "%dx 오버샘플링이 포함된 8 또는 16 비트 모노만 지원됩니다." -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Failed to add service TXT record" -msgstr "서비스 TXT 레코드를 추가하는 것에 실패했습니다" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "" -#: shared-bindings/mdns/Server.c -msgid "" -"Failed to add service TXT record; non-string or bytes found in txt_records" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC가 현재 사용 중입니다" + +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" msgstr "" -"서비스 TXT 레코드를 추가하는 것에 실패했습니다; txt_records에서 비문자열 또" -"는 바이트가 발견되었습니다" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "Failed to allocate %q buffer" -msgstr "%q 버퍼 할당에 실패했습니다" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#, fuzzy +msgid "All event channels in use" +msgstr "모든 이벤트 채널이 사용 중입니다" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to allocate Wifi memory" -msgstr "Wifi 메모리 할당에 실패했습니다" +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/I2C.c +#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/busio/I2C.c +msgid "No pull up found on SDA or SCL; check your wiring" +msgstr "SDA 또는 SCL에서 풀업을 찾을 수 없습니다; 케이블 연결을 확인하십시오" -#: ports/espressif/common-hal/wifi/ScannedNetworks.c -msgid "Failed to allocate wifi scan memory" -msgstr "wifi 검색 메모리 할당에 실패했습니다" +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "%q must be power of 2" +msgstr "%q는 2의 거듭제곱이어야 합니다" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Failed to buffer the sample" -msgstr "샘플 버퍼링에 실패했습니다" +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c +#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c +#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c +#: shared-bindings/paralleldisplaybus/ParallelBus.c +#: shared-bindings/qspibus/QSPIBus.c shared-module/bitbangio/SPI.c +msgid "No %q pin" +msgstr "%q 핀이 없습니다" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: internal error" -msgstr "연결에 실패했습니다: 내부 오류" +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +#, fuzzy +msgid "All RX FIFOs in use" +msgstr "모든 RX FIFOs가 사용 중입니다" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: timeout" -msgstr "연결에 실패했습니다: 시간 초과" +#: ports/atmel-samd/common-hal/canio/Listener.c +#, fuzzy +msgid "Already have all-matches listener" +msgstr "이미 모든 일치 리스너가 있습니다" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Failed to parse MP3 file" -msgstr "MP3 파일 분석에 실패했습니다" +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "필터가 너무 복잡합니다" -#: ports/nordic/sd_mutex.c +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +#: ports/nordic/common-hal/digitalio/DigitalInOut.c +#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "출력 모드에서는 끌어올 수 없습니다" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_pins[%d]" +msgstr "잘못된 data_pins[%d]" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c +#: shared-bindings/microcontroller/Pin.c +msgid "Invalid %q pin" +msgstr "잘못된 %q 핀" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +#: ports/cxd56/common-hal/microcontroller/__init__.c +#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c +msgid "No bootloader present" +msgstr "" + +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "데이터 0 핀은 바이트 정렬되어야 합니다" + +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c #, c-format -msgid "Failed to release mutex, err 0x%04x" -msgstr "뮤텍스 해제에 실패했습니다, 오류 0x%04x" +msgid "Bus pin %d is already in use" +msgstr "Bus 핀 %d은 이미 사용 중입니다" -#: supervisor/shared/safe_mode.c -#, fuzzy -msgid "Failed to write internal flash." -msgstr "내부 플래시를 쓰는 것에 실패했습니다." +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/pulseio/PulseIn.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c +#: shared-bindings/ps2io/Ps2.c +msgid "pop from empty %q" +msgstr "" -#: py/moderrno.c -msgid "File exists" -msgstr "파일이 있습니다" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "Input taking too long" +msgstr "입력이 너무 오래 걸린다" -#: shared-module/os/getenv.c -msgid "File not found" -msgstr "파일을 찾을 수 없습니다" +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "다른 전송이 이미 활성화되었습니다" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "Filters too complex" -msgstr "필터가 너무 복잡합니다" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "%q failure: %d" +msgstr "%q 실패: %d" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is duplicate" -msgstr "펌웨어가 중복되었습니다" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/cxd56/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c +#: shared-module/sdcardio/SDCard.c +#, c-format +msgid "Buffer must be a multiple of %d bytes" +msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is invalid" -msgstr "펌웨어가 잘못되었습니다" +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is too big" -msgstr "펌웨어가 너무 큽니다" +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/stm/common-hal/busio/UART.c +msgid "UART init" +msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" -msgstr "L8 색상 공간의 경우, 입력 비트맵은 픽셀 당 8 비트를 가져야 합니다" +#: ports/cxd56/common-hal/camera/Camera.c +#, fuzzy +msgid "Camera init" +msgstr "카메라 초기화" -#: shared-bindings/bitmaptools/__init__.c -msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" -msgstr "RGB 색상 공간의 경우, 입력 비트맵은 픽셀 당 16 비트를 가져야 합니다" +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Size not supported" +msgstr "" #: ports/cxd56/common-hal/camera/Camera.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c +msgid "Buffer too small" +msgstr "버퍼가 너무 작습니다" + +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "지원되지 않는 형식입니다" -#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c -msgid "" -"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" -msgstr "" -"주파수는 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 또는 1008 Mhz 여야 " -"합니다" - -#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c -#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c -msgid "Function requires lock" -msgstr "이 함수에는 잠금이 필요합니다" - #: ports/cxd56/common-hal/gnss/GNSS.c msgid "GNSS init" msgstr "GNSS 초기화" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Generic Failure" -msgstr "일반 오류" - -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Group already used" -msgstr "이미 사용된 그룹" - -#: supervisor/shared/safe_mode.c -msgid "Hard fault: memory access or instruction error." -msgstr "치명적인 실수: 메모리 액세스 또는 명령 오류." - -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c -#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c -#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c -msgid "Hardware in use, try alternative pins" -msgstr "하드웨어가 사용 중입니다, 대체 핀을 사용해보십시오" +#: ports/cxd56/common-hal/sdioio/SDCard.c +msgid "SDCard init" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Heap allocation when VM not running." -msgstr "VM이 작동하지 않을 때 힙이 할당됩니다." +#: ports/espressif/bindings/espnow/ESPNow.c +#: ports/espressif/common-hal/espulp/ULP.c +#: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize.c +msgid "Already running" +msgstr "이미 실행 중입니다" -#: extmod/vfs_posix_file.c py/objstringio.c -msgid "I/O operation on closed file" -msgstr "닫힌 파일에서 I/O 작업" +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q는 %q입니다" -#: ports/stm/common-hal/busio/I2C.c -msgid "I2C init error" -msgstr "I2C 초기화 오류" +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "" -#: ports/raspberrypi/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "I2C peripheral in use" -msgstr "I2C 주변 기기가 사용 중입니다" +#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h +#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h +msgid "You pressed the BOOT button at start up." +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "In-buffer elements must be <= 4 bytes long" -msgstr "버퍼 내 요소 길이는 <= 4여야 합니다" +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "" -#: shared-bindings/_pew/PewPew.c -msgid "Incorrect buffer size" -msgstr "잘못된 버퍼 크기" +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Init program size invalid" -msgstr "초기화 프로그램의 크기가 잘못되었습니다" +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +#: ports/espressif/boards/vidi_x/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin direction conflicts with initial out pin direction" -msgstr "초기 설정한 핀의 방향이 초기 바깥쪽 핀의 방향과 충돌합니다" +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin state conflicts with initial out pin state" -msgstr "초기 설정한 핀의 상태가 초기 바깥쪽 핀의 상태와 충돌합니다" +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "" -#: shared-bindings/bitops/__init__.c -#, fuzzy, c-format -msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" -msgstr "입력 버퍼 길이 (%d) 는 스트랜드 수 (%d)의 배수여야 한다" +#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h +msgid "You pressed button DOWN at start up." +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -msgid "Input taking too long" -msgstr "입력이 너무 오래 걸린다" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Update failed" +msgstr "" -#: py/moderrno.c -msgid "Input/output error" -msgstr "입력/출력 오류" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Scan already in progress. Stop with stop_scan." +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient authentication" -msgstr "불충분한 인증" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: internal error" +msgstr "연결에 실패했습니다: 내부 오류" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient encryption" -msgstr "불충분한 암호화" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data too large for advertisement packet" +msgstr "광고 (브로드 캐스트) 패킷에 대한 데이터가 너무 큽니다" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient memory pool for the image" -msgstr "이미지에 대한 메모리 풀이 부족합니다" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Already advertising." +msgstr "이미 광고 중입니다." -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient stream input buffer" -msgstr "불충분한 스트림 입력 버퍼" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#, fuzzy +msgid "Extended advertisements with scan response not supported." +msgstr "검색 응답이 있는 확장 광고는 지원되지 않습니다." -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Interface must be started" -msgstr "인터페이스를 시작해야 합니다" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data not supported with directed advertising" +msgstr "직접 광고에서는 데이터가 지원되지 않습니다" -#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c -msgid "Internal audio buffer too small" -msgstr "내부 오디오 버퍼가 너무 작습니다" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#, c-format +msgid "Timeout is too long: Maximum timeout length is %d seconds" +msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "Internal define error" -msgstr "내부 정의 오류" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +msgid "MITM security not supported" +msgstr "" -#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c -msgid "Internal error" -msgstr "내부 오류" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Internal error #%d" -msgstr "내부 오류 #%d" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: ports/atmel-samd/common-hal/countio/Counter.c -#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c -#: ports/atmel-samd/common-hal/max3421e/Max3421E.c -#: ports/atmel-samd/common-hal/ps2io/Ps2.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-bindings/pwmio/PWMOut.c -msgid "Internal resource(s) in use" +#: ports/espressif/common-hal/_bleio/Characteristic.c +msgid "Too many descriptors" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Internal watchdog timer expired." -msgstr "내부 감시 타이머가 만료되었습니다." +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "이 특성에 대한 CCCD가 없습니다" -#: supervisor/shared/safe_mode.c -msgid "Interrupt error." -msgstr "인터럽트 오류." +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "로컬 특성에 CCCD를 설정할 수 없습니다" -#: shared-module/jpegio/JpegDecoder.c -msgid "Interrupted by output function" -msgstr "출력 함수로 인해 종료되었다" +#: ports/espressif/common-hal/_bleio/Connection.c +#: ports/nordic/common-hal/_bleio/Connection.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "" -#: ports/espressif/common-hal/_bleio/Service.c -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/espressif/common-hal/microcontroller/Processor.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c -#: ports/raspberrypi/bindings/picodvi/Framebuffer.c -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q" -msgstr "잘못된 %q" +#: ports/espressif/common-hal/_bleio/Descriptor.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q and %q" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Writes not supported on Characteristic" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c -#: shared-bindings/microcontroller/Pin.c -msgid "Invalid %q pin" -msgstr "잘못된 %q 핀" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Total data to write is larger than %q" +msgstr "" -#: ports/stm/common-hal/analogio/AnalogIn.c -msgid "Invalid ADC Unit value" -msgstr "잘못된 ADC 단위 값" +#: ports/espressif/common-hal/_bleio/__init__.c +#, fuzzy +msgid "Nimble out of memory" +msgstr "빠른 메모리 부족" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid BLE parameter" msgstr "잘못된 BLE 파라미터" -#: shared-bindings/wifi/Radio.c -msgid "Invalid BSSID" -msgstr "잘못된 BSSID" - -#: shared-bindings/wifi/Radio.c -msgid "Invalid MAC address" -msgstr "잘못된 MAC 주소" - -#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c -msgid "Invalid argument" -msgstr "잘못된 인수" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#: ports/zephyr-cp/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "Not connected" +msgstr "연결되지 않았습니다" -#: shared-module/displayio/Bitmap.c -msgid "Invalid bits per value" -msgstr "값 당 잘못된 비트" +#: ports/espressif/common-hal/_bleio/__init__.c +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Already in progress" +msgstr "" -#: shared-module/os/getenv.c +#: ports/espressif/common-hal/_bleio/__init__.c #, c-format -msgid "Invalid byte %.*s" -msgstr "잘못된 바이트 %.*s" +msgid "Unknown system firmware error at %s:%d: %d" +msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: ports/espressif/common-hal/_bleio/__init__.c #, c-format -msgid "Invalid data_pins[%d]" -msgstr "잘못된 data_pins[%d]" - -#: shared-module/msgpack/__init__.c -msgid "Invalid format" -msgstr "잘못된 형식" - -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" -msgstr "형식 청크 크기가 잘못되었습니다" - -#: shared-bindings/wifi/Radio.c -msgid "Invalid hex password" -msgstr "잘못된 16진수 패스워드" - -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Invalid multicast MAC address" -msgstr "잘못된 멀티캐스트 MAC 주소" - -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid size" -msgstr "잘못된 크기" - -#: shared-module/ssl/SSLSocket.c -msgid "Invalid socket for TLS" -msgstr "TLS에 대한 잘못된 소켓" - -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid state" -msgstr "잘못된 상태" - -#: shared-module/os/getenv.c -msgid "Invalid unicode escape" -msgstr "잘못된 유니코드 이스케이프" +msgid "Unknown system firmware error: %d" +msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Key must be 16, 24, or 32 bytes long" -msgstr "키는 16, 24, 또는 32 바이트 길이여야 합니다" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient authentication" +msgstr "불충분한 인증" -#: shared-module/os/getenv.c -msgid "Key not found" -msgstr "키를 찾을 수 없습니다" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient encryption" +msgstr "불충분한 암호화" -#: shared-module/is31fl3741/FrameBuffer.c -msgid "LED mappings must match display size" -msgstr "LED 매핑은 디스플레이 크기와 일치해야 합니다" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error at %s:%d: %d" +msgstr "" -#: py/compile.c -msgid "LHS of keyword arg must be an id" -msgstr "키워드 인수의 LHS 는 id 여야 합니다" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error: %d" +msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer already in a group" -msgstr "레이어가 이미 그룹에 있습니다" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +#, fuzzy +msgid "Cannot wake on pin edge. Only level." +msgstr "핀의 에지에서는 깨울 수 없습니다. 레벨에서만 깨울 수 있습니다." -#: shared-module/displayio/Group.c -msgid "Layer must be a Group or TileGrid subclass" -msgstr "레이어는 그룹 또는 TileGrid 하위 클래스 여야 합니다" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot pull on input-only pin." +msgstr "입력 전용 핀을 끌어올 수 없습니다." -#: shared-bindings/audiocore/RawSample.c -msgid "Length of %q must be an even multiple of channel_count * type_size" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on two low pins from deep sleep." msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "MAC address was invalid" -msgstr "MAC 주소는 잘못되었습니다" - -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/espressif/common-hal/_bleio/Descriptor.c -msgid "MITM security not supported" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" -#: shared-bindings/is31fl3741/IS31FL3741.c -msgid "Mapping must be a tuple" -msgstr "매핑은 투플이어야 합니다" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on RTC IO from deep sleep." +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched data size" -msgstr "일치하지 않는 데이터 크기" +#: ports/espressif/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set." +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched swap flag" -msgstr "일치하지 않는 스왑 플래그" +#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c +msgid "Only one %q can be set in deep sleep." +msgstr "딥 슬립에서는 하나의 %q만 설정할 수 있습니다." -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/espressif/common-hal/analogbufio/BufferedIn.c #, fuzzy -msgid "Missing first_in_pin. %q[%u] reads pin(s)" -msgstr "first_in_pin이 누락되어 있습니다. %q[%u]이 pin(s)을 읽습니다" - -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" -msgstr "first_in_pin이 누락되었습니다. %q[%u]는 pin(s)에서 이동합니다" +msgid "%q must be array of type 'H'" +msgstr "%q는 'H' 유형의 배열이어야 합니다" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] waits based on pin" -msgstr "first_in_pin이 누락되었습니다. %q[%u]는 핀에 따라 대기 중입니다" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +#: shared-bindings/audioi2sin/I2SIn.c +msgid "%q must be 8, 16, 24, or 32" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" -msgstr "first_out_pin이 누락되었습니다. %q[%u]는 pin(s)으로 이동합니다" +#: ports/espressif/common-hal/audiobusio/__init__.c +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#, fuzzy +msgid "Peripheral in use" +msgstr "주변 기기가 사용 중입니다" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] writes pin(s)" -msgstr "first_out_pin이 누락되었습니다. %q[%u]는 pin(s)에 씁니다" +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 8 or 16" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, fuzzy -msgid "Missing first_set_pin. %q[%u] sets pin(s)" -msgstr "first_set_pin이 누락되었습니다. %q[%u]는 pin(s)을 설정합니다" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#, fuzzy -msgid "Missing jmp_pin. %q[%u] jumps on pin" -msgstr "jmp_pin이 누락되었습니다. %q[%u] 핀으로 점프합니다" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" -#: shared-module/storage/__init__.c -msgid "Mount point directory missing" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c -msgid "Must be a %q subclass." -msgstr "%q의 하위클래스여야 합니다." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -msgid "Must provide 5/6/5 RGB pins" -msgstr "5/6/5 RGB 핀을 제공해야 합니다" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c -msgid "Must provide MISO or MOSI pin" -msgstr "MISO 또는 MOSI 핀을 제공해야 합니다" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Must use a multiple of 6 rgb pins, not %d" -msgstr "%d이 아닌, 6 rgb 핀을 여러 개 사용해야 합니다" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "NLR jump failed. Likely memory corruption." -msgstr "NLR 는 점프에 실패했습니다. 아마도 메모리 손상일 것입니다." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" -#: ports/espressif/common-hal/nvm/ByteArray.c -msgid "NVS Error" -msgstr "NVS 오류" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" -#: shared-bindings/socketpool/SocketPool.c -msgid "Name or service not known" -msgstr "이름 또는 서비스를 알 수 없습니다" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "New bitmap must be same size as old bitmap" -msgstr "새로운 비트맵은 원본 비트맵과 크기가 같아야 합니다" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/nordic/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "사용 중인 모든 I2C주변 기기" -#: ports/espressif/common-hal/_bleio/__init__.c -#, fuzzy -msgid "Nimble out of memory" -msgstr "빠른 메모리 부족" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c +msgid "Unable to create lock" +msgstr "" + +#: ports/espressif/common-hal/busio/SPI.c +msgid "SPI configuration failed" +msgstr "" + +#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "사용중인 모든 SPI주변 기기" -#: ports/atmel-samd/common-hal/busio/UART.c #: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/canio/CAN.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "ESP-IDF memory allocation failed" +msgstr "ESP-IDF 메모리 할당에 실패하였습니다" + #: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/SPI.c #: ports/mimxrt10xx/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c -#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c -#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c -#: shared-bindings/paralleldisplaybus/ParallelBus.c -#: shared-module/bitbangio/SPI.c -msgid "No %q pin" -msgstr "%q 핀이 없습니다" +msgid "Cannot specify RTS or CTS in RS485 mode" +msgstr "RS485 모드에서는 RTS 또는 CTS를 지정할 수 없습니다" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "No CCCD for this Characteristic" -msgstr "이 특성에 대한 CCCD가 없습니다" +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "RS485 inversion specified when not in RS485 mode" +msgstr "RS485 모드가 아닐 때 RS485 반전이 지정됩니다" -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "No DAC on chip" -msgstr "칩에 DAC가 없습니다" +#: ports/espressif/common-hal/canio/CAN.c +msgid "Baudrate not supported by peripheral" +msgstr "주변 기기에서 전송 속도가 지원되지 않습니다" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA channel found" -msgstr "DMA 채널을 찾을 수 없습니다" +#: ports/espressif/common-hal/canio/CAN.c +#, fuzzy +msgid "All CAN peripherals are in use" +msgstr "모든 CAN 주변 기기가 사용 중입니다" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA pacing timer found" -msgstr "DMA 간격 타이머를 찾을 수 없습니다" +#: ports/espressif/common-hal/canio/CAN.c +msgid "loopback + silent mode not supported by peripheral" +msgstr "" -#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#: ports/espressif/common-hal/canio/CAN.c #, c-format -msgid "No I2C device at address: 0x%x" -msgstr "주소에 I2C 장치가 없습니다: 0x%x" - -#: supervisor/shared/web_workflow/web_workflow.c -msgid "No IP" -msgstr "IP가 없습니다" +msgid "twai_driver_install returned esp-idf error #%d" +msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/__init__.c -#: ports/cxd56/common-hal/microcontroller/__init__.c -#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c -msgid "No bootloader present" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_start returned esp-idf error #%d" msgstr "" -#: shared-module/usb/core/Device.c -#, fuzzy -msgid "No configuration set" -msgstr "구성이 설정되어 있지 않습니다" +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +msgid "Must provide 5/6/5 RGB pins" +msgstr "5/6/5 RGB 핀을 제공해야 합니다" -#: shared-bindings/_bleio/PacketBuffer.c -msgid "No connection: length cannot be determined" -msgstr "연결이 없습니다: 길이를 결정할 수 없습니다" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is duplicate" +msgstr "펌웨어가 중복되었습니다" -#: shared-bindings/board/__init__.c -msgid "No default %q bus" -msgstr "기본 버스 %q가 없습니다" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "펌웨어가 잘못되었습니다" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -msgid "No free GCLKs" -msgstr "무료 GCLKs가 없습니다" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "펌웨어가 너무 큽니다" -#: shared-bindings/os/__init__.c -msgid "No hardware random available" -msgstr "임의의 하드웨어를 사용할 수 없습니다" +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c +msgid "no such attribute" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Generic Failure" +msgstr "일반 오류" + +#: ports/espressif/common-hal/espidf/__init__.c #, fuzzy -msgid "No in in program" -msgstr "프로그램에 입력이 없습니다" +msgid "Out of memory" +msgstr "메모리 부족" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c +msgid "Invalid argument" +msgstr "잘못된 인수" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Invalid size" +msgstr "잘못된 크기" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Requested resource not found" +msgstr "" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Operation or feature not supported" +msgstr "작업 또는 기능이 지원되지 않습니다" + +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c #, fuzzy -msgid "No in or out in program" -msgstr "프로그램에 입력 또는 출력이 없습니다" +msgid "Operation timed out" +msgstr "작업 시간 초과되었습니다" -#: py/objint.c shared-bindings/time/__init__.c -msgid "No long integer support" -msgstr "긴 정수 지원이 없습니다" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Received response was invalid" +msgstr "수신된 응답이 잘못되었습니다" -#: shared-bindings/wifi/Radio.c -msgid "No network with that ssid" -msgstr "이 ssid를 사용하는 네트워크가 없습니다" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "CRC or checksum was invalid" +msgstr "CRC 또는 checksum이 잘못되었습니다" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No out in program" -msgstr "프로그램에 출력이 없습니다" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Version was invalid" +msgstr "" -#: ports/atmel-samd/common-hal/busio/I2C.c -#: ports/espressif/common-hal/busio/I2C.c -#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/busio/I2C.c -msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "SDA 또는 SCL에서 풀업을 찾을 수 없습니다; 케이블 연결을 확인하십시오" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "MAC address was invalid" +msgstr "MAC 주소는 잘못되었습니다" -#: shared-module/touchio/TouchIn.c -msgid "No pulldown on pin; 1Mohm recommended" -msgstr "핀에 풀다운이 없습니다; 1Mohm를 권장합니다" +#: ports/espressif/common-hal/espidf/__init__.c +#, fuzzy, c-format +msgid "%s error 0x%x" +msgstr "%s 오류 0x%x" -#: py/moderrno.c -msgid "No space left on device" -msgstr "장치에 남은 공간이 없습니다" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "프로그램이 너무 깁니다" -#: py/moderrno.c -msgid "No such device" -msgstr "해당 장치가 없습니다" +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/mipidsi/Bus.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/usb_host/Port.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c +msgid "%q in use" +msgstr "%q 사용 중입니다" -#: py/moderrno.c -msgid "No such file/directory" -msgstr "해당 파일/디렉토리가 없습니다" +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "하나의 %q만 설정할 수 있습니다." -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "No timer available" -msgstr "사용 가능한 타이머가 없습니다" +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +#, fuzzy +msgid "Only one address is allowed" +msgstr "오직 하나의 주소만 허용됩니다" -#: shared-module/usb/core/Device.c -msgid "No usb host port initialized" -msgstr "usb 호스트 포트가 초기화되지 않았습니다" +#: ports/espressif/common-hal/max3421e/Max3421E.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Nordic system firmware out of memory" -msgstr "Nordic 시스템 펌웨어에 메모리가 부족합니다" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS only works with built-in WiFi" +msgstr "" -#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string" -msgstr "유효한 IP 문자열이 아닙니다" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS already initialized" +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "Not connected" -msgstr "연결되지 않았습니다" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Unable to start mDNS query" +msgstr "" -#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c -#: shared-bindings/audiopwmio/PWMAudioOut.c -msgid "Not playing" -msgstr "재생되지 않았습니다" +#: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nordic/common-hal/memorymap/AddressRange.c +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "주소 범위가 허용되지 않습니다" -#: shared-module/jpegio/JpegDecoder.c -#, fuzzy -msgid "Not supported JPEG standard" -msgstr "지원되지 않는 JPEG 표준" +#: ports/espressif/common-hal/nvm/ByteArray.c +msgid "NVS Error" +msgstr "NVS 오류" #: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c #: ports/espressif/common-hal/sdioio/SDCard.c @@ -1609,751 +1593,873 @@ msgstr "지원되지 않는 JPEG 표준" msgid "Number of data_pins must be %d or %d, not %d" msgstr "" -#: shared-bindings/util.c -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." +#: ports/espressif/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" msgstr "" -"개체가 초기화 해제되어 더 이사 사용될 수 없습니다. 새로운 개체를 만드십시오." -#: ports/nordic/common-hal/busio/UART.c -msgid "Odd parity is not supported" -msgstr "홀수 패리티는 지원되지 않습니다" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Off" -msgstr "꺼짐 (연결 끊김)" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-bindings/pwmio/PWMOut.c +#: supervisor/shared/settings.c +msgid "Internal error" +msgstr "내부 오류" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Ok" -msgstr "켜짐 (연결됨)" +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c #, c-format -msgid "Only 8 or 16 bit mono with %dx oversampling supported." -msgstr "%dx 오버샘플링이 포함된 8 또는 16 비트 모노만 지원됩니다." +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -msgid "Only IPv4 addresses supported" -msgstr "IPv4 주소만 지원됩니다" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Only IPv4 sockets supported" -msgstr "IPv4 소켓만 지원됩니다" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" -#: shared-module/displayio/OnDiskBitmap.c +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" + +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "" -"Only Windows format, uncompressed BMP supported: given header size is %d" -msgstr "윈도우 형식, 비압축 BMP만 지원됩니다: 지정된 헤더 크기는 %d 입니다" +msgid "SDIO Init Error 0x%02x" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -#, fuzzy -msgid "Only connectable advertisements can be directed" -msgstr "연결 가능한 광고만 지시할 수 있습니다" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Unsupported socket type" +msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Only edge detection is available on this hardware" -msgstr "이 하드웨어에서는 에지 감지만 가능합니다" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Out of sockets" +msgstr "소켓 부족" -#: shared-bindings/ipaddress/__init__.c -msgid "Only int or string supported for ip" -msgstr "ip에는 정수 또는 문자열만 지원됩니다" +#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio" +msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, fuzzy, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +#, fuzzy +msgid "%q must be <= %u" +msgstr "%q 는 <= %u 여야 합니다" + +#: ports/espressif/common-hal/wifi/Monitor.c +msgid "monitor init failed" msgstr "" -"흑백, 인덱싱된 4bpp 또는 8bpp, 그리고 16bpp 또는 그 이상의 BMP만 지원됩니다: " -"%d bpp가 지정되었습니다" -#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one %q can be set in deep sleep." -msgstr "딥 슬립에서는 하나의 %q만 설정할 수 있습니다." +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Interface must be started" +msgstr "인터페이스를 시작해야 합니다" -#: ports/espressif/common-hal/espulp/ULPAlarm.c -msgid "Only one %q can be set." -msgstr "하나의 %q만 설정할 수 있습니다." +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Invalid multicast MAC address" +msgstr "잘못된 멀티캐스트 MAC 주소" -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c #, fuzzy -msgid "Only one address is allowed" -msgstr "오직 하나의 주소만 허용됩니다" +msgid "Already scanning for wifi networks" +msgstr "이미 wifi 네트워크를 찾고 있습니다" -#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c -#: ports/nordic/common-hal/alarm/time/TimeAlarm.c -#: ports/stm/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" -#: ports/espressif/common-hal/alarm/time/TimeAlarm.c -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set." -msgstr "" +#: ports/espressif/common-hal/wifi/ScannedNetworks.c +msgid "Failed to allocate wifi scan memory" +msgstr "wifi 검색 메모리 할당에 실패했습니다" -#: shared-module/displayio/ColorConverter.c -#, fuzzy -msgid "Only one color can be transparent at a time" -msgstr "한 번에 한 가지 색상만 투명할 수 있습니다" +#: ports/espressif/common-hal/wifi/__init__.c +msgid "Failed to allocate Wifi memory" +msgstr "Wifi 메모리 할당에 실패했습니다" -#: py/moderrno.c -#, fuzzy -msgid "Operation not permitted" -msgstr "작업이 허용되지 않습니다" +#: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +msgid "Only IPv4 addresses supported" +msgstr "IPv4 주소만 지원됩니다" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation or feature not supported" -msgstr "작업 또는 기능이 지원되지 않습니다" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/busio/SPI.c +msgid "Must provide MISO or MOSI pin" +msgstr "MISO 또는 MOSI 핀을 제공해야 합니다" -#: ports/espressif/common-hal/espidf/__init__.c -#, fuzzy -msgid "Operation timed out" -msgstr "작업 시간 초과되었습니다" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c +#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c +#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c +msgid "Hardware in use, try alternative pins" +msgstr "하드웨어가 사용 중입니다, 대체 핀을 사용해보십시오" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Out of MDNS service slots" -msgstr "MDNS 서비스 슬롯 부족" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -#, fuzzy -msgid "Out of memory" -msgstr "메모리 부족" +#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c +msgid "" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +msgstr "" +"주파수는 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 또는 1008 Mhz 여야 " +"합니다" -#: ports/espressif/common-hal/socketpool/Socket.c -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Out of sockets" -msgstr "소켓 부족" +#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Out-buffer elements must be <= 4 bytes long" -msgstr "출력 버퍼 요소의 길이는 <= 4 바이트 여야 합니다" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "timeout must be < 655.35 secs" +msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -#, fuzzy -msgid "PWM restart" -msgstr "PWM 재시작" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "non-zero timeout must be > 0.01" +msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -#, fuzzy -msgid "PWM slice already in use" -msgstr "PWM slice가 이미 사용 중입니다" +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: timeout" +msgstr "연결에 실패했습니다: 시간 초과" -#: ports/raspberrypi/common-hal/countio/Counter.c -#, fuzzy -msgid "PWM slice channel A already in use" -msgstr "PWM slice channel A가 이미 사용 중입니다" +#: ports/nordic/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "" -#: shared-module/jpegio/JpegDecoder.c -#, fuzzy -msgid "Parameter error" -msgstr "파라미터 오류" +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Nordic system firmware out of memory" +msgstr "Nordic 시스템 펌웨어에 메모리가 부족합니다" -#: ports/espressif/common-hal/audiobusio/__init__.c -#, fuzzy -msgid "Peripheral in use" -msgstr "주변 기기가 사용 중입니다" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %04x" +msgstr "" -#: py/moderrno.c -msgid "Permission denied" -msgstr "권한이 거부 되었습니다" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown gatt error: 0x%04x" +msgstr "" + +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +msgid "" +"Unspecified issue. The pairing request on the other device may have been " +"declined or ignored." +msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Pin cannot wake from Deep Sleep" -msgstr "핀은 딥 슬립에서 깨어날 수 없습니다" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#, c-format +msgid "Unknown security error: 0x%04x" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/nordic/common-hal/alarm/pin/PinAlarm.c #, fuzzy -msgid "Pin count too large" -msgstr "핀 수 너무 큼" +msgid "Cannot wake on pin edge, only level" +msgstr "핀의 에지에서 깨울 수 없고, 레벨에서만 깨울 수 있습니다" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -#: ports/stm/common-hal/pulseio/PulseIn.c -msgid "Pin interrupt already in use" -msgstr "핀 인터럽트는 이미 사용 중입니다" +#: ports/nordic/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +msgstr "사용 중인 장치" -#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -msgid "Pin is input only" -msgstr "핀은 입력 전용입니다" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "Pin must be on PWM Channel B" -msgstr "핀은 PWM 채널 B에 있어야 합니다" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c +#: ports/nordic/common-hal/busio/UART.c #, c-format -msgid "" -"Pinout uses %d bytes per element, which consumes more than the ideal %d " -"bytes. If this cannot be avoided, pass allow_inefficient=True to the " -"constructor" +msgid "error = 0x%08lX" msgstr "" -#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c -msgid "Pins must be sequential" -msgstr "핀은 순차적이어야 합니다" +#: ports/nordic/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "홀수 패리티는 지원되지 않습니다" -#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c -msgid "Pins must be sequential GPIO pins" -msgstr "핀은 순차적인 GPIO 핀이어야 합니다" +#: ports/nordic/common-hal/countio/Counter.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +msgid "All channels in use" +msgstr "모든 채널이 사용중입니다" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Pins must share PWM slice" +#: ports/nordic/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "온도 데이터를 수신 할 수 없습니다" + +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" -#: shared-module/usb/core/Device.c -msgid "Pipe error" -msgstr "파이프 오류" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "timeout duration exceeded the maximum supported value" +msgstr "" -#: py/builtinhelp.c -msgid "Plus any modules on the filesystem\n" -msgstr "게다가 파일 시스템의 모든 모듈\n" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "%q cannot be changed once mode is set to %q" +msgstr "" -#: shared-module/vectorio/Polygon.c -msgid "Polygon needs at least 3 points" -msgstr "다각형은 최소 3개의 점이 필요합니다" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "뮤텍스 획득에 실패했습니다, 오류 0x%04x" -#: supervisor/shared/safe_mode.c -msgid "Power dipped. Make sure you are providing enough power." -msgstr "전력이 내려갔습니다. 충분한 전력을 제공할 수 있는지 확인하십시오." +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "뮤텍스 해제에 실패했습니다, 오류 0x%04x" -#: shared-bindings/_bleio/Adapter.c -#, fuzzy -msgid "Prefix buffer must be on the heap" -msgstr "앞의 버퍼는 힙에 있어야 합니다" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "오디오 변환이 구현되지 않음" -#: main.c -msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" -msgstr "아무 키나 눌러 REPL을 입력한다. 다시 로드할땐 CTRL-D를 사용한다.\n" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c +#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c +#: shared-module/synthio/Synthesizer.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q는 %q가 아닌 %q 또는 %q 유형이어야 합니다" -#: main.c -msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" -msgstr "알람, CTRL-C 또는 파일을 작성하기 전까지 딥 슬립을 하는 척합니다\n" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Program size invalid" +msgstr "프로그램 크기가 잘못되었습니다" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does IN without loading ISR" -msgstr "프로그램이 ISR을 로드하지 않고 IN을 실행했습니다" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Init program size invalid" +msgstr "초기화 프로그램의 크기가 잘못되었습니다" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Buffer elements must be 4 bytes long or less" +msgstr "버퍼 요소는 4바이트 이하여야 합니다" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does OUT without loading OSR" -msgstr "프로그램이 OSR을 로드하지 않고 OUT을 실행했습니다" +msgid "Mismatched data size" +msgstr "일치하지 않는 데이터 크기" #: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Program size invalid" -msgstr "프로그램 크기가 잘못되었습니다" +msgid "Out-buffer elements must be <= 4 bytes long" +msgstr "출력 버퍼 요소의 길이는 <= 4 바이트 여야 합니다" -#: ports/espressif/common-hal/espulp/ULP.c -msgid "Program too long" -msgstr "프로그램이 너무 깁니다" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "In-buffer elements must be <= 4 bytes long" +msgstr "버퍼 내 요소 길이는 <= 4여야 합니다" -#: shared-bindings/digitalio/DigitalInOut.c -#, fuzzy -msgid "Pull not used when direction is output." -msgstr "방향이 출력 될 때 풀은 사용되지 않습니다" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/I2C.c +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/I2C.c +#: shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "이 함수에는 잠금이 필요합니다" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "RISE_AND_FALL not available on this chip" -msgstr "이 칩에서는 RISE_AND_FALL을 사용할 수 없습니다" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "RLE-compressed BMP not supported" +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c +#: ports/stm/common-hal/alarm/touch/TouchAlarm.c +msgid "Touch alarms not available" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG DeInit Error" -msgstr "RNG DeInit 오류" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG Init Error" -msgstr "RNG 초기화 오류" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "Bit clock and word select must be sequential GPIO pins" +msgstr "비트 클럭 및 워드 선택은 순차적 GPIO 핀이어야 합니다" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" -msgstr "RS485" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Too many channels in sample." +msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "RS485 inversion specified when not in RS485 mode" -msgstr "RS485 모드가 아닐 때 RS485 반전이 지정됩니다" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Audio source error" +msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c -msgid "RTC is not supported on this board" -msgstr "이 보드에서는 PTC가 지원되지 않습니다" +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 16, 24, or 32" +msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "Random number generation error" -msgstr "난수 생성 오류" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "" -#: shared-bindings/_bleio/__init__.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c -#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c -msgid "Read-only" -msgstr "읽기 전용" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "DMA 간격 타이머를 찾을 수 없습니다" -#: extmod/vfs_fat.c py/moderrno.c -msgid "Read-only filesystem" -msgstr "읽기 전용 파일 시스템" +#: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "I2C peripheral in use" +msgstr "I2C 주변 기기가 사용 중입니다" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Received response was invalid" -msgstr "수신된 응답이 잘못되었습니다" +#: ports/raspberrypi/common-hal/busio/SPI.c +msgid "SPI peripheral in use" +msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Reconnecting" -msgstr "다시 연결하는 중입니다" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "" -#: shared-bindings/epaperdisplay/EPaperDisplay.c -msgid "Refresh too soon" -msgstr "너무 빨리 새로고침하였습니다" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "Pin must be on PWM Channel B" +msgstr "핀은 PWM 채널 B에 있어야 합니다" -#: shared-bindings/canio/RemoteTransmissionRequest.c -msgid "RemoteTransmissionRequests limited to 8 bytes" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "RISE_AND_FALL not available on this chip" +msgstr "이 칩에서는 RISE_AND_FALL을 사용할 수 없습니다" + +#: ports/raspberrypi/common-hal/countio/Counter.c +#, fuzzy +msgid "PWM slice already in use" +msgstr "PWM slice가 이미 사용 중입니다" + +#: ports/raspberrypi/common-hal/countio/Counter.c +#, fuzzy +msgid "PWM slice channel A already in use" +msgstr "PWM slice channel A가 이미 사용 중입니다" + +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +#, fuzzy +msgid "All state machines in use" +msgstr "모든 상태 머신이 사용 중입니다" + +#: ports/raspberrypi/common-hal/floppyio/__init__.c +msgid "timeout waiting for flux" +msgstr "" + +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: shared-module/floppyio/__init__.c +msgid "timeout waiting for index pulse" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Requested AES mode is unsupported" -msgstr "" +#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +msgid "Pins must be sequential" +msgstr "핀은 순차적이어야 합니다" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Requested resource not found" +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +msgid "Invalid %q and %q" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "Right channel unsupported" -msgstr "" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Failed to add service TXT record" +msgstr "서비스 TXT 레코드를 추가하는 것에 실패했습니다" -#: shared-module/jpegio/JpegDecoder.c -msgid "Right format but not supported" -msgstr "" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "MDNS 서비스 슬롯 부족" -#: main.c -msgid "Running in safe mode! Not running saved code.\n" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to access unaligned IO register" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "SD card CSD format not supported" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to write to read-only memory" msgstr "" -#: ports/cxd56/common-hal/sdioio/SDCard.c -msgid "SDCard init" -msgstr "" +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +msgid "All timers for this pin are in use" +msgstr "핀의 모든 타이머가 사용 중입니다" -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO GetCardInfo Error %d" -msgstr "" +#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c +msgid "Pins must be sequential GPIO pins" +msgstr "핀은 순차적인 GPIO 핀이어야 합니다" -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO Init Error %x" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "Pin count too large" +msgstr "핀 수 너무 큼" -#: ports/espressif/common-hal/busio/SPI.c -msgid "SPI configuration failed" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "Missing jmp_pin. %q[%u] jumps on pin" +msgstr "jmp_pin이 누락되었습니다. %q[%u] 핀으로 점프합니다" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI init error" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] uses extra pin" +msgstr "%q[%u]에서 추가 핀 사용" -#: ports/raspberrypi/common-hal/busio/SPI.c -msgid "SPI peripheral in use" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] waits based on pin" +msgstr "first_in_pin이 누락되었습니다. %q[%u]는 핀에 따라 대기 중입니다" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI re-init" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] waits on input outside of count" +msgstr "%q[%u]이(가) 카운트 외부의 입력을 대기합니다" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "Scale dimensions must divide by 3" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +msgstr "first_in_pin이 누락되었습니다. %q[%u]는 pin(s)에서 이동합니다" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Scan already in progress. Stop with stop_scan." -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "%q[%u] shifts in more bits than pin count" +msgstr "%q[%u]가 핀 수보다 더 많은 비트로 이동했습니다" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -msgid "Serializer in use" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +msgstr "first_out_pin이 누락되었습니다. %q[%u]는 pin(s)으로 이동합니다" -#: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "%q[%u] shifts out more bits than pin count" +msgstr "%q[%u]이(가) 핀 수보다 많은 비트를 전송합니다" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Size not supported" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "Missing first_set_pin. %q[%u] sets pin(s)" +msgstr "first_set_pin이 누락되었습니다. %q[%u]는 pin(s)을 설정합니다" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Slice and value different lengths." -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] writes pin(s)" +msgstr "first_out_pin이 누락되었습니다. %q[%u]는 pin(s)에 씁니다" -#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/TileGrid.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Slices not supported" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "Missing first_in_pin. %q[%u] reads pin(s)" +msgstr "first_in_pin이 누락되어 있습니다. %q[%u]이 pin(s)을 읽습니다" -#: ports/espressif/common-hal/socketpool/SocketPool.c -#: ports/raspberrypi/common-hal/socketpool/SocketPool.c -msgid "SocketPool can only be used with wifi.radio" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does IN without loading ISR" +msgstr "프로그램이 ISR을 로드하지 않고 IN을 실행했습니다" -#: shared-bindings/aesio/aes.c -msgid "Source and destination buffers must be the same length" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does OUT without loading OSR" +msgstr "프로그램이 OSR을 로드하지 않고 OUT을 실행했습니다" -#: shared-bindings/paralleldisplaybus/ParallelBus.c -msgid "Specify exactly one of data0 or data_pins" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin state conflicts with initial out pin state" +msgstr "초기 설정한 핀의 상태가 초기 바깥쪽 핀의 상태와 충돌합니다" -#: supervisor/shared/safe_mode.c -msgid "Stack overflow. Increase stack size." -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin direction conflicts with initial out pin direction" +msgstr "초기 설정한 핀의 방향이 초기 바깥쪽 핀의 방향과 충돌합니다" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Supply one of monotonic_time or epoch_time" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "pull masks conflict with direction masks" msgstr "" -#: shared-bindings/gnss/GNSS.c -msgid "System entry must be gnss.SatelliteSystem" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No out in program" +msgstr "프로그램에 출력이 없습니다" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Temperature read timed out" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "No in in program" +msgstr "프로그램에 입력이 없습니다" -#: supervisor/shared/safe_mode.c -msgid "The `microcontroller` module was used to boot into safe mode." -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#, fuzzy +msgid "No in or out in program" +msgstr "프로그램에 입력 또는 출력이 없습니다" -#: py/obj.c -msgid "The above exception was the direct cause of the following exception:" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched swap flag" +msgstr "일치하지 않는 스왑 플래그" -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d, not %d" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +msgid "Data pins must be consecutive" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "" +#: ports/raspberrypi/common-hal/socketpool/Socket.c +msgid "Only IPv4 sockets supported" +msgstr "IPv4 소켓만 지원됩니다" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "" +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All dma channels in use" +msgstr "모든 dma채널이 사용 중입니다" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Third-party firmware fatal error." -msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q는 이 보드에 대한 읽기 전용입니다" -#: shared-module/imagecapture/ParallelImageCapture.c -msgid "This microcontroller does not support continuous capture." -msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "AP could not be started" +msgstr "AP를 시작할 수 없습니다" -#: shared-module/paralleldisplaybus/ParallelBus.c -msgid "" -"This microcontroller only supports data0=, not data_pins=, because it " -"requires contiguous pins." -msgstr "" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Only edge detection is available on this hardware" +msgstr "이 하드웨어에서는 에지 감지만 가능합니다" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile height must exactly divide bitmap height" -msgstr "" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +#: ports/stm/common-hal/pulseio/PulseIn.c +msgid "Pin interrupt already in use" +msgstr "핀 인터럽트는 이미 사용 중입니다" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c -msgid "Tile index out of bounds" -msgstr "" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Pin cannot wake from Deep Sleep" +msgstr "핀은 딥 슬립에서 깨어날 수 없습니다" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile width must exactly divide bitmap width" -msgstr "" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +#, fuzzy +msgid "Deep sleep pins must use a rising edge with pulldown" +msgstr "딥 슬립 핀은 풀다운이 있는 상승 에지를 사용해야 합니다" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Time is in the past." -msgstr "" +#: ports/stm/common-hal/analogio/AnalogIn.c +msgid "Invalid ADC Unit value" +msgstr "잘못된 ADC 단위 값" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -#, c-format -msgid "Timeout is too long: Maximum timeout length is %d seconds" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Device Init Error" +msgstr "DAC 장치 초기화 오류" + +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Channel Init Error" +msgstr "DAC 채널 초기화 오류" + +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample." -msgstr "" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +#, fuzzy +msgid "Another PWMAudioOut is already active" +msgstr "다른 PWMaudioOut이 이미 활성화되어 있습니다" -#: ports/espressif/common-hal/_bleio/Characteristic.c -msgid "Too many descriptors" -msgstr "" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "버퍼 길이 %d가 너무 큽니다. 그것은 %d보다 작아야 합니다" -#: shared-module/displayio/__init__.c -msgid "Too many display busses; forgot displayio.release_displays() ?" -msgstr "" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Failed to buffer the sample" +msgstr "샘플 버퍼링에 실패했습니다" -#: shared-module/displayio/__init__.c -msgid "Too many displays" -msgstr "" +#: ports/stm/common-hal/busio/I2C.c +msgid "I2C init error" +msgstr "I2C 초기화 오류" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than %q" +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI init error" msgstr "" -#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c -#: ports/stm/common-hal/alarm/touch/TouchAlarm.c -msgid "Touch alarms not available" +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI re-init" msgstr "" -#: py/obj.c -msgid "Traceback (most recent call last):\n" -msgstr "" +#: ports/stm/common-hal/busio/UART.c +msgid "Internal define error" +msgstr "내부 정의 오류" #: ports/stm/common-hal/busio/UART.c -msgid "UART de-init" -msgstr "" +msgid "Could not start interrupt, RX busy" +msgstr "인터럽트를 시작할 수 없습니다, RX가 사용 중입니다" -#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c #: ports/stm/common-hal/busio/UART.c -msgid "UART init" +msgid "UART write" msgstr "" -#: ports/raspberrypi/common-hal/busio/UART.c -msgid "UART peripheral in use" +#: ports/stm/common-hal/busio/UART.c +msgid "UART de-init" msgstr "" #: ports/stm/common-hal/busio/UART.c msgid "UART re-init" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART write" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Temperature read timed out" msgstr "" -#: main.c -msgid "UID:" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Voltage read timed out" msgstr "" -#: shared-module/usb_hid/Device.c -msgid "USB busy" -msgstr "" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG Init Error" +msgstr "RNG 초기화 오류" -#: supervisor/shared/safe_mode.c -msgid "USB devices need more endpoints than are available." -msgstr "" +#: ports/stm/common-hal/os/__init__.c +msgid "Random number generation error" +msgstr "난수 생성 오류" -#: supervisor/shared/safe_mode.c -msgid "USB devices specify too many interface names." -msgstr "" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG DeInit Error" +msgstr "RNG DeInit 오류" -#: shared-module/usb_hid/Device.c -msgid "USB error" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "timer re-init" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID integer value must be 0-0xffff" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "channel re-init" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" -msgstr "UUID문자열이 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'형식이 아닙니다" - -#: shared-bindings/_bleio/UUID.c -msgid "UUID value is not str, int or byte buffer" -msgstr "" -"UUID값이 문자열(str), 정수(int) 또는 바이트버퍼가(byte buffer) 아닙니다" +#: ports/stm/common-hal/pwmio/PWMOut.c +#, fuzzy +msgid "PWM restart" +msgstr "PWM 재시작" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to access unaligned IO register" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Unable to allocate buffers for signed conversion" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "SDIO GetCardInfo Error %d" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Unable to allocate to the heap." -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#, fuzzy +msgid ".show(x) removed. Use .root_group = x" +msgstr ".show(x)가 제거되었습니다. .root_group = x를 사용합니다" -#: ports/espressif/common-hal/busio/I2C.c -msgid "Unable to create lock" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Brightness not adjustable" +msgstr "밝기를 조절할 수 없습니다" -#: shared-module/i2cdisplaybus/I2CDisplayBus.c -#: shared-module/is31fl3741/IS31FL3741.c -#, c-format -msgid "Unable to find I2C Display at %x" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c py/argcheck.c +#: shared-bindings/busdisplay/BusDisplay.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "%q must be %d-%d" +msgstr "%q는 %d-%d이어야 합니다" -#: py/parse.c -msgid "Unable to init parser" -msgstr "파서를 초기화(init) 할 수 없습니다" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Group already used" +msgstr "이미 사용된 그룹" -#: shared-module/displayio/OnDiskBitmap.c -msgid "Unable to read color palette data" +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Invalid advertising data" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Unable to start mDNS query" +#: ports/zephyr-cp/common-hal/audiobusio/I2SOut.c +#: ports/zephyr-cp/common-hal/busio/I2C.c +#: ports/zephyr-cp/common-hal/busio/SPI.c +#: ports/zephyr-cp/common-hal/busio/UART.c +msgid "Use device tree to define %q devices" msgstr "" -#: shared-bindings/nvm/ByteArray.c -msgid "Unable to write to nvm." +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to write to read-only memory" +#: ports/zephyr-cp/common-hal/usb_hid/Device.c shared-module/usb_hid/Device.c +msgid "USB error" msgstr "" -#: shared-bindings/alarm/SleepMemory.c -msgid "Unable to write to sleep_memory." +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" msgstr "" -#: ports/nordic/common-hal/_bleio/UUID.c -msgid "Unexpected nrfx uuid type" -msgstr "" +#: ports/zephyr-cp/common-hal/zephyr_display/Display.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Below minimum frame rate" +msgstr "최소 프레임 속도 미만" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error at %s:%d: %d" +#: py/argcheck.c +msgid "function doesn't take keyword arguments" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c +#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c +#: shared-bindings/time/__init__.c #, c-format -msgid "Unknown BLE error: %d" +msgid "function takes %d positional arguments but %d were given" msgstr "" -#: ports/espressif/common-hal/max3421e/Max3421E.c -#: ports/raspberrypi/common-hal/wifi/__init__.c +#: py/argcheck.c #, c-format -msgid "Unknown error code %d" +msgid "function missing %d required positional arguments" msgstr "" -#: shared-bindings/wifi/Radio.c +#: py/argcheck.c #, c-format -msgid "Unknown failure %d" +msgid "function expected at most %d arguments, got %d" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown gatt error: 0x%04x" -msgstr "" +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' 인수가 필요합니다" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: supervisor/shared/safe_mode.c -msgid "Unknown reason." +#: py/argcheck.c +msgid "extra positional arguments given" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown security error: 0x%04x" +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c +msgid "unexpected keyword argument '%q'" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error at %s:%d: %d" +#: py/argcheck.c +msgid "extra keyword arguments given" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %04x" +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c +msgid "argument num/types mismatch" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %d" +#: py/argcheck.c +msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -#: shared-module/_pixelmap/PixelMap.c -#, c-format -msgid "Unmatched number of items on RHS (expected %d, got %d)." -msgstr "" +#: py/argcheck.c +msgid "%q must be %d" +msgstr "%q는 %d이어야 합니다" + +#: py/argcheck.c +#, fuzzy +msgid "%q must be >= %d" +msgstr "%q 는 >= %d 여야 합니다" + +#: py/argcheck.c shared-bindings/gifio/GifWriter.c +#: shared-module/gifio/OnDiskGif.c +#, fuzzy +msgid "%q must be <= %d" +msgstr "%q 는 <= %d 여야 합니다" + +#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c +#: shared-module/synthio/__init__.c +msgid "%q must be of type %q, not %q" +msgstr "%q는 %q가 아니라 %q 유형이어야 합니다" + +#: py/argcheck.c +msgid "%q length must be %d-%d" +msgstr "%q 길이는 %d - %d이어야 합니다" + +#: py/argcheck.c +msgid "%q length must be >= %d" +msgstr "%q 길이는 >= %d이어야 합니다" + +#: py/argcheck.c +msgid "%q length must be <= %d" +msgstr "%q 길이는 <= %d>여야 합니다" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" +msgstr "%q 길이는 %d이어야 합니다" + +#: py/argcheck.c shared-module/audiofilters/Filter.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q의 %q는 %q가 아니라 %q 유형이어야 합니다" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "" -"Unspecified issue. Can be that the pairing prompt on the other device was " -"declined or ignored." +#: py/asmthumb.c +msgid "too many locals for native method" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Unsupported colorspace" +#: py/asmxtensa.c +msgid "ERROR: xtensa %q out of range" msgstr "" -#: shared-module/displayio/bus_core.c -msgid "Unsupported display bus type" +#: py/asmxtensa.c +msgid "ERROR: %q %q not word-aligned" msgstr "" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "" +#: py/bc.c py/objnamedtuple.c +#, fuzzy +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q()는 %d 위치 인수를 사용하지만 %d이(가) 주어졌습니다" -#: shared-bindings/hashlib/__init__.c -msgid "Unsupported hash algorithm" +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -msgid "Unsupported socket type" +#: py/bc.c +msgid "unexpected keyword argument" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Update failed" +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length != required fixed length" +#: py/bc.c +msgid "function missing required keyword argument '%q'" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length > max_length" +#: py/bc.c +msgid "function missing keyword-only argument" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Version was invalid" +#: py/binary.c py/objarray.c +msgid "bad typecode" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Voltage read timed out" +#: py/builtinevex.c +msgid "bad compile mode" msgstr "" -#: main.c -msgid "WARNING: Your code filename has two extensions\n" -msgstr "" +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "게다가 파일 시스템의 모든 모듈\n" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" +#: py/builtinhelp.c +msgid "object " msgstr "" +#: py/builtinhelp.c +msgid " is of type %q\n" +msgstr " %q 유형입니다\n" + #: py/builtinhelp.c #, c-format msgid "" @@ -2364,379 +2470,329 @@ msgid "" "To list built-in modules type `help(\"modules\")`.\n" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "Wi-Fi: " -msgstr "" - -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "" - -#: main.c -msgid "Woken up by alarm.\n" -msgstr "" - -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Writes not supported on Characteristic" -msgstr "" - -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "You pressed both buttons at start up." -msgstr "" - -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h -msgid "You pressed button A at start up." -msgstr "" - -#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h -msgid "You pressed button DOWN at start up." -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up" -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h -#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h -msgid "You pressed the BOOT button at start up." -msgstr "" - -#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h -msgid "You pressed the GPIO0 button at start up." -msgstr "" - -#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h -msgid "You pressed the Rec button at start up." -msgstr "" - -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "You pressed the SW38 button at start up." -msgstr "" - -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -#: ports/espressif/boards/vidi_x/mpconfigboard.h -msgid "You pressed the VOLUME button at start up." +#: py/builtinimport.c +msgid "script compilation not supported" msgstr "" -#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h -msgid "You pressed the central button at start up." +#: py/builtinimport.c +msgid "can't perform relative import" msgstr "" -#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h -msgid "You pressed the left button at start up." +#: py/builtinimport.c +msgid "module not found" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the reset button during boot." +#: py/builtinimport.c +msgid "no module named '%q'" msgstr "" -#: supervisor/shared/micropython.c -msgid "[truncated due to length]" +#: py/builtinimport.c +msgid "relative import" msgstr "" -#: py/objtype.c -msgid "__init__() should return None" +#: py/compile.c +msgid "can't assign to expression" msgstr "" -#: py/objtype.c -#, c-format -msgid "__init__() should return None, not '%s'" +#: py/compile.c +msgid "multiple *x in assignment" msgstr "" -#: py/objobject.c -msgid "__new__ arg must be a user-type" +#: py/compile.c +msgid "non-default argument follows default argument" msgstr "" -#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c -msgid "a bytes-like object is required" +#: py/compile.c +msgid "invalid micropython decorator" msgstr "" -#: shared-bindings/i2ctarget/I2CTarget.c -msgid "addresses is empty" +#: py/compile.c +msgid "invalid arch" msgstr "" #: py/compile.c -msgid "annotation must be an identifier" +msgid "can't delete expression" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "arange: cannot compute length" -msgstr "" +#: py/compile.c +msgid "'break'/'continue' outside loop" +msgstr "'break'/'continue' 외부 루프" -#: py/modbuiltins.c -msgid "arg is an empty sequence" -msgstr "" +#: py/compile.c +msgid "'return' outside function" +msgstr "'return' 는 함수 외부에 존재합니다" -#: py/objobject.c -msgid "arg must be user-type" +#: py/compile.c +msgid "import * not at module level" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort argument must be an ndarray" +#: py/compile.c +msgid "identifier redefined as global" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort is not implemented for flattened arrays" +#: py/compile.c +msgid "no binding for nonlocal found" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "argument must be None, an integer or a tuple of integers" +#: py/compile.c +msgid "identifier redefined as nonlocal" msgstr "" #: py/compile.c -msgid "argument name reused" +msgid "can't declare nonlocal in outer code" msgstr "" -#: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c -msgid "argument num/types mismatch" +#: py/compile.c +msgid "default 'except' must be last" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c -msgid "arguments must be ndarrays" +#: py/compile.c +msgid "async for/with outside async function" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array and index length must be equal" -msgstr "" +#: py/compile.c +#, fuzzy +msgid "*x must be assignment target" +msgstr "*x는 할당 대상이어야 합니다" -#: extmod/ulab/code/numpy/io/io.c -msgid "array has too many dimensions" +#: py/compile.c +msgid "super() can't find self" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array is too big" -msgstr "" +#: py/compile.c +#, fuzzy +msgid "* arg after **" +msgstr "* 인수 뒤에 **" -#: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c -msgid "array/bytes required on right side" +#: py/compile.c +msgid "too many args" msgstr "" -#: py/asmxtensa.c -msgid "asm overflow" -msgstr "" +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "키워드 인수의 LHS 는 id 여야 합니다" #: py/compile.c -msgid "async for/with outside async function" +msgid "positional arg after **" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get (arg)min/(arg)max of empty sequence" +#: py/compile.c +msgid "positional arg after keyword arg" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get argmin/argmax of an empty sequence" -msgstr "" +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "구문(syntax)가 유효하지 않습니다" -#: py/objstr.c -msgid "attributes not supported" +#: py/compile.c +msgid "expecting key:value for dict" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "axis is out of bounds" +#: py/compile.c +msgid "expecting just a value for set" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -msgid "axis must be None, or an integer" -msgstr "" +#: py/compile.c +msgid "'yield' outside function" +msgstr "'yield' 는 함수 외부에 존재합니다" -#: extmod/ulab/code/numpy/numerical.c -msgid "axis too long" -msgstr "" +#: py/compile.c +#, fuzzy +msgid "'yield from' inside async function" +msgstr "비동기 함수 내 'yield from'" -#: shared-bindings/bitmaptools/__init__.c -msgid "background value out of range of target" -msgstr "" +#: py/compile.c +msgid "'await' outside function" +msgstr "'await' 는 펑크션 외부에 있습니다" -#: py/builtinevex.c -msgid "bad compile mode" +#: py/compile.c +msgid "unknown type '%q'" msgstr "" -#: py/objstr.c -msgid "bad conversion specifier" +#: py/compile.c +msgid "annotation must be an identifier" msgstr "" -#: py/objstr.c -msgid "bad format string" +#: py/compile.c +msgid "argument name reused" msgstr "" -#: py/binary.c py/objarray.c -msgid "bad typecode" +#: py/compile.c +msgid "inline assembler must be a function" msgstr "" -#: py/emitnative.c -msgid "binary op %q not implemented" +#: py/compile.c +msgid "unknown type" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "bitmap size and depth must match" +#: py/compile.c +msgid "return annotation must be an identifier" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "bitmap sizes must match" +#: py/compile.c +msgid "expecting an assembler instruction" msgstr "" -#: extmod/modrandom.c -msgid "bits must be 32 or less" +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' 에는 1 개의 독립변수가 필요합니다" + +#: py/compile.c +msgid "label redefined" msgstr "" -#: shared-bindings/audiomixer/Mixer.c -msgid "bits_per_sample must be 8 or 16" -msgstr "bits_per_sample은 8 또는 16이어야합니다." +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' 에는 1 개의 독립변수가 필요합니다" -#: py/emitinlinethumb.c -msgid "branch not in range" -msgstr "" +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' 에는 >=2 개의 독립변수가 필요합니다" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer is smaller than requested size" -msgstr "" +#: py/compile.c +#, fuzzy +msgid "'data' requires integer arguments" +msgstr "'data' 에는 정수 인수가 필요합니다" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer size must be a multiple of element size" +#: py/compile.c +msgid "cannot emit native code for this architecture" msgstr "" -#: shared-module/struct/__init__.c -msgid "buffer size must match format" +#: py/emitbc.c +msgid "bytecode overflow" msgstr "" -#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c -msgid "buffer slices must be of equal length" +#: py/emitinlinerv32.c +msgid "can only have up to 4 parameters for RV32 assembly" msgstr "" -#: py/modstruct.c shared-module/struct/__init__.c -msgid "buffer too small" +#: py/emitinlinerv32.c +msgid "parameters must be registers in sequence a0 to a3" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "buffer too small for requested bytes" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: expecting %q" msgstr "" -#: py/emitbc.c -msgid "bytecode overflow" +#: py/emitinlinerv32.c +msgid "opcode '%q': expecting %d arguments" msgstr "" -#: py/objarray.c -msgid "bytes length not a multiple of item size" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: out of range" msgstr "" -#: py/objstr.c -msgid "bytes value out of range" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: unknown register" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is out of range" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: undefined label '%q'" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is read only" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: must not be zero" msgstr "" -#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c -#: shared-module/vectorio/Rectangle.c -msgid "can only have one parent" +#: py/emitinlinerv32.c +msgid "invalid RV32 instruction '%q'" msgstr "" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "can only specify one unknown dimension" -msgstr "" +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s'는 최대 r%d를 필요로 합니다" -#: py/objtype.c -msgid "can't add special method to already-subclassed class" -msgstr "" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' 에는 레지스터가 필요합니다" -#: py/compile.c -msgid "can't assign to expression" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' 에는 특별한 레지스터가 필요합니다" -#: extmod/modasyncio.c -msgid "can't cancel self" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' 에는 FPU레지스터가 필요합니다" -#: shared-module/adafruit_pixelbuf/PixelBuf.c -msgid "can't convert %q to %q" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' {r0, r1, ...}은 을 기대합니다" -#: py/obj.c +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' 는 정수 여야합니다" + +#: py/emitinlinethumb.c #, fuzzy, c-format -msgid "can't convert %s to complex" -msgstr "%s 를 복합어로 변환할 수 없습니다" +msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" +msgstr "'%s' 정수 0x%x 이 마스크 0x%x에 맞지 않습니다" -#: py/obj.c -#, c-format -msgid "can't convert %s to float" -msgstr "" +#: py/emitinlinethumb.c +#, fuzzy, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' 에는 [a, b] 형식의 주소가 필요합니다" -#: py/objint.c py/runtime.c +#: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format -msgid "can't convert %s to int" -msgstr "" - -#: py/objstr.c -msgid "can't convert '%q' object to %q implicitly" -msgstr "" +msgid "'%s' expects a label" +msgstr "'%s' 에는 라벨이 필요합니다" -#: extmod/ulab/code/numpy/vector.c -msgid "can't convert complex to float" +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" msgstr "" -#: py/obj.c -msgid "can't convert to complex" +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" -#: py/obj.c -msgid "can't convert to float" +#: py/emitinlinethumb.c +msgid "branch not in range" msgstr "" -#: py/runtime.c -msgid "can't convert to int" +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/objstr.c -msgid "can't convert to str implicitly" +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" msgstr "" -#: py/compile.c -msgid "can't declare nonlocal in outer code" -msgstr "" +#: py/emitinlinextensa.c +#, fuzzy, c-format +msgid "'%s' integer %d isn't within range %d..%d" +msgstr "'%s' 정수 %d가 %d..%d 범위 내에 있지 않습니다" -#: py/compile.c -msgid "can't delete expression" +#: py/emitinlinextensa.c +#, c-format +msgid "%d is not a multiple of %d" msgstr "" -#: py/emitnative.c -msgid "can't do binary op between '%q' and '%q'" +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" msgstr "" #: py/emitnative.c -msgid "can't do unary op of '%q'" +msgid "conversion to object" msgstr "" #: py/emitnative.c -msgid "can't implicitly convert '%q' to 'bool'" -msgstr "" - -#: py/runtime.c -msgid "can't import name %q" +msgid "local '%q' used before type known" msgstr "" #: py/emitnative.c @@ -2747,24 +2803,8 @@ msgstr "" msgid "can't load with '%q' index" msgstr "" -#: py/builtinimport.c -msgid "can't perform relative import" -msgstr "" - -#: py/objgenerator.c -msgid "can't send non-None value to a just-started generator" -msgstr "" - -#: shared-module/sdcardio/SDCard.c -msgid "can't set 512 block size" -msgstr "" - -#: py/objexcept.c py/objnamedtuple.c -msgid "can't set attribute" -msgstr "" - -#: py/runtime.c -msgid "can't set attribute '%q'" +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" msgstr "" #: py/emitnative.c @@ -2779,66 +2819,52 @@ msgstr "" msgid "can't store with '%q' index" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from automatic field numbering to manual field specification" -msgstr "" - -#: py/objstr.c -msgid "" -"can't switch from manual field specification to automatic field numbering" -msgstr "" - -#: py/objcomplex.c -msgid "can't truncate-divide a complex number" -msgstr "" - -#: extmod/modasyncio.c -msgid "can't wait" +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot assign new shape" +#: py/emitnative.c +msgid "'not' not implemented" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "cannot cast output with casting rule" +#: py/emitnative.c +msgid "can't do unary op of '%q'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex to dtype" +#: py/emitnative.c +msgid "div/mod not implemented for uint" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex type" +#: py/emitnative.c +msgid "comparison of int and uint" msgstr "" -#: py/objtype.c -msgid "cannot create '%q' instances" +#: py/emitnative.c +msgid "binary op %q not implemented" msgstr "" -#: py/objtype.c -msgid "cannot create instance" +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot delete array elements" +#: py/emitnative.c +msgid "casting" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot reshape array" +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" msgstr "" #: py/emitnative.c -msgid "casting" +msgid "must raise an object" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "channel re-init" +#: py/emitnative.c +msgid "native yield" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "chars buffer too small" +#: py/lexer.c +msgid "unicode name escapes" msgstr "" #: py/modbuiltins.c @@ -2849,1324 +2875,1633 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "clip point must be (x,y) tuple" +#: py/modbuiltins.c +msgid "arg is an empty sequence" msgstr "" -#: shared-bindings/msgpack/ExtType.c -msgid "code outside range 0~127" +#: py/modbuiltins.c +msgid "ord expects a character" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a buffer, tuple, list, or int" +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "pow() 는 3개의 인수를 지원하지 않습니다" + +#: py/modbuiltins.c +msgid "must use keyword argument for key function" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +#: py/moderrno.c +#, fuzzy +msgid "Operation not permitted" +msgstr "작업이 허용되지 않습니다" + +#: py/moderrno.c +msgid "No such file/directory" +msgstr "해당 파일/디렉토리가 없습니다" + +#: py/moderrno.c +msgid "Input/output error" +msgstr "입력/출력 오류" + +#: py/moderrno.c +msgid "Permission denied" +msgstr "권한이 거부 되었습니다" + +#: py/moderrno.c +msgid "File exists" +msgstr "파일이 있습니다" + +#: py/moderrno.c +msgid "No such device" +msgstr "해당 장치가 없습니다" + +#: py/moderrno.c +msgid "No space left on device" +msgstr "장치에 남은 공간이 없습니다" + +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" msgstr "" -#: shared-bindings/displayio/Palette.c -msgid "color must be between 0x000000 and 0xffffff" +#: py/modmath.c +msgid "negative factorial" msgstr "" -#: py/emitnative.c -msgid "comparison of int and uint" +#: py/modmicropython.c +msgid "schedule queue full" msgstr "" -#: py/objcomplex.c -msgid "complex divide by zero" +#: py/modstruct.c shared-module/struct/__init__.c +msgid "buffer too small" msgstr "" -#: py/objfloat.c py/parsenum.c -msgid "complex values not supported" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" msgstr "" -#: extmod/modzlib.c -msgid "compression header" +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "사전(dict)이 예상되었습니다" + +#: py/nativeglue.c +msgid "set unsupported" msgstr "" -#: py/emitnative.c -msgid "conversion to object" +#: py/nativeglue.c +msgid "slice unsupported" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be linear arrays" +#: py/nativeglue.c +msgid "float unsupported" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be ndarrays" +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c +msgid "can't convert %q to %q" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must not be empty" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "위 예외를 처리하는 동안, 또 다른 예외가 발생하였습니다:" + +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "corrupted file" +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " 파일 \"%q\", 라인 %d" + +#: py/obj.c +msgid " File \"%q\"" +msgstr " 파일 \"%q\"" + +#: py/obj.c +msgid ", in %q\n" +msgstr ", 에서 %q\n" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "could not invert Vandermonde matrix" +#: py/obj.c +msgid "can't convert to float" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "couldn't determine SD card version" +#: py/obj.c +#, c-format +msgid "can't convert %s to float" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "cross is defined for 1D arrays of length 3" +#: py/obj.c +msgid "can't convert to complex" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be iterable" +#: py/obj.c +#, fuzzy, c-format +msgid "can't convert %s to complex" +msgstr "%s 를 복합어로 변환할 수 없습니다" + +#: py/obj.c +msgid "expected tuple/list" +msgstr "튜플(tuple) 또는 리스트(list)이 예상되었습니다" + +#: py/obj.c +#, c-format +msgid "object '%s' isn't a tuple or list" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be of equal length" +#: py/obj.c +msgid "tuple/list has wrong length" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: py/obj.c #, c-format -msgid "data pin #%d in use" +msgid "requested length %d but object has length %d" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "data type not understood" +#: py/obj.c +msgid "indices must be integers" msgstr "" -#: py/parsenum.c -msgid "decimal numbers not supported" +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q 인덱스는 %s 가 아닌 정수 여야합니다" + +#: py/obj.c +msgid "object has no len" msgstr "" -#: py/compile.c -msgid "default 'except' must be last" +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "default is not a function" +#: py/obj.c +msgid "object doesn't support item deletion" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +#: py/obj.c +#, fuzzy, c-format +msgid "'%s' object doesn't support item deletion" +msgstr "'%s' 개체가 항목 삭제를 지원하지 않습니다" + +#: py/obj.c +msgid "object isn't subscriptable" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +#: py/obj.c +#, c-format +msgid "'%s' object isn't subscriptable" +msgstr "'%s' 개체를 subscriptable 할 수 없습니다" + +#: py/obj.c +msgid "object doesn't support item assignment" msgstr "" -#: py/objdict.c -msgid "dict update sequence has wrong length" +#: py/obj.c +#, fuzzy, c-format +msgid "'%s' object doesn't support item assignment" +msgstr "'%s' 개체가 항목 할당을 지원하지 않습니다" + +#: py/obj.c +msgid "object with buffer protocol required" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "diff argument must be an ndarray" +#: py/objarray.c +msgid "bytes length not a multiple of item size" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "differentiation order out of range" +#: py/objarray.c py/objstr.c +msgid "string argument without an encoding" msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "dimensions do not match" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" msgstr "" -#: py/emitnative.c -msgid "div/mod not implemented for uint" +#: py/objarray.c py/objstr.c +msgid "substring not found" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "divide by zero" +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: py/runtime.c -msgid "division by zero" +#: py/objarray.c +msgid "lhs and rhs should be compatible" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "dtype must be float, or complex" +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "dtype of int32 is not supported" +#: py/objarray.c +msgid "memoryview offset too large" msgstr "" -#: py/objdeque.c -msgid "empty" +#: py/objcomplex.c +msgid "can't truncate-divide a complex number" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "empty file" +#: py/objcomplex.c +msgid "complex divide by zero" msgstr "" -#: extmod/modasyncio.c extmod/modheapq.c -msgid "empty heap" +#: py/objcomplex.c +msgid "0.0 to a complex power" msgstr "" -#: py/objstr.c -msgid "empty separator" -msgstr "" +#: py/objdeque.c +msgid "full" +msgstr "완전한(full)" -#: shared-bindings/random/__init__.c -msgid "empty sequence" +#: py/objdeque.c +msgid "empty" msgstr "" -#: py/objstr.c -msgid "end of format while looking for conversion specifier" +#: py/objdict.c +msgid "dict update sequence has wrong length" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "epoch_time not supported on this board" +#: py/objexcept.c py/objnamedtuple.c +msgid "can't set attribute" msgstr "" -#: ports/nordic/common-hal/busio/UART.c -#, c-format -msgid "error = 0x%08lX" +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" msgstr "" -#: py/runtime.c -msgid "exceptions must derive from BaseException" +#: py/objgenerator.c +msgid "generator already executing" msgstr "" -#: py/objstr.c -msgid "expected ':' after format specifier" -msgstr "':'이 예상되었습니다" - -#: py/obj.c -msgid "expected tuple/list" -msgstr "튜플(tuple) 또는 리스트(list)이 예상되었습니다" - -#: py/modthread.c -msgid "expecting a dict for keyword args" -msgstr "사전(dict)이 예상되었습니다" - -#: py/compile.c -msgid "expecting an assembler instruction" +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" msgstr "" -#: py/compile.c -msgid "expecting just a value for set" +#: py/objgenerator.c py/runtime.c +msgid "generator raised StopIteration" msgstr "" -#: py/compile.c -msgid "expecting key:value for dict" +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "ext_hook is not a function" +#: py/objint.c py/runtime.c +#, c-format +msgid "can't convert %s to int" msgstr "" -#: py/argcheck.c -msgid "extra keyword arguments given" -msgstr "" +#: py/objint.c +msgid "float too big" +msgstr "float이 너무 큽니다" -#: py/argcheck.c -msgid "extra positional arguments given" +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" msgstr "" -#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c -#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c -msgid "file must be a file opened in byte mode" -msgstr "" +#: py/objint.c shared-bindings/time/__init__.c +msgid "No long integer support" +msgstr "긴 정수 지원이 없습니다" -#: shared-bindings/traceback/__init__.c -msgid "file write is not available" +#: py/objint.c py/sequence.c +msgid "small int overflow" msgstr "" +#: py/objint.c shared-bindings/_bleio/Connection.c #: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "" +msgid "%q=%q" +msgstr "%q=%q" -#: extmod/ulab/code/numpy/vector.c -msgid "first argument must be a callable" +#: py/objint_longlong.c py/parsenum.c +msgid "result overflows long long storage" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "first argument must be a function" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative shift count" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "first argument must be a tuple of ndarrays" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" msgstr "" -#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c -msgid "first argument must be an ndarray" +#: py/objint_longlong.c py/objint_mpz.c +msgid "overflow converting long int to machine word" msgstr "" -#: py/objtype.c -msgid "first argument to super() must be type" +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "first two arguments must be ndarrays" +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "flattening order must be either 'C', or 'F'" +#: py/objobject.c +msgid "__new__ arg must be a user-type" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "flip argument must be an ndarray" +#: py/objobject.c +msgid "arg must be user-type" msgstr "" -#: py/objint.c -msgid "float too big" -msgstr "float이 너무 큽니다" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +#, fuzzy +msgid "%q step cannot be zero" +msgstr "%q 단계는 0일 수 없습니다" -#: py/nativeglue.c -msgid "float unsupported" +#: py/objslice.c +msgid "Cannot subclass slice" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "font must be 2048 bytes long" +#: py/objstr.c +msgid "bytes value out of range" msgstr "" -#: extmod/moddeflate.c -msgid "format" +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" msgstr "" #: py/objstr.c -msgid "format requires a dict" +msgid "empty separator" msgstr "" -#: py/objdeque.c -msgid "full" -msgstr "완전한(full)" +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "" -#: py/argcheck.c -msgid "function doesn't take keyword arguments" +#: py/objstr.c +msgid "bad format string" msgstr "" -#: py/argcheck.c +#: py/objstr.c #, c-format -msgid "function expected at most %d arguments, got %d" +msgid "unmatched '%c' in format" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "function got multiple values for argument '%q'" +#: py/objstr.c +msgid "bad conversion specifier" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "function has the same sign at the ends of interval" +#: py/objstr.c +msgid "end of format while looking for conversion specifier" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "function is defined for ndarrays only" +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "function is implemented for ndarrays only" -msgstr "" +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "':'이 예상되었습니다" -#: py/argcheck.c -#, c-format -msgid "function missing %d required positional arguments" +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" msgstr "" -#: py/bc.c -msgid "function missing keyword-only argument" -msgstr "" +#: py/objstr.c +msgid "%q index out of range" +msgstr "%q 인덱스 범위를 벗어났습니다" -#: py/bc.c -msgid "function missing required keyword argument '%q'" +#: py/objstr.c +msgid "attributes not supported" msgstr "" -#: py/bc.c -#, c-format -msgid "function missing required positional argument #%d" +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c -#: shared-bindings/time/__init__.c -#, c-format -msgid "function takes %d positional arguments but %d were given" -msgstr "" +#: py/objstr.c +msgid "invalid format specifier" +msgstr "형식 지정자(format specifier)가 유효하지 않습니다" -#: py/objgenerator.c -msgid "generator already executing" +#: py/objstr.c +msgid "sign not allowed in string format specifier" msgstr "" -#: py/objgenerator.c -msgid "generator ignored GeneratorExit" +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: py/objgenerator.c py/runtime.c -msgid "generator raised StopIteration" +#: py/objstr.c +msgid "unknown format code '%c' for object of type '%q'" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "graphic must be 2048 bytes long" +#: py/objstr.c +#, fuzzy +msgid "'=' alignment not allowed in string format specifier" +msgstr "'=' 문자열 형식 지정자에서 정렬이 허용되지 않습니다" + +#: py/objstr.c +msgid "format needs a dict" msgstr "" -#: extmod/modhashlib.c -msgid "hash is final" +#: py/objstr.c +msgid "incomplete format key" msgstr "" -#: extmod/modheapq.c -msgid "heap must be a list" +#: py/objstr.c +msgid "incomplete format" msgstr "" -#: py/compile.c -msgid "identifier redefined as global" +#: py/objstr.c +msgid "format string needs more arguments" msgstr "" -#: py/compile.c -msgid "identifier redefined as nonlocal" +#: py/objstr.c +#, c-format +msgid "%%c needs int or char" msgstr "" -#: py/compile.c -msgid "import * not at module level" +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" msgstr "" -#: py/persistentcode.c -msgid "incompatible .mpy arch" +#: py/objstr.c +msgid "format string didn't convert all arguments" msgstr "" -#: py/persistentcode.c -msgid "incompatible .mpy file" +#: py/objstr.c +msgid "non-hex digit" msgstr "" #: py/objstr.c -msgid "incomplete format" +msgid "can't convert to str implicitly" msgstr "" #: py/objstr.c -msgid "incomplete format key" +msgid "can't convert '%q' object to %q implicitly" msgstr "" -#: extmod/modbinascii.c -msgid "incorrect padding" +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c -msgid "index is out of bounds" +#: py/objstrunicode.c +msgid "string index out of range" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "index must be tuple or int" +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "네이티브 개체에 액세스하기 전에 super().__init__()를 호출하십시오." + +#: py/objtype.c +msgid "__init__() should return None" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "indices must be integers, slices, or Boolean lists" +#: py/objtype.c py/runtime.c +msgid "object not callable" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" +#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c +msgid "'%q' object isn't callable" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "initial values must be iterable" +#: py/objtype.c +msgid "type takes 1 or 3 arguments" msgstr "" -#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c -msgid "initial_value length is wrong" +#: py/objtype.c +msgid "can't create instance" msgstr "" -#: py/compile.c -msgid "inline assembler must be a function" +#: py/objtype.c +msgid "can't create '%q' instances" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output dimensions differ" +#: py/objtype.c +msgid "can't add special method to already-subclassed class" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output shapes differ" +#: py/objtype.c +msgid "type isn't an acceptable base type" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input argument must be an integer, a tuple, or a list" +#: py/objtype.c +msgid "type '%q' isn't an acceptable base type" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "input array length must be power of 2" +#: py/objtype.c +msgid "multiple inheritance not supported" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input arrays are not compatible" +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input data must be an iterable" +#: py/objtype.c +msgid "first argument to super() must be type" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input dtype must be float or complex" +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input is not iterable" +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "input matrix is asymmetric" +#: py/parse.c +msgid "not a constant" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "input matrix is singular" +#: py/parse.c +msgid "Unable to init parser" +msgstr "파서를 초기화(init) 할 수 없습니다" + +#: py/parse.c +msgid "unexpected indent" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input must be 1- or 2-d" +#: py/parse.c +msgid "unindent doesn't match any outer indent level" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be a 1D ndarray" +#: py/parse.c +msgid "malformed f-string" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c -msgid "input must be a dense ndarray" +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "구문(syntax)가 정수가 유효하지 않습니다" + +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "구문(syntax)가 정수가 유효하지 않습니다" + +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "숫자에 대한 구문(syntax)가 유효하지 않습니다" + +#: py/parsenum.c +msgid "decimal numbers not supported" msgstr "" -#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c -msgid "input must be an ndarray" +#: py/persistentcode.c +msgid "incompatible .mpy file" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be an ndarray, or a scalar" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "input must be one-dimensional" +#: py/persistentcode.c +msgid "native code in .mpy unsupported" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "input must be square matrix" +#: py/persistentcode.c +msgid "incompatible .mpy arch" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "input must be tuple, list, range, or ndarray" +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "'%q' object does not support '%q'" +msgstr "'%q' 개체가 '%q'를 지원하지 않습니다" + +#: py/qstr.c +msgid "name too long" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input vectors must be of equal length" +#: py/runtime.c +msgid "name not defined" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "interp is defined for 1D iterables of equal length" +#: py/runtime.c +msgid "name '%q' isn't defined" msgstr "" -#: shared-bindings/_bleio/Adapter.c -#, c-format -msgid "interval must be in range %s-%s" +#: py/runtime.c +msgid "unsupported type for operator" msgstr "" -#: py/compile.c -msgid "invalid arch" +#: py/runtime.c +msgid "unsupported type for %q: '%s'" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +#: py/runtime.c +msgid "unsupported types for %q: '%q', '%q'" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid cert" -msgstr "cert가 유효하지 않습니다" +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "" -#: shared-bindings/bitmaptools/__init__.c +#: py/runtime.c #, c-format -msgid "invalid element size %d for bits_per_pixel %d\n" +msgid "need more than %d values to unpack" msgstr "" -#: shared-bindings/bitmaptools/__init__.c +#: py/runtime.c #, c-format -msgid "invalid element_size %d, must be, 1, 2, or 4" +msgid "too many values to unpack (expected %d)" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "invalid exception" +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" msgstr "" -#: py/objstr.c -msgid "invalid format specifier" -msgstr "형식 지정자(format specifier)가 유효하지 않습니다" - -#: shared-bindings/wifi/Radio.c -msgid "invalid hostname" +#: py/runtime.c +msgid "module '%q' has no attribute '%q'" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid key" -msgstr "키가 유효하지 않습니다" +#: py/runtime.c +#, fuzzy +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' 개체에 '%q' 특성이 없습니다" -#: py/compile.c -msgid "invalid micropython decorator" +#: py/runtime.c +msgid "can't set attribute '%q'" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c -msgid "invalid setting" +#: py/runtime.c +msgid "object not iterable" msgstr "" -#: shared-bindings/random/__init__.c -msgid "invalid step" -msgstr "단계(step)가 유효하지 않습니다" - -#: py/compile.c py/parse.c -msgid "invalid syntax" -msgstr "구문(syntax)가 유효하지 않습니다" - -#: py/parsenum.c -msgid "invalid syntax for integer" -msgstr "구문(syntax)가 정수가 유효하지 않습니다" - -#: py/parsenum.c -#, c-format -msgid "invalid syntax for integer with base %d" -msgstr "구문(syntax)가 정수가 유효하지 않습니다" - -#: py/parsenum.c -msgid "invalid syntax for number" -msgstr "숫자에 대한 구문(syntax)가 유효하지 않습니다" +#: py/runtime.c +msgid "'%q' object isn't iterable" +msgstr "'%q' 개체를 사용할 수 없습니다" -#: py/objtype.c -msgid "issubclass() arg 1 must be a class" +#: py/runtime.c +msgid "object not an iterator" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 2 must be a class or a tuple of classes" -msgstr "" +#: py/runtime.c +msgid "'%q' object isn't an iterator" +msgstr "'%q' 개체가 iterator가 아닙니다" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "iterations did not converge" +#: py/runtime.c +msgid "exceptions must derive from BaseException" msgstr "" -#: py/objstr.c -msgid "join expects a list of str/bytes objects consistent with self object" +#: py/runtime.c +msgid "can't import name %q" msgstr "" -#: py/argcheck.c -msgid "keyword argument(s) not implemented - use normal args instead" +#: py/runtime.c +msgid "memory allocation failed, heap is locked" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -msgid "label '%q' not defined" +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" msgstr "" - -#: py/compile.c -msgid "label redefined" + +#: py/runtime.c +msgid "can't convert to int" msgstr "" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" +#: py/runtime.c +msgid "division by zero" msgstr "" -#: py/objarray.c -msgid "lhs and rhs should be compatible" +#: py/runtime.c +msgid "maximum recursion depth exceeded" msgstr "" -#: py/emitnative.c -msgid "local '%q' has type '%q' but source is '%q'" +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" msgstr "" -#: py/emitnative.c -msgid "local '%q' used before type known" +#: py/stream.c shared-bindings/getpass/__init__.c +msgid "stream operation not supported" msgstr "" #: py/vm.c msgid "local variable referenced before assignment" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "loopback + silent mode not supported by peripheral" +#: py/vm.c +msgid "no active exception to reraise" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS already initialized" +#: py/vm.c +msgid "opcode" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS only works with built-in WiFi" -msgstr "" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot create a new Adapter; use _bleio.adapter;" +msgstr "_bleio.adapter를 사용해서; 새로운 Adapter를 만들 수 없습니다;" -#: py/parse.c -msgid "malformed f-string" -msgstr "" +#: shared-bindings/_bleio/Adapter.c +msgid "Could not set address" +msgstr "주소를 설정할 수 없습니다" -#: shared-bindings/_stage/Layer.c -msgid "map buffer too small" +#: shared-bindings/_bleio/Adapter.c +#, c-format +msgid "interval must be in range %s-%s" msgstr "" -#: py/modmath.c shared-bindings/math/__init__.c -msgid "math domain error" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot have scan responses for extended, connectable advertisements." +msgstr "확장되고 연결 가능한 광고에 대한 검색 응답을 가질 수 없습니다." + +#: shared-bindings/_bleio/Adapter.c +#, fuzzy +msgid "Only connectable advertisements can be directed" +msgstr "연결 가능한 광고만 지시할 수 있습니다" + +#: shared-bindings/_bleio/Adapter.c +msgid "non-zero timeout must be >= interval" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "matrix is not positive definite" +#: shared-bindings/_bleio/Adapter.c +msgid "window must be <= interval" msgstr "" -#: ports/espressif/common-hal/_bleio/Descriptor.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/Adapter.c +#, fuzzy +msgid "Prefix buffer must be on the heap" +msgstr "앞의 버퍼는 힙에 있어야 합니다" + +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "CharacteristicBuffer 쓰기는 제공되지 않습니다" + +#: shared-bindings/_bleio/Connection.c +msgid "" +"Connection has been disconnected and can no longer be used. Create a new " +"connection." +msgstr "연결이 끊어져 더 이상 사용할 수 없습니다. 새로운 연결을 만드십시오." + +#: shared-bindings/_bleio/PacketBuffer.c #, c-format -msgid "max_length must be 0-%d when fixed_length is %s" -msgstr "" +msgid "Buffer too short by %d bytes" +msgstr "버퍼가 %d 바이트로 너무 짧습니다" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c -msgid "maximum number of dimensions is " -msgstr "" +#: shared-bindings/_bleio/PacketBuffer.c +msgid "No connection: length cannot be determined" +msgstr "연결이 없습니다: 길이를 결정할 수 없습니다" -#: py/runtime.c -msgid "maximum recursion depth exceeded" -msgstr "" +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "UUID문자열이 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'형식이 아닙니다" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter must be > 0" +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" msgstr "" +"UUID값이 문자열(str), 정수(int) 또는 바이트버퍼가(byte buffer) 아닙니다" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter should be > 0" +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "median argument must be an ndarray" -msgstr "" +#: shared-bindings/_bleio/__init__.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c +#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c +msgid "Read-only" +msgstr "읽기 전용" -#: py/runtime.c -#, c-format -msgid "memory allocation failed, allocating %u bytes" -msgstr "" +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "잘못된 버퍼 크기" -#: py/runtime.c -msgid "memory allocation failed, heap is locked" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" msgstr "" -#: py/objarray.c -msgid "memoryview offset too large" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/objarray.c -msgid "memoryview: length is not a multiple of itemsize" +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" msgstr "" -#: extmod/modtime.c -msgid "mktime needs a tuple of length 8 or 9" +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "mode must be complete, or reduced" -msgstr "" +#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +msgid "Pin is input only" +msgstr "핀은 입력 전용입니다" -#: py/builtinimport.c -msgid "module not found" +#: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" -#: ports/espressif/common-hal/wifi/Monitor.c -msgid "monitor init failed" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "Key must be 16, 24, or 32 bytes long" +msgstr "키는 16, 24, 또는 32 바이트 길이여야 합니다" -#: extmod/ulab/code/numpy/poly.c -msgid "more degrees of freedom than data points" +#: shared-bindings/aesio/aes.c +msgid "Requested AES mode is unsupported" msgstr "" -#: py/compile.c -msgid "multiple *x in assignment" +#: shared-bindings/aesio/aes.c +msgid "Source and destination buffers must be the same length" msgstr "" -#: py/objtype.c -msgid "multiple bases have instance lay-out conflict" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "ECB only operates on 16 bytes at a time" +msgstr "ECB는 한 번에 16 바이트에서만 작동합니다" -#: py/objtype.c -msgid "multiple inheritance not supported" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "CBC blocks must be multiples of 16 bytes" +msgstr "CBC 블록은 16 바이트의 배수여야 합니다" -#: py/emitnative.c -msgid "must raise an object" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." msgstr "" -#: py/modbuiltins.c -msgid "must use keyword argument for key function" -msgstr "" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +#, fuzzy +msgid "Array values should be single bytes." +msgstr "배열 값은 1바이트 여야합니다." -#: py/runtime.c -msgid "name '%q' is not defined" +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." msgstr "" -#: py/runtime.c -msgid "name not defined" -msgstr "" +#: shared-bindings/alarm/__init__.c +msgid "Expected a kind of %q" +msgstr "%q 유형이 필요합니다" -#: py/qstr.c -msgid "name too long" -msgstr "" +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "이 보드에서는 PTC가 지원되지 않습니다" -#: py/persistentcode.c -msgid "native code in .mpy unsupported" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" msgstr "" -#: py/asmthumb.c -msgid "native method too big" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" msgstr "" -#: py/emitnative.c -msgid "native yield" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "ndarray length overflows" -msgstr "" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q는 'H' 또는 'B' 타입의 바이트 배열 또는 배열이어야 합니다" -#: py/runtime.c -#, c-format -msgid "need more than %d values to unpack" +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c shared-bindings/mcp4822/MCP4822.c +#: shared-bindings/usb_audio/USBMicrophone.c +msgid "Not playing" +msgstr "재생되지 않았습니다" + +#: shared-bindings/audiobusio/PDMIn.c +msgid "%q must be multiple of 8." msgstr "" -#: py/modmath.c -msgid "negative factorial" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Cannot record to a file" +msgstr "파일에 녹음 할 수 없습니다" + +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "대상 용량이 destination_length보다 작습니다." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: py/objint_longlong.c py/objint_mpz.c py/runtime.c -msgid "negative power with no float support" +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: py/objint_mpz.c py/runtime.c -msgid "negative shift count" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q는 h, H, b 또는 B 유형의 바이트 배열 또는 배열이어야 합니다" + +#: shared-bindings/audiocore/RawSample.c +msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "nested index must be int" +#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c +msgid "file must be a file opened in byte mode" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no SD card" -msgstr "" +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/Flanger.c +#: shared-bindings/audiodelays/GranularPitchShift.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c +#: shared-bindings/audiomixer/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "bits_per_sample은 8 또는 16이어야합니다" -#: py/vm.c -msgid "no active exception to reraise" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" msgstr "" -#: py/compile.c -msgid "no binding for nonlocal found" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "no default packer" +#: shared-bindings/audioi2sin/I2SIn.c +#, c-format +msgid "invalid destination buffer, must be an array of type: %c" msgstr "" -#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c -msgid "no default seed" -msgstr "" +#: shared-bindings/audioio/AudioOut.c +msgid "%q and %q must be different" +msgstr "%q와 %q는 달라야 합니다" -#: py/builtinimport.c -msgid "no module named '%q'" +#: shared-bindings/bitmapfilter/__init__.c +msgid "" +"weights must be a sequence with an odd square number of elements (usually 9 " +"or 25)" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no response from SD card" +#: shared-bindings/bitmapfilter/__init__.c +msgid "weights must be an object of type %q, %q, %q, or %q, not %q " msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c -msgid "no such attribute" +#: shared-bindings/bitmaptools/__init__.c +msgid "clip point must be (x,y) tuple" msgstr "" -#: ports/espressif/common-hal/_bleio/Connection.c -#: ports/nordic/common-hal/_bleio/Connection.c -msgid "non-UUID found in service_uuids_whitelist" +#: shared-bindings/bitmaptools/__init__.c +msgid "source palette too large" msgstr "" -#: py/compile.c -msgid "non-default argument follows default argument" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Bitmap size and bits per value must match" +msgstr "비트맵 크기와 값 당 비트가 일치해야 합니다" -#: py/objstr.c -msgid "non-hex digit found" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" +msgstr "L8 색상 공간의 경우, 입력 비트맵은 픽셀 당 8 비트를 가져야 합니다" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "non-zero timeout must be > 0.01" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" +msgstr "RGB 색상 공간의 경우, 입력 비트맵은 픽셀 당 16 비트를 가져야 합니다" -#: shared-bindings/_bleio/Adapter.c -msgid "non-zero timeout must be >= interval" +#: shared-bindings/bitmaptools/__init__.c +msgid "Unsupported colorspace" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "not a 128-bit UUID" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap size must match the other bitmaps" msgstr "" -#: py/parse.c -msgid "not a constant" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap must have 8 bits per pixel" msgstr "" -#: py/objstr.c -msgid "not all arguments converted during string formatting" +#: shared-bindings/bitmaptools/__init__.c +msgid "out of range of target" msgstr "" -#: py/objstr.c -msgid "not enough arguments for format string" +#: shared-bindings/bitmaptools/__init__.c +msgid "value out of range of target" msgstr "" -#: extmod/ulab/code/numpy/carray/carray_tools.c -msgid "not implemented for complex dtype" +#: shared-bindings/bitmaptools/__init__.c +msgid "background value out of range of target" msgstr "" -#: extmod/ulab/code/numpy/bitwise.c -msgid "not supported for input types" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "좌표 배열 유형은 크기가 다릅니다" -#: extmod/ulab/code/numpy/create.c -msgid "number of points must be at least 2" -msgstr "" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "좌표 배열의 길이가 다릅니다" -#: py/builtinhelp.c -msgid "object " +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" -#: py/obj.c +#: shared-bindings/bitmaptools/__init__.c #, c-format -msgid "object '%s' isn't a tuple or list" +msgid "invalid element size %d for bits_per_pixel %d\n" msgstr "" -#: py/obj.c -msgid "object doesn't support item assignment" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" -#: py/obj.c -msgid "object doesn't support item deletion" +#: shared-bindings/bitmaptools/__init__.c +msgid "bitmap sizes must match" msgstr "" -#: py/obj.c -msgid "object has no len" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 2 or 65536" msgstr "" -#: py/obj.c -msgid "object isn't subscriptable" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 65536" msgstr "" -#: py/runtime.c -msgid "object not an iterator" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 8" msgstr "" -#: py/objtype.c py/runtime.c -msgid "object not callable" +#: shared-bindings/bitmaptools/__init__.c +msgid "unsupported colorspace for dither" msgstr "" -#: py/sequence.c shared-bindings/displayio/Group.c -msgid "object not in sequence" -msgstr "" +#: shared-bindings/bitops/__init__.c +#, fuzzy, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "입력 버퍼 길이 (%d) 는 스트랜드 수 (%d)의 배수여야 한다" -#: py/runtime.c -msgid "object not iterable" -msgstr "" +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "기본 버스 %q가 없습니다" -#: py/obj.c -#, c-format -msgid "object of type '%s' has no len()" -msgstr "" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c +msgid "Display rotation must be in 90 degree increments" +msgstr "디스플레이 회전은 90도씩 증가해야 합니다" -#: py/obj.c -msgid "object with buffer protocol required" -msgstr "" +#: shared-bindings/busdisplay/BusDisplay.c +msgid "%q must be 1 when %q is True" +msgstr "%q가 참일 때 %q는 1이어야 합니다" -#: py/objstr.c -msgid "odd-length string" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Display must have a 16 bit colorspace." +msgstr "디스플레이는 16 비트 색 공간을 가져야 합니다." + +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c +msgid "tx and rx cannot both be None" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "off" +#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "%q의 하위클래스여야 합니다." + +#: shared-bindings/canio/RemoteTransmissionRequest.c +msgid "RemoteTransmissionRequests limited to 8 bytes" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "offset is too large" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Cannot set value when direction is input." +msgstr "방향이 입력되면 값을 설정할 수 없습니다." + +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Drive mode not used when direction is input." +msgstr "방향을 입력할 때 드라이브 모드는 사용되지 않습니다." + +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +#, fuzzy +msgid "Pull not used when direction is output." +msgstr "방향이 출력 될 때 풀은 사용되지 않습니다" + +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" msgstr "" -#: shared-bindings/dualbank/__init__.c -msgid "offset must be >= 0" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "offset must be non-negative and no greater than buffer length" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only bit_depth=16 is supported" +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "값을 삭제할 수 없습니다" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +msgid "Slices not supported" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only mono is supported" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "only ndarrays can be concatenated" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only oversample=64 is supported" +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only sample_rate=16000 is supported" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer, tuple, list, or int" msgstr "" -#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "only slices with step=1 (aka None) are supported" +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c +msgid "unsupported %q type" msgstr "" -#: py/vm.c -msgid "opcode" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c -msgid "operands could not be broadcast together" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for 2D arrays only" +#: shared-bindings/displayio/TileGrid.c +msgid "New bitmap must be same size as old bitmap" +msgstr "새로운 비트맵은 원본 비트맵과 크기가 같아야 합니다" + +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for ndarrays only" +#: shared-bindings/dualbank/__init__.c +msgid "offset must be >= 0" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is implemented for 1D Boolean arrays only" +#: shared-bindings/epaperdisplay/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "너무 빨리 새로고침하였습니다" + +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Buffer is not a bytearray." +msgstr "버퍼는 바이트 배열이 아닙니다." + +#: shared-bindings/gnss/GNSS.c +msgid "System entry must be gnss.SatelliteSystem" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "operation is not implemented on ndarrays" +#: shared-bindings/hashlib/__init__.c +msgid "Unsupported hash algorithm" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is not supported for given type" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "operation not supported for the input types" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" msgstr "" -#: py/modbuiltins.c -msgid "ord expects a character" +#: shared-bindings/i2ctarget/I2CTarget.c +msgid "addresses is empty" msgstr "" -#: py/modbuiltins.c +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "유효한 IP 문자열이 아닙니다" + +#: shared-bindings/ipaddress/IPv4Address.c #, c-format -msgid "ord() expected a character, but string of length %d found" +msgid "Address must be %d bytes long" +msgstr "주소 길이는 %d 바이트 여야합니다" + +#: shared-bindings/ipaddress/__init__.c +msgid "Only int or string supported for ip" +msgstr "ip에는 정수 또는 문자열만 지원됩니다" + +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "width must be greater than zero" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out array is too small" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "Scale dimensions must divide by 3" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "out has wrong type" +#: shared-bindings/is31fl3741/IS31FL3741.c +msgid "Mapping must be a tuple" +msgstr "매핑은 투플이어야 합니다" + +#: shared-bindings/jpegio/JpegDecoder.c +msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for complex dtype" +#: shared-bindings/mdns/Server.c +msgid "" +"Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" +"서비스 TXT 레코드를 추가하는 것에 실패했습니다; txt_records에서 비문자열 또" +"는 바이트가 발견되었습니다" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for function" +#: shared-bindings/memorymap/AddressRange.c +msgid "Address range wraps around" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out must be a float dense array" +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" +msgstr "%q에 중복된 핀이 포함" + +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" +msgstr "%q 및 %q에 중복된 핀이 포함" + +#: shared-bindings/msgpack/ExtType.c +msgid "code outside range 0~127" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be an ndarray" +#: shared-bindings/msgpack/__init__.c +msgid "default is not a function" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be of float dtype" +#: shared-bindings/msgpack/__init__.c +msgid "ext_hook is not a function" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "out of range of target" +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array has wrong type" +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "임의의 하드웨어를 사용할 수 없습니다" + +#: shared-bindings/paralleldisplaybus/ParallelBus.c +msgid "Specify exactly one of data0 or data_pins" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array must be contiguous" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "명령을 보내는 것에 실패했습니다." + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "배열은 하프워드(유형 'H')가 포함되어야 합니다" + +#: shared-bindings/pwmio/PWMOut.c +msgid "Conflicting settings for shared resource" msgstr "" -#: py/objint_mpz.c -msgid "overflow converting long int to machine word" +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" msgstr "" -#: py/modstruct.c -#, c-format -msgid "pack expected %d items for packing (got %d)" +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "단계(step)가 유효하지 않습니다" + +#: shared-bindings/random/__init__.c +msgid "empty sequence" msgstr "" -#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c -msgid "palette must be 32 bytes long" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" msgstr "" -#: py/emitinlinextensa.c -msgid "parameters must be registers in sequence a2 to a5" +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: py/emitinlinethumb.c -msgid "parameters must be registers in sequence r0 to r3" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" msgstr "" -#: extmod/vfs_posix_file.c -msgid "poll on file not available on win32" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" msgstr "" -#: ports/espressif/common-hal/pulseio/PulseIn.c -msgid "pop from an empty PulseIn" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/pulseio/PulseIn.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c -#: shared-bindings/ps2io/Ps2.c -msgid "pop from empty %q" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "%d이 아닌, 6 rgb 핀을 여러 개 사용해야 합니다" + +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +"%d 주소 핀들, %d rgb 핀들과 %d 타일 들은 높이가 %d임을 나타낸다, %d가 아니라" #: shared-bindings/socketpool/Socket.c msgid "port must be >= 0" msgstr "" -#: py/compile.c -msgid "positional arg after **" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "buffer too small for requested bytes" msgstr "" -#: py/compile.c -msgid "positional arg after keyword arg" -msgstr "" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "이름 또는 서비스를 알 수 없습니다" -#: py/objint_mpz.c -msgid "pow() 3rd argument cannot be 0" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." msgstr "" -#: py/objint_mpz.c -msgid "pow() with 3 arguments requires integers" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "pull masks conflict with direction masks" -msgstr "" +#: shared-bindings/storage/__init__.c shared-bindings/usb_audio/__init__.c +#: shared-bindings/usb_cdc/__init__.c shared-bindings/usb_hid/__init__.c +#: shared-bindings/usb_midi/__init__.c shared-bindings/usb_video/__init__.c +msgid "Cannot change USB devices now" +msgstr "현재 USB 디바이스를 변경할 수 없습니다" -#: py/parse.c -msgid "raw f-strings are not supported" -msgstr "" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c +msgid "File not found" +msgstr "파일을 찾을 수 없습니다" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "real and imaginary parts must be of equal length" +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" msgstr "" -#: py/builtinimport.c -msgid "relative import" +#: shared-bindings/traceback/__init__.c +msgid "Supply both or neither of %q and %q" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "results cannot be cast to specified type" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" msgstr "" -#: py/compile.c -msgid "return annotation must be an identifier" +#: shared-bindings/usb_audio/USBSpeaker.c +msgid "destination must be an array of type 'h'" msgstr "" -#: py/emitnative.c -msgid "return expected '%q' but got '%q'" +#: shared-bindings/usb_audio/__init__.c +msgid "At least one of microphone and speaker must be enabled" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] duplicates another pin assignment" -msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "%q, %q 및 %q의 길이는 모두 같아야 합니다" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] is not on the same port as clock" +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." msgstr "" +"개체가 초기화 해제되어 더 이사 사용될 수 없습니다. 새로운 개체를 만드십시오." -#: extmod/ulab/code/numpy/numerical.c -msgid "roll argument must be an ndarray" -msgstr "" +#: shared-bindings/warnings/__init__.c +msgid "%q must be a subclass of %q" +msgstr "%q는 %q의 하위 클래스여야 합니다" -#: py/objstr.c -msgid "rsplit(None,n)" -msgstr "" +#: shared-bindings/wifi/Monitor.c +#, fuzzy +msgid "%q out of bounds" +msgstr "%q가 경계를 벗어남" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -msgid "sampling rate out of range" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Invalid hex password" +msgstr "잘못된 16진수 패스워드" -#: py/modmicropython.c -msgid "schedule queue full" +#: shared-bindings/wifi/Radio.c +msgid "invalid hostname" msgstr "" -#: py/builtinimport.c -msgid "script compilation not supported" +#: shared-bindings/wifi/Radio.c +msgid "Invalid MAC address" +msgstr "잘못된 MAC 주소" + +#: shared-bindings/wifi/Radio.c +msgid "AuthMode.OPEN is not used with password" +msgstr "AuthMode.OPEN은 암호와 함께 사용되지 않습니다" + +#: shared-bindings/wifi/Radio.c +msgid "Invalid BSSID" +msgstr "잘못된 BSSID" + +#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c +msgid "Authentication failure" +msgstr "인증 실패" + +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "이 ssid를 사용하는 네트워크가 없습니다" + +#: shared-bindings/wifi/Radio.c +#, c-format +msgid "Unknown failure %d" msgstr "" -#: py/nativeglue.c -msgid "set unsupported" +#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#, c-format +msgid "No I2C device at address: 0x%x" +msgstr "주소에 I2C 장치가 없습니다: 0x%x" + +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "형식 청크 크기가 잘못되었습니다" + +#: shared-module/audiocore/__init__.c shared-module/usb_audio/USBMicrophone.c +msgid "The sample's %q does not match" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "shape must be None, and integer or a tuple of integers" +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "shape must be integer or tuple of integers" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Only 8/16-bit mono/stereo is supported" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "short read" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "buffer_size too small for source" msgstr "" -#: py/objstr.c -msgid "sign not allowed in string format specifier" -msgstr "" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Couldn't allocate decoder" +msgstr "디코더를 할당할 수 없습니다" -#: py/objstr.c -msgid "sign not allowed with integer format specifier 'c'" -msgstr "" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Failed to parse MP3 file" +msgstr "MP3 파일 분석에 실패했습니다" -#: extmod/ulab/code/ulab_tools.c -msgid "size is defined for ndarrays only" +#: shared-module/bitbangio/I2C.c +msgid "%q too long" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "size must match out.shape when used together" +#: shared-module/bitmapfilter/__init__.c +msgid "bitmap size and depth must match" msgstr "" -#: py/nativeglue.c -msgid "slice unsupported" +#: shared-module/bitmapfilter/__init__.c +msgid "unsupported bitmap depth" msgstr "" -#: py/objint.c py/sequence.c -msgid "small int overflow" -msgstr "" +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "값 당 잘못된 비트" -#: main.c -msgid "soft reboot\n" -msgstr "" +#: shared-module/displayio/ColorConverter.c +#, fuzzy +msgid "Only one color can be transparent at a time" +msgstr "한 번에 한 가지 색상만 투명할 수 있습니다" -#: extmod/ulab/code/numpy/numerical.c -msgid "sort argument must be an ndarray" -msgstr "" +#: shared-module/displayio/Group.c +msgid "Layer already in a group" +msgstr "레이어가 이미 그룹에 있습니다" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos array must be of shape (n_section, 6)" -msgstr "" +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass" +msgstr "레이어는 그룹 또는 TileGrid 하위 클래스 여야 합니다" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos[:, 3] should be all ones" -msgstr "" +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "윈도우 형식, 비압축 BMP만 지원됩니다: 지정된 헤더 크기는 %d 입니다" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sosfilt requires iterable arguments" +#: shared-module/displayio/OnDiskBitmap.c +msgid "RLE-compressed BMP not supported" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source palette too large" +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 2 or 65536" +#: shared-module/displayio/__init__.c +msgid "Too many displays" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 65536" +#: shared-module/displayio/__init__.c +msgid "Too many display busses; forgot displayio.release_displays() ?" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 8" +#: shared-module/displayio/bus_core.c +msgid "Unsupported display bus type" msgstr "" -#: extmod/modre.c -msgid "splitting with sub-captures" +#: shared-module/gifio/GifWriter.c +msgid "unsupported colorspace for GifWriter" msgstr "" -#: py/objstr.c -msgid "start/end indices" +#: shared-module/i2cdisplaybus/I2CDisplayBus.c +#: shared-module/is31fl3741/IS31FL3741.c +#, c-format +msgid "Unable to find I2C Display at %x" msgstr "" -#: shared-bindings/random/__init__.c -msgid "stop not reachable from start" +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" msgstr "" -#: py/stream.c shared-bindings/getpass/__init__.c -msgid "stream operation not supported" +#: shared-module/imagecapture/ParallelImageCapture.c +msgid "This microcontroller does not support continuous capture." msgstr "" -#: py/objarray.c py/objstr.c -msgid "string argument without an encoding" -msgstr "" +#: shared-module/is31fl3741/FrameBuffer.c +msgid "LED mappings must match display size" +msgstr "LED 매핑은 디스플레이 크기와 일치해야 합니다" -#: py/objstrunicode.c -msgid "string index out of range" -msgstr "" +#: shared-module/jpegio/JpegDecoder.c +msgid "Interrupted by output function" +msgstr "출력 함수로 인해 종료되었다" -#: py/objstrunicode.c -#, c-format -msgid "string indices must be integers, not %s" -msgstr "" +#: shared-module/jpegio/JpegDecoder.c +msgid "Device error or wrong termination of input stream" +msgstr "장치 오류 또는 입력 스트림의 잘못된 종료" -#: py/objarray.c py/objstr.c -msgid "substring not found" -msgstr "" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient memory pool for the image" +msgstr "이미지에 대한 메모리 풀이 부족합니다" -#: py/compile.c -msgid "super() can't find self" -msgstr "" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient stream input buffer" +msgstr "불충분한 스트림 입력 버퍼" -#: extmod/modjson.c -msgid "syntax error in JSON" +#: shared-module/jpegio/JpegDecoder.c +#, fuzzy +msgid "Parameter error" +msgstr "파라미터 오류" + +#: shared-module/jpegio/JpegDecoder.c +msgid "Data format error (may be broken data)" +msgstr "데이터 형식 오류(손상된 데이터일 수 있습니다)" + +#: shared-module/jpegio/JpegDecoder.c +msgid "Right format but not supported" msgstr "" -#: extmod/modtime.c -msgid "ticks interval overflow" +#: shared-module/jpegio/JpegDecoder.c +msgid "Unsupported JPEG (may be progressive)" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "timeout duration exceeded the maximum supported value" +#: shared-module/jpegio/JpegDecoder.c +msgid "%q() without %q()" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "timeout must be < 655.35 secs" +#: shared-module/memorymonitor/AllocationAlarm.c +#, c-format +msgid "Attempt to allocate %d blocks" +msgstr "%d 블록 할당 시도" + +#: shared-module/msgpack/__init__.c +msgid "short read" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -msgid "timeout waiting for flux" +#: shared-module/msgpack/__init__.c +msgid "no default packer" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: shared-module/floppyio/__init__.c -msgid "timeout waiting for index pulse" +#: shared-module/msgpack/__init__.c supervisor/shared/settings.c +msgid "Invalid format" +msgstr "잘못된 형식" + +#: shared-module/paralleldisplaybus/ParallelBus.c +msgid "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." msgstr "" +#: shared-module/rgbmatrix/RGBMatrix.c +msgid "No timer available" +msgstr "사용 가능한 타이머가 없습니다" + +#: shared-module/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Internal error #%d" +msgstr "내부 오류 #%d" + #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" msgstr "" @@ -4175,276 +4510,282 @@ msgstr "" msgid "timeout waiting for v2 card" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "timer re-init" +#: shared-module/sdcardio/SDCard.c +msgid "no SD card" msgstr "" -#: shared-bindings/time/__init__.c -msgid "timestamp out of range for platform time_t" +#: shared-module/sdcardio/SDCard.c +msgid "couldn't determine SD card version" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "tobytes can be invoked for dense arrays only" +#: shared-module/sdcardio/SDCard.c +msgid "no response from SD card" msgstr "" -#: py/compile.c -msgid "too many args" +#: shared-module/sdcardio/SDCard.c +msgid "SD card CSD format not supported" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c -msgid "too many dimensions" +#: shared-module/sdcardio/SDCard.c +msgid "can't set 512 block size" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "too many indices" -msgstr "" +#: shared-module/ssl/SSLSocket.c +msgid "Invalid socket for TLS" +msgstr "TLS에 대한 잘못된 소켓" -#: py/asmthumb.c -msgid "too many locals for native method" -msgstr "" +#: shared-module/ssl/SSLSocket.c +msgid "invalid key" +msgstr "키가 유효하지 않습니다" -#: py/runtime.c -#, c-format -msgid "too many values to unpack (expected %d)" -msgstr "" +#: shared-module/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "cert가 유효하지 않습니다" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D arrays of equal length" +#: shared-module/storage/__init__.c +msgid "Mount point directory missing" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D iterables" +#: shared-module/storage/__init__.c +msgid "Cannot remount path when visible via USB." msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "" +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' 및 'O'는 지원되지 않는 형식 유형입니다" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_driver_install returned esp-idf error #%d" +#: shared-module/struct/__init__.c +msgid "buffer size must match format" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_start returned esp-idf error #%d" -msgstr "" +#: shared-module/synthio/__init__.c +#, fuzzy +msgid "%q must be array of type 'h'" +msgstr "%q는 'h' 유형의 배열이어야 합니다" -#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c -msgid "tx and rx cannot both be None" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" msgstr "" -#: py/objtype.c -msgid "type '%q' is not an acceptable base type" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" msgstr "" -#: py/objtype.c -msgid "type is not an acceptable base type" -msgstr "" +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "핀에 풀다운이 없습니다; 1Mohm를 권장합니다" + +#: shared-module/usb/core/Device.c +msgid "No usb host port initialized" +msgstr "usb 호스트 포트가 초기화되지 않았습니다" -#: py/runtime.c -msgid "type object '%q' has no attribute '%q'" -msgstr "" +#: shared-module/usb/core/Device.c +msgid "Pipe error" +msgstr "파이프 오류" -#: py/objtype.c -msgid "type takes 1 or 3 arguments" -msgstr "" +#: shared-module/usb/core/Device.c +#, fuzzy +msgid "No configuration set" +msgstr "구성이 설정되어 있지 않습니다" -#: py/objint_longlong.c -msgid "ulonglong too large" +#: shared-module/usb_hid/Device.c +msgid "USB busy" msgstr "" -#: py/parse.c -msgid "unexpected indent" +#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Rectangle.c +msgid "can only have one parent" msgstr "" -#: py/bc.c -msgid "unexpected keyword argument" -msgstr "" +#: shared-module/vectorio/Polygon.c +msgid "Polygon needs at least 3 points" +msgstr "다각형은 최소 3개의 점이 필요합니다" -#: py/argcheck.c py/bc.c py/objnamedtuple.c -#: shared-bindings/traceback/__init__.c -msgid "unexpected keyword argument '%q'" -msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "다시 연결하는 중입니다" -#: py/lexer.c -msgid "unicode name escapes" -msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "켜짐 (연결됨)" -#: py/parse.c -msgid "unindent doesn't match any outer indent level" -msgstr "" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "꺼짐 (연결 끊김)" -#: py/objstr.c -#, c-format -msgid "unknown conversion specifier %c" +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" -#: py/objstr.c -msgid "unknown format code '%c' for object of type '%q'" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" msgstr "" +"\n" +"안전 모드에 있는 이유는 다음과 같습니다:\n" -#: py/compile.c -msgid "unknown type" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Power dipped. Make sure you are providing enough power." +msgstr "전력이 내려갔습니다. 충분한 전력을 제공할 수 있는지 확인하십시오." -#: py/compile.c -msgid "unknown type '%q'" +#: supervisor/shared/safe_mode.c +msgid "You pressed the BOOT button at start up" msgstr "" -#: py/objstr.c -#, c-format -msgid "unmatched '%c' in format" +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." msgstr "" -#: py/objtype.c py/runtime.c -msgid "unreadable attribute" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CIRCUITPY drive could not be found or created." +msgstr "CIRCUITPY 드라이브를 찾거나 만들 수 없습니다." -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -msgid "unsupported %q type" +#: supervisor/shared/safe_mode.c +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "safemode.py에 오류가 있습니다." -#: py/emitinlinextensa.c -#, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" +#: supervisor/shared/safe_mode.c +msgid "Stack overflow. Increase stack size." msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "unsupported bitmap depth" +#: supervisor/shared/safe_mode.c +msgid "USB devices need more endpoints than are available." msgstr "" -#: shared-module/gifio/GifWriter.c -msgid "unsupported colorspace for GifWriter" +#: supervisor/shared/safe_mode.c +msgid "USB devices specify too many interface names." msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "unsupported colorspace for dither" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Boot device must be first (interface #0)." +msgstr "부팅 장치는 첫 번째(인터페이스 #0)여야 합니다." -#: py/objstr.c -#, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Internal watchdog timer expired." +msgstr "내부 감시 타이머가 만료되었습니다." -#: py/runtime.c -msgid "unsupported type for %q: '%s'" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython core code crashed hard. Whoops!\n" +msgstr "CircuitPython 핵심 코드가 심하게 충돌했습니다. 앗!\n" -#: py/runtime.c -msgid "unsupported type for operator" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "VM이 작동하지 않을 때 힙이 할당됩니다." -#: py/runtime.c -msgid "unsupported types for %q: '%q', '%q'" -msgstr "" +#: supervisor/shared/safe_mode.c +#, fuzzy +msgid "Failed to write internal flash." +msgstr "내부 플래시를 쓰는 것에 실패했습니다." -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols is too high" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Hard fault: memory access or instruction error." +msgstr "치명적인 실수: 메모리 액세스 또는 명령 오류." -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols keyword must be specified" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "인터럽트 오류." -#: py/objint.c -#, c-format -msgid "value must fit in %d byte(s)" -msgstr "" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "NLR 는 점프에 실패했습니다. 아마도 메모리 손상일 것입니다." -#: shared-bindings/bitmaptools/__init__.c -msgid "value out of range of target" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate to the heap." msgstr "" -#: extmod/moddeflate.c -msgid "wbits" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." msgstr "" -#: shared-bindings/bitmapfilter/__init__.c +#: supervisor/shared/safe_mode.c msgid "" -"weights must be a sequence with an odd square number of elements (usually 9 " -"or 25)" +"\n" +"Please file an issue with your program at github.com/adafruit/circuitpython/" +"issues." msgstr "" +"\n" +"github.com/adafruit/circuitpython/issues 에\n" +"프로그램 오류를 제출하세요." -#: shared-bindings/bitmapfilter/__init__.c -msgid "weights must be an object of type %q, %q, %q, or %q, not %q " +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" msgstr "" +"\n" +"재설정을 눌러 안전 모드를 종료합니다.\n" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "width must be greater than zero" -msgstr "" +#: supervisor/shared/settings.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "%s'을(를) 검색하는 동안 오류가 발생했습니다:\n" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "" +#: supervisor/shared/settings.c +msgid "Invalid unicode escape" +msgstr "잘못된 유니코드 이스케이프" -#: ports/raspberrypi/common-hal/wifi/Monitor.c -msgid "wifi.Monitor not available" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "Wi-Fi: " msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "window must be <= interval" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "off" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "wrong axis index" -msgstr "" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "No IP" +msgstr "IP가 없습니다" -#: extmod/ulab/code/numpy/create.c -msgid "wrong axis specified" -msgstr "" +#~ msgid "%q renamed %q" +#~ msgstr "%q가 %q로 이름이 변경되었습니다" -#: extmod/ulab/code/numpy/io/io.c -msgid "wrong dtype" -msgstr "" +#, c-format +#~ msgid "Buffer + offset too small %d %d %d" +#~ msgstr "Buffer + offset이 너무 작습니다 %d %d %d" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong index type" -msgstr "" +#~ msgid "Byte buffer must be 16 bytes." +#~ msgstr "잘못된 크기의 버퍼. 16 바이트 여야합니다." -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c -#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c -#: extmod/ulab/code/numpy/vector.c -msgid "wrong input type" -msgstr "" +#, c-format +#~ msgid "Invalid byte %.*s" +#~ msgstr "잘못된 바이트 %.*s" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of condition array" -msgstr "" +#~ msgid "Key not found" +#~ msgstr "키를 찾을 수 없습니다" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of index array" -msgstr "" +#, fuzzy +#~ msgid "Not supported JPEG standard" +#~ msgstr "지원되지 않는 JPEG 표준" -#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c -msgid "wrong number of arguments" -msgstr "" +#, fuzzy +#~ msgid "%q moved from %q to %q" +#~ msgstr "%q가 %q에서 %q로 이동했습니다" -#: py/runtime.c -msgid "wrong number of values to unpack" -msgstr "" +#, c-format +#~ msgid "%%c requires int or char" +#~ msgstr "%%c 전수(int)또는 캐릭터(char)필요합니다" -#: extmod/ulab/code/numpy/vector.c -msgid "wrong output type" -msgstr "" +#~ msgid "'%q' object is not callable" +#~ msgstr "'%q' 개체를 호출할 수 없습니다" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be an ndarray" -msgstr "" +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "USB를 통해 표시될 때 '/'은 다시 마운트할 수 없습니다." -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of float type" -msgstr "" +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "데이터 청크는 fmt 청크를 따라야 합니다" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of shape (n_section, 2)" -msgstr "" +#, fuzzy, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "흑백, 인덱싱된 4bpp 또는 8bpp, 그리고 16bpp 또는 그 이상의 BMP만 지원됩니" +#~ "다: %d bpp가 지정되었습니다" #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "버퍼 길이는 512의 배수여야 합니다" @@ -4560,13 +4901,13 @@ msgstr "" #~ msgid "'%s' object does not support item deletion" #~ msgstr "'%s' 은 삭제할 수 없습니다" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "'%s' 은 수정할 수 없습니다" #~ msgid "'%s' object is not callable" #~ msgstr "'%s' 을 검색 할 수 없습니다" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "'%s' 은 변경할 수 없습니다" #~ msgid "'break' outside loop" diff --git a/locale/nl.po b/locale/nl.po index 2d53144a4ff..bafb415635e 100644 --- a/locale/nl.po +++ b/locale/nl.po @@ -6,15 +6,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-16 15:03+0000\n" -"Last-Translator: Jeff Epler \n" +"PO-Revision-Date: 2025-07-13 16:01+0000\n" +"Last-Translator: Mirthe Winter \n" "Language-Team: none\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.2\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" @@ -49,7 +49,7 @@ msgstr "" #: py/obj.c msgid " File \"%q\"" -msgstr " Bestand" +msgstr " Bestand \"%q\"" #: py/obj.c msgid " File \"%q\", line %d" @@ -61,7 +61,7 @@ msgstr "" #: main.c msgid " not found.\n" -msgstr "" +msgstr " niet gevonden.\n" #: main.c msgid " output:\n" @@ -82,7 +82,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "" @@ -102,7 +102,11 @@ msgstr "" msgid "%q failure: %d" msgstr "%q fout: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "" @@ -154,7 +158,7 @@ msgstr "" msgid "%q length must be >= %d" msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "" @@ -214,6 +218,7 @@ msgstr "" #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "" @@ -223,6 +228,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "" @@ -268,7 +274,8 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "" @@ -302,7 +309,7 @@ msgid "'%q' object does not support '%q'" msgstr "'%q' object ondersteunt geen '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "'%q' object is geen iterator" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -310,7 +317,7 @@ msgid "'%q' object is not callable" msgstr "'%q' object is niet aanroepbaar" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "'%q' object is niet itereerbaar" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -537,7 +544,6 @@ msgstr "Alle timers voor deze pin zijn in gebruik" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Alle timers zijn in gebruik" @@ -550,6 +556,10 @@ msgstr "Advertising is al bezig." msgid "Already have all-matches listener" msgstr "Heeft al een luisteraar voor 'all-matches'" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Al in uitvoering" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -559,6 +569,7 @@ msgstr "Wordt al uitgevoerd" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Zoekt al naar WiFi netwerken" @@ -585,6 +596,10 @@ msgstr "Array moet halfwords (type 'H') bevatten" msgid "Array values should be single bytes." msgstr "Array waardes moet enkele bytes zijn." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -594,6 +609,11 @@ msgstr "Poging om %d blokken toe te wijzen" msgid "Audio conversion not implemented" msgstr "" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Audiobronfout" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -611,8 +631,8 @@ msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -"Auto-herlaad staat aan. Sla bestanden simpelweg op over USB om uit te voeren " -"of start REPL om uit te schakelen.\n" +"Auto-herlaad staat aan. Sla bestanden simpelweg via USB op om ze uit te " +"voeren of start REPL om ze uit te schakelen.\n" #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" @@ -681,7 +701,7 @@ msgstr "Buffer is %d bytes te klein" #: shared-bindings/framebufferio/FramebufferDisplay.c #: shared-bindings/struct/__init__.c shared-module/struct/__init__.c msgid "Buffer too small" -msgstr "" +msgstr "Buffer te klein" #: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c #: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c @@ -727,6 +747,10 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -773,7 +797,7 @@ msgid "Cannot record to a file" msgstr "Kan niet opnemen naar een bestand" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." +msgid "Cannot remount path when visible via USB." msgstr "" #: shared-bindings/digitalio/DigitalInOut.c @@ -789,6 +813,10 @@ msgstr "Kan RTS of CTS niet specificeren in RS485 modus" msgid "Cannot subclass slice" msgstr "Kan slice niet subclasseren" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "" @@ -825,6 +853,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "Kan adres niet zetten" @@ -837,6 +869,11 @@ msgstr "Kan interrupt niet starten, RX is bezig" msgid "Couldn't allocate decoder" msgstr "Kan decoder niet alloceren" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC kanaal Init Fout" @@ -854,10 +891,6 @@ msgstr "DAC al in gebruik" msgid "Data 0 pin must be byte aligned" msgstr "Data 0 pin moet byte uitgelijnd zijn" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Data chunk moet gevolgd worden door fmt chunk" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "" @@ -901,7 +934,7 @@ msgstr "Beeldscherm rotatie moet in stappen van 90 graden" #: main.c msgid "Done" -msgstr "" +msgstr "Gedaan" #: shared-bindings/digitalio/DigitalInOut.c msgid "Drive mode not used when direction is input." @@ -988,15 +1021,47 @@ msgstr "Verbinding mislukt: interne fout" msgid "Failed to connect: timeout" msgstr "Verbinding mislukt: timeout" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Mislukt om MP3 bestand te ontleden" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Mislukt mutex los te laten, err 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Schrijven naar interne flash mislukt." @@ -1005,23 +1070,25 @@ msgstr "Schrijven naar interne flash mislukt." msgid "File exists" msgstr "Bestand bestaat" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" -msgstr "" +msgstr "Bestand niet gevonden" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Filters zijn te complex" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is duplicate" -msgstr "" +msgstr "Firmware is duplicaat" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is invalid" -msgstr "" +msgstr "Firmware is ongeldig" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is too big" @@ -1035,7 +1102,7 @@ msgstr "" msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "Formaat wordt niet ondersteund" @@ -1055,7 +1122,7 @@ msgstr "" #: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" -msgstr "" +msgstr "Generieke mislukking" #: shared-bindings/framebufferio/FramebufferDisplay.c #: shared-module/busdisplay/BusDisplay.c @@ -1143,6 +1210,7 @@ msgid "Insufficient stream input buffer" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "" @@ -1156,7 +1224,7 @@ msgstr "Interne define fout" #: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c msgid "Internal error" -msgstr "" +msgstr "Interne fout" #: shared-module/rgbmatrix/RGBMatrix.c #, c-format @@ -1182,7 +1250,7 @@ msgstr "" #: supervisor/shared/safe_mode.c msgid "Interrupt error." -msgstr "" +msgstr "Interruptfout." #: shared-module/jpegio/JpegDecoder.c msgid "Interrupted by output function" @@ -1198,7 +1266,9 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "Ongeldige %q" @@ -1221,7 +1291,7 @@ msgstr "Ongeldige ADC Unit waarde" #: ports/espressif/common-hal/_bleio/__init__.c #: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid BLE parameter" -msgstr "" +msgstr "Ongeldige BLE-parameter" #: shared-bindings/wifi/Radio.c msgid "Invalid BSSID" @@ -1229,6 +1299,10 @@ msgstr "Ongeldig BSSID" #: shared-bindings/wifi/Radio.c msgid "Invalid MAC address" +msgstr "Ongeldig MAC-adres" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c @@ -1251,7 +1325,7 @@ msgstr "" #: shared-module/msgpack/__init__.c msgid "Invalid format" -msgstr "" +msgstr "Ongeldig formaat" #: shared-module/audiocore/WaveFile.c msgid "Invalid format chunk size" @@ -1262,24 +1336,26 @@ msgid "Invalid hex password" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c msgid "Invalid size" -msgstr "" +msgstr "Ongeldige grootte" #: shared-module/ssl/SSLSocket.c msgid "Invalid socket for TLS" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" -msgstr "" +msgstr "Ongeldige staat" #: shared-module/os/getenv.c msgid "Invalid unicode escape" -msgstr "" +msgstr "Ongeldige unicode escape" #: shared-bindings/aesio/aes.c msgid "Key must be 16, 24, or 32 bytes long" @@ -1287,7 +1363,7 @@ msgstr "Sleutel moet 16, 24, of 32 bytes lang zijn" #: shared-module/os/getenv.c msgid "Key not found" -msgstr "" +msgstr "Sleutel niet gevonden" #: shared-module/is31fl3741/FrameBuffer.c msgid "LED mappings must match display size" @@ -1318,6 +1394,11 @@ msgstr "" msgid "MITM security not supported" msgstr "" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "" @@ -1363,7 +1444,8 @@ msgstr "" msgid "Mount point directory missing" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "%q moet een subklasse zijn." @@ -1442,7 +1524,7 @@ msgstr "" #: supervisor/shared/web_workflow/web_workflow.c msgid "No IP" -msgstr "" +msgstr "Geen IP" #: ports/atmel-samd/common-hal/microcontroller/__init__.c #: ports/cxd56/common-hal/microcontroller/__init__.c @@ -1503,6 +1585,10 @@ msgstr "" msgid "No pulldown on pin; 1Mohm recommended" msgstr "Geen pulldown op pin; 1MOhm aangeraden" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "" + #: py/moderrno.c msgid "No space left on device" msgstr "Geen ruimte meer beschikbaar op apparaat" @@ -1606,15 +1692,6 @@ msgstr "" msgid "Only int or string supported for ip" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Alleen monochrome en 4bpp of 8bpp, en 16bpp of grotere geïndiceerde BMP's " -"zijn ondersteund: %d bpp is gegeven" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "" @@ -1665,6 +1742,7 @@ msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Geen sockets meer beschikbaar" @@ -1684,6 +1762,10 @@ msgstr "" msgid "PWM slice channel A already in use" msgstr "" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "" @@ -1763,7 +1845,7 @@ msgstr "Prefix buffer moet op de heap zijn" #: main.c msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" -"Druk een willekeurige toets om de REPL te starten. Gebruik CTRL+D om te " +"Druk op een willekeurige toets om de REPL te starten. Gebruik CTRL+D om te " "herstarten.\n" #: main.c @@ -1786,6 +1868,10 @@ msgstr "" msgid "Program too long" msgstr "" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull niet gebruikt wanneer de richting output is." @@ -1806,10 +1892,30 @@ msgstr "RNG DeInit Fout" msgid "RNG Init Error" msgstr "RNG Init Fout" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1841,7 +1947,7 @@ msgstr "" #: supervisor/shared/bluetooth/bluetooth.c msgid "Reconnecting" -msgstr "" +msgstr "Opnieuw aansluiten" #: shared-bindings/epaperdisplay/EPaperDisplay.c msgid "Refresh too soon" @@ -1937,11 +2043,13 @@ msgstr "Slice en waarde hebben verschillende lengtes." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Slices niet ondersteund" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool kan alleen met wifi.radio gebruikt worden" @@ -1981,21 +2089,9 @@ msgstr "" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "De lengte van rgb_pins moet 6, 12, 18, 24 of 30 zijn" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "De sample's bits_per_sample komen niet overeen met die van de mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "De sample's kanaal aantal komt niet overeen met die van de mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "De sample's sample rate komt niet overeen met die van de mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "De sample's signature komt niet overeen met die van de mixer" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2015,7 +2111,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "Tile hoogte moet exact de bitmap hoogte verdelen" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Tile index buiten bereik" @@ -2023,6 +2121,10 @@ msgstr "Tile index buiten bereik" msgid "Tile width must exactly divide bitmap width" msgstr "Tile breedte moet exact de bitmap breedte verdelen" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "Tijdstip ligt in het verleden." @@ -2090,7 +2192,7 @@ msgstr "" #: main.c msgid "UID:" -msgstr "" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2153,6 +2255,10 @@ msgstr "Niet in staat om de parser te initialiseren" msgid "Unable to read color palette data" msgstr "Niet in staat kleurenpalet data te lezen" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2247,15 +2353,12 @@ msgstr "" msgid "Unsupported display bus type" msgstr "Niet-ondersteund beeldscherm bus type" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Niet-ondersteunde format" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "" @@ -2306,11 +2409,13 @@ msgstr "" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " -msgstr "" +msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "WiFi is niet ingeschakeld" #: main.c msgid "Woken up by alarm.\n" @@ -2332,6 +2437,7 @@ msgstr "" #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "" @@ -2345,6 +2451,7 @@ msgstr "" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "" @@ -2405,6 +2512,10 @@ msgstr "een bytes-achtig object is vereist" msgid "addresses is empty" msgstr "adressen zijn leeg" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "" + #: py/compile.c msgid "annotation must be an identifier" msgstr "" @@ -2483,6 +2594,10 @@ msgstr "poging om argmin/argmax van een lege sequentie te krijgen" msgid "attributes not supported" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "as is buiten bereik" @@ -2519,6 +2634,10 @@ msgstr "verkeerde typecode" msgid "binary op %q not implemented" msgstr "binaire op %q niet geïmplementeerd" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "" + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "" @@ -2531,6 +2650,15 @@ msgstr "" msgid "bits must be 32 or less" msgstr "" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample moet 8 of 16 zijn" @@ -2613,7 +2741,7 @@ msgstr "kan niet toewijzen aan expressie" msgid "can't cancel self" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "kan %q niet naar %q converteren" @@ -3074,7 +3202,7 @@ msgid "format" msgstr "" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "format vereist een dict" #: py/objdeque.c @@ -3199,7 +3327,7 @@ msgstr "" #: ports/espressif/common-hal/pulseio/PulseIn.c #: shared-bindings/bitmaptools/__init__.c msgid "index out of range" -msgstr "index is buiten bereik" +msgstr "index buiten bereik" #: py/obj.c msgid "indices must be integers" @@ -3209,10 +3337,6 @@ msgstr "indices moeten integers zijn" msgid "indices must be integers, slices, or Boolean lists" msgstr "indices moeten integers, segmenten (slices) of Boolean lijsten zijn" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "oorspronkelijke waarden moeten itereerbaar zijn" @@ -3409,10 +3533,6 @@ msgstr "label '%q' is niet gedefinieerd" msgid "label redefined" msgstr "label opnieuw gedefinieerd" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "level moet tussen 0 en 1 liggen" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs en rhs moeten compatibel zijn" @@ -3544,7 +3664,7 @@ msgid "must use keyword argument for key function" msgstr "voor sleutelfunctie moet een trefwoordargument gebruikt worden" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "naam '%q' is niet gedefinieerd" #: py/runtime.c @@ -3962,6 +4082,10 @@ msgstr "roll argument moet een ndarray zijn" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4181,11 +4305,11 @@ msgid "tx and rx cannot both be None" msgstr "tx en rx kunnen niet beiden None zijn" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "type '%q' is geen aanvaardbaar basistype" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "type is geen aanvaardbaar basistype" #: py/runtime.c @@ -4247,7 +4371,9 @@ msgstr "" msgid "unreadable attribute" msgstr "onleesbaar attribuut" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "niet ondersteund %q type" @@ -4325,14 +4451,9 @@ msgstr "" msgid "width must be greater than zero" msgstr "breedte moet groter dan nul zijn" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" -msgstr "" +msgstr "wifi.monitor niet beschikbaar" #: shared-bindings/_bleio/Adapter.c msgid "window must be <= interval" @@ -4392,6 +4513,35 @@ msgstr "zi moet van type float zijn" msgid "zi must be of shape (n_section, 2)" msgstr "zi moet vorm (n_section, 2) hebben" +#~ msgid "Unsupported format" +#~ msgstr "Niet-ondersteunde format" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Data chunk moet gevolgd worden door fmt chunk" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Alleen monochrome en 4bpp of 8bpp, en 16bpp of grotere geïndiceerde BMP's " +#~ "zijn ondersteund: %d bpp is gegeven" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "level moet tussen 0 en 1 liggen" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "De sample's bits_per_sample komen niet overeen met die van de mixer" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "De sample's kanaal aantal komt niet overeen met die van de mixer" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "De sample's sample rate komt niet overeen met die van de mixer" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "De sample's signature komt niet overeen met die van de mixer" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Buffer lengte moet een veelvoud van 512 zijn" @@ -4591,13 +4741,13 @@ msgstr "zi moet vorm (n_section, 2) hebben" #~ msgid "'%s' object does not support item deletion" #~ msgstr "'%s' object ondersteunt item verwijdering niet" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "'%s' object is geen iterator" #~ msgid "'%s' object is not callable" #~ msgstr "'%s' object is niet aanroepbaar" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "'%s' object is niet itereerbaar" #~ msgid "'%s' object is not subscriptable" @@ -4615,7 +4765,7 @@ msgstr "zi moet vorm (n_section, 2) hebben" #~ msgid "'continue' outside loop" #~ msgstr "'continue' buiten de loop" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "'coroutine' object is geen iterator" #~ msgid "ADC2 is being used by WiFi" @@ -5392,7 +5542,7 @@ msgstr "zi moet vorm (n_section, 2) hebben" #~ msgid "firstbit must be MSB" #~ msgstr "het eerste bit moet het MSB zijn" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "functie accepteert geen keyword argumenten" #~ msgid "function is implemented for scalars and ndarrays only" @@ -5470,7 +5620,7 @@ msgstr "zi moet vorm (n_section, 2) hebben" #~ msgid "n must be between 0, and 9" #~ msgstr "n moet tussen 0 en 9 liggen" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "naam hergebruikt voor argument" #~ msgid "no available NIC" diff --git a/locale/pl.po b/locale/pl.po index f1428354151..2e55f983e00 100644 --- a/locale/pl.po +++ b/locale/pl.po @@ -7,16 +7,16 @@ msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2023-11-16 15:03+0000\n" -"Last-Translator: Szymon Jakubiak \n" +"PO-Revision-Date: 2025-08-06 18:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: pl\n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " -"|| n%100>=20) ? 1 : 2;\n" -"X-Generator: Weblate 5.2\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" @@ -31,6 +31,8 @@ msgid "" "\n" "Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"Wykonywanie zatrzymane przez auto-reload. Wkrótce nastąpi przeładowanie.\n" #: supervisor/shared/safe_mode.c msgid "" @@ -38,6 +40,9 @@ msgid "" "Please file an issue with your program at github.com/adafruit/circuitpython/" "issues." msgstr "" +"\n" +"Proszę dodaj problem z twoim programem na github.com/adafruit/circuitpython/" +"issues." #: supervisor/shared/safe_mode.c msgid "" @@ -85,22 +90,24 @@ msgstr "%%c wymaga int lub char" msgid "" "%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +"%d pinów adresowalnych, %d pinów rgb oraz %d płytek wskazują na wysokość %d, " +"nie %d" #: shared-bindings/microcontroller/Pin.c msgid "%q and %q contain duplicate pins" msgstr "%q oraz %q zawierają zduplikowane piny" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q and %q muszą być różne" #: ports/atmel-samd/common-hal/audiobusio/I2SOut.c msgid "%q and %q must share a clock unit" -msgstr "" +msgstr "%q i %q muszą współdzielić jednostkę zegara" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "%q cannot be changed once mode is set to %q" -msgstr "" +msgstr "%q nie może zostać zmienione po ustawieniu trybu %q" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -110,7 +117,11 @@ msgstr "%q zawiera zduplikowane piny" msgid "%q failure: %d" msgstr "%q niepowodzenie: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q w %q musi być typu %q lub %q, nie %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q w %q musi być typu %q, a nie %q" @@ -156,19 +167,19 @@ msgstr "długość %q musi być w zakresie od %d do %d" #: py/argcheck.c msgid "%q length must be <= %d" -msgstr "" +msgstr "długość %q musi być <= %d" #: py/argcheck.c msgid "%q length must be >= %d" -msgstr "" +msgstr "długość %q musi być >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "" #: py/argcheck.c msgid "%q must be %d" -msgstr "" +msgstr "%q musi być %d" #: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/displayio/Bitmap.c @@ -176,16 +187,16 @@ msgstr "" #: shared-bindings/is31fl3741/FrameBuffer.c #: shared-bindings/rgbmatrix/RGBMatrix.c msgid "%q must be %d-%d" -msgstr "" +msgstr "%q musi być %d-%d" #: shared-bindings/busdisplay/BusDisplay.c msgid "%q must be 1 when %q is True" -msgstr "" +msgstr "%q musi wynosić 1, gdy %q jest True" #: py/argcheck.c shared-bindings/gifio/GifWriter.c #: shared-module/gifio/OnDiskGif.c msgid "%q must be <= %d" -msgstr "" +msgstr "%q musi być <= %d" #: ports/espressif/common-hal/watchdog/WatchDogTimer.c msgid "%q must be <= %u" @@ -193,7 +204,7 @@ msgstr "" #: py/argcheck.c msgid "%q must be >= %d" -msgstr "" +msgstr "%q musi być >= %d" #: shared-bindings/analogbufio/BufferedIn.c msgid "%q must be a bytearray or array of type 'H' or 'B'" @@ -222,6 +233,7 @@ msgstr "" #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "" @@ -231,6 +243,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q musi być typu %q, a nie %q" @@ -276,7 +289,8 @@ msgstr "" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q oraz %q muszą być tej samej długośći" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -310,7 +324,7 @@ msgid "'%q' object does not support '%q'" msgstr "Obiekt '%q' nie wspiera '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "Obiekt '%q' nie jest iteratorem" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -318,7 +332,7 @@ msgid "'%q' object is not callable" msgstr "Obiekt '%q' nie jest wywoływalny" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "Obiekt '%q' nie jest iterowalny" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -545,7 +559,6 @@ msgstr "Wszystkie timery tej nóżki w użyciu" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Wszystkie timery w użyciu" @@ -558,6 +571,10 @@ msgstr "" msgid "Already have all-matches listener" msgstr "" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Już trwa" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -567,6 +584,7 @@ msgstr "Już uruchomiony" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "" @@ -593,6 +611,10 @@ msgstr "Tablica musi zawierać pół-słowa (typ 'H')" msgid "Array values should be single bytes." msgstr "Wartości powinny być bajtami." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -602,6 +624,11 @@ msgstr "Próba przydzielenia %d bloków" msgid "Audio conversion not implemented" msgstr "Konwersja audio nie została zaimplementowana" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "" @@ -737,6 +764,10 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -784,7 +815,7 @@ msgid "Cannot record to a file" msgstr "Nie można nagrać do pliku" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." +msgid "Cannot remount path when visible via USB." msgstr "" #: shared-bindings/digitalio/DigitalInOut.c @@ -800,6 +831,10 @@ msgstr "Nie można określić RTS ani CTS w trybie RS485" msgid "Cannot subclass slice" msgstr "Nie można dziedziczyć ze slice" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "" @@ -836,6 +871,10 @@ msgstr "" msgid "Coordinate arrays types have different sizes" msgstr "" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "Nie można ustawić adresu" @@ -848,6 +887,11 @@ msgstr "Nie można rozpocząć przerwania, RX jest zajęty" msgid "Couldn't allocate decoder" msgstr "Nie udało się przydzielić dekodera" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Błąd inicjalizacji kanału DAC" @@ -865,10 +909,6 @@ msgstr "DAC w użyciu" msgid "Data 0 pin must be byte aligned" msgstr "Nóżka data 0 musi być wyrównana do bajtu" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Fragment danych musi następować po fragmencie fmt" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "" @@ -1001,15 +1041,47 @@ msgstr "Nie udało się połączyć: błąd wewnętrzny" msgid "Failed to connect: timeout" msgstr "Nie udało się połączyć: upłynął limit czasu" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Nie można przeanalizować pliku MP3" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Nie udało się zwolnić blokady, błąd 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Nie udało się zapisać wewnętrznej pamięci flash." @@ -1018,12 +1090,14 @@ msgstr "Nie udało się zapisać wewnętrznej pamięci flash." msgid "File exists" msgstr "Plik istnieje" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "Plik nie znaleziony" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "" @@ -1052,7 +1126,7 @@ msgstr "" "W bitmapie wejściowej dla przestrzeni kolorów RGB piksel musi składać się z " "16 bitów" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "Nie wspierany format" @@ -1162,6 +1236,7 @@ msgid "Insufficient stream input buffer" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "" @@ -1217,7 +1292,9 @@ msgstr "" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "Nieprawidłowe %q" @@ -1250,6 +1327,10 @@ msgstr "" msgid "Invalid MAC address" msgstr "" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Zły argument" @@ -1281,6 +1362,7 @@ msgid "Invalid hex password" msgstr "" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "" @@ -1293,6 +1375,7 @@ msgid "Invalid socket for TLS" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "Nieprawidłowy stan" @@ -1337,6 +1420,11 @@ msgstr "" msgid "MITM security not supported" msgstr "" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "" @@ -1382,7 +1470,8 @@ msgstr "" msgid "Mount point directory missing" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Musi być podklasą %q." @@ -1522,6 +1611,10 @@ msgstr "" msgid "No pulldown on pin; 1Mohm recommended" msgstr "Brak rozwijanego menu na pinezce; 1Mohm zalecane" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "" + #: py/moderrno.c msgid "No space left on device" msgstr "Brak miejsca" @@ -1621,15 +1714,6 @@ msgstr "" msgid "Only int or string supported for ip" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Obsługiwane są tylko monochromatyczne, indeksowane 4 bpp lub 8 bpp oraz 16 " -"bpp lub więcej BMP: podano %d bpp" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "" @@ -1680,6 +1764,7 @@ msgstr "Brak pamięci" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "" @@ -1689,7 +1774,7 @@ msgstr "" #: ports/stm/common-hal/pwmio/PWMOut.c msgid "PWM restart" -msgstr "" +msgstr "Ponowne uruchomienie PWM" #: ports/raspberrypi/common-hal/countio/Counter.c msgid "PWM slice already in use" @@ -1699,9 +1784,13 @@ msgstr "" msgid "PWM slice channel A already in use" msgstr "" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" -msgstr "" +msgstr "Błąd parametru" #: ports/espressif/common-hal/audiobusio/__init__.c msgid "Peripheral in use" @@ -1798,6 +1887,10 @@ msgstr "" #: ports/espressif/common-hal/espulp/ULP.c msgid "Program too long" +msgstr "Program zbyt długi" + +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" msgstr "" #: shared-bindings/digitalio/DigitalInOut.c @@ -1820,10 +1913,30 @@ msgstr "Błąd RNG DeInit" msgid "RNG Init Error" msgstr "Błąd inicjalizacji RNG" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" -msgstr "" +msgstr "RS485" #: ports/espressif/common-hal/busio/UART.c #: ports/mimxrt10xx/common-hal/busio/UART.c @@ -1855,7 +1968,7 @@ msgstr "Otrzymana odpowiedź była nieprawidłowa" #: supervisor/shared/bluetooth/bluetooth.c msgid "Reconnecting" -msgstr "" +msgstr "Ponowne połączenie" #: shared-bindings/epaperdisplay/EPaperDisplay.c msgid "Refresh too soon" @@ -1940,7 +2053,7 @@ msgstr "" #: ports/cxd56/common-hal/camera/Camera.c msgid "Size not supported" -msgstr "" +msgstr "Rozmiar nieobsługiwany" #: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c #: shared-bindings/nvm/ByteArray.c @@ -1951,11 +2064,13 @@ msgstr "Fragment i wartość są różnych długości." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Fragmenty nieobsługiwane" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "" @@ -1995,21 +2110,9 @@ msgstr "" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Wartość bits_per_sample nie pasuje do miksera" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Liczba kanałów nie pasuje do miksera" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "Sample rate nie pasuje do miksera" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "Znak nie pasuje do miksera" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2029,7 +2132,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "Wysokość bitmapy musi być wielokrotnością wysokości kafelka" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "" @@ -2037,6 +2142,10 @@ msgstr "" msgid "Tile width must exactly divide bitmap width" msgstr "Szerokość bitmapy musi być wielokrotnością szerokości kafelka" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "" @@ -2075,7 +2184,7 @@ msgstr "" #: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c #: ports/stm/common-hal/alarm/touch/TouchAlarm.c msgid "Touch alarms not available" -msgstr "" +msgstr "Alarmy dotykowe niedostępne" #: py/obj.c msgid "Traceback (most recent call last):\n" @@ -2104,7 +2213,7 @@ msgstr "" #: main.c msgid "UID:" -msgstr "" +msgstr "UID:" #: shared-module/usb_hid/Device.c msgid "USB busy" @@ -2120,7 +2229,7 @@ msgstr "" #: shared-module/usb_hid/Device.c msgid "USB error" -msgstr "" +msgstr "Błąd USB" #: shared-bindings/_bleio/UUID.c msgid "UUID integer value must be 0-0xffff" @@ -2167,6 +2276,10 @@ msgstr "Błąd ustawienia parsera" msgid "Unable to read color palette data" msgstr "Nie można odczytać danych palety" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2182,7 +2295,7 @@ msgstr "" #: shared-bindings/alarm/SleepMemory.c msgid "Unable to write to sleep_memory." -msgstr "" +msgstr "Nie można zapisać do sleep_memory." #: ports/nordic/common-hal/_bleio/UUID.c msgid "Unexpected nrfx uuid type" @@ -2261,22 +2374,19 @@ msgstr "" msgid "Unsupported display bus type" msgstr "Zły typ magistrali wyświetlaczy" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Zły format" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update failed" -msgstr "" +msgstr "Aktualizacja nie powiodła się" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c @@ -2315,14 +2425,21 @@ msgid "" "\n" "To list built-in modules type `help(\"modules\")`.\n" msgstr "" +"Witamy w Adafruit CircuitPython %s!\n" +"\n" +"Odwiedź circuitpython.org po więcej informacji.\n" +"\n" +"Aby wyświetlić listę wbudowanych modułów wpisz `help(„modules”)`.\n" #: supervisor/shared/web_workflow/web_workflow.c msgid "Wi-Fi: " -msgstr "" +msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "WiFi nie jest włączone" #: main.c msgid "Woken up by alarm.\n" @@ -2344,6 +2461,7 @@ msgstr "" #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "" @@ -2357,6 +2475,7 @@ msgstr "" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "" @@ -2417,6 +2536,10 @@ msgstr "wymagany obiekt typu bytes" msgid "addresses is empty" msgstr "adres jest pusty" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "" + #: py/compile.c msgid "annotation must be an identifier" msgstr "" @@ -2495,6 +2618,10 @@ msgstr "próba uzyskania argmin / argmax pustej sekwencji" msgid "attributes not supported" msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "" @@ -2531,6 +2658,10 @@ msgstr "zły typecode" msgid "binary op %q not implemented" msgstr "brak dwu-argumentowego operatora %q" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth musi wynosić 8, 16, 24 lub 32." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "" @@ -2541,8 +2672,17 @@ msgstr "" #: extmod/modrandom.c msgid "bits must be 32 or less" -msgstr "" +msgstr "bitów musi wynosić 32 lub mniej" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample musi wynosić 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample musi być 8 lub 16" @@ -2624,7 +2764,7 @@ msgstr "przypisanie do wyrażenia" msgid "can't cancel self" msgstr "" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "nie można dokonać konwersji %q na %q" @@ -2747,7 +2887,7 @@ msgstr "" #: extmod/modasyncio.c msgid "can't wait" -msgstr "" +msgstr "nie mogę się doczekać" #: extmod/ulab/code/ndarray.c msgid "cannot assign new shape" @@ -2934,7 +3074,7 @@ msgstr "" #: extmod/ulab/code/numpy/create.c msgid "divide by zero" -msgstr "" +msgstr "dziel przez zero" #: py/runtime.c msgid "division by zero" @@ -2954,7 +3094,7 @@ msgstr "puste" #: extmod/ulab/code/numpy/io/io.c msgid "empty file" -msgstr "" +msgstr "puste plik" #: extmod/modasyncio.c extmod/modheapq.c msgid "empty heap" @@ -3073,7 +3213,7 @@ msgstr "float zbyt wielki" #: py/nativeglue.c msgid "float unsupported" -msgstr "" +msgstr "float nieobsługiwany" #: shared-bindings/_stage/Text.c msgid "font must be 2048 bytes long" @@ -3081,10 +3221,10 @@ msgstr "font musi mieć 2048 bajtów długości" #: extmod/moddeflate.c msgid "format" -msgstr "" +msgstr "format" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "format wymaga słownika" #: py/objdeque.c @@ -3182,7 +3322,7 @@ msgstr "" #: py/persistentcode.c msgid "incompatible .mpy file" -msgstr "" +msgstr "niekompatybilny plik .mpy" #: py/objstr.c msgid "incomplete format" @@ -3219,10 +3359,6 @@ msgid "indices must be integers, slices, or Boolean lists" msgstr "" "indeksy muszą być liczbami całkowitymi, wycinkami lub listami boolowskimi" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "wartości początkowe muszą być iterowalne" @@ -3417,10 +3553,6 @@ msgstr "etykieta '%q' niezdefiniowana" msgid "label redefined" msgstr "etykieta przedefiniowana" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "poziom musi wynosić od 0 do 1" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lewa i prawa strona powinny być kompatybilne" @@ -3552,7 +3684,7 @@ msgid "must use keyword argument for key function" msgstr "funkcja key musi być podana jako argument nazwany" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "nazwa '%q' niezdefiniowana" #: py/runtime.c @@ -3602,7 +3734,7 @@ msgstr "" #: shared-module/sdcardio/SDCard.c msgid "no SD card" -msgstr "" +msgstr "brak karty SD" #: py/vm.c msgid "no active exception to reraise" @@ -3683,7 +3815,7 @@ msgstr "liczba punktów musi wynosić co najmniej 2" #: py/builtinhelp.c msgid "object " -msgstr "" +msgstr "obiekt " #: py/obj.c #, c-format @@ -3737,7 +3869,7 @@ msgstr "łańcuch o nieparzystej długości" #: supervisor/shared/web_workflow/web_workflow.c msgid "off" -msgstr "" +msgstr "wył" #: extmod/ulab/code/utils/utils.c msgid "offset is too large" @@ -3970,6 +4102,10 @@ msgstr "" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4189,11 +4325,11 @@ msgid "tx and rx cannot both be None" msgstr "tx i rx nie mogą być oba None" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "typ '%q' nie może być bazowy" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "typ nie może być bazowy" #: py/runtime.c @@ -4255,7 +4391,9 @@ msgstr "" msgid "unreadable attribute" msgstr "nieczytelny atrybut" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "zły typ %q" @@ -4333,11 +4471,6 @@ msgstr "" msgid "width must be greater than zero" msgstr "szerokość musi być większa niż zero" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "" @@ -4400,6 +4533,35 @@ msgstr "" msgid "zi must be of shape (n_section, 2)" msgstr "" +#~ msgid "Unsupported format" +#~ msgstr "Zły format" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Fragment danych musi następować po fragmencie fmt" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Obsługiwane są tylko monochromatyczne, indeksowane 4 bpp lub 8 bpp oraz " +#~ "16 bpp lub więcej BMP: podano %d bpp" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "poziom musi wynosić od 0 do 1" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "Wartość bits_per_sample nie pasuje do miksera" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "Liczba kanałów nie pasuje do miksera" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "Sample rate nie pasuje do miksera" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "Znak nie pasuje do miksera" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Długość bufora musi być wielokrotnością 512" @@ -4571,13 +4733,13 @@ msgstr "" #~ msgid "'%s' object does not support item deletion" #~ msgstr "'%s' obiekt nie wspiera usuwania elementów" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "'%s' obiekt nie jest iteratorem" #~ msgid "'%s' object is not callable" #~ msgstr "'%s' nie można wywoływać obiektu" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "'%s' nie można iterować po obiekcie" #~ msgid "'%s' object is not subscriptable" @@ -5341,7 +5503,7 @@ msgstr "" #~ msgid "firstbit must be MSB" #~ msgstr "firstbit musi być MSB" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "funkcja nie bierze argumentów nazwanych" #~ msgid "int() arg 2 must be >= 2 and <= 36" @@ -5389,7 +5551,7 @@ msgstr "" #~ msgid "name must be a string" #~ msgstr "nazwa musi być łańcuchem" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "nazwa użyta ponownie jako argument" #~ msgid "no available NIC" diff --git a/locale/pt_BR.po b/locale/pt_BR.po index a99a50c89a4..5bb98dc74c5 100644 --- a/locale/pt_BR.po +++ b/locale/pt_BR.po @@ -6,15 +6,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2024-09-23 03:16+0000\n" -"Last-Translator: Wellington Terumi Uemura \n" +"PO-Revision-Date: 2025-06-09 12:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.8-dev\n" +"X-Generator: Weblate 5.12-dev\n" #: main.c msgid "" @@ -95,7 +95,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "%q e %q contêm pinos duplicados" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q e %q devem ser diferentes" @@ -115,7 +115,11 @@ msgstr "%q contém pinos duplicados" msgid "%q failure: %d" msgstr "%q falha: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q em %q deve ser do tipo %q ou %q, não %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q em %q deve ser do tipo %q e não %q" @@ -167,7 +171,7 @@ msgstr "o comprimento de %q deve ser <= %d" msgid "%q length must be >= %d" msgstr "o comprimento de %q deve ser >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "%q foi movido de %q para %q" @@ -227,6 +231,7 @@ msgstr "%q deve ser um múltiplo de 8." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q deve ser do tipo %q ou %q e não %q" @@ -236,6 +241,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "%q deve ser do tipo %q, %q ou %q e não %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q deve ser do tipo %q e não %q" @@ -281,7 +287,8 @@ msgstr "%q() sem %q()" msgid "%q, %q, and %q must all be the same length" msgstr "todos os %q, %q, e %q devem ter mesmo comprimento" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -315,7 +322,7 @@ msgid "'%q' object does not support '%q'" msgstr "O objeto '%q' não suporta '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "O objeto '%q' não é um iterador" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -323,7 +330,7 @@ msgid "'%q' object is not callable" msgstr "O objeto '%s' não é invocável" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "O objeto '%q' não é iterável" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -552,7 +559,6 @@ msgstr "Todos os temporizadores para este pino estão em uso" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Todos os temporizadores em uso" @@ -565,6 +571,10 @@ msgstr "Já está anunciando." msgid "Already have all-matches listener" msgstr "Já há um ouvinte com todas as correspondências" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Já em andamento" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -574,6 +584,7 @@ msgstr "Já está em execução" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Já está em busca das redes de wifi" @@ -600,6 +611,12 @@ msgstr "Array deve conter meias palavras (tipo 'H')" msgid "Array values should be single bytes." msgstr "Os valores das matrizes devem ser bytes simples." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "" +"Transferência SPI assíncrona em andamento nesse barramento, continue " +"aguardando." + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -609,6 +626,11 @@ msgstr "Tentativa de alocar %d blocos" msgid "Audio conversion not implemented" msgstr "A conversão de áudio ainda não foi implementada" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Erro na fonte de áudio" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "O AuthMode.OPEN não é usado com senha" @@ -745,6 +767,11 @@ msgid "Can only alarm on two low pins from deep sleep." msgstr "" "O alarme só é possível nos dois pinos com sinal baixo a partir do deep sleep." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" +"Não é possível construir o AudioOut porque o canal contínuo já está aberto" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -792,8 +819,8 @@ msgid "Cannot record to a file" msgstr "Não é possível gravar em um arquivo" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "Não é possível montar '/' quando estiver visível pelo USB." +msgid "Cannot remount path when visible via USB." +msgstr "" #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -808,6 +835,10 @@ msgstr "Não é possível definir o RTS ou CTS no modo RS485" msgid "Cannot subclass slice" msgstr "Não é possível subclassificar a fatia" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "Não é possível usar GPIO0..15 junto com GPIO32..47" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "Não é possível acordar na borda do pino, nível apenas" @@ -843,6 +874,10 @@ msgstr "As coordenadas das matrizes possuem comprimentos diferentes" msgid "Coordinate arrays types have different sizes" msgstr "Os tipos das coordenadas das matrizes possuem tamanhos diferentes" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "Não foi possível definir o endereço" @@ -855,6 +890,11 @@ msgstr "Não foi possível iniciar a interrupção, RX ocupado" msgid "Couldn't allocate decoder" msgstr "Não foi possível alocar o decodificador" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Erro de Inicialização do Canal DAC" @@ -872,10 +912,6 @@ msgstr "DAC em uso" msgid "Data 0 pin must be byte aligned" msgstr "O pino de dados 0 deve ser alinhado por bytes" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Pedaço de dados deve seguir o pedaço de cortes" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "Erro no formato dos dados (os dados podem estar truncados)" @@ -1009,15 +1045,47 @@ msgstr "Falha ao conectar: erro interno" msgid "Failed to connect: timeout" msgstr "Falha ao conectar: tempo limite" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "Houve uma falha ao criar canais contínuos: arg inválido" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "Houve uma falha ao criar canais contínuos: estado inválido" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Houve uma falha ao criar canais contínuos: sem mem" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Houve uma falha ao criar canais contínuos: não encontrado" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Houve uma falha ao ativar o modo contínuo" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Falha ao analisar o arquivo MP3" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Houve uma falha ao registrar a chamada de retorno de eventos contínuos" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Houve uma falha ao liberar o mutex, err 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "Houve uma falha ao definir o nome do host" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Houve uma falha ao iniciar o áudio assíncrono" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Falha ao gravar o flash interno." @@ -1026,12 +1094,14 @@ msgstr "Falha ao gravar o flash interno." msgid "File exists" msgstr "Arquivo já existe" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "Arquivo não encontrado" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Os filtros são muito complexos" @@ -1057,7 +1127,7 @@ msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" "Para espaços de cor RGB, o bitmap da entrada deve ter 16 bits por pixel" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "O formato não é suportado" @@ -1173,6 +1243,7 @@ msgid "Insufficient stream input buffer" msgstr "O buffer do fluxo de entrada é insuficiente" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "A interface deve ser iniciada" @@ -1228,7 +1299,9 @@ msgstr "Interrompido pela função de saída" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "%q Inválido" @@ -1261,6 +1334,10 @@ msgstr "BSSID Inválido" msgid "Invalid MAC address" msgstr "Endereço MAC inválido" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Argumento inválido" @@ -1292,6 +1369,7 @@ msgid "Invalid hex password" msgstr "Senha hexadecimal inválida" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Endereço MAC multicast inválido" @@ -1304,6 +1382,7 @@ msgid "Invalid socket for TLS" msgstr "Soquete inválido para o TLS" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "Estado inválido" @@ -1349,6 +1428,11 @@ msgstr "O endereço MAC era inválido" msgid "MITM security not supported" msgstr "Não há suporte para segurança MITM" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "Erro de relógio MMC/SDIO %x" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "O mapeamento deve ser uma tupla" @@ -1394,7 +1478,8 @@ msgstr "Falta jmp_pin. %q[%u] jumper no pino" msgid "Mount point directory missing" msgstr "Falta o diretório do ponto de montagem" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Deve ser uma subclasse %q." @@ -1536,6 +1621,10 @@ msgstr "" msgid "No pulldown on pin; 1Mohm recommended" msgstr "Não há pulldown no pino; É recomendável utilizar um resistor de 1M ohm" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "" + #: py/moderrno.c msgid "No space left on device" msgstr "Não resta espaço no dispositivo" @@ -1639,15 +1728,6 @@ msgstr "Apenas a detecção de borda está disponível neste hardware" msgid "Only int or string supported for ip" msgstr "Apenas int ou string é suportado para ip" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"São compatíveis apenas os BMPs monocromáticos, indexados em 4bpp ou 8bpp e " -"16bpp ou superior: determinado %d bpp" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "Apenas um %q pode ser colocado em hibernação profunda." @@ -1698,6 +1778,7 @@ msgstr "Sem memória" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Sem soquetes" @@ -1717,6 +1798,12 @@ msgstr "A fatia do PWM já está em uso" msgid "PWM slice channel A already in use" msgstr "O canal A da fatia do PWM já está em uso" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" +"Os buffers de pacotes para uma transferência SPI devem ter o mesmo " +"comprimento." + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "Erro de parâmetro" @@ -1823,6 +1910,10 @@ msgstr "O tamanho do programa é inválido" msgid "Program too long" msgstr "Programa muito longo" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "O Pull não foi usado quando a direção for gerada." @@ -1843,6 +1934,26 @@ msgstr "Erro DeInit RNG" msgid "RNG Init Error" msgstr "Houve um erro na inicialização do RNG" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1974,11 +2085,13 @@ msgstr "Fatie e avalie os diferentes comprimentos." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Fatiamento não compatível" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "O SocketPool só pode ser usado com rádio wifi.radio" @@ -2019,21 +2132,9 @@ msgstr "A exceção acima foi a causa direta da seguinte exceção:" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "O comprimento dos rgb_pins devem ser 6, 12, 18, 24, ou 30" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "A amostragem bits_per_sample não coincide com a do mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "A contagem da amostragem dos canais não coincide com o a do mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "A taxa de amostragem da amostra não coincide com a do mixer" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "A amostragem \"signedness\" não coincide com a do mixer" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "Não há correspondência nas amostras %q" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2055,7 +2156,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "A altura do bloco deve dividir exatamente com a altura do bitmap" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "O índice do bloco está fora dos limites" @@ -2063,6 +2166,10 @@ msgstr "O índice do bloco está fora dos limites" msgid "Tile width must exactly divide bitmap width" msgstr "A largura do bloco deve dividir exatamente com a largura do bitmap" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "O tempo está no passado." @@ -2198,6 +2305,12 @@ msgstr "Não foi possível iniciar o analisador" msgid "Unable to read color palette data" msgstr "Não foi possível ler os dados da paleta de cores" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" +"Não é possível enviar uma mensagem CAN: todos os buffers de mensagens Tx " +"estão ocupados" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2292,15 +2405,12 @@ msgstr "Espaço de cor não compatível" msgid "Unsupported display bus type" msgstr "Não há suporte para o tipo do display bus" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Formato não suportado" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "Sem compatibilidade com o algoritmo de hash" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "Tipo de soquete não suportado" @@ -2358,9 +2468,11 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "O Wi-Fi não está ativado" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "O WiFi não está habilitado" #: main.c msgid "Woken up by alarm.\n" @@ -2382,6 +2494,7 @@ msgstr "Você pressionou os dois botões durante a inicialização." #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "Você pressionou o botão A na inicialização." @@ -2395,6 +2508,7 @@ msgstr "Você pressionou o botão BOOT na inicialização" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "Você pressionou o botão BOOT ao iniciar." @@ -2455,6 +2569,10 @@ msgstr "é necessário objetos tipo bytes" msgid "addresses is empty" msgstr "os endereços estão vazios" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "já está tocando" + #: py/compile.c msgid "annotation must be an identifier" msgstr "a anotação deve ser um identificador" @@ -2534,6 +2652,10 @@ msgstr "tente obter argmin/argmax de uma sequência vazia" msgid "attributes not supported" msgstr "atributos não compatíveis" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "formato de áudio não compatível" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "o eixo está fora dos limites" @@ -2570,6 +2692,10 @@ msgstr "typecode incorreto" msgid "binary op %q not implemented" msgstr "a operação binário %q não foi implementada" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "o bit_depth deve ser 8, 16, 24 ou 32." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "o tamanho e a profundidade do bitmap devem corresponder" @@ -2582,6 +2708,15 @@ msgstr "os tamanhos do bitmap devem coincidir" msgid "bits must be 32 or less" msgstr "bits deve ser 32 ou menos" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample deve ser 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample deve ser 8 ou 16" @@ -2663,7 +2798,7 @@ msgstr "a expressão não pode ser atribuída" msgid "can't cancel self" msgstr "não é possível cancelar a si mesmo" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "não é possível converter %q para %q" @@ -3131,7 +3266,7 @@ msgid "format" msgstr "formato" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "formato requer um dict" #: py/objdeque.c @@ -3265,10 +3400,6 @@ msgstr "os índices devem ser inteiros" msgid "indices must be integers, slices, or Boolean lists" msgstr "os índices devem ser números inteiros, fatias ou listas booleanas" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "inicialização do I2C" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "os valores iniciais devem ser iteráveis" @@ -3467,10 +3598,6 @@ msgstr "o rótulo '%q' não foi definido" msgid "label redefined" msgstr "o rótulo foi redefinido" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "o nível deve estar entre 0 e 1" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "o lhs e rhs devem ser compatíveis" @@ -3604,7 +3731,7 @@ msgid "must use keyword argument for key function" msgstr "deve usar o argumento da palavra-chave para a função da chave" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "o nome '%q' não está definido" #: py/runtime.c @@ -4027,6 +4154,10 @@ msgstr "argumento de enrolar deve ser um ndarray" msgid "rsplit(None,n)" msgstr "rsplit(Nenhum,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed deve ser verdadeiro" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4046,7 +4177,8 @@ msgstr "conjunto não suportado" #: extmod/ulab/code/numpy/random/random.c msgid "shape must be None, and integer or a tuple of integers" -msgstr "shape deve ser None, um número inteiro ou uma tupla de números inteiros" +msgstr "" +"shape deve ser None, um número inteiro ou uma tupla de números inteiros" #: extmod/ulab/code/ndarray.c msgid "shape must be integer or tuple of integers" @@ -4246,11 +4378,11 @@ msgid "tx and rx cannot both be None" msgstr "TX e RX não podem ser ambos" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "o tipo '%q' não é um tipo base aceitável" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "tipo não é um tipo base aceitável" #: py/runtime.c @@ -4312,7 +4444,9 @@ msgstr "'%c' sem correspondência no formato" msgid "unreadable attribute" msgstr "atributo ilegível" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "tipo %q não suportado" @@ -4392,11 +4526,6 @@ msgstr "os pesos devem ser um objeto do tipo %q, %q, %q ou %q, e não %q " msgid "width must be greater than zero" msgstr "a largura deve ser maior que zero" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "o wifi não está ativo" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "O wifi.Monitor não está disponível" @@ -4459,6 +4588,50 @@ msgstr "zi deve ser de um tipo float" msgid "zi must be of shape (n_section, 2)" msgstr "zi deve estar na forma (n_section, 2)" +#~ msgid "Unsupported format" +#~ msgstr "Formato não suportado" + +#~ msgid "Wifi is not enabled" +#~ msgstr "O Wi-Fi não está ativado" + +#~ msgid "wifi is not enabled" +#~ msgstr "o wifi não está ativo" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "Não é possível montar '/' quando estiver visível pelo USB." + +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q deve ser um objeto %q, %q ou %q" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Pedaço de dados deve seguir o pedaço de cortes" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "São compatíveis apenas os BMPs monocromáticos, indexados em 4bpp ou 8bpp " +#~ "e 16bpp ou superior: determinado %d bpp" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "o nível deve estar entre 0 e 1" + +#~ msgid "init I2C" +#~ msgstr "inicialização do I2C" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "A amostragem bits_per_sample não coincide com a do mixer" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "A contagem da amostragem dos canais não coincide com o a do mixer" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "A taxa de amostragem da amostra não coincide com a do mixer" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "A amostragem \"signedness\" não coincide com a do mixer" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "O comprimento do Buffer deve ser um múltiplo de 512" @@ -4804,13 +4977,13 @@ msgstr "zi deve estar na forma (n_section, 2)" #~ msgid "'%s' object does not support item deletion" #~ msgstr "O objeto '%s' não é compatível com exclusão do item" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "O objeto '%s' não é um iterador" #~ msgid "'%s' object is not callable" #~ msgstr "O objeto '%s' não é invocável" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "O objeto '%s' não é iterável" #~ msgid "'%s' object is not subscriptable" @@ -4830,7 +5003,7 @@ msgstr "zi deve estar na forma (n_section, 2)" #~ msgid "'continue' outside loop" #~ msgstr "'continue' fora do loop" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "O objeto 'corrotina' não é um iterador" #~ msgid "(x,y) integers required" @@ -6187,7 +6360,7 @@ msgstr "zi deve estar na forma (n_section, 2)" #~ msgid "frequency is read-only for this board" #~ msgstr "nesta placa, a frequência é de apenas leitura" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "função não aceita argumentos de palavras-chave" #~ msgid "function is implemented for scalars and ndarrays only" @@ -6316,7 +6489,7 @@ msgstr "zi deve estar na forma (n_section, 2)" #~ msgid "name must be a string" #~ msgstr "heap deve ser uma lista" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "o nome foi reutilizado para o argumento" #~ msgid "no available NIC" diff --git a/locale/ru.po b/locale/ru.po index c2077dfa858..9dac60be0b9 100644 --- a/locale/ru.po +++ b/locale/ru.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-07-29 17:55+0000\n" -"Last-Translator: gfbdrgng \n" +"PO-Revision-Date: 2025-06-30 16:01+0000\n" +"Last-Translator: MAE \n" "Language-Team: none\n" "Language: ru\n" "MIME-Version: 1.0\n" @@ -16,532 +16,829 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -"X-Generator: Weblate 5.7-dev\n" +"X-Generator: Weblate 5.13-dev\n" -#: main.c -msgid "" -"\n" -"Code done running.\n" -msgstr "" -"\n" -"Программа закончила выполнение.\n" +#: extmod/modasyncio.c extmod/modheapq.c +msgid "empty heap" +msgstr "пустая куча" -#: main.c -msgid "" -"\n" -"Code stopped by auto-reload. Reloading soon.\n" -msgstr "" -"\n" -"Программа остановлена автоматической перезагрузкой. Скоро перезагрузка.\n" +#: extmod/modasyncio.c +msgid "can't cancel self" +msgstr "Не могу отменить себя" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Please file an issue with your program at github.com/adafruit/circuitpython/" -"issues." -msgstr "" -"\n" -"Пожалуйста подайте вопрос с вашей программой на github.com/adafruit/" -"circuitpython/issues." +#: extmod/modasyncio.c +msgid "can't wait" +msgstr "не может ждать" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Press reset to exit safe mode.\n" +#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c +msgid "a bytes-like object is required" +msgstr "Требуется байтоподобный объект" + +#: extmod/modbinascii.c +msgid "incorrect padding" +msgstr "Неправильная набивка" + +#: extmod/moddeflate.c +msgid "format" +msgstr "формат" + +#: extmod/moddeflate.c +msgid "wbits" msgstr "" -"\n" -"Нажмите на сброс чтобы выйти из безопасного режима.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"You are in safe mode because:\n" +#: extmod/modhashlib.c +msgid "hash is final" +msgstr "хэш является окончательным" + +#: extmod/modheapq.c +msgid "heap must be a list" +msgstr "куча должна быть списком" + +#: extmod/modjson.c +msgid "syntax error in JSON" +msgstr "синтаксис ошибка в JSON" + +#: extmod/modrandom.c +msgid "bits must be 32 or less" +msgstr "биты должны быть 32 или менее" + +#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c +msgid "no default seed" +msgstr "Нет начального числа по умолчанию" + +#: extmod/modre.c +msgid "splitting with sub-captures" +msgstr "разделение с помощью подзахватов" + +#: extmod/modre.c +msgid "regex too complex" msgstr "" -"\n" -"Вы в безопасном режиме потому что:\n" -#: py/obj.c -msgid " File \"%q\"" -msgstr " Файл \"%q\"" +#: extmod/modre.c +msgid "Error in regex" +msgstr "Ошибка в регулярном выражении" -#: py/obj.c -msgid " File \"%q\", line %d" -msgstr " Файл \"%q\", строка %d" +#: extmod/modtime.c +msgid "mktime needs a tuple of length 8 or 9" +msgstr "mktime нужен кортеж длины 8 или 9" -#: py/builtinhelp.c -msgid " is of type %q\n" -msgstr " имеет тип %q\n" +#: extmod/modtime.c +msgid "ticks interval overflow" +msgstr "переполнение интервала тиков" -#: main.c -msgid " not found.\n" -msgstr " не найден.\n" +#: extmod/modzlib.c +msgid "compression header" +msgstr "Заголовок сжатия" -#: main.c -msgid " output:\n" -msgstr " вывод:\n" +#: extmod/ulab/code/ndarray.c +msgid "data type not understood" +msgstr "Тип данных не понят" -#: py/objstr.c -#, c-format -msgid "%%c requires int or char" -msgstr "%%c требует int или char" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "массив слишком велик" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +#: extmod/ulab/code/ndarray.c +msgid "ndarray length overflows" +msgstr "Переполнение длины массива ndarray" + +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex type" +msgstr "Не удается преобразовать сложный тип" + +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c +msgid "too many dimensions" +msgstr "Слишком много измерений" + +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c +msgid "index is out of bounds" +msgstr "индекс выходит из границ" + +#: extmod/ulab/code/ndarray.c +msgid "indices must be integers, slices, or Boolean lists" +msgstr "индексы должны быть целыми числами, срезами или логическими списками" + +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c +msgid "operands could not be broadcast together" +msgstr "Операнды не могут транслироваться вместе" + +#: extmod/ulab/code/ndarray.c +msgid "array and index length must be equal" +msgstr "Длина массива и индекса должна быть равна" + +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex to dtype" +msgstr "не может превратить комплекс в dtype" + +#: extmod/ulab/code/ndarray.c +msgid "operation is implemented for 1D Boolean arrays only" +msgstr "операция реализована только для 1D логических массивов" + +#: extmod/ulab/code/ndarray.c +msgid "too many indices" +msgstr "Слишком много индексов" + +#: extmod/ulab/code/ndarray.c +msgid "cannot delete array elements" +msgstr "Не удается удалить элементы массива" + +#: extmod/ulab/code/ndarray.c +msgid "flattening order must be either 'C', or 'F'" +msgstr "порядок сглаживания должен быть либо 'C', либо 'F'" + +#: extmod/ulab/code/ndarray.c +msgid "tobytes can be invoked for dense arrays only" +msgstr "Тобайты могут быть вызваны только для плотных массивов" + +#: extmod/ulab/code/ndarray.c +msgid "operation is not supported for given type" +msgstr "Операция не поддерживается для данного типа" + +#: extmod/ulab/code/ndarray.c +msgid "shape must be integer or tuple of integers" +msgstr "фигура должна быть целым числом или кортежом целых чисел" + +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c +msgid "maximum number of dimensions is " +msgstr "Максимальное количество измерений составляет " + +#: extmod/ulab/code/ndarray.c +msgid "can only specify one unknown dimension" +msgstr "Можно указать только одно неизвестное измерение" + +#: extmod/ulab/code/ndarray.c +msgid "cannot reshape array" +msgstr "Не удается изменить форму массива" + +#: extmod/ulab/code/ndarray.c +msgid "cannot assign new shape" +msgstr "Не удается назначить новую фигуру" + +#: extmod/ulab/code/ndarray.c +msgid "function is defined for ndarrays only" +msgstr "Функция определяется только для массивов ndarrays" + +#: extmod/ulab/code/ndarray_operators.c +msgid "operation not supported for the input types" +msgstr "операция не поддерживается для типов ввода" + +#: extmod/ulab/code/ndarray_operators.c +msgid "dtype of int32 is not supported" +msgstr "dtype int32 не поддерживается" + +#: extmod/ulab/code/ndarray_operators.c +msgid "cannot cast output with casting rule" +msgstr "Не удается привести выходные данные с помощью правила приведения" + +#: extmod/ulab/code/ndarray_operators.c +msgid "results cannot be cast to specified type" +msgstr "Результаты не могут быть приведены к указанному типу" + +#: extmod/ulab/code/numpy/approx.c +msgid "interp is defined for 1D iterables of equal length" +msgstr "interp определен для 1D-итераций одинаковой длины" + +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D iterables" +msgstr "ловушка определена для одномерных 1D итераций" + +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D arrays of equal length" +msgstr "ловушка определена для одномерных 1D массивов одинаковой длины" + +#: extmod/ulab/code/numpy/bitwise.c +msgid "not supported for input types" +msgstr "Не поддерживается для типов ввода" + +#: extmod/ulab/code/numpy/carray/carray.c +msgid "function is implemented for ndarrays only" +msgstr "Функция реализована только для массивов ndarrays" + +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be an ndarray, or a scalar" +msgstr "Ввод должен быть массивом ndarray или скаляр" + +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be a 1D ndarray" +msgstr "Ввод должен быть 1D массивом ndarray" + +#: extmod/ulab/code/numpy/carray/carray_tools.c +msgid "not implemented for complex dtype" +msgstr "не реализовано для сложного типа d" + +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c +#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c +#: extmod/ulab/code/numpy/vector.c +msgid "wrong input type" +msgstr "Неправильный тип ввода" + +#: extmod/ulab/code/numpy/create.c +msgid "input argument must be an integer, a tuple, or a list" +msgstr "Входной аргумент должен быть целым числом, кортежом или списком" + +#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c +msgid "wrong number of arguments" +msgstr "неправильное количество аргументов" + +#: extmod/ulab/code/numpy/create.c py/objint_longlong.c py/objint_mpz.c +msgid "divide by zero" +msgstr "Делим на ноль" + +#: extmod/ulab/code/numpy/create.c +msgid "arange: cannot compute length" +msgstr "arange: не удается вычислить длину" + +#: extmod/ulab/code/numpy/create.c +msgid "first argument must be a tuple of ndarrays" +msgstr "Первый аргумент должен быть кортежом массива ndarrays" + +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "только массивы ndarrays могут быть объединены" + +#: extmod/ulab/code/numpy/create.c +msgid "wrong axis specified" +msgstr "Указана неправильная ось" + +#: extmod/ulab/code/numpy/create.c +msgid "input arrays are not compatible" +msgstr "Входные массивы несовместимы" + +#: extmod/ulab/code/numpy/create.c +msgid "input must be 1- or 2-d" +msgstr "Вход должен быть 1- или 2-D" + +#: extmod/ulab/code/numpy/create.c +msgid "number of points must be at least 2" +msgstr "Количество баллов должно быть не менее 2" + +#: extmod/ulab/code/numpy/create.c +msgid "offset must be non-negative and no greater than buffer length" +msgstr "Смещение должно быть неотрицательным и не превышать длину буфера" + +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer size must be a multiple of element size" +msgstr "Размер буфера должен быть кратен размеру элемента" + +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer is smaller than requested size" +msgstr "Размер буфера меньше запрошенного" + +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is defined for ndarrays only" +msgstr "FFT определено только для массивов ndarrays" + +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is implemented for linear arrays only" +msgstr "FFT реализовано только для линейных массивов" + +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "input array length must be power of 2" +msgstr "Длина входного массива должна быть равна степени 2" + +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "real and imaginary parts must be of equal length" +msgstr "реальные и воображаемые части должны быть одинаковой длины" + +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be ndarrays" +msgstr "переплетение аргументов должно быть массивами ndarrays" + +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be linear arrays" +msgstr "Аргументы свертки должны быть линейными массивами" + +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must not be empty" +msgstr "аргументы свертки не должны быть пустыми" + +#: extmod/ulab/code/numpy/io/io.c +msgid "corrupted file" +msgstr "Поврежденный файл" + +#: extmod/ulab/code/numpy/io/io.c +msgid "wrong dtype" +msgstr "Неправильный тип" + +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols keyword must be specified" +msgstr "Ключевое слово usecols должно быть указано" + +#: extmod/ulab/code/numpy/io/io.c +msgid "empty file" +msgstr "пустой файл" + +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols is too high" +msgstr "Usecols слишком высок" + +#: extmod/ulab/code/numpy/io/io.c +msgid "array has too many dimensions" +msgstr "Массив имеет слишком много измерений" + +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "input matrix is asymmetric" +msgstr "Входная матрица асимметрична" + +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "matrix is not positive definite" +msgstr "матрица не является положительно определенной" + +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "iterations did not converge" +msgstr "итерации не сходятся" + +#: extmod/ulab/code/numpy/linalg/linalg.c +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "input matrix is singular" +msgstr "Входная матрица является сингулярной" + +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for ndarrays only" +msgstr "операция определена только для массивов ndarrays" + +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for 2D arrays only" +msgstr "операция определена только для 2D-массивов" + +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "mode must be complete, or reduced" +msgstr "Режим должен быть завершенным или уменьшенным" + +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" msgstr "" -"Адресные контакты %d, контакты rgb %d и плитки %d обозначают высоту %d, а не " -"%d" +"Попытка получить аргумент минимальный/аргумент максимальный пустой " +"последовательности" -#: shared-bindings/microcontroller/Pin.c -msgid "%q and %q contain duplicate pins" -msgstr "%q и %q содержат пины дупликаты" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get (arg)min/(arg)max of empty sequence" +msgstr "" +"Попытка получить (аргумент)минимальный/(аргумент)максимальный пустой " +"последовательности" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "%q and %q must be different" -msgstr "%q и %q должны быть разными" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +msgid "axis must be None, or an integer" +msgstr "ось должна быть None или целым числом" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "%q and %q must share a clock unit" -msgstr "%q и %q должны иметь общую единицу тактового генератора" +#: extmod/ulab/code/numpy/numerical.c +msgid "operation is not implemented on ndarrays" +msgstr "операция не реализована на массивах ndarrays" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "%q cannot be changed once mode is set to %q" -msgstr "%q не может быть изменен после установки режима на %q" +#: extmod/ulab/code/numpy/numerical.c +msgid "input must be tuple, list, range, or ndarray" +msgstr "Ввод должен быть кортеж, список, диапазон или массивом ndarray" -#: shared-bindings/microcontroller/Pin.c -msgid "%q contains duplicate pins" -msgstr "%q содержит пины дупликаты" +#: extmod/ulab/code/numpy/numerical.c +msgid "sort argument must be an ndarray" +msgstr "аргумент сортировки должен быть массивом ndarray" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -msgid "%q failure: %d" -msgstr "%q сбой: %d" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort argument must be an ndarray" +msgstr "аргумент сортировки должен быть аргументом массива ndarray" -#: py/argcheck.c -msgid "%q in %q must be of type %q, not %q" -msgstr "%q в %q должно быть типа %q, а не %q" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort is not implemented for flattened arrays" +msgstr "сортировка arg не реализована для сглаженных массивов" -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/usb_host/Port.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c -msgid "%q in use" -msgstr "%q используется" +#: extmod/ulab/code/numpy/numerical.c +msgid "axis too long" +msgstr "Слишком длинная ось" -#: py/objstr.c -msgid "%q index out of range" -msgstr "Индекс %q вне диапазона" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c +msgid "arguments must be ndarrays" +msgstr "Аргументы должны быть массивами ndarrays" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "Индексы %q должны быть целыми числами, а не %s" +#: extmod/ulab/code/numpy/numerical.c +msgid "cross is defined for 1D arrays of length 3" +msgstr "крест определяется для 1D массивов длины 3" -#: shared-module/bitbangio/SPI.c -msgid "%q init failed" -msgstr "Инициализация %q не удалась" +#: extmod/ulab/code/numpy/numerical.c +msgid "diff argument must be an ndarray" +msgstr "аргумент DIFF должен быть массивом ndarray" -#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c -msgid "%q is %q" -msgstr "%q является %q" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" +msgstr "индекс вне диапазона" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "%q is read-only for this board" -msgstr "%q читается только для этой доски" +#: extmod/ulab/code/numpy/numerical.c +msgid "differentiation order out of range" +msgstr "Порядок дифференциации вне диапазона" -#: py/argcheck.c shared-bindings/usb_hid/Device.c -msgid "%q length must be %d" -msgstr "Длинна %q должна быть %d" +#: extmod/ulab/code/numpy/numerical.c +msgid "flip argument must be an ndarray" +msgstr "Флип -аргумент должен быть массивом ndarray" -#: py/argcheck.c -msgid "%q length must be %d-%d" -msgstr "Длинна %q должна быть %d-%d" +#: extmod/ulab/code/numpy/numerical.c +msgid "wrong axis index" +msgstr "Неправильный индекс оси" + +#: extmod/ulab/code/numpy/numerical.c +msgid "median argument must be an ndarray" +msgstr "Средний аргумент должен быть массивом ndarray" + +#: extmod/ulab/code/numpy/numerical.c +msgid "roll argument must be an ndarray" +msgstr "аргумент roll должен быть массивом ndarray" -#: py/argcheck.c -msgid "%q length must be <= %d" -msgstr "Длинна %q должна быть <= %d" +#: extmod/ulab/code/numpy/poly.c +msgid "input data must be an iterable" +msgstr "Входные данные должны быть итерируемыми" -#: py/argcheck.c -msgid "%q length must be >= %d" -msgstr "Длинна %q должна быть >= %d" +#: extmod/ulab/code/numpy/poly.c +msgid "more degrees of freedom than data points" +msgstr "Больше степеней свободы чем точек данных" -#: py/modsys.c py/objmodule.c py/runtime.c -msgid "%q moved from %q to %q" -msgstr "%q переместился из %q в %q" +#: extmod/ulab/code/numpy/poly.c +msgid "input vectors must be of equal length" +msgstr "Входные векторы должны быть одинаковой длины" -#: py/argcheck.c -msgid "%q must be %d" -msgstr "%q должно быть %d" +#: extmod/ulab/code/numpy/poly.c +msgid "could not invert Vandermonde matrix" +msgstr "не удалось инвертировать матрицу Вандермонда" -#: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "%q must be %d-%d" -msgstr "%q должно быть %d-%d" +#: extmod/ulab/code/numpy/poly.c +msgid "input is not iterable" +msgstr "Ввод не является итерируемым" -#: shared-bindings/busdisplay/BusDisplay.c -msgid "%q must be 1 when %q is True" -msgstr "%q должен быть равен 1, если %q имеет значение True" +#: extmod/ulab/code/numpy/random/random.c +msgid "argument must be None, an integer or a tuple of integers" +msgstr "аргумент должен быть None, целым числом или кортежем целых чисел" -#: py/argcheck.c shared-bindings/gifio/GifWriter.c -#: shared-module/gifio/OnDiskGif.c -msgid "%q must be <= %d" -msgstr "%q должно быть <= %d" +#: extmod/ulab/code/numpy/random/random.c +msgid "shape must be None, and integer or a tuple of integers" +msgstr "форма должна быть None, целым числом или кортежем целых чисел" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "%q must be <= %u" -msgstr "%q должно быть <= %u" +#: extmod/ulab/code/numpy/random/random.c +msgid "out has wrong type" +msgstr "out имеет неправильный тип" -#: py/argcheck.c -msgid "%q must be >= %d" -msgstr "%q должно быть >= %d" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array has wrong type" +msgstr "Выходной массив имеет неправильный тип" -#: shared-bindings/analogbufio/BufferedIn.c -msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "%q должен быть массивом байтов или массивом типа «H» или «B»" +#: extmod/ulab/code/numpy/random/random.c +msgid "size must match out.shape when used together" +msgstr "Размер должен соответствовать out.shape при совместном использовании" -#: shared-bindings/audiocore/RawSample.c -msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -msgstr "%q должен быть массивом байтов или массивом типа «h», «H», «b» или «B»" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array must be contiguous" +msgstr "выходной массив должен быть непрерывным" -#: shared-bindings/warnings/__init__.c -msgid "%q must be a subclass of %q" -msgstr "%q должен быть подклассом %q" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of condition array" +msgstr "неправильная длина массива состояния" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -msgid "%q must be array of type 'H'" -msgstr "%q должен быть массивом типа 'H \"" +#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c +msgid "first argument must be an ndarray" +msgstr "Первым аргументом должен быть массивом ndarray" -#: shared-module/synthio/__init__.c -msgid "%q must be array of type 'h'" -msgstr "%q должен быть массивом типа 'h \"" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong index type" +msgstr "Неправильный тип индекса" -#: shared-bindings/audiobusio/PDMIn.c -msgid "%q must be multiple of 8." -msgstr "%q должно быть кратно 8." +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of index array" +msgstr "неправильная длина массива индексов" -#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c -#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c -#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c -#: shared-module/synthio/Synthesizer.c -msgid "%q must be of type %q or %q, not %q" -msgstr "%q должно быть типа%q или%q, а не%q" +#: extmod/ulab/code/numpy/transform.c +msgid "dimensions do not match" +msgstr "Размеры не совпадают" -#: shared-bindings/jpegio/JpegDecoder.c -msgid "%q must be of type %q, %q, or %q, not %q" -msgstr "%q должен иметь тип %q, %q или %q, а не %q" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be an ndarray" +msgstr "out должен быть массивом ndarray" -#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c -#: shared-module/synthio/__init__.c -msgid "%q must be of type %q, not %q" -msgstr "%q должно быть типа %q, а не %q" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be of float dtype" +msgstr "Выход должен быть поплавкового типа" -#: ports/atmel-samd/common-hal/busio/UART.c -msgid "%q must be power of 2" -msgstr "%q должен быть во 2-й степени" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output dimensions differ" +msgstr "Входные и выходные размеры различаются" -#: shared-bindings/wifi/Monitor.c -msgid "%q out of bounds" -msgstr "%q за пределом" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output shapes differ" +msgstr "Входные и выходные формы различаются" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c -#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c -msgid "%q out of range" -msgstr "%q вне диапазона" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for function" +msgstr "ключевое слово не поддерживается для функции" -#: py/objmodule.c py/runtime.c -msgid "%q renamed %q" -msgstr "%q переименован %q" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for complex dtype" +msgstr "Ключевое слово out не поддерживается для сложного типа d" -#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c -msgid "%q step cannot be zero" -msgstr "Шаг %q не может быть нулём" +#: extmod/ulab/code/numpy/vector.c +msgid "dtype must be float, or complex" +msgstr "Тип d должен быть плавающим или сложным" -#: shared-module/bitbangio/I2C.c -msgid "%q too long" -msgstr "%q слишком долго" +#: extmod/ulab/code/numpy/vector.c +msgid "can't convert complex to float" +msgstr "Не может преобразовать сложный в плавающий" -#: py/bc.c py/objnamedtuple.c -msgid "%q() takes %d positional arguments but %d were given" -msgstr "%q() принимает %d позиционных аргументов, но было передано %d" +#: extmod/ulab/code/numpy/vector.c +msgid "input dtype must be float or complex" +msgstr "Входной тип dtype должен быть плавающим или сложным" -#: shared-module/jpegio/JpegDecoder.c -msgid "%q() without %q()" -msgstr "%q() без %q()" +#: extmod/ulab/code/numpy/vector.c +msgid "first argument must be a callable" +msgstr "Первый аргумент должен быть вызываемым" -#: shared-bindings/usb_hid/Device.c -msgid "%q, %q, and %q must all be the same length" -msgstr "%q, %q, и %q должны быть одной длинны" +#: extmod/ulab/code/numpy/vector.c +msgid "wrong output type" +msgstr "неверный тип вывода" -#: py/objint.c shared-bindings/storage/__init__.c -msgid "%q=%q" -msgstr "%q=%q" +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "first two arguments must be ndarrays" +msgstr "Первые два аргумента должны быть массивами ndarrays" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts in more bits than pin count" -msgstr "%q [%u] смещается в большем количестве чем количество пинов" +#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c +msgid "input must be a dense ndarray" +msgstr "Ввод должен быть плотным массивом ndarray" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts out more bits than pin count" -msgstr "%q[%u] смещает больше битов чем количество выводов" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "first argument must be a function" +msgstr "первый аргумент должен быть функцией" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] uses extra pin" -msgstr "%q[%u] использует дополнительный контакт" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "function has the same sign at the ends of interval" +msgstr "функция имеет один и тот же знак в конце интервала" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] waits on input outside of count" -msgstr "%q [%u] ожидает ввода за пределами графа" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter should be > 0" +msgstr "макситер должен быть > 0" -#: ports/espressif/common-hal/espidf/__init__.c -#, c-format -msgid "%s error 0x%x" -msgstr "%s ошибка 0x%x" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter must be > 0" +msgstr "maxiter должен быть > 0" -#: py/argcheck.c -msgid "'%q' argument required" -msgstr "Требуется аргумент '%q'" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be iterable" +msgstr "Данные должны быть итерируемыми" -#: py/proto.c -msgid "'%q' object does not support '%q'" -msgstr "Объект '%q' не поддерживает '%q'" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "initial values must be iterable" +msgstr "Начальные значения должны быть итерируемыми" -#: py/runtime.c -msgid "'%q' object is not an iterator" -msgstr "Объект '%q' не является итератором" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be of equal length" +msgstr "Данные должны быть одинаковой длины" -#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c -msgid "'%q' object is not callable" -msgstr "Объект '%q' не является вызываемым" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sosfilt requires iterable arguments" +msgstr "sosфильтр требует повторяющихся аргументов" -#: py/runtime.c -msgid "'%q' object is not iterable" -msgstr "Объект '%q' не является итерируемым" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "input must be one-dimensional" +msgstr "Входные данные должны быть одномерными" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a label" -msgstr "'%s' ожидает метку" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be an ndarray" +msgstr "зи, должно быть, массивом ndarray" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a register" -msgstr "'%s' ожидает регистр" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of shape (n_section, 2)" +msgstr "zi должен иметь форму (n_section, 2)" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects a special register" -msgstr "'%s' ожидает специальный регистр" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of float type" +msgstr "zi должно быть типа float" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an FPU register" -msgstr "'%s' ожидает регистр FPU" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos array must be of shape (n_section, 6)" +msgstr "Массив sos должен иметь форму (n_section, 6)" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s' ожидает адрес в формате [a, b]" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos[:, 3] should be all ones" +msgstr "sos[:, 3] должны быть все единицы" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects an integer" -msgstr "'%s' ожидает целое число" +#: extmod/ulab/code/ulab_tools.c +msgid "axis is out of bounds" +msgstr "Ось выходит за пределы" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects at most r%d" -msgstr "'%s' ожидает не более r%d" +#: extmod/ulab/code/ulab_tools.c +msgid "size is defined for ndarrays only" +msgstr "размер определен только для массива ndarrays" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' ожидает {r0, r1, ...}" +#: extmod/ulab/code/ulab_tools.c +msgid "input must be square matrix" +msgstr "Входные данные должны быть квадратной матрицей" -#: py/emitinlinextensa.c -#, c-format -msgid "'%s' integer %d isn't within range %d..%d" -msgstr "'%s' целое число %d не находится в пределах диапазона %d..%d" +#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c +msgid "input must be an ndarray" +msgstr "Ввод должен быть массивом ndarray" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" -msgstr "'%s' целое число 0x%x не помещается в маску 0x%x" +#: extmod/ulab/code/utils/utils.c +msgid "out must be a float dense array" +msgstr "Out должен быть плотным массивом с плавающей запятой" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item assignment" -msgstr "Объект '%s' не поддерживает присвоение элементов" +#: extmod/ulab/code/utils/utils.c +msgid "offset is too large" +msgstr "Смещение слишком большое" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item deletion" -msgstr "Объект '%s' не поддерживает удаление элементов" +#: extmod/ulab/code/utils/utils.c +msgid "out array is too small" +msgstr "Наш массив слишком мал" -#: py/runtime.c -msgid "'%s' object has no attribute '%q'" -msgstr "Объект '%s' не имеет атрибута '%q'" +#: extmod/vfs_fat.c py/moderrno.c +msgid "Read-only filesystem" +msgstr "Файловая система только для чтения" -#: py/obj.c -#, c-format -msgid "'%s' object isn't subscriptable" -msgstr "Объект '%s' не может быть подписан" +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "Операция ввода-вывода на закрытом файле" -#: py/objstr.c -msgid "'=' alignment not allowed in string format specifier" -msgstr "Выравнивание '=' недопустимо в спецификаторе формата строки" +#: extmod/vfs_posix_file.c +msgid "poll on file not available on win32" +msgstr "Опрос в файле недоступен в Win32" -#: shared-module/struct/__init__.c -msgid "'S' and 'O' are not supported format types" -msgstr "'S' и 'O' не являются поддерживаемыми типами форматов" +#: main.c +msgid "Done" +msgstr "Выполнено" -#: py/compile.c -msgid "'align' requires 1 argument" -msgstr "«выравнивание» требует 1 аргумента" +#: main.c +msgid " output:\n" +msgstr " вывод:\n" -#: py/compile.c -msgid "'await' outside function" -msgstr "«ожидание» внешняя функция" +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" +msgstr "" +"Автоматическая перезагрузка включена. Просто сохрани файл по USB или зайди в " +"REPL чтобы отключить.\n" -#: py/compile.c -msgid "'break'/'continue' outside loop" -msgstr "'прервать'/'продолжить' вне цикла" +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Автоматическая перезагрузка отключена.\n" -#: py/compile.c -msgid "'data' requires at least 2 arguments" -msgstr "«данные» требуют как минимум 2 аргумента" +#: main.c +msgid "Running in safe mode! Not running saved code.\n" +msgstr "Работает в безопасном режиме! Сохраненный код не выполняется.\n" -#: py/compile.c -msgid "'data' requires integer arguments" -msgstr "«данные» требуют целочисленных аргументов" +#: main.c +msgid " not found.\n" +msgstr " не найден.\n" -#: py/compile.c -msgid "'label' requires 1 argument" -msgstr "«метка» требует 1 аргумент" +#: main.c +msgid "WARNING: Your code filename has two extensions\n" +msgstr "ВНИМАНИЕ: Имя файла кода имеет два расширения\n" -#: py/emitnative.c -msgid "'not' not implemented" +#: main.c +msgid "" +"\n" +"Code stopped by auto-reload. Reloading soon.\n" msgstr "" +"\n" +"Программа остановлена автоматической перезагрузкой. Скоро перезагрузка.\n" -#: py/compile.c -msgid "'return' outside function" -msgstr "«возврат» внешняя функция" +#: main.c +msgid "" +"\n" +"Code done running.\n" +msgstr "" +"\n" +"Программа закончила выполнение.\n" -#: py/compile.c -msgid "'yield from' inside async function" -msgstr "«выход из» внутри асинхронной функции" +#: main.c +msgid "Woken up by alarm.\n" +msgstr "Проснулся по тревоге.\n" -#: py/compile.c -msgid "'yield' outside function" -msgstr "внешняя функция \"выход\"" +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" +msgstr "" +"Нажмите любую клавишу чтобы зайти в REPL. Используйте CTRL-D для " +"перезагрузки.\n" -#: py/compile.c -msgid "* arg after **" -msgstr "* аргумент после **" +#: main.c +msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +msgstr "" +"Притворяюсь глубоким сном до сигнала тревоги, CTRL-C или записи файла.\n" -#: py/compile.c -msgid "*x must be assignment target" -msgstr "*x должно быть целью назначения" +#: main.c +msgid "UID:" +msgstr "UID:" -#: py/obj.c -msgid ", in %q\n" -msgstr ", в %q\n" +#: main.c +msgid "soft reboot\n" +msgstr "Мягкая перезагрузка\n" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid ".show(x) removed. Use .root_group = x" -msgstr ". Показать(x) удален. Используйте . корневую_группу = x" +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c +#: ports/stm/common-hal/audioio/AudioOut.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c +#: shared-module/busdisplay/BusDisplay.c shared-module/ssl/SSLContext.c +msgid "%q init failed" +msgstr "Инициализация %q не удалась" -#: py/objcomplex.c -msgid "0.0 to a complex power" -msgstr "0.0 в комплексную степень" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" -#: py/modbuiltins.c -msgid "3-arg pow() not supported" -msgstr "Pow() с 3 аргументами не поддерживается" +#: ports/analog/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c +#: shared-bindings/bitmaptools/__init__.c shared-bindings/canio/Match.c +#: shared-bindings/time/__init__.c +msgid "%q out of range" +msgstr "%q вне диапазона" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "AP could not be started" -msgstr "AP не может быть запущен" +#: ports/analog/common-hal/busio/SPI.c +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid state" +msgstr "Неверное состояние" -#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, c-format -msgid "Address must be %d bytes long" -msgstr "Адрес должен быть длиной %d байт" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" -#: ports/espressif/common-hal/memorymap/AddressRange.c -#: ports/nordic/common-hal/memorymap/AddressRange.c -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Address range not allowed" -msgstr "Диапазон адресов не разрешен" +#: ports/analog/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "RS485" -#: shared-bindings/memorymap/AddressRange.c -msgid "Address range wraps around" -msgstr "Обертывание диапазона адресов" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" +msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "All CAN peripherals are in use" -msgstr "Все периферийные устройства CAN уже используются" +#: ports/analog/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Both RX and TX required for flow control" +msgstr "Для управления потоком требуется как RX так и TX" -#: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/nordic/common-hal/busio/I2C.c -msgid "All I2C peripherals are in use" -msgstr "Все периферийные устройства I2C уже используются" +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c +msgid "Failed to allocate %q buffer" +msgstr "Не удалось выделить буфер %q" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "All RX FIFOs in use" -msgstr "Все RX FIFO уже используются" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" +msgstr "" -#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c -msgid "All SPI peripherals are in use" -msgstr "Все периферийные устройства SPI уже используются" +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" +msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c msgid "All UART peripherals are in use" msgstr "Все периферийные устройства UART уже используются" -#: ports/nordic/common-hal/countio/Counter.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c -msgid "All channels in use" -msgstr "Все каналы уже используются" - -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All dma channels in use" -msgstr "Все используемые каналы dma" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "All event channels in use" -msgstr "Все каналы событий уже используются" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c +#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/microcontroller/Processor.c +#: ports/espressif/common-hal/mipidsi/Display.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +#: ports/raspberrypi/bindings/picodvi/Framebuffer.c +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c +msgid "Invalid %q" +msgstr "Недопустимый %q" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All state machines in use" -msgstr "Все машины состояний уже используются" +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" #: ports/atmel-samd/audio_dma.c msgid "All sync event channels in use" msgstr "Все каналы событий синхронизации уже используются" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -msgid "All timers for this pin are in use" -msgstr "Все таймеры для этого пина уже используются" +#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "Внутренний звуковой буфер слишком мал" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" +msgstr "Калибровка доступна только для чтения" + +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" +msgstr "Калибровка выходит за пределы допустимого диапазона" + +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." +msgstr "Вы нажали обе кнопки при запуске." #: ports/atmel-samd/common-hal/_pew/PewPew.c #: ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -552,145 +849,234 @@ msgstr "Все таймеры для этого пина уже использу #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Все таймеры уже используются" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Already advertising." -msgstr "Уже реклама." +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: ports/atmel-samd/common-hal/countio/Counter.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/max3421e/Max3421E.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +msgid "Internal resource(s) in use" +msgstr "Используемые внутренние ресурсы" -#: ports/atmel-samd/common-hal/canio/Listener.c -msgid "Already have all-matches listener" -msgstr "Уже есть универсальный слушатель" +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: supervisor/shared/safe_mode.c +msgid "Unknown reason." +msgstr "Причина неизвестна." -#: ports/espressif/bindings/espnow/ESPNow.c -#: ports/espressif/common-hal/espulp/ULP.c -#: shared-module/memorymonitor/AllocationAlarm.c -#: shared-module/memorymonitor/AllocationSize.c -msgid "Already running" -msgstr "Уже запущен" +#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +#: ports/nordic/common-hal/alarm/time/TimeAlarm.c +#: ports/stm/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set" +msgstr "Можно установить только один будильник" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Already scanning for wifi networks" -msgstr "Поиск сетей wifi уже происходит" +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "No DAC on chip" +msgstr "DAC отсутствует на чипе" -#: shared-module/os/getenv.c -#, c-format -msgid "An error occurred while retrieving '%s':\n" -msgstr "Произошла ошибка при получении '%s':\n" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "%q and %q must share a clock unit" +msgstr "%q и %q должны иметь общую единицу тактового генератора" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Another PWMAudioOut is already active" -msgstr "Другой аудиовыход PWM уже активен" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "Сериализатор используется" -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -msgid "Another send is already active" -msgstr "Другая передача уже активна" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Источник тактирования уже используется" -#: shared-bindings/pulseio/PulseOut.c -msgid "Array must contain halfwords (type 'H')" -msgstr "Массив должен содержать полуслова (тип 'H')" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" +msgstr "Свободные GCLK отсутствуют" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Array values should be single bytes." -msgstr "Значения массива должны быть однобайтовыми." +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample" +msgstr "Слишком много каналов в выборке" -#: shared-module/memorymonitor/AllocationAlarm.c +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "No DMA channel found" +msgstr "Канал DMA не найден" + +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Unable to allocate buffers for signed conversion" +msgstr "Не удается выделить буферы для подписанного преобразования" + +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c #, c-format -msgid "Attempt to allocate %d blocks" -msgstr "Попытка выделения %d блоков" +msgid "Only 8 or 16 bit mono with %dx oversampling supported." +msgstr "Поддерживается только 8 или 16-битное моно с передискретизацией %dx." -#: ports/raspberrypi/audio_dma.c -msgid "Audio conversion not implemented" -msgstr "Преобразование звука не реализовано" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" +msgstr "Частота дискретизации выходит за пределы допустимого диапазона" -#: shared-bindings/wifi/Radio.c -msgid "AuthMode.OPEN is not used with password" -msgstr "Режим авторизации.OPEN не используется с паролем" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC уже используется" -#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c -msgid "Authentication failure" -msgstr "Ошибка аутентификации" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" +msgstr "Правый канал не поддерживается" -#: main.c -msgid "Auto-reload is off.\n" -msgstr "Автоматическая перезагрузка отключена.\n" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Все каналы событий уже используются" -#: main.c -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" -msgstr "" -"Автоматическая перезагрузка включена. Просто сохрани файл по USB или зайди в " -"REPL чтобы отключить.\n" +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/I2C.c +#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/busio/I2C.c +msgid "No pull up found on SDA or SCL; check your wiring" +msgstr "На SDA или SCL не обнаружено подтягивания; проверь свою проводку" -#: ports/espressif/common-hal/canio/CAN.c -msgid "Baudrate not supported by peripheral" -msgstr "Скорость передачи данных не поддерживается периферийным устройством" +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "%q must be power of 2" +msgstr "%q должен быть во 2-й степени" -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Below minimum frame rate" -msgstr "Ниже минимальной частоты кадров" +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c +#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c +#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c +#: shared-bindings/paralleldisplaybus/ParallelBus.c +#: shared-bindings/qspibus/QSPIBus.c shared-module/bitbangio/SPI.c +msgid "No %q pin" +msgstr "Нет пина %q" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Bit clock and word select must be sequential GPIO pins" -msgstr "Несколько часов и слов должны быть последовательными GPIO пинами" +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "Все RX FIFO уже используются" -#: shared-bindings/bitmaptools/__init__.c -msgid "Bitmap size and bits per value must match" -msgstr "" -"Размер растрового изображения и число битов на значение должны совпадать" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "Уже есть универсальный слушатель" -#: supervisor/shared/safe_mode.c -msgid "Boot device must be first (interface #0)." -msgstr "Загрузочное устройство должно быть первым (интерфейс #0)." +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "Фильтры слишком сложные" -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Both RX and TX required for flow control" -msgstr "Для управления потоком требуется как RX так и TX" +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +#: ports/nordic/common-hal/digitalio/DigitalInOut.c +#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Невозможно получить pull в режиме вывода" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Brightness not adjustable" -msgstr "Яркость не регулируется" +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "Invalid data_pins[%d]" +msgstr "Неверный data_pins[%d]" + +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#, c-format +msgid "data pin #%d in use" +msgstr "data-пин #%d уже используется" + +#: ports/atmel-samd/common-hal/microcontroller/Pin.c +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c +#: shared-bindings/microcontroller/Pin.c +msgid "Invalid %q pin" +msgstr "Недопустимый пин %q" + +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +#: ports/cxd56/common-hal/microcontroller/__init__.c +#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c +msgid "No bootloader present" +msgstr "Отсутствует загрузчик" + +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "Пин data 0 должен быть байтово выровнен" -#: shared-bindings/_bleio/UUID.c +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c #, c-format -msgid "Buffer + offset too small %d %d %d" -msgstr "Буфер + сдвиг слишком малы %d %d %d" +msgid "Bus pin %d is already in use" +msgstr "Вывод шины %d уже используется" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Buffer elements must be 4 bytes long or less" -msgstr "Элементы буфера должны иметь длину не более 4 байт" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/pulseio/PulseIn.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c +#: shared-bindings/ps2io/Ps2.c +msgid "pop from empty %q" +msgstr "Всплывающее окно из пустого %q" -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Buffer is not a bytearray." -msgstr "Буфер не является байтовым массивом." +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "Input taking too long" +msgstr "Ввод занимает слишком много времени" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, c-format -msgid "Buffer length %d too big. It must be less than %d" -msgstr "Размер буфера %d слишком большой. Он должен быть меньше чем %d" +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Другая передача уже активна" + +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "%q failure: %d" +msgstr "%q сбой: %d" #: ports/atmel-samd/common-hal/sdioio/SDCard.c #: ports/cxd56/common-hal/sdioio/SDCard.c #: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c #: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c #: shared-module/sdcardio/SDCard.c #, c-format msgid "Buffer must be a multiple of %d bytes" +msgstr "Буфер должен быть кратен %d байт" + +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -#, c-format -msgid "Buffer too short by %d bytes" -msgstr "Буфер слишком короткий на %d байт" +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/stm/common-hal/busio/UART.c +msgid "UART init" +msgstr "Инициализация UART" + +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Camera init" +msgstr "Иницализация камеры" + +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Size not supported" +msgstr "Размер не поддерживается" #: ports/cxd56/common-hal/camera/Camera.c #: shared-bindings/busdisplay/BusDisplay.c @@ -699,347 +1085,375 @@ msgstr "Буфер слишком короткий на %d байт" msgid "Buffer too small" msgstr "Слишком маленький буфер" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, c-format -msgid "Bus pin %d is already in use" -msgstr "Вывод шины %d уже используется" - -#: shared-bindings/_bleio/UUID.c -msgid "Byte buffer must be 16 bytes." -msgstr "Буфер байтов должен быть размером 16 байтам." +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c +msgid "Format not supported" +msgstr "Формат не поддерживается" -#: shared-bindings/aesio/aes.c -msgid "CBC blocks must be multiples of 16 bytes" -msgstr "Блоки CBC должны быть кратны 16 байтам" +#: ports/cxd56/common-hal/gnss/GNSS.c +msgid "GNSS init" +msgstr "Инициализация GNSS" -#: supervisor/shared/safe_mode.c -msgid "CIRCUITPY drive could not be found or created." -msgstr "Диск CIRCUTPY не удалось найти или создать." +#: ports/cxd56/common-hal/sdioio/SDCard.c +msgid "SDCard init" +msgstr "Инициализация SD-карты" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "CRC or checksum was invalid" -msgstr "CRC или контрольная сумма неправильная" +#: ports/espressif/bindings/espnow/ESPNow.c +#: ports/espressif/common-hal/espulp/ULP.c +#: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize.c +msgid "Already running" +msgstr "Уже запущен" -#: py/objtype.c -msgid "Call super().__init__() before accessing native object." -msgstr "Вызовите super().__init__() перед доступом к собственному объекту." +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q является %q" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Camera init" -msgstr "Иницализация камеры" +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." +msgstr "Вы нажали кнопку SW38 при запуске." -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on RTC IO from deep sleep." -msgstr "Возможен только сигнал тревоги по RTC IO из глубокого сна." +#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h +#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h +msgid "You pressed the BOOT button at start up." +msgstr "При запуске вы нажали кнопку BOOT." -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on one low pin while others alarm high from deep sleep." -msgstr "" -"Может сигнализировать только по одному низкому контакту в то время как " -"другие сигнализируют о высоком уровне после глубокого сна." +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." +msgstr "Вы нажали кнопку GPIO0 при запуске." -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on two low pins from deep sleep." -msgstr "" -"Из глубокого сна может сигнализировать только по двум низким контактам." +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." +msgstr "Вы нажали кнопку «Запись» при запуске." -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "Can't set CCCD on local Characteristic" -msgstr "Невозможно установить CCCD для локальной характеристики" +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +#: ports/espressif/boards/vidi_x/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." +msgstr "Вы нажали кнопку ГРОМКОСТЬ при запуске." -#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c -#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c -#: shared-bindings/usb_video/__init__.c -msgid "Cannot change USB devices now" -msgstr "Невозможно изменить USB устройство сейчас" +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." +msgstr "Вы нажали центральную кнопку при запуске." -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot create a new Adapter; use _bleio.adapter;" -msgstr "Невозможно создать новый Adapter; используйте _bleio.adapter;" +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h +msgid "You pressed button A at start up." +msgstr "Вы нажали кнопку A при запуске." -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Cannot delete values" -msgstr "Невозможно удалить значения" +#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h +msgid "You pressed button DOWN at start up." +msgstr "Вы нажали кнопку ВНИЗ при запуске." -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c -#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c -#: ports/nordic/common-hal/digitalio/DigitalInOut.c -#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c -msgid "Cannot get pull while in output mode" -msgstr "Невозможно получить pull в режиме вывода" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Update failed" +msgstr "Обновление не удалось" -#: ports/nordic/common-hal/microcontroller/Processor.c -msgid "Cannot get temperature" -msgstr "Невозможно получить температуру" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Scan already in progress. Stop with stop_scan." +msgstr "Сканирование уже выполняется. Остановитесь на stop_scan." -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot have scan responses for extended, connectable advertisements." -msgstr "" -"Не может быть ответов на сканирование для расширенных подключаемых рекламных " -"объявлений." +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: internal error" +msgstr "Не удалось подключиться: внутренняя ошибка" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot pull on input-only pin." -msgstr "Невозможно вытащить контакт только для ввода." +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data too large for advertisement packet" +msgstr "Данные слишком велики для пакета объявления" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Cannot record to a file" -msgstr "Невозможно записать в файл" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Already advertising." +msgstr "Уже реклама." -#: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "Невозможно перемонтировать '/' пока он виден через USB." +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Extended advertisements with scan response not supported." +msgstr "Расширенные объявления с ответом сканирования не поддерживаются." -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Cannot set value when direction is input." -msgstr "Невозможно установить значение при вводе направления." +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data not supported with directed advertising" +msgstr "Данные не поддерживаются направленным объявлением" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "Невозможно указать RTS или CTS в режиме RS485" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#, c-format +msgid "Timeout is too long: Maximum timeout length is %d seconds" +msgstr "Таймаут слишком длинный: максимальная длина таймаута %d секунд" -#: py/objslice.c -msgid "Cannot subclass slice" -msgstr "Невозможно создать подкласс среза" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +msgid "MITM security not supported" +msgstr "Защита от MITM не поддерживается" -#: ports/nordic/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge, only level" -msgstr "" -"Невозможно проснуться по изменению логического уровня, только по уровню" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" +msgstr "Длина значения! = требуемая фиксированная длина" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge. Only level." -msgstr "Невозможно проснуться по спаду росту на пине. Только по уровню." +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" +msgstr "Длина значения > максимальная_длина" -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "CharacteristicBuffer writing not provided" -msgstr "ХарактеристикаЗапись в буфер не предусмотрена" +#: ports/espressif/common-hal/_bleio/Characteristic.c +msgid "Too many descriptors" +msgstr "Слишком много дескрипторов" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "Основной код CircuitPython сильно разбился. Упс!\n" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +msgid "No CCCD for this Characteristic" +msgstr "Для этой характеристики нет CCCD" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Clock unit in use" -msgstr "Источник тактирования уже используется" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "Невозможно установить CCCD для локальной характеристики" -#: shared-bindings/_bleio/Connection.c -msgid "" -"Connection has been disconnected and can no longer be used. Create a new " -"connection." -msgstr "" -"Соединение было отключено и больше не может использоваться. Создайте новое " -"соединение." +#: ports/espressif/common-hal/_bleio/Connection.c +#: ports/nordic/common-hal/_bleio/Connection.c +msgid "non-UUID found in service_uuids_whitelist" +msgstr "не-UUID найден в сервисе_uuids_белый список" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays have different lengths" -msgstr "Координатные массивы имеют разные длины" +#: ports/espressif/common-hal/_bleio/Descriptor.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" +msgstr "максимальная_длина должна быть 0-%d когда фиксированная длина %s" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays types have different sizes" -msgstr "Типы массивов координат имеют разные размеры" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Writes not supported on Characteristic" +msgstr "Запись не поддерживается в Характеристика" -#: shared-bindings/_bleio/Adapter.c -msgid "Could not set address" -msgstr "Не удалось задать адрес" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Total data to write is larger than %q" +msgstr "Общее количество данных для записи превышает %q" -#: ports/stm/common-hal/busio/UART.c -msgid "Could not start interrupt, RX busy" -msgstr "Не удалось запустить прерывание, RX занят" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Nimble out of memory" +msgstr "Изображение памяти" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Couldn't allocate decoder" -msgstr "Не удалось выделить место для декодера" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid BLE parameter" +msgstr "Недопустимый параметр BLE" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Channel Init Error" -msgstr "Ошибка инициализации канала DAC" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#: ports/zephyr-cp/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "Not connected" +msgstr "Не подключено" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Device Init Error" -msgstr "Ошибка инициализации устройства DAC" +#: ports/espressif/common-hal/_bleio/__init__.c +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Already in progress" +msgstr "Уже в процессе" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "DAC already in use" -msgstr "DAC уже используется" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error at %s:%d: %d" +msgstr "Неизвестная системная ошибка прошивки на %s:%d: %d" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -msgid "Data 0 pin must be byte aligned" -msgstr "Пин data 0 должен быть байтово выровнен" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %d" +msgstr "Неизвестная ошибка прошивки системы: %d" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Блок данных должен следовать за блоком fmt" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient authentication" +msgstr "Неполная аутентификация" -#: shared-module/jpegio/JpegDecoder.c -msgid "Data format error (may be broken data)" -msgstr "Ошибка формата данных (возможно, данные повреждены)" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient encryption" +msgstr "Недостаточное шифрование" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data not supported with directed advertising" -msgstr "Данные не поддерживаются направленным объявлением" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error at %s:%d: %d" +msgstr "Неизвестная ошибка BLE в %s:%d: %d" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data too large for advertisement packet" -msgstr "Данные слишком велики для пакета объявления" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error: %d" +msgstr "Неизвестная ошибка BLE: %d" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Deep sleep pins must use a rising edge with pulldown" -msgstr "" -"Выводы глубокого сна должны использовать сигнал по возрастанию с подтяжкой к " -"земле" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge. Only level." +msgstr "Невозможно проснуться по спаду росту на пине. Только по уровню." -#: shared-bindings/audiobusio/PDMIn.c -msgid "Destination capacity is smaller than destination_length." -msgstr "Емкость места назначения меньше длины места назначения." +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot pull on input-only pin." +msgstr "Невозможно вытащить контакт только для ввода." -#: shared-module/jpegio/JpegDecoder.c -msgid "Device error or wrong termination of input stream" -msgstr "Ошибка устройства или неправильное завершение входного потока" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on two low pins from deep sleep." +msgstr "" +"Из глубокого сна может сигнализировать только по двум низким контактам." -#: ports/nordic/common-hal/audiobusio/I2SOut.c -msgid "Device in use" -msgstr "Устройство используется" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on one low pin while others alarm high from deep sleep." +msgstr "" +"Может сигнализировать только по одному низкому контакту в то время как " +"другие сигнализируют о высоком уровне после глубокого сна." -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display must have a 16 bit colorspace." -msgstr "Дисплей должен иметь 16 битное цветовое пространство." +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on RTC IO from deep sleep." +msgstr "Возможен только сигнал тревоги по RTC IO из глубокого сна." -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display rotation must be in 90 degree increments" -msgstr "Поворот дисплея должен осуществляться с шагом 90 градусов" +#: ports/espressif/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set." +msgstr "Можно установить только один будильник alarm.time." -#: main.c -msgid "Done" -msgstr "Выполнено" +#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c +msgid "Only one %q can be set in deep sleep." +msgstr "Только один %q может быть переведен в режим глубокого сна." -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Drive mode not used when direction is input." -msgstr "Режим движения не используется при вводе направления." +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q должен быть массивом типа 'H \"" -#: py/obj.c -msgid "During handling of the above exception, another exception occurred:" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +#: shared-bindings/audioi2sin/I2SIn.c +msgid "%q must be 8, 16, 24, or 32" msgstr "" -"При обращении с вышеуказанным исключением произошло еще одно исключение:" -#: shared-bindings/aesio/aes.c -msgid "ECB only operates on 16 bytes at a time" -msgstr "ECB работает только с 16 байтами за раз" +#: ports/espressif/common-hal/audiobusio/__init__.c +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +msgid "Peripheral in use" +msgstr "Периферийные устройства в использовании" -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/canio/CAN.c -msgid "ESP-IDF memory allocation failed" -msgstr "Ошибка выделения памяти ESP-IDF" +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 8 or 16" +msgstr "" -#: extmod/modre.c -msgid "Error in regex" -msgstr "Ошибка в регулярном выражении" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Error in safemode.py." -msgstr "Ошибка в сейфе. py." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "" -#: shared-bindings/alarm/__init__.c -msgid "Expected a kind of %q" -msgstr "Ожидаемый вид %q" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Extended advertisements with scan response not supported." -msgstr "Расширенные объявления с ответом сканирования не поддерживаются." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is defined for ndarrays only" -msgstr "FFT определено только для массивов ndarrays" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is implemented for linear arrays only" -msgstr "FFT реализовано только для линейных массивов" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "" -#: shared-bindings/ps2io/Ps2.c -msgid "Failed sending command." -msgstr "Не удалось отправить команду." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to acquire mutex, err 0x%04x" -msgstr "Не удалось получить mutex, ошибка 0x%04x" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Failed to add service TXT record" -msgstr "Не удалось добавить служебную запись TXT" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "" -#: shared-bindings/mdns/Server.c -msgid "" -"Failed to add service TXT record; non-string or bytes found in txt_records" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" msgstr "" -"Не удалось добавить служебную TXT-запись; в txt_records обнаружена нестрока " -"или байт" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "Failed to allocate %q buffer" -msgstr "Не удалось выделить буфер %q" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/nordic/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Все периферийные устройства I2C уже используются" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to allocate Wifi memory" -msgstr "Не удалось выделить память Wifi" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c +msgid "Unable to create lock" +msgstr "Не удается создать блокировку" -#: ports/espressif/common-hal/wifi/ScannedNetworks.c -msgid "Failed to allocate wifi scan memory" -msgstr "Не удалось выделить память для сканирования wifi" +#: ports/espressif/common-hal/busio/SPI.c +msgid "SPI configuration failed" +msgstr "Сбой конфигурации SPI" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Failed to buffer the sample" -msgstr "Не удалось выполнить буферизацию образца" +#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Все периферийные устройства SPI уже используются" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: internal error" -msgstr "Не удалось подключиться: внутренняя ошибка" +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/canio/CAN.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "ESP-IDF memory allocation failed" +msgstr "Ошибка выделения памяти ESP-IDF" + +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Cannot specify RTS or CTS in RS485 mode" +msgstr "Невозможно указать RTS или CTS в режиме RS485" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: timeout" -msgstr "Не удалось подключиться: таймаут" +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "RS485 inversion specified when not in RS485 mode" +msgstr "Инверсия RS485 указана, когда она не находится в режиме RS485" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Failed to parse MP3 file" -msgstr "Не удалось распарсить файл MP3" +#: ports/espressif/common-hal/canio/CAN.c +msgid "Baudrate not supported by peripheral" +msgstr "Скорость передачи данных не поддерживается периферийным устройством" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to release mutex, err 0x%04x" -msgstr "Не удалось освободить mutex, ошибка 0x%04x" +#: ports/espressif/common-hal/canio/CAN.c +msgid "All CAN peripherals are in use" +msgstr "Все периферийные устройства CAN уже используются" -#: supervisor/shared/safe_mode.c -msgid "Failed to write internal flash." -msgstr "Не удалось записать внутреннюю флэш-память." +#: ports/espressif/common-hal/canio/CAN.c +msgid "loopback + silent mode not supported by peripheral" +msgstr "" +"Замыкание на себя + бесшумный режим, не поддерживаемый периферийными " +"устройствами" -#: py/moderrno.c -msgid "File exists" -msgstr "Файл существует" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_driver_install returned esp-idf error #%d" +msgstr "twai_driver_install вернул ошибку esp-idf #%d" -#: shared-module/os/getenv.c -msgid "File not found" -msgstr "Файл не найден" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_start returned esp-idf error #%d" +msgstr "twai_start вернул ошибку esp-idf #%d" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "Filters too complex" -msgstr "Фильтры слишком сложные" +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +msgid "Must provide 5/6/5 RGB pins" +msgstr "Должен иметь 5/6/5 контактов RGB" #: ports/espressif/common-hal/dualbank/__init__.c msgid "Firmware is duplicate" @@ -1053,3416 +1467,3436 @@ msgstr "Недопустимая прошивка" msgid "Firmware is too big" msgstr "Прошивка слишком большая" -#: shared-bindings/bitmaptools/__init__.c -msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" -msgstr "" -"Для цветового пространства L8 входное растровое изображение должно иметь 8 " -"бит на пиксель" - -#: shared-bindings/bitmaptools/__init__.c -msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" -msgstr "" -"Для цветовых пространств RGB входное растровое изображение должно иметь 16 " -"бит на пиксель" - -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Format not supported" -msgstr "Формат не поддерживается" - -#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c -msgid "" -"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" -msgstr "" -"Частота должна быть 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 или 1008 " -"МГц" - -#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c -#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c -msgid "Function requires lock" -msgstr "Функция требует блокировки" +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c +msgid "no such attribute" +msgstr "нет такого атрибута" -#: ports/cxd56/common-hal/gnss/GNSS.c -msgid "GNSS init" -msgstr "Инициализация GNSS" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" +msgstr "Недопустимый параметр" #: ports/espressif/common-hal/espidf/__init__.c msgid "Generic Failure" msgstr "Общий сбой" -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Group already used" -msgstr "Группа уже используется" - -#: supervisor/shared/safe_mode.c -msgid "Hard fault: memory access or instruction error." -msgstr "Жесткая ошибка: доступ к памяти или ошибка инструкции." - -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c -#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c -#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c -msgid "Hardware in use, try alternative pins" -msgstr "Оборудование используется, попробуйте использовать другие пины" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Out of memory" +msgstr "Не хватает памяти" -#: supervisor/shared/safe_mode.c -msgid "Heap allocation when VM not running." -msgstr "Выделение кучи, когда виртуальная машина не запущена." +#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c +msgid "Invalid argument" +msgstr "Недопустимый аргумент" -#: extmod/vfs_posix_file.c py/objstringio.c -msgid "I/O operation on closed file" -msgstr "Операция ввода-вывода на закрытом файле" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Invalid size" +msgstr "Неверный размер" -#: ports/stm/common-hal/busio/I2C.c -msgid "I2C init error" -msgstr "Ошибка инициализации I2C" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Requested resource not found" +msgstr "Запрошенный ресурс не найден" -#: ports/raspberrypi/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "I2C peripheral in use" -msgstr "Периферийное устройство I2C уже используется" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Operation or feature not supported" +msgstr "Операция или функция, не поддерживаемые" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "In-buffer elements must be <= 4 bytes long" -msgstr "Элементы буфера должны быть длиной <= 4 байта" +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "Operation timed out" +msgstr "Истекло время ожидания операции" -#: shared-bindings/_pew/PewPew.c -msgid "Incorrect buffer size" -msgstr "Неправильный размер буфера" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Received response was invalid" +msgstr "Полученный ответ недействителен" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Init program size invalid" -msgstr "Неверный размер программы инициализации" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "CRC or checksum was invalid" +msgstr "CRC или контрольная сумма неправильная" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin direction conflicts with initial out pin direction" -msgstr "" -"Исходное установленное направление штифта конфликтует с исходным " -"направлением вывода" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Version was invalid" +msgstr "Версия была недействительной" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin state conflicts with initial out pin state" -msgstr "" -"Исходное установленное состояние контакта конфликтует с исходным состоянием " -"выхода" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "MAC address was invalid" +msgstr "MAC адрес был недействительным" -#: shared-bindings/bitops/__init__.c +#: ports/espressif/common-hal/espidf/__init__.c #, c-format -msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" -msgstr "Длина входного буфера (%d) должна быть кратна количеству цепочек (%d)" - -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -msgid "Input taking too long" -msgstr "Ввод занимает слишком много времени" - -#: py/moderrno.c -msgid "Input/output error" -msgstr "Ошибка ввода/вывода" - -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient authentication" -msgstr "Неполная аутентификация" +msgid "%s error 0x%x" +msgstr "%s ошибка 0x%x" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient encryption" -msgstr "Недостаточное шифрование" +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" +msgstr "Слишком длинная программа" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient memory pool for the image" -msgstr "Недостаточный объем памяти для изображения" +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/mipidsi/Bus.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/usb_host/Port.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c +msgid "%q in use" +msgstr "%q используется" -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient stream input buffer" -msgstr "Недостаточный буфер ввода потока" +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." +msgstr "Можно установить только один %q." -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Interface must be started" -msgstr "Интерфейс должен быть запущен" +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "Only one address is allowed" +msgstr "Разрешен только один адрес" -#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c -msgid "Internal audio buffer too small" -msgstr "Внутренний звуковой буфер слишком мал" +#: ports/espressif/common-hal/max3421e/Max3421E.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" +msgstr "Неизвестный код ошибки %d" -#: ports/stm/common-hal/busio/UART.c -msgid "Internal define error" -msgstr "Внутренняя ошибка определения" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS only works with built-in WiFi" +msgstr "mDNS работает только со встроенным WiFi" -#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c -msgid "Internal error" -msgstr "Внутренняя ошибка" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS already initialized" +msgstr "mDNS уже инициализирован" -#: shared-module/rgbmatrix/RGBMatrix.c -#, c-format -msgid "Internal error #%d" -msgstr "Внутренняя ошибка #%d" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Unable to start mDNS query" +msgstr "Не удается запустить запрос mDNS" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: ports/atmel-samd/common-hal/countio/Counter.c -#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c -#: ports/atmel-samd/common-hal/max3421e/Max3421E.c -#: ports/atmel-samd/common-hal/ps2io/Ps2.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-bindings/pwmio/PWMOut.c -msgid "Internal resource(s) in use" -msgstr "Используемые внутренние ресурсы" +#: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nordic/common-hal/memorymap/AddressRange.c +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" +msgstr "Диапазон адресов не разрешен" -#: supervisor/shared/safe_mode.c -msgid "Internal watchdog timer expired." -msgstr "Внутренний сторожевой таймер истек." +#: ports/espressif/common-hal/nvm/ByteArray.c +msgid "NVS Error" +msgstr "Ошибка NVS" -#: supervisor/shared/safe_mode.c -msgid "Interrupt error." -msgstr "Прерванная ошибка." +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d or %d, not %d" +msgstr "Количество выводов_данных должно быть %d или %d, а не %d" -#: shared-module/jpegio/JpegDecoder.c -msgid "Interrupted by output function" -msgstr "Прерывается функцией выхода" +#: ports/espressif/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" +msgstr "вытолкнуть из пустого импульсного входа" -#: ports/espressif/common-hal/_bleio/Service.c -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/espressif/common-hal/microcontroller/Processor.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c -#: ports/raspberrypi/bindings/picodvi/Framebuffer.c -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q" -msgstr "Недопустимый %q" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q and %q" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-bindings/pwmio/PWMOut.c +#: supervisor/shared/settings.c +msgid "Internal error" +msgstr "Внутренняя ошибка" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/Pin.c -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -#: ports/mimxrt10xx/common-hal/microcontroller/Pin.c -#: shared-bindings/microcontroller/Pin.c -msgid "Invalid %q pin" -msgstr "Недопустимый пин %q" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "" -#: ports/stm/common-hal/analogio/AnalogIn.c -msgid "Invalid ADC Unit value" -msgstr "Недопустимое значение единицы ADC" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Invalid BLE parameter" -msgstr "Недопустимый параметр BLE" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid BSSID" -msgstr "Неверный BSSID" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "Invalid MAC address" -msgstr "Неверный MAC-адрес" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c -msgid "Invalid argument" -msgstr "Недопустимый аргумент" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "" -#: shared-module/displayio/Bitmap.c -msgid "Invalid bits per value" -msgstr "Недопустимое бит-на-значение" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "" -#: shared-module/os/getenv.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "Invalid byte %.*s" -msgstr "Неверный байт %.*s" +msgid "SDIO Init Error 0x%02x" +msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c -#, c-format -msgid "Invalid data_pins[%d]" -msgstr "Неверный data_pins[%d]" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Unsupported socket type" +msgstr "Неподдерживаемый тип сокета" -#: shared-module/msgpack/__init__.c -msgid "Invalid format" -msgstr "Недопустимый формат" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Out of sockets" +msgstr "Вне розеток" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" -msgstr "Неверный размер блока формата" +#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio" +msgstr "SocketPool можно использовать только с wifi.radio" -#: shared-bindings/wifi/Radio.c -msgid "Invalid hex password" -msgstr "Неверный шестнадцатеричный пароль" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +msgid "%q must be <= %u" +msgstr "%q должно быть <= %u" + +#: ports/espressif/common-hal/wifi/Monitor.c +msgid "monitor init failed" +msgstr "Сбой инициализации монитора" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Interface must be started" +msgstr "Интерфейс должен быть запущен" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Неверный MAC-адрес многоадресной рассылки" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid size" -msgstr "Неверный размер" - -#: shared-module/ssl/SSLSocket.c -msgid "Invalid socket for TLS" -msgstr "Неверный сокет для TLS" - -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid state" -msgstr "Неверное состояние" - -#: shared-module/os/getenv.c -msgid "Invalid unicode escape" -msgstr "Недопустимое экранирование Юникода" - -#: shared-bindings/aesio/aes.c -msgid "Key must be 16, 24, or 32 bytes long" -msgstr "Ключ должен быть длинной 16, 24 или 32 байта" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Already scanning for wifi networks" +msgstr "Поиск сетей wifi уже происходит" -#: shared-module/os/getenv.c -msgid "Key not found" -msgstr "Ключ не найден" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "" -#: shared-module/is31fl3741/FrameBuffer.c -msgid "LED mappings must match display size" -msgstr "Светодиодные сопоставления должны соответствовать размеру дисплея" +#: ports/espressif/common-hal/wifi/ScannedNetworks.c +msgid "Failed to allocate wifi scan memory" +msgstr "Не удалось выделить память для сканирования wifi" -#: py/compile.c -msgid "LHS of keyword arg must be an id" -msgstr "LHS ключевого слова arg должен быть идентификатором(id)" +#: ports/espressif/common-hal/wifi/__init__.c +msgid "Failed to allocate Wifi memory" +msgstr "Не удалось выделить память Wifi" -#: shared-module/displayio/Group.c -msgid "Layer already in a group" -msgstr "Слой уже в группе (Group)" +#: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +msgid "Only IPv4 addresses supported" +msgstr "Поддерживаются только адреса IPv4" -#: shared-module/displayio/Group.c -msgid "Layer must be a Group or TileGrid subclass" -msgstr "Слой должен быть группой (Group) или субклассом TileGrid" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/busio/SPI.c +msgid "Must provide MISO or MOSI pin" +msgstr "Пин MISO или MOSI должен быть предоставлен" -#: shared-bindings/audiocore/RawSample.c -msgid "Length of %q must be an even multiple of channel_count * type_size" -msgstr "Длина %q должна быть четной, кратной количеству каналов * размер_типа" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c +#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c +#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c +msgid "Hardware in use, try alternative pins" +msgstr "Оборудование используется, попробуйте использовать другие пины" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "MAC address was invalid" -msgstr "MAC адрес был недействительным" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/espressif/common-hal/_bleio/Descriptor.c -msgid "MITM security not supported" -msgstr "Защита от MITM не поддерживается" +#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c +msgid "" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +msgstr "" +"Частота должна быть 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 или 1008 " +"МГц" -#: shared-bindings/is31fl3741/IS31FL3741.c -msgid "Mapping must be a tuple" -msgstr "Сопоставление должно быть кортежом" +#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." +msgstr "Вы нажали левую кнопку при запуске." -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched data size" -msgstr "Размер данных различается" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "timeout must be < 655.35 secs" +msgstr "таймаут должен быть < 655.35 сек" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched swap flag" -msgstr "Несоответствующий флаг подкачки" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "non-zero timeout must be > 0.01" +msgstr "Ненулевое время ожидания должно быть > 0,01" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] reads pin(s)" -msgstr "Отсутствует first_in_pin. %q[%u] читает выводы" +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: timeout" +msgstr "Не удалось подключиться: таймаут" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" -msgstr "Отсутствует first_in_pin. %q[%u] смещается от контакта (контактов)" +#: ports/nordic/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" +msgstr "Неожиданный тип nrfx uuid" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] waits based on pin" -msgstr "Отсутствует first_in_pin. Инструкция %d ожидает на основе пина" +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Nordic system firmware out of memory" +msgstr "Скандинавская система прошивки из памяти" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" -msgstr "Отсутствует first_out_pin. %q[%u] переключается на контакты" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %04x" +msgstr "Неизвестная системная ошибка прошивки: %04x" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] writes pin(s)" -msgstr "Отсутствует first_out_pin. %q[%u] записывает выводы" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown gatt error: 0x%04x" +msgstr "Неизвестная ошибка gatt: 0x%04x" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_set_pin. %q[%u] sets pin(s)" -msgstr "Отсутствует first_set_pin. %q[%u] устанавливает контакты" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +msgid "" +"Unspecified issue. The pairing request on the other device may have been " +"declined or ignored." +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing jmp_pin. %q[%u] jumps on pin" -msgstr "Не хватает jmp_pin.%q [%u] прыгает на пин" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#, c-format +msgid "Unknown security error: 0x%04x" +msgstr "Неизвестная ошибка безопасности: 0x%04x" -#: shared-module/storage/__init__.c -msgid "Mount point directory missing" -msgstr "Отсутствует каталог точки монтирования" +#: ports/nordic/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge, only level" +msgstr "" +"Невозможно проснуться по изменению логического уровня, только по уровню" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c -msgid "Must be a %q subclass." -msgstr "Должен быть субклассом %q." +#: ports/nordic/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +msgstr "Устройство используется" -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -msgid "Must provide 5/6/5 RGB pins" -msgstr "Должен иметь 5/6/5 контактов RGB" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" +msgstr "только образец_рейт=16000 поддерживается" -#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c -msgid "Must provide MISO or MOSI pin" -msgstr "Пин MISO или MOSI должен быть предоставлен" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" +msgstr "поддерживается только бит_глубина=16" -#: shared-bindings/rgbmatrix/RGBMatrix.c +#: ports/nordic/common-hal/busio/UART.c #, c-format -msgid "Must use a multiple of 6 rgb pins, not %d" -msgstr "Количество используемых rgb-пинов должно быть кратно 6, а не %d" +msgid "error = 0x%08lX" +msgstr "ошибка = 0x%08lX" -#: supervisor/shared/safe_mode.c -msgid "NLR jump failed. Likely memory corruption." -msgstr "Прыжок NLR не удался. Вероятно повреждение памяти." +#: ports/nordic/common-hal/busio/UART.c +msgid "Odd parity is not supported" +msgstr "Нечетная четность не поддерживается" -#: ports/espressif/common-hal/nvm/ByteArray.c -msgid "NVS Error" -msgstr "Ошибка NVS" +#: ports/nordic/common-hal/countio/Counter.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +msgid "All channels in use" +msgstr "Все каналы уже используются" -#: shared-bindings/socketpool/SocketPool.c -msgid "Name or service not known" -msgstr "Имя или услуга не известны" +#: ports/nordic/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "Невозможно получить температуру" -#: shared-bindings/displayio/TileGrid.c -msgid "New bitmap must be same size as old bitmap" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" -"Новое растровое изображение должно быть того же размера, что и старое " -"растровое изображение" +"Сторожевой таймер не может быть деинициализирован, если установлен режим " +"RESET" -#: ports/espressif/common-hal/_bleio/__init__.c -msgid "Nimble out of memory" -msgstr "Изображение памяти" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "timeout duration exceeded the maximum supported value" +msgstr "" +"Продолжительность таймаута превысила максимальное поддерживаемое значение" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c -#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c -#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c -#: shared-bindings/paralleldisplaybus/ParallelBus.c -#: shared-module/bitbangio/SPI.c -msgid "No %q pin" -msgstr "Нет пина %q" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "%q cannot be changed once mode is set to %q" +msgstr "%q не может быть изменен после установки режима на %q" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "No CCCD for this Characteristic" -msgstr "Для этой характеристики нет CCCD" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Не удалось получить mutex, ошибка 0x%04x" -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "No DAC on chip" -msgstr "DAC отсутствует на чипе" +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Не удалось освободить mutex, ошибка 0x%04x" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA channel found" -msgstr "Канал DMA не найден" +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "Преобразование звука не реализовано" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA pacing timer found" -msgstr "Таймер стимуляции DMA не найден" +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c +#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c +#: shared-module/synthio/Synthesizer.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q должно быть типа%q или%q, а не%q" -#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c -#, c-format -msgid "No I2C device at address: 0x%x" -msgstr "Нет устройства I2C по адресу: %x" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Program size invalid" +msgstr "Недопустимый размер программы" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "No IP" -msgstr "Нет IP" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Init program size invalid" +msgstr "Неверный размер программы инициализации" -#: ports/atmel-samd/common-hal/microcontroller/__init__.c -#: ports/cxd56/common-hal/microcontroller/__init__.c -#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c -msgid "No bootloader present" -msgstr "Отсутствует загрузчик" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Buffer elements must be 4 bytes long or less" +msgstr "Элементы буфера должны иметь длину не более 4 байт" -#: shared-module/usb/core/Device.c -msgid "No configuration set" -msgstr "Нет конфигураций" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched data size" +msgstr "Размер данных различается" -#: shared-bindings/_bleio/PacketBuffer.c -msgid "No connection: length cannot be determined" -msgstr "Нет соединения: длина не может быть определена" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Out-buffer elements must be <= 4 bytes long" +msgstr "Элементы вне буфера должны иметь длину <= 4 байта" -#: shared-bindings/board/__init__.c -msgid "No default %q bus" -msgstr "Нет шины %q по умолчанию" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "In-buffer elements must be <= 4 bytes long" +msgstr "Элементы буфера должны быть длиной <= 4 байта" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -msgid "No free GCLKs" -msgstr "Свободные GCLK отсутствуют" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/I2C.c +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/I2C.c +#: shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "Функция требует блокировки" -#: shared-bindings/os/__init__.c -msgid "No hardware random available" -msgstr "Отсутствует аппаратный генератор случайных чисел" +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" +msgstr "Буферные фрагменты должны быть одинаковой длины" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in in program" -msgstr "Нет в программе" +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c +#: ports/stm/common-hal/alarm/touch/TouchAlarm.c +msgid "Touch alarms not available" +msgstr "Сенсорные сигналы недоступны" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c #: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in or out in program" -msgstr "В программе отсутствует ввод или вывод" +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "Невозможно использовать GPIO0..15 вместе с GPIO32..47" -#: py/objint.c shared-bindings/time/__init__.c -msgid "No long integer support" -msgstr "Нет поддержки длинных целых чисел (long integer)" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "Bit clock and word select must be sequential GPIO pins" +msgstr "Несколько часов и слов должны быть последовательными GPIO пинами" -#: shared-bindings/wifi/Radio.c -msgid "No network with that ssid" -msgstr "Нет сети с этим ssid" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Too many channels in sample." +msgstr "Слишком много каналов в выборке." -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No out in program" -msgstr "В программе отсутствует вывод" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Audio source error" +msgstr "" + +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 16, 24, or 32" +msgstr "" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" +msgstr "Пины должны иметь общий срез PWM" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" +msgstr "Таймер стимуляции DMA не найден" -#: ports/atmel-samd/common-hal/busio/I2C.c -#: ports/espressif/common-hal/busio/I2C.c -#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c #: ports/raspberrypi/common-hal/busio/I2C.c -msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "На SDA или SCL не обнаружено подтягивания; проверь свою проводку" +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "I2C peripheral in use" +msgstr "Периферийное устройство I2C уже используется" -#: shared-module/touchio/TouchIn.c -msgid "No pulldown on pin; 1Mohm recommended" -msgstr "Отсутствует подтяжка к земле на пине; Рекомендуется 1 Мегаом" +#: ports/raspberrypi/common-hal/busio/SPI.c +msgid "SPI peripheral in use" +msgstr "Используемое периферийное устройство SPI" -#: py/moderrno.c -msgid "No space left on device" -msgstr "На устройстве не осталось свободного места" +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" +msgstr "Используемое периферийное устройство UART" -#: py/moderrno.c -msgid "No such device" -msgstr "Нет такого устройства" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "Pin must be on PWM Channel B" +msgstr "Пин должен быть на канале ШИМ B" -#: py/moderrno.c -msgid "No such file/directory" -msgstr "Файл/директория не существует" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "RISE_AND_FALL not available on this chip" +msgstr "RISE_AND_FALL недоступен на этом чипе" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "No timer available" -msgstr "Нет доступного таймера" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice already in use" +msgstr "PWM уже используется" -#: shared-module/usb/core/Device.c -msgid "No usb host port initialized" -msgstr "Порт USB-хоста не инициализирован" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice channel A already in use" +msgstr "PWM канал среза A уже используется" + +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All state machines in use" +msgstr "Все машины состояний уже используются" + +#: ports/raspberrypi/common-hal/floppyio/__init__.c +msgid "timeout waiting for flux" +msgstr "таймаут ожидания потока" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Nordic system firmware out of memory" -msgstr "Скандинавская система прошивки из памяти" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: shared-module/floppyio/__init__.c +msgid "timeout waiting for index pulse" +msgstr "таймаут ожидания индексного импульса" -#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string" -msgstr "Недействительная строка IP" +#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +msgid "Pins must be sequential" +msgstr "Пины должны быть последовательными" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "Not connected" -msgstr "Не подключено" +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +msgid "Invalid %q and %q" +msgstr "Недопустимые %q и %q" -#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c -#: shared-bindings/audiopwmio/PWMAudioOut.c -msgid "Not playing" -msgstr "Не воспроизводится (Not playing)" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Failed to add service TXT record" +msgstr "Не удалось добавить служебную запись TXT" -#: shared-module/jpegio/JpegDecoder.c -msgid "Not supported JPEG standard" -msgstr "Не поддерживается Стандарт JPEG" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" +msgstr "Отсутствуют сервисные слоты MDNS" -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#, c-format -msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to access unaligned IO register" +msgstr "Невозможно получить доступ к невыровненному регистру ввода-вывода" -#: shared-bindings/util.c -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." -msgstr "" -"Объект был деинициализирован и больше не может быть использован. Создайте " -"новый объект." +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to write to read-only memory" +msgstr "Невозможно записать в постоянную память" -#: ports/nordic/common-hal/busio/UART.c -msgid "Odd parity is not supported" -msgstr "Нечетная четность не поддерживается" +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +msgid "All timers for this pin are in use" +msgstr "Все таймеры для этого пина уже используются" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Off" -msgstr "Выключено" +#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c +msgid "Pins must be sequential GPIO pins" +msgstr "Пины должны быть последовательными выводами GPIO" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Ok" -msgstr "Да" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Pin count too large" +msgstr "Слишком большое количество пинов" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -#, c-format -msgid "Only 8 or 16 bit mono with %dx oversampling supported." -msgstr "Поддерживается только 8 или 16-битное моно с передискретизацией %dx." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing jmp_pin. %q[%u] jumps on pin" +msgstr "Не хватает jmp_pin.%q [%u] прыгает на пин" -#: ports/espressif/common-hal/wifi/__init__.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -msgid "Only IPv4 addresses supported" -msgstr "Поддерживаются только адреса IPv4" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] uses extra pin" +msgstr "%q[%u] использует дополнительный контакт" -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Only IPv4 sockets supported" -msgstr "Поддерживаются только сокеты IPv4" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] waits based on pin" +msgstr "Отсутствует first_in_pin. Инструкция %d ожидает на основе пина" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only Windows format, uncompressed BMP supported: given header size is %d" -msgstr "" -"Поддерживается только формат Windows, несжатый BMP: заданный размер " -"заголовка - %d" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] waits on input outside of count" +msgstr "%q [%u] ожидает ввода за пределами графа" -#: shared-bindings/_bleio/Adapter.c -msgid "Only connectable advertisements can be directed" -msgstr "Только подключаемые объявления могут быть направлены" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +msgstr "Отсутствует first_in_pin. %q[%u] смещается от контакта (контактов)" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Only edge detection is available on this hardware" -msgstr "На этом аппаратном обеспечении доступно только обнаружение края" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts in more bits than pin count" +msgstr "%q [%u] смещается в большем количестве чем количество пинов" -#: shared-bindings/ipaddress/__init__.c -msgid "Only int or string supported for ip" -msgstr "Для IP поддерживаются только int или строка" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +msgstr "Отсутствует first_out_pin. %q[%u] переключается на контакты" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Только монохром, индексированный 4bpp или 8bpp, и 16bpp или больше BMP " -"поддерживаются: %d bpp" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts out more bits than pin count" +msgstr "%q[%u] смещает больше битов чем количество выводов" -#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one %q can be set in deep sleep." -msgstr "Только один %q может быть переведен в режим глубокого сна." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_set_pin. %q[%u] sets pin(s)" +msgstr "Отсутствует first_set_pin. %q[%u] устанавливает контакты" -#: ports/espressif/common-hal/espulp/ULPAlarm.c -msgid "Only one %q can be set." -msgstr "Можно установить только один %q." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] writes pin(s)" +msgstr "Отсутствует first_out_pin. %q[%u] записывает выводы" -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "Only one address is allowed" -msgstr "Разрешен только один адрес" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] reads pin(s)" +msgstr "Отсутствует first_in_pin. %q[%u] читает выводы" -#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c -#: ports/nordic/common-hal/alarm/time/TimeAlarm.c -#: ports/stm/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set" -msgstr "Можно установить только один будильник" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does IN without loading ISR" +msgstr "Программа выполняет IN без загрузки ISR" -#: ports/espressif/common-hal/alarm/time/TimeAlarm.c -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set." -msgstr "Можно установить только один будильник alarm.time." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does OUT without loading OSR" +msgstr "Программа выполняет ВЫХОД без загрузки OSR" -#: shared-module/displayio/ColorConverter.c -msgid "Only one color can be transparent at a time" -msgstr "Только один цвет может быть прозрачным одновременно" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin state conflicts with initial out pin state" +msgstr "" +"Исходное установленное состояние контакта конфликтует с исходным состоянием " +"выхода" -#: py/moderrno.c -msgid "Operation not permitted" -msgstr "Операция не разрешена" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin direction conflicts with initial out pin direction" +msgstr "" +"Исходное установленное направление штифта конфликтует с исходным " +"направлением вывода" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation or feature not supported" -msgstr "Операция или функция, не поддерживаемые" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "pull masks conflict with direction masks" +msgstr "Маски вытягивания конфликтуют с масками направления" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Operation timed out" -msgstr "Истекло время ожидания операции" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No out in program" +msgstr "В программе отсутствует вывод" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Out of MDNS service slots" -msgstr "Отсутствуют сервисные слоты MDNS" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in in program" +msgstr "Нет в программе" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Out of memory" -msgstr "Не хватает памяти" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in or out in program" +msgstr "В программе отсутствует ввод или вывод" -#: ports/espressif/common-hal/socketpool/Socket.c -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Out of sockets" -msgstr "Вне розеток" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched swap flag" +msgstr "Несоответствующий флаг подкачки" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Out-buffer elements must be <= 4 bytes long" -msgstr "Элементы вне буфера должны иметь длину <= 4 байта" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d, not %d" +msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "PWM restart" -msgstr "PWM перезагрузка" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +msgid "Data pins must be consecutive" +msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "PWM slice already in use" -msgstr "PWM уже используется" +#: ports/raspberrypi/common-hal/socketpool/Socket.c +msgid "Only IPv4 sockets supported" +msgstr "Поддерживаются только сокеты IPv4" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "PWM slice channel A already in use" -msgstr "PWM канал среза A уже используется" +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All dma channels in use" +msgstr "Все используемые каналы dma" -#: shared-module/jpegio/JpegDecoder.c -msgid "Parameter error" -msgstr "Ошибка параметра" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" +msgstr "Wi-Fi. Монитор недоступен" -#: ports/espressif/common-hal/audiobusio/__init__.c -msgid "Peripheral in use" -msgstr "Периферийные устройства в использовании" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q читается только для этой доски" -#: py/moderrno.c -msgid "Permission denied" -msgstr "Отказано в разрешении" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "AP could not be started" +msgstr "AP не может быть запущен" #: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Pin cannot wake from Deep Sleep" -msgstr "Пин не может вывести из глубокого сна" - -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Pin count too large" -msgstr "Слишком большое количество пинов" +msgid "Only edge detection is available on this hardware" +msgstr "На этом аппаратном обеспечении доступно только обнаружение края" #: ports/stm/common-hal/alarm/pin/PinAlarm.c #: ports/stm/common-hal/pulseio/PulseIn.c -msgid "Pin interrupt already in use" -msgstr "Прерывание пина уже используется" - -#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -msgid "Pin is input only" -msgstr "Пин является только входом" +msgid "Pin interrupt already in use" +msgstr "Прерывание пина уже используется" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "Pin must be on PWM Channel B" -msgstr "Пин должен быть на канале ШИМ B" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Pin cannot wake from Deep Sleep" +msgstr "Пин не может вывести из глубокого сна" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"Pinout uses %d bytes per element, which consumes more than the ideal %d " -"bytes. If this cannot be avoided, pass allow_inefficient=True to the " -"constructor" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Deep sleep pins must use a rising edge with pulldown" msgstr "" -"Распиновка использует %d байт на элемент, что превышает идеальное %d байт. " -"Если этого нельзя избежать, передайте конструктору allow_inefficient=True" +"Выводы глубокого сна должны использовать сигнал по возрастанию с подтяжкой к " +"земле" -#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c -msgid "Pins must be sequential" -msgstr "Пины должны быть последовательными" +#: ports/stm/common-hal/analogio/AnalogIn.c +msgid "Invalid ADC Unit value" +msgstr "Недопустимое значение единицы ADC" -#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c -msgid "Pins must be sequential GPIO pins" -msgstr "Пины должны быть последовательными выводами GPIO" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Device Init Error" +msgstr "Ошибка инициализации устройства DAC" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Pins must share PWM slice" -msgstr "Пины должны иметь общий срез PWM" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Channel Init Error" +msgstr "Ошибка инициализации канала DAC" -#: shared-module/usb/core/Device.c -msgid "Pipe error" -msgstr "Ошибка трубопровода" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" +msgstr "Поддерживается только моно" -#: py/builtinhelp.c -msgid "Plus any modules on the filesystem\n" -msgstr "Плюс любые модули в файловой системе\n" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" +msgstr "поддерживается только выборка = 64" -#: shared-module/vectorio/Polygon.c -msgid "Polygon needs at least 3 points" -msgstr "Полигону необходимо как минимум 3 точки" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Another PWMAudioOut is already active" +msgstr "Другой аудиовыход PWM уже активен" -#: supervisor/shared/safe_mode.c -msgid "Power dipped. Make sure you are providing enough power." -msgstr "" -"Мощность просела. Убедитесь, что вы обеспечиваете достаточную мощность." +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +#, c-format +msgid "Buffer length %d too big. It must be less than %d" +msgstr "Размер буфера %d слишком большой. Он должен быть меньше чем %d" -#: shared-bindings/_bleio/Adapter.c -msgid "Prefix buffer must be on the heap" -msgstr "Буфер префикса должен находиться в куче" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Failed to buffer the sample" +msgstr "Не удалось выполнить буферизацию образца" -#: main.c -msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" -msgstr "" -"Нажмите любую клавишу чтобы зайти в REPL. Используйте CTRL-D для " -"перезагрузки.\n" +#: ports/stm/common-hal/busio/I2C.c +msgid "I2C init error" +msgstr "Ошибка инициализации I2C" -#: main.c -msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" -msgstr "" -"Притворяюсь глубоким сном до сигнала тревоги, CTRL-C или записи файла.\n" +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI init error" +msgstr "Ошибка инициализации SPI" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does IN without loading ISR" -msgstr "Программа выполняет IN без загрузки ISR" +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI re-init" +msgstr "Повторная инициализация SPI" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does OUT without loading OSR" -msgstr "Программа выполняет ВЫХОД без загрузки OSR" +#: ports/stm/common-hal/busio/UART.c +msgid "Internal define error" +msgstr "Внутренняя ошибка определения" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Program size invalid" -msgstr "Недопустимый размер программы" +#: ports/stm/common-hal/busio/UART.c +msgid "Could not start interrupt, RX busy" +msgstr "Не удалось запустить прерывание, RX занят" -#: ports/espressif/common-hal/espulp/ULP.c -msgid "Program too long" -msgstr "Слишком длинная программа" +#: ports/stm/common-hal/busio/UART.c +msgid "UART write" +msgstr "Запись UART" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Pull not used when direction is output." -msgstr "Тяга не используется, когда выводится направление." +#: ports/stm/common-hal/busio/UART.c +msgid "UART de-init" +msgstr "Деинициализация UART" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "RISE_AND_FALL not available on this chip" -msgstr "RISE_AND_FALL недоступен на этом чипе" +#: ports/stm/common-hal/busio/UART.c +msgid "UART re-init" +msgstr "Повторная инициализация UART" -#: shared-module/displayio/OnDiskBitmap.c -msgid "RLE-compressed BMP not supported" -msgstr "RLE-сжатый BMP не поддерживается" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Temperature read timed out" +msgstr "Истекло время ожидания считывания температуры" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG DeInit Error" -msgstr "Ошибка деинициализации генератора случайных чисел" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Voltage read timed out" +msgstr "Истекло время ожидания считывания напряжения" #: ports/stm/common-hal/os/__init__.c msgid "RNG Init Error" msgstr "Ошибка инициализации RNG" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" -msgstr "RS485" - -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "RS485 inversion specified when not in RS485 mode" -msgstr "Инверсия RS485 указана, когда она не находится в режиме RS485" - -#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c -msgid "RTC is not supported on this board" -msgstr "RTC не поддерживается на этой плате" - #: ports/stm/common-hal/os/__init__.c msgid "Random number generation error" msgstr "Ошибка генерации случайных чисел" -#: shared-bindings/_bleio/__init__.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c -#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c -msgid "Read-only" -msgstr "Только для чтения" - -#: extmod/vfs_fat.c py/moderrno.c -msgid "Read-only filesystem" -msgstr "Файловая система только для чтения" - -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Received response was invalid" -msgstr "Полученный ответ недействителен" - -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Reconnecting" -msgstr "Повторное соединение" - -#: shared-bindings/epaperdisplay/EPaperDisplay.c -msgid "Refresh too soon" -msgstr "Слишком раннее обновление" - -#: shared-bindings/canio/RemoteTransmissionRequest.c -msgid "RemoteTransmissionRequests limited to 8 bytes" -msgstr "Запросы на удаленную передачу ограничены 8 байтами" - -#: shared-bindings/aesio/aes.c -msgid "Requested AES mode is unsupported" -msgstr "Запрошенный режим AES не поддерживается" - -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Requested resource not found" -msgstr "Запрошенный ресурс не найден" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "Right channel unsupported" -msgstr "Правый канал не поддерживается" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG DeInit Error" +msgstr "Ошибка деинициализации генератора случайных чисел" -#: shared-module/jpegio/JpegDecoder.c -msgid "Right format but not supported" -msgstr "Правильный формат, но не поддерживается" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "timer re-init" +msgstr "Повторное инициализация таймера" -#: main.c -msgid "Running in safe mode! Not running saved code.\n" -msgstr "Работает в безопасном режиме! Сохраненный код не выполняется.\n" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "channel re-init" +msgstr "Реинициализация канала" -#: shared-module/sdcardio/SDCard.c -msgid "SD card CSD format not supported" -msgstr "Формат CSD SD-карты не поддерживается" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "PWM restart" +msgstr "PWM перезагрузка" -#: ports/cxd56/common-hal/sdioio/SDCard.c -msgid "SDCard init" -msgstr "Инициализация SD-карты" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO GetCardInfo Error %d" msgstr "Ошибка получения информации о карте SDIO %d" -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO Init Error %x" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid ".show(x) removed. Use .root_group = x" +msgstr ". Показать(x) удален. Используйте . корневую_группу = x" -#: ports/espressif/common-hal/busio/SPI.c -msgid "SPI configuration failed" -msgstr "Сбой конфигурации SPI" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Brightness not adjustable" +msgstr "Яркость не регулируется" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI init error" -msgstr "Ошибка инициализации SPI" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c py/argcheck.c +#: shared-bindings/busdisplay/BusDisplay.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "%q must be %d-%d" +msgstr "%q должно быть %d-%d" -#: ports/raspberrypi/common-hal/busio/SPI.c -msgid "SPI peripheral in use" -msgstr "Используемое периферийное устройство SPI" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Group already used" +msgstr "Группа уже используется" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI re-init" -msgstr "Повторная инициализация SPI" +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Invalid advertising data" +msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "Scale dimensions must divide by 3" -msgstr "Размеры шкалы необходимо разделить на 3" +#: ports/zephyr-cp/common-hal/audiobusio/I2SOut.c +#: ports/zephyr-cp/common-hal/busio/I2C.c +#: ports/zephyr-cp/common-hal/busio/SPI.c +#: ports/zephyr-cp/common-hal/busio/UART.c +msgid "Use device tree to define %q devices" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Scan already in progress. Stop with stop_scan." -msgstr "Сканирование уже выполняется. Остановитесь на stop_scan." +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -msgid "Serializer in use" -msgstr "Сериализатор используется" +#: ports/zephyr-cp/common-hal/usb_hid/Device.c shared-module/usb_hid/Device.c +msgid "USB error" +msgstr "Ошибка USB" -#: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname" -msgstr "Контекст на стороне сервера не может иметь имя хоста" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Size not supported" -msgstr "Размер не поддерживается" +#: ports/zephyr-cp/common-hal/zephyr_display/Display.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Below minimum frame rate" +msgstr "Ниже минимальной частоты кадров" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Slice and value different lengths." -msgstr "Нарежьте и оцените разную длину." +#: py/argcheck.c +msgid "function doesn't take keyword arguments" +msgstr "функция не принимает аргументы ключевых слов" -#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/TileGrid.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Slices not supported" -msgstr "Фрагменты не поддерживаются" +#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c +#: shared-bindings/time/__init__.c +#, c-format +msgid "function takes %d positional arguments but %d were given" +msgstr "функция принимает %d позиционные аргументы, но %d были заданы" -#: ports/espressif/common-hal/socketpool/SocketPool.c -#: ports/raspberrypi/common-hal/socketpool/SocketPool.c -msgid "SocketPool can only be used with wifi.radio" -msgstr "SocketPool можно использовать только с wifi.radio" +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" +msgstr "Функция отсутствует %d обязательные позиционные аргументы" -#: shared-bindings/aesio/aes.c -msgid "Source and destination buffers must be the same length" -msgstr "Исходный и конечный буферы должны иметь одинаковую длину" +#: py/argcheck.c +#, c-format +msgid "function expected at most %d arguments, got %d" +msgstr "функция, ожидаемая в большинстве %d аргументов, получила %d" -#: shared-bindings/paralleldisplaybus/ParallelBus.c -msgid "Specify exactly one of data0 or data_pins" -msgstr "Укажите точно один из data0 или data_pins" +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "Требуется аргумент '%q'" -#: supervisor/shared/safe_mode.c -msgid "Stack overflow. Increase stack size." -msgstr "Переполнение стека. Увеличьте размер стека." +#: py/argcheck.c +msgid "extra positional arguments given" +msgstr "Приведены дополнительные позиционные аргументы" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Supply one of monotonic_time or epoch_time" -msgstr "Поставьте один из monotonic_time или epoch_time" +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c +msgid "unexpected keyword argument '%q'" +msgstr "неожиданный аргумент ключевого слова '%q'" -#: shared-bindings/gnss/GNSS.c -msgid "System entry must be gnss.SatelliteSystem" -msgstr "Системная запись должна быть gnss. Спутниковая система" +#: py/argcheck.c +msgid "extra keyword arguments given" +msgstr "Приведены дополнительные аргументы ключевых слов" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Temperature read timed out" -msgstr "Истекло время ожидания считывания температуры" +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c +msgid "argument num/types mismatch" +msgstr "Аргумент Несоответствие числа/типов" -#: supervisor/shared/safe_mode.c -msgid "The `microcontroller` module was used to boot into safe mode." +#: py/argcheck.c +msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" -"Модуль «микроконтроллер» использовался для загрузки в безопасном режиме." +"Аргумент(ы) ключевого слова не реализован - используйте вместо него обычные " +"аргументы" -#: py/obj.c -msgid "The above exception was the direct cause of the following exception:" -msgstr "" -"Вышеупомянутое исключение было непосредственной причиной следующего " -"исключения:" +#: py/argcheck.c +msgid "%q must be %d" +msgstr "%q должно быть %d" -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" -msgstr "Длина rgb_pins должна быть 6, 12, 18, 24 или 30" +#: py/argcheck.c +msgid "%q must be >= %d" +msgstr "%q должно быть >= %d" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Bits_per_sample сэмпла не соответствует битам микшера" +#: py/argcheck.c shared-bindings/gifio/GifWriter.c +#: shared-module/gifio/OnDiskGif.c +msgid "%q must be <= %d" +msgstr "%q должно быть <= %d" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Количество каналов образца не совпадает с количеством каналов микшера" +#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c +#: shared-module/synthio/__init__.c +msgid "%q must be of type %q, not %q" +msgstr "%q должно быть типа %q, а не %q" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "Частота дискретизации семпла не соответствует частоте микшера" +#: py/argcheck.c +msgid "%q length must be %d-%d" +msgstr "Длинна %q должна быть %d-%d" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "Подпись семпла не совпадает с подписью микшера" +#: py/argcheck.c +msgid "%q length must be >= %d" +msgstr "Длинна %q должна быть >= %d" -#: supervisor/shared/safe_mode.c -msgid "Third-party firmware fatal error." -msgstr "Неустранимая ошибка прошивки стороннего производителя." +#: py/argcheck.c +msgid "%q length must be <= %d" +msgstr "Длинна %q должна быть <= %d" -#: shared-module/imagecapture/ParallelImageCapture.c -msgid "This microcontroller does not support continuous capture." -msgstr "Этот микроконтроллер не поддерживает непрерывный захват." +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" +msgstr "Длинна %q должна быть %d" -#: shared-module/paralleldisplaybus/ParallelBus.c -msgid "" -"This microcontroller only supports data0=, not data_pins=, because it " -"requires contiguous pins." +#: py/argcheck.c shared-module/audiofilters/Filter.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q в %q должно быть типа %q, а не %q" + +#: py/asmthumb.c +msgid "too many locals for native method" +msgstr "Слишком много местных жителей для нативного метода" + +#: py/asmxtensa.c +msgid "ERROR: xtensa %q out of range" msgstr "" -"Этот микроконтроллер поддерживает только data0=, а не data_pins=, поскольку " -"для него требуются смежные выводы." -#: shared-bindings/displayio/TileGrid.c -msgid "Tile height must exactly divide bitmap height" -msgstr "Высота плитки должна точно делить высоту растрового изображения" +#: py/asmxtensa.c +msgid "ERROR: %q %q not word-aligned" +msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c -msgid "Tile index out of bounds" -msgstr "Выход индекса плитки за пределы" +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q() принимает %d позиционных аргументов, но было передано %d" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile width must exactly divide bitmap width" -msgstr "Ширина плитки должна точно делить ширину растрового изображения" +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" +msgstr "функция имеет несколько значений для аргументации%q \"" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Time is in the past." -msgstr "Время в прошлом." +#: py/bc.c +msgid "unexpected keyword argument" +msgstr "Неожиданный аргумент ключевого слова" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c +#: py/bc.c #, c-format -msgid "Timeout is too long: Maximum timeout length is %d seconds" -msgstr "Таймаут слишком длинный: максимальная длина таймаута %d секунд" +msgid "function missing required positional argument #%d" +msgstr "В функции отсутствует обязательный позиционный аргумент #%d" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample" -msgstr "Слишком много каналов в выборке" +#: py/bc.c +msgid "function missing required keyword argument '%q'" +msgstr "В функции отсутствует обязательный аргумент ключевого слова '%q'" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample." -msgstr "Слишком много каналов в выборке." +#: py/bc.c +msgid "function missing keyword-only argument" +msgstr "функция отсутствует аргумент только по ключевому слову" -#: ports/espressif/common-hal/_bleio/Characteristic.c -msgid "Too many descriptors" -msgstr "Слишком много дескрипторов" +#: py/binary.c py/objarray.c +msgid "bad typecode" +msgstr "Неверный шрифт" -#: shared-module/displayio/__init__.c -msgid "Too many display busses; forgot displayio.release_displays() ?" -msgstr "Слишком много шин дисплея; забыл displayio.release_displays()?" +#: py/builtinevex.c +msgid "bad compile mode" +msgstr "Неверный режим компиляции" -#: shared-module/displayio/__init__.c -msgid "Too many displays" -msgstr "Слишком много дисплеев" +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" +msgstr "Плюс любые модули в файловой системе\n" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than %q" -msgstr "Общее количество данных для записи превышает %q" +#: py/builtinhelp.c +msgid "object " +msgstr "объект " -#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c -#: ports/stm/common-hal/alarm/touch/TouchAlarm.c -msgid "Touch alarms not available" -msgstr "Сенсорные сигналы недоступны" +#: py/builtinhelp.c +msgid " is of type %q\n" +msgstr " имеет тип %q\n" -#: py/obj.c -msgid "Traceback (most recent call last):\n" -msgstr "Трассировка (последний вызов):\n" +#: py/builtinhelp.c +#, c-format +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Visit circuitpython.org for more information.\n" +"\n" +"To list built-in modules type `help(\"modules\")`.\n" +msgstr "" +"Добро пожаловать в Adafruit CircuitPython %s! \n" +"\n" +"Посетите circuitpython.org для получения дополнительной информации. \n" +"\n" +"Чтобы получить список встроенных модулей, введите 'help(\"modules\")'.\n" -#: ports/stm/common-hal/busio/UART.c -msgid "UART de-init" -msgstr "Деинициализация UART" +#: py/builtinimport.c +msgid "script compilation not supported" +msgstr "Компиляция скриптов не поддерживается" -#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c -#: ports/stm/common-hal/busio/UART.c -msgid "UART init" -msgstr "Инициализация UART" +#: py/builtinimport.c +msgid "can't perform relative import" +msgstr "Не удается выполнить относительный импорт" + +#: py/builtinimport.c +msgid "module not found" +msgstr "модуль не найден" + +#: py/builtinimport.c +msgid "no module named '%q'" +msgstr "Нет модуля с именем '%Q'" + +#: py/builtinimport.c +msgid "relative import" +msgstr "Относительный импорт" -#: ports/raspberrypi/common-hal/busio/UART.c -msgid "UART peripheral in use" -msgstr "Используемое периферийное устройство UART" +#: py/compile.c +msgid "can't assign to expression" +msgstr "Не удается назначить выражение" -#: ports/stm/common-hal/busio/UART.c -msgid "UART re-init" -msgstr "Повторная инициализация UART" +#: py/compile.c +msgid "multiple *x in assignment" +msgstr "Несколько *x в назначении" -#: ports/stm/common-hal/busio/UART.c -msgid "UART write" -msgstr "Запись UART" +#: py/compile.c +msgid "non-default argument follows default argument" +msgstr "" +"Аргумент отличный от аргумента по умолчанию следует за аргументом по " +"умолчанию" -#: main.c -msgid "UID:" -msgstr "UID:" +#: py/compile.c +msgid "invalid micropython decorator" +msgstr "неверный декоратор микропитона" -#: shared-module/usb_hid/Device.c -msgid "USB busy" -msgstr "USB занят" +#: py/compile.c +msgid "invalid arch" +msgstr "недействительная арка" -#: supervisor/shared/safe_mode.c -msgid "USB devices need more endpoints than are available." -msgstr "USB-устройствам требуется больше конечных точек, чем доступно." +#: py/compile.c +msgid "can't delete expression" +msgstr "Не удается удалить выражение" -#: supervisor/shared/safe_mode.c -msgid "USB devices specify too many interface names." -msgstr "USB-устройства указывают слишком много имен интерфейсов." +#: py/compile.c +msgid "'break'/'continue' outside loop" +msgstr "'прервать'/'продолжить' вне цикла" -#: shared-module/usb_hid/Device.c -msgid "USB error" -msgstr "Ошибка USB" +#: py/compile.c +msgid "'return' outside function" +msgstr "«возврат» внешняя функция" -#: shared-bindings/_bleio/UUID.c -msgid "UUID integer value must be 0-0xffff" -msgstr "Целое значение UUID должно быть равно 0-0xffff" +#: py/compile.c +msgid "import * not at module level" +msgstr "Импорт * не на уровне модуля" -#: shared-bindings/_bleio/UUID.c -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" -msgstr "UUID строка не 'xxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxxx \"" +#: py/compile.c +msgid "identifier redefined as global" +msgstr "идентификатор переопределен как глобальный" -#: shared-bindings/_bleio/UUID.c -msgid "UUID value is not str, int or byte buffer" -msgstr "Значение UUID не является строковым, целым или байтовым буфером" +#: py/compile.c +msgid "no binding for nonlocal found" +msgstr "Привязка для нелокальных не найдена" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to access unaligned IO register" -msgstr "Невозможно получить доступ к невыровненному регистру ввода-вывода" +#: py/compile.c +msgid "identifier redefined as nonlocal" +msgstr "идентификатор переопределен как нелокальный" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Unable to allocate buffers for signed conversion" -msgstr "Не удается выделить буферы для подписанного преобразования" +#: py/compile.c +msgid "can't declare nonlocal in outer code" +msgstr "не может объявить нелокальный во внешнем коде" -#: supervisor/shared/safe_mode.c -msgid "Unable to allocate to the heap." -msgstr "Невозможно выделить место в куче." +#: py/compile.c +msgid "default 'except' must be last" +msgstr "по умолчанию \"за исключением\" должно быть последним" -#: ports/espressif/common-hal/busio/I2C.c -msgid "Unable to create lock" -msgstr "Не удается создать блокировку" +#: py/compile.c +msgid "async for/with outside async function" +msgstr "async для/вместе с внешней async-функцией" -#: shared-module/i2cdisplaybus/I2CDisplayBus.c -#: shared-module/is31fl3741/IS31FL3741.c -#, c-format -msgid "Unable to find I2C Display at %x" -msgstr "Не удается найти дисплей I2C в %x" +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x должно быть целью назначения" -#: py/parse.c -msgid "Unable to init parser" -msgstr "Не удается инициировать синтаксический анализатор" +#: py/compile.c +msgid "super() can't find self" +msgstr "super() не может найти себя" -#: shared-module/displayio/OnDiskBitmap.c -msgid "Unable to read color palette data" -msgstr "Не удается прочитать данные цветовой палитры" +#: py/compile.c +msgid "* arg after **" +msgstr "* аргумент после **" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Unable to start mDNS query" -msgstr "Не удается запустить запрос mDNS" +#: py/compile.c +msgid "too many args" +msgstr "слишком много аргументов" -#: shared-bindings/nvm/ByteArray.c -msgid "Unable to write to nvm." -msgstr "Невозможно выполнить запись в nvm." +#: py/compile.c +msgid "LHS of keyword arg must be an id" +msgstr "LHS ключевого слова arg должен быть идентификатором(id)" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to write to read-only memory" -msgstr "Невозможно записать в постоянную память" +#: py/compile.c +msgid "positional arg after **" +msgstr "позиционный аргумент после **" -#: shared-bindings/alarm/SleepMemory.c -msgid "Unable to write to sleep_memory." -msgstr "Невозможно записать в Sleep_memory." +#: py/compile.c +msgid "positional arg after keyword arg" +msgstr "позиционный аргумент после ключевого слова аргумента" -#: ports/nordic/common-hal/_bleio/UUID.c -msgid "Unexpected nrfx uuid type" -msgstr "Неожиданный тип nrfx uuid" +#: py/compile.c py/parse.c +msgid "invalid syntax" +msgstr "недействительный синтаксис" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error at %s:%d: %d" -msgstr "Неизвестная ошибка BLE в %s:%d: %d" +#: py/compile.c +msgid "expecting key:value for dict" +msgstr "ожидание ключа: значение для дикта" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error: %d" -msgstr "Неизвестная ошибка BLE: %d" +#: py/compile.c +msgid "expecting just a value for set" +msgstr "ожидание только значения для набора" -#: ports/espressif/common-hal/max3421e/Max3421E.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unknown error code %d" -msgstr "Неизвестный код ошибки %d" +#: py/compile.c +msgid "'yield' outside function" +msgstr "внешняя функция \"выход\"" -#: shared-bindings/wifi/Radio.c -#, c-format -msgid "Unknown failure %d" -msgstr "Неизвестный сбой %d" +#: py/compile.c +msgid "'yield from' inside async function" +msgstr "«выход из» внутри асинхронной функции" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown gatt error: 0x%04x" -msgstr "Неизвестная ошибка gatt: 0x%04x" +#: py/compile.c +msgid "'await' outside function" +msgstr "«ожидание» внешняя функция" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: supervisor/shared/safe_mode.c -msgid "Unknown reason." -msgstr "Причина неизвестна." +#: py/compile.c +msgid "unknown type '%q'" +msgstr "Неизвестный тип '%q'" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown security error: 0x%04x" -msgstr "Неизвестная ошибка безопасности: 0x%04x" +#: py/compile.c +msgid "annotation must be an identifier" +msgstr "Аннотация должна быть идентификатором" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error at %s:%d: %d" -msgstr "Неизвестная системная ошибка прошивки на %s:%d: %d" +#: py/compile.c +msgid "argument name reused" +msgstr "Повторное использование имени аргумента" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %04x" -msgstr "Неизвестная системная ошибка прошивки: %04x" +#: py/compile.c +msgid "inline assembler must be a function" +msgstr "Встроенный ассемблер должен быть функцией" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %d" -msgstr "Неизвестная ошибка прошивки системы: %d" +#: py/compile.c +msgid "unknown type" +msgstr "Неизвестный тип" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -#: shared-module/_pixelmap/PixelMap.c -#, c-format -msgid "Unmatched number of items on RHS (expected %d, got %d)." -msgstr "" -"Непревзойденное количество элементов на RHS (ожидалось %d, получено %d)." +#: py/compile.c +msgid "return annotation must be an identifier" +msgstr "Возвращаемая аннотация должна быть идентификатором" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "" -"Unspecified issue. Can be that the pairing prompt on the other device was " -"declined or ignored." -msgstr "" -"Неуказанная проблема. Возможно, запрос на сопряжение на другом устройстве " -"был отклонен или проигнорирован." +#: py/compile.c +msgid "expecting an assembler instruction" +msgstr "Ожидание инструкции ассемблера" -#: shared-bindings/bitmaptools/__init__.c -msgid "Unsupported colorspace" -msgstr "Неподдерживаемое цветовое пространство" +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "«метка» требует 1 аргумент" -#: shared-module/displayio/bus_core.c -msgid "Unsupported display bus type" -msgstr "Неподдерживаемый тип шины дисплея" +#: py/compile.c +msgid "label redefined" +msgstr "Метка переопределена" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Неподдерживаемый формат" +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "«выравнивание» требует 1 аргумента" -#: shared-bindings/hashlib/__init__.c -msgid "Unsupported hash algorithm" -msgstr "Неподдерживаемый алгоритм хеширования" +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "«данные» требуют как минимум 2 аргумента" -#: ports/espressif/common-hal/socketpool/Socket.c -msgid "Unsupported socket type" -msgstr "Неподдерживаемый тип сокета" +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "«данные» требуют целочисленных аргументов" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Update failed" -msgstr "Обновление не удалось" +#: py/compile.c +msgid "cannot emit native code for this architecture" +msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length != required fixed length" -msgstr "Длина значения! = требуемая фиксированная длина" +#: py/emitbc.c +msgid "bytecode overflow" +msgstr "Переполнение байт-кода" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length > max_length" -msgstr "Длина значения > максимальная_длина" +#: py/emitinlinerv32.c +msgid "can only have up to 4 parameters for RV32 assembly" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Version was invalid" -msgstr "Версия была недействительной" +#: py/emitinlinerv32.c +msgid "parameters must be registers in sequence a0 to a3" +msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Voltage read timed out" -msgstr "Истекло время ожидания считывания напряжения" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: expecting %q" +msgstr "" -#: main.c -msgid "WARNING: Your code filename has two extensions\n" -msgstr "ВНИМАНИЕ: Имя файла кода имеет два расширения\n" +#: py/emitinlinerv32.c +msgid "opcode '%q': expecting %d arguments" +msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: out of range" msgstr "" -"Сторожевой таймер не может быть деинициализирован, если установлен режим " -"RESET" -#: py/builtinhelp.c -#, c-format -msgid "" -"Welcome to Adafruit CircuitPython %s!\n" -"\n" -"Visit circuitpython.org for more information.\n" -"\n" -"To list built-in modules type `help(\"modules\")`.\n" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: unknown register" msgstr "" -"Добро пожаловать в Adafruit CircuitPython %s! \n" -"\n" -"Посетите circuitpython.org для получения дополнительной информации. \n" -"\n" -"Чтобы получить список встроенных модулей, введите 'help(\"modules\")'.\n" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "Wi-Fi: " -msgstr "Wi-Fi: " +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: undefined label '%q'" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "Wifi не включен" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: must not be zero" +msgstr "" -#: main.c -msgid "Woken up by alarm.\n" -msgstr "Проснулся по тревоге.\n" +#: py/emitinlinerv32.c +msgid "invalid RV32 instruction '%q'" +msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Writes not supported on Characteristic" -msgstr "Запись не поддерживается в Характеристика" +#: py/emitinlinethumb.c +msgid "can only have up to 4 parameters to Thumb assembly" +msgstr "может иметь только до 4 параметров для сборки большого пальца" -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "You pressed both buttons at start up." -msgstr "Вы нажали обе кнопки при запуске." +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" +msgstr "Параметры должны быть регистрами в последовательности от r0 до r3" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h -msgid "You pressed button A at start up." -msgstr "Вы нажали кнопку A при запуске." +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' ожидает не более r%d" -#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h -msgid "You pressed button DOWN at start up." -msgstr "Вы нажали кнопку ВНИЗ при запуске." +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' ожидает регистр" -#: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up" -msgstr "Вы нажали кнопку BOOT при запуске" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' ожидает специальный регистр" -#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h -#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h -msgid "You pressed the BOOT button at start up." -msgstr "При запуске вы нажали кнопку BOOT." +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' ожидает регистр FPU" -#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h -msgid "You pressed the GPIO0 button at start up." -msgstr "Вы нажали кнопку GPIO0 при запуске." +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' ожидает {r0, r1, ...}" -#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h -msgid "You pressed the Rec button at start up." -msgstr "Вы нажали кнопку «Запись» при запуске." +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects an integer" +msgstr "'%s' ожидает целое число" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "You pressed the SW38 button at start up." -msgstr "Вы нажали кнопку SW38 при запуске." +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" +msgstr "'%s' целое число 0x%x не помещается в маску 0x%x" -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -#: ports/espressif/boards/vidi_x/mpconfigboard.h -msgid "You pressed the VOLUME button at start up." -msgstr "Вы нажали кнопку ГРОМКОСТЬ при запуске." +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s' ожидает адрес в формате [a, b]" -#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h -msgid "You pressed the central button at start up." -msgstr "Вы нажали центральную кнопку при запуске." +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' ожидает метку" -#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h -msgid "You pressed the left button at start up." -msgstr "Вы нажали левую кнопку при запуске." +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" +msgstr "Метка '%q' не определена" -#: supervisor/shared/safe_mode.c -msgid "You pressed the reset button during boot." -msgstr "Вы нажали кнопку сброса во время загрузки." +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" +msgstr "неподдерживаемая инструкция Thumb '%s' с аргументами %d" -#: supervisor/shared/micropython.c -msgid "[truncated due to length]" -msgstr "[отрезается по длине]" +#: py/emitinlinethumb.c +msgid "branch not in range" +msgstr "Ветвь не в пределах досягаемости" -#: py/objtype.c -msgid "__init__() should return None" -msgstr "__init__() должен возвращать значение None" +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" +msgstr "может иметь только до 4 параметров для сборки Xtensa" -#: py/objtype.c -#, c-format -msgid "__init__() should return None, not '%s'" -msgstr "__init__() должна возвращать Нет, а не \"%s\"" +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" +msgstr "Параметры должны быть регистрами в последовательности от a2 до a5" -#: py/objobject.c -msgid "__new__ arg must be a user-type" -msgstr "__new__ arg должен быть пользовательского типа" +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d isn't within range %d..%d" +msgstr "'%s' целое число %d не находится в пределах диапазона %d..%d" -#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c -msgid "a bytes-like object is required" -msgstr "Требуется байтоподобный объект" +#: py/emitinlinextensa.c +#, c-format +msgid "%d is not a multiple of %d" +msgstr "" -#: shared-bindings/i2ctarget/I2CTarget.c -msgid "addresses is empty" -msgstr "адреса пусты" +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" +msgstr "неподдерживаемая инструкция Xtensa '%s' с аргументами %d" -#: py/compile.c -msgid "annotation must be an identifier" -msgstr "Аннотация должна быть идентификатором" +#: py/emitnative.c +msgid "conversion to object" +msgstr "Преобразование в объект" -#: extmod/ulab/code/numpy/create.c -msgid "arange: cannot compute length" -msgstr "arange: не удается вычислить длину" +#: py/emitnative.c +msgid "local '%q' used before type known" +msgstr "местный '%q' используется перед типом" -#: py/modbuiltins.c -msgid "arg is an empty sequence" -msgstr "arg - пустая последовательность" +#: py/emitnative.c +msgid "can't load from '%q'" +msgstr "Не удается загрузить из '%q'" -#: py/objobject.c -msgid "arg must be user-type" -msgstr "arg должен быть пользовательского типа" +#: py/emitnative.c +msgid "can't load with '%q' index" +msgstr "Не удается загрузить с индексом '%q'" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort argument must be an ndarray" -msgstr "аргумент сортировки должен быть аргументом массива ndarray" +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" +msgstr "Локальный '%q' имеет тип '%q', но источник '%q'" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort is not implemented for flattened arrays" -msgstr "сортировка arg не реализована для сглаженных массивов" +#: py/emitnative.c +msgid "can't store '%q'" +msgstr "Не удается сохранить '%q'" -#: extmod/ulab/code/numpy/random/random.c -msgid "argument must be None, an integer or a tuple of integers" -msgstr "" +#: py/emitnative.c +msgid "can't store to '%q'" +msgstr "невозможно сохранить в «%q»" -#: py/compile.c -msgid "argument name reused" -msgstr "Повторное использование имени аргумента" +#: py/emitnative.c +msgid "can't store with '%q' index" +msgstr "не может хранить с индексом%q" -#: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c -msgid "argument num/types mismatch" -msgstr "Аргумент Несоответствие числа/типов" +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" +msgstr "не может неявно преобразовать '%q' в 'bool'" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c -msgid "arguments must be ndarrays" -msgstr "Аргументы должны быть массивами ndarrays" +#: py/emitnative.c +msgid "'not' not implemented" +msgstr "'не' не реализовано" -#: extmod/ulab/code/ndarray.c -msgid "array and index length must be equal" -msgstr "Длина массива и индекса должна быть равна" +#: py/emitnative.c +msgid "can't do unary op of '%q'" +msgstr "Невозможно выполнить унарную операцию '%q'" -#: extmod/ulab/code/numpy/io/io.c -msgid "array has too many dimensions" -msgstr "Массив имеет слишком много измерений" +#: py/emitnative.c +msgid "div/mod not implemented for uint" +msgstr "div/mod не реализован для uint" -#: extmod/ulab/code/ndarray.c -msgid "array is too big" -msgstr "массив слишком велик" +#: py/emitnative.c +msgid "comparison of int and uint" +msgstr "сравнение int и uint" -#: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c -msgid "array/bytes required on right side" -msgstr "массив/байты, необходимые справа" +#: py/emitnative.c +msgid "binary op %q not implemented" +msgstr "двоичная операция %q не реализована" -#: py/asmxtensa.c -msgid "asm overflow" -msgstr "Переполнение ASM" +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" +msgstr "Не могу выполнить двоичную операцию между '%q' и '%q'" -#: py/compile.c -msgid "async for/with outside async function" -msgstr "async для/вместе с внешней async-функцией" +#: py/emitnative.c +msgid "casting" +msgstr "кастинг" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get (arg)min/(arg)max of empty sequence" -msgstr "" -"Попытка получить (аргумент)минимальный/(аргумент)максимальный пустой " -"последовательности" +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" +msgstr "Возврат ожидался '%q', но получил '%q'" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get argmin/argmax of an empty sequence" -msgstr "" -"Попытка получить аргумент минимальный/аргумент максимальный пустой " -"последовательности" +#: py/emitnative.c +msgid "must raise an object" +msgstr "должен поднять объект" -#: py/objstr.c -msgid "attributes not supported" -msgstr "Атрибуты не поддерживаются" +#: py/emitnative.c +msgid "native yield" +msgstr "родной урожай" -#: extmod/ulab/code/ulab_tools.c -msgid "axis is out of bounds" -msgstr "Ось выходит за пределы" +#: py/lexer.c +msgid "unicode name escapes" +msgstr "Экранирование имен в Юникоде" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -msgid "axis must be None, or an integer" -msgstr "ось должна быть None или целым числом" +#: py/modbuiltins.c +msgid "chr() arg not in range(0x110000)" +msgstr "chr() аргумент вне диапазона (0x110000)" -#: extmod/ulab/code/numpy/numerical.c -msgid "axis too long" -msgstr "Слишком длинная ось" +#: py/modbuiltins.c +msgid "chr() arg not in range(256)" +msgstr "chr() аргумент вне диапазона (256)" -#: shared-bindings/bitmaptools/__init__.c -msgid "background value out of range of target" -msgstr "Фоновое значение вне диапазона цели" +#: py/modbuiltins.c +msgid "arg is an empty sequence" +msgstr "arg - пустая последовательность" -#: py/builtinevex.c -msgid "bad compile mode" -msgstr "Неверный режим компиляции" +#: py/modbuiltins.c +msgid "ord expects a character" +msgstr "Орд ожидает персонажа" -#: py/objstr.c -msgid "bad conversion specifier" -msgstr "Неверный спецификатор преобразования" +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" +msgstr "ord() ожидал символ, но строка длины %d найдена" -#: py/objstr.c -msgid "bad format string" -msgstr "Строка неверного формата" +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "Pow() с 3 аргументами не поддерживается" -#: py/binary.c py/objarray.c -msgid "bad typecode" -msgstr "Неверный шрифт" +#: py/modbuiltins.c +msgid "must use keyword argument for key function" +msgstr "Необходимо использовать аргумент ключевого слова для ключевой функции" -#: py/emitnative.c -msgid "binary op %q not implemented" -msgstr "двоичная операция %q не реализована" +#: py/moderrno.c +msgid "Operation not permitted" +msgstr "Операция не разрешена" -#: shared-module/bitmapfilter/__init__.c -msgid "bitmap size and depth must match" -msgstr "Размер и глубина растрового изображения должны совпадать" +#: py/moderrno.c +msgid "No such file/directory" +msgstr "Файл/директория не существует" -#: shared-bindings/bitmaptools/__init__.c -msgid "bitmap sizes must match" -msgstr "Размеры растровых изображений должны совпадать" +#: py/moderrno.c +msgid "Input/output error" +msgstr "Ошибка ввода/вывода" -#: extmod/modrandom.c -msgid "bits must be 32 or less" -msgstr "биты должны быть 32 или менее" +#: py/moderrno.c +msgid "Permission denied" +msgstr "Отказано в разрешении" -#: shared-bindings/audiomixer/Mixer.c -msgid "bits_per_sample must be 8 or 16" -msgstr "bits_per_sample должно быть 8 или 16" +#: py/moderrno.c +msgid "File exists" +msgstr "Файл существует" -#: py/emitinlinethumb.c -msgid "branch not in range" -msgstr "Ветвь не в пределах досягаемости" +#: py/moderrno.c +msgid "No such device" +msgstr "Нет такого устройства" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer is smaller than requested size" -msgstr "Размер буфера меньше запрошенного" +#: py/moderrno.c +msgid "No space left on device" +msgstr "На устройстве не осталось свободного места" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer size must be a multiple of element size" -msgstr "Размер буфера должен быть кратен размеру элемента" +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" +msgstr "Ошибка математической области" -#: shared-module/struct/__init__.c -msgid "buffer size must match format" -msgstr "Размер буфера должен соответствовать формату" +#: py/modmath.c +msgid "negative factorial" +msgstr "отрицательный факториал" -#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c -msgid "buffer slices must be of equal length" -msgstr "Буферные фрагменты должны быть одинаковой длины" +#: py/modmicropython.c +msgid "schedule queue full" +msgstr "Расписание Очередь заполнена" #: py/modstruct.c shared-module/struct/__init__.c msgid "buffer too small" msgstr "буфер слишком мал" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "buffer too small for requested bytes" -msgstr "Слишком маленький буфер для запрашиваемых байтов" - -#: py/emitbc.c -msgid "bytecode overflow" -msgstr "Переполнение байт-кода" - -#: py/objarray.c -msgid "bytes length not a multiple of item size" -msgstr "длина байтов, не кратная размеру элемента" - -#: py/objstr.c -msgid "bytes value out of range" -msgstr "Значение байтов вне диапазона" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" +msgstr "Упаковка ожидаемых %d товаров для упаковки (получил %d)" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is out of range" -msgstr "Калибровка выходит за пределы допустимого диапазона" +#: py/modthread.c +msgid "expecting a dict for keyword args" +msgstr "ожидание определения аргументов ключевых слов" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is read only" -msgstr "Калибровка доступна только для чтения" +#: py/nativeglue.c +msgid "set unsupported" +msgstr "Установить не поддерживается" -#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c -#: shared-module/vectorio/Rectangle.c -msgid "can only have one parent" -msgstr "может иметь только одного родителя" +#: py/nativeglue.c +msgid "slice unsupported" +msgstr "Фрагмент не поддерживается" -#: py/emitinlinethumb.c -msgid "can only have up to 4 parameters to Thumb assembly" -msgstr "может иметь только до 4 параметров для сборки большого пальца" +#: py/nativeglue.c +msgid "float unsupported" +msgstr "Плавающий без поддержки" -#: py/emitinlinextensa.c -msgid "can only have up to 4 parameters to Xtensa assembly" -msgstr "может иметь только до 4 параметров для сборки Xtensa" +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c +msgid "can't convert %q to %q" +msgstr "Не удается преобразовать %q в %q" -#: extmod/ulab/code/ndarray.c -msgid "can only specify one unknown dimension" -msgstr "Можно указать только одно неизвестное измерение" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "" +"При обращении с вышеуказанным исключением произошло еще одно исключение:" -#: py/objtype.c -msgid "can't add special method to already-subclassed class" +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -"Не удается добавить специальный метод к уже имеющемуся подклассу классу" +"Вышеупомянутое исключение было непосредственной причиной следующего " +"исключения:" -#: py/compile.c -msgid "can't assign to expression" -msgstr "Не удается назначить выражение" +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " Файл \"%q\", строка %d" -#: extmod/modasyncio.c -msgid "can't cancel self" -msgstr "Не могу отменить себя" +#: py/obj.c +msgid " File \"%q\"" +msgstr " Файл \"%q\"" -#: shared-module/adafruit_pixelbuf/PixelBuf.c -msgid "can't convert %q to %q" -msgstr "Не удается преобразовать %q в %q" +#: py/obj.c +msgid ", in %q\n" +msgstr ", в %q\n" + +#: py/obj.c +msgid "Traceback (most recent call last):\n" +msgstr "Трассировка (последний вызов):\n" #: py/obj.c -#, c-format -msgid "can't convert %s to complex" -msgstr "не может преобразовать %s в сложный" +msgid "can't convert to float" +msgstr "Не удается преобразовать в float" #: py/obj.c #, c-format msgid "can't convert %s to float" msgstr "не могу преобразовать %s в число с плавающей запятой" -#: py/objint.c py/runtime.c -#, c-format -msgid "can't convert %s to int" -msgstr "Невозможно преобразовать %s в int" +#: py/obj.c +msgid "can't convert to complex" +msgstr "не может быть преобразован в сложный" -#: py/objstr.c -msgid "can't convert '%q' object to %q implicitly" -msgstr "не может конвертировать «%q» в% q косвенно" +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" +msgstr "не может преобразовать %s в сложный" -#: extmod/ulab/code/numpy/vector.c -msgid "can't convert complex to float" -msgstr "Не может преобразовать сложный в плавающий" +#: py/obj.c +msgid "expected tuple/list" +msgstr "Ожидаемый кортеж/список" #: py/obj.c -msgid "can't convert to complex" -msgstr "не может быть преобразован в сложный" +#, c-format +msgid "object '%s' isn't a tuple or list" +msgstr "Объект \"%s\" не является кортежом или списком" #: py/obj.c -msgid "can't convert to float" -msgstr "Не удается преобразовать в float" +msgid "tuple/list has wrong length" +msgstr "Кортеж/список имеет неправильную длину" -#: py/runtime.c -msgid "can't convert to int" -msgstr "Не удается преобразовать в int" +#: py/obj.c +#, c-format +msgid "requested length %d but object has length %d" +msgstr "запрашиваемая длина %d, но объект имеет длину %d" -#: py/objstr.c -msgid "can't convert to str implicitly" -msgstr "не может превратиться в полосу неявно" +#: py/obj.c +msgid "indices must be integers" +msgstr "индексы должны быть целыми числами" -#: py/compile.c -msgid "can't declare nonlocal in outer code" -msgstr "не может объявить нелокальный во внешнем коде" +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "Индексы %q должны быть целыми числами, а не %s" -#: py/compile.c -msgid "can't delete expression" -msgstr "Не удается удалить выражение" +#: py/obj.c +msgid "object has no len" +msgstr "Объект не имеет объектива" -#: py/emitnative.c -msgid "can't do binary op between '%q' and '%q'" -msgstr "Не могу выполнить двоичную операцию между '%q' и '%q'" +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" +msgstr "объект типа «%s» не имеет len()" -#: py/emitnative.c -msgid "can't do unary op of '%q'" -msgstr "" +#: py/obj.c +msgid "object doesn't support item deletion" +msgstr "Объект не поддерживает удаление элементов" -#: py/emitnative.c -msgid "can't implicitly convert '%q' to 'bool'" -msgstr "не может неявно преобразовать '%q' в 'bool'" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item deletion" +msgstr "Объект '%s' не поддерживает удаление элементов" -#: py/runtime.c -msgid "can't import name %q" -msgstr "Невозможно импортировать имя %q" +#: py/obj.c +msgid "object isn't subscriptable" +msgstr "Объект не имеет индекса" -#: py/emitnative.c -msgid "can't load from '%q'" -msgstr "Не удается загрузить из '%q'" +#: py/obj.c +#, c-format +msgid "'%s' object isn't subscriptable" +msgstr "Объект '%s' не может быть подписан" -#: py/emitnative.c -msgid "can't load with '%q' index" -msgstr "Не удается загрузить с индексом '%q'" +#: py/obj.c +msgid "object doesn't support item assignment" +msgstr "Объект не поддерживает назначение элементов" -#: py/builtinimport.c -msgid "can't perform relative import" -msgstr "Не удается выполнить относительный импорт" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item assignment" +msgstr "Объект '%s' не поддерживает присвоение элементов" -#: py/objgenerator.c -msgid "can't send non-None value to a just-started generator" -msgstr "" -"не может отправить значение, отличное от None, только что запущенному " -"генератору" +#: py/obj.c +msgid "object with buffer protocol required" +msgstr "Объект с обязательным буферным протоколом" -#: shared-module/sdcardio/SDCard.c -msgid "can't set 512 block size" -msgstr "Не удается установить размер блока 512" +#: py/objarray.c +msgid "bytes length not a multiple of item size" +msgstr "длина байтов, не кратная размеру элемента" -#: py/objexcept.c py/objnamedtuple.c -msgid "can't set attribute" -msgstr "Не удается установить атрибут" +#: py/objarray.c py/objstr.c +msgid "string argument without an encoding" +msgstr "строковый аргумент без кодировки" -#: py/runtime.c -msgid "can't set attribute '%q'" -msgstr "Не удается установить атрибут '%q'" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" +msgstr "вид памяти: длина не является множеством элементов" -#: py/emitnative.c -msgid "can't store '%q'" -msgstr "Не удается сохранить '%q'" +#: py/objarray.c py/objstr.c +msgid "substring not found" +msgstr "Подстрока не найдена" -#: py/emitnative.c -msgid "can't store to '%q'" -msgstr "невозможно сохранить в «%q»" +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" +msgstr "поддерживаются только срезы с шагом = 1 (так как нет)" -#: py/emitnative.c -msgid "can't store with '%q' index" -msgstr "не может хранить с индексом%q" +#: py/objarray.c +msgid "lhs and rhs should be compatible" +msgstr "lhs и rhs должны быть совместимыми" -#: py/objstr.c -msgid "" -"can't switch from automatic field numbering to manual field specification" -msgstr "" -"Не удается переключиться с автоматической нумерации полей на ручную " -"спецификацию полей" +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" +msgstr "массив/байты, необходимые справа" -#: py/objstr.c -msgid "" -"can't switch from manual field specification to automatic field numbering" -msgstr "не может переключаться с ручного поля на автоматическую нумерацию поля" +#: py/objarray.c +msgid "memoryview offset too large" +msgstr "Слишком большое смещение просмотра памяти" #: py/objcomplex.c msgid "can't truncate-divide a complex number" msgstr "нельзя усекать и делить комплексное число" -#: extmod/modasyncio.c -msgid "can't wait" -msgstr "не может ждать" - -#: extmod/ulab/code/ndarray.c -msgid "cannot assign new shape" -msgstr "Не удается назначить новую фигуру" +#: py/objcomplex.c +msgid "complex divide by zero" +msgstr "комплексное деление на ноль" -#: extmod/ulab/code/ndarray_operators.c -msgid "cannot cast output with casting rule" -msgstr "Не удается привести выходные данные с помощью правила приведения" +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0 в комплексную степень" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex to dtype" -msgstr "не может превратить комплекс в dtype" +#: py/objdeque.c +msgid "full" +msgstr "полный" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex type" -msgstr "Не удается преобразовать сложный тип" +#: py/objdeque.c +msgid "empty" +msgstr "пусто" -#: py/objtype.c -msgid "cannot create '%q' instances" -msgstr "Не удается создать экземпляры '%q'" +#: py/objdict.c +msgid "dict update sequence has wrong length" +msgstr "последовательность обновления дикта имеет неправильную длину" -#: py/objtype.c -msgid "cannot create instance" -msgstr "Не удается создать экземпляр" +#: py/objexcept.c py/objnamedtuple.c +msgid "can't set attribute" +msgstr "Не удается установить атрибут" -#: extmod/ulab/code/ndarray.c -msgid "cannot delete array elements" -msgstr "Не удается удалить элементы массива" +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" +msgstr "Комплексные значения не поддерживаются" -#: extmod/ulab/code/ndarray.c -msgid "cannot reshape array" -msgstr "Не удается изменить форму массива" +#: py/objgenerator.c +msgid "generator already executing" +msgstr "генератор уже работает" -#: py/emitnative.c -msgid "casting" -msgstr "кастинг" +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" +msgstr "" +"не может отправить значение, отличное от None, только что запущенному " +"генератору" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "channel re-init" -msgstr "Реинициализация канала" +#: py/objgenerator.c py/runtime.c +msgid "generator raised StopIteration" +msgstr "генератор поднят Остановить итерацию" -#: shared-bindings/_stage/Text.c -msgid "chars buffer too small" -msgstr "Слишком маленький буфер символов" +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" +msgstr "генератор проигнорировал Выход" -#: py/modbuiltins.c -msgid "chr() arg not in range(0x110000)" -msgstr "chr() аргумент вне диапазона (0x110000)" +#: py/objint.c py/runtime.c +#, c-format +msgid "can't convert %s to int" +msgstr "Невозможно преобразовать %s в int" -#: py/modbuiltins.c -msgid "chr() arg not in range(256)" -msgstr "chr() аргумент вне диапазона (256)" +#: py/objint.c +msgid "float too big" +msgstr "Поплавок слишком большой" -#: shared-bindings/bitmaptools/__init__.c -msgid "clip point must be (x,y) tuple" -msgstr "Точка клипа должна быть кортежом (x,y)" +#: py/objint.c +#, c-format +msgid "value must fit in %d byte(s)" +msgstr "Значение должно совпадать с байтами %d" -#: shared-bindings/msgpack/ExtType.c -msgid "code outside range 0~127" -msgstr "код вне диапазона 0~127" +#: py/objint.c shared-bindings/time/__init__.c +msgid "No long integer support" +msgstr "Нет поддержки длинных целых чисел (long integer)" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "" -"Цветовой буфер должен иметь размер 3 байта (RGB) или 4 байта (RGB + байт " -"заполнения)" +#: py/objint.c py/sequence.c +msgid "small int overflow" +msgstr "Маленькое переполнение int" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a buffer, tuple, list, or int" -msgstr "Цветовой буфер должен быть буфером, кортежом, списком или целым числом" +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c +msgid "%q=%q" +msgstr "%q=%q" -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" +#: py/objint_longlong.c py/parsenum.c +msgid "result overflows long long storage" msgstr "" -"цветовой буфер должен быть байтом массива или массивом типа \"b\" или \"B\"" - -#: shared-bindings/displayio/Palette.c -msgid "color must be between 0x000000 and 0xffffff" -msgstr "Цвет должен быть от 0x000000 до 0xffffff" -#: py/emitnative.c -msgid "comparison of int and uint" -msgstr "сравнение int и uint" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative shift count" +msgstr "Количество отрицательных сдвигов" -#: py/objcomplex.c -msgid "complex divide by zero" -msgstr "комплексное деление на ноль" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" +msgstr "Отрицательная мощность без поплавковой опоры" -#: py/objfloat.c py/parsenum.c -msgid "complex values not supported" -msgstr "Комплексные значения не поддерживаются" +#: py/objint_longlong.c py/objint_mpz.c +msgid "overflow converting long int to machine word" +msgstr "переполнение преобразование длинного целого в машинное слово" -#: extmod/modzlib.c -msgid "compression header" -msgstr "Заголовок сжатия" +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" +msgstr "pow() с 3 аргументами требует целых чисел" -#: py/emitnative.c -msgid "conversion to object" -msgstr "Преобразование в объект" +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" +msgstr "3-й аргумент pow() не может быть равен 0" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be linear arrays" -msgstr "Аргументы свертки должны быть линейными массивами" +#: py/objobject.c +msgid "__new__ arg must be a user-type" +msgstr "__new__ arg должен быть пользовательского типа" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be ndarrays" -msgstr "переплетение аргументов должно быть массивами ndarrays" +#: py/objobject.c +msgid "arg must be user-type" +msgstr "arg должен быть пользовательского типа" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must not be empty" -msgstr "аргументы свертки не должны быть пустыми" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "Шаг %q не может быть нулём" -#: extmod/ulab/code/numpy/io/io.c -msgid "corrupted file" -msgstr "Поврежденный файл" +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Невозможно создать подкласс среза" -#: extmod/ulab/code/numpy/poly.c -msgid "could not invert Vandermonde matrix" -msgstr "не удалось инвертировать матрицу Вандермонда" +#: py/objstr.c +msgid "bytes value out of range" +msgstr "Значение байтов вне диапазона" -#: shared-module/sdcardio/SDCard.c -msgid "couldn't determine SD card version" -msgstr "Не удалось определить версию SD карты" +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" +msgstr "" +"присоединяйтесь к ожидающему список стр/байт объектов, совместимых с " +"самообъектом" -#: extmod/ulab/code/numpy/numerical.c -msgid "cross is defined for 1D arrays of length 3" -msgstr "крест определяется для 1D массивов длины 3" +#: py/objstr.c +msgid "empty separator" +msgstr "пустой сепаратор" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be iterable" -msgstr "Данные должны быть итерируемыми" +#: py/objstr.c +msgid "rsplit(None,n)" +msgstr "rsplit(Нет;n)" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be of equal length" -msgstr "Данные должны быть одинаковой длины" +#: py/objstr.c +msgid "bad format string" +msgstr "Строка неверного формата" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +#: py/objstr.c #, c-format -msgid "data pin #%d in use" -msgstr "data-пин #%d уже используется" +msgid "unmatched '%c' in format" +msgstr "Несовпадающий '%c' в формате" -#: extmod/ulab/code/ndarray.c -msgid "data type not understood" -msgstr "Тип данных не понят" +#: py/objstr.c +msgid "bad conversion specifier" +msgstr "Неверный спецификатор преобразования" -#: py/parsenum.c -msgid "decimal numbers not supported" -msgstr "Десятичные числа не поддерживаются" +#: py/objstr.c +msgid "end of format while looking for conversion specifier" +msgstr "конец формата при поиске спецификатора преобразования" -#: py/compile.c -msgid "default 'except' must be last" -msgstr "по умолчанию \"за исключением\" должно быть последним" +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" +msgstr "Неизвестный спецификатор преобразования %c" -#: shared-bindings/msgpack/__init__.c -msgid "default is not a function" -msgstr "По умолчанию не является функцией" +#: py/objstr.c +msgid "expected ':' after format specifier" +msgstr "Ожидаемый ':' после спецификатора формата" -#: shared-bindings/audiobusio/PDMIn.c +#: py/objstr.c msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" -msgstr "" -"буфер назначения должен быть байтоммассива или массивом типа \"B\" для " -"бит_глубины = 8" - -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +"can't switch from automatic field numbering to manual field specification" msgstr "" -"буфер назначения должен быть массивом типа «H» для битовой_глубины = 16" - -#: py/objdict.c -msgid "dict update sequence has wrong length" -msgstr "последовательность обновления дикта имеет неправильную длину" +"Не удается переключиться с автоматической нумерации полей на ручную " +"спецификацию полей" -#: extmod/ulab/code/numpy/numerical.c -msgid "diff argument must be an ndarray" -msgstr "аргумент DIFF должен быть массивом ndarray" +#: py/objstr.c +msgid "%q index out of range" +msgstr "Индекс %q вне диапазона" -#: extmod/ulab/code/numpy/numerical.c -msgid "differentiation order out of range" -msgstr "Порядок дифференциации вне диапазона" +#: py/objstr.c +msgid "attributes not supported" +msgstr "Атрибуты не поддерживаются" -#: extmod/ulab/code/numpy/transform.c -msgid "dimensions do not match" -msgstr "Размеры не совпадают" +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" +msgstr "не может переключаться с ручного поля на автоматическую нумерацию поля" -#: py/emitnative.c -msgid "div/mod not implemented for uint" -msgstr "div/mod не реализован для uint" +#: py/objstr.c +msgid "invalid format specifier" +msgstr "Недопустимый спецификатор формата" -#: extmod/ulab/code/numpy/create.c -msgid "divide by zero" -msgstr "Делим на ноль" +#: py/objstr.c +msgid "sign not allowed in string format specifier" +msgstr "Знак не разрешен в спецификаторе строкового формата" -#: py/runtime.c -msgid "division by zero" -msgstr "Деление на ноль" +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" +msgstr "Знак не разрешен со спецификатором целочисленного формата 'c'" -#: extmod/ulab/code/numpy/vector.c -msgid "dtype must be float, or complex" -msgstr "Тип d должен быть плавающим или сложным" +#: py/objstr.c +msgid "unknown format code '%c' for object of type '%q'" +msgstr "Неизвестный код формата '%c' для объекта типа '%q'" -#: extmod/ulab/code/ndarray_operators.c -msgid "dtype of int32 is not supported" -msgstr "dtype int32 не поддерживается" +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "Выравнивание '=' недопустимо в спецификаторе формата строки" -#: py/objdeque.c -msgid "empty" -msgstr "пусто" +#: py/objstr.c +msgid "format needs a dict" +msgstr "Формат требует диктата" -#: extmod/ulab/code/numpy/io/io.c -msgid "empty file" -msgstr "пустой файл" +#: py/objstr.c +msgid "incomplete format key" +msgstr "Неполный ключ форматирования" -#: extmod/modasyncio.c extmod/modheapq.c -msgid "empty heap" -msgstr "пустая куча" +#: py/objstr.c +msgid "incomplete format" +msgstr "Неполный формат" #: py/objstr.c -msgid "empty separator" -msgstr "пустой сепаратор" +msgid "format string needs more arguments" +msgstr "" -#: shared-bindings/random/__init__.c -msgid "empty sequence" -msgstr "пустая последовательность" +#: py/objstr.c +#, c-format +msgid "%%c needs int or char" +msgstr "" #: py/objstr.c -msgid "end of format while looking for conversion specifier" -msgstr "конец формата при поиске спецификатора преобразования" +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" +msgstr "Неподдерживаемый символ формата '%c' (0x%x) при индексе %d" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "epoch_time not supported on this board" -msgstr "epoch_time не поддерживается на этой плате" +#: py/objstr.c +msgid "format string didn't convert all arguments" +msgstr "" -#: ports/nordic/common-hal/busio/UART.c -#, c-format -msgid "error = 0x%08lX" -msgstr "ошибка = 0x%08lX" +#: py/objstr.c +msgid "non-hex digit" +msgstr "" -#: py/runtime.c -msgid "exceptions must derive from BaseException" -msgstr "исключения должны быть производными от базового исключения" +#: py/objstr.c +msgid "can't convert to str implicitly" +msgstr "не может превратиться в полосу неявно" #: py/objstr.c -msgid "expected ':' after format specifier" -msgstr "Ожидаемый ':' после спецификатора формата" +msgid "can't convert '%q' object to %q implicitly" +msgstr "не может конвертировать «%q» в% q косвенно" -#: py/obj.c -msgid "expected tuple/list" -msgstr "Ожидаемый кортеж/список" +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" +msgstr "Индексы строк должны быть целыми числами, а не %s" -#: py/modthread.c -msgid "expecting a dict for keyword args" -msgstr "ожидание определения аргументов ключевых слов" +#: py/objstrunicode.c +msgid "string index out of range" +msgstr "индекс строки выходит за пределы диапазона" -#: py/compile.c -msgid "expecting an assembler instruction" -msgstr "Ожидание инструкции ассемблера" +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "Вызовите super().__init__() перед доступом к собственному объекту." -#: py/compile.c -msgid "expecting just a value for set" -msgstr "ожидание только значения для набора" +#: py/objtype.c +msgid "__init__() should return None" +msgstr "__init__() должен возвращать значение None" -#: py/compile.c -msgid "expecting key:value for dict" -msgstr "ожидание ключа: значение для дикта" +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" +msgstr "__init__() должна возвращать Нет, а не \"%s\"" -#: shared-bindings/msgpack/__init__.c -msgid "ext_hook is not a function" -msgstr "ext_hook не является функцией" +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" +msgstr "Нечитаемый атрибут" -#: py/argcheck.c -msgid "extra keyword arguments given" -msgstr "Приведены дополнительные аргументы ключевых слов" +#: py/objtype.c py/runtime.c +msgid "object not callable" +msgstr "Объект не вызывается" -#: py/argcheck.c -msgid "extra positional arguments given" -msgstr "Приведены дополнительные позиционные аргументы" +#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c +msgid "'%q' object isn't callable" +msgstr "" -#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c -#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c -msgid "file must be a file opened in byte mode" -msgstr "Файл должен быть файлом, открытым в байтовом режиме" +#: py/objtype.c +msgid "type takes 1 or 3 arguments" +msgstr "тип занимает 1 или 3 аргумента" -#: shared-bindings/traceback/__init__.c -msgid "file write is not available" -msgstr "Запись файлов недоступна" +#: py/objtype.c +msgid "can't create instance" +msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" -msgstr "Файловая система должна предусматривать метод монтирования" +#: py/objtype.c +msgid "can't create '%q' instances" +msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "first argument must be a callable" -msgstr "Первый аргумент должен быть вызываемым" +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" +"Не удается добавить специальный метод к уже имеющемуся подклассу классу" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "first argument must be a function" -msgstr "первый аргумент должен быть функцией" +#: py/objtype.c +msgid "type isn't an acceptable base type" +msgstr "Тип не является приемлемым базовым типом" -#: extmod/ulab/code/numpy/create.c -msgid "first argument must be a tuple of ndarrays" -msgstr "Первый аргумент должен быть кортежом массива ndarrays" +#: py/objtype.c +msgid "type '%q' isn't an acceptable base type" +msgstr "Тип '%Q' не является допустимым базовым типом" -#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c -msgid "first argument must be an ndarray" -msgstr "Первым аргументом должен быть массивом ndarray" +#: py/objtype.c +msgid "multiple inheritance not supported" +msgstr "Множественное наследование не поддерживается" + +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" +msgstr "Несколько баз имеют конфликт расположения экземпляров" #: py/objtype.c msgid "first argument to super() must be type" msgstr "первый аргумент супер() должен быть типом" -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "first two arguments must be ndarrays" -msgstr "Первые два аргумента должны быть массивами ndarrays" +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" +msgstr "issubclass() arg 2 должен быть классом или кортежом классов" -#: extmod/ulab/code/ndarray.c -msgid "flattening order must be either 'C', or 'F'" -msgstr "порядок сглаживания должен быть либо 'C', либо 'F'" +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" +msgstr "issubclass() arg 1 должен быть классом" -#: extmod/ulab/code/numpy/numerical.c -msgid "flip argument must be an ndarray" -msgstr "Флип -аргумент должен быть массивом ndarray" +#: py/parse.c +msgid "not a constant" +msgstr "не константа" -#: py/objint.c -msgid "float too big" -msgstr "Поплавок слишком большой" +#: py/parse.c +msgid "Unable to init parser" +msgstr "Не удается инициировать синтаксический анализатор" -#: py/nativeglue.c -msgid "float unsupported" -msgstr "Плавающий без поддержки" +#: py/parse.c +msgid "unexpected indent" +msgstr "Неожиданный отступ" -#: shared-bindings/_stage/Text.c -msgid "font must be 2048 bytes long" -msgstr "Длина шрифта должна составлять 2048 байт" +#: py/parse.c +msgid "unindent doesn't match any outer indent level" +msgstr "Отступ не совпадает ни с одним уровнем внешнего отступа" -#: extmod/moddeflate.c -msgid "format" -msgstr "формат" +#: py/parse.c +msgid "malformed f-string" +msgstr "Неправильно сформированная F-строка" -#: py/objstr.c -msgid "format requires a dict" -msgstr "Формат требует диктата" +#: py/parsenum.c +msgid "invalid syntax for integer" +msgstr "недействительный синтаксис для целых чисел" -#: py/objdeque.c -msgid "full" -msgstr "полный" +#: py/parsenum.c +#, c-format +msgid "invalid syntax for integer with base %d" +msgstr "недействительный синтаксис для целых чисел с основанием %d" -#: py/argcheck.c -msgid "function doesn't take keyword arguments" -msgstr "функция не принимает аргументы ключевых слов" +#: py/parsenum.c +msgid "invalid syntax for number" +msgstr "недействительный синтаксис для номера" -#: py/argcheck.c -#, c-format -msgid "function expected at most %d arguments, got %d" -msgstr "функция, ожидаемая в большинстве %d аргументов, получила %d" +#: py/parsenum.c +msgid "decimal numbers not supported" +msgstr "Десятичные числа не поддерживаются" -#: py/bc.c py/objnamedtuple.c -msgid "function got multiple values for argument '%q'" -msgstr "функция имеет несколько значений для аргументации%q \"" +#: py/persistentcode.c +msgid "incompatible .mpy file" +msgstr "несовместимый файл .mpy" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "function has the same sign at the ends of interval" -msgstr "функция имеет один и тот же знак в конце интервала" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" +msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "function is defined for ndarrays only" -msgstr "Функция определяется только для массивов ndarrays" +#: py/persistentcode.c +msgid "native code in .mpy unsupported" +msgstr "Нативный код в .mpy не поддерживается" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "function is implemented for ndarrays only" -msgstr "Функция реализована только для массивов ndarrays" +#: py/persistentcode.c +msgid "incompatible .mpy arch" +msgstr "несовместимые .mpy арка" -#: py/argcheck.c -#, c-format -msgid "function missing %d required positional arguments" -msgstr "Функция отсутствует %d обязательные позиционные аргументы" +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "'%q' object does not support '%q'" +msgstr "Объект '%q' не поддерживает '%q'" -#: py/bc.c -msgid "function missing keyword-only argument" -msgstr "функция отсутствует аргумент только по ключевому слову" +#: py/qstr.c +msgid "name too long" +msgstr "слишком длинное имя" -#: py/bc.c -msgid "function missing required keyword argument '%q'" -msgstr "В функции отсутствует обязательный аргумент ключевого слова '%q'" +#: py/runtime.c +msgid "name not defined" +msgstr "Имя не определено" -#: py/bc.c +#: py/runtime.c +msgid "name '%q' isn't defined" +msgstr "Имя '%q' не определено" + +#: py/runtime.c +msgid "unsupported type for operator" +msgstr "Неподдерживаемый тип для оператора" + +#: py/runtime.c +msgid "unsupported type for %q: '%s'" +msgstr "неподдерживаемый тип для %q: '%s'" + +#: py/runtime.c +msgid "unsupported types for %q: '%q', '%q'" +msgstr "Неподдерживаемые типы для %q: '%q', '%q'" + +#: py/runtime.c +msgid "wrong number of values to unpack" +msgstr "Неправильное количество значений для распаковки" + +#: py/runtime.c #, c-format -msgid "function missing required positional argument #%d" -msgstr "В функции отсутствует обязательный позиционный аргумент #%d" +msgid "need more than %d values to unpack" +msgstr "Для распаковки требуется более значений %d" -#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c -#: shared-bindings/time/__init__.c +#: py/runtime.c #, c-format -msgid "function takes %d positional arguments but %d were given" -msgstr "функция принимает %d позиционные аргументы, но %d были заданы" +msgid "too many values to unpack (expected %d)" +msgstr "Слишком много значений для распаковки (ожидаемый %d)" + +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" +msgstr "тип объекта '%q' не имеет атрибута '%q \"" + +#: py/runtime.c +msgid "module '%q' has no attribute '%q'" +msgstr "" + +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "Объект '%s' не имеет атрибута '%q'" + +#: py/runtime.c +msgid "can't set attribute '%q'" +msgstr "Не удается установить атрибут '%q'" + +#: py/runtime.c +msgid "object not iterable" +msgstr "Объект не итерируемый" + +#: py/runtime.c +msgid "'%q' object isn't iterable" +msgstr "Объект '%q' не является итерируемым" -#: py/objgenerator.c -msgid "generator already executing" -msgstr "генератор уже работает" +#: py/runtime.c +msgid "object not an iterator" +msgstr "объект не итератор" -#: py/objgenerator.c -msgid "generator ignored GeneratorExit" -msgstr "генератор проигнорировал Выход" +#: py/runtime.c +msgid "'%q' object isn't an iterator" +msgstr "Объект '%q' не является итератором" -#: py/objgenerator.c py/runtime.c -msgid "generator raised StopIteration" -msgstr "генератор поднят Остановить итерацию" +#: py/runtime.c +msgid "exceptions must derive from BaseException" +msgstr "исключения должны быть производными от базового исключения" -#: shared-bindings/_stage/Layer.c -msgid "graphic must be 2048 bytes long" -msgstr "Длина рисунка должна составлять 2048 байт" +#: py/runtime.c +msgid "can't import name %q" +msgstr "Невозможно импортировать имя %q" -#: extmod/modhashlib.c -msgid "hash is final" -msgstr "хэш является окончательным" +#: py/runtime.c +msgid "memory allocation failed, heap is locked" +msgstr "Не удалось выделить память, куча заблокирована" -#: extmod/modheapq.c -msgid "heap must be a list" -msgstr "куча должна быть списком" +#: py/runtime.c +#, c-format +msgid "memory allocation failed, allocating %u bytes" +msgstr "Сбой выделения памяти, выделение %u байт" -#: py/compile.c -msgid "identifier redefined as global" -msgstr "идентификатор переопределен как глобальный" +#: py/runtime.c +msgid "can't convert to int" +msgstr "Не удается преобразовать в int" -#: py/compile.c -msgid "identifier redefined as nonlocal" -msgstr "идентификатор переопределен как нелокальный" +#: py/runtime.c +msgid "division by zero" +msgstr "Деление на ноль" -#: py/compile.c -msgid "import * not at module level" -msgstr "Импорт * не на уровне модуля" +#: py/runtime.c +msgid "maximum recursion depth exceeded" +msgstr "Превышена максимальная глубина рекурсии" -#: py/persistentcode.c -msgid "incompatible .mpy arch" -msgstr "несовместимые .mpy арка" +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" +msgstr "объект не в последовательности" -#: py/persistentcode.c -msgid "incompatible .mpy file" -msgstr "несовместимый файл .mpy" +#: py/stream.c shared-bindings/getpass/__init__.c +msgid "stream operation not supported" +msgstr "Потоковая операция не поддерживается" -#: py/objstr.c -msgid "incomplete format" -msgstr "Неполный формат" +#: py/vm.c +msgid "local variable referenced before assignment" +msgstr "локальная переменная, на которую ссылается перед присвоением" -#: py/objstr.c -msgid "incomplete format key" -msgstr "Неполный ключ форматирования" +#: py/vm.c +msgid "no active exception to reraise" +msgstr "Нет активного исключения для повторного создания" -#: extmod/modbinascii.c -msgid "incorrect padding" -msgstr "Неправильная набивка" +#: py/vm.c +msgid "opcode" +msgstr "код операции" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c -msgid "index is out of bounds" -msgstr "индекс выходит из границ" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot create a new Adapter; use _bleio.adapter;" +msgstr "Невозможно создать новый Adapter; используйте _bleio.adapter;" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "index must be tuple or int" -msgstr "Индекс должен быть кортежом или целым кортежом" +#: shared-bindings/_bleio/Adapter.c +msgid "Could not set address" +msgstr "Не удалось задать адрес" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" -msgstr "индекс вне диапазона" +#: shared-bindings/_bleio/Adapter.c +#, c-format +msgid "interval must be in range %s-%s" +msgstr "Интервал должен находиться в диапазоне %s-%s" -#: py/obj.c -msgid "indices must be integers" -msgstr "индексы должны быть целыми числами" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot have scan responses for extended, connectable advertisements." +msgstr "" +"Не может быть ответов на сканирование для расширенных подключаемых рекламных " +"объявлений." -#: extmod/ulab/code/ndarray.c -msgid "indices must be integers, slices, or Boolean lists" -msgstr "индексы должны быть целыми числами, срезами или логическими списками" +#: shared-bindings/_bleio/Adapter.c +msgid "Only connectable advertisements can be directed" +msgstr "Только подключаемые объявления могут быть направлены" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "инициализация I2C" +#: shared-bindings/_bleio/Adapter.c +msgid "non-zero timeout must be >= interval" +msgstr "Ненулевое время ожидания должно быть >= интервал" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "initial values must be iterable" -msgstr "Начальные значения должны быть итерируемыми" +#: shared-bindings/_bleio/Adapter.c +msgid "window must be <= interval" +msgstr "окно должно быть <= интервал" -#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c -msgid "initial_value length is wrong" -msgstr "длина первоначального_значения ошибочна" +#: shared-bindings/_bleio/Adapter.c +msgid "Prefix buffer must be on the heap" +msgstr "Буфер префикса должен находиться в куче" -#: py/compile.c -msgid "inline assembler must be a function" -msgstr "Встроенный ассемблер должен быть функцией" +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "ХарактеристикаЗапись в буфер не предусмотрена" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output dimensions differ" -msgstr "Входные и выходные размеры различаются" +#: shared-bindings/_bleio/Connection.c +msgid "" +"Connection has been disconnected and can no longer be used. Create a new " +"connection." +msgstr "" +"Соединение было отключено и больше не может использоваться. Создайте новое " +"соединение." -#: extmod/ulab/code/numpy/vector.c -msgid "input and output shapes differ" -msgstr "Входные и выходные формы различаются" +#: shared-bindings/_bleio/PacketBuffer.c +#, c-format +msgid "Buffer too short by %d bytes" +msgstr "Буфер слишком короткий на %d байт" -#: extmod/ulab/code/numpy/create.c -msgid "input argument must be an integer, a tuple, or a list" -msgstr "Входной аргумент должен быть целым числом, кортежом или списком" +#: shared-bindings/_bleio/PacketBuffer.c +msgid "No connection: length cannot be determined" +msgstr "Нет соединения: длина не может быть определена" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "input array length must be power of 2" -msgstr "Длина входного массива должна быть равна степени 2" +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "UUID строка не 'xxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxxxxx \"" -#: extmod/ulab/code/numpy/create.c -msgid "input arrays are not compatible" -msgstr "Входные массивы несовместимы" +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "Значение UUID не является строковым, целым или байтовым буфером" -#: extmod/ulab/code/numpy/poly.c -msgid "input data must be an iterable" -msgstr "Входные данные должны быть итерируемыми" +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "не 128-битный UUID" -#: extmod/ulab/code/numpy/vector.c -msgid "input dtype must be float or complex" -msgstr "Входной тип dtype должен быть плавающим или сложным" +#: shared-bindings/_bleio/__init__.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c +#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c +msgid "Read-only" +msgstr "Только для чтения" -#: extmod/ulab/code/numpy/poly.c -msgid "input is not iterable" -msgstr "Ввод не является итерируемым" +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "Неправильный размер буфера" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "input matrix is asymmetric" -msgstr "Входная матрица асимметрична" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" +msgstr "вложенный индекс должен быть int" -#: extmod/ulab/code/numpy/linalg/linalg.c -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "input matrix is singular" -msgstr "Входная матрица является сингулярной" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" +msgstr "Индекс должен быть кортежом или целым кортежом" -#: extmod/ulab/code/numpy/create.c -msgid "input must be 1- or 2-d" -msgstr "Вход должен быть 1- или 2-D" +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" +msgstr "Слишком маленький буфер карты" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be a 1D ndarray" -msgstr "Ввод должен быть 1D массивом ndarray" +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" +msgstr "Слишком маленький буфер символов" -#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c -msgid "input must be a dense ndarray" -msgstr "Ввод должен быть плотным массивом ndarray" +#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +msgid "Pin is input only" +msgstr "Пин является только входом" -#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c -msgid "input must be an ndarray" -msgstr "Ввод должен быть массивом ndarray" +#: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c +#, c-format +msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgstr "" +"Непревзойденное количество элементов на RHS (ожидалось %d, получено %d)." -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be an ndarray, or a scalar" -msgstr "Ввод должен быть массивом ndarray или скаляр" +#: shared-bindings/aesio/aes.c +msgid "Key must be 16, 24, or 32 bytes long" +msgstr "Ключ должен быть длинной 16, 24 или 32 байта" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "input must be one-dimensional" -msgstr "Входные данные должны быть одномерными" +#: shared-bindings/aesio/aes.c +msgid "Requested AES mode is unsupported" +msgstr "Запрошенный режим AES не поддерживается" -#: extmod/ulab/code/ulab_tools.c -msgid "input must be square matrix" -msgstr "Входные данные должны быть квадратной матрицей" +#: shared-bindings/aesio/aes.c +msgid "Source and destination buffers must be the same length" +msgstr "Исходный и конечный буферы должны иметь одинаковую длину" -#: extmod/ulab/code/numpy/numerical.c -msgid "input must be tuple, list, range, or ndarray" -msgstr "Ввод должен быть кортеж, список, диапазон или массивом ndarray" +#: shared-bindings/aesio/aes.c +msgid "ECB only operates on 16 bytes at a time" +msgstr "ECB работает только с 16 байтами за раз" -#: extmod/ulab/code/numpy/poly.c -msgid "input vectors must be of equal length" -msgstr "Входные векторы должны быть одинаковой длины" +#: shared-bindings/aesio/aes.c +msgid "CBC blocks must be multiples of 16 bytes" +msgstr "Блоки CBC должны быть кратны 16 байтам" -#: extmod/ulab/code/numpy/approx.c -msgid "interp is defined for 1D iterables of equal length" -msgstr "interp определен для 1D-итераций одинаковой длины" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." +msgstr "Нарежьте и оцените разную длину." -#: shared-bindings/_bleio/Adapter.c -#, c-format -msgid "interval must be in range %s-%s" -msgstr "Интервал должен находиться в диапазоне %s-%s" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Значения массива должны быть однобайтовыми." -#: py/compile.c -msgid "invalid arch" -msgstr "недействительная арка" +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." +msgstr "Невозможно записать в Sleep_memory." -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" -msgstr "неверный бит_на_пиксель %d, должно быть 1, 2, 4, 8, 16, 24 или 32" +#: shared-bindings/alarm/__init__.c +msgid "Expected a kind of %q" +msgstr "Ожидаемый вид %q" -#: shared-module/ssl/SSLSocket.c -msgid "invalid cert" -msgstr "Неверный сертификат" +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" +msgstr "RTC не поддерживается на этой плате" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element size %d for bits_per_pixel %d\n" -msgstr "недопустимый размер элемента %d для битов на_пиксель %d\n" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" +msgstr "Поставьте один из monotonic_time или epoch_time" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element_size %d, must be, 1, 2, or 4" -msgstr "аннулированный элемент_размер %d, должен быть, 1, 2 или 4" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" +msgstr "epoch_time не поддерживается на этой плате" -#: shared-bindings/traceback/__init__.c -msgid "invalid exception" -msgstr "Недопустимое исключение" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." +msgstr "Время в прошлом." -#: py/objstr.c -msgid "invalid format specifier" -msgstr "Недопустимый спецификатор формата" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q должен быть массивом байтов или массивом типа «H» или «B»" -#: shared-bindings/wifi/Radio.c -msgid "invalid hostname" -msgstr "Недопустимое имя хоста" +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c shared-bindings/mcp4822/MCP4822.c +#: shared-bindings/usb_audio/USBMicrophone.c +msgid "Not playing" +msgstr "Не воспроизводится (Not playing)" -#: shared-module/ssl/SSLSocket.c -msgid "invalid key" -msgstr "Неверный ключ" +#: shared-bindings/audiobusio/PDMIn.c +msgid "%q must be multiple of 8." +msgstr "%q должно быть кратно 8." -#: py/compile.c -msgid "invalid micropython decorator" -msgstr "неверный декоратор микропитона" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Cannot record to a file" +msgstr "Невозможно записать в файл" -#: ports/espressif/common-hal/espcamera/Camera.c -msgid "invalid setting" -msgstr "Недопустимый параметр" +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "Емкость места назначения меньше длины места назначения." -#: shared-bindings/random/__init__.c -msgid "invalid step" -msgstr "недействительный шаг" +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +msgstr "" +"буфер назначения должен быть массивом типа «H» для битовой_глубины = 16" -#: py/compile.c py/parse.c -msgid "invalid syntax" -msgstr "недействительный синтаксис" +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +msgstr "" +"буфер назначения должен быть байтоммассива или массивом типа \"B\" для " +"бит_глубины = 8" -#: py/parsenum.c -msgid "invalid syntax for integer" -msgstr "недействительный синтаксис для целых чисел" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q должен быть массивом байтов или массивом типа «h», «H», «b» или «B»" -#: py/parsenum.c -#, c-format -msgid "invalid syntax for integer with base %d" -msgstr "недействительный синтаксис для целых чисел с основанием %d" +#: shared-bindings/audiocore/RawSample.c +msgid "Length of %q must be an even multiple of channel_count * type_size" +msgstr "Длина %q должна быть четной, кратной количеству каналов * размер_типа" -#: py/parsenum.c -msgid "invalid syntax for number" -msgstr "недействительный синтаксис для номера" +#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c +msgid "file must be a file opened in byte mode" +msgstr "Файл должен быть файлом, открытым в байтовом режиме" -#: py/objtype.c -msgid "issubclass() arg 1 must be a class" -msgstr "issubclass() arg 1 должен быть классом" +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/Flanger.c +#: shared-bindings/audiodelays/GranularPitchShift.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c +#: shared-bindings/audiomixer/Mixer.c +msgid "bits_per_sample must be 8 or 16" +msgstr "bits_per_sample должно быть 8 или 16" -#: py/objtype.c -msgid "issubclass() arg 2 must be a class or a tuple of classes" -msgstr "issubclass() arg 2 должен быть классом или кортежом классов" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "iterations did not converge" -msgstr "итерации не сходятся" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "" -#: py/objstr.c -msgid "join expects a list of str/bytes objects consistent with self object" +#: shared-bindings/audioi2sin/I2SIn.c +#, c-format +msgid "invalid destination buffer, must be an array of type: %c" msgstr "" -"присоединяйтесь к ожидающему список стр/байт объектов, совместимых с " -"самообъектом" -#: py/argcheck.c -msgid "keyword argument(s) not implemented - use normal args instead" +#: shared-bindings/audioio/AudioOut.c +msgid "%q and %q must be different" +msgstr "%q и %q должны быть разными" + +#: shared-bindings/bitmapfilter/__init__.c +msgid "" +"weights must be a sequence with an odd square number of elements (usually 9 " +"or 25)" msgstr "" -"Аргумент(ы) ключевого слова не реализован - используйте вместо него обычные " -"аргументы" +"Весом должна быть последовательность с нечетным квадратным числом элементов " +"(обычно 9 или 25)" -#: py/emitinlinethumb.c py/emitinlinextensa.c -msgid "label '%q' not defined" -msgstr "Метка '%q' не определена" +#: shared-bindings/bitmapfilter/__init__.c +msgid "weights must be an object of type %q, %q, %q, or %q, not %q " +msgstr "Веса должны быть объектом типа %q, %q, %q или %q, а не %q " -#: py/compile.c -msgid "label redefined" -msgstr "Метка переопределена" +#: shared-bindings/bitmaptools/__init__.c +msgid "clip point must be (x,y) tuple" +msgstr "Точка клипа должна быть кортежом (x,y)" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "уровень должен быть между 0 и 1" +#: shared-bindings/bitmaptools/__init__.c +msgid "source palette too large" +msgstr "Исходная палитра слишком велика" -#: py/objarray.c -msgid "lhs and rhs should be compatible" -msgstr "lhs и rhs должны быть совместимыми" +#: shared-bindings/bitmaptools/__init__.c +msgid "Bitmap size and bits per value must match" +msgstr "" +"Размер растрового изображения и число битов на значение должны совпадать" -#: py/emitnative.c -msgid "local '%q' has type '%q' but source is '%q'" -msgstr "Локальный '%q' имеет тип '%q', но источник '%q'" +#: shared-bindings/bitmaptools/__init__.c +msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" +msgstr "" +"Для цветового пространства L8 входное растровое изображение должно иметь 8 " +"бит на пиксель" -#: py/emitnative.c -msgid "local '%q' used before type known" -msgstr "местный '%q' используется перед типом" +#: shared-bindings/bitmaptools/__init__.c +msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" +msgstr "" +"Для цветовых пространств RGB входное растровое изображение должно иметь 16 " +"бит на пиксель" -#: py/vm.c -msgid "local variable referenced before assignment" -msgstr "локальная переменная, на которую ссылается перед присвоением" +#: shared-bindings/bitmaptools/__init__.c +msgid "Unsupported colorspace" +msgstr "Неподдерживаемое цветовое пространство" -#: ports/espressif/common-hal/canio/CAN.c -msgid "loopback + silent mode not supported by peripheral" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap size must match the other bitmaps" msgstr "" -"Замыкание на себя + бесшумный режим, не поддерживаемый периферийными " -"устройствами" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS already initialized" -msgstr "mDNS уже инициализирован" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap must have 8 bits per pixel" +msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS only works with built-in WiFi" -msgstr "mDNS работает только со встроенным WiFi" +#: shared-bindings/bitmaptools/__init__.c +msgid "out of range of target" +msgstr "вне досягаемости цели" -#: py/parse.c -msgid "malformed f-string" -msgstr "Неправильно сформированная F-строка" +#: shared-bindings/bitmaptools/__init__.c +msgid "value out of range of target" +msgstr "Величина выходящая за пределы диапазона цели" -#: shared-bindings/_stage/Layer.c -msgid "map buffer too small" -msgstr "Слишком маленький буфер карты" +#: shared-bindings/bitmaptools/__init__.c +msgid "background value out of range of target" +msgstr "Фоновое значение вне диапазона цели" -#: py/modmath.c shared-bindings/math/__init__.c -msgid "math domain error" -msgstr "Ошибка математической области" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "Типы массивов координат имеют разные размеры" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "matrix is not positive definite" -msgstr "матрица не является положительно определенной" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "Координатные массивы имеют разные длины" -#: ports/espressif/common-hal/_bleio/Descriptor.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element_size %d, must be, 1, 2, or 4" +msgstr "аннулированный элемент_размер %d, должен быть, 1, 2 или 4" + +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element size %d for bits_per_pixel %d\n" +msgstr "недопустимый размер элемента %d для битов на_пиксель %d\n" + +#: shared-bindings/bitmaptools/__init__.c #, c-format -msgid "max_length must be 0-%d when fixed_length is %s" -msgstr "максимальная_длина должна быть 0-%d когда фиксированная длина %s" +msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +msgstr "неверный бит_на_пиксель %d, должно быть 1, 2, 4, 8, 16, 24 или 32" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c -msgid "maximum number of dimensions is " -msgstr "Максимальное количество измерений составляет " +#: shared-bindings/bitmaptools/__init__.c +msgid "bitmap sizes must match" +msgstr "Размеры растровых изображений должны совпадать" -#: py/runtime.c -msgid "maximum recursion depth exceeded" -msgstr "Превышена максимальная глубина рекурсии" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 2 or 65536" +msgstr "source_bitmap должен иметь значение_счет 2 или 65536" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter must be > 0" -msgstr "maxiter должен быть > 0" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 65536" +msgstr "source_bitmap должен иметь значение_счет 65536" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter should be > 0" -msgstr "макситер должен быть > 0" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 8" +msgstr "source_bitmap должен иметь значение_счет 8" -#: extmod/ulab/code/numpy/numerical.c -msgid "median argument must be an ndarray" -msgstr "Средний аргумент должен быть массивом ndarray" +#: shared-bindings/bitmaptools/__init__.c +msgid "unsupported colorspace for dither" +msgstr "Неподдерживаемое цветовое пространство для дизеринга" -#: py/runtime.c +#: shared-bindings/bitops/__init__.c #, c-format -msgid "memory allocation failed, allocating %u bytes" -msgstr "Сбой выделения памяти, выделение %u байт" +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "Длина входного буфера (%d) должна быть кратна количеству цепочек (%d)" -#: py/runtime.c -msgid "memory allocation failed, heap is locked" -msgstr "Не удалось выделить память, куча заблокирована" +#: shared-bindings/board/__init__.c +msgid "No default %q bus" +msgstr "Нет шины %q по умолчанию" -#: py/objarray.c -msgid "memoryview offset too large" -msgstr "Слишком большое смещение просмотра памяти" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c +msgid "Display rotation must be in 90 degree increments" +msgstr "Поворот дисплея должен осуществляться с шагом 90 градусов" -#: py/objarray.c -msgid "memoryview: length is not a multiple of itemsize" -msgstr "вид памяти: длина не является множеством элементов" +#: shared-bindings/busdisplay/BusDisplay.c +msgid "%q must be 1 when %q is True" +msgstr "%q должен быть равен 1, если %q имеет значение True" -#: extmod/modtime.c -msgid "mktime needs a tuple of length 8 or 9" -msgstr "mktime нужен кортеж длины 8 или 9" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Display must have a 16 bit colorspace." +msgstr "Дисплей должен иметь 16 битное цветовое пространство." -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "mode must be complete, or reduced" -msgstr "Режим должен быть завершенным или уменьшенным" +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c +msgid "tx and rx cannot both be None" +msgstr "tx и rx не могут быть одновременно None" -#: py/builtinimport.c -msgid "module not found" -msgstr "модуль не найден" +#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." +msgstr "Должен быть субклассом %q." -#: ports/espressif/common-hal/wifi/Monitor.c -msgid "monitor init failed" -msgstr "Сбой инициализации монитора" +#: shared-bindings/canio/RemoteTransmissionRequest.c +msgid "RemoteTransmissionRequests limited to 8 bytes" +msgstr "Запросы на удаленную передачу ограничены 8 байтами" -#: extmod/ulab/code/numpy/poly.c -msgid "more degrees of freedom than data points" -msgstr "Больше степеней свободы чем точек данных" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Cannot set value when direction is input." +msgstr "Невозможно установить значение при вводе направления." -#: py/compile.c -msgid "multiple *x in assignment" -msgstr "Несколько *x в назначении" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Drive mode not used when direction is input." +msgstr "Режим движения не используется при вводе направления." -#: py/objtype.c -msgid "multiple bases have instance lay-out conflict" -msgstr "Несколько баз имеют конфликт расположения экземпляров" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Pull not used when direction is output." +msgstr "Тяга не используется, когда выводится направление." -#: py/objtype.c -msgid "multiple inheritance not supported" -msgstr "Множественное наследование не поддерживается" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" +msgstr "" -#: py/emitnative.c -msgid "must raise an object" -msgstr "должен поднять объект" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" +msgstr "" -#: py/modbuiltins.c -msgid "must use keyword argument for key function" -msgstr "Необходимо использовать аргумент ключевого слова для ключевой функции" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" +msgstr "" -#: py/runtime.c -msgid "name '%q' is not defined" -msgstr "Имя '%q' не определено" +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Невозможно удалить значения" -#: py/runtime.c -msgid "name not defined" -msgstr "Имя не определено" +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +msgid "Slices not supported" +msgstr "Фрагменты не поддерживаются" -#: py/qstr.c -msgid "name too long" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" +"цветовой буфер должен быть байтом массива или массивом типа \"b\" или \"B\"" -#: py/persistentcode.c -msgid "native code in .mpy unsupported" -msgstr "Нативный код в .mpy не поддерживается" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" +msgstr "" +"Цветовой буфер должен иметь размер 3 байта (RGB) или 4 байта (RGB + байт " +"заполнения)" -#: py/asmthumb.c -msgid "native method too big" -msgstr "родной метод слишком большой" +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" +msgstr "Цвет должен быть от 0x000000 до 0xffffff" -#: py/emitnative.c -msgid "native yield" -msgstr "родной урожай" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer, tuple, list, or int" +msgstr "Цветовой буфер должен быть буфером, кортежом, списком или целым числом" -#: extmod/ulab/code/ndarray.c -msgid "ndarray length overflows" -msgstr "Переполнение длины массива ndarray" +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c +msgid "unsupported %q type" +msgstr "Неподдерживаемый тип %Q" -#: py/runtime.c -#, c-format -msgid "need more than %d values to unpack" -msgstr "Для распаковки требуется более значений %d" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" +msgstr "Ширина плитки должна точно делить ширину растрового изображения" -#: py/modmath.c -msgid "negative factorial" -msgstr "отрицательный факториал" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" +msgstr "Высота плитки должна точно делить высоту растрового изображения" -#: py/objint_longlong.c py/objint_mpz.c py/runtime.c -msgid "negative power with no float support" -msgstr "Отрицательная мощность без поплавковой опоры" +#: shared-bindings/displayio/TileGrid.c +msgid "New bitmap must be same size as old bitmap" +msgstr "" +"Новое растровое изображение должно быть того же размера, что и старое " +"растровое изображение" -#: py/objint_mpz.c py/runtime.c -msgid "negative shift count" -msgstr "Количество отрицательных сдвигов" +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" +msgstr "Выход индекса плитки за пределы" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "nested index must be int" -msgstr "вложенный индекс должен быть int" +#: shared-bindings/dualbank/__init__.c +msgid "offset must be >= 0" +msgstr "Смещение должно быть >= 0" -#: shared-module/sdcardio/SDCard.c -msgid "no SD card" -msgstr "нет SD карты" +#: shared-bindings/epaperdisplay/EPaperDisplay.c +msgid "Refresh too soon" +msgstr "Слишком раннее обновление" -#: py/vm.c -msgid "no active exception to reraise" -msgstr "Нет активного исключения для повторного создания" +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Buffer is not a bytearray." +msgstr "Буфер не является байтовым массивом." -#: py/compile.c -msgid "no binding for nonlocal found" -msgstr "Привязка для нелокальных не найдена" +#: shared-bindings/gnss/GNSS.c +msgid "System entry must be gnss.SatelliteSystem" +msgstr "Системная запись должна быть gnss. Спутниковая система" -#: shared-module/msgpack/__init__.c -msgid "no default packer" -msgstr "Нет упаковщика по умолчанию" +#: shared-bindings/hashlib/__init__.c +msgid "Unsupported hash algorithm" +msgstr "Неподдерживаемый алгоритм хеширования" -#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c -msgid "no default seed" -msgstr "Нет начального числа по умолчанию" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" +msgstr "" -#: py/builtinimport.c -msgid "no module named '%q'" -msgstr "Нет модуля с именем '%Q'" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" +msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no response from SD card" -msgstr "нет ответа с SD карты" +#: shared-bindings/i2ctarget/I2CTarget.c +msgid "addresses is empty" +msgstr "адреса пусты" -#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c -msgid "no such attribute" -msgstr "нет такого атрибута" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" +msgstr "Недействительная строка IP" + +#: shared-bindings/ipaddress/IPv4Address.c +#, c-format +msgid "Address must be %d bytes long" +msgstr "Адрес должен быть длиной %d байт" + +#: shared-bindings/ipaddress/__init__.c +msgid "Only int or string supported for ip" +msgstr "Для IP поддерживаются только int или строка" + +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "width must be greater than zero" +msgstr "ширина должна быть больше нуля" + +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "Scale dimensions must divide by 3" +msgstr "Размеры шкалы необходимо разделить на 3" + +#: shared-bindings/is31fl3741/IS31FL3741.c +msgid "Mapping must be a tuple" +msgstr "Сопоставление должно быть кортежом" -#: ports/espressif/common-hal/_bleio/Connection.c -#: ports/nordic/common-hal/_bleio/Connection.c -msgid "non-UUID found in service_uuids_whitelist" -msgstr "не-UUID найден в сервисе_uuids_белый список" +#: shared-bindings/jpegio/JpegDecoder.c +msgid "%q must be of type %q, %q, or %q, not %q" +msgstr "%q должен иметь тип %q, %q или %q, а не %q" -#: py/compile.c -msgid "non-default argument follows default argument" +#: shared-bindings/mdns/Server.c +msgid "" +"Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -"Аргумент отличный от аргумента по умолчанию следует за аргументом по " -"умолчанию" - -#: py/objstr.c -msgid "non-hex digit found" -msgstr "Ненайдена шестнадцатеричная цифра" +"Не удалось добавить служебную TXT-запись; в txt_records обнаружена нестрока " +"или байт" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "non-zero timeout must be > 0.01" -msgstr "Ненулевое время ожидания должно быть > 0,01" +#: shared-bindings/memorymap/AddressRange.c +msgid "Address range wraps around" +msgstr "Обертывание диапазона адресов" -#: shared-bindings/_bleio/Adapter.c -msgid "non-zero timeout must be >= interval" -msgstr "Ненулевое время ожидания должно быть >= интервал" +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" +msgstr "%q содержит пины дупликаты" -#: shared-bindings/_bleio/UUID.c -msgid "not a 128-bit UUID" -msgstr "не 128-битный UUID" +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" +msgstr "%q и %q содержат пины дупликаты" -#: py/parse.c -msgid "not a constant" -msgstr "не константа" +#: shared-bindings/msgpack/ExtType.c +msgid "code outside range 0~127" +msgstr "код вне диапазона 0~127" -#: py/objstr.c -msgid "not all arguments converted during string formatting" -msgstr "Не все аргументы преобразуются при форматировании строки" +#: shared-bindings/msgpack/__init__.c +msgid "default is not a function" +msgstr "По умолчанию не является функцией" -#: py/objstr.c -msgid "not enough arguments for format string" -msgstr "Недостаточно аргументов для строки форматирования" +#: shared-bindings/msgpack/__init__.c +msgid "ext_hook is not a function" +msgstr "ext_hook не является функцией" -#: extmod/ulab/code/numpy/carray/carray_tools.c -msgid "not implemented for complex dtype" -msgstr "не реализовано для сложного типа d" +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." +msgstr "Невозможно выполнить запись в nvm." -#: extmod/ulab/code/numpy/bitwise.c -msgid "not supported for input types" -msgstr "Не поддерживается для типов ввода" +#: shared-bindings/os/__init__.c +msgid "No hardware random available" +msgstr "Отсутствует аппаратный генератор случайных чисел" -#: extmod/ulab/code/numpy/create.c -msgid "number of points must be at least 2" -msgstr "Количество баллов должно быть не менее 2" +#: shared-bindings/paralleldisplaybus/ParallelBus.c +msgid "Specify exactly one of data0 or data_pins" +msgstr "Укажите точно один из data0 или data_pins" -#: py/builtinhelp.c -msgid "object " -msgstr "объект " +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "Не удалось отправить команду." -#: py/obj.c -#, c-format -msgid "object '%s' isn't a tuple or list" -msgstr "Объект \"%s\" не является кортежом или списком" +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Массив должен содержать полуслова (тип 'H')" -#: py/obj.c -msgid "object doesn't support item assignment" -msgstr "Объект не поддерживает назначение элементов" +#: shared-bindings/pwmio/PWMOut.c +msgid "Conflicting settings for shared resource" +msgstr "" -#: py/obj.c -msgid "object doesn't support item deletion" -msgstr "Объект не поддерживает удаление элементов" +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" +msgstr "Остановка недоступна с начального запуска" -#: py/obj.c -msgid "object has no len" -msgstr "Объект не имеет объектива" +#: shared-bindings/random/__init__.c +msgid "invalid step" +msgstr "недействительный шаг" -#: py/obj.c -msgid "object isn't subscriptable" -msgstr "Объект не имеет индекса" +#: shared-bindings/random/__init__.c +msgid "empty sequence" +msgstr "пустая последовательность" -#: py/runtime.c -msgid "object not an iterator" -msgstr "объект не итератор" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "" -#: py/objtype.c py/runtime.c -msgid "object not callable" -msgstr "Объект не вызывается" +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" +msgstr "Длина rgb_pins должна быть 6, 12, 18, 24 или 30" -#: py/sequence.c shared-bindings/displayio/Group.c -msgid "object not in sequence" -msgstr "объект не в последовательности" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] is not on the same port as clock" +msgstr "rgb_pins[%d] не находится на том же порту что и часы" -#: py/runtime.c -msgid "object not iterable" -msgstr "Объект не итерируемый" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" +msgstr "rgb_pins[%d] дублирует другое назначение пинов" -#: py/obj.c +#: shared-bindings/rgbmatrix/RGBMatrix.c #, c-format -msgid "object of type '%s' has no len()" -msgstr "объект типа «%s» не имеет len()" +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" +msgstr "" +"Распиновка использует %d байт на элемент, что превышает идеальное %d байт. " +"Если этого нельзя избежать, передайте конструктору allow_inefficient=True" -#: py/obj.c -msgid "object with buffer protocol required" -msgstr "Объект с обязательным буферным протоколом" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" +msgstr "Количество используемых rgb-пинов должно быть кратно 6, а не %d" -#: py/objstr.c -msgid "odd-length string" -msgstr "Строка нечетной длины" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +msgstr "" +"Адресные контакты %d, контакты rgb %d и плитки %d обозначают высоту %d, а не " +"%d" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "off" -msgstr "выключить" +#: shared-bindings/socketpool/Socket.c +msgid "port must be >= 0" +msgstr "порт должен быть >= 0" -#: extmod/ulab/code/utils/utils.c -msgid "offset is too large" -msgstr "Смещение слишком большое" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "buffer too small for requested bytes" +msgstr "Слишком маленький буфер для запрашиваемых байтов" -#: shared-bindings/dualbank/__init__.c -msgid "offset must be >= 0" -msgstr "Смещение должно быть >= 0" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" +msgstr "Имя или услуга не известны" -#: extmod/ulab/code/numpy/create.c -msgid "offset must be non-negative and no greater than buffer length" -msgstr "Смещение должно быть неотрицательным и не превышать длину буфера" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only bit_depth=16 is supported" -msgstr "поддерживается только бит_глубина=16" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" +msgstr "Контекст на стороне сервера не может иметь имя хоста" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only mono is supported" -msgstr "Поддерживается только моно" +#: shared-bindings/storage/__init__.c shared-bindings/usb_audio/__init__.c +#: shared-bindings/usb_cdc/__init__.c shared-bindings/usb_hid/__init__.c +#: shared-bindings/usb_midi/__init__.c shared-bindings/usb_video/__init__.c +msgid "Cannot change USB devices now" +msgstr "Невозможно изменить USB устройство сейчас" -#: extmod/ulab/code/numpy/create.c -msgid "only ndarrays can be concatenated" -msgstr "только массивы ndarrays могут быть объединены" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c +msgid "File not found" +msgstr "Файл не найден" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only oversample=64 is supported" -msgstr "поддерживается только выборка = 64" +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" +msgstr "" +"Временная метка выходит за пределы допустимого диапазона для платформы time_t" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only sample_rate=16000 is supported" -msgstr "только образец_рейт=16000 поддерживается" +#: shared-bindings/traceback/__init__.c +msgid "Supply both or neither of %q and %q" +msgstr "" -#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "only slices with step=1 (aka None) are supported" -msgstr "поддерживаются только срезы с шагом = 1 (так как нет)" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" +msgstr "Запись файлов недоступна" -#: py/vm.c -msgid "opcode" -msgstr "код операции" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" +msgstr "Недопустимое исключение" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c -msgid "operands could not be broadcast together" -msgstr "Операнды не могут транслироваться вместе" +#: shared-bindings/usb_audio/USBSpeaker.c +msgid "destination must be an array of type 'h'" +msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for 2D arrays only" -msgstr "операция определена только для 2D-массивов" +#: shared-bindings/usb_audio/__init__.c +msgid "At least one of microphone and speaker must be enabled" +msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for ndarrays only" -msgstr "операция определена только для массивов ndarrays" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "%q, %q, и %q должны быть одной длинны" -#: extmod/ulab/code/ndarray.c -msgid "operation is implemented for 1D Boolean arrays only" -msgstr "операция реализована только для 1D логических массивов" +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." +msgstr "" +"Объект был деинициализирован и больше не может быть использован. Создайте " +"новый объект." -#: extmod/ulab/code/numpy/numerical.c -msgid "operation is not implemented on ndarrays" -msgstr "операция не реализована на массивах ndarrays" +#: shared-bindings/warnings/__init__.c +msgid "%q must be a subclass of %q" +msgstr "%q должен быть подклассом %q" -#: extmod/ulab/code/ndarray.c -msgid "operation is not supported for given type" -msgstr "Операция не поддерживается для данного типа" +#: shared-bindings/wifi/Monitor.c +msgid "%q out of bounds" +msgstr "%q за пределом" -#: extmod/ulab/code/ndarray_operators.c -msgid "operation not supported for the input types" -msgstr "операция не поддерживается для типов ввода" +#: shared-bindings/wifi/Radio.c +msgid "Invalid hex password" +msgstr "Неверный шестнадцатеричный пароль" -#: py/modbuiltins.c -msgid "ord expects a character" -msgstr "Орд ожидает персонажа" +#: shared-bindings/wifi/Radio.c +msgid "invalid hostname" +msgstr "Недопустимое имя хоста" -#: py/modbuiltins.c -#, c-format -msgid "ord() expected a character, but string of length %d found" -msgstr "ord() ожидал символ, но строка длины %d найдена" +#: shared-bindings/wifi/Radio.c +msgid "Invalid MAC address" +msgstr "Неверный MAC-адрес" -#: extmod/ulab/code/utils/utils.c -msgid "out array is too small" -msgstr "Наш массив слишком мал" +#: shared-bindings/wifi/Radio.c +msgid "AuthMode.OPEN is not used with password" +msgstr "Режим авторизации.OPEN не используется с паролем" -#: extmod/ulab/code/numpy/random/random.c -msgid "out has wrong type" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Invalid BSSID" +msgstr "Неверный BSSID" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for complex dtype" -msgstr "Ключевое слово out не поддерживается для сложного типа d" +#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c +msgid "Authentication failure" +msgstr "Ошибка аутентификации" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for function" -msgstr "ключевое слово не поддерживается для функции" +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" +msgstr "Нет сети с этим ssid" -#: extmod/ulab/code/utils/utils.c -msgid "out must be a float dense array" -msgstr "Out должен быть плотным массивом с плавающей запятой" +#: shared-bindings/wifi/Radio.c +#, c-format +msgid "Unknown failure %d" +msgstr "Неизвестный сбой %d" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be an ndarray" -msgstr "out должен быть массивом ndarray" +#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#, c-format +msgid "No I2C device at address: 0x%x" +msgstr "Нет устройства I2C по адресу: %x" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be of float dtype" -msgstr "Выход должен быть поплавкового типа" +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Неверный размер блока формата" -#: shared-bindings/bitmaptools/__init__.c -msgid "out of range of target" -msgstr "вне досягаемости цели" +#: shared-module/audiocore/__init__.c shared-module/usb_audio/USBMicrophone.c +msgid "The sample's %q does not match" +msgstr "%q образца не совпадает" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array has wrong type" +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array must be contiguous" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Only 8/16-bit mono/stereo is supported" msgstr "" -#: py/objint_mpz.c -msgid "overflow converting long int to machine word" -msgstr "переполнение преобразование длинного целого в машинное слово" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "buffer_size too small for source" +msgstr "" -#: py/modstruct.c -#, c-format -msgid "pack expected %d items for packing (got %d)" -msgstr "Упаковка ожидаемых %d товаров для упаковки (получил %d)" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Couldn't allocate decoder" +msgstr "Не удалось выделить место для декодера" -#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c -msgid "palette must be 32 bytes long" -msgstr "Длина палитры должна составлять 32 байта" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Failed to parse MP3 file" +msgstr "Не удалось распарсить файл MP3" -#: py/emitinlinextensa.c -msgid "parameters must be registers in sequence a2 to a5" -msgstr "Параметры должны быть регистрами в последовательности от a2 до a5" +#: shared-module/bitbangio/I2C.c +msgid "%q too long" +msgstr "%q слишком долго" -#: py/emitinlinethumb.c -msgid "parameters must be registers in sequence r0 to r3" -msgstr "Параметры должны быть регистрами в последовательности от r0 до r3" +#: shared-module/bitmapfilter/__init__.c +msgid "bitmap size and depth must match" +msgstr "Размер и глубина растрового изображения должны совпадать" -#: extmod/vfs_posix_file.c -msgid "poll on file not available on win32" -msgstr "Опрос в файле недоступен в Win32" +#: shared-module/bitmapfilter/__init__.c +msgid "unsupported bitmap depth" +msgstr "неподдерживаемая глубина растрового изображения" -#: ports/espressif/common-hal/pulseio/PulseIn.c -msgid "pop from an empty PulseIn" -msgstr "вытолкнуть из пустого импульсного входа" +#: shared-module/displayio/Bitmap.c +msgid "Invalid bits per value" +msgstr "Недопустимое бит-на-значение" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/pulseio/PulseIn.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c -#: shared-bindings/ps2io/Ps2.c -msgid "pop from empty %q" -msgstr "Всплывающее окно из пустого %q" +#: shared-module/displayio/ColorConverter.c +msgid "Only one color can be transparent at a time" +msgstr "Только один цвет может быть прозрачным одновременно" -#: shared-bindings/socketpool/Socket.c -msgid "port must be >= 0" -msgstr "порт должен быть >= 0" +#: shared-module/displayio/Group.c +msgid "Layer already in a group" +msgstr "Слой уже в группе (Group)" -#: py/compile.c -msgid "positional arg after **" -msgstr "позиционный аргумент после **" +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass" +msgstr "Слой должен быть группой (Group) или субклассом TileGrid" -#: py/compile.c -msgid "positional arg after keyword arg" -msgstr "позиционный аргумент после ключевого слова аргумента" +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" +msgstr "" +"Поддерживается только формат Windows, несжатый BMP: заданный размер " +"заголовка - %d" -#: py/objint_mpz.c -msgid "pow() 3rd argument cannot be 0" -msgstr "3-й аргумент pow() не может быть равен 0" +#: shared-module/displayio/OnDiskBitmap.c +msgid "RLE-compressed BMP not supported" +msgstr "RLE-сжатый BMP не поддерживается" -#: py/objint_mpz.c -msgid "pow() with 3 arguments requires integers" -msgstr "pow() с 3 аргументами требует целых чисел" +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" +msgstr "Не удается прочитать данные цветовой палитры" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "pull masks conflict with direction masks" -msgstr "Маски вытягивания конфликтуют с масками направления" +#: shared-module/displayio/__init__.c +msgid "Too many displays" +msgstr "Слишком много дисплеев" -#: py/parse.c -msgid "raw f-strings are not supported" -msgstr "Необработанные F-строки не поддерживаются" +#: shared-module/displayio/__init__.c +msgid "Too many display busses; forgot displayio.release_displays() ?" +msgstr "Слишком много шин дисплея; забыл displayio.release_displays()?" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "real and imaginary parts must be of equal length" -msgstr "реальные и воображаемые части должны быть одинаковой длины" +#: shared-module/displayio/bus_core.c +msgid "Unsupported display bus type" +msgstr "Неподдерживаемый тип шины дисплея" -#: py/builtinimport.c -msgid "relative import" -msgstr "Относительный импорт" +#: shared-module/gifio/GifWriter.c +msgid "unsupported colorspace for GifWriter" +msgstr "неподдерживаемое цветовое пространство для GifWriter" -#: py/obj.c +#: shared-module/i2cdisplaybus/I2CDisplayBus.c +#: shared-module/is31fl3741/IS31FL3741.c #, c-format -msgid "requested length %d but object has length %d" -msgstr "запрашиваемая длина %d, но объект имеет длину %d" +msgid "Unable to find I2C Display at %x" +msgstr "Не удается найти дисплей I2C в %x" -#: extmod/ulab/code/ndarray_operators.c -msgid "results cannot be cast to specified type" -msgstr "Результаты не могут быть приведены к указанному типу" +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" +msgstr "" -#: py/compile.c -msgid "return annotation must be an identifier" -msgstr "Возвращаемая аннотация должна быть идентификатором" +#: shared-module/imagecapture/ParallelImageCapture.c +msgid "This microcontroller does not support continuous capture." +msgstr "Этот микроконтроллер не поддерживает непрерывный захват." -#: py/emitnative.c -msgid "return expected '%q' but got '%q'" -msgstr "Возврат ожидался '%q', но получил '%q'" +#: shared-module/is31fl3741/FrameBuffer.c +msgid "LED mappings must match display size" +msgstr "Светодиодные сопоставления должны соответствовать размеру дисплея" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] duplicates another pin assignment" -msgstr "rgb_pins[%d] дублирует другое назначение пинов" +#: shared-module/jpegio/JpegDecoder.c +msgid "Interrupted by output function" +msgstr "Прерывается функцией выхода" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] is not on the same port as clock" -msgstr "rgb_pins[%d] не находится на том же порту что и часы" +#: shared-module/jpegio/JpegDecoder.c +msgid "Device error or wrong termination of input stream" +msgstr "Ошибка устройства или неправильное завершение входного потока" -#: extmod/ulab/code/numpy/numerical.c -msgid "roll argument must be an ndarray" -msgstr "аргумент roll должен быть массивом ndarray" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient memory pool for the image" +msgstr "Недостаточный объем памяти для изображения" -#: py/objstr.c -msgid "rsplit(None,n)" -msgstr "rsplit(Нет;n)" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient stream input buffer" +msgstr "Недостаточный буфер ввода потока" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -msgid "sampling rate out of range" -msgstr "Частота дискретизации выходит за пределы допустимого диапазона" +#: shared-module/jpegio/JpegDecoder.c +msgid "Parameter error" +msgstr "Ошибка параметра" -#: py/modmicropython.c -msgid "schedule queue full" -msgstr "Расписание Очередь заполнена" +#: shared-module/jpegio/JpegDecoder.c +msgid "Data format error (may be broken data)" +msgstr "Ошибка формата данных (возможно, данные повреждены)" + +#: shared-module/jpegio/JpegDecoder.c +msgid "Right format but not supported" +msgstr "Правильный формат, но не поддерживается" + +#: shared-module/jpegio/JpegDecoder.c +msgid "Unsupported JPEG (may be progressive)" +msgstr "" + +#: shared-module/jpegio/JpegDecoder.c +msgid "%q() without %q()" +msgstr "%q() без %q()" + +#: shared-module/memorymonitor/AllocationAlarm.c +#, c-format +msgid "Attempt to allocate %d blocks" +msgstr "Попытка выделения %d блоков" + +#: shared-module/msgpack/__init__.c +msgid "short read" +msgstr "короткое чтение" -#: py/builtinimport.c -msgid "script compilation not supported" -msgstr "Компиляция скриптов не поддерживается" +#: shared-module/msgpack/__init__.c +msgid "no default packer" +msgstr "Нет упаковщика по умолчанию" -#: py/nativeglue.c -msgid "set unsupported" -msgstr "Установить не поддерживается" +#: shared-module/msgpack/__init__.c supervisor/shared/settings.c +msgid "Invalid format" +msgstr "Недопустимый формат" -#: extmod/ulab/code/numpy/random/random.c -msgid "shape must be None, and integer or a tuple of integers" +#: shared-module/paralleldisplaybus/ParallelBus.c +msgid "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." msgstr "" +"Этот микроконтроллер поддерживает только data0=, а не data_pins=, поскольку " +"для него требуются смежные выводы." -#: extmod/ulab/code/ndarray.c -msgid "shape must be integer or tuple of integers" -msgstr "фигура должна быть целым числом или кортежом целых чисел" +#: shared-module/rgbmatrix/RGBMatrix.c +msgid "No timer available" +msgstr "Нет доступного таймера" -#: shared-module/msgpack/__init__.c -msgid "short read" -msgstr "короткое чтение" +#: shared-module/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Internal error #%d" +msgstr "Внутренняя ошибка #%d" -#: py/objstr.c -msgid "sign not allowed in string format specifier" -msgstr "Знак не разрешен в спецификаторе строкового формата" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v1 card" +msgstr "Таймаут в ожидании карты v1" -#: py/objstr.c -msgid "sign not allowed with integer format specifier 'c'" -msgstr "Знак не разрешен со спецификатором целочисленного формата 'c'" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v2 card" +msgstr "Таймаут ожидания карты v2" -#: extmod/ulab/code/ulab_tools.c -msgid "size is defined for ndarrays only" -msgstr "размер определен только для массива ndarrays" +#: shared-module/sdcardio/SDCard.c +msgid "no SD card" +msgstr "нет SD карты" -#: extmod/ulab/code/numpy/random/random.c -msgid "size must match out.shape when used together" -msgstr "" +#: shared-module/sdcardio/SDCard.c +msgid "couldn't determine SD card version" +msgstr "Не удалось определить версию SD карты" -#: py/nativeglue.c -msgid "slice unsupported" -msgstr "Фрагмент не поддерживается" +#: shared-module/sdcardio/SDCard.c +msgid "no response from SD card" +msgstr "нет ответа с SD карты" -#: py/objint.c py/sequence.c -msgid "small int overflow" -msgstr "Маленькое переполнение int" +#: shared-module/sdcardio/SDCard.c +msgid "SD card CSD format not supported" +msgstr "Формат CSD SD-карты не поддерживается" -#: main.c -msgid "soft reboot\n" -msgstr "Мягкая перезагрузка\n" +#: shared-module/sdcardio/SDCard.c +msgid "can't set 512 block size" +msgstr "Не удается установить размер блока 512" -#: extmod/ulab/code/numpy/numerical.c -msgid "sort argument must be an ndarray" -msgstr "аргумент сортировки должен быть массивом ndarray" +#: shared-module/ssl/SSLSocket.c +msgid "Invalid socket for TLS" +msgstr "Неверный сокет для TLS" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos array must be of shape (n_section, 6)" -msgstr "Массив sos должен иметь форму (n_section, 6)" +#: shared-module/ssl/SSLSocket.c +msgid "invalid key" +msgstr "Неверный ключ" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos[:, 3] should be all ones" -msgstr "sos[:, 3] должны быть все единицы" +#: shared-module/ssl/SSLSocket.c +msgid "invalid cert" +msgstr "Неверный сертификат" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sosfilt requires iterable arguments" -msgstr "sosфильтр требует повторяющихся аргументов" +#: shared-module/storage/__init__.c +msgid "Mount point directory missing" +msgstr "Отсутствует каталог точки монтирования" -#: shared-bindings/bitmaptools/__init__.c -msgid "source palette too large" -msgstr "Исходная палитра слишком велика" +#: shared-module/storage/__init__.c +msgid "Cannot remount path when visible via USB." +msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 2 or 65536" -msgstr "source_bitmap должен иметь значение_счет 2 или 65536" +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' и 'O' не являются поддерживаемыми типами форматов" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 65536" -msgstr "source_bitmap должен иметь значение_счет 65536" +#: shared-module/struct/__init__.c +msgid "buffer size must match format" +msgstr "Размер буфера должен соответствовать формату" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 8" -msgstr "source_bitmap должен иметь значение_счет 8" +#: shared-module/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q должен быть массивом типа 'h \"" -#: extmod/modre.c -msgid "splitting with sub-captures" -msgstr "разделение с помощью подзахватов" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "" -#: py/objstr.c -msgid "start/end indices" -msgstr "Начальные/конечные индексы" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "" -#: shared-bindings/random/__init__.c -msgid "stop not reachable from start" -msgstr "Остановка недоступна с начального запуска" +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" +msgstr "Отсутствует подтяжка к земле на пине; Рекомендуется 1 Мегаом" -#: py/stream.c shared-bindings/getpass/__init__.c -msgid "stream operation not supported" -msgstr "Потоковая операция не поддерживается" +#: shared-module/usb/core/Device.c +msgid "No usb host port initialized" +msgstr "Порт USB-хоста не инициализирован" -#: py/objarray.c py/objstr.c -msgid "string argument without an encoding" -msgstr "строковый аргумент без кодировки" +#: shared-module/usb/core/Device.c +msgid "Pipe error" +msgstr "Ошибка трубопровода" -#: py/objstrunicode.c -msgid "string index out of range" -msgstr "индекс строки выходит за пределы диапазона" +#: shared-module/usb/core/Device.c +msgid "No configuration set" +msgstr "Нет конфигураций" -#: py/objstrunicode.c -#, c-format -msgid "string indices must be integers, not %s" -msgstr "Индексы строк должны быть целыми числами, а не %s" +#: shared-module/usb_hid/Device.c +msgid "USB busy" +msgstr "USB занят" -#: py/objarray.c py/objstr.c -msgid "substring not found" -msgstr "Подстрока не найдена" +#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Rectangle.c +msgid "can only have one parent" +msgstr "может иметь только одного родителя" -#: py/compile.c -msgid "super() can't find self" -msgstr "super() не может найти себя" +#: shared-module/vectorio/Polygon.c +msgid "Polygon needs at least 3 points" +msgstr "Полигону необходимо как минимум 3 точки" -#: extmod/modjson.c -msgid "syntax error in JSON" -msgstr "синтаксис ошибка в JSON" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" +msgstr "Повторное соединение" -#: extmod/modtime.c -msgid "ticks interval overflow" -msgstr "переполнение интервала тиков" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" +msgstr "Да" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "timeout duration exceeded the maximum supported value" -msgstr "" -"Продолжительность таймаута превысила максимальное поддерживаемое значение" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" +msgstr "Выключено" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "timeout must be < 655.35 secs" -msgstr "таймаут должен быть < 655.35 сек" +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" +msgstr "[отрезается по длине]" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -msgid "timeout waiting for flux" -msgstr "таймаут ожидания потока" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"You are in safe mode because:\n" +msgstr "" +"\n" +"Вы в безопасном режиме потому что:\n" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: shared-module/floppyio/__init__.c -msgid "timeout waiting for index pulse" -msgstr "таймаут ожидания индексного импульса" +#: supervisor/shared/safe_mode.c +msgid "Power dipped. Make sure you are providing enough power." +msgstr "" +"Мощность просела. Убедитесь, что вы обеспечиваете достаточную мощность." -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v1 card" -msgstr "Таймаут в ожидании карты v1" +#: supervisor/shared/safe_mode.c +msgid "You pressed the BOOT button at start up" +msgstr "Вы нажали кнопку BOOT при запуске" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v2 card" -msgstr "Таймаут ожидания карты v2" +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." +msgstr "Вы нажали кнопку сброса во время загрузки." -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "timer re-init" -msgstr "Повторное инициализация таймера" +#: supervisor/shared/safe_mode.c +msgid "CIRCUITPY drive could not be found or created." +msgstr "Диск CIRCUTPY не удалось найти или создать." -#: shared-bindings/time/__init__.c -msgid "timestamp out of range for platform time_t" +#: supervisor/shared/safe_mode.c +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -"Временная метка выходит за пределы допустимого диапазона для платформы time_t" +"Модуль «микроконтроллер» использовался для загрузки в безопасном режиме." -#: extmod/ulab/code/ndarray.c -msgid "tobytes can be invoked for dense arrays only" -msgstr "Тобайты могут быть вызваны только для плотных массивов" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." +msgstr "Ошибка в сейфе. py." -#: py/compile.c -msgid "too many args" -msgstr "слишком много аргументов" +#: supervisor/shared/safe_mode.c +msgid "Stack overflow. Increase stack size." +msgstr "Переполнение стека. Увеличьте размер стека." -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c -msgid "too many dimensions" -msgstr "Слишком много измерений" +#: supervisor/shared/safe_mode.c +msgid "USB devices need more endpoints than are available." +msgstr "USB-устройствам требуется больше конечных точек, чем доступно." -#: extmod/ulab/code/ndarray.c -msgid "too many indices" -msgstr "Слишком много индексов" +#: supervisor/shared/safe_mode.c +msgid "USB devices specify too many interface names." +msgstr "USB-устройства указывают слишком много имен интерфейсов." -#: py/asmthumb.c -msgid "too many locals for native method" -msgstr "Слишком много местных жителей для нативного метода" +#: supervisor/shared/safe_mode.c +msgid "Boot device must be first (interface #0)." +msgstr "Загрузочное устройство должно быть первым (интерфейс #0)." -#: py/runtime.c -#, c-format -msgid "too many values to unpack (expected %d)" -msgstr "Слишком много значений для распаковки (ожидаемый %d)" +#: supervisor/shared/safe_mode.c +msgid "Internal watchdog timer expired." +msgstr "Внутренний сторожевой таймер истек." -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D arrays of equal length" -msgstr "ловушка определена для одномерных 1D массивов одинаковой длины" +#: supervisor/shared/safe_mode.c +msgid "CircuitPython core code crashed hard. Whoops!\n" +msgstr "Основной код CircuitPython сильно разбился. Упс!\n" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D iterables" -msgstr "ловушка определена для одномерных 1D итераций" +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." +msgstr "Выделение кучи, когда виртуальная машина не запущена." -#: py/obj.c -msgid "tuple/list has wrong length" -msgstr "Кортеж/список имеет неправильную длину" +#: supervisor/shared/safe_mode.c +msgid "Failed to write internal flash." +msgstr "Не удалось записать внутреннюю флэш-память." -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_driver_install returned esp-idf error #%d" -msgstr "twai_driver_install вернул ошибку esp-idf #%d" +#: supervisor/shared/safe_mode.c +msgid "Hard fault: memory access or instruction error." +msgstr "Жесткая ошибка: доступ к памяти или ошибка инструкции." -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_start returned esp-idf error #%d" -msgstr "twai_start вернул ошибку esp-idf #%d" +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." +msgstr "Прерванная ошибка." -#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c -msgid "tx and rx cannot both be None" -msgstr "tx и rx не могут быть одновременно None" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." +msgstr "Прыжок NLR не удался. Вероятно повреждение памяти." -#: py/objtype.c -msgid "type '%q' is not an acceptable base type" -msgstr "Тип '%Q' не является допустимым базовым типом" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate to the heap." +msgstr "Невозможно выделить место в куче." -#: py/objtype.c -msgid "type is not an acceptable base type" -msgstr "Тип не является приемлемым базовым типом" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." +msgstr "Неустранимая ошибка прошивки стороннего производителя." -#: py/runtime.c -msgid "type object '%q' has no attribute '%q'" -msgstr "тип объекта '%q' не имеет атрибута '%q \"" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Please file an issue with your program at github.com/adafruit/circuitpython/" +"issues." +msgstr "" +"\n" +"Пожалуйста подайте вопрос с вашей программой на github.com/adafruit/" +"circuitpython/issues." -#: py/objtype.c -msgid "type takes 1 or 3 arguments" -msgstr "тип занимает 1 или 3 аргумента" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" +msgstr "" +"\n" +"Нажмите на сброс чтобы выйти из безопасного режима.\n" -#: py/objint_longlong.c -msgid "ulonglong too large" -msgstr "голова длинная слишком большая" +#: supervisor/shared/settings.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "Произошла ошибка при получении '%s':\n" -#: py/parse.c -msgid "unexpected indent" -msgstr "Неожиданный отступ" +#: supervisor/shared/settings.c +msgid "Invalid unicode escape" +msgstr "Недопустимое экранирование Юникода" -#: py/bc.c -msgid "unexpected keyword argument" -msgstr "Неожиданный аргумент ключевого слова" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "Wi-Fi: " +msgstr "Wi-Fi: " -#: py/argcheck.c py/bc.c py/objnamedtuple.c -#: shared-bindings/traceback/__init__.c -msgid "unexpected keyword argument '%q'" -msgstr "неожиданный аргумент ключевого слова '%q'" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "off" +msgstr "выключить" -#: py/lexer.c -msgid "unicode name escapes" -msgstr "Экранирование имен в Юникоде" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "No IP" +msgstr "Нет IP" -#: py/parse.c -msgid "unindent doesn't match any outer indent level" -msgstr "Отступ не совпадает ни с одним уровнем внешнего отступа" +#~ msgid "" +#~ "Unspecified issue. Can be that the pairing prompt on the other device was " +#~ "declined or ignored." +#~ msgstr "" +#~ "Неуказанная проблема. Возможно, запрос на сопряжение на другом устройстве " +#~ "был отклонен или проигнорирован." -#: py/objstr.c #, c-format -msgid "unknown conversion specifier %c" -msgstr "Неизвестный спецификатор преобразования %c" +#~ msgid "SDIO Init Error %x" +#~ msgstr "Ошибка инициализации SDIO %x" -#: py/objstr.c -msgid "unknown format code '%c' for object of type '%q'" -msgstr "Неизвестный код формата '%c' для объекта типа '%q'" +#~ msgid "bit_depth must be 8, 16, 24, or 32." +#~ msgstr "Глубина_бита должна быть равна 8, 16, 24 или 32." -#: py/compile.c -msgid "unknown type" -msgstr "Неизвестный тип" +#~ msgid "%q renamed %q" +#~ msgstr "%q переименован %q" -#: py/compile.c -msgid "unknown type '%q'" -msgstr "Неизвестный тип '%q'" +#~ msgid "asm overflow" +#~ msgstr "Переполнение ASM" -#: py/objstr.c -#, c-format -msgid "unmatched '%c' in format" -msgstr "Несовпадающий '%c' в формате" +#~ msgid "cannot create instance" +#~ msgstr "Не удается создать экземпляр" -#: py/objtype.c py/runtime.c -msgid "unreadable attribute" -msgstr "Нечитаемый атрибут" +#~ msgid "native method too big" +#~ msgstr "родной метод слишком большой" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -msgid "unsupported %q type" -msgstr "Неподдерживаемый тип %Q" +#~ msgid "ulonglong too large" +#~ msgstr "голова длинная слишком большая" -#: py/emitinlinethumb.c -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" -msgstr "неподдерживаемая инструкция Thumb '%s' с аргументами %d" +#~ msgid "font must be 2048 bytes long" +#~ msgstr "Длина шрифта должна составлять 2048 байт" + +#~ msgid "graphic must be 2048 bytes long" +#~ msgstr "Длина рисунка должна составлять 2048 байт" + +#~ msgid "palette must be 32 bytes long" +#~ msgstr "Длина палитры должна составлять 32 байта" -#: py/emitinlinextensa.c #, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" -msgstr "неподдерживаемая инструкция Xtensa '%s' с аргументами %d" +#~ msgid "Buffer + offset too small %d %d %d" +#~ msgstr "Буфер + сдвиг слишком малы %d %d %d" -#: shared-module/bitmapfilter/__init__.c -msgid "unsupported bitmap depth" -msgstr "неподдерживаемая глубина растрового изображения" +#~ msgid "Byte buffer must be 16 bytes." +#~ msgstr "Буфер байтов должен быть размером 16 байтам." -#: shared-module/gifio/GifWriter.c -msgid "unsupported colorspace for GifWriter" -msgstr "неподдерживаемое цветовое пространство для GifWriter" +#~ msgid "UUID integer value must be 0-0xffff" +#~ msgstr "Целое значение UUID должно быть равно 0-0xffff" -#: shared-bindings/bitmaptools/__init__.c -msgid "unsupported colorspace for dither" -msgstr "Неподдерживаемое цветовое пространство для дизеринга" +#~ msgid "initial_value length is wrong" +#~ msgstr "длина первоначального_значения ошибочна" -#: py/objstr.c #, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" -msgstr "Неподдерживаемый символ формата '%c' (0x%x) при индексе %d" +#~ msgid "Invalid byte %.*s" +#~ msgstr "Неверный байт %.*s" -#: py/runtime.c -msgid "unsupported type for %q: '%s'" -msgstr "неподдерживаемый тип для %q: '%s'" +#~ msgid "Key not found" +#~ msgstr "Ключ не найден" -#: py/runtime.c -msgid "unsupported type for operator" -msgstr "Неподдерживаемый тип для оператора" +#~ msgid "Not supported JPEG standard" +#~ msgstr "Не поддерживается Стандарт JPEG" -#: py/runtime.c -msgid "unsupported types for %q: '%q', '%q'" -msgstr "Неподдерживаемые типы для %q: '%q', '%q'" +#~ msgid "%q moved from %q to %q" +#~ msgstr "%q переместился из %q в %q" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols is too high" -msgstr "Usecols слишком высок" +#~ msgid "filesystem must provide mount method" +#~ msgstr "Файловая система должна предусматривать метод монтирования" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols keyword must be specified" -msgstr "Ключевое слово usecols должно быть указано" +#~ msgid "start/end indices" +#~ msgstr "Начальные/конечные индексы" -#: py/objint.c #, c-format -msgid "value must fit in %d byte(s)" -msgstr "Значение должно совпадать с байтами %d" - -#: shared-bindings/bitmaptools/__init__.c -msgid "value out of range of target" -msgstr "Величина выходящая за пределы диапазона цели" +#~ msgid "%%c requires int or char" +#~ msgstr "%%c требует int или char" -#: extmod/moddeflate.c -#, fuzzy -msgid "wbits" -msgstr "wbits" +#~ msgid "'%q' object is not callable" +#~ msgstr "Объект '%q' не является вызываемым" -#: shared-bindings/bitmapfilter/__init__.c -msgid "" -"weights must be a sequence with an odd square number of elements (usually 9 " -"or 25)" -msgstr "" -"Весом должна быть последовательность с нечетным квадратным числом элементов " -"(обычно 9 или 25)" +#~ msgid "cannot create '%q' instances" +#~ msgstr "Не удается создать экземпляры '%q'" -#: shared-bindings/bitmapfilter/__init__.c -msgid "weights must be an object of type %q, %q, %q, or %q, not %q " -msgstr "Веса должны быть объектом типа %q, %q, %q или %q, а не %q " +#~ msgid "non-hex digit found" +#~ msgstr "Ненайдена шестнадцатеричная цифра" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "width must be greater than zero" -msgstr "ширина должна быть больше нуля" +#~ msgid "not all arguments converted during string formatting" +#~ msgstr "Не все аргументы преобразуются при форматировании строки" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "Wi-Fi не включен" +#~ msgid "not enough arguments for format string" +#~ msgstr "Недостаточно аргументов для строки форматирования" -#: ports/raspberrypi/common-hal/wifi/Monitor.c -msgid "wifi.Monitor not available" -msgstr "Wi-Fi. Монитор недоступен" +#~ msgid "odd-length string" +#~ msgstr "Строка нечетной длины" -#: shared-bindings/_bleio/Adapter.c -msgid "window must be <= interval" -msgstr "окно должно быть <= интервал" +#~ msgid "raw f-strings are not supported" +#~ msgstr "Необработанные F-строки не поддерживаются" -#: extmod/ulab/code/numpy/numerical.c -msgid "wrong axis index" -msgstr "Неправильный индекс оси" +#~ msgid "Unsupported format" +#~ msgstr "Неподдерживаемый формат" -#: extmod/ulab/code/numpy/create.c -msgid "wrong axis specified" -msgstr "Указана неправильная ось" +#~ msgid "Wifi is not enabled" +#~ msgstr "Wifi не включен" -#: extmod/ulab/code/numpy/io/io.c -msgid "wrong dtype" -msgstr "Неправильный тип" +#~ msgid "wifi is not enabled" +#~ msgstr "Wi-Fi не включен" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong index type" -msgstr "Неправильный тип индекса" +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "Невозможно перемонтировать '/' пока он виден через USB." -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c -#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c -#: extmod/ulab/code/numpy/vector.c -msgid "wrong input type" -msgstr "Неправильный тип ввода" +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q должен быть объектом %q, %q или %q" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of condition array" -msgstr "неправильная длина массива состояния" +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Блок данных должен следовать за блоком fmt" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of index array" -msgstr "неправильная длина массива индексов" +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Только монохром, индексированный 4bpp или 8bpp, и 16bpp или больше BMP " +#~ "поддерживаются: %d bpp" -#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c -msgid "wrong number of arguments" -msgstr "неправильное количество аргументов" +#~ msgid "level must be between 0 and 1" +#~ msgstr "уровень должен быть между 0 и 1" -#: py/runtime.c -msgid "wrong number of values to unpack" -msgstr "Неправильное количество значений для распаковки" +#~ msgid "init I2C" +#~ msgstr "инициализация I2C" -#: extmod/ulab/code/numpy/vector.c -msgid "wrong output type" -msgstr "неверный тип вывода" +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "Bits_per_sample сэмпла не соответствует битам микшера" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be an ndarray" -msgstr "зи, должно быть, массивом ndarray" +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "" +#~ "Количество каналов образца не совпадает с количеством каналов микшера" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of float type" -msgstr "zi должно быть типа float" +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "Частота дискретизации семпла не соответствует частоте микшера" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of shape (n_section, 2)" -msgstr "zi должен иметь форму (n_section, 2)" +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "Подпись семпла не совпадает с подписью микшера" #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Размер буфера должен быть кратен 512" @@ -4695,7 +5129,7 @@ msgstr "zi должен иметь форму (n_section, 2)" #~ msgid "'continue' outside loop" #~ msgstr "«продолжить» вне цикла" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "Объект 'coroutine' не является итератором" #~ msgid "(x,y) integers required" @@ -4890,8 +5324,8 @@ msgstr "zi должен иметь форму (n_section, 2)" #~ msgstr "IV должен быть длиной %d байт" #~ msgid "" -#~ "Incompatible .mpy file. Please update all .mpy files. See http://adafru." -#~ "it/mpy-update for more info." +#~ "Incompatible .mpy file. Please update all .mpy files. See http://" +#~ "adafru.it/mpy-update for more info." #~ msgstr "" #~ "Несовместимый файл .mpy. Пожалуйста, обновите все файлы .mpy. См. http://" #~ "adafru.it/mpy-update для получения дополнительной информации." diff --git a/locale/sv.po b/locale/sv.po index be6185a2009..cfdbaa3064b 100644 --- a/locale/sv.po +++ b/locale/sv.po @@ -6,15 +6,15 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2024-01-15 16:06+0000\n" -"Last-Translator: Jonny Bergdahl \n" +"PO-Revision-Date: 2025-06-15 23:04+0000\n" +"Last-Translator: Jonny Bergdahl \n" "Language-Team: LANGUAGE \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.4-dev\n" +"X-Generator: Weblate 5.12-dev\n" #: main.c msgid "" @@ -94,7 +94,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "%q och %q innehåller duplicerade pinnar" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q och %q måste vara olika" @@ -104,7 +104,7 @@ msgstr "%q och %q måste dela klockenhet" #: ports/nordic/common-hal/watchdog/WatchDogTimer.c msgid "%q cannot be changed once mode is set to %q" -msgstr "" +msgstr "%q kan inte ändras efter att läge satts till %q" #: shared-bindings/microcontroller/Pin.c msgid "%q contains duplicate pins" @@ -114,7 +114,11 @@ msgstr "%q innehåller dubblettstift" msgid "%q failure: %d" msgstr "%q-fel: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q in %1 måste vara av typ %q eller %q, inte %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q i %q måste vara av typen %q, inte %q" @@ -166,7 +170,7 @@ msgstr "längden på %q måste vara <= %d" msgid "%q length must be >= %d" msgstr "längden på %q måste vara >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "%q flyttad från %q till %q" @@ -228,6 +232,7 @@ msgstr "%q måste vara en multipel av 8." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q måste vara av typen %q eller %q, inte %q" @@ -237,6 +242,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "%q måste vara av typen %q, %q, eller %q, inte %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q måste vara av typen %q, inte %q" @@ -282,7 +288,8 @@ msgstr "%q() utan %q()" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q och %q måste vara lika långa" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -316,7 +323,7 @@ msgid "'%q' object does not support '%q'" msgstr "Objektet '%q' stöder inte '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "Objektet '%q' är inte en iterator" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -324,13 +331,13 @@ msgid "'%q' object is not callable" msgstr "Objektet '%q' kan inte anropas" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "Objektet '%q' är inte itererbart" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format msgid "'%s' expects a label" -msgstr "'%s' förväntar sig en label" +msgstr "'%s' förväntar sig en etikett" #: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format @@ -430,7 +437,7 @@ msgstr "'label' kräver 1 argument" #: py/emitnative.c msgid "'not' not implemented" -msgstr "" +msgstr "'not' är inte implementerat" #: py/compile.c msgid "'return' outside function" @@ -454,7 +461,7 @@ msgstr "*x måste vara mål för tilldelning" #: py/obj.c msgid ", in %q\n" -msgstr ", i %q\n" +msgstr ", i%q\n" #: shared-bindings/busdisplay/BusDisplay.c #: shared-bindings/epaperdisplay/EPaperDisplay.c @@ -551,7 +558,6 @@ msgstr "Alla timers för denna pinne är i bruk" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "Alla timers används" @@ -564,6 +570,10 @@ msgstr "Annonserar redan." msgid "Already have all-matches listener" msgstr "Har redan lyssnare för all-matchningar" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "Pågår redan" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -573,6 +583,7 @@ msgstr "Kör redan" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "Skannar redan efter WiFi-nätverk" @@ -599,6 +610,10 @@ msgstr "Matrisen måste innehålla halfwords (typ \"H\")" msgid "Array values should be single bytes." msgstr "Matrisvärden ska bestå av enstaka bytes." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "Async SPI-överföring pågår på denna buss, forsätter vänta." + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -608,6 +623,11 @@ msgstr "Försök att tilldela %d block" msgid "Audio conversion not implemented" msgstr "Ljudkonvertering inte implementerad" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "Fel på ljudkälla" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN används inte med lösenord" @@ -625,8 +645,8 @@ msgid "" "Auto-reload is on. Simply save files over USB to run them or enter REPL to " "disable.\n" msgstr "" -"Autoladdning är på. Spara filer via USB för att köra dem eller ange REPL för " -"att inaktivera.\n" +"Autoladdning är på. Spara filer via USB för att köra dem eller gå till REPL " +"för att inaktivera.\n" #: ports/espressif/common-hal/canio/CAN.c msgid "Baudrate not supported by peripheral" @@ -683,7 +703,7 @@ msgstr "Buffertlängd %d för stor. Den måste vara mindre än %d" #: shared-module/sdcardio/SDCard.c #, c-format msgid "Buffer must be a multiple of %d bytes" -msgstr "" +msgstr "Buffer måste vara multipel av %d byte" #: shared-bindings/_bleio/PacketBuffer.c #, c-format @@ -742,6 +762,10 @@ msgstr "" msgid "Can only alarm on two low pins from deep sleep." msgstr "Kan bara larma från djup sömn på två låga pinnar." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "Kan inte skapa AudioOut eftersom kontinuerlig kanal redan är öppen" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -788,8 +812,8 @@ msgid "Cannot record to a file" msgstr "Det går inte att spela in till en fil" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "Det går inte att montera om '/' när den är synlig via USB." +msgid "Cannot remount path when visible via USB." +msgstr "Kan inte montera sökväg när den är åtkomlig via USB." #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -804,6 +828,10 @@ msgstr "Det går inte att specificera RTS eller CTS i RS485-läget" msgid "Cannot subclass slice" msgstr "Det går inte att subklassa slice" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "Kan inte använda GPIO0..15 tillsammans med GPIO32..47" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "Kan inte vakna på pin edge, bara nivå" @@ -840,6 +868,10 @@ msgstr "Arrayer för koordinater har olika längd" msgid "Coordinate arrays types have different sizes" msgstr "Arrayer för koordinater har olika storlek" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "Kan inte publicera till ROS topic" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "Kan inte ange adress" @@ -852,6 +884,11 @@ msgstr "Det gick inte att starta avbrott, RX upptagen" msgid "Couldn't allocate decoder" msgstr "Det gick inte att allokera avkodaren" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "Kritiskt ROS-fel vid mjuk omstart, reset krävs: %d" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "Initieringsfel för DAC-kanal" @@ -869,10 +906,6 @@ msgstr "DAC används redan" msgid "Data 0 pin must be byte aligned" msgstr "Datapinne 0 måste vara bytejusterad" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Datasegmentet måste följa fmt-segmentet" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "Dataformatfel (kan var felaktig data)" @@ -1006,15 +1039,47 @@ msgstr "Det gick inte att ansluta: internt fel" msgid "Failed to connect: timeout" msgstr "Det gick inte att ansluta: timeout" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "Kan inte skapa kontinuerliga kanaler: ogiltigt argument" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "Det gick inte att skapa kontinuerliga kanaler: ogiltigt läge" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Det gick inte att skapa kontinuerliga kanaler: Inget minne" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Det gick inte att skapa kontinuerliga kanaler: inte funnen" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Kan inte skapa kontinuerlig" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Det gick inte att tolka MP3-filen" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Kan inte registrera kontinuerlig händelsers callback" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Det gick inte att frigöra mutex, fel 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "Kan inte sätta värdnamn" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Kan inte starta async audio" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Det gick inte att skriva till intern flash." @@ -1023,12 +1088,14 @@ msgstr "Det gick inte att skriva till intern flash." msgid "File exists" msgstr "Filen finns redan" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "Filen hittades inte" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "Filter för komplexa" @@ -1053,7 +1120,7 @@ msgstr "För L8-färgrymden måste indatabitmappen ha 8 bitar per pixel" msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "För RGB-färgrymder måste indatabitmappen ha 16 bitar per pixel" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "Format stöds inte" @@ -1165,6 +1232,7 @@ msgid "Insufficient stream input buffer" msgstr "Otillräcklig buffer för inström" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "Gränssnittet måste vara startat" @@ -1196,7 +1264,7 @@ msgstr "Internt fel #%d" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-bindings/pwmio/PWMOut.c msgid "Internal resource(s) in use" -msgstr "" +msgstr "Intern(a) resurs(er) används redan" #: supervisor/shared/safe_mode.c msgid "Internal watchdog timer expired." @@ -1220,14 +1288,16 @@ msgstr "Avbruten av utgångsfunktion" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "Ogiltig %q" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c #: shared-module/aurora_epaper/aurora_framebuffer.c msgid "Invalid %q and %q" -msgstr "" +msgstr "Ogiltig %q och %q" #: ports/atmel-samd/common-hal/microcontroller/Pin.c #: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c @@ -1253,6 +1323,10 @@ msgstr "Ogiltig BSSID" msgid "Invalid MAC address" msgstr "Ogiltig MAC-adress" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "Ogiltigt ROS domän-id" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Ogiltigt argument" @@ -1284,6 +1358,7 @@ msgid "Invalid hex password" msgstr "Ogiltigt hex-lösenord" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "Ogiltig MAC-adress för multicast" @@ -1296,6 +1371,7 @@ msgid "Invalid socket for TLS" msgstr "Ogiltig socket för TLS" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "Ogiltigt tillstånd" @@ -1329,7 +1405,7 @@ msgstr "Layer måste vara en underklass av Group eller TileGrid" #: shared-bindings/audiocore/RawSample.c msgid "Length of %q must be an even multiple of channel_count * type_size" -msgstr "" +msgstr "Längden på %q måste vara en jämn multipel av channel_count * type_size" #: ports/espressif/common-hal/espidf/__init__.c msgid "MAC address was invalid" @@ -1338,7 +1414,12 @@ msgstr "MAC-adressen var ogiltig" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/espressif/common-hal/_bleio/Descriptor.c msgid "MITM security not supported" -msgstr "" +msgstr "MITM-säkerhet stöds inte" + +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "Fel på MMC/SDIO-klocka: %x" #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" @@ -1383,9 +1464,10 @@ msgstr "Saknad jmp_pin. %q[%u] hoppar på pin" #: shared-module/storage/__init__.c msgid "Mount point directory missing" -msgstr "" +msgstr "Katalog för monteringspunkt saknas" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Måste vara en %q-subklass." @@ -1470,7 +1552,7 @@ msgstr "Ingen IP" #: ports/cxd56/common-hal/microcontroller/__init__.c #: ports/mimxrt10xx/common-hal/microcontroller/__init__.c msgid "No bootloader present" -msgstr "" +msgstr "Bootloader saknas" #: shared-module/usb/core/Device.c msgid "No configuration set" @@ -1525,6 +1607,10 @@ msgstr "Ingen pull-up hittades på SDA eller SCL; kontrollera inkopplingen" msgid "No pulldown on pin; 1Mohm recommended" msgstr "Ingen pulldown på pinnen; 1Mohm rekommenderas" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "Pullup saknas på pinne; 1MOhm rekommenderas" + #: py/moderrno.c msgid "No space left on device" msgstr "Inget utrymme kvar på enheten" @@ -1572,7 +1658,7 @@ msgstr "JPEG-standard stöds ej" #: ports/espressif/common-hal/sdioio/SDCard.c #, c-format msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +msgstr "Antal för data_pins måste vara %d eller %d, inte %d" #: shared-bindings/util.c msgid "" @@ -1627,15 +1713,6 @@ msgstr "Endast kantdetektering är tillgänglig för denna hårdvara" msgid "Only int or string supported for ip" msgstr "Endast int eller string stöds för ip" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Endast monokrom, indexerad 4 bpp eller 8 bpp och 16 bpp eller högre BMP: er " -"stöds: %d bpp angiven" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "Endast en %q kan sättas i djup sömn." @@ -1686,6 +1763,7 @@ msgstr "Slut på minne" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "Slut på sockets" @@ -1705,6 +1783,10 @@ msgstr "PWM-segment används redan" msgid "PWM slice channel A already in use" msgstr "PWM-segmentkanal A används redan" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "Paketbuffertar för en SPI-överföring måste ha samma längd." + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "Parameterfel" @@ -1807,6 +1889,10 @@ msgstr "Programstorlek ogiltig" msgid "Program too long" msgstr "Programmet är för långt" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "Publicerare kan bara skapas from föräldranod" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Pull används inte när riktningen är output." @@ -1827,6 +1913,26 @@ msgstr "RNG DeInit-fel" msgid "RNG Init Error" msgstr "RNG Init-fel" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "Fel vid ROS initialisering, är agent ansluten?" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "Fel vid ROS intern inställning" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "Fel vid ROS minnesallokering" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "Fel vid ROS-nods initialisering" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "Fel vid initialisering av ROS topic" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1909,7 +2015,7 @@ msgstr "SDIO GetCardInfo-fel %d" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO Init Error %x" -msgstr "" +msgstr "SDIO Init Fel %x" #: ports/espressif/common-hal/busio/SPI.c msgid "SPI configuration failed" @@ -1958,11 +2064,13 @@ msgstr "Slice och värde har olika längd." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Slice stöds inte" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool kan endast användas med wifi.radio" @@ -1976,7 +2084,7 @@ msgstr "Ange en av data0 eller data_pins" #: supervisor/shared/safe_mode.c msgid "Stack overflow. Increase stack size." -msgstr "" +msgstr "Stack overflow. Öka stackstorleken." #: shared-bindings/alarm/time/TimeAlarm.c msgid "Supply one of monotonic_time or epoch_time" @@ -2002,21 +2110,9 @@ msgstr "Ovanstående undantag var den direkta orsaken till följande undantag:" msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "Längden på rgb_pins vara 6, 12, 18, 24 eller 30" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Samplingens bits_per_sample matchar inte mixerns" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Samplingens kanalantal matchar inte mixerns" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "Samplingens frekvens matchar inte mixerns" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "Samplingens signerad/osignerad stämmer inte med mixern" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "Prov %q matchar inte" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2038,7 +2134,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "Tile-höjden måste vara jämnt delbar med höjd på bitmap" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Tile-index utanför gräns" @@ -2046,6 +2144,10 @@ msgstr "Tile-index utanför gräns" msgid "Tile width must exactly divide bitmap width" msgstr "Tile-bredd måste vara jämnt delbar med bredd på bitmap" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "TilePaletteMapper får bara bindas till ett TileGrid en gång" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "Tid har passerats." @@ -2066,7 +2168,7 @@ msgstr "För många kanaler i sampling." #: ports/espressif/common-hal/_bleio/Characteristic.c msgid "Too many descriptors" -msgstr "" +msgstr "För många beskrivningar" #: shared-module/displayio/__init__.c msgid "Too many display busses; forgot displayio.release_displays() ?" @@ -2092,7 +2194,7 @@ msgstr "Traceback (senaste anrop):\n" #: ports/stm/common-hal/busio/UART.c msgid "UART de-init" -msgstr "UART omstart" +msgstr "Avinitiering av UART" #: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c #: ports/stm/common-hal/busio/UART.c @@ -2176,6 +2278,11 @@ msgstr "Kan inte initiera tolken" msgid "Unable to read color palette data" msgstr "Det går inte att läsa färgpalettdata" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "" +"Kan inte skicka CAN-meddelande: alla Tx-meddelandebuffertar är upptagna" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2270,22 +2377,19 @@ msgstr "Färgrymd stöds inte" msgid "Unsupported display bus type" msgstr "Busstyp för display stöds inte" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Format stöds inte" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "Hash-algoritmen stöds inte" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" -msgstr "" +msgstr "Sockettyp stöds ej" #: ports/espressif/common-hal/_bleio/Adapter.c #: ports/espressif/common-hal/dualbank/__init__.c msgid "Update failed" -msgstr "" +msgstr "Uppdatering misslyckades" #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c @@ -2334,8 +2438,10 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "WiFi är inte aktiverat" #: main.c @@ -2358,6 +2464,7 @@ msgstr "Du tryckte ner båda knapparna vid start." #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "Du tryckte ner knapp A vid start." @@ -2371,8 +2478,9 @@ msgstr "Du tryckte ner BOOT-knappen vid start" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." -msgstr "" +msgstr "Du tryckte på BOOT-knappen vid start." #: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h msgid "You pressed the GPIO0 button at start up." @@ -2431,6 +2539,10 @@ msgstr "ett bytesliknande objekt krävs" msgid "addresses is empty" msgstr "adresserna är tomma" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "spelas redan" + #: py/compile.c msgid "annotation must be an identifier" msgstr "Annoteringen måste vara en identifierare" @@ -2457,7 +2569,7 @@ msgstr "argsort är inte implementerad för tillplattade matriser" #: extmod/ulab/code/numpy/random/random.c msgid "argument must be None, an integer or a tuple of integers" -msgstr "" +msgstr "argument måste vara None, en integer eller en tuple av heltal" #: py/compile.c msgid "argument name reused" @@ -2509,6 +2621,10 @@ msgstr "försök att få argmin/argmax för en tom sekvens" msgid "attributes not supported" msgstr "Attribut stöds ej" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "audioformatet stöds inte" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "axis är utanför gränsen" @@ -2545,9 +2661,13 @@ msgstr "Ogiltig typkod" msgid "binary op %q not implemented" msgstr "binär op %q är inte implementerad" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth måste vara 8, 16, 24, or 32." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" -msgstr "" +msgstr "bitmaps size och depth måste matcha" #: shared-bindings/bitmaptools/__init__.c msgid "bitmap sizes must match" @@ -2557,6 +2677,15 @@ msgstr "bitmappsstorlekar måste matcha" msgid "bits must be 32 or less" msgstr "bits måste vara 32 eller färre" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample måste vara 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "bits_per_sample måste vara 8 eller 16" @@ -2638,7 +2767,7 @@ msgstr "kan inte tilldela uttryck" msgid "can't cancel self" msgstr "kan inte avbryta sig själv" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "kan inte konvertera %q till %q" @@ -2695,7 +2824,7 @@ msgstr "kan inte göra binära op mellan '%q' och '%q'" #: py/emitnative.c msgid "can't do unary op of '%q'" -msgstr "" +msgstr "kan inte göra unary operation av '%q'" #: py/emitnative.c msgid "can't implicitly convert '%q' to 'bool'" @@ -3102,7 +3231,7 @@ msgid "format" msgstr "format" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "formatet kräver en dict" #: py/objdeque.c @@ -3236,10 +3365,6 @@ msgstr "index måste vara heltal" msgid "indices must be integers, slices, or Boolean lists" msgstr "index måste vara heltal, slices, eller Boolean-listor" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "I2C start" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "initialvärden måste vara iterable" @@ -3436,10 +3561,6 @@ msgstr "etiketten '%q' har inte definierats" msgid "label redefined" msgstr "etiketten omdefinierad" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "level ska ligga mellan 0 och 1" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs och rhs måste vara kompatibla" @@ -3571,7 +3692,7 @@ msgid "must use keyword argument for key function" msgstr "måste använda nyckelordsargument för nyckelfunktion" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "namnet '%q' är inte definierat" #: py/runtime.c @@ -3580,7 +3701,7 @@ msgstr "namn inte definierat" #: py/qstr.c msgid "name too long" -msgstr "" +msgstr "namn för långt" #: py/persistentcode.c msgid "native code in .mpy unsupported" @@ -3846,7 +3967,7 @@ msgstr "matrisen för out är för liten" #: extmod/ulab/code/numpy/random/random.c msgid "out has wrong type" -msgstr "" +msgstr "out har fel typ" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for complex dtype" @@ -3874,11 +3995,11 @@ msgstr "utanför räckvidd för target" #: extmod/ulab/code/numpy/random/random.c msgid "output array has wrong type" -msgstr "" +msgstr "output array har fel typ" #: extmod/ulab/code/numpy/random/random.c msgid "output array must be contiguous" -msgstr "" +msgstr "output array måste vara kontinuerlig" #: py/objint_mpz.c msgid "overflow converting long int to machine word" @@ -3989,6 +4110,10 @@ msgstr "argumentet roll måste vara en ndarray" msgid "rsplit(None,n)" msgstr "rsplit(None,n)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed måste vara sann" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -3996,7 +4121,7 @@ msgstr "samplingsfrekvens utanför räckvidden" #: py/modmicropython.c msgid "schedule queue full" -msgstr "schemakön full" +msgstr "schemakö full" #: py/builtinimport.c msgid "script compilation not supported" @@ -4008,7 +4133,7 @@ msgstr "set stöds inte" #: extmod/ulab/code/numpy/random/random.c msgid "shape must be None, and integer or a tuple of integers" -msgstr "" +msgstr "shape måste vara None, integer eller en tuple av integers" #: extmod/ulab/code/ndarray.c msgid "shape must be integer or tuple of integers" @@ -4032,7 +4157,7 @@ msgstr "storlek är enbart definierad ndarrays" #: extmod/ulab/code/numpy/random/random.c msgid "size must match out.shape when used together" -msgstr "" +msgstr "size måste matcha out.shape när dom används tillsammans" #: py/nativeglue.c msgid "slice unsupported" @@ -4133,12 +4258,12 @@ msgstr "timeout måste vara < 655,35 sekunder" #: ports/raspberrypi/common-hal/floppyio/__init__.c msgid "timeout waiting for flux" -msgstr "" +msgstr "tidsgräns överskriden vid väntan på flux" #: ports/raspberrypi/common-hal/floppyio/__init__.c #: shared-module/floppyio/__init__.c msgid "timeout waiting for index pulse" -msgstr "" +msgstr "Tidsgräns överskriden vid väntan på indexpuls" #: shared-module/sdcardio/SDCard.c msgid "timeout waiting for v1 card" @@ -4208,11 +4333,11 @@ msgid "tx and rx cannot both be None" msgstr "tx och rx kan inte båda vara None" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "typ '%q' är inte en acceptabel bastyp" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "typ är inte en acceptabel bastyp" #: py/runtime.c @@ -4274,7 +4399,9 @@ msgstr "Omatchad '%c' i format" msgid "unreadable attribute" msgstr "attribut kan inte läsas" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "typ %q stöds inte" @@ -4290,7 +4417,7 @@ msgstr "Xtensa-instruktion '%s' med %d argument stöds inte" #: shared-module/bitmapfilter/__init__.c msgid "unsupported bitmap depth" -msgstr "" +msgstr "Bitmapps­djupet stöds inte" #: shared-module/gifio/GifWriter.c msgid "unsupported colorspace for GifWriter" @@ -4343,20 +4470,17 @@ msgid "" "weights must be a sequence with an odd square number of elements (usually 9 " "or 25)" msgstr "" +"vikterna måste vara en sekvens med ett udda kvadrattal antal element " +"(vanligtvis 9 eller 25)" #: shared-bindings/bitmapfilter/__init__.c msgid "weights must be an object of type %q, %q, %q, or %q, not %q " -msgstr "" +msgstr "Vikter måste vara ett objekt av typen %q, %q, %q eller %q, inte %q " #: shared-bindings/is31fl3741/FrameBuffer.c msgid "width must be greater than zero" msgstr "width måste vara större än noll" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "WiFi är inte aktiverat" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "wifi.Monitor är inte tillgänglig" @@ -4419,6 +4543,47 @@ msgstr "zi måste vara av typ float" msgid "zi must be of shape (n_section, 2)" msgstr "zi måste vara i formen (n_section, 2)" +#~ msgid "Unsupported format" +#~ msgstr "Format stöds inte" + +#~ msgid "Wifi is not enabled" +#~ msgstr "WiFi är inte aktiverat" + +#~ msgid "wifi is not enabled" +#~ msgstr "WiFi är inte aktiverat" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "Det går inte att montera om '/' när den är synlig via USB." + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Datasegmentet måste följa fmt-segmentet" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Endast monokrom, indexerad 4 bpp eller 8 bpp och 16 bpp eller högre BMP: " +#~ "er stöds: %d bpp angiven" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "level ska ligga mellan 0 och 1" + +#~ msgid "init I2C" +#~ msgstr "I2C start" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "Samplingens bits_per_sample matchar inte mixerns" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "Samplingens kanalantal matchar inte mixerns" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "Samplingens frekvens matchar inte mixerns" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "Samplingens signerad/osignerad stämmer inte med mixern" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Buffertlängd måste vara en multipel av 512" @@ -4758,13 +4923,13 @@ msgstr "zi måste vara i formen (n_section, 2)" #~ msgid "'%s' object does not support item deletion" #~ msgstr "Objektet '%s' stöder inte borttagning av objekt" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "Objektet '%s' är inte en iterator" #~ msgid "'%s' object is not callable" #~ msgstr "Objektet '%s' kan inte anropas" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "Objektet '%s' är inte itererable" #~ msgid "'%s' object is not subscriptable" @@ -4782,7 +4947,7 @@ msgstr "zi måste vara i formen (n_section, 2)" #~ msgid "'continue' outside loop" #~ msgstr "'continue' utanför loop" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "objektet 'coroutine\" är inte en iterator" #~ msgid "(x,y) integers required" @@ -5885,7 +6050,7 @@ msgstr "zi måste vara i formen (n_section, 2)" #~ msgid "frequency is read-only for this board" #~ msgstr "frekvens är skrivskyddad för detta kort" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "funktionen tar inte nyckelordsargument" #~ msgid "function is implemented for scalars and ndarrays only" @@ -5985,7 +6150,7 @@ msgstr "zi måste vara i formen (n_section, 2)" #~ msgid "n must be between 0, and 9" #~ msgstr "n måste vara mellan 0 och 9" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "namn återanvänt för argument" #~ msgid "no available NIC" diff --git a/locale/tr.po b/locale/tr.po index 247678ee6c8..0b4d0026e47 100644 --- a/locale/tr.po +++ b/locale/tr.po @@ -7,1219 +7,995 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2024-07-03 19:09+0000\n" -"Last-Translator: Hacı \n" +"PO-Revision-Date: 2026-07-08 15:01+0000\n" +"Last-Translator: H B \n" "Language-Team: none\n" "Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 5.7-dev\n" +"X-Generator: Weblate 2026.7.1.dev0\n" -#: main.c -msgid "" -"\n" -"Code done running.\n" +#: extmod/modasyncio.c extmod/modheapq.c +msgid "empty heap" msgstr "" -"\n" -"Program çalıştırıldı.\n" -#: main.c -msgid "" -"\n" -"Code stopped by auto-reload. Reloading soon.\n" +#: extmod/modasyncio.c +msgid "can't cancel self" msgstr "" -"\n" -"Program otomatik yeniden yükleme tarafından durduruldu. Birazdan tekrar " -"yüklenecek.\n" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Please file an issue with your program at github.com/adafruit/circuitpython/" -"issues." +#: extmod/modasyncio.c +msgid "can't wait" msgstr "" -"\n" -"Lütfen programınızla ilgili bir sorunu github.com/adafruit/circuitpython/" -"issues adresinden bildirin." -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"Press reset to exit safe mode.\n" +#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c +msgid "a bytes-like object is required" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "" -"\n" -"You are in safe mode because:\n" +#: extmod/modbinascii.c +msgid "incorrect padding" msgstr "" -"\n" -"Güvenli moddasın çünkü:\n" - -#: py/obj.c -msgid " File \"%q\"" -msgstr " \"%q\" dosyası" - -#: py/obj.c -msgid " File \"%q\", line %d" -msgstr " \"%q\" dosyası, %d numaralı satır" - -#: py/builtinhelp.c -msgid " is of type %q\n" -msgstr " nesnesi, %q tipindedir\n" - -#: main.c -msgid " not found.\n" -msgstr " bulunamadı.\n" - -#: main.c -msgid " output:\n" -msgstr " çıktı:\n" - -#: py/objstr.c -#, c-format -msgid "%%c requires int or char" -msgstr "%%c int veya char tipine ihtiyaç duyar" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" +#: extmod/moddeflate.c +msgid "format" msgstr "" -"%d adres pinleri, %d RGB pinleri ve %d döşemeleri %d'nin yüksekliği " -"gösterir, %d'nin değil" -#: shared-bindings/microcontroller/Pin.c -msgid "%q and %q contain duplicate pins" -msgstr "%q ve %q yinelenen pinler içeriyor" - -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "%q and %q must be different" -msgstr "%q ve %q farklı olmalılar" +#: extmod/moddeflate.c +msgid "wbits" +msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "%q and %q must share a clock unit" +#: extmod/modhashlib.c +msgid "hash is final" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "%q cannot be changed once mode is set to %q" -msgstr "Mod %q olarak ayarlandıktan sonra %q değiştirilemez" +#: extmod/modheapq.c +msgid "heap must be a list" +msgstr "" -#: shared-bindings/microcontroller/Pin.c -msgid "%q contains duplicate pins" -msgstr "%q yinelenen pinler içeriyor" +#: extmod/modjson.c +msgid "syntax error in JSON" +msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -msgid "%q failure: %d" -msgstr "%q hata: %d" +#: extmod/modrandom.c +msgid "bits must be 32 or less" +msgstr "" -#: py/argcheck.c -msgid "%q in %q must be of type %q, not %q" +#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c +msgid "no default seed" msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/usb_host/Port.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/microcontroller/Pin.c shared-module/max3421e/Max3421E.c -msgid "%q in use" -msgstr "%q kullanımda" +#: extmod/modre.c +msgid "splitting with sub-captures" +msgstr "" -#: py/objstr.c -msgid "%q index out of range" -msgstr "%q indeksi aralık dışında" +#: extmod/modre.c +msgid "regex too complex" +msgstr "" -#: py/obj.c -msgid "%q indices must be integers, not %s" -msgstr "%q indeksleri integer olmalı, %s değil" +#: extmod/modre.c +msgid "Error in regex" +msgstr "regex'te hata" -#: shared-module/bitbangio/SPI.c -msgid "%q init failed" -msgstr "%q init başarısız oldu" +#: extmod/modtime.c +msgid "mktime needs a tuple of length 8 or 9" +msgstr "" -#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c -msgid "%q is %q" -msgstr "%q %q dir" +#: extmod/modtime.c +msgid "ticks interval overflow" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "%q is read-only for this board" +#: extmod/modzlib.c +msgid "compression header" msgstr "" -#: py/argcheck.c shared-bindings/usb_hid/Device.c -msgid "%q length must be %d" -msgstr "%q boyutu %d olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "data type not understood" +msgstr "" -#: py/argcheck.c -msgid "%q length must be %d-%d" -msgstr "%q boyutları %d-%d olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "array is too big" +msgstr "" -#: py/argcheck.c -msgid "%q length must be <= %d" -msgstr "%q boyutu <= %d olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "ndarray length overflows" +msgstr "" -#: py/argcheck.c -msgid "%q length must be >= %d" -msgstr "%q boyutu >= %d olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex type" +msgstr "" -#: py/modsys.c py/objmodule.c py/runtime.c -msgid "%q moved from %q to %q" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c +msgid "too many dimensions" msgstr "" -#: py/argcheck.c -msgid "%q must be %d" -msgstr "%q, %d olmalıdır" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c +msgid "index is out of bounds" +msgstr "" -#: py/argcheck.c shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/is31fl3741/FrameBuffer.c -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "%q must be %d-%d" -msgstr "%q, %d-%d olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "indices must be integers, slices, or Boolean lists" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -msgid "%q must be 1 when %q is True" -msgstr "%q 1 olmalı, %q True olduğu zaman" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c +msgid "operands could not be broadcast together" +msgstr "" -#: py/argcheck.c shared-bindings/gifio/GifWriter.c -#: shared-module/gifio/OnDiskGif.c -msgid "%q must be <= %d" -msgstr "%q <= %d olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "array and index length must be equal" +msgstr "" -#: ports/espressif/common-hal/watchdog/WatchDogTimer.c -msgid "%q must be <= %u" +#: extmod/ulab/code/ndarray.c +msgid "cannot convert complex to dtype" msgstr "" -#: py/argcheck.c -msgid "%q must be >= %d" -msgstr "%q >= %d olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "operation is implemented for 1D Boolean arrays only" +msgstr "" -#: shared-bindings/analogbufio/BufferedIn.c -msgid "%q must be a bytearray or array of type 'H' or 'B'" -msgstr "%q 'H' ya da 'B' tipi bir bytearray ya da array olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "too many indices" +msgstr "" -#: shared-bindings/audiocore/RawSample.c -msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" -msgstr "%q 'h', 'H', 'b' ya da 'B' tipi bir bytearray ya da array olmalı" +#: extmod/ulab/code/ndarray.c +msgid "cannot delete array elements" +msgstr "" -#: shared-bindings/warnings/__init__.c -msgid "%q must be a subclass of %q" +#: extmod/ulab/code/ndarray.c +msgid "flattening order must be either 'C', or 'F'" msgstr "" -#: ports/espressif/common-hal/analogbufio/BufferedIn.c -msgid "%q must be array of type 'H'" +#: extmod/ulab/code/ndarray.c +msgid "tobytes can be invoked for dense arrays only" msgstr "" -#: shared-module/synthio/__init__.c -msgid "%q must be array of type 'h'" +#: extmod/ulab/code/ndarray.c +msgid "operation is not supported for given type" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "%q must be multiple of 8." +#: extmod/ulab/code/ndarray.c +msgid "shape must be integer or tuple of integers" msgstr "" -#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c -#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c -#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c -#: shared-module/synthio/Synthesizer.c -msgid "%q must be of type %q or %q, not %q" +#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c +msgid "maximum number of dimensions is " msgstr "" -#: shared-bindings/jpegio/JpegDecoder.c -msgid "%q must be of type %q, %q, or %q, not %q" +#: extmod/ulab/code/ndarray.c +msgid "can only specify one unknown dimension" msgstr "" -#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c -#: shared-module/synthio/__init__.c -msgid "%q must be of type %q, not %q" +#: extmod/ulab/code/ndarray.c +msgid "cannot reshape array" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -msgid "%q must be power of 2" -msgstr "%q, 2'nin kuvveti olmalıdır" +#: extmod/ulab/code/ndarray.c +msgid "cannot assign new shape" +msgstr "" -#: shared-bindings/wifi/Monitor.c -msgid "%q out of bounds" -msgstr "%q sınırların dışında" +#: extmod/ulab/code/ndarray.c +msgid "function is defined for ndarrays only" +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c -#: shared-bindings/canio/Match.c shared-bindings/time/__init__.c -msgid "%q out of range" -msgstr "%q aralık dışında" +#: extmod/ulab/code/ndarray_operators.c +msgid "operation not supported for the input types" +msgstr "" -#: py/objmodule.c py/runtime.c -msgid "%q renamed %q" +#: extmod/ulab/code/ndarray_operators.c +msgid "dtype of int32 is not supported" msgstr "" -#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c -msgid "%q step cannot be zero" -msgstr "%q sıfır olamaz" +#: extmod/ulab/code/ndarray_operators.c +msgid "cannot cast output with casting rule" +msgstr "" -#: shared-module/bitbangio/I2C.c -msgid "%q too long" -msgstr "%q çok uzun" +#: extmod/ulab/code/ndarray_operators.c +msgid "results cannot be cast to specified type" +msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "%q() takes %d positional arguments but %d were given" -msgstr "%q(), %d konumsal argümanını alır ancak %d verildi" +#: extmod/ulab/code/numpy/approx.c +msgid "interp is defined for 1D iterables of equal length" +msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "%q() without %q()" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D iterables" msgstr "" -#: shared-bindings/usb_hid/Device.c -msgid "%q, %q, and %q must all be the same length" -msgstr "%q, %q ve %q aynı uzunlukta olmalıdır" +#: extmod/ulab/code/numpy/approx.c +msgid "trapz is defined for 1D arrays of equal length" +msgstr "" -#: py/objint.c shared-bindings/storage/__init__.c -msgid "%q=%q" -msgstr "%q=%q" +#: extmod/ulab/code/numpy/bitwise.c +msgid "not supported for input types" +msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts in more bits than pin count" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "function is implemented for ndarrays only" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] shifts out more bits than pin count" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be an ndarray, or a scalar" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] uses extra pin" +#: extmod/ulab/code/numpy/carray/carray.c +msgid "input must be a 1D ndarray" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "%q[%u] waits on input outside of count" +#: extmod/ulab/code/numpy/carray/carray_tools.c +msgid "not implemented for complex dtype" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -#, c-format -msgid "%s error 0x%x" -msgstr "%s hatası 0x%x" +#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c +#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c +#: extmod/ulab/code/numpy/vector.c +msgid "wrong input type" +msgstr "" -#: py/argcheck.c -msgid "'%q' argument required" -msgstr "'%q' argümanı gerekli" +#: extmod/ulab/code/numpy/create.c +msgid "input argument must be an integer, a tuple, or a list" +msgstr "" -#: py/proto.c -msgid "'%q' object does not support '%q'" -msgstr "'%q' nesnesi '%q' öğesini desteklemiyor" +#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c +msgid "wrong number of arguments" +msgstr "" -#: py/runtime.c -msgid "'%q' object is not an iterator" -msgstr "'%q' nesnesi bir iteratör değildir" +#: extmod/ulab/code/numpy/create.c py/objint_longlong.c py/objint_mpz.c +msgid "divide by zero" +msgstr "" -#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c -msgid "'%q' object is not callable" -msgstr "'%q' nesnesi çağrılabilir değil" +#: extmod/ulab/code/numpy/create.c +msgid "arange: cannot compute length" +msgstr "" -#: py/runtime.c -msgid "'%q' object is not iterable" -msgstr "'%q' nesnesi iterable değildir" +#: extmod/ulab/code/numpy/create.c +msgid "first argument must be a tuple of ndarrays" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a label" -msgstr "'%s' bir etiket bekliyor" +#: extmod/ulab/code/numpy/create.c +msgid "only ndarrays can be concatenated" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects a register" -msgstr "'%s' bir yazmaç bekliyor" +#: extmod/ulab/code/numpy/create.c +msgid "wrong axis specified" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects a special register" -msgstr "'%s' özel bir yazmaç bekliyor" +#: extmod/ulab/code/numpy/create.c +msgid "input arrays are not compatible" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an FPU register" -msgstr "'%s' bir FPU yazmacı bekliyor" +#: extmod/ulab/code/numpy/create.c +msgid "input must be 1- or 2-d" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects an address of the form [a, b]" -msgstr "'%s', [a, b] biçiminde bir adres bekliyor" +#: extmod/ulab/code/numpy/create.c +msgid "number of points must be at least 2" +msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -#, c-format -msgid "'%s' expects an integer" -msgstr "'%s' bir integer bekliyor" +#: extmod/ulab/code/numpy/create.c +msgid "offset must be non-negative and no greater than buffer length" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects at most r%d" -msgstr "'%s' en fazla r%d bekler" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer size must be a multiple of element size" +msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' expects {r0, r1, ...}" -msgstr "'%s' {r0, r1, ...} bekliyor" +#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c +msgid "buffer is smaller than requested size" +msgstr "" -#: py/emitinlinextensa.c -#, c-format -msgid "'%s' integer %d isn't within range %d..%d" -msgstr "'%s' integer %d, %d..%d aralığında değil" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is defined for ndarrays only" +msgstr "FFT sadece ndarrays'te tanımlandı" -#: py/emitinlinethumb.c -#, c-format -msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" -msgstr "'%s' integer 0x%x, 0x%x maskesine uymuyor" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "FFT is implemented for linear arrays only" +msgstr "FFT yalnızca doğrusal diziler için uygulanır" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item assignment" -msgstr "'%s' nesnesi, öğe atamasını desteklemiyor" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "input array length must be power of 2" +msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object doesn't support item deletion" -msgstr "'%s' nesnesi, öğe silmeyi desteklemiyor" +#: extmod/ulab/code/numpy/fft/fft_tools.c +msgid "real and imaginary parts must be of equal length" +msgstr "" -#: py/runtime.c -msgid "'%s' object has no attribute '%q'" -msgstr "'%s' nesnesinin '%q' özelliği yok" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be ndarrays" +msgstr "" -#: py/obj.c -#, c-format -msgid "'%s' object isn't subscriptable" -msgstr "'%s' nesnesi subscriptable özelliğe sahip değil" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must be linear arrays" +msgstr "" -#: py/objstr.c -msgid "'=' alignment not allowed in string format specifier" -msgstr "'=' hizalamasına string biçiminde izin verilmez" +#: extmod/ulab/code/numpy/filter.c +msgid "convolve arguments must not be empty" +msgstr "" -#: shared-module/struct/__init__.c -msgid "'S' and 'O' are not supported format types" -msgstr "'S' ve 'O' desteklenen biçim türlerinden değildir" +#: extmod/ulab/code/numpy/io/io.c +msgid "corrupted file" +msgstr "" -#: py/compile.c -msgid "'align' requires 1 argument" -msgstr "'align' 1 argümana ihtiyaç duyar" +#: extmod/ulab/code/numpy/io/io.c +msgid "wrong dtype" +msgstr "" -#: py/compile.c -msgid "'await' outside function" -msgstr "fonksiyon dışında 'await'" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols keyword must be specified" +msgstr "" -#: py/compile.c -msgid "'break'/'continue' outside loop" -msgstr "Döngü dışında 'break'/'continue'" +#: extmod/ulab/code/numpy/io/io.c +msgid "empty file" +msgstr "" -#: py/compile.c -msgid "'data' requires at least 2 arguments" -msgstr "'data' en az 2 argümana ihtiyaç duyar" +#: extmod/ulab/code/numpy/io/io.c +msgid "usecols is too high" +msgstr "" -#: py/compile.c -msgid "'data' requires integer arguments" -msgstr "'data' integer tipinde argümanlara ihtiyaç duyar" +#: extmod/ulab/code/numpy/io/io.c +msgid "array has too many dimensions" +msgstr "" -#: py/compile.c -msgid "'label' requires 1 argument" -msgstr "'label' 1 argümana ihtiyaç duyar" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "input matrix is asymmetric" +msgstr "" -#: py/emitnative.c -msgid "'not' not implemented" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "matrix is not positive definite" msgstr "" -#: py/compile.c -msgid "'return' outside function" -msgstr "fonksiyon dışında 'return'" - -#: py/compile.c -msgid "'yield from' inside async function" -msgstr "asenkron fonksiyon içinde 'yield from'" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "iterations did not converge" +msgstr "" -#: py/compile.c -msgid "'yield' outside function" -msgstr "fonksiyon dışında 'yield'" +#: extmod/ulab/code/numpy/linalg/linalg.c +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "input matrix is singular" +msgstr "" -#: py/compile.c -msgid "* arg after **" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for ndarrays only" msgstr "" -#: py/compile.c -msgid "*x must be assignment target" -msgstr "*x atama hedefi olmalıdır" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "operation is defined for 2D arrays only" +msgstr "" -#: py/obj.c -msgid ", in %q\n" -msgstr ", içinde %q\n" +#: extmod/ulab/code/numpy/linalg/linalg.c +msgid "mode must be complete, or reduced" +msgstr "" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid ".show(x) removed. Use .root_group = x" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get argmin/argmax of an empty sequence" msgstr "" -#: py/objcomplex.c -msgid "0.0 to a complex power" -msgstr "0.0'dan bir karmaşık güce" +#: extmod/ulab/code/numpy/numerical.c +msgid "attempt to get (arg)min/(arg)max of empty sequence" +msgstr "" -#: py/modbuiltins.c -msgid "3-arg pow() not supported" -msgstr "3-argümanlı pow() desteklenmemektedir" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +msgid "axis must be None, or an integer" +msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "AP could not be started" +#: extmod/ulab/code/numpy/numerical.c +msgid "operation is not implemented on ndarrays" msgstr "" -#: shared-bindings/_bleio/Address.c shared-bindings/ipaddress/IPv4Address.c -#, c-format -msgid "Address must be %d bytes long" -msgstr "Adres %d byte uzunluğunda olmalıdır" +#: extmod/ulab/code/numpy/numerical.c +msgid "input must be tuple, list, range, or ndarray" +msgstr "" -#: ports/espressif/common-hal/memorymap/AddressRange.c -#: ports/nordic/common-hal/memorymap/AddressRange.c -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Address range not allowed" +#: extmod/ulab/code/numpy/numerical.c +msgid "sort argument must be an ndarray" msgstr "" -#: shared-bindings/memorymap/AddressRange.c -msgid "Address range wraps around" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort argument must be an ndarray" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "All CAN peripherals are in use" -msgstr "Tüm CAN çevre birimleri kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "argsort is not implemented for flattened arrays" +msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/nordic/common-hal/busio/I2C.c -msgid "All I2C peripherals are in use" -msgstr "Tüm I2C çevre birimleri kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "axis too long" +msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "All RX FIFOs in use" -msgstr "Tüm RX FIFO'ları kullanımda" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c +msgid "arguments must be ndarrays" +msgstr "" -#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c -msgid "All SPI peripherals are in use" -msgstr "Tüm SPI çevre birimleri kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "cross is defined for 1D arrays of length 3" +msgstr "" -#: ports/espressif/common-hal/busio/UART.c ports/nordic/common-hal/busio/UART.c -msgid "All UART peripherals are in use" -msgstr "Tüm UART çevre birimleri kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "diff argument must be an ndarray" +msgstr "" -#: ports/nordic/common-hal/countio/Counter.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c -msgid "All channels in use" -msgstr "Tüm kanallar kullanımda" +#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c +#: ports/espressif/common-hal/pulseio/PulseIn.c +#: shared-bindings/bitmaptools/__init__.c +msgid "index out of range" +msgstr "" -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All dma channels in use" +#: extmod/ulab/code/numpy/numerical.c +msgid "differentiation order out of range" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "All event channels in use" -msgstr "Tüm olay kanalları kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "flip argument must be an ndarray" +msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/usb_host/Port.c -msgid "All state machines in use" -msgstr "Tüm durum makineleri kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "wrong axis index" +msgstr "" -#: ports/atmel-samd/audio_dma.c -msgid "All sync event channels in use" -msgstr "Tüm asenkron olay kanalları kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "median argument must be an ndarray" +msgstr "" -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c -msgid "All timers for this pin are in use" -msgstr "Bu pin için tüm zamanlayıcılar kullanımda" +#: extmod/ulab/code/numpy/numerical.c +msgid "roll argument must be an ndarray" +msgstr "" -#: ports/atmel-samd/common-hal/_pew/PewPew.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/nordic/peripherals/nrf/timers.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c -msgid "All timers in use" -msgstr "Tüm zamanlayıcılar kullanımda" +#: extmod/ulab/code/numpy/poly.c +msgid "input data must be an iterable" +msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Already advertising." -msgstr "Halihazırda duyuruluyor." +#: extmod/ulab/code/numpy/poly.c +msgid "more degrees of freedom than data points" +msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -msgid "Already have all-matches listener" -msgstr "Tüm eşleşmelerle eşleşen dinleyiciniz var" +#: extmod/ulab/code/numpy/poly.c +msgid "input vectors must be of equal length" +msgstr "" -#: ports/espressif/bindings/espnow/ESPNow.c -#: ports/espressif/common-hal/espulp/ULP.c -#: shared-module/memorymonitor/AllocationAlarm.c -#: shared-module/memorymonitor/AllocationSize.c -msgid "Already running" -msgstr "Halihazırda çalışıyor" +#: extmod/ulab/code/numpy/poly.c +msgid "could not invert Vandermonde matrix" +msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Already scanning for wifi networks" -msgstr "Halihazırda wifi ağları için tarama yapılıyor" +#: extmod/ulab/code/numpy/poly.c +msgid "input is not iterable" +msgstr "" -#: shared-module/os/getenv.c -#, c-format -msgid "An error occurred while retrieving '%s':\n" +#: extmod/ulab/code/numpy/random/random.c +msgid "argument must be None, an integer or a tuple of integers" msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Another PWMAudioOut is already active" -msgstr "Başka bir PWMAudioOut zaten aktif durumda" +#: extmod/ulab/code/numpy/random/random.c +msgid "shape must be None, and integer or a tuple of integers" +msgstr "" -#: ports/atmel-samd/common-hal/pulseio/PulseOut.c -#: ports/cxd56/common-hal/pulseio/PulseOut.c -msgid "Another send is already active" -msgstr "Başka bir gönderme zaten aktif" +#: extmod/ulab/code/numpy/random/random.c +msgid "out has wrong type" +msgstr "" -#: shared-bindings/pulseio/PulseOut.c -msgid "Array must contain halfwords (type 'H')" -msgstr "Dizi yarımsözcüklere sahip olmalıdır (tip 'H')" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array has wrong type" +msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Array values should be single bytes." -msgstr "Dizi değerleri tekil bytelar olmalıdır." +#: extmod/ulab/code/numpy/random/random.c +msgid "size must match out.shape when used together" +msgstr "" -#: shared-module/memorymonitor/AllocationAlarm.c -#, c-format -msgid "Attempt to allocate %d blocks" -msgstr "%d bloğun ayrılması girişimi" +#: extmod/ulab/code/numpy/random/random.c +msgid "output array must be contiguous" +msgstr "" -#: ports/raspberrypi/audio_dma.c -msgid "Audio conversion not implemented" -msgstr "Ses dönüşümü implemente edilmedi" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of condition array" +msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "AuthMode.OPEN is not used with password" -msgstr "AuthMode.OPEN bir şifre ile kullanılmadı" +#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c +msgid "first argument must be an ndarray" +msgstr "" -#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c -msgid "Authentication failure" -msgstr "Kimlik doğrulama hatası" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong index type" +msgstr "" -#: main.c -msgid "Auto-reload is off.\n" -msgstr "Otomatik yeniden yükleme devre dışı.\n" +#: extmod/ulab/code/numpy/transform.c +msgid "wrong length of index array" +msgstr "" -#: main.c -msgid "" -"Auto-reload is on. Simply save files over USB to run them or enter REPL to " -"disable.\n" +#: extmod/ulab/code/numpy/transform.c +msgid "dimensions do not match" msgstr "" -"Otomatik yeniden yükleme aktif. Dosyaları çalıştırmak için USB aracılığı ile " -"kaydedin ya da deaktif etmek için REPL moda girin.\n" -#: ports/espressif/common-hal/canio/CAN.c -msgid "Baudrate not supported by peripheral" -msgstr "Baudhızı, çevre birimi tarafından desteklenmiyor" - -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Below minimum frame rate" -msgstr "Minimum kare hızından altında" - -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Bit clock and word select must be sequential GPIO pins" +#: extmod/ulab/code/numpy/vector.c +msgid "out must be an ndarray" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Bitmap size and bits per value must match" -msgstr "Bitmap boyutu ve bit başına değer uyuşmalı" - -#: supervisor/shared/safe_mode.c -msgid "Boot device must be first (interface #0)." +#: extmod/ulab/code/numpy/vector.c +msgid "out must be of float dtype" msgstr "" -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Both RX and TX required for flow control" -msgstr "Hem RX hem de TX akış kontrolü için gerekli" - -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Brightness not adjustable" -msgstr "Parlaklık ayarlanabilir değil" - -#: shared-bindings/_bleio/UUID.c -#, c-format -msgid "Buffer + offset too small %d %d %d" -msgstr "Buffer + offset çok küçük %d %d %d" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output dimensions differ" +msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Buffer elements must be 4 bytes long or less" -msgstr "Buffer elementleri 4 bit olmak zorunda" +#: extmod/ulab/code/numpy/vector.c +msgid "input and output shapes differ" +msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Buffer is not a bytearray." -msgstr "Buffer bir bytearray değil." +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for function" +msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -#, c-format -msgid "Buffer length %d too big. It must be less than %d" -msgstr "Mevcut arabellek boyutu %d çok büyük. En fazla %d kadar olmalı" +#: extmod/ulab/code/numpy/vector.c +msgid "out keyword is not supported for complex dtype" +msgstr "" -#: ports/atmel-samd/common-hal/sdioio/SDCard.c -#: ports/cxd56/common-hal/sdioio/SDCard.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c -#: shared-module/sdcardio/SDCard.c -#, c-format -msgid "Buffer must be a multiple of %d bytes" +#: extmod/ulab/code/numpy/vector.c +msgid "dtype must be float, or complex" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -#, c-format -msgid "Buffer too short by %d bytes" -msgstr "Buffer bitten %d daha az" +#: extmod/ulab/code/numpy/vector.c +msgid "can't convert complex to float" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c -msgid "Buffer too small" +#: extmod/ulab/code/numpy/vector.c +msgid "input dtype must be float or complex" msgstr "" -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c -#, c-format -msgid "Bus pin %d is already in use" -msgstr "Veriyolu pini %d kullanımda" +#: extmod/ulab/code/numpy/vector.c +msgid "first argument must be a callable" +msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "Byte buffer must be 16 bytes." -msgstr "Bit buffer'ı 16bit olmalı." +#: extmod/ulab/code/numpy/vector.c +msgid "wrong output type" +msgstr "" -#: shared-bindings/aesio/aes.c -msgid "CBC blocks must be multiples of 16 bytes" -msgstr "CBC blokları 16 baytın katları şeklinde olmalı" +#: extmod/ulab/code/scipy/linalg/linalg.c +msgid "first two arguments must be ndarrays" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CIRCUITPY drive could not be found or created." -msgstr "CIRCUITPY sürücüsü bulunamadı veya oluşturulamadı." +#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c +msgid "input must be a dense ndarray" +msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "CRC or checksum was invalid" -msgstr "CRC yada checksum geçersiz" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "first argument must be a function" +msgstr "" -#: py/objtype.c -msgid "Call super().__init__() before accessing native object." -msgstr "Yerel nesneye erişmeden önce super().__init__() fonksiyonunu çağırın." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "function has the same sign at the ends of interval" +msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Camera init" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter should be > 0" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on RTC IO from deep sleep." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "maxiter must be > 0" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on one low pin while others alarm high from deep sleep." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be iterable" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Can only alarm on two low pins from deep sleep." +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "initial values must be iterable" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -msgid "Can't set CCCD on local Characteristic" +#: extmod/ulab/code/scipy/optimize/optimize.c +msgid "data must be of equal length" msgstr "" -#: shared-bindings/storage/__init__.c shared-bindings/usb_cdc/__init__.c -#: shared-bindings/usb_hid/__init__.c shared-bindings/usb_midi/__init__.c -#: shared-bindings/usb_video/__init__.c -msgid "Cannot change USB devices now" -msgstr "USB aygıtları şu an değiştirilemez" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sosfilt requires iterable arguments" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Cannot create a new Adapter; use _bleio.adapter;" -msgstr "yeni Adaptör oluşturulamadı, _bleio.adapter kullanın" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "input must be one-dimensional" +msgstr "" -#: shared-bindings/displayio/Bitmap.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Cannot delete values" -msgstr "Değerler silinemez" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be an ndarray" +msgstr "" -#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c -#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c -#: ports/nordic/common-hal/digitalio/DigitalInOut.c -#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c -msgid "Cannot get pull while in output mode" -msgstr "Çıkış modundayken çekme alınamıyor" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of shape (n_section, 2)" +msgstr "" -#: ports/nordic/common-hal/microcontroller/Processor.c -msgid "Cannot get temperature" -msgstr "Isı okunamadı" +#: extmod/ulab/code/scipy/signal/signal.c +msgid "zi must be of float type" +msgstr "" -#: shared-bindings/_bleio/Adapter.c -#, fuzzy -msgid "Cannot have scan responses for extended, connectable advertisements." -msgstr "Genişletilmiş, bağlanabilir reklamlar için tarama yanıtları yapılamaz." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos array must be of shape (n_section, 6)" +msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot pull on input-only pin." +#: extmod/ulab/code/scipy/signal/signal.c +msgid "sos[:, 3] should be all ones" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Cannot record to a file" -msgstr "Dosyaya kayıt yapılamıyor" +#: extmod/ulab/code/ulab_tools.c +msgid "axis is out of bounds" +msgstr "" -#: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "'/' USB ile görünür olduğunda, yeniden bağlanamaz." +#: extmod/ulab/code/ulab_tools.c +msgid "size is defined for ndarrays only" +msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Cannot set value when direction is input." -msgstr "Yön, giriş olduğunda değer ayarlanamıyor." +#: extmod/ulab/code/ulab_tools.c +msgid "input must be square matrix" +msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "Cannot specify RTS or CTS in RS485 mode" -msgstr "RS485 modunda RTS veya CTS belirtilemez" +#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c +msgid "input must be an ndarray" +msgstr "" -#: py/objslice.c -msgid "Cannot subclass slice" +#: extmod/ulab/code/utils/utils.c +msgid "out must be a float dense array" msgstr "" -#: ports/nordic/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge, only level" +#: extmod/ulab/code/utils/utils.c +msgid "offset is too large" msgstr "" -#: ports/espressif/common-hal/alarm/pin/PinAlarm.c -msgid "Cannot wake on pin edge. Only level." +#: extmod/ulab/code/utils/utils.c +msgid "out array is too small" msgstr "" -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "CharacteristicBuffer writing not provided" -msgstr "CharacteristicBuffer yazılmı sağlanmadı" +#: extmod/vfs_fat.c py/moderrno.c +msgid "Read-only filesystem" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "CircuitPython core code crashed hard. Whoops!\n" -msgstr "CircuitPython kor kodu patladı. Haydaaa!\n" +#: extmod/vfs_posix_file.c py/objstringio.c +msgid "I/O operation on closed file" +msgstr "Kapalı dosyada I/O işlemi" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Clock unit in use" -msgstr "Saat ünitesi kullanımda" +#: extmod/vfs_posix_file.c +msgid "poll on file not available on win32" +msgstr "" -#: shared-bindings/_bleio/Connection.c -msgid "" -"Connection has been disconnected and can no longer be used. Create a new " -"connection." -msgstr "Bağlantı koparıldı ve tekrar kullanılamaz. Yeni bir bağlantı kurun." +#: main.c +msgid "Done" +msgstr "Tamamlandı" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays have different lengths" -msgstr "" +#: main.c +msgid " output:\n" +msgstr " çıktı:\n" -#: shared-bindings/bitmaptools/__init__.c -msgid "Coordinate arrays types have different sizes" +#: main.c +msgid "" +"Auto-reload is on. Simply save files over USB to run them or enter REPL to " +"disable.\n" msgstr "" +"Otomatik yeniden yükleme aktif. Dosyaları çalıştırmak için USB aracılığı ile " +"kaydedin ya da deaktif etmek için REPL moda girin.\n" -#: shared-bindings/_bleio/Adapter.c -msgid "Could not set address" -msgstr "Adres ayarlanamadı" - -#: ports/stm/common-hal/busio/UART.c -msgid "Could not start interrupt, RX busy" -msgstr "Kesinti başlatılamadı, RX kullanımda" +#: main.c +msgid "Auto-reload is off.\n" +msgstr "Otomatik yeniden yükleme devre dışı.\n" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Couldn't allocate decoder" +#: main.c +msgid "Running in safe mode! Not running saved code.\n" msgstr "" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Channel Init Error" -msgstr "" +#: main.c +msgid " not found.\n" +msgstr " bulunamadı.\n" -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "DAC Device Init Error" +#: main.c +msgid "WARNING: Your code filename has two extensions\n" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "DAC already in use" -msgstr "DAC zaten kullanımda" - -#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c -msgid "Data 0 pin must be byte aligned" -msgstr "Data 0 pini bite hizalı olmalı" - -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Veri öbeği, fmt yığınını takip etmelidir" +#: main.c +msgid "" +"\n" +"Code stopped by auto-reload. Reloading soon.\n" +msgstr "" +"\n" +"Program otomatik yeniden yükleme tarafından durduruldu. Birazdan tekrar " +"yüklenecek.\n" -#: shared-module/jpegio/JpegDecoder.c -msgid "Data format error (may be broken data)" +#: main.c +msgid "" +"\n" +"Code done running.\n" msgstr "" +"\n" +"Program çalıştırıldı.\n" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data not supported with directed advertising" +#: main.c +msgid "Woken up by alarm.\n" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Data too large for advertisement packet" +#: main.c +msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" msgstr "" +"REPL moda girmek için herhangi bir tuşa basınız. Programı yeniden yüklemek " +"için CTRL+D tuş kombinasyonunu kullanabilirsiniz.\n" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Deep sleep pins must use a rising edge with pulldown" +#: main.c +msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" msgstr "" +"Alarma, CTRL-C'ye veya dosya yazana kadar derin uyku moduna geçiliyor.\n" -#: shared-bindings/audiobusio/PDMIn.c -msgid "Destination capacity is smaller than destination_length." -msgstr "Hedef kapasitesi, hedef_uzunluğundan daha küçük." +#: main.c +msgid "UID:" +msgstr "UID:" -#: shared-module/jpegio/JpegDecoder.c -msgid "Device error or wrong termination of input stream" +#: main.c +msgid "soft reboot\n" msgstr "" -#: ports/nordic/common-hal/audiobusio/I2SOut.c -msgid "Device in use" -msgstr "Cihaz kullanımda" - -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display must have a 16 bit colorspace." -msgstr "Ekran 16 bitlik bir renk uzayına sahip olmalıdır." +#: ports/analog/common-hal/busio/SPI.c ports/analog/common-hal/busio/UART.c +#: ports/stm/common-hal/audioio/AudioOut.c +#: shared-bindings/digitalio/DigitalInOutProtocol.c +#: shared-module/busdisplay/BusDisplay.c shared-module/ssl/SSLContext.c +msgid "%q init failed" +msgstr "%q init başarısız oldu" -#: shared-bindings/busdisplay/BusDisplay.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c -#: shared-bindings/framebufferio/FramebufferDisplay.c -msgid "Display rotation must be in 90 degree increments" -msgstr "Ekran dönüşü 90 derecelik artışlarla olmalıdır" +#: ports/analog/common-hal/busio/SPI.c +msgid "SPI needs MOSI, MISO, and SCK" +msgstr "" -#: main.c -msgid "Done" -msgstr "Tamamlandı" +#: ports/analog/common-hal/busio/SPI.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/argcheck.c +#: shared-bindings/bitmaptools/__init__.c shared-bindings/canio/Match.c +#: shared-bindings/time/__init__.c +msgid "%q out of range" +msgstr "%q aralık dışında" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Drive mode not used when direction is input." -msgstr "Yön, giriş olduğunda sürüş modu kullanılmaz." +#: ports/analog/common-hal/busio/SPI.c +#: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid state" +msgstr "Geçersiz durum" -#: py/obj.c -msgid "During handling of the above exception, another exception occurred:" -msgstr "Yukarıdaki hatanın işlenmesi sırasında başka bir hata oluştu:" +#: ports/analog/common-hal/busio/SPI.c +msgid "Failed to set SPI Clock Mode" +msgstr "" -#: shared-bindings/aesio/aes.c -msgid "ECB only operates on 16 bytes at a time" -msgstr "ECB aynı anda yalnızca 16 baytla çalışır" +#: ports/analog/common-hal/busio/UART.c +#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c +msgid "RS485" +msgstr "RS485" -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/canio/CAN.c -msgid "ESP-IDF memory allocation failed" +#: ports/analog/common-hal/busio/UART.c +msgid "UART needs TX & RX" msgstr "" -#: extmod/modre.c -msgid "Error in regex" -msgstr "regex'te hata" +#: ports/analog/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Both RX and TX required for flow control" +msgstr "Hem RX hem de TX akış kontrolü için gerekli" -#: supervisor/shared/safe_mode.c -msgid "Error in safemode.py." +#: ports/analog/common-hal/busio/UART.c shared-module/rgbmatrix/RGBMatrix.c +msgid "Failed to allocate %q buffer" msgstr "" -#: shared-bindings/alarm/__init__.c -msgid "Expected a kind of %q" +#: ports/analog/common-hal/busio/UART.c +msgid "UART read error" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Extended advertisements with scan response not supported." +#: ports/analog/common-hal/busio/UART.c +msgid "UART transaction timeout" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is defined for ndarrays only" -msgstr "FFT sadece ndarrays'te tanımlandı" +#: ports/analog/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +msgid "All UART peripherals are in use" +msgstr "Tüm UART çevre birimleri kullanımda" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "FFT is implemented for linear arrays only" -msgstr "FFT yalnızca doğrusal diziler için uygulanır" +#: ports/analog/common-hal/busio/UART.c +#: ports/analog/peripherals/max32690/max32_i2c.c +#: ports/analog/peripherals/max32690/max32_spi.c +#: ports/analog/peripherals/max32690/max32_uart.c +#: ports/espressif/common-hal/_bleio/Service.c +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/microcontroller/Processor.c +#: ports/espressif/common-hal/mipidsi/Display.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +#: ports/raspberrypi/bindings/picodvi/Framebuffer.c +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/mipidsi/Display.c +#: shared-bindings/pwmio/PWMOut.c shared-bindings/supervisor/__init__.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c +msgid "Invalid %q" +msgstr "Geçersiz %q" -#: shared-bindings/ps2io/Ps2.c -msgid "Failed sending command." -msgstr "Komut gönderilemedi." +#: ports/analog/common-hal/busio/UART.c +msgid "Timeout must be < 100 seconds" +msgstr "" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to acquire mutex, err 0x%04x" -msgstr "Muteks alınamadı, err 0x%04x" +#: ports/atmel-samd/audio_dma.c +msgid "All sync event channels in use" +msgstr "Tüm asenkron olay kanalları kullanımda" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Failed to add service TXT record" -msgstr "" +#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c +msgid "Internal audio buffer too small" +msgstr "Dahili ses arabelleği çok küçük" -#: shared-bindings/mdns/Server.c -msgid "" -"Failed to add service TXT record; non-string or bytes found in txt_records" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is read only" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "Failed to allocate %q buffer" +#: ports/atmel-samd/bindings/samd/Clock.c +msgid "calibration is out of range" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -msgid "Failed to allocate Wifi memory" +#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h +#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h +msgid "You pressed both buttons at start up." msgstr "" -#: ports/espressif/common-hal/wifi/ScannedNetworks.c -msgid "Failed to allocate wifi scan memory" +#: ports/atmel-samd/common-hal/_pew/PewPew.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +#: ports/nordic/common-hal/audiopwmio/PWMAudioOut.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/peripherals/nrf/timers.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "All timers in use" +msgstr "Tüm zamanlayıcılar kullanımda" + +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: ports/atmel-samd/common-hal/countio/Counter.c +#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c +#: ports/atmel-samd/common-hal/max3421e/Max3421E.c +#: ports/atmel-samd/common-hal/ps2io/Ps2.c +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +msgid "Internal resource(s) in use" msgstr "" -#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c -msgid "Failed to buffer the sample" +#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c +#: supervisor/shared/safe_mode.c +msgid "Unknown reason." msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: internal error" -msgstr "Bağlantı kurulamadı: internal error" +#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c +#: ports/nordic/common-hal/alarm/time/TimeAlarm.c +#: ports/stm/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set" +msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Failed to connect: timeout" -msgstr "Bağlantı kurulamadı: timeout" +#: ports/atmel-samd/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "No DAC on chip" +msgstr "" -#: shared-module/audiomp3/MP3Decoder.c -msgid "Failed to parse MP3 file" -msgstr "MP3 dosyası ayrıştırılamadı" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "%q and %q must share a clock unit" +msgstr "%q ve %q bir saat birimi paylaşmalıdır" -#: ports/nordic/sd_mutex.c -#, c-format -msgid "Failed to release mutex, err 0x%04x" -msgstr "Muteks serbest bırakılamadı, err 0x%04x" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +msgid "Serializer in use" +msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Failed to write internal flash." -msgstr "Dahili flaş yazılamadı." +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Clock unit in use" +msgstr "Saat ünitesi kullanımda" -#: py/moderrno.c -msgid "File exists" -msgstr "Dosya var" - -#: shared-module/os/getenv.c -msgid "File not found" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/atmel-samd/common-hal/touchio/TouchIn.c +msgid "No free GCLKs" msgstr "" -#: ports/atmel-samd/common-hal/canio/Listener.c -#: ports/espressif/common-hal/canio/Listener.c -#: ports/stm/common-hal/canio/Listener.c -msgid "Filters too complex" -msgstr "Filtreler çok karmaşık" - -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is duplicate" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +msgid "Too many channels in sample" msgstr "" -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is invalid" -msgstr "Yazılım geçersiz" - -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Firmware is too big" -msgstr "Yazılım çok büyük" - -#: shared-bindings/bitmaptools/__init__.c -msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "No DMA channel found" msgstr "" -"L8 renk uzayı için, giriş bitmap'i piksel başına 8 bayta sahip olmalıdır" -#: shared-bindings/bitmaptools/__init__.c -msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" +#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Unable to allocate buffers for signed conversion" msgstr "" -"RGB renk uzayı için, giriş bitmap'i piksel başına 16 bayta sahip olmalıdır" - -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Format not supported" -msgstr "Format desteklenmiyor" -#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c -msgid "" -"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +#, c-format +msgid "Only 8 or 16 bit mono with %dx oversampling supported." msgstr "" -"Frekans 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 ya da 1008 Mhz " -"olmalıdır" - -#: shared-bindings/bitbangio/I2C.c shared-bindings/bitbangio/SPI.c -#: shared-bindings/busio/I2C.c shared-bindings/busio/SPI.c -msgid "Function requires lock" -msgstr "Fonksiyon kilit gerektirir" - -#: ports/cxd56/common-hal/gnss/GNSS.c -msgid "GNSS init" -msgstr "GNSS init" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Generic Failure" +#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c +#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c +msgid "sampling rate out of range" msgstr "" -#: shared-bindings/framebufferio/FramebufferDisplay.c -#: shared-module/busdisplay/BusDisplay.c -#: shared-module/framebufferio/FramebufferDisplay.c -msgid "Group already used" -msgstr "Grup zaten kullanılıyor" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "DAC already in use" +msgstr "DAC zaten kullanımda" -#: supervisor/shared/safe_mode.c -msgid "Hard fault: memory access or instruction error." +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "Right channel unsupported" msgstr "" -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c -#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c -#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c -msgid "Hardware in use, try alternative pins" -msgstr "Donanım kullanımda, alternatif pinleri deneyin" +#: ports/atmel-samd/common-hal/audioio/AudioOut.c +msgid "All event channels in use" +msgstr "Tüm olay kanalları kullanımda" -#: supervisor/shared/safe_mode.c -msgid "Heap allocation when VM not running." +#: ports/atmel-samd/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/I2C.c +#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/busio/I2C.c +msgid "No pull up found on SDA or SCL; check your wiring" msgstr "" -#: extmod/vfs_posix_file.c py/objstringio.c -msgid "I/O operation on closed file" -msgstr "Kapalı dosyada I/O işlemi" - -#: ports/stm/common-hal/busio/I2C.c -msgid "I2C init error" -msgstr "I2C init hatası" - -#: ports/raspberrypi/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "I2C peripheral in use" -msgstr "I2C çevre cihazı kullanımda" +#: ports/atmel-samd/common-hal/busio/UART.c +msgid "%q must be power of 2" +msgstr "%q, 2'nin kuvveti olmalıdır" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "In-buffer elements must be <= 4 bytes long" -msgstr "Buffer öğeleri <=4 bayt uzunluğunda olmalı" +#: ports/atmel-samd/common-hal/busio/UART.c +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +#: ports/nordic/common-hal/busio/UART.c +#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c +#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c +#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c +#: shared-bindings/paralleldisplaybus/ParallelBus.c +#: shared-bindings/qspibus/QSPIBus.c shared-module/bitbangio/SPI.c +msgid "No %q pin" +msgstr "%q pini yok" -#: shared-bindings/_pew/PewPew.c -msgid "Incorrect buffer size" -msgstr "Yanlış buffer size" +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "All RX FIFOs in use" +msgstr "Tüm RX FIFO'ları kullanımda" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Init program size invalid" -msgstr "Init program boyutu geçersiz" +#: ports/atmel-samd/common-hal/canio/Listener.c +msgid "Already have all-matches listener" +msgstr "Tüm eşleşmelerle eşleşen dinleyiciniz var" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin direction conflicts with initial out pin direction" -msgstr "İlk pin yönü, ilk çıkış pin yönüyle çakışıyor" +#: ports/atmel-samd/common-hal/canio/Listener.c +#: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c +#: ports/stm/common-hal/canio/Listener.c +msgid "Filters too complex" +msgstr "Filtreler çok karmaşık" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Initial set pin state conflicts with initial out pin state" -msgstr "İlk pinin durumu, ilk çıkış pininin durumu ile çakışıyor" +#: ports/atmel-samd/common-hal/digitalio/DigitalInOut.c +#: ports/mimxrt10xx/common-hal/digitalio/DigitalInOut.c +#: ports/nordic/common-hal/digitalio/DigitalInOut.c +#: ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +msgid "Cannot get pull while in output mode" +msgstr "Çıkış modundayken çekme alınamıyor" -#: shared-bindings/bitops/__init__.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format -msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" -msgstr "Giriş buffer uzunluğu (%d) strand sayımının (%d) katı olmalıdır" - -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -msgid "Input taking too long" -msgstr "Giriş çok uzun sürüyor" - -#: py/moderrno.c -msgid "Input/output error" -msgstr "Giriş/çıkış hatası" - -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient authentication" -msgstr "Yetersiz kimlik doğrulama" - -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Insufficient encryption" -msgstr "Yetersiz şifreleme" - -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient memory pool for the image" -msgstr "" - -#: shared-module/jpegio/JpegDecoder.c -msgid "Insufficient stream input buffer" -msgstr "" - -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Interface must be started" -msgstr "Arayüz başlatılmalıdır" - -#: ports/atmel-samd/audio_dma.c ports/raspberrypi/audio_dma.c -msgid "Internal audio buffer too small" -msgstr "Dahili ses arabelleği çok küçük" - -#: ports/stm/common-hal/busio/UART.c -msgid "Internal define error" -msgstr "Dahili tanımlama hatası" - -#: shared-bindings/pwmio/PWMOut.c shared-module/os/getenv.c -msgid "Internal error" -msgstr "Dahili hata" +msgid "Invalid data_pins[%d]" +msgstr "Geçersiz veri_pini [%d]" -#: shared-module/rgbmatrix/RGBMatrix.c +#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c #, c-format -msgid "Internal error #%d" -msgstr "Dahili hata #%d" - -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: ports/atmel-samd/common-hal/countio/Counter.c -#: ports/atmel-samd/common-hal/frequencyio/FrequencyIn.c -#: ports/atmel-samd/common-hal/max3421e/Max3421E.c -#: ports/atmel-samd/common-hal/ps2io/Ps2.c -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-bindings/pwmio/PWMOut.c -msgid "Internal resource(s) in use" -msgstr "" - -#: supervisor/shared/safe_mode.c -msgid "Internal watchdog timer expired." -msgstr "Dahili bekçi zamanlayıcısının süresi doldu." - -#: supervisor/shared/safe_mode.c -msgid "Interrupt error." -msgstr "" - -#: shared-module/jpegio/JpegDecoder.c -msgid "Interrupted by output function" -msgstr "" - -#: ports/espressif/common-hal/_bleio/Service.c -#: ports/espressif/common-hal/espulp/ULP.c -#: ports/espressif/common-hal/microcontroller/Processor.c -#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c -#: ports/mimxrt10xx/common-hal/pwmio/PWMOut.c -#: ports/raspberrypi/bindings/picodvi/Framebuffer.c -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c -#: shared-bindings/digitalio/DigitalInOut.c -#: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q" -msgstr "Geçersiz %q" - -#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c -#: shared-module/aurora_epaper/aurora_framebuffer.c -msgid "Invalid %q and %q" +msgid "data pin #%d in use" msgstr "" #: ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -1229,432 +1005,488 @@ msgstr "" msgid "Invalid %q pin" msgstr "Geersi %q pin" -#: ports/stm/common-hal/analogio/AnalogIn.c -msgid "Invalid ADC Unit value" -msgstr "Geçersiz ADC Ünite değeri" - -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Invalid BLE parameter" -msgstr "Geçersiz BLE parametresi" - -#: shared-bindings/wifi/Radio.c -msgid "Invalid BSSID" -msgstr "Geçersiz BSSID" - -#: shared-bindings/wifi/Radio.c -msgid "Invalid MAC address" -msgstr "Geçersiz MAC adresi" - -#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c -msgid "Invalid argument" -msgstr "Geçersiz argüman" - -#: shared-module/displayio/Bitmap.c -#, fuzzy -msgid "Invalid bits per value" -msgstr "Geçersiz bit başına değer" - -#: shared-module/os/getenv.c -#, c-format -msgid "Invalid byte %.*s" +#: ports/atmel-samd/common-hal/microcontroller/__init__.c +#: ports/cxd56/common-hal/microcontroller/__init__.c +#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c +msgid "No bootloader present" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c -#, c-format -msgid "Invalid data_pins[%d]" -msgstr "Geçersiz veri_pini [%d]" - -#: shared-module/msgpack/__init__.c -msgid "Invalid format" -msgstr "" +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +msgid "Data 0 pin must be byte aligned" +msgstr "Data 0 pini bite hizalı olmalı" -#: shared-module/audiocore/WaveFile.c -msgid "Invalid format chunk size" -msgstr "Geçersiz biçim yığın boyutu" +#: ports/atmel-samd/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/nordic/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c +#, c-format +msgid "Bus pin %d is already in use" +msgstr "Veriyolu pini %d kullanımda" -#: shared-bindings/wifi/Radio.c -msgid "Invalid hex password" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +#: ports/cxd56/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/raspberrypi/common-hal/pulseio/PulseIn.c +#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c +#: shared-bindings/ps2io/Ps2.c +msgid "pop from empty %q" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -msgid "Invalid multicast MAC address" -msgstr "Geçersiz multicast MAC adresi" +#: ports/atmel-samd/common-hal/pulseio/PulseIn.c +msgid "Input taking too long" +msgstr "Giriş çok uzun sürüyor" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid size" -msgstr "Geçersiz boyut" +#: ports/atmel-samd/common-hal/pulseio/PulseOut.c +#: ports/cxd56/common-hal/pulseio/PulseOut.c +msgid "Another send is already active" +msgstr "Başka bir gönderme zaten aktif" -#: shared-module/ssl/SSLSocket.c -msgid "Invalid socket for TLS" -msgstr "TLS için geçersiz soket" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "%q failure: %d" +msgstr "%q hata: %d" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Invalid state" -msgstr "Geçersiz durum" +#: ports/atmel-samd/common-hal/sdioio/SDCard.c +#: ports/cxd56/common-hal/sdioio/SDCard.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c shared-bindings/floppyio/__init__.c +#: shared-module/sdcardio/SDCard.c +#, c-format +msgid "Buffer must be a multiple of %d bytes" +msgstr "Tampon, %d baytların katı olmalıdır" -#: shared-module/os/getenv.c -msgid "Invalid unicode escape" +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." msgstr "" +"Bu veri yolunda asenkron SPI transferi devam ediyor, beklemeye devam edin." -#: shared-bindings/aesio/aes.c -msgid "Key must be 16, 24, or 32 bytes long" -msgstr "Anahtar 16, 24 veya 32 bayt uzunluğunda olmalıdır" - -#: shared-module/os/getenv.c -msgid "Key not found" +#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c +#: ports/stm/common-hal/busio/UART.c +msgid "UART init" msgstr "" -#: shared-module/is31fl3741/FrameBuffer.c -msgid "LED mappings must match display size" -msgstr "LED eşlemeleri ekran boyutuyla eşleşmelidir" +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Camera init" +msgstr "Kamerayı başlat" -#: py/compile.c -msgid "LHS of keyword arg must be an id" +#: ports/cxd56/common-hal/camera/Camera.c +msgid "Size not supported" msgstr "" -#: shared-module/displayio/Group.c -msgid "Layer already in a group" -msgstr "Katman zaten bir grupta" - -#: shared-module/displayio/Group.c -msgid "Layer must be a Group or TileGrid subclass" -msgstr "Katman, bir Grup ya da TileGrid alt sınıfı olmalıdır" - -#: shared-bindings/audiocore/RawSample.c -msgid "Length of %q must be an even multiple of channel_count * type_size" -msgstr "" +#: ports/cxd56/common-hal/camera/Camera.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/struct/__init__.c shared-module/struct/__init__.c +msgid "Buffer too small" +msgstr "Tampon çok küçük" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "MAC address was invalid" -msgstr "MAC adresi geçersiz" +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c +msgid "Format not supported" +msgstr "Format desteklenmiyor" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/espressif/common-hal/_bleio/Descriptor.c -msgid "MITM security not supported" +#: ports/cxd56/common-hal/gnss/GNSS.c +msgid "GNSS init" +msgstr "GNSS init" + +#: ports/cxd56/common-hal/sdioio/SDCard.c +msgid "SDCard init" msgstr "" -#: shared-bindings/is31fl3741/IS31FL3741.c -msgid "Mapping must be a tuple" -msgstr "Map tuple olmalıdır" +#: ports/espressif/bindings/espnow/ESPNow.c +#: ports/espressif/common-hal/espulp/ULP.c +#: shared-module/memorymonitor/AllocationAlarm.c +#: shared-module/memorymonitor/AllocationSize.c +msgid "Already running" +msgstr "Halihazırda çalışıyor" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched data size" -msgstr "" +#: ports/espressif/bindings/espnow/Peer.c shared-bindings/dualbank/__init__.c +msgid "%q is %q" +msgstr "%q %q dir" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Mismatched swap flag" +#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h +msgid "You pressed the SW38 button at start up." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] reads pin(s)" +#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h +#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h +msgid "You pressed the BOOT button at start up." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" +#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h +msgid "You pressed the GPIO0 button at start up." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_in_pin. %q[%u] waits based on pin" +#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h +msgid "You pressed the Rec button at start up." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" +#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h +#: ports/espressif/boards/vidi_x/mpconfigboard.h +msgid "You pressed the VOLUME button at start up." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_out_pin. %q[%u] writes pin(s)" +#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h +#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h +msgid "You pressed the central button at start up." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing first_set_pin. %q[%u] sets pin(s)" +#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h +#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h +msgid "You pressed button A at start up." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Missing jmp_pin. %q[%u] jumps on pin" +#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h +msgid "You pressed button DOWN at start up." msgstr "" -#: shared-module/storage/__init__.c -msgid "Mount point directory missing" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Update failed" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c -msgid "Must be a %q subclass." +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Scan already in progress. Stop with stop_scan." msgstr "" -#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c -msgid "Must provide 5/6/5 RGB pins" -msgstr "" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: internal error" +msgstr "Bağlantı kurulamadı: internal error" -#: ports/mimxrt10xx/common-hal/busio/SPI.c shared-bindings/busio/SPI.c -msgid "Must provide MISO or MOSI pin" +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data too large for advertisement packet" +msgstr "Veri, reklam paketi için çok büyük" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Already advertising." +msgstr "Halihazırda duyuruluyor." + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Extended advertisements with scan response not supported." msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "Data not supported with directed advertising" +msgstr "Veri, hedefli reklamcılıkla desteklenmemektedir" + +#: ports/espressif/common-hal/_bleio/Adapter.c +#: ports/nordic/common-hal/_bleio/Adapter.c #, c-format -msgid "Must use a multiple of 6 rgb pins, not %d" +msgid "Timeout is too long: Maximum timeout length is %d seconds" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "NLR jump failed. Likely memory corruption." +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/espressif/common-hal/_bleio/Descriptor.c +msgid "MITM security not supported" msgstr "" -#: ports/espressif/common-hal/nvm/ByteArray.c -msgid "NVS Error" -msgstr "NVS hatası" - -#: shared-bindings/socketpool/SocketPool.c -msgid "Name or service not known" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length != required fixed length" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "New bitmap must be same size as old bitmap" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +msgid "Value length > max_length" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -msgid "Nimble out of memory" +#: ports/espressif/common-hal/_bleio/Characteristic.c +msgid "Too many descriptors" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c -#: ports/espressif/common-hal/busio/SPI.c -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/SPI.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c -#: ports/raspberrypi/common-hal/busio/UART.c ports/stm/common-hal/busio/SPI.c -#: ports/stm/common-hal/busio/UART.c shared-bindings/fourwire/FourWire.c -#: shared-bindings/i2cdisplaybus/I2CDisplayBus.c -#: shared-bindings/paralleldisplaybus/ParallelBus.c -#: shared-module/bitbangio/SPI.c -msgid "No %q pin" -msgstr "%q pini yok" - #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c msgid "No CCCD for this Characteristic" msgstr "" -#: ports/atmel-samd/common-hal/analogio/AnalogOut.c -#: ports/stm/common-hal/analogio/AnalogOut.c -msgid "No DAC on chip" -msgstr "" +#: ports/espressif/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +msgid "Can't set CCCD on local Characteristic" +msgstr "Yerel Karakteristikte CCCD ayarlanamaz" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA channel found" +#: ports/espressif/common-hal/_bleio/Connection.c +#: ports/nordic/common-hal/_bleio/Connection.c +msgid "non-UUID found in service_uuids_whitelist" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "No DMA pacing timer found" +#: ports/espressif/common-hal/_bleio/Descriptor.c +#: ports/nordic/common-hal/_bleio/Characteristic.c +#: ports/nordic/common-hal/_bleio/Descriptor.c +#, c-format +msgid "max_length must be 0-%d when fixed_length is %s" msgstr "" -#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c -#, c-format -msgid "No I2C device at address: 0x%x" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Writes not supported on Characteristic" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "No IP" -msgstr "IP yok" +#: ports/espressif/common-hal/_bleio/PacketBuffer.c +#: ports/nordic/common-hal/_bleio/PacketBuffer.c +#: ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c +msgid "Total data to write is larger than %q" +msgstr "" -#: ports/atmel-samd/common-hal/microcontroller/__init__.c -#: ports/cxd56/common-hal/microcontroller/__init__.c -#: ports/mimxrt10xx/common-hal/microcontroller/__init__.c -msgid "No bootloader present" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Nimble out of memory" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No configuration set" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Invalid BLE parameter" +msgstr "Geçersiz BLE parametresi" + +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Characteristic.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#: ports/zephyr-cp/common-hal/_bleio/Descriptor.c +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "Not connected" msgstr "" -#: shared-bindings/_bleio/PacketBuffer.c -msgid "No connection: length cannot be determined" +#: ports/espressif/common-hal/_bleio/__init__.c +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Already in progress" +msgstr "Zaten işlemde" + +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error at %s:%d: %d" msgstr "" -#: shared-bindings/board/__init__.c -msgid "No default %q bus" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %d" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/atmel-samd/common-hal/touchio/TouchIn.c -msgid "No free GCLKs" +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient authentication" +msgstr "Yetersiz kimlik doğrulama" + +#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Insufficient encryption" +msgstr "Yetersiz şifreleme" + +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error at %s:%d: %d" msgstr "" -#: shared-bindings/os/__init__.c -msgid "No hardware random available" +#: ports/espressif/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown BLE error: %d" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in in program" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge. Only level." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No in or out in program" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot pull on input-only pin." +msgstr "Sadece giriş olan pinde pull ayarlanamaz." + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on two low pins from deep sleep." +msgstr "Derin uykudan uyanırken yalnızca iki düşük pinde alarm tetiklenebilir." + +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on one low pin while others alarm high from deep sleep." msgstr "" +"Derin uykudan uyanırken, diğerleri yüksek seviyede alarm verecek şekilde " +"ayarlanmışken sadece tek bir düşük pinde alarm tetiklenebilir." -#: py/objint.c shared-bindings/time/__init__.c -msgid "No long integer support" +#: ports/espressif/common-hal/alarm/pin/PinAlarm.c +msgid "Can only alarm on RTC IO from deep sleep." +msgstr "Sadece alarm RTC IO'yu uyandırabilir." + +#: ports/espressif/common-hal/alarm/time/TimeAlarm.c +#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c +msgid "Only one alarm.time alarm can be set." msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "No network with that ssid" +#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c +msgid "Only one %q can be set in deep sleep." msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "No out in program" +#: ports/espressif/common-hal/analogbufio/BufferedIn.c +msgid "%q must be array of type 'H'" +msgstr "%q, 'H' dizisi türünde olmalıdır" + +#: ports/espressif/common-hal/audiobusio/PDMIn.c +#: shared-bindings/audioi2sin/I2SIn.c +msgid "%q must be 8, 16, 24, or 32" +msgstr "%q 8, 16, 24 veya 32 olmalıdır" + +#: ports/espressif/common-hal/audiobusio/__init__.c +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +msgid "Peripheral in use" msgstr "" -#: ports/atmel-samd/common-hal/busio/I2C.c -#: ports/espressif/common-hal/busio/I2C.c -#: ports/mimxrt10xx/common-hal/busio/I2C.c ports/nordic/common-hal/busio/I2C.c -#: ports/raspberrypi/common-hal/busio/I2C.c -msgid "No pull up found on SDA or SCL; check your wiring" -msgstr "" +#: ports/espressif/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 8 or 16" +msgstr "%q 8 veya 16 olmalıdır" -#: shared-module/touchio/TouchIn.c -msgid "No pulldown on pin; 1Mohm recommended" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" msgstr "" -#: py/moderrno.c -msgid "No space left on device" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" msgstr "" -#: py/moderrno.c -msgid "No such device" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" msgstr "" -#: py/moderrno.c -msgid "No such file/directory" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" msgstr "" -#: shared-module/rgbmatrix/RGBMatrix.c -msgid "No timer available" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" msgstr "" -#: shared-module/usb/core/Device.c -msgid "No usb host port initialized" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "Nordic system firmware out of memory" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" msgstr "" -#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c -msgid "Not a valid IP string" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#: ports/nordic/common-hal/_bleio/__init__.c -#: shared-bindings/_bleio/CharacteristicBuffer.c -msgid "Not connected" -msgstr "" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "AudioOut oluşturulamıyor çünkü kesintisiz kanal zaten açık" -#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c -#: shared-bindings/audiopwmio/PWMAudioOut.c -msgid "Not playing" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Not supported JPEG standard" -msgstr "" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/nordic/common-hal/busio/I2C.c +msgid "All I2C peripherals are in use" +msgstr "Tüm I2C çevre birimleri kullanımda" -#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c -#: ports/espressif/common-hal/sdioio/SDCard.c -#, c-format -msgid "Number of data_pins must be %d or %d, not %d" +#: ports/espressif/common-hal/busio/I2C.c +#: ports/espressif/common-hal/busio/SPI.c +msgid "Unable to create lock" msgstr "" -#: shared-bindings/util.c -msgid "" -"Object has been deinitialized and can no longer be used. Create a new object." +#: ports/espressif/common-hal/busio/SPI.c +msgid "SPI configuration failed" msgstr "" -#: ports/nordic/common-hal/busio/UART.c -msgid "Odd parity is not supported" -msgstr "" +#: ports/espressif/common-hal/busio/SPI.c ports/nordic/common-hal/busio/SPI.c +msgid "All SPI peripherals are in use" +msgstr "Tüm SPI çevre birimleri kullanımda" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Off" +#: ports/espressif/common-hal/busio/SPI.c +#: ports/espressif/common-hal/canio/CAN.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +msgid "ESP-IDF memory allocation failed" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Ok" -msgstr "" +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "Cannot specify RTS or CTS in RS485 mode" +msgstr "RS485 modunda RTS veya CTS belirtilemez" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -#, c-format -msgid "Only 8 or 16 bit mono with %dx oversampling supported." +#: ports/espressif/common-hal/busio/UART.c +#: ports/mimxrt10xx/common-hal/busio/UART.c +msgid "RS485 inversion specified when not in RS485 mode" msgstr "" -#: ports/espressif/common-hal/wifi/__init__.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -msgid "Only IPv4 addresses supported" -msgstr "" +#: ports/espressif/common-hal/canio/CAN.c +msgid "Baudrate not supported by peripheral" +msgstr "Baudhızı, çevre birimi tarafından desteklenmiyor" -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Only IPv4 sockets supported" +#: ports/espressif/common-hal/canio/CAN.c +msgid "All CAN peripherals are in use" +msgstr "Tüm CAN çevre birimleri kullanımda" + +#: ports/espressif/common-hal/canio/CAN.c +msgid "loopback + silent mode not supported by peripheral" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c +#: ports/espressif/common-hal/canio/CAN.c #, c-format -msgid "" -"Only Windows format, uncompressed BMP supported: given header size is %d" +msgid "twai_driver_install returned esp-idf error #%d" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Only connectable advertisements can be directed" +#: ports/espressif/common-hal/canio/CAN.c +#, c-format +msgid "twai_start returned esp-idf error #%d" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Only edge detection is available on this hardware" +#: ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +msgid "Must provide 5/6/5 RGB pins" msgstr "" -#: shared-bindings/ipaddress/__init__.c -msgid "Only int or string supported for ip" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is duplicate" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is invalid" +msgstr "Yazılım geçersiz" -#: ports/espressif/common-hal/alarm/touch/TouchAlarm.c -msgid "Only one %q can be set in deep sleep." -msgstr "" +#: ports/espressif/common-hal/dualbank/__init__.c +msgid "Firmware is too big" +msgstr "Yazılım çok büyük" -#: ports/espressif/common-hal/espulp/ULPAlarm.c -msgid "Only one %q can be set." +#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c +msgid "no such attribute" msgstr "" -#: ports/espressif/common-hal/i2ctarget/I2CTarget.c -#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c -msgid "Only one address is allowed" +#: ports/espressif/common-hal/espcamera/Camera.c +msgid "invalid setting" msgstr "" -#: ports/atmel-samd/common-hal/alarm/time/TimeAlarm.c -#: ports/nordic/common-hal/alarm/time/TimeAlarm.c -#: ports/stm/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Generic Failure" msgstr "" -#: ports/espressif/common-hal/alarm/time/TimeAlarm.c -#: ports/raspberrypi/common-hal/alarm/time/TimeAlarm.c -msgid "Only one alarm.time alarm can be set." +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Out of memory" msgstr "" -#: shared-module/displayio/ColorConverter.c -msgid "Only one color can be transparent at a time" -msgstr "" +#: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c +msgid "Invalid argument" +msgstr "Geçersiz argüman" -#: py/moderrno.c -msgid "Operation not permitted" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Invalid size" +msgstr "Geçersiz boyut" + +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Requested resource not found" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c @@ -1662,1025 +1494,1274 @@ msgid "Operation or feature not supported" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c msgid "Operation timed out" msgstr "" -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Out of MDNS service slots" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Received response was invalid" msgstr "" #: ports/espressif/common-hal/espidf/__init__.c -msgid "Out of memory" -msgstr "" +msgid "CRC or checksum was invalid" +msgstr "CRC yada checksum geçersiz" -#: ports/espressif/common-hal/socketpool/Socket.c -#: ports/raspberrypi/common-hal/socketpool/Socket.c -msgid "Out of sockets" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "Version was invalid" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Out-buffer elements must be <= 4 bytes long" +#: ports/espressif/common-hal/espidf/__init__.c +msgid "MAC address was invalid" +msgstr "MAC adresi geçersiz" + +#: ports/espressif/common-hal/espidf/__init__.c +#, c-format +msgid "%s error 0x%x" +msgstr "%s hatası 0x%x" + +#: ports/espressif/common-hal/espulp/ULP.c +msgid "Program too long" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "PWM restart" +#: ports/espressif/common-hal/espulp/ULP.c +#: ports/espressif/common-hal/mipidsi/Bus.c +#: ports/espressif/common-hal/qspibus/QSPIBus.c +#: ports/mimxrt10xx/common-hal/audiobusio/__init__.c +#: ports/mimxrt10xx/common-hal/usb_host/Port.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c shared-bindings/microcontroller/Pin.c +#: shared-module/max3421e/Max3421E.c +msgid "%q in use" +msgstr "%q kullanımda" + +#: ports/espressif/common-hal/espulp/ULPAlarm.c +msgid "Only one %q can be set." msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "PWM slice already in use" +#: ports/espressif/common-hal/i2ctarget/I2CTarget.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "Only one address is allowed" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "PWM slice channel A already in use" +#: ports/espressif/common-hal/max3421e/Max3421E.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +#, c-format +msgid "Unknown error code %d" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Parameter error" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS only works with built-in WiFi" msgstr "" -#: ports/espressif/common-hal/audiobusio/__init__.c -msgid "Peripheral in use" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "mDNS already initialized" msgstr "" -#: py/moderrno.c -msgid "Permission denied" +#: ports/espressif/common-hal/mdns/Server.c +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Unable to start mDNS query" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -msgid "Pin cannot wake from Deep Sleep" +#: ports/espressif/common-hal/memorymap/AddressRange.c +#: ports/nordic/common-hal/memorymap/AddressRange.c +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Address range not allowed" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Pin count too large" +#: ports/espressif/common-hal/nvm/ByteArray.c +msgid "NVS Error" +msgstr "NVS hatası" + +#: ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +#: ports/espressif/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d or %d, not %d" msgstr "" -#: ports/stm/common-hal/alarm/pin/PinAlarm.c -#: ports/stm/common-hal/pulseio/PulseIn.c -msgid "Pin interrupt already in use" +#: ports/espressif/common-hal/pulseio/PulseIn.c +msgid "pop from an empty PulseIn" msgstr "" -#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c -msgid "Pin is input only" +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-module/usb/core/Device.c +msgid "Could not allocate DMA capable buffer" +msgstr "DMA yetenekli tampon tahsis edilemedi" + +#: ports/espressif/common-hal/qspibus/QSPIBus.c shared-bindings/pwmio/PWMOut.c +#: supervisor/shared/settings.c +msgid "Internal error" +msgstr "Dahili hata" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "Pin must be on PWM Channel B" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" msgstr "" -#: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "" -"Pinout uses %d bytes per element, which consumes more than the ideal %d " -"bytes. If this cannot be avoided, pass allow_inefficient=True to the " -"constructor" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "ROS konusuna yayımlanamadı" + +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" msgstr "" +"Yazılımsal yeniden başlatma sırasında kritik ROS hatası, sıfırlama " +"gerekiyor: %d" -#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c -msgid "Pins must be sequential" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" msgstr "" -#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c -msgid "Pins must be sequential GPIO pins" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" msgstr "" -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Pins must share PWM slice" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" msgstr "" -#: shared-module/usb/core/Device.c -msgid "Pipe error" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" msgstr "" -#: py/builtinhelp.c -msgid "Plus any modules on the filesystem\n" +#: ports/espressif/common-hal/sdioio/SDCard.c +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "SDIO Init Error 0x%02x" msgstr "" -#: shared-module/vectorio/Polygon.c -msgid "Polygon needs at least 3 points" +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Unsupported socket type" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Power dipped. Make sure you are providing enough power." +#: ports/espressif/common-hal/socketpool/Socket.c +#: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c +msgid "Out of sockets" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "Prefix buffer must be on the heap" +#: ports/espressif/common-hal/socketpool/SocketPool.c +#: ports/raspberrypi/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio" msgstr "" -#: main.c -msgid "Press any key to enter the REPL. Use CTRL-D to reload.\n" +#: ports/espressif/common-hal/watchdog/WatchDogTimer.c +msgid "%q must be <= %u" +msgstr "%q, %u değerinden küçük veya eşit olmalıdır" + +#: ports/espressif/common-hal/wifi/Monitor.c +msgid "monitor init failed" msgstr "" -"REPL moda girmek için herhangi bir tuşa basınız. Programı yeniden yüklemek " -"için CTRL+D tuş kombinasyonunu kullanabilirsiniz.\n" -#: main.c -msgid "Pretending to deep sleep until alarm, CTRL-C or file write.\n" +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Interface must be started" +msgstr "Arayüz başlatılmalıdır" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Invalid multicast MAC address" +msgstr "Geçersiz multicast MAC adresi" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Already scanning for wifi networks" +msgstr "Halihazırda wifi ağları için tarama yapılıyor" + +#: ports/espressif/common-hal/wifi/Radio.c +#: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" msgstr "" -"Alarma, CTRL-C'ye veya dosya yazana kadar derin uyku moduna geçiliyor.\n" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does IN without loading ISR" +#: ports/espressif/common-hal/wifi/ScannedNetworks.c +msgid "Failed to allocate wifi scan memory" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "Program does OUT without loading OSR" +#: ports/espressif/common-hal/wifi/__init__.c +msgid "Failed to allocate Wifi memory" msgstr "" -#: ports/raspberrypi/bindings/rp2pio/StateMachine.c -msgid "Program size invalid" +#: ports/espressif/common-hal/wifi/__init__.c +#: ports/raspberrypi/common-hal/wifi/__init__.c +msgid "Only IPv4 addresses supported" msgstr "" -#: ports/espressif/common-hal/espulp/ULP.c -msgid "Program too long" +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/busio/SPI.c +msgid "Must provide MISO or MOSI pin" msgstr "" -#: shared-bindings/digitalio/DigitalInOut.c -msgid "Pull not used when direction is output." +#: ports/mimxrt10xx/common-hal/busio/SPI.c +#: ports/mimxrt10xx/common-hal/busio/UART.c ports/stm/common-hal/busio/I2C.c +#: ports/stm/common-hal/busio/SPI.c ports/stm/common-hal/busio/UART.c +#: ports/stm/common-hal/canio/CAN.c ports/stm/common-hal/sdioio/SDCard.c +msgid "Hardware in use, try alternative pins" +msgstr "Donanım kullanımda, alternatif pinleri deneyin" + +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" msgstr "" -#: ports/raspberrypi/common-hal/countio/Counter.c -msgid "RISE_AND_FALL not available on this chip" +#: ports/mimxrt10xx/common-hal/microcontroller/Processor.c +msgid "" +"Frequency must be 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 or 1008 Mhz" msgstr "" +"Frekans 24, 150, 396, 450, 528, 600, 720, 816, 912, 960 ya da 1008 Mhz " +"olmalıdır" -#: shared-module/displayio/OnDiskBitmap.c -msgid "RLE-compressed BMP not supported" +#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h +msgid "You pressed the left button at start up." msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG DeInit Error" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "timeout must be < 655.35 secs" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "RNG Init Error" +#: ports/nordic/common-hal/_bleio/Adapter.c +msgid "non-zero timeout must be > 0.01" msgstr "" -#: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c -#: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c -msgid "RS485" +#: ports/nordic/common-hal/_bleio/Adapter.c +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Failed to connect: timeout" +msgstr "Bağlantı kurulamadı: timeout" + +#: ports/nordic/common-hal/_bleio/UUID.c +msgid "Unexpected nrfx uuid type" msgstr "" -#: ports/espressif/common-hal/busio/UART.c -#: ports/mimxrt10xx/common-hal/busio/UART.c -msgid "RS485 inversion specified when not in RS485 mode" +#: ports/nordic/common-hal/_bleio/__init__.c +msgid "Nordic system firmware out of memory" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c -msgid "RTC is not supported on this board" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown system firmware error: %04x" msgstr "" -#: ports/stm/common-hal/os/__init__.c -msgid "Random number generation error" +#: ports/nordic/common-hal/_bleio/__init__.c +#, c-format +msgid "Unknown gatt error: 0x%04x" msgstr "" -#: shared-bindings/_bleio/__init__.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c -#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c -msgid "Read-only" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +msgid "" +"Unspecified issue. The pairing request on the other device may have been " +"declined or ignored." msgstr "" -#: extmod/vfs_fat.c py/moderrno.c -msgid "Read-only filesystem" +#: ports/nordic/common-hal/_bleio/__init__.c +#: ports/zephyr-cp/common-hal/_bleio/Connection.c +#, c-format +msgid "Unknown security error: 0x%04x" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Received response was invalid" +#: ports/nordic/common-hal/alarm/pin/PinAlarm.c +msgid "Cannot wake on pin edge, only level" +msgstr "Pin kenarı ile uyandırılamaz, yalnızca seviye ile uyanabilir" + +#: ports/nordic/common-hal/audiobusio/I2SOut.c +msgid "Device in use" +msgstr "Cihaz kullanımda" + +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only sample_rate=16000 is supported" msgstr "" -#: supervisor/shared/bluetooth/bluetooth.c -msgid "Reconnecting" +#: ports/nordic/common-hal/audiobusio/PDMIn.c +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only bit_depth=16 is supported" msgstr "" -#: shared-bindings/epaperdisplay/EPaperDisplay.c -msgid "Refresh too soon" +#: ports/nordic/common-hal/busio/UART.c +#, c-format +msgid "error = 0x%08lX" msgstr "" -#: shared-bindings/canio/RemoteTransmissionRequest.c -msgid "RemoteTransmissionRequests limited to 8 bytes" +#: ports/nordic/common-hal/busio/UART.c +msgid "Odd parity is not supported" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Requested AES mode is unsupported" +#: ports/nordic/common-hal/countio/Counter.c +#: ports/nordic/common-hal/pulseio/PulseIn.c +#: ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +msgid "All channels in use" +msgstr "Tüm kanallar kullanımda" + +#: ports/nordic/common-hal/microcontroller/Processor.c +msgid "Cannot get temperature" +msgstr "Isı okunamadı" + +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Requested resource not found" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "timeout duration exceeded the maximum supported value" msgstr "" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -msgid "Right channel unsupported" +#: ports/nordic/common-hal/watchdog/WatchDogTimer.c +msgid "%q cannot be changed once mode is set to %q" +msgstr "Mod %q olarak ayarlandıktan sonra %q değiştirilemez" + +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to acquire mutex, err 0x%04x" +msgstr "Muteks alınamadı, err 0x%04x" + +#: ports/nordic/sd_mutex.c +#, c-format +msgid "Failed to release mutex, err 0x%04x" +msgstr "Muteks serbest bırakılamadı, err 0x%04x" + +#: ports/raspberrypi/audio_dma.c +msgid "Audio conversion not implemented" +msgstr "Ses dönüşümü implemente edilmedi" + +#: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c +#: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c +#: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c +#: shared-module/synthio/Synthesizer.c +msgid "%q must be of type %q or %q, not %q" +msgstr "%q; %q veya %q tipi olmalıdır, %q değil" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Program size invalid" msgstr "" -#: shared-module/jpegio/JpegDecoder.c -msgid "Right format but not supported" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Init program size invalid" +msgstr "Init program boyutu geçersiz" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Buffer elements must be 4 bytes long or less" +msgstr "Buffer elementleri 4 bit olmak zorunda" + +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched data size" msgstr "" -#: main.c -msgid "Running in safe mode! Not running saved code.\n" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "Out-buffer elements must be <= 4 bytes long" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "SD card CSD format not supported" +#: ports/raspberrypi/bindings/rp2pio/StateMachine.c +msgid "In-buffer elements must be <= 4 bytes long" +msgstr "Buffer öğeleri <=4 bayt uzunluğunda olmalı" + +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/I2C.c +#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/I2C.c +#: shared-bindings/busio/SPI.c +msgid "Function requires lock" +msgstr "Fonksiyon kilit gerektirir" + +#: ports/raspberrypi/bindings/wiznet/PIO_SPI.c shared-bindings/bitbangio/SPI.c +#: shared-bindings/busio/SPI.c +msgid "buffer slices must be of equal length" msgstr "" -#: ports/cxd56/common-hal/sdioio/SDCard.c -msgid "SDCard init" +#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c +#: ports/stm/common-hal/alarm/touch/TouchAlarm.c +msgid "Touch alarms not available" msgstr "" -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO GetCardInfo Error %d" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "GPIO0..15, GPIO32..47 ile birlikte kullanılamaz" + +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "Bit clock and word select must be sequential GPIO pins" +msgstr "Bit saati ve kelime seçimi ardışık GPIO pinleri olmalı" + +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Too many channels in sample." msgstr "" -#: ports/espressif/common-hal/sdioio/SDCard.c -#: ports/stm/common-hal/sdioio/SDCard.c -#, c-format -msgid "SDIO Init Error %x" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +msgid "Audio source error" +msgstr "Ses kaynağı hatası" + +#: ports/raspberrypi/common-hal/audioi2sin/I2SIn.c +msgid "%q must be 16, 24, or 32" +msgstr "%q 16,24 veya 32 olmalıdır" + +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Pins must share PWM slice" msgstr "" -#: ports/espressif/common-hal/busio/SPI.c -msgid "SPI configuration failed" +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "No DMA pacing timer found" msgstr "" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI init error" -msgstr "" +#: ports/raspberrypi/common-hal/busio/I2C.c +#: ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +msgid "I2C peripheral in use" +msgstr "I2C çevre cihazı kullanımda" #: ports/raspberrypi/common-hal/busio/SPI.c msgid "SPI peripheral in use" msgstr "" -#: ports/stm/common-hal/busio/SPI.c -msgid "SPI re-init" -msgstr "" - -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "Scale dimensions must divide by 3" -msgstr "" - -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "Scan already in progress. Stop with stop_scan." +#: ports/raspberrypi/common-hal/busio/UART.c +msgid "UART peripheral in use" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -msgid "Serializer in use" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "Pin must be on PWM Channel B" msgstr "" -#: shared-bindings/ssl/SSLContext.c -msgid "Server side context cannot have hostname" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "RISE_AND_FALL not available on this chip" msgstr "" -#: ports/cxd56/common-hal/camera/Camera.c -msgid "Size not supported" +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice already in use" msgstr "" -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "Slice and value different lengths." +#: ports/raspberrypi/common-hal/countio/Counter.c +msgid "PWM slice channel A already in use" msgstr "" -#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c -#: shared-bindings/displayio/TileGrid.c -#: shared-bindings/memorymonitor/AllocationSize.c -#: shared-bindings/pulseio/PulseIn.c -msgid "Slices not supported" -msgstr "" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All state machines in use" +msgstr "Tüm durum makineleri kullanımda" -#: ports/espressif/common-hal/socketpool/SocketPool.c -#: ports/raspberrypi/common-hal/socketpool/SocketPool.c -msgid "SocketPool can only be used with wifi.radio" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +msgid "timeout waiting for flux" msgstr "" -#: shared-bindings/aesio/aes.c -msgid "Source and destination buffers must be the same length" +#: ports/raspberrypi/common-hal/floppyio/__init__.c +#: shared-module/floppyio/__init__.c +msgid "timeout waiting for index pulse" msgstr "" -#: shared-bindings/paralleldisplaybus/ParallelBus.c -msgid "Specify exactly one of data0 or data_pins" +#: ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +msgid "Pins must be sequential" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Stack overflow. Increase stack size." +#: ports/raspberrypi/common-hal/mcp4822/MCP4822.c +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +#: shared-module/aurora_epaper/aurora_framebuffer.c +msgid "Invalid %q and %q" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Supply one of monotonic_time or epoch_time" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Failed to add service TXT record" msgstr "" -#: shared-bindings/gnss/GNSS.c -msgid "System entry must be gnss.SatelliteSystem" +#: ports/raspberrypi/common-hal/mdns/Server.c +msgid "Out of MDNS service slots" msgstr "" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Temperature read timed out" +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to access unaligned IO register" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "The `microcontroller` module was used to boot into safe mode." +#: ports/raspberrypi/common-hal/memorymap/AddressRange.c +msgid "Unable to write to read-only memory" msgstr "" -#: py/obj.c -msgid "The above exception was the direct cause of the following exception:" -msgstr "" +#: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +msgid "All timers for this pin are in use" +msgstr "Bu pin için tüm zamanlayıcılar kullanımda" -#: shared-bindings/rgbmatrix/RGBMatrix.c -msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" +#: ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c +msgid "Pins must be sequential GPIO pins" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Pin count too large" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing jmp_pin. %q[%u] jumps on pin" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] uses extra pin" msgstr "" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] waits based on pin" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "Third-party firmware fatal error." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] waits on input outside of count" msgstr "" -#: shared-module/imagecapture/ParallelImageCapture.c -msgid "This microcontroller does not support continuous capture." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] shifts in from pin(s)" msgstr "" -#: shared-module/paralleldisplaybus/ParallelBus.c -msgid "" -"This microcontroller only supports data0=, not data_pins=, because it " -"requires contiguous pins." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts in more bits than pin count" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile height must exactly divide bitmap height" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] shifts out to pin(s)" msgstr "" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c -msgid "Tile index out of bounds" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "%q[%u] shifts out more bits than pin count" msgstr "" -#: shared-bindings/displayio/TileGrid.c -msgid "Tile width must exactly divide bitmap width" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_set_pin. %q[%u] sets pin(s)" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "Time is in the past." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_out_pin. %q[%u] writes pin(s)" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/nordic/common-hal/_bleio/Adapter.c -#, c-format -msgid "Timeout is too long: Maximum timeout length is %d seconds" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Missing first_in_pin. %q[%u] reads pin(s)" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does IN without loading ISR" msgstr "" -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -msgid "Too many channels in sample." +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Program does OUT without loading OSR" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -msgid "Too many descriptors" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin state conflicts with initial out pin state" +msgstr "İlk pinin durumu, ilk çıkış pininin durumu ile çakışıyor" -#: shared-module/displayio/__init__.c -msgid "Too many display busses; forgot displayio.release_displays() ?" -msgstr "" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Initial set pin direction conflicts with initial out pin direction" +msgstr "İlk pin yönü, ilk çıkış pin yönüyle çakışıyor" -#: shared-module/displayio/__init__.c -msgid "Too many displays" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "pull masks conflict with direction masks" msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Total data to write is larger than %q" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No out in program" msgstr "" -#: ports/raspberrypi/common-hal/alarm/touch/TouchAlarm.c -#: ports/stm/common-hal/alarm/touch/TouchAlarm.c -msgid "Touch alarms not available" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in in program" msgstr "" -#: py/obj.c -msgid "Traceback (most recent call last):\n" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "No in or out in program" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART de-init" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Mismatched swap flag" msgstr "" -#: ports/cxd56/common-hal/busio/UART.c ports/espressif/common-hal/busio/UART.c -#: ports/stm/common-hal/busio/UART.c -msgid "UART init" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +#, c-format +msgid "Number of data_pins must be %d, not %d" msgstr "" -#: ports/raspberrypi/common-hal/busio/UART.c -msgid "UART peripheral in use" +#: ports/raspberrypi/common-hal/sdioio/SDCard.c +msgid "Data pins must be consecutive" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART re-init" +#: ports/raspberrypi/common-hal/socketpool/Socket.c +msgid "Only IPv4 sockets supported" msgstr "" -#: ports/stm/common-hal/busio/UART.c -msgid "UART write" -msgstr "" +#: ports/raspberrypi/common-hal/usb_host/Port.c +msgid "All dma channels in use" +msgstr "Kullanımdaki tüm dma kanalları" -#: main.c -msgid "UID:" +#: ports/raspberrypi/common-hal/wifi/Monitor.c +msgid "wifi.Monitor not available" msgstr "" -#: shared-module/usb_hid/Device.c -msgid "USB busy" -msgstr "" +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "%q is read-only for this board" +msgstr "%q bu kart için salt okunur" -#: supervisor/shared/safe_mode.c -msgid "USB devices need more endpoints than are available." +#: ports/raspberrypi/common-hal/wifi/Radio.c +msgid "AP could not be started" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "USB devices specify too many interface names." +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Only edge detection is available on this hardware" msgstr "" -#: shared-module/usb_hid/Device.c -msgid "USB error" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +#: ports/stm/common-hal/pulseio/PulseIn.c +msgid "Pin interrupt already in use" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID integer value must be 0-0xffff" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Pin cannot wake from Deep Sleep" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +#: ports/stm/common-hal/alarm/pin/PinAlarm.c +msgid "Deep sleep pins must use a rising edge with pulldown" msgstr "" +"Derin uyku pinleri, aşağı çekme direnci ile yükselen kenar kullanmalıdır" -#: shared-bindings/_bleio/UUID.c -msgid "UUID value is not str, int or byte buffer" -msgstr "" +#: ports/stm/common-hal/analogio/AnalogIn.c +msgid "Invalid ADC Unit value" +msgstr "Geçersiz ADC Ünite değeri" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to access unaligned IO register" -msgstr "" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Device Init Error" +msgstr "DAC cihazı başlatma hatası" -#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c -#: ports/atmel-samd/common-hal/audioio/AudioOut.c -#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c -#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -msgid "Unable to allocate buffers for signed conversion" -msgstr "" +#: ports/stm/common-hal/analogio/AnalogOut.c +#: ports/stm/common-hal/audioio/AudioOut.c +msgid "DAC Channel Init Error" +msgstr "DAC kanalı başlatma hatası" -#: supervisor/shared/safe_mode.c -msgid "Unable to allocate to the heap." +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only mono is supported" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "Unable to create lock" +#: ports/stm/common-hal/audiobusio/PDMIn.c +msgid "only oversample=64 is supported" msgstr "" -#: shared-module/i2cdisplaybus/I2CDisplayBus.c -#: shared-module/is31fl3741/IS31FL3741.c +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Another PWMAudioOut is already active" +msgstr "Başka bir PWMAudioOut zaten aktif durumda" + +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c #, c-format -msgid "Unable to find I2C Display at %x" -msgstr "" +msgid "Buffer length %d too big. It must be less than %d" +msgstr "Mevcut arabellek boyutu %d çok büyük. En fazla %d kadar olmalı" -#: py/parse.c -msgid "Unable to init parser" +#: ports/stm/common-hal/audiopwmio/PWMAudioOut.c +msgid "Failed to buffer the sample" msgstr "" -#: shared-module/displayio/OnDiskBitmap.c -msgid "Unable to read color palette data" -msgstr "" +#: ports/stm/common-hal/busio/I2C.c +msgid "I2C init error" +msgstr "I2C init hatası" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "Unable to start mDNS query" +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI init error" msgstr "" -#: shared-bindings/nvm/ByteArray.c -msgid "Unable to write to nvm." +#: ports/stm/common-hal/busio/SPI.c +msgid "SPI re-init" msgstr "" -#: ports/raspberrypi/common-hal/memorymap/AddressRange.c -msgid "Unable to write to read-only memory" -msgstr "" +#: ports/stm/common-hal/busio/UART.c +msgid "Internal define error" +msgstr "Dahili tanımlama hatası" -#: shared-bindings/alarm/SleepMemory.c -msgid "Unable to write to sleep_memory." +#: ports/stm/common-hal/busio/UART.c +msgid "Could not start interrupt, RX busy" +msgstr "Kesinti başlatılamadı, RX kullanımda" + +#: ports/stm/common-hal/busio/UART.c +msgid "UART write" msgstr "" -#: ports/nordic/common-hal/_bleio/UUID.c -msgid "Unexpected nrfx uuid type" +#: ports/stm/common-hal/busio/UART.c +msgid "UART de-init" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error at %s:%d: %d" +#: ports/stm/common-hal/busio/UART.c +msgid "UART re-init" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown BLE error: %d" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Temperature read timed out" msgstr "" -#: ports/espressif/common-hal/max3421e/Max3421E.c -#: ports/raspberrypi/common-hal/wifi/__init__.c -#, c-format -msgid "Unknown error code %d" +#: ports/stm/common-hal/microcontroller/Processor.c +msgid "Voltage read timed out" msgstr "" -#: shared-bindings/wifi/Radio.c -#, c-format -msgid "Unknown failure %d" +#: ports/stm/common-hal/os/__init__.c +msgid "RNG Init Error" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown gatt error: 0x%04x" +#: ports/stm/common-hal/os/__init__.c +msgid "Random number generation error" msgstr "" -#: ports/atmel-samd/common-hal/alarm/pin/PinAlarm.c -#: supervisor/shared/safe_mode.c -msgid "Unknown reason." +#: ports/stm/common-hal/os/__init__.c +msgid "RNG DeInit Error" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown security error: 0x%04x" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "timer re-init" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error at %s:%d: %d" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "channel re-init" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -#, c-format -msgid "Unknown system firmware error: %04x" +#: ports/stm/common-hal/pwmio/PWMOut.c +msgid "PWM restart" msgstr "" -#: ports/espressif/common-hal/_bleio/__init__.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "Unknown system firmware error: %d" +msgid "MMC/SDIO Clock Error %x" msgstr "" -#: shared-bindings/adafruit_pixelbuf/PixelBuf.c -#: shared-module/_pixelmap/PixelMap.c +#: ports/stm/common-hal/sdioio/SDCard.c #, c-format -msgid "Unmatched number of items on RHS (expected %d, got %d)." +msgid "SDIO GetCardInfo Error %d" msgstr "" -#: ports/nordic/common-hal/_bleio/__init__.c -msgid "" -"Unspecified issue. Can be that the pairing prompt on the other device was " -"declined or ignored." +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid ".show(x) removed. Use .root_group = x" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "Unsupported colorspace" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Brightness not adjustable" +msgstr "Parlaklık ayarlanabilir değil" -#: shared-module/displayio/bus_core.c -msgid "Unsupported display bus type" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c py/argcheck.c +#: shared-bindings/busdisplay/BusDisplay.c shared-bindings/displayio/Bitmap.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/is31fl3741/FrameBuffer.c +#: shared-bindings/rgbmatrix/RGBMatrix.c +msgid "%q must be %d-%d" +msgstr "%q, %d-%d olmalıdır" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "" +#: ports/zephyr-cp/bindings/zephyr_display/Display.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Group already used" +msgstr "Grup zaten kullanılıyor" -#: shared-bindings/hashlib/__init__.c -msgid "Unsupported hash algorithm" +#: ports/zephyr-cp/common-hal/_bleio/Adapter.c +msgid "Invalid advertising data" msgstr "" -#: ports/espressif/common-hal/socketpool/Socket.c -msgid "Unsupported socket type" +#: ports/zephyr-cp/common-hal/audiobusio/I2SOut.c +#: ports/zephyr-cp/common-hal/busio/I2C.c +#: ports/zephyr-cp/common-hal/busio/SPI.c +#: ports/zephyr-cp/common-hal/busio/UART.c +msgid "Use device tree to define %q devices" msgstr "" -#: ports/espressif/common-hal/_bleio/Adapter.c -#: ports/espressif/common-hal/dualbank/__init__.c -msgid "Update failed" +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c +msgid "SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length != required fixed length" +#: ports/zephyr-cp/common-hal/usb_hid/Device.c shared-module/usb_hid/Device.c +msgid "USB error" msgstr "" -#: ports/espressif/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -msgid "Value length > max_length" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" msgstr "" -#: ports/espressif/common-hal/espidf/__init__.c -msgid "Version was invalid" -msgstr "" +#: ports/zephyr-cp/common-hal/zephyr_display/Display.c +#: shared-module/busdisplay/BusDisplay.c +#: shared-module/framebufferio/FramebufferDisplay.c +msgid "Below minimum frame rate" +msgstr "Minimum kare hızından altında" -#: ports/stm/common-hal/microcontroller/Processor.c -msgid "Voltage read timed out" +#: py/argcheck.c +msgid "function doesn't take keyword arguments" msgstr "" -#: main.c -msgid "WARNING: Your code filename has two extensions\n" +#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c +#: shared-bindings/time/__init__.c +#, c-format +msgid "function takes %d positional arguments but %d were given" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "WatchDogTimer cannot be deinitialized once mode is set to RESET" +#: py/argcheck.c +#, c-format +msgid "function missing %d required positional arguments" msgstr "" -#: py/builtinhelp.c +#: py/argcheck.c #, c-format -msgid "" -"Welcome to Adafruit CircuitPython %s!\n" -"\n" -"Visit circuitpython.org for more information.\n" -"\n" -"To list built-in modules type `help(\"modules\")`.\n" +msgid "function expected at most %d arguments, got %d" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "Wi-Fi: " +#: py/argcheck.c +msgid "'%q' argument required" +msgstr "'%q' argümanı gerekli" + +#: py/argcheck.c +msgid "extra positional arguments given" msgstr "" -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" +#: py/argcheck.c py/bc.c py/objnamedtuple.c +#: shared-bindings/traceback/__init__.c +msgid "unexpected keyword argument '%q'" msgstr "" -#: main.c -msgid "Woken up by alarm.\n" +#: py/argcheck.c +msgid "extra keyword arguments given" msgstr "" -#: ports/espressif/common-hal/_bleio/PacketBuffer.c -#: ports/nordic/common-hal/_bleio/PacketBuffer.c -msgid "Writes not supported on Characteristic" +#: py/argcheck.c shared-bindings/_stage/__init__.c +#: shared-bindings/digitalio/DigitalInOut.c +msgid "argument num/types mismatch" msgstr "" -#: ports/atmel-samd/boards/circuitplayground_express/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_crickit/mpconfigboard.h -#: ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h -#: ports/atmel-samd/boards/meowmeow/mpconfigboard.h -msgid "You pressed both buttons at start up." +#: py/argcheck.c +msgid "keyword argument(s) not implemented - use normal args instead" msgstr "" -#: ports/espressif/boards/m5stack_core_basic/mpconfigboard.h -#: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h -#: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h -msgid "You pressed button A at start up." +#: py/argcheck.c +msgid "%q must be %d" +msgstr "%q, %d olmalıdır" + +#: py/argcheck.c +msgid "%q must be >= %d" +msgstr "%q >= %d olmalıdır" + +#: py/argcheck.c shared-bindings/gifio/GifWriter.c +#: shared-module/gifio/OnDiskGif.c +msgid "%q must be <= %d" +msgstr "%q <= %d olmalıdır" + +#: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c +#: shared-module/synthio/__init__.c +msgid "%q must be of type %q, not %q" +msgstr "%q; %q tipi olmalıdır, %q değil" + +#: py/argcheck.c +msgid "%q length must be %d-%d" +msgstr "%q boyutları %d-%d olmalıdır" + +#: py/argcheck.c +msgid "%q length must be >= %d" +msgstr "%q boyutu >= %d olmalıdır" + +#: py/argcheck.c +msgid "%q length must be <= %d" +msgstr "%q boyutu <= %d olmalıdır" + +#: py/argcheck.c shared-bindings/usb_hid/Device.c +msgid "%q length must be %d" +msgstr "%q boyutu %d olmalıdır" + +#: py/argcheck.c shared-module/audiofilters/Filter.c +msgid "%q in %q must be of type %q, not %q" +msgstr "%q'nün içindeki %q, %q tipi olmalıdır, %q değil" + +#: py/asmthumb.c +msgid "too many locals for native method" msgstr "" -#: ports/espressif/boards/m5stack_m5paper/mpconfigboard.h -msgid "You pressed button DOWN at start up." +#: py/asmxtensa.c +msgid "ERROR: xtensa %q out of range" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the BOOT button at start up" +#: py/asmxtensa.c +msgid "ERROR: %q %q not word-aligned" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h -#: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h -msgid "You pressed the BOOT button at start up." -msgstr "" +#: py/bc.c py/objnamedtuple.c +msgid "%q() takes %d positional arguments but %d were given" +msgstr "%q(), %d konumsal argümanını alır ancak %d verildi" -#: ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.h -msgid "You pressed the GPIO0 button at start up." +#: py/bc.c py/objnamedtuple.c +msgid "function got multiple values for argument '%q'" msgstr "" -#: ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.h -msgid "You pressed the Rec button at start up." +#: py/bc.c +msgid "unexpected keyword argument" msgstr "" -#: ports/espressif/boards/adafruit_feather_esp32_v2/mpconfigboard.h -msgid "You pressed the SW38 button at start up." +#: py/bc.c +#, c-format +msgid "function missing required positional argument #%d" msgstr "" -#: ports/espressif/boards/hardkernel_odroid_go/mpconfigboard.h -#: ports/espressif/boards/vidi_x/mpconfigboard.h -msgid "You pressed the VOLUME button at start up." +#: py/bc.c +msgid "function missing required keyword argument '%q'" msgstr "" -#: ports/espressif/boards/m5stack_atom_echo/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_lite/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.h -#: ports/espressif/boards/m5stack_atom_u/mpconfigboard.h -msgid "You pressed the central button at start up." +#: py/bc.c +msgid "function missing keyword-only argument" msgstr "" -#: ports/nordic/boards/aramcon2_badge/mpconfigboard.h -msgid "You pressed the left button at start up." +#: py/binary.c py/objarray.c +msgid "bad typecode" msgstr "" -#: supervisor/shared/safe_mode.c -msgid "You pressed the reset button during boot." +#: py/builtinevex.c +msgid "bad compile mode" msgstr "" -#: supervisor/shared/micropython.c -msgid "[truncated due to length]" +#: py/builtinhelp.c +msgid "Plus any modules on the filesystem\n" msgstr "" -#: py/objtype.c -msgid "__init__() should return None" +#: py/builtinhelp.c +msgid "object " msgstr "" -#: py/objtype.c +#: py/builtinhelp.c +msgid " is of type %q\n" +msgstr " nesnesi, %q tipindedir\n" + +#: py/builtinhelp.c #, c-format -msgid "__init__() should return None, not '%s'" +msgid "" +"Welcome to Adafruit CircuitPython %s!\n" +"\n" +"Visit circuitpython.org for more information.\n" +"\n" +"To list built-in modules type `help(\"modules\")`.\n" msgstr "" -#: py/objobject.c -msgid "__new__ arg must be a user-type" +#: py/builtinimport.c +msgid "script compilation not supported" msgstr "" -#: extmod/modbinascii.c extmod/modhashlib.c py/objarray.c -msgid "a bytes-like object is required" +#: py/builtinimport.c +msgid "can't perform relative import" msgstr "" -#: shared-bindings/i2ctarget/I2CTarget.c -msgid "addresses is empty" +#: py/builtinimport.c +msgid "module not found" msgstr "" -#: py/compile.c -msgid "annotation must be an identifier" +#: py/builtinimport.c +msgid "no module named '%q'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "arange: cannot compute length" +#: py/builtinimport.c +msgid "relative import" msgstr "" -#: py/modbuiltins.c -msgid "arg is an empty sequence" +#: py/compile.c +msgid "can't assign to expression" msgstr "" -#: py/objobject.c -msgid "arg must be user-type" +#: py/compile.c +msgid "multiple *x in assignment" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort argument must be an ndarray" +#: py/compile.c +msgid "non-default argument follows default argument" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "argsort is not implemented for flattened arrays" +#: py/compile.c +msgid "invalid micropython decorator" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "argument must be None, an integer or a tuple of integers" +#: py/compile.c +msgid "invalid arch" msgstr "" #: py/compile.c -msgid "argument name reused" +msgid "can't delete expression" msgstr "" -#: py/argcheck.c shared-bindings/_stage/__init__.c -#: shared-bindings/digitalio/DigitalInOut.c -msgid "argument num/types mismatch" -msgstr "" +#: py/compile.c +msgid "'break'/'continue' outside loop" +msgstr "Döngü dışında 'break'/'continue'" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/numpy/transform.c -msgid "arguments must be ndarrays" +#: py/compile.c +msgid "'return' outside function" +msgstr "fonksiyon dışında 'return'" + +#: py/compile.c +msgid "import * not at module level" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array and index length must be equal" +#: py/compile.c +msgid "identifier redefined as global" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "array has too many dimensions" +#: py/compile.c +msgid "no binding for nonlocal found" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "array is too big" +#: py/compile.c +msgid "identifier redefined as nonlocal" msgstr "" -#: py/objarray.c shared-bindings/alarm/SleepMemory.c -#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c -msgid "array/bytes required on right side" +#: py/compile.c +msgid "can't declare nonlocal in outer code" msgstr "" -#: py/asmxtensa.c -msgid "asm overflow" +#: py/compile.c +msgid "default 'except' must be last" msgstr "" #: py/compile.c msgid "async for/with outside async function" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get (arg)min/(arg)max of empty sequence" -msgstr "" +#: py/compile.c +msgid "*x must be assignment target" +msgstr "*x atama hedefi olmalıdır" -#: extmod/ulab/code/numpy/numerical.c -msgid "attempt to get argmin/argmax of an empty sequence" +#: py/compile.c +msgid "super() can't find self" msgstr "" -#: py/objstr.c -msgid "attributes not supported" +#: py/compile.c +msgid "* arg after **" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "axis is out of bounds" +#: py/compile.c +msgid "too many args" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -msgid "axis must be None, or an integer" +#: py/compile.c +msgid "LHS of keyword arg must be an id" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "axis too long" +#: py/compile.c +msgid "positional arg after **" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "background value out of range of target" +#: py/compile.c +msgid "positional arg after keyword arg" msgstr "" -#: py/builtinevex.c -msgid "bad compile mode" +#: py/compile.c py/parse.c +msgid "invalid syntax" msgstr "" -#: py/objstr.c -msgid "bad conversion specifier" +#: py/compile.c +msgid "expecting key:value for dict" msgstr "" -#: py/objstr.c -msgid "bad format string" +#: py/compile.c +msgid "expecting just a value for set" msgstr "" -#: py/binary.c py/objarray.c -msgid "bad typecode" -msgstr "" +#: py/compile.c +msgid "'yield' outside function" +msgstr "fonksiyon dışında 'yield'" -#: py/emitnative.c -msgid "binary op %q not implemented" +#: py/compile.c +msgid "'yield from' inside async function" +msgstr "asenkron fonksiyon içinde 'yield from'" + +#: py/compile.c +msgid "'await' outside function" +msgstr "fonksiyon dışında 'await'" + +#: py/compile.c +msgid "unknown type '%q'" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "bitmap size and depth must match" +#: py/compile.c +msgid "annotation must be an identifier" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "bitmap sizes must match" +#: py/compile.c +msgid "argument name reused" msgstr "" -#: extmod/modrandom.c -msgid "bits must be 32 or less" +#: py/compile.c +msgid "inline assembler must be a function" msgstr "" -#: shared-bindings/audiomixer/Mixer.c -msgid "bits_per_sample must be 8 or 16" +#: py/compile.c +msgid "unknown type" msgstr "" -#: py/emitinlinethumb.c -msgid "branch not in range" +#: py/compile.c +msgid "return annotation must be an identifier" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer is smaller than requested size" +#: py/compile.c +msgid "expecting an assembler instruction" msgstr "" -#: extmod/ulab/code/numpy/create.c extmod/ulab/code/utils/utils.c -msgid "buffer size must be a multiple of element size" +#: py/compile.c +msgid "'label' requires 1 argument" +msgstr "'label' 1 argümana ihtiyaç duyar" + +#: py/compile.c +msgid "label redefined" msgstr "" -#: shared-module/struct/__init__.c -msgid "buffer size must match format" +#: py/compile.c +msgid "'align' requires 1 argument" +msgstr "'align' 1 argümana ihtiyaç duyar" + +#: py/compile.c +msgid "'data' requires at least 2 arguments" +msgstr "'data' en az 2 argümana ihtiyaç duyar" + +#: py/compile.c +msgid "'data' requires integer arguments" +msgstr "'data' integer tipinde argümanlara ihtiyaç duyar" + +#: py/compile.c +msgid "cannot emit native code for this architecture" msgstr "" -#: shared-bindings/bitbangio/SPI.c shared-bindings/busio/SPI.c -msgid "buffer slices must be of equal length" +#: py/emitbc.c +msgid "bytecode overflow" msgstr "" -#: py/modstruct.c shared-module/struct/__init__.c -msgid "buffer too small" +#: py/emitinlinerv32.c +msgid "can only have up to 4 parameters for RV32 assembly" msgstr "" -#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c -msgid "buffer too small for requested bytes" +#: py/emitinlinerv32.c +msgid "parameters must be registers in sequence a0 to a3" +msgstr "" + +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: expecting %q" msgstr "" -#: py/emitbc.c -msgid "bytecode overflow" +#: py/emitinlinerv32.c +msgid "opcode '%q': expecting %d arguments" msgstr "" -#: py/objarray.c -msgid "bytes length not a multiple of item size" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: out of range" msgstr "" -#: py/objstr.c -msgid "bytes value out of range" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: unknown register" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is out of range" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: undefined label '%q'" msgstr "" -#: ports/atmel-samd/bindings/samd/Clock.c -msgid "calibration is read only" +#: py/emitinlinerv32.c +msgid "opcode '%q' argument %d: must not be zero" msgstr "" -#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c -#: shared-module/vectorio/Rectangle.c -msgid "can only have one parent" +#: py/emitinlinerv32.c +msgid "invalid RV32 instruction '%q'" msgstr "" #: py/emitinlinethumb.c msgid "can only have up to 4 parameters to Thumb assembly" msgstr "" -#: py/emitinlinextensa.c -msgid "can only have up to 4 parameters to Xtensa assembly" +#: py/emitinlinethumb.c +msgid "parameters must be registers in sequence r0 to r3" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "can only specify one unknown dimension" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects at most r%d" +msgstr "'%s' en fazla r%d bekler" -#: py/objtype.c -msgid "can't add special method to already-subclassed class" -msgstr "" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a register" +msgstr "'%s' bir yazmaç bekliyor" -#: py/compile.c -msgid "can't assign to expression" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects a special register" +msgstr "'%s' özel bir yazmaç bekliyor" -#: extmod/modasyncio.c -msgid "can't cancel self" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects an FPU register" +msgstr "'%s' bir FPU yazmacı bekliyor" -#: shared-module/adafruit_pixelbuf/PixelBuf.c -msgid "can't convert %q to %q" -msgstr "" +#: py/emitinlinethumb.c +#, c-format +msgid "'%s' expects {r0, r1, ...}" +msgstr "'%s' {r0, r1, ...} bekliyor" -#: py/obj.c +#: py/emitinlinethumb.c py/emitinlinextensa.c #, c-format -msgid "can't convert %s to complex" -msgstr "" +msgid "'%s' expects an integer" +msgstr "'%s' bir integer bekliyor" -#: py/obj.c +#: py/emitinlinethumb.c #, c-format -msgid "can't convert %s to float" -msgstr "" +msgid "'%s' integer 0x%x doesn't fit in mask 0x%x" +msgstr "'%s' integer 0x%x, 0x%x maskesine uymuyor" -#: py/objint.c py/runtime.c +#: py/emitinlinethumb.c #, c-format -msgid "can't convert %s to int" -msgstr "" +msgid "'%s' expects an address of the form [a, b]" +msgstr "'%s', [a, b] biçiminde bir adres bekliyor" -#: py/objstr.c -msgid "can't convert '%q' object to %q implicitly" -msgstr "" +#: py/emitinlinethumb.c py/emitinlinextensa.c +#, c-format +msgid "'%s' expects a label" +msgstr "'%s' bir etiket bekliyor" -#: extmod/ulab/code/numpy/vector.c -msgid "can't convert complex to float" +#: py/emitinlinethumb.c py/emitinlinextensa.c +msgid "label '%q' not defined" msgstr "" -#: py/obj.c -msgid "can't convert to complex" +#: py/emitinlinethumb.c +#, c-format +msgid "unsupported Thumb instruction '%s' with %d arguments" msgstr "" -#: py/obj.c -msgid "can't convert to float" +#: py/emitinlinethumb.c +msgid "branch not in range" msgstr "" -#: py/runtime.c -msgid "can't convert to int" +#: py/emitinlinextensa.c +msgid "can only have up to 4 parameters to Xtensa assembly" msgstr "" -#: py/objstr.c -msgid "can't convert to str implicitly" +#: py/emitinlinextensa.c +msgid "parameters must be registers in sequence a2 to a5" msgstr "" -#: py/compile.c -msgid "can't declare nonlocal in outer code" -msgstr "" +#: py/emitinlinextensa.c +#, c-format +msgid "'%s' integer %d isn't within range %d..%d" +msgstr "'%s' integer %d, %d..%d aralığında değil" -#: py/compile.c -msgid "can't delete expression" -msgstr "" +#: py/emitinlinextensa.c +#, c-format +msgid "%d is not a multiple of %d" +msgstr "%d %d'nin katı değil" -#: py/emitnative.c -msgid "can't do binary op between '%q' and '%q'" +#: py/emitinlinextensa.c +#, c-format +msgid "unsupported Xtensa instruction '%s' with %d arguments" msgstr "" #: py/emitnative.c -msgid "can't do unary op of '%q'" +msgid "conversion to object" msgstr "" #: py/emitnative.c -msgid "can't implicitly convert '%q' to 'bool'" -msgstr "" - -#: py/runtime.c -msgid "can't import name %q" +msgid "local '%q' used before type known" msgstr "" #: py/emitnative.c @@ -2691,24 +2772,8 @@ msgstr "" msgid "can't load with '%q' index" msgstr "" -#: py/builtinimport.c -msgid "can't perform relative import" -msgstr "" - -#: py/objgenerator.c -msgid "can't send non-None value to a just-started generator" -msgstr "" - -#: shared-module/sdcardio/SDCard.c -msgid "can't set 512 block size" -msgstr "" - -#: py/objexcept.c py/objnamedtuple.c -msgid "can't set attribute" -msgstr "" - -#: py/runtime.c -msgid "can't set attribute '%q'" +#: py/emitnative.c +msgid "local '%q' has type '%q' but source is '%q'" msgstr "" #: py/emitnative.c @@ -2723,66 +2788,52 @@ msgstr "" msgid "can't store with '%q' index" msgstr "" -#: py/objstr.c -msgid "" -"can't switch from automatic field numbering to manual field specification" -msgstr "" - -#: py/objstr.c -msgid "" -"can't switch from manual field specification to automatic field numbering" -msgstr "" - -#: py/objcomplex.c -msgid "can't truncate-divide a complex number" -msgstr "" - -#: extmod/modasyncio.c -msgid "can't wait" +#: py/emitnative.c +msgid "can't implicitly convert '%q' to 'bool'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot assign new shape" +#: py/emitnative.c +msgid "'not' not implemented" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "cannot cast output with casting rule" +#: py/emitnative.c +msgid "can't do unary op of '%q'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex to dtype" +#: py/emitnative.c +msgid "div/mod not implemented for uint" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot convert complex type" +#: py/emitnative.c +msgid "comparison of int and uint" msgstr "" -#: py/objtype.c -msgid "cannot create '%q' instances" +#: py/emitnative.c +msgid "binary op %q not implemented" msgstr "" -#: py/objtype.c -msgid "cannot create instance" +#: py/emitnative.c +msgid "can't do binary op between '%q' and '%q'" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot delete array elements" +#: py/emitnative.c +msgid "casting" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "cannot reshape array" +#: py/emitnative.c +msgid "return expected '%q' but got '%q'" msgstr "" #: py/emitnative.c -msgid "casting" +msgid "must raise an object" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "channel re-init" +#: py/emitnative.c +msgid "native yield" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "chars buffer too small" +#: py/lexer.c +msgid "unicode name escapes" msgstr "" #: py/modbuiltins.c @@ -2793,577 +2844,572 @@ msgstr "" msgid "chr() arg not in range(256)" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "clip point must be (x,y) tuple" -msgstr "" - -#: shared-bindings/msgpack/ExtType.c -msgid "code outside range 0~127" -msgstr "" - -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" -msgstr "" - -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a buffer, tuple, list, or int" -msgstr "" - -#: shared-bindings/displayio/Palette.c -msgid "color buffer must be a bytearray or array of type 'b' or 'B'" -msgstr "" - -#: shared-bindings/displayio/Palette.c -msgid "color must be between 0x000000 and 0xffffff" -msgstr "" - -#: py/emitnative.c -msgid "comparison of int and uint" -msgstr "" - -#: py/objcomplex.c -msgid "complex divide by zero" -msgstr "" - -#: py/objfloat.c py/parsenum.c -msgid "complex values not supported" +#: py/modbuiltins.c +msgid "arg is an empty sequence" msgstr "" -#: extmod/modzlib.c -msgid "compression header" +#: py/modbuiltins.c +msgid "ord expects a character" msgstr "" -#: py/emitnative.c -msgid "conversion to object" +#: py/modbuiltins.c +#, c-format +msgid "ord() expected a character, but string of length %d found" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be linear arrays" -msgstr "" +#: py/modbuiltins.c +msgid "3-arg pow() not supported" +msgstr "3-argümanlı pow() desteklenmemektedir" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must be ndarrays" +#: py/modbuiltins.c +msgid "must use keyword argument for key function" msgstr "" -#: extmod/ulab/code/numpy/filter.c -msgid "convolve arguments must not be empty" +#: py/moderrno.c +msgid "Operation not permitted" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "corrupted file" +#: py/moderrno.c +msgid "No such file/directory" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "could not invert Vandermonde matrix" -msgstr "" +#: py/moderrno.c +msgid "Input/output error" +msgstr "Giriş/çıkış hatası" -#: shared-module/sdcardio/SDCard.c -msgid "couldn't determine SD card version" +#: py/moderrno.c +msgid "Permission denied" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "cross is defined for 1D arrays of length 3" -msgstr "" +#: py/moderrno.c +msgid "File exists" +msgstr "Dosya var" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be iterable" +#: py/moderrno.c +msgid "No such device" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "data must be of equal length" +#: py/moderrno.c +msgid "No space left on device" msgstr "" -#: ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c -#, c-format -msgid "data pin #%d in use" +#: py/modmath.c shared-bindings/math/__init__.c +msgid "math domain error" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "data type not understood" +#: py/modmath.c +msgid "negative factorial" msgstr "" -#: py/parsenum.c -msgid "decimal numbers not supported" +#: py/modmicropython.c +msgid "schedule queue full" msgstr "" -#: py/compile.c -msgid "default 'except' must be last" +#: py/modstruct.c shared-module/struct/__init__.c +msgid "buffer too small" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "default is not a function" +#: py/modstruct.c +#, c-format +msgid "pack expected %d items for packing (got %d)" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "" -"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" +#: py/modthread.c +msgid "expecting a dict for keyword args" msgstr "" -#: shared-bindings/audiobusio/PDMIn.c -msgid "destination buffer must be an array of type 'H' for bit_depth = 16" +#: py/nativeglue.c +msgid "set unsupported" msgstr "" -#: py/objdict.c -msgid "dict update sequence has wrong length" +#: py/nativeglue.c +msgid "slice unsupported" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "diff argument must be an ndarray" +#: py/nativeglue.c +msgid "float unsupported" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "differentiation order out of range" +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c +msgid "can't convert %q to %q" msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "dimensions do not match" -msgstr "" +#: py/obj.c +msgid "During handling of the above exception, another exception occurred:" +msgstr "Yukarıdaki hatanın işlenmesi sırasında başka bir hata oluştu:" -#: py/emitnative.c -msgid "div/mod not implemented for uint" +#: py/obj.c +msgid "The above exception was the direct cause of the following exception:" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "divide by zero" -msgstr "" +#: py/obj.c +msgid " File \"%q\", line %d" +msgstr " \"%q\" dosyası, %d numaralı satır" -#: py/runtime.c -msgid "division by zero" -msgstr "" +#: py/obj.c +msgid " File \"%q\"" +msgstr " \"%q\" dosyası" -#: extmod/ulab/code/numpy/vector.c -msgid "dtype must be float, or complex" -msgstr "" +#: py/obj.c +msgid ", in %q\n" +msgstr ", içinde %q\n" -#: extmod/ulab/code/ndarray_operators.c -msgid "dtype of int32 is not supported" +#: py/obj.c +msgid "Traceback (most recent call last):\n" msgstr "" -#: py/objdeque.c -msgid "empty" +#: py/obj.c +msgid "can't convert to float" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "empty file" +#: py/obj.c +#, c-format +msgid "can't convert %s to float" msgstr "" -#: extmod/modasyncio.c extmod/modheapq.c -msgid "empty heap" +#: py/obj.c +msgid "can't convert to complex" msgstr "" -#: py/objstr.c -msgid "empty separator" +#: py/obj.c +#, c-format +msgid "can't convert %s to complex" msgstr "" -#: shared-bindings/random/__init__.c -msgid "empty sequence" +#: py/obj.c +msgid "expected tuple/list" msgstr "" -#: py/objstr.c -msgid "end of format while looking for conversion specifier" +#: py/obj.c +#, c-format +msgid "object '%s' isn't a tuple or list" msgstr "" -#: shared-bindings/alarm/time/TimeAlarm.c -msgid "epoch_time not supported on this board" +#: py/obj.c +msgid "tuple/list has wrong length" msgstr "" -#: ports/nordic/common-hal/busio/UART.c +#: py/obj.c #, c-format -msgid "error = 0x%08lX" +msgid "requested length %d but object has length %d" msgstr "" -#: py/runtime.c -msgid "exceptions must derive from BaseException" +#: py/obj.c +msgid "indices must be integers" msgstr "" -#: py/objstr.c -msgid "expected ':' after format specifier" -msgstr "" +#: py/obj.c +msgid "%q indices must be integers, not %s" +msgstr "%q indeksleri integer olmalı, %s değil" #: py/obj.c -msgid "expected tuple/list" +msgid "object has no len" msgstr "" -#: py/modthread.c -msgid "expecting a dict for keyword args" +#: py/obj.c +#, c-format +msgid "object of type '%s' has no len()" msgstr "" -#: py/compile.c -msgid "expecting an assembler instruction" +#: py/obj.c +msgid "object doesn't support item deletion" msgstr "" -#: py/compile.c -msgid "expecting just a value for set" -msgstr "" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item deletion" +msgstr "'%s' nesnesi, öğe silmeyi desteklemiyor" -#: py/compile.c -msgid "expecting key:value for dict" +#: py/obj.c +msgid "object isn't subscriptable" msgstr "" -#: shared-bindings/msgpack/__init__.c -msgid "ext_hook is not a function" -msgstr "" +#: py/obj.c +#, c-format +msgid "'%s' object isn't subscriptable" +msgstr "'%s' nesnesi subscriptable özelliğe sahip değil" -#: py/argcheck.c -msgid "extra keyword arguments given" +#: py/obj.c +msgid "object doesn't support item assignment" msgstr "" -#: py/argcheck.c -msgid "extra positional arguments given" -msgstr "" +#: py/obj.c +#, c-format +msgid "'%s' object doesn't support item assignment" +msgstr "'%s' nesnesi, öğe atamasını desteklemiyor" -#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c -#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c -#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c -msgid "file must be a file opened in byte mode" +#: py/obj.c +msgid "object with buffer protocol required" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "file write is not available" +#: py/objarray.c +msgid "bytes length not a multiple of item size" msgstr "" -#: shared-bindings/storage/__init__.c -msgid "filesystem must provide mount method" +#: py/objarray.c py/objstr.c +msgid "string argument without an encoding" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "first argument must be a callable" +#: py/objarray.c +msgid "memoryview: length is not a multiple of itemsize" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "first argument must be a function" +#: py/objarray.c py/objstr.c +msgid "substring not found" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "first argument must be a tuple of ndarrays" +#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "only slices with step=1 (aka None) are supported" msgstr "" -#: extmod/ulab/code/numpy/transform.c extmod/ulab/code/numpy/vector.c -msgid "first argument must be an ndarray" +#: py/objarray.c +msgid "lhs and rhs should be compatible" msgstr "" -#: py/objtype.c -msgid "first argument to super() must be type" +#: py/objarray.c shared-bindings/alarm/SleepMemory.c +#: shared-bindings/memorymap/AddressRange.c shared-bindings/nvm/ByteArray.c +msgid "array/bytes required on right side" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "first two arguments must be ndarrays" +#: py/objarray.c +msgid "memoryview offset too large" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "flattening order must be either 'C', or 'F'" +#: py/objcomplex.c +msgid "can't truncate-divide a complex number" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "flip argument must be an ndarray" +#: py/objcomplex.c +msgid "complex divide by zero" msgstr "" -#: py/objint.c -msgid "float too big" -msgstr "" +#: py/objcomplex.c +msgid "0.0 to a complex power" +msgstr "0.0'dan bir karmaşık güce" -#: py/nativeglue.c -msgid "float unsupported" +#: py/objdeque.c +msgid "full" msgstr "" -#: shared-bindings/_stage/Text.c -msgid "font must be 2048 bytes long" +#: py/objdeque.c +msgid "empty" msgstr "" -#: extmod/moddeflate.c -msgid "format" +#: py/objdict.c +msgid "dict update sequence has wrong length" msgstr "" -#: py/objstr.c -msgid "format requires a dict" +#: py/objexcept.c py/objnamedtuple.c +msgid "can't set attribute" msgstr "" -#: py/objdeque.c -msgid "full" +#: py/objfloat.c py/parsenum.c +msgid "complex values not supported" msgstr "" -#: py/argcheck.c -msgid "function doesn't take keyword arguments" +#: py/objgenerator.c +msgid "generator already executing" msgstr "" -#: py/argcheck.c -#, c-format -msgid "function expected at most %d arguments, got %d" +#: py/objgenerator.c +msgid "can't send non-None value to a just-started generator" msgstr "" -#: py/bc.c py/objnamedtuple.c -msgid "function got multiple values for argument '%q'" +#: py/objgenerator.c py/runtime.c +msgid "generator raised StopIteration" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "function has the same sign at the ends of interval" +#: py/objgenerator.c +msgid "generator ignored GeneratorExit" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "function is defined for ndarrays only" +#: py/objint.c py/runtime.c +#, c-format +msgid "can't convert %s to int" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "function is implemented for ndarrays only" +#: py/objint.c +msgid "float too big" msgstr "" -#: py/argcheck.c +#: py/objint.c #, c-format -msgid "function missing %d required positional arguments" +msgid "value must fit in %d byte(s)" msgstr "" -#: py/bc.c -msgid "function missing keyword-only argument" +#: py/objint.c shared-bindings/time/__init__.c +msgid "No long integer support" msgstr "" -#: py/bc.c -msgid "function missing required keyword argument '%q'" +#: py/objint.c py/sequence.c +msgid "small int overflow" msgstr "" -#: py/bc.c -#, c-format -msgid "function missing required positional argument #%d" -msgstr "" +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c +msgid "%q=%q" +msgstr "%q=%q" -#: py/argcheck.c py/bc.c py/objnamedtuple.c shared-bindings/_eve/__init__.c -#: shared-bindings/time/__init__.c -#, c-format -msgid "function takes %d positional arguments but %d were given" +#: py/objint_longlong.c py/parsenum.c +msgid "result overflows long long storage" msgstr "" -#: py/objgenerator.c -msgid "generator already executing" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative shift count" msgstr "" -#: py/objgenerator.c -msgid "generator ignored GeneratorExit" +#: py/objint_longlong.c py/objint_mpz.c py/runtime.c +msgid "negative power with no float support" msgstr "" -#: py/objgenerator.c py/runtime.c -msgid "generator raised StopIteration" +#: py/objint_longlong.c py/objint_mpz.c +msgid "overflow converting long int to machine word" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "graphic must be 2048 bytes long" +#: py/objint_mpz.c +msgid "pow() with 3 arguments requires integers" msgstr "" -#: extmod/modhashlib.c -msgid "hash is final" +#: py/objint_mpz.c +msgid "pow() 3rd argument cannot be 0" msgstr "" -#: extmod/modheapq.c -msgid "heap must be a list" +#: py/objobject.c +msgid "__new__ arg must be a user-type" msgstr "" -#: py/compile.c -msgid "identifier redefined as global" +#: py/objobject.c +msgid "arg must be user-type" msgstr "" -#: py/compile.c -msgid "identifier redefined as nonlocal" -msgstr "" +#: py/objrange.c py/objslice.c shared-bindings/random/__init__.c +msgid "%q step cannot be zero" +msgstr "%q sıfır olamaz" -#: py/compile.c -msgid "import * not at module level" -msgstr "" +#: py/objslice.c +msgid "Cannot subclass slice" +msgstr "Alt sınıf kesilemez" -#: py/persistentcode.c -msgid "incompatible .mpy arch" +#: py/objstr.c +msgid "bytes value out of range" msgstr "" -#: py/persistentcode.c -msgid "incompatible .mpy file" +#: py/objstr.c +msgid "join expects a list of str/bytes objects consistent with self object" msgstr "" #: py/objstr.c -msgid "incomplete format" +msgid "empty separator" msgstr "" #: py/objstr.c -msgid "incomplete format key" -msgstr "" +msgid "rsplit(None,n)" +msgstr "rsplit(None,n)" -#: extmod/modbinascii.c -msgid "incorrect padding" +#: py/objstr.c +msgid "bad format string" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/transform.c -msgid "index is out of bounds" +#: py/objstr.c +#, c-format +msgid "unmatched '%c' in format" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "index must be tuple or int" +#: py/objstr.c +msgid "bad conversion specifier" msgstr "" -#: extmod/ulab/code/numpy/numerical.c extmod/ulab/code/ulab_tools.c -#: ports/espressif/common-hal/pulseio/PulseIn.c -#: shared-bindings/bitmaptools/__init__.c -msgid "index out of range" +#: py/objstr.c +msgid "end of format while looking for conversion specifier" msgstr "" -#: py/obj.c -msgid "indices must be integers" +#: py/objstr.c +#, c-format +msgid "unknown conversion specifier %c" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "indices must be integers, slices, or Boolean lists" +#: py/objstr.c +msgid "expected ':' after format specifier" msgstr "" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" +#: py/objstr.c +msgid "" +"can't switch from automatic field numbering to manual field specification" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "initial values must be iterable" +#: py/objstr.c +msgid "%q index out of range" +msgstr "%q indeksi aralık dışında" + +#: py/objstr.c +msgid "attributes not supported" msgstr "" -#: shared-bindings/_bleio/Characteristic.c shared-bindings/_bleio/Descriptor.c -msgid "initial_value length is wrong" +#: py/objstr.c +msgid "" +"can't switch from manual field specification to automatic field numbering" msgstr "" -#: py/compile.c -msgid "inline assembler must be a function" +#: py/objstr.c +msgid "invalid format specifier" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output dimensions differ" +#: py/objstr.c +msgid "sign not allowed in string format specifier" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input and output shapes differ" +#: py/objstr.c +msgid "sign not allowed with integer format specifier 'c'" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input argument must be an integer, a tuple, or a list" +#: py/objstr.c +msgid "unknown format code '%c' for object of type '%q'" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "input array length must be power of 2" +#: py/objstr.c +msgid "'=' alignment not allowed in string format specifier" +msgstr "'=' hizalamasına string biçiminde izin verilmez" + +#: py/objstr.c +msgid "format needs a dict" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input arrays are not compatible" +#: py/objstr.c +msgid "incomplete format key" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input data must be an iterable" +#: py/objstr.c +msgid "incomplete format" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "input dtype must be float or complex" +#: py/objstr.c +msgid "format string needs more arguments" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input is not iterable" +#: py/objstr.c +#, c-format +msgid "%%c needs int or char" +msgstr "%%c int ya da char gerektirir" + +#: py/objstr.c +#, c-format +msgid "unsupported format character '%c' (0x%x) at index %d" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "input matrix is asymmetric" +#: py/objstr.c +msgid "format string didn't convert all arguments" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -#: extmod/ulab/code/scipy/linalg/linalg.c -msgid "input matrix is singular" +#: py/objstr.c +msgid "non-hex digit" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "input must be 1- or 2-d" +#: py/objstr.c +msgid "can't convert to str implicitly" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be a 1D ndarray" +#: py/objstr.c +msgid "can't convert '%q' object to %q implicitly" msgstr "" -#: extmod/ulab/code/scipy/linalg/linalg.c extmod/ulab/code/user/user.c -msgid "input must be a dense ndarray" +#: py/objstrunicode.c +#, c-format +msgid "string indices must be integers, not %s" msgstr "" -#: extmod/ulab/code/user/user.c shared-bindings/_eve/__init__.c -msgid "input must be an ndarray" +#: py/objstrunicode.c +msgid "string index out of range" msgstr "" -#: extmod/ulab/code/numpy/carray/carray.c -msgid "input must be an ndarray, or a scalar" +#: py/objtype.c +msgid "Call super().__init__() before accessing native object." +msgstr "Yerel nesneye erişmeden önce super().__init__() fonksiyonunu çağırın." + +#: py/objtype.c +msgid "__init__() should return None" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "input must be one-dimensional" +#: py/objtype.c +#, c-format +msgid "__init__() should return None, not '%s'" msgstr "" -#: extmod/ulab/code/ulab_tools.c -msgid "input must be square matrix" +#: py/objtype.c py/runtime.c +msgid "unreadable attribute" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "input must be tuple, list, range, or ndarray" +#: py/objtype.c py/runtime.c +msgid "object not callable" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "input vectors must be of equal length" +#: py/objtype.c py/runtime.c shared-module/atexit/__init__.c +msgid "'%q' object isn't callable" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "interp is defined for 1D iterables of equal length" +#: py/objtype.c +msgid "type takes 1 or 3 arguments" msgstr "" -#: shared-bindings/_bleio/Adapter.c -#, c-format -msgid "interval must be in range %s-%s" +#: py/objtype.c +msgid "can't create instance" msgstr "" -#: py/compile.c -msgid "invalid arch" +#: py/objtype.c +msgid "can't create '%q' instances" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" +#: py/objtype.c +msgid "can't add special method to already-subclassed class" +msgstr "" + +#: py/objtype.c +msgid "type isn't an acceptable base type" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid cert" +#: py/objtype.c +msgid "type '%q' isn't an acceptable base type" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element size %d for bits_per_pixel %d\n" +#: py/objtype.c +msgid "multiple inheritance not supported" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -#, c-format -msgid "invalid element_size %d, must be, 1, 2, or 4" +#: py/objtype.c +msgid "multiple bases have instance lay-out conflict" msgstr "" -#: shared-bindings/traceback/__init__.c -msgid "invalid exception" +#: py/objtype.c +msgid "first argument to super() must be type" msgstr "" -#: py/objstr.c -msgid "invalid format specifier" +#: py/objtype.c +msgid "issubclass() arg 2 must be a class or a tuple of classes" msgstr "" -#: shared-bindings/wifi/Radio.c -msgid "invalid hostname" +#: py/objtype.c +msgid "issubclass() arg 1 must be a class" msgstr "" -#: shared-module/ssl/SSLSocket.c -msgid "invalid key" +#: py/parse.c +msgid "not a constant" msgstr "" -#: py/compile.c -msgid "invalid micropython decorator" +#: py/parse.c +msgid "Unable to init parser" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c -msgid "invalid setting" +#: py/parse.c +msgid "unexpected indent" msgstr "" -#: shared-bindings/random/__init__.c -msgid "invalid step" +#: py/parse.c +msgid "unindent doesn't match any outer indent level" msgstr "" -#: py/compile.c py/parse.c -msgid "invalid syntax" +#: py/parse.c +msgid "malformed f-string" msgstr "" #: py/parsenum.c @@ -3379,109 +3425,110 @@ msgstr "" msgid "invalid syntax for number" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 1 must be a class" +#: py/parsenum.c +msgid "decimal numbers not supported" msgstr "" -#: py/objtype.c -msgid "issubclass() arg 2 must be a class or a tuple of classes" +#: py/persistentcode.c +msgid "incompatible .mpy file" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "iterations did not converge" +#: py/persistentcode.c +msgid "MicroPython .mpy file; use CircuitPython mpy-cross" msgstr "" -#: py/objstr.c -msgid "join expects a list of str/bytes objects consistent with self object" +#: py/persistentcode.c +msgid "native code in .mpy unsupported" msgstr "" -#: py/argcheck.c -msgid "keyword argument(s) not implemented - use normal args instead" +#: py/persistentcode.c +msgid "incompatible .mpy arch" msgstr "" -#: py/emitinlinethumb.c py/emitinlinextensa.c -msgid "label '%q' not defined" -msgstr "" +#: py/proto.c shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "'%q' object does not support '%q'" +msgstr "'%q' nesnesi '%q' öğesini desteklemiyor" -#: py/compile.c -msgid "label redefined" +#: py/qstr.c +msgid "name too long" msgstr "" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" +#: py/runtime.c +msgid "name not defined" msgstr "" -#: py/objarray.c -msgid "lhs and rhs should be compatible" +#: py/runtime.c +msgid "name '%q' isn't defined" msgstr "" -#: py/emitnative.c -msgid "local '%q' has type '%q' but source is '%q'" +#: py/runtime.c +msgid "unsupported type for operator" msgstr "" -#: py/emitnative.c -msgid "local '%q' used before type known" +#: py/runtime.c +msgid "unsupported type for %q: '%s'" msgstr "" -#: py/vm.c -msgid "local variable referenced before assignment" +#: py/runtime.c +msgid "unsupported types for %q: '%q', '%q'" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -msgid "loopback + silent mode not supported by peripheral" +#: py/runtime.c +msgid "wrong number of values to unpack" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS already initialized" +#: py/runtime.c +#, c-format +msgid "need more than %d values to unpack" msgstr "" -#: ports/espressif/common-hal/mdns/Server.c -#: ports/raspberrypi/common-hal/mdns/Server.c -msgid "mDNS only works with built-in WiFi" +#: py/runtime.c +#, c-format +msgid "too many values to unpack (expected %d)" msgstr "" -#: py/parse.c -msgid "malformed f-string" +#: py/runtime.c +msgid "type object '%q' has no attribute '%q'" msgstr "" -#: shared-bindings/_stage/Layer.c -msgid "map buffer too small" +#: py/runtime.c +msgid "module '%q' has no attribute '%q'" msgstr "" -#: py/modmath.c shared-bindings/math/__init__.c -msgid "math domain error" -msgstr "" +#: py/runtime.c +msgid "'%s' object has no attribute '%q'" +msgstr "'%s' nesnesinin '%q' özelliği yok" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "matrix is not positive definite" +#: py/runtime.c +msgid "can't set attribute '%q'" msgstr "" -#: ports/espressif/common-hal/_bleio/Descriptor.c -#: ports/nordic/common-hal/_bleio/Characteristic.c -#: ports/nordic/common-hal/_bleio/Descriptor.c -#, c-format -msgid "max_length must be 0-%d when fixed_length is %s" +#: py/runtime.c +msgid "object not iterable" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/random/random.c -msgid "maximum number of dimensions is " -msgstr "" +#: py/runtime.c +msgid "'%q' object isn't iterable" +msgstr "'%q' nesnesi iterable değildir" #: py/runtime.c -msgid "maximum recursion depth exceeded" +msgid "object not an iterator" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter must be > 0" +#: py/runtime.c +msgid "'%q' object isn't an iterator" +msgstr "'%q' nesnesi bir iteratör değildir" + +#: py/runtime.c +msgid "exceptions must derive from BaseException" msgstr "" -#: extmod/ulab/code/scipy/optimize/optimize.c -msgid "maxiter should be > 0" +#: py/runtime.c +msgid "can't import name %q" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "median argument must be an ndarray" +#: py/runtime.c +msgid "memory allocation failed, heap is locked" msgstr "" #: py/runtime.c @@ -3490,461 +3537,615 @@ msgid "memory allocation failed, allocating %u bytes" msgstr "" #: py/runtime.c -msgid "memory allocation failed, heap is locked" +msgid "can't convert to int" msgstr "" -#: py/objarray.c -msgid "memoryview offset too large" +#: py/runtime.c +msgid "division by zero" msgstr "" -#: py/objarray.c -msgid "memoryview: length is not a multiple of itemsize" +#: py/runtime.c +msgid "maximum recursion depth exceeded" msgstr "" -#: extmod/modtime.c -msgid "mktime needs a tuple of length 8 or 9" +#: py/sequence.c shared-bindings/displayio/Group.c +msgid "object not in sequence" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "mode must be complete, or reduced" +#: py/stream.c shared-bindings/getpass/__init__.c +msgid "stream operation not supported" msgstr "" -#: py/builtinimport.c -msgid "module not found" +#: py/vm.c +msgid "local variable referenced before assignment" msgstr "" -#: ports/espressif/common-hal/wifi/Monitor.c -msgid "monitor init failed" +#: py/vm.c +msgid "no active exception to reraise" msgstr "" -#: extmod/ulab/code/numpy/poly.c -msgid "more degrees of freedom than data points" +#: py/vm.c +msgid "opcode" msgstr "" -#: py/compile.c -msgid "multiple *x in assignment" +#: shared-bindings/_bleio/Adapter.c +msgid "Cannot create a new Adapter; use _bleio.adapter;" +msgstr "yeni Adaptör oluşturulamadı; _bleio.adapter kullanın;" + +#: shared-bindings/_bleio/Adapter.c +msgid "Could not set address" +msgstr "Adres ayarlanamadı" + +#: shared-bindings/_bleio/Adapter.c +#, c-format +msgid "interval must be in range %s-%s" msgstr "" -#: py/objtype.c -msgid "multiple bases have instance lay-out conflict" +#: shared-bindings/_bleio/Adapter.c +#, fuzzy +msgid "Cannot have scan responses for extended, connectable advertisements." +msgstr "Genişletilmiş, bağlanabilir reklamlar için tarama yanıtları yapılamaz." + +#: shared-bindings/_bleio/Adapter.c +msgid "Only connectable advertisements can be directed" msgstr "" -#: py/objtype.c -msgid "multiple inheritance not supported" +#: shared-bindings/_bleio/Adapter.c +msgid "non-zero timeout must be >= interval" msgstr "" -#: py/emitnative.c -msgid "must raise an object" +#: shared-bindings/_bleio/Adapter.c +msgid "window must be <= interval" msgstr "" -#: py/modbuiltins.c -msgid "must use keyword argument for key function" +#: shared-bindings/_bleio/Adapter.c +msgid "Prefix buffer must be on the heap" msgstr "" -#: py/runtime.c -msgid "name '%q' is not defined" +#: shared-bindings/_bleio/CharacteristicBuffer.c +msgid "CharacteristicBuffer writing not provided" +msgstr "CharacteristicBuffer yazılmı sağlanmadı" + +#: shared-bindings/_bleio/Connection.c +msgid "" +"Connection has been disconnected and can no longer be used. Create a new " +"connection." +msgstr "Bağlantı koparıldı ve tekrar kullanılamaz. Yeni bir bağlantı kurun." + +#: shared-bindings/_bleio/PacketBuffer.c +#, c-format +msgid "Buffer too short by %d bytes" +msgstr "Buffer bitten %d daha az" + +#: shared-bindings/_bleio/PacketBuffer.c +msgid "No connection: length cannot be determined" msgstr "" -#: py/runtime.c -msgid "name not defined" +#: shared-bindings/_bleio/UUID.c +msgid "UUID string not 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "UUID value is not str, int or byte buffer" +msgstr "" + +#: shared-bindings/_bleio/UUID.c +msgid "not a 128-bit UUID" +msgstr "" + +#: shared-bindings/_bleio/__init__.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c shared-module/bitmaptools/__init__.c +#: shared-module/displayio/Bitmap.c shared-module/displayio/Group.c +msgid "Read-only" msgstr "" -#: py/qstr.c -msgid "name too long" +#: shared-bindings/_pew/PewPew.c +msgid "Incorrect buffer size" +msgstr "Yanlış buffer size" + +#: shared-bindings/_pixelmap/PixelMap.c +msgid "nested index must be int" msgstr "" -#: py/persistentcode.c -msgid "native code in .mpy unsupported" +#: shared-bindings/_pixelmap/PixelMap.c +msgid "index must be tuple or int" msgstr "" -#: py/asmthumb.c -msgid "native method too big" +#: shared-bindings/_stage/Layer.c +msgid "map buffer too small" msgstr "" -#: py/emitnative.c -msgid "native yield" +#: shared-bindings/_stage/Text.c +msgid "chars buffer too small" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "ndarray length overflows" +#: shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +msgid "Pin is input only" msgstr "" -#: py/runtime.c +#: shared-bindings/adafruit_pixelbuf/PixelBuf.c +#: shared-module/_pixelmap/PixelMap.c #, c-format -msgid "need more than %d values to unpack" +msgid "Unmatched number of items on RHS (expected %d, got %d)." msgstr "" -#: py/modmath.c -msgid "negative factorial" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "Key must be 16, 24, or 32 bytes long" +msgstr "Anahtar 16, 24 veya 32 bayt uzunluğunda olmalıdır" -#: py/objint_longlong.c py/objint_mpz.c py/runtime.c -msgid "negative power with no float support" +#: shared-bindings/aesio/aes.c +msgid "Requested AES mode is unsupported" msgstr "" -#: py/objint_mpz.c py/runtime.c -msgid "negative shift count" +#: shared-bindings/aesio/aes.c +msgid "Source and destination buffers must be the same length" msgstr "" -#: shared-bindings/_pixelmap/PixelMap.c -msgid "nested index must be int" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "ECB only operates on 16 bytes at a time" +msgstr "ECB aynı anda yalnızca 16 baytla çalışır" -#: shared-module/sdcardio/SDCard.c -msgid "no SD card" -msgstr "" +#: shared-bindings/aesio/aes.c +msgid "CBC blocks must be multiples of 16 bytes" +msgstr "CBC blokları 16 baytın katları şeklinde olmalı" -#: py/vm.c -msgid "no active exception to reraise" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Slice and value different lengths." msgstr "" -#: py/compile.c -msgid "no binding for nonlocal found" +#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c +#: shared-bindings/nvm/ByteArray.c +msgid "Array values should be single bytes." +msgstr "Dizi değerleri tekil bytelar olmalıdır." + +#: shared-bindings/alarm/SleepMemory.c +msgid "Unable to write to sleep_memory." msgstr "" -#: shared-module/msgpack/__init__.c -msgid "no default packer" +#: shared-bindings/alarm/__init__.c +msgid "Expected a kind of %q" msgstr "" -#: extmod/modrandom.c extmod/ulab/code/numpy/random/random.c -msgid "no default seed" +#: shared-bindings/alarm/time/TimeAlarm.c shared-bindings/time/__init__.c +msgid "RTC is not supported on this board" msgstr "" -#: py/builtinimport.c -msgid "no module named '%q'" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Supply one of monotonic_time or epoch_time" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "no response from SD card" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "epoch_time not supported on this board" msgstr "" -#: ports/espressif/common-hal/espcamera/Camera.c py/objobject.c py/runtime.c -msgid "no such attribute" +#: shared-bindings/alarm/time/TimeAlarm.c +msgid "Time is in the past." msgstr "" -#: ports/espressif/common-hal/_bleio/Connection.c -#: ports/nordic/common-hal/_bleio/Connection.c -msgid "non-UUID found in service_uuids_whitelist" +#: shared-bindings/analogbufio/BufferedIn.c +msgid "%q must be a bytearray or array of type 'H' or 'B'" +msgstr "%q 'H' ya da 'B' tipi bir bytearray ya da array olmalıdır" + +#: shared-bindings/audiobusio/I2SOut.c shared-bindings/audioio/AudioOut.c +#: shared-bindings/audiopwmio/PWMAudioOut.c shared-bindings/mcp4822/MCP4822.c +#: shared-bindings/usb_audio/USBMicrophone.c +msgid "Not playing" msgstr "" -#: py/compile.c -msgid "non-default argument follows default argument" +#: shared-bindings/audiobusio/PDMIn.c +msgid "%q must be multiple of 8." +msgstr "%q 8'in katı olmalıdır." + +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Cannot record to a file" +msgstr "Dosyaya kayıt yapılamıyor" + +#: shared-bindings/audiobusio/PDMIn.c shared-bindings/audioi2sin/I2SIn.c +msgid "Destination capacity is smaller than destination_length." +msgstr "Hedef kapasitesi, hedef_uzunluğundan daha küçük." + +#: shared-bindings/audiobusio/PDMIn.c +msgid "destination buffer must be an array of type 'H' for bit_depth = 16" msgstr "" -#: py/objstr.c -msgid "non-hex digit found" +#: shared-bindings/audiobusio/PDMIn.c +msgid "" +"destination buffer must be a bytearray or array of type 'B' for bit_depth = 8" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "non-zero timeout must be > 0.01" +#: shared-bindings/audiocore/RawSample.c +msgid "%q must be a bytearray or array of type 'h', 'H', 'b', or 'B'" +msgstr "%q 'h', 'H', 'b' ya da 'B' tipi bir bytearray ya da array olmalı" + +#: shared-bindings/audiocore/RawSample.c +msgid "Length of %q must be an even multiple of channel_count * type_size" msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "non-zero timeout must be >= interval" +#: shared-bindings/audiocore/WaveFile.c shared-bindings/audiomp3/MP3Decoder.c +#: shared-bindings/displayio/OnDiskBitmap.c shared-bindings/gifio/OnDiskGif.c +#: shared-bindings/synthio/__init__.c shared-module/gifio/GifWriter.c +msgid "file must be a file opened in byte mode" msgstr "" -#: shared-bindings/_bleio/UUID.c -msgid "not a 128-bit UUID" +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/Flanger.c +#: shared-bindings/audiodelays/GranularPitchShift.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c +#: shared-bindings/audiomixer/Mixer.c +msgid "bits_per_sample must be 8 or 16" msgstr "" -#: py/parse.c -msgid "not a constant" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" msgstr "" -#: py/objstr.c -msgid "not all arguments converted during string formatting" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" msgstr "" -#: py/objstr.c -msgid "not enough arguments for format string" +#: shared-bindings/audioi2sin/I2SIn.c +#, c-format +msgid "invalid destination buffer, must be an array of type: %c" msgstr "" -#: extmod/ulab/code/numpy/carray/carray_tools.c -msgid "not implemented for complex dtype" +#: shared-bindings/audioio/AudioOut.c +msgid "%q and %q must be different" +msgstr "%q ve %q farklı olmalılar" + +#: shared-bindings/bitmapfilter/__init__.c +msgid "" +"weights must be a sequence with an odd square number of elements (usually 9 " +"or 25)" msgstr "" -#: extmod/ulab/code/numpy/bitwise.c -msgid "not supported for input types" +#: shared-bindings/bitmapfilter/__init__.c +msgid "weights must be an object of type %q, %q, %q, or %q, not %q " msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "number of points must be at least 2" +#: shared-bindings/bitmaptools/__init__.c +msgid "clip point must be (x,y) tuple" msgstr "" -#: py/builtinhelp.c -msgid "object " +#: shared-bindings/bitmaptools/__init__.c +msgid "source palette too large" msgstr "" -#: py/obj.c -#, c-format -msgid "object '%s' isn't a tuple or list" +#: shared-bindings/bitmaptools/__init__.c +msgid "Bitmap size and bits per value must match" +msgstr "Bitmap boyutu ve bit başına değer uyuşmalı" + +#: shared-bindings/bitmaptools/__init__.c +msgid "For L8 colorspace, input bitmap must have 8 bits per pixel" msgstr "" +"L8 renk uzayı için, giriş bitmap'i piksel başına 8 bayta sahip olmalıdır" -#: py/obj.c -msgid "object doesn't support item assignment" +#: shared-bindings/bitmaptools/__init__.c +msgid "For RGB colorspaces, input bitmap must have 16 bits per pixel" msgstr "" +"RGB renk uzayı için, giriş bitmap'i piksel başına 16 bayta sahip olmalıdır" -#: py/obj.c -msgid "object doesn't support item deletion" +#: shared-bindings/bitmaptools/__init__.c +msgid "Unsupported colorspace" msgstr "" -#: py/obj.c -msgid "object has no len" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap size must match the other bitmaps" msgstr "" -#: py/obj.c -msgid "object isn't subscriptable" +#: shared-bindings/bitmaptools/__init__.c +msgid "Mask bitmap must have 8 bits per pixel" msgstr "" -#: py/runtime.c -msgid "object not an iterator" +#: shared-bindings/bitmaptools/__init__.c +msgid "out of range of target" msgstr "" -#: py/objtype.c py/runtime.c -msgid "object not callable" +#: shared-bindings/bitmaptools/__init__.c +msgid "value out of range of target" msgstr "" -#: py/sequence.c shared-bindings/displayio/Group.c -msgid "object not in sequence" +#: shared-bindings/bitmaptools/__init__.c +msgid "background value out of range of target" msgstr "" -#: py/runtime.c -msgid "object not iterable" +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays types have different sizes" +msgstr "Kordinat dizilerinin türlerifarklı boyutlara sahip" + +#: shared-bindings/bitmaptools/__init__.c +msgid "Coordinate arrays have different lengths" +msgstr "Kordinat dizilerinin uzunlukları farklı" + +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid element_size %d, must be, 1, 2, or 4" msgstr "" -#: py/obj.c +#: shared-bindings/bitmaptools/__init__.c #, c-format -msgid "object of type '%s' has no len()" +msgid "invalid element size %d for bits_per_pixel %d\n" msgstr "" -#: py/obj.c -msgid "object with buffer protocol required" +#: shared-bindings/bitmaptools/__init__.c +#, c-format +msgid "invalid bits_per_pixel %d, must be, 1, 2, 4, 8, 16, 24, or 32" msgstr "" -#: py/objstr.c -msgid "odd-length string" +#: shared-bindings/bitmaptools/__init__.c +msgid "bitmap sizes must match" msgstr "" -#: supervisor/shared/web_workflow/web_workflow.c -msgid "off" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 2 or 65536" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "offset is too large" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 65536" msgstr "" -#: shared-bindings/dualbank/__init__.c -msgid "offset must be >= 0" +#: shared-bindings/bitmaptools/__init__.c +msgid "source_bitmap must have value_count of 8" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "offset must be non-negative and no greater than buffer length" +#: shared-bindings/bitmaptools/__init__.c +msgid "unsupported colorspace for dither" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only bit_depth=16 is supported" +#: shared-bindings/bitops/__init__.c +#, c-format +msgid "Input buffer length (%d) must be a multiple of the strand count (%d)" +msgstr "Giriş buffer uzunluğu (%d) strand sayımının (%d) katı olmalıdır" + +#: shared-bindings/board/__init__.c +msgid "No default %q bus" msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only mono is supported" +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/epaperdisplay/EPaperDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +#: shared-bindings/mipidsi/Display.c +msgid "Display rotation must be in 90 degree increments" +msgstr "Ekran dönüşü 90 derecelik artışlarla olmalıdır" + +#: shared-bindings/busdisplay/BusDisplay.c +msgid "%q must be 1 when %q is True" +msgstr "%q 1 olmalı, %q True olduğu zaman" + +#: shared-bindings/busdisplay/BusDisplay.c +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Display must have a 16 bit colorspace." +msgstr "Ekran 16 bitlik bir renk uzayına sahip olmalıdır." + +#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c +msgid "tx and rx cannot both be None" msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "only ndarrays can be concatenated" +#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +msgid "Must be a %q subclass." msgstr "" -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only oversample=64 is supported" +#: shared-bindings/canio/RemoteTransmissionRequest.c +msgid "RemoteTransmissionRequests limited to 8 bytes" msgstr "" -#: ports/nordic/common-hal/audiobusio/PDMIn.c -#: ports/stm/common-hal/audiobusio/PDMIn.c -msgid "only sample_rate=16000 is supported" -msgstr "" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Cannot set value when direction is input." +msgstr "Yön, giriş olduğunda değer ayarlanamıyor." -#: py/objarray.c py/objstr.c py/objstrunicode.c py/objtuple.c -#: shared-bindings/alarm/SleepMemory.c shared-bindings/memorymap/AddressRange.c -#: shared-bindings/nvm/ByteArray.c -msgid "only slices with step=1 (aka None) are supported" -msgstr "" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Drive mode not used when direction is input." +msgstr "Yön, giriş olduğunda sürüş modu kullanılmaz." -#: py/vm.c -msgid "opcode" +#: shared-bindings/digitalio/DigitalInOut.c +#: shared-bindings/i2cioexpander/IOPin.c +msgid "Pull not used when direction is output." msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/bitwise.c -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/vector.c -msgid "operands could not be broadcast together" -msgstr "" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' method" +msgstr "%q nesnesinde '%q' metodu eksik" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for 2D arrays only" +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "%q object missing '%q' attribute" +msgstr "%q nesnesinde '%q' niteliği eksik" + +#: shared-bindings/digitalio/DigitalInOutProtocol.c +msgid "object does not support DigitalInOut protocol" msgstr "" -#: extmod/ulab/code/numpy/linalg/linalg.c -msgid "operation is defined for ndarrays only" +#: shared-bindings/displayio/Bitmap.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +msgid "Cannot delete values" +msgstr "Değerler silinemez" + +#: shared-bindings/displayio/Bitmap.c shared-bindings/displayio/Group.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/memorymonitor/AllocationSize.c +#: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +msgid "Slices not supported" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is implemented for 1D Boolean arrays only" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a bytearray or array of type 'b' or 'B'" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "operation is not implemented on ndarrays" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be 3 bytes (RGB) or 4 bytes (RGB + pad byte)" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "operation is not supported for given type" +#: shared-bindings/displayio/Palette.c +msgid "color must be between 0x000000 and 0xffffff" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "operation not supported for the input types" +#: shared-bindings/displayio/Palette.c +msgid "color buffer must be a buffer, tuple, list, or int" msgstr "" -#: py/modbuiltins.c -msgid "ord expects a character" +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c +msgid "unsupported %q type" msgstr "" -#: py/modbuiltins.c -#, c-format -msgid "ord() expected a character, but string of length %d found" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile width must exactly divide bitmap width" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out array is too small" +#: shared-bindings/displayio/TileGrid.c +msgid "Tile height must exactly divide bitmap height" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "out has wrong type" +#: shared-bindings/displayio/TileGrid.c +msgid "New bitmap must be same size as old bitmap" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for complex dtype" +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c +msgid "Tile index out of bounds" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out keyword is not supported for function" +#: shared-bindings/dualbank/__init__.c +msgid "offset must be >= 0" msgstr "" -#: extmod/ulab/code/utils/utils.c -msgid "out must be a float dense array" +#: shared-bindings/epaperdisplay/EPaperDisplay.c +msgid "Refresh too soon" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be an ndarray" +#: shared-bindings/framebufferio/FramebufferDisplay.c +msgid "Buffer is not a bytearray." +msgstr "Buffer bir bytearray değil." + +#: shared-bindings/gnss/GNSS.c +msgid "System entry must be gnss.SatelliteSystem" msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "out must be of float dtype" +#: shared-bindings/hashlib/__init__.c +msgid "Unsupported hash algorithm" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "out of range of target" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "address out of range" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array has wrong type" +#: shared-bindings/i2cioexpander/IOExpander.c +msgid "num_pins must be 8 or 16" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "output array must be contiguous" +#: shared-bindings/i2ctarget/I2CTarget.c +msgid "addresses is empty" msgstr "" -#: py/objint_mpz.c -msgid "overflow converting long int to machine word" +#: shared-bindings/ipaddress/IPv4Address.c shared-bindings/ipaddress/__init__.c +msgid "Not a valid IP string" msgstr "" -#: py/modstruct.c +#: shared-bindings/ipaddress/IPv4Address.c #, c-format -msgid "pack expected %d items for packing (got %d)" -msgstr "" +msgid "Address must be %d bytes long" +msgstr "Adres %d byte uzunluğunda olmalıdır" -#: shared-bindings/_stage/Layer.c shared-bindings/_stage/Text.c -msgid "palette must be 32 bytes long" +#: shared-bindings/ipaddress/__init__.c +msgid "Only int or string supported for ip" msgstr "" -#: py/emitinlinextensa.c -msgid "parameters must be registers in sequence a2 to a5" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "width must be greater than zero" msgstr "" -#: py/emitinlinethumb.c -msgid "parameters must be registers in sequence r0 to r3" +#: shared-bindings/is31fl3741/FrameBuffer.c +msgid "Scale dimensions must divide by 3" msgstr "" -#: extmod/vfs_posix_file.c -msgid "poll on file not available on win32" -msgstr "" +#: shared-bindings/is31fl3741/IS31FL3741.c +msgid "Mapping must be a tuple" +msgstr "Map tuple olmalıdır" -#: ports/espressif/common-hal/pulseio/PulseIn.c -msgid "pop from an empty PulseIn" -msgstr "" +#: shared-bindings/jpegio/JpegDecoder.c +msgid "%q must be of type %q, %q, or %q, not %q" +msgstr "%q; %q, %q veya %q tipi olmalıdır, %q değil" -#: ports/atmel-samd/common-hal/pulseio/PulseIn.c -#: ports/cxd56/common-hal/pulseio/PulseIn.c -#: ports/nordic/common-hal/pulseio/PulseIn.c -#: ports/raspberrypi/common-hal/pulseio/PulseIn.c -#: ports/stm/common-hal/pulseio/PulseIn.c py/objdict.c py/objlist.c py/objset.c -#: shared-bindings/ps2io/Ps2.c -msgid "pop from empty %q" +#: shared-bindings/mdns/Server.c +msgid "" +"Failed to add service TXT record; non-string or bytes found in txt_records" msgstr "" -#: shared-bindings/socketpool/Socket.c -msgid "port must be >= 0" -msgstr "" +#: shared-bindings/memorymap/AddressRange.c +msgid "Address range wraps around" +msgstr "Adres aralığı başa döner" -#: py/compile.c -msgid "positional arg after **" -msgstr "" +#: shared-bindings/microcontroller/Pin.c +msgid "%q contains duplicate pins" +msgstr "%q yinelenen pinler içeriyor" -#: py/compile.c -msgid "positional arg after keyword arg" +#: shared-bindings/microcontroller/Pin.c +msgid "%q and %q contain duplicate pins" +msgstr "%q ve %q yinelenen pinler içeriyor" + +#: shared-bindings/msgpack/ExtType.c +msgid "code outside range 0~127" msgstr "" -#: py/objint_mpz.c -msgid "pow() 3rd argument cannot be 0" +#: shared-bindings/msgpack/__init__.c +msgid "default is not a function" msgstr "" -#: py/objint_mpz.c -msgid "pow() with 3 arguments requires integers" +#: shared-bindings/msgpack/__init__.c +msgid "ext_hook is not a function" msgstr "" -#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c -msgid "pull masks conflict with direction masks" +#: shared-bindings/nvm/ByteArray.c +msgid "Unable to write to nvm." msgstr "" -#: py/parse.c -msgid "raw f-strings are not supported" +#: shared-bindings/os/__init__.c +msgid "No hardware random available" msgstr "" -#: extmod/ulab/code/numpy/fft/fft_tools.c -msgid "real and imaginary parts must be of equal length" +#: shared-bindings/paralleldisplaybus/ParallelBus.c +msgid "Specify exactly one of data0 or data_pins" msgstr "" -#: py/builtinimport.c -msgid "relative import" +#: shared-bindings/ps2io/Ps2.c +msgid "Failed sending command." +msgstr "Komut gönderilemedi." + +#: shared-bindings/pulseio/PulseOut.c +msgid "Array must contain halfwords (type 'H')" +msgstr "Dizi yarımsözcüklere sahip olmalıdır (tip 'H')" + +#: shared-bindings/pwmio/PWMOut.c +msgid "Conflicting settings for shared resource" msgstr "" -#: py/obj.c -#, c-format -msgid "requested length %d but object has length %d" +#: shared-bindings/random/__init__.c +msgid "stop not reachable from start" msgstr "" -#: extmod/ulab/code/ndarray_operators.c -msgid "results cannot be cast to specified type" +#: shared-bindings/random/__init__.c +msgid "invalid step" msgstr "" -#: py/compile.c -msgid "return annotation must be an identifier" +#: shared-bindings/random/__init__.c +msgid "empty sequence" msgstr "" -#: py/emitnative.c -msgid "return expected '%q' but got '%q'" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c -#, c-format -msgid "rgb_pins[%d] duplicates another pin assignment" +msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "" #: shared-bindings/rgbmatrix/RGBMatrix.c @@ -3952,444 +4153,570 @@ msgstr "" msgid "rgb_pins[%d] is not on the same port as clock" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "roll argument must be an ndarray" -msgstr "" - -#: py/objstr.c -msgid "rsplit(None,n)" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "rgb_pins[%d] duplicates another pin assignment" msgstr "" -#: ports/atmel-samd/common-hal/audiobusio/PDMIn.c -#: ports/raspberrypi/common-hal/audiobusio/PDMIn.c -msgid "sampling rate out of range" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"Pinout uses %d bytes per element, which consumes more than the ideal %d " +"bytes. If this cannot be avoided, pass allow_inefficient=True to the " +"constructor" msgstr "" -#: py/modmicropython.c -msgid "schedule queue full" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Must use a multiple of 6 rgb pins, not %d" msgstr "" -#: py/builtinimport.c -msgid "script compilation not supported" +#: shared-bindings/rgbmatrix/RGBMatrix.c +#, c-format +msgid "" +"%d address pins, %d rgb pins and %d tiles indicate a height of %d, not %d" msgstr "" +"%d adres pinleri, %d RGB pinleri ve %d döşemeleri %d'nin yüksekliği " +"gösterir, %d'nin değil" -#: py/nativeglue.c -msgid "set unsupported" +#: shared-bindings/socketpool/Socket.c +msgid "port must be >= 0" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "shape must be None, and integer or a tuple of integers" +#: shared-bindings/socketpool/Socket.c shared-bindings/ssl/SSLSocket.c +msgid "buffer too small for requested bytes" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "shape must be integer or tuple of integers" +#: shared-bindings/socketpool/SocketPool.c +msgid "Name or service not known" msgstr "" -#: shared-module/msgpack/__init__.c -msgid "short read" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." msgstr "" -#: py/objstr.c -msgid "sign not allowed in string format specifier" +#: shared-bindings/ssl/SSLContext.c +msgid "Server side context cannot have hostname" msgstr "" -#: py/objstr.c -msgid "sign not allowed with integer format specifier 'c'" -msgstr "" +#: shared-bindings/storage/__init__.c shared-bindings/usb_audio/__init__.c +#: shared-bindings/usb_cdc/__init__.c shared-bindings/usb_hid/__init__.c +#: shared-bindings/usb_midi/__init__.c shared-bindings/usb_video/__init__.c +msgid "Cannot change USB devices now" +msgstr "USB aygıtları şu an değiştirilemez" -#: extmod/ulab/code/ulab_tools.c -msgid "size is defined for ndarrays only" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c +msgid "File not found" msgstr "" -#: extmod/ulab/code/numpy/random/random.c -msgid "size must match out.shape when used together" +#: shared-bindings/time/__init__.c +msgid "timestamp out of range for platform time_t" msgstr "" -#: py/nativeglue.c -msgid "slice unsupported" +#: shared-bindings/traceback/__init__.c +msgid "Supply both or neither of %q and %q" msgstr "" -#: py/objint.c py/sequence.c -msgid "small int overflow" +#: shared-bindings/traceback/__init__.c +msgid "file write is not available" msgstr "" -#: main.c -msgid "soft reboot\n" +#: shared-bindings/traceback/__init__.c +msgid "invalid exception" msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "sort argument must be an ndarray" +#: shared-bindings/usb_audio/USBSpeaker.c +msgid "destination must be an array of type 'h'" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos array must be of shape (n_section, 6)" -msgstr "" +#: shared-bindings/usb_audio/__init__.c +msgid "At least one of microphone and speaker must be enabled" +msgstr "Mikrofon veya hoparlörden en az biri etkinleştirilmiş olmalı" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sos[:, 3] should be all ones" -msgstr "" +#: shared-bindings/usb_hid/Device.c +msgid "%q, %q, and %q must all be the same length" +msgstr "%q, %q ve %q aynı uzunlukta olmalıdır" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "sosfilt requires iterable arguments" +#: shared-bindings/util.c +msgid "" +"Object has been deinitialized and can no longer be used. Create a new object." msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source palette too large" -msgstr "" +#: shared-bindings/warnings/__init__.c +msgid "%q must be a subclass of %q" +msgstr "%q, %q'nün alt türü olmalıdır" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 2 or 65536" -msgstr "" +#: shared-bindings/wifi/Monitor.c +msgid "%q out of bounds" +msgstr "%q sınırların dışında" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 65536" +#: shared-bindings/wifi/Radio.c +msgid "Invalid hex password" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "source_bitmap must have value_count of 8" +#: shared-bindings/wifi/Radio.c +msgid "invalid hostname" msgstr "" -#: extmod/modre.c -msgid "splitting with sub-captures" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "Invalid MAC address" +msgstr "Geçersiz MAC adresi" -#: py/objstr.c -msgid "start/end indices" -msgstr "" +#: shared-bindings/wifi/Radio.c +msgid "AuthMode.OPEN is not used with password" +msgstr "AuthMode.OPEN bir şifre ile kullanılmadı" -#: shared-bindings/random/__init__.c -msgid "stop not reachable from start" +#: shared-bindings/wifi/Radio.c +msgid "Invalid BSSID" +msgstr "Geçersiz BSSID" + +#: shared-bindings/wifi/Radio.c supervisor/shared/web_workflow/web_workflow.c +msgid "Authentication failure" +msgstr "Kimlik doğrulama hatası" + +#: shared-bindings/wifi/Radio.c +msgid "No network with that ssid" msgstr "" -#: py/stream.c shared-bindings/getpass/__init__.c -msgid "stream operation not supported" +#: shared-bindings/wifi/Radio.c +#, c-format +msgid "Unknown failure %d" msgstr "" -#: py/objarray.c py/objstr.c -msgid "string argument without an encoding" +#: shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +#, c-format +msgid "No I2C device at address: 0x%x" msgstr "" -#: py/objstrunicode.c -msgid "string index out of range" +#: shared-module/audiocore/WaveFile.c +msgid "Invalid format chunk size" +msgstr "Geçersiz biçim yığın boyutu" + +#: shared-module/audiocore/__init__.c shared-module/usb_audio/USBMicrophone.c +msgid "The sample's %q does not match" msgstr "" -#: py/objstrunicode.c -#, c-format -msgid "string indices must be integers, not %s" +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q'nün içindeki %q, %q veya %q tipi olmalıdır, %q değil" + +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "Only 8/16-bit mono/stereo is supported" msgstr "" -#: py/objarray.c py/objstr.c -msgid "substring not found" +#: shared-module/audiofilewriter/AudioFileWriter.c +msgid "buffer_size too small for source" msgstr "" -#: py/compile.c -msgid "super() can't find self" +#: shared-module/audiomp3/MP3Decoder.c +msgid "Couldn't allocate decoder" +msgstr "Deşifre edici tahsis edilemedi" + +#: shared-module/audiomp3/MP3Decoder.c +msgid "Failed to parse MP3 file" +msgstr "MP3 dosyası ayrıştırılamadı" + +#: shared-module/bitbangio/I2C.c +msgid "%q too long" +msgstr "%q çok uzun" + +#: shared-module/bitmapfilter/__init__.c +msgid "bitmap size and depth must match" msgstr "" -#: extmod/modjson.c -msgid "syntax error in JSON" +#: shared-module/bitmapfilter/__init__.c +msgid "unsupported bitmap depth" msgstr "" -#: extmod/modtime.c -msgid "ticks interval overflow" +#: shared-module/displayio/Bitmap.c +#, fuzzy +msgid "Invalid bits per value" +msgstr "Geçersiz bit başına değer" + +#: shared-module/displayio/ColorConverter.c +msgid "Only one color can be transparent at a time" msgstr "" -#: ports/nordic/common-hal/watchdog/WatchDogTimer.c -msgid "timeout duration exceeded the maximum supported value" +#: shared-module/displayio/Group.c +msgid "Layer already in a group" +msgstr "Katman zaten bir grupta" + +#: shared-module/displayio/Group.c +msgid "Layer must be a Group or TileGrid subclass" +msgstr "Katman, bir Grup ya da TileGrid alt sınıfı olmalıdır" + +#: shared-module/displayio/OnDiskBitmap.c +#, c-format +msgid "" +"Only Windows format, uncompressed BMP supported: given header size is %d" msgstr "" -#: ports/nordic/common-hal/_bleio/Adapter.c -msgid "timeout must be < 655.35 secs" +#: shared-module/displayio/OnDiskBitmap.c +msgid "RLE-compressed BMP not supported" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -msgid "timeout waiting for flux" +#: shared-module/displayio/OnDiskBitmap.c +msgid "Unable to read color palette data" msgstr "" -#: ports/raspberrypi/common-hal/floppyio/__init__.c -#: shared-module/floppyio/__init__.c -msgid "timeout waiting for index pulse" +#: shared-module/displayio/__init__.c +msgid "Too many displays" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v1 card" +#: shared-module/displayio/__init__.c +msgid "Too many display busses; forgot displayio.release_displays() ?" msgstr "" -#: shared-module/sdcardio/SDCard.c -msgid "timeout waiting for v2 card" +#: shared-module/displayio/bus_core.c +msgid "Unsupported display bus type" msgstr "" -#: ports/stm/common-hal/pwmio/PWMOut.c -msgid "timer re-init" +#: shared-module/gifio/GifWriter.c +msgid "unsupported colorspace for GifWriter" msgstr "" -#: shared-bindings/time/__init__.c -msgid "timestamp out of range for platform time_t" +#: shared-module/i2cdisplaybus/I2CDisplayBus.c +#: shared-module/is31fl3741/IS31FL3741.c +#, c-format +msgid "Unable to find I2C Display at %x" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "tobytes can be invoked for dense arrays only" +#: shared-module/i2cioexpander/IOExpander.c +msgid "Cannot deinitialize board IOExpander" +msgstr "Kart IOExpander'ı devreden çıkarılamıyor" + +#: shared-module/imagecapture/ParallelImageCapture.c +msgid "This microcontroller does not support continuous capture." msgstr "" -#: py/compile.c -msgid "too many args" +#: shared-module/is31fl3741/FrameBuffer.c +msgid "LED mappings must match display size" +msgstr "LED eşlemeleri ekran boyutuyla eşleşmelidir" + +#: shared-module/jpegio/JpegDecoder.c +msgid "Interrupted by output function" msgstr "" -#: extmod/ulab/code/ndarray.c extmod/ulab/code/numpy/create.c -msgid "too many dimensions" +#: shared-module/jpegio/JpegDecoder.c +msgid "Device error or wrong termination of input stream" msgstr "" -#: extmod/ulab/code/ndarray.c -msgid "too many indices" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient memory pool for the image" msgstr "" -#: py/asmthumb.c -msgid "too many locals for native method" +#: shared-module/jpegio/JpegDecoder.c +msgid "Insufficient stream input buffer" msgstr "" -#: py/runtime.c -#, c-format -msgid "too many values to unpack (expected %d)" +#: shared-module/jpegio/JpegDecoder.c +msgid "Parameter error" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D arrays of equal length" +#: shared-module/jpegio/JpegDecoder.c +msgid "Data format error (may be broken data)" +msgstr "Veri formatı hatası (bozuk veri olabilir)" + +#: shared-module/jpegio/JpegDecoder.c +msgid "Right format but not supported" msgstr "" -#: extmod/ulab/code/numpy/approx.c -msgid "trapz is defined for 1D iterables" +#: shared-module/jpegio/JpegDecoder.c +msgid "Unsupported JPEG (may be progressive)" msgstr "" -#: py/obj.c -msgid "tuple/list has wrong length" +#: shared-module/jpegio/JpegDecoder.c +msgid "%q() without %q()" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c +#: shared-module/memorymonitor/AllocationAlarm.c #, c-format -msgid "twai_driver_install returned esp-idf error #%d" +msgid "Attempt to allocate %d blocks" +msgstr "%d bloğun ayrılması girişimi" + +#: shared-module/msgpack/__init__.c +msgid "short read" msgstr "" -#: ports/espressif/common-hal/canio/CAN.c -#, c-format -msgid "twai_start returned esp-idf error #%d" +#: shared-module/msgpack/__init__.c +msgid "no default packer" msgstr "" -#: shared-bindings/busio/UART.c shared-bindings/canio/CAN.c -msgid "tx and rx cannot both be None" +#: shared-module/msgpack/__init__.c supervisor/shared/settings.c +msgid "Invalid format" msgstr "" -#: py/objtype.c -msgid "type '%q' is not an acceptable base type" +#: shared-module/paralleldisplaybus/ParallelBus.c +msgid "" +"This microcontroller only supports data0=, not data_pins=, because it " +"requires contiguous pins." msgstr "" -#: py/objtype.c -msgid "type is not an acceptable base type" +#: shared-module/rgbmatrix/RGBMatrix.c +msgid "No timer available" msgstr "" -#: py/runtime.c -msgid "type object '%q' has no attribute '%q'" -msgstr "" +#: shared-module/rgbmatrix/RGBMatrix.c +#, c-format +msgid "Internal error #%d" +msgstr "Dahili hata #%d" -#: py/objtype.c -msgid "type takes 1 or 3 arguments" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v1 card" msgstr "" -#: py/objint_longlong.c -msgid "ulonglong too large" +#: shared-module/sdcardio/SDCard.c +msgid "timeout waiting for v2 card" msgstr "" -#: py/parse.c -msgid "unexpected indent" +#: shared-module/sdcardio/SDCard.c +msgid "no SD card" msgstr "" -#: py/bc.c -msgid "unexpected keyword argument" +#: shared-module/sdcardio/SDCard.c +msgid "couldn't determine SD card version" msgstr "" -#: py/argcheck.c py/bc.c py/objnamedtuple.c -#: shared-bindings/traceback/__init__.c -msgid "unexpected keyword argument '%q'" +#: shared-module/sdcardio/SDCard.c +msgid "no response from SD card" msgstr "" -#: py/lexer.c -msgid "unicode name escapes" +#: shared-module/sdcardio/SDCard.c +msgid "SD card CSD format not supported" msgstr "" -#: py/parse.c -msgid "unindent doesn't match any outer indent level" +#: shared-module/sdcardio/SDCard.c +msgid "can't set 512 block size" msgstr "" -#: py/objstr.c -#, c-format -msgid "unknown conversion specifier %c" -msgstr "" +#: shared-module/ssl/SSLSocket.c +msgid "Invalid socket for TLS" +msgstr "TLS için geçersiz soket" -#: py/objstr.c -msgid "unknown format code '%c' for object of type '%q'" +#: shared-module/ssl/SSLSocket.c +msgid "invalid key" msgstr "" -#: py/compile.c -msgid "unknown type" +#: shared-module/ssl/SSLSocket.c +msgid "invalid cert" msgstr "" -#: py/compile.c -msgid "unknown type '%q'" +#: shared-module/storage/__init__.c +msgid "Mount point directory missing" msgstr "" -#: py/objstr.c -#, c-format -msgid "unmatched '%c' in format" -msgstr "" +#: shared-module/storage/__init__.c +msgid "Cannot remount path when visible via USB." +msgstr "USB üzerinden görünür durumdayken yol yeniden bağlanamaz." -#: py/objtype.c py/runtime.c -msgid "unreadable attribute" -msgstr "" +#: shared-module/struct/__init__.c +msgid "'S' and 'O' are not supported format types" +msgstr "'S' ve 'O' desteklenen biçim türlerinden değildir" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c -msgid "unsupported %q type" +#: shared-module/struct/__init__.c +msgid "buffer size must match format" msgstr "" -#: py/emitinlinethumb.c -#, c-format -msgid "unsupported Thumb instruction '%s' with %d arguments" -msgstr "" +#: shared-module/synthio/__init__.c +msgid "%q must be array of type 'h'" +msgstr "%q, 'h' dizisi türünde olmalıdır" -#: py/emitinlinextensa.c -#, c-format -msgid "unsupported Xtensa instruction '%s' with %d arguments" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" msgstr "" -#: shared-module/bitmapfilter/__init__.c -msgid "unsupported bitmap depth" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" msgstr "" -#: shared-module/gifio/GifWriter.c -msgid "unsupported colorspace for GifWriter" +#: shared-module/touchio/TouchIn.c +msgid "No pulldown on pin; 1Mohm recommended" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "unsupported colorspace for dither" +#: shared-module/usb/core/Device.c +msgid "No usb host port initialized" msgstr "" -#: py/objstr.c -#, c-format -msgid "unsupported format character '%c' (0x%x) at index %d" +#: shared-module/usb/core/Device.c +msgid "Pipe error" msgstr "" -#: py/runtime.c -msgid "unsupported type for %q: '%s'" +#: shared-module/usb/core/Device.c +msgid "No configuration set" msgstr "" -#: py/runtime.c -msgid "unsupported type for operator" +#: shared-module/usb_hid/Device.c +msgid "USB busy" msgstr "" -#: py/runtime.c -msgid "unsupported types for %q: '%q', '%q'" +#: shared-module/vectorio/Circle.c shared-module/vectorio/Polygon.c +#: shared-module/vectorio/Rectangle.c +msgid "can only have one parent" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols is too high" +#: shared-module/vectorio/Polygon.c +msgid "Polygon needs at least 3 points" msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "usecols keyword must be specified" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Reconnecting" msgstr "" -#: py/objint.c -#, c-format -msgid "value must fit in %d byte(s)" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Ok" msgstr "" -#: shared-bindings/bitmaptools/__init__.c -msgid "value out of range of target" +#: supervisor/shared/bluetooth/bluetooth.c +msgid "Off" msgstr "" -#: extmod/moddeflate.c -msgid "wbits" +#: supervisor/shared/micropython.c +msgid "[truncated due to length]" msgstr "" -#: shared-bindings/bitmapfilter/__init__.c +#: supervisor/shared/safe_mode.c msgid "" -"weights must be a sequence with an odd square number of elements (usually 9 " -"or 25)" +"\n" +"You are in safe mode because:\n" msgstr "" +"\n" +"Güvenli moddasın çünkü:\n" -#: shared-bindings/bitmapfilter/__init__.c -msgid "weights must be an object of type %q, %q, %q, or %q, not %q " +#: supervisor/shared/safe_mode.c +msgid "Power dipped. Make sure you are providing enough power." msgstr "" -#: shared-bindings/is31fl3741/FrameBuffer.c -msgid "width must be greater than zero" +#: supervisor/shared/safe_mode.c +msgid "You pressed the BOOT button at start up" msgstr "" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" +#: supervisor/shared/safe_mode.c +msgid "You pressed the reset button during boot." msgstr "" -#: ports/raspberrypi/common-hal/wifi/Monitor.c -msgid "wifi.Monitor not available" +#: supervisor/shared/safe_mode.c +msgid "CIRCUITPY drive could not be found or created." +msgstr "CIRCUITPY sürücüsü bulunamadı veya oluşturulamadı." + +#: supervisor/shared/safe_mode.c +msgid "The `microcontroller` module was used to boot into safe mode." msgstr "" -#: shared-bindings/_bleio/Adapter.c -msgid "window must be <= interval" +#: supervisor/shared/safe_mode.c +msgid "Error in safemode.py." msgstr "" -#: extmod/ulab/code/numpy/numerical.c -msgid "wrong axis index" +#: supervisor/shared/safe_mode.c +msgid "Stack overflow. Increase stack size." msgstr "" -#: extmod/ulab/code/numpy/create.c -msgid "wrong axis specified" +#: supervisor/shared/safe_mode.c +msgid "USB devices need more endpoints than are available." msgstr "" -#: extmod/ulab/code/numpy/io/io.c -msgid "wrong dtype" +#: supervisor/shared/safe_mode.c +msgid "USB devices specify too many interface names." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong index type" +#: supervisor/shared/safe_mode.c +msgid "Boot device must be first (interface #0)." +msgstr "Önyükleme cihazı birinci olmalı (arayüz #0)." + +#: supervisor/shared/safe_mode.c +msgid "Internal watchdog timer expired." +msgstr "Dahili bekçi zamanlayıcısının süresi doldu." + +#: supervisor/shared/safe_mode.c +msgid "CircuitPython core code crashed hard. Whoops!\n" +msgstr "CircuitPython kor kodu patladı. Haydaaa!\n" + +#: supervisor/shared/safe_mode.c +msgid "Heap allocation when VM not running." msgstr "" -#: extmod/ulab/code/numpy/compare.c extmod/ulab/code/numpy/create.c -#: extmod/ulab/code/numpy/io/io.c extmod/ulab/code/numpy/transform.c -#: extmod/ulab/code/numpy/vector.c -msgid "wrong input type" +#: supervisor/shared/safe_mode.c +msgid "Failed to write internal flash." +msgstr "Dahili flaş yazılamadı." + +#: supervisor/shared/safe_mode.c +msgid "Hard fault: memory access or instruction error." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of condition array" +#: supervisor/shared/safe_mode.c +msgid "Interrupt error." msgstr "" -#: extmod/ulab/code/numpy/transform.c -msgid "wrong length of index array" +#: supervisor/shared/safe_mode.c +msgid "NLR jump failed. Likely memory corruption." msgstr "" -#: extmod/ulab/code/numpy/create.c py/objarray.c py/objstr.c -msgid "wrong number of arguments" +#: supervisor/shared/safe_mode.c +msgid "Unable to allocate to the heap." msgstr "" -#: py/runtime.c -msgid "wrong number of values to unpack" +#: supervisor/shared/safe_mode.c +msgid "Third-party firmware fatal error." msgstr "" -#: extmod/ulab/code/numpy/vector.c -msgid "wrong output type" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Please file an issue with your program at github.com/adafruit/circuitpython/" +"issues." msgstr "" +"\n" +"Lütfen programınızla ilgili bir sorunu github.com/adafruit/circuitpython/" +"issues adresinden bildirin." -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be an ndarray" +#: supervisor/shared/safe_mode.c +msgid "" +"\n" +"Press reset to exit safe mode.\n" msgstr "" +"\n" +"Güvenli moddan çıkmak için reset'e basın\n" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of float type" +#: supervisor/shared/settings.c +#, c-format +msgid "An error occurred while retrieving '%s':\n" +msgstr "'%s' alınırken hata yaşandı:\n" + +#: supervisor/shared/settings.c +msgid "Invalid unicode escape" msgstr "" -#: extmod/ulab/code/scipy/signal/signal.c -msgid "zi must be of shape (n_section, 2)" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "Wi-Fi: " +msgstr "Wi-Fi: " + +#: supervisor/shared/web_workflow/web_workflow.c +msgid "off" msgstr "" +#: supervisor/shared/web_workflow/web_workflow.c +msgid "No IP" +msgstr "IP yok" + +#, c-format +#~ msgid "Buffer + offset too small %d %d %d" +#~ msgstr "Buffer + offset çok küçük %d %d %d" + +#~ msgid "Byte buffer must be 16 bytes." +#~ msgstr "Bit buffer'ı 16bit olmalı." + +#, c-format +#~ msgid "%%c requires int or char" +#~ msgstr "%%c int veya char tipine ihtiyaç duyar" + +#~ msgid "'%q' object is not callable" +#~ msgstr "'%q' nesnesi çağrılabilir değil" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "'/' USB ile görünür olduğunda, yeniden bağlanamaz." + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Veri öbeği, fmt yığınını takip etmelidir" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Arabellek boyutu 512'nin katı olmalı" @@ -4518,7 +4845,7 @@ msgstr "" #~ msgid "'continue' outside loop" #~ msgstr "döngü dışında 'continue'" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "'coroutine' nesnesi bir iteratör değildir" #~ msgid "(x,y) integers required" @@ -4616,8 +4943,8 @@ msgstr "" #~ msgstr "IV %d bayt uzunluğunda olmalı" #~ msgid "" -#~ "Incompatible .mpy file. Please update all .mpy files. See http://adafru." -#~ "it/mpy-update for more info." +#~ "Incompatible .mpy file. Please update all .mpy files. See http://" +#~ "adafru.it/mpy-update for more info." #~ msgstr "" #~ "Uyumsuz .mpy dosyası. Lütfen tüm .mpy dosyalarını güncelleyin. Daha fazla " #~ "bilgi için http://adafru.it/mpy-update ." diff --git a/locale/zh_Latn_pinyin.po b/locale/zh_Latn_pinyin.po index 46bec68f754..f3f9483cc4c 100644 --- a/locale/zh_Latn_pinyin.po +++ b/locale/zh_Latn_pinyin.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: circuitpython-cn\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2021-01-04 12:55-0600\n" -"PO-Revision-Date: 2024-09-06 04:09+0000\n" +"PO-Revision-Date: 2025-07-15 00:01+0000\n" "Last-Translator: hexthat \n" "Language-Team: Chinese Hanyu Pinyin\n" "Language: zh_Latn_pinyin\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.8-dev\n" +"X-Generator: Weblate 5.13-dev\n" #: main.c msgid "" @@ -96,7 +96,7 @@ msgstr "" msgid "%q and %q contain duplicate pins" msgstr "%q hé %q bāo hán chóng fù yǐn jiǎo" -#: ports/atmel-samd/common-hal/audioio/AudioOut.c +#: shared-bindings/audioio/AudioOut.c msgid "%q and %q must be different" msgstr "%q hé %q bìxū bùtóng" @@ -116,7 +116,11 @@ msgstr "%q bāo hán chóng fù de yǐn jiǎo" msgid "%q failure: %d" msgstr "%q Shībài: %d" -#: py/argcheck.c +#: shared-module/audiodelays/MultiTapDelay.c +msgid "%q in %q must be of type %q or %q, not %q" +msgstr "%q zhōngde %q bìxū shì %q huò %q lèixíng, érbùshì %q" + +#: py/argcheck.c shared-module/audiofilters/Filter.c msgid "%q in %q must be of type %q, not %q" msgstr "%q zhōng de %q bì xū shì %q lèi xíng, ér bù shì %q" @@ -168,7 +172,7 @@ msgstr "%q chángdù bìxū <= %d" msgid "%q length must be >= %d" msgstr "%q chángdù bìxū >= %d" -#: py/modsys.c py/objmodule.c py/runtime.c +#: py/modsys.c py/runtime.c msgid "%q moved from %q to %q" msgstr "%q cóng %q yídòngdào %q" @@ -229,6 +233,7 @@ msgstr "%q bìxū shì 8 debèishù." #: ports/raspberrypi/bindings/cyw43/__init__.c py/argcheck.c py/objexcept.c #: shared-bindings/bitmapfilter/__init__.c shared-bindings/canio/CAN.c #: shared-bindings/digitalio/Pull.c shared-bindings/supervisor/__init__.c +#: shared-module/audiofilters/Filter.c shared-module/displayio/__init__.c #: shared-module/synthio/Synthesizer.c msgid "%q must be of type %q or %q, not %q" msgstr "%q de lèi xíng bì xū shì %q huò %q, ér bù shì %q" @@ -238,6 +243,7 @@ msgid "%q must be of type %q, %q, or %q, not %q" msgstr "%q bìxūshì %q, %q huò %q lèixíng, érbùshì %q" #: py/argcheck.c py/runtime.c shared-bindings/bitmapfilter/__init__.c +#: shared-module/audiodelays/MultiTapDelay.c shared-module/synthio/Note.c #: shared-module/synthio/__init__.c msgid "%q must be of type %q, not %q" msgstr "%q de lèi xíng bì xū shì %q, ér bù shì %q" @@ -283,7 +289,8 @@ msgstr "búdài %q() de %q()" msgid "%q, %q, and %q must all be the same length" msgstr "%q, %q, hé %q bì xū cháng dù xiāng tóng" -#: py/objint.c shared-bindings/storage/__init__.c +#: py/objint.c shared-bindings/_bleio/Connection.c +#: shared-bindings/storage/__init__.c msgid "%q=%q" msgstr "%q=%q" @@ -317,7 +324,7 @@ msgid "'%q' object does not support '%q'" msgstr "'%q' duì xiàng bù zhī chí '%q'" #: py/runtime.c -msgid "'%q' object is not an iterator" +msgid "'%q' object isn't an iterator" msgstr "%q' duìxiàng bùshì yígè diédàiqì" #: py/objtype.c py/runtime.c shared-module/atexit/__init__.c @@ -325,7 +332,7 @@ msgid "'%q' object is not callable" msgstr "%q' duìxiàng bù kě bèi diàoyòng" #: py/runtime.c -msgid "'%q' object is not iterable" +msgid "'%q' object isn't iterable" msgstr "%q' duìxiàng bù kě yòngyú diédài" #: py/emitinlinethumb.c py/emitinlinextensa.c @@ -431,7 +438,7 @@ msgstr "'label' xūyào 1 gè cānshù" #: py/emitnative.c msgid "'not' not implemented" -msgstr "" +msgstr "'not' wèi shíxiàn" #: py/compile.c msgid "'return' outside function" @@ -552,7 +559,6 @@ msgstr "cǐ yǐnjiǎo de suǒyǒu jìshíqì dōu zài shǐyòng zhōng" #: ports/nordic/common-hal/pulseio/PulseIn.c #: ports/nordic/peripherals/nrf/timers.c #: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c -#: ports/stm/peripherals/timers.c msgid "All timers in use" msgstr "suǒyǒu jìshí qì dōu zài shǐyòng zhōng" @@ -565,6 +571,10 @@ msgstr "Mùqián zhèngzài guǎngbō." msgid "Already have all-matches listener" msgstr "yǐjīng yǒu all-matches jiāntīng qì" +#: ports/espressif/common-hal/_bleio/__init__.c +msgid "Already in progress" +msgstr "yǐzài jìnxíng zhōng" + #: ports/espressif/bindings/espnow/ESPNow.c #: ports/espressif/common-hal/espulp/ULP.c #: shared-module/memorymonitor/AllocationAlarm.c @@ -574,6 +584,7 @@ msgstr "yǐjīng zài yùnxíng" #: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Already scanning for wifi networks" msgstr "yǐjīng zài sǎomiáo WIFI wǎngluò" @@ -600,6 +611,10 @@ msgstr "Shùzǔ bìxū bāohán halfwords (type 'H')" msgid "Array values should be single bytes." msgstr "shùzǔ de zhí yīnggāi shì dān'gè zìjié." +#: ports/atmel-samd/common-hal/spitarget/SPITarget.c +msgid "Async SPI transfer in progress on this bus, keep awaiting." +msgstr "zài zhè gè qì chē shàng, jì xù děng." + #: shared-module/memorymonitor/AllocationAlarm.c #, c-format msgid "Attempt to allocate %d blocks" @@ -609,6 +624,11 @@ msgstr "shìtú fēnpèi %d blocks" msgid "Audio conversion not implemented" msgstr "yīnpín zhuǎnhuàn wèi bèi shíxiàn" +#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c +#: ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +msgid "Audio source error" +msgstr "yīnpín yuán cuòwù" + #: shared-bindings/wifi/Radio.c msgid "AuthMode.OPEN is not used with password" msgstr "AuthMode.OPEN wèi shǐyòng mìmǎ" @@ -684,7 +704,7 @@ msgstr "Huǎnchōng qū chángdù%d tài dà. Tā bìxū xiǎoyú%d" #: shared-module/sdcardio/SDCard.c #, c-format msgid "Buffer must be a multiple of %d bytes" -msgstr "" +msgstr "huǎnchōngqū bìxū shì %d zìjié de bèishù" #: shared-bindings/_bleio/PacketBuffer.c #, c-format @@ -745,6 +765,10 @@ msgid "Can only alarm on two low pins from deep sleep." msgstr "" "Zhǐ néng cóng shēndù shuìmián zhōng de liǎng gè dī yǐn jiǎo shàng bàojǐng." +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Can't construct AudioOut because continuous channel already open" +msgstr "wúfǎ gòuzào AudioOut, yīnwéi liánxù tōngdào yǐ dǎkāi" + #: ports/espressif/common-hal/_bleio/Characteristic.c #: ports/nordic/common-hal/_bleio/Characteristic.c msgid "Can't set CCCD on local Characteristic" @@ -790,8 +814,8 @@ msgid "Cannot record to a file" msgstr "Wúfǎ jìlù dào wénjiàn" #: shared-module/storage/__init__.c -msgid "Cannot remount '/' when visible via USB." -msgstr "tōngguò USB kějiàn shí wúfǎ chóngxīn ānzhuāng '/'." +msgid "Cannot remount path when visible via USB." +msgstr "tōngguò USB kějiàn shí wúfǎ chóngxīn guàzǎi lùjìng." #: shared-bindings/digitalio/DigitalInOut.c msgid "Cannot set value when direction is input." @@ -806,6 +830,10 @@ msgstr "wúfǎ zài RS485 móshì xià zhǐdìng RTS huò CTS" msgid "Cannot subclass slice" msgstr "bùnéng zǐlèihuà qiēpiàn" +#: ports/raspberrypi/common-hal/rp2pio/StateMachine.c +msgid "Cannot use GPIO0..15 together with GPIO32..47" +msgstr "wúfǎ shǐyòng GPIO0..15 liántóng GPIO32..47" + #: ports/nordic/common-hal/alarm/pin/PinAlarm.c msgid "Cannot wake on pin edge, only level" msgstr "wúfǎ shǐyòng biānyuán huànxǐng, zhǐnéng shǐyòng diànpíng" @@ -840,6 +868,10 @@ msgstr "zuòbiāo shùzǔ jùyǒu bùtóng de chángdù" msgid "Coordinate arrays types have different sizes" msgstr "zuòbiāo shùzǔ lèixíng jùyǒu bùtóng de dàxiǎo" +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "Could not publish to ROS topic" +msgstr "wúfǎ fābù dào ROS zhǔtí" + #: shared-bindings/_bleio/Adapter.c msgid "Could not set address" msgstr "wúfǎ shèzhì dìzhǐ" @@ -852,6 +884,11 @@ msgstr "Wúfǎ qǐdòng zhōngduàn,RX máng" msgid "Couldn't allocate decoder" msgstr "wúfǎ fēnpèi jiěmǎ qì" +#: ports/espressif/common-hal/rclcpy/__init__.c +#, c-format +msgid "Critical ROS failure during soft reboot, reset required: %d" +msgstr "ruǎn chóngqǐ qījiān fāshēng guānjiàn de ROS gùzhàng, xūyàozhòngzhì: %d" + #: ports/stm/common-hal/analogio/AnalogOut.c msgid "DAC Channel Init Error" msgstr "DAC tōngdào chūshǐhuà cuòwù" @@ -869,10 +906,6 @@ msgstr "DAC zhèngzài bèi shǐyòng" msgid "Data 0 pin must be byte aligned" msgstr "shù jù 0 yǐn jiǎo bì xū shì zì jié duì qí de" -#: shared-module/audiocore/WaveFile.c -msgid "Data chunk must follow fmt chunk" -msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài" - #: shared-module/jpegio/JpegDecoder.c msgid "Data format error (may be broken data)" msgstr "shùjù géshì cuòwù (kěnéngshì shùjù sǔnhuài)" @@ -1007,15 +1040,47 @@ msgstr "Liánjiē shībài: Nèibù cuòwù" msgid "Failed to connect: timeout" msgstr "Liánjiē shībài: Chāoshí" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid arg" +msgstr "Wúfǎ chuàngjiàn liánxù tōngdào: Cānshù wúxiào" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: invalid state" +msgstr "Wúfǎ chuàngjiàn liánxù tōngdào: Zhuàngtài wúxiào" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: no mem" +msgstr "Wúfǎ chuàngjiàn liánxù tōngdào: Wú nèicún" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to create continuous channels: not found" +msgstr "Wúfǎ chuàngjiàn liánxù tōngdào: Wèi zhǎodào" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to enable continuous" +msgstr "Wúfǎ qǐyòng liánxù" + #: shared-module/audiomp3/MP3Decoder.c msgid "Failed to parse MP3 file" msgstr "Wúfǎ jiěxī MP3 wénjiàn" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to register continuous events callback" +msgstr "Liánxù shìjiàn huítiáo zhùcè shībài" + #: ports/nordic/sd_mutex.c #, c-format msgid "Failed to release mutex, err 0x%04x" msgstr "Wúfǎ shìfàng mutex, err 0x%04x" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "Failed to set hostname" +msgstr "wúfǎ shèzhì zhǔjīmíng" + +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "Failed to start async audio" +msgstr "Wúfǎ qǐdòng yìbù yīnpín" + #: supervisor/shared/safe_mode.c msgid "Failed to write internal flash." msgstr "Wúfǎ xiě rù nèibù shǎncún." @@ -1024,12 +1089,14 @@ msgstr "Wúfǎ xiě rù nèibù shǎncún." msgid "File exists" msgstr "Wénjiàn cúnzài" +#: shared-bindings/supervisor/__init__.c shared-module/lvfontio/OnDiskFont.c #: shared-module/os/getenv.c msgid "File not found" msgstr "zhǎo bú dào wén jiàn" #: ports/atmel-samd/common-hal/canio/Listener.c #: ports/espressif/common-hal/canio/Listener.c +#: ports/mimxrt10xx/common-hal/canio/Listener.c #: ports/stm/common-hal/canio/Listener.c msgid "Filters too complex" msgstr "guò lǜ qì tài fù zá" @@ -1057,7 +1124,7 @@ msgstr "" "zài GRB sè yù zhōng, měi gè shū rù de xiàng sù bì xū shì 16 wèi (16 bit) shù " "jù" -#: ports/cxd56/common-hal/camera/Camera.c +#: ports/cxd56/common-hal/camera/Camera.c shared-module/audiocore/WaveFile.c msgid "Format not supported" msgstr "Bù zhīyuán géshì" @@ -1171,6 +1238,7 @@ msgid "Insufficient stream input buffer" msgstr "liú shūrù huǎnchōngqū bùzú" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Interface must be started" msgstr "jiē kǒu bì xū qǐ dòng" @@ -1226,7 +1294,9 @@ msgstr "bèi shūchū gōngnéng zhōngduàn" #: ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c py/argcheck.c #: shared-bindings/digitalio/DigitalInOut.c #: shared-bindings/epaperdisplay/EPaperDisplay.c shared-bindings/pwmio/PWMOut.c +#: shared-bindings/supervisor/__init__.c #: shared-module/aurora_epaper/aurora_framebuffer.c +#: shared-module/lvfontio/OnDiskFont.c msgid "Invalid %q" msgstr "wú xiào %q" @@ -1259,6 +1329,10 @@ msgstr "Wúxiào de BSSID" msgid "Invalid MAC address" msgstr "wú xiào de MAC dì zhǐ" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "Invalid ROS domain ID" +msgstr "wúxiàode ROS yù ID" + #: ports/espressif/common-hal/espidf/__init__.c py/moderrno.c msgid "Invalid argument" msgstr "Wúxiào de cānshù" @@ -1290,6 +1364,7 @@ msgid "Invalid hex password" msgstr "Shíliù jìn zhì mìmǎ wúxiào" #: ports/espressif/common-hal/wifi/Radio.c +#: ports/zephyr-cp/common-hal/wifi/Radio.c msgid "Invalid multicast MAC address" msgstr "wú xiào de duō bō MAC dì zhǐ" @@ -1302,6 +1377,7 @@ msgid "Invalid socket for TLS" msgstr "TLS de chā zuò wú xiào" #: ports/espressif/common-hal/espidf/__init__.c +#: ports/nordic/common-hal/_bleio/__init__.c msgid "Invalid state" msgstr "wú xiào zhuàng tài" @@ -1346,6 +1422,11 @@ msgstr "MAC dì zhǐ wú xiào" msgid "MITM security not supported" msgstr "bù zhīchí MITM ānquánxìng" +#: ports/stm/common-hal/sdioio/SDCard.c +#, c-format +msgid "MMC/SDIO Clock Error %x" +msgstr "MMC/SDIO shízhōngcuòwù %x" + #: shared-bindings/is31fl3741/IS31FL3741.c msgid "Mapping must be a tuple" msgstr "yìng shè bì xū shì yuán zǔ" @@ -1391,7 +1472,8 @@ msgstr "quēshǎo jmp_pin. %q[%u] tiàodào yǐn jiǎoshàng" msgid "Mount point directory missing" msgstr "quēshǎo guàzǎi diǎn mùlù" -#: shared-bindings/busio/UART.c shared-bindings/displayio/Group.c +#: ports/zephyr-cp/bindings/zephyr_serial/UART.c shared-bindings/busio/UART.c +#: shared-bindings/displayio/Group.c msgid "Must be a %q subclass." msgstr "Bìxū shì %q zi lèi." @@ -1531,6 +1613,10 @@ msgstr "zài SDA huò SCL shàng wèi zhǎo dào shàng lā; jiǎn chá nín de msgid "No pulldown on pin; 1Mohm recommended" msgstr "Yǐn jiǎo shàng méiyǒu xiàlā; 1Mohm tuījiàn" +#: shared-module/touchio/TouchIn.c +msgid "No pullup on pin; 1Mohm recommended" +msgstr "Yǐn jiǎo shàng wú shàng lā diànzǔ; jiànyì shǐyòng 1Mohm" + #: py/moderrno.c msgid "No space left on device" msgstr "Shèbèi shàng méiyǒu kònggé" @@ -1578,7 +1664,7 @@ msgstr "bù zhīchí JPEG biāozhǔn" #: ports/espressif/common-hal/sdioio/SDCard.c #, c-format msgid "Number of data_pins must be %d or %d, not %d" -msgstr "" +msgstr "data_pins shù bìxū shì %d huò %d, érbùshì %d" #: shared-bindings/util.c msgid "" @@ -1633,15 +1719,6 @@ msgstr "cǐ yìng jiàn shàng jǐn tí gòng biān yuán jiǎn cè" msgid "Only int or string supported for ip" msgstr "jǐn zhī chí IP de zhěng shù huò zì fú chuàn" -#: shared-module/displayio/OnDiskBitmap.c -#, c-format -msgid "" -"Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: " -"%d bpp given" -msgstr "" -"Jǐn zhīchí dān sè, suǒyǐn wéi 4bpp huò 8bpp yǐjí 16bpp huò gèng gāo de BMP: " -"Gěi chū %d bpp" - #: ports/espressif/common-hal/alarm/touch/TouchAlarm.c msgid "Only one %q can be set in deep sleep." msgstr "zài shēn dù shuì mián zhōng zhǐ néng shè zhì yí gè %q." @@ -1692,6 +1769,7 @@ msgstr "nèi cún bù zú" #: ports/espressif/common-hal/socketpool/Socket.c #: ports/raspberrypi/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Out of sockets" msgstr "tào jiē zì wài" @@ -1711,6 +1789,11 @@ msgstr "yǐ jīng zài shǐ yòng de PWM qiē piàn" msgid "PWM slice channel A already in use" msgstr "PWM qiē piàn tōng dào A yǐ zài shǐ yòng zhōng" +#: shared-bindings/spitarget/SPITarget.c +msgid "Packet buffers for an SPI transfer must have the same length." +msgstr "" +"SPI chuánshū de shùjù bāo huǎnchōng qū bìxū jùyǒu xiāngtóng de chángdù." + #: shared-module/jpegio/JpegDecoder.c msgid "Parameter error" msgstr "cānshù cuòwù" @@ -1813,6 +1896,10 @@ msgstr "chéng xù dà xiǎo wú xiào" msgid "Program too long" msgstr "chéng xù tài cháng" +#: shared-bindings/rclcpy/Publisher.c +msgid "Publishers can only be created from a parent node" +msgstr "chūbǎnshāng zhǐ néngcóng fù jiédiǎn chuàngjiàn" + #: shared-bindings/digitalio/DigitalInOut.c msgid "Pull not used when direction is output." msgstr "Fāngxiàng shūchū shí Pull méiyǒu shǐyòng." @@ -1833,6 +1920,26 @@ msgstr "RNG qǔxiāo chūshǐhuà cuòwù" msgid "RNG Init Error" msgstr "RNG chūshǐhuà cuòwù" +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS failed to initialize. Is agent connected?" +msgstr "ROS chūshǐhuàshībài. dàilǐ yǐ liánjiē ma?" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS internal setup failure" +msgstr "ROS nèibù shèzhì shībài" + +#: ports/espressif/common-hal/rclcpy/__init__.c +msgid "ROS memory allocator failure" +msgstr "ROS nèicún fēnpèiqì shībài" + +#: ports/espressif/common-hal/rclcpy/Node.c +msgid "ROS node failed to initialize" +msgstr "ROS jiédiǎn chūshǐhuà shībài" + +#: ports/espressif/common-hal/rclcpy/Publisher.c +msgid "ROS topic failed to initialize" +msgstr "ROS zhǔtí chūshǐhuà shībài" + #: ports/atmel-samd/common-hal/busio/UART.c ports/cxd56/common-hal/busio/UART.c #: ports/nordic/common-hal/busio/UART.c ports/stm/common-hal/busio/UART.c msgid "RS485" @@ -1915,7 +2022,7 @@ msgstr "SDIO GetCardInfo Cuòwù %d" #: ports/stm/common-hal/sdioio/SDCard.c #, c-format msgid "SDIO Init Error %x" -msgstr "" +msgstr "SDIO rècuòwù %x" #: ports/espressif/common-hal/busio/SPI.c msgid "SPI configuration failed" @@ -1964,11 +2071,13 @@ msgstr "Qiēpiàn hé zhí bùtóng chángdù." #: shared-bindings/displayio/TileGrid.c #: shared-bindings/memorymonitor/AllocationSize.c #: shared-bindings/pulseio/PulseIn.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c msgid "Slices not supported" msgstr "Qiēpiàn bù shòu zhīchí" #: ports/espressif/common-hal/socketpool/SocketPool.c #: ports/raspberrypi/common-hal/socketpool/SocketPool.c +#: ports/zephyr-cp/common-hal/socketpool/SocketPool.c msgid "SocketPool can only be used with wifi.radio" msgstr "SocketPool zhǐ néng yǔ wifi.Radio yīqǐ shǐyòng" @@ -2008,21 +2117,9 @@ msgstr "shàng shù yì cháng shì yǐ xià yì cháng de zhí jiē yuán yīn: msgid "The length of rgb_pins must be 6, 12, 18, 24, or 30" msgstr "Rgb_pins de chángdù bìxū wèi 6,12,18,24 huò 30" -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's bits_per_sample does not match the mixer's" -msgstr "Yàngběn de bits_per_sample yǔ hǔn yīn qì bù pǐpèi" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's channel count does not match the mixer's" -msgstr "Yàngběn de píndào jìshù yǔ hǔn yīn qì bù xiāngfú" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's sample rate does not match the mixer's" -msgstr "Yàngběn de yàngběn sùdù yǔ hǔn yīn qì de xiāngchà bù pǐpèi" - -#: shared-module/audiomixer/MixerVoice.c -msgid "The sample's signedness does not match the mixer's" -msgstr "Yàngběn de qiānmíng yǔ hǔn yīn qì de qiānmíng bù pǐpèi" +#: shared-module/audiocore/__init__.c +msgid "The sample's %q does not match" +msgstr "yàngběn de %q bù pǐpèi" #: supervisor/shared/safe_mode.c msgid "Third-party firmware fatal error." @@ -2044,7 +2141,9 @@ msgstr "" msgid "Tile height must exactly divide bitmap height" msgstr "Píng pū gāodù bìxū huàfēn wèi tú gāodù" -#: shared-bindings/displayio/TileGrid.c shared-module/displayio/TileGrid.c +#: shared-bindings/displayio/TileGrid.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-module/displayio/TileGrid.c msgid "Tile index out of bounds" msgstr "Píng pū zhǐshù chāochū fànwéi" @@ -2052,6 +2151,10 @@ msgstr "Píng pū zhǐshù chāochū fànwéi" msgid "Tile width must exactly divide bitmap width" msgstr "Píng pū kuāndù bìxū huàfēn wèi tú kuāndù" +#: shared-module/tilepalettemapper/TilePaletteMapper.c +msgid "TilePaletteMapper may only be bound to a TileGrid once" +msgstr "TilePaletteMapper zhǐnéng bǎngdìng dào yígè TileGrid shàngyícì" + #: shared-bindings/alarm/time/TimeAlarm.c msgid "Time is in the past." msgstr "shí jiān yǐ jīng guò qù." @@ -2182,6 +2285,10 @@ msgstr "Wúfǎ chūshǐhuà jiěxī qì" msgid "Unable to read color palette data" msgstr "Wúfǎ dúqǔ tiáosèbǎn shùjù" +#: ports/mimxrt10xx/common-hal/canio/CAN.c +msgid "Unable to send CAN Message: all Tx message buffers are busy" +msgstr "wúfǎ fāsòng CAN xiāoxi: suǒyǒuTx xiāoxi huǎnchōngqū dōumáng" + #: ports/espressif/common-hal/mdns/Server.c #: ports/raspberrypi/common-hal/mdns/Server.c msgid "Unable to start mDNS query" @@ -2276,15 +2383,12 @@ msgstr "bú zhī chí de sè cǎi kōng jiān" msgid "Unsupported display bus type" msgstr "Bù zhīchí de gōnggòng qìchē lèixíng" -#: shared-module/audiocore/WaveFile.c -msgid "Unsupported format" -msgstr "Bù zhīchí de géshì" - #: shared-bindings/hashlib/__init__.c msgid "Unsupported hash algorithm" msgstr "bù zhīchí de hā xī suànfǎ" #: ports/espressif/common-hal/socketpool/Socket.c +#: ports/zephyr-cp/common-hal/socketpool/Socket.c msgid "Unsupported socket type" msgstr "bù zhīchí de tàojiēzì lèixíng" @@ -2340,9 +2444,11 @@ msgstr "" msgid "Wi-Fi: " msgstr "Wi-Fi: " +#: ports/espressif/common-hal/wifi/Radio.c #: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "Wifi is not enabled" -msgstr "wú xiàn wǎng luò wèi qǐ yòng" +#: ports/zephyr-cp/common-hal/wifi/Radio.c +msgid "WiFi is not enabled" +msgstr "WiFi wèi qǐyòng" #: main.c msgid "Woken up by alarm.\n" @@ -2364,6 +2470,7 @@ msgstr "nín zài qǐ dòng shí àn xià le liǎng gè àn niǔ." #: ports/espressif/boards/m5stack_core_fire/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c/mpconfigboard.h #: ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.h +#: ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h msgid "You pressed button A at start up." msgstr "nín zài qǐ dòng shí àn xià le àn niǔ A." @@ -2377,6 +2484,7 @@ msgstr "nín zài qǐ dòng shí àn xià le qǐ dòng àn niǔ" #: ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.h #: ports/espressif/boards/adafruit_itsybitsy_esp32/mpconfigboard.h +#: ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h msgid "You pressed the BOOT button at start up." msgstr "nínzài qǐdòngshí ànxià le BOOTànniǔ." @@ -2437,6 +2545,10 @@ msgstr "xūyào yīgè zì jié lèi duìxiàng" msgid "addresses is empty" msgstr "dìzhǐ wèi kōng" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "already playing" +msgstr "yǐjīng zàiwán le" + #: py/compile.c msgid "annotation must be an identifier" msgstr "zhù shì bì xū shì biāo zhì fú" @@ -2463,7 +2575,7 @@ msgstr "wèi wéi pīn hé shù zǔ shí xiàn argsort" #: extmod/ulab/code/numpy/random/random.c msgid "argument must be None, an integer or a tuple of integers" -msgstr "" +msgstr "cānshù bìxū shì None, zhěngshù huò zhěngshù yuánzǔ" #: py/compile.c msgid "argument name reused" @@ -2515,6 +2627,10 @@ msgstr "chángshì huòqǔ kōng xùliè de argmin/ argmax" msgid "attributes not supported" msgstr "bù zhīchí de shǔxìng" +#: ports/espressif/common-hal/audioio/AudioOut.c +msgid "audio format not supported" +msgstr "bù zhīchí yīnpín géshì" + #: extmod/ulab/code/ulab_tools.c msgid "axis is out of bounds" msgstr "zhóu chāo chū biān jiè" @@ -2551,6 +2667,10 @@ msgstr "cuòwù de dàimǎ lèixíng" msgid "binary op %q not implemented" msgstr "èrjìnzhì bǎn qián bǎn %q wèi zhíxíng" +#: ports/espressif/common-hal/audiobusio/PDMIn.c +msgid "bit_depth must be 8, 16, 24, or 32." +msgstr "bit_depth bìxū shì 8, 16, 24, huò 32." + #: shared-module/bitmapfilter/__init__.c msgid "bitmap size and depth must match" msgstr "wèitú dà xiǎohé shēndù bìxū pǐpèi" @@ -2563,6 +2683,15 @@ msgstr "wèi tú dà xiǎo bì xū pǐ pèi" msgid "bits must be 32 or less" msgstr "wèi bì xū shì 32 huò gèng shǎo" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "bits_per_sample must be 16" +msgstr "bits_per_sample bìxū wèi 16" + +#: shared-bindings/audiodelays/Chorus.c shared-bindings/audiodelays/Echo.c +#: shared-bindings/audiodelays/MultiTapDelay.c +#: shared-bindings/audiodelays/PitchShift.c +#: shared-bindings/audiofilters/Distortion.c +#: shared-bindings/audiofilters/Filter.c shared-bindings/audiofilters/Phaser.c #: shared-bindings/audiomixer/Mixer.c msgid "bits_per_sample must be 8 or 16" msgstr "měi jiàn yàngběn bìxū wèi 8 huò 16" @@ -2644,7 +2773,7 @@ msgstr "bùnéng fēnpèi dào biǎodá shì" msgid "can't cancel self" msgstr "bù néng qǔ xiāo zì wǒ" -#: shared-module/adafruit_pixelbuf/PixelBuf.c +#: py/obj.c shared-module/adafruit_pixelbuf/PixelBuf.c msgid "can't convert %q to %q" msgstr "Wúfǎ jiāng %q zhuǎnhuàn wèi %q" @@ -2701,7 +2830,7 @@ msgstr "bùnéng zài '%q' hé '%q' zhī jiān jìnxíng èr yuán yùnsuàn" #: py/emitnative.c msgid "can't do unary op of '%q'" -msgstr "" +msgstr "wúfǎ zhíxíng '%q' de yīyuán yùnsuàn" #: py/emitnative.c msgid "can't implicitly convert '%q' to 'bool'" @@ -3109,7 +3238,7 @@ msgid "format" msgstr "Géshì" #: py/objstr.c -msgid "format requires a dict" +msgid "format needs a dict" msgstr "géshì yāoqiú yīgè yǔjù" #: py/objdeque.c @@ -3243,10 +3372,6 @@ msgstr "suǒyǐn bìxū shì zhěngshù" msgid "indices must be integers, slices, or Boolean lists" msgstr "suǒyǐn bìxū shì zhěngshù, qiēpiàn huò bù'ěr zhí lièbiǎo" -#: ports/espressif/common-hal/busio/I2C.c -msgid "init I2C" -msgstr "chūshǐhuà I2C" - #: extmod/ulab/code/scipy/optimize/optimize.c msgid "initial values must be iterable" msgstr "chūshǐ zhí bìxū shì kě diédài de" @@ -3442,10 +3567,6 @@ msgstr "biāoqiān '%q' wèi dìngyì" msgid "label redefined" msgstr "biāoqiān chóngxīn dìngyì" -#: shared-bindings/audiomixer/MixerVoice.c -msgid "level must be between 0 and 1" -msgstr "Level bìxū jiè yú 0 hé 1 zhī jiān" - #: py/objarray.c msgid "lhs and rhs should be compatible" msgstr "lhs hé rhs yīnggāi jiānróng" @@ -3577,7 +3698,7 @@ msgid "must use keyword argument for key function" msgstr "bìxū shǐyòng guānjiàn cí cānshù" #: py/runtime.c -msgid "name '%q' is not defined" +msgid "name '%q' isn't defined" msgstr "míngchēng '%q' wèi dìngyì" #: py/runtime.c @@ -3852,7 +3973,7 @@ msgstr "chū zhèn liè tài xiǎo" #: extmod/ulab/code/numpy/random/random.c msgid "out has wrong type" -msgstr "" +msgstr "out de lèixíng cuòwù" #: extmod/ulab/code/numpy/vector.c msgid "out keyword is not supported for complex dtype" @@ -3880,11 +4001,11 @@ msgstr "mù biāo fàn wéi wài" #: extmod/ulab/code/numpy/random/random.c msgid "output array has wrong type" -msgstr "" +msgstr "output array de lèixíng cuòwù" #: extmod/ulab/code/numpy/random/random.c msgid "output array must be contiguous" -msgstr "" +msgstr "output array bìxū shì liánxù de" #: py/objint_mpz.c msgid "overflow converting long int to machine word" @@ -3995,6 +4116,10 @@ msgstr "gǔn dòng cān shù bì xū shì ndarray" msgid "rsplit(None,n)" msgstr "Rchāifēn(wú,N)" +#: shared-bindings/audiofreeverb/Freeverb.c +msgid "samples_signed must be true" +msgstr "samples_signed bìxū wéi zhēn" + #: ports/atmel-samd/common-hal/audiobusio/PDMIn.c #: ports/raspberrypi/common-hal/audiobusio/PDMIn.c msgid "sampling rate out of range" @@ -4014,7 +4139,7 @@ msgstr "shè zhì bù shòu zhī chí" #: extmod/ulab/code/numpy/random/random.c msgid "shape must be None, and integer or a tuple of integers" -msgstr "" +msgstr "shape bìxū shì None, bìng qiěshì integer huò zhěngshù yuánzǔ" #: extmod/ulab/code/ndarray.c msgid "shape must be integer or tuple of integers" @@ -4038,7 +4163,7 @@ msgstr "dàxiǎo jǐn wèi ndarrays dìngyì" #: extmod/ulab/code/numpy/random/random.c msgid "size must match out.shape when used together" -msgstr "" +msgstr "yìqǐ shǐ yòngshí, size bìxū yǔ out.shape pǐpèi" #: py/nativeglue.c msgid "slice unsupported" @@ -4217,11 +4342,11 @@ msgid "tx and rx cannot both be None" msgstr "tx hé rx bùnéng dōu shì wú" #: py/objtype.c -msgid "type '%q' is not an acceptable base type" +msgid "type '%q' isn't an acceptable base type" msgstr "lèixíng '%q' bùshì kě jiēshòu de jīchǔ lèixíng" #: py/objtype.c -msgid "type is not an acceptable base type" +msgid "type isn't an acceptable base type" msgstr "lèixíng bùshì kě jiēshòu de jīchǔ lèixíng" #: py/runtime.c @@ -4283,7 +4408,9 @@ msgstr "gé shì bù pǐ pèi de '%c'" msgid "unreadable attribute" msgstr "bùkě dú shǔxìng" -#: shared-bindings/displayio/TileGrid.c shared-bindings/vectorio/VectorShape.c +#: shared-bindings/displayio/TileGrid.c shared-bindings/terminalio/Terminal.c +#: shared-bindings/tilepalettemapper/TilePaletteMapper.c +#: shared-bindings/vectorio/VectorShape.c msgid "unsupported %q type" msgstr "bù zhīchí %q lèixíng" @@ -4364,11 +4491,6 @@ msgstr "" msgid "width must be greater than zero" msgstr "kuāndù bìxū dàyú líng" -#: ports/espressif/common-hal/wifi/Radio.c -#: ports/raspberrypi/common-hal/wifi/Radio.c -msgid "wifi is not enabled" -msgstr "wèi qǐ yòng WIFI" - #: ports/raspberrypi/common-hal/wifi/Monitor.c msgid "wifi.Monitor not available" msgstr "wú xiàn wǎng luò xiǎn shì qì bù kě yòng" @@ -4431,6 +4553,50 @@ msgstr "zi bìxū wèi fú diǎn xíng" msgid "zi must be of shape (n_section, 2)" msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" +#~ msgid "Unsupported format" +#~ msgstr "Bù zhīchí de géshì" + +#~ msgid "Wifi is not enabled" +#~ msgstr "wú xiàn wǎng luò wèi qǐ yòng" + +#~ msgid "wifi is not enabled" +#~ msgstr "wèi qǐ yòng WIFI" + +#~ msgid "Cannot remount '/' when visible via USB." +#~ msgstr "tōngguò USB kějiàn shí wúfǎ chóngxīn ānzhuāng '/'." + +#~ msgid "%q must be a %q object, %q, or %q" +#~ msgstr "%q bìxū shì %q duìxiàng, %q huò %q" + +#~ msgid "Data chunk must follow fmt chunk" +#~ msgstr "Shùjù kuài bìxū zūnxún fmt qū kuài" + +#, c-format +#~ msgid "" +#~ "Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs " +#~ "supported: %d bpp given" +#~ msgstr "" +#~ "Jǐn zhīchí dān sè, suǒyǐn wéi 4bpp huò 8bpp yǐjí 16bpp huò gèng gāo de " +#~ "BMP: Gěi chū %d bpp" + +#~ msgid "level must be between 0 and 1" +#~ msgstr "Level bìxū jiè yú 0 hé 1 zhī jiān" + +#~ msgid "init I2C" +#~ msgstr "chūshǐhuà I2C" + +#~ msgid "The sample's bits_per_sample does not match the mixer's" +#~ msgstr "Yàngběn de bits_per_sample yǔ hǔn yīn qì bù pǐpèi" + +#~ msgid "The sample's channel count does not match the mixer's" +#~ msgstr "Yàngběn de píndào jìshù yǔ hǔn yīn qì bù xiāngfú" + +#~ msgid "The sample's sample rate does not match the mixer's" +#~ msgstr "Yàngběn de yàngběn sùdù yǔ hǔn yīn qì de xiāngchà bù pǐpèi" + +#~ msgid "The sample's signedness does not match the mixer's" +#~ msgstr "Yàngběn de qiānmíng yǔ hǔn yīn qì de qiānmíng bù pǐpèi" + #~ msgid "Buffer length must be a multiple of 512" #~ msgstr "Huǎnchōngqū chángdù bìxū wéi 512 de bèishù" @@ -4760,13 +4926,13 @@ msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" #~ msgid "'%s' object does not support item deletion" #~ msgstr "'%s' duìxiàng bù zhīchí shānchú xiàngmù" -#~ msgid "'%s' object is not an iterator" +#~ msgid "'%s' object isn't an iterator" #~ msgstr "'%s' duìxiàng bùshì yīgè diédài qì" #~ msgid "'%s' object is not callable" #~ msgstr "'%s' duìxiàng wúfǎ diàoyòng" -#~ msgid "'%s' object is not iterable" +#~ msgid "'%s' object isn't iterable" #~ msgstr "'%s' duìxiàng bùnéng diédài" #~ msgid "'%s' object is not subscriptable" @@ -4782,7 +4948,7 @@ msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" #~ msgid "'continue' outside loop" #~ msgstr "'continue' wèiyú xúnhuán zhīwài" -#~ msgid "'coroutine' object is not an iterator" +#~ msgid "'coroutine' object isn't an iterator" #~ msgstr "'coroutine' duìxiàng búshì yígè diédàiqì" #~ msgid "(x,y) integers required" @@ -6130,7 +6296,7 @@ msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" #~ msgid "frequency is read-only for this board" #~ msgstr "cǐ zhǔ bǎn de pín lǜ wéi zhǐ dú" -#~ msgid "function does not take keyword arguments" +#~ msgid "function doesn't take keyword arguments" #~ msgstr "hánshù méiyǒu guānjiàn cí cānshù" #~ msgid "function is implemented for scalars and ndarrays only" @@ -6232,7 +6398,7 @@ msgstr "zi bìxū jùyǒu xíngzhuàng (n_section,2)" #~ msgid "name must be a string" #~ msgstr "míngchēng bìxū shì yīgè zìfú chuàn" -#~ msgid "name reused for argument" +#~ msgid "argument name reused" #~ msgstr "cān shǔ míngchēng bèi chóngxīn shǐyòng" #~ msgid "no available NIC" diff --git a/main.c b/main.c index a463fbe4afe..2020cb8c307 100644 --- a/main.c +++ b/main.c @@ -21,6 +21,7 @@ #include "py/stackctrl.h" #include "shared/readline/readline.h" +#include "shared/runtime/gchelper.h" #include "shared/runtime/pyexec.h" #include "background.h" @@ -42,6 +43,7 @@ #include "supervisor/shared/external_flash/external_flash.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/supervisor/Runtime.h" @@ -82,6 +84,10 @@ #include "shared-module/keypad/__init__.h" #endif +#if CIRCUITPY_AUDIOFILEWRITER +#include "shared-module/audiofilewriter/AudioFileWriter.h" +#endif + #if CIRCUITPY_MEMORYMONITOR #include "shared-module/memorymonitor/__init__.h" #endif @@ -111,8 +117,8 @@ uint8_t value_out = 0; #endif -#if MICROPY_ENABLE_PYSTACK && CIRCUITPY_OS_GETENV -#include "shared-module/os/__init__.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" #endif static void reset_devices(void) { @@ -123,23 +129,24 @@ static void reset_devices(void) { static uint8_t *_heap; static uint8_t *_pystack; +static volatile bool _vm_is_running = false; static const char line_clear[] = "\x1b[2K\x1b[0G"; #if MICROPY_ENABLE_PYSTACK || MICROPY_ENABLE_GC static uint8_t *_allocate_memory(safe_mode_t safe_mode, const char *env_key, size_t default_size, size_t *final_size) { *final_size = default_size; - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_SETTINGS_TOML if (safe_mode == SAFE_MODE_NONE) { - (void)common_hal_os_getenv_int(env_key, (mp_int_t *)final_size); - if (*final_size < 0) { - *final_size = default_size; + mp_int_t size; + if (settings_get_int(env_key, &size) == SETTINGS_OK && size > 0) { + *final_size = size; } } #endif uint8_t *ptr = port_malloc(*final_size, false); - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_SETTINGS_TOML if (ptr == NULL) { // Fallback to the build size. ptr = port_malloc(default_size, false); @@ -203,17 +210,37 @@ static void start_mp(safe_mode_t safe_mode) { mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib)); mp_obj_list_init((mp_obj_list_t *)mp_sys_argv, 0); + + // Always return to root + common_hal_os_chdir("/"); + + _vm_is_running = true; } static void stop_mp(void) { + _vm_is_running = false; #if MICROPY_VFS - mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); // Unmount all heap allocated vfs mounts. - while (gc_nbytes(vfs) > 0) { - vfs = vfs->next; + mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); + if (vfs != NULL) { + do { + if (gc_ptr_on_heap(vfs)) { + // mp_vfs_umount will splice out an unmounted vfs from the vfs_mount_table linked list. + mp_vfs_umount(vfs->obj); + // Start over at the beginning of the list since the first entry may have been removed. + vfs = MP_STATE_VM(vfs_mount_table); + continue; + } + vfs = vfs->next; + } while (vfs != NULL); + + // The last vfs is CIRCUITPY and the root directory. + vfs = MP_STATE_VM(vfs_mount_table); + while (vfs->next != NULL) { + vfs = vfs->next; + } } - MP_STATE_VM(vfs_mount_table) = vfs; MP_STATE_VM(vfs_cur) = vfs; #endif @@ -314,6 +341,9 @@ static void count_strn(void *data, const char *str, size_t len) { } static void cleanup_after_vm(mp_obj_t exception) { + // Do any port cleanup needed before anything else, including releasing board buses. + reset_port_early(); + // Get the traceback of any exception from this run off the heap. // MP_OBJ_SENTINEL means "this run does not contribute to traceback storage, don't touch it" // MP_OBJ_NULL (=0) means "this run completed successfully, clear any stored traceback" @@ -373,6 +403,10 @@ static void cleanup_after_vm(mp_obj_t exception) { keypad_reset(); #endif + #if CIRCUITPY_AUDIOFILEWRITER + audiofilewriter_reset(); + #endif + // Close user-initiated sockets. #if CIRCUITPY_SOCKETPOOL socketpool_user_reset(); @@ -393,8 +427,13 @@ static void cleanup_after_vm(mp_obj_t exception) { // Free the heap last because other modules may reference heap memory and need to shut down. filesystem_flush(); + + // Runs finalisers while shutting down the heap. stop_mp(); + // Don't reset pins until finalisers have run. + reset_all_pins(); + // Let the workflows know we've reset in case they want to restart. supervisor_workflow_reset(); } @@ -413,17 +452,6 @@ static void print_code_py_status_message(safe_mode_t safe_mode) { } static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *simulate_reset) { - bool serial_connected_at_start = serial_connected(); - bool printed_safe_mode_message = false; - #if CIRCUITPY_AUTORELOAD_DELAY_MS > 0 - if (serial_connected_at_start) { - serial_write("\r\n"); - print_code_py_status_message(safe_mode); - print_safe_mode_message(safe_mode); - printed_safe_mode_message = true; - } - #endif - bool skip_repl = false; bool skip_wait = false; bool found_main = false; @@ -458,9 +486,12 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s next_code_configuration->options &= ~SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; next_code_options = next_code_configuration->options; if (next_code_configuration->filename[0] != '\0') { + if (next_code_configuration->working_directory != NULL) { + common_hal_os_chdir(next_code_configuration->working_directory); + } // This is where the user's python code is actually executed: const char *const filenames[] = { next_code_configuration->filename }; - found_main = maybe_run_list(filenames, MP_ARRAY_SIZE(filenames)); + found_main = maybe_run_list(filenames, 1); if (!found_main) { serial_write(next_code_configuration->filename); serial_write_compressed(MP_ERROR_TEXT(" not found.\n")); @@ -494,6 +525,7 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s // Finished executing python code. Cleanup includes filesystem flush and a board reset. + _vm_is_running = false; cleanup_after_vm(_exec_result.exception); _exec_result.exception = NULL; @@ -571,8 +603,8 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s size_t total_time = blink_time + LED_SLEEP_TIME_MS; #endif - // This loop is waits after code completes. It waits for fake sleeps to - // finish, user input or autoreloads. + // This loop is run after code completes. It waits for fake sleeps to + // finish, waits for user input, or waits for an autoreload. #if CIRCUITPY_ALARM bool fake_sleeping = false; #endif @@ -619,20 +651,13 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s // If messages haven't been printed yet, print them if (!printed_press_any_key && serial_connected() && !autoreload_pending()) { - if (!serial_connected_at_start) { - print_code_py_status_message(safe_mode); - } - - if (!printed_safe_mode_message) { - print_safe_mode_message(safe_mode); - printed_safe_mode_message = true; - } + print_code_py_status_message(safe_mode); + print_safe_mode_message(safe_mode); serial_write("\r\n"); serial_write_compressed(MP_ERROR_TEXT("Press any key to enter the REPL. Use CTRL-D to reload.\n")); printed_press_any_key = true; } if (!serial_connected()) { - serial_connected_at_start = false; printed_press_any_key = false; } @@ -640,7 +665,7 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s #if CIRCUITPY_ALARM if (_exec_result.return_code & PYEXEC_DEEP_SLEEP) { const bool awoke_from_true_deep_sleep = - common_hal_mcu_processor_get_reset_reason() == RESET_REASON_DEEP_SLEEP_ALARM; + common_hal_mcu_processor_get_reset_reason() == MCU_RESET_REASON_DEEP_SLEEP_ALARM; if (fake_sleeping) { // This waits until a pretend deep sleep alarm occurs. They are set @@ -772,6 +797,15 @@ static bool __attribute__((noinline)) run_code_py(safe_mode_t safe_mode, bool *s #if CIRCUITPY_ALARM if (fake_sleeping) { board_init(); + #if CIRCUITPY_DISPLAYIO + common_hal_displayio_auto_primary_display(); + #endif + // Undo any preserve_dios. + #if CIRCUITPY_ALARM_PRESERVE_DIOS + common_hal_alarm_clear_pin_preservations(); + #endif + // Reset pins, as if there was a hard reset. + reset_all_pins(); // Pretend that the next run is the first run, as if we were reset. *simulate_reset = true; } @@ -841,6 +875,14 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { boot_output = &boot_text; #endif + // Get the base filesystem. + fs_user_mount_t *vfs = filesystem_circuitpy(); + FATFS *fs = &vfs->fatfs; + + // Allow boot.py access to CIRCUITPY, and allow writes to boot_out.txt. + // We can't use the regular flags for this, because they might get modified inside boot.py. + filesystem_set_ignore_write_protection(vfs, true); + // Write version info mp_printf(&mp_plat_print, "%s\nBoard ID:%s\n", MICROPY_FULL_VERSION_INFO, CIRCUITPY_BOARD_ID); #if CIRCUITPY_MICROCONTROLLER && COMMON_HAL_MCU_PROCESSOR_UID_LENGTH > 0 @@ -859,10 +901,6 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { #ifdef CIRCUITPY_BOOT_OUTPUT_FILE - // Get the base filesystem. - fs_user_mount_t *vfs = (fs_user_mount_t *)MP_STATE_VM(vfs_mount_table)->obj; - FATFS *fs = &vfs->fatfs; - boot_output = NULL; #if CIRCUITPY_STATUS_BAR supervisor_status_bar_resume(); @@ -884,9 +922,6 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { // in case power is momentary or will fail shortly due to, say a low, battery. mp_hal_delay_ms(1000); - // USB isn't up, so we can write the file. - // operating at the oofatfs (f_open) layer means the usb concurrent write permission - // is not even checked! f_open(fs, &boot_output_file, CIRCUITPY_BOOT_OUTPUT_FILE, FA_WRITE | FA_CREATE_ALWAYS); UINT chars_written; f_write(&boot_output_file, boot_text.buf, boot_text.len, &chars_written); @@ -894,14 +929,13 @@ static void __attribute__ ((noinline)) run_boot_py(safe_mode_t safe_mode) { filesystem_flush(); } #endif - } - port_post_boot_py(true); + // Back to regular filesystem protections. + filesystem_set_ignore_write_protection(vfs, false); + } cleanup_after_vm(_exec_result.exception); _exec_result.exception = NULL; - - port_post_boot_py(false); } static int run_repl(safe_mode_t safe_mode) { @@ -974,13 +1008,23 @@ static int run_repl(safe_mode_t safe_mode) { return exit_code; } +#if defined(__ZEPHYR__) && __ZEPHYR__ == 1 +#include + +int circuitpython_main(void) { +#else int __attribute__((used)) main(void) { + #endif // initialise the cpu and peripherals set_safe_mode(port_init()); + // All ports need pins reset, after never-reset pins are marked in port_init(); + reset_all_pins(); + port_heap_init(); + // Turn on RX and TX LEDs if we have them. init_rxtx_leds(); @@ -995,18 +1039,12 @@ int __attribute__((used)) main(void) { serial_early_init(); mp_hal_stdout_tx_str(line_clear); - // Wait briefly to give a reset window where we'll enter safe mode after the reset. - if (get_safe_mode() == SAFE_MODE_NONE) { - set_safe_mode(wait_for_safe_mode_reset()); - } - stack_init(); #if CIRCUITPY_STATUS_BAR supervisor_status_bar_init(); #endif - #if !INTERNAL_FLASH_FILESYSTEM // Set up anything that might need to get done before we try to use SPI flash // This is needed for some boards where flash relies on GPIO setup to work @@ -1023,6 +1061,13 @@ int __attribute__((used)) main(void) { set_safe_mode(SAFE_MODE_NO_CIRCUITPY); } + // Wait briefly to give a reset window where we'll enter safe mode after the reset. + // Do this after mounting the filesystem because settings.toml can contain + // CIRCUITPY_SAFE_MODE_DELAY to change the default delay. + if (get_safe_mode() == SAFE_MODE_NONE) { + set_safe_mode(wait_for_safe_mode_reset()); + } + #if CIRCUITPY_BLEIO // Early init so that a reset press can cause BLE public advertising. Need the filesystem to // read settings.toml. @@ -1047,6 +1092,10 @@ int __attribute__((used)) main(void) { // displays init after filesystem, since they could share the flash SPI board_init(); + #if CIRCUITPY_DISPLAYIO + common_hal_displayio_auto_primary_display(); + #endif + mp_hal_stdout_tx_str(line_clear); // This is first time we are running CircuitPython after a reset or power-up. @@ -1092,9 +1141,6 @@ int __attribute__((used)) main(void) { } simulate_reset = false; - // Always return to root before trying to run files. - common_hal_os_chdir("/"); - if (pyexec_mode_kind == PYEXEC_MODE_FRIENDLY_REPL) { // If code.py did a fake deep sleep, pretend that we // are running code.py for the first time after a hard @@ -1103,7 +1149,7 @@ int __attribute__((used)) main(void) { } else { skip_repl = false; } - } else if (exit_code != 0) { + } else if (exit_code != PYEXEC_NORMAL_EXIT) { break; } @@ -1119,8 +1165,7 @@ int __attribute__((used)) main(void) { void gc_collect(void) { gc_collect_start(); - mp_uint_t regs[10]; - mp_uint_t sp = cpu_get_regs_and_sp(regs); + gc_helper_collect_regs_and_stack(); // This collects root pointers from the VFS mount table. Some of them may // have lost their references in the VM even though they are mounted. @@ -1154,28 +1199,25 @@ void gc_collect(void) { common_hal_wifi_gc_collect(); #endif - // This naively collects all object references from an approximate stack - // range. - gc_collect_root((void **)sp, ((mp_uint_t)port_stack_get_top() - sp) / sizeof(mp_uint_t)); gc_collect_end(); } -// Ports may provide an implementation of this function if it is needed -MP_WEAK void port_gc_collect() { -} - size_t gc_get_max_new_split(void) { return port_heap_get_largest_free_size(); } -void NORETURN nlr_jump_fail(void *val) { +void MP_NORETURN nlr_jump_fail(void *val) { reset_into_safe_mode(SAFE_MODE_NLR_JUMP_FAIL); while (true) { } } +bool vm_is_running(void) { + return _vm_is_running; +} + #ifndef NDEBUG -static void NORETURN __fatal_error(const char *msg) { +static void MP_NORETURN __fatal_error(const char *msg) { #if CIRCUITPY_DEBUG == 0 reset_into_safe_mode(SAFE_MODE_HARD_FAULT); #endif diff --git a/mpy-cross/Makefile b/mpy-cross/Makefile index 9962e9bcbb2..bd9e0fb1f54 100644 --- a/mpy-cross/Makefile +++ b/mpy-cross/Makefile @@ -25,6 +25,12 @@ CFLAGS += -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables # CIRCUITPY-CHANGE CFLAGS += -DCIRCUITPY +# Build a static executable. +# Useful for builds that must run on multiple operating system versions. Used for published mpy-cross versions. +ifdef STATIC_BUILD +CFLAGS += -static -static-libgcc -static-libstdc++ +endif + # Debugging/Optimization ifdef DEBUG CFLAGS += -g @@ -47,6 +53,10 @@ LDFLAGS_ARCH = -Wl,-Map=$@.map,--cref -Wl,--gc-sections endif LDFLAGS += $(LDFLAGS_MOD) $(LDFLAGS_ARCH) -lm $(LDFLAGS_EXTRA) +ifdef STATIC_BUILD +LDFLAGS += -static -static-libgcc -static-libstdc++ +endif + # source files # CIRCUITPY-CHANGE: extra files SRC_C = \ diff --git a/mpy-cross/main.c b/mpy-cross/main.c index 611da764687..add07c3d49b 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -34,13 +34,19 @@ #include "py/persistentcode.h" #include "py/runtime.h" #include "py/gc.h" -#include "py/stackctrl.h" +#include "py/parsenum.h" #include "genhdr/mpversion.h" #ifdef _WIN32 // CIRCUITPY-CHANGE #include "fmode.h" #endif +#if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32 +#include "py/asmrv32.h" + +static asm_rv32_backend_options_t rv32_options = { 0 }; +#endif + // Command line options, with their defaults static uint emit_opt = MP_EMIT_OPT_NONE; mp_uint_t mp_verbose_flag = 0; @@ -55,7 +61,7 @@ static void stdout_print_strn(void *env, const char *str, size_t len) { (void)dummy; } -static const mp_print_t mp_stdout_print = {NULL, stdout_print_strn}; +const mp_print_t mp_stdout_print = {NULL, stdout_print_strn}; static void stderr_print_strn(void *env, const char *str, size_t len) { (void)env; @@ -82,13 +88,20 @@ static int compile_and_save(const char *file, const char *output_file, const cha source_name = qstr_from_str(source_file); } - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); mp_compiled_module_t cm; cm.context = m_new_obj(mp_module_context_t); + cm.arch_flags = 0; + #if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32 + if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_RV32IMC && mp_dynamic_compiler.backend_options != NULL) { + cm.arch_flags = ((asm_rv32_backend_options_t *)mp_dynamic_compiler.backend_options)->allowed_extensions; + } + #endif + mp_compile_to_raw_code(&parse_tree, source_name, false, &cm); if ((output_file != NULL && strcmp(output_file, "-") == 0) || @@ -130,7 +143,11 @@ static int usage(char **argv) { "\n" "Target specific options:\n" "-msmall-int-bits=number : set the maximum bits used to encode a small-int\n" - "-march= : set architecture for native emitter; x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp, armv7emdp, xtensa, xtensawin\n" + "-march= : set architecture for native emitter;\n" + " x86, x64, armv6, armv6m, armv7m, armv7em, armv7emsp,\n" + " armv7emdp, xtensa, xtensawin, rv32imc, rv64imc, host, debug\n" + "-march-flags= : set architecture-specific flags (can be either a dec/hex/bin value or a string)\n" + " supported flags for rv32imc: zba\n" "\n" "Implementation specific options:\n", argv[0] ); @@ -211,9 +228,39 @@ static char *backslash_to_forwardslash(char *path) { return path; } -MP_NOINLINE int main_(int argc, char **argv) { - mp_stack_set_limit(40000 * (sizeof(void *) / 4)); +// This will need to be reworked in case mpy-cross needs to set more bits than +// what its small int representation allows to fit in there. +static bool parse_integer(const char *value, mp_uint_t *integer) { + assert(value && "Attempting to parse a NULL string"); + assert(integer && "Attempting to store into a NULL integer buffer"); + + size_t value_length = strlen(value); + int base = 10; + if (value_length > 2 && value[0] == '0') { + if ((value[1] | 0x20) == 'b') { + base = 2; + } else if ((value[1] | 0x20) == 'x') { + base = 16; + } else { + return false; + } + } + + bool valid = false; + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t parsed = mp_parse_num_integer(value, value_length, base, NULL); + if (mp_obj_is_small_int(parsed)) { + *integer = MP_OBJ_SMALL_INT_VALUE(parsed); + valid = true; + } + nlr_pop(); + } + return valid; +} + +MP_NOINLINE int main_(int argc, char **argv) { pre_process_options(argc, argv); char *heap = malloc(heap_size); @@ -236,11 +283,13 @@ MP_NOINLINE int main_(int argc, char **argv) { // don't support native emitter unless -march is specified mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_NONE; mp_dynamic_compiler.nlr_buf_num_regs = 0; + mp_dynamic_compiler.backend_options = NULL; const char *input_file = NULL; const char *output_file = NULL; const char *source_file = NULL; bool option_parsing_active = true; + const char *arch_flags = NULL; // parse main options for (int a = 1; a < argc; a++) { @@ -314,6 +363,15 @@ MP_NOINLINE int main_(int argc, char **argv) { } else if (strcmp(arch, "xtensawin") == 0) { mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_XTENSAWIN; mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_XTENSAWIN; + } else if (strcmp(arch, "rv32imc") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_RV32IMC; + mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_RV32I; + } else if (strcmp(arch, "rv64imc") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_RV64IMC; + mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_RV64I; + } else if (strcmp(arch, "debug") == 0) { + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_DEBUG; + mp_dynamic_compiler.nlr_buf_num_regs = 0; } else if (strcmp(arch, "host") == 0) { #if defined(__i386__) || defined(_M_IX86) mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_X86; @@ -324,6 +382,9 @@ MP_NOINLINE int main_(int argc, char **argv) { #elif defined(__arm__) && !defined(__thumb2__) mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_ARMV6; mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_ARM_THUMB_FP; + #elif defined(__riscv) && (__riscv_xlen == 64) + mp_dynamic_compiler.native_arch = MP_NATIVE_ARCH_RV64IMC; + mp_dynamic_compiler.nlr_buf_num_regs = MICROPY_NLR_NUM_REGS_RV64I; #else mp_printf(&mp_stderr_print, "unable to determine host architecture for -march=host\n"); exit(1); @@ -331,6 +392,8 @@ MP_NOINLINE int main_(int argc, char **argv) { } else { return usage(argv); } + } else if (strncmp(argv[a], "-march-flags=", sizeof("-march-flags=") - 1) == 0) { + arch_flags = argv[a] + sizeof("-march-flags=") - 1; } else if (strcmp(argv[a], "--") == 0) { option_parsing_active = false; } else { @@ -345,6 +408,38 @@ MP_NOINLINE int main_(int argc, char **argv) { } } + if (arch_flags && mp_dynamic_compiler.native_arch != MP_NATIVE_ARCH_NONE) { + bool processed = false; + #if MICROPY_EMIT_NATIVE && MICROPY_EMIT_RV32 + if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_RV32IMC) { + mp_dynamic_compiler.backend_options = (void *)&rv32_options; + mp_uint_t raw_flags = 0; + if (parse_integer(arch_flags, &raw_flags)) { + if ((raw_flags & ~((mp_uint_t)RV32_EXT_ALL)) == 0) { + rv32_options.allowed_extensions = raw_flags; + processed = true; + } + } else if (strncmp(arch_flags, "zba", sizeof("zba") - 1) == 0) { + rv32_options.allowed_extensions |= RV32_EXT_ZBA; + processed = true; + } + } + #endif + if (!processed) { + mp_printf(&mp_stderr_print, "unrecognised arch flags\n"); + exit(1); + } + } + + #if MICROPY_EMIT_NATIVE + if ((MP_STATE_VM(default_emit_opt) == MP_EMIT_OPT_NATIVE_PYTHON + || MP_STATE_VM(default_emit_opt) == MP_EMIT_OPT_VIPER) + && mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_NONE) { + mp_printf(&mp_stderr_print, "arch not specified\n"); + exit(1); + } + #endif + if (input_file == NULL) { mp_printf(&mp_stderr_print, "no input file\n"); exit(1); @@ -364,7 +459,7 @@ MP_NOINLINE int main_(int argc, char **argv) { } int main(int argc, char **argv) { - mp_stack_ctrl_init(); + mp_cstack_init_with_sp_here(40000 * (sizeof(void *) / 4)); return main_(argc, argv); } diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index bdd10efdaea..36bcbc11394 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -50,11 +50,16 @@ #define MICROPY_EMIT_XTENSA (1) #define MICROPY_EMIT_INLINE_XTENSA (1) #define MICROPY_EMIT_XTENSAWIN (1) +#define MICROPY_EMIT_RV32 (1) +#define MICROPY_EMIT_INLINE_RV32 (1) +#define MICROPY_EMIT_NATIVE_DEBUG (1) +#define MICROPY_EMIT_NATIVE_DEBUG_PRINTER (&mp_stdout_print) #define MICROPY_DYNAMIC_COMPILER (1) #define MICROPY_COMP_CONST_FOLDING (1) #define MICROPY_COMP_MODULE_CONST (1) #define MICROPY_COMP_CONST (1) +#define MICROPY_COMP_CONST_FLOAT (1) #define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (1) #define MICROPY_COMP_TRIPLE_TUPLE_ASSIGN (1) #define MICROPY_COMP_RETURN_IF_EXPR (1) @@ -86,11 +91,12 @@ #define MICROPY_GCREGS_SETJMP (1) #endif -#define MICROPY_PY___FILE__ (0) +#define MICROPY_MODULE___FILE__ (0) #define MICROPY_PY_ARRAY (0) #define MICROPY_PY_ATTRTUPLE (0) #define MICROPY_PY_COLLECTIONS (0) -#define MICROPY_PY_MATH (0) +#define MICROPY_PY_MATH (MICROPY_COMP_CONST_FLOAT) +#define MICROPY_PY_MATH_CONSTANTS (MICROPY_COMP_CONST_FLOAT) #define MICROPY_PY_CMATH (0) #define MICROPY_PY_GC (0) #define MICROPY_PY_IO (0) @@ -98,23 +104,6 @@ // type definitions for the specific machine -#ifdef __LP64__ -typedef long mp_int_t; // must be pointer size -typedef unsigned long mp_uint_t; // must be pointer size -#elif defined(__MINGW32__) && defined(_WIN64) -#include -typedef __int64 mp_int_t; -typedef unsigned __int64 mp_uint_t; -#elif defined(_MSC_VER) && defined(_WIN64) -typedef __int64 mp_int_t; -typedef unsigned __int64 mp_uint_t; -#else -// These are definitions for machines where sizeof(int) == sizeof(void*), -// regardless for actual size. -typedef int mp_int_t; // must be pointer size -typedef unsigned int mp_uint_t; // must be pointer size -#endif - // Cannot include , as it may lead to symbol name clashes #if _FILE_OFFSET_BITS == 64 && !defined(__LP64__) typedef long long mp_off_t; @@ -139,7 +128,7 @@ typedef long mp_off_t; #ifdef _MSC_VER #define MP_ENDIANNESS_LITTLE (1) -#define NORETURN __declspec(noreturn) +#define MP_NORETURN __declspec(noreturn) #define MP_NOINLINE __declspec(noinline) #define MP_ALWAYSINLINE __forceinline #define MP_LIKELY(x) (x) @@ -169,3 +158,5 @@ typedef int ssize_t; typedef mp_off_t off_t; #endif + +extern const struct _mp_print_t mp_stdout_print; diff --git a/mpy-cross/mpy_cross/__init__.py b/mpy-cross/mpy_cross/__init__.py index 5020033e8c8..6d7002a3b89 100644 --- a/mpy-cross/mpy_cross/__init__.py +++ b/mpy-cross/mpy_cross/__init__.py @@ -25,7 +25,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from __future__ import print_function import os import re import stat @@ -43,6 +42,8 @@ "NATIVE_ARCH_ARMV7EMDP": "armv7emdp", "NATIVE_ARCH_XTENSA": "xtensa", "NATIVE_ARCH_XTENSAWIN": "xtensawin", + "NATIVE_ARCH_RV32IMC": "rv32imc", + "NATIVE_ARCH_RV64IMC": "rv64imc", } globals().update(NATIVE_ARCHS) diff --git a/mpy-cross/mpy_cross/__main__.py b/mpy-cross/mpy_cross/__main__.py index 2b6b81c3333..fe78a9e077e 100644 --- a/mpy-cross/mpy_cross/__main__.py +++ b/mpy-cross/mpy_cross/__main__.py @@ -25,7 +25,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from __future__ import print_function import argparse import sys diff --git a/ports/analog/Makefile b/ports/analog/Makefile new file mode 100644 index 00000000000..6b86bd70396 --- /dev/null +++ b/ports/analog/Makefile @@ -0,0 +1,314 @@ +# This file is part of the CircuitPython project: https://circuitpython.org +# +# SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +# SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +# SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +# +# SPDX-License-Identifier: MIT + +BOARD ?= apard32690 +CROSS_COMPILE = arm-none-eabi- + +# Includes mpconfigboard.mk & mpconfigport.mk, +# along with numerous other shared environment makefiles. +include ../../py/circuitpy_mkenv.mk + +# MCU_SERIES e.g. "max32" +# MCU_VARIANT e.g. "max32690" +# defined in mpconfigboard.mk +MCU_SERIES_LOWER := $(shell echo $(MCU_SERIES) | tr '[:upper:]' '[:lower:]') +MCU_SERIES_UPPER := $(shell echo $(MCU_SERIES) | tr '[:lower:]' '[:upper:]') +MCU_VARIANT_LOWER := $(shell echo $(MCU_VARIANT) | tr '[:upper:]' '[:lower:]') +MCU_VARIANT_UPPER := $(shell echo $(MCU_VARIANT) | tr '[:lower:]' '[:upper:]') + + +# ******************************************************************************* +#### MSDK INCLUDES #### +# Necessary for msdk makefiles +TARGET := $(MCU_VARIANT_UPPER) +TARGET_UC := $(MCU_VARIANT_UPPER) +TARGET_LC := $(MCU_VARIANT_LOWER) + +MSDK_ROOT = ./msdk +MSDK_LIBS = $(MSDK_ROOT)/Libraries +CMSIS_ROOT = $(MSDK_LIBS)/CMSIS +ADI_PERIPH = $(MSDK_ROOT)/Libraries/PeriphDrivers +ADI_MISC_DRIVERS_DIR ?= $(MSDK_LIBS)/MiscDrivers +ADI_BOARD_DIR = $(MSDK_LIBS)/Boards/$(MCU_VARIANT_UPPER)/$(BOARD) + +# For debugging the build +ifneq ($(BUILD_VERBOSE),"") +$(info MSDK_ROOT is $(MSDK_ROOT)) +$(info MSDK_LIBS is $(MSDK_LIBS)) +$(info CMSIS_ROOT is $(CMSIS_ROOT)) +$(info ADI_PERIPH is $(ADI_PERIPH)) +$(info ADI_MISC_DRIVERS_DIR is $(ADI_MISC_DRIVERS_DIR)) +$(info ADI_BOARD_DIR is $(ADI_BOARD_DIR)) +$(info MAXIM_PATH is $(MAXIM_PATH)) +endif + +# ----------------- +# Sources & Include +# ----------------- +# Define max32 die type for PeriphDriver Includes +# default to me18 for max32690 +# more info: +# https://analogdevicesinc.github.io/msdk//USERGUIDE/#die-types-to-part-numbers +ifeq ($(MCU_VARIANT_LOWER), "max32690") +DIE_TYPE=me18 +else +DIE_TYPE=me18 +endif + +PERIPH_SRC = $(ADI_PERIPH)/Source +PERIPH_INC = $(ADI_PERIPH)/Include/$(MCU_VARIANT_UPPER) + +INC += -I. +INC += -I../.. +INC += -I$(BUILD) +INC += -I$(BUILD)/genhdr +INC += -I./../../lib/cmsis/inc +INC += -I./boards/ +INC += -I./boards/$(BOARD) +INC += -I./peripherals/ +INC += -I../../lib/mp-readline + +INC += \ + -I$(TOP)/$(BOARD_PATH) \ + -I$(TOP)/lib/cmsis/inc \ + -I$(CMSIS_ROOT)/Include \ + -I$(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Include \ + -I$(PERIPH_INC) \ + -I$(PERIPH_SRC)/SYS \ + -I$(PERIPH_SRC)/CTB \ + -I$(PERIPH_SRC)/DMA \ + -I$(PERIPH_SRC)/FLC \ + -I$(PERIPH_SRC)/GPIO \ + -I$(PERIPH_SRC)/ICC \ + -I$(PERIPH_SRC)/TMR \ + -I$(PERIPH_SRC)/RTC \ + -I$(PERIPH_SRC)/UART \ + -I$(PERIPH_SRC)/TRNG \ + -I$(PERIPH_SRC)/I2C \ + -I$(PERIPH_SRC)/SPI + +INC += -I$(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Source/GCC + +SRC_MAX32 += \ + $(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Source/heap.c \ + $(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Source/system_$(MCU_VARIANT_LOWER).c \ + $(PERIPH_SRC)/SYS/mxc_assert.c \ + $(PERIPH_SRC)/SYS/mxc_delay.c \ + $(PERIPH_SRC)/SYS/mxc_lock.c \ + $(PERIPH_SRC)/SYS/nvic_table.c \ + $(PERIPH_SRC)/SYS/pins_$(DIE_TYPE).c \ + $(PERIPH_SRC)/SYS/sys_$(DIE_TYPE).c \ + $(PERIPH_SRC)/CTB/ctb_$(DIE_TYPE).c \ + $(PERIPH_SRC)/CTB/ctb_reva.c \ + $(PERIPH_SRC)/CTB/ctb_common.c \ + $(PERIPH_SRC)/DMA/dma_reva.c \ + $(PERIPH_SRC)/DMA/dma_$(DIE_TYPE).c \ + $(PERIPH_SRC)/FLC/flc_common.c \ + $(PERIPH_SRC)/FLC/flc_$(DIE_TYPE).c \ + $(PERIPH_SRC)/FLC/flc_reva.c \ + $(PERIPH_SRC)/GPIO/gpio_common.c \ + $(PERIPH_SRC)/GPIO/gpio_$(DIE_TYPE).c \ + $(PERIPH_SRC)/GPIO/gpio_reva.c \ + $(PERIPH_SRC)/ICC/icc_$(DIE_TYPE).c \ + $(PERIPH_SRC)/ICC/icc_reva.c \ + $(PERIPH_SRC)/RTC/rtc_$(DIE_TYPE).c \ + $(PERIPH_SRC)/RTC/rtc_reva.c \ + $(PERIPH_SRC)/TMR/tmr_common.c \ + $(PERIPH_SRC)/TMR/tmr_revb.c \ + $(PERIPH_SRC)/TMR/tmr_$(DIE_TYPE).c \ + $(PERIPH_SRC)/UART/uart_common.c \ + $(PERIPH_SRC)/UART/uart_$(DIE_TYPE).c \ + $(PERIPH_SRC)/UART/uart_revb.c \ + $(PERIPH_SRC)/TRNG/trng_revb.c \ + $(PERIPH_SRC)/TRNG/trng_$(DIE_TYPE).c \ + $(PERIPH_SRC)/I2C/i2c_$(DIE_TYPE).c \ + $(PERIPH_SRC)/I2C/i2c_reva.c \ + $(PERIPH_SRC)/SPI/spi_$(DIE_TYPE).c \ + $(PERIPH_SRC)/SPI/spi_reva1.c + +SRC_C += $(SRC_MAX32) \ + boards/$(BOARD)/board.c \ + boards/$(BOARD)/pins.c \ + peripherals/$(MCU_VARIANT_LOWER)/pins.c \ + peripherals/$(MCU_VARIANT_LOWER)/gpios.c \ + peripherals/$(MCU_VARIANT_LOWER)/max32_uart.c \ + peripherals/$(MCU_VARIANT_LOWER)/max32_i2c.c \ + peripherals/$(MCU_VARIANT_LOWER)/max32_spi.c + +# ******************************************************************************* +### Compiler & Linker Flags ### +COMPILER ?= GCC + +ifeq ($(COMPILER), GCC) + +STARTUPFILE = $(CMSIS_ROOT)/Device/Maxim/$(MCU_VARIANT_UPPER)/Source/GCC/startup_$(MCU_VARIANT_LOWER).s +# STARTUPFILE = $(ADI_BOARD_DIR)/Source/startup_$(MCU_VARIANT_LOWER).s + +# CircuitPython custom linkerfile (necessary for build steps & filesystems) +LINKERFILE = linking/$(MCU_VARIANT_LOWER)_cktpy.ld +LDFLAGS += -nostartfiles -specs=nano.specs +endif + +SRC_S += $(STARTUPFILE) +SRC_S += shared/runtime/gchelper_thumb2.s + +SRC_C += shared/runtime/gchelper_native.c + +# Needed to compile some MAX32 headers +CFLAGS += -D$(MCU_VARIANT_UPPER) \ + -DTARGET_REV=0x4131 \ + -DTARGET=$(MCU_VARIANT_UPPER) \ + -DIAR_PRAGMAS=0 \ + -DRISCV_LOAD=0 \ + -DCONFIG_TRUSTED_EXECUTION_SECURE=0 + +# todo: add these for linkerfiles later on so that it's easier to add new boards +# -DFLASH_ORIGIN \ +# -DFLASH_SIZE \ +# -DSRAM_ORIGIN \ +# -DSRAM_SIZE + +CPU_CORE=cortex-m4 +CFLAGS += -mthumb -mcpu=$(CPU_CORE) -mfloat-abi=softfp -mfpu=fpv4-sp-d16 + +# NOTE: Start with DEBUG=1 defaults for now +ifeq ($(DEBUG),) +DEBUG ?= 1 +endif + +ifeq ($(DEBUG),1) +COPT = -ggdb3 -Og -Os +else +COPT += -Os +endif + +# TinyUSB CFLAGS +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_$(MCU_VARIANT_UPPER) \ + -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED \ + -DCFG_TUSB_OS=OPT_OS_NONE \ + -DCFG_TUD_CDC_TX_BUFSIZE=1024 \ + -DCFG_TUD_CDC_RX_BUFSIZE=1024 \ + -DCFG_TUD_MSC_BUFSIZE=4096 \ + -DCFG_TUD_MIDI_RX_BUFSIZE=128 \ + -DCFG_TUD_MIDI_TX_BUFSIZE=128 \ + -DCFG_TUD_VENDOR_RX_BUFSIZE=1024 \ + -DCFG_TUD_VENDOR_TX_BUFSIZE=1024 + +# Add TinyUSB sources +INC += -I../../lib/tinyusb/src +INC += -I../../supervisor/shared/usb +SRC_C += lib/tinyusb/src/portable/mentor/musb/dcd_musb.c + +# Add port sources incl. any board functions +SRC_C += \ + boards/$(BOARD)/board.c \ + background.c \ + mphalport.c \ + +CFLAGS += $(INC) -Werror -Wall -std=gnu11 -nostartfiles $(BASE_CFLAGS) $(COPT) + +# Suppress some errors for MSDK +# cast-align warning will be suppressed; +# it gets generated by CircuitPy's TLSF memory allocator lib +CFLAGS += -Wno-error=unused-parameter \ + -Wno-error=old-style-declaration \ + -Wno-error=sign-compare \ + -Wno-error=strict-prototypes \ + -Wno-error=cast-qual \ + -Wno-error=unused-variable \ + -Wno-error=lto-type-mismatch \ + -Wno-error=cast-align \ + -Wno-error=nested-externs \ + -Wno-error=sign-compare \ + -Wno-cast-align \ + -Wno-sign-compare \ + +ENTRY = Reset_Handler +LDFLAGS += $(CFLAGS) --entry $(ENTRY) -Wl,-nostdlib -Wl,-T,$(LINKERFILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections +LIBS := -lgcc -lc + +# If not using CKTPY mathlib, use toolchain mathlib +ifndef INTERNAL_LIBM +LIBS += -lm +endif + +# ******************************************************************************* +### PORT-DEFINED BUILD RULES ### +# This section attempts to build the Python core, the supervisor, and any +# port-provided source code. +# +# QSTR sources are provided for the initial build step, which generates +# Python constants to represent C data which gets passed into the GC. + +# OBJ includes +OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) +ifeq ($(INTERNAL_LIBM),1) +OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) +endif +OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) + +# List of sources for qstr extraction +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_CIRCUITPY_COMMON) \ + $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_MOD) +# Sources that only hold QSTRs after pre-processing. +SRC_QSTR_PREPROCESSOR += + +# Default build target +all: $(BUILD)/firmware.elf $(BUILD)/firmware.hex $(BUILD)/firmware.bin + +clean-all: + rm -rf build-* + +# Optional flash option when running within an installed MSDK to use OpenOCD +# Mainline OpenOCD does not yet have the MAX32's flash algorithm integrated. +# If the MSDK is installed, flash-msdk can be run to utilize the the modified +# openocd with the algorithms +MAXIM_PATH := $(subst \,/,$(MAXIM_PATH)) +OPENOCD ?= $(MAXIM_PATH)/Tools/OpenOCD/openocd +OPENOCD_SCRIPTS ?= $(MAXIM_PATH)/Tools/OpenOCD/scripts +flash-msdk: + $(OPENOCD) -s $(OPENOCD_SCRIPTS) \ + -f interface/cmsis-dap.cfg -f target/$(MCU_VARIANT_LOWER).cfg \ + -c "program $(BUILD)/firmware.elf verify; init; reset; exit" + +flash-openocd-jlink: + $(OPENOCD) -s $(OPENOCD_SCRIPTS) \ + -f interface/jlink.cfg -f target/$(MCU_VARIANT_LOWER).cfg \ + -c "program $(BUILD)/firmware.elf verify; init; reset; exit" + +# flash target using JLink +JLINK_DEVICE = $(MCU_VARIANT_LOWER) + +JLINKEXE ?= JLink.exe +JLINKEXE += -if SWD -device ${JLINK_DEVICE} -speed 4000 +COMMAND_FILE := tools/flash_max32.jlink + +flash-jlink: $(BUILD)/firmware.bin + @$(JLINKEXE) -device $(MCU_VARIANT_UPPER) -NoGui 1 -CommandFile ${COMMAND_FILE} + +$(BUILD)/firmware.elf: $(OBJ) + $(STEPECHO) "LINK $@" + $(Q)echo $^ > $(BUILD)/firmware.objs + $(Q)$(CC) -o $@ $(LDFLAGS) @$(BUILD)/firmware.objs -Wl,--print-memory-usage -Wl,--start-group $(LIBS) -Wl,--end-group + $(Q)$(SIZE) $@ | $(PYTHON) $(TOP)/tools/build_memory_info.py $(LINKERFILE) $(BUILD) + +$(BUILD)/firmware.hex: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O ihex $^ $@ + +$(BUILD)/firmware.bin: $(BUILD)/firmware.elf + $(STEPECHO) "Create $@" + $(Q)$(OBJCOPY) -O binary $^ $@ + +# ******************************************************************************* +### CKTPY BUILD RULES ### +include $(TOP)/py/mkrules.mk diff --git a/ports/analog/README.md b/ports/analog/README.md new file mode 100644 index 00000000000..fa5ab1f4a77 --- /dev/null +++ b/ports/analog/README.md @@ -0,0 +1,59 @@ +# Analog Devices "MAX32" MCUs + +This port brings CircuitPython to ADI's "MAX32" series of microcontrollers. These devices are mostly ARM Cortex-M4-based and focus on delivering performance at low-power levels. Currently this port only supports MAX32690. + +## Structure of this port + +- **`boards/:`** Board-specific definitions including pins, board initialization, etc. +- **`common-hal/:`** Port-specific implementations of CircuitPython common-hal APIs. When a new module is enabled, this is often where the implementation is found. Expected functions for modules in `common-hal` are usually found in `shared-bindings/` or `shared-module/` in the CircuitPy root directory. +- **`linking/:`** Linkerfiles customized for CircuitPython. These are distinct from the linkerfiles used in MSDK as they adopt the structure required by CircuitPython. They may also omit unused features and memory sections, e.g. Mailboxes, RISC-V Flash, & Hyperbus RAM for MAX32690. +- **`msdk:/`** SDK for MAX32 devices. More info on our GitHub: [Analog Devices MSDK GitHub](https://github.com/analogdevicesinc/msdk) +- **`peripherals:/`** Helper files for peripherals such as clocks, gpio, etc. These files tend to be specific to vendor SDKs and provide some useful functions for the common-hal interfaces. +- **`supervisor/:`** Implementation files for the CircuitPython supervisor. This includes port setup, usb, and a filesystem on a storage medium such as SD Card/eMMC, QSPI Flash, or internal flash memory. Currently the internal flash is used. This folder is the most important part of a port's core functionality for CircuitPython. +- **`supervisor/port.c:`** Port-specific startup code including clock initialization, console startup, etc. + +- `. :` Build system and high-level interface to the CircuitPython core for the ADI port. + +## Building for MAX32 devices + +Ensure CircuitPython dependencies are up-to-date by following the CircuitPython introduction on Adafruit's Website: [Building CircuitPython - Introduction](https://learn.adafruit.com/building-circuitpython/introduction). You will require the [ARM GNU Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads), with ARM GCC >=13.x. It is also necessary to fetch all submodules and build the `mpy-cross` compiler, per the "Building CircuitPython" guide. + +Ensure the ARM toolchain is contained on your PATH. This can be done in MinGW or WSL by exporting a prefix to the PATH variable. The author's path is included below as an example: + + $ export ARM_GNU_PATH=C:/x-tools/arm-win/arm-none-eabi-w64-i686-13.3rel1/bin + $ export PATH=$ARM_GNU_PATH:$PATH + +This needs to be done each time you open a command environment to build CircuitPython. It can be useful to set up a simple shell script for this. + +Once you have built `mpy-cross` and set up your build system for CircuitPython, you can build for MAX32 devices using the following commands: + + $ cd ports/analog + $ make BOARD= + +Be aware the build may take a long time without parallelizing via the `-jN` flag, where N is the # of cores on your machine. + +## Flashing the board + +Universal instructions on flashing MAX32 devices this project can be found in the **[MSDK User Guide](https://analogdevicesinc.github.io/msdk/USERGUIDE/)**. + +In addition, a user may flash the device by calling `make` with the `flash-msdk` target from within the `ports/analog` directory, as below: + +``` +$ make BOARD= flash-msdk +``` + +This requires the following: +- A MAX32625PICO is connected to the PC via USB +- The PICO board shows up as a "DAPLINK" drive which implements the CMSIS-DAP interface. +- The PICO board is connected to the target board via a 10-pin SWD ribbon cable. + - If SWD connectors are not keyed, the P1 indicator (red line) on the SWD ribbon cable should match the P1 indicator on the board silkscreen near the 10-pin SWD connector. + +## Using the REPL + +Once the device is plugged in, it will enumerate via USB as both a USB Serial Device (CDC) and a Mass Storage Device (MSC). You can connect to the Python REPL with your favorite Serial Monitor program e.g. TeraTerm, VS Code, Putty, etc. Use any buadrate with 8-bit, No Parity, 1 Stop Bit (8N1) settings. From this point forward, you can run Python code on the MCU! If you want help with learning CircuitPython-specific code or learning Python in general, a good place to start is Adafruit's ["Welcome to CircuitPython"](https://learn.adafruit.com/welcome-to-circuitpython/) guide. + +## Editing code.py + +Python code may be executed from `code.py` the `CIRCUITPY:` drive. When editing this file, please be aware that some text editors will work better than others. A list of suggested text editors can be found at Adafruit's guide here: https://learn.adafruit.com/welcome-to-circuitpython/recommended-editors + +Once you save `code.py`, it gets written back to the device you are running Circuitpython on, and will automatically run and output it's result to the REPL. You can also automatically reload and run code.py any time from the REPL by pressing CTRL+D. diff --git a/ports/analog/background.c b/ports/analog/background.c new file mode 100644 index 00000000000..ad840c6dcda --- /dev/null +++ b/ports/analog/background.c @@ -0,0 +1,43 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "py/runtime.h" +#include "supervisor/filesystem.h" +#include "supervisor/usb.h" +#include "supervisor/shared/stack.h" + +#include "max32_port.h" + +// From boards/$(BOARD)/board.c +extern const mxc_gpio_cfg_t pb_pin[]; +extern const int num_pbs; +extern const mxc_gpio_cfg_t led_pin[]; +extern const int num_leds; + +/** NOTE: ALL "ticks" refer to a 1/1024 s period */ +static int status_ticks = 0; + +// This function is where port-specific background +// tasks should be performed +// Execute port specific actions during background tick. Only if ticks are enabled. +void port_background_tick(void) { + status_ticks++; +} + +// Execute port specific actions during background tasks. This is before the +// background callback system and happens *very* often. Use +// port_background_tick() when possible. +void port_background_task(void) { +} + +// Take port specific actions at the beginning and end of background ticks. +// This is used e.g., to set a monitoring pin for debug purposes. "Actual +// work" should be done in port_background_tick() instead. +void port_start_background_tick(void) { +} +void port_finish_background_tick(void) { +} diff --git a/ports/analog/background.h b/ports/analog/background.h new file mode 100644 index 00000000000..d32f2b0dc2c --- /dev/null +++ b/ports/analog/background.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_BACKGROUND_H +#define MICROPY_INCLUDED_BACKGROUND_H + +#endif // MICROPY_INCLUDED_BACKGROUND_H diff --git a/ports/analog/boards/apard32690/README.md b/ports/analog/boards/apard32690/README.md new file mode 100644 index 00000000000..960a26a007f --- /dev/null +++ b/ports/analog/boards/apard32690/README.md @@ -0,0 +1,36 @@ +# AD-APARD32690-SL + +This board features the MAX32690, a dual-core ARM Cortex-M4/RISC-V MCU with 3MiB Flash, 1MiB SRAM. The board also has support for 10BASE-T1L Ethernet, Wifi, Bluetooth, USB, and Security via MAXQ1065. However, most of these features are not yet available for this CircuitPython port (USB will be added soon; others are currently unplanned). + +## Onboard connectors & peripherals + +This board comes in a form-factor similar to an Arduino Mega, enabling Arduino-style shield boards to be plugged in and evaluated with the MAX32690. This vastly opens up the options for easily plugging peripherals into the board, especially when combined with the two Pmod:tm: connectors, P8 (SPI) and P13 (I2C). + +## Product Resources + +For more info about AD-APARD32690-SL, visit our product webpages for datasheets, User Guides, Software, and Design Documents: + +[AD-APARD32690-SL Product Webpage](https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/ad-apard32690-sl.html) +[AD-APARD32690-SL User Guide](https://wiki.analog.com/resources/eval/user-guides/ad-apard32690-sl) + +### Building for this board + +To build for this board, ensure you are in the `ports/analog` directory and run the following command. Note that passing in the `-jN` flag, where N is the # of cores on your machine, can speed up compile times. + +``` +make BOARD=apard32690 +``` + +### Flashing this board + +To flash the board, run the following command if using the MAX32625PICO: + +``` +make BOARD=APARD flash-msdk +``` + +If using Segger JLink, please run the following command instead: + +``` +make BOARD=APARD flash-jlink +``` diff --git a/ports/analog/boards/apard32690/board.c b/ports/analog/boards/apard32690/board.c new file mode 100644 index 00000000000..76c3e7f5591 --- /dev/null +++ b/ports/analog/boards/apard32690/board.c @@ -0,0 +1,32 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "supervisor/port.h" +#include "mpconfigboard.h" +#include "max32_port.h" + +/***** OPTIONAL BOARD-SPECIFIC FUNCTIONS from supervisor/board.h *****/ +// DEFAULT: Using the weak-defined supervisor/shared/board.c functions + +// Initializes board related state once on start up. +void board_init(void) { +} + +// Returns true if the user initiates safe mode in a board specific way. +// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific +// way. +// bool board_requests_safe_mode(void); + +// Reset the state of off MCU components such as neopixels. +// void reset_board(void); + +// Deinit the board. This should put the board in deep sleep durable, low power +// state. It should not prevent the user access method from working (such as +// disabling USB, BLE or flash) because CircuitPython may continue to run. +// void board_deinit(void); + +/*******************************************************************/ diff --git a/ports/analog/boards/apard32690/mpconfigboard.h b/ports/analog/boards/apard32690/mpconfigboard.h new file mode 100644 index 00000000000..19b75a79d81 --- /dev/null +++ b/ports/analog/boards/apard32690/mpconfigboard.h @@ -0,0 +1,40 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices Inc. +// +// SPDX-License-Identifier: MIT + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Glenn Ruben Bakke +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "APARD32690" +#define MICROPY_HW_MCU_NAME "max32690" + +#define FLASH_SIZE (0x300000) // 3MiB +#define FLASH_PAGE_SIZE (0x4000) // 16384 byte pages (16 KiB) + +#define BOARD_HAS_CRYSTAL 1 +#define NUM_GPIO_PORTS 5 +#define CONSOLE_UART MXC_UART0 + +// #if INTERNAL_FLASH_FILESYSTEM +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR (0x102E0000) // for MAX32690 +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (128 * 1024) // 64K + +#define MAX32_FLASH_SIZE 0x300000 // 3 MiB +#define INTERNAL_FLASH_FILESYSTEM_SIZE CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x102E0000 // Load into the last MiB of code/data storage + +// #else +// #define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (0) +// #endif + + #define MICROPY_HW_LED_STATUS (&pin_P2_01) diff --git a/ports/analog/boards/apard32690/mpconfigboard.mk b/ports/analog/boards/apard32690/mpconfigboard.mk new file mode 100644 index 00000000000..0e62f25f3f8 --- /dev/null +++ b/ports/analog/boards/apard32690/mpconfigboard.mk @@ -0,0 +1,31 @@ +# This file is part of the CircuitPython project: https://circuitpython.org +# +# SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +# SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +# +# SPDX-License-Identifier: MIT + +MCU_SERIES=max32 +MCU_VARIANT=max32690 + +INTERNAL_FLASH_FILESYSTEM=1 +# FLASH: 0x10000000 to 0x10300000 (ARM) +# SRAM: 0x20000000 to 0x20100000 + +#### USB CONFIGURATION +# Use 0x0456 for Analog Devices, Inc.; 0B6A for Maxim +USB_VID=0x0456 +# USB_VID=0x0B6A +USB_PID=0x003C +USB_MANUFACTURER="Analog Devices, Inc." +USB_PRODUCT="MAX32690 APARD" + +# NOTE: MAX32 devices do not support IN/OUT pairs on the same EP +USB_NUM_ENDPOINT_PAIRS=12 +### + +# define UID len for memory safety (buffer gets passed as a raw ptr) +COMMON_HAL_MCU_PROCESSOR_UID_LENGTH=30 + +# NOTE: Not implementing external flash for now +# CFLAGS+=-DEXT_FLASH_MX25 diff --git a/ports/analog/boards/apard32690/pins.c b/ports/analog/boards/apard32690/pins.c new file mode 100644 index 00000000000..f4970aff7ae --- /dev/null +++ b/ports/analog/boards/apard32690/pins.c @@ -0,0 +1,133 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + // P0 + { MP_ROM_QSTR(MP_QSTR_P0_0), MP_ROM_PTR(&pin_P0_00) }, + { MP_ROM_QSTR(MP_QSTR_P0_1), MP_ROM_PTR(&pin_P0_01) }, + { MP_ROM_QSTR(MP_QSTR_P0_2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P0_3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P0_4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P0_5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P0_6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P0_7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P0_8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P0_9), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + // P1 + { MP_ROM_QSTR(MP_QSTR_P1_0), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_1), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_2), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_3), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_P1_4), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_5), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_P1_6), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_P1_7), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_8), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_P1_9), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_P1_16), MP_ROM_PTR(&pin_P1_16) }, + { MP_ROM_QSTR(MP_QSTR_P1_17), MP_ROM_PTR(&pin_P1_17) }, + { MP_ROM_QSTR(MP_QSTR_P1_18), MP_ROM_PTR(&pin_P1_18) }, + { MP_ROM_QSTR(MP_QSTR_P1_19), MP_ROM_PTR(&pin_P1_19) }, + { MP_ROM_QSTR(MP_QSTR_P1_20), MP_ROM_PTR(&pin_P1_20) }, + { MP_ROM_QSTR(MP_QSTR_P1_21), MP_ROM_PTR(&pin_P1_21) }, + { MP_ROM_QSTR(MP_QSTR_P1_22), MP_ROM_PTR(&pin_P1_22) }, + { MP_ROM_QSTR(MP_QSTR_P1_23), MP_ROM_PTR(&pin_P1_23) }, + { MP_ROM_QSTR(MP_QSTR_P1_24), MP_ROM_PTR(&pin_P1_24) }, + { MP_ROM_QSTR(MP_QSTR_P1_25), MP_ROM_PTR(&pin_P1_25) }, + { MP_ROM_QSTR(MP_QSTR_P1_26), MP_ROM_PTR(&pin_P1_26) }, + { MP_ROM_QSTR(MP_QSTR_P1_27), MP_ROM_PTR(&pin_P1_27) }, + { MP_ROM_QSTR(MP_QSTR_P1_28), MP_ROM_PTR(&pin_P1_28) }, + { MP_ROM_QSTR(MP_QSTR_P1_29), MP_ROM_PTR(&pin_P1_29) }, + { MP_ROM_QSTR(MP_QSTR_P1_30), MP_ROM_PTR(&pin_P1_30) }, + { MP_ROM_QSTR(MP_QSTR_P1_31), MP_ROM_PTR(&pin_P1_31) }, + // P2 + { MP_ROM_QSTR(MP_QSTR_P2_0), MP_ROM_PTR(&pin_P2_00) }, + { MP_ROM_QSTR(MP_QSTR_P2_1), MP_ROM_PTR(&pin_P2_01) }, + { MP_ROM_QSTR(MP_QSTR_P2_2), MP_ROM_PTR(&pin_P2_02) }, + { MP_ROM_QSTR(MP_QSTR_P2_3), MP_ROM_PTR(&pin_P2_03) }, + { MP_ROM_QSTR(MP_QSTR_P2_4), MP_ROM_PTR(&pin_P2_04) }, + { MP_ROM_QSTR(MP_QSTR_P2_5), MP_ROM_PTR(&pin_P2_05) }, + { MP_ROM_QSTR(MP_QSTR_P2_6), MP_ROM_PTR(&pin_P2_06) }, + { MP_ROM_QSTR(MP_QSTR_P2_7), MP_ROM_PTR(&pin_P2_07) }, + { MP_ROM_QSTR(MP_QSTR_P2_8), MP_ROM_PTR(&pin_P2_08) }, + { MP_ROM_QSTR(MP_QSTR_P2_9), MP_ROM_PTR(&pin_P2_09) }, + { MP_ROM_QSTR(MP_QSTR_P2_10), MP_ROM_PTR(&pin_P2_10) }, + { MP_ROM_QSTR(MP_QSTR_P2_11), MP_ROM_PTR(&pin_P2_11) }, + { MP_ROM_QSTR(MP_QSTR_P2_12), MP_ROM_PTR(&pin_P2_12) }, + { MP_ROM_QSTR(MP_QSTR_P2_13), MP_ROM_PTR(&pin_P2_13) }, + { MP_ROM_QSTR(MP_QSTR_P2_14), MP_ROM_PTR(&pin_P2_14) }, + { MP_ROM_QSTR(MP_QSTR_P2_15), MP_ROM_PTR(&pin_P2_15) }, + { MP_ROM_QSTR(MP_QSTR_P2_16), MP_ROM_PTR(&pin_P2_16) }, + { MP_ROM_QSTR(MP_QSTR_P2_17), MP_ROM_PTR(&pin_P2_17) }, + { MP_ROM_QSTR(MP_QSTR_P2_18), MP_ROM_PTR(&pin_P2_18) }, + { MP_ROM_QSTR(MP_QSTR_P2_19), MP_ROM_PTR(&pin_P2_19) }, + { MP_ROM_QSTR(MP_QSTR_P2_20), MP_ROM_PTR(&pin_P2_20) }, + { MP_ROM_QSTR(MP_QSTR_P2_21), MP_ROM_PTR(&pin_P2_21) }, + { MP_ROM_QSTR(MP_QSTR_P2_22), MP_ROM_PTR(&pin_P2_22) }, + { MP_ROM_QSTR(MP_QSTR_P2_23), MP_ROM_PTR(&pin_P2_23) }, + { MP_ROM_QSTR(MP_QSTR_P2_24), MP_ROM_PTR(&pin_P2_24) }, + { MP_ROM_QSTR(MP_QSTR_P2_25), MP_ROM_PTR(&pin_P2_25) }, + { MP_ROM_QSTR(MP_QSTR_P2_26), MP_ROM_PTR(&pin_P2_26) }, + { MP_ROM_QSTR(MP_QSTR_P2_27), MP_ROM_PTR(&pin_P2_27) }, + { MP_ROM_QSTR(MP_QSTR_P2_28), MP_ROM_PTR(&pin_P2_28) }, + { MP_ROM_QSTR(MP_QSTR_P2_29), MP_ROM_PTR(&pin_P2_29) }, + { MP_ROM_QSTR(MP_QSTR_P2_30), MP_ROM_PTR(&pin_P2_30) }, + { MP_ROM_QSTR(MP_QSTR_P2_31), MP_ROM_PTR(&pin_P2_31) }, + // P3 + { MP_ROM_QSTR(MP_QSTR_P3_0), MP_ROM_PTR(&pin_P3_00) }, + { MP_ROM_QSTR(MP_QSTR_P3_1), MP_ROM_PTR(&pin_P3_01) }, + { MP_ROM_QSTR(MP_QSTR_P3_2), MP_ROM_PTR(&pin_P3_02) }, + { MP_ROM_QSTR(MP_QSTR_P3_3), MP_ROM_PTR(&pin_P3_03) }, + { MP_ROM_QSTR(MP_QSTR_P3_4), MP_ROM_PTR(&pin_P3_04) }, + { MP_ROM_QSTR(MP_QSTR_P3_5), MP_ROM_PTR(&pin_P3_05) }, + { MP_ROM_QSTR(MP_QSTR_P3_6), MP_ROM_PTR(&pin_P3_06) }, + { MP_ROM_QSTR(MP_QSTR_P3_7), MP_ROM_PTR(&pin_P3_07) }, + { MP_ROM_QSTR(MP_QSTR_P3_8), MP_ROM_PTR(&pin_P3_08) }, + { MP_ROM_QSTR(MP_QSTR_P3_9), MP_ROM_PTR(&pin_P3_09) }, + // P4 + { MP_ROM_QSTR(MP_QSTR_P4_0), MP_ROM_PTR(&pin_P4_00) }, + { MP_ROM_QSTR(MP_QSTR_P4_1), MP_ROM_PTR(&pin_P4_01) }, + + // Silkscreen aliases + { MP_ROM_QSTR(MP_QSTR_LED0), MP_ROM_PTR(&pin_P2_01) }, + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_S2), MP_ROM_PTR(&pin_P1_27) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/analog/boards/max32690evkit/board.c b/ports/analog/boards/max32690evkit/board.c new file mode 100644 index 00000000000..76c3e7f5591 --- /dev/null +++ b/ports/analog/boards/max32690evkit/board.c @@ -0,0 +1,32 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "supervisor/port.h" +#include "mpconfigboard.h" +#include "max32_port.h" + +/***** OPTIONAL BOARD-SPECIFIC FUNCTIONS from supervisor/board.h *****/ +// DEFAULT: Using the weak-defined supervisor/shared/board.c functions + +// Initializes board related state once on start up. +void board_init(void) { +} + +// Returns true if the user initiates safe mode in a board specific way. +// Also add BOARD_USER_SAFE_MODE in mpconfigboard.h to explain the board specific +// way. +// bool board_requests_safe_mode(void); + +// Reset the state of off MCU components such as neopixels. +// void reset_board(void); + +// Deinit the board. This should put the board in deep sleep durable, low power +// state. It should not prevent the user access method from working (such as +// disabling USB, BLE or flash) because CircuitPython may continue to run. +// void board_deinit(void); + +/*******************************************************************/ diff --git a/ports/analog/boards/max32690evkit/mpconfigboard.h b/ports/analog/boards/max32690evkit/mpconfigboard.h new file mode 100644 index 00000000000..e4395e8a0ae --- /dev/null +++ b/ports/analog/boards/max32690evkit/mpconfigboard.h @@ -0,0 +1,41 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices Inc. +// +// SPDX-License-Identifier: MIT + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Glenn Ruben Bakke +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "MAX32690 EvKit" +#define MICROPY_HW_MCU_NAME "max32690" + +#define FLASH_SIZE (0x300000) // 3MiB +#define FLASH_PAGE_SIZE (0x4000) // 16384 byte pages (16 KiB) + +#define BOARD_HAS_CRYSTAL 1 +#define NUM_GPIO_PORTS 5 +#define CONSOLE_UART MXC_UART2 + +// #if INTERNAL_FLASH_FILESYSTEM +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR (0x102E0000) // for MAX32690 +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (128 * 1024) // 64K + +#define MAX32_FLASH_SIZE 0x300000 // 3 MiB +#define INTERNAL_FLASH_FILESYSTEM_SIZE CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x102E0000 // Load into the last MiB of code/data storage + +// #else +// #define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (0) +// #endif + +#define MICROPY_HW_LED_STATUS (&pin_P2_12) +#define MICROPY_HW_LED_STATUS_INVERTED 1 diff --git a/ports/analog/boards/max32690evkit/mpconfigboard.mk b/ports/analog/boards/max32690evkit/mpconfigboard.mk new file mode 100644 index 00000000000..a97bc9ddacd --- /dev/null +++ b/ports/analog/boards/max32690evkit/mpconfigboard.mk @@ -0,0 +1,31 @@ +# This file is part of the CircuitPython project: https://circuitpython.org +# +# SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +# SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +# +# SPDX-License-Identifier: MIT + +MCU_SERIES=max32 +MCU_VARIANT=max32690 + +INTERNAL_FLASH_FILESYSTEM=1 +# FLASH: 0x10000000 to 0x10300000 (ARM) +# SRAM: 0x20000000 to 0x20100000 + +#### USB CONFIGURATION +# Use 0x0456 for Analog Devices, Inc.; 0B6A for Maxim +USB_VID=0x0456 +# USB_VID=0x0B6A +USB_PID=0x003D +USB_MANUFACTURER="Analog Devices, Inc." +USB_PRODUCT="MAX32690 EvKit" + +# NOTE: MAX32 devices do not support IN/OUT pairs on the same EP +USB_NUM_ENDPOINT_PAIRS=12 +### + +# define UID len for memory safety (buffer gets passed as a raw ptr) +COMMON_HAL_MCU_PROCESSOR_UID_LENGTH=30 + +# NOTE: Not implementing external flash for now +# CFLAGS+=-DEXT_FLASH_MX25 diff --git a/ports/analog/boards/max32690evkit/pins.c b/ports/analog/boards/max32690evkit/pins.c new file mode 100644 index 00000000000..3270e4d62b2 --- /dev/null +++ b/ports/analog/boards/max32690evkit/pins.c @@ -0,0 +1,131 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + // P0 + { MP_ROM_QSTR(MP_QSTR_P0_0), MP_ROM_PTR(&pin_P0_00) }, + { MP_ROM_QSTR(MP_QSTR_P0_1), MP_ROM_PTR(&pin_P0_01) }, + { MP_ROM_QSTR(MP_QSTR_P0_2), MP_ROM_PTR(&pin_P0_02) }, + { MP_ROM_QSTR(MP_QSTR_P0_3), MP_ROM_PTR(&pin_P0_03) }, + { MP_ROM_QSTR(MP_QSTR_P0_4), MP_ROM_PTR(&pin_P0_04) }, + { MP_ROM_QSTR(MP_QSTR_P0_5), MP_ROM_PTR(&pin_P0_05) }, + { MP_ROM_QSTR(MP_QSTR_P0_6), MP_ROM_PTR(&pin_P0_06) }, + { MP_ROM_QSTR(MP_QSTR_P0_7), MP_ROM_PTR(&pin_P0_07) }, + { MP_ROM_QSTR(MP_QSTR_P0_8), MP_ROM_PTR(&pin_P0_08) }, + { MP_ROM_QSTR(MP_QSTR_P0_9), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + { MP_ROM_QSTR(MP_QSTR_P0_26), MP_ROM_PTR(&pin_P0_26) }, + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + { MP_ROM_QSTR(MP_QSTR_P0_29), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + // P1 + { MP_ROM_QSTR(MP_QSTR_P1_0), MP_ROM_PTR(&pin_P1_00) }, + { MP_ROM_QSTR(MP_QSTR_P1_1), MP_ROM_PTR(&pin_P1_01) }, + { MP_ROM_QSTR(MP_QSTR_P1_2), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_P1_3), MP_ROM_PTR(&pin_P1_03) }, + { MP_ROM_QSTR(MP_QSTR_P1_4), MP_ROM_PTR(&pin_P1_04) }, + { MP_ROM_QSTR(MP_QSTR_P1_5), MP_ROM_PTR(&pin_P1_05) }, + { MP_ROM_QSTR(MP_QSTR_P1_6), MP_ROM_PTR(&pin_P1_06) }, + { MP_ROM_QSTR(MP_QSTR_P1_7), MP_ROM_PTR(&pin_P1_07) }, + { MP_ROM_QSTR(MP_QSTR_P1_8), MP_ROM_PTR(&pin_P1_08) }, + { MP_ROM_QSTR(MP_QSTR_P1_9), MP_ROM_PTR(&pin_P1_09) }, + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_P1_16), MP_ROM_PTR(&pin_P1_16) }, + { MP_ROM_QSTR(MP_QSTR_P1_17), MP_ROM_PTR(&pin_P1_17) }, + { MP_ROM_QSTR(MP_QSTR_P1_18), MP_ROM_PTR(&pin_P1_18) }, + { MP_ROM_QSTR(MP_QSTR_P1_19), MP_ROM_PTR(&pin_P1_19) }, + { MP_ROM_QSTR(MP_QSTR_P1_20), MP_ROM_PTR(&pin_P1_20) }, + { MP_ROM_QSTR(MP_QSTR_P1_21), MP_ROM_PTR(&pin_P1_21) }, + { MP_ROM_QSTR(MP_QSTR_P1_22), MP_ROM_PTR(&pin_P1_22) }, + { MP_ROM_QSTR(MP_QSTR_P1_23), MP_ROM_PTR(&pin_P1_23) }, + { MP_ROM_QSTR(MP_QSTR_P1_24), MP_ROM_PTR(&pin_P1_24) }, + { MP_ROM_QSTR(MP_QSTR_P1_25), MP_ROM_PTR(&pin_P1_25) }, + { MP_ROM_QSTR(MP_QSTR_P1_26), MP_ROM_PTR(&pin_P1_26) }, + { MP_ROM_QSTR(MP_QSTR_P1_27), MP_ROM_PTR(&pin_P1_27) }, + { MP_ROM_QSTR(MP_QSTR_P1_28), MP_ROM_PTR(&pin_P1_28) }, + { MP_ROM_QSTR(MP_QSTR_P1_29), MP_ROM_PTR(&pin_P1_29) }, + { MP_ROM_QSTR(MP_QSTR_P1_30), MP_ROM_PTR(&pin_P1_30) }, + { MP_ROM_QSTR(MP_QSTR_P1_31), MP_ROM_PTR(&pin_P1_31) }, + // P2 + { MP_ROM_QSTR(MP_QSTR_P2_0), MP_ROM_PTR(&pin_P2_00) }, + { MP_ROM_QSTR(MP_QSTR_P2_1), MP_ROM_PTR(&pin_P2_01) }, + { MP_ROM_QSTR(MP_QSTR_P2_2), MP_ROM_PTR(&pin_P2_02) }, + { MP_ROM_QSTR(MP_QSTR_P2_3), MP_ROM_PTR(&pin_P2_03) }, + { MP_ROM_QSTR(MP_QSTR_P2_4), MP_ROM_PTR(&pin_P2_04) }, + { MP_ROM_QSTR(MP_QSTR_P2_5), MP_ROM_PTR(&pin_P2_05) }, + { MP_ROM_QSTR(MP_QSTR_P2_6), MP_ROM_PTR(&pin_P2_06) }, + { MP_ROM_QSTR(MP_QSTR_P2_7), MP_ROM_PTR(&pin_P2_07) }, + { MP_ROM_QSTR(MP_QSTR_P2_8), MP_ROM_PTR(&pin_P2_08) }, + { MP_ROM_QSTR(MP_QSTR_P2_9), MP_ROM_PTR(&pin_P2_09) }, + { MP_ROM_QSTR(MP_QSTR_P2_10), MP_ROM_PTR(&pin_P2_10) }, + { MP_ROM_QSTR(MP_QSTR_P2_11), MP_ROM_PTR(&pin_P2_11) }, + { MP_ROM_QSTR(MP_QSTR_P2_12), MP_ROM_PTR(&pin_P2_12) }, + { MP_ROM_QSTR(MP_QSTR_P2_13), MP_ROM_PTR(&pin_P2_13) }, + { MP_ROM_QSTR(MP_QSTR_P2_14), MP_ROM_PTR(&pin_P2_14) }, + { MP_ROM_QSTR(MP_QSTR_P2_15), MP_ROM_PTR(&pin_P2_15) }, + { MP_ROM_QSTR(MP_QSTR_P2_16), MP_ROM_PTR(&pin_P2_16) }, + { MP_ROM_QSTR(MP_QSTR_P2_17), MP_ROM_PTR(&pin_P2_17) }, + { MP_ROM_QSTR(MP_QSTR_P2_18), MP_ROM_PTR(&pin_P2_18) }, + { MP_ROM_QSTR(MP_QSTR_P2_19), MP_ROM_PTR(&pin_P2_19) }, + { MP_ROM_QSTR(MP_QSTR_P2_20), MP_ROM_PTR(&pin_P2_20) }, + { MP_ROM_QSTR(MP_QSTR_P2_21), MP_ROM_PTR(&pin_P2_21) }, + { MP_ROM_QSTR(MP_QSTR_P2_22), MP_ROM_PTR(&pin_P2_22) }, + { MP_ROM_QSTR(MP_QSTR_P2_23), MP_ROM_PTR(&pin_P2_23) }, + { MP_ROM_QSTR(MP_QSTR_P2_24), MP_ROM_PTR(&pin_P2_24) }, + { MP_ROM_QSTR(MP_QSTR_P2_25), MP_ROM_PTR(&pin_P2_25) }, + { MP_ROM_QSTR(MP_QSTR_P2_26), MP_ROM_PTR(&pin_P2_26) }, + { MP_ROM_QSTR(MP_QSTR_P2_27), MP_ROM_PTR(&pin_P2_27) }, + { MP_ROM_QSTR(MP_QSTR_P2_28), MP_ROM_PTR(&pin_P2_28) }, + { MP_ROM_QSTR(MP_QSTR_P2_29), MP_ROM_PTR(&pin_P2_29) }, + { MP_ROM_QSTR(MP_QSTR_P2_30), MP_ROM_PTR(&pin_P2_30) }, + { MP_ROM_QSTR(MP_QSTR_P2_31), MP_ROM_PTR(&pin_P2_31) }, + // P3 + { MP_ROM_QSTR(MP_QSTR_P3_0), MP_ROM_PTR(&pin_P3_00) }, + { MP_ROM_QSTR(MP_QSTR_P3_1), MP_ROM_PTR(&pin_P3_01) }, + { MP_ROM_QSTR(MP_QSTR_P3_2), MP_ROM_PTR(&pin_P3_02) }, + { MP_ROM_QSTR(MP_QSTR_P3_3), MP_ROM_PTR(&pin_P3_03) }, + { MP_ROM_QSTR(MP_QSTR_P3_4), MP_ROM_PTR(&pin_P3_04) }, + { MP_ROM_QSTR(MP_QSTR_P3_5), MP_ROM_PTR(&pin_P3_05) }, + { MP_ROM_QSTR(MP_QSTR_P3_6), MP_ROM_PTR(&pin_P3_06) }, + { MP_ROM_QSTR(MP_QSTR_P3_7), MP_ROM_PTR(&pin_P3_07) }, + { MP_ROM_QSTR(MP_QSTR_P3_8), MP_ROM_PTR(&pin_P3_08) }, + { MP_ROM_QSTR(MP_QSTR_P3_9), MP_ROM_PTR(&pin_P3_09) }, + // P4 + { MP_ROM_QSTR(MP_QSTR_P4_0), MP_ROM_PTR(&pin_P4_00) }, + { MP_ROM_QSTR(MP_QSTR_P4_1), MP_ROM_PTR(&pin_P4_01) }, + + // Board silkscreen Aliases + { MP_ROM_QSTR(MP_QSTR_LED0), MP_ROM_PTR(&pin_P0_14) }, + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P2_12) }, + { MP_ROM_QSTR(MP_QSTR_PB0), MP_ROM_PTR(&pin_P4_00) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/analog/common-hal/board/__init__.c b/ports/analog/common-hal/board/__init__.c new file mode 100644 index 00000000000..bcae8371c18 --- /dev/null +++ b/ports/analog/common-hal/board/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT diff --git a/ports/analog/common-hal/busio/I2C.c b/ports/analog/common-hal/busio/I2C.c new file mode 100644 index 00000000000..7ebe721b3f4 --- /dev/null +++ b/ports/analog/common-hal/busio/I2C.c @@ -0,0 +1,256 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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. + */ + +#include "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "max32_port.h" + +#define I2C_PRIORITY 1 + +// Set each bit to indicate an active I2c +static uint8_t i2c_active = 0; +static volatile int i2c_err; + +// I2C struct for configuring GPIO pins +extern const mxc_gpio_cfg_t i2c_maps[NUM_I2C]; + +// Construct I2C protocol, this function init i2c peripheral +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t *scl, + const mcu_pin_obj_t *sda, + uint32_t frequency, uint32_t timeout) { + // Check for NULL Pointers && valid I2C settings + assert(self); + + /* NOTE: The validate_obj_is_free_pin() calls in shared-bindings/busio/I2C.c + will ensure that scl and sda are both pins and cannot be null + ref: https://github.com/adafruit/circuitpython/pull/10413 + */ + + // Assign I2C ID based on pins + int i2c_id = pinsToI2c(sda, scl); + if (i2c_id == -1) { + return; + } else { + self->i2c_id = i2c_id; + self->i2c_regs = MXC_I2C_GET_I2C(i2c_id); + } + + // Check for valid I2C controller + assert((self->i2c_id >= 0) && (self->i2c_id < NUM_I2C)); + assert(!(i2c_active & (1 << self->i2c_id))); + + // Attach I2C pins + self->sda = sda; + self->scl = scl; + common_hal_mcu_pin_claim(self->sda); + common_hal_mcu_pin_claim(self->scl); + + // Clear all flags + MXC_I2C_ClearFlags(self->i2c_regs, 0xFFFFFF, 0xFFFFFF); + + // Init as master, no slave address + MXC_I2C_Shutdown(self->i2c_regs); + MXC_I2C_Init(self->i2c_regs, 1, 0); + + // Set frequency arg (CircuitPython shared-bindings validate) + MXC_I2C_SetFrequency(self->i2c_regs, frequency); + + // Indicate to this module that the I2C is active + i2c_active |= (1 << self->i2c_id); + + // Set the timeout to a default value + if (timeout > 100) { + self->timeout = 1; + } else { + self->timeout = timeout; + } + + return; +} + +// Never reset I2C obj when reload +void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { + common_hal_never_reset_pin(self->sda); + common_hal_never_reset_pin(self->scl); +} + +// Check I2C status, deinited or not +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + return self->sda == NULL; +} + +// Deinit i2c obj, reset I2C pin +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + MXC_I2C_Shutdown(self->i2c_regs); + + common_hal_reset_pin(self->sda); + common_hal_reset_pin(self->scl); + + self->sda = NULL; + self->scl = NULL; +} + +// Probe device in I2C bus +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + uint32_t int_fl0; + bool ret = 0; + + // If not in Master mode, error out (can happen in some error conditions) + if (!(self->i2c_regs->ctrl & MXC_F_I2C_CTRL_MST_MODE)) { + return false; + } + + // Clear FIFOs & all interrupt flags + MXC_I2C_ClearRXFIFO(self->i2c_regs); + MXC_I2C_ClearTXFIFO(self->i2c_regs); + MXC_I2C_ClearFlags(self->i2c_regs, 0xFFFFFF, 0xFFFFFF); + + // Pre-load target address into transmit FIFO + addr = (addr << 1); + self->i2c_regs->fifo = addr; + + // Set start bit & wait for it to clear + MXC_I2C_Start(self->i2c_regs); + + // wait for ACK/NACK + while (!(self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_ADDR_ACK) && + !(self->i2c_regs->intfl0 & MXC_F_I2C_INTFL0_ADDR_NACK_ERR)) { + } + + // Save interrupt flags for ACK/NACK checking + int_fl0 = self->i2c_regs->intfl0; + + // Set / Wait for stop + MXC_I2C_Stop(self->i2c_regs); + + // Wait for controller not busy, then clear flags + while (self->i2c_regs->status & MXC_F_I2C_STATUS_BUSY) { + ; + } + MXC_I2C_ClearFlags(self->i2c_regs, 0xFFFFFF, 0xFFFFFF); + + if (int_fl0 & MXC_F_I2C_INTFL0_ADDR_ACK) { + ret = true; + } else { + ret = false; + } + return ret; +} + +// Lock I2C bus +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + + if (self->i2c_regs->status & MXC_F_I2C_STATUS_BUSY) { + return false; + } else { + self->has_lock = true; + return true; + } +} + +// Check I2C lock status +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +// Unlock I2C bus +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; +} + +// Write data to the device selected by address +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + + int ret; + mxc_i2c_req_t wr_req = { + .addr = addr, + .i2c = self->i2c_regs, + .tx_buf = (uint8_t *)data, + .tx_len = len, + .rx_buf = NULL, + .rx_len = 0, + .callback = NULL + }; + ret = MXC_I2C_MasterTransaction(&wr_req); + if (ret) { + return -MP_EIO; + } + + return 0; +} + +// Read into buffer from the device selected by address +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, + uint16_t addr, + uint8_t *data, size_t len) { + + int ret; + mxc_i2c_req_t rd_req = { + .addr = addr, + .i2c = self->i2c_regs, + .tx_buf = NULL, + .tx_len = 0, + .rx_buf = data, + .rx_len = len, + .callback = NULL + }; + ret = MXC_I2C_MasterTransaction(&rd_req); + if (ret) { + // Return I/O error + return -MP_EIO; + } + + return 0; +} + +// Write the bytes from out_data to the device selected by address +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, + uint8_t *in_data, size_t in_len) { + + int ret; + mxc_i2c_req_t wr_rd_req = { + .addr = addr, + .i2c = self->i2c_regs, + .tx_buf = out_data, + .tx_len = out_len, + .rx_buf = in_data, + .rx_len = in_len, + .callback = NULL + }; + ret = MXC_I2C_MasterTransaction(&wr_rd_req); + if (ret) { + return -MP_EIO; + } + + return 0; +} diff --git a/ports/analog/common-hal/busio/I2C.h b/ports/analog/common-hal/busio/I2C.h new file mode 100644 index 00000000000..55c230ee2f9 --- /dev/null +++ b/ports/analog/common-hal/busio/I2C.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +// HAL-specific +#include "i2c.h" +#include "gpio.h" + +// Define a struct for what BUSIO.I2C should carry +typedef struct { + mp_obj_base_t base; + + int i2c_id; + mxc_i2c_regs_t *i2c_regs; + const mcu_pin_obj_t *scl; + const mcu_pin_obj_t *sda; + const int frequency; + + uint32_t timeout; + bool has_lock; +} busio_i2c_obj_t; diff --git a/ports/analog/common-hal/busio/SPI.c b/ports/analog/common-hal/busio/SPI.c new file mode 100644 index 00000000000..bdbe6da9d94 --- /dev/null +++ b/ports/analog/common-hal/busio/SPI.c @@ -0,0 +1,343 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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. + */ + +#include "shared-bindings/busio/SPI.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/board.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "max32_port.h" +#include "spi_reva1.h" + +// Note that any bugs introduced in this file can cause crashes +// at startupfor chips using external SPI flash. + +#define SPI_PRIORITY 1 + +typedef enum { + SPI_FREE = 0, + SPI_BUSY, +} spi_status_t; + +// Set each bit to indicate an active SPI +static uint8_t spi_active = 0; +static spi_status_t spi_status[NUM_SPI]; +static volatile int spi_err; + +// Construct SPI protocol, this function init SPI peripheral +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t *sck, + const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, + bool half_duplex) { + int err = 0; + + // Check for NULL Pointer + assert(self); + + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + + // Assign SPI ID based on pins + int spi_id = pinsToSpi(mosi, miso, sck); + if (spi_id == -1) { + return; + } else { + self->spi_id = spi_id; + self->spi_regs = MXC_SPI_GET_SPI(spi_id); + } + + // Other pins default to true + mxc_spi_pins_t spi_pins = { + .clock = TRUE, + .mosi = TRUE, + .miso = TRUE, + .ss0 = FALSE, + .ss1 = FALSE, + .ss2 = FALSE, + .vddioh = true, + .drvstr = MXC_GPIO_DRVSTR_0 + }; + + assert((self->spi_id >= 0) && (self->spi_id < NUM_SPI)); + + // Init SPI controller + if ((mosi != NULL) && (miso != NULL) && (sck != NULL)) { + // spi, mastermode, quadModeUsed, numSubs, ssPolarity, frequency + err = MXC_SPI_Init(self->spi_regs, MXC_SPI_TYPE_CONTROLLER, MXC_SPI_INTERFACE_STANDARD, + 1, 0x01, 1000000, spi_pins); + MXC_GPIO_SetVSSEL(MXC_GPIO_GET_GPIO(sck->port), MXC_GPIO_VSSEL_VDDIOH, (sck->mask | miso->mask | mosi->mask | MXC_GPIO_PIN_0)); + if (err) { + // NOTE: Reuse existing messages from locales/circuitpython.pot to save space + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_SPI); + } + } else { + mp_raise_NotImplementedError(MP_ERROR_TEXT("SPI needs MOSI, MISO, and SCK")); + } + + // Attach SPI pins + self->mosi = mosi; + self->miso = miso; + self->sck = sck; + common_hal_mcu_pin_claim(self->mosi); + common_hal_mcu_pin_claim(self->miso); + common_hal_mcu_pin_claim(self->sck); + + // Indicate to this module that the SPI is active + spi_active |= (1 << self->spi_id); + + return; +} + +// Never reset SPI when reload +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + common_hal_never_reset_pin(self->mosi); + common_hal_never_reset_pin(self->miso); + common_hal_never_reset_pin(self->sck); + common_hal_never_reset_pin(self->nss); +} + +// Check SPI status, deinited or not +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + return self->sck == NULL; +} + +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->sck = NULL; +} + +// Deinit SPI obj +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + + MXC_SPI_Shutdown(self->spi_regs); + common_hal_reset_pin(self->mosi); + common_hal_reset_pin(self->miso); + common_hal_reset_pin(self->sck); + common_hal_reset_pin(self->nss); + + self->mosi = NULL; + self->miso = NULL; + self->nss = NULL; + + common_hal_busio_spi_mark_deinit(self); +} + +// Configures the SPI bus. The SPI object must be locked. +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, + uint8_t polarity, + uint8_t phase, + uint8_t bits) { + + mxc_spi_clkmode_t clk_mode; + int ret; + + self->polarity = polarity; + self->phase = phase; + self->bits = bits; + + switch ((polarity << 1) | (phase)) { + case 0b00: + clk_mode = MXC_SPI_CLKMODE_0; + break; + case 0b01: + clk_mode = MXC_SPI_CLKMODE_1; + break; + case 0b10: + clk_mode = MXC_SPI_CLKMODE_2; + break; + case 0b11: + clk_mode = MXC_SPI_CLKMODE_3; + break; + default: + // should not be reachable; validated in shared-bindings/busio/SPI.c + return false; + } + + ret = MXC_SPI_SetFrequency(self->spi_regs, baudrate); + if (ret) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q out of range"), MP_QSTR_baudrate); + return false; + } + + // MXC_SPI_SetFrequency() floors the clock divisor, so the actual rate can be + // HIGHER than requested. Treat baudrate as a ceiling: if the hardware + // overshoots, bisect downward on the requested target for the highest rate + // that does not exceed baudrate. MXC_SPI_GetFrequency() reports the actual + // configured rate, so we don't depend on the divisor internals. + uint32_t actual = MXC_SPI_GetFrequency(self->spi_regs); + if (actual > baudrate) { + uint32_t lo = 1; // f(lo) <= baudrate + uint32_t hi = baudrate; // f(hi) > baudrate (just measured) + while (hi - lo > 1) { + uint32_t mid = lo + (hi - lo) / 2; + MXC_SPI_SetFrequency(self->spi_regs, mid); + if (MXC_SPI_GetFrequency(self->spi_regs) <= baudrate) { + lo = mid; + } else { + hi = mid; + } + } + MXC_SPI_SetFrequency(self->spi_regs, lo); + actual = MXC_SPI_GetFrequency(self->spi_regs); + } + self->baudrate = actual; + ret = MXC_SPI_SetDataSize(self->spi_regs, bits); + if (ret == E_BAD_PARAM) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q out of range"), MP_QSTR_bits); + return false; + } else if (ret == E_BAD_STATE) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid state")); + } + ret = MXC_SPI_SetMode(self->spi_regs, clk_mode); + if (ret) { + mp_raise_ValueError(MP_ERROR_TEXT("Failed to set SPI Clock Mode")); + return false; + } + return true; +} + +// Lock SPI bus +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + if (spi_status[self->spi_id] != SPI_BUSY) { + self->has_lock = true; + return true; + } else { + return false; + } +} + +// Check SPI lock status +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +// Unlock SPI bus +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; +} + +// Write the data contained in buffer +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t *data, + size_t len) { + int ret = 0; + + mxc_spi_req_t wr_req = { + .spi = self->spi_regs, + .ssIdx = 0, + .txCnt = 0, + .rxCnt = 0, + .txData = (uint8_t *)data, + .txLen = len, + .rxData = NULL, + .rxLen = 0, + .ssDeassert = 1, + .completeCB = NULL, + .txDummyValue = 0xFF, + }; + ret = MXC_SPI_MasterTransaction(&wr_req); + if (ret) { + return false; + } else { + return true; + } +} + +// Read data into buffer +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, + uint8_t write_value) { + + int ret = 0; + + mxc_spi_req_t rd_req = { + .spi = self->spi_regs, + .ssIdx = 0, + .txCnt = 0, + .rxCnt = 0, + .txData = NULL, + .txLen = len, + .rxData = data, + .rxLen = len, + .ssDeassert = 1, + .completeCB = NULL, + .txDummyValue = write_value, + }; + ret = MXC_SPI_MasterTransaction(&rd_req); + if (ret) { + return false; + } else { + return true; + } +} + +// Write out the data in data_out +// while simultaneously reading data into data_in +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, + const uint8_t *data_out, + uint8_t *data_in, + size_t len) { + + int ret = 0; + + mxc_spi_req_t rd_req = { + .spi = self->spi_regs, + .ssIdx = 0, + .txCnt = 0, + .rxCnt = 0, + .txData = (uint8_t *)data_out, + .txLen = len, + .rxData = data_in, + .rxLen = len, + .ssDeassert = 1, + .completeCB = NULL, + .txDummyValue = 0xFF, + }; + ret = MXC_SPI_MasterTransaction(&rd_req); + if (ret) { + return false; + } else { + return true; + } +} + +// Get SPI baudrate +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t *self) { + return self->baudrate; +} + +// Get SPI phase +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t *self) { + return self->phase; +} + +// Get SPI polarity +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self) { + return self->polarity; +} diff --git a/ports/analog/common-hal/busio/SPI.h b/ports/analog/common-hal/busio/SPI.h new file mode 100644 index 00000000000..d10601876fb --- /dev/null +++ b/ports/analog/common-hal/busio/SPI.h @@ -0,0 +1,41 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_SPI_H +#define MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_SPI_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +// HAL-specific +#include "spi.h" + +// Define a struct for what BUSIO.SPI should carry +typedef struct { + mp_obj_base_t base; + + // Spi regs & pins + int spi_id; + mxc_spi_regs_t *spi_regs; + const mcu_pin_obj_t *sck; + const mcu_pin_obj_t *mosi; + const mcu_pin_obj_t *miso; + const mcu_pin_obj_t *nss; + + // Configuration + uint32_t baudrate; + uint16_t prescaler; + uint8_t polarity; + uint8_t phase; + uint8_t bits; + + // Synch data + bool has_lock; +} busio_spi_obj_t; + +void spi_reset(void); + +#endif // MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_SPI_H diff --git a/ports/analog/common-hal/busio/UART.c b/ports/analog/common-hal/busio/UART.c new file mode 100644 index 00000000000..be7851f52a2 --- /dev/null +++ b/ports/analog/common-hal/busio/UART.c @@ -0,0 +1,460 @@ +/* + * This file is part of Adafruit for EFR32 project + * + * The MIT License (MIT) + * + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + * + * 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 CIRCUITPY_BUSIO_UART + +#include "mpconfigport.h" +#include "supervisor/shared/tick.h" + +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/UART.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared/readline/readline.h" +#include "shared/runtime/interrupt_char.h" + +#include "py/gc.h" +#include "py/ringbuf.h" +#include "py/mperrno.h" +#include "py/mpprint.h" +#include "py/runtime.h" + +#include "max32_port.h" +#include "UART.h" +#include "nvic_table.h" + +// UART IRQ Priority +#define UART_PRIORITY 1 + +typedef enum { + UART_9600 = 9600, + UART_14400 = 14400, + UART_19200 = 19200, + UART_38400 = 38400, + UART_57600 = 57600, + UART_115200 = 115200, + UART_230400 = 230400, + UART_460800 = 460800, + UART_921600 = 921600, +} uart_valid_baudrates; + +typedef enum { + UART_FREE = 0, + UART_BUSY, + UART_NEVER_RESET, +} uart_status_t; + +static uint32_t timeout_ms = 0; + +// Set each bit to indicate an active UART +// will be checked by ISR Handler for which ones to call +static uint8_t uarts_active = 0; +static uart_status_t uart_status[NUM_UARTS]; +static volatile int uart_err; +static uint8_t uart_never_reset_mask = 0; +static busio_uart_obj_t *context; + +static bool isValidBaudrate(uint32_t baudrate) { + switch (baudrate) { + case UART_9600: + return true; + break; + case UART_14400: + return true; + break; + case UART_19200: + return true; + break; + case UART_38400: + return true; + break; + case UART_57600: + return true; + break; + case UART_115200: + return true; + break; + case UART_230400: + return true; + break; + case UART_460800: + return true; + break; + case UART_921600: + return true; + break; + default: + return false; + break; + } +} + +static mxc_uart_parity_t convertParity(busio_uart_parity_t busio_parity) { + switch (busio_parity) { + case BUSIO_UART_PARITY_NONE: + return MXC_UART_PARITY_DISABLE; + case BUSIO_UART_PARITY_EVEN: + return MXC_UART_PARITY_EVEN_0; + case BUSIO_UART_PARITY_ODD: + return MXC_UART_PARITY_ODD_0; + default: + // not reachable due to validation in shared-bindings/busio/SPI.c + return MXC_UART_PARITY_DISABLE; + } +} + +void uart_isr(void) { + for (int i = 0; i < NUM_UARTS; i++) { + if (uarts_active & (1 << i)) { + MXC_UART_AsyncHandler(MXC_UART_GET_UART(i)); + } + } +} + +// Callback gets called when AsyncRequest is COMPLETE +// (e.g. txLen == txCnt) +static volatile void uartCallback(mxc_uart_req_t *req, int error) { + uart_status[MXC_UART_GET_IDX(req->uart)] = UART_FREE; + uart_err = error; + + MXC_SYS_Crit_Enter(); + ringbuf_put_n(context->ringbuf, req->rxData, req->rxLen); + MXC_SYS_Crit_Exit(); +} + +// Construct an underlying UART object. +void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, + const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, + const mcu_pin_obj_t *rs485_dir, bool rs485_invert, + uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, + bool sigint_enabled) { + int err, temp; + + // Check for NULL Pointers && valid UART settings + assert(self); + + // Assign UART ID based on pins + temp = pinsToUart(tx, rx); + if (temp == -1) { + // Error will be indicated by pinsToUart(tx, rx) function + return; + } else { + self->uart_id = temp; + self->uart_regs = MXC_UART_GET_UART(temp); + } + assert((self->uart_id >= 0) && (self->uart_id < NUM_UARTS)); + + // Check for size of ringbuffer, desire powers of 2 + // At least use 1 byte if no size is given + assert((receiver_buffer_size & (receiver_buffer_size - 1)) == 0); + if (receiver_buffer_size == 0) { + receiver_buffer_size += 1; + } + + // Indicate RS485 not implemented + if ((rs485_dir != NULL) || (rs485_invert)) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("RS485")); + } + + if ((rx != NULL) && (tx != NULL)) { + err = MXC_UART_Init(self->uart_regs, baudrate, MXC_UART_IBRO_CLK); + if (err != E_NO_ERROR) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_UART); + } + + // attach & configure pins + self->tx_pin = tx; + self->rx_pin = rx; + common_hal_mcu_pin_claim(self->tx_pin); + common_hal_mcu_pin_claim(self->rx_pin); + } else { + mp_raise_NotImplementedError(MP_ERROR_TEXT("UART needs TX & RX")); + } + + if ((cts) && (rts)) { + MXC_UART_SetFlowCtrl(self->uart_regs, MXC_UART_FLOW_EN, 8); + self->cts_pin = cts; + self->rts_pin = rts; + common_hal_mcu_pin_claim(self->cts_pin); + common_hal_mcu_pin_claim(self->rts_pin); + } else if (cts || rts) { + mp_raise_ValueError(MP_ERROR_TEXT("Both RX and TX required for flow control")); + } + + // Set stop bits & data size + assert((stop == 1) || (stop == 2)); + mp_arg_validate_int(bits, 8, MP_QSTR_bits); + MXC_UART_SetDataSize(self->uart_regs, bits); + MXC_UART_SetStopBits(self->uart_regs, stop); + + // Set parity + MXC_UART_SetParity(self->uart_regs, convertParity(parity)); + + // attach UART parameters + self->stop_bits = stop; // must be 1 or 2 + self->bits = bits; + self->parity = parity; + self->baudrate = baudrate; + self->error = E_NO_ERROR; + + // Indicate to this module that the UART is active + uarts_active |= (1 << self->uart_id); + + // Set the timeout to a default value + if (((timeout < 0.0) || (timeout > 100.0))) { + self->timeout = 1.0; + } else { + self->timeout = timeout; + } + + // Initialize ringbuffer + if (receiver_buffer == NULL) { + self->ringbuf = m_malloc_without_collect(receiver_buffer_size); + if (!ringbuf_alloc(self->ringbuf, receiver_buffer_size)) { + m_malloc_fail(receiver_buffer_size); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to allocate %q buffer"), + MP_QSTR_UART); + } + } else { + if (!(ringbuf_init(self->ringbuf, receiver_buffer, receiver_buffer_size))) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Failed to allocate %q buffer"), + MP_QSTR_UART); + } + } + + context = self; + + // Setup UART interrupt + NVIC_ClearPendingIRQ(MXC_UART_GET_IRQ(self->uart_id)); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + NVIC_SetPriority(MXC_UART_GET_IRQ(self->uart_id), UART_PRIORITY); + NVIC_SetVector(MXC_UART_GET_IRQ(self->uart_id), (uint32_t)uart_isr); + + NVIC_EnableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + + return; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + assert(self); + + if (!common_hal_busio_uart_deinited(self)) { + // First disable the ISR to avoid pre-emption + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + + // Shutdown the UART Controller + MXC_UART_Shutdown(self->uart_regs); + self->error = E_UNINITIALIZED; + + assert(self->rx_pin && self->tx_pin); + reset_pin_number(self->rx_pin->port, self->rx_pin->mask); + reset_pin_number(self->tx_pin->port, self->tx_pin->mask); + + if (self->cts_pin && self->rts_pin) { + reset_pin_number(self->cts_pin->port, self->cts_pin->mask); + reset_pin_number(self->rts_pin->port, self->rts_pin->mask); + } + + self->tx_pin = NULL; + self->rx_pin = NULL; + self->cts_pin = NULL; + self->rts_pin = NULL; + + ringbuf_deinit(self->ringbuf); + + // Indicate to this module that the UART is not active + uarts_active &= ~(1 << self->uart_id); + } +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + if (uarts_active & (1 << self->uart_id)) { + return false; + } else { + return true; + }; +} + +// Read characters. len is in characters. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, + uint8_t *data, size_t len, int *errcode) { + int err; + uint32_t start_time = 0; + static size_t bytes_remaining; + + // Setup globals & status tracking + uart_err = E_NO_ERROR; + uarts_active |= (1 << self->uart_id); + uart_status[self->uart_id] = UART_BUSY; + bytes_remaining = len; + + mxc_uart_req_t uart_rd_req; + uart_rd_req.rxCnt = 0; + uart_rd_req.txCnt = 0; + uart_rd_req.rxData = data; + uart_rd_req.txData = NULL; + uart_rd_req.rxLen = bytes_remaining; + uart_rd_req.txLen = 0; + uart_rd_req.uart = self->uart_regs; + uart_rd_req.callback = (void *)uartCallback; + + // Initiate the read transaction + start_time = supervisor_ticks_ms64(); + err = MXC_UART_TransactionAsync(&uart_rd_req); + if (err != E_NO_ERROR) { + *errcode = err; + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("UART read error")); + } + + // Wait for transaction completion or timeout + while ((uart_status[self->uart_id] != UART_FREE) && + (supervisor_ticks_ms64() - start_time < (self->timeout * 1000))) { + } + + // If the timeout gets hit, abort and error out + if (uart_status[self->uart_id] != UART_FREE) { + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_RuntimeError(MP_ERROR_TEXT("UART transaction timeout")); + } + // Check for errors from the callback + else if (uart_err != E_NO_ERROR) { + mp_raise_RuntimeError(MP_ERROR_TEXT("UART read error")); + MXC_UART_AbortAsync(self->uart_regs); + } + + // Copy the data from the ringbuf (or return error) + MXC_SYS_Crit_Enter(); + err = ringbuf_get_n(context->ringbuf, data, len); + MXC_SYS_Crit_Exit(); + + return err; +} + +// Write characters. len is in characters NOT bytes! +// This function blocks until the timeout finishes +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, + const uint8_t *data, size_t len, int *errcode) { + int err; + static size_t bytes_remaining; + + // Setup globals & status tracking + uart_err = E_NO_ERROR; + uarts_active |= (1 << self->uart_id); + uart_status[self->uart_id] = UART_BUSY; + bytes_remaining = len; + + mxc_uart_req_t uart_wr_req = {}; + + // Setup transaction + uart_wr_req.rxCnt = 0; + uart_wr_req.txCnt = 0; + uart_wr_req.rxData = NULL; + uart_wr_req.txData = data; + uart_wr_req.txLen = bytes_remaining; + uart_wr_req.rxLen = 0; + uart_wr_req.uart = self->uart_regs; + uart_wr_req.callback = (void *)uartCallback; + + // Start the transaction + err = MXC_UART_TransactionAsync(&uart_wr_req); + if (err != E_NO_ERROR) { + *errcode = err; + MXC_UART_AbortAsync(self->uart_regs); + NVIC_DisableIRQ(MXC_UART_GET_IRQ(self->uart_id)); + mp_raise_ValueError(MP_ERROR_TEXT("All UART peripherals are in use")); + } + + // Wait for transaction completion + while (uart_status[self->uart_id] != UART_FREE) { + // Call the handler and abort if errors + uart_err = MXC_UART_AsyncHandler(self->uart_regs); + if (uart_err != E_NO_ERROR) { + MXC_UART_AbortAsync(self->uart_regs); + } + } + // Check for errors from the callback + if (uart_err != E_NO_ERROR) { + MXC_UART_AbortAsync(self->uart_regs); + } + + return len; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + return self->baudrate; +} + +// Validate baudrate +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + if (isValidBaudrate(baudrate)) { + self->baudrate = baudrate; + } else { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_baudrate); + } +} + +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return self->timeout; +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { + if (timeout > 100.0) { + mp_raise_ValueError(MP_ERROR_TEXT("Timeout must be < 100 seconds")); + } + + timeout_ms = 1000 * (uint32_t)timeout; + self->timeout = (uint32_t)timeout; + + return; +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + return ringbuf_num_filled(self->ringbuf); +} + +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { + MXC_UART_ClearRXFIFO(self->uart_regs); + ringbuf_clear(self->ringbuf); +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + return !(MXC_UART_GetStatus(self->uart_regs) & (MXC_F_UART_STATUS_TX_BUSY)); +} + +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { + common_hal_never_reset_pin(self->tx_pin); + common_hal_never_reset_pin(self->rx_pin); + common_hal_never_reset_pin(self->cts_pin); + common_hal_never_reset_pin(self->rts_pin); + uart_never_reset_mask |= (1 << (self->uart_id)); +} + +#endif // CIRCUITPY_BUSIO_UART diff --git a/ports/analog/common-hal/busio/UART.h b/ports/analog/common-hal/busio/UART.h new file mode 100644 index 00000000000..296c738772e --- /dev/null +++ b/ports/analog/common-hal/busio/UART.h @@ -0,0 +1,39 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#ifndef MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_UART_H +#define MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_UART_H + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" +#include "py/ringbuf.h" + +#include "max32_port.h" + +// Define a struct for what BUSIO.UART should contain +typedef struct { + mp_obj_base_t base; + int error; + float timeout; + + int uart_id; + int uart_map; + mxc_uart_regs_t *uart_regs; + ringbuf_t *ringbuf; + bool parity; + uint8_t bits; + uint8_t stop_bits; + uint32_t baudrate; + + const mcu_pin_obj_t *rx_pin; + const mcu_pin_obj_t *tx_pin; + const mcu_pin_obj_t *rts_pin; + const mcu_pin_obj_t *cts_pin; +} busio_uart_obj_t; + +void uart_reset(void); + +#endif // MICROPY_INCLUDED_MAX32_COMMON_HAL_BUSIO_UART_H diff --git a/ports/analog/common-hal/busio/__init__.c b/ports/analog/common-hal/busio/__init__.c new file mode 100644 index 00000000000..ff05be051bb --- /dev/null +++ b/ports/analog/common-hal/busio/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT diff --git a/ports/analog/common-hal/digitalio/DigitalInOut.c b/ports/analog/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 00000000000..93e2242fbb6 --- /dev/null +++ b/ports/analog/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,298 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE 1 +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "max32_port.h" +#include "gpio_reva.h" +#include "mxc_errors.h" + +extern mxc_gpio_regs_t *gpio_ports[NUM_GPIO_PORTS]; + +void common_hal_digitalio_digitalinout_never_reset( + digitalio_digitalinout_obj_t *self) { + common_hal_never_reset_pin(self->pin); +} + +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) { + return self->pin == NULL; +} + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) { + + common_hal_mcu_pin_claim(pin); + self->pin = pin; + self->open_drain = false; + self->vssel = MXC_GPIO_VSSEL_VDDIOH; + + mxc_gpio_cfg_t new_gpio_cfg = { + .port = gpio_ports[self->pin->port], + .mask = (self->pin->mask), + .vssel = self->vssel, + .func = MXC_GPIO_FUNC_IN, + .drvstr = MXC_GPIO_DRVSTR_0, + .pad = MXC_GPIO_PAD_NONE, + }; + MXC_GPIO_Config(&new_gpio_cfg); + + return DIGITALINOUT_OK; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } + + reset_pin_number(self->pin->port, self->pin->mask); + self->pin = NULL; +} + +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + mxc_gpio_regs_t *port = gpio_ports[self->pin->port]; + uint32_t mask = self->pin->mask; + + int err = E_NO_ERROR; + + if (self->pin->port == 4) { + // Set GPIO(s) to input mode + MXC_MCR->gpio4_ctrl &= ~GPIO4_OUTEN_MASK(mask); + MXC_MCR->outen &= ~GPIO4_AFEN_MASK(mask); + } else { + err = MXC_GPIO_RevA_SetAF((mxc_gpio_reva_regs_t *)port, MXC_GPIO_FUNC_IN, mask); + } + if (err != E_NO_ERROR) { + return DIGITALINOUT_PIN_BUSY; + } + return common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t *self, bool value, + digitalio_drive_mode_t drive_mode) { + mxc_gpio_regs_t *port = gpio_ports[self->pin->port]; + uint32_t mask = self->pin->mask; + + self->open_drain = (drive_mode == DRIVE_MODE_OPEN_DRAIN); + + // Set GPIO(s) to output mode + if (self->pin->port == 4) { + MXC_MCR->gpio4_ctrl |= GPIO4_OUTEN_MASK(mask); + MXC_MCR->outen &= ~GPIO4_AFEN_MASK(mask); + } else { + MXC_GPIO_RevA_SetAF((mxc_gpio_reva_regs_t *)port, MXC_GPIO_FUNC_OUT, mask); + } + + common_hal_digitalio_digitalinout_set_value(self, value); + + return DIGITALINOUT_OK; +} + +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t *self) { + + mxc_gpio_regs_t *port = gpio_ports[self->pin->port]; + uint32_t mask = self->pin->mask; + + // Open drain must be considered output for CircuitPython API to work properly + if (self->open_drain) { + return DIRECTION_OUTPUT; + } + + if (self->pin->port < 4) { + // Check that I/O mode is enabled and we don't have in AND out on at the same time + MP_STATIC_ASSERT_NONCONSTEXPR(!((port->en0 & mask) && (port->inen & mask) && (port->outen & mask))); + + if ((port->en0 & mask) && (port->outen & mask)) { + return DIRECTION_OUTPUT; + } else if ((port->en0 & mask) && (port->inen & mask)) { + return DIRECTION_INPUT; + // do not try to drive a pin which has an odd configuration here + } else { + return DIRECTION_INPUT; + } + } else { + if (MXC_MCR->gpio4_ctrl & GPIO4_OUTEN_MASK(mask)) { + return DIRECTION_OUTPUT; + } else { + return DIRECTION_INPUT; + } + } +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t *self, bool value) { + digitalio_direction_t dir = + common_hal_digitalio_digitalinout_get_direction(self); + + mxc_gpio_regs_t *port = gpio_ports[self->pin->port]; + uint32_t mask = self->pin->mask; + + MXC_GPIO_SetVSSEL(port, self->vssel, mask); + + if (self->open_drain) { + // Open-drain can be done by setting to input mode, no pullup/pulldown + // when the value is high (no sink current into GPIO) + if (value) { + // set to input, no pull + common_hal_digitalio_digitalinout_switch_to_input(self, PULL_NONE); + } else { + // can't use common_hal_switch_to_output b/c it calls this function + // set the GPIO to output, low + if (self->pin->port == 4) { + MXC_MCR->gpio4_ctrl |= GPIO4_OUTEN_MASK(mask); + MXC_MCR->outen &= ~GPIO4_AFEN_MASK(mask); + } else { + MXC_GPIO_RevA_SetAF((mxc_gpio_reva_regs_t *)port, MXC_GPIO_FUNC_OUT, mask); + } + MXC_GPIO_OutClr(port, mask); + } + } else if (dir == DIRECTION_OUTPUT) { + if (value) { + MXC_GPIO_OutSet(port, mask); + } else { + MXC_GPIO_OutClr(port, mask); + } + } +} + +bool common_hal_digitalio_digitalinout_get_value(digitalio_digitalinout_obj_t *self) { + digitalio_direction_t dir = + common_hal_digitalio_digitalinout_get_direction(self); + + mxc_gpio_regs_t *port = gpio_ports[self->pin->port]; + uint32_t mask = self->pin->mask; + + if (self->open_drain) { + return MXC_GPIO_InGet(port, mask) && mask; + } + + if (dir == DIRECTION_INPUT) { + if (self->pin->port == 4) { + return (bool)(MXC_MCR->gpio4_ctrl & GPIO4_DATAIN_MASK(mask)); + } + return MXC_GPIO_InGet(port, mask) && mask; + } else { + return MXC_GPIO_OutGet(port, mask) && mask; + } +} + +digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t *self, digitalio_drive_mode_t drive_mode) { + + // Check what the current value is + bool value = common_hal_digitalio_digitalinout_get_value(self); + self->open_drain = (drive_mode == DRIVE_MODE_OPEN_DRAIN); + + // Re-set the value to account for different setting methods for drive types + // Switch to output will both set the output config + // AND set the value for the new drive type + common_hal_digitalio_digitalinout_switch_to_output(self, value, drive_mode); + + return DIGITALINOUT_OK; +} + +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t *self) { + if (self->open_drain) { + return DRIVE_MODE_OPEN_DRAIN; + } else { + return DRIVE_MODE_PUSH_PULL; + } +} + +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + + mxc_gpio_regs_t *port = gpio_ports[self->pin->port]; + uint32_t mask = self->pin->mask; + + // GPIO4 handling + if (self->pin->port == 4) { + switch (pull) { + case PULL_NONE: + // disable pullup/pulldown + MXC_MCR->gpio4_ctrl |= GPIO4_PULLDIS_MASK(mask); + break; + case PULL_UP: + // enable pullup/pulldown (clear the mask) + // then set output value to 1 + MXC_MCR->gpio4_ctrl &= ~(GPIO4_PULLDIS_MASK(mask)); + MXC_MCR->gpio4_ctrl |= GPIO4_DATAOUT_MASK(mask); + break; + case PULL_DOWN: + // enable pullup/pulldown (clear the mask) + // then clear output value to 0 + MXC_MCR->gpio4_ctrl &= ~(GPIO4_PULLDIS_MASK(mask)); + MXC_MCR->gpio4_ctrl &= ~(GPIO4_DATAOUT_MASK(mask)); + break; + default: + break; + } + return DIGITALINOUT_OK; + } else { + // padctrl registers only work in input mode + if ((mask & port->en0) & (mask & ~(port->outen))) { + // PULL_NONE, PULL_UP, or PULL_DOWN + switch (pull) { + case PULL_NONE: + port->padctrl0 &= ~(mask); + port->padctrl1 &= ~(mask); + break; + case PULL_UP: + port->padctrl0 |= mask; + port->padctrl1 &= ~(mask); + port->ps &= ~(mask); + break; + case PULL_DOWN: + port->padctrl0 &= ~mask; + port->padctrl1 |= mask; + port->ps &= ~mask; + break; + default: + break; + } + return DIGITALINOUT_OK; + } else { + return DIGITALINOUT_PIN_BUSY; + } + } +} + +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t *self) { + + mxc_gpio_regs_t *port = gpio_ports[self->pin->port]; + uint32_t mask = self->pin->mask; + + bool pin_padctrl0 = (port->padctrl0) & (mask); + bool pin_padctrl1 = (port->padctrl1) & (mask); + + if (self->pin->port == 4) { + if (MXC_MCR->gpio4_ctrl & GPIO4_PULLDIS_MASK(mask)) { + return PULL_NONE; + } else { + if (MXC_MCR->gpio4_ctrl & GPIO4_DATAOUT_MASK(mask)) { + return PULL_UP; + } else { + return PULL_DOWN; + } + } + } else { + if ((pin_padctrl0) && !(pin_padctrl1)) { + return PULL_UP; + } else if (!(pin_padctrl0) && pin_padctrl1) { + return PULL_DOWN; + } else if (!(pin_padctrl0) && !(pin_padctrl1)) { + return PULL_NONE; + } else { + return PULL_NONE; + } + } +} diff --git a/ports/analog/common-hal/digitalio/DigitalInOut.h b/ports/analog/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 00000000000..d10345fa3fa --- /dev/null +++ b/ports/analog/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,17 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2019 Lucian Copeland for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + bool open_drain; + mxc_gpio_vssel_t vssel; +} digitalio_digitalinout_obj_t; diff --git a/ports/analog/common-hal/digitalio/__init__.c b/ports/analog/common-hal/digitalio/__init__.c new file mode 100644 index 00000000000..fa222ed01f0 --- /dev/null +++ b/ports/analog/common-hal/digitalio/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// No digitalio module functions. diff --git a/ports/analog/common-hal/microcontroller/Pin.c b/ports/analog/common-hal/microcontroller/Pin.c new file mode 100644 index 00000000000..83e2f3b9c3a --- /dev/null +++ b/ports/analog/common-hal/microcontroller/Pin.c @@ -0,0 +1,113 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/microcontroller/Pin.h" +#include "mpconfigboard.h" +#include "pins.h" + +#include "max32_port.h" + +#include "common-hal/microcontroller/Pin.h" + +static uint32_t claimed_pins[NUM_GPIO_PORTS]; + +// defined in board.c +extern mxc_gpio_regs_t *gpio_ports[NUM_GPIO_PORTS]; + +static uint32_t never_reset_pins[NUM_GPIO_PORTS]; + +#define INVALID_PIN 0xFF // id for invalid pin + +void reset_all_pins(void) { + // reset all pins except for never_reset_pins + for (int i = 0; i < NUM_GPIO_PORTS; i++) { + for (int j = 0; j < 32; j++) { + if (!(never_reset_pins[i] & (1 << j))) { + reset_pin_number(i, j); + } + } + // set claimed pins to never_reset pins + claimed_pins[i] = never_reset_pins[i]; + } +} + +void reset_pin_number(uint8_t pin_port, uint8_t pin_pad) { + if ((pin_port == INVALID_PIN) || (pin_port > NUM_GPIO_PORTS)) { + return; + } + + uint32_t mask = 1 << (pin_pad); + + /** START: RESET LOGIC for GPIOs */ + // Switch to I/O mode first + gpio_ports[pin_port]->en0_set = mask; + + // set GPIO configuration enable bits to I/O + gpio_ports[pin_port]->en0_clr = mask; + gpio_ports[pin_port]->en1_clr = mask; + gpio_ports[pin_port]->en2_clr = mask; + + // enable input mode GPIOn_INEN.pin = 1 + gpio_ports[pin_port]->inen |= mask; + + // High Impedance mode enable (GPIOn_PADCTRL1 = 0, _PADCTRL0 = 0), pu/pd disable + gpio_ports[pin_port]->padctrl0 &= ~mask; + gpio_ports[pin_port]->padctrl1 &= ~mask; + + // Output mode disable GPIOn_OUTEN = 0 + gpio_ports[pin_port]->outen |= mask; + + // Interrupt disable GPIOn_INTEN = 0 + gpio_ports[pin_port]->inten &= ~mask; + /** END: RESET LOGIC for GPIOs */ +} + +uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t *pin) { + if (pin == NULL) { + return INVALID_PIN; + } + + // most max32 gpio ports have 32 pins + // todo (low prior.): encode # of pins for each port, since some GPIO ports differ + return pin->port * 32 + pin->mask; +} + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { + if (pin == NULL) { + return true; + } + return !(claimed_pins[pin->port] & (pin->mask)); +} + +void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) { + if ((pin != NULL) && (pin->mask != INVALID_PIN)) { + never_reset_pins[pin->port] |= (1 << pin->mask); + + // any never reset pin must also be claimed + claimed_pins[pin->port] |= (1 << pin->mask); + } +} + +void common_hal_reset_pin(const mcu_pin_obj_t *pin) { + if (pin == NULL) { + return; + } + + reset_pin_number(pin->port, pin->mask); +} + +void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) { + if (pin == NULL) { + return; + } + claimed_pins[pin->port] |= (1 << pin->mask); +} + +void common_hal_mcu_pin_reset_number(uint8_t pin_no) { + reset_pin_number(pin_no / 32, pin_no & 32); +} diff --git a/ports/analog/common-hal/microcontroller/Pin.h b/ports/analog/common-hal/microcontroller/Pin.h new file mode 100644 index 00000000000..169586e7e90 --- /dev/null +++ b/ports/analog/common-hal/microcontroller/Pin.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/mphal.h" + +#include "peripherals/pins.h" + +void reset_all_pins(void); +// reset_pin_number takes the pin number instead of the pointer so that objects don't +// need to store a full pointer. +void reset_pin_number(uint8_t pin_port, uint8_t pin_pad); diff --git a/ports/analog/common-hal/microcontroller/Processor.c b/ports/analog/common-hal/microcontroller/Processor.c new file mode 100644 index 00000000000..3695ecdf671 --- /dev/null +++ b/ports/analog/common-hal/microcontroller/Processor.c @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#include +#include "py/runtime.h" + +#if CIRCUITPY_ALARM +#include "common-hal/alarm/__init__.h" +#endif + +#include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/ResetReason.h" + +#include "max32_port.h" + +// No means of getting core temperature for currently supported devices +float common_hal_mcu_processor_get_temperature(void) { + return NAN; +} + +// MAX32690 can measure VCORE +// TODO: (low prior.) Implement ADC API under "peripherals" and use API to measure VCORE +float common_hal_mcu_processor_get_voltage(void) { + return NAN; +} + +uint32_t common_hal_mcu_processor_get_frequency(void) { + return SystemCoreClock; +} + +// NOTE: COMMON_HAL_MCU_PROCESSOR_UID_LENGTH is defined in mpconfigboard.h +// Use this per device to make sure raw_id is an appropriate minimum number of bytes +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + MXC_SYS_GetUSN(raw_id, NULL); // NULL checksum will not be verified by AES + return; +} + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + #if CIRCUITPY_ALARM + // TODO: (low prior.) add reset reason in alarm / deepsleep cases (should require alarm peripheral API in "peripherals") + #endif + return MCU_RESET_REASON_UNKNOWN; +} diff --git a/ports/analog/common-hal/microcontroller/Processor.h b/ports/analog/common-hal/microcontroller/Processor.h new file mode 100644 index 00000000000..aab7727550a --- /dev/null +++ b/ports/analog/common-hal/microcontroller/Processor.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 12 + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} mcu_processor_obj_t; diff --git a/ports/analog/common-hal/microcontroller/__init__.c b/ports/analog/common-hal/microcontroller/__init__.c new file mode 100644 index 00000000000..207ddbe52f3 --- /dev/null +++ b/ports/analog/common-hal/microcontroller/__init__.c @@ -0,0 +1,408 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SP3_X-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft for Adafruit Industries +// SP3_X-FileCopyrightText: Copyright (c) 2019 Lucian Copeland for Adafruit Industries +// SP3_X-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SP3_X-License-Identifier: MIT + +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Processor.h" + +// #include "shared-bindings/nvm/ByteArray.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" +#include "supervisor/port.h" +#include "supervisor/filesystem.h" +#include "supervisor/shared/safe_mode.h" + + +#include "max32690.h" +#include "mxc_delay.h" + +/** NOTE: It is not advised to directly include the below! + * These are includes taken care of by the core cmsis file. + * e.g. "max32690.h". Since CMSIS is compiled as lib, these are + * included there as for example. +*/ +// #include // For enable/disable interrupts +// #include // For NVIC_SystemReset +// #include // For __DMB Data Memory Barrier (flush DBUS activity) + +void common_hal_mcu_delay_us(uint32_t delay) { + + MXC_Delay(MXC_DELAY_USEC(delay)); +} + +volatile uint32_t nesting_count = 0; + +void common_hal_mcu_disable_interrupts(void) { + __disable_irq(); + __DMB(); + nesting_count++; +} + +void common_hal_mcu_enable_interrupts(void) { + if (nesting_count == 0) { + // This is very very bad because it means there was mismatched disable/enables. + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); + } + nesting_count--; + if (nesting_count > 0) { + return; + } + __DMB(); // flush internal DBUS before proceeding + __enable_irq(); +} + +static bool next_reset_to_bootloader = false; + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + if (runmode == RUNMODE_SAFE_MODE) { + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); + } + if (runmode == RUNMODE_BOOTLOADER) { + next_reset_to_bootloader = true; + } +} + +void common_hal_mcu_reset(void) { + if (next_reset_to_bootloader) { + reset_to_bootloader(); + } else { + NVIC_SystemReset(); + } +} + +// The singleton microcontroller.Processor object, bound to microcontroller.cpu +// It currently only has properties, and no state. +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +// This maps MCU pin names to pin objects. +static const mp_rom_map_elem_t mcu_pin_global_dict_table[] = { + #if defined(PIN_P0_01) && !defined(IGNORE_PIN_P0_01) + { MP_ROM_QSTR(MP_QSTR_P0_01), MP_ROM_PTR(&pin_P0_01) }, + #endif + #if defined(PIN_P0_02) && !defined(IGNORE_PIN_P0_02) + { MP_ROM_QSTR(MP_QSTR_P0_02), MP_ROM_PTR(&pin_P0_02) }, + #endif + #if defined(PIN_P0_03) && !defined(IGNORE_PIN_P0_03) + { MP_ROM_QSTR(MP_QSTR_P0_03), MP_ROM_PTR(&pin_P0_03) }, + #endif + #if defined(PIN_P0_04) && !defined(IGNORE_PIN_P0_04) + { MP_ROM_QSTR(MP_QSTR_P0_04), MP_ROM_PTR(&pin_P0_04) }, + #endif + #if defined(PIN_P0_05) && !defined(IGNORE_PIN_P0_05) + { MP_ROM_QSTR(MP_QSTR_P0_05), MP_ROM_PTR(&pin_P0_05) }, + #endif + #if defined(PIN_P0_06) && !defined(IGNORE_PIN_P0_06) + { MP_ROM_QSTR(MP_QSTR_P0_06), MP_ROM_PTR(&pin_P0_06) }, + #endif + #if defined(PIN_P0_07) && !defined(IGNORE_PIN_P0_07) + { MP_ROM_QSTR(MP_QSTR_P0_07), MP_ROM_PTR(&pin_P0_07) }, + #endif + #if defined(PIN_P0_08) && !defined(IGNORE_PIN_P0_08) + { MP_ROM_QSTR(MP_QSTR_P0_08), MP_ROM_PTR(&pin_P0_08) }, + #endif + #if defined(PIN_P0_09) && !defined(IGNORE_PIN_P0_09) + { MP_ROM_QSTR(MP_QSTR_P0_09), MP_ROM_PTR(&pin_P0_09) }, + #endif + #if defined(PIN_P0_10) && !defined(IGNORE_PIN_P0_10) + { MP_ROM_QSTR(MP_QSTR_P0_10), MP_ROM_PTR(&pin_P0_10) }, + #endif + #if defined(PIN_P0_11) && !defined(IGNORE_PIN_P0_11) + { MP_ROM_QSTR(MP_QSTR_P0_11), MP_ROM_PTR(&pin_P0_11) }, + #endif + #if defined(PIN_P0_12) && !defined(IGNORE_PIN_P0_12) + { MP_ROM_QSTR(MP_QSTR_P0_12), MP_ROM_PTR(&pin_P0_12) }, + #endif + #if defined(PIN_P0_13) && !defined(IGNORE_PIN_P0_13) + { MP_ROM_QSTR(MP_QSTR_P0_13), MP_ROM_PTR(&pin_P0_13) }, + #endif + #if defined(PIN_P0_14) && !defined(IGNORE_PIN_P0_14) + { MP_ROM_QSTR(MP_QSTR_P0_14), MP_ROM_PTR(&pin_P0_14) }, + #endif + #if defined(PIN_P0_15) && !defined(IGNORE_PIN_P0_15) + { MP_ROM_QSTR(MP_QSTR_P0_15), MP_ROM_PTR(&pin_P0_15) }, + #endif + #if defined(PIN_P0_16) && !defined(IGNORE_PIN_P0_16) + { MP_ROM_QSTR(MP_QSTR_P0_16), MP_ROM_PTR(&pin_P0_16) }, + #endif + #if defined(PIN_P0_17) && !defined(IGNORE_PIN_P0_17) + { MP_ROM_QSTR(MP_QSTR_P0_17), MP_ROM_PTR(&pin_P0_17) }, + #endif + #if defined(PIN_P0_18) && !defined(IGNORE_PIN_P0_18) + { MP_ROM_QSTR(MP_QSTR_P0_18), MP_ROM_PTR(&pin_P0_18) }, + #endif + #if defined(PIN_P0_19) && !defined(IGNORE_PIN_P0_19) + { MP_ROM_QSTR(MP_QSTR_P0_19), MP_ROM_PTR(&pin_P0_19) }, + #endif + #if defined(PIN_P0_20) && !defined(IGNORE_PIN_P0_20) + { MP_ROM_QSTR(MP_QSTR_P0_20), MP_ROM_PTR(&pin_P0_20) }, + #endif + #if defined(PIN_P0_21) && !defined(IGNORE_PIN_P0_21) + { MP_ROM_QSTR(MP_QSTR_P0_21), MP_ROM_PTR(&pin_P0_21) }, + #endif + #if defined(PIN_P0_22) && !defined(IGNORE_PIN_P0_22) + { MP_ROM_QSTR(MP_QSTR_P0_22), MP_ROM_PTR(&pin_P0_22) }, + #endif + #if defined(PIN_P0_23) && !defined(IGNORE_PIN_P0_23) + { MP_ROM_QSTR(MP_QSTR_P0_23), MP_ROM_PTR(&pin_P0_23) }, + #endif + #if defined(PIN_P0_24) && !defined(IGNORE_PIN_P0_24) + { MP_ROM_QSTR(MP_QSTR_P0_24), MP_ROM_PTR(&pin_P0_24) }, + #endif + #if defined(PIN_P0_25) && !defined(IGNORE_PIN_P0_25) + { MP_ROM_QSTR(MP_QSTR_P0_25), MP_ROM_PTR(&pin_P0_25) }, + #endif + #if defined(PIN_P0_27) && !defined(IGNORE_PIN_P0_27) + { MP_ROM_QSTR(MP_QSTR_P0_27), MP_ROM_PTR(&pin_P0_27) }, + #endif + #if defined(PIN_P0_28) && !defined(IGNORE_PIN_P0_28) + { MP_ROM_QSTR(MP_QSTR_P0_28), MP_ROM_PTR(&pin_P0_28) }, + #endif + #if defined(PIN_P0_30) && !defined(IGNORE_PIN_P0_30) + { MP_ROM_QSTR(MP_QSTR_P0_30), MP_ROM_PTR(&pin_P0_30) }, + #endif + #if defined(PIN_P0_31) && !defined(IGNORE_PIN_P0_31) + { MP_ROM_QSTR(MP_QSTR_P0_31), MP_ROM_PTR(&pin_P0_31) }, + #endif + + #if defined(PIN_P1_01) && !defined(IGNORE_PIN_P1_01) + { MP_ROM_QSTR(MP_QSTR_P1_01), MP_ROM_PTR(&pin_P1_01) }, + #endif + #if defined(PIN_P1_02) && !defined(IGNORE_PIN_P1_02) + { MP_ROM_QSTR(MP_QSTR_P1_02), MP_ROM_PTR(&pin_P1_02) }, + #endif + #if defined(PIN_P1_03) && !defined(IGNORE_PIN_P1_03) + { MP_ROM_QSTR(MP_QSTR_P1_03), MP_ROM_PTR(&pin_P1_03) }, + #endif + #if defined(PIN_P1_04) && !defined(IGNORE_PIN_P1_04) + { MP_ROM_QSTR(MP_QSTR_P1_04), MP_ROM_PTR(&pin_P1_04) }, + #endif + #if defined(PIN_P1_05) && !defined(IGNORE_PIN_P1_05) + { MP_ROM_QSTR(MP_QSTR_P1_05), MP_ROM_PTR(&pin_P1_05) }, + #endif + #if defined(PIN_P1_06) && !defined(IGNORE_PIN_P1_06) + { MP_ROM_QSTR(MP_QSTR_P1_06), MP_ROM_PTR(&pin_P1_06) }, + #endif + #if defined(PIN_P1_07) && !defined(IGNORE_PIN_P1_07) + { MP_ROM_QSTR(MP_QSTR_P1_07), MP_ROM_PTR(&pin_P1_07) }, + #endif + #if defined(PIN_P1_08) && !defined(IGNORE_PIN_P1_08) + { MP_ROM_QSTR(MP_QSTR_P1_08), MP_ROM_PTR(&pin_P1_08) }, + #endif + #if defined(PIN_P1_09) && !defined(IGNORE_PIN_P1_09) + { MP_ROM_QSTR(MP_QSTR_P1_09), MP_ROM_PTR(&pin_P1_09) }, + #endif + #if defined(PIN_P1_10) && !defined(IGNORE_PIN_P1_10) + { MP_ROM_QSTR(MP_QSTR_P1_10), MP_ROM_PTR(&pin_P1_10) }, + #endif + #if defined(PIN_P1_11) && !defined(IGNORE_PIN_P1_11) + { MP_ROM_QSTR(MP_QSTR_P1_11), MP_ROM_PTR(&pin_P1_11) }, + #endif + #if defined(PIN_P1_12) && !defined(IGNORE_PIN_P1_12) + { MP_ROM_QSTR(MP_QSTR_P1_12), MP_ROM_PTR(&pin_P1_12) }, + #endif + #if defined(PIN_P1_13) && !defined(IGNORE_PIN_P1_13) + { MP_ROM_QSTR(MP_QSTR_P1_13), MP_ROM_PTR(&pin_P1_13) }, + #endif + #if defined(PIN_P1_14) && !defined(IGNORE_PIN_P1_14) + { MP_ROM_QSTR(MP_QSTR_P1_14), MP_ROM_PTR(&pin_P1_14) }, + #endif + #if defined(PIN_P1_15) && !defined(IGNORE_PIN_P1_15) + { MP_ROM_QSTR(MP_QSTR_P1_15), MP_ROM_PTR(&pin_P1_15) }, + #endif + #if defined(PIN_P1_16) && !defined(IGNORE_PIN_P1_16) + { MP_ROM_QSTR(MP_QSTR_P1_16), MP_ROM_PTR(&pin_P1_16) }, + #endif + #if defined(PIN_P1_17) && !defined(IGNORE_PIN_P1_17) + { MP_ROM_QSTR(MP_QSTR_P1_17), MP_ROM_PTR(&pin_P1_17) }, + #endif + #if defined(PIN_P1_18) && !defined(IGNORE_PIN_P1_18) + { MP_ROM_QSTR(MP_QSTR_P1_18), MP_ROM_PTR(&pin_P1_18) }, + #endif + #if defined(PIN_P1_19) && !defined(IGNORE_PIN_P1_19) + { MP_ROM_QSTR(MP_QSTR_P1_19), MP_ROM_PTR(&pin_P1_19) }, + #endif + #if defined(PIN_P1_20) && !defined(IGNORE_PIN_P1_20) + { MP_ROM_QSTR(MP_QSTR_P1_20), MP_ROM_PTR(&pin_P1_20) }, + #endif + #if defined(PIN_P1_21) && !defined(IGNORE_PIN_P1_21) + { MP_ROM_QSTR(MP_QSTR_P1_21), MP_ROM_PTR(&pin_P1_21) }, + #endif + #if defined(PIN_P1_22) && !defined(IGNORE_PIN_P1_22) + { MP_ROM_QSTR(MP_QSTR_P1_22), MP_ROM_PTR(&pin_P1_22) }, + #endif + #if defined(PIN_P1_23) && !defined(IGNORE_PIN_P1_23) + { MP_ROM_QSTR(MP_QSTR_P1_23), MP_ROM_PTR(&pin_P1_23) }, + #endif + #if defined(PIN_P1_24) && !defined(IGNORE_PIN_P1_24) + { MP_ROM_QSTR(MP_QSTR_P1_24), MP_ROM_PTR(&pin_P1_24) }, + #endif + #if defined(PIN_P1_25) && !defined(IGNORE_PIN_P1_25) + { MP_ROM_QSTR(MP_QSTR_P1_25), MP_ROM_PTR(&pin_P1_25) }, + #endif + #if defined(PIN_P1_26) && !defined(IGNORE_PIN_P1_26) + { MP_ROM_QSTR(MP_QSTR_P1_26), MP_ROM_PTR(&pin_P1_26) }, + #endif + #if defined(PIN_P1_27) && !defined(IGNORE_PIN_P1_27) + { MP_ROM_QSTR(MP_QSTR_P1_27), MP_ROM_PTR(&pin_P1_27) }, + #endif + #if defined(PIN_P1_28) && !defined(IGNORE_PIN_P1_28) + { MP_ROM_QSTR(MP_QSTR_P1_28), MP_ROM_PTR(&pin_P1_28) }, + #endif + #if defined(PIN_P1_29) && !defined(IGNORE_PIN_P1_29) + { MP_ROM_QSTR(MP_QSTR_P1_29), MP_ROM_PTR(&pin_P1_29) }, + #endif + #if defined(PIN_P1_30) && !defined(IGNORE_PIN_P1_30) + { MP_ROM_QSTR(MP_QSTR_P1_30), MP_ROM_PTR(&pin_P1_30) }, + #endif + #if defined(PIN_P1_31) && !defined(IGNORE_PIN_P1_31) + { MP_ROM_QSTR(MP_QSTR_P1_31), MP_ROM_PTR(&pin_P1_31) }, + #endif + + #if defined(PIN_P2_01) && !defined(IGNORE_PIN_P2_01) + { MP_ROM_QSTR(MP_QSTR_P2_01), MP_ROM_PTR(&pin_P2_01) }, + #endif + #if defined(PIN_P2_02) && !defined(IGNORE_PIN_P2_02) + { MP_ROM_QSTR(MP_QSTR_P2_02), MP_ROM_PTR(&pin_P2_02) }, + #endif + #if defined(PIN_P2_03) && !defined(IGNORE_PIN_P2_03) + { MP_ROM_QSTR(MP_QSTR_P2_03), MP_ROM_PTR(&pin_P2_03) }, + #endif + #if defined(PIN_P2_04) && !defined(IGNORE_PIN_P2_04) + { MP_ROM_QSTR(MP_QSTR_P2_04), MP_ROM_PTR(&pin_P2_04) }, + #endif + #if defined(PIN_P2_05) && !defined(IGNORE_PIN_P2_05) + { MP_ROM_QSTR(MP_QSTR_P2_05), MP_ROM_PTR(&pin_P2_05) }, + #endif + #if defined(PIN_P2_06) && !defined(IGNORE_PIN_P2_06) + { MP_ROM_QSTR(MP_QSTR_P2_06), MP_ROM_PTR(&pin_P2_06) }, + #endif + #if defined(PIN_P2_07) && !defined(IGNORE_PIN_P2_07) + { MP_ROM_QSTR(MP_QSTR_P2_07), MP_ROM_PTR(&pin_P2_07) }, + #endif + #if defined(PIN_P2_10) && !defined(IGNORE_PIN_P2_10) + { MP_ROM_QSTR(MP_QSTR_P2_10), MP_ROM_PTR(&pin_P2_10) }, + #endif + #if defined(PIN_P2_11) && !defined(IGNORE_PIN_P2_11) + { MP_ROM_QSTR(MP_QSTR_P2_11), MP_ROM_PTR(&pin_P2_11) }, + #endif + #if defined(PIN_P2_12) && !defined(IGNORE_PIN_P2_12) + { MP_ROM_QSTR(MP_QSTR_P2_12), MP_ROM_PTR(&pin_P2_12) }, + #endif + #if defined(PIN_P2_13) && !defined(IGNORE_PIN_P2_13) + { MP_ROM_QSTR(MP_QSTR_P2_13), MP_ROM_PTR(&pin_P2_13) }, + #endif + #if defined(PIN_P2_14) && !defined(IGNORE_PIN_P2_14) + { MP_ROM_QSTR(MP_QSTR_P2_14), MP_ROM_PTR(&pin_P2_14) }, + #endif + #if defined(PIN_P2_15) && !defined(IGNORE_PIN_P2_15) + { MP_ROM_QSTR(MP_QSTR_P2_15), MP_ROM_PTR(&pin_P2_15) }, + #endif + #if defined(PIN_P2_16) && !defined(IGNORE_PIN_P2_16) + { MP_ROM_QSTR(MP_QSTR_P2_16), MP_ROM_PTR(&pin_P2_16) }, + #endif + #if defined(PIN_P2_17) && !defined(IGNORE_PIN_P2_17) + { MP_ROM_QSTR(MP_QSTR_P2_17), MP_ROM_PTR(&pin_P2_17) }, + #endif + #if defined(PIN_P2_18) && !defined(IGNORE_PIN_P2_18) + { MP_ROM_QSTR(MP_QSTR_P2_18), MP_ROM_PTR(&pin_P2_18) }, + #endif + #if defined(PIN_P2_19) && !defined(IGNORE_PIN_P2_19) + { MP_ROM_QSTR(MP_QSTR_P2_19), MP_ROM_PTR(&pin_P2_19) }, + #endif + #if defined(PIN_P2_20) && !defined(IGNORE_PIN_P2_20) + { MP_ROM_QSTR(MP_QSTR_P2_20), MP_ROM_PTR(&pin_P2_20) }, + #endif + #if defined(PIN_P2_21) && !defined(IGNORE_PIN_P2_21) + { MP_ROM_QSTR(MP_QSTR_P2_21), MP_ROM_PTR(&pin_P2_21) }, + #endif + #if defined(PIN_P2_22) && !defined(IGNORE_PIN_P2_22) + { MP_ROM_QSTR(MP_QSTR_P2_22), MP_ROM_PTR(&pin_P2_22) }, + #endif + #if defined(PIN_P2_23) && !defined(IGNORE_PIN_P2_23) + { MP_ROM_QSTR(MP_QSTR_P2_23), MP_ROM_PTR(&pin_P2_23) }, + #endif + #if defined(PIN_P2_24) && !defined(IGNORE_PIN_P2_24) + { MP_ROM_QSTR(MP_QSTR_P2_24), MP_ROM_PTR(&pin_P2_24) }, + #endif + #if defined(PIN_P2_25) && !defined(IGNORE_PIN_P2_25) + { MP_ROM_QSTR(MP_QSTR_P2_25), MP_ROM_PTR(&pin_P2_25) }, + #endif + #if defined(PIN_P2_26) && !defined(IGNORE_PIN_P2_26) + { MP_ROM_QSTR(MP_QSTR_P2_26), MP_ROM_PTR(&pin_P2_26) }, + #endif + #if defined(PIN_P2_27) && !defined(IGNORE_PIN_P2_27) + { MP_ROM_QSTR(MP_QSTR_P2_27), MP_ROM_PTR(&pin_P2_27) }, + #endif + #if defined(PIN_P2_28) && !defined(IGNORE_PIN_P2_28) + { MP_ROM_QSTR(MP_QSTR_P2_28), MP_ROM_PTR(&pin_P2_28) }, + #endif + #if defined(PIN_P2_30) && !defined(IGNORE_PIN_P2_30) + { MP_ROM_QSTR(MP_QSTR_P2_30), MP_ROM_PTR(&pin_P2_30) }, + #endif + #if defined(PIN_P2_31) && !defined(IGNORE_PIN_P2_31) + { MP_ROM_QSTR(MP_QSTR_P2_31), MP_ROM_PTR(&pin_P2_31) }, + #endif + + #if defined(PIN_P3_01) && !defined(IGNORE_PIN_P3_01) + { MP_ROM_QSTR(MP_QSTR_P3_01), MP_ROM_PTR(&pin_P3_01) }, + #endif + #if defined(PIN_P3_02) && !defined(IGNORE_PIN_P3_02) + { MP_ROM_QSTR(MP_QSTR_P3_02), MP_ROM_PTR(&pin_P3_02) }, + #endif + #if defined(PIN_P3_03) && !defined(IGNORE_PIN_P3_03) + { MP_ROM_QSTR(MP_QSTR_P3_03), MP_ROM_PTR(&pin_P3_03) }, + #endif + #if defined(PIN_P3_04) && !defined(IGNORE_PIN_P3_04) + { MP_ROM_QSTR(MP_QSTR_P3_04), MP_ROM_PTR(&pin_P3_04) }, + #endif + #if defined(PIN_P3_05) && !defined(IGNORE_PIN_P3_05) + { MP_ROM_QSTR(MP_QSTR_P3_05), MP_ROM_PTR(&pin_P3_05) }, + #endif + #if defined(PIN_P3_06) && !defined(IGNORE_PIN_P3_06) + { MP_ROM_QSTR(MP_QSTR_P3_06), MP_ROM_PTR(&pin_P3_06) }, + #endif + #if defined(PIN_P3_07) && !defined(IGNORE_PIN_P3_07) + { MP_ROM_QSTR(MP_QSTR_P3_07), MP_ROM_PTR(&pin_P3_07) }, + #endif + #if defined(PIN_P3_08) && !defined(IGNORE_PIN_P3_08) + { MP_ROM_QSTR(MP_QSTR_P3_08), MP_ROM_PTR(&pin_P3_08) }, + #endif + #if defined(PIN_P3_09) && !defined(IGNORE_PIN_P3_09) + { MP_ROM_QSTR(MP_QSTR_P3_09), MP_ROM_PTR(&pin_P3_09) }, + #endif + + #if defined(PIN_P4_01) && !defined(IGNORE_PIN_P4_01) + { MP_ROM_QSTR(MP_QSTR_P4_01), MP_ROM_PTR(&pin_P4_02) }, + #endif + #if defined(PIN_P4_02) && !defined(IGNORE_PIN_P4_02) + { MP_ROM_QSTR(MP_QSTR_P4_01), MP_ROM_PTR(&pin_P4_02) }, + #endif + +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table); + + +/** NOTE: Not implemented yet */ +// #if CIRCUITPY_INTERNAL_NVM_SIZE > 0 +// // The singleton nvm.ByteArray object. +// const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { +// .base = { +// .type = &nvm_bytearray_type, +// }, +// .len = NVM_BYTEARRAY_BUFFER_SIZE, +// .start_address = (uint8_t *)(CIRCUITPY_INTERNAL_NVM_START_ADDR) +// }; +// #endif diff --git a/ports/analog/common-hal/os/__init__.c b/ports/analog/common-hal/os/__init__.c new file mode 100644 index 00000000000..508b40798e2 --- /dev/null +++ b/ports/analog/common-hal/os/__init__.c @@ -0,0 +1,30 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2019 Lucian Copeland for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "py/objstr.h" +#include "py/objtuple.h" + +#include "py/mperrno.h" +#include "py/runtime.h" + +// #include "peripherals/periph.h" + +// true random number generator, TRNG +#include "trng.h" + +bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { + #if (HAS_TRNG) + // get a random number of "length" number of bytes + MXC_TRNG_Random(buffer, length); + return true; + #else + #endif + return false; +} diff --git a/ports/analog/common-hal/rtc/RTC.c b/ports/analog/common-hal/rtc/RTC.c new file mode 100644 index 00000000000..c9d2258c1ec --- /dev/null +++ b/ports/analog/common-hal/rtc/RTC.c @@ -0,0 +1,42 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Nick Moore for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2019 Artur Pacholec +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" +#include "shared/timeutils/timeutils.h" +#include "supervisor/port.h" + +// This is the time in seconds since 2000 that the RTC was started. +// TODO: Change the offset to ticks so that it can be a subsecond adjustment. +static uint32_t rtc_offset = 0; + +void common_hal_rtc_get_time(timeutils_struct_time_t *tm) { + uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; + timeutils_seconds_since_2000_to_struct_time(rtc_offset + ticks_s, tm); +} + +void common_hal_rtc_set_time(timeutils_struct_time_t *tm) { + uint64_t ticks_s = port_get_raw_ticks(NULL) / 1024; + uint32_t epoch_s = timeutils_seconds_since_2000( + tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec + ); + rtc_offset = epoch_s - ticks_s; +} + +// the calibration function will be implemented in near future +// the RTC oscillator on my MAX32690-APARD is only off by 0.001 second +// the inaccuracy is still tolerable +int common_hal_rtc_get_calibration(void) { + return 0; +} + +void common_hal_rtc_set_calibration(int calibration) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_calibration); +} diff --git a/ports/analog/common-hal/rtc/RTC.h b/ports/analog/common-hal/rtc/RTC.h new file mode 100644 index 00000000000..590bc93ab52 --- /dev/null +++ b/ports/analog/common-hal/rtc/RTC.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Noralf Trønnes +// SPDX-FileCopyrightText: Copyright (c) 2019 Artur Pacholec +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +extern void rtc_reset(void); diff --git a/ports/analog/common-hal/rtc/__init__.c b/ports/analog/common-hal/rtc/__init__.c new file mode 100644 index 00000000000..ddf788bb0b5 --- /dev/null +++ b/ports/analog/common-hal/rtc/__init__.c @@ -0,0 +1,6 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT diff --git a/ports/analog/linking/max32690_cktpy.ld b/ports/analog/linking/max32690_cktpy.ld new file mode 100644 index 00000000000..9b32121a135 --- /dev/null +++ b/ports/analog/linking/max32690_cktpy.ld @@ -0,0 +1,186 @@ +/** This file is part of the CircuitPython project: https://circuitpython.org +* +* SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices Inc. +* +* SPDX-License-Identifier: MIT +*/ + +MEMORY { + ROM (rx) : ORIGIN = 0x00000000, LENGTH = 128K + FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 3M + FLASH_FIRMWARE (rx) : ORIGIN = 0x10000000, LENGTH = 2992K + FLASH_FS (rx) : ORIGIN = 0x102E0000, LENGTH = 128K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 1M +} +/* Minimum flash page is 16K */ +/* FLASH FIRMWARE: 3072K [3MB] - 16K - 64K = 2992K */ + +SECTIONS { + .rom : + { + KEEP(*(.rom_vector*)) + KEEP(*(.rom_handlers*)) + } > ROM + + + /** FIXME: can't place this in its own section for some reason + * system doesn't exit ROM code unless *(.isr_vector) + * is placed in the beginning of .text, + * even if .text is moved upward and *(.isr_vector) is + * placed at 0x10000000. + **/ + + /* Place ISR vector in a separate flash section */ + /* .isr_vector : */ + /* { */ + /* ISR Vector beginning of .text */ + /* KEEP(*(.isr_vector)) */ + /* KEEP(*(.isr_vector*)) */ + /* } > FLASH_ISR */ + + .text : + { + . = ALIGN(4); + _text = .; + + /* ISR Vector beginning of .text */ + /** fixme: may want to move this to FLASH_ISR long-term */ + KEEP(*(.isr_vector)) + KEEP(*(.isr_vector*)) + + . = ALIGN(4); + + /* program code; exclude RISCV code */ + EXCLUDE_FILE (*riscv.o) *(.text*) + *(.rodata*) /* read-only data: "const" */ + + KEEP(*(.init)) + KEEP(*(.fini)) + + /* .ctors */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + + /* .dtors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + /* C++ Exception handling */ + KEEP(*(.eh_frame*)) + . = ALIGN(4); + _etext = .; + } > FLASH_FIRMWARE + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH_FIRMWARE + + /* Binary import */ + .bin_storage : + { + FILL(0xFF) + _bin_start_ = .; + KEEP(*(.bin_storage_img)) + _bin_end_ = .; + . = ALIGN(4); + } > FLASH_FIRMWARE + + /* it's used for C++ exception handling */ + /* we need to keep this to avoid overlapping */ + .ARM.exidx : + { + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } > FLASH_FIRMWARE + + .data : + { + . = ALIGN(4); + _data = .; + _sdata = .; + + *(vtable) + *(.data*) /*read-write initialized data: initialized global variable*/ + + /* These array sections are used by __libc_init_array to call static C++ constructors */ + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + + /* Run the flash programming functions from SRAM */ + *(.flashprog) + + . = ALIGN(4); + _edata = .; + } > RAM AT>FLASH_FIRMWARE + __load_data = LOADADDR(.data); + + .bss : + { + . = ALIGN(4); + _sbss = .; /* Provide _sbss for Cktpy */ + _bss = .; + + *(.bss*) /*read-write zero initialized data: uninitialized global variable*/ + *(COMMON) + + . = ALIGN(4); + _ebss = .; + _ezero = .; /* Provide _ezero /_ebss for CktPython (same as ebss) */ + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + + _stack = __StackTop; + _estack = __StackLimit; /* Provide _estack for CktPython */ + + .heap (COPY): + { + . = ALIGN(4); + _heap = .; + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + *(.heap*) + __HeapLimit = ABSOLUTE(__StackLimit); + } > RAM + + _eheap = __HeapLimit; + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= _ebss, "region RAM overflowed with stack") +} diff --git a/ports/analog/max32_port.h b/ports/analog/max32_port.h new file mode 100644 index 00000000000..89830e96b0a --- /dev/null +++ b/ports/analog/max32_port.h @@ -0,0 +1,79 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#ifndef MAX32_PORT_H +#define MAX32_PORT_H + +#include + +#include "mxc_assert.h" +#include "mxc_delay.h" +#include "mxc_device.h" +#include "mxc_pins.h" +#include "mxc_sys.h" +#include "mcr_regs.h" + +#include "gpio.h" + +#ifdef MAX32690 +#include "system_max32690.h" +#include "max32690.h" + +// UART Ports & pins +#include "peripherals/max32690/max32_uart.h" +#include "peripherals/max32690/max32_i2c.h" +#include "peripherals/max32690/max32_spi.h" + +/** START: GPIO4 Handling specific to MAX32690 */ + #define GPIO4_PIN_MASK 0x00000003 + #define GPIO4_RESET_MASK 0xFFFFFF77 + #define GPIO4_OUTEN_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_OE_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_OE_POS - 1))) + #define GPIO4_PULLDIS_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_PE_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_PE_POS - 1))) + #define GPIO4_DATAOUT_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ + ((mask & (1 << 1)) << (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) + #define GPIO4_DATAOUT_GET_MASK(mask) \ + ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_DO) >> MXC_F_MCR_GPIO4_CTRL_P40_DO_POS) | \ + ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_DO) >> \ + (MXC_F_MCR_GPIO4_CTRL_P41_DO_POS - 1))) & \ + mask) + #define GPIO4_DATAIN_MASK(mask) \ + ((((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P40_IN) >> MXC_F_MCR_GPIO4_CTRL_P40_IN_POS) | \ + ((MXC_MCR->gpio4_ctrl & MXC_F_MCR_GPIO4_CTRL_P41_IN) >> \ + (MXC_F_MCR_GPIO4_CTRL_P41_IN_POS - 1))) & \ + mask) + #define GPIO4_AFEN_MASK(mask) \ + (((mask & (1 << 0)) << MXC_F_MCR_OUTEN_PDOWN_OUT_EN_POS) | \ + ((mask & (1 << 1)) >> (MXC_F_MCR_OUTEN_SQWOUT_EN_POS + 1))) +/** END: GPIO4 Handling specific to MAX32690 */ + +#endif + +/** Linker variables defined.... + * _estack: end of the stack + * _ebss: end of BSS section + * _ezero: same as ebss (acc. to main.c) + */ +extern uint32_t _ezero; +extern uint32_t _estack; +extern uint32_t _ebss; // Stored at the end of the bss section (which includes the heap). +extern uint32_t __stack, __heap; + +extern uint32_t SystemCoreClock; + +// Tick timer should be 1/1024 s. RTC Oscillator is usually 32.768 kHz ERTCO. +#define TICKS_PER_SEC 1024 + +#ifdef MAX32690 +// 12-bit ssec register, ticks @ 4096 Hz +#define SUBSEC_PER_TICK 4 +#endif + +#endif // MAX32_PORT_H diff --git a/ports/analog/mpconfigport.h b/ports/analog/mpconfigport.h new file mode 100644 index 00000000000..3296661fca7 --- /dev/null +++ b/ports/analog/mpconfigport.h @@ -0,0 +1,32 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2015 Glenn Ruben Bakke +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +// 24KiB stack +#define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 + +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED (1) + +// Also includes mpconfigboard.h +#include "py/circuitpy_mpconfig.h" + +// Board flags: +#ifndef BOARD_OVERWRITE_SWD +#define BOARD_OVERWRITE_SWD (0) +#endif +#ifndef BOARD_VTOR_DEFER +#define BOARD_VTOR_DEFER (0) +#endif +#ifndef BOARD_NO_VBUS_SENSE +#define BOARD_NO_VBUS_SENSE (0) +#endif +#ifndef BOARD_NO_USB_OTG_ID_SENSE +#define BOARD_NO_USB_OTG_ID_SENSE (0) +#endif diff --git a/ports/analog/mpconfigport.mk b/ports/analog/mpconfigport.mk new file mode 100644 index 00000000000..f1cd0bb2901 --- /dev/null +++ b/ports/analog/mpconfigport.mk @@ -0,0 +1,74 @@ +# This file is part of the CircuitPython project: https://circuitpython.org +# +# SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +# SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +# SPDX-FileCopyrightText: Copyright (c) 2025 Peggy Zhu, Analog Devices, Inc. +# +# SPDX-License-Identifier: MIT + +CHIP_FAMILY ?= max32 + +# Necessary to build CircuitPython +LONGINT_IMPL ?= MPZ +INTERNAL_LIBM ?= 1 + +# Req'd for OS; all max32 have TRNG +CFLAGS += -DHAS_TRNG=1 + +INTERNAL_FLASH_FILESYSTEM = 1 + +#################################################################################### +# Suggested config for first-time porting +#################################################################################### +# These modules are implemented in ports//common-hal: + +CIRCUITPY_BUSIO ?= 1 +CIRCUITPY_RTC ?= 1 + +# Other modules (may or may not implement): +CIRCUITPY_ANALOGIO ?= 0 +CIRCUITPY_AUDIOBUSIO ?= 0 +CIRCUITPY_AUDIOIO ?= 0 +CIRCUITPY_COUNTIO ?= 0 +CIRCUITPY_NEOPIXEL_WRITE ?= 0 +CIRCUITPY_FREQUENCYIO ?= 0 +CIRCUITPY_I2CTARGET ?= 0 +CIRCUITPY_PULSEIO ?= 0 +CIRCUITPY_PWMIO ?= 0 +CIRCUITPY_NVM ?= 0 +CIRCUITPY_ROTARYIO ?= 0 +CIRCUITPY_SDCARDIO ?= 0 +CIRCUITPY_FRAMEBUFFERIO ?= 0 +# Requires SPI, PulseIO (stub ok): +CIRCUITPY_DISPLAYIO ?= 0 + +# These modules are implemented in shared-module/ - they can be included in +# any port once their prerequisites in common-hal are complete. +# No requirements, but takes extra flash +CIRCUITPY_ULAB = 1 +# Requires DigitalIO: +CIRCUITPY_BITBANGIO ?= 1 +# Requires Microcontroller +CIRCUITPY_TOUCHIO ?= 1 +# Requires OS +CIRCUITPY_RANDOM ?= 1 +# Requires busio.UART +CIRCUITPY_CONSOLE_UART ?= 0 +# Does nothing without I2C +CIRCUITPY_REQUIRE_I2C_PULLUPS = 0 +# Requires neopixel_write or SPI (dotstar) +CIRCUITPY_PIXELBUF ?= 0 + +#################################################################################### +# Required for clean building (additional CircuitPython Defaults) +#################################################################################### + +# Depends on BUSIO +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_KEYPAD = 0 +CIRCUITPY_BUSDEVICE = 0 + +# For CircuitPython CI +CIRCUITPY_BUILD_EXTENSIONS ?= elf + +CIRCUITPY_PORT_SERIAL = 1 diff --git a/ports/analog/mphalport.c b/ports/analog/mphalport.c new file mode 100644 index 00000000000..8f305d6325e --- /dev/null +++ b/ports/analog/mphalport.c @@ -0,0 +1,25 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#include "mphalport.h" +#include "py/mphal.h" + +// includes __enable/__disable interrupts +#include "mxc_sys.h" + +#include "shared-bindings/microcontroller/__init__.h" + +void mp_hal_delay_us(mp_uint_t delay) { + common_hal_mcu_delay_us(delay); +} + +void mp_hal_disable_all_interrupts(void) { + __disable_irq(); +} + +void mp_hal_enable_all_interrupts(void) { + __enable_irq(); +} diff --git a/ports/analog/mphalport.h b/ports/analog/mphalport.h new file mode 100644 index 00000000000..3cd3e00c6e1 --- /dev/null +++ b/ports/analog/mphalport.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "lib/oofatfs/ff.h" +#include "supervisor/shared/tick.h" + +// Global millisecond tick count +static inline mp_uint_t mp_hal_ticks_ms(void) { + return supervisor_ticks_ms32(); +} + +void mp_hal_set_interrupt_char(int c); + +void mp_hal_disable_all_interrupts(void); +void mp_hal_enable_all_interrupts(void); diff --git a/ports/analog/msdk b/ports/analog/msdk new file mode 160000 index 00000000000..db69388844d --- /dev/null +++ b/ports/analog/msdk @@ -0,0 +1 @@ +Subproject commit db69388844d29e727cd245b90b54279341f77401 diff --git a/ports/analog/peripherals/max32690/gpios.c b/ports/analog/peripherals/max32690/gpios.c new file mode 100644 index 00000000000..d0dd3ad0fc1 --- /dev/null +++ b/ports/analog/peripherals/max32690/gpios.c @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "gpios.h" + +volatile mxc_gpio_regs_t *gpio_ports[NUM_GPIO_PORTS] = +{MXC_GPIO0, MXC_GPIO1, MXC_GPIO2, MXC_GPIO3, MXC_GPIO4}; diff --git a/ports/analog/peripherals/max32690/gpios.h b/ports/analog/peripherals/max32690/gpios.h new file mode 100644 index 00000000000..fe912277282 --- /dev/null +++ b/ports/analog/peripherals/max32690/gpios.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "py/mphal.h" + +// MSDK HAL includes +#include "gpio.h" +#include "gpio_regs.h" +#include "max32690.h" diff --git a/ports/analog/peripherals/max32690/max32_i2c.c b/ports/analog/peripherals/max32690/max32_i2c.c new file mode 100644 index 00000000000..4b9ec8b4db2 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_i2c.c @@ -0,0 +1,75 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +#include "common-hal/busio/I2C.h" +#include "max32_i2c.h" +#include "max32690.h" + +#include "py/runtime.h" +#include "py/mperrno.h" + + +/* Note: The MAX32690 assigns the same alternate function to multiple sets + * of pins. The drivers will enable both sets so that either can be used. + * Users should ensure the unused set is left unconnected. + * + * See MAX32690 Rev A2 Errata #16: + * https://www.analog.com/media/en/technical-documentation/data-sheets/max32690_a2_errata_rev2.pdf + * + * Additionally, note that the TQFN package does not expose some of the duplicate pins. For this package, + * enabling the un-routed GPIOs has been shown to cause initialization issues with the I2C block. + * To work around this, "MAX32690GTK_PACKAGE_TQFN" can be defined by the build system. The recommend place + * to do it is in the "board.mk" file of the BSP. This will prevent the inaccessible pins from being configured. + */ + +const mxc_gpio_cfg_t i2c_maps[NUM_I2C] = { + // I2C0 + { MXC_GPIO2, (MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // I2C1 + { MXC_GPIO0, (MXC_GPIO_PIN_11 | MXC_GPIO_PIN_12), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // I2C2 + { MXC_GPIO1, (MXC_GPIO_PIN_7 | MXC_GPIO_PIN_8), MXC_GPIO_FUNC_ALT3, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, +}; +#ifndef MAX32690GTK_PACKAGE_TQFN +const mxc_gpio_cfg_t i2c_maps_extra[NUM_I2C] = { + // I2C0A + { MXC_GPIO0, (MXC_GPIO_PIN_30 | MXC_GPIO_PIN_31), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_PULL_UP, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, + // I2C1A + { MXC_GPIO2, (MXC_GPIO_PIN_17 | MXC_GPIO_PIN_18), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_PULL_UP, MXC_GPIO_VSSEL_VDDIOH, MXC_GPIO_DRVSTR_0 }, + // I2C2C + { MXC_GPIO0, (MXC_GPIO_PIN_13 | MXC_GPIO_PIN_14), MXC_GPIO_FUNC_ALT3, + MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, +}; +#endif + +int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl) { + for (int i = 0; i < NUM_I2C; i++) { + if ((i2c_maps[i].port == (MXC_GPIO_GET_GPIO(sda->port))) + && (i2c_maps[i].mask == ((sda->mask) | (scl->mask)))) { + return i; + } + } + + // Additional for loop to cover alternate potential I2C maps + #ifndef MAX32690GTK_PACKAGE_TQFN + for (int i = 0; i < NUM_I2C; i++) { + if ((i2c_maps_extra[i].port == (MXC_GPIO_GET_GPIO(sda->port))) + && (i2c_maps_extra[i].mask == ((sda->mask) | (scl->mask)))) { + return i; + } + } + #endif + + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pins); + return -1; +} diff --git a/ports/analog/peripherals/max32690/max32_i2c.h b/ports/analog/peripherals/max32690/max32_i2c.h new file mode 100644 index 00000000000..b64cfd308dc --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_i2c.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "i2c_regs.h" +#include "mxc_sys.h" +#include "i2c.h" +#include "peripherals/pins.h" + +#define NUM_I2C 3 + +int pinsToI2c(const mcu_pin_obj_t *sda, const mcu_pin_obj_t *scl); diff --git a/ports/analog/peripherals/max32690/max32_spi.c b/ports/analog/peripherals/max32690/max32_spi.c new file mode 100644 index 00000000000..c78fd64dbd7 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_spi.c @@ -0,0 +1,44 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +#include "common-hal/busio/SPI.h" +#include "max32_spi.h" +#include "max32690.h" + +#include "py/runtime.h" +#include "py/mperrno.h" + +const mxc_gpio_cfg_t spi_maps[NUM_SPI] = { + // SPI0 + { MXC_GPIO2, (MXC_GPIO_PIN_27 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), + MXC_GPIO_FUNC_ALT2, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // SPI1 + { MXC_GPIO1, (MXC_GPIO_PIN_26 | MXC_GPIO_PIN_28 | MXC_GPIO_PIN_29), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // SPI2 + { MXC_GPIO2, (MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3 | MXC_GPIO_PIN_4), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // SPI3 + { MXC_GPIO0, (MXC_GPIO_PIN_16 | MXC_GPIO_PIN_20 | MXC_GPIO_PIN_21), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + // SPI4 + { MXC_GPIO1, (MXC_GPIO_PIN_1 | MXC_GPIO_PIN_2 | MXC_GPIO_PIN_3), + MXC_GPIO_FUNC_ALT1, MXC_GPIO_PAD_NONE, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, +}; + +int pinsToSpi(const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, + const mcu_pin_obj_t *sck) { + for (int i = 0; i < NUM_SPI; i++) { + if ((spi_maps[i].port == (MXC_GPIO_GET_GPIO(mosi->port))) + && (spi_maps[i].mask == ((mosi->mask) | (miso->mask) | (sck->mask)))) { + return i; + } + } + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pins); + return -1; +} diff --git a/ports/analog/peripherals/max32690/max32_spi.h b/ports/analog/peripherals/max32690/max32_spi.h new file mode 100644 index 00000000000..76bb48a59a7 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_spi.h @@ -0,0 +1,17 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "spi_regs.h" +#include "mxc_sys.h" +#include "spi.h" +#include "peripherals/pins.h" + +#define NUM_SPI 5 + +int pinsToSpi(const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, + const mcu_pin_obj_t *sck); diff --git a/ports/analog/peripherals/max32690/max32_uart.c b/ports/analog/peripherals/max32690/max32_uart.c new file mode 100644 index 00000000000..7d377087974 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_uart.c @@ -0,0 +1,36 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +#include "common-hal/busio/UART.h" +#include "max32_uart.h" +#include "max32690.h" + +#include "py/runtime.h" +#include "py/mperrno.h" + +const mxc_gpio_cfg_t uart_maps[NUM_UARTS] = { + { MXC_GPIO2, (MXC_GPIO_PIN_11 | MXC_GPIO_PIN_12), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + { MXC_GPIO2, (MXC_GPIO_PIN_14 | MXC_GPIO_PIN_16), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + { MXC_GPIO1, (MXC_GPIO_PIN_9 | MXC_GPIO_PIN_10), MXC_GPIO_FUNC_ALT1, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 }, + { MXC_GPIO3, (MXC_GPIO_PIN_0 | MXC_GPIO_PIN_1), MXC_GPIO_FUNC_ALT2, + MXC_GPIO_PAD_WEAK_PULL_UP, MXC_GPIO_VSSEL_VDDIO, MXC_GPIO_DRVSTR_0 } +}; + +int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx) { + for (int i = 0; i < NUM_UARTS; i++) { + if ((uart_maps[i].port == (MXC_GPIO_GET_GPIO(tx->port))) + && (uart_maps[i].mask == ((tx->mask) | (rx->mask)))) { + return i; + } + } + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pins); + return -1; +} diff --git a/ports/analog/peripherals/max32690/max32_uart.h b/ports/analog/peripherals/max32690/max32_uart.h new file mode 100644 index 00000000000..f03b500a3c5 --- /dev/null +++ b/ports/analog/peripherals/max32690/max32_uart.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "uart_regs.h" +#include "mxc_sys.h" +#include "uart.h" +#include "peripherals/pins.h" + +#define NUM_UARTS 4 + +int pinsToUart(const mcu_pin_obj_t *rx, const mcu_pin_obj_t *tx); diff --git a/ports/analog/peripherals/max32690/pins.c b/ports/analog/peripherals/max32690/pins.c new file mode 100644 index 00000000000..7550dc549ef --- /dev/null +++ b/ports/analog/peripherals/max32690/pins.c @@ -0,0 +1,123 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/mphal.h" +#include "peripherals/pins.h" +#include "max32690.h" + +const mcu_pin_obj_t pin_P0_00 = PIN(0, 0); +const mcu_pin_obj_t pin_P0_01 = PIN(0, 1); +const mcu_pin_obj_t pin_P0_02 = PIN(0, 2); +const mcu_pin_obj_t pin_P0_03 = PIN(0, 3); +const mcu_pin_obj_t pin_P0_04 = PIN(0, 4); +const mcu_pin_obj_t pin_P0_05 = PIN(0, 5); +const mcu_pin_obj_t pin_P0_06 = PIN(0, 6); +const mcu_pin_obj_t pin_P0_07 = PIN(0, 7); +const mcu_pin_obj_t pin_P0_08 = PIN(0, 8); +const mcu_pin_obj_t pin_P0_09 = PIN(0, 9); +const mcu_pin_obj_t pin_P0_10 = PIN(0, 10); +const mcu_pin_obj_t pin_P0_11 = PIN(0, 11); +const mcu_pin_obj_t pin_P0_12 = PIN(0, 12); +const mcu_pin_obj_t pin_P0_13 = PIN(0, 13); +const mcu_pin_obj_t pin_P0_14 = PIN(0, 14); +const mcu_pin_obj_t pin_P0_15 = PIN(0, 15); +const mcu_pin_obj_t pin_P0_16 = PIN(0, 16); +const mcu_pin_obj_t pin_P0_17 = PIN(0, 17); +const mcu_pin_obj_t pin_P0_18 = PIN(0, 18); +const mcu_pin_obj_t pin_P0_19 = PIN(0, 19); +const mcu_pin_obj_t pin_P0_20 = PIN(0, 20); +const mcu_pin_obj_t pin_P0_21 = PIN(0, 21); +const mcu_pin_obj_t pin_P0_22 = PIN(0, 22); +const mcu_pin_obj_t pin_P0_23 = PIN(0, 23); +const mcu_pin_obj_t pin_P0_24 = PIN(0, 24); +const mcu_pin_obj_t pin_P0_25 = PIN(0, 25); +const mcu_pin_obj_t pin_P0_26 = PIN(0, 26); +const mcu_pin_obj_t pin_P0_27 = PIN(0, 27); +const mcu_pin_obj_t pin_P0_28 = PIN(0, 28); +const mcu_pin_obj_t pin_P0_29 = PIN(0, 29); +const mcu_pin_obj_t pin_P0_30 = PIN(0, 30); +const mcu_pin_obj_t pin_P0_31 = PIN(0, 31); + +const mcu_pin_obj_t pin_P1_00 = PIN(1, 0); +const mcu_pin_obj_t pin_P1_01 = PIN(1, 1); +const mcu_pin_obj_t pin_P1_02 = PIN(1, 2); +const mcu_pin_obj_t pin_P1_03 = PIN(1, 3); +const mcu_pin_obj_t pin_P1_04 = PIN(1, 4); +const mcu_pin_obj_t pin_P1_05 = PIN(1, 5); +const mcu_pin_obj_t pin_P1_06 = PIN(1, 6); +const mcu_pin_obj_t pin_P1_07 = PIN(1, 7); +const mcu_pin_obj_t pin_P1_08 = PIN(1, 8); +const mcu_pin_obj_t pin_P1_09 = PIN(1, 9); +const mcu_pin_obj_t pin_P1_10 = PIN(1, 10); +const mcu_pin_obj_t pin_P1_11 = PIN(1, 11); +const mcu_pin_obj_t pin_P1_12 = PIN(1, 12); +const mcu_pin_obj_t pin_P1_13 = PIN(1, 13); +const mcu_pin_obj_t pin_P1_14 = PIN(1, 14); +const mcu_pin_obj_t pin_P1_15 = PIN(1, 15); +const mcu_pin_obj_t pin_P1_16 = PIN(1, 16); +const mcu_pin_obj_t pin_P1_17 = PIN(1, 17); +const mcu_pin_obj_t pin_P1_18 = PIN(1, 18); +const mcu_pin_obj_t pin_P1_19 = PIN(1, 19); +const mcu_pin_obj_t pin_P1_20 = PIN(1, 20); +const mcu_pin_obj_t pin_P1_21 = PIN(1, 21); +const mcu_pin_obj_t pin_P1_22 = PIN(1, 22); +const mcu_pin_obj_t pin_P1_23 = PIN(1, 23); +const mcu_pin_obj_t pin_P1_24 = PIN(1, 24); +const mcu_pin_obj_t pin_P1_25 = PIN(1, 25); +const mcu_pin_obj_t pin_P1_26 = PIN(1, 26); +const mcu_pin_obj_t pin_P1_27 = PIN(1, 27); +const mcu_pin_obj_t pin_P1_28 = PIN(1, 28); +const mcu_pin_obj_t pin_P1_29 = PIN(1, 29); +const mcu_pin_obj_t pin_P1_30 = PIN(1, 30); +const mcu_pin_obj_t pin_P1_31 = PIN(1, 31); + +const mcu_pin_obj_t pin_P2_00 = PIN(2, 0); +const mcu_pin_obj_t pin_P2_01 = PIN(2, 1); +const mcu_pin_obj_t pin_P2_02 = PIN(2, 2); +const mcu_pin_obj_t pin_P2_03 = PIN(2, 3); +const mcu_pin_obj_t pin_P2_04 = PIN(2, 4); +const mcu_pin_obj_t pin_P2_05 = PIN(2, 5); +const mcu_pin_obj_t pin_P2_06 = PIN(2, 6); +const mcu_pin_obj_t pin_P2_07 = PIN(2, 7); +const mcu_pin_obj_t pin_P2_08 = PIN(2, 8); +const mcu_pin_obj_t pin_P2_09 = PIN(2, 9); +const mcu_pin_obj_t pin_P2_10 = PIN(2, 10); +const mcu_pin_obj_t pin_P2_11 = PIN(2, 11); +const mcu_pin_obj_t pin_P2_12 = PIN(2, 12); +const mcu_pin_obj_t pin_P2_13 = PIN(2, 13); +const mcu_pin_obj_t pin_P2_14 = PIN(2, 14); +const mcu_pin_obj_t pin_P2_15 = PIN(2, 15); +const mcu_pin_obj_t pin_P2_16 = PIN(2, 16); +const mcu_pin_obj_t pin_P2_17 = PIN(2, 17); +const mcu_pin_obj_t pin_P2_18 = PIN(2, 18); +const mcu_pin_obj_t pin_P2_19 = PIN(2, 19); +const mcu_pin_obj_t pin_P2_20 = PIN(2, 20); +const mcu_pin_obj_t pin_P2_21 = PIN(2, 21); +const mcu_pin_obj_t pin_P2_22 = PIN(2, 22); +const mcu_pin_obj_t pin_P2_23 = PIN(2, 23); +const mcu_pin_obj_t pin_P2_24 = PIN(2, 24); +const mcu_pin_obj_t pin_P2_25 = PIN(2, 25); +const mcu_pin_obj_t pin_P2_26 = PIN(2, 26); +const mcu_pin_obj_t pin_P2_27 = PIN(2, 27); +const mcu_pin_obj_t pin_P2_28 = PIN(2, 28); +const mcu_pin_obj_t pin_P2_29 = PIN(2, 29); +const mcu_pin_obj_t pin_P2_30 = PIN(2, 30); +const mcu_pin_obj_t pin_P2_31 = PIN(2, 31); + +const mcu_pin_obj_t pin_P3_00 = PIN(3, 0); +const mcu_pin_obj_t pin_P3_01 = PIN(3, 1); +const mcu_pin_obj_t pin_P3_02 = PIN(3, 2); +const mcu_pin_obj_t pin_P3_03 = PIN(3, 3); +const mcu_pin_obj_t pin_P3_04 = PIN(3, 4); +const mcu_pin_obj_t pin_P3_05 = PIN(3, 5); +const mcu_pin_obj_t pin_P3_06 = PIN(3, 6); +const mcu_pin_obj_t pin_P3_07 = PIN(3, 7); +const mcu_pin_obj_t pin_P3_08 = PIN(3, 8); +const mcu_pin_obj_t pin_P3_09 = PIN(3, 9); + +const mcu_pin_obj_t pin_P4_00 = PIN(4, 0); +const mcu_pin_obj_t pin_P4_01 = PIN(4, 1); diff --git a/ports/analog/peripherals/max32690/pins.h b/ports/analog/peripherals/max32690/pins.h new file mode 100644 index 00000000000..44022decdf7 --- /dev/null +++ b/ports/analog/peripherals/max32690/pins.h @@ -0,0 +1,120 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +extern const mcu_pin_obj_t pin_P0_00; +extern const mcu_pin_obj_t pin_P0_01; +extern const mcu_pin_obj_t pin_P0_02; +extern const mcu_pin_obj_t pin_P0_03; +extern const mcu_pin_obj_t pin_P0_04; +extern const mcu_pin_obj_t pin_P0_05; +extern const mcu_pin_obj_t pin_P0_06; +extern const mcu_pin_obj_t pin_P0_07; +extern const mcu_pin_obj_t pin_P0_08; +extern const mcu_pin_obj_t pin_P0_09; +extern const mcu_pin_obj_t pin_P0_10; +extern const mcu_pin_obj_t pin_P0_11; +extern const mcu_pin_obj_t pin_P0_12; +extern const mcu_pin_obj_t pin_P0_13; +extern const mcu_pin_obj_t pin_P0_14; +extern const mcu_pin_obj_t pin_P0_15; +extern const mcu_pin_obj_t pin_P0_16; +extern const mcu_pin_obj_t pin_P0_17; +extern const mcu_pin_obj_t pin_P0_18; +extern const mcu_pin_obj_t pin_P0_19; +extern const mcu_pin_obj_t pin_P0_20; +extern const mcu_pin_obj_t pin_P0_21; +extern const mcu_pin_obj_t pin_P0_22; +extern const mcu_pin_obj_t pin_P0_23; +extern const mcu_pin_obj_t pin_P0_24; +extern const mcu_pin_obj_t pin_P0_25; +extern const mcu_pin_obj_t pin_P0_26; +extern const mcu_pin_obj_t pin_P0_27; +extern const mcu_pin_obj_t pin_P0_28; +extern const mcu_pin_obj_t pin_P0_29; +extern const mcu_pin_obj_t pin_P0_30; +extern const mcu_pin_obj_t pin_P0_31; + +extern const mcu_pin_obj_t pin_P1_00; +extern const mcu_pin_obj_t pin_P1_01; +extern const mcu_pin_obj_t pin_P1_02; +extern const mcu_pin_obj_t pin_P1_03; +extern const mcu_pin_obj_t pin_P1_04; +extern const mcu_pin_obj_t pin_P1_05; +extern const mcu_pin_obj_t pin_P1_06; +extern const mcu_pin_obj_t pin_P1_07; +extern const mcu_pin_obj_t pin_P1_08; +extern const mcu_pin_obj_t pin_P1_09; +extern const mcu_pin_obj_t pin_P1_10; +extern const mcu_pin_obj_t pin_P1_11; +extern const mcu_pin_obj_t pin_P1_12; +extern const mcu_pin_obj_t pin_P1_13; +extern const mcu_pin_obj_t pin_P1_14; +extern const mcu_pin_obj_t pin_P1_15; +extern const mcu_pin_obj_t pin_P1_16; +extern const mcu_pin_obj_t pin_P1_17; +extern const mcu_pin_obj_t pin_P1_18; +extern const mcu_pin_obj_t pin_P1_19; +extern const mcu_pin_obj_t pin_P1_20; +extern const mcu_pin_obj_t pin_P1_21; +extern const mcu_pin_obj_t pin_P1_22; +extern const mcu_pin_obj_t pin_P1_23; +extern const mcu_pin_obj_t pin_P1_24; +extern const mcu_pin_obj_t pin_P1_25; +extern const mcu_pin_obj_t pin_P1_26; +extern const mcu_pin_obj_t pin_P1_27; +extern const mcu_pin_obj_t pin_P1_28; +extern const mcu_pin_obj_t pin_P1_29; +extern const mcu_pin_obj_t pin_P1_30; +extern const mcu_pin_obj_t pin_P1_31; + +extern const mcu_pin_obj_t pin_P2_00; +extern const mcu_pin_obj_t pin_P2_01; +extern const mcu_pin_obj_t pin_P2_02; +extern const mcu_pin_obj_t pin_P2_03; +extern const mcu_pin_obj_t pin_P2_04; +extern const mcu_pin_obj_t pin_P2_05; +extern const mcu_pin_obj_t pin_P2_06; +extern const mcu_pin_obj_t pin_P2_07; +extern const mcu_pin_obj_t pin_P2_08; +extern const mcu_pin_obj_t pin_P2_09; +extern const mcu_pin_obj_t pin_P2_10; +extern const mcu_pin_obj_t pin_P2_11; +extern const mcu_pin_obj_t pin_P2_12; +extern const mcu_pin_obj_t pin_P2_13; +extern const mcu_pin_obj_t pin_P2_14; +extern const mcu_pin_obj_t pin_P2_15; +extern const mcu_pin_obj_t pin_P2_16; +extern const mcu_pin_obj_t pin_P2_17; +extern const mcu_pin_obj_t pin_P2_18; +extern const mcu_pin_obj_t pin_P2_19; +extern const mcu_pin_obj_t pin_P2_20; +extern const mcu_pin_obj_t pin_P2_21; +extern const mcu_pin_obj_t pin_P2_22; +extern const mcu_pin_obj_t pin_P2_23; +extern const mcu_pin_obj_t pin_P2_24; +extern const mcu_pin_obj_t pin_P2_25; +extern const mcu_pin_obj_t pin_P2_26; +extern const mcu_pin_obj_t pin_P2_27; +extern const mcu_pin_obj_t pin_P2_28; +extern const mcu_pin_obj_t pin_P2_29; +extern const mcu_pin_obj_t pin_P2_30; +extern const mcu_pin_obj_t pin_P2_31; + +extern const mcu_pin_obj_t pin_P3_00; +extern const mcu_pin_obj_t pin_P3_01; +extern const mcu_pin_obj_t pin_P3_02; +extern const mcu_pin_obj_t pin_P3_03; +extern const mcu_pin_obj_t pin_P3_04; +extern const mcu_pin_obj_t pin_P3_05; +extern const mcu_pin_obj_t pin_P3_06; +extern const mcu_pin_obj_t pin_P3_07; +extern const mcu_pin_obj_t pin_P3_08; +extern const mcu_pin_obj_t pin_P3_09; + +extern const mcu_pin_obj_t pin_P4_00; // BTLDR Stimulus +extern const mcu_pin_obj_t pin_P4_01; diff --git a/ports/analog/peripherals/pins.h b/ports/analog/peripherals/pins.h new file mode 100644 index 00000000000..3bd7d02bf46 --- /dev/null +++ b/ports/analog/peripherals/pins.h @@ -0,0 +1,36 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +// STD includes +#include +#include + +// CktPy includes +#include "py/obj.h" + +// HAL includes +#include "gpio.h" +#include "gpio_regs.h" + +typedef struct { + mp_obj_base_t base; + uint8_t port; + uint32_t mask; // the pad # target e.g. P0.01 is Port=0, Mask=1 + mxc_gpio_vssel_t level; +} mcu_pin_obj_t; + +extern const mp_obj_type_t mcu_pin_type; + +#define PIN(pin_port, pin_mask) { {&mcu_pin_type}, .port = pin_port, .mask = 1UL << pin_mask, .level = MXC_GPIO_VSSEL_VDDIO } + +// for non-connected pins +#define NO_PIN 0xFF + +#ifdef MAX32690 +#include "max32690/pins.h" +#endif diff --git a/ports/analog/qstrdefsport.h b/ports/analog/qstrdefsport.h new file mode 100644 index 00000000000..2d2c2609234 --- /dev/null +++ b/ports/analog/qstrdefsport.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// Do not use #pragma once in this file; it will cause a warning during qstr generation. + +// qstrs specific to this port +// *FORMAT-OFF* diff --git a/ports/analog/supervisor/internal_flash.c b/ports/analog/supervisor/internal_flash.c new file mode 100644 index 00000000000..8518b235566 --- /dev/null +++ b/ports/analog/supervisor/internal_flash.c @@ -0,0 +1,246 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George +// SPDX-FileCopyrightText: Copyright (c) 2020 Lucian Copeland for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "supervisor/internal_flash.h" + +#include +#include +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" + +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "supervisor/filesystem.h" +#include "supervisor/flash.h" +#include "supervisor/shared/safe_mode.h" +#if CIRCUITPY_USB_DEVICE +#include "supervisor/usb.h" +#endif + +#include "mpconfigboard.h" + +// MAX32 HAL Includes +#include "flc.h" +#include "flc_reva.h" +#include "icc.h" // includes icc_.c for MSDK die type +#include "mxc_device.h" + +/** + * NOTE: + * ANY function which modifies flash contents must execute from a crit section. + * This is because FLC functions are loc'd in RAM, and an ISR executing + * from Flash will trigger a HardFault. + * + * An alternative would be to initialize with NVIC_SetRAM(), + * which makes ISRs execute from RAM. + * + * NOTE: + * Additionally, any code that modifies flash contents must disable the + * cache. Turn off ICC0 any time flash is to be modified. Remember to re-enable if using. + * + * For Maxim devices which include an additional RISC-V processor, this shall be ignored. + * Therefore only ICC0 need be used for the purpose of these functions. + */ + +typedef struct { + const uint32_t base_addr; + const uint32_t sector_size; + const uint32_t num_sectors; +} flash_layout_t; + +#ifdef MAX32690 +// struct layout is the actual layout of flash +// FS Code will use INTERNAL_FLASH_FILESYSTEM_START_ADDR +// and won't conflict with ISR vector in first 16 KiB of flash +static const flash_layout_t flash_layout[] = { + { 0x10000000, FLASH_PAGE_SIZE, 192}, + // { 0x10300000, 0x2000, 32 }, // RISC-V flash +}; +// must be able to hold a full page (for re-writing upon erase) +static uint32_t page_buffer[FLASH_PAGE_SIZE / 4] = {0x0}; + +#else +#error "Invalid BOARD. Please set BOARD equal to any board under 'boards/'." +#endif + +static inline int32_t block2addr(uint32_t block) { + if (block >= 0 && block < INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS) { + return CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR + block * FILESYSTEM_BLOCK_SIZE; + } else { + return -1; + } +} + +// Get index, start addr, & size of the flash sector where addr lies +int flash_get_sector_info(uint32_t addr, uint32_t *start_addr, uint32_t *size) { + // This function should return -1 in the event of errors. + if (addr >= flash_layout[0].base_addr) { + uint32_t sector_index = 0; + if (MP_ARRAY_SIZE(flash_layout) == 1) { + sector_index = (addr - flash_layout[0].base_addr) / flash_layout[0].sector_size; + if (sector_index >= flash_layout[0].num_sectors) { + return -1; // addr is not in flash + } + if (start_addr) { + *start_addr = flash_layout[0].base_addr + (sector_index * flash_layout[0].sector_size); + } else { + return -1; // start_addr is NULL + } + if (size) { + *size = flash_layout[0].sector_size; + } else { + return -1; // size is NULL + } + return sector_index; + } + + // algorithm for multiple flash sections + for (uint8_t i = 0; i < MP_ARRAY_SIZE(flash_layout); ++i) { + for (uint8_t j = 0; j < flash_layout[i].num_sectors; ++j) { + uint32_t sector_start_next = flash_layout[i].base_addr + + (j + 1) * flash_layout[i].sector_size; + if (addr < sector_start_next) { + if (start_addr) { + *start_addr = flash_layout[i].base_addr + + j * flash_layout[i].sector_size; + } + if (size) { + *size = flash_layout[i].sector_size; + } + return sector_index; + } + ++sector_index; + } + } + } + return -1; +} + +void supervisor_flash_init(void) { + // No initialization needed. + // Pay attention to the note at the top of this file! +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + return INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS; +} + +void port_internal_flash_flush(void) { + + // Flush all instruction cache + // ME18 has bug where top-level sysctrl flush bit only works one. + // Have to use low-level flush bits for each ICC instance. + MXC_ICC_Flush(MXC_ICC0); + MXC_ICC_Flush(MXC_ICC1); + + // Clear the line fill buffer by reading 2 pages from flash + volatile uint32_t *line_addr; + volatile uint32_t line; + line_addr = (uint32_t *)(MXC_FLASH_MEM_BASE); + line = *line_addr; + line_addr = (uint32_t *)(MXC_FLASH_MEM_BASE + MXC_FLASH_PAGE_SIZE); + line = *line_addr; + (void)line; // Silence build warnings that this variable is not used. +} + +// Read flash blocks, using cache if it contains the right data +// return 0 on success, non-zero on error +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + // Find the address of the block we want to read + int src_addr = block2addr(block); + if (src_addr == -1) { + // bad block num + return 1; + } + + uint32_t sector_size, sector_start; + if (flash_get_sector_info(src_addr, §or_start, §or_size) == -1) { + // bad sector idx + return 2; + } + + /** NOTE: The MXC_FLC_Read function executes from SRAM and does some more error checking + * than memcpy does. Will use it for now. + */ + MXC_FLC_Read(src_addr, dest, FILESYSTEM_BLOCK_SIZE * num_blocks); + + return 0; // success +} + +// Write to flash blocks +// return 0 on success, non-zero on error +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { + uint32_t error, blocks_left, count, page_start, page_size = 0; + + while (num_blocks > 0) { + int dest_addr = block2addr(block_num); + // bad block number passed in + if (dest_addr == -1) { + return 1; + } + + if (flash_get_sector_info(dest_addr, &page_start, &page_size) == -1) { + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); + } + + // Find the number of blocks left within this sector + // BLOCKS_LEFT = (SECTOR_SIZE - BLOCK_OFFSET within sector)) / BLOCK_SIZE + blocks_left = (page_size - (dest_addr - page_start)) / FILESYSTEM_BLOCK_SIZE; + count = MIN(num_blocks, blocks_left); + + MXC_ICC_Disable(MXC_ICC0); + + // Buffer the page of flash to erase + MXC_FLC_Read(page_start, page_buffer, page_size); + + // Erase flash page + MXC_CRITICAL( + error = MXC_FLC_PageErase(dest_addr); + ); + if (error != E_NO_ERROR) { + // lock flash & reset + MXC_FLC0->ctrl = (MXC_FLC0->ctrl & ~MXC_F_FLC_REVA_CTRL_UNLOCK) | MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED; + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); + } + + // Copy new src data into the page buffer + // fill the new data in at the offset dest_addr - page_start + // account for uint32_t page_buffer vs uint8_t src + memcpy((page_buffer + (dest_addr - page_start) / 4), src, count * FILESYSTEM_BLOCK_SIZE); + + // Write new page buffer back into flash + MXC_CRITICAL( + error = MXC_FLC_Write(page_start, page_size, page_buffer); + ); + if (error != E_NO_ERROR) { + // lock flash & reset + MXC_FLC0->ctrl = (MXC_FLC0->ctrl & ~MXC_F_FLC_REVA_CTRL_UNLOCK) | MXC_S_FLC_REVA_CTRL_UNLOCK_LOCKED; + reset_into_safe_mode(SAFE_MODE_FLASH_WRITE_FAIL); + } + + MXC_ICC_Enable(MXC_ICC0); + + block_num += count; + src += count * FILESYSTEM_BLOCK_SIZE; + num_blocks -= count; + } + return 0; // success +} + +// Empty the fs cache +void supervisor_flash_release_cache(void) { + supervisor_flash_flush(); +} diff --git a/ports/analog/supervisor/internal_flash.h b/ports/analog/supervisor/internal_flash.h new file mode 100644 index 00000000000..cc25f80be77 --- /dev/null +++ b/ports/analog/supervisor/internal_flash.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/mpconfig.h" + +#define INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS (INTERNAL_FLASH_FILESYSTEM_SIZE / FILESYSTEM_BLOCK_SIZE) diff --git a/ports/analog/supervisor/port.c b/ports/analog/supervisor/port.c new file mode 100644 index 00000000000..e95deaba2a8 --- /dev/null +++ b/ports/analog/supervisor/port.c @@ -0,0 +1,333 @@ +/****************************************************************************** + * + * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. All Rights Reserved. + * (now owned by Analog Devices, Inc.), + * Copyright (C) 2023 Analog Devices, Inc. All Rights Reserved. This software + * is proprietary to Analog Devices, Inc. and its licensors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ******************************************************************************/ + +/** + * @file port.c + * @author Brandon Hurst @ Analog Devices, Inc. + * @brief Functions required for a basic CircuitPython port + * @date 2024-07-30 + * + * @copyright Copyright (c) 2024 + */ + +#include +#include +#include "supervisor/background_callback.h" +#include "supervisor/board.h" +#include "supervisor/port.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" + +// Sys includes +#include "max32_port.h" +#include "nvic_table.h" + +// Timers +#include "mxc_delay.h" +#include "rtc.h" + +// true random number generator, TRNG +#include "trng.h" + +// msec to RTC subsec ticks (4 kHz) +/* Converts a time in milleseconds to equivalent RSSA register value */ +#define MSEC_TO_SS_ALARM(x) (0 - ((x * 4096) / 1000)) + +// Externs defined by linker .ld file +extern uint32_t _stack, _heap, _estack, _eheap; +extern uint32_t _ebss; + +// From boards/$(BOARD)/board.c +extern const mxc_gpio_cfg_t pb_pin[]; +extern const int num_pbs; +extern const mxc_gpio_cfg_t led_pin[]; +extern const int num_leds; + +// For saving rtc data for ticks +static uint32_t subsec, sec = 0; +static uint32_t tick_flag = 0; + +// defined by cmsis core files +extern void NVIC_SystemReset(void) MP_NORETURN; + +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; + + MXC_DelayHandler(); +} + + +safe_mode_t port_init(void) { + int err = E_NO_ERROR; + + // Set Vector Table to RAM & configure ARM core to use RAM-based ISRs + // This allows definition of ISRs with custom names + // + // Useful for mapping ISRs with names not related to a specific IRQn. + // Source: https://arm-software.github.io/CMSIS_5/Core/html/using_VTOR_pg.html + NVIC_SetRAM(); + + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); + NVIC_EnableIRQ(SysTick_IRQn); + + // Enable GPIO (enables clocks + common init for ports) + for (int i = 0; i < MXC_CFG_GPIO_INSTANCES; i++) { + err = MXC_GPIO_Init(0x1 << i); + if (err) { + return SAFE_MODE_PROGRAMMATIC; + } + } + + // Enable clock to RTC peripheral + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_ERTCO_EN; + while (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_ERTCO_RDY)) { + ; + } + + NVIC_EnableIRQ(RTC_IRQn); + NVIC_EnableIRQ(USB_IRQn); + + // Init RTC w/ 0sec, 0subsec + // Driven by 32.768 kHz ERTCO, with ssec= 1/4096 s + while (MXC_RTC_Init(0, 0) != E_SUCCESS) { + } + ; + + // enable 1 sec RTC SSEC alarm + MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE); + MXC_RTC_SetSubsecondAlarm(MSEC_TO_SS_ALARM(1000)); + MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE); + + // Enable RTC + while (MXC_RTC_Start() != E_SUCCESS) { + } + ; + + // enable TRNG (true random number generator) + #if CIRCUITPY_RANDOM + MXC_TRNG_Init(); + #endif + + return SAFE_MODE_NONE; +} + +void TRNG_IRQHandler(void) { + MXC_TRNG_Handler(); +} + +void RTC_IRQHandler(void) { + // Read flags to clear + int flags = MXC_RTC_GetFlags(); + + switch (flags) { + case MXC_F_RTC_CTRL_SSEC_ALARM: + MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_SSEC_ALARM); + break; + case MXC_F_RTC_CTRL_TOD_ALARM: + MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_TOD_ALARM); + break; + case MXC_F_RTC_CTRL_RDY: + MXC_RTC_ClearFlags(MXC_F_RTC_CTRL_RDY); + break; + default: + break; + } + + tick_flag = 1; +} + +// Reset the MCU completely +void reset_cpu(void) { + // includes MCU reset request + awaits on memory bus + NVIC_SystemReset(); +} + +// Reset MCU state +void reset_port(void) { +} + +// Reset to the bootloader +// note: not implemented since max32 requires external signals to +// activate bootloaders +void reset_to_bootloader(void) { + NVIC_SystemReset(); + while (true) { + __NOP(); + } +} + +/** Acquire values of stack & heap starts & limits + * Return variables defined by linkerscript. + */ +uint32_t *port_stack_get_limit(void) { + // ignore array bounds GCC warnings + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Warray-bounds" + + // NOTE: Only return how much stack we have allotted for CircuitPython + return port_stack_get_top() - (CIRCUITPY_DEFAULT_STACK_SIZE + CIRCUITPY_EXCEPTION_STACK_SIZE) / sizeof(uint32_t); + #pragma GCC diagnostic pop +} +uint32_t *port_stack_get_top(void) { + return &_stack; +} +uint32_t *port_heap_get_bottom(void) { + return &_heap; +} +uint32_t *port_heap_get_top(void) { + return port_stack_get_limit(); +} + +/** Save & retrieve a word from memory over a reset cycle. + * Used for safe mode + */ +void port_set_saved_word(uint32_t value) { + _ebss = value; +} +uint32_t port_get_saved_word(void) { + return _ebss; +} + +// Raw monotonic tick count since startup. +// NOTE (rollover): +// seconds reg is 32 bits, can hold up to 2^32-1 +// theref. rolls over after ~136 years +uint64_t port_get_raw_ticks(uint8_t *subticks) { + // Ensure we can read from ssec register as soon as we can + // MXC function does cross-tick / busy checking of RTC controller + if (MXC_RTC->ctrl & MXC_F_RTC_CTRL_EN) { + // NOTE: RTC_GetTime always returns BUSY if RTC is not running + while ((MXC_RTC_GetTime(&sec, &subsec)) != E_NO_ERROR) { + ; + } + } else { + sec = MXC_RTC->sec; + subsec = MXC_RTC->ssec; + } + + // Return ticks given total subseconds + // ticks = TICKS/s * s + subsec/ subs/tick + uint64_t raw_ticks = ((uint64_t)TICKS_PER_SEC) * sec + (subsec / SUBSEC_PER_TICK); + + if (subticks) { + // subticks may only be filled to a resn of 1/4096 in some cases + // e.g. multiply by 32 / 8 = 4 to get true 1/32768 subticks + *subticks = (32 / (SUBSEC_PER_TICK)) * (subsec - (subsec / SUBSEC_PER_TICK)); + } + + return raw_ticks; +} + +// Enable 1/1024 second tick. +void port_enable_tick(void) { + while (MXC_RTC_Start() == E_BUSY) { + ; + } +} + +// Disable 1/1024 second tick. +void port_disable_tick(void) { + while (MXC_RTC_Stop() == E_BUSY) { + ; + } +} + +// Wake the CPU after a given # of ticks or sooner +void port_interrupt_after_ticks(uint32_t ticks) { + uint32_t ticks_msec = 0; + + ticks_msec = (ticks / TICKS_PER_SEC) * 1000; + + // Disable RTC interrupts + MXC_RTC_DisableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE | + MXC_F_RTC_CTRL_TOD_ALARM_IE | MXC_F_RTC_CTRL_RDY_IE); + + // Stop RTC & store current time & ticks + port_get_raw_ticks(NULL); + + // Clear the flag to be set by the RTC Handler + tick_flag = 0; + + // Subsec alarm is the starting/reload value of the SSEC counter. + // ISR triggered when SSEC rolls over from 0xFFFF_FFFF to 0x0 + while (MXC_RTC_SetSubsecondAlarm(MSEC_TO_SS_ALARM(ticks_msec)) != E_SUCCESS) { + } + + MXC_RTC_EnableInt(MXC_F_RTC_CTRL_SSEC_ALARM_IE); + +} + +void port_idle_until_interrupt(void) { + #if CIRCUITPY_RTC + // Check if alarm triggers before we even got here + if (MXC_RTC_GetFlags() == (MXC_F_RTC_CTRL_TOD_ALARM | MXC_F_RTC_CTRL_SSEC_ALARM)) { + return; + } + #endif + + // Interrupts should be disabled to ensure the ISR queue is flushed + // WFI still returns as long as the interrupt flag toggles; + // only when we re-enable interrupts will the ISR function trigger + common_hal_mcu_disable_interrupts(); + if (!background_callback_pending()) { + __DSB(); + /** DEBUG: may comment out WFI for debugging port functions */ + // __WFI(); + } + common_hal_mcu_enable_interrupts(); +} + +__attribute__((used)) void MemManage_Handler(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +__attribute__((used)) void BusFault_Handler(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +__attribute__((used)) void UsageFault_Handler(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +__attribute__((used)) void HardFault_Handler(void) { + reset_into_safe_mode(SAFE_MODE_HARD_FAULT); + while (true) { + asm ("nop;"); + } +} + +// Required by libc _init_array loops in startup code +// if we are compiling using "-nostdlib/-nostartfiles" +void _init(void) { +} diff --git a/ports/analog/supervisor/serial.c b/ports/analog/supervisor/serial.c new file mode 100644 index 00000000000..bd4472875a0 --- /dev/null +++ b/ports/analog/supervisor/serial.c @@ -0,0 +1,88 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017, 2018 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2019 Lucian Copeland for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) Brandon Hurst, Analog Devices, Inc. +// +// SPDX-License-Identifier: MIT + +#include "py/mphal.h" +#include +#include "supervisor/shared/serial.h" + +#include "uart.h" +#include "uart_regs.h" + +#ifndef MAX32_SERIAL +#define MAX32_SERIAL 0 +#endif + +#if MAX32_SERIAL +#ifdef MAX32690 +#define CONSOLE_UART MXC_UART0 +#endif +#endif + +void port_serial_early_init(void) { + +} + +void port_serial_init(void) { + #if MAX32_SERIAL + MXC_GCR->clkctrl |= MXC_F_GCR_CLKCTRL_IBRO_EN; + while (!(MXC_GCR->clkctrl & MXC_F_GCR_CLKCTRL_IBRO_RDY)) { + ; + } + MXC_UART_Init(CONSOLE_UART, 115200, MXC_UART_IBRO_CLK); + #endif +} + +bool port_serial_connected(void) { + return true; +} + +char port_serial_read(void) { + #if MAX32_SERIAL + // uint8_t data; + // HAL_UART_Receive(&huart2, &data, 1, 500); + // return data; + uint8_t rData; + + mxc_uart_req_t uart_req = { + .uart = CONSOLE_UART, + .rxCnt = 0, + .txCnt = 0, + .txData = NULL, + .rxData = &rData, + .txLen = 0, + .rxLen = 1 + }; + MXC_UART_Transaction(&uart_req); + return rData; + #else + return -1; + #endif +} + +uint32_t port_serial_bytes_available(void) { + #if MAX32_SERIAL + return MXC_UART_GetRXFIFOAvailable(CONSOLE_UART); + #else + return 0; + #endif +} + +void port_serial_write_substring(const char *text, uint32_t len) { + #if MAX32_SERIAL + mxc_uart_req_t uart_req = { + .uart = CONSOLE_UART, + .rxCnt = 0, + .txCnt = 0, + .txData = (const unsigned char *)text, + .rxData = NULL, + .txLen = len, + .rxLen = 0 + }; + MXC_UART_Transaction(&uart_req); + #endif +} diff --git a/ports/analog/supervisor/usb.c b/ports/analog/supervisor/usb.c new file mode 100644 index 00000000000..1624359ab51 --- /dev/null +++ b/ports/analog/supervisor/usb.c @@ -0,0 +1,43 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 hathach for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Brandon Hurst, Analog Devices, Inc +// +// SPDX-License-Identifier: MIT + +#include "supervisor/usb.h" +#include "common-hal/microcontroller/Pin.h" + +#include "py/mpconfig.h" + +#include "lib/tinyusb/src/device/usbd.h" + +// max32 includes +#include "mxc_sys.h" +#include "gcr_regs.h" +#include "mcr_regs.h" + +void init_usb_hardware(void) { + // USB GPIOs are non-configurable on MAX32 devices + // No need to add them to the never_reset list for mcu/Pin API. + + // 1 ms SysTick initialized in board.c + + // Enable requisite clocks & power for USB + MXC_SYS_ClockSourceEnable(MXC_SYS_CLOCK_IPO); + MXC_MCR->ldoctrl |= MXC_F_MCR_LDOCTRL_0P9EN; + MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_USB); + MXC_SYS_Reset_Periph(MXC_SYS_RESET0_USB); + + // Supervisor calls TinyUSB's dcd_init, + // which initializes the USB PHY. + // Depending on CIRCUITPY_TINYUSB and CIRCUITPY_USB_DEVICE + + // Interrupt enables are left to TUSB depending on the device class +} + +void USB_IRQHandler(void) { + // Schedules USB background callback + // appropriate to a given device class via TinyUSB lib + usb_irq_handler(0); +} diff --git a/ports/analog/tools/debug-dap.gdb b/ports/analog/tools/debug-dap.gdb new file mode 100644 index 00000000000..d0aa7e2b13f --- /dev/null +++ b/ports/analog/tools/debug-dap.gdb @@ -0,0 +1,3 @@ +target remote :3333 +break main +continue diff --git a/ports/analog/tools/debug-dap.sh b/ports/analog/tools/debug-dap.sh new file mode 100644 index 00000000000..df2964fcb12 --- /dev/null +++ b/ports/analog/tools/debug-dap.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Primer on taking cmd line args in Linux shell scripts +# $0 is the script itself +# $1 $2 $3 are arg1, arg2, arg3, etc + +# Export OCD Path +### USER ACTION: Replace with your path to OpenOCD ### +OCD_PATH="~/MaximSDK/Tools/OpenOCD" + +# Call openocd to setup the debug server, storing the PID for OpenOCD +sh -c "openocd -s $OCD_PATH/scripts -f interface/cmsis-dap.cfg -f target/$1.cfg -c \"init; reset halt\" " & + +# Allow enough time for OCD server to set up +# + wait for the sleep to finish +sleep 3 & +wait $! + +# spawn the gdb process and store the gdb_pid +gdb-multiarch build-apard32690/firmware.elf -x "tools/debug-dap.gdb" + +# when gdb exits, kill all openocd processes +killall openocd diff --git a/ports/analog/tools/flash_max32.jlink b/ports/analog/tools/flash_max32.jlink new file mode 100644 index 00000000000..0453f4cb077 --- /dev/null +++ b/ports/analog/tools/flash_max32.jlink @@ -0,0 +1,7 @@ +selectinterface swd +erase +loadbin build-apard32690/firmware.bin 0x10000000 +reset +halt +go +exit diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 0c4eb386130..0aaf6e3d849 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -107,7 +107,7 @@ else endif endif -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes -Werror=old-style-definition ifeq ($(CHIP_FAMILY), samd21) CFLAGS += \ @@ -117,7 +117,7 @@ CFLAGS += \ -msoft-float \ -mfloat-abi=soft \ -DSAMD21 -LIBS := libs/libgcc-12.1.0-Os-v6-m-nofp.a -lc +LIBS := libs/libgcc-14.2.0-Os-v6-m-nofp.a -lc else LIBS := -lgcc -lc endif @@ -169,7 +169,7 @@ LIBS += -lm endif ifeq ($(CHIP_FAMILY), samd21) -LDFLAGS += -mthumb -mcpu=cortex-m0plus -Lasf/thirdparty/CMSIS/Lib/GCC/ +LDFLAGS += -mthumb -mcpu=cortex-m0plus -Lasf/thirdparty/CMSIS/Lib/GCC/ # codespell:ignore thirdparty BOOTLOADER_SIZE := 0x2000 else ifeq ($(CHIP_FAMILY), samd51) LDFLAGS += -mthumb -mcpu=cortex-m4 @@ -284,6 +284,7 @@ SRC_C += \ lib/tinyusb/src/portable/microchip/samd/dcd_samd.c \ mphalport.c \ reset.c \ + shared/runtime/gchelper_native.c \ timer_handler.c \ $(SRC_PERIPHERALS) \ @@ -308,20 +309,11 @@ ifeq ($(CIRCUITPY_AUDIOBUSIO),1) SRC_C += peripherals/samd/i2s.c peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/i2s.c endif -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - -# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, -# because a few modules have files both in common-hal/ and shared-module/. -# Doing a $(sort ...) removes duplicates as part of sorting. -SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) - -SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s +ifeq ($(CHIP_FAMILY), samd21) +SRC_S += shared/runtime/gchelper_thumb1.s +else +SRC_S += shared/runtime/gchelper_thumb2.s +endif OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_ASF:.c=.o)) @@ -343,7 +335,7 @@ OBJ_EXTRA_ORDER_DEPS += $(HEADER_BUILD)/candata.h $(HEADER_BUILD)/candata.h: tools/mkcandata.py | $(HEADER_BUILD) $(Q)$(PYTHON) $< > $@ -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR += peripherals/samd/$(PERIPHERALS_CHIP_FAMILY)/clocks.c diff --git a/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h index 5979d1ee997..157db0d3f7f 100644 --- a/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/samd21/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h index e05560e6358..6dd21277b78 100644 --- a/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/samd51/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h index e05560e6358..6dd21277b78 100644 --- a/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/same51/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h b/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h index e05560e6358..6dd21277b78 100644 --- a/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h +++ b/ports/atmel-samd/asf4_conf/same54/hpl_sercom_config.h @@ -431,7 +431,7 @@ // <0x2=>8x arithmetic // <0x3=>8x fractional // <0x3=>3x -// How many over-sampling bits used when samling data state +// How many over-sampling bits used when sampling data state // usart_arch_sampr #ifndef CONF_SERCOM_2_USART_SAMPR #define CONF_SERCOM_2_USART_SAMPR 0x0 diff --git a/ports/atmel-samd/audio_dma.c b/ports/atmel-samd/audio_dma.c index 39c9dde648e..e3980401506 100644 --- a/ports/atmel-samd/audio_dma.c +++ b/ports/atmel-samd/audio_dma.c @@ -30,9 +30,7 @@ static audio_dma_t *audio_dma_state[AUDIO_DMA_CHANNEL_COUNT]; // This cannot be in audio_dma_state because it's volatile. static volatile bool audio_dma_pending[AUDIO_DMA_CHANNEL_COUNT]; -static bool audio_dma_allocated[AUDIO_DMA_CHANNEL_COUNT]; - -uint8_t find_sync_event_channel_raise() { +uint8_t find_sync_event_channel_raise(void) { uint8_t event_channel = find_sync_event_channel(); if (event_channel >= EVSYS_SYNCH_NUM) { mp_raise_RuntimeError(MP_ERROR_TEXT("All sync event channels in use")); @@ -40,33 +38,15 @@ uint8_t find_sync_event_channel_raise() { return event_channel; } -uint8_t dma_allocate_channel(void) { - uint8_t channel; - for (channel = 0; channel < AUDIO_DMA_CHANNEL_COUNT; channel++) { - if (!audio_dma_allocated[channel]) { - audio_dma_allocated[channel] = true; - return channel; - } - } - return channel; // i.e., return failure -} - -void dma_free_channel(uint8_t channel) { - assert(channel < AUDIO_DMA_CHANNEL_COUNT); - assert(audio_dma_allocated[channel]); - audio_dma_disable_channel(channel); - audio_dma_allocated[channel] = false; -} - void audio_dma_disable_channel(uint8_t channel) { - if (channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (channel == NO_DMA_CHANNEL) { return; } dma_disable_channel(channel); } void audio_dma_enable_channel(uint8_t channel) { - if (channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (channel == NO_DMA_CHANNEL) { return; } dma_enable_channel(channel); @@ -191,8 +171,8 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, bool output_signed, uint32_t output_register_address, uint8_t dma_trigger_source) { - uint8_t dma_channel = dma_allocate_channel(); - if (dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + uint8_t dma_channel = dma_allocate_audio_channel(); + if (dma_channel == NO_DMA_CHANNEL) { return AUDIO_DMA_DMA_BUSY; } @@ -220,15 +200,27 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, } - dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0], max_buffer_length); + dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0], + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + dma->buffer_length[0], // Old size + #endif + max_buffer_length); + dma->buffer_length[0] = max_buffer_length; + if (dma->buffer[0] == NULL) { return AUDIO_DMA_MEMORY_ERROR; } if (!dma->single_buffer) { - dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1], max_buffer_length); + dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1], + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + dma->buffer_length[1], // Old size + #endif + max_buffer_length); + dma->buffer_length[1] = max_buffer_length; + if (dma->buffer[1] == NULL) { return AUDIO_DMA_MEMORY_ERROR; } @@ -251,7 +243,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, } - if (audiosample_bits_per_sample(sample) == 16) { + if (audiosample_get_bits_per_sample(sample) == 16) { dma->beat_size = 2; dma->bytes_per_sample = 2; } else { @@ -262,7 +254,7 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, } } // Transfer both channels at once. - if (!single_channel_output && audiosample_channel_count(sample) == 2) { + if (!single_channel_output && audiosample_get_channel_count(sample) == 2) { dma->beat_size *= 2; } @@ -306,14 +298,14 @@ audio_dma_result audio_dma_setup_playback(audio_dma_t *dma, void audio_dma_stop(audio_dma_t *dma) { uint8_t channel = dma->dma_channel; - if (channel < AUDIO_DMA_CHANNEL_COUNT) { + if (channel != NO_DMA_CHANNEL) { audio_dma_disable_channel(channel); disable_event_channel(dma->event_channel); MP_STATE_PORT(playing_audio)[channel] = NULL; audio_dma_state[channel] = NULL; dma_free_channel(dma->dma_channel); } - dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT; + dma->dma_channel = NO_DMA_CHANNEL; dma->playing_in_progress = false; } @@ -326,7 +318,7 @@ void audio_dma_resume(audio_dma_t *dma) { } bool audio_dma_get_paused(audio_dma_t *dma) { - if (dma->dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (dma->dma_channel == NO_DMA_CHANNEL) { return false; } uint32_t status = dma_transfer_status(dma->dma_channel); @@ -335,22 +327,21 @@ bool audio_dma_get_paused(audio_dma_t *dma) { } void audio_dma_init(audio_dma_t *dma) { - dma->dma_channel = AUDIO_DMA_CHANNEL_COUNT; + dma->dma_channel = NO_DMA_CHANNEL; } void audio_dma_reset(void) { for (uint8_t i = 0; i < AUDIO_DMA_CHANNEL_COUNT; i++) { audio_dma_state[i] = NULL; audio_dma_pending[i] = false; - audio_dma_allocated[i] = false; - audio_dma_disable_channel(i); + dma_free_channel(i); dma_descriptor(i)->BTCTRL.bit.VALID = false; MP_STATE_PORT(playing_audio)[i] = NULL; } } bool audio_dma_get_playing(audio_dma_t *dma) { - if (dma->dma_channel >= AUDIO_DMA_CHANNEL_COUNT) { + if (dma->dma_channel == NO_DMA_CHANNEL) { return false; } return dma->playing_in_progress; diff --git a/ports/atmel-samd/audio_dma.h b/ports/atmel-samd/audio_dma.h index 284e2cbfd4f..7b42a7b6114 100644 --- a/ports/atmel-samd/audio_dma.h +++ b/ports/atmel-samd/audio_dma.h @@ -10,6 +10,7 @@ #include "py/obj.h" #include "shared-module/audiocore/RawSample.h" #include "shared-module/audiocore/WaveFile.h" +#include "shared-module/audiocore/__init__.h" #include "supervisor/background_callback.h" typedef struct { @@ -40,16 +41,9 @@ typedef enum { AUDIO_DMA_MEMORY_ERROR, } audio_dma_result; -uint32_t audiosample_sample_rate(mp_obj_t sample_obj); -uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj); -uint8_t audiosample_channel_count(mp_obj_t sample_obj); - void audio_dma_init(audio_dma_t *dma); void audio_dma_reset(void); -uint8_t dma_allocate_channel(void); -void dma_free_channel(uint8_t channel); - // This sets everything up but doesn't start the timer. // Sample is the python object for the sample to play. // loop is true if we should loop the sample. diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 2410f0fddb7..3d25bd340b1 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -14,7 +14,7 @@ #include "supervisor/shared/stack.h" #include "supervisor/port.h" -#ifdef CIRCUITPY_DISPLAYIO +#if CIRCUITPY_DISPLAYIO #include "shared-module/displayio/__init__.h" #endif diff --git a/ports/atmel-samd/bindings/samd/Clock.c b/ports/atmel-samd/bindings/samd/Clock.c index 1564d65fc8c..9610c6e8c3a 100644 --- a/ports/atmel-samd/bindings/samd/Clock.c +++ b/ports/atmel-samd/bindings/samd/Clock.c @@ -74,6 +74,7 @@ MP_PROPERTY_GETTER(samd_clock_frequency_obj, //| calibration: int //| """Clock calibration. Not all clocks can be calibrated.""" //| +//| static mp_obj_t samd_clock_get_calibration(mp_obj_t self_in) { samd_clock_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int_from_uint(clock_get_calibration(self->type, self->index)); diff --git a/ports/atmel-samd/bindings/samd/__init__.c b/ports/atmel-samd/bindings/samd/__init__.c index 9f3ad1c3dd0..114a1e7b74c 100644 --- a/ports/atmel-samd/bindings/samd/__init__.c +++ b/ports/atmel-samd/bindings/samd/__init__.c @@ -11,6 +11,7 @@ #include "bindings/samd/Clock.h" //| """SAMD implementation settings""" +//| //| """:mod:`samd.clock` --- samd clock names //| -------------------------------------------------------- diff --git a/ports/atmel-samd/boards/adafruit_trrs_trinkey_m0/mpconfigboard.h b/ports/atmel-samd/boards/adafruit_trrs_trinkey_m0/mpconfigboard.h index 8e53129679f..7b206ddaf54 100644 --- a/ports/atmel-samd/boards/adafruit_trrs_trinkey_m0/mpconfigboard.h +++ b/ports/atmel-samd/boards/adafruit_trrs_trinkey_m0/mpconfigboard.h @@ -40,3 +40,6 @@ // no PA29 #define IGNORE_PIN_PA30 1 #define IGNORE_PIN_PA31 1 + +// A couple Learn examples do `array.array('d', ...)` so enable it. +#define MICROPY_PY_DOUBLE_TYPECODE 1 diff --git a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/board.c b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/board.c new file mode 100644 index 00000000000..b44a1ae51e0 --- /dev/null +++ b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.h b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.h new file mode 100644 index 00000000000..cdd5c96aeba --- /dev/null +++ b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bradán Lane STUDIO +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Bradán Lane STUDIO Coin M0" +#define MICROPY_HW_MCU_NAME "samd21g18" + +#define MICROPY_HW_LED_STATUS (&pin_PA17) + +#define SPI_FLASH_MOSI_PIN &pin_PB22 +#define SPI_FLASH_MISO_PIN &pin_PB03 +#define SPI_FLASH_SCK_PIN &pin_PB23 +#define SPI_FLASH_CS_PIN &pin_PA27 + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 // USB_D+ +#define IGNORE_PIN_PA25 1 // USB_D- + +#define IGNORE_PIN_PA30 1 // SWCLK +#define IGNORE_PIN_PA31 1 // SWDIO diff --git a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk new file mode 100644 index 00000000000..9a2cdcd668e --- /dev/null +++ b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/mpconfigboard.mk @@ -0,0 +1,46 @@ +# This file is part of the CircuitPython project: https://circuitpython.org +# +# SPDX-FileCopyrightText: Copyright (c) 2024 Bradán Lane STUDIO +# +# SPDX-License-Identifier: MIT + +# TODO new VID:PID not yet approved via pidcodes.github.com +USB_VID = 0x1209 +USB_PID = 0x5687 + +USB_PRODUCT = "Coin M0" +USB_MANUFACTURER = "Bradán Lane STUDIO" + +CHIP_VARIANT = SAMD21G18A +CHIP_FAMILY = samd21 + +#CIRCUITPY_BUILD_EXTENSIONS = bin,uf2 + +SPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" +LONGINT_IMPL = MPZ + +# the M0 Coin has limited functionality and many modules can be eliminated + +# there may be more modules which are of no used but will require further digging + +# Disable modules that are unusable on this special-purpose board. + +CIRCUITPY_FULL_BUILD = 1 + +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 +CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_USB_HID = 1 +CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_NEOPIXEL_WRITE = 1 +CIRCUITPY_PIXELBUF = 1 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/atmel-samd/boards/bradanlanestudio_coin_m0/pins.c b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/pins.c new file mode 100644 index 00000000000..7e74918ee46 --- /dev/null +++ b/ports/atmel-samd/boards/bradanlanestudio_coin_m0/pins.c @@ -0,0 +1,35 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Neopixels + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PA07) }, + + // discrete LEDs + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PA19) }, + + // on-board LED + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PA17) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA02) }, // Analog only; no PWM + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH2), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH1), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH3), MP_ROM_PTR(&pin_PB02) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk index c647039bc8a..121becc472d 100755 --- a/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitbrains_basic_m0/mpconfigboard.mk @@ -10,4 +10,6 @@ SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" LONGINT_IMPL = MPZ -CIRCUITPY_JPEGIO = 0 +CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk index b470a2860e6..5c1cab422cb 100755 --- a/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitbrains_deluxe_m4/mpconfigboard.mk @@ -10,6 +10,9 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ, S25FL064L" LONGINT_IMPL = MPZ +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_PS2IO = 1 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_SPITARGET = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 diff --git a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk index 95123ae5b85..2ad140094b3 100644 --- a/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/datalore_ip_m4/mpconfigboard.mk @@ -9,5 +9,9 @@ CHIP_FAMILY = samd51 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JVxQ, W25Q16JVxM" LONGINT_IMPL = MPZ -CIRCUITPY_SYNTHIO = 0 + +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_SPITARGET = 0 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 diff --git a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk index 00418114841..1152fb4acc4 100644 --- a/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_express/mpconfigboard.mk @@ -10,4 +10,6 @@ SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ +CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h index be48cb81055..8fdf20f186b 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.h @@ -20,6 +20,8 @@ #define SPI_FLASH_SCK_PIN &pin_PA09 #define SPI_FLASH_CS_PIN &pin_PA13 +#define BOARD_HAS_CRYSTAL 1 + #define DEFAULT_I2C_BUS_SCL (&pin_PA23) #define DEFAULT_I2C_BUS_SDA (&pin_PA22) diff --git a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk index 811336885b8..dd58e8d1ce5 100644 --- a/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m0_supersized/mpconfigboard.mk @@ -9,3 +9,7 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "S25FL064L" LONGINT_IMPL = MPZ + +CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk index 57c1ac918f9..206716c6879 100644 --- a/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_can/mpconfigboard.mk @@ -13,9 +13,13 @@ LONGINT_IMPL = MPZ CIRCUITPY__EVE = 1 CIRCUITPY_BITMAPFILTER = 0 CIRCUITPY_CANIO = 1 -CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_GIFIO = 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_LTO_PARTITION = one diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h index 0ca05115204..ff6256eea6d 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.h @@ -41,6 +41,7 @@ #define IGNORE_PIN_PA27 1 #define IGNORE_PIN_PB00 1 #define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 #define IGNORE_PIN_PB06 1 #define IGNORE_PIN_PB07 1 #define IGNORE_PIN_PB30 1 diff --git a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk index 377e4f4f0f8..f780ea4aa3d 100644 --- a/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/feather_m4_express/mpconfigboard.mk @@ -11,9 +11,12 @@ EXTERNAL_FLASH_DEVICES = "GD25Q16C,W25Q16JVxQ" LONGINT_IMPL = MPZ CIRCUITPY__EVE = 1 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 -CIRCUITPY_SYNTHIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 # We don't have room for the fonts for terminalio for certain languages, # so turn off terminalio, and if it's off and displayio is on, diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index 637129a0e9d..fd5ad548512 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -54,9 +54,9 @@ void board_init(void) { common_hal_busio_spi_never_reset(spi); common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA28, // Command or data - &pin_PA01, // Chip select - &pin_PA27, // Reset + MP_OBJ_FROM_PTR(&pin_PA28), // Command or data + MP_OBJ_FROM_PTR(&pin_PA01), // Chip select + MP_OBJ_FROM_PTR(&pin_PA27), // Reset 12000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/hallowing_m4_express/board.c b/ports/atmel-samd/boards/hallowing_m4_express/board.c index bfef5fbcd75..c7217b70b0a 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m4_express/board.c @@ -35,9 +35,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB31, // TFT_DC Command or data - &pin_PA27, // TFT_CS Chip select - &pin_PB30, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PB31), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA27), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PB30), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk index 74f1d3e5599..76c60b44646 100644 --- a/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/hallowing_m4_express/mpconfigboard.mk @@ -11,5 +11,13 @@ EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" LONGINT_IMPL = MPZ CIRCUITPY_AESIO = 0 -CIRCUITPY_JPEGIO = 0 -CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_CODEOP = 0 +CIRCUITPY_EPAPERDISPLAY = 0 +CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_I2CDISPLAYBUS = 0 +CIRCUITPY_I2CTARGET = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_SHARPDISPLAY = 0 +CIRCUITPY_SPITARGET = 0 diff --git a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk index 4c11a905baa..be22cb94fae 100644 --- a/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/itsybitsy_m4_express/mpconfigboard.mk @@ -10,8 +10,22 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "GD25Q16C,W25Q16JVxQ" LONGINT_IMPL = MPZ +CIRCUITPY__EVE = 1 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 -CIRCUITPY_GIFIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_BITBANG_APA102 = 1 + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk index ea38dc9d538..d4801359cf8 100644 --- a/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m0_express/mpconfigboard.mk @@ -10,4 +10,6 @@ SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ +CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk index 69cd5b0e286..cb7e690c6c0 100644 --- a/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_airlift_lite/mpconfigboard.mk @@ -11,9 +11,13 @@ EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ CIRCUITPY__EVE = 0 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 + # We don't have room for the fonts for terminalio for certain languages, # so turn off terminalio, and if it's off and displayio is on, diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h index c3074a5740d..b7ca7986ded 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.h @@ -48,3 +48,5 @@ #define IGNORE_PIN_PB04 1 #define IGNORE_PIN_PB05 1 #define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 diff --git a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk index 4f01c141e48..d5aef01a037 100644 --- a/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk +++ b/ports/atmel-samd/boards/metro_m4_express/mpconfigboard.mk @@ -11,9 +11,12 @@ EXTERNAL_FLASH_DEVICES = "S25FL116K, S25FL216K, GD25Q16C, W25Q16JVxQ" LONGINT_IMPL = MPZ CIRCUITPY__EVE = 1 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 # We don't have room for the fonts for terminalio for certain languages, # so turn off terminalio, and if it's off and displayio is on, diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/board.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/board.c new file mode 100644 index 00000000000..b44a1ae51e0 --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.h b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.h new file mode 100644 index 00000000000..4416d8517d2 --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.h @@ -0,0 +1,33 @@ + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Microchip Curiosity CircuitPython" +#define MICROPY_HW_MCU_NAME "same51j20" +#define CIRCUITPY_MCU_FAMILY samd51 + +#define MICROPY_HW_LED_STATUS (&pin_PB23) +#define MICROPY_HW_NEOPIXEL (&pin_PB22) + +#define BOARD_HAS_CRYSTAL 1 + +// USB is always used internally so skip the pin objects for it. +#define IGNORE_PIN_PA24 1 +#define IGNORE_PIN_PA25 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_PB30) +#define DEFAULT_I2C_BUS_SDA (&pin_PB31) + +#define CIRCUITPY_BOARD_SPI (3) +// These correspond to the CIRCUITPY_BOARD_BUS_SINGLETON definitions in pins.c +#define CIRCUITPY_BOARD_SPI_PIN { \ + {.clock = &pin_PB03, .mosi = &pin_PB02, .miso = &pin_PB00}, /*board.SPI()*/ \ + {.clock = &pin_PA05, .mosi = &pin_PA04, .miso = NULL}, /*board.LCD_SPI()*/ \ + {.clock = &pin_PA17, .mosi = &pin_PA16, .miso = &pin_PA18}, /*board.SD_SPI()*/ \ +} + +#define DEFAULT_CAN_BUS_TX (&pin_PB12) +#define DEFAULT_CAN_BUS_RX (&pin_PB13) +#define DEFAULT_CAN_BUS_STDBY (&pin_PB17) + +#define DEFAULT_UART_BUS_RX (&pin_PA23) +#define DEFAULT_UART_BUS_TX (&pin_PA22) diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.mk b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.mk new file mode 100644 index 00000000000..985eb4c6a44 --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x04D8 +USB_PID = 0xE52B +USB_PRODUCT = "Microchip Curiosity CircuitPython" +USB_MANUFACTURER = "Microchip Technology Inc" + +CHIP_VARIANT = SAME51J20A +CHIP_FAMILY = same51 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "SST26VF016B,SST26VF032B,SST26VF064B" +LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 +CIRCUITPY_CANIO = 1 diff --git a/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c new file mode 100644 index 00000000000..49c7f7565e2 --- /dev/null +++ b/ports/atmel-samd/boards/microchip_curiosity_circuitpython/pins.c @@ -0,0 +1,91 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +// The singleton for board.SPI() is already defined. +// board.LCD_SPI() +CIRCUITPY_BOARD_BUS_SINGLETON(lcd_spi, spi, 1) +// board.SD_SPI() +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 2) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PA20) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PA21) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PA27) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB16) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PB23) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB23) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_PB22) }, + + { MP_ROM_QSTR(MP_QSTR_VREF), MP_ROM_PTR(&pin_PA03) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&pin_PA02) }, + + { MP_ROM_QSTR(MP_QSTR_CAP1), MP_ROM_PTR(&pin_PB09) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_PA06) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB30) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB31) }, + + { MP_ROM_QSTR(MP_QSTR_BLE_TX), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_BLE_RX), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_BLE_CLR), MP_ROM_PTR(&pin_PA14) }, + + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_PA16) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_PA18) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_PA17) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_PA19) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT), MP_ROM_PTR(&pin_PB00) }, + + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_IMU_ADDR), MP_ROM_PTR(&pin_PB01) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB02) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB03) }, + + { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_PA22) }, + { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_PA23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_PB13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_PB12) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_CAN_STDBY), MP_ROM_PTR(&pin_PB17) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PB17) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_lcd_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk index 73c56fb5fba..8fae53c0101 100644 --- a/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/mini_sam_m4/mpconfigboard.mk @@ -10,9 +10,13 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q16JVxM, W25Q16JVxQ" LONGINT_IMPL = MPZ +CIRCUITPY__EVE = 1 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 CIRCUITPY_BITBANG_APA102 = 1 diff --git a/ports/atmel-samd/boards/monster_m4sk/board.c b/ports/atmel-samd/boards/monster_m4sk/board.c index 1d4fd69b7f7..1c143ad9270 100644 --- a/ports/atmel-samd/boards/monster_m4sk/board.c +++ b/ports/atmel-samd/boards/monster_m4sk/board.c @@ -35,9 +35,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA07, // TFT_DC Command or data - &pin_PA06, // TFT_CS Chip select - &pin_PA04, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PA07), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA06), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA04), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/openbook_m4/board.c b/ports/atmel-samd/boards/openbook_m4/board.c index 032ebe9f628..ebabfb84e9b 100644 --- a/ports/atmel-samd/boards/openbook_m4/board.c +++ b/ports/atmel-samd/boards/openbook_m4/board.c @@ -44,49 +44,33 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB05, // EPD_DC Command or data - &pin_PB07, // EPD_CS Chip select - &pin_PA00, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_PB05), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB07), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA00), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct(display, - bus, - start_sequence, - sizeof(start_sequence), - 0, // start up time - stop_sequence, - sizeof(stop_sequence), - 300, // width - 400, // height - 300, // RAM width - 400, // RAM height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x13, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command (can add this for grayscale eventually) - false, // color_bits_inverted - 0x000000, // highlight_color - refresh_sequence, // refresh_display_sequence - sizeof(refresh_sequence), - 40, // refresh_time - &pin_PA01, // busy_pin - false, // busy_state - 5, // seconds_per_frame - false, // chip_select (don't always toggle chip select) - false, // grayscale - false, // acep - false, // two_byte_sequence_length - false); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = start_sequence; + args.start_sequence_len = sizeof(start_sequence); + args.stop_sequence = stop_sequence; + args.stop_sequence_len = sizeof(stop_sequence); + args.width = 300; + args.height = 400; + args.ram_width = 300; + args.ram_height = 400; + args.rotation = 270; + args.write_black_ram_command = 0x13; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 40.0; + args.busy_pin = &pin_PA01; + args.seconds_per_frame = 5.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk index c6eaa6bd64d..2701fd249f9 100644 --- a/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk +++ b/ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk @@ -10,6 +10,10 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ +CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_I2CTARGET = 0 +CIRCUITPY_JPEGIO = 0 CIRCUITPY_KEYPAD = 1 CIRCUITPY_SYNTHIO = 0 -CIRCUITPY_JPEGIO = 0 +CIRCUITPY_TERMINALIO_VT100 = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 diff --git a/ports/atmel-samd/boards/pewpew_lcd/board.c b/ports/atmel-samd/boards/pewpew_lcd/board.c index 6a10132e11d..d60efd39bf7 100644 --- a/ports/atmel-samd/boards/pewpew_lcd/board.c +++ b/ports/atmel-samd/boards/pewpew_lcd/board.c @@ -54,9 +54,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA19, // TFT_DC Command or data - &pin_PA17, // TFT_CS Chip select - &pin_PA18, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PA19), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA17), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA18), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk b/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk index 823f5698156..58047f2506e 100644 --- a/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pewpew_lcd/mpconfigboard.mk @@ -41,7 +41,8 @@ CIRCUITPY_BITBANG_APA102 = 0 CIRCUITPY_BITBANGIO = 0 CIRCUITPY_BITMAPFILTER = 0 CIRCUITPY_BITMAPTOOLS = 0 -CIRCUITPY_BLEIO = 0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BLEIO_NATIVE = 0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 @@ -54,6 +55,7 @@ CIRCUITPY_PULSEIO = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_ROTARYIO = 0 CIRCUITPY_RTC = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 CIRCUITPY_ULAB = 0 CIRCUITPY_USB_HID = 0 CIRCUITPY_USB_MIDI = 0 diff --git a/ports/atmel-samd/boards/pewpew_m4/board.c b/ports/atmel-samd/boards/pewpew_m4/board.c index 2007d755c69..ac67b82a3dc 100644 --- a/ports/atmel-samd/boards/pewpew_m4/board.c +++ b/ports/atmel-samd/boards/pewpew_m4/board.c @@ -83,9 +83,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA16, // TFT_DC Command or data - &pin_PA11, // TFT_CS Chip select - &pin_PA17, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PA16), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PA11), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA17), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pybadge/board.c b/ports/atmel-samd/boards/pybadge/board.c index 545918374e2..e938e96e19e 100644 --- a/ports/atmel-samd/boards/pybadge/board.c +++ b/ports/atmel-samd/boards/pybadge/board.c @@ -56,9 +56,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB05, // TFT_DC Command or data - &pin_PB07, // TFT_CS Chip select - &pin_PA00, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PB05), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB07), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA00), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk index 8005146114a..70571b6c77d 100644 --- a/ports/atmel-samd/boards/pybadge/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pybadge/mpconfigboard.mk @@ -18,6 +18,17 @@ CIRCUITPY_I2CDISPLAYBUS = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_KEYPAD = 1 CIRCUITPY_PARALLELDISPLAYBUS= 0 +CIRCUITPY_SPITARGET = 0 CIRCUITPY_STAGE = 1 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pybadge + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk index 347462919f8..08d867c6e1c 100644 --- a/ports/atmel-samd/boards/pycubed/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed/mpconfigboard.mk @@ -27,8 +27,8 @@ CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 -CIRCUITPY_BLEIO_HCI=0 -CIRCUITPY_BLEIO=0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BLEIO_NATIVE = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk index ac8af21dcb6..52129f0b187 100644 --- a/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed_mram/mpconfigboard.mk @@ -27,8 +27,8 @@ CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 -CIRCUITPY_BLEIO_HCI=0 -CIRCUITPY_BLEIO=0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BLEIO_NATIVE = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/atmel-samd/boards/pycubed_mram_v05/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed_mram_v05/mpconfigboard.mk index ac8af21dcb6..52129f0b187 100644 --- a/ports/atmel-samd/boards/pycubed_mram_v05/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed_mram_v05/mpconfigboard.mk @@ -27,8 +27,8 @@ CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 -CIRCUITPY_BLEIO_HCI=0 -CIRCUITPY_BLEIO=0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BLEIO_NATIVE = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/atmel-samd/boards/pycubed_v05/mpconfigboard.mk b/ports/atmel-samd/boards/pycubed_v05/mpconfigboard.mk index 923ab2eaaef..43d3b9f1f83 100644 --- a/ports/atmel-samd/boards/pycubed_v05/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pycubed_v05/mpconfigboard.mk @@ -28,8 +28,8 @@ CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_PS2IO = 0 -CIRCUITPY_BLEIO_HCI=0 -CIRCUITPY_BLEIO=0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BLEIO_NATIVE = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/atmel-samd/boards/pygamer/board.c b/ports/atmel-samd/boards/pygamer/board.c index 53275ac686a..fcf6aff0e65 100644 --- a/ports/atmel-samd/boards/pygamer/board.c +++ b/ports/atmel-samd/boards/pygamer/board.c @@ -57,9 +57,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PB05, // TFT_DC Command or data - &pin_PB12, // TFT_CS Chip select - &pin_PA00, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PB05), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB12), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PA00), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk index 5149dda508f..0c6f16f8b63 100644 --- a/ports/atmel-samd/boards/pygamer/mpconfigboard.mk +++ b/ports/atmel-samd/boards/pygamer/mpconfigboard.mk @@ -12,12 +12,24 @@ LONGINT_IMPL = MPZ CIRCUITPY_AESIO = 0 CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_EPAPERDISPLAY = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_GIFIO = 0 CIRCUITPY_I2CDISPLAYBUS = 0 CIRCUITPY_JPEGIO = 0 CIRCUITPY_KEYPAD = 1 CIRCUITPY_PARALLELDISPLAYBUS= 0 +CIRCUITPY_SPITARGET = 0 CIRCUITPY_STAGE = 1 FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/pygamer + +# We don't have room for the fonts for terminalio for certain languages, +# so turn off terminalio, and if it's off and displayio is on, +# force a clean build. +# Note that we cannot test $(CIRCUITPY_DISPLAYIO) directly with an +# ifeq, because it's not set yet. +ifneq (,$(filter $(TRANSLATION),ja ko ru)) +CIRCUITPY_TERMINALIO = 0 +RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) +endif diff --git a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c index d3d1ae3a956..1ee80c98786 100644 --- a/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c +++ b/ports/atmel-samd/boards/seeeduino_wio_terminal/board.c @@ -52,9 +52,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PC06, // TFT_DC Command or data - &pin_PB21, // TFT_CS Chip select - &pin_PC07, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_PC06), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_PB21), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_PC07), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk b/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk index dd8afd51f6e..4ade6a14831 100644 --- a/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk +++ b/ports/atmel-samd/boards/seeeduino_wio_terminal/mpconfigboard.mk @@ -9,6 +9,14 @@ CHIP_FAMILY = samd51 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" LONGINT_IMPL = MPZ + +CIRCUITPY__EVE = 1 +CIRCUITPY_CODEOP = 0 CIRCUITPY_FLOPPYIO = 0 -CIRCUITPY_FRAMEBUFFERIO = 0 +CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_SHARPDISPLAY = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_VECTORIO = 0 diff --git a/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk index 7c576a0376b..99c447b7a9d 100644 --- a/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk +++ b/ports/atmel-samd/boards/silicognition-m4-shim/mpconfigboard.mk @@ -10,5 +10,8 @@ QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = GD25Q16C LONGINT_IMPL = MPZ +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_SPITARGET = 0 CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 diff --git a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk index d19e606319b..441853c554d 100644 --- a/ports/atmel-samd/boards/snekboard/mpconfigboard.mk +++ b/ports/atmel-samd/boards/snekboard/mpconfigboard.mk @@ -9,3 +9,6 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" LONGINT_IMPL = MPZ + +CIRCUITPY_CODEOP = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk index ef23e560224..b34dfb3d2e6 100755 --- a/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk +++ b/ports/atmel-samd/boards/sparkfun_redboard_turbo/mpconfigboard.mk @@ -10,4 +10,6 @@ SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q32FV" LONGINT_IMPL = MPZ +CIRCUITPY_CODEOP = 0 +CIRCUITPY_ERRNO = 0 CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h index bc157d6c86b..7eec1d64f8e 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.h @@ -31,6 +31,43 @@ #define DEFAULT_UART_BUS_RX (&pin_PA07) #define DEFAULT_UART_BUS_TX (&pin_PA06) +#define IGNORE_PIN_PA03 1 +#define IGNORE_PIN_PA04 1 +#define IGNORE_PIN_PA12 1 +#define IGNORE_PIN_PA13 1 +#define IGNORE_PIN_PA14 1 +#define IGNORE_PIN_PA15 1 +#define IGNORE_PIN_PA18 1 +#define IGNORE_PIN_PA20 1 +#define IGNORE_PIN_PA21 1 +#define IGNORE_PIN_PA22 1 +#define IGNORE_PIN_PA23 1 // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 +#define IGNORE_PIN_PA27 1 +#define IGNORE_PIN_PA28 1 +#define IGNORE_PIN_PA30 1 +#define IGNORE_PIN_PA31 1 +#define IGNORE_PIN_PB01 1 +#define IGNORE_PIN_PB02 1 +#define IGNORE_PIN_PB03 1 +#define IGNORE_PIN_PB04 1 +#define IGNORE_PIN_PB05 1 +#define IGNORE_PIN_PB06 1 +#define IGNORE_PIN_PB07 1 +#define IGNORE_PIN_PB08 1 +#define IGNORE_PIN_PB09 1 +#define IGNORE_PIN_PB10 1 +#define IGNORE_PIN_PB11 1 +#define IGNORE_PIN_PB12 1 +#define IGNORE_PIN_PB13 1 +#define IGNORE_PIN_PB14 1 +#define IGNORE_PIN_PB15 1 +#define IGNORE_PIN_PB16 1 +#define IGNORE_PIN_PB17 1 +#define IGNORE_PIN_PB22 1 +#define IGNORE_PIN_PB23 1 +#define IGNORE_PIN_PB30 1 +#define IGNORE_PIN_PB31 1 +#define IGNORE_PIN_PB00 1 diff --git a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk index 028114091ec..29b5865d419 100644 --- a/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk +++ b/ports/atmel-samd/boards/trinket_m0_haxpress/mpconfigboard.mk @@ -9,3 +9,5 @@ CHIP_FAMILY = samd21 SPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = W25Q32BV LONGINT_IMPL = MPZ + +CIRCUITPY_CODEOP = 0 diff --git a/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk b/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk index 1181abd9640..3ce42ed3a7e 100644 --- a/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk +++ b/ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk @@ -9,5 +9,10 @@ CHIP_FAMILY = samd51 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" LONGINT_IMPL = MPZ + +CIRCUITPY_I2CTARGET = 0 +CIRCUITPY_SPITARGET = 0 CIRCUITPY_SYNTHIO = 0 CIRCUITPY_JPEGIO = 0 +CIRCUITPY_TERMINALIO_VT100 = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index bbf3839c516..34f769e358f 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -53,9 +53,9 @@ void board_init(void) { busio_spi_obj_t *spi = common_hal_board_create_spi(0); common_hal_fourwire_fourwire_construct(bus, spi, - &pin_PA09, // Command or data - &pin_PA08, // Chip select - NULL, // Reset + MP_OBJ_FROM_PTR(&pin_PA09), // Command or data + MP_OBJ_FROM_PTR(&pin_PA08), // Chip select + mp_const_none, // Reset 24000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk index d23ce47f58f..e2f0ab66145 100644 --- a/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk +++ b/ports/atmel-samd/boards/winterbloom_big_honking_button/mpconfigboard.mk @@ -21,7 +21,8 @@ CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_AUDIOBUSIO = 0 -CIRCUITPY_BLEIO = 0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BLEIO_NATIVE = 0 CIRCUITPY_DISPLAYIO = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_I2CTARGET = 0 diff --git a/ports/atmel-samd/common-hal/_pew/PewPew.c b/ports/atmel-samd/common-hal/_pew/PewPew.c index 84ff7bc16c7..c3f9330faae 100644 --- a/ports/atmel-samd/common-hal/_pew/PewPew.c +++ b/ports/atmel-samd/common-hal/_pew/PewPew.c @@ -38,7 +38,7 @@ void pewpew_interrupt_handler(uint8_t index) { tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; } -void pew_init() { +void pew_init(void) { pew_obj_t *pew = MP_STATE_VM(pew_singleton); common_hal_digitalio_digitalinout_switch_to_input(pew->buttons, PULL_UP); @@ -105,6 +105,6 @@ void pew_reset(void) { MP_STATE_VM(pew_singleton) = NULL; } -uint16_t pew_get_ticks() { +uint16_t pew_get_ticks(void) { return pewpew_ticks; } diff --git a/ports/atmel-samd/common-hal/alarm/__init__.c b/ports/atmel-samd/common-hal/alarm/__init__.c index 483aa1a9679..153647f4e89 100644 --- a/ports/atmel-samd/common-hal/alarm/__init__.c +++ b/ports/atmel-samd/common-hal/alarm/__init__.c @@ -127,13 +127,10 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { - if (n_dios > 0) { - mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_preserve_dios); - } _setup_sleep_alarms(true, n_alarms, alarms); } -void NORETURN common_hal_alarm_enter_deep_sleep(void) { +void MP_NORETURN common_hal_alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); alarm_time_timealarm_prepare_for_deep_sleep(); // port_disable_tick(); // TODO: Required for SAMD? diff --git a/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.c b/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.c index 44396fa8e8a..de98b7ec85a 100644 --- a/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/atmel-samd/common-hal/alarm/touch/TouchAlarm.c @@ -7,6 +7,6 @@ #include "shared-bindings/alarm/touch/TouchAlarm.h" #include "shared-bindings/microcontroller/__init__.h" -void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) { +MP_NORETURN void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_TouchAlarm); } diff --git a/ports/atmel-samd/common-hal/analogio/AnalogIn.c b/ports/atmel-samd/common-hal/analogio/AnalogIn.c index c633cf44b67..801ab18f7fd 100644 --- a/ports/atmel-samd/common-hal/analogio/AnalogIn.c +++ b/ports/atmel-samd/common-hal/analogio/AnalogIn.c @@ -64,7 +64,7 @@ void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { self->pin = NULL; } -void analogin_reset() { +void analogin_reset(void) { } uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { diff --git a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c index b8c8e93e88d..e12fe731000 100644 --- a/ports/atmel-samd/common-hal/audiobusio/I2SOut.c +++ b/ports/atmel-samd/common-hal/audiobusio/I2SOut.c @@ -77,7 +77,11 @@ void i2sout_reset(void) { // Caller validates that pins are free. void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, - const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) { + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified, + bool external_clock) { + if (external_clock) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_external_clock); + } if (main_clock != NULL) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_main_clock); } @@ -211,15 +215,18 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, if (common_hal_audiobusio_i2sout_get_playing(self)) { common_hal_audiobusio_i2sout_stop(self); } + + audiosample_check(sample); + #ifdef SAMD21 if ((I2S->CTRLA.vec.CKEN & (1 << self->clock_unit)) == 1) { mp_raise_RuntimeError(MP_ERROR_TEXT("Clock unit in use")); } #endif - uint8_t bits_per_sample = audiosample_bits_per_sample(sample); + uint8_t bits_per_sample = audiosample_get_bits_per_sample(sample); // We always output stereo so output twice as many bits. uint16_t bits_per_sample_output = bits_per_sample * 2; - uint16_t divisor = 48000000 / (bits_per_sample_output * audiosample_sample_rate(sample)); + uint16_t divisor = 48000000 / (bits_per_sample_output * audiosample_get_sample_rate(sample)); // Find a free GCLK to generate the MCLK signal. uint8_t gclk = find_free_gclk(divisor); if (gclk > GCLK_GEN_NUM) { @@ -235,7 +242,7 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, } else { clkctrl |= I2S_CLKCTRL_FSOUTINV | I2S_CLKCTRL_BITDELAY_I2S; } - uint8_t channel_count = audiosample_channel_count(sample); + uint8_t channel_count = audiosample_get_channel_count(sample); if (channel_count > 2) { mp_raise_ValueError(MP_ERROR_TEXT("Too many channels in sample")); } @@ -245,7 +252,7 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, #ifdef SAM_D5X_E5X uint32_t serctrl = (self->clock_unit << I2S_RXCTRL_CLKSEL_Pos) | I2S_TXCTRL_TXSAME_SAME; #endif - if (audiosample_channel_count(sample) == 1) { + if (audiosample_get_channel_count(sample) == 1) { serctrl |= SERCTRL(MONO_MONO); } else { serctrl |= SERCTRL(MONO_STEREO); diff --git a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c index 3244d06979e..f409563f5ed 100644 --- a/ports/atmel-samd/common-hal/audiobusio/PDMIn.c +++ b/ports/atmel-samd/common-hal/audiobusio/PDMIn.c @@ -364,7 +364,7 @@ static uint16_t filter_sample(uint32_t pdm_samples[4]) { // output_buffer_length is the number of slots, not the number of bytes. uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t *self, uint16_t *output_buffer, uint32_t output_buffer_length) { - uint8_t dma_channel = dma_allocate_channel(); + uint8_t dma_channel = dma_allocate_audio_channel(); pdmin_event_channel = find_sync_event_channel_raise(); pdmin_dma_block_done = false; diff --git a/ports/atmel-samd/common-hal/audioio/AudioOut.c b/ports/atmel-samd/common-hal/audioio/AudioOut.c index e6c90243fa5..9bff11fa6b4 100644 --- a/ports/atmel-samd/common-hal/audioio/AudioOut.c +++ b/ports/atmel-samd/common-hal/audioio/AudioOut.c @@ -79,6 +79,9 @@ static void ramp_value(uint16_t start, uint16_t end) { // Caller validates that pins are free. void common_hal_audioio_audioout_construct(audioio_audioout_obj_t *self, const mcu_pin_obj_t *left_channel, const mcu_pin_obj_t *right_channel, uint16_t quiescent_value) { + + // The case of left_channel == right_channel is already disallowed in shared-bindings. + #ifdef SAM_D5X_E5X bool dac_clock_enabled = hri_mclk_get_APBDMASK_DAC_bit(MCLK); #endif @@ -107,10 +110,6 @@ void common_hal_audioio_audioout_construct(audioio_audioout_obj_t *self, if (right_channel != NULL && right_channel != &pin_PA02 && right_channel != &pin_PA05) { raise_ValueError_invalid_pin_name(MP_QSTR_right_channel); } - if (right_channel == left_channel) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("%q and %q must be different"), - MP_QSTR_left_channel, MP_QSTR_right_channel); - } claim_pin(left_channel); if (right_channel != NULL) { claim_pin(right_channel); @@ -332,8 +331,11 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self, if (common_hal_audioio_audioout_get_playing(self)) { common_hal_audioio_audioout_stop(self); } + + audiosample_check(sample); + audio_dma_result result = AUDIO_DMA_OK; - uint32_t sample_rate = audiosample_sample_rate(sample); + uint32_t sample_rate = audiosample_get_sample_rate(sample); #ifdef SAMD21 const uint32_t max_sample_rate = 350000; #endif @@ -364,12 +366,12 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self, right_channel_reg = (uint32_t)&DAC->DATABUF[0].reg; } - size_t num_channels = audiosample_channel_count(sample); + size_t num_channels = audiosample_get_channel_count(sample); if (num_channels == 2 && // Are DAC channels sequential? left_channel_reg + 2 == right_channel_reg && - audiosample_bits_per_sample(sample) == 16) { + audiosample_get_bits_per_sample(sample) == 16) { result = audio_dma_setup_playback(&self->left_dma, sample, loop, false, 0, false /* output unsigned */, left_channel_reg, @@ -403,7 +405,7 @@ void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self, } } Tc *timer = tc_insts[self->tc_index]; - set_timer_frequency(timer, audiosample_sample_rate(sample)); + set_timer_frequency(timer, audiosample_get_sample_rate(sample)); timer->COUNT16.CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER; while (timer->COUNT16.STATUS.bit.STOP == 1) { } diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index 9c15848f568..d9da050dabe 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -53,7 +53,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, uint32_t sda_pinmux, scl_pinmux; // Ensure the object starts in its deinit state. - self->sda_pin = NO_PIN; + common_hal_busio_i2c_mark_deinit(self); + Sercom *sercom = samd_i2c_get_sercom(scl, sda, &sercom_index, &sda_pinmux, &scl_pinmux); if (sercom == NULL) { raise_ValueError_invalid_pins(); @@ -108,33 +109,40 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, mp_arg_error_invalid(MP_QSTR_frequency); } + if (i2c_m_sync_enable(&self->i2c_desc) != ERR_NONE) { + common_hal_busio_i2c_deinit(self); + mp_raise_OSError(MP_EIO); + } + self->sda_pin = sda->number; self->scl_pin = scl->number; claim_pin(sda); claim_pin(scl); - if (i2c_m_sync_enable(&self->i2c_desc) != ERR_NONE) { - common_hal_busio_i2c_deinit(self); - mp_raise_OSError(MP_EIO); - } + // Prevent bulk sercom reset from resetting us. The finalizer will instead. + never_reset_sercom(self->i2c_desc.device.hw); } bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { return self->sda_pin == NO_PIN; } +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + self->sda_pin = NO_PIN; +} + void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { if (common_hal_busio_i2c_deinited(self)) { return; } + allow_reset_sercom(self->i2c_desc.device.hw); i2c_m_sync_disable(&self->i2c_desc); i2c_m_sync_deinit(&self->i2c_desc); reset_pin_number(self->sda_pin); reset_pin_number(self->scl_pin); - self->sda_pin = NO_PIN; - self->scl_pin = NO_PIN; + common_hal_busio_i2c_mark_deinit(self); } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { @@ -168,7 +176,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_negative_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { uint16_t attempts = ATTEMPTS; @@ -189,17 +197,17 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, if (status == I2C_OK) { return 0; } else if (status == I2C_ERR_BAD_ADDRESS) { - return MP_ENODEV; + return -MP_ENODEV; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { uint16_t attempts = ATTEMPTS; @@ -220,14 +228,14 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, if (status == ERR_NONE) { return 0; } else if (status == I2C_ERR_BAD_ADDRESS) { - return MP_ENODEV; + return -MP_ENODEV; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_negative_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } @@ -236,8 +244,6 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { - never_reset_sercom(self->i2c_desc.device.hw); - never_reset_pin_number(self->scl_pin); never_reset_pin_number(self->sda_pin); } diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 1da42aaad09..19fd81e425d 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -17,11 +17,22 @@ #include "hal/include/hal_gpio.h" #include "hal/include/hal_spi_m_sync.h" -#include "hal/include/hpl_spi_m_sync.h" #include "samd/dma.h" #include "samd/sercom.h" + +static void setup_pin(const mcu_pin_obj_t *pin, uint32_t pinmux, const enum gpio_direction direction) { + gpio_set_pin_direction(pin->number, direction); + gpio_set_pin_pull_mode(pin->number, GPIO_PULL_OFF); + gpio_set_pin_function(pin->number, pinmux); + if (direction == GPIO_DIRECTION_OUT) { + // Use strong drive strength for SPI outputs. + hri_port_set_PINCFG_DRVSTR_bit(PORT, (enum gpio_port)GPIO_PORT(pin->number), GPIO_PIN(pin->number)); + } + claim_pin(pin); +} + void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { @@ -42,7 +53,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } // Ensure the object starts in its deinit state. - self->clock_pin = NO_PIN; + common_hal_busio_spi_mark_deinit(self); // Special case for SAMR21 boards. (feather_radiofruit_zigbee) #if defined(PIN_PC19F_SERCOM4_PAD0) @@ -76,6 +87,7 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, if (!samd_peripherals_valid_spi_clock_pad(clock_pad)) { continue; } + // find mosi_pad first, since it corresponds to dopo which takes limited values for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { if (!mosi_none) { if (sercom_index == mosi->sercom[j].index) { @@ -125,6 +137,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Pads must be set after spi_m_sync_init(), which uses default values from // the prototypical SERCOM. + + // Set to SPI host mode and choose pads. + hri_sercomspi_write_CTRLA_MODE_bf(sercom, 3); hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo); hri_sercomspi_write_CTRLA_DIPO_bf(sercom, miso_pad); @@ -137,30 +152,21 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_OSError(MP_EIO); } - gpio_set_pin_direction(clock->number, GPIO_DIRECTION_OUT); - gpio_set_pin_pull_mode(clock->number, GPIO_PULL_OFF); - gpio_set_pin_function(clock->number, clock_pinmux); - claim_pin(clock); + setup_pin(clock, clock_pinmux, GPIO_DIRECTION_OUT); self->clock_pin = clock->number; if (mosi_none) { self->MOSI_pin = NO_PIN; } else { - gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_OUT); - gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF); - gpio_set_pin_function(mosi->number, mosi_pinmux); + setup_pin(mosi, mosi_pinmux, GPIO_DIRECTION_OUT); self->MOSI_pin = mosi->number; - claim_pin(mosi); } if (miso_none) { self->MISO_pin = NO_PIN; } else { - gpio_set_pin_direction(miso->number, GPIO_DIRECTION_IN); - gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF); - gpio_set_pin_function(miso->number, miso_pinmux); + setup_pin(miso, miso_pinmux, GPIO_DIRECTION_IN); self->MISO_pin = miso->number; - claim_pin(miso); } spi_m_sync_enable(&self->spi_desc); @@ -178,6 +184,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock_pin == NO_PIN; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock_pin = NO_PIN; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -189,7 +199,9 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { reset_pin_number(self->clock_pin); reset_pin_number(self->MOSI_pin); reset_pin_number(self->MISO_pin); - self->clock_pin = NO_PIN; + + // This smashes self->clock_pin, so don't do it before resetting the pin above. + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c b/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c index 05d5075e578..56eb82678ec 100644 --- a/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c +++ b/ports/atmel-samd/common-hal/imagecapture/ParallelImageCapture.c @@ -135,7 +135,8 @@ void common_hal_imagecapture_parallelimagecapture_singleshot_capture(imagecaptur mp_buffer_info_t bufinfo; mp_get_buffer_raise(buffer, &bufinfo, MP_BUFFER_RW); - uint8_t dma_channel = dma_allocate_channel(); + // Allocate a permanent channel (not really audio). + uint8_t dma_channel = dma_allocate_audio_channel(); uint32_t *dest = bufinfo.buf; size_t count = bufinfo.len / 4; // PCC receives 4 bytes (2 pixels) at a time diff --git a/ports/atmel-samd/common-hal/microcontroller/Processor.c b/ports/atmel-samd/common-hal/microcontroller/Processor.c index 95ecde815e6..235229ab34c 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Processor.c +++ b/ports/atmel-samd/common-hal/microcontroller/Processor.c @@ -328,5 +328,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } diff --git a/ports/atmel-samd/common-hal/os/__init__.c b/ports/atmel-samd/common-hal/os/__init__.c index 2c1de431c66..89b5e85135d 100644 --- a/ports/atmel-samd/common-hal/os/__init__.c +++ b/ports/atmel-samd/common-hal/os/__init__.c @@ -16,38 +16,6 @@ #include "hal/include/hal_rand_sync.h" #endif -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -#ifdef SAMD21 -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "samd21"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "samd21"); -#endif -#ifdef SAM_D5X_E5X -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "samd51"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "samd51"); -#endif -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { #ifdef SAM_D5X_E5X hri_mclk_set_APBCMASK_TRNG_bit(MCLK); diff --git a/ports/atmel-samd/common-hal/pulseio/PulseIn.c b/ports/atmel-samd/common-hal/pulseio/PulseIn.c index 705f8ceeb8b..e8434717c42 100644 --- a/ports/atmel-samd/common-hal/pulseio/PulseIn.c +++ b/ports/atmel-samd/common-hal/pulseio/PulseIn.c @@ -130,7 +130,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use")); } - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); + self->buffer = (uint16_t *)m_malloc_without_collect(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } diff --git a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c index c6cd4605784..a8c87d82ed2 100644 --- a/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/atmel-samd/common-hal/rotaryio/IncrementalEncoder.c @@ -17,6 +17,10 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { + + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + if (!pin_a->has_extint) { raise_ValueError_invalid_pin_name(MP_QSTR_pin_a); } @@ -83,10 +87,13 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o turn_off_eic_channel(self->eic_channel_b); reset_pin_number(self->pin_a); - self->pin_a = NO_PIN; - reset_pin_number(self->pin_b); - self->pin_b = NO_PIN; + + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { + self->pin_a = NO_PIN; } void incrementalencoder_interrupt_handler(uint8_t channel) { diff --git a/ports/atmel-samd/common-hal/sdioio/SDCard.c b/ports/atmel-samd/common-hal/sdioio/SDCard.c index 8ff1a391bb2..e38a664ed48 100644 --- a/ports/atmel-samd/common-hal/sdioio/SDCard.c +++ b/ports/atmel-samd/common-hal/sdioio/SDCard.c @@ -9,6 +9,7 @@ #include "py/runtime.h" #include "common-hal/microcontroller/Pin.h" +#include "extmod/vfs.h" #include "shared-bindings/sdioio/SDCard.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" @@ -170,43 +171,85 @@ static void debug_print_state(sdioio_sdcard_obj_t *self, const char *what, sd_mm #endif } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { - check_for_deinit(self); - check_whole_block(bufinfo); +mp_negative_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); self->state_programming = true; - sd_mmc_err_t r = sd_mmc_init_write_blocks(0, start_block, bufinfo->len / 512); + sd_mmc_err_t r = sd_mmc_init_write_blocks(0, start_block, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_init_write_blocks", r); - return -EIO; + return -MP_EIO; } - r = sd_mmc_start_write_blocks(bufinfo->buf, bufinfo->len / 512); + r = sd_mmc_start_write_blocks(buf, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_start_write_blocks", r); - return -EIO; + return -MP_EIO; } - // debug_print_state(self, "after writeblocks OK"); return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_negative_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { check_for_deinit(self); check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +mp_negative_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); - sd_mmc_err_t r = sd_mmc_init_read_blocks(0, start_block, bufinfo->len / 512); + sd_mmc_err_t r = sd_mmc_init_read_blocks(0, start_block, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_init_read_blocks", r); - return -EIO; + return -MP_EIO; } - r = sd_mmc_start_read_blocks(bufinfo->buf, bufinfo->len / 512); + r = sd_mmc_start_read_blocks(buf, num_blocks); if (r != SD_MMC_OK) { debug_print_state(self, "sd_mmc_start_read_blocks", r); - return -EIO; + return -MP_EIO; } sd_mmc_wait_end_of_write_blocks(0); return 0; } +mp_negative_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + check_for_deinit(self); + check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { check_for_deinit(self); return true; diff --git a/ports/atmel-samd/common-hal/spitarget/SPITarget.c b/ports/atmel-samd/common-hal/spitarget/SPITarget.c new file mode 100644 index 00000000000..e5011b141fc --- /dev/null +++ b/ports/atmel-samd/common-hal/spitarget/SPITarget.c @@ -0,0 +1,245 @@ +#include "common-hal/spitarget/SPITarget.h" +#include "common-hal/busio/__init__.h" + +#include "shared-bindings/spitarget/SPITarget.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "hpl_sercom_config.h" +#include "peripheral_clk_config.h" + +#include "hal/include/hal_gpio.h" +#include "hal/include/hal_spi_m_sync.h" + +#include "hpl_sercom_config.h" +#include "samd/sercom.h" + +void common_hal_spitarget_spi_target_construct(spitarget_spi_target_obj_t *self, + const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss) { + Sercom *sercom = NULL; + uint8_t sercom_index; + uint32_t clock_pinmux = 0; + uint32_t mosi_pinmux = 0; + uint32_t miso_pinmux = 0; + uint32_t ss_pinmux = 0; + uint8_t clock_pad = 0; + uint8_t mosi_pad = 0; + uint8_t miso_pad = 0; + uint8_t dopo = 255; + + // Ensure the object starts in its deinit state. + self->clock_pin = NO_PIN; + + // Special case for SAMR21 boards. (feather_radiofruit_zigbee) + #if defined(PIN_PC19F_SERCOM4_PAD0) + if (miso == &pin_PC19) { + if (mosi == &pin_PB30 && sck == &pin_PC18) { + sercom = SERCOM4; + sercom_index = 4; + clock_pinmux = MUX_F; + mosi_pinmux = MUX_F; + miso_pinmux = MUX_F; + clock_pad = 3; + mosi_pad = 2; + miso_pad = 0; + dopo = samd_peripherals_get_spi_dopo(clock_pad, mosi_pad); + } + // Error, leave SERCOM unset to throw an exception later. + } else + #endif + { + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + sercom_index = sck->sercom[i].index; // 2 for SERCOM2, etc. + if (sercom_index >= SERCOM_INST_NUM) { + continue; + } + Sercom *potential_sercom = sercom_insts[sercom_index]; + if (potential_sercom->SPI.CTRLA.bit.ENABLE != 0) { + continue; + } + clock_pinmux = PINMUX(sck->number, (i == 0) ? MUX_C : MUX_D); + clock_pad = sck->sercom[i].pad; + if (!samd_peripherals_valid_spi_clock_pad(clock_pad)) { + continue; + } + // find miso_pad first, since it corresponds to dopo which takes limited values + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (sercom_index == miso->sercom[j].index) { + miso_pinmux = PINMUX(miso->number, (j == 0) ? MUX_C : MUX_D); + miso_pad = miso->sercom[j].pad; + dopo = samd_peripherals_get_spi_dopo(clock_pad, miso_pad); + if (dopo > 0x3) { + continue; // pad combination not possible + } + } else { + continue; + } + for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { + if (sercom_index == mosi->sercom[k].index) { + mosi_pinmux = PINMUX(mosi->number, (k == 0) ? MUX_C : MUX_D); + mosi_pad = mosi->sercom[k].pad; + for (int m = 0; m < NUM_SERCOMS_PER_PIN; m++) { + if (sercom_index == ss->sercom[m].index) { + ss_pinmux = PINMUX(ss->number, (m == 0) ? MUX_C : MUX_D); + sercom = potential_sercom; + break; + } + } + if (sercom != NULL) { + break; + } + } + } + if (sercom != NULL) { + break; + } + } + if (sercom != NULL) { + break; + } + } + } + if (sercom == NULL) { + raise_ValueError_invalid_pins(); + } + + // Set up SPI clocks on SERCOM. + samd_peripherals_sercom_clock_init(sercom, sercom_index); + + if (spi_m_sync_init(&self->spi_desc, sercom) != ERR_NONE) { + mp_raise_OSError(MP_EIO); + } + + // Pads must be set after spi_m_sync_init(), which uses default values from + // the prototypical SERCOM. + + hri_sercomspi_write_CTRLA_MODE_bf(sercom, 2); + hri_sercomspi_write_CTRLA_DOPO_bf(sercom, dopo); + hri_sercomspi_write_CTRLA_DIPO_bf(sercom, mosi_pad); + hri_sercomspi_write_CTRLB_PLOADEN_bit(sercom, 1); + + // Always start at 250khz which is what SD cards need. They are sensitive to + // SPI bus noise before they are put into SPI mode. + uint8_t baud_value = samd_peripherals_spi_baudrate_to_baud_reg_value(250000); + if (spi_m_sync_set_baudrate(&self->spi_desc, baud_value) != ERR_NONE) { + // spi_m_sync_set_baudrate does not check for validity, just whether the device is + // busy or not + mp_raise_OSError(MP_EIO); + } + + gpio_set_pin_direction(sck->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(sck->number, GPIO_PULL_OFF); + gpio_set_pin_function(sck->number, clock_pinmux); + claim_pin(sck); + self->clock_pin = sck->number; + + gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF); + gpio_set_pin_function(mosi->number, mosi_pinmux); + self->MOSI_pin = mosi->number; + claim_pin(mosi); + + gpio_set_pin_direction(miso->number, GPIO_DIRECTION_OUT); + gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF); + gpio_set_pin_function(miso->number, miso_pinmux); + self->MISO_pin = miso->number; + claim_pin(miso); + + gpio_set_pin_direction(ss->number, GPIO_DIRECTION_IN); + gpio_set_pin_pull_mode(ss->number, GPIO_PULL_OFF); + gpio_set_pin_function(ss->number, ss_pinmux); + self->SS_pin = ss->number; + claim_pin(ss); + + self->running_dma.failure = 1; // not started + self->mosi_packet = NULL; + self->miso_packet = NULL; + + spi_m_sync_enable(&self->spi_desc); +} + +bool common_hal_spitarget_spi_target_deinited(spitarget_spi_target_obj_t *self) { + return self->clock_pin == NO_PIN; +} + +void common_hal_spitarget_spi_target_deinit(spitarget_spi_target_obj_t *self) { + if (common_hal_spitarget_spi_target_deinited(self)) { + return; + } + allow_reset_sercom(self->spi_desc.dev.prvt); + + spi_m_sync_disable(&self->spi_desc); + spi_m_sync_deinit(&self->spi_desc); + reset_pin_number(self->clock_pin); + reset_pin_number(self->MOSI_pin); + reset_pin_number(self->MISO_pin); + reset_pin_number(self->SS_pin); + self->clock_pin = NO_PIN; +} + +void common_hal_spitarget_spi_target_transfer_start(spitarget_spi_target_obj_t *self, + uint8_t *mosi_packet, const uint8_t *miso_packet, size_t len) { + if (len == 0) { + return; + } + if (self->running_dma.failure != 1) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Async SPI transfer in progress on this bus, keep awaiting.")); + } + + self->mosi_packet = mosi_packet; + self->miso_packet = miso_packet; + + Sercom *sercom = self->spi_desc.dev.prvt; + shared_dma_transfer_start(&self->running_dma, sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); + + // There is an issue where if an unexpected SPI transfer is received before the user calls "end" for the in-progress, expected + // transfer, the SERCOM has an error and gets confused. This can be detected from INTFLAG.ERROR. I think the code in + // ports/atmel-samd/peripherals/samd/dma.c at line 277 (as of this commit; it's the part that reads s->SPI.INTFLAG.bit.RXC and + // s->SPI.DATA.reg) is supposed to fix this, but experimentation seems to show that it does not in fact fix anything. Anyways, if + // the ERROR bit is set, let's just reset the peripheral and then setup the transfer again -- that seems to work. + if (hri_sercomspi_get_INTFLAG_ERROR_bit(sercom)) { + shared_dma_transfer_close(&self->running_dma); + + // disable the sercom + spi_m_sync_disable(&self->spi_desc); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + + // save configurations + hri_sercomspi_ctrla_reg_t ctrla_saved_val = hri_sercomspi_get_CTRLA_reg(sercom, -1); // -1 mask is all ones: save all bits + hri_sercomspi_ctrlb_reg_t ctrlb_saved_val = hri_sercomspi_get_CTRLB_reg(sercom, -1); // -1 mask is all ones: save all bits + hri_sercomspi_baud_reg_t baud_saved_val = hri_sercomspi_get_BAUD_reg(sercom, -1); // -1 mask is all ones: save all bits + // reset + hri_sercomspi_set_CTRLA_SWRST_bit(sercom); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + // re-write configurations + hri_sercomspi_write_CTRLA_reg(sercom, ctrla_saved_val); + hri_sercomspi_write_CTRLB_reg(sercom, ctrlb_saved_val); + hri_sercomspi_write_BAUD_reg(sercom, baud_saved_val); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + + // re-enable the sercom + spi_m_sync_enable(&self->spi_desc); + hri_sercomspi_wait_for_sync(sercom, SERCOM_SPI_SYNCBUSY_MASK); + + shared_dma_transfer_start(&self->running_dma, sercom, miso_packet, &sercom->SPI.DATA.reg, &sercom->SPI.DATA.reg, mosi_packet, len, 0); + } +} + +bool common_hal_spitarget_spi_target_transfer_is_finished(spitarget_spi_target_obj_t *self) { + return self->running_dma.failure == 1 || shared_dma_transfer_finished(&self->running_dma); +} + +int common_hal_spitarget_spi_target_transfer_close(spitarget_spi_target_obj_t *self) { + if (self->running_dma.failure == 1) { + return 0; + } + int res = shared_dma_transfer_close(&self->running_dma); + self->running_dma.failure = 1; + + self->mosi_packet = NULL; + self->miso_packet = NULL; + + return res; +} diff --git a/ports/atmel-samd/common-hal/spitarget/SPITarget.h b/ports/atmel-samd/common-hal/spitarget/SPITarget.h new file mode 100644 index 00000000000..9fff23c1743 --- /dev/null +++ b/ports/atmel-samd/common-hal/spitarget/SPITarget.h @@ -0,0 +1,24 @@ +#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_TARGET_H +#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_TARGET_H + +#include "common-hal/microcontroller/Pin.h" +#include "hal/include/hal_spi_m_sync.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + + struct spi_m_sync_descriptor spi_desc; + + uint8_t clock_pin; + uint8_t MOSI_pin; + uint8_t MISO_pin; + uint8_t SS_pin; + + uint8_t *mosi_packet; + const uint8_t *miso_packet; + + dma_transfer_t running_dma; +} spitarget_spi_target_obj_t; + +#endif // MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_TARGET_H diff --git a/ports/atmel-samd/common-hal/spitarget/__init__.c b/ports/atmel-samd/common-hal/spitarget/__init__.c new file mode 100644 index 00000000000..c0ce8cef9a1 --- /dev/null +++ b/ports/atmel-samd/common-hal/spitarget/__init__.c @@ -0,0 +1 @@ +// No spitarget module functions. diff --git a/ports/atmel-samd/common-hal/touchio/TouchIn.c b/ports/atmel-samd/common-hal/touchio/TouchIn.c index 05c3f3ee923..822d614a602 100644 --- a/ports/atmel-samd/common-hal/touchio/TouchIn.c +++ b/ports/atmel-samd/common-hal/touchio/TouchIn.c @@ -12,6 +12,7 @@ #include "py/binary.h" #include "py/mphal.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/Pull.h" #include "shared-bindings/touchio/TouchIn.h" // Native touchio only exists for SAMD21 @@ -38,7 +39,7 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { } void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, - const mcu_pin_obj_t *pin) { + const mcu_pin_obj_t *pin, const digitalio_pull_t pull) { if (!pin->has_touch) { raise_ValueError_invalid_pin(); } @@ -90,7 +91,7 @@ void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t *self) { self->config.pin = NO_PIN; } -void touchin_reset() { +void touchin_reset(void) { Ptc *ptc = ((Ptc *)PTC); if (ptc->CTRLA.bit.ENABLE == 1) { ptc->CTRLA.bit.ENABLE = 0; diff --git a/ports/atmel-samd/libs/libgcc-12.1.0-Os-v6-m-nofp.a b/ports/atmel-samd/libs/libgcc-12.1.0-Os-v6-m-nofp.a deleted file mode 100644 index 56692d5d056..00000000000 Binary files a/ports/atmel-samd/libs/libgcc-12.1.0-Os-v6-m-nofp.a and /dev/null differ diff --git a/ports/atmel-samd/libs/libgcc-14.2.0-Os-v6-m-nofp.a b/ports/atmel-samd/libs/libgcc-14.2.0-Os-v6-m-nofp.a new file mode 100644 index 00000000000..6a708c1ffaa Binary files /dev/null and b/ports/atmel-samd/libs/libgcc-14.2.0-Os-v6-m-nofp.a differ diff --git a/ports/atmel-samd/mpconfigport.h b/ports/atmel-samd/mpconfigport.h index f02f3d595d9..d6d21c35817 100644 --- a/ports/atmel-samd/mpconfigport.h +++ b/ports/atmel-samd/mpconfigport.h @@ -51,6 +51,8 @@ // See https://github.com/micropython/micropython/pull/11353 #define MICROPY_NLR_THUMB_USE_LONG_JUMP (1) +// Don't store qstr hashes and do string compares instead. +#define MICROPY_QSTR_BYTES_IN_HASH (0) #endif // SAMD21 @@ -64,12 +66,13 @@ #define CIRCUITPY_MCU_FAMILY samd51 #ifdef SAMD51 #define MICROPY_PY_SYS_PLATFORM "MicroChip SAMD51" +#elif defined(SAME51) +#define MICROPY_PY_SYS_PLATFORM "MicroChip SAME51" #elif defined(SAME54) #define MICROPY_PY_SYS_PLATFORM "MicroChip SAME54" #endif #define SPI_FLASH_MAX_BAUDRATE 24000000 -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) -#define MICROPY_PY_FUNCTION_ATTRS (1) + // MICROPY_PY_ERRNO_LIST - Use the default #endif // SAM_D5X_E5X @@ -101,6 +104,11 @@ #define CIRCUITPY_DEFAULT_STACK_SIZE 3584 #endif +#ifndef CIRCUITPY_PYSTACK_SIZE +// Default for most boards is 2048 starting with CircuitPython 10, but on SAMD21, keep it at previous lower value. +#define CIRCUITPY_PYSTACK_SIZE 1536 +#endif + #ifndef SAMD21_BOD33_LEVEL // Set brownout detection to ~2.7V. Default from factory is 1.7V, // which is too low for proper operation of external SPI flash chips diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index c3449485cf4..f846f490aa4 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -12,6 +12,9 @@ CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 1 CIRCUITPY_LTO = 1 CIRCUITPY_KEYPAD_DEMUX ?= 0 +CIRCUITPY_LVFONTIO ?= 0 + +CIRCUITPY_DIGITALINOUT_PROTOCOL = 0 ###################################################################### # Put samd21-only choices here. @@ -45,10 +48,11 @@ CIRCUITPY_I2CTARGET ?= 0 CIRCUITPY_JSON ?= 0 CIRCUITPY_KEYPAD ?= 0 CIRCUITPY_MSGPACK ?= 0 -CIRCUITPY_OS_GETENV ?= 0 CIRCUITPY_PIXELMAP ?= 0 CIRCUITPY_RE ?= 0 CIRCUITPY_SDCARDIO ?= 0 +CIRCUITPY_SETTINGS_TOML ?= 0 +CIRCUITPY_SPITARGET ?= 0 CIRCUITPY_SYNTHIO ?= 0 CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 CIRCUITPY_TRACEBACK ?= 0 @@ -58,6 +62,9 @@ CIRCUITPY_ZLIB = 0 # Turn off a few more things that don't fit in 192kB +CIRCUITPY_TERMINALIO_VT100 = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 + ifeq ($(INTERNAL_FLASH_FILESYSTEM),1) CIRCUITPY_ONEWIREIO ?= 0 CIRCUITPY_SAFEMODE_PY ?= 0 @@ -88,11 +95,11 @@ endif # samd21 ###################################################################### ###################################################################### -# Put samd51-only choices here. +# Put samx5x-only choices here. -ifeq ($(CHIP_FAMILY),samd51) +ifneq ($(filter $(CHIP_FAMILY),samd51 same51 same54),) -# No native touchio on SAMD51. +# No native touchio on SAMx5x. CIRCUITPY_TOUCHIO_USE_NATIVE = 0 ifeq ($(CIRCUITPY_FULL_BUILD),0) @@ -118,6 +125,7 @@ CIRCUITPY_MAX3421E ?= $(HAS_1MB_FLASH) CIRCUITPY_PS2IO ?= 1 CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FRAMEBUFFERIO) CIRCUITPY_SAMD ?= 1 +CIRCUITPY_SPITARGET ?= 1 CIRCUITPY_SYNTHIO_MAX_CHANNELS = 12 CIRCUITPY_ULAB_OPTIMIZE_SIZE ?= 1 CIRCUITPY_WATCHDOG ?= 1 @@ -127,32 +135,7 @@ ifeq ($(CHIP_VARIANT),SAMD51G19A) CIRCUITPY_AUDIOBUSIO = 0 endif -endif # samd51 -###################################################################### - -###################################################################### -# Put same51-only choices here. - -ifeq ($(CHIP_FAMILY),same51) - -# No native touchio on SAME51. -CIRCUITPY_TOUCHIO_USE_NATIVE = 0 - -ifeq ($(CIRCUITPY_FULL_BUILD),0) -CIRCUITPY_LTO_PARTITION ?= one -endif - -# The ?='s allow overriding in mpconfigboard.mk. - -CIRCUITPY_ALARM ?= 1 -CIRCUITPY_PS2IO ?= 1 -CIRCUITPY_SAMD ?= 1 -CIRCUITPY_FLOPPYIO ?= $(CIRCUITPY_FULL_BUILD) -CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_FULL_BUILD) -CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_FRAMEBUFFERIO) -CIRCUITPY_ULAB_OPTIMIZE_SIZE ?= 1 - -endif # same51 +endif # samx5x ###################################################################### CIRCUITPY_BUILD_EXTENSIONS ?= uf2 diff --git a/ports/atmel-samd/peripherals b/ports/atmel-samd/peripherals index 82e514b6e0d..e98b6b79976 160000 --- a/ports/atmel-samd/peripherals +++ b/ports/atmel-samd/peripherals @@ -1 +1 @@ -Subproject commit 82e514b6e0d1a2b09dc73be9973663b6b837a817 +Subproject commit e98b6b799768d21d8f8e2d0a071f19cf7d80467d diff --git a/ports/atmel-samd/reset.c b/ports/atmel-samd/reset.c index 9cacd4ab951..816e23e3251 100644 --- a/ports/atmel-samd/reset.c +++ b/ports/atmel-samd/reset.c @@ -9,7 +9,7 @@ #include "reset.h" #include "supervisor/filesystem.h" -void NVIC_SystemReset(void) NORETURN; +void NVIC_SystemReset(void) MP_NORETURN; void reset(void) { filesystem_flush(); diff --git a/ports/atmel-samd/reset.h b/ports/atmel-samd/reset.h index c74d25fa01e..248d43779fd 100644 --- a/ports/atmel-samd/reset.h +++ b/ports/atmel-samd/reset.h @@ -16,6 +16,6 @@ extern uint32_t _bootloader_dbl_tap; -void reset_to_bootloader(void) NORETURN; -void reset(void) NORETURN; +void reset_to_bootloader(void) MP_NORETURN; +void reset(void) MP_NORETURN; bool bootloader_available(void); diff --git a/ports/atmel-samd/sd_mmc/sd_mmc.c b/ports/atmel-samd/sd_mmc/sd_mmc.c index 60b4d9f8985..6724e88f42a 100644 --- a/ports/atmel-samd/sd_mmc/sd_mmc.c +++ b/ports/atmel-samd/sd_mmc/sd_mmc.c @@ -160,9 +160,9 @@ static struct sd_mmc_card sd_mmc_cards[CONF_SD_MMC_MEM_CNT]; /** HAL driver instance */ static void *sd_mmc_hal; -/** Index of current slot configurated */ +/** Index of current slot configured */ static uint8_t sd_mmc_slot_sel; -/** Pointer on current slot configurated */ +/** Pointer on current slot configured */ static struct sd_mmc_card *sd_mmc_card; /** Number of block to read or write on the current transfer */ static uint16_t sd_mmc_nb_block_to_tranfer = 0; @@ -238,7 +238,7 @@ static bool mmc_mci_op_cond(void) { uint32_t retry, resp; /* - * Timeout 1s = 400KHz / ((6+6)*8) cylces = 4200 retry + * Timeout 1s = 400KHz / ((6+6)*8) cycles = 4200 retry * 6 = cmd byte size * 6 = response byte size */ @@ -277,7 +277,7 @@ static bool sd_mci_op_cond(uint8_t v2) { uint32_t arg, retry, resp; /* - * Timeout 1s = 400KHz / ((6+6+6+6)*8) cylces = 2100 retry + * Timeout 1s = 400KHz / ((6+6+6+6)*8) cycles = 2100 retry * 6 = cmd byte size * 6 = response byte size * 6 = cmd byte size @@ -339,7 +339,7 @@ static bool sdio_op_cond(void) { /* * Wait card ready - * Timeout 1s = 400KHz / ((6+4)*8) cylces = 5000 retry + * Timeout 1s = 400KHz / ((6+4)*8) cycles = 5000 retry * 6 = cmd byte size * 4(SPI) 6(MCI) = response byte size */ @@ -1292,13 +1292,13 @@ static bool sd_mmc_mci_install_mmc(void) { void sd_mmc_init(void *hal, sd_mmc_detect_t *card_detects, sd_mmc_detect_t *wp_detects) { /* GPIO will be used to detect card and write protect. - * The related clocks and pinmux must be configurated in good + * The related clocks and pinmux must be configured in good * condition. */ for (uint8_t slot = 0; slot < CONF_SD_MMC_MEM_CNT; slot++) { sd_mmc_cards[slot].state = SD_MMC_CARD_STATE_NO_CARD; } - sd_mmc_slot_sel = 0xFF; /* No slot configurated */ + sd_mmc_slot_sel = 0xFF; /* No slot configured */ sd_mmc_hal = hal; _cd = card_detects; _wp = wp_detects; diff --git a/ports/atmel-samd/sd_mmc/sd_mmc.h b/ports/atmel-samd/sd_mmc/sd_mmc.h index cdc98e7108e..7b70a631164 100644 --- a/ports/atmel-samd/sd_mmc/sd_mmc.h +++ b/ports/atmel-samd/sd_mmc/sd_mmc.h @@ -113,7 +113,7 @@ typedef struct sd_mmc_detect { uint16_t val; /**< Detection value */ } sd_mmc_detect_t; -/** This SD MMC stack uses the maximum block size autorized (512 bytes) */ +/** This SD MMC stack uses the maximum block size authorized (512 bytes) */ #define SD_MMC_BLOCK_SIZE 512 /** diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 8f5115789da..288446cf62e 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -339,6 +339,7 @@ safe_mode_t port_init(void) { init_shared_dma(); // Reset everything into a known state before board_init. + // Pins are reset in main() after this routine returns. reset_port(); #ifdef SAMD21 @@ -411,8 +412,6 @@ void reset_port(void) { reset_ticks(); } - reset_all_pins(); - // Output clocks for debugging. // not supported by SAMD51G; uncomment for SAMD51J or update for 51G // #ifdef SAM_D5X_E5X @@ -686,7 +685,7 @@ void port_idle_until_interrupt(void) { /** * \brief Default interrupt handler for unused IRQs. */ -__attribute__((used)) void HardFault_Handler(void) { +__attribute__((used)) MP_NORETURN void HardFault_Handler(void) { #ifdef ENABLE_MICRO_TRACE_BUFFER // Turn off the micro trace buffer so we don't fill it up in the infinite // loop below. diff --git a/ports/atmel-samd/supervisor/samd21_cpu.s b/ports/atmel-samd/supervisor/samd21_cpu.s deleted file mode 100755 index 741bb21358a..00000000000 --- a/ports/atmel-samd/supervisor/samd21_cpu.s +++ /dev/null @@ -1,35 +0,0 @@ -.syntax unified -.cpu cortex-m0 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0, #0] -str r5, [r0, #4] -str r6, [r0, #8] -str r7, [r0, #12] -push {r1} -mov r1, r8 -str r1, [r0, #16] -mov r1, r9 -str r1, [r0, #20] -mov r1, r10 -str r1, [r0, #24] -mov r1, r11 -str r1, [r0, #28] -mov r1, r12 -str r1, [r0, #32] -mov r1, r13 -str r1, [r0, #36] -pop {r1} - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/atmel-samd/supervisor/samd51_cpu.s b/ports/atmel-samd/supervisor/samd51_cpu.s deleted file mode 100755 index 9e6807a5e2e..00000000000 --- a/ports/atmel-samd/supervisor/samd51_cpu.s +++ /dev/null @@ -1,27 +0,0 @@ -.syntax unified -.cpu cortex-m4 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0], #4 -str r5, [r0], #4 -str r6, [r0], #4 -str r7, [r0], #4 -str r8, [r0], #4 -str r9, [r0], #4 -str r10, [r0], #4 -str r11, [r0], #4 -str r12, [r0], #4 -str r13, [r0], #4 - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/atmel-samd/supervisor/same51_cpu.s b/ports/atmel-samd/supervisor/same51_cpu.s deleted file mode 100755 index 9e6807a5e2e..00000000000 --- a/ports/atmel-samd/supervisor/same51_cpu.s +++ /dev/null @@ -1,27 +0,0 @@ -.syntax unified -.cpu cortex-m4 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0], #4 -str r5, [r0], #4 -str r6, [r0], #4 -str r7, [r0], #4 -str r8, [r0], #4 -str r9, [r0], #4 -str r10, [r0], #4 -str r11, [r0], #4 -str r12, [r0], #4 -str r13, [r0], #4 - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/atmel-samd/supervisor/same54_cpu.s b/ports/atmel-samd/supervisor/same54_cpu.s deleted file mode 100755 index 9e6807a5e2e..00000000000 --- a/ports/atmel-samd/supervisor/same54_cpu.s +++ /dev/null @@ -1,27 +0,0 @@ -.syntax unified -.cpu cortex-m4 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0], #4 -str r5, [r0], #4 -str r6, [r0], #4 -str r7, [r0], #4 -str r8, [r0], #4 -str r9, [r0], #4 -str r10, [r0], #4 -str r11, [r0], #4 -str r12, [r0], #4 -str r13, [r0], #4 - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/atmel-samd/tools/gen_pin_name_table.py b/ports/atmel-samd/tools/gen_pin_name_table.py deleted file mode 100644 index 16af2540bdd..00000000000 --- a/ports/atmel-samd/tools/gen_pin_name_table.py +++ /dev/null @@ -1,380 +0,0 @@ -# This file is part of the CircuitPython project: https://circuitpython.org -# -# SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -# This helper generates the pinout tables in ../README.rst. - -import os -import os.path - -pins = [ - "PA00", - "PA01", - "PA02", - "PA03", - "PB08", - "PB09", - "PA04", - "PA05", - "PA06", - "PA07", - "PA08", - "PA09", - "PA10", - "PA11", - "PB10", - "PB11", - "PA12", - "PA13", - "PA14", - "PA15", - "PA16", - "PA17", - "PA18", - "PA19", - "PA20", - "PA21", - "PA22", - "PA23", - "PA24", - "PA25", - "PB22", - "PB23", - "PA27", - "PA28", - "PA29", - "PA30", - "PA31", - "PB02", - "PB03", -] - -# Dictionary keys: [board][pin] = list of pin names -mapping = {} - -QSTR = " { MP_OBJ_NEW_QSTR(MP_QSTR_" - -for board in os.listdir("boards"): - if not os.path.isdir("boards/" + board): - continue - mapping[board] = {} - with open("boards/" + board + "/pins.c", "r") as f: - for line in f: - if line.startswith(QSTR): - board_name, _, pin = line.split(")") - board_name = board_name[len(QSTR) :] - pin = pin[-8:-4] - if pin not in mapping[board]: - mapping[board][pin] = [] - mapping[board][pin].append(board_name) - -column_width = {} -for board in mapping: - column_width[board] = len(board) - for pin in mapping[board]: - l = len(" / ".join("``" + x + "``" for x in mapping[board][pin])) - column_width[board] = max(l, column_width[board]) - -first_column_width = len("`microcontroller.pin`") -print("=" * first_column_width, end="") -total_board_width = -2 -for board in column_width: - column = " " + "=" * column_width[board] - total_board_width += len(column) - print(column, end="") - -print() -print("`microcontroller.pin` `board`") -print("-" * first_column_width + " " + "-" * total_board_width) - -print("Datasheet".ljust(first_column_width), end="") -for board in column_width: - print(" " + board.ljust(column_width[board]), end="") -print() - -print("=" * first_column_width, end="") -for board in column_width: - column = " " + "=" * column_width[board] - print(column, end="") -print() - -for pin in pins: - print(pin.ljust(first_column_width), end="") - for board in column_width: - if pin in mapping[board]: - names = " / ".join("``" + x + "``" for x in mapping[board][pin]) - print(" " + names.ljust(column_width[board]), end="") - else: - print(" " * (column_width[board] + 2), end="") - print() - -print("=" * first_column_width, end="") -for board in column_width: - column = " " + "=" * column_width[board] - print(column, end="") -print() - -print() -print() -# Generate pin capabilities too. - -ALL_BUT_USB = list(pins) -ALL_BUT_USB.remove("PA24") -ALL_BUT_USB.remove("PA25") - -# dictionary is [module][class] = [pins] -capabilities = { - "analogio": { - "AnalogIn": [ - "PA02", - "PA03", - "PB08", - "PB09", - "PA04", - "PA05", - "PA06", - "PA07", - "PA08", - "PA09", - "PA10", - "PA11", - "PB02", - "PB03", - ], - "AnalogOut": ["PA02"], - }, - "audioio": {"AudioOut": ["PA02"]}, - "bitbangio": {"I2C": ALL_BUT_USB, "SPI": ALL_BUT_USB}, - "busio": { - "I2C - SDA": ["PA00", "PB08", "PA08", "PA12", "PA16", "PA22", "PB02"], # SERCOM pad 0 - "I2C - SCL": ["PA01", "PB09", "PA09", "PA13", "PA17", "PA23", "PB03"], # SERCOM pad 1 - "SPI - MISO": [ - "PA00", - "PA01", - "PB08", - "PB09", - "PA04", - "PA05", - "PA06", - "PA07", - "PA08", - "PA09", - "PA10", - "PA11", - "PB10", - "PB11", - "PA12", - "PA13", - "PA14", - "PA15", - "PA16", - "PA17", - "PA18", - "PA19", - "PA20", - "PA21", - "PA22", - "PA23", - "PB22", - "PB23", - "PA30", - "PA31", - "PB02", - "PB03", - ], # any SERCOM pad - "SPI - MOSI": [ - "PA00", - "PB08", - "PA04", - "PA06", - "PA08", - "PA10", - "PA11", - "PB10", - "PB11", - "PA14", - "PA15", - "PA16", - "PA18", - "PA19", - "PA20", - "PA21", - "PA22", - "PB22", - "PB23", - "PA30", - "PA31", - "PB02", - ], # any pad but 1 - "SPI - SCK": [ - "PA01", - "PB09", - "PA05", - "PA07", - "PA09", - "PA11", - "PB11", - "PA13", - "PA15", - "PA17", - "PA19", - "PA21", - "PA23", - "PB23", - "PA31", - "PB03", - ], # 1 or 3 - "UART - RX": [ - "PA00", - "PA01", - "PB08", - "PB09", - "PA04", - "PA05", - "PA06", - "PA07", - "PA08", - "PA09", - "PA10", - "PA11", - "PB10", - "PB11", - "PA12", - "PA13", - "PA14", - "PA15", - "PA16", - "PA17", - "PA18", - "PA19", - "PA20", - "PA21", - "PA22", - "PA23", - "PB22", - "PB23", - "PA30", - "PA31", - "PB02", - "PB03", - ], # any pad - "UART - TX": [ - "PA00", - "PB08", - "PA04", - "PA06", - "PA08", - "PA10", - "PB10", - "PA12", - "PA14", - "PA16", - "PA18", - "PA20", - "PA22", - "PB22", - "PA30", - "PB02", - ], # pad 0 or 2 - }, - "digitalio": {"DigitalInOut": ALL_BUT_USB}, - "onewireio": {"OneWire": ALL_BUT_USB}, - "pulseio": { - "PulseIn": ALL_BUT_USB, - "PWMOut": [ - "PA01", - "PB09", - "PA04", - "PA05", - "PA06", - "PA07", - "PA08", - "PA09", - "PA10", - "PA11", - "PB10", - "PB11", - "PA12", - "PA13", - "PA14", - "PA15", - "PA16", - "PA17", - "PA18", - "PA19", - "PA20", - "PA21", - "PA22", - "PA23", - "PA30", - "PA31", - ], - }, - "ps2io": {"Ps2": ALL_BUT_USB}, - "touchio": { - "TouchIn": ["PA02", "PA03", "PB08", "PB09", "PA04", "PA05", "PA06", "PA07", "PB02", "PB03"] - }, -} - -column_width = {} -for module in capabilities: - for c in capabilities[module]: - column_width[module + c] = max(len("**Yes**"), len(c)) - -module_width = {} -for module in capabilities: - module_width[module] = 0 - for c in capabilities[module]: - module_width[module] += column_width[module + c] + 2 - module_width[module] -= 2 - - if module_width[module] < (len(module) + 2): - column_width[module + c] += len(module) + 2 - module_width[module] - module_width[module] = len(module) + 2 - -first_column_width = len("`microcontroller.pin`") -print("=" * first_column_width, end="") -for module in capabilities: - for c in capabilities[module]: - print(" " + "=" * column_width[module + c], end="") -print() - -print("`microcontroller.pin`", end="") -for module in capabilities: - print(" " + ("`" + module + "`").ljust(module_width[module]), end="") -print() - -print("-" * first_column_width, end="") -for module in capabilities: - print(" " + "-" * module_width[module], end="") -print() - -print("Datasheet".ljust(first_column_width), end="") -for module in capabilities: - for c in capabilities[module]: - print(" " + c.ljust(column_width[module + c]), end="") -print() - -print("=" * first_column_width, end="") -for module in capabilities: - for c in capabilities[module]: - print(" " + "=" * column_width[module + c], end="") -print() - -for pin in pins: - print(pin.ljust(first_column_width), end="") - for module in capabilities: - for c in capabilities[module]: - if pin in capabilities[module][c]: - print(" " + "**Yes**".ljust(column_width[module + c]), end="") - else: - print(" " * (column_width[module + c] + 2), end="") - print() - -print("=" * first_column_width, end="") -for module in capabilities: - for c in capabilities[module]: - print(" " + "=" * column_width[module + c], end="") -print() diff --git a/ports/atmel-samd/tools/mkcandata.py b/ports/atmel-samd/tools/mkcandata.py index d505c81bdc4..06731a91547 100755 --- a/ports/atmel-samd/tools/mkcandata.py +++ b/ports/atmel-samd/tools/mkcandata.py @@ -15,8 +15,8 @@ def defines(name, suffix): {{&pin_{pin}, {instance}, PIN_{pin}, {pinmux} & 0xffff}}, #endif""" ) - print(f"{{NULL, 0, 0}}") - print(f"}};") + print("{NULL, 0, 0}") + print("};") print() diff --git a/ports/atmel-samd/tools/mksdiodata.py b/ports/atmel-samd/tools/mksdiodata.py index bfdcd696c26..5e59c6249b1 100755 --- a/ports/atmel-samd/tools/mksdiodata.py +++ b/ports/atmel-samd/tools/mksdiodata.py @@ -14,8 +14,8 @@ def defines(name, function): {{&pin_{pin}, {instance}, PIN_{pin}, {pinmux} & 0xffff}}, #endif""" ) - print(f"{{NULL, 0, 0}}") - print(f"}};") + print("{NULL, 0, 0}") + print("};") print() diff --git a/ports/broadcom/Makefile b/ports/broadcom/Makefile index 56c8c323744..dda93c6fd7c 100644 --- a/ports/broadcom/Makefile +++ b/ports/broadcom/Makefile @@ -48,6 +48,7 @@ SRC_C += bindings/videocore/__init__.c \ lib/sdmmc/sdmmc_mmc.c \ lib/sdmmc/sdmmc_sd.c \ lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c \ + lib/tinyusb/src/portable/synopsys/dwc2/dwc2_common.c \ peripherals/broadcom/caches.c \ peripherals/broadcom/gen/interrupt_handlers.c \ peripherals/broadcom/gen/pins.c \ @@ -58,18 +59,7 @@ SRC_C += bindings/videocore/__init__.c \ SRC_S = peripherals/broadcom/boot$(SUFFIX).s -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - -# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, -# because a few modules have files both in common-hal/ and shared-modules/. -# Doing a $(sort ...) removes duplicates as part of sorting. -SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) +SRC_C += shared/runtime/gchelper_generic.c OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) @@ -107,11 +97,11 @@ else endif -CFLAGS += $(INC) -Wall -Werror -std=gnu11 $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) +CFLAGS += $(INC) -Wall -Werror -std=gnu11 $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=old-style-definition $(BUILD)/lib/tlsf/tlsf.o: CFLAGS += -Wno-cast-align -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) LDFLAGS += $(CFLAGS) -T peripherals/broadcom/link$(SUFFIX).ld -Wl,--gc-sections -Wl,-Map=$@.map # -Wl,--cref diff --git a/ports/broadcom/bindings/videocore/Framebuffer.c b/ports/broadcom/bindings/videocore/Framebuffer.c index f5d8ab8d34b..66135baa7fe 100644 --- a/ports/broadcom/bindings/videocore/Framebuffer.c +++ b/ports/broadcom/bindings/videocore/Framebuffer.c @@ -26,6 +26,7 @@ //| //| A Framebuffer is often used in conjunction with a //| `framebufferio.FramebufferDisplay`.""" +//| static mp_obj_t videocore_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_width, ARG_height, }; @@ -51,6 +52,7 @@ static mp_obj_t videocore_framebuffer_make_new(const mp_obj_type_t *type, size_t //| rgbmatrix instance. After deinitialization, no further operations //| may be performed.""" //| ... +//| static mp_obj_t videocore_framebuffer_deinit(mp_obj_t self_in) { videocore_framebuffer_obj_t *self = (videocore_framebuffer_obj_t *)self_in; common_hal_videocore_framebuffer_deinit(self); @@ -79,6 +81,7 @@ MP_PROPERTY_GETTER(videocore_framebuffer_width_obj, //| height: int //| """The height of the display, in pixels""" //| +//| static mp_obj_t videocore_framebuffer_get_height(mp_obj_t self_in) { videocore_framebuffer_obj_t *self = (videocore_framebuffer_obj_t *)self_in; check_for_deinit(self); diff --git a/ports/broadcom/common-hal/busio/I2C.c b/ports/broadcom/common-hal/busio/I2C.c index 29e7aa6713f..7c1eafe281d 100644 --- a/ports/broadcom/common-hal/busio/I2C.c +++ b/ports/broadcom/common-hal/busio/I2C.c @@ -47,9 +47,14 @@ void reset_i2c(void) { void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + size_t instance_index = NUM_I2C; uint8_t scl_alt = 0; uint8_t sda_alt = 0; + for (scl_alt = 0; scl_alt < 6; scl_alt++) { if (scl->functions[scl_alt].type != PIN_FUNCTION_I2C || i2c_in_use[scl->functions[scl_alt].index] || @@ -90,17 +95,19 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { return self->sda_pin == NULL; } +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + self->sda_pin = NULL; +} + void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { if (common_hal_busio_i2c_deinited(self)) { return; } - never_reset_i2c[self->index] = false; i2c_in_use[self->index] = false; common_hal_reset_pin(self->sda_pin); common_hal_reset_pin(self->scl_pin); - self->sda_pin = NULL; - self->scl_pin = NULL; + common_hal_busio_i2c_mark_deinit(self); } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { @@ -130,7 +137,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { // Discussion of I2C implementation is here: https://github.com/raspberrypi/linux/issues/254 -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_negative_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { COMPLETE_MEMORY_READS; self->peripheral->S_b.DONE = true; @@ -175,7 +182,7 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, while (self->peripheral->S_b.ERR == 1) { RUN_BACKGROUND_TASKS; } - return MP_ENODEV; + return -MP_ENODEV; } if (loop_len < len) { @@ -185,19 +192,19 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return 0; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { COMPLETE_MEMORY_READS; self->peripheral->A_b.ADDR = addr; if (self->finish_write) { self->finish_write = false; if (self->peripheral->S_b.ERR == 1) { - return MP_ENODEV; + return -MP_ENODEV; } self->peripheral->FIFO_b.DATA = self->last_write_data; } else { @@ -229,15 +236,15 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, while (self->peripheral->S_b.ERR == 1) { RUN_BACKGROUND_TASKS; } - return MP_ENODEV; + return -MP_ENODEV; } return 0; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_negative_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/broadcom/common-hal/busio/SPI.c b/ports/broadcom/common-hal/busio/SPI.c index 2396a9b921e..9e4834e86f3 100644 --- a/ports/broadcom/common-hal/busio/SPI.c +++ b/ports/broadcom/common-hal/busio/SPI.c @@ -30,31 +30,8 @@ static SPI0_Type *spi[NUM_SPI] = {SPI0, NULL, NULL}; static SPI1_Type *aux_spi[NUM_SPI] = {NULL, SPI1, SPI2}; #endif -static bool never_reset_spi[NUM_SPI]; static bool spi_in_use[NUM_SPI]; -void reset_spi(void) { - for (size_t i = 0; i < NUM_SPI; i++) { - if (never_reset_spi[i]) { - continue; - } - - if (i == 1 || i == 2) { - if (i == 1) { - AUX->ENABLES_b.SPI_1 = false; - } else { - AUX->ENABLES_b.SPI_2 = false; - } - aux_spi[i]->CNTL0 = 0; - } else { - // Set CS back to default. All 0 except read enable. - spi[i]->CS = SPI0_CS_REN_Msk; - } - - spi_in_use[i] = false; - } -} - void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { @@ -67,6 +44,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_NotImplementedError(MP_ERROR_TEXT("Half duplex SPI is not implemented")); } + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + // BCM_VERSION != 2711 have 3 SPI but as listed in peripherals/gen/pins.c two are on // index 0, once one index 0 SPI is found the other will throw an invalid_pins error. for (size_t i = 0; i < NUM_SPI; i++) { @@ -118,8 +98,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[self->index] = true; - common_hal_never_reset_pin(self->clock); common_hal_never_reset_pin(self->MOSI); common_hal_never_reset_pin(self->MISO); @@ -129,16 +107,19 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } - never_reset_spi[self->index] = false; common_hal_reset_pin(self->clock); common_hal_reset_pin(self->MOSI); common_hal_reset_pin(self->MISO); - self->clock = NULL; + spi_in_use[self->index] = false; if (self->index == 1 || @@ -149,7 +130,12 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { } else if (self->index == 2) { AUX->ENABLES_b.SPI_2 = false; } + } else { + // Set CS back to default. All 0 except read enable. + spi[self->index]->CS = SPI0_CS_REN_Msk; } + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/ports/broadcom/common-hal/busio/SPI.h b/ports/broadcom/common-hal/busio/SPI.h index aec91263677..3d52b6b0a44 100644 --- a/ports/broadcom/common-hal/busio/SPI.h +++ b/ports/broadcom/common-hal/busio/SPI.h @@ -23,5 +23,3 @@ typedef struct { uint8_t bits; uint8_t index; } busio_spi_obj_t; - -void reset_spi(void); diff --git a/ports/broadcom/common-hal/microcontroller/Processor.c b/ports/broadcom/common-hal/microcontroller/Processor.c index 4956604f9b6..94eafe6c3d1 100644 --- a/ports/broadcom/common-hal/microcontroller/Processor.c +++ b/ports/broadcom/common-hal/microcontroller/Processor.c @@ -31,5 +31,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } diff --git a/ports/broadcom/common-hal/microcontroller/__init__.c b/ports/broadcom/common-hal/microcontroller/__init__.c index b0ed1fcb9ec..279be26f91a 100644 --- a/ports/broadcom/common-hal/microcontroller/__init__.c +++ b/ports/broadcom/common-hal/microcontroller/__init__.c @@ -11,6 +11,7 @@ #include "common-hal/microcontroller/__init__.h" #include "peripherals/broadcom/defines.h" #include "peripherals/broadcom/interrupts.h" +#include "supervisor/port.h" #include "mphalport.h" @@ -39,6 +40,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { } void common_hal_mcu_reset(void) { + reset_cpu(); } // The singleton microcontroller.Processor object, bound to microcontroller.cpu diff --git a/ports/broadcom/common-hal/os/__init__.c b/ports/broadcom/common-hal/os/__init__.c index 72a9a07e907..c1c50234451 100644 --- a/ports/broadcom/common-hal/os/__init__.c +++ b/ports/broadcom/common-hal/os/__init__.c @@ -10,33 +10,6 @@ #include "py/objtuple.h" #include "py/qstr.h" -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; - -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_HW_MCU_NAME); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_HW_MCU_NAME); -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { return false; } diff --git a/ports/broadcom/common-hal/sdioio/SDCard.c b/ports/broadcom/common-hal/sdioio/SDCard.c index f87d40cd8dc..2c9e6a2bb58 100644 --- a/ports/broadcom/common-hal/sdioio/SDCard.c +++ b/ports/broadcom/common-hal/sdioio/SDCard.c @@ -11,6 +11,7 @@ #include "py/runtime.h" #include "common-hal/microcontroller/Pin.h" +#include "extmod/vfs.h" #include "shared-bindings/sdioio/SDCard.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" @@ -304,44 +305,95 @@ static void check_whole_block(mp_buffer_info_t *bufinfo) { } } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +// Native function for VFS blockdev layer +mp_negative_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); if (!self->init) { - return -EIO; + return -MP_EIO; } - check_whole_block(bufinfo); self->state_programming = true; COMPLETE_MEMORY_READS; - sdmmc_err_t error = sdmmc_write_sectors(&self->card_info, bufinfo->buf, - start_block, bufinfo->len / 512); + sdmmc_err_t error = sdmmc_write_sectors(&self->card_info, buf, + start_block, num_blocks); COMPLETE_MEMORY_READS; if (error != SDMMC_OK) { mp_printf(&mp_plat_print, "write sectors result %d\n", error); - return -EIO; + return -MP_EIO; } return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_negative_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { if (!self->init) { - return -EIO; + return -MP_EIO; } check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +mp_negative_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!self->init) { + return -MP_EIO; + } COMPLETE_MEMORY_READS; - sdmmc_err_t error = sdmmc_read_sectors(&self->card_info, bufinfo->buf, - start_block, bufinfo->len / 512); + sdmmc_err_t error = sdmmc_read_sectors(&self->card_info, buf, + start_block, num_blocks); COMPLETE_MEMORY_READS; if (error != SDMMC_OK) { - mp_printf(&mp_plat_print, "read sectors result %d when reading block %d for %d\n", error, start_block, bufinfo->len / 512); - return -EIO; + mp_printf(&mp_plat_print, "read sectors result %d when reading block %d for %d\n", error, start_block, num_blocks); + return -MP_EIO; } return 0; } +mp_negative_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + if (!self->init) { + return -MP_EIO; + } + check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { if (!self->init) { return false; diff --git a/ports/broadcom/mpconfigport.h b/ports/broadcom/mpconfigport.h index b9990be75ec..73fae8295de 100644 --- a/ports/broadcom/mpconfigport.h +++ b/ports/broadcom/mpconfigport.h @@ -13,8 +13,7 @@ #define CIRCUITPY_MCU_FAMILY broadcom #define MICROPY_PY_SYS_PLATFORM "BROADCOM" -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (1) -#define MICROPY_PY_FUNCTION_ATTRS (1) + #if BCM_VERSION == 2837 || BCM_VERSION == 2711 #define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_A) #elif BCM_VERSION == 2835 @@ -27,6 +26,8 @@ #define MICROPY_FATFS_EXFAT (1) #define MICROPY_FATFS_MKFS_FAT32 (1) +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED (1) + //////////////////////////////////////////////////////////////////////////////////////////////////// // This also includes mpconfigboard.h. diff --git a/ports/broadcom/mpconfigport.mk b/ports/broadcom/mpconfigport.mk index 543e1746836..844794b107a 100644 --- a/ports/broadcom/mpconfigport.mk +++ b/ports/broadcom/mpconfigport.mk @@ -22,6 +22,11 @@ CIRCUITPY_VIDEOCORE = 1 INTERNAL_FLASH_FILESYSTEM = 1 USB_NUM_ENDPOINT_PAIRS = 8 -USB_HIGHSPEED = 1 CIRCUITPY_BUILD_EXTENSIONS ?= disk.img.zip,kernel8.img + +ifeq ($(CHIP_VARIANT), "bcm2711") +CIRCUITPY_MIN_GCC_VERSION ?= 14 +else ifeq ($(CHIP_VARIANT), "bcm2837") +CIRCUITPY_MIN_GCC_VERSION ?= 14 +endif diff --git a/ports/broadcom/supervisor/port.c b/ports/broadcom/supervisor/port.c index 33b20b7c864..a0f0be30dd7 100644 --- a/ports/broadcom/supervisor/port.c +++ b/ports/broadcom/supervisor/port.c @@ -67,7 +67,6 @@ safe_mode_t port_init(void) { void reset_port(void) { #if CIRCUITPY_BUSIO reset_i2c(); - reset_spi(); reset_uart(); #endif @@ -85,8 +84,6 @@ void reset_port(void) { #if CIRCUITPY_AUDIOCORE audio_dma_reset(); #endif - - reset_all_pins(); } void reset_to_bootloader(void) { @@ -143,7 +140,11 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { } COMPLETE_MEMORY_READS; uint64_t microseconds = hi << 32 | lo; - return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977; + int64_t all_subticks = microseconds * 512 / 15625; + if (subticks != NULL) { + *subticks = all_subticks % 32; + } + return all_subticks / 32; } void TIMER_1_IRQHandler(void) { diff --git a/ports/cxd56/Makefile b/ports/cxd56/Makefile index 30abb8bb47f..88c39210220 100644 --- a/ports/cxd56/Makefile +++ b/ports/cxd56/Makefile @@ -74,7 +74,7 @@ CFLAGS += \ -fdata-sections \ -Wall \ -OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions +OPTIMIZATION_FLAGS ?= -O2 # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) @@ -110,15 +110,9 @@ LDFLAGS = \ CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_CXD56 -DCFG_TUD_MIDI_RX_BUFSIZE=512 -DCFG_TUD_CDC_RX_BUFSIZE=1024 -DCFG_TUD_MIDI_TX_BUFSIZE=512 -DCFG_TUD_CDC_TX_BUFSIZE=1024 -DCFG_TUD_MSC_BUFSIZE=512 $(CFLAGS_MOD) -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) +SRC_S = shared/runtime/gchelper_thumb2.s -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - -SRC_S = supervisor/cpu.s +SRC_C += shared/runtime/gchelper_native.c SRC_C += \ background.c \ @@ -129,8 +123,7 @@ SRC_C += \ OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif @@ -138,7 +131,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR += diff --git a/ports/cxd56/boards/spresense/mpconfigboard.h b/ports/cxd56/boards/spresense/mpconfigboard.h index 2d334ef29b3..c9510771b18 100644 --- a/ports/cxd56/boards/spresense/mpconfigboard.h +++ b/ports/cxd56/boards/spresense/mpconfigboard.h @@ -18,5 +18,3 @@ #define DEFAULT_UART_BUS_RX (&pin_UART2_RXD) #define DEFAULT_UART_BUS_TX (&pin_UART2_TXD) - -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) diff --git a/ports/cxd56/common-hal/busio/I2C.c b/ports/cxd56/common-hal/busio/I2C.c index 20ee4ac0f84..8e846b2402d 100644 --- a/ports/cxd56/common-hal/busio/I2C.c +++ b/ports/cxd56/common-hal/busio/I2C.c @@ -16,6 +16,10 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + if (frequency != I2C_SPEED_STANDARD && frequency != I2C_SPEED_FAST) { mp_arg_error_invalid(MP_QSTR_frequency); } @@ -44,12 +48,18 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { reset_pin_number(self->scl_pin->number); reset_pin_number(self->sda_pin->number); + + common_hal_busio_i2c_mark_deinit(self); } bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { return self->i2c_dev == NULL; } +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + self->i2c_dev = NULL; +} + bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { if (common_hal_busio_i2c_deinited(self)) { return false; @@ -81,7 +91,7 @@ bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { return I2C_TRANSFER(self->i2c_dev, &msg, 1) < 0 ? false : true; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) { +static mp_negative_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len, bool stop) { struct i2c_msg_s msg; msg.frequency = self->frequency; @@ -92,12 +102,12 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addre return -I2C_TRANSFER(self->i2c_dev, &msg, 1); } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len) { +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len) { struct i2c_msg_s msg; msg.frequency = self->frequency; @@ -108,9 +118,9 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8 return -I2C_TRANSFER(self->i2c_dev, &msg, 1); } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_negative_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/cxd56/common-hal/busio/SPI.c b/ports/cxd56/common-hal/busio/SPI.c index 8eedb624201..595b868f348 100644 --- a/ports/cxd56/common-hal/busio/SPI.c +++ b/ports/cxd56/common-hal/busio/SPI.c @@ -54,7 +54,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { return; } - self->spi_dev = NULL; + common_hal_busio_spi_mark_deinit(self); reset_pin_number(self->clock_pin->number); reset_pin_number(self->mosi_pin->number); @@ -65,11 +65,34 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->spi_dev == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->spi_dev = NULL; +} + bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { uint8_t mode; - self->frequency = baudrate; - SPI_SETFREQUENCY(self->spi_dev, baudrate); + // SPI_SETFREQUENCY() picks the nearest available frequency and returns it, + // which can be HIGHER than requested (it overshoots at low frequencies). + // Treat baudrate as a ceiling: if the driver overshoots, bisect downward on + // the requested target for the highest available frequency that does not + // exceed baudrate. The driver returns the actual frequency each call, so we + // don't depend on its divisor internals. + uint32_t actual = SPI_SETFREQUENCY(self->spi_dev, baudrate); + if (actual > baudrate) { + uint32_t lo = 1; // f(lo) <= baudrate + uint32_t hi = baudrate; // f(hi) > baudrate (just measured) + while (hi - lo > 1) { + uint32_t mid = lo + (hi - lo) / 2; + if (SPI_SETFREQUENCY(self->spi_dev, mid) <= baudrate) { + lo = mid; + } else { + hi = mid; + } + } + actual = SPI_SETFREQUENCY(self->spi_dev, lo); + } + self->frequency = actual; if (polarity == 0) { if (phase == 0) { diff --git a/ports/cxd56/common-hal/camera/Camera.c b/ports/cxd56/common-hal/camera/Camera.c index c3c935a168d..b9fa2787ef7 100644 --- a/ports/cxd56/common-hal/camera/Camera.c +++ b/ports/cxd56/common-hal/camera/Camera.c @@ -44,7 +44,7 @@ static const image_size_t isx019_image_size_table[] = { { VIDEO_HSIZE_QUADVGA, VIDEO_VSIZE_QUADVGA }, }; -static const char *get_imgsensor_name() { +static const char *get_imgsensor_name(void) { static struct v4l2_capability cap; ioctl(camera_dev.fd, VIDIOC_QUERYCAP, (unsigned long)&cap); @@ -113,7 +113,7 @@ static void camera_start_streaming(enum v4l2_buf_type type) { ioctl(camera_dev.fd, VIDIOC_STREAMON, (unsigned long)&type); } -static void camera_start_preview() { +static void camera_start_preview(void) { camera_set_format(V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_PIX_FMT_UYVY, VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA); v4l2_buffer_t buf; diff --git a/ports/cxd56/common-hal/microcontroller/Processor.c b/ports/cxd56/common-hal/microcontroller/Processor.c index 6b9d20afa04..a3e2a44a3e4 100644 --- a/ports/cxd56/common-hal/microcontroller/Processor.c +++ b/ports/cxd56/common-hal/microcontroller/Processor.c @@ -30,5 +30,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } diff --git a/ports/cxd56/common-hal/microcontroller/__init__.c b/ports/cxd56/common-hal/microcontroller/__init__.c index fa872f2807b..f7ac0c174ae 100644 --- a/ports/cxd56/common-hal/microcontroller/__init__.c +++ b/ports/cxd56/common-hal/microcontroller/__init__.c @@ -61,6 +61,8 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { void common_hal_mcu_reset(void) { filesystem_flush(); boardctl(BOARDIOC_RESET, 0); + // boardctl is noreturn in this case. + __builtin_unreachable(); } static const mp_rom_map_elem_t mcu_pin_globals_table[] = { diff --git a/ports/cxd56/common-hal/os/__init__.c b/ports/cxd56/common-hal/os/__init__.c index 7d211b3a79d..902228f1db0 100644 --- a/ports/cxd56/common-hal/os/__init__.c +++ b/ports/cxd56/common-hal/os/__init__.c @@ -10,43 +10,7 @@ #include "py/objstr.h" #include "py/objtuple.h" -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; - -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "spresense"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "spresense"); -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - +// No HW TRNG. bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { - uint32_t i = 0; - - while (i < length) { - uint32_t new_random = rand(); - for (int j = 0; j < 4 && i < length; j++) { - buffer[i] = new_random & 0xff; - i++; - new_random >>= 8; - } - } - - return true; + return false; } diff --git a/ports/cxd56/common-hal/pulseio/PulseIn.c b/ports/cxd56/common-hal/pulseio/PulseIn.c index f0063d3f0d8..0c45cf85032 100644 --- a/ports/cxd56/common-hal/pulseio/PulseIn.c +++ b/ports/cxd56/common-hal/pulseio/PulseIn.c @@ -65,7 +65,7 @@ static int pulsein_interrupt_handler(int irq, FAR void *context, FAR void *arg) void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); + self->buffer = (uint16_t *)m_malloc_without_collect(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } diff --git a/ports/cxd56/common-hal/sdioio/SDCard.c b/ports/cxd56/common-hal/sdioio/SDCard.c index aa1d1371770..227011a8871 100644 --- a/ports/cxd56/common-hal/sdioio/SDCard.c +++ b/ports/cxd56/common-hal/sdioio/SDCard.c @@ -8,6 +8,7 @@ #include #include +#include "extmod/vfs.h" #include "py/mperrno.h" #include "py/runtime.h" @@ -95,22 +96,73 @@ static void check_whole_block(mp_buffer_info_t *bufinfo) { } } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +// Native function for VFS blockdev layer +mp_negative_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + int result = self->inode->u.i_bops->read(self->inode, buf, start_block, num_blocks); + if (result < 0) { + return -MP_EIO; + } + return 0; +} + +mp_negative_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { if (common_hal_sdioio_sdcard_deinited(self)) { raise_deinited_error(); } check_whole_block(bufinfo); - return self->inode->u.i_bops->read(self->inode, bufinfo->buf, start_block, bufinfo->len / 512); + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +// Native function for VFS blockdev layer +mp_negative_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + int result = self->inode->u.i_bops->write(self->inode, buf, start_block, num_blocks); + if (result < 0) { + return -MP_EIO; + } + return 0; +} + +mp_negative_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { if (common_hal_sdioio_sdcard_deinited(self)) { raise_deinited_error(); } check_whole_block(bufinfo); - return self->inode->u.i_bops->write(self->inode, bufinfo->buf, start_block, bufinfo->len / 512); + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } } void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self) { diff --git a/ports/cxd56/mkspk/clefia.c b/ports/cxd56/mkspk/clefia.c index e946ee5348a..d36f638fa0b 100644 --- a/ports/cxd56/mkspk/clefia.c +++ b/ports/cxd56/mkspk/clefia.c @@ -466,16 +466,16 @@ int clefiakeyset(unsigned char *rk, const unsigned char *skey) { void clefiaencrypt(unsigned char *ct, const unsigned char *pt, const unsigned char *rk, const int r) { - unsigned char rin[16]; + unsigned char r_in[16]; unsigned char rout[16]; - bytecpy(rin, pt, 16); + bytecpy(r_in, pt, 16); - bytexor(rin + 4, rin + 4, rk + 0, 4); /* initial key whitening */ - bytexor(rin + 12, rin + 12, rk + 4, 4); + bytexor(r_in + 4, r_in + 4, rk + 0, 4); /* initial key whitening */ + bytexor(r_in + 12, r_in + 12, rk + 4, 4); rk += 8; - clefiagfn4(rout, rin, rk, r); /* GFN_{4,r} */ + clefiagfn4(rout, r_in, rk, r); /* GFN_{4,r} */ bytecpy(ct, rout, 16); bytexor(ct + 4, ct + 4, rk + r * 8 + 0, 4); /* final key whitening */ diff --git a/ports/cxd56/mpconfigport.h b/ports/cxd56/mpconfigport.h index 3bcb2528687..ec606a76547 100644 --- a/ports/cxd56/mpconfigport.h +++ b/ports/cxd56/mpconfigport.h @@ -8,6 +8,9 @@ #define MICROPY_PY_SYS_PLATFORM "CXD56" +// SD card socket on board is configured for sdioio, which is not supported for automatic USB presentation. +#define CIRCUITPY_SDCARD_USB (0) + // 64kiB stack #define CIRCUITPY_DEFAULT_STACK_SIZE (0x10000) @@ -20,6 +23,8 @@ #define USB_MSC_EP_NUM_OUT (5) #define USB_MSC_EP_NUM_IN (4) +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED (1) + #include "py/circuitpy_mpconfig.h" #define MICROPY_BYTES_PER_GC_BLOCK (32) diff --git a/ports/cxd56/mpconfigport.mk b/ports/cxd56/mpconfigport.mk index cb54233a07e..ebfaa91f251 100644 --- a/ports/cxd56/mpconfigport.mk +++ b/ports/cxd56/mpconfigport.mk @@ -1,5 +1,3 @@ -USB_HIGHSPEED = 1 - # Number of USB endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 6 diff --git a/ports/cxd56/supervisor/cpu.s b/ports/cxd56/supervisor/cpu.s deleted file mode 100755 index 9e6807a5e2e..00000000000 --- a/ports/cxd56/supervisor/cpu.s +++ /dev/null @@ -1,27 +0,0 @@ -.syntax unified -.cpu cortex-m4 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0], #4 -str r5, [r0], #4 -str r6, [r0], #4 -str r7, [r0], #4 -str r8, [r0], #4 -str r9, [r0], #4 -str r10, [r0], #4 -str r11, [r0], #4 -str r12, [r0], #4 -str r13, [r0], #4 - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/cxd56/supervisor/port.c b/ports/cxd56/supervisor/port.c index 237013ff2bd..3dc54df96fb 100644 --- a/ports/cxd56/supervisor/port.c +++ b/ports/cxd56/supervisor/port.c @@ -66,8 +66,6 @@ void reset_port(void) { #if CIRCUITPY_RTC rtc_reset(); #endif - - reset_all_pins(); } void reset_to_bootloader(void) { @@ -124,7 +122,9 @@ void board_timerhook(void) { uint64_t port_get_raw_ticks(uint8_t *subticks) { uint64_t count = cxd56_rtc_count(); - *subticks = count % 32; + if (subticks != NULL) { + *subticks = count % 32; + } return count / 32; } diff --git a/ports/cxd56/tools/flash_writer.py b/ports/cxd56/tools/flash_writer.py index fc15cf8c289..9c53e1b56c7 100755 --- a/ports/cxd56/tools/flash_writer.py +++ b/ports/cxd56/tools/flash_writer.py @@ -595,11 +595,11 @@ def main(): if subprocess.call("cd " + sys.path[0] + "; ./reset_board.sh", shell=True) == 0: print("auto reset board success!!") do_wait_reset = False - bootrom_msg = writer.cancel_autoboot() + writer.cancel_autoboot() if ConfigArgs.DTR_RESET: do_wait_reset = False - bootrom_msg = writer.cancel_autoboot() + writer.cancel_autoboot() if ConfigArgs.WAIT_RESET is False and do_wait_reset is True: rx = writer.recv() @@ -617,7 +617,7 @@ def main(): # Wait to reset the board print("Please press RESET button on target board") sys.stdout.flush() - bootrom_msg = writer.cancel_autoboot() + writer.cancel_autoboot() # Remove files if ConfigArgs.ERASE_NAME: diff --git a/ports/espressif/CMakeLists.txt b/ports/espressif/CMakeLists.txt index addcd36f172..e612e4f31de 100644 --- a/ports/espressif/CMakeLists.txt +++ b/ports/espressif/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required(VERSION 3.16) set(ENV{IDF_PATH} ${CMAKE_SOURCE_DIR}/esp-idf) # The component list here determines what options we get in menuconfig and what the ninja file can build. -set(COMPONENTS bt driver esp_driver_dac esp_driver_gpio esp_driver_gptimer esp_driver_i2s esp_driver_ledc esp_driver_pcnt esp_driver_rmt esp_driver_spi esp_driver_tsens esp_driver_uart esp-tls esp_adc_cal esp_event esp_netif esp_psram esp_wifi esptool_py freertos log lwip main mbedtls mdns soc ulp usb wpa_supplicant esp-camera esp_lcd vfs esp_vfs_console sdmmc) +set(COMPONENTS bt driver esp_driver_dac esp_driver_gpio esp_driver_gptimer esp_driver_i2c esp_driver_i2s esp_driver_ledc esp_driver_pcnt esp_driver_rmt esp_driver_sdmmc esp_driver_spi esp_driver_touch_sens esp_driver_tsens esp_driver_uart esp-tls esp_adc esp_event esp_netif esp_psram esp_security esp_wifi esptool_py freertos log lwip main mbedtls mdns pthread soc ulp wpa_supplicant esp_lcd vfs esp_stdio sdmmc esp-camera) set(EXTRA_COMPONENT_DIRS "esp-protocols/components/mdns" "esp-camera") include($ENV{IDF_PATH}/tools/cmake/project.cmake) diff --git a/ports/espressif/Makefile b/ports/espressif/Makefile index c14c9cf438b..ca70127565f 100644 --- a/ports/espressif/Makefile +++ b/ports/espressif/Makefile @@ -6,28 +6,10 @@ include ../../py/circuitpy_mkenv.mk -ifeq ($(IDF_TARGET),esp32c2) -IDF_TARGET_ARCH = riscv -CROSS_COMPILE = riscv32-esp-elf- -else ifeq ($(IDF_TARGET),esp32c3) -IDF_TARGET_ARCH = riscv -CROSS_COMPILE = riscv32-esp-elf- -else ifeq ($(IDF_TARGET),esp32p4) -IDF_TARGET_ARCH = riscv -CROSS_COMPILE = riscv32-esp-elf- -else ifeq ($(IDF_TARGET),esp32c6) -IDF_TARGET_ARCH = riscv -CROSS_COMPILE = riscv32-esp-elf- -else ifeq ($(IDF_TARGET),esp32h2) -IDF_TARGET_ARCH = riscv -CROSS_COMPILE = riscv32-esp-elf- -else -IDF_TARGET_ARCH = xtensa -CROSS_COMPILE = xtensa-$(IDF_TARGET)-elf- -endif - ifeq ($(IDF_TARGET),esp32s3) BT_IDF_TARGET = esp32c3 +else ifeq ($(IDF_TARGET),esp32c61) +BT_IDF_TARGET = esp32c6 else BT_IDF_TARGET = $(IDF_TARGET) endif @@ -65,43 +47,51 @@ INC += \ -isystem esp-idf/components/bt/host/nimble/nimble/porting/nimble/include \ -isystem esp-idf/components/bt/host/nimble/nimble/porting/npl/freertos/include \ -isystem esp-idf/components/bt/host/nimble/port/include \ - -isystem esp-idf/components/driver/i2c/include \ - -isystem esp-idf/components/driver/touch_sensor/include \ - -isystem esp-idf/components/driver/touch_sensor/$(IDF_TARGET)/include \ + -isystem esp-idf/components/bt/porting/include \ + -isystem esp-idf/components/bt/porting/npl/freertos/include \ + -isystem esp-idf/components/bt/porting/transport/include \ + -isystem esp-idf/components/esp_driver_touch_sens/include \ -isystem esp-idf/components/driver/twai/include \ + -isystem esp-idf/components/driver/i2c/include \ -isystem esp-idf/components/efuse/include \ -isystem esp-idf/components/efuse/$(IDF_TARGET)/include \ - -isystem esp-idf/components/$(IDF_TARGET)/include \ -isystem esp-idf/components/esp_adc/include \ -isystem esp-idf/components/esp_adc/$(IDF_TARGET)/include \ -isystem esp-idf/components/esp_app_format/include \ -isystem esp-idf/components/esp_bootloader_format/include \ -isystem esp-idf/components/esp_common/include \ - -isystem esp-idf/components/esp_driver_deprecated \ -isystem esp-idf/components/esp_driver_dac/include \ -isystem esp-idf/components/esp_driver_gpio/include \ -isystem esp-idf/components/esp_driver_gptimer/include \ -isystem esp-idf/components/esp_driver_i2c/include \ -isystem esp-idf/components/esp_driver_i2s/include \ - -isystem esp-idf/components/esp_driver_$(IDF_TARGET)/include \ -isystem esp-idf/components/esp_driver_ledc/include \ + -isystem esp-idf/components/esp_driver_parlio/include \ -isystem esp-idf/components/esp_driver_pcnt/include \ -isystem esp-idf/components/esp_driver_rmt/include \ -isystem esp-idf/components/esp_driver_sdio/include \ -isystem esp-idf/components/esp_driver_sdmmc/include \ + -isystem esp-idf/components/esp_driver_sdmmc/legacy/include \ + -isystem esp-idf/components/esp_driver_dma/include \ -isystem esp-idf/components/esp_driver_spi/include \ -isystem esp-idf/components/esp_driver_tsens/include \ -isystem esp-idf/components/esp_driver_uart/include \ -isystem esp-idf/components/esp_event/include \ - -isystem esp-idf/components/esp_hw_support/dma/include \ -isystem esp-idf/components/esp_hw_support/include \ -isystem esp-idf/components/esp_hw_support/include/soc \ + -isystem esp-idf/components/esp_hw_support/port/$(IDF_TARGET)/private_include \ + -isystem esp-idf/components/esp_hw_support/etm/include \ + -isystem esp-idf/components/esp_mm/include \ -isystem esp-idf/components/esp_netif/include \ + -isystem esp-idf/components/esp_blockdev/include \ -isystem esp-idf/components/esp_partition/include \ -isystem esp-idf/components/esp_pm/include \ -isystem esp-idf/components/esp_psram/include \ -isystem esp-idf/components/esp_ringbuf/include \ -isystem esp-idf/components/esp_rom/include \ + -isystem esp-idf/components/esp_rom/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_rom/$(IDF_TARGET)/include/$(IDF_TARGET) \ + -isystem esp-idf/components/esp_security/include \ -isystem esp-idf/components/esp_system/include \ -isystem esp-idf/components/esp_timer/include \ -isystem esp-idf/components/esp_wifi/include \ @@ -118,6 +108,38 @@ INC += \ -isystem esp-idf/components/hal/include \ -isystem esp-idf/components/hal/$(IDF_TARGET)/include \ -isystem esp-idf/components/hal/platform_port/include \ + -isystem esp-idf/components/esp_hal_gpio/include \ + -isystem esp-idf/components/esp_hal_gpio/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_timg/include \ + -isystem esp-idf/components/esp_hal_ana_conv/include \ + -isystem esp-idf/components/esp_hal_touch_sens/include \ + -isystem esp-idf/components/esp_hal_uart/include \ + -isystem esp-idf/components/esp_hal_gpspi/include \ + -isystem esp-idf/components/esp_hal_i2c/include \ + -isystem esp-idf/components/esp_hal_i2s/include \ + -isystem esp-idf/components/esp_hal_i2s/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_ledc/include \ + -isystem esp-idf/components/esp_hal_pcnt/include \ + -isystem esp-idf/components/esp_hal_rmt/include \ + -isystem esp-idf/components/esp_hal_rmt/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_twai/include \ + -isystem esp-idf/components/esp_hal_twai/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_timg/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_gpspi/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_dma/include \ + -isystem esp-idf/components/esp_hal_dma/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_lcd/include \ + -isystem esp-idf/components/esp_hal_lcd/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_sd/include \ + -isystem esp-idf/components/esp_hal_sd/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_usb/include \ + -isystem esp-idf/components/esp_hal_usb/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_parlio/include \ + -isystem esp-idf/components/esp_hal_pmu/include \ + -isystem esp-idf/components/esp_hal_pmu/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_wdt/include \ + -isystem esp-idf/components/esp_hal_wdt/$(IDF_TARGET)/include \ + -isystem esp-idf/components/esp_hal_security/include \ -isystem esp-idf/components/heap/include \ -isystem esp-idf/components/log/include \ -isystem esp-idf/components/lwip/include \ @@ -127,19 +149,20 @@ INC += \ -isystem esp-idf/components/lwip/port/freertos/include \ -isystem esp-idf/components/mbedtls/esp_crt_bundle/include \ -isystem esp-idf/components/mbedtls/mbedtls/include \ + -isystem esp-idf/components/mbedtls/mbedtls/tf-psa-crypto/include \ + -isystem esp-idf/components/mbedtls/mbedtls/tf-psa-crypto/drivers/builtin/include \ -isystem esp-idf/components/mbedtls/port/include \ - -isystem esp-idf/components/newlib/platform_include \ + -isystem esp-idf/components/mbedtls/port/psa_driver/include \ + -isystem esp-idf/components/esp_libc/platform_include \ -isystem esp-idf/components/nvs_flash/include \ - -isystem esp-idf/components/sdio/include \ -isystem esp-idf/components/sdmmc/include \ -isystem esp-idf/components/soc/include \ -isystem esp-idf/components/soc/$(IDF_TARGET)/include \ + -isystem esp-idf/components/soc/$(IDF_TARGET)/register \ -isystem esp-idf/components/spi_flash/include \ - -isystem esp-idf/components/usb/include \ -isystem esp-idf/components/ulp/ulp_fsm/include \ -isystem esp-idf/components/ulp/ulp_riscv/include \ -isystem esp-idf/components/ulp/ulp_common/include \ - -isystem esp-idf/components/ulp/ulp_common/include/$(IDF_TARGET) \ -isystem esp-idf/components/$(IDF_TARGET_ARCH)/include \ -isystem esp-idf/components/$(IDF_TARGET_ARCH)/$(IDF_TARGET)/include \ -isystem esp-protocols/components/mdns/include @@ -148,6 +171,7 @@ CFLAGS += \ -DHAVE_CONFIG_H \ -DESP_PLATFORM=1 \ -DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\" \ + -DMBEDTLS_DECLARE_PRIVATE_IDENTIFIERS \ -DMBEDTLS_PADLOCK_FILE=\"ports/espressif/esp-idf/components/mbedtls/mbedtls/library/padlock.h\" \ -DUNITY_INCLUDE_CONFIG_H -DWITH_POSIX \ -DMP3DEC_GENERIC @@ -164,6 +188,8 @@ CFLAGS += -DSTACK_CANARY_VALUE=0xa5a5a5a5 REGISTRATION_FUNCTIONS = \ -u ld_include_highint_hdl \ -u __cxx_fatal_exception \ + -u __cxx_init_dummy \ + -u __cxa_guard_dummy \ -u esp_app_desc \ -u esp_timer_init_include_func \ -u uart_vfs_include_dev_init \ @@ -171,13 +197,66 @@ REGISTRATION_FUNCTIONS = \ -u __ubsan_include \ -u esp_system_include_startup_funcs \ -u esp_efuse_startup_include_func \ - -u newlib_include_heap_impl \ - -u newlib_include_syscalls_impl \ - -u newlib_include_pthread_impl \ - -u newlib_include_assert_impl \ - -u newlib_include_init_funcs \ + -u esp_libc_include_heap_impl \ + -u esp_libc_include_reent_syscalls_impl \ + -u esp_libc_include_syscalls_impl \ + -u esp_libc_include_pthread_impl \ + -u esp_libc_include_assert_impl \ + -u esp_libc_include_getentropy_impl \ + -u esp_libc_include_init_funcs \ + -u esp_libc_init_funcs \ -u include_esp_phy_override \ - -u vfs_include_syscalls_impl + -u vfs_include_syscalls_impl \ + -u esp_vfs_include_nullfs_register \ + -u usb_serial_jtag_vfs_include_dev_init \ + -u usb_serial_jtag_connection_monitor_include \ + -u esp_flash_spi_init_include_func \ + -u pthread_include_pthread_impl \ + -u pthread_include_pthread_cond_var_impl \ + -u pthread_include_pthread_local_storage_impl \ + -u pthread_include_pthread_rwlock_impl \ + -u pthread_include_pthread_semaphore_impl \ + -u esp_security_init_include_impl \ + -u mbedtls_psa_crypto_init_include_impl + +# RISC-V picolibc ships optimized memcpy/memset/etc. that need forcing +# (gated by CONFIG_LIBC_OPTIMIZED_MISALIGNED_ACCESS in IDF's esp_libc CMake). +ifeq ($(IDF_TARGET_ARCH),riscv) +REGISTRATION_FUNCTIONS += \ + -u esp_libc_include_memcpy_impl \ + -u esp_libc_include_memmove_impl \ + -u esp_libc_include_memcmp_impl \ + -u esp_libc_include_memset_impl \ + -u esp_libc_include_strcpy_impl \ + -u esp_libc_include_strncpy_impl \ + -u esp_libc_include_strcmp_impl \ + -u esp_libc_include_strncmp_impl +endif + +# Chips with PAU + TOP power-down (SOC_PAU_SUPPORTED && SOC_PM_SUPPORT_TOP_PD): +# C5, C6, C61, H2, H21, H4, P4. These pull in sleep_gpio + system-peripheral +# retention, and the SW-driven RISC-V CPU register save/restore path. +ifneq ($(filter $(IDF_TARGET),esp32c5 esp32c6 esp32c61 esp32h2 esp32h21 esp32h4 esp32p4),) +REGISTRATION_FUNCTIONS += \ + -u esp_sleep_gpio_include \ + -u sleep_system_peripheral_dummy \ + -u rv_core_critical_regs_save \ + -u rv_core_critical_regs_restore +endif + +# RISC-V chips with a hardware FPU (H4, P4) need FPU register save/restore +# alongside the CPU retention path. +ifneq ($(filter $(IDF_TARGET),esp32h4 esp32p4),) +REGISTRATION_FUNCTIONS += \ + -u rv_core_fpu_save \ + -u rv_core_fpu_restore +endif + +ifneq ($(CIRCUITPY_WIFI),0) +ifeq ($(filter $(IDF_TARGET),esp32s2 esp32p4),) +REGISTRATION_FUNCTIONS += -u esp_coex_init_include_func +endif +endif #Debugging/Optimization @@ -190,12 +269,12 @@ ifeq ($(DEBUG), 1) OPTIMIZATION_FLAGS ?= -Og CFLAGS += -DDEBUG endif - # You may want to enable these flags to make setting breakpoints easier. - # CFLAGS += -fno-inline -fno-ipa-sra +# You may want to enable these flags to make setting breakpoints easier. +# CFLAGS += -fno-inline -fno-ipa-sra else CFLAGS += -DNDEBUG - # RISC-V is larger than xtensa - # Use -Os for RISC-V when it overflows +# RISC-V is larger than xtensa +# Use -Os for RISC-V when it overflows ifeq ($(IDF_TARGET_ARCH),riscv) OPTIMIZATION_FLAGS ?= -Os else @@ -206,48 +285,66 @@ endif # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) -CFLAGS += $(INC) -Werror -Wall -std=gnu11 -Wl,--gc-sections $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes +# Default ROM symbol maps; per-chip blocks below may override. +IDF_TARGET_ROM_LD ?= $(IDF_TARGET).rom.ld +# Floating-point/libgcc ROM map. IDF picks between libgcc and rvfp based on +# CONFIG_COMPILER_FLOAT_LIB_FROM_GCCLIB (rvfp xor libgcc, never both). Default +# to libgcc; targets that ship the rvfp variant in ROM (P4 in particular) +# override this. +IDF_TARGET_ROM_FLOAT_LD ?= $(IDF_TARGET).rom.libgcc.ld -# Most current ESPs have nano versions of newlib in ROM so we use them. -ifneq ($(IDF_TARGET),esp32c6) - CFLAGS += --specs=nano.specs - LDFLAGS += -T$(IDF_TARGET).rom.newlib-nano.ld -else - LDFLAGS += -T$(IDF_TARGET).rom.newlib-normal.ld -endif +CFLAGS += $(INC) -Werror -Wall -std=gnu11 -Wl,--gc-sections $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes -Werror=old-style-definition -Wno-error=cpp -Wno-cpp + +# ESP-IDF v6.0 uses picolibc instead of newlib. +CFLAGS += --specs=picolibc.specs ifeq ($(IDF_TARGET_ARCH),xtensa) # Remove the last two flags once TinyUSB is updated with the `#include ` instead of # `#include "xtensa/xtensa_api.h"`. -CFLAGS += -mlongcalls -isystem esp-idf/components/xtensa/deprecated_include/ -Wno-error=cpp + CFLAGS += -mlongcalls -fno-builtin-memcpy -fno-builtin-memset -fno-builtin-bzero + CFLAGS += -isystem esp-idf/components/xtensa/deprecated_include/ +ifeq ($(IDF_TARGET),esp32) + CFLAGS += -Wno-frame-address +endif + CFLAGS += -DMICROPY_GCREGS_SETJMP=1 + +# Wrap longjmp with a patched version that protects register window update with a critical section + LDFLAGS += -Wl,--wrap=longjmp + + SRC_C += shared/runtime/gchelper_generic.c else ifeq ($(IDF_TARGET_ARCH),riscv) -ifeq ($(IDF_TARGET),esp32p4) -CFLAGS += -march=rv32imafc_zicsr_zifencei_xesppie -mabi=ilp32f -else -CFLAGS += -march=rv32imac_zicsr_zifencei -endif + ifeq ($(IDF_TARGET),esp32p4) + CFLAGS += -march=rv32imafc_zicsr_zifencei_zaamo_zalrsc -mabi=ilp32f + else ifeq ($(IDF_TARGET),$(filter $(IDF_TARGET),esp32c2 esp32c3)) + CFLAGS += -march=rv32imc_zicsr_zifencei + else + CFLAGS += -march=rv32imac_zicsr_zifencei_zaamo_zalrsc + endif -LDFLAGS += \ - -Lesp-idf/components/riscv/ld \ - -Trom.api.ld + LDFLAGS += \ + -Lesp-idf/components/riscv/ld \ + -Trom.api.ld + + SRC_C += shared/runtime/gchelper_native.c + SRC_S = shared/runtime/gchelper_rv32i.s endif -$(BUILD)/lib/tlsf/tlsf.o: CFLAGS += -Wno-cast-align -LDFLAGS += $(CFLAGS) -Wl,-nostdlib -Wl,-Map=$@.map -Wl,-cref -Wl,--undefined=uxTopUsedPriority +LDFLAGS += $(CFLAGS) -nostartfiles -Wl,-nostdlib -Wl,-Map=$@.map -Wl,-cref -Wl,--undefined=uxTopUsedPriority LDFLAGS += \ -L$(BUILD)/esp-idf/esp-idf/esp_system/ld \ -Lesp-idf/components/esp_rom/$(IDF_TARGET)/ld \ -Lesp-idf/components/soc/$(IDF_TARGET)/ld \ + -Lesp-idf/components/esp_hal_wdt/$(IDF_TARGET) \ -Tmemory.ld \ -Tsections.ld \ -T$(IDF_TARGET).peripherals.ld \ - -T$(IDF_TARGET).rom.ld \ + -T$(IDF_TARGET_ROM_LD) \ -T$(IDF_TARGET).rom.api.ld \ - -T$(IDF_TARGET).rom.libgcc.ld \ + -T$(IDF_TARGET_ROM_FLOAT_LD) \ -Wl,-Bstatic \ -Wl,--no-warn-mismatch \ -Wl,--build-id=none \ @@ -255,92 +352,201 @@ LDFLAGS += \ ifeq ($(IDF_TARGET),esp32) LDFLAGS += \ - -Tesp32.rom.newlib-data.ld \ - -Tesp32.rom.newlib-funcs.ld \ - -Tesp32.rom.newlib-time.ld \ - -Tesp32.rom.spiflash_legacy.ld + -Tesp32.rom.libc-funcs.ld + +CFLAGS += -isystem esp-idf/components/esp_driver_touch_sens/hw_ver1/include CHIP_COMPONENTS = \ - esp_driver_dac + esp_driver_dac \ + esp_driver_touch_sens \ + esp_hal_i2s \ + esp_hal_lcd \ + esp_hal_pcnt \ + esp_hal_pmu \ + esp_hal_rmt \ + esp_hal_touch_sens \ + esp_hal_twai else ifeq ($(IDF_TARGET),esp32c2) LDFLAGS += \ + -Tesp32c2.rom.ble.ld \ -Tesp32c2.rom.heap.ld \ - -Tesp32c2.rom.newlib.ld \ + -Tesp32c2.rom.libc.ld \ -Tesp32c2.rom.version.ld \ -Tesp32c2.rom.systimer.ld \ - -Tesp32c2.rom.wdt.ld + -Trom.wdt.ld CFLAGS += -DSOC_XTAL_FREQ_MHZ=CONFIG_XTAL_FREQ CHIP_COMPONENTS = \ - esp_driver_tsens + esp_driver_tsens \ + esp_hal_dma \ + esp_hal_pmu else ifeq ($(IDF_TARGET),esp32c3) +# esp32c2 has none of: esp_hal_i2s esp_hal_lcd esp_hal_pcnt esp_hal_touch_sens esp_hal_twai LDFLAGS += \ - -Tesp32c3.rom.newlib.ld \ - -Tesp32c3.rom.newlib-time.ld \ + -Tesp32c3.rom.libc.ld \ -Tesp32c3.rom.version.ld \ - -Tesp32c3.rom.eco3.ld + -Tesp32c3.rom.eco3_bt_funcs.ld \ + -Tesp32c3.rom.eco3.ld \ + -Tesp32c3.rom.bt_funcs.ld CHIP_COMPONENTS = \ - esp_driver_tsens + esp_driver_tsens \ + esp_driver_usb_serial_jtag \ + esp_hal_dma \ + esp_hal_i2s \ + esp_hal_pmu \ + esp_hal_rmt \ + esp_hal_twai \ + esp_hal_usb else ifeq ($(IDF_TARGET),esp32c6) LDFLAGS += \ -Tesp32c6.rom.phy.ld \ -Tesp32c6.rom.pp.ld \ -Tesp32c6.rom.net80211.ld \ - -Tesp32c6.rom.newlib.ld \ + -Tesp32c6.rom.libc.ld \ -Tesp32c6.rom.coexist.ld \ -Tesp32c6.rom.heap.ld \ -Tesp32c6.rom.systimer.ld \ - -Tesp32c6.rom.wdt.ld + -Trom.wdt.ld + + +CHIP_COMPONENTS = \ + esp_driver_tsens \ + esp_driver_usb_serial_jtag \ + esp_hal_dma \ + esp_hal_i2s \ + esp_hal_pcnt \ + esp_hal_pmu \ + esp_hal_rmt \ + esp_hal_twai \ + esp_hal_usb + +else ifeq ($(IDF_TARGET),esp32c61) +LDFLAGS += \ + -Tesp32c61.rom.phy.ld \ + -Tesp32c61.rom.pp.ld \ + -Tesp32c61.rom.net80211.ld \ + -Tesp32c61.rom.libc.ld \ + -Tesp32c61.rom.version.ld \ + -Tesp32c61.rom.coexist.ld \ + -Tesp32c61.rom.heap.ld \ + -Tesp32c61.rom.systimer.ld \ + -Trom.wdt.ld CHIP_COMPONENTS = \ - esp_driver_tsens + esp_driver_tsens \ + esp_driver_usb_serial_jtag \ + esp_hal_dma \ + esp_hal_i2s \ + esp_hal_pmu \ + esp_hal_usb else ifeq ($(IDF_TARGET),esp32p4) +CIRCUITPY_ESP32P4_REV ?= 1 +CFLAGS += \ + -isystem esp-idf/components/soc/esp32p4/register/hw_ver$(CIRCUITPY_ESP32P4_REV) \ + -isystem esp-idf/components/esp_hw_support/ldo/include \ + -isystem esp-idf/components/esp_driver_touch_sens/hw_ver3/include + +ifeq ($(CIRCUITPY_ESP32P4_REV),3) +IDF_TARGET_ROM_LD = esp32p4.rom.eco5.ld +IDF_TARGET_ROM_FLOAT_LD = esp32p4.rom.eco5.rvfp.ld +LDFLAGS += \ + -Tesp32p4.rom.systimer.ld \ + -Tesp32p4.rom.eco5.libc.ld \ + -Tesp32p4.rom.version.ld \ + -Trom.wdt.ld +else +IDF_TARGET_ROM_FLOAT_LD = esp32p4.rom.rvfp.ld LDFLAGS += \ - -Tesp32p4.rom.newlib.ld \ + -Tesp32p4.rom.libc.ld \ -Tesp32p4.rom.systimer.ld \ - -Tesp32p4.rom.wdt.ld + -Tesp32p4.rom.version.ld \ + -Trom.wdt.ld +endif CHIP_COMPONENTS = \ - esp_driver_tsens + esp_driver_touch_sens \ + esp_driver_tsens \ + esp_driver_usb_serial_jtag \ + esp_hal_dma \ + esp_hal_i2s \ + esp_hal_lcd \ + esp_hal_pcnt \ + esp_hal_pmu \ + esp_hal_rmt \ + esp_hal_touch_sens \ + esp_hal_twai \ + esp_hal_usb else ifeq ($(IDF_TARGET),esp32h2) LDFLAGS += \ -Tesp32h2.rom.heap.ld \ - -Tesp32h2.rom.newlib.ld \ + -Tesp32h2.rom.libc.ld \ -Tesp32h2.rom.systimer.ld \ - -Tesp32h2.rom.wdt.ld + -Trom.wdt.ld CHIP_COMPONENTS = \ - esp_driver_tsens + esp_driver_tsens \ + esp_driver_usb_serial_jtag \ + esp_hal_dma \ + esp_hal_i2s \ + esp_hal_pcnt \ + esp_hal_pmu \ + esp_hal_rmt \ + esp_hal_twai \ + esp_hal_usb else ifeq ($(IDF_TARGET),esp32s2) +CFLAGS += -isystem esp-idf/components/esp_driver_touch_sens/hw_ver2/include + LDFLAGS += \ - -Tesp32s2.rom.newlib-data.ld \ - -Tesp32s2.rom.newlib-funcs.ld \ - -Tesp32s2.rom.newlib-time.ld \ + -Tesp32s2.rom.libc-funcs.ld \ -Tesp32s2.rom.spiflash_legacy.ld CHIP_COMPONENTS = \ esp_driver_dac \ - esp_driver_tsens + esp_driver_touch_sens \ + esp_driver_tsens \ + esp_hal_dma \ + esp_hal_i2s \ + esp_hal_lcd \ + esp_hal_pcnt \ + esp_hal_pmu \ + esp_hal_rmt \ + esp_hal_touch_sens \ + esp_hal_twai \ + esp_hal_usb else ifeq ($(IDF_TARGET),esp32s3) +CFLAGS += -isystem esp-idf/components/esp_driver_touch_sens/hw_ver2/include + LDFLAGS += \ - -Tesp32s3.rom.newlib.ld \ + -Tesp32s3.rom.libc.ld \ -Tesp32s3.rom.version.ld \ -Tesp32s3.rom.systimer.ld \ - -Tesp32s3.rom.wdt.ld + -Tesp32s3.rom.bt_funcs.ld \ + -Trom.wdt.ld CHIP_COMPONENTS = \ - esp_driver_tsens + esp_driver_touch_sens \ + esp_driver_tsens \ + esp_driver_usb_serial_jtag \ + esp_hal_dma \ + esp_hal_i2s \ + esp_hal_lcd \ + esp_hal_pcnt \ + esp_hal_pmu \ + esp_hal_rmt \ + esp_hal_touch_sens \ + esp_hal_twai \ + esp_hal_usb endif @@ -361,6 +567,8 @@ else ifeq ($(IDF_TARGET),esp32c3) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32C3 else ifeq ($(IDF_TARGET),esp32c6) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32C6 +else ifeq ($(IDF_TARGET),esp32c61) +CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32C61 else ifeq ($(IDF_TARGET),esp32p4) CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_ESP32P4 else ifeq ($(IDF_TARGET),esp32h2) @@ -376,10 +584,19 @@ CFLAGS += \ -DCFG_TUD_TASK_QUEUE_SZ=32 endif ifeq ($(CIRCUITPY_USB_DEVICE),1) +ifeq ($(IDF_TARGET),esp32s2) +# Make more room in internal RAM on the S2. +CFLAGS += \ + -DCFG_TUD_CDC_RX_BUFSIZE=128 \ + -DCFG_TUD_CDC_TX_BUFSIZE=128 \ + -DCFG_TUD_MSC_BUFSIZE=1024 +else CFLAGS += \ -DCFG_TUD_CDC_RX_BUFSIZE=1024 \ -DCFG_TUD_CDC_TX_BUFSIZE=1024 \ - -DCFG_TUD_MSC_BUFSIZE=4096 \ + -DCFG_TUD_MSC_BUFSIZE=4096 +endif +CFLAGS += \ -DCFG_TUD_MIDI_RX_BUFSIZE=128 \ -DCFG_TUD_MIDI_TX_BUFSIZE=128 \ -DCFG_TUD_VENDOR_RX_BUFSIZE=128 \ @@ -396,11 +613,10 @@ SRC_C += \ boards/$(BOARD)/board.c \ boards/$(BOARD)/pins.c \ shared/netutils/netutils.c \ - peripherals/i2c.c \ peripherals/$(IDF_TARGET)/pins.c ifeq ($(CIRCUITPY_SSL),1) -SRC_C += lib/mbedtls_config/crt_bundle.c +SRC_C += common-hal/ssl/crt_bundle.c endif SRC_C += $(wildcard common-hal/espidf/*.c) @@ -414,14 +630,20 @@ SRC_C += peripherals/touch.c endif ifneq ($(CIRCUITPY_USB_DEVICE),0) -SRC_C += lib/tinyusb/src/portable/espressif/esp32sx/dcd_esp32sx.c +SRC_C += \ + lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c \ + lib/tinyusb/src/portable/synopsys/dwc2/dwc2_common.c endif ifneq ($(CIRCUITPY_AUDIOBUSIO),0) CHIP_COMPONENTS += esp_driver_i2s endif -ifneq ($(CIRCUITPY_BLEIO),0) +ifneq ($(CIRCUITPY_AUDIOI2SIN),0) +CHIP_COMPONENTS += esp_driver_i2s +endif + +ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) SRC_C += common-hal/_bleio/ble_events.c endif @@ -432,6 +654,13 @@ CFLAGS += \ -isystem esp-idf/components/esp_lcd/rgb/include endif +ifneq ($(CIRCUITPY_MIPIDSI),0) +CFLAGS += \ + -isystem esp-idf/components/esp_lcd/include \ + -isystem esp-idf/components/esp_lcd/interface \ + -isystem esp-idf/components/esp_lcd/dsi/include +endif + ifneq ($(CIRCUITPY_ESPCAMERA),0) SRC_CAMERA := \ $(wildcard common-hal/espcamera/*.c) \ @@ -441,6 +670,55 @@ CFLAGS += -isystem esp-camera/driver/include CFLAGS += -isystem esp-camera/conversions/include endif +ifneq ($(CIRCUITPY_RCLCPY),0) +CFLAGS += -isystem microros-lib/include +CFLAGS += -isystem microros-lib/include/rcl +CFLAGS += -isystem microros-lib/include/statistics_msgs +CFLAGS += -isystem microros-lib/include/composition_interfaces +CFLAGS += -isystem microros-lib/include/example_interfaces +CFLAGS += -isystem microros-lib/include/rmw_microxrcedds_c +CFLAGS += -isystem microros-lib/include/test_msgs +CFLAGS += -isystem microros-lib/include/std_msgs +CFLAGS += -isystem microros-lib/include/rcutils +CFLAGS += -isystem microros-lib/include/lifecycle_msgs +CFLAGS += -isystem microros-lib/include/rosidl_typesupport_interface +CFLAGS += -isystem microros-lib/include/service_msgs +CFLAGS += -isystem microros-lib/include/visualization_msgs +CFLAGS += -isystem microros-lib/include/rosidl_dynamic_typesupport +CFLAGS += -isystem microros-lib/include/stereo_msgs +CFLAGS += -isystem microros-lib/include/ucdr +CFLAGS += -isystem microros-lib/include/rosidl_typesupport_c +CFLAGS += -isystem microros-lib/include/std_srvs +CFLAGS += -isystem microros-lib/include/rcl_lifecycle +CFLAGS += -isystem microros-lib/include/action_msgs +CFLAGS += -isystem microros-lib/include/micro_ros_utilities +CFLAGS += -isystem microros-lib/include/rcl_action +CFLAGS += -isystem microros-lib/include/rcl_logging_interface +CFLAGS += -isystem microros-lib/include/type_description_interfaces +CFLAGS += -isystem microros-lib/include/nav_msgs +CFLAGS += -isystem microros-lib/include/actionlib_msgs +CFLAGS += -isystem microros-lib/include/rmw +CFLAGS += -isystem microros-lib/include/rclc_parameter +CFLAGS += -isystem microros-lib/include/geometry_msgs +CFLAGS += -isystem microros-lib/include/sensor_msgs +CFLAGS += -isystem microros-lib/include/trajectory_msgs +CFLAGS += -isystem microros-lib/include/shape_msgs +CFLAGS += -isystem microros-lib/include/rosidl_runtime_c +CFLAGS += -isystem microros-lib/include/rclc +CFLAGS += -isystem microros-lib/include/rosgraph_msgs +CFLAGS += -isystem microros-lib/include/rclc_lifecycle +CFLAGS += -isystem microros-lib/include/rcl_interfaces +CFLAGS += -isystem microros-lib/include/diagnostic_msgs +CFLAGS += -isystem microros-lib/include/micro_ros_msgs +CFLAGS += -isystem microros-lib/include/rosidl_typesupport_introspection_c +CFLAGS += -isystem microros-lib/include/uxr +CFLAGS += -isystem microros-lib/include/unique_identifier_msgs +CFLAGS += -isystem microros-lib/include/rosidl_typesupport_microxrcedds_c +CFLAGS += -isystem microros-lib/include/builtin_interfaces +CFLAGS += -isystem microros-lib/include/tracetools +CFLAGS += -isystem microros-lib/include/rmw_microros +endif + ifneq ($(CIRCUITPY_ESPIDF),0) SRC_ESPIDF := \ $(wildcard common-hal/espidf/*.c) \ @@ -486,29 +764,19 @@ ifneq ($(CIRCUITPY_FREQUENCYIO),0) CHIP_COMPONENTS += esp_driver_pcnt endif -SRC_COMMON_HAL_EXPANDED = \ - $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - -SRC_SHARED_MODULE_EXPANDED = \ - $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - ifneq ($(FROZEN_MPY_DIR),) FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) endif OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os @@ -516,7 +784,7 @@ $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os $(BUILD)/lib/protomatter/src/core.o: CFLAGS += -DESP32 # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) # IDF build commands IDF_PATH = $(realpath ./esp-idf) @@ -527,24 +795,34 @@ $(BUILD)/esp-idf: TARGET_SDKCONFIG = esp-idf-config/sdkconfig-$(IDF_TARGET).defaults +# Choose the correct partition layout, based on UF2 or not, flash size, etc. +UF2_BOOTLOADER ?= $(CIRCUITPY_USB_DEVICE) + ifeq ($(CIRCUITPY_ESP_FLASH_SIZE), 2MB) +# ..... No 2MB UF2 boards, so always no OTA, not UF2 FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-ota-no-uf2.defaults -else -UF2_BOOTLOADER ?= $(CIRCUITPY_USB_DEVICE) -ifeq ($(UF2_BOOTLOADER), 1) - FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE).defaults -else -ifeq ($(CIRCUITPY_ESP_FLASH_SIZE), 4MB) - ifeq ($(CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT), 1) - FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-uf2.defaults +else ifeq ($(CIRCUITPY_ESP_FLASH_SIZE), 4MB) + ifeq ($(UF2_BOOTLOADER), 1) +#............. ESP32-S2 and ESP32-S3 do not have an extra ota partition for OTA update. + FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-ota.defaults else - FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-ota-no-uf2.defaults +# ............. Non-UF2 4MB: C3, C6, etc. + ifeq ($(CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT), 1) +# .................... Some boards use a 2MB firmware and almost 2MB user filesystem, for historical reasons. + FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-ota-no-uf2-large-user_fs.defaults + else + FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-ota-no-uf2.defaults + endif endif else - FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-uf2.defaults -endif -endif +# ..... All the rest are >4MB flash + ifeq ($(UF2_BOOTLOADER), 1) + FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE).defaults + else + FLASH_SIZE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-uf2.defaults + endif endif + FLASH_MODE_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_MODE).defaults FLASH_SPEED_SDKCONFIG ?= esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_FREQ).defaults @@ -561,17 +839,23 @@ else DEBUG_SDKCONFIG = esp-idf-config/sdkconfig-opt.defaults endif -SDKCONFIGS := esp-idf-config/sdkconfig.defaults;$(DEBUG_SDKCONFIG);$(FLASH_SIZE_SDKCONFIG);$(FLASH_MODE_SDKCONFIG);$(FLASH_SPEED_SDKCONFIG);$(PSRAM_SDKCONFIG);$(PSRAM_SIZE_SDKCONFIG);$(PSRAM_MODE_SDKCONFIG);$(PSRAM_SPEED_SDKCONFIG);$(TARGET_SDKCONFIG);boards/$(BOARD)/sdkconfig -ifneq ($(CIRCUITPY_BLEIO),0) - SDKCONFIGS := esp-idf-config/sdkconfig-ble.defaults;$(SDKCONFIGS) +ifeq ($(ENABLE_JTAG), 1) + CFLAGS += -DENABLE_JTAG=1 endif + +ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) + BLE_SDKCONFIG := ;esp-idf-config/sdkconfig-ble.defaults +endif + +SDKCONFIGS := esp-idf-config/sdkconfig.defaults;$(DEBUG_SDKCONFIG);$(FLASH_SIZE_SDKCONFIG);$(FLASH_MODE_SDKCONFIG);$(FLASH_SPEED_SDKCONFIG);$(PSRAM_SDKCONFIG);$(PSRAM_SIZE_SDKCONFIG);$(PSRAM_MODE_SDKCONFIG);$(PSRAM_SPEED_SDKCONFIG);$(BLE_SDKCONFIG);$(TARGET_SDKCONFIG);boards/$(BOARD)/sdkconfig + # create the config headers .PHONY: do-sdkconfig do-sdkconfig: $(BUILD)/esp-idf/config/sdkconfig.h QSTR_GLOBAL_REQUIREMENTS += $(BUILD)/esp-idf/config/sdkconfig.h $(BUILD)/esp-idf/config/sdkconfig.h: boards/$(BOARD)/sdkconfig boards/$(BOARD)/mpconfigboard.mk CMakeLists.txt | $(BUILD)/esp-idf - $(STEPECHO) "LINK $@" - $(Q)env IDF_PATH=$(IDF_PATH) cmake -S . -B $(BUILD)/esp-idf -DSDKCONFIG=$(BUILD)/esp-idf/sdkconfig -DSDKCONFIG_DEFAULTS="$(SDKCONFIGS)" -DCMAKE_TOOLCHAIN_FILE=$(IDF_PATH)/tools/cmake/toolchain-$(IDF_TARGET).cmake -DIDF_TARGET=$(IDF_TARGET) -GNinja + $(STEPECHO) "Create $@" + $(Q)env IDF_PATH=$(IDF_PATH) IDF_COMPONENT_MANAGER=0 cmake -S . -B $(BUILD)/esp-idf -DSDKCONFIG=$(BUILD)/esp-idf/sdkconfig -DSDKCONFIG_DEFAULTS="$(SDKCONFIGS)" -DCMAKE_TOOLCHAIN_FILE=$(IDF_PATH)/tools/cmake/toolchain-$(IDF_TARGET).cmake -DIDF_TARGET=$(IDF_TARGET) -GNinja $(Q)$(PYTHON) tools/check-sdkconfig.py \ CIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK) \ CIRCUITPY_STORAGE_EXTEND=$(CIRCUITPY_STORAGE_EXTEND) \ @@ -608,7 +892,8 @@ ifneq ($(IDF_TARGET),esp32p4) BINARY_BLOBS = esp-idf/components/esp_phy/lib/$(IDF_TARGET)/libphy.a endif ifneq ($(CIRCUITPY_WIFI),0) - BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, $(BINARY_WIFI_BLOBS)) + BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, $(BINARY_WIFI_BLOBS)) + BINARY_BLOBS += esp-idf/components/esp_coex/lib/$(IDF_TARGET)/libcoexist.a ifneq ($(IDF_TARGET),esp32c2) BINARY_BLOBS += $(addprefix esp-idf/components/esp_wifi/lib/$(IDF_TARGET)/, libmesh.a libwapi.a) endif @@ -618,23 +903,24 @@ ifeq ($(IDF_TARGET),esp32) BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/librtc.a endif -ESP_IDF_COMPONENTS_LINK = $(IDF_TARGET_ARCH) $(CHIP_COMPONENTS) app_update bootloader_support driver esp_driver_gpio esp_driver_gptimer esp_driver_ledc esp_driver_spi esp_driver_uart efuse esp_adc esp_app_format esp_common esp_event esp_hw_support esp_mm esp_partition esp_pm esp_ringbuf esp_rom esp_system esp_timer freertos hal heap log newlib nvs_flash pthread soc spi_flash vfs esp_vfs_console +ESP_IDF_COMPONENTS_LINK = $(IDF_TARGET_ARCH) $(CHIP_COMPONENTS) app_update bootloader_support driver esp_driver_dma esp_driver_gpio esp_driver_gptimer esp_driver_i2c esp_driver_ledc esp_driver_spi esp_driver_uart efuse esp_adc esp_app_format esp_common esp_event esp_gdbstub esp_hal_ana_conv esp_hal_clock esp_hal_gpio esp_hal_gpspi esp_hal_i2c esp_hal_ledc esp_hal_mspi esp_hal_security esp_hal_timg esp_hal_uart esp_hal_wdt esp_hw_support esp_mm esp_partition esp_pm esp_ringbuf esp_rom esp_system esp_timer freertos hal heap log esp_libc nvs_flash nvs_sec_provider pthread soc spi_flash vfs esp_stdio ifneq ($(CIRCUITPY_WIFI),0) - ESP_IDF_COMPONENTS_LINK += esp_coex esp_netif esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy + ESP_IDF_COMPONENTS_LINK += esp_coex esp_netif esp_security esp-tls esp_wifi lwip mbedtls mdns wpa_supplicant esp_phy endif -ifneq ($(CIRCUITPY_BLEIO),0) +ifneq ($(CIRCUITPY_BLEIO_NATIVE),0) BLE_IMPL_esp32 := esp32 BLE_IMPL_esp32s3 := esp32c3 BLE_IMPL_esp32c2 := libble BLE_IMPL_esp32c3 := esp32c3 BLE_IMPL_esp32c6 := libble + BLE_IMPL_esp32c61 := libble BLE_IMPL_esp32h2 := libble BLE_IMPL = $(BLE_IMPL_$(IDF_TARGET)) - ESP_IDF_COMPONENTS_LINK += bt esp_phy + ESP_IDF_COMPONENTS_LINK += bt esp_phy esp_security ifeq ($(BLE_IMPL),esp32) - # BLE will hang the ESP32 and trigger an interrupt watchdog without this undefined symbol at - # link because a weak version of the interrupt that BLE uses will be linked incorrectly. +# BLE will hang the ESP32 and trigger an interrupt watchdog without this undefined symbol at +# link because a weak version of the interrupt that BLE uses will be linked incorrectly. REGISTRATION_FUNCTIONS += -u ld_include_hli_vectors_bt BINARY_BLOBS += esp-idf/components/bt/controller/lib_esp32/$(IDF_TARGET)/libbtdm_app.a endif @@ -645,10 +931,17 @@ ifneq ($(CIRCUITPY_BLEIO),0) endif ifeq ($(BLE_IMPL),libble) - BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/libbtbb.a \ - esp-idf/components/bt/controller/lib_$(IDF_TARGET)/$(IDF_TARGET)-bt-lib/libble_app.a + BINARY_BLOBS += esp-idf/components/esp_phy/lib/$(IDF_TARGET)/libbtbb.a + ifeq ($(BT_IDF_TARGET),esp32c6) + BINARY_BLOBS += esp-idf/components/bt/controller/lib_$(BT_IDF_TARGET)/$(BT_IDF_TARGET)-bt-lib/$(IDF_TARGET)/libble_app.a + else + BINARY_BLOBS += esp-idf/components/bt/controller/lib_$(IDF_TARGET)/$(IDF_TARGET)-bt-lib/libble_app.a + endif endif endif +ifeq ($(IDF_TARGET),esp32p4) + ESP_IDF_COMPONENTS_LINK += esp_security +endif ifneq ($(CIRCUITPY_ESPULP),0) ESP_IDF_COMPONENTS_LINK += ulp endif @@ -658,20 +951,27 @@ endif ifneq ($(CIRCUITPY_DOTCLOCKFRAMEBUFFER),0) ESP_IDF_COMPONENTS_LINK += esp_lcd endif +ifneq ($(CIRCUITPY_MIPIDSI),0) + ESP_IDF_COMPONENTS_LINK += esp_lcd +endif ifneq ($(CIRCUITPY_PARALLELDISPLAYBUS),0) ESP_IDF_COMPONENTS_LINK += esp_lcd endif -ifneq ($(CIRCUITPY_USB_DEVICE),0) - ESP_IDF_COMPONENTS_LINK += usb +ifneq ($(CIRCUITPY_QSPIBUS),0) + ESP_IDF_COMPONENTS_LINK += esp_lcd endif ifneq ($(CIRCUITPY_SDIOIO),0) - ESP_IDF_COMPONENTS_LINK += sdmmc esp_driver_sdmmc + ESP_IDF_COMPONENTS_LINK += sdmmc esp_driver_sdmmc esp_driver_sd_intf esp_hal_sd endif ESP_IDF_COMPONENTS_EXPANDED = $(foreach component, $(ESP_IDF_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/$(component)/lib$(component).a) MBEDTLS_COMPONENTS_LINK = crypto tls x509 MBEDTLS_COMPONENTS_LINK_EXPANDED = $(foreach component, $(MBEDTLS_COMPONENTS_LINK), $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/library/libmbed$(component).a) +MBEDTLS_COMPONENTS_LINK_EXPANDED += $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/library/libtfpsacrypto.a +MBEDTLS_COMPONENTS_LINK_EXPANDED += $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/tf-psa-crypto/drivers/builtin/libmbed-builtin.a +MBEDTLS_COMPONENTS_LINK_EXPANDED += $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/tf-psa-crypto/drivers/everest/libeverest.a +MBEDTLS_COMPONENTS_LINK_EXPANDED += $(BUILD)/esp-idf/esp-idf/mbedtls/mbedtls/tf-psa-crypto/drivers/p256-m/libp256m.a ifeq ($(IDF_TARGET_ARCH),xtensa) BINARY_BLOBS += esp-idf/components/xtensa/$(IDF_TARGET)/libxt_hal.a @@ -683,6 +983,18 @@ ESP_IDF_COMPONENTS_EXPANDED += $(BUILD)/esp-idf/esp-idf/esp-camera/libesp-camera #$(error $(ESP_IDF_COMPONENTS_EXPANDED)) endif +ifneq ($(CIRCUITPY_RCLCPY),0) + ifeq ($(IDF_TARGET),esp32) + BINARY_BLOBS += microros-lib/esp32/libmicroros.a + else ifeq ($(IDF_TARGET),esp32s2) + BINARY_BLOBS+= microros-lib/esp32s2/libmicroros.a + else ifeq ($(IDF_TARGET),esp32s3) + BINARY_BLOBS += microros-lib/esp32s3/libmicroros.a + else + $(error Unsupported Espressif target for Micro-ROS: $(IDF_TARGET).) + endif +endif + ifneq ($(VALID_BOARD),) # From esp-idf/components/bootloader/Kconfig.projbuild # BOOTLOADER_OFFSET is determined by chip type, based on the ROM bootloader, and is not changeable. @@ -696,6 +1008,8 @@ else ifeq ($(IDF_TARGET),esp32c3) BOOTLOADER_OFFSET = 0x0 else ifeq ($(IDF_TARGET),esp32c6) BOOTLOADER_OFFSET = 0x0 +else ifeq ($(IDF_TARGET),esp32c61) +BOOTLOADER_OFFSET = 0x0 else ifeq ($(IDF_TARGET),esp32p4) BOOTLOADER_OFFSET = 0x2000 else ifeq ($(IDF_TARGET),esp32s3) @@ -709,7 +1023,7 @@ endif IDF_CMAKE_TARGETS = \ bootloader/bootloader.bin \ - esp-idf/esp_system/__ldgen_output_sections.ld \ + __ldgen_output_sections.ld \ $(foreach component, $(ESP_IDF_COMPONENTS_LINK), esp-idf/$(component)/lib$(component).a) PARTITION_TABLE_OFFSET = 0x8000 @@ -734,9 +1048,9 @@ else ESPTOOLPY_FLASHFREQ = $(CIRCUITPY_ESP_FLASH_FREQ) endif -FLASH_FLAGS = --flash_mode $(ESPTOOLPY_FLASHMODE) --flash_freq $(ESPTOOLPY_FLASHFREQ) --flash_size $(CIRCUITPY_ESP_FLASH_SIZE) +FLASH_FLAGS = --flash-mode $(ESPTOOLPY_FLASHMODE) --flash-freq $(ESPTOOLPY_FLASHFREQ) --flash-size $(CIRCUITPY_ESP_FLASH_SIZE) -ESPTOOL_FLAGS ?= --before=default_reset --after=no_reset --baud 921600 +ESPTOOL_FLAGS ?= --before=default-reset --after=no-reset --baud 921600 ifeq ($(UF2_BOOTLOADER),1) all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 @@ -756,7 +1070,7 @@ $(BUILD)/firmware.elf: $(OBJ) | esp-idf-stamp $(IDF_CMAKE_TARGETS) $(BUILD)/circuitpython-firmware.bin: $(BUILD)/firmware.elf | tools/build_memory_info.py $(STEPECHO) "Create $@" - $(Q)esptool.py --chip $(IDF_TARGET) elf2image $(FLASH_FLAGS) --elf-sha256-offset 0xb0 -o $@ $^ + $(Q)esptool --chip $(IDF_TARGET) elf2image $(FLASH_FLAGS) --elf-sha256-offset 0xb0 -o $@ $^ $(Q)$(PYTHON) tools/build_memory_info.py $< $(BUILD)/esp-idf/sdkconfig $@ $(BUILD) ifeq ($(VALID_BOARD),) @@ -768,16 +1082,17 @@ endif UF2_FAMILY_ID_esp32s2 = 0xbfdd4eee UF2_FAMILY_ID_esp32s3 = 0xc47e5767 +UF2_FAMILY_ID_esp32p4 = 0x540ddf62 $(BUILD)/firmware.uf2: $(BUILD)/circuitpython-firmware.bin $(STEPECHO) "Create $@" $(Q)$(PYTHON) $(TOP)/tools/uf2/utils/uf2conv.py -f $(UF2_FAMILY_ID_$(IDF_TARGET)) -b 0x0000 -c -o $@ $^ flash: $(BUILD)/firmware.bin - esptool.py --chip $(IDF_TARGET) -p $(PORT) $(ESPTOOL_FLAGS) write_flash $(FLASH_FLAGS) 0x0000 $^ + esptool --chip $(IDF_TARGET) -p $(PORT) $(ESPTOOL_FLAGS) write-flash $(FLASH_FLAGS) 0x0000 $^ flash-circuitpython-only: $(BUILD)/circuitpython-firmware.bin - esptool.py --chip $(IDF_TARGET) -p $(PORT) $(ESPTOOL_FLAGS) write_flash $(FLASH_FLAGS) $(FIRMWARE_OFFSET) $^ + esptool --chip $(IDF_TARGET) -p $(PORT) $(ESPTOOL_FLAGS) write-flash $(FLASH_FLAGS) $(FIRMWARE_OFFSET) $^ monitor: $(BUILD)/firmware.elf cp $< build/circuitpython.elf diff --git a/ports/espressif/README.rst b/ports/espressif/README.rst index 63174fd1670..5af91591f7e 100644 --- a/ports/espressif/README.rst +++ b/ports/espressif/README.rst @@ -41,7 +41,7 @@ Connecting to the ESP32-C3 **USB Connection:** -On ESP32-C3 REV3 chips, a USB Serial/JTAG Controller is available. Note: This USB connection cannot be used for a ``CIRCUITPY`` drive. +On ESP32-C3 REV3 chips, a USB Serial/JTAG Controller is available. Note: This USB connection cannot be used for a **CIRCUITPY** drive. Depending on the board you have, the USB port may or may not be connected to native USB. @@ -222,4 +222,3 @@ And follow the Espressif GDB tutorial `instructions for connecting None: //| """Deinitialises the camera and releases all memory resources for reuse.""" //| ... +//| static mp_obj_t espcamera_camera_deinit(mp_obj_t self_in) { espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_espcamera_camera_deinit(self); @@ -159,25 +162,24 @@ static void check_for_deinit(espcamera_camera_obj_t *self) { //| def __enter__(self) -> Camera: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t espcamera_camera_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - return espcamera_camera_deinit(args[0]); -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espcamera_camera___exit___obj, 4, 4, espcamera_camera_obj___exit__); +//| +// Provided by context manager helper. //| frame_available: bool //| """True if a frame is available, False otherwise""" +//| static mp_obj_t espcamera_camera_frame_available_get(const mp_obj_t self_in) { espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - return mp_obj_new_bool(esp_camera_fb_available()); + return mp_obj_new_bool(common_hal_espcamera_camera_available(self)); } static MP_DEFINE_CONST_FUN_OBJ_1(espcamera_camera_frame_available_get_obj, espcamera_camera_frame_available_get); @@ -193,6 +195,7 @@ MP_PROPERTY_GETTER(espcamera_camera_frame_available_obj, //| If `pixel_format` is `PixelFormat.JPEG`, the returned value is a read-only `memoryview`. //| Otherwise, the returned value is a read-only `displayio.Bitmap`. //| """ +//| static mp_obj_t espcamera_camera_take(size_t n_args, const mp_obj_t *args) { espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_float_t timeout = n_args < 2 ? MICROPY_FLOAT_CONST(0.25) : mp_obj_get_float(args[1]); @@ -229,6 +232,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espcamera_camera_take_obj, 1, 2, espc //| the other properties to set, they are set together in a single function call. //| //| If an argument is unspecified or None, then the setting is unchanged.""" +//| static mp_obj_t espcamera_camera_reconfigure(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -257,7 +261,7 @@ static mp_obj_t espcamera_camera_reconfigure(mp_uint_t n_args, const mp_obj_t *p args[ARG_grab_mode].u_obj != MP_ROM_NONE ? validate_grab_mode(args[ARG_grab_mode].u_obj, MP_QSTR_grab_mode) : common_hal_espcamera_camera_get_grab_mode(self); - bool framebuffer_count = + mp_int_t framebuffer_count = args[ARG_framebuffer_count].u_obj != MP_ROM_NONE ? mp_obj_get_int(args[ARG_framebuffer_count].u_obj) : common_hal_espcamera_camera_get_framebuffer_count(self); @@ -912,6 +916,7 @@ MP_PROPERTY_GETTER(espcamera_camera_grab_mode_obj, //| framebuffer_count: int //| """True if double buffering is used""" //| +//| static mp_obj_t espcamera_camera_get_framebuffer_count(const mp_obj_t self_in) { espcamera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -939,8 +944,8 @@ static const mp_rom_map_elem_t espcamera_camera_locals_table[] = { { MP_ROM_QSTR(MP_QSTR_denoise), MP_ROM_PTR(&espcamera_camera_denoise_obj) }, { MP_ROM_QSTR(MP_QSTR_framebuffer_count), MP_ROM_PTR(&espcamera_camera_framebuffer_count_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&espcamera_camera_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espcamera_camera___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_exposure_ctrl), MP_ROM_PTR(&espcamera_camera_exposure_ctrl_obj) }, { MP_ROM_QSTR(MP_QSTR_frame_available), MP_ROM_PTR(&espcamera_camera_frame_available_obj) }, { MP_ROM_QSTR(MP_QSTR_frame_size), MP_ROM_PTR(&espcamera_camera_frame_size_obj) }, diff --git a/ports/espressif/bindings/espcamera/__init__.c b/ports/espressif/bindings/espcamera/__init__.c index 3443ccee42b..dbdb0ffb481 100644 --- a/ports/espressif/bindings/espcamera/__init__.c +++ b/ports/espressif/bindings/espcamera/__init__.c @@ -26,6 +26,7 @@ //| //| """ //| +//| //| class GrabMode: //| """Controls when a new frame is grabbed.""" @@ -36,6 +37,7 @@ //| LATEST: GrabMode //| """Except when 1 frame buffer is used, queue will always contain the last ``fb_count`` frames""" //| +//| MAKE_ENUM_VALUE(espcamera_grab_mode_type, grab_mode, WHEN_EMPTY, CAMERA_GRAB_WHEN_EMPTY); MAKE_ENUM_VALUE(espcamera_grab_mode_type, grab_mode, LATEST, CAMERA_GRAB_LATEST); @@ -65,6 +67,7 @@ camera_grab_mode_t validate_grab_mode(mp_obj_t obj, qstr arg_name) { //| JPEG: PixelFormat //| """A compressed format""" //| +//| MAKE_ENUM_VALUE(espcamera_pixel_format_type, pixel_format, RGB565, PIXFORMAT_RGB565); MAKE_ENUM_VALUE(espcamera_pixel_format_type, pixel_format, GRAYSCALE, PIXFORMAT_GRAYSCALE); @@ -153,6 +156,7 @@ pixformat_t validate_pixel_format(mp_obj_t obj, qstr arg_name) { //| QSXGA: FrameSize //| """2560x1920""" //| +//| MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, R96X96, FRAMESIZE_96X96); MAKE_ENUM_VALUE(espcamera_frame_size_type, frame_size, R240X240, FRAMESIZE_240X240); @@ -222,6 +226,7 @@ framesize_t validate_frame_size(mp_obj_t obj, qstr arg_name) { //| GAIN_64X: GainCeiling //| GAIN_128X: GainCeiling //| +//| MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_2X, GAINCEILING_2X); MAKE_ENUM_VALUE(espcamera_gain_ceiling_type, gain_ceiling, GAIN_4X, GAINCEILING_4X); diff --git a/ports/espressif/bindings/espidf/__init__.c b/ports/espressif/bindings/espidf/__init__.c index 3d6321017f2..897da0eb571 100644 --- a/ports/espressif/bindings/espidf/__init__.c +++ b/ports/espressif/bindings/espidf/__init__.c @@ -20,11 +20,13 @@ //| that could be implemented by other frameworks. It should only include ESP-IDF specific //| things.""" //| +//| //| def heap_caps_get_total_size() -> int: //| """Return the total size of the ESP-IDF, which includes the CircuitPython heap.""" //| ... //| +//| static mp_obj_t espidf_heap_caps_get_total_size(void) { return MP_OBJ_NEW_SMALL_INT(heap_caps_get_total_size(MALLOC_CAP_8BIT)); @@ -35,6 +37,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_total_size_obj, espidf_heap_caps_ //| """Return total free memory in the ESP-IDF heap.""" //| ... //| +//| static mp_obj_t espidf_heap_caps_get_free_size(void) { return MP_OBJ_NEW_SMALL_INT(heap_caps_get_free_size(MALLOC_CAP_8BIT)); @@ -45,6 +48,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_free_size_obj, espidf_heap_caps_g //| """Return the size of largest free memory block in the ESP-IDF heap.""" //| ... //| +//| static mp_obj_t espidf_heap_caps_get_largest_free_block(void) { return MP_OBJ_NEW_SMALL_INT(heap_caps_get_largest_free_block(MALLOC_CAP_8BIT)); @@ -58,6 +62,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(espidf_heap_caps_get_largest_free_block_obj, espidf_he //| layout of data in nvs has changed. The old data will be lost when you perform this operation. //| """ //| +//| static mp_obj_t espidf_erase_nvs(void) { ESP_ERROR_CHECK(nvs_flash_deinit()); ESP_ERROR_CHECK(nvs_flash_erase()); @@ -84,6 +89,7 @@ static void espidf_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_pr //| //| ... //| +//| MP_DEFINE_CONST_OBJ_TYPE( mp_type_espidf_IDFError, MP_QSTR_IDFError, @@ -99,7 +105,8 @@ MP_DEFINE_CONST_OBJ_TYPE( //| //| ... //| -NORETURN void mp_raise_espidf_MemoryError(void) { +//| +MP_NORETURN void mp_raise_espidf_MemoryError(void) { nlr_raise(mp_obj_new_exception(&mp_type_espidf_MemoryError)); } @@ -116,6 +123,7 @@ MP_DEFINE_CONST_OBJ_TYPE( //| def get_total_psram() -> int: //| """Returns the number of bytes of psram detected, or 0 if psram is not present or not configured""" //| +//| static mp_obj_t espidf_get_total_psram(void) { return MP_OBJ_NEW_SMALL_INT(common_hal_espidf_get_total_psram()); } diff --git a/ports/espressif/bindings/espidf/__init__.h b/ports/espressif/bindings/espidf/__init__.h index 7c112abf736..92d2e0c2769 100644 --- a/ports/espressif/bindings/espidf/__init__.h +++ b/ports/espressif/bindings/espidf/__init__.h @@ -15,9 +15,9 @@ extern const mp_obj_type_t mp_type_espidf_IDFError; extern const mp_obj_type_t mp_type_espidf_MemoryError; -NORETURN void mp_raise_espidf_MemoryError(void); +MP_NORETURN void mp_raise_espidf_MemoryError(void); -void raise_esp_error(esp_err_t err) NORETURN; +void raise_esp_error(esp_err_t err) MP_NORETURN; #define CHECK_ESP_RESULT(x) do { int res = (x); if (res != ESP_OK) raise_esp_error(res); } while (0) size_t common_hal_espidf_get_total_psram(void); diff --git a/ports/espressif/bindings/espnow/ESPNow.c b/ports/espressif/bindings/espnow/ESPNow.c index 80dfac93c12..345d51b6dff 100644 --- a/ports/espressif/bindings/espnow/ESPNow.c +++ b/ports/espressif/bindings/espnow/ESPNow.c @@ -12,6 +12,7 @@ #include "py/stream.h" #include "shared-bindings/util.h" +#include "shared/runtime/context_manager_helpers.h" #include "bindings/espnow/ESPNow.h" #include "bindings/espnow/Peer.h" @@ -39,8 +40,11 @@ static void espnow_check_for_deinit(espnow_obj_t *self) { //| :param int buffer_size: The size of the internal ring buffer. Default: 526 bytes. //| :param int phy_rate: The ESP-NOW physical layer rate. Default: 1 Mbps. //| `wifi_phy_rate_t `_ +//| +//| **Limitations:** Currently, setting ``phy_rate`` does nothing. The rate is always 1 Mbps. //| """ //| ... +//| static mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_buffer_size, ARG_phy_rate }; static const mp_arg_t allowed_args[] = { @@ -71,6 +75,7 @@ static mp_obj_t espnow_make_new(const mp_obj_type_t *type, size_t n_args, size_t //| def deinit(self) -> None: //| """Deinitializes ESP-NOW and releases it for another program.""" //| ... +//| static mp_obj_t espnow_deinit(mp_obj_t self_in) { espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); espnow_check_for_deinit(self); @@ -82,17 +87,15 @@ static MP_DEFINE_CONST_FUN_OBJ_1(espnow_deinit_obj, espnow_deinit); //| def __enter__(self) -> ESPNow: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t espnow_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - return espnow_deinit(args[0]); -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow___exit___obj, 4, 4, espnow_obj___exit__); +//| +// Provided by context manager helper. // --- Send and Read messages --- @@ -109,6 +112,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espnow___exit___obj, 4, 4, espnow_obj //| :param Peer peer: Send message to this peer. If `None`, send to all registered peers. //| """ //| ... +//| static mp_obj_t espnow_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_message, ARG_peer }; static const mp_arg_t allowed_args[] = { @@ -143,6 +147,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(espnow_send_obj, 2, espnow_send); //| //| :returns: An `ESPNowPacket` if available in the buffer, otherwise `None`.""" //| ... +//| static mp_obj_t espnow_read(mp_obj_t self_in) { espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); espnow_check_for_deinit(self); @@ -204,6 +209,7 @@ MP_PROPERTY_GETTER(espnow_read_failure_obj, //| //| :param ReadableBuffer pmk: The ESP-NOW Primary Master Key (length = 16 bytes).""" //| ... +//| static mp_obj_t espnow_set_pmk(mp_obj_t self_in, mp_obj_t key) { espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); espnow_check_for_deinit(self); @@ -227,6 +233,8 @@ MP_PROPERTY_GETTER(espnow_buffer_size_obj, //| phy_rate: int //| """The ESP-NOW physical layer rate. //| `wifi_phy_rate_t `_ +//| +//| **Limitations:** Currently, setting ``phy_rate`` does nothing. The rate is always 1 Mbps. //| """ //| static mp_obj_t espnow_get_phy_rate(const mp_obj_t self_in) { @@ -263,8 +271,8 @@ MP_PROPERTY_GETTER(espnow_peers_obj, static const mp_rom_map_elem_t espnow_locals_dict_table[] = { // Context managers - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espnow___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Deinit the object { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espnow_deinit_obj) }, @@ -325,6 +333,7 @@ static const mp_stream_p_t espnow_stream_p = { //| """Return the number of `bytes` available to read. Used to implement ``len()``.""" //| ... //| +//| static mp_obj_t espnow_unary_op(mp_unary_op_t op, mp_obj_t self_in) { espnow_obj_t *self = MP_OBJ_TO_PTR(self_in); espnow_check_for_deinit(self); diff --git a/ports/espressif/bindings/espnow/ESPNowPacket.c b/ports/espressif/bindings/espnow/ESPNowPacket.c index c53ed9dc77c..3d85c88fc44 100644 --- a/ports/espressif/bindings/espnow/ESPNowPacket.c +++ b/ports/espressif/bindings/espnow/ESPNowPacket.c @@ -21,6 +21,7 @@ //| time: int //| """The time in milliseconds since the device last booted when the packet was received.""" //| +//| const mp_obj_namedtuple_type_t espnow_packet_type_obj = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_ESPNowPacket), diff --git a/ports/espressif/bindings/espnow/Peer.c b/ports/espressif/bindings/espnow/Peer.c index 70600a4fb1d..3e731849144 100644 --- a/ports/espressif/bindings/espnow/Peer.c +++ b/ports/espressif/bindings/espnow/Peer.c @@ -32,6 +32,7 @@ //| :param bool encrypted: Whether or not to use encryption. //| """ //| ... +//| static mp_obj_t espnow_peer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_mac, ARG_lmk, ARG_channel, ARG_interface, ARG_encrypted }; static const mp_arg_t allowed_args[] = { @@ -167,6 +168,7 @@ MP_PROPERTY_GETSET(espnow_peer_interface_obj, //| encrypted: bool //| """Whether or not to use encryption.""" //| +//| static mp_obj_t espnow_peer_get_encrypted(const mp_obj_t self_in) { espnow_peer_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(self->peer_info.encrypt); diff --git a/ports/espressif/bindings/espnow/Peers.c b/ports/espressif/bindings/espnow/Peers.c index 2f168768c91..57ab2d5f6c6 100644 --- a/ports/espressif/bindings/espnow/Peers.c +++ b/ports/espressif/bindings/espnow/Peers.c @@ -21,6 +21,7 @@ //| def __init__(self) -> None: //| """You cannot create an instance of `Peers`.""" //| ... +//| //| def append(self, peer: Peer) -> None: //| """Append peer. @@ -28,6 +29,7 @@ //| :param Peer peer: The peer object to append. //| """ //| ... +//| static mp_obj_t espnow_peers_append(mp_obj_t self_in, mp_obj_t arg) { espnow_peer_obj_t *peer = MP_OBJ_TO_PTR(mp_arg_validate_type(arg, &espnow_peer_type, MP_QSTR_Peer)); CHECK_ESP_RESULT(esp_now_add_peer(&peer->peer_info)); @@ -43,6 +45,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(espnow_peers_append_obj, espnow_peers_append); //| """ //| ... //| +//| static mp_obj_t espnow_peers_remove(mp_obj_t self_in, mp_obj_t arg) { espnow_peer_obj_t *peer = MP_OBJ_TO_PTR(mp_arg_validate_type(arg, &espnow_peer_type, MP_QSTR_Peer)); CHECK_ESP_RESULT(esp_now_del_peer(peer->peer_info.peer_addr)); diff --git a/ports/espressif/bindings/espnow/__init__.c b/ports/espressif/bindings/espnow/__init__.c index 79bc0b0f3a6..6415bf0d1e6 100644 --- a/ports/espressif/bindings/espnow/__init__.c +++ b/ports/espressif/bindings/espnow/__init__.c @@ -51,6 +51,7 @@ //| for packet in packets: //| print(packet) //| """ +//| //| ... //| diff --git a/ports/espressif/bindings/espulp/Architecture.c b/ports/espressif/bindings/espulp/Architecture.c index ee45035e89d..bcf094e7e11 100644 --- a/ports/espressif/bindings/espulp/Architecture.c +++ b/ports/espressif/bindings/espulp/Architecture.c @@ -20,6 +20,7 @@ MAKE_ENUM_VALUE(espulp_architecture_type, architecture, RISCV, RISCV); //| RISCV: Architecture //| """The ULP RISC-V Coprocessor.""" //| +//| MAKE_ENUM_MAP(espulp_architecture) { MAKE_ENUM_MAP_ENTRY(architecture, FSM), MAKE_ENUM_MAP_ENTRY(architecture, RISCV), diff --git a/ports/espressif/bindings/espulp/ULP.c b/ports/espressif/bindings/espulp/ULP.c index fb7c84495e5..294678cb1da 100644 --- a/ports/espressif/bindings/espulp/ULP.c +++ b/ports/espressif/bindings/espulp/ULP.c @@ -6,6 +6,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" +#include "shared/runtime/context_manager_helpers.h" #include "bindings/espulp/ULP.h" #include "py/enum.h" @@ -22,6 +23,7 @@ //| :param Architecture arch: The ulp arch. //| """ //| ... +//| static mp_obj_t espulp_ulp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_arch }; static const mp_arg_t allowed_args[] = { @@ -49,6 +51,7 @@ static void check_for_deinit(espulp_ulp_obj_t *self) { //| def deinit(self) -> None: //| """Deinitialises the ULP and releases it for another program.""" //| ... +//| static mp_obj_t espulp_ulp_deinit(mp_obj_t self_in) { espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_espulp_ulp_deinit(self); @@ -59,17 +62,15 @@ static MP_DEFINE_CONST_FUN_OBJ_1(espulp_ulp_deinit_obj, espulp_ulp_deinit); //| def __enter__(self) -> ULP: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t espulp_ulp_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - return espulp_ulp_deinit(args[0]); -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espulp_ulp___exit___obj, 4, 4, espulp_ulp_obj___exit__); +//| +// Provided by context manager helper. //| def set_wakeup_period(self, period_index: int, period_us: int) -> None: //| """Sets the wakeup period for the ULP. @@ -79,6 +80,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(espulp_ulp___exit___obj, 4, 4, espulp //| By default, the value stored in period index 0 is used. //| :param int period_us: The wakeup period given in microseconds.""" //| ... +//| static mp_obj_t espulp_ulp_set_wakeup_period(mp_obj_t self_in, mp_obj_t period_index, mp_obj_t period_us) { espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -95,7 +97,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(espulp_ulp_set_wakeup_period_obj, espulp_ulp_se //| program: ReadableBuffer, //| *, //| entrypoint: int = 0, -//| pins: Sequence[microcontroller.Pin] = () +//| pins: Sequence[microcontroller.Pin] = (), //| ) -> None: //| """Loads the program into ULP memory and then runs the program. //| @@ -107,6 +109,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(espulp_ulp_set_wakeup_period_obj, espulp_ulp_se //| :param Sequence[microcontroller.Pin] pins: Pins made available to the ULP. //| The pins are claimed and not reset until `halt()` is called.""" //| ... +//| static mp_obj_t espulp_ulp_run(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); @@ -155,6 +158,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(espulp_ulp_run_obj, 2, espulp_ulp_run); //| Note: for the FSM ULP, a running ULP program is not actually interrupted. //| Instead, only the wakeup timer is stopped.""" //| ... +//| static mp_obj_t espulp_ulp_halt(mp_obj_t self_in) { espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -167,6 +171,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(espulp_ulp_halt_obj, espulp_ulp_halt); //| arch: Architecture //| """The ulp architecture. (read-only)""" //| +//| static mp_obj_t espulp_ulp_get_arch(mp_obj_t self_in) { espulp_ulp_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -180,8 +185,8 @@ MP_PROPERTY_GETTER(espulp_ulp_arch_obj, static const mp_rom_map_elem_t espulp_ulp_locals_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&espulp_ulp_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&espulp_ulp___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_set_wakeup_period), MP_ROM_PTR(&espulp_ulp_set_wakeup_period_obj) }, { MP_ROM_QSTR(MP_QSTR_run), MP_ROM_PTR(&espulp_ulp_run_obj) }, { MP_ROM_QSTR(MP_QSTR_halt), MP_ROM_PTR(&espulp_ulp_halt_obj) }, diff --git a/ports/espressif/bindings/espulp/ULPAlarm.c b/ports/espressif/bindings/espulp/ULPAlarm.c index edff8e44b8e..6c31137f9ae 100644 --- a/ports/espressif/bindings/espulp/ULPAlarm.c +++ b/ports/espressif/bindings/espulp/ULPAlarm.c @@ -20,6 +20,7 @@ //| :param ULP ulp: The ulp instance""" //| ... //| +//| static mp_obj_t espulp_ulpalarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_ulp }; static const mp_arg_t allowed_args[] = { diff --git a/ports/espressif/bindings/espulp/__init__.c b/ports/espressif/bindings/espulp/__init__.c index 59a3519868c..9808ab55f42 100644 --- a/ports/espressif/bindings/espulp/__init__.c +++ b/ports/espressif/bindings/espulp/__init__.c @@ -33,14 +33,17 @@ //| print(shared_mem[0]) //| # ulp.halt() //| """ +//| //| ... //| +//| //| def get_rtc_gpio_number(pin: microcontroller.Pin) -> Optional[int]: //| """Return the RTC GPIO number of the given pin or None if not connected //| to RTC GPIO.""" //| ... //| +//| static mp_obj_t espulp_get_rtc_gpio_number(mp_obj_t pin_obj) { const mcu_pin_obj_t *pin = validate_obj_is_pin(pin_obj, MP_QSTR_pin); diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.h b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.h index bc02e85367b..2fb1696000c 100644 --- a/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.h +++ b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.h @@ -18,3 +18,6 @@ // For entering safe mode #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (11.0) diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.mk b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.mk index f0067c0d22b..ad0e985cd6f 100644 --- a/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.mk +++ b/ports/espressif/boards/01space_lcd042_esp32c3/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/01space_lcd042_esp32c3/sdkconfig b/ports/espressif/boards/01space_lcd042_esp32c3/sdkconfig index 3a08db70d5f..e9628662160 100644 --- a/ports/espressif/boards/01space_lcd042_esp32c3/sdkconfig +++ b/ports/espressif/boards/01space_lcd042_esp32c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="01Space-LCD042-ESP32C3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_esp32s3_camera/board.c b/ports/espressif/boards/adafruit_esp32s3_camera/board.c index 027b7ca8b6e..d8b0832d3d0 100644 --- a/ports/espressif/boards/adafruit_esp32s3_camera/board.c +++ b/ports/espressif/boards/adafruit_esp32s3_camera/board.c @@ -16,7 +16,6 @@ #include "esp_log.h" #include "esp_err.h" -#include "driver/i2c.h" #define DELAY 0x80 @@ -38,9 +37,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO40, // TFT_DC Command or data - &pin_GPIO39, // TFT_CS Chip select - &pin_GPIO38, // TFT_RESET Reset + MP_OBJ_FROM_PTR(&pin_GPIO40), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO39), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO38), // TFT_RESET Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/adafruit_esp32s3_camera/mpconfigboard.mk b/ports/espressif/boards/adafruit_esp32s3_camera/mpconfigboard.mk index 9f8acf042f6..62b6d3612b3 100644 --- a/ports/espressif/boards/adafruit_esp32s3_camera/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_esp32s3_camera/mpconfigboard.mk @@ -13,13 +13,12 @@ CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m -# No OTA partition: larger firmware partition -FLASH_SIZE_SDKCONFIG = esp-idf-config/sdkconfig-flash-$(CIRCUITPY_ESP_FLASH_SIZE)-no-ota.defaults +CIRCUITPY_ESPCAMERA = 1 CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOI2SIN = 0 CIRCUITPY_CANIO = 0 CIRCUITPY_DUALBANK = 0 -CIRCUITPY_ESPCAMERA = 1 CIRCUITPY_FRAMEBUFFERIO = 0 CIRCUITPY_KEYPAD = 0 CIRCUITPY_ONEWIREIO = 0 diff --git a/ports/espressif/boards/adafruit_esp32s3_camera/sdkconfig b/ports/espressif/boards/adafruit_esp32s3_camera/sdkconfig index 1bddb7a89fb..a12cbe62f14 100644 --- a/ports/espressif/boards/adafruit_esp32s3_camera/sdkconfig +++ b/ports/espressif/boards/adafruit_esp32s3_camera/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # diff --git a/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.mk index f39b1594eda..28821ed7b48 100644 --- a/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/mpconfigboard.mk @@ -6,3 +6,6 @@ IDF_TARGET = esp32c6 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/sdkconfig index 0cc38a499d0..e9628662160 100644 --- a/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32c6_4mbflash_nopsram/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="Adafruit-Feather-ESP32C6" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c index e554be121db..1fe3fd62800 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO40, // DC - &pin_GPIO42, // CS - &pin_GPIO41, // RST + MP_OBJ_FROM_PTR(&pin_GPIO40), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO41), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h index 42b51434edf..f2ec187abde 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.h @@ -23,7 +23,7 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) -#define DEFAULT_UART_BUS_RX (&pin_GPIO34) -#define DEFAULT_UART_BUS_TX (&pin_GPIO35) +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO39) #define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk index 06a1bf706d3..a0be8c7a5ca 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/mpconfigboard.mk @@ -13,3 +13,6 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Already have a display. +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig index e69de29bb2d..e9628662160 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32s2_reverse_tft/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c index 1ebb357aed5..22af4caa652 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s2_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO39, // DC - &pin_GPIO7, // CS - &pin_GPIO40, // RST + MP_OBJ_FROM_PTR(&pin_GPIO39), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO40), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk index 68abfe8cca7..6fafa82485a 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk @@ -12,7 +12,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -OPTIMIZATION_FLAGS = -Os -CIRCUITPY_ESPCAMERA = 0 -CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32s3_4mbflash_2mbpsram/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk index bf0dc3f320f..cdf1657d8be 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32s3_nopsram/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c index e554be121db..1fe3fd62800 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO40, // DC - &pin_GPIO42, // CS - &pin_GPIO41, // RST + MP_OBJ_FROM_PTR(&pin_GPIO40), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO41), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h index c11780faf41..5053a1b2b58 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.h @@ -23,7 +23,7 @@ #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) -#define DEFAULT_UART_BUS_RX (&pin_GPIO34) -#define DEFAULT_UART_BUS_TX (&pin_GPIO35) +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO39) #define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk index 0aebfea1713..a82ae6d4f04 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/mpconfigboard.mk @@ -14,5 +14,5 @@ CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m -CIRCUITPY_ESPCAMERA = 0 +# Already have a display. CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32s3_reverse_tft/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c b/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c index e3569d864e7..587c742a64f 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO39, // DC - &pin_GPIO7, // CS - &pin_GPIO40, // RST + MP_OBJ_FROM_PTR(&pin_GPIO39), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO40), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk index c7d6c33a3fd..71ef6d222a2 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/mpconfigboard.mk @@ -10,9 +10,9 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 -CIRCUITPY_PARALLELDISPLAYBUS = 0 - CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Already have a display. +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_feather_esp32s3_tft/sdkconfig b/ports/espressif/boards/adafruit_feather_esp32s3_tft/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/adafruit_feather_esp32s3_tft/sdkconfig +++ b/ports/espressif/boards/adafruit_feather_esp32s3_tft/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk index 2715f5ca306..f948521eb6d 100644 --- a/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_feather_huzzah32/mpconfigboard.mk @@ -6,6 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_BLEIO = 0 -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_funhouse/board.c b/ports/espressif/boards/adafruit_funhouse/board.c index 061a6abf0d8..83499f5a492 100644 --- a/ports/espressif/boards/adafruit_funhouse/board.c +++ b/ports/espressif/boards/adafruit_funhouse/board.c @@ -37,9 +37,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO39, // TFT_DC Command or data - &pin_GPIO40, // TFT_CS Chip select - &pin_GPIO41, // TFT_RESET Reset + MP_OBJ_FROM_PTR(&pin_GPIO39), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO40), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO41), // TFT_RESET Reset 5000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk index e956964776c..43045b4cd98 100644 --- a/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_funhouse/mpconfigboard.mk @@ -9,6 +9,11 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Specialized board. CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_MAX3421E = 0 CIRCUITPY_PS2IO = 0 @@ -21,7 +26,3 @@ CIRCUITPY_FRAMEBUFFERIO = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel - -CIRCUITPY_ESP_PSRAM_SIZE = 2MB -CIRCUITPY_ESP_PSRAM_MODE = qio -CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.mk b/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.mk index 24909715b97..9b816b2ba28 100644 --- a/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_huzzah32_breakout/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c index 321a5a1f2c7..61659755be2 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/board.c @@ -7,9 +7,11 @@ #include "supervisor/board.h" #include "mpconfigboard.h" +#include "driver/gpio.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/fourwire/FourWire.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/__init__.h" #include "shared-module/displayio/__init__.h" #include "supervisor/shared/board.h" @@ -21,7 +23,7 @@ static const char *TAG = "board"; // This is an ILO373 control chip. The display is a 2.9" grayscale EInk. -const uint8_t display_start_sequence[] = { +const uint8_t il0373_display_start_sequence[] = { 0x01, 5, 0x03, 0x00, 0x2b, 0x2b, 0x13, // power setting 0x06, 3, 0x17, 0x17, 0x17, // booster soft start 0x04, DELAY, 200, // power on and wait 200 ms @@ -83,17 +85,201 @@ const uint8_t display_start_sequence[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -const uint8_t display_stop_sequence[] = { +const uint8_t il0373_display_stop_sequence[] = { 0x50, 0x01, 0x17, // CDI Setting 0x82, 0x01, 0x00, // VCM DC to -0.1V 0x02, 0x00 // Power off }; -const uint8_t refresh_sequence[] = { +const uint8_t il0373_display_refresh_sequence[] = { 0x12, 0x00 }; + +// This is an SSD1680 control chip. The display is a 2.9" grayscale EInk. +const uint8_t ssd1680_display_start_sequence[] = { + 0x12, DELAY, 0x00, 0x14, // soft reset and wait 20ms + 0x11, 0x00, 0x01, 0x03, // Ram data entry mode + 0x3c, 0x00, 0x01, 0x03, // border color + 0x2c, 0x00, 0x01, 0x28, // Set vcom voltage + 0x03, 0x00, 0x01, 0x17, // Set gate voltage + 0x04, 0x00, 0x03, 0x41, 0xae, 0x32, // Set source voltage + 0x4e, 0x00, 0x01, 0x01, // ram x count + 0x4f, 0x00, 0x02, 0x00, 0x00, // ram y count + 0x01, 0x00, 0x03, 0x27, 0x01, 0x00, // set display size + 0x32, 0x00, 0x99, // Update waveforms + 0x2a, 0x60, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L0 + 0x20, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L1 + 0x28, 0x60, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L2 + 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L3 + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L4 + 0x00, 0x02, 0x00, 0x05, 0x14, 0x00, 0x00, // TP, SR, RP of Group0 + 0x1E, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x01, // TP, SR, RP of Group1 + 0x00, 0x02, 0x00, 0x05, 0x14, 0x00, 0x00, // TP, SR, RP of Group2 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group3 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group4 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group5 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group6 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group9 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group10 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // TP, SR, RP of Group11 + 0x24, 0x22, 0x22, 0x22, 0x23, 0x32, 0x00, 0x00, 0x00, // FR, XON + 0x22, 0x00, 0x01, 0xc7 // display update mode +}; + +// FPC-7519rev.b panels (User ID byte 0x44 or 0xca) need colstart=8 and tuned VCOM + LUT. +// LUT: Good Display reference (GxEPD2_4G / GDEM029T94) with VS rows reversed (L0↔L3, L1↔L2). +// Reason: CircuitPython maps luma 0→L0 and luma 255→L3. On this panel VSH1(0x40) drives WHITE and +// VSL(0x20) drives BLACK, so L0 must carry the black-driving waveform and L3 the white-driving +// waveform — opposite from GxEPD2_4G's Arduino convention (where index 0 = white constant). +// VS=0x48 = VSH1/GND/VSL/GND alternating for DC balance. +// VCOM=0x24 empirically tuned for FPC-7519rev.b contrast. Both 0x44 and 0xca share this sequence. +const uint8_t ssd1680_fpc7519_display_start_sequence[] = { + 0x12, DELAY, 0x00, 0x14, // soft reset and wait 20ms + 0x11, 0x00, 0x01, 0x03, // Ram data entry mode + 0x3c, 0x00, 0x01, 0x03, // border color + 0x2c, 0x00, 0x01, 0x24, // Set vcom voltage (0x24 tuned for FPC-7519rev.b contrast) + 0x03, 0x00, 0x01, 0x17, // Set gate voltage + 0x04, 0x00, 0x03, 0x41, 0xae, 0x32, // Set source voltage + 0x4e, 0x00, 0x01, 0x01, // ram x count + 0x4f, 0x00, 0x02, 0x00, 0x00, // ram y count + 0x01, 0x00, 0x03, 0x27, 0x01, 0x00, // set display size + 0x32, 0x00, 0x99, // Update waveforms (153 bytes follow) + // VS rows: only L0↔L3 are swapped relative to GxEPD2_4G; L1 and L2 stay in place. + // Reason: CircuitPython luma maps 0→L0, 64-127→L2, 128-191→L1, 255→L3. + // GxEPD2 uses L0=white-driver, L3=black-driver (opposite of CircuitPython for extremes). + // GxEPD2 L1=lighter-gray, L2=darker-gray; CircuitPython L1=mid-bright, L2=mid-dark — same ordering. + // So: swap only L0↔L3 (polarity); L1 and L2 keep their GxEPD2 positions (gradient preserved). + // 0x48 = VSH1/GND/VSL/GND alternating — better DC balance than 0x60 (VSH1/VSL/GND/GND) + 0x20, 0x48, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L0 (darkest/black) ← GxEPD2 L3 + 0x08, 0x48, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L1 (mid-light) ← GxEPD2 L1 (luma 128-191 → lighter) + 0x02, 0x48, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L2 (mid-dark) ← GxEPD2 L2 (luma 64-127 → darker) + 0x40, 0x48, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L3 (lightest/white) ← GxEPD2 L0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L4 VCOM + // Timing groups — Good Display reference timing + 0x0A, 0x19, 0x00, 0x03, 0x08, 0x00, 0x00, // Group0: 10+25 / 3+8 frames activation + 0x14, 0x01, 0x00, 0x14, 0x01, 0x00, 0x03, // Group1: 20+1 / 20+1 frames, RP=3 repeats + 0x0A, 0x03, 0x00, 0x08, 0x19, 0x00, 0x00, // Group2: 10+3 / 8+25 frames (mirror of G0) + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // Group3: 1 frame settle + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group4 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group5 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group6 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group9 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group10 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group11 + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, // XON + 0x22, 0x00, 0x01, 0xc7 // display update mode +}; + +const uint8_t ssd1680_display_stop_sequence[] = { + 0x10, DELAY, 0x01, 0x01, 0x64 +}; + +const uint8_t ssd1680_display_refresh_sequence[] = { + 0x20, 0x00, 0x00 +}; + + +typedef enum { + DISPLAY_IL0373, + DISPLAY_SSD1680_COLSTART_0, + DISPLAY_SSD1680_COLSTART_8, // FPC-7519rev.b (User ID 0x44 or 0xca) +} display_type_t; + +static display_type_t detect_display_type(void) { + // Bitbang 4-wire SPI with a bidirectional data line to read the first byte of register 0x2e, + // which is the 10-byte USER ID. + // NOTE: the SSD1680 drives its response back on the MOSI/DATA line (GPIO35) in half-duplex + // mode, NOT on the separate MISO line (GPIO37). Read with GPIO35 switched to input. + // On the IL0373 it will return 0xff because it's not a valid register. + // With SSD1680, we have seen two types: + // 1. The first batch of displays, labeled "FPC-A005 20.06.15 TRX", which needs colstart=0. + // These have 10 bytes of zeros in the User ID. + // 2. Later panels, labeled "FPC-7519rev.b", which need colstart=8 and a tuned LUT/VCOM. + // Two controller variants exist within this panel generation: + // User ID [0x44, 0x0, 0x4, 0x0, 0x25, 0x0, 0x1, 0x78, 0x2b, 0xe] + // User ID [0xca, 0xfe, 0x0, 0x16, 0x80, 0x0, 0x75, 0x1, 0x0, 0x98] + // Both carry the same ribbon label and show the same display characteristics. + // So let's distinguish just by the first byte. + digitalio_digitalinout_obj_t data; + digitalio_digitalinout_obj_t clock; + digitalio_digitalinout_obj_t chip_select; + digitalio_digitalinout_obj_t data_command; + digitalio_digitalinout_obj_t reset; + data.base.type = &digitalio_digitalinout_type; + clock.base.type = &digitalio_digitalinout_type; + chip_select.base.type = &digitalio_digitalinout_type; + data_command.base.type = &digitalio_digitalinout_type; + reset.base.type = &digitalio_digitalinout_type; + + common_hal_digitalio_digitalinout_construct(&data, &pin_GPIO35); + common_hal_digitalio_digitalinout_construct(&clock, &pin_GPIO36); + common_hal_digitalio_digitalinout_construct(&chip_select, &pin_GPIO8); + common_hal_digitalio_digitalinout_construct(&data_command, &pin_GPIO7); + common_hal_digitalio_digitalinout_construct(&reset, &pin_GPIO6); + + // Set CS and DC low + common_hal_digitalio_digitalinout_switch_to_output(&chip_select, false, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output(&data_command, false, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output(&data, false, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output(&clock, false, DRIVE_MODE_PUSH_PULL); + + // Pulse RESET low to wake SSD1680 from deep sleep (entered via stop_sequence on prior run). + // SSD1680 ignores all SPI commands while in deep sleep; only a hardware reset exits it. + common_hal_digitalio_digitalinout_switch_to_output(&reset, false, DRIVE_MODE_PUSH_PULL); + common_hal_mcu_delay_us(200); + common_hal_digitalio_digitalinout_set_value(&reset, true); + common_hal_mcu_delay_us(10000); // 10ms for controller to come out of reset + + uint8_t status_read = 0x2e; // SSD1680 User ID register. Not a valid register on IL0373. + for (int i = 0; i < 8; i++) { + common_hal_digitalio_digitalinout_set_value(&data, (status_read & (1 << (7 - i))) != 0); + common_hal_digitalio_digitalinout_set_value(&clock, true); + common_hal_digitalio_digitalinout_set_value(&clock, false); + } + + // Set DC high for data and switch to input with pull-up in case the SSD1680 doesn't send any + // data back (as it should.) + common_hal_digitalio_digitalinout_switch_to_input(&data, PULL_UP); + common_hal_digitalio_digitalinout_set_value(&data_command, true); + uint8_t status = 0; + for (int bit = 0; bit < 8; bit++) { + status <<= 1; + if (common_hal_digitalio_digitalinout_get_value(&data)) { + status |= 1; + } + common_hal_digitalio_digitalinout_set_value(&clock, true); + common_hal_digitalio_digitalinout_set_value(&clock, false); + } + + // Set CS high + common_hal_digitalio_digitalinout_set_value(&chip_select, true); + + common_hal_digitalio_digitalinout_deinit(&data); + common_hal_digitalio_digitalinout_deinit(&clock); + common_hal_digitalio_digitalinout_deinit(&chip_select); + common_hal_digitalio_digitalinout_deinit(&data_command); + common_hal_digitalio_digitalinout_deinit(&reset); + + switch (status) { + case 0xff: + return DISPLAY_IL0373; + case 0x00: + return DISPLAY_SSD1680_COLSTART_0; + default: // unknown SSD1680 variant — assume newer panel needs colstart=8 + case 0x44: + case 0xca: + return DISPLAY_SSD1680_COLSTART_8; + } +} + void board_init(void) { + display_type_t display_type = detect_display_type(); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; busio_spi_obj_t *spi = &bus->inline_bus; common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO35, NULL, false); @@ -102,47 +288,72 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO7, // EPD_DC Command or data - &pin_GPIO8, // EPD_CS Chip select - &pin_GPIO6, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO7), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO8), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO6), // EPD_RST Reset 4000000, // Baudrate 0, // Polarity 0); // Phase epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 296, // width - 128, // height - 160, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x10, // write_black_ram_command - false, // black_bits_inverted - 0x13, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - refresh_sequence, sizeof(refresh_sequence), - 1.0, // refresh_time - &pin_GPIO5, // busy_pin - false, // busy_state - 5.0, // seconds_per_frame - false, // always_toggle_chip_select - true, // grayscale - false, // acep - false, // two_byte_sequence_length - false); // address_little_endian + + if (display_type == DISPLAY_IL0373) { + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = il0373_display_start_sequence; + args.start_sequence_len = sizeof(il0373_display_start_sequence); + args.stop_sequence = il0373_display_stop_sequence; + args.stop_sequence_len = sizeof(il0373_display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 160; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = 0x10; + args.write_color_ram_command = 0x13; + args.refresh_sequence = il0373_display_refresh_sequence; + args.refresh_sequence_len = sizeof(il0373_display_refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO5; + args.seconds_per_frame = 5.0; + args.grayscale = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); + } else { + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + if (display_type == DISPLAY_SSD1680_COLSTART_8) { + args.colstart = 8; + args.start_sequence = ssd1680_fpc7519_display_start_sequence; + args.start_sequence_len = sizeof(ssd1680_fpc7519_display_start_sequence); + } else { + args.start_sequence = ssd1680_display_start_sequence; + args.start_sequence_len = sizeof(ssd1680_display_start_sequence); + } + args.stop_sequence = ssd1680_display_stop_sequence; + args.stop_sequence_len = sizeof(ssd1680_display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 250; + args.ram_height = 296; + args.rotation = 270; + args.set_column_window_command = 0x44; + args.set_row_window_command = 0x45; + args.set_current_column_command = 0x4e; + args.set_current_row_command = 0x4f; + args.write_black_ram_command = 0x24; + args.write_color_ram_command = 0x26; + args.refresh_sequence = ssd1680_display_refresh_sequence; + args.refresh_sequence_len = sizeof(ssd1680_display_refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO5; + args.busy_state = true; + args.seconds_per_frame = 5.0; + args.grayscale = true; + args.two_byte_sequence_length = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); + } } bool espressif_board_reset_pin_number(gpio_num_t pin_number) { diff --git a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk index 01b9ec73e9c..582eb32eaef 100644 --- a/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_magtag_2.9_grayscale/mpconfigboard.mk @@ -9,7 +9,11 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_PARALLELDISPLAYBUS = 0 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ConnectionManager @@ -19,7 +23,3 @@ FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_LIS3DH - -CIRCUITPY_ESP_PSRAM_SIZE = 2MB -CIRCUITPY_ESP_PSRAM_MODE = qio -CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/adafruit_matrixportal_s3/mpconfigboard.mk b/ports/espressif/boards/adafruit_matrixportal_s3/mpconfigboard.mk index 51a03b34610..e213980ccdf 100644 --- a/ports/espressif/boards/adafruit_matrixportal_s3/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_matrixportal_s3/mpconfigboard.mk @@ -13,7 +13,6 @@ CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m -CIRCUITPY_ESPCAMERA = 0 - # Not enough pins. +CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_matrixportal_s3/sdkconfig b/ports/espressif/boards/adafruit_matrixportal_s3/sdkconfig index db95a623aa9..e9628662160 100644 --- a/ports/espressif/boards/adafruit_matrixportal_s3/sdkconfig +++ b/ports/espressif/boards/adafruit_matrixportal_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="matrixportal-s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_metro_esp32s3/sdkconfig b/ports/espressif/boards/adafruit_metro_esp32s3/sdkconfig index 4b1cfa36412..e9628662160 100644 --- a/ports/espressif/boards/adafruit_metro_esp32s3/sdkconfig +++ b/ports/espressif/boards/adafruit_metro_esp32s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="Metro-ESP32S3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_mini_sparkle_motion/board.c b/ports/espressif/boards/adafruit_mini_sparkle_motion/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/adafruit_mini_sparkle_motion/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_mini_sparkle_motion/mpconfigboard.h b/ports/espressif/boards/adafruit_mini_sparkle_motion/mpconfigboard.h new file mode 100644 index 00000000000..9c83117fe55 --- /dev/null +++ b/ports/espressif/boards/adafruit_mini_sparkle_motion/mpconfigboard.h @@ -0,0 +1,25 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Adafruit Mini Sparkle Motion" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO12) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO19}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO25, .rx = &pin_GPIO26}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_mini_sparkle_motion/mpconfigboard.mk b/ports/espressif/boards/adafruit_mini_sparkle_motion/mpconfigboard.mk new file mode 100644 index 00000000000..25c857fc597 --- /dev/null +++ b/ports/espressif/boards/adafruit_mini_sparkle_motion/mpconfigboard.mk @@ -0,0 +1,12 @@ +CIRCUITPY_CREATOR_ID = 0x0000239A +CIRCUITPY_CREATION_ID = 0x00320007 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Few pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_mini_sparkle_motion/pins.c b/ports/espressif/boards/adafruit_mini_sparkle_motion/pins.c new file mode 100644 index 00000000000..d8d42e8a2bc --- /dev/null +++ b/ports/espressif/boards/adafruit_mini_sparkle_motion/pins.c @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/tests/extmod/ssl_poll.py.exp b/ports/espressif/boards/adafruit_mini_sparkle_motion/sdkconfig similarity index 100% rename from tests/extmod/ssl_poll.py.exp rename to ports/espressif/boards/adafruit_mini_sparkle_motion/sdkconfig diff --git a/ports/espressif/boards/adafruit_p4gpio/board.c b/ports/espressif/boards/adafruit_p4gpio/board.c new file mode 100644 index 00000000000..8287c3ea247 --- /dev/null +++ b/ports/espressif/boards/adafruit_p4gpio/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_p4gpio/mpconfigboard.h b/ports/espressif/boards/adafruit_p4gpio/mpconfigboard.h new file mode 100644 index 00000000000..294896c5c34 --- /dev/null +++ b/ports/espressif/boards/adafruit_p4gpio/mpconfigboard.h @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Adafruit P4 GPIO" +#define MICROPY_HW_MCU_NAME "ESP32P4" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO52) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO35) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO54) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO53) + +// Use the second USB device (numbered 0 and 1) -- HS PHY routed to J1. +#define CIRCUITPY_USB_DEVICE_INSTANCE 1 +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED (1) + +// FS USB on GPIO24/25 routed to J2. +#define CIRCUITPY_USB_HOST_INSTANCE 0 diff --git a/ports/espressif/boards/adafruit_p4gpio/mpconfigboard.mk b/ports/espressif/boards/adafruit_p4gpio/mpconfigboard.mk new file mode 100644 index 00000000000..dc1560b2bb5 --- /dev/null +++ b/ports/espressif/boards/adafruit_p4gpio/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x239A +USB_PID = 0x8174 +USB_PRODUCT = "Adafruit P4 GPIO" +USB_MANUFACTURER = "Adafruit" + +IDF_TARGET = esp32p4 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 32MB +CIRCUITPY_ESP_PSRAM_MODE = hpi +CIRCUITPY_ESP_PSRAM_FREQ = 200m diff --git a/ports/espressif/boards/adafruit_p4gpio/pins.c b/ports/espressif/boards/adafruit_p4gpio/pins.c new file mode 100644 index 00000000000..77ed1f89513 --- /dev/null +++ b/ports/espressif/boards/adafruit_p4gpio/pins.c @@ -0,0 +1,85 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Header J8 (B1) + { MP_ROM_QSTR(MP_QSTR_B1_0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_B1_1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_B1_2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_B1_3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_B1_4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_B1_5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_B1_6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_B1_7), MP_ROM_PTR(&pin_GPIO7) }, + + // Header J7 (B2) + { MP_ROM_QSTR(MP_QSTR_B2_0), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_B2_1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_B2_2), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_B2_3), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_B2_4), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_B2_5), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_B2_6), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_B2_7), MP_ROM_PTR(&pin_GPIO15) }, + + // Header J6 (B3) + { MP_ROM_QSTR(MP_QSTR_B3_0), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_B3_1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_B3_2), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_B3_3), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_B3_4), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_B3_5), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_B3_6), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_B3_7), MP_ROM_PTR(&pin_GPIO23) }, + + // Header J3 (T3) + { MP_ROM_QSTR(MP_QSTR_T3_0), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_T3_1), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_T3_2), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_T3_3), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_T3_4), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_T3_5), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_T3_6), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_T3_7), MP_ROM_PTR(&pin_GPIO26) }, + + // Header J4 (T2) + { MP_ROM_QSTR(MP_QSTR_T2_0), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_T2_1), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_T2_2), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_T2_3), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_T2_4), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_T2_5), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_T2_6), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_T2_7), MP_ROM_PTR(&pin_GPIO34) }, + + // Header J5 (T1) + { MP_ROM_QSTR(MP_QSTR_T1_0), MP_ROM_PTR(&pin_GPIO51) }, + { MP_ROM_QSTR(MP_QSTR_T1_1), MP_ROM_PTR(&pin_GPIO50) }, + { MP_ROM_QSTR(MP_QSTR_T1_2), MP_ROM_PTR(&pin_GPIO49) }, + { MP_ROM_QSTR(MP_QSTR_T1_3), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_T1_4), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_T1_5), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_T1_6), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_T1_7), MP_ROM_PTR(&pin_GPIO44) }, + + // Boot button (also exposed on J9/J10 pin 2) + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO35) }, + + // NeoPixel + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO52) }, + + // StemmaQT / Qwiic I2C (J11) + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO54) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/adafruit_p4gpio/sdkconfig b/ports/espressif/boards/adafruit_p4gpio/sdkconfig new file mode 100644 index 00000000000..681e52bf82c --- /dev/null +++ b/ports/espressif/boards/adafruit_p4gpio/sdkconfig @@ -0,0 +1,70 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Bootloader config +# +# +# Log +# +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +# end of Format + +# end of Log + +# default: +CONFIG_BOOTLOADER_CPU_CLK_FREQ_MHZ=90 +# +# Serial Flash Configurations +# +# CONFIG_BOOTLOADER_FLASH_XMC_SUPPORT is not set +# end of Serial Flash Configurations + +# end of Bootloader config + +# +# Component config +# +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +# end of Bluetooth + +# +# Hardware Settings +# +# +# Chip revision +# +CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y +CONFIG_ESP32P4_REV_MIN_100=y +# default: +CONFIG_ESP32P4_REV_MIN_FULL=100 +# default: +CONFIG_ESP_REV_MIN_FULL=100 +# default: +CONFIG_ESP32P4_REV_MAX_FULL=199 +# default: +CONFIG_ESP_REV_MAX_FULL=199 +# end of Chip revision + +# end of Hardware Settings + +# +# ESP System Settings +# +# default: +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_360=y +# default: +# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_400 is not set +# default: +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=360 +# end of ESP System Settings + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h b/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h index 799a53c5c78..a0bc2b9f374 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_qtpy_esp32_pico/mpconfigboard.h @@ -26,3 +26,6 @@ // UART pins attached to the USB-serial converter chip #define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) #define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk index 4063a639522..a17418eff19 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32c3/mpconfigboard.mk @@ -7,9 +7,8 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 # Not enough pins. CIRCUITPY_PARALLELDISPLAYBUS = 0 +CIRCUITPY_RGBMATRIX = 0 diff --git a/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig b/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig index aa82df2b813..e9628662160 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig +++ b/ports/espressif/boards/adafruit_qtpy_esp32c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="Adafruit-QTPy-ESP32C3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.h b/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.h index c59dbfc81c9..a0c73d0bcdf 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_qtpy_esp32s2/mpconfigboard.h @@ -25,3 +25,6 @@ #define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO5, .rx = &pin_GPIO16}} #define DOUBLE_TAP_PIN (&pin_GPIO10) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.h b/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.h index ad97ab057fb..9760bbfeb44 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.h @@ -25,3 +25,6 @@ #define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO5, .rx = &pin_GPIO16}} #define DOUBLE_TAP_PIN (&pin_GPIO10) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk index afc6e335c1a..09571a63a59 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/mpconfigboard.mk @@ -13,6 +13,6 @@ CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m -CIRCUITPY_ESPCAMERA = 0 # Not enough pins. +CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/sdkconfig b/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/sdkconfig +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_4mbflash_2mbpsram/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.h b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.h index fcdefda3b40..6073bd47d0e 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.h +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.h @@ -25,3 +25,6 @@ #define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO5, .rx = &pin_GPIO16}} #define DOUBLE_TAP_PIN (&pin_GPIO10) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk index 43ac269cd09..053b15647c1 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/mpconfigboard.mk @@ -10,7 +10,5 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 - -# Not enough pins. +# Few pins. CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig +++ b/ports/espressif/boards/adafruit_qtpy_esp32s3_nopsram/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_qualia_s3_rgb666/sdkconfig b/ports/espressif/boards/adafruit_qualia_s3_rgb666/sdkconfig index 8e26f268e76..e9628662160 100644 --- a/ports/espressif/boards/adafruit_qualia_s3_rgb666/sdkconfig +++ b/ports/espressif/boards/adafruit_qualia_s3_rgb666/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="qualia" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/adafruit_sparkle_motion/board.c b/ports/espressif/boards/adafruit_sparkle_motion/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_sparkle_motion/mpconfigboard.h b/ports/espressif/boards/adafruit_sparkle_motion/mpconfigboard.h new file mode 100644 index 00000000000..3f93d080331 --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion/mpconfigboard.h @@ -0,0 +1,25 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Adafruit Sparkle Motion" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO4) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO2) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO13, .sda = &pin_GPIO14}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO9, .rx = &pin_GPIO10}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_sparkle_motion/mpconfigboard.mk b/ports/espressif/boards/adafruit_sparkle_motion/mpconfigboard.mk new file mode 100644 index 00000000000..2765a63cef6 --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion/mpconfigboard.mk @@ -0,0 +1,12 @@ +CIRCUITPY_CREATOR_ID = 0x0000239A +CIRCUITPY_CREATION_ID = 0x00320006 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Very few pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/adafruit_sparkle_motion/pins.c b/ports/espressif/boards/adafruit_sparkle_motion/pins.c new file mode 100644 index 00000000000..f22cb50608d --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion/pins.c @@ -0,0 +1,62 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + { MP_ROM_QSTR(MP_QSTR_IR), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SIG1), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SIG2), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SIG3), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_SIG4), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/tests/feature_check/io_module.py.exp b/ports/espressif/boards/adafruit_sparkle_motion/sdkconfig similarity index 100% rename from tests/feature_check/io_module.py.exp rename to ports/espressif/boards/adafruit_sparkle_motion/sdkconfig diff --git a/ports/espressif/boards/adafruit_sparkle_motion_stick/board.c b/ports/espressif/boards/adafruit_sparkle_motion_stick/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion_stick/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/adafruit_sparkle_motion_stick/mpconfigboard.h b/ports/espressif/boards/adafruit_sparkle_motion_stick/mpconfigboard.h new file mode 100644 index 00000000000..fdc289fb845 --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion_stick/mpconfigboard.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Adafruit Sparkle Motion Stick" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO4) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO18) + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/adafruit_sparkle_motion_stick/mpconfigboard.mk b/ports/espressif/boards/adafruit_sparkle_motion_stick/mpconfigboard.mk new file mode 100644 index 00000000000..d1bfe2f9742 --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion_stick/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x0000239A +CIRCUITPY_CREATION_ID = 0x00320008 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/adafruit_sparkle_motion_stick/pins.c b/ports/espressif/boards/adafruit_sparkle_motion_stick/pins.c new file mode 100644 index 00000000000..a5fdadac1e0 --- /dev/null +++ b/ports/espressif/boards/adafruit_sparkle_motion_stick/pins.c @@ -0,0 +1,32 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_IR), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/adafruit_sparkle_motion_stick/sdkconfig b/ports/espressif/boards/adafruit_sparkle_motion_stick/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk index 515b6da5c07..e51bdc7d8cc 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/mpconfigboard.mk @@ -9,4 +9,12 @@ CIRCUITPY_ESP_FLASH_SIZE = 2MB CIRCUITPY_DUALBANK = 0 +CIRCUITPY_AESIO = 0 +CIRCUITPY_CANIO = 0 +CIRCUITPY_GETPASS = 0 +CIRCUITPY_JPEGIO = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_ZLIB = 0 + CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig index 411bc17724a..79713bb57e8 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig +++ b/ports/espressif/boards/ai_thinker_esp32-c3s-2m/sdkconfig @@ -7,9 +7,32 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="AIThinker-ESP32C3S-2M" # end of LWIP +# +# Wireless Coexistence +# +# CONFIG_ESP_COEX_SW_COEXIST_ENABLE is not set +# end of Wireless Coexistence + +# +# LibC +# +# CONFIG_LIBC_OPTIMIZED_MISALIGNED_ACCESS is not set +# end of LibC + +# +# mbedTLS +# +# +# Certificate Bundle +# +# CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL is not set +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y +# end of Certificate Bundle +# +# end of mbedTLS + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk index f907853f238..9bcaa3473a2 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk +++ b/ports/espressif/boards/ai_thinker_esp32-c3s/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 diff --git a/ports/espressif/boards/ai_thinker_esp32-c3s/sdkconfig b/ports/espressif/boards/ai_thinker_esp32-c3s/sdkconfig index 435604eb4b8..e9628662160 100644 --- a/ports/espressif/boards/ai_thinker_esp32-c3s/sdkconfig +++ b/ports/espressif/boards/ai_thinker_esp32-c3s/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="AIThinker-ESP32C3S" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/arduino_nano_esp32s3/mpconfigboard.mk b/ports/espressif/boards/arduino_nano_esp32s3/mpconfigboard.mk index 3abf3d9afcb..4974b7a9c89 100644 --- a/ports/espressif/boards/arduino_nano_esp32s3/mpconfigboard.mk +++ b/ports/espressif/boards/arduino_nano_esp32s3/mpconfigboard.mk @@ -21,5 +21,3 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m INTERNAL_FLASH_FILESYSTEM = 0 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = GD25WQ128E - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/arduino_nano_esp32s3/sdkconfig b/ports/espressif/boards/arduino_nano_esp32s3/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/arduino_nano_esp32s3/sdkconfig +++ b/ports/espressif/boards/arduino_nano_esp32s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/mpconfigboard.mk b/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/mpconfigboard.mk index 3abf3d9afcb..4974b7a9c89 100644 --- a/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/mpconfigboard.mk +++ b/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/mpconfigboard.mk @@ -21,5 +21,3 @@ CIRCUITPY_ESP_PSRAM_FREQ = 80m INTERNAL_FLASH_FILESYSTEM = 0 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = GD25WQ128E - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/sdkconfig b/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/sdkconfig index b2e5c546b82..e9628662160 100644 --- a/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/sdkconfig +++ b/ports/espressif/boards/arduino_nano_esp32s3_inverted_statusled/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="nano-esp32" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/artisense_rd00/sdkconfig b/ports/espressif/boards/artisense_rd00/sdkconfig index 36749a928bd..e9628662160 100644 --- a/ports/espressif/boards/artisense_rd00/sdkconfig +++ b/ports/espressif/boards/artisense_rd00/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="RD00-ESP32S2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.h b/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.h index 8f20dc5bfe2..31dba37970c 100644 --- a/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.h +++ b/ports/espressif/boards/atmegazero_esp32s2/mpconfigboard.h @@ -22,3 +22,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define MICROPY_HW_NEOPIXEL (&pin_GPIO40) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/atmegazero_esp32s2/sdkconfig b/ports/espressif/boards/atmegazero_esp32s2/sdkconfig index 0748a66c5ca..e9628662160 100644 --- a/ports/espressif/boards/atmegazero_esp32s2/sdkconfig +++ b/ports/espressif/boards/atmegazero_esp32s2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="ATMegaZero-Esp32s2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/autosportlabs_esp32_can_x2/sdkconfig b/ports/espressif/boards/autosportlabs_esp32_can_x2/sdkconfig index 30ffa1a8296..e9628662160 100644 --- a/ports/espressif/boards/autosportlabs_esp32_can_x2/sdkconfig +++ b/ports/espressif/boards/autosportlabs_esp32_can_x2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="autosportlabs-esp32-can-x2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/barduino/mpconfigboard.mk b/ports/espressif/boards/barduino/mpconfigboard.mk index fed67ab635b..61c5feea811 100644 --- a/ports/espressif/boards/barduino/mpconfigboard.mk +++ b/ports/espressif/boards/barduino/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/barduino/sdkconfig b/ports/espressif/boards/barduino/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/barduino/sdkconfig +++ b/ports/espressif/boards/barduino/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk index a03e6c32eb2..dfd6a665f3b 100644 --- a/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk +++ b/ports/espressif/boards/beetle-esp32-c3/mpconfigboard.mk @@ -1,4 +1,4 @@ -# TODO +# A better directory name for this board would be dfrobot_beetle_esp32_c3. CIRCUITPY_CREATOR_ID = 0x10101010 CIRCUITPY_CREATION_ID = 0x00C30001 @@ -8,6 +8,4 @@ CIRCUITPY_ESP_FLASH_MODE=qio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/beetle-esp32-c3/sdkconfig b/ports/espressif/boards/beetle-esp32-c3/sdkconfig index 2b4299082a2..e9628662160 100644 --- a/ports/espressif/boards/beetle-esp32-c3/sdkconfig +++ b/ports/espressif/boards/beetle-esp32-c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="beetle-esp32-c3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/bpi_bit_s2/mpconfigboard.mk b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.mk index e9dd3da71f4..a9bb35b51f7 100644 --- a/ports/espressif/boards/bpi_bit_s2/mpconfigboard.mk +++ b/ports/espressif/boards/bpi_bit_s2/mpconfigboard.mk @@ -9,9 +9,9 @@ CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=40m CIRCUITPY_ESP_FLASH_SIZE=4MB -# Include these Python libraries in firmware. -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel - CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/bpi_bit_s2/sdkconfig b/ports/espressif/boards/bpi_bit_s2/sdkconfig index c9b6f75868d..e9628662160 100644 --- a/ports/espressif/boards/bpi_bit_s2/sdkconfig +++ b/ports/espressif/boards/bpi_bit_s2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="BPI-BIT-S2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/bpi_leaf_s3/sdkconfig b/ports/espressif/boards/bpi_leaf_s3/sdkconfig index 6b3f2584c71..e9628662160 100644 --- a/ports/espressif/boards/bpi_leaf_s3/sdkconfig +++ b/ports/espressif/boards/bpi_leaf_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="BPI-Leaf-S3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/bpi_picow_s3/sdkconfig b/ports/espressif/boards/bpi_picow_s3/sdkconfig index 914b0772640..e9628662160 100644 --- a/ports/espressif/boards/bpi_picow_s3/sdkconfig +++ b/ports/espressif/boards/bpi_picow_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="BPI-PicoW-S3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/brainboardz_neuron/sdkconfig b/ports/espressif/boards/brainboardz_neuron/sdkconfig index e553af17769..e9628662160 100755 --- a/ports/espressif/boards/brainboardz_neuron/sdkconfig +++ b/ports/espressif/boards/brainboardz_neuron/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="BrainBoardzNeuron" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/cezerio_dev_ESP32C6/board.c b/ports/espressif/boards/cezerio_dev_ESP32C6/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/cezerio_dev_ESP32C6/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/cezerio_dev_ESP32C6/mpconfigboard.h b/ports/espressif/boards/cezerio_dev_ESP32C6/mpconfigboard.h new file mode 100644 index 00000000000..65832e3cc9c --- /dev/null +++ b/ports/espressif/boards/cezerio_dev_ESP32C6/mpconfigboard.h @@ -0,0 +1,30 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "cezerio dev ESP32C6" +#define MICROPY_HW_MCU_NAME "ESP32C6" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO3) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO7) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO21) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO23) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO17) +#define DEFAULT_UART_BUS_TX (&pin_GPIO16) + +// For entering safe mode, use BOOT button +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/cezerio_dev_ESP32C6/mpconfigboard.mk b/ports/espressif/boards/cezerio_dev_ESP32C6/mpconfigboard.mk new file mode 100644 index 00000000000..fe93c7a849a --- /dev/null +++ b/ports/espressif/boards/cezerio_dev_ESP32C6/mpconfigboard.mk @@ -0,0 +1,11 @@ +CIRCUITPY_CREATOR_ID = 0x11361206 +CIRCUITPY_CREATION_ID = 0x00C60001 + +IDF_TARGET = esp32c6 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/cezerio_dev_ESP32C6/pins.c b/ports/espressif/boards/cezerio_dev_ESP32C6/pins.c new file mode 100644 index 00000000000..ed881ab1ac0 --- /dev/null +++ b/ports/espressif/boards/cezerio_dev_ESP32C6/pins.c @@ -0,0 +1,101 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_RGB), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IMUSC), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IMUSD), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_MATRIX), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MO), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MI), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/cezerio_dev_ESP32C6/sdkconfig b/ports/espressif/boards/cezerio_dev_ESP32C6/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/cezerio_dev_ESP32C6/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/circuitart_zero_s3/mpconfigboard.h b/ports/espressif/boards/circuitart_zero_s3/mpconfigboard.h index 973e6118393..973e2f5bac2 100644 --- a/ports/espressif/boards/circuitart_zero_s3/mpconfigboard.h +++ b/ports/espressif/boards/circuitart_zero_s3/mpconfigboard.h @@ -32,3 +32,6 @@ #define DEFAULT_TFT_CS (&pin_GPIO39) #define DEFAULT_TFT_DC (&pin_GPIO5) #define DEFAULT_TFT_RST (&pin_GPIO40) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/circuitart_zero_s3/sdkconfig b/ports/espressif/boards/circuitart_zero_s3/sdkconfig index 0e6ef9fd17a..e9628662160 100644 --- a/ports/espressif/boards/circuitart_zero_s3/sdkconfig +++ b/ports/espressif/boards/circuitart_zero_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="CircuitART Zero S3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/columbia-dsl-sensor/mpconfigboard.mk b/ports/espressif/boards/columbia-dsl-sensor/mpconfigboard.mk index 9d11052ee5c..f37fe88a4fc 100644 --- a/ports/espressif/boards/columbia-dsl-sensor/mpconfigboard.mk +++ b/ports/espressif/boards/columbia-dsl-sensor/mpconfigboard.mk @@ -12,5 +12,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/columbia-dsl-sensor/sdkconfig b/ports/espressif/boards/columbia-dsl-sensor/sdkconfig index 05d2603dfba..e9628662160 100644 --- a/ports/espressif/boards/columbia-dsl-sensor/sdkconfig +++ b/ports/espressif/boards/columbia-dsl-sensor/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="columbia-dsl-sensor" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk index 3e7e54c9a63..861ae00b0f5 100644 --- a/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk +++ b/ports/espressif/boards/crcibernetica-ideaboard/mpconfigboard.mk @@ -7,9 +7,6 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_BLEIO = 0 -CIRCUITPY_ESPCAMERA = 0 - # Include these Python libraries in firmware FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ConnectionManager FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests diff --git a/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk b/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk index 86fefedfb95..707687b5cf3 100644 --- a/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk +++ b/ports/espressif/boards/crumpspace_crumps2/mpconfigboard.mk @@ -9,11 +9,11 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + CIRCUITPY_BITBANG_APA102 = 1 # Include these Python libraries in firmware. # FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DotStar - -CIRCUITPY_ESP_PSRAM_SIZE = 2MB -CIRCUITPY_ESP_PSRAM_MODE = qio -CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/crumpspace_crumps2/sdkconfig b/ports/espressif/boards/crumpspace_crumps2/sdkconfig index e1f568a2d8d..e9628662160 100644 --- a/ports/espressif/boards/crumpspace_crumps2/sdkconfig +++ b/ports/espressif/boards/crumpspace_crumps2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="CrumpS2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/cytron_maker_feather_aiot_s3/sdkconfig b/ports/espressif/boards/cytron_maker_feather_aiot_s3/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/cytron_maker_feather_aiot_s3/sdkconfig +++ b/ports/espressif/boards/cytron_maker_feather_aiot_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/deneyap_kart/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart/mpconfigboard.mk index df54649ec52..69d81074fa7 100644 --- a/ports/espressif/boards/deneyap_kart/mpconfigboard.mk +++ b/ports/espressif/boards/deneyap_kart/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.mk index 17dfe4fe768..b1b6c9eab4b 100644 --- a/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.mk +++ b/ports/espressif/boards/deneyap_kart_1a/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.mk index cb994090192..5a2fd709a5e 100644 --- a/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.mk +++ b/ports/espressif/boards/deneyap_kart_1a_v2/mpconfigboard.mk @@ -13,10 +13,3 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 -CIRCUITPY_BITMAPFILTER = 0 -CIRCUITPY_CODEOP = 0 -CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/deneyap_kart_1a_v2/sdkconfig b/ports/espressif/boards/deneyap_kart_1a_v2/sdkconfig index 2d5e06f9851..e9628662160 100644 --- a/ports/espressif/boards/deneyap_kart_1a_v2/sdkconfig +++ b/ports/espressif/boards/deneyap_kart_1a_v2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="DeneyapKart1A_v2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/deneyap_kart_g/mpconfigboard.mk b/ports/espressif/boards/deneyap_kart_g/mpconfigboard.mk index 8aaea636b84..46e0fbb3e23 100644 --- a/ports/espressif/boards/deneyap_kart_g/mpconfigboard.mk +++ b/ports/espressif/boards/deneyap_kart_g/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/deneyap_kart_g/sdkconfig b/ports/espressif/boards/deneyap_kart_g/sdkconfig index f239c314052..e9628662160 100644 --- a/ports/espressif/boards/deneyap_kart_g/sdkconfig +++ b/ports/espressif/boards/deneyap_kart_g/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="DeneyapKartG" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/deneyap_mini/mpconfigboard.mk b/ports/espressif/boards/deneyap_mini/mpconfigboard.mk index 007b7ebc82a..8f6257ff02b 100644 --- a/ports/espressif/boards/deneyap_mini/mpconfigboard.mk +++ b/ports/espressif/boards/deneyap_mini/mpconfigboard.mk @@ -9,7 +9,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/deneyap_mini/sdkconfig b/ports/espressif/boards/deneyap_mini/sdkconfig index 3bcde1ab9e6..e9628662160 100644 --- a/ports/espressif/boards/deneyap_mini/sdkconfig +++ b/ports/espressif/boards/deneyap_mini/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="DeneyapMini" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.mk b/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.mk index 457d4b93161..9712e8437f7 100644 --- a/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.mk +++ b/ports/espressif/boards/deneyap_mini_v2/mpconfigboard.mk @@ -13,5 +13,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/deneyap_mini_v2/sdkconfig b/ports/espressif/boards/deneyap_mini_v2/sdkconfig index be30fb4463d..e9628662160 100644 --- a/ports/espressif/boards/deneyap_mini_v2/sdkconfig +++ b/ports/espressif/boards/deneyap_mini_v2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="DeneyapMini_v2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/deshipu_ugame_s3/board.c b/ports/espressif/boards/deshipu_ugame_s3/board.c new file mode 100644 index 00000000000..dc09786e74c --- /dev/null +++ b/ports/espressif/boards/deshipu_ugame_s3/board.c @@ -0,0 +1,123 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2020 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#include "supervisor/board.h" +#include "mpconfigboard.h" + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#include "esp_log.h" +#include "esp_err.h" + +fourwire_fourwire_obj_t board_display_obj; + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 0x80, // Software reset then delay 0x80 (128ms) + 0xEF, 3, 0x03, 0x80, 0x02, + 0xCF, 3, 0x00, 0xC1, 0x30, + 0xED, 4, 0x64, 0x03, 0x12, 0x81, + 0xE8, 3, 0x85, 0x00, 0x78, + 0xCB, 5, 0x39, 0x2C, 0x00, 0x34, 0x02, + 0xF7, 1, 0x20, + 0xEA, 2, 0x00, 0x00, + 0xc0, 1, 0x23, // Power control VRH[5:0] + 0xc1, 1, 0x10, // Power control SAP[2:0];BT[3:0] + 0xc5, 2, 0x3e, 0x28, // VCM control + 0xc7, 1, 0x86, // VCM control2 + 0x37, 1, 0x00, // Vertical scroll zero + 0x3a, 1, 0x55, // COLMOD: Pixel Format Set + 0xb1, 2, 0x00, 0x18, // Frame Rate Control (In Normal Mode/Full Colors) + 0xb6, 3, 0x08, 0x82, 0x27, // Display Function Control + 0xF2, 1, 0x00, // 3Gamma Function Disable + 0x26, 1, 0x01, // Gamma curve selected + 0xe0, 15, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, // Set Gamma + 0xe1, 15, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, // Set Gamma + 0x11, 0 | DELAY, 0x78, // Exit Sleep then delay 0x78 (120ms) + 0x29, 0 | DELAY, 0x78, // Display on then delay 0x78 (120ms) + 0x36, 1, 0x38, +}; + + +void board_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO12, &pin_GPIO11, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO10), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO13), // TFT_RESET Reset + 48000000L, // Baudrate + 0, // Polarity + 0); // Phase + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 320, // Width (after rotation) + 240, // Height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // Color depth + false, // Grayscale + false, // Pixels in a byte share a row. Only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO21, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 20, // native_frames_per_second + true, // backlight_on_high + false, // not SH1107 + 50000); // backlight pwm frequency +} + +void board_deinit(void) { +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/deshipu_ugame_s3/mpconfigboard.h b/ports/espressif/boards/deshipu_ugame_s3/mpconfigboard.h new file mode 100644 index 00000000000..da7c3b4e8a4 --- /dev/null +++ b/ports/espressif/boards/deshipu_ugame_s3/mpconfigboard.h @@ -0,0 +1,28 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2023 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#define MICROPY_HW_BOARD_NAME "uGame S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" diff --git a/ports/espressif/boards/deshipu_ugame_s3/mpconfigboard.mk b/ports/espressif/boards/deshipu_ugame_s3/mpconfigboard.mk new file mode 100644 index 00000000000..36a0ce040c5 --- /dev/null +++ b/ports/espressif/boards/deshipu_ugame_s3/mpconfigboard.mk @@ -0,0 +1,27 @@ +USB_VID = 0x1209 +USB_PID = 0xD187 +USB_PRODUCT = "uGameS3" +USB_MANUFACTURER = "deshipu" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_STAGE = 1 +CIRCUITPY_KEYPAD = 1 + +CIRCUITPY_CANIO = 0 +CIRCUITPY_DUALBANK = 0 +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_ROTARYIO = 0 + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/ugame_s3 diff --git a/ports/espressif/boards/deshipu_ugame_s3/pins.c b/ports/espressif/boards/deshipu_ugame_s3/pins.c new file mode 100644 index 00000000000..54bd5dcdb4f --- /dev/null +++ b/ports/espressif/boards/deshipu_ugame_s3/pins.c @@ -0,0 +1,43 @@ +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_P1), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_LEFT), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_UP), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_RIGHT), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_DOWN), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_X), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_O), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_Z), MP_ROM_PTR(&pin_GPIO47) }, + + { MP_ROM_QSTR(MP_QSTR_LIGHT), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO8) }, + + + { MP_ROM_QSTR(MP_QSTR_AUDIO_BCLK), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_AUDIO_LRCLK), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_AUDIO_DATA), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_AUDIO_GAIN), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/deshipu_ugame_s3/sdkconfig b/ports/espressif/boards/deshipu_ugame_s3/sdkconfig new file mode 100644 index 00000000000..1bddb7a89fb --- /dev/null +++ b/ports/espressif/boards/deshipu_ugame_s3/sdkconfig @@ -0,0 +1,22 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" +# end of LWIP + +# +# Camera configuration +# +# CONFIG_OV7725_SUPPORT is not set +# CONFIG_OV3660_SUPPORT is not set +# end of Camera configuration + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk index 9f657c6552d..01db9cff090 100644 --- a/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk +++ b/ports/espressif/boards/doit_esp32_devkit_v1/mpconfigboard.mk @@ -6,6 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/elecrow_crowpanel_3.5/board.c b/ports/espressif/boards/elecrow_crowpanel_3.5/board.c new file mode 100755 index 00000000000..f52f23a9ae8 --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_3.5/board.c @@ -0,0 +1,100 @@ +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "common-hal/microcontroller/Pin.h" + +// reference: lv_micropython ili9XXX.py +// reference: ILI9488 datasheet + +#define DELAY_FLAG 0x80 + +#define COLORMODE_BGR 0b00001000 +#define ROTATION_Y_FLIP 0b10000000 +#define ROTATION_X_FLIP 0b01000000 +#define ROTATION_MV 0b00100000 + +// DBI type C (SPI) only has 3bit and 18bit format support, 3bit = 2 pixels per byte, 18bit = one color per byte +#define COLORFORMAT_3BIT 0b00000001 +#define COLORFORMAT_16BIT 0b00000101 +#define COLORFORMAT_18BIT 0b00000110 +#define COLORFORMAT_24BIT 0b00000111 + +static uint8_t display_init_sequence[] = { + 0x01, DELAY_FLAG | 0, 200, // Software Reset + 0x11, DELAY_FLAG | 0, 120, // Exit Sleep Mode + 0xE0, 15, 0x00, 0x03, 0x09, 0x08, 0x16, 0x0A, 0x3F, 0x78, 0x4C, 0x09, 0x0A, 0x08, 0x16, 0x1A, 0x0F, // Positive Gamma Control + 0xE1, 15, 0x00, 0x16, 0x19, 0x03, 0x0F, 0x05, 0x32, 0x45, 0x46, 0x04, 0x0E, 0x0D, 0x35, 0x37, 0x0F, // Negative Gamma Control + 0xC0, 2, 0x17, 0x15, // Power Control 1 + 0xC1, 1, 0x41, // Power Control 2 + 0xC2, 1, 0x44, // Power Control 3 / Normal Mode + 0xC5, 3, 0x00, 0x12, 0x80, // VCOM Control + 0x36, 1, ROTATION_Y_FLIP, // Colormode & Rotation + 0x3A, 1, COLORFORMAT_18BIT, // Interface pixel format + 0xB0, 1, 0x00, // Interface mode control + 0xB1, 1, 0xA0, // Frame Rate Control + 0xB4, 1, 0x02, // Display Inversion Control + 0xB6, 2, 0x02, 0x02, // Display Function Control + 0xE9, 1, 0x00, // Set Image Function + 0x53, 1, 0x28, // CTRL Display Value + 0x51, 1, 0x7F, // Display Brightness + 0xF7, 4, 0xA9, 0x51, 0x2C, 0x02, // Adjust Control 3 + 0x29, DELAY_FLAG | 0, 25 // Display ON +}; + +void board_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO14, &pin_GPIO13, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset + 20000000, // Baudrate + 0, // Polarity + 0); // Phase + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + common_hal_busdisplay_busdisplay_construct(display, + bus, + 320, // Width (after rotation) + 480, // Height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 24, // Color depth + false, // grayscale + false, // pixels in byte share row. only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO27, // backlight pin + 0x51, // cmd to write brightness + 0.5f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000); // backlight pwm frequency +} + +void board_deinit(void) { + common_hal_displayio_release_displays(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/elecrow_crowpanel_3.5/mpconfigboard.h b/ports/espressif/boards/elecrow_crowpanel_3.5/mpconfigboard.h new file mode 100644 index 00000000000..9c080fd3223 --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_3.5/mpconfigboard.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Chris Drake, independently providing these changes. + * + * 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. + */ + +#define MICROPY_HW_BOARD_NAME "Elecrow CrowPanel" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}} + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}, /* SD */ \ + {.clock = &pin_GPIO14, .mosi = &pin_GPIO13, .miso = &pin_GPIO12} /* LCD & touch */ } + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) + +#define CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP (1) diff --git a/ports/espressif/boards/elecrow_crowpanel_3.5/mpconfigboard.mk b/ports/espressif/boards/elecrow_crowpanel_3.5/mpconfigboard.mk new file mode 100755 index 00000000000..f92068909fb --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_3.5/mpconfigboard.mk @@ -0,0 +1,17 @@ +CIRCUITPY_CREATOR_ID = 0xDD500000 +CIRCUITPY_CREATION_ID = 0x00320000 + +IDF_TARGET = esp32 + +# This board doesn't have USB by default, it +# instead uses a CH340C USB-to-Serial chip +CIRCUITPY_USB_DEVICE = 0 +CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/elecrow_crowpanel_3.5/pins.c b/ports/espressif/boards/elecrow_crowpanel_3.5/pins.c new file mode 100755 index 00000000000..147db0a346d --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_3.5/pins.c @@ -0,0 +1,72 @@ +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // TFT and Touch Panel share the same SPI bus + { MP_ROM_QSTR(MP_QSTR_TFT_MISO), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CLK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_TP_CS), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TP_IRQ), MP_ROM_PTR(&pin_GPIO36) }, + + // Version 2.2 hardware (Sep 2024) swaps MISO & touch CS pins + { MP_ROM_QSTR(MP_QSTR_TFT_MISO_ALT), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TP_CS_ALT), MP_ROM_PTR(&pin_GPIO12) }, + + // SD card SPI bus + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_SPEAK), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/elecrow_crowpanel_3.5/sdkconfig b/ports/espressif/boards/elecrow_crowpanel_3.5/sdkconfig new file mode 100755 index 00000000000..a571ec9cacb --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_3.5/sdkconfig @@ -0,0 +1,9 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# +# Component config +# +# +# Hardware Settings diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c new file mode 100644 index 00000000000..c292ea113aa --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/board.c @@ -0,0 +1,102 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +// SSD1683 EPD Driver chip +const uint8_t display_start_sequence[] = { + // Init + 0x12, 0x80, 0x0a, // Soft reset + 0x01, 0x03, 0x2b, 0x01, 0x00, // Set MUX as 300 + 0x21, 0x02, 0x40, 0x00, // Display update control + 0x3c, 0x01, 0x01, // Border waveform + 0x11, 0x01, 0x03, // X- mode + 0x44, 0x02, 0x00, 0x31, // Set RAM X Address Start/End Pos + 0x45, 0x04, 0x00, 0x00, 0x2b, 0x01, // Set RAM Y Address Start/End Pos + 0x4e, 0x01, 0x00, // Set RAM X Address counter + 0x4f, 0x02, 0x00, 0x00, // Set RAM Y Address counter +}; + +const uint8_t display_stop_sequence[] = { + 0x10, 0x01, 0x32, +}; + +const uint8_t refresh_sequence[] = { + 0x22, 0x01, 0xf7, // Display update sequence option + 0x20, 0x80, 0x0a, // Master activation +}; + +void board_init(void) { + + // Enable EPD with driver pin + digitalio_digitalinout_obj_t epd_enable_pin_obj; + epd_enable_pin_obj.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&epd_enable_pin_obj, &pin_GPIO7); + common_hal_digitalio_digitalinout_switch_to_output(&epd_enable_pin_obj, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&epd_enable_pin_obj); + + // Set up the SPI object used to control the display + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO12, &pin_GPIO11, NULL, false); + common_hal_busio_spi_never_reset(spi); + + // Set up the DisplayIO pin object + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO46), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO45), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO47), // EPD_RST Reset + 1000000, // Baudrate + 0, // Polarity + 0); // Phase + + // Set up the DisplayIO epaper object + epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; + display->base.type = &epaperdisplay_epaperdisplay_type; + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 1.0; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 400; + args.height = 300; + args.ram_width = 400; + args.ram_height = 300; + args.write_black_ram_command = 0x24; + args.write_color_ram_command = 0x26; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO48; + args.busy_state = true; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); +} + +void board_deinit(void) { + epaperdisplay_epaperdisplay_obj_t *display = &displays[0].epaper_display; + if (display->base.type == &epaperdisplay_epaperdisplay_type) { + while (common_hal_epaperdisplay_epaperdisplay_get_busy(display)) { + RUN_BACKGROUND_TASKS; + } + } + common_hal_displayio_release_displays(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/mpconfigboard.h b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/mpconfigboard.h new file mode 100644 index 00000000000..f3c494ed483 --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/mpconfigboard.h @@ -0,0 +1,27 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "CrowPanel 4.2 EPaper" +#define MICROPY_HW_MCU_NAME "ESP32S3" +#define MICROPY_HW_LED_STATUS (&pin_GPIO41) +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN { \ + {.clock = &pin_GPIO39, .mosi = &pin_GPIO40, .miso = &pin_GPIO13}, /*SD*/ \ + {.clock = &pin_GPIO12, .mosi = &pin_GPIO11}, /*EPD*/ \ +} + +// UART pins attached to the USB-serial converter chip +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX +#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/mpconfigboard.mk b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/mpconfigboard.mk new file mode 100644 index 00000000000..3f14971607b --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/mpconfigboard.mk @@ -0,0 +1,17 @@ +CIRCUITPY_CREATOR_ID = 0x1C350000 +CIRCUITPY_CREATION_ID = 0x00000001 + +# This board doesn't have USB by default, it +# instead uses a CH340C USB-to-Serial chip +CIRCUITPY_USB_DEVICE = 0 +CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/pins.c b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/pins.c new file mode 100644 index 00000000000..21a15d0732b --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/pins.c @@ -0,0 +1,73 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(tf_spi, spi, 0) +CIRCUITPY_BOARD_BUS_SINGLETON(epd_spi, spi, 1) + + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Buttons + { MP_ROM_QSTR(MP_QSTR_BUTTON_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_EXIT), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_MENU), MP_ROM_PTR(&pin_GPIO2) }, + + // Rocker Switch + { MP_ROM_QSTR(MP_QSTR_ROCKER_DOWN), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_ROCKER_CLICK), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_ROCKER_UP), MP_ROM_PTR(&pin_GPIO6) }, + + // LED + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO41) }, + + // Device Control (Pins that, when activated, enable devices) + { MP_ROM_QSTR(MP_QSTR_EPD_ENABLE), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_TF_ENABLE), MP_ROM_PTR(&pin_GPIO42) }, + + // EPD + { MP_ROM_QSTR(MP_QSTR_EPD_BUSY), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_EPD_RES), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_EPD_DC), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_EPD_CS), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_EPD_CLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_EPD_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + + // TF Slot + { MP_ROM_QSTR(MP_QSTR_TF_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_TF_MOSI), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_TF_CLK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_TF_MISO), MP_ROM_PTR(&pin_GPIO13) }, + + // User accessible GPIO + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // Objects + { MP_ROM_QSTR(MP_QSTR_TF_SPI), MP_ROM_PTR(&board_tf_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_EPD_SPI), MP_ROM_PTR(&board_epd_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/sdkconfig b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/elecrow_crowpanel_4_2_epaper/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk index dc73ae08f55..6234a6b60cc 100644 --- a/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk +++ b/ports/espressif/boards/electroniccats_bastwifi/mpconfigboard.mk @@ -5,9 +5,6 @@ USB_MANUFACTURER = "ElectronicCats" IDF_TARGET = esp32s2 -CIRCUITPY_NEOPIXEL_WRITE = 0 - CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/es3ink/sdkconfig b/ports/espressif/boards/es3ink/sdkconfig index b023c59d035..e9628662160 100644 --- a/ports/espressif/boards/es3ink/sdkconfig +++ b/ports/espressif/boards/es3ink/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="es3ink" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32_devkitc_v4_wroom_32e/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_devkitc_v4_wroom_32e/mpconfigboard.mk index 766196f9b30..aa34430a34c 100644 --- a/ports/espressif/boards/espressif_esp32_devkitc_v4_wroom_32e/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32_devkitc_v4_wroom_32e/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32_devkitc_v4_wrover/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_devkitc_v4_wrover/mpconfigboard.mk index 6ff7d4e519b..848c55d54c1 100644 --- a/ports/espressif/boards/espressif_esp32_devkitc_v4_wrover/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32_devkitc_v4_wrover/mpconfigboard.mk @@ -7,8 +7,6 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 - CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 40m diff --git a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk index 92d855842ff..1980ff38ccd 100644 --- a/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32_eye/mpconfigboard.mk @@ -13,12 +13,5 @@ CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 40m -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_CANIO = 0 CIRCUITPY_NEOPIXEL_WRITE = 0 -CIRCUITPY_PIXELBUF = 0 -CIRCUITPY_PS2IO = 0 -CIRCUITPY_ROTARYIO = 0 -CIRCUITPY_TOUCHIO = 0 -CIRCUITPY_KEYPAD = 0 diff --git a/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.mk index 4865e855023..664c24c358f 100644 --- a/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32_lyrat/mpconfigboard.mk @@ -10,7 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 4MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 40m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk index 5b4f4b7ead6..1bbb997a710 100644 --- a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 diff --git a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/sdkconfig b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/sdkconfig index c4def86e697..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/sdkconfig +++ b/ports/espressif/boards/espressif_esp32c3_devkitm_1_n4/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="ESP32-C3-DevKitM-1" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/board.c b/ports/espressif/boards/espressif_esp32c3_lyra_v2/board.c new file mode 100644 index 00000000000..b3b20cfe2d3 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.h b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.h new file mode 100644 index 00000000000..d38d4f4d09f --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Board setup +#define MICROPY_HW_BOARD_NAME "ESP32-C3-Lyra-V2" +#define MICROPY_HW_MCU_NAME "ESP32-C3N4" + +// Status LED +#define MICROPY_HW_NEOPIXEL (&pin_GPIO10) +#define MICROPY_HW_NEOPIXEL_COUNT (1) + +// Default bus pins +#define DEFAULT_UART_BUS_RX (&pin_GPIO20) +#define DEFAULT_UART_BUS_TX (&pin_GPIO21) + +// Serial over UART +#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX +#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk new file mode 100644 index 00000000000..4b23a76ba6a --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x000C303A +CIRCUITPY_CREATION_ID = 0x00C3A000 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/pins.c b/ports/espressif/boards/espressif_esp32c3_lyra_v2/pins.c new file mode 100644 index 00000000000..5f7c3d084dd --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c3_lyra_v2/pins.c @@ -0,0 +1,41 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32c3_lyra_v2/sdkconfig b/ports/espressif/boards/espressif_esp32c3_lyra_v2/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/board.c b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.h b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.h new file mode 100644 index 00000000000..d901bfb37ba --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-C61-DevKitC-1-N8R2" +#define MICROPY_HW_MCU_NAME "ESP32C61" + +#define DEFAULT_UART_BUS_RX (&pin_GPIO10) +#define DEFAULT_UART_BUS_TX (&pin_GPIO11) diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.mk new file mode 100644 index 00000000000..1092a874a68 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/mpconfigboard.mk @@ -0,0 +1,13 @@ +CIRCUITPY_CREATOR_ID = 0x000C303A +CIRCUITPY_CREATION_ID = 0x00C61001 + +IDF_TARGET = esp32c61 +IDF_TARGET_ARCH = riscv + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/pins.c b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/pins.c new file mode 100644 index 00000000000..901e5216657 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/pins.c @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_IO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_IO28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_IO29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/sdkconfig b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32c61_devkitc_1_n8r2/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/espressif_esp32c6_devkitc_1_n8/sdkconfig b/ports/espressif/boards/espressif_esp32c6_devkitc_1_n8/sdkconfig index 54a54730756..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32c6_devkitc_1_n8/sdkconfig +++ b/ports/espressif/boards/espressif_esp32c6_devkitc_1_n8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32c6" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/mpconfigboard.mk index 9685a7e62c5..75e097afa84 100644 --- a/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32c6 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_AUDIOMP3 = 0 diff --git a/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/sdkconfig b/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/sdkconfig index 30a4bea2cc6..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/sdkconfig +++ b/ports/espressif/boards/espressif_esp32c6_devkitm_1_n4/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="ESP32-C6-DevKitM-1" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32h2_devkitm_1_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32h2_devkitm_1_n4/mpconfigboard.mk index 82eb611bdf3..d1458fecec5 100644 --- a/ports/espressif/boards/espressif_esp32h2_devkitm_1_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32h2_devkitm_1_n4/mpconfigboard.mk @@ -6,3 +6,6 @@ IDF_TARGET = esp32h2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 48m CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h b/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h index 37ade1fc539..89a103e6196 100644 --- a/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h +++ b/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.h @@ -1,6 +1,6 @@ // This file is part of the CircuitPython project: https://circuitpython.org // -// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries // // SPDX-License-Identifier: MIT @@ -16,5 +16,11 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO38) #define DEFAULT_UART_BUS_TX (&pin_GPIO37) -#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX -#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO8) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO7) + +// Use the second USB device (numbered 0 and 1) +#define CIRCUITPY_USB_DEVICE_INSTANCE 1 +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED (1) + +#define CIRCUITPY_USB_HOST_INSTANCE 0 diff --git a/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.mk index 43ab506659e..247a1371192 100644 --- a/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32p4_function_ev/mpconfigboard.mk @@ -1,14 +1,14 @@ -# USB_VID = 0x303A -# USB_PID = 0x7003 -# USB_PRODUCT = "ESP32-P4-Function-EV" -# USB_MANUFACTURER = "Espressif" +USB_VID = 0x303A +USB_PID = 0x7013 +USB_PRODUCT = "ESP32-P4-Function-EV" +USB_MANUFACTURER = "Espressif" IDF_TARGET = esp32p4 CIRCUITPY_ESP_FLASH_SIZE = 16MB -CIRCUITPY_ESP_FLASH_MODE = opi +CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 32MB -CIRCUITPY_ESP_PSRAM_MODE = opi -CIRCUITPY_ESP_PSRAM_FREQ = 80m +CIRCUITPY_ESP_PSRAM_MODE = hpi +CIRCUITPY_ESP_PSRAM_FREQ = 200m diff --git a/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c b/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c index 3bb64f434d0..165ce711b73 100644 --- a/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c +++ b/ports/espressif/boards/espressif_esp32p4_function_ev/pins.c @@ -1,6 +1,6 @@ // This file is part of the CircuitPython project: https://circuitpython.org // -// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries // // SPDX-License-Identifier: MIT @@ -9,47 +9,82 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, - { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + // Header Block J1 + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO8) }, { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, - { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, - { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, - { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, - { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, - { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, - { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO37) }, { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, - { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_C6_WAKEUP), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_C6_EN), MP_ROM_PTR(&pin_GPIO54) }, + { MP_ROM_QSTR(MP_QSTR_IO54), MP_ROM_PTR(&pin_GPIO54) }, + + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_PA_CTRL), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_IO53), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, - { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + + // I2S + { MP_ROM_QSTR(MP_QSTR_I2S_DSDIN), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_I2S_ASDOUT), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO13) }, + + // Ethernet + { MP_ROM_QSTR(MP_QSTR_RMII_RXDV), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_RMII_RXD0), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_RMII_RXD1), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_MDC), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXD0), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXD1), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXEN), MP_ROM_PTR(&pin_GPIO49) }, + { MP_ROM_QSTR(MP_QSTR_RMII_CLK), MP_ROM_PTR(&pin_GPIO50) }, + { MP_ROM_QSTR(MP_QSTR_PHY_RSTN), MP_ROM_PTR(&pin_GPIO51) }, + { MP_ROM_QSTR(MP_QSTR_MDIO), MP_ROM_PTR(&pin_GPIO52) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + // SD Card + { MP_ROM_QSTR(MP_QSTR_SD_DATA0), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA1), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA2), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA3), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SD_PWRN), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32p4_function_ev/sdkconfig b/ports/espressif/boards/espressif_esp32p4_function_ev/sdkconfig index e69de29bb2d..3bce8cc0c13 100644 --- a/ports/espressif/boards/espressif_esp32p4_function_ev/sdkconfig +++ b/ports/espressif/boards/espressif_esp32p4_function_ev/sdkconfig @@ -0,0 +1,2 @@ +CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y +CONFIG_ESP32P4_REV_MIN_100=y diff --git a/ports/espressif/boards/espressif_esp32p4x_function_ev/board.c b/ports/espressif/boards/espressif_esp32p4x_function_ev/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32p4x_function_ev/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32p4x_function_ev/mpconfigboard.h b/ports/espressif/boards/espressif_esp32p4x_function_ev/mpconfigboard.h new file mode 100644 index 00000000000..d0b44fdff58 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32p4x_function_ev/mpconfigboard.h @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-P4X-Function-EV" +#define MICROPY_HW_MCU_NAME "ESP32P4" + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO37) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO8) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO7) + +// Use the second USB device (numbered 0 and 1) +#define CIRCUITPY_USB_DEVICE_INSTANCE 1 +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED (1) + +#define CIRCUITPY_USB_HOST_INSTANCE 0 diff --git a/ports/espressif/boards/espressif_esp32p4x_function_ev/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32p4x_function_ev/mpconfigboard.mk new file mode 100644 index 00000000000..bad638a0018 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32p4x_function_ev/mpconfigboard.mk @@ -0,0 +1,16 @@ +USB_VID = 0x303A +USB_PID = 0x7014 +USB_PRODUCT = "ESP32-P4X-Function-EV" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32p4 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 32MB +CIRCUITPY_ESP_PSRAM_MODE = hpi +CIRCUITPY_ESP_PSRAM_FREQ = 200m + +CIRCUITPY_ESP32P4_REV = 3 diff --git a/ports/espressif/boards/espressif_esp32p4x_function_ev/pins.c b/ports/espressif/boards/espressif_esp32p4x_function_ev/pins.c new file mode 100644 index 00000000000..165ce711b73 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32p4x_function_ev/pins.c @@ -0,0 +1,90 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Header Block J1 + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_C6_WAKEUP), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_C6_EN), MP_ROM_PTR(&pin_GPIO54) }, + { MP_ROM_QSTR(MP_QSTR_IO54), MP_ROM_PTR(&pin_GPIO54) }, + + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_PA_CTRL), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_IO53), MP_ROM_PTR(&pin_GPIO53) }, + + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + + // I2S + { MP_ROM_QSTR(MP_QSTR_I2S_DSDIN), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_I2S_ASDOUT), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCLK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO13) }, + + // Ethernet + { MP_ROM_QSTR(MP_QSTR_RMII_RXDV), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_RMII_RXD0), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_RMII_RXD1), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_MDC), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXD0), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXD1), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_RMII_TXEN), MP_ROM_PTR(&pin_GPIO49) }, + { MP_ROM_QSTR(MP_QSTR_RMII_CLK), MP_ROM_PTR(&pin_GPIO50) }, + { MP_ROM_QSTR(MP_QSTR_PHY_RSTN), MP_ROM_PTR(&pin_GPIO51) }, + { MP_ROM_QSTR(MP_QSTR_MDIO), MP_ROM_PTR(&pin_GPIO52) }, + + // SD Card + { MP_ROM_QSTR(MP_QSTR_SD_DATA0), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA1), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA2), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_DATA3), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SD_PWRN), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32p4x_function_ev/sdkconfig b/ports/espressif/boards/espressif_esp32p4x_function_ev/sdkconfig new file mode 100644 index 00000000000..a062a5b5c48 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32p4x_function_ev/sdkconfig @@ -0,0 +1,68 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Bootloader config +# +# +# Log +# +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +# CONFIG_BOOTLOADER_LOG_LEVEL_INFO is not set +# default: +CONFIG_BOOTLOADER_LOG_LEVEL=2 +# +# Format +# +# CONFIG_BOOTLOADER_LOG_COLORS is not set +# end of Format + +# end of Log + +# end of Bootloader config + +# +# Component config +# +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +# end of Bluetooth + +# +# Hardware Settings +# +# +# Chip revision +# +# CONFIG_ESP32P4_REV_MIN_300 is not set +CONFIG_ESP32P4_REV_MIN_301=y +# default: +CONFIG_ESP32P4_REV_MIN_FULL=301 +# default: +CONFIG_ESP_REV_MIN_FULL=301 +# end of Chip revision + +# default: +CONFIG_P4_REV3_MSPI_CRASH_AFTER_POWER_UP_WORKAROUND=y +# default: +CONFIG_P4_REV3_MSPI_WORKAROUND_SIZE=0x100 +# end of Hardware Settings + +# +# ESP-STDIO +# +# CONFIG_ESP_CONSOLE_UART_DEFAULT is not set +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y +# default: +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y +# default: +CONFIG_ESP_CONSOLE_UART_NUM=-1 +# default: +CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=6 +# end of ESP-STDIO + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk index 37f0450490c..271e0fd8d95 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/sdkconfig b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/sdkconfig index 57f0da698aa..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/sdkconfig b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/sdkconfig index 57f0da698aa..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n4r2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/sdkconfig b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/sdkconfig index 57f0da698aa..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s2_devkitc_1_n8r2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_box/board.c b/ports/espressif/boards/espressif_esp32s3_box/board.c index 54edb47bac3..a27411fd79c 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box/board.c @@ -31,9 +31,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO48, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO48), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk index 765f9968a99..6c117b1f67e 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_box/mpconfigboard.mk @@ -12,5 +12,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_box/sdkconfig b/ports/espressif/boards/espressif_esp32s3_box/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_box/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_box/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c index e675c0f915b..48a49e03bc3 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/board.c +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/board.c @@ -32,9 +32,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO48, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO48), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk index fe83e2e34dd..e54f55fd642 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/mpconfigboard.mk @@ -12,5 +12,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig b/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_box_lite/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/mpconfigboard.mk index 0a7925420f7..d182a144992 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n16/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/board.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/mpconfigboard.h b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/mpconfigboard.h new file mode 100644 index 00000000000..9df0ebcdb40 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-S3-DevKitC-1-N32R16" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO38) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define AUTORESET_DELAY_MS 500 diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/mpconfigboard.mk new file mode 100644 index 00000000000..15fcf8697fc --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x7003 +USB_PRODUCT = "ESP32-S3-DevKitC-1-N32R16" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 32MB +CIRCUITPY_ESP_FLASH_MODE = opi +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 16MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/pins.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/pins.c new file mode 100644 index 00000000000..e77a3813e94 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/pins.c @@ -0,0 +1,55 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r16/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n32r8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk index bd2cd4c0a33..ea5597d3702 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/board.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/mpconfigboard.h b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/mpconfigboard.h new file mode 100644 index 00000000000..02fe72fe4a7 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/mpconfigboard.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup +#define MICROPY_HW_BOARD_NAME "ESP32-S3-DevKitC-1-N8R2 (ROS version)" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/mpconfigboard.mk new file mode 100644 index 00000000000..b6ae3cf73b4 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/mpconfigboard.mk @@ -0,0 +1,16 @@ +USB_VID = 0x303A +USB_PID = 0x7003 +USB_PRODUCT = "ESP32-S3-DevKitC-1-N8R2 CPY/ROS" +USB_MANUFACTURER = "Espressif" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_RCLCPY = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/pins.c b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/pins.c new file mode 100644 index 00000000000..3bb64f434d0 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/pins.c @@ -0,0 +1,55 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r2_ros/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8_hacktablet/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8_hacktablet/sdkconfig index 46e3a741091..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8_hacktablet/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_devkitc_1_n8r8_hacktablet/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3-hacktablet" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk index fdbd686e090..5a410afaa06 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/sdkconfig b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_devkitm_1_n8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_eye/board.c b/ports/espressif/boards/espressif_esp32s3_eye/board.c index c48c9428cf4..43445b034e4 100644 --- a/ports/espressif/boards/espressif_esp32s3_eye/board.c +++ b/ports/espressif/boards/espressif_esp32s3_eye/board.c @@ -56,9 +56,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO43, // DC - &pin_GPIO44, // CS - NULL, // no reset pin + MP_OBJ_FROM_PTR(&pin_GPIO43), // DC + MP_OBJ_FROM_PTR(&pin_GPIO44), // CS + mp_const_none, // no reset pin 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/espressif_esp32s3_eye/sdkconfig b/ports/espressif/boards/espressif_esp32s3_eye/sdkconfig index eebef2db64d..ac1c5357176 100644 --- a/ports/espressif/boards/espressif_esp32s3_eye/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_eye/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3-eye" # end of LWIP CONFIG_OV2640_SUPPORT=y # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_lcd_ev/sdkconfig b/ports/espressif/boards/espressif_esp32s3_lcd_ev/sdkconfig index 75153e42020..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_lcd_ev/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_lcd_ev/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3-lcd-ev" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_lcd_ev_v1.5/sdkconfig b/ports/espressif/boards/espressif_esp32s3_lcd_ev_v1.5/sdkconfig index e3fc638ec05..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_lcd_ev_v1.5/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_lcd_ev_v1.5/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3-lcd-ev-v1.5" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c index 94d08bb56c8..96513a14741 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/board.c @@ -7,6 +7,7 @@ #include "supervisor/board.h" #include "mpconfigboard.h" #include "shared-bindings/microcontroller/Pin.h" +#include "driver/gpio.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/fourwire/FourWire.h" @@ -59,9 +60,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO8, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk index 947b689fafe..b0abc221418 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/sdkconfig b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/sdkconfig +++ b/ports/espressif/boards/espressif_esp32s3_usb_otg_n8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/mpconfigboard.mk b/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/mpconfigboard.mk index 0925e8de64d..3631493c267 100644 --- a/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/mpconfigboard.mk @@ -6,3 +6,6 @@ IDF_TARGET = esp32c2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 60m CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/sdkconfig b/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/sdkconfig index cf803dfc43a..f53dd7f8795 100644 --- a/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/sdkconfig +++ b/ports/espressif/boards/espressif_esp8684_devkitc_02_n4/sdkconfig @@ -32,7 +32,6 @@ CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp8684" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk b/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk index d00bf432c97..cb766aa2312 100644 --- a/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/espressif_saola_1_wroom/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/firebeetle2_esp32s3/sdkconfig b/ports/espressif/boards/firebeetle2_esp32s3/sdkconfig index 6c5d1f19866..49798548225 100644 --- a/ports/espressif/boards/firebeetle2_esp32s3/sdkconfig +++ b/ports/espressif/boards/firebeetle2_esp32s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" CONFIG_OV2640_SUPPORT=y CONFIG_OV7725_SUPPORT=y # end of LWIP diff --git a/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk b/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk index 1cc62cb69d4..7b4f1e9d1d2 100644 --- a/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/franzininho_wifi_wroom/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk index a06ac482090..a77626e5104 100644 --- a/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_m/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/gravitech_cucumber_m/sdkconfig b/ports/espressif/boards/gravitech_cucumber_m/sdkconfig index ec6db5c72ea..e9628662160 100644 --- a/ports/espressif/boards/gravitech_cucumber_m/sdkconfig +++ b/ports/espressif/boards/gravitech_cucumber_m/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_m" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk index 1cdf6273bee..f593b77cfff 100644 --- a/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk +++ b/ports/espressif/boards/gravitech_cucumber_ms/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/gravitech_cucumber_ms/sdkconfig b/ports/espressif/boards/gravitech_cucumber_ms/sdkconfig index f3cc39cc678..e9628662160 100644 --- a/ports/espressif/boards/gravitech_cucumber_ms/sdkconfig +++ b/ports/espressif/boards/gravitech_cucumber_ms/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_ms" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/gravitech_cucumber_r/sdkconfig b/ports/espressif/boards/gravitech_cucumber_r/sdkconfig index e817a86205a..e9628662160 100644 --- a/ports/espressif/boards/gravitech_cucumber_r/sdkconfig +++ b/ports/espressif/boards/gravitech_cucumber_r/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_r" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/gravitech_cucumber_rs/sdkconfig b/ports/espressif/boards/gravitech_cucumber_rs/sdkconfig index 873eb7207a0..e9628662160 100644 --- a/ports/espressif/boards/gravitech_cucumber_rs/sdkconfig +++ b/ports/espressif/boards/gravitech_cucumber_rs/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="cucumber_rs" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/hardkernel_odroid_go/board.c b/ports/espressif/boards/hardkernel_odroid_go/board.c index 647fcd740eb..0c2fe8a87c3 100644 --- a/ports/espressif/boards/hardkernel_odroid_go/board.c +++ b/ports/espressif/boards/hardkernel_odroid_go/board.c @@ -6,6 +6,7 @@ #include "supervisor/board.h" #include "mpconfigboard.h" +#include "driver/gpio.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/fourwire/FourWire.h" #include "shared-module/displayio/__init__.h" @@ -51,9 +52,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO21, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO21), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/board.c b/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/board.c index 317fb0d88a1..d0ae1465042 100644 --- a/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/board.c +++ b/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/board.c @@ -34,10 +34,10 @@ uint8_t display_init_sequence[] = { // SSD1306 digitalio_digitalinout_obj_t display_on; static void display_init(void) { - // Need to bring GPIO21 high or the screen doesn't get power + // Need to bring GPIO36 high or the screen doesn't get power // & the board can't see the i2c bus at all. - common_hal_digitalio_digitalinout_construct(&display_on, &pin_GPIO21); - common_hal_digitalio_digitalinout_switch_to_output(&display_on, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_construct(&display_on, &pin_GPIO36); + common_hal_digitalio_digitalinout_switch_to_output(&display_on, false, DRIVE_MODE_PUSH_PULL); common_hal_digitalio_digitalinout_never_reset(&display_on); busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); @@ -48,7 +48,7 @@ static void display_init(void) { bus, i2c, 0x3c, - NULL + &pin_GPIO21 // broken-out on V3 ); busdisplay_busdisplay_obj_t *display = &allocate_display()->display; diff --git a/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/mpconfigboard.mk b/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/mpconfigboard.mk index 633cca09823..d5cbac7ea59 100644 --- a/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/mpconfigboard.mk +++ b/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/mpconfigboard.mk @@ -20,10 +20,5 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 - -CIRCUITPY_DISPLAYIO = 1 - FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Shapes FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_RFM9x diff --git a/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/sdkconfig b/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/sdkconfig index ab4e9875add..a71099850d5 100644 --- a/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/sdkconfig +++ b/ports/espressif/boards/heltec_esp32s3_wifi_lora_v3/sdkconfig @@ -8,7 +8,6 @@ # LWIP # CONFIG_ESP_PHY_ENABLE_USB=n -CONFIG_LWIP_LOCAL_HOSTNAME="HELTEC-ESP32S3-V3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/heltec_vision_master_e290/board.c b/ports/espressif/boards/heltec_vision_master_e290/board.c new file mode 100644 index 00000000000..5a102c7119b --- /dev/null +++ b/ports/espressif/boards/heltec_vision_master_e290/board.c @@ -0,0 +1,107 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +const uint8_t display_start_sequence[] = { + 0x12, 0x80, 0x14, // Soft reset and wait 20ms + 0x11, 0x01, 0x03, // Ram data entry mode + 0x3c, 0x01, 0x05, // border color + 0x2c, 0x01, 0x36, // set vcom voltage + 0x03, 0x01, 0x17, // Set gate voltage + 0x04, 0x03, 0x41, 0x00, 0x32, // Set source voltage + 0x4e, 0x01, 0x01, // ram x count + 0x4f, 0x02, 0x00, 0x00, // ram y count + 0x01, 0x03, 0x27, 0x01, 0x00, // set display size + 0x22, 0x01, 0xf4, // display update mode +}; + +const uint8_t display_stop_sequence[] = { + 0x10, 0x81, 0x01, 0x64, // Deep sleep +}; + +const uint8_t refresh_sequence[] = { + 0x20, +}; + +void board_init(void) { + + // Set vext high to enable EPD + digitalio_digitalinout_obj_t vext_pin_obj; + vext_pin_obj.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&vext_pin_obj, &pin_GPIO18); + common_hal_digitalio_digitalinout_switch_to_output(&vext_pin_obj, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&vext_pin_obj); + + // Set up the SPI object used to control the display + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO2, &pin_GPIO1, NULL, false); + common_hal_busio_spi_never_reset(spi); + + // Set up the DisplayIO pin object + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO4), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO3), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO5), // EPD_RST Reset + 1000000, // Baudrate + 0, // Polarity + 0); // Phase + + // Set up the DisplayIO epaper object + epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; + display->base.type = &epaperdisplay_epaperdisplay_type; + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 250; + args.ram_height = 296; + args.colstart = 8; + args.rotation = 90; + args.set_column_window_command = 0x44; + args.set_row_window_command = 0x45; + args.set_current_column_command = 0x4E; + args.set_current_row_command = 0x4F; + args.write_black_ram_command = 0x24; + args.write_color_ram_command = 0x26; + args.highlight_color = 0xFF0000; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO6; + args.busy_state = true; + args.seconds_per_frame = 2.0; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); +} + +void board_deinit(void) { + epaperdisplay_epaperdisplay_obj_t *display = &displays[0].epaper_display; + if (display->base.type == &epaperdisplay_epaperdisplay_type) { + while (common_hal_epaperdisplay_epaperdisplay_get_busy(display)) { + RUN_BACKGROUND_TASKS; + } + } + common_hal_displayio_release_displays(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/heltec_vision_master_e290/mpconfigboard.h b/ports/espressif/boards/heltec_vision_master_e290/mpconfigboard.h new file mode 100644 index 00000000000..f46fcf30cd6 --- /dev/null +++ b/ports/espressif/boards/heltec_vision_master_e290/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Heltec Vison Master E290" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN { \ + {.clock = &pin_GPIO2, .mosi = &pin_GPIO1, .miso = NULL}, \ + {.clock = &pin_GPIO9, .mosi = &pin_GPIO10, .miso = &pin_GPIO11}, \ +} + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN { \ + {.scl = &pin_GPIO38, .sda = &pin_GPIO39}, \ +} + +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) diff --git a/ports/espressif/boards/heltec_vision_master_e290/mpconfigboard.mk b/ports/espressif/boards/heltec_vision_master_e290/mpconfigboard.mk new file mode 100644 index 00000000000..e5ab355fee9 --- /dev/null +++ b/ports/espressif/boards/heltec_vision_master_e290/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x82C9 +USB_PRODUCT = "Vision Master E290" +USB_MANUFACTURER = "Heltec" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/heltec_vision_master_e290/pins.c b/ports/espressif/boards/heltec_vision_master_e290/pins.c new file mode 100644 index 00000000000..9fb7b797fb1 --- /dev/null +++ b/ports/espressif/boards/heltec_vision_master_e290/pins.c @@ -0,0 +1,77 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(epd_spi, spi, 0) +CIRCUITPY_BOARD_BUS_SINGLETON(lora_spi, spi, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // User buttons + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO21) }, + + // LED + { MP_ROM_QSTR(MP_QSTR_LED0), MP_ROM_PTR(&pin_GPIO45) }, + + // ADC (When ADC_CTRL is high, VBAT is connected to ADC_IN with 390K/100K voltage divider) + { MP_ROM_QSTR(MP_QSTR_ADC_CTRL), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_ADC_IN), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO7) }, + + // VEXT powers epd and lora antenna boost when high + { MP_ROM_QSTR(MP_QSTR_VEXT_CTRL), MP_ROM_PTR(&pin_GPIO18) }, + + // LORA SPI, Reset, and More + { MP_ROM_QSTR(MP_QSTR_LORA_CS), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_LORA_SCK), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LORA_MOSI), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LORA_MISO), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LORA_RESET), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LORA_BUSY), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LORA_DIO1), MP_ROM_PTR(&pin_GPIO14) }, + + // eInk Display + { MP_ROM_QSTR(MP_QSTR_EPD_MOSI), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_EPD_SCK), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_EPD_CS), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_EPD_DC), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_EPD_RESET), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_EPD_BUSY), MP_ROM_PTR(&pin_GPIO6) }, + + // I2C on external connector P2 + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO39) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // User available pins on GPIO header + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, // BOOT pin (IO0) is on header + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + // objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_EPD_SPI), MP_ROM_PTR(&board_epd_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_LORA_SPI), MP_ROM_PTR(&board_lora_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].epaper_display)}, + +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/heltec_vision_master_e290/sdkconfig b/ports/espressif/boards/heltec_vision_master_e290/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/heltec_vision_master_e290/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/heltec_wireless_paper/board.c b/ports/espressif/boards/heltec_wireless_paper/board.c new file mode 100644 index 00000000000..38f6472e085 --- /dev/null +++ b/ports/espressif/boards/heltec_wireless_paper/board.c @@ -0,0 +1,139 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +const uint8_t display_start_sequence[] = { + 0x04, 0x80, 0xc8, // power on + 0x00, 0x01, 0x1f, // panel setting + 0x50, 0x01, 0x97, // CDI setting + + // common voltage + 0x20, 0x2a, + 0x00, 0x0A, 0x00, 0x00, 0x00, 0x01, + 0x60, 0x14, 0x14, 0x00, 0x00, 0x01, + 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x13, 0x0A, 0x01, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // White to White + 0x21, 0x2a, + 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01, + 0x90, 0x14, 0x14, 0x00, 0x00, 0x01, + 0x10, 0x14, 0x0A, 0x00, 0x00, 0x01, + 0xA0, 0x13, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Black to White + 0x22, 0x2a, + 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01, + 0x90, 0x14, 0x14, 0x00, 0x00, 0x01, + 0x00, 0x14, 0x0A, 0x00, 0x00, 0x01, + 0x99, 0x0B, 0x04, 0x04, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // White to Black + 0x23, 0x2a, + 0x40, 0x0A, 0x00, 0x00, 0x00, 0x01, + 0x90, 0x14, 0x14, 0x00, 0x00, 0x01, + 0x00, 0x14, 0x0A, 0x00, 0x00, 0x01, + 0x99, 0x0C, 0x01, 0x03, 0x04, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // Black to Black + 0x24, 0x2a, + 0x80, 0x0A, 0x00, 0x00, 0x00, 0x01, + 0x90, 0x14, 0x14, 0x00, 0x00, 0x01, + 0x20, 0x14, 0x0A, 0x00, 0x00, 0x01, + 0x50, 0x13, 0x01, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +const uint8_t display_stop_sequence[] = { + 0x50, 0x01, 0xf7, + 0x07, 0x01, 0xa5, +}; + +const uint8_t refresh_sequence[] = { + 0x12, +}; + +void board_init(void) { + + // Set vext on (active low) to enable EPD + digitalio_digitalinout_obj_t vext_pin_obj; + vext_pin_obj.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&vext_pin_obj, &pin_GPIO45); + common_hal_digitalio_digitalinout_switch_to_output(&vext_pin_obj, false, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&vext_pin_obj); + + // Set up the SPI object used to control the display + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO3, &pin_GPIO2, NULL, false); + common_hal_busio_spi_never_reset(spi); + + // Set up the DisplayIO pin object + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO5), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO4), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO6), // EPD_RST Reset + 1000000, // Baudrate + 0, // Polarity + 0); // Phase + + // Set up the DisplayIO epaper object + epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; + display->base.type = &epaperdisplay_epaperdisplay_type; + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 250; + args.height = 122; + args.ram_width = 128; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = 0x13; + args.write_color_ram_command = 0x10; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO7; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); +} + +void board_deinit(void) { + epaperdisplay_epaperdisplay_obj_t *display = &displays[0].epaper_display; + if (display->base.type == &epaperdisplay_epaperdisplay_type) { + while (common_hal_epaperdisplay_epaperdisplay_get_busy(display)) { + RUN_BACKGROUND_TASKS; + } + } + common_hal_displayio_release_displays(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/heltec_wireless_paper/mpconfigboard.h b/ports/espressif/boards/heltec_wireless_paper/mpconfigboard.h new file mode 100644 index 00000000000..0c54e3276c5 --- /dev/null +++ b/ports/espressif/boards/heltec_wireless_paper/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Heltec Wireless Paper" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN { \ + {.clock = &pin_GPIO3, .mosi = &pin_GPIO2, .miso = NULL}, \ + {.clock = &pin_GPIO9, .mosi = &pin_GPIO10, .miso = &pin_GPIO11}, \ +} + +// UART definition for UART connected to the CP210x +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Serial over UART +#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX +#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX diff --git a/ports/espressif/boards/heltec_wireless_paper/mpconfigboard.mk b/ports/espressif/boards/heltec_wireless_paper/mpconfigboard.mk new file mode 100644 index 00000000000..35a9ac1402e --- /dev/null +++ b/ports/espressif/boards/heltec_wireless_paper/mpconfigboard.mk @@ -0,0 +1,21 @@ +# Product URL: https://heltec.org/project/wifi-lora-32-v3/ +# Schematic: https://resource.heltec.cn/download/WiFi_LoRa32_V3/HTIT-WB32LA(F)_V3_Schematic_Diagram.pdf +# Datasheet: https://resource.heltec.cn/download/WiFi_LoRa32_V3/HTIT-WB32LA_V3(Rev1.1).pdf +# Pinout: https://resource.heltec.cn/download/WiFi_LoRa32_V3/HTIT-WB32LA(F)_V3.png + +CIRCUITPY_CREATOR_ID = 0x148E173C +CIRCUITPY_CREATION_ID = 0x00530002 + +USB_PRODUCT = "Heltec-Wireless-Paper" +USB_MANUFACTURER = "Heltec" + +IDF_TARGET = esp32s3 + +# This board doesn't have USB by default, it +# instead uses a CP2102 USB-to-Serial chip +CIRCUITPY_USB_DEVICE = 0 +CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/heltec_wireless_paper/pins.c b/ports/espressif/boards/heltec_wireless_paper/pins.c new file mode 100644 index 00000000000..908fd0f5dac --- /dev/null +++ b/ports/espressif/boards/heltec_wireless_paper/pins.c @@ -0,0 +1,55 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Sole programmable button + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + + // LED + { MP_ROM_QSTR(MP_QSTR_LED0), MP_ROM_PTR(&pin_GPIO18) }, + + // ADC (When ADC_CTRL is low, VBAT is connected to ADC_IN with 10K/10K voltage divider) + { MP_ROM_QSTR(MP_QSTR_ADC_CTRL), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_ADC_IN), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO20) }, + + // VEXT powers epd and lora antenna boost when low + { MP_ROM_QSTR(MP_QSTR_VEXT_CTRL), MP_ROM_PTR(&pin_GPIO45) }, + + // UART that's connected to CP210x over USB + { MP_ROM_QSTR(MP_QSTR_DEBUG_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_DEBUG_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // LORA SPI, Reset, and More + { MP_ROM_QSTR(MP_QSTR_LORA_CS), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_LORA_SCK), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LORA_MOSI), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LORA_MISO), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LORA_RESET), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LORA_BUSY), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LORA_DIO1), MP_ROM_PTR(&pin_GPIO14) }, + + // eInk Display + { MP_ROM_QSTR(MP_QSTR_EPD_MOSI), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_EPD_SCK), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_EPD_CS), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_EPD_DC), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_EPD_RES), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_EPD_BUSY), MP_ROM_PTR(&pin_GPIO7) }, + + // objects + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].epaper_display)}, + +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/heltec_wireless_paper/sdkconfig b/ports/espressif/boards/heltec_wireless_paper/sdkconfig new file mode 100644 index 00000000000..a71099850d5 --- /dev/null +++ b/ports/espressif/boards/heltec_wireless_paper/sdkconfig @@ -0,0 +1,15 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +CONFIG_ESP_PHY_ENABLE_USB=n +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/hexky_s2/board.c b/ports/espressif/boards/hexky_s2/board.c index c1e1801fed6..41f97796be4 100644 --- a/ports/espressif/boards/hexky_s2/board.c +++ b/ports/espressif/boards/hexky_s2/board.c @@ -57,9 +57,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO34, // DC - &pin_GPIO33, // CS - &pin_GPIO41, // RST + MP_OBJ_FROM_PTR(&pin_GPIO34), // DC + MP_OBJ_FROM_PTR(&pin_GPIO33), // CS + MP_OBJ_FROM_PTR(&pin_GPIO41), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/hexky_s2/mpconfigboard.mk b/ports/espressif/boards/hexky_s2/mpconfigboard.mk index 94d98aa8654..825d8721333 100644 --- a/ports/espressif/boards/hexky_s2/mpconfigboard.mk +++ b/ports/espressif/boards/hexky_s2/mpconfigboard.mk @@ -10,8 +10,8 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel - CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/hiibot_iots2/board.c b/ports/espressif/boards/hiibot_iots2/board.c index e9941cbc368..e3af7b45835 100644 --- a/ports/espressif/boards/hiibot_iots2/board.c +++ b/ports/espressif/boards/hiibot_iots2/board.c @@ -62,9 +62,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO35, // DC - &pin_GPIO36, // CS - NULL, // NO RST ? + MP_OBJ_FROM_PTR(&pin_GPIO35), // DC + MP_OBJ_FROM_PTR(&pin_GPIO36), // CS + mp_const_none, // NO RST ? 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk b/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk index 743acf85a45..3d3c584c702 100644 --- a/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk +++ b/ports/espressif/boards/hiibot_iots2/mpconfigboard.mk @@ -8,7 +8,6 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -#CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio diff --git a/ports/espressif/boards/hiibot_iots2/sdkconfig b/ports/espressif/boards/hiibot_iots2/sdkconfig index b2b83eb6e6c..e9628662160 100644 --- a/ports/espressif/boards/hiibot_iots2/sdkconfig +++ b/ports/espressif/boards/hiibot_iots2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="HiiBot_IoTs2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/ikea_alpstuga_esp32_s3/board.c b/ports/espressif/boards/ikea_alpstuga_esp32_s3/board.c new file mode 100644 index 00000000000..6d735a9b031 --- /dev/null +++ b/ports/espressif/boards/ikea_alpstuga_esp32_s3/board.c @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "driver/gpio.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/ikea_alpstuga_esp32_s3/mpconfigboard.h b/ports/espressif/boards/ikea_alpstuga_esp32_s3/mpconfigboard.h new file mode 100644 index 00000000000..9a826047351 --- /dev/null +++ b/ports/espressif/boards/ikea_alpstuga_esp32_s3/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Ikea Alpstuga Drop-In ESP32S3 4MB Flash 2MB PSRAM" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO33) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO9) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO3) + +#define DOUBLE_TAP_PIN (&pin_GPIO34) diff --git a/ports/espressif/boards/ikea_alpstuga_esp32_s3/mpconfigboard.mk b/ports/espressif/boards/ikea_alpstuga_esp32_s3/mpconfigboard.mk new file mode 100644 index 00000000000..fbfb0f1ed3f --- /dev/null +++ b/ports/espressif/boards/ikea_alpstuga_esp32_s3/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x239A +USB_PID = 0x8178 +USB_PRODUCT = "Ikea Alpstuga Drop-In ESP32S3 4MB Flash 2MB PSRAM" +USB_MANUFACTURER = "Adafruit" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/ikea_alpstuga_esp32_s3/pins.c b/ports/espressif/boards/ikea_alpstuga_esp32_s3/pins.c new file mode 100644 index 00000000000..20991f032bd --- /dev/null +++ b/ports/espressif/boards/ikea_alpstuga_esp32_s3/pins.c @@ -0,0 +1,38 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_1), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_2), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_3), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/ikea_alpstuga_esp32_s3/sdkconfig b/ports/espressif/boards/ikea_alpstuga_esp32_s3/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/ikea_alpstuga_esp32_s3/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/lilygo_tdeck/board.c b/ports/espressif/boards/lilygo_tdeck/board.c index f2b3ebb12c8..45b889760a1 100644 --- a/ports/espressif/boards/lilygo_tdeck/board.c +++ b/ports/espressif/boards/lilygo_tdeck/board.c @@ -32,9 +32,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO11, // TFT_DC Command or data - &pin_GPIO12, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO11), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO12), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase @@ -72,4 +72,13 @@ void board_init(void) { 50000); // backlight pwm frequency } +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + if (pin_number == 10) { + // Pull screen power high + config_pin_as_output_with_level(pin_number, true); + return true; + } + return false; +} + // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_tdeck/mpconfigboard.h b/ports/espressif/boards/lilygo_tdeck/mpconfigboard.h index aca85d815e0..48bca4a2d0e 100644 --- a/ports/espressif/boards/lilygo_tdeck/mpconfigboard.h +++ b/ports/espressif/boards/lilygo_tdeck/mpconfigboard.h @@ -8,7 +8,7 @@ // Micropython setup -#define MICROPY_HW_BOARD_NAME "LILYGO T-DECK" +#define MICROPY_HW_BOARD_NAME "LILYGO T-Deck (Plus)" #define MICROPY_HW_MCU_NAME "ESP32S3" #define DEFAULT_SPI_BUS_SCK (&pin_GPIO40) diff --git a/ports/espressif/boards/lilygo_tdeck/mpconfigboard.mk b/ports/espressif/boards/lilygo_tdeck/mpconfigboard.mk index 52399a81d66..fc30e96c793 100644 --- a/ports/espressif/boards/lilygo_tdeck/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_tdeck/mpconfigboard.mk @@ -1,6 +1,6 @@ USB_VID = 0x303A USB_PID = 0x81B6 -USB_PRODUCT = "T DECK" +USB_PRODUCT = "T-Deck (Plus)" USB_MANUFACTURER = "LILYGO" IDF_TARGET = esp32s3 @@ -12,3 +12,13 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Few pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_MAX3421E = 0 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_ROTARYIO = 0 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_FocalTouch +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/espressif/boards/lilygo_tdeck/pins.c b/ports/espressif/boards/lilygo_tdeck/pins.c index 256c1453149..fe489d4561a 100644 --- a/ports/espressif/boards/lilygo_tdeck/pins.c +++ b/ports/espressif/boards/lilygo_tdeck/pins.c @@ -10,99 +10,117 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, - { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, - { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, - { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, - { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, - { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, - { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, - { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, - { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, - { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, - { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, - { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + // SPI + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, - { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, - { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, - { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, - { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, - { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, - - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, - // SPI control pins - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO40) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - // I2C control pins + // I2C { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - // TFT control pins + // Display { MP_ROM_QSTR(MP_QSTR_TFT_BKLT), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, - // SD card control pins + // SD card { MP_ROM_QSTR(MP_QSTR_SDCARD_CS), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, // Input Interrupts { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_KEYBOARD_INT), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, // Trackball control pins { MP_ROM_QSTR(MP_QSTR_TRACKBALL_CLICK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TRACKBALL_UP), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_TRACKBALL_DOWN), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_TRACKBALL_LEFT), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_TRACKBALL_RIGHT), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, // Microphone control pins { MP_ROM_QSTR(MP_QSTR_MICROPHONE_SCK), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_WS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_DIN), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_MICROPHONE_MCK), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, // Speaker control pins { MP_ROM_QSTR(MP_QSTR_SPEAKER_SCK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER_WS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER_DOUT), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, // LoRa control pins { MP_ROM_QSTR(MP_QSTR_LORA_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LORA_DIO1), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_LORA_RST), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LORA_BUSY), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, // Battery and Peripheral Power { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_POWER_ON), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + // Port, used for GPS + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, - { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_tdeck/sdkconfig b/ports/espressif/boards/lilygo_tdeck/sdkconfig index 35bfb64a016..e9628662160 100644 --- a/ports/espressif/boards/lilygo_tdeck/sdkconfig +++ b/ports/espressif/boards/lilygo_tdeck/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="T-DECK" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_tdisplay_s3/board.c b/ports/espressif/boards/lilygo_tdisplay_s3/board.c index fe62edf1ed8..a02dab7173d 100644 --- a/ports/espressif/boards/lilygo_tdisplay_s3/board.c +++ b/ports/espressif/boards/lilygo_tdisplay_s3/board.c @@ -6,6 +6,7 @@ #include "supervisor/board.h" #include "mpconfigboard.h" +#include "driver/gpio.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-module/displayio/__init__.h" #include "shared-module/displayio/mipi_constants.h" diff --git a/ports/espressif/boards/lilygo_tdisplay_s3/sdkconfig b/ports/espressif/boards/lilygo_tdisplay_s3/sdkconfig index 7c974337593..e9628662160 100644 --- a/ports/espressif/boards/lilygo_tdisplay_s3/sdkconfig +++ b/ports/espressif/boards/lilygo_tdisplay_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="T-DISPLAY-S3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c b/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c index ede20df200f..0782e2161ca 100644 --- a/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c +++ b/ports/espressif/boards/lilygo_tdisplay_s3_pro/board.c @@ -34,9 +34,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO9, // TFT_DC Command or data - &pin_GPIO39, // TFT_CS Chip select - &pin_GPIO47, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO39), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO47), // TFT_RST Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/lilygo_tdisplay_s3_pro/sdkconfig b/ports/espressif/boards/lilygo_tdisplay_s3_pro/sdkconfig index 03805d7f206..a12cbe62f14 100644 --- a/ports/espressif/boards/lilygo_tdisplay_s3_pro/sdkconfig +++ b/ports/espressif/boards/lilygo_tdisplay_s3_pro/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="T-Display S3 Pro" # end of LWIP # diff --git a/ports/espressif/boards/lilygo_tdongle_s3/board.c b/ports/espressif/boards/lilygo_tdongle_s3/board.c new file mode 100644 index 00000000000..47fef9ee214 --- /dev/null +++ b/ports/espressif/boards/lilygo_tdongle_s3/board.c @@ -0,0 +1,111 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#define DELAY 0x80 + +// display init sequence according to Adafruit_CircuitPython_ST7735R +// https://github.com/adafruit/Adafruit_CircuitPython_ST7735R +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 0x96, + // SLPOUT and Delay + 0x11, 0 | DELAY, 0xFF, + 0xB1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xB3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xB4, 0x01, 0x07, // _INVCTR line inversion + 0xC0, 0x03, 0xA2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xC1, 0x01, 0xC5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xC2, 0x02, 0x0A, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xC3, 0x02, 0x8A, 0x2A, + 0xC4, 0x02, 0x8A, 0xEE, + 0xC5, 0x01, 0x0E, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x20, 0x00, // _INVOFF + 0x36, 0x01, 0x18, // _MADCTL bottom to top refresh + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle osc equalie, + // fix on VTL + 0x3A, 0x01, 0x05, // COLMOD - 16bit color + 0xE0, 0x10, 0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xE1, 0x10, 0x03, 0x1D, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0 | DELAY, 0x0A, // _NORON + 0x29, 0 | DELAY, 0x64, // _DISPON + // 0x36, 0x01, 0xC0, // _MADCTL Default rotation plus BGR encoding + 0x36, 0x01, 0xC8, // _MADCTL Default rotation plus RGB encoding + 0x21, 0x00, // _INVON +}; + +static void display_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + + common_hal_busio_spi_construct( + spi, + &pin_GPIO5, // CLK + &pin_GPIO3, // MOSI + NULL, // MISO not connected + false); // Not half-duplex + + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO2), // DC + MP_OBJ_FROM_PTR(&pin_GPIO4), // CS + MP_OBJ_FROM_PTR(&pin_GPIO1), // RST + 10000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 160, // width (after rotation) + 80, // height (after rotation) + 26, // column start + 1, // row start + 90, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO38, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + false, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lilygo_tdongle_s3/mpconfigboard.h b/ports/espressif/boards/lilygo_tdongle_s3/mpconfigboard.h new file mode 100644 index 00000000000..a987bac317b --- /dev/null +++ b/ports/espressif/boards/lilygo_tdongle_s3/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "LILYGO T-Dongle S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_APA102_MOSI (&pin_GPIO40) +#define MICROPY_HW_APA102_SCK (&pin_GPIO39) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO44) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/lilygo_tdongle_s3/mpconfigboard.mk b/ports/espressif/boards/lilygo_tdongle_s3/mpconfigboard.mk new file mode 100644 index 00000000000..bc883366b5d --- /dev/null +++ b/ports/espressif/boards/lilygo_tdongle_s3/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x303a +USB_PID = 0x82C2 +USB_PRODUCT = "T-Dongle S3" +USB_MANUFACTURER = "LILYGO" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +# Few pins. +CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lilygo_tdongle_s3/pins.c b/ports/espressif/boards/lilygo_tdongle_s3/pins.c new file mode 100644 index 00000000000..42fd1424cc6 --- /dev/null +++ b/ports/espressif/boards/lilygo_tdongle_s3/pins.c @@ -0,0 +1,65 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // 1 to 1 mappings + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + + // Reset Button + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + + // RX and TX + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // Stemma port (if available) + { MP_ROM_QSTR(MP_QSTR_STEMMA_SDA), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_SCL), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // 0.96 inch LCD ST7735 + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DIN), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + + // APA102 control pins (Leds) + { MP_ROM_QSTR(MP_QSTR_APA102_CLK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_APA102_DI), MP_ROM_PTR(&pin_GPIO40) }, + + // SD card control pins + { MP_ROM_QSTR(MP_QSTR_SD_D0), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SD_D1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SD_D2), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SD_D3), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO16) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_tdongle_s3/sdkconfig b/ports/espressif/boards/lilygo_tdongle_s3/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/lilygo_tdongle_s3/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/board.c b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c index b8dfc4d5b14..46e2ecf863c 100644 --- a/ports/espressif/boards/lilygo_tembed_esp32s3/board.c +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/board.c @@ -17,8 +17,9 @@ uint8_t display_init_sequence[] = { 0x01, 0x80, 0x96, // _SWRESET and Delay 150ms 0x11, 0x80, 0xFF, // _SLPOUT and Delay 500ms 0x3A, 0x81, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x21, 0x80, 0xA, // _INVON 0x13, 0x80, 0x0A, // _NORON and Delay 10ms - 0x36, 0x01, 0xC8, // _MADCTL + 0x36, 0x01, 0xC0, // _MADCTL 0x29, 0x80, 0xFF, // _DISPON and Delay 500ms }; @@ -31,9 +32,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO13, // TFT_DC Command or data - &pin_GPIO10, // TFT_CS Chip select - &pin_GPIO9, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO13), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO10), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.h b/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.h index 18bf2ac67de..2ba9717b88d 100644 --- a/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.h +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/mpconfigboard.h @@ -11,7 +11,9 @@ #define MICROPY_HW_BOARD_NAME "LILYGO TEMBED ESP32S3" #define MICROPY_HW_MCU_NAME "ESP32S3" -#define MICROPY_HW_NEOPIXEL (&pin_GPIO48) +#define MICROPY_HW_APA102_MOSI (&pin_GPIO42) +#define MICROPY_HW_APA102_SCK (&pin_GPIO45) +#define MICROPY_HW_APA102_COUNT (7) #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) #define DEFAULT_SPI_BUS_SCK (&pin_GPIO12) diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/pins.c b/ports/espressif/boards/lilygo_tembed_esp32s3/pins.c index 58cf8a71e27..7984a829b16 100644 --- a/ports/espressif/boards/lilygo_tembed_esp32s3/pins.c +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/pins.c @@ -46,7 +46,6 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, - { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO48) }, { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, diff --git a/ports/espressif/boards/lilygo_tembed_esp32s3/sdkconfig b/ports/espressif/boards/lilygo_tembed_esp32s3/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/lilygo_tembed_esp32s3/sdkconfig +++ b/ports/espressif/boards/lilygo_tembed_esp32s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_tqt_pro_nopsram/board.c b/ports/espressif/boards/lilygo_tqt_pro_nopsram/board.c new file mode 100644 index 00000000000..fe72222a22c --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_nopsram/board.c @@ -0,0 +1,100 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 255, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, 0x68, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x29, 0 | DELAY, 255, +}; + + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO6), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO1), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 128, // width (after rotation) + 128, // height (after rotation) + 1, // column start + 2, // row start + 90, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO10, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + false, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} diff --git a/ports/espressif/boards/lilygo_tqt_pro_nopsram/mpconfigboard.h b/ports/espressif/boards/lilygo_tqt_pro_nopsram/mpconfigboard.h new file mode 100644 index 00000000000..6aa9ea30b9e --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_nopsram/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "LILYGO T-QT PRO NO PSRAM" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO44, .sda = &pin_GPIO43}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO3, .mosi = &pin_GPIO2}} diff --git a/ports/espressif/boards/lilygo_tqt_pro_nopsram/mpconfigboard.mk b/ports/espressif/boards/lilygo_tqt_pro_nopsram/mpconfigboard.mk new file mode 100644 index 00000000000..5c7ff943cb3 --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_nopsram/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303a +USB_PID = 0x8154 +USB_PRODUCT = "T-QT PRO NO PSRAM" +USB_MANUFACTURER = "LILYGO" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +# Not enough pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/lilygo_tqt_pro_nopsram/pins.c b/ports/espressif/boards/lilygo_tqt_pro_nopsram/pins.c new file mode 100644 index 00000000000..e26e885ef54 --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_nopsram/pins.c @@ -0,0 +1,56 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // front buttons + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + + // Left side top to bottom + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + + // Right side top to bottom + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + // Stemma QT port + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // 0.85 inch LCD GC9107 + { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_spi_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_tqt_pro_nopsram/sdkconfig b/ports/espressif/boards/lilygo_tqt_pro_nopsram/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/lilygo_tqt_pro_psram/board.c b/ports/espressif/boards/lilygo_tqt_pro_psram/board.c new file mode 100644 index 00000000000..fe72222a22c --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_psram/board.c @@ -0,0 +1,100 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 150, + // sleep out + 0x11, 0 | DELAY, 255, + // normal display mode on + 0x13, 0, + // display and color format settings + 0x36, 1, 0x68, + 0xB6, 2, 0x0A, 0x82, + 0x3A, 1 | DELAY, 0x55, 10, + // ST7789V frame rate setting + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // voltages: VGH / VGL + 0xB7, 1, 0x35, + // ST7789V power setting + 0xBB, 1, 0x28, + 0xC0, 1, 0x0C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x10, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + // ST7789V gamma setting + 0xE0, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x32, 0x44, 0x42, 0x06, 0x0E, 0x12, 0x14, 0x17, + 0xE1, 14, 0xD0, 0x00, 0x02, 0x07, 0x0A, 0x28, 0x31, 0x54, 0x47, 0x0E, 0x1C, 0x17, 0x1B, 0x1E, + 0x21, 0, + // display on + 0x29, 0 | DELAY, 255, +}; + + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO6), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO1), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 128, // width (after rotation) + 128, // height (after rotation) + 1, // column start + 2, // row start + 90, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO10, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + false, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} diff --git a/ports/espressif/boards/lilygo_tqt_pro_psram/mpconfigboard.h b/ports/espressif/boards/lilygo_tqt_pro_psram/mpconfigboard.h new file mode 100644 index 00000000000..b0140b746ee --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_psram/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "LILYGO T-QT PRO PSRAM" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO44, .sda = &pin_GPIO43}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO3, .mosi = &pin_GPIO2}} diff --git a/ports/espressif/boards/lilygo_tqt_pro_psram/mpconfigboard.mk b/ports/espressif/boards/lilygo_tqt_pro_psram/mpconfigboard.mk new file mode 100644 index 00000000000..2006f98fbd7 --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_psram/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x303a +USB_PID = 0x8154 +USB_PRODUCT = "T-QT PRO PSRAM" +USB_MANUFACTURER = "LILYGO" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Not enough pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/lilygo_tqt_pro_psram/pins.c b/ports/espressif/boards/lilygo_tqt_pro_psram/pins.c new file mode 100644 index 00000000000..e26e885ef54 --- /dev/null +++ b/ports/espressif/boards/lilygo_tqt_pro_psram/pins.c @@ -0,0 +1,56 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // front buttons + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + + // Left side top to bottom + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + + // Right side top to bottom + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + // Stemma QT port + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // 0.85 inch LCD GC9107 + { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_spi_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lilygo_tqt_pro_psram/sdkconfig b/ports/espressif/boards/lilygo_tqt_pro_psram/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk index 0fd65d99d6e..8550c526def 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t-01c3/mpconfigboard.mk @@ -8,3 +8,6 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/lilygo_ttgo_t-01c3/sdkconfig b/ports/espressif/boards/lilygo_ttgo_t-01c3/sdkconfig index 54105bd51b3..e9628662160 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-01c3/sdkconfig +++ b/ports/espressif/boards/lilygo_ttgo_t-01c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="LILYGO TTGO T-01C3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.h b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.h index 247e58d916d..382f6e3f598 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.h +++ b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.h @@ -16,3 +16,6 @@ #define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX #define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk index d7eba6ea262..35ac1d44c62 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 diff --git a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/sdkconfig b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/sdkconfig index fc0f5c6edd2..e9628662160 100644 --- a/ports/espressif/boards/lilygo_ttgo_t-oi-plus/sdkconfig +++ b/ports/espressif/boards/lilygo_ttgo_t-oi-plus/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="LILYGO TTGO T-OI PLUS" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk index 0fbcf5c62bf..8cacf57efdf 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_t8_esp32_s2_wroom/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2/sdkconfig b/ports/espressif/boards/lilygo_ttgo_t8_s2/sdkconfig index 23f6593f1b2..e9628662160 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2/sdkconfig +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="TTGO-T8-ESP32-S2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c index 2b77e24b91e..6fcfb5c19a4 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/board.c @@ -62,9 +62,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO37, // DC - &pin_GPIO34, // CS - &pin_GPIO38, // RST + MP_OBJ_FROM_PTR(&pin_GPIO37), // DC + MP_OBJ_FROM_PTR(&pin_GPIO34), // CS + MP_OBJ_FROM_PTR(&pin_GPIO38), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/sdkconfig b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/sdkconfig index 23f6593f1b2..e9628662160 100644 --- a/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/sdkconfig +++ b/ports/espressif/boards/lilygo_ttgo_t8_s2_st7789/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="TTGO-T8-ESP32-S2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c index 97574398ca2..8ed5462a2d3 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/board.c @@ -42,9 +42,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO16, // DC - &pin_GPIO5, // CS - &pin_GPIO23, // RST + MP_OBJ_FROM_PTR(&pin_GPIO16), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO23), // RST 24000000, // baudrate (default from the driver) // 40000000, 0, // polarity diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk index dd177ec1c90..e76ffaba310 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/mpconfigboard.mk @@ -6,5 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig index 61beea449b1..e9628662160 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_16m/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="TTGO-TDISPLAY" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c index 2d3cb64d455..a90cc5eb66a 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/board.c @@ -41,9 +41,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO16, // DC - &pin_GPIO5, // CS - &pin_GPIO23, // RST + MP_OBJ_FROM_PTR(&pin_GPIO16), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO23), // RST 24000000, // baudrate (default from the driver) // 40000000, 0, // polarity diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/mpconfigboard.mk b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/mpconfigboard.mk index af1bd8b1789..8e89a6a2b3a 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/sdkconfig b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/sdkconfig index 61beea449b1..e9628662160 100644 --- a/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/sdkconfig +++ b/ports/espressif/boards/lilygo_ttgo_tdisplay_esp32_4m/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="TTGO-TDISPLAY" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c index 266515c2338..5ea85ec00c6 100644 --- a/ports/espressif/boards/lilygo_twatch_2020_v3/board.c +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/board.c @@ -46,9 +46,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO5, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + mp_const_none, // RST 24000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig b/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig index d1e302072ae..e69de29bb2d 100644 --- a/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig +++ b/ports/espressif/boards/lilygo_twatch_2020_v3/sdkconfig @@ -1,22 +0,0 @@ -# -# Espressif IoT Development Framework Configuration -# -# -# Component config -# -# -# ESP System Settings -# -CONFIG_ESP_CONSOLE_UART_CUSTOM=y -# CONFIG_ESP_CONSOLE_NONE is not set -CONFIG_ESP_CONSOLE_UART=y -CONFIG_ESP_CONSOLE_UART_CUSTOM_NUM_0=y -CONFIG_ESP_CONSOLE_UART_NUM=0 -CONFIG_ESP_CONSOLE_UART_TX_GPIO=1 -CONFIG_ESP_CONSOLE_UART_RX_GPIO=3 -CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 -# end of ESP System Settings - -# end of Component config - -# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/lilygo_twatch_s3/board.c b/ports/espressif/boards/lilygo_twatch_s3/board.c index 51f5933d177..a9fd3db46e7 100644 --- a/ports/espressif/boards/lilygo_twatch_s3/board.c +++ b/ports/espressif/boards/lilygo_twatch_s3/board.c @@ -108,9 +108,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO38, // DC - &pin_GPIO12, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO38), // DC + MP_OBJ_FROM_PTR(&pin_GPIO12), // CS + mp_const_none, // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/lilygo_twatch_s3/mpconfigboard.mk b/ports/espressif/boards/lilygo_twatch_s3/mpconfigboard.mk index 5d63032d5bf..1d3154c1826 100644 --- a/ports/espressif/boards/lilygo_twatch_s3/mpconfigboard.mk +++ b/ports/espressif/boards/lilygo_twatch_s3/mpconfigboard.mk @@ -10,6 +10,11 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Specialized board. CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_PARALLELDISPLAYBUS = 0 CIRCUITPY_MAX3421E = 0 @@ -19,10 +24,6 @@ CIRCUITPY_PS2IO = 0 CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_ROTARYIO = 0 -CIRCUITPY_ESP_PSRAM_SIZE = 8MB -CIRCUITPY_ESP_PSRAM_MODE = opi -CIRCUITPY_ESP_PSRAM_FREQ = 80m - # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_FocalTouch FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_IRRemote diff --git a/ports/espressif/boards/lilygo_twatch_s3/sdkconfig b/ports/espressif/boards/lilygo_twatch_s3/sdkconfig index 08b2b772c5c..e9628662160 100644 --- a/ports/espressif/boards/lilygo_twatch_s3/sdkconfig +++ b/ports/espressif/boards/lilygo_twatch_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="t-watch-s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk index 36dc38883ff..99c910e6d24 100644 --- a/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_c3_mini/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE=qio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/lolin_c3_mini/sdkconfig b/ports/espressif/boards/lolin_c3_mini/sdkconfig index 932a4a2cbd0..e9628662160 100644 --- a/ports/espressif/boards/lolin_c3_mini/sdkconfig +++ b/ports/espressif/boards/lolin_c3_mini/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="lolin-c3-mini" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lolin_c3_pico/mpconfigboard.h b/ports/espressif/boards/lolin_c3_pico/mpconfigboard.h index 24800307223..6ee4cd4cf95 100644 --- a/ports/espressif/boards/lolin_c3_pico/mpconfigboard.h +++ b/ports/espressif/boards/lolin_c3_pico/mpconfigboard.h @@ -26,3 +26,6 @@ #define CIRCUITPY_BOARD_UART (1) #define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}} + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/lolin_c3_pico/mpconfigboard.mk b/ports/espressif/boards/lolin_c3_pico/mpconfigboard.mk index 25027d4c97b..6778550a2d1 100644 --- a/ports/espressif/boards/lolin_c3_pico/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_c3_pico/mpconfigboard.mk @@ -7,12 +7,7 @@ CIRCUITPY_ESP_FLASH_MODE=qio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 -# Not enough flash -CIRCUITPY_SOCKETPOOL_IPV6 = 0 - # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/lolin_c3_pico/sdkconfig b/ports/espressif/boards/lolin_c3_pico/sdkconfig index ba2885933e7..e9628662160 100644 --- a/ports/espressif/boards/lolin_c3_pico/sdkconfig +++ b/ports/espressif/boards/lolin_c3_pico/sdkconfig @@ -7,8 +7,6 @@ # # LWIP # -# CONFIG_LWIP_IPV6 is not set -CONFIG_LWIP_LOCAL_HOSTNAME="lolin-c3-pico" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lolin_s2_mini/sdkconfig b/ports/espressif/boards/lolin_s2_mini/sdkconfig index ac239ca333e..e9628662160 100644 --- a/ports/espressif/boards/lolin_s2_mini/sdkconfig +++ b/ports/espressif/boards/lolin_s2_mini/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="LS2Mini" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lolin_s2_pico/sdkconfig b/ports/espressif/boards/lolin_s2_pico/sdkconfig index c2238c68143..e9628662160 100644 --- a/ports/espressif/boards/lolin_s2_pico/sdkconfig +++ b/ports/espressif/boards/lolin_s2_pico/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="Lolin-S2Pico" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lolin_s3/mpconfigboard.mk b/ports/espressif/boards/lolin_s3/mpconfigboard.mk index fbcdece670b..a86dd6578bd 100644 --- a/ports/espressif/boards/lolin_s3/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_s3/mpconfigboard.mk @@ -12,5 +12,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lolin_s3/sdkconfig b/ports/espressif/boards/lolin_s3/sdkconfig index b90e3fa57ed..e9628662160 100644 --- a/ports/espressif/boards/lolin_s3/sdkconfig +++ b/ports/espressif/boards/lolin_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="LOLIN-S3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lolin_s3_mini/mpconfigboard.mk b/ports/espressif/boards/lolin_s3_mini/mpconfigboard.mk index f58218d5e6b..fff6cae6d33 100644 --- a/ports/espressif/boards/lolin_s3_mini/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_s3_mini/mpconfigboard.mk @@ -13,10 +13,5 @@ CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m -CIRCUITPY_ESPCAMERA = 0 -CIRCUITPY_BITMAPFILTER = 0 -CIRCUITPY_CODEOP = 0 -CIRCUITPY_PARALLELDISPLAYBUS = 0 - # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/lolin_s3_mini/sdkconfig b/ports/espressif/boards/lolin_s3_mini/sdkconfig index 36be9c760ed..e9628662160 100644 --- a/ports/espressif/boards/lolin_s3_mini/sdkconfig +++ b/ports/espressif/boards/lolin_s3_mini/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="LOLIN-S3-MINI" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/lolin_s3_mini_pro/board.c b/ports/espressif/boards/lolin_s3_mini_pro/board.c new file mode 100644 index 00000000000..39e645bc7b5 --- /dev/null +++ b/ports/espressif/boards/lolin_s3_mini_pro/board.c @@ -0,0 +1,84 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + + +#define DELAY 0x80 + +// display init sequence according to ST7789 +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, 0 | DELAY, 0xff, // _SLPOUT and Delay 500ms + 0x3A, 1 | DELAY, 0x55, 0x0a, // _COLMOD and Delay 10ms + 0x36, 0x01, 0x08, // _MADCTL + 0x21, 0x80, 0x0A, // _INVON Hack and Delay 10ms + 0x13, 0x80, 0x0A, // _NORON and Delay 10ms + 0x29, 0 | DELAY, 0xff // _DISPON and Delay 500ms +}; + + +void board_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + // busio_spi_obj_t *spi = common_hal_board_create_spi(0); + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO40, &pin_GPIO38, NULL, false); + common_hal_busio_spi_never_reset(spi); + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO36), // DC + MP_OBJ_FROM_PTR(&pin_GPIO35), // CS + MP_OBJ_FROM_PTR(&pin_GPIO34), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 128, // width (after rotation) + 128, // height (after rotation) + 2, // column start + 1, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO33, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 200 // backlight pwm frequency + ); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/lolin_s3_mini_pro/mpconfigboard.h b/ports/espressif/boards/lolin_s3_mini_pro/mpconfigboard.h new file mode 100644 index 00000000000..bdbea2d18cb --- /dev/null +++ b/ports/espressif/boards/lolin_s3_mini_pro/mpconfigboard.h @@ -0,0 +1,27 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 David Sullivan +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "LOLIN S3 MINI PRO 4MB Flash 2MB PSRAM" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO8) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO11) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO12) + +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO38) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO39) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO40) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/lolin_s3_mini_pro/mpconfigboard.mk b/ports/espressif/boards/lolin_s3_mini_pro/mpconfigboard.mk new file mode 100644 index 00000000000..f08c733e43a --- /dev/null +++ b/ports/espressif/boards/lolin_s3_mini_pro/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303a +USB_PID = 0x8217 +USB_PRODUCT = "LOLIN S3 MINI PRO 4MB Flash 2MB PSRAM" +USB_MANUFACTURER = "WEMOS" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/lolin_s3_mini_pro/pins.c b/ports/espressif/boards/lolin_s3_mini_pro/pins.c new file mode 100644 index 00000000000..595cdd48900 --- /dev/null +++ b/ports/espressif/boards/lolin_s3_mini_pro/pins.c @@ -0,0 +1,68 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 David Sullivan +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // User buttons + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON2), MP_ROM_PTR(&pin_GPIO48) }, + + // LEDs + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_ENABLE), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO9) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO12) }, + + // IMU QMI8658C + { MP_ROM_QSTR(MP_QSTR_IMU_INT1), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT2), MP_ROM_PTR(&pin_GPIO21) }, + + // TFT Display + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RES), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO33) }, + + // SPI + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO38) }, + + // User accessible GPIO + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // Objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/lolin_s3_mini_pro/sdkconfig b/ports/espressif/boards/lolin_s3_mini_pro/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/lolin_s3_mini_pro/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/lolin_s3_pro/mpconfigboard.mk b/ports/espressif/boards/lolin_s3_pro/mpconfigboard.mk index 9df3f3580cd..f20732df49c 100755 --- a/ports/espressif/boards/lolin_s3_pro/mpconfigboard.mk +++ b/ports/espressif/boards/lolin_s3_pro/mpconfigboard.mk @@ -12,5 +12,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/lolin_s3_pro/sdkconfig b/ports/espressif/boards/lolin_s3_pro/sdkconfig index 4dfe8da3fb0..e9628662160 100755 --- a/ports/espressif/boards/lolin_s3_pro/sdkconfig +++ b/ports/espressif/boards/lolin_s3_pro/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="LOLIN-S3-PRO" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.mk b/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.mk index ea3c7a44621..03f5171a310 100644 --- a/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.mk +++ b/ports/espressif/boards/luatos_core_esp32c3/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/luatos_core_esp32c3/sdkconfig b/ports/espressif/boards/luatos_core_esp32c3/sdkconfig index 7d94db0b5b1..e9628662160 100644 --- a/ports/espressif/boards/luatos_core_esp32c3/sdkconfig +++ b/ports/espressif/boards/luatos_core_esp32c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="luatos-core-esp32c3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/luatos_core_esp32c3_ch343/mpconfigboard.mk b/ports/espressif/boards/luatos_core_esp32c3_ch343/mpconfigboard.mk index bb793f0f262..9e777889c0f 100644 --- a/ports/espressif/boards/luatos_core_esp32c3_ch343/mpconfigboard.mk +++ b/ports/espressif/boards/luatos_core_esp32c3_ch343/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 diff --git a/ports/espressif/boards/luatos_core_esp32c3_ch343/sdkconfig b/ports/espressif/boards/luatos_core_esp32c3_ch343/sdkconfig index 7d94db0b5b1..e9628662160 100644 --- a/ports/espressif/boards/luatos_core_esp32c3_ch343/sdkconfig +++ b/ports/espressif/boards/luatos_core_esp32c3_ch343/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="luatos-core-esp32c3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk index a40381f8a34..c896ed0c8a4 100644 --- a/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_echo/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_echo/sdkconfig b/ports/espressif/boards/m5stack_atom_echo/sdkconfig index 861e4ebad39..e9628662160 100644 --- a/ports/espressif/boards/m5stack_atom_echo/sdkconfig +++ b/ports/espressif/boards/m5stack_atom_echo/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomEcho" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk index 215fd976df3..5ca1db04f3b 100644 --- a/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_lite/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_lite/sdkconfig b/ports/espressif/boards/m5stack_atom_lite/sdkconfig index eaaf716a15e..e9628662160 100644 --- a/ports/espressif/boards/m5stack_atom_lite/sdkconfig +++ b/ports/espressif/boards/m5stack_atom_lite/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomLite" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk index 081750d143f..ace0e7f02cf 100644 --- a/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_matrix/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_matrix/sdkconfig b/ports/espressif/boards/m5stack_atom_matrix/sdkconfig index 730f17de0e1..e9628662160 100644 --- a/ports/espressif/boards/m5stack_atom_matrix/sdkconfig +++ b/ports/espressif/boards/m5stack_atom_matrix/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomMatrix" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk index abcd5f8724d..0f8ab59f744 100644 --- a/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atom_u/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atom_u/sdkconfig b/ports/espressif/boards/m5stack_atom_u/sdkconfig index 06d0f016937..e9628662160 100644 --- a/ports/espressif/boards/m5stack_atom_u/sdkconfig +++ b/ports/espressif/boards/m5stack_atom_u/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskAtomU" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_atoms3/board.c b/ports/espressif/boards/m5stack_atoms3/board.c index df620976b61..3dbd8a1a2b8 100644 --- a/ports/espressif/boards/m5stack_atoms3/board.c +++ b/ports/espressif/boards/m5stack_atoms3/board.c @@ -39,9 +39,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO33, // DC - &pin_GPIO15, // CS - &pin_GPIO34, // RST + MP_OBJ_FROM_PTR(&pin_GPIO33), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO34), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_atoms3/mpconfigboard.mk b/ports/espressif/boards/m5stack_atoms3/mpconfigboard.mk index 9bc53033a1f..7738713aa53 100644 --- a/ports/espressif/boards/m5stack_atoms3/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atoms3/mpconfigboard.mk @@ -8,4 +8,6 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB + +# Few pins. CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atoms3/sdkconfig b/ports/espressif/boards/m5stack_atoms3/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/m5stack_atoms3/sdkconfig +++ b/ports/espressif/boards/m5stack_atoms3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.mk b/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.mk index 8bb5ab76d85..736fb3222b5 100644 --- a/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atoms3_lite/mpconfigboard.mk @@ -8,4 +8,6 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB + +# Few pins. CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atoms3_lite/sdkconfig b/ports/espressif/boards/m5stack_atoms3_lite/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/m5stack_atoms3_lite/sdkconfig +++ b/ports/espressif/boards/m5stack_atoms3_lite/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_atoms3u/mpconfigboard.mk b/ports/espressif/boards/m5stack_atoms3u/mpconfigboard.mk index dc65fefc4bf..e68f4efdc65 100644 --- a/ports/espressif/boards/m5stack_atoms3u/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_atoms3u/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_atoms3u/sdkconfig b/ports/espressif/boards/m5stack_atoms3u/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/m5stack_atoms3u/sdkconfig +++ b/ports/espressif/boards/m5stack_atoms3u/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_cardputer/board.c b/ports/espressif/boards/m5stack_cardputer/board.c index 6fdc2f8ea5c..00630cd36d2 100644 --- a/ports/espressif/boards/m5stack_cardputer/board.c +++ b/ports/espressif/boards/m5stack_cardputer/board.c @@ -50,9 +50,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO34, // DC - &pin_GPIO37, // CS - &pin_GPIO33, // RST + MP_OBJ_FROM_PTR(&pin_GPIO34), // DC + MP_OBJ_FROM_PTR(&pin_GPIO37), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk b/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk index 6e9aaa76420..bc30ae3afd5 100644 --- a/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_cardputer/mpconfigboard.mk @@ -8,9 +8,9 @@ IDF_TARGET = esp32s3 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB -CIRCUITPY_ESPCAMERA = 0 -CIRCUITPY_GIFIO = 1 +# Very few pins. +CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_MAX3421E = 0 -SRC_C += boards/$(BOARD)/cardputer_keyboard.c +SRC_C += module/cardputer_keyboard.c diff --git a/ports/espressif/boards/m5stack_cardputer/sdkconfig b/ports/espressif/boards/m5stack_cardputer/sdkconfig index b48116f764d..e9628662160 100644 --- a/ports/espressif/boards/m5stack_cardputer/sdkconfig +++ b/ports/espressif/boards/m5stack_cardputer/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="m5stack-cardputer" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_cardputer_ros/board.c b/ports/espressif/boards/m5stack_cardputer_ros/board.c new file mode 100644 index 00000000000..00630cd36d2 --- /dev/null +++ b/ports/espressif/boards/m5stack_cardputer_ros/board.c @@ -0,0 +1,95 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "mpconfigboard.h" +#include "supervisor/board.h" +#include "supervisor/shared/serial.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "py/runtime.h" +#include "py/ringbuf.h" +#include "shared/runtime/interrupt_char.h" + + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + // SWRESET and Delay 140ms + 0x01, 0 | DELAY, 140, + // SLPOUT and Delay 10ms + 0x11, 0 | DELAY, 10, + // COLMOD 65k colors and 16 bit 5-6-5 + 0x3A, 1, 0x55, + // INVON Iiversion on + 0x21, 0, + // NORON normal operation (full update) + 0x13, 0, + // MADCTL columns RTL, page/column reverse order + 0x36, 1, 0x60, + // RAMCTRL color word little endian + 0xB0, 2, 0x00, 0xF8, + // DIPON display on + 0x29, 0, +}; + + +// Overrides the weakly linked function from supervisor/shared/board.c +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + // see here for inspiration: https://github.com/m5stack/M5GFX/blob/33d7d3135e816a86a008fae8ab3757938cee95d2/src/M5GFX.cpp#L1350 + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO34), // DC + MP_OBJ_FROM_PTR(&pin_GPIO37), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 240, // width (after rotation) + 135, // height (after rotation) + 40, // column start + 53, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + false, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO38, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 350 // backlight pwm frequency + ); +} + +// TODO: Should we turn off the display when asleep, in board_deinit() ? diff --git a/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.h b/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.h new file mode 100644 index 00000000000..4b62c7d76e6 --- /dev/null +++ b/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Cardputer (ROS version)" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO36, .mosi = &pin_GPIO35}, \ + {.clock = &pin_GPIO40, .mosi = &pin_GPIO14, .miso = &pin_GPIO39}} diff --git a/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.mk b/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.mk new file mode 100644 index 00000000000..98d2ad502dd --- /dev/null +++ b/ports/espressif/boards/m5stack_cardputer_ros/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x303A +USB_PID = 0x81DA +USB_PRODUCT = "M5Stack Cardputer - Circuitpython/ROS" +USB_MANUFACTURER = "M5STACK" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_RCLCPY = 0 + +# Very few pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_MAX3421E = 0 + +SRC_C += module/cardputer_keyboard.c diff --git a/ports/espressif/boards/m5stack_cardputer_ros/pins.c b/ports/espressif/boards/m5stack_cardputer_ros/pins.c new file mode 100644 index 00000000000..ba309e0dcbf --- /dev/null +++ b/ports/espressif/boards/m5stack_cardputer_ros/pins.c @@ -0,0 +1,86 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 1) +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Port A + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_PORTA1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_PORTA2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO2) }, + + // Keyboard + { MP_ROM_QSTR(MP_QSTR_KB_COL_0), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_KB_COL_1), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_KB_COL_2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_KB_COL_3), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_KB_COL_4), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_KB_COL_5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_KB_COL_6), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_KB_A_0), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_KB_A_1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_KB_A_2), MP_ROM_PTR(&pin_GPIO11) }, + + // Neopixel + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + + // Speaker + { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DATA), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_ROM_PTR(&pin_GPIO43) }, + + // Mic + { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO43) }, + + // IR + { MP_ROM_QSTR(MP_QSTR_IR_TX), MP_ROM_PTR(&pin_GPIO44) }, + + // SD + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO12) }, + + + // Display + { MP_ROM_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RS), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DATA), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BL), MP_ROM_PTR(&pin_GPIO38) }, + + // Button + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + + // Battery + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO10) }, + + // Other + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_TFT_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, + + // Display object + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_cardputer_ros/sdkconfig b/ports/espressif/boards/m5stack_cardputer_ros/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/m5stack_cardputer_ros/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/m5stack_core2/board.c b/ports/espressif/boards/m5stack_core2/board.c index 9d5c2bd650a..2e13c06c44f 100644 --- a/ports/espressif/boards/m5stack_core2/board.c +++ b/ports/espressif/boards/m5stack_core2/board.c @@ -318,9 +318,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO15, // DC - &pin_GPIO5, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO15), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + mp_const_none, // RST 32000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_core2/sdkconfig b/ports/espressif/boards/m5stack_core2/sdkconfig index c8ac5f43acf..116258b906b 100644 --- a/ports/espressif/boards/m5stack_core2/sdkconfig +++ b/ports/espressif/boards/m5stack_core2/sdkconfig @@ -29,7 +29,6 @@ CONFIG_ESP_REV_MIN_FULL=300 # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskCore2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_core_basic/board.c b/ports/espressif/boards/m5stack_core_basic/board.c index 4ae128817a1..5a18d33e527 100644 --- a/ports/espressif/boards/m5stack_core_basic/board.c +++ b/ports/espressif/boards/m5stack_core_basic/board.c @@ -42,9 +42,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO14, // CS - &pin_GPIO33, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO14), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk index dedcde81e63..964f61a04f4 100644 --- a/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_core_basic/mpconfigboard.mk @@ -6,4 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 16MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_core_basic/sdkconfig b/ports/espressif/boards/m5stack_core_basic/sdkconfig index 5b7ecf87097..116258b906b 100644 --- a/ports/espressif/boards/m5stack_core_basic/sdkconfig +++ b/ports/espressif/boards/m5stack_core_basic/sdkconfig @@ -29,7 +29,6 @@ CONFIG_ESP_REV_MIN_FULL=300 # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskCoreBasic" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_core_fire/board.c b/ports/espressif/boards/m5stack_core_fire/board.c index 4ae128817a1..5a18d33e527 100644 --- a/ports/espressif/boards/m5stack_core_fire/board.c +++ b/ports/espressif/boards/m5stack_core_fire/board.c @@ -42,9 +42,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO14, // CS - &pin_GPIO33, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO14), // CS + MP_OBJ_FROM_PTR(&pin_GPIO33), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk index 591c596bbcf..e62fd3d4e57 100644 --- a/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_core_fire/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_core_fire/sdkconfig b/ports/espressif/boards/m5stack_core_fire/sdkconfig index 0e7b9709383..116258b906b 100644 --- a/ports/espressif/boards/m5stack_core_fire/sdkconfig +++ b/ports/espressif/boards/m5stack_core_fire/sdkconfig @@ -29,7 +29,6 @@ CONFIG_ESP_REV_MIN_FULL=300 # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskCoreFire" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_cores3/board.c b/ports/espressif/boards/m5stack_cores3/board.c index f49d6349997..e4e178ee3c9 100644 --- a/ports/espressif/boards/m5stack_cores3/board.c +++ b/ports/espressif/boards/m5stack_cores3/board.c @@ -38,16 +38,18 @@ uint8_t display_init_sequence[] = { }; static bool display_init(void) { - busio_spi_obj_t *spi = common_hal_board_create_spi(0); fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO37, NULL, false); + common_hal_busio_spi_never_reset(spi); bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO35, // DC - &pin_GPIO3, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO35), // DC + MP_OBJ_FROM_PTR(&pin_GPIO3), // CS + mp_const_none, // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_cores3/mpconfigboard.h b/ports/espressif/boards/m5stack_cores3/mpconfigboard.h index 9af6ccf2fb4..0e5e136e3ea 100644 --- a/ports/espressif/boards/m5stack_cores3/mpconfigboard.h +++ b/ports/espressif/boards/m5stack_cores3/mpconfigboard.h @@ -15,9 +15,5 @@ #define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO11, .sda = &pin_GPIO12}, \ {.scl = &pin_GPIO1, .sda = &pin_GPIO2}} -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO37) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO35) - #define DEFAULT_UART_BUS_RX (&pin_GPIO18) #define DEFAULT_UART_BUS_TX (&pin_GPIO17) diff --git a/ports/espressif/boards/m5stack_cores3/pins.c b/ports/espressif/boards/m5stack_cores3/pins.c index 2ebb225277d..11357d79a72 100644 --- a/ports/espressif/boards/m5stack_cores3/pins.c +++ b/ports/espressif/boards/m5stack_cores3/pins.c @@ -28,42 +28,57 @@ CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - // M5 Bus (except I2S & PORT B) - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO37) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO36) }, + // M5 Bus (except I2S) + // The SPI bus MISO is also used for the TFT D/C signal, so it is not available for general use + // therefore the SPI bus is not listed on the M5 Bus { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_PORTC_RX), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_A18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_PORTC_TX), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, - // Port B - { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, - // I2S { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_ROM_PTR(&pin_GPIO34) }, { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_ROM_PTR(&pin_GPIO33) }, - { MP_ROM_QSTR(MP_QSTR_IS2_DATA), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_IS2_MASTER_CLOCK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DATA_OUT), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DATA_IN), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MASTER_CLOCK), MP_ROM_PTR(&pin_GPIO0) }, // Camera { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA), MP_ROM_PTR(&camera_data_tuple) }, @@ -82,6 +97,8 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CAMERA_XCLK), MP_ROM_PTR(&pin_GPIO2) }, // Display + { MP_ROM_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_GPIO36) }, { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO3) }, { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO35) }, @@ -92,7 +109,6 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} diff --git a/ports/espressif/boards/m5stack_cores3/sdkconfig b/ports/espressif/boards/m5stack_cores3/sdkconfig index 2eb2f0a850b..7c3c05764ba 100644 --- a/ports/espressif/boards/m5stack_cores3/sdkconfig +++ b/ports/espressif/boards/m5stack_cores3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="m5stack-cores3" # end of LWIP # diff --git a/ports/espressif/boards/m5stack_cores3_se/board.c b/ports/espressif/boards/m5stack_cores3_se/board.c new file mode 100644 index 00000000000..cb0ed4aea06 --- /dev/null +++ b/ports/espressif/boards/m5stack_cores3_se/board.c @@ -0,0 +1,226 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "common-hal/microcontroller/Pin.h" + + +#define DELAY 0x80 +#define AXP2101_I2C_ADDRESS 0x34 +#define AW9523B_I2C_ADDRESS 0x58 + +uint8_t display_init_sequence[] = { + 0x01, DELAY, 0x80, // Software reset then delay 0x80 (128ms) + 0xC8, 0x03, 0xFF, 0x93, 0x42, // Turn on the external command + 0xC0, 0x02, 0x12, 0x12, // Power Control 1 + 0xC1, 0x01, 0x03, // Power Control 2 + 0xC5, 0x01, 0xF2, // VCOM Control 1 + 0xB0, 0x01, 0xE0, // RGB Interface SYNC Mode + 0xF6, 0x03, 0x01, 0x00, 0x00, // Interface control + 0XE0, 0x0F, 0x00, 0x0C, 0x11, 0x04, 0x11, 0x08, 0x37, 0x89, 0x4C, 0x06, 0x0C, 0x0A, 0x2E, 0x34, 0x0F, // Positive Gamma Correction + 0xE1, 0x0F, 0x00, 0x0B, 0x11, 0x05, 0x13, 0x09, 0x33, 0x67, 0x48, 0x07, 0x0E, 0x0B, 0x2E, 0x33, 0x0F, // Negative Gamma Correction + 0xB6, 0x04, 0x08, 0x82, 0x1D, 0x04, // Display Function Control + 0x3A, 0x01, 0x55, // COLMOD: Pixel Format Set 16 bit + 0x21, 0x00, // Display inversion ON + 0x36, 0x01, 0x08, // Memory Access Control: RGB order + 0x11, DELAY, 0x78, // Exit Sleep then delay 0x78 (120ms) + 0x29, DELAY, 0x78, // Display on then delay 0x78 (120ms) +}; + +static bool display_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO36, &pin_GPIO37, NULL, false); + common_hal_busio_spi_never_reset(spi); + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO35), // DC + MP_OBJ_FROM_PTR(&pin_GPIO3), // CS + mp_const_none, // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 320, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 61, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); + + return true; +} + +static bool axp2101_init(busio_i2c_obj_t *i2c) { + int rc; + uint8_t write_buf[2]; + + // 0x90 = 0b1011_0011 // LDOS ON/OFF control 0 + // Compared to CoreS3: ALDO2 (bit 2) and ALDO3 (bit 3) disabled (no ES7210/camera) + write_buf[0] = 0x90; + write_buf[1] = 0b10110011; + rc = common_hal_busio_i2c_write(i2c, AXP2101_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x92, 0x0D // ALDO1 set to 1.8v for AW88298 + write_buf[0] = 0x92; + write_buf[1] = 0x0D; + rc = common_hal_busio_i2c_write(i2c, AXP2101_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x95, 0x1C // ALDO4 set to 3.3v for TF card slot + write_buf[0] = 0x95; + write_buf[1] = 0x1C; + rc = common_hal_busio_i2c_write(i2c, AXP2101_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x99, 0x18 // DLDO1 set to 2.9v for TFT backlight + write_buf[0] = 0x99; + write_buf[1] = 0x18; + rc = common_hal_busio_i2c_write(i2c, AXP2101_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x27, 0x00 // PowerKey Hold=1sec / PowerOff=4sec + write_buf[0] = 0x27; + write_buf[1] = 0x00; + rc = common_hal_busio_i2c_write(i2c, AXP2101_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x69, 0x11 // CHGLED setting + write_buf[0] = 0x69; + write_buf[1] = 0x11; + rc = common_hal_busio_i2c_write(i2c, AXP2101_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x10, 0x30 // PMU common config + write_buf[0] = 0x10; + write_buf[1] = 0x30; + rc = common_hal_busio_i2c_write(i2c, AXP2101_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + return true; +} + +static bool aw9523b_init(busio_i2c_obj_t *i2c) { + int rc; + uint8_t write_buf[2]; + + // 0x02 = 0b0000_0111 // AW_RST, BUD_OUT_EN, TOUCH_RST + write_buf[0] = 0x02; + write_buf[1] = 0b00000111; + rc = common_hal_busio_i2c_write(i2c, AW9523B_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x03 = 0b1000_0011 // BOOST_EN, CAM_RST, LCD_RST + write_buf[0] = 0x03; + write_buf[1] = 0b10000011; + rc = common_hal_busio_i2c_write(i2c, AW9523B_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x04 = 0b0001_1000 // Set TF_SW, ES_INT as input + write_buf[0] = 0x04; + write_buf[1] = 0b00011000; + rc = common_hal_busio_i2c_write(i2c, AW9523B_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x05 = 0b0000_1100 // Set AW_INT, TOUCH_INT as input + write_buf[0] = 0x05; + write_buf[1] = 0b00001100; + rc = common_hal_busio_i2c_write(i2c, AW9523B_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + // 0x11 = 0b0001_0000 // Set P0 outputs in push pull mode + write_buf[0] = 0x11; + write_buf[1] = 0b00010000; + rc = common_hal_busio_i2c_write(i2c, AW9523B_I2C_ADDRESS, write_buf, sizeof(write_buf)); + if (rc != 0) { + return false; + } + + return true; +} + +void board_init(void) { + // Deselect SD card on shared SPI bus before display init (see #10536) + config_pin_as_output_with_level(GPIO_NUM_4, true); + + busio_i2c_obj_t *internal_i2c = common_hal_board_create_i2c(0); + + if (!axp2101_init(internal_i2c)) { + mp_printf(&mp_plat_print, "could not initialize AXP2101"); + return; + } + + if (!aw9523b_init(internal_i2c)) { + mp_printf(&mp_plat_print, "could not initialize AW9523B"); + return; + } + + if (!display_init()) { + mp_printf(&mp_plat_print, "could not initialize the display"); + return; + } +} diff --git a/ports/espressif/boards/m5stack_cores3_se/mpconfigboard.h b/ports/espressif/boards/m5stack_cores3_se/mpconfigboard.h new file mode 100644 index 00000000000..edfcbb3c91b --- /dev/null +++ b/ports/espressif/boards/m5stack_cores3_se/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack CoreS3 SE" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO5) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO11, .sda = &pin_GPIO12}, \ + {.scl = &pin_GPIO1, .sda = &pin_GPIO2}} + +#define DEFAULT_UART_BUS_RX (&pin_GPIO18) +#define DEFAULT_UART_BUS_TX (&pin_GPIO17) diff --git a/ports/espressif/boards/m5stack_cores3_se/mpconfigboard.mk b/ports/espressif/boards/m5stack_cores3_se/mpconfigboard.mk new file mode 100644 index 00000000000..2413c43cebe --- /dev/null +++ b/ports/espressif/boards/m5stack_cores3_se/mpconfigboard.mk @@ -0,0 +1,27 @@ +USB_VID = 0x303A +USB_PID = 0x8348 + +USB_PRODUCT = "M5Stack CoreS3 SE" +USB_MANUFACTURER = "M5Stack" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_PARALLELDISPLAYBUS = 0 + +OPTIMIZATION_FLAGS = -Os + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ConnectionManager +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Shapes +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_FakeRequests +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests diff --git a/ports/espressif/boards/m5stack_cores3_se/pins.c b/ports/espressif/boards/m5stack_cores3_se/pins.c new file mode 100644 index 00000000000..f003b74e122 --- /dev/null +++ b/ports/espressif/boards/m5stack_cores3_se/pins.c @@ -0,0 +1,86 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // M5 Bus (except I2S) + // The SPI bus MISO is also used for the TFT D/C signal, so it is not available for general use + // therefore the SPI bus is not listed on the M5 Bus + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_PORTC_RX), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_A18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_PORTC_TX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_A17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IR), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + + // I2S + { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DATA_OUT), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DATA_IN), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MASTER_CLOCK), MP_ROM_PTR(&pin_GPIO0) }, + + // Display + { MP_ROM_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO35) }, + + // Misc + { MP_ROM_QSTR(MP_QSTR_I2C_INTERRUPT), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SDCARD_CS), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_cores3_se/sdkconfig b/ports/espressif/boards/m5stack_cores3_se/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/m5stack_cores3_se/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/m5stack_dial/board.c b/ports/espressif/boards/m5stack_dial/board.c index 4e7cf4b0240..6214255612b 100644 --- a/ports/espressif/boards/m5stack_dial/board.c +++ b/ports/espressif/boards/m5stack_dial/board.c @@ -49,9 +49,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO4, // DC - &pin_GPIO7, // CS - &pin_GPIO8, // RST + MP_OBJ_FROM_PTR(&pin_GPIO4), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO8), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_dial/mpconfigboard.mk b/ports/espressif/boards/m5stack_dial/mpconfigboard.mk index cfdb0f16905..b87b5e6f925 100644 --- a/ports/espressif/boards/m5stack_dial/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_dial/mpconfigboard.mk @@ -10,7 +10,6 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB +# Very few pins. CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_PARALLELDISPLAYBUS = 0 - -OPTIMIZATION_FLAGS = -Os diff --git a/ports/espressif/boards/m5stack_dial/sdkconfig b/ports/espressif/boards/m5stack_dial/sdkconfig index 2938bb3bfa7..e9628662160 100644 --- a/ports/espressif/boards/m5stack_dial/sdkconfig +++ b/ports/espressif/boards/m5stack_dial/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="m5stack-dial" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_dinmeter/board.c b/ports/espressif/boards/m5stack_dinmeter/board.c new file mode 100644 index 00000000000..37fafa994dc --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/board.c @@ -0,0 +1,107 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "mpconfigboard.h" +#include "supervisor/board.h" +#include "supervisor/shared/serial.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "py/runtime.h" +#include "py/ringbuf.h" +#include "shared/runtime/interrupt_char.h" + + +uint8_t display_init_sequence[] = { + 0x01, 0x80, 0x96, // SWRESET and Delay 150ms + 0x11, 0x80, 0xff, // SLPOUT and Delay + 0xb1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR2 + 0xb3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xb4, 0x01, 0x07, // _INVCTR line inversion + 0xc0, 0x03, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 0x01, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 0x02, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 0x02, 0x8a, 0x2a, + 0xc4, 0x02, 0x8a, 0xee, + 0xc5, 0x01, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x36, 0x01, 0xc8, // MADCTL Rotate display + 0x21, 0x00, // _INVON + 0x3a, 0x01, 0x05, // COLMOD - 16bit color + 0xe0, 0x10, 0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xe1, 0x10, 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0x80, 0x0a, // _NORON + 0x29, 0x80, 0x64 // _DISPON +}; + + +// Overrides the weakly linked function from supervisor/shared/board.c +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + // see here for inspiration: https://github.com/m5stack/M5GFX/blob/33d7d3135e816a86a008fae8ab3757938cee95d2/src/M5GFX.cpp#L1350 + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO4), // DC + MP_OBJ_FROM_PTR(&pin_GPIO7), // CS + MP_OBJ_FROM_PTR(&pin_GPIO8), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 240, // width (after rotation) + 135, // height (after rotation) + 40, // column start + 52, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO9, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 80, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Hold pin must be set high to avoid a power off when battery powered + if (pin_number == 46) { + // Turn on hold output + config_pin_as_output_with_level(pin_number, true); + return true; + } + return false; +} + +// TODO: Should we turn off the display when asleep, in board_deinit() ? diff --git a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.h b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.h new file mode 100644 index 00000000000..2d69e61ea95 --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 CDarius +// SPDX-FileCopyrightText: Copyright (c) 2025 juergenpabel +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack DinMeter" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO12, .sda = &pin_GPIO11}, \ + {.scl = &pin_GPIO15, .sda = &pin_GPIO13}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO6, .mosi = &pin_GPIO5}} + +#define CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP (1) diff --git a/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk new file mode 100644 index 00000000000..81a23af1fe4 --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x303A +USB_PID = 0x830B + +USB_PRODUCT = "DinMeter" +USB_MANUFACTURER = "M5Stack" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +# Very few pins. +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 diff --git a/ports/espressif/boards/m5stack_dinmeter/pins.c b/ports/espressif/boards/m5stack_dinmeter/pins.c new file mode 100644 index 00000000000..f75e05e848b --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/pins.c @@ -0,0 +1,61 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Juergen Pabel +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(porta_i2c, i2c, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Port A + { MP_ROM_QSTR(MP_QSTR_PORTA_SCL), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_SDA), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + // Port B + { MP_ROM_QSTR(MP_QSTR_PORTB_IN), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_PORTB_OUT), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + + // Encoder + { MP_ROM_QSTR(MP_QSTR_ENC_A), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_ENC_B), MP_ROM_PTR(&pin_GPIO40) }, + + // Button + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + // Misc + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_KNOB_BUTTON), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_POWER_HOLD), MP_ROM_PTR(&pin_GPIO46) }, + + // Display + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_I2C), MP_ROM_PTR(&board_porta_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_dinmeter/sdkconfig b/ports/espressif/boards/m5stack_dinmeter/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/m5stack_dinmeter/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/m5stack_m5paper/board.c b/ports/espressif/boards/m5stack_m5paper/board.c index fbf66fa5ccd..db68df79c42 100644 --- a/ports/espressif/boards/m5stack_m5paper/board.c +++ b/ports/espressif/boards/m5stack_m5paper/board.c @@ -74,6 +74,7 @@ void board_init(void) { // false, // always_toggle_chip_select // false, // grayscale // true, // acep + // false, // spectra6 // false, // two_byte_sequence_length // false // address_little_endian // ); diff --git a/ports/espressif/boards/m5stack_m5paper/mpconfigboard.mk b/ports/espressif/boards/m5stack_m5paper/mpconfigboard.mk index bacf270a663..bbc07263273 100644 --- a/ports/espressif/boards/m5stack_m5paper/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_m5paper/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_SIZE = 16MB CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/m5stack_m5paper/sdkconfig b/ports/espressif/boards/m5stack_m5paper/sdkconfig index fbf94f27494..116258b906b 100644 --- a/ports/espressif/boards/m5stack_m5paper/sdkconfig +++ b/ports/espressif/boards/m5stack_m5paper/sdkconfig @@ -29,7 +29,6 @@ CONFIG_ESP_REV_MIN_FULL=300 # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5Paper" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.mk b/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.mk index 2c856c6fc00..2f3b62f90fa 100644 --- a/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_stamp_c3/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE=qio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 diff --git a/ports/espressif/boards/m5stack_stamp_c3/sdkconfig b/ports/espressif/boards/m5stack_stamp_c3/sdkconfig index 87330ec13bd..e9628662160 100644 --- a/ports/espressif/boards/m5stack_stamp_c3/sdkconfig +++ b/ports/espressif/boards/m5stack_stamp_c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="m5stack-stamp-c3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_stamp_s3/board.c b/ports/espressif/boards/m5stack_stamp_s3/board.c new file mode 100644 index 00000000000..2978eb0ca12 --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_s3/board.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: 2025 Stella Schwankl +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" diff --git a/ports/espressif/boards/m5stack_stamp_s3/mpconfigboard.h b/ports/espressif/boards/m5stack_stamp_s3/mpconfigboard.h new file mode 100644 index 00000000000..568ba94be9a --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_s3/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: 2025 Stella Schwankl +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Stamp-S3" +#define MICROPY_HW_MCU_NAME "ESP32-S3FN8" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO15) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO13) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/m5stack_stamp_s3/mpconfigboard.mk b/ports/espressif/boards/m5stack_stamp_s3/mpconfigboard.mk new file mode 100644 index 00000000000..d2f1bc3c471 --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_s3/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x303A +USB_PID = 0x816B +USB_PRODUCT = "M5Stack StampS3 - CircuitPython" +USB_MANUFACTURER = "M5STACK" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/m5stack_stamp_s3/pins.c b/ports/espressif/boards/m5stack_stamp_s3/pins.c new file mode 100644 index 00000000000..11995b8c0f8 --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_s3/pins.c @@ -0,0 +1,152 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: 2025 Stella Schwankl +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 1) +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Button + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO0) }, + + // GPIO + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_G1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_TCH1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_TCH2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_TCH3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_TCH4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_TCH5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_TCH6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_TCH7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_TCH8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_TCH9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_TCH10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_TCH11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_G12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_TCH12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_G13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_TCH13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_G14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TCH14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_G15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_G39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_G40), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_G41), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_G42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_G43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_G44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_G46), MP_ROM_PTR(&pin_GPIO46) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // Neopixel + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + + // Display + { MP_ROM_QSTR(MP_QSTR_TFT_RST), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RS), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_TFT_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DAT), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DATA), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_TFT_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BL), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_TFT_SPI), MP_ROM_PTR(&board_spi_obj) }, + + // Extended Port Pins + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_G16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_G17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_G18), MP_ROM_PTR(&pin_GPIO18) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_stamp_s3/sdkconfig b/ports/espressif/boards/m5stack_stamp_s3/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/m5stack_stamp_s3/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/m5stack_stick_c/board.c b/ports/espressif/boards/m5stack_stick_c/board.c index 641d2d1db7e..491ddead860 100644 --- a/ports/espressif/boards/m5stack_stick_c/board.c +++ b/ports/espressif/boards/m5stack_stick_c/board.c @@ -154,9 +154,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO23, // DC - &pin_GPIO5, // CS - &pin_GPIO18, // RST + MP_OBJ_FROM_PTR(&pin_GPIO23), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO18), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_stick_c/mpconfigboard.mk b/ports/espressif/boards/m5stack_stick_c/mpconfigboard.mk index ce94e71dff2..7f8b24c8081 100644 --- a/ports/espressif/boards/m5stack_stick_c/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_stick_c/mpconfigboard.mk @@ -6,8 +6,5 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 SRC_C += pmic/axp192/axp192.c diff --git a/ports/espressif/boards/m5stack_stick_c/sdkconfig b/ports/espressif/boards/m5stack_stick_c/sdkconfig index 2e72fdb2163..e9628662160 100644 --- a/ports/espressif/boards/m5stack_stick_c/sdkconfig +++ b/ports/espressif/boards/m5stack_stick_c/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskStickC" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_stick_c_plus/board.c b/ports/espressif/boards/m5stack_stick_c_plus/board.c index eec6a208260..8902521db8e 100644 --- a/ports/espressif/boards/m5stack_stick_c_plus/board.c +++ b/ports/espressif/boards/m5stack_stick_c_plus/board.c @@ -154,9 +154,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO23, // DC - &pin_GPIO5, // CS - &pin_GPIO18, // RST + MP_OBJ_FROM_PTR(&pin_GPIO23), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO18), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.mk b/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.mk index bee1fc7e781..8960a568feb 100644 --- a/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_stick_c_plus/mpconfigboard.mk @@ -6,8 +6,5 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 SRC_C += pmic/axp192/axp192.c diff --git a/ports/espressif/boards/m5stack_stick_c_plus/sdkconfig b/ports/espressif/boards/m5stack_stick_c_plus/sdkconfig index 54f50db25c3..e9628662160 100644 --- a/ports/espressif/boards/m5stack_stick_c_plus/sdkconfig +++ b/ports/espressif/boards/m5stack_stick_c_plus/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StaskStickCPlus" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/m5stack_stick_c_plus2/board.c b/ports/espressif/boards/m5stack_stick_c_plus2/board.c new file mode 100644 index 00000000000..d84faa1888d --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus2/board.c @@ -0,0 +1,137 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 n0xa, 2025 bootc +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "driver/gpio.h" +#include "common-hal/microcontroller/Pin.h" + +// display init sequence according to adafruit_st7735r.py library +uint8_t display_init_sequence[] = { + 0x01, 0x80, 0x96, // SWRESET and Delay 150ms + 0x11, 0x80, 0xff, // SLPOUT and Delay + 0xb1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xb2, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR2 + 0xb3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xb4, 0x01, 0x07, // _INVCTR line inversion + 0xc0, 0x03, 0xa2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xc1, 0x01, 0xc5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xc2, 0x02, 0x0a, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xc3, 0x02, 0x8a, 0x2a, + 0xc4, 0x02, 0x8a, 0xee, + 0xc5, 0x01, 0x0e, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x36, 0x01, 0xc8, // MADCTL Rotate display + 0x21, 0x00, // _INVON + 0x3a, 0x01, 0x05, // COLMOD - 16bit color + 0xe0, 0x10, 0x02, 0x1c, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2d, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xe1, 0x10, 0x03, 0x1d, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0x80, 0x0a, // _NORON + 0x29, 0x80, 0x64 // _DISPON +}; + +static void display_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO13, &pin_GPIO15, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO14), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST + 10000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 135, // width (after rotation) + 240, // height (after rotation) + 40, // column start + 52, // row start + 1, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO27, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + display_init(); +} + +bool board_requests_safe_mode(void) { + // Enable HOLD early on + config_pin_as_output_with_level(GPIO_NUM_4, true); + + // Change the buttons to inputs + gpio_set_direction(GPIO_NUM_35, GPIO_MODE_INPUT); + gpio_set_pull_mode(GPIO_NUM_35, GPIO_FLOATING); + gpio_set_direction(GPIO_NUM_37, GPIO_MODE_INPUT); + gpio_set_pull_mode(GPIO_NUM_37, GPIO_FLOATING); + gpio_set_direction(GPIO_NUM_39, GPIO_MODE_INPUT); + gpio_set_pull_mode(GPIO_NUM_39, GPIO_FLOATING); + + // Let the pins settle + mp_hal_delay_ms(1); + + // Safe mode if BTN_A is held at boot (logic low) + return gpio_get_level(GPIO_NUM_37) == 0; // BTN_A +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + switch (pin_number) { + case GPIO_NUM_4: // HOLD + // HOLD(G4) pin must be set high to avoid a power off when battery powered + config_pin_as_output_with_level(pin_number, true); + return true; + + case GPIO_NUM_35: // BTN_C/PWR + case GPIO_NUM_37: // BTN_A + case GPIO_NUM_39: // BTN_B + gpio_set_direction(pin_number, GPIO_MODE_INPUT); + gpio_set_pull_mode(pin_number, GPIO_FLOATING); + return true; + + default: + return false; + } + return false; +} diff --git a/ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h b/ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h new file mode 100644 index 00000000000..fd11ec3ff4f --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 n0xa, 2025 bootc +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Stick C Plus2" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO19) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO22, .sda = &pin_GPIO21}, \ + {.scl = &pin_GPIO33, .sda = &pin_GPIO32}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO37) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION MP_ERROR_TEXT("You pressed button A at start up.") + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.mk b/ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.mk new file mode 100644 index 00000000000..ae0736c4208 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus2/mpconfigboard.mk @@ -0,0 +1,20 @@ +CIRCUITPY_CREATOR_ID = 0x10151015 +CIRCUITPY_CREATION_ID = 0x0032000C + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m +CIRCUITPY_ESP_PSRAM_SIZE = 2MB + +# The safe mode wait gets us very close to the 3s time for the board to shut +# down when BTN_C/PWR is held down. We skip the wait and instead enter safe +# mode if BTN_A is held down during boot with no timeout. +CIRCUITPY_SKIP_SAFE_MODE_WAIT = 1 + +# Enable PDMIn for the microphone +CIRCUITPY_AUDIOBUSIO_PDMIN = 1 diff --git a/ports/espressif/boards/m5stack_stick_c_plus2/pins.c b/ports/espressif/boards/m5stack_stick_c_plus2/pins.c new file mode 100644 index 00000000000..74594821765 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus2/pins.c @@ -0,0 +1,78 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 n0xa, 2025 bootc +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(grove_i2c, i2c, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Pin port on the top + { MP_ROM_QSTR(MP_QSTR_G26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_G36), MP_ROM_PTR(&pin_GPIO36) }, // G36/G25 pin + { MP_ROM_QSTR(MP_QSTR_G25), MP_ROM_PTR(&pin_GPIO25) }, // G36/G25 pin + { MP_ROM_QSTR(MP_QSTR_G0), MP_ROM_PTR(&pin_GPIO0) }, // also PDM_MIC_CLK + + // Grove port on the bottom + { MP_ROM_QSTR(MP_QSTR_G32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_SDA), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_G33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_SCL), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_GROVE_I2C), MP_ROM_PTR(&board_grove_i2c_obj) }, + + // Buttons + { MP_ROM_QSTR(MP_QSTR_G37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_BTN_A), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_G39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_BTN_B), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_G35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_BTN_C), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_BTN_PWR), MP_ROM_PTR(&pin_GPIO35) }, // also WAKE + + // Buzzer / Speaker + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO2) }, + + // Red and IR LED (single pin) + { MP_ROM_QSTR(MP_QSTR_G19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IR_LED), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO19) }, + + // LCD display + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, + + // Battery voltage sense + { MP_ROM_QSTR(MP_QSTR_G38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO38) }, + + // Microphone + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_CLK), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_G34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_PDM_MIC_DATA), MP_ROM_PTR(&pin_GPIO34) }, + + // Internal I2C (IMU and RTC) + { MP_ROM_QSTR(MP_QSTR_G21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SYS_SDA), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_G22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SYS_SCL), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // Sleep/Wake signal + { MP_ROM_QSTR(MP_QSTR_WAKE), MP_ROM_PTR(&pin_GPIO35) }, + + // Power hold + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_HOLD), MP_ROM_PTR(&pin_GPIO4) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_stick_c_plus2/sdkconfig b/ports/espressif/boards/m5stack_stick_c_plus2/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/m5stack_stick_c_plus2/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/m5stack_tab5/board.c b/ports/espressif/boards/m5stack_tab5/board.c new file mode 100644 index 00000000000..7c7c768d5c1 --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/board.c @@ -0,0 +1,379 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/mipidsi/Bus.h" +#include "shared-bindings/mipidsi/Display.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/framebufferio/__init__.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" +#include "ports/espressif/common-hal/microcontroller/Pin.h" + +// Statically allocate the MIPI DSI bus (only one DSI bus on ESP32-P4) +static mipidsi_bus_obj_t board_mipidsi_bus; + +// ILI9881C initialization sequence +static const uint8_t ili9881c_init_sequence[] = { + 0xff, 0x03, 0x98, 0x81, 0x00, + 0x01, 0x80, 0x78, // software reset + // CMD_Page 1 + 0xff, 0x03, 0x98, 0x81, 0x01, + 0xb7, 0x01, 0x03, // set 2 lane + // CMD Page 0 + 0xff, 0x03, 0x98, 0x81, 0x00, + 0x11, 0x80, 0x0a, // out of sleep + 0x36, 0x01, 0x00, // madctl + 0x3a, 0x01, 0x55, // colmod + // CMD_Page 3 + 0xff, 0x03, 0x98, 0x81, 0x03, + 0x01, 0x01, 0x00, + 0x02, 0x01, 0x00, + 0x03, 0x01, 0x73, + 0x04, 0x01, 0x00, + 0x05, 0x01, 0x00, + 0x06, 0x01, 0x08, + 0x07, 0x01, 0x00, + 0x08, 0x01, 0x00, + 0x09, 0x01, 0x1b, + 0x0a, 0x01, 0x01, + 0x0b, 0x01, 0x01, + 0x0c, 0x01, 0x0d, + 0x0d, 0x01, 0x01, + 0x0e, 0x01, 0x01, + 0x0f, 0x01, 0x26, + 0x10, 0x01, 0x26, + 0x11, 0x01, 0x00, + 0x12, 0x01, 0x00, + 0x13, 0x01, 0x02, + 0x14, 0x01, 0x00, + 0x15, 0x01, 0x00, + 0x16, 0x01, 0x00, + 0x17, 0x01, 0x00, + 0x18, 0x01, 0x00, + 0x19, 0x01, 0x00, + 0x1a, 0x01, 0x00, + 0x1b, 0x01, 0x00, + 0x1c, 0x01, 0x00, + 0x1d, 0x01, 0x00, + 0x1e, 0x01, 0x40, + 0x1f, 0x01, 0x00, + 0x20, 0x01, 0x06, + 0x21, 0x01, 0x01, + 0x22, 0x01, 0x00, + 0x23, 0x01, 0x00, + 0x24, 0x01, 0x00, + 0x25, 0x01, 0x00, + 0x26, 0x01, 0x00, + 0x27, 0x01, 0x00, + 0x28, 0x01, 0x33, + 0x29, 0x01, 0x03, + 0x2a, 0x01, 0x00, + 0x2b, 0x01, 0x00, + 0x2c, 0x01, 0x00, + 0x2d, 0x01, 0x00, + 0x2e, 0x01, 0x00, + 0x2f, 0x01, 0x00, + 0x30, 0x01, 0x00, + 0x31, 0x01, 0x00, + 0x32, 0x01, 0x00, + 0x33, 0x01, 0x00, + 0x34, 0x01, 0x00, + 0x35, 0x01, 0x00, + 0x36, 0x01, 0x00, + 0x37, 0x01, 0x00, + 0x38, 0x01, 0x00, + 0x39, 0x01, 0x00, + 0x3a, 0x01, 0x00, + 0x3b, 0x01, 0x00, + 0x3c, 0x01, 0x00, + 0x3d, 0x01, 0x00, + 0x3e, 0x01, 0x00, + 0x3f, 0x01, 0x00, + 0x40, 0x01, 0x00, + 0x41, 0x01, 0x00, + 0x42, 0x01, 0x00, + 0x43, 0x01, 0x00, + 0x44, 0x01, 0x00, + 0x50, 0x01, 0x01, + 0x51, 0x01, 0x23, + 0x52, 0x01, 0x45, + 0x53, 0x01, 0x67, + 0x54, 0x01, 0x89, + 0x55, 0x01, 0xab, + 0x56, 0x01, 0x01, + 0x57, 0x01, 0x23, + 0x58, 0x01, 0x45, + 0x59, 0x01, 0x67, + 0x5a, 0x01, 0x89, + 0x5b, 0x01, 0xab, + 0x5c, 0x01, 0xcd, + 0x5d, 0x01, 0xef, + 0x5e, 0x01, 0x11, + 0x5f, 0x01, 0x02, + 0x60, 0x01, 0x00, + 0x61, 0x01, 0x07, + 0x62, 0x01, 0x06, + 0x63, 0x01, 0x0e, + 0x64, 0x01, 0x0f, + 0x65, 0x01, 0x0c, + 0x66, 0x01, 0x0d, + 0x67, 0x01, 0x02, + 0x68, 0x01, 0x02, + 0x69, 0x01, 0x02, + 0x6a, 0x01, 0x02, + 0x6b, 0x01, 0x02, + 0x6c, 0x01, 0x02, + 0x6d, 0x01, 0x02, + 0x6e, 0x01, 0x02, + 0x6f, 0x01, 0x02, + 0x70, 0x01, 0x02, + 0x71, 0x01, 0x02, + 0x72, 0x01, 0x02, + 0x73, 0x01, 0x05, + 0x74, 0x01, 0x01, + 0x75, 0x01, 0x02, + 0x76, 0x01, 0x00, + 0x77, 0x01, 0x07, + 0x78, 0x01, 0x06, + 0x79, 0x01, 0x0e, + 0x7a, 0x01, 0x0f, + 0x7b, 0x01, 0x0c, + 0x7c, 0x01, 0x0d, + 0x7d, 0x01, 0x02, + 0x7e, 0x01, 0x02, + 0x7f, 0x01, 0x02, + 0x80, 0x01, 0x02, + 0x81, 0x01, 0x02, + 0x82, 0x01, 0x02, + 0x83, 0x01, 0x02, + 0x84, 0x01, 0x02, + 0x85, 0x01, 0x02, + 0x86, 0x01, 0x02, + 0x87, 0x01, 0x02, + 0x88, 0x01, 0x02, + 0x89, 0x01, 0x05, + 0x8a, 0x01, 0x01, + // CMD_Page 4 + 0xff, 0x03, 0x98, 0x81, 0x04, + 0x38, 0x01, 0x01, + 0x39, 0x01, 0x00, + 0x6c, 0x01, 0x15, + 0x6e, 0x01, 0x1a, + 0x6f, 0x01, 0x25, + 0x3a, 0x01, 0xa4, + 0x8d, 0x01, 0x20, + 0x87, 0x01, 0xba, + 0x3b, 0x01, 0x98, + // CMD_Page 1 + 0xff, 0x03, 0x98, 0x81, 0x01, + 0x22, 0x01, 0x0a, + 0x31, 0x01, 0x00, + 0x50, 0x01, 0x6b, + 0x51, 0x01, 0x66, + 0x53, 0x01, 0x73, + 0x55, 0x01, 0x8b, + 0x60, 0x01, 0x1b, + 0x61, 0x01, 0x01, + 0x62, 0x01, 0x0c, + 0x63, 0x01, 0x00, + // Gamma P + 0xa0, 0x01, 0x00, + 0xa1, 0x01, 0x15, + 0xa2, 0x01, 0x1f, + 0xa3, 0x01, 0x13, + 0xa4, 0x01, 0x11, + 0xa5, 0x01, 0x21, + 0xa6, 0x01, 0x17, + 0xa7, 0x01, 0x1b, + 0xa8, 0x01, 0x6b, + 0xa9, 0x01, 0x1e, + 0xaa, 0x01, 0x2b, + 0xab, 0x01, 0x5d, + 0xac, 0x01, 0x19, + 0xad, 0x01, 0x14, + 0xae, 0x01, 0x4b, + 0xaf, 0x01, 0x1d, + 0xb0, 0x01, 0x27, + 0xb1, 0x01, 0x49, + 0xb2, 0x01, 0x5d, + 0xb3, 0x01, 0x39, + // Gamma N + 0xc0, 0x01, 0x00, + 0xc1, 0x01, 0x01, + 0xc2, 0x01, 0x0c, + 0xc3, 0x01, 0x11, + 0xc4, 0x01, 0x15, + 0xc5, 0x01, 0x28, + 0xc6, 0x01, 0x1b, + 0xc7, 0x01, 0x1c, + 0xc8, 0x01, 0x62, + 0xc9, 0x01, 0x1c, + 0xca, 0x01, 0x29, + 0xcb, 0x01, 0x60, + 0xcc, 0x01, 0x16, + 0xcd, 0x01, 0x17, + 0xce, 0x01, 0x4a, + 0xcf, 0x01, 0x23, + 0xd0, 0x01, 0x24, + 0xd1, 0x01, 0x4f, + 0xd2, 0x01, 0x5f, + 0xd3, 0x01, 0x39, + // CMD_Page 0 + 0xff, 0x03, 0x98, 0x81, 0x00, + 0x35, 0x00, + 0xfe, 0x00, + 0x29, 0x00, +}; + +// I2C addresses +#define GOODIX_TOUCH_ADDRESS 0x14 +#define ST7123_ADDRESS 0x55 +#define I2C_DEV_ADDR_PI4IOE1 0x43 + +// PI4IOE GPIO expander registers +#define PI4IO_REG_CHIP_RESET 0x01 +#define PI4IO_REG_IO_DIR 0x03 +#define PI4IO_REG_OUT_SET 0x05 +#define PI4IO_REG_OUT_H_IM 0x07 +#define PI4IO_REG_PULL_SEL 0x0D +#define PI4IO_REG_PULL_EN 0x0B + +void board_init(void) { + // Initialize I2C for GPIO expander and display detection + busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); + + // Initialize PI4IOE GPIO expander to control LCD reset + uint8_t write_buf[2]; + + common_hal_busio_i2c_try_lock(i2c); + + // Chip reset + write_buf[0] = PI4IO_REG_CHIP_RESET; + write_buf[1] = 0xFF; + common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2); + + // Set IO direction (bit 7 as output for LCD reset) + write_buf[0] = PI4IO_REG_IO_DIR; + write_buf[1] = 0b01111111; + common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2); + + // Set output high-impedance mode + write_buf[0] = PI4IO_REG_OUT_H_IM; + write_buf[1] = 0b00000000; + common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2); + + // Set pull select + write_buf[0] = PI4IO_REG_PULL_SEL; + write_buf[1] = 0b01111111; + common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2); + + // Enable pull resistors + write_buf[0] = PI4IO_REG_PULL_EN; + write_buf[1] = 0b01111111; + common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2); + + // Set output state (including LCD reset) + write_buf[0] = PI4IO_REG_OUT_SET; + write_buf[1] = 0b01110110; + common_hal_busio_i2c_write(i2c, I2C_DEV_ADDR_PI4IOE1, write_buf, 2); + + // Small delay for reset to take effect + mp_hal_delay_ms(100); + + // Probe I2C bus to detect which display is present + bool has_goodix = common_hal_busio_i2c_probe(i2c, GOODIX_TOUCH_ADDRESS); + bool has_st7123 = common_hal_busio_i2c_probe(i2c, ST7123_ADDRESS); + + common_hal_busio_i2c_unlock(i2c); + + // Configure display parameters based on detected hardware + uint32_t bus_frequency; + uint32_t pixel_clock_frequency; + const uint8_t *init_sequence; + size_t init_sequence_len; + uint32_t hsync_pulse_width, hsync_back_porch, hsync_front_porch; + uint32_t vsync_pulse_width, vsync_back_porch, vsync_front_porch; + + if (has_goodix) { + // ILI9881C display with Goodix touch + bus_frequency = 730000000; + pixel_clock_frequency = 60000000; + init_sequence = ili9881c_init_sequence; + init_sequence_len = sizeof(ili9881c_init_sequence); + hsync_pulse_width = 40; + hsync_back_porch = 140; + hsync_front_porch = 40; + vsync_pulse_width = 4; + vsync_back_porch = 20; + vsync_front_porch = 20; + } else if (has_st7123) { + // ST7123 display + bus_frequency = 965000000; + pixel_clock_frequency = 70000000; + init_sequence = NULL; // ST7123 doesn't use init sequence + init_sequence_len = 0; + hsync_pulse_width = 2; + hsync_back_porch = 40; + hsync_front_porch = 40; + vsync_pulse_width = 2; + vsync_back_porch = 8; + vsync_front_porch = 220; + + // Not tested now + return; + } else { + return; + } + + // Initialize the statically allocated MIPI DSI bus + board_mipidsi_bus.base.type = &mipidsi_bus_type; + common_hal_mipidsi_bus_construct(&board_mipidsi_bus, bus_frequency, 2); // 2 lanes + + // Allocate display bus for the display object + primary_display_bus_t *display_bus_obj = allocate_display_bus_or_raise(); + mipidsi_display_obj_t *display = &display_bus_obj->mipidsi; + display->base.type = &mipidsi_display_type; + + common_hal_mipidsi_display_construct( + display, + &board_mipidsi_bus, // Use statically allocated bus + init_sequence, + init_sequence_len, + 0, // virtual_channel + 720, // width + 1280, // height + 0, // rotation + 16, // color_depth + &pin_GPIO22, // backlight_pin (LCD_BL) + 0.1f, // brightness + 60, // native_frames_per_second + true, // backlight_on_high + hsync_pulse_width, + hsync_back_porch, + hsync_front_porch, + vsync_pulse_width, + vsync_back_porch, + vsync_front_porch, + pixel_clock_frequency + ); + + // Create framebuffer display + framebufferio_framebufferdisplay_obj_t *fb_display = &allocate_display()->framebuffer_display; + fb_display->base.type = &framebufferio_framebufferdisplay_type; + + common_hal_framebufferio_framebufferdisplay_construct( + fb_display, + MP_OBJ_FROM_PTR(display), + 0, // rotation + true // auto_refresh + ); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/m5stack_tab5/mpconfigboard.h b/ports/espressif/boards/m5stack_tab5/mpconfigboard.h new file mode 100644 index 00000000000..6c748e93ecd --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/mpconfigboard.h @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "M5Stack Tab5" +#define MICROPY_HW_MCU_NAME "ESP32P4" + +// I2C bus for touch, IMU, RTC, power monitor, and GPIO expanders +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO32, .sda = &pin_GPIO31}} + +// UART +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO37) + +// SPI on M5-Bus +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO5) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO19) + +// Use the second USB device (numbered 0 and 1) +#define CIRCUITPY_USB_DEVICE_INSTANCE 0 +#define CIRCUITPY_ESP32P4_SWAP_LSFS (1) diff --git a/ports/espressif/boards/m5stack_tab5/mpconfigboard.mk b/ports/espressif/boards/m5stack_tab5/mpconfigboard.mk new file mode 100644 index 00000000000..4871a259e7a --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x832B +USB_PRODUCT = "M5Stack Tab5" +USB_MANUFACTURER = "M5Stack" + +IDF_TARGET = esp32p4 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 32MB +CIRCUITPY_ESP_PSRAM_MODE = hpi +CIRCUITPY_ESP_PSRAM_FREQ = 200m diff --git a/ports/espressif/boards/m5stack_tab5/pins.c b/ports/espressif/boards/m5stack_tab5/pins.c new file mode 100644 index 00000000000..c64d8803c02 --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/pins.c @@ -0,0 +1,132 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // M5-Bus and general GPIO + { MP_ROM_QSTR(MP_QSTR_G2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_G3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_G4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_G6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_G7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_G16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_G17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_G35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_G45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_G47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_G48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_G51), MP_ROM_PTR(&pin_GPIO51) }, + { MP_ROM_QSTR(MP_QSTR_G52), MP_ROM_PTR(&pin_GPIO52) }, + + // SPI (on M5-Bus) + { MP_ROM_QSTR(MP_QSTR_G5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_G18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_G19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + + // UART (on M5-Bus) + { MP_ROM_QSTR(MP_QSTR_G37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_TXD0), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_G38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_RXD0), MP_ROM_PTR(&pin_GPIO38) }, + + // I2C (Touch, IMU, RTC, Power Monitor, GPIO Expanders) + { MP_ROM_QSTR(MP_QSTR_G31), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_G32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO32) }, + + // Touch Panel + { MP_ROM_QSTR(MP_QSTR_G23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_TP_INT), MP_ROM_PTR(&pin_GPIO23) }, + + // LCD + { MP_ROM_QSTR(MP_QSTR_G22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO22) }, + + // Audio ES8388/ES7210 + { MP_ROM_QSTR(MP_QSTR_G26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DSDIN), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_G27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCLK), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_G28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_I2S_ASDOUT), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_G29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_G30), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO30) }, + + // Camera + { MP_ROM_QSTR(MP_QSTR_G36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_CAM_MCLK), MP_ROM_PTR(&pin_GPIO36) }, + + // microSD Card (SDIO mode) + { MP_ROM_QSTR(MP_QSTR_G39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT0), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_G40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT1), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_G41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT2), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_G42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT3), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_G43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_G44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO44) }, + + // RS485 + { MP_ROM_QSTR(MP_QSTR_G20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_RS485_TX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_G21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_RS485_RX), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_G34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_RS485_DIR), MP_ROM_PTR(&pin_GPIO34) }, + + // HY2.0-4P PORT.A + { MP_ROM_QSTR(MP_QSTR_G53), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_Y), MP_ROM_PTR(&pin_GPIO53) }, + { MP_ROM_QSTR(MP_QSTR_G54), MP_ROM_PTR(&pin_GPIO54) }, + { MP_ROM_QSTR(MP_QSTR_PORTA_W), MP_ROM_PTR(&pin_GPIO54) }, + + // ESP32-C6 SDIO interface + { MP_ROM_QSTR(MP_QSTR_G8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D3), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_G9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D2), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_G10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D1), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_G11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_D0), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_G12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_CK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_G13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_C6_SDIO2_CMD), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_G14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_C6_IO2), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_G15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_C6_RESET), MP_ROM_PTR(&pin_GPIO15) }, + + // I2C and SPI objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/m5stack_tab5/sdkconfig b/ports/espressif/boards/m5stack_tab5/sdkconfig new file mode 100644 index 00000000000..3bce8cc0c13 --- /dev/null +++ b/ports/espressif/boards/m5stack_tab5/sdkconfig @@ -0,0 +1,2 @@ +CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y +CONFIG_ESP32P4_REV_MIN_100=y diff --git a/ports/espressif/boards/m5stack_timer_camera_x/mpconfigboard.mk b/ports/espressif/boards/m5stack_timer_camera_x/mpconfigboard.mk index 4fcacd94d3d..e17f5061d9e 100644 --- a/ports/espressif/boards/m5stack_timer_camera_x/mpconfigboard.mk +++ b/ports/espressif/boards/m5stack_timer_camera_x/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = opi CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/m5stack_timer_camera_x/sdkconfig b/ports/espressif/boards/m5stack_timer_camera_x/sdkconfig index a600e00b31a..116258b906b 100644 --- a/ports/espressif/boards/m5stack_timer_camera_x/sdkconfig +++ b/ports/espressif/boards/m5stack_timer_camera_x/sdkconfig @@ -29,7 +29,6 @@ CONFIG_ESP_REV_MIN_FULL=300 # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="M5StackTimerX" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/magiclick_s3_n4r2/mpconfigboard.mk b/ports/espressif/boards/magiclick_s3_n4r2/mpconfigboard.mk index 6c2159c6478..fe2eb2c7a76 100644 --- a/ports/espressif/boards/magiclick_s3_n4r2/mpconfigboard.mk +++ b/ports/espressif/boards/magiclick_s3_n4r2/mpconfigboard.mk @@ -14,5 +14,6 @@ CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB +# No pins. CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_DISPLAYIO = 1 diff --git a/ports/espressif/boards/magiclick_s3_n4r2/sdkconfig b/ports/espressif/boards/magiclick_s3_n4r2/sdkconfig index 3e9b8e2f173..122e6f90246 100644 --- a/ports/espressif/boards/magiclick_s3_n4r2/sdkconfig +++ b/ports/espressif/boards/magiclick_s3_n4r2/sdkconfig @@ -8,7 +8,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="MagiClick-ESP32S3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/maker_badge/mpconfigboard.mk b/ports/espressif/boards/maker_badge/mpconfigboard.mk index 979ae581e3d..13229c02dbf 100644 --- a/ports/espressif/boards/maker_badge/mpconfigboard.mk +++ b/ports/espressif/boards/maker_badge/mpconfigboard.mk @@ -3,14 +3,12 @@ USB_PID = 0x2030 USB_PRODUCT = "Maker badge" USB_MANUFACTURER = "Czech maker" -CIRCUITPY_ESPCAMERA = 0 +IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=40m CIRCUITPY_ESP_FLASH_SIZE=4MB -IDF_TARGET = esp32s2 - FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ConnectionManager FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/maker_badge/sdkconfig b/ports/espressif/boards/maker_badge/sdkconfig index d62227df74f..e9628662160 100644 --- a/ports/espressif/boards/maker_badge/sdkconfig +++ b/ports/espressif/boards/maker_badge/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="Maker_badge" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/makerfabs_tft7/board.c b/ports/espressif/boards/makerfabs_tft7/board.c index dd0ffa26528..a994cfef381 100644 --- a/ports/espressif/boards/makerfabs_tft7/board.c +++ b/ports/espressif/boards/makerfabs_tft7/board.c @@ -6,13 +6,14 @@ #include "supervisor/board.h" #include "mpconfigboard.h" + #include "shared-bindings/board/__init__.h" #include "shared-bindings/dotclockframebuffer/DotClockFramebuffer.h" #include "shared-bindings/dotclockframebuffer/__init__.h" #include "shared-bindings/framebufferio/FramebufferDisplay.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-module/displayio/__init__.h" -#include "shared-module/os/__init__.h" +#include "supervisor/shared/settings.h" static const mcu_pin_obj_t *blue_pins[] = { &pin_GPIO8, @@ -40,14 +41,14 @@ static const mcu_pin_obj_t *red_pins[] = { static void display_init(void) { mp_int_t height = 0, width = 0, frequency = 0; - os_getenv_err_t result; + settings_err_t result; - result = common_hal_os_getenv_int("CIRCUITPY_DISPLAY_WIDTH", &width); - if (result == GETENV_OK && width == 800) { + result = settings_get_int("CIRCUITPY_DISPLAY_WIDTH", &width); + if (result == SETTINGS_OK && width == 800) { width = 800; height = 480; frequency = 6500000; - } else if (result == GETENV_OK && width == 1024) { + } else if (result == SETTINGS_OK && width == 1024) { width = 1024; height = 600; frequency = 10000000; diff --git a/ports/espressif/boards/makerfabs_tft7/sdkconfig b/ports/espressif/boards/makerfabs_tft7/sdkconfig index 5853b29ae94..e9628662160 100644 --- a/ports/espressif/boards/makerfabs_tft7/sdkconfig +++ b/ports/espressif/boards/makerfabs_tft7/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="matouch-tft" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk b/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk index 37c27203af3..d82f62df377 100644 --- a/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk +++ b/ports/espressif/boards/makergo_esp32c3_supermini/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/makergo_esp32c3_supermini/sdkconfig b/ports/espressif/boards/makergo_esp32c3_supermini/sdkconfig index dc7f10a362f..e9628662160 100644 --- a/ports/espressif/boards/makergo_esp32c3_supermini/sdkconfig +++ b/ports/espressif/boards/makergo_esp32c3_supermini/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="makergo-esp32c3-supermini" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/makergo_esp32c6_supermini/board.c b/ports/espressif/boards/makergo_esp32c6_supermini/board.c new file mode 100644 index 00000000000..8cb7168e0da --- /dev/null +++ b/ports/espressif/boards/makergo_esp32c6_supermini/board.c @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 bill88t +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "driver/gpio.h" +#include "common-hal/microcontroller/Pin.h" + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + if (pin_number == 15) { + // Turn on the spare led on boot as a power indicator. + config_pin_as_output_with_level(pin_number, true); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/makergo_esp32c6_supermini/mpconfigboard.h b/ports/espressif/boards/makergo_esp32c6_supermini/mpconfigboard.h new file mode 100644 index 00000000000..0d17aef1109 --- /dev/null +++ b/ports/espressif/boards/makergo_esp32c6_supermini/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bill Sideris, independently providing these changes. +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Board setup +#define MICROPY_HW_BOARD_NAME "Maker Go ESP32C6 Supermini" +#define MICROPY_HW_MCU_NAME "ESP32-C6" + +// Status LED +#define MICROPY_HW_NEOPIXEL (&pin_GPIO8) +#define MICROPY_HW_NEOPIXEL_COUNT (1) + +// Default bus pins +#define DEFAULT_UART_BUS_TX (&pin_GPIO17) +#define DEFAULT_UART_BUS_RX (&pin_GPIO16) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/makergo_esp32c6_supermini/mpconfigboard.mk b/ports/espressif/boards/makergo_esp32c6_supermini/mpconfigboard.mk new file mode 100644 index 00000000000..ca425c01593 --- /dev/null +++ b/ports/espressif/boards/makergo_esp32c6_supermini/mpconfigboard.mk @@ -0,0 +1,11 @@ +CIRCUITPY_CREATOR_ID = 0x19981000 +CIRCUITPY_CREATION_ID = 0x00C60001 + +IDF_TARGET = esp32c6 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/makergo_esp32c6_supermini/pins.c b/ports/espressif/boards/makergo_esp32c6_supermini/pins.c new file mode 100644 index 00000000000..b396e5bb1af --- /dev/null +++ b/ports/espressif/boards/makergo_esp32c6_supermini/pins.c @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bill Sideris, independently providing these changes. +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Left to Right top to bottom + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + // Extras + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/makergo_esp32c6_supermini/sdkconfig b/ports/espressif/boards/makergo_esp32c6_supermini/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/makergo_esp32c6_supermini/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk index b2ea6005db5..79821f7c0e5 100644 --- a/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk +++ b/ports/espressif/boards/microdev_micro_c3/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/microdev_micro_c3/sdkconfig b/ports/espressif/boards/microdev_micro_c3/sdkconfig index 9b13279bd38..e9628662160 100644 --- a/ports/espressif/boards/microdev_micro_c3/sdkconfig +++ b/ports/espressif/boards/microdev_micro_c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="MicroDev-microC3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h b/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h index b7b327b23d3..db2d353f998 100644 --- a/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h +++ b/ports/espressif/boards/microdev_micro_s2/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DEFAULT_UART_BUS_RX (&pin_GPIO44) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/microdev_micro_s2/sdkconfig b/ports/espressif/boards/microdev_micro_s2/sdkconfig index f6158eac3ec..e9628662160 100644 --- a/ports/espressif/boards/microdev_micro_s2/sdkconfig +++ b/ports/espressif/boards/microdev_micro_s2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="MicroDev-microS2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk index 1d370fd30e7..9b96aa31c9e 100644 --- a/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_serial/mpconfigboard.mk @@ -9,12 +9,6 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_AESIO = 0 -CIRCUITPY_AUDIOBUSIO = 0 -CIRCUITPY_CANIO = 0 -CIRCUITPY_CODEOP = 0 -CIRCUITPY_ESPCAMERA = 0 - FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ConnectionManager FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk b/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk index 691da625e03..d6447ee7134 100644 --- a/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk +++ b/ports/espressif/boards/mixgo_ce_udisk/mpconfigboard.mk @@ -9,10 +9,6 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_AESIO = 0 -CIRCUITPY_CODEOP = 0 -CIRCUITPY_ESPCAMERA = 0 - FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ConnectionManager FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Requests FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/morpheans_morphesp-240/board.c b/ports/espressif/boards/morpheans_morphesp-240/board.c index 5b1c3f82bbb..44266cce6ed 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/board.c +++ b/ports/espressif/boards/morpheans_morphesp-240/board.c @@ -138,9 +138,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO14, // DC - &pin_GPIO10, // CS - &pin_GPIO9, // RST + MP_OBJ_FROM_PTR(&pin_GPIO14), // DC + MP_OBJ_FROM_PTR(&pin_GPIO10), // CS + MP_OBJ_FROM_PTR(&pin_GPIO9), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk b/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk index 8a6b359d238..5c806cb69b2 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk +++ b/ports/espressif/boards/morpheans_morphesp-240/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/morpheans_morphesp-240/sdkconfig b/ports/espressif/boards/morpheans_morphesp-240/sdkconfig index b0a838eacc8..e9628662160 100644 --- a/ports/espressif/boards/morpheans_morphesp-240/sdkconfig +++ b/ports/espressif/boards/morpheans_morphesp-240/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="MORPHESP-240" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk index bb3c0ea4d82..b2540a8c3b8 100644 --- a/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/muselab_nanoesp32_s2_wroom/mpconfigboard.mk @@ -8,4 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/board.c b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/board.c new file mode 100755 index 00000000000..e2517f8640a --- /dev/null +++ b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/board.c @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "driver/gpio.h" + +void board_init(void) { + reset_board(); +} + +void reset_board(void) { + // Turn on I2C power by default. + gpio_set_direction(14, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(14, true); + + // Turn on SD power by default + gpio_set_direction(3, GPIO_MODE_DEF_OUTPUT); + gpio_set_level(3, true); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/mpconfigboard.h b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/mpconfigboard.h new file mode 100755 index 00000000000..c3181ea9431 --- /dev/null +++ b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/mpconfigboard.h @@ -0,0 +1,36 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "NHB Systems JL401-S3 4MB Flash 2MB PSRAM" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO1) +#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO2) + +// #define MICROPY_HW_LED_STATUS (&pin_GPIO13) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO48) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO47) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO12) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO13) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO18) +#define DEFAULT_UART_BUS_TX (&pin_GPIO17) + +#define DOUBLE_TAP_PIN (&pin_GPIO38) + +#define DEFAULT_SD_SCK (&pin_GPIO12) +#define DEFAULT_SD_MOSI (&pin_GPIO11) +#define DEFAULT_SD_MISO (&pin_GPIO13) +#define DEFAULT_SD_CS (&pin_GPIO10) +#define DEFAULT_SD_CARD_DETECT (&pin_GPIO9) +#define DEFAULT_SD_CARD_INSERTED true diff --git a/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/mpconfigboard.mk b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/mpconfigboard.mk new file mode 100755 index 00000000000..fdc981fdccc --- /dev/null +++ b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x834A +USB_PRODUCT = "NHB Systems JL401-S3 4MB Flash 2MB PSRAM" +USB_MANUFACTURER = "NHB Systems" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/pins.c b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/pins.c new file mode 100644 index 00000000000..111659bee61 --- /dev/null +++ b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/pins.c @@ -0,0 +1,89 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL_POWER), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_SD_PWR), MP_ROM_PTR(&pin_GPIO3)}, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + + // { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + // { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_I2C_POWER), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + // D33 to D36 used for AD7124 SPI + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + // { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/sdkconfig b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/sdkconfig new file mode 100755 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/nhbsystems_jl401_4mbflash_2mbpsram/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/nodemcu_esp32c2/mpconfigboard.mk b/ports/espressif/boards/nodemcu_esp32c2/mpconfigboard.mk index dd90b325b6d..249dd80bebd 100644 --- a/ports/espressif/boards/nodemcu_esp32c2/mpconfigboard.mk +++ b/ports/espressif/boards/nodemcu_esp32c2/mpconfigboard.mk @@ -6,3 +6,6 @@ IDF_TARGET = esp32c2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 60m CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/nodemcu_esp32c2/sdkconfig b/ports/espressif/boards/nodemcu_esp32c2/sdkconfig index ed7abbdd59b..f53dd7f8795 100644 --- a/ports/espressif/boards/nodemcu_esp32c2/sdkconfig +++ b/ports/espressif/boards/nodemcu_esp32c2/sdkconfig @@ -32,7 +32,6 @@ CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200 # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="nodemcu-esp32c2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/odt_pixelwing_esp32_s2/sdkconfig b/ports/espressif/boards/odt_pixelwing_esp32_s2/sdkconfig index 3017a9532f6..e9628662160 100644 --- a/ports/espressif/boards/odt_pixelwing_esp32_s2/sdkconfig +++ b/ports/espressif/boards/odt_pixelwing_esp32_s2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="PixelWing-ESP32S2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/oxocard_artwork/board.c b/ports/espressif/boards/oxocard_artwork/board.c index 600bc0c5943..5fe8e814558 100644 --- a/ports/espressif/boards/oxocard_artwork/board.c +++ b/ports/espressif/boards/oxocard_artwork/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase @@ -60,7 +60,7 @@ static void display_init(void) { 240, // width (after rotation) 240, // height (after rotation) 0, // column start - 80, // row start + 0, // row start 0, // rotation 16, // color depth false, // grayscale diff --git a/ports/espressif/boards/oxocard_artwork/mpconfigboard.mk b/ports/espressif/boards/oxocard_artwork/mpconfigboard.mk index a7dfe8b8e33..61367774a21 100644 --- a/ports/espressif/boards/oxocard_artwork/mpconfigboard.mk +++ b/ports/espressif/boards/oxocard_artwork/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/oxocard_connect/board.c b/ports/espressif/boards/oxocard_connect/board.c index 89be45c8226..2c013811474 100644 --- a/ports/espressif/boards/oxocard_connect/board.c +++ b/ports/espressif/boards/oxocard_connect/board.c @@ -44,9 +44,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/oxocard_connect/mpconfigboard.mk b/ports/espressif/boards/oxocard_connect/mpconfigboard.mk index 49b8a4f4c87..ea00787921d 100644 --- a/ports/espressif/boards/oxocard_connect/mpconfigboard.mk +++ b/ports/espressif/boards/oxocard_connect/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/oxocard_connect/pins.c b/ports/espressif/boards/oxocard_connect/pins.c index dbee3e0c435..3a1a88786c1 100644 --- a/ports/espressif/boards/oxocard_connect/pins.c +++ b/ports/espressif/boards/oxocard_connect/pins.c @@ -12,8 +12,8 @@ CIRCUITPY_BOARD_BUS_SINGLETON(stemma_i2c, i2c, 1) static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_BTN5), MP_ROM_PTR(&pin_GPIO0) }, - { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BTN5), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO2) }, { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, { MP_ROM_QSTR(MP_QSTR_LCD_LED), MP_ROM_PTR(&pin_GPIO19) }, @@ -39,7 +39,6 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_IN06), MP_ROM_PTR(&pin_GPIO34) }, { MP_ROM_QSTR(MP_QSTR_IN07), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/espressif/boards/oxocard_galaxy/board.c b/ports/espressif/boards/oxocard_galaxy/board.c index 600bc0c5943..5fe8e814558 100644 --- a/ports/espressif/boards/oxocard_galaxy/board.c +++ b/ports/espressif/boards/oxocard_galaxy/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase @@ -60,7 +60,7 @@ static void display_init(void) { 240, // width (after rotation) 240, // height (after rotation) 0, // column start - 80, // row start + 0, // row start 0, // rotation 16, // color depth false, // grayscale diff --git a/ports/espressif/boards/oxocard_galaxy/mpconfigboard.mk b/ports/espressif/boards/oxocard_galaxy/mpconfigboard.mk index 915d7cc5862..e4786df383c 100644 --- a/ports/espressif/boards/oxocard_galaxy/mpconfigboard.mk +++ b/ports/espressif/boards/oxocard_galaxy/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/oxocard_science/board.c b/ports/espressif/boards/oxocard_science/board.c index 600bc0c5943..5fe8e814558 100644 --- a/ports/espressif/boards/oxocard_science/board.c +++ b/ports/espressif/boards/oxocard_science/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO27, // DC - &pin_GPIO15, // CS - &pin_GPIO4, // RST + MP_OBJ_FROM_PTR(&pin_GPIO27), // DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // CS + MP_OBJ_FROM_PTR(&pin_GPIO4), // RST 24000000, // baudrate 0, // polarity 0 // phase @@ -60,7 +60,7 @@ static void display_init(void) { 240, // width (after rotation) 240, // height (after rotation) 0, // column start - 80, // row start + 0, // row start 0, // rotation 16, // color depth false, // grayscale diff --git a/ports/espressif/boards/oxocard_science/mpconfigboard.mk b/ports/espressif/boards/oxocard_science/mpconfigboard.mk index d31be7d7992..9d89108f392 100644 --- a/ports/espressif/boards/oxocard_science/mpconfigboard.mk +++ b/ports/espressif/boards/oxocard_science/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/pcbcupid_glyph_c3/board.c b/ports/espressif/boards/pcbcupid_glyph_c3/board.c new file mode 100644 index 00000000000..8bc15c17551 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c3/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 PCBCupid +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/pcbcupid_glyph_c3/mpconfigboard.h b/ports/espressif/boards/pcbcupid_glyph_c3/mpconfigboard.h new file mode 100644 index 00000000000..064559a4dc8 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c3/mpconfigboard.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 PCBCupid +// +// SPDX-License-Identifier: MIT +#pragma once + +#define MICROPY_HW_BOARD_NAME "PCBCupid GLYPH C3" +#define MICROPY_HW_MCU_NAME "ESP32-C3" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO1) + +#define DEFAULT_UART_BUS_TX (&pin_GPIO21) +#define DEFAULT_UART_BUS_RX (&pin_GPIO20) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO10) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO6) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO7) diff --git a/ports/espressif/boards/pcbcupid_glyph_c3/mpconfigboard.mk b/ports/espressif/boards/pcbcupid_glyph_c3/mpconfigboard.mk new file mode 100644 index 00000000000..dea0619ee7e --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c3/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x20241402 +CIRCUITPY_CREATION_ID = 0x00C30001 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/pcbcupid_glyph_c3/pins.c b/ports/espressif/boards/pcbcupid_glyph_c3/pins.c new file mode 100644 index 00000000000..2d15da17bd9 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c3/pins.c @@ -0,0 +1,36 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 PCBCupid +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/board/__init__.h" +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/pcbcupid_glyph_c3/sdkconfig b/ports/espressif/boards/pcbcupid_glyph_c3/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c3/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/pcbcupid_glyph_c6/board.c b/ports/espressif/boards/pcbcupid_glyph_c6/board.c new file mode 100644 index 00000000000..3c254a05417 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c6/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 PCBCupid +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/pcbcupid_glyph_c6/mpconfigboard.h b/ports/espressif/boards/pcbcupid_glyph_c6/mpconfigboard.h new file mode 100644 index 00000000000..6c83a0f4ecb --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c6/mpconfigboard.h @@ -0,0 +1,18 @@ +#pragma once + +#define MICROPY_HW_BOARD_NAME "Pcbcupid GLYPH C6" +#define MICROPY_HW_MCU_NAME "ESP32-C6" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO14) + +#define DEFAULT_UART_BUS_TX (&pin_GPIO16) +#define DEFAULT_UART_BUS_RX (&pin_GPIO17) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO21) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO23) + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) diff --git a/ports/espressif/boards/pcbcupid_glyph_c6/mpconfigboard.mk b/ports/espressif/boards/pcbcupid_glyph_c6/mpconfigboard.mk new file mode 100644 index 00000000000..8c2e6d74453 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c6/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x20241402 +CIRCUITPY_CREATION_ID = 0x00C60001 + +IDF_TARGET = esp32c6 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/pcbcupid_glyph_c6/pins.c b/ports/espressif/boards/pcbcupid_glyph_c6/pins.c new file mode 100644 index 00000000000..c2a4db30854 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c6/pins.c @@ -0,0 +1,56 @@ +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/pcbcupid_glyph_c6/sdkconfig b/ports/espressif/boards/pcbcupid_glyph_c6/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_c6/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/pcbcupid_glyph_h2/board.c b/ports/espressif/boards/pcbcupid_glyph_h2/board.c new file mode 100644 index 00000000000..4e6bc405957 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_h2/board.c @@ -0,0 +1,7 @@ +// SPDX-FileCopyrightText: Copyright (c) 2024 PCBCupid +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/pcbcupid_glyph_h2/mpconfigboard.h b/ports/espressif/boards/pcbcupid_glyph_h2/mpconfigboard.h new file mode 100644 index 00000000000..0060381696e --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_h2/mpconfigboard.h @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: Copyright (c) 2024 PCBCupid +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Pcbcupid GLYPH H2" +#define MICROPY_HW_MCU_NAME "ESP32H2" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO0) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO25) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO23) +#define DEFAULT_UART_BUS_TX (&pin_GPIO24) diff --git a/ports/espressif/boards/pcbcupid_glyph_h2/mpconfigboard.mk b/ports/espressif/boards/pcbcupid_glyph_h2/mpconfigboard.mk new file mode 100644 index 00000000000..4acde24d6f6 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_h2/mpconfigboard.mk @@ -0,0 +1,11 @@ +CIRCUITPY_CREATOR_ID = 0x20241402 +CIRCUITPY_CREATION_ID = 0x00110001 + +IDF_TARGET = esp32h2 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 48m +CIRCUITPY_ESP_FLASH_SIZE = 4MB +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 + +CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/pcbcupid_glyph_h2/pins.c b/ports/espressif/boards/pcbcupid_glyph_h2/pins.c new file mode 100644 index 00000000000..550ba4e3101 --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_h2/pins.c @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: Copyright (c) 2024 PCBCupid +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO0) }, + + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_IO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO23) }, + + + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO5) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/pcbcupid_glyph_h2/sdkconfig b/ports/espressif/boards/pcbcupid_glyph_h2/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/pcbcupid_glyph_s3/board.c b/ports/espressif/boards/pcbcupid_glyph_s3/board.c new file mode 100644 index 00000000000..27b058c946f --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_s3/board.c @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 PCBCupid +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +void board_init(void) { +} diff --git a/ports/espressif/boards/pcbcupid_glyph_s3/mpconfigboard.h b/ports/espressif/boards/pcbcupid_glyph_s3/mpconfigboard.h new file mode 100644 index 00000000000..bc17cb65dfc --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_s3/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 PCBCupid +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "PCBCupid GLYPH S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO21) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO35) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO36) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/pcbcupid_glyph_s3/mpconfigboard.mk b/ports/espressif/boards/pcbcupid_glyph_s3/mpconfigboard.mk new file mode 100644 index 00000000000..9228197411f --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_s3/mpconfigboard.mk @@ -0,0 +1,10 @@ +USB_VID = 0x303A +USB_PID = 0x8373 +USB_PRODUCT = "GLYPH S3" +USB_MANUFACTURER = "PCBCupid" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB diff --git a/ports/espressif/boards/pcbcupid_glyph_s3/pins.c b/ports/espressif/boards/pcbcupid_glyph_s3/pins.c new file mode 100644 index 00000000000..5b962f2f74d --- /dev/null +++ b/ports/espressif/boards/pcbcupid_glyph_s3/pins.c @@ -0,0 +1,59 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 PCBCupid +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/pcbcupid_glyph_s3/sdkconfig b/ports/espressif/boards/pcbcupid_glyph_s3/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/board.c b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.h b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.h new file mode 100644 index 00000000000..2114fecf373 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Prokyber Ai-On-The-Edge-Cam" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO12) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO48) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.mk b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.mk new file mode 100644 index 00000000000..82419bb8074 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x1209 +USB_PID = 0xDABB +USB_PRODUCT = "AI-ON-THE-EDGE-CAM" +USB_MANUFACTURER = "Prokyber" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m +CIRCUITPY_ESP_PSRAM_SIZE = 8MB diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c new file mode 100644 index 00000000000..68dc40781a4 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/pins.c @@ -0,0 +1,106 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" + +static const mp_rom_obj_tuple_t camera_data_tuple = { + {&mp_type_tuple}, + 8, + { + MP_ROM_PTR(&pin_GPIO11), + MP_ROM_PTR(&pin_GPIO9), + MP_ROM_PTR(&pin_GPIO8), + MP_ROM_PTR(&pin_GPIO10), + MP_ROM_PTR(&pin_GPIO47), + MP_ROM_PTR(&pin_GPIO18), + MP_ROM_PTR(&pin_GPIO17), + MP_ROM_PTR(&pin_GPIO16), + } +}; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_PER_EN), MP_ROM_PTR(&pin_GPIO46) }, + + // SD + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + + // Ethernet + { MP_ROM_QSTR(MP_QSTR_ETH_RST), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_ETH_INT), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_ETH_MOSI), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_ETH_MISO), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_ETH_CLK), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_ETH_CS), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + + // LEDs + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA), MP_ROM_PTR(&camera_data_tuple) }, + + { MP_ROM_QSTR(MP_QSTR_CAMERA_VSYNC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_HREF), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA9), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_XCLK), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA8), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA7), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_PCLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA6), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA2), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA5), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA3), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_DATA4), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOD), MP_ROM_PTR(&pin_GPIO4) }, // SDA + { MP_ROM_QSTR(MP_QSTR_CAMERA_SIOC), MP_ROM_PTR(&pin_GPIO5) }, // SCL + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/prokyber_ai_on_the_edge_cam/sdkconfig b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/sdkconfig new file mode 100644 index 00000000000..ac1c5357176 --- /dev/null +++ b/ports/espressif/boards/prokyber_ai_on_the_edge_cam/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP +CONFIG_OV2640_SUPPORT=y +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/red-s2-wroom/board.c b/ports/espressif/boards/red-s2-wroom/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/red-s2-wroom/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/red-s2-wroom/mpconfigboard.h b/ports/espressif/boards/red-s2-wroom/mpconfigboard.h new file mode 100644 index 00000000000..24a5948e0c1 --- /dev/null +++ b/ports/espressif/boards/red-s2-wroom/mpconfigboard.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Red S2-WROOM" +#define MICROPY_HW_MCU_NAME "ESP32S2" diff --git a/ports/espressif/boards/red-s2-wroom/mpconfigboard.mk b/ports/espressif/boards/red-s2-wroom/mpconfigboard.mk new file mode 100644 index 00000000000..33a83f954a7 --- /dev/null +++ b/ports/espressif/boards/red-s2-wroom/mpconfigboard.mk @@ -0,0 +1,10 @@ +USB_VID = 0x303A +USB_PID = 0x82C4 +USB_PRODUCT = "ESP32-S2-WROOM" +USB_MANUFACTURER = "Unknown" + +IDF_TARGET = esp32s2 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/red-s2-wroom/pins.c b/ports/espressif/boards/red-s2-wroom/pins.c new file mode 100644 index 00000000000..1e0be2b4e8a --- /dev/null +++ b/ports/espressif/boards/red-s2-wroom/pins.c @@ -0,0 +1,55 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/red-s2-wroom/sdkconfig b/ports/espressif/boards/red-s2-wroom/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/board.c b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/board.c index 6cc4f2e089e..fea7fe2c300 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/board.c +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/board.c @@ -4,10 +4,6 @@ // // SPDX-License-Identifier: MIT -#include "supervisor/board.h" #include "mpconfigboard.h" -#include "esp_log.h" -#include "esp_err.h" -#include "driver/i2c.h" // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h index c05b6a93a10..d7f24b255d6 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/mpconfigboard.h @@ -12,9 +12,9 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO7) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO9) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO7) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO9) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO6) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO6) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c index aa3a6f7b7f5..fbb6014685c 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/pins.c @@ -31,49 +31,92 @@ static const mp_rom_obj_tuple_t camera_data_tuple = { static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO1) }, - { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO2) }, - { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO3) }, - { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO4) }, - { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO5) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO6) }, - { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, - { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO9) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO8) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SD), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_I2S_SCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SCL), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_RX_1), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX_1), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SCK_1), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_MISO_1), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D5), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_MOSI_1), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D6), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_SDCS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_CAM_DATA), MP_ROM_PTR(&camera_data_tuple) }, { MP_ROM_QSTR(MP_QSTR_CAM_D0), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_CAM_D1), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_CAM_D2), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_CAM_D3), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_CAM_D4), MP_ROM_PTR(&pin_GPIO14) }, - { MP_ROM_QSTR(MP_QSTR_CAM_D5), MP_ROM_PTR(&pin_GPIO12) }, - { MP_ROM_QSTR(MP_QSTR_CAM_D6), MP_ROM_PTR(&pin_GPIO11) }, { MP_ROM_QSTR(MP_QSTR_CAM_D7), MP_ROM_PTR(&pin_GPIO48) }, - { MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO10) }, { MP_ROM_QSTR(MP_QSTR_CAM_HREF), MP_ROM_PTR(&pin_GPIO47) }, - { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO13) }, - { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO38) }, - { MP_ROM_QSTR(MP_QSTR_CAM_SCL), MP_ROM_PTR(&pin_GPIO39) }, - { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO40) }, - { MP_ROM_QSTR(MP_QSTR_MIC_DATA), MP_ROM_PTR(&pin_GPIO41) }, - { MP_ROM_QSTR(MP_QSTR_MIC_CLK), MP_ROM_PTR(&pin_GPIO42) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/sdkconfig b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/sdkconfig index 3023ed221c3..2d98e822542 100644 --- a/ports/espressif/boards/seeed_xiao_esp32_s3_sense/sdkconfig +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_sense/sdkconfig @@ -5,16 +5,13 @@ # Component config # # -# LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" -# end of LWIP # Camera configuration # -CONFIG_OV2640_SUPPORT=y # CONFIG_OV7725_SUPPORT is not set -# CONFIG_OV3660_SUPPORT is not set +CONFIG_OV2640_SUPPORT=y # end of Camera configuration + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/board.c b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/board.c new file mode 100644 index 00000000000..fea7fe2c300 --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "mpconfigboard.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/mpconfigboard.h b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/mpconfigboard.h new file mode 100644 index 00000000000..79deafd6125 --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/mpconfigboard.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Bernhard Bablok +// +// SPDX-License-Identifier: MIT + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Seeed Xiao ESP32-S3 Trmnl DIY Kit" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO21) + +// the unpopulated NFC-header also provides UART +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.rx = &pin_GPIO41, .tx = &pin_GPIO42}} + +// SPI0 is used by the display connector +// SPI1 is used by a two secondary flash chips (one unpopulated) +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN \ + {{.clock = &pin_GPIO7, .mosi = &pin_GPIO9}, \ + {.clock = &pin_GPIO13, .mosi = &pin_GPIO11, .miso = &pin_GPIO12} \ + } diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/mpconfigboard.mk b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/mpconfigboard.mk new file mode 100644 index 00000000000..9a6b15aa76c --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/mpconfigboard.mk @@ -0,0 +1,32 @@ +USB_VID = 0x2886 +USB_PID = 0x0300 + +USB_PRODUCT = "Seeed Xiao ESP32-S3 Trmnl DIY Kit" +USB_MANUFACTURER = "Seeed Studio" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_RAINBOWIO = 0 +CIRCUITPY__EVE = 0 +CIRCUITPY_PS2IO = 0 +CIRCUITPY_CANIO = 0 +CIRCUITPY_MAX3421E = 0 +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_PARALLELDISPLAYBUS = 0 +CIRCUITPY_COUNTIO = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_ROTARYIO = 0 + +CIRCUITPY_AUDIOCORE = 0 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOBUSIO_PDMIN = 0 +CIRCUITPY_AUDIOI2SIN = 0 diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/pins.c b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/pins.c new file mode 100644 index 00000000000..422f16b787b --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/pins.c @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_BTN1), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_BTN2), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_EDP_BUSY), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_BTN3), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_ADC_EN), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_CLK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_MOSI), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_EDP_DC), MP_ROM_PTR(&pin_GPIO10) }, + + // connected to two additional flash chips (one unpopulated) + { MP_ROM_QSTR(MP_QSTR_SPI1_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SPI1_MISO), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SPI1_CLK), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_EDP_RES), MP_ROM_PTR(&pin_GPIO38) }, + + // connected to two additional flash chips (CS0 unpopulated) + { MP_ROM_QSTR(MP_QSTR_SPI1_CS0), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SPI1_CS1), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_PWR_EN), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_CS), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/sdkconfig b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/sdkconfig new file mode 100644 index 00000000000..ce6696bf50f --- /dev/null +++ b/ports/espressif/boards/seeed_xiao_esp32_s3_trmnl_diy_kit/sdkconfig @@ -0,0 +1,11 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk index b71a41ef6e3..c5b266ca744 100644 --- a/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk +++ b/ports/espressif/boards/seeed_xiao_esp32c3/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/seeed_xiao_esp32c3/sdkconfig b/ports/espressif/boards/seeed_xiao_esp32c3/sdkconfig index a593f1d1736..e9628662160 100644 --- a/ports/espressif/boards/seeed_xiao_esp32c3/sdkconfig +++ b/ports/espressif/boards/seeed_xiao_esp32c3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="seeed-xiao-esp32c3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.h b/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.h index 6f803cd9c96..6918056cf86 100644 --- a/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.h +++ b/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.h @@ -17,3 +17,6 @@ // For entering safe mode, use BOOT button #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.mk b/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.mk index 9d95fe94449..ce6763afbcc 100644 --- a/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.mk +++ b/ports/espressif/boards/seeed_xiao_esp32c6/mpconfigboard.mk @@ -6,3 +6,6 @@ IDF_TARGET = esp32c6 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/seeed_xiao_esp32c6/pins.c b/ports/espressif/boards/seeed_xiao_esp32c6/pins.c index b7aeb90d2b1..1b62b37065e 100644 --- a/ports/espressif/boards/seeed_xiao_esp32c6/pins.c +++ b/ports/espressif/boards/seeed_xiao_esp32c6/pins.c @@ -47,6 +47,9 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO6) }, { MP_ROM_QSTR(MP_QSTR_LP_I2C_SDA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_LED_INVERTED), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_LP_I2C_SCL), MP_ROM_PTR(&pin_GPIO7) }, diff --git a/ports/espressif/boards/seeed_xiao_esp32c6/sdkconfig b/ports/espressif/boards/seeed_xiao_esp32c6/sdkconfig index a69b0b6c770..e9628662160 100644 --- a/ports/espressif/boards/seeed_xiao_esp32c6/sdkconfig +++ b/ports/espressif/boards/seeed_xiao_esp32c6/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="seeed-xiao-esp32c6" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk index a8c32ae88df..6b97c870cc0 100644 --- a/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk +++ b/ports/espressif/boards/sensebox_mcu_esp32s2/mpconfigboard.mk @@ -1,7 +1,7 @@ USB_VID = 0x303A USB_PID = 0x81B9 USB_PRODUCT = "senseBox MCU-S2 ESP32S2" -USB_MANUFACTURER = "Espressif" +USB_MANUFACTURER = "senseBox" IDF_TARGET = esp32s2 @@ -9,8 +9,6 @@ CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m -CIRCUITPY_ESPCAMERA = 0 - CIRCUITPY_REQUIRE_I2C_PULLUPS = 0 CIRCUITPY_I2C_ALLOW_STRAPPING_PINS = 1 diff --git a/ports/espressif/boards/sensebox_mcu_esp32s2/sdkconfig b/ports/espressif/boards/sensebox_mcu_esp32s2/sdkconfig index d8608c527c0..e9628662160 100644 --- a/ports/espressif/boards/sensebox_mcu_esp32s2/sdkconfig +++ b/ports/espressif/boards/sensebox_mcu_esp32s2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="senseBox MCU-S2 ESP32S2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/sensebox_mcu_eye_esp32s3/board.c b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/board.c new file mode 100644 index 00000000000..fea7fe2c300 --- /dev/null +++ b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "mpconfigboard.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/sensebox_mcu_eye_esp32s3/mpconfigboard.h b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/mpconfigboard.h new file mode 100644 index 00000000000..300154fe344 --- /dev/null +++ b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "senseBox MCU Eye ESP32S3" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO45) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO1) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) diff --git a/ports/espressif/boards/sensebox_mcu_eye_esp32s3/mpconfigboard.mk b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/mpconfigboard.mk new file mode 100644 index 00000000000..be3c65746c8 --- /dev/null +++ b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/mpconfigboard.mk @@ -0,0 +1,21 @@ +USB_VID = 0x303A +USB_PID = 0x82D2 + +USB_PRODUCT = "senseBox-eye ESP32S3" +USB_MANUFACTURER = "senseBox" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_ESPCAMERA = 1 +CIRCUITPY_AUDIOBUSIO = 1 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/sensebox_mcu_eye_esp32s3/pins.c b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/pins.c new file mode 100644 index 00000000000..71b984f7ff5 --- /dev/null +++ b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/pins.c @@ -0,0 +1,82 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(sscb_i2c, i2c, 2) + +static const mp_rom_obj_tuple_t camera_data_tuple = { + // The order matters. + // They must be ordered from low to high (CAM_D0, CAM_D1...CAM_D7). + + // Do not include any of the control pins in here. + {&mp_type_tuple}, + 8, + { + MP_ROM_PTR(&pin_GPIO11), + MP_ROM_PTR(&pin_GPIO9), + MP_ROM_PTR(&pin_GPIO8), + MP_ROM_PTR(&pin_GPIO10), + MP_ROM_PTR(&pin_GPIO12), + MP_ROM_PTR(&pin_GPIO18), + MP_ROM_PTR(&pin_GPIO17), + MP_ROM_PTR(&pin_GPIO16), + } +}; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + {MP_ROM_QSTR(MP_QSTR_BUTTON_SW), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_A48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_UART_ENABLE), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_CAM_DATA), MP_ROM_PTR(&camera_data_tuple) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D0), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D2), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D3), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D4), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D5), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D6), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D7), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_CAM_HREF), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CAM_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_PWDN), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCLK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_SD_ENABLE), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/sensebox_mcu_eye_esp32s3/sdkconfig b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/sdkconfig new file mode 100644 index 00000000000..919f4d9f345 --- /dev/null +++ b/ports/espressif/boards/sensebox_mcu_eye_esp32s3/sdkconfig @@ -0,0 +1,19 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP +# Camera configuration +# +CONFIG_OV2640_SUPPORT=y +# CONFIG_OV7725_SUPPORT is not set +# CONFIG_OV3660_SUPPORT is not set +# end of Camera configuration +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/smartbeedesigns_bee_data_logger/mpconfigboard.mk b/ports/espressif/boards/smartbeedesigns_bee_data_logger/mpconfigboard.mk index 6ded5c4e198..6465252ac46 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_data_logger/mpconfigboard.mk +++ b/ports/espressif/boards/smartbeedesigns_bee_data_logger/mpconfigboard.mk @@ -9,10 +9,8 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB - FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DS3231 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/smartbeedesigns_bee_data_logger/sdkconfig b/ports/espressif/boards/smartbeedesigns_bee_data_logger/sdkconfig index deb1b88d7ca..e9628662160 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_data_logger/sdkconfig +++ b/ports/espressif/boards/smartbeedesigns_bee_data_logger/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="smartbeedesigns_bee_data_logger" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk index 72ad30af2e0..5bfa7340d56 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/mpconfigboard.mk @@ -9,6 +9,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB - FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/sdkconfig b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/sdkconfig index fe95b60d4c8..e9628662160 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_motion_s3/sdkconfig +++ b/ports/espressif/boards/smartbeedesigns_bee_motion_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="smartbeedesigns_bee_motion_s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk index 095924385b7..fc11e4bd21c 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/mpconfigboard.mk @@ -9,6 +9,4 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 8MB - FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/smartbeedesigns_bee_s3/sdkconfig b/ports/espressif/boards/smartbeedesigns_bee_s3/sdkconfig index 2c7a057567f..e9628662160 100644 --- a/ports/espressif/boards/smartbeedesigns_bee_s3/sdkconfig +++ b/ports/espressif/boards/smartbeedesigns_bee_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="smartbeedesigns_bee_s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/solderparty_esp32p4_stamp_xl/board.c b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/solderparty_esp32p4_stamp_xl/mpconfigboard.h b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/mpconfigboard.h new file mode 100644 index 00000000000..d6a8b734f62 --- /dev/null +++ b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "ESP32-P4 Stamp XL" +#define MICROPY_HW_MCU_NAME "ESP32P4" + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO38) +#define DEFAULT_UART_BUS_TX (&pin_GPIO37) + +#define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX +#define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX diff --git a/ports/espressif/boards/solderparty_esp32p4_stamp_xl/mpconfigboard.mk b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/mpconfigboard.mk new file mode 100644 index 00000000000..ff633cbae2a --- /dev/null +++ b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x1209 +USB_PID = 0x0001 +USB_PRODUCT = "ESP32-P4 Stamp XL" +USB_MANUFACTURER = "Solder Party" + +IDF_TARGET = esp32p4 + +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 32MB +CIRCUITPY_ESP_PSRAM_MODE = hpi +CIRCUITPY_ESP_PSRAM_FREQ = 200m diff --git a/ports/espressif/boards/solderparty_esp32p4_stamp_xl/pins.c b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/pins.c new file mode 100644 index 00000000000..03f2d0dd2a3 --- /dev/null +++ b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/pins.c @@ -0,0 +1,49 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_IO25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_IO26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_IO27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_IO28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_IO29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_IO30), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_IO31), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_IO32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_IO49), MP_ROM_PTR(&pin_GPIO49) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/solderparty_esp32p4_stamp_xl/sdkconfig b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/sdkconfig new file mode 100644 index 00000000000..3bce8cc0c13 --- /dev/null +++ b/ports/espressif/boards/solderparty_esp32p4_stamp_xl/sdkconfig @@ -0,0 +1,2 @@ +CONFIG_ESP32P4_SELECTS_REV_LESS_V3=y +CONFIG_ESP32P4_REV_MIN_100=y diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c b/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c index 89bcbf6b8dd..f4288ae45ac 100644 --- a/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/board.c @@ -42,9 +42,9 @@ static bool display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO0, // DC - &pin_GPIO2, // CS - &pin_GPIO5, // RST + MP_OBJ_FROM_PTR(&pin_GPIO0), // DC + MP_OBJ_FROM_PTR(&pin_GPIO2), // CS + MP_OBJ_FROM_PTR(&pin_GPIO5), // RST 10000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/sdkconfig b/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/sdkconfig index f3f2d53d3b8..e9628662160 100644 --- a/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/sdkconfig +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_44/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="spotpear-esp32c3-lcd-1-44" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/board.c b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/board.c new file mode 100644 index 00000000000..30879e71404 --- /dev/null +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/board.c @@ -0,0 +1,84 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + + +#define DELAY 0x80 + +// display init sequence according to ST7789 +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, 0 | DELAY, 0xff, // _SLPOUT and Delay 500ms + 0x3A, 1 | DELAY, 0x55, 0x0a, // _COLMOD and Delay 10ms + 0x36, 0x01, 0x08, // _MADCTL + 0x21, 0x80, 0x0A, // _INVON Hack and Delay 10ms + 0x13, 0x80, 0x0A, // _NORON and Delay 10ms + 0x29, 0 | DELAY, 0xff // _DISPON and Delay 500ms +}; + + +void board_init(void) { + + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO5, &pin_GPIO6, NULL, false); + common_hal_busio_spi_never_reset(spi); + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO2), // DC + MP_OBJ_FROM_PTR(&pin_GPIO3), // CS + MP_OBJ_FROM_PTR(&pin_GPIO10), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 280, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 20, // row start + 270, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 200 // backlight pwm frequency + ); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/mpconfigboard.h b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/mpconfigboard.h new file mode 100644 index 00000000000..513ab48284c --- /dev/null +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 Neradoc +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Board setup +#define MICROPY_HW_BOARD_NAME "Spotpear ESP32C3 LCD 1.69" +#define MICROPY_HW_MCU_NAME "ESP32-C3FH4" + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO7, .sda = &pin_GPIO11}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO5, .mosi = &pin_GPIO6, .miso = &pin_GPIO4}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO21, .rx = &pin_GPIO20}} diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/mpconfigboard.mk b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/mpconfigboard.mk new file mode 100644 index 00000000000..08f792b4136 --- /dev/null +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/mpconfigboard.mk @@ -0,0 +1,10 @@ +CIRCUITPY_CREATOR_ID = 0x18760000 +CIRCUITPY_CREATION_ID = 0x00DD0002 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/pins.c b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/pins.c new file mode 100644 index 00000000000..666333b8ffa --- /dev/null +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/pins.c @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 CDarius +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // buttons + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO9) }, + + // buzzer + { MP_ROM_QSTR(MP_QSTR_BUZZER), MP_ROM_PTR(&pin_GPIO1) }, + + // SPI + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO6) }, + + // LCD + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO8) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO11) }, + + // Touch + { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_RST), MP_ROM_PTR(&pin_GPIO10) }, + + // UART (on unpopulated header) + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + // Objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/sdkconfig b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/spotpear_esp32c3_lcd_1_69/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/sqfmi_watchy/board.c b/ports/espressif/boards/sqfmi_watchy/board.c index 25a7be4613c..9cea4e98095 100644 --- a/ports/espressif/boards/sqfmi_watchy/board.c +++ b/ports/espressif/boards/sqfmi_watchy/board.c @@ -150,9 +150,9 @@ void board_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO10, // EPD_DC Command or data - &pin_GPIO5, // EPD_CS Chip select - &pin_GPIO9, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO10), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO9), // EPD_RST Reset 2000000, // Baudrate 0, // Polarity 0 // Phase @@ -160,39 +160,33 @@ void board_init(void) { epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - (double)0.01, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 200, // width - 200, // height - 200, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 0, // rotation - 0x44, // set_column_window_command - 0x45, // set_row_window_command - 0x4E, // set_current_column_command - 0x4F, // set_current_row_command - 0x24, // write_black_ram_command - true, // black_bits_inverted - 0x26, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - refresh_sequence, sizeof(refresh_sequence), - (double)1.0, // refresh_time - &pin_GPIO19, // busy_pin - true, // busy_state - (double)5.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // two_byte_sequence_length - true // address_little_endian - ); + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 0.01; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 200; + args.height = 200; + args.ram_width = 200; + args.ram_height = 296; + args.set_column_window_command = 0x44; + args.set_row_window_command = 0x45; + args.set_current_column_command = 0x4E; + args.set_current_row_command = 0x4F; + args.write_black_ram_command = 0x24; + args.black_bits_inverted = true; + args.write_color_ram_command = 0x26; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO19; + args.busy_state = true; + args.seconds_per_frame = 5.0; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } bool board_requests_safe_mode(void) { diff --git a/ports/espressif/boards/sqfmi_watchy/mpconfigboard.mk b/ports/espressif/boards/sqfmi_watchy/mpconfigboard.mk index 520894ea70a..b1c8c64f8ba 100644 --- a/ports/espressif/boards/sqfmi_watchy/mpconfigboard.mk +++ b/ports/espressif/boards/sqfmi_watchy/mpconfigboard.mk @@ -1,13 +1,8 @@ CIRCUITPY_CREATOR_ID = 0x4496E3F4 CIRCUITPY_CREATION_ID = 0x00320024 - -CIRCUITPY_ESPCAMERA = 0 +IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE=dio CIRCUITPY_ESP_FLASH_FREQ=40m CIRCUITPY_ESP_FLASH_SIZE=4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -IDF_TARGET = esp32 diff --git a/ports/espressif/boards/sqfmi_watchy/sdkconfig b/ports/espressif/boards/sqfmi_watchy/sdkconfig index 0eb5e8d4cb1..7d6572eeeee 100644 --- a/ports/espressif/boards/sqfmi_watchy/sdkconfig +++ b/ports/espressif/boards/sqfmi_watchy/sdkconfig @@ -1,5 +1,4 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="Watchy" # end of LWIP diff --git a/ports/espressif/boards/sunton_esp32_2424S012/board.c b/ports/espressif/boards/sunton_esp32_2424S012/board.c index c313ded8637..4e56bee7d8b 100644 --- a/ports/espressif/boards/sunton_esp32_2424S012/board.c +++ b/ports/espressif/boards/sunton_esp32_2424S012/board.c @@ -105,9 +105,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO2, // DC - &pin_GPIO10, // CS - NULL, // RST + MP_OBJ_FROM_PTR(&pin_GPIO2), // DC + MP_OBJ_FROM_PTR(&pin_GPIO10), // CS + mp_const_none, // RST 80000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/sunton_esp32_2424S012/mpconfigboard.mk b/ports/espressif/boards/sunton_esp32_2424S012/mpconfigboard.mk index 2a84d801bc3..716a01084c1 100644 --- a/ports/espressif/boards/sunton_esp32_2424S012/mpconfigboard.mk +++ b/ports/espressif/boards/sunton_esp32_2424S012/mpconfigboard.mk @@ -7,6 +7,4 @@ CIRCUITPY_ESP_FLASH_MODE=qio CIRCUITPY_ESP_FLASH_FREQ=80m CIRCUITPY_ESP_FLASH_SIZE=4MB -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 diff --git a/ports/espressif/boards/sunton_esp32_2424S012/sdkconfig b/ports/espressif/boards/sunton_esp32_2424S012/sdkconfig index 5b7c8255a97..e9628662160 100644 --- a/ports/espressif/boards/sunton_esp32_2424S012/sdkconfig +++ b/ports/espressif/boards/sunton_esp32_2424S012/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="sunton-esp32-2424S012" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/sunton_esp32_2432S024C/board.c b/ports/espressif/boards/sunton_esp32_2432S024C/board.c new file mode 100644 index 00000000000..d50f19f9972 --- /dev/null +++ b/ports/espressif/boards/sunton_esp32_2432S024C/board.c @@ -0,0 +1,112 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Olav Schettler +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" + +#include "common-hal/microcontroller/Pin.h" +#include "driver/gpio.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "supervisor/shared/settings.h" + +uint8_t display_init_sequence[] = { + 0x01, 0x80, 0x80, // # Software reset then delay 0x80 (128ms) + 0xEF, 0x03, 0x03, 0x80, 0x02, + 0xCF, 0x03, 0x00, 0xC1, 0x30, + 0xED, 0x04, 0x64, 0x03, 0x12, 0x81, + 0xE8, 0x03, 0x85, 0x00, 0x78, + 0xCB, 0x05, 0x39, 0x2C, 0x00, 0x34, 0x02, + 0xF7, 0x01, 0x20, + 0xEA, 0x02, 0x00, 0x00, + 0xc0, 0x01, 0x23, // # Power control VRH[5:0] + 0xc1, 0x01, 0x10, // # Power control SAP[2:0];BT[3:0] + 0xc5, 0x02, 0x3e, 0x28, // # VCM control + 0xc7, 0x01, 0x86, // # VCM control2 + 0x36, 0x01, 0x38, // # Memory Access Control + 0x37, 0x01, 0x00, // # Vertical scroll zero + 0x3a, 0x01, 0x55, // # COLMOD: Pixel Format Set + 0xb1, 0x02, 0x00, 0x18, // # Frame Rate Control (In Normal Mode/Full Colors) + 0xb6, 0x03, 0x08, 0x82, 0x27, // # Display Function Control + 0xF2, 0x01, 0x00, // # 3Gamma Function Disable + 0x26, 0x01, 0x01, // # Gamma curve selected + 0xe0, 0x0f, 0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08, 0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00, // # Set Gamma + 0xe1, 0x0f, 0x00, 0x0E, 0x14, 0x03, 0x11, 0x07, 0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F, // # Set Gamma + 0x11, 0x80, 0x48, // # Exit Sleep then delay + 0x29, 0x80, 0x78, // # Display on then delay 0x78 (120ms) +}; + +static void display_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + mp_int_t rotation; + common_hal_busio_spi_construct(spi, &pin_GPIO14, &pin_GPIO13, &pin_GPIO12, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset + 6000000, // Baudrate + 0, // Polarity + 0); // Phase + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + settings_err_t result = settings_get_int("CIRCUITPY_DISPLAY_ROTATION", &rotation); + if (result != SETTINGS_OK) { + rotation = 0; + } + + common_hal_busdisplay_busdisplay_construct(display, + bus, + 320, // Width + 240, // Height + 0, // column start + 0, // row start + rotation, // rotation + 16, // Color depth + false, // Grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO27, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000); // backlight pwm frequency +} + +void board_init(void) { + display_init(); +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + // Pull the speaker pin low to reduce noise on reset + if (pin_number == 26) { + // Turn on TFT + config_pin_as_output_with_level(pin_number, false); + return true; + } + return false; +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/sunton_esp32_2432S024C/mpconfigboard.h b/ports/espressif/boards/sunton_esp32_2432S024C/mpconfigboard.h new file mode 100644 index 00000000000..501b06caa28 --- /dev/null +++ b/ports/espressif/boards/sunton_esp32_2432S024C/mpconfigboard.h @@ -0,0 +1,27 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Olav Schettler +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "sunton_esp32_2432S024C" +#define MICROPY_HW_MCU_NAME "ESP32-D0WD-V3" +#define MICROPY_HW_LED_STATUS (&pin_GPIO17) // LED_BLUE + +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) + +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO33) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO32) + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN { \ + {.clock = &pin_GPIO18, .mosi = &pin_GPIO23, .miso = &pin_GPIO19}, /*SD*/ \ + {.clock = &pin_GPIO14, .mosi = &pin_GPIO13, .miso = &pin_GPIO12}, /*LCD*/ \ +} + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/sunton_esp32_2432S024C/mpconfigboard.mk b/ports/espressif/boards/sunton_esp32_2432S024C/mpconfigboard.mk new file mode 100644 index 00000000000..fcb3e98458e --- /dev/null +++ b/ports/espressif/boards/sunton_esp32_2432S024C/mpconfigboard.mk @@ -0,0 +1,8 @@ +CIRCUITPY_CREATOR_ID = 0x19991000 +CIRCUITPY_CREATION_ID = 0x00AA024C + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB diff --git a/ports/espressif/boards/sunton_esp32_2432S024C/pins.c b/ports/espressif/boards/sunton_esp32_2432S024C/pins.c new file mode 100644 index 00000000000..6544017cd99 --- /dev/null +++ b/ports/espressif/boards/sunton_esp32_2432S024C/pins.c @@ -0,0 +1,68 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Olav Schettler +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 0) +CIRCUITPY_BOARD_BUS_SINGLETON(lcd_spi, spi, 2) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Boot button + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + + // Blue LED + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO17) }, + + // RGB LED + { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_GPIO17) }, + + // CDS Light sensor (Not present on all boards) + { MP_ROM_QSTR(MP_QSTR_LDR), MP_ROM_PTR(&pin_GPIO34) }, + + // Speaker pin + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO26) }, + + // User available GPIO + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, // P3 Pin 1 + { MP_ROM_QSTR(MP_QSTR_IO22), MP_ROM_PTR(&pin_GPIO22) }, // P3 Pin 2 + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, // P3 Pin 3 + + // i2c + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO32) }, + + // TF card slot + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO5) }, + + // ILI9341 display (spi) + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BCKL), MP_ROM_PTR(&pin_GPIO27) }, + + // Touch (CST820) + { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_RST), MP_ROM_PTR(&pin_GPIO25) }, + + // objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_lcd_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/sunton_esp32_2432S024C/sdkconfig b/ports/espressif/boards/sunton_esp32_2432S024C/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/sunton_esp32_2432S028/board.c b/ports/espressif/boards/sunton_esp32_2432S028/board.c index b249c45dd8f..6cd4a080c99 100644 --- a/ports/espressif/boards/sunton_esp32_2432S028/board.c +++ b/ports/espressif/boards/sunton_esp32_2432S028/board.c @@ -6,13 +6,14 @@ #include "supervisor/board.h" #include "mpconfigboard.h" + +#include "common-hal/microcontroller/Pin.h" +#include "driver/gpio.h" #include "shared-bindings/board/__init__.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-module/displayio/__init__.h" #include "shared-module/displayio/mipi_constants.h" -#include "driver/gpio.h" -#include "common-hal/microcontroller/Pin.h" -#include "shared-module/os/__init__.h" +#include "supervisor/shared/settings.h" uint8_t display_init_sequence[] = { 0x01, 0x80, 0x80, // # Software reset then delay 0x80 (128ms) @@ -50,17 +51,17 @@ static void display_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO2, // TFT_DC Command or data - &pin_GPIO15, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset 6000000, // Baudrate 0, // Polarity 0); // Phase busdisplay_busdisplay_obj_t *display = &allocate_display()->display; display->base.type = &busdisplay_busdisplay_type; - os_getenv_err_t result = common_hal_os_getenv_int("CIRCUITPY_DISPLAY_ROTATION", &rotation); - if (result != GETENV_OK) { + settings_err_t result = settings_get_int("CIRCUITPY_DISPLAY_ROTATION", &rotation); + if (result != SETTINGS_OK) { rotation = 0; } diff --git a/ports/espressif/boards/sunton_esp32_2432S028/mpconfigboard.mk b/ports/espressif/boards/sunton_esp32_2432S028/mpconfigboard.mk index 444c80227ab..d4c4fb94c71 100644 --- a/ports/espressif/boards/sunton_esp32_2432S028/mpconfigboard.mk +++ b/ports/espressif/boards/sunton_esp32_2432S028/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_ESPCAMERA = 0 - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/sunton_esp32_2432S028/pins.c b/ports/espressif/boards/sunton_esp32_2432S028/pins.c index b852ab11e04..7791c1685eb 100644 --- a/ports/espressif/boards/sunton_esp32_2432S028/pins.c +++ b/ports/espressif/boards/sunton_esp32_2432S028/pins.c @@ -45,7 +45,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO5) }, - // ILI9341 dsplay (spi) + // ILI9341 display (spi) { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO12) }, { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_GPIO14) }, diff --git a/ports/espressif/boards/sunton_esp32_2432S032C/board.c b/ports/espressif/boards/sunton_esp32_2432S032C/board.c index b2160e0aa4f..db621cfe8c9 100644 --- a/ports/espressif/boards/sunton_esp32_2432S032C/board.c +++ b/ports/espressif/boards/sunton_esp32_2432S032C/board.c @@ -43,9 +43,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO2, // TFT_DC - &pin_GPIO15, // TFT_CS - NULL, // TFT_RST + MP_OBJ_FROM_PTR(&pin_GPIO2), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO15), // TFT_CS + mp_const_none, // TFT_RST 26600000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/espressif/boards/sunton_esp32_2432S032C/mpconfigboard.mk b/ports/espressif/boards/sunton_esp32_2432S032C/mpconfigboard.mk index 15e3b102c9b..f36374a456a 100644 --- a/ports/espressif/boards/sunton_esp32_2432S032C/mpconfigboard.mk +++ b/ports/espressif/boards/sunton_esp32_2432S032C/mpconfigboard.mk @@ -6,5 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/sunton_esp32_8048S050/board.c b/ports/espressif/boards/sunton_esp32_8048S050/board.c index fa2b03754ec..b1794529ff0 100644 --- a/ports/espressif/boards/sunton_esp32_8048S050/board.c +++ b/ports/espressif/boards/sunton_esp32_8048S050/board.c @@ -6,12 +6,15 @@ #include "supervisor/board.h" #include "mpconfigboard.h" + +#include "driver/gpio.h" #include "shared-bindings/board/__init__.h" #include "shared-bindings/dotclockframebuffer/DotClockFramebuffer.h" #include "shared-bindings/dotclockframebuffer/__init__.h" #include "shared-bindings/framebufferio/FramebufferDisplay.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-module/displayio/__init__.h" +#include "supervisor/shared/settings.h" static const mcu_pin_obj_t *blue_pins[] = { &pin_GPIO8, @@ -37,6 +40,7 @@ static const mcu_pin_obj_t *red_pins[] = { }; static void display_init(void) { + mp_int_t frequency; // Turn on backlight gpio_set_direction(2, GPIO_MODE_DEF_OUTPUT); @@ -45,6 +49,10 @@ static void display_init(void) { dotclockframebuffer_framebuffer_obj_t *framebuffer = &allocate_display_bus_or_raise()->dotclock; framebuffer->base.type = &dotclockframebuffer_framebuffer_type; + settings_err_t result = settings_get_int("CIRCUITPY_DISPLAY_FREQUENCY", &frequency); + if (result != SETTINGS_OK) { + frequency = 12500000; + } common_hal_dotclockframebuffer_framebuffer_construct( framebuffer, @@ -55,7 +63,7 @@ static void display_init(void) { red_pins, MP_ARRAY_SIZE(red_pins), green_pins, MP_ARRAY_SIZE(green_pins), blue_pins, MP_ARRAY_SIZE(blue_pins), - 12500000, // Frequency + frequency, // Frequency 800, // width 480, // height 4, 8, 8, true, // horiz: pulse, back porch, front porch, idle low diff --git a/ports/espressif/boards/sunton_esp32_8048S050/sdkconfig b/ports/espressif/boards/sunton_esp32_8048S050/sdkconfig index 71012f46188..e9628662160 100644 --- a/ports/espressif/boards/sunton_esp32_8048S050/sdkconfig +++ b/ports/espressif/boards/sunton_esp32_8048S050/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="sunton-esp32-8048S050" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/sunton_esp32_8048S070/board.c b/ports/espressif/boards/sunton_esp32_8048S070/board.c index ecc9b7c1236..3d6a9c81e6d 100644 --- a/ports/espressif/boards/sunton_esp32_8048S070/board.c +++ b/ports/espressif/boards/sunton_esp32_8048S070/board.c @@ -6,6 +6,7 @@ #include "supervisor/board.h" #include "mpconfigboard.h" +#include "driver/gpio.h" #include "shared-bindings/board/__init__.h" #include "shared-bindings/dotclockframebuffer/DotClockFramebuffer.h" #include "shared-bindings/dotclockframebuffer/__init__.h" diff --git a/ports/espressif/boards/sunton_esp32_8048S070/sdkconfig b/ports/espressif/boards/sunton_esp32_8048S070/sdkconfig index 61e94a741ff..e9628662160 100644 --- a/ports/espressif/boards/sunton_esp32_8048S070/sdkconfig +++ b/ports/espressif/boards/sunton_esp32_8048S070/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="sunton-esp32-8048S070" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk b/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk index 2e0e84456cb..f273085b192 100644 --- a/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk +++ b/ports/espressif/boards/targett_module_clip_wroom/mpconfigboard.mk @@ -8,5 +8,3 @@ IDF_TARGET = esp32s2 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/thingpulse_pendrive_s3/mpconfigboard.mk b/ports/espressif/boards/thingpulse_pendrive_s3/mpconfigboard.mk index 66f5a4aba70..cb273b7a45d 100644 --- a/ports/espressif/boards/thingpulse_pendrive_s3/mpconfigboard.mk +++ b/ports/espressif/boards/thingpulse_pendrive_s3/mpconfigboard.mk @@ -13,7 +13,8 @@ CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m +# No pins. CIRCUITPY_ESPCAMERA = 0 -CIRCUITPY_DISPLAYIO = 1 +CIRCUITPY_PARALLELDISPLAYBUS = 0 FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/thingpulse_pendrive_s3/sdkconfig b/ports/espressif/boards/thingpulse_pendrive_s3/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/thingpulse_pendrive_s3/sdkconfig +++ b/ports/espressif/boards/thingpulse_pendrive_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/ttgo_t8_v1_7/mpconfigboard.mk b/ports/espressif/boards/ttgo_t8_v1_7/mpconfigboard.mk index 6556b6881f3..aa9f2e1c1b3 100644 --- a/ports/espressif/boards/ttgo_t8_v1_7/mpconfigboard.mk +++ b/ports/espressif/boards/ttgo_t8_v1_7/mpconfigboard.mk @@ -7,4 +7,6 @@ CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB -CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_ESP_PSRAM_SIZE = 4MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/unexpectedmaker_bling/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_bling/mpconfigboard.h index 671f714daea..f9aad2c4ba3 100644 --- a/ports/espressif/boards/unexpectedmaker_bling/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_bling/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DOUBLE_TAP_PIN (&pin_GPIO47) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_bling/sdkconfig b/ports/espressif/boards/unexpectedmaker_bling/sdkconfig index 8e693ad1cb4..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_bling/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_bling/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMBling" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_blizzard_s3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_blizzard_s3/mpconfigboard.h index dd677dad7b9..86275b0d784 100644 --- a/ports/espressif/boards/unexpectedmaker_blizzard_s3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_blizzard_s3/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DOUBLE_TAP_PIN (&pin_GPIO47) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_blizzard_s3/sdkconfig b/ports/espressif/boards/unexpectedmaker_blizzard_s3/sdkconfig index eea8c00b59b..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_blizzard_s3/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_blizzard_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMBlizzardS3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_edges3d/board.c b/ports/espressif/boards/unexpectedmaker_edges3d/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_edges3d/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/unexpectedmaker_edges3d/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_edges3d/mpconfigboard.h new file mode 100644 index 00000000000..a9271bc1e00 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_edges3d/mpconfigboard.h @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit +// Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "EDGES3D" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO4) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO7) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO5) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_edges3d/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_edges3d/mpconfigboard.mk new file mode 100644 index 00000000000..01e2edc4164 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_edges3d/mpconfigboard.mk @@ -0,0 +1,16 @@ +USB_VID = 0x303A +USB_PID = 0x82DD +USB_PRODUCT = "EDGES3D" +USB_MANUFACTURER = "UnexpectedMaker" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_SIZE = 8MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +CIRCUITPY_STAGE = 1 diff --git a/ports/espressif/boards/unexpectedmaker_edges3d/pins.c b/ports/espressif/boards/unexpectedmaker_edges3d/pins.c new file mode 100644 index 00000000000..b753ea207b1 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_edges3d/pins.c @@ -0,0 +1,126 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit +// Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + {MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0)}, + {MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0)}, + + {MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1)}, + {MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO1)}, + {MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1)}, + + {MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2)}, + {MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO2)}, + {MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2)}, + + {MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3)}, + {MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO3)}, + {MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3)}, + + {MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4)}, + {MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO4)}, + {MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4)}, + + {MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5)}, + {MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO5)}, + {MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5)}, + + {MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6)}, + {MP_ROM_QSTR(MP_QSTR_FG_INT), MP_ROM_PTR(&pin_GPIO6)}, + + {MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7)}, + {MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO7)}, + {MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7)}, + + {MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8)}, + {MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8)}, + {MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO8)}, + {MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8)}, + + {MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO9)}, + {MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9)}, + {MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO9)}, + {MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9)}, + + {MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10)}, + {MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO10)}, + {MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10)}, + + {MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11)}, + {MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO11)}, + {MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11)}, + + {MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12)}, + {MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO12)}, + {MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12)}, + + {MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13)}, + {MP_ROM_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO13)}, + {MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13)}, + + {MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14)}, + {MP_ROM_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO14)}, + {MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14)}, + + {MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15)}, + {MP_ROM_QSTR(MP_QSTR_A14), MP_ROM_PTR(&pin_GPIO15)}, + {MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15)}, + + {MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16)}, + {MP_ROM_QSTR(MP_QSTR_A15), MP_ROM_PTR(&pin_GPIO16)}, + {MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16)}, + + {MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17)}, + {MP_ROM_QSTR(MP_QSTR_A16), MP_ROM_PTR(&pin_GPIO17)}, + {MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17)}, + + {MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18)}, + {MP_ROM_QSTR(MP_QSTR_A17), MP_ROM_PTR(&pin_GPIO18)}, + {MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18)}, + + {MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21)}, + {MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21)}, + + {MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39)}, + {MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39)}, + {MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_GPIO39)}, + + {MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40)}, + {MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO40)}, + {MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_GPIO40)}, + + {MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41)}, + {MP_ROM_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO41)}, + {MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_GPIO41)}, + + {MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42)}, + {MP_ROM_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO42)}, + {MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_GPIO42)}, + + {MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43)}, + {MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43)}, + {MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43)}, + + {MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44)}, + {MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44)}, + {MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44)}, + + {MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45)}, + {MP_ROM_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_GPIO45)}, + + {MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46)}, + {MP_ROM_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_GPIO46)}, + + {MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj)}, + {MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj)}, + {MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/unexpectedmaker_edges3d/sdkconfig b/ports/espressif/boards/unexpectedmaker_edges3d/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/unexpectedmaker_edges3d/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h index d8349cdb58b..1df282a3326 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers2/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_feathers2/sdkconfig b/ports/espressif/boards/unexpectedmaker_feathers2/sdkconfig index a1e5e03b769..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_feathers2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h index 1dd6b79a9b9..5141c6d7793 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers2_neo/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_neo/sdkconfig b/ports/espressif/boards/unexpectedmaker_feathers2_neo/sdkconfig index cc781c9a3dd..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_neo/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_feathers2_neo/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS2Neo" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h index 1d6c9035ac6..c2f9197fad8 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/sdkconfig b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/sdkconfig index a1e5e03b769..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_feathers2_prerelease/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h index 53157a1ff11..dc48fe3f40f 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers3/mpconfigboard.h @@ -28,3 +28,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DOUBLE_TAP_PIN (&pin_GPIO47) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_feathers3/pins.c b/ports/espressif/boards/unexpectedmaker_feathers3/pins.c index e611348caa0..63153d3d696 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3/pins.c +++ b/ports/espressif/boards/unexpectedmaker_feathers3/pins.c @@ -128,6 +128,10 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LDO2), MP_ROM_PTR(&pin_GPIO39) }, { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + // built-in vs uFL antenna switch (LOW=built-in, HIGH=uFL, default=built-in) + { MP_ROM_QSTR(MP_QSTR_ANTENNA_SWITCH), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + // I2C { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/espressif/boards/unexpectedmaker_feathers3/sdkconfig b/ports/espressif/boards/unexpectedmaker_feathers3/sdkconfig index 3ccd3175c69..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_feathers3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_feathers3_neo/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_feathers3_neo/mpconfigboard.h index 037190d9aa8..18f2513e6af 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3_neo/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_feathers3_neo/mpconfigboard.h @@ -27,3 +27,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) // #define DOUBLE_TAP_PIN (&pin_GPIO47) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_feathers3_neo/sdkconfig b/ports/espressif/boards/unexpectedmaker_feathers3_neo/sdkconfig index df8f15b5439..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_feathers3_neo/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_feathers3_neo/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMFeatherS3 Neo" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_nanos3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_nanos3/mpconfigboard.h index 022d6f3373e..f59ce34fb6a 100644 --- a/ports/espressif/boards/unexpectedmaker_nanos3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_nanos3/mpconfigboard.h @@ -23,3 +23,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_nanos3/sdkconfig b/ports/espressif/boards/unexpectedmaker_nanos3/sdkconfig index 815f002d382..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_nanos3/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_nanos3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMNanoS3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_omgs3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_omgs3/mpconfigboard.h index 5fd666524c7..5ec5945cdfe 100644 --- a/ports/espressif/boards/unexpectedmaker_omgs3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_omgs3/mpconfigboard.h @@ -24,3 +24,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_omgs3/sdkconfig b/ports/espressif/boards/unexpectedmaker_omgs3/sdkconfig index 9de28080ff3..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_omgs3/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_omgs3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMOMGS3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.h index bec68c88cb1..dfef3399844 100644 --- a/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_pros3/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DOUBLE_TAP_PIN (&pin_GPIO47) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_pros3/sdkconfig b/ports/espressif/boards/unexpectedmaker_pros3/sdkconfig index 21b91a2199a..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_pros3/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_pros3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMProS3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/mpconfigboard.h index 2cf95fa9a6d..b0bbcd2d457 100644 --- a/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/mpconfigboard.h @@ -17,3 +17,6 @@ #define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/sdkconfig b/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/sdkconfig index 8eae792a583..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_rgbtouch_mini/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMRGBT" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_tinyc6/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinyc6/mpconfigboard.h index 3e4995437d5..6f7e84c5c75 100644 --- a/ports/espressif/boards/unexpectedmaker_tinyc6/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_tinyc6/mpconfigboard.h @@ -23,3 +23,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO17) #define DEFAULT_UART_BUS_TX (&pin_GPIO16) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_tinyc6/sdkconfig b/ports/espressif/boards/unexpectedmaker_tinyc6/sdkconfig index c989bb78dc7..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_tinyc6/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_tinyc6/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyC6" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.h index c03aa8d7fbc..6300506e9e1 100644 --- a/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.h @@ -18,3 +18,6 @@ // UART pins attached to the USB-serial converter chip #define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) #define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.mk index 4086abba11e..80acff0ca49 100644 --- a/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_tinypico/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.h index 2ab781f1a2e..6b01e2c2e13 100644 --- a/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.h @@ -18,3 +18,6 @@ // UART pins attached to the USB-serial converter chip #define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) #define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.mk b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.mk index 550e0d4a76c..c919aff8aef 100644 --- a/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.mk +++ b/ports/espressif/boards/unexpectedmaker_tinypico_nano/mpconfigboard.mk @@ -10,5 +10,3 @@ CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_PSRAM_SIZE = 8MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.h index d7c87bfdba2..07c453cb7bc 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_tinys2/mpconfigboard.h @@ -23,3 +23,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_tinys2/sdkconfig b/ports/espressif/boards/unexpectedmaker_tinys2/sdkconfig index 647e33d8f5a..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys2/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_tinys2/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyS2" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.h index 2556e714d67..066dd00386c 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_tinys3/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO43) #define DOUBLE_TAP_PIN (&pin_GPIO47) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_tinys3/sdkconfig b/ports/espressif/boards/unexpectedmaker_tinys3/sdkconfig index d08f76926e0..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_tinys3/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_tinys3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyS3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/unexpectedmaker_tinywatch_s3/mpconfigboard.h b/ports/espressif/boards/unexpectedmaker_tinywatch_s3/mpconfigboard.h index 6f0181c4acb..309c2e2e702 100644 --- a/ports/espressif/boards/unexpectedmaker_tinywatch_s3/mpconfigboard.h +++ b/ports/espressif/boards/unexpectedmaker_tinywatch_s3/mpconfigboard.h @@ -21,3 +21,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/unexpectedmaker_tinywatch_s3/sdkconfig b/ports/espressif/boards/unexpectedmaker_tinywatch_s3/sdkconfig index 12b5605f4e5..e9628662160 100644 --- a/ports/espressif/boards/unexpectedmaker_tinywatch_s3/sdkconfig +++ b/ports/espressif/boards/unexpectedmaker_tinywatch_s3/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="UMTinyWATCHS3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/vidi_x/board.c b/ports/espressif/boards/vidi_x/board.c index e53dfd82ad9..57e2b896213 100644 --- a/ports/espressif/boards/vidi_x/board.c +++ b/ports/espressif/boards/vidi_x/board.c @@ -6,6 +6,7 @@ #include "supervisor/board.h" #include "mpconfigboard.h" +#include "driver/gpio.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/fourwire/FourWire.h" #include "shared-module/displayio/__init__.h" @@ -51,9 +52,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO21, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO21), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset 40000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/espressif/boards/vidi_x/sdkconfig b/ports/espressif/boards/vidi_x/sdkconfig index bdd999b4fc9..e9628662160 100644 --- a/ports/espressif/boards/vidi_x/sdkconfig +++ b/ports/espressif/boards/vidi_x/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="vidi-x" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/board.c b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/board.c new file mode 100644 index 00000000000..e56c096e403 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/board.c @@ -0,0 +1,99 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Benjamin Shockley +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + +// Driver is ST7789V3 +// Display Panel is LBS147TC-IF15 +// 172 X 320 Pixels RGB 18-bit + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 120, + 0x11, 0 | DELAY, 120, + 0x13, 0, + 0x36, 1, 0x00, + 0x3A, 1 | DELAY, 0x05, 10, + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + 0xB7, 1, 0x35, + 0xBB, 1, 0x20, + 0xC0, 1, 0x2C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x13, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + 0xE0, 14, 0xF0, 0x00, 0x04, 0x04, 0x04, 0x05, 0x29, 0x33, 0x3E, 0x38, 0x12, 0x12, 0x28, 0x30, + 0xE1, 14, 0xF0, 0x07, 0x0A, 0x0D, 0x0B, 0x07, 0x28, 0x33, 0x3E, 0x36, 0x14, 0x14, 0x29, 0x32, + 0x21, 0, + 0x29, 0 | DELAY, 255, +}; + +static void display_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO15), // DC + MP_OBJ_FROM_PTR(&pin_GPIO14), // CS + MP_OBJ_FROM_PTR(&pin_GPIO21), // RST + 80000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 172, // width (after rotation) + 320, // height (after rotation) + 34, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO22, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h new file mode 100644 index 00000000000..d745d366562 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.h @@ -0,0 +1,36 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Benjamin Shockley +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-C6 LCD 1.47" +#define MICROPY_HW_MCU_NAME "ESP32-C6FH4" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO8) +#define MICROPY_HW_NEOPIXEL_ORDER_GRB (1) + +// I2C +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO0, .sda = &pin_GPIO1}} + +// SPI +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO7, .mosi = &pin_GPIO6, .miso = &pin_GPIO5}} + +// TXD0 and RXD0 +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO16, .rx = &pin_GPIO17}} + +// For entering safe mode, use BOOT button +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) + +// Explanation of how a user got into safe mode +#define BOARD_USER_SAFE_MODE_ACTION MP_ERROR_TEXT("You pressed the BOOT button at start up.") + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.mk new file mode 100644 index 00000000000..e838f8ad2e5 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/mpconfigboard.mk @@ -0,0 +1,11 @@ +CIRCUITPY_CREATOR_ID = 0x1BBB0000 +CIRCUITPY_CREATION_ID = 0x00C60002 + +IDF_TARGET = esp32c6 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +# Board was originally defined with a 2MB firmware, almost 2MB user filesystem. Leave it that way. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT = 1 diff --git a/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/pins.c b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/pins.c new file mode 100644 index 00000000000..9b9b91d8f64 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/pins.c @@ -0,0 +1,70 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Benjamin Shockley +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_IO23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)} +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/sdkconfig b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_c6_lcd_1_47/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c index cb6fb310338..0bf710ec34c 100644 --- a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/board.c @@ -61,9 +61,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO18, // DC - &pin_GPIO9, // CS - &pin_GPIO21, // RST + MP_OBJ_FROM_PTR(&pin_GPIO18), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO21), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.h index c74499cf80a..638eb0390d8 100644 --- a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/mpconfigboard.h @@ -20,3 +20,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/sdkconfig b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/sdkconfig index 7c86f9f8e37..e9628662160 100644 --- a/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32_s2_pico_lcd/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="waveshare" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/waveshare_esp32_s3_amoled_241/board.c b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/board.c new file mode 100644 index 00000000000..7b57f48bcdb --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/board.c @@ -0,0 +1,106 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "shared-bindings/qspibus/QSPIBus.h" +#include "shared-bindings/busdisplay/BusDisplay.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +// RM690B0 AMOLED initialization sequence. +// Format: command byte, length | 0x80 (if delay), data bytes..., [delay ms] +// Based on vendor recommendations, tested with Waveshare 2.41" AMOLED panel. +// Non-const to match upstream common_hal_busdisplay_busdisplay_construct signature. +static uint8_t display_init_sequence[] = { + // Page select and configuration + 0xFE, 0x01, 0x20, // Enter user command mode + 0x26, 0x01, 0x0A, // Bias setting + 0x24, 0x01, 0x80, // Source output control + 0xFE, 0x01, 0x13, // Page 13 + 0xEB, 0x01, 0x0E, // Vendor command + 0xFE, 0x01, 0x00, // Return to page 0 + // Display configuration + 0x3A, 0x01, 0x55, // COLMOD: 16-bit RGB565 + 0xC2, 0x81, 0x00, 0x0A, // Vendor command + 10ms delay + 0x35, 0x00, // Tearing effect line on (no data) + 0x51, 0x81, 0x00, 0x0A, // Brightness control + 10ms delay + // Power on + 0x11, 0x80, 0x50, // Sleep out + 80ms delay + // Display window (MV=1: CASET→rows, RASET→cols) + 0x2A, 0x04, 0x00, 0x10, 0x01, 0xD1, // CASET: 16..465 (450px + 16 offset) + 0x2B, 0x04, 0x00, 0x00, 0x02, 0x57, // RASET: 0..599 (600px) + // Enable display + 0x29, 0x80, 0x0A, // Display on + 10ms delay + // Memory access: MV=1, ML=1 for landscape + 0x36, 0x81, 0x30, 0x0A, // MADCTL + 10ms delay + // Brightness + 0x51, 0x01, 0xFF, // Set brightness to maximum +}; + +void board_init(void) { + // 0. Enable display power before any bus/display init. + digitalio_digitalinout_obj_t power_pin; + power_pin.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&power_pin, CIRCUITPY_LCD_POWER); + common_hal_digitalio_digitalinout_set_value(&power_pin, true); + common_hal_digitalio_digitalinout_never_reset(&power_pin); + // Allow power rail to settle before reset/init. + mp_hal_delay_ms(200); + + // 1. Allocate and construct QSPI bus + qspibus_qspibus_obj_t *bus = &allocate_display_bus_or_raise()->qspi_bus; + bus->base.type = &qspibus_qspibus_type; + + common_hal_qspibus_qspibus_construct(bus, + CIRCUITPY_LCD_CLK, // clock + CIRCUITPY_LCD_D0, // data0 + CIRCUITPY_LCD_D1, // data1 + CIRCUITPY_LCD_D2, // data2 + CIRCUITPY_LCD_D3, // data3 + CIRCUITPY_LCD_CS, // cs + NULL, // dcx (not used, QSPI uses encoded commands) + CIRCUITPY_LCD_RESET, // reset + 40000000); // 40 MHz + + // 2. Allocate and construct BusDisplay with RM690B0 init sequence. + // Physical panel: 450 cols × 600 rows. + // MADCTL MV=1 swaps row/col → logical 600×450 landscape. + busdisplay_busdisplay_obj_t *display = &allocate_display_or_raise()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct(display, + bus, + 600, // width (logical, after MV=1 swap) + 450, // height (logical, after MV=1 swap) + 0, // colstart + 16, // rowstart (physical row offset) + 0, // rotation + 16, // color_depth (RGB565) + false, // grayscale + false, // pixels_in_byte_share_row + 1, // bytes_per_cell + false, // reverse_pixels_in_byte + false, // reverse_bytes_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set_column_command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set_row_command + MIPI_COMMAND_WRITE_MEMORY_START, // write_ram_command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // backlight_pin (AMOLED — no backlight GPIO) + 0x51, // brightness_command + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000); // backlight_pwm_frequency +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.h new file mode 100644 index 00000000000..7a67f925ab1 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.h @@ -0,0 +1,37 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3-Touch-AMOLED-2.41" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +// I2C bus - Disabled on boot to avoid conflicts. User must manually initialize I2C. +#define CIRCUITPY_BOARD_I2C (0) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO48, .sda = &pin_GPIO47}} + +// Display refresh buffer: 8192 bytes = 2048 uint32_t words on stack. +// ESP32-S3 main task stack is 24KB; verified safe with this board. +#define CIRCUITPY_DISPLAY_AREA_BUFFER_SIZE (8192) + +// AMOLED Display (displayio + qspibus path) - initialized in board_init() +#define CIRCUITPY_BOARD_DISPLAY (1) +#define CIRCUITPY_LCD_CS (&pin_GPIO9) +#define CIRCUITPY_LCD_CLK (&pin_GPIO10) +#define CIRCUITPY_LCD_D0 (&pin_GPIO11) +#define CIRCUITPY_LCD_D1 (&pin_GPIO12) +#define CIRCUITPY_LCD_D2 (&pin_GPIO13) +#define CIRCUITPY_LCD_D3 (&pin_GPIO14) +#define CIRCUITPY_LCD_RESET (&pin_GPIO21) +#define CIRCUITPY_LCD_POWER (&pin_GPIO16) + +// No default SPI bus — SD card uses SDIO, display uses QSPI. +#define CIRCUITPY_BOARD_SPI (0) + +// Default UART bus +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.mk new file mode 100644 index 00000000000..f901246804c --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/mpconfigboard.mk @@ -0,0 +1,35 @@ +# This file is part of the CircuitPython project: https://circuitpython.org +# SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +# SPDX-License-Identifier: MIT + +USB_VID = 0x303A +USB_PID = 0x8278 +USB_MANUFACTURER = "Waveshare" +USB_PRODUCT = "ESP32-S3-Touch-AMOLED-2.41" + +IDF_TARGET = esp32s3 + +# Flash configuration - 16MB QSPI Flash +CIRCUITPY_ESP_FLASH_SIZE = 16MB +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m + +# PSRAM configuration - 8MB Octal PSRAM +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +OPTIMIZATION_FLAGS = -Os + +# QSPI bus for RM690B0 AMOLED display +CIRCUITPY_QSPIBUS = 1 +CIRCUITPY_PARALLELDISPLAYBUS = 0 + +# No camera on this board +CIRCUITPY_ESPCAMERA = 0 + +# Capacitive touch not available; board uses I2C touch controller +CIRCUITPY_TOUCHIO = 0 + +# SD card via SDMMC interface +CIRCUITPY_SDIOIO = 1 diff --git a/ports/espressif/boards/waveshare_esp32_s3_amoled_241/pins.c b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/pins.c new file mode 100644 index 00000000000..8804cace06d --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/pins.c @@ -0,0 +1,109 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/mphal.h" +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // ================================================================= + // ONBOARD PERIPHERALS - Functional Names + // ================================================================= + + // Boot/Control/Battery/Display Power + // NOTE: GPIO16 is shared between battery control circuitry and LCD power + // (see CIRCUITPY_QSPIBUS_PANEL_POWER_PIN in mpconfigboard.h). + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_KEY_BAT), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_BAT_CONTROL), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LCD_POWER), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO17) }, + + // I2C Bus (shared by Touch, RTC, IMU, IO Expander) + // NOTE: board.I2C auto-initialization is disabled (CIRCUITPY_BOARD_I2C=0) + // to avoid boot conflicts. Users must manually create I2C bus: + // i2c = busio.I2C(board.SCL, board.SDA) + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO48) }, + + // Touch Panel (FT6336U on I2C) + // NOTE: TP_INT is routed through the TCA9554 IO expander (EXIO2), + // not a direct ESP32-S3 GPIO — no TOUCH_INT alias is possible here. + { MP_ROM_QSTR(MP_QSTR_TP_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_TP_SCL), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_TP_RESET), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_SCL), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_RST), MP_ROM_PTR(&pin_GPIO3) }, + + // RTC (PCF85063 on I2C) + { MP_ROM_QSTR(MP_QSTR_RTC_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_RTC_SCL), MP_ROM_PTR(&pin_GPIO48) }, + + // IMU (QMI8658 on I2C) + { MP_ROM_QSTR(MP_QSTR_IMU_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IMU_SCL), MP_ROM_PTR(&pin_GPIO48) }, + + // I/O Expander (TCA9554 on I2C) + { MP_ROM_QSTR(MP_QSTR_EXIO_SDA), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_EXIO_SCL), MP_ROM_PTR(&pin_GPIO48) }, + + // USB + { MP_ROM_QSTR(MP_QSTR_USB_D_N), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_USB_D_P), MP_ROM_PTR(&pin_GPIO20) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // QSPI Display (RM690B0) - canonical generic LCD aliases. + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D0), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D1), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D2), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D3), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RESET), MP_ROM_PTR(&pin_GPIO21) }, + + // Display Aliases + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_SCK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_D0), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_D1), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_D2), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_D3), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_RST), MP_ROM_PTR(&pin_GPIO21) }, + + // SD Card (SDIO / SDMMC) + { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_CMD), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_D0), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_D3), MP_ROM_PTR(&pin_GPIO2) }, + + // ================================================================= + // GENERAL PURPOSE I/O (IOxx - Espressif Convention) + // ================================================================= + // Only pins NOT dedicated to onboard peripherals are exposed here. + // Use functional names above for dedicated pins (e.g., SDA, SD_CS). + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, // BOOT button (available when not holding BOOT) + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, // TP_RESET (available if touch not used) + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, // Available + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, // Available + + // Board display (initialized in board_init) + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_amoled_241/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/sdkconfig new file mode 100644 index 00000000000..fa60cc4c237 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_amoled_241/sdkconfig @@ -0,0 +1,3 @@ +# +# Configuration file for the Waveshare ESP32-S3 Touch AMOLED 2.41 +# diff --git a/ports/espressif/boards/waveshare_esp32_s3_eth/board.c b/ports/espressif/boards/waveshare_esp32_s3_eth/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_eth/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s3_eth/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_eth/mpconfigboard.h new file mode 100644 index 00000000000..5630a162798 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_eth/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3-ETH" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_eth/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_eth/mpconfigboard.mk new file mode 100644 index 00000000000..f1f5128d26f --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_eth/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303a +USB_PID = 0x82a7 +USB_PRODUCT = "ESP32-S3-ETH" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m +CIRCUITPY_ESP_PSRAM_SIZE = 8MB diff --git a/ports/espressif/boards/waveshare_esp32_s3_eth/pins.c b/ports/espressif/boards/waveshare_esp32_s3_eth/pins.c new file mode 100644 index 00000000000..ac2b3e3258d --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_eth/pins.c @@ -0,0 +1,80 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + + // SD + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + + // Ethernet + { MP_ROM_QSTR(MP_QSTR_ETH_RST), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_ETH_INT), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_ETH_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_ETH_MISO), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_ETH_CLK), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_ETH_CS), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + + // USB - these pins are broken out on the header + // D_N + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + // D_P + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + + // NeoPixel + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_eth/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_eth/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_eth/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/waveshare_esp32_s3_geek/board.c b/ports/espressif/boards/waveshare_esp32_s3_geek/board.c index 71f742b51f4..0ce44753264 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_geek/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_geek/board.c @@ -30,26 +30,17 @@ uint8_t display_init_sequence[] = { }; static void display_init(void) { - busio_spi_obj_t *spi = common_hal_board_create_spi(0); fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; - common_hal_busio_spi_construct( - spi, - &pin_GPIO12, // CLK - &pin_GPIO11, // MOSI - NULL, // MISO not connected - false); // Not half-duplex - - bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // TFT_DC - &pin_GPIO10, // TFT_CS - &pin_GPIO9, // TFT_RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO10), // TFT_CS + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_RST 50000000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/espressif/boards/waveshare_esp32_s3_geek/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_geek/mpconfigboard.h index 2da021447e3..adb5a1c3af7 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_geek/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32_s3_geek/mpconfigboard.h @@ -17,6 +17,9 @@ #define DEFAULT_I2C_BUS_SCL (&pin_GPIO17) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO16) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO12, .mosi = &pin_GPIO11}, \ + {.clock = &pin_GPIO36, .mosi = &pin_GPIO35, .miso = &pin_GPIO37}} + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_geek/pins.c b/ports/espressif/boards/waveshare_esp32_s3_geek/pins.c index 01c3baf8c9f..65d391ec9ea 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_geek/pins.c +++ b/ports/espressif/boards/waveshare_esp32_s3_geek/pins.c @@ -5,8 +5,10 @@ // SPDX-License-Identifier: MIT #include "shared-bindings/board/__init__.h" - #include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 1) + static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS @@ -64,11 +66,11 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, // SD Card - { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO36)}, - { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO35)}, - { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO37)}, - { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO34)}, - { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, // Pin 38 is for the SDIO interface, and therefore not included in the SPI object // LCD @@ -78,6 +80,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO9) }, { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO7) }, { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, }; diff --git a/ports/espressif/boards/waveshare_esp32_s3_geek/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_geek/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_geek/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32_s3_geek/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c index 36990c85566..ee47ccb0bc9 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/board.c @@ -105,9 +105,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // DC - &pin_GPIO9, // CS - &pin_GPIO12, // RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST 80000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.h index 1e1acbdd9f8..f19baae3c46 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.h @@ -23,3 +23,6 @@ #define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX #define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.mk index a8ac3b5d245..f4d1f33be79 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.mk +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/mpconfigboard.mk @@ -21,4 +21,5 @@ INTERNAL_FLASH_FILESYSTEM = 0 QSPI_FLASH_FILESYSTEM = 1 EXTERNAL_FLASH_DEVICES = W25Q128JVxQ +# Not enough pins. CIRCUITPY_ESPCAMERA = 0 diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/sdkconfig index bcfb4d48ffe..e9628662160 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_28/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="waveshare-esp32-s3-lcd-1-28" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/board.c b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/board.c new file mode 100644 index 00000000000..4ecf87948ad --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/board.c @@ -0,0 +1,99 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Benjamin Shockley +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + +// Driver is ST7789V3 +// Display Panel is LBS147TC-IF15 +// 172 X 320 Pixels RGB 18-bit + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 120, + 0x11, 0 | DELAY, 120, + 0x13, 0, + 0x36, 1, 0x00, + 0x3A, 1 | DELAY, 0x05, 10, + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + 0xB7, 1, 0x35, + 0xBB, 1, 0x20, + 0xC0, 1, 0x2C, + 0xC2, 2, 0x01, 0xFF, + 0xC3, 1, 0x13, + 0xC4, 1, 0x20, + 0xC6, 1, 0x0F, + 0xD0, 2, 0xA4, 0xA1, + 0xE0, 14, 0xF0, 0x00, 0x04, 0x04, 0x04, 0x05, 0x29, 0x33, 0x3E, 0x38, 0x12, 0x12, 0x28, 0x30, + 0xE1, 14, 0xF0, 0x07, 0x0A, 0x0D, 0x0B, 0x07, 0x28, 0x33, 0x3E, 0x36, 0x14, 0x14, 0x29, 0x32, + 0x21, 0, + 0x29, 0 | DELAY, 255, +}; + +static void display_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO41), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO39), // RST + 80000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 172, // width (after rotation) + 320, // height (after rotation) + 34, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO48, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/mpconfigboard.h new file mode 100644 index 00000000000..47d03fe9554 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/mpconfigboard.h @@ -0,0 +1,25 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Benjamin Shockley +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3 LCD 1.47" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO17) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO16) + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO40, .mosi = &pin_GPIO45}, \ + {.clock = &pin_GPIO14, .mosi = &pin_GPIO15, .miso = &pin_GPIO16}} + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/mpconfigboard.mk new file mode 100644 index 00000000000..fbdc6a7a1ec --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x828B +USB_PRODUCT = "ESP32-S3-LCD-1.47" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/pins.c b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/pins.c new file mode 100644 index 00000000000..a2ebbb79a87 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/pins.c @@ -0,0 +1,81 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Button + { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + // RGB LED + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_GP38), MP_ROM_PTR(&pin_GPIO38) }, + + // 7-12 LCD + // LCD Backlight + { MP_ROM_QSTR(MP_QSTR_GP48), MP_ROM_PTR(&pin_GPIO48) }, + // LCD DC + { MP_ROM_QSTR(MP_QSTR_GP41), MP_ROM_PTR(&pin_GPIO41) }, + // LCD RST + { MP_ROM_QSTR(MP_QSTR_GP39), MP_ROM_PTR(&pin_GPIO39) }, + // LCD CS + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_GP42), MP_ROM_PTR(&pin_GPIO42) }, + // LCD MOSI + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_GP45), MP_ROM_PTR(&pin_GPIO45) }, + // LCD SCK + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GP40), MP_ROM_PTR(&pin_GPIO40) }, + + // 14-21 SD + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + // 43-44 UART + { MP_ROM_QSTR(MP_QSTR_GP43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_GP44), MP_ROM_PTR(&pin_GPIO44) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // SD Card + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, + // Pin 38 is for the SDIO interface, and therefore not included in the SPI object + + // LCD + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_lcd_1_47/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/waveshare_esp32_s3_matrix/board.c b/ports/espressif/boards/waveshare_esp32_s3_matrix/board.c new file mode 100644 index 00000000000..5859571eefa --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_matrix/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 David Sullivan +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s3_matrix/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_matrix/mpconfigboard.h new file mode 100644 index 00000000000..c6c68e8336f --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_matrix/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 David Sullivan +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3-Matrix" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_matrix/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_matrix/mpconfigboard.mk new file mode 100644 index 00000000000..0378c23be69 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_matrix/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x303a +USB_PID = 0x826E +USB_PRODUCT = "Waveshare ESP32-S3-Matrix" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 4MB + +CIRCUITPY_ESP_PSRAM_SIZE = 2MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/waveshare_esp32_s3_matrix/pins.c b/ports/espressif/boards/waveshare_esp32_s3_matrix/pins.c new file mode 100644 index 00000000000..a107cd61c22 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_matrix/pins.c @@ -0,0 +1,91 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 David Sullivan +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Top side of the board - left column + // (top to bottom, preceded by 5V, GND & 3.3V) + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + // Top side of the board - right column (bottom to top) + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO37) }, + + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO40) }, + + // Numbering breaks up for TX/RX but it's still the top side, right column + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // Neopixel + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO14) }, + + // QMI8658C IMU + { MP_ROM_QSTR(MP_QSTR_IMU_SDA), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IMU_SCL), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT1), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT2), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_matrix/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_matrix/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_matrix/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/waveshare_esp32_s3_pico/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_pico/mpconfigboard.h index 866fbdaea55..2b95643a41e 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_pico/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32_s3_pico/mpconfigboard.h @@ -11,6 +11,7 @@ #define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3-Pico" #define MICROPY_HW_MCU_NAME "ESP32S3" +#define MICROPY_HW_NEOPIXEL_ORDER_GRB (1) #define MICROPY_HW_NEOPIXEL (&pin_GPIO21) #define DEFAULT_UART_BUS_RX (&pin_GPIO12) @@ -22,3 +23,6 @@ #define DEFAULT_SPI_BUS_SCK (&pin_GPIO36) #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO35) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO37) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_pico/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_pico/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_pico/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32_s3_pico/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/waveshare_esp32_s3_tiny/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_tiny/mpconfigboard.h index fb33519370c..1785cc4486a 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_tiny/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32_s3_tiny/mpconfigboard.h @@ -17,3 +17,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO19) #define DEFAULT_UART_BUS_TX (&pin_GPIO20) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_tiny/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_tiny/sdkconfig index 19f833ad74c..e9628662160 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_tiny/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32_s3_tiny/sdkconfig @@ -7,8 +7,6 @@ # # LWIP # -# CONFIG_LWIP_IPV6 is not set -CONFIG_LWIP_LOCAL_HOSTNAME="waveshare-esp32-s3-tiny" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/board.c b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/board.c new file mode 100644 index 00000000000..a3a9eec0471 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/mpconfigboard.h new file mode 100644 index 00000000000..590b0fc5c5c --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3-Tiny-N8R8" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +// This corrects the color ordering so that the CircuitPython status lights behave as expected +#define MICROPY_HW_NEOPIXEL_ORDER_GRB (1) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO38) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO19) +#define DEFAULT_UART_BUS_TX (&pin_GPIO20) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/mpconfigboard.mk new file mode 100644 index 00000000000..ebb8317c457 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/mpconfigboard.mk @@ -0,0 +1,16 @@ +USB_VID = 0x303a +USB_PID = 0x8379 +USB_PRODUCT = "ESP32-S3-Tiny-N8R8" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/pins.c b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/pins.c new file mode 100644 index 00000000000..917ef0506ab --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/pins.c @@ -0,0 +1,61 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_IO34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_IO35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_IO36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_IO37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_IO38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_IO39), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_IO40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_IO41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_IO42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_IO45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_IO46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + + // NEOPIXEL (GRB Color Order) + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO38) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + // Any pins can be I2C + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + // Any pins can be SPI + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_tiny_n8r8/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c new file mode 100644 index 00000000000..1bdd74e77ee --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/board.c @@ -0,0 +1,145 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 natheihei +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + +// Driver is JD9853 +// 172 X 320 Pixels RGB 18-bit +// Init sequence converted from Arduino example + +uint8_t display_init_sequence[] = { + // Command: 0x11 (SLPOUT: Sleep Out) + // Description: Exits sleep mode. A 120ms delay is added for the power supply and clock circuits to stabilize. + 0x11, 0 | DELAY, 120, + + 0xDF, 2, 0x98, 0x53, + 0xB2, 1, 0x23, + + 0xB7, 4, 0x00, 0x47, 0x00, 0x6F, + 0xBB, 6, 0x1C, 0x1A, 0x55, 0x73, 0x63, 0xF0, + 0xC0, 2, 0x44, 0xA4, + 0xC1, 1, 0x16, + 0xC3, 8, 0x7D, 0x07, 0x14, 0x06, 0xCF, 0x71, 0x72, 0x77, + 0xC4, 12, 0x00, 0x00, 0xA0, 0x79, 0x0B, 0x0A, 0x16, 0x79, 0x0B, 0x0A, 0x16, 0x82, + + 0xC8, 32, 0x3F, 0x32, 0x29, 0x29, 0x27, 0x2B, 0x27, 0x28, 0x28, 0x26, 0x25, 0x17, 0x12, 0x0D, 0x04, 0x00, + 0x3F, 0x32, 0x29, 0x29, 0x27, 0x2B, 0x27, 0x28, 0x28, 0x26, 0x25, 0x17, 0x12, 0x0D, 0x04, 0x00, + + 0xD0, 5, 0x04, 0x06, 0x6B, 0x0F, 0x00, + 0xD7, 2, 0x00, 0x30, + 0xE6, 1, 0x14, + 0xDE, 1, 0x01, + + 0xB7, 5, 0x03, 0x13, 0xEF, 0x35, 0x35, + 0xC1, 3, 0x14, 0x15, 0xC0, + 0xC2, 2, 0x06, 0x3A, + 0xC4, 2, 0x72, 0x12, + 0xBE, 1, 0x00, + 0xDE, 1, 0x02, + + 0xE5, 3, 0x00, 0x02, 0x00, + 0xE5, 3, 0x01, 0x02, 0x00, + + 0xDE, 1, 0x00, + + // Command: 0x35 (TEON: Tearing Effect Line ON) + // Description: Turns on the Tearing Effect output signal. + 0x35, 1, 0x00, + + // Command: 0x3A (COLMOD: Pixel Format Set) + // Description: Sets the pixel format for the MCU interface. + 0x3A, 1, 0x05, + + // Command: 0x2A (CASET: Column Address Set) + // Description: Defines the accessible column range in frame memory. + 0x2A, 4, 0x00, 0x22, 0x00, 0xCD, + + // Command: 0x2B (PASET: Page Address Set) + // Description: Defines the accessible page (row) range. + 0x2B, 4, 0x00, 0x00, 0x01, 0x3F, + + 0xDE, 1, 0x02, + 0xE5, 3, 0x00, 0x02, 0x00, + 0xDE, 1, 0x00, + + // Command: 0x36 (MADCTL: Memory Access Control) + // Description: Sets the read/write scanning direction of the frame memory. + 0x36, 1, 0x00, + + // Command: 0x21 (INVON: Display Inversion ON) + // 0x21, 0 | DELAY, 10, + + // Command: 0x29 (DISPON: Display ON) + // Description: Turns the display on by enabling output from the frame memory. + 0x29, 0, +}; + +static void display_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO45), // DC + MP_OBJ_FROM_PTR(&pin_GPIO21), // CS + MP_OBJ_FROM_PTR(&pin_GPIO40), // RST + 80000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 172, // width (after rotation) + 320, // height (after rotation) + 34, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO46, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Display + display_init(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.h new file mode 100644 index 00000000000..7fed8626501 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.h @@ -0,0 +1,25 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 natheihei +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3 Touch LCD 1.47" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.rx = &pin_GPIO44, .tx = &pin_GPIO43}} + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO41, .sda = &pin_GPIO42}} /* for Touchscreen */ + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO38, .mosi = &pin_GPIO39}, /* for LCD display */ \ + {.clock = &pin_GPIO16, .mosi = &pin_GPIO15, .miso = &pin_GPIO17} /* for SD Card */} + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.mk new file mode 100644 index 00000000000..b337b211495 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x8325 +USB_PRODUCT = "ESP32-S3-Touch-LCD-1.47" +USB_MANUFACTURER = "Waveshare Electronics" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/pins.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/pins.c new file mode 100644 index 00000000000..32c7d0dd21d --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/pins.c @@ -0,0 +1,58 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 natheihei +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(touch_i2c, i2c, 0) +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // GPIO + { MP_ROM_QSTR(MP_QSTR_GPIO1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GPIO3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GPIO5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GPIO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GPIO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GPIO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GPIO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GPIO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GPIO11), MP_ROM_PTR(&pin_GPIO11) }, + + // I2C (occupied by Touch I2C) + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // SD Card + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_D0), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SD_D1), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SD_D2), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SD_D3), MP_ROM_PTR(&pin_GPIO14) }, + // CLK, CMD, D0 is also included in the SPI object as its MISO pin, MOSI pin, and SCK pin respectively + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, + + // AXS5106L Touch + { MP_ROM_QSTR(MP_QSTR_TOUCH_I2C), MP_ROM_PTR(&board_touch_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_RST), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_TOUCH_IRQ), MP_ROM_PTR(&pin_GPIO48) }, + + // JD9853 LCD Display + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_1_47/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/board.c new file mode 100644 index 00000000000..71e2d745623 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/board.c @@ -0,0 +1,78 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + 0x01, DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, DELAY, 0xFF, // _SLPOUT and Delay 500ms + 0x3A, DELAY | 1, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x21, DELAY, 0x0A, // _INVON Hack and Delay 10ms + 0x13, DELAY, 0x0A, // _NORON and Delay 10ms + 0x36, 0x01, 0x60, // _MADCTL + 0x29, DELAY, 0xFF, // _DISPON and Delay 500ms +}; + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO42), // DC + MP_OBJ_FROM_PTR(&pin_GPIO45), // CS + MP_OBJ_FROM_PTR(&pin_GPIO0), // RST + // 24000000, + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 320, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO1, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/mpconfigboard.h new file mode 100644 index 00000000000..d6b66bffafa --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Neradoc +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32S3 Touch LCD 2" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO47, .sda = &pin_GPIO48}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO39, .mosi = &pin_GPIO38, .miso = &pin_GPIO40}} + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/mpconfigboard.mk new file mode 100644 index 00000000000..a6c719bf50f --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x82CE +USB_MANUFACTURER = "Waveshare Electronics" +USB_PRODUCT = "ESP32S3 Touch LCD 2" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/pins.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/pins.c new file mode 100644 index 00000000000..015a7a33952 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/pins.c @@ -0,0 +1,94 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // User accessible GPIO + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_IO6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_IO9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_IO16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_IO17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_IO48), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IO14), MP_ROM_PTR(&pin_GPIO14) }, + + // User button + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + + // Battery ADC + {MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_GPIO5)}, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO48) }, + + // CST816D Touch + { MP_ROM_QSTR(MP_QSTR_TOUCH_INT), MP_ROM_PTR(&pin_GPIO46) }, + + // QMI8658 IMU + { MP_ROM_QSTR(MP_QSTR_IMU_INT), MP_ROM_PTR(&pin_GPIO3) }, + + // SPI + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO40) }, + + // LCD + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RESET), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO1) }, + + // SD Card slot + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO41) }, + + // Camera connector + { MP_ROM_QSTR(MP_QSTR_CAM_HREF), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_CAM_VSYNC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_CAM_XCLK), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_CAM_PCLK), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_CAM_PWDN), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D0), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D1), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D2), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D3), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D4), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D5), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D6), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_CAM_D7), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_TWI_CLK), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_TWI_SDA), MP_ROM_PTR(&pin_GPIO21) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + + // Objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c new file mode 100755 index 00000000000..49177f48fe7 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/board.c @@ -0,0 +1,77 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + +// display init sequence according to LilyGO example app +uint8_t display_init_sequence[] = { + 0x01, DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, DELAY, 0xFF, // _SLPOUT and Delay 500ms + 0x3A, DELAY | 1, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x21, DELAY, 0x0A, // _INVON Hack and Delay 10ms + 0x13, DELAY, 0x0A, // _NORON and Delay 10ms + 0x36, 0x01, 0x60, // _MADCTL + 0x29, DELAY, 0xFF, // _DISPON and Delay 500ms +}; + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO41), // DC + MP_OBJ_FROM_PTR(&pin_GPIO42), // CS + MP_OBJ_FROM_PTR(&pin_GPIO39), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 320, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO5, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.h new file mode 100755 index 00000000000..a04002de73f --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Neradoc +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare ESP32-S3 Touch LCD 2.8" +#define MICROPY_HW_MCU_NAME "ESP32S3" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO3, .sda = &pin_GPIO1}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO40, .mosi = &pin_GPIO45, .miso = &pin_GPIO46}} + +#define DEFAULT_UART_BUS_RX (&pin_GPIO44) +#define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk new file mode 100755 index 00000000000..421a5897600 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x303A +USB_PID = 0x825F +USB_MANUFACTURER = "Waveshare Electronics" +USB_PRODUCT = "ESP32-S3 Touch LCD 2.8" + +IDF_TARGET = esp32s3 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = opi +CIRCUITPY_ESP_PSRAM_FREQ = 80m diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c new file mode 100755 index 00000000000..0bfb3e940b4 --- /dev/null +++ b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/pins.c @@ -0,0 +1,86 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // LCD (SPI0) + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MISO), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO5) }, // PWM-capable + + // microSD (SPI1) + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO21) }, + + // Touch panel (I2C0) + { MP_ROM_QSTR(MP_QSTR_TP_SCL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_TP_SDA), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_TP_RST), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_TP_INT), MP_ROM_PTR(&pin_GPIO4) }, + + // IMU (I2C1) + { MP_ROM_QSTR(MP_QSTR_IMU_SCL), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IMU_SDA), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT2), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_IMU_INT1), MP_ROM_PTR(&pin_GPIO13) }, + + // I2S Audio + { MP_ROM_QSTR(MP_QSTR_I2S_BCK), MP_ROM_PTR(&pin_GPIO48) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DIN), MP_ROM_PTR(&pin_GPIO47) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCK), MP_ROM_PTR(&pin_GPIO38) }, + + // Battery management + { MP_ROM_QSTR(MP_QSTR_BAT_CONTROL), MP_ROM_PTR(&pin_GPIO7) }, // control pin + { MP_ROM_QSTR(MP_QSTR_BAT_PWR), MP_ROM_PTR(&pin_GPIO6) }, // Board name + { MP_ROM_QSTR(MP_QSTR_KEY_BAT), MP_ROM_PTR(&pin_GPIO6) }, // Schematics name + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO8) }, // VBAT sense (ADC) + + // UART header + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO44) }, + + // I2C header + { MP_ROM_QSTR(MP_QSTR_I2C_SCL), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_I2C_SDA), MP_ROM_PTR(&pin_GPIO11) }, + + // Boot/User button + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON0), MP_ROM_PTR(&pin_GPIO0) }, + + // Primary bus pins + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO40) }, // Primary SPI (LCD) + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO46) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, // Primary I2C (TP) + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO1) }, + + // Objects + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + + // User accessible + { MP_ROM_QSTR(MP_QSTR_IO10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_IO11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_IO15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_IO18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_IO19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_IO20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_IO43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_IO44), MP_ROM_PTR(&pin_GPIO44) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_touch_lcd_2_8/sdkconfig new file mode 100755 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.h index da6b7a8a855..f0a19c0e290 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.h @@ -16,3 +16,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.mk b/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.mk index e1f616dea12..6e386e70e17 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.mk +++ b/ports/espressif/boards/waveshare_esp32_s3_zero/mpconfigboard.mk @@ -13,10 +13,5 @@ CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_FREQ = 80m -CIRCUITPY_ESPCAMERA = 0 -CIRCUITPY_BITMAPFILTER = 0 -CIRCUITPY_CODEOP = 0 -CIRCUITPY_PARALLELDISPLAYBUS = 0 - # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel diff --git a/ports/espressif/boards/waveshare_esp32_s3_zero/pins.c b/ports/espressif/boards/waveshare_esp32_s3_zero/pins.c index c4cd4ab8219..15225b1c57c 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_zero/pins.c +++ b/ports/espressif/boards/waveshare_esp32_s3_zero/pins.c @@ -9,6 +9,11 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + // BOOT button labeled simply as "B" on silkscreen + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + // Top side of the board - left column // (top to bottom, preceded by 5V, GND & 3.3V) { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_GPIO1) }, @@ -147,8 +152,7 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + // UART - using TX RX on silkscreen { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/waveshare_esp32_s3_zero/sdkconfig b/ports/espressif/boards/waveshare_esp32_s3_zero/sdkconfig index 608f7e6a11c..e9628662160 100644 --- a/ports/espressif/boards/waveshare_esp32_s3_zero/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32_s3_zero/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="ESP32-S3-Zero" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h index 2888af9184a..5875725a00f 100644 --- a/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h +++ b/ports/espressif/boards/waveshare_esp32s2_pico/mpconfigboard.h @@ -23,3 +23,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO44) #define DEFAULT_UART_BUS_TX (&pin_GPIO43) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig b/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig index 7c86f9f8e37..e9628662160 100644 --- a/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig +++ b/ports/espressif/boards/waveshare_esp32s2_pico/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="waveshare" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/weact_esp32c6_n4/mpconfigboard.mk b/ports/espressif/boards/weact_esp32c6_n4/mpconfigboard.mk index 45309d28904..bdd407ef10d 100644 --- a/ports/espressif/boards/weact_esp32c6_n4/mpconfigboard.mk +++ b/ports/espressif/boards/weact_esp32c6_n4/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32c6 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 - -CIRCUITPY_AUDIOMP3 = 0 diff --git a/ports/espressif/boards/weact_esp32c6_n4/sdkconfig b/ports/espressif/boards/weact_esp32c6_n4/sdkconfig index 63084f9368d..e9628662160 100644 --- a/ports/espressif/boards/weact_esp32c6_n4/sdkconfig +++ b/ports/espressif/boards/weact_esp32c6_n4/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="WEACT-ESP32-C6" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/weact_esp32c6_n8/sdkconfig b/ports/espressif/boards/weact_esp32c6_n8/sdkconfig index 63084f9368d..e9628662160 100644 --- a/ports/espressif/boards/weact_esp32c6_n8/sdkconfig +++ b/ports/espressif/boards/weact_esp32c6_n8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="WEACT-ESP32-C6" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.h b/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.h index 6a9f0357156..fa0ed02f676 100644 --- a/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.h +++ b/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.h @@ -20,3 +20,6 @@ // UART pins attached to the USB-serial converter chip #define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) #define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) + +// Reduce wifi.radio.tx_power due to the antenna design of this board +#define CIRCUITPY_WIFI_DEFAULT_TX_POWER (15) diff --git a/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.mk b/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.mk index 3c456881819..83e2289e729 100644 --- a/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.mk +++ b/ports/espressif/boards/wemos_lolin32_lite/mpconfigboard.mk @@ -6,7 +6,3 @@ IDF_TARGET = esp32 CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_FREQ = 80m CIRCUITPY_ESP_FLASH_SIZE = 4MB - -CIRCUITPY_ESPCAMERA = 0 - -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT = 1 diff --git a/ports/espressif/boards/wemos_lolin32_lite/sdkconfig b/ports/espressif/boards/wemos_lolin32_lite/sdkconfig index 72be49f97e8..e9628662160 100644 --- a/ports/espressif/boards/wemos_lolin32_lite/sdkconfig +++ b/ports/espressif/boards/wemos_lolin32_lite/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="LOLIN32Lite" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/xteink_x4/board.c b/ports/espressif/boards/xteink_x4/board.c new file mode 100644 index 00000000000..b5b193c65fe --- /dev/null +++ b/ports/espressif/boards/xteink_x4/board.c @@ -0,0 +1,130 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// SPDX-FileCopyrightText: Copyright (c) 2021 skieast/Bruce Segal +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/board.h" + +#define DELAY 0x80 + +// SSD1677 controller driving a GDEQ0426T82 4.26" 800x480 E-Ink display. + +const uint8_t ssd1677_display_start_sequence[] = { + // Software Reset + 0x12, DELAY, 0x00, 0x14, + + // Temperature Sensor Control (use internal sensor) + 0x18, 0x00, 0x01, 0x80, + + // Booster Soft Start + 0x0C, 0x00, 0x05, 0xAE, 0xC7, 0xC3, 0xC0, 0x40, + + // Driver Output Control: 480 gates, GD=0, SM=1, TB=0 = 0x02 + 0x01, 0x00, 0x03, 0xDF, 0x01, 0x02, + + // Data Entry Mode: X increment, Y decrement = 0x01 + 0x11, 0x00, 0x01, 0x01, + + // Border Waveform Control + 0x3C, 0x00, 0x01, 0x01, + + // Set RAM X Address Start/End: 0 to 799 + 0x44, 0x00, 0x04, 0x00, 0x00, 0x1F, 0x03, + + // Set RAM Y Address Start/End: 479 down to 0 + 0x45, 0x00, 0x04, 0xDF, 0x01, 0x00, 0x00, + + // Set RAM X Counter to 0 + 0x4E, 0x00, 0x02, 0x00, 0x00, + + // Set RAM Y Counter to 479 + 0x4F, 0x00, 0x02, 0xDF, 0x01, + + // Auto Write BW RAM (clear to white) + 0x46, DELAY, 0x01, 0xF7, 0xFF, + + // Display Update Control 1: bypass RED + 0x21, 0x00, 0x02, 0x40, 0x00, + + // Display Update Control 2: full refresh with OTP LUT + 0x22, 0x00, 0x01, 0xF7, +}; + +const uint8_t ssd1677_display_stop_sequence[] = { + 0x22, 0x00, 0x01, 0x83, + 0x20, 0x00, 0x00, + 0x10, 0x00, 0x01, 0x01, +}; + +const uint8_t ssd1677_display_refresh_sequence[] = { + 0x20, 0x00, 0x00, +}; + +void board_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO8, &pin_GPIO10, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO4), + MP_OBJ_FROM_PTR(&pin_GPIO21), + MP_OBJ_FROM_PTR(&pin_GPIO5), + 40000000, + 0, + 0); + + epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; + display->base.type = &epaperdisplay_epaperdisplay_type; + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = ssd1677_display_start_sequence; + args.start_sequence_len = sizeof(ssd1677_display_start_sequence); + args.stop_sequence = ssd1677_display_stop_sequence; + args.stop_sequence_len = sizeof(ssd1677_display_stop_sequence); + args.width = 800; + args.height = 480; + args.ram_width = 800; + args.ram_height = 480; + args.rotation = 0; + args.write_black_ram_command = 0x24; + args.black_bits_inverted = false; + args.refresh_sequence = ssd1677_display_refresh_sequence; + args.refresh_sequence_len = sizeof(ssd1677_display_refresh_sequence); + args.refresh_time = 1.6; + args.busy_pin = &pin_GPIO6; + args.busy_state = true; + args.seconds_per_frame = 5.0; + args.grayscale = false; + args.two_byte_sequence_length = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); +} + +bool espressif_board_reset_pin_number(gpio_num_t pin_number) { + return false; +} + +void board_deinit(void) { + epaperdisplay_epaperdisplay_obj_t *display = &displays[0].epaper_display; + if (display->base.type == &epaperdisplay_epaperdisplay_type) { + while (common_hal_epaperdisplay_epaperdisplay_get_busy(display)) { + RUN_BACKGROUND_TASKS; + } + } + common_hal_displayio_release_displays(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/espressif/boards/xteink_x4/mpconfigboard.h b/ports/espressif/boards/xteink_x4/mpconfigboard.h new file mode 100644 index 00000000000..5d4bb372228 --- /dev/null +++ b/ports/espressif/boards/xteink_x4/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// SPDX-FileCopyrightText: Copyright (c) 2021 skieast/Bruce Segal +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Board setup +#define MICROPY_HW_BOARD_NAME "Xteink X4" +#define MICROPY_HW_MCU_NAME "ESP32-C3" + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO8, .mosi = &pin_GPIO10, .miso = &pin_GPIO7}} + +// For entering safe mode +#define CIRCUITPY_BOOT_BUTTON (&pin_GPIO3) diff --git a/ports/espressif/boards/xteink_x4/mpconfigboard.mk b/ports/espressif/boards/xteink_x4/mpconfigboard.mk new file mode 100644 index 00000000000..8668aad1818 --- /dev/null +++ b/ports/espressif/boards/xteink_x4/mpconfigboard.mk @@ -0,0 +1,29 @@ +CIRCUITPY_CREATOR_ID = 0x0EEE0000 +CIRCUITPY_CREATION_ID = 0x00C30001 + +IDF_TARGET = esp32c3 + +CIRCUITPY_ESP_FLASH_MODE = dio +CIRCUITPY_ESP_FLASH_FREQ = 40m +CIRCUITPY_ESP_FLASH_SIZE = 16MB + +CIRCUITPY_ESP_USB_SERIAL_JTAG = 1 + +CIRCUITPY_PARALLELDISPLAYBUS = 0 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOCORE = 0 +CIRCUITPY_AUDIOMIXER = 0 +CIRCUITPY_AUDIOMP3 = 0 +CIRCUITPY_CAMERA = 0 +CIRCUITPY_CANIO = 0 +CIRCUITPY_DOTCLOCKFRAMEBUFFER = 0 +CIRCUITPY_KEYPAD = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_ULAB = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_PWMIO = 0 +CIRCUITPY_RAINBOWIO = 0 +CIRCUITPY_SYNTHIO = 0 diff --git a/ports/espressif/boards/xteink_x4/pins.c b/ports/espressif/boards/xteink_x4/pins.c new file mode 100644 index 00000000000..6b8232d4cb3 --- /dev/null +++ b/ports/espressif/boards/xteink_x4/pins.c @@ -0,0 +1,52 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// SPDX-FileCopyrightText: Copyright (c) 2021 skieast/Bruce Segal +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_BOOT0), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_ADC_1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_ADC_2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_EPD_MOSI), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_EPD_SCK), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_EPD_BUSY), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_EPD_RESET), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_EPD_DC), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_EPD_CS), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].epaper_display)}, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/espressif/boards/xteink_x4/sdkconfig b/ports/espressif/boards/xteink_x4/sdkconfig new file mode 100644 index 00000000000..e9628662160 --- /dev/null +++ b/ports/espressif/boards/xteink_x4/sdkconfig @@ -0,0 +1,14 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# LWIP +# +# end of LWIP + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/boards/yd_esp32_s3_n16r8/sdkconfig b/ports/espressif/boards/yd_esp32_s3_n16r8/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/yd_esp32_s3_n16r8/sdkconfig +++ b/ports/espressif/boards/yd_esp32_s3_n16r8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/yd_esp32_s3_n8r8/sdkconfig b/ports/espressif/boards/yd_esp32_s3_n8r8/sdkconfig index f5ef7976811..e9628662160 100644 --- a/ports/espressif/boards/yd_esp32_s3_n8r8/sdkconfig +++ b/ports/espressif/boards/yd_esp32_s3_n8r8/sdkconfig @@ -7,7 +7,6 @@ # # LWIP # -CONFIG_LWIP_LOCAL_HOSTNAME="espressif-esp32s3" # end of LWIP # end of Component config diff --git a/ports/espressif/boards/yoto_mini_2024/board.c b/ports/espressif/boards/yoto_mini_2024/board.c new file mode 100644 index 00000000000..fb6a96a957d --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/board.c @@ -0,0 +1,203 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "board.h" + +#include "supervisor/board.h" + +#include "extmod/vfs_fat.h" + +#include "py/mpstate.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-bindings/sdioio/SDCard.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#include "supervisor/filesystem.h" + +static sdioio_sdcard_obj_t sdmmc; +static mp_vfs_mount_t _sdcard_vfs; +static fs_user_mount_t _sdcard_usermount; +static i2cioexpander_ioexpander_obj_t ioexpander; + +#define DELAY 0x80 + +// This is a GC9306. +uint8_t display_init_sequence[] = { + 0xfe, 0, + 0xef, 0, + + // // sw reset + // 0x01, 0 | DELAY, 150, + // normal display mode on + // 0x13, 0, + // display and color format settings + 0x36, 1, 0x48, // Memory access control. mini does 0x48, not 0, 2, 3, 4 or 6 + 0x3A, 1 | DELAY, 0x55, 10, // COLMOD. mini does 0x06 + 0xa4, 2, 0x44, 0x44, // power control 7 + 0xa5, 2, 0x42, 0x42, + 0xaa, 2, 0x88, 0x88, + 0xae, 1, 0x2b, + 0xe8, 2, 0x22, 0x0b, // frame rate + 0xe3, 2, 0x01, 0x10, + 0xff, 1, 0x61, + 0xac, 1, 0x00, + 0xad, 1, 0x33, + 0xaf, 1, 0x77, + 0xa6, 2, 0x1c, 0x1c, // power control 2 + 0xa7, 2, 0x1c, 0x1c, // power control 3 + 0xa8, 2, 0x10, 0x10, // power control 4 + 0xa9, 2, 0x0d, 0x0d, // power control 5 + 0xf0, 6, 0x02, 0x01, 0x00, 0x00, 0x00, 0x05, // Gamma settings + 0xf1, 6, 0x01, 0x02, 0x00, 0x06, 0x10, 0x0e, + 0xf2, 6, 0x03, 0x11, 0x28, 0x02, 0x00, 0x48, + 0xf3, 6, 0x0c, 0x11, 0x30, 0x00, 0x00, 0x46, + 0xf4, 6, 0x05, 0x1f, 0x1f, 0x36, 0x30, 0x0f, + 0xf5, 6, 0x04, 0x1d, 0x1a, 0x38, 0x3f, 0x0f, // Last gamma setting + 0x35, 1, 0x00, + 0x44, 2, 0x00, 0x0a, // set tear scan line + 0x21, 0, // display inversion on + // sleep out + 0x11, 0 | DELAY, 255, + + // display on + 0x29, 0 | DELAY, 255, +}; + +void board_init(void) { + // Wait for everything to start + mp_hal_delay_ms(300); + + // Initialize the board's peripherals here. + busio_i2c_obj_t *i2c = MP_OBJ_TO_PTR(common_hal_board_create_i2c(0)); + + // Initialize the IOExpander + ioexpander.base.type = &i2cioexpander_ioexpander_type; + common_hal_i2cioexpander_ioexpander_construct( + &ioexpander, + MP_OBJ_FROM_PTR(i2c), + 0x20, // I2C address + 16, // Number of pins + 2, // Output register + 0, // Input register + 6); // Direction register + + board_set(MP_QSTR_IOEXPANDER, MP_OBJ_FROM_PTR(&ioexpander)); + board_set(MP_QSTR_PLUG_STATUS, ioexpander.pins->items[8 + 5]); + board_set(MP_QSTR_CHARGE_STATUS, ioexpander.pins->items[8 + 7]); + board_set(MP_QSTR_POWER_BUTTON, ioexpander.pins->items[8 + 3]); + board_set(MP_QSTR_ENC1_BUTTON, ioexpander.pins->items[5]); + board_set(MP_QSTR_ENC2_BUTTON, ioexpander.pins->items[4]); + board_set(MP_QSTR_HEADPHONE_DETECT, ioexpander.pins->items[8 + 1]); + board_set(MP_QSTR_PACTRL, ioexpander.pins->items[6]); + board_set(MP_QSTR_DISPLAY_CS, ioexpander.pins->items[0]); + board_set(MP_QSTR_DISPLAY_DC, ioexpander.pins->items[1]); + board_set(MP_QSTR_DISPLAY_RESET, ioexpander.pins->items[2]); + + board_set(MP_QSTR_LEVEL_CONVERTER, ioexpander.pins->items[3]); + board_set(MP_QSTR_LEVEL_POWER_ENABLE, ioexpander.pins->items[8 + 4]); + board_set(MP_QSTR_LEVEL_VINHOLD, ioexpander.pins->items[8 + 6]); + + board_set(MP_QSTR_TILT, ioexpander.pins->items[8 + 2]); + + // Only on some variants + board_set(MP_QSTR_RTC_INT, ioexpander.pins->items[7]); + + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[2]), true, DRIVE_MODE_PUSH_PULL); + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[3]), true, DRIVE_MODE_PUSH_PULL); + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[6]), true, DRIVE_MODE_PUSH_PULL); + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[14]), true, DRIVE_MODE_PUSH_PULL); + + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + ioexpander.pins->items[1], // DC + ioexpander.pins->items[0], // CS + ioexpander.pins->items[2], // RST + 25000000, // baudrate + 0, // polarity + 0 // phase + ); + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 240, // width (after rotation) + 240, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO26, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); + + digitalinout_result_t sd_enable_res = common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander.pins->items[12]), false, DRIVE_MODE_PUSH_PULL); + if (sd_enable_res != DIGITALINOUT_OK) { + mp_printf(&mp_plat_print, "Failed to initialize IOExpander. Skipping SD card\n"); + return; + } + + sdmmc.base.type = &sdioio_SDCard_type; + const mcu_pin_obj_t *data_pins[4] = {MP_ROM_PTR(&pin_GPIO2), MP_ROM_PTR(&pin_GPIO4), MP_ROM_PTR(&pin_GPIO12), MP_ROM_PTR(&pin_GPIO13)}; + common_hal_sdioio_sdcard_construct(&sdmmc, MP_ROM_PTR(&pin_GPIO14), MP_ROM_PTR(&pin_GPIO15), 4, data_pins, 25 * 1000000); + + fs_user_mount_t *vfs = &_sdcard_usermount; + vfs->base.type = &mp_fat_vfs_type; + vfs->fatfs.drv = vfs; + + // Initialise underlying block device + vfs->blockdev.block_size = FF_MIN_SS; // default, will be populated by call to MP_BLOCKDEV_IOCTL_BLOCK_SIZE + mp_vfs_blockdev_init(&vfs->blockdev, &sdmmc); + + // mount the block device so the VFS methods can be used + FRESULT res = f_mount(&vfs->fatfs); + if (res != FR_OK) { + common_hal_sdioio_sdcard_deinit(&sdmmc); + return; + } + common_hal_sdioio_sdcard_never_reset(&sdmmc); + + filesystem_set_concurrent_write_protection(vfs, true); + filesystem_set_writable_by_usb(vfs, false); + + mp_vfs_mount_t *sdcard_vfs = &_sdcard_vfs; + sdcard_vfs->str = "/sd"; + sdcard_vfs->len = 3; + sdcard_vfs->obj = MP_OBJ_FROM_PTR(&_sdcard_usermount); + sdcard_vfs->next = MP_STATE_VM(vfs_mount_table); + MP_STATE_VM(vfs_mount_table) = sdcard_vfs; +} diff --git a/ports/espressif/boards/yoto_mini_2024/board.h b/ports/espressif/boards/yoto_mini_2024/board.h new file mode 100644 index 00000000000..1e40b62b047 --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/board.h @@ -0,0 +1,3 @@ +#include "py/obj.h" + +extern void board_set(qstr key, mp_obj_t value); diff --git a/ports/espressif/boards/yoto_mini_2024/mpconfigboard.h b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.h new file mode 100644 index 00000000000..4fcc2afaae8 --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Yoto Mini 2024" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_MUTABLE_BOARD (1) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO25, .sda = &pin_GPIO21}} +#define CIRCUITPY_BOARD_I2C_SPEED (400000) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO23, .mosi = &pin_GPIO22, .miso = NULL}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/yoto_mini_2024/mpconfigboard.mk b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.mk new file mode 100644 index 00000000000..356e7015a04 --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/mpconfigboard.mk @@ -0,0 +1,14 @@ +CIRCUITPY_CREATOR_ID = 0x40100000 +CIRCUITPY_CREATION_ID = 0x00320002 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 40m + +CIRCUITPY_I2CIOEXPANDER = 1 diff --git a/ports/espressif/boards/yoto_mini_2024/pins.c b/ports/espressif/boards/yoto_mini_2024/pins.c new file mode 100644 index 00000000000..d4ff3b4863f --- /dev/null +++ b/ports/espressif/boards/yoto_mini_2024/pins.c @@ -0,0 +1,79 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT +// + +#include "board.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static mp_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_MUTABLE_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + { MP_ROM_QSTR(MP_QSTR_ENC1A), MP_OBJ_FROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_ENC1B), MP_OBJ_FROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_ENC2A), MP_OBJ_FROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_ENC2B), MP_OBJ_FROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_OBJ_FROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_OBJ_FROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY_SCK), MP_OBJ_FROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_MOSI), MP_OBJ_FROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_NFC_IN), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_NFC_OUT), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_OBJ_FROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCLK), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_OBJ_FROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER_INT), MP_OBJ_FROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_OBJ_FROM_PTR(&displays[0].display)}, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_OBJ_FROM_PTR(&board_i2c_obj) }, + + // Filled in by board_init() + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_PLUG_STATUS), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_POWER_BUTTON), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_ENC1_BUTTON), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_ENC2_BUTTON), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_HEADPHONE_DETECT), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_PACTRL), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_DC), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_RESET), mp_const_none }, + + { MP_ROM_QSTR(MP_QSTR_LEVEL_CONVERTER), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_LEVEL_POWER_ENABLE), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_LEVEL_VINHOLD), mp_const_none }, + + { MP_ROM_QSTR(MP_QSTR_TILT), mp_const_none }, + + // Only on some variants + { MP_ROM_QSTR(MP_QSTR_RTC_INT), mp_const_none }, + +}; +MP_DEFINE_MUTABLE_DICT(board_module_globals, board_module_globals_table); + +void board_set(qstr q, mp_obj_t value) { + mp_obj_t key = MP_OBJ_NEW_QSTR(q); + for (size_t i = 0; i < MP_ARRAY_SIZE(board_module_globals_table); i++) { + if (board_module_globals_table[i].key == key) { + board_module_globals_table[i].value = value; + return; + } + } +} diff --git a/ports/espressif/boards/yoto_mini_2024/sdkconfig b/ports/espressif/boards/yoto_mini_2024/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/boards/yoto_player_v3/board.c b/ports/espressif/boards/yoto_player_v3/board.c new file mode 100644 index 00000000000..fd6ee40b9f3 --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/board.c @@ -0,0 +1,148 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "board.h" + +#include "supervisor/board.h" + +#include "extmod/vfs_fat.h" + +#include "py/mpstate.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-bindings/sdioio/SDCard.h" + +#include "supervisor/filesystem.h" + +static sdioio_sdcard_obj_t sdmmc; +static mp_vfs_mount_t _sdcard_vfs; +static fs_user_mount_t _sdcard_usermount; +static i2cioexpander_ioexpander_obj_t ioexpander0; // First chip (p0/p1) +static i2cioexpander_ioexpander_obj_t ioexpander1; // Second chip (p2/p3) + +void board_init(void) { + // Wait for everything to start + mp_hal_delay_ms(300); + + // Initialize the board's peripherals here. + busio_i2c_obj_t *i2c = MP_OBJ_TO_PTR(common_hal_board_create_i2c(0)); + + // Initialize the IOExpanders + // V3/V3-E uses two PI4IOE5V6416 chips (16 pins each) + // First chip (0x20): p0 (pins 0-7), p1 (pins 8-15) + ioexpander0.base.type = &i2cioexpander_ioexpander_type; + common_hal_i2cioexpander_ioexpander_construct( + &ioexpander0, + MP_OBJ_FROM_PTR(i2c), + 0x20, // I2C address for first chip + 16, // Number of pins + 2, // Output register + 0, // Input register + 6); // Direction register + + // Second chip (0x21): p2 (pins 0-7), p3 (pins 8-15) + ioexpander1.base.type = &i2cioexpander_ioexpander_type; + common_hal_i2cioexpander_ioexpander_construct( + &ioexpander1, + MP_OBJ_FROM_PTR(i2c), + 0x21, // I2C address for second chip + 16, // Number of pins + 2, // Output register + 0, // Input register + 6); // Direction register + + board_set(MP_QSTR_IOEXPANDER0, MP_OBJ_FROM_PTR(&ioexpander0)); + board_set(MP_QSTR_IOEXPANDER1, MP_OBJ_FROM_PTR(&ioexpander1)); + + // Battery and charging (from first chip - p0/p1) + board_set(MP_QSTR_BATTERY_ALERT, ioexpander0.pins->items[6]); // IOX.0.6 + board_set(MP_QSTR_QI_STATUS, ioexpander0.pins->items[7]); // IOX.0.7 + board_set(MP_QSTR_QI_I2C_INT, ioexpander0.pins->items[0]); // IOX.0.0 + board_set(MP_QSTR_USB_STATUS, ioexpander0.pins->items[8 + 0]); // IOX.1.0 + board_set(MP_QSTR_CHARGE_STATUS, ioexpander0.pins->items[8 + 4]); // IOX.1.4 + + // Buttons (from first chip - p0/p1) + board_set(MP_QSTR_POWER_BUTTON, ioexpander0.pins->items[8 + 3]); // IOX.1.3 + board_set(MP_QSTR_ENC1_BUTTON, ioexpander0.pins->items[5]); // IOX.0.5 + board_set(MP_QSTR_ENC2_BUTTON, ioexpander0.pins->items[4]); // IOX.0.4 + + // Audio (from first chip - p0/p1 and second chip - p2/p3) + board_set(MP_QSTR_HEADPHONE_DETECT, ioexpander0.pins->items[8 + 1]); // IOX.1.1 + board_set(MP_QSTR_PACTRL, ioexpander1.pins->items[4]); // IOX.2.4 + + // Display - V3/V3-E uses ht16d35x with 4 CS lines (from second chip - p2) + board_set(MP_QSTR_DISPLAY_CS0, ioexpander1.pins->items[0]); // IOX.2.0 + board_set(MP_QSTR_DISPLAY_CS1, ioexpander1.pins->items[1]); // IOX.2.1 + board_set(MP_QSTR_DISPLAY_CS2, ioexpander1.pins->items[2]); // IOX.2.2 + board_set(MP_QSTR_DISPLAY_CS3, ioexpander1.pins->items[3]); // IOX.2.3 + + // Power control (from second chip - p2/p3) + board_set(MP_QSTR_LEVEL_CONVERTER, ioexpander1.pins->items[8 + 0]); // IOX.3.0 + board_set(MP_QSTR_LEVEL_POWER_ENABLE, ioexpander1.pins->items[5]); // IOX.2.5 + board_set(MP_QSTR_LEVEL_VINHOLD, ioexpander1.pins->items[8 + 1]); // IOX.3.1 + board_set(MP_QSTR_LEVEL_VOUTEN, ioexpander1.pins->items[8 + 3]); // IOX.3.3 + + // Sensors (from first chip - p0/p1) + board_set(MP_QSTR_TILT, ioexpander0.pins->items[8 + 2]); // IOX.1.2 + board_set(MP_QSTR_RTC_INT, ioexpander0.pins->items[1]); // IOX.0.1 + + // Qi charging control (V3-E, from second chip - p2/p3) + board_set(MP_QSTR_QI_CHARGE_ENABLE, ioexpander1.pins->items[6]); // IOX.2.6 + board_set(MP_QSTR_USB_CHARGE_ENABLE, ioexpander1.pins->items[7]); // IOX.2.7 + board_set(MP_QSTR_QI_ENABLE_5W, ioexpander1.pins->items[8 + 5]); // IOX.3.5 + + // Output pin 3 high. Not clear why. + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander0.pins->items[3]), true, DRIVE_MODE_PUSH_PULL); + + // Initialize output pins + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[0]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS0 (IOX.2.0) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[1]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS1 (IOX.2.1) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[2]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS2 (IOX.2.2) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[3]), true, DRIVE_MODE_PUSH_PULL); // DISPLAY_CS3 (IOX.2.3) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[4]), true, DRIVE_MODE_PUSH_PULL); // PACTRL (IOX.2.4) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[5]), false, DRIVE_MODE_PUSH_PULL); // LEVEL_POWER_ENABLE (IOX.2.5) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[6]), true, DRIVE_MODE_PUSH_PULL); // QI_CHARGE_ENABLE + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[7]), false, DRIVE_MODE_PUSH_PULL); // USB_CHARGE_ENABLE + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 0]), true, DRIVE_MODE_PUSH_PULL); // LEVEL_CONVERTER (IOX.3.0) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 1]), true, DRIVE_MODE_PUSH_PULL); // VINHOLD (IOX.3.1) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 3]), true, DRIVE_MODE_PUSH_PULL); // VOUTEN (IOX.3.3) + common_hal_i2cioexpander_iopin_switch_to_output(MP_OBJ_TO_PTR(ioexpander1.pins->items[8 + 5]), false, DRIVE_MODE_PUSH_PULL); // QI_ENABLE_5W (IOX.3.5) + + // Initialize SD card + // V3/V3-E uses single-line SD (sd1 mode), not 4-line (sd4 mode) like Mini + sdmmc.base.type = &sdioio_SDCard_type; + const mcu_pin_obj_t *data_pins[1] = {MP_ROM_PTR(&pin_GPIO2)}; + common_hal_sdioio_sdcard_construct(&sdmmc, MP_ROM_PTR(&pin_GPIO14), MP_ROM_PTR(&pin_GPIO15), 1, data_pins, 25 * 1000000); + + fs_user_mount_t *vfs = &_sdcard_usermount; + vfs->base.type = &mp_fat_vfs_type; + vfs->fatfs.drv = vfs; + + // Initialise underlying block device + vfs->blockdev.block_size = FF_MIN_SS; // default, will be populated by call to MP_BLOCKDEV_IOCTL_BLOCK_SIZE + mp_vfs_blockdev_init(&vfs->blockdev, &sdmmc); + + // mount the block device so the VFS methods can be used + FRESULT res = f_mount(&vfs->fatfs); + if (res != FR_OK) { + common_hal_sdioio_sdcard_deinit(&sdmmc); + return; + } + common_hal_sdioio_sdcard_never_reset(&sdmmc); + + filesystem_set_concurrent_write_protection(vfs, true); + filesystem_set_writable_by_usb(vfs, false); + + mp_vfs_mount_t *sdcard_vfs = &_sdcard_vfs; + sdcard_vfs->str = "/sd"; + sdcard_vfs->len = 3; + sdcard_vfs->obj = MP_OBJ_FROM_PTR(&_sdcard_usermount); + sdcard_vfs->next = MP_STATE_VM(vfs_mount_table); + MP_STATE_VM(vfs_mount_table) = sdcard_vfs; +} diff --git a/ports/espressif/boards/yoto_player_v3/board.h b/ports/espressif/boards/yoto_player_v3/board.h new file mode 100644 index 00000000000..1e40b62b047 --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/board.h @@ -0,0 +1,3 @@ +#include "py/obj.h" + +extern void board_set(qstr key, mp_obj_t value); diff --git a/ports/espressif/boards/yoto_player_v3/mpconfigboard.h b/ports/espressif/boards/yoto_player_v3/mpconfigboard.h new file mode 100644 index 00000000000..1660c4881f9 --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/mpconfigboard.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Yoto Player V3" +#define MICROPY_HW_MCU_NAME "ESP32" + +#define CIRCUITPY_MUTABLE_BOARD (1) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO25, .sda = &pin_GPIO21}} +#define CIRCUITPY_BOARD_I2C_SPEED (400000) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO23, .mosi = &pin_GPIO22, .miso = &pin_GPIO26}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO17, .rx = &pin_GPIO16}} + +// UART pins attached to the USB-serial converter chip +#define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO1) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO3) diff --git a/ports/espressif/boards/yoto_player_v3/mpconfigboard.mk b/ports/espressif/boards/yoto_player_v3/mpconfigboard.mk new file mode 100644 index 00000000000..a1b940316c4 --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/mpconfigboard.mk @@ -0,0 +1,14 @@ +CIRCUITPY_CREATOR_ID = 0x40100000 +CIRCUITPY_CREATION_ID = 0x00320001 + +IDF_TARGET = esp32 + +CIRCUITPY_ESP_FLASH_MODE = qio +CIRCUITPY_ESP_FLASH_FREQ = 80m +CIRCUITPY_ESP_FLASH_SIZE = 8MB + +CIRCUITPY_ESP_PSRAM_SIZE = 8MB +CIRCUITPY_ESP_PSRAM_MODE = qio +CIRCUITPY_ESP_PSRAM_FREQ = 40m + +CIRCUITPY_I2CIOEXPANDER = 1 diff --git a/ports/espressif/boards/yoto_player_v3/pins.c b/ports/espressif/boards/yoto_player_v3/pins.c new file mode 100644 index 00000000000..0862a020fdf --- /dev/null +++ b/ports/espressif/boards/yoto_player_v3/pins.c @@ -0,0 +1,104 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT +// + +#include "board.h" + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static mp_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_MUTABLE_BOARD_DICT_STANDARD_ITEMS + + // External pins are in silkscreen order, from top to bottom, left side, then right side + // Encoder 1: V3-E uses GPIO26/13, V3 uses GPIO35/13 + { MP_ROM_QSTR(MP_QSTR_ENC1A), MP_OBJ_FROM_PTR(&pin_GPIO26) }, // V3-E: GPIO26, V3: GPIO35 + { MP_ROM_QSTR(MP_QSTR_ENC1A_V3), MP_OBJ_FROM_PTR(&pin_GPIO35) }, // V3-E: GPIO26, V3: GPIO35 + { MP_ROM_QSTR(MP_QSTR_ENC1B), MP_OBJ_FROM_PTR(&pin_GPIO13) }, + + // Encoder 2: Both V3 and V3-E use GPIO27/4 + { MP_ROM_QSTR(MP_QSTR_ENC2A), MP_OBJ_FROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_ENC2B), MP_OBJ_FROM_PTR(&pin_GPIO4) }, + + // Light sensor (V3/V3-E) + { MP_ROM_QSTR(MP_QSTR_LIGHT_SENSOR), MP_OBJ_FROM_PTR(&pin_GPIO36) }, + + // Temperature sensors (V3/V3-E) + { MP_ROM_QSTR(MP_QSTR_TEMP_SENSOR), MP_OBJ_FROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_QI_RX_TEMP_SENSOR), MP_OBJ_FROM_PTR(&pin_GPIO35) }, // V3-E only + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_OBJ_FROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_OBJ_FROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY_SCK), MP_OBJ_FROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_OBJ_FROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_MOSI), MP_OBJ_FROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_OBJ_FROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_MISO), MP_OBJ_FROM_PTR(&pin_GPIO26) }, // V3/V3-E have MISO + { MP_ROM_QSTR(MP_QSTR_MISO), MP_OBJ_FROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_NFC_IN), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_OBJ_FROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_NFC_OUT), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_OBJ_FROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_OBJ_FROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_OBJ_FROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WORD_SELECT), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCLK), MP_OBJ_FROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_OBJ_FROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER_INT), MP_OBJ_FROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_OBJ_FROM_PTR(&board_i2c_obj) }, + + // Filled in by board_init() + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER0), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_IOEXPANDER1), mp_const_none }, + { MP_ROM_QSTR(MP_QSTR_BATTERY_ALERT), mp_const_none }, // IOX.0.6 + { MP_ROM_QSTR(MP_QSTR_QI_STATUS), mp_const_none }, // IOX.0.7 + { MP_ROM_QSTR(MP_QSTR_USB_STATUS), mp_const_none }, // IOX.1.0 + { MP_ROM_QSTR(MP_QSTR_CHARGE_STATUS), mp_const_none }, // IOX.1.4 + { MP_ROM_QSTR(MP_QSTR_POWER_BUTTON), mp_const_none }, // IOX.1.3 + { MP_ROM_QSTR(MP_QSTR_ENC1_BUTTON), mp_const_none }, // IOX.0.5 + { MP_ROM_QSTR(MP_QSTR_ENC2_BUTTON), mp_const_none }, // IOX.0.4 + { MP_ROM_QSTR(MP_QSTR_HEADPHONE_DETECT), mp_const_none }, // IOX.1.1 + { MP_ROM_QSTR(MP_QSTR_PACTRL), mp_const_none }, // IOX.2.4 + // V3/V3-E use ht16d35x display with 4 CS lines + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS0), mp_const_none }, // IOX.2.0 + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS1), mp_const_none }, // IOX.2.1 + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS2), mp_const_none }, // IOX.2.2 + { MP_ROM_QSTR(MP_QSTR_DISPLAY_CS3), mp_const_none }, // IOX.2.3 + + { MP_ROM_QSTR(MP_QSTR_LEVEL_CONVERTER), mp_const_none }, // IOX.3.0 + { MP_ROM_QSTR(MP_QSTR_LEVEL_POWER_ENABLE), mp_const_none }, // IOX.2.5 + { MP_ROM_QSTR(MP_QSTR_LEVEL_VINHOLD), mp_const_none }, // IOX.3.1 + { MP_ROM_QSTR(MP_QSTR_LEVEL_VOUTEN), mp_const_none }, // IOX.3.3 + + { MP_ROM_QSTR(MP_QSTR_TILT), mp_const_none }, // IOX.1.2 + { MP_ROM_QSTR(MP_QSTR_RTC_INT), mp_const_none }, // IOX.0.1 + + // Qi charging pins (V3-E) + { MP_ROM_QSTR(MP_QSTR_QI_CHARGE_ENABLE), mp_const_none }, // IOX.2.6 + { MP_ROM_QSTR(MP_QSTR_QI_ENABLE_5W), mp_const_none }, // IOX.3.5 + { MP_ROM_QSTR(MP_QSTR_QI_I2C_INT), mp_const_none }, // IOX.0.0 + + // USB-C charging pins (V3/V3-E) + { MP_ROM_QSTR(MP_QSTR_USB_CHARGE_ENABLE), mp_const_none }, // IOX.2.7 + +}; +MP_DEFINE_MUTABLE_DICT(board_module_globals, board_module_globals_table); + +void board_set(qstr q, mp_obj_t value) { + mp_obj_t key = MP_OBJ_NEW_QSTR(q); + for (size_t i = 0; i < MP_ARRAY_SIZE(board_module_globals_table); i++) { + if (board_module_globals_table[i].key == key) { + board_module_globals_table[i].value = value; + return; + } + } +} diff --git a/ports/espressif/boards/yoto_player_v3/sdkconfig b/ports/espressif/boards/yoto_player_v3/sdkconfig new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/common-hal/_bleio/Adapter.c b/ports/espressif/common-hal/_bleio/Adapter.c index f604e02c200..4feb6b2b96b 100644 --- a/ports/espressif/common-hal/_bleio/Adapter.c +++ b/ports/espressif/common-hal/_bleio/Adapter.c @@ -44,8 +44,8 @@ #include "esp_nimble_hci.h" #include "nvs_flash.h" -#if CIRCUITPY_OS_GETENV -#include "shared-module/os/__init__.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" #endif // Status variables used while busy-waiting for events. @@ -61,7 +61,7 @@ static void nimble_host_task(void *param) { static void _on_sync(void) { - int rc = ble_hs_util_ensure_addr(false); + int rc __attribute__((unused)) = ble_hs_util_ensure_addr(false); assert(rc == 0); _nimble_sync = true; @@ -105,10 +105,10 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable ble_svc_gatt_init(); ble_svc_ans_init(); - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_SETTINGS_TOML char ble_name[1 + MYNEWT_VAL_BLE_SVC_GAP_DEVICE_NAME_MAX_LENGTH]; - os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name)); - if (result == GETENV_OK) { + settings_err_t result = settings_get_str("CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name)); + if (result == SETTINGS_OK) { ble_svc_gap_device_name_set(ble_name); } else #endif @@ -384,7 +384,7 @@ static int _connect_event(struct ble_gap_event *event, void *self_in) { // connection and need a new tuple. self->connection_objs = NULL; } else { - // The loop waiting for the connection to be comnpleted will stop when _connection_status changes. + // The loop waiting for the connection to be completed will stop when _connection_status changes. _connection_status = -event->connect.status; } break; @@ -561,10 +561,6 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, bool high_duty_directed = directed_to != NULL && interval <= 3.5 && timeout <= 1; // Really 1.3, but it's an int uint32_t timeout_ms = timeout * 1000; - if (timeout_ms == 0) { - timeout_ms = BLE_HS_FOREVER; - } - #if MYNEWT_VAL(BLE_EXT_ADV) bool extended = advertising_data_len > BLE_ADV_LEGACY_DATA_MAX_LEN || @@ -626,8 +622,12 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, } } + // If timeout_ms is zero, it means advertise forever. This is different than ble_gap_adv_start(). rc = ble_gap_ext_adv_start(0, timeout_ms, 0); + #else + // Extended advertising not enabled. + uint8_t conn_mode = connectable ? BLE_GAP_CONN_MODE_UND : BLE_GAP_CONN_MODE_NON; if (directed_to != NULL) { conn_mode = BLE_GAP_CONN_MODE_DIR; @@ -654,8 +654,10 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, return rc; } } - rc = ble_gap_adv_start(own_addr_type, directed_to != NULL ? &peer: NULL, - timeout_ms, + // If timeout_ms is BLE_HS_FOREVER, it means advertise forever. This is different than ble_gap_ext_adv_start(). + rc = ble_gap_adv_start(own_addr_type, + directed_to != NULL ? &peer: NULL, + timeout_ms == 0 ? BLE_HS_FOREVER : timeout_ms, &adv_params, _advertising_event, self); #endif @@ -733,13 +735,13 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) { } bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self) { - return ble_gap_adv_active(); + return common_hal_bleio_adapter_get_enabled(self) && ble_gap_adv_active(); } bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { bleio_connection_internal_t *connection = &bleio_connections[i]; - if (connection->conn_handle != BLEIO_HANDLE_INVALID && connection->mtu != 0) { + if (connection->conn_handle != BLEIO_HANDLE_INVALID) { return true; } } @@ -754,7 +756,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) { mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT]; for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { bleio_connection_internal_t *connection = &bleio_connections[i]; - if (connection->conn_handle != BLEIO_HANDLE_INVALID && connection->mtu != 0) { + if (connection->conn_handle != BLEIO_HANDLE_INVALID) { if (connection->connection_obj == mp_const_none) { connection->connection_obj = bleio_connection_new_from_internal(connection); } @@ -817,10 +819,11 @@ void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) { } void bleio_adapter_reset(bleio_adapter_obj_t *adapter) { - common_hal_bleio_adapter_stop_scan(adapter); - if (common_hal_bleio_adapter_get_advertising(adapter)) { - common_hal_bleio_adapter_stop_advertising(adapter); + if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { + return; } + common_hal_bleio_adapter_stop_scan(adapter); + common_hal_bleio_adapter_stop_advertising(adapter); adapter->connection_objs = NULL; for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { diff --git a/ports/espressif/common-hal/_bleio/Characteristic.c b/ports/espressif/common-hal/_bleio/Characteristic.c index 34f221ac9bf..ff9ab35c1b9 100644 --- a/ports/espressif/common-hal/_bleio/Characteristic.c +++ b/ports/espressif/common-hal/_bleio/Characteristic.c @@ -75,18 +75,24 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, self->flags |= BLE_GATT_CHR_F_WRITE_AUTHEN; } - if (gc_alloc_possible()) { - self->current_value = m_malloc(max_length); - } else { - self->current_value = port_malloc(max_length, false); - if (self->current_value == NULL) { - reset_into_safe_mode(SAFE_MODE_NO_HEAP); + // If max_length is 0, then no storage is allocated. + if (max_length > 0) { + if (gc_alloc_possible()) { + self->current_value = m_malloc_without_collect(max_length); + } else { + self->current_value = port_malloc(max_length, false); + if (self->current_value == NULL) { + reset_into_safe_mode(SAFE_MODE_NO_HEAP); + } } } self->current_value_alloc = max_length; self->current_value_len = 0; - if (initial_value_bufinfo != NULL) { + self->max_length = max_length; + self->fixed_length = fixed_length; + + if (!service->is_remote && initial_value_bufinfo != NULL) { common_hal_bleio_characteristic_set_value(self, initial_value_bufinfo); } @@ -96,9 +102,6 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, self->descriptor_list = NULL; } - self->max_length = max_length; - self->fixed_length = fixed_length; - if (service->is_remote) { // If the service is remote, we're buffering incoming notifications and indications. self->handle = handle; @@ -109,23 +112,25 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, } bool common_hal_bleio_characteristic_deinited(bleio_characteristic_obj_t *self) { - return self->current_value == NULL; + return self->handle == BLEIO_HANDLE_INVALID; } void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self) { if (common_hal_bleio_characteristic_deinited(self)) { return; } - if (self->current_value == NULL) { - return; - } + if (self->current_value != NULL) { + if (gc_ptr_on_heap(self->current_value)) { + m_free(self->current_value); + } else { + port_free(self->current_value); + } - if (gc_nbytes(self->current_value) > 0) { - m_free(self->current_value); - } else { - port_free(self->current_value); + self->current_value = NULL; } - self->current_value = NULL; + + // Used to indicate deinit. + self->handle = BLEIO_HANDLE_INVALID; } mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self) { @@ -172,7 +177,6 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, } } else { // Validate data length for local characteristics only. - // TODO: Test this once we can get servers going. if (self->fixed_length && bufinfo->len != self->max_length) { mp_raise_ValueError(MP_ERROR_TEXT("Value length != required fixed length")); } @@ -316,7 +320,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, } const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); - common_hal_bleio_check_connected(conn_handle); + bleio_check_connected(conn_handle); uint16_t cccd_value = (notify ? 1 << 0 : 0) | diff --git a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c index 8020af2873d..2f34666420b 100644 --- a/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/espressif/common-hal/_bleio/CharacteristicBuffer.c @@ -16,12 +16,19 @@ #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Connection.h" #include "shared-bindings/_bleio/CharacteristicBuffer.h" +#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/shared/tick.h" #include "common-hal/_bleio/ble_events.h" +// The ringbuf is filled from the nimble_host task, which preempts the VM task +// at arbitrary points, and ringbuf operations are not atomic, so guard them +// with interrupts disabled. + +// Runs on the nimble_host task. void bleio_characteristic_buffer_extend(bleio_characteristic_buffer_obj_t *self, const uint8_t *data, size_t len) { + common_hal_mcu_disable_interrupts(); if (self->watch_for_interrupt_char) { for (uint16_t i = 0; i < len; i++) { if (data[i] == mp_interrupt_char) { @@ -34,6 +41,7 @@ void bleio_characteristic_buffer_extend(bleio_characteristic_buffer_obj_t *self, } else { ringbuf_put_n(&self->ringbuf, data, len); } + common_hal_mcu_enable_interrupts(); } void _common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, @@ -54,7 +62,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe bleio_characteristic_obj_t *characteristic, mp_float_t timeout, size_t buffer_size) { - uint8_t *buffer = m_malloc(buffer_size); + uint8_t *buffer = m_malloc_without_collect(buffer_size); _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL, false); } @@ -70,20 +78,23 @@ uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer } } + common_hal_mcu_disable_interrupts(); uint32_t num_bytes_read = ringbuf_get_n(&self->ringbuf, data, len); + common_hal_mcu_enable_interrupts(); return num_bytes_read; } -// NOTE: The nRF port has protection around these operations because the ringbuf -// is filled from an interrupt. On ESP the ringbuf is filled from the BLE host -// task that won't interrupt us. - uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) { - return ringbuf_num_filled(&self->ringbuf); + common_hal_mcu_disable_interrupts(); + uint32_t count = ringbuf_num_filled(&self->ringbuf); + common_hal_mcu_enable_interrupts(); + return count; } void common_hal_bleio_characteristic_buffer_clear_rx_buffer(bleio_characteristic_buffer_obj_t *self) { + common_hal_mcu_disable_interrupts(); ringbuf_clear(&self->ringbuf); + common_hal_mcu_enable_interrupts(); } bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self) { diff --git a/ports/espressif/common-hal/_bleio/Connection.c b/ports/espressif/common-hal/_bleio/Connection.c index 8c88bfe3ec5..91d2336ee68 100644 --- a/ports/espressif/common-hal/_bleio/Connection.c +++ b/ports/espressif/common-hal/_bleio/Connection.c @@ -30,6 +30,9 @@ #include "common-hal/_bleio/ble_events.h" +#include "freertos/FreeRTOS.h" +#include "freertos/queue.h" + #include "host/ble_att.h" // Uncomment to turn on debug logging just in this file. @@ -65,7 +68,7 @@ int bleio_connection_event_cb(struct ble_gap_event *event, void *connection_in) case BLE_GAP_EVENT_CONN_UPDATE: { struct ble_gap_conn_desc desc; - int rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc); + int rc __attribute__((unused)) = ble_gap_conn_find(event->conn_update.conn_handle, &desc); assert(rc == 0); connection->conn_params_updating = false; break; @@ -181,44 +184,148 @@ void common_hal_bleio_connection_set_connection_interval(bleio_connection_intern // Zero when discovery is in process. BLE_HS_EDONE or a BLE_HS_ error code when done. static volatile int _last_discovery_status; -static uint64_t _discovery_start_time; - -// Give 20 seconds for discovery +// Give 20 seconds for each step of discovery: services, characteristics, attributes. #define DISCOVERY_TIMEOUT_MS 20000 -static void _start_discovery_timeout(void) { - _discovery_start_time = common_hal_time_monotonic_ms(); +// Record result of last discovery step: services, characteristics, descriptors. +static void _set_discovery_step_status(int status) { + _last_discovery_status = status; } -static int _wait_for_discovery_step_done(void) { - const uint64_t timeout_time_ms = _discovery_start_time + DISCOVERY_TIMEOUT_MS; - while ((_last_discovery_status == 0) && (common_hal_time_monotonic_ms() < timeout_time_ms)) { - RUN_BACKGROUND_TASKS; - if (mp_hal_is_interrupted()) { - // Return prematurely. Then the interrupt will be raised. - _last_discovery_status = BLE_HS_EDONE; - } +static void _check_discovery_status(int status) { + #if CIRCUITPY_VERBOSE_BLE + mp_printf(&mp_plat_print, "discovery step status: %d\n", status); + #endif + + if (status == BLE_HS_EDONE) { + return; + } + if (status < BLE_HS_ERR_ATT_BASE) { + CHECK_NIMBLE_ERROR(status); + return; } - return _last_discovery_status; + CHECK_BLE_ERROR(status); } -// Record result of last discovery step: services, characteristics, descriptors. -static void _set_discovery_step_status(int status) { - _last_discovery_status = status; +// Raw discovery results are staged here by the NimBLE host-task callbacks. +// Those callbacks run on the "nimble_host" task, NOT the VM task, so they must +// not allocate from the MicroPython heap: an allocation there can trigger a +// gc_collect() that scans the wrong task's stack and frees the VM's live +// objects. Instead the callbacks copy the plain NimBLE result struct into this +// FreeRTOS queue, and the VM task drains it and builds the Python objects. +// +// Discovery is serialized (one discover_remote_services() at a time), so a +// single file-static queue suffices. It must hold one ATT-PDU burst of records: +// within a response PDU the host task invokes the callback repeatedly without +// yielding, so the VM task cannot drain until the next PDU's round-trip. The +// largest burst is a find-information response at the maximum ATT MTU we +// advertise (CONFIG_BT_NIMBLE_ATT_PREFERRED_MTU, 256): about 64 descriptor +// records. The depth is twice that. +// +// The queue is created on first use from the FreeRTOS (IDF) heap, not the GC +// heap, so it needs no GC root and survives soft reloads: a stale procedure's +// sends always land in live memory. It is never deleted. + +// One queue item, sized to the largest record type, so one queue can serve every +// discovery step. +typedef union { + struct ble_gatt_svc svc; + struct ble_gatt_chr chr; + struct ble_gatt_dsc dsc; +} discovery_record_t; + +#define DISCOVERY_QUEUE_DEPTH (128) +static QueueHandle_t _discovery_queue; + +// Create the queue on first use, and empty it before a discovery step. Runs on +// the VM task. xQueueReset() is safe against a stale procedure from a previous +// errored, timed-out, or interrupted discovery that may still be sending +// records on the nimble_host task. +static void _reset_discovery_queue(void) { + if (_discovery_queue == NULL) { + _discovery_queue = xQueueCreate(DISCOVERY_QUEUE_DEPTH, sizeof(discovery_record_t)); + if (_discovery_queue == NULL) { + m_malloc_fail(DISCOVERY_QUEUE_DEPTH * sizeof(discovery_record_t)); + } + } + xQueueReset(_discovery_queue); } static int _discovered_service_cb(uint16_t conn_handle, const struct ble_gatt_error *error, const struct ble_gatt_svc *svc, void *arg) { - bleio_connection_internal_t *self = (bleio_connection_internal_t *)arg; + if (error->status != 0) { + #if CIRCUITPY_VERBOSE_BLE + mp_printf(&mp_plat_print, "_discovered_service_cb error->status: %d, handle: %d\n", + error->status, error->att_handle); + #endif + // BLE_HS_EDONE or some error has occurred. + _set_discovery_step_status(error->status); + return 0; + } + + // Runs on the nimble_host task: stage the raw result only, never allocate. + discovery_record_t record = { .svc = *svc }; + if (xQueueSend(_discovery_queue, &record, 0) != pdTRUE) { + _set_discovery_step_status(BLE_HS_ENOMEM); + } + return 0; +} + +static int _discovered_characteristic_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + const struct ble_gatt_chr *chr, + void *arg) { + if (error->status != 0) { + #if CIRCUITPY_VERBOSE_BLE + mp_printf(&mp_plat_print, "_discovered_characteristic_cb error->status: %d, handle: %d\n", + error->status, error->att_handle); + #endif + + // BLE_HS_EDONE or some error has occurred. + _set_discovery_step_status(error->status); + return 0; + } + + // Runs on the nimble_host task: stage the raw result only, never allocate. + discovery_record_t record = { .chr = *chr }; + if (xQueueSend(_discovery_queue, &record, 0) != pdTRUE) { + _set_discovery_step_status(BLE_HS_ENOMEM); + } + return 0; +} + +static int _discovered_descriptor_cb(uint16_t conn_handle, + const struct ble_gatt_error *error, + uint16_t chr_val_handle, + const struct ble_gatt_dsc *dsc, + void *arg) { if (error->status != 0) { + #if CIRCUITPY_VERBOSE_BLE + mp_printf(&mp_plat_print, "_discovered_descriptor_cb error->status: %d, handle: %d\n", + error->status, error->att_handle); + #endif + // BLE_HS_EDONE or some error has occurred. _set_discovery_step_status(error->status); return 0; } + // Runs on the nimble_host task: stage the raw result only, never allocate. + discovery_record_t record = { .dsc = *dsc }; + if (xQueueSend(_discovery_queue, &record, 0) != pdTRUE) { + _set_discovery_step_status(BLE_HS_ENOMEM); + } + return 0; +} + +// Build a Service object from a staged raw record. Runs on the VM task. +static void _build_service(void *ctx, const void *record) { + bleio_connection_internal_t *self = ctx; + const struct ble_gatt_svc *svc = record; + bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); // Initialize several fields at once. @@ -236,27 +343,53 @@ static int _discovered_service_cb(uint16_t conn_handle, mp_obj_list_append(MP_OBJ_FROM_PTR(self->remote_service_list), MP_OBJ_FROM_PTR(service)); - return 0; } -static int _discovered_characteristic_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - const struct ble_gatt_chr *chr, - void *arg) { - bleio_service_obj_t *service = (bleio_service_obj_t *)arg; - - if (error->status != 0) { - // BLE_HS_EDONE or some error has occurred. - _set_discovery_step_status(error->status); - return 0; +// Drain and build all staged records on the VM task, until the step completes +// and the queue is empty. build() is invoked for each raw record with ctx +// passed through. Returns the discovery step status. +static int _drain_records(void *ctx, + void (*build)(void *ctx, const void *record)) { + const uint64_t timeout_time_ms = common_hal_time_monotonic_ms() + DISCOVERY_TIMEOUT_MS; + discovery_record_t record; + while (true) { + if (xQueueReceive(_discovery_queue, &record, 0) == pdTRUE) { + build(ctx, &record); + continue; + } + // Queue is empty. + if (_last_discovery_status != 0) { + // On EDONE or a NimBLE error, the terminal callback has already + // run, so no more records will arrive: drain any that raced in, + // then stop. On ENOMEM (our own send failure) the procedure may + // still be running, but we are raising anyway; any later + // discovery resets the queue before reuse. + while (xQueueReceive(_discovery_queue, &record, 0) == pdTRUE) { + build(ctx, &record); + } + return _last_discovery_status; + } + if (common_hal_time_monotonic_ms() >= timeout_time_ms) { + return BLE_HS_ETIMEOUT; + } + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + // Return prematurely. Then the interrupt will be raised. + _set_discovery_step_status(BLE_HS_EDONE); + } } +} + +// Build a Characteristic object from a staged raw record. Runs on the VM task. +static void _build_characteristic(void *ctx, const void *record) { + bleio_service_obj_t *service = ctx; + const struct ble_gatt_chr *chr = record; bleio_characteristic_obj_t *characteristic = mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); // Known characteristic UUID. bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); - uuid->nimble_ble_uuid = chr->uuid; bleio_characteristic_properties_t props = @@ -281,32 +414,17 @@ static int _discovered_characteristic_cb(uint16_t conn_handle, characteristic->def_handle = chr->def_handle; #if CIRCUITPY_VERBOSE_BLE - mp_printf(&mp_plat_print, "_discovered_characteristic_cb: char handle: %d\n", characteristic->handle); + mp_printf(&mp_plat_print, "_build_characteristic: char handle: %d\n", characteristic->handle); #endif mp_obj_list_append(MP_OBJ_FROM_PTR(service->characteristic_list), MP_OBJ_FROM_PTR(characteristic)); - return 0; } -static int _discovered_descriptor_cb(uint16_t conn_handle, - const struct ble_gatt_error *error, - uint16_t chr_val_handle, - const struct ble_gatt_dsc *dsc, - void *arg) { - bleio_characteristic_obj_t *characteristic = (bleio_characteristic_obj_t *)arg; - - if (error->status != 0) { - - #if CIRCUITPY_VERBOSE_BLE - mp_printf(&mp_plat_print, "_discovered_descriptor_cb error->status: %d, handle: %d\n", - error->status, error->att_handle); - #endif - - // BLE_HS_EDONE or some error has occurred. - _set_discovery_step_status(error->status); - return 0; - } +// Build a Descriptor object from a staged raw record. Runs on the VM task. +static void _build_descriptor(void *ctx, const void *record) { + bleio_characteristic_obj_t *characteristic = ctx; + const struct ble_gatt_dsc *dsc = record; // Remember handles for certain well-known descriptors. switch (dsc->uuid.u16.value) { @@ -337,33 +455,28 @@ static int _discovered_descriptor_cb(uint16_t conn_handle, descriptor->handle = dsc->handle; #if CIRCUITPY_VERBOSE_BLE - mp_printf(&mp_plat_print, "_discovered_descriptor_cb: char handle: %d, desc handle: %d, uuid type: %d, u16 value: 0x%x\n", + mp_printf(&mp_plat_print, "_build_descriptor: char handle: %d, desc handle: %d, uuid type: %d, u16 value: 0x%x\n", characteristic->handle, descriptor->handle, dsc->uuid.u.type, dsc->uuid.u16.value); #endif mp_obj_list_append(MP_OBJ_FROM_PTR(characteristic->descriptor_list), MP_OBJ_FROM_PTR(descriptor)); - return 0; } static void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t service_uuids_whitelist) { // Start over with an empty list. self->remote_service_list = mp_obj_new_list(0, NULL); - // Start timeout in case discovery gets stuck. - _start_discovery_timeout(); - if (service_uuids_whitelist == mp_const_none) { - // Reset discovery status before starting callbacks + // Reset discovery status and staging queue before starting callbacks. _set_discovery_step_status(0); + _reset_discovery_queue(); CHECK_NIMBLE_ERROR(ble_gattc_disc_all_svcs(self->conn_handle, _discovered_service_cb, self)); - // Wait for _discovered_service_cb() to be called multiple times until it's done. - int status = _wait_for_discovery_step_done(); - if (status != BLE_HS_EDONE) { - CHECK_BLE_ERROR(status); - } + // Drain staged services and build them on the VM task until done. + int status = _drain_records(self, _build_service); + _check_discovery_status(status); } else { mp_obj_iter_buf_t iter_buf; mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); @@ -374,27 +487,26 @@ static void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t } bleio_uuid_obj_t *uuid = MP_OBJ_TO_PTR(uuid_obj); - // Reset discovery status before starting callbacks + // Reset discovery status and staging queue before starting callbacks. _set_discovery_step_status(0); + _reset_discovery_queue(); CHECK_NIMBLE_ERROR(ble_gattc_disc_svc_by_uuid(self->conn_handle, &uuid->nimble_ble_uuid.u, _discovered_service_cb, self)); - // Wait for _discovered_service_cb() to be called multiple times until it's done. - int status = _wait_for_discovery_step_done(); - if (status != BLE_HS_EDONE) { - CHECK_BLE_ERROR(status); - } + // Drain staged services and build them on the VM task until done. + int status = _drain_records(self, _build_service); + _check_discovery_status(status); } } // Now discover characteristics for each discovered service. - for (size_t i = 0; i < self->remote_service_list->len; i++) { bleio_service_obj_t *service = MP_OBJ_TO_PTR(self->remote_service_list->items[i]); - // Reset discovery status before starting callbacks + // Reset discovery status and staging queue before starting callbacks. _set_discovery_step_status(0); + _reset_discovery_queue(); CHECK_NIMBLE_ERROR(ble_gattc_disc_all_chrs(self->conn_handle, service->start_handle, @@ -402,11 +514,9 @@ static void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t _discovered_characteristic_cb, service)); - // Wait for _discovered_characteristic_cb() to be called multiple times until it's done. - int status = _wait_for_discovery_step_done(); - if (status != BLE_HS_EDONE) { - CHECK_BLE_ERROR(status); - } + // Drain staged characteristics and build them on the VM task until done. + int status = _drain_records(service, _build_characteristic); + _check_discovery_status(status); // Got characteristics for this service. Now discover descriptors for each characteristic. size_t char_list_len = service->characteristic_list->len; @@ -423,15 +533,16 @@ static void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t uint16_t end_handle = next_characteristic == NULL ? service->end_handle - : next_characteristic->handle - 1; + : next_characteristic->def_handle - 1; // Pre-check if there are no descriptors to discover so descriptor discovery doesn't fail if (end_handle <= characteristic->handle) { continue; } - // Reset discovery status before starting callbacks + // Reset discovery status and staging queue before starting callbacks. _set_discovery_step_status(0); + _reset_discovery_queue(); // The descriptor handle inclusive range is [characteristic->handle + 1, end_handle], // but ble_gattc_disc_all_dscs() requires starting with characteristic->handle. @@ -439,11 +550,9 @@ static void discover_remote_services(bleio_connection_internal_t *self, mp_obj_t end_handle, _discovered_descriptor_cb, characteristic)); - // Wait for _discovered_descriptor_cb to be called multiple times until it's done. - status = _wait_for_discovery_step_done(); - if (status != BLE_HS_EDONE) { - CHECK_BLE_ERROR(status); - } + // Drain staged descriptors and build them on the VM task until done. + status = _drain_records(characteristic, _build_descriptor); + _check_discovery_status(status); } } } diff --git a/ports/espressif/common-hal/_bleio/Connection.h b/ports/espressif/common-hal/_bleio/Connection.h index 326eca02ecd..5f33eb43b5d 100644 --- a/ports/espressif/common-hal/_bleio/Connection.h +++ b/ports/espressif/common-hal/_bleio/Connection.h @@ -64,6 +64,7 @@ void bleio_connection_clear(bleio_connection_internal_t *self); int bleio_connection_event_cb(struct ble_gap_event *event, void *connection_in); +void bleio_check_connected(uint16_t conn_handle); uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self); mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *connection); bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle); diff --git a/ports/espressif/common-hal/_bleio/PacketBuffer.c b/ports/espressif/common-hal/_bleio/PacketBuffer.c index a6cbdc53069..a14c627f110 100644 --- a/ports/espressif/common-hal/_bleio/PacketBuffer.c +++ b/ports/espressif/common-hal/_bleio/PacketBuffer.c @@ -15,6 +15,7 @@ #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Connection.h" #include "shared-bindings/_bleio/PacketBuffer.h" +#include "shared-bindings/microcontroller/__init__.h" #include "supervisor/shared/tick.h" #include "supervisor/shared/bluetooth/serial.h" @@ -23,6 +24,11 @@ #include "host/ble_att.h" +// The ringbuf and the pending outgoing buffers are shared with the nimble_host +// task, which preempts the VM task at arbitrary points, and ringbuf operations +// are not atomic, so guard the shared accesses with interrupts disabled. + +// Runs on the nimble_host task. void bleio_packet_buffer_extend(bleio_packet_buffer_obj_t *self, uint16_t conn_handle, const uint8_t *data, size_t len) { if (self->conn_handle != conn_handle) { return; @@ -34,6 +40,8 @@ void bleio_packet_buffer_extend(bleio_packet_buffer_obj_t *self, uint16_t conn_h return; } + common_hal_mcu_disable_interrupts(); + // Make room for the new value by dropping the oldest packets first. while (ringbuf_num_empty(&self->ringbuf) < len + sizeof(uint16_t)) { uint16_t packet_length; @@ -45,6 +53,8 @@ void bleio_packet_buffer_extend(bleio_packet_buffer_obj_t *self, uint16_t conn_h } ringbuf_put_n(&self->ringbuf, (uint8_t *)&len, sizeof(uint16_t)); ringbuf_put_n(&self->ringbuf, data, len); + + common_hal_mcu_enable_interrupts(); } static int packet_buffer_on_ble_client_evt(struct ble_gap_event *event, void *param); @@ -240,17 +250,17 @@ void common_hal_bleio_packet_buffer_construct( uint32_t *incoming_buffer = NULL; if (incoming) { incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size); - incoming_buffer = m_malloc(incoming_buffer_size); + incoming_buffer = m_malloc_without_collect(incoming_buffer_size); } uint32_t *outgoing1 = NULL; uint32_t *outgoing2 = NULL; if (outgoing) { - outgoing1 = m_malloc(max_packet_size); + outgoing1 = m_malloc_without_collect(max_packet_size); // Only allocate the second buffer if we are doing writes with responses. // Without responses, we just write as quickly as we can. if (outgoing == CHAR_PROP_WRITE || outgoing == CHAR_PROP_INDICATE) { - outgoing2 = m_malloc(max_packet_size); + outgoing2 = m_malloc_without_collect(max_packet_size); } } _common_hal_bleio_packet_buffer_construct(self, characteristic, @@ -264,6 +274,8 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self return 0; } + common_hal_mcu_disable_interrupts(); + // Get packet length, which is in first two bytes of packet. uint16_t packet_length; ringbuf_get_n(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t)); @@ -282,6 +294,8 @@ mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self ret = packet_length; } + common_hal_mcu_enable_interrupts(); + return ret; } @@ -324,6 +338,10 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, c size_t num_bytes_written = 0; + // The nimble_host task may modify pending_size, pending_index, and + // packet_queued via queue_next_write(), so guard the append. + common_hal_mcu_disable_interrupts(); + uint32_t *pending = self->outgoing[self->pending_index]; if (self->pending_size == 0) { @@ -335,6 +353,8 @@ mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, c self->pending_size += len; num_bytes_written += len; + common_hal_mcu_enable_interrupts(); + // If no writes are queued then sneak in this data. if (!self->packet_queued) { // This will queue up the packet even if it can't send immediately. @@ -440,3 +460,7 @@ void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { ble_event_remove_handler(packet_buffer_on_ble_client_evt, self); ringbuf_deinit(&self->ringbuf); } + +bool common_hal_bleio_packet_buffer_connected(bleio_packet_buffer_obj_t *self) { + return !common_hal_bleio_packet_buffer_deinited(self) && self->conn_handle != BLEIO_HANDLE_INVALID; +} diff --git a/ports/espressif/common-hal/_bleio/__init__.c b/ports/espressif/common-hal/_bleio/__init__.c index 328cf7ec552..552ba0575b3 100644 --- a/ports/espressif/common-hal/_bleio/__init__.c +++ b/ports/espressif/common-hal/_bleio/__init__.c @@ -31,10 +31,13 @@ static uint64_t _timeout_start_time; background_callback_t bleio_background_callback; -void bleio_user_reset() { - // Stop any user scanning or advertising. - common_hal_bleio_adapter_stop_scan(&common_hal_bleio_adapter_obj); - common_hal_bleio_adapter_stop_advertising(&common_hal_bleio_adapter_obj); +void bleio_user_reset(void) { + if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { + return; + } + // Stop any user scanning or advertising, and stop all connections. + // TODO: Don't stop BLE workflow connection. + bleio_adapter_reset(&common_hal_bleio_adapter_obj); ble_event_remove_heap_handlers(); @@ -43,7 +46,7 @@ void bleio_user_reset() { } // Turn off BLE on a reset or reload. -void bleio_reset() { +void bleio_reset(void) { // Set this explicitly to save data. if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { return; @@ -103,6 +106,9 @@ void check_nimble_error(int rc, const char *file, size_t line) { case BLE_HS_ENOTCONN: mp_raise_ConnectionError(MP_ERROR_TEXT("Not connected")); return; + case BLE_HS_EALREADY: + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Already in progress")); + return; default: #if CIRCUITPY_VERBOSE_BLE || CIRCUITPY_DEBUG if (file) { @@ -152,7 +158,7 @@ void check_notify(BaseType_t result) { mp_raise_msg(&mp_type_TimeoutError, NULL); } -void common_hal_bleio_check_connected(uint16_t conn_handle) { +void bleio_check_connected(uint16_t conn_handle) { if (conn_handle == BLEIO_HANDLE_INVALID) { mp_raise_ConnectionError(MP_ERROR_TEXT("Not connected")); } diff --git a/ports/espressif/common-hal/_bleio/ble_events.c b/ports/espressif/common-hal/_bleio/ble_events.c index 6a616819a8b..b57362fe007 100644 --- a/ports/espressif/common-hal/_bleio/ble_events.c +++ b/ports/espressif/common-hal/_bleio/ble_events.c @@ -16,7 +16,7 @@ #include "py/mpstate.h" #include "py/runtime.h" -#if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE +#if CIRCUITPY_BLE_SERIAL_SERVICE && CIRCUITPY_VERBOSE_BLE #include "supervisor/shared/bluetooth/serial.h" #endif @@ -64,7 +64,7 @@ void ble_event_add_handler(ble_gap_event_fn *func, void *param) { } // Add a new handler to the front of the list - ble_event_handler_entry_t *handler = m_new(ble_event_handler_entry_t, 1); + ble_event_handler_entry_t *handler = m_new_obj(ble_event_handler_entry_t); ble_event_add_handler_entry(handler, func, param); } @@ -85,7 +85,7 @@ void ble_event_remove_handler(ble_gap_event_fn *func, void *param) { } int ble_event_run_handlers(struct ble_gap_event *event) { - #if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE && CIRCUITPY_VERBOSE_BLE ble_serial_disable(); #endif @@ -101,7 +101,7 @@ int ble_event_run_handlers(struct ble_gap_event *event) { done = it->func(event, it->param) || done; it = next; } - #if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE && CIRCUITPY_VERBOSE_BLE ble_serial_enable(); #endif return 0; diff --git a/ports/espressif/common-hal/alarm/SleepMemory.c b/ports/espressif/common-hal/alarm/SleepMemory.c index 938772e53ca..f2a6aaa7a95 100644 --- a/ports/espressif/common-hal/alarm/SleepMemory.c +++ b/ports/espressif/common-hal/alarm/SleepMemory.c @@ -15,14 +15,45 @@ // Data storage for singleton instance of SleepMemory. // Might be RTC_SLOW_MEM or RTC_FAST_MEM, depending on setting of CONFIG_ESP32S2_RTCDATA_IN_FAST_MEM. -static RTC_DATA_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; +#if defined(CONFIG_SOC_RTC_FAST_MEM_SUPPORTED) || defined(CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED) +static RTC_NOINIT_ATTR uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; void alarm_sleep_memory_reset(void) { - // ESP-IDF build system takes care of doing esp_sleep_pd_config() or the equivalent with - // the correct settings, depending on which RTC mem we are using. - // https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/api-reference/system/sleep_modes.html#power-down-of-rtc-peripherals-and-memories + // With RTC_NOINIT_ATTR, the bootloader does not initialize sleep memory. + // Preserve contents on resets where the RTC domain stays powered (software + // reset, watchdog, panic, deep sleep wake). Clear on everything else — + // after power-on, SRAM contents are undefined; after brown-out, the RTC + // domain was reset by hardware (System Reset scope per TRM Figure 6.1-1). + esp_reset_reason_t reason = esp_reset_reason(); + switch (reason) { + case ESP_RST_SW: // microcontroller.reset() / esp_restart() + case ESP_RST_DEEPSLEEP: // deep sleep wake + case ESP_RST_PANIC: // unhandled exception + case ESP_RST_INT_WDT: // interrupt watchdog + case ESP_RST_TASK_WDT: // task watchdog + case ESP_RST_WDT: // other watchdog + // RTC domain was not reset — sleep memory is intact. + break; + default: + // Power-on, brown-out, unknown, or any other reason where + // RTC SRAM contents may be undefined. Clear to zero. + memset(_sleep_mem, 0, sizeof(_sleep_mem)); + break; + } +} + +#else + +// Chips without RTC memory can't persist SleepMemory across deep sleep. +static uint8_t _sleep_mem[SLEEP_MEMORY_LENGTH]; + +void alarm_sleep_memory_reset(void) { + // Do nothing for chips without RTC memory. } +#endif + + uint32_t common_hal_alarm_sleep_memory_get_length(alarm_sleep_memory_obj_t *self) { return sizeof(_sleep_mem); } diff --git a/ports/espressif/common-hal/alarm/__init__.c b/ports/espressif/common-hal/alarm/__init__.c index 629f976039f..751ef121e5f 100644 --- a/ports/espressif/common-hal/alarm/__init__.c +++ b/ports/espressif/common-hal/alarm/__init__.c @@ -57,68 +57,61 @@ void alarm_reset(void) { esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL); } -static esp_sleep_wakeup_cause_t _get_wakeup_cause(bool deep_sleep) { +static uint32_t _get_wakeup_causes(bool deep_sleep) { // First check if the modules remember what last woke up if (alarm_pin_pinalarm_woke_this_cycle()) { - return ESP_SLEEP_WAKEUP_GPIO; + return 1 << ESP_SLEEP_WAKEUP_GPIO; } if (alarm_time_timealarm_woke_this_cycle()) { - return ESP_SLEEP_WAKEUP_TIMER; + return 1 << ESP_SLEEP_WAKEUP_TIMER; } #if CIRCUITPY_ALARM_TOUCH if (alarm_touch_touchalarm_woke_this_cycle()) { - return ESP_SLEEP_WAKEUP_TOUCHPAD; + return 1 << ESP_SLEEP_WAKEUP_TOUCHPAD; } #endif #if CIRCUITPY_ESPULP if (espulp_ulpalarm_woke_this_cycle()) { - return ESP_SLEEP_WAKEUP_ULP; + return 1 << ESP_SLEEP_WAKEUP_ULP; } #endif // If waking from true deep sleep, modules will have lost their state, // so check the deep wakeup cause manually if (deep_sleep) { - return esp_sleep_get_wakeup_cause(); + return esp_sleep_get_wakeup_causes(); } - return ESP_SLEEP_WAKEUP_UNDEFINED; + return 0; } bool common_hal_alarm_woken_from_sleep(void) { - return _get_wakeup_cause(false) != ESP_SLEEP_WAKEUP_UNDEFINED; + return _get_wakeup_causes(false) != 0; } mp_obj_t common_hal_alarm_record_wake_alarm(void) { // If woken from deep sleep, create a copy alarm similar to what would have // been passed in originally. Otherwise, just return none - esp_sleep_wakeup_cause_t cause = _get_wakeup_cause(true); - switch (cause) { - case ESP_SLEEP_WAKEUP_TIMER: { - return alarm_time_timealarm_record_wake_alarm(); - } + uint32_t causes = _get_wakeup_causes(true); - case ESP_SLEEP_WAKEUP_GPIO: - case ESP_SLEEP_WAKEUP_EXT0: - case ESP_SLEEP_WAKEUP_EXT1: { - return alarm_pin_pinalarm_record_wake_alarm(); - } + if (causes & (1 << ESP_SLEEP_WAKEUP_TIMER)) { + return alarm_time_timealarm_record_wake_alarm(); + } - #if CIRCUITPY_ALARM_TOUCH - case ESP_SLEEP_WAKEUP_TOUCHPAD: { - return alarm_touch_touchalarm_record_wake_alarm(); - } - #endif + if (causes & ((1 << ESP_SLEEP_WAKEUP_GPIO) | (1 << ESP_SLEEP_WAKEUP_EXT0) | (1 << ESP_SLEEP_WAKEUP_EXT1))) { + return alarm_pin_pinalarm_record_wake_alarm(); + } - #if CIRCUITPY_ESPULP - case ESP_SLEEP_WAKEUP_ULP: { - return espulp_ulpalarm_record_wake_alarm(); - } - #endif + #if CIRCUITPY_ALARM_TOUCH + if (causes & (1 << ESP_SLEEP_WAKEUP_TOUCHPAD)) { + return alarm_touch_touchalarm_record_wake_alarm(); + } + #endif - case ESP_SLEEP_WAKEUP_UNDEFINED: - default: - // Not a deep sleep reset. - break; + #if CIRCUITPY_ESPULP + if (causes & (1 << ESP_SLEEP_WAKEUP_ULP)) { + return espulp_ulpalarm_record_wake_alarm(); } + #endif + return mp_const_none; } @@ -144,32 +137,22 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj RUN_BACKGROUND_TASKS; // Detect if interrupt was alarm or ctrl-C interrupt. if (common_hal_alarm_woken_from_sleep()) { - esp_sleep_wakeup_cause_t cause = _get_wakeup_cause(false); - switch (cause) { - case ESP_SLEEP_WAKEUP_TIMER: { - wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms, alarms); - break; - } - case ESP_SLEEP_WAKEUP_GPIO: { - wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms, alarms); - break; - } - #if CIRCUITPY_ALARM_TOUCH - case ESP_SLEEP_WAKEUP_TOUCHPAD: { - wake_alarm = alarm_touch_touchalarm_find_triggered_alarm(n_alarms, alarms); - break; - } - #endif - #if CIRCUITPY_ESPULP - case ESP_SLEEP_WAKEUP_ULP: { - wake_alarm = espulp_ulpalarm_find_triggered_alarm(n_alarms, alarms); - break; - } - #endif - default: - // Should not reach this, if all light sleep types are covered correctly - break; + uint32_t causes = _get_wakeup_causes(false); + if (causes & (1 << ESP_SLEEP_WAKEUP_TIMER)) { + wake_alarm = alarm_time_timealarm_find_triggered_alarm(n_alarms, alarms); + } else if (causes & (1 << ESP_SLEEP_WAKEUP_GPIO)) { + wake_alarm = alarm_pin_pinalarm_find_triggered_alarm(n_alarms, alarms); + } + #if CIRCUITPY_ALARM_TOUCH + else if (causes & (1 << ESP_SLEEP_WAKEUP_TOUCHPAD)) { + wake_alarm = alarm_touch_touchalarm_find_triggered_alarm(n_alarms, alarms); + } + #endif + #if CIRCUITPY_ESPULP + else if (causes & (1 << ESP_SLEEP_WAKEUP_ULP)) { + wake_alarm = espulp_ulpalarm_find_triggered_alarm(n_alarms, alarms); } + #endif shared_alarm_save_wake_alarm(wake_alarm); break; } @@ -189,7 +172,7 @@ void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *ala _setup_sleep_alarms(true, n_alarms, alarms); } -void NORETURN common_hal_alarm_enter_deep_sleep(void) { +void MP_NORETURN common_hal_alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); #if CIRCUITPY_ALARM_TOUCH alarm_touch_touchalarm_prepare_for_deep_sleep(); @@ -199,7 +182,7 @@ void NORETURN common_hal_alarm_enter_deep_sleep(void) { #endif // We no longer need to remember the pin preservations, since any pin resets are all done. - clear_pin_preservations(); + common_hal_alarm_clear_pin_preservations(); // The ESP-IDF caches the deep sleep settings and applies them before sleep. // We don't need to worry about resetting them in the interim. diff --git a/ports/espressif/common-hal/alarm/pin/PinAlarm.c b/ports/espressif/common-hal/alarm/pin/PinAlarm.c index 45f676fa599..3301612356b 100644 --- a/ports/espressif/common-hal/alarm/pin/PinAlarm.c +++ b/ports/espressif/common-hal/alarm/pin/PinAlarm.c @@ -14,10 +14,12 @@ #include "esp_sleep.h" #include "hal/gpio_ll.h" +#include "driver/gpio.h" #include "esp_debug_helpers.h" #ifdef SOC_PM_SUPPORT_EXT0_WAKEUP #include "soc/rtc_cntl_reg.h" +#include "soc/rtc_io_reg.h" #endif #include "driver/rtc_io.h" @@ -100,24 +102,34 @@ mp_obj_t alarm_pin_pinalarm_find_triggered_alarm(size_t n_alarms, const mp_obj_t } mp_obj_t alarm_pin_pinalarm_record_wake_alarm(void) { - esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + uint32_t causes = esp_sleep_get_wakeup_causes(); // Pin status will persist into a fake deep sleep uint64_t pin_status = ((uint64_t)pin_63_32_status) << 32 | pin_31_0_status; size_t pin_number = 64; #ifdef SOC_PM_SUPPORT_EXT0_WAKEUP - if (cause == ESP_SLEEP_WAKEUP_EXT0) { - pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL); + if (causes & (1 << ESP_SLEEP_WAKEUP_EXT0)) { + int rtc_io_pin_number = REG_GET_FIELD(RTC_IO_EXT_WAKEUP0_REG, RTC_IO_EXT_WAKEUP0_SEL); + // Look up the GPIO equivalent pin for this RTC GPIO pin. On ESP32, the numbering + // is different for RTC_GPIO and regular GPIO, and there's no mapping table. + // The RTC and GPIO pin numbers match for all other current chips, so we could skip this + // for those chips, but it's not expensive, and maybe there will be another mismatch in the future. + for (gpio_num_t gpio_num = 0; gpio_num < SOC_GPIO_PIN_COUNT; gpio_num++) { + if (rtc_io_number_get(gpio_num) == rtc_io_pin_number) { + pin_number = gpio_num; + break; + } + } } else { #endif #ifdef SOC_PM_SUPPORT_EXT1_WAKEUP - if (cause == ESP_SLEEP_WAKEUP_EXT1) { + if (causes & (1 << ESP_SLEEP_WAKEUP_EXT1)) { pin_status = esp_sleep_get_ext1_wakeup_status(); } #endif #ifdef SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP - if (cause == ESP_SLEEP_WAKEUP_GPIO) { + if (causes & (1 << ESP_SLEEP_WAKEUP_GPIO)) { pin_status = esp_sleep_get_gpio_wakeup_status(); } #endif @@ -295,11 +307,11 @@ static esp_err_t _setup_deep_sleep(size_t low_count, size_t high_count) { return _setup_ext1(low_count, high_count); } #endif - esp_err_t result = esp_deep_sleep_enable_gpio_wakeup(low_alarms, ESP_GPIO_WAKEUP_GPIO_LOW); + esp_err_t result = esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(low_alarms, ESP_GPIO_WAKEUP_GPIO_LOW); if (result != ESP_OK) { return result; } - result = esp_deep_sleep_enable_gpio_wakeup(high_alarms, ESP_GPIO_WAKEUP_GPIO_HIGH); + result = esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(high_alarms, ESP_GPIO_WAKEUP_GPIO_HIGH); return result; } #else @@ -348,38 +360,40 @@ void alarm_pin_pinalarm_set_alarms(bool deep_sleep, size_t n_alarms, const mp_ob if (gpio_isr_register(gpio_interrupt, NULL, 0, &gpio_interrupt_handle) != ESP_OK) { mp_raise_ValueError(MP_ERROR_TEXT("Can only alarm on RTC IO from deep sleep.")); } - for (size_t i = 0; i < 64; i++) { - uint64_t mask = 1ull << i; + for (gpio_num_t pin = 0; pin < SOC_GPIO_PIN_COUNT; pin++) { + uint64_t mask = 1ULL << pin; bool high = (high_alarms & mask) != 0; bool low = (low_alarms & mask) != 0; bool pull = (pull_pins & mask) != 0; if (!(high || low)) { continue; } - if (rtc_gpio_is_valid_gpio(i)) { + if (rtc_gpio_is_valid_gpio(pin)) { #ifdef SOC_PM_SUPPORT_RTC_PERIPH_PD - rtc_gpio_deinit(i); + rtc_gpio_deinit(pin); #endif } - gpio_int_type_t interrupt_mode = GPIO_INTR_DISABLE; - gpio_pull_mode_t pull_mode = GPIO_FLOATING; + gpio_set_direction(pin, GPIO_MODE_INPUT); + if (pull) { + if (high) { + ESP_ERROR_CHECK(gpio_set_pull_mode(pin, GPIO_PULLDOWN_ONLY)); + } else { + ESP_ERROR_CHECK(gpio_set_pull_mode(pin, GPIO_PULLUP_ONLY)); + } + } else { + ESP_ERROR_CHECK(gpio_set_pull_mode(pin, GPIO_FLOATING)); + } + gpio_int_type_t intr = GPIO_INTR_DISABLE; if (high) { - interrupt_mode = GPIO_INTR_HIGH_LEVEL; - pull_mode = GPIO_PULLDOWN_ONLY; + intr = GPIO_INTR_HIGH_LEVEL; } if (low) { - interrupt_mode = GPIO_INTR_LOW_LEVEL; - pull_mode = GPIO_PULLUP_ONLY; - } - gpio_set_direction(i, GPIO_MODE_DEF_INPUT); - PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[i], PIN_FUNC_GPIO); - if (pull) { - gpio_set_pull_mode(i, pull_mode); + intr = GPIO_INTR_LOW_LEVEL; } - never_reset_pin_number(i); - // Sets interrupt type and wakeup bits. - gpio_wakeup_enable(i, interrupt_mode); - gpio_intr_enable(i); + never_reset_pin_number(pin); + gpio_wakeup_enable(pin, intr); + gpio_set_intr_type(pin, intr); + gpio_intr_enable(pin); } // Wait for any pulls to settle. mp_hal_delay_ms(50); diff --git a/ports/espressif/common-hal/alarm/touch/TouchAlarm.c b/ports/espressif/common-hal/alarm/touch/TouchAlarm.c index 5791a980d54..93756b3c2ca 100644 --- a/ports/espressif/common-hal/alarm/touch/TouchAlarm.c +++ b/ports/espressif/common-hal/alarm/touch/TouchAlarm.c @@ -17,7 +17,7 @@ static uint16_t touch_channel_mask; static volatile bool woke_up = false; void common_hal_alarm_touch_touchalarm_construct(alarm_touch_touchalarm_obj_t *self, const mcu_pin_obj_t *pin) { - if (pin->touch_channel == TOUCH_PAD_MAX) { + if (pin->touch_channel == NO_TOUCH_CHANNEL) { raise_ValueError_invalid_pin(); } claim_pin(pin); @@ -40,35 +40,28 @@ mp_obj_t alarm_touch_touchalarm_record_wake_alarm(void) { alarm->base.type = &alarm_touch_touchalarm_type; alarm->pin = NULL; - #if defined(CONFIG_IDF_TARGET_ESP32) - touch_pad_t wake_channel; - if (touch_pad_get_wakeup_status(&wake_channel) != ESP_OK) { - return alarm; - } - #else - touch_pad_t wake_channel = touch_pad_get_current_meas_channel(); - if (wake_channel == TOUCH_PAD_MAX) { - return alarm; - } - #endif - // Map the pin number back to a pin object. for (size_t i = 0; i < mcu_pin_globals.map.used; i++) { const mcu_pin_obj_t *pin_obj = MP_OBJ_TO_PTR(mcu_pin_globals.map.table[i].value); - if (pin_obj->touch_channel == wake_channel) { - alarm->pin = mcu_pin_globals.map.table[i].value; - break; + if (pin_obj->touch_channel != NO_TOUCH_CHANNEL) { + if ((touch_channel_mask & (1 << pin_obj->touch_channel)) != 0) { + alarm->pin = mcu_pin_globals.map.table[i].value; + break; + } } } return alarm; } -// This is used to wake the main CircuitPython task. -static void touch_interrupt(void *arg) { - (void)arg; +// This callback is used to wake the main CircuitPython task during light sleep. +static bool touch_active_callback(touch_sensor_handle_t sens_handle, const touch_active_event_data_t *event, void *user_ctx) { + (void)sens_handle; + (void)event; + (void)user_ctx; woke_up = true; port_wake_main_task_from_isr(); + return false; } void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alarms, const mp_obj_t *alarms) { @@ -81,7 +74,7 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar mp_raise_ValueError_varg(MP_ERROR_TEXT("Only one %q can be set in deep sleep."), MP_QSTR_TouchAlarm); } touch_alarm = MP_OBJ_TO_PTR(alarms[i]); - touch_channel_mask |= 1 << touch_alarm->pin->number; + touch_channel_mask |= 1 << touch_alarm->pin->touch_channel; // Resetting the pin will set a pull-up, which we don't want. skip_reset_once_pin_number(touch_alarm->pin->number); touch_alarm_set = true; @@ -92,47 +85,76 @@ void alarm_touch_touchalarm_set_alarm(const bool deep_sleep, const size_t n_alar return; } - // configure interrupt for pretend to deep sleep - // this will be disabled if we actually deep sleep - - // reset touch peripheral + // Reset touch peripheral and keep it from being reset again peripherals_touch_reset(); peripherals_touch_never_reset(true); - for (uint8_t i = 1; i <= 14; i++) { - if ((touch_channel_mask & 1 << i) != 0) { - touch_pad_t touch_channel = (touch_pad_t)i; - // initialize touchpad - peripherals_touch_init(touch_channel); - - // wait for touch data to reset - mp_hal_delay_ms(10); - - // configure trigger threshold - #if defined(CONFIG_IDF_TARGET_ESP32) - uint16_t touch_value; - // ESP32 touch_pad_read() returns a lower value when a pin is touched, not a higher value - // Typical values on a Feather ESP32 V2 are 600 with a short jumper untouched, - // 70 touched. - touch_pad_read(touch_channel, &touch_value); - touch_pad_set_thresh(touch_channel, touch_value / 2); - #else - uint32_t touch_value; - touch_pad_read_benchmark(touch_channel, &touch_value); - touch_pad_set_thresh(touch_channel, touch_value / 10); // 10% - #endif + // Initialize all touch channels used for alarms + for (uint8_t i = TOUCH_MIN_CHAN_ID; i <= TOUCH_MAX_CHAN_ID; i++) { + if ((touch_channel_mask & (1 << i)) != 0) { + peripherals_touch_init(i); } } - // configure touch interrupt - #if defined(CONFIG_IDF_TARGET_ESP32) - touch_pad_isr_register(touch_interrupt, NULL); - touch_pad_intr_enable(); - #else - touch_pad_timeout_set(true, TOUCH_PAD_THRESHOLD_MAX); - touch_pad_isr_register(touch_interrupt, NULL, TOUCH_PAD_INTR_MASK_ALL); - touch_pad_intr_enable(TOUCH_PAD_INTR_MASK_ACTIVE | TOUCH_PAD_INTR_MASK_INACTIVE); - #endif + // Wait for touch data to stabilize + mp_hal_delay_ms(10); + + // Now stop scanning and disable so we can reconfigure thresholds + touch_sensor_handle_t controller = peripherals_touch_get_controller(); + touch_sensor_stop_continuous_scanning(controller); + touch_sensor_disable(controller); + + // Configure thresholds based on initial readings + for (uint8_t i = TOUCH_MIN_CHAN_ID; i <= TOUCH_MAX_CHAN_ID; i++) { + if ((touch_channel_mask & (1 << i)) == 0) { + continue; + } + touch_channel_handle_t chan = peripherals_touch_get_handle(i); + + uint32_t benchmark = 0; + #if defined(SOC_TOUCH_SUPPORT_BENCHMARK) && SOC_TOUCH_SUPPORT_BENCHMARK + touch_channel_read_data(chan, TOUCH_CHAN_DATA_TYPE_BENCHMARK, &benchmark); + #else + touch_channel_read_data(chan, TOUCH_CHAN_DATA_TYPE_SMOOTH, &benchmark); + #endif + + #if SOC_TOUCH_SENSOR_VERSION == 1 + touch_channel_config_t chan_cfg = { + .abs_active_thresh = {(uint32_t)(benchmark / 2)}, + .charge_speed = TOUCH_CHARGE_SPEED_7, + .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, + .group = TOUCH_CHAN_TRIG_GROUP_BOTH, + }; + #elif SOC_TOUCH_SENSOR_VERSION == 2 + touch_channel_config_t chan_cfg = { + .active_thresh = {(uint32_t)(benchmark / 10)}, + .charge_speed = TOUCH_CHARGE_SPEED_7, + .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, + }; + #elif SOC_TOUCH_SENSOR_VERSION == 3 + // Values are similar to an ESP-IDF example: 1000, 2500, 5000. + touch_channel_config_t chan_cfg = { + .active_thresh = {(uint32_t)(benchmark / 10), (uint32_t)(benchmark / 4), (uint32_t)(benchmark / 2)}, + }; + #else + #error bad SOC_TOUCH_SENSOR_VERSION + #endif + touch_sensor_reconfig_channel(chan, &chan_cfg); + } + + // Set up filter for proper active/inactive detection + touch_sensor_filter_config_t filter_cfg = TOUCH_SENSOR_DEFAULT_FILTER_CONFIG(); + touch_sensor_config_filter(controller, &filter_cfg); + + // Register callback for light sleep wakeup + touch_event_callbacks_t callbacks = { + .on_active = touch_active_callback, + }; + touch_sensor_register_callbacks(controller, &callbacks, NULL); + + // Re-enable and start scanning + touch_sensor_enable(controller); + touch_sensor_start_continuous_scanning(controller); } void alarm_touch_touchalarm_prepare_for_deep_sleep(void) { @@ -140,45 +162,43 @@ void alarm_touch_touchalarm_prepare_for_deep_sleep(void) { return; } - touch_pad_t touch_channel = TOUCH_PAD_MAX; - for (uint8_t i = 1; i <= 14; i++) { - if ((touch_channel_mask & 1 << i) != 0) { - touch_channel = (touch_pad_t)i; + touch_sensor_handle_t controller = peripherals_touch_get_controller(); + + // Find the first alarm channel for deep sleep + int deep_slp_chan_id = -1; + for (uint8_t i = TOUCH_MIN_CHAN_ID; i <= TOUCH_MAX_CHAN_ID; i++) { + if ((touch_channel_mask & (1 << i)) != 0) { + deep_slp_chan_id = i; break; } } - // reset touch peripheral - peripherals_touch_never_reset(false); - peripherals_touch_reset(); - - // initialize touchpad - peripherals_touch_init(touch_channel); + if (deep_slp_chan_id < 0) { + return; + } - #if !defined(CONFIG_IDF_TARGET_ESP32) - // configure touchpad for sleep - touch_pad_sleep_channel_enable(touch_channel, true); - touch_pad_sleep_channel_enable_proximity(touch_channel, false); + // Stop scanning and disable to reconfigure for deep sleep + touch_sensor_stop_continuous_scanning(controller); + touch_sensor_disable(controller); + + #if SOC_TOUCH_SUPPORT_SLEEP_WAKEUP + touch_sleep_config_t sleep_cfg = { + .slp_wakeup_lvl = TOUCH_DEEP_SLEEP_WAKEUP, + #if SOC_TOUCH_SENSOR_VERSION == 1 + .deep_slp_sens_cfg = NULL, + #else + .deep_slp_allow_pd = false, + .deep_slp_chan = peripherals_touch_get_handle(deep_slp_chan_id), + .deep_slp_sens_cfg = NULL, + #endif + }; + touch_sensor_config_sleep_wakeup(controller, &sleep_cfg); #endif - // wait for touch data to reset - mp_hal_delay_ms(10); - - // configure trigger threshold - #if defined(CONFIG_IDF_TARGET_ESP32) - uint16_t touch_value; - touch_pad_read(touch_channel, &touch_value); - // ESP32 touch_pad_read() returns a lower value when a pin is touched, not a higher value - // Typical values on a Feather ESP32 V2 are 600 with a short jumper untouched, - // 70 touched. - touch_pad_set_thresh(touch_channel, touch_value / 2); - #else - uint32_t touch_value; - touch_pad_sleep_channel_read_smooth(touch_channel, &touch_value); - touch_pad_sleep_set_threshold(touch_channel, touch_value / 10); // 10% - #endif + // Re-enable for sleep + touch_sensor_enable(controller); + touch_sensor_start_continuous_scanning(controller); - // enable touchpad wakeup esp_sleep_enable_touchpad_wakeup(); esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); } diff --git a/ports/espressif/common-hal/analogbufio/BufferedIn.c b/ports/espressif/common-hal/analogbufio/BufferedIn.c index aac7ad28daf..747d7d53878 100644 --- a/ports/espressif/common-hal/analogbufio/BufferedIn.c +++ b/ports/espressif/common-hal/analogbufio/BufferedIn.c @@ -23,7 +23,7 @@ #define NUM_SAMPLES_PER_INTERRUPT 256 #define NUM_ADC_CHANNELS 1 #define DMA_BUFFER_SIZE 1024 -#define ATTENUATION ADC_ATTEN_DB_11 +#define ATTENUATION ADC_ATTEN_DB_12 #define ADC_READ_TIMEOUT_MS 2000 #define ADC_PIN_MAX_VALUE 0xfff @@ -33,7 +33,7 @@ #elif defined(CONFIG_IDF_TARGET_ESP32S2) #define ADC_RESULT_BYTE 2 #define ADC_CONV_LIMIT_EN 0 -#elif defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) +#elif defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32C61) #define ADC_RESULT_BYTE 4 #define ADC_CONV_LIMIT_EN 0 #elif defined(CONFIG_IDF_TARGET_ESP32S3) diff --git a/ports/espressif/common-hal/analogio/AnalogIn.c b/ports/espressif/common-hal/analogio/AnalogIn.c index 16340e91ac9..9809962b394 100644 --- a/ports/espressif/common-hal/analogio/AnalogIn.c +++ b/ports/espressif/common-hal/analogio/AnalogIn.c @@ -23,7 +23,7 @@ #define DEFAULT_VREF 1100 #define NO_OF_SAMPLES 2 -#define ATTENUATION ADC_ATTEN_DB_11 +#define ATTENUATION ADC_ATTEN_DB_12 #if defined(CONFIG_IDF_TARGET_ESP32) #define DATA_WIDTH ADC_BITWIDTH_12 #elif defined(CONFIG_IDF_TARGET_ESP32C2) @@ -32,6 +32,8 @@ #define DATA_WIDTH ADC_BITWIDTH_12 #elif defined(CONFIG_IDF_TARGET_ESP32C6) #define DATA_WIDTH ADC_BITWIDTH_12 +#elif defined(CONFIG_IDF_TARGET_ESP32C61) +#define DATA_WIDTH ADC_BITWIDTH_12 #elif defined(CONFIG_IDF_TARGET_ESP32P4) #define DATA_WIDTH ADC_BITWIDTH_12 #elif defined(CONFIG_IDF_TARGET_ESP32S2) @@ -86,10 +88,8 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { adc_cali_scheme_ver_t supported_schemes; adc_cali_check_scheme(&supported_schemes); - #ifndef CONFIG_IDF_TARGET_ESP32P4 adc_cali_scheme_ver_t calibration_scheme = 0; adc_cali_handle_t calibration; - #endif #if defined(ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED) && ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED adc_cali_curve_fitting_config_t config = { .unit_id = self->pin->adc_index, @@ -137,11 +137,7 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { // This corrects non-linear regions of the ADC range with a LUT, so it's a better reading than raw int voltage; - #ifdef CONFIG_IDF_TARGET_ESP32P4 - voltage = 0; - #else adc_cali_raw_to_voltage(calibration, adc_reading, &voltage); - #endif #if defined(ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED) && ADC_CALI_SCHEME_CURVE_FITTING_SUPPORTED if (calibration_scheme == ADC_CALI_SCHEME_VER_CURVE_FITTING) { diff --git a/ports/espressif/common-hal/analogio/AnalogIn.h b/ports/espressif/common-hal/analogio/AnalogIn.h index 944039bec2a..cd5f1b5d9ef 100644 --- a/ports/espressif/common-hal/analogio/AnalogIn.h +++ b/ports/espressif/common-hal/analogio/AnalogIn.h @@ -8,7 +8,7 @@ #include "common-hal/microcontroller/Pin.h" -#include "components/hal/include/hal/adc_types.h" +#include "hal/adc_types.h" #include "FreeRTOS.h" #include "freertos/semphr.h" #include "py/obj.h" diff --git a/ports/espressif/common-hal/audiobusio/I2SOut.c b/ports/espressif/common-hal/audiobusio/I2SOut.c index adfc081389a..21b4aa829b3 100644 --- a/ports/espressif/common-hal/audiobusio/I2SOut.c +++ b/ports/espressif/common-hal/audiobusio/I2SOut.c @@ -28,7 +28,11 @@ // Caller validates that pins are free. void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, - const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) { + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified, + bool external_clock) { + if (external_clock) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_external_clock); + } port_i2s_allocate_init(&self->i2s, left_justified); i2s_std_config_t i2s_config = { diff --git a/ports/espressif/common-hal/audiobusio/PDMIn.c b/ports/espressif/common-hal/audiobusio/PDMIn.c index 72d32ef2b2c..7718f096c89 100644 --- a/ports/espressif/common-hal/audiobusio/PDMIn.c +++ b/ports/espressif/common-hal/audiobusio/PDMIn.c @@ -3,3 +3,127 @@ // SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC // // SPDX-License-Identifier: MIT + + +#include "bindings/espidf/__init__.h" + +#include "common-hal/audiobusio/PDMIn.h" +#include "py/mpprint.h" +#include "py/runtime.h" +#include "shared-bindings/audiobusio/PDMIn.h" + + +#include "driver/i2s_pdm.h" + + + +#if CIRCUITPY_AUDIOBUSIO_PDMIN + + + +/** + Note: I think this function needs an additional parameter for the word select + pin. It takes `mono`, a boolean indicating if it should be mono or + stereo, but without a word select pin, I don't think one can get + the other channel. +*/ + +void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self, + const mcu_pin_obj_t *clock_pin, + const mcu_pin_obj_t *data_pin, + uint32_t sample_rate, + uint8_t bit_depth, + bool mono, + uint8_t oversample) { + + if (bit_depth != I2S_DATA_BIT_WIDTH_8BIT + && bit_depth != I2S_DATA_BIT_WIDTH_16BIT + && bit_depth != I2S_DATA_BIT_WIDTH_24BIT + && bit_depth != I2S_DATA_BIT_WIDTH_32BIT) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be 8, 16, 24, or 32"), MP_QSTR_bit_depth); + } + + i2s_chan_config_t chanConfig = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_0, I2S_ROLE_MASTER); + esp_err_t err = i2s_new_channel(&chanConfig, NULL, &self->rx_chan); + CHECK_ESP_RESULT(err); + + i2s_pdm_rx_config_t pdm_rx_cfg = { + .clk_cfg = I2S_PDM_RX_CLK_DEFAULT_CONFIG(sample_rate), + .slot_cfg = I2S_PDM_RX_SLOT_DEFAULT_CONFIG(bit_depth, mono ? I2S_SLOT_MODE_MONO : I2S_SLOT_MODE_STEREO), + .gpio_cfg = + { + .clk = clock_pin->number, + .din = data_pin->number, + .invert_flags = + { + .clk_inv = false, + }, + }, + }; + err = i2s_channel_init_pdm_rx_mode(self->rx_chan, &pdm_rx_cfg); + CHECK_ESP_RESULT(err); + + err = i2s_channel_enable(self->rx_chan); + CHECK_ESP_RESULT(err); + + self->clock_pin = clock_pin; + self->data_pin = data_pin; + claim_pin(clock_pin); + claim_pin(data_pin); + + self->sample_rate = sample_rate; + self->bit_depth = bit_depth; +} + +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t *self) { + return self->clock_pin == NULL; +} + +void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t *self) { + if (common_hal_audiobusio_pdmin_deinited(self)) { + return; + } + + esp_err_t err = i2s_channel_disable(self->rx_chan); + CHECK_ESP_RESULT(err); + err = i2s_del_channel(self->rx_chan); + CHECK_ESP_RESULT(err); + + // common_hal_audiobusio_i2sout_stop(self); + + if (self->clock_pin) { + reset_pin_number(self->clock_pin->number); + } + self->clock_pin = NULL; + + if (self->data_pin) { + reset_pin_number(self->data_pin->number); + } + self->data_pin = NULL; +} + +/** + `length` is the buffer element count, not the byte count. +*/ + +uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t *self, + uint16_t *buffer, + uint32_t length) { +// mp_printf(MP_PYTHON_PRINTER, "Copying bytes to buffer\n"); + + size_t result = 0; + size_t elementSize = common_hal_audiobusio_pdmin_get_bit_depth(self) / 8; + esp_err_t err = i2s_channel_read(self->rx_chan, buffer, length * elementSize, &result, 100); + CHECK_ESP_RESULT(err); + return result; +} + +uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t *self) { + return self->bit_depth; +} + +uint32_t common_hal_audiobusio_pdmin_get_sample_rate(audiobusio_pdmin_obj_t *self) { + return self->sample_rate; +} + +#endif diff --git a/ports/espressif/common-hal/audiobusio/PDMIn.h b/ports/espressif/common-hal/audiobusio/PDMIn.h index c9069db9fd7..d64142b6fb0 100644 --- a/ports/espressif/common-hal/audiobusio/PDMIn.h +++ b/ports/espressif/common-hal/audiobusio/PDMIn.h @@ -5,3 +5,21 @@ // SPDX-License-Identifier: MIT #pragma once + +#include "py/obj.h" + +#include "common-hal/audiobusio/__init__.h" +#include "common-hal/microcontroller/Pin.h" + +#if CIRCUITPY_AUDIOBUSIO_PDMIN + +typedef struct { + i2s_t i2s; + i2s_chan_handle_t rx_chan; + const mcu_pin_obj_t *clock_pin; + const mcu_pin_obj_t *data_pin; + uint32_t sample_rate; + uint8_t bit_depth; +} audiobusio_pdmin_obj_t; + +#endif diff --git a/ports/espressif/common-hal/audiobusio/__init__.c b/ports/espressif/common-hal/audiobusio/__init__.c index 0841ab1d2ea..dae711100d3 100644 --- a/ports/espressif/common-hal/audiobusio/__init__.c +++ b/ports/espressif/common-hal/audiobusio/__init__.c @@ -39,25 +39,32 @@ static void i2s_fill_buffer(i2s_t *self) { self->next_buffer_size = 0; return; } - while (!self->stopping && output_buffer_size > 0) { + while (output_buffer_size > 0) { if (self->sample_data == self->sample_end) { + if (self->last_buffer) { + // The final buffer has been fully output; stop now instead of + // fetching another (which for a single-buffer sample would just + // replay it). + self->stopping = true; + break; + } uint32_t sample_buffer_length; audioio_get_buffer_result_t get_buffer_result = audiosample_get_buffer(self->sample, false, 0, &self->sample_data, &sample_buffer_length); self->sample_end = self->sample_data + sample_buffer_length; + if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) { + self->stopping = true; + break; + } if (get_buffer_result == GET_BUFFER_DONE) { if (self->loop) { audiosample_reset_buffer(self->sample, false, 0); } else { - self->stopping = true; - break; + // Output this final buffer before stopping; don't fetch again. + self->last_buffer = true; } } - if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) { - self->stopping = true; - break; - } } size_t sample_bytecount = self->sample_end - self->sample_data; // The framecount is the minimum of space left in the output buffer or left in the incoming sample. @@ -96,6 +103,11 @@ static void i2s_fill_buffer(i2s_t *self) { output_buffer += framecount * CIRCUITPY_OUTPUT_SLOTS; output_buffer_size -= framecount * bytes_per_output_frame; } + // Sample ended mid-buffer (or was empty/errored): silence the rest so the + // DMA doesn't play stale data. + if (output_buffer_size > 0) { + memset(output_buffer, 0, output_buffer_size); + } self->next_buffer = NULL; self->next_buffer_size = 0; } @@ -108,7 +120,7 @@ static void i2s_callback_fun(void *self_in) { static bool i2s_event_interrupt(i2s_chan_handle_t handle, i2s_event_data_t *event, void *self_in) { i2s_t *self = self_in; self->underrun = self->underrun || self->next_buffer != NULL; - self->next_buffer = *(int16_t **)event->data; + self->next_buffer = (int16_t *)event->dma_buf; self->next_buffer_size = event->size; background_callback_add(&self->callback, i2s_callback_fun, self_in); return false; @@ -145,12 +157,13 @@ void port_i2s_deinit(i2s_t *self) { } void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { + audiosample_check(sample); // Pause to disable the I2S channel so we can adjust the clock. port_i2s_pause(self); self->sample = sample; self->loop = loop; - self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; - self->channel_count = audiosample_channel_count(sample); + self->bytes_per_sample = audiosample_get_bits_per_sample(sample) / 8; + self->channel_count = audiosample_get_channel_count(sample); bool single_buffer; bool samples_signed; uint32_t max_buffer_length; @@ -164,7 +177,7 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { audiosample_reset_buffer(self->sample, false, 0); - uint32_t sample_rate = audiosample_sample_rate(sample); + uint32_t sample_rate = audiosample_get_sample_rate(sample); i2s_std_clk_config_t clk_config = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate); CHECK_ESP_RESULT(i2s_channel_reconfig_std_clock(self->handle, &clk_config)); @@ -172,6 +185,7 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { self->playing = true; self->paused = false; self->stopping = false; + self->last_buffer = false; // This will be slow but we can't rewind the underlying sample. So, we will // preload one frame at a time and drop the last sample that can't fit. // We cap ourselves at the max DMA set to prevent a sample drop if starting @@ -179,12 +193,12 @@ void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { uint32_t starting_frame; size_t bytes_loaded = 4; size_t preloaded = 0; - while (bytes_loaded > 0 && preloaded < CIRCUITPY_BUFFER_SIZE * CIRCUITPY_BUFFER_COUNT) { + while (bytes_loaded > 0 && preloaded < I2S_DMA_BUFFER_MAX_SIZE * CIRCUITPY_BUFFER_COUNT) { self->next_buffer = &starting_frame; self->next_buffer_size = sizeof(starting_frame); i2s_fill_buffer(self); i2s_channel_preload_data(self->handle, &starting_frame, sizeof(uint32_t), &bytes_loaded); - preloaded += 1; + preloaded += bytes_loaded; } // enable the channel @@ -209,6 +223,7 @@ void port_i2s_stop(i2s_t *self) { self->sample = NULL; self->playing = false; self->stopping = false; + self->last_buffer = false; } void port_i2s_pause(i2s_t *self) { diff --git a/ports/espressif/common-hal/audiobusio/__init__.h b/ports/espressif/common-hal/audiobusio/__init__.h index 0088cb87d5f..af341460e49 100644 --- a/ports/espressif/common-hal/audiobusio/__init__.h +++ b/ports/espressif/common-hal/audiobusio/__init__.h @@ -19,6 +19,7 @@ typedef struct { bool paused; // True when the I2S channel is configured but disabled. bool playing; // True when the I2S channel is configured. bool stopping; + bool last_buffer; // True once the sample's final buffer has been fetched but not yet fully output. bool samples_signed; int8_t bytes_per_sample; int8_t channel_count; diff --git a/ports/espressif/common-hal/audioi2sin/I2SIn.c b/ports/espressif/common-hal/audioi2sin/I2SIn.c new file mode 100644 index 00000000000..9a85d11f493 --- /dev/null +++ b/ports/espressif/common-hal/audioi2sin/I2SIn.c @@ -0,0 +1,449 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "bindings/espidf/__init__.h" + +#include "common-hal/audioi2sin/I2SIn.h" +#include "py/runtime.h" +#include "shared-bindings/audioi2sin/I2SIn.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/audioi2sin/__init__.h" +#include "supervisor/port.h" + +#include "driver/i2s_std.h" + +#if CIRCUITPY_AUDIOI2SIN + +void common_hal_audioi2sin_i2sin_construct(audioi2sin_i2sin_obj_t *self, + const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, + uint32_t sample_rate, uint8_t bit_depth, uint8_t output_bit_depth, + bool mono, bool left_justified, bool samples_signed, + bool external_clock) { + if (external_clock) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_external_clock); + } + + i2s_data_bit_width_t bit_width = (i2s_data_bit_width_t)bit_depth; + + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(I2S_NUM_AUTO, I2S_ROLE_MASTER); + esp_err_t err = i2s_new_channel(&chan_cfg, NULL, &self->rx_chan); + if (err == ESP_ERR_NOT_FOUND) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Peripheral in use")); + } + CHECK_ESP_RESULT(err); + + // Always configure the bus as stereo. The newer-family I2S peripherals + // (S2/S3/C-series) ignore I2S_SLOT_MODE_MONO on RX and write both slots + // into the DMA buffer regardless, which yields buffers that fill at 2x + // the WS rate and produces half-speed audio. By configuring stereo and + // dropping one slot ourselves in record_to_buffer, behavior is uniform + // across chips. + i2s_std_slot_config_t slot_cfg = left_justified + ? (i2s_std_slot_config_t)I2S_STD_MSB_SLOT_DEFAULT_CONFIG(bit_width, I2S_SLOT_MODE_STEREO) + : (i2s_std_slot_config_t)I2S_STD_PHILIPS_SLOT_DEFAULT_CONFIG(bit_width, I2S_SLOT_MODE_STEREO); + + i2s_std_config_t std_cfg = { + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(sample_rate), + .slot_cfg = slot_cfg, + .gpio_cfg = { + .mclk = main_clock != NULL ? main_clock->number : I2S_GPIO_UNUSED, + .bclk = bit_clock->number, + .ws = word_select->number, + .dout = I2S_GPIO_UNUSED, + .din = data->number, + }, + }; + CHECK_ESP_RESULT(i2s_channel_init_std_mode(self->rx_chan, &std_cfg)); + CHECK_ESP_RESULT(i2s_channel_enable(self->rx_chan)); + + self->bit_clock = bit_clock; + self->word_select = word_select; + self->data = data; + self->mclk = main_clock; + self->sample_rate = sample_rate; + self->bit_depth = bit_depth; + self->mono = mono; + self->samples_signed = samples_signed; + + // Populate the audiosample base so I2SIn can stream into the audio pipeline. + // Streaming requires an 8- or 16-bit output depth (reset_buffer enforces it); + // the owned conversion buffer is allocated lazily on first reset_buffer(). + uint8_t channel_count = mono ? 1 : 2; + self->base.sample_rate = sample_rate; + self->base.bits_per_sample = output_bit_depth; + self->base.channel_count = channel_count; + self->base.samples_signed = samples_signed; + self->base.single_buffer = false; + self->base.max_buffer_length = + 2 * AUDIOI2SIN_STREAM_FRAMES * (output_bit_depth / 8) * channel_count; + self->output_buffer = NULL; + self->output_half_bytes = self->base.max_buffer_length / 2; + self->output_index = 0; + + claim_pin(bit_clock); + claim_pin(word_select); + claim_pin(data); + if (main_clock) { + claim_pin(main_clock); + } +} + +bool common_hal_audioi2sin_i2sin_deinited(audioi2sin_i2sin_obj_t *self) { + return self->data == NULL; +} + +void common_hal_audioi2sin_i2sin_deinit(audioi2sin_i2sin_obj_t *self) { + if (common_hal_audioi2sin_i2sin_deinited(self)) { + return; + } + + if (self->rx_chan) { + i2s_channel_disable(self->rx_chan); + i2s_del_channel(self->rx_chan); + self->rx_chan = NULL; + } + + if (self->bit_clock) { + reset_pin_number(self->bit_clock->number); + } + self->bit_clock = NULL; + + if (self->word_select) { + reset_pin_number(self->word_select->number); + } + self->word_select = NULL; + + if (self->data) { + reset_pin_number(self->data->number); + } + self->data = NULL; + + if (self->mclk) { + reset_pin_number(self->mclk->number); + } + self->mclk = NULL; + + if (self->output_buffer != NULL) { + port_free(self->output_buffer); + self->output_buffer = NULL; + } + audiosample_mark_deinit(&self->base); +} + +// Sign-extend a raw I2S sample (in the low `in_depth` bits of `raw`) to a +// canonical int32 value. +static inline int32_t i2sin_normalize_signed(uint32_t raw, uint8_t in_depth) { + if (in_depth == 32) { + return (int32_t)raw; + } + if (in_depth == 24) { + uint32_t sign_bit = 0x800000u; + return (int32_t)((raw ^ sign_bit) - sign_bit); + } + if (in_depth == 16) { + return (int16_t)(raw & 0xffffu); + } + return (int8_t)(raw & 0xffu); +} + +// Read a single sample from the DMA scratch at the given byte offset for the +// configured input bit depth. +static inline uint32_t i2sin_read_raw(const uint8_t *src, uint8_t in_depth) { + if (in_depth == 8) { + return (uint32_t)(*src); + } + if (in_depth == 16) { + uint16_t v; + memcpy(&v, src, sizeof(v)); + return v; + } + uint32_t v; + memcpy(&v, src, sizeof(v)); + return v; +} + +// Normalize `raw` from `in_depth` for this port's wire format, then hand off to +// the shared converter to rescale `in_depth` -> `out_depth` and write it to +// `buffer` at sample index `idx`. The depth conversion + unsigned-WAV flip + +// container store live in `shared_audioi2sin_write_converted` (shared with other +// ports); see that helper for the upscale/downscale semantics. +static inline void i2sin_write_converted(void *buffer, uint32_t idx, + uint32_t raw, uint8_t in_depth, uint8_t out_depth, bool samples_signed) { + int32_t s = i2sin_normalize_signed(raw, in_depth); + shared_audioi2sin_write_converted(buffer, idx, s, in_depth, out_depth, samples_signed); +} + +// I2S delivers signed PCM. When samples_signed is false, XOR each sample with +// the sign bit for its width to convert to unsigned PCM (WAV convention). +static void i2sin_convert_to_unsigned(void *buffer, uint32_t samples, + uint8_t bit_depth, size_t element_size) { + (void)element_size; + uint32_t *p = (uint32_t *)buffer; + + if (bit_depth == 8) { + // 4 samples per word + uint32_t words = samples / 4; + for (uint32_t i = 0; i < words; i++) { + p[i] ^= 0x80808080u; + } + // tail: 0–3 leftover bytes + uint8_t *tail = (uint8_t *)(p + words); + for (uint32_t i = 0; i < (samples & 3u); i++) { + tail[i] ^= 0x80u; + } + } else if (bit_depth == 16) { + // 2 samples per word + uint32_t words = samples / 2; + for (uint32_t i = 0; i < words; i++) { + p[i] ^= 0x80008000u; + } + if (samples & 1u) { + ((uint16_t *)(p + words))[0] ^= 0x8000u; + } + } else { + // 24- or 32-bit: one sample per 32-bit slot + uint32_t mask = (bit_depth == 24) ? 0x00800000u : 0x80000000u; + for (uint32_t i = 0; i < samples; i++) { + p[i] ^= mask; + } + } +} + + +uint32_t common_hal_audioi2sin_i2sin_record_to_buffer(audioi2sin_i2sin_obj_t *self, + void *buffer, uint32_t length) { + size_t element_size = self->bit_depth / 8; + // 24-bit samples occupy a 32-bit slot on the I2S bus. + if (self->bit_depth == 24) { + element_size = 4; + } + + if (self->base.bits_per_sample != self->bit_depth) { + // Bit-depth conversion path: always read at input width into scratch, + // convert each sample into the user's buffer at output width. + const uint8_t in_depth = self->bit_depth; + const uint8_t out_depth = self->base.bits_per_sample; + const bool samples_signed = self->samples_signed; + uint8_t scratch[256]; + const size_t in_frame_bytes = 2 * element_size; + const size_t scratch_frames = sizeof(scratch) / in_frame_bytes; + uint32_t produced = 0; + while (produced < length) { + size_t want_frames; + if (self->mono) { + want_frames = length - produced; + } else { + want_frames = (length - produced + 1) / 2; + } + if (want_frames > scratch_frames) { + want_frames = scratch_frames; + } + size_t got_bytes = 0; + esp_err_t err = i2s_channel_read(self->rx_chan, scratch, + want_frames * in_frame_bytes, &got_bytes, portMAX_DELAY); + CHECK_ESP_RESULT(err); + size_t got_frames = got_bytes / in_frame_bytes; + for (size_t i = 0; i < got_frames && produced < length; i++) { + const uint8_t *frame = scratch + i * in_frame_bytes; + uint32_t left_raw = i2sin_read_raw(frame, in_depth); + i2sin_write_converted(buffer, produced++, left_raw, + in_depth, out_depth, samples_signed); + if (!self->mono && produced < length) { + uint32_t right_raw = i2sin_read_raw(frame + element_size, in_depth); + i2sin_write_converted(buffer, produced++, right_raw, + in_depth, out_depth, samples_signed); + } + } + if (got_frames < want_frames) { + break; + } + } + return produced; + } + + uint32_t produced; + if (!self->mono) { + size_t result = 0; + esp_err_t err = i2s_channel_read(self->rx_chan, buffer, length * element_size, + &result, portMAX_DELAY); + CHECK_ESP_RESULT(err); + produced = result / element_size; + } else { + // Mono: bus is configured stereo, so each WS frame yields two slots in + // the DMA buffer. Read in chunks into a scratch and keep only the left + // slot of each frame. + uint8_t scratch[256]; + const size_t frame_bytes = 2 * element_size; + const size_t scratch_frames = sizeof(scratch) / frame_bytes; + uint8_t *out = (uint8_t *)buffer; + produced = 0; + while (produced < length) { + size_t want_frames = length - produced; + if (want_frames > scratch_frames) { + want_frames = scratch_frames; + } + size_t got_bytes = 0; + esp_err_t err = i2s_channel_read(self->rx_chan, scratch, + want_frames * frame_bytes, &got_bytes, portMAX_DELAY); + CHECK_ESP_RESULT(err); + size_t got_frames = got_bytes / frame_bytes; + for (size_t i = 0; i < got_frames; i++) { + memcpy(out + produced * element_size, + scratch + i * frame_bytes, + element_size); + produced++; + } + if (got_frames < want_frames) { + break; + } + } + } + + if (!self->samples_signed && produced > 0) { + i2sin_convert_to_unsigned(buffer, produced, self->bit_depth, element_size); + } + return produced; +} + +uint8_t common_hal_audioi2sin_i2sin_get_bit_depth(audioi2sin_i2sin_obj_t *self) { + return self->bit_depth; +} + +uint32_t common_hal_audioi2sin_i2sin_get_sample_rate(audioi2sin_i2sin_obj_t *self) { + return self->sample_rate; +} + +bool common_hal_audioi2sin_i2sin_get_samples_signed(audioi2sin_i2sin_obj_t *self) { + return self->samples_signed; +} + +// Always false here: this port hands the capture ring to the IDF driver, which +// drops frames internally without telling us. Detecting it would require +// registering an on_recv_q_ovf callback on the channel. +bool common_hal_audioi2sin_i2sin_get_overflow(audioi2sin_i2sin_obj_t *self) { + (void)self; + return false; +} + +// Write `count` silence samples at output depth starting at sample index `idx`. +// For signed PCM silence is 0; for unsigned (WAV) it is mid-scale. +static void i2sin_fill_silence(void *buffer, uint32_t idx, uint32_t count, + uint8_t out_depth, bool samples_signed) { + if (out_depth == 8) { + uint8_t v = samples_signed ? 0 : 0x80u; + memset((uint8_t *)buffer + idx, v, count); + } else { // 16-bit (the only other streamable width) + uint16_t v = samples_signed ? 0 : 0x8000u; + uint16_t *p = (uint16_t *)buffer + idx; + for (uint32_t i = 0; i < count; i++) { + p[i] = v; + } + } +} + +// Non-blocking fill: read whatever frames are immediately available from the I2S +// driver and convert them into `buffer` (output depth, interleaved), padding the +// remainder with silence on underrun. The bus is configured stereo, so each WS +// frame yields two slots; for mono we keep the left slot. `out_depth` is always 8 +// or 16 here (reset_buffer rejects 24/32). Runs in the output backend's refill +// (background callback) context, so i2s_channel_read is called with a 0 ms +// timeout and never blocks. +void common_hal_audioi2sin_i2sin_fill_buffer(audioi2sin_i2sin_obj_t *self, + uint8_t *buffer, uint32_t frames) { + const uint8_t in_depth = self->bit_depth; + const uint8_t out_depth = self->base.bits_per_sample; + const bool samples_signed = self->samples_signed; + const bool stereo = !self->mono; + const uint8_t channel_count = stereo ? 2 : 1; + size_t element_size = (in_depth == 24) ? 4 : (in_depth / 8); + const size_t in_frame_bytes = 2 * element_size; // bus is always stereo + const uint32_t total_samples = frames * channel_count; + + uint8_t scratch[256]; + const size_t scratch_frames = sizeof(scratch) / in_frame_bytes; + + uint32_t produced = 0; + while (produced < total_samples) { + size_t want_frames = (total_samples - produced + channel_count - 1) / channel_count; + if (want_frames > scratch_frames) { + want_frames = scratch_frames; + } + size_t got_bytes = 0; + // 0 ms timeout: return immediately with whatever is buffered. + esp_err_t err = i2s_channel_read(self->rx_chan, scratch, + want_frames * in_frame_bytes, &got_bytes, 0); + if (err != ESP_OK && err != ESP_ERR_TIMEOUT) { + break; + } + size_t got_frames = got_bytes / in_frame_bytes; + if (got_frames == 0) { + break; // underrun: pad with silence below + } + for (size_t i = 0; i < got_frames && produced < total_samples; i++) { + const uint8_t *frame = scratch + i * in_frame_bytes; + uint32_t left_raw = i2sin_read_raw(frame, in_depth); + i2sin_write_converted(buffer, produced++, left_raw, + in_depth, out_depth, samples_signed); + if (stereo && produced < total_samples) { + uint32_t right_raw = i2sin_read_raw(frame + element_size, in_depth); + i2sin_write_converted(buffer, produced++, right_raw, + in_depth, out_depth, samples_signed); + } + } + if (got_frames < want_frames) { + break; + } + } + if (produced < total_samples) { + i2sin_fill_silence(buffer, produced, total_samples - produced, + out_depth, samples_signed); + } +} + +void common_hal_audioi2sin_i2sin_reset_buffer(audioi2sin_i2sin_obj_t *self, + bool single_channel_output, uint8_t channel) { + (void)single_channel_output; + (void)channel; + // The audio pipeline only carries 8- or 16-bit samples; 24/32-bit modes can + // still record() but cannot stream. + if (self->base.bits_per_sample != 8 && self->base.bits_per_sample != 16) { + mp_raise_ValueError_varg( + MP_ERROR_TEXT("%q must be 8 or 16"), MP_QSTR_output_bit_depth); + } + if (self->output_buffer == NULL) { + self->output_buffer = (uint8_t *)port_malloc(self->base.max_buffer_length, false); + if (self->output_buffer == NULL) { + m_malloc_fail(self->base.max_buffer_length); + } + } + self->output_index = 0; +} + +audioio_get_buffer_result_t common_hal_audioi2sin_i2sin_get_buffer( + audioi2sin_i2sin_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + uint32_t half = self->output_half_bytes; + uint8_t *out = self->output_buffer + half * self->output_index; + self->output_index = 1 - self->output_index; + + uint32_t bytes_per_sample = self->base.bits_per_sample / 8; + uint32_t frames = half / (bytes_per_sample * self->base.channel_count); + common_hal_audioi2sin_i2sin_fill_buffer(self, out, frames); + + if (single_channel_output) { + out += (channel % self->base.channel_count) * bytes_per_sample; + } + *buffer = out; + *buffer_length = half; + // A live mic is an infinite stream; never report DONE or the backend stops. + return GET_BUFFER_MORE_DATA; +} + +#endif // CIRCUITPY_AUDIOI2SIN diff --git a/ports/espressif/common-hal/audioi2sin/I2SIn.h b/ports/espressif/common-hal/audioi2sin/I2SIn.h new file mode 100644 index 00000000000..a6fc7224c32 --- /dev/null +++ b/ports/espressif/common-hal/audioi2sin/I2SIn.h @@ -0,0 +1,43 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" + +#include "shared-module/audiocore/__init__.h" + +#include "driver/i2s_std.h" + +#if CIRCUITPY_AUDIOI2SIN + +// Frames handed to the output backend per get_buffer() call; see the matching +// rp2 header for the rationale. +#define AUDIOI2SIN_STREAM_FRAMES (256) + +typedef struct { + // so I2SIn can be used directly as an audiosample source. + audiosample_base_t base; + i2s_chan_handle_t rx_chan; + const mcu_pin_obj_t *bit_clock; + const mcu_pin_obj_t *word_select; + const mcu_pin_obj_t *data; + const mcu_pin_obj_t *mclk; + uint32_t sample_rate; + uint8_t bit_depth; + bool mono; + bool samples_signed; + // Owned double-buffer of converted (output-depth, interleaved) samples, + // allocated lazily on first reset_buffer(). base.max_buffer_length is the + // whole buffer; get_buffer() returns output_half_bytes of it. + uint8_t *output_buffer; + size_t output_half_bytes; + uint8_t output_index; +} audioi2sin_i2sin_obj_t; + +#endif diff --git a/ports/espressif/common-hal/audioi2sin/__init__.c b/ports/espressif/common-hal/audioi2sin/__init__.c new file mode 100644 index 00000000000..584c821b996 --- /dev/null +++ b/ports/espressif/common-hal/audioi2sin/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT diff --git a/ports/espressif/common-hal/audioio/AudioOut.c b/ports/espressif/common-hal/audioio/AudioOut.c new file mode 100644 index 00000000000..e6aed580e27 --- /dev/null +++ b/ports/espressif/common-hal/audioio/AudioOut.c @@ -0,0 +1,644 @@ + +#include + +#include "py/runtime.h" + +#include "common-hal/audioio/AudioOut.h" +#include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/audiocore/__init__.h" + +#include "driver/dac_continuous.h" + +#if defined(CONFIG_IDF_TARGET_ESP32) +#define pin_CHANNEL_0 pin_GPIO25 +#define pin_CHANNEL_1 pin_GPIO26 +#elif defined(CONFIG_IDF_TARGET_ESP32S2) +#define pin_CHANNEL_0 pin_GPIO17 +#define pin_CHANNEL_1 pin_GPIO18 +#endif + +static dac_continuous_handle_t _active_handle; + +#define INCREMENT_BUF_IDX(idx) ((idx + 1) % (NUM_DMA_BUFFERS + 1)) + +static bool audioout_convert_noop( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + *out_buffer = in_buffer; + *out_buffer_size = in_buffer_size; + return false; +} + +static bool audioout_convert_u8s_u8m( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size / 2); + buffer_changed = true; + } + audiosample_convert_u8s_u8m(*out_buffer, (uint8_t *)in_buffer, in_buffer_size / 2); + *out_buffer_size = in_buffer_size / 2; + return buffer_changed; +} + +static bool audioout_convert_u8m_u8s( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size * 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size * 2); + buffer_changed = true; + } + audiosample_convert_u8m_u8s(*out_buffer, (uint8_t *)in_buffer, in_buffer_size); + *out_buffer_size = in_buffer_size * 2; + return buffer_changed; +} + +static bool audioout_convert_s8m_u8m( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size); + buffer_changed = true; + } + audiosample_convert_s8m_u8m(*out_buffer, (int8_t *)in_buffer, in_buffer_size); + *out_buffer_size = in_buffer_size; + return buffer_changed; +} + +static bool audioout_convert_s8s_u8m( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size / 2); + buffer_changed = true; + } + audiosample_convert_s8s_u8m(*out_buffer, (int8_t *)in_buffer, in_buffer_size / 2); + *out_buffer_size = in_buffer_size / 2; + return buffer_changed; +} + +static bool audioout_convert_s8m_u8s( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size * 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size * 2); + buffer_changed = true; + } + audiosample_convert_s8m_u8s(*out_buffer, (int8_t *)in_buffer, in_buffer_size); + *out_buffer_size = in_buffer_size * 2; + return buffer_changed; +} + +static bool audioout_convert_s8s_u8s( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size); + buffer_changed = true; + } + audiosample_convert_s8s_u8s(*out_buffer, (int8_t *)in_buffer, in_buffer_size); + *out_buffer_size = in_buffer_size; + return buffer_changed; +} + +static bool audioout_convert_u16m_u8m( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size / 2); + buffer_changed = true; + } + audiosample_convert_u16m_u8m(*out_buffer, (uint16_t *)in_buffer, in_buffer_size / 2); + *out_buffer_size = in_buffer_size / 2; + return buffer_changed; +} + +static bool audioout_convert_u16m_u8s( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size); + buffer_changed = true; + } + audiosample_convert_u16m_u8s(*out_buffer, (uint16_t *)in_buffer, in_buffer_size / 2); + *out_buffer_size = in_buffer_size; + return buffer_changed; +} + +static bool audioout_convert_u16s_u8m( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 4 > *out_buffer_size) { + *out_buffer = m_malloc(in_buffer_size / 4); + buffer_changed = true; + } + audiosample_convert_u16s_u8m(*out_buffer, (uint16_t *)in_buffer, in_buffer_size / 4); + *out_buffer_size = in_buffer_size / 4; + return buffer_changed; +} + +static bool audioout_convert_u16s_u8s( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size / 2); + buffer_changed = true; + } + audiosample_convert_u16s_u8s(*out_buffer, (uint16_t *)in_buffer, in_buffer_size / 4); + *out_buffer_size = in_buffer_size / 2; + return buffer_changed; +} + +static bool audioout_convert_s16m_u8m( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size / 2); + buffer_changed = true; + } + audiosample_convert_s16m_u8m(*out_buffer, (int16_t *)in_buffer, in_buffer_size / 2); + *out_buffer_size = in_buffer_size / 2; + return buffer_changed; +} + +static bool audioout_convert_s16m_u8s( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size); + buffer_changed = true; + } + audiosample_convert_s16m_u8s(*out_buffer, (int16_t *)in_buffer, in_buffer_size / 2); + *out_buffer_size = in_buffer_size; + return buffer_changed; +} + +static bool audioout_convert_s16s_u8m( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 4 > *out_buffer_size) { + *out_buffer = m_malloc(in_buffer_size / 4); + buffer_changed = true; + } + audiosample_convert_s16s_u8m(*out_buffer, (int16_t *)in_buffer, in_buffer_size / 4); + *out_buffer_size = in_buffer_size / 4; + return buffer_changed; +} + +static bool audioout_convert_s16s_u8s( + void *in_buffer, + size_t in_buffer_size, + uint8_t **out_buffer, + uint32_t *out_buffer_size) { + + bool buffer_changed = false; + if (in_buffer_size / 2 > *out_buffer_size) { + *out_buffer = m_malloc_without_collect(in_buffer_size / 2); + buffer_changed = true; + } + audiosample_convert_s16s_u8s(*out_buffer, (int16_t *)in_buffer, in_buffer_size / 4); + *out_buffer_size = in_buffer_size / 2; + return buffer_changed; +} + +#define CONV_MATCH(bps, sign, ichans, ochans) ((bps & 0xf) | ((sign & 0x1) << 4) | ((ichans & 0x3) << 5) | ((ochans & 0x3) << 7)) + +static audioout_sample_convert_func_t audioout_get_samples_convert_func( + size_t in_bits_per_sample, + int in_channels, + bool in_signed, + int out_channels) { + + switch CONV_MATCH(in_bits_per_sample, in_signed, in_channels, out_channels) { + case CONV_MATCH(8, false, 1, 1): + case CONV_MATCH(8, false, 2, 2): + return audioout_convert_noop; + case CONV_MATCH(8, false, 2, 1): + return audioout_convert_u8s_u8m; + case CONV_MATCH(8, false, 1, 2): + return audioout_convert_u8m_u8s; + case CONV_MATCH(8, true, 1, 1): + return audioout_convert_s8m_u8m; + case CONV_MATCH(8, true, 2, 1): + return audioout_convert_s8s_u8m; + case CONV_MATCH(8, true, 1, 2): + return audioout_convert_s8m_u8s; + case CONV_MATCH(8, true, 2, 2): + return audioout_convert_s8s_u8s; + case CONV_MATCH(16, false, 1, 1): + return audioout_convert_u16m_u8m; + case CONV_MATCH(16, false, 1, 2): + return audioout_convert_u16m_u8s; + case CONV_MATCH(16, false, 2, 1): + return audioout_convert_u16s_u8m; + case CONV_MATCH(16, false, 2, 2): + return audioout_convert_u16s_u8s; + case CONV_MATCH(16, true, 1, 1): + return audioout_convert_s16m_u8m; + case CONV_MATCH(16, true, 1, 2): + return audioout_convert_s16m_u8s; + case CONV_MATCH(16, true, 2, 1): + return audioout_convert_s16s_u8m; + case CONV_MATCH(16, true, 2, 2): + return audioout_convert_s16s_u8s; + default: + mp_raise_RuntimeError(MP_ERROR_TEXT("audio format not supported")); + } +} + +static void audioio_audioout_start(audioio_audioout_obj_t *self) { + esp_err_t ret; + + self->playing = true; + self->paused = false; + + ret = dac_continuous_start_async_writing(self->handle); + if (ret != ESP_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to start async audio")); + } +} + +static void audioio_audioout_stop(audioio_audioout_obj_t *self, bool full_stop) { + dac_continuous_stop_async_writing(self->handle); + if (full_stop) { + self->get_buffer_index = 0; + self->put_buffer_index = 0; + self->sample_buffer = NULL; + self->sample = NULL; + self->playing = false; + self->paused = false; + } else { + self->paused = true; + } +} + +static bool audioout_fill_buffer(audioio_audioout_obj_t *self) { + if (!self->playing) { + return false; + } + + audioio_get_buffer_result_t get_buffer_result; + + uint8_t dma_buf_idx = self->get_buffer_index; + + if (dma_buf_idx == self->put_buffer_index) { + return false; + } + + uint8_t *dma_buf = self->dma_buffers[dma_buf_idx].ptr; + size_t dma_buf_size = self->dma_buffers[dma_buf_idx].size; + + self->get_buffer_index = INCREMENT_BUF_IDX(dma_buf_idx); + + bool single_channel_output = true; // whether or not we have 1 or 2 output channels + uint8_t channel = 0; // which channel right now? + uint8_t *raw_sample_buf; // raw audio sample buffer + uint32_t raw_sample_buf_size; // raw audio sample buffer len + uint8_t *sample_buf = self->scratch_buffer; // converted audio sample buffer + uint32_t sample_buf_size = self->scratch_buffer_size; // converted audio sample buffer len + size_t bytes_loaded; + esp_err_t ret; + + if (self->sample_buffer != NULL && self->sample_buffer_size > 0) { + sample_buf = self->sample_buffer; + sample_buf_size = self->sample_buffer_size; + get_buffer_result = self->sample_buffer_result; + } else { + get_buffer_result = audiosample_get_buffer(self->sample, + single_channel_output, + channel, + &raw_sample_buf, &raw_sample_buf_size); + + if (get_buffer_result == GET_BUFFER_ERROR) { + audioio_audioout_stop(self, true); + return false; + } + + bool buffer_changed; + buffer_changed = self->samples_convert( + raw_sample_buf, + raw_sample_buf_size, + &sample_buf, + &sample_buf_size); + + if (buffer_changed) { + if (self->scratch_buffer != NULL) { + m_free(self->scratch_buffer); + } + self->scratch_buffer = sample_buf; + self->scratch_buffer_size = sample_buf_size; + } + } + + if (sample_buf_size > 0) { + ret = dac_continuous_write_asynchronously(self->handle, + dma_buf, dma_buf_size, + sample_buf, sample_buf_size, + &bytes_loaded); + + if (ret != ESP_OK) { + return false; + } + } + + sample_buf_size -= bytes_loaded; + if (sample_buf_size == 0) { + sample_buf = NULL; + } else { + sample_buf += bytes_loaded; + } + + self->sample_buffer = sample_buf; + self->sample_buffer_size = sample_buf_size; + self->sample_buffer_result = get_buffer_result; + + if (get_buffer_result == GET_BUFFER_DONE && sample_buf_size == 0) { + if (self->looping) { + audiosample_reset_buffer(self->sample, true, 0); + } else { + // TODO: figure out if it is ok to call this here or do we need + // to somehow wait for all of the samples to be flushed + audioio_audioout_stop(self, true); + return false; + } + } + + return true; +} + +static void audioout_fill_buffers(audioio_audioout_obj_t *self) { + while (audioout_fill_buffer(self)) { + ; + } +} + +static void audioout_buf_callback_fun(void *user_data) { + audioio_audioout_obj_t *self = (audioio_audioout_obj_t *)user_data; + audioout_fill_buffers(self); +} + +static bool IRAM_ATTR handle_convert_done(dac_continuous_handle_t handle, const dac_event_data_t *event, void *user_data) { + audioio_audioout_obj_t *self = (audioio_audioout_obj_t *)user_data; + + uint8_t *newly_freed_dma_buf = event->buf; + size_t newly_freed_dma_buf_size = event->buf_size; + + uint8_t get_buf_idx = self->get_buffer_index; + uint8_t put_buf_idx = self->put_buffer_index; + uint8_t new_put_buf_idx = INCREMENT_BUF_IDX(put_buf_idx); + + // if the ring buffer of dma buffers is full then drop this one + if (get_buf_idx == new_put_buf_idx) { + return false; + } + + self->dma_buffers[put_buf_idx].ptr = newly_freed_dma_buf; + self->dma_buffers[put_buf_idx].size = newly_freed_dma_buf_size; + + self->put_buffer_index = new_put_buf_idx; + + background_callback_add(&self->callback, audioout_buf_callback_fun, user_data); + + return false; +} + +static void audioout_init(audioio_audioout_obj_t *self) { + dac_continuous_digi_clk_src_t clk_src = DAC_DIGI_CLK_SRC_DEFAULT; + if (self->freq_hz < 19600) { + clk_src = DAC_DIGI_CLK_SRC_APLL; + } + + dac_continuous_config_t cfg = { + .chan_mask = self->channel_mask, + .desc_num = NUM_DMA_BUFFERS, + .buf_size = DMA_BUFFER_SIZE, + .freq_hz = self->freq_hz, + .offset = 0, + .clk_src = clk_src, + .chan_mode = self->channel_mode, + }; + + esp_err_t ret; + + ret = dac_continuous_new_channels(&cfg, &self->handle); + if (ret == ESP_ERR_INVALID_ARG) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to create continuous channels: invalid arg")); + } else if (ret == ESP_ERR_INVALID_STATE) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to create continuous channels: invalid state")); + } else if (ret == ESP_ERR_NOT_FOUND) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to create continuous channels: not found")); + } else if (ret == ESP_ERR_NO_MEM) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to create continuous channels: no mem")); + } + + _active_handle = self->handle; + + dac_event_callbacks_t callbacks = { + .on_convert_done = handle_convert_done, + .on_stop = NULL, + }; + + ret = dac_continuous_register_event_callback(self->handle, &callbacks, (void *)self); + if (ret != ESP_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to register continuous events callback")); + } + + ret = dac_continuous_enable(self->handle); + if (ret != ESP_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to enable continuous")); + } +} + +void common_hal_audioio_audioout_construct(audioio_audioout_obj_t *self, + const mcu_pin_obj_t *left_channel_pin, const mcu_pin_obj_t *right_channel_pin, uint16_t quiescent_value) { + + if (_active_handle != NULL) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Can't construct AudioOut because continuous channel already open")); + } + + self->playing = false; + self->paused = false; + self->freq_hz = DEFAULT_SAMPLE_RATE; + + // The case of left_channel == right_channel is already disallowed in shared-bindings. + + if ((left_channel_pin == &pin_CHANNEL_0 && + right_channel_pin == &pin_CHANNEL_1) || + (left_channel_pin == &pin_CHANNEL_1 && + right_channel_pin == &pin_CHANNEL_0)) { + self->channel_mask = DAC_CHANNEL_MASK_ALL; + self->num_channels = 2; + self->channel_mode = DAC_CHANNEL_MODE_ALTER; + } else if (left_channel_pin == &pin_CHANNEL_0 && + right_channel_pin == NULL) { + self->channel_mask = DAC_CHANNEL_MASK_CH0; + self->num_channels = 1; + self->channel_mode = DAC_CHANNEL_MODE_SIMUL; + } else if (left_channel_pin == &pin_CHANNEL_1 && + right_channel_pin == NULL) { + self->channel_mask = DAC_CHANNEL_MASK_CH1; + self->num_channels = 1; + self->channel_mode = DAC_CHANNEL_MODE_SIMUL; + } else { + raise_ValueError_invalid_pin(); + } + + audioout_init(self); +} + +bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t *self) { + return self->handle == NULL; +} + +void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t *self) { + if (common_hal_audioio_audioout_deinited(self)) { + return; + } + + if (self->playing) { + common_hal_audioio_audioout_stop(self); + } + dac_continuous_disable(self->handle); + dac_continuous_del_channels(self->handle); + if (self->scratch_buffer != NULL) { + m_free(self->scratch_buffer); + self->scratch_buffer = NULL; + self->scratch_buffer_size = 0; + } + self->handle = NULL; + _active_handle = NULL; +} + +void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self, + mp_obj_t sample, bool loop) { + + if (self->playing) { + mp_raise_RuntimeError(MP_ERROR_TEXT("already playing")); + } + + audiosample_check(sample); + + size_t samples_size; + uint8_t channel_count; + bool samples_signed; + bool _single_buffer; + uint32_t _max_buffer_length; + uint8_t _spacing; + uint32_t freq_hz; + + audiosample_reset_buffer(sample, true, 0); + + self->sample = sample; + self->looping = loop; + freq_hz = audiosample_get_sample_rate(self->sample); + + // Workaround: always reset the DAC completely between plays, + // due to a bug that causes the left and right channels to be swapped randomly. + // See https://github.com/espressif/esp-idf/issues/11425 + // TODO: Remove the `true` when this issue is fixed. + if (true || freq_hz != self->freq_hz) { + common_hal_audioio_audioout_deinit(self); + self->freq_hz = freq_hz; + audioout_init(self); + } + + samples_size = audiosample_get_bits_per_sample(self->sample); + channel_count = audiosample_get_channel_count(self->sample); + audiosample_get_buffer_structure(self->sample, false, + &_single_buffer, &samples_signed, + &_max_buffer_length, &_spacing); + + self->samples_convert = audioout_get_samples_convert_func( + samples_size, + channel_count, + samples_signed, + self->num_channels); + + audioio_audioout_start(self); +} + +void common_hal_audioio_audioout_pause(audioio_audioout_obj_t *self) { + if (!self->playing || self->paused) { + return; + } + audioio_audioout_stop(self, false); +} + +void common_hal_audioio_audioout_resume(audioio_audioout_obj_t *self) { + if (!self->playing || !self->paused) { + return; + } + audioio_audioout_start(self); +} + +bool common_hal_audioio_audioout_get_paused(audioio_audioout_obj_t *self) { + return self->playing && self->paused; +} + +void common_hal_audioio_audioout_stop(audioio_audioout_obj_t *self) { + if (!self->playing) { + return; + } + audioio_audioout_stop(self, true); +} + +bool common_hal_audioio_audioout_get_playing(audioio_audioout_obj_t *self) { + return self->playing && !self->paused; +} diff --git a/ports/espressif/common-hal/audioio/AudioOut.h b/ports/espressif/common-hal/audioio/AudioOut.h new file mode 100644 index 00000000000..b35d9ffdcf7 --- /dev/null +++ b/ports/espressif/common-hal/audioio/AudioOut.h @@ -0,0 +1,47 @@ + +#pragma once + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +#include "supervisor/background_callback.h" +#include "shared-module/audiocore/__init__.h" + +#include "driver/dac_continuous.h" + + +#define NUM_DMA_BUFFERS 6 +#define DMA_BUFFER_SIZE 512 + +#define DEFAULT_SAMPLE_RATE 32000 + +typedef bool (*audioout_sample_convert_func_t)(void *in_buffer, size_t in_buffer_size, uint8_t **out_buffer, uint32_t *out_buffer_size); + +typedef struct { + uint8_t *ptr; + size_t size; +} buf_info_t; + +typedef struct { + mp_obj_base_t base; + dac_continuous_handle_t handle; + dac_channel_mask_t channel_mask; + uint32_t freq_hz; + uint8_t num_channels; + dac_continuous_channel_mode_t channel_mode; + mp_obj_t sample; + bool playing; + bool paused; + bool looping; + uint8_t *sample_buffer; + size_t sample_buffer_size; + audioio_get_buffer_result_t sample_buffer_result; + uint8_t get_buffer_index; + uint8_t put_buffer_index; + buf_info_t dma_buffers[NUM_DMA_BUFFERS + 1]; + background_callback_t callback; + uint8_t *scratch_buffer; + size_t scratch_buffer_size; + audioout_sample_convert_func_t samples_convert; +} audioio_audioout_obj_t; diff --git a/ports/espressif/common-hal/audioio/__init__.c b/ports/espressif/common-hal/audioio/__init__.c new file mode 100644 index 00000000000..f7af773c4b8 --- /dev/null +++ b/ports/espressif/common-hal/audioio/__init__.c @@ -0,0 +1,2 @@ + +#include "common-hal/audioio/__init__.h" diff --git a/ports/espressif/common-hal/audioio/__init__.h b/ports/espressif/common-hal/audioio/__init__.h new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/espressif/common-hal/busio/I2C.c b/ports/espressif/common-hal/busio/I2C.c index 046d2ba2e23..30f16276eae 100644 --- a/ports/espressif/common-hal/busio/I2C.c +++ b/ports/espressif/common-hal/busio/I2C.c @@ -6,15 +6,22 @@ #include "shared-bindings/busio/I2C.h" #include "py/mperrno.h" +#include "py/mphal.h" #include "py/runtime.h" -#include "components/driver/i2c/include/driver/i2c.h" +#include "driver/gpio.h" +#include "soc/soc_caps.h" +#include "bindings/espidf/__init__.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, - const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout_us) { + + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + // Pins 45 and 46 are "strapping" pins that impact start up behavior. They usually need to // be pulled-down so pulling them up for I2C is a bad idea. To make this hard, we don't // support I2C on these pins. @@ -60,45 +67,60 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, } #endif + + i2c_master_bus_config_t config = { + .i2c_port = -1, // auto + .sda_io_num = sda->number, + .scl_io_num = scl->number, + .clk_source = I2C_CLK_SRC_DEFAULT, + .glitch_ignore_cnt = 7, + .flags = { + #if CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP + .enable_internal_pullup = true, /*!< Internal GPIO pull mode for I2C sda signal*/ + #else + .enable_internal_pullup = false, /*!< Internal GPIO pull mode for I2C sda signal*/ + #endif + } + }; + esp_err_t result = i2c_new_master_bus(&config, &self->handle); + + if (result == ESP_ERR_NOT_FOUND) { + mp_raise_ValueError(MP_ERROR_TEXT("All I2C peripherals are in use")); + } + CHECK_ESP_RESULT(result); + + // Record which port the auto-selected bus landed on. There is no public accessor to map + // a bus handle back to its port, so match the handle against each initialized port. + // Other code (e.g. espcamera) needs the port number to reuse this same bus rather than + // create a second master bus on the same pins. + self->port = -1; + for (i2c_port_num_t port = 0; port < (int)SOC_HP_I2C_NUM; port++) { + i2c_master_bus_handle_t bus_handle; + if (i2c_master_get_bus_handle(port, &bus_handle) == ESP_OK && bus_handle == self->handle) { + self->port = port; + break; + } + } + self->xSemaphore = xSemaphoreCreateMutex(); if (self->xSemaphore == NULL) { + i2c_del_master_bus(self->handle); + self->handle = NULL; mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to create lock")); } self->sda_pin = sda; self->scl_pin = scl; - self->i2c_num = peripherals_i2c_get_free_num(); - self->has_lock = 0; - - if (self->i2c_num == I2C_NUM_MAX) { - mp_raise_ValueError(MP_ERROR_TEXT("All I2C peripherals are in use")); - } - - const i2c_config_t i2c_conf = { - .mode = I2C_MODE_MASTER, - .sda_io_num = self->sda_pin->number, - .scl_io_num = self->scl_pin->number, - #if CIRCUITPY_I2C_ALLOW_INTERNAL_PULL_UP - .sda_pullup_en = GPIO_PULLUP_ENABLE, /*!< Internal GPIO pull mode for I2C sda signal*/ - .scl_pullup_en = GPIO_PULLUP_ENABLE, /*!< Internal GPIO pull mode for I2C scl signal*/ - #else - .sda_pullup_en = GPIO_PULLUP_DISABLE, /*!< Internal GPIO pull mode for I2C sda signal*/ - .scl_pullup_en = GPIO_PULLUP_DISABLE, /*!< Internal GPIO pull mode for I2C scl signal*/ - #endif - - .master = { - .clk_speed = frequency, - } - }; + self->has_lock = false; + self->frequency = frequency; - // Initialize I2C. - esp_err_t err = peripherals_i2c_init(self->i2c_num, &i2c_conf); - if (err != ESP_OK) { - if (err == ESP_FAIL) { - mp_raise_OSError(MP_EIO); - } else { - mp_raise_RuntimeError(MP_ERROR_TEXT("init I2C")); - } - } + // Ignore the passed-in clock-stretching timeout. It is not used, as documented in shared-bindings. + // Instead use 1000 ms, which is standard across ports. + // self->timeout_ms = timeout_us / 1000; + // // Round up timeout to nearest ms. + // if (timeout_us % 1000 != 0) { + // self->timeout_ms += 1; + // } + self->timeout_ms = 1000; claim_pin(sda); claim_pin(scl); @@ -108,32 +130,37 @@ bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { return self->sda_pin == NULL; } +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + self->sda_pin = NULL; +} + void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { if (common_hal_busio_i2c_deinited(self)) { return; } - peripherals_i2c_deinit(self->i2c_num); + i2c_del_master_bus(self->handle); + self->handle = NULL; + + // Release the mutex before we delete it. Otherwise FreeRTOS gets unhappy. + xSemaphoreGive(self->xSemaphore); + vSemaphoreDelete(self->xSemaphore); + self->xSemaphore = NULL; + self->has_lock = false; common_hal_reset_pin(self->sda_pin); common_hal_reset_pin(self->scl_pin); - self->sda_pin = NULL; - self->scl_pin = NULL; -} - -static esp_err_t i2c_zero_length_write(busio_i2c_obj_t *self, uint8_t addr, TickType_t timeout) { - // i2c_master_write_to_device() won't do zero-length writes, so we do it by hand. - i2c_cmd_handle_t cmd = i2c_cmd_link_create(); - i2c_master_start(cmd); - i2c_master_write_byte(cmd, addr << 1, true); - i2c_master_stop(cmd); - esp_err_t result = i2c_master_cmd_begin(self->i2c_num, cmd, timeout); - i2c_cmd_link_delete(cmd); - return result; + common_hal_busio_i2c_mark_deinit(self); } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { - esp_err_t result = i2c_zero_length_write(self, addr, pdMS_TO_TICKS(10)); + esp_err_t result = i2c_master_probe(self->handle, addr, 10); + + #if defined(CONFIG_IDF_TARGET_ESP32S2) + // ESP32-S2 gives spurious results when probe is called multiple times in succession without this delay. + mp_hal_delay_ms(1); + #endif + return result == ESP_OK; } @@ -153,45 +180,74 @@ bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { } void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } xSemaphoreGive(self->xSemaphore); self->has_lock = false; } -static uint8_t convert_esp_err(esp_err_t result) { +static mp_negative_errno_t convert_esp_err(esp_err_t result) { switch (result) { case ESP_OK: return 0; case ESP_FAIL: - return MP_ENODEV; + return -MP_ENODEV; case ESP_ERR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: - return MP_EIO; + return -MP_EIO; } } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { - return convert_esp_err(len == 0 - ? i2c_zero_length_write(self, addr, pdMS_TO_TICKS(1000)) - : i2c_master_write_to_device(self->i2c_num, (uint8_t)addr, data, len, pdMS_TO_TICKS(1000)) - ); +static size_t _transaction_duration_ms(size_t frequency, size_t len) { + size_t khz = frequency / 1000; + size_t bytes_per_ms = khz / 8; + // + 1 for the address byte + return (len + 1) / bytes_per_ms + 1000; +} + +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { + i2c_device_config_t dev_config = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = addr, + .scl_speed_hz = self->frequency + }; + i2c_master_dev_handle_t dev_handle; + CHECK_ESP_RESULT(i2c_master_bus_add_device(self->handle, &dev_config, &dev_handle)); + esp_err_t result = i2c_master_transmit(dev_handle, data, len, _transaction_duration_ms(self->frequency, len) + self->timeout_ms); + CHECK_ESP_RESULT(i2c_master_bus_rm_device(dev_handle)); + return convert_esp_err(result); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - return convert_esp_err( - i2c_master_read_from_device(self->i2c_num, (uint8_t)addr, data, len, pdMS_TO_TICKS(1000))); +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { + i2c_device_config_t dev_config = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = addr, + .scl_speed_hz = self->frequency + }; + i2c_master_dev_handle_t dev_handle; + CHECK_ESP_RESULT(i2c_master_bus_add_device(self->handle, &dev_config, &dev_handle)); + esp_err_t result = i2c_master_receive(dev_handle, data, len, _transaction_duration_ms(self->frequency, len) + self->timeout_ms); + CHECK_ESP_RESULT(i2c_master_bus_rm_device(dev_handle)); + return convert_esp_err(result); } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - return convert_esp_err( - i2c_master_write_read_device(self->i2c_num, (uint8_t)addr, - out_data, out_len, in_data, in_len, pdMS_TO_TICKS(1000))); + i2c_device_config_t dev_config = { + .dev_addr_length = I2C_ADDR_BIT_LEN_7, + .device_address = addr, + .scl_speed_hz = self->frequency + }; + i2c_master_dev_handle_t dev_handle; + CHECK_ESP_RESULT(i2c_master_bus_add_device(self->handle, &dev_config, &dev_handle)); + esp_err_t result = i2c_master_transmit_receive(dev_handle, out_data, out_len, in_data, in_len, _transaction_duration_ms(self->frequency, out_len) + _transaction_duration_ms(self->frequency, in_len) + self->timeout_ms); + CHECK_ESP_RESULT(i2c_master_bus_rm_device(dev_handle)); + return convert_esp_err(result); } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { - never_reset_i2c(self->i2c_num); - common_hal_never_reset_pin(self->scl_pin); common_hal_never_reset_pin(self->sda_pin); } diff --git a/ports/espressif/common-hal/busio/I2C.h b/ports/espressif/common-hal/busio/I2C.h index 6e040224ece..ef69cba7091 100644 --- a/ports/espressif/common-hal/busio/I2C.h +++ b/ports/espressif/common-hal/busio/I2C.h @@ -8,18 +8,21 @@ #include "common-hal/microcontroller/Pin.h" -#include "components/hal/include/hal/i2c_types.h" +#include "hal/i2c_types.h" #include "FreeRTOS.h" #include "freertos/semphr.h" #include "py/obj.h" -#include "peripherals/i2c.h" +#include "driver/i2c_master.h" typedef struct { mp_obj_base_t base; const mcu_pin_obj_t *scl_pin; const mcu_pin_obj_t *sda_pin; - i2c_port_t i2c_num; + size_t timeout_ms; + size_t frequency; + i2c_master_bus_handle_t handle; + i2c_port_num_t port; SemaphoreHandle_t xSemaphore; bool has_lock; } busio_i2c_obj_t; diff --git a/ports/espressif/common-hal/busio/SPI.c b/ports/espressif/common-hal/busio/SPI.c index 6439ca41129..b85f8cddd2a 100644 --- a/ports/espressif/common-hal/busio/SPI.c +++ b/ports/espressif/common-hal/busio/SPI.c @@ -16,42 +16,76 @@ #define SPI_MAX_DMA_BITS (SPI_MAX_DMA_LEN * 8) #define MAX_SPI_TRANSACTIONS 10 -static bool spi_never_reset[SOC_SPI_PERIPH_NUM]; static spi_device_handle_t spi_handle[SOC_SPI_PERIPH_NUM]; -static StaticSemaphore_t spi_mutex[SOC_SPI_PERIPH_NUM]; static bool spi_bus_is_free(spi_host_device_t host_id) { return spi_bus_get_attr(host_id) == NULL; } -void spi_reset(void) { - for (spi_host_device_t host_id = SPI2_HOST; host_id < SOC_SPI_PERIPH_NUM; host_id++) { - if (spi_never_reset[host_id]) { - continue; - } - if (!spi_bus_is_free(host_id)) { - spi_bus_remove_device(spi_handle[host_id]); - spi_bus_free(host_id); - } +// Add a throwaway device at the given target clock, ask the driver what +// frequency it would actually produce, then remove it. Returns the actual +// frequency in Hz, or -1 if a device could not be added at that target. +static int spi_probe_actual_freq(busio_spi_obj_t *self, + spi_device_interface_config_t *device_config, int target_hz) { + device_config->clock_speed_hz = target_hz; + spi_device_handle_t handle; + if (spi_bus_add_device(self->host_id, device_config, &handle) != ESP_OK) { + return -1; } + int freq_khz = 0; + spi_device_get_actual_freq(handle, &freq_khz); + spi_bus_remove_device(handle); + return freq_khz * 1000; } static void set_spi_config(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { - // 128 is a 50% duty cycle. - const int closest_clock = spi_get_actual_clock(APB_CLK_FREQ, baudrate, 128); - const spi_device_interface_config_t device_config = { - .clock_speed_hz = closest_clock, + spi_device_interface_config_t device_config = { + .clock_speed_hz = baudrate, .mode = phase | (polarity << 1), .spics_io_num = -1, // No CS pin .queue_size = MAX_SPI_TRANSACTIONS, .pre_cb = NULL }; + + // The ESP-IDF driver rounds clock_speed_hz to the nearest frequency it can + // produce, which may be HIGHER than requested. Treat baudrate as a ceiling: + // probe candidate targets (each time adding a throwaway device, asking the + // driver what it actually produced, and removing it) and keep the highest + // target whose actual frequency does not exceed baudrate. We don't inspect + // divisor internals -- those vary between Espressif chips -- only the + // public add/measure/remove API. + int target = baudrate; + int actual = spi_probe_actual_freq(self, &device_config, target); + if (actual < 0 || actual > (int)baudrate) { + // Bisect for the highest target whose actual frequency is <= baudrate. + // Stop refining once the interval is within 1 kHz, the resolution that + // spi_device_get_actual_freq reports. + int lo = 1; + int hi = baudrate; + while (hi - lo > 1000) { + int mid = lo + (hi - lo) / 2; + int mid_actual = spi_probe_actual_freq(self, &device_config, mid); + if (mid_actual >= 0 && mid_actual <= (int)baudrate) { + lo = mid; + } else { + hi = mid; + } + } + target = lo; + } + + device_config.clock_speed_hz = target; esp_err_t result = spi_bus_add_device(self->host_id, &device_config, &spi_handle[self->host_id]); if (result != ESP_OK) { mp_raise_RuntimeError(MP_ERROR_TEXT("SPI configuration failed")); } - self->baudrate = closest_clock; + + // Report the frequency the driver actually settled on for the real device. + int actual_khz = 0; + spi_device_get_actual_freq(spi_handle[self->host_id], &actual_khz); + self->baudrate = actual_khz * 1000; + self->requested_baudrate = baudrate; self->polarity = polarity; self->phase = phase; self->bits = bits; @@ -61,6 +95,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + const spi_bus_config_t bus_config = { .mosi_io_num = mosi != NULL ? mosi->number : -1, .miso_io_num = miso != NULL ? miso->number : -1, @@ -90,6 +127,12 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, raise_ValueError_invalid_pins(); } + self->mutex = xSemaphoreCreateMutex(); + if (self->mutex == NULL) { + spi_bus_free(self->host_id); + mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to create lock")); + } + set_spi_config(self, 250000, 0, 0, 8); self->MOSI = mosi; @@ -103,12 +146,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, claim_pin(miso); } claim_pin(clock); - - self->mutex = xSemaphoreCreateMutexStatic(&spi_mutex[self->host_id]); } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - spi_never_reset[self->host_id] = true; common_hal_never_reset_pin(self->clock); if (self->MOSI != NULL) { common_hal_never_reset_pin(self->MOSI); @@ -122,6 +162,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -132,11 +176,10 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { RUN_BACKGROUND_TASKS; } - // Mark us as deinit early in case we are used in an interrupt. + // Mark as deinit early in case we are used in an interrupt. common_hal_reset_pin(self->clock); - self->clock = NULL; + common_hal_busio_spi_mark_deinit(self); - spi_never_reset[self->host_id] = false; spi_bus_remove_device(spi_handle[self->host_id]); spi_bus_free(self->host_id); @@ -151,7 +194,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { - if (baudrate == self->baudrate && + if (baudrate == self->requested_baudrate && polarity == self->polarity && phase == self->phase && bits == self->bits) { @@ -162,19 +205,27 @@ bool common_hal_busio_spi_configure(busio_spi_obj_t *self, return true; } -bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { +// Wait as long as needed for the lock. This is used by SD card access from USB. +// Overrides the default busy-wait implementation in shared-bindings/busio/SPI.c +bool common_hal_busio_spi_wait_for_lock(busio_spi_obj_t *self, uint32_t timeout_ms) { if (common_hal_busio_spi_deinited(self)) { return false; } - return xSemaphoreTake(self->mutex, 1) == pdTRUE; + return xSemaphoreTake(self->mutex, pdMS_TO_TICKS(timeout_ms)) == pdTRUE; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + return common_hal_busio_spi_wait_for_lock(self, 0); } bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { - return self->mutex != NULL && xSemaphoreGetMutexHolder(self->mutex) == xTaskGetCurrentTaskHandle(); + return (self->mutex != NULL) && (xSemaphoreGetMutexHolder(self->mutex) == xTaskGetCurrentTaskHandle()); } void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { - xSemaphoreGive(self->mutex); + if (self->mutex != NULL) { + xSemaphoreGive(self->mutex); + } } bool common_hal_busio_spi_write(busio_spi_obj_t *self, diff --git a/ports/espressif/common-hal/busio/SPI.h b/ports/espressif/common-hal/busio/SPI.h index 820f29333c7..4886ab173ab 100644 --- a/ports/espressif/common-hal/busio/SPI.h +++ b/ports/espressif/common-hal/busio/SPI.h @@ -21,9 +21,8 @@ typedef struct { uint8_t bits; uint8_t phase; uint8_t polarity; - uint32_t baudrate; + uint32_t baudrate; // Actual frequency, reported by the frequency property. + uint32_t requested_baudrate; // Value passed to configure(); used for the cache-hit check. SemaphoreHandle_t mutex; } busio_spi_obj_t; - -void spi_reset(void); diff --git a/ports/espressif/common-hal/busio/UART.c b/ports/espressif/common-hal/busio/UART.c index ad5e6fcef1b..01c8321843a 100644 --- a/ports/espressif/common-hal/busio/UART.c +++ b/ports/espressif/common-hal/busio/UART.c @@ -140,7 +140,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, uart_config.flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS; } else if (have_rts) { uart_config.flow_ctrl = UART_HW_FLOWCTRL_RTS; - } else if (have_rts) { + } else if (have_cts) { uart_config.flow_ctrl = UART_HW_FLOWCTRL_CTS; } diff --git a/ports/espressif/common-hal/digitalio/DigitalInOut.c b/ports/espressif/common-hal/digitalio/DigitalInOut.c index ed537419405..e4272ba1ff5 100644 --- a/ports/espressif/common-hal/digitalio/DigitalInOut.c +++ b/ports/espressif/common-hal/digitalio/DigitalInOut.c @@ -11,8 +11,11 @@ #include "hal/gpio_hal.h" static bool _pin_is_input(uint8_t pin_number) { - const uint32_t iomux = READ_PERI_REG(GPIO_PIN_MUX_REG[pin_number]); - return (iomux & FUN_IE) != 0; + gpio_io_config_t config; + if (gpio_get_io_config((gpio_num_t)pin_number, &config) != ESP_OK) { + return false; + } + return config.ie; } void digitalio_digitalinout_preserve_for_deep_sleep(size_t n_dios, digitalio_digitalinout_obj_t *preserve_dios[]) { @@ -113,10 +116,12 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( digitalio_digitalinout_obj_t *self) { - if (GPIO_HAL_GET_HW(GPIO_PORT_0)->pin[self->pin->number].pad_driver == 1) { + gpio_io_config_t config; + if (gpio_get_io_config((gpio_num_t)self->pin->number, &config) != ESP_OK) { + // Should it fail closed or open? return DRIVE_MODE_OPEN_DRAIN; } - return DRIVE_MODE_PUSH_PULL; + return config.od ? DRIVE_MODE_OPEN_DRAIN : DRIVE_MODE_PUSH_PULL; } digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( @@ -134,11 +139,10 @@ digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( digitalio_digitalinout_obj_t *self) { - gpio_num_t gpio_num = self->pin->number; - if (REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PU)) { - return PULL_UP; - } else if (REG_GET_BIT(GPIO_PIN_MUX_REG[gpio_num], FUN_PD)) { - return PULL_DOWN; + gpio_io_config_t config; + if (gpio_get_io_config((gpio_num_t)self->pin->number, &config) != ESP_OK) { + // Should it fail closed or open? + return PULL_NONE; } - return PULL_NONE; + return config.pd ? PULL_DOWN : PULL_UP; } diff --git a/ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c b/ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c index 591c455722e..5df379432a9 100644 --- a/ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c +++ b/ports/espressif/common-hal/dotclockframebuffer/DotClockFramebuffer.c @@ -14,7 +14,7 @@ #include "hal/dma_types.h" #include "hal/lcd_hal.h" #include "hal/lcd_ll.h" -#include "soc/lcd_periph.h" +#include "hal/lcd_periph.h" #include "esp_log.h" #define TAG "LCD" @@ -109,8 +109,7 @@ void common_hal_dotclockframebuffer_framebuffer_construct(dotclockframebuffer_fr cfg->timings.flags.pclk_idle_high = pclk_idle_high; cfg->data_width = 16; - cfg->sram_trans_align = 8; - cfg->psram_trans_align = 64; + cfg->dma_burst_size = 64; cfg->hsync_gpio_num = valid_pin(hsync, MP_QSTR_hsync); cfg->vsync_gpio_num = valid_pin(vsync, MP_QSTR_vsync); cfg->de_gpio_num = valid_pin(de, MP_QSTR_de); diff --git a/ports/espressif/common-hal/espcamera/Camera.c b/ports/espressif/common-hal/espcamera/Camera.c index bcf4732fcd8..c8f693fa3f1 100644 --- a/ports/espressif/common-hal/espcamera/Camera.c +++ b/ports/espressif/common-hal/espcamera/Camera.c @@ -21,6 +21,11 @@ #error espcamera only works on boards configured with spiram, disable it in mpconfigboard.mk #endif +// The underlying esp-camera driver only handles a singleton camera. +// Track it here so it can be reset, releasing its +// device on the shared I2C bus, before the I2C bus is deinited. +static espcamera_camera_obj_t *live_camera = NULL; + static void i2c_lock(espcamera_camera_obj_t *self) { if (common_hal_busio_i2c_deinited(self->i2c)) { raise_deinited_error(); @@ -77,13 +82,20 @@ void common_hal_espcamera_camera_construct( self->i2c = i2c; - self->camera_config.pin_pwdn = common_hal_mcu_pin_number(powerdown_pin); - self->camera_config.pin_reset = common_hal_mcu_pin_number(reset_pin); - self->camera_config.pin_xclk = common_hal_mcu_pin_number(external_clock_pin); - - self->camera_config.pin_sccb_sda = NO_PIN; - self->camera_config.pin_sccb_scl = NO_PIN; - /* sccb i2c port set below */ + // These pins might be NULL because they were not specified. + // Note that common_hal_mcu_pin_number() returns NO_PIN (- =1) if pass NULL, but as a `uint8_t`, + // so it becomes 255. The camera driver expects non-specified pins to be < 0. + // So we have to set the pins to NO_PIN explicitly, + // instead of relying on the return value from common_hal_mcu_pin_number(). + self->camera_config.pin_pwdn = powerdown_pin ? common_hal_mcu_pin_number(powerdown_pin) : NO_PIN; + self->camera_config.pin_reset = reset_pin ? common_hal_mcu_pin_number(reset_pin) : NO_PIN; + self->camera_config.pin_xclk = external_clock_pin ? common_hal_mcu_pin_number(external_clock_pin) : NO_PIN; + + // Reuse the I2C bus that CircuitPython already created on these pins instead of letting + // esp32-camera create a second master bus on the same pins, which doesn't work. + self->camera_config.pin_sccb_sda = -1; + self->camera_config.pin_sccb_scl = -1; + self->camera_config.sccb_i2c_port = i2c->port; self->camera_config.pin_d7 = data_pins[7]; self->camera_config.pin_d6 = data_pins[6]; @@ -106,13 +118,23 @@ void common_hal_espcamera_camera_construct( self->camera_config.fb_count = framebuffer_count; self->camera_config.grab_mode = grab_mode; - self->camera_config.sccb_i2c_port = i2c->i2c_num; + i2c_lock(self); esp_err_t result = esp_camera_init(&self->camera_config); i2c_unlock(self); CHECK_ESP_RESULT(result); + + // Only record the camera once esp_camera_init() has succeeded, so a failed + // second construction doesn't overwrite the live singleton. + live_camera = self; +} + +void espcamera_reset(void) { + if (live_camera != NULL) { + common_hal_espcamera_camera_deinit(live_camera); + } } extern void common_hal_espcamera_camera_deinit(espcamera_camera_obj_t *self) { @@ -120,8 +142,17 @@ extern void common_hal_espcamera_camera_deinit(espcamera_camera_obj_t *self) { return; } + // Only tear down the shared esp-camera driver if this object owns it. A + // second, failed construction leaves live_camera pointing at the first + // camera; deiniting that failed object must not destroy the live one. + bool was_live = (live_camera == self); + if (was_live) { + live_camera = NULL; + } + common_hal_pwmio_pwmout_deinit(&self->pwm); + // Does nothing if pin is NO_PIN (-1). reset_pin_number(self->camera_config.pin_pwdn); reset_pin_number(self->camera_config.pin_reset); reset_pin_number(self->camera_config.pin_xclk); @@ -135,7 +166,9 @@ extern void common_hal_espcamera_camera_deinit(espcamera_camera_obj_t *self) { reset_pin_number(self->camera_config.pin_d1); reset_pin_number(self->camera_config.pin_d0); - esp_camera_deinit(); + if (was_live) { + esp_camera_deinit(); + } reset_pin_number(self->camera_config.pin_pclk); reset_pin_number(self->camera_config.pin_vsync); @@ -149,7 +182,7 @@ bool common_hal_espcamera_camera_deinited(espcamera_camera_obj_t *self) { } bool common_hal_espcamera_camera_available(espcamera_camera_obj_t *self) { - return esp_camera_fb_available(); + return esp_camera_available_frames(); } camera_fb_t *common_hal_espcamera_camera_take(espcamera_camera_obj_t *self, int timeout_ms) { diff --git a/ports/espressif/common-hal/espcamera/Camera.h b/ports/espressif/common-hal/espcamera/Camera.h index 718fe9a69c4..dd099558aa6 100644 --- a/ports/espressif/common-hal/espcamera/Camera.h +++ b/ports/espressif/common-hal/espcamera/Camera.h @@ -18,3 +18,7 @@ typedef struct espcamera_camera_obj { pwmio_pwmout_obj_t pwm; busio_i2c_obj_t *i2c; } espcamera_obj_t; + +// Deinitialize the active camera, if any, so it releases its device on the +// shared I2C bus. Called from reset_port_early(). +void espcamera_reset(void); diff --git a/ports/espressif/common-hal/espnow/ESPNow.c b/ports/espressif/common-hal/espnow/ESPNow.c index 79bded96fb4..eb3b57174a3 100644 --- a/ports/espressif/common-hal/espnow/ESPNow.c +++ b/ports/espressif/common-hal/espnow/ESPNow.c @@ -17,6 +17,7 @@ #include "common-hal/espnow/ESPNow.h" +#include "esp_now.h" #include "mphalport.h" #include "esp_now.h" @@ -56,7 +57,7 @@ typedef struct { // Callback triggered when a sent packet is acknowledged by the peer (or not). // Just count the number of responses and number of failures. // These are used in the send() logic. -static void send_cb(const uint8_t *mac, esp_now_send_status_t status) { +static void send_cb(const esp_now_send_info_t *tx_info, esp_now_send_status_t status) { espnow_obj_t *self = MP_STATE_PORT(espnow_singleton); if (status == ESP_NOW_SEND_SUCCESS) { self->send_success++; @@ -119,10 +120,20 @@ void common_hal_espnow_init(espnow_obj_t *self) { common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, true); } - CHECK_ESP_RESULT(esp_wifi_config_espnow_rate(ESP_IF_WIFI_STA, self->phy_rate)); - CHECK_ESP_RESULT(esp_wifi_config_espnow_rate(ESP_IF_WIFI_AP, self->phy_rate)); - CHECK_ESP_RESULT(esp_now_init()); + + // esp_now_set_peer_rate_config() is poorly documented, and we haven't figured out + // what the esp_now_rate_config_t settings should be. For now, just ignore phy_rate. + // Note that esp_now_set_peer_rate_config() must be called after esp_now-init(). + // + // esp_now_rate_config_t rate_config = { + // .phymode = WIFI_PHY_MODE_LR, + // .rate = self->phy_rate, + // .ersu = false, + // .dcm = false, + // }; + // CHECK_ESP_RESULT(esp_now_set_peer_rate_config(NULL, &rate_config)); + CHECK_ESP_RESULT(esp_now_register_send_cb(send_cb)); CHECK_ESP_RESULT(esp_now_register_recv_cb(recv_cb)); } diff --git a/ports/espressif/common-hal/frequencyio/FrequencyIn.c b/ports/espressif/common-hal/frequencyio/FrequencyIn.c index 96644348504..72fb36e0b91 100644 --- a/ports/espressif/common-hal/frequencyio/FrequencyIn.c +++ b/ports/espressif/common-hal/frequencyio/FrequencyIn.c @@ -117,7 +117,7 @@ void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t self->pin = pin->number; self->capture_period_ms = capture_period_ms; - self->internal_data = heap_caps_malloc(MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL, sizeof(_internal_data_t)); + self->internal_data = heap_caps_malloc(sizeof(_internal_data_t), MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); if (self->internal_data == NULL) { raise_esp_error(ESP_ERR_NO_MEM); } diff --git a/ports/espressif/common-hal/i2ctarget/I2CTarget.c b/ports/espressif/common-hal/i2ctarget/I2CTarget.c index 003e7731faa..648f71e6953 100644 --- a/ports/espressif/common-hal/i2ctarget/I2CTarget.c +++ b/ports/espressif/common-hal/i2ctarget/I2CTarget.c @@ -12,6 +12,19 @@ #include "common-hal/i2ctarget/I2CTarget.h" #include "shared-bindings/microcontroller/Pin.h" +static bool i2c_slave_on_receive(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg) { + i2ctarget_i2c_target_obj_t *self = (i2ctarget_i2c_target_obj_t *)arg; + for (uint32_t i = 0; i < evt_data->length; i++) { + uint16_t next_head = (self->recv_head + 1) % I2CTARGET_RECV_BUF_SIZE; + if (next_head == self->recv_tail) { + break; // buffer full + } + self->recv_buf[self->recv_head] = evt_data->buffer[i]; + self->recv_head = next_head; + } + return false; +} + void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint8_t *addresses, unsigned int num_addresses, bool smbus) { @@ -31,32 +44,40 @@ void common_hal_i2ctarget_i2c_target_construct(i2ctarget_i2c_target_obj_t *self, self->sda_pin = sda; self->scl_pin = scl; - self->i2c_num = peripherals_i2c_get_free_num(); - if (self->i2c_num == I2C_NUM_MAX) { - mp_raise_ValueError(MP_ERROR_TEXT("All I2C peripherals are in use")); - } - - const i2c_config_t i2c_conf = { - .mode = I2C_MODE_SLAVE, - .sda_io_num = self->sda_pin->number, - .scl_io_num = self->scl_pin->number, - .sda_pullup_en = GPIO_PULLUP_ENABLE, - .scl_pullup_en = GPIO_PULLUP_ENABLE, - .slave.addr_10bit_en = 0, - .slave.slave_addr = self->addresses[0], + self->recv_head = 0; + self->recv_tail = 0; + + i2c_slave_config_t slave_config = { + .i2c_port = -1, // auto + .sda_io_num = sda->number, + .scl_io_num = scl->number, + .clk_source = I2C_CLK_SRC_DEFAULT, + .send_buf_depth = 256, + .receive_buf_depth = 256, + .slave_addr = addresses[0], + .addr_bit_len = I2C_ADDR_BIT_LEN_7, + .flags = { + .enable_internal_pullup = true, + }, }; - // Initialize I2C. - esp_err_t err = peripherals_i2c_init(self->i2c_num, &i2c_conf); + esp_err_t err = i2c_new_slave_device(&slave_config, &self->handle); if (err != ESP_OK) { - if (err == ESP_FAIL) { + if (err == ESP_ERR_NOT_FOUND) { + mp_raise_ValueError(MP_ERROR_TEXT("All I2C peripherals are in use")); + } else if (err == ESP_FAIL) { mp_raise_OSError(MP_EIO); } else { mp_arg_error_invalid(MP_QSTR_I2CTarget); } } + i2c_slave_event_callbacks_t cbs = { + .on_receive = i2c_slave_on_receive, + }; + i2c_slave_register_event_callbacks(self->handle, &cbs, self); + claim_pin(sda); claim_pin(scl); } @@ -70,7 +91,8 @@ void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) { return; } - peripherals_i2c_deinit(self->i2c_num); + i2c_del_slave_device(self->handle); + self->handle = NULL; common_hal_reset_pin(self->sda_pin); common_hal_reset_pin(self->scl_pin); @@ -83,24 +105,34 @@ int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *sel *address = self->addresses[0]; *is_read = true; *is_restart = false; - return 1; + // Check if we have received data + if (self->recv_head != self->recv_tail) { + *is_read = false; + return 1; + } + return 0; } int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) { - i2c_slave_read_buffer(self->i2c_num, data, 128, 0); + if (self->recv_head == self->recv_tail) { + return 0; // no data available + } + *data = self->recv_buf[self->recv_tail]; + self->recv_tail = (self->recv_tail + 1) % I2CTARGET_RECV_BUF_SIZE; return 1; } int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) { - i2c_reset_tx_fifo(self->i2c_num); - i2c_slave_write_buffer(self->i2c_num, &data, 128, 0); + uint32_t write_len; + esp_err_t err = i2c_slave_write(self->handle, &data, 1, &write_len, 100); + if (err != ESP_OK || write_len == 0) { + return 0; + } return 1; } void common_hal_i2ctarget_i2c_target_ack(i2ctarget_i2c_target_obj_t *self, bool ack) { - } void common_hal_i2ctarget_i2c_target_close(i2ctarget_i2c_target_obj_t *self) { - } diff --git a/ports/espressif/common-hal/i2ctarget/I2CTarget.h b/ports/espressif/common-hal/i2ctarget/I2CTarget.h index 2dcfb581eb3..fc41ac84ebc 100644 --- a/ports/espressif/common-hal/i2ctarget/I2CTarget.h +++ b/ports/espressif/common-hal/i2ctarget/I2CTarget.h @@ -7,14 +7,19 @@ #pragma once #include "py/obj.h" -#include "peripherals/i2c.h" +#include "driver/i2c_slave.h" #include "common-hal/microcontroller/Pin.h" +#define I2CTARGET_RECV_BUF_SIZE 128 + typedef struct { mp_obj_base_t base; - i2c_port_t i2c_num; + i2c_slave_dev_handle_t handle; uint8_t *addresses; uint8_t num_addresses; const mcu_pin_obj_t *scl_pin; const mcu_pin_obj_t *sda_pin; + uint8_t recv_buf[I2CTARGET_RECV_BUF_SIZE]; + volatile uint16_t recv_head; + volatile uint16_t recv_tail; } i2ctarget_i2c_target_obj_t; diff --git a/ports/espressif/common-hal/mdns/RemoteService.c b/ports/espressif/common-hal/mdns/RemoteService.c index 515a3f7bf02..3d80199397e 100644 --- a/ports/espressif/common-hal/mdns/RemoteService.c +++ b/ports/espressif/common-hal/mdns/RemoteService.c @@ -9,56 +9,27 @@ #include "shared-bindings/ipaddress/IPv4Address.h" const char *common_hal_mdns_remoteservice_get_service_type(mdns_remoteservice_obj_t *self) { - if (self->result == NULL) { - return ""; - } - return self->result->service_type; + return self->service_name; } const char *common_hal_mdns_remoteservice_get_protocol(mdns_remoteservice_obj_t *self) { - if (self->result == NULL) { - return ""; - } - return self->result->proto; + return self->protocol; } const char *common_hal_mdns_remoteservice_get_instance_name(mdns_remoteservice_obj_t *self) { - if (self->result == NULL) { - return ""; - } - return self->result->instance_name; + return self->instance_name; } const char *common_hal_mdns_remoteservice_get_hostname(mdns_remoteservice_obj_t *self) { - if (self->result == NULL) { - return ""; - } - return self->result->hostname; + return self->hostname; } mp_int_t common_hal_mdns_remoteservice_get_port(mdns_remoteservice_obj_t *self) { - if (self->result == NULL) { - return 0; - } - return self->result->port; + return self->port; } uint32_t mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) { - if (self->result == NULL || - self->result->ip_protocol != MDNS_IP_PROTOCOL_V4 || - self->result->addr == NULL) { - return 0; - } - mdns_ip_addr_t *cur = self->result->addr; - while (cur != NULL) { - if (cur->addr.type == ESP_IPADDR_TYPE_V4) { - return cur->addr.u_addr.ip4.addr; - } - - cur = cur->next; - } - - return 0; + return self->ipv4_address; } mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self) { @@ -68,8 +39,3 @@ mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t } return common_hal_ipaddress_new_ipv4address(addr); } - -void common_hal_mdns_remoteservice_deinit(mdns_remoteservice_obj_t *self) { - mdns_query_results_free(self->result); - self->result = NULL; -} diff --git a/ports/espressif/common-hal/mdns/RemoteService.h b/ports/espressif/common-hal/mdns/RemoteService.h index 6fb3000c7d1..89ff69be29d 100644 --- a/ports/espressif/common-hal/mdns/RemoteService.h +++ b/ports/espressif/common-hal/mdns/RemoteService.h @@ -8,7 +8,15 @@ #include "mdns.h" +// The IDF's mdns_result_t lives on the IDF heap and is only valid while mdns +// is inited. Copy what we need into the object instead so that the object's +// lifetime is independent of the mdns.Server's. typedef struct { mp_obj_base_t base; - mdns_result_t *result; + uint32_t ipv4_address; + uint16_t port; + char protocol[5]; // RFC 6763 Section 7.2 - 4 bytes + 1 for NUL + char service_name[17]; // RFC 6763 Section 7.2 - 16 bytes + 1 for NUL + char instance_name[64]; // RFC 6763 Section 7.2 - 63 bytes + 1 for NUL + char hostname[64]; // RFC 6762 Appendix A - 63 bytes for label + 1 for NUL } mdns_remoteservice_obj_t; diff --git a/ports/espressif/common-hal/mdns/Server.c b/ports/espressif/common-hal/mdns/Server.c index 81a4415cecd..7eaa9a442a2 100644 --- a/ports/espressif/common-hal/mdns/Server.c +++ b/ports/espressif/common-hal/mdns/Server.c @@ -6,6 +6,8 @@ #include "shared-bindings/mdns/Server.h" +#include + #include "py/gc.h" #include "py/runtime.h" #include "shared-bindings/mdns/RemoteService.h" @@ -18,6 +20,13 @@ // could be created.) static mdns_server_obj_t *_active_object = NULL; +// strlcpy(), but a NULL src yields an empty string instead of undefined +// behavior. The IDF leaves mdns_result_t fields NULL when a query didn't +// resolve them. +static void strlcpy_or_empty(char *dest, const char *src, size_t dest_len) { + strlcpy(dest, src == NULL ? "" : src, dest_len); +} + void mdns_server_construct(mdns_server_obj_t *self, bool workflow) { if (_active_object != NULL) { if (self == _active_object) { @@ -33,10 +42,12 @@ void mdns_server_construct(mdns_server_obj_t *self, bool workflow) { } _active_object = self; - uint8_t mac[6]; - esp_netif_get_mac(common_hal_wifi_radio_obj.netif, mac); - snprintf(self->default_hostname, sizeof(self->default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]); - common_hal_mdns_server_set_hostname(self, self->default_hostname); + self->instance_name[0] = '\0'; + + // Match the netif hostname set when `import wifi` was called. + const char *netif_hostname; + esp_netif_get_hostname(common_hal_wifi_radio_obj.netif, &netif_hostname); + common_hal_mdns_server_set_hostname(self, netif_hostname); self->inited = true; @@ -96,11 +107,11 @@ void common_hal_mdns_server_set_hostname(mdns_server_obj_t *self, const char *ho while (!mdns_hostname_exists(hostname)) { RUN_BACKGROUND_TASKS; } - self->hostname = hostname; + strlcpy_or_empty(self->hostname, hostname, sizeof(self->hostname)); } const char *common_hal_mdns_server_get_instance_name(mdns_server_obj_t *self) { - if (self->instance_name == NULL) { + if (self->instance_name[0] == '\0') { return self->hostname; } return self->instance_name; @@ -108,7 +119,28 @@ const char *common_hal_mdns_server_get_instance_name(mdns_server_obj_t *self) { void common_hal_mdns_server_set_instance_name(mdns_server_obj_t *self, const char *instance_name) { mdns_instance_name_set(instance_name); - self->instance_name = instance_name; + strlcpy_or_empty(self->instance_name, instance_name, sizeof(self->instance_name)); +} + +// Copy everything we expose out of the IDF's result so that the RemoteService +// no longer references IDF-owned memory. The caller is responsible for freeing +// the result itself. +static void copy_data_into_remote_service(mdns_result_t *result, mdns_remoteservice_obj_t *out) { + out->base.type = &mdns_remoteservice_type; + out->port = result->port; + out->ipv4_address = 0; + if (result->ip_protocol == MDNS_IP_PROTOCOL_V4) { + for (mdns_ip_addr_t *cur = result->addr; cur != NULL; cur = cur->next) { + if (cur->addr.type == ESP_IPADDR_TYPE_V4) { + out->ipv4_address = cur->addr.u_addr.ip4.addr; + break; + } + } + } + strlcpy_or_empty(out->protocol, result->proto, sizeof(out->protocol)); + strlcpy_or_empty(out->service_name, result->service_type, sizeof(out->service_name)); + strlcpy_or_empty(out->instance_name, result->instance_name, sizeof(out->instance_name)); + strlcpy_or_empty(out->hostname, result->hostname, sizeof(out->hostname)); } size_t mdns_server_find(mdns_server_obj_t *self, const char *service_type, const char *protocol, @@ -124,23 +156,15 @@ size_t mdns_server_find(mdns_server_obj_t *self, const char *service_type, const } mdns_query_async_delete(search); mdns_result_t *next = results; - // Don't error if we're out of memory. Instead, truncate the tuple. - uint8_t added = 0; + // Truncate if we don't have space for everything the IDF found. + size_t added = 0; while (next != NULL && added < out_len) { - mdns_remoteservice_obj_t *service = &out[added]; - - service->result = next; - service->base.type = &mdns_remoteservice_type; + copy_data_into_remote_service(next, &out[added]); next = next->next; - // Break the linked list so we free each result separately. - service->result->next = NULL; added++; } - if (added < out_len) { - // Free the remaining results from the IDF because we don't have - // enough space in Python. - mdns_query_results_free(next); - } + // We've copied out everything we need, so release the IDF's copy. + mdns_query_results_free(results); return num_results; } @@ -159,36 +183,40 @@ mp_obj_t common_hal_mdns_server_find(mdns_server_obj_t *self, const char *servic // The empty tuple object is shared and stored in flash so return early if // we got it. Without this we'll crash when trying to set len below. if (num_results == 0) { + mdns_query_results_free(results); return MP_OBJ_FROM_PTR(tuple); } mdns_result_t *next = results; // Don't error if we're out of memory. Instead, truncate the tuple. uint8_t added = 0; while (next != NULL) { - mdns_remoteservice_obj_t *service = gc_alloc(sizeof(mdns_remoteservice_obj_t), GC_ALLOC_FLAG_HAS_FINALISER); + mdns_remoteservice_obj_t *service = m_malloc_maybe(sizeof(mdns_remoteservice_obj_t)); if (service == NULL) { if (added == 0) { + mdns_query_results_free(results); m_malloc_fail(sizeof(mdns_remoteservice_obj_t)); } - // Free the remaining results from the IDF because we don't have - // enough space in Python. - mdns_query_results_free(next); break; } - service->result = next; - service->base.type = &mdns_remoteservice_type; + copy_data_into_remote_service(next, service); next = next->next; - // Break the linked list so we free each result separately. - service->result->next = NULL; tuple->items[added] = MP_OBJ_FROM_PTR(service); added++; } tuple->len = added; + // We've copied out everything we need, so release the IDF's copy. + mdns_query_results_free(results); + return MP_OBJ_FROM_PTR(tuple); } void common_hal_mdns_server_advertise_service(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_int_t port, const char *txt_records[], size_t num_txt_records) { + // Reject rather than silently drop them. See the TODO below. + if (num_txt_records > 0) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_txt_records); + } + if (mdns_service_exists(service_type, protocol, NULL)) { mdns_service_port_set(service_type, protocol, port); } else { diff --git a/ports/espressif/common-hal/mdns/Server.h b/ports/espressif/common-hal/mdns/Server.h index 42ffd878d13..e7bfabb9528 100644 --- a/ports/espressif/common-hal/mdns/Server.h +++ b/ports/espressif/common-hal/mdns/Server.h @@ -10,9 +10,11 @@ typedef struct { mp_obj_base_t base; - const char *hostname; - const char *instance_name; - char default_hostname[sizeof("cpy-XXXXXX")]; + // Store copies rather than the caller's pointers. The setters are handed + // GC-heap strings, which are recycled when the VM resets while this object + // (and the web workflow's static one) lives on. + char hostname[64]; // RFC 6762 Appendix A - 63 bytes for label + 1 for NUL + char instance_name[64]; // RFC 6763 Section 7.2 - 63 bytes + 1 for NUL // Track if this object owns access to the underlying MDNS service. bool inited; } mdns_server_obj_t; diff --git a/ports/espressif/common-hal/microcontroller/Pin.c b/ports/espressif/common-hal/microcontroller/Pin.c index 70912afb545..34b9578d580 100644 --- a/ports/espressif/common-hal/microcontroller/Pin.c +++ b/ports/espressif/common-hal/microcontroller/Pin.c @@ -7,6 +7,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/alarm/__init__.h" #include "py/mphal.h" @@ -77,6 +78,15 @@ static uint64_t _in_use_pin_mask; #define GPIO_SEL_47 ((uint64_t)PIN_BIT(47)) /*!< Pin 47 selected */ #define GPIO_SEL_48 ((uint64_t)PIN_BIT(48)) /*!< Pin 48 selected */ #endif +#if SOC_GPIO_PIN_COUNT > 49 +#define GPIO_SEL_49 ((uint64_t)PIN_BIT(49)) /*!< Pin 49 selected */ +#define GPIO_SEL_50 ((uint64_t)PIN_BIT(50)) /*!< Pin 50 selected */ +#define GPIO_SEL_51 ((uint64_t)PIN_BIT(51)) /*!< Pin 51 selected */ +#define GPIO_SEL_52 ((uint64_t)PIN_BIT(52)) /*!< Pin 52 selected */ +#define GPIO_SEL_53 ((uint64_t)PIN_BIT(53)) /*!< Pin 53 selected */ +#define GPIO_SEL_54 ((uint64_t)PIN_BIT(54)) /*!< Pin 54 selected */ +#define GPIO_SEL_55 ((uint64_t)PIN_BIT(55)) /*!< Pin 55 selected */ +#endif // Bit mask of all pins that should never EVER be reset. // Typically these are SPI flash and PSRAM control pins, and communication pins. @@ -146,6 +156,29 @@ static const uint64_t pin_mask_reset_forbidden = #endif #endif // ESP32C6 + #if defined(CONFIG_IDF_TARGET_ESP32C61) + // Never ever reset pins used to communicate with SPI flash. + GPIO_SEL_15 | // SPICS0 (flash CS#) + GPIO_SEL_16 | // SPIQ (MISO/SIO1) + GPIO_SEL_17 | // SPIWP (WP#/SIO2) + GPIO_SEL_19 | // SPIHD (HOLD#/SIO3) + GPIO_SEL_20 | // SPICLK (CLK) + GPIO_SEL_21 | // SPID (MOSI/SIO0) + #if CIRCUITPY_ESP_USB_SERIAL_JTAG + // Never ever reset serial/JTAG communication pins. + GPIO_SEL_12 | // USB D- + GPIO_SEL_13 | // USB D+ + #endif + #if defined(CONFIG_SPIRAM) + GPIO_SEL_14 | // SPICS1 (PSRAM CS#); keep if PSRAM in use + #endif + #if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) && CONFIG_ESP_CONSOLE_UART_DEFAULT && CONFIG_ESP_CONSOLE_UART_NUM == 0 + // Never reset debug UART/console pins. + GPIO_SEL_10 | + GPIO_SEL_11 | + #endif + #endif // ESP32C6 + #if defined(CONFIG_IDF_TARGET_ESP32H2) // Never ever reset pins used to communicate with the in-package SPI flash. GPIO_SEL_15 | @@ -172,17 +205,27 @@ static const uint64_t pin_mask_reset_forbidden = #endif // ESP32H2 #if defined(CONFIG_IDF_TARGET_ESP32P4) - // Never ever reset pins used to communicate with the SPI flash. - GPIO_SEL_28 | - GPIO_SEL_29 | - GPIO_SEL_30 | - GPIO_SEL_32 | - GPIO_SEL_33 | - GPIO_SEL_34 | - #if CIRCUITPY_ESP_USB_SERIAL_JTAG + // SPI flash is on dedicated pins. + + // USB is on the FS OTG + #if CIRCUITPY_USB_DEVICE_INSTANCE == 0 + #if CIRCUITPY_ESP32P4_SWAP_LSFS == 1 + // We leave 24 and 25 alone in addition to 26 and 27 when swapped. It doesn't work otherwise. (Not sure why.) + GPIO_SEL_24 | // USB D- + GPIO_SEL_25 | // USB D+ + #endif + GPIO_SEL_26 | // USB D- + GPIO_SEL_27 | // USB D+ + #endif + #if CIRCUITPY_ESP_USB_SERIAL_JTAG || (defined(CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) && CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG) // Never ever reset serial/JTAG communication pins. - GPIO_SEL_50 | // USB D- - GPIO_SEL_51 | // USB D+ + #if CIRCUITPY_ESP32P4_SWAP_LSFS == 1 + GPIO_SEL_26 | // USB D- + GPIO_SEL_27 | // USB D+ + #else + GPIO_SEL_24 | // USB D- + GPIO_SEL_25 | // USB D+ + #endif #endif #if defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) && CONFIG_ESP_CONSOLE_UART_DEFAULT && CONFIG_ESP_CONSOLE_UART_NUM == 0 // Never reset debug UART/console pins. @@ -326,7 +369,7 @@ void preserve_pin_number(gpio_num_t pin_number) { } } -void clear_pin_preservations(void) { +void common_hal_alarm_clear_pin_preservations(void) { _preserved_pin_mask = 0; } @@ -370,9 +413,8 @@ void reset_all_pins(void) { gpio_deep_sleep_hold_dis(); #endif - for (uint8_t i = 0; i < GPIO_PIN_COUNT; i++) { - uint32_t iomux_address = GPIO_PIN_MUX_REG[i]; - if (iomux_address == 0 || + for (gpio_num_t i = 0; i < SOC_GPIO_PIN_COUNT; i++) { + if (!GPIO_IS_VALID_GPIO(i) || _never_reset(i) || _skip_reset_once(i) || _preserved_pin(i)) { diff --git a/ports/espressif/common-hal/microcontroller/Pin.h b/ports/espressif/common-hal/microcontroller/Pin.h index aba7fa68323..7925ac9f8de 100644 --- a/ports/espressif/common-hal/microcontroller/Pin.h +++ b/ports/espressif/common-hal/microcontroller/Pin.h @@ -29,7 +29,6 @@ extern bool pin_number_is_free(gpio_num_t pin_number); extern void never_reset_pin_number(gpio_num_t pin_number); extern void preserve_pin_number(gpio_num_t pin_number); -extern void clear_pin_preservations(void); // Allow the board to reset a pin in a board-specific way. This can be used // for LEDs or enable pins to put them in a state beside the default pull-up. diff --git a/ports/espressif/common-hal/microcontroller/Processor.c b/ports/espressif/common-hal/microcontroller/Processor.c index 8a6a14c0236..72c9845241c 100644 --- a/ports/espressif/common-hal/microcontroller/Processor.c +++ b/ports/espressif/common-hal/microcontroller/Processor.c @@ -59,7 +59,7 @@ uint32_t common_hal_mcu_processor_get_frequency(void) { // If the requested frequency is not supported by the hardware, return the next lower supported frequency static uint32_t get_valid_cpu_frequency(uint32_t requested_freq_mhz) { - #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + #if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) uint32_t valid_cpu_frequencies[] = {20, 40, 80, 160}; #elif defined(CONFIG_IDF_TARGET_ESP32C2) uint32_t valid_cpu_frequencies[] = {20, 40, 80, 120}; @@ -126,6 +126,8 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SYS_0_REG); #elif defined(CONFIG_IDF_TARGET_ESP32C2) uint32_t mac_address_part = REG_READ(EFUSE_RD_BLK2_DATA0_REG); + #elif defined(CONFIG_IDF_TARGET_ESP32C61) + uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SYS0_REG); #else uint32_t mac_address_part = REG_READ(EFUSE_RD_MAC_SPI_SYS_0_REG); #endif @@ -145,6 +147,8 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { mac_address_part = REG_READ(EFUSE_RD_MAC_SYS_1_REG); #elif defined(CONFIG_IDF_TARGET_ESP32C2) mac_address_part = REG_READ(EFUSE_RD_BLK2_DATA1_REG); + #elif defined(CONFIG_IDF_TARGET_ESP32C61) + mac_address_part = REG_READ(EFUSE_RD_MAC_SYS1_REG); #else mac_address_part = REG_READ(EFUSE_RD_MAC_SPI_SYS_1_REG); #endif @@ -161,41 +165,41 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { switch (esp_reset_reason()) { case ESP_RST_POWERON: - return RESET_REASON_POWER_ON; + return MCU_RESET_REASON_POWER_ON; case ESP_RST_SW: case ESP_RST_PANIC: - return RESET_REASON_SOFTWARE; + return MCU_RESET_REASON_SOFTWARE; case ESP_RST_INT_WDT: case ESP_RST_TASK_WDT: case ESP_RST_WDT: - return RESET_REASON_WATCHDOG; + return MCU_RESET_REASON_WATCHDOG; case ESP_RST_BROWNOUT: - return RESET_REASON_BROWNOUT; + return MCU_RESET_REASON_BROWNOUT; case ESP_RST_SDIO: case ESP_RST_EXT: - return RESET_REASON_RESET_PIN; - - case ESP_RST_DEEPSLEEP: - switch (esp_sleep_get_wakeup_cause()) { - case ESP_SLEEP_WAKEUP_TIMER: - case ESP_SLEEP_WAKEUP_EXT0: - case ESP_SLEEP_WAKEUP_EXT1: - case ESP_SLEEP_WAKEUP_TOUCHPAD: - case ESP_SLEEP_WAKEUP_ULP: - return RESET_REASON_DEEP_SLEEP_ALARM; - - case ESP_SLEEP_WAKEUP_UNDEFINED: - default: - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_RESET_PIN; + + case ESP_RST_DEEPSLEEP: { + uint32_t wakeup_causes = esp_sleep_get_wakeup_causes(); + uint32_t alarm_causes = + BIT(ESP_SLEEP_WAKEUP_TIMER) | + BIT(ESP_SLEEP_WAKEUP_EXT0) | + BIT(ESP_SLEEP_WAKEUP_EXT1) | + BIT(ESP_SLEEP_WAKEUP_TOUCHPAD) | + BIT(ESP_SLEEP_WAKEUP_ULP); + if (wakeup_causes & alarm_causes) { + return MCU_RESET_REASON_DEEP_SLEEP_ALARM; } + return MCU_RESET_REASON_UNKNOWN; + } case ESP_RST_UNKNOWN: default: - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } } diff --git a/ports/espressif/common-hal/microcontroller/__init__.c b/ports/espressif/common-hal/microcontroller/__init__.c index 918366b8933..9b50cd7b5d2 100644 --- a/ports/espressif/common-hal/microcontroller/__init__.c +++ b/ports/espressif/common-hal/microcontroller/__init__.c @@ -36,6 +36,9 @@ #elif defined(CONFIG_IDF_TARGET_ESP32C6) #include "soc/lp_aon_reg.h" #include "esp32c6/rom/rtc.h" +#elif defined(CONFIG_IDF_TARGET_ESP32C61) +#include "soc/lp_aon_reg.h" +#include "esp32c61/rom/rtc.h" #elif defined(CONFIG_IDF_TARGET_ESP32P4) #include "esp32p4/rom/rtc.h" #elif defined(CONFIG_IDF_TARGET_ESP32S2) @@ -83,7 +86,7 @@ void common_hal_mcu_enable_interrupts(void) { void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { switch (runmode) { case RUNMODE_UF2: - #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) + #if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32C61) mp_arg_error_invalid(MP_QSTR_run_mode); #else // 0x11F2 is APP_REQUEST_UF2_RESET_HINT & is defined by TinyUF2 @@ -139,7 +142,7 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { } } -void NORETURN common_hal_mcu_reset(void) { +void MP_NORETURN common_hal_mcu_reset(void) { filesystem_flush(); // TODO: implement as part of flash improvements esp_restart(); } diff --git a/ports/espressif/common-hal/mipidsi/Bus.c b/ports/espressif/common-hal/mipidsi/Bus.c new file mode 100644 index 00000000000..dbb559ea30f --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Bus.c @@ -0,0 +1,69 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/mipidsi/Bus.h" +#include "bindings/espidf/__init__.h" +#include "py/runtime.h" +#include + +void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequency, uint8_t num_lanes) { + self->frequency = frequency; + self->num_data_lanes = num_lanes; + self->bus_handle = NULL; + + if (self->use_count > 0) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_mipidsi); + } + + esp_ldo_channel_handle_t ldo_mipi_phy = NULL; + esp_ldo_channel_config_t ldo_mipi_phy_config = { + .chan_id = 3, + .voltage_mv = 2500, + }; + ESP_ERROR_CHECK(esp_ldo_acquire_channel(&ldo_mipi_phy_config, &ldo_mipi_phy)); + + // Create the DSI bus + esp_lcd_dsi_bus_config_t bus_config = { + .bus_id = 0, + .num_data_lanes = num_lanes, + .phy_clk_src = MIPI_DSI_PHY_CLK_SRC_DEFAULT, + .lane_bit_rate_mbps = frequency / 1000000, // Convert Hz to MHz + }; + + CHECK_ESP_RESULT(esp_lcd_new_dsi_bus(&bus_config, &self->bus_handle)); +} + +void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self) { + if (self->use_count > 0) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_Bus); + } + if (common_hal_mipidsi_bus_deinited(self)) { + return; + } + + // Delete the DSI bus + if (self->bus_handle != NULL) { + esp_lcd_del_dsi_bus(self->bus_handle); + self->bus_handle = NULL; + } + + self->frequency = 0; + self->num_data_lanes = 0; +} + +bool common_hal_mipidsi_bus_deinited(mipidsi_bus_obj_t *self) { + return self->bus_handle == NULL; +} + +void mipidsi_bus_increment_use_count(mipidsi_bus_obj_t *self) { + self->use_count++; +} +void mipidsi_bus_decrement_use_count(mipidsi_bus_obj_t *self) { + self->use_count--; + if (self->use_count == 0) { + common_hal_mipidsi_bus_deinit(self); + } +} diff --git a/ports/espressif/common-hal/mipidsi/Bus.h b/ports/espressif/common-hal/mipidsi/Bus.h new file mode 100644 index 00000000000..b6257fd7223 --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Bus.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include + +typedef struct { + mp_obj_base_t base; + mp_uint_t frequency; + esp_lcd_dsi_bus_handle_t bus_handle; + uint8_t num_data_lanes; + uint8_t use_count; // Up to 4 displays +} mipidsi_bus_obj_t; + +void mipidsi_bus_increment_use_count(mipidsi_bus_obj_t *self); +void mipidsi_bus_decrement_use_count(mipidsi_bus_obj_t *self); diff --git a/ports/espressif/common-hal/mipidsi/Display.c b/ports/espressif/common-hal/mipidsi/Display.c new file mode 100644 index 00000000000..dc70f901437 --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Display.c @@ -0,0 +1,290 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/mipidsi/Display.h" +#include "shared-bindings/mipidsi/Bus.h" +#include "shared-bindings/pwmio/PWMOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/time/__init__.h" +#include "bindings/espidf/__init__.h" +#include +#include +#include "py/runtime.h" + +// Cache write-back function (should be from rom/cache.h but it's not always available) +extern int Cache_WriteBack_Addr(uint32_t addr, uint32_t size); + +void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self, + mipidsi_bus_obj_t *bus, + const uint8_t *init_sequence, + size_t init_sequence_len, + mp_uint_t virtual_channel, + mp_uint_t width, + mp_uint_t height, + mp_int_t rotation, + mp_uint_t color_depth, + const mcu_pin_obj_t *backlight_pin, + mp_float_t brightness, + mp_uint_t native_frames_per_second, + bool backlight_on_high, + mp_uint_t hsync_pulse_width, + mp_uint_t hsync_back_porch, + mp_uint_t hsync_front_porch, + mp_uint_t vsync_pulse_width, + mp_uint_t vsync_back_porch, + mp_uint_t vsync_front_porch, + mp_uint_t pixel_clock_frequency) { + self->bus = bus; + self->virtual_channel = virtual_channel; + self->width = width; + self->height = height; + self->rotation = rotation; + self->color_depth = color_depth; + self->native_frames_per_second = native_frames_per_second; + self->backlight_on_high = backlight_on_high; + self->framebuffer = NULL; + self->dbi_io_handle = NULL; + self->dpi_panel_handle = NULL; + + // Create the DBI interface for sending commands + esp_lcd_dbi_io_config_t dbi_config = { + .virtual_channel = virtual_channel, + .lcd_cmd_bits = 8, + .lcd_param_bits = 8, + }; + + CHECK_ESP_RESULT(esp_lcd_new_panel_io_dbi(bus->bus_handle, &dbi_config, &self->dbi_io_handle)); + + // Determine the pixel format based on color depth + lcd_color_format_t color_format; + if (color_depth == 16) { + color_format = LCD_COLOR_FMT_RGB565; + } else if (color_depth == 24) { + color_format = LCD_COLOR_FMT_RGB888; + } else { + common_hal_mipidsi_display_deinit(self); + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth); + } + + // Create the DPI panel for sending pixel data + esp_lcd_dpi_panel_config_t dpi_config = { + .virtual_channel = virtual_channel, + .dpi_clk_src = MIPI_DSI_DPI_CLK_SRC_DEFAULT, + .dpi_clock_freq_mhz = pixel_clock_frequency / 1000000, + .in_color_format = color_format, + .num_fbs = 1, + .video_timing = { + .h_size = width, + .v_size = height, + .hsync_pulse_width = hsync_pulse_width, + .hsync_back_porch = hsync_back_porch, + .hsync_front_porch = hsync_front_porch, + .vsync_pulse_width = vsync_pulse_width, + .vsync_back_porch = vsync_back_porch, + .vsync_front_porch = vsync_front_porch, + }, + .flags = { + .disable_lp = false, + }, + }; + + esp_err_t ret = esp_lcd_new_panel_dpi(bus->bus_handle, &dpi_config, &self->dpi_panel_handle); + if (ret != ESP_OK) { + common_hal_mipidsi_display_deinit(self); + CHECK_ESP_RESULT(ret); + } + + // Get the framebuffer allocated by the driver + void *fb = NULL; + ret = esp_lcd_dpi_panel_get_frame_buffer(self->dpi_panel_handle, 1, &fb); + if (ret != ESP_OK || fb == NULL) { + common_hal_mipidsi_display_deinit(self); + CHECK_ESP_RESULT(ret); + } + + self->framebuffer = (uint8_t *)fb; + self->framebuffer_size = width * height * (color_depth / 8); + + // Send initialization sequence (format matches busdisplay) + #define DELAY 0x80 + uint32_t i = 0; + while (i < init_sequence_len) { + const uint8_t *cmd = init_sequence + i; + uint8_t data_size = *(cmd + 1); + bool delay = (data_size & DELAY) != 0; + data_size &= ~DELAY; + const uint8_t *data = cmd + 2; + esp_lcd_panel_io_tx_param(self->dbi_io_handle, cmd[0], data, data_size); + + uint16_t delay_length_ms = 0; + if (delay) { + data_size++; + delay_length_ms = *(cmd + 1 + data_size); + if (delay_length_ms == 255) { + delay_length_ms = 500; + } + } + common_hal_time_delay_ms(delay_length_ms); + i += 2 + data_size; + } + + // Initialize the panel after sending init commands + ret = esp_lcd_panel_init(self->dpi_panel_handle); + if (ret != ESP_OK) { + common_hal_mipidsi_display_deinit(self); + CHECK_ESP_RESULT(ret); + } + + // Setup backlight PWM if pin is provided + self->backlight_inout.base.type = &mp_type_NoneType; + if (backlight_pin != NULL && common_hal_mcu_pin_is_free(backlight_pin)) { + #if (CIRCUITPY_PWMIO) + pwmout_result_t result = common_hal_pwmio_pwmout_construct(&self->backlight_pwm, backlight_pin, 0, 50000, false); + if (result != PWMOUT_OK) { + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + common_hal_never_reset_pin(backlight_pin); + } else { + self->backlight_pwm.base.type = &pwmio_pwmout_type; + common_hal_pwmio_pwmout_never_reset(&self->backlight_pwm); + } + #else + self->backlight_inout.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->backlight_inout, backlight_pin); + common_hal_never_reset_pin(backlight_pin); + #endif + + // Set initial brightness + #if (CIRCUITPY_PWMIO) + if (self->backlight_pwm.base.type == &pwmio_pwmout_type) { + common_hal_pwmio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t)(brightness * 0xFFFF)); + } else + #endif + if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + bool on = brightness > 0; + if (!backlight_on_high) { + on = !on; + } + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, on); + } + } + mipidsi_bus_increment_use_count(self->bus); +} + +void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self) { + if (common_hal_mipidsi_display_deinited(self)) { + return; + } + + // Cleanup backlight + #if (CIRCUITPY_PWMIO) + if (self->backlight_pwm.base.type == &pwmio_pwmout_type) { + common_hal_pwmio_pwmout_deinit(&self->backlight_pwm); + } else + #endif + if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_deinit(&self->backlight_inout); + } + + // Delete the DPI panel + if (self->dpi_panel_handle != NULL) { + esp_lcd_panel_del(self->dpi_panel_handle); + self->dpi_panel_handle = NULL; + } + + // Delete the DBI interface + if (self->dbi_io_handle != NULL) { + esp_lcd_panel_io_del(self->dbi_io_handle); + self->dbi_io_handle = NULL; + } + + mipidsi_bus_decrement_use_count(self->bus); + self->bus = NULL; + self->framebuffer = NULL; +} + +bool common_hal_mipidsi_display_deinited(mipidsi_display_obj_t *self) { + return self->dpi_panel_handle == NULL; +} + +void common_hal_mipidsi_display_refresh(mipidsi_display_obj_t *self) { + // Drawing the framebuffer we got from the IDF will flush the cache(s) so + // DMA can see our changes. It won't cause an extra copy. + esp_lcd_panel_draw_bitmap(self->dpi_panel_handle, 0, 0, self->width, self->height, self->framebuffer); + + // The DPI panel will automatically refresh from the framebuffer + // No explicit refresh call is needed as the DSI hardware continuously + // sends data from the framebuffer to the display +} + +mp_float_t common_hal_mipidsi_display_get_brightness(mipidsi_display_obj_t *self) { + return self->current_brightness; +} + +bool common_hal_mipidsi_display_set_brightness(mipidsi_display_obj_t *self, mp_float_t brightness) { + if (!self->backlight_on_high) { + brightness = 1.0 - brightness; + } + bool ok = false; + + // Avoid PWM types and functions when the module isn't enabled + #if (CIRCUITPY_PWMIO) + bool ispwm = (self->backlight_pwm.base.type == &pwmio_pwmout_type) ? true : false; + #else + bool ispwm = false; + #endif + + if (ispwm) { + #if (CIRCUITPY_PWMIO) + common_hal_pwmio_pwmout_set_duty_cycle(&self->backlight_pwm, (uint16_t)(0xffff * brightness)); + ok = true; + #else + ok = false; + #endif + } else if (self->backlight_inout.base.type == &digitalio_digitalinout_type) { + common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, brightness > 0.99); + ok = true; + } + if (ok) { + self->current_brightness = brightness; + } + return ok; +} + +int common_hal_mipidsi_display_get_width(mipidsi_display_obj_t *self) { + return self->width; +} + +int common_hal_mipidsi_display_get_height(mipidsi_display_obj_t *self) { + return self->height; +} + +int common_hal_mipidsi_display_get_row_stride(mipidsi_display_obj_t *self) { + return self->width * (self->color_depth / 8); +} + +int common_hal_mipidsi_display_get_color_depth(mipidsi_display_obj_t *self) { + return self->color_depth; +} + +int common_hal_mipidsi_display_get_native_frames_per_second(mipidsi_display_obj_t *self) { + return self->native_frames_per_second; +} + +bool common_hal_mipidsi_display_get_grayscale(mipidsi_display_obj_t *self) { + return false; +} + +mp_int_t common_hal_mipidsi_display_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { + mipidsi_display_obj_t *self = (mipidsi_display_obj_t *)self_in; + + bufinfo->buf = self->framebuffer; + bufinfo->len = self->framebuffer_size; + bufinfo->typecode = 'B'; + + return 0; +} diff --git a/ports/espressif/common-hal/mipidsi/Display.h b/ports/espressif/common-hal/mipidsi/Display.h new file mode 100644 index 00000000000..cbc87e268dc --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/Display.h @@ -0,0 +1,38 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-bindings/mipidsi/Bus.h" +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/digitalio/DigitalInOut.h" +#include "common-hal/pwmio/PWMOut.h" +#include +#include + +typedef struct { + mp_obj_base_t base; + mipidsi_bus_obj_t *bus; + mp_uint_t virtual_channel; + mp_uint_t width; + mp_uint_t height; + mp_int_t rotation; + mp_uint_t color_depth; + mp_uint_t native_frames_per_second; + uint8_t *framebuffer; + esp_lcd_panel_io_handle_t dbi_io_handle; + esp_lcd_panel_handle_t dpi_panel_handle; + size_t framebuffer_size; + union { + digitalio_digitalinout_obj_t backlight_inout; + #if CIRCUITPY_PWMIO + pwmio_pwmout_obj_t backlight_pwm; + #endif + }; + bool backlight_on_high; + mp_float_t current_brightness; +} mipidsi_display_obj_t; diff --git a/ports/espressif/common-hal/mipidsi/__init__.c b/ports/espressif/common-hal/mipidsi/__init__.c new file mode 100644 index 00000000000..173f2146e87 --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/mipidsi/__init__.h" diff --git a/ports/espressif/common-hal/mipidsi/__init__.h b/ports/espressif/common-hal/mipidsi/__init__.h new file mode 100644 index 00000000000..972a7c082fd --- /dev/null +++ b/ports/espressif/common-hal/mipidsi/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/ports/espressif/common-hal/neopixel_write/__init__.c b/ports/espressif/common-hal/neopixel_write/__init__.c index d0d46a31797..cd62220f620 100644 --- a/ports/espressif/common-hal/neopixel_write/__init__.c +++ b/ports/espressif/common-hal/neopixel_write/__init__.c @@ -31,6 +31,8 @@ #include "driver/gpio.h" #include "driver/rmt_tx.h" +#include "hal/rmt_periph.h" +#include "soc/soc_caps.h" // Use closer to WS2812-style timings instead of WS2812B, to accommodate more varieties. #define WS2812_T0H_NS (316) @@ -53,14 +55,13 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, .trans_queue_depth = 1, }; - // Greedily try and grab as much RMT memory as we can. The more we get, the - // smoother the output will be because we'll trigger fewer interrupts. We'll - // give it all back once we're done. + // Greedily allocate as much RMT memory as possible, stepping down by one + // channel's worth each time. More memory means fewer interrupts and smoother output. + // We'll give it all back once we're done. rmt_channel_handle_t channel; esp_err_t result = ESP_ERR_NOT_FOUND; - // If no other channels are in use, we can use all of the RMT RAM including the RX channels. - config.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * SOC_RMT_CHANNELS_PER_GROUP; - while (result == ESP_ERR_NOT_FOUND && config.mem_block_symbols > 0) { + config.mem_block_symbols = SOC_RMT_MEM_WORDS_PER_CHANNEL * RMT_LL_CHANS_PER_INST; + while (result == ESP_ERR_NOT_FOUND && config.mem_block_symbols >= SOC_RMT_MEM_WORDS_PER_CHANNEL) { result = rmt_new_tx_channel(&config, &channel); config.mem_block_symbols -= SOC_RMT_MEM_WORDS_PER_CHANNEL; } @@ -117,6 +118,7 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, rmt_del_channel(channel); raise_esp_error(result); } + result = ESP_ERR_TIMEOUT; while (result == ESP_ERR_TIMEOUT) { RUN_BACKGROUND_TASKS; diff --git a/ports/espressif/common-hal/nvm/ByteArray.c b/ports/espressif/common-hal/nvm/ByteArray.c index adea91411b6..971f9bc7991 100644 --- a/ports/espressif/common-hal/nvm/ByteArray.c +++ b/ports/espressif/common-hal/nvm/ByteArray.c @@ -46,7 +46,7 @@ static esp_err_t get_bytes(nvs_handle_t handle, uint8_t **buf_out) { *buf_out = NULL; return result; } - buf = m_malloc(size); // this SHOULD be the same as + buf = m_malloc_without_collect(size); // this SHOULD be the same as if (result == ESP_OK) { result = nvs_get_blob(handle, "data", buf, &size); } else { diff --git a/ports/espressif/common-hal/os/__init__.c b/ports/espressif/common-hal/os/__init__.c index 4063090fe1f..fff89c8476d 100644 --- a/ports/espressif/common-hal/os/__init__.c +++ b/ports/espressif/common-hal/os/__init__.c @@ -15,32 +15,6 @@ #include "esp_system.h" #include "esp_random.h" -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_HW_MCU_NAME); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_HW_MCU_NAME); -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { uint32_t i = 0; while (i < length) { diff --git a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c index 7721b5e197f..52c4b67bf4e 100644 --- a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c +++ b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.c @@ -18,7 +18,7 @@ #include "common-hal/microcontroller/Pin.h" #include "py/runtime.h" -#include "driver/gpio.h" +#include /* * Current pin limitations for ESP32-S2 ParallelBus: diff --git a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h index 4724ba7231a..114a1e527a6 100644 --- a/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h +++ b/ports/espressif/common-hal/paralleldisplaybus/ParallelBus.h @@ -8,7 +8,7 @@ #include "common-hal/digitalio/DigitalInOut.h" -#include "esp-idf/components/esp_lcd/include/esp_lcd_panel_io.h" +#include typedef struct { mp_obj_base_t base; diff --git a/ports/espressif/common-hal/pulseio/PulseIn.c b/ports/espressif/common-hal/pulseio/PulseIn.c index cf24b42a052..f7e50079056 100644 --- a/ports/espressif/common-hal/pulseio/PulseIn.c +++ b/ports/espressif/common-hal/pulseio/PulseIn.c @@ -74,14 +74,14 @@ static bool _done_callback(rmt_channel_handle_t rx_chan, void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); + self->buffer = (uint16_t *)m_malloc_without_collect(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } // We add one to the maxlen version to ensure that two symbols at lease are // captured because we may skip the first portion of a symbol. self->raw_symbols_size = MIN(64, maxlen / 2 + 1) * sizeof(rmt_symbol_word_t); - self->raw_symbols = (rmt_symbol_word_t *)m_malloc(self->raw_symbols_size); + self->raw_symbols = (rmt_symbol_word_t *)m_malloc_without_collect(self->raw_symbols_size); if (self->raw_symbols == NULL) { m_free(self->buffer); m_malloc_fail(self->raw_symbols_size); @@ -127,6 +127,9 @@ bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t *self) { } void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t *self) { + if (common_hal_pulseio_pulsein_deinited(self)) { + return; + } rmt_disable(self->channel); reset_pin_number(self->pin->number); rmt_del_channel(self->channel); diff --git a/ports/espressif/common-hal/pulseio/PulseOut.c b/ports/espressif/common-hal/pulseio/PulseOut.c index b76c8438559..8995043b825 100644 --- a/ports/espressif/common-hal/pulseio/PulseOut.c +++ b/ports/espressif/common-hal/pulseio/PulseOut.c @@ -54,6 +54,9 @@ bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t *self) { } void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t *self) { + if (common_hal_pulseio_pulseout_deinited(self)) { + return; + } rmt_disable(self->channel); rmt_del_encoder(self->encoder); rmt_del_channel(self->channel); @@ -66,7 +69,7 @@ void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t *self, uint16_t *pu // Circuitpython allows 16 bit pulse values, while ESP32 only allows 15 bits // Thus, we use entire items for one pulse, rather than switching inside each item for (size_t i = 0; i < length; i++) { - // Setting the RMT duration to 0 has undefined behavior, so avoid that pre-emptively. + // Setting the RMT duration to 0 has undefined behavior, so avoid that preemptively. if (pulses[i] == 0) { continue; } diff --git a/ports/espressif/common-hal/qspibus/QSPIBus.c b/ports/espressif/common-hal/qspibus/QSPIBus.c new file mode 100644 index 00000000000..6fb872248e2 --- /dev/null +++ b/ports/espressif/common-hal/qspibus/QSPIBus.c @@ -0,0 +1,571 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#include "shared-bindings/qspibus/QSPIBus.h" + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" + +#include "py/gc.h" +#include "py/runtime.h" + +#include "driver/gpio.h" +#include "esp_heap_caps.h" +#include "soc/soc_caps.h" +#include + +#define QSPI_OPCODE_WRITE_CMD (0x02U) +#define QSPI_OPCODE_WRITE_COLOR (0x32U) +#define LCD_CMD_RAMWR (0x2CU) +#define LCD_CMD_RAMWRC (0x3CU) +#define LCD_CMD_DISPOFF (0x28U) +#define LCD_CMD_SLPIN (0x10U) +#define QSPI_DMA_BUFFER_COUNT (2U) +#define QSPI_DMA_BUFFER_SIZE (16U * 1024U) +#define QSPI_COLOR_TIMEOUT_MS (1000U) +static void qspibus_release_dma_buffers(qspibus_qspibus_obj_t *self) { + for (size_t i = 0; i < QSPI_DMA_BUFFER_COUNT; i++) { + if (self->dma_buffer[i] != NULL) { + heap_caps_free(self->dma_buffer[i]); + self->dma_buffer[i] = NULL; + } + } + self->dma_buffer_size = 0; + self->active_buffer = 0; + self->inflight_transfers = 0; + self->transfer_in_progress = false; +} + +static bool qspibus_allocate_dma_buffers(qspibus_qspibus_obj_t *self) { + const size_t candidates[] = { + QSPI_DMA_BUFFER_SIZE, + QSPI_DMA_BUFFER_SIZE / 2, + QSPI_DMA_BUFFER_SIZE / 4, + }; + + for (size_t c = 0; c < MP_ARRAY_SIZE(candidates); c++) { + size_t size = candidates[c]; + bool ok = true; + for (size_t i = 0; i < QSPI_DMA_BUFFER_COUNT; i++) { + self->dma_buffer[i] = heap_caps_malloc(size, MALLOC_CAP_DMA | MALLOC_CAP_8BIT); + if (self->dma_buffer[i] == NULL) { + ok = false; + break; + } + } + if (ok) { + self->dma_buffer_size = size; + self->active_buffer = 0; + self->inflight_transfers = 0; + self->transfer_in_progress = false; + return true; + } + qspibus_release_dma_buffers(self); + } + return false; +} + +// Reset transfer bookkeeping after timeout/error. Drains any stale semaphore +// tokens that late ISR completions may have posted after the timeout expired. +static void qspibus_reset_transfer_state(qspibus_qspibus_obj_t *self) { + self->inflight_transfers = 0; + self->transfer_in_progress = false; + if (self->transfer_done_sem != NULL) { + while (xSemaphoreTake(self->transfer_done_sem, 0) == pdTRUE) { + } + } +} + +static bool qspibus_wait_one_transfer_done(qspibus_qspibus_obj_t *self, TickType_t timeout) { + if (self->inflight_transfers == 0) { + self->transfer_in_progress = false; + return true; + } + + if (xSemaphoreTake(self->transfer_done_sem, timeout) != pdTRUE) { + return false; + } + self->inflight_transfers--; + self->transfer_in_progress = (self->inflight_transfers > 0); + return true; +} + +static bool qspibus_wait_all_transfers_done(qspibus_qspibus_obj_t *self, TickType_t timeout) { + while (self->inflight_transfers > 0) { + if (!qspibus_wait_one_transfer_done(self, timeout)) { + return false; + } + } + return true; +} + +static void qspibus_send_command_bytes( + qspibus_qspibus_obj_t *self, + uint8_t command, + const uint8_t *data, + size_t len) { + + if (!self->bus_initialized) { + raise_deinited_error(); + } + if (self->inflight_transfers >= QSPI_DMA_BUFFER_COUNT) { + if (!qspibus_wait_one_transfer_done(self, pdMS_TO_TICKS(QSPI_COLOR_TIMEOUT_MS))) { + qspibus_reset_transfer_state(self); + mp_raise_OSError_msg(MP_ERROR_TEXT("Operation timed out")); + } + } + + uint32_t packed_cmd = ((uint32_t)QSPI_OPCODE_WRITE_CMD << 24) | ((uint32_t)command << 8); + esp_err_t err = esp_lcd_panel_io_tx_param(self->io_handle, packed_cmd, data, len); + if (err != ESP_OK) { + qspibus_reset_transfer_state(self); + mp_raise_OSError_msg_varg(MP_ERROR_TEXT("%q failure: %d"), MP_QSTR_QSPI, (int)err); + } +} + +static void qspibus_send_color_bytes( + qspibus_qspibus_obj_t *self, + uint8_t command, + const uint8_t *data, + size_t len) { + + if (!self->bus_initialized) { + raise_deinited_error(); + } + + if (len == 0) { + qspibus_send_command_bytes(self, command, NULL, 0); + return; + } + + // RAMWR must transition to RAMWRC for continued payload chunks. + uint8_t chunk_command = command; + const uint8_t *cursor = data; + size_t remaining = len; + + // Drain stale semaphore tokens that late ISR completions may have + // posted after a previous qspibus_reset_transfer_state(). Without + // this, a stale token could satisfy a future wait, causing the next + // transfer to skip its real DMA-done wait. + if (self->inflight_transfers == 0 && self->transfer_done_sem != NULL) { + while (xSemaphoreTake(self->transfer_done_sem, 0) == pdTRUE) { + } + } + + while (remaining > 0) { + // inflight_transfers is only modified in task context (never from ISR), + // so no atomic/critical section is needed. The ISR only signals the + // counting semaphore; all counter bookkeeping happens task-side. + if (self->inflight_transfers >= QSPI_DMA_BUFFER_COUNT) { + if (!qspibus_wait_one_transfer_done(self, pdMS_TO_TICKS(QSPI_COLOR_TIMEOUT_MS))) { + qspibus_reset_transfer_state(self); + mp_raise_OSError_msg(MP_ERROR_TEXT("Operation timed out")); + } + } + + size_t chunk = remaining; + if (chunk > self->dma_buffer_size) { + chunk = self->dma_buffer_size; + } + + uint8_t *buffer = self->dma_buffer[self->active_buffer]; + memcpy(buffer, cursor, chunk); + + uint32_t packed_cmd = ((uint32_t)QSPI_OPCODE_WRITE_COLOR << 24) | ((uint32_t)chunk_command << 8); + esp_err_t err = esp_lcd_panel_io_tx_color(self->io_handle, packed_cmd, buffer, chunk); + if (err != ESP_OK) { + qspibus_reset_transfer_state(self); + mp_raise_OSError_msg_varg(MP_ERROR_TEXT("%q failure: %d"), MP_QSTR_QSPI, (int)err); + } + + self->inflight_transfers++; + self->transfer_in_progress = true; + self->active_buffer = (self->active_buffer + 1) % QSPI_DMA_BUFFER_COUNT; + + if (chunk_command == LCD_CMD_RAMWR) { + chunk_command = LCD_CMD_RAMWRC; + } + + cursor += chunk; + remaining -= chunk; + } + + // Let DMA complete asynchronously. The next begin_transaction() will + // wait for all in-flight transfers, allowing fill_area() computation + // to overlap with DMA. The explicit wait is only needed for the + // Python write_data() API path where callers expect the transfer to + // be finished on return. +} + +static bool qspibus_is_color_payload_command(uint8_t command) { + return command == LCD_CMD_RAMWR || command == LCD_CMD_RAMWRC; +} + +static void qspibus_panel_sleep_best_effort(qspibus_qspibus_obj_t *self) { + if (!self->bus_initialized || self->io_handle == NULL) { + return; + } + + if (!qspibus_wait_all_transfers_done(self, pdMS_TO_TICKS(QSPI_COLOR_TIMEOUT_MS))) { + qspibus_reset_transfer_state(self); + } + + // If a command is buffered, flush it first so the panel state machine + // doesn't get a truncated transaction before sleep. + if (self->has_pending_command) { + uint32_t pending = ((uint32_t)QSPI_OPCODE_WRITE_CMD << 24) | ((uint32_t)self->pending_command << 8); + (void)esp_lcd_panel_io_tx_param(self->io_handle, pending, NULL, 0); + self->has_pending_command = false; + } + + uint32_t disp_off = ((uint32_t)QSPI_OPCODE_WRITE_CMD << 24) | ((uint32_t)LCD_CMD_DISPOFF << 8); + (void)esp_lcd_panel_io_tx_param(self->io_handle, disp_off, NULL, 0); + vTaskDelay(pdMS_TO_TICKS(20)); + + uint32_t sleep_in = ((uint32_t)QSPI_OPCODE_WRITE_CMD << 24) | ((uint32_t)LCD_CMD_SLPIN << 8); + (void)esp_lcd_panel_io_tx_param(self->io_handle, sleep_in, NULL, 0); + vTaskDelay(pdMS_TO_TICKS(120)); +} + +static bool IRAM_ATTR qspibus_on_color_trans_done( + esp_lcd_panel_io_handle_t io_handle, + esp_lcd_panel_io_event_data_t *event_data, + void *user_ctx) { + (void)io_handle; + (void)event_data; + + qspibus_qspibus_obj_t *self = (qspibus_qspibus_obj_t *)user_ctx; + if (self->transfer_done_sem == NULL) { + return false; + } + BaseType_t x_higher_priority_task_woken = pdFALSE; + + xSemaphoreGiveFromISR(self->transfer_done_sem, &x_higher_priority_task_woken); + return x_higher_priority_task_woken == pdTRUE; +} + +void common_hal_qspibus_qspibus_construct( + qspibus_qspibus_obj_t *self, + const mcu_pin_obj_t *clock, + const mcu_pin_obj_t *data0, + const mcu_pin_obj_t *data1, + const mcu_pin_obj_t *data2, + const mcu_pin_obj_t *data3, + const mcu_pin_obj_t *cs, + const mcu_pin_obj_t *dcx, + const mcu_pin_obj_t *reset, + uint32_t frequency) { + + self->io_handle = NULL; + self->host_id = SPI2_HOST; + self->clock_pin = clock->number; + self->data0_pin = data0->number; + self->data1_pin = data1->number; + self->data2_pin = data2->number; + self->data3_pin = data3->number; + self->cs_pin = cs->number; + self->dcx_pin = (dcx != NULL) ? dcx->number : -1; + self->reset_pin = (reset != NULL) ? reset->number : -1; + self->frequency = frequency; + self->bus_initialized = false; + self->in_transaction = false; + self->has_pending_command = false; + self->pending_command = 0; + self->transfer_in_progress = false; + self->active_buffer = 0; + self->inflight_transfers = 0; + self->dma_buffer_size = 0; + self->dma_buffer[0] = NULL; + self->dma_buffer[1] = NULL; + self->transfer_done_sem = NULL; + + self->transfer_done_sem = xSemaphoreCreateCounting(QSPI_DMA_BUFFER_COUNT, 0); + if (self->transfer_done_sem == NULL) { + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("ESP-IDF memory allocation failed")); + } + + if (!qspibus_allocate_dma_buffers(self)) { + common_hal_qspibus_qspibus_deinit(self); + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Could not allocate DMA capable buffer")); + } + + const spi_bus_config_t bus_config = { + .sclk_io_num = self->clock_pin, + .mosi_io_num = self->data0_pin, + .miso_io_num = self->data1_pin, + .quadwp_io_num = self->data2_pin, + .quadhd_io_num = self->data3_pin, + .max_transfer_sz = self->dma_buffer_size, + .flags = SPICOMMON_BUSFLAG_MASTER | SPICOMMON_BUSFLAG_GPIO_PINS, + }; + + esp_err_t err = spi_bus_initialize(self->host_id, &bus_config, SPI_DMA_CH_AUTO); + if (err != ESP_OK) { + common_hal_qspibus_qspibus_deinit(self); + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_SPI); + } + + // Mark bus as initialized so deinit knows to call spi_bus_free(). + self->bus_initialized = true; + + const esp_lcd_panel_io_spi_config_t io_config = { + .cs_gpio_num = self->cs_pin, + .dc_gpio_num = -1, + .spi_mode = 0, + .pclk_hz = self->frequency, + .trans_queue_depth = QSPI_DMA_BUFFER_COUNT, + .on_color_trans_done = qspibus_on_color_trans_done, + .user_ctx = self, + .lcd_cmd_bits = 32, + .lcd_param_bits = 8, + .flags = { + .quad_mode = 1, + }, + }; + + err = esp_lcd_new_panel_io_spi((esp_lcd_spi_bus_handle_t)self->host_id, &io_config, &self->io_handle); + if (err != ESP_OK) { + common_hal_qspibus_qspibus_deinit(self); + mp_raise_OSError_msg_varg(MP_ERROR_TEXT("%q failure: %d"), MP_QSTR_QSPI, (int)err); + } + + claim_pin(clock); + claim_pin(data0); + claim_pin(data1); + claim_pin(data2); + claim_pin(data3); + claim_pin(cs); + if (dcx != NULL) { + claim_pin(dcx); + gpio_set_direction((gpio_num_t)self->dcx_pin, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t)self->dcx_pin, 1); + } + + if (reset != NULL) { + claim_pin(reset); + + gpio_set_direction((gpio_num_t)self->reset_pin, GPIO_MODE_OUTPUT); + gpio_set_level((gpio_num_t)self->reset_pin, 0); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level((gpio_num_t)self->reset_pin, 1); + vTaskDelay(pdMS_TO_TICKS(120)); + } +} + +void common_hal_qspibus_qspibus_deinit(qspibus_qspibus_obj_t *self) { + if (self->bus_initialized) { + qspibus_panel_sleep_best_effort(self); + self->in_transaction = false; + + if (self->io_handle != NULL) { + esp_lcd_panel_io_del(self->io_handle); + self->io_handle = NULL; + } + + spi_bus_free(self->host_id); + self->bus_initialized = false; + } + + if (self->transfer_done_sem != NULL) { + // Set NULL before delete so late ISR callbacks (if any) see NULL and skip. + SemaphoreHandle_t sem = self->transfer_done_sem; + self->transfer_done_sem = NULL; + vSemaphoreDelete(sem); + } + + qspibus_release_dma_buffers(self); + + reset_pin_number(self->clock_pin); + reset_pin_number(self->data0_pin); + reset_pin_number(self->data1_pin); + reset_pin_number(self->data2_pin); + reset_pin_number(self->data3_pin); + reset_pin_number(self->cs_pin); + if (self->dcx_pin >= 0) { + reset_pin_number(self->dcx_pin); + } + if (self->reset_pin >= 0) { + reset_pin_number(self->reset_pin); + } + + self->bus_initialized = false; + self->in_transaction = false; + self->has_pending_command = false; + self->pending_command = 0; + self->transfer_in_progress = false; + self->inflight_transfers = 0; +} + +bool common_hal_qspibus_qspibus_deinited(qspibus_qspibus_obj_t *self) { + return !self->bus_initialized; +} + +void common_hal_qspibus_qspibus_write_command( + qspibus_qspibus_obj_t *self, + uint8_t command) { + if (!self->bus_initialized) { + raise_deinited_error(); + } + if (self->in_transaction) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Internal error")); + } + + // If caller stages command-only operations repeatedly, flush the previous + // pending command as no-data before replacing it. + if (self->has_pending_command) { + qspibus_send_command_bytes(self, self->pending_command, NULL, 0); + } + + self->pending_command = command; + self->has_pending_command = true; +} + +void common_hal_qspibus_qspibus_write_data( + qspibus_qspibus_obj_t *self, + const uint8_t *data, + size_t len) { + if (!self->bus_initialized) { + raise_deinited_error(); + } + if (self->in_transaction) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Internal error")); + } + if (len == 0) { + if (self->has_pending_command) { + qspibus_send_command_bytes(self, self->pending_command, NULL, 0); + self->has_pending_command = false; + } + return; + } + if (!self->has_pending_command) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Internal error")); + } + + if (qspibus_is_color_payload_command(self->pending_command)) { + qspibus_send_color_bytes(self, self->pending_command, data, len); + // Python API: wait for DMA to finish so callers see the transfer as + // complete on return. The internal displayio path skips this wait + // to allow fill_area/DMA overlap. + if (!qspibus_wait_all_transfers_done(self, pdMS_TO_TICKS(QSPI_COLOR_TIMEOUT_MS))) { + qspibus_reset_transfer_state(self); + mp_raise_OSError_msg(MP_ERROR_TEXT("Operation timed out")); + } + } else { + qspibus_send_command_bytes(self, self->pending_command, data, len); + } + self->has_pending_command = false; +} + +bool common_hal_qspibus_qspibus_reset(mp_obj_t obj) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(obj); + if (!self->bus_initialized || self->reset_pin < 0) { + return false; + } + + gpio_set_level((gpio_num_t)self->reset_pin, 0); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_set_level((gpio_num_t)self->reset_pin, 1); + vTaskDelay(pdMS_TO_TICKS(120)); + return true; +} + +bool common_hal_qspibus_qspibus_bus_free(mp_obj_t obj) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(obj); + return self->bus_initialized && !self->in_transaction && !self->transfer_in_progress && !self->has_pending_command; +} + +bool common_hal_qspibus_qspibus_begin_transaction(mp_obj_t obj) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(obj); + if (!self->bus_initialized || self->in_transaction || self->has_pending_command) { + return false; + } + // Wait for any in-flight DMA to complete before starting a new + // transaction. This replaces the old non-blocking bus_free() check + // and enables fill_area()/DMA overlap: the CPU fills the next + // subrectangle while the previous DMA runs, and this wait only + // blocks when we actually need the bus for the next send. + if (self->transfer_in_progress) { + if (!qspibus_wait_all_transfers_done(self, pdMS_TO_TICKS(QSPI_COLOR_TIMEOUT_MS))) { + qspibus_reset_transfer_state(self); + return false; + } + } + self->in_transaction = true; + return true; +} + +void common_hal_qspibus_qspibus_send( + mp_obj_t obj, + display_byte_type_t data_type, + display_chip_select_behavior_t chip_select, + const uint8_t *data, + uint32_t data_length) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(obj); + (void)chip_select; + if (!self->bus_initialized) { + raise_deinited_error(); + } + if (!self->in_transaction) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Internal error")); + } + + if (data_type == DISPLAY_COMMAND) { + for (uint32_t i = 0; i < data_length; i++) { + if (self->has_pending_command) { + qspibus_send_command_bytes(self, self->pending_command, NULL, 0); + } + self->pending_command = data[i]; + self->has_pending_command = true; + } + return; + } + + if (!self->has_pending_command) { + if (data_length == 0) { + // Zero-length data write after a no-data command is benign. + return; + } + mp_raise_RuntimeError(MP_ERROR_TEXT("Internal error")); + } + + if (data_length == 0) { + qspibus_send_command_bytes(self, self->pending_command, NULL, 0); + self->has_pending_command = false; + return; + } + + if (qspibus_is_color_payload_command(self->pending_command)) { + qspibus_send_color_bytes(self, self->pending_command, data, data_length); + } else { + qspibus_send_command_bytes(self, self->pending_command, data, data_length); + } + self->has_pending_command = false; +} + +void common_hal_qspibus_qspibus_end_transaction(mp_obj_t obj) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(obj); + if (!self->bus_initialized) { + return; + } + if (self->has_pending_command) { + qspibus_send_command_bytes(self, self->pending_command, NULL, 0); + self->has_pending_command = false; + } + self->in_transaction = false; +} + +void common_hal_qspibus_qspibus_flush(mp_obj_t obj) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(obj); + if (!self->bus_initialized) { + return; + } + if (!qspibus_wait_all_transfers_done(self, pdMS_TO_TICKS(QSPI_COLOR_TIMEOUT_MS))) { + qspibus_reset_transfer_state(self); + } +} + +void common_hal_qspibus_qspibus_collect_ptrs(mp_obj_t obj) { + (void)obj; +} diff --git a/ports/espressif/common-hal/qspibus/QSPIBus.h b/ports/espressif/common-hal/qspibus/QSPIBus.h new file mode 100644 index 00000000000..eaaa971a79c --- /dev/null +++ b/ports/espressif/common-hal/qspibus/QSPIBus.h @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include + +#include "py/obj.h" + +#include "esp-idf/components/esp_lcd/include/esp_lcd_panel_io.h" +#include "driver/spi_master.h" +#include "freertos/FreeRTOS.h" +#include "freertos/semphr.h" + +typedef struct { + mp_obj_base_t base; + + // ESP LCD panel IO handle used for QSPI transactions. + esp_lcd_panel_io_handle_t io_handle; + + // SPI host (SPI2_HOST on ESP32-S3). + spi_host_device_t host_id; + + // Claimed GPIO numbers. + int8_t clock_pin; + int8_t data0_pin; + int8_t data1_pin; + int8_t data2_pin; + int8_t data3_pin; + int8_t cs_pin; + int8_t dcx_pin; // -1 when optional DCX line is not provided. + int8_t reset_pin; // -1 when reset line is not provided. + + uint32_t frequency; + bool bus_initialized; + bool in_transaction; + bool has_pending_command; + uint8_t pending_command; + bool transfer_in_progress; + uint8_t active_buffer; + uint8_t inflight_transfers; + size_t dma_buffer_size; + uint8_t *dma_buffer[2]; + + // Signaled from ISR when panel IO transfer completes. + SemaphoreHandle_t transfer_done_sem; +} qspibus_qspibus_obj_t; diff --git a/ports/espressif/common-hal/qspibus/__init__.c b/ports/espressif/common-hal/qspibus/__init__.c new file mode 100644 index 00000000000..2f763b218cb --- /dev/null +++ b/ports/espressif/common-hal/qspibus/__init__.c @@ -0,0 +1,3 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT diff --git a/ports/espressif/common-hal/qspibus/__init__.h b/ports/espressif/common-hal/qspibus/__init__.h new file mode 100644 index 00000000000..2f763b218cb --- /dev/null +++ b/ports/espressif/common-hal/qspibus/__init__.h @@ -0,0 +1,3 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT diff --git a/ports/espressif/common-hal/rclcpy/Node.c b/ports/espressif/common-hal/rclcpy/Node.c new file mode 100644 index 00000000000..f68daa44fc3 --- /dev/null +++ b/ports/espressif/common-hal/rclcpy/Node.c @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/rclcpy/Node.h" +#include "shared-bindings/rclcpy/__init__.h" + +#include "esp_log.h" + +void common_hal_rclcpy_node_construct(rclcpy_node_obj_t *self, + const char *node_name, const char *node_namespace) { + + rclc_node_init_default(&self->rcl_node, node_name, node_namespace, &rclcpy_default_context.rcl_support); + if (!rcl_node_is_valid(&self->rcl_node)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ROS node failed to initialize")); + } + self->deinited = false; +} + +bool common_hal_rclcpy_node_deinited(rclcpy_node_obj_t *self) { + return self->deinited; +} + +void common_hal_rclcpy_node_deinit(rclcpy_node_obj_t *self) { + if (common_hal_rclcpy_node_deinited(self)) { + return; + } + // Clean up Micro-ROS object + rcl_ret_t ret = rcl_node_fini(&self->rcl_node); + if (ret != RCL_RET_OK) { + // TODO: node_fini returns a fail here, but doesn't impede microros + // from restarting. Debug left for future investigation. + ESP_LOGW("RCLCPY", "Node cleanup error: %d", ret); + // rclcpy_default_context.critical_fail=RCLCPY_NODE_FAIL; + } + self->deinited = true; +} + +const char *common_hal_rclcpy_node_get_name(rclcpy_node_obj_t *self) { + return rcl_node_get_name(&self->rcl_node); +} + +const char *common_hal_rclcpy_node_get_namespace(rclcpy_node_obj_t *self) { + return rcl_node_get_namespace(&self->rcl_node); +} diff --git a/ports/espressif/common-hal/rclcpy/Node.h b/ports/espressif/common-hal/rclcpy/Node.h new file mode 100644 index 00000000000..c019a654e5a --- /dev/null +++ b/ports/espressif/common-hal/rclcpy/Node.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "py/runtime.h" + +#include +#include +#include +#include +#include + + +typedef struct { + mp_obj_base_t base; + bool deinited; + rcl_node_t rcl_node; +} rclcpy_node_obj_t; diff --git a/ports/espressif/common-hal/rclcpy/Publisher.c b/ports/espressif/common-hal/rclcpy/Publisher.c new file mode 100644 index 00000000000..81df154687a --- /dev/null +++ b/ports/espressif/common-hal/rclcpy/Publisher.c @@ -0,0 +1,64 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/rclcpy/Publisher.h" + +#include "esp_log.h" + +void common_hal_rclcpy_publisher_construct(rclcpy_publisher_obj_t *self, rclcpy_node_obj_t *node, + const char *topic_name) { + + // Create Int32 type object + // TODO: support other message types through class imports + const rosidl_message_type_support_t *type_support = ROSIDL_GET_MSG_TYPE_SUPPORT(std_msgs, msg, Int32); + + // Creates a reliable Int32 publisher + rcl_ret_t rc = rclc_publisher_init_default( + &self->rcl_publisher, &node->rcl_node, + type_support, topic_name); + if (RCL_RET_OK != rc) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ROS topic failed to initialize")); + } + + self->node = node; +} + +bool common_hal_rclcpy_publisher_deinited(rclcpy_publisher_obj_t *self) { + return self->node == NULL; +} + +void common_hal_rclcpy_publisher_deinit(rclcpy_publisher_obj_t *self) { + if (common_hal_rclcpy_publisher_deinited(self)) { + return; + } + // Clean up Micro-ROS object + rcl_ret_t ret = rcl_publisher_fini(&self->rcl_publisher, &self->node->rcl_node); + if (ret != RCL_RET_OK) { + // TODO: publisher_fini returns a fail here, but doesn't impede microros + // from restarting. Debug left for future investigation. + ESP_LOGW("RCLCPY", "Publisher cleanup error: %d", ret); + // rclcpy_default_context.critical_fail=RCLCPY_PUB_FAIL; + } + self->node = NULL; +} + +void common_hal_rclcpy_publisher_publish_int32(rclcpy_publisher_obj_t *self, int32_t data) { + // Int32 message object + std_msgs__msg__Int32 msg; + + // Set message value + msg.data = data; + + // Publish message + rcl_ret_t rc = rcl_publish(&self->rcl_publisher, &msg, NULL); + if (RCL_RET_OK != rc) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Could not publish to ROS topic")); + } +} + +const char *common_hal_rclcpy_publisher_get_topic_name(rclcpy_publisher_obj_t *self) { + return rcl_publisher_get_topic_name(&self->rcl_publisher); +} diff --git a/ports/espressif/common-hal/rclcpy/Publisher.h b/ports/espressif/common-hal/rclcpy/Publisher.h new file mode 100644 index 00000000000..fdc45293cd2 --- /dev/null +++ b/ports/espressif/common-hal/rclcpy/Publisher.h @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include "common-hal/rclcpy/Node.h" +#include "common-hal/rclcpy/__init__.h" + +#include +#include +#include +#include +#include +#include + + +typedef struct { + mp_obj_base_t base; + rclcpy_node_obj_t *node; + rcl_publisher_t rcl_publisher; +} rclcpy_publisher_obj_t; diff --git a/ports/espressif/common-hal/rclcpy/__init__.c b/ports/espressif/common-hal/rclcpy/__init__.c new file mode 100644 index 00000000000..e0e6fd8b4f4 --- /dev/null +++ b/ports/espressif/common-hal/rclcpy/__init__.c @@ -0,0 +1,122 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/rclcpy/__init__.h" + +#include "esp_log.h" + +#define RCLCPY_SUPPORT_FAIL 1 +#define RCLCPY_OPTIONS_FAIL 2 + +rclcpy_context_t rclcpy_default_context = { + .initialized = false, + .critical_fail = 0, +}; + +static void *microros_allocate(size_t size, void *state) { + (void)state; + return m_malloc(size); +} + +static void microros_deallocate(void *pointer, void *state) { + (void)state; + m_free(pointer); +} + +static void *microros_reallocate(void *pointer, size_t size, void *state) { + (void)state; + return m_realloc(pointer, size); +} + +static void *microros_zero_allocate(size_t number_of_elements, size_t size_of_element, void *state) { + (void)state; + size_t total_size = number_of_elements * size_of_element; + void *ptr = m_malloc(total_size); + if (ptr != NULL) { + memset(ptr, 0, total_size); + } + return ptr; +} + +void rclcpy_reset(void) { + if (rclcpy_default_context.initialized) { + // Clean up micro-ROS objects + rcl_ret_t ret = rclc_support_fini(&rclcpy_default_context.rcl_support); + if (ret != RCL_RET_OK) { + // ESP_LOGW("RCLCPY", "Support cleanup error: %d", ret); + rclcpy_default_context.critical_fail = RCLCPY_SUPPORT_FAIL; + } + ret = rcl_init_options_fini(&rclcpy_default_context.init_options); + if (ret != RCL_RET_OK) { + // ESP_LOGW("RCLCPY", "Init options cleanup error: %d", ret); + rclcpy_default_context.critical_fail = RCLCPY_OPTIONS_FAIL; + } + + // Reset context state + memset(&rclcpy_default_context, 0, sizeof(rclcpy_default_context)); + rclcpy_default_context.initialized = false; + } +} + +void common_hal_rclcpy_init(const char *agent_ip, const char *agent_port, int16_t domain_id) { + if (rclcpy_default_context.critical_fail != 0) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("Critical ROS failure during soft reboot, reset required: %d"), rclcpy_default_context.critical_fail); + } + + // Set up circuitpython-friendly allocator + rcl_allocator_t custom_allocator = rcutils_get_zero_initialized_allocator(); + custom_allocator.allocate = microros_allocate; + custom_allocator.deallocate = microros_deallocate; + custom_allocator.reallocate = microros_reallocate; + custom_allocator.zero_allocate = microros_zero_allocate; + if (!rcutils_set_default_allocator(&custom_allocator)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ROS memory allocator failure")); + } + rclcpy_default_context.rcl_allocator = custom_allocator; + + rcl_ret_t ret; + + // Micro-ROS options initialization + rclcpy_default_context.init_options = rcl_get_zero_initialized_init_options(); + ret = rcl_init_options_init(&rclcpy_default_context.init_options, rclcpy_default_context.rcl_allocator); + if (ret != RCL_RET_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ROS internal setup failure")); + } + if (domain_id < 0) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid ROS domain ID")); + } + ret = rcl_init_options_set_domain_id(&rclcpy_default_context.init_options, domain_id); + if (ret != RCL_RET_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ROS internal setup failure")); + } + + // Set up Micro-ROS Agent + rclcpy_default_context.rmw_options = rcl_init_options_get_rmw_init_options(&rclcpy_default_context.init_options); + ret = rmw_uros_options_set_udp_address(agent_ip, agent_port, rclcpy_default_context.rmw_options); + if (ret != RCL_RET_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ROS internal setup failure")); + } + + // Final support object init requires a connected agent + ret = rclc_support_init_with_options(&rclcpy_default_context.rcl_support, + 0, + NULL, + &rclcpy_default_context.init_options, + &rclcpy_default_context.rcl_allocator); + if (ret != RCL_RET_OK) { + mp_raise_RuntimeError(MP_ERROR_TEXT("ROS failed to initialize. Is agent connected?")); + } else { + rclcpy_default_context.initialized = true; + } +} + +rclcpy_context_t *common_hal_rclcpy_get_default_context(void) { + return &rclcpy_default_context; +} + +bool common_hal_rclcpy_default_context_is_initialized(void) { + return rclcpy_default_context.initialized; +} diff --git a/ports/espressif/common-hal/rclcpy/__init__.h b/ports/espressif/common-hal/rclcpy/__init__.h new file mode 100644 index 00000000000..f3ebd4787e7 --- /dev/null +++ b/ports/espressif/common-hal/rclcpy/__init__.h @@ -0,0 +1,30 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "py/runtime.h" + +#include +#include +#include +#include +#include +#include + + +typedef struct { + bool initialized; + uint8_t critical_fail; + rcl_allocator_t rcl_allocator; + rclc_support_t rcl_support; + rcl_init_options_t init_options; + rmw_init_options_t *rmw_options; +} rclcpy_context_t; + +extern rclcpy_context_t rclcpy_default_context; +void rclcpy_reset(void); diff --git a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c index ba8b70221b7..f65c7fdd9f1 100644 --- a/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/espressif/common-hal/rotaryio/IncrementalEncoder.c @@ -21,6 +21,10 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode // // These routines also implicitly configure the weak internal pull-ups, as expected // in CircuitPython. + + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + pcnt_unit_config_t unit_config = { // Set counter limit .low_limit = INT16_MIN, @@ -87,6 +91,10 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o pcnt_del_channel(self->channel_a); pcnt_del_channel(self->channel_b); pcnt_del_unit(self->unit); + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { self->unit = NULL; } diff --git a/ports/espressif/common-hal/sdioio/SDCard.c b/ports/espressif/common-hal/sdioio/SDCard.c index 6fd27c28945..35850f2f8ae 100644 --- a/ports/espressif/common-hal/sdioio/SDCard.c +++ b/ports/espressif/common-hal/sdioio/SDCard.c @@ -10,6 +10,7 @@ #include "driver/sdmmc_host.h" #include "ports/espressif/esp-idf/components/sdmmc/include/sdmmc_cmd.h" +#include "extmod/vfs.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/util.h" #include "shared-bindings/sdioio/SDCard.h" @@ -21,6 +22,7 @@ static const char *TAG = "SDCard.c"; static bool slot_in_use[2]; static bool never_reset_sdio[2] = { false, false }; +static bool host_initialized = false; static void common_hal_sdioio_sdcard_check_for_deinit(sdioio_sdcard_obj_t *self) { if (common_hal_sdioio_sdcard_deinited(self)) { @@ -109,21 +111,22 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, if (!slot_in_use[0] && !slot_in_use[1]) { err = sdmmc_host_init(); if (err != ESP_OK) { - mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error %x"), err); + mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error 0x%02x"), err); } + host_initialized = true; } err = sdmmc_host_init_slot(sd_slot, &slot_config); if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to initialize SDMMC slot: %x", err); - mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error %x"), err); + mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error 0x%02x"), err); } // sdmmc_card_t card; // self->card = malloc(sizeof(sdmmc_card_t)); err = sdmmc_card_init(&host, &self->card); if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to initialize SDMMC card: %x", err); - mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error %x"), err); + mp_raise_OSError_msg_varg(MP_ERROR_TEXT("SDIO Init Error 0x%02x"), err); } common_hal_sdioio_sdcard_check_for_deinit(self); @@ -168,32 +171,73 @@ static void check_whole_block(mp_buffer_info_t *bufinfo, int sector_size) { } } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { - common_hal_sdioio_sdcard_check_for_deinit(self); - check_whole_block(bufinfo, self->card.csd.sector_size); - esp_err_t err; - ESP_LOGI(TAG, "in common_hal_sdioio_sdcard_writeblocks"); - // err = sdmmc_io_write_blocks(&self->card, 1, start_block, bufinfo->buf, bufinfo->len); - err = sdmmc_write_sectors(&self->card, bufinfo->buf, start_block, bufinfo->len / self->card.csd.sector_size); +mp_negative_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + ESP_LOGI(TAG, "in sdioio_sdcard_writeblocks"); + esp_err_t err = sdmmc_write_sectors(&self->card, buf, start_block, num_blocks); if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to write blocks with err 0x%X", err); + return -MP_EIO; } return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_negative_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { common_hal_sdioio_sdcard_check_for_deinit(self); check_whole_block(bufinfo, self->card.csd.sector_size); - esp_err_t err; - ESP_LOGI(TAG, "in common_hal_sdioio_sdcard_readblocks"); - // err = sdmmc_io_read_blocks(&self->card, 1, start_block, bufinfo->buf, bufinfo->len); - err = sdmmc_read_sectors(&self->card, bufinfo->buf, start_block, bufinfo->len / self->card.csd.sector_size); + + uint32_t num_blocks = bufinfo->len / self->card.csd.sector_size; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +mp_negative_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + ESP_LOGI(TAG, "in sdioio_sdcard_readblocks"); + esp_err_t err = sdmmc_read_sectors(&self->card, buf, start_block, num_blocks); if (err != ESP_OK) { ESP_LOGW(TAG, "Failed to read blocks with err 0x%X", err); + return -MP_EIO; } return 0; } +mp_negative_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + common_hal_sdioio_sdcard_check_for_deinit(self); + check_whole_block(bufinfo, self->card.csd.sector_size); + + uint32_t num_blocks = bufinfo->len / self->card.csd.sector_size; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { return true; } @@ -210,8 +254,9 @@ void common_hal_sdioio_sdcard_deinit(sdioio_sdcard_obj_t *self) { never_reset_sdio[get_slot_index(self)] = false; slot_in_use[get_slot_index(self)] = false; - if (!slot_in_use[0] && !slot_in_use[1]) { + if (!slot_in_use[0] && !slot_in_use[1] && host_initialized) { sdmmc_host_deinit(); + host_initialized = false; } reset_pin_number(self->command); @@ -245,14 +290,15 @@ void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self) { } } -void sdioio_reset() { +void sdioio_reset(void) { for (size_t i = 0; i < MP_ARRAY_SIZE(slot_in_use); i++) { if (!never_reset_sdio[i]) { slot_in_use[i] = false; } } - if (!slot_in_use[0] && !slot_in_use[1]) { + if (!slot_in_use[0] && !slot_in_use[1] && host_initialized) { sdmmc_host_deinit(); + host_initialized = false; } return; diff --git a/ports/espressif/common-hal/socketpool/Socket.c b/ports/espressif/common-hal/socketpool/Socket.c index 0a36eff95b4..5128e93c858 100644 --- a/ports/espressif/common-hal/socketpool/Socket.c +++ b/ports/espressif/common-hal/socketpool/Socket.c @@ -483,7 +483,7 @@ void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, socklen_t socklen = sizeof(error_code); result = getsockopt(self->num, SOL_SOCKET, SO_ERROR, &error_code, &socklen); if (result < 0 || error_code != 0) { - mp_raise_OSError(errno); + mp_raise_OSError(error_code); } self->connected = true; return; diff --git a/ports/espressif/common-hal/socketpool/SocketPool.c b/ports/espressif/common-hal/socketpool/SocketPool.c index aa7461d3ffe..5d7890af171 100644 --- a/ports/espressif/common-hal/socketpool/SocketPool.c +++ b/ports/espressif/common-hal/socketpool/SocketPool.c @@ -24,18 +24,6 @@ void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *sel // common_hal_socketpool_socket is in socketpool/Socket.c to centralize open socket tracking. int socketpool_getaddrinfo_common(const char *host, int service, const struct addrinfo *hints, struct addrinfo **res) { - // As of 2022, the version of lwip in esp-idf does not handle the - // trailing-dot syntax of domain names, so emulate it. - // Remove this once https://github.com/espressif/esp-idf/issues/10013 has - // been implemented - if (host) { - size_t strlen_host = strlen(host); - if (strlen_host && host[strlen_host - 1] == '.') { - mp_obj_t nodot = mp_obj_new_str(host, strlen_host - 1); - host = mp_obj_str_get_str(nodot); - } - } - char service_buf[6]; snprintf(service_buf, sizeof(service_buf), "%d", service); diff --git a/ports/espressif/common-hal/ssl/crt_bundle.c b/ports/espressif/common-hal/ssl/crt_bundle.c new file mode 100644 index 00000000000..53a07f4db1b --- /dev/null +++ b/ports/espressif/common-hal/ssl/crt_bundle.c @@ -0,0 +1,37 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// In ESP-IDF v5.4, Espressif changed the format of the in-flash cert bundle, which +// made lib/mbedtls_config/crt_bundle.c no longer work. Rather than update that, +// just wrap those functions and use the ESP-IDF versions. + +#include "py/mperrno.h" +#include "mbedtls/x509_crt.h" +#include "lib/mbedtls_config/crt_bundle.h" +#include "esp_crt_bundle.h" + +static int convert_esp_err(esp_err_t ret) { + switch (ret) { + case ESP_OK: + return 0; + default: + // Right now esp_crt_bundle.c doesn't return very specific errors. + case ESP_ERR_INVALID_ARG: + return -MP_EINVAL; + } +} + +int crt_bundle_attach(mbedtls_ssl_config *ssl_conf) { + return convert_esp_err(esp_crt_bundle_attach(ssl_conf)); +} + +void crt_bundle_detach(mbedtls_ssl_config *conf) { + esp_crt_bundle_detach(conf); +} + +int crt_bundle_set(const uint8_t *x509_bundle, size_t bundle_size) { + return convert_esp_err(esp_crt_bundle_set(x509_bundle, bundle_size)); +} diff --git a/ports/espressif/common-hal/touchio/TouchIn.c b/ports/espressif/common-hal/touchio/TouchIn.c index 2a37e6e526f..147acb2cfbf 100644 --- a/ports/espressif/common-hal/touchio/TouchIn.c +++ b/ports/espressif/common-hal/touchio/TouchIn.c @@ -9,9 +9,10 @@ #include "py/runtime.h" #include "peripherals/touch.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/Pull.h" void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, - const mcu_pin_obj_t *pin) { + const mcu_pin_obj_t *pin, const digitalio_pull_t pull) { if (pin->touch_channel == NO_TOUCH_CHANNEL) { raise_ValueError_invalid_pin(); } diff --git a/ports/espressif/common-hal/wifi/Radio.c b/ports/espressif/common-hal/wifi/Radio.c index 1e499b9d1d6..51d4913926f 100644 --- a/ports/espressif/common-hal/wifi/Radio.c +++ b/ports/espressif/common-hal/wifi/Radio.c @@ -13,6 +13,7 @@ #include "common-hal/wifi/__init__.h" #include "shared/runtime/interrupt_char.h" #include "py/gc.h" +#include "py/mphal.h" #include "py/obj.h" #include "py/runtime.h" #include "shared-bindings/ipaddress/IPv4Address.h" @@ -115,7 +116,7 @@ void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *host mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { uint8_t mac[MAC_ADDRESS_LENGTH]; - esp_wifi_get_mac(ESP_IF_WIFI_STA, mac); + esp_wifi_get_mac(WIFI_IF_STA, mac); return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH); } @@ -126,7 +127,7 @@ void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t if ((mac[0] & 0b1) == 0b1) { mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid multicast MAC address")); } - esp_wifi_set_mac(ESP_IF_WIFI_STA, mac); + esp_wifi_set_mac(WIFI_IF_STA, mac); } mp_float_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self) { @@ -139,28 +140,49 @@ void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t esp_wifi_set_max_tx_power(tx_power * 4.0f); } -mp_int_t common_hal_wifi_radio_get_listen_interval(wifi_radio_obj_t *self) { - wifi_config_t *config = &self->sta_config; - return config->sta.listen_interval; +wifi_power_management_t common_hal_wifi_radio_get_power_management(wifi_radio_obj_t *self) { + wifi_ps_type_t ps; + esp_err_t ret = esp_wifi_get_ps(&ps); + if (ret == ESP_OK) { + switch (ps) { + case WIFI_PS_MIN_MODEM: + return POWER_MANAGEMENT_MIN; + case WIFI_PS_MAX_MODEM: + return POWER_MANAGEMENT_MAX; + case WIFI_PS_NONE: + return POWER_MANAGEMENT_NONE; + } + } + return POWER_MANAGEMENT_MIN; } -void common_hal_wifi_radio_set_listen_interval(wifi_radio_obj_t *self, const mp_int_t listen_interval) { - wifi_config_t *config = &self->sta_config; - config->sta.listen_interval = listen_interval; - if (listen_interval == 1) { - esp_wifi_set_ps(WIFI_PS_MIN_MODEM); - } else if (listen_interval > 1) { - esp_wifi_set_ps(WIFI_PS_MAX_MODEM); - } else { - esp_wifi_set_ps(WIFI_PS_NONE); - } - esp_wifi_set_config(ESP_IF_WIFI_STA, config); +void common_hal_wifi_radio_set_power_management(wifi_radio_obj_t *self, wifi_power_management_t power_management) { + switch (power_management) { + case POWER_MANAGEMENT_MIN: + esp_wifi_set_ps(WIFI_PS_MIN_MODEM); + break; + case POWER_MANAGEMENT_MAX: { + // listen_interval is only used in this case. + wifi_config_t *config = &self->sta_config; + // This is a typical value seen in various examples. + config->sta.listen_interval = 3; + esp_wifi_set_ps(WIFI_PS_MAX_MODEM); + esp_wifi_set_config(WIFI_IF_STA, config); + } + break; + case POWER_MANAGEMENT_NONE: + esp_wifi_set_ps(WIFI_PS_NONE); + break; + case POWER_MANAGEMENT_UNKNOWN: + // This should be prevented in shared-bindings. + break; + } } mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) { uint8_t mac[MAC_ADDRESS_LENGTH]; - esp_wifi_get_mac(ESP_IF_WIFI_AP, mac); + esp_wifi_get_mac(WIFI_IF_AP, mac); return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH); } @@ -171,7 +193,7 @@ void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint if ((mac[0] & 0b1) == 0b1) { mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid multicast MAC address")); } - esp_wifi_set_mac(ESP_IF_WIFI_AP, mac); + esp_wifi_set_mac(WIFI_IF_AP, mac); } mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel) { @@ -179,7 +201,7 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, u mp_raise_RuntimeError(MP_ERROR_TEXT("Already scanning for wifi networks")); } if (!common_hal_wifi_radio_get_enabled(self)) { - mp_raise_RuntimeError(MP_ERROR_TEXT("wifi is not enabled")); + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); } set_mode_station(self, true); @@ -248,6 +270,13 @@ void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_ config->ap.max_connection = max_connections; esp_wifi_set_config(WIFI_IF_AP, config); + // Wait a few ms for the AP to start. Empirically, this takes < 3ms on ESP32, and < 1ms on other chips. + for (size_t ms = 0; ms < 10; ms++) { + if (common_hal_wifi_radio_get_ap_active(self)) { + break; + } + mp_hal_delay_ms(1); + } } bool common_hal_wifi_radio_get_ap_active(wifi_radio_obj_t *self) { @@ -298,7 +327,7 @@ mp_obj_t common_hal_wifi_radio_get_stations_ap(wifi_radio_obj_t *self) { wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t *bssid, size_t bssid_len) { if (!common_hal_wifi_radio_get_enabled(self)) { - mp_raise_RuntimeError(MP_ERROR_TEXT("wifi is not enabled")); + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); } wifi_config_t *config = &self->sta_config; @@ -365,7 +394,7 @@ wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t } else { config->sta.scan_method = WIFI_FAST_SCAN; } - esp_wifi_set_config(ESP_IF_WIFI_STA, config); + esp_wifi_set_config(WIFI_IF_STA, config); self->starting_retries = 5; self->retries_left = 5; esp_wifi_connect(); diff --git a/ports/espressif/common-hal/wifi/__init__.c b/ports/espressif/common-hal/wifi/__init__.c index c2a63ceede7..7a9aea3b5e0 100644 --- a/ports/espressif/common-hal/wifi/__init__.c +++ b/ports/espressif/common-hal/wifi/__init__.c @@ -30,6 +30,10 @@ wifi_radio_obj_t common_hal_wifi_radio_obj; #include "lwip/sockets.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" +#endif + #if CIRCUITPY_STATUS_BAR #include "supervisor/shared/status_bar.h" #endif @@ -40,6 +44,8 @@ wifi_radio_obj_t common_hal_wifi_radio_obj; #include "nvs_flash.h" #endif +#define MAC_ADDRESS_LENGTH 6 + static const char *TAG = "CP wifi"; static void schedule_background_on_cp_core(void *arg) { @@ -86,7 +92,192 @@ static void event_handler(void *arg, esp_event_base_t event_base, ESP_LOGW(TAG, "disconnected"); wifi_event_sta_disconnected_t *d = (wifi_event_sta_disconnected_t *)event_data; uint8_t reason = d->reason; - ESP_LOGW(TAG, "reason %d 0x%02x", reason, reason); + const char *reason_str = "unknown"; + switch (reason) { + case WIFI_REASON_UNSPECIFIED: + reason_str = "unspecified"; + break; + case WIFI_REASON_AUTH_EXPIRE: + reason_str = "auth expire"; + break; + case WIFI_REASON_AUTH_LEAVE: + reason_str = "auth leave"; + break; + case WIFI_REASON_DISASSOC_DUE_TO_INACTIVITY: + reason_str = "disassoc inactivity"; + break; + case WIFI_REASON_ASSOC_TOOMANY: + reason_str = "assoc toomany"; + break; + case WIFI_REASON_CLASS2_FRAME_FROM_NONAUTH_STA: + reason_str = "class2 from nonauth"; + break; + case WIFI_REASON_CLASS3_FRAME_FROM_NONASSOC_STA: + reason_str = "class3 from nonassoc"; + break; + case WIFI_REASON_ASSOC_LEAVE: + reason_str = "assoc leave"; + break; + case WIFI_REASON_ASSOC_NOT_AUTHED: + reason_str = "assoc not authed"; + break; + case WIFI_REASON_DISASSOC_PWRCAP_BAD: + reason_str = "disassoc pwrcap bad"; + break; + case WIFI_REASON_DISASSOC_SUPCHAN_BAD: + reason_str = "disassoc supchan bad"; + break; + case WIFI_REASON_BSS_TRANSITION_DISASSOC: + reason_str = "bss transition disassoc"; + break; + case WIFI_REASON_IE_INVALID: + reason_str = "ie invalid"; + break; + case WIFI_REASON_MIC_FAILURE: + reason_str = "mic failure"; + break; + case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: + reason_str = "4way handshake timeout"; + break; + case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT: + reason_str = "group key update timeout"; + break; + case WIFI_REASON_IE_IN_4WAY_DIFFERS: + reason_str = "ie in 4way differs"; + break; + case WIFI_REASON_GROUP_CIPHER_INVALID: + reason_str = "group cipher invalid"; + break; + case WIFI_REASON_PAIRWISE_CIPHER_INVALID: + reason_str = "pairwise cipher invalid"; + break; + case WIFI_REASON_AKMP_INVALID: + reason_str = "akmp invalid"; + break; + case WIFI_REASON_UNSUPP_RSN_IE_VERSION: + reason_str = "unsupp rsn ie version"; + break; + case WIFI_REASON_INVALID_RSN_IE_CAP: + reason_str = "invalid rsn ie cap"; + break; + case WIFI_REASON_802_1X_AUTH_FAILED: + reason_str = "802.1x auth failed"; + break; + case WIFI_REASON_CIPHER_SUITE_REJECTED: + reason_str = "cipher suite rejected"; + break; + case WIFI_REASON_TDLS_PEER_UNREACHABLE: + reason_str = "tdls peer unreachable"; + break; + case WIFI_REASON_TDLS_UNSPECIFIED: + reason_str = "tdls unspecified"; + break; + case WIFI_REASON_SSP_REQUESTED_DISASSOC: + reason_str = "ssp requested disassoc"; + break; + case WIFI_REASON_NO_SSP_ROAMING_AGREEMENT: + reason_str = "no ssp roaming agreement"; + break; + case WIFI_REASON_BAD_CIPHER_OR_AKM: + reason_str = "bad cipher or akm"; + break; + case WIFI_REASON_NOT_AUTHORIZED_THIS_LOCATION: + reason_str = "not authorized this location"; + break; + case WIFI_REASON_SERVICE_CHANGE_PERCLUDES_TS: + reason_str = "service change precludes ts"; + break; + case WIFI_REASON_UNSPECIFIED_QOS: + reason_str = "unspecified qos"; + break; + case WIFI_REASON_NOT_ENOUGH_BANDWIDTH: + reason_str = "not enough bandwidth"; + break; + case WIFI_REASON_MISSING_ACKS: + reason_str = "missing acks"; + break; + case WIFI_REASON_EXCEEDED_TXOP: + reason_str = "exceeded txop"; + break; + case WIFI_REASON_STA_LEAVING: + reason_str = "sta leaving"; + break; + case WIFI_REASON_END_BA: + reason_str = "end ba"; + break; + case WIFI_REASON_UNKNOWN_BA: + reason_str = "unknown ba"; + break; + case WIFI_REASON_TIMEOUT: + reason_str = "timeout"; + break; + case WIFI_REASON_PEER_INITIATED: + reason_str = "peer initiated"; + break; + case WIFI_REASON_AP_INITIATED: + reason_str = "ap initiated"; + break; + case WIFI_REASON_INVALID_FT_ACTION_FRAME_COUNT: + reason_str = "invalid ft action frame count"; + break; + case WIFI_REASON_INVALID_PMKID: + reason_str = "invalid pmkid"; + break; + case WIFI_REASON_INVALID_MDE: + reason_str = "invalid mde"; + break; + case WIFI_REASON_INVALID_FTE: + reason_str = "invalid fte"; + break; + case WIFI_REASON_TRANSMISSION_LINK_ESTABLISH_FAILED: + reason_str = "transmission link establish failed"; + break; + case WIFI_REASON_ALTERATIVE_CHANNEL_OCCUPIED: + reason_str = "alternative channel occupied"; + break; + case WIFI_REASON_BEACON_TIMEOUT: + reason_str = "beacon timeout"; + break; + case WIFI_REASON_NO_AP_FOUND: + reason_str = "no ap found"; + break; + case WIFI_REASON_AUTH_FAIL: + reason_str = "auth fail"; + break; + case WIFI_REASON_ASSOC_FAIL: + reason_str = "assoc fail"; + break; + case WIFI_REASON_HANDSHAKE_TIMEOUT: + reason_str = "handshake timeout"; + break; + case WIFI_REASON_CONNECTION_FAIL: + reason_str = "connection fail"; + break; + case WIFI_REASON_AP_TSF_RESET: + reason_str = "ap tsf reset"; + break; + case WIFI_REASON_ROAMING: + reason_str = "roaming"; + break; + case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG: + reason_str = "assoc comeback time too long"; + break; + case WIFI_REASON_SA_QUERY_TIMEOUT: + reason_str = "sa query timeout"; + break; + case WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY: + reason_str = "no ap found w compatible security"; + break; + case WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD: + reason_str = "no ap found in authmode threshold"; + break; + case WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD: + reason_str = "no ap found in rssi threshold"; + break; + default: + break; + } + ESP_LOGW(TAG, "reason %d 0x%02x %s", reason, reason, reason_str); if (radio->retries_left > 0 && reason != WIFI_REASON_AUTH_FAIL && reason != WIFI_REASON_NO_AP_FOUND && @@ -102,12 +293,132 @@ static void event_handler(void *arg, esp_event_base_t event_base, break; } - // Cases to handle later. - // case WIFI_EVENT_STA_AUTHMODE_CHANGE: - default: { - ESP_LOGW(TAG, "event %ld 0x%02ld", event_id, event_id); + case WIFI_EVENT_WIFI_READY: + ESP_LOGW(TAG, "wifi ready"); + break; + case WIFI_EVENT_STA_AUTHMODE_CHANGE: + ESP_LOGW(TAG, "sta authmode change"); + break; + case WIFI_EVENT_STA_WPS_ER_SUCCESS: + ESP_LOGW(TAG, "sta wps er success"); + break; + case WIFI_EVENT_STA_WPS_ER_FAILED: + ESP_LOGW(TAG, "sta wps er failed"); + break; + case WIFI_EVENT_STA_WPS_ER_TIMEOUT: + ESP_LOGW(TAG, "sta wps er timeout"); + break; + case WIFI_EVENT_STA_WPS_ER_PIN: + ESP_LOGW(TAG, "sta wps er pin"); + break; + case WIFI_EVENT_STA_WPS_ER_PBC_OVERLAP: + ESP_LOGW(TAG, "sta wps er pbc overlap"); + break; + case WIFI_EVENT_AP_PROBEREQRECVED: + ESP_LOGW(TAG, "ap probereqrecved"); + break; + case WIFI_EVENT_FTM_REPORT: + ESP_LOGW(TAG, "ftm report"); + break; + case WIFI_EVENT_STA_BSS_RSSI_LOW: + ESP_LOGW(TAG, "sta bss rssi low"); + break; + case WIFI_EVENT_ACTION_TX_STATUS: + ESP_LOGW(TAG, "action tx status"); + break; + case WIFI_EVENT_ROC_DONE: + ESP_LOGW(TAG, "roc done"); + break; + case WIFI_EVENT_STA_BEACON_TIMEOUT: + ESP_LOGW(TAG, "sta beacon timeout"); + break; + case WIFI_EVENT_CONNECTIONLESS_MODULE_WAKE_INTERVAL_START: + ESP_LOGW(TAG, "connectionless module wake interval start"); + break; + case WIFI_EVENT_AP_WPS_RG_SUCCESS: + ESP_LOGW(TAG, "ap wps rg success"); + break; + case WIFI_EVENT_AP_WPS_RG_FAILED: + ESP_LOGW(TAG, "ap wps rg failed"); + break; + case WIFI_EVENT_AP_WPS_RG_TIMEOUT: + ESP_LOGW(TAG, "ap wps rg timeout"); + break; + case WIFI_EVENT_AP_WPS_RG_PIN: + ESP_LOGW(TAG, "ap wps rg pin"); + break; + case WIFI_EVENT_AP_WPS_RG_PBC_OVERLAP: + ESP_LOGW(TAG, "ap wps rg pbc overlap"); + break; + case WIFI_EVENT_ITWT_SETUP: + ESP_LOGW(TAG, "itwt setup"); + break; + case WIFI_EVENT_ITWT_TEARDOWN: + ESP_LOGW(TAG, "itwt teardown"); + break; + case WIFI_EVENT_ITWT_PROBE: + ESP_LOGW(TAG, "itwt probe"); + break; + case WIFI_EVENT_ITWT_SUSPEND: + ESP_LOGW(TAG, "itwt suspend"); + break; + case WIFI_EVENT_TWT_WAKEUP: + ESP_LOGW(TAG, "twt wakeup"); + break; + case WIFI_EVENT_BTWT_SETUP: + ESP_LOGW(TAG, "btwt setup"); + break; + case WIFI_EVENT_BTWT_TEARDOWN: + ESP_LOGW(TAG, "btwt teardown"); + break; + case WIFI_EVENT_NAN_SYNC_STARTED: + ESP_LOGW(TAG, "nan sync started"); + break; + case WIFI_EVENT_NAN_SYNC_STOPPED: + ESP_LOGW(TAG, "nan sync stopped"); + break; + case WIFI_EVENT_NAN_SVC_MATCH: + ESP_LOGW(TAG, "nan svc match"); + break; + case WIFI_EVENT_NAN_REPLIED: + ESP_LOGW(TAG, "nan replied"); + break; + case WIFI_EVENT_NAN_RECEIVE: + ESP_LOGW(TAG, "nan receive"); + break; + case WIFI_EVENT_NDP_INDICATION: + ESP_LOGW(TAG, "ndp indication"); + break; + case WIFI_EVENT_NDP_CONFIRM: + ESP_LOGW(TAG, "ndp confirm"); + break; + case WIFI_EVENT_NDP_TERMINATED: + ESP_LOGW(TAG, "ndp terminated"); + break; + case WIFI_EVENT_HOME_CHANNEL_CHANGE: + ESP_LOGW(TAG, "home channel change"); + break; + case WIFI_EVENT_STA_NEIGHBOR_REP: + ESP_LOGW(TAG, "sta neighbor rep"); + break; + case WIFI_EVENT_AP_WRONG_PASSWORD: + ESP_LOGW(TAG, "ap wrong password"); + break; + case WIFI_EVENT_STA_BEACON_OFFSET_UNSTABLE: + ESP_LOGW(TAG, "sta beacon offset unstable"); + break; + case WIFI_EVENT_DPP_URI_READY: + ESP_LOGW(TAG, "dpp uri ready"); + break; + case WIFI_EVENT_DPP_CFG_RECVD: + ESP_LOGW(TAG, "dpp cfg recvd"); + break; + case WIFI_EVENT_DPP_FAILED: + ESP_LOGW(TAG, "dpp failed"); + break; + default: + ESP_LOGW(TAG, "unknown event %ld", event_id); break; - } } } @@ -144,8 +455,8 @@ void common_hal_wifi_init(bool user_initiated) { common_hal_wifi_radio_obj.base.type = &wifi_radio_type; if (!wifi_ever_inited) { - ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); + ESP_ERROR_CHECK(esp_netif_init()); wifi_ever_inited = true; } @@ -173,6 +484,7 @@ void common_hal_wifi_init(bool user_initiated) { &self->handler_instance_got_ip)); wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT(); + esp_err_t result = esp_wifi_init(&config); #ifdef CONFIG_ESP32_WIFI_NVS_ENABLED // Generally we don't use this because we store ssid and passwords ourselves in the filesystem. esp_err_t err = nvs_flash_init(); @@ -183,8 +495,10 @@ void common_hal_wifi_init(bool user_initiated) { err = nvs_flash_init(); } ESP_ERROR_CHECK(err); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH)); + #else + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); #endif - esp_err_t result = esp_wifi_init(&config); if (result == ESP_ERR_NO_MEM) { if (gc_alloc_possible()) { mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Failed to allocate Wifi memory")); @@ -197,6 +511,36 @@ void common_hal_wifi_init(bool user_initiated) { ESP_LOGE(TAG, "WiFi error code: %x", result); return; } + + #if CIRCUITPY_SETTINGS_TOML + char hostname[CONFIG_LWIP_DHCPS_MAX_HOSTNAME_LEN]; + if (settings_get_str("CIRCUITPY_WIFI_HOSTNAME", hostname, sizeof(hostname)) == SETTINGS_OK) { + ESP_ERROR_CHECK(esp_netif_set_hostname(self->netif, hostname)); + } + #else + if (false) { + } + #endif + else { + // Set the default lwip_local_hostname capped at 32 characters. We trim off + // the start of the board name (likely manufacturer) because the end is + // often more unique to the board. + size_t board_len = MIN(32 - ((MAC_ADDRESS_LENGTH * 2) + 6), strlen(CIRCUITPY_BOARD_ID)); + size_t board_trim = strlen(CIRCUITPY_BOARD_ID) - board_len; + // Avoid double _ in the hostname. + if (CIRCUITPY_BOARD_ID[board_trim] == '_') { + board_trim++; + } + + char cpy_default_hostname[board_len + (MAC_ADDRESS_LENGTH * 2) + 6]; + uint8_t mac[MAC_ADDRESS_LENGTH]; + esp_wifi_get_mac(WIFI_IF_STA, mac); + snprintf(cpy_default_hostname, sizeof(cpy_default_hostname), "cpy-%s-%02x%02x%02x%02x%02x%02x", CIRCUITPY_BOARD_ID + board_trim, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + + const char *default_lwip_local_hostname = cpy_default_hostname; + ESP_ERROR_CHECK(esp_netif_set_hostname(self->netif, default_lwip_local_hostname)); + } + // set station mode to avoid the default SoftAP common_hal_wifi_radio_start_station(self); // start wifi diff --git a/ports/espressif/esp-camera b/ports/espressif/esp-camera index d529ebdffb8..303985ab678 160000 --- a/ports/espressif/esp-camera +++ b/ports/espressif/esp-camera @@ -1 +1 @@ -Subproject commit d529ebdffb84131b1aadaec32a7373b319b70391 +Subproject commit 303985ab678391b78ebe0baff98edcc863f296c2 diff --git a/ports/espressif/esp-idf b/ports/espressif/esp-idf index 3ecf6bafcf0..2b900d1222c 160000 --- a/ports/espressif/esp-idf +++ b/ports/espressif/esp-idf @@ -1 +1 @@ -Subproject commit 3ecf6bafcf045e0d2705ef49524456801df4f754 +Subproject commit 2b900d1222cfce5dfa340ed99375af69ec1ee192 diff --git a/ports/espressif/esp-idf-config/partitions-4MB-no-ota-no-uf2-large-user_fs.csv b/ports/espressif/esp-idf-config/partitions-4MB-no-ota-no-uf2-large-user_fs.csv new file mode 100644 index 00000000000..59e0d9d1212 --- /dev/null +++ b/ports/espressif/esp-idf-config/partitions-4MB-no-ota-no-uf2-large-user_fs.csv @@ -0,0 +1,7 @@ +# Name, Type, SubType, Offset, Size +# bootloader, app, boot, 0x1000/0x0, 28/32K +# partition_table, data, table, 0x8000, 4K +nvs, data, nvs, 0x9000, 20K +otadata, data, ota, 0xe000, 8K +ota_0, app, ota_0, 0x10000, 2048K +user_fs, data, fat, 0x210000, 1984K diff --git a/ports/espressif/esp-idf-config/partitions-4MB-no-ota-no-uf2.csv b/ports/espressif/esp-idf-config/partitions-4MB-no-ota-no-uf2.csv index 59e0d9d1212..49d043d7672 100644 --- a/ports/espressif/esp-idf-config/partitions-4MB-no-ota-no-uf2.csv +++ b/ports/espressif/esp-idf-config/partitions-4MB-no-ota-no-uf2.csv @@ -3,5 +3,5 @@ # partition_table, data, table, 0x8000, 4K nvs, data, nvs, 0x9000, 20K otadata, data, ota, 0xe000, 8K -ota_0, app, ota_0, 0x10000, 2048K -user_fs, data, fat, 0x210000, 1984K +ota_0, app, ota_0, 0x10000, 2816K +user_fs, data, fat, 0x2d0000, 1216K diff --git a/ports/espressif/esp-idf-config/sdkconfig-debug.defaults b/ports/espressif/esp-idf-config/sdkconfig-debug.defaults index a9c8e34e547..368ba81bb4a 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-debug.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-debug.defaults @@ -7,6 +7,21 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y # end of Compiler options +# Bootloader config +# +# +# Log +# +# +# Format +# +CONFIG_BOOTLOADER_LOG_COLORS=y +# end of Format + +# end of Log + +# end of Bootloader config + # # Component config # @@ -19,6 +34,17 @@ CONFIG_ESP_CONSOLE_SECONDARY_NONE=y # CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG is not set # end of ESP System Settings +# +# Log +# +# +# Format +# +CONFIG_LOG_COLORS=y +# end of Format + +# end of Log + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults index 5789c442a62..1b2698068ed 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32.defaults @@ -62,10 +62,10 @@ CONFIG_ESP_IPC_TASK_STACK_SIZE=1536 # end of Wi-Fi # -# Newlib +# LibC # -CONFIG_NEWLIB_NANO_FORMAT=y -# end of Newlib +CONFIG_LIBC_NEWLIB_NANO_FORMAT=y +# end of LibC # # SPI Flash driver diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32c2.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32c2.defaults index bf9e57494c7..661b2b52801 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32c2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32c2.defaults @@ -1,6 +1,10 @@ # # Espressif IoT Development Framework Configuration # +# Compiler options +# +CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS=y +# end of Compiler options # # Component config # @@ -39,10 +43,10 @@ CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=4 # end of Wi-Fi # -# Newlib +# LibC # -CONFIG_NEWLIB_NANO_FORMAT=y -# end of Newlib +CONFIG_LIBC_NEWLIB_NANO_FORMAT=y +# end of LibC # end of Component config diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults index bf9e57494c7..661b2b52801 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32c3.defaults @@ -1,6 +1,10 @@ # # Espressif IoT Development Framework Configuration # +# Compiler options +# +CONFIG_COMPILER_SAVE_RESTORE_LIBCALLS=y +# end of Compiler options # # Component config # @@ -39,10 +43,10 @@ CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=4 # end of Wi-Fi # -# Newlib +# LibC # -CONFIG_NEWLIB_NANO_FORMAT=y -# end of Newlib +CONFIG_LIBC_NEWLIB_NANO_FORMAT=y +# end of LibC # end of Component config diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults index 85dde905f3c..63f42cac952 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32c6.defaults @@ -49,6 +49,12 @@ CONFIG_ESP_PHY_ENABLE_USB=y CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=4 # end of Wi-Fi +# +# mbedTLS +# +# CONFIG_MBEDTLS_HARDWARE_SHA is not set +# end of mbedTLS + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32c61.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32c61.defaults new file mode 100644 index 00000000000..85dde905f3c --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32c61.defaults @@ -0,0 +1,54 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# Bluetooth +# +CONFIG_BT_ENABLED=y +CONFIG_BT_NIMBLE_ENABLED=y +# +# NimBLE Options +# +CONFIG_BT_NIMBLE_LOG_LEVEL_NONE=y +CONFIG_BT_NIMBLE_NVS_PERSIST=y +# +# Memory Settings +# +CONFIG_BT_NIMBLE_TRANSPORT_ACL_FROM_LL_COUNT=20 +CONFIG_BT_NIMBLE_TRANSPORT_EVT_SIZE=70 +# end of Memory Settings + +CONFIG_BT_NIMBLE_EXT_ADV=y +# end of NimBLE Options + +# end of Bluetooth + +# +# Driver Configurations +# +# +# PCNT Configuration +# +CONFIG_PCNT_CTRL_FUNC_IN_IRAM=y +# end of PCNT Configuration + +# end of Driver Configurations + +# +# PHY +# +CONFIG_ESP_PHY_ENABLE_USB=y +# end of PHY + +# +# Wi-Fi +# +CONFIG_ESP_WIFI_STATIC_RX_BUFFER_NUM=4 +# end of Wi-Fi + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32p4.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32p4.defaults index e69de29bb2d..0806066e20b 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32p4.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32p4.defaults @@ -0,0 +1,21 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Component config +# +# +# Bluetooth +# +# CONFIG_BT_ENABLED is not set +# end of Bluetooth + +# +# mbedTLS +# +# CONFIG_MBEDTLS_CMAC_C is not set +# end of mbedTLS + +# end of Component config + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults index 66e06667a1a..126b49c6fd3 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s2.defaults @@ -43,10 +43,10 @@ CONFIG_ESP_WIFI_RX_BA_WIN=4 # end of Wi-Fi # -# Newlib +# LibC # -CONFIG_NEWLIB_NANO_FORMAT=y -# end of Newlib +CONFIG_LIBC_NEWLIB_NANO_FORMAT=y +# end of LibC # # Ultra Low Power (ULP) Co-processor @@ -55,7 +55,7 @@ CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_FSM=y CONFIG_ULP_COPROC_TYPE_RISCV=y # Note: enabling both ULPs simultaneously only works due to a modification of adafruit/esp-idf # (see adafruit/esp-idf/pull/16) until espressif/esp-idf/issues/12999 is fixed. -CONFIG_ULP_COPROC_RESERVE_MEM=8176 +CONFIG_ULP_COPROC_RESERVE_MEM=8144 # end of Ultra Low Power (ULP) Co-processor # end of Component config diff --git a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults index fe3c3e0a2da..b48bb58df3f 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-esp32s3.defaults @@ -83,10 +83,10 @@ CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=16 # end of Wi-Fi # -# Newlib +# LibC # -CONFIG_NEWLIB_NANO_FORMAT=y -# end of Newlib +CONFIG_LIBC_NEWLIB_NANO_FORMAT=y +# end of LibC # # Ultra Low Power (ULP) Co-processor @@ -95,7 +95,7 @@ CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_FSM=y CONFIG_ULP_COPROC_TYPE_RISCV=y # Note: enabling both ULPs simultaneously only works due to a modification of adafruit/esp-idf # (see adafruit/esp-idf/pull/16) until espressif/esp-idf/issues/12999 is fixed. -CONFIG_ULP_COPROC_RESERVE_MEM=8176 +CONFIG_ULP_COPROC_RESERVE_MEM=8144 # end of Ultra Low Power (ULP) Co-processor # end of Component config diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-120m.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-120m.defaults index fadf55d8d79..d582a77798c 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-flash-120m.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-120m.defaults @@ -1,15 +1,4 @@ CONFIG_ESPTOOLPY_FLASHFREQ_120M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_64M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_60M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_48M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_32M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_30M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_24M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_16M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_15M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y CONFIG_SPI_FLASH_UNDER_HIGH_FREQ=y +CONFIG_SPI_FLASH_HPM_ENA=y +CONFIG_BOOTLOADER_FLASH_DC_AWARE=y diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-2MB-no-ota-no-uf2.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-2MB-no-ota-no-uf2.defaults index 2d0b2ac5eb9..21365b751d1 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-flash-2MB-no-ota-no-uf2.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-2MB-no-ota-no-uf2.defaults @@ -7,7 +7,6 @@ CONFIG_ESPTOOLPY_FLASHSIZE_2MB=y # CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set CONFIG_ESPTOOLPY_FLASHSIZE="2MB" -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y # end of Serial flasher config CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-2MB-no-ota-no-uf2.csv" diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-32MB.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-32MB.defaults index bbdd32afb81..a5a93778864 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-flash-32MB.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-32MB.defaults @@ -8,7 +8,6 @@ # CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set CONFIG_ESPTOOLPY_FLASHSIZE_32MB=y CONFIG_ESPTOOLPY_FLASHSIZE="32MB" -CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y # end of Serial flasher config CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-32MB.csv" diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-40m.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-40m.defaults index 235a62a57ee..ffc4b5c1cb8 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-flash-40m.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-40m.defaults @@ -1,14 +1 @@ -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_64M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_60M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_48M is not set CONFIG_ESPTOOLPY_FLASHFREQ_40M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_32M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_30M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_24M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_16M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_15M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT is not set diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-48m.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-48m.defaults index b710fd22554..f6838e88703 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-flash-48m.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-48m.defaults @@ -1,14 +1 @@ -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_64M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_60M is not set CONFIG_ESPTOOLPY_FLASHFREQ_48M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_32M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_30M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_24M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_16M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_15M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_48M_DEFAULT=y diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-4MB-no-ota-no-uf2-large-user_fs.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-4MB-no-ota-no-uf2-large-user_fs.defaults new file mode 100644 index 00000000000..0a585e9d523 --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-4MB-no-ota-no-uf2-large-user_fs.defaults @@ -0,0 +1,25 @@ +# +# Espressif IoT Development Framework Configuration +# +# +# Serial flasher config +# +# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_32MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_64MB is not set +# CONFIG_ESPTOOLPY_FLASHSIZE_128MB is not set +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +# end of Serial flasher config + +# +# Partition Table +# +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="esp-idf-config/partitions-4MB-no-ota-no-uf2-large-user_fs.csv" +CONFIG_PARTITION_TABLE_FILENAME="esp-idf-config/partitions-4MB-no-ota-no-uf2-large-user_fs.csv" +# end of Partition Table + +# end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-60m.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-60m.defaults index 7068d0ce740..797665f527f 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-flash-60m.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-60m.defaults @@ -1,14 +1 @@ -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_64M is not set CONFIG_ESPTOOLPY_FLASHFREQ_60M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_48M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_32M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_30M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_24M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_16M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_15M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT is not set diff --git a/ports/espressif/esp-idf-config/sdkconfig-flash-80m.defaults b/ports/espressif/esp-idf-config/sdkconfig-flash-80m.defaults index 2ea44190037..7014fa95495 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-flash-80m.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-flash-80m.defaults @@ -1,14 +1 @@ -# CONFIG_ESPTOOLPY_FLASHFREQ_120M is not set CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -# CONFIG_ESPTOOLPY_FLASHFREQ_64M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_60M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_48M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_40M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_32M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_30M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_24M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_16M is not set -# CONFIG_ESPTOOLPY_FLASHFREQ_15M is not set -CONFIG_ESPTOOLPY_FLASHFREQ_80M_DEFAULT=y diff --git a/ports/espressif/esp-idf-config/sdkconfig-opt.defaults b/ports/espressif/esp-idf-config/sdkconfig-opt.defaults index 16f5b990386..0da23e81227 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-opt.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-opt.defaults @@ -38,6 +38,24 @@ CONFIG_ESP_CONSOLE_SECONDARY_NONE=y CONFIG_LOG_DEFAULT_LEVEL_NONE=y # end of Log output +# +# Log +# +# +# Log Level +# +# +# Level Settings +# +# CONFIG_LOG_DYNAMIC_LEVEL_CONTROL is not set +CONFIG_LOG_TAG_LEVEL_IMPL_NONE=y +# CONFIG_LOG_TAG_LEVEL_IMPL_CACHE_AND_LINKED_LIST is not set +# end of Level Settings + +# end of Log Level + +# end of Log + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig-psram-16MB.defaults b/ports/espressif/esp-idf-config/sdkconfig-psram-16MB.defaults new file mode 100644 index 00000000000..f3f2fc60bc6 --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-psram-16MB.defaults @@ -0,0 +1,5 @@ +# CONFIG_SPIRAM_TYPE_AUTO is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM16 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM32 is not set +# CONFIG_SPIRAM_TYPE_ESPPSRAM64 is not set +CONFIG_SPIRAM_TYPE_AUTO=y diff --git a/ports/espressif/esp-idf-config/sdkconfig-psram-200m.defaults b/ports/espressif/esp-idf-config/sdkconfig-psram-200m.defaults new file mode 100644 index 00000000000..8fdb028c734 --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-psram-200m.defaults @@ -0,0 +1,4 @@ +# For ESP32-P4 +CONFIG_SPIRAM_SPEED_200M=y +# CONFIG_SPIRAM_SPEED_20M is not set +CONFIG_SPIRAM_SPEED=200 diff --git a/ports/espressif/esp-idf-config/sdkconfig-psram-hpi.defaults b/ports/espressif/esp-idf-config/sdkconfig-psram-hpi.defaults new file mode 100644 index 00000000000..4795ee78772 --- /dev/null +++ b/ports/espressif/esp-idf-config/sdkconfig-psram-hpi.defaults @@ -0,0 +1,3 @@ +# CONFIG_SPIRAM_MODE_QUAD is not set +# CONFIG_SPIRAM_MODE_OCT is not set +CONFIG_SPIRAM_MODE_HEX=y diff --git a/ports/espressif/esp-idf-config/sdkconfig-psram.defaults b/ports/espressif/esp-idf-config/sdkconfig-psram.defaults index 3d4dc69178e..6dafa51ed1d 100644 --- a/ports/espressif/esp-idf-config/sdkconfig-psram.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig-psram.defaults @@ -22,6 +22,11 @@ CONFIG_SPIRAM_USE_CAPS_ALLOC=y CONFIG_ESP_WIFI_CACHE_TX_BUFFER_NUM=16 # end of Wi-Fi +# +# mbedTLS +# +CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y + # end of Component config # end of Espressif IoT Development Framework Configuration diff --git a/ports/espressif/esp-idf-config/sdkconfig.defaults b/ports/espressif/esp-idf-config/sdkconfig.defaults index 2d877783868..9859e5e94a8 100644 --- a/ports/espressif/esp-idf-config/sdkconfig.defaults +++ b/ports/espressif/esp-idf-config/sdkconfig.defaults @@ -17,9 +17,15 @@ CONFIG_PARTITION_TABLE_CUSTOM=y # GPTimer Configuration # CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y -CONFIG_GPTIMER_ISR_IRAM_SAFE=y +CONFIG_GPTIMER_ISR_CACHE_SAFE=y # end of GPTimer Configuration +# +# Touch Configuration +# +CONFIG_TOUCH_SUPPRESS_DEPRECATE_WARN=y +# end of Touch Configuration + # end of Driver Configurations # @@ -39,6 +45,7 @@ CONFIG_PM_ENABLE=y # required for CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384 # CONFIG_ESP_TASK_WDT_INIT is not set # CONFIG_ESP_DEBUG_OCDAWARE is not set +# CONFIG_ESP_SYSTEM_HW_STACK_GUARD is not set # end of ESP System Settings @@ -58,28 +65,24 @@ CONFIG_ESP_MAIN_TASK_STACK_SIZE=16384 CONFIG_FREERTOS_HZ=1000 # end of Kernel +# +# LibC +# +# end of LibC + # # LWIP # +CONFIG_LWIP_TCPIP_TASK_STACK_SIZE=4096 CONFIG_LWIP_MAX_SOCKETS=8 CONFIG_LWIP_SO_RCVBUF=y # # IPv6 # CONFIG_LWIP_IPV6_AUTOCONFIG=y -CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS=2 +CONFIG_LWIP_IPV6_RDNSS_MAX_DNS_SERVERS=0 CONFIG_LWIP_IPV6_DHCP6=y # -# TCP -# -CONFIG_LWIP_MAX_ACTIVE_TCP=4 -CONFIG_LWIP_MAX_LISTENING_TCP=4 -CONFIG_LWIP_TCP_SYNMAXRTX=6 -CONFIG_LWIP_TCP_SND_BUF_DEFAULT=2880 -CONFIG_LWIP_TCP_WND_DEFAULT=2880 -CONFIG_LWIP_TCP_RTO_TIME=3000 -# end of TCP - # end of LWIP # @@ -95,9 +98,7 @@ CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=2048 # # Certificate Bundle # -CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_NONE=y -CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y -CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="../../lib/certificates/data/roots.pem" +CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_FULL=y # end of Certificate Bundle # CONFIG_MBEDTLS_GCM_SUPPORT_NON_AES_CIPHER is not set @@ -114,16 +115,12 @@ CONFIG_MBEDTLS_SSL_PROTO_DTLS=y # CONFIG_MBEDTLS_PEM_WRITE_C is not set # end of Certificates -# CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED is not set -# CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED is not set # CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED is not set -# CONFIG_MBEDTLS_ECP_DP_SECP192K1_ENABLED is not set -# CONFIG_MBEDTLS_ECP_DP_SECP224K1_ENABLED is not set # CONFIG_MBEDTLS_ECP_DP_BP256R1_ENABLED is not set # CONFIG_MBEDTLS_ECP_DP_BP384R1_ENABLED is not set # CONFIG_MBEDTLS_ECP_DP_BP512R1_ENABLED is not set # CONFIG_MBEDTLS_ECP_FIXED_POINT_OPTIM is not set -# CONFIG_MBEDTLS_ERROR_STRINGS is not set +CONFIG_MBEDTLS_ERROR_STRINGS=y # end of mbedTLS # diff --git a/ports/espressif/esp-protocols b/ports/espressif/esp-protocols index ea54eef0d0f..2f492c02289 160000 --- a/ports/espressif/esp-protocols +++ b/ports/espressif/esp-protocols @@ -1 +1 @@ -Subproject commit ea54eef0d0fe59bd53a49c916f87065518b957eb +Subproject commit 2f492c02289015ecbb36851dd1bd04e0eb0a9937 diff --git a/ports/espressif/microros-lib b/ports/espressif/microros-lib new file mode 160000 index 00000000000..4b2a696dec7 --- /dev/null +++ b/ports/espressif/microros-lib @@ -0,0 +1 @@ +Subproject commit 4b2a696dec7f0f865e014ea4b83f2332df7e9560 diff --git a/ports/espressif/boards/m5stack_cardputer/cardputer_keyboard.c b/ports/espressif/module/cardputer_keyboard.c similarity index 83% rename from ports/espressif/boards/m5stack_cardputer/cardputer_keyboard.c rename to ports/espressif/module/cardputer_keyboard.c index 4bb7dd7c42b..548275001ac 100644 --- a/ports/espressif/boards/m5stack_cardputer/cardputer_keyboard.c +++ b/ports/espressif/module/cardputer_keyboard.c @@ -16,7 +16,7 @@ #include "shared-module/keypad_demux/DemuxKeyMatrix.h" #include "supervisor/shared/reload.h" -#include "keymap.h" +#include "cardputer_keymap.h" //| """M5Stack Cardputer keyboard integration. //| """ @@ -31,12 +31,13 @@ //| """" //| KEYBOARD: keypad_demux.DemuxKeymatrix //| -keypad_demux_demuxkeymatrix_obj_t cardputer_keyboard_obj; -bool cardputer_keyboard_serial_attached = false; -void cardputer_keyboard_init(void); -void keyboard_seq(const char *seq); -void update_keyboard(keypad_eventqueue_obj_t *queue); +keypad_demux_demuxkeymatrix_obj_t cardputer_keyboard; +static bool cardputer_keyboard_serial_attached = false; + +// Forward declarations. +static void keyboard_seq(const char *seq); +static void update_keyboard(keypad_eventqueue_obj_t *queue); //| def detach_serial() -> None: //| """Stops consuming keyboard events and routing them to sys.stdin.""" @@ -44,7 +45,7 @@ void update_keyboard(keypad_eventqueue_obj_t *queue); //| static mp_obj_t detach_serial(void) { cardputer_keyboard_serial_attached = false; - common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, NULL); + common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard.events, NULL); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_0(detach_serial_obj, detach_serial); @@ -54,7 +55,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(detach_serial_obj, detach_serial); //| ... //| static mp_obj_t attach_serial(void) { - common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard_obj.events, update_keyboard); + common_hal_keypad_eventqueue_set_event_handler(cardputer_keyboard.events, update_keyboard); cardputer_keyboard_serial_attached = true; return mp_const_none; } @@ -79,20 +80,20 @@ static mp_obj_t key_to_char(mp_obj_t key_obj, mp_obj_t shifted_obj) { static MP_DEFINE_CONST_FUN_OBJ_2(key_to_char_obj, key_to_char); // Ring buffer of characters consumed from keyboard events (when serial attached) -ringbuf_t keyqueue; -char keybuf[32]; +static ringbuf_t keyqueue; +static char keybuf[32]; keypad_event_obj_t event; -char keystate[56]; +static char keystate[56] = {0}; // Keyboard pins -const mcu_pin_obj_t *row_addr_pins[] = { +static const mcu_pin_obj_t *row_addr_pins[] = { &pin_GPIO8, &pin_GPIO9, &pin_GPIO11, }; -const mcu_pin_obj_t *column_pins[] = { +static const mcu_pin_obj_t *column_pins[] = { &pin_GPIO13, &pin_GPIO15, &pin_GPIO3, @@ -102,20 +103,22 @@ const mcu_pin_obj_t *column_pins[] = { &pin_GPIO7 }; -void cardputer_keyboard_init(void) { - cardputer_keyboard_obj.base.type = &keypad_demux_demuxkeymatrix_type; +static void cardputer_keyboard_init(void) { common_hal_keypad_demux_demuxkeymatrix_construct( - &cardputer_keyboard_obj, // self - 3, // num_row_addr_pins - row_addr_pins, // row_addr_pins - 7, // num_column_pins - column_pins, // column_pins - 0.01f, // interval - 20, // max_events - 2 // debounce_threshold + &cardputer_keyboard, // self + MP_ARRAY_SIZE(row_addr_pins), // num_row_addr_pins + row_addr_pins, // row_addr_pins + MP_ARRAY_SIZE(column_pins), // num_column_pins + column_pins, // column_pins + true, // columns_to_anodes + false, // transpose + 0.01f, // interval + 20, // max_events + 2, // debounce_threshold + false // use_gc_allocator ); - demuxkeymatrix_never_reset(&cardputer_keyboard_obj); + demuxkeymatrix_never_reset(&cardputer_keyboard); ringbuf_init(&keyqueue, (uint8_t *)keybuf, sizeof(keybuf)); attach_serial(); } @@ -148,13 +151,13 @@ char board_serial_read(void) { } } -void keyboard_seq(const char *seq) { +static void keyboard_seq(const char *seq) { while (*seq) { ringbuf_put(&keyqueue, *seq++); } } -void update_keyboard(keypad_eventqueue_obj_t *queue) { +static void update_keyboard(keypad_eventqueue_obj_t *queue) { uint8_t ascii = 0; if (common_hal_keypad_eventqueue_get_length(queue) == 0) { @@ -221,7 +224,7 @@ void update_keyboard(keypad_eventqueue_obj_t *queue) { static const mp_rom_map_elem_t cardputer_keyboard_module_globals_table[] = { {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cardputer_keyboard)}, - {MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&cardputer_keyboard_obj)}, + {MP_ROM_QSTR(MP_QSTR_KEYBOARD), MP_ROM_PTR(&cardputer_keyboard)}, {MP_ROM_QSTR(MP_QSTR_attach_serial), MP_ROM_PTR(&attach_serial_obj)}, {MP_ROM_QSTR(MP_QSTR_detach_serial), MP_ROM_PTR(&detach_serial_obj)}, {MP_ROM_QSTR(MP_QSTR_key_to_char), MP_ROM_PTR(&key_to_char_obj)}, diff --git a/ports/espressif/boards/m5stack_cardputer/keymap.h b/ports/espressif/module/cardputer_keymap.h similarity index 100% rename from ports/espressif/boards/m5stack_cardputer/keymap.h rename to ports/espressif/module/cardputer_keymap.h diff --git a/ports/espressif/mpconfigport.h b/ports/espressif/mpconfigport.h index 98c1986240b..7f1a581571e 100644 --- a/ports/espressif/mpconfigport.h +++ b/ports/espressif/mpconfigport.h @@ -22,9 +22,12 @@ #define MICROPY_NLR_SETJMP (1) #define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 +// PSRAM can require more stack space for GC. +#define MICROPY_ALLOC_GC_STACK_SIZE (128) + // Nearly all boards have this because it is used to enter the ROM bootloader. #ifndef CIRCUITPY_BOOT_BUTTON - #if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) + #if defined(CONFIG_IDF_TARGET_ESP32C2) || defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6) || defined(CONFIG_IDF_TARGET_ESP32H2) || defined(CONFIG_IDF_TARGET_ESP32C61) #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO9) #elif !defined(CONFIG_IDF_TARGET_ESP32) #define CIRCUITPY_BOOT_BUTTON (&pin_GPIO0) @@ -65,3 +68,7 @@ extern portMUX_TYPE background_task_mutex; #ifndef CIRCUITPY_WIFI_DEFAULT_TX_POWER #define CIRCUITPY_WIFI_DEFAULT_TX_POWER (20) #endif + +#ifndef CIRCUITPY_ESP32P4_SWAP_LSFS +#define CIRCUITPY_ESP32P4_SWAP_LSFS (0) +#endif diff --git a/ports/espressif/mpconfigport.mk b/ports/espressif/mpconfigport.mk index 4bc24a720ca..98fe3224a49 100644 --- a/ports/espressif/mpconfigport.mk +++ b/ports/espressif/mpconfigport.mk @@ -1,18 +1,50 @@ -# Use internal flash for CIRCUITPY drive +# This file is part of the CircuitPython project: https://circuitpython.org +# +# SPDX-FileCopyrightText: Copyright (c) 2025 Adafruit Industries +# +# SPDX-License-Identifier: MIT + + +ifeq ($(IDF_TARGET),esp32c2) +IDF_TARGET_ARCH = riscv +CROSS_COMPILE = riscv32-esp-elf- +else ifeq ($(IDF_TARGET),esp32c3) +IDF_TARGET_ARCH = riscv +CROSS_COMPILE = riscv32-esp-elf- +else ifeq ($(IDF_TARGET),esp32p4) +IDF_TARGET_ARCH = riscv +CROSS_COMPILE = riscv32-esp-elf- +else ifeq ($(IDF_TARGET),esp32c6) +IDF_TARGET_ARCH = riscv +CROSS_COMPILE = riscv32-esp-elf- +else ifeq ($(IDF_TARGET),esp32c61) +IDF_TARGET_ARCH = riscv +CROSS_COMPILE = riscv32-esp-elf- +else ifeq ($(IDF_TARGET),esp32h2) +IDF_TARGET_ARCH = riscv +CROSS_COMPILE = riscv32-esp-elf- +else +IDF_TARGET_ARCH = xtensa +CROSS_COMPILE = xtensa-$(IDF_TARGET)-elf- +endif + +# Use "internal flash" for CIRCUITPY drive. +# Even thought it's an external flash chip, it appears as internal. INTERNAL_FLASH_FILESYSTEM = 1 # Internal math library is substantially smaller than toolchain one INTERNAL_LIBM = 0 -# Longints can be implemented as mpz, as longlong, or not +# Longints can be implemented as MPZ, as LONGLONG, or NONE LONGINT_IMPL = MPZ # Default to no-psram CIRCUITPY_ESP_PSRAM_SIZE ?= 0 -# New 4MB boards will not have OTA support but more room for alarm, ble and other -# newer features. -CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT ?= 0 +# Some 4MB non-USB boards were initially defined with 2MB firmware, almost 2MB user_fs partitions. +# Others were defined with 1.4M+1.4M (now a single 2.8MB) firmware partitions / 1.2MB user_fs. +# Keep the former as is, so that the user filesystem will be unchanged. +CIRCUITPY_4MB_FLASH_LARGE_USER_FS_LAYOUT ?= 0 # Enable more features CIRCUITPY_FULL_BUILD ?= 1 @@ -20,21 +52,27 @@ CIRCUITPY_FULL_BUILD ?= 1 # If SSL is enabled, it's mbedtls CIRCUITPY_SSL_MBEDTLS = 1 -# Wifi Power Save -CIRCUITPY_WIFI_RADIO_SETTABLE_LISTEN_INTERVAL = 1 - # Never use our copy of MBEDTLS CIRCUITPY_HASHLIB_MBEDTLS_ONLY = 0 +CIRCUITPY_PORT_SERIAL = 1 + +CIRCUITPY_LIB_TLSF = 0 + +CIRCUITPY_LIBC_STRING0 = 0 + # These modules are implemented in ports//common-hal: +CIRCUITPY__EVE ?= 1 CIRCUITPY_ALARM ?= 1 -CIRCUITPY_ALARM_TOUCH ?= 0 +CIRCUITPY_ALARM_PRESERVE_DIOS ?= 1 +CIRCUITPY_ALARM_TOUCH ?= 1 CIRCUITPY_ANALOGBUFIO ?= 1 CIRCUITPY_AUDIOBUSIO ?= 1 -CIRCUITPY_AUDIOBUSIO_PDMIN ?= 0 -CIRCUITPY_AUDIOIO ?= 0 -CIRCUITPY_BLEIO ?= 1 +CIRCUITPY_AUDIOBUSIO_PDMIN ?= 1 +CIRCUITPY_AUDIOI2SIN ?= 1 +CIRCUITPY_AUDIOIO ?= 1 CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BLEIO_NATIVE ?= 1 CIRCUITPY_CANIO ?= 1 CIRCUITPY_COUNTIO ?= 1 CIRCUITPY_ESPCAMERA ?= 1 @@ -43,45 +81,47 @@ CIRCUITPY_ESPULP ?= 1 CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_FREQUENCYIO ?= 1 CIRCUITPY_HASHLIB ?= 1 -CIRCUITPY_I2CTARGET ?= 0 +CIRCUITPY_I2CTARGET = 0 CIRCUITPY_MAX3421E ?= 1 CIRCUITPY_MEMORYMAP ?= 1 +CIRCUITPY_RCLCPY ?= 0 CIRCUITPY_NVM ?= 1 CIRCUITPY_PARALLELDISPLAYBUS ?= 1 CIRCUITPY_PS2IO ?= 1 CIRCUITPY_RGBMATRIX ?= 1 CIRCUITPY_ROTARYIO ?= 1 CIRCUITPY_SDIOIO ?= 1 +CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY ?= 1 CIRCUITPY_SYNTHIO_MAX_CHANNELS ?= 12 +CIRCUITPY_TOUCHIO ?= 1 CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 CIRCUITPY_WATCHDOG ?= 1 CIRCUITPY_WIFI ?= 1 CIRCUITPY_SOCKETPOOL_IPV6 ?= 1 -# Enable _eve module -CIRCUITPY__EVE ?= 1 - -# Conditionally turn off modules/features +# Conditionally turn off modules/features per chip type +#### esp32 ############################################################ ifeq ($(IDF_TARGET),esp32) # Modules -CIRCUITPY_ALARM_TOUCH = 1 CIRCUITPY_RGBMATRIX = 0 -# SDMMC not supported yet -CIRCUITPY_SDIOIO = 0 - -# Features +# Has no USB CIRCUITPY_USB_DEVICE = 0 +#### esp32c2 ########################################################## else ifeq ($(IDF_TARGET),esp32c2) -# C2 ROM spits out the UART at 74880 when connected to a 26mhz crystal! Debug -# prints will default to that too. +# C2 ROM spits out the UART at 74880 when connected to a 26mhz crystal! +# Debug prints will default to that too. # Modules CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_ESPULP = 0 CIRCUITPY_MEMORYMAP = 0 +# No capacitive touch peripheral +CIRCUITPY_ALARM_TOUCH = 0 +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 + # No I80 support from the IDF CIRCUITPY_PARALLELDISPLAYBUS = 0 @@ -98,6 +138,10 @@ CIRCUITPY_ANALOGBUFIO = 0 # No I2S CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOI2SIN = 0 + +# No DAC +CIRCUITPY_AUDIOIO = 0 # No RMT CIRCUITPY_NEOPIXEL_WRITE = 0 @@ -107,12 +151,11 @@ CIRCUITPY_RGBMATRIX = 0 # No SDMMC CIRCUITPY_SDIOIO = 0 -CIRCUITPY_TOUCHIO ?= 1 -CIRCUITPY_TOUCHIO_USE_NATIVE = 0 # Features CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG = 0 +#### esp32c3 ########################################################## else ifeq ($(IDF_TARGET),esp32c3) # Modules CIRCUITPY_ESPCAMERA = 0 @@ -122,6 +165,17 @@ CIRCUITPY_MEMORYMAP = 0 # No I80 support from the IDF CIRCUITPY_PARALLELDISPLAYBUS = 0 +# No capacitive touch peripheral +CIRCUITPY_ALARM_TOUCH = 0 +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 + +# No DAC +CIRCUITPY_AUDIOIO = 0 + +# No I2S peripheral PDM-to-PCM hardware support +CIRCUITPY_AUDIOBUSIO_PDMIN = 0 +CIRCUITPY_AUDIOI2SIN = 0 + # No PCNT peripheral CIRCUITPY_FREQUENCYIO = 0 CIRCUITPY_COUNTIO = 0 @@ -130,12 +184,11 @@ CIRCUITPY_ROTARYIO = 0 # No SDMMC CIRCUITPY_SDIOIO = 0 -CIRCUITPY_TOUCHIO ?= 1 -CIRCUITPY_TOUCHIO_USE_NATIVE = 0 # Features CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 +#### esp32c6 ########################################################## else ifeq ($(IDF_TARGET),esp32c6) # Modules CIRCUITPY_ESPCAMERA = 0 @@ -143,8 +196,19 @@ CIRCUITPY_ESPULP = 0 CIRCUITPY_MEMORYMAP = 0 CIRCUITPY_RGBMATRIX = 0 +# No capacitive touch peripheral +CIRCUITPY_ALARM_TOUCH = 0 +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 + +# No DAC +CIRCUITPY_AUDIOIO = 0 + +# No I2S peripheral PDM-to-PCM hardware support +CIRCUITPY_AUDIOBUSIO_PDMIN = 0 + # No space for this CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOI2SIN = 0 # No I80 support from the IDF CIRCUITPY_PARALLELDISPLAYBUS = 0 @@ -152,28 +216,76 @@ CIRCUITPY_PARALLELDISPLAYBUS = 0 # No SDMMC CIRCUITPY_SDIOIO = 0 -CIRCUITPY_TOUCHIO ?= 1 -CIRCUITPY_TOUCHIO_USE_NATIVE = 0 # Features CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 -else ifeq ($(IDF_TARGET),esp32h2) +#### esp32c6 ########################################################## +else ifeq ($(IDF_TARGET),esp32c61) # Modules CIRCUITPY_ESPCAMERA = 0 CIRCUITPY_ESPULP = 0 CIRCUITPY_MEMORYMAP = 0 CIRCUITPY_RGBMATRIX = 0 +# No capacitive touch peripheral +CIRCUITPY_ALARM_TOUCH = 0 +CIRCUITPY_TOUCHIO_USE_NATIVE = 0 + +# No DAC +CIRCUITPY_AUDIOIO = 0 + +# No space for this +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOI2SIN = 0 + # No I80 support from the IDF CIRCUITPY_PARALLELDISPLAYBUS = 0 # No SDMMC CIRCUITPY_SDIOIO = 0 -CIRCUITPY_TOUCHIO ?= 1 +# Features +CIRCUITPY_USB_DEVICE = 0 +CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 + +# No TWAI on chip +CIRCUITPY_CANIO = 0 + +# No RMT on chip +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_PULSEIO = 0 +CIRCUITPY_RGBMATRIX = 0 + +# No PCNT on chip +CIRCUITPY_COUNTIO = 0 +CIRCUITPY_ROTARYIO = 0 +CIRCUITPY_FREQUENCYIO = 0 + +#### esp32h2 ########################################################## +else ifeq ($(IDF_TARGET),esp32h2) +# Modules +CIRCUITPY_ESPCAMERA = 0 +CIRCUITPY_ESPULP = 0 +CIRCUITPY_MEMORYMAP = 0 +CIRCUITPY_RGBMATRIX = 0 + +# No capacitive touch peripheral +CIRCUITPY_ALARM_TOUCH = 0 CIRCUITPY_TOUCHIO_USE_NATIVE = 0 +# No DAC +CIRCUITPY_AUDIOIO = 0 + +# No I2S peripheral PDM-to-PCM hardware support +CIRCUITPY_AUDIOBUSIO_PDMIN = 0 + +# No I80 support from the IDF +CIRCUITPY_PARALLELDISPLAYBUS = 0 + +# No SDMMC +CIRCUITPY_SDIOIO = 0 + # Features CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 1 @@ -181,20 +293,25 @@ CIRCUITPY_WIFI = 0 CIRCUITPY_MAX3421E = 0 +#### esp32p4 ########################################################## else ifeq ($(IDF_TARGET),esp32p4) +# No DAC +CIRCUITPY_AUDIOIO = 0 + # No wifi # TODO: Support ESP32-C6 coprocessor on some boards. -CIRCUITPY_BLEIO = 0 +CIRCUITPY_BLEIO_NATIVE = 0 CIRCUITPY_WIFI = 0 CIRCUITPY_SSL = 0 -CIRCUITPY_TOUCHIO = 1 -CIRCUITPY_TOUCHIO_USE_NATIVE = 0 +# Second stage bootloader doesn't work when the factory partition is empty due to +# UF2 missing. +UF2_BOOTLOADER = 0 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_TUSB_MEM_ALIGN = 64 -# TinyUSB doesn't have it upstreamed -# https://github.com/hathach/tinyusb/issues/2791 -CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_MAX3421E = 0 # Update this for the 40mhz processor. @@ -212,65 +329,64 @@ CIRCUITPY_PARALLELDISPLAYBUS = 0 # Library doesn't support P4 yet it seems CIRCUITPY_ESPCAMERA = 0 +# P4 has MIPI-DSI +CIRCUITPY_MIPIDSI = 1 + +#### esp32s2 ########################################################## else ifeq ($(IDF_TARGET),esp32s2) # Modules -CIRCUITPY_ALARM_TOUCH = 1 +CIRCUITPY_AUDIOIO ?= 1 +CIRCUITPY_AUDIOFILEWRITER ?= 1 + +# No I2S peripheral PDM-to-PCM hardware support +CIRCUITPY_AUDIOBUSIO_PDMIN = 0 + # No BLE in hw -CIRCUITPY_BLEIO = 0 +CIRCUITPY_BLEIO_NATIVE = 0 # No SDMMC CIRCUITPY_SDIOIO = 0 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 0 +#### esp32s3 ########################################################## else ifeq ($(IDF_TARGET),esp32s3) + # Modules -CIRCUITPY_ALARM_TOUCH = 1 CIRCUITPY_ESP_USB_SERIAL_JTAG ?= 0 -# No room for _bleio on boards with 4MB flash -ifeq ($(CIRCUITPY_ESP_FLASH_SIZE),4MB) -CIRCUITPY_BLEIO = 0 -endif +# No DAC +CIRCUITPY_AUDIOIO = 0 endif +#### end chip-specific choices ######################################## -# bitmapfilter does not fit on 4MB boards unless they are set up as camera boards -ifeq ($(CIRCUITPY_ESP_FLASH_SIZE),4MB) -CIRCUITPY_BITMAPFILTER ?= 0 -OPTIMIZATION_FLAGS ?= -Os -CIRCUITPY_DUALBANK ?= 0 -else +# By default, enable dualbank, and it'll be disabled for small flash sizes CIRCUITPY_DUALBANK ?= 1 -endif -# We used to default to OTA partition layout but are moving away from it so that -# BLE and alarm can be included. This setting prevents the partition layout from -# changing. -ifeq ($(CIRCUITPY_LEGACY_4MB_FLASH_LAYOUT), 1) -ifeq ($(IDF_TARGET_ARCH), xtensa) - CIRCUITPY_ALARM ?= 1 -else -CIRCUITPY_ALARM = 0 -endif -CIRCUITPY_DUALBANK = 1 -CIRCUITPY_BLEIO = 0 +# No room for large modules on 2MB boards +# 2MB boards have a single firmware partition, and can't do dualbank. +ifeq ($(CIRCUITPY_ESP_FLASH_SIZE),2MB) +CIRCUITPY__EVE = 0 +CIRCUITPY_AUDIOMP3 = 0 +CIRCUITPY_BITMAPFILTER = 0 +CIRCUITPY_BLEIO_NATIVE = 0 +CIRCUITPY_DUALBANK = 0 +CIRCUITPY_MAX3421E = 0 +CIRCUITPY_RGBMATRIX = 0 CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY = 0 -else -CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY = 1 +OPTIMIZATION_FLAGS ?= -Os endif -# No room for dualbank or mp3 on boards with 2MB flash -ifeq ($(CIRCUITPY_ESP_FLASH_SIZE),2MB) -CIRCUITPY_BITMAPFILTER ?= 0 +# 4MB boards have a single firmware partition, and can't do dualbank. +ifeq ($(CIRCUITPY_ESP_FLASH_SIZE),4MB) CIRCUITPY_DUALBANK = 0 -CIRCUITPY_AUDIOMP3 = 0 -CIRCUITPY_BLEIO = 0 +OPTIMIZATION_FLAGS ?= -Os endif -# No room for _eve on boards with 4MB flash -ifeq ($(CIRCUITPY_ESP_FLASH_SIZE),4MB) -CIRCUITPY__EVE = 0 +# espcamera does not work on boards without SPIRAM +ifeq ($(CIRCUITPY_ESP_PSRAM_SIZE),0) +CIRCUITPY_ESPCAMERA = 0 endif # Modules dependent on other modules @@ -279,8 +395,8 @@ CIRCUITPY_GIFIO ?= $(CIRCUITPY_DISPLAYIO) CIRCUITPY_JPEGIO ?= $(CIRCUITPY_DISPLAYIO) CIRCUITPY_QRIO ?= $(CIRCUITPY_ESPCAMERA) -CIRCUITPY_BLE_FILE_SERVICE ?= $(CIRCUITPY_BLEIO) -CIRCUITPY_SERIAL_BLE ?= $(CIRCUITPY_BLEIO) +CIRCUITPY_BLE_FILE_SERVICE ?= $(CIRCUITPY_BLEIO_NATIVE) +CIRCUITPY_BLE_SERIAL_SERVICE ?= $(CIRCUITPY_BLEIO_NATIVE) # Features dependent on other features ifneq ($(CIRCUITPY_USB_DEVICE),0) @@ -301,8 +417,18 @@ endif USB_NUM_ENDPOINT_PAIRS = 7 USB_NUM_IN_ENDPOINTS = 5 +# usb_audio is compiled in on the S3 but claims no endpoints until +# usb_audio.enable() is called from boot.py, so enabling it by default does not +# affect existing boards. Freeing one IN endpoint (usb_hid.disable()) is then the +# only thing a user needs, with no custom build. +ifeq ($(IDF_TARGET),esp32s3) +# It needs the TinyUSB device stack and audiocore, so leave it off for boards +# that turn either off. The S3 has no AUDIOIO and no AUDIOPWMIO, so audiocore +# follows CIRCUITPY_AUDIOBUSIO here. +ifeq ($(filter 0,$(CIRCUITPY_USB_DEVICE) $(CIRCUITPY_AUDIOCORE) $(CIRCUITPY_AUDIOBUSIO)),) +CIRCUITPY_USB_AUDIO ?= 1 +endif +endif + # Usually lots of flash space available CIRCUITPY_MESSAGE_COMPRESSION_LEVEL ?= 1 - -CIRCUITPY_AUDIOMP3 ?= 1 -CIRCUITPY_AUDIOMP3_USE_PORT_ALLOCATOR ?= 1 diff --git a/ports/espressif/mphalport.c b/ports/espressif/mphalport.c index 87b16ac3e4c..9046bbf7b10 100644 --- a/ports/espressif/mphalport.c +++ b/ports/espressif/mphalport.c @@ -8,25 +8,7 @@ #include "py/mphal.h" #include "supervisor/cpu.h" -#if defined(CONFIG_IDF_TARGET_ESP32) -#include "components/esp_rom/include/esp32/rom/ets_sys.h" -#elif defined(CONFIG_IDF_TARGET_ESP32C2) -#include "components/esp_rom/include/esp32c2/rom/ets_sys.h" -#elif defined(CONFIG_IDF_TARGET_ESP32P4) -#include "components/esp_rom/include/esp32p4/rom/ets_sys.h" -#elif defined(CONFIG_IDF_TARGET_ESP32C3) -#include "components/esp_rom/include/esp32c3/rom/ets_sys.h" -#elif defined(CONFIG_IDF_TARGET_ESP32C6) -#include "components/esp_rom/include/esp32c6/rom/ets_sys.h" -#elif defined(CONFIG_IDF_TARGET_ESP32H2) -#include "components/esp_rom/include/esp32h2/rom/ets_sys.h" -#elif defined(CONFIG_IDF_TARGET_ESP32S2) -#include "components/esp_rom/include/esp32s2/rom/ets_sys.h" -#elif defined(CONFIG_IDF_TARGET_ESP32S3) -#include "components/esp_rom/include/esp32s3/rom/ets_sys.h" -#else -#error Unknown CONFIG_IDF_TARGET_xxx -#endif +#include "rom/ets_sys.h" #include "esp_attr.h" @@ -39,7 +21,6 @@ void IRAM_ATTR mp_hal_delay_us(mp_uint_t delay) { // This is provided by the esp-idf/components/xtensa/esp32s2/libhal.a binary blob. #ifndef CONFIG_IDF_TARGET_ARCH_RISCV extern void xthal_window_spill(void); -#endif mp_uint_t cpu_get_regs_and_sp(mp_uint_t *regs) { // xtensa has more registers than an instruction can address. The 16 that @@ -55,8 +36,7 @@ mp_uint_t cpu_get_regs_and_sp(mp_uint_t *regs) { // there is a HAL call to do it. There is a bit of a race condition here // because the register value could change after it's been restored but that // is unlikely to happen with a heap pointer while we do a GC. - #ifndef CONFIG_IDF_TARGET_ARCH_RISCV xthal_window_spill(); - #endif - return (mp_uint_t)__builtin_frame_address(0); + return (mp_uint_t)__builtin_stack_address(); } +#endif diff --git a/ports/espressif/peripherals/esp32/pins.c b/ports/espressif/peripherals/esp32/pins.c index e2c45bd06fc..3aa12c9e675 100644 --- a/ports/espressif/peripherals/esp32/pins.c +++ b/ports/espressif/peripherals/esp32/pins.c @@ -6,11 +6,11 @@ #include "peripherals/pins.h" -const mcu_pin_obj_t pin_GPIO0 = PIN(0, ADC_UNIT_2, ADC_CHANNEL_1, TOUCH_PAD_NUM1); +const mcu_pin_obj_t pin_GPIO0 = PIN(0, ADC_UNIT_2, ADC_CHANNEL_1, 1); const mcu_pin_obj_t pin_GPIO1 = PIN(1, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); -const mcu_pin_obj_t pin_GPIO2 = PIN(2, ADC_UNIT_2, ADC_CHANNEL_2, TOUCH_PAD_NUM2); +const mcu_pin_obj_t pin_GPIO2 = PIN(2, ADC_UNIT_2, ADC_CHANNEL_2, 2); const mcu_pin_obj_t pin_GPIO3 = PIN(3, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); -const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_2, ADC_CHANNEL_0, TOUCH_PAD_NUM0); +const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_2, ADC_CHANNEL_0, 0); const mcu_pin_obj_t pin_GPIO5 = PIN(5, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO6 = PIN(6, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO7 = PIN(7, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); @@ -18,10 +18,10 @@ const mcu_pin_obj_t pin_GPIO8 = PIN(8, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL) const mcu_pin_obj_t pin_GPIO9 = PIN(9, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO10 = PIN(10, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO11 = PIN(11, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); -const mcu_pin_obj_t pin_GPIO12 = PIN(12, ADC_UNIT_2, ADC_CHANNEL_5, TOUCH_PAD_NUM5); -const mcu_pin_obj_t pin_GPIO13 = PIN(13, ADC_UNIT_2, ADC_CHANNEL_4, TOUCH_PAD_NUM4); -const mcu_pin_obj_t pin_GPIO14 = PIN(14, ADC_UNIT_2, ADC_CHANNEL_6, TOUCH_PAD_NUM6); -const mcu_pin_obj_t pin_GPIO15 = PIN(15, ADC_UNIT_2, ADC_CHANNEL_3, TOUCH_PAD_NUM3); +const mcu_pin_obj_t pin_GPIO12 = PIN(12, ADC_UNIT_2, ADC_CHANNEL_5, 5); +const mcu_pin_obj_t pin_GPIO13 = PIN(13, ADC_UNIT_2, ADC_CHANNEL_4, 4); +const mcu_pin_obj_t pin_GPIO14 = PIN(14, ADC_UNIT_2, ADC_CHANNEL_6, 6); +const mcu_pin_obj_t pin_GPIO15 = PIN(15, ADC_UNIT_2, ADC_CHANNEL_3, 3); const mcu_pin_obj_t pin_GPIO16 = PIN(16, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO17 = PIN(17, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO18 = PIN(18, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); @@ -34,13 +34,13 @@ const mcu_pin_obj_t pin_GPIO23 = PIN(23, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNE // no GPIO24 const mcu_pin_obj_t pin_GPIO25 = PIN(25, ADC_UNIT_2, ADC_CHANNEL_8, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO26 = PIN(26, ADC_UNIT_2, ADC_CHANNEL_9, NO_TOUCH_CHANNEL); -const mcu_pin_obj_t pin_GPIO27 = PIN(27, ADC_UNIT_2, ADC_CHANNEL_7, TOUCH_PAD_NUM7); +const mcu_pin_obj_t pin_GPIO27 = PIN(27, ADC_UNIT_2, ADC_CHANNEL_7, 7); // no GPIO28 // no GPIO29 // no GPIO30 // no GPIO31 -const mcu_pin_obj_t pin_GPIO32 = PIN(32, ADC_UNIT_1, ADC_CHANNEL_4, TOUCH_PAD_NUM9); -const mcu_pin_obj_t pin_GPIO33 = PIN(33, ADC_UNIT_1, ADC_CHANNEL_5, TOUCH_PAD_NUM8); +const mcu_pin_obj_t pin_GPIO32 = PIN(32, ADC_UNIT_1, ADC_CHANNEL_4, 9); +const mcu_pin_obj_t pin_GPIO33 = PIN(33, ADC_UNIT_1, ADC_CHANNEL_5, 8); const mcu_pin_obj_t pin_GPIO34 = PIN(34, ADC_UNIT_1, ADC_CHANNEL_6, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO35 = PIN(35, ADC_UNIT_1, ADC_CHANNEL_7, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO36 = PIN(36, ADC_UNIT_1, ADC_CHANNEL_0, NO_TOUCH_CHANNEL); diff --git a/ports/espressif/peripherals/esp32c61/pins.c b/ports/espressif/peripherals/esp32c61/pins.c new file mode 100644 index 00000000000..a32e1e8da98 --- /dev/null +++ b/ports/espressif/peripherals/esp32c61/pins.c @@ -0,0 +1,38 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#include "peripherals/pins.h" + +const mcu_pin_obj_t pin_GPIO0 = PIN(0, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO1 = PIN(1, ADC_UNIT_1, ADC_CHANNEL_0, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO2 = PIN(2, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO3 = PIN(3, ADC_UNIT_1, ADC_CHANNEL_1, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_1, ADC_CHANNEL_2, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO5 = PIN(5, ADC_UNIT_1, ADC_CHANNEL_3, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO6 = PIN(6, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO7 = PIN(7, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO8 = PIN(8, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO9 = PIN(9, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO10 = PIN(10, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO11 = PIN(11, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO12 = PIN(12, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO13 = PIN(13, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO14 = PIN(14, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO15 = PIN(15, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO16 = PIN(16, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO17 = PIN(17, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO18 = PIN(18, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO19 = PIN(19, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO20 = PIN(20, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO21 = PIN(21, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO22 = PIN(22, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO23 = PIN(23, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO24 = PIN(24, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO25 = PIN(25, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO26 = PIN(26, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO27 = PIN(27, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO28 = PIN(28, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); +const mcu_pin_obj_t pin_GPIO29 = PIN(29, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); diff --git a/ports/espressif/peripherals/esp32c61/pins.h b/ports/espressif/peripherals/esp32c61/pins.h new file mode 100644 index 00000000000..908c9fe29f0 --- /dev/null +++ b/ports/espressif/peripherals/esp32c61/pins.h @@ -0,0 +1,72 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// DO NOT include this file directly. +// Use shared-bindings/microcontroller/Pin.h instead. +// This ensures that all necessary includes are already included. + +#pragma once + +#define GPIO0_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO0; +#define GPIO1_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO1; +#define GPIO2_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO2; +#define GPIO3_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO3; +#define GPIO4_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO4; +#define GPIO5_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO5; +#define GPIO6_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO6; +#define GPIO7_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO7; +#define GPIO8_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO8; +#define GPIO9_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO9; +#define GPIO10_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO10; +#define GPIO11_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO11; +#define GPIO12_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO12; +#define GPIO13_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO13; +#define GPIO14_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO14; +#define GPIO15_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO15; +#define GPIO16_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO16; +#define GPIO17_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO17; +#define GPIO18_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO18; +#define GPIO19_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO19; +#define GPIO20_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO20; +#define GPIO21_EXISTS 0 +extern const mcu_pin_obj_t pin_GPIO21; +#define GPIO22_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO22; +#define GPIO23_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO23; +#define GPIO24_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO24; +#define GPIO25_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO25; +#define GPIO26_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO26; +#define GPIO27_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO27; +#define GPIO28_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO28; +#define GPIO29_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO29; diff --git a/ports/espressif/peripherals/esp32p4/pins.c b/ports/espressif/peripherals/esp32p4/pins.c index 24e509d40c6..a4e085e6971 100644 --- a/ports/espressif/peripherals/esp32p4/pins.c +++ b/ports/espressif/peripherals/esp32p4/pins.c @@ -8,20 +8,20 @@ const mcu_pin_obj_t pin_GPIO0 = PIN(0, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO1 = PIN(1, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); -const mcu_pin_obj_t pin_GPIO2 = PIN(2, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM0); -const mcu_pin_obj_t pin_GPIO3 = PIN(3, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM1); -const mcu_pin_obj_t pin_GPIO4 = PIN(4, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM2); -const mcu_pin_obj_t pin_GPIO5 = PIN(5, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM3); -const mcu_pin_obj_t pin_GPIO6 = PIN(6, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM4); -const mcu_pin_obj_t pin_GPIO7 = PIN(7, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM5); -const mcu_pin_obj_t pin_GPIO8 = PIN(8, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM6); -const mcu_pin_obj_t pin_GPIO9 = PIN(9, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM7); -const mcu_pin_obj_t pin_GPIO10 = PIN(10, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM8); -const mcu_pin_obj_t pin_GPIO11 = PIN(11, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM9); -const mcu_pin_obj_t pin_GPIO12 = PIN(12, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM10); -const mcu_pin_obj_t pin_GPIO13 = PIN(13, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM11); -const mcu_pin_obj_t pin_GPIO14 = PIN(14, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM12); -const mcu_pin_obj_t pin_GPIO15 = PIN(15, NO_ADC, NO_ADC_CHANNEL, TOUCH_PAD_NUM13); +const mcu_pin_obj_t pin_GPIO2 = PIN(2, NO_ADC, NO_ADC_CHANNEL, 0); +const mcu_pin_obj_t pin_GPIO3 = PIN(3, NO_ADC, NO_ADC_CHANNEL, 1); +const mcu_pin_obj_t pin_GPIO4 = PIN(4, NO_ADC, NO_ADC_CHANNEL, 2); +const mcu_pin_obj_t pin_GPIO5 = PIN(5, NO_ADC, NO_ADC_CHANNEL, 3); +const mcu_pin_obj_t pin_GPIO6 = PIN(6, NO_ADC, NO_ADC_CHANNEL, 4); +const mcu_pin_obj_t pin_GPIO7 = PIN(7, NO_ADC, NO_ADC_CHANNEL, 5); +const mcu_pin_obj_t pin_GPIO8 = PIN(8, NO_ADC, NO_ADC_CHANNEL, 6); +const mcu_pin_obj_t pin_GPIO9 = PIN(9, NO_ADC, NO_ADC_CHANNEL, 7); +const mcu_pin_obj_t pin_GPIO10 = PIN(10, NO_ADC, NO_ADC_CHANNEL, 8); +const mcu_pin_obj_t pin_GPIO11 = PIN(11, NO_ADC, NO_ADC_CHANNEL, 9); +const mcu_pin_obj_t pin_GPIO12 = PIN(12, NO_ADC, NO_ADC_CHANNEL, 10); +const mcu_pin_obj_t pin_GPIO13 = PIN(13, NO_ADC, NO_ADC_CHANNEL, 11); +const mcu_pin_obj_t pin_GPIO14 = PIN(14, NO_ADC, NO_ADC_CHANNEL, 12); +const mcu_pin_obj_t pin_GPIO15 = PIN(15, NO_ADC, NO_ADC_CHANNEL, 13); const mcu_pin_obj_t pin_GPIO16 = PIN(16, ADC_UNIT_1, ADC_CHANNEL_0, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO17 = PIN(17, ADC_UNIT_1, ADC_CHANNEL_1, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO18 = PIN(18, ADC_UNIT_1, ADC_CHANNEL_2, NO_TOUCH_CHANNEL); diff --git a/ports/espressif/peripherals/esp32p4/pins.h b/ports/espressif/peripherals/esp32p4/pins.h index 5c106b316c0..59cf4258a40 100644 --- a/ports/espressif/peripherals/esp32p4/pins.h +++ b/ports/espressif/peripherals/esp32p4/pins.h @@ -54,6 +54,14 @@ extern const mcu_pin_obj_t pin_GPIO19; extern const mcu_pin_obj_t pin_GPIO20; #define GPIO21_EXISTS 1 extern const mcu_pin_obj_t pin_GPIO21; +#define GPIO22_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO22; +#define GPIO23_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO23; +#define GPIO24_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO24; +#define GPIO25_EXISTS 1 +extern const mcu_pin_obj_t pin_GPIO25; #define GPIO26_EXISTS 1 extern const mcu_pin_obj_t pin_GPIO26; #define GPIO27_EXISTS 1 diff --git a/ports/espressif/peripherals/esp32s2/pins.c b/ports/espressif/peripherals/esp32s2/pins.c index b5e8d483175..cfaecd0ac6d 100644 --- a/ports/espressif/peripherals/esp32s2/pins.c +++ b/ports/espressif/peripherals/esp32s2/pins.c @@ -7,20 +7,20 @@ #include "peripherals/pins.h" const mcu_pin_obj_t pin_GPIO0 = PIN(0, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); -const mcu_pin_obj_t pin_GPIO1 = PIN(1, ADC_UNIT_1, ADC_CHANNEL_0, TOUCH_PAD_NUM1); -const mcu_pin_obj_t pin_GPIO2 = PIN(2, ADC_UNIT_1, ADC_CHANNEL_1, TOUCH_PAD_NUM2); -const mcu_pin_obj_t pin_GPIO3 = PIN(3, ADC_UNIT_1, ADC_CHANNEL_2, TOUCH_PAD_NUM3); -const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_1, ADC_CHANNEL_3, TOUCH_PAD_NUM4); -const mcu_pin_obj_t pin_GPIO5 = PIN(5, ADC_UNIT_1, ADC_CHANNEL_4, TOUCH_PAD_NUM5); -const mcu_pin_obj_t pin_GPIO6 = PIN(6, ADC_UNIT_1, ADC_CHANNEL_5, TOUCH_PAD_NUM6); -const mcu_pin_obj_t pin_GPIO7 = PIN(7, ADC_UNIT_1, ADC_CHANNEL_6, TOUCH_PAD_NUM7); -const mcu_pin_obj_t pin_GPIO8 = PIN(8, ADC_UNIT_1, ADC_CHANNEL_7, TOUCH_PAD_NUM8); -const mcu_pin_obj_t pin_GPIO9 = PIN(9, ADC_UNIT_1, ADC_CHANNEL_8, TOUCH_PAD_NUM9); -const mcu_pin_obj_t pin_GPIO10 = PIN(10, ADC_UNIT_1, ADC_CHANNEL_9, TOUCH_PAD_NUM10); -const mcu_pin_obj_t pin_GPIO11 = PIN(11, ADC_UNIT_2, ADC_CHANNEL_0, TOUCH_PAD_NUM11); -const mcu_pin_obj_t pin_GPIO12 = PIN(12, ADC_UNIT_2, ADC_CHANNEL_1, TOUCH_PAD_NUM12); -const mcu_pin_obj_t pin_GPIO13 = PIN(13, ADC_UNIT_2, ADC_CHANNEL_2, TOUCH_PAD_NUM13); -const mcu_pin_obj_t pin_GPIO14 = PIN(14, ADC_UNIT_2, ADC_CHANNEL_3, TOUCH_PAD_NUM14); +const mcu_pin_obj_t pin_GPIO1 = PIN(1, ADC_UNIT_1, ADC_CHANNEL_0, 1); +const mcu_pin_obj_t pin_GPIO2 = PIN(2, ADC_UNIT_1, ADC_CHANNEL_1, 2); +const mcu_pin_obj_t pin_GPIO3 = PIN(3, ADC_UNIT_1, ADC_CHANNEL_2, 3); +const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_1, ADC_CHANNEL_3, 4); +const mcu_pin_obj_t pin_GPIO5 = PIN(5, ADC_UNIT_1, ADC_CHANNEL_4, 5); +const mcu_pin_obj_t pin_GPIO6 = PIN(6, ADC_UNIT_1, ADC_CHANNEL_5, 6); +const mcu_pin_obj_t pin_GPIO7 = PIN(7, ADC_UNIT_1, ADC_CHANNEL_6, 7); +const mcu_pin_obj_t pin_GPIO8 = PIN(8, ADC_UNIT_1, ADC_CHANNEL_7, 8); +const mcu_pin_obj_t pin_GPIO9 = PIN(9, ADC_UNIT_1, ADC_CHANNEL_8, 9); +const mcu_pin_obj_t pin_GPIO10 = PIN(10, ADC_UNIT_1, ADC_CHANNEL_9, 10); +const mcu_pin_obj_t pin_GPIO11 = PIN(11, ADC_UNIT_2, ADC_CHANNEL_0, 11); +const mcu_pin_obj_t pin_GPIO12 = PIN(12, ADC_UNIT_2, ADC_CHANNEL_1, 12); +const mcu_pin_obj_t pin_GPIO13 = PIN(13, ADC_UNIT_2, ADC_CHANNEL_2, 13); +const mcu_pin_obj_t pin_GPIO14 = PIN(14, ADC_UNIT_2, ADC_CHANNEL_3, 14); const mcu_pin_obj_t pin_GPIO15 = PIN(15, ADC_UNIT_2, ADC_CHANNEL_4, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO16 = PIN(16, ADC_UNIT_2, ADC_CHANNEL_5, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO17 = PIN(17, ADC_UNIT_2, ADC_CHANNEL_6, NO_TOUCH_CHANNEL); diff --git a/ports/espressif/peripherals/esp32s3/pins.c b/ports/espressif/peripherals/esp32s3/pins.c index c51c4b93575..745cb4a7a67 100644 --- a/ports/espressif/peripherals/esp32s3/pins.c +++ b/ports/espressif/peripherals/esp32s3/pins.c @@ -9,20 +9,20 @@ // NOTE: These numbers do NOT always match the package and module pin number. // These are by solely by GPIO numbers. const mcu_pin_obj_t pin_GPIO0 = PIN(0, NO_ADC, NO_ADC_CHANNEL, NO_TOUCH_CHANNEL); -const mcu_pin_obj_t pin_GPIO1 = PIN(1, ADC_UNIT_1, ADC_CHANNEL_0, TOUCH_PAD_NUM1); -const mcu_pin_obj_t pin_GPIO2 = PIN(2, ADC_UNIT_1, ADC_CHANNEL_1, TOUCH_PAD_NUM2); -const mcu_pin_obj_t pin_GPIO3 = PIN(3, ADC_UNIT_1, ADC_CHANNEL_2, TOUCH_PAD_NUM3); -const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_1, ADC_CHANNEL_3, TOUCH_PAD_NUM4); -const mcu_pin_obj_t pin_GPIO5 = PIN(5, ADC_UNIT_1, ADC_CHANNEL_4, TOUCH_PAD_NUM5); -const mcu_pin_obj_t pin_GPIO6 = PIN(6, ADC_UNIT_1, ADC_CHANNEL_5, TOUCH_PAD_NUM6); -const mcu_pin_obj_t pin_GPIO7 = PIN(7, ADC_UNIT_1, ADC_CHANNEL_6, TOUCH_PAD_NUM7); -const mcu_pin_obj_t pin_GPIO8 = PIN(8, ADC_UNIT_1, ADC_CHANNEL_7, TOUCH_PAD_NUM8); -const mcu_pin_obj_t pin_GPIO9 = PIN(9, ADC_UNIT_1, ADC_CHANNEL_8, TOUCH_PAD_NUM9); -const mcu_pin_obj_t pin_GPIO10 = PIN(10, ADC_UNIT_1, ADC_CHANNEL_9, TOUCH_PAD_NUM10); -const mcu_pin_obj_t pin_GPIO11 = PIN(11, ADC_UNIT_2, ADC_CHANNEL_0, TOUCH_PAD_NUM11); -const mcu_pin_obj_t pin_GPIO12 = PIN(12, ADC_UNIT_2, ADC_CHANNEL_1, TOUCH_PAD_NUM12); -const mcu_pin_obj_t pin_GPIO13 = PIN(13, ADC_UNIT_2, ADC_CHANNEL_2, TOUCH_PAD_NUM13); -const mcu_pin_obj_t pin_GPIO14 = PIN(14, ADC_UNIT_2, ADC_CHANNEL_3, TOUCH_PAD_NUM14); +const mcu_pin_obj_t pin_GPIO1 = PIN(1, ADC_UNIT_1, ADC_CHANNEL_0, 1); +const mcu_pin_obj_t pin_GPIO2 = PIN(2, ADC_UNIT_1, ADC_CHANNEL_1, 2); +const mcu_pin_obj_t pin_GPIO3 = PIN(3, ADC_UNIT_1, ADC_CHANNEL_2, 3); +const mcu_pin_obj_t pin_GPIO4 = PIN(4, ADC_UNIT_1, ADC_CHANNEL_3, 4); +const mcu_pin_obj_t pin_GPIO5 = PIN(5, ADC_UNIT_1, ADC_CHANNEL_4, 5); +const mcu_pin_obj_t pin_GPIO6 = PIN(6, ADC_UNIT_1, ADC_CHANNEL_5, 6); +const mcu_pin_obj_t pin_GPIO7 = PIN(7, ADC_UNIT_1, ADC_CHANNEL_6, 7); +const mcu_pin_obj_t pin_GPIO8 = PIN(8, ADC_UNIT_1, ADC_CHANNEL_7, 8); +const mcu_pin_obj_t pin_GPIO9 = PIN(9, ADC_UNIT_1, ADC_CHANNEL_8, 9); +const mcu_pin_obj_t pin_GPIO10 = PIN(10, ADC_UNIT_1, ADC_CHANNEL_9, 10); +const mcu_pin_obj_t pin_GPIO11 = PIN(11, ADC_UNIT_2, ADC_CHANNEL_0, 11); +const mcu_pin_obj_t pin_GPIO12 = PIN(12, ADC_UNIT_2, ADC_CHANNEL_1, 12); +const mcu_pin_obj_t pin_GPIO13 = PIN(13, ADC_UNIT_2, ADC_CHANNEL_2, 13); +const mcu_pin_obj_t pin_GPIO14 = PIN(14, ADC_UNIT_2, ADC_CHANNEL_3, 14); const mcu_pin_obj_t pin_GPIO15 = PIN(15, ADC_UNIT_2, ADC_CHANNEL_4, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO16 = PIN(16, ADC_UNIT_2, ADC_CHANNEL_5, NO_TOUCH_CHANNEL); const mcu_pin_obj_t pin_GPIO17 = PIN(17, ADC_UNIT_2, ADC_CHANNEL_6, NO_TOUCH_CHANNEL); diff --git a/ports/espressif/peripherals/i2c.c b/ports/espressif/peripherals/i2c.c deleted file mode 100644 index 744aa07f43d..00000000000 --- a/ports/espressif/peripherals/i2c.c +++ /dev/null @@ -1,65 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2020 microDev -// -// SPDX-License-Identifier: MIT - -#include "peripherals/i2c.h" - -typedef enum { - STATUS_FREE = 0, - STATUS_IN_USE, - STATUS_NEVER_RESET -} i2c_status_t; - -static i2c_status_t i2c_status[I2C_NUM_MAX]; - -void i2c_reset(void) { - for (i2c_port_t num = 0; num < (i2c_port_t)I2C_NUM_MAX; num++) { - if (i2c_status[num] == STATUS_IN_USE) { - i2c_driver_delete(num); - i2c_status[num] = STATUS_FREE; - } - } -} - -void never_reset_i2c(i2c_port_t num) { - i2c_status[num] = STATUS_NEVER_RESET; -} - -esp_err_t peripherals_i2c_init(i2c_port_t num, const i2c_config_t *i2c_conf) { - esp_err_t err = i2c_param_config(num, i2c_conf); - if (err != ESP_OK) { - return err; - } - size_t rx_buf_len = 0; - size_t tx_buf_len = 0; - #ifdef SOC_I2C_SUPPORT_SLAVE - if (i2c_conf->mode == I2C_MODE_SLAVE) { - rx_buf_len = 256; - tx_buf_len = 256; - } - #endif - return i2c_driver_install(num, i2c_conf->mode, rx_buf_len, tx_buf_len, 0); -} - -void peripherals_i2c_deinit(i2c_port_t num) { - i2c_reset_rx_fifo(num); - i2c_reset_tx_fifo(num); - i2c_driver_delete(num); - i2c_status[num] = STATUS_FREE; -} - -i2c_port_t peripherals_i2c_get_free_num(void) { - i2c_port_t i2c_num = I2C_NUM_MAX; - for (i2c_port_t num = 0; num < (int)I2C_NUM_MAX; num++) { - if (i2c_status[num] == STATUS_FREE) { - i2c_num = num; - break; - } - } - if (i2c_num != I2C_NUM_MAX) { - i2c_status[i2c_num] = STATUS_IN_USE; - } - return i2c_num; -} diff --git a/ports/espressif/peripherals/i2c.h b/ports/espressif/peripherals/i2c.h deleted file mode 100644 index a97889fe5ac..00000000000 --- a/ports/espressif/peripherals/i2c.h +++ /dev/null @@ -1,15 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2020 microDev -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include "driver/i2c.h" - -extern void i2c_reset(void); -extern void never_reset_i2c(i2c_port_t num); -extern esp_err_t peripherals_i2c_init(i2c_port_t num, const i2c_config_t *i2c_conf); -extern void peripherals_i2c_deinit(i2c_port_t num); -extern i2c_port_t peripherals_i2c_get_free_num(void); diff --git a/ports/espressif/peripherals/pins.h b/ports/espressif/peripherals/pins.h index f89855e308f..431a136545a 100644 --- a/ports/espressif/peripherals/pins.h +++ b/ports/espressif/peripherals/pins.h @@ -12,16 +12,15 @@ #include "py/obj.h" -#include "components/hal/include/hal/gpio_types.h" -#include "components/hal/include/hal/adc_types.h" -#include "components/hal/include/hal/touch_sensor_types.h" +#include "hal/gpio_types.h" +#include "hal/adc_types.h" typedef struct { mp_obj_base_t base; gpio_num_t number; uint8_t adc_index : 2; uint8_t adc_channel : 6; - touch_pad_t touch_channel; + int8_t touch_channel; } mcu_pin_obj_t; extern const mp_obj_type_t mcu_pin_type; @@ -31,7 +30,7 @@ extern const mp_obj_type_t mcu_pin_type; #define NO_ADC SOC_ADC_PERIPH_NUM #define NO_ADC_CHANNEL SOC_ADC_MAX_CHANNEL_NUM -#define NO_TOUCH_CHANNEL TOUCH_PAD_MAX +#define NO_TOUCH_CHANNEL (-1) // This macro is used to simplify pin definition in peripherals//pins.c #define PIN(p_number, p_adc_index, p_adc_channel, p_touch_channel) \ @@ -52,6 +51,8 @@ extern const mp_obj_type_t mcu_pin_type; #include "esp32c3/pins.h" #elif defined(CONFIG_IDF_TARGET_ESP32C6) #include "esp32c6/pins.h" +#elif defined(CONFIG_IDF_TARGET_ESP32C61) +#include "esp32c61/pins.h" #elif defined(CONFIG_IDF_TARGET_ESP32P4) #include "esp32p4/pins.h" #elif defined(CONFIG_IDF_TARGET_ESP32H2) diff --git a/ports/espressif/peripherals/touch.c b/ports/espressif/peripherals/touch.c index 71340d94371..f55c16d3969 100644 --- a/ports/espressif/peripherals/touch.c +++ b/ports/espressif/peripherals/touch.c @@ -4,54 +4,144 @@ // // SPDX-License-Identifier: MIT -#include "py/gc.h" #include "peripherals/touch.h" -static bool touch_inited = false; -static bool touch_never_reset = false; +static touch_sensor_handle_t touch_controller = NULL; +static touch_channel_handle_t touch_channels[TOUCH_TOTAL_CHAN_NUM] = {NULL}; +static bool touch_never_reset_flag = false; +static bool touch_enabled = false; +static bool touch_scanning = false; + +static int chan_index(int channel_id) { + return channel_id - TOUCH_MIN_CHAN_ID; +} + +touch_sensor_handle_t peripherals_touch_get_controller(void) { + return touch_controller; +} + +touch_channel_handle_t peripherals_touch_get_handle(int channel_id) { + return touch_channels[chan_index(channel_id)]; +} void peripherals_touch_reset(void) { - if (touch_inited && !touch_never_reset) { - touch_pad_deinit(); - touch_inited = false; + if (touch_controller != NULL && !touch_never_reset_flag) { + if (touch_scanning) { + touch_sensor_stop_continuous_scanning(touch_controller); + touch_scanning = false; + } + if (touch_enabled) { + touch_sensor_disable(touch_controller); + touch_enabled = false; + } + for (unsigned int i = 0; i < TOUCH_TOTAL_CHAN_NUM; i++) { + if (touch_channels[i] != NULL) { + touch_sensor_del_channel(touch_channels[i]); + touch_channels[i] = NULL; + } + } + touch_sensor_del_controller(touch_controller); + touch_controller = NULL; } } void peripherals_touch_never_reset(const bool enable) { - touch_never_reset = enable; + touch_never_reset_flag = enable; } -void peripherals_touch_init(const touch_pad_t touchpad) { - if (!touch_inited) { - touch_pad_init(); - touch_pad_set_fsm_mode(TOUCH_FSM_MODE_TIMER); +void peripherals_touch_init(const int channel_id) { + int idx = chan_index(channel_id); + + // Already initialized this channel + if (touch_channels[idx] != NULL) { + return; } - // touch_pad_config() must be done before touch_pad_fsm_start() the first time. - // Otherwise the calibration is wrong and we get maximum raw values if there is - // a trace of any significant length on the pin. - #if defined(CONFIG_IDF_TARGET_ESP32) - touch_pad_config(touchpad, 0); + + // Stop scanning and disable before modifying channels + if (touch_scanning) { + touch_sensor_stop_continuous_scanning(touch_controller); + touch_scanning = false; + } + if (touch_enabled) { + touch_sensor_disable(touch_controller); + touch_enabled = false; + } + + if (touch_controller == NULL) { + #if SOC_TOUCH_SENSOR_VERSION == 1 + touch_sensor_sample_config_t sample_cfg = TOUCH_SENSOR_V1_DEFAULT_SAMPLE_CONFIG(5.0, TOUCH_VOLT_LIM_L_0V5, TOUCH_VOLT_LIM_H_1V7); + #elif SOC_TOUCH_SENSOR_VERSION == 2 + touch_sensor_sample_config_t sample_cfg = TOUCH_SENSOR_V2_DEFAULT_SAMPLE_CONFIG(500, TOUCH_VOLT_LIM_L_0V5, TOUCH_VOLT_LIM_H_2V2); + #elif SOC_TOUCH_SENSOR_VERSION == 3 + touch_sensor_sample_config_t sample_cfg = TOUCH_SENSOR_V3_DEFAULT_SAMPLE_CONFIG2(3, 29, 8, 3); + #else + #error bad SOC_TOUCH_SENSOR_VERSION + #endif + touch_sensor_config_t sens_cfg = TOUCH_SENSOR_DEFAULT_BASIC_CONFIG(1, &sample_cfg); + touch_sensor_new_controller(&sens_cfg, &touch_controller); + } + + #if SOC_TOUCH_SENSOR_VERSION == 1 + touch_channel_config_t chan_cfg = { + .abs_active_thresh = {1000}, + .charge_speed = TOUCH_CHARGE_SPEED_7, + .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, + .group = TOUCH_CHAN_TRIG_GROUP_BOTH, + }; + #elif SOC_TOUCH_SENSOR_VERSION == 2 + touch_channel_config_t chan_cfg = { + .active_thresh = {2000}, + .charge_speed = TOUCH_CHARGE_SPEED_7, + .init_charge_volt = TOUCH_INIT_CHARGE_VOLT_DEFAULT, + }; + #elif SOC_TOUCH_SENSOR_VERSION == 3 + // Values are similar to an ESP-IDF example: 1000, 2500, 5000. + touch_channel_config_t chan_cfg = { + .active_thresh = {1000, 2000, 5000}, + }; #else - touch_pad_config(touchpad); - touch_pad_fsm_start(); + #error bad SOC_TOUCH_SENSOR_VERSION #endif - touch_inited = true; + + touch_sensor_new_channel(touch_controller, channel_id, &chan_cfg, &touch_channels[idx]); + + // Enable and start continuous scanning + touch_sensor_enable(touch_controller); + touch_enabled = true; + touch_sensor_start_continuous_scanning(touch_controller); + touch_scanning = true; } -uint16_t peripherals_touch_read(touch_pad_t touchpad) { - #if defined(CONFIG_IDF_TARGET_ESP32) - uint16_t touch_value; - touch_pad_read(touchpad, &touch_value); +uint16_t peripherals_touch_read(int channel_id) { + int idx = chan_index(channel_id); + if (touch_channels[idx] == NULL) { + return 0; + } + + uint32_t touch_value = 0; - // ESP32 touch_pad_read() returns a lower value when a pin is touched instead of a higher value. - // Flip the values around to be consistent with TouchIn assumptions. - return UINT16_MAX - touch_value; - #else - uint32_t touch_value; - touch_pad_read_raw_data(touchpad, &touch_value); + #if SOC_TOUCH_SENSOR_VERSION == 1 + // ESP32 touch reads a lower value when touched. + // Flip the values to be consistent with TouchIn assumptions. + touch_channel_read_data(touch_channels[idx], TOUCH_CHAN_DATA_TYPE_RAW, &touch_value); + if (touch_value > UINT16_MAX) { + return 0; + } + return UINT16_MAX - (uint16_t)touch_value; + touch_channel_read_data(touch_channels[idx], TOUCH_CHAN_DATA_TYPE_RAW, &touch_value); + return UINT16_MAX - (uint16_t)touch_value; + #elif SOC_TOUCH_SENSOR_VERSION == 2 + if (touch_value > UINT16_MAX) { + return UINT16_MAX; + } + return (uint16_t)touch_value; + #elif SOC_TOUCH_SENSOR_VERSION == 3 + touch_channel_read_data(touch_channels[idx], TOUCH_CHAN_DATA_TYPE_SMOOTH, &touch_value); if (touch_value > UINT16_MAX) { return UINT16_MAX; } return (uint16_t)touch_value; + #else + #error bad SOC_TOUCH_SENSOR_VERSION #endif } diff --git a/ports/espressif/peripherals/touch.h b/ports/espressif/peripherals/touch.h index 6be4f8c2be1..00a96193c88 100644 --- a/ports/espressif/peripherals/touch.h +++ b/ports/espressif/peripherals/touch.h @@ -6,9 +6,11 @@ #pragma once -#include "driver/touch_pad.h" +#include "driver/touch_sens.h" -extern uint16_t peripherals_touch_read(touch_pad_t touchpad); +extern void peripherals_touch_init(const int channel_id); +extern uint16_t peripherals_touch_read(int channel_id); extern void peripherals_touch_reset(void); extern void peripherals_touch_never_reset(const bool enable); -extern void peripherals_touch_init(const touch_pad_t touchpad); +extern touch_sensor_handle_t peripherals_touch_get_controller(void); +extern touch_channel_handle_t peripherals_touch_get_handle(int channel_id); diff --git a/ports/espressif/supervisor/port.c b/ports/espressif/supervisor/port.c index be80e419d66..0d47f7ecd19 100644 --- a/ports/espressif/supervisor/port.c +++ b/ports/espressif/supervisor/port.c @@ -24,7 +24,6 @@ #include "bindings/espulp/__init__.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/analogio/AnalogOut.h" -#include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" #include "common-hal/dualbank/__init__.h" @@ -48,12 +47,16 @@ #include "peripherals/touch.h" #endif -#if CIRCUITPY_BLEIO +#if CIRCUITPY_BLEIO_NATIVE #include "shared-bindings/_bleio/__init__.h" #endif #if CIRCUITPY_ESPCAMERA -#include "esp_camera.h" +#include "common-hal/espcamera/Camera.h" +#endif + +#if CIRCUITPY_RCLCPY +#include "common-hal/rclcpy/__init__.h" #endif #include "soc/efuse_reg.h" @@ -100,7 +103,7 @@ static esp_timer_handle_t _sleep_timer; TaskHandle_t circuitpython_task = NULL; -extern void esp_restart(void) NORETURN; +extern void esp_restart(void) MP_NORETURN; static void tick_on_cp_core(void *arg) { supervisor_tick(); @@ -191,8 +194,8 @@ static void _never_reset_spi_ram_flash(void) { const uint32_t spiconfig = esp_rom_efuse_get_flash_gpio_info(); if (spiconfig == ESP_ROM_EFUSE_FLASH_DEFAULT_SPI) { - never_reset_pin_number(SPI_IOMUX_PIN_NUM_CLK); - never_reset_pin_number(SPI_IOMUX_PIN_NUM_CS); + never_reset_pin_number(MSPI_IOMUX_PIN_NUM_CLK); + never_reset_pin_number(MSPI_IOMUX_PIN_NUM_CS0); never_reset_pin_number(PSRAM_SPIQ_SD0_IO); never_reset_pin_number(PSRAM_SPID_SD1_IO); never_reset_pin_number(PSRAM_SPIWP_SD3_IO); @@ -213,6 +216,11 @@ static void _never_reset_spi_ram_flash(void) { never_reset_pin_number(bootloader_flash_get_wp_pin()); } #endif // CONFIG_IDF_TARGET_ESP32 + #if defined(CONFIG_IDF_TARGET_ESP32C61) + #if defined(CONFIG_SPIRAM) + common_hal_never_reset_pin(&pin_GPIO14); + #endif + #endif } safe_mode_t port_init(void) { @@ -236,19 +244,19 @@ safe_mode_t port_init(void) { #endif // Send the ROM output out of the UART. This includes early logs. - #if DEBUG + #if DEBUG && (defined(CONFIG_ESP_CONSOLE_UART_DEFAULT) && CONFIG_ESP_CONSOLE_UART_DEFAULT) esp_rom_install_uart_printf(); #endif #define pin_GPIOn(n) pin_GPIO##n #define pin_GPIOn_EXPAND(x) pin_GPIOn(x) - #ifdef CONFIG_CONSOLE_UART_TX_GPIO - common_hal_never_reset_pin(&pin_GPIOn_EXPAND(CONFIG_CONSOLE_UART_TX_GPIO)); + #ifdef CONFIG_ESP_CONSOLE_UART_TX_GPIO + common_hal_never_reset_pin(&pin_GPIOn_EXPAND(CONFIG_ESP_CONSOLE_UART_TX_GPIO)); #endif - #ifdef CONFIG_CONSOLE_UART_RX_GPIO - common_hal_never_reset_pin(&pin_GPIOn_EXPAND(CONFIG_CONSOLE_UART_RX_GPIO)); + #ifdef CONFIG_ESP_CONSOLE_UART_RX_GPIO + common_hal_never_reset_pin(&pin_GPIOn_EXPAND(CONFIG_ESP_CONSOLE_UART_RX_GPIO)); #endif #ifndef ENABLE_JTAG @@ -268,7 +276,7 @@ safe_mode_t port_init(void) { common_hal_never_reset_pin(&pin_GPIO40); common_hal_never_reset_pin(&pin_GPIO41); common_hal_never_reset_pin(&pin_GPIO42); - #elif defined(CONFIG_IDF_TARGET_ESP32P4) + #elif defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32C61) common_hal_never_reset_pin(&pin_GPIO3); common_hal_never_reset_pin(&pin_GPIO4); common_hal_never_reset_pin(&pin_GPIO5); @@ -293,6 +301,10 @@ safe_mode_t port_init(void) { break; } + if (board_requests_safe_mode()) { + return SAFE_MODE_USER; + } + return SAFE_MODE_NONE; } @@ -301,18 +313,18 @@ void port_heap_init(void) { } void *port_malloc(size_t size, bool dma_capable) { - size_t caps = MALLOC_CAP_8BIT; if (dma_capable) { - caps |= MALLOC_CAP_DMA; + // SPIRAM is not DMA-capable, so don't bother to ask for it. + return heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_DMA); } void *ptr = NULL; - // Try SPIRAM first when available. + // Try SPIRAM first if available. #ifdef CONFIG_SPIRAM - ptr = heap_caps_malloc(size, caps | MALLOC_CAP_SPIRAM); + ptr = heap_caps_malloc(size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM); #endif if (ptr == NULL) { - ptr = heap_caps_malloc(size, caps); + ptr = heap_caps_malloc(size, MALLOC_CAP_8BIT); } return ptr; } @@ -321,8 +333,12 @@ void port_free(void *ptr) { heap_caps_free(ptr); } -void *port_realloc(void *ptr, size_t size) { - return heap_caps_realloc(ptr, size, MALLOC_CAP_8BIT); +void *port_realloc(void *ptr, size_t size, bool dma_capable) { + size_t caps = MALLOC_CAP_8BIT; + if (dma_capable) { + caps |= MALLOC_CAP_DMA; + } + return heap_caps_realloc(ptr, size, caps); } size_t port_heap_get_largest_free_size(void) { @@ -330,25 +346,27 @@ size_t port_heap_get_largest_free_size(void) { return free_size; } -void reset_port(void) { - // TODO deinit for esp32-camera +void reset_port_early(void) { + // esp-camera adds an I2C device on the ESP I2C bus, and keeps it there. This + // is unlike busio.I2C, which adds and removes the device on each operation. + // So have the esp-camera API shut down the camera now, before reset_board_buses() tries to delete the I2C bus. + // Unfortunately, there is no I2C driver API to enumerate or delete all the devices. #if CIRCUITPY_ESPCAMERA - esp_camera_deinit(); + espcamera_reset(); #endif +} + +void reset_port(void) { #if CIRCUITPY_SSL ssl_reset(); #endif - reset_all_pins(); - #if CIRCUITPY_ANALOGIO analogout_reset(); #endif #if CIRCUITPY_BUSIO - i2c_reset(); - spi_reset(); uart_reset(); #endif @@ -372,6 +390,10 @@ void reset_port(void) { ps2_reset(); #endif + #if CIRCUITPY_RCLCPY + rclcpy_reset(); + #endif + #if CIRCUITPY_RTC rtc_reset(); #endif @@ -388,8 +410,8 @@ void reset_port(void) { watchdog_reset(); #endif - // Yield so the idle task can run and do any IDF cleanup needed. - port_yield(); + // Yield so the idle task, at priority 0, can run and do any IDF cleanup needed. + port_task_sleep_ms(4); } void reset_to_bootloader(void) { @@ -455,11 +477,11 @@ void port_disable_tick(void) { esp_timer_stop(_tick_timer); } -void port_wake_main_task() { +void port_wake_main_task(void) { xTaskNotifyGive(circuitpython_task); } -void port_wake_main_task_from_isr() { +void port_wake_main_task_from_isr(void) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; vTaskNotifyGiveFromISR(circuitpython_task, &xHigherPriorityTaskWoken); if (xHigherPriorityTaskWoken == pdTRUE) { @@ -467,8 +489,13 @@ void port_wake_main_task_from_isr() { } } -void port_yield() { - vTaskDelay(4); +// Yield to other tasks at the same priority. +void port_task_yield(void) { + vTaskDelay(0); +} + +void port_task_sleep_ms(uint32_t msecs) { + vTaskDelay(pdMS_TO_TICKS(msecs)); } void sleep_timer_cb(void *arg) { @@ -491,11 +518,17 @@ void port_idle_until_interrupt(void) { } } -void port_post_boot_py(bool heap_valid) { - if (!heap_valid && filesystem_present()) { +#if CIRCUITPY_WIFI +void port_boot_info(void) { + uint8_t mac[6]; + esp_wifi_get_mac(WIFI_IF_STA, mac); + mp_printf(&mp_plat_print, "MAC"); + for (int i = 0; i < 6; i++) { + mp_printf(&mp_plat_print, ":%02X", mac[i]); } + mp_printf(&mp_plat_print, "\n"); } - +#endif // Wrap main in app_main that the IDF expects. extern void main(void); diff --git a/ports/espressif/supervisor/serial.c b/ports/espressif/supervisor/serial.c index 1d2fc58683a..e9277008a3c 100644 --- a/ports/espressif/supervisor/serial.c +++ b/ports/espressif/supervisor/serial.c @@ -15,6 +15,9 @@ #include "supervisor/usb_serial_jtag.h" #endif +void port_serial_early_init(void) { +} + void port_serial_init(void) { #if CIRCUITPY_ESP_USB_SERIAL_JTAG usb_serial_jtag_init(); diff --git a/ports/espressif/supervisor/usb.c b/ports/espressif/supervisor/usb.c index 3cd070e7c5d..7c3b1561a44 100644 --- a/ports/espressif/supervisor/usb.c +++ b/ports/espressif/supervisor/usb.c @@ -2,6 +2,7 @@ // // SPDX-FileCopyrightText: Copyright (c) 2018 hathach for Adafruit Industries // SPDX-FileCopyrightText: Copyright (c) 2019 Lucian Copeland for Adafruit Industries +// SPDX-FileContributor: 2025 Nicolai Electronics // // SPDX-License-Identifier: MIT @@ -20,21 +21,15 @@ #include "driver/gpio.h" #include "esp_private/periph_ctrl.h" -#if defined(CONFIG_IDF_TARGET_ESP32C3) -#include "components/esp_rom/include/esp32c3/rom/gpio.h" -#elif defined(CONFIG_IDF_TARGET_ESP32C6) -#include "components/esp_rom/include/esp32c6/rom/gpio.h" -#elif defined(CONFIG_IDF_TARGET_ESP32S2) -#include "components/esp_rom/include/esp32s2/rom/gpio.h" -#elif defined(CONFIG_IDF_TARGET_ESP32S3) -#include "components/esp_rom/include/esp32s3/rom/gpio.h" -#endif - #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "tusb.h" +#ifdef CONFIG_IDF_TARGET_ESP32P4 +#include "hal/usb_serial_jtag_ll.h" +#endif + #if CIRCUITPY_USB_DEVICE #ifdef CFG_TUSB_DEBUG #define USBD_STACK_SIZE (3 * configMINIMAL_STACK_SIZE) @@ -45,7 +40,7 @@ StackType_t usb_device_stack[USBD_STACK_SIZE]; StaticTask_t usb_device_taskdef; -static usb_phy_handle_t phy_hdl; +static usb_phy_handle_t device_phy_hdl; // USB Device Driver task // This top level thread process all usb events and invoke callbacks @@ -59,34 +54,10 @@ static void usb_device_task(void *param) { tud_task(); tud_cdc_write_flush(); } - vTaskDelay(1); + // Yield with zero delay to switch to any other tasks at same priority. + port_task_yield(); } } - -/** - * Callback invoked when received an "wanted" char. - * @param itf Interface index (for multiple cdc interfaces) - * @param wanted_char The wanted char (set previously) - */ -void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { - (void)itf; // not used - // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB. - // So, we must notify the other task when a CTRL-C is received. - port_wake_main_task(); - // Workaround for using shared/runtime/interrupt_char.c - // Compare mp_interrupt_char with wanted_char and ignore if not matched - if (mp_interrupt_char == wanted_char) { - tud_cdc_read_flush(); // flush read fifo - mp_sched_keyboard_interrupt(); - } -} - -void tud_cdc_rx_cb(uint8_t itf) { - (void)itf; - // Workaround for "press any key to enter REPL" response being delayed on espressif. - // Wake main task when any key is pressed. - port_wake_main_task(); -} #endif // CIRCUITPY_USB_DEVICE void init_usb_hardware(void) { @@ -94,9 +65,45 @@ void init_usb_hardware(void) { // Configure USB PHY usb_phy_config_t phy_conf = { .controller = USB_PHY_CTRL_OTG, + #if defined(CONFIG_IDF_TARGET_ESP32P4) && CIRCUITPY_USB_DEVICE_INSTANCE == 1 + .target = USB_PHY_TARGET_UTMI, + #else + .target = USB_PHY_TARGET_INT, + #endif .otg_mode = USB_OTG_MODE_DEVICE, + #if defined(CONFIG_IDF_TARGET_ESP32P4) && CIRCUITPY_USB_DEVICE_INSTANCE == 0 + .otg_speed = USB_PHY_SPEED_FULL, + #else + // https://github.com/hathach/tinyusb/issues/2943#issuecomment-2601888322 + // Set speed to undefined (auto-detect) to avoid timing/race issue with S3 with host such as macOS + .otg_speed = USB_PHY_SPEED_UNDEFINED, + #endif }; - usb_new_phy(&phy_conf, &phy_hdl); + usb_new_phy(&phy_conf, &device_phy_hdl); + + #if CIRCUITPY_ESP32P4_SWAP_LSFS == 1 + #ifndef CONFIG_IDF_TARGET_ESP32P4 + #error "LSFS swap is only supported on ESP32P4" + #endif + // Switch the USB PHY + const usb_serial_jtag_pull_override_vals_t override_disable_usb = { + .dm_pd = true, .dm_pu = false, .dp_pd = true, .dp_pu = false + }; + const usb_serial_jtag_pull_override_vals_t override_enable_usb = { + .dm_pd = false, .dm_pu = false, .dp_pd = false, .dp_pu = true + }; + + // Drop off the bus by removing the pull-up on USB DP + usb_serial_jtag_ll_phy_enable_pull_override(&override_disable_usb); + + // Select USB mode by swapping and un-swapping the two PHYs + vTaskDelay(pdMS_TO_TICKS(500)); // Wait for disconnect before switching to device + usb_serial_jtag_ll_phy_select(1); + + // Put the device back onto the bus by re-enabling the pull-up on USB DP + usb_serial_jtag_ll_phy_enable_pull_override(&override_enable_usb); + usb_serial_jtag_ll_phy_disable_pull_override(); + #endif // Pin the USB task to the same core as CircuitPython. This way we leave // the other core for networking. @@ -104,7 +111,7 @@ void init_usb_hardware(void) { "usbd", USBD_STACK_SIZE, NULL, - 5, + 1, usb_device_stack, &usb_device_taskdef, xPortGetCoreID()); diff --git a/ports/espressif/tools/build_memory_info.py b/ports/espressif/tools/build_memory_info.py index ba4b6db4cbc..0cf609c4d63 100644 --- a/ports/espressif/tools/build_memory_info.py +++ b/ports/espressif/tools/build_memory_info.py @@ -40,11 +40,10 @@ ], "esp32p4": [ # Name, Start, Length - ("RTC Fast Memory", (0x600F_E000,), 8 * 1024), - ("RTC Slow Memory", (0x5000_0000,), 8 * 1024), - ("Internal SRAM 0", (0x4037_0000,), 32 * 1024), - ("Internal SRAM 1", (0x3FC8_0000, 0x4037_8000), 416 * 1024), - ("Internal SRAM 2", (0x3FCF_0000,), 64 * 1024), + ("HP RAM", (0x3010_0000,), 8 * 1024), + ("PSRAM", (0x4800_0000,), 64 * 1024 * 1024), + ("L2MEM", (0x4FF0_0000,), 768 * 1024), + ("LP RAM", (0x5010_8000,), 32 * 1024), ], "esp32c2": [ # Name, Start, Length @@ -62,6 +61,12 @@ ("LP SRAM", (0x5000_0000,), 16 * 1024), ("HP SRAM", (0x4080_0000,), 512 * 1024), ], + "esp32c61": [ + # Name, Start, Length + ("LP SRAM", (0x5000_0000,), 16 * 1024), + ("HP SRAM", (0x4080_0000,), 320 * 1024), + ("PSRAM", (0x4200_0000,), 2 * 1024 * 1024), + ], "esp32h2": [ # Name, Start, Length ("LP SRAM", (0x5000_0000,), 4 * 1024), diff --git a/ports/espressif/tools/check-sdkconfig.py b/ports/espressif/tools/check-sdkconfig.py index 8a7ef882177..12254a71d01 100755 --- a/ports/espressif/tools/check-sdkconfig.py +++ b/ports/espressif/tools/check-sdkconfig.py @@ -29,7 +29,7 @@ def validate(sdk_config, circuitpy_config): if circuitpy_config.get(var): with open(partition_table) as f: content = f.read() - if not "ota_1" in content: + if "ota_1" not in content: raise SystemExit( f"{var} is incompatible with {partition_table=} (no ota_1 partition)" ) diff --git a/ports/espressif/tools/decode_backtrace.py b/ports/espressif/tools/decode_backtrace.py index 6d2772d39f7..2001482ffd6 100644 --- a/ports/espressif/tools/decode_backtrace.py +++ b/ports/espressif/tools/decode_backtrace.py @@ -1,31 +1,54 @@ """Simple script that translates "Backtrace:" lines from the ESP output to files - and line numbers. +and line numbers. - Run with: python3 tools/decode_backtrace.py +Run with: python3 tools/decode_backtrace.py - Enter the backtrace line at the "? " prompt. CTRL-C to exit the script. - """ +Enter the backtrace line at the "? " prompt. CTRL-C to exit the script. +""" import subprocess import sys board = sys.argv[1] +# Allow `board-name` or `build-board-name/ as the arg, to allow simple tab completion of boardname. +board = board.replace("build-", "").replace("/", "") print(board) +elfs = [ + f"build-{board}/firmware.elf", + # Add additional ELF files here such as the ROM ELF files from: + # https://github.com/espressif/esp-rom-elfs/releases + # "/home/tannewt/Downloads/esp-rom-elfs-20241011/esp32c6_rev0_rom.elf", +] + while True: + print('"Backtrace:" or "Stack memory:". CTRL-D to finish multiline paste') addresses = input("? ") if addresses.startswith("Backtrace:"): addresses = addresses[len("Backtrace:") :] - if addresses.startswith("Stack memory:"): - addresses = addresses[len("Stack memory:") :] - addresses = addresses.strip().split() - addresses = [address.split(":")[0] for address in addresses] + addresses = addresses.strip().split() + addresses = [address.split(":")[0] for address in addresses] + elif addresses.startswith("Stack memory:"): + addresses = [] + extra_lines = sys.stdin.readlines() + for line in extra_lines: + if not line.strip(): + continue + addresses.extend(line.split(":")[1].strip().split()) for address in addresses: - result = subprocess.run( - ["xtensa-esp32s2-elf-addr2line", "-aipfe", "build-{}/firmware.elf".format(board)] - + [address], - capture_output=True, - ) - stdout = result.stdout.decode("utf-8") - if "?? ??" not in stdout: - print(stdout.strip()) + if address == "0xa5a5a5a5": + # Skip stack fill value. + continue + for elf in elfs: + result = subprocess.run( + ["riscv32-esp-elf-addr2line", "-aipfe", elf, address], + capture_output=True, + ) + stdout = result.stdout.decode("utf-8") + if not stdout: + continue + if "?? ??" not in stdout: + print(stdout.strip()) + break + + print("loop") diff --git a/ports/espressif/tools/update_sdkconfig.py b/ports/espressif/tools/update_sdkconfig.py index c1e7ebd349c..d46514873bd 100644 --- a/ports/espressif/tools/update_sdkconfig.py +++ b/ports/espressif/tools/update_sdkconfig.py @@ -1,11 +1,10 @@ """This script updates the sdkconfigs based on the menuconfig results in a given - build.""" +build.""" import pathlib import click import copy import kconfiglib -import kconfiglib.core import os OPT_SETTINGS = [ @@ -139,10 +138,9 @@ def sym_default(sym): # to n or the symbol to m in those cases). if ( sym.choice - and not sym.choice.is_optional and sym.choice._selection_from_defaults() is sym - and sym.orig_type is kconfiglib.core.BOOL - and sym.tri_value == 2 + and sym.orig_type == kconfiglib.core.BOOL + and sym.bool_value == 2 ): return True @@ -158,7 +156,7 @@ def sym_default(sym): default=False, help="Updates the sdkconfigs outside of the board directory.", ) -def update(debug, board, update_all): +def update(debug, board, update_all): # noqa: C901 too complex """Updates related sdkconfig files based on the build directory version that was likely modified by menuconfig.""" @@ -192,7 +190,7 @@ def update(debug, board, update_all): psram_freq = value elif key == "UF2_BOOTLOADER": uf2_bootloader = not (value == "0") - elif key == "CIRCUITPY_BLEIO": + elif key == "CIRCUITPY_BLEIO_NATIVE": ble_enabled = not (value == "0") os.environ["IDF_TARGET"] = target @@ -203,8 +201,8 @@ def update(debug, board, update_all): kconfig_path = pathlib.Path(f"build-{board}/esp-idf/kconfigs.in") - kconfig_path = pathlib.Path(f"esp-idf/Kconfig") - kconfig = kconfiglib.Kconfig(kconfig_path) + kconfig_path = pathlib.Path("esp-idf/Kconfig") + kconfig = kconfiglib.Kconfig(str(kconfig_path)) input_config = pathlib.Path(f"build-{board}/esp-idf/sdkconfig") kconfig.load_config(input_config) @@ -231,7 +229,7 @@ def update(debug, board, update_all): sdkconfigs.extend((flash_size_config, flash_mode_config, flash_freq_config)) if psram_size != "0": - psram_config = pathlib.Path(f"esp-idf-config/sdkconfig-psram.defaults") + psram_config = pathlib.Path("esp-idf-config/sdkconfig-psram.defaults") psram_size_config = pathlib.Path(f"esp-idf-config/sdkconfig-psram-{psram_size}.defaults") psram_mode_config = pathlib.Path(f"esp-idf-config/sdkconfig-psram-{psram_mode}.defaults") psram_freq_config = pathlib.Path(f"esp-idf-config/sdkconfig-psram-{psram_freq}.defaults") @@ -239,13 +237,13 @@ def update(debug, board, update_all): target_config = pathlib.Path(f"esp-idf-config/sdkconfig-{target}.defaults") sdkconfigs.append(target_config) if ble_enabled: - ble_config = pathlib.Path(f"esp-idf-config/sdkconfig-ble.defaults") + ble_config = pathlib.Path("esp-idf-config/sdkconfig-ble.defaults") sdkconfigs.append(ble_config) board_config = pathlib.Path(f"boards/{board}/sdkconfig") # Don't include the board file in cp defaults. The board may have custom # overrides. - cp_kconfig_defaults = kconfiglib.Kconfig(kconfig_path) + cp_kconfig_defaults = kconfiglib.Kconfig(str(kconfig_path)) for default_file in sdkconfigs: cp_kconfig_defaults.load_config(default_file, replace=False) @@ -322,7 +320,7 @@ def update(debug, board, update_all): if print_debug: print(" " * len(current_group), i, config_string.strip()) - # Some files are `rsource`d into another kconfig with $IDF_TARGET as + # Some files are `rsource`d into another kconfig with $IDF_TARGET as # codespell:ignore rsource # part of the path. kconfiglib doesn't show this as a reference so # we have to look ourselves. target_reference = target in item.name_and_loc @@ -333,7 +331,7 @@ def update(debug, board, update_all): shared_keys = {} first = True for path in pathlib.Path(".").glob(loc): - kc = kconfiglib.Kconfig(path) + kc = kconfiglib.Kconfig(str(path)) all_file_syms = set() for sym in kc.unique_defined_syms: all_file_syms.add(sym) @@ -379,6 +377,8 @@ def update(debug, board, update_all): all_references.update(rdep.referenced) psram_reference = False for referenced in all_references: + if not referenced.name: + continue if referenced.name.startswith("IDF_TARGET"): target_reference = True if referenced.name in target_symbols: diff --git a/ports/litex/Makefile b/ports/litex/Makefile index 4e20b3c4ca1..cc813a49f8e 100644 --- a/ports/litex/Makefile +++ b/ports/litex/Makefile @@ -32,13 +32,13 @@ ifeq ($(DEBUG), 1) OPTIMIZATION_FLAGS ?= -Og else CFLAGS += -DNDEBUG -ggdb3 - OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions + OPTIMIZATION_FLAGS ?= -O2 endif # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) -CFLAGS += $(INC) -Werror -Wall -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes +CFLAGS += $(INC) -Werror -Wall -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes -Werror=old-style-definition # TODO: check this CFLAGS += -D__START=main -DFOMU @@ -77,16 +77,12 @@ ifneq ($(CIRCUITPY_USB),0) SRC_C += lib/tinyusb/src/portable/valentyusb/eptri/dcd_eptri.c endif -SRC_S = \ +SRC_S_UPPER = \ crt0-vexriscv.S -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) +SRC_S = shared/runtime/gchelper_rv32i.s -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) +SRC_C += shared/runtime/gchelper_native.c $(BUILD)/lib/tlsf/tlsf.o: CFLAGS += -Wno-cast-align @@ -96,20 +92,20 @@ FROZEN_MPY_MPY_FILES := $(addprefix $(BUILD)/,$(FROZEN_MPY_PY_FILES:.py=.mpy)) endif OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR += diff --git a/ports/litex/common-hal/microcontroller/Pin.c b/ports/litex/common-hal/microcontroller/Pin.c index dea848f1ec3..bb3636c5b3f 100644 --- a/ports/litex/common-hal/microcontroller/Pin.c +++ b/ports/litex/common-hal/microcontroller/Pin.c @@ -11,6 +11,10 @@ static uint8_t claimed_pins[1]; +void reset_all_pins(void) { + // TODO +} + // Mark pin as free and return it to a quiescent state. void reset_pin_number(uint8_t pin_port, uint8_t pin_number) { if (pin_port == 0x0F) { diff --git a/ports/litex/common-hal/microcontroller/Pin.h b/ports/litex/common-hal/microcontroller/Pin.h index 542f3e979b5..860a8c9ccad 100644 --- a/ports/litex/common-hal/microcontroller/Pin.h +++ b/ports/litex/common-hal/microcontroller/Pin.h @@ -7,6 +7,7 @@ #pragma once #include "py/mphal.h" +#include "py/obj.h" typedef struct { diff --git a/ports/litex/common-hal/microcontroller/Processor.c b/ports/litex/common-hal/microcontroller/Processor.c index cf80a01d4e6..0d1c29b1ad0 100644 --- a/ports/litex/common-hal/microcontroller/Processor.c +++ b/ports/litex/common-hal/microcontroller/Processor.c @@ -46,5 +46,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } diff --git a/ports/litex/common-hal/os/__init__.c b/ports/litex/common-hal/os/__init__.c index e6da1904da5..659411187fa 100644 --- a/ports/litex/common-hal/os/__init__.c +++ b/ports/litex/common-hal/os/__init__.c @@ -12,32 +12,6 @@ #include "shared-bindings/os/__init__.h" -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "litex"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "litex"); -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { return false; } diff --git a/ports/litex/mpconfigport.h b/ports/litex/mpconfigport.h index 8e7537af6a6..7ac34a44336 100644 --- a/ports/litex/mpconfigport.h +++ b/ports/litex/mpconfigport.h @@ -9,7 +9,6 @@ #define CIRCUITPY_INTERNAL_NVM_SIZE (0) #define MICROPY_NLR_THUMB (0) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #include "py/circuitpy_mpconfig.h" diff --git a/ports/litex/mpconfigport.mk b/ports/litex/mpconfigport.mk index d8dc4eef1ed..a93a3890bbc 100644 --- a/ports/litex/mpconfigport.mk +++ b/ports/litex/mpconfigport.mk @@ -31,3 +31,4 @@ CIRCUITPY_USB_HID = 1 CIRCUITPY_USB_MIDI = 1 CIRCUITPY_BUILD_EXTENSIONS ?= dfu +CIRCUITPY_MIN_GCC_VERSION ?= 8 diff --git a/ports/litex/mphalport.c b/ports/litex/mphalport.c index cc74762a14f..b94699e81e7 100644 --- a/ports/litex/mphalport.c +++ b/ports/litex/mphalport.c @@ -54,9 +54,3 @@ void isr(void) { // Decrease the "nesting count". Note: This should be going from 1 -> 0. nesting_count -= 1; } - -mp_uint_t cpu_get_regs_and_sp(mp_uint_t *regs) { - unsigned long __tmp; - asm volatile ("mv %0, x2" : "=r" (__tmp)); - return __tmp; -} diff --git a/ports/litex/supervisor/port.c b/ports/litex/supervisor/port.c index 7009956c317..7f9aab7f7ff 100644 --- a/ports/litex/supervisor/port.c +++ b/ports/litex/supervisor/port.c @@ -59,7 +59,6 @@ extern uint32_t _heap_start; extern uint32_t _estack; void reset_port(void) { - // reset_all_pins(); // i2c_reset(); // spi_reset(); // uart_reset(); @@ -114,6 +113,9 @@ uint64_t port_get_raw_ticks(uint8_t *subticks) { common_hal_mcu_disable_interrupts(); uint64_t raw_tick_snapshot = raw_ticks; common_hal_mcu_enable_interrupts(); + if (subticks != NULL) { + *subticks = 0; + } return raw_tick_snapshot; } diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile index f13207451e6..74667fd3d64 100644 --- a/ports/mimxrt10xx/Makefile +++ b/ports/mimxrt10xx/Makefile @@ -45,7 +45,7 @@ ifeq ($(DEBUG), 1) CFLAGS += -fno-ipa-sra endif -CFLAGS += $(INC) -ggdb -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes +CFLAGS += $(INC) -ggdb -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes -Werror=old-style-definition # TODO: add these when -Werror is applied # Disable some warnings, as do most ports. NXP SDK causes undef, tinyusb causes cast-align @@ -126,6 +126,10 @@ SRC_SDK += drivers/adc_12b1msps_sar/fsl_adc.c \ drivers/tempmon/fsl_tempmon.c endif +ifeq ($(CIRCUITPY_CANIO), 1) +SRC_SDK += drivers/flexcan/fsl_flexcan.c +endif + ifeq ($(CHIP_FAMILY), MIMXRT1176) SRC_SDK += devices/$(CHIP_FAMILY)/drivers/fsl_anatop_ai.c \ devices/$(CHIP_FAMILY)/drivers/fsl_dcdc.c \ @@ -157,30 +161,25 @@ SRC_C += \ endif -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) +SRC_S_UPPER = \ + sdk/devices/$(CHIP_FAMILY)/gcc/startup_$(CHIP_CORE).S -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) +SRC_S = shared/runtime/gchelper_thumb2.s -SRC_S = \ - sdk/devices/$(CHIP_FAMILY)/gcc/startup_$(CHIP_CORE).S \ - supervisor/cpu.S +SRC_C += shared/runtime/gchelper_native.c OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SDK:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_S:.S=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 $(BUILD)/firmware.hex diff --git a/ports/mimxrt10xx/boards/teensy40/mpconfigboard.h b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.h index e7565d64438..e6931752e3e 100644 --- a/ports/mimxrt10xx/boards/teensy40/mpconfigboard.h +++ b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.h @@ -25,3 +25,6 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO_AD_B0_03) #define DEFAULT_UART_BUS_TX (&pin_GPIO_AD_B0_02) + +#define CIRCUITPY_USB_DEVICE_INSTANCE 0 +#define CIRCUITPY_USB_HOST_INSTANCE 1 diff --git a/ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk index 9cb1e636b6f..f26f8dbd72b 100644 --- a/ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk +++ b/ports/mimxrt10xx/boards/teensy40/mpconfigboard.mk @@ -7,4 +7,5 @@ CHIP_VARIANT = MIMXRT1062DVJ6A CHIP_FAMILY = MIMXRT1062 FLASH = W25Q16JV CIRCUITPY__EVE = 1 +CIRCUITPY_USB_HOST = 1 CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY = 1 diff --git a/ports/mimxrt10xx/boards/teensy40/pins.c b/ports/mimxrt10xx/boards/teensy40/pins.c index 7aacdf95e15..dc8b07605b2 100644 --- a/ports/mimxrt10xx/boards/teensy40/pins.c +++ b/ports/mimxrt10xx/boards/teensy40/pins.c @@ -120,6 +120,10 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { {MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj)}, {MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj)}, + // USB Host (pads) + {MP_ROM_QSTR(MP_QSTR_USB_HOST_DP), MP_ROM_PTR(&pin_USB_OTG2_DP)}, + {MP_ROM_QSTR(MP_QSTR_USB_HOST_DM), MP_ROM_PTR(&pin_USB_OTG2_DN)}, + // other i2c ports defined {MP_OBJ_NEW_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_GPIO_AD_B1_06)}, {MP_OBJ_NEW_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_GPIO_AD_B1_07)}, diff --git a/ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk b/ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk index 7d16b797c52..6d1f802d6e3 100644 --- a/ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk +++ b/ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk @@ -7,5 +7,6 @@ CHIP_VARIANT = MIMXRT1062DVJ6A CHIP_FAMILY = MIMXRT1062 FLASH = W25Q64JV CIRCUITPY__EVE = 1 +CIRCUITPY_CANIO = 1 CIRCUITPY_USB_HOST = 1 CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY = 1 diff --git a/ports/mimxrt10xx/boards/teensy41/pins.c b/ports/mimxrt10xx/boards/teensy41/pins.c index 64eac9e4b70..84236382330 100644 --- a/ports/mimxrt10xx/boards/teensy41/pins.c +++ b/ports/mimxrt10xx/boards/teensy41/pins.c @@ -179,5 +179,23 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { {MP_OBJ_NEW_QSTR(MP_QSTR_TX7), MP_ROM_PTR(&pin_GPIO_EMC_31)}, {MP_OBJ_NEW_QSTR(MP_QSTR_RX8), MP_ROM_PTR(&pin_GPIO_B1_13)}, {MP_OBJ_NEW_QSTR(MP_QSTR_TX8), MP_ROM_PTR(&pin_GPIO_B1_12)}, + + // CAN and CAN-FD + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN1_RX), MP_ROM_PTR(&pin_GPIO_AD_B1_09)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN1_TX), MP_ROM_PTR(&pin_GPIO_AD_B1_08)}, + + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN2_RX), MP_ROM_PTR(&pin_GPIO_AD_B0_03)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN2_TX), MP_ROM_PTR(&pin_GPIO_AD_B0_02)}, + + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN3_RX), MP_ROM_PTR(&pin_GPIO_EMC_37)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN3_TX), MP_ROM_PTR(&pin_GPIO_EMC_36)}, + + // "CAN" is an alias for CAN1 + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN_RX), MP_ROM_PTR(&pin_GPIO_AD_B1_09)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_CAN_TX), MP_ROM_PTR(&pin_GPIO_AD_B1_08)}, + + // "CANFD" is an alias for CAN3 + {MP_OBJ_NEW_QSTR(MP_QSTR_CANFD_RX), MP_ROM_PTR(&pin_GPIO_EMC_37)}, + {MP_OBJ_NEW_QSTR(MP_QSTR_CANFD_TX), MP_ROM_PTR(&pin_GPIO_EMC_36)}, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.c b/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.c index c785f4e090e..b844325a00a 100644 --- a/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.c +++ b/ports/mimxrt10xx/common-hal/audiobusio/I2SOut.c @@ -53,7 +53,11 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) { // Caller validates that pins are free. void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, - const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) { + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified, + bool external_clock) { + if (external_clock) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_external_clock); + } int instance = -1; const mcu_periph_obj_t *bclk_periph = find_pin_function(mcu_i2s_tx_bclk_list, bit_clock, &instance, MP_QSTR_bit_clock); diff --git a/ports/mimxrt10xx/common-hal/audiobusio/__init__.c b/ports/mimxrt10xx/common-hal/audiobusio/__init__.c index fcedf34ef72..d51ea773acb 100644 --- a/ports/mimxrt10xx/common-hal/audiobusio/__init__.c +++ b/ports/mimxrt10xx/common-hal/audiobusio/__init__.c @@ -309,7 +309,7 @@ void port_i2s_initialize(i2s_t *self, int instance, sai_transceiver_t *config) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_I2SOut); } for (size_t i = 0; i < MP_ARRAY_SIZE(self->buffers); i++) { - self->buffers[i] = m_malloc(AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t)); + self->buffers[i] = m_malloc_without_collect(AUDIO_BUFFER_FRAME_COUNT * sizeof(uint32_t)); } self->peripheral = peripheral; SAI_Init(self->peripheral); @@ -372,13 +372,14 @@ static void set_sai_clocking_for_sample_rate(uint32_t sample_rate) { } void port_i2s_play(i2s_t *self, mp_obj_t sample, bool loop) { + audiosample_check(sample); self->sample = sample; self->loop = loop; - self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; - self->channel_count = audiosample_channel_count(sample); + self->bytes_per_sample = audiosample_get_bits_per_sample(sample) / 8; + self->channel_count = audiosample_get_channel_count(sample); int instance = SAI_GetInstance(self->peripheral); i2s_playing |= (1 << instance); - uint32_t sample_rate = audiosample_sample_rate(sample); + uint32_t sample_rate = audiosample_get_sample_rate(sample); if (sample_rate != self->sample_rate) { if (__builtin_popcount(i2s_playing) <= 1) { // as this is the first/only i2s instance playing audio, we can @@ -439,6 +440,6 @@ void port_i2s_resume(i2s_t *self) { self->paused = false; } -void i2s_reset() { +void i2s_reset(void) { // this port relies on object finalizers for reset } diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.c b/ports/mimxrt10xx/common-hal/busio/I2C.c index fb45553d400..93c0ab30123 100644 --- a/ports/mimxrt10xx/common-hal/busio/I2C.c +++ b/ports/mimxrt10xx/common-hal/busio/I2C.c @@ -27,16 +27,6 @@ // arrays use 0 based numbering: I2C1 is stored at index 0 static bool reserved_i2c[MP_ARRAY_SIZE(mcu_i2c_banks)]; -static bool never_reset_i2c[MP_ARRAY_SIZE(mcu_i2c_banks)]; - -void i2c_reset(void) { - for (uint i = 0; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) { - if (!never_reset_i2c[i]) { - reserved_i2c[i] = false; - LPI2C_MasterDeinit(mcu_i2c_banks[i]); - } - } -} static void config_periph_pin(const mcu_periph_obj_t *periph) { IOMUXC_SetPinMux( @@ -76,6 +66,9 @@ static void i2c_check_pin_config(const mcu_pin_obj_t *pin, uint32_t pull) { void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + #if CIRCUITPY_REQUIRE_I2C_PULLUPS // Test that the pins are in a high state. (Hopefully indicating they are pulled up.) IOMUXC_SetPinMux(sda->mux_reg, IOMUXC_SW_MUX_CTL_PAD_MUX_MODE_ALT5, 0, 0, 0, 0); @@ -153,8 +146,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { - never_reset_i2c[self->sda->bank_idx - 1] = true; - common_hal_never_reset_pin(self->sda->pin); common_hal_never_reset_pin(self->scl->pin); } @@ -168,15 +159,17 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { return; } reserved_i2c[self->sda->bank_idx - 1] = false; - never_reset_i2c[self->sda->bank_idx - 1] = false; LPI2C_MasterDeinit(self->i2c); common_hal_reset_pin(self->sda->pin); common_hal_reset_pin(self->scl->pin); + common_hal_busio_i2c_mark_deinit(self); +} + +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { self->sda = NULL; - self->scl = NULL; } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { @@ -208,7 +201,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_negative_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { lpi2c_master_transfer_t xfer = { 0 }; @@ -222,15 +215,15 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return 0; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { lpi2c_master_transfer_t xfer = { 0 }; @@ -244,12 +237,12 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, return 0; } - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_negative_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/mimxrt10xx/common-hal/busio/I2C.h b/ports/mimxrt10xx/common-hal/busio/I2C.h index 06b86cd2d34..153c2541090 100644 --- a/ports/mimxrt10xx/common-hal/busio/I2C.h +++ b/ports/mimxrt10xx/common-hal/busio/I2C.h @@ -19,5 +19,3 @@ typedef struct { const mcu_periph_obj_t *scl; const mcu_periph_obj_t *sda; } busio_i2c_obj_t; - -void i2c_reset(void); diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c index 732b23d8c9b..90695be4b4e 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.c +++ b/ports/mimxrt10xx/common-hal/busio/SPI.c @@ -26,7 +26,6 @@ // arrays use 0 based numbering: SPI1 is stored at index 0 static bool reserved_spi[MP_ARRAY_SIZE(mcu_spi_banks)]; -static bool never_reset_spi[MP_ARRAY_SIZE(mcu_spi_banks)]; #if IMXRT11XX static const clock_ip_name_t s_lpspiClocks[] = LPSPI_CLOCKS; @@ -53,22 +52,6 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) { | IOMUXC_SW_PAD_CTL_PAD_SRE(0)); } -void spi_reset(void) { - for (uint i = 0; i < MP_ARRAY_SIZE(mcu_spi_banks); i++) { - if (!never_reset_spi[i]) { - reserved_spi[i] = false; - #if IMXRT11XX - // Skip resetting SPIs that aren't clocked. Doing so generates a bus fault. - if ((CCM->LPCG[s_lpspiClocks[i + 1]].STATUS0 & CCM_LPCG_STATUS0_ON_MASK) == ((uint32_t)kCLOCK_Off & CCM_LPCG_STATUS0_ON_MASK)) { - continue; - } - #endif - - LPSPI_Deinit(mcu_spi_banks[i]); - } - } -} - void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { @@ -82,6 +65,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + for (uint i = 0; i < sck_count; i++) { if (mcu_spi_sck_list[i].pin != clock) { continue; @@ -200,7 +186,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[self->clock->bank_idx - 1] = true; common_hal_never_reset_pin(self->clock->pin); if (self->mosi != NULL) { common_hal_never_reset_pin(self->mosi->pin); @@ -214,21 +199,25 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } LPSPI_Deinit(self->spi); reserved_spi[self->clock->bank_idx - 1] = false; - never_reset_spi[self->clock->bank_idx - 1] = false; common_hal_reset_pin(self->clock->pin); common_hal_reset_pin(self->mosi->pin); common_hal_reset_pin(self->miso->pin); - self->clock = NULL; self->mosi = NULL; self->miso = NULL; + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.h b/ports/mimxrt10xx/common-hal/busio/SPI.h index 67801078261..d86489428ec 100644 --- a/ports/mimxrt10xx/common-hal/busio/SPI.h +++ b/ports/mimxrt10xx/common-hal/busio/SPI.h @@ -21,5 +21,3 @@ typedef struct { const mcu_periph_obj_t *mosi; const mcu_periph_obj_t *miso; } busio_spi_obj_t; - -void spi_reset(void); diff --git a/ports/mimxrt10xx/common-hal/canio/CAN.c b/ports/mimxrt10xx/common-hal/canio/CAN.c new file mode 100644 index 00000000000..0b598af1521 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/canio/CAN.c @@ -0,0 +1,445 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 qutefox +// SPDX-FileCopyrightText: Copyright (c) 2025 SamantazFox +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/runtime.h" +#include "py/mperrno.h" + +#include "common-hal/canio/CAN.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/port.h" +#include "supervisor/shared/tick.h" + +#include "sdk/drivers/flexcan/fsl_flexcan.h" + + +// Be verbose +#define MIMXRT_CANIO_CAN_DEBUG(...) (void)0 +// #define MIMXRT_CANIO_CAN_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) + +#define MIMXRT_CANIO_CAN_CALLBACK_DEBUG(...) (void)0 +// #define MIMXRT_CANIO_CAN_CALLBACK_DEBUG(...) mp_printf(&mp_plat_print, __VA_ARGS__) + + +static CAN_Type *const flexcan_bases[] = CAN_BASE_PTRS; // e.g.: { (CAN_Type *)0u, CAN1, CAN2, CAN3 } +static canio_can_obj_t *can_objs[MP_ARRAY_SIZE(mcu_can_banks)]; + +// Get frequency of flexcan clock. +#define MIMXRT10XX_FLEXCAN_CLK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (CLOCK_GetDiv(kCLOCK_CanDiv) + 1)) + +static void config_periph_pin(const mcu_periph_obj_t *periph) { + if (!periph) { + return; + } + IOMUXC_SetPinMux( + periph->pin->mux_reg, periph->mux_mode, + periph->input_reg, periph->input_idx, + 0, + 0); + + IOMUXC_SetPinConfig(0, 0, 0, 0, + periph->pin->cfg_reg, + IOMUXC_SW_PAD_CTL_PAD_PUS(0) // Pull Up/Down Config. Field: 100K Ohm Pull Down + #if IMXRT10XX + | IOMUXC_SW_PAD_CTL_PAD_HYS(0) // Hyst. Enable Field: Hysteresis Disabled + | IOMUXC_SW_PAD_CTL_PAD_PKE(1) // Pull/Keep Enable Field: Pull/Keeper Enabled + | IOMUXC_SW_PAD_CTL_PAD_SPEED(2) // Speed Field: medium (100MHz) + #endif + | IOMUXC_SW_PAD_CTL_PAD_PUE(0) // Pull/Keep Select Field: Keeper + | IOMUXC_SW_PAD_CTL_PAD_ODE(0) // Open Drain Enable Field: Open Drain Disabled + | IOMUXC_SW_PAD_CTL_PAD_DSE(6) // Drive Strength Field: R0/6 + | IOMUXC_SW_PAD_CTL_PAD_SRE(0)); // Slew Rate Field: Slow Slew Rate +} + +static uint8_t mimxrt10xx_flexcan_get_free_tx_mbid(canio_can_obj_t *self) { + // Get the next free tx message buffer atomically so that an interrupt can't occur while + // doing bit search. + // + // The idea here is that in an integer each bit acts as a boolean telling us if a + // tx message buffer is in use or not. + // If a free message buffer is found then we set it as used and return it's index. + bool found_free_tx_mb = false; + int8_t tx_array_id = 0; + mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + for ( ; tx_array_id < MIMXRT10XX_FLEXCAN_TX_MB_NUM; ++tx_array_id) + { + uint64_t tx_array_id_bit = (1UL << tx_array_id); + if (!(self->data->tx_state & tx_array_id_bit)) { + // Found a free tx array id. Mark it as used. + MIMXRT_CANIO_CAN_DEBUG("canio: Found free Tx MB: %d\n", tx_array_id); + self->data->tx_state |= tx_array_id_bit; + found_free_tx_mb = true; + break; + } + } + MICROPY_END_ATOMIC_SECTION(atomic_state); + + if (!found_free_tx_mb) { + mp_raise_ValueError(MP_ERROR_TEXT("Unable to send CAN Message: all Tx message buffers are busy")); + } + + return MIMXRT10XX_FLEXCAN_TX_ARRID_TO_MBID(tx_array_id); +} + +static void mimxrt10xx_flexcan_set_tx_mb_free_by_mbid(canio_can_obj_t *self, uint8_t mb_idx) { + // We simply set the Nth bit zero. This means that that message buffer is free to use. + uint64_t tx_array_id_bit = (1UL << MIMXRT10XX_FLEXCAN_TX_MBID_TO_ARRID(mb_idx)); + self->data->tx_state &= ~(tx_array_id_bit); +} + +static void mimxrt10xx_flexcan_set_tx_mb_busy_by_mbid(canio_can_obj_t *self, uint8_t mb_idx) { + // We simply set the Nth bit 1. This means that that message buffer is busy and cannot be used. + uint64_t tx_array_id_bit = (1UL << MIMXRT10XX_FLEXCAN_TX_MBID_TO_ARRID(mb_idx)); + self->data->tx_state |= tx_array_id_bit; +} + +static void mimxrt10xx_flexcan_abort_tx_frames(canio_can_obj_t *self) { + for (uint8_t tx_array_id = 0; tx_array_id < MIMXRT10XX_FLEXCAN_TX_MB_NUM; ++tx_array_id) + { + uint64_t tx_array_id_bit = (1UL << tx_array_id); + if (self->data->tx_state & tx_array_id_bit) { + // Found a used/busy tx message buffer. Abort it. + FLEXCAN_TransferAbortSend(self->data->base, &self->data->handle, MIMXRT10XX_FLEXCAN_TX_ARRID_TO_MBID(tx_array_id)); + + self->data->tx_state &= ~(tx_array_id_bit); // Mark tx message buffer as free. + } + } +} + +static void mimxrt10xx_flexcan_handle_error(canio_can_obj_t *self) { + canio_bus_state_t state = common_hal_canio_can_state_get(self); + if (state == BUS_STATE_OFF) { + // Abort any pending tx and rx in case of bus-off. + mimxrt10xx_flexcan_abort_tx_frames(self); + FLEXCAN_TransferAbortReceiveFifo(self->data->base, &self->data->handle); + } +} + +static FLEXCAN_CALLBACK(mimxrt10xx_flexcan_callback) +{ + (void)base; // unused variable + (void)handle; // unused variable + // The result field can either be a message buffer index or a status flags value. + + canio_can_obj_t *self = (canio_can_obj_t *)userData; + + switch (status) { + + // Process rx message buffer is idle event. + case kStatus_FLEXCAN_RxIdle: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxIdle\n"); + // We don't control any rx message buffers 'manually'. The rx fifo has control. + break; + + // Process tx message buffer is idle event. + case kStatus_FLEXCAN_TxIdle: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = TxIdle\n"); + mimxrt10xx_flexcan_set_tx_mb_free_by_mbid(self, result); + break; + + // Process tx message buffer is busy event. + case kStatus_FLEXCAN_TxBusy: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = TxBusy\n"); + mimxrt10xx_flexcan_set_tx_mb_busy_by_mbid(self, result); + break; + + // Process remote message is send out and message buffer changed to receive one event. + case kStatus_FLEXCAN_TxSwitchToRx: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = TxSwitchToRx\n"); + mimxrt10xx_flexcan_set_tx_mb_free_by_mbid(self, result); + break; + + // Process rx message buffer is busy event. + case kStatus_FLEXCAN_RxBusy: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxBusy\n"); + break; + + // Process rx message buffer is overflowed event. + case kStatus_FLEXCAN_RxOverflow: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxOverflow\n"); + break; + + // Process rx message fifo is busy event. + case kStatus_FLEXCAN_RxFifoBusy: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxFifoBusy\n"); + break; + + // Process rx message fifo is idle event. + case kStatus_FLEXCAN_RxFifoIdle: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxFifoIdle\n"); + break; + + // Process rx message fifo is overflowed event. + case kStatus_FLEXCAN_RxFifoOverflow: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxFifoOverflow\n"); + break; + + // Process rx message fifo is almost overflowed event. + case kStatus_FLEXCAN_RxFifoWarning: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxFifoWarning\n"); + break; + + // Process rx message fifo is disabled during reading event. + case kStatus_FLEXCAN_RxFifoDisabled: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = RxFifoDisabled\n"); + break; + + // Process FlexCAN is waken up from stop mode event. + case kStatus_FLEXCAN_WakeUp: + MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = WakeUp\n"); + break; + + // Process unhandled interrupt asserted event. + case kStatus_FLEXCAN_UnHandled: + // Process FlexCAN module error and status event. + case kStatus_FLEXCAN_ErrorStatus: + // This is *very* verbose when the bus is disconnected! + // MIMXRT_CANIO_CAN_CALLBACK_DEBUG("canio: callback got status = UnHandled or ErrorStatus"); + + // We could do some fancy statistics update, but canio does not have. + mimxrt10xx_flexcan_handle_error(self); + break; + } +} + +void common_hal_canio_can_construct(canio_can_obj_t *self, const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, int baudrate, bool loopback, bool silent) { + + int instance = -1; + const mcu_periph_obj_t *rx_periph = find_pin_function(mcu_can_rx_list, rx, &instance, MP_QSTR_rx); + const mcu_periph_obj_t *tx_periph = find_pin_function(mcu_can_tx_list, tx, &instance, MP_QSTR_tx); + + MIMXRT_CANIO_CAN_DEBUG("canio: init instance: %d\n", instance); + MIMXRT_CANIO_CAN_DEBUG("canio: init loopback: %d\n", loopback ? 1 : 0); + MIMXRT_CANIO_CAN_DEBUG("canio: init silent: %d\n", silent ? 1 : 0); + MIMXRT_CANIO_CAN_DEBUG("canio: init baudrate: %d\n", baudrate); + + self->rx_pin = rx; + self->tx_pin = tx; + config_periph_pin(rx_periph); + config_periph_pin(tx_periph); + + self->loopback = loopback; + self->silent = silent; + self->baudrate = baudrate; + + self->data = m_malloc_without_collect(sizeof(mimxrt10xx_flexcan_data_t)); + self->data->base = flexcan_bases[instance]; // 'flexcan_bases' start indexing from 1. (The first element is NULL) + self->data->tx_state = 0; + + // Get flexcan module default configuration. + flexcan_config_t config; + FLEXCAN_GetDefaultConfig(&config); + + // Change default flexcan module configuration based on canio constructor parameters. + config.clkSrc = CLOCK_GetMux(kCLOCK_CanMux); + config.baudRate = baudrate; + config.enableLoopBack = loopback; + config.enableListenOnlyMode = silent; + config.maxMbNum = 64; + config.enableIndividMask = true; // required to enable matching using a 'Listener' + // config.disableSelfReception = true; // TODO: do we want to disable this? + + #if (defined(MIMXRT10XX_FLEXCAN_USE_IMPROVED_TIMING_CONFIG) && MIMXRT10XX_FLEXCAN_USE_IMPROVED_TIMING_CONFIG) + // If improved timing configuration is enabled then tell the SDK to calculate it. + flexcan_timing_config_t timing_config; + memset(&timing_config, 0, sizeof(flexcan_timing_config_t)); + if (FLEXCAN_CalculateImprovedTimingValues(self->data->base, config.baudRate, MIMXRT10XX_FLEXCAN_CLK_FREQ, &timing_config)) { + // SDK could calculate the improved timing configuration. Yay! + // Let's update our flexcan module config to use it. + memcpy(&(config.timingConfig), &timing_config, sizeof(flexcan_timing_config_t)); + } + #endif + + // Initialize the flexcan module with user-defined settings. + FLEXCAN_Init(self->data->base, &config, MIMXRT10XX_FLEXCAN_CLK_FREQ); + + // Create FlexCAN handle structure and set call back function. + // As callback data we set 'self'. In callback we can cast it back to 'canio_can_obj_t'. + FLEXCAN_TransferCreateHandle(self->data->base, &self->data->handle, mimxrt10xx_flexcan_callback, (void *)self); + + // Set rx mask to don't care on all bits. + flexcan_rx_fifo_config_t fifo_config; + fifo_config.idFilterNum = 0; + fifo_config.idFilterTable = self->data->rx_fifo_filter; + fifo_config.idFilterType = kFLEXCAN_RxFifoFilterTypeA; + fifo_config.priority = kFLEXCAN_RxFifoPrioHigh; + FLEXCAN_SetRxFifoConfig(self->data->base, &fifo_config, true); + + claim_pin(rx); + claim_pin(tx); + + can_objs[instance] = self; +} + +bool common_hal_canio_can_loopback_get(canio_can_obj_t *self) { + return self->loopback; +} + +int common_hal_canio_can_baudrate_get(canio_can_obj_t *self) { + return self->baudrate; +} + +int common_hal_canio_can_transmit_error_count_get(canio_can_obj_t *self) { + uint8_t tx_err_cnt; // Transmit error counter. + FLEXCAN_GetBusErrCount(self->data->base, &tx_err_cnt, NULL); + return tx_err_cnt; +} + +int common_hal_canio_can_receive_error_count_get(canio_can_obj_t *self) { + uint8_t rx_err_cnt; // Transmit error counter. + FLEXCAN_GetBusErrCount(self->data->base, NULL, &rx_err_cnt); + return rx_err_cnt; +} + +canio_bus_state_t common_hal_canio_can_state_get(canio_can_obj_t *self) { + uint64_t status_flags = FLEXCAN_GetStatusFlags(self->data->base); + if ((status_flags & CAN_ESR1_FLTCONF(2)) != 0U) { + return BUS_STATE_OFF; + } + if ((status_flags & CAN_ESR1_FLTCONF(1)) != 0U) { + return BUS_STATE_ERROR_PASSIVE; + } + if ((status_flags & (kFLEXCAN_TxErrorWarningFlag | kFLEXCAN_RxErrorWarningFlag)) != 0) { + return BUS_STATE_ERROR_WARNING; + } + return BUS_STATE_ERROR_ACTIVE; +} + +void common_hal_canio_can_restart(canio_can_obj_t *self) { + // Supposedly the felxcan SDK has built in recovery. + // But I will leave this code here just in case. + + canio_bus_state_t state = common_hal_canio_can_state_get(self); + if (state != BUS_STATE_OFF) { + return; + } + + self->data->base->CTRL1 &= ~CAN_CTRL1_BOFFREC_MASK; + + // Hard coded wait time for bus to recover. + uint64_t deadline = supervisor_ticks_ms64() + 100; // 100ms timeout + do { + if (supervisor_ticks_ms64() > deadline) { + break; + } + RUN_BACKGROUND_TASKS; + } while (common_hal_canio_can_state_get(self) == BUS_STATE_OFF); + + self->data->base->CTRL1 |= CAN_CTRL1_BOFFREC_MASK; +} + +bool common_hal_canio_can_auto_restart_get(canio_can_obj_t *self) { + return self->auto_restart; +} + +void common_hal_canio_can_auto_restart_set(canio_can_obj_t *self, bool value) { + self->auto_restart = value; +} + +static void maybe_auto_restart(canio_can_obj_t *self) { + if (self->auto_restart) { + common_hal_canio_can_restart(self); + } +} + +void common_hal_canio_can_send(canio_can_obj_t *self, mp_obj_t message_in) { + maybe_auto_restart(self); + + canio_bus_state_t state = common_hal_canio_can_state_get(self); + if (state == BUS_STATE_OFF) { + // Bus is off. Transmit failed. + mp_raise_OSError(MP_ENODEV); + } + + canio_message_obj_t *message = message_in; + + flexcan_frame_t tx_frame; + memset(&tx_frame, 0, sizeof(tx_frame)); // Zero out output. + + if (message->extended) { + tx_frame.id = FLEXCAN_ID_EXT(message->id); + tx_frame.format = kFLEXCAN_FrameFormatExtend; + } else { + tx_frame.id = FLEXCAN_ID_STD(message->id); + tx_frame.format = kFLEXCAN_FrameFormatStandard; + } + + if (message->base.type == &canio_remote_transmission_request_type) { + tx_frame.type = kFLEXCAN_FrameTypeRemote; + } else { + tx_frame.type = kFLEXCAN_FrameTypeData; + } + + tx_frame.length = message->size; + + // We can safely copy all bytes, as both flexcan_frame_t and + // canio_message_obj_t define the data array as 8 bytes long, + // even if the actual DLC is shorter. + tx_frame.dataByte0 = message->data[0]; + tx_frame.dataByte1 = message->data[1]; + tx_frame.dataByte2 = message->data[2]; + tx_frame.dataByte3 = message->data[3]; + tx_frame.dataByte4 = message->data[4]; + tx_frame.dataByte5 = message->data[5]; + tx_frame.dataByte6 = message->data[6]; + tx_frame.dataByte7 = message->data[7]; + + flexcan_mb_transfer_t tx_xfer; + tx_xfer.mbIdx = mimxrt10xx_flexcan_get_free_tx_mbid(self); + tx_xfer.frame = &tx_frame; + + // Setup tx message buffer. + FLEXCAN_SetTxMbConfig(self->data->base, tx_xfer.mbIdx, true); + + if (FLEXCAN_TransferSendNonBlocking(self->data->base, &self->data->handle, &tx_xfer) != kStatus_Success) { + mp_raise_OSError(MP_EIO); + } +} + +bool common_hal_canio_can_silent_get(canio_can_obj_t *self) { + return self->silent; +} + +bool common_hal_canio_can_deinited(canio_can_obj_t *self) { + return !self->data; +} + +void common_hal_canio_can_check_for_deinit(canio_can_obj_t *self) { + if (common_hal_canio_can_deinited(self)) { + raise_deinited_error(); + } +} + +void common_hal_canio_can_deinit(canio_can_obj_t *self) { + if (self->data) { + mimxrt10xx_flexcan_abort_tx_frames(self); + FLEXCAN_TransferAbortReceiveFifo(self->data->base, &self->data->handle); + + FLEXCAN_Deinit(self->data->base); + + // Free can data by doing nothing and letting gc take care of it. + // If the VM has finished already, this will be safe. + self->data = NULL; + } + + common_hal_reset_pin(self->rx_pin); + common_hal_reset_pin(self->tx_pin); + + self->rx_pin = NULL; + self->tx_pin = NULL; +} + +void common_hal_canio_reset(void) { + for (size_t i = 0; i < MP_ARRAY_SIZE(can_objs); i++) { + if (can_objs[i]) { + common_hal_canio_can_deinit(can_objs[i]); + can_objs[i] = NULL; + } + } +} diff --git a/ports/mimxrt10xx/common-hal/canio/CAN.h b/ports/mimxrt10xx/common-hal/canio/CAN.h new file mode 100644 index 00000000000..11c77c9d4a4 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/canio/CAN.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 qutefox +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-bindings/canio/__init__.h" +#include "shared-bindings/canio/CAN.h" +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/canio/__init__.h" + +typedef struct canio_can_obj { + mp_obj_base_t base; + mimxrt10xx_flexcan_data_t *data; + int baudrate; + const mcu_pin_obj_t *rx_pin; + const mcu_pin_obj_t *tx_pin; + bool loopback : 1; + bool silent : 1; + bool auto_restart : 1; +} canio_can_obj_t; diff --git a/ports/mimxrt10xx/common-hal/canio/Listener.c b/ports/mimxrt10xx/common-hal/canio/Listener.c new file mode 100644 index 00000000000..e6355499834 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/canio/Listener.c @@ -0,0 +1,171 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 qutefox +// SPDX-FileCopyrightText: Copyright (c) 2025 SamantazFox +// +// SPDX-License-Identifier: MIT + + +#include +#include + +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mperrno.h" + +#include "shared/runtime/interrupt_char.h" + +#include "common-hal/canio/__init__.h" +#include "common-hal/canio/Listener.h" +#include "shared-bindings/canio/Listener.h" +#include "shared-bindings/util.h" +#include "supervisor/shared/tick.h" +#include "sdk/drivers/flexcan/fsl_flexcan.h" + + +// Convert from back from FLEXCAN IDs to normal CAN IDs. +#define FLEXCAN_ID_TO_CAN_ID_STD(id) \ + ((uint32_t)((((uint32_t)(id)) & CAN_ID_STD_MASK) >> CAN_ID_STD_SHIFT)) + +#define FLEXCAN_ID_TO_CAN_ID_EXT(id) \ + ((uint32_t)((((uint32_t)(id)) & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK)) \ + >> CAN_ID_EXT_SHIFT)) + + +void common_hal_canio_listener_construct(canio_listener_obj_t *self, canio_can_obj_t *can, size_t nmatch, canio_match_obj_t **matches, float timeout) { + + common_hal_canio_listener_set_timeout(self, timeout); + + if (nmatch > MIMXRT10XX_FLEXCAN_RX_FILTER_COUNT) { + mp_raise_ValueError(MP_ERROR_TEXT("Filters too complex")); + } + + self->can = can; + + // Init configuration variables + flexcan_rx_fifo_config_t fifo_config; + fifo_config.idFilterNum = nmatch; + fifo_config.idFilterTable = self->can->data->rx_fifo_filter; + fifo_config.idFilterType = kFLEXCAN_RxFifoFilterTypeA; + fifo_config.priority = kFLEXCAN_RxFifoPrioHigh; + + if (nmatch == 0) { + // If the user has provided no matches, we need to set at least one + // filter that instructs the system to ignore all bits. + fifo_config.idFilterNum = 1; + self->can->data->rx_fifo_filter[0] = 0x0; + FLEXCAN_SetRxIndividualMask(self->can->data->base, 0, 0x0); + } else { + // Required to touch any CAN registers + FLEXCAN_EnterFreezeMode(self->can->data->base); + + for (size_t i = 0; i < nmatch; i++) { + if (matches[i]->extended) { + self->can->data->rx_fifo_filter[i] = FLEXCAN_RX_FIFO_EXT_FILTER_TYPE_A(matches[i]->id, 0, 1); + self->can->data->base->RXIMR[i] = FLEXCAN_RX_FIFO_EXT_MASK_TYPE_A(matches[i]->mask, 0, 1); + } else { + self->can->data->rx_fifo_filter[i] = FLEXCAN_RX_FIFO_STD_FILTER_TYPE_A(matches[i]->id, 0, 0); + self->can->data->base->RXIMR[i] = FLEXCAN_RX_FIFO_STD_MASK_TYPE_A(matches[i]->mask, 0, 0); + } + } + + // For consistency, even though FLEXCAN_SetRxFifoConfig() below will + // enter and exit freeze mode again anyway + FLEXCAN_ExitFreezeMode(self->can->data->base); + } + + FLEXCAN_SetRxFifoConfig(self->can->data->base, &fifo_config, true); +} + +void common_hal_canio_listener_set_timeout(canio_listener_obj_t *self, float timeout) { + self->timeout_ms = (int)MICROPY_FLOAT_C_FUN(ceil)(timeout * 1000); +} + +float common_hal_canio_listener_get_timeout(canio_listener_obj_t *self) { + return self->timeout_ms / 1000.0f; +} + +void common_hal_canio_listener_check_for_deinit(canio_listener_obj_t *self) { + if (!self->can) { + raise_deinited_error(); + } + common_hal_canio_can_check_for_deinit(self->can); +} + +int common_hal_canio_listener_in_waiting(canio_listener_obj_t *self) { + if (FLEXCAN_GetMbStatusFlags(self->can->data->base, kFLEXCAN_RxFifoFrameAvlFlag)) { + return 1; + } + return 0; +} + +mp_obj_t common_hal_canio_listener_receive(canio_listener_obj_t *self) { + if (!common_hal_canio_listener_in_waiting(self)) { + uint64_t deadline = supervisor_ticks_ms64() + self->timeout_ms; + do { + if (supervisor_ticks_ms64() > deadline) { + return NULL; + } + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return NULL; + } + } while (!common_hal_canio_listener_in_waiting(self)); + } + + flexcan_frame_t rx_frame; + if (FLEXCAN_ReadRxFifo(self->can->data->base, &rx_frame) != kStatus_Success) { + mp_raise_OSError(MP_EIO); + } + + // We've read from the FIFO, clear the "frame available" flag, which + // allows the CPU to serve the next FIFO entry + FLEXCAN_ClearMbStatusFlags(self->can->data->base, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag); + + const mp_obj_type_t *type; + if (rx_frame.type == kFLEXCAN_FrameTypeRemote) { + type = &canio_remote_transmission_request_type; + } else { + type = &canio_message_type; + } + canio_message_obj_t *message = mp_obj_malloc(canio_message_obj_t, type); + memset(message, 0, sizeof(canio_message_obj_t)); + + if (rx_frame.format == kFLEXCAN_FrameFormatExtend) { + message->extended = true; + message->id = rx_frame.id; + } else { + message->extended = false; + message->id = rx_frame.id >> 18; // standard ids are left-aligned + } + + + message->size = rx_frame.length; + + // We can safely copy all bytes, as both flexcan_frame_t and + // canio_message_obj_t define the data array as 8 bytes long. + message->data[0] = rx_frame.dataByte0; + message->data[1] = rx_frame.dataByte1; + message->data[2] = rx_frame.dataByte2; + message->data[3] = rx_frame.dataByte3; + message->data[4] = rx_frame.dataByte4; + message->data[5] = rx_frame.dataByte5; + message->data[6] = rx_frame.dataByte6; + message->data[7] = rx_frame.dataByte7; + + return message; +} + +void common_hal_canio_listener_deinit(canio_listener_obj_t *self) { + if (self->can) { + // Clear all filters. + flexcan_rx_fifo_config_t fifo_config; + fifo_config.idFilterNum = 0; + fifo_config.idFilterTable = self->can->data->rx_fifo_filter; + fifo_config.idFilterType = kFLEXCAN_RxFifoFilterTypeA; + fifo_config.priority = kFLEXCAN_RxFifoPrioHigh; + FLEXCAN_SetRxFifoConfig(self->can->data->base, &fifo_config, true); + } + self->can = NULL; +} diff --git a/ports/mimxrt10xx/common-hal/canio/Listener.h b/ports/mimxrt10xx/common-hal/canio/Listener.h new file mode 100644 index 00000000000..2c1c1c82d50 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/canio/Listener.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 qutefox +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/canio/CAN.h" +#include "shared-module/canio/Match.h" + +typedef struct canio_listener_obj { + mp_obj_base_t base; + canio_can_obj_t *can; + uint32_t timeout_ms; +} canio_listener_obj_t; diff --git a/ports/mimxrt10xx/common-hal/canio/__init__.c b/ports/mimxrt10xx/common-hal/canio/__init__.c new file mode 100644 index 00000000000..aaae9be4d4c --- /dev/null +++ b/ports/mimxrt10xx/common-hal/canio/__init__.c @@ -0,0 +1,8 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 qutefox +// SPDX-FileCopyrightText: Copyright (c) 2025 SamantazFox +// +// SPDX-License-Identifier: MIT + +#include "common-hal/canio/__init__.h" diff --git a/ports/mimxrt10xx/common-hal/canio/__init__.h b/ports/mimxrt10xx/common-hal/canio/__init__.h new file mode 100644 index 00000000000..8f63b6c2f11 --- /dev/null +++ b/ports/mimxrt10xx/common-hal/canio/__init__.h @@ -0,0 +1,54 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2023 qutefox +// SPDX-FileCopyrightText: Copyright (c) 2025 SamantazFox +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/canio/Message.h" +#include "sdk/drivers/flexcan/fsl_flexcan.h" + +// There are 64 message buffers in each mimxrt10xx chip. +// Rx fifo will use the message buffers at the front (from index zero). +// As far as I can see rx fifo uses message buffer 0 to 5. +// Also id filter table might occupy message buffer memory area 6 to 37. +// +// Let's use the last few message buffers for sending. +// +// We use 8 (tx) message buffers in total. +// This makes tracking the state (free/busy) of each (tx) message buffer easy. +// We can use a single byte, where each bit represent the state. +// Zero means the message buffer can be used for sending. +// One means the message buffer is busy sending. +// If you make this larger then you have to change the type of 'tx_state' in struct 'mimxrt10xx_flexcan_data_t'. +#define MIMXRT10XX_FLEXCAN_TX_MB_NUM (8) + +// For safety we use SDK provided macro to get the last message buffer index instead of hard coding it. +#define MIMXRT10XX_FLEXCAN_TX_MBID_MAX (FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(0)) +#define MIMXRT10XX_FLEXCAN_TX_MBID_MIN (MIMXRT10XX_FLEXCAN_TX_MBID_MAX - MIMXRT10XX_FLEXCAN_TX_MB_NUM) + +// Convert from tx message buffer index to frame array index. +#define MIMXRT10XX_FLEXCAN_TX_MBID_TO_ARRID(x) (x - MIMXRT10XX_FLEXCAN_TX_MBID_MIN) + +// Convert from frame array index to tx message buffer index. +#define MIMXRT10XX_FLEXCAN_TX_ARRID_TO_MBID(x) (x + MIMXRT10XX_FLEXCAN_TX_MBID_MIN) + +// We limit the amount of filter+mask pairs to 8 because above that the filters +// are impacted by the global mask rather than individual masks alone, which is +// not compatible with the current canio implementation. +// +// See Table 44-22 of the i.MX RT1060 Processor Reference Manual, Rev. 3 +// for more details. +#define MIMXRT10XX_FLEXCAN_RX_FILTER_COUNT (8) + +// Enables/disables SDK calculated "improved" timing configuration. +#define MIMXRT10XX_FLEXCAN_USE_IMPROVED_TIMING_CONFIG (1) + +typedef struct { + CAN_Type *base; // FlexCAN peripheral base address. + flexcan_handle_t handle; // FlexCAN handle which can be used for FlexCAN transactional APIs. + uint8_t tx_state; + uint32_t rx_fifo_filter[MIMXRT10XX_FLEXCAN_RX_FILTER_COUNT]; +} mimxrt10xx_flexcan_data_t; diff --git a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c index 23e854953d6..c7cbd52566b 100644 --- a/ports/mimxrt10xx/common-hal/microcontroller/Processor.c +++ b/ports/mimxrt10xx/common-hal/microcontroller/Processor.c @@ -77,5 +77,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } diff --git a/ports/mimxrt10xx/common-hal/os/__init__.c b/ports/mimxrt10xx/common-hal/os/__init__.c index 79ae228dc42..ac168f2ed09 100644 --- a/ports/mimxrt10xx/common-hal/os/__init__.c +++ b/ports/mimxrt10xx/common-hal/os/__init__.c @@ -17,31 +17,6 @@ #include "sdk/drivers/trng/fsl_trng.h" #endif -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "mimxrt10xx"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "mimxrt10xx"); -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { #if CIRCUITPY_RANDOM trng_config_t trngConfig; diff --git a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c index e1507c7fc02..169ce096307 100644 --- a/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c +++ b/ports/mimxrt10xx/common-hal/pwmio/PWMOut.c @@ -144,7 +144,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, // We want variable frequency but another class has already claim a fixed frequency. if (variable_frequency) { - return PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE; + return PWMOUT_INTERNAL_RESOURCES_IN_USE; } // Another pin is already using this output. @@ -153,7 +153,7 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, } if (frequency != _pwm_sm_frequencies[flexpwm_index][submodule]) { - return PWMOUT_INVALID_FREQUENCY_ON_PIN; + return PWMOUT_INTERNAL_RESOURCES_IN_USE; } // Submodule is already running at our target frequency and the output diff --git a/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c index c71f8b212e1..211b5c186f3 100644 --- a/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/mimxrt10xx/common-hal/rotaryio/IncrementalEncoder.c @@ -26,6 +26,9 @@ static void encoder_change(void *self_in) { void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + self->pin_a = pin_a; self->pin_b = pin_b; @@ -49,7 +52,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode } bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self) { - return !self->pin_a; + return self->pin_a == NULL; } void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t *self) { @@ -62,6 +65,9 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o common_hal_reset_pin(self->pin_a); common_hal_reset_pin(self->pin_b); + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { self->pin_a = NULL; - self->pin_b = NULL; } diff --git a/ports/mimxrt10xx/common-hal/usb_host/Port.c b/ports/mimxrt10xx/common-hal/usb_host/Port.c index 31af4ed5823..a7e73ab5b5c 100644 --- a/ports/mimxrt10xx/common-hal/usb_host/Port.c +++ b/ports/mimxrt10xx/common-hal/usb_host/Port.c @@ -47,5 +47,8 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, self->dp = dp; self->dm = dm; + claim_pin(dp); + claim_pin(dm); + return self; } diff --git a/ports/mimxrt10xx/mpconfigport.h b/ports/mimxrt10xx/mpconfigport.h index 4f9acd7a9fd..df634dc7328 100644 --- a/ports/mimxrt10xx/mpconfigport.h +++ b/ports/mimxrt10xx/mpconfigport.h @@ -17,10 +17,6 @@ extern uint8_t _ld_filesystem_end; extern uint8_t _ld_default_stack_size; #define CIRCUITPY_DEFAULT_STACK_SIZE ((uint32_t)&_ld_default_stack_size) -#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) -#define MICROPY_PY_FUNCTION_ATTRS (0) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) - #define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR ((uint32_t)&_ld_filesystem_start) #define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE ((uint32_t)(&_ld_filesystem_end - &_ld_filesystem_start)) @@ -29,6 +25,8 @@ extern uint8_t _ld_default_stack_size; // are aligned to cache lines. #define MICROPY_BYTES_PER_GC_BLOCK (32) +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED (1) + #include "py/circuitpy_mpconfig.h" // TODO: diff --git a/ports/mimxrt10xx/mpconfigport.mk b/ports/mimxrt10xx/mpconfigport.mk index 20d802eb354..b3f078c7ecf 100644 --- a/ports/mimxrt10xx/mpconfigport.mk +++ b/ports/mimxrt10xx/mpconfigport.mk @@ -2,8 +2,6 @@ LD_FILE = $(FLASH).ld $(CHIP_FAMILY).ld imxrt10xx.ld INTERNAL_LIBM = 1 -USB_HIGHSPEED = 1 - # Number of USB endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 8 # Align buffers on the cache boundary so we don't inadvertently load them early. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pin_names.h index 1d6a9cafaf8..3cf071f62ca 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1011/pin_names.h @@ -6,8 +6,7 @@ // // SPDX-License-Identifier: MIT -#pragma once - +// OK to include more than once because FORMAT_PIN may be different. // define FORMAT_PIN(pin_name) and then include this file. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/pin_names.h index ee8b47b61af..a0bb59e5479 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1015/pin_names.h @@ -6,7 +6,7 @@ // // SPDX-License-Identifier: MIT -#pragma once +// OK to include more than once because FORMAT_PIN may be different. // define FORMAT_PIN(pin_name) and then include this file. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pin_names.h index 1218cd8ed8d..45203c59968 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1021/pin_names.h @@ -6,7 +6,7 @@ // // SPDX-License-Identifier: MIT -#pragma once +// OK to include more than once because FORMAT_PIN may be different. // define FORMAT_PIN(pin_name) and then include this file. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/pin_names.h index 42f03e02f91..8a98f4560a6 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1042/pin_names.h @@ -6,7 +6,7 @@ // // SPDX-License-Identifier: MIT -#pragma once +// OK to include more than once because FORMAT_PIN may be different. // define FORMAT_PIN(pin_name) and then include this file. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/pin_names.h index 5483206f94f..41d2d67f81a 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1052/pin_names.h @@ -6,7 +6,7 @@ // // SPDX-License-Identifier: MIT -#pragma once +// OK to include more than once because FORMAT_PIN may be different. // define FORMAT_PIN(pin_name) and then include this file. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c index 9385c9cc4c7..86ae09f7ca0 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/clocks.c @@ -167,9 +167,9 @@ void clocks_init(void) { CLOCK_DisableClock(kCLOCK_Can2S); CLOCK_DisableClock(kCLOCK_Can3S); /* Set CAN_CLK_PODF. */ - CLOCK_SetDiv(kCLOCK_CanDiv, 1); + CLOCK_SetDiv(kCLOCK_CanDiv, 2); // Clock divider for master flexcan clock source /* Set Can clock source. */ - CLOCK_SetMux(kCLOCK_CanMux, 2); + CLOCK_SetMux(kCLOCK_CanMux, 0); // Select 60M clock divided by USB1 PLL (480 MHz) as master flexcan clock source /* Disable UART clock gate. */ CLOCK_DisableClock(kCLOCK_Lpuart1); CLOCK_DisableClock(kCLOCK_Lpuart2); diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c index 4d5e909bede..cc19dc137b6 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.c @@ -276,6 +276,40 @@ const mcu_periph_obj_t mcu_mqs_right_list[3] = { PERIPH_PIN(3, 2, 0, 0, &pin_GPIO_B0_00), }; +CAN_Type *const mcu_can_banks[3] = { CAN1, CAN2, CAN3 }; + +const mcu_periph_obj_t mcu_can_rx_list[11] = { + PERIPH_PIN(1, 4, kIOMUXC_FLEXCAN1_RX_SELECT_INPUT, 0, &pin_GPIO_SD_B1_03), + PERIPH_PIN(1, 3, kIOMUXC_FLEXCAN1_RX_SELECT_INPUT, 1, &pin_GPIO_EMC_18), + PERIPH_PIN(1, 2, kIOMUXC_FLEXCAN1_RX_SELECT_INPUT, 2, &pin_GPIO_AD_B1_09), + PERIPH_PIN(1, 2, kIOMUXC_FLEXCAN1_RX_SELECT_INPUT, 3, &pin_GPIO_B0_03), + + PERIPH_PIN(2, 3, kIOMUXC_FLEXCAN2_RX_SELECT_INPUT, 0, &pin_GPIO_EMC_10), + PERIPH_PIN(2, 0, kIOMUXC_FLEXCAN2_RX_SELECT_INPUT, 1, &pin_GPIO_AD_B0_03), + PERIPH_PIN(2, 6, kIOMUXC_FLEXCAN2_RX_SELECT_INPUT, 2, &pin_GPIO_AD_B0_15), + PERIPH_PIN(2, 6, kIOMUXC_FLEXCAN2_RX_SELECT_INPUT, 3, &pin_GPIO_B1_09), + + PERIPH_PIN(3, 9, 0, 0, &pin_GPIO_EMC_37), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_AD_B0_11), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_AD_B0_15), +}; + +const mcu_periph_obj_t mcu_can_tx_list[11] = { + PERIPH_PIN(1, 3, 0, 0, &pin_GPIO_EMC_17), + PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_AD_B1_08), + PERIPH_PIN(1, 2, 0, 0, &pin_GPIO_B0_02), + PERIPH_PIN(1, 4, 0, 0, &pin_GPIO_SD_B1_02), + + PERIPH_PIN(2, 3, 0, 0, &pin_GPIO_EMC_09), + PERIPH_PIN(2, 0, 0, 0, &pin_GPIO_AD_B0_02), + PERIPH_PIN(2, 6, 0, 0, &pin_GPIO_AD_B0_14), + PERIPH_PIN(2, 6, 0, 0, &pin_GPIO_B1_08), + + PERIPH_PIN(3, 9, 0, 0, &pin_GPIO_EMC_36), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_AD_B0_10), + PERIPH_PIN(3, 8, 0, 0, &pin_GPIO_AD_B0_14), +}; + const mcu_pwm_obj_t mcu_pwm_list[67] = { PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, IOMUXC_GPIO_EMC_23_FLEXPWM1_PWMA00, &pin_GPIO_EMC_23), PWM_PIN(PWM1, kPWM_Module_0, kPWM_PwmA, IOMUXC_GPIO_SD_B0_00_FLEXPWM1_PWMA00, &pin_GPIO_SD_B0_00), diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h index ab1355ae55a..9c41e563c48 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/periph.h @@ -41,4 +41,8 @@ extern const mcu_periph_obj_t mcu_i2s_mclk_list[7]; extern const mcu_periph_obj_t mcu_mqs_left_list[3]; extern const mcu_periph_obj_t mcu_mqs_right_list[3]; +extern CAN_Type *const mcu_can_banks[3]; +extern const mcu_periph_obj_t mcu_can_rx_list[11]; +extern const mcu_periph_obj_t mcu_can_tx_list[11]; + extern const mcu_pwm_obj_t mcu_pwm_list[67]; diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/pin_names.h index 5483206f94f..41d2d67f81a 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1062/pin_names.h @@ -6,7 +6,7 @@ // // SPDX-License-Identifier: MIT -#pragma once +// OK to include more than once because FORMAT_PIN may be different. // define FORMAT_PIN(pin_name) and then include this file. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/pin_names.h index ec23d603de7..b5a5b86b4dd 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/MIMXRT1176/pin_names.h @@ -6,7 +6,7 @@ // // SPDX-License-Identifier: MIT -#pragma once +// OK to include more than once because FORMAT_PIN may be different. // define FORMAT_PIN(pin_name) and then include this file. diff --git a/ports/mimxrt10xx/peripherals/mimxrt10xx/pin_names.h b/ports/mimxrt10xx/peripherals/mimxrt10xx/pin_names.h index 22fa6c57296..ffaa74edc38 100644 --- a/ports/mimxrt10xx/peripherals/mimxrt10xx/pin_names.h +++ b/ports/mimxrt10xx/peripherals/mimxrt10xx/pin_names.h @@ -5,8 +5,6 @@ // // SPDX-License-Identifier: MIT -#pragma once - // OK to include more than once because FORMAT_PIN may be different. #ifdef MIMXRT1011_SERIES diff --git a/ports/mimxrt10xx/reset.h b/ports/mimxrt10xx/reset.h index 04c951221e9..cae838556bc 100644 --- a/ports/mimxrt10xx/reset.h +++ b/ports/mimxrt10xx/reset.h @@ -16,6 +16,6 @@ #define DBL_TAP_MAGIC 0xf01669ef // Randomly selected, adjusted to have first and last bit set #define DBL_TAP_MAGIC_QUICK_BOOT 0xf02669ef -void reset_to_bootloader(void) NORETURN; -void reset(void) NORETURN; +void reset_to_bootloader(void) MP_NORETURN; +void reset(void) MP_NORETURN; bool bootloader_available(void); diff --git a/ports/mimxrt10xx/supervisor/cpu.S b/ports/mimxrt10xx/supervisor/cpu.S deleted file mode 100755 index 9e6807a5e2e..00000000000 --- a/ports/mimxrt10xx/supervisor/cpu.S +++ /dev/null @@ -1,27 +0,0 @@ -.syntax unified -.cpu cortex-m4 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0], #4 -str r5, [r0], #4 -str r6, [r0], #4 -str r7, [r0], #4 -str r8, [r0], #4 -str r9, [r0], #4 -str r10, [r0], #4 -str r11, [r0], #4 -str r12, [r0], #4 -str r13, [r0], #4 - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c index fe7ee14a3b7..62d2569cfde 100644 --- a/ports/mimxrt10xx/supervisor/port.c +++ b/ports/mimxrt10xx/supervisor/port.c @@ -22,7 +22,6 @@ #include "common-hal/microcontroller/Pin.h" #include "common-hal/rtc/RTC.h" -#include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "shared-bindings/microcontroller/__init__.h" @@ -426,11 +425,6 @@ safe_mode_t port_init(void) { } void reset_port(void) { - #if CIRCUITPY_BUSIO - i2c_reset(); - spi_reset(); - #endif - #if CIRCUITPY_AUDIOIO audio_dma_reset(); #endif @@ -452,8 +446,6 @@ void reset_port(void) { #endif // reset_event_system(); - - reset_all_pins(); } void reset_to_bootloader(void) { diff --git a/ports/mimxrt10xx/tools/gen_peripherals_data.py b/ports/mimxrt10xx/tools/gen_peripherals_data.py index e255ed844a5..e9ceeb63f2d 100644 --- a/ports/mimxrt10xx/tools/gen_peripherals_data.py +++ b/ports/mimxrt10xx/tools/gen_peripherals_data.py @@ -1,4 +1,5 @@ import sys +import re import pathlib import xml.etree.ElementTree as ET @@ -8,6 +9,7 @@ "LPUART": ["RX", "TX", "RTS", "CTS"], "I2S": ["RX_DATA0", "RX_SYNC", "TX_BCLK", "TX_DATA0", "TX_SYNC", "MCLK"], "MQS": ["LEFT", "RIGHT"], + "CAN": ["RX", "TX"], } SIGNAL_RENAME = { @@ -21,6 +23,23 @@ "RX_DATA": "RX_DATA0", } +INSTANCE_RENAME = {"FLEXCAN": "CAN"} + +INSTANCE_RE = re.compile("([a-zA-Z0-9]+?)([0-9]+)$") + + +def rename_instance(instance: str) -> str: + instance_match = INSTANCE_RE.match(instance) + if instance_match is None: + return instance + instance_res = instance_match.groups() + if len(instance_res) < 2: + return instance + instance_name = str(instance_res[0]) + instance_id = str(instance_res[1]) + return INSTANCE_RENAME.get(instance_name, instance_name) + instance_id + + SKIP_LPSR = True svd_folder = pathlib.Path(sys.argv[1]) @@ -37,6 +56,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2019 Lucian Copeland for Adafruit Industries // SPDX-FileCopyrightText: Copyright (c) 2019 Artur Pacholec // SPDX-FileCopyrightText: Copyright (c) 2023 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2023 qutefox // // SPDX-License-Identifier: MIT """ @@ -54,6 +74,7 @@ print(device) autogen_warning = autogen_warning_template.format(device) svd_fn = svd_folder / device / (device + ".xml") + if not svd_fn.exists(): svd_fn = svd_folder / device / (device + "_cm7.xml") @@ -144,8 +165,10 @@ if name.endswith("SELECT_INPUT"): name_split = name.split("_") instance = name_split[0] + instance = rename_instance(instance) signal = "_".join(name_split[1:-2]) signal = SIGNAL_RENAME.get(signal, signal) + if instance not in peripheral_inputs: peripheral_inputs[instance] = {} if signal not in peripheral_inputs[instance]: @@ -232,6 +255,7 @@ print("skipping", pin_name, connection) continue instance, signal = connection.split("_", maxsplit=1) + instance = rename_instance(instance) signal = SIGNAL_RENAME.get(signal, signal) if instance not in peripheral_inputs: peripheral_inputs[instance] = {} @@ -264,7 +288,7 @@ pins_h.append("// Pads can be reset. Other pins like USB cannot be.") pins_h.append(f"#define PAD_COUNT ({pin_number})") pins_h.append(f"#define PIN_COUNT (PAD_COUNT + {len(usb_pins)})") - pins_h.append(f"extern const mcu_pin_obj_t mcu_pin_list[PIN_COUNT];") + pins_h.append("extern const mcu_pin_obj_t mcu_pin_list[PIN_COUNT];") pins_h.append("") out_dir.mkdir(exist_ok=True) @@ -283,11 +307,12 @@ "", ] - for ptype in SIGNALS: + for ptype, signals in SIGNALS: instances = all_peripherals[ptype] short_name = ptype.lower() if short_name.startswith("lp"): short_name = short_name[2:] + # Only one MQS exists and it is related to SAI3 if ptype != "MQS": periph_h.append( @@ -298,7 +323,7 @@ f"{ptype}_Type *const mcu_{short_name}_banks[{len(instances)}] = {{ {joined_instances} }};" ) periph_c.append("") - for signal in SIGNALS[ptype]: + for signal in signals: pin_count = 0 for instance in instances: if instance not in peripheral_inputs or signal not in peripheral_inputs[instance]: @@ -332,8 +357,8 @@ periph_c.append( f" PERIPH_PIN({instance_number}, {alt}, {select_input}, {input_value}, &pin_{pin_name})," ) - periph_c.append(f"}};") - periph_c.append(f"") + periph_c.append("};") + periph_c.append("") periph_h.append("") pwm_outputs.sort(key=lambda x: x[:3]) @@ -348,7 +373,7 @@ periph_c.append( f" PWM_PIN(PWM{pwm_instance}, kPWM_Module_{module}, kPWM_Pwm{channel}, IOMUXC_{pin_name}_{connection}, &pin_{pin_name})," ) - periph_c.append(f"}};") + periph_c.append("};") periph_c.append("") periph_h.append("") diff --git a/ports/nordic/Makefile b/ports/nordic/Makefile index 85acb9d8b4e..1e283fc699c 100755 --- a/ports/nordic/Makefile +++ b/ports/nordic/Makefile @@ -36,8 +36,8 @@ ifeq ($(DEBUG), 1) CFLAGS += -ggdb3 OPTIMIZATION_FLAGS = -Og else - OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions - CFLAGS += -DNDEBUG -ggdb3 + OPTIMIZATION_FLAGS ?= -O2 + CFLAGS += -DNDEBUG endif ifeq ($(NRF_DEBUG_PRINT), 1) @@ -47,7 +47,7 @@ endif # option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk CFLAGS += $(OPTIMIZATION_FLAGS) -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -nostdlib -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) -Werror=missing-prototypes -Werror=old-style-definition # Nordic Softdevice SDK header files contains inline assembler that has # broken constraints. As a result the IPA-modref pass, introduced in gcc-11, @@ -146,20 +146,9 @@ SRC_C += $(SRC_DCD) $(patsubst %.c,$(BUILD)/%.o,$(SRC_DCD)): CFLAGS += -Wno-missing-prototypes endif # CIRCUITPY_USB_DEVICE -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) +SRC_S = shared/runtime/gchelper_thumb2.s -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - -# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, -# because a few modules have files both in common-hal/ and shared-module/. -# Doing a $(sort ...) removes duplicates as part of sorting. -SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) - -SRC_S = supervisor/cpu.s +SRC_C += shared/runtime/gchelper_native.c OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_NRFX:.c=.o)) @@ -180,7 +169,7 @@ $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR += diff --git a/ports/nordic/bluetooth/ble_drv.c b/ports/nordic/bluetooth/ble_drv.c index 35d577f117c..7085aa477b5 100644 --- a/ports/nordic/bluetooth/ble_drv.c +++ b/ports/nordic/bluetooth/ble_drv.c @@ -20,7 +20,7 @@ #include "py/mpstate.h" #include "mpconfigport.h" -#if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE +#if CIRCUITPY_BLE_SERIAL_SERVICE && CIRCUITPY_VERBOSE_BLE #include "supervisor/shared/bluetooth/serial.h" #endif @@ -229,7 +229,7 @@ void SD_EVT_IRQHandler(void) { } } - #if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE && CIRCUITPY_VERBOSE_BLE ble_serial_disable(); #endif while (1) { @@ -270,7 +270,7 @@ void SD_EVT_IRQHandler(void) { } #endif } - #if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE && CIRCUITPY_VERBOSE_BLE ble_serial_enable(); #endif } diff --git a/ports/nordic/boards/TG-Watch/mpconfigboard.h b/ports/nordic/boards/TG-Watch/mpconfigboard.h index 8ebb88f6f86..4016b1ea84c 100644 --- a/ports/nordic/boards/TG-Watch/mpconfigboard.h +++ b/ports/nordic/boards/TG-Watch/mpconfigboard.h @@ -13,7 +13,7 @@ #define MICROPY_HW_MCU_NAME "nRF52840" // TG-Gui requires a deeper call stack than normal CircuitPython, this is intentional overkill -#define CIRCUITPY_PYSTACK_SIZE 8192 // 1536 is the normal size, (32 bytes/frame * 48 frames) +#define CIRCUITPY_PYSTACK_SIZE 8192 // the board has a 32mhz crystal but NOT a 32khz one #define BOARD_HAS_32KHZ_XTAL 0 diff --git a/ports/nordic/boards/bluemicro833/mpconfigboard.mk b/ports/nordic/boards/bluemicro833/mpconfigboard.mk index 3fcb7cdbb07..e1502f09b55 100644 --- a/ports/nordic/boards/bluemicro833/mpconfigboard.mk +++ b/ports/nordic/boards/bluemicro833/mpconfigboard.mk @@ -17,6 +17,7 @@ CIRCUITPY_NVM = 0 CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_PIXELBUF = 1 CIRCUITPY_PIXELMAP = 0 +CIRCUITPY_PULSEIO = 0 CIRCUITPY_TOUCHIO = 0 # Features to disable diff --git a/ports/nordic/boards/circuitplayground_bluefruit/mpconfigboard.h b/ports/nordic/boards/circuitplayground_bluefruit/mpconfigboard.h index 91cf68095d2..d63a9ccd5d8 100644 --- a/ports/nordic/boards/circuitplayground_bluefruit/mpconfigboard.h +++ b/ports/nordic/boards/circuitplayground_bluefruit/mpconfigboard.h @@ -50,3 +50,7 @@ #define DEFAULT_UART_BUS_TX (&pin_P0_14) #define SPEAKER_ENABLE_PIN (&pin_P1_04) + +// Uncomment to allow debugging over console UART +// #define CIRCUITPY_CONSOLE_UART_TX (&pin_P0_14) +// #define CIRCUITPY_CONSOLE_UART_RX (&pin_P0_30) diff --git a/ports/nordic/boards/clue_nrf52840_express/board.c b/ports/nordic/boards/clue_nrf52840_express/board.c index e2cd8a324ba..0b331b63a96 100644 --- a/ports/nordic/boards/clue_nrf52840_express/board.c +++ b/ports/nordic/boards/clue_nrf52840_express/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_13, // TFT_DC Command or data - &pin_P0_12, // TFT_CS Chip select - &pin_P1_03, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_13), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_12), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_P1_03), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/nordic/boards/electronut_labs_blip/mpconfigboard.mk b/ports/nordic/boards/electronut_labs_blip/mpconfigboard.mk index 0e3b1b90489..fc59a101e45 100644 --- a/ports/nordic/boards/electronut_labs_blip/mpconfigboard.mk +++ b/ports/nordic/boards/electronut_labs_blip/mpconfigboard.mk @@ -11,3 +11,4 @@ INTERNAL_FLASH_FILESYSTEM = 1 CIRCUITPY_AUDIOIO = 0 CIRCUITPY_DISPLAYIO = 1 CIRCUITPY_STAGE = 1 +CIRCUITPY_DIGITALINOUT_PROTOCOL = 0 diff --git a/ports/nordic/boards/espruino_banglejs2/board.c b/ports/nordic/boards/espruino_banglejs2/board.c index 16af0269168..09adb43f8be 100644 --- a/ports/nordic/boards/espruino_banglejs2/board.c +++ b/ports/nordic/boards/espruino_banglejs2/board.c @@ -9,7 +9,6 @@ #include "mpconfigboard.h" #include "shared-bindings/busio/SPI.h" -#include "shared-bindings/fourwire/FourWire.h" #include "shared-bindings/framebufferio/FramebufferDisplay.h" #include "shared-bindings/sharpdisplay/SharpMemoryFramebuffer.h" #include "shared-module/displayio/__init__.h" diff --git a/ports/nordic/boards/hiibot_bluefi/board.c b/ports/nordic/boards/hiibot_bluefi/board.c index 73430d675eb..a05be7a0a63 100644 --- a/ports/nordic/boards/hiibot_bluefi/board.c +++ b/ports/nordic/boards/hiibot_bluefi/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_27, // TFT_DC Command or data - &pin_P0_05, // TFT_CS Chip select - NULL, // no TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_27), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_05), // TFT_CS Chip select + mp_const_none, // no TFT_RST Reset // &pin_P1_14, // TFT_RST Reset 60000000, // Baudrate 0, // Polarity diff --git a/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c b/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c index 64199b98009..4f9c051478a 100644 --- a/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c +++ b/ports/nordic/boards/makerdiary_nrf52840_m2_devkit/board.c @@ -35,9 +35,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_08, // TFT_DC Command or data - &pin_P0_06, // TFT_CS Chip select - &pin_P1_09, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_08), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_06), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_P1_09), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/nordic/boards/ohs2020_badge/board.c b/ports/nordic/boards/ohs2020_badge/board.c index ea716006cb4..d16d99473f0 100644 --- a/ports/nordic/boards/ohs2020_badge/board.c +++ b/ports/nordic/boards/ohs2020_badge/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_P0_08, // TFT_DC Command or data - &pin_P0_14, // TFT_CS Chip select - &pin_P0_13, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_P0_08), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_P0_14), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_P0_13), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/nordic/boards/omnimo_nrf52840/board.c b/ports/nordic/boards/omnimo_nrf52840/board.c new file mode 100644 index 00000000000..b44a1ae51e0 --- /dev/null +++ b/ports/nordic/boards/omnimo_nrf52840/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/nordic/boards/omnimo_nrf52840/mpconfigboard.h b/ports/nordic/boards/omnimo_nrf52840/mpconfigboard.h new file mode 100644 index 00000000000..301df3ff9f4 --- /dev/null +++ b/ports/nordic/boards/omnimo_nrf52840/mpconfigboard.h @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Glenn Ruben Bakke +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "nrfx/hal/nrf_gpio.h" + +#define MICROPY_HW_BOARD_NAME "OMNIMO nRF52840" +#define MICROPY_HW_MCU_NAME "nRF52840" + +#define MICROPY_HW_NEOPIXEL (&pin_P0_16) + +#define CIRCUITPY_STATUS_LED_POWER (&pin_P1_10) + + +#define MICROPY_HW_LED_STATUS (&pin_P1_15) + +#if QSPI_FLASH_FILESYSTEM +#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(0, 17) +#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(0, 22) +#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(0, 23) +#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(0, 21) +#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(0, 19) +#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(0, 20) +#endif + +#if SPI_FLASH_FILESYSTEM +#define SPI_FLASH_MOSI_PIN &pin_P0_17 +#define SPI_FLASH_MISO_PIN &pin_P0_22 +#define SPI_FLASH_SCK_PIN &pin_P0_19 +#define SPI_FLASH_CS_PIN &pin_P0_20 +#endif + +#define BOARD_HAS_CRYSTAL 1 + +#define DEFAULT_I2C_BUS_SCL (&pin_P0_11) +#define DEFAULT_I2C_BUS_SDA (&pin_P0_12) + +#define DEFAULT_SPI_BUS_SCK (&pin_P0_14) +#define DEFAULT_SPI_BUS_MOSI (&pin_P0_13) +#define DEFAULT_SPI_BUS_MISO (&pin_P0_15) + +#define DEFAULT_UART_BUS_RX (&pin_P0_24) +#define DEFAULT_UART_BUS_TX (&pin_P0_25) diff --git a/ports/nordic/boards/omnimo_nrf52840/mpconfigboard.mk b/ports/nordic/boards/omnimo_nrf52840/mpconfigboard.mk new file mode 100644 index 00000000000..e73be61d728 --- /dev/null +++ b/ports/nordic/boards/omnimo_nrf52840/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x1209 +USB_PID = 0xCECE +USB_PRODUCT = "OMNIMO nRF52840" +USB_MANUFACTURER = "eAFAQ" + +MCU_CHIP = nrf52840 + +QSPI_FLASH_FILESYSTEM = 1 +EXTERNAL_FLASH_DEVICES = "GD25Q16C, W25Q16JVxQ" diff --git a/ports/nordic/boards/omnimo_nrf52840/pins.c b/ports/nordic/boards/omnimo_nrf52840/pins.c new file mode 100644 index 00000000000..8016037a0ae --- /dev/null +++ b/ports/nordic/boards/omnimo_nrf52840/pins.c @@ -0,0 +1,115 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_P0_04) }, // Feather + { MP_ROM_QSTR(MP_QSTR_PMOD4), MP_ROM_PTR(&pin_P0_04) }, // PMOD + + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_P0_05) }, // Feather + { MP_ROM_QSTR(MP_QSTR_PMOD3), MP_ROM_PTR(&pin_P0_05) }, // PMOD + + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_P0_30) }, // Feather + { MP_ROM_QSTR(MP_QSTR_PMOD2), MP_ROM_PTR(&pin_P0_30) }, // PMOD + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_P0_28) }, // Feather + { MP_ROM_QSTR(MP_QSTR_PMOD1), MP_ROM_PTR(&pin_P0_28) }, // PMOD + + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_P0_02) }, // Feather + + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_P0_03) }, // Feather + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_P0_29) }, + { MP_ROM_QSTR(MP_QSTR_BATTERY), MP_ROM_PTR(&pin_P0_29) }, + + { MP_ROM_QSTR(MP_QSTR_SWITCH), MP_ROM_PTR(&pin_P1_02) }, + { MP_ROM_QSTR(MP_QSTR_BTN1), MP_ROM_PTR(&pin_P1_02) }, + + { MP_ROM_QSTR(MP_QSTR_BTN2), MP_ROM_PTR(&pin_P1_07) }, + + { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) }, + { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_P1_09) }, // Feather + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_P1_08) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_TX), MP_ROM_PTR(&pin_P1_08) }, // mikroBUS + + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_P0_07) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_RX), MP_ROM_PTR(&pin_P0_07) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_P0_26) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_INT), MP_ROM_PTR(&pin_P0_26) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_P0_27) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_PWM), MP_ROM_PTR(&pin_P0_27) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_P1_14) }, // Feather + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_P1_13) }, // Feather + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_P1_12) }, // Feather + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_P0_16) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P0_14) }, // Feather + + { MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_P0_31) }, + { MP_ROM_QSTR(MP_QSTR_mikroBUS_AN), MP_ROM_PTR(&pin_P0_31) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_P0_13) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_RST), MP_ROM_PTR(&pin_P0_13) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_P0_15) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_CS), MP_ROM_PTR(&pin_P0_15) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_P0_25) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_MISO), MP_ROM_PTR(&pin_P0_25) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_P0_24) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_SCK), MP_ROM_PTR(&pin_P0_24) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_P0_11) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_SCL), MP_ROM_PTR(&pin_P0_11) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_P0_12) }, // Feather + { MP_ROM_QSTR(MP_QSTR_mikroBUS_SDA), MP_ROM_PTR(&pin_P0_12) }, // mikroBUS + + { MP_ROM_QSTR(MP_QSTR_PMOD5), MP_ROM_PTR(&pin_P1_11) }, // PMOD + { MP_ROM_QSTR(MP_QSTR_PMOD6), MP_ROM_PTR(&pin_P1_01) }, // PMOD + { MP_ROM_QSTR(MP_QSTR_PMOD7), MP_ROM_PTR(&pin_P1_03) }, // PMOD + { MP_ROM_QSTR(MP_QSTR_PMOD8), MP_ROM_PTR(&pin_P1_05) }, // PMOD + + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_L), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_RED_LED), MP_ROM_PTR(&pin_P1_10) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_P1_10) }, + + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_P1_15) }, + { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_P1_15) }, + + { MP_ROM_QSTR(MP_QSTR_QWIIC_SCL), MP_ROM_PTR(&pin_P0_06) }, + + { MP_ROM_QSTR(MP_QSTR_QWIIC_SDA), MP_ROM_PTR(&pin_P0_08) }, + + { MP_ROM_QSTR(MP_QSTR_VOUTEN), MP_ROM_PTR(&pin_P1_04) }, + + { MP_ROM_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_P1_06) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + /// For Qwiic + { MP_ROM_QSTR(MP_QSTR_QWIIC), MP_ROM_PTR(&board_i2c_obj) }, + +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/nordic/boards/particle_boron/mpconfigboard.mk b/ports/nordic/boards/particle_boron/mpconfigboard.mk index 26fe7b83db6..e0ee123c99a 100644 --- a/ports/nordic/boards/particle_boron/mpconfigboard.mk +++ b/ports/nordic/boards/particle_boron/mpconfigboard.mk @@ -6,4 +6,4 @@ USB_MANUFACTURER = "Particle" MCU_CHIP = nrf52840 QSPI_FLASH_FILESYSTEM = 1 -EXTERNAL_FLASH_DEVICES = "MX25L3233F" +EXTERNAL_FLASH_DEVICES = "MX25L3233F,MX25R6435F" diff --git a/ports/nordic/boards/pca10100/mpconfigboard.mk b/ports/nordic/boards/pca10100/mpconfigboard.mk index a081a0db479..34bcc47cf9f 100644 --- a/ports/nordic/boards/pca10100/mpconfigboard.mk +++ b/ports/nordic/boards/pca10100/mpconfigboard.mk @@ -9,3 +9,4 @@ INTERNAL_FLASH_FILESYSTEM = 1 CIRCUITPY_ONEWIREIO = 0 CIRCUITPY_AUDIOMIXER = 0 +CIRCUITPY_RAINBOWIO = 0 diff --git a/ports/nordic/common-hal/_bleio/Adapter.c b/ports/nordic/common-hal/_bleio/Adapter.c index b252cc49e58..2ca9df89710 100644 --- a/ports/nordic/common-hal/_bleio/Adapter.c +++ b/ports/nordic/common-hal/_bleio/Adapter.c @@ -32,9 +32,8 @@ #include "supervisor/usb.h" #endif -#if CIRCUITPY_OS_GETENV -#include "shared-bindings/os/__init__.h" -#include "shared-module/os/__init__.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" #endif #define BLE_MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_0_625_MS) @@ -324,11 +323,11 @@ static void bleio_adapter_reset_name(bleio_adapter_obj_t *self) { default_ble_name[len - 1] = nibble_to_hex_lower[addr.addr[0] & 0xf]; default_ble_name[len] = '\0'; // for now we add null for compatibility with C ASCIIZ strings - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_SETTINGS_TOML char ble_name[32]; - os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name)); - if (result == GETENV_OK) { + settings_err_t result = settings_get_str("CIRCUITPY_BLE_NAME", ble_name, sizeof(ble_name)); + if (result == SETTINGS_OK) { common_hal_bleio_adapter_set_name(self, ble_name); return; } @@ -524,7 +523,7 @@ mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t } self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi); size_t max_packet_size = extended ? BLE_GAP_SCAN_BUFFER_EXTENDED_MAX_SUPPORTED : BLE_GAP_SCAN_BUFFER_MAX; - uint8_t *raw_data = m_malloc(sizeof(ble_data_t) + max_packet_size); + uint8_t *raw_data = m_malloc_without_collect(sizeof(ble_data_t) + max_packet_size); ble_data_t *sd_data = (ble_data_t *)raw_data; self->scan_results->common_hal_data = sd_data; sd_data->len = max_packet_size; diff --git a/ports/nordic/common-hal/_bleio/Attribute.h b/ports/nordic/common-hal/_bleio/Attribute.h index 5fa6b4d6377..9a58e16bb86 100644 --- a/ports/nordic/common-hal/_bleio/Attribute.h +++ b/ports/nordic/common-hal/_bleio/Attribute.h @@ -6,6 +6,15 @@ #pragma once +#include + +#include "py/obj.h" + #include "shared-module/_bleio/Attribute.h" extern void bleio_attribute_gatts_set_security_mode(ble_gap_conn_sec_mode_t *perm, bleio_attribute_security_mode_t security_mode); + +size_t bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len); +void bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo); +size_t bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len); +void bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response); diff --git a/ports/nordic/common-hal/_bleio/Characteristic.c b/ports/nordic/common-hal/_bleio/Characteristic.c index 33a373f76c4..2e6042e48e7 100644 --- a/ports/nordic/common-hal/_bleio/Characteristic.c +++ b/ports/nordic/common-hal/_bleio/Characteristic.c @@ -80,8 +80,8 @@ void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, // to allocate. self->initial_value_len = initial_value_bufinfo->len; if (gc_alloc_possible()) { - if (gc_nbytes(initial_value_bufinfo->buf) > 0) { - uint8_t *initial_value = m_malloc(self->initial_value_len); + if (gc_ptr_on_heap(initial_value_bufinfo->buf)) { + uint8_t *initial_value = m_malloc_without_collect(self->initial_value_len); memcpy(initial_value, initial_value_bufinfo->buf, self->initial_value_len); self->initial_value = initial_value; } else { @@ -138,10 +138,10 @@ size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *sel if (self->handle != BLE_GATT_HANDLE_INVALID) { uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); if (common_hal_bleio_service_get_is_remote(self->service)) { - return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len); + return bleio_gattc_read(self->handle, conn_handle, buf, len); } else { // conn_handle is ignored for non-system attributes. - return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len); + return bleio_gatts_read(self->handle, conn_handle, buf, len); } } @@ -159,7 +159,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, if (common_hal_bleio_service_get_is_remote(self->service)) { uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); // Last argument is true if write-no-reponse desired. - common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, + bleio_gattc_write(self->handle, conn_handle, bufinfo, (self->props & CHAR_PROP_WRITE_NO_RESPONSE)); } else { // Validate data length for local characteristics only. @@ -172,7 +172,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, // Always write the value locally even if no connections are active. // conn_handle is ignored for non-system attributes, so we use BLE_CONN_HANDLE_INVALID. - common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo); + bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo); // Check to see if we need to notify or indicate any active connections. for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { bleio_connection_internal_t *connection = &bleio_connections[i]; @@ -255,7 +255,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, } const uint16_t conn_handle = bleio_connection_get_conn_handle(self->service->connection); - common_hal_bleio_check_connected(conn_handle); + bleio_check_connected(conn_handle); uint16_t cccd_value = (notify ? BLE_GATT_HVX_NOTIFICATION : 0) | diff --git a/ports/nordic/common-hal/_bleio/CharacteristicBuffer.c b/ports/nordic/common-hal/_bleio/CharacteristicBuffer.c index 9a86afb39ac..6d1b9b550ef 100644 --- a/ports/nordic/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/nordic/common-hal/_bleio/CharacteristicBuffer.c @@ -97,7 +97,7 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe bleio_characteristic_obj_t *characteristic, mp_float_t timeout, size_t buffer_size) { - uint8_t *buffer = m_malloc(buffer_size); + uint8_t *buffer = m_malloc_without_collect(buffer_size); _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, buffer, buffer_size, NULL, false); } diff --git a/ports/nordic/common-hal/_bleio/Connection.h b/ports/nordic/common-hal/_bleio/Connection.h index 110677dc78b..ea1edf17603 100644 --- a/ports/nordic/common-hal/_bleio/Connection.h +++ b/ports/nordic/common-hal/_bleio/Connection.h @@ -65,6 +65,7 @@ typedef struct { void bleio_connection_clear(bleio_connection_internal_t *self); bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in); +void bleio_check_connected(uint16_t conn_handle); uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self); mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *connection); bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle); diff --git a/ports/nordic/common-hal/_bleio/Descriptor.c b/ports/nordic/common-hal/_bleio/Descriptor.c index 959c8e5c9c0..0d27ca5dc2e 100644 --- a/ports/nordic/common-hal/_bleio/Descriptor.c +++ b/ports/nordic/common-hal/_bleio/Descriptor.c @@ -43,9 +43,9 @@ size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8 if (self->handle != BLE_GATT_HANDLE_INVALID) { uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection); if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { - return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len); + return bleio_gattc_read(self->handle, conn_handle, buf, len); } else { - return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len); + return bleio_gatts_read(self->handle, conn_handle, buf, len); } } @@ -58,7 +58,7 @@ void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buff uint16_t conn_handle = bleio_connection_get_conn_handle(self->characteristic->service->connection); if (common_hal_bleio_service_get_is_remote(self->characteristic->service)) { // false means WRITE_REQ, not write-no-response - common_hal_bleio_gattc_write(self->handle, conn_handle, bufinfo, false); + bleio_gattc_write(self->handle, conn_handle, bufinfo, false); } else { // Validate data length for local descriptors only. if (self->fixed_length && bufinfo->len != self->max_length) { @@ -68,7 +68,7 @@ void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buff mp_raise_ValueError(MP_ERROR_TEXT("Value length > max_length")); } - common_hal_bleio_gatts_write(self->handle, conn_handle, bufinfo); + bleio_gatts_write(self->handle, conn_handle, bufinfo); } } diff --git a/ports/nordic/common-hal/_bleio/PacketBuffer.c b/ports/nordic/common-hal/_bleio/PacketBuffer.c index f3058f6c23d..6b3e86e3b7a 100644 --- a/ports/nordic/common-hal/_bleio/PacketBuffer.c +++ b/ports/nordic/common-hal/_bleio/PacketBuffer.c @@ -278,14 +278,14 @@ void common_hal_bleio_packet_buffer_construct( uint32_t *incoming_buffer = NULL; if (incoming) { incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size); - incoming_buffer = m_malloc(incoming_buffer_size); + incoming_buffer = m_malloc_without_collect(incoming_buffer_size); } uint32_t *outgoing1 = NULL; uint32_t *outgoing2 = NULL; if (outgoing) { - outgoing1 = m_malloc(max_packet_size); - outgoing2 = m_malloc(max_packet_size); + outgoing1 = m_malloc_without_collect(max_packet_size); + outgoing2 = m_malloc_without_collect(max_packet_size); } _common_hal_bleio_packet_buffer_construct(self, characteristic, incoming_buffer, incoming_buffer_size, @@ -485,3 +485,7 @@ void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { ringbuf_deinit(&self->ringbuf); } } + +bool common_hal_bleio_packet_buffer_connected(bleio_packet_buffer_obj_t *self) { + return !common_hal_bleio_packet_buffer_deinited(self) && self->conn_handle != BLE_CONN_HANDLE_INVALID; +} diff --git a/ports/nordic/common-hal/_bleio/Service.c b/ports/nordic/common-hal/_bleio/Service.c index edd67a5fe73..1bd75f8a481 100644 --- a/ports/nordic/common-hal/_bleio/Service.c +++ b/ports/nordic/common-hal/_bleio/Service.c @@ -131,7 +131,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, BLE_GAP_CONN_SEC_MODE_SET_OPEN(&user_desc_md.read_perm); // If the description is on the Python heap, then have the SD copy it. If not, assume it's // static and will live for longer than the SD. - user_desc_md.vloc = gc_nbytes(user_description) > 0 ? BLE_GATTS_VLOC_STACK : BLE_GATTS_VLOC_USER; + user_desc_md.vloc = gc_ptr_on_heap(user_description) ? BLE_GATTS_VLOC_STACK : BLE_GATTS_VLOC_USER; char_md.p_user_desc_md = &user_desc_md; char_md.p_char_user_desc = (const uint8_t *)user_description; char_md.char_user_desc_max_size = strlen(user_description); diff --git a/ports/nordic/common-hal/_bleio/__init__.c b/ports/nordic/common-hal/_bleio/__init__.c index 8c5a46d036e..3d76b93ff15 100644 --- a/ports/nordic/common-hal/_bleio/__init__.c +++ b/ports/nordic/common-hal/_bleio/__init__.c @@ -35,6 +35,9 @@ void check_nrf_error(uint32_t err_code) { case NRF_ERROR_INVALID_PARAM: mp_raise_ValueError(MP_ERROR_TEXT("Invalid BLE parameter")); return; + case NRF_ERROR_INVALID_STATE: + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Invalid state")); + return; case BLE_ERROR_INVALID_CONN_HANDLE: mp_raise_ConnectionError(MP_ERROR_TEXT("Not connected")); return; @@ -67,7 +70,7 @@ void check_sec_status(uint8_t sec_status) { switch (sec_status) { case BLE_GAP_SEC_STATUS_UNSPECIFIED: - mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unspecified issue. Can be that the pairing prompt on the other device was declined or ignored.")); + mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unspecified issue. The pairing request on the other device may have been declined or ignored.")); return; default: mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unknown security error: 0x%04x"), sec_status); @@ -77,7 +80,7 @@ void check_sec_status(uint8_t sec_status) { void common_hal_bleio_init(void) { } -void bleio_user_reset() { +void bleio_user_reset(void) { if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { // Stop any user scanning or advertising. common_hal_bleio_adapter_stop_scan(&common_hal_bleio_adapter_obj); @@ -91,7 +94,7 @@ void bleio_user_reset() { } // Turn off BLE on a reset or reload. -void bleio_reset() { +void bleio_reset(void) { // Set this explicitly to save data. common_hal_bleio_adapter_obj.base.type = &bleio_adapter_type; if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { @@ -109,14 +112,14 @@ void bleio_reset() { // It currently only has properties and no state. Inited by bleio_reset bleio_adapter_obj_t common_hal_bleio_adapter_obj; -void common_hal_bleio_check_connected(uint16_t conn_handle) { +void bleio_check_connected(uint16_t conn_handle) { if (conn_handle == BLE_CONN_HANDLE_INVALID) { mp_raise_ConnectionError(MP_ERROR_TEXT("Not connected")); } } // GATTS read of a Characteristic or Descriptor. -size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len) { +size_t bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len) { // conn_handle is ignored unless this is a system attribute. // If we're not connected, that's OK, because we can still read and write the local value. @@ -130,7 +133,7 @@ size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_ return gatts_value.len; } -void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) { +void bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) { // conn_handle is ignored unless this is a system attribute. // If we're not connected, that's OK, because we can still read and write the local value. @@ -185,8 +188,8 @@ static bool _on_gattc_read_rsp_evt(ble_evt_t *ble_evt, void *param) { return true; } -size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len) { - common_hal_bleio_check_connected(conn_handle); +size_t bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len) { + bleio_check_connected(conn_handle); read_info_t read_info; read_info.buf = buf; @@ -210,15 +213,15 @@ size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_ RUN_BACKGROUND_TASKS; } // Test if we were disconnected while reading - common_hal_bleio_check_connected(read_info.conn_handle); + bleio_check_connected(read_info.conn_handle); ble_drv_remove_event_handler(_on_gattc_read_rsp_evt, &read_info); check_gatt_status(read_info.status); return read_info.final_len; } -void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) { - common_hal_bleio_check_connected(conn_handle); +void bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response) { + bleio_check_connected(conn_handle); ble_gattc_write_params_t write_params = { .write_op = write_no_response ? BLE_GATT_OP_WRITE_CMD: BLE_GATT_OP_WRITE_REQ, diff --git a/ports/nordic/common-hal/alarm/__init__.c b/ports/nordic/common-hal/alarm/__init__.c index 9753b0321fd..5db3e269994 100644 --- a/ports/nordic/common-hal/alarm/__init__.c +++ b/ports/nordic/common-hal/alarm/__init__.c @@ -232,15 +232,12 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { - if (n_dios > 0) { - mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_preserve_dios); - } _setup_sleep_alarms(true, n_alarms, alarms); } #define PRESCALER_VALUE_IN_DEEP_SLEEP (1024) -void NORETURN common_hal_alarm_enter_deep_sleep(void) { +void MP_NORETURN common_hal_alarm_enter_deep_sleep(void) { alarm_pin_pinalarm_prepare_for_deep_sleep(); alarm_time_timealarm_prepare_for_deep_sleep(); diff --git a/ports/nordic/common-hal/alarm/__init__.h b/ports/nordic/common-hal/alarm/__init__.h index 91d717ccce2..336447689ff 100644 --- a/ports/nordic/common-hal/alarm/__init__.h +++ b/ports/nordic/common-hal/alarm/__init__.h @@ -13,7 +13,7 @@ #include "common-hal/alarm/touch/TouchAlarm.h" typedef enum { - NRF_SLEEP_WAKEUP_UNDEFINED, + NRF_SLEEP_WAKEUP_UNDEFINED = 0, NRF_SLEEP_WAKEUP_GPIO, NRF_SLEEP_WAKEUP_TIMER, NRF_SLEEP_WAKEUP_TOUCHPAD, @@ -33,8 +33,9 @@ extern const alarm_sleep_memory_obj_t alarm_sleep_memory_obj; enum { SLEEPMEM_WAKEUP_BY_NONE = 0, - SLEEPMEM_WAKEUP_BY_PIN = 1, - SLEEPMEM_WAKEUP_BY_TIMER = 2, + SLEEPMEM_WAKEUP_BY_PIN, + SLEEPMEM_WAKEUP_BY_TIMER, + SLEEPMEM_WAKEUP_BY_TOUCH, }; #define WAKEUP_PIN_UNDEF 0xFF extern uint8_t sleepmem_wakeup_event; diff --git a/ports/nordic/common-hal/audiobusio/I2SOut.c b/ports/nordic/common-hal/audiobusio/I2SOut.c index 6e8fc208813..fbdaa93cfa4 100644 --- a/ports/nordic/common-hal/audiobusio/I2SOut.c +++ b/ports/nordic/common-hal/audiobusio/I2SOut.c @@ -107,23 +107,30 @@ static void i2s_buffer_fill(audiobusio_i2sout_obj_t *self) { while (!self->paused && !self->stopping && bytesleft) { if (self->sample_data == self->sample_end) { + if (self->last_buffer) { + // The final buffer has been fully output; stop now instead of + // fetching another (which for a single-buffer sample would just + // replay it). + self->stopping = true; + break; + } uint32_t sample_buffer_length; audioio_get_buffer_result_t get_buffer_result = audiosample_get_buffer(self->sample, false, 0, &self->sample_data, &sample_buffer_length); self->sample_end = self->sample_data + sample_buffer_length; + if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) { + self->stopping = true; + break; + } if (get_buffer_result == GET_BUFFER_DONE) { if (self->loop) { audiosample_reset_buffer(self->sample, false, 0); } else { - self->stopping = true; - break; + // Output this final buffer before stopping; don't fetch again. + self->last_buffer = true; } } - if (get_buffer_result == GET_BUFFER_ERROR || sample_buffer_length == 0) { - self->stopping = true; - break; - } } uint16_t bytecount = MIN(bytesleft, (size_t)(self->sample_end - self->sample_data)); if (self->samples_signed) { @@ -182,7 +189,11 @@ static void i2s_buffer_fill(audiobusio_i2sout_obj_t *self) { void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, - const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) { + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified, + bool external_clock) { + if (external_clock) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_external_clock); + } if (main_clock != NULL) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_main_clock); } @@ -238,10 +249,12 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, common_hal_audiobusio_i2sout_stop(self); } + audiosample_check(sample); + self->sample = sample; self->loop = loop; - uint32_t sample_rate = audiosample_sample_rate(sample); - self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; + uint32_t sample_rate = audiosample_get_sample_rate(sample); + self->bytes_per_sample = audiosample_get_bits_per_sample(sample) / 8; uint32_t max_buffer_length; bool single_buffer, samples_signed; @@ -269,8 +282,8 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, self->buffer_length = sample_rate * buffer_length_ms * self->bytes_per_sample * self->channel_count / 1000; self->buffer_length = (self->buffer_length + 3) & ~3; - self->buffers[0] = m_malloc(self->buffer_length); - self->buffers[1] = m_malloc(self->buffer_length); + self->buffers[0] = m_malloc_without_collect(self->buffer_length); + self->buffers[1] = m_malloc_without_collect(self->buffer_length); audiosample_reset_buffer(self->sample, false, 0); @@ -280,6 +293,7 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, self->playing = true; self->paused = false; self->stopping = false; + self->last_buffer = false; i2s_buffer_fill(self); NRF_I2S->RXTXD.MAXCNT = self->buffer_length / 4; diff --git a/ports/nordic/common-hal/audiobusio/I2SOut.h b/ports/nordic/common-hal/audiobusio/I2SOut.h index 7cb62ae3d2b..33ec917eb64 100644 --- a/ports/nordic/common-hal/audiobusio/I2SOut.h +++ b/ports/nordic/common-hal/audiobusio/I2SOut.h @@ -30,6 +30,7 @@ typedef struct { bool left_justified : 1; bool playing : 1; bool stopping : 1; + bool last_buffer : 1; bool paused : 1; bool loop : 1; bool samples_signed : 1; diff --git a/ports/nordic/common-hal/audiopwmio/PWMAudioOut.c b/ports/nordic/common-hal/audiopwmio/PWMAudioOut.c index 89c83bc0669..75df88e4416 100644 --- a/ports/nordic/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/nordic/common-hal/audiopwmio/PWMAudioOut.c @@ -136,7 +136,7 @@ static void audiopwmout_background_obj(audiopwmio_pwmaudioout_obj_t *self) { } } -void audiopwmout_background() { +void audiopwmout_background(void) { // Check the NVIC first because it is part of the CPU and fast to read. if (!NVIC_GetPendingIRQ(PWM0_IRQn) && !NVIC_GetPendingIRQ(PWM1_IRQn) && @@ -188,6 +188,26 @@ bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t *se return !self->pwm; } +static void free_buffers(audiopwmio_pwmaudioout_obj_t *self) { + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(self->buffers[0], self->buffer_size[0]); + self->buffer_size[0] = 0; + #else + m_free(self->buffers[0]); + #endif + + self->buffers[0] = NULL; + + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(self->buffers[1], self->buffer_size[1]); + self->buffer_size[1] = 0; + #else + m_free(self->buffers[1]); + #endif + + self->buffers[1] = NULL; +} + void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t *self) { if (common_hal_audiopwmio_pwmaudioout_deinited(self)) { return; @@ -209,36 +229,43 @@ void common_hal_audiopwmio_pwmaudioout_deinit(audiopwmio_pwmaudioout_obj_t *self self->pwm = NULL; - m_free(self->buffers[0]); - self->buffers[0] = NULL; - - m_free(self->buffers[1]); - self->buffers[1] = NULL; + free_buffers(self); } void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, mp_obj_t sample, bool loop) { if (common_hal_audiopwmio_pwmaudioout_get_playing(self)) { common_hal_audiopwmio_pwmaudioout_stop(self); } + + audiosample_check(sample); + self->sample = sample; self->loop = loop; - uint32_t sample_rate = audiosample_sample_rate(sample); - self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; + uint32_t sample_rate = audiosample_get_sample_rate(sample); + self->bytes_per_sample = audiosample_get_bits_per_sample(sample) / 8; uint32_t max_buffer_length; uint8_t spacing; audiosample_get_buffer_structure(sample, /* single channel */ false, &self->single_buffer, &self->signed_to_unsigned, &max_buffer_length, &spacing); - self->sample_channel_count = audiosample_channel_count(sample); + self->sample_channel_count = audiosample_get_channel_count(sample); mp_arg_validate_length_max(max_buffer_length, UINT16_MAX, MP_QSTR_buffer); - uint16_t buffer_length = (uint16_t)max_buffer_length; - self->buffers[0] = m_malloc(buffer_length * 2 * sizeof(uint16_t)); + size_t buffer_size = (size_t)max_buffer_length * 2 * sizeof(uint16_t); + + self->buffers[0] = m_malloc_without_collect(buffer_size); + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + self->buffer_size[0] = buffer_size; + #endif + if (!self->single_buffer) { - self->buffers[1] = m_malloc(buffer_length * 2 * sizeof(uint16_t)); + self->buffers[1] = m_malloc_without_collect(buffer_size); + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + self->buffer_size[1] = buffer_size; + #endif } @@ -274,11 +301,7 @@ void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) self->stopping = false; self->paused = false; - m_free(self->buffers[0]); - self->buffers[0] = NULL; - - m_free(self->buffers[1]); - self->buffers[1] = NULL; + free_buffers(self); } bool common_hal_audiopwmio_pwmaudioout_get_playing(audiopwmio_pwmaudioout_obj_t *self) { diff --git a/ports/nordic/common-hal/audiopwmio/PWMAudioOut.h b/ports/nordic/common-hal/audiopwmio/PWMAudioOut.h index 9569811ccd9..da0761441f8 100644 --- a/ports/nordic/common-hal/audiopwmio/PWMAudioOut.h +++ b/ports/nordic/common-hal/audiopwmio/PWMAudioOut.h @@ -12,7 +12,11 @@ typedef struct { mp_obj_base_t base; mp_obj_t *sample; NRF_PWM_Type *pwm; + uint16_t *buffers[2]; + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + size_t buffer_size[2]; // Keeps track of allocated size + #endif uint16_t quiescent_value; uint16_t scale; diff --git a/ports/nordic/common-hal/busio/I2C.c b/ports/nordic/common-hal/busio/I2C.c index 292f669f170..999737f632b 100644 --- a/ports/nordic/common-hal/busio/I2C.c +++ b/ports/nordic/common-hal/busio/I2C.c @@ -21,7 +21,8 @@ // all TWI instances have the same max size // 16 bits for 840, 10 bits for 810, 8 bits for 832 #define I2C_MAX_XFER_LEN MIN(((1UL << TWIM0_EASYDMA_MAXCNT_SIZE) - 1), 1024) -#define I2C_TIMEOUT 1000 // 1 second timeout +// 1 second timeout +#define I2C_TIMEOUT 1000 static twim_peripheral_t twim_peripherals[] = { #if NRFX_CHECK(NRFX_TWIM0_ENABLED) @@ -40,42 +41,24 @@ static twim_peripheral_t twim_peripherals[] = { #endif }; -static bool never_reset[MP_ARRAY_SIZE(twim_peripherals)]; - -void i2c_reset(void) { - for (size_t i = 0; i < MP_ARRAY_SIZE(twim_peripherals); i++) { - if (never_reset[i]) { - continue; - } - nrfx_twim_uninit(&twim_peripherals[i].twim); - twim_peripherals[i].in_use = false; - } -} void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { - for (size_t i = 0; i < MP_ARRAY_SIZE(twim_peripherals); i++) { - if (self->twim_peripheral == &twim_peripherals[i]) { - never_reset[i] = true; - - never_reset_pin_number(self->scl_pin_number); - never_reset_pin_number(self->sda_pin_number); - break; - } - } + never_reset_pin_number(self->scl_pin_number); + never_reset_pin_number(self->sda_pin_number); } -static uint8_t twi_error_to_mp(const nrfx_err_t err) { +static mp_negative_errno_t twi_error_to_mp(const nrfx_err_t err) { switch (err) { case NRFX_ERROR_DRV_TWI_ERR_ANACK: - return MP_ENODEV; + return -MP_ENODEV; case NRFX_ERROR_BUSY: - return MP_EBUSY; + return -MP_EBUSY; case NRFX_ERROR_INVALID_ADDR: case NRFX_ERROR_DRV_TWI_ERR_DNACK: case NRFX_ERROR_DRV_TWI_ERR_OVERRUN: - return MP_EIO; + return -MP_EIO; case NRFX_ERROR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: break; } @@ -91,6 +74,10 @@ static void twim_event_handler(nrfx_twim_evt_t const *p_event, void *p_context) } void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + if (scl->number == sda->number) { raise_ValueError_invalid_pins(); } @@ -172,10 +159,13 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { reset_pin_number(self->sda_pin_number); reset_pin_number(self->scl_pin_number); - self->sda_pin_number = NO_PIN; - self->scl_pin_number = NO_PIN; self->twim_peripheral->in_use = false; + common_hal_busio_i2c_mark_deinit(self); +} + +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + self->sda_pin_number = NO_PIN; } // nrfx_twim_tx doesn't support 0-length data so we fall back to the hal API @@ -268,9 +258,9 @@ static nrfx_err_t _twim_xfer_with_timeout(busio_i2c_obj_t *self, nrfx_twim_xfer_ } } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { +static mp_negative_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool stopBit) { if (len == 0) { - return common_hal_busio_i2c_probe(self, addr) ? 0 : MP_ENODEV; + return common_hal_busio_i2c_probe(self, addr) ? 0 : -MP_ENODEV; } nrfx_err_t err = NRFX_SUCCESS; @@ -296,11 +286,11 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, return twi_error_to_mp(err); } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { if (len == 0) { return 0; } @@ -327,9 +317,9 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t return twi_error_to_mp(err); } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_negative_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/nordic/common-hal/busio/I2C.h b/ports/nordic/common-hal/busio/I2C.h index d94ff6929bc..c1c1839f892 100644 --- a/ports/nordic/common-hal/busio/I2C.h +++ b/ports/nordic/common-hal/busio/I2C.h @@ -25,5 +25,3 @@ typedef struct { uint8_t scl_pin_number; uint8_t sda_pin_number; } busio_i2c_obj_t; - -void i2c_reset(void); diff --git a/ports/nordic/common-hal/busio/SPI.c b/ports/nordic/common-hal/busio/SPI.c index 8af4c5f4e83..de54dd08a27 100644 --- a/ports/nordic/common-hal/busio/SPI.c +++ b/ports/nordic/common-hal/busio/SPI.c @@ -59,26 +59,13 @@ static const spim_peripheral_t spim_peripherals[] = { #endif }; -static bool never_reset[MP_ARRAY_SIZE(spim_peripherals)]; - // Separate RAM area for SPIM3 transmit buffer to avoid SPIM3 hardware errata. // https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52840_Rev2%2FERR%2FnRF52840%2FRev2%2Flatest%2Fanomaly_840_198.html static uint8_t *spim3_transmit_buffer = (uint8_t *)SPIM3_BUFFER_RAM_START_ADDR; -void spi_reset(void) { - for (size_t i = 0; i < MP_ARRAY_SIZE(spim_peripherals); i++) { - if (never_reset[i]) { - continue; - } - nrfx_spim_uninit(&spim_peripherals[i].spim); - } -} - void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { for (size_t i = 0; i < MP_ARRAY_SIZE(spim_peripherals); i++) { if (self->spim_peripheral == &spim_peripherals[i]) { - never_reset[i] = true; - never_reset_pin_number(self->clock_pin_number); never_reset_pin_number(self->MOSI_pin_number); never_reset_pin_number(self->MISO_pin_number); @@ -125,6 +112,9 @@ static nrf_spim_frequency_t baudrate_to_spim_frequency(const uint32_t baudrate) void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } @@ -178,6 +168,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock_pin_number == NO_PIN; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock_pin_number = NO_PIN; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; @@ -188,6 +182,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { reset_pin_number(self->clock_pin_number); reset_pin_number(self->MOSI_pin_number); reset_pin_number(self->MISO_pin_number); + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { diff --git a/ports/nordic/common-hal/busio/SPI.h b/ports/nordic/common-hal/busio/SPI.h index 7bfddd9625d..3260c5c27de 100644 --- a/ports/nordic/common-hal/busio/SPI.h +++ b/ports/nordic/common-hal/busio/SPI.h @@ -23,5 +23,3 @@ typedef struct { uint8_t MOSI_pin_number; uint8_t MISO_pin_number; } busio_spi_obj_t; - -void spi_reset(void); diff --git a/ports/nordic/common-hal/busio/UART.c b/ports/nordic/common-hal/busio/UART.c index c9b0024db92..7a4219a9728 100644 --- a/ports/nordic/common-hal/busio/UART.c +++ b/ports/nordic/common-hal/busio/UART.c @@ -122,7 +122,7 @@ void uart_reset(void) { void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { // Don't never reset objects on the heap. - if (gc_alloc_possible() && gc_nbytes(self) > 0) { + if (gc_alloc_possible() && gc_ptr_on_heap(self)) { return; } for (size_t i = 0; i < MP_ARRAY_SIZE(nrfx_uartes); i++) { @@ -182,7 +182,8 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, .interrupt_priority = NRFX_UARTE_DEFAULT_CONFIG_IRQ_PRIORITY, .hal_cfg = { .hwfc = hwfc ? NRF_UARTE_HWFC_ENABLED : NRF_UARTE_HWFC_DISABLED, - .parity = (parity == BUSIO_UART_PARITY_NONE) ? NRF_UARTE_PARITY_EXCLUDED : NRF_UARTE_PARITY_INCLUDED + .parity = (parity == BUSIO_UART_PARITY_NONE) ? NRF_UARTE_PARITY_EXCLUDED : NRF_UARTE_PARITY_INCLUDED, + .stop = (stop == 2 ? NRF_UARTE_STOP_TWO : NRF_UARTE_STOP_ONE), } }; @@ -325,7 +326,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, if (!nrfx_is_in_ram(data)) { // Allocate long strings on the heap. if (len > 128 && gc_alloc_possible()) { - tx_buf = (uint8_t *)m_malloc(len); + tx_buf = (uint8_t *)m_malloc_without_collect(len); } else { tx_buf = alloca(len); } @@ -346,7 +347,7 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, RUN_BACKGROUND_TASKS; } - if (!nrfx_is_in_ram(data) && gc_alloc_possible() && gc_nbytes(tx_buf) > 0) { + if (!nrfx_is_in_ram(data) && gc_alloc_possible() && gc_ptr_on_heap(tx_buf)) { gc_free(tx_buf); } diff --git a/ports/nordic/common-hal/microcontroller/Processor.c b/ports/nordic/common-hal/microcontroller/Processor.c index c80da222307..fc3f0e7150e 100644 --- a/ports/nordic/common-hal/microcontroller/Processor.c +++ b/ports/nordic/common-hal/microcontroller/Processor.c @@ -109,28 +109,28 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - mcu_reset_reason_t r = RESET_REASON_UNKNOWN; + mcu_reset_reason_t r = MCU_RESET_REASON_UNKNOWN; if (reset_reason_saved == 0) { - r = RESET_REASON_POWER_ON; + r = MCU_RESET_REASON_POWER_ON; } else if (reset_reason_saved & POWER_RESETREAS_RESETPIN_Msk) { - r = RESET_REASON_RESET_PIN; + r = MCU_RESET_REASON_RESET_PIN; } else if (reset_reason_saved & POWER_RESETREAS_DOG_Msk) { - r = RESET_REASON_WATCHDOG; + r = MCU_RESET_REASON_WATCHDOG; } else if (reset_reason_saved & POWER_RESETREAS_SREQ_Msk) { - r = RESET_REASON_SOFTWARE; + r = MCU_RESET_REASON_SOFTWARE; #if CIRCUITPY_ALARM // Our "deep sleep" is still actually light sleep followed by a software // reset. Adding this check here ensures we treat it as-if we're waking // from deep sleep. if (sleepmem_wakeup_event != SLEEPMEM_WAKEUP_BY_NONE) { - r = RESET_REASON_DEEP_SLEEP_ALARM; + r = MCU_RESET_REASON_DEEP_SLEEP_ALARM; } #endif } else if ((reset_reason_saved & POWER_RESETREAS_OFF_Msk) || (reset_reason_saved & POWER_RESETREAS_LPCOMP_Msk) || (reset_reason_saved & POWER_RESETREAS_NFC_Msk) || (reset_reason_saved & POWER_RESETREAS_VBUS_Msk)) { - r = RESET_REASON_DEEP_SLEEP_ALARM; + r = MCU_RESET_REASON_DEEP_SLEEP_ALARM; } return r; } diff --git a/ports/nordic/common-hal/microcontroller/__init__.c b/ports/nordic/common-hal/microcontroller/__init__.c index 86e7916d754..fbb40afe044 100644 --- a/ports/nordic/common-hal/microcontroller/__init__.c +++ b/ports/nordic/common-hal/microcontroller/__init__.c @@ -8,6 +8,10 @@ #include "py/obj.h" #include "py/runtime.h" +#if CIRCUITPY_ALARM +#include "common-hal/alarm/__init__.h" +#endif + #include "common-hal/microcontroller/Pin.h" #include "common-hal/microcontroller/Processor.h" @@ -31,7 +35,7 @@ void common_hal_mcu_delay_us(uint32_t delay) { static volatile uint32_t nesting_count = 0; static uint8_t is_nested_critical_region; -void common_hal_mcu_disable_interrupts() { +void common_hal_mcu_disable_interrupts(void) { if (nesting_count == 0) { // Unlike __disable_irq(), this should only be called the first time // "is_nested_critical_region" is sd's equivalent of our nesting count @@ -47,7 +51,7 @@ void common_hal_mcu_disable_interrupts() { nesting_count++; } -void common_hal_mcu_enable_interrupts() { +void common_hal_mcu_enable_interrupts(void) { if (nesting_count == 0) { // This is very very bad because it means there was mismatched disable/enables. reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); @@ -78,6 +82,14 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { void common_hal_mcu_reset(void) { filesystem_flush(); + + // Clear any saved info about last deep sleep wakeup, + // to avoid confusing this software reset with a real deep sleep reset. + // See logic in common_hal_mcu_processor_get_reset_reason(). + #if CIRCUITPY_ALARM + sleepmem_wakeup_event = SLEEPMEM_WAKEUP_BY_NONE; + #endif + reset_cpu(); } diff --git a/ports/nordic/common-hal/os/__init__.c b/ports/nordic/common-hal/os/__init__.c index 78aa1e040cf..54b8ad026a7 100644 --- a/ports/nordic/common-hal/os/__init__.c +++ b/ports/nordic/common-hal/os/__init__.c @@ -17,32 +17,6 @@ #include "nrf_rng.h" -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "nrf52"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "nrf52"); - -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { #ifdef BLUETOOTH_SD uint8_t sd_en = 0; diff --git a/ports/nordic/common-hal/pulseio/PulseIn.c b/ports/nordic/common-hal/pulseio/PulseIn.c index 0a2286090e0..dce3a9c96c1 100644 --- a/ports/nordic/common-hal/pulseio/PulseIn.c +++ b/ports/nordic/common-hal/pulseio/PulseIn.c @@ -98,7 +98,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu } _objs[idx] = self; - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); + self->buffer = (uint16_t *)m_malloc_without_collect(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } diff --git a/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c b/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c index b0617fae7e5..2e8b308ff64 100644 --- a/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/nordic/common-hal/rotaryio/IncrementalEncoder.c @@ -32,6 +32,9 @@ static void _intr_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + self->pin_a = pin_a->number; self->pin_b = pin_b->number; @@ -78,6 +81,10 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o nrfx_gpiote_in_uninit(self->pin_b); reset_pin_number(self->pin_a); reset_pin_number(self->pin_b); + + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { self->pin_a = NO_PIN; - self->pin_b = NO_PIN; } diff --git a/ports/nordic/mpconfigport.h b/ports/nordic/mpconfigport.h index ed6c2827000..33fcfa371e0 100644 --- a/ports/nordic/mpconfigport.h +++ b/ports/nordic/mpconfigport.h @@ -13,8 +13,6 @@ #include "nrf_sdm.h" // for SD_FLASH_SIZE #include "peripherals/nrf/nvm.h" // for FLASH_PAGE_SIZE -#define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) #define MICROPY_PY_SYS_STDIO_BUFFER (1) // 24kiB stack diff --git a/ports/nordic/mpconfigport.mk b/ports/nordic/mpconfigport.mk index 58700817d51..028ceca9fcd 100644 --- a/ports/nordic/mpconfigport.mk +++ b/ports/nordic/mpconfigport.mk @@ -9,6 +9,15 @@ CIRCUITPY_BUILD_EXTENSIONS ?= uf2 # Number of USB endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 8 +# The nRF52 USBD implements isochronous transfers only on the fixed, dedicated +# endpoint number 8 (EP_ISO_NUM in TinyUSB's dcd_nrf5x.c); dcd_edpt_open() rejects +# an ISO endpoint on any other number, so a usb_audio mic/speaker placed on a +# sequentially-allocated endpoint would enumerate but never transfer data. Force +# the usb_audio isochronous endpoint onto endpoint 8. (Only read by usb_audio +# code, so it is harmless when CIRCUITPY_USB_AUDIO is off; defined unconditionally +# to stay independent of where that flag gets set in the include order.) +CFLAGS += -DUSB_AUDIO_ISO_EP_NUM=8 + # All nRF ports have longints. LONGINT_IMPL = MPZ @@ -25,13 +34,15 @@ CIRCUITPY_SYNTHIO_MAX_CHANNELS = 12 # Native BLEIO is not compatible with HCI _bleio. CIRCUITPY_BLEIO_HCI = 0 -CIRCUITPY_BLEIO ?= 1 +CIRCUITPY_BLEIO_NATIVE ?= 1 # No I2CPeripheral implementation CIRCUITPY_I2CTARGET = 0 CIRCUITPY_RTC ?= 1 +CIRCUITPY_SETTINGS_TOML ?= 1 + # frequencyio not yet implemented CIRCUITPY_FREQUENCYIO = 0 @@ -40,11 +51,9 @@ CIRCUITPY_ROTARYIO_SOFTENCODER = 1 # Sleep and Wakeup CIRCUITPY_ALARM ?= 1 -# Turn on the BLE file service +# Turn on the BLE file and serial services for BLE workflow CIRCUITPY_BLE_FILE_SERVICE ?= 1 - -# Turn on the BLE serial service -CIRCUITPY_SERIAL_BLE ?= 1 +CIRCUITPY_BLE_SERIAL_SERVICE ?= 1 CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE ?= 1 @@ -63,6 +72,8 @@ CIRCUITPY_MEMORYMAP ?= 1 CIRCUITPY_RGBMATRIX ?= 1 CIRCUITPY_FRAMEBUFFERIO ?= 1 +CIRCUITPY_HASHLIB ?= 1 + CIRCUITPY_COUNTIO ?= 1 CIRCUITPY_WATCHDOG ?= 1 @@ -81,6 +92,8 @@ ifeq ($(INTERNAL_FLASH_FILESYSTEM),1) OPTIMIZATION_FLAGS ?= -Os CIRCUITPY_LTO = 1 CIRCUITPY_LTO_PARTITION = balanced +else + CIRCUITPY_USB_AUDIO ?= 1 endif else diff --git a/ports/nordic/peripherals/nrf/pins.h b/ports/nordic/peripherals/nrf/pins.h index 096568e87c3..96810764de9 100644 --- a/ports/nordic/peripherals/nrf/pins.h +++ b/ports/nordic/peripherals/nrf/pins.h @@ -12,6 +12,8 @@ #include #include +#include "py/obj.h" + #include "nrf_gpio.h" typedef struct { diff --git a/ports/nordic/supervisor/cpu.s b/ports/nordic/supervisor/cpu.s deleted file mode 100755 index 9e6807a5e2e..00000000000 --- a/ports/nordic/supervisor/cpu.s +++ /dev/null @@ -1,27 +0,0 @@ -.syntax unified -.cpu cortex-m4 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0], #4 -str r5, [r0], #4 -str r6, [r0], #4 -str r7, [r0], #4 -str r8, [r0], #4 -str r9, [r0], #4 -str r10, [r0], #4 -str r11, [r0], #4 -str r12, [r0], #4 -str r13, [r0], #4 - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/nordic/supervisor/port.c b/ports/nordic/supervisor/port.c index 759cb8ed425..1eabfcbe216 100644 --- a/ports/nordic/supervisor/port.c +++ b/ports/nordic/supervisor/port.c @@ -27,7 +27,6 @@ #include "common-hal/microcontroller/Pin.h" #include "common-hal/alarm/time/TimeAlarm.h" #include "common-hal/analogio/AnalogIn.h" -#include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" #include "common-hal/rtc/RTC.h" @@ -190,8 +189,6 @@ safe_mode_t port_init(void) { void reset_port(void) { #if CIRCUITPY_BUSIO - i2c_reset(); - spi_reset(); uart_reset(); #endif @@ -218,8 +215,6 @@ void reset_port(void) { nrfx_gpiote_uninit(); } nrfx_gpiote_init(NRFX_GPIOTE_CONFIG_IRQ_PRIORITY); - - reset_all_pins(); } void reset_to_bootloader(void) { diff --git a/ports/raspberrypi/Makefile b/ports/raspberrypi/Makefile old mode 100644 new mode 100755 index fd4da22ea08..603121e059f --- a/ports/raspberrypi/Makefile +++ b/ports/raspberrypi/Makefile @@ -12,6 +12,7 @@ HAL_DIR=hal/$(MCU_SERIES) ifeq ($(CIRCUITPY_CYW43),1) INC_CYW43 := \ + -isystem lib/cyw43-driver \ -isystem lib/cyw43-driver/firmware \ -isystem lib/cyw43-driver/src \ -isystem lib/lwip/src/include \ @@ -21,7 +22,21 @@ INC_CYW43 := \ -isystem sdk/src/rp2_common/pico_lwip/include/ \ -isystem sdk/src/rp2_common/pico_rand/include/ \ -CFLAGS_CYW43 := -DCYW43_LWIP=1 -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_USE_SPI -DIGNORE_GPIO25 -DIGNORE_GPIO23 -DIGNORE_GPIO24 -DCYW43_LOGIC_DEBUG=0 -DCYW43_USE_STATS=0 -DPICO_BUILD -DCYW43_ENABLE_BLUETOOTH=0 -DPICO_CYW43_ARCH_POLL=0 +CFLAGS_CYW43 := \ + -DCYW43_LWIP=1 \ + -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 \ + -DCYW43_USE_SPI=1 \ + -DUSE_SDIOIT=0 \ + -DIGNORE_GPIO25 \ + -DIGNORE_GPIO23 \ + -DIGNORE_GPIO24 \ + -DCYW43_LOGIC_DEBUG=0 \ + -DCYW43_USE_STATS=0 \ + -DPICO_BUILD \ + -DCYW43_ENABLE_BLUETOOTH=0 \ + -DCIRCUITPY_CYW43_INIT_DELAY=$(CIRCUITPY_CYW43_INIT_DELAY) \ + -DPICO_CYW43_ARCH_POLL=0 + SRC_SDK_CYW43 := \ src/common/pico_sync/sem.c \ src/rp2_common/pico_async_context/async_context_base.c \ @@ -69,6 +84,33 @@ SRC_CYW43 := SRC_LWIP := endif +ifeq ($(CIRCUITPY_WIZNET), 1) +INC_WIZNET := \ + -isystem common-hal/wiznet \ + +SRC_WIZNET := \ + common-hal/wiznet/wizchip_pio_spi.c \ + +WIZNET_PIOASM = $(BUILD)/pioasm/pioasm/pioasm +.PHONY: pioasmBuild +pioasmBuild: $(WIZNET_PIOASM) + +$(WIZNET_PIOASM): + $(Q)cmake -S pioasm -B $(BUILD)/pioasm + $(MAKE) -C $(BUILD)/pioasm pioasmBuild + +$(BUILD)/wizchip_pio_spi.pio.h: common-hal/wiznet/wizchip_pio_spi.pio $(WIZNET_PIOASM) + $(Q)$(WIZNET_PIOASM) -o c-sdk $< $@ +$(BUILD)/common-hal/wiznet/wizchip_pio_spi.o: $(BUILD)/wizchip_pio_spi.pio.h + +$(BUILD)/genhdr/qstr.i.last: $(BUILD)/wizchip_pio_spi.pio.h + +else +INC_WIZNET := +SRC_WIZNET := + +endif + CHIP_VARIANT_LOWER = $(shell echo $(CHIP_VARIANT) | tr '[:upper:]' '[:lower:]') INC += \ @@ -79,8 +121,6 @@ INC += \ -I../shared/timeutils \ -Iboards/$(BOARD) \ -Iboards/ \ - -isystem ./../../lib/cmsis/inc \ - -isystem sdk/ \ -isystem sdk/src/common/boot_picobin_headers/include/ \ -isystem sdk/src/common/boot_picoboot_headers/include/ \ -isystem sdk/src/common/hardware_claim/include/ \ @@ -93,6 +133,9 @@ INC += \ -isystem sdk/src/$(CHIP_VARIANT_LOWER)/hardware_regs/include/ \ -isystem sdk/src/$(CHIP_VARIANT_LOWER)/hardware_structs/include/ \ -isystem sdk/src/$(CHIP_VARIANT_LOWER)/pico_platform/include/ \ + -isystem sdk/src/rp2_common/boot_bootrom_headers/include/ \ + -isystem sdk/src/rp2_common/cmsis/stub/CMSIS/Core/Include/ \ + -isystem sdk/src/rp2_common/cmsis/stub/CMSIS/Device/${CHIP_VARIANT}/Include \ -isystem sdk/src/rp2_common/cmsis/ \ -isystem sdk/src/rp2_common/hardware_adc/include/ \ -isystem sdk/src/rp2_common/hardware_base/include/ \ @@ -110,6 +153,7 @@ INC += \ -isystem sdk/src/rp2_common/hardware_powman/include/ \ -isystem sdk/src/rp2_common/hardware_pwm/include/ \ -isystem sdk/src/rp2_common/hardware_resets/include/ \ + -isystem sdk/src/rp2_common/hardware_rcp/include/ \ -isystem sdk/src/rp2_common/hardware_rtc/include/ \ -isystem sdk/src/rp2_common/hardware_spi/include/ \ -isystem sdk/src/rp2_common/hardware_sync/include/ \ @@ -120,10 +164,12 @@ INC += \ -isystem sdk/src/rp2_common/hardware_vreg/include/ \ -isystem sdk/src/rp2_common/hardware_watchdog/include/ \ -isystem sdk/src/rp2_common/hardware_xosc/include/ \ + -isystem sdk/src/rp2_common/hardware_xip_cache/include/ \ -isystem sdk/src/rp2_common/pico_aon_timer/include/ \ -isystem sdk/src/rp2_common/pico_atomic/include/ \ -isystem sdk/src/rp2_common/pico_bootrom/include/ \ -isystem sdk/src/rp2_common/pico_double/include/ \ + -isystem sdk/src/rp2_common/pico_flash/include/ \ -isystem sdk/src/rp2_common/pico_mem_ops/include/ \ -isystem sdk/src/rp2_common/pico_multicore/include/ \ -isystem sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include/ \ @@ -132,12 +178,13 @@ INC += \ -isystem sdk/src/rp2_common/pico_float/include/ \ -isystem sdk/src/rp2_common/pico_runtime/include/ \ -isystem sdk/src/rp2_common/pico_runtime_init/include/ \ + -isystem sdk/src/rp2_common/pico_platform_common/include/ \ -isystem sdk/src/rp2_common/pico_platform_compiler/include/ \ -isystem sdk/src/rp2_common/pico_platform_sections/include/ \ -isystem sdk/src/rp2_common/pico_platform_panic/include/ \ -isystem sdk/src/rp2_common/pico_time_adapter/include/ \ -isystem sdk/src/rp2_common/pico_unique_id/include/ \ -$(INC_CYW43) \ + $(INC_CYW43) \ -Isdk_config \ -I../../lib/tinyusb/src \ -I../../supervisor/shared/usb \ @@ -158,7 +205,7 @@ CFLAGS += \ -DPICO_DOUBLE_ROM=1 \ -DPICO_FLOAT_ROM=1 \ -DPICO_BITS_IN_RAM=0 \ - -DPICO_DIVIDER_IN_RAM=0 \ + -DPICO_DIVIDER_IN_RAM=1 \ -DPICO_DOUBLE_PROPAGATE_NANS=0 \ -DPICO_DOUBLE_IN_RAM=0 \ -DPICO_MEM_IN_RAM=0 \ @@ -192,7 +239,7 @@ CFLAGS += $(OPTIMIZATION_FLAGS) CFLAGS += $(CFLAGS_CYW43) #Debugging/Optimization ifeq ($(DEBUG), 1) - CFLAGS += -ggdb3 -O3 + CFLAGS += -ggdb3 -Og # No LTO because we may place some functions in RAM instead of flash. else CFLAGS += -DNDEBUG @@ -204,12 +251,15 @@ else endif endif -# Remove -Wno-stringop-overflow after we can test with CI's GCC 10. Mac's looks weird. -DISABLE_WARNINGS = -Wno-stringop-overflow -Wno-cast-align +DISABLE_WARNINGS = -Wno-cast-align -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=missing-prototypes +CFLAGS += $(INC) -Wtype-limits -Wall -Werror -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=missing-prototypes -Wold-style-definition PICO_LDFLAGS = --specs=nosys.specs --specs=nano.specs +# The SDK's panic() is flash-resident, but core1 may run with flash access +# disabled by the MPU. Route panics to the RAM-resident __wrap_panic in +# supervisor/port.c, which halts safely on core1 and prints on core0. +PICO_LDFLAGS += -Wl,--wrap=panic # Use toolchain libm if we're not using our own. ifndef INTERNAL_LIBM @@ -377,6 +427,8 @@ OTHER_PICO_FLAGS := \ -Wl,--wrap=__aeabi_uidivmod \ -Wl,--wrap=__aeabi_uldivmod +SRC_S = shared/runtime/gchelper_thumb1.s + ifeq ($(CHIP_VARIANT),RP2040) CFLAGS += \ -march=armv6-m \ @@ -386,8 +438,7 @@ CFLAGS += \ -msoft-float \ -mfloat-abi=soft -CFLAGS += \ - -DPICO_RP2040 +CFLAGS += -DPICO_RP2040=1 -DPICO_RP2350=0 SRC_SDK_CHIP_VARIANT := \ src/rp2_common/hardware_rtc/rtc.c \ @@ -415,12 +466,12 @@ UF2_ID = 0xE48BFF56 DOUBLE_EABI = rp2040 endif ifeq ($(CHIP_VARIANT),RP2350) -CFLAGS += \ - -march=armv8-m.main+fp+dsp \ +AFLAGS = -march=armv8-m.main+fp+dsp \ -mthumb \ - -mabi=aapcs-linux \ -mcpu=cortex-m33 \ -mfloat-abi=softfp +CFLAGS += $(AFLAGS) \ + -mabi=aapcs-linux # ARM Secure family id UF2_ID = 0xe48bff59 @@ -430,7 +481,7 @@ DOUBLE_EABI = dcp INC += \ -isystem sdk/src/rp2_common/hardware_dcp/include/ -CFLAGS += -DPICO_RP2350=1 +CFLAGS += -DPICO_RP2040=0 -DPICO_RP2350=1 SRC_SDK_CHIP_VARIANT := \ src/rp2_common/hardware_powman/powman.c \ @@ -440,7 +491,7 @@ SRC_S_UPPER_CHIP_VARIANT := \ sdk/src/rp2_common/pico_double/double_fma_dcp.S \ sdk/src/rp2_common/pico_double/double_sci_m33.S \ sdk/src/rp2_common/pico_float/float_sci_m33_vfp.S \ - sdk/src/rp2_common/pico_float/float_conv_m33.S \ + sdk/src/rp2_common/pico_float/float_common_m33.S \ PICO_LDFLAGS += $(PICO_WRAP_FLOAT_SCI_FLAGS) $(PICO_WRAP_DOUBLE_FLAGS) @@ -454,6 +505,7 @@ endif endif +SRC_C += shared/runtime/gchelper_native.c SRC_SDK := \ src/common/hardware_claim/claim.c \ @@ -483,6 +535,7 @@ SRC_SDK := \ src/rp2_common/hardware_uart/uart.c \ src/rp2_common/hardware_vreg/vreg.c \ src/rp2_common/hardware_watchdog/watchdog.c \ + src/rp2_common/hardware_xip_cache/xip_cache.c \ src/rp2_common/hardware_xosc/xosc.c \ src/rp2_common/pico_aon_timer/aon_timer.c \ src/rp2_common/pico_atomic/atomic.c \ @@ -515,6 +568,10 @@ SRC_C += \ bindings/rp2pio/__init__.c \ common-hal/rp2pio/StateMachine.c \ common-hal/rp2pio/__init__.c \ + bindings/wiznet/PIO_SPI.c \ + bindings/wiznet/__init__.c \ + common-hal/wiznet/PIO_SPI.c \ + common-hal/wiznet/__init__.c \ audio_dma.c \ background.c \ peripherals/pins.c \ @@ -524,6 +581,7 @@ SRC_C += \ mphalport.c \ $(SRC_CYW43) \ $(SRC_LWIP) \ + $(SRC_WIZNET) \ ifeq ($(CIRCUITPY_USB_HOST), 1) @@ -535,128 +593,139 @@ SRC_C += \ INC += \ -isystem lib/Pico-PIO-USB/src + +# Core1 posts USB events while core0 may hold the TinyUSB queue mutex. The +# contended wait path calls these two flash-resident SDK functions, and core1 +# must not execute from flash. Replace them with RAM-resident implementations +# in common-hal/usb_host/Port.c on USB host builds only. See issue #11116. +PICO_LDFLAGS += -Wl,--wrap=best_effort_wfe_or_timeout -Wl,--wrap=time_us_64 endif ifeq ($(CIRCUITPY_PICODVI),1) SRC_C += \ bindings/picodvi/__init__.c \ bindings/picodvi/Framebuffer.c \ + common-hal/picodvi/__init__.c \ common-hal/picodvi/Framebuffer_$(CHIP_VARIANT).c \ ifeq ($(CHIP_VARIANT),RP2040) -SRC_C += \ +SRC_PICODVI := \ lib/PicoDVI/software/libdvi/dvi.c \ lib/PicoDVI/software/libdvi/dvi_serialiser.c \ lib/PicoDVI/software/libdvi/dvi_timing.c \ lib/PicoDVI/software/libdvi/tmds_encode.c \ +SRC_C += $(SRC_PICODVI) +$(patsubst %.c,$(BUILD)/%.o,$(SRC_PICODVI))): CFLAGS += -Wno-old-style-definition + endif endif +ifeq ($(CIRCUITPY_SDIOIO),1) +# Vendored Adafruit SdFat PIO SDIO card driver (C++). The common-hal C sources +# (SDCard.c, __init__.c) are picked up automatically through SRC_COMMON_HAL. +SRC_SDIOIO_CXX := \ + common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.cpp \ + common-hal/sdioio/sdfat_pio/shim.cpp \ + common-hal/sdioio/sdfat_pio/cxx_runtime.cpp \ + +INC += -Icommon-hal/sdioio/sdfat_pio + +# The upstream driver body is guarded by ARDUINO_ARCH_RP2040 and was written +# against the Arduino RP2040 core, so define that macro for it. It is vendored +# third-party code, so don't fail the build on its warnings. +$(BUILD)/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.o: CXXFLAGS += -DARDUINO_ARCH_RP2040 -Wno-error +endif + ifeq ($(CIRCUITPY_SSL),1) -CFLAGS += -isystem $(TOP)/mbedtls/include -SRC_MBEDTLS := $(addprefix lib/mbedtls/library/, \ - aes.c \ - aesni.c \ - arc4.c \ - asn1parse.c \ - asn1write.c \ - base64.c \ - bignum.c \ - blowfish.c \ - camellia.c \ - ccm.c \ - certs.c \ - chacha20.c \ - chachapoly.c \ - cipher.c \ - cipher_wrap.c \ - cmac.c \ - constant_time.c \ - ctr_drbg.c \ - debug.c \ - des.c \ - dhm.c \ - ecdh.c \ - ecdsa.c \ - ecjpake.c \ - ecp.c \ - ecp_curves.c \ - entropy.c \ - entropy_poll.c \ - gcm.c \ - havege.c \ - hmac_drbg.c \ - md2.c \ - md4.c \ - md5.c \ - md.c \ - oid.c \ - padlock.c \ - pem.c \ - pk.c \ - pkcs11.c \ - pkcs12.c \ - pkcs5.c \ - pkparse.c \ - pk_wrap.c \ - pkwrite.c \ - platform.c \ - platform_util.c \ - poly1305.c \ - ripemd160.c \ - rsa.c \ - rsa_internal.c \ - sha1.c \ - sha256.c \ - sha512.c \ - ssl_cache.c \ - ssl_ciphersuites.c \ - ssl_cli.c \ - ssl_cookie.c \ - ssl_msg.c \ - ssl_srv.c \ - ssl_ticket.c \ - ssl_tls.c \ - timing.c \ - x509.c \ - x509_create.c \ - x509_crl.c \ - x509_crt.c \ - x509_csr.c \ - x509write_crt.c \ - x509write_csr.c \ - xtea.c \ - ) +# mbedtls 4.x keeps only TLS and X.509 in library/; crypto lives in the tf-psa-crypto +# submodule, split across core/, drivers/builtin/src/, extras/, platform/ and +# utilities/. +# +# Deliberately excluded: +# - mbedtls_config.c, tf_psa_crypto_config.c: pure config-validation translation +# units that #include generated *_config_check_*.h headers. Skipping them is what +# lets us skip that second code generator. +# - net_sockets.c: CircuitPython drives the socket through socketpool callbacks. +# - pkcs7.c: unused, and MBEDTLS_PKCS7_C is off. +# - psa_its_file.c: filesystem-backed PSA key storage; we have no persistent keys. +# - drivers/{everest,p256-m,pqcp}: alternative curve and ML-DSA implementations. +mbedtls_sources = $(patsubst $(TOP)/%,%,$(filter-out $(2),$(wildcard $(TOP)/$(1)/*.c))) + +SRC_MBEDTLS := \ + $(call mbedtls_sources,lib/mbedtls/library,\ + $(TOP)/lib/mbedtls/library/mbedtls_config.c \ + $(TOP)/lib/mbedtls/library/net_sockets.c \ + $(TOP)/lib/mbedtls/library/pkcs7.c) \ + $(call mbedtls_sources,lib/mbedtls/tf-psa-crypto/core,\ + $(TOP)/lib/mbedtls/tf-psa-crypto/core/psa_its_file.c \ + $(TOP)/lib/mbedtls/tf-psa-crypto/core/tf_psa_crypto_config.c) \ + $(call mbedtls_sources,lib/mbedtls/tf-psa-crypto/drivers/builtin/src) \ + $(call mbedtls_sources,lib/mbedtls/tf-psa-crypto/extras) \ + $(call mbedtls_sources,lib/mbedtls/tf-psa-crypto/platform) \ + $(call mbedtls_sources,lib/mbedtls/tf-psa-crypto/utilities) SRC_C += $(SRC_MBEDTLS) lib/mbedtls_config/mbedtls_port.c lib/mbedtls_config/crt_bundle.c +# Public headers of mbedtls and of tf-psa-crypto, then the internal ones. mbedtls 4.x +# still reaches into tf-psa-crypto's internals, so upstream compiles the TLS layer +# with both; see TF_PSA_CRYPTO_LIBRARY_{PUBLIC,PRIVATE}_INCLUDE in +# lib/mbedtls/tf-psa-crypto/scripts/crypto-common.make. CFLAGS += \ -isystem $(TOP)/lib/mbedtls/include \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/include \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/drivers/builtin/include \ + -isystem $(TOP)/lib/mbedtls/library \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/core \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/dispatch \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/drivers/builtin/src \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/extras \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/platform \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/utilities \ -DMBEDTLS_CONFIG_FILE='"$(TOP)/lib/mbedtls_config/mbedtls_config.h"' \ + -DTF_PSA_CRYPTO_CONFIG_FILE='"$(TOP)/lib/mbedtls_config/tf_psa_crypto_config.h"' \ -$(BUILD)/x509_crt_bundle.S: $(TOP)/lib/certificates/data/roots.pem $(TOP)/tools/gen_crt_bundle.py +$(BUILD)/x509_crt_bundle.S: $(TOP)/lib/certificates/data/roots-full.pem $(TOP)/tools/gen_crt_bundle.py $(Q)$(PYTHON) $(TOP)/tools/gen_crt_bundle.py -i $< -o $@ --asm OBJ_MBEDTLS := $(BUILD)/x509_crt_bundle.o -$(patsubst %.c,$(BUILD)/%.o,$(SRC_MBEDTLS))): CFLAGS += -Wno-suggest-attribute=format + +# mbedtls 4.x dispatches PSA crypto through a wrapper layer that is generated from +# jinja templates rather than shipped in the repo, so build it. +# It is the same each time, so we could save it, but this makes updating mbedtls easier. +# +# generate_driver_wrappers.py resolves `mbedtls_framework` relative to its own tree, +# which would mean initializing a third nested submodule (tf-psa-crypto/framework). +# Point PYTHONPATH at the top-level framework submodule instead; mbedtls pins both to +# the same commit. +MBEDTLS_GEN := $(BUILD)/tf-psa-crypto +MBEDTLS_WRAPPERS_H := $(MBEDTLS_GEN)/psa_crypto_driver_wrappers.h +MBEDTLS_WRAPPERS_C := $(MBEDTLS_GEN)/psa_crypto_driver_wrappers_no_static.c + +# The script writes both files at once. Naming both as targets of one rule would run +# it twice; see the same workaround in py/py.mk. +$(MBEDTLS_WRAPPERS_C): $(MBEDTLS_WRAPPERS_H) + @true + +$(MBEDTLS_WRAPPERS_H): $(TOP)/lib/mbedtls/tf-psa-crypto/scripts/generate_driver_wrappers.py + $(STEPECHO) "GEN $@" + $(Q)mkdir -p $(MBEDTLS_GEN) + $(Q)PYTHONPATH=$(TOP)/lib/mbedtls/framework/scripts $(PYTHON) $< $(MBEDTLS_GEN) + +OBJ_MBEDTLS += $(MBEDTLS_WRAPPERS_C:.c=.o) +CFLAGS += -I$(MBEDTLS_GEN) + +# psa_crypto.c and friends #include the generated header, so it has to exist before +# any of them compile. +$(patsubst %.c,$(BUILD)/%.o,$(SRC_MBEDTLS)) $(OBJ_MBEDTLS): $(MBEDTLS_WRAPPERS_H) +# Vendored third-party code, so don't hold it to CircuitPython's warning settings. The +# unused-but-set variables are real but harmless: they are in key-exchange paths that +# are compiled out. +$(patsubst %.c,$(BUILD)/%.o,$(SRC_MBEDTLS)) $(OBJ_MBEDTLS): CFLAGS += \ + -Wno-suggest-attribute=format \ + -Wno-unused-but-set-variable else OBJ_MBEDTLS := endif - -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - -# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, -# because a few modules have files both in common-hal/ and shared-module/. -# Doing a $(sort ...) removes duplicates as part of sorting. -SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) - -SRC_S = supervisor/$(CHIP_FAMILY)_cpu.s BOOT2_S_CFLAGS ?= -DPICO_FLASH_SPI_CLKDIV=4 SRC_S_UPPER = sdk/src/rp2_common/hardware_irq/irq_handler_chain.S \ sdk/src/rp2_common/pico_bit_ops/bit_ops_aeabi.S \ @@ -672,6 +741,12 @@ endif $(patsubst %.S,$(BUILD)/%.o,$(SRC_S_UPPER)): CFLAGS += -Wno-undef +# Derive the C++ flags from the C flags (mirroring the unix port) so the +# vendored C++ translation unit picks up all the SDK include paths and defines. +# Strip the C-only options that g++ rejects, and disable exceptions/RTTI to +# match the firmware's constraints. +CXXFLAGS += $(filter-out -std=gnu11 -Werror=missing-prototypes -Wold-style-definition -Wstrict-prototypes -Werror-implicit-function-declaration -Wnested-externs,$(CFLAGS)) -std=gnu++17 -fno-exceptions -fno-rtti + OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_SDK:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) @@ -684,6 +759,9 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) OBJ += $(BUILD)/boot2_padded_checksummed.o OBJ += $(OBJ_MBEDTLS) +ifeq ($(CIRCUITPY_SDIOIO),1) +OBJ += $(addprefix $(BUILD)/, $(SRC_SDIOIO_CXX:.cpp=.o)) +endif $(BUILD)/%.o: $(BUILD)/%.S $(STEPECHO) "CC $<" @@ -714,7 +792,7 @@ $(BUILD)/boot2.elf: $(BUILD)/stage2.c $(Q)$(CC) $(CFLAGS) $(BOOT2_S_CFLAGS) -Os -ggdb3 -I. -fPIC --specs=nosys.specs -nostartfiles -Wl,-T,boot_stage2/$(CHIP_VARIANT).ld -Wl,-Map=$@.map -o $@ $< $(Q)$(SIZE) $@ -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) all: $(BUILD)/firmware.uf2 @@ -726,6 +804,21 @@ endif LINKER_SCRIPTS += -Wl,-T,link-$(CHIP_VARIANT_LOWER).ld +# Builds where core1 locks flash out via the MPU and may only execute +# RAM-resident code: USB host (PIO-USB frame loop), and picodvi on RP2040 +# (TMDS encode loop). Check the linked ELF from each core1 entry point. +# picodvi's DMA IRQ handler and scanline callback run on core1 but are +# reached only through registered pointers, so they are extra roots. +CORE1_CHECK_ROOTS := +ifeq ($(CIRCUITPY_USB_HOST),1) +CORE1_CHECK_ROOTS += --root core1_main +endif +ifeq ($(CHIP_VARIANT),RP2040) +ifeq ($(CIRCUITPY_PICODVI),1) +CORE1_CHECK_ROOTS += --root core1_main --root dvi_dma1_irq --root core1_scanline_callback +endif +endif + ifeq ($(VALID_BOARD),) $(BUILD)/firmware.elf: invalid-board else @@ -734,6 +827,10 @@ $(BUILD)/firmware.elf: $(OBJ) $(BOARD_LD) link-$(CHIP_VARIANT_LOWER).ld $(Q)echo $(OBJ) > $(BUILD)/firmware.objs $(Q)echo $(PICO_LDFLAGS) > $(BUILD)/firmware.ldflags $(Q)$(CC) -o $@ $(CFLAGS) @$(BUILD)/firmware.ldflags $(LINKER_SCRIPTS) -Wl,--print-memory-usage -Wl,-Map=$@.map -Wl,-cref -Wl,--gc-sections @$(BUILD)/firmware.objs -Wl,-lc +ifneq ($(CORE1_CHECK_ROOTS),) + $(STEPECHO) "CHECK core1 flash calls" + $(Q)$(PYTHON) $(TOP)/tools/check_core1_flash_calls.py $@ $(CORE1_CHECK_ROOTS) +endif endif $(BUILD)/firmware.bin: $(BUILD)/firmware.elf diff --git a/ports/raspberrypi/audio_dma.c b/ports/raspberrypi/audio_dma.c index c837bc116d4..8b2f78266e3 100644 --- a/ports/raspberrypi/audio_dma.c +++ b/ports/raspberrypi/audio_dma.c @@ -9,18 +9,23 @@ #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" #include "shared-bindings/microcontroller/__init__.h" -#include "bindings/rp2pio/StateMachine.h" #include "supervisor/background_callback.h" #include "py/mpstate.h" #include "py/runtime.h" -#include "src/rp2_common/hardware_irq/include/hardware/irq.h" -#include "hardware/regs/intctrl.h" // For isr_ macro. +#include "hardware/irq.h" #if CIRCUITPY_AUDIOCORE +// audio_dma and rp2pio cooperate on DMA_IRQ_0 using the SDK's shared interrupt +// handlers. We add our handler when we enable our first channel and remove it +// when our last channel is disabled. See the DMA IRQ allocation notes in +// common-hal/microcontroller/__init__.c. +static void audio_dma_enable_irq(uint channel); +static void audio_dma_disable_irq(uint channel); + void audio_dma_reset(void) { for (size_t channel = 0; channel < NUM_DMA_CHANNELS; channel++) { if (MP_STATE_PORT(playing_audio)[channel] == NULL) { @@ -118,6 +123,7 @@ static size_t audio_dma_convert_samples(audio_dma_t *dma, uint8_t *input, uint32 // buffer_idx is 0 or 1. static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { + assert(dma->channel[buffer_idx] < NUM_DMA_CHANNELS); size_t dma_channel = dma->channel[buffer_idx]; audioio_get_buffer_result_t get_buffer_result; @@ -128,6 +134,7 @@ static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { if (get_buffer_result == GET_BUFFER_ERROR) { audio_dma_stop(dma); + dma->dma_result = AUDIO_DMA_SOURCE_ERROR; return; } @@ -157,10 +164,16 @@ static void audio_dma_load_next_block(audio_dma_t *dma, size_t buffer_idx) { !dma_channel_is_busy(dma->channel[1])) { // No data has been read, and both DMA channels have now finished, so it's safe to stop. audio_dma_stop(dma); - dma->playing_in_progress = false; + dma->dma_result = AUDIO_DMA_OK; + return; } } } + // Enable the channel so that it can be played. + if (!dma->paused) { + dma_hw->ch[dma_channel].al1_ctrl |= DMA_CH1_CTRL_TRIG_EN_BITS; + } + dma->dma_result = AUDIO_DMA_OK; } // Playback should be shutdown before calling this. @@ -201,7 +214,7 @@ audio_dma_result audio_dma_setup_playback( dma->output_signed = output_signed; dma->sample_spacing = 1; dma->output_resolution = output_resolution; - dma->sample_resolution = audiosample_bits_per_sample(sample); + dma->sample_resolution = audiosample_get_bits_per_sample(sample); dma->output_register_address = output_register_address; dma->swap_channel = swap_channel; @@ -214,6 +227,7 @@ audio_dma_result audio_dma_setup_playback( uint32_t max_buffer_length; audiosample_get_buffer_structure(sample, single_channel_output, &single_buffer, &samples_signed, &max_buffer_length, &dma->sample_spacing); + dma->single_buffer = single_buffer; // Check to see if we have to scale the resolution up. if (dma->sample_resolution <= 8 && dma->output_resolution > 8) { @@ -225,15 +239,33 @@ audio_dma_result audio_dma_setup_playback( max_buffer_length /= dma->sample_spacing; } - dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0], max_buffer_length); + #if PICO_RP2350 + dma->buffer[0] = (uint8_t *)port_realloc(dma->buffer[0], max_buffer_length, true); + #else + dma->buffer[0] = (uint8_t *)m_realloc(dma->buffer[0], + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + dma->buffer_length[0], // Old size + #endif + max_buffer_length); + #endif dma->buffer_length[0] = max_buffer_length; + if (dma->buffer[0] == NULL) { return AUDIO_DMA_MEMORY_ERROR; } if (!single_buffer) { - dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1], max_buffer_length); + #if PICO_RP2350 + dma->buffer[1] = (uint8_t *)port_realloc(dma->buffer[1], max_buffer_length, true); + #else + dma->buffer[1] = (uint8_t *)m_realloc(dma->buffer[1], + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + dma->buffer_length[1], // Old size + #endif + max_buffer_length); + #endif dma->buffer_length[1] = max_buffer_length; + if (dma->buffer[1] == NULL) { return AUDIO_DMA_MEMORY_ERROR; } @@ -248,7 +280,7 @@ audio_dma_result audio_dma_setup_playback( dma->output_size = 1; } // Transfer both channels at once. - if (!single_channel_output && audiosample_channel_count(sample) == 2) { + if (!single_channel_output && audiosample_get_channel_count(sample) == 2) { dma->output_size *= 2; } enum dma_channel_transfer_size dma_size = DMA_SIZE_8; @@ -277,10 +309,18 @@ audio_dma_result audio_dma_setup_playback( MP_STATE_PORT(playing_audio)[dma->channel[0]] = dma; MP_STATE_PORT(playing_audio)[dma->channel[1]] = dma; + dma->paused = false; + // Load the first two blocks up front. audio_dma_load_next_block(dma, 0); + if (dma->dma_result != AUDIO_DMA_OK) { + return dma->dma_result; + } if (!single_buffer) { audio_dma_load_next_block(dma, 1); + if (dma->dma_result != AUDIO_DMA_OK) { + return dma->dma_result; + } } // Special case the DMA for a single buffer. It's commonly used for a single wave length of sound @@ -303,8 +343,8 @@ audio_dma_result audio_dma_setup_playback( } else { // Enable our DMA channels on DMA_IRQ_0 to the CPU. This will wake us up when // we're WFI. - dma_hw->inte0 |= (1 << dma->channel[0]) | (1 << dma->channel[1]); - irq_set_mask_enabled(1 << DMA_IRQ_0, true); + audio_dma_enable_irq(dma->channel[0]); + audio_dma_enable_irq(dma->channel[1]); } dma->playing_in_progress = true; @@ -314,17 +354,14 @@ audio_dma_result audio_dma_setup_playback( } void audio_dma_stop(audio_dma_t *dma) { + dma->paused = true; + // Disable our interrupts. - uint32_t channel_mask = 0; if (dma->channel[0] < NUM_DMA_CHANNELS) { - channel_mask |= 1 << dma->channel[0]; + audio_dma_disable_irq(dma->channel[0]); } if (dma->channel[1] < NUM_DMA_CHANNELS) { - channel_mask |= 1 << dma->channel[1]; - } - dma_hw->inte0 &= ~channel_mask; - if (!dma_hw->inte0) { - irq_set_mask_enabled(1 << DMA_IRQ_0, false); + audio_dma_disable_irq(dma->channel[1]); } // Run any remaining audio tasks because we remove ourselves from @@ -333,12 +370,13 @@ void audio_dma_stop(audio_dma_t *dma) { for (size_t i = 0; i < 2; i++) { size_t channel = dma->channel[i]; + dma->channel[i] = NUM_DMA_CHANNELS; if (channel == NUM_DMA_CHANNELS) { // Channel not in use. continue; } - dma_channel_config c = dma_channel_get_default_config(dma->channel[i]); + dma_channel_config c = dma_channel_get_default_config(channel); channel_config_set_enable(&c, false); dma_channel_set_config(channel, &c, false /* trigger */); @@ -351,7 +389,6 @@ void audio_dma_stop(audio_dma_t *dma) { dma_channel_set_trans_count(channel, 0, false /* trigger */); dma_channel_unclaim(channel); MP_STATE_PORT(playing_audio)[channel] = NULL; - dma->channel[i] = NUM_DMA_CHANNELS; } dma->playing_in_progress = false; @@ -363,6 +400,7 @@ void audio_dma_stop(audio_dma_t *dma) { void audio_dma_pause(audio_dma_t *dma) { dma_hw->ch[dma->channel[0]].al1_ctrl &= ~DMA_CH0_CTRL_TRIG_EN_BITS; dma_hw->ch[dma->channel[1]].al1_ctrl &= ~DMA_CH1_CTRL_TRIG_EN_BITS; + dma->paused = true; } void audio_dma_resume(audio_dma_t *dma) { @@ -375,15 +413,14 @@ void audio_dma_resume(audio_dma_t *dma) { dma_hw->ch[dma->channel[0]].al1_ctrl |= DMA_CH0_CTRL_TRIG_EN_BITS; dma_hw->ch[dma->channel[1]].al1_ctrl |= DMA_CH1_CTRL_TRIG_EN_BITS; } + dma->paused = false; } bool audio_dma_get_paused(audio_dma_t *dma) { if (dma->channel[0] >= NUM_DMA_CHANNELS) { return false; } - uint32_t control = dma_hw->ch[dma->channel[0]].ctrl_trig; - - return (control & DMA_CH0_CTRL_TRIG_EN_BITS) == 0; + return dma->playing_in_progress && dma->paused; } uint32_t audio_dma_pause_all(void) { @@ -411,22 +448,55 @@ void audio_dma_init(audio_dma_t *dma) { dma->buffer[0] = NULL; dma->buffer[1] = NULL; + dma->buffer_length[0] = 0; + dma->buffer_length[1] = 0; + dma->channel[0] = NUM_DMA_CHANNELS; dma->channel[1] = NUM_DMA_CHANNELS; + + dma->playing_in_progress = false; + dma->paused = false; } void audio_dma_deinit(audio_dma_t *dma) { + #if PICO_RP2350 + port_free(dma->buffer[0]); + #else + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(dma->buffer[0], dma->buffer_length[0]); + #else m_free(dma->buffer[0]); + #endif + #endif dma->buffer[0] = NULL; - + dma->buffer_length[0] = 0; + + #if PICO_RP2350 + port_free(dma->buffer[1]); + #else + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(dma->buffer[1], dma->buffer_length[1]); + #else m_free(dma->buffer[1]); + #endif + #endif dma->buffer[1] = NULL; + dma->buffer_length[1] = 0; } bool audio_dma_get_playing(audio_dma_t *dma) { if (dma->channel[0] == NUM_DMA_CHANNELS) { return false; } + // A single-buffer, non-looping sample plays entirely in hardware via DMA + // chaining, with no completion interrupt to stop it. Detect when its DMA + // channel has drained and finish so that playing_in_progress is cleared. + if (dma->single_buffer && !dma->loop && + dma->playing_in_progress && !dma->paused && + !dma_channel_is_busy(dma->channel[0])) { + audio_dma_stop(dma); + return false; + } return dma->playing_in_progress; } @@ -435,6 +505,8 @@ bool audio_dma_get_playing(audio_dma_t *dma) { // NOTE(dhalbert): I successfully printed from here while debugging. // So it's possible, but be careful. static void dma_callback_fun(void *arg) { + // Any audio interrupts that happen below will requeue the background task + // after updating channels_to_load_mask. audio_dma_t *dma = arg; if (dma == NULL) { return; @@ -442,29 +514,44 @@ static void dma_callback_fun(void *arg) { common_hal_mcu_disable_interrupts(); uint32_t channels_to_load_mask = dma->channels_to_load_mask; + // This can be 0 if the background task was queued between the call to + // dma_callback_fun and the above read of channels_to_load_mask. dma->channels_to_load_mask = 0; common_hal_mcu_enable_interrupts(); - // Load the blocks for the requested channels. - uint32_t channel = 0; - while (channels_to_load_mask) { - if (channels_to_load_mask & 1) { - if (dma->channel[0] == channel) { - audio_dma_load_next_block(dma, 0); - } - if (dma->channel[1] == channel) { - audio_dma_load_next_block(dma, 1); - } - } - channels_to_load_mask >>= 1; - channel++; + uint8_t first_filled_channel = NUM_DMA_CHANNELS; + size_t filled_count = 0; + if (dma->channel[0] != NUM_DMA_CHANNELS && (channels_to_load_mask & (1 << dma->channel[0]))) { + audio_dma_load_next_block(dma, 0); + first_filled_channel = dma->channel[0]; + filled_count++; + } + if (dma->channel[1] != NUM_DMA_CHANNELS && (channels_to_load_mask & (1 << dma->channel[1]))) { + audio_dma_load_next_block(dma, 1); + first_filled_channel = dma->channel[1]; + filled_count++; + } + + // Restart if the other channel has been queued while we were filling the first or we filled two + // now. (Two get filled if the second buffer completes while the first is waiting in the + // background task queue.) + if (first_filled_channel != NUM_DMA_CHANNELS && (dma->channels_to_load_mask != 0 || filled_count == 2)) { + dma_channel_start(first_filled_channel); } } -void __not_in_flash_func(isr_dma_0)(void) { +// Shared DMA_IRQ_0 handler for audio. It acknowledges and services only audio +// channels, leaving any other channels' interrupts for the other shared +// handlers (e.g. rp2pio) to acknowledge. +static void __not_in_flash_func(audio_dma_irq_handler)(void) { for (size_t i = 0; i < NUM_DMA_CHANNELS; i++) { uint32_t mask = 1 << i; - if ((dma_hw->intr & mask) == 0) { + if ((dma_hw->ints0 & mask) == 0) { + continue; + } + audio_dma_t *dma = MP_STATE_PORT(playing_audio)[i]; + if (dma == NULL) { + // Not one of our channels; leave it for another shared handler. continue; } // acknowledge interrupt early. Doing so late means that you could lose an @@ -472,16 +559,40 @@ void __not_in_flash_func(isr_dma_0)(void) { // completed by the time callback_add() / dma_complete() returned. This // affected PIO continuous write more than audio. dma_hw->ints0 = mask; - if (MP_STATE_PORT(playing_audio)[i] != NULL) { - audio_dma_t *dma = MP_STATE_PORT(playing_audio)[i]; - // Record all channels whose DMA has completed; they need loading. - dma->channels_to_load_mask |= mask; - background_callback_add(&dma->callback, dma_callback_fun, (void *)dma); - } - if (MP_STATE_PORT(background_pio)[i] != NULL) { - rp2pio_statemachine_obj_t *pio = MP_STATE_PORT(background_pio)[i]; - rp2pio_statemachine_dma_complete(pio, i); - } + // Record all channels whose DMA has completed; they need loading. + dma->channels_to_load_mask |= mask; + // Disable the channel so that we don't play it without filling it. + dma_hw->ch[i].al1_ctrl &= ~DMA_CH0_CTRL_TRIG_EN_BITS; + // This is a noop if the callback is already queued. + background_callback_add(&dma->callback, dma_callback_fun, (void *)dma); + } +} + +// Channels (bitmask) audio currently has enabled on DMA_IRQ_0. Used to decide +// when to add/remove our shared interrupt handler. +static uint32_t audio_dma_irq0_channel_mask = 0; + +static void audio_dma_enable_irq(uint channel) { + // Clear any latent interrupt so that we don't immediately disable the channel. + dma_hw->ints0 = 1u << channel; + if (audio_dma_irq0_channel_mask == 0) { + irq_add_shared_handler(DMA_IRQ_0, audio_dma_irq_handler, + PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY); + } + audio_dma_irq0_channel_mask |= 1u << channel; + dma_irqn_set_channel_enabled(0, channel, true); + irq_set_enabled(DMA_IRQ_0, true); +} + +static void audio_dma_disable_irq(uint channel) { + dma_irqn_set_channel_enabled(0, channel, false); + audio_dma_irq0_channel_mask &= ~(1u << channel); + if (audio_dma_irq0_channel_mask == 0) { + irq_remove_handler(DMA_IRQ_0, audio_dma_irq_handler); + } + // Turn off the IRQ line entirely once no one (audio or rp2pio) needs it. + if (dma_hw->inte0 == 0) { + irq_set_enabled(DMA_IRQ_0, false); } } diff --git a/ports/raspberrypi/audio_dma.h b/ports/raspberrypi/audio_dma.h index 7c33a9e2ac3..57e47c7444e 100644 --- a/ports/raspberrypi/audio_dma.h +++ b/ports/raspberrypi/audio_dma.h @@ -9,11 +9,18 @@ #include "py/obj.h" #include "supervisor/background_callback.h" -#include "src/rp2_common/hardware_dma/include/hardware/dma.h" +#include "hardware/dma.h" + +typedef enum { + AUDIO_DMA_OK, + AUDIO_DMA_DMA_BUSY, + AUDIO_DMA_MEMORY_ERROR, + AUDIO_DMA_SOURCE_ERROR, +} audio_dma_result; typedef struct { mp_obj_t sample; - uint8_t *buffer[2]; + uint8_t *buffer[2]; // Allocated through port_malloc on RP2350 so they are dma-able size_t buffer_length[2]; uint32_t channels_to_load_mask; uint32_t output_register_address; @@ -24,22 +31,18 @@ typedef struct { uint8_t sample_spacing; uint8_t output_resolution; // in bits uint8_t sample_resolution; // in bits + audio_dma_result dma_result; bool loop; + bool single_buffer; bool single_channel_output; bool signed_to_unsigned; bool unsigned_to_signed; bool output_signed; bool playing_in_progress; + bool paused; bool swap_channel; } audio_dma_t; -typedef enum { - AUDIO_DMA_OK, - AUDIO_DMA_DMA_BUSY, - AUDIO_DMA_MEMORY_ERROR, -} audio_dma_result; - - void audio_dma_init(audio_dma_t *dma); void audio_dma_deinit(audio_dma_t *dma); void audio_dma_reset(void); diff --git a/ports/raspberrypi/bindings/cyw43/__init__.c b/ports/raspberrypi/bindings/cyw43/__init__.c index 83aacdc48ae..93755d6ce1e 100644 --- a/ports/raspberrypi/bindings/cyw43/__init__.c +++ b/ports/raspberrypi/bindings/cyw43/__init__.c @@ -12,11 +12,11 @@ #include "shared-bindings/microcontroller/Pin.h" #include "bindings/cyw43/__init__.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "lib/cyw43-driver/src/cyw43.h" -static int power_management_value = PM_DISABLED; +static uint32_t power_management_value = CONST_CYW43_DEFAULT_PM; void cyw43_enter_deep_sleep(void) { #define WL_REG_ON 23 @@ -35,6 +35,7 @@ void bindings_cyw43_wifi_enforce_pm(void) { //| in :py:mod:`board`. A `CywPin` can be used as a DigitalInOut, but not with other //| peripherals such as `PWMOut`.""" //| +//| MP_DEFINE_CONST_OBJ_TYPE( cyw43_pin_type, MP_QSTR_CywPin, @@ -42,14 +43,24 @@ MP_DEFINE_CONST_OBJ_TYPE( print, shared_bindings_microcontroller_pin_print ); +uint32_t cyw43_get_power_management_value(void) { + return power_management_value; +} + +void cyw43_set_power_management_value(uint32_t value) { + power_management_value = value; + bindings_cyw43_wifi_enforce_pm(); +} + //| PM_STANDARD: int -//| """The standard power management mode""" +//| """The default power management mode; same as PM_PERFORMANCE""" //| PM_AGGRESSIVE: int //| """Aggressive power management mode for optimal power usage at the cost of performance""" //| PM_PERFORMANCE: int //| """Performance power management mode where more power is used to increase performance""" //| PM_DISABLED: int -//| """Disable power management and always use highest power mode. CircuitPython sets this value at reset time, because it provides the best connectivity reliability.""" +//| """Disable power management and always use highest power mode.""" +//| //| //| def set_power_management(value: int) -> None: //| """Set the power management register @@ -80,10 +91,10 @@ MP_DEFINE_CONST_OBJ_TYPE( //| usage. //| """ //| +//| static mp_obj_t cyw43_set_power_management(const mp_obj_t value_in) { mp_int_t value = mp_obj_get_int(value_in); - power_management_value = value; - bindings_cyw43_wifi_enforce_pm(); + cyw43_set_power_management_value(value); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(cyw43_set_power_management_obj, cyw43_set_power_management); @@ -91,7 +102,8 @@ static MP_DEFINE_CONST_FUN_OBJ_1(cyw43_set_power_management_obj, cyw43_set_power //| def get_power_management() -> int: //| """Retrieve the power management register""" //| -static mp_obj_t cyw43_get_power_management() { +//| +static mp_obj_t cyw43_get_power_management(void) { return mp_obj_new_int(power_management_value); } static MP_DEFINE_CONST_FUN_OBJ_0(cyw43_get_power_management_obj, cyw43_get_power_management); @@ -122,10 +134,10 @@ static const mp_rom_map_elem_t cyw43_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_CywPin), MP_ROM_PTR(&cyw43_pin_type) }, { MP_ROM_QSTR(MP_QSTR_set_power_management), &cyw43_set_power_management_obj }, { MP_ROM_QSTR(MP_QSTR_get_power_management), &cyw43_get_power_management_obj }, - { MP_ROM_QSTR(MP_QSTR_PM_STANDARD), MP_ROM_INT(PM_STANDARD) }, - { MP_ROM_QSTR(MP_QSTR_PM_AGGRESSIVE), MP_ROM_INT(PM_AGGRESSIVE) }, - { MP_ROM_QSTR(MP_QSTR_PM_PERFORMANCE), MP_ROM_INT(PM_PERFORMANCE) }, - { MP_ROM_QSTR(MP_QSTR_PM_DISABLED), MP_ROM_INT(PM_DISABLED) }, + { MP_ROM_QSTR(MP_QSTR_PM_STANDARD), MP_ROM_INT(CONST_CYW43_DEFAULT_PM) }, + { MP_ROM_QSTR(MP_QSTR_PM_AGGRESSIVE), MP_ROM_INT(CONST_CYW43_AGGRESSIVE_PM) }, + { MP_ROM_QSTR(MP_QSTR_PM_PERFORMANCE), MP_ROM_INT(CONST_CYW43_PERFORMANCE_PM) }, + { MP_ROM_QSTR(MP_QSTR_PM_DISABLED), MP_ROM_INT(CONST_CYW43_NONE_PM) }, }; static MP_DEFINE_CONST_DICT(cyw43_module_globals, cyw43_module_globals_table); diff --git a/ports/raspberrypi/bindings/cyw43/__init__.h b/ports/raspberrypi/bindings/cyw43/__init__.h index 51657b075d2..70f9ec294fb 100644 --- a/ports/raspberrypi/bindings/cyw43/__init__.h +++ b/ports/raspberrypi/bindings/cyw43/__init__.h @@ -16,21 +16,25 @@ const mcu_pin_obj_t *validate_obj_is_free_pin_including_cyw43(mp_obj_t obj, qstr const mcu_pin_obj_t *validate_obj_is_free_pin_or_gpio29(mp_obj_t obj, qstr arg_name); const mcu_pin_obj_t *validate_obj_is_pin_including_cyw43(mp_obj_t obj, qstr arg_name); -#define CONSTANT_CYW43_PM_VALUE(pm_mode, pm2_sleep_ret_ms, li_beacon_period, li_dtim_period, li_assoc) \ +// This is equivalent to the code in cyw43.h, except that the values are computed at compile time. +// A `CONST_` prefix has been added to the computation function (expressed as a macro) and the values. + +#define CONST_cyw43_pm_value(pm_mode, pm2_sleep_ret_ms, li_beacon_period, li_dtim_period, li_assoc) \ (li_assoc << 20 | /* listen interval sent to ap */ \ li_dtim_period << 16 | \ li_beacon_period << 12 | \ (pm2_sleep_ret_ms / 10) << 4 | /* cyw43_ll_wifi_pm multiplies this by 10 */ \ pm_mode /* CYW43_PM2_POWERSAVE_MODE etc */) -// CYW43_DEFAULT_PM (except a compile-time constant) -#define PM_STANDARD CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 200, 1, 1, 10) -// CYW43_AGGRESSIVE_PM (except a compile-time constant) -#define PM_AGGRESSIVE CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 2000, 1, 1, 10) -// CYW43_PERFORMANCE_PM (except a compile-time constant) -#define PM_PERFORMANCE CONSTANT_CYW43_PM_VALUE(CYW43_PM2_POWERSAVE_MODE, 20, 1, 1, 1) -// The 0xa11140 magic value -#define PM_DISABLED CONSTANT_CYW43_PM_VALUE(CYW43_NO_POWERSAVE_MODE, 200, 1, 1, 10) +#define CONST_CYW43_DEFAULT_PM (CONST_CYW43_PERFORMANCE_PM) + +#define CONST_CYW43_NONE_PM (CONST_cyw43_pm_value(CYW43_NO_POWERSAVE_MODE, 10, 0, 0, 0)) + +#define CONST_CYW43_AGGRESSIVE_PM (CONST_cyw43_pm_value(CYW43_PM1_POWERSAVE_MODE, 10, 0, 0, 0)) + +#define CONST_CYW43_PERFORMANCE_PM (CONST_cyw43_pm_value(CYW43_PM2_POWERSAVE_MODE, 200, 1, 1, 10)) +extern uint32_t cyw43_get_power_management_value(void); +extern void cyw43_set_power_management_value(uint32_t value); extern void bindings_cyw43_wifi_enforce_pm(void); void cyw43_enter_deep_sleep(void); diff --git a/ports/raspberrypi/bindings/picodvi/Framebuffer.c b/ports/raspberrypi/bindings/picodvi/Framebuffer.c index 7a8ca40f9f6..e80ffea470c 100644 --- a/ports/raspberrypi/bindings/picodvi/Framebuffer.c +++ b/ports/raspberrypi/bindings/picodvi/Framebuffer.c @@ -41,28 +41,40 @@ //| This allocates a very large framebuffer and is most likely to succeed //| the earlier it is attempted. //| -//| Each dp and dn pair of pins must be neighboring, such as 19 and 20. -//| They must also be ordered the same way. In other words, dp must be -//| less than dn for all pairs or dp must be greater than dn for all pairs. +//| On RP2040, each dp and dn pair of pins must be neighboring, such as +//| 19 and 20. They must also be ordered the same way. In other words, +//| dp must be less than dn for all pairs or dp must be greater than dn +//| for all pairs. +//| +//| On RP2350, all pins must be an HSTX output but can be in any order. //| //| The framebuffer pixel format varies depending on color_depth: //| //| * 1 - Each bit is a pixel. Either white (1) or black (0). -//| * 2 - Each 2 bits is a pixels. Grayscale between white (0x3) and black (0x0). -//| * 4 - Each nibble is a pixels in RGB format. The fourth bit is ignored. (RP2350 only) -//| * 8 - Each byte is a pixels in RGB332 format. -//| * 16 - Each two bytes are a pixel in RGB565 format. +//| * 2 - Each two bits is a pixel. Grayscale between white (0x3) and black (0x0). +//| * 4 - Each nibble is a pixel in RGB format. The fourth bit is ignored. (RP2350 only) +//| * 8 - Each byte is a pixel in RGB332 format. +//| * 16 - Each two bytes is a pixel in RGB565 format. +//| * 32 - Each four bytes is a pixel in RGB888 format. The top byte is ignored. +//| +//| Output resolution support varies between the RP2040 and RP2350. +//| +//| On RP2040, two output resolutions are currently supported, 640x480 +//| and 800x480. Monochrome framebuffers (color_depth=1 or 2) must be +//| full resolution. Color framebuffers must be half resolution (320x240 +//| or 400x240) and pixels will be duplicated to create the signal. //| -//| Two output resolutions are currently supported, 640x480 and 800x480. -//| Monochrome framebuffers (color_depth=1 or 2) must be full resolution. -//| Color framebuffers must be half resolution (320x240 or 400x240) and -//| pixels will be duplicated to create the signal. +//| On RP2350, output resolution is either 640x480 or 720x400. Monochrome +//| framebuffers (color_depth=1 or 2) must be full resolution. 4-bit +//| color must also be full resolution. 8-bit color can be quarter, half +//| or full resolution. 16-bit color and 32-bit color must be quarter or +//| half resolution due to internal RAM limitations. //| //| A Framebuffer is often used in conjunction with a //| `framebufferio.FramebufferDisplay`. //| -//| :param int width: the width of the target display signal. Only 320, 400, 640 or 800 is currently supported depending on color_depth. -//| :param int height: the height of the target display signal. Only 240 or 480 is currently supported depending on color_depth. +//| :param int width: the width of the source framebuffer. Support varies with chipset. +//| :param int height: the height of the source framebuffer. Support varies with chipset. //| :param ~microcontroller.Pin clk_dp: the positive clock signal pin //| :param ~microcontroller.Pin clk_dn: the negative clock signal pin //| :param ~microcontroller.Pin red_dp: the positive red signal pin @@ -72,8 +84,9 @@ //| :param ~microcontroller.Pin blue_dp: the positive blue signal pin //| :param ~microcontroller.Pin blue_dn: the negative blue signal pin //| :param int color_depth: the color depth of the framebuffer in bits. 1, 2 for grayscale -//| and 8 or 16 for color +//| and 4 (RP2350 only), 8 or 16 for color, 32 for color (RP2350 only) //| """ +//| static mp_obj_t picodvi_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_width, ARG_height, ARG_clk_dp, ARG_clk_dn, ARG_red_dp, ARG_red_dn, ARG_green_dp, @@ -102,7 +115,7 @@ static mp_obj_t picodvi_framebuffer_make_new(const mp_obj_type_t *type, size_t n mp_uint_t width = (mp_uint_t)mp_arg_validate_int_min(args[ARG_width].u_int, 0, MP_QSTR_width); mp_uint_t height = (mp_uint_t)mp_arg_validate_int_min(args[ARG_height].u_int, 0, MP_QSTR_height); mp_uint_t color_depth = args[ARG_color_depth].u_int; - if (color_depth != 1 && color_depth != 2 && color_depth != 4 && color_depth != 8 && color_depth != 16) { + if (color_depth != 1 && color_depth != 2 && color_depth != 4 && color_depth != 8 && color_depth != 16 && color_depth != 32) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth); } common_hal_picodvi_framebuffer_construct(self, @@ -125,6 +138,7 @@ static mp_obj_t picodvi_framebuffer_make_new(const mp_obj_type_t *type, size_t n //| `picodvi.Framebuffer` instance. After deinitialization, no further operations //| may be performed.""" //| ... +//| static mp_obj_t picodvi_framebuffer_deinit(mp_obj_t self_in) { picodvi_framebuffer_obj_t *self = (picodvi_framebuffer_obj_t *)self_in; common_hal_picodvi_framebuffer_deinit(self); @@ -153,6 +167,7 @@ MP_PROPERTY_GETTER(picodvi_framebuffer_width_obj, //| height: int //| """The width of the framebuffer, in pixels. It may be doubled for output.""" //| +//| static mp_obj_t picodvi_framebuffer_get_height(mp_obj_t self_in) { picodvi_framebuffer_obj_t *self = (picodvi_framebuffer_obj_t *)self_in; check_for_deinit(self); @@ -163,11 +178,42 @@ MP_DEFINE_CONST_FUN_OBJ_1(picodvi_framebuffer_get_height_obj, picodvi_framebuffe MP_PROPERTY_GETTER(picodvi_framebuffer_height_obj, (mp_obj_t)&picodvi_framebuffer_get_height_obj); +//| color_depth: int +//| """The color depth of the framebuffer.""" +static mp_obj_t picodvi_framebuffer_get_color_depth(mp_obj_t self_in) { + picodvi_framebuffer_obj_t *self = (picodvi_framebuffer_obj_t *)self_in; + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_picodvi_framebuffer_get_color_depth(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(picodvi_framebuffer_get_color_depth_obj, picodvi_framebuffer_get_color_depth); +MP_PROPERTY_GETTER(picodvi_framebuffer_color_depth_obj, + (mp_obj_t)&picodvi_framebuffer_get_color_depth_obj); + +//| def wait_for_vblank(self) -> None: +//| """Block until the next frame boundary (vertical blank), then return. Call this right +//| before a full-framebuffer repaint so the repaint starts at the top of scanout and races +//| ahead of the beam, avoiding tearing without a second framebuffer. The repaint must +//| complete faster than one scanout sweep (~16 ms at 60 Hz) to stay ahead of the beam; +//| if it cannot (e.g. a full 640x480 ``displayio`` refresh), use a lower resolution or +//| repaint a smaller area. Bounded by a short timeout, so it is safe even if no DVI +//| signal is active. No-op on the RP2040 PIO-DVI path.""" +//| ... +static mp_obj_t picodvi_framebuffer_wait_for_vblank(mp_obj_t self_in) { + picodvi_framebuffer_obj_t *self = (picodvi_framebuffer_obj_t *)self_in; + check_for_deinit(self); + common_hal_picodvi_framebuffer_wait_for_vblank(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(picodvi_framebuffer_wait_for_vblank_obj, picodvi_framebuffer_wait_for_vblank); + + static const mp_rom_map_elem_t picodvi_framebuffer_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&picodvi_framebuffer_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_wait_for_vblank), MP_ROM_PTR(&picodvi_framebuffer_wait_for_vblank_obj) }, { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&picodvi_framebuffer_width_obj) }, { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&picodvi_framebuffer_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_color_depth), MP_ROM_PTR(&picodvi_framebuffer_color_depth_obj) }, }; static MP_DEFINE_CONST_DICT(picodvi_framebuffer_locals_dict, picodvi_framebuffer_locals_dict_table); @@ -207,7 +253,7 @@ static int picodvi_framebuffer_get_bytes_per_cell_proto(mp_obj_t self_in) { } static int picodvi_framebuffer_get_native_frames_per_second_proto(mp_obj_t self_in) { - return 60; + return common_hal_picodvi_framebuffer_get_native_frames_per_second(self_in); } static bool picodvi_framebuffer_get_pixels_in_byte_share_row_proto(mp_obj_t self_in) { diff --git a/ports/raspberrypi/bindings/picodvi/Framebuffer.h b/ports/raspberrypi/bindings/picodvi/Framebuffer.h index 7cb335e91e7..d5f59fe84c3 100644 --- a/ports/raspberrypi/bindings/picodvi/Framebuffer.h +++ b/ports/raspberrypi/bindings/picodvi/Framebuffer.h @@ -12,6 +12,9 @@ extern const mp_obj_type_t picodvi_framebuffer_type; +bool common_hal_picodvi_framebuffer_preflight( + mp_uint_t width, mp_uint_t height, + mp_uint_t color_depth); void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, mp_uint_t width, mp_uint_t height, const mcu_pin_obj_t *clk_dp, const mcu_pin_obj_t *clk_dn, @@ -22,9 +25,11 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, void common_hal_picodvi_framebuffer_deinit(picodvi_framebuffer_obj_t *self); bool common_hal_picodvi_framebuffer_deinited(picodvi_framebuffer_obj_t *self); void common_hal_picodvi_framebuffer_refresh(picodvi_framebuffer_obj_t *self); +void common_hal_picodvi_framebuffer_wait_for_vblank(picodvi_framebuffer_obj_t *self); int common_hal_picodvi_framebuffer_get_width(picodvi_framebuffer_obj_t *self); int common_hal_picodvi_framebuffer_get_height(picodvi_framebuffer_obj_t *self); int common_hal_picodvi_framebuffer_get_row_stride(picodvi_framebuffer_obj_t *self); int common_hal_picodvi_framebuffer_get_color_depth(picodvi_framebuffer_obj_t *self); +int common_hal_picodvi_framebuffer_get_native_frames_per_second(picodvi_framebuffer_obj_t *self); bool common_hal_picodvi_framebuffer_get_grayscale(picodvi_framebuffer_obj_t *self); mp_int_t common_hal_picodvi_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags); diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.c b/ports/raspberrypi/bindings/rp2pio/StateMachine.c index 806674ee4c3..398685be8a0 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.c +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.c @@ -24,9 +24,14 @@ //| import memorymap //| //| FifoType = Literal["auto", "txrx", "tx", "rx", "txput", "txget", "putget"] +//| """A type representing one of the strings ``"auto"``, ``"txrx"``, ``"tx"``, ``"rx"``, ``"txput"``, ``"txget"`` or ``"putget"``. These values are supported on RP2350. For type-checking only, not actually defined in CircuitPython.""" //| FifoType_piov0 = Literal["auto", "txrx", "tx", "rx"] +//| """A type representing one of the strings ``"auto"``, ``"txrx"``, ``"tx"``, or ``"rx"``. These values are supported on both RP2350 and RP2040. For type-checking only, not actually defined in CircuitPython.""" //| MovStatusType = Literal["txfifo", "rxfifo", "irq"] -//| MovStatusType_piov0 = Literal["txfifo"] +//| """A type representing one of the strings ``"txfifo"``, ``"rxfifo"``, or ``"irq"``. These values are supported on RP2350. For type-checking only, not actually defined in CircuitPython.""" +//| MovStatusType_piov0 = Literal["txfifo", "rxfifo"] +//| """A type representing one of the strings ``"txfifo"``, ``"rxfifo"``. These values are supported on RP2350 and RP2040. For type-checking only, not actually defined in CircuitPython.""" +//| //| //| class StateMachine: //| """A single PIO StateMachine @@ -64,6 +69,7 @@ //| initial_set_pin_direction: int = 0x1F, //| first_sideset_pin: Optional[microcontroller.Pin] = None, //| sideset_pin_count: int = 1, +//| sideset_pindirs: bool = False, //| initial_sideset_pin_state: int = 0, //| initial_sideset_pin_direction: int = 0x1F, //| sideset_enable: bool = False, @@ -133,6 +139,7 @@ //| :param int in_pin_count: the count of consecutive pins to use with IN starting at first_in_pin //| :param int set_pin_count: the count of consecutive pins to use with SET starting at first_set_pin //| :param int sideset_pin_count: the count of consecutive pins to use with a side set starting at first_sideset_pin. Does not include sideset enable +//| :param bool sideset_pindirs: `True` to indicate that the side set values should be applied to the PINDIRs and not the PINs //| :param int pio_version: The version of the PIO peripheral required by the program. The constructor will raise an error if the actual hardware is not compatible with this program version. //| :param bool auto_push: When True, automatically save data from input shift register //| (ISR) into the rx FIFO when an IN instruction shifts more than push_threshold bits @@ -150,11 +157,12 @@ //| :param int wrap: The instruction after which to wrap to the ``wrap`` //| instruction. As a special case, -1 (the default) indicates the //| last instruction of the program. -//| :param FifoType fifo_type: How the program accessess the FIFOs. PIO version 0 only supports a subset of values. -//| :param MovStatusType mov_status_type: What condition the ``mov status`` instruction checks. PIO version 0 only supports a subset of values. +//| :param FifoType fifo_type: How the program accessess the FIFOs. PIO version 0 in the RP2040 only supports a subset of values, `FifoType_piov0`. +//| :param MovStatusType mov_status_type: What condition the ``mov status`` instruction checks. PIO version 0 in the RP2040 only supports a subset of values, `MovStatusType_piov0`. //| :param MovStatusType mov_status_n: The FIFO depth or IRQ the ``mov status`` instruction checks for. For ``mov_status irq`` this includes the encoding of the ``next``/``prev`` selection bits. //| """ //| ... +//| static int one_of(qstr_short_t what, mp_obj_t arg, size_t n_options, const qstr_short_t options[], const int values[]) { for (size_t i = 0; i < n_options; i++) { @@ -173,7 +181,8 @@ static mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n ARG_first_in_pin, ARG_in_pin_count, ARG_pull_in_pin_up, ARG_pull_in_pin_down, ARG_first_set_pin, ARG_set_pin_count, ARG_initial_set_pin_state, ARG_initial_set_pin_direction, - ARG_first_sideset_pin, ARG_sideset_pin_count, ARG_initial_sideset_pin_state, ARG_initial_sideset_pin_direction, + ARG_first_sideset_pin, ARG_sideset_pin_count, ARG_sideset_pindirs, + ARG_initial_sideset_pin_state, ARG_initial_sideset_pin_direction, ARG_sideset_enable, ARG_jmp_pin, ARG_jmp_pin_pull, ARG_exclusive_pin_use, @@ -211,6 +220,7 @@ static mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n { MP_QSTR_first_sideset_pin, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_sideset_pin_count, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_sideset_pindirs, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_initial_sideset_pin_state, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, { MP_QSTR_initial_sideset_pin_direction, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0x1f} }, @@ -326,13 +336,14 @@ static mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n args[ARG_frequency].u_int, init_bufinfo.buf, init_bufinfo.len / 2, may_exec_bufinfo.buf, may_exec_bufinfo.len / 2, - first_out_pin, out_pin_count, args[ARG_initial_out_pin_state].u_int, args[ARG_initial_out_pin_direction].u_int, - first_in_pin, in_pin_count, args[ARG_pull_in_pin_up].u_int, args[ARG_pull_in_pin_down].u_int, - first_set_pin, set_pin_count, args[ARG_initial_set_pin_state].u_int, args[ARG_initial_set_pin_direction].u_int, - first_sideset_pin, sideset_pin_count, args[ARG_initial_sideset_pin_state].u_int, args[ARG_initial_sideset_pin_direction].u_int, + first_out_pin, out_pin_count, PIO_PINMASK32_FROM_VALUE(args[ARG_initial_out_pin_state].u_int), PIO_PINMASK32_FROM_VALUE(args[ARG_initial_out_pin_direction].u_int), + first_in_pin, in_pin_count, PIO_PINMASK32_FROM_VALUE(args[ARG_pull_in_pin_up].u_int), PIO_PINMASK32_FROM_VALUE(args[ARG_pull_in_pin_down].u_int), + first_set_pin, set_pin_count, PIO_PINMASK32_FROM_VALUE(args[ARG_initial_set_pin_state].u_int), PIO_PINMASK32_FROM_VALUE(args[ARG_initial_set_pin_direction].u_int), + first_sideset_pin, sideset_pin_count, args[ARG_sideset_pindirs].u_bool, + PIO_PINMASK32_FROM_VALUE(args[ARG_initial_sideset_pin_state].u_int), PIO_PINMASK32_FROM_VALUE(args[ARG_initial_sideset_pin_direction].u_int), args[ARG_sideset_enable].u_bool, jmp_pin, jmp_pin_pull, - 0, + PIO_PINMASK_FROM_VALUE(0), // wait_gpio_mask args[ARG_exclusive_pin_use].u_bool, args[ARG_auto_pull].u_bool, pull_threshold, args[ARG_out_shift_right].u_bool, args[ARG_wait_for_txstall].u_bool, @@ -348,6 +359,7 @@ static mp_obj_t rp2pio_statemachine_make_new(const mp_obj_type_t *type, size_t n //| def deinit(self) -> None: //| """Turn off the state machine and release its resources.""" //| ... +//| static mp_obj_t rp2pio_statemachine_obj_deinit(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rp2pio_statemachine_deinit(self); @@ -359,17 +371,13 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_deinit_obj, rp2pio_statemachine_ob //| """No-op used by Context Managers. //| Provided by context manager helper.""" //| ... +//| //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t rp2pio_statemachine_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_rp2pio_statemachine_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rp2pio_statemachine_obj___exit___obj, 4, 4, rp2pio_statemachine_obj___exit__); +//| static void check_for_deinit(rp2pio_statemachine_obj_t *self) { @@ -381,6 +389,7 @@ static void check_for_deinit(rp2pio_statemachine_obj_t *self) { //| def restart(self) -> None: //| """Resets this state machine, runs any init and enables the clock.""" //| ... +//| // TODO: "and any others given. They must share an underlying PIO. An exception will be raised otherwise."" static mp_obj_t rp2pio_statemachine_restart(mp_obj_t self_obj) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_obj); @@ -399,6 +408,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_restart_obj, rp2pio_statemachine_r //| This can be used to output internal state to the RX FIFO and then //| read with `readinto`.""" //| ... +//| static mp_obj_t rp2pio_statemachine_run(mp_obj_t self_obj, mp_obj_t instruction_obj) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); @@ -417,6 +427,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(rp2pio_statemachine_run_obj, rp2pio_statemachine_run); //| def stop(self) -> None: //| """Stops the state machine clock. Use `restart` to enable it.""" //| ... +//| static mp_obj_t rp2pio_statemachine_stop(mp_obj_t self_obj) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); @@ -448,6 +459,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_obj, rp2pio_statemachine_stop //| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` //| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order""" //| ... +//| static mp_obj_t rp2pio_statemachine_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_swap }; static const mp_arg_t allowed_args[] = { @@ -496,6 +508,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine //| once: Optional[ReadableBuffer] = None, //| *, //| loop: Optional[ReadableBuffer] = None, +//| loop2: Optional[ReadableBuffer] = None, //| swap: bool = False, //| ) -> None: //| """Write data to the TX fifo in the background, with optional looping. @@ -504,7 +517,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine //| This means that any ``once`` or ``loop`` buffer will be written at least once. //| Then the ``once`` and/or ``loop`` buffers are queued. and the function returns. //| The ``once`` buffer (if specified) will be written just once. -//| Finally, the ``loop`` buffer (if specified) will continue being looped indefinitely. +//| Finally, the ``loop`` and/or ``loop2`` buffer (if specified) will continue being looped indefinitely. If both ``loop`` and ``loop2`` are specified, they will alternate. //| //| Writes to the FIFO will match the input buffer's element size. For example, bytearray elements //| will perform 8 bit writes to the PIO FIFO. The RP2040's memory bus will duplicate the value into @@ -531,14 +544,16 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_obj, 2, rp2pio_statemachine //| //| :param ~Optional[circuitpython_typing.ReadableBuffer] once: Data to be written once //| :param ~Optional[circuitpython_typing.ReadableBuffer] loop: Data to be written repeatedly +//| :param ~Optional[circuitpython_typing.ReadableBuffer] loop2: Data to be written repeatedly //| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order //| """ //| ... +//| -static void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_bytes) { +static void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_bytes, mp_uint_t direction) { if (obj != mp_const_none) { info->obj = obj; - mp_get_buffer_raise(obj, &info->info, MP_BUFFER_READ); + mp_get_buffer_raise(obj, &info->info, direction); size_t stride = mp_binary_get_size('@', info->info.typecode, NULL); if (stride > 4) { mp_raise_ValueError(MP_ERROR_TEXT("Buffer elements must be 4 bytes long or less")); @@ -553,27 +568,29 @@ static void fill_buf_info(sm_buf_info *info, mp_obj_t obj, size_t *stride_in_byt } static mp_obj_t rp2pio_statemachine_background_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_once, ARG_loop, ARG_swap }; + enum { ARG_once, ARG_loop, ARG_loop2, ARG_swap }; static const mp_arg_t allowed_args[] = { { MP_QSTR_once, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_loop, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, - { MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_loop2, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - sm_buf_info once_info; - sm_buf_info loop_info; size_t stride_in_bytes = 0; - fill_buf_info(&once_info, args[ARG_once].u_obj, &stride_in_bytes); - fill_buf_info(&loop_info, args[ARG_loop].u_obj, &stride_in_bytes); + + fill_buf_info(&self->once_write_buf_info, args[ARG_once].u_obj, &stride_in_bytes, MP_BUFFER_READ); + fill_buf_info(&self->loop_write_buf_info, args[ARG_loop].u_obj, &stride_in_bytes, MP_BUFFER_READ); + fill_buf_info(&self->loop2_write_buf_info, args[ARG_loop2].u_obj, &stride_in_bytes, MP_BUFFER_READ); + if (!stride_in_bytes) { return mp_const_none; } - bool ok = common_hal_rp2pio_statemachine_background_write(self, &once_info, &loop_info, stride_in_bytes, args[ARG_swap].u_bool); + bool ok = common_hal_rp2pio_statemachine_background_write(self, stride_in_bytes, args[ARG_swap].u_bool); if (mp_hal_is_interrupted()) { return mp_const_none; @@ -589,6 +606,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_background_write_obj, 1, rp2pio_s //| """Immediately stop a background write, if one is in progress. Any //| DMA in progress is halted, but items already in the TX FIFO are not //| affected.""" +//| static mp_obj_t rp2pio_statemachine_obj_stop_background_write(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); bool ok = common_hal_rp2pio_statemachine_stop_background_write(self); @@ -602,6 +620,7 @@ static mp_obj_t rp2pio_statemachine_obj_stop_background_write(mp_obj_t self_in) } MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_background_write_obj, rp2pio_statemachine_obj_stop_background_write); + //| writing: bool //| """Returns True if a background write is in progress""" static mp_obj_t rp2pio_statemachine_obj_get_writing(mp_obj_t self_in) { @@ -610,30 +629,154 @@ static mp_obj_t rp2pio_statemachine_obj_get_writing(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_writing_obj, rp2pio_statemachine_obj_get_writing); -const mp_obj_property_t rp2pio_statemachine_writing_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&rp2pio_statemachine_get_writing_obj, - MP_ROM_NONE, - MP_ROM_NONE}, -}; - +MP_PROPERTY_GETTER(rp2pio_statemachine_writing_obj, + (mp_obj_t)&rp2pio_statemachine_get_writing_obj); +//| pending_write: int //| pending: int //| """Returns the number of pending buffers for background writing. //| -//| If the number is 0, then a `StateMachine.background_write` call will not block.""" -static mp_obj_t rp2pio_statemachine_obj_get_pending(mp_obj_t self_in) { +//| If the number is 0, then a `StateMachine.background_write` call will not block. +//| Note that `pending` is a deprecated alias for `pending_write` and will be removed +//| in a future version of CircuitPython.""" +//| + + +static mp_obj_t rp2pio_statemachine_obj_get_pending_write(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending(self)); + return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending_write(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_obj, rp2pio_statemachine_obj_get_pending); +MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_write_obj, rp2pio_statemachine_obj_get_pending_write); -const mp_obj_property_t rp2pio_statemachine_pending_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&rp2pio_statemachine_get_pending_obj, - MP_ROM_NONE, - MP_ROM_NONE}, -}; +MP_PROPERTY_GETTER(rp2pio_statemachine_pending_obj, + (mp_obj_t)&rp2pio_statemachine_get_pending_write_obj); + +MP_PROPERTY_GETTER(rp2pio_statemachine_pending_write_obj, + (mp_obj_t)&rp2pio_statemachine_get_pending_write_obj); + + +// ================================================================================================================================= + +//| def background_read( +//| self, +//| once: Optional[WriteableBuffer] = None, +//| *, +//| loop: Optional[WriteableBuffer] = None, +//| loop2: Optional[WriteableBuffer] = None, +//| swap: bool = False, +//| ) -> None: +//| """Read data from the RX fifo in the background, with optional looping. +//| +//| First, if any previous ``once`` or ``loop`` buffer has not been started, this function blocks until they have been started. +//| This means that any ``once`` or ``loop`` buffer will be read at least once. +//| Then the ``once`` and/or ``loop`` buffers are queued. and the function returns. +//| The ``once`` buffer (if specified) will be read just once. +//| Finally, the ``loop`` and/or ``loop2`` buffer (if specified) will continue being read indefinitely. If both ``loop`` and ``loop2`` are specified, they will alternate. +//| +//| Reads from the FIFO will match the input buffer's element size. For example, bytearray elements +//| will perform 8 bit reads from the PIO FIFO. The RP2040's memory bus will duplicate the value into +//| the other byte positions. So, pulling more data in the PIO assembly will read the duplicated values. +//| +//| To perform 16 or 32 bits reads from the FIFO use an `array.array` with a type code of the desired +//| size, or use `memoryview.cast` to change the interpretation of an +//| existing buffer. To receive just part of a larger buffer, slice a `memoryview` +//| of it. +//| +//| Most use cases will probably only use one of ``once`` or ``loop``. +//| +//| Having neither ``once`` nor ``loop`` terminates an existing +//| background looping read after exactly a whole loop. This is in contrast to +//| `stop_background_read`, which interrupts an ongoing DMA operation. +//| +//| :param ~Optional[circuitpython_typing.WriteableBuffer] once: Data to be read once +//| :param ~Optional[circuitpython_typing.WriteableBuffer] loop: Data to be read repeatedly +//| :param ~Optional[circuitpython_typing.WriteableBuffer] loop2: Data to be read repeatedly +//| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order +//| """ +//| ... +//| + + +static mp_obj_t rp2pio_statemachine_background_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_once, ARG_loop, ARG_loop2, ARG_swap }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_once, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_loop, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_loop2, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_swap, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + size_t stride_in_bytes = 0; + + fill_buf_info(&self->once_read_buf_info, args[ARG_once].u_obj, &stride_in_bytes, MP_BUFFER_WRITE); + fill_buf_info(&self->loop_read_buf_info, args[ARG_loop].u_obj, &stride_in_bytes, MP_BUFFER_WRITE); + fill_buf_info(&self->loop2_read_buf_info, args[ARG_loop2].u_obj, &stride_in_bytes, MP_BUFFER_WRITE); + + if (!stride_in_bytes) { + return mp_const_none; + } + + bool ok = common_hal_rp2pio_statemachine_background_read(self, stride_in_bytes, args[ARG_swap].u_bool); + + if (mp_hal_is_interrupted()) { + return mp_const_none; + } + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_background_read_obj, 1, rp2pio_statemachine_background_read); + +//| def stop_background_read(self) -> None: +//| """Immediately stop a background read, if one is in progress. Any +//| DMA in progress is halted, but items already in the RX FIFO are not +//| affected.""" +//| +static mp_obj_t rp2pio_statemachine_obj_stop_background_read(mp_obj_t self_in) { + rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); + bool ok = common_hal_rp2pio_statemachine_stop_background_read(self); + if (mp_hal_is_interrupted()) { + return mp_const_none; + } + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_stop_background_read_obj, rp2pio_statemachine_obj_stop_background_read); + +//| reading: bool +//| """Returns True if a background read is in progress""" +static mp_obj_t rp2pio_statemachine_obj_get_reading(mp_obj_t self_in) { + rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_rp2pio_statemachine_get_reading(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_reading_obj, rp2pio_statemachine_obj_get_reading); + +MP_PROPERTY_GETTER(rp2pio_statemachine_reading_obj, + (mp_obj_t)&rp2pio_statemachine_get_reading_obj); + +//| pending_read: int +//| """Returns the number of pending buffers for background reading. +//| +//| If the number is 0, then a `StateMachine.background_read` call will not block.""" +//| +static mp_obj_t rp2pio_statemachine_obj_get_pending_read(mp_obj_t self_in) { + rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_int(common_hal_rp2pio_statemachine_get_pending_read(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_pending_read_obj, rp2pio_statemachine_obj_get_pending_read); + +MP_PROPERTY_GETTER(rp2pio_statemachine_pending_read_obj, + (mp_obj_t)&rp2pio_statemachine_get_pending_read_obj); + + +// ================================================================================================================================= //| def readinto( //| self, @@ -659,6 +802,7 @@ const mp_obj_property_t rp2pio_statemachine_pending_obj = { //| :param int end: End of the slice; this index is not included. Defaults to ``len(buffer)`` //| :param bool swap: For 2- and 4-byte elements, swap (reverse) the byte order""" //| ... +//| static mp_obj_t rp2pio_statemachine_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_swap }; @@ -729,6 +873,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_readinto_obj, 2, rp2pio_statemach //| :param bool swap_in: For 2- and 4-rx elements, swap (reverse) the byte order for the buffer being received (read) //| """ //| ... +//| static mp_obj_t rp2pio_statemachine_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer_out, ARG_buffer_in, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end, ARG_swap_out, ARG_swap_in }; @@ -794,6 +939,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(rp2pio_statemachine_write_readinto_obj, 2, rp2pio_sta //| def clear_rxfifo(self) -> None: //| """Clears any unread bytes in the rxfifo.""" //| ... +//| static mp_obj_t rp2pio_statemachine_obj_clear_rxfifo(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rp2pio_statemachine_clear_rxfifo(self); @@ -804,6 +950,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_clear_rxfifo_obj, rp2pio_statemach //| def clear_txstall(self) -> None: //| """Clears the txstall flag.""" //| ... +//| static mp_obj_t rp2pio_statemachine_obj_clear_txstall(mp_obj_t self_in) { rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rp2pio_statemachine_clear_txstall(self); @@ -847,13 +994,8 @@ static mp_obj_t rp2pio_statemachine_obj_get_txstall(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_txstall_obj, rp2pio_statemachine_obj_get_txstall); -const mp_obj_property_t rp2pio_statemachine_txstall_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&rp2pio_statemachine_get_txstall_obj, - MP_ROM_NONE, - MP_ROM_NONE}, -}; - +MP_PROPERTY_GETTER(rp2pio_statemachine_txstall_obj, + (mp_obj_t)&rp2pio_statemachine_get_txstall_obj); //| rxstall: bool //| """True when the state machine has stalled due to a full RX FIFO since the last @@ -938,10 +1080,47 @@ MP_PROPERTY_GETTER(rp2pio_statemachine_rxfifo_obj, (mp_obj_t)&rp2pio_statemachine_get_rxfifo_obj); +//| last_read: array.array +//| """Returns the buffer most recently filled by background reads. +//| +//| This property is self-clearing -- once read, subsequent reads +//| will return a zero-length buffer until the background read buffer +//| changes or restarts. +//| """ +static mp_obj_t rp2pio_statemachine_obj_get_last_read(mp_obj_t self_in) { + rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_rp2pio_statemachine_get_last_read(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_last_read_obj, rp2pio_statemachine_obj_get_last_read); + +MP_PROPERTY_GETTER(rp2pio_statemachine_last_read_obj, + (mp_obj_t)&rp2pio_statemachine_get_last_read_obj); + + +//| last_write: array.array +//| """Returns the buffer most recently emptied by background writes. +//| +//| This property is self-clearing -- once read, subsequent reads +//| will return a zero-length buffer until the background write buffer +//| changes or restarts. +//| """ +//| +//| +static mp_obj_t rp2pio_statemachine_obj_get_last_write(mp_obj_t self_in) { + rp2pio_statemachine_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_rp2pio_statemachine_get_last_write(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(rp2pio_statemachine_get_last_write_obj, rp2pio_statemachine_obj_get_last_write); + +MP_PROPERTY_GETTER(rp2pio_statemachine_last_write_obj, + (mp_obj_t)&rp2pio_statemachine_get_last_write_obj); + static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rp2pio_statemachine_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&rp2pio_statemachine_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&rp2pio_statemachine_stop_obj) }, { MP_ROM_QSTR(MP_QSTR_restart), MP_ROM_PTR(&rp2pio_statemachine_restart_obj) }, @@ -952,10 +1131,17 @@ static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&rp2pio_statemachine_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&rp2pio_statemachine_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&rp2pio_statemachine_write_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_background_write), MP_ROM_PTR(&rp2pio_statemachine_background_write_obj) }, { MP_ROM_QSTR(MP_QSTR_stop_background_write), MP_ROM_PTR(&rp2pio_statemachine_stop_background_write_obj) }, { MP_ROM_QSTR(MP_QSTR_writing), MP_ROM_PTR(&rp2pio_statemachine_writing_obj) }, - { MP_ROM_QSTR(MP_QSTR_pending), MP_ROM_PTR(&rp2pio_statemachine_pending_obj) }, + { MP_ROM_QSTR(MP_QSTR_pending), MP_ROM_PTR(&rp2pio_statemachine_pending_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_pending_write), MP_ROM_PTR(&rp2pio_statemachine_pending_write_obj) }, + + { MP_ROM_QSTR(MP_QSTR_background_read), MP_ROM_PTR(&rp2pio_statemachine_background_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop_background_read), MP_ROM_PTR(&rp2pio_statemachine_stop_background_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_reading), MP_ROM_PTR(&rp2pio_statemachine_reading_obj) }, + { MP_ROM_QSTR(MP_QSTR_pending_read), MP_ROM_PTR(&rp2pio_statemachine_pending_read_obj) }, { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&rp2pio_statemachine_frequency_obj) }, { MP_ROM_QSTR(MP_QSTR_rxstall), MP_ROM_PTR(&rp2pio_statemachine_rxstall_obj) }, @@ -966,6 +1152,10 @@ static const mp_rom_map_elem_t rp2pio_statemachine_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_pc), MP_ROM_PTR(&rp2pio_statemachine_pc_obj) }, { MP_ROM_QSTR(MP_QSTR_rxfifo), MP_ROM_PTR(&rp2pio_statemachine_rxfifo_obj) }, + + { MP_ROM_QSTR(MP_QSTR_last_read), MP_ROM_PTR(&rp2pio_statemachine_last_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_last_write), MP_ROM_PTR(&rp2pio_statemachine_last_write_obj) }, + }; static MP_DEFINE_CONST_DICT(rp2pio_statemachine_locals_dict, rp2pio_statemachine_locals_dict_table); diff --git a/ports/raspberrypi/bindings/rp2pio/StateMachine.h b/ports/raspberrypi/bindings/rp2pio/StateMachine.h index 41cceb30635..3c775a96449 100644 --- a/ports/raspberrypi/bindings/rp2pio/StateMachine.h +++ b/ports/raspberrypi/bindings/rp2pio/StateMachine.h @@ -21,19 +21,20 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, size_t frequency, const uint16_t *init, size_t init_len, const uint16_t *may_exec, size_t may_exec_len, - const mcu_pin_obj_t *first_out_pin, uint8_t out_pin_count, uint32_t initial_out_pin_state, uint32_t initial_out_pin_direction, - const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, uint32_t pull_pin_up, uint32_t pull_pin_down, - const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, uint32_t initial_set_pin_state, uint32_t initial_set_pin_direction, - const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, uint32_t initial_sideset_pin_state, uint32_t initial_sideset_pin_direction, + const mcu_pin_obj_t *first_out_pin, uint8_t out_pin_count, pio_pinmask32_t initial_out_pin_state, pio_pinmask32_t initial_out_pin_direction, + const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, pio_pinmask32_t in_pull_pin_up, pio_pinmask32_t in_pull_pin_down, + const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, pio_pinmask32_t initial_set_pin_state, pio_pinmask32_t initial_set_pin_direction, + const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, bool sideset_pindirs, + pio_pinmask32_t initial_sideset_pin_state, pio_pinmask32_t initial_sideset_pin_direction, bool sideset_enable, const mcu_pin_obj_t *jmp_pin, digitalio_pull_t jmp_pin_pull, - uint32_t wait_gpio_mask, + pio_pinmask_t wait_gpio_mask, bool exclusive_pin_use, bool auto_pull, uint8_t pull_threshold, bool out_shift_right, bool wait_for_txstall, bool auto_push, uint8_t push_threshold, bool in_shift_right, bool user_interruptible, - int wrap_taget, int wrap, + int wrap_target, int wrap, int offset, int fifo_type, int mov_status_type, @@ -41,6 +42,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self); bool common_hal_rp2pio_statemachine_deinited(rp2pio_statemachine_obj_t *self); +void common_hal_rp2pio_statemachine_mark_deinit(rp2pio_statemachine_obj_t *self); void common_hal_rp2pio_statemachine_never_reset(rp2pio_statemachine_obj_t *self); @@ -50,10 +52,34 @@ void common_hal_rp2pio_statemachine_run(rp2pio_statemachine_obj_t *self, const u // Lengths are in bytes. bool common_hal_rp2pio_statemachine_write(rp2pio_statemachine_obj_t *self, const uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap); -bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once_obj, const sm_buf_info *loop_obj, uint8_t stride_in_bytes, bool swap); + +bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, + uint8_t stride_in_bytes, bool swap); + +bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *self, + uint8_t stride_in_bytes, bool swap); + bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_obj_t *self); -mp_int_t common_hal_rp2pio_statemachine_get_pending(rp2pio_statemachine_obj_t *self); +bool common_hal_rp2pio_statemachine_stop_background_read(rp2pio_statemachine_obj_t *self); + +// Set the once / loop / loop2 read buffers from raw pointers without going +// through an mp_obj_t wrapper. Pass NULL/0 for unused slots. The caller owns +// the memory; it must remain valid until stop_background_read. +void common_hal_rp2pio_statemachine_set_read_buffers_raw(rp2pio_statemachine_obj_t *self, + void *once, size_t once_len, + void *loop, size_t loop_len, + void *loop2, size_t loop2_len); + +// Returns the DMA channel index used by the current background read, or -1 +// if no background read is active. +int common_hal_rp2pio_statemachine_get_read_dma_channel(rp2pio_statemachine_obj_t *self); + +mp_int_t common_hal_rp2pio_statemachine_get_pending_write(rp2pio_statemachine_obj_t *self); +mp_int_t common_hal_rp2pio_statemachine_get_pending_read(rp2pio_statemachine_obj_t *self); + bool common_hal_rp2pio_statemachine_get_writing(rp2pio_statemachine_obj_t *self); +bool common_hal_rp2pio_statemachine_get_reading(rp2pio_statemachine_obj_t *self); + bool common_hal_rp2pio_statemachine_readinto(rp2pio_statemachine_obj_t *self, uint8_t *data, size_t len, uint8_t stride_in_bytes, bool swap); bool common_hal_rp2pio_statemachine_write_readinto(rp2pio_statemachine_obj_t *self, const uint8_t *data_out, size_t out_len, uint8_t out_stride_in_bytes, @@ -65,6 +91,7 @@ void common_hal_rp2pio_statemachine_set_frequency(rp2pio_statemachine_obj_t *sel bool common_hal_rp2pio_statemachine_get_rxstall(rp2pio_statemachine_obj_t *self); void common_hal_rp2pio_statemachine_clear_rxfifo(rp2pio_statemachine_obj_t *self); + bool common_hal_rp2pio_statemachine_get_txstall(rp2pio_statemachine_obj_t *self); void common_hal_rp2pio_statemachine_clear_txstall(rp2pio_statemachine_obj_t *self); size_t common_hal_rp2pio_statemachine_get_in_waiting(rp2pio_statemachine_obj_t *self); @@ -75,3 +102,6 @@ int common_hal_rp2pio_statemachine_get_pc(rp2pio_statemachine_obj_t *self); void common_hal_rp2pio_statemachine_set_interrupt_handler(rp2pio_statemachine_obj_t *self, void (*handler)(void *), void *arg, int mask); mp_obj_t common_hal_rp2pio_statemachine_get_rxfifo(rp2pio_statemachine_obj_t *self); + +mp_obj_t common_hal_rp2pio_statemachine_get_last_read(rp2pio_statemachine_obj_t *self); +mp_obj_t common_hal_rp2pio_statemachine_get_last_write(rp2pio_statemachine_obj_t *self); diff --git a/ports/raspberrypi/bindings/rp2pio/__init__.c b/ports/raspberrypi/bindings/rp2pio/__init__.c index 6f981de3dcb..e68c376ae80 100644 --- a/ports/raspberrypi/bindings/rp2pio/__init__.c +++ b/ports/raspberrypi/bindings/rp2pio/__init__.c @@ -24,11 +24,13 @@ //| See the warning in `digitalio` for more information. //| """ //| +//| //| def pins_are_sequential(pins: List[microcontroller.Pin]) -> bool: //| """Return True if the pins have sequential GPIO numbers, False otherwise""" //| ... //| +//| static mp_obj_t rp2pio_pins_are_sequential(mp_obj_t pins_obj) { size_t len; mp_obj_t *items; diff --git a/ports/raspberrypi/bindings/wiznet/PIO_SPI.c b/ports/raspberrypi/bindings/wiznet/PIO_SPI.c new file mode 100755 index 00000000000..1f860fc9979 --- /dev/null +++ b/ports/raspberrypi/bindings/wiznet/PIO_SPI.c @@ -0,0 +1,299 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft +// +// SPDX-License-Identifier: MIT + +// TODO: wiznet.PIO_SPI class. +// This file contains all of the Python API definitions for the +// wiznet.PIO_SPI class. + +#include + +#include "shared-bindings/microcontroller/Pin.h" +#include "bindings/wiznet/PIO_SPI.h" +#include "shared-bindings/util.h" + +#include "shared/runtime/buffer_helper.h" +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mperrno.h" +#include "py/objproperty.h" +#include "py/runtime.h" + + +// TODO: class WIZNET_PIO_SPI + + +static mp_obj_t wiznet_pio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + #if CIRCUITPY_WIZNET + wiznet_pio_spi_obj_t *self = mp_obj_malloc(wiznet_pio_spi_obj_t, &wiznet_pio_spi_type); + enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_half_duplex, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj, MP_QSTR_mosi); + const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj, MP_QSTR_miso); + + if (!miso && !mosi) { + mp_raise_ValueError(MP_ERROR_TEXT("Must provide MISO or MOSI pin")); + } + + common_hal_wiznet_pio_spi_construct(self, clock, mosi, miso, args[ARG_half_duplex].u_bool); + return MP_OBJ_FROM_PTR(self); + #else + mp_raise_NotImplementedError(NULL); + #endif // CIRCUITPY_WIZNET +} + +#if CIRCUITPY_WIZNET + +// TODO: def deinit + +static mp_obj_t wiznet_pio_spi_obj_deinit(mp_obj_t self_in) { + wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_wiznet_pio_spi_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(wiznet_pio_spi_deinit_obj, wiznet_pio_spi_obj_deinit); + +// TODO: def __enter__ + +// TODO: def __exit__ + +static void check_lock(wiznet_pio_spi_obj_t *self) { + asm (""); + if (!common_hal_wiznet_pio_spi_has_lock(self)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Function requires lock")); + } +} + +static void check_for_deinit(wiznet_pio_spi_obj_t *self) { + if (common_hal_wiznet_pio_spi_deinited(self)) { + raise_deinited_error(); + } +} + +// TODO: def configure + +static mp_obj_t wiznet_pio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + }; + wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + uint8_t polarity = (uint8_t)mp_arg_validate_int_range(args[ARG_polarity].u_int, 0, 1, MP_QSTR_polarity); + uint8_t phase = (uint8_t)mp_arg_validate_int_range(args[ARG_phase].u_int, 0, 1, MP_QSTR_phase); + uint8_t bits = (uint8_t)mp_arg_validate_int_range(args[ARG_bits].u_int, 8, 9, MP_QSTR_bits); + + if (!common_hal_wiznet_pio_spi_configure(self, args[ARG_baudrate].u_int, + polarity, phase, bits)) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(wiznet_pio_spi_configure_obj, 1, wiznet_pio_spi_configure); + +// TODO: def try_lock + +static mp_obj_t wiznet_pio_spi_obj_try_lock(mp_obj_t self_in) { + wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_wiznet_pio_spi_try_lock(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(wiznet_pio_spi_try_lock_obj, wiznet_pio_spi_obj_try_lock); + +// TODO: def unlock + +static mp_obj_t wiznet_pio_spi_obj_unlock(mp_obj_t self_in) { + wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_wiznet_pio_spi_unlock(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(wiznet_pio_spi_unlock_obj, wiznet_pio_spi_obj_unlock); + +// TODO: def write + +static mp_obj_t wiznet_pio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_start, ARG_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + + wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + // Compute bounds in terms of elements, not bytes. + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); + int32_t start = args[ARG_start].u_int; + size_t length = bufinfo.len / stride_in_bytes; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + + if (length == 0) { + return mp_const_none; + } + + bool ok = common_hal_wiznet_pio_spi_write(self, ((uint8_t *)bufinfo.buf) + start, length); + + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(wiznet_pio_spi_write_obj, 1, wiznet_pio_spi_write); + +// TODO: def readinto + +static mp_obj_t wiznet_pio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_write_value, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); + // Compute bounds in terms of elements, not bytes. + int stride_in_bytes = mp_binary_get_size('@', bufinfo.typecode, NULL); + int32_t start = args[ARG_start].u_int; + size_t length = bufinfo.len / stride_in_bytes; + normalize_buffer_bounds(&start, args[ARG_end].u_int, &length); + + // Treat start and length in terms of bytes from now on. + start *= stride_in_bytes; + length *= stride_in_bytes; + + if (length == 0) { + return mp_const_none; + } + + bool ok = common_hal_wiznet_pio_spi_read(self, ((uint8_t *)bufinfo.buf) + start, length, args[ARG_write_value].u_int); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(wiznet_pio_spi_readinto_obj, 1, wiznet_pio_spi_readinto); + + +// TODO: def write_readinto + +static mp_obj_t wiznet_pio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_out_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_in_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_out_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_out_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_in_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_in_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + wiznet_pio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t buf_out_info; + mp_get_buffer_raise(args[ARG_out_buffer].u_obj, &buf_out_info, MP_BUFFER_READ); + int out_stride_in_bytes = mp_binary_get_size('@', buf_out_info.typecode, NULL); + int32_t out_start = args[ARG_out_start].u_int; + size_t out_length = buf_out_info.len / out_stride_in_bytes; + normalize_buffer_bounds(&out_start, args[ARG_out_end].u_int, &out_length); + + mp_buffer_info_t buf_in_info; + mp_get_buffer_raise(args[ARG_in_buffer].u_obj, &buf_in_info, MP_BUFFER_WRITE); + int in_stride_in_bytes = mp_binary_get_size('@', buf_in_info.typecode, NULL); + int32_t in_start = args[ARG_in_start].u_int; + size_t in_length = buf_in_info.len / in_stride_in_bytes; + normalize_buffer_bounds(&in_start, args[ARG_in_end].u_int, &in_length); + + // Treat start and length in terms of bytes from now on. + out_start *= out_stride_in_bytes; + out_length *= out_stride_in_bytes; + in_start *= in_stride_in_bytes; + in_length *= in_stride_in_bytes; + + if (out_length != in_length) { + mp_raise_ValueError(MP_ERROR_TEXT("buffer slices must be of equal length")); + } + + if (out_length == 0) { + return mp_const_none; + } + + bool ok = common_hal_wiznet_pio_spi_transfer(self, + ((uint8_t *)buf_out_info.buf) + out_start, + ((uint8_t *)buf_in_info.buf) + in_start, + out_length); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(wiznet_pio_spi_write_readinto_obj, 1, wiznet_pio_spi_write_readinto); + +#endif // CIRCUITPY_WIZNET + +static const mp_rom_map_elem_t wiznet_pio_spi_locals_dict_table[] = { + #if CIRCUITPY_WIZNET + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&wiznet_pio_spi_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + + { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&wiznet_pio_spi_configure_obj) }, + { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&wiznet_pio_spi_try_lock_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&wiznet_pio_spi_unlock_obj) }, + + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&wiznet_pio_spi_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&wiznet_pio_spi_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&wiznet_pio_spi_write_readinto_obj) }, + + #endif // CIRCUITPY_WIZNET +}; +static MP_DEFINE_CONST_DICT(wiznet_pio_spi_locals_dict, wiznet_pio_spi_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + wiznet_pio_spi_type, + MP_QSTR_PIO_SPI, + MP_TYPE_FLAG_NONE, + make_new, wiznet_pio_spi_make_new, + locals_dict, &wiznet_pio_spi_locals_dict + ); + +wiznet_pio_spi_obj_t *validate_obj_is_wiznet_pio_spi_bus(mp_obj_t obj, qstr arg_name) { + return mp_arg_validate_type(obj, &wiznet_pio_spi_type, arg_name); +} diff --git a/ports/raspberrypi/bindings/wiznet/PIO_SPI.h b/ports/raspberrypi/bindings/wiznet/PIO_SPI.h new file mode 100755 index 00000000000..0289ac0767a --- /dev/null +++ b/ports/raspberrypi/bindings/wiznet/PIO_SPI.h @@ -0,0 +1,40 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/wiznet/PIO_SPI.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t wiznet_pio_spi_type; + +// Construct an underlying SPI object. +extern void common_hal_wiznet_pio_spi_construct(wiznet_pio_spi_obj_t *self, + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, bool half_duplex); + +extern void common_hal_wiznet_pio_spi_deinit(wiznet_pio_spi_obj_t *self); +extern bool common_hal_wiznet_pio_spi_deinited(wiznet_pio_spi_obj_t *self); + +extern bool common_hal_wiznet_pio_spi_configure(wiznet_pio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); + +extern bool common_hal_wiznet_pio_spi_try_lock(wiznet_pio_spi_obj_t *self); +extern bool common_hal_wiznet_pio_spi_has_lock(wiznet_pio_spi_obj_t *self); +extern void common_hal_wiznet_pio_spi_unlock(wiznet_pio_spi_obj_t *self); + +// Writes out the given data. +extern bool common_hal_wiznet_pio_spi_write(wiznet_pio_spi_obj_t *self, const uint8_t *data, size_t len); + +// Reads in len bytes while outputting the byte write_value. +extern bool common_hal_wiznet_pio_spi_read(wiznet_pio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value); + +// Reads and write len bytes simultaneously. +extern bool common_hal_wiznet_pio_spi_transfer(wiznet_pio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len); + +extern wiznet_pio_spi_obj_t *validate_obj_is_wiznet_pio_spi_bus(mp_obj_t obj_in, qstr arg_name); diff --git a/ports/raspberrypi/bindings/wiznet/__init__.c b/ports/raspberrypi/bindings/wiznet/__init__.c new file mode 100755 index 00000000000..6ed3c2886cc --- /dev/null +++ b/ports/raspberrypi/bindings/wiznet/__init__.c @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "bindings/wiznet/PIO_SPI.h" + +#include "py/runtime.h" + +static const mp_rom_map_elem_t wiznet_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wiznet) }, + { MP_ROM_QSTR(MP_QSTR_PIO_SPI), MP_ROM_PTR(&wiznet_pio_spi_type) }, +}; + +static MP_DEFINE_CONST_DICT(wiznet_module_globals, wiznet_module_globals_table); + +const mp_obj_module_t wiznet_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&wiznet_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_wiznet, wiznet_module); diff --git a/ports/raspberrypi/bindings/wiznet/__init__.h b/ports/raspberrypi/bindings/wiznet/__init__.h new file mode 100755 index 00000000000..370e233985f --- /dev/null +++ b/ports/raspberrypi/bindings/wiznet/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/ports/raspberrypi/boards/0xcb_gemini/board.c b/ports/raspberrypi/boards/0xcb_gemini/board.c new file mode 100644 index 00000000000..ebb56e8a474 --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_gemini/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Conor Burns for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/0xcb_gemini/mpconfigboard.h b/ports/raspberrypi/boards/0xcb_gemini/mpconfigboard.h new file mode 100644 index 00000000000..7321c6fb5f9 --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_gemini/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Conor Burns for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "0xCB Gemini" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO16) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO7) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO4) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/0xcb_gemini/mpconfigboard.mk b/ports/raspberrypi/boards/0xcb_gemini/mpconfigboard.mk new file mode 100644 index 00000000000..f5ff14edc8d --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_gemini/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x1209 +USB_PID = 0xCB65 +USB_PRODUCT = "Gemini" +USB_MANUFACTURER = "0xCB" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" diff --git a/ports/raspberrypi/boards/0xcb_gemini/pico-sdk-configboard.h b/ports/raspberrypi/boards/0xcb_gemini/pico-sdk-configboard.h new file mode 100644 index 00000000000..cd0307c5a9a --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_gemini/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Conor Burns for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/0xcb_gemini/pins.c b/ports/raspberrypi/boards/0xcb_gemini/pins.c new file mode 100644 index 00000000000..3250a37835e --- /dev/null +++ b/ports/raspberrypi/boards/0xcb_gemini/pins.c @@ -0,0 +1,71 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Conor Burns for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Right side top to bottom + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SDI), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SDO), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + // Bottom side right to left + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + + // Left side bottom to top + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + // Backside bottom to top + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + // VBUS sense voltage divider when jumper connected https://docs.keeb.supply/0xcb-gemini/guide/#split-capability + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/42keebs_frood/pins.c b/ports/raspberrypi/boards/42keebs_frood/pins.c index 45436250518..2e7ac22475b 100644 --- a/ports/raspberrypi/boards/42keebs_frood/pins.c +++ b/ports/raspberrypi/boards/42keebs_frood/pins.c @@ -49,6 +49,9 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO19) }, diff --git a/ports/raspberrypi/boards/8086_rp2040_interfacer/board.c b/ports/raspberrypi/boards/8086_rp2040_interfacer/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/8086_rp2040_interfacer/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/8086_rp2040_interfacer/mpconfigboard.h b/ports/raspberrypi/boards/8086_rp2040_interfacer/mpconfigboard.h new file mode 100644 index 00000000000..860ca65321c --- /dev/null +++ b/ports/raspberrypi/boards/8086_rp2040_interfacer/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "8086 RP2040 Interfacer" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO16) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO27) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO26) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO13) +#define DEFAULT_UART_BUS_TX (&pin_GPIO12) + +// #define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX +// #define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX diff --git a/ports/raspberrypi/boards/8086_rp2040_interfacer/mpconfigboard.mk b/ports/raspberrypi/boards/8086_rp2040_interfacer/mpconfigboard.mk new file mode 100644 index 00000000000..644d7d7520f --- /dev/null +++ b/ports/raspberrypi/boards/8086_rp2040_interfacer/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x3171 +USB_PID = 0x010D +USB_PRODUCT = "RP2040 Interfacer" +USB_MANUFACTURER = "8086 Consultancy" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" diff --git a/ports/raspberrypi/boards/8086_rp2040_interfacer/pico-sdk-configboard.h b/ports/raspberrypi/boards/8086_rp2040_interfacer/pico-sdk-configboard.h new file mode 100644 index 00000000000..ce5a7645b4e --- /dev/null +++ b/ports/raspberrypi/boards/8086_rp2040_interfacer/pico-sdk-configboard.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/8086_rp2040_interfacer/pins.c b/ports/raspberrypi/boards/8086_rp2040_interfacer/pins.c new file mode 100644 index 00000000000..07ff7fbe31a --- /dev/null +++ b/ports/raspberrypi/boards/8086_rp2040_interfacer/pins.c @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_PULL_SDA), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_PULL_SCL), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_LED_UART), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_LED_STQW), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.h index 34360169423..4c500366dfc 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.h +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.h @@ -23,3 +23,11 @@ // #define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX // #define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX + +// Onboard microSD slot on SPI1. +#define DEFAULT_SD_SCK (&pin_GPIO18) +#define DEFAULT_SD_MOSI (&pin_GPIO19) +#define DEFAULT_SD_MISO (&pin_GPIO20) +#define DEFAULT_SD_CS (&pin_GPIO23) +#define DEFAULT_SD_CARD_DETECT (&pin_GPIO16) +#define DEFAULT_SD_CARD_INSERTED true diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.mk index 529853b22f5..cc0880ac544 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.mk +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/mpconfigboard.mk @@ -7,3 +7,5 @@ CHIP_VARIANT = RP2040 CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" + +CIRCUITPY_SDIOIO = 1 diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/pins.c index 78d09407a65..1ab755f0aa1 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/pins.c +++ b/ports/raspberrypi/boards/adafruit_feather_rp2040_adalogger/pins.c @@ -4,8 +4,21 @@ // // SPDX-License-Identifier: MIT +#include "py/objtuple.h" #include "shared-bindings/board/__init__.h" +// Four consecutive data GPIOs for the 4-bit SDIO interface (sdioio.SDCard). +static const mp_rom_obj_tuple_t sdio_data_tuple = { + {&mp_type_tuple}, + 4, + { + MP_ROM_PTR(&pin_GPIO20), + MP_ROM_PTR(&pin_GPIO21), + MP_ROM_PTR(&pin_GPIO22), + MP_ROM_PTR(&pin_GPIO23), + } +}; + static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS @@ -49,18 +62,26 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_CLOCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_SD_DAT0), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_SD_DAT1), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_SD_DAT2), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO22) }, { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO23) }, { MP_ROM_QSTR(MP_QSTR_SD_DAT3), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA), MP_ROM_PTR(&sdio_data_tuple) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2350/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2350/board.c index e6a868ab212..fddd2572c1f 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2350/board.c +++ b/ports/raspberrypi/boards/adafruit_feather_rp2350/board.c @@ -4,6 +4,13 @@ // // SPDX-License-Identifier: MIT +#include "py/obj.h" #include "supervisor/board.h" +#include "common-hal/picodvi/__init__.h" + // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + +void board_init(void) { + picodvi_autoconstruct(); +} diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2350/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2350/mpconfigboard.h index 1e238789a3d..d0c114a97e4 100644 --- a/ports/raspberrypi/boards/adafruit_feather_rp2350/mpconfigboard.h +++ b/ports/raspberrypi/boards/adafruit_feather_rp2350/mpconfigboard.h @@ -20,3 +20,12 @@ #define DEFAULT_UART_BUS_TX (&pin_GPIO0) #define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO8) + +#define DEFAULT_DVI_BUS_CLK_DN (&pin_GPIO15) +#define DEFAULT_DVI_BUS_CLK_DP (&pin_GPIO14) +#define DEFAULT_DVI_BUS_RED_DN (&pin_GPIO19) +#define DEFAULT_DVI_BUS_RED_DP (&pin_GPIO18) +#define DEFAULT_DVI_BUS_GREEN_DN (&pin_GPIO17) +#define DEFAULT_DVI_BUS_GREEN_DP (&pin_GPIO16) +#define DEFAULT_DVI_BUS_BLUE_DN (&pin_GPIO13) +#define DEFAULT_DVI_BUS_BLUE_DP (&pin_GPIO12) diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/board.c b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/mpconfigboard.h new file mode 100644 index 00000000000..b77664cf85c --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/mpconfigboard.h @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Adafruit Feather RP2350 Adalogger" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO21) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO8) + +#define DEFAULT_SD_SCK (&pin_GPIO14) +#define DEFAULT_SD_MOSI (&pin_GPIO15) +#define DEFAULT_SD_MISO (&pin_GPIO16) +#define DEFAULT_SD_CS (&pin_GPIO19) +#define DEFAULT_SD_CARD_DETECT (&pin_GPIO13) +#define DEFAULT_SD_CARD_INSERTED false diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/mpconfigboard.mk new file mode 100644 index 00000000000..6ab89398de7 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x239A +USB_PID = 0x816E +USB_PRODUCT = "Feather RP2350 Adalogger" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/pico-sdk-configboard.h new file mode 100644 index 00000000000..2d9283a9192 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/pico-sdk-configboard.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/pins.c b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/pins.c new file mode 100644 index 00000000000..ac9a29abaad --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_feather_rp2350_adalogger/pins.c @@ -0,0 +1,69 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_IO4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_IO7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO7) }, + + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT0), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_SD_DAT1), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT2), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_SD_DAT3), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c index 0750411dafc..903ed6a9044 100644 --- a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/board.c @@ -34,9 +34,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO25, // TFT_DC Command or data - &pin_GPIO29, // TFT_CS Chip select - NULL, // TFT_RESET Reset + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_DC), + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_CS), + mp_const_none, // TFT_RESET Reset 40000000, // Baudrate 0, // Polarity 0); // Phase @@ -62,7 +62,7 @@ void board_init(void) { MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command display_init_sequence, sizeof(display_init_sequence), - &pin_GPIO28, // backlight pin + CIRCUITPY_BOARD_TFT_BACKLIGHT, NO_BRIGHTNESS_COMMAND, 1.0f, // brightness false, // single_byte_bounds diff --git a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/mpconfigboard.h index 6f41981e248..57c2be2207b 100644 --- a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/mpconfigboard.h @@ -9,10 +9,14 @@ #define MICROPY_HW_BOARD_NAME "Adafruit Floppsy RP2040" #define MICROPY_HW_MCU_NAME "rp2040" -#define MICROPY_HW_NEOPIXEL (&pin_GPIO15) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO22) #define DEFAULT_I2C_BUS_SCL (&pin_GPIO17) #define DEFAULT_I2C_BUS_SDA (&pin_GPIO16) +#define CIRCUITPY_BOARD_TFT_DC (&pin_GPIO23) +#define CIRCUITPY_BOARD_TFT_CS (&pin_GPIO24) +#define CIRCUITPY_BOARD_TFT_BACKLIGHT (&pin_GPIO25) + #define CIRCUITPY_BOARD_SPI (1) -#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO26, .mosi = &pin_GPIO27}} +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = &pin_GPIO20 }} diff --git a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/pins.c b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/pins.c index 800962637e5..cfeb426e31a 100644 --- a/ports/raspberrypi/boards/adafruit_floppsy_rp2040/pins.c +++ b/ports/raspberrypi/boards/adafruit_floppsy_rp2040/pins.c @@ -6,45 +6,57 @@ #include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_OBJ_NEW_QSTR(MP_QSTR_DENSITY), MP_ROM_PTR(&pin_GPIO0) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SELECT), MP_ROM_PTR(&pin_GPIO1) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOTOR), MP_ROM_PTR(&pin_GPIO2) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_DIRECTION), MP_ROM_PTR(&pin_GPIO3) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_STEP), MP_ROM_PTR(&pin_GPIO4) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WRDATA), MP_ROM_PTR(&pin_GPIO5) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WRGATE), MP_ROM_PTR(&pin_GPIO6) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SIDE), MP_ROM_PTR(&pin_GPIO7) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_FLOPPY_DIRECTION), MP_ROM_PTR(&pin_GPIO8) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_INDEX), MP_ROM_PTR(&pin_GPIO9) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_TRACK0), MP_ROM_PTR(&pin_GPIO10) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_WRPROT), MP_ROM_PTR(&pin_GPIO11) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_RDDATA), MP_ROM_PTR(&pin_GPIO12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_READY), MP_ROM_PTR(&pin_GPIO13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PERIPH_RESET), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_DENSITY), MP_ROM_PTR(&pin_GPIO1) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SELECT), MP_ROM_PTR(&pin_GPIO2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOTOR), MP_ROM_PTR(&pin_GPIO3) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_DIRECTION), MP_ROM_PTR(&pin_GPIO4) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_STEP), MP_ROM_PTR(&pin_GPIO5) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WRDATA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WRGATE), MP_ROM_PTR(&pin_GPIO7) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SIDE), MP_ROM_PTR(&pin_GPIO8) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_FLOPPY_DIRECTION), MP_ROM_PTR(&pin_GPIO9) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_INDEX), MP_ROM_PTR(&pin_GPIO10) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TRACK0), MP_ROM_PTR(&pin_GPIO11) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_WRPROT), MP_ROM_PTR(&pin_GPIO12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_RDDATA), MP_ROM_PTR(&pin_GPIO13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_READY), MP_ROM_PTR(&pin_GPIO14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_FLOPPY_ENABLE), MP_ROM_PTR(&pin_GPIO15) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO16) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO17) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_AW9523_SD_CD), MP_ROM_INT(15) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AW9523_BUTTON_LEFT), MP_ROM_INT(0) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AW9523_BUTTON_UP), MP_ROM_INT(1) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AW9523_BUTTON_RIGHT), MP_ROM_INT(2) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AW9523_BUTTON_DOWN), MP_ROM_INT(3) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CD), MP_ROM_PTR(&pin_GPIO24) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO20) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO18) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO21) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO19) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_GPIO19) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_DC) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_CS) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_BACKLIGHT) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO20) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO21) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO22) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO23) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].framebuffer_display)}, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/raspberrypi/boards/adafruit_fruit_jam/board.c b/ports/raspberrypi/boards/adafruit_fruit_jam/board.c new file mode 100644 index 00000000000..a868bc02b71 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_fruit_jam/board.c @@ -0,0 +1,57 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "common-hal/microcontroller/Pin.h" +#include "hardware/gpio.h" +#include "py/mphal.h" +#include "shared-bindings/usb_host/Port.h" +#include "supervisor/board.h" + +#include "common-hal/picodvi/__init__.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + +#define I2S_RESET_PIN_NUMBER 22 + +bool board_reset_pin_number(uint8_t pin_number) { + #if defined(DEFAULT_USB_HOST_5V_POWER) + if (pin_number == DEFAULT_USB_HOST_5V_POWER->number) { + // doing this (rather than gpio_init) in this specific order ensures no + // glitch if pin was already configured as a high output. gpio_init() temporarily + // configures the pin as an input, so the power enable value would potentially + // glitch. + gpio_put(pin_number, 1); + gpio_set_dir(pin_number, GPIO_OUT); + gpio_set_function(pin_number, GPIO_FUNC_SIO); + + return true; + } + #endif + // Set I2S out of reset. + if (pin_number == I2S_RESET_PIN_NUMBER) { + gpio_put(pin_number, 1); + gpio_set_dir(pin_number, GPIO_OUT); + gpio_set_function(pin_number, GPIO_FUNC_SIO); + + return true; + } + return false; +} + +void board_init(void) { + // Reset the DAC to put it in a known state. + gpio_put(I2S_RESET_PIN_NUMBER, 0); + gpio_set_dir(I2S_RESET_PIN_NUMBER, GPIO_OUT); + gpio_set_function(I2S_RESET_PIN_NUMBER, GPIO_FUNC_SIO); + mp_hal_delay_us(1); + board_reset_pin_number(I2S_RESET_PIN_NUMBER); + + #if defined(DEFAULT_USB_HOST_DATA_PLUS) + common_hal_usb_host_port_construct(DEFAULT_USB_HOST_DATA_PLUS, DEFAULT_USB_HOST_DATA_MINUS); + #endif + + picodvi_autoconstruct(); +} diff --git a/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h new file mode 100644 index 00000000000..08c3271552c --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.h @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Adafruit Fruit Jam" +#define MICROPY_HW_MCU_NAME "rp2350b" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO32) +#define MICROPY_HW_NEOPIXEL_COUNT (5) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO30) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO31) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO28) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO9) +#define DEFAULT_UART_BUS_TX (&pin_GPIO8) + +#define DEFAULT_USB_HOST_DATA_PLUS (&pin_GPIO1) +#define DEFAULT_USB_HOST_DATA_MINUS (&pin_GPIO2) +#define DEFAULT_USB_HOST_5V_POWER (&pin_GPIO11) + +#define DEFAULT_DVI_BUS_CLK_DN (&pin_GPIO12) +#define DEFAULT_DVI_BUS_CLK_DP (&pin_GPIO13) +#define DEFAULT_DVI_BUS_RED_DN (&pin_GPIO14) +#define DEFAULT_DVI_BUS_RED_DP (&pin_GPIO15) +#define DEFAULT_DVI_BUS_GREEN_DN (&pin_GPIO16) +#define DEFAULT_DVI_BUS_GREEN_DP (&pin_GPIO17) +#define DEFAULT_DVI_BUS_BLUE_DN (&pin_GPIO18) +#define DEFAULT_DVI_BUS_BLUE_DP (&pin_GPIO19) + +#define DEFAULT_SD_SCK (&pin_GPIO34) +#define DEFAULT_SD_MOSI (&pin_GPIO35) +#define DEFAULT_SD_MISO (&pin_GPIO36) +#define DEFAULT_SD_CS (&pin_GPIO39) +#define DEFAULT_SD_CARD_DETECT (&pin_GPIO33) +#define DEFAULT_SD_CARD_INSERTED true + +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO47) + +// #define CIRCUITPY_CONSOLE_UART_TX (&pin_GPIO44) +// #define CIRCUITPY_CONSOLE_UART_RX (&pin_GPIO45) + +// #define CIRCUITPY_DEBUG_TINYUSB 0 + +#define CIRCUITPY_SAVES_PARTITION_SIZE (2 * 1024 * 1024) diff --git a/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.mk new file mode 100644 index 00000000000..086c823adb4 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_fruit_jam/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x239A +USB_PID = 0x816C +USB_PRODUCT = "Fruit Jam" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = B +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY_SDIOIO = 1 + +# CIRCUITPY_DISPLAY_FONT = $(TOP)/tools/fonts/unifont-16.0.02-all.bdf +# CIRCUITPY_FONT_EXTRA_CHARACTERS = "🖮🖱️" diff --git a/ports/raspberrypi/boards/adafruit_fruit_jam/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_fruit_jam/pico-sdk-configboard.h new file mode 100644 index 00000000000..2d9283a9192 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_fruit_jam/pico-sdk-configboard.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_fruit_jam/pins.c b/ports/raspberrypi/boards/adafruit_fruit_jam/pins.c new file mode 100644 index 00000000000..e6d41ae4989 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_fruit_jam/pins.c @@ -0,0 +1,121 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" + +// Four consecutive data GPIOs for the 4-bit SDIO interface (sdioio.SDCard). +static const mp_rom_obj_tuple_t sdio_data_tuple = { + {&mp_type_tuple}, + 4, + { + MP_ROM_PTR(&pin_GPIO36), + MP_ROM_PTR(&pin_GPIO37), + MP_ROM_PTR(&pin_GPIO38), + MP_ROM_PTR(&pin_GPIO39), + } +}; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + + // On JST PH connector. + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO40) }, + + // On header + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO41) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO42) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO43) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO44) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_IR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON1), MP_ROM_PTR(&pin_GPIO0) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON2), MP_ROM_PTR(&pin_GPIO4) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON3), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO28) }, + + // Shared with ESP TX/RX. + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_ESP_CS), MP_ROM_PTR(&pin_GPIO46) }, + // was GPIO0 on ESP32. Used for IRQ and mode switching. + { MP_ROM_QSTR(MP_QSTR_ESP_IRQ), MP_ROM_PTR(&pin_GPIO23) }, + // BUSY is also known as READY, and is RTS for BLE mode. + { MP_ROM_QSTR(MP_QSTR_ESP_BUSY), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_ESP_RESET), MP_ROM_PTR(&pin_GPIO22) }, + // TX and RX are from the point of view of the RP2350. + { MP_ROM_QSTR(MP_QSTR_ESP_TX), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_ESP_RX), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_CKN), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_CKP), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D0N), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D0P), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D1N), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D1P), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D2N), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D2P), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_PERIPH_RESET), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_DIN), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_I2S_IRQ), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO34) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_CLOCK), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO36) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO39) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA), MP_ROM_PTR(&sdio_data_tuple) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_PLUS), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_MINUS), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_5V_POWER), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + // Shared with ESP TX/RX. + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c index 60f3fc7317a..ec37b398e22 100644 --- a/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c +++ b/ports/raspberrypi/boards/adafruit_macropad_rp2040/board.c @@ -10,7 +10,7 @@ #include "shared-module/displayio/mipi_constants.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/board.h" #include "supervisor/shared/board.h" @@ -29,7 +29,7 @@ uint8_t display_init_sequence[] = { 0xda, 1, 0x12, // com pins 0x81, 1, 0xff, // contrast 255 0xd9, 1, 0x1f, // pre/dis-charge 2DCLKs/2CLKs - 0xdb, 1, 0x20, // VCOM deslect 0.770 + 0xdb, 1, 0x20, // VCOM select 0.770 0x20, 1, 0x20, 0x33, 0, // VPP 9V 0xa6, 0, // not inverted @@ -46,9 +46,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO24, // Command or data - &pin_GPIO22, // Chip select - &pin_GPIO23, // Reset + MP_OBJ_FROM_PTR(&pin_GPIO24), // Command or data + MP_OBJ_FROM_PTR(&pin_GPIO22), // Chip select + MP_OBJ_FROM_PTR(&pin_GPIO23), // Reset 10000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.h index 4242599354c..fdbd18c0e66 100644 --- a/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.h +++ b/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.h @@ -20,3 +20,11 @@ #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +// Onboard microSD slot. +#define DEFAULT_SD_SCK (&pin_GPIO18) +#define DEFAULT_SD_MOSI (&pin_GPIO19) +#define DEFAULT_SD_MISO (&pin_GPIO20) +#define DEFAULT_SD_CS (&pin_GPIO23) +#define DEFAULT_SD_CARD_DETECT (&pin_GPIO15) +#define DEFAULT_SD_CARD_INSERTED true diff --git a/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.mk index 20c3042b7a1..8b3ce22c1bc 100644 --- a/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.mk +++ b/ports/raspberrypi/boards/adafruit_metro_rp2040/mpconfigboard.mk @@ -7,3 +7,5 @@ CHIP_VARIANT = RP2040 CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ,W25Q128JV" + +CIRCUITPY_SDIOIO = 1 diff --git a/ports/raspberrypi/boards/adafruit_metro_rp2040/pins.c b/ports/raspberrypi/boards/adafruit_metro_rp2040/pins.c index 859e7cacb08..b541aea6f1f 100644 --- a/ports/raspberrypi/boards/adafruit_metro_rp2040/pins.c +++ b/ports/raspberrypi/boards/adafruit_metro_rp2040/pins.c @@ -4,8 +4,21 @@ // // SPDX-License-Identifier: MIT +#include "py/objtuple.h" #include "shared-bindings/board/__init__.h" +// Four consecutive data GPIOs for the 4-bit SDIO interface (sdioio.SDCard). +static const mp_rom_obj_tuple_t sdio_data_tuple = { + {&mp_type_tuple}, + 4, + { + MP_ROM_PTR(&pin_GPIO20), + MP_ROM_PTR(&pin_GPIO21), + MP_ROM_PTR(&pin_GPIO22), + MP_ROM_PTR(&pin_GPIO23), + } +}; + static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS @@ -64,6 +77,8 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO23) }, { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA), MP_ROM_PTR(&sdio_data_tuple) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, diff --git a/ports/raspberrypi/boards/adafruit_metro_rp2350/board.c b/ports/raspberrypi/boards/adafruit_metro_rp2350/board.c index e6a868ab212..f85d1076c0b 100644 --- a/ports/raspberrypi/boards/adafruit_metro_rp2350/board.c +++ b/ports/raspberrypi/boards/adafruit_metro_rp2350/board.c @@ -4,6 +4,36 @@ // // SPDX-License-Identifier: MIT +#include "common-hal/microcontroller/Pin.h" +#include "hardware/gpio.h" +#include "shared-bindings/usb_host/Port.h" #include "supervisor/board.h" +#include "common-hal/picodvi/__init__.h" + // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + + +#if defined(DEFAULT_USB_HOST_5V_POWER) +bool board_reset_pin_number(uint8_t pin_number) { + if (pin_number == DEFAULT_USB_HOST_5V_POWER->number) { + // doing this (rather than gpio_init) in this specific order ensures no + // glitch if pin was already configured as a high output. gpio_init() temporarily + // configures the pin as an input, so the power enable value would potentially + // glitch. + gpio_put(pin_number, 1); + gpio_set_dir(pin_number, GPIO_OUT); + gpio_set_function(pin_number, GPIO_FUNC_SIO); + + return true; + } + return false; +} +#endif + +void board_init(void) { + #if defined(DEFAULT_USB_HOST_DATA_PLUS) + common_hal_usb_host_port_construct(DEFAULT_USB_HOST_DATA_PLUS, DEFAULT_USB_HOST_DATA_MINUS); + #endif + picodvi_autoconstruct(); +} diff --git a/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.h index 22be24aacdf..1a583046416 100644 --- a/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.h +++ b/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.h @@ -5,16 +5,16 @@ // SPDX-License-Identifier: MIT #define MICROPY_HW_BOARD_NAME "Adafruit Metro RP2350" -#define MICROPY_HW_MCU_NAME "rp2350a" +#define MICROPY_HW_MCU_NAME "rp2350b" -#define MICROPY_HW_NEOPIXEL (&pin_GPIO14) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO25) -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO24) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO25) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) -#define DEFAULT_SPI_BUS_SCK (&pin_GPIO22) -#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) -#define DEFAULT_SPI_BUS_MISO (&pin_GPIO20) +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO30) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO31) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO28) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) @@ -22,4 +22,23 @@ // #define CIRCUITPY_CONSOLE_UART_RX DEFAULT_UART_BUS_RX // #define CIRCUITPY_CONSOLE_UART_TX DEFAULT_UART_BUS_TX -#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO8) +#define DEFAULT_USB_HOST_DATA_PLUS (&pin_GPIO32) +#define DEFAULT_USB_HOST_DATA_MINUS (&pin_GPIO33) +#define DEFAULT_USB_HOST_5V_POWER (&pin_GPIO29) +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO47) + +#define DEFAULT_DVI_BUS_CLK_DN (&pin_GPIO15) +#define DEFAULT_DVI_BUS_CLK_DP (&pin_GPIO14) +#define DEFAULT_DVI_BUS_RED_DN (&pin_GPIO19) +#define DEFAULT_DVI_BUS_RED_DP (&pin_GPIO18) +#define DEFAULT_DVI_BUS_GREEN_DN (&pin_GPIO17) +#define DEFAULT_DVI_BUS_GREEN_DP (&pin_GPIO16) +#define DEFAULT_DVI_BUS_BLUE_DN (&pin_GPIO13) +#define DEFAULT_DVI_BUS_BLUE_DP (&pin_GPIO12) + +#define DEFAULT_SD_SCK (&pin_GPIO34) +#define DEFAULT_SD_MOSI (&pin_GPIO35) +#define DEFAULT_SD_MISO (&pin_GPIO36) +#define DEFAULT_SD_CS (&pin_GPIO39) +#define DEFAULT_SD_CARD_DETECT (&pin_GPIO40) +#define DEFAULT_SD_CARD_INSERTED false diff --git a/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.mk index 94a3c5c3f37..6d499c367d7 100644 --- a/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.mk +++ b/ports/raspberrypi/boards/adafruit_metro_rp2350/mpconfigboard.mk @@ -4,7 +4,9 @@ USB_PRODUCT = "Metro RP2350" USB_MANUFACTURER = "Adafruit" CHIP_VARIANT = RP2350 -CHIP_PACKAGE = A +CHIP_PACKAGE = B CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY_SDIOIO = 1 diff --git a/ports/raspberrypi/boards/adafruit_metro_rp2350/pins.c b/ports/raspberrypi/boards/adafruit_metro_rp2350/pins.c index 80f046f9bd9..a38c2496dd6 100644 --- a/ports/raspberrypi/boards/adafruit_metro_rp2350/pins.c +++ b/ports/raspberrypi/boards/adafruit_metro_rp2350/pins.c @@ -4,18 +4,30 @@ // // SPDX-License-Identifier: MIT +#include "py/objtuple.h" #include "shared-bindings/board/__init__.h" +// Four consecutive data GPIOs for the 4-bit SDIO interface (sdioio.SDCard). +static const mp_rom_obj_tuple_t sdio_data_tuple = { + {&mp_type_tuple}, + 4, + { + MP_ROM_PTR(&pin_GPIO36), + MP_ROM_PTR(&pin_GPIO37), + MP_ROM_PTR(&pin_GPIO38), + MP_ROM_PTR(&pin_GPIO39), + } +}; + static const mp_rom_map_elem_t board_module_globals_table[] = { CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS - { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO24) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO41) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO42) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO43) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO44) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO45) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO46) }, // On-board switch reverses D0 and D1 connections to RX and TX. @@ -37,20 +49,62 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO24) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_CKN), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_CKP), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D0N), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D0P), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D1N), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D1P), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D2N), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D2P), MP_ROM_PTR(&pin_GPIO12) }, + + // GPIO's on HSTX connector + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO34) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_CLOCK), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO35) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO36) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO36) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO37) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO38) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO39) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO39) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO24) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SDIO_DATA), MP_ROM_PTR(&sdio_data_tuple) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CARD_DETECT), MP_ROM_PTR(&pin_GPIO40) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO22) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO23) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO20) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_PLUS), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_MINUS), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_5V_POWER), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, diff --git a/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c b/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c index 5a44f1167f0..ae948d089b5 100644 --- a/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c +++ b/ports/raspberrypi/boards/adafruit_qt2040_trinkey/board.c @@ -7,6 +7,6 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_tinychad_rp2350/board.c b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/board.c new file mode 100644 index 00000000000..cfa2308f796 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/board.c @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "supervisor/board.h" + +#include "common-hal/picodvi/__init__.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/adafruit_tinychad_rp2350/mpconfigboard.h b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/mpconfigboard.h new file mode 100644 index 00000000000..958ab01a0b6 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Adafruit Tinychad RP2350" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO17) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO19) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO18) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO10) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO12) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/adafruit_tinychad_rp2350/mpconfigboard.mk b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/mpconfigboard.mk new file mode 100644 index 00000000000..36359c88fe4 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x239A +USB_PID = 0x8170 +USB_PRODUCT = "Tinychad RP2350" +USB_MANUFACTURER = "Adafruit" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/adafruit_tinychad_rp2350/pico-sdk-configboard.h b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/pico-sdk-configboard.h new file mode 100644 index 00000000000..2d9283a9192 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/pico-sdk-configboard.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/adafruit_tinychad_rp2350/pins.c b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/pins.c new file mode 100644 index 00000000000..0d769fd4d56 --- /dev/null +++ b/ports/raspberrypi/boards/adafruit_tinychad_rp2350/pins.c @@ -0,0 +1,54 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_CS), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/archi/mpconfigboard.mk b/ports/raspberrypi/boards/archi/mpconfigboard.mk index 1189e6879b9..faf9833da62 100644 --- a/ports/raspberrypi/boards/archi/mpconfigboard.mk +++ b/ports/raspberrypi/boards/archi/mpconfigboard.mk @@ -20,3 +20,5 @@ FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_seesaw FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_framebuf FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SimpleIO + +OPTIMIZATION_FLAGS = -O2 diff --git a/ports/raspberrypi/boards/boardsource_blok/board.c b/ports/raspberrypi/boards/boardsource_blok/board.c index 0c7574ea8a8..5d714c242b5 100644 --- a/ports/raspberrypi/boards/boardsource_blok/board.c +++ b/ports/raspberrypi/boards/boardsource_blok/board.c @@ -6,7 +6,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" void board_init(void) { diff --git a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c index 60efe1e2822..f091c4b05a8 100644 --- a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c +++ b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/board.c @@ -26,9 +26,9 @@ #include "shared-module/displayio/__init__.h" #include "supervisor/shared/board.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" -#include "src/rp2_common/hardware_adc/include/hardware/adc.h" +#include "hardware/adc.h" #define ADC_FIRST_PIN_NUMBER 26 #define ADC_PIN_COUNT 4 extern void common_hal_mcu_delay_us(uint32_t); @@ -212,9 +212,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO11, // DEFAULT_SPI_BUS_DC, // EPD_DC Command or data - &pin_GPIO13, // DEFAULT_SPI_BUS_CS, // EPD_CS Chip select - &pin_GPIO10, // DEFAULT_SPI_BUS_RESET, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO11), // DEFAULT_SPI_BUS_DC, // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO13), // DEFAULT_SPI_BUS_CS, // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO10), // DEFAULT_SPI_BUS_RESET, // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase @@ -251,71 +251,62 @@ void board_init(void) { if ((vid_setting == 1) || // DCNextGen SSD1681 BWR rotated 270 (vid_setting == 3) || // Explorer SSD1681 BW rotated 0 (vid_setting == 4)) { // Explorer SSD1681 BWR rotated 0 - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - _start_sequence_ssd1681, sizeof(_start_sequence_ssd1681), - 1.0, // start up time - _stop_sequence_ssd1681, sizeof(_stop_sequence_ssd1681), - WIDTH, // width - HEIGHT, // height - WIDTH, // ram_width - HEIGHT + 0x60, // ram_height RAM is actually only 200 bits high but we use 296 to match the 9 bits - 0, // colstart - 0, // rowstart - rotation, // rotation - SSD_SET_RAMXPOS, // set_column_window_command - SSD_SET_RAMYPOS, // set_row_window_command - SSD_SET_RAMXCOUNT, // set_current_column_command - SSD_SET_RAMYCOUNT, // set_current_row_command - SSD_WRITE_RAM_BLK, // write_black_ram_command - false, // black_bits_inverted - SSD_WRITE_RAM_RED, // write_color_ram_command - false, // color_bits_inverted - 0xFF0000, // highlight_color (RED for tri-color display) - _refresh_sequence_ssd1681, sizeof(_refresh_sequence_ssd1681), // refresh_display_command - refresh_time, // refresh_time - &pin_GPIO9, // DEFAULT_SPI_BUS_BUSY, // busy_pin - true, // busy_state - seconds_per_frame, // seconds_per_frame (does not seem the user can change this) - true, // always_toggle_chip_select - false, // not grayscale - false, // not acep - false, // not two_byte_sequence_length - true); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = _start_sequence_ssd1681; + args.start_sequence_len = sizeof(_start_sequence_ssd1681); + args.start_up_time = 1.0; + args.stop_sequence = _stop_sequence_ssd1681; + args.stop_sequence_len = sizeof(_stop_sequence_ssd1681); + args.width = WIDTH; + args.height = HEIGHT; + args.ram_width = WIDTH; + args.ram_height = HEIGHT + 0x60; + args.rotation = rotation; + args.set_column_window_command = SSD_SET_RAMXPOS; + args.set_row_window_command = SSD_SET_RAMYPOS; + args.set_current_column_command = SSD_SET_RAMXCOUNT; + args.set_current_row_command = SSD_SET_RAMYCOUNT; + args.write_black_ram_command = SSD_WRITE_RAM_BLK; + args.write_color_ram_command = SSD_WRITE_RAM_RED; + args.highlight_color = 0xFF0000; + args.refresh_sequence = _refresh_sequence_ssd1681; + args.refresh_sequence_len = sizeof(_refresh_sequence_ssd1681); + args.refresh_time = refresh_time; + args.busy_pin = &pin_GPIO9; + args.busy_state = true; + args.seconds_per_frame = seconds_per_frame; + args.always_toggle_chip_select = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } else if (vid_setting == 2) { // Explorer SSD1608 BW - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - _start_sequence_ssd1608, sizeof(_start_sequence_ssd1608), - 1.0, // start up time - _stop_sequence_ssd1608, sizeof(_stop_sequence_ssd1608), - WIDTH, // width - HEIGHT, // height - WIDTH, // ram_width - HEIGHT /* + 0x60 */, // ram_height RAM is actually only 200 bits high but we use 296 to match the 9 bits - 0, // colstart - 0, // rowstart - rotation, // rotation - SSD_SET_RAMXPOS, // set_column_window_command - SSD_SET_RAMYPOS, // set_row_window_command - SSD_SET_RAMXCOUNT, // set_current_column_command - SSD_SET_RAMYCOUNT, // set_current_row_command - SSD_WRITE_RAM_BLK, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color (RED for tri-color display) - _refresh_sequence_ssd1608, sizeof(_refresh_sequence_ssd1608), // refresh_display_command - refresh_time, // refresh_time - &pin_GPIO9, // DEFAULT_SPI_BUS_BUSY, // busy_pin - true, // busy_state - seconds_per_frame, // seconds_per_frame (does not seem the user can change this) - true, // always_toggle_chip_select - false, // not grayscale - false, // not acep - false, // not two_byte_sequence_length - true); // address_little_endian + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = _start_sequence_ssd1608; + args.start_sequence_len = sizeof(_start_sequence_ssd1608); + args.start_up_time = 1.0; + args.stop_sequence = _stop_sequence_ssd1608; + args.stop_sequence_len = sizeof(_stop_sequence_ssd1608); + args.width = WIDTH; + args.height = HEIGHT; + args.ram_width = WIDTH; + args.ram_height = HEIGHT; + args.rotation = rotation; + args.set_column_window_command = SSD_SET_RAMXPOS; + args.set_row_window_command = SSD_SET_RAMYPOS; + args.set_current_column_command = SSD_SET_RAMXCOUNT; + args.set_current_row_command = SSD_SET_RAMYCOUNT; + args.write_black_ram_command = SSD_WRITE_RAM_BLK; + args.write_color_ram_command = NO_COMMAND; + args.refresh_sequence = _refresh_sequence_ssd1608; + args.refresh_sequence_len = sizeof(_refresh_sequence_ssd1608); + args.refresh_time = refresh_time; + args.busy_pin = &pin_GPIO9; + args.busy_state = true; + args.seconds_per_frame = seconds_per_frame; + args.always_toggle_chip_select = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } else { // what should happen if this firmware is installed on some other board? // currently, we mark the display as None diff --git a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/mpconfigboard.mk b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/mpconfigboard.mk index 14f27c07b99..edb4f3bb3d8 100644 --- a/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/mpconfigboard.mk +++ b/ports/raspberrypi/boards/bradanlanestudio_explorer_rp2040/mpconfigboard.mk @@ -15,6 +15,9 @@ EXTERNAL_FLASH_DEVICES = "GD25Q64C" CIRCUITPY__EVE = 1 +# The default is -O3. +OPTIMIZATION_FLAGS = -Os + FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_asyncio FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Bitmap_Font FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Shapes diff --git a/ports/raspberrypi/boards/challenger_rp2350_wifi6_ble5/mpconfigboard.mk b/ports/raspberrypi/boards/challenger_rp2350_wifi6_ble5/mpconfigboard.mk index d4f2cdb90d0..7663bcfb19d 100644 --- a/ports/raspberrypi/boards/challenger_rp2350_wifi6_ble5/mpconfigboard.mk +++ b/ports/raspberrypi/boards/challenger_rp2350_wifi6_ble5/mpconfigboard.mk @@ -12,5 +12,9 @@ EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" CIRCUITPY__EVE = 1 CIRCUITPY_ALARM = 0 +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 + + FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HID FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register diff --git a/ports/raspberrypi/boards/cytron_edu_pico_w/mpconfigboard.mk b/ports/raspberrypi/boards/cytron_edu_pico_w/mpconfigboard.mk index c3c387f8130..384b0060df8 100644 --- a/ports/raspberrypi/boards/cytron_edu_pico_w/mpconfigboard.mk +++ b/ports/raspberrypi/boards/cytron_edu_pico_w/mpconfigboard.mk @@ -20,10 +20,23 @@ CIRCUITPY_WIFI = 1 CIRCUITPY_PICODVI = 1 -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' +# The default is -O3. Change to -O2 because the build was overflowing. +OPTIMIZATION_FLAGS = -O2 + # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor diff --git a/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/board.c b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/link.ld b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/link.ld new file mode 100644 index 00000000000..e814bead4c5 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/link.ld @@ -0,0 +1 @@ +firmware_size = 1532k; diff --git a/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/mpconfigboard.h b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/mpconfigboard.h new file mode 100644 index 00000000000..8eab7e5a525 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Cytron EDU PICO 2" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +#define MICROPY_HW_LED_STATUS (&pin_CYW0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = &pin_GPIO16}} diff --git a/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/mpconfigboard.mk b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/mpconfigboard.mk new file mode 100644 index 00000000000..75d49696a13 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/mpconfigboard.mk @@ -0,0 +1,57 @@ +USB_VID = 0x2E8A +USB_PID = 0x107E +USB_PRODUCT = "Cytron EDU PICO 2 for Pico 2W" +USB_MANUFACTURER = "Cytron" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY_SDCARDIO = 1 + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 + +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + -DCYW43_PIO_CLOCK_DIV_INT=3 + +# The default is -O3. +OPTIMIZATION_FLAGS = -Os + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SimpleIO +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_framebuf +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_OPT4048 +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SSD1306 +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ImageLoad +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_AHTx0 +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_HTTPServer +FROZEN_MPY_DIRS += $(TOP)/frozen/CircuitPython_edupico2_paj7620 + +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/pico-sdk-configboard.h b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/pins.c b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/pins.c new file mode 100644 index 00000000000..83b93e72685 --- /dev/null +++ b/ports/raspberrypi/boards/cytron_edu_v2_pico_2w/pins.c @@ -0,0 +1,86 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + // Motor Controls + { MP_ROM_QSTR(MP_QSTR_M1A), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_M1B), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_M2A), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_M2B), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_LOG_SWITCH), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + // SPI Pins for SD Card + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_USB_RELAY), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_CYW1) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_CYW0) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_CYW2) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_PLUS), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_DATA_MINUS), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_USB_HOST_POWER), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_spi_obj) }, + + + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/cytron_maker_pi_rp2040/pins.c b/ports/raspberrypi/boards/cytron_maker_pi_rp2040/pins.c index 53fae76ac1b..dbfc713930b 100644 --- a/ports/raspberrypi/boards/cytron_maker_pi_rp2040/pins.c +++ b/ports/raspberrypi/boards/cytron_maker_pi_rp2040/pins.c @@ -62,6 +62,8 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VBATT), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, diff --git a/ports/raspberrypi/boards/cytron_motion_2350_pro/mpconfigboard.mk b/ports/raspberrypi/boards/cytron_motion_2350_pro/mpconfigboard.mk index 0ac939ce6a2..9a766f42da7 100644 --- a/ports/raspberrypi/boards/cytron_motion_2350_pro/mpconfigboard.mk +++ b/ports/raspberrypi/boards/cytron_motion_2350_pro/mpconfigboard.mk @@ -11,6 +11,10 @@ EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" CIRCUITPY__EVE = 1 +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 + + # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Motor diff --git a/ports/raspberrypi/boards/datanoise_picoadk_v2/board.c b/ports/raspberrypi/boards/datanoise_picoadk_v2/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/datanoise_picoadk_v2/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/datanoise_picoadk_v2/mpconfigboard.h b/ports/raspberrypi/boards/datanoise_picoadk_v2/mpconfigboard.h new file mode 100644 index 00000000000..d14f625d618 --- /dev/null +++ b/ports/raspberrypi/boards/datanoise_picoadk_v2/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Datanoise PicoADK V2" +#define MICROPY_HW_MCU_NAME "rp2350a" + + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO3) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO4) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO13) +#define DEFAULT_UART_BUS_TX (&pin_GPIO12) diff --git a/ports/raspberrypi/boards/datanoise_picoadk_v2/mpconfigboard.mk b/ports/raspberrypi/boards/datanoise_picoadk_v2/mpconfigboard.mk new file mode 100644 index 00000000000..42d747537af --- /dev/null +++ b/ports/raspberrypi/boards/datanoise_picoadk_v2/mpconfigboard.mk @@ -0,0 +1,16 @@ +USB_VID = 0x2E8A +USB_PID = 0x10AE +USB_PRODUCT = "PicoADK V2" +USB_MANUFACTURER = "Datanoise" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q32C,W25Q32JVxQ" + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 + +# Include these Python libraries in firmware. +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SD diff --git a/ports/raspberrypi/boards/datanoise_picoadk_v2/pico-sdk-configboard.h b/ports/raspberrypi/boards/datanoise_picoadk_v2/pico-sdk-configboard.h new file mode 100644 index 00000000000..ce5a7645b4e --- /dev/null +++ b/ports/raspberrypi/boards/datanoise_picoadk_v2/pico-sdk-configboard.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/datanoise_picoadk_v2/pins.c b/ports/raspberrypi/boards/datanoise_picoadk_v2/pins.c new file mode 100644 index 00000000000..39c6c605488 --- /dev/null +++ b/ports/raspberrypi/boards/datanoise_picoadk_v2/pins.c @@ -0,0 +1,57 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_CS0), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_MIDI_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_I2S_DIN), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BCLK), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_I2S_LRCLK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_SDIO_CLOCK), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/hack_club_sprig/board.c b/ports/raspberrypi/boards/hack_club_sprig/board.c index 89b1b3b75b7..94c5a7c5be9 100644 --- a/ports/raspberrypi/boards/hack_club_sprig/board.c +++ b/ports/raspberrypi/boards/hack_club_sprig/board.c @@ -10,7 +10,7 @@ #include "shared-bindings/fourwire/FourWire.h" #include "shared-module/displayio/__init__.h" #include "shared-module/displayio/mipi_constants.h" -#include "supervisor/shared/board.h" +#include "shared-bindings/board/__init__.h" // display init sequence from CircuitPython library https://github.com/adafruit/Adafruit_CircuitPython_ST7735R/blob/dfae353330cf051d1f31db9e4b681c8d70900cc5/adafruit_st7735r.py @@ -57,17 +57,14 @@ uint8_t display_init_sequence[] = { void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; - busio_spi_obj_t *spi = &bus->inline_bus; - common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, &pin_GPIO16, false); - common_hal_busio_spi_never_reset(spi); - bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO22, // DC - &pin_GPIO20, // CS - &pin_GPIO26, // RST + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_DC), + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_CS), + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_TFT_RESET), 30000000, 0, 0); @@ -92,7 +89,7 @@ void board_init(void) { MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command display_init_sequence, sizeof(display_init_sequence), - &pin_GPIO17, // backlight pin + CIRCUITPY_BOARD_TFT_BACKLIGHT, NO_BRIGHTNESS_COMMAND, 1.0f, // brightness false, // single_byte_bounds @@ -104,4 +101,8 @@ void board_init(void) { 50000); // backlight pwm frequency } +void board_deinit(void) { + common_hal_displayio_release_displays(); +} + // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.h b/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.h index 041aca6d45e..bfc0469a711 100644 --- a/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.h +++ b/ports/raspberrypi/boards/hack_club_sprig/mpconfigboard.h @@ -10,3 +10,11 @@ #define MICROPY_HW_MCU_NAME "rp2040" #define MICROPY_HW_LED_STATUS (&pin_GPIO4) + +#define CIRCUITPY_BOARD_TFT_DC (&pin_GPIO22) +#define CIRCUITPY_BOARD_TFT_CS (&pin_GPIO20) +#define CIRCUITPY_BOARD_TFT_RESET (&pin_GPIO26) +#define CIRCUITPY_BOARD_TFT_BACKLIGHT (&pin_GPIO17) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = &pin_GPIO16 }} diff --git a/ports/raspberrypi/boards/hack_club_sprig/pins.c b/ports/raspberrypi/boards/hack_club_sprig/pins.c index e5ce1478398..7802ef5466d 100644 --- a/ports/raspberrypi/boards/hack_club_sprig/pins.c +++ b/ports/raspberrypi/boards/hack_club_sprig/pins.c @@ -60,7 +60,6 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, - // Start Sprig-specific definitions { MP_ROM_QSTR(MP_QSTR_BLUE_LED), MP_ROM_PTR(&pin_GPIO4) }, @@ -79,18 +78,23 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_BUTTON_K), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_BUTTON_L), MP_ROM_PTR(&pin_GPIO15) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO16) }, - { MP_ROM_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, - { MP_ROM_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_CARD_CS), MP_ROM_PTR(&pin_GPIO21) }, - { MP_ROM_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(&pin_GPIO22) }, - { MP_ROM_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_DC), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_DC) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_CS), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_CS) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_RESET), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_RESET) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_BACKLIGHT) }, + { MP_ROM_QSTR(MP_QSTR_TFT_LITE), MP_ROM_PTR(CIRCUITPY_BOARD_TFT_BACKLIGHT) }, + { MP_ROM_QSTR(MP_QSTR_WHITE_LED), MP_ROM_PTR(&pin_GPIO28) }, { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/heiafr_picomo_v2/board.c b/ports/raspberrypi/boards/heiafr_picomo_v2/board.c index 8c60341489f..15324b40ecd 100644 --- a/ports/raspberrypi/boards/heiafr_picomo_v2/board.c +++ b/ports/raspberrypi/boards/heiafr_picomo_v2/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO16, // TFT_DC Command or data - &pin_GPIO17, // TFT_CS Chip select - NULL, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO16), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset 62500000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/heiafr_picomo_v3/board.c b/ports/raspberrypi/boards/heiafr_picomo_v3/board.c new file mode 100644 index 00000000000..15324b40ecd --- /dev/null +++ b/ports/raspberrypi/boards/heiafr_picomo_v3/board.c @@ -0,0 +1,93 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "supervisor/shared/board.h" + + +#define DELAY 0x80 + +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 150, // SWRESET + + 0x36, 1, 0x04, // MADCTL + 0x35, 1, 0x00, // TEON + 0xB2, 5, 0x0c, 0x0c, 0x00, 0x33, 0x33, // FRMCTR2 + 0x3A, 1, 0x05, // COLMOD + 0xB7, 1, 0x14, // GCTRL + 0xBB, 1, 0x37, // VCOMS + 0xC0, 1, 0x2c, // LCMCTRL + 0xC2, 1, 0x01, // VDVVRHEN + 0xC3, 1, 0x12, // VRHS + 0xC4, 1, 0x20, // VDVS + 0xD0, 2, 0xa4, 0xa1, // PWRCTRL1 + 0xC6, 1, 0x0f, // FRCTRL2 + 0xE0, 14, 0xd0, 0x04, 0x0d, 0x11, 0x13, 0x2b, 0x3f, 0x54, 0x4c, 0x18, 0x0d, 0x0b, 0x1f, 0x23, // GMCTRP1 + 0xE1, 14, 0xd0, 0x04, 0x0c, 0x11, 0x13, 0x2c, 0x3f, 0x44, 0x51, 0x2f, 0x1f, 0x1f, 0x20, 0x23, // GMCTRN1 + 0x21, 0, // INVON + + 0x11, 0 | DELAY, 255, // SLPOUT + 0x29, 0 | DELAY, 100, // DISPON + + 0x2a, 4, 0x00, 0, 0x00, 0xfe, // CASET + 0x2b, 4, 0x00, 0, 0x00, 0xfe, // RASET + 0x2c, 0, // RAMWR +}; + +void board_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO16), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // TFT_CS Chip select + mp_const_none, // TFT_RST Reset + 62500000, // Baudrate + 0, // Polarity + 0); // Phase + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + common_hal_busdisplay_busdisplay_construct(display, + bus, + 240, // Width + 280, // Height + 0, // column start + 20, // row start + 0, // rotation + 16, // Color depth + false, // Grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_bytes_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // Set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // Set row command + MIPI_COMMAND_WRITE_MEMORY_START, // Write memory command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // no backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 0); // backlight pwm frequency +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/heiafr_picomo_v3/mpconfigboard.h b/ports/raspberrypi/boards/heiafr_picomo_v3/mpconfigboard.h new file mode 100644 index 00000000000..39094f8972d --- /dev/null +++ b/ports/raspberrypi/boards/heiafr_picomo_v3/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "HEIA-FR Picomo V3" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO10) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO9) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO8) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) diff --git a/ports/raspberrypi/boards/heiafr_picomo_v3/mpconfigboard.mk b/ports/raspberrypi/boards/heiafr_picomo_v3/mpconfigboard.mk new file mode 100644 index 00000000000..2ee1fad50c9 --- /dev/null +++ b/ports/raspberrypi/boards/heiafr_picomo_v3/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x2E8A +USB_PID = 0x10C4 + +USB_PRODUCT = "Picomo V3" +USB_MANUFACTURER = "HEIA-FR" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY__EVE = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Register +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ST7789 +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Shapes +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ProgressBar diff --git a/ports/raspberrypi/boards/heiafr_picomo_v3/pico-sdk-configboard.h b/ports/raspberrypi/boards/heiafr_picomo_v3/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/heiafr_picomo_v3/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/heiafr_picomo_v3/pins.c b/ports/raspberrypi/boards/heiafr_picomo_v3/pins.c new file mode 100644 index 00000000000..eb1a1ec1d41 --- /dev/null +++ b/ports/raspberrypi/boards/heiafr_picomo_v3/pins.c @@ -0,0 +1,110 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + {MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0)}, + {MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1)}, + {MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2)}, + + {MP_ROM_QSTR(MP_QSTR_SW_UP), MP_ROM_PTR(&pin_GPIO3)}, + {MP_ROM_QSTR(MP_QSTR_S1), MP_ROM_PTR(&pin_GPIO3)}, + {MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3)}, + + {MP_ROM_QSTR(MP_QSTR_SW_MID), MP_ROM_PTR(&pin_GPIO4)}, + {MP_ROM_QSTR(MP_QSTR_S5), MP_ROM_PTR(&pin_GPIO4)}, + {MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4)}, + + {MP_ROM_QSTR(MP_QSTR_SW_DOWN), MP_ROM_PTR(&pin_GPIO5)}, + {MP_ROM_QSTR(MP_QSTR_S2), MP_ROM_PTR(&pin_GPIO5)}, + {MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5)}, + + {MP_ROM_QSTR(MP_QSTR_SW_TOPR), MP_ROM_PTR(&pin_GPIO6)}, + {MP_ROM_QSTR(MP_QSTR_BOOTSEL), MP_ROM_PTR(&pin_GPIO6)}, + {MP_ROM_QSTR(MP_QSTR_S7), MP_ROM_PTR(&pin_GPIO6)}, + {MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6)}, + + {MP_ROM_QSTR(MP_QSTR_SW_RIGHT), MP_ROM_PTR(&pin_GPIO7)}, + {MP_ROM_QSTR(MP_QSTR_S4), MP_ROM_PTR(&pin_GPIO7)}, + {MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7)}, + + {MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO8)}, + {MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8)}, + + {MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO9)}, + {MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9)}, + + {MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO10)}, + {MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10)}, + + {MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11)}, + + {MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12)}, + {MP_ROM_QSTR(MP_QSTR_BUZZER), MP_ROM_PTR(&pin_GPIO12)}, + + {MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13)}, + {MP_ROM_QSTR(MP_QSTR_VER_MSB), MP_ROM_PTR(&pin_GPIO13)}, + + {MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14)}, + {MP_ROM_QSTR(MP_QSTR_VER_LSB), MP_ROM_PTR(&pin_GPIO14)}, + + {MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15)}, + + {MP_ROM_QSTR(MP_QSTR_DISP_DC), MP_ROM_PTR(&pin_GPIO16)}, + {MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16)}, + + {MP_ROM_QSTR(MP_QSTR_DISP_CS), MP_ROM_PTR(&pin_GPIO17)}, + {MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17)}, + + {MP_ROM_QSTR(MP_QSTR_DISP_SCL), MP_ROM_PTR(&pin_GPIO18)}, + {MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18)}, + + {MP_ROM_QSTR(MP_QSTR_DISP_SDA), MP_ROM_PTR(&pin_GPIO19)}, + {MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19)}, + + {MP_ROM_QSTR(MP_QSTR_TEMP_SDA), MP_ROM_PTR(&pin_GPIO20)}, + {MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20)}, + + {MP_ROM_QSTR(MP_QSTR_TEMP_SCL), MP_ROM_PTR(&pin_GPIO21)}, + {MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21)}, + + {MP_ROM_QSTR(MP_QSTR_SW_LEFT), MP_ROM_PTR(&pin_GPIO22)}, + {MP_ROM_QSTR(MP_QSTR_S3), MP_ROM_PTR(&pin_GPIO22)}, + {MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22)}, + + {MP_ROM_QSTR(MP_QSTR_SW_TOPL), MP_ROM_PTR(&pin_GPIO23)}, + {MP_ROM_QSTR(MP_QSTR_S6), MP_ROM_PTR(&pin_GPIO23)}, + {MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23)}, + + {MP_ROM_QSTR(MP_QSTR_USB_OVCUR), MP_ROM_PTR(&pin_GPIO24)}, + {MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24)}, + + {MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25)}, + + {MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26)}, + {MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26)}, + {MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26)}, + + {MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27)}, + {MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27)}, + {MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27)}, + + {MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28)}, + {MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28)}, + {MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28)}, + + {MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29)}, + {MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29)}, + + {MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj)}, + {MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj)}, + {MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/hxr_sao_dmm/board.c b/ports/raspberrypi/boards/hxr_sao_dmm/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/hxr_sao_dmm/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/hxr_sao_dmm/mpconfigboard.h b/ports/raspberrypi/boards/hxr_sao_dmm/mpconfigboard.h new file mode 100644 index 00000000000..3b20682ee30 --- /dev/null +++ b/ports/raspberrypi/boards/hxr_sao_dmm/mpconfigboard.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "HXR.DK SAO Digital Multimeter" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO15) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO14) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_BOARD_I2C (2) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}, \ + {.scl = &pin_GPIO15, .sda = &pin_GPIO14}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO0, .rx = &pin_GPIO1}} diff --git a/ports/raspberrypi/boards/hxr_sao_dmm/mpconfigboard.mk b/ports/raspberrypi/boards/hxr_sao_dmm/mpconfigboard.mk new file mode 100644 index 00000000000..f841b1818b4 --- /dev/null +++ b/ports/raspberrypi/boards/hxr_sao_dmm/mpconfigboard.mk @@ -0,0 +1,17 @@ +USB_VID = 0x1209 +USB_PID = 0xFD42 +USB_PRODUCT = "SAO Digital Multimeter" +USB_MANUFACTURER = "HXR.DK" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 +CIRCUITPY_PICODVI = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Bitmap_Font +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Shapes +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 diff --git a/ports/raspberrypi/boards/hxr_sao_dmm/pico-sdk-configboard.h b/ports/raspberrypi/boards/hxr_sao_dmm/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/hxr_sao_dmm/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/hxr_sao_dmm/pins.c b/ports/raspberrypi/boards/hxr_sao_dmm/pins.c new file mode 100644 index 00000000000..1457f47eb2a --- /dev/null +++ b/ports/raspberrypi/boards/hxr_sao_dmm/pins.c @@ -0,0 +1,103 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(sao_i2c, i2c, 1) + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SAO_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SDA0), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SAO_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SCL0), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY_SDA), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SDA1), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY_SCL), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SCL1), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_ENC_A), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_ENC_B), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON_FN), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_BUZZER_A), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_PWM3_A), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_BUZZER_B), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_PWM3_B), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_SAO_GPIO1), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_SAO_GPIO2), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_MEASURE_RES), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_MEASURE_VIN), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SAO_I2C), MP_ROM_PTR(&board_sao_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c b/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c index 559800e34d9..d3c80c5cb87 100644 --- a/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_encoderpad_rp2040/board.c @@ -6,7 +6,7 @@ #include "shared-bindings/board/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" #include "supervisor/board.h" diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c index c123fd785c9..2bb2d06dcad 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey18/board.c @@ -6,7 +6,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" void reset_board(void) { diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c index f0a39533355..743e9b14b52 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey44/board.c @@ -6,7 +6,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" void reset_board(void) { diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c index 360f18e382e..ab07a4aaaed 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey60/board.c @@ -6,7 +6,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" void reset_board(void) { diff --git a/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c b/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c index 751726a065d..b9fa212c96d 100644 --- a/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c +++ b/ports/raspberrypi/boards/jpconstantineau_pykey87/board.c @@ -6,7 +6,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" void reset_board(void) { diff --git a/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c b/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c index 78cc912130e..2e9ccd45d56 100644 --- a/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c +++ b/ports/raspberrypi/boards/lilygo_t_display_rp2040/board.c @@ -63,9 +63,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO1, // DC - &pin_GPIO5, // CS - NULL, // RST (Reset pin tie to 0, do not set here) + MP_OBJ_FROM_PTR(&pin_GPIO1), // DC + MP_OBJ_FROM_PTR(&pin_GPIO5), // CS + mp_const_none, // RST (Reset pin tie to 0, do not set here) 40000000, // baudrate 1, // polarity 0 // phase diff --git a/ports/raspberrypi/boards/mtm_computer/board.c b/ports/raspberrypi/boards/mtm_computer/board.c new file mode 100644 index 00000000000..4fec0cd5b8b --- /dev/null +++ b/ports/raspberrypi/boards/mtm_computer/board.c @@ -0,0 +1,40 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "shared-bindings/mcp4822/MCP4822.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "peripherals/pins.h" +#include "py/runtime.h" + +// board.DAC() — factory function that constructs an mcp4822.MCP4822 with +// the MTM Workshop Computer's DAC pins (GP18=SCK, GP19=SDI, GP21=CS). + +static mp_obj_t board_dac_singleton = MP_OBJ_NULL; + +static mp_obj_t board_dac_factory(void) { + if (board_dac_singleton == MP_OBJ_NULL) { + mcp4822_mcp4822_obj_t *dac = mp_obj_malloc_with_finaliser( + mcp4822_mcp4822_obj_t, &mcp4822_mcp4822_type); + common_hal_mcp4822_mcp4822_construct( + dac, + &pin_GPIO18, // clock (SCK) + &pin_GPIO19, // mosi (SDI) + &pin_GPIO21, // cs + 1); // gain 1x + board_dac_singleton = MP_OBJ_FROM_PTR(dac); + } + return board_dac_singleton; +} +MP_DEFINE_CONST_FUN_OBJ_0(board_dac_obj, board_dac_factory); + +void board_deinit(void) { + if (board_dac_singleton != MP_OBJ_NULL) { + common_hal_mcp4822_mcp4822_deinit(MP_OBJ_TO_PTR(board_dac_singleton)); + board_dac_singleton = MP_OBJ_NULL; + } +} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/mtm_computer/mpconfigboard.h b/ports/raspberrypi/boards/mtm_computer/mpconfigboard.h new file mode 100644 index 00000000000..1825cef28e5 --- /dev/null +++ b/ports/raspberrypi/boards/mtm_computer/mpconfigboard.h @@ -0,0 +1,14 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Music Thing Modular Workshop Computer" +#define MICROPY_HW_MCU_NAME "rp2040" + + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/mtm_computer/mpconfigboard.mk b/ports/raspberrypi/boards/mtm_computer/mpconfigboard.mk new file mode 100644 index 00000000000..45c99711d72 --- /dev/null +++ b/ports/raspberrypi/boards/mtm_computer/mpconfigboard.mk @@ -0,0 +1,14 @@ +USB_VID = 0x2E8A +USB_PID = 0x10C1 +USB_PRODUCT = "Workshop Computer" +USB_MANUFACTURER = "Music Thing Modular" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY_AUDIOEFFECTS = 1 +CIRCUITPY_IMAGECAPTURE = 0 +CIRCUITPY_PICODVI = 0 +CIRCUITPY_MCP4822 = 1 diff --git a/ports/raspberrypi/boards/mtm_computer/pico-sdk-configboard.h b/ports/raspberrypi/boards/mtm_computer/pico-sdk-configboard.h new file mode 100644 index 00000000000..ce5a7645b4e --- /dev/null +++ b/ports/raspberrypi/boards/mtm_computer/pico-sdk-configboard.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/mtm_computer/pins.c b/ports/raspberrypi/boards/mtm_computer/pins.c new file mode 100644 index 00000000000..ffdf2687702 --- /dev/null +++ b/ports/raspberrypi/boards/mtm_computer/pins.c @@ -0,0 +1,114 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +extern const mp_obj_fun_builtin_fixed_t board_dac_obj; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_UART_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_UART_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_PULSE_1_IN), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_PULSE_2_IN), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_NORM_PROBE), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + + // GPIO 5,6,7 are ID bits: 0,0,0 = Proto1.2 (pins floating), 1,0,0 = Proto 2.0 + { MP_ROM_QSTR(MP_QSTR_ID0), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_ID1), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_ID2), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_PULSE_1_OUT), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_PULSE_2_OUT), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_LED4), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_LED5), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_LED6), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_EEPROM_SDA), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_EEPROM_SCL), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_DAC_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_DAC_SDI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + // GP20 is unused + // { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_DAC_CS), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_CV_2_OUT), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_CV_1_OUT), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_MUX_A), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_MUX_B), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_AUDIO_R_IN), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_AUDIO_L_IN), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_MUX_1), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_MUX_2), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + + // Factory function: dac = board.DAC() returns a configured mcp4822.MCP4822 + { MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&board_dac_obj) }, + + // { MP_ROM_QSTR(MP_QSTR_EEPROM_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/orpheus_pico/board.c b/ports/raspberrypi/boards/orpheus_pico/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/orpheus_pico/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/orpheus_pico/mpconfigboard.h b/ports/raspberrypi/boards/orpheus_pico/mpconfigboard.h new file mode 100644 index 00000000000..8c6269771fd --- /dev/null +++ b/ports/raspberrypi/boards/orpheus_pico/mpconfigboard.h @@ -0,0 +1,13 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Orpheus Pico" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO25) +#define MICROPY_HW_LED_STATUS (&pin_GPIO23) diff --git a/ports/raspberrypi/boards/orpheus_pico/mpconfigboard.mk b/ports/raspberrypi/boards/orpheus_pico/mpconfigboard.mk new file mode 100644 index 00000000000..9b570211c8f --- /dev/null +++ b/ports/raspberrypi/boards/orpheus_pico/mpconfigboard.mk @@ -0,0 +1,11 @@ +USB_VID = 0x2E8A +USB_PID = 0x10D0 +USB_PRODUCT = "Orpheus Pico" +USB_MANUFACTURER = "Hack Club" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/orpheus_pico/pico-sdk-configboard.h b/ports/raspberrypi/boards/orpheus_pico/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/orpheus_pico/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/orpheus_pico/pins.c b/ports/raspberrypi/boards/orpheus_pico/pins.c new file mode 100644 index 00000000000..24d656c18c9 --- /dev/null +++ b/ports/raspberrypi/boards/orpheus_pico/pins.c @@ -0,0 +1,57 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/pajenicko_picopad/board.c b/ports/raspberrypi/boards/pajenicko_picopad/board.c index 0ca13b3ec2e..d8f93922623 100644 --- a/ports/raspberrypi/boards/pajenicko_picopad/board.c +++ b/ports/raspberrypi/boards/pajenicko_picopad/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO17, // TFT_DC Command or data - &pin_GPIO21, // TFT_CS Chip select - &pin_GPIO20, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO17), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO21), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO20), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk b/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk index 5f5de1180a7..8a364e4b840 100644 --- a/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pajenicko_picopad/mpconfigboard.mk @@ -9,9 +9,12 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" +CIRCUITPY_USB_HOST = 0 + CIRCUITPY_KEYPAD = 1 CIRCUITPY_STAGE = 1 CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_AUDIOEFFECTS = 0 CIRCUITPY__EVE = 1 @@ -28,6 +31,16 @@ CIRCUITPY_PICODVI = 1 # Pimoroni PicoSystem peripherals are compatible, we can use of existing ugame.py FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/picosystem -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/board.c b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/board.c new file mode 100644 index 00000000000..1ce23b26459 --- /dev/null +++ b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/board.c @@ -0,0 +1 @@ +#include "shared-bindings/board/__init__.h" diff --git a/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/mpconfigboard.h b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/mpconfigboard.h new file mode 100644 index 00000000000..75deccbc8ed --- /dev/null +++ b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/mpconfigboard.h @@ -0,0 +1,12 @@ +#ifndef MICROPY_INCLUDED_RASPBERRYPI_BOARDS_PCBCUPID_Glyph_Mini_2040 +#define MICROPY_INCLUDED_RASPBERRYPI_BOARDS_PCBCUPID_Glyph_Mini_2040 + +#define MICROPY_HW_BOARD_NAME "PCBCupid Glyph Mini 2040" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define FLASH_SIZE (8 * 1024 * 1024) +#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (7 * 1024 * 1024) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO16) + +#endif diff --git a/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/mpconfigboard.mk b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/mpconfigboard.mk new file mode 100644 index 00000000000..415aecd6395 --- /dev/null +++ b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x2E8A +USB_PID = 0x1123 +USB_PRODUCT = "Glyph Mini 2040" +USB_MANUFACTURER = "PCBCupid" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/pico-sdk-configboard.h b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/pins.c b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/pins.c new file mode 100644 index 00000000000..d2719b1ebea --- /dev/null +++ b/ports/raspberrypi/boards/pcbcupid_glyph_mini_2040/pins.c @@ -0,0 +1,37 @@ +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO16) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/pimoroni_badger2040/board.c b/ports/raspberrypi/boards/pimoroni_badger2040/board.c index 457bff33b44..80eddb49e13 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040/board.c @@ -263,9 +263,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO20, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO21, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO20), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO21), // EPD_RST Reset 1200000, // Baudrate 0, // Polarity 0); // Phase @@ -273,38 +273,27 @@ void board_init(void) { // Set up the DisplayIO epaper object epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 296, // width - 128, // height - 160, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - DTM2, // write_black_ram_command - true, // black_bits_inverted - DTM1, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - refresh_sequence, sizeof(refresh_sequence), // refresh_display_command - 1.0, // refresh_time - &pin_GPIO26, // busy_pin - false, // busy_state - 2.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 160; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = DTM2; + args.black_bits_inverted = true; + args.write_color_ram_command = DTM1; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO26; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } void board_deinit(void) { diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c index 30c05273b94..ef5da7ceabc 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040w/board.c +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/board.c @@ -263,9 +263,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO20, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO21, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO20), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO21), // EPD_RST Reset 1200000, // Baudrate 0, // Polarity 0); // Phase @@ -273,38 +273,27 @@ void board_init(void) { // Set up the DisplayIO epaper object epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 296, // width - 128, // height - 160, // ram_width - 296, // ram_height - 0, // colstart - 0, // rowstart - 270, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - DTM2, // write_black_ram_command - true, // black_bits_inverted - DTM1, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - refresh_sequence, sizeof(refresh_sequence), // refresh_display_command - 1.0, // refresh_time - &pin_GPIO26, // busy_pin - false, // busy_state - 2.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - false, // acep - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 296; + args.height = 128; + args.ram_width = 160; + args.ram_height = 296; + args.rotation = 270; + args.write_black_ram_command = DTM2; + args.black_bits_inverted = true; + args.write_color_ram_command = DTM1; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO26; + args.seconds_per_frame = 2.0; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } void board_deinit(void) { diff --git a/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.mk index 65b9b9bfc86..dc70c551959 100644 --- a/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_badger2040w/mpconfigboard.mk @@ -22,7 +22,17 @@ CIRCUITPY_WIFI = 1 CIRCUITPY_PICODVI = 0 CIRCUITPY_USB_HOST = 0 -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/pimoroni_badger2350/badger2350-shared.h b/ports/raspberrypi/boards/pimoroni_badger2350/badger2350-shared.h new file mode 100644 index 00000000000..4cc67efd4df --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2350/badger2350-shared.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +extern digitalio_digitalinout_obj_t i2c_power_en_pin_obj; +extern const mp_obj_fun_builtin_fixed_t set_update_speed_obj; +extern const mp_obj_fun_builtin_fixed_t get_reset_state_obj; +extern const mp_obj_fun_builtin_fixed_t on_reset_pressed_obj; diff --git a/ports/raspberrypi/boards/pimoroni_badger2350/board.c b/ports/raspberrypi/boards/pimoroni_badger2350/board.c new file mode 100644 index 00000000000..1da13b80339 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2350/board.c @@ -0,0 +1,225 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" + +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/board.h" +#include "supervisor/board.h" +#include "badger2350-shared.h" + +#include "hardware/gpio.h" +#include "hardware/structs/iobank0.h" + +digitalio_digitalinout_obj_t i2c_power_en_pin_obj; +static volatile uint32_t reset_button_state = 0; + +// Forward declaration to satisfy -Wmissing-prototypes +static void preinit_button_state(void) __attribute__((constructor(101))); + + +// pin definitions +// Button pin definitions for Badger2350 +#define SW_A_PIN 7 +#define SW_B_PIN 9 +#define SW_C_PIN 10 +#define SW_DOWN_PIN 6 +#define SW_UP_PIN 11 + +static const uint8_t _sw_pin_nrs[] = { + SW_A_PIN, SW_B_PIN, SW_C_PIN, SW_DOWN_PIN, SW_UP_PIN +}; + +// Mask of all front button pins +#define SW_MASK ((1 << SW_A_PIN) | (1 << SW_B_PIN) | (1 << SW_C_PIN) | \ + (1 << SW_DOWN_PIN) | (1 << SW_UP_PIN)) + +// This function runs BEFORE main() via constructor attribute! +// This is the key to fast button state detection. +// Priority 101 = runs very early + +static void preinit_button_state(void) { + // Configure button pins as inputs with pull-downs using direct register access + // This is faster than SDK functions and works before full init + + for (size_t i = 0; i < sizeof(_sw_pin_nrs); i++) { + uint8_t pin_nr = _sw_pin_nrs[i]; + // Set as input + sio_hw->gpio_oe_clr = 1u << pin_nr; + // enable pull-ups + pads_bank0_hw->io[pin_nr] = PADS_BANK0_GPIO0_IE_BITS | + PADS_BANK0_GPIO0_PUE_BITS; + // Set GPIO function + iobank0_hw->io[pin_nr].ctrl = 5; // SIO function + } + + // Small delay for pins to settle (just a few cycles) + for (volatile int i = 0; i < 100; i++) { + __asm volatile ("nop"); + } + + // Capture button states NOW - before anything else runs + reset_button_state = ~sio_hw->gpio_in & SW_MASK; +} + +static mp_obj_t _get_reset_state(void) { + return mp_obj_new_int(reset_button_state); +} +MP_DEFINE_CONST_FUN_OBJ_0(get_reset_state_obj, _get_reset_state); + +static mp_obj_t _on_reset_pressed(mp_obj_t pin_in) { + mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_in); + return mp_obj_new_bool( + (reset_button_state & (1 << pin->number)) != 0); +} +MP_DEFINE_CONST_FUN_OBJ_1(on_reset_pressed_obj, _on_reset_pressed); + +// The display uses an SSD1680 control chip. +uint8_t _start_sequence[] = { + 0x12, 0x80, 0x00, 0x14, // soft reset and wait 20ms + 0x11, 0x00, 0x01, 0x03, // Ram data entry mode + 0x3c, 0x00, 0x01, 0x03, // border color + 0x2c, 0x00, 0x01, 0x28, // Set vcom voltage + 0x03, 0x00, 0x01, 0x17, // Set gate voltage + 0x04, 0x00, 0x03, 0x41, 0xae, 0x32, // Set source voltage + 0x4e, 0x00, 0x01, 0x00, // ram x count + 0x4f, 0x00, 0x02, 0x00, 0x00, // ram y count + 0x01, 0x00, 0x03, 0x07, 0x01, 0x00, // set display size + 0x32, 0x00, 0x99, // Update waveforms + + // offset 44 + 0x40, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L0 + 0xA0, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L1 + 0xA8, 0x65, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L2 + 0xAA, 0x65, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L3 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VS L4 + + // offset 104 + 0x02, 0x00, 0x00, 0x05, 0x0A, 0x00, 0x03, // Group0 (with default speed==0) + // offset 111 + 0x19, 0x19, 0x00, 0x02, 0x00, 0x00, 0x03, // Group1 (with default speed==0) + // offset 118 + 0x05, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x03, // Group2 (with default speed==0) + + // offset 125 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group3 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group4 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group5 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group6 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group7 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group8 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group9 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group10 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Group11 + 0x44, 0x42, 0x22, 0x22, 0x23, 0x32, 0x00, // Config + 0x00, 0x00, // FR, XON + + 0x22, 0x00, 0x01, 0xc7, // display update mode + +}; + +const uint8_t _stop_sequence[] = { + 0x10, 0x00, 0x01, 0x01 // DSM deep sleep mode 1 +}; + +const uint8_t _refresh_sequence[] = { + 0x20, 0x00, 0x00 // ADUS +}; + +// Change update speed. This changes the repeat-count in the LUTs +// Pimoroni uses: 0 == slow ... 3 == fast +// and calculates the LUT repeat count as 3-speed + +#define SPEED_OFFSET_1 110 +#define SPEED_OFFSET_2 117 +#define SPEED_OFFSET_3 124 + +static mp_obj_t _set_update_speed(mp_obj_t speed_in) { + mp_int_t speed = mp_obj_get_int(speed_in); + uint8_t count = (uint8_t)3 - (uint8_t)(speed & 3); + _start_sequence[SPEED_OFFSET_1] = count; + _start_sequence[SPEED_OFFSET_2] = count; + _start_sequence[SPEED_OFFSET_3] = count; + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_1(set_update_speed_obj, _set_update_speed); + +void board_init(void) { + // Drive the I2C_POWER_EN pin high + i2c_power_en_pin_obj.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct( + &i2c_power_en_pin_obj, &pin_GPIO27); + common_hal_digitalio_digitalinout_switch_to_output( + &i2c_power_en_pin_obj, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_never_reset(&i2c_power_en_pin_obj); + + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct(spi, &pin_GPIO18, &pin_GPIO19, NULL, false); + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO20), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO21), // EPD_RST Reset + 12000000, // Baudrate + 0, // Polarity + 0); // Phase + + // create and configure display + epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; + display->base.type = &epaperdisplay_epaperdisplay_type; + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = _start_sequence; + args.start_sequence_len = sizeof(_start_sequence); + args.stop_sequence = _stop_sequence; + args.stop_sequence_len = sizeof(_stop_sequence); + args.width = 264; + args.height = 176; + args.ram_width = 250; + args.ram_height = 296; + args.rotation = 270; + args.set_column_window_command = 0x44; + args.set_row_window_command = 0x45; + args.set_current_column_command = 0x4e; + args.set_current_row_command = 0x4f; + args.write_black_ram_command = 0x24; + args.write_color_ram_command = 0x26; + args.color_bits_inverted = true; + args.refresh_sequence = _refresh_sequence; + args.refresh_sequence_len = sizeof(_refresh_sequence); + args.refresh_time = 1.0; + args.busy_pin = &pin_GPIO16; + args.busy_state = true; + args.seconds_per_frame = 3.0; + args.grayscale = true; + args.two_byte_sequence_length = true; + args.address_little_endian = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); +} + +void board_deinit(void) { + epaperdisplay_epaperdisplay_obj_t *display = &displays[0].epaper_display; + if (display->base.type == &epaperdisplay_epaperdisplay_type) { + while (common_hal_epaperdisplay_epaperdisplay_get_busy(display)) { + RUN_BACKGROUND_TASKS; + } + } + common_hal_displayio_release_displays(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_badger2350/link.ld b/ports/raspberrypi/boards/pimoroni_badger2350/link.ld new file mode 100644 index 00000000000..e814bead4c5 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2350/link.ld @@ -0,0 +1 @@ +firmware_size = 1532k; diff --git a/ports/raspberrypi/boards/pimoroni_badger2350/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_badger2350/mpconfigboard.h new file mode 100644 index 00000000000..6cffd190ad6 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2350/mpconfigboard.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Bernhard Bablok +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Pimoroni Badger 2350" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +#define MICROPY_HW_LED_STATUS (&pin_GPIO0) + +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) + +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO8) diff --git a/ports/raspberrypi/boards/pimoroni_badger2350/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_badger2350/mpconfigboard.mk new file mode 100644 index 00000000000..58f88af2518 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2350/mpconfigboard.mk @@ -0,0 +1,41 @@ +USB_VID = 0x2E8A +USB_PID = 0x1100 +USB_PRODUCT = "Pimoroni Badger 2350" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 + +# PIO clock divider set to 2 (default), consider changing if TM2 gSPI +# becomes unreliable. +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_PIO_CLOCK_DIV_INT=2 \ + -DCYW43_PIO_CLOCK_DIV_FRAC=0 +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' + +FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-pcf85063a diff --git a/ports/raspberrypi/boards/pimoroni_badger2350/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_badger2350/pico-sdk-configboard.h new file mode 100644 index 00000000000..42e0612bf8b --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2350/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_badger2350/pins.c b/ports/raspberrypi/boards/pimoroni_badger2350/pins.c new file mode 100644 index 00000000000..1a66961e68f --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_badger2350/pins.c @@ -0,0 +1,135 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "badger2350-shared.h" + + +// LUT manipulation +static const mp_rom_map_elem_t lut_update_table[] = { + { MP_ROM_QSTR(MP_QSTR_SET_UPDATE_SPEED), (mp_obj_t)&set_update_speed_obj }, + { MP_ROM_QSTR(MP_QSTR_SPEED_SLOW), MP_ROM_INT(0) }, + { MP_ROM_QSTR(MP_QSTR_SPEED_FAST), MP_ROM_INT(1) }, + { MP_ROM_QSTR(MP_QSTR_SPEED_FASTER), MP_ROM_INT(2) }, + { MP_ROM_QSTR(MP_QSTR_SPEED_FASTEST), MP_ROM_INT(3) }, +}; +MP_DEFINE_CONST_DICT(lut_update_dict, lut_update_table); + +const mp_obj_module_t display_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&lut_update_dict, +}; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_display), MP_ROM_PTR(&display_module) }, + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LED0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_LED1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_LED2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_LED3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SW_DOWN), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO7) }, + + // GP8 is reserved for PSRAM chip select + + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SW_B), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_SW_C), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_SW_UP), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_RTC_ALARM), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SW_RESET), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SW_INT), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_INKY_BUSY), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_INKY_CS), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_INKY_DC), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_INKY_RST), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SW_HOME), MP_ROM_PTR(&pin_GPIO22) }, + + // GP23, GP24, GP25, and GP29 are reserved for RM2 gSPI + + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_VBAT_SENSE), MP_ROM_PTR(&pin_GPIO26) }, + + // GP27 is the used for I2C power-enable, driven high by board.c + { MP_ROM_QSTR(MP_QSTR_I2C_POWER_EN), MP_ROM_PTR(&i2c_power_en_pin_obj) }, + + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_SENSE_1V1), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + + // Pins accessed though the RM2 module (CYW43439) + // CYW0, CYW1 is unconnected + { MP_ROM_QSTR(MP_QSTR_CHARGE_STAT), MP_ROM_PTR(&pin_CYW2) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].epaper_display)}, + + // button-state on reset + // Use `board.RESET_STATE()` to query the state of all buttons at reset. + // To detect individual key-presses, `board.ON_RESET_PRESSED()` + // is simpler. + { MP_ROM_QSTR(MP_QSTR_RESET_STATE), (mp_obj_t)&get_reset_state_obj }, + + // Use `board.ON_RESET_PRESSED(board.SW_A)` to check if `SW_A` was pressed + // during reset. + { MP_ROM_QSTR(MP_QSTR_ON_RESET_PRESSED), (mp_obj_t)&on_reset_pressed_obj }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/pimoroni_explorer2350/board.c b/ports/raspberrypi/boards/pimoroni_explorer2350/board.c new file mode 100644 index 00000000000..d0c6d9a57ce --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_explorer2350/board.c @@ -0,0 +1,145 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/paralleldisplaybus/ParallelBus.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "hardware/gpio.h" + +// Display pins from Pimoroni Explorer parallel bus: {cs=27, dc=28, wr=30, rd=31, d0=32, bl=26} +#define LCD_BACKLIGHT_PIN 26 +#define LCD_CS_PIN 27 +#define LCD_DC_PIN 28 +#define LCD_WR_PIN 30 +#define LCD_RD_PIN 31 +#define LCD_D0_PIN 32 // Data pins are GPIO32-39 (8 consecutive pins) + +#define DELAY 0x80 + +// ST7789V display init sequence for 320x240 parallel bus +// Based on Pimoroni's pimoroni-pico ST7789 driver configuration +uint8_t display_init_sequence[] = { + // Software reset + 0x01, 0 | DELAY, 150, + // Sleep out + 0x11, 0 | DELAY, 255, + // Tearing effect line on (frame sync) + 0x35, 1, 0x00, + // COLMOD: 16-bit color (5-6-5 RGB) + 0x3A, 1, 0x55, + // Porch control (PORCTRL) + 0xB2, 5, 0x0C, 0x0C, 0x00, 0x33, 0x33, + // Gate control (GCTRL) - VGH=13.26V, VGL=-10.43V + 0xB7, 1, 0x35, + // VCOM setting (VCOMS) + 0xBB, 1, 0x1F, + // LCM control (LCMCTRL) + 0xC0, 1, 0x2C, + // VDV and VRH command enable (VDVVRHEN) + 0xC2, 1, 0x01, + // VRH set (VRHS) + 0xC3, 1, 0x12, + // VDV set (VDVS) + 0xC4, 1, 0x20, + // Frame rate control (FRCTRL2) + 0xC6, 1, 0x0F, + // Power control 1 (PWCTRL1) + 0xD0, 2, 0xA4, 0xA1, + // RAM control (RAMCTRL) - for proper endianness + 0xB0, 2, 0x00, 0xC0, + // Positive gamma correction + 0xE0, 14, 0xD0, 0x08, 0x11, 0x08, 0x0C, 0x15, 0x39, 0x33, 0x50, 0x36, 0x13, 0x14, 0x29, 0x2D, + // Negative gamma correction + 0xE1, 14, 0xD0, 0x08, 0x10, 0x08, 0x06, 0x06, 0x39, 0x44, 0x51, 0x0B, 0x16, 0x14, 0x2F, 0x31, + // Inversion on + 0x21, 0, + // Normal display mode on + 0x13, 0 | DELAY, 10, + // MADCTL: MX=0, MY=1, MV=1, ML=1 (COL_ORDER | SWAP_XY | SCAN_ORDER) = 0x70 + // This configures the 320x240 display in landscape orientation + 0x36, 1, 0x70, + // Display on + 0x29, 0 | DELAY, 100, +}; + +static void display_init(void) { + paralleldisplaybus_parallelbus_obj_t *bus = &allocate_display_bus()->parallel_bus; + bus->base.type = ¶lleldisplaybus_parallelbus_type; + + common_hal_paralleldisplaybus_parallelbus_construct(bus, + &pin_GPIO32, // Data0 (D0) - data pins are sequential GPIO32-39 + &pin_GPIO28, // Command/Data (DC) + &pin_GPIO27, // Chip select (CS) + &pin_GPIO30, // Write (WR) + &pin_GPIO31, // Read (RD) + NULL, // Reset (directly connected to board reset) + 15000000); // Frequency - ST7789 min clock cycle ~66ns = ~15MHz + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct(display, + bus, + 320, // Width + 240, // Height + 0, // column start + 0, // row start + 0, // rotation + 16, // Color depth + false, // grayscale + false, // pixels_in_byte_share_row + 1, // bytes per cell + false, // reverse_pixels_in_byte + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO26, // Backlight pin (BL) + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Ensure backlight is on before display init + board_reset_pin_number(LCD_BACKLIGHT_PIN); + display_init(); +} + +// Prevent the backlight pin from being reset, keeping display visible across soft resets +bool board_reset_pin_number(uint8_t pin_number) { + if (pin_number == LCD_BACKLIGHT_PIN) { + // Keep backlight on - set high output without glitching + gpio_put(pin_number, 1); + gpio_set_dir(pin_number, GPIO_OUT); + gpio_set_function(pin_number, GPIO_FUNC_SIO); + return true; + } + return false; +} + +void reset_board(void) { + // Keep backlight on during reset + board_reset_pin_number(LCD_BACKLIGHT_PIN); +} + +void board_deinit(void) { + // Backlight will be handled by board_reset_pin_number +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_explorer2350/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_explorer2350/mpconfigboard.h new file mode 100644 index 00000000000..dd269aa6b84 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_explorer2350/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Pimoroni Explorer" +#define MICROPY_HW_MCU_NAME "rp2350b" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO21, .sda = &pin_GPIO20}} + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/pimoroni_explorer2350/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_explorer2350/mpconfigboard.mk new file mode 100644 index 00000000000..4409dbf57df --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_explorer2350/mpconfigboard.mk @@ -0,0 +1,13 @@ +USB_VID = 0x2E8A +USB_PID = 0x10C0 +USB_PRODUCT = "Explorer" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = B +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +# GPIO12-19 needed for picodvi, but several are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/pimoroni_explorer2350/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_explorer2350/pico-sdk-configboard.h new file mode 100644 index 00000000000..66b57dfd13d --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_explorer2350/pico-sdk-configboard.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_explorer2350/pins.c b/ports/raspberrypi/boards/pimoroni_explorer2350/pins.c new file mode 100644 index 00000000000..8154a43de00 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_explorer2350/pins.c @@ -0,0 +1,124 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // User GPIOs (accent connector) + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + // Servo pins + { MP_ROM_QSTR(MP_QSTR_SERVO1), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SERVO2), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SERVO3), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SERVO4), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + + // Audio + { MP_ROM_QSTR(MP_QSTR_AUDIO), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_AMP_EN), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + // Buttons + { MP_ROM_QSTR(MP_QSTR_SW_C), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SW_B), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_SW_X), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_SW_Y), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_SW_Z), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + // User button + { MP_ROM_QSTR(MP_QSTR_SW_USER), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + // LED? + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + // Display parallel bus pins (ST7789V 320x240) + // Pins from Pimoroni: {cs=27, dc=28, wr=30, rd=31, d0=32, bl=26} + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_LCD_WR), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_GP30), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RD), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_GP31), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D0), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_GP32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D1), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_GP33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D2), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_GP34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D3), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_GP35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D4), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GP36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D5), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_GP37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D6), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_GP38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_LCD_D7), MP_ROM_PTR(&pin_GPIO39) }, + { MP_ROM_QSTR(MP_QSTR_GP39), MP_ROM_PTR(&pin_GPIO39) }, + + // ADC pins (RP2350B extended GPIOs) + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_ADC0), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GP40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_ADC1), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_GP41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_ADC2), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_GP42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_ADC3), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_GP43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_ADC4), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_GP44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_ADC5), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_GP45), MP_ROM_PTR(&pin_GPIO45) }, + + // I2C object + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // Display object + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c index 650d307711e..58c54334d59 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/board.c @@ -58,47 +58,35 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO28, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO27, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO28), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO27), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 1.0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 600, // width - 448, // height - 640, // ram_width - 480, // ram_height - 0, // colstart - 0, // rowstart - 0, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x10, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - refresh_sequence, sizeof(refresh_sequence), - 28.0, // refresh_time - NULL, // busy_pin - false, // busy_state - 40.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - true, // acep - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 1.0; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 600; + args.height = 448; + args.ram_width = 640; + args.ram_height = 480; + args.write_black_ram_command = 0x10; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 28.0; + args.busy_pin = NULL; + args.seconds_per_frame = 40.0; + args.acep = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h index d2547cc1615..a8c404c4225 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.h @@ -14,8 +14,8 @@ #define MICROPY_HW_LED_STATUS (&pin_GPIO6) -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.mk index c0f67869a08..69b23a72be7 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_5_7/mpconfigboard.mk @@ -20,7 +20,17 @@ CIRCUITPY_WIFI = 1 CIRCUITPY_PICODVI = 0 CIRCUITPY_USB_HOST = 0 -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c index a24c91e546d..fc6ca67f3ae 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/board.c @@ -117,47 +117,36 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO28, // EPD_DC Command or data - &pin_GPIO17, // EPD_CS Chip select - &pin_GPIO27, // EPD_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO28), // EPD_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO17), // EPD_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO27), // EPD_RST Reset 1000000, // Baudrate 0, // Polarity 0); // Phase epaperdisplay_epaperdisplay_obj_t *display = &allocate_display()->epaper_display; display->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - display, - bus, - display_start_sequence, sizeof(display_start_sequence), - 1.0, // start up time - display_stop_sequence, sizeof(display_stop_sequence), - 800, // width - 480, // height - 800, // ram_width - 480, // ram_height - 0, // colstart - 0, // rowstart - 180, // rotation - NO_COMMAND, // set_column_window_command - NO_COMMAND, // set_row_window_command - NO_COMMAND, // set_current_column_command - NO_COMMAND, // set_current_row_command - 0x10, // write_black_ram_command - false, // black_bits_inverted - NO_COMMAND, // write_color_ram_command - false, // color_bits_inverted - 0x000000, // highlight_color - refresh_sequence, sizeof(refresh_sequence), - 28.0, // refresh_time - NULL, // busy_pin - false, // busy_state - 30.0, // seconds_per_frame - false, // always_toggle_chip_select - false, // grayscale - true, // acep - false, // two_byte_sequence_length - false); // address_little_endian + + epaperdisplay_construct_args_t args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + args.bus = bus; + args.start_sequence = display_start_sequence; + args.start_sequence_len = sizeof(display_start_sequence); + args.start_up_time = 1.0; + args.stop_sequence = display_stop_sequence; + args.stop_sequence_len = sizeof(display_stop_sequence); + args.width = 800; + args.height = 480; + args.ram_width = 800; + args.ram_height = 480; + args.rotation = 180; + args.write_black_ram_command = 0x10; + args.refresh_sequence = refresh_sequence; + args.refresh_sequence_len = sizeof(refresh_sequence); + args.refresh_time = 28.0; + args.busy_pin = NULL; + args.seconds_per_frame = 30.0; + args.acep = true; + common_hal_epaperdisplay_epaperdisplay_construct(display, &args); } // Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h index 42cb1196a54..32477b12c29 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.h @@ -14,8 +14,8 @@ #define MICROPY_HW_LED_STATUS (&pin_GPIO6) -#define DEFAULT_I2C_BUS_SCL (&pin_GPIO4) -#define DEFAULT_I2C_BUS_SDA (&pin_GPIO5) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) diff --git a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.mk index ca57f8419ef..ee04517499e 100644 --- a/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_inky_frame_7_3/mpconfigboard.mk @@ -20,7 +20,17 @@ CIRCUITPY_WIFI = 1 CIRCUITPY_PICODVI = 0 CIRCUITPY_USB_HOST = 0 -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/pimoroni_pico_dv_base_w/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_pico_dv_base_w/mpconfigboard.mk index a1ab3b2939e..02cbe3b69b7 100644 --- a/ports/raspberrypi/boards/pimoroni_pico_dv_base_w/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_pico_dv_base_w/mpconfigboard.mk @@ -19,8 +19,25 @@ CIRCUITPY_SOCKETPOOL = 1 CIRCUITPY_WIFI = 1 CIRCUITPY_PICODVI = 1 +CIRCUITPY_AUDIOEFFECTS = 0 +CIRCUITPY_AUDIOFILEWRITER = 0 +CIRCUITPY_BLEIO_HCI = 0 + +# No room: this board fills FLASH_FIRMWARE. Frees ~9kB. Not the board's I2S +# line-out/HDMI audio, which audiobusio still provides. +CIRCUITPY_USB_AUDIO = 0 + +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/pimoroni_pico_plus2/pins.c b/ports/raspberrypi/boards/pimoroni_pico_plus2/pins.c index 6c8345afe7e..1a8663d9a7e 100644 --- a/ports/raspberrypi/boards/pimoroni_pico_plus2/pins.c +++ b/ports/raspberrypi/boards/pimoroni_pico_plus2/pins.c @@ -61,17 +61,25 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO45) }, { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO45) }, - { MP_ROM_QSTR(MP_QSTR_SPICE_CS), MP_ROM_PTR(&pin_GPIO33) }, - { MP_ROM_QSTR(MP_QSTR_SPICE_SCK), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_SPCE_CS), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_GP33), MP_ROM_PTR(&pin_GPIO33) }, + + { MP_ROM_QSTR(MP_QSTR_SPCE_SCK), MP_ROM_PTR(&pin_GPIO34) }, { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO34) }, - { MP_ROM_QSTR(MP_QSTR_SPICE_TX), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_GP34), MP_ROM_PTR(&pin_GPIO34) }, + + { MP_ROM_QSTR(MP_QSTR_SPCE_MOSI), MP_ROM_PTR(&pin_GPIO35) }, { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO35) }, - { MP_ROM_QSTR(MP_QSTR_SPICE_RX), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_GP35), MP_ROM_PTR(&pin_GPIO35) }, + + { MP_ROM_QSTR(MP_QSTR_SPCE_MISO), MP_ROM_PTR(&pin_GPIO32) }, { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO32) }, - { MP_ROM_QSTR(MP_QSTR_SPICE_BL), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GP32), MP_ROM_PTR(&pin_GPIO32) }, + + { MP_ROM_QSTR(MP_QSTR_SPCE_BL), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GP36), MP_ROM_PTR(&pin_GPIO36) }, { MP_ROM_QSTR(MP_QSTR_TFT_BACKLIGHT), MP_ROM_PTR(&pin_GPIO36) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; diff --git a/ports/raspberrypi/boards/pimoroni_pico_plus2w/board.c b/ports/raspberrypi/boards/pimoroni_pico_plus2w/board.c new file mode 100644 index 00000000000..4878f16e66e --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_pico_plus2w/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_pico_plus2w/link.ld b/ports/raspberrypi/boards/pimoroni_pico_plus2w/link.ld new file mode 100644 index 00000000000..e814bead4c5 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_pico_plus2w/link.ld @@ -0,0 +1 @@ +firmware_size = 1532k; diff --git a/ports/raspberrypi/boards/pimoroni_pico_plus2w/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_pico_plus2w/mpconfigboard.h new file mode 100644 index 00000000000..28f19c762f1 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_pico_plus2w/mpconfigboard.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Pimoroni Pico Plus 2 W" +#define MICROPY_HW_MCU_NAME "rp2350b" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +#define MICROPY_HW_LED_STATUS (&pin_CYW0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} + +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO47) diff --git a/ports/raspberrypi/boards/pimoroni_pico_plus2w/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_pico_plus2w/mpconfigboard.mk new file mode 100644 index 00000000000..b06c1246d35 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_pico_plus2w/mpconfigboard.mk @@ -0,0 +1,37 @@ +USB_VID = 0x2E8A +USB_PID = 0x10BD +USB_PRODUCT = "Pico Plus 2 W" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = B +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +# PIO clock divider set to 2 (default), consider changing if TM2 gSPI +# becomes unreliable. +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 \ + -DCYW43_PIO_CLOCK_DIV_INT=2 \ + -DCYW43_PIO_CLOCK_DIV_FRAC=0 +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/pimoroni_pico_plus2w/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_pico_plus2w/pico-sdk-configboard.h new file mode 100644 index 00000000000..42e0612bf8b --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_pico_plus2w/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_pico_plus2w/pins.c b/ports/raspberrypi/boards/pimoroni_pico_plus2w/pins.c new file mode 100644 index 00000000000..718e9b97813 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_pico_plus2w/pins.c @@ -0,0 +1,76 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + // GP23, GP24, GP25, and GP29 are reserved for RM2 gSPI + + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + + // GP30 through GP39 are unconnected + + // GP40 through GP47 have analog input capability + { MP_ROM_QSTR(MP_QSTR_GP40_A0), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_GP40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_GP41_A1), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_GP41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_GP42_A2), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_GP42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO43) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO43) }, + + // GP44 is unconnected + + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO45) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO45) }, + + // GP46 is unconnected + // GP47 is reserved for PSRAM chip select + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // Pins accessed though the RM2 module (CYW43439) + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_CYW0) }, + // CYW1 is unconnected + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_CYW2) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/pimoroni_picosystem/board.c b/ports/raspberrypi/boards/pimoroni_picosystem/board.c index 40756b56426..e5956e43ed1 100644 --- a/ports/raspberrypi/boards/pimoroni_picosystem/board.c +++ b/ports/raspberrypi/boards/pimoroni_picosystem/board.c @@ -51,9 +51,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO9, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO4, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_RST Reset 60000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/pimoroni_plasma2040w/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_plasma2040w/mpconfigboard.mk index 26a0ab6f832..442991fa126 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2040w/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_plasma2040w/mpconfigboard.mk @@ -20,7 +20,17 @@ CIRCUITPY_WIFI = 1 CIRCUITPY_PICODVI = 0 CIRCUITPY_USB_HOST = 0 -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h index 72b1e1d0439..097cbd8baa3 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h +++ b/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.h @@ -5,7 +5,7 @@ // SPDX-License-Identifier: MIT #define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2350" -#define MICROPY_HW_MCU_NAME "rp2350b" +#define MICROPY_HW_MCU_NAME "rp2350a" #define CIRCUITPY_RGB_STATUS_INVERTED_PWM #define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.mk index 56fd7b641de..52dcd3fbe71 100644 --- a/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_plasma2350/mpconfigboard.mk @@ -10,3 +10,6 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350w/board.c b/ports/raspberrypi/boards/pimoroni_plasma2350w/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2350w/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350w/link.ld b/ports/raspberrypi/boards/pimoroni_plasma2350w/link.ld new file mode 100644 index 00000000000..d1edd9567c5 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2350w/link.ld @@ -0,0 +1 @@ +firmware_size = 3064k; diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h b/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h new file mode 100644 index 00000000000..576299d939c --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.h @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Pimoroni Plasma 2350W" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define CIRCUITPY_RGB_STATUS_INVERTED_PWM +#define CIRCUITPY_RGB_STATUS_R (&pin_GPIO16) +#define CIRCUITPY_RGB_STATUS_G (&pin_GPIO17) +#define CIRCUITPY_RGB_STATUS_B (&pin_GPIO18) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO21, .sda = &pin_GPIO20}} + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO21) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO20) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO10) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO11) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.mk new file mode 100644 index 00000000000..cab35965a0f --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2350w/mpconfigboard.mk @@ -0,0 +1,38 @@ +USB_VID = 0x2E8A +USB_PID = 0x10BF +USB_PRODUCT = "Plasma 2350 W" +USB_MANUFACTURER = "Pimoroni" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 +CIRCUITPY_PICODVI = 0 +CIRCUITPY_USB_HOST = 0 + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 + +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(3064 * 1024)' diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350w/pico-sdk-configboard.h b/ports/raspberrypi/boards/pimoroni_plasma2350w/pico-sdk-configboard.h new file mode 100644 index 00000000000..66b57dfd13d --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2350w/pico-sdk-configboard.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/pimoroni_plasma2350w/pins.c b/ports/raspberrypi/boards/pimoroni_plasma2350w/pins.c new file mode 100644 index 00000000000..e49812ba803 --- /dev/null +++ b/ports/raspberrypi/boards/pimoroni_plasma2350w/pins.c @@ -0,0 +1,78 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + // GPIO2 through GPIO11 are unconnected + + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_SW_A), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO12) }, + + // GPIO13 is unconnected + + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_DATA), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_INT), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_SW_BOOT), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_USER_SW), MP_ROM_PTR(&pin_GPIO22) }, + + // GPIO23 through GPIO25 are connected to the RM2 module + + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + // GPIO29 is connected to the RM2 module + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/pimoroni_tiny2350/mpconfigboard.mk b/ports/raspberrypi/boards/pimoroni_tiny2350/mpconfigboard.mk index 9ffdf263003..b94022c1f6d 100644 --- a/ports/raspberrypi/boards/pimoroni_tiny2350/mpconfigboard.mk +++ b/ports/raspberrypi/boards/pimoroni_tiny2350/mpconfigboard.mk @@ -10,3 +10,6 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but several are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/proveskit_rp2040_v4/board.c b/ports/raspberrypi/boards/proveskit_rp2040_v4/board.c new file mode 100644 index 00000000000..6dc59205e4e --- /dev/null +++ b/ports/raspberrypi/boards/proveskit_rp2040_v4/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "common-hal/microcontroller/Pin.h" diff --git a/ports/raspberrypi/boards/proveskit_rp2040_v4/mpconfigboard.h b/ports/raspberrypi/boards/proveskit_rp2040_v4/mpconfigboard.h new file mode 100644 index 00000000000..4c2f9a93b07 --- /dev/null +++ b/ports/raspberrypi/boards/proveskit_rp2040_v4/mpconfigboard.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "PROVES Kit v4" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO24) + +#define CIRCUITPY_DRIVE_LABEL "PROVESKIT" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO3) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO2) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO10) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO8) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO11) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/proveskit_rp2040_v4/mpconfigboard.mk b/ports/raspberrypi/boards/proveskit_rp2040_v4/mpconfigboard.mk new file mode 100644 index 00000000000..7ae012032f7 --- /dev/null +++ b/ports/raspberrypi/boards/proveskit_rp2040_v4/mpconfigboard.mk @@ -0,0 +1,9 @@ +USB_VID = 0x1209 +USB_PID = 0xE004 +USB_PRODUCT = "ProvesKit RP2040 v4" +USB_MANUFACTURER = "Bronco Space" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "GD25Q64C,W25Q64JVxQ" diff --git a/ports/raspberrypi/boards/proveskit_rp2040_v4/pico-sdk-configboard.h b/ports/raspberrypi/boards/proveskit_rp2040_v4/pico-sdk-configboard.h new file mode 100644 index 00000000000..d109816d138 --- /dev/null +++ b/ports/raspberrypi/boards/proveskit_rp2040_v4/pico-sdk-configboard.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/proveskit_rp2040_v4/pins.c b/ports/raspberrypi/boards/proveskit_rp2040_v4/pins.c new file mode 100644 index 00000000000..cb3861010fc --- /dev/null +++ b/ports/raspberrypi/boards/proveskit_rp2040_v4/pins.c @@ -0,0 +1,55 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "supervisor/board.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_SPI0_CS1), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_NEO_PWR), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_CS2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_I2C1_SDA), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_I2C1_SCL), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_I2C0_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_I2C0_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_PC), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_VS), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_MISO), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_CS0), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_SPI0_SCK), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_SPI0_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_RF1_RST), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_WDT_WDI), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_RF1_IO4), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_RF1_IO0), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIX), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_HS), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/raspberry_pi_pico2_w/board.c b/ports/raspberrypi/boards/raspberry_pi_pico2_w/board.c new file mode 100644 index 00000000000..299f32da04f --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico2_w/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/raspberry_pi_pico2_w/link.ld b/ports/raspberrypi/boards/raspberry_pi_pico2_w/link.ld new file mode 100644 index 00000000000..e814bead4c5 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico2_w/link.ld @@ -0,0 +1 @@ +firmware_size = 1532k; diff --git a/ports/raspberrypi/boards/raspberry_pi_pico2_w/mpconfigboard.h b/ports/raspberrypi/boards/raspberry_pi_pico2_w/mpconfigboard.h new file mode 100644 index 00000000000..4f13dd13efc --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico2_w/mpconfigboard.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico 2 W" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +#define MICROPY_HW_LED_STATUS (&pin_CYW0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/raspberrypi/boards/raspberry_pi_pico2_w/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico2_w/mpconfigboard.mk new file mode 100644 index 00000000000..e1407c16854 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico2_w/mpconfigboard.mk @@ -0,0 +1,35 @@ +USB_VID = 0x239A +USB_PID = 0x8162 +USB_PRODUCT = "Pico 2 W" +USB_MANUFACTURER = "Raspberry Pi" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 \ + -DCYW43_PIO_CLOCK_DIV_INT=3 + +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/raspberry_pi_pico2_w/pico-sdk-configboard.h b/ports/raspberrypi/boards/raspberry_pi_pico2_w/pico-sdk-configboard.h new file mode 100644 index 00000000000..945802d1ab1 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico2_w/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/raspberry_pi_pico2_w/pins.c b/ports/raspberrypi/boards/raspberry_pi_pico2_w/pins.c new file mode 100644 index 00000000000..7ec6b409724 --- /dev/null +++ b/ports/raspberrypi/boards/raspberry_pi_pico2_w/pins.c @@ -0,0 +1,59 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_CYW1) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_CYW0) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_CYW2) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk index 157c0eb03be..e658db65f4d 100644 --- a/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk +++ b/ports/raspberrypi/boards/raspberry_pi_pico_w/mpconfigboard.mk @@ -21,6 +21,16 @@ CIRCUITPY_SOCKETPOOL = 1 CIRCUITPY_WIFI = 1 -CFLAGS += -DCYW43_PIN_WL_HOST_WAKE=24 -DCYW43_PIN_WL_REG_ON=23 -DCYW43_WL_GPIO_COUNT=3 -DCYW43_WL_GPIO_LED_PIN=0 +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + # Must be accompanied by a linker script change CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/seeeduino_xiao_rp2350/mpconfigboard.mk b/ports/raspberrypi/boards/seeeduino_xiao_rp2350/mpconfigboard.mk index d5f866bd89e..f51d5271215 100644 --- a/ports/raspberrypi/boards/seeeduino_xiao_rp2350/mpconfigboard.mk +++ b/ports/raspberrypi/boards/seeeduino_xiao_rp2350/mpconfigboard.mk @@ -8,3 +8,6 @@ CHIP_PACKAGE = A CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "P25Q16H" + +# GPIO12-19 needed for picodvi, but several are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/sparkfun_pro_micro_rp2350/mpconfigboard.mk b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2350/mpconfigboard.mk index e5d6e1b8ff8..53cdf72963f 100644 --- a/ports/raspberrypi/boards/sparkfun_pro_micro_rp2350/mpconfigboard.mk +++ b/ports/raspberrypi/boards/sparkfun_pro_micro_rp2350/mpconfigboard.mk @@ -8,3 +8,6 @@ CHIP_PACKAGE = A CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/board.c b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/link.ld b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/link.ld new file mode 100644 index 00000000000..e814bead4c5 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/link.ld @@ -0,0 +1 @@ +firmware_size = 1532k; diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/mpconfigboard.h b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/mpconfigboard.h new file mode 100644 index 00000000000..86891e2dca5 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/mpconfigboard.h @@ -0,0 +1,27 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "SparkFun Thing Plus RP2350" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO14) + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO7) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO6) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO2) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO3) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO4) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO8) + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +#define MICROPY_HW_LED_STATUS (&pin_CYW0) diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/mpconfigboard.mk b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/mpconfigboard.mk new file mode 100644 index 00000000000..81d7f660473 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/mpconfigboard.mk @@ -0,0 +1,41 @@ +USB_VID = 0x1B4F +USB_PID = 0x0038 +USB_PRODUCT = "Thing Plus RP2350" +USB_MANUFACTURER = "SparkFun" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel/ + +CIRCUITPY_USB_HOST = 0 + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +# GPIO12-19 needed for picodvi, but GPIO14 is used for a NeoPixel. +CIRCUITPY_PICODVI = 0 + +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 + +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/pico-sdk-configboard.h b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/pico-sdk-configboard.h new file mode 100644 index 00000000000..2d9283a9192 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/pico-sdk-configboard.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/pins.c b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/pins.c new file mode 100644 index 00000000000..3710272e1f0 --- /dev/null +++ b/ports/raspberrypi/boards/sparkfun_thing_plus_rp2350/pins.c @@ -0,0 +1,65 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_CYW0) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_CYW2) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/studiolab_picoexpander/board.c b/ports/raspberrypi/boards/studiolab_picoexpander/board.c new file mode 100644 index 00000000000..299f32da04f --- /dev/null +++ b/ports/raspberrypi/boards/studiolab_picoexpander/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/studiolab_picoexpander/link.ld b/ports/raspberrypi/boards/studiolab_picoexpander/link.ld new file mode 100644 index 00000000000..e814bead4c5 --- /dev/null +++ b/ports/raspberrypi/boards/studiolab_picoexpander/link.ld @@ -0,0 +1 @@ +firmware_size = 1532k; diff --git a/ports/raspberrypi/boards/studiolab_picoexpander/mpconfigboard.h b/ports/raspberrypi/boards/studiolab_picoexpander/mpconfigboard.h new file mode 100644 index 00000000000..ea475f68222 --- /dev/null +++ b/ports/raspberrypi/boards/studiolab_picoexpander/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Studiolab Pico Expander" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE (1) + +#define MICROPY_HW_LED_STATUS (&pin_CYW0) +#define MICROPY_HW_NEOPIXEL (&pin_GPIO2) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = &pin_GPIO16}} diff --git a/ports/raspberrypi/boards/studiolab_picoexpander/mpconfigboard.mk b/ports/raspberrypi/boards/studiolab_picoexpander/mpconfigboard.mk new file mode 100644 index 00000000000..7214b36da28 --- /dev/null +++ b/ports/raspberrypi/boards/studiolab_picoexpander/mpconfigboard.mk @@ -0,0 +1,38 @@ +USB_VID = 0x1209 +USB_PID = 0xC1C1 +USB_PRODUCT = "StudioLab Pico Expander" +USB_MANUFACTURER = "Raspberry Pi" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 + +CIRCUITPY_CYW43 = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_HASHLIB = 1 +CIRCUITPY_WEB_WORKFLOW = 1 +CIRCUITPY_MDNS = 1 +CIRCUITPY_SOCKETPOOL = 1 +CIRCUITPY_WIFI = 1 + +# GPIO12-19 needed for picodvi, but GPIO15 is used for a button. +CIRCUITPY_PICODVI = 0 + +CFLAGS += \ + -DCYW43_PIN_WL_DYNAMIC=0 \ + -DCYW43_DEFAULT_PIN_WL_HOST_WAKE=24 \ + -DCYW43_DEFAULT_PIN_WL_REG_ON=23 \ + -DCYW43_DEFAULT_PIN_WL_CLOCK=29 \ + -DCYW43_DEFAULT_PIN_WL_DATA_IN=24 \ + -DCYW43_DEFAULT_PIN_WL_DATA_OUT=24 \ + -DCYW43_DEFAULT_PIN_WL_CS=25 \ + -DCYW43_WL_GPIO_COUNT=3 \ + -DCYW43_WL_GPIO_LED_PIN=0 \ + -DCYW43_PIO_CLOCK_DIV_INT=3 + +# Must be accompanied by a linker script change +CFLAGS += -DCIRCUITPY_FIRMWARE_SIZE='(1536 * 1024)' diff --git a/ports/raspberrypi/boards/studiolab_picoexpander/pico-sdk-configboard.h b/ports/raspberrypi/boards/studiolab_picoexpander/pico-sdk-configboard.h new file mode 100644 index 00000000000..945802d1ab1 --- /dev/null +++ b/ports/raspberrypi/boards/studiolab_picoexpander/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/studiolab_picoexpander/pins.c b/ports/raspberrypi/boards/studiolab_picoexpander/pins.c new file mode 100644 index 00000000000..6faafbfd177 --- /dev/null +++ b/ports/raspberrypi/boards/studiolab_picoexpander/pins.c @@ -0,0 +1,113 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + + { MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_BTN), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_A26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_A27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_A28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_CYW1) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_CYW0) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_CYW2) }, + + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/teenage_engineering_ep2350/board.c b/ports/raspberrypi/boards/teenage_engineering_ep2350/board.c new file mode 100644 index 00000000000..982ebb6deb1 --- /dev/null +++ b/ports/raspberrypi/boards/teenage_engineering_ep2350/board.c @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +#include "mpconfigboard.h" +#include "common-hal/microcontroller/Pin.h" +#include "hardware/gpio.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. + +static void assert_power_hold(void) { + // Doing this (rather than gpio_init()) in this specific order ensures no + // glitch if the pin was already configured as a high output. gpio_init() + // temporarily configures the pin as an input, which would release the + // latch and power the board off. + gpio_put(MICROPY_HW_POWER_HOLD_PIN_NUMBER, 1); + gpio_set_dir(MICROPY_HW_POWER_HOLD_PIN_NUMBER, GPIO_OUT); + gpio_set_function(MICROPY_HW_POWER_HOLD_PIN_NUMBER, GPIO_FUNC_SIO); +} + +// Forward declaration to satisfy -Wmissing-prototypes +static void preinit_power_hold(void) __attribute__((constructor(101))); + +// Runs before main(), so the latch is set as early as it can possibly be. +static void preinit_power_hold(void) { + assert_power_hold(); +} + +// The EP-2350 has no power switch: pressing the handle applies power directly, +// and firmware must set the power hold latch on GPIO2 before the handle is +// released or the unit dies. The latch is a true set/reset latch, so a single +// high pulse is enough, but the pin must never be left low. +// +// reset_all_pins() runs this for every pin at startup and again on every soft +// reload, so the latch is re-asserted instead of being reset to an input. The +// pin is deliberately not claimed with never_reset(), so user code can still +// take board.POWER_HOLD and drive it low to power the unit off. +bool board_reset_pin_number(uint8_t pin_number) { + if (pin_number == MICROPY_HW_POWER_HOLD_PIN_NUMBER) { + assert_power_hold(); + return true; + } + return false; +} diff --git a/ports/raspberrypi/boards/teenage_engineering_ep2350/mpconfigboard.h b/ports/raspberrypi/boards/teenage_engineering_ep2350/mpconfigboard.h new file mode 100644 index 00000000000..fc3ad16bdc2 --- /dev/null +++ b/ports/raspberrypi/boards/teenage_engineering_ep2350/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "Teenage Engineering ting fx EP-2350" +#define MICROPY_HW_MCU_NAME "rp2350a" + +// Top white LED. Also available as board.LED_WHITE1. +#define MICROPY_HW_LED_STATUS (&pin_GPIO0) + +// GPIO2 is the power hold latch: high keeps the unit powered, low powers it +// off immediately. It is asserted in board_reset_pin_number() so that it +// survives every pin reset. +#define MICROPY_HW_POWER_HOLD_PIN_NUMBER (2) + +// Codec (0x1b) and accelerometer (0x18) share I2C1. External pull-ups. +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO15, .sda = &pin_GPIO14}} diff --git a/ports/raspberrypi/boards/teenage_engineering_ep2350/mpconfigboard.mk b/ports/raspberrypi/boards/teenage_engineering_ep2350/mpconfigboard.mk new file mode 100644 index 00000000000..704edf815e6 --- /dev/null +++ b/ports/raspberrypi/boards/teenage_engineering_ep2350/mpconfigboard.mk @@ -0,0 +1,20 @@ +USB_VID = 0x239A +USB_PID = 0x8176 +USB_PRODUCT = "ting fx EP-2350" +USB_MANUFACTURER = "Teenage Engineering" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +# Winbond W25Q16JV, 2MB (16Mbit) on CS0, nothing on CS1. +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +# Only 2MB of flash: firmware gets the default 1020kB and the CIRCUITPY drive +# gets the rest (~1MB). + +# GPIO12-19 are needed for picodvi, but they are all in use here (I2S, I2C, +# LEDs, handle switches) and no pins are broken out. +CIRCUITPY_PICODVI = 0 + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/teenage_engineering_ep2350/pico-sdk-configboard.h b/ports/raspberrypi/boards/teenage_engineering_ep2350/pico-sdk-configboard.h new file mode 100644 index 00000000000..f72de7902c9 --- /dev/null +++ b/ports/raspberrypi/boards/teenage_engineering_ep2350/pico-sdk-configboard.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/teenage_engineering_ep2350/pins.c b/ports/raspberrypi/boards/teenage_engineering_ep2350/pins.c new file mode 100644 index 00000000000..ed448aa4def --- /dev/null +++ b/ports/raspberrypi/boards/teenage_engineering_ep2350/pins.c @@ -0,0 +1,118 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // LEDs, one dedicated GPIO each, active high. + // Two columns of four, numbered top (nearest the handle) to bottom. + // Note: GP0 and GP16 share a PWM slice/channel, so the their LEDs + // cannot be PWM-dimmed independently. + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LED_WHITE1), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_LED_WHITE2), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_LED_WHITE3), MP_ROM_PTR(&pin_GPIO4) }, + + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_LED_WHITE4), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_LED_RED1), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_LED_RED2), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_LED_RED3), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_LED_RED4), MP_ROM_PTR(&pin_GPIO17) }, + + // Side buttons. Switches to ground, no external pull-ups: use Pull.UP, + // pressed reads False. + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_TOP), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_MIDDLE), MP_ROM_PTR(&pin_GPIO3) }, + + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_BOTTOM), MP_ROM_PTR(&pin_GPIO1) }, + + // Handle: a two-stage switch. HANDLE_IN reads False when the handle is + // fully seated; HANDLE_OUT reads True as soon as the handle is moved. + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_HANDLE_IN), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_HANDLE_OUT), MP_ROM_PTR(&pin_GPIO20) }, + + // Power hold latch. Held high by the board so the unit stays powered once + // the handle is released. Driving it low powers the unit off immediately. + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_POWER_HOLD), MP_ROM_PTR(&pin_GPIO2) }, + + // I2C1: NAU88L21 codec at 0x1b, accelerometer at 0x18. External pull-ups. + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO14) }, + + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO15) }, + + // I2S to the codec. The codec is the I2S clock source (it drives BCLK and + // LRCLK); the MCU only supplies MCLK. + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DIN), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_I2S_DOUT), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_I2S_WS), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_I2S_BIT_CLOCK), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_I2S_MCLK), MP_ROM_PTR(&pin_GPIO12) }, + + // Unidentified / unconnected. + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + // Analog. GP26/GP27 are unconnected. + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + // Handle position potentiometer: how far the handle has been pressed in. + // Continuous and monotonic over the travel, but it only swings across a + // narrow part of the range, roughly 32370 counts (1.63 V) with the + // handle at rest down to 29850 counts + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_HANDLE_POSITION), MP_ROM_PTR(&pin_GPIO28) }, + + // Volume potentiometer wiper, full scale 0 - 3.3V. + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLUME), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/tinycircuits_thumby/board.c b/ports/raspberrypi/boards/tinycircuits_thumby/board.c new file mode 100644 index 00000000000..3a306b35f0d --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby/board.c @@ -0,0 +1,81 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" + +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + + +uint8_t display_init_sequence[] = { + 0xAE, 0, // DISPLAY_OFF + 0x20, 1, 0x00, // Set memory addressing to horizontal mode. + 0x81, 1, 0xcf, // set contrast control + 0xA1, 0, // Column 127 is segment 0 + 0xA6, 0, // Normal display + 0xc8, 0, // Normal display + 0xA8, 1, 0x3f, // Mux ratio is 1/64 + 0xd5, 1, 0x80, // Set divide ratio + 0xd9, 1, 0xf1, // Set pre-charge period + 0xda, 1, 0x12, // Set com configuration + 0xdb, 1, 0x40, // Set vcom configuration + 0x8d, 1, 0x14, // Enable charge pump + 0xAF, 0, // DISPLAY_ON +}; + +void board_init(void) { + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + bus->base.type = &fourwire_fourwire_type; + common_hal_fourwire_fourwire_construct(bus, + spi, + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_OLED_DC), // Command or data + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_OLED_CS), // Chip select + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_OLED_RESET), // Reset + 10000000, // Baudrate + 0, // Polarity + 0); // Phase + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 72, // Width (after rotation) + 40, // Height (after rotation) + 28, // column start + 28, // row start + 0, // rotation + 1, // Color depth + true, // grayscale + false, // pixels in byte share row. only used for depth < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + 0x21, // Set column command + 0x22, // Set row command + 44, // Write memory command + display_init_sequence, + sizeof(display_init_sequence), + NULL, // backlight pin + 0x81, + 1.0f, // brightness + true, // single_byte_bounds + true, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 0); // backlight pwm frequency +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/tinycircuits_thumby/mpconfigboard.h b/ports/raspberrypi/boards/tinycircuits_thumby/mpconfigboard.h new file mode 100644 index 00000000000..cec0fc10f55 --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "TinyCircuits Thumby" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) + +#define CIRCUITPY_BOARD_OLED_DC (&pin_GPIO17) +#define CIRCUITPY_BOARD_OLED_CS (&pin_GPIO16) +#define CIRCUITPY_BOARD_OLED_RESET (&pin_GPIO20) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = DEFAULT_SPI_BUS_SCK, .mosi = DEFAULT_SPI_BUS_MOSI, .miso = NULL}} diff --git a/ports/raspberrypi/boards/tinycircuits_thumby/mpconfigboard.mk b/ports/raspberrypi/boards/tinycircuits_thumby/mpconfigboard.mk new file mode 100644 index 00000000000..d8140e6cb0a --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x1209 +USB_PID = 0x3500 +USB_PRODUCT = "Thumby" +USB_MANUFACTURER = "TinyCircuits" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" + +CIRCUITPY_STAGE = 1 +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_AUDIOPWMIO = 1 +CIRCUITPY_KEYPAD = 1 + +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_framebuf +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_SSD1306 +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 diff --git a/ports/raspberrypi/boards/tinycircuits_thumby/pico-sdk-configboard.h b/ports/raspberrypi/boards/tinycircuits_thumby/pico-sdk-configboard.h new file mode 100644 index 00000000000..ce5a7645b4e --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby/pico-sdk-configboard.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. + +// Allow extra time for xosc to start. +#define PICO_XOSC_STARTUP_DELAY_MULTIPLIER 64 diff --git a/ports/raspberrypi/boards/tinycircuits_thumby/pins.c b/ports/raspberrypi/boards/tinycircuits_thumby/pins.c new file mode 100644 index 00000000000..0a087bb8db8 --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby/pins.c @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Link Cable (ASR00074) + { MP_ROM_QSTR(MP_QSTR_EXT_TX), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_EXT), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_EXT_PU), MP_ROM_PTR(&pin_GPIO1) }, + + // 0.42 inch OLED AST1042 + { MP_ROM_QSTR(MP_QSTR_OLED_CS), MP_ROM_PTR(CIRCUITPY_BOARD_OLED_CS) }, + { MP_ROM_QSTR(MP_QSTR_OLED_DC), MP_ROM_PTR(CIRCUITPY_BOARD_OLED_DC) }, + { MP_ROM_QSTR(MP_QSTR_OLED_RESET), MP_ROM_PTR(CIRCUITPY_BOARD_OLED_RESET) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(DEFAULT_SPI_BUS_SCK) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(DEFAULT_SPI_BUS_MOSI) }, + + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display)}, + + // Buttons + { MP_ROM_QSTR(MP_QSTR_BUTTON_LEFT), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_UP), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_RIGHT), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_DOWN), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_1), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_2), MP_ROM_PTR(&pin_GPIO27) }, + + // Mono PWM Speaker + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO28) }, + + // Hardware revision ID pins + { MP_OBJ_NEW_QSTR(MP_QSTR_ID3), MP_ROM_PTR(&pin_GPIO12) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ID2), MP_ROM_PTR(&pin_GPIO13) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ID1), MP_ROM_PTR(&pin_GPIO14) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ID0), MP_ROM_PTR(&pin_GPIO15) }, + + // Power pins + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO26) } +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/tinycircuits_thumby_color/board.c b/ports/raspberrypi/boards/tinycircuits_thumby_color/board.c new file mode 100644 index 00000000000..17c512cb2a6 --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby_color/board.c @@ -0,0 +1,108 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/fourwire/FourWire.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + + +#define DELAY 0x80 + +// display init sequence according to TinyCircuits-Tiny-Game-Engine +uint8_t display_init_sequence[] = { + 0xFE, 0, // inter register enable 1 + 0xEF, 0, // inter register enable 2 + 0xB0, 1, 0xC0, + 0xB1, 1, 0x80, + 0xB2, 1, 0x2F, + 0xB3, 1, 0x03, + 0xB7, 1, 0x01, + 0xB6, 1, 0x19, + 0xAC, 1, 0xC8, // Complement Principle of RGB 5, 6, 5 + 0xAB, 1, 0x0f, // ? + 0x3A, 1, 0x05, // COLMOD: Pixel Format Set + 0xB4, 1, 0x04, // ? + 0xA8, 1, 0x07, // Frame Rate Set + 0xB8, 1, 0x08, // ? + 0xE7, 1, 0x5A, // VREG_CTL + 0xE8, 1, 0x23, // VGH_SET + 0xE9, 1, 0x47, // VGL_SET + 0xEA, 1, 0x99, // VGH_VGL_CLK + 0xC6, 1, 0x30, // ? + 0xC7, 1, 0x1F, // ? + 0xF0, 14, 0x05, 0x1D, 0x51, 0x2F, 0x85, 0x2A, 0x11, 0x62, 0x00, 0x07, 0x07, 0x0F, 0x08, 0x1F, // SET_GAMMA1 + 0xF1, 14, 0x2E, 0x41, 0x62, 0x56, 0xA5, 0x3A, 0x3f, 0x60, 0x0F, 0x07, 0x0A, 0x18, 0x18, 0x1D, // SET_GAMMA2 + 0x11, 0 | DELAY, 120, + 0x29, 0 | DELAY, 10, // display on +}; + +void board_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct( + spi, + DEFAULT_SPI_BUS_SCK, // CLK + DEFAULT_SPI_BUS_MOSI, // MOSI + NULL, // MISO not connected + false // Not half-duplex + ); + + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_LCD_DC), // DC + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_LCD_CS), // CS + MP_OBJ_FROM_PTR(CIRCUITPY_BOARD_LCD_RESET), // RST + 80000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 128, // width (after rotation) + 128, // height (after rotation) + 0, // column start + 0, // row start + 0, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + CIRCUITPY_BOARD_LCD_BACKLIGHT, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void reset_board(void) { +} diff --git a/ports/raspberrypi/boards/tinycircuits_thumby_color/mpconfigboard.h b/ports/raspberrypi/boards/tinycircuits_thumby_color/mpconfigboard.h new file mode 100644 index 00000000000..fc76138bb8a --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby_color/mpconfigboard.h @@ -0,0 +1,27 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "TinyCircuits Thumby Color" +#define MICROPY_HW_MCU_NAME "rp2350" + +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO9) +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO8) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = DEFAULT_I2C_BUS_SCL, .sda = DEFAULT_I2C_BUS_SDA}} + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) + +#define CIRCUITPY_BOARD_LCD_DC (&pin_GPIO16) +#define CIRCUITPY_BOARD_LCD_CS (&pin_GPIO17) +#define CIRCUITPY_BOARD_LCD_RESET (&pin_GPIO4) +#define CIRCUITPY_BOARD_LCD_BACKLIGHT (&pin_GPIO7) + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = DEFAULT_SPI_BUS_SCK, .mosi = DEFAULT_SPI_BUS_MOSI, .miso = NULL}} diff --git a/ports/raspberrypi/boards/tinycircuits_thumby_color/mpconfigboard.mk b/ports/raspberrypi/boards/tinycircuits_thumby_color/mpconfigboard.mk new file mode 100644 index 00000000000..6159a39ba55 --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby_color/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x1209 +USB_PID = 0x3501 +USB_PRODUCT = "Thumby Color" +USB_MANUFACTURER = "TinyCircuits" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY_STAGE = 1 +CIRCUITPY_AUDIOIO = 1 +CIRCUITPY_AUDIOPWMIO = 1 +CIRCUITPY_KEYPAD = 1 + +# GPIO12-19 needed for picodvi, but many are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/tinycircuits_thumby_color/pico-sdk-configboard.h b/ports/raspberrypi/boards/tinycircuits_thumby_color/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby_color/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/tinycircuits_thumby_color/pins.c b/ports/raspberrypi/boards/tinycircuits_thumby_color/pins.c new file mode 100644 index 00000000000..d0e63512d7a --- /dev/null +++ b/ports/raspberrypi/boards/tinycircuits_thumby_color/pins.c @@ -0,0 +1,58 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // Buttons + { MP_ROM_QSTR(MP_QSTR_BUTTON_UP), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_LEFT), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_DOWN), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_RIGHT), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_A), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_B), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_BUMPER_LEFT), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_BUMPER_RIGHT), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_MENU), MP_ROM_PTR(&pin_GPIO26) }, + + // LED + { MP_ROM_QSTR(MP_QSTR_LED_R), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LED_G), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LED_B), MP_ROM_PTR(&pin_GPIO12) }, + + // Rumble + { MP_ROM_QSTR(MP_QSTR_RUMBLE), MP_ROM_PTR(&pin_GPIO5) }, + + // Mono PWM Speaker + { MP_ROM_QSTR(MP_QSTR_SPEAKER), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_SPEAKER_ENABLE), MP_ROM_PTR(&pin_GPIO20) }, + + // 0.85 inch TFT GC9107 + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(CIRCUITPY_BOARD_LCD_CS) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(CIRCUITPY_BOARD_LCD_DC) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RESET), MP_ROM_PTR(CIRCUITPY_BOARD_LCD_RESET) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(CIRCUITPY_BOARD_LCD_BACKLIGHT) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SCK), MP_ROM_PTR(DEFAULT_SPI_BUS_SCK) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(DEFAULT_SPI_BUS_MOSI) }, + + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_spi_obj) }, + + // RTC I2C + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(DEFAULT_I2C_BUS_SDA) }, + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(DEFAULT_I2C_BUS_SCL) }, + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // Power pins + { MP_ROM_QSTR(MP_QSTR_CHARGE_STAT), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/ugame22/board.c b/ports/raspberrypi/boards/ugame22/board.c index a208326a094..ed17a13ebc1 100644 --- a/ports/raspberrypi/boards/ugame22/board.c +++ b/ports/raspberrypi/boards/ugame22/board.c @@ -7,7 +7,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/fourwire/FourWire.h" @@ -52,9 +52,9 @@ void board_init(void) { bus->base.type = &fourwire_fourwire_type; common_hal_fourwire_fourwire_construct(bus, spi, - &pin_GPIO4, // TFT_DC Command or data - &pin_GPIO5, // TFT_CS Chip select - &pin_GPIO1, // TFT_RST Reset + MP_OBJ_FROM_PTR(&pin_GPIO4), // TFT_DC Command or data + MP_OBJ_FROM_PTR(&pin_GPIO5), // TFT_CS Chip select + MP_OBJ_FROM_PTR(&pin_GPIO1), // TFT_RST Reset 80000000L, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c b/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c index 71269f0d185..431840fb0c5 100644 --- a/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2040_geek/board.c @@ -37,9 +37,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // TFT_DC - &pin_GPIO9, // TFT_CS - &pin_GPIO12, // TFT_RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // TFT_RST 50000000, // Baudrate 0, // Polarity 0 // Phase diff --git a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c index f17ca53d724..44d279da43f 100644 --- a/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c +++ b/ports/raspberrypi/boards/waveshare_rp2040_lcd_0_96/board.c @@ -60,9 +60,9 @@ static void display_init(void) { common_hal_fourwire_fourwire_construct( bus, spi, - &pin_GPIO8, // DC - &pin_GPIO9, // CS - &pin_GPIO12, // RST + MP_OBJ_FROM_PTR(&pin_GPIO8), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST 40000000, // baudrate 0, // polarity 0 // phase diff --git a/ports/raspberrypi/boards/waveshare_rp2350_geek/board.c b/ports/raspberrypi/boards/waveshare_rp2350_geek/board.c new file mode 100644 index 00000000000..431840fb0c5 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_geek/board.c @@ -0,0 +1,86 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + + +#include "mpconfigboard.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" +#include "shared-bindings/board/__init__.h" + +#define DELAY 0x80 + + +// display init sequence according to https://github.com/adafruit/Adafruit_CircuitPython_ST7789 +uint8_t display_init_sequence[] = { + 0x01, 0 | DELAY, 0x96, // _SWRESET and Delay 150ms + 0x11, 0 | DELAY, 0xFF, // _SLPOUT and Delay 500ms + 0x3A, 0x81, 0x55, 0x0A, // _COLMOD and Delay 10ms + 0x36, 0x01, 0x08, // _MADCTL + 0x21, 0 | DELAY, 0x0A, // _INVON Hack and Delay 10ms + 0x13, 0 | DELAY, 0x0A, // _NORON and Delay 10ms + 0x36, 0x01, 0xC0, // _MADCTL + 0x29, 0 | DELAY, 0xFF, // _DISPON and Delay 500ms +}; + +static void display_init(void) { + + busio_spi_obj_t *spi = common_hal_board_create_spi(0); + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO8), // TFT_DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // TFT_CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // TFT_RST + 50000000, // Baudrate + 0, // Polarity + 0 // Phase + + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 240, // Width + 135, // Height + 53, // column start + 40, // row start + 270, // rotation + 16, // Color depth + false, // Grayscale + false, // Pixels in a byte share a row + 1, // bytes per cell + false, // reverse_pixels_in_byte + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO25, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 1000 // backlight pwm frequency + ); +} + +void board_init(void) { + display_init(); +} diff --git a/ports/raspberrypi/boards/waveshare_rp2350_geek/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_geek/mpconfigboard.h new file mode 100644 index 00000000000..25788973115 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_geek/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-GEEK" +#define MICROPY_HW_MCU_NAME "rp2350" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO29, .sda = &pin_GPIO28}} + +#define CIRCUITPY_BOARD_SPI (2) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO10, .mosi = &pin_GPIO11}, \ + {.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = &pin_GPIO20}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO4, .rx = &pin_GPIO5}} diff --git a/ports/raspberrypi/boards/waveshare_rp2350_geek/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_geek/mpconfigboard.mk new file mode 100644 index 00000000000..e1d89c1fbca --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_geek/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B6 +USB_PRODUCT = "RP2350-GEEK" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but many of the pins are used for other purposes. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_geek/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_geek/pico-sdk-configboard.h new file mode 100644 index 00000000000..a2e741ef9e5 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_geek/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_geek/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_geek/pins.c new file mode 100644 index 00000000000..8fa4f56051e --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_geek/pins.c @@ -0,0 +1,78 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +CIRCUITPY_BOARD_BUS_SINGLETON(sd_spi, spi, 1) +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + // 2-3 DEBUG + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + // 4-5 UART + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + // 8-12 LCD + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + // 16-17 I2C + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + // 18-23 SD Card + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + // 25 LCD Backlight + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + // 28-29 I2C + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + + // UART + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + + // I2C + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + + // SPI SD Card + { MP_ROM_QSTR(MP_QSTR_SD_SCK), MP_ROM_PTR(&pin_GPIO18)}, + { MP_ROM_QSTR(MP_QSTR_SD_MOSI), MP_ROM_PTR(&pin_GPIO19)}, + { MP_ROM_QSTR(MP_QSTR_SD_MISO), MP_ROM_PTR(&pin_GPIO20)}, + { MP_ROM_QSTR(MP_QSTR_SD_CS), MP_ROM_PTR(&pin_GPIO23)}, + { MP_ROM_QSTR(MP_QSTR_SD_SPI), MP_ROM_PTR(&board_sd_spi_obj) }, + + // SDIO SD Card + { MP_ROM_QSTR(MP_QSTR_SDIO_CLK), MP_ROM_PTR(&pin_GPIO18)}, + { MP_ROM_QSTR(MP_QSTR_SDIO_COMMAND), MP_ROM_PTR(&pin_GPIO19)}, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA0), MP_ROM_PTR(&pin_GPIO20)}, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA1), MP_ROM_PTR(&pin_GPIO21)}, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA2), MP_ROM_PTR(&pin_GPIO22)}, + { MP_ROM_QSTR(MP_QSTR_SDIO_DATA3), MP_ROM_PTR(&pin_GPIO23)}, + + // LCD + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_MOSI), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BACKLIGHT), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_LCD_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/board.c b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/board.c new file mode 100644 index 00000000000..44d279da43f --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/board.c @@ -0,0 +1,109 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/displayio/mipi_constants.h" + +#define DELAY 0x80 + + +// display init sequence according to Adafruit_CircuitPython_ST7735R +// https://github.com/adafruit/Adafruit_CircuitPython_ST7735R +uint8_t display_init_sequence[] = { + // sw reset + 0x01, 0 | DELAY, 0x96, + // SLPOUT and Delay + 0x11, 0 | DELAY, 0xFF, + 0xB1, 0x03, 0x01, 0x2C, 0x2D, // _FRMCTR1 + 0xB3, 0x06, 0x01, 0x2C, 0x2D, 0x01, 0x2C, 0x2D, // _FRMCTR3 + 0xB4, 0x01, 0x07, // _INVCTR line inversion + 0xC0, 0x03, 0xA2, 0x02, 0x84, // _PWCTR1 GVDD = 4.7V, 1.0uA + 0xC1, 0x01, 0xC5, // _PWCTR2 VGH=14.7V, VGL=-7.35V + 0xC2, 0x02, 0x0A, 0x00, // _PWCTR3 Opamp current small, Boost frequency + 0xC3, 0x02, 0x8A, 0x2A, + 0xC4, 0x02, 0x8A, 0xEE, + 0xC5, 0x01, 0x0E, // _VMCTR1 VCOMH = 4V, VOML = -1.1V + 0x20, 0x00, // _INVOFF + 0x36, 0x01, 0x18, // _MADCTL bottom to top refresh + // 1 clk cycle nonoverlap, 2 cycle gate rise, 3 cycle osc equalie, + // fix on VTL + 0x3A, 0x01, 0x05, // COLMOD - 16bit color + 0xE0, 0x10, 0x02, 0x1C, 0x07, 0x12, 0x37, 0x32, 0x29, 0x2D, 0x29, 0x25, 0x2B, 0x39, 0x00, 0x01, 0x03, 0x10, // _GMCTRP1 Gamma + 0xE1, 0x10, 0x03, 0x1D, 0x07, 0x06, 0x2E, 0x2C, 0x29, 0x2D, 0x2E, 0x2E, 0x37, 0x3F, 0x00, 0x00, 0x02, 0x10, // _GMCTRN1 + 0x13, 0 | DELAY, 0x0A, // _NORON + 0x29, 0 | DELAY, 0x64, // _DISPON + // 0x36, 0x01, 0xC0, // _MADCTL Default rotation plus BGR encoding + 0x36, 0x01, 0xC8, // _MADCTL Default rotation plus RGB encoding + 0x21, 0x00, // _INVON +}; + +static void display_init(void) { + fourwire_fourwire_obj_t *bus = &allocate_display_bus()->fourwire_bus; + busio_spi_obj_t *spi = &bus->inline_bus; + common_hal_busio_spi_construct( + spi, + &pin_GPIO10, // CLK + &pin_GPIO11, // MOSI + NULL, // MISO not connected + false // Not half-duplex + ); + + common_hal_busio_spi_never_reset(spi); + + bus->base.type = &fourwire_fourwire_type; + + common_hal_fourwire_fourwire_construct( + bus, + spi, + MP_OBJ_FROM_PTR(&pin_GPIO8), // DC + MP_OBJ_FROM_PTR(&pin_GPIO9), // CS + MP_OBJ_FROM_PTR(&pin_GPIO12), // RST + 40000000, // baudrate + 0, // polarity + 0 // phase + ); + + busdisplay_busdisplay_obj_t *display = &allocate_display()->display; + display->base.type = &busdisplay_busdisplay_type; + common_hal_busdisplay_busdisplay_construct( + display, + bus, + 160, // width (after rotation) + 80, // height (after rotation) + 26, // column start + 1, // row start + 90, // rotation + 16, // color depth + false, // grayscale + false, // pixels in a byte share a row. Only valid for depths < 8 + 1, // bytes per cell. Only valid for depths < 8 + false, // reverse_pixels_in_byte. Only valid for depths < 8 + true, // reverse_pixels_in_word + MIPI_COMMAND_SET_COLUMN_ADDRESS, // set column command + MIPI_COMMAND_SET_PAGE_ADDRESS, // set row command + MIPI_COMMAND_WRITE_MEMORY_START, // write memory command + display_init_sequence, + sizeof(display_init_sequence), + &pin_GPIO25, // backlight pin + NO_BRIGHTNESS_COMMAND, + 1.0f, // brightness + false, // single_byte_bounds + false, // data_as_commands + true, // auto_refresh + 60, // native_frames_per_second + true, // backlight_on_high + false, // SH1107_addressing + 50000 // backlight pwm frequency + ); +} + +void board_init(void) { + // Display + display_init(); +} +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/mpconfigboard.h new file mode 100644 index 00000000000..53f913d7c09 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/mpconfigboard.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-LCD-0.96" +#define MICROPY_HW_MCU_NAME "rp2350" + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO21, .sda = &pin_GPIO20}} + +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO18, .mosi = &pin_GPIO19, .miso = &pin_GPIO16}} + +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO0, .rx = &pin_GPIO1}} diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/mpconfigboard.mk new file mode 100644 index 00000000000..62861864bbb --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/mpconfigboard.mk @@ -0,0 +1,12 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B7 +USB_PRODUCT = "Waveshare RP2350-LCD-0.96" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "P25Q32SH" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/pins.c new file mode 100644 index 00000000000..bd3a8310345 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_0_96/pins.c @@ -0,0 +1,63 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + + // ADC + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + + // 0.96 inch LCD ST7735s + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_LCD_DIN), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].display) }, + + // Power pins + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/board.c b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/mpconfigboard.h new file mode 100644 index 00000000000..0fc7bb372b1 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/mpconfigboard.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-LCD-1.28" +#define MICROPY_HW_MCU_NAME "rp2350" diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/mpconfigboard.mk new file mode 100644 index 00000000000..f04b91f8b0d --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/mpconfigboard.mk @@ -0,0 +1,21 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B3 +USB_PRODUCT = "Waveshare RP2350-LCD-1.28" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "P25Q32SH" + +CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but GPIO12 is used for display reset. +CIRCUITPY_PICODVI = 0 + +# TODO: Add custom QMI8658 driver +# FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_qmi8658 + +# TODO: Add custom GC9A01 driver +# FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_gc9a01 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/pins.c new file mode 100644 index 00000000000..78e40ad3265 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_lcd_1_28/pins.c @@ -0,0 +1,76 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_SDA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_SCL), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_DIN), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + + + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_INT1), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_INT2), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO29) }, // Battery voltage readout, 0.50 bias +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2350_one/board.c b/ports/raspberrypi/boards/waveshare_rp2350_one/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_one/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_one/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_one/mpconfigboard.h new file mode 100644 index 00000000000..d8efe2396e0 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_one/mpconfigboard.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-One" +#define MICROPY_HW_MCU_NAME "rp2350" + +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) + +#define DEFAULT_I2C_BUS_SDA (&pin_GPIO4) +#define DEFAULT_I2C_BUS_SCL (&pin_GPIO5) + +#define DEFAULT_SPI_BUS_CK (&pin_GPIO6) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO7) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO8) + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO16) diff --git a/ports/raspberrypi/boards/waveshare_rp2350_one/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_one/mpconfigboard.mk new file mode 100644 index 00000000000..bde7153c029 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_one/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B5 +USB_PRODUCT = "RP2350-One" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but GPIO16 is not broken out and is used for NeoPixel. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_one/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_one/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_one/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_one/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_one/pins.c new file mode 100644 index 00000000000..5b172616aba --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_one/pins.c @@ -0,0 +1,62 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2350_plus/board.c b/ports/raspberrypi/boards/waveshare_rp2350_plus/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_plus/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_plus/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_plus/mpconfigboard.h new file mode 100644 index 00000000000..a8df27661d3 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_plus/mpconfigboard.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-Plus" +#define MICROPY_HW_MCU_NAME "rp2350" diff --git a/ports/raspberrypi/boards/waveshare_rp2350_plus/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_plus/mpconfigboard.mk new file mode 100644 index 00000000000..d70259ab271 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_plus/mpconfigboard.mk @@ -0,0 +1,12 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B1 +USB_PRODUCT = "RP2350-Plus" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_plus/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_plus/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_plus/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_plus/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_plus/pins.c new file mode 100644 index 00000000000..1263586686b --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_plus/pins.c @@ -0,0 +1,60 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2350_tiny/board.c b/ports/raspberrypi/boards/waveshare_rp2350_tiny/board.c new file mode 100644 index 00000000000..a019bac4255 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_tiny/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bill Sideris +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_tiny/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_tiny/mpconfigboard.h new file mode 100644 index 00000000000..f4a9e0231de --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_tiny/mpconfigboard.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bill Sideris +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-Tiny" +#define MICROPY_HW_MCU_NAME "rp2350" + +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO16) diff --git a/ports/raspberrypi/boards/waveshare_rp2350_tiny/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_tiny/mpconfigboard.mk new file mode 100644 index 00000000000..79fafbacf5c --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_tiny/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B2 +USB_PRODUCT = "RP2350-Tiny" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "P25Q32SH" + +CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but GPIO16-19 are not available. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_tiny/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_tiny/pico-sdk-configboard.h new file mode 100644 index 00000000000..307388439fa --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_tiny/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bill Sideris +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_tiny/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_tiny/pins.c new file mode 100644 index 00000000000..9b6f5331336 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_tiny/pins.c @@ -0,0 +1,53 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Bill Sideris +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/board.c b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/mpconfigboard.h new file mode 100644 index 00000000000..4bf2cdfac6e --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/mpconfigboard.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-TOUCH-LCD-1.28" +#define MICROPY_HW_MCU_NAME "rp2350" diff --git a/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/mpconfigboard.mk new file mode 100644 index 00000000000..0ec6c4ec008 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/mpconfigboard.mk @@ -0,0 +1,21 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B4 +USB_PRODUCT = "Waveshare RP2350-TOUCH-LCD-1.28" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but GPIO12 is used for display reset. +CIRCUITPY_PICODVI = 0 + +# TODO: Add custom QMI8658 driver +# FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_qmi8658 + +# TODO: Add custom GC9A01 driver +# FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython_gc9a01 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/pins.c new file mode 100644 index 00000000000..c14fdb6e23b --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_touch_lcd_1_28/pins.c @@ -0,0 +1,76 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_SDA), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_SCL), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_DC), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CS), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_CLK), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_DIN), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_RST), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_INT1), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_IMU_INT2), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LCD_BL), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_BAT_ADC), MP_ROM_PTR(&pin_GPIO29) }, // Battery voltage readout, 0.50 bias +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/waveshare_rp2350_zero/board.c b/ports/raspberrypi/boards/waveshare_rp2350_zero/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_zero/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_zero/mpconfigboard.h b/ports/raspberrypi/boards/waveshare_rp2350_zero/mpconfigboard.h new file mode 100644 index 00000000000..c1517f08c10 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_zero/mpconfigboard.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "Waveshare RP2350-Zero" +#define MICROPY_HW_MCU_NAME "rp2350" + +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) + +#define MICROPY_HW_NEOPIXEL (&pin_GPIO16) diff --git a/ports/raspberrypi/boards/waveshare_rp2350_zero/mpconfigboard.mk b/ports/raspberrypi/boards/waveshare_rp2350_zero/mpconfigboard.mk new file mode 100644 index 00000000000..7f0a3c71cbb --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_zero/mpconfigboard.mk @@ -0,0 +1,15 @@ +USB_VID = 0x2E8A +USB_PID = 0x10B0 +USB_PRODUCT = "RP2350-Zero" +USB_MANUFACTURER = "Waveshare Electronics" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "P25Q32SH" + +CIRCUITPY__EVE = 1 + +# GPIO12-19 needed for picodvi, but GPIO16 is not broken out and is used for NeoPixel. +CIRCUITPY_PICODVI = 0 diff --git a/ports/raspberrypi/boards/waveshare_rp2350_zero/pico-sdk-configboard.h b/ports/raspberrypi/boards/waveshare_rp2350_zero/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_zero/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/waveshare_rp2350_zero/pins.c b/ports/raspberrypi/boards/waveshare_rp2350_zero/pins.c new file mode 100644 index 00000000000..5b172616aba --- /dev/null +++ b/ports/raspberrypi/boards/waveshare_rp2350_zero/pins.c @@ -0,0 +1,62 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO0) }, + + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO1) }, + + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/weact_studio_rp2350b_core/board.c b/ports/raspberrypi/boards/weact_studio_rp2350b_core/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_rp2350b_core/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/weact_studio_rp2350b_core/mpconfigboard.h b/ports/raspberrypi/boards/weact_studio_rp2350b_core/mpconfigboard.h new file mode 100644 index 00000000000..95a81334c73 --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_rp2350b_core/mpconfigboard.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#define MICROPY_HW_BOARD_NAME "WeAct Studio RP2350B Core" +#define MICROPY_HW_MCU_NAME "rp2350b" + +#define CIRCUITPY_PSRAM_CHIP_SELECT (&pin_GPIO0) diff --git a/ports/raspberrypi/boards/weact_studio_rp2350b_core/mpconfigboard.mk b/ports/raspberrypi/boards/weact_studio_rp2350b_core/mpconfigboard.mk new file mode 100644 index 00000000000..d86f28280f3 --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_rp2350b_core/mpconfigboard.mk @@ -0,0 +1,12 @@ +USB_VID = 0x1209 +USB_PID = 0xDEC1 +USB_PRODUCT = "RP2350B Core" +USB_MANUFACTURER = "WeAct Studio" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = B +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 diff --git a/ports/raspberrypi/boards/weact_studio_rp2350b_core/pico-sdk-configboard.h b/ports/raspberrypi/boards/weact_studio_rp2350b_core/pico-sdk-configboard.h new file mode 100644 index 00000000000..66b57dfd13d --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_rp2350b_core/pico-sdk-configboard.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/weact_studio_rp2350b_core/pins.c b/ports/raspberrypi/boards/weact_studio_rp2350b_core/pins.c new file mode 100644 index 00000000000..d6a82becfdd --- /dev/null +++ b/ports/raspberrypi/boards/weact_studio_rp2350b_core/pins.c @@ -0,0 +1,91 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_BUTTON), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP30), MP_ROM_PTR(&pin_GPIO30) }, + { MP_ROM_QSTR(MP_QSTR_GP31), MP_ROM_PTR(&pin_GPIO31) }, + { MP_ROM_QSTR(MP_QSTR_GP32), MP_ROM_PTR(&pin_GPIO32) }, + { MP_ROM_QSTR(MP_QSTR_GP33), MP_ROM_PTR(&pin_GPIO33) }, + { MP_ROM_QSTR(MP_QSTR_GP34), MP_ROM_PTR(&pin_GPIO34) }, + { MP_ROM_QSTR(MP_QSTR_GP35), MP_ROM_PTR(&pin_GPIO35) }, + { MP_ROM_QSTR(MP_QSTR_GP36), MP_ROM_PTR(&pin_GPIO36) }, + { MP_ROM_QSTR(MP_QSTR_GP37), MP_ROM_PTR(&pin_GPIO37) }, + { MP_ROM_QSTR(MP_QSTR_GP38), MP_ROM_PTR(&pin_GPIO38) }, + { MP_ROM_QSTR(MP_QSTR_GP39), MP_ROM_PTR(&pin_GPIO39) }, + + { MP_ROM_QSTR(MP_QSTR_GP40), MP_ROM_PTR(&pin_GPIO40) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO40) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP40_A0), MP_ROM_PTR(&pin_GPIO40) }, + + { MP_ROM_QSTR(MP_QSTR_GP41), MP_ROM_PTR(&pin_GPIO41) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO41) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP41_A1), MP_ROM_PTR(&pin_GPIO41) }, + + { MP_ROM_QSTR(MP_QSTR_GP42), MP_ROM_PTR(&pin_GPIO42) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO42) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP42_A2), MP_ROM_PTR(&pin_GPIO42) }, + + { MP_ROM_QSTR(MP_QSTR_GP43), MP_ROM_PTR(&pin_GPIO43) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO43) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP43_A3), MP_ROM_PTR(&pin_GPIO43) }, + + { MP_ROM_QSTR(MP_QSTR_GP44), MP_ROM_PTR(&pin_GPIO44) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO44) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP44_A4), MP_ROM_PTR(&pin_GPIO44) }, + + { MP_ROM_QSTR(MP_QSTR_GP45), MP_ROM_PTR(&pin_GPIO45) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO45) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP45_A5), MP_ROM_PTR(&pin_GPIO45) }, + + { MP_ROM_QSTR(MP_QSTR_GP46), MP_ROM_PTR(&pin_GPIO46) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO46) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP46_A6), MP_ROM_PTR(&pin_GPIO46) }, + + { MP_ROM_QSTR(MP_QSTR_GP47), MP_ROM_PTR(&pin_GPIO47) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO47) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_GP47_A7), MP_ROM_PTR(&pin_GPIO47) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/_aic3105.py b/ports/raspberrypi/boards/weenoisemakers_noisenugget/_aic3105.py new file mode 100644 index 00000000000..06923e374b7 --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/_aic3105.py @@ -0,0 +1,564 @@ +from adafruit_bus_device import i2c_device + +import time + +# Page select register +AIC3X_PAGE_SELECT = 0 +# Software reset register +AIC3X_RESET = 1 +# Codec Sample rate select register +AIC3X_SAMPLE_RATE_SEL_REG = 2 +# PLL progrramming register A +AIC3X_PLL_PROGA_REG = 3 +# PLL progrramming register B +AIC3X_PLL_PROGB_REG = 4 +# PLL progrramming register C +AIC3X_PLL_PROGC_REG = 5 +# PLL progrramming register D +AIC3X_PLL_PROGD_REG = 6 +# Codec datapath setup register +AIC3X_CODEC_DATAPATH_REG = 7 +# Audio serial data interface control register A +AIC3X_ASD_INTF_CTRLA = 8 +# Audio serial data interface control register B +AIC3X_ASD_INTF_CTRLB = 9 +# Audio serial data interface control register C +AIC3X_ASD_INTF_CTRLC = 10 +# Audio overflow status and PLL R value programming register +AIC3X_OVRF_STATUS_AND_PLLR_REG = 11 +# Audio codec digital filter control register +AIC3X_CODEC_DFILT_CTRL = 12 +# Headset/button press detection register +AIC3X_HEADSET_DETECT_CTRL_A = 13 +AIC3X_HEADSET_DETECT_CTRL_B = 14 +# ADC PGA Gain control registers +LADC_VOL = 15 +RADC_VOL = 16 +# MIC3 control registers +MIC3LR_2_LADC_CTRL = 17 +MIC3LR_2_RADC_CTRL = 18 +# Line1 Input control registers +LINE1L_2_LADC_CTRL = 19 +LINE1R_2_LADC_CTRL = 21 +LINE1R_2_RADC_CTRL = 22 +LINE1L_2_RADC_CTRL = 24 +# Line2 Input control registers +LINE2L_2_LADC_CTRL = 20 +LINE2R_2_RADC_CTRL = 23 +# MICBIAS Control Register +MICBIAS_CTRL = 25 + +# AGC Control Registers A, B, C +LAGC_CTRL_A = 26 +LAGC_CTRL_B = 27 +LAGC_CTRL_C = 28 +RAGC_CTRL_A = 29 +RAGC_CTRL_B = 30 +RAGC_CTRL_C = 31 + +# DAC Power and Left High Power Output control registers +DAC_PWR = 37 +HPLCOM_CFG = 37 +# Right High Power Output control registers +HPRCOM_CFG = 38 +# High Power Output Stage Control Register +HPOUT_SC = 40 +# DAC Output Switching control registers +DAC_LINE_MUX = 41 +# High Power Output Driver Pop Reduction registers +HPOUT_POP_REDUCTION = 42 +# DAC Digital control registers +LDAC_VOL = 43 +RDAC_VOL = 44 +# Left High Power Output control registers +LINE2L_2_HPLOUT_VOL = 45 +PGAL_2_HPLOUT_VOL = 46 +DACL1_2_HPLOUT_VOL = 47 +LINE2R_2_HPLOUT_VOL = 48 +PGAR_2_HPLOUT_VOL = 49 +DACR1_2_HPLOUT_VOL = 50 +HPLOUT_CTRL = 51 +# Left High Power COM control registers +LINE2L_2_HPLCOM_VOL = 52 +PGAL_2_HPLCOM_VOL = 53 +DACL1_2_HPLCOM_VOL = 54 +LINE2R_2_HPLCOM_VOL = 55 +PGAR_2_HPLCOM_VOL = 56 +DACR1_2_HPLCOM_VOL = 57 +HPLCOM_CTRL = 58 +# Right High Power Output control registers +LINE2L_2_HPROUT_VOL = 59 +PGAL_2_HPROUT_VOL = 60 +DACL1_2_HPROUT_VOL = 61 +LINE2R_2_HPROUT_VOL = 62 +PGAR_2_HPROUT_VOL = 63 +DACR1_2_HPROUT_VOL = 64 +HPROUT_CTRL = 65 +# Right High Power COM control registers +LINE2L_2_HPRCOM_VOL = 66 +PGAL_2_HPRCOM_VOL = 67 +DACL1_2_HPRCOM_VOL = 68 +LINE2R_2_HPRCOM_VOL = 69 +PGAR_2_HPRCOM_VOL = 70 +DACR1_2_HPRCOM_VOL = 71 +HPRCOM_CTRL = 72 +# Mono Line Output Plus/Minus control registers +LINE2L_2_MONOLOPM_VOL = 73 +PGAL_2_MONOLOPM_VOL = 74 +DACL1_2_MONOLOPM_VOL = 75 +LINE2R_2_MONOLOPM_VOL = 76 +PGAR_2_MONOLOPM_VOL = 77 +DACR1_2_MONOLOPM_VOL = 78 +MONOLOPM_CTRL = 79 +# Left Line Output Plus/Minus control registers +LINE2L_2_LLOPM_VOL = 80 +PGAL_2_LLOPM_VOL = 81 +DACL1_2_LLOPM_VOL = 82 +LINE2R_2_LLOPM_VOL = 83 +PGAR_2_LLOPM_VOL = 84 +DACR1_2_LLOPM_VOL = 85 +LLOPM_CTRL = 86 +# Right Line Output Plus/Minus control registers +LINE2L_2_RLOPM_VOL = 87 +PGAL_2_RLOPM_VOL = 88 +DACL1_2_RLOPM_VOL = 89 +LINE2R_2_RLOPM_VOL = 90 +PGAR_2_RLOPM_VOL = 91 +DACR1_2_RLOPM_VOL = 92 +RLOPM_CTRL = 93 + +MODULE_POWER_STATUS = 94 + +# GPIO/IRQ registers +AIC3X_STICKY_IRQ_FLAGS_REG = 96 +AIC3X_RT_IRQ_FLAGS_REG = 97 + +AIC3X_CLOCK_REG = 101 +# Clock generation control register +AIC3X_CLKGEN_CTRL_REG = 102 +# New AGC registers +LAGCN_ATTACK = 103 +LAGCN_DECAY = 104 +RAGCN_ATTACK = 105 +RAGCN_DECAY = 106 +# New Programmable ADC Digital Path and I2C Bus Condition Register +NEW_ADC_DIGITALPATH = 107 +# Passive Analog Signal Bypass Selection During Powerdown Register +PASSIVE_BYPASS = 108 +# DAC Quiescent Current Adjustment Register +DAC_ICC_ADJ = 109 + + +# My kingdom for enums, and strong typing... +LINE2_L = 0 +PGA_L = 1 +DAC_L1 = 2 +LINE2_R = 3 +PGA_R = 4 +DAC_R1 = 5 + +# Don't use the same values for the sink and source "enums", this way a runtime +# error will tell us when we mix the two. +HP_L_OUT = 10 +HP_L_COM = 11 +HP_R_OUT = 12 +HP_R_COM = 13 +LINE_OUT_L = 14 +LINE_OUT_R = 15 + + +class AIC3105: + def __init__(self, i2c_bus, sample_rate, address=0x18): + self.i2c_device = i2c_device.I2CDevice(i2c_bus, address) + self._buf = bytearray(2) + self._sample_rate = sample_rate + + self._registers_copy = [ + 0b00000000, # 0 + 0b00000000, # 1 + 0b00000000, # 2 + 0b00010000, # 3 + 0b00000010, # 4 + 0b00000000, # 5 + 0b00000000, # 6 + 0b00000000, # 7 + 0b00000000, # 8 + 0b00000000, # 9 + 0b00000000, # 10 + 0b00000001, # 11 + 0b00000000, # 12 + 0b00000000, # 13 + 0b00000000, # 14 + 0b10000000, # 15 + 0b10000000, # 16 + 0b11111111, # 17 + 0b11111111, # 18 + 0b01111000, # 19 + 0b01111000, # 20 + 0b01111000, # 21 + 0b01111000, # 22 + 0b01111000, # 23 + 0b01111000, # 24 + 0b00000000, # 25 + 0b00000000, # 26 + 0b11111110, # 27 + 0b00000000, # 28 + 0b00000000, # 29 + 0b11111110, # 30 + 0b00000000, # 31 + 0b00000000, # 32 + 0b00000000, # 33 + 0b00000000, # 34 + 0b00000000, # 35 + 0b00000000, # 36 + 0b00000000, # 37 + 0b00000000, # 38 + 0b00000000, # 39 + 0b00000000, # 40 + 0b00000000, # 41 + 0b00000000, # 42 + 0b10000000, # 43 + 0b10000000, # 44 + 0b00000000, # 45 + 0b00000000, # 46 + 0b00000000, # 47 + 0b00000000, # 48 + 0b00000000, # 49 + 0b00000000, # 50 + 0b00000110, # 51 + 0b00000000, # 52 + 0b00000000, # 53 + 0b00000000, # 54 + 0b00000000, # 55 + 0b00000000, # 56 + 0b00000000, # 57 + 0b00000110, # 58 + 0b00000000, # 59 + 0b00000000, # 60 + 0b00000000, # 61 + 0b00000000, # 62 + 0b00000000, # 63 + 0b00000000, # 64 + 0b00000010, # 65 + 0b00000000, # 66 + 0b00000000, # 67 + 0b00000000, # 68 + 0b00000000, # 69 + 0b00000000, # 70 + 0b00000000, # 71 + 0b00000010, # 72 + 0b00000000, # 73 + 0b00000000, # 74 + 0b00000000, # 75 + 0b00000000, # 76 + 0b00000000, # 77 + 0b00000000, # 78 + 0b00000000, # 79 + 0b00000000, # 80 + 0b00000000, # 81 + 0b00000000, # 82 + 0b00000000, # 83 + 0b00000000, # 84 + 0b00000000, # 85 + 0b00000010, # 86 + 0b00000000, # 87 + 0b00000000, # 88 + 0b00000000, # 89 + 0b00000000, # 90 + 0b00000000, # 91 + 0b00000000, # 92 + 0b00000010, # 93 + 0b00000000, # 94 + 0b00000000, # 95 + 0b00000000, # 96 + 0b00000000, # 97 + 0b00000000, # 98 + 0b00000000, # 99 + 0b00000000, # 100 + 0b00000000, # 101 + 0b00000010, # 102 + 0b00000000, # 103 + 0b00000000, # 104 + 0b00000000, # 105 + 0b00000000, # 106 + 0b00000000, # 107 + 0b00000000, # 108 + 0b00000000, + ] # 109 + + def _write_register(self, reg, value): + self._buf[0] = reg & 0xFF + self._buf[1] = value & 0xFF + # print("_write_register reg:0x{:02x} value:0x{:02x}".format(reg, value)) + with self.i2c_device as i2c: + i2c.write(self._buf) + self._registers_copy[reg] = value + + def _write_bit(self, reg, pos, value): + current = self._registers_copy[reg] + mask = 1 << pos + + if value == 0: + new = current & (~mask) + else: + new = current | mask + self._write_register(reg, new) + + def _write_multi(self, reg, msb, lsb, value): + new = self._registers_copy[reg] + + # Clear bits for the range we case about + for x in range(lsb, msb + 1): + new = new & (~(1 << x)) + + new = new | (value << lsb) + + self._write_register(reg, new) + + def sink_base_register(self, sink): + if sink == HP_L_OUT: + return 45 + if sink == HP_L_COM: + return 52 + if sink == HP_R_OUT: + return 59 + if sink == HP_R_COM: + return 66 + if sink == LINE_OUT_L: + return 80 + if sink == LINE_OUT_R: + return 87 + + raise RuntimeError("invalid sink") + + def source_register_offset(self, source): + if source == LINE2_L: + return 0 + if source == PGA_L: + return 1 + if source == DAC_L1: + return 2 + if source == LINE2_R: + return 3 + if source == PGA_R: + return 4 + if source == DAC_R1: + return 5 + raise RuntimeError("invalid source") + + def power_on(self, sink): + reg = self.sink_base_register(sink) + 6 + self._write_bit(reg, 0, 1) + + def power_off(self, sink): + reg = self.sink_base_register(sink) + 6 + self._write_bit(reg, 0, 0) + + def mute(self, sink): + reg = self.sink_base_register(sink) + 6 + self._write_bit(reg, 3, 0) + + def unmute(self, sink): + reg = self.sink_base_register(sink) + 6 + self._write_bit(reg, 3, 1) + + def route(self, source, sink): + reg = self.sink_base_register(sink) + self.source_register_offset(source) + self._write_bit(reg, 7, 1) + + def unroute(self, source, sink): + reg = self.sink_base_register(sink) + self.source_register_offset(source) + self._write_bit(reg, 7, 0) + + def volume_convert(self, volume, min, max, mute_value): + if volume == 0.0 or volume < 0.0: + return mute_value + elif volume > 1.0: + volume = 1.0 + + if max > min: + amplitude = max - min + val = volume * amplitude + return int(min + val) + else: + amplitude = min - max + val = (1.0 - volume) * amplitude + return int(max + val) + + def PGA_volume(self, volume): + return self.volume_convert(volume, 0, 0b1111111, 0) + + def output_stage_volume(self, volume): + return self.volume_convert(volume, 117, 0, 118) + + def set_volume(self, source, sink, volume): + vol = self.output_stage_volume(volume) + reg = self.sink_base_register(sink) + self.source_register_offset(source) + self._write_multi(reg, 6, 0, vol) + + def set_HP_volume(self, left, right): + self.set_volume(DAC_L1, HP_L_OUT, left) + self.set_volume(DAC_R1, HP_R_OUT, right) + + def enable_line_out(self, left, right): + if left: + self.power_on(LINE_OUT_L) + self.route(DAC_L1, LINE_OUT_L) + self.route(DAC_L1, LINE_OUT_R) + self.unmute(LINE_OUT_L) + else: + self.power_off(LINE_OUT_L) + self.unroute(DAC_L1, LINE_OUT_L) + self.unroute(DAC_L1, LINE_OUT_R) + self.mute(LINE_OUT_L) + + if right: + self.power_on(LINE_OUT_R) + self.route(DAC_R1, LINE_OUT_L) + self.route(DAC_R1, LINE_OUT_R) + self.unmute(LINE_OUT_R) + else: + self.power_off(LINE_OUT_R) + self.unroute(DAC_R1, LINE_OUT_L) + self.unroute(DAC_R1, LINE_OUT_R) + self.mute(LINE_OUT_R) + + def set_line_out_volume( + self, left_to_left, right_to_right, left_to_right=0.0, right_to_left=0.0 + ): + self.set_volume(DAC_L1, LINE_OUT_L, left_to_left) + self.set_volume(DAC_L1, LINE_OUT_R, left_to_right) + self.set_volume(DAC_R1, LINE_OUT_R, right_to_right) + self.set_volume(DAC_R1, LINE_OUT_L, right_to_left) + + def enable_mic_bias(self): + self._write_multi(MICBIAS_CTRL, 7, 6, 0b10) + + def start_i2s_out(self): + if self._sample_rate == 8000: + cfg = [5, 4613, 1, 8] + elif self._sample_rate == 16000: + cfg = [5, 4613, 1, 4] + elif self._sample_rate == 22050: + cfg = [7, 5264, 1, 4] + elif self._sample_rate == 32000: + cfg = [5, 4613, 1, 2] + elif self._sample_rate == 44100: + cfg = [7, 5264, 1, 2] + elif self._sample_rate == 48000: + cfg = [8, 1920, 1, 2] + else: + raise RuntimeError("invalid sample rate: " + str(self._sample_rate)) + + J = cfg[0] + D = cfg[1] + R = cfg[2] + P = cfg[3] + + # Select Page 0 + self._write_bit(AIC3X_PAGE_SELECT, 0, 0) + + # Soft reset + self._write_bit(AIC3X_RESET, 7, 1) + + # Let's start with clock configuration. + + # PLL P = 2 + self._write_multi(AIC3X_PLL_PROGA_REG, 2, 0, P) + + # PLL R = 1 + self._write_multi(AIC3X_OVRF_STATUS_AND_PLLR_REG, 3, 0, R) + + # PLL J = 7 + self._write_multi(AIC3X_PLL_PROGB_REG, 7, 2, J) + + # PLL D = 5264 + PLL_D = D + REG_C = PLL_D >> 6 + REG_D = PLL_D & 0x3F + self._write_multi(AIC3X_PLL_PROGC_REG, 7, 0, REG_C) + self._write_multi(AIC3X_PLL_PROGD_REG, 7, 2, REG_D) + + # Select the PLLCLK_IN source. 0: MCLK, 1: GPIO2, 2: BCLK + self._write_multi(AIC3X_CLKGEN_CTRL_REG, 5, 4, 2) + + # Select the CLKDIV_IN source. 0: MCLK, 1: GPIO2, 2: BCLK + # + # Note: When PLL is used CLKDIV_IN still needs some kind of clock + # signal. So if there's no MCLK, BCLK should be used here as well + self._write_multi(AIC3X_CLKGEN_CTRL_REG, 6, 7, 0) + + # Enable PLL + self._write_bit(AIC3X_PLL_PROGA_REG, 7, 1) + + # Set FS(ref) value for AGC time constants to 44.1KHz + self._write_bit(AIC3X_CODEC_DATAPATH_REG, 7, 1) + + # CODEC_CLKIN Source Selection. 0: PLLDIV_OUT. 1: CLKDIV_OUT + self._write_bit(AIC3X_CLOCK_REG, 0, 0) + + # Note: We leave the ADC Sample Rate Select and DAC Sample Rate Select + # at the default value: fs(ref) / 1 + + # Audio Serial Data Interface at the default settings: I2S + # mode, 16bits words, + self._write_multi(AIC3X_ASD_INTF_CTRLB, 7, 6, 0b00) + + # Output Driver Power-On Delay Control + self._write_multi(HPOUT_POP_REDUCTION, 7, 4, 0b1000) + + # Driver Ramp-Up Step Timing Control + self._write_multi(HPOUT_POP_REDUCTION, 3, 2, 0b01) + + # Power outputs + self.power_on(HP_L_OUT) + self.power_on(HP_R_OUT) + + # L and R DACs Power On + self._write_multi(DAC_PWR, 7, 6, 0b11) + + # Left DAC plays left input data + self._write_multi(AIC3X_CODEC_DATAPATH_REG, 4, 3, 0b01) + # Right DAC plays right input data + self._write_multi(AIC3X_CODEC_DATAPATH_REG, 2, 1, 0b01) + + # Unmute L DAC + self._write_bit(LDAC_VOL, 7, 0) + # Unmute R DAC + self._write_bit(RDAC_VOL, 7, 0) + + # Left-DAC output selects DAC_L1 path. + self._write_multi(DAC_LINE_MUX, 7, 6, 0) + # Right-DAC output selects DAC_R1 path. + self._write_multi(DAC_LINE_MUX, 5, 4, 0) + + # DAC to HP + self.route(DAC_L1, HP_L_OUT) + self.route(DAC_R1, HP_R_OUT) + + # DAC to Line-Out + self.route(DAC_L1, LINE_OUT_L) + self.route(DAC_R1, LINE_OUT_R) + + # Enable Left ADC + self._write_bit(LINE1L_2_LADC_CTRL, 2, 1) + # Enable Right ADC + self._write_bit(LINE1R_2_RADC_CTRL, 2, 1) + + # Unmute L ADC PGA + self._write_bit(LADC_VOL, 7, 0) + # Unmute R ADC PGA + self._write_bit(RADC_VOL, 7, 0) + + # Programs high-power outputs for ac-coupled driver configuration + self._write_bit(AIC3X_HEADSET_DETECT_CTRL_B, 7, 1) + + # HPLCOM configured as independent single-ended output + self._write_multi(HPLCOM_CFG, 5, 4, 2) + + # HPRCOM configured as independent single-ended output + self._write_multi(HPRCOM_CFG, 5, 3, 1) + + # Unmute outputs + self.unmute(HP_L_OUT) + self.unmute(HP_R_OUT) diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/_tca6408.py b/ports/raspberrypi/boards/weenoisemakers_noisenugget/_tca6408.py new file mode 100644 index 00000000000..6b3d90b5de5 --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/_tca6408.py @@ -0,0 +1,65 @@ +from adafruit_bus_device import i2c_device + +IO_EXP_SPK_Enable_L_Mask = 0b00000001 +IO_EXP_SPK_Enable_R_Mask = 0b00000010 +IO_EXP_SPK_Gain_0_Mask = 0b00000100 +IO_EXP_SPK_Gain_1_Mask = 0b00001000 +IO_EXP_DAC_Not_Reset_Mask = 0b00010000 +IO_EXP_Jack_Detect_Mask = 0b00100000 + +IO_EXP_INPUT_REG = 0 +IO_EXP_OUTPUT_REG = 1 +IO_EXP_CONFIG_REG = 3 + +IO_EXP_CONFIG_REG_INIT = IO_EXP_Jack_Detect_Mask +IO_EXP_OUTPUT_REG_INIT = 0b00000000 + + +class TCA6408: + def __init__(self, i2c_bus, address=0x20): + self._i2c_device = i2c_device.I2CDevice(i2c_bus, address) + self._buf = bytearray(2) + self._reg_state = IO_EXP_OUTPUT_REG_INIT + + self._write_register(IO_EXP_OUTPUT_REG, self._reg_state) + self._write_register(IO_EXP_CONFIG_REG, IO_EXP_CONFIG_REG_INIT) + + def _write_register(self, reg, value): + self._buf[0] = reg & 0xFF + self._buf[1] = value & 0xFF + with self._i2c_device as i2c: + i2c.write(self._buf) + + def _set_out(self, new_state): + self._write_register(IO_EXP_OUTPUT_REG, new_state) + self._reg_state = new_state + + def enable_codec(self): + self._set_out(self._reg_state | IO_EXP_DAC_Not_Reset_Mask) + + def enable_speakers(self, left, right): + new_state = self._reg_state + if left: + new_state = new_state | IO_EXP_SPK_Enable_L_Mask + else: + new_state = new_state & ~IO_EXP_SPK_Enable_L_Mask + + if right: + new_state = new_state | IO_EXP_SPK_Enable_R_Mask + else: + new_state = new_state & ~IO_EXP_SPK_Enable_R_Mask + + self._set_out(new_state) + + def set_speakers_gain(self, g0, g1): + new_state = self._reg_state + + if g0: + new_state = new_state | IO_EXP_SPK_Gain_0_Mask + else: + new_state = new_state & ~IO_EXP_SPK_Gain_0_Mask + + if g1: + new_state = new_state | IO_EXP_SPK_Gain_1_Mask + else: + new_state = new_state & ~IO_EXP_SPK_Gain_1_Mask diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/board.c b/ports/raspberrypi/boards/weenoisemakers_noisenugget/board.c new file mode 100644 index 00000000000..331653173ec --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/board.c @@ -0,0 +1,29 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Scott Shawcroft for Adafruit Industries + * + * 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. + */ + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/mpconfigboard.h b/ports/raspberrypi/boards/weenoisemakers_noisenugget/mpconfigboard.h new file mode 100644 index 00000000000..ddebab5b8a3 --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/mpconfigboard.h @@ -0,0 +1,2 @@ +#define MICROPY_HW_BOARD_NAME "Noise Nugget 2040" +#define MICROPY_HW_MCU_NAME "rp2040" diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/mpconfigboard.mk b/ports/raspberrypi/boards/weenoisemakers_noisenugget/mpconfigboard.mk new file mode 100644 index 00000000000..a90f1a3db45 --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x2E8A +USB_PID = 0x1090 +USB_PRODUCT = "Noise Nugget 2040" +USB_MANUFACTURER = "Wee Noise Makers" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q128JVxQ" + +CIRCUITPY__EVE = 1 + +FROZEN_MPY_DIRS += $(TOP)/ports/raspberrypi/boards/weenoisemakers_noisenugget +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_NeoPixel +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_ImageLoad +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_DisplayIO_SSD1306 +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_Display_Text +FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_MIDI diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/noise_nugget.py b/ports/raspberrypi/boards/weenoisemakers_noisenugget/noise_nugget.py new file mode 100644 index 00000000000..02dab040e5f --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/noise_nugget.py @@ -0,0 +1,115 @@ +from board import * +import audiobusio +import busio +import time +import _aic3105 +import _tca6408 + +_AUDIO = None +_DAC = None +_I2C = None +_IO_EXP = None +_SAMPLE_RATE = 22050 + + +def io_exp(): + global _IO_EXP + + if not _IO_EXP: + _IO_EXP = _tca6408.TCA6408(i2c()) + + return _IO_EXP + + +def i2c(): + global _I2C + + if not _I2C: + SCL = GP7 + SDA = GP6 + _I2C = busio.I2C(SCL, SDA) + + return _I2C + + +def _init_dac(sample_rate): + global _DAC + global _SAMPLE_RATE + + if not _DAC: + _SAMPLE_RATE = sample_rate + + _DAC = _aic3105.AIC3105(i2c(), sample_rate) + _DAC.start_i2s_out() + + return _DAC + + +def audio(sample_rate=22050): + global _AUDIO + global _DAC + + if not _AUDIO: + i2s_out = GP1 + i2s_lrclk = GP2 + i2s_bclk = GP3 + + io_exp().enable_codec() + + time.sleep(0.1) + + # Must init the dac here + _init_dac(sample_rate) + _DAC.set_HP_volume(0.5, 0.5) + + _AUDIO = audiobusio.I2SOut(i2s_bclk, i2s_lrclk, i2s_out, left_justified=False) + + return _AUDIO + + +def sample_rate(): + return _SAMPLE_RATE + + +def _check_dac_init(): + global _DAC + if not _DAC: + raise RuntimeError("audio not initialized. Call noise_nugget.audio() first.") + + +def set_HP_volume(left, right): + global _DAC + + _check_dac_init() + + _DAC.set_HP_volume(left, right) + + +def enable_speakers(left, right): + global _DAC + + _check_dac_init() + + _DAC.enable_line_out(left, right) + io_exp().enable_speakers(left, right) + + +def set_speakers_volume(left_to_left, right_to_right, left_to_right=0.0, right_to_left=0.0): + global _DAC + + _check_dac_init() + + _DAC.set_line_out_volume(left_to_left, right_to_right, left_to_right, right_to_left) + + +def set_speakers_gain(gain): + if gain == 0: + io_exp().set_speakers_gain(False, False) + elif gain == 1: + io_exp().set_speakers_gain(True, False) + elif gain == 2: + io_exp().set_speakers_gain(False, True) + elif gain == 3: + io_exp().set_speakers_gain(True, True) + else: + raise RuntimeError("invalid speaker gain " + str(gain) + " (must be between 0 and 3)") diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/pgb1.py b/ports/raspberrypi/boards/weenoisemakers_noisenugget/pgb1.py new file mode 100644 index 00000000000..6e822e75c8c --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/pgb1.py @@ -0,0 +1,320 @@ +from board import * +import busio +import displayio +import adafruit_displayio_ssd1306 +from fourwire import FourWire +from neopixel import NeoPixel +import pwmio +from digitalio import DigitalInOut, Direction, Pull + +_DISPLAY = None +_LEDS = None +_KEYBOARD_STATE = 0 +_KEYBOARD_PREV_STATE = 0 + +VOLTAGE_MONITOR = A2 +BATTERY = A2 + +K_TRACK = 0x10000000 +K_STEP = 0x08000000 +K_PLAY = 0x02000000 +K_REC = 0x04000000 +K_ALT = 0x00040000 +K_PATT = 0x00001000 +K_SONG = 0x00000040 +K_MENU = 0x00000020 + +K_UP = 0x00020000 +K_DOWN = 0x00800000 +K_RIGHT = 0x00000800 +K_LEFT = 0x20000000 +K_A = 0x01000000 +K_B = 0x00000001 + +K_1 = 0x00400000 +K_2 = 0x00010000 +K_3 = 0x00000400 +K_4 = 0x00000010 +K_5 = 0x00000002 +K_6 = 0x00000080 +K_7 = 0x00002000 +K_8 = 0x00080000 +K_9 = 0x00200000 +K_10 = 0x00008000 +K_11 = 0x00000200 +K_12 = 0x00000008 +K_13 = 0x00000004 +K_14 = 0x00000100 +K_15 = 0x00004000 +K_16 = 0x00100000 + +KEY_LIST = [ + K_TRACK, + K_STEP, + K_PLAY, + K_REC, + K_ALT, + K_PATT, + K_SONG, + K_MENU, + K_UP, + K_DOWN, + K_RIGHT, + K_LEFT, + K_A, + K_B, + K_1, + K_2, + K_3, + K_4, + K_5, + K_6, + K_7, + K_8, + K_9, + K_10, + K_11, + K_12, + K_13, + K_14, + K_15, + K_16, +] + +KEY_NAME = { + K_TRACK: "Track", + K_STEP: "Step", + K_PLAY: "Play", + K_REC: "Rec", + K_ALT: "Alt", + K_PATT: "Pattern", + K_SONG: "Song", + K_MENU: "Menu", + K_UP: "Up", + K_DOWN: "Down", + K_RIGHT: "Right", + K_LEFT: "Left", + K_A: "A", + K_B: "B", + K_1: "1", + K_2: "2", + K_3: "3", + K_4: "4", + K_5: "5", + K_6: "6", + K_7: "7", + K_8: "8", + K_9: "9", + K_10: "10", + K_11: "11", + K_12: "12", + K_13: "13", + K_14: "14", + K_15: "15", + K_16: "16", +} + +LED_MENU = 0 +LED_SONG = 1 +LED_PATT = 2 +LED_ALT = 3 +LED_TRACK = 4 +LED_K_1 = 5 +LED_K_2 = 6 +LED_K_3 = 7 +LED_K_4 = 8 +LED_K_5 = 9 +LED_K_6 = 10 +LED_K_7 = 11 +LED_K_8 = 12 +LED_PLAY = 13 +LED_STEP = 14 +LED_K_9 = 15 +LED_K_10 = 16 +LED_K_11 = 17 +LED_K_12 = 18 +LED_K_13 = 19 +LED_K_14 = 20 +LED_K_15 = 21 +LED_K_16 = 22 +LED_REC = 23 + +_KEY_COL = [ + DigitalInOut(GP21), + DigitalInOut(GP22), + DigitalInOut(GP26), + DigitalInOut(GP23), + DigitalInOut(GP29), +] +_KEY_ROW = [ + DigitalInOut(GP20), + DigitalInOut(GP18), + DigitalInOut(GP19), + DigitalInOut(GP24), + DigitalInOut(GP25), + DigitalInOut(GP27), +] + +for pin in _KEY_COL: + pin.direction = Direction.OUTPUT + pin.value = False + +for pin in _KEY_ROW: + pin.direction = Direction.INPUT + pin.pull = Pull.DOWN + + +def scan_keyboard(): + global _KEYBOARD_STATE + global _KEYBOARD_PREV_STATE + + val = 0 + for col in _KEY_COL: + col.value = True + for row in _KEY_ROW: + val = val << 1 + if row.value: + val = val | 1 + col.value = False + _KEYBOARD_PREV_STATE = _KEYBOARD_STATE + _KEYBOARD_STATE = val + + +def pressed(keys): + global _KEYBOARD_STATE + + return (_KEYBOARD_STATE & keys) != 0 + + +def falling(keys): + global _KEYBOARD_STATE + global _KEYBOARD_PREV_STATE + + all_falling_keys = _KEYBOARD_STATE & ~_KEYBOARD_PREV_STATE + return (all_falling_keys & keys) != 0 + + +def raising(keys): + global _KEYBOARD_STATE + global _KEYBOARD_PREV_STATE + + all_raising_keys = ~_KEYBOARD_STATE & _KEYBOARD_PREV_STATE + return (all_raising_keys & keys) != 0 + + +def display(spi_frequency=1000000): + global _DISPLAY + + if not _DISPLAY: + displayio.release_displays() + + spi = busio.SPI(GP10, GP11) + cs = None + dc = GP12 + reset = GP13 + + display_bus = FourWire( + spi, command=dc, chip_select=cs, reset=reset, baudrate=spi_frequency + ) + _DISPLAY = adafruit_displayio_ssd1306.SSD1306(display_bus, width=128, height=64) + + return _DISPLAY + + +def neopixel(brightness=0.1): + global _LEDS + + if not _LEDS: + _LEDS = NeoPixel(GP14, 24, brightness=brightness) + + return _LEDS + + +def key_to_led(key): + map = { + K_TRACK: LED_TRACK, + K_STEP: LED_STEP, + K_PLAY: LED_PLAY, + K_REC: LED_REC, + K_ALT: LED_ALT, + K_PATT: LED_PATT, + K_SONG: LED_SONG, + K_MENU: LED_MENU, + K_1: LED_K_1, + K_2: LED_K_2, + K_3: LED_K_3, + K_4: LED_K_4, + K_5: LED_K_5, + K_6: LED_K_6, + K_7: LED_K_7, + K_8: LED_K_8, + K_9: LED_K_9, + K_10: LED_K_10, + K_11: LED_K_11, + K_12: LED_K_12, + K_13: LED_K_13, + K_14: LED_K_14, + K_15: LED_K_15, + K_16: LED_K_16, + } + return map[key] + + +def simple_synth(synth, verbose=False): + base_note = 60 + + leds = neopixel() + + keys = [ + (K_9, 0), + (K_2, 1), + (K_10, 2), + (K_3, 3), + (K_11, 4), + (K_12, 5), + (K_5, 6), + (K_13, 7), + (K_6, 8), + (K_14, 9), + (K_7, 10), + (K_15, 11), + (K_16, 12), + ] + + for key, _ in keys: + leds[key_to_led(key)] = (0, 0, 255) + leds[key_to_led(K_1)] = (255, 255, 0) + leds[key_to_led(K_8)] = (255, 255, 0) + leds.show() + + while True: + scan_keyboard() + + # Lower base note 1 octave down + if falling(K_1) and base_note > 12: + # Turn off any potentially on notes + for _, offset in keys: + synth.release(base_note + offset) + base_note -= 12 + if verbose: + print("Octave down") + + # Raise base note 1 octave up + if falling(K_8) and base_note <= 96: + # Turn off any potentially on notes + for _, offset in keys: + synth.release(base_note + offset) + base_note += 12 + if verbose: + print("Octave up") + + for key, offset in keys: + note = base_note + offset + if falling(key): + if verbose: + print("On " + str(note)) + synth.press(note) + if raising(key): + if verbose: + print("Off " + str(note)) + synth.release(note) diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/pico-sdk-configboard.h b/ports/raspberrypi/boards/weenoisemakers_noisenugget/pico-sdk-configboard.h new file mode 100644 index 00000000000..36da55d4571 --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/pico-sdk-configboard.h @@ -0,0 +1 @@ +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/weenoisemakers_noisenugget/pins.c b/ports/raspberrypi/boards/weenoisemakers_noisenugget/pins.c new file mode 100644 index 00000000000..bbd3105956b --- /dev/null +++ b/ports/raspberrypi/boards/weenoisemakers_noisenugget/pins.c @@ -0,0 +1,54 @@ +#include "shared-bindings/board/__init__.h" + +const mcu_pin_obj_t pin_GPIO_fake; + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_NEOPIXEL), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_GP29_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_GP29), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.h b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.h index ba60f5f72d2..b3ff46a70d7 100644 --- a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.h +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.h @@ -9,9 +9,14 @@ #define MICROPY_HW_BOARD_NAME "W5100S-EVB-Pico" #define MICROPY_HW_MCU_NAME "rp2040" +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + #define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.mk index c7b6f312fc5..3ab04a09833 100644 --- a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.mk +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/mpconfigboard.mk @@ -9,3 +9,9 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" CIRCUITPY__EVE = 1 +CIRCUITPY_FLOPPYIO = 0 +CIRCUITPY_SSL = 1 +CIRCUITPY_USB_HOST = 0 + +# The default is -O3. Change to -O2 because the build was overflowing. +OPTIMIZATION_FLAGS = -O2 diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/pins.c b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/pins.c index 1263586686b..969affad785 100644 --- a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/pins.c +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico/pins.c @@ -25,12 +25,25 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MISO), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_CS), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MOSI), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_RST), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_INT), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, @@ -56,5 +69,9 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/board.c b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/mpconfigboard.h b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/mpconfigboard.h new file mode 100644 index 00000000000..f8d7378c2d9 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "W5100S-EVB-Pico2" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/mpconfigboard.mk new file mode 100644 index 00000000000..d47571e7950 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/mpconfigboard.mk @@ -0,0 +1,19 @@ +USB_VID = 0x2E8A +USB_PID = 0x109E +USB_PRODUCT = "W5100S-EVB-Pico2" +USB_MANUFACTURER = "WIZnet" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 +CIRCUITPY_SSL = 1 + +# GPIO12-19 needed for picodvi, but GPIO16 is used for Wiznet. +CIRCUITPY_PICODVI = 0 + +# The default is -O3. Change to -O2 because the build was overflowing. +OPTIMIZATION_FLAGS = -O2 diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/pico-sdk-configboard.h b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/pins.c b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/pins.c new file mode 100644 index 00000000000..dbc4e9ad76d --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5100s_evb_pico2/pins.c @@ -0,0 +1,77 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_CS), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_RST), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_INT), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.h b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.h index 7aeca9bdb2c..95cd9be2cce 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.h +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.h @@ -9,9 +9,14 @@ #define MICROPY_HW_BOARD_NAME "W5500-EVB-Pico" #define MICROPY_HW_MCU_NAME "rp2040" +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + #define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) #define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) #define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) #define DEFAULT_UART_BUS_RX (&pin_GPIO1) #define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk index 127cdaba380..4a8343963bc 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/mpconfigboard.mk @@ -9,4 +9,9 @@ CHIP_FAMILY = rp2 EXTERNAL_FLASH_DEVICES = "W25Q16JVxQ" CIRCUITPY__EVE = 1 +CIRCUITPY_FLOPPYIO = 0 CIRCUITPY_SSL = 1 +CIRCUITPY_USB_HOST = 0 + +# The default is -O3. Change to -O2 because the build was overflowing. +OPTIMIZATION_FLAGS = -O2 diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c index a24ff3f3a60..969affad785 100644 --- a/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico/pins.c @@ -26,22 +26,22 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, - { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_W5K_MISO), MP_ROM_PTR(&pin_GPIO16) }, { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, - { MP_ROM_QSTR(MP_QSTR_W5500_CS), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_W5K_CS), MP_ROM_PTR(&pin_GPIO17) }, { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, - { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_W5K_SCK), MP_ROM_PTR(&pin_GPIO18) }, { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, - { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_W5K_MOSI), MP_ROM_PTR(&pin_GPIO19) }, { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, - { MP_ROM_QSTR(MP_QSTR_W5500_RST), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_W5K_RST), MP_ROM_PTR(&pin_GPIO20) }, { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, - { MP_ROM_QSTR(MP_QSTR_W5500_INT), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_W5K_INT), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, @@ -55,12 +55,10 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, - { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, - { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, @@ -72,8 +70,8 @@ static const mp_rom_map_elem_t board_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_W5K_SPI), MP_ROM_PTR(&board_spi_obj) }, { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, }; MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/board.c b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/board.c new file mode 100644 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/mpconfigboard.h b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/mpconfigboard.h new file mode 100644 index 00000000000..6523d82a38d --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/mpconfigboard.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "W5500-EVB-Pico2" +#define MICROPY_HW_MCU_NAME "rp2350a" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO25) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO18) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO19) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO16) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO5, .sda = &pin_GPIO4}} diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/mpconfigboard.mk new file mode 100644 index 00000000000..68b621fdf97 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/mpconfigboard.mk @@ -0,0 +1,19 @@ +USB_VID = 0x2E8A +USB_PID = 0x109F +USB_PRODUCT = "W5500-EVB-Pico2" +USB_MANUFACTURER = "WIZnet" + +CHIP_VARIANT = RP2350 +CHIP_PACKAGE = A +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "W25Q32JVxQ" + +CIRCUITPY__EVE = 1 +CIRCUITPY_SSL = 1 + +# GPIO12-19 needed for picodvi, but GPIO16 is used for Wiznet. +CIRCUITPY_PICODVI = 0 + +# The default is -O3. Change to -O2 because the build was overflowing. +OPTIMIZATION_FLAGS = -O2 diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/pico-sdk-configboard.h b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/pico-sdk-configboard.h new file mode 100644 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/pins.c b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/pins.c new file mode 100644 index 00000000000..dbc4e9ad76d --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w5500_evb_pico2/pins.c @@ -0,0 +1,77 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MISO), MP_ROM_PTR(&pin_GPIO16) }, + { MP_ROM_QSTR(MP_QSTR_GP16), MP_ROM_PTR(&pin_GPIO16) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_CS), MP_ROM_PTR(&pin_GPIO17) }, + { MP_ROM_QSTR(MP_QSTR_GP17), MP_ROM_PTR(&pin_GPIO17) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SCK), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MOSI), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_RST), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_INT), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_SMPS_MODE), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/board.c b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/board.c new file mode 100755 index 00000000000..e6a868ab212 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/board.c @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/mpconfigboard.h b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/mpconfigboard.h new file mode 100755 index 00000000000..b5ccfb5ffd9 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/mpconfigboard.h @@ -0,0 +1,30 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#define MICROPY_HW_BOARD_NAME "W55RP20-EVB-Pico" +#define MICROPY_HW_MCU_NAME "rp2040" + +#define MICROPY_HW_LED_STATUS (&pin_GPIO19) + +#define DEFAULT_SPI_BUS_SCK (&pin_GPIO21) +#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO23) +#define DEFAULT_SPI_BUS_MISO (&pin_GPIO22) + +#define DEFAULT_UART_BUS_RX (&pin_GPIO1) +#define DEFAULT_UART_BUS_TX (&pin_GPIO0) + +// Wiznet HW config. +#define MICROPY_HW_WIZNET_PIO_SPI_ID (0) +#define MICROPY_HW_WIZNET_PIO_SPI_BAUDRATE (20 * 1000 * 1000) +#define MICROPY_HW_WIZNET_PIO_SPI_SCK (21) +#define MICROPY_HW_WIZNET_PIO_SPI_MOSI (23) +#define MICROPY_HW_WIZNET_PIO_SPI_MISO (22) +#define MICROPY_HW_WIZNET_PIO_PIN_CS (20) +#define MICROPY_HW_WIZNET_PIO_PIN_RST (25) +// Connecting the INTN pin enables RECV interrupt handling of incoming data. +#define MICROPY_HW_WIZNET_PIN_INTN (24) diff --git a/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/mpconfigboard.mk b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/mpconfigboard.mk new file mode 100755 index 00000000000..d43195c0f2a --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/mpconfigboard.mk @@ -0,0 +1,16 @@ +USB_VID = 0x2E8A +USB_PID = 0x0005 +USB_PRODUCT = "W55RP20-EVB-Pico" +USB_MANUFACTURER = "WIZnet" + +CHIP_VARIANT = RP2040 +CHIP_FAMILY = rp2 + +EXTERNAL_FLASH_DEVICES = "PY25Q16HB" + +CIRCUITPY_WIZNET = 1 +CIRCUITPY__EVE = 1 +CIRCUITPY_SSL = 1 +CIRCUITPY_USB_HOST = 0 + +OPTIMIZATION_FLAGS = -O2 diff --git a/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/pico-sdk-configboard.h b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/pico-sdk-configboard.h new file mode 100755 index 00000000000..110195b7794 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/pico-sdk-configboard.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Put board-specific pico-sdk definitions here. This file must exist. diff --git a/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/pins.c b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/pins.c new file mode 100755 index 00000000000..37ecfd3dfb1 --- /dev/null +++ b/ports/raspberrypi/boards/wiznet_w55rp20_evb_pico/pins.c @@ -0,0 +1,72 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_GP0), MP_ROM_PTR(&pin_GPIO0) }, + { MP_ROM_QSTR(MP_QSTR_GP1), MP_ROM_PTR(&pin_GPIO1) }, + { MP_ROM_QSTR(MP_QSTR_GP2), MP_ROM_PTR(&pin_GPIO2) }, + { MP_ROM_QSTR(MP_QSTR_GP3), MP_ROM_PTR(&pin_GPIO3) }, + { MP_ROM_QSTR(MP_QSTR_GP4), MP_ROM_PTR(&pin_GPIO4) }, + { MP_ROM_QSTR(MP_QSTR_GP5), MP_ROM_PTR(&pin_GPIO5) }, + { MP_ROM_QSTR(MP_QSTR_GP6), MP_ROM_PTR(&pin_GPIO6) }, + { MP_ROM_QSTR(MP_QSTR_GP7), MP_ROM_PTR(&pin_GPIO7) }, + { MP_ROM_QSTR(MP_QSTR_GP8), MP_ROM_PTR(&pin_GPIO8) }, + { MP_ROM_QSTR(MP_QSTR_GP9), MP_ROM_PTR(&pin_GPIO9) }, + { MP_ROM_QSTR(MP_QSTR_GP10), MP_ROM_PTR(&pin_GPIO10) }, + { MP_ROM_QSTR(MP_QSTR_GP11), MP_ROM_PTR(&pin_GPIO11) }, + { MP_ROM_QSTR(MP_QSTR_GP12), MP_ROM_PTR(&pin_GPIO12) }, + { MP_ROM_QSTR(MP_QSTR_GP13), MP_ROM_PTR(&pin_GPIO13) }, + { MP_ROM_QSTR(MP_QSTR_GP14), MP_ROM_PTR(&pin_GPIO14) }, + { MP_ROM_QSTR(MP_QSTR_GP15), MP_ROM_PTR(&pin_GPIO15) }, + + { MP_ROM_QSTR(MP_QSTR_VBUS_SENSE), MP_ROM_PTR(&pin_GPIO18) }, + { MP_ROM_QSTR(MP_QSTR_GP18), MP_ROM_PTR(&pin_GPIO18) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_GPIO19) }, + { MP_ROM_QSTR(MP_QSTR_GP19), MP_ROM_PTR(&pin_GPIO19) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_CS), MP_ROM_PTR(&pin_GPIO20) }, + { MP_ROM_QSTR(MP_QSTR_GP20), MP_ROM_PTR(&pin_GPIO20) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SCK), MP_ROM_PTR(&pin_GPIO21) }, + { MP_ROM_QSTR(MP_QSTR_GP21), MP_ROM_PTR(&pin_GPIO21) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MISO), MP_ROM_PTR(&pin_GPIO22) }, + { MP_ROM_QSTR(MP_QSTR_GP22), MP_ROM_PTR(&pin_GPIO22) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_MOSI), MP_ROM_PTR(&pin_GPIO23) }, + { MP_ROM_QSTR(MP_QSTR_GP23), MP_ROM_PTR(&pin_GPIO23) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_INT), MP_ROM_PTR(&pin_GPIO24) }, + { MP_ROM_QSTR(MP_QSTR_GP24), MP_ROM_PTR(&pin_GPIO24) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_RST), MP_ROM_PTR(&pin_GPIO25) }, + { MP_ROM_QSTR(MP_QSTR_GP25), MP_ROM_PTR(&pin_GPIO25) }, + + { MP_ROM_QSTR(MP_QSTR_GP26_A0), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_GP26), MP_ROM_PTR(&pin_GPIO26) }, + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO26) }, + + { MP_ROM_QSTR(MP_QSTR_GP27_A1), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_GP27), MP_ROM_PTR(&pin_GPIO27) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO27) }, + + { MP_ROM_QSTR(MP_QSTR_GP28_A2), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_GP28), MP_ROM_PTR(&pin_GPIO28) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO28) }, + + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO29) }, + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_GPIO29) }, + + { MP_ROM_QSTR(MP_QSTR_W5K_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, + { MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_i2c_obj) }, +}; +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/raspberrypi/boards/wk-50/board.c b/ports/raspberrypi/boards/wk-50/board.c index 9ebde0a6f33..2ea197d2b2e 100644 --- a/ports/raspberrypi/boards/wk-50/board.c +++ b/ports/raspberrypi/boards/wk-50/board.c @@ -6,7 +6,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" void reset_board(void) { diff --git a/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c b/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c index 415a7b3b3e8..f8e9958433b 100644 --- a/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c +++ b/ports/raspberrypi/boards/zrichard_rp2.65-f/board.c @@ -6,7 +6,7 @@ #include "supervisor/board.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include "supervisor/shared/board.h" void reset_board(void) { diff --git a/ports/raspberrypi/boot_stage2/RP2040.c.jinja b/ports/raspberrypi/boot_stage2/RP2040.c.jinja index 4c001525dcc..c00b35fa662 100644 --- a/ports/raspberrypi/boot_stage2/RP2040.c.jinja +++ b/ports/raspberrypi/boot_stage2/RP2040.c.jinja @@ -1,7 +1,7 @@ -#include "sdk/src/rp2040/hardware_structs/include/hardware/structs/ssi.h" -#include "sdk/src/rp2040/hardware_structs/include/hardware/structs/pads_qspi.h" -#include "sdk/src/rp2040/hardware_regs/include/hardware/regs/addressmap.h" -#include "sdk/src/rp2040/hardware_regs/include/hardware/regs/m0plus.h" +#include "hardware/structs/ssi.h" +#include "hardware/structs/pads_qspi.h" +#include "hardware/regs/addressmap.h" +#include "hardware/regs/m0plus.h" // "Mode bits" are 8 special bits sent immediately after // the address bits in a "Read Data Fast Quad I/O" command sequence. diff --git a/ports/raspberrypi/common-hal/alarm/__init__.c b/ports/raspberrypi/common-hal/alarm/__init__.c index 35af1655100..39ad8ca1fe6 100644 --- a/ports/raspberrypi/common-hal/alarm/__init__.c +++ b/ports/raspberrypi/common-hal/alarm/__init__.c @@ -141,6 +141,10 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj mp_obj_t wake_alarm = mp_const_none; + // Save current clocks. + uint32_t saved_sleep_en0 = clocks_hw->sleep_en0; + uint32_t saved_sleep_en1 = clocks_hw->sleep_en1; + while (!mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; // Detect if interrupt was alarm or ctrl-C interrupt. @@ -163,33 +167,34 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj break; } - // Prune the clock for sleep + // Prune the clocks for sleep. clocks_hw->sleep_en0 &= RP_LIGHTSLEEP_EN0_MASK; clocks_hw->sleep_en1 = RP_LIGHTSLEEP_EN1_MASK; // Enable System Control Block (SCB) deep sleep - uint save = scb_hw->scr; - scb_hw->scr = save | M0PLUS_SCR_SLEEPDEEP_BITS; + scb_hw->scr |= M0PLUS_SCR_SLEEPDEEP_BITS; __wfi(); } + // Restore clocks so other wfi() uses, like time.sleep(), won't use the light-sleep settings. + clocks_hw->sleep_en0 = saved_sleep_en0; + clocks_hw->sleep_en1 = saved_sleep_en1; + if (mp_hal_is_interrupted()) { return mp_const_none; // Shouldn't be given to python code because exception handling should kick in. } + alarm_reset(); return wake_alarm; } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { - if (n_dios > 0) { - mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_preserve_dios); - } _setup_sleep_alarms(true, n_alarms, alarms); } -void NORETURN common_hal_alarm_enter_deep_sleep(void) { +void MP_NORETURN common_hal_alarm_enter_deep_sleep(void) { bool timealarm_set = alarm_time_timealarm_is_set(); #if CIRCUITPY_CYW43 diff --git a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c index ecebb072775..350306390ee 100644 --- a/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c +++ b/ports/raspberrypi/common-hal/alarm/pin/PinAlarm.c @@ -39,7 +39,7 @@ static void gpio_callback(uint gpio, uint32_t events) { } } -void alarm_pin_pinalarm_entering_deep_sleep() { +void alarm_pin_pinalarm_entering_deep_sleep(void) { _not_yet_deep_sleeping = false; } diff --git a/ports/raspberrypi/common-hal/analogbufio/BufferedIn.c b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.c index 7385b21ea95..fe74f321392 100644 --- a/ports/raspberrypi/common-hal/analogbufio/BufferedIn.c +++ b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.c @@ -11,20 +11,25 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared/runtime/interrupt_char.h" #include "py/runtime.h" -#include "src/rp2_common/hardware_adc/include/hardware/adc.h" -#include "src/rp2_common/hardware_dma/include/hardware/dma.h" -#include "src/common/pico_stdlib_headers/include/pico/stdlib.h" - -#define ADC_FIRST_PIN_NUMBER 26 -#define ADC_PIN_COUNT 4 +#include "hardware/adc.h" +#include "hardware/dma.h" +#include "pico/stdlib.h" #define ADC_CLOCK_INPUT 48000000 #define ADC_MAX_CLOCK_DIV (1 << (ADC_DIV_INT_MSB - ADC_DIV_INT_LSB + 1)) void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *self, const mcu_pin_obj_t *pin, uint32_t sample_rate) { // Make sure pin number is in range for ADC - if (pin->number < ADC_FIRST_PIN_NUMBER || pin->number >= (ADC_FIRST_PIN_NUMBER + ADC_PIN_COUNT)) { - raise_ValueError_invalid_pins(); + if ((pin->number < ADC_BASE_PIN) + || (pin->number > ADC_BASE_PIN + NUM_ADC_CHANNELS - 1) + // On many boards with a CYW43 radio co-processor, CYW43_DEFAULT_PIN_WL_CLOCK (usually GPIO29), + // is both a voltage monitor and also SPI SCK to the CYW43. + // Disallow its use for BufferedIn. + #if defined(CIRCUITPY_CYW43) && defined(CYW43_DEFAULT_PIN_WL_CLOCK) + || (pin->number == CYW43_DEFAULT_PIN_WL_CLOCK) + #endif + ) { + raise_ValueError_invalid_pin(); } // Validate sample rate here @@ -35,7 +40,7 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s claim_pin(pin); // TODO: find a way to accept ADC4 for temperature - self->chan = pin->number - ADC_FIRST_PIN_NUMBER; + self->chan = pin->number - ADC_BASE_PIN; // Init GPIO for analogue use: hi-Z, no pulls, disable digital input buffer. // TODO: Make sure we share the ADC well. Right now we just assume it is diff --git a/ports/raspberrypi/common-hal/analogbufio/BufferedIn.h b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.h index f0c536f3921..587668c1a7b 100644 --- a/ports/raspberrypi/common-hal/analogbufio/BufferedIn.h +++ b/ports/raspberrypi/common-hal/analogbufio/BufferedIn.h @@ -8,7 +8,7 @@ #pragma once #include "common-hal/microcontroller/Pin.h" -#include "src/rp2_common/hardware_dma/include/hardware/dma.h" +#include "hardware/dma.h" #include "py/obj.h" diff --git a/ports/raspberrypi/common-hal/analogio/AnalogIn.c b/ports/raspberrypi/common-hal/analogio/AnalogIn.c index 301b965c86c..2a9c2d1d42d 100644 --- a/ports/raspberrypi/common-hal/analogio/AnalogIn.c +++ b/ports/raspberrypi/common-hal/analogio/AnalogIn.c @@ -10,22 +10,14 @@ #include "shared-bindings/microcontroller/Pin.h" #include "py/runtime.h" -#include "src/rp2_common/hardware_adc/include/hardware/adc.h" +#include "hardware/adc.h" -#define ADC_PIN_COUNT (NUM_ADC_CHANNELS - 1) - -#if ADC_PIN_COUNT == 4 -#define ADC_FIRST_PIN_NUMBER 26 -#else -#define ADC_FIRST_PIN_NUMBER 40 -#endif - -// Voltage monitor is special on Pico W, because this pin is shared between the -// voltage monitor function and the wifi function. Special handling is required -// to read the analog voltage. +// On many boards with a CYW43 radio co-processor, CYW43_DEFAULT_PIN_WL_CLOCK (usually GPIO29), +// is both a voltage monitor and also SPI SCK to the CYW43. +// Special handling is required to read the analog voltage. #if CIRCUITPY_CYW43 #include "bindings/cyw43/__init__.h" -#define SPECIAL_PIN(pin) (pin->number == 29) +#define SPECIAL_PIN(pin) (pin->number == CYW43_DEFAULT_PIN_WL_CLOCK) const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj) { return validate_obj_is_free_pin_or_gpio29(obj, MP_QSTR_pin); @@ -35,7 +27,7 @@ const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t obj) { #endif void common_hal_analogio_analogin_construct(analogio_analogin_obj_t *self, const mcu_pin_obj_t *pin) { - if (pin->number < ADC_FIRST_PIN_NUMBER || pin->number > ADC_FIRST_PIN_NUMBER + ADC_PIN_COUNT) { + if (pin->number < ADC_BASE_PIN || pin->number > ADC_BASE_PIN + NUM_ADC_CHANNELS - 1) { raise_ValueError_invalid_pin(); } @@ -70,7 +62,7 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { uint32_t old_pad = pads_bank0_hw->io[self->pin->number]; uint32_t old_ctrl = io_bank0_hw->io[self->pin->number].ctrl; adc_gpio_init(self->pin->number); - adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER); + adc_select_input(self->pin->number - ADC_BASE_PIN); common_hal_mcu_delay_us(100); value = adc_read(); gpio_init(self->pin->number); @@ -78,7 +70,7 @@ uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { io_bank0_hw->io[self->pin->number].ctrl = old_ctrl; common_hal_mcu_enable_interrupts(); } else { - adc_select_input(self->pin->number - ADC_FIRST_PIN_NUMBER); + adc_select_input(self->pin->number - ADC_BASE_PIN); value = adc_read(); } // Stretch 12-bit ADC reading to 16-bit range diff --git a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c index 60200e5c121..2687af52e2d 100644 --- a/ports/raspberrypi/common-hal/audiobusio/I2SOut.c +++ b/ports/raspberrypi/common-hal/audiobusio/I2SOut.c @@ -19,139 +19,248 @@ #include "bindings/rp2pio/StateMachine.h" const uint16_t i2s_program[] = { -// ; Load the next set of samples -// ; /--- LRCLK -// ; |/-- BCLK -// ; || -// pull noblock side 0b01 ; Loads OSR with the next FIFO value or X - 0x8880, -// mov x osr side 0b01 ; Save the new value in case we need it again - 0xa827, -// set y 14 side 0b01 - 0xe84e, -// bitloop1: -// out pins 1 side 0b00 [2] - 0x6201, -// jmp y-- bitloop1 side 0b01 [2] - 0x0a83, -// out pins 1 side 0b10 [2] - 0x7201, -// set y 14 side 0b11 [2] - 0xfa4e, -// bitloop0: -// out pins 1 side 0b10 [2] - 0x7201, -// jmp y-- bitloop0 side 0b11 [2] - 0x1a87, -// out pins 1 side 0b00 [2] - 0x6201 + +/* From i2s.pio: + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- LRCLK + ; |/-- BCLK + ; || + pull noblock side 0b11 ; Loads OSR with the next FIFO value or X + mov x osr side 0b11 ; Save the new value in case we need it again + set y 14 side 0b11 +bitloop1: + out pins 1 side 0b10 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b00 [2] + set y 14 side 0b01 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b01 [2] + out pins 1 side 0b10 [2] +*/ + // Above assembled with pioasm. + 0x9880, // 0: pull noblock side 3 + 0xb827, // 1: mov x, osr side 3 + 0xf84e, // 2: set y, 14 side 3 + 0x7201, // 3: out pins, 1 side 2 [2] + 0x1a83, // 4: jmp y--, 3 side 3 [2] + 0x6201, // 5: out pins, 1 side 0 [2] + 0xea4e, // 6: set y, 14 side 1 [2] + 0x6201, // 7: out pins, 1 side 0 [2] + 0x0a87, // 8: jmp y--, 7 side 1 [2] + 0x7201, // 9: out pins, 1 side 2 [2] }; + const uint16_t i2s_program_left_justified[] = { -// ; Load the next set of samples -// ; /--- LRCLK -// ; |/-- BCLK -// ; || -// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X - 0x9880, -// mov x osr side 0b11 ; Save the new value in case we need it again - 0xb827, -// set y 14 side 0b11 - 0xf84e, -// bitloop1: -// out pins 1 side 0b00 [2] - 0x6201, -// jmp y-- bitloop1 side 0b01 [2] - 0x0a83, -// out pins 1 side 0b00 [2] - 0x6201, -// set y 14 side 0b01 [2] - 0xea4e, -// bitloop0: -// out pins 1 side 0b10 [2] - 0x7201, -// jmp y-- bitloop0 side 0b11 [2] - 0x1a87, -// out pins 1 side 0b10 [2] - 0x7201 +/* From i2s_left.pio: + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- LRCLK + ; |/-- BCLK + ; || + pull noblock side 0b01 ; Loads OSR with the next FIFO value or X + mov x osr side 0b01 ; Save the new value in case we need it again + set y 14 side 0b01 +bitloop1: + out pins 1 side 0b10 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b10 [2] + set y 14 side 0b11 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b01 [2] + out pins 1 side 0b00 [2] +*/ + // Above assembled with pioasm. + 0x8880, // 0: pull noblock side 1 + 0xa827, // 1: mov x, osr side 1 + 0xe84e, // 2: set y, 14 side 1 + 0x7201, // 3: out pins, 1 side 2 [2] + 0x1a83, // 4: jmp y--, 3 side 3 [2] + 0x7201, // 5: out pins, 1 side 2 [2] + 0xfa4e, // 6: set y, 14 side 3 [2] + 0x6201, // 7: out pins, 1 side 0 [2] + 0x0a87, // 8: jmp y--, 7 side 1 [2] + 0x6201, // 9: out pins, 1 side 0 [2] }; // Another version of i2s_program with the LRCLC and BCLK pin swapped const uint16_t i2s_program_swap[] = { -// ; Load the next set of samples -// ; /--- BCLK -// ; |/-- LRCLK -// ; || -// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X - 0x9880, -// mov x osr side 0b11 ; Save the new value in case we need it again - 0xb827, -// set y 14 side 0b11 - 0xf84e, -// bitloop1: -// out pins 1 side 0b01 [2] - 0x6a01, -// jmp y-- bitloop1 side 0b11 [2] - 0x1a83, -// out pins 1 side 0b00 [2] - 0x6201, -// set y 14 side 0b10 [2] - 0xf24e, -// bitloop0: -// out pins 1 side 0b00 [2] - 0x6201, -// jmp y-- bitloop0 side 0b10 [2] - 0x1287, -// out pins 1 side 0b01 [2] - 0x6a01 +/* From i2s_swap.pio: + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- BCLK + ; |/-- LRCLK + ; || + pull noblock side 0b11 ; Loads OSR with the next FIFO value or X + mov x osr side 0b11 ; Save the new value in case we need it again + set y 14 side 0b11 +bitloop1: + out pins 1 side 0b01 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b00 [2] + set y 14 side 0b10 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b10 [2] + out pins 1 side 0b01 [2] +*/ + // Above assembled with pioasm. + 0x9880, // 0: pull noblock side 3 + 0xb827, // 1: mov x, osr side 3 + 0xf84e, // 2: set y, 14 side 3 + 0x6a01, // 3: out pins, 1 side 1 [2] + 0x1a83, // 4: jmp y--, 3 side 3 [2] + 0x6201, // 5: out pins, 1 side 0 [2] + 0xf24e, // 6: set y, 14 side 2 [2] + 0x6201, // 7: out pins, 1 side 0 [2] + 0x1287, // 8: jmp y--, 7 side 2 [2] + 0x6a01, // 9: out pins, 1 side 1 [2] }; // Another version of i2s_program_left_justified with the LRCLC and BCLK pin // swapped. const uint16_t i2s_program_left_justified_swap[] = { -// ; Load the next set of samples -// ; /--- BCLK -// ; |/-- LRCLK -// ; || -// pull noblock side 0b11 ; Loads OSR with the next FIFO value or X - 0x9880, -// mov x osr side 0b11 ; Save the new value in case we need it again - 0xb827, -// set y 14 side 0b11 - 0xf84e, -// bitloop1: -// out pins 1 side 0b00 [2] - 0x6201, -// jmp y-- bitloop1 side 0b10 [2] - 0x1283, -// out pins 1 side 0b00 [2] - 0x6201, -// set y 14 side 0b10 [2] - 0xf24e, -// bitloop0: -// out pins 1 side 0b01 [2] - 0x6a01, -// jmp y-- bitloop0 side 0b11 [2] - 0x1a87, -// out pins 1 side 0b01 [2] - 0x6a01 +/* From i2s_swap_left.pio: + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- BCLK + ; |/-- LRCLK + ; || + pull noblock side 0b10 ; Loads OSR with the next FIFO value or X + mov x osr side 0b10 ; Save the new value in case we need it again + set y 14 side 0b10 +bitloop1: + out pins 1 side 0b01 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b01 [2] + set y 14 side 0b11 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b10 [2] + out pins 1 side 0b00 [2] +*/ + // Above assembled with pioasm. + 0x9080, // 0: pull noblock side 2 + 0xb027, // 1: mov x, osr side 2 + 0xf04e, // 2: set y, 14 side 2 + 0x6a01, // 3: out pins, 1 side 1 [2] + 0x1a83, // 4: jmp y--, 3 side 3 [2] + 0x6a01, // 5: out pins, 1 side 1 [2] + 0xfa4e, // 6: set y, 14 side 3 [2] + 0x6201, // 7: out pins, 1 side 0 [2] + 0x1287, // 8: jmp y--, 7 side 2 [2] + 0x6201, // 9: out pins, 1 side 0 [2] }; +// External-clock TX. BCLK and WS are inputs driven by something +// else, so the state machine side-sets nothing and waits on the two clocks +// instead. `wait gpio` encodes an absolute pin index, so unlike the internal-clock +// programs above this one cannot be a static table: it is assembled at +// construct time with the pin numbers patched in. +// +// 0: wait 0 gpio W +// 1: wait 1 gpio W ; right channel starts (WS changes on a BCLK fall) +// .wrap_target +// 2: pull noblock ; refills OSR from X on underflow, as the internal-clock program does +// 3: mov x, osr +// 4: set y, 31 +// 5: wait 1 gpio B +// 6: wait 0 gpio B ; drive on the falling edge; receiver latches on rising +// 7: out pins, 1 +// 8: jmp y--, 5 +// .wrap +// +// Left-justified moves the `out` ahead of the two waits, which drives the MSB +// on the same falling edge WS changed on. The first loop iteration's `wait 1` +// otherwise lands on the Philips delay bit, so no pre-roll is needed. +// +// One 32-bit FIFO word covers a whole 16-bit stereo frame; at 24/32 bits the +// frame is two words (right then left). Same layout the internal-clock programs use. +#define I2S_EXT_CLOCK_PROGRAM_LEN (9) +#define I2S_EXT_CLOCK_WRAP_TARGET (2) +#define I2S_EXT_CLOCK_WRAP (8) + +static void build_i2sout_ext_clock_program(uint16_t *prog, uint8_t bclk, uint8_t ws, bool left_justified) { + const uint16_t wait_0_bclk = 0x2000 | bclk; + const uint16_t wait_1_bclk = 0x2080 | bclk; + prog[0] = 0x2000 | ws; // wait 0 gpio W + prog[1] = 0x2080 | ws; // wait 1 gpio W + prog[2] = 0x8080; // pull noblock + prog[3] = 0xa027; // mov x, osr + prog[4] = 0xe05f; // set y, 31 + if (left_justified) { + prog[5] = 0x6001; // out pins, 1 + prog[6] = wait_1_bclk; + prog[7] = wait_0_bclk; + } else { + prog[5] = wait_1_bclk; + prog[6] = wait_0_bclk; + prog[7] = 0x6001; // out pins, 1 + } + prog[8] = 0x0080 | 5; // jmp y--, 5 +} + +// `wait gpio` indices are relative to the PIO's GPIO base, which +// rp2pio_statemachine_construct picks the same way. +static uint8_t i2s_wait_gpio_index(const mcu_pin_obj_t *pin, uint8_t gpio_offset) { + if (pin->number < gpio_offset) { + mp_raise_ValueError(MP_ERROR_TEXT("Cannot use GPIO0..15 together with GPIO32..47")); + } + return pin->number - gpio_offset; +} + void i2sout_reset(void) { } // Caller validates that pins are free. void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, - const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified) { + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified, + bool external_clock) { if (main_clock != NULL) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_main_clock); } const mcu_pin_obj_t *sideset_pin = NULL; const uint16_t *program = NULL; size_t program_len = 0; - - if (bit_clock->number == word_select->number - 1) { + uint16_t ext_clock_program[I2S_EXT_CLOCK_PROGRAM_LEN]; + pio_pinmask_t wait_gpio_mask = PIO_PINMASK_NONE; + + self->external_clock = external_clock; + + if (external_clock) { + // In external clock mode the clocks are `wait gpio` targets, so they + // need not be sequential GPIOs. + uint8_t gpio_offset = 0; + #if NUM_BANK0_GPIOS > 32 + if (bit_clock->number >= 32 || word_select->number >= 32 || data->number >= 32) { + gpio_offset = 16; + } + #endif + build_i2sout_ext_clock_program(ext_clock_program, + i2s_wait_gpio_index(bit_clock, gpio_offset), + i2s_wait_gpio_index(word_select, gpio_offset), + left_justified); + program = ext_clock_program; + program_len = I2S_EXT_CLOCK_PROGRAM_LEN; + wait_gpio_mask = PIO_PINMASK_OR(PIO_PINMASK_FROM_PIN(bit_clock->number), + PIO_PINMASK_FROM_PIN(word_select->number)); + } else if (bit_clock->number == word_select->number - 1) { sideset_pin = bit_clock; if (left_justified) { @@ -181,23 +290,28 @@ void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, common_hal_rp2pio_statemachine_construct( &self->state_machine, program, program_len, - 44100 * 32 * 6, // Clock at 44.1 khz to warm the DAC up. + // Clock at 44.1 khz to warm the DAC up. In external clock mode the SM + // is driven by the waits, not the clock divider, so run it at sysclk. + external_clock ? 0 : 44100 * 32 * 6, NULL, 0, // init NULL, 0, // may_exec - data, 1, 0, 0xffffffff, // out pin + data, 1, PIO_PINMASK32_NONE, PIO_PINMASK32_ALL, // out pin NULL, 0, // in pins - 0, 0, // in pulls - NULL, 0, 0, 0x1f, // set pins - sideset_pin, 2, 0, 0x1f, // sideset pins + PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // in pulls + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // set pins + sideset_pin, sideset_pin == NULL ? 0 : 2, false, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // sideset pins false, // No sideset enable NULL, PULL_NONE, // jump pin - 0, // wait gpio pins + wait_gpio_mask, // wait gpio pins + // The clocks are shared through wait_gpio_mask, which _check_gpio_mask_free + // already allows to be shared; the data pin stays exclusively ours. true, // exclusive pin use false, 32, false, // shift out left to start with MSB false, // Wait for txstall false, 32, false, // in settings false, // Not user-interruptible. - 0, -1, // wrap settings + external_clock ? I2S_EXT_CLOCK_WRAP_TARGET : 0, + external_clock ? I2S_EXT_CLOCK_WRAP : -1, // wrap settings PIO_ANY_OFFSET, PIO_FIFO_TYPE_DEFAULT, PIO_MOV_STATUS_DEFAULT, @@ -232,7 +346,9 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, common_hal_audiobusio_i2sout_stop(self); } - uint8_t bits_per_sample = audiosample_bits_per_sample(sample); + audiosample_check(sample); + + uint8_t bits_per_sample = audiosample_get_bits_per_sample(sample); // Make sure we transmit a minimum of 16 bits. // TODO: Maybe we need an intermediate object to upsample instead. This is // only needed for some I2S devices that expect at least 8. @@ -242,13 +358,19 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, // We always output stereo so output twice as many bits. uint16_t bits_per_sample_output = bits_per_sample * 2; size_t clocks_per_bit = 6; - uint32_t frequency = bits_per_sample_output * audiosample_sample_rate(sample); - uint8_t channel_count = audiosample_channel_count(sample); + uint32_t frequency = bits_per_sample_output * audiosample_get_sample_rate(sample); + uint8_t channel_count = audiosample_get_channel_count(sample); if (channel_count > 2) { mp_raise_ValueError(MP_ERROR_TEXT("Too many channels in sample.")); } - common_hal_rp2pio_statemachine_set_frequency(&self->state_machine, clocks_per_bit * frequency); + // An external clock can't be retimed: the sample rate has to match whatever + // the outside world is running WS at, or the pitch is wrong. The restart + // still matters -- it re-execs the program at its offset, so every play() + // re-syncs to WS. + if (!self->external_clock) { + common_hal_rp2pio_statemachine_set_frequency(&self->state_machine, clocks_per_bit * frequency); + } common_hal_rp2pio_statemachine_restart(&self->state_machine); // On the RP2040, output registers are always written with a 32-bit write. @@ -274,6 +396,9 @@ void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, } else if (result == AUDIO_DMA_MEMORY_ERROR) { common_hal_audiobusio_i2sout_stop(self); mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to allocate buffers for signed conversion")); + } else if (result == AUDIO_DMA_SOURCE_ERROR) { + common_hal_audiobusio_i2sout_stop(self); + mp_raise_RuntimeError(MP_ERROR_TEXT("Audio source error")); } self->playing = true; diff --git a/ports/raspberrypi/common-hal/audiobusio/I2SOut.h b/ports/raspberrypi/common-hal/audiobusio/I2SOut.h index 2996640dc2d..def66225bf3 100644 --- a/ports/raspberrypi/common-hal/audiobusio/I2SOut.h +++ b/ports/raspberrypi/common-hal/audiobusio/I2SOut.h @@ -18,6 +18,7 @@ typedef struct { rp2pio_statemachine_obj_t state_machine; audio_dma_t dma; bool left_justified; + bool external_clock; bool playing; } audiobusio_i2sout_obj_t; diff --git a/ports/raspberrypi/common-hal/audiobusio/PDMIn.c b/ports/raspberrypi/common-hal/audiobusio/PDMIn.c index b6e9d767d4b..b436469d090 100644 --- a/ports/raspberrypi/common-hal/audiobusio/PDMIn.c +++ b/ports/raspberrypi/common-hal/audiobusio/PDMIn.c @@ -43,17 +43,17 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self, // Use the state machine to manage pins. common_hal_rp2pio_statemachine_construct(&self->state_machine, pdmin, MP_ARRAY_SIZE(pdmin), - sample_rate * 32 * 2, // Frequency based on sample rate + sample_rate * OVERSAMPLING * 2, // Frequency based on sample rate NULL, 0, NULL, 0, // may_exec - NULL, 1, 0, 0xffffffff, // out pin + NULL, 1, PIO_PINMASK32_NONE, PIO_PINMASK32_ALL, // out pin data_pin, 1, // in pins - 0, 0, // in pulls - NULL, 0, 0, 0x1f, // set pins - clock_pin, 1, 0, 0x1f, // sideset pins + PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // in pulls + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // set pins + clock_pin, 1, false, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // sideset pins false, // No sideset enable NULL, PULL_NONE, // jump pin - 0, // wait gpio pins + PIO_PINMASK_NONE, // wait gpio pins true, // exclusive pin use false, 32, false, // out settings false, // Wait for txstall @@ -64,7 +64,8 @@ void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self, PIO_FIFO_TYPE_DEFAULT, PIO_MOV_STATUS_DEFAULT, PIO_MOV_N_DEFAULT); uint32_t actual_frequency = common_hal_rp2pio_statemachine_get_frequency(&self->state_machine); - if (actual_frequency < MIN_MIC_CLOCK) { + if (actual_frequency < 2 * MIN_MIC_CLOCK) { // 2 PIO samples per audio clock + common_hal_audiobusio_pdmin_deinit(self); mp_raise_ValueError(MP_ERROR_TEXT("sampling rate out of range")); } diff --git a/ports/raspberrypi/common-hal/audiobusio/README.pio b/ports/raspberrypi/common-hal/audiobusio/README.pio new file mode 100644 index 00000000000..53c73fbc199 --- /dev/null +++ b/ports/raspberrypi/common-hal/audiobusio/README.pio @@ -0,0 +1,7 @@ +.pio files right now are compiled by hand with pico-sdk/tools/pioasm and inserted into I2SOut.c + +i2s.pio regular pin order, not left_justified +i2s_left.pio regular pin order, left_justified + +i2s_swap.pio swapped pin order, not left_justified +i2s_swap_left.pio swapped pin order, left_justified diff --git a/ports/raspberrypi/common-hal/audiobusio/i2s.pio b/ports/raspberrypi/common-hal/audiobusio/i2s.pio new file mode 100644 index 00000000000..b3557eeb918 --- /dev/null +++ b/ports/raspberrypi/common-hal/audiobusio/i2s.pio @@ -0,0 +1,25 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- LRCLK + ; |/-- BCLK + ; || + pull noblock side 0b11 ; Loads OSR with the next FIFO value or X + mov x osr side 0b11 ; Save the new value in case we need it again + set y 14 side 0b11 +bitloop1: + out pins 1 side 0b10 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b00 [2] + set y 14 side 0b01 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b01 [2] + out pins 1 side 0b10 [2] diff --git a/ports/raspberrypi/common-hal/audiobusio/i2s_left.pio b/ports/raspberrypi/common-hal/audiobusio/i2s_left.pio new file mode 100644 index 00000000000..4830ec42078 --- /dev/null +++ b/ports/raspberrypi/common-hal/audiobusio/i2s_left.pio @@ -0,0 +1,25 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- LRCLK + ; |/-- BCLK + ; || + pull noblock side 0b01 ; Loads OSR with the next FIFO value or X + mov x osr side 0b01 ; Save the new value in case we need it again + set y 14 side 0b01 +bitloop1: + out pins 1 side 0b10 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b10 [2] + set y 14 side 0b11 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b01 [2] + out pins 1 side 0b00 [2] diff --git a/ports/raspberrypi/common-hal/audiobusio/i2s_swap.pio b/ports/raspberrypi/common-hal/audiobusio/i2s_swap.pio new file mode 100644 index 00000000000..a7ecf94c764 --- /dev/null +++ b/ports/raspberrypi/common-hal/audiobusio/i2s_swap.pio @@ -0,0 +1,25 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- BCLK + ; |/-- LRCLK + ; || + pull noblock side 0b11 ; Loads OSR with the next FIFO value or X + mov x osr side 0b11 ; Save the new value in case we need it again + set y 14 side 0b11 +bitloop1: + out pins 1 side 0b01 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b00 [2] + set y 14 side 0b10 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b10 [2] + out pins 1 side 0b01 [2] diff --git a/ports/raspberrypi/common-hal/audiobusio/i2s_swap_left.pio b/ports/raspberrypi/common-hal/audiobusio/i2s_swap_left.pio new file mode 100644 index 00000000000..4e6373dd65a --- /dev/null +++ b/ports/raspberrypi/common-hal/audiobusio/i2s_swap_left.pio @@ -0,0 +1,25 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2s +.side_set 2 + +; Load the next set of samples + ; /--- BCLK + ; |/-- LRCLK + ; || + pull noblock side 0b10 ; Loads OSR with the next FIFO value or X + mov x osr side 0b10 ; Save the new value in case we need it again + set y 14 side 0b10 +bitloop1: + out pins 1 side 0b01 [2] ; Right channel first + jmp y-- bitloop1 side 0b11 [2] + out pins 1 side 0b01 [2] + set y 14 side 0b11 [2] +bitloop0: + out pins 1 side 0b00 [2] ; Then left channel + jmp y-- bitloop0 side 0b10 [2] + out pins 1 side 0b00 [2] diff --git a/ports/raspberrypi/common-hal/audioi2sin/I2SIn.c b/ports/raspberrypi/common-hal/audioi2sin/I2SIn.c new file mode 100644 index 00000000000..bb0b0204111 --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/I2SIn.c @@ -0,0 +1,856 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" +#include "common-hal/audioi2sin/I2SIn.h" +#include "shared-bindings/audioi2sin/I2SIn.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/audioi2sin/__init__.h" +#include "bindings/rp2pio/StateMachine.h" +#include "supervisor/port.h" + +#include "hardware/dma.h" + +#if CIRCUITPY_AUDIOI2SIN + +// 16-bit programs sample a stereo frame of 16+16 = 32 bits and rely on +// auto-push at 32 to deliver one packed (right<<16 | left) word per frame. +// 32-bit programs sample 32 bits per channel and produce two FIFO words per +// frame (right first, then left). Each bit takes 6 PIO clocks (a [2]-delay +// pair). 24-bit recordings reuse the 32-bit programs because most 24-bit +// MEMS mics (SPH0645LM4H, INMP441, ICS-43434) transmit their 24 valid bits +// left-justified inside a 32-bit slot. +// +// `in pins 1` runs on a cycle where side-set drives BCLK high. The attached +// device updates the data line on the BCLK falling edge, so by the rising edge it +// has settled and is safe to sample. Sampling at BCLK low (the previous, +// incorrect arrangement) catches the data mid-transition and the result is +// effectively noise. +#define PIO_CLOCKS_PER_BIT (6) + +// Internal-clock RX, regular pin order (BCLK = WS - 1), Philips alignment. +static const uint16_t i2sin_program[] = { + 0xb842, // 0: nop side 3 + // .wrap_target + 0xf94e, // 1: set y, 14 side 3 [1] + 0xb242, // 2: nop side 2 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xa242, // 5: nop side 0 [2] + 0x4801, // 6: in pins, 1 side 1 + 0xe94e, // 7: set y, 14 side 1 [1] + 0xa242, // 8: nop side 0 [2] + 0x4801, // 9: in pins, 1 side 1 + 0x0988, // 10: jmp y--, 8 side 1 [1] + 0xb242, // 11: nop side 2 [2] + 0x5801, // 12: in pins, 1 side 3 + // .wrap +}; + +// Internal-clock RX, regular pin order, left-justified. +static const uint16_t i2sin_program_left_justified[] = { + 0xa842, // 0: nop side 1 + // .wrap_target + 0xe94e, // 1: set y, 14 side 1 [1] + 0xb242, // 2: nop side 2 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xb242, // 5: nop side 2 [2] + 0x5801, // 6: in pins, 1 side 3 + 0xf94e, // 7: set y, 14 side 3 [1] + 0xa242, // 8: nop side 0 [2] + 0x4801, // 9: in pins, 1 side 1 + 0x0988, // 10: jmp y--, 8 side 1 [1] + 0xa242, // 11: nop side 0 [2] + 0x4801, // 12: in pins, 1 side 1 + // .wrap +}; + +// Internal-clock RX, swapped pin order (BCLK = WS + 1), Philips alignment. +static const uint16_t i2sin_program_swap[] = { + 0xb842, // 0: nop side 3 + // .wrap_target + 0xf94e, // 1: set y, 14 side 3 [1] + 0xaa42, // 2: nop side 1 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xa242, // 5: nop side 0 [2] + 0x5001, // 6: in pins, 1 side 2 + 0xf14e, // 7: set y, 14 side 2 [1] + 0xa242, // 8: nop side 0 [2] + 0x5001, // 9: in pins, 1 side 2 + 0x1188, // 10: jmp y--, 8 side 2 [1] + 0xaa42, // 11: nop side 1 [2] + 0x5801, // 12: in pins, 1 side 3 + // .wrap +}; + +// Internal-clock RX, swapped pin order, left-justified. +static const uint16_t i2sin_program_left_justified_swap[] = { + 0xb042, // 0: nop side 2 + // .wrap_target + 0xf14e, // 1: set y, 14 side 2 [1] + 0xaa42, // 2: nop side 1 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xaa42, // 5: nop side 1 [2] + 0x5801, // 6: in pins, 1 side 3 + 0xf94e, // 7: set y, 14 side 3 [1] + 0xa242, // 8: nop side 0 [2] + 0x5001, // 9: in pins, 1 side 2 + 0x1188, // 10: jmp y--, 8 side 2 [1] + 0xa242, // 11: nop side 0 [2] + 0x5001, // 12: in pins, 1 side 2 + // .wrap +}; + +// 32-bit-per-channel variants: identical to the 16-bit programs above except +// the loop counter is set to 30 (so each `bitloop` runs 31 in's, plus one +// outside the loop = 32 in's per channel). +static const uint16_t i2sin_program_32[] = { + 0xb842, // 0: nop side 3 + // .wrap_target + 0xf95e, // 1: set y, 30 side 3 [1] + 0xb242, // 2: nop side 2 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xa242, // 5: nop side 0 [2] + 0x4801, // 6: in pins, 1 side 1 + 0xe95e, // 7: set y, 30 side 1 [1] + 0xa242, // 8: nop side 0 [2] + 0x4801, // 9: in pins, 1 side 1 + 0x0988, // 10: jmp y--, 8 side 1 [1] + 0xb242, // 11: nop side 2 [2] + 0x5801, // 12: in pins, 1 side 3 + // .wrap +}; + +static const uint16_t i2sin_program_left_justified_32[] = { + 0xa842, // 0: nop side 1 + // .wrap_target + 0xe95e, // 1: set y, 30 side 1 [1] + 0xb242, // 2: nop side 2 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xb242, // 5: nop side 2 [2] + 0x5801, // 6: in pins, 1 side 3 + 0xf95e, // 7: set y, 30 side 3 [1] + 0xa242, // 8: nop side 0 [2] + 0x4801, // 9: in pins, 1 side 1 + 0x0988, // 10: jmp y--, 8 side 1 [1] + 0xa242, // 11: nop side 0 [2] + 0x4801, // 12: in pins, 1 side 1 + // .wrap +}; + +static const uint16_t i2sin_program_swap_32[] = { + 0xb842, // 0: nop side 3 + // .wrap_target + 0xf95e, // 1: set y, 30 side 3 [1] + 0xaa42, // 2: nop side 1 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xa242, // 5: nop side 0 [2] + 0x5001, // 6: in pins, 1 side 2 + 0xf15e, // 7: set y, 30 side 2 [1] + 0xa242, // 8: nop side 0 [2] + 0x5001, // 9: in pins, 1 side 2 + 0x1188, // 10: jmp y--, 8 side 2 [1] + 0xaa42, // 11: nop side 1 [2] + 0x5801, // 12: in pins, 1 side 3 + // .wrap +}; + +static const uint16_t i2sin_program_left_justified_swap_32[] = { + 0xb042, // 0: nop side 2 + // .wrap_target + 0xf15e, // 1: set y, 30 side 2 [1] + 0xaa42, // 2: nop side 1 [2] + 0x5801, // 3: in pins, 1 side 3 + 0x1982, // 4: jmp y--, 2 side 3 [1] + 0xaa42, // 5: nop side 1 [2] + 0x5801, // 6: in pins, 1 side 3 + 0xf95e, // 7: set y, 30 side 3 [1] + 0xa242, // 8: nop side 0 [2] + 0x5001, // 9: in pins, 1 side 2 + 0x1188, // 10: jmp y--, 8 side 2 [1] + 0xa242, // 11: nop side 0 [2] + 0x5001, // 12: in pins, 1 side 2 + // .wrap +}; + +// External-clock RX. BCLK and WS are inputs driven by something +// else -- another I2S object or the codec -- so the state machine side-sets +// nothing and waits on the two clocks instead. `wait gpio` encodes an absolute +// pin index, so unlike the internal-clock programs above this one is assembled at +// construct time with the pin numbers patched in. +// +// 0: wait 0 gpio W ; resync: find a WS rising edge, i.e. the start +// 1: wait 1 gpio W ; of the RIGHT channel (matches word order) +// .wrap_target +// 2: set y, 31 +// 3: wait 0 gpio B ; data changes here +// 4: wait 1 gpio B ; ...and is settled here +// 5: in pins, 1 +// 6: jmp y--, 3 +// .wrap +// +// `set y, 31` + `jmp y--` runs the loop exactly 32 times, so with auto-push at +// 32 and shift-left this pushes one 32-bit word per 32 BCLK, MSB first -- +// identical to what the internal-clock programs produce, so record_to_buffer and +// fill_buffer need no changes. One template covers every bit_depth: at 16 bits +// a 32-BCLK frame is one push (right<<16 | left), at 24/32 a 64-BCLK frame is +// two pushes (right then left). +// +// The WS resync lands on the first data bit, so the program above is +// the `left_justified` alignment: data starts on the WS edge and no instruction +// is spent on a delay bit. The default (Philips) alignment is that program plus +// one more BCLK of skew, the other of the two possible alignments. +// +// Free-running after the initial sync: the external frame must be exactly +// 2 x bits_per_channel BCLKs, the same assumption internal clock mode already bakes +// in. If sync is lost it stays lost. +#define I2SIN_EXT_CLOCK_MAX_PROGRAM_LEN (8) +// The bit loop is the last 5 instructions; everything before it is one-shot sync. +#define I2SIN_EXT_CLOCK_WRAP_TARGET(len) ((int)(len) - 5) + +static size_t build_i2sin_ext_clock_program(uint16_t *prog, uint8_t bclk, uint8_t ws, + bool left_justified) { + const uint16_t wait_0_bclk = 0x2000 | bclk; + const uint16_t wait_1_bclk = 0x2080 | bclk; + size_t len = 0; + prog[len++] = 0x2000 | ws; // wait 0 gpio W + prog[len++] = 0x2080 | ws; // wait 1 gpio W + if (!left_justified) { + prog[len++] = wait_1_bclk; // one more BCLK of skew + } + const size_t bitloop = len + 1; + prog[len++] = 0xe05f; // set y, 31 + prog[len++] = wait_0_bclk; + prog[len++] = wait_1_bclk; + prog[len++] = 0x4001; // in pins, 1 + prog[len++] = 0x0080 | bitloop; // jmp y--, bitloop + return len; +} + +// `wait gpio` indices are relative to the PIO's GPIO base, which +// rp2pio_statemachine_construct picks the same way. +static uint8_t i2s_wait_gpio_index(const mcu_pin_obj_t *pin, uint8_t gpio_offset) { + if (pin->number < gpio_offset) { + mp_raise_ValueError(MP_ERROR_TEXT("Cannot use GPIO0..15 together with GPIO32..47")); + } + return pin->number - gpio_offset; +} + +// Caller validates that pins are free. +void common_hal_audioi2sin_i2sin_construct(audioi2sin_i2sin_obj_t *self, + const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, + uint32_t sample_rate, uint8_t bit_depth, uint8_t output_bit_depth, + bool mono, bool left_justified, bool samples_signed, + bool external_clock) { + + if (main_clock != NULL) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_main_clock); + } + if (bit_depth != 16 && bit_depth != 24 && bit_depth != 32) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be 16, 24, or 32"), MP_QSTR_bit_depth); + } + + // 24- and 32-bit recordings both clock 32 bits per channel; 24-bit MEMS + // mics deliver their data left-justified inside that 32-bit slot. + bool wide = (bit_depth != 16); + uint32_t bits_per_channel = wide ? 32 : 16; + uint32_t pio_clocks_per_frame = bits_per_channel * 2 * PIO_CLOCKS_PER_BIT; + + const mcu_pin_obj_t *sideset_pin = NULL; + const uint16_t *program = NULL; + size_t program_len = 0; + uint16_t ext_clock_program[I2SIN_EXT_CLOCK_MAX_PROGRAM_LEN]; + pio_pinmask_t wait_gpio_mask = PIO_PINMASK_NONE; + + if (external_clock) { + // In external clock mode the clocks are `wait gpio` targets, so they + // need not be sequential GPIOs. + uint8_t gpio_offset = 0; + #if NUM_BANK0_GPIOS > 32 + if (bit_clock->number >= 32 || word_select->number >= 32 || data->number >= 32) { + gpio_offset = 16; + } + #endif + program_len = build_i2sin_ext_clock_program(ext_clock_program, + i2s_wait_gpio_index(bit_clock, gpio_offset), + i2s_wait_gpio_index(word_select, gpio_offset), + left_justified); + program = ext_clock_program; + wait_gpio_mask = PIO_PINMASK_OR(PIO_PINMASK_FROM_PIN(bit_clock->number), + PIO_PINMASK_FROM_PIN(word_select->number)); + } else if (bit_clock->number == word_select->number - 1) { + sideset_pin = bit_clock; + if (left_justified) { + program = wide ? i2sin_program_left_justified_32 : i2sin_program_left_justified; + program_len = wide ? MP_ARRAY_SIZE(i2sin_program_left_justified_32) + : MP_ARRAY_SIZE(i2sin_program_left_justified); + } else { + program = wide ? i2sin_program_32 : i2sin_program; + program_len = wide ? MP_ARRAY_SIZE(i2sin_program_32) + : MP_ARRAY_SIZE(i2sin_program); + } + } else if (bit_clock->number == word_select->number + 1) { + sideset_pin = word_select; + if (left_justified) { + program = wide ? i2sin_program_left_justified_swap_32 : i2sin_program_left_justified_swap; + program_len = wide ? MP_ARRAY_SIZE(i2sin_program_left_justified_swap_32) + : MP_ARRAY_SIZE(i2sin_program_left_justified_swap); + } else { + program = wide ? i2sin_program_swap_32 : i2sin_program_swap; + program_len = wide ? MP_ARRAY_SIZE(i2sin_program_swap_32) + : MP_ARRAY_SIZE(i2sin_program_swap); + } + } else { + mp_raise_ValueError(MP_ERROR_TEXT("Bit clock and word select must be sequential GPIO pins")); + } + + common_hal_rp2pio_statemachine_construct( + &self->state_machine, + program, program_len, + // In external clock mode the SM is driven by the waits, not the clock + // divider, so run it at sysclk. + external_clock ? 0 : sample_rate *pio_clocks_per_frame, + NULL, 0, // init + NULL, 0, // may_exec + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // out pin + data, 1, // in pins + PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // in pulls + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // set pins + sideset_pin, sideset_pin == NULL ? 0 : 2, false, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // sideset pins + false, // No sideset enable + NULL, PULL_NONE, // jump pin + wait_gpio_mask, // wait gpio pins + // The clocks are shared through wait_gpio_mask, which _check_gpio_mask_free + // already allows to be shared; the data pin stays exclusively ours. + true, // exclusive pin use + false, 32, false, // out settings (unused) + false, // Wait for txstall + true, 32, false, // in settings: auto-push at 32 bits, shift left (MSB first) + false, // Not user-interruptible. + external_clock ? I2SIN_EXT_CLOCK_WRAP_TARGET(program_len) : 1, + external_clock ? (int)program_len - 1 : -1, // wrap settings + PIO_ANY_OFFSET, + PIO_FIFO_TYPE_DEFAULT, + PIO_MOV_STATUS_DEFAULT, + PIO_MOV_N_DEFAULT); + + // In external clock mode the SM runs at sysclk and the real rate is + // whatever the outside world drives WS at, so `sample_rate` is a + // declaration rather than a measurement. A mismatch shows up as the same + // slow drift the underrun-pad / overflow-drop paths in fill_buffer absorb. + self->sample_rate = external_clock + ? sample_rate + : common_hal_rp2pio_statemachine_get_frequency(&self->state_machine) / pio_clocks_per_frame; + self->bit_depth = bit_depth; + self->mono = mono; + self->samples_signed = samples_signed; + self->left_justified = left_justified; + self->external_clock = external_clock; + self->settled = false; + self->ring = NULL; + self->ring_size = 0; + self->half_size = 0; + self->read_pos = 0; + self->dma_channel = -1; + self->overflow = false; + + // Populate the audiosample base so I2SIn can feed the audio pipeline as a + // streaming source. The output depth must be 8 or 16 to actually stream; we + // still fill base here (so sample_rate/bits_per_sample/etc. read back) and + // raise from reset_buffer if a 24/32-bit instance is played. The owned + // conversion buffer is allocated lazily on first reset_buffer(). + uint8_t channel_count = mono ? 1 : 2; + // Report the *nominal* requested rate (not the PIO-derived self->sample_rate, + // which can be off by a fraction of a Hz). audiosample_must_match requires + // exact equality against the consumer, which is configured for the nominal + // rate; the tiny capture-clock difference shows up as the slow drift that the + // underrun silence-pad / overflow-drop paths in fill_buffer absorb. + self->base.sample_rate = sample_rate; + self->base.bits_per_sample = output_bit_depth; + self->base.channel_count = channel_count; + self->base.samples_signed = samples_signed; + self->base.single_buffer = false; + self->base.max_buffer_length = + 2 * AUDIOI2SIN_STREAM_FRAMES * (output_bit_depth / 8) * channel_count; + self->output_buffer = NULL; + self->output_half_bytes = self->base.max_buffer_length / 2; + self->output_index = 0; + + // Each PIO frame produces 4 bytes in the FIFO regardless of bit depth + // (16-bit auto-pushes one packed stereo word, 24/32-bit pushes two + // separate 32-bit words). One stereo frame is therefore either 4 or + // 8 bytes; size the half-buffer for ~40 ms of audio so a slow consumer + // (SD card flush etc.) can complete without overrunning. + size_t bytes_per_frame = (bit_depth == 16) ? 4 : 8; + size_t target = (size_t)self->sample_rate * bytes_per_frame * 40 / 1000; + size_t half_size = (target > 4096) ? target : 4096; + // Round up to a multiple of 8 so 24/32-bit pair reads never straddle + // the half boundary. + half_size = (half_size + 7u) & ~(size_t)7u; + + self->ring = (uint8_t *)port_malloc(2 * half_size, true); + if (self->ring == NULL) { + common_hal_rp2pio_statemachine_deinit(&self->state_machine); + m_malloc_fail(2 * half_size); + } + self->half_size = half_size; + self->ring_size = 2 * half_size; + + common_hal_rp2pio_statemachine_set_read_buffers_raw(&self->state_machine, + NULL, 0, + self->ring, half_size, + self->ring + half_size, half_size); + if (!common_hal_rp2pio_statemachine_background_read(&self->state_machine, 4, false)) { + port_free(self->ring); + self->ring = NULL; + common_hal_rp2pio_statemachine_deinit(&self->state_machine); + mp_raise_OSError(MP_EIO); + } + self->dma_channel = common_hal_rp2pio_statemachine_get_read_dma_channel(&self->state_machine); +} + +bool common_hal_audioi2sin_i2sin_deinited(audioi2sin_i2sin_obj_t *self) { + return common_hal_rp2pio_statemachine_deinited(&self->state_machine); +} + +void common_hal_audioi2sin_i2sin_deinit(audioi2sin_i2sin_obj_t *self) { + if (common_hal_audioi2sin_i2sin_deinited(self)) { + return; + } + common_hal_rp2pio_statemachine_stop_background_read(&self->state_machine); + common_hal_rp2pio_statemachine_deinit(&self->state_machine); + if (self->ring != NULL) { + port_free(self->ring); + self->ring = NULL; + } + if (self->output_buffer != NULL) { + port_free(self->output_buffer); + self->output_buffer = NULL; + } + self->ring_size = 0; + self->half_size = 0; + self->dma_channel = -1; + audiosample_mark_deinit(&self->base); +} + +uint8_t common_hal_audioi2sin_i2sin_get_bit_depth(audioi2sin_i2sin_obj_t *self) { + return self->bit_depth; +} + +uint32_t common_hal_audioi2sin_i2sin_get_sample_rate(audioi2sin_i2sin_obj_t *self) { + return self->sample_rate; +} + +bool common_hal_audioi2sin_i2sin_get_samples_signed(audioi2sin_i2sin_obj_t *self) { + return self->samples_signed; +} + +// The flag latches when record_to_buffer or fill_buffer finds the DMA more than +// a half-buffer ahead of the read cursor and has to skip forward. Reading clears +// it so a streaming consumer can attribute each report to a known interval. +bool common_hal_audioi2sin_i2sin_get_overflow(audioi2sin_i2sin_obj_t *self) { + bool overflow = self->overflow; + self->overflow = false; + return overflow; +} + +// In 16-bit mode, each PIO frame produces a single 32-bit FIFO word with bits +// 31..16 = right channel and bits 15..0 = left channel (both MSB-first signed +// 16-bit). In 24/32-bit mode each frame produces two FIFO words: right first, +// then left, each MSB-first in the full 32 bits. For mono we keep the left +// channel; for stereo we emit (left, right) pairs. +// +// `output_buffer_length` is the requested number of samples to write (sample +// width = 2 bytes for bit_depth=16, 4 bytes for bit_depth=24 or 32). Returns +// the number actually written. +// Compute the byte offset inside `ring` that the DMA is currently writing +// (one past the last word it finished). Always lies in [0, ring_size). +static size_t i2sin_write_pos(audioi2sin_i2sin_obj_t *self) { + uintptr_t addr = (uintptr_t)dma_channel_hw_addr(self->dma_channel)->write_addr; + uintptr_t base = (uintptr_t)self->ring; + if (addr < base || addr >= base + self->ring_size) { + // The ISR retargets write_addr to the start of the next half right + // after a transfer completes; it should always be in-range, but if + // we observe it mid-update just report "no new data". + return self->read_pos; + } + return (size_t)(addr - base); +} + +// 24-bit non-left-justified data arrives in the low 24 bits of the FIFO word +// with the sign bit at bit 23 and bits 31..24 zero. To make it decode +// correctly as int32 (array typecode "i"), lift the sign bit to bit 31. +static inline uint32_t movesign24(uint32_t val) { + return ((val & 0x800000u) << 8) | (val & 0x7fffffu); +} + +// Sign-extend a raw FIFO sample to a canonical int32 value. `raw` holds the +// sample as delivered by the PIO program for the given input bit depth and +// alignment. The returned int32 represents the same magnitude with the sign +// bit at bit 31. +static inline int32_t i2sin_normalize_signed(uint32_t raw, uint8_t in_depth, + bool left_justified) { + if (in_depth == 32) { + return (int32_t)raw; + } + if (in_depth == 24) { + if (left_justified) { + // value in bits 31..8, sign at 31; arithmetic shift right 8 + return (int32_t)raw >> 8; + } + // value in bits 23..0, sign at 23 + uint32_t sign_bit = 0x800000u; + return (int32_t)((raw ^ sign_bit) - sign_bit); + } + // 16-bit: low 16 bits, sign at 15 + return (int16_t)(raw & 0xffffu); +} + +// Normalize `raw` (input-depth bits, just-read FIFO sample) for this port's wire +// format, then hand off to the shared converter to rescale `in_depth` -> +// `out_depth` and write it to `buffer` at sample index `idx`. The depth +// conversion + unsigned-WAV flip + container store live in +// `shared_audioi2sin_write_converted` (shared with other ports); see that helper +// for the upscale/downscale semantics. +// +// For signed 24-bit output, the int32 slot holds the sign-extended value +// (range -2^23 .. 2^23-1) — unlike the default `output_bit_depth=bit_depth=24` +// path which uses `movesign24`, the converted path returns proper two's +// complement so the result decodes correctly as int32. +static inline void i2sin_write_converted(void *buffer, uint32_t idx, + uint32_t raw, uint8_t in_depth, uint8_t out_depth, + bool samples_signed, bool left_justified) { + int32_t s = i2sin_normalize_signed(raw, in_depth, left_justified); + shared_audioi2sin_write_converted(buffer, idx, s, in_depth, out_depth, samples_signed); +} + +uint32_t common_hal_audioi2sin_i2sin_record_to_buffer(audioi2sin_i2sin_obj_t *self, + void *buffer, uint32_t output_buffer_length) { + uint32_t output_count = 0; + const size_t ring_size = self->ring_size; + const size_t half_size = self->half_size; + + // I2S delivers signed PCM. When the caller asked for unsigned samples, + // flip the sign bit per sample (XOR with 0x8000 for 16-bit, 0x800000 for + // 24-bit data in a 32-bit slot, 0x80000000 for 32-bit), matching the WAV + // convention. The default (no-conversion) path applies the flip to the + // raw FIFO word before splitting into channels; the conversion path + // applies the flip per output sample at output bit width. + const bool convert = self->base.bits_per_sample != self->bit_depth; + const uint32_t flip16 = (!convert && !self->samples_signed) ? 0x80008000u : 0u; + const uint32_t flip32 = (!convert && !self->samples_signed) + ? (self->bit_depth == 24 ? 0x800000u : 0x80000000u) + : 0u; + const bool fix_sign24 = !convert + && self->bit_depth == 24 + && self->samples_signed + && !self->left_justified; + const uint8_t in_depth = self->bit_depth; + const uint8_t out_depth = self->base.bits_per_sample; + const bool left_justified = self->left_justified; + const bool samples_signed = self->samples_signed; + + if (self->bit_depth == 16) { + // 16-bit mode auto-pushes one stereo frame per FIFO word. The DMA has + // been streaming since construct time, so the ring already contains + // settled data; drop the first 4 bytes once to discard a single + // pre-record frame (matches the prior synchronous behaviour). + uint16_t *output = convert ? NULL : (uint16_t *)buffer; + while (output_count < output_buffer_length) { + size_t write_pos = i2sin_write_pos(self); + size_t avail = (write_pos + ring_size - self->read_pos) % ring_size; + if (avail > half_size) { + // DMA has filled more than one half ahead of us -- we lost + // data. Snap to just behind the DMA on a 4-byte boundary. + self->overflow = true; + self->read_pos = write_pos & ~(size_t)3u; + avail = 0; + } + if (!self->settled && avail >= 4) { + self->read_pos = (self->read_pos + 4) % ring_size; + avail -= 4; + self->settled = true; + } + if (avail < 4) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return output_count; + } + continue; + } + while (avail >= 4 && output_count < output_buffer_length) { + uint32_t frame = *(volatile uint32_t *)(self->ring + self->read_pos) ^ flip16; + uint16_t left = (uint16_t)(frame & 0xffff); + uint16_t right = (uint16_t)(frame >> 16); + if (!convert) { + if (self->mono) { + output[output_count++] = left; + } else { + output[output_count++] = left; + if (output_count >= output_buffer_length) { + self->read_pos = (self->read_pos + 4) % ring_size; + avail -= 4; + break; + } + output[output_count++] = right; + } + } else { + i2sin_write_converted(buffer, output_count++, left, + in_depth, out_depth, samples_signed, left_justified); + if (!self->mono) { + if (output_count >= output_buffer_length) { + self->read_pos = (self->read_pos + 4) % ring_size; + avail -= 4; + break; + } + i2sin_write_converted(buffer, output_count++, right, + in_depth, out_depth, samples_signed, left_justified); + } + } + self->read_pos = (self->read_pos + 4) % ring_size; + avail -= 4; + } + } + } else { + // 24-/32-bit mode emits two FIFO pushes per stereo frame (right then + // left). The state machine was started at instruction 0 by the + // constructor, so the very first push is the right channel and + // alternation is preserved as long as we never touch the program + // counter and always read an even number of words. half_size is a + // multiple of 8, so reading 8-byte pairs stays aligned across the + // ring wrap. + uint32_t *output = convert ? NULL : (uint32_t *)buffer; + while (output_count < output_buffer_length) { + size_t write_pos = i2sin_write_pos(self); + size_t avail = (write_pos + ring_size - self->read_pos) % ring_size; + if (avail > half_size) { + // Overflow: snap to a frame-aligned position one half behind + // the DMA's current half so we resume on the right channel. + self->overflow = true; + size_t cur_half = (write_pos < half_size) ? 0 : half_size; + self->read_pos = (cur_half + half_size) % ring_size; + self->settled = false; + avail = (write_pos + ring_size - self->read_pos) % ring_size; + } + if (!self->settled && avail >= 8) { + self->read_pos = (self->read_pos + 8) % ring_size; + avail -= 8; + self->settled = true; + } + if (avail < 8) { + RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + return output_count; + } + continue; + } + while (avail >= 8 && output_count < output_buffer_length) { + uint32_t right = *(volatile uint32_t *)(self->ring + self->read_pos) ^ flip32; + size_t next_pos = (self->read_pos + 4) % ring_size; + uint32_t left = *(volatile uint32_t *)(self->ring + next_pos) ^ flip32; + if (fix_sign24) { + right = movesign24(right); + left = movesign24(left); + } + if (!convert) { + if (self->mono) { + output[output_count++] = left; + } else { + output[output_count++] = left; + if (output_count >= output_buffer_length) { + self->read_pos = (self->read_pos + 8) % ring_size; + avail -= 8; + break; + } + output[output_count++] = right; + } + } else { + i2sin_write_converted(buffer, output_count++, left, + in_depth, out_depth, samples_signed, left_justified); + if (!self->mono) { + if (output_count >= output_buffer_length) { + self->read_pos = (self->read_pos + 8) % ring_size; + avail -= 8; + break; + } + i2sin_write_converted(buffer, output_count++, right, + in_depth, out_depth, samples_signed, left_justified); + } + } + self->read_pos = (self->read_pos + 8) % ring_size; + avail -= 8; + } + } + } + + return output_count; +} + +// Write `count` silence samples at output depth starting at sample index `idx`. +// For signed PCM silence is 0; for unsigned (WAV) it is mid-scale. +static void i2sin_fill_silence(void *buffer, uint32_t idx, uint32_t count, + uint8_t out_depth, bool samples_signed) { + if (out_depth == 8) { + uint8_t v = samples_signed ? 0 : 0x80u; + memset((uint8_t *)buffer + idx, v, count); + } else { // 16-bit (the only other streamable width) + uint16_t v = samples_signed ? 0 : 0x8000u; + uint16_t *p = (uint16_t *)buffer + idx; + for (uint32_t i = 0; i < count; i++) { + p[i] = v; + } + } +} + +// Non-blocking fill: convert up to `frames` frames currently available in the +// DMA ring into `buffer` (output depth, interleaved), padding the remainder with +// silence on underrun rather than spinning. Used by get_buffer() from the output +// backend's refill interrupt, so it must never block. `out_depth` is always 8 or +// 16 here (reset_buffer rejects 24/32). Reuses the same per-sample conversion as +// record_to_buffer via i2sin_write_converted. +void common_hal_audioi2sin_i2sin_fill_buffer(audioi2sin_i2sin_obj_t *self, + uint8_t *buffer, uint32_t frames) { + const size_t ring_size = self->ring_size; + const size_t half_size = self->half_size; + const uint8_t in_depth = self->bit_depth; + const uint8_t out_depth = self->base.bits_per_sample; + const bool samples_signed = self->samples_signed; + const bool left_justified = self->left_justified; + const bool stereo = !self->mono; + const uint8_t channel_count = stereo ? 2 : 1; + const size_t frame_bytes = (in_depth == 16) ? 4 : 8; + const uint32_t total_samples = frames * channel_count; + + uint32_t produced = 0; + while (produced < total_samples) { + size_t write_pos = i2sin_write_pos(self); + size_t avail = (write_pos + ring_size - self->read_pos) % ring_size; + if (avail > half_size) { + // The consumer is slower than the mic and the ring is filling up + // (the overflow case record_to_buffer also handles). Drop back to + // just behind the DMA so latency stays bounded; the discarded audio + // shows up as a brief discontinuity, not a hang. + self->overflow = true; + if (in_depth == 16) { + self->read_pos = write_pos & ~(size_t)3u; + } else { + size_t cur_half = (write_pos < half_size) ? 0 : half_size; + self->read_pos = (cur_half + half_size) % ring_size; + self->settled = false; + } + avail = (write_pos + ring_size - self->read_pos) % ring_size; + } + if (!self->settled && avail >= frame_bytes) { + // Drop one frame so playback starts on a settled sample and (for + // 24/32-bit) on the right-channel word the program emits first. + self->read_pos = (self->read_pos + frame_bytes) % ring_size; + avail -= frame_bytes; + self->settled = true; + } + if (avail < frame_bytes) { + break; // underrun: pad the rest with silence below + } + uint32_t left, right; + if (in_depth == 16) { + uint32_t fr = *(volatile uint32_t *)(self->ring + self->read_pos); + left = fr & 0xffffu; + right = fr >> 16; + } else { + right = *(volatile uint32_t *)(self->ring + self->read_pos); + size_t next_pos = (self->read_pos + 4) % ring_size; + left = *(volatile uint32_t *)(self->ring + next_pos); + } + i2sin_write_converted(buffer, produced++, left, + in_depth, out_depth, samples_signed, left_justified); + if (stereo && produced < total_samples) { + i2sin_write_converted(buffer, produced++, right, + in_depth, out_depth, samples_signed, left_justified); + } + self->read_pos = (self->read_pos + frame_bytes) % ring_size; + } + if (produced < total_samples) { + i2sin_fill_silence(buffer, produced, total_samples - produced, + out_depth, samples_signed); + } +} + +void common_hal_audioi2sin_i2sin_reset_buffer(audioi2sin_i2sin_obj_t *self, + bool single_channel_output, uint8_t channel) { + (void)single_channel_output; + (void)channel; + // The audio pipeline only carries 8- or 16-bit samples. 24/32-bit modes can + // still record() but cannot stream; fail clearly the first time playback is + // set up rather than emitting garbage. + if (self->base.bits_per_sample != 8 && self->base.bits_per_sample != 16) { + mp_raise_ValueError_varg( + MP_ERROR_TEXT("%q must be 8 or 16"), MP_QSTR_output_bit_depth); + } + if (self->output_buffer == NULL) { + // The output backend's DMA reads this buffer directly, so it must be + // DMA-capable like the input ring. + self->output_buffer = (uint8_t *)port_malloc(self->base.max_buffer_length, true); + if (self->output_buffer == NULL) { + m_malloc_fail(self->base.max_buffer_length); + } + } + self->output_index = 0; + // An external-clock SM free-runs a 32-BCLK counter from the WS edge it + // synced to at construct time, so anything that disturbs the frame leaves + // it locked to the wrong half-frame or the wrong bit for good. Re-exec the + // program here so playback always begins from a fresh WS sync. An + // internal-clock SM generates its own clocks and has nothing to sync to, + // so leave it alone. + if (self->external_clock) { + common_hal_rp2pio_statemachine_restart(&self->state_machine); + // restart() clears the shift counters but not the RX FIFO, and the + // words still sitting in it were captured with the old alignment. + pio_sm_clear_fifos(self->state_machine.pio, self->state_machine.state_machine); + } + // Resync to live audio: snap the read cursor just behind the DMA write head + // (frame-aligned) and re-settle so playback begins on fresh samples. + size_t write_pos = i2sin_write_pos(self); + self->read_pos = (self->bit_depth == 16) + ? (write_pos & ~(size_t)3u) + : (write_pos & ~(size_t)7u); + self->settled = false; + self->overflow = false; +} + +audioio_get_buffer_result_t common_hal_audioi2sin_i2sin_get_buffer( + audioi2sin_i2sin_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + uint32_t half = self->output_half_bytes; + uint8_t *out = self->output_buffer + half * self->output_index; + self->output_index = 1 - self->output_index; + + uint32_t bytes_per_sample = self->base.bits_per_sample / 8; + uint32_t frames = half / (bytes_per_sample * self->base.channel_count); + common_hal_audioi2sin_i2sin_fill_buffer(self, out, frames); + + if (single_channel_output) { + out += (channel % self->base.channel_count) * bytes_per_sample; + } + *buffer = out; + *buffer_length = half; + // A live mic is an infinite stream; never report DONE or the backend stops. + return GET_BUFFER_MORE_DATA; +} + +#endif // CIRCUITPY_AUDIOI2SIN diff --git a/ports/raspberrypi/common-hal/audioi2sin/I2SIn.h b/ports/raspberrypi/common-hal/audioi2sin/I2SIn.h new file mode 100644 index 00000000000..594a9fccb02 --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/I2SIn.h @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" +#include "bindings/rp2pio/StateMachine.h" + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" + +// Number of audio frames a single get_buffer() call hands to the output backend +// (one frame = one mono sample, or an L+R pair in stereo). This sets the pull +// granularity and the silence-pad chunk on underrun. Kept independent of the DMA +// half-buffer so the two can be tuned separately. +#define AUDIOI2SIN_STREAM_FRAMES (256) + +typedef struct { + // so I2SIn can be used directly as an audiosample source. + audiosample_base_t base; + uint32_t sample_rate; + uint8_t bit_depth; + bool mono; + bool samples_signed; + bool left_justified; + bool external_clock; + bool settled; + rp2pio_statemachine_obj_t state_machine; + // Background DMA ring buffer. The state machine alternates DMA writes + // between the two halves so BCLK never stalls between record() calls. + uint8_t *ring; + size_t ring_size; + size_t half_size; + size_t read_pos; + int dma_channel; + bool overflow; + // Owned double-buffer returned to the output backend by get_buffer(), holding + // converted (output-depth, interleaved) samples. Allocated lazily on the first + // reset_buffer() so record()-only use pays no extra RAM. base.max_buffer_length + // is the whole buffer; get_buffer() returns output_half_bytes of it. + uint8_t *output_buffer; + size_t output_half_bytes; + uint8_t output_index; +} audioi2sin_i2sin_obj_t; diff --git a/ports/raspberrypi/common-hal/audioi2sin/README.pio b/ports/raspberrypi/common-hal/audioi2sin/README.pio new file mode 100644 index 00000000000..664c1301a72 --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/README.pio @@ -0,0 +1,14 @@ +.pio files right now are compiled by hand with pico-sdk/tools/pioasm and inserted into I2SIn.c + +i2sin.pio I2S RX, 16 bits/channel, regular pin order, not left_justified +i2sin_left.pio I2S RX, 16 bits/channel, regular pin order, left_justified +i2sin_swap.pio I2S RX, 16 bits/channel, swapped pin order, not left_justified +i2sin_swap_left.pio I2S RX, 16 bits/channel, swapped pin order, left_justified +i2sin_32.pio I2S RX, 32 bits/channel, regular pin order, not left_justified +i2sin_left_32.pio I2S RX, 32 bits/channel, regular pin order, left_justified +i2sin_swap_32.pio I2S RX, 32 bits/channel, swapped pin order, not left_justified +i2sin_swap_left_32.pio I2S RX, 32 bits/channel, swapped pin order, left_justified + +The 32-bit programs are also used for bit_depth=24 because most 24-bit I2S +mics (SPH0645LM4H, INMP441, ICS-43434) place their 24 valid data bits +left-justified inside a 32-bit slot. diff --git a/ports/raspberrypi/common-hal/audioi2sin/__init__.c b/ports/raspberrypi/common-hal/audioi2sin/__init__.c new file mode 100644 index 00000000000..584c821b996 --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin.pio new file mode 100644 index 00000000000..b9d7c9ee28e --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin.pio @@ -0,0 +1,34 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin +.side_set 2 + +; Internal-clock I2S RX. Generates BCLK and LRCLK via side-set and samples the +; data pin. The attached device updates `data` on BCLK falling edge, so this +; program samples on the rising edge: every `in pins 1` runs on a side-set value +; with BCLK=1, and the loop/transition instructions hold BCLK=0 so the +; device has time to settle the next bit. + ; /--- LRCLK + ; |/-- BCLK + ; || + nop side 0b11 +.wrap_target + set y 14 side 0b11 [1] +bitloop1: + nop side 0b10 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b00 [2] + in pins 1 side 0b01 + set y 14 side 0b01 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b01 + jmp y-- bitloop0 side 0b01 [1] + nop side 0b10 [2] + in pins 1 side 0b11 +.wrap diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin_32.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin_32.pio new file mode 100644 index 00000000000..4d79a179668 --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin_32.pio @@ -0,0 +1,35 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin_32 +.side_set 2 + +; Internal-clock I2S RX, 32 bits per channel (also used for 24-bit mics that +; transmit data left-justified in a 32-bit slot). Generates BCLK and LRCLK +; via side-set and samples the data pin. The attached device updates `data` on +; BCLK falling edge, so this program samples on the rising edge: every `in pins 1` +; runs on a side-set value with BCLK=1, and the preceding nop holds BCLK=0 +; so the device has time to settle the next bit. + ; /--- LRCLK + ; |/-- BCLK + ; || + nop side 0b11 +.wrap_target + set y 30 side 0b11 [1] +bitloop1: + nop side 0b10 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b00 [2] + in pins 1 side 0b01 + set y 30 side 0b01 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b01 + jmp y-- bitloop0 side 0b01 [1] + nop side 0b10 [2] + in pins 1 side 0b11 +.wrap diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin_left.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin_left.pio new file mode 100644 index 00000000000..a5b8cf15970 --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin_left.pio @@ -0,0 +1,30 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin_left +.side_set 2 + +; Internal-clock I2S RX, left-justified. Mirrors the timing of i2s_left.pio. + ; /--- LRCLK + ; |/-- BCLK + ; || + nop side 0b01 +.wrap_target + set y 14 side 0b01 [1] +bitloop1: + nop side 0b10 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b10 [2] + in pins 1 side 0b11 + set y 14 side 0b11 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b01 + jmp y-- bitloop0 side 0b01 [1] + nop side 0b00 [2] + in pins 1 side 0b01 +.wrap diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin_left_32.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin_left_32.pio new file mode 100644 index 00000000000..c7c18073c0d --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin_left_32.pio @@ -0,0 +1,30 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin_left_32 +.side_set 2 + +; Internal-clock I2S RX, 32 bits per channel, left-justified. + ; /--- LRCLK + ; |/-- BCLK + ; || + nop side 0b01 +.wrap_target + set y 30 side 0b01 [1] +bitloop1: + nop side 0b10 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b10 [2] + in pins 1 side 0b11 + set y 30 side 0b11 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b01 + jmp y-- bitloop0 side 0b01 [1] + nop side 0b00 [2] + in pins 1 side 0b01 +.wrap diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap.pio new file mode 100644 index 00000000000..8ff2e468c0c --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap.pio @@ -0,0 +1,31 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin_swap +.side_set 2 + +; Internal-clock I2S RX with the LRCLK and BCLK pin order swapped (BCLK is the +; higher-numbered GPIO). + ; /--- BCLK + ; |/-- LRCLK + ; || + nop side 0b11 +.wrap_target + set y 14 side 0b11 [1] +bitloop1: + nop side 0b01 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b00 [2] + in pins 1 side 0b10 + set y 14 side 0b10 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b10 + jmp y-- bitloop0 side 0b10 [1] + nop side 0b01 [2] + in pins 1 side 0b11 +.wrap diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_32.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_32.pio new file mode 100644 index 00000000000..05d92ab019f --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_32.pio @@ -0,0 +1,31 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin_swap_32 +.side_set 2 + +; Internal-clock I2S RX, 32 bits per channel, with the LRCLK and BCLK pin order +; swapped (BCLK is the higher-numbered GPIO). + ; /--- BCLK + ; |/-- LRCLK + ; || + nop side 0b11 +.wrap_target + set y 30 side 0b11 [1] +bitloop1: + nop side 0b01 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b00 [2] + in pins 1 side 0b10 + set y 30 side 0b10 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b10 + jmp y-- bitloop0 side 0b10 [1] + nop side 0b01 [2] + in pins 1 side 0b11 +.wrap diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_left.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_left.pio new file mode 100644 index 00000000000..79fb1bd7a6a --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_left.pio @@ -0,0 +1,31 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin_swap_left +.side_set 2 + +; Internal-clock I2S RX, left-justified, with the LRCLK and BCLK pin order +; swapped (BCLK is the higher-numbered GPIO). + ; /--- BCLK + ; |/-- LRCLK + ; || + nop side 0b10 +.wrap_target + set y 14 side 0b10 [1] +bitloop1: + nop side 0b01 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b01 [2] + in pins 1 side 0b11 + set y 14 side 0b11 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b10 + jmp y-- bitloop0 side 0b10 [1] + nop side 0b00 [2] + in pins 1 side 0b10 +.wrap diff --git a/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_left_32.pio b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_left_32.pio new file mode 100644 index 00000000000..0228fa729dd --- /dev/null +++ b/ports/raspberrypi/common-hal/audioi2sin/i2sin_swap_left_32.pio @@ -0,0 +1,31 @@ +; This file is part of the CircuitPython project: https://circuitpython.org +; +; SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +; +; SPDX-License-Identifier: MIT + +.program i2sin_swap_left_32 +.side_set 2 + +; Internal-clock I2S RX, 32 bits per channel, left-justified, with the LRCLK and +; BCLK pin order swapped (BCLK is the higher-numbered GPIO). + ; /--- BCLK + ; |/-- LRCLK + ; || + nop side 0b10 +.wrap_target + set y 30 side 0b10 [1] +bitloop1: + nop side 0b01 [2] ; Right channel first + in pins 1 side 0b11 + jmp y-- bitloop1 side 0b11 [1] + nop side 0b01 [2] + in pins 1 side 0b11 + set y 30 side 0b11 [1] +bitloop0: + nop side 0b00 [2] ; Then left channel + in pins 1 side 0b10 + jmp y-- bitloop0 side 0b10 [1] + nop side 0b00 [2] + in pins 1 side 0b10 +.wrap diff --git a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c index d4cf161e619..3ab8eb814a1 100644 --- a/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/raspberrypi/common-hal/audiopwmio/PWMAudioOut.c @@ -20,8 +20,8 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Processor.h" -#include "src/rp2040/hardware_structs/include/hardware/structs/dma.h" -#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" +#include "hardware/structs/dma.h" +#include "hardware/pwm.h" // The PWM clock frequency is base_clock_rate / PWM_TOP, typically 125_000_000 / PWM_TOP. // We pick BITS_PER_SAMPLE so we get a clock frequency that is above what would cause aliasing. @@ -160,6 +160,8 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, common_hal_audiopwmio_pwmaudioout_stop(self); } + audiosample_check(sample); + // TODO: Share pacing timers based on frequency. size_t pacing_timer = NUM_DMA_TIMERS; for (size_t i = 0; i < NUM_DMA_TIMERS; i++) { @@ -187,7 +189,7 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, // to trigger the DMA. Each has a 16 bit fractional divisor system clock * X / Y where X and Y // are 16-bit. - uint32_t sample_rate = audiosample_sample_rate(sample); + uint32_t sample_rate = audiosample_get_sample_rate(sample); uint32_t system_clock = common_hal_mcu_processor_get_frequency(); uint32_t best_denominator; @@ -214,6 +216,10 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, common_hal_audiopwmio_pwmaudioout_stop(self); mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to allocate buffers for signed conversion")); } + if (result == AUDIO_DMA_SOURCE_ERROR) { + common_hal_audiopwmio_pwmaudioout_stop(self); + mp_raise_RuntimeError(MP_ERROR_TEXT("Audio source error")); + } // OK! We got all of the resources we need and dma is ready. } diff --git a/ports/raspberrypi/common-hal/busio/I2C.c b/ports/raspberrypi/common-hal/busio/I2C.c index d8e13344cfe..1441a2a7a06 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.c +++ b/ports/raspberrypi/common-hal/busio/I2C.c @@ -13,7 +13,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/bitbangio/I2C.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" // Synopsys DW_apb_i2c (v2.01) IP @@ -22,21 +22,14 @@ // One second #define BUS_TIMEOUT_US 1000000 -static bool never_reset_i2c[2]; static i2c_inst_t *i2c[2] = {i2c0, i2c1}; -void reset_i2c(void) { - for (size_t i = 0; i < 2; i++) { - if (never_reset_i2c[i]) { - continue; - } - - i2c_deinit(i2c[i]); - } -} - void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + + // Ensure object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + self->peripheral = NULL; // I2C pins have a regular pattern. SCL is always odd and SDA is even. They match up in pairs // so we can divide by two to get the instance. This pattern repeats. @@ -93,7 +86,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // // Do not use the default supplied clock stretching timeout here. // It is too short for some devices. Use the busio timeout instead. - shared_module_bitbangio_i2c_construct(&self->bitbangio_i2c, scl, sda, + shared_module_bitbangio_i2c_construct(&self->bitbangio_i2c, MP_OBJ_FROM_PTR(scl), MP_OBJ_FROM_PTR(sda), frequency, BUS_TIMEOUT_US); self->baudrate = i2c_init(self->peripheral, frequency); @@ -115,14 +108,16 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { if (common_hal_busio_i2c_deinited(self)) { return; } - never_reset_i2c[i2c_hw_index(self->peripheral)] = false; i2c_deinit(self->peripheral); reset_pin_number(self->sda_pin); reset_pin_number(self->scl_pin); + common_hal_busio_i2c_mark_deinit(self); +} + +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { self->sda_pin = NO_PIN; - self->scl_pin = NO_PIN; } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { @@ -149,7 +144,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_negative_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { if (len == 0) { // The RP2040 I2C peripheral will not perform 0 byte writes. @@ -179,20 +174,20 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, } switch (result) { case PICO_ERROR_GENERIC: - return MP_ENODEV; + return -MP_ENODEV; case PICO_ERROR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: - return MP_EIO; + return -MP_EIO; } } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { size_t result = i2c_read_timeout_us(self->peripheral, addr, data, len, false, BUS_TIMEOUT_US); if (result == len) { @@ -200,17 +195,17 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, } switch (result) { case PICO_ERROR_GENERIC: - return MP_ENODEV; + return -MP_ENODEV; case PICO_ERROR_TIMEOUT: - return MP_ETIMEDOUT; + return -MP_ETIMEDOUT; default: - return MP_EIO; + return -MP_EIO; } } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_negative_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } @@ -219,8 +214,6 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { - never_reset_i2c[i2c_hw_index(self->peripheral)] = true; - never_reset_pin_number(self->scl_pin); never_reset_pin_number(self->sda_pin); } diff --git a/ports/raspberrypi/common-hal/busio/I2C.h b/ports/raspberrypi/common-hal/busio/I2C.h index 9d97025c48e..7a6fd1b9d1f 100644 --- a/ports/raspberrypi/common-hal/busio/I2C.h +++ b/ports/raspberrypi/common-hal/busio/I2C.h @@ -11,7 +11,7 @@ #include "py/obj.h" -#include "src/rp2_common/hardware_i2c/include/hardware/i2c.h" +#include "hardware/i2c.h" typedef struct { mp_obj_base_t base; @@ -22,5 +22,3 @@ typedef struct { uint8_t scl_pin; uint8_t sda_pin; } busio_i2c_obj_t; - -void reset_i2c(void); diff --git a/ports/raspberrypi/common-hal/busio/SPI.c b/ports/raspberrypi/common-hal/busio/SPI.c index 7a033250f91..aeb06d919ae 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.c +++ b/ports/raspberrypi/common-hal/busio/SPI.c @@ -14,29 +14,19 @@ #include "common-hal/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_dma/include/hardware/dma.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/dma.h" +#include "hardware/gpio.h" #define NO_INSTANCE 0xff -static bool never_reset_spi[2]; -static spi_inst_t *spi[2] = {spi0, spi1}; - -void reset_spi(void) { - for (size_t i = 0; i < 2; i++) { - if (never_reset_spi[i]) { - continue; - } - - spi_deinit(spi[i]); - } -} - void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { size_t instance_index = NO_INSTANCE; + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + if (half_duplex) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); } @@ -96,8 +86,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, } void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[spi_get_index(self->peripheral)] = true; - common_hal_never_reset_pin(self->clock); common_hal_never_reset_pin(self->MOSI); common_hal_never_reset_pin(self->MISO); @@ -107,17 +95,21 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->clock == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->clock = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } - never_reset_spi[spi_get_index(self->peripheral)] = false; spi_deinit(self->peripheral); common_hal_reset_pin(self->clock); common_hal_reset_pin(self->MOSI); common_hal_reset_pin(self->MISO); - self->clock = NULL; + + common_hal_busio_spi_mark_deinit(self); } bool common_hal_busio_spi_configure(busio_spi_obj_t *self, @@ -182,7 +174,10 @@ static bool _transfer(busio_spi_obj_t *self, chan_tx = dma_claim_unused_channel(false); chan_rx = dma_claim_unused_channel(false); } - bool use_dma = chan_rx >= 0 && chan_tx >= 0; + bool has_dma_channels = chan_rx >= 0 && chan_tx >= 0; + // Only use DMA if both data buffers are in SRAM. Otherwise, we'll stall the DMA with PSRAM or flash cache misses. + bool data_in_sram = data_in >= (uint8_t *)SRAM_BASE && data_out >= (uint8_t *)SRAM_BASE; + bool use_dma = has_dma_channels && data_in_sram; if (use_dma) { dma_channel_config c = dma_channel_get_default_config(chan_tx); channel_config_set_transfer_data_size(&c, DMA_SIZE_8); diff --git a/ports/raspberrypi/common-hal/busio/SPI.h b/ports/raspberrypi/common-hal/busio/SPI.h index 27d4cf6f3c7..3d43c1eff00 100644 --- a/ports/raspberrypi/common-hal/busio/SPI.h +++ b/ports/raspberrypi/common-hal/busio/SPI.h @@ -10,7 +10,7 @@ #include "py/obj.h" -#include "src/rp2_common/hardware_spi/include/hardware/spi.h" +#include "hardware/spi.h" typedef struct { mp_obj_base_t base; @@ -25,5 +25,3 @@ typedef struct { uint8_t phase; uint8_t bits; } busio_spi_obj_t; - -void reset_spi(void); diff --git a/ports/raspberrypi/common-hal/busio/UART.c b/ports/raspberrypi/common-hal/busio/UART.c index aeb0ff4bea2..074c78c2f4a 100644 --- a/ports/raspberrypi/common-hal/busio/UART.c +++ b/ports/raspberrypi/common-hal/busio/UART.c @@ -14,8 +14,8 @@ #include "common-hal/microcontroller/Pin.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_irq/include/hardware/irq.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/irq.h" +#include "hardware/gpio.h" #define NO_PIN 0xff @@ -50,7 +50,7 @@ static void pin_check(const uint8_t uart, const mcu_pin_obj_t *pin, const uint8_ if (pins_uart != uart) { raise_ValueError_invalid_pins(); } - #ifdef PICO_RP2350 + #if PICO_RP2350 if ((pin_type == 0 && pin->number % 4 == 2) || (pin_type == 1 && pin->number % 4 == 3)) { return; @@ -67,7 +67,7 @@ static uint8_t pin_init(const uint8_t uart, const mcu_pin_obj_t *pin, const uint } claim_pin(pin); gpio_function_t function = GPIO_FUNC_UART; - #ifdef PICO_RP2350 + #if PICO_RP2350 if ((pin_type == 0 && pin->number % 4 == 2) || (pin_type == 1 && pin->number % 4 == 3)) { function = GPIO_FUNC_UART_AUX; diff --git a/ports/raspberrypi/common-hal/busio/UART.h b/ports/raspberrypi/common-hal/busio/UART.h index ca75235ddf8..3709907633c 100644 --- a/ports/raspberrypi/common-hal/busio/UART.h +++ b/ports/raspberrypi/common-hal/busio/UART.h @@ -9,7 +9,7 @@ #include "py/obj.h" #include "py/ringbuf.h" -#include "src/rp2_common/hardware_uart/include/hardware/uart.h" +#include "hardware/uart.h" typedef struct { mp_obj_base_t base; diff --git a/ports/raspberrypi/common-hal/countio/Counter.c b/ports/raspberrypi/common-hal/countio/Counter.c index 1a270bf8820..ba82ca8e7ab 100644 --- a/ports/raspberrypi/common-hal/countio/Counter.c +++ b/ports/raspberrypi/common-hal/countio/Counter.c @@ -13,9 +13,9 @@ #include "shared-bindings/digitalio/Pull.h" #include "common-hal/pwmio/PWMOut.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" -#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" -#include "src/rp2_common/hardware_irq/include/hardware/irq.h" +#include "hardware/gpio.h" +#include "hardware/pwm.h" +#include "hardware/irq.h" void common_hal_countio_counter_construct(countio_counter_obj_t *self, diff --git a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c index 60849eb120a..f20facdad7d 100644 --- a/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c +++ b/ports/raspberrypi/common-hal/digitalio/DigitalInOut.c @@ -14,7 +14,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #if CIRCUITPY_CYW43 #include "pico/cyw43_arch.h" diff --git a/ports/raspberrypi/common-hal/floppyio/__init__.c b/ports/raspberrypi/common-hal/floppyio/__init__.c index a8a31c63d21..3f76e892da8 100644 --- a/ports/raspberrypi/common-hal/floppyio/__init__.c +++ b/ports/raspberrypi/common-hal/floppyio/__init__.c @@ -77,7 +77,8 @@ int common_hal_floppyio_flux_readinto(void *buf, size_t len, digitalio_digitalin memset(buf, 0, len); - uint32_t pins_we_use = 1 << data->pin->number; + + pio_pinmask_t pins_we_use = PIO_PINMASK_FROM_PIN(data->pin->number); rp2pio_statemachine_obj_t state_machine; bool ok = rp2pio_statemachine_construct(&state_machine, @@ -86,10 +87,10 @@ int common_hal_floppyio_flux_readinto(void *buf, size_t len, digitalio_digitalin NULL, 0, // init program NULL, 0, // out index->pin, 1, // in - 1, 0, // in pull up/down + PIO_PINMASK_FROM_PIN(index->pin->number), PIO_PINMASK_FROM_VALUE(0), // pull up/down NULL, 0, // set - NULL, 0, // sideset - 0, 0, // initial pin state + NULL, 0, false, // sideset + PIO_PINMASK_FROM_VALUE(0), PIO_PINMASK_FROM_VALUE(0), // initial pin state data->pin, // jump pin pins_we_use, false, true, true, 32, false, // TX setting we don't use diff --git a/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c index 4f226fe56e9..a40f6e26608 100644 --- a/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c +++ b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.c @@ -14,7 +14,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "py/runtime.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" static i2c_inst_t *i2c[2] = {i2c0, i2c1}; @@ -85,6 +85,13 @@ void common_hal_i2ctarget_i2c_target_deinit(i2ctarget_i2c_target_obj_t *self) { } int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *self, uint8_t *address, bool *is_read, bool *is_restart) { + // Interrupt bits must be cleared by software. Clear the STOP and + // RESTART interrupt bits after an I2C transaction finishes. + if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_STOP_DET_BITS) { + self->peripheral->hw->clr_stop_det; + self->peripheral->hw->clr_restart_det; + } + if (!((self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RX_FULL_BITS) || (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_RD_REQ_BITS))) { return 0; } @@ -98,12 +105,20 @@ int common_hal_i2ctarget_i2c_target_is_addressed(i2ctarget_i2c_target_obj_t *sel } int common_hal_i2ctarget_i2c_target_read_byte(i2ctarget_i2c_target_obj_t *self, uint8_t *data) { - if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) { - *data = (uint8_t)self->peripheral->hw->data_cmd; - return 1; - } else { - return 0; + // Wait for data to arrive or a STOP condition indicating the transfer is over. + // Without this wait, the CPU can drain the FIFO faster than bytes arrive on the + // I2C bus, causing transfers to be split into multiple partial reads. + for (int t = 0; t < 100; t++) { + if (self->peripheral->hw->status & I2C_IC_STATUS_RFNE_BITS) { + *data = (uint8_t)self->peripheral->hw->data_cmd; + return 1; + } + if (self->peripheral->hw->raw_intr_stat & I2C_IC_INTR_STAT_R_STOP_DET_BITS) { + break; + } + mp_hal_delay_us(10); } + return 0; } int common_hal_i2ctarget_i2c_target_write_byte(i2ctarget_i2c_target_obj_t *self, uint8_t data) { diff --git a/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.h b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.h index 0b6c2875e3f..5d4e0690cbf 100644 --- a/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.h +++ b/ports/raspberrypi/common-hal/i2ctarget/I2CTarget.h @@ -8,7 +8,7 @@ #include "py/obj.h" #include "common-hal/microcontroller/Pin.h" -#include "src/rp2_common/hardware_i2c/include/hardware/i2c.h" +#include "hardware/i2c.h" typedef struct { mp_obj_base_t base; diff --git a/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c b/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c index ac378d58770..d0a7a1d7b08 100644 --- a/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c +++ b/ports/raspberrypi/common-hal/imagecapture/ParallelImageCapture.c @@ -18,8 +18,8 @@ #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/__init__.h" -#include "src/rp2_common/hardware_pio/include/hardware/pio.h" -#include "src/rp2_common/hardware_pio/include/hardware/pio_instructions.h" +#include "hardware/pio.h" +#include "hardware/pio_instructions.h" // Define this to (1), and you can scope the instruction-pointer of the state machine on D26..28 (note the weird encoding though!) #define DEBUG_STATE_MACHINE (0) @@ -83,18 +83,19 @@ void common_hal_imagecapture_parallelimagecapture_construct(imagecapture_paralle common_hal_mcu_processor_get_frequency(), // full speed (4 instructions per loop -> max pclk 30MHz @ 120MHz) 0, 0, // init NULL, 0, // may_exec - NULL, 0, 0, 0, // out pins + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // out pins pin_from_number(data_pins[0]), data_count, // in pins - 0, 0, // in pulls - NULL, 0, 0, 0, // set pins + PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // in pulls + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // set pins #if DEBUG_STATE_MACHINE - &pin_GPIO26, 3, 7, 7, // sideset pins + &pin_GPIO26, 3, PIO_PINMASK32_FROM_VALUE(7), PIO_PINMASK32_FROM_VALUE(7), // sideset pins #else - NULL, 0, 0, 0, // sideset pins + NULL, 0, false, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // sideset pins #endif false, // No sideset enable NULL, PULL_NONE, // jump pin - (1 << vertical_sync->number) | (1 << horizontal_reference->number) | (1 << data_clock->number), // wait gpio pins + PIO_PINMASK_OR3(PIO_PINMASK_FROM_PIN(vertical_sync->number), PIO_PINMASK_FROM_PIN(horizontal_reference->number), PIO_PINMASK_FROM_PIN(data_clock->number)), + // wait gpio pins true, // exclusive pin use false, 32, false, // out settings false, // wait for txstall diff --git a/ports/raspberrypi/common-hal/max3421e/Max3421E.c b/ports/raspberrypi/common-hal/max3421e/Max3421E.c index 20ce701b9f3..0077b460ed0 100644 --- a/ports/raspberrypi/common-hal/max3421e/Max3421E.c +++ b/ports/raspberrypi/common-hal/max3421e/Max3421E.c @@ -10,7 +10,7 @@ #include "shared-bindings/busio/SPI.h" #include "supervisor/usb.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" static max3421e_max3421e_obj_t *active_max = NULL; diff --git a/ports/raspberrypi/common-hal/mcp4822/MCP4822.c b/ports/raspberrypi/common-hal/mcp4822/MCP4822.c new file mode 100644 index 00000000000..ba4a39b11d8 --- /dev/null +++ b/ports/raspberrypi/common-hal/mcp4822/MCP4822.c @@ -0,0 +1,288 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT +// +// MCP4822 dual-channel 12-bit SPI DAC audio output. +// Uses PIO + DMA for non-blocking audio playback, mirroring audiobusio.I2SOut. + +#include +#include + +#include "mpconfigport.h" + +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "common-hal/mcp4822/MCP4822.h" +#include "shared-bindings/mcp4822/MCP4822.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/audiocore/__init__.h" +#include "bindings/rp2pio/StateMachine.h" + +// ───────────────────────────────────────────────────────────────────────────── +// PIO program for MCP4822 SPI DAC +// ───────────────────────────────────────────────────────────────────────────── +// +// Pin assignment: +// OUT pin (1) = MOSI — serial data out +// SET pins (N) = MOSI through CS — for CS control & command-bit injection +// SIDE-SET pin (1) = SCK — serial clock +// +// SET PINS bit mapping (bit0=MOSI, ..., bit N=CS): +// 0 = CS low, MOSI low 1 = CS low, MOSI high +// (1 << cs_bit_pos) = CS high, MOSI low +// +// SIDE-SET (1 pin, SCK): side 0 = SCK low, side 1 = SCK high +// +// MCP4822 16-bit command word: +// [15] channel (0=A, 1=B) [14] don't care [13] gain (1=1x, 0=2x) +// [12] output enable (1) [11:0] 12-bit data +// +// DMA feeds unsigned 16-bit audio samples. RP2040 narrow-write replication +// fills both halves of the 32-bit PIO FIFO entry with the same value, +// giving mono→stereo for free. +// +// The PIO pulls 32 bits, then sends two SPI transactions: +// Channel A: cmd nibble, then all 16 sample bits from upper half-word +// Channel B: cmd nibble, then all 16 sample bits from lower half-word +// The MCP4822 captures exactly 16 bits per CS frame (4 cmd + 12 data), +// so only the top 12 of the 16 sample bits become DAC data. The bottom +// 4 sample bits clock out harmlessly after the DAC has latched. +// This gives correct 16-bit → 12-bit scaling (effectively sample >> 4). +// +// PIO instruction encoding with .side_set 1 (no opt): +// [15:13] opcode [12] side-set [11:8] delay [7:0] operands +// +// Total: 26 instructions, 86 PIO clocks per audio sample. +// ───────────────────────────────────────────────────────────────────────────── + +static const uint16_t mcp4822_pio_program[] = { + // side SCK + // 0: pull noblock side 0 ; Get 32 bits or keep X if FIFO empty + 0x8080, + // 1: mov x, osr side 0 ; Save for pull-noblock fallback + 0xA027, + + // ── Channel A: command nibble 0b0011 (1x gain) ──────────────────────── + // 2: set pins, 0 side 0 ; CS low, MOSI=0 (bit15=0: channel A) + 0xE000, + // 3: nop side 1 ; SCK high — latch bit 15 + 0xB042, + // 4: set pins, 0 side 0 ; MOSI=0 (bit14=0: don't care) + 0xE000, + // 5: nop side 1 ; SCK high + 0xB042, + // 6: set pins, 1 side 0 ; MOSI=1 (bit13=1: gain 1x) [patched for 2x] + 0xE001, + // 7: nop side 1 ; SCK high + 0xB042, + // 8: set pins, 1 side 0 ; MOSI=1 (bit12=1: output active) + 0xE001, + // 9: nop side 1 ; SCK high + 0xB042, + // 10: set y, 15 side 0 ; Loop counter: 16 sample bits + 0xE04F, + // 11: out pins, 1 side 0 ; Data bit → MOSI; SCK low (bitloopA) + 0x6001, + // 12: jmp y--, 11 side 1 ; SCK high, loop back + 0x108B, + // 13: set pins, 4 side 0 ; CS high — DAC A latches + 0xE004, + + // ── Channel B: command nibble 0b1011 (1x gain) ──────────────────────── + // 14: set pins, 1 side 0 ; CS low, MOSI=1 (bit15=1: channel B) + 0xE001, + // 15: nop side 1 ; SCK high + 0xB042, + // 16: set pins, 0 side 0 ; MOSI=0 (bit14=0) + 0xE000, + // 17: nop side 1 ; SCK high + 0xB042, + // 18: set pins, 1 side 0 ; MOSI=1 (bit13=1: gain 1x) [patched for 2x] + 0xE001, + // 19: nop side 1 ; SCK high + 0xB042, + // 20: set pins, 1 side 0 ; MOSI=1 (bit12=1: output active) + 0xE001, + // 21: nop side 1 ; SCK high + 0xB042, + // 22: set y, 15 side 0 ; Loop counter: 16 sample bits + 0xE04F, + // 23: out pins, 1 side 0 ; Data bit → MOSI; SCK low (bitloopB) + 0x6001, + // 24: jmp y--, 23 side 1 ; SCK high, loop back + 0x1097, + // 25: set pins, 4 side 0 ; CS high — DAC B latches + 0xE004, +}; + +// Clocks per sample: 2 (pull+mov) + 42 (chanA) + 42 (chanB) = 86 +// Per channel: 8(4 cmd bits × 2 clks) + 1(set y) + 32(16 bits × 2 clks) + 1(cs high) = 42 +#define MCP4822_CLOCKS_PER_SAMPLE 86 + +// MCP4822 gain bit (bit 13) position in the PIO program: +// Instruction 6 = channel A gain bit +// Instruction 18 = channel B gain bit +// 1x gain: set pins, 1 (0xE001) — bit 13 = 1 +// 2x gain: set pins, 0 (0xE000) — bit 13 = 0 +#define MCP4822_PIO_GAIN_INSTR_A 6 +#define MCP4822_PIO_GAIN_INSTR_B 18 +#define MCP4822_PIO_GAIN_1X 0xE001 // set pins, 1 +#define MCP4822_PIO_GAIN_2X 0xE000 // set pins, 0 + +void mcp4822_reset(void) { +} + +// Caller validates that pins are free. +void common_hal_mcp4822_mcp4822_construct(mcp4822_mcp4822_obj_t *self, + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *cs, uint8_t gain) { + + // The SET pin group spans from MOSI to CS. + // MOSI must have a lower GPIO number than CS, gap at most 4. + if (cs->number <= mosi->number || (cs->number - mosi->number) > 4) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q and %q"), MP_QSTR_CS, MP_QSTR_MOSI); + } + + uint8_t set_count = cs->number - mosi->number + 1; + + // Build a mutable copy of the PIO program and patch the gain bit + uint16_t program[MP_ARRAY_SIZE(mcp4822_pio_program)]; + memcpy(program, mcp4822_pio_program, sizeof(mcp4822_pio_program)); + uint16_t gain_instr = (gain == 2) ? MCP4822_PIO_GAIN_2X : MCP4822_PIO_GAIN_1X; + program[MCP4822_PIO_GAIN_INSTR_A] = gain_instr; + program[MCP4822_PIO_GAIN_INSTR_B] = gain_instr; + + // Initial SET pin state: CS high (bit at CS position), others low + uint32_t cs_bit_position = cs->number - mosi->number; + pio_pinmask32_t initial_set_state = PIO_PINMASK32_FROM_VALUE(1u << cs_bit_position); + pio_pinmask32_t initial_set_dir = PIO_PINMASK32_FROM_VALUE((1u << set_count) - 1); + + common_hal_rp2pio_statemachine_construct( + &self->state_machine, + program, MP_ARRAY_SIZE(mcp4822_pio_program), + 44100 * MCP4822_CLOCKS_PER_SAMPLE, // Initial frequency; play() adjusts + NULL, 0, // No init program + NULL, 0, // No may_exec + mosi, 1, // OUT: MOSI, 1 pin + PIO_PINMASK32_NONE, PIO_PINMASK32_ALL, // OUT state=low, dir=output + NULL, 0, // IN: none + PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // IN pulls: none + mosi, set_count, // SET: MOSI..CS + initial_set_state, initial_set_dir, // SET state (CS high), dir=output + clock, 1, false, // SIDE-SET: SCK, 1 pin, not pindirs + PIO_PINMASK32_NONE, // SIDE-SET state: SCK low + PIO_PINMASK32_FROM_VALUE(0x1), // SIDE-SET dir: output + false, // No sideset enable + NULL, PULL_NONE, // No jump pin + PIO_PINMASK_NONE, // No wait GPIO + true, // Exclusive pin use + false, 32, false, // OUT shift: no autopull, 32-bit, shift left + false, // Don't wait for txstall + false, 32, false, // IN shift (unused) + false, // Not user-interruptible + 0, -1, // Wrap: whole program + PIO_ANY_OFFSET, + PIO_FIFO_TYPE_DEFAULT, + PIO_MOV_STATUS_DEFAULT, + PIO_MOV_N_DEFAULT + ); + + self->playing = false; + audio_dma_init(&self->dma); +} + +bool common_hal_mcp4822_mcp4822_deinited(mcp4822_mcp4822_obj_t *self) { + return common_hal_rp2pio_statemachine_deinited(&self->state_machine); +} + +void common_hal_mcp4822_mcp4822_deinit(mcp4822_mcp4822_obj_t *self) { + if (common_hal_mcp4822_mcp4822_deinited(self)) { + return; + } + if (common_hal_mcp4822_mcp4822_get_playing(self)) { + common_hal_mcp4822_mcp4822_stop(self); + } + common_hal_rp2pio_statemachine_deinit(&self->state_machine); + audio_dma_deinit(&self->dma); +} + +void common_hal_mcp4822_mcp4822_play(mcp4822_mcp4822_obj_t *self, + mp_obj_t sample, bool loop) { + + if (common_hal_mcp4822_mcp4822_get_playing(self)) { + common_hal_mcp4822_mcp4822_stop(self); + } + + audiosample_check(sample); + + uint8_t bits_per_sample = audiosample_get_bits_per_sample(sample); + if (bits_per_sample < 16) { + bits_per_sample = 16; + } + + uint32_t sample_rate = audiosample_get_sample_rate(sample); + uint8_t channel_count = audiosample_get_channel_count(sample); + if (channel_count > 2) { + mp_raise_ValueError(MP_ERROR_TEXT("Too many channels in sample.")); + } + + // PIO clock = sample_rate × clocks_per_sample + common_hal_rp2pio_statemachine_set_frequency( + &self->state_machine, + (uint32_t)sample_rate * MCP4822_CLOCKS_PER_SAMPLE); + common_hal_rp2pio_statemachine_restart(&self->state_machine); + + audio_dma_result result = audio_dma_setup_playback( + &self->dma, + sample, + loop, + false, // single_channel_output + 0, // audio_channel + false, // output_signed = false (unsigned for MCP4822) + bits_per_sample, // output_resolution + (uint32_t)&self->state_machine.pio->txf[self->state_machine.state_machine], + self->state_machine.tx_dreq, + false); // swap_channel + + if (result == AUDIO_DMA_DMA_BUSY) { + common_hal_mcp4822_mcp4822_stop(self); + mp_raise_RuntimeError(MP_ERROR_TEXT("No DMA channel found")); + } else if (result == AUDIO_DMA_MEMORY_ERROR) { + common_hal_mcp4822_mcp4822_stop(self); + mp_raise_RuntimeError(MP_ERROR_TEXT("Unable to allocate buffers for signed conversion")); + } else if (result == AUDIO_DMA_SOURCE_ERROR) { + common_hal_mcp4822_mcp4822_stop(self); + mp_raise_RuntimeError(MP_ERROR_TEXT("Audio source error")); + } + + self->playing = true; +} + +void common_hal_mcp4822_mcp4822_pause(mcp4822_mcp4822_obj_t *self) { + audio_dma_pause(&self->dma); +} + +void common_hal_mcp4822_mcp4822_resume(mcp4822_mcp4822_obj_t *self) { + audio_dma_resume(&self->dma); +} + +bool common_hal_mcp4822_mcp4822_get_paused(mcp4822_mcp4822_obj_t *self) { + return audio_dma_get_paused(&self->dma); +} + +void common_hal_mcp4822_mcp4822_stop(mcp4822_mcp4822_obj_t *self) { + audio_dma_stop(&self->dma); + common_hal_rp2pio_statemachine_stop(&self->state_machine); + self->playing = false; +} + +bool common_hal_mcp4822_mcp4822_get_playing(mcp4822_mcp4822_obj_t *self) { + bool playing = audio_dma_get_playing(&self->dma); + if (!playing && self->playing) { + common_hal_mcp4822_mcp4822_stop(self); + } + return playing; +} diff --git a/ports/raspberrypi/common-hal/mcp4822/MCP4822.h b/ports/raspberrypi/common-hal/mcp4822/MCP4822.h new file mode 100644 index 00000000000..53c8e862b63 --- /dev/null +++ b/ports/raspberrypi/common-hal/mcp4822/MCP4822.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/rp2pio/StateMachine.h" + +#include "audio_dma.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + rp2pio_statemachine_obj_t state_machine; + audio_dma_t dma; + bool playing; +} mcp4822_mcp4822_obj_t; + +void mcp4822_reset(void); diff --git a/ports/raspberrypi/common-hal/mcp4822/__init__.c b/ports/raspberrypi/common-hal/mcp4822/__init__.c new file mode 100644 index 00000000000..48981fc88a7 --- /dev/null +++ b/ports/raspberrypi/common-hal/mcp4822/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +// No module-level init needed. diff --git a/ports/raspberrypi/common-hal/mdns/RemoteService.c b/ports/raspberrypi/common-hal/mdns/RemoteService.c index 650e86da9d9..3d80199397e 100644 --- a/ports/raspberrypi/common-hal/mdns/RemoteService.c +++ b/ports/raspberrypi/common-hal/mdns/RemoteService.c @@ -39,6 +39,3 @@ mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t } return common_hal_ipaddress_new_ipv4address(addr); } - -void common_hal_mdns_remoteservice_deinit(mdns_remoteservice_obj_t *self) { -} diff --git a/ports/raspberrypi/common-hal/mdns/Server.c b/ports/raspberrypi/common-hal/mdns/Server.c index 4c87dd46640..1afccf4eb48 100644 --- a/ports/raspberrypi/common-hal/mdns/Server.c +++ b/ports/raspberrypi/common-hal/mdns/Server.c @@ -42,10 +42,15 @@ void mdns_server_construct(mdns_server_obj_t *self, bool workflow) { } self->inited = true; + self->instance_name[0] = '\0'; + self->num_txt_records = 0; + self->txt_storage = NULL; + uint8_t mac[6]; wifi_radio_get_mac_address(&common_hal_wifi_radio_obj, mac); - snprintf(self->default_hostname, sizeof(self->default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]); - common_hal_mdns_server_set_hostname(self, self->default_hostname); + char default_hostname[sizeof("cpy-XXXXXX")]; + snprintf(default_hostname, sizeof(default_hostname), "cpy-%02x%02x%02x", mac[3], mac[4], mac[5]); + common_hal_mdns_server_set_hostname(self, default_hostname); if (workflow) { // Add a second host entry to respond to "circuitpython.local" queries as well. @@ -91,15 +96,18 @@ void common_hal_mdns_server_set_hostname(mdns_server_obj_t *self, const char *ho mdns_resp_add_netif(NETIF_STA, hostname); } - self->hostname = hostname; + strlcpy(self->hostname, hostname, sizeof(self->hostname)); } const char *common_hal_mdns_server_get_instance_name(mdns_server_obj_t *self) { + if (self->instance_name[0] == '\0') { + return self->hostname; + } return self->instance_name; } void common_hal_mdns_server_set_instance_name(mdns_server_obj_t *self, const char *instance_name) { - self->instance_name = instance_name; + strlcpy(self->instance_name, instance_name, sizeof(self->instance_name)); } typedef struct { @@ -211,7 +219,7 @@ static void alloc_search_result_cb(struct mdns_answer *answer, const char *varpa if ((flags & MDNS_SEARCH_RESULT_FIRST) != 0) { // first - mdns_remoteservice_obj_t *service = m_malloc(sizeof(mdns_remoteservice_obj_t)); + mdns_remoteservice_obj_t *service = m_malloc_maybe(sizeof(mdns_remoteservice_obj_t)); if (service == NULL) { // alloc fails mdns_search_stop(state->request_id); @@ -288,15 +296,64 @@ static void srv_txt_cb(struct mdns_service *service, void *ptr) { } } +// Take our own copies of the TXT records. lwip only stores srv_txt_cb and this +// object, and calls back at packet-build time, so the caller's strings must +// outlive the call -- and the caller hands us pointers into GC-heap strings. +// +// WARNING: the copies live on the GC heap, which is only safe because TXT +// records can reach us solely through the Python binding, so the VM is +// necessarily running and this object is itself a GC object that dies with the +// same heap. The supervisor's static mdns_server_obj_t never gets TXT records +// (web_workflow.c passes NULL, 0). If supervisor code ever needs to advertise +// TXT records, this must move off the GC heap first -- an inline pool in +// mdns_server_obj_t, or port_malloc -- or the records will dangle after the +// first VM reset. static void assign_txt_records(mdns_server_obj_t *self, const char *txt_records[], size_t num_txt_records) { - size_t allowed_num_txt_records = MDNS_MAX_TXT_RECORDS < num_txt_records ? MDNS_MAX_TXT_RECORDS : num_txt_records; - self->num_txt_records = allowed_num_txt_records; - for (size_t i = 0; i < allowed_num_txt_records; i++) { - self->txt_records[i] = txt_records[i]; + size_t total = 0; + for (size_t i = 0; i < num_txt_records; i++) { + total += strlen(txt_records[i]) + 1; } + + // Build the replacement before touching self, so that the allocation, and + // any MemoryError it raises, happens outside the lwip lock below. + char *storage = NULL; + const char *records[MDNS_MAX_TXT_RECORDS]; + if (total > 0) { + storage = m_malloc_maybe(total); + if (storage == NULL) { + m_malloc_fail(total); + } + char *next = storage; + for (size_t i = 0; i < num_txt_records; i++) { + size_t size = strlen(txt_records[i]) + 1; + memcpy(next, txt_records[i], size); + records[i] = next; + next += size; + } + } + + // srv_txt_cb reads these from the lwip IRQ, so hold lwip off while they + // change. Otherwise a callback already part way through the old records + // keeps pointers into storage we are about to release. + MICROPY_PY_LWIP_ENTER + char *old_storage = self->txt_storage; + for (size_t i = 0; i < num_txt_records; i++) { + self->txt_records[i] = records[i]; + } + self->txt_storage = storage; + self->num_txt_records = num_txt_records; + MICROPY_PY_LWIP_EXIT + + // Nothing can be holding pointers into it now, so release it here rather + // than leaving the GC to do it at an unpredictable time. + m_free(old_storage); } void common_hal_mdns_server_advertise_service(mdns_server_obj_t *self, const char *service_type, const char *protocol, mp_int_t port, const char *txt_records[], size_t num_txt_records) { + // Check before touching any state, so a rejected call leaves the existing + // advertisement alone. + mp_arg_validate_length_max(num_txt_records, MDNS_MAX_TXT_RECORDS, MP_QSTR_txt_records); + enum mdns_sd_proto proto = DNSSD_PROTO_UDP; if (strcmp(protocol, "_tcp") == 0) { proto = DNSSD_PROTO_TCP; @@ -316,7 +373,7 @@ void common_hal_mdns_server_advertise_service(mdns_server_obj_t *self, const cha } assign_txt_records(self, txt_records, num_txt_records); - int8_t slot = mdns_resp_add_service(NETIF_STA, self->instance_name, service_type, proto, port, srv_txt_cb, self); + int8_t slot = mdns_resp_add_service(NETIF_STA, common_hal_mdns_server_get_instance_name(self), service_type, proto, port, srv_txt_cb, self); if (slot < 0) { mp_raise_RuntimeError(MP_ERROR_TEXT("Out of MDNS service slots")); return; diff --git a/ports/raspberrypi/common-hal/mdns/Server.h b/ports/raspberrypi/common-hal/mdns/Server.h index 620e201c897..041add08818 100644 --- a/ports/raspberrypi/common-hal/mdns/Server.h +++ b/ports/raspberrypi/common-hal/mdns/Server.h @@ -14,11 +14,16 @@ typedef struct { mp_obj_base_t base; - const char *hostname; - const char *instance_name; - char default_hostname[sizeof("cpy-XXXXXX")]; + // Store copies rather than the caller's pointers. The setters are handed + // GC-heap strings, which are recycled when the VM resets while this object + // (and the web workflow's static one) lives on. + char hostname[64]; // RFC 6762 Appendix A - 63 bytes for label + 1 for NUL + char instance_name[64]; // RFC 6763 Section 7.2 - 63 bytes + 1 for NUL const char *service_type[MDNS_MAX_SERVICES]; size_t num_txt_records; + // Owned copies of the TXT records, packed NUL-separated into txt_storage, + // which lives on the GC heap. See the warning on assign_txt_records(). + char *txt_storage; const char *txt_records[MDNS_MAX_TXT_RECORDS]; // Track if this object owns access to the underlying MDNS service. bool inited; diff --git a/ports/raspberrypi/common-hal/memorymap/AddressRange.c b/ports/raspberrypi/common-hal/memorymap/AddressRange.c index 0796a3b860b..a5e860cb40c 100644 --- a/ports/raspberrypi/common-hal/memorymap/AddressRange.c +++ b/ports/raspberrypi/common-hal/memorymap/AddressRange.c @@ -14,7 +14,7 @@ #include "hardware/regs/addressmap.h" // RP2 address map ranges, must be arranged in order by ascending start address -#ifdef PICO_RP2040 +#if PICO_RP2040 addressmap_rp2_range_t rp2_ranges[] = { {(uint8_t *)ROM_BASE, 0x00004000, ROM}, // boot ROM {(uint8_t *)XIP_BASE, 0x00100000, XIP}, // XIP normal cache operation @@ -36,7 +36,7 @@ addressmap_rp2_range_t rp2_ranges[] = { {(uint8_t *)PPB_BASE, 0x00004000, IO} // PPB registers }; #endif -#ifdef PICO_RP2350 +#if PICO_RP2350 addressmap_rp2_range_t rp2_ranges[] = { {(uint8_t *)ROM_BASE, 0x00004000, ROM}, // boot ROM {(uint8_t *)XIP_BASE, 0x00100000, XIP}, // XIP normal cache operation diff --git a/ports/raspberrypi/common-hal/microcontroller/Pin.c b/ports/raspberrypi/common-hal/microcontroller/Pin.c index 4ea7516d709..3c5286d36c4 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Pin.c +++ b/ports/raspberrypi/common-hal/microcontroller/Pin.c @@ -9,7 +9,7 @@ #include "common-hal/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" static uint64_t gpio_bank0_pin_claimed; diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.c b/ports/raspberrypi/common-hal/microcontroller/Processor.c index 678ceefbf92..c093a964c39 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Processor.c +++ b/ports/raspberrypi/common-hal/microcontroller/Processor.c @@ -15,31 +15,26 @@ #include "shared-bindings/time/__init__.h" #include "pico/stdlib.h" -#include "src/rp2_common/hardware_adc/include/hardware/adc.h" -#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h" -#include "src/rp2_common/hardware_vreg/include/hardware/vreg.h" -#include "src/rp2_common/hardware_watchdog/include/hardware/watchdog.h" - -#ifdef PICO_RP2040 -#include "src/rp2040/hardware_regs/include/hardware/regs/vreg_and_chip_reset.h" -#endif -#ifdef PICO_RP2350 -#include "src/rp2350/hardware_regs/include/hardware/regs/powman.h" -#endif -#include "src/rp2040/hardware_regs/include/hardware/regs/watchdog.h" - -#ifdef PICO_RP2040 -#include "src/rp2040/hardware_structs/include/hardware/structs/vreg_and_chip_reset.h" +#include "hardware/adc.h" +#include "hardware/clocks.h" +#include "hardware/vreg.h" +#include "hardware/watchdog.h" + +#if PICO_RP2040 +#include "hardware/regs/vreg_and_chip_reset.h" +#include "hardware/structs/vreg_and_chip_reset.h" #endif -#ifdef PICO_RP2350 -#include "src/rp2350/hardware_structs/include/hardware/structs/powman.h" +#if PICO_RP2350 +#include "hardware/regs/powman.h" +#include "hardware/structs/powman.h" #endif -#include "src/rp2040/hardware_structs/include/hardware/structs/watchdog.h" +#include "hardware/regs/watchdog.h" +#include "hardware/structs/watchdog.h" float common_hal_mcu_processor_get_temperature(void) { adc_init(); adc_set_temp_sensor_enabled(true); - adc_select_input(4); + adc_select_input(ADC_TEMPERATURE_CHANNEL_NUM); uint16_t value = adc_read(); adc_set_temp_sensor_enabled(false); float voltage = value * 3.3 / (1 << 12); @@ -83,41 +78,41 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - mcu_reset_reason_t reason = RESET_REASON_UNKNOWN; + mcu_reset_reason_t reason = MCU_RESET_REASON_UNKNOWN; - #ifdef PICO_RP2040 + #if PICO_RP2040 uint32_t chip_reset_reg = vreg_and_chip_reset_hw->chip_reset; if (chip_reset_reg & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_PSM_RESTART_BITS) { - reason = RESET_REASON_RESCUE_DEBUG; + reason = MCU_RESET_REASON_RESCUE_DEBUG; } if (chip_reset_reg & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_RUN_BITS) { - reason = RESET_REASON_RESET_PIN; + reason = MCU_RESET_REASON_RESET_PIN; } if (chip_reset_reg & VREG_AND_CHIP_RESET_CHIP_RESET_HAD_POR_BITS) { // NOTE: This register is also used for brownout, but there is no way to differentiate between power on and brown out - reason = RESET_REASON_POWER_ON; + reason = MCU_RESET_REASON_POWER_ON; } #endif - #ifdef PICO_RP2350 + #if PICO_RP2350 uint32_t chip_reset_reg = powman_hw->chip_reset; if (chip_reset_reg & POWMAN_CHIP_RESET_HAD_RESCUE_BITS) { - reason = RESET_REASON_RESCUE_DEBUG; + reason = MCU_RESET_REASON_RESCUE_DEBUG; } if (chip_reset_reg & POWMAN_CHIP_RESET_HAD_RUN_LOW_BITS) { - reason = RESET_REASON_RESET_PIN; + reason = MCU_RESET_REASON_RESET_PIN; } if (chip_reset_reg & POWMAN_CHIP_RESET_HAD_BOR_BITS) { - reason = RESET_REASON_BROWNOUT; + reason = MCU_RESET_REASON_BROWNOUT; } if (chip_reset_reg & POWMAN_CHIP_RESET_HAD_POR_BITS) { - reason = RESET_REASON_POWER_ON; + reason = MCU_RESET_REASON_POWER_ON; } #endif @@ -125,12 +120,12 @@ mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { // The watchdog is used for software reboots such as resetting after copying a UF2 via the bootloader. if (watchdog_caused_reboot()) { - reason = RESET_REASON_SOFTWARE; + reason = MCU_RESET_REASON_SOFTWARE; } // Actual watchdog usage will set a special value that this function detects. if (watchdog_enable_caused_reboot()) { - reason = RESET_REASON_WATCHDOG; + reason = MCU_RESET_REASON_WATCHDOG; } return reason; diff --git a/ports/raspberrypi/common-hal/microcontroller/Processor.h b/ports/raspberrypi/common-hal/microcontroller/Processor.h index 31f89f58fd3..df1e1cf2333 100644 --- a/ports/raspberrypi/common-hal/microcontroller/Processor.h +++ b/ports/raspberrypi/common-hal/microcontroller/Processor.h @@ -6,7 +6,7 @@ #pragma once -#include "src/rp2_common/pico_unique_id/include/pico/unique_id.h" +#include "pico/unique_id.h" #define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH PICO_UNIQUE_BOARD_ID_SIZE_BYTES diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.c b/ports/raspberrypi/common-hal/microcontroller/__init__.c index 7911c21e3cc..3d8bd381f5e 100644 --- a/ports/raspberrypi/common-hal/microcontroller/__init__.c +++ b/ports/raspberrypi/common-hal/microcontroller/__init__.c @@ -19,16 +19,34 @@ #include "supervisor/port.h" #include "supervisor/shared/safe_mode.h" -#include "src/rp2040/hardware_structs/include/hardware/structs/sio.h" -#include "src/rp2_common/hardware_sync/include/hardware/sync.h" +#include "hardware/structs/sio.h" +#include "hardware/sync.h" #include "hardware/watchdog.h" +#include "hardware/irq.h" + +// DMA interrupt (DMA_IRQ_n) allocation for this port: +// +// DMA_IRQ_0 Shared. audiocore (audio_dma.c) and rp2pio (StateMachine.c) each +// register a shared handler with irq_add_shared_handler() and +// service only their own DMA channels. Any new code that needs a +// DMA completion interrupt should do the same: add a shared handler +// on DMA_IRQ_0, check dma_hw->ints0, and acknowledge only its own +// channels. Runs at the default IRQ priority and is masked during +// flash writes (see common_hal_mcu_disable_interrupts below). +// DMA_IRQ_1 Exclusive to picodvi (Framebuffer_RP2040.c / Framebuffer_RP2350.c), +// registered with irq_set_exclusive_handler() at the highest +// priority. On RP2350 it is deliberately kept enabled during flash +// writes via BASEPRI (see below) so the display keeps refreshing. +// DMA_IRQ_2 RP2350 only; currently unused / free. +// DMA_IRQ_3 RP2350 only; currently unused / free. void common_hal_mcu_delay_us(uint32_t delay) { mp_hal_delay_us(delay); } volatile uint32_t nesting_count = 0; +#if PICO_RP2040 void common_hal_mcu_disable_interrupts(void) { // We don't use save_and_disable_interrupts() from the sdk because we don't want to worry about PRIMASK. // This is what we do on the SAMD21 via CMSIS. @@ -48,6 +66,40 @@ void common_hal_mcu_enable_interrupts(void) { __dmb(); asm volatile ("cpsie i" : : : "memory"); } +#else +#include "RP2350.h" +#define PICO_ELEVATED_IRQ_PRIORITY (0x60) // between PICO_DEFAULT and PIOCO_HIGHEST_IRQ_PRIORITY +static uint32_t oldBasePri = 0; // 0 (default) masks nothing, other values mask equal-or-larger priority values +void common_hal_mcu_disable_interrupts(void) { + uint32_t my_interrupts = save_and_disable_interrupts(); + if (nesting_count == 0) { + // We must keep DMA_IRQ_1 (reserved for pico dvi) enabled at all times, + // including during flash writes. Do this by setting the priority mask (BASEPRI + // register). + // grab old base priority + oldBasePri = __get_BASEPRI(); + // and set the new one + __set_BASEPRI_MAX(PICO_ELEVATED_IRQ_PRIORITY); + __isb(); // Instruction synchronization barrier + } + nesting_count++; + restore_interrupts(my_interrupts); +} + +void common_hal_mcu_enable_interrupts(void) { + uint32_t my_interrupts = save_and_disable_interrupts(); + if (nesting_count == 0) { + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); + } + nesting_count--; + if (nesting_count == 0) { + // return to the old priority setting + __set_BASEPRI(oldBasePri); + __isb(); // Instruction synchronization barrier + } + restore_interrupts(my_interrupts); +} +#endif static bool next_reset_to_bootloader = false; diff --git a/ports/raspberrypi/common-hal/microcontroller/__init__.h b/ports/raspberrypi/common-hal/microcontroller/__init__.h index e9a7602bc04..8798c857404 100644 --- a/ports/raspberrypi/common-hal/microcontroller/__init__.h +++ b/ports/raspberrypi/common-hal/microcontroller/__init__.h @@ -6,7 +6,7 @@ #pragma once -#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h" +#include "hardware/platform_defs.h" #include "peripherals/pins.h" const mcu_pin_obj_t *mcu_get_pin_by_number(int); diff --git a/ports/raspberrypi/common-hal/neopixel_write/__init__.c b/ports/raspberrypi/common-hal/neopixel_write/__init__.c index c3002220468..76db28a41e1 100644 --- a/ports/raspberrypi/common-hal/neopixel_write/__init__.c +++ b/ports/raspberrypi/common-hal/neopixel_write/__init__.c @@ -40,17 +40,17 @@ void common_hal_neopixel_write(const digitalio_digitalinout_obj_t *digitalinout, // TODO: Cache the state machine after we create it once. We'll need a way to // change the pins then though. - uint32_t pins_we_use = 1 << digitalinout->pin->number; + pio_pinmask_t pins_we_use = PIO_PINMASK_FROM_PIN(digitalinout->pin->number); bool ok = rp2pio_statemachine_construct(&state_machine, neopixel_program, MP_ARRAY_SIZE(neopixel_program), 12800000, // 12.8MHz, to get appropriate sub-bit times in PIO program. NULL, 0, // init program NULL, 1, // out NULL, 1, // in - 0, 0, // in pulls + PIO_PINMASK_NONE, PIO_PINMASK_NONE, // gpio pulls NULL, 1, // set - digitalinout->pin, 1, // sideset - 0, pins_we_use, // initial pin state + digitalinout->pin, 1, false, // sideset + PIO_PINMASK_NONE, pins_we_use, // initial pin state NULL, // jump pin pins_we_use, true, false, true, 8, false, // TX, auto pull every 8 bits. shift left to output msb first diff --git a/ports/raspberrypi/common-hal/nvm/ByteArray.c b/ports/raspberrypi/common-hal/nvm/ByteArray.c index 541f1a34bd7..558f38240ce 100644 --- a/ports/raspberrypi/common-hal/nvm/ByteArray.c +++ b/ports/raspberrypi/common-hal/nvm/ByteArray.c @@ -10,8 +10,9 @@ #include #include "py/runtime.h" -#include "src/rp2_common/hardware_flash/include/hardware/flash.h" +#include "hardware/flash.h" #include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/internal_flash.h" extern uint32_t __flash_binary_start; static const uint32_t flash_binary_start = (uint32_t)&__flash_binary_start; @@ -26,17 +27,16 @@ static void write_page(uint32_t page_addr, uint32_t offset, uint32_t len, uint8_ // Write a whole page to flash, buffering it first and then erasing and rewriting it // since we can only write a whole page at a time. if (offset == 0 && len == FLASH_PAGE_SIZE) { - // disable interrupts to prevent core hang on rp2040 - common_hal_mcu_disable_interrupts(); + supervisor_flash_pre_write(); flash_range_program(RMV_OFFSET(page_addr), bytes, FLASH_PAGE_SIZE); - common_hal_mcu_enable_interrupts(); + supervisor_flash_post_write(); } else { uint8_t buffer[FLASH_PAGE_SIZE]; memcpy(buffer, (uint8_t *)page_addr, FLASH_PAGE_SIZE); memcpy(buffer + offset, bytes, len); - common_hal_mcu_disable_interrupts(); + supervisor_flash_pre_write(); flash_range_program(RMV_OFFSET(page_addr), buffer, FLASH_PAGE_SIZE); - common_hal_mcu_enable_interrupts(); + supervisor_flash_post_write(); } } @@ -57,8 +57,10 @@ static void erase_and_write_sector(uint32_t address, uint32_t len, uint8_t *byte memcpy(buffer + address, bytes, len); // disable interrupts to prevent core hang on rp2040 common_hal_mcu_disable_interrupts(); + supervisor_flash_pre_write(); flash_range_erase(RMV_OFFSET(CIRCUITPY_INTERNAL_NVM_START_ADDR), FLASH_SECTOR_SIZE); flash_range_program(RMV_OFFSET(CIRCUITPY_INTERNAL_NVM_START_ADDR), buffer, FLASH_SECTOR_SIZE); + supervisor_flash_post_write(); common_hal_mcu_enable_interrupts(); } diff --git a/ports/raspberrypi/common-hal/os/__init__.c b/ports/raspberrypi/common-hal/os/__init__.c index 28c8ed94671..d2a8da4caef 100644 --- a/ports/raspberrypi/common-hal/os/__init__.c +++ b/ports/raspberrypi/common-hal/os/__init__.c @@ -18,61 +18,159 @@ #include -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "rp2040"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "rp2040"); -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} +#ifdef HAS_RP2350_TRNG +#include "hardware/structs/trng.h" +#include "hardware/sync.h" +#endif // NIST Special Publication 800-90B (draft) recommends several extractors, // including the SHA hash family and states that if the amount of entropy input // is twice the number of bits output from them, that output can be considered -// essentially fully random. If every RANDOM_SAFETY_MARGIN bits from -// `rosc_hw->randombit` have at least 1 bit of entropy, then this criterion is met. +// essentially fully random. +// +// This works by seeding `random_state` with entropy from hardware sources +// (SHA-256 as the conditioning function), then using that state as a counter +// input (SHA-256 as a CSPRNG), re-seeding at least every 256 blocks (8kB). // -// This works by seeding the `random_state` with plenty of random bits (SHA256 -// as entropy harvesting function), then using that state it as a counter input -// (SHA256 as a CSPRNG), re-seeding at least every 256 blocks (8kB). +// On RP2350, entropy comes from both the dedicated TRNG peripheral and the +// ROSC. On RP2040, the ROSC is the only available source. // // In practice, `PractRand` doesn't detect any gross problems with the output // random numbers on samples of 1 to 8 megabytes, no matter the setting of -// RANDOM_SAFETY_MARGIN. (it does detect "unusual" results from time to time, +// ROSC_SAFETY_MARGIN. (it does detect "unusual" results from time to time, // as it will with any RNG) -#define RANDOM_SAFETY_MARGIN (4) + +// Number of ROSC collection rounds on RP2040. Each round feeds +// SHA256_BLOCK_SIZE bytes into the hash; we do 2*N rounds so the +// raw-to-output ratio satisfies 800-90B's 2:1 minimum. +#define ROSC_SAFETY_MARGIN (4) static BYTE random_state[SHA256_BLOCK_SIZE]; + +// Collect `count` bytes from the ROSC, one bit per read. +static void rosc_random_bytes(BYTE *buf, size_t count) { + for (size_t i = 0; i < count; i++) { + buf[i] = rosc_hw->randombit & 1; + for (int k = 0; k < 8; k++) { + buf[i] = (buf[i] << 1) ^ (rosc_hw->randombit & 1); + } + } +} + +#ifdef HAS_RP2350_TRNG + +// TRNG_DEBUG_CONTROL bypass bits: +// +// bit 1 VNC_BYPASS Von Neumann corrector +// bit 2 TRNG_CRNGT_BYPASS Continuous Random Number Generator Test +// bit 3 AUTO_CORRELATE_BYPASS Autocorrelation test +// +// We bypass Von Neumann and autocorrelation but keep CRNGT. +// +// Von Neumann (bypassed): ~4x throughput cost for bias removal. +// Redundant here because SHA-256 conditioning already handles +// biased input -- that's what the 2:1 oversampling ratio is for. +// +// Autocorrelation (bypassed): has a non-trivial false-positive rate +// at high sampling speeds and halts the TRNG until SW reset on +// failure. SHA-256 is not bothered by correlated input. ARM's own +// TZ-TRNG 90B reference configuration also bypasses it (0x0A). +// +// CRNGT (kept): compares consecutive 192-bit EHR outputs. Flags if +// identical -- false-positive rate 2^-192, throughput cost zero. +// This is our early warning for a stuck oscillator or a successful +// injection lock to a fixed state. +#define TRNG_BYPASS_BITS \ + (TRNG_TRNG_DEBUG_CONTROL_VNC_BYPASS_BITS | \ + TRNG_TRNG_DEBUG_CONTROL_AUTO_CORRELATE_BYPASS_BITS) + +// Collect 192 raw bits (6 x 32-bit words) from the TRNG. +// Returns false on CRNGT failure (consecutive identical EHR outputs). +// +// Holds PICO_SPINLOCK_ID_RAND (the SDK's lock for this peripheral) +// with interrupts disabled for the duration of the collection, which +// takes ~192 ROSC cycles (~24us at 8MHz). +static bool trng_collect_192(uint32_t out[6]) { + spin_lock_t *lock = spin_lock_instance(PICO_SPINLOCK_ID_RAND); + uint32_t save = spin_lock_blocking(lock); + + trng_hw->trng_debug_control = TRNG_BYPASS_BITS; + // One rng_clk cycle between samples. The SDK uses 0 here, but it + // also sets debug_control = -1u (full bypass). The behavior of + // sample_cnt1 = 0 with health tests still active is undocumented, + // so we use 1 to be safe. + trng_hw->sample_cnt1 = 1; + trng_hw->rnd_source_enable = 1; + trng_hw->rng_icr = 0xFFFFFFFF; + + while (trng_hw->trng_busy) { + } + + if (trng_hw->rng_isr & TRNG_RNG_ISR_CRNGT_ERR_BITS) { + // Drain ehr_data so the hardware starts a fresh collection. + // (Reading the last word clears the valid flag.) + for (int i = 0; i < 6; i++) { + (void)trng_hw->ehr_data[i]; + } + trng_hw->rng_icr = TRNG_RNG_ISR_CRNGT_ERR_BITS; + spin_unlock(lock, save); + return false; + } + + for (int i = 0; i < 6; i++) { + out[i] = trng_hw->ehr_data[i]; + } + + // Switch the inverter chain length for the next collection, using + // bits from the sample we just read. Only bits [1:0] matter -- they + // select one of four chain lengths, changing the ROSC frequency. + // This is borrowed from pico_rand's injection-locking countermeasure. + // (The SDK uses its PRNG state here instead of raw output; either + // works since the real defense is SHA-256 conditioning, not this.) + trng_hw->trng_config = out[0]; + + spin_unlock(lock, save); + return true; +} + +#endif // HAS_RP2350_TRNG + static void seed_random_bits(BYTE out[SHA256_BLOCK_SIZE]) { CRYAL_SHA256_CTX context; sha256_init(&context); - for (int i = 0; i < 2 * RANDOM_SAFETY_MARGIN; i++) { - for (int j = 0; j < SHA256_BLOCK_SIZE; j++) { - out[j] = rosc_hw->randombit & 1; - for (int k = 0; k < 8; k++) { - out[j] = (out[j] << 1) ^ (rosc_hw->randombit & 1); + + #ifdef HAS_RP2350_TRNG + // 384 bits from TRNG + 384 bits from ROSC = 768 bits into the hash, + // giving a 3:1 ratio over the 256-bit output (800-90B wants >= 2:1). + // Two independent sources so a failure in one doesn't zero the input. + + // TRNG: 2 x 192 bits. + for (int i = 0; i < 2; i++) { + uint32_t trng_buf[6] = {0}; + for (int attempt = 0; attempt < 3; attempt++) { + if (trng_collect_192(trng_buf)) { + break; } + // CRNGT failure. If all 3 retries fail, trng_buf stays zeroed + // and we rely entirely on the ROSC contribution below. } + sha256_update(&context, (const BYTE *)trng_buf, sizeof(trng_buf)); + } + + // ROSC: 2 x 24 bytes = 384 bits. + for (int i = 0; i < 2; i++) { + BYTE rosc_buf[24]; + rosc_random_bytes(rosc_buf, sizeof(rosc_buf)); + sha256_update(&context, rosc_buf, sizeof(rosc_buf)); + } + #else + // RP2040: ROSC is the only entropy source. + for (int i = 0; i < 2 * ROSC_SAFETY_MARGIN; i++) { + rosc_random_bytes(out, SHA256_BLOCK_SIZE); sha256_update(&context, out, SHA256_BLOCK_SIZE); } + #endif + sha256_final(&context, out); } @@ -87,10 +185,11 @@ static void get_random_bits(BYTE out[SHA256_BLOCK_SIZE]) { } bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { -#define ROSC_POWER_SAVE (1) // assume ROSC is not necessarily active all the time + #define ROSC_POWER_SAVE (1) // assume ROSC is not necessarily active all the time #if ROSC_POWER_SAVE uint32_t old_rosc_ctrl = rosc_hw->ctrl; - rosc_hw->ctrl = (old_rosc_ctrl & ~ROSC_CTRL_ENABLE_BITS) | (ROSC_CTRL_ENABLE_VALUE_ENABLE << 12); + rosc_hw->ctrl = (old_rosc_ctrl & ~ROSC_CTRL_ENABLE_BITS) + | (ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB); #endif while (length) { size_t n = MIN(length, SHA256_BLOCK_SIZE); diff --git a/ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c b/ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c index bb0d3c1fd42..517d960b765 100644 --- a/ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c +++ b/ports/raspberrypi/common-hal/paralleldisplaybus/ParallelBus.c @@ -79,13 +79,13 @@ void common_hal_paralleldisplaybus_parallelbus_construct(paralleldisplaybus_para frequency * 2, // frequency multiplied by 2 as 2 PIO instructions NULL, 0, // init NULL, 0, // may_exec - data0, 8, 0, 255, // first out pin, # out pins - NULL, 0, 0, 0, // first in pin, # in pins - NULL, 0, 0, 0, // first set pin - write, 1, 0, 1, // first sideset pin + data0, 8, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(255), // first out pin, # out pins + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // first in pin, # in pins + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // first set pin + write, 1, false, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(1), // first sideset pin false, // No sideset enable NULL, PULL_NONE, // jump pin - 0, // wait gpio pins + PIO_PINMASK_NONE, // wait gpio pins true, // exclusive pin usage true, 8, true, // TX, auto pull every 8 bits. shift left to output msb first false, // wait for TX stall diff --git a/ports/raspberrypi/common-hal/picodvi/Framebuffer.h b/ports/raspberrypi/common-hal/picodvi/Framebuffer.h index 50288578590..82c0b189b89 100644 --- a/ports/raspberrypi/common-hal/picodvi/Framebuffer.h +++ b/ports/raspberrypi/common-hal/picodvi/Framebuffer.h @@ -6,7 +6,7 @@ #pragma once -#ifdef PICO_RP2040 +#if PICO_RP2040 #include "Framebuffer_RP2040.h" #else #include "Framebuffer_RP2350.h" diff --git a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c index b244fb8bbd0..53ed37cefbe 100644 --- a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c +++ b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2040.c @@ -13,20 +13,18 @@ #include "common-hal/rp2pio/StateMachine.h" #include "supervisor/port.h" -#include "src/common/pico_stdlib_headers/include/pico/stdlib.h" -#include "src/rp2040/hardware_structs/include/hardware/structs/mpu.h" -#include "src/rp2_common/cmsis/stub/CMSIS/Device/RP2040/Include/RP2040.h" -#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h" -#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" -#include "src/rp2_common/hardware_vreg/include/hardware/vreg.h" -#include "src/rp2_common/pico_multicore/include/pico/multicore.h" +#include "pico/stdlib.h" +#include "hardware/structs/mpu.h" +#include "RP2040.h" // (cmsis) +#include "hardware/clocks.h" +#include "hardware/pwm.h" +#include "hardware/vreg.h" +#include "pico/multicore.h" #include "lib/PicoDVI/software/libdvi/tmds_encode.h" picodvi_framebuffer_obj_t *active_picodvi = NULL; -static PIO pio_instances[2] = {pio0, pio1}; - static void __not_in_flash_func(core1_main)(void) { // The MPU is reset before this starts. @@ -143,7 +141,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, // If the width is > 400, then it must not be color frame buffer and vice // versa. - if ((width > 400) == color_framebuffer || color_depth == 4) { + if ((width > 400) == color_framebuffer || color_depth == 4 || color_depth == 32) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth); } @@ -176,32 +174,23 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, uint8_t slice = pwm_gpio_to_slice_num(self->pin_pair[0]); - pio_program_t program_struct = { - .instructions = NULL, - .length = 2, - .origin = -1 - }; - size_t pio_index = NUM_PIOS; - int free_state_machines[4]; // We may find all four free. We only use the first three. - for (size_t i = 0; i < NUM_PIOS; i++) { - PIO pio = pio_instances[i]; - uint8_t free_count = 0; - for (size_t sm = 0; sm < NUM_PIO_STATE_MACHINES; sm++) { - if (!pio_sm_is_claimed(pio, sm)) { - free_state_machines[free_count] = sm; - free_count++; - } - } - if (free_count >= 3 && pio_can_add_program(pio, &program_struct)) { - pio_index = i; - break; - } - } - + // We need a PIO with room for a 2-instruction program and 3 free state machines. + size_t pio_index = rp2pio_statemachine_find_pio(2, 3); if (pio_index == NUM_PIOS) { mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use")); } + // Collect the free state machines on the chosen PIO. We only use the first three. + int free_state_machines[4]; // We may find all four free. + uint8_t free_count = 0; + PIO pio = pio_get_instance(pio_index); + for (size_t sm = 0; sm < NUM_PIO_STATE_MACHINES; sm++) { + if (!pio_sm_is_claimed(pio, sm)) { + free_state_machines[free_count] = sm; + free_count++; + } + } + self->width = width; self->height = height; @@ -244,7 +233,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, } for (size_t i = 0; i < 3; i++) { - rp2pio_statemachine_never_reset(pio_instances[pio_index], free_state_machines[i]); + rp2pio_statemachine_never_reset(pio_get_instance(pio_index), free_state_machines[i]); } // For the output. @@ -253,7 +242,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, self->color_depth = color_depth; self->dvi.timing = timing; - self->dvi.ser_cfg.pio = pio_instances[pio_index]; + self->dvi.ser_cfg.pio = pio_get_instance(pio_index); self->dvi.ser_cfg.sm_tmds[0] = free_state_machines[0]; self->dvi.ser_cfg.sm_tmds[1] = free_state_machines[1]; self->dvi.ser_cfg.sm_tmds[2] = free_state_machines[2]; @@ -375,6 +364,11 @@ bool common_hal_picodvi_framebuffer_deinited(picodvi_framebuffer_obj_t *self) { void common_hal_picodvi_framebuffer_refresh(picodvi_framebuffer_obj_t *self) { } +void common_hal_picodvi_framebuffer_wait_for_vblank(picodvi_framebuffer_obj_t *self) { + // No frame-boundary counter on the RP2040 PIO-DVI path; vblank sync is a no-op here (the + // tear-free full-repaint path is RP2350/HSTX, e.g. Fruit Jam). Present so the binding links. +} + int common_hal_picodvi_framebuffer_get_width(picodvi_framebuffer_obj_t *self) { return self->width; } @@ -387,6 +381,10 @@ int common_hal_picodvi_framebuffer_get_color_depth(picodvi_framebuffer_obj_t *se return self->color_depth; } +int common_hal_picodvi_framebuffer_get_native_frames_per_second(picodvi_framebuffer_obj_t *self) { + return 60; +} + bool common_hal_picodvi_framebuffer_get_grayscale(picodvi_framebuffer_obj_t *self) { return self->color_depth < 8; } diff --git a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c index c3d2b7bea2f..8c846ffc440 100644 --- a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c +++ b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.c @@ -29,16 +29,17 @@ #include "py/gc.h" #include "py/runtime.h" #include "shared-bindings/time/__init__.h" +#include "supervisor/background_callback.h" #include "supervisor/port.h" -#include "src/common/pico_stdlib_headers/include/pico/stdlib.h" +#include "pico/stdlib.h" // This is from: https://github.com/raspberrypi/pico-examples-rp2350/blob/a1/hstx/dvi_out_hstx_encoder/dvi_out_hstx_encoder.c -#include "sdk/src/rp2_common/hardware_dma/include/hardware/dma.h" -#include "sdk/src/rp2350/hardware_structs/include/hardware/structs/bus_ctrl.h" -#include "sdk/src/rp2350/hardware_structs/include/hardware/structs/hstx_ctrl.h" -#include "sdk/src/rp2350/hardware_structs/include/hardware/structs/hstx_fifo.h" +#include "hardware/dma.h" +#include "hardware/structs/bus_ctrl.h" +#include "hardware/structs/hstx_ctrl.h" +#include "hardware/structs/hstx_fifo.h" // ---------------------------------------------------------------------------- // DVI constants @@ -53,25 +54,37 @@ #define SYNC_V1_H0 (TMDS_CTRL_10 | (TMDS_CTRL_00 << 10) | (TMDS_CTRL_00 << 20)) #define SYNC_V1_H1 (TMDS_CTRL_11 | (TMDS_CTRL_00 << 10) | (TMDS_CTRL_00 << 20)) -#define MODE_H_SYNC_POLARITY 0 -#define MODE_H_FRONT_PORCH 16 -#define MODE_H_SYNC_WIDTH 96 -#define MODE_H_BACK_PORCH 48 -#define MODE_H_ACTIVE_PIXELS 640 - -#define MODE_V_SYNC_POLARITY 0 -#define MODE_V_FRONT_PORCH 10 -#define MODE_V_SYNC_WIDTH 2 -#define MODE_V_BACK_PORCH 33 -#define MODE_V_ACTIVE_LINES 480 - -#define MODE_H_TOTAL_PIXELS ( \ - MODE_H_FRONT_PORCH + MODE_H_SYNC_WIDTH + \ - MODE_H_BACK_PORCH + MODE_H_ACTIVE_PIXELS \ +#define MODE_720_H_SYNC_POLARITY 0 +#define MODE_720_H_FRONT_PORCH 8 +#define MODE_720_H_SYNC_WIDTH 32 +#define MODE_720_H_BACK_PORCH 40 +#define MODE_720_H_ACTIVE_PIXELS 720 + +#define MODE_720_V_SYNC_POLARITY 0 +#define MODE_720_V_FRONT_PORCH 3 +#define MODE_720_V_SYNC_WIDTH 4 +#define MODE_720_V_BACK_PORCH 218 +#define MODE_720_V_ACTIVE_LINES 400 + +#define MODE_640_H_SYNC_POLARITY 0 +#define MODE_640_H_FRONT_PORCH 16 +#define MODE_640_H_SYNC_WIDTH 96 +#define MODE_640_H_BACK_PORCH 48 +#define MODE_640_H_ACTIVE_PIXELS 640 + +#define MODE_640_V_SYNC_POLARITY 0 +#define MODE_640_V_FRONT_PORCH 10 +#define MODE_640_V_SYNC_WIDTH 2 +#define MODE_640_V_BACK_PORCH 133 +#define MODE_640_V_ACTIVE_LINES 480 + +#define MODE_720_V_TOTAL_LINES ( \ + MODE_720_V_FRONT_PORCH + MODE_720_V_SYNC_WIDTH + \ + MODE_720_V_BACK_PORCH + MODE_720_V_ACTIVE_LINES \ ) -#define MODE_V_TOTAL_LINES ( \ - MODE_V_FRONT_PORCH + MODE_V_SYNC_WIDTH + \ - MODE_V_BACK_PORCH + MODE_V_ACTIVE_LINES \ +#define MODE_640_V_TOTAL_LINES ( \ + MODE_640_V_FRONT_PORCH + MODE_640_V_SYNC_WIDTH + \ + MODE_640_V_BACK_PORCH + MODE_640_V_ACTIVE_LINES \ ) #define HSTX_CMD_RAW (0x0u << 12) @@ -83,50 +96,123 @@ // ---------------------------------------------------------------------------- // HSTX command lists -static uint32_t vblank_line_vsync_off[] = { - HSTX_CMD_RAW_REPEAT | MODE_H_FRONT_PORCH, +#define VSYNC_LEN 6 +#define VACTIVE_LEN 9 + +static uint32_t vblank_line640_vsync_off[VSYNC_LEN] = { + HSTX_CMD_RAW_REPEAT | MODE_640_H_FRONT_PORCH, SYNC_V1_H1, - HSTX_CMD_RAW_REPEAT | MODE_H_SYNC_WIDTH, + HSTX_CMD_RAW_REPEAT | MODE_640_H_SYNC_WIDTH, SYNC_V1_H0, - HSTX_CMD_RAW_REPEAT | (MODE_H_BACK_PORCH + MODE_H_ACTIVE_PIXELS), + HSTX_CMD_RAW_REPEAT | (MODE_640_H_BACK_PORCH + MODE_640_H_ACTIVE_PIXELS), SYNC_V1_H1 }; -static uint32_t vblank_line_vsync_on[] = { - HSTX_CMD_RAW_REPEAT | MODE_H_FRONT_PORCH, +static uint32_t vblank_line640_vsync_on[VSYNC_LEN] = { + HSTX_CMD_RAW_REPEAT | MODE_640_H_FRONT_PORCH, SYNC_V0_H1, - HSTX_CMD_RAW_REPEAT | MODE_H_SYNC_WIDTH, + HSTX_CMD_RAW_REPEAT | MODE_640_H_SYNC_WIDTH, SYNC_V0_H0, - HSTX_CMD_RAW_REPEAT | (MODE_H_BACK_PORCH + MODE_H_ACTIVE_PIXELS), + HSTX_CMD_RAW_REPEAT | (MODE_640_H_BACK_PORCH + MODE_640_H_ACTIVE_PIXELS), SYNC_V0_H1 }; -static uint32_t vactive_line[] = { - HSTX_CMD_RAW_REPEAT | MODE_H_FRONT_PORCH, +static uint32_t vactive_line640[VACTIVE_LEN] = { + HSTX_CMD_RAW_REPEAT | MODE_640_H_FRONT_PORCH, SYNC_V1_H1, HSTX_CMD_NOP, - HSTX_CMD_RAW_REPEAT | MODE_H_SYNC_WIDTH, + HSTX_CMD_RAW_REPEAT | MODE_640_H_SYNC_WIDTH, SYNC_V1_H0, HSTX_CMD_NOP, - HSTX_CMD_RAW_REPEAT | MODE_H_BACK_PORCH, + HSTX_CMD_RAW_REPEAT | MODE_640_H_BACK_PORCH, SYNC_V1_H1, - HSTX_CMD_TMDS | MODE_H_ACTIVE_PIXELS + HSTX_CMD_TMDS | MODE_640_H_ACTIVE_PIXELS +}; + +static uint32_t vblank_line720_vsync_off[VSYNC_LEN] = { + HSTX_CMD_RAW_REPEAT | MODE_720_H_FRONT_PORCH, + SYNC_V1_H1, + HSTX_CMD_RAW_REPEAT | MODE_720_H_SYNC_WIDTH, + SYNC_V1_H0, + HSTX_CMD_RAW_REPEAT | (MODE_720_H_BACK_PORCH + MODE_720_H_ACTIVE_PIXELS), + SYNC_V1_H1 +}; + +static uint32_t vblank_line720_vsync_on[VSYNC_LEN] = { + HSTX_CMD_RAW_REPEAT | MODE_720_H_FRONT_PORCH, + SYNC_V0_H1, + HSTX_CMD_RAW_REPEAT | MODE_720_H_SYNC_WIDTH, + SYNC_V0_H0, + HSTX_CMD_RAW_REPEAT | (MODE_720_H_BACK_PORCH + MODE_720_H_ACTIVE_PIXELS), + SYNC_V0_H1 +}; + +static uint32_t vactive_line720[VACTIVE_LEN] = { + HSTX_CMD_RAW_REPEAT | MODE_720_H_FRONT_PORCH, + SYNC_V1_H1, + HSTX_CMD_NOP, + HSTX_CMD_RAW_REPEAT | MODE_720_H_SYNC_WIDTH, + SYNC_V1_H0, + HSTX_CMD_NOP, + HSTX_CMD_RAW_REPEAT | MODE_720_H_BACK_PORCH, + SYNC_V1_H1, + HSTX_CMD_TMDS | MODE_720_H_ACTIVE_PIXELS }; picodvi_framebuffer_obj_t *active_picodvi = NULL; +// Incremented once per completed frame by the DMA frame-boundary IRQ, so refresh() can block +// until the next frame starts (vblank sync). A full-framebuffer repaint that begins right after a +// frame boundary then races ahead of scanout, avoiding tearing without a second framebuffer. +static volatile uint32_t framebuffer_frame_count = 0; + static void __not_in_flash_func(dma_irq_handler)(void) { if (active_picodvi == NULL) { return; } uint ch_num = active_picodvi->dma_pixel_channel; - dma_channel_hw_t *ch = &dma_hw->ch[ch_num]; dma_hw->intr = 1u << ch_num; // Set the read_addr back to the start and trigger the first transfer (which // will trigger the pixel channel). - ch = &dma_hw->ch[active_picodvi->dma_command_channel]; + dma_channel_hw_t *ch = &dma_hw->ch[active_picodvi->dma_command_channel]; ch->al3_read_addr_trig = (uintptr_t)active_picodvi->dma_commands; + framebuffer_frame_count++; // frame boundary: scanout has wrapped back to the top +} + +bool common_hal_picodvi_framebuffer_preflight( + mp_uint_t width, mp_uint_t height, + mp_uint_t color_depth) { + + // These modes don't duplicate pixels so we can do sub-byte colors. They + // take too much ram for more than 8bit color though. + bool full_resolution = color_depth == 1 || color_depth == 2 || color_depth == 4 || color_depth == 8; + // These modes rely on the memory transfer to duplicate values across bytes. + bool doubled = color_depth == 8 || color_depth == 16 || color_depth == 32; + + // for each supported resolution, check the color depth is supported + if (width == 640 && height == 480) { + return full_resolution; + } + if (width == 320 && height == 240) { + return doubled; + } + if (width == 160 && height == 120) { + return doubled; + } + + if (width == 720 && height == 400) { + return full_resolution; + } + + if (width == 360 && height == 200) { + return doubled; + } + + if (width == 180 && height == 100) { + return doubled; + } + return false; } void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, @@ -140,11 +226,19 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, mp_raise_msg_varg(&mp_type_RuntimeError, MP_ERROR_TEXT("%q in use"), MP_QSTR_picodvi); } - if (!(width == 640 && height == 480) && !(width == 320 && height == 240 && (color_depth == 16 || color_depth == 8))) { + if (!common_hal_picodvi_framebuffer_preflight(width, height, color_depth)) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q and %q"), MP_QSTR_width, MP_QSTR_height); } - bool pixel_doubled = width == 320 && height == 240; + self->dma_command_channel = -1; + self->dma_pixel_channel = -1; + + if (width % 160 == 0) { + self->output_width = 640; + } else { + self->output_width = 720; + } + size_t output_scaling = self->output_width / width; size_t all_allocated = 0; int8_t pins[8] = { @@ -173,68 +267,86 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, self->width = width; self->height = height; - self->pitch = (self->width * color_depth) / 8; self->color_depth = color_depth; - // Align each row to words. - if (self->pitch % sizeof(uint32_t) != 0) { - self->pitch += sizeof(uint32_t) - (self->pitch % sizeof(uint32_t)); - } - self->pitch /= sizeof(uint32_t); + // Pitch is number of 32-bit words per line. We round up pitch_bytes to the nearest word + // so that each scanline begins on a natural 32-bit word boundary. + size_t pitch_bytes = (self->width * color_depth) / 8; + self->pitch = (pitch_bytes + sizeof(uint32_t) - 1) / sizeof(uint32_t); size_t framebuffer_size = self->pitch * self->height; // We check that allocations aren't in PSRAM because we haven't added XIP // streaming support. self->framebuffer = (uint32_t *)port_malloc(framebuffer_size * sizeof(uint32_t), true); if (self->framebuffer == NULL || ((size_t)self->framebuffer & 0xf0000000) == 0x10000000) { + common_hal_picodvi_framebuffer_deinit(self); m_malloc_fail(framebuffer_size * sizeof(uint32_t)); return; } + memset(self->framebuffer, 0, framebuffer_size * sizeof(uint32_t)); // We compute all DMA transfers needed for a single frame. This ensure we don't have any super // quick interrupts that we need to respond to. Each transfer takes two words, trans_count and // read_addr. Active pixel lines need two transfers due to different read addresses. When pixel // doubling, then we must also set transfer size. size_t dma_command_size = 2; - if (pixel_doubled) { + if (output_scaling > 1) { dma_command_size = 4; } - self->dma_commands_len = (MODE_V_FRONT_PORCH + MODE_V_SYNC_WIDTH + MODE_V_BACK_PORCH + 2 * MODE_V_ACTIVE_LINES + 1) * dma_command_size; + + if (self->output_width == 640) { + self->dma_commands_len = (MODE_640_V_FRONT_PORCH + MODE_640_V_SYNC_WIDTH + MODE_640_V_BACK_PORCH + 2 * MODE_640_V_ACTIVE_LINES + 1) * dma_command_size; + } else { + self->dma_commands_len = (MODE_720_V_FRONT_PORCH + MODE_720_V_SYNC_WIDTH + MODE_720_V_BACK_PORCH + 2 * MODE_720_V_ACTIVE_LINES + 1) * dma_command_size; + } self->dma_commands = (uint32_t *)port_malloc(self->dma_commands_len * sizeof(uint32_t), true); - if (self->dma_commands == NULL || ((size_t)self->framebuffer & 0xf0000000) == 0x10000000) { - port_free(self->framebuffer); + if (self->dma_commands == NULL || ((size_t)self->dma_commands & 0xf0000000) == 0x10000000) { + common_hal_picodvi_framebuffer_deinit(self); m_malloc_fail(self->dma_commands_len * sizeof(uint32_t)); return; } - int dma_pixel_channel_maybe = dma_claim_unused_channel(false); - if (dma_pixel_channel_maybe < 0) { + // The command channel and the pixel channel form a pipeline that feeds combined HSTX + // commands and pixel data to the HSTX FIFO. The command channel reads a pre-computed + // list of control/status words from the dma_commands buffer and writes them to the + // pixel channel's control/status registers. Under control of the command channel, the + // pixel channel smears/swizzles pixel data from the framebuffer and combines + // it with HSTX commands, forwarding the combined stream to the HSTX FIFO. + + self->dma_pixel_channel = dma_claim_unused_channel(false); + self->dma_command_channel = dma_claim_unused_channel(false); + if (self->dma_pixel_channel < 0 || self->dma_command_channel < 0) { + common_hal_picodvi_framebuffer_deinit(self); mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use")); return; } - int dma_command_channel_maybe = dma_claim_unused_channel(false); - if (dma_command_channel_maybe < 0) { - dma_channel_unclaim((uint)dma_pixel_channel_maybe); - mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use")); - return; + size_t command_word = 0; + size_t frontporch_start; + if (self->output_width == 640) { + frontporch_start = MODE_640_V_TOTAL_LINES - MODE_640_V_FRONT_PORCH; + } else { + frontporch_start = MODE_720_V_TOTAL_LINES - MODE_720_V_FRONT_PORCH; } - self->dma_pixel_channel = dma_pixel_channel_maybe; - self->dma_command_channel = dma_command_channel_maybe; - - size_t words_per_line; - if (self->color_depth > 8) { - words_per_line = (self->width * (self->color_depth / 8)) / sizeof(uint32_t); + size_t frontporch_end = frontporch_start; + if (self->output_width == 640) { + frontporch_end += MODE_640_V_FRONT_PORCH; } else { - words_per_line = (self->width / (8 / self->color_depth)) / sizeof(uint32_t); + frontporch_end += MODE_720_V_FRONT_PORCH; } - - size_t command_word = 0; - size_t frontporch_start = MODE_V_TOTAL_LINES - MODE_V_FRONT_PORCH; - size_t frontporch_end = frontporch_start + MODE_V_FRONT_PORCH; size_t vsync_start = 0; - size_t vsync_end = vsync_start + MODE_V_SYNC_WIDTH; + size_t vsync_end = vsync_start; + if (self->output_width == 640) { + vsync_end += MODE_640_V_SYNC_WIDTH; + } else { + vsync_end += MODE_720_V_SYNC_WIDTH; + } size_t backporch_start = vsync_end; - size_t backporch_end = backporch_start + MODE_V_BACK_PORCH; + size_t backporch_end = backporch_start; + if (self->output_width == 640) { + backporch_end += MODE_640_V_BACK_PORCH; + } else { + backporch_end += MODE_720_V_BACK_PORCH; + } size_t active_start = backporch_end; uint32_t dma_ctrl = self->dma_command_channel << DMA_CH0_CTRL_TRIG_CHAIN_TO_LSB | @@ -243,10 +355,12 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, DMA_CH0_CTRL_TRIG_INCR_READ_BITS | DMA_CH0_CTRL_TRIG_EN_BITS; uint32_t dma_pixel_ctrl; - if (pixel_doubled) { + if (output_scaling > 1) { // We do color_depth size transfers when pixel doubling. The memory bus will - // duplicate the 16 bits to produce 32 bits for the HSTX. - if (color_depth == 16) { + // duplicate the bytes read to produce 32 bits for the HSTX. + if (color_depth == 32) { + dma_pixel_ctrl = dma_ctrl | DMA_SIZE_32 << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB; + } else if (color_depth == 16) { dma_pixel_ctrl = dma_ctrl | DMA_SIZE_16 << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB; } else { dma_pixel_ctrl = dma_ctrl | DMA_SIZE_8 << DMA_CH0_CTRL_TRIG_DATA_SIZE_LSB; @@ -263,34 +377,46 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, // Write ctrl and write_addr once when not pixel doubling because they don't // change. (write_addr doesn't change when pixel doubling either but we need // to rewrite it because it is after the ctrl register.) - if (!pixel_doubled) { + if (output_scaling == 1) { dma_channel_hw_addr(self->dma_pixel_channel)->al1_ctrl = dma_ctrl; dma_channel_hw_addr(self->dma_pixel_channel)->al1_write_addr = dma_write_addr; } - for (size_t v_scanline = 0; v_scanline < MODE_V_TOTAL_LINES; v_scanline++) { - if (pixel_doubled) { + + uint32_t *vblank_line_vsync_on = self->output_width == 640 ? vblank_line640_vsync_on : vblank_line720_vsync_on; + uint32_t *vblank_line_vsync_off = self->output_width == 640 ? vblank_line640_vsync_off : vblank_line720_vsync_off; + uint32_t *vactive_line = self->output_width == 640 ? vactive_line640 : vactive_line720; + + size_t mode_v_total_lines; + if (self->output_width == 640) { + mode_v_total_lines = MODE_640_V_TOTAL_LINES; + } else { + mode_v_total_lines = MODE_720_V_TOTAL_LINES; + } + + for (size_t v_scanline = 0; v_scanline < mode_v_total_lines; v_scanline++) { + if (output_scaling > 1) { self->dma_commands[command_word++] = dma_ctrl; self->dma_commands[command_word++] = dma_write_addr; } if (vsync_start <= v_scanline && v_scanline < vsync_end) { - self->dma_commands[command_word++] = count_of(vblank_line_vsync_on); + self->dma_commands[command_word++] = VSYNC_LEN; self->dma_commands[command_word++] = (uintptr_t)vblank_line_vsync_on; } else if (backporch_start <= v_scanline && v_scanline < backporch_end) { - self->dma_commands[command_word++] = count_of(vblank_line_vsync_off); + self->dma_commands[command_word++] = VSYNC_LEN; self->dma_commands[command_word++] = (uintptr_t)vblank_line_vsync_off; } else if (frontporch_start <= v_scanline && v_scanline < frontporch_end) { - self->dma_commands[command_word++] = count_of(vblank_line_vsync_off); + self->dma_commands[command_word++] = VSYNC_LEN; self->dma_commands[command_word++] = (uintptr_t)vblank_line_vsync_off; } else { - self->dma_commands[command_word++] = count_of(vactive_line); + self->dma_commands[command_word++] = VACTIVE_LEN; self->dma_commands[command_word++] = (uintptr_t)vactive_line; size_t row = v_scanline - active_start; - size_t transfer_count = words_per_line; - if (pixel_doubled) { + size_t transfer_count = self->pitch; + if (output_scaling > 1) { self->dma_commands[command_word++] = dma_pixel_ctrl; self->dma_commands[command_word++] = dma_write_addr; - row /= 2; - // When pixel doubling, we do one transfer per pixel and it gets + row /= output_scaling; + // When pixel scaling, we do one transfer per pixel and it gets // mirrored into the rest of the word. transfer_count = self->width; } @@ -300,7 +426,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, } } // Last command is NULL which will trigger an IRQ. - if (pixel_doubled) { + if (output_scaling > 1) { self->dma_commands[command_word++] = DMA_CH0_CTRL_TRIG_IRQ_QUIET_BITS | DMA_CH0_CTRL_TRIG_EN_BITS; self->dma_commands[command_word++] = 0; @@ -308,7 +434,16 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, self->dma_commands[command_word++] = 0; self->dma_commands[command_word++] = 0; - if (color_depth == 16) { + if (color_depth == 32) { + // Configure HSTX's TMDS encoder for RGB888 + hstx_ctrl_hw->expand_tmds = + 7 << HSTX_CTRL_EXPAND_TMDS_L2_NBITS_LSB | + 16 << HSTX_CTRL_EXPAND_TMDS_L2_ROT_LSB | + 7 << HSTX_CTRL_EXPAND_TMDS_L1_NBITS_LSB | + 8 << HSTX_CTRL_EXPAND_TMDS_L1_ROT_LSB | + 7 << HSTX_CTRL_EXPAND_TMDS_L0_NBITS_LSB | + 0 << HSTX_CTRL_EXPAND_TMDS_L0_ROT_LSB; + } else if (color_depth == 16) { // Configure HSTX's TMDS encoder for RGB565 hstx_ctrl_hw->expand_tmds = 4 << HSTX_CTRL_EXPAND_TMDS_L2_NBITS_LSB | @@ -346,18 +481,25 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, (color_depth - 1) << HSTX_CTRL_EXPAND_TMDS_L0_NBITS_LSB | rot << HSTX_CTRL_EXPAND_TMDS_L0_ROT_LSB; } - size_t shifts_before_empty = ((32 / color_depth) % 32); - if (pixel_doubled && color_depth == 8) { - // All but 320x240 at 8bits will shift through all 32 bits. We are only - // doubling so we only need 16 bits (2 x 8) to get our doubled pixel. - shifts_before_empty = 2; + size_t pixels_per_word; + if (output_scaling == 1) { + pixels_per_word = 32 / color_depth; + } else { + pixels_per_word = 1; + } + + size_t shifts_before_empty = (pixels_per_word % 32); + if (output_scaling > 1) { + shifts_before_empty *= output_scaling; } + size_t shift_amount = color_depth % 32; + // Pixels come in 32 bits at a time. color_depth dictates the number // of pixels per word. Control symbols (RAW) are an entire 32-bit word. hstx_ctrl_hw->expand_shift = shifts_before_empty << HSTX_CTRL_EXPAND_SHIFT_ENC_N_SHIFTS_LSB | - color_depth << HSTX_CTRL_EXPAND_SHIFT_ENC_SHIFT_LSB | + shift_amount << HSTX_CTRL_EXPAND_SHIFT_ENC_SHIFT_LSB | 1 << HSTX_CTRL_EXPAND_SHIFT_RAW_N_SHIFTS_LSB | 0 << HSTX_CTRL_EXPAND_SHIFT_RAW_SHIFT_LSB; @@ -410,7 +552,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, // This wraps the transfer back to the start of the write address. size_t wrap = 3; // 8 bytes because we write two DMA registers. volatile uint32_t *write_addr = &dma_hw->ch[self->dma_pixel_channel].al3_transfer_count; - if (pixel_doubled) { + if (output_scaling > 1) { wrap = 4; // 16 bytes because we write all four DMA registers. write_addr = &dma_hw->ch[self->dma_pixel_channel].al3_ctrl; } @@ -430,6 +572,7 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, dma_hw->inte1 = (1u << self->dma_pixel_channel); irq_set_exclusive_handler(DMA_IRQ_1, dma_irq_handler); irq_set_enabled(DMA_IRQ_1, true); + irq_set_priority(DMA_IRQ_1, PICO_HIGHEST_IRQ_PRIORITY); bus_ctrl_hw->priority = BUSCTRL_BUS_PRIORITY_DMA_W_BITS | BUSCTRL_BUS_PRIORITY_DMA_R_BITS; @@ -442,7 +585,10 @@ void common_hal_picodvi_framebuffer_construct(picodvi_framebuffer_obj_t *self, dma_irq_handler(); } -static void _turn_off_dma(uint8_t channel) { +static void _turn_off_dma(int channel) { + if (channel < 0) { + return; + } dma_channel_config c = dma_channel_get_default_config(channel); channel_config_set_enable(&c, false); dma_channel_set_config(channel, &c, false /* trigger */); @@ -465,6 +611,8 @@ void common_hal_picodvi_framebuffer_deinit(picodvi_framebuffer_obj_t *self) { _turn_off_dma(self->dma_pixel_channel); _turn_off_dma(self->dma_command_channel); + self->dma_pixel_channel = -1; + self->dma_command_channel = -1; active_picodvi = NULL; @@ -484,6 +632,23 @@ bool common_hal_picodvi_framebuffer_deinited(picodvi_framebuffer_obj_t *self) { void common_hal_picodvi_framebuffer_refresh(picodvi_framebuffer_obj_t *self) { } +void common_hal_picodvi_framebuffer_wait_for_vblank(picodvi_framebuffer_obj_t *self) { + // Block until the next frame boundary (vblank). A full-framebuffer repaint issued right after + // this returns starts at the top of scanout and stays ahead of the beam, so it does not tear + // mid-screen. Bounded by a timeout so a stopped or absent DVI signal can never hang the caller. + if (self != active_picodvi) { + return; + } + uint32_t start = framebuffer_frame_count; + uint64_t timeout = common_hal_time_monotonic_ms() + 30; // ~2 frames @ 60 Hz + while (framebuffer_frame_count == start) { + RUN_BACKGROUND_TASKS; // don't starve USB host / other tasks during the ~<16 ms wait + if (common_hal_time_monotonic_ms() >= timeout) { + break; + } + } +} + int common_hal_picodvi_framebuffer_get_width(picodvi_framebuffer_obj_t *self) { return self->width; } @@ -496,6 +661,10 @@ int common_hal_picodvi_framebuffer_get_color_depth(picodvi_framebuffer_obj_t *se return self->color_depth; } +int common_hal_picodvi_framebuffer_get_native_frames_per_second(picodvi_framebuffer_obj_t *self) { + return self->output_width == 640 ? 60 : 70; +} + bool common_hal_picodvi_framebuffer_get_grayscale(picodvi_framebuffer_obj_t *self) { return self->color_depth < 4; } @@ -503,7 +672,13 @@ bool common_hal_picodvi_framebuffer_get_grayscale(picodvi_framebuffer_obj_t *sel mp_int_t common_hal_picodvi_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) { picodvi_framebuffer_obj_t *self = (picodvi_framebuffer_obj_t *)self_in; bufinfo->buf = self->framebuffer; - bufinfo->typecode = self->color_depth > 8 ? 'H' : 'B'; + if (self->color_depth == 32) { + bufinfo->typecode = 'I'; + } else if (self->color_depth == 16) { + bufinfo->typecode = 'H'; + } else { + bufinfo->typecode = 'B'; + } bufinfo->len = self->framebuffer_len * sizeof(uint32_t); return 0; } diff --git a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.h b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.h index abb75dc2782..fa08bc77d93 100644 --- a/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.h +++ b/ports/raspberrypi/common-hal/picodvi/Framebuffer_RP2350.h @@ -36,8 +36,9 @@ typedef struct { size_t dma_commands_len; // in words mp_uint_t width; mp_uint_t height; + mp_uint_t output_width; uint16_t pitch; // Number of words between rows. (May be more than a width's worth.) uint8_t color_depth; - uint8_t dma_pixel_channel; - uint8_t dma_command_channel; + int dma_pixel_channel; + int dma_command_channel; } picodvi_framebuffer_obj_t; diff --git a/ports/raspberrypi/common-hal/picodvi/__init__.c b/ports/raspberrypi/common-hal/picodvi/__init__.c new file mode 100644 index 00000000000..c2d4b297b39 --- /dev/null +++ b/ports/raspberrypi/common-hal/picodvi/__init__.c @@ -0,0 +1,169 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "common-hal/picodvi/__init__.h" +#include "common-hal/picodvi/Framebuffer.h" +#include "bindings/picodvi/Framebuffer.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/board/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/safe_mode.h" +#include "supervisor/shared/settings.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "supervisor/port_heap.h" + +#if defined(DEFAULT_DVI_BUS_CLK_DP) +static bool picodvi_autoconstruct_enabled(mp_int_t *default_width, mp_int_t *default_height) { + char buf[sizeof("detect")]; + buf[0] = 0; + + // (any failure leaves the content of buf untouched: an empty nul-terminated string + (void)settings_get_str("CIRCUITPY_PICODVI_ENABLE", buf, sizeof(buf)); + + if (!strcasecmp(buf, "never")) { + return false; + } + if (!strcasecmp(buf, "always")) { + return true; + } + + // It's "detect" or else an invalid value which is treated the same as "detect". + + // check if address 0x50 is live on the I2C bus + busio_i2c_obj_t *i2c = common_hal_board_create_i2c(0); + if (!i2c) { + return false; + } + if (!common_hal_busio_i2c_try_lock(i2c)) { + return false; + } + bool probed = common_hal_busio_i2c_probe(i2c, 0x50); + if (probed) { + uint8_t edid[128]; + uint8_t out[1] = {0}; + common_hal_busio_i2c_write_read(i2c, 0x50, out, 1, edid, sizeof(edid)); + bool edid_ok = true; + if (edid[0] != 0x00 || edid[1] != 0xFF || edid[2] != 0xFF || edid[3] != 0xFF || edid[4] != 0xFF || edid[5] != 0xFF || edid[6] != 0xFF || edid[7] != 0x00) { + edid_ok = false; + } + uint8_t checksum = 0; + for (size_t i = 0; i < sizeof(edid); i++) { + checksum += edid[i]; + } + if (checksum != 0) { + edid_ok = false; + } + + if (edid_ok) { + uint8_t established_timings = edid[35]; + if ((established_timings & 0xa0) == 0) { + // Check that 720x400@70Hz or 640x480@60Hz is supported. If not + // and we read EDID ok, then don't autostart. + probed = false; + } else { + size_t offset = 54; + uint16_t preferred_pixel_clock = edid[offset] | (edid[offset + 1] << 8); + if (preferred_pixel_clock != 0) { + size_t preferred_width = ((edid[offset + 4] & 0xf0) << 4) | edid[offset + 2]; + size_t preferred_height = ((edid[offset + 7] & 0xf0) << 4) | edid[offset + 5]; + // Use 720x400 on 1080p, 4k and 8k displays. + if ((established_timings & 0x80) != 0 && + preferred_width % 1920 == 0 && + preferred_height % 1080 == 0) { + *default_width = 720; + *default_height = 400; + } else { + *default_width = 640; + *default_height = 480; + } + } + } + } + } + common_hal_busio_i2c_unlock(i2c); + return probed; +} + +// For picodvi_autoconstruct to work, the 8 DVI/HSTX pin names must be defined, AND +// i2c bus 0 must also be connected to DVI with on-board pull ups +void picodvi_autoconstruct(void) { + if (get_safe_mode() != SAFE_MODE_NONE) { + return; + } + + mp_int_t default_width = 640; + mp_int_t default_height = 480; + if (!picodvi_autoconstruct_enabled(&default_width, &default_height)) { + return; + } + + mp_int_t width = default_width; + mp_int_t height = 0; + mp_int_t color_depth = 8; + mp_int_t rotation = 0; + + (void)settings_get_int("CIRCUITPY_DISPLAY_WIDTH", &width); + (void)settings_get_int("CIRCUITPY_DISPLAY_HEIGHT", &height); + (void)settings_get_int("CIRCUITPY_DISPLAY_COLOR_DEPTH", &color_depth); + (void)settings_get_int("CIRCUITPY_DISPLAY_ROTATION", &rotation); + + if (height == 0) { + switch (width) { + case 720: + height = 400; + break; + case 640: + height = 480; + break; + case 320: + height = 240; + break; + case 360: + height = 200; + break; + } + } + + if (rotation != 0 && rotation != 90 && rotation != 180 && rotation != 270) { + // invalid rotation + rotation = 0; + } + + if (!common_hal_picodvi_framebuffer_preflight(width, height, color_depth)) { + // invalid configuration, set back to default + width = default_width; + height = default_height; + color_depth = 8; + } + + // construct framebuffer and display + picodvi_framebuffer_obj_t *fb = &allocate_display_bus_or_raise()->picodvi; + fb->base.type = &picodvi_framebuffer_type; + common_hal_picodvi_framebuffer_construct(fb, + width, height, + DEFAULT_DVI_BUS_CLK_DP, + DEFAULT_DVI_BUS_CLK_DN, + DEFAULT_DVI_BUS_RED_DP, + DEFAULT_DVI_BUS_RED_DN, + DEFAULT_DVI_BUS_GREEN_DP, + DEFAULT_DVI_BUS_GREEN_DN, + DEFAULT_DVI_BUS_BLUE_DP, + DEFAULT_DVI_BUS_BLUE_DN, + color_depth); + + framebufferio_framebufferdisplay_obj_t *display = &allocate_display()->framebuffer_display; + display->base.type = &framebufferio_framebufferdisplay_type; + common_hal_framebufferio_framebufferdisplay_construct( + display, + MP_OBJ_FROM_PTR(fb), + rotation, + true); +} +#else +void picodvi_autoconstruct(void) { +} +#endif diff --git a/ports/raspberrypi/common-hal/picodvi/__init__.h b/ports/raspberrypi/common-hal/picodvi/__init__.h new file mode 100644 index 00000000000..41f3656339a --- /dev/null +++ b/ports/raspberrypi/common-hal/picodvi/__init__.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +extern void picodvi_autoconstruct(void); diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.c b/ports/raspberrypi/common-hal/pulseio/PulseIn.c index a3b8a06f4ab..a2bfeec6c6a 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.c @@ -4,7 +4,7 @@ // // SPDX-License-Identifier: MIT -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" +#include "hardware/gpio.h" #include @@ -26,7 +26,7 @@ static const uint16_t pulsein_program[] = { void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu_pin_obj_t *pin, uint16_t maxlen, bool idle_state) { - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); + self->buffer = (uint16_t *)m_malloc_without_collect(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { m_malloc_fail(maxlen * sizeof(uint16_t)); } @@ -41,13 +41,13 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, 1000000, // frequency NULL, 0, // init, init_len NULL, 0, // may_exec - NULL, 0, 0, 0, // first out pin, # out pins, initial_out_pin_state - pin, 1, 0, 0, // first in pin, # in pins - NULL, 0, 0, 0, // first set pin - NULL, 0, 0, 0, // first sideset pin + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // first out pin, # out pins, initial_out_pin_state + pin, 1, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // first in pin, # in pins + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // first set pin + NULL, 0, false, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // first sideset pin false, // No sideset enable NULL, PULL_NONE, // jump pin, jmp_pull - 0, // wait gpio pins + PIO_PINMASK_NONE, // wait gpio pins true, // exclusive pin usage false, 8, false, // TX, setting we don't use false, // wait for TX stall diff --git a/ports/raspberrypi/common-hal/pulseio/PulseIn.h b/ports/raspberrypi/common-hal/pulseio/PulseIn.h index cca1dedfabc..369d7b8f450 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseIn.h +++ b/ports/raspberrypi/common-hal/pulseio/PulseIn.h @@ -7,7 +7,7 @@ #pragma once #include "common-hal/microcontroller/Pin.h" -#include "src/rp2_common/hardware_pio/include/hardware/pio.h" +#include "hardware/pio.h" #include "common-hal/rp2pio/StateMachine.h" #include "py/obj.h" diff --git a/ports/raspberrypi/common-hal/pulseio/PulseOut.c b/ports/raspberrypi/common-hal/pulseio/PulseOut.c index 114bff13979..84d02e20cce 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseOut.c +++ b/ports/raspberrypi/common-hal/pulseio/PulseOut.c @@ -14,9 +14,9 @@ #include "shared-bindings/microcontroller/__init__.h" #include "common-hal/pwmio/PWMOut.h" #include "hardware/structs/pwm.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" -#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" -#include "src/common/pico_time/include/pico/time.h" +#include "hardware/gpio.h" +#include "hardware/pwm.h" +#include "pico/time.h" volatile alarm_id_t cur_alarm = 0; diff --git a/ports/raspberrypi/common-hal/pulseio/PulseOut.h b/ports/raspberrypi/common-hal/pulseio/PulseOut.h index fa264c36b7f..cff82f2c28c 100644 --- a/ports/raspberrypi/common-hal/pulseio/PulseOut.h +++ b/ports/raspberrypi/common-hal/pulseio/PulseOut.h @@ -8,7 +8,7 @@ #include "common-hal/microcontroller/Pin.h" #include "common-hal/pwmio/PWMOut.h" -#include "src/common/pico_time/include/pico/time.h" +#include "pico/time.h" #include "py/obj.h" diff --git a/ports/raspberrypi/common-hal/pwmio/PWMOut.c b/ports/raspberrypi/common-hal/pwmio/PWMOut.c index e0572eccd9e..2a643974291 100644 --- a/ports/raspberrypi/common-hal/pwmio/PWMOut.c +++ b/ports/raspberrypi/common-hal/pwmio/PWMOut.c @@ -12,10 +12,10 @@ #include "shared-bindings/pwmio/PWMOut.h" #include "shared-bindings/microcontroller/Processor.h" -#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h" -#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" -#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" +#include "hardware/platform_defs.h" +#include "hardware/clocks.h" +#include "hardware/gpio.h" +#include "hardware/pwm.h" uint32_t target_slice_frequencies[NUM_PWM_SLICES]; uint32_t slice_variable_frequency; @@ -78,7 +78,7 @@ pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t ab_channel, bool variable if (target_slice_frequencies[slice] > 0) { // If we want to change frequency then we can't share. if (variable_frequency) { - return PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE; + return PWMOUT_INTERNAL_RESOURCES_IN_USE; } // If the other user wants a variable frequency then we can't share either. if ((slice_variable_frequency & (1 << slice)) != 0) { @@ -86,7 +86,7 @@ pwmout_result_t pwmout_allocate(uint8_t slice, uint8_t ab_channel, bool variable } // If we're both fixed frequency but we don't match target frequencies then we can't share. if (target_slice_frequencies[slice] != frequency) { - return PWMOUT_INVALID_FREQUENCY_ON_PIN; + return PWMOUT_INTERNAL_RESOURCES_IN_USE; } } diff --git a/ports/raspberrypi/common-hal/rgbmatrix/RGBMatrix.c b/ports/raspberrypi/common-hal/rgbmatrix/RGBMatrix.c index 029e2b2755e..875da343251 100644 --- a/ports/raspberrypi/common-hal/rgbmatrix/RGBMatrix.c +++ b/ports/raspberrypi/common-hal/rgbmatrix/RGBMatrix.c @@ -12,8 +12,8 @@ #include "shared-bindings/pwmio/PWMOut.h" #include "shared-module/rgbmatrix/RGBMatrix.h" -#include "src/rp2_common/hardware_pwm/include/hardware/pwm.h" -#include "src/rp2_common/hardware_irq/include/hardware/irq.h" +#include "hardware/pwm.h" +#include "hardware/irq.h" void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) { // Choose a PWM channel based on the first RGB pin diff --git a/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c b/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c index b5af0474be7..d71ff60b2eb 100644 --- a/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c +++ b/ports/raspberrypi/common-hal/rotaryio/IncrementalEncoder.c @@ -43,6 +43,9 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { const mcu_pin_obj_t *pins[] = { pin_a, pin_b }; + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + // Start out with swapped to match behavior with other ports. self->swapped = true; if (!common_hal_rp2pio_pins_are_sequential(2, pins)) { @@ -62,14 +65,14 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode 1000000, encoder_init, MP_ARRAY_SIZE(encoder_init), // init NULL, 0, // may_exec - NULL, 0, 0, 0, // out pin + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_NONE, // out pin pins[0], 2, // in pins - 3, 0, // in pulls - NULL, 0, 0, 0x1f, // set pins - NULL, 0, 0, 0x1f, // sideset pins + PIO_PINMASK32_FROM_VALUE(3), PIO_PINMASK32_NONE, // in pulls + NULL, 0, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // set pins + NULL, 0, false, PIO_PINMASK32_NONE, PIO_PINMASK32_FROM_VALUE(0x1f), // sideset pins false, // No sideset enable NULL, PULL_NONE, // jump pin - 0, // wait gpio pins + PIO_PINMASK_NONE, // wait gpio pins true, // exclusive pin use false, 32, false, // out settings false, // Wait for txstall @@ -89,6 +92,7 @@ void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencode } bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self) { + // Use the deinit state of the PIO state machine. return common_hal_rp2pio_statemachine_deinited(&self->state_machine); } @@ -100,6 +104,11 @@ void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_o common_hal_rp2pio_statemachine_deinit(&self->state_machine); } +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { + // Use the deinit state of the PIO state machine. + common_hal_rp2pio_statemachine_mark_deinit(&self->state_machine); +} + static void incrementalencoder_interrupt_handler(void *self_in) { rotaryio_incrementalencoder_obj_t *self = self_in; diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index bffc9400b34..2f815cd2ee0 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -14,12 +14,12 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/memorymap/AddressRange.h" -#include "src/rp2040/hardware_regs/include/hardware/platform_defs.h" -#include "src/rp2_common/hardware_clocks/include/hardware/clocks.h" -#include "src/rp2_common/hardware_dma/include/hardware/dma.h" -#include "src/rp2_common/hardware_pio/include/hardware/pio_instructions.h" -#include "src/rp2040/hardware_structs/include/hardware/structs/iobank0.h" -#include "src/rp2_common/hardware_irq/include/hardware/irq.h" +#include "hardware/platform_defs.h" +#include "hardware/structs/iobank0.h" +#include "hardware/clocks.h" +#include "hardware/dma.h" +#include "hardware/pio_instructions.h" +#include "hardware/irq.h" #include "shared/runtime/interrupt_char.h" #include "py/obj.h" @@ -35,57 +35,124 @@ static uint8_t _current_program_offset[NUM_PIOS][NUM_PIO_STATE_MACHINES]; static uint8_t _current_program_len[NUM_PIOS][NUM_PIO_STATE_MACHINES]; static bool _never_reset[NUM_PIOS][NUM_PIO_STATE_MACHINES]; -static uint32_t _current_pins[NUM_PIOS]; -static uint32_t _current_sm_pins[NUM_PIOS][NUM_PIO_STATE_MACHINES]; -static int8_t _sm_dma_plus_one[NUM_PIOS][NUM_PIO_STATE_MACHINES]; +static pio_pinmask_t _current_pins[NUM_PIOS]; +static pio_pinmask_t _current_sm_pins[NUM_PIOS][NUM_PIO_STATE_MACHINES]; -#define SM_DMA_ALLOCATED(pio_index, sm) (_sm_dma_plus_one[(pio_index)][(sm)] != 0) -#define SM_DMA_GET_CHANNEL(pio_index, sm) (_sm_dma_plus_one[(pio_index)][(sm)] - 1) -#define SM_DMA_CLEAR_CHANNEL(pio_index, sm) (_sm_dma_plus_one[(pio_index)][(sm)] = 0) -#define SM_DMA_SET_CHANNEL(pio_index, sm, channel) (_sm_dma_plus_one[(pio_index)][(sm)] = (channel) + 1) +static int8_t _sm_dma_plus_one_write[NUM_PIOS][NUM_PIO_STATE_MACHINES]; +static int8_t _sm_dma_plus_one_read[NUM_PIOS][NUM_PIO_STATE_MACHINES]; + +#define SM_DMA_ALLOCATED_WRITE(pio_index, sm) (_sm_dma_plus_one_write[(pio_index)][(sm)] != 0) +#define SM_DMA_GET_CHANNEL_WRITE(pio_index, sm) (_sm_dma_plus_one_write[(pio_index)][(sm)] - 1) +#define SM_DMA_CLEAR_CHANNEL_WRITE(pio_index, sm) (_sm_dma_plus_one_write[(pio_index)][(sm)] = 0) +#define SM_DMA_SET_CHANNEL_WRITE(pio_index, sm, channel) (_sm_dma_plus_one_write[(pio_index)][(sm)] = (channel) + 1) + +#define SM_DMA_ALLOCATED_READ(pio_index, sm) (_sm_dma_plus_one_read[(pio_index)][(sm)] != 0) +#define SM_DMA_GET_CHANNEL_READ(pio_index, sm) (_sm_dma_plus_one_read[(pio_index)][(sm)] - 1) +#define SM_DMA_CLEAR_CHANNEL_READ(pio_index, sm) (_sm_dma_plus_one_read[(pio_index)][(sm)] = 0) +#define SM_DMA_SET_CHANNEL_READ(pio_index, sm, channel) (_sm_dma_plus_one_read[(pio_index)][(sm)] = (channel) + 1) -static PIO pio_instances[NUM_PIOS] = { - pio0, - pio1 - #if NUM_PIOS == 3 - , pio2 - #endif -}; typedef void (*interrupt_handler_type)(void *); static interrupt_handler_type _interrupt_handler[NUM_PIOS][NUM_PIO_STATE_MACHINES]; static void *_interrupt_arg[NUM_PIOS][NUM_PIO_STATE_MACHINES]; static void rp2pio_statemachine_interrupt_handler(void); -static void rp2pio_statemachine_set_pull(uint32_t pull_pin_up, uint32_t pull_pin_down, uint32_t pins_we_use) { +static void rp2pio_statemachine_set_pull(pio_pinmask_t pull_pin_up, pio_pinmask_t pull_pin_down, pio_pinmask_t pins_we_use) { for (size_t i = 0; i < NUM_BANK0_GPIOS; i++) { - bool used = pins_we_use & (1 << i); + bool used = PIO_PINMASK_IS_SET(pins_we_use, i); if (used) { - bool pull_up = pull_pin_up & (1 << i); - bool pull_down = pull_pin_down & (1 << i); + bool pull_up = PIO_PINMASK_IS_SET(pull_pin_up, i); + bool pull_down = PIO_PINMASK_IS_SET(pull_pin_down, i); gpio_set_pulls(i, pull_up, pull_down); } } } -static void rp2pio_statemachine_clear_dma(int pio_index, int sm) { - if (SM_DMA_ALLOCATED(pio_index, sm)) { - int channel = SM_DMA_GET_CHANNEL(pio_index, sm); - uint32_t channel_mask = 1u << channel; - dma_hw->inte0 &= ~channel_mask; - if (!dma_hw->inte0) { - irq_set_mask_enabled(1 << DMA_IRQ_0, false); +// audio_dma and rp2pio cooperate on DMA_IRQ_0 using the SDK's shared interrupt +// handlers. We add our handler when we enable our first channel and remove it +// when our last channel is disabled. See the DMA IRQ allocation notes in +// common-hal/microcontroller/__init__.c. + +// Shared DMA_IRQ_0 handler for rp2pio background reads and writes. It +// acknowledges and services only its own channels, leaving any other channels' +// interrupts (e.g. audio) for the other shared handlers to acknowledge. +static void __not_in_flash_func(rp2pio_dma_irq_handler)(void) { + for (size_t i = 0; i < NUM_DMA_CHANNELS; i++) { + uint32_t mask = 1 << i; + if ((dma_hw->ints0 & mask) == 0) { + continue; + } + rp2pio_statemachine_obj_t *read = MP_STATE_PORT(background_pio_read)[i]; + rp2pio_statemachine_obj_t *write = MP_STATE_PORT(background_pio_write)[i]; + if (read == NULL && write == NULL) { + // Not one of our channels; leave it for another shared handler. + continue; + } + // Acknowledge the interrupt early; see the comment in audio_dma.c. + dma_hw->ints0 = mask; + if (read != NULL) { + rp2pio_statemachine_dma_complete_read(read, i); + } + if (write != NULL) { + rp2pio_statemachine_dma_complete_write(write, i); } - MP_STATE_PORT(background_pio)[channel] = NULL; - dma_channel_abort(channel); - dma_channel_unclaim(channel); } - SM_DMA_CLEAR_CHANNEL(pio_index, sm); +} + +// Channels (bitmask) rp2pio currently has enabled on DMA_IRQ_0. Used to decide +// when to add/remove our shared interrupt handler. +static uint32_t rp2pio_dma_irq0_channel_mask = 0; + +static void rp2pio_dma_enable_irq(uint channel) { + // Clear any latent interrupt so that we don't immediately re-trigger. + dma_hw->ints0 = 1u << channel; + if (rp2pio_dma_irq0_channel_mask == 0) { + irq_add_shared_handler(DMA_IRQ_0, rp2pio_dma_irq_handler, + PICO_SHARED_IRQ_HANDLER_DEFAULT_ORDER_PRIORITY); + } + rp2pio_dma_irq0_channel_mask |= 1u << channel; + dma_irqn_set_channel_enabled(0, channel, true); + irq_set_enabled(DMA_IRQ_0, true); +} + +static void rp2pio_dma_disable_irq(uint channel) { + dma_irqn_set_channel_enabled(0, channel, false); + rp2pio_dma_irq0_channel_mask &= ~(1u << channel); + if (rp2pio_dma_irq0_channel_mask == 0) { + irq_remove_handler(DMA_IRQ_0, rp2pio_dma_irq_handler); + } + // Turn off the IRQ line entirely once no one (audio or rp2pio) needs it. + if (dma_hw->inte0 == 0) { + irq_set_enabled(DMA_IRQ_0, false); + } +} + +static void rp2pio_statemachine_clear_dma_write(int pio_index, int sm) { + if (SM_DMA_ALLOCATED_WRITE(pio_index, sm)) { + int channel_write = SM_DMA_GET_CHANNEL_WRITE(pio_index, sm); + rp2pio_dma_disable_irq(channel_write); + MP_STATE_PORT(background_pio_write)[channel_write] = NULL; + dma_channel_abort(channel_write); + dma_channel_unclaim(channel_write); + } + SM_DMA_CLEAR_CHANNEL_WRITE(pio_index, sm); +} + +static void rp2pio_statemachine_clear_dma_read(int pio_index, int sm) { + if (SM_DMA_ALLOCATED_READ(pio_index, sm)) { + int channel_read = SM_DMA_GET_CHANNEL_READ(pio_index, sm); + rp2pio_dma_disable_irq(channel_read); + MP_STATE_PORT(background_pio_read)[channel_read] = NULL; + dma_channel_abort(channel_read); + dma_channel_unclaim(channel_read); + } + SM_DMA_CLEAR_CHANNEL_READ(pio_index, sm); } static void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) { uint8_t pio_index = pio_get_index(pio); - rp2pio_statemachine_clear_dma(pio_index, sm); + rp2pio_statemachine_clear_dma_write(pio_index, sm); + rp2pio_statemachine_clear_dma_read(pio_index, sm); uint32_t program_id = _current_program_id[pio_index][sm]; if (program_id == 0) { return; @@ -106,9 +173,9 @@ static void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) { pio_remove_program(pio, &program_struct, offset); } - uint32_t pins = _current_sm_pins[pio_index][sm]; + pio_pinmask_t pins = _current_sm_pins[pio_index][sm]; for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) { - if ((pins & (1 << pin_number)) == 0) { + if (!PIO_PINMASK_IS_SET(pins, pin_number)) { continue; } _pin_reference_count[pin_number]--; @@ -116,17 +183,17 @@ static void _reset_statemachine(PIO pio, uint8_t sm, bool leave_pins) { if (!leave_pins) { reset_pin_number(pin_number); } - _current_pins[pio_index] &= ~(1 << pin_number); + PIO_PINMASK_CLEAR(_current_pins[pio_index], pin_number); } } - _current_sm_pins[pio_index][sm] = 0; + _current_sm_pins[pio_index][sm] = PIO_PINMASK_NONE; pio->inte0 &= ~((PIO_IRQ0_INTF_SM0_RXNEMPTY_BITS | PIO_IRQ0_INTF_SM0_TXNFULL_BITS | PIO_IRQ0_INTF_SM0_BITS) << sm); pio_sm_unclaim(pio, sm); } void reset_rp2pio_statemachine(void) { for (size_t i = 0; i < NUM_PIOS; i++) { - PIO pio = pio_instances[i]; + PIO pio = pio_get_instance(i); for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) { if (_never_reset[i][j]) { continue; @@ -143,8 +210,8 @@ void reset_rp2pio_statemachine(void) { } } -static uint32_t _check_pins_free(const mcu_pin_obj_t *first_pin, uint8_t pin_count, bool exclusive_pin_use) { - uint32_t pins_we_use = 0; +static pio_pinmask_t _check_pins_free(const mcu_pin_obj_t *first_pin, uint8_t pin_count, bool exclusive_pin_use) { + pio_pinmask_t pins_we_use = PIO_PINMASK_NONE; if (first_pin != NULL) { for (size_t i = 0; i < pin_count; i++) { uint8_t pin_number = first_pin->number + i; @@ -159,25 +226,27 @@ static uint32_t _check_pins_free(const mcu_pin_obj_t *first_pin, uint8_t pin_cou if (exclusive_pin_use || _pin_reference_count[pin_number] == 0) { assert_pin_free(pin); } - pins_we_use |= 1 << pin_number; + PIO_PINMASK_SET(pins_we_use, pin_number); } } return pins_we_use; } -static bool can_add_program(PIO pio, const pio_program_t *program, int offset) { - if (offset == -1) { - return pio_can_add_program(pio, program); - } - return pio_can_add_program_at_offset(pio, program, offset); -} - -static uint add_program(PIO pio, const pio_program_t *program, int offset) { - if (offset == -1) { - return pio_add_program(pio, program); - } else { - pio_add_program_at_offset(pio, program, offset); - return offset; +// Same as _check_pins_free but over an explicit GPIO mask, for pins a program +// only waits on. Sharing with another state machine is always allowed for +// these; the caller isn't driving them. +static void _check_gpio_mask_free(pio_pinmask_t mask) { + for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) { + if (!PIO_PINMASK_IS_SET(mask, pin_number)) { + continue; + } + const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number); + if (!pin) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_Pin); + } + if (_pin_reference_count[pin_number] == 0) { + assert_pin_free(pin); + } } } @@ -208,18 +277,104 @@ static int compute_fifo_depth(enum pio_fifo_join join) { return 4; } + +// from pico-sdk/src/rp2_common/hardware_pio/pio.c +static bool is_gpio_compatible(PIO pio, uint32_t used_gpio_ranges) { + #if PICO_PIO_VERSION > 0 + bool gpio_base = pio_get_gpio_base(pio); + return !((gpio_base && (used_gpio_ranges & 1)) || + (!gpio_base && (used_gpio_ranges & 4))); + #else + ((void)pio); + ((void)used_gpio_ranges); + return true; + #endif +} + +static uint32_t required_gpio_ranges(uint gpio_base, uint gpio_count) { + if (!gpio_count) { + return 0; + } + return (1u << (gpio_base >> 4)) | + (1u << ((gpio_base + gpio_count - 1) >> 4)); +} + +// Look for a PIO that already uses some of the pins we need. The cross-PIO +// overlap check in rp2pio_statemachine_construct fails a construct outright +// when its pins live on another PIO, so a generic claim can hand us a PIO that +// can't work while a usable one sits idle. +static bool use_pio_owning_pins(PIO *pio_out, int *sm_out, int *offset_inout, pio_program_t *program_struct, pio_pinmask_t pins_we_use, uint gpio_base, uint gpio_count) { + if (PIO_PINMASK_VALUE(pins_we_use) == 0) { + return false; + } + uint32_t ranges = required_gpio_ranges(gpio_base, gpio_count); + for (size_t i = 0; i < NUM_PIOS; i++) { + PIO pio = pio_get_instance(i); + if (PIO_PINMASK_VALUE(PIO_PINMASK_AND(_current_pins[i], pins_we_use)) == 0) { + continue; + } + if (!is_gpio_compatible(pio, ranges) || !pio_can_add_program(pio, program_struct)) { + continue; + } + int sm = pio_claim_unused_sm(pio, false); + if (sm < 0) { + continue; + } + *pio_out = pio; + *sm_out = sm; + *offset_inout = pio_add_program(pio, program_struct); + return true; + } + return false; +} + +// FNV-1a over the instruction words. Never returns 0, which _current_program_id +// uses to mean "no program". +static uint32_t program_hash(const uint16_t *program, size_t program_len) { + uint32_t hash = 0x811c9dc5; + for (size_t i = 0; i < program_len; i++) { + hash = (hash ^ (program[i] & 0xff)) * 0x01000193; + hash = (hash ^ (program[i] >> 8)) * 0x01000193; + } + return hash == 0 ? 1 : hash; +} + +static bool use_existing_program(PIO *pio_out, int *sm_out, int *offset_inout, uint32_t program_id, size_t program_len, uint gpio_base, uint gpio_count) { + uint32_t ranges = required_gpio_ranges(gpio_base, gpio_count); + + for (size_t i = 0; i < NUM_PIOS; i++) { + PIO pio = pio_get_instance(i); + if (!is_gpio_compatible(pio, ranges)) { + continue; + } + for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) { + if (_current_program_id[i][j] == program_id && + _current_program_len[i][j] == program_len && + (*offset_inout == -1 || *offset_inout == _current_program_offset[i][j])) { + *sm_out = pio_claim_unused_sm(pio, false); + if (*sm_out >= 0) { + *pio_out = pio; + *offset_inout = _current_program_offset[i][j]; + return true; + } + } + } + } + return false; +} + bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, const uint16_t *program, size_t program_len, size_t frequency, const uint16_t *init, size_t init_len, const mcu_pin_obj_t *first_out_pin, uint8_t out_pin_count, const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, - uint32_t pull_pin_up, uint32_t pull_pin_down, + pio_pinmask_t pull_pin_up, pio_pinmask_t pull_pin_down, // GPIO numbering const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, - const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, - uint32_t initial_pin_state, uint32_t initial_pin_direction, + const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, bool sideset_pindirs, + pio_pinmask_t initial_pin_state, pio_pinmask_t initial_pin_direction, const mcu_pin_obj_t *jmp_pin, - uint32_t pins_we_use, bool tx_fifo, bool rx_fifo, + pio_pinmask_t pins_we_use, bool tx_fifo, bool rx_fifo, bool auto_pull, uint8_t pull_threshold, bool out_shift_right, bool wait_for_txstall, bool auto_push, uint8_t push_threshold, bool in_shift_right, @@ -231,85 +386,114 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, int fifo_type, int mov_status_type, int mov_status_n ) { - // Create a program id that isn't the pointer so we can store it without storing the original object. - uint32_t program_id = ~((uint32_t)program); + // Create a program id we can store without storing the original object. + // This has to hash the instructions rather than the pointer: programs that + // encode absolute pin numbers (`wait gpio`) are assembled into a caller's + // stack buffer, so two different programs can share an address, and + // use_existing_program() would then hand the second one the first one's + // already-loaded instructions. Hashing the contents also lets identical + // programs from different arrays share a single copy in instruction memory. + uint32_t program_id = program_hash(program, program_len); + + uint gpio_base = 0, gpio_count = 0; + #if NUM_BANK0_GPIOS > 32 + if (PIO_PINMASK_VALUE(pins_we_use) >> 32) { + if (PIO_PINMASK_VALUE(pins_we_use) & 0xffff) { + // Uses pins from 0-15 and 32-47. not possible + return false; + } + } + + pio_pinmask_value_t v = PIO_PINMASK_VALUE(pins_we_use); + if (v) { + while (!(v & 1)) { + gpio_base++; + v >>= 1; + } + while (v) { + gpio_count++; + v >>= 1; + } + } + #endif // Next, find a PIO and state machine to use. - size_t pio_index = NUM_PIOS; - uint8_t program_offset = 32; pio_program_t program_struct = { .instructions = (uint16_t *)program, .length = program_len, - .origin = -1 + .origin = offset, }; - for (size_t i = 0; i < NUM_PIOS; i++) { - PIO pio = pio_instances[i]; - uint8_t free_count = 0; - for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) { - if (_current_program_id[i][j] == program_id && - _current_program_len[i][j] == program_len && - (offset == -1 || offset == _current_program_offset[i][j])) { - program_offset = _current_program_offset[i][j]; - } - if (!pio_sm_is_claimed(pio, j)) { - free_count++; - } - } - if (free_count > 0 && (program_offset < 32 || can_add_program(pio, &program_struct, offset))) { - pio_index = i; - if (program_offset < 32) { - break; - } + PIO pio; + int state_machine; + bool added = false; + + if (use_existing_program(&pio, &state_machine, &offset, program_id, program_len, gpio_base, gpio_count)) { + // Program is already loaded and shareable; nothing to add. + } else if (use_pio_owning_pins(&pio, &state_machine, &offset, &program_struct, pins_we_use, gpio_base, gpio_count)) { + added = true; + } else { + uint program_offset; + bool r = pio_claim_free_sm_and_add_program_for_gpio_range(&program_struct, &pio, (uint *)&state_machine, &program_offset, gpio_base, gpio_count, true); + if (!r) { + return false; } - // Reset program offset if we weren't able to find a free state machine - // on that PIO. (We would have broken the loop otherwise.) - program_offset = 32; + offset = program_offset; + added = true; } - size_t state_machine = NUM_PIO_STATE_MACHINES; - if (pio_index < NUM_PIOS) { - PIO pio = pio_instances[pio_index]; - for (size_t i = 0; i < NUM_PIOS; i++) { - if (i == pio_index) { - continue; - } - if ((_current_pins[i] & pins_we_use) != 0) { - // Pin in use by another PIO already. - return false; + size_t pio_index = pio_get_index(pio); + for (size_t i = 0; i < NUM_PIOS; i++) { + if (i == pio_index) { + continue; + } + pio_pinmask_t intersection = PIO_PINMASK_AND(_current_pins[i], pins_we_use); + if (PIO_PINMASK_VALUE(intersection) != 0) { + if (added) { + pio_remove_program(pio, &program_struct, offset); } + pio_sm_unclaim(pio, state_machine); + // Pin in use by another PIO already. + return false; } - state_machine = pio_claim_unused_sm(pio, false); - } - if (pio_index == NUM_PIOS || state_machine < 0 || state_machine >= NUM_PIO_STATE_MACHINES) { - return false; } - self->pio = pio_instances[pio_index]; + // Sanity check that state_machine number is valid. + assert(state_machine >= 0); + self->pio = pio; self->state_machine = state_machine; - if (program_offset == 32) { - program_offset = add_program(self->pio, &program_struct, offset); - } - self->offset = program_offset; + self->offset = offset; _current_program_id[pio_index][state_machine] = program_id; _current_program_len[pio_index][state_machine] = program_len; - _current_program_offset[pio_index][state_machine] = program_offset; + _current_program_offset[pio_index][state_machine] = offset; _current_sm_pins[pio_index][state_machine] = pins_we_use; - _current_pins[pio_index] |= pins_we_use; + PIO_PINMASK_MERGE(_current_pins[pio_index], pins_we_use); + + // Only configure the pins no other state machine has claimed yet. A shared + // pin that this state machine doesn't drive (a clock it only waits on, say) + // would otherwise be forced back to input, clobbering its owner's setup. + pio_pinmask_t pins_we_own = PIO_PINMASK_NONE; + for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) { + if (PIO_PINMASK_IS_SET(pins_we_use, pin_number) && _pin_reference_count[pin_number] == 0) { + PIO_PINMASK_SET(pins_we_own, pin_number); + } + } + self->pins_we_own = pins_we_own; - pio_sm_set_pins_with_mask(self->pio, state_machine, initial_pin_state, pins_we_use); - pio_sm_set_pindirs_with_mask(self->pio, state_machine, initial_pin_direction, pins_we_use); - rp2pio_statemachine_set_pull(pull_pin_up, pull_pin_down, pins_we_use); + pio_sm_set_pins_with_mask64(self->pio, state_machine, PIO_PINMASK_VALUE(initial_pin_state), PIO_PINMASK_VALUE(pins_we_own)); + pio_sm_set_pindirs_with_mask64(self->pio, state_machine, PIO_PINMASK_VALUE(initial_pin_direction), PIO_PINMASK_VALUE(pins_we_own)); + rp2pio_statemachine_set_pull(pull_pin_up, pull_pin_down, pins_we_own); self->initial_pin_state = initial_pin_state; self->initial_pin_direction = initial_pin_direction; self->pull_pin_up = pull_pin_up; self->pull_pin_down = pull_pin_down; for (size_t pin_number = 0; pin_number < NUM_BANK0_GPIOS; pin_number++) { - if ((pins_we_use & (1 << pin_number)) == 0) { + if (!PIO_PINMASK_IS_SET(pins_we_use, pin_number)) { continue; } const mcu_pin_obj_t *pin = mcu_get_pin_by_number(pin_number); if (!pin) { + // TODO: should be impossible, but free resources here anyway return false; } _pin_reference_count[pin_number]++; @@ -327,7 +511,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, gpio_set_drive_strength(pin_number, GPIO_DRIVE_STRENGTH_2MA); } - pio_sm_config c = {0, 0, 0}; + pio_sm_config c = pio_get_default_sm_config(); if (frequency == 0) { frequency = clock_get_hz(clk_sys); @@ -354,7 +538,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, if (sideset_enable) { total_sideset_bits += 1; } - sm_config_set_sideset(&c, total_sideset_bits, sideset_enable, false /* pin direction */); + sm_config_set_sideset(&c, total_sideset_bits, sideset_enable, sideset_pindirs); sm_config_set_sideset_pins(&c, first_sideset_pin->number); } if (jmp_pin != NULL) { @@ -368,8 +552,8 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, mp_arg_validate_int_range(wrap_target, 0, program_len - 1, MP_QSTR_wrap_target); - wrap += program_offset; - wrap_target += program_offset; + wrap += offset; + wrap_target += offset; sm_config_set_wrap(&c, wrap_target, wrap); sm_config_set_in_shift(&c, in_shift_right, auto_push, push_threshold); @@ -413,16 +597,18 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, sm_config_set_fifo_join(&c, join); + sm_config_set_mov_status(&c, mov_status_type, mov_status_n); + // TODO: these arguments - // int mov_status_type, int mov_status_n, // int set_count, int out_count self->sm_config = c; // no DMA allocated - SM_DMA_CLEAR_CHANNEL(pio_index, state_machine); + SM_DMA_CLEAR_CHANNEL_READ(pio_index, state_machine); + SM_DMA_CLEAR_CHANNEL_WRITE(pio_index, state_machine); - pio_sm_init(self->pio, self->state_machine, program_offset, &c); + pio_sm_init(self->pio, self->state_machine, offset, &c); common_hal_rp2pio_statemachine_run(self, init, init_len); common_hal_rp2pio_statemachine_set_frequency(self, frequency); @@ -430,18 +616,20 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, return true; } -static uint32_t mask_and_rotate(const mcu_pin_obj_t *first_pin, uint32_t bit_count, uint32_t value) { +static pio_pinmask_t mask_and_shift(const mcu_pin_obj_t *first_pin, uint32_t bit_count, pio_pinmask32_t value_in) { if (!first_pin) { - return 0; + return PIO_PINMASK_NONE; } - value = value & ((1 << bit_count) - 1); - uint32_t shift = first_pin->number; - return value << shift | value >> (32 - shift); + pio_pinmask_value_t mask = (PIO_PINMASK_C(1) << bit_count) - 1; + pio_pinmask_value_t value = (pio_pinmask_value_t)PIO_PINMASK32_VALUE(value_in); + int shift = first_pin->number; + return PIO_PINMASK_FROM_VALUE((value & mask) << shift); } typedef struct { struct { - uint32_t pins_we_use, in_pin_count, out_pin_count; + pio_pinmask_t pins_we_use; + uint8_t in_pin_count, out_pin_count, pio_gpio_offset; bool has_jmp_pin, auto_push, auto_pull, has_in_pin, has_out_pin, has_set_pin; } inputs; struct { @@ -467,12 +655,12 @@ static void consider_instruction(introspect_t *state, uint16_t full_instruction, } } if (instruction == pio_instr_bits_wait) { - uint16_t wait_source = (full_instruction & 0x0060) >> 5; - uint16_t wait_index = full_instruction & 0x001f; - if (wait_source == 0 && (state->inputs.pins_we_use & (1 << wait_index)) == 0) { // GPIO + const uint16_t wait_source = (full_instruction & 0x0060) >> 5; + const uint16_t wait_index = full_instruction & 0x001f; + const uint16_t wait_pin = wait_index + state->inputs.pio_gpio_offset; + if (wait_source == 0 && !PIO_PINMASK_IS_SET(state->inputs.pins_we_use, wait_pin)) { // GPIO mp_raise_ValueError_varg(MP_ERROR_TEXT("%q[%u] uses extra pin"), what_program, i); - } - if (wait_source == 1) { // Input pin + } else if (wait_source == 1) { // Input pin if (!state->inputs.has_in_pin) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Missing first_in_pin. %q[%u] waits based on pin"), what_program, i); } @@ -552,14 +740,15 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, size_t frequency, const uint16_t *init, size_t init_len, const uint16_t *may_exec, size_t may_exec_len, - const mcu_pin_obj_t *first_out_pin, uint8_t out_pin_count, uint32_t initial_out_pin_state, uint32_t initial_out_pin_direction, + const mcu_pin_obj_t *first_out_pin, uint8_t out_pin_count, pio_pinmask32_t initial_out_pin_state32, pio_pinmask32_t initial_out_pin_direction32, const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, - uint32_t pull_pin_up, uint32_t pull_pin_down, - const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, uint32_t initial_set_pin_state, uint32_t initial_set_pin_direction, - const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, uint32_t initial_sideset_pin_state, uint32_t initial_sideset_pin_direction, + pio_pinmask32_t in_pull_pin_up32, pio_pinmask32_t in_pull_pin_down32, // relative to first_in_pin + const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, pio_pinmask32_t initial_set_pin_state32, pio_pinmask32_t initial_set_pin_direction32, + const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, bool sideset_pindirs, + pio_pinmask32_t initial_sideset_pin_state32, pio_pinmask32_t initial_sideset_pin_direction32, bool sideset_enable, const mcu_pin_obj_t *jmp_pin, digitalio_pull_t jmp_pull, - uint32_t wait_gpio_mask, + pio_pinmask_t wait_gpio_mask, bool exclusive_pin_use, bool auto_pull, uint8_t pull_threshold, bool out_shift_right, bool wait_for_txstall, @@ -571,18 +760,33 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, int mov_status_type, int mov_status_n) { + // Ensure object starts in its deinit state. + common_hal_rp2pio_statemachine_mark_deinit(self); + // First, check that all pins are free OR already in use by any PIO if exclusive_pin_use is false. - uint32_t pins_we_use = wait_gpio_mask; - pins_we_use |= _check_pins_free(first_out_pin, out_pin_count, exclusive_pin_use); - pins_we_use |= _check_pins_free(first_in_pin, in_pin_count, exclusive_pin_use); - pins_we_use |= _check_pins_free(first_set_pin, set_pin_count, exclusive_pin_use); - pins_we_use |= _check_pins_free(first_sideset_pin, sideset_pin_count, exclusive_pin_use); - pins_we_use |= _check_pins_free(jmp_pin, 1, exclusive_pin_use); + _check_gpio_mask_free(wait_gpio_mask); + pio_pinmask_t pins_we_use = wait_gpio_mask; + PIO_PINMASK_MERGE(pins_we_use, _check_pins_free(first_out_pin, out_pin_count, exclusive_pin_use)); + PIO_PINMASK_MERGE(pins_we_use, _check_pins_free(first_in_pin, in_pin_count, exclusive_pin_use)); + PIO_PINMASK_MERGE(pins_we_use, _check_pins_free(first_set_pin, set_pin_count, exclusive_pin_use)); + PIO_PINMASK_MERGE(pins_we_use, _check_pins_free(first_sideset_pin, sideset_pin_count, exclusive_pin_use)); + PIO_PINMASK_MERGE(pins_we_use, _check_pins_free(jmp_pin, 1, exclusive_pin_use)); + + int pio_gpio_offset = 0; + #if NUM_BANK0_GPIOS > 32 + if (PIO_PINMASK_VALUE(pins_we_use) >> 32) { + pio_gpio_offset = 16; + if (PIO_PINMASK_VALUE(pins_we_use) & 0xffff) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Cannot use GPIO0..15 together with GPIO32..47")); + } + } + #endif // Look through the program to see what we reference and make sure it was provided. introspect_t state = { .inputs = { .pins_we_use = pins_we_use, + .pio_gpio_offset = pio_gpio_offset, .has_jmp_pin = jmp_pin != NULL, .has_in_pin = first_in_pin != NULL, .has_out_pin = first_out_pin != NULL, @@ -604,43 +808,54 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, mp_raise_ValueError_varg(MP_ERROR_TEXT("Program does OUT without loading OSR")); } - uint32_t initial_pin_state = mask_and_rotate(first_out_pin, out_pin_count, initial_out_pin_state); - uint32_t initial_pin_direction = mask_and_rotate(first_out_pin, out_pin_count, initial_out_pin_direction); - initial_set_pin_state = mask_and_rotate(first_set_pin, set_pin_count, initial_set_pin_state); - initial_set_pin_direction = mask_and_rotate(first_set_pin, set_pin_count, initial_set_pin_direction); - uint32_t set_out_overlap = mask_and_rotate(first_out_pin, out_pin_count, 0xffffffff) & - mask_and_rotate(first_set_pin, set_pin_count, 0xffffffff); + pio_pinmask_t initial_pin_state = mask_and_shift(first_out_pin, out_pin_count, initial_out_pin_state32); + pio_pinmask_t initial_pin_direction = mask_and_shift(first_out_pin, out_pin_count, initial_out_pin_direction32); + pio_pinmask_t initial_set_pin_state = mask_and_shift(first_set_pin, set_pin_count, initial_set_pin_state32); + pio_pinmask_t initial_set_pin_direction = mask_and_shift(first_set_pin, set_pin_count, initial_set_pin_direction32); + pio_pinmask_t set_out_overlap = PIO_PINMASK_AND(mask_and_shift(first_out_pin, out_pin_count, PIO_PINMASK32_ALL), + mask_and_shift(first_set_pin, set_pin_count, PIO_PINMASK32_ALL)); // Check that OUT and SET settings agree because we don't have a way of picking one over the other. - if ((initial_pin_state & set_out_overlap) != (initial_set_pin_state & set_out_overlap)) { + if (!PIO_PINMASK_EQUAL( + PIO_PINMASK_AND(initial_pin_state, set_out_overlap), + PIO_PINMASK_AND(initial_set_pin_state, set_out_overlap))) { mp_raise_ValueError(MP_ERROR_TEXT("Initial set pin state conflicts with initial out pin state")); } - if ((initial_pin_direction & set_out_overlap) != (initial_set_pin_direction & set_out_overlap)) { + if (!PIO_PINMASK_EQUAL( + PIO_PINMASK_AND(initial_pin_direction, set_out_overlap), + PIO_PINMASK_AND(initial_set_pin_direction, set_out_overlap))) { mp_raise_ValueError(MP_ERROR_TEXT("Initial set pin direction conflicts with initial out pin direction")); } - initial_pin_state |= initial_set_pin_state; - initial_pin_direction |= initial_set_pin_direction; + PIO_PINMASK_MERGE(initial_pin_state, initial_set_pin_state); + PIO_PINMASK_MERGE(initial_pin_direction, initial_set_pin_direction); // Sideset overrides OUT or SET so we always use its values. - uint32_t sideset_mask = mask_and_rotate(first_sideset_pin, sideset_pin_count, 0x1f); - initial_pin_state = (initial_pin_state & ~sideset_mask) | mask_and_rotate(first_sideset_pin, sideset_pin_count, initial_sideset_pin_state); - initial_pin_direction = (initial_pin_direction & ~sideset_mask) | mask_and_rotate(first_sideset_pin, sideset_pin_count, initial_sideset_pin_direction); + pio_pinmask_t sideset_mask = mask_and_shift(first_sideset_pin, sideset_pin_count, PIO_PINMASK32_FROM_VALUE(0x1f)); + initial_pin_state = PIO_PINMASK_OR( + PIO_PINMASK_AND_NOT(initial_pin_state, sideset_mask), + mask_and_shift(first_sideset_pin, sideset_pin_count, initial_sideset_pin_state32)); + initial_pin_direction = PIO_PINMASK_OR( + PIO_PINMASK_AND_NOT(initial_pin_direction, sideset_mask), + mask_and_shift(first_sideset_pin, sideset_pin_count, initial_sideset_pin_direction32)); // Deal with pull up/downs - uint32_t pull_up = mask_and_rotate(first_in_pin, in_pin_count, pull_pin_up); - uint32_t pull_down = mask_and_rotate(first_in_pin, in_pin_count, pull_pin_down); + pio_pinmask_t pull_up = mask_and_shift(first_in_pin, in_pin_count, in_pull_pin_up32); + pio_pinmask_t pull_down = mask_and_shift(first_in_pin, in_pin_count, in_pull_pin_down32); if (jmp_pin) { - uint32_t jmp_mask = mask_and_rotate(jmp_pin, 1, 0x1f); + pio_pinmask_t jmp_mask = mask_and_shift(jmp_pin, 1, PIO_PINMASK32_FROM_VALUE(0x1f)); if (jmp_pull == PULL_UP) { - pull_up |= jmp_mask; + PIO_PINMASK_MERGE(pull_up, jmp_mask); } if (jmp_pull == PULL_DOWN) { - pull_down |= jmp_mask; + PIO_PINMASK_MERGE(pull_down, jmp_mask); } } - if (initial_pin_direction & (pull_up | pull_down)) { + if (PIO_PINMASK_VALUE( + PIO_PINMASK_AND(initial_pin_direction, + PIO_PINMASK_OR(pull_up, pull_down)))) { mp_raise_ValueError(MP_ERROR_TEXT("pull masks conflict with direction masks")); } + bool ok = rp2pio_statemachine_construct( self, program, program_len, @@ -650,7 +865,7 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, first_in_pin, in_pin_count, pull_up, pull_down, first_set_pin, set_pin_count, - first_sideset_pin, sideset_pin_count, + first_sideset_pin, sideset_pin_count, sideset_pindirs, initial_pin_state, initial_pin_direction, jmp_pin, pins_we_use, state.outputs.tx_fifo, state.outputs.rx_fifo, @@ -664,6 +879,8 @@ void common_hal_rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, fifo_type, mov_status_type, mov_status_n); if (!ok) { + // indicate state machine never inited + common_hal_rp2pio_statemachine_mark_deinit(self); mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use")); } } @@ -674,11 +891,10 @@ void common_hal_rp2pio_statemachine_restart(rp2pio_statemachine_obj_t *self) { // the desired offset, so we can just use self->offset. pio_sm_exec(self->pio, self->state_machine, self->offset); pio_sm_restart(self->pio, self->state_machine); - uint8_t pio_index = pio_get_index(self->pio); - uint32_t pins_we_use = _current_sm_pins[pio_index][self->state_machine]; - pio_sm_set_pins_with_mask(self->pio, self->state_machine, self->initial_pin_state, pins_we_use); - pio_sm_set_pindirs_with_mask(self->pio, self->state_machine, self->initial_pin_direction, pins_we_use); - rp2pio_statemachine_set_pull(self->pull_pin_up, self->pull_pin_down, pins_we_use); + pio_pinmask_t pins_we_own = self->pins_we_own; + pio_sm_set_pins_with_mask64(self->pio, self->state_machine, PIO_PINMASK_VALUE(self->initial_pin_state), PIO_PINMASK_VALUE(pins_we_own)); + pio_sm_set_pindirs_with_mask64(self->pio, self->state_machine, PIO_PINMASK_VALUE(self->initial_pin_direction), PIO_PINMASK_VALUE(pins_we_own)); + rp2pio_statemachine_set_pull(self->pull_pin_up, self->pull_pin_down, pins_we_own); common_hal_rp2pio_statemachine_run(self, self->init, self->init_len); pio_sm_set_enabled(self->pio, self->state_machine, true); } @@ -727,6 +943,38 @@ void rp2pio_statemachine_never_reset(PIO pio, int sm) { _never_reset[pio_index][sm] = true; } +// Pick a PIO that has room for a program of program_size instructions and at +// least sm_count free state machines; returns its index, or NUM_PIOS if none +// qualifies. This lets an out-of-tree PIO user (e.g. the sdioio SDIO driver, +// which manages its own SDK-level pio_claim_unused_sm / pio_add_program) pick a +// PIO cooperatively rather than blindly seizing pio0/pio1/pio2. Because it uses +// the same SDK claim/instruction bookkeeping that rp2pio itself relies on, a hit +// here means the caller's subsequent claims on the returned PIO will succeed and +// will not collide with an existing rp2pio user. +uint8_t rp2pio_statemachine_find_pio(int program_size, int sm_count) { + pio_program_t test_program = { + .instructions = NULL, + .length = program_size, + .origin = -1, + }; + for (size_t i = 0; i < NUM_PIOS; i++) { + PIO pio = pio_get_instance(i); + if (!pio_can_add_program(pio, &test_program)) { + continue; + } + int free_sms = 0; + for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) { + if (!pio_sm_is_claimed(pio, j)) { + free_sms++; + } + } + if (free_sms >= sm_count) { + return i; + } + } + return NUM_PIOS; +} + void rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self, bool leave_pins) { common_hal_rp2pio_statemachine_stop(self); (void)common_hal_rp2pio_statemachine_stop_background_write(self); @@ -746,6 +994,10 @@ void common_hal_rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self) { rp2pio_statemachine_deinit(self, false); } +void common_hal_rp2pio_statemachine_mark_deinit(rp2pio_statemachine_obj_t *self) { + self->state_machine = NUM_PIO_STATE_MACHINES; +} + void common_hal_rp2pio_statemachine_never_reset(rp2pio_statemachine_obj_t *self) { rp2pio_statemachine_never_reset(self->pio, self->state_machine); // TODO: never reset all the pins @@ -773,25 +1025,64 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, // This implementation is based on SPI but varies because the tx and rx buffers // may be different lengths and occur at different times or speeds. - // Use DMA for large transfers if channels are available. - // Don't exceed FIFO size. - const size_t dma_min_size_threshold = self->fifo_depth; int chan_tx = -1; int chan_rx = -1; size_t len = MAX(out_len, in_len); bool tx = data_out != NULL; bool rx = data_in != NULL; - bool use_dma = len >= dma_min_size_threshold || swap_out || swap_in; + bool free_data_out = false; + bool free_data_in = false; + uint8_t *sram_data_out = (uint8_t *)data_out; + uint8_t *sram_data_in = data_in; + bool tx_fits_in_fifo = (out_len / out_stride_in_bytes) <= self->fifo_depth; + bool rx_fits_in_fifo = (in_len / in_stride_in_bytes) <= self->fifo_depth; + bool use_dma = !(tx_fits_in_fifo && rx_fits_in_fifo) || swap_out || swap_in; + if (use_dma) { - // Use DMA channels to service the two FIFOs + // We can only reliably use DMA for SRAM buffers. So, if we're given PSRAM buffers, + // then copy them to SRAM first. If we can't, then fail. + // Use DMA channels to service the two FIFOs. Fail if we can't allocate DMA channels. if (tx) { + if (data_out < (uint8_t *)SRAM_BASE) { + // Try to allocate a temporary buffer for DMA transfer + uint8_t *temp_buffer = (uint8_t *)port_malloc(len, true); + if (temp_buffer == NULL) { + mp_printf(&mp_plat_print, "Failed to allocate temporary buffer for DMA tx\n"); + return false; + } + memcpy(temp_buffer, data_out, len); + sram_data_out = temp_buffer; + free_data_out = true; + } chan_tx = dma_claim_unused_channel(false); // DMA allocation failed... if (chan_tx < 0) { + if (free_data_out) { + port_free(sram_data_out); + } + if (free_data_in) { + port_free(sram_data_in); + } return false; } } if (rx) { + if (data_in < (uint8_t *)SRAM_BASE) { + // Try to allocate a temporary buffer for DMA transfer + uint8_t *temp_buffer = (uint8_t *)port_malloc(len, true); + if (temp_buffer == NULL) { + mp_printf(&mp_plat_print, "Failed to allocate temporary buffer for DMA rx\n"); + if (chan_tx >= 0) { + dma_channel_unclaim(chan_tx); + } + if (free_data_out) { + port_free(sram_data_out); + } + return false; + } + sram_data_in = temp_buffer; + free_data_in = true; + } chan_rx = dma_claim_unused_channel(false); // DMA allocation failed... if (chan_rx < 0) { @@ -799,6 +1090,12 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, if (chan_tx >= 0) { dma_channel_unclaim(chan_tx); } + if (free_data_out) { + port_free(sram_data_out); + } + if (free_data_in) { + port_free(sram_data_in); + } return false; } } @@ -830,7 +1127,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, channel_config_set_bswap(&c, swap_out); dma_channel_configure(chan_tx, &c, tx_destination, - data_out, + sram_data_out, out_len / out_stride_in_bytes, false); channel_mask |= 1u << chan_tx; @@ -843,7 +1140,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, channel_config_set_write_increment(&c, true); channel_config_set_bswap(&c, swap_in); dma_channel_configure(chan_rx, &c, - data_in, + sram_data_in, rx_source, in_len / in_stride_in_bytes, false); @@ -870,8 +1167,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, self->pio->fdebug = stall_mask; } - // If we have claimed only one channel successfully, we should release immediately. This also - // releases the DMA after use_dma has been done. + // Release the DMA channels after use_dma has been done. if (chan_rx >= 0) { dma_channel_unclaim(chan_rx); } @@ -880,31 +1176,31 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, } if (!use_dma && !(self->user_interruptible && mp_hal_is_interrupted())) { - // Use software for small transfers, or if couldn't claim two DMA channels + // Use software for small transfers size_t rx_remaining = in_len / in_stride_in_bytes; size_t tx_remaining = out_len / out_stride_in_bytes; while (rx_remaining || tx_remaining) { while (tx_remaining && !pio_sm_is_tx_fifo_full(self->pio, self->state_machine)) { if (out_stride_in_bytes == 1) { - *tx_destination = *data_out; + *tx_destination = *sram_data_out; } else if (out_stride_in_bytes == 2) { - *((uint16_t *)tx_destination) = *((uint16_t *)data_out); + *((uint16_t *)tx_destination) = *((uint16_t *)sram_data_out); } else if (out_stride_in_bytes == 4) { - *((uint32_t *)tx_destination) = *((uint32_t *)data_out); + *((uint32_t *)tx_destination) = *((uint32_t *)sram_data_out); } - data_out += out_stride_in_bytes; + sram_data_out += out_stride_in_bytes; --tx_remaining; } while (rx_remaining && !pio_sm_is_rx_fifo_empty(self->pio, self->state_machine)) { if (in_stride_in_bytes == 1) { - *data_in = (uint8_t)*rx_source; + *sram_data_in = (uint8_t)*rx_source; } else if (in_stride_in_bytes == 2) { - *((uint16_t *)data_in) = *((uint16_t *)rx_source); + *((uint16_t *)sram_data_in) = *((uint16_t *)rx_source); } else if (in_stride_in_bytes == 4) { - *((uint32_t *)data_in) = *((uint32_t *)rx_source); + *((uint32_t *)sram_data_in) = *((uint32_t *)rx_source); } - data_in += in_stride_in_bytes; + sram_data_in += in_stride_in_bytes; --rx_remaining; } RUN_BACKGROUND_TASKS; @@ -916,7 +1212,7 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, self->pio->fdebug = stall_mask; } // Wait for the state machine to finish transmitting the data we've queued - // up. + // up (either from the CPU or via DMA.) if (tx) { while (!pio_sm_is_tx_fifo_empty(self->pio, self->state_machine) || (self->wait_for_txstall && (self->pio->fdebug & stall_mask) == 0)) { @@ -926,6 +1222,14 @@ static bool _transfer(rp2pio_statemachine_obj_t *self, } } } + if (free_data_out) { + port_free(sram_data_out); + } + if (free_data_in) { + // Copy the data from the SRAM buffer to the user PSRAM buffer. + memcpy(data_in, sram_data_in, len); + port_free(sram_data_in); + } return true; } @@ -1004,7 +1308,7 @@ void common_hal_rp2pio_statemachine_set_interrupt_handler(rp2pio_statemachine_ob static void rp2pio_statemachine_interrupt_handler(void) { for (size_t pio_index = 0; pio_index < NUM_PIOS; pio_index++) { - PIO pio = pio_instances[pio_index]; + PIO pio = pio_get_instance(pio_index); for (size_t sm = 0; sm < NUM_PIO_STATE_MACHINES; sm++) { if (!_interrupt_handler[pio_index][sm]) { continue; @@ -1023,16 +1327,49 @@ uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self) { return _current_program_offset[pio_index][sm]; } -bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, const sm_buf_info *once, const sm_buf_info *loop, uint8_t stride_in_bytes, bool swap) { +bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t *self, uint8_t stride_in_bytes, bool swap) { + uint8_t pio_index = pio_get_index(self->pio); uint8_t sm = self->state_machine; - int pending_buffers = (once->info.len != 0) + (loop->info.len != 0); - if (!once->info.len) { - once = loop; + self->switched_write_buffers = false; + + int pending_buffers_write = (self->once_write_buf_info.info.len != 0) + (self->loop_write_buf_info.info.len != 0) + (self->loop2_write_buf_info.info.len != 0); + + // If all buffer arguments have nonzero length, write once_write_buf, loop_write_buf, loop2_write_buf and repeat last two forever + + if (!(self->once_write_buf_info.info.len)) { + if (!self->loop_write_buf_info.info.len) { + // If once_write_buf and loop_write_buf have zero length, write loop2_write_buf forever + self->once_write_buf_info = self->loop2_write_buf_info; + self->loop_write_buf_info = self->loop2_write_buf_info; + } else { + if (!(self->loop2_write_buf_info.info.len)) { + // If once_write_buf and loop2_write_buf have zero length, write loop_write_buf forever + self->once_write_buf_info = self->loop_write_buf_info; + self->loop2_write_buf_info = self->loop_write_buf_info; + } else { + // If only once_write_buf has zero length, write loop_write_buf, loop2_write_buf, and repeat last two forever + self->once_write_buf_info = self->loop_write_buf_info; + self->loop_write_buf_info = self->loop2_write_buf_info; + self->loop2_write_buf_info = self->once_write_buf_info; + } + } + } else { + if (!(self->loop_write_buf_info.info.len)) { + // If once_write_buf has nonzero length and loop_write_buf has zero length, write once_write_buf, loop2_write_buf and repeat last buf forever + self->loop_write_buf_info = self->loop2_write_buf_info; + } else { + if (!self->loop2_write_buf_info.info.len) { + // If once_write_buf has nonzero length and loop2_write_buf have zero length, write once_write_buf, loop_write_buf and repeat last buf forever + self->loop2_write_buf_info = self->loop_write_buf_info; + } + } } - if (SM_DMA_ALLOCATED(pio_index, sm)) { + // if DMA is already going (i.e. this is not the first call to background_write), + // block until once_write_buf and loop_write_buf have each been written at least once + if (SM_DMA_ALLOCATED_WRITE(pio_index, sm)) { if (stride_in_bytes != self->background_stride_in_bytes) { mp_raise_ValueError(MP_ERROR_TEXT("Mismatched data size")); } @@ -1040,7 +1377,7 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t * mp_raise_ValueError(MP_ERROR_TEXT("Mismatched swap flag")); } - while (self->pending_buffers) { + while (self->pending_buffers_write) { RUN_BACKGROUND_TASKS; if (self->user_interruptible && mp_hal_is_interrupted()) { return false; @@ -1048,13 +1385,14 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t * } common_hal_mcu_disable_interrupts(); - self->once = *once; - self->loop = *loop; - self->pending_buffers = pending_buffers; - - if (self->dma_completed && self->once.info.len) { - rp2pio_statemachine_dma_complete(self, SM_DMA_GET_CHANNEL(pio_index, sm)); - self->dma_completed = false; + self->next_write_buf_1 = self->once_write_buf_info; + self->next_write_buf_2 = self->loop_write_buf_info; + self->next_write_buf_3 = self->loop2_write_buf_info; + self->pending_buffers_write = pending_buffers_write; + + if (self->dma_completed_write && self->next_write_buf_1.info.len) { + rp2pio_statemachine_dma_complete_write(self, SM_DMA_GET_CHANNEL_WRITE(pio_index, sm)); + self->dma_completed_write = false; } common_hal_mcu_enable_interrupts(); @@ -1062,82 +1400,281 @@ bool common_hal_rp2pio_statemachine_background_write(rp2pio_statemachine_obj_t * return true; } - int channel = dma_claim_unused_channel(false); - if (channel == -1) { + int channel_write = dma_claim_unused_channel(false); + if (channel_write == -1) { return false; } - SM_DMA_SET_CHANNEL(pio_index, sm, channel); + SM_DMA_SET_CHANNEL_WRITE(pio_index, sm, channel_write); volatile uint8_t *tx_destination = (volatile uint8_t *)&self->pio->txf[self->state_machine]; self->tx_dreq = pio_get_dreq(self->pio, self->state_machine, true); - dma_channel_config c; + dma_channel_config c_write; + + self->current_write_buf = self->once_write_buf_info; + self->next_write_buf_1 = self->loop_write_buf_info; + self->next_write_buf_2 = self->loop2_write_buf_info; + self->next_write_buf_3 = self->loop_write_buf_info; + + self->pending_buffers_write = pending_buffers_write; + self->dma_completed_write = false; - self->current = *once; - self->once = *loop; - self->loop = *loop; - self->pending_buffers = pending_buffers; - self->dma_completed = false; self->background_stride_in_bytes = stride_in_bytes; self->byteswap = swap; - c = dma_channel_get_default_config(channel); - channel_config_set_transfer_data_size(&c, _stride_to_dma_size(stride_in_bytes)); - channel_config_set_dreq(&c, self->tx_dreq); - channel_config_set_read_increment(&c, true); - channel_config_set_write_increment(&c, false); - channel_config_set_bswap(&c, swap); - dma_channel_configure(channel, &c, + c_write = dma_channel_get_default_config(channel_write); + channel_config_set_transfer_data_size(&c_write, _stride_to_dma_size(stride_in_bytes)); + channel_config_set_dreq(&c_write, self->tx_dreq); + channel_config_set_read_increment(&c_write, true); + channel_config_set_write_increment(&c_write, false); + channel_config_set_bswap(&c_write, swap); + dma_channel_configure(channel_write, &c_write, tx_destination, - once->info.buf, - once->info.len / stride_in_bytes, + self->once_write_buf_info.info.buf, + self->once_write_buf_info.info.len / stride_in_bytes, false); common_hal_mcu_disable_interrupts(); - MP_STATE_PORT(background_pio)[channel] = self; - dma_hw->inte0 |= 1u << channel; - irq_set_mask_enabled(1 << DMA_IRQ_0, true); - dma_start_channel_mask(1u << channel); + + MP_STATE_PORT(background_pio_write)[channel_write] = self; + rp2pio_dma_enable_irq(channel_write); + dma_start_channel_mask(1u << channel_write); common_hal_mcu_enable_interrupts(); return true; } -void rp2pio_statemachine_dma_complete(rp2pio_statemachine_obj_t *self, int channel) { - self->current = self->once; - self->once = self->loop; +void rp2pio_statemachine_dma_complete_write(rp2pio_statemachine_obj_t *self, int channel_write) { + self->current_write_buf = self->next_write_buf_1; + self->next_write_buf_1 = self->next_write_buf_2; + self->next_write_buf_2 = self->next_write_buf_3; + self->next_write_buf_3 = self->next_write_buf_1; - if (self->current.info.buf) { - if (self->pending_buffers > 0) { - self->pending_buffers--; + if (self->current_write_buf.info.buf) { + if (self->pending_buffers_write > 0) { + self->pending_buffers_write--; } - dma_channel_set_read_addr(channel, self->current.info.buf, false); - dma_channel_set_trans_count(channel, self->current.info.len / self->background_stride_in_bytes, true); + dma_channel_set_read_addr(channel_write, self->current_write_buf.info.buf, false); + dma_channel_set_trans_count(channel_write, self->current_write_buf.info.len / self->background_stride_in_bytes, true); } else { - self->dma_completed = true; - self->pending_buffers = 0; // should be a no-op + self->dma_completed_write = true; + self->pending_buffers_write = 0; // should be a no-op } + + self->switched_write_buffers = true; } bool common_hal_rp2pio_statemachine_stop_background_write(rp2pio_statemachine_obj_t *self) { uint8_t pio_index = pio_get_index(self->pio); uint8_t sm = self->state_machine; - rp2pio_statemachine_clear_dma(pio_index, sm); - memset(&self->current, 0, sizeof(self->current)); - memset(&self->once, 0, sizeof(self->once)); - memset(&self->loop, 0, sizeof(self->loop)); - self->pending_buffers = 0; + rp2pio_statemachine_clear_dma_write(pio_index, sm); + memset(&self->current_write_buf, 0, sizeof(self->current_write_buf)); + memset(&self->next_write_buf_1, 0, sizeof(self->next_write_buf_1)); + memset(&self->next_write_buf_2, 0, sizeof(self->next_write_buf_2)); + memset(&self->next_write_buf_3, 0, sizeof(self->next_write_buf_3)); + self->pending_buffers_write = 0; return true; } bool common_hal_rp2pio_statemachine_get_writing(rp2pio_statemachine_obj_t *self) { - return !self->dma_completed; + return !self->dma_completed_write; } -int common_hal_rp2pio_statemachine_get_pending(rp2pio_statemachine_obj_t *self) { - return self->pending_buffers; +int common_hal_rp2pio_statemachine_get_pending_write(rp2pio_statemachine_obj_t *self) { + return self->pending_buffers_write; +} + +// ================================================================================= + +bool common_hal_rp2pio_statemachine_background_read(rp2pio_statemachine_obj_t *self, uint8_t stride_in_bytes, bool swap) { + + uint8_t pio_index = pio_get_index(self->pio); + uint8_t sm = self->state_machine; + + self->switched_read_buffers = false; + + int pending_buffers_read = (self->once_read_buf_info.info.len != 0) + (self->loop_read_buf_info.info.len != 0) + (self->loop2_read_buf_info.info.len != 0); + + // If all buffer arguments have nonzero length, read once_read_buf, loop_read_buf, loop2_read_buf and repeat last two forever + + if (!(self->once_read_buf_info.info.len)) { + if (!(self->loop_read_buf_info.info.len)) { + // If once_read_buf and loop_read_buf have zero length, read loop2_read_buf forever + self->once_read_buf_info = self->loop2_read_buf_info; + self->loop_read_buf_info = self->loop2_read_buf_info; + } else { + if (!(self->loop2_read_buf_info.info.len)) { + // If once_read_buf and loop2_read_buf have zero length, read loop_read_buf forever + self->once_read_buf_info = self->loop_read_buf_info; + self->loop2_read_buf_info = self->loop_read_buf_info; + } else { + // If only once_read_buf has zero length, read loop_read_buf, loop2_read_buf, and repeat last two forever + self->once_read_buf_info = self->loop_read_buf_info; + self->loop_read_buf_info = self->loop2_read_buf_info; + self->loop2_read_buf_info = self->once_read_buf_info; + } + } + } else { + if (!(self->loop_read_buf_info.info.len)) { + // If once_read_buf has nonzero length and loop_read_buf has zero length, read once_read_buf, loop2_read_buf and repeat last buf forever + self->loop_read_buf_info = self->loop2_read_buf_info; + } else { + if (!(self->loop2_read_buf_info.info.len)) { + // If once_read_buf has nonzero length and loop2_read_buf have zero length, read once_read_buf, loop_read_buf and repeat last buf forever + self->loop2_read_buf_info = self->loop_read_buf_info; + + } + } + } + + if (SM_DMA_ALLOCATED_READ(pio_index, sm)) { + if (stride_in_bytes != self->background_stride_in_bytes) { + mp_raise_ValueError(MP_ERROR_TEXT("Mismatched data size")); + } + if (swap != self->byteswap) { + mp_raise_ValueError(MP_ERROR_TEXT("Mismatched swap flag")); + } + + while (self->pending_buffers_read) { + RUN_BACKGROUND_TASKS; + if (self->user_interruptible && mp_hal_is_interrupted()) { + return false; + } + } + + common_hal_mcu_disable_interrupts(); + self->next_read_buf_1 = self->once_read_buf_info; + self->next_read_buf_2 = self->loop_read_buf_info; + self->next_read_buf_3 = self->loop2_read_buf_info; + self->pending_buffers_read = pending_buffers_read; + + if (self->dma_completed_read && self->next_read_buf_1.info.len) { + rp2pio_statemachine_dma_complete_read(self, SM_DMA_GET_CHANNEL_READ(pio_index, sm)); + self->dma_completed_read = false; + } + + common_hal_mcu_enable_interrupts(); + + return true; + } + + int channel_read = dma_claim_unused_channel(false); + if (channel_read == -1) { + return false; + } + SM_DMA_SET_CHANNEL_READ(pio_index, sm, channel_read); + + // set up receive DMA + + volatile uint8_t *rx_source = (volatile uint8_t *)&self->pio->rxf[self->state_machine]; + + self->rx_dreq = pio_get_dreq(self->pio, self->state_machine, false); + + dma_channel_config c_read; + + self->current_read_buf = self->once_read_buf_info; + self->next_read_buf_1 = self->loop_read_buf_info; + self->next_read_buf_2 = self->loop2_read_buf_info; + self->next_read_buf_3 = self->loop_read_buf_info; + + self->pending_buffers_read = pending_buffers_read; + self->dma_completed_read = false; + + self->background_stride_in_bytes = stride_in_bytes; + self->byteswap = swap; + + c_read = dma_channel_get_default_config(channel_read); + channel_config_set_transfer_data_size(&c_read, _stride_to_dma_size(stride_in_bytes)); + channel_config_set_dreq(&c_read, self->rx_dreq); + channel_config_set_read_increment(&c_read, false); + channel_config_set_write_increment(&c_read, true); + channel_config_set_bswap(&c_read, swap); + dma_channel_configure(channel_read, &c_read, + self->once_read_buf_info.info.buf, + rx_source, + self->once_read_buf_info.info.len / stride_in_bytes, + false); + + common_hal_mcu_disable_interrupts(); + MP_STATE_PORT(background_pio_read)[channel_read] = self; + rp2pio_dma_enable_irq(channel_read); + dma_start_channel_mask((1u << channel_read)); + common_hal_mcu_enable_interrupts(); + + return true; +} + +void rp2pio_statemachine_dma_complete_read(rp2pio_statemachine_obj_t *self, int channel_read) { + + self->current_read_buf = self->next_read_buf_1; + self->next_read_buf_1 = self->next_read_buf_2; + self->next_read_buf_2 = self->next_read_buf_3; + self->next_read_buf_3 = self->next_read_buf_1; + + if (self->current_read_buf.info.buf) { + if (self->pending_buffers_read > 0) { + self->pending_buffers_read--; + } + dma_channel_set_write_addr(channel_read, self->current_read_buf.info.buf, false); + dma_channel_set_trans_count(channel_read, self->current_read_buf.info.len / self->background_stride_in_bytes, true); + } else { + self->dma_completed_read = true; + self->pending_buffers_read = 0; // should be a no-op + } + + self->switched_read_buffers = true; +} + +bool common_hal_rp2pio_statemachine_stop_background_read(rp2pio_statemachine_obj_t *self) { + uint8_t pio_index = pio_get_index(self->pio); + uint8_t sm = self->state_machine; + rp2pio_statemachine_clear_dma_read(pio_index, sm); + memset(&self->current_read_buf, 0, sizeof(self->current_read_buf)); + memset(&self->next_read_buf_1, 0, sizeof(self->next_read_buf_1)); + memset(&self->next_read_buf_2, 0, sizeof(self->next_read_buf_2)); + memset(&self->next_read_buf_3, 0, sizeof(self->next_read_buf_3)); + self->pending_buffers_read = 0; + return true; +} + +void common_hal_rp2pio_statemachine_set_read_buffers_raw(rp2pio_statemachine_obj_t *self, + void *once, size_t once_len, + void *loop, size_t loop_len, + void *loop2, size_t loop2_len) { + memset(&self->once_read_buf_info, 0, sizeof(self->once_read_buf_info)); + memset(&self->loop_read_buf_info, 0, sizeof(self->loop_read_buf_info)); + memset(&self->loop2_read_buf_info, 0, sizeof(self->loop2_read_buf_info)); + if (once && once_len) { + self->once_read_buf_info.info.buf = once; + self->once_read_buf_info.info.len = once_len; + } + if (loop && loop_len) { + self->loop_read_buf_info.info.buf = loop; + self->loop_read_buf_info.info.len = loop_len; + } + if (loop2 && loop2_len) { + self->loop2_read_buf_info.info.buf = loop2; + self->loop2_read_buf_info.info.len = loop2_len; + } +} + +int common_hal_rp2pio_statemachine_get_read_dma_channel(rp2pio_statemachine_obj_t *self) { + uint8_t pio_index = pio_get_index(self->pio); + uint8_t sm = self->state_machine; + if (!SM_DMA_ALLOCATED_READ(pio_index, sm)) { + return -1; + } + return SM_DMA_GET_CHANNEL_READ(pio_index, sm); +} + +bool common_hal_rp2pio_statemachine_get_reading(rp2pio_statemachine_obj_t *self) { + return !self->dma_completed_read; +} + +int common_hal_rp2pio_statemachine_get_pending_read(rp2pio_statemachine_obj_t *self) { + return self->pending_buffers_read; } int common_hal_rp2pio_statemachine_get_offset(rp2pio_statemachine_obj_t *self) { @@ -1149,7 +1686,7 @@ int common_hal_rp2pio_statemachine_get_offset(rp2pio_statemachine_obj_t *self) { int common_hal_rp2pio_statemachine_get_pc(rp2pio_statemachine_obj_t *self) { uint8_t pio_index = pio_get_index(self->pio); - PIO pio = pio_instances[pio_index]; + PIO pio = pio_get_instance(pio_index); uint8_t sm = self->state_machine; return pio_sm_get_pc(pio, sm); } @@ -1163,7 +1700,24 @@ mp_obj_t common_hal_rp2pio_statemachine_get_rxfifo(rp2pio_statemachine_obj_t *se return mp_const_none; } +mp_obj_t common_hal_rp2pio_statemachine_get_last_read(rp2pio_statemachine_obj_t *self) { + if (self->switched_read_buffers) { + self->switched_read_buffers = false; + return self->next_read_buf_1.obj; + } + return mp_const_empty_bytes; +} + +mp_obj_t common_hal_rp2pio_statemachine_get_last_write(rp2pio_statemachine_obj_t *self) { + if (self->switched_write_buffers) { + self->switched_write_buffers = false; + return self->next_write_buf_1.obj; + } + return mp_const_empty_bytes; +} + // Use a compile-time constant for MP_REGISTER_POINTER so the preprocessor will // not split the expansion across multiple lines. -MP_REGISTER_ROOT_POINTER(mp_obj_t background_pio[enum_NUM_DMA_CHANNELS]); +MP_REGISTER_ROOT_POINTER(mp_obj_t background_pio_read[enum_NUM_DMA_CHANNELS]); +MP_REGISTER_ROOT_POINTER(mp_obj_t background_pio_write[enum_NUM_DMA_CHANNELS]); diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.h b/ports/raspberrypi/common-hal/rp2pio/StateMachine.h index 16946e4f728..c2007ca1905 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.h +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.h @@ -10,7 +10,81 @@ #include "common-hal/microcontroller/Pin.h" #include "common-hal/memorymap/AddressRange.h" -#include "src/rp2_common/hardware_pio/include/hardware/pio.h" +#include "hardware/pio.h" + +// Shared PIO allocator declarations (rp2pio_statemachine_find_pio, +// rp2pio_statemachine_never_reset, rp2pio_statemachine_reset_ok). Kept in a +// separate, mp-free header so external C++ drivers can include them too. +#include "pio_alloc.h" + +// pio_pinmask_t can hold ANY pin masks, so it is used before selection of gpiobase +#if NUM_BANK0_GPIOS > 32 +typedef struct { uint64_t value; +} pio_pinmask_t; +typedef uint64_t pio_pinmask_value_t; +#define PIO_PINMASK_C(c) UINT64_C(c) +#define PIO_PINMASK_BIT (64) +#define PIO_PINMASK(i) (UINT64_C(1) << (i)) +#define PIO_PINMASK_PRINT(p) mp_printf(&mp_plat_print, \ + "%s:%d: %s = %08x %08x\n", \ + __FILE__, __LINE__, #p, \ + (uint32_t)(PIO_PINMASK_VALUE(p) >> 32), \ + (uint32_t)PIO_PINMASK_VALUE(p)); +#define PIO_PINMASK_ALL PIO_PINMASK_FROM_VALUE(~UINT64_C(0)) +#else +typedef struct { uint32_t value; +} pio_pinmask_t; +typedef uint32_t pio_pinmask_value_t; +#define PIO_PINMASK_C(c) UINT32_C(c) +#define PIO_PINMASK_BIT (32) +#define PIO_PINMASK(i) (UINT32_C(1) << (i)) +#define PIO_PINMASK_PRINT(p) mp_printf(&mp_plat_print, "%s:%d: %s = %08x\n", \ + __FILE__, __LINE__, #p, \ + (uint32_t)(PIO_PINMASK_VALUE(p))); +#define PIO_PINMASK_ALL PIO_PINMASK_FROM_VALUE(~UINT32_C(0)) +#endif +#define PIO_PINMASK_VALUE(p) ((p).value) +#define PIO_PINMASK_FROM_VALUE(v) ((pio_pinmask_t) {(v)}) +#define PIO_PINMASK_FROM_PIN(i) ((pio_pinmask_t) {(PIO_PINMASK(i))}) +#define PIO_PINMASK_NONE PIO_PINMASK_FROM_VALUE(0) +#define PIO_PINMASK_SET(p, i) ((p).value |= PIO_PINMASK(i)) +#define PIO_PINMASK_CLEAR(p, i) ((p).value &= ~PIO_PINMASK(i)) +#define PIO_PINMASK_IS_SET(p, i) (((p).value & PIO_PINMASK(i)) != 0) +#define PIO_PINMASK_BINOP(op, p, q) PIO_PINMASK_FROM_VALUE((p).value op(q).value) +#define PIO_PINMASK_BINOP_ASSIGN(op, p, q) ((p).value op(q).value) +#define PIO_PINMASK_EQUAL(p, q) ((p).value == (q).value) +#define PIO_PINMASK_AND(p, q) PIO_PINMASK_BINOP(&, (p), (q)) +#define PIO_PINMASK_AND_NOT(p, q) PIO_PINMASK_BINOP(&~, (p), (q)) +#define PIO_PINMASK_OR(p, q) PIO_PINMASK_BINOP(|, (p), (q)) +#define PIO_PINMASK_OR3(p, q, r) PIO_PINMASK_OR((p), PIO_PINMASK_OR((q), (r))) +#define PIO_PINMASK_INTERSECT(p, q) PIO_PINMASK_BINOP_ASSIGN( &=, (p), (q)) +#define PIO_PINMASK_DIFFERENCE(p, q) PIO_PINMASK_BINOP_ASSIGN( &= ~, (p), (q)) +#define PIO_PINMASK_MERGE(p, q) PIO_PINMASK_BINOP_ASSIGN( |=, (p), (q)) + +// pio peripheral registers only work 32 bits at a time and depend on the selection of base +// (0 only on RP2040 & RP2350A; 0 or 16 on RP2350B) +typedef struct { uint32_t value32; +} pio_pinmask32_t; +#define PIO_PINMASK32(i) (1u << (i)) +#define PIO_PINMASK32_C(c) UINT32_C(c) +#define PIO_PINMASK32_NONE PIO_PINMASK32_FROM_VALUE(0) +#define PIO_PINMASK32_ALL PIO_PINMASK32_FROM_VALUE(~UINT32_C(0)) +#define PIO_PINMASK32_BASE(i, base) PIO_PINMASK32((i) - (base)) +#define PIO_PINMASK32_VALUE(p) ((p).value32) +#define PIO_PINMASK32_FROM_VALUE(v) ((pio_pinmask32_t) {(v)}) +#define PIO_PINMASK32_SET(p, i) ((p).value32 |= PIO_PINMASK32_VALUE(i)) +#define PIO_PINMASK32_CLEAR(p, i) ((p).value32 &= ~PIO_PINMASK32_VALUE(i)) +#define PIO_PINMASK32_IS_SET(p, i) (((p).value32 & PIO_PINMASK32_VALUE(i)) != 0) +#define PIO_PINMASK32_BINOP(op, p, q) PIO_PINMASK32_FROM_VALUE((p).value32 op(q).value32) +#define PIO_PINMASK32_AND(p, q) PIO_PINMASK32_BINOP(&, (p), (q)) +#define PIO_PINMASK32_AND_NOT(p, q) PIO_PINMASK32_BINOP(&~, (p), (q)) +#define PIO_PINMASK32_OR(p, q) PIO_PINMASK32_BINOP(|, (p), (q)) +#define PIO_PINMASK32_OR3(p, q, r) PIO_PINMASK32_OR((p), PIO_PINMASK32_OR((q), (r))) +#define PIO_PINMASK32_INTERSECT(p, q) PIO_PINMASK32_BINOP( &=, (p), (q)) +#define PIO_PINMASK32_DIFFERENCE(p, q) PIO_PINMASK32_BINOP( &= ~, (p), (q)) +#define PIO_PINMASK32_MERGE(p, q) PIO_PINMASK32_BINOP( |=, (p), (q)) +#define PIO_PINMASK32_FROM_PINMASK_WITH_OFFSET(p, gpio_offset) PIO_PINMASK32_FROM_VALUE(PIO_PINMASK_VALUE((p)) >> (gpio_offset)) +#define PIO_PINMASK_FROM_PINMASK32_WITH_OFFSET(p, gpio_offset) PIO_PINMASK_FROM_VALUE(PIO_PINMASK32_VALUE((p)) << (gpio_offset)) enum { PIO_ANY_OFFSET = -1 }; enum { PIO_FIFO_JOIN_AUTO = -1, PIO_FIFO_TYPE_DEFAULT = PIO_FIFO_JOIN_AUTO }; @@ -22,17 +96,20 @@ typedef struct sm_buf_info { mp_buffer_info_t info; } sm_buf_info; +#define RP2PIO_STATEMACHINE_N_BUFS 3 + typedef struct { mp_obj_base_t base; - uint32_t pins; // Bitmask of what pins this state machine uses. + pio_pinmask32_t pins; // Bitmask of what pins this state machine uses. int state_machine; PIO pio; const uint16_t *init; size_t init_len; - uint32_t initial_pin_state; - uint32_t initial_pin_direction; - uint32_t pull_pin_up; - uint32_t pull_pin_down; + pio_pinmask_t pins_we_own; // Subset of pins that no other state machine had already claimed. + pio_pinmask_t initial_pin_state; + pio_pinmask_t initial_pin_direction; + pio_pinmask_t pull_pin_up; + pio_pinmask_t pull_pin_down; uint tx_dreq; uint rx_dreq; uint32_t actual_frequency; @@ -43,14 +120,29 @@ typedef struct { bool out_shift_right; bool in_shift_right; bool user_interruptible; + #if NUM_BANK0_GPIOS > 32 + uint8_t pio_gpio_offset; + #endif uint8_t offset; uint8_t fifo_depth; // Either 4 if FIFOs are not joined, or 8 if they are. // dma-related items - volatile int pending_buffers; - sm_buf_info current, once, loop; + volatile int pending_buffers_write; + volatile int pending_buffers_read; + int write_buf_index, read_buf_index; + sm_buf_info write_buf[RP2PIO_STATEMACHINE_N_BUFS]; + sm_buf_info read_buf[RP2PIO_STATEMACHINE_N_BUFS]; + + sm_buf_info once_read_buf_info, loop_read_buf_info, loop2_read_buf_info; + sm_buf_info current_read_buf, next_read_buf_1, next_read_buf_2, next_read_buf_3; + sm_buf_info once_write_buf_info, loop_write_buf_info, loop2_write_buf_info; + sm_buf_info current_write_buf, next_write_buf_1, next_write_buf_2, next_write_buf_3; + + bool switched_write_buffers, switched_read_buffers; + int background_stride_in_bytes; - bool dma_completed, byteswap; + bool dma_completed_write, byteswap; + bool dma_completed_read; #if PICO_PIO_VERSION > 0 memorymap_addressrange_obj_t rxfifo_obj; #endif @@ -65,12 +157,12 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, const uint16_t *init, size_t init_len, const mcu_pin_obj_t *first_out_pin, uint8_t out_pin_count, const mcu_pin_obj_t *first_in_pin, uint8_t in_pin_count, - uint32_t pull_pin_up, uint32_t pull_pin_down, + pio_pinmask_t pull_pin_up, pio_pinmask_t pull_pin_down, const mcu_pin_obj_t *first_set_pin, uint8_t set_pin_count, - const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, - uint32_t initial_pin_state, uint32_t initial_pin_direction, + const mcu_pin_obj_t *first_sideset_pin, uint8_t sideset_pin_count, bool sideset_pindirs, + pio_pinmask_t initial_pin_state, pio_pinmask_t initial_pin_direction, const mcu_pin_obj_t *jmp_pin, - uint32_t pins_we_use, bool tx_fifo, bool rx_fifo, + pio_pinmask_t pins_we_use, bool tx_fifo, bool rx_fifo, bool auto_pull, uint8_t pull_threshold, bool out_shift_right, bool wait_for_txstall, bool auto_push, uint8_t push_threshold, bool in_shift_right, @@ -85,11 +177,7 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, uint8_t rp2pio_statemachine_program_offset(rp2pio_statemachine_obj_t *self); void rp2pio_statemachine_deinit(rp2pio_statemachine_obj_t *self, bool leave_pins); -void rp2pio_statemachine_dma_complete(rp2pio_statemachine_obj_t *self, int channel); - -void rp2pio_statemachine_reset_ok(PIO pio, int sm); -void rp2pio_statemachine_never_reset(PIO pio, int sm); - -uint8_t rp2pio_statemachine_find_pio(int program_size, int sm_count); +void rp2pio_statemachine_dma_complete_write(rp2pio_statemachine_obj_t *self, int channel); +void rp2pio_statemachine_dma_complete_read(rp2pio_statemachine_obj_t *self, int channel); extern const mp_obj_type_t rp2pio_statemachine_type; diff --git a/ports/raspberrypi/common-hal/rp2pio/pio_alloc.h b/ports/raspberrypi/common-hal/rp2pio/pio_alloc.h new file mode 100644 index 00000000000..ceb4e31631a --- /dev/null +++ b/ports/raspberrypi/common-hal/rp2pio/pio_alloc.h @@ -0,0 +1,36 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Shared PIO allocator declarations that let external drivers (including the +// vendored C++ PioSdioCard driver) cooperate with CircuitPython's rp2pio PIO +// allocator instead of seizing whole PIO blocks through the raw SDK. The +// definitions live in common-hal/rp2pio/StateMachine.c. This header +// deliberately does NOT include the MicroPython object headers pulled in by the +// full rp2pio StateMachine.h, so it can be included from C++ translation units. +// The declarations are given C linkage for that reason. + +#pragma once + +#include "hardware/pio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// See common-hal/rp2pio/StateMachine.c. Returns a PIO index (0..NUM_PIOS-1) with +// room for program_size instructions and sm_count free state machines, or +// NUM_PIOS if none qualifies. +uint8_t rp2pio_statemachine_find_pio(int program_size, int sm_count); + +// Mark / unmark a state machine as surviving (or not) a soft reset, so +// rp2pio's reset path keeps its bookkeeping coherent with the SMs a driver +// claims directly. +void rp2pio_statemachine_never_reset(PIO pio, int sm); +void rp2pio_statemachine_reset_ok(PIO pio, int sm); + +#ifdef __cplusplus +} +#endif diff --git a/ports/raspberrypi/common-hal/rtc/RTC.c b/ports/raspberrypi/common-hal/rtc/RTC.c index 3bdf599d270..67935502ad3 100644 --- a/ports/raspberrypi/common-hal/rtc/RTC.c +++ b/ports/raspberrypi/common-hal/rtc/RTC.c @@ -11,8 +11,8 @@ #include "py/runtime.h" #include "shared/timeutils/timeutils.h" -#include "src/common/pico_util/include/pico/util/datetime.h" -#include "src/rp2_common/pico_aon_timer/include/pico/aon_timer.h" +#include "pico/util/datetime.h" +#include "pico/aon_timer.h" void common_hal_rtc_init(void) { // We start the RTC at 0 which mark as January 1, 2000. diff --git a/ports/raspberrypi/common-hal/sdioio/SDCard.c b/ports/raspberrypi/common-hal/sdioio/SDCard.c new file mode 100644 index 00000000000..04b78dbc4d2 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/SDCard.c @@ -0,0 +1,260 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "common-hal/sdioio/SDCard.h" +#include "common-hal/sdioio/sdfat_pio/shim.h" + +#include "extmod/vfs.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/sdioio/SDCard.h" +#include "shared-bindings/util.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "hardware/platform_defs.h" // NUM_PIOS + +// Live-instance tracking for soft-reset cleanup. The vendored SdFat PIO driver +// claims its PIO block through the raw SDK (pio_claim_unused_sm), whose claim +// bitset lives in static RAM and survives a soft reboot. Because the GC heap is +// wiped without running finalizers, a successfully-constructed card would leak +// its whole PIO block on every Ctrl-D (see sdio_init_troubleshooting.md, +// "Error 43 is a PIO-leak red herring"). We keep a static table of the live +// cards so sdioio_reset() can deinit them (→ pioEnd() → SDK unclaim) before the +// heap is reset. A card is registered only after a fully successful construct +// and removed on deinit; each card consumes a whole PIO, so NUM_PIOS slots is a +// hard upper bound. +static sdioio_sdcard_obj_t *_active_cards[NUM_PIOS]; + +static void register_card(sdioio_sdcard_obj_t *self) { + for (size_t i = 0; i < MP_ARRAY_SIZE(_active_cards); i++) { + if (_active_cards[i] == NULL) { + _active_cards[i] = self; + return; + } + } +} + +static void unregister_card(sdioio_sdcard_obj_t *self) { + for (size_t i = 0; i < MP_ARRAY_SIZE(_active_cards); i++) { + if (_active_cards[i] == self) { + _active_cards[i] = NULL; + return; + } + } +} + +// Maximum SD clock the PIO driver is allowed to be asked for. At a typical +// 150 MHz clk_sys the driver tops out near 37.5 MHz (clkDiv == 1); the cap is +// generous and the achieved rate is reported back through the `frequency` +// property. +#define SDIO_MAX_FREQUENCY (50000000) + +void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *command, + uint8_t num_data, const mcu_pin_obj_t **data, uint32_t frequency) { + // The vendored PIO driver only supports 4-bit mode and requires the four + // data lines to be on consecutive GPIOs (DAT0..DAT3). + if (num_data != 4) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Number of data_pins must be %d, not %d"), 4, num_data); + } + for (size_t i = 1; i < num_data; i++) { + if (data[i]->number != data[0]->number + i) { + mp_raise_ValueError(MP_ERROR_TEXT("Data pins must be consecutive")); + } + } + + mp_arg_validate_int_max(frequency, SDIO_MAX_FREQUENCY, MP_QSTR_frequency); + + self->num_data = num_data; + self->clock = clock->number; + self->command = command->number; + for (size_t i = 0; i < num_data; i++) { + self->data[i] = data[i]->number; + } + + claim_pin(clock); + claim_pin(command); + for (size_t i = 0; i < num_data; i++) { + claim_pin(data[i]); + } + + sdfat_pio_card_new(&self->card); + uint32_t actual_frequency = 0; + bool ok = sdfat_pio_card_begin(&self->card, clock->number, command->number, + data[0]->number, frequency, &actual_frequency); + if (!ok) { + // The driver's error code identifies the SD command/phase that failed + // (see SdCardInfo.h SD_CARD_ERROR_* codes). + uint8_t error_code = sdfat_pio_card_error_code(&self->card); + sdfat_pio_card_end(&self->card); + sdfat_pio_card_free(&self->card); + reset_pin_number(self->clock); + reset_pin_number(self->command); + for (size_t i = 0; i < num_data; i++) { + reset_pin_number(self->data[i]); + } + self->command = COMMON_HAL_MCU_NO_PIN; + mp_raise_OSError_msg_varg( + MP_ERROR_TEXT("SDIO Init Error 0x%02x"), error_code); + } + + self->frequency = actual_frequency; + self->capacity = sdfat_pio_card_sector_count(&self->card); + + // Track the live card so sdioio_reset() can release its leaked PIO block on + // the next soft reboot. + register_card(self); +} + +uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t *self) { + return self->capacity; +} + +uint32_t common_hal_sdioio_sdcard_get_frequency(sdioio_sdcard_obj_t *self) { + return self->frequency; +} + +uint8_t common_hal_sdioio_sdcard_get_width(sdioio_sdcard_obj_t *self) { + return self->num_data; +} + +static void check_for_deinit(sdioio_sdcard_obj_t *self) { + if (common_hal_sdioio_sdcard_deinited(self)) { + raise_deinited_error(); + } +} + +static void check_whole_block(mp_buffer_info_t *bufinfo) { + if (bufinfo->len % 512) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Buffer must be a multiple of %d bytes"), 512); + } +} + +// Native function for the VFS blockdev layer. The PIO driver is synchronous and +// polling, so these block until the transfer completes. +mp_negative_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!sdfat_pio_card_read_sectors(&self->card, start_block, buf, num_blocks)) { + return -MP_EIO; + } + return 0; +} + +mp_negative_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!sdfat_pio_card_write_sectors(&self->card, start_block, buf, num_blocks)) { + return -MP_EIO; + } + return 0; +} + +mp_negative_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + check_for_deinit(self); + check_whole_block(bufinfo); + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +mp_negative_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + check_for_deinit(self); + check_whole_block(bufinfo); + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer. +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed. + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors. + return true; + + default: + return false; // Unsupported command. + } +} + +bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { + // Only 4-bit mode is supported (see construct); reject a request for any + // other width. Reconfiguring the clock at runtime is not implemented yet, + // so the frequency argument is accepted but ignored. + if (bits != 0 && bits != self->num_data) { + return false; + } + return true; +} + +bool common_hal_sdioio_sdcard_deinited(sdioio_sdcard_obj_t *self) { + return self->command == COMMON_HAL_MCU_NO_PIN; +} + +void common_hal_sdioio_sdcard_deinit(sdioio_sdcard_obj_t *self) { + if (common_hal_sdioio_sdcard_deinited(self)) { + return; + } + + unregister_card(self); + + sdfat_pio_card_end(&self->card); + sdfat_pio_card_free(&self->card); + + reset_pin_number(self->command); + self->command = COMMON_HAL_MCU_NO_PIN; + reset_pin_number(self->clock); + self->clock = COMMON_HAL_MCU_NO_PIN; + for (size_t i = 0; i < self->num_data; i++) { + reset_pin_number(self->data[i]); + self->data[i] = COMMON_HAL_MCU_NO_PIN; + } +} + +void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self) { + if (common_hal_sdioio_sdcard_deinited(self)) { + return; + } + + self->never_reset = true; + + never_reset_pin_number(self->command); + never_reset_pin_number(self->clock); + for (size_t i = 0; i < self->num_data; i++) { + never_reset_pin_number(self->data[i]); + } + + // Also protect the PIO state machines the driver claimed so the rp2pio + // soft-reset path keeps its never-reset bookkeeping coherent with them. + sdfat_pio_card_never_reset(&self->card); +} + +void sdioio_reset(void) { + // Release every live card that isn't protected by never_reset. deinit() + // runs pioEnd(), which unclaims the PIO at the SDK level. + for (size_t i = 0; i < MP_ARRAY_SIZE(_active_cards); i++) { + sdioio_sdcard_obj_t *self = _active_cards[i]; + if (self == NULL || self->never_reset) { + continue; + } + // deinit() calls unregister_card(), clearing this slot. + common_hal_sdioio_sdcard_deinit(self); + } +} diff --git a/ports/raspberrypi/common-hal/sdioio/SDCard.h b/ports/raspberrypi/common-hal/sdioio/SDCard.h new file mode 100644 index 00000000000..a4dca731f73 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/SDCard.h @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/sdioio/sdfat_pio/shim.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // In-place storage for the vendored C++ PioSdioCard instance, constructed + // and torn down through the extern "C" shim in sdfat_pio/. + sdioio_pio_card_storage_t card; + uint32_t frequency; + uint32_t capacity; // Number of 512-byte blocks. + uint8_t num_data; + uint8_t command; + uint8_t clock; + uint8_t data[4]; + bool never_reset; +} sdioio_sdcard_obj_t; + +// Called by the supervisor on soft reset to release any card that is not +// protected with never_reset. +void sdioio_reset(void); diff --git a/ports/raspberrypi/common-hal/sdioio/__init__.c b/ports/raspberrypi/common-hal/sdioio/__init__.c new file mode 100644 index 00000000000..4a92fca8794 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/__init__.c @@ -0,0 +1,8 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// No sdioio module functions. The whole API lives on sdioio.SDCard, which is +// implemented in SDCard.c. diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/DbgLog.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/DbgLog.h new file mode 100644 index 00000000000..8d1ba8db85a --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/DbgLog.h @@ -0,0 +1,41 @@ +/** + * Copyright (c) 2011-2025 Bill Greiman, 2026 Tim Cocks for Adafruit Industries + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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. + */ +/** + * \file + * \brief Classes for Debug messages. + * + * CircuitPython vendored, trimmed copy. The upstream DbgLog.h includes the + * Arduino Printable.h and defines a family of helper print classes (Bin, Hex, + * Num, Dbl, logmsg...). Those are only referenced when debug output is enabled + * (ENABLE_DBG_MSG / USE_DEBUG_MODE), which it is not in this build, so they are + * omitted to keep the Arduino Print dependency out of the firmware. Only the + * no-op DBG_MSG() macro that PioSdioCard.cpp uses on its normal paths remains. + */ +#pragma once + +/** Debug messages are disabled in the CircuitPython build. */ +#define DBG_MSG(...) \ + do { \ + } while (0) diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.cpp b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.cpp new file mode 100644 index 00000000000..f91515ccef2 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.cpp @@ -0,0 +1,1026 @@ +/** + * Copyright (c) 2011-2025 Bill Greiman, 2026 Tim Cocks for Adafruit Industries + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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. + */ +#ifdef ARDUINO_ARCH_RP2040 +#include + +#include // Required for std::max, std::min +#define DEBUG_FILE "PioSdioCard.cpp" +#include "../SdCardInfo.h" +#include "DbgLog.h" +#include "PioSdioCard.h" +#include "PioSdioCard.pio.h" +// CIRCUITPY-CHANGE: cooperate with CircuitPython's rp2pio PIO allocator +#include "common-hal/rp2pio/pio_alloc.h" +//------------------------------------------------------------------------------ +// USE_DEBUG_MODE 0 - no debug, 1 - print message, 2 - Use scope/analyzer. +#define USE_DEBUG_MODE 0 + +const uint PIO_CLK_DIV_RUN = 1; + +const uint PIN_SDIO_UNDEFINED = 63u; + +const uint DAT_FIFO_DEPTH = 8; +//============================================================================== +// Command definitions. +enum { RSP_R0 = 0, RSP_R1 = 1, RSP_R2 = 2, RSP_R3 = 3, RSP_R6 = 6, RSP_R7 = 7 }; +static const CmdRsp_t CMD0_R0(CMD0, RSP_R0); +static const CmdRsp_t CMD2_R2(CMD2, RSP_R2); +static const CmdRsp_t CMD3_R6(CMD3, RSP_R6); +static const CmdRsp_t CMD6_R1(CMD6, RSP_R1); +static const CmdRsp_t CMD7_R1(CMD7, RSP_R1); +static const CmdRsp_t CMD8_R7(CMD8, RSP_R7); +static const CmdRsp_t CMD9_R2(CMD9, RSP_R2); +static const CmdRsp_t CMD10_R2(CMD10, RSP_R2); +static const CmdRsp_t CMD12_R1(CMD12, RSP_R1); +static const CmdRsp_t CMD13_R1(CMD13, RSP_R1); +static const CmdRsp_t CMD18_R1(CMD18, RSP_R1); +static const CmdRsp_t CMD25_R1(CMD25, RSP_R1); +static const CmdRsp_t CMD32_R1(CMD32, RSP_R1); +static const CmdRsp_t CMD33_R1(CMD33, RSP_R1); +static const CmdRsp_t CMD38_R1(CMD38, RSP_R1); +static const CmdRsp_t CMD55_R1(CMD55, RSP_R1); +static const CmdRsp_t ACMD6_R1(ACMD6, RSP_R1); +static const CmdRsp_t ACMD13_R1(ACMD13, RSP_R1); +static const CmdRsp_t ACMD41_R3(ACMD41, RSP_R3); +static const CmdRsp_t ACMD51_R1(ACMD51, RSP_R1); +//============================================================================== +class Timeout { + public: + explicit Timeout(uint ms) : _usStart(0), _usTimeout(1000 * ms) {} + bool timedOut() { + if (_usStart) { + return (usSinceBoot() - _usStart) > _usTimeout; + } + _usStart = usSinceBoot(); + return false; + } + uint32_t usSinceBoot() { return to_us_since_boot(get_absolute_time()); } + uint32_t _usStart; + uint32_t _usTimeout; +}; +//============================================================================== +#if USE_DEBUG_MODE +//------------------------------------------------------------------------------ +static inline void gpioStatus(uint gpio) { + logmsgln("gpio", gpio, " drive: ", gpio_get_drive_strength(gpio)); + // logmsgln("gpio", gpio, + // " drive: ", static_cast(gpio_get_drive_strength(gpio))); + logmsgln("gpio", gpio, " slew: ", gpio_get_slew_rate(gpio)); + logmsgln("gpio", gpio, " hyst: ", gpio_is_input_hysteresis_enabled(gpio)); + logmsgln("gpio", gpio, " pull: ", gpio_is_pulled_up(gpio)); +} +//------------------------------------------------------------------------------ +static inline void pioRegs(PIO pio) { + logmsgln("ctrl: 0b", Bin(pio->ctrl)); + logmsgln("fstat: 0b", Bin(pio->fstat)); + logmsgln("fdebug: 0b", Bin(pio->fdebug)); + logmsgln("flevel: 0b", Bin(pio->flevel)); + logmsgln("padout: 0b", Bin(pio->dbg_padout)); + logmsgln("padoe: 0b", Bin(pio->dbg_padoe)); + logmsgln("cfginfo: 0x", Hex(pio->dbg_cfginfo)); + logmsgln("sync_bypass: 0b", Bin(pio->input_sync_bypass)); +} +//------------------------------------------------------------------------------ +static inline void pioSmRegs(PIO pio, uint sm) { + logmsgln("sm", sm, " clkdiv: 0x", Hex(pio->sm[sm].clkdiv)); + logmsgln("sm", sm, " execctrl: 0x", Hex(pio->sm[sm].execctrl)); + logmsgln("sm", sm, " shiftctrl: 0x", Hex(pio->sm[sm].shiftctrl)); + logmsgln("sm", sm, " addr: 0x", Hex(pio->sm[sm].addr)); + logmsgln("sm", sm, " pinctrl: 0x", Hex(pio->sm[sm].pinctrl)); +} +//------------------------------------------------------------------------------ +#endif // USE_DEBUG_MODE +#define sdError(code) \ + { \ + setSdErrorCode(code, __LINE__); \ + DBG_MSG(#code); \ + } +#define SDIO_FAIL() DBG_MSG("SDIO_FAIL") +//============================================================================== +// CRC functions. +//------------------------------------------------------------------------------ +// See this library's extras folder. +static const uint8_t crc7_table[256] = { + 0x00, 0x12, 0x24, 0x36, 0x48, 0x5a, 0x6c, 0x7e, // 00 - 07 + 0x90, 0x82, 0xb4, 0xa6, 0xd8, 0xca, 0xfc, 0xee, // 08 - 0f + 0x32, 0x20, 0x16, 0x04, 0x7a, 0x68, 0x5e, 0x4c, // 10 - 17 + 0xa2, 0xb0, 0x86, 0x94, 0xea, 0xf8, 0xce, 0xdc, // 18 - 1f + 0x64, 0x76, 0x40, 0x52, 0x2c, 0x3e, 0x08, 0x1a, // 20 - 27 + 0xf4, 0xe6, 0xd0, 0xc2, 0xbc, 0xae, 0x98, 0x8a, // 28 - 2f + 0x56, 0x44, 0x72, 0x60, 0x1e, 0x0c, 0x3a, 0x28, // 30 - 37 + 0xc6, 0xd4, 0xe2, 0xf0, 0x8e, 0x9c, 0xaa, 0xb8, // 38 - 3f + 0xc8, 0xda, 0xec, 0xfe, 0x80, 0x92, 0xa4, 0xb6, // 40 - 47 + 0x58, 0x4a, 0x7c, 0x6e, 0x10, 0x02, 0x34, 0x26, // 48 - 4f + 0xfa, 0xe8, 0xde, 0xcc, 0xb2, 0xa0, 0x96, 0x84, // 50 - 57 + 0x6a, 0x78, 0x4e, 0x5c, 0x22, 0x30, 0x06, 0x14, // 58 - 5f + 0xac, 0xbe, 0x88, 0x9a, 0xe4, 0xf6, 0xc0, 0xd2, // 60 - 67 + 0x3c, 0x2e, 0x18, 0x0a, 0x74, 0x66, 0x50, 0x42, // 68 - 6f + 0x9e, 0x8c, 0xba, 0xa8, 0xd6, 0xc4, 0xf2, 0xe0, // 70 - 77 + 0x0e, 0x1c, 0x2a, 0x38, 0x46, 0x54, 0x62, 0x70, // 78 - 7f + 0x82, 0x90, 0xa6, 0xb4, 0xca, 0xd8, 0xee, 0xfc, // 80 - 87 + 0x12, 0x00, 0x36, 0x24, 0x5a, 0x48, 0x7e, 0x6c, // 88 - 8f + 0xb0, 0xa2, 0x94, 0x86, 0xf8, 0xea, 0xdc, 0xce, // 90 - 97 + 0x20, 0x32, 0x04, 0x16, 0x68, 0x7a, 0x4c, 0x5e, // 98 - 9f + 0xe6, 0xf4, 0xc2, 0xd0, 0xae, 0xbc, 0x8a, 0x98, // a0 - a7 + 0x76, 0x64, 0x52, 0x40, 0x3e, 0x2c, 0x1a, 0x08, // a8 - af + 0xd4, 0xc6, 0xf0, 0xe2, 0x9c, 0x8e, 0xb8, 0xaa, // b0 - b7 + 0x44, 0x56, 0x60, 0x72, 0x0c, 0x1e, 0x28, 0x3a, // b8 - bf + 0x4a, 0x58, 0x6e, 0x7c, 0x02, 0x10, 0x26, 0x34, // c0 - c7 + 0xda, 0xc8, 0xfe, 0xec, 0x92, 0x80, 0xb6, 0xa4, // c8 - cf + 0x78, 0x6a, 0x5c, 0x4e, 0x30, 0x22, 0x14, 0x06, // d0 - d7 + 0xe8, 0xfa, 0xcc, 0xde, 0xa0, 0xb2, 0x84, 0x96, // d8 - df + 0x2e, 0x3c, 0x0a, 0x18, 0x66, 0x74, 0x42, 0x50, // e0 - e7 + 0xbe, 0xac, 0x9a, 0x88, 0xf6, 0xe4, 0xd2, 0xc0, // e8 - ef + 0x1c, 0x0e, 0x38, 0x2a, 0x54, 0x46, 0x70, 0x62, // f0 - f7 + 0x8c, 0x9e, 0xa8, 0xba, 0xc4, 0xd6, 0xe0, 0xf2 // f8 - ff +}; +//------------------------------------------------------------------------------ +inline static uint8_t CRC7(const uint8_t* data, uint8_t n) { + uint8_t crc = 0; + for (uint8_t i = 0; i < n; i++) { + crc = crc7_table[crc ^ data[i]]; + } + return crc | 1; +} +//------------------------------------------------------------------------------ +// Modified from sdio_crc16_4bit_checksum() in +// https://github.com/ZuluSCSI/ZuluSCSI-firmware +// +static inline __attribute__((always_inline)) uint64_t crc16(uint64_t crc, + uint32_t data_in) { + // Shift out 8 bits for each line + uint32_t data_out = crc >> 32; + crc <<= 32; + + // XOR outgoing data to itself with 4 bit delay + data_out ^= (data_out >> 16); + + // XOR incoming data to outgoing data with 4 bit delay + data_out ^= (data_in >> 16); + + // XOR outgoing and incoming data to accumulator at each tap + uint64_t xorred = data_out ^ data_in; + crc ^= xorred; + crc ^= xorred << (5 * 4); + crc ^= xorred << (12 * 4); + return crc; +} +//------------------------------------------------------------------------------ +//============================================================================== +// add to PioSdioCard class int the future. +// PioSdioCard::PioSdioCard() +// PioSdioCard::~PioSdioCard() +//------------------------------------------------------------------------------ +bool PioSdioCard::cardAcmd(uint32_t rca, CmdRsp_t cmdRsp, uint32_t arg) { + return cardCommand(CMD55_R1, rca) && cardCommand(cmdRsp, arg); +} +//------------------------------------------------------------------------------ +bool PioSdioCard::begin(PioSdioConfig sdioConfig) { + pioEnd(); + Timeout timeout(SD_INIT_TIMEOUT); + uint32_t arg; + m_curState = IDLE_STATE; + m_errorCode = SD_CARD_ERROR_NONE; + m_highCapacity = false; + m_initDone = false; + m_version2 = false; + m_clkPin = sdioConfig.clkPin(); + m_cmdPin = sdioConfig.cmdPin(); + m_dat0Pin = sdioConfig.dat0Pin(); + + // Four PIO cycles per SD CLK cycle. + m_clkDiv = ceil((0.00025 * clock_get_hz(clk_sys)) / SD_MAX_INIT_RATE_KHZ); + +#if USE_DEBUG_MODE == 2 + Serial.println(); + pioRegs(m_pio); + pioSmRegs(m_pio, m_sm0); + pioSmRegs(m_pio, m_sm1); + gpioStatus(m_clkPin); + gpioStatus(m_cmdPin); + while (Serial.read() >= 0) { + } + Serial.println("Logic Analyzer on then type any char"); + while (!Serial.available()) { + } +#endif // USE_DEBUG_MODE + // A few cards still require clocks after power-up. + powerUpClockCycles(); + if (!pioInit()) { + goto fail; + } + pioConfig(m_clkDiv); + if (!cardCommand(CMD0_R0, 0)) { + sdError(SD_CARD_ERROR_CMD0); + goto fail; + } + if (cardCommand(CMD8_R7, 0X1AA)) { + if (m_cardRsp != 0X1AA) { + sdError(SD_CARD_ERROR_CMD8); + goto fail; + } + m_version2 = true; + } else { + m_version2 = false; + m_errorCode = SD_CARD_ERROR_NONE; + } + arg = m_version2 ? 0X40300000 : 0x00300000; + while (true) { + if (!cardAcmd(0, ACMD41_R3, arg)) { + sdError(SD_CARD_ERROR_ACMD41); + goto fail; + } + if (m_cardRsp & 0x80000000) { + break; + } + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_ACMD41); + goto fail; + } + } + m_ocr = m_cardRsp; + if (m_cardRsp & 0x40000000) { + // Is high capacity. + m_highCapacity = true; + } + if (!cardCommand(CMD2_R2, 0)) { + sdError(SD_CARD_ERROR_CMD2); + goto fail; + } + if (!cardCommand(CMD3_R6, 0)) { + sdError(SD_CARD_ERROR_CMD3); + goto fail; + } + m_rca = m_cardRsp & 0xFFFF0000; + if (!cardCommand(CMD9_R2, m_rca, &m_csd)) { + sdError(SD_CARD_ERROR_CMD9); + goto fail; + } + if (!cardCommand(CMD10_R2, m_rca, &m_cid)) { + sdError(SD_CARD_ERROR_CMD10); + goto fail; + } + if (!cardCommand(CMD7_R1, m_rca)) { + sdError(SD_CARD_ERROR_CMD7); + goto fail; + } + + if (!cardAcmd(m_rca, ACMD6_R1, 2)) { + sdError(SD_CARD_ERROR_ACMD6); + goto fail; + } + m_clkDiv = sdioConfig.clkDiv(); + pioConfig(m_clkDiv); + if (!cardAcmd(m_rca, ACMD51_R1, 0)) { + sdError(SD_CARD_ERROR_ACMD51); + goto fail; + } + if (!readData(&m_scr, sizeof(m_scr))) { + DBG_MSG("readData"); + goto fail; + } + if (!cardAcmd(m_rca, ACMD13_R1, 0)) { + sdError(SD_CARD_ERROR_ACMD13); + SDIO_FAIL(); + goto fail; + } + + if (!readData(&m_sds, sizeof(m_sds))) { + SDIO_FAIL(); + goto fail; + } + m_initDone = true; + + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::cardCMD6(uint32_t arg, uint8_t* status) { + if (!cardCommand(CMD6_R1, arg)) { + sdError(SD_CARD_ERROR_CMD6); + goto fail; + } + if (!readData(status, 64)) { + SDIO_FAIL(); + goto fail; + } + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::cardCommand(CmdRsp_t cmd, uint32_t arg, void* rsp) { + uint8_t buf[6]; + uint nRsp = cmd.rsp == RSP_R0 ? 0 : cmd.rsp == RSP_R2 ? 17 : 6; + const io_ro_8* rxFifo = reinterpret_cast(&m_pio->rxf[m_sm0]); + io_wo_8* txFifo = reinterpret_cast(&m_pio->txf[m_sm0]); + pio_sm_set_enabled(m_pio, m_sm1, false); + pio_sm_init(m_pio, m_sm0, m_cmdRspOffset, &m_cmdConfig); + pio_sm_exec(m_pio, m_sm0, pio_encode_set(pio_pindirs, 1)); + *txFifo = 55; + pio_sm_exec(m_pio, m_sm0, pio_encode_out(pio_x, 8)); + *txFifo = nRsp ? 8 * nRsp - 1 : 0; + pio_sm_exec(m_pio, m_sm0, pio_encode_out(pio_y, 8)); + pio_sm_set_enabled(m_pio, m_sm0, true); + uint n = 0; + buf[n++] = (uint8_t)(cmd.idx | 0x40); + buf[n++] = (uint8_t)(arg >> 24U); + buf[n++] = (uint8_t)(arg >> 16U); + buf[n++] = (uint8_t)(arg >> 8U); + buf[n++] = (uint8_t)arg; + buf[n++] = CRC7(buf, 5); + *txFifo = 0XFF; + for (uint i = 0; i < n; i++) { + while (pio_sm_is_tx_fifo_full(m_pio, m_sm0)) { + } + *txFifo = buf[i]; + } + + Timeout timeout(SD_CMD_TIMEOUT); + if (!nRsp) { + uint32_t fdebug_tx_stall = 1u << (PIO_FDEBUG_TXSTALL_LSB + m_sm0); + m_pio->fdebug = fdebug_tx_stall; + while (!(m_pio->fdebug & fdebug_tx_stall)) { + if (timeout.timedOut()) { + goto fail; + } + } + goto done; + } + uint8_t rtn[20]; + + for (uint i = 0; i < nRsp; i++) { + while (pio_sm_is_rx_fifo_empty(m_pio, m_sm0)) { + if (timeout.timedOut()) { + goto fail; + } + } + rtn[i] = *rxFifo; + } + if (cmd.rsp == RSP_R3) { + if (rtn[0] != 0X3F || rtn[5] != 0XFF) { + goto fail; + } + } else { + uint8_t crc; + if (cmd.rsp == RSP_R2) { + crc = CRC7(rtn + 1, nRsp - 2); + } else { + crc = CRC7(rtn, nRsp - 1); + } + if (rtn[nRsp - 1] != crc) { +#if USE_DEBUG_MODE + Serial.printf("CHK: %02X, CRC: %02X\n", rtn[nRsp - 1], crc); + for (uint i = 0; i < nRsp; i++) { + Serial.printf(" %02X", rtn[i]); + } + Serial.println(); +#endif // USE_DEBUG_MODE + sdError(SD_CARD_ERROR_READ_CRC); + goto fail; + } + } + if (nRsp == 6) { + m_cardRsp = (rtn[1] << 24) | (rtn[2] << 16) | (rtn[3] << 8) | rtn[4]; + if (rsp) { + *reinterpret_cast(rsp) = m_cardRsp; + } + } else if (rsp && nRsp == 17) { + memcpy(rsp, rtn + 1, 16); + } + +done: + pio_sm_set_enabled(m_pio, m_sm0, false); + return true; + +fail: +#if USE_DEBUG_MODE + DBG_MSG("CMD", cmd.idx, " failed"); +#endif // USE_DEBUG_MODE + pio_sm_set_enabled(m_pio, m_sm0, false); + return false; +} +//------------------------------------------------------------------------------ +void PioSdioCard::end() { pioEnd(); } +//------------------------------------------------------------------------------ +void PioSdioCard::neverReset() { + if (!m_pio) { + return; + } + if (m_sm0 >= 0) { + rp2pio_statemachine_never_reset(m_pio, m_sm0); + } + if (m_sm1 >= 0) { + rp2pio_statemachine_never_reset(m_pio, m_sm1); + } +} +//------------------------------------------------------------------------------ +bool PioSdioCard::erase(uint32_t firstSector, uint32_t lastSector) { + Timeout timeout(SD_ERASE_TIMEOUT); + if (!syncDevice()) { + SDIO_FAIL(); + goto fail; + } + // check for single sector erase + if (!m_csd.eraseSingleBlock()) { + // erase size mask + uint8_t m = m_csd.eraseSize() - 1; + if ((firstSector & m) != 0 || ((lastSector + 1) & m) != 0) { + // error card can't erase specified area + sdError(SD_CARD_ERROR_ERASE_SINGLE_SECTOR); + goto fail; + } + } + if (!m_highCapacity) { + firstSector <<= 9; + lastSector <<= 9; + } + if (!cardCommand(CMD32_R1, firstSector)) { + sdError(SD_CARD_ERROR_CMD32); + goto fail; + } + if (!cardCommand(CMD33_R1, lastSector)) { + sdError(SD_CARD_ERROR_CMD33); + goto fail; + } + if (!cardCommand(CMD38_R1, 0)) { + sdError(SD_CARD_ERROR_CMD38); + goto fail; + } + while (isBusy()) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_ERASE_TIMEOUT); + goto fail; + } + } + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +uint8_t PioSdioCard::errorCode() const { return m_errorCode; } +//------------------------------------------------------------------------------ +uint32_t PioSdioCard::errorData() const { return m_cardRsp; } +//------------------------------------------------------------------------------ +uint32_t PioSdioCard::errorLine() const { return m_errorLine; } +//------------------------------------------------------------------------------ +bool PioSdioCard::isBusy() { + return gpio_get(m_dat0Pin) ? false : !(status() & CARD_STATUS_READY_FOR_DATA); +} +//------------------------------------------------------------------------------ +void PioSdioCard::pioConfig(float clkDiv) { + m_cmdConfig = + pio_cmd_rsp_program_config(m_cmdRspOffset, m_cmdPin, m_clkPin, clkDiv); + m_rdClkConfig = + pio_rd_clk_program_config(m_rdClkOffset, m_dat0Pin, m_clkPin, clkDiv); + m_rdDataConfig = + pio_rd_data_program_config(m_rdDataOffset, m_dat0Pin, clkDiv); + m_wrDataConfig = + pio_wr_data_program_config(m_wrDataOffset, m_dat0Pin, m_clkPin, clkDiv); + m_wrRespConfig = + pio_wr_resp_program_config(m_wrRespOffset, m_dat0Pin, m_clkPin, clkDiv); +} +//------------------------------------------------------------------------------ +void PioSdioCard::pioEnd() { + if (!m_pio) { + return; + } + // CIRCUITPY-CHANGE: release only the two state machines we claimed (see + // pioInit) rather than every SM on the block, and clear their rp2pio + // never-reset flag so a later reuse of the same SM number by rp2pio is not + // wrongly protected across a soft reset. + if (m_sm0 >= 0) { + pio_sm_set_enabled(m_pio, m_sm0, false); + rp2pio_statemachine_reset_ok(m_pio, m_sm0); + pio_sm_unclaim(m_pio, m_sm0); + m_sm0 = -1; + } + if (m_sm1 >= 0) { + pio_sm_set_enabled(m_pio, m_sm1, false); + rp2pio_statemachine_reset_ok(m_pio, m_sm1); + pio_sm_unclaim(m_pio, m_sm1); + m_sm1 = -1; + } + if (m_cmdRspOffset >= 0) { + pio_remove_program(m_pio, &cmd_rsp_program, m_cmdRspOffset); + m_cmdRspOffset = -1; + } + if (m_rdClkOffset >= 0) { + pio_remove_program(m_pio, &rd_clk_program, m_rdClkOffset); + m_rdClkOffset = -1; + } + if (m_rdDataOffset >= 0) { + pio_remove_program(m_pio, &rd_data_program, m_rdDataOffset); + m_rdDataOffset = -1; + } + if (m_wrDataOffset >= 0) { + pio_remove_program(m_pio, &wr_data_program, m_wrDataOffset); + m_wrDataOffset = -1; + } + if (m_wrRespOffset >= 0) { + pio_remove_program(m_pio, &wr_resp_program, m_wrRespOffset); + m_wrRespOffset = -1; + } + m_pio = nullptr; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::pioInit() { + uint pin[] = {m_clkPin, m_cmdPin, m_dat0Pin, + m_dat0Pin + 1, m_dat0Pin + 2, m_dat0Pin + 3}; + // CIRCUITPY-CHANGE: the PIO's gpio_base (0 or 16). input_sync_bypass bits are + // relative to this base, so it must be subtracted from the raw GPIO numbers + // below (a raw `1 << pin` is UB for pins >= 32, e.g. Fruit Jam's GPIO34-39, + // and silently becomes a no-op on Cortex-M). Declared before the first goto so + // the error paths don't bypass its initialization. + uint gpio_base = 0; + // Declared before the first goto for the same reason as gpio_base. + uint pio_index = 0; + uint16_t pio_instructions[PIO_INSTRUCTION_COUNT]; + pio_program_t pio_program = {.instructions = nullptr, + .length = PIO_INSTRUCTION_COUNT, + .origin = -1, + .pio_version = 0, +#if PICO_PIO_VERSION > 0 + .used_gpio_ranges = 0x0 +#endif + }; + // CIRCUITPY-CHANGE: pick a PIO through CircuitPython's rp2pio allocator and + // claim only the two state machines this driver uses, rather than seizing an + // entire PIO block via the raw SDK. This lets sdioio coexist with rp2pio and + // other PIO users. The five programs total total_pio_length (31) instructions, + // so this effectively requires an empty PIO; find_pio enforces that, which in + // turn guarantees the chosen PIO has no other user whose gpio_base the + // pio_set_gpio_base() call below could disturb. + pio_index = rp2pio_statemachine_find_pio(total_pio_length, 2); + if (pio_index >= NUM_PIOS) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + m_pio = pio_get_instance(pio_index); + m_sm0 = pio_claim_unused_sm(m_pio, false); + m_sm1 = pio_claim_unused_sm(m_pio, false); + if (m_sm0 < 0 || m_sm1 < 0) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } +#if PICO_PIO_USE_GPIO_BASE + if (std::max({m_clkPin, m_cmdPin, m_dat0Pin + 3}) > 31) { + if (std::min({m_clkPin, m_cmdPin, m_dat0Pin}) < 16 || + pio_set_gpio_base(m_pio, 16) != PICO_OK) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + gpio_base = 16; + } else if (pio_set_gpio_base(m_pio, 0) != PICO_OK) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } +#endif // PICO_PIO_USE_GPIO_BASE + rd_data_patch_program(&pio_program, pio_instructions, m_clkPin); + m_rdDataOffset = pio_add_program(m_pio, &pio_program); + if (m_rdDataOffset < 0) { + DBG_MSG("m_rdDataOffset: ", m_rdDataOffset); + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + m_cmdRspOffset = pio_add_program(m_pio, &cmd_rsp_program); + if (m_cmdRspOffset < 0) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + m_rdClkOffset = pio_add_program(m_pio, &rd_clk_program); + if (m_rdClkOffset < 0) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + m_wrDataOffset = pio_add_program(m_pio, &wr_data_program); + if (m_wrDataOffset < 0) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + m_wrRespOffset = pio_add_program(m_pio, &wr_resp_program); + if (m_wrRespOffset < 0) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + for (uint i = 0; i < 6U; i++) { + gpio_pull_up(pin[i]); + } + gpio_set_drive_strength(m_clkPin, GPIO_DRIVE_STRENGTH_8MA); + gpio_set_slew_rate(m_clkPin, GPIO_SLEW_RATE_FAST); + + for (uint i = 0; i < 6U; i++) { + pio_gpio_init(m_pio, pin[i]); + } + // input_sync_bypass bits are relative to the PIO's gpio_base (0 or 16), so + // subtract it. Using the raw pin numbers here is undefined for pins >= 32 + // (Fruit Jam's SD pins are GPIO34-39) and evaluates to 0 on Cortex-M, leaving + // the input synchronizers in place -- benign at the ~400 kHz init rate but a + // source of CMD/DAT mis-sampling at the 25 MHz run rate. + m_pio->input_sync_bypass |= (1u << (m_clkPin - gpio_base)) | + (1u << (m_cmdPin - gpio_base)) | (0xFu << (m_dat0Pin - gpio_base)); + if (pio_sm_set_consecutive_pindirs(m_pio, m_sm0, m_clkPin, 1, true) != + PICO_OK || + pio_sm_set_consecutive_pindirs(m_pio, m_sm0, m_cmdPin, 1, true) != + PICO_OK || + pio_sm_set_consecutive_pindirs(m_pio, m_sm0, m_dat0Pin, 4, false) != + PICO_OK) { + sdError(SD_CARD_ERROR_ADD_PIO_PROGRAM); + goto fail; + } + return true; + +fail: + pioEnd(); + return false; +} +//------------------------------------------------------------------------------ +// A few cards still need at least 74 clocks after power-up. from the spec: +// +// After 1 ms VDD stable time, host provides at least 74 clocks while keeping +// CMD high before issuing the first command. In the case of SPI mode, CS +// shall be held high during 74 clock cycles. +// +// The original April 15, 2001 spec explains the 74 clocks: +// +// The additional 10 clocks (over the 64 clocks after which the card should be +// ready for communication) is provided to eliminate power-up synchronization +// problems. +// +void PioSdioCard::powerUpClockCycles() { + // Two clk_sys per SD clock cycle. + uint32_t nWait = ceil(0.0005 * clock_get_hz(clk_sys) / SD_MAX_INIT_RATE_KHZ); + gpio_init(m_cmdPin); + gpio_set_drive_strength(m_cmdPin, GPIO_DRIVE_STRENGTH_8MA); + gpio_set_dir(m_cmdPin, true); + gpio_put(m_cmdPin, 1); + gpio_init(m_clkPin); + gpio_set_drive_strength(m_clkPin, GPIO_DRIVE_STRENGTH_8MA); + gpio_set_dir(m_clkPin, true); + + // Send 80 SD CLK cycles with CMD high. End with CLK low. + for (uint i = 0; i <= 160; i++) { + gpio_put(m_clkPin, 1 & i); + busy_wait_at_least_cycles(nWait); + } +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readCID(cid_t* cid) { + memcpy(cid, &m_cid, sizeof(cid_t)); + return true; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readCSD(csd_t* csd) { + memcpy(csd, &m_csd, sizeof(csd_t)); + return true; +} +//------------------------------------------------------------------------------ +bool __time_critical_func(PioSdioCard::readData)(void* dst, size_t count) { + uint32_t buf[128]; + uint n32 = count / 4; + uint nr = n32 + 2; + const uint mask = (1ul << m_sm0) | (1ul << m_sm1); + io_wo_8* txFifo = reinterpret_cast(&m_pio->txf[m_sm1]); + pio_sm_init(m_pio, m_sm0, m_rdDataOffset, &m_rdDataConfig); + pio_sm_init(m_pio, m_sm1, m_rdClkOffset, &m_rdClkConfig); + pio_set_sm_mask_enabled(m_pio, mask, true); + + uint nf = nr < DAT_FIFO_DEPTH ? nr : DAT_FIFO_DEPTH; + for (uint it = 0; it < nf; it++) { + *txFifo = 0XFF; + } + io_ro_32* rxFifo = reinterpret_cast(&m_pio->rxf[m_sm0]); + uint32_t* dst32 = (uint)dst & 3 ? buf : reinterpret_cast(dst); + uint64_t crc = 0; + uint64_t chk = 0; + Timeout timeout(SD_READ_TIMEOUT); + uint ir = 0; + if (nf < nr) { + uint nb = nr - nf; + while (true) { + while (pio_sm_get_rx_fifo_level(m_pio, m_sm0) < 4) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_READ_TIMEOUT); + goto fail; + } + } + uint32_t tmp = *rxFifo; + *txFifo = 0XFF; + dst32[ir++] = __builtin_bswap32(tmp); + crc = crc16(crc, tmp); + tmp = *rxFifo; + *txFifo = 0XFF; + dst32[ir++] = __builtin_bswap32(tmp); + crc = crc16(crc, tmp); + if (ir == nb) { + break; + } + tmp = *rxFifo; + *txFifo = 0XFF; + dst32[ir++] = __builtin_bswap32(tmp); + crc = crc16(crc, tmp); + tmp = *rxFifo; + *txFifo = 0XFF; + dst32[ir++] = __builtin_bswap32(tmp); + crc = crc16(crc, tmp); + } + } + for (; ir < nr; ir++) { + while (pio_sm_is_rx_fifo_empty(m_pio, m_sm0)) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_READ_TIMEOUT); + goto fail; + } + } + uint32_t tmp = *rxFifo; + if (ir < n32) { + dst32[ir] = __builtin_bswap32(tmp); + crc = crc16(crc, tmp); + } else { + chk <<= 32; + chk |= tmp; + } + } + if (crc != chk) { +#if USE_DEBUG_MODE + Serial.printf("crc: %llX\r\nchk: %llX\r\n", crc, chk); +#endif // USE_DEBUG_MODE + sdError(SD_CARD_ERROR_READ_CRC); + goto fail; + } + pio_set_sm_mask_enabled(m_pio, mask, false); + if (dst32 == buf) { + memcpy(dst, buf, count); + } + return true; + +fail: + pio_set_sm_mask_enabled(m_pio, mask, false); + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readData(uint8_t* dst) { return readData(dst, 512); } +//------------------------------------------------------------------------------ +bool PioSdioCard::readOCR(uint32_t* ocr) { + *ocr = m_ocr; + return true; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readSCR(scr_t* scr) { + memcpy(scr, &m_scr, sizeof(scr_t)); + return true; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readSDS(sds_t* sds) { + memcpy(sds, &m_sds, sizeof(sds_t)); + return true; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readSector(Sector_t sector, uint8_t* dst) { + if (m_curState != READ_STATE || sector != m_curSector) { + if (!syncDevice()) { + SDIO_FAIL(); + goto fail; + } + if (!readStart(sector)) { + sdError(SD_CARD_ERROR_READ_START); + goto fail; + } + m_curSector = sector; + m_curState = READ_STATE; + } + if (!readData(dst, 512)) { + SDIO_FAIL(); + goto fail; + } + m_curSector++; + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readSectors(Sector_t sector, uint8_t* dst, size_t ns) { + for (size_t i = 0; i < ns; i++) { + if (!readSector(sector + i, dst + i * 512UL)) { + SDIO_FAIL(); + goto fail; + } + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readStart(Sector_t sector) { + uint arg = m_highCapacity ? sector : 512 * sector; + if (!cardCommand(CMD18_R1, arg)) { + sdError(SD_CARD_ERROR_CMD18); + goto fail; + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::readStop() { + if (!syncDevice()) { + SDIO_FAIL(); + return false; + } + return true; +} +//------------------------------------------------------------------------------ +uint32_t PioSdioCard::status() { + return cardCommand(CMD13_R1, m_rca) ? m_cardRsp : CARD_STATUS_ERROR; +} +//------------------------------------------------------------------------------ +Sector_t PioSdioCard::sectorCount() { return m_csd.capacity(); } +//------------------------------------------------------------------------------ +bool PioSdioCard::syncDevice() { + if (m_curState != IDLE_STATE) { + Timeout timeout(SD_INIT_TIMEOUT); + while (!gpio_get(m_dat0Pin)) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_CMD12); + goto fail; + } + } + if (!cardCommand(CMD12_R1, 0)) { + sdError(SD_CARD_ERROR_CMD12); + goto fail; + } + while (isBusy()) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_CMD12); + goto fail; + } + } + m_curState = IDLE_STATE; + } + return true; + +fail: + return false; +} +//------------------------------------------------------------------------------ +uint8_t PioSdioCard::type() const { + return !m_initDone ? 0 + : !m_version2 ? SD_CARD_TYPE_SD1 + : !m_highCapacity ? SD_CARD_TYPE_SD2 + : SD_CARD_TYPE_SDHC; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::writeSector(Sector_t sector, const uint8_t* src) { + return writeSectors(sector, src, 1); +} +//------------------------------------------------------------------------------ +bool PioSdioCard::writeSectors(Sector_t sector, const uint8_t* src, size_t ns) { + if (m_curState != WRITE_STATE || m_curSector != sector) { + if (!syncDevice()) { + SDIO_FAIL(); + goto fail; + } + if (!writeStart(sector)) { + sdError(SD_CARD_ERROR_WRITE_START); + goto fail; + } + m_curSector = sector; + m_curState = WRITE_STATE; + } + for (size_t i = 0; i < ns; i++, src += 512) { + if (!writeData(src)) { + sdError(SD_CARD_ERROR_WRITE_DATA); + goto fail; + } + } + m_curSector += ns; + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +bool __time_critical_func(PioSdioCard::writeData)(const uint8_t* src) { + const uint32_t* src32; + uint32_t buf[128]; + if ((uint)src & 3) { + memcpy(buf, src, 512); + src32 = (const uint32_t*)buf; + } else { + src32 = (const uint32_t*)src; + } + uint32_t tmp; + io_wo_32* txFifo = reinterpret_cast(&m_pio->txf[m_sm0]); + io_ro_32* rxFifo = reinterpret_cast(&m_pio->rxf[m_sm1]); + uint8_t rsp; + uint mask = (1ul << m_sm0) | (1ul << m_sm1); + uint64_t crc = 0; + + Timeout timeout(SD_WRITE_TIMEOUT); + while (!gpio_get(m_dat0Pin)) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_WRITE_TIMEOUT); + goto fail; + } + } + pio_sm_init(m_pio, m_sm0, m_wrDataOffset, &m_wrDataConfig); + pio_sm_init(m_pio, m_sm1, m_wrRespOffset, &m_wrRespConfig); + *txFifo = 1048; // 8 + 1024 + 16 + 1 - 1; + pio_sm_exec(m_pio, m_sm0, pio_encode_out(pio_x, 32)); + pio_sm_exec(m_pio, m_sm0, pio_encode_set(pio_pindirs, 0XF)); + *txFifo = 0xFFFFFFF0; + pio_set_sm_mask_enabled(m_pio, mask, true); + for (int i = 0; i < 128;) { + while (pio_sm_get_tx_fifo_level(m_pio, m_sm0) > 4) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_WRITE_FIFO); + goto fail; + } + } + tmp = __builtin_bswap32(src32[i++]); + crc = crc16(crc, tmp); + *txFifo = tmp; + tmp = __builtin_bswap32(src32[i++]); + crc = crc16(crc, tmp); + *txFifo = tmp; + tmp = __builtin_bswap32(src32[i++]); + crc = crc16(crc, tmp); + *txFifo = tmp; + tmp = __builtin_bswap32(src32[i++]); + crc = crc16(crc, tmp); + *txFifo = tmp; + } + while (pio_sm_get_tx_fifo_level(m_pio, m_sm0) > 5) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_WRITE_FIFO); + goto fail; + } + } + *txFifo = static_cast(crc >> 32); + *txFifo = static_cast(crc); + *txFifo = 0xFFFFFFFF; + + while (pio_sm_is_rx_fifo_empty(m_pio, m_sm1)) { + if (timeout.timedOut()) { + sdError(SD_CARD_ERROR_READ_FIFO); + goto fail; + } + } + rsp = *rxFifo; + if ((rsp & 0X1F) != 0b101) { +#if USE_DEBUG_MODE + Serial.printf("wr rsp: %02X\n", rsp); +#endif // USE_DEBUG_MODE + sdError(SD_CARD_ERROR_WRITE_DATA); + goto fail; + } + return true; +fail: + pio_set_sm_mask_enabled(m_pio, mask, false); + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::writeStart(Sector_t sector) { + uint arg = m_highCapacity ? sector : 512 * sector; + if (!cardCommand(CMD25_R1, arg)) { + sdError(SD_CARD_ERROR_CMD25); + goto fail; + } + return true; +fail: + return false; +} +//------------------------------------------------------------------------------ +bool PioSdioCard::writeStop() { + if (!syncDevice()) { + SDIO_FAIL(); + return false; + } + return true; +} +#endif // ARDUINO_ARCH_RP2040 diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.h new file mode 100644 index 00000000000..bc1d39a26fb --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.h @@ -0,0 +1,361 @@ +/** + * Copyright (c) 2011-2025 Bill Greiman, 2026 Tim Cocks for Adafruit Industries + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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. + */ +/** + * \file + * \brief Classes for PIO SDIO cards. + */ +#pragma once +// CIRCUITPY-CHANGE: Upstream relies on Arduino.h (pulled in via SdFatConfig.h) +// to declare the RP2 SDK PIO types (PIO, pio_sm_config), the `uint` alias used +// by this class's members, and the SDK functions the driver calls (gpio_*, +// clock_get_hz, the pico/time helpers) plus memcpy. This vendored build trims +// that Arduino path, so include those directly here. +#include +#include "hardware/clocks.h" +#include "hardware/gpio.h" +#include "hardware/pio.h" +#include "pico/time.h" +#include "../../common/SysCall.h" +#include "../SdCardInterface.h" +#if defined(ARDUINO_ARCH_RP2040) && defined(PIN_SD_CLK) && \ + defined(PIN_SD_CMD_MOSI) && defined(PIN_SD_DAT0_MISO) && \ + defined(PIN_SD_DAT1) && defined(PIN_SD_DAT2) && defined(PIN_SD_DAT3_CS) +#define HAS_BUILTIN_PIO_SDIO +#endif +class PioSdioConfig; +/** SdioConfig type for PIO SDIO */ +typedef PioSdioConfig SdioConfig; +class PioSdioCard; +/** Sdio type for PIO SDIO */ +typedef PioSdioCard SdioCard; +// ------------------------------------------------------------------------------ +/** + * \class PioSdioConfig + * \brief SDIO card configuration. + */ +class PioSdioConfig { +public: + /** + * PioSdioConfig constructor. + * \param[in] clkPin gpio pin for SDIO CLK. + * \param[in] cmdPin gpio pin for SDIO CMD. + * \param[in] dat0Pin gpio start pin for SDIO DAT[4]. + * \param[in] clkDiv PIO clock divisor. + */ + PioSdioConfig(uint clkPin, uint cmdPin, uint dat0Pin, float clkDiv = 1.0) + : m_clkPin(clkPin), + m_cmdPin(cmdPin), + m_dat0Pin(dat0Pin), + m_clkDiv(clkDiv) { + } + /** \return gpio for SDIO CLK */ + uint clkPin() { + return m_clkPin; + } + /** \return gpio for SDIO CMD */ + uint cmdPin() { + return m_cmdPin; + } + /** \return gpio for SDIO DAT0 */ + uint dat0Pin() { + return m_dat0Pin; + } + /** \return PIO clock divisor */ + float clkDiv() { + return m_clkDiv; + } + +private: + PioSdioConfig() : m_clkPin(63u), m_cmdPin(63u), m_dat0Pin(63u), m_clkDiv(0) { + } + const uint8_t m_clkPin; + const uint8_t m_cmdPin; + const uint8_t m_dat0Pin; + const float m_clkDiv; +}; +// ------------------------------------------------------------------------------ +/** + * \class CmdRsp_t + * \brief SD command/response type. + */ +class CmdRsp_t { +public: + /** + * \param[in] idx_ Command index. + * \param[in] rsp_ Response type. + */ + CmdRsp_t(uint8_t idx_, uint8_t rsp_) : idx(idx_), rsp(rsp_) { + } + uint8_t idx; ///< Command index. + uint8_t rsp; ///< Response type. +}; +// ------------------------------------------------------------------------------ +/** + * \class PioSdioCard + * \brief Raw SDIO access to SD and SDHC flash memory cards. + */ +class PioSdioCard: public SdCardInterface { +public: + PioSdioCard() = default; // cppcheck-suppress uninitMemberVar + /** Initialize the SD card. + * \param[in] config SDIO card configuration. + * \return true for success or false for failure. + */ + bool begin(PioSdioConfig config); + /** CMD6 Switch mode: Check Function Set Function. + * \param[in] arg CMD6 argument. + * \param[out] status return status data. + * + * \return true for success or false for failure. + */ + bool cardCMD6(uint32_t arg, uint8_t *status) final; + /** Disable an SDIO card. + * not implemented. + */ + void end() final; + /** CIRCUITPY-CHANGE: mark this card's PIO state machines as surviving a soft + * reset, keeping rp2pio's never-reset bookkeeping coherent with the SMs this + * driver claims directly. */ + void neverReset(); + + #ifndef DOXYGEN_SHOULD_SKIP_THIS + uint32_t __attribute__((error("use sectorCount()"))) cardSize(); + #endif // DOXYGEN_SHOULD_SKIP_THIS + /** Erase a range of sectors. + * + * \param[in] firstSector The address of the first sector in the range. + * \param[in] lastSector The address of the last sector in the range. + * + * \note This function requests the SD card to do a flash erase for a + * range of sectors. The data on the card after an erase operation is + * either 0 or 1, depends on the card vendor. The card must support + * single sector erase. + * + * \return true for success or false for failure. + */ + bool erase(Sector_t firstSector, Sector_t lastSector) final; + /** + * \return code for the last error. See SdCardInfo.h for a list of error + * codes. + */ + uint8_t errorCode() const final; + /** \return error data for last error. */ + uint32_t errorData() const final; + /** \return error line for last error. Tmp function for debug. */ + uint32_t errorLine() const; + /** + * Check for busy with CMD13. + * + * \return true if busy else false. + */ + bool isBusy() final; + /** \return the SD clock frequency in kHz. */ + uint32_t kHzSdClk(); + /** + * Read a 512 byte sector from an SD card. + * + * \param[in] sector Logical sector to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return true for success or false for failure. + */ + bool readSector(Sector_t sector, uint8_t *dst) final; + /** + * Read multiple 512 byte sectors from an SD card. + * + * \param[in] sector Logical sector to be read. + * \param[in] ns Number of sectors to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return true for success or false for failure. + */ + bool readSectors(Sector_t sector, uint8_t *dst, size_t ns) final; + /** + * Read a card's CID register. The CID contains card identification + * information such as Manufacturer ID, Product name, Product serial + * number and Manufacturing date. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCID(cid_t *cid) final; + /** + * Read a card's CSD register. The CSD contains Card-Specific Data that + * provides information regarding access to the card's contents. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + bool readCSD(csd_t *csd) final; + /** Read one data sector in a multiple sector read sequence + * + * \param[out] dst Pointer to the location for the data to be read. + * + * \return true for success or false for failure. + */ + bool readData(uint8_t *dst); + /** Read OCR register. + * + * \param[out] ocr Value of OCR register. + * \return true for success or false for failure. + */ + bool readOCR(uint32_t *ocr) final; + /** Read SCR register. + * + * \param[out] scr Value of SCR register. + * \return true for success or false for failure. + */ + bool readSCR(scr_t *scr) final; + /** Return the 64 byte SD Status register. + * \param[out] sds location for 64 status bytes. + * \return true for success or false for failure. + */ + bool readSDS(sds_t *sds) final; + /** Start a read multiple sectors sequence. + * + * \param[in] sector Address of first sector in sequence. + * + * \note This function is used with readData() and readStop() for optimized + * multiple sector reads. + * + * \return true for success or false for failure. + */ + bool readStart(Sector_t sector); + /** End a read multiple sectors sequence. + * + * \return true for success or false for failure. + */ + bool readStop(); + /** \return SDIO card status. */ + uint32_t status() final; + /** + * Determine the size of an SD flash memory card. + * + * \return The number of 512 byte data sectors in the card + * or zero if an error occurs. + */ + Sector_t sectorCount() final; + /** + * Send CMD12 to stop read or write. + * + * \param[in] blocking If true, wait for command complete. + * + * \return true for success or false for failure. + */ + bool stopTransmission(bool blocking); + /** \return success if sync successful. Not for user apps. */ + bool syncDevice() final; + /** Return the card type: SD V1, SD V2 or SDHC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC. + */ + uint8_t type() const final; + /** + * Writes a 512 byte sector to an SD card. + * + * \param[in] sector Logical sector to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return true for success or false for failure. + */ + bool writeSector(Sector_t sector, const uint8_t *src) final; + /** + * Write multiple 512 byte sectors to an SD card. + * + * \param[in] sector Logical sector to be written. + * \param[in] ns Number of sectors to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return true for success or false for failure. + */ + bool writeSectors(Sector_t sector, const uint8_t *src, size_t ns) final; + /** Write one data sector in a multiple sector write sequence. + * \param[in] src Pointer to the location of the data to be written. + * \return true for success or false for failure. + */ + bool writeData(const uint8_t *src); + /** Start a write multiple sectors sequence. + * + * \param[in] sector Address of first sector in sequence. + * + * \note This function is used with writeData() and writeStop() + * for optimized multiple sector writes. + * + * \return true for success or false for failure. + */ + bool writeStart(Sector_t sector); + + /** End a write multiple sectors sequence. + * + * \return true for success or false for failure. + */ + bool writeStop(); + +private: + // ---------------------------------------------------------------------------- + bool cardAcmd(uint32_t rca, CmdRsp_t cmdRsp, uint32_t arg); + bool cardCommand(CmdRsp_t cmd, uint32_t arg, void *rsp = nullptr); + void pioConfig(float clkDiv); + void pioEnd(); + bool pioInit(); + void powerUpClockCycles(); + bool readData(void *dst, size_t count); + void setSdErrorCode(uint8_t code, uint32_t line) { + m_errorCode = code; + m_errorLine = line; + } + static const uint8_t IDLE_STATE = 0; + static const uint8_t READ_STATE = 1; + static const uint8_t WRITE_STATE = 2; + Sector_t m_curSector = 0; + uint8_t m_curState = IDLE_STATE; + uint m_cardRsp; + uint m_errorCode; + uint m_errorLine; + bool m_highCapacity; + bool m_initDone = false; + uint m_ocr; + bool m_version2; + uint m_rca; + cid_t m_cid; + csd_t m_csd; + scr_t m_scr; + sds_t m_sds; + + float m_clkDiv = 0; + uint m_clkPin = 63u; // PIN_SDIO_UNDEFINED; + uint m_cmdPin = 63u; // PIN_SDIO_UNDEFINED; + uint m_dat0Pin = 63u; // PIN_SDIO_UNDEFINED; + PIO m_pio = nullptr; + int m_sm0 = -1; + int m_sm1 = -1; + int m_cmdRspOffset = -1; + pio_sm_config m_cmdConfig; + int m_rdDataOffset = -1; + pio_sm_config m_rdDataConfig; + int m_rdClkOffset = -1; + pio_sm_config m_rdClkConfig; + int m_wrDataOffset = -1; + pio_sm_config m_wrDataConfig; + int m_wrRespOffset = -1; + pio_sm_config m_wrRespConfig; +}; diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.pio.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.pio.h new file mode 100644 index 00000000000..3130fd4edc0 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/PioSdio/PioSdioCard.pio.h @@ -0,0 +1,331 @@ +/** +* Copyright (c) 2011-2025 Bill Greiman, 2026 Tim Cocks for Adafruit Industries + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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 file is autogenerated by pioasm; do not edit! // +// -------------------------------------------------- // + +#pragma once + +#if !PICO_NO_HARDWARE +#include "hardware/pio.h" +#endif + +#define SDIO_IRQ 7 + +// ------- // +// cmd_rsp // +// ------- // + +#define cmd_rsp_wrap_target 0 +#define cmd_rsp_wrap 9 +#define cmd_rsp_pio_version 0 + +static const uint16_t cmd_rsp_program_instructions[] = { + // .wrap_target + 0x7101, // 0: out pins, 1 side 0 [1] + 0x1940, // 1: jmp x--, 0 side 1 [1] + 0x1160, // 2: jmp !y, 0 side 0 [1] + 0xfb80, // 3: set pindirs, 0 side 1 [3] + 0xb342, // 4: nop side 0 [3] + 0xba42, // 5: nop side 1 [2] + 0x00c4, // 6: jmp pin, 4 + 0x4001, // 7: in pins, 1 + 0x9260, // 8: push iffull block side 0 [2] + 0x1987, // 9: jmp y--, 7 side 1 [1] + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program cmd_rsp_program = { + .instructions = cmd_rsp_program_instructions, + .length = 10, + .origin = -1, + .pio_version = cmd_rsp_pio_version, + #if PICO_PIO_VERSION > 0 + .used_gpio_ranges = 0x0 + #endif +}; + +static inline pio_sm_config cmd_rsp_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + cmd_rsp_wrap_target, offset + cmd_rsp_wrap); + sm_config_set_sideset(&c, 2, true, false); + return c; +} + +static inline pio_sm_config pio_cmd_rsp_program_config(uint offset, uint cmd_pin, uint clk_pin, float clk_div) { + pio_sm_config c = cmd_rsp_program_get_default_config(offset); + sm_config_set_sideset_pins(&c, clk_pin); + sm_config_set_out_pins(&c, cmd_pin, 1); + sm_config_set_in_pins(&c, cmd_pin); + sm_config_set_set_pins(&c, cmd_pin, 1); + sm_config_set_jmp_pin(&c, cmd_pin); + sm_config_set_in_shift(&c, false, false, 8); + sm_config_set_out_shift(&c, false, true, 8); + sm_config_set_clkdiv(&c, clk_div); + return c; +} + +#endif + +// ------ // +// rd_clk // +// ------ // + +#define rd_clk_wrap_target 3 +#define rd_clk_wrap 4 +#define rd_clk_pio_version 0 + +static const uint16_t rd_clk_program_instructions[] = { + 0xb342, // 0: nop side 0 [3] + 0x1bc0, // 1: jmp pin, 0 side 1 [3] + 0xc007, // 2: irq nowait 7 + // .wrap_target + 0x7261, // 3: out null, 1 side 0 [2] + 0xb942, // 4: nop side 1 [1] + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program rd_clk_program = { + .instructions = rd_clk_program_instructions, + .length = 5, + .origin = -1, + .pio_version = rd_clk_pio_version, + #if PICO_PIO_VERSION > 0 + .used_gpio_ranges = 0x0 + #endif +}; + +static inline pio_sm_config rd_clk_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + rd_clk_wrap_target, offset + rd_clk_wrap); + sm_config_set_sideset(&c, 2, true, false); + return c; +} + +static inline pio_sm_config pio_rd_clk_program_config(uint offset, uint d0_pin, uint clk_pin, float clk_div) { + pio_sm_config c = rd_clk_program_get_default_config(offset); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); + sm_config_set_sideset_pins(&c, clk_pin); + sm_config_set_in_pins(&c, d0_pin); + sm_config_set_jmp_pin(&c, d0_pin); + sm_config_set_out_shift(&c, false, true, 8); + sm_config_set_clkdiv(&c, clk_div); + return c; +} + +#endif + +// ------- // +// rd_data // +// ------- // + +#define rd_data_wrap_target 1 +#define rd_data_wrap 3 +#define rd_data_pio_version 0 + +#define rd_data_offset_wait0 1u +#define rd_data_offset_wait1 2u + +static const uint16_t rd_data_program_instructions[] = { + 0x20c7, // 0: wait 1 irq, 7 + // .wrap_target + 0x2000, // 1: wait 0 gpio, 0 + 0x2080, // 2: wait 1 gpio, 0 + 0x4004, // 3: in pins, 4 + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program rd_data_program = { + .instructions = rd_data_program_instructions, + .length = 4, + .origin = -1, + .pio_version = rd_data_pio_version, + #if PICO_PIO_VERSION > 0 + .used_gpio_ranges = 0x1 + #endif +}; + +static inline pio_sm_config rd_data_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + rd_data_wrap_target, offset + rd_data_wrap); + return c; +} + +static inline void rd_data_patch_program(pio_program *prog, uint16_t *inst, uint clk_pin) { + *prog = rd_data_program; + prog->instructions = inst; + #if PICO_PIO_VERSION > 0 + prog->used_gpio_ranges = clk_pin < 16 ? 1 : clk_pin < 32 ? 2 : clk_pin < 48 ? 4 : 8; + #endif + memcpy(inst, rd_data_program_instructions, sizeof(rd_data_program_instructions)); + inst[rd_data_offset_wait0] = pio_encode_wait_gpio(0, clk_pin); + inst[rd_data_offset_wait1] = pio_encode_wait_gpio(1, clk_pin); +} +static inline pio_sm_config pio_rd_data_program_config(uint offset, uint data_pin, float clk_div) { + pio_sm_config c = rd_data_program_get_default_config(offset); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_RX); + sm_config_set_in_pins(&c, data_pin); + sm_config_set_in_shift(&c, false, true, 32); + sm_config_set_clkdiv(&c, clk_div); + return c; +} + +#endif + +// ------- // +// wr_data // +// ------- // + +#define wr_data_wrap_target 3 +#define wr_data_wrap 3 +#define wr_data_pio_version 0 + +static const uint16_t wr_data_program_instructions[] = { + 0x7104, // 0: out pins, 4 side 0 [1] + 0x1940, // 1: jmp x--, 0 side 1 [1] + 0xc007, // 2: irq nowait 7 + // .wrap_target + 0xa042, // 3: nop + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program wr_data_program = { + .instructions = wr_data_program_instructions, + .length = 4, + .origin = -1, + .pio_version = wr_data_pio_version, + #if PICO_PIO_VERSION > 0 + .used_gpio_ranges = 0x0 + #endif +}; + +static inline pio_sm_config wr_data_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + wr_data_wrap_target, offset + wr_data_wrap); + sm_config_set_sideset(&c, 2, true, false); + return c; +} + +static inline pio_sm_config pio_wr_data_program_config(uint offset, uint data_pin, uint clk_pin, float clk_div) { + pio_sm_config c = wr_data_program_get_default_config(offset); + sm_config_set_fifo_join(&c, PIO_FIFO_JOIN_TX); + sm_config_set_sideset_pins(&c, clk_pin); + sm_config_set_out_pins(&c, data_pin, 4); + sm_config_set_set_pins(&c, data_pin, 4); + sm_config_set_out_shift(&c, false, true, 32); + sm_config_set_clkdiv(&c, clk_div); + return c; +} + +#endif + +// ------- // +// wr_resp // +// ------- // + +#define wr_resp_wrap_target 2 +#define wr_resp_wrap 3 +#define wr_resp_pio_version 0 + +static const uint16_t wr_resp_program_instructions[] = { + 0x20c7, // 0: wait 1 irq, 7 + 0xe180, // 1: set pindirs, 0 [1] + // .wrap_target + 0x5c01, // 2: in pins, 1 side 1 [4] + 0x9440, // 3: push iffull noblock side 0 [4] + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program wr_resp_program = { + .instructions = wr_resp_program_instructions, + .length = 4, + .origin = -1, + .pio_version = wr_resp_pio_version, + #if PICO_PIO_VERSION > 0 + .used_gpio_ranges = 0x0 + #endif +}; + +static inline pio_sm_config wr_resp_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + wr_resp_wrap_target, offset + wr_resp_wrap); + sm_config_set_sideset(&c, 2, true, false); + return c; +} + +static inline pio_sm_config pio_wr_resp_program_config(uint offset, uint data_pin, uint clk_pin, float clk_div) { + pio_sm_config c = wr_resp_program_get_default_config(offset); + sm_config_set_sideset_pins(&c, clk_pin); + sm_config_set_in_pins(&c, data_pin); + sm_config_set_set_pins(&c, data_pin, 4); + sm_config_set_in_shift(&c, false, false, 8); + sm_config_set_clkdiv(&c, clk_div); + return c; +} +static const size_t total_pio_length = + cmd_rsp_program.length + rd_data_program.length + rd_clk_program.length + + wr_data_program.length + wr_resp_program.length; + +#endif + +// -------- // +// fill_pio // +// -------- // + +#define fill_pio_wrap_target 0 +#define fill_pio_wrap 3 +#define fill_pio_pio_version 0 + +static const uint16_t fill_pio_program_instructions[] = { + // .wrap_target + 0x0000, // 0: jmp 0 + 0x0001, // 1: jmp 1 + 0x0002, // 2: jmp 2 + 0x0003, // 3: jmp 3 + // .wrap +}; + +#if !PICO_NO_HARDWARE +static const struct pio_program fill_pio_program = { + .instructions = fill_pio_program_instructions, + .length = 4, + .origin = -1, + .pio_version = fill_pio_pio_version, + #if PICO_PIO_VERSION > 0 + .used_gpio_ranges = 0x0 + #endif +}; + +static inline pio_sm_config fill_pio_program_get_default_config(uint offset) { + pio_sm_config c = pio_get_default_sm_config(); + sm_config_set_wrap(&c, offset + fill_pio_wrap_target, offset + fill_pio_wrap); + return c; +} +#endif diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/SdCardInfo.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/SdCardInfo.h new file mode 100644 index 00000000000..c84f9778725 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/SdCardInfo.h @@ -0,0 +1,530 @@ +/** + * Copyright (c) 2011-2025 Bill Greiman, 2026 Tim Cocks for Adafruit Industries + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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. + */ +/** + * \file + * \brief Definitions for SD cards. + */ +#pragma once +#include + +#include "../common/SysCall.h" +// Based on the document: +// +// SD Specifications +// Part 1 +// Physical Layer +// Simplified Specification +// Version 8.00 +// Sep 23, 2020 +// +// https://www.sdcard.org/downloads/pls/ +#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ +// SD registers are big endian. +#error bit fields in structures assume little endian processor. +#endif // __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ +// ------------------------------------------------------------------------------ +// SD card errors +// See the SD Specification for command info. +/** Define error codes and brief description. */ +#define SD_ERROR_CODE_LIST \ + SD_CARD_ERROR(NONE, "No error") \ + SD_CARD_ERROR(CMD0, "Card reset failed") \ + SD_CARD_ERROR(CMD2, "SDIO read CID") \ + SD_CARD_ERROR(CMD3, "SDIO publish RCA") \ + SD_CARD_ERROR(CMD6, "Switch card function") \ + SD_CARD_ERROR(CMD7, "SDIO card select") \ + SD_CARD_ERROR(CMD8, "Send and check interface settings") \ + SD_CARD_ERROR(CMD9, "Read CSD data") \ + SD_CARD_ERROR(CMD10, "Read CID data") \ + SD_CARD_ERROR(CMD12, "Stop multiple block transmission") \ + SD_CARD_ERROR(CMD13, "Read card status") \ + SD_CARD_ERROR(CMD17, "Read single block") \ + SD_CARD_ERROR(CMD18, "Read multiple blocks") \ + SD_CARD_ERROR(CMD24, "Write single block") \ + SD_CARD_ERROR(CMD25, "Write multiple blocks") \ + SD_CARD_ERROR(CMD32, "Set first erase block") \ + SD_CARD_ERROR(CMD33, "Set last erase block") \ + SD_CARD_ERROR(CMD38, "Erase selected blocks") \ + SD_CARD_ERROR(CMD58, "Read OCR register") \ + SD_CARD_ERROR(CMD59, "Set CRC mode") \ + SD_CARD_ERROR(ACMD6, "Set SDIO bus width") \ + SD_CARD_ERROR(ACMD13, "Read extended status") \ + SD_CARD_ERROR(ACMD23, "Set pre-erased count") \ + SD_CARD_ERROR(ACMD41, "Activate card initialization") \ + SD_CARD_ERROR(ACMD51, "Read SCR data") \ + SD_CARD_ERROR(READ_TOKEN, "Bad read data token") \ + SD_CARD_ERROR(READ_CRC, "Read CRC error") \ + SD_CARD_ERROR(READ_FIFO, "SDIO fifo read timeout") \ + SD_CARD_ERROR(READ_REG, "Read CID or CSD failed.") \ + SD_CARD_ERROR(READ_START, "Bad readStart argument") \ + SD_CARD_ERROR(READ_TIMEOUT, "Read data timeout") \ + SD_CARD_ERROR(STOP_TRAN, "Multiple block stop failed") \ + SD_CARD_ERROR(TRANSFER_COMPLETE, "SDIO transfer complete") \ + SD_CARD_ERROR(WRITE_DATA, "Write data not accepted") \ + SD_CARD_ERROR(WRITE_FIFO, "SDIO fifo write timeout") \ + SD_CARD_ERROR(WRITE_START, "Bad writeStart argument") \ + SD_CARD_ERROR(WRITE_PROGRAMMING, "Flash programming") \ + SD_CARD_ERROR(WRITE_TIMEOUT, "Write timeout") \ + SD_CARD_ERROR(DMA, "DMA transfer failed") \ + SD_CARD_ERROR(ERASE, "Card did not accept erase commands") \ + SD_CARD_ERROR(ERASE_SINGLE_SECTOR, "Card does not support erase") \ + SD_CARD_ERROR(ERASE_TIMEOUT, "Erase command timeout") \ + SD_CARD_ERROR(INIT_NOT_CALLED, "Card has not been initialized") \ + SD_CARD_ERROR(ADD_PIO_PROGRAM, "Add PIO program") \ + SD_CARD_ERROR(INVALID_CARD_CONFIG, "Invalid card config") \ + SD_CARD_ERROR(FUNCTION_NOT_SUPPORTED, "Unsupported SDIO command") + +enum { +/** Macro for generation of error codes using an enum. */ +#define SD_CARD_ERROR(e, m) SD_CARD_ERROR_##e, + SD_ERROR_CODE_LIST +#undef SD_CARD_ERROR + SD_CARD_ERROR_UNKNOWN +}; +/** Print the enum symbol for an error code. + * \param[in] pr Print stream. + * \param[in] code enum value for error. + */ +void printSdErrorSymbol(print_t *pr, uint8_t code); +/** Print text for an error code. + * \param[in] pr Print stream. + * \param[in] code enum value for error. + */ +void printSdErrorText(print_t *pr, uint8_t code); +// ------------------------------------------------------------------------------ +// card types +/** Standard capacity V1 SD card */ +const uint8_t SD_CARD_TYPE_SD1 = 1; +/** Standard capacity V2 SD card */ +const uint8_t SD_CARD_TYPE_SD2 = 2; +/** High Capacity SD card */ +const uint8_t SD_CARD_TYPE_SDHC = 3; +// ------------------------------------------------------------------------------ +// SD operation timeouts +/** command timeout ms */ +const uint16_t SD_CMD_TIMEOUT = 300; +/** erase timeout ms */ +const uint16_t SD_ERASE_TIMEOUT = 10000; +/** init timeout ms */ +const uint16_t SD_INIT_TIMEOUT = 2000; +/** read timeout ms */ +const uint16_t SD_READ_TIMEOUT = 300; +/** write time out ms */ +const uint16_t SD_WRITE_TIMEOUT = 600; +// ------------------------------------------------------------------------------ +// SD card commands +/** GO_IDLE_STATE - init card in spi mode if CS low */ +const uint8_t CMD0 = 0X00; +/** ALL_SEND_CID - Asks any card to send the CID. */ +const uint8_t CMD2 = 0X02; +/** SEND_RELATIVE_ADDR - Ask the card to publish a new RCA. */ +const uint8_t CMD3 = 0X03; +/** SWITCH_FUNC - Switch Function Command */ +const uint8_t CMD6 = 0X06; +/** SELECT/DESELECT_CARD - toggles between the stand-by and transfer states. */ +const uint8_t CMD7 = 0X07; +/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/ +const uint8_t CMD8 = 0X08; +/** SEND_CSD - read the Card Specific Data (CSD register) */ +const uint8_t CMD9 = 0X09; +/** SEND_CID - read the card identification information (CID register) */ +const uint8_t CMD10 = 0X0A; +/** VOLTAGE_SWITCH -Switch to 1.8V bus signaling level. */ +const uint8_t CMD11 = 0X0B; +/** STOP_TRANSMISSION - end multiple sector read sequence */ +const uint8_t CMD12 = 0X0C; +/** SEND_STATUS - read the card status register */ +const uint8_t CMD13 = 0X0D; +/** READ_SINGLE_SECTOR - read a single data sector from the card */ +const uint8_t CMD17 = 0X11; +/** READ_MULTIPLE_SECTOR - read multiple data sectors from the card */ +const uint8_t CMD18 = 0X12; +/** WRITE_SECTOR - write a single data sector to the card */ +const uint8_t CMD24 = 0X18; +/** WRITE_MULTIPLE_SECTOR - write sectors of data until a STOP_TRANSMISSION */ +const uint8_t CMD25 = 0X19; +/** ERASE_WR_BLK_START - sets the address of the first sector to be erased */ +const uint8_t CMD32 = 0X20; +/** ERASE_WR_BLK_END - sets the address of the last sector of the continuous + range to be erased*/ +const uint8_t CMD33 = 0X21; +/** ERASE - erase all previously selected sectors */ +const uint8_t CMD38 = 0X26; +/** APP_CMD - escape for application specific command */ +const uint8_t CMD55 = 0X37; +/** READ_OCR - read the OCR register of a card */ +const uint8_t CMD58 = 0X3A; +/** CRC_ON_OFF - enable or disable CRC checking */ +const uint8_t CMD59 = 0X3B; +/** SET_BUS_WIDTH - Defines the data bus width for data transfer. */ +const uint8_t ACMD6 = 0X06; +/** SD_STATUS - Send the SD Status. */ +const uint8_t ACMD13 = 0X0D; +/** SET_WR_BLK_ERASE_COUNT - Set the number of write sectors to be + pre-erased before writing */ +const uint8_t ACMD23 = 0X17; +/** SD_SEND_OP_COMD - Sends host capacity support information and + activates the card's initialization process */ +const uint8_t ACMD41 = 0X29; +/** Reads the SD Configuration Register (SCR). */ +const uint8_t ACMD51 = 0X33; +// ============================================================================== +// CARD_STATUS +/** The command's argument was out of the allowed range for this card. */ +const uint32_t CARD_STATUS_OUT_OF_RANGE = 1UL << 31; +/** A misaligned address which did not match the sector length. */ +const uint32_t CARD_STATUS_ADDRESS_ERROR = 1UL << 30; +/** The transferred sector length is not allowed for this card. */ +const uint32_t CARD_STATUS_SECTOR_LEN_ERROR = 1UL << 29; +/** An error in the sequence of erase commands occurred. */ +const uint32_t CARD_STATUS_ERASE_SEQ_ERROR = 1UL << 28; +/** An invalid selection of write-sectors for erase occurred. */ +const uint32_t CARD_STATUS_ERASE_PARAM = 1UL << 27; +/** Set when the host attempts to write to a protected sector. */ +const uint32_t CARD_STATUS_WP_VIOLATION = 1UL << 26; +/** When set, signals that the card is locked by the host. */ +const uint32_t CARD_STATUS_CARD_IS_LOCKED = 1UL << 25; +/** Set when a sequence or password error has been detected. */ +const uint32_t CARD_STATUS_LOCK_UNLOCK_FAILED = 1UL << 24; +/** The CRC check of the previous command failed. */ +const uint32_t CARD_STATUS_COM_CRC_ERROR = 1UL << 23; +/** Command not legal for the card state. */ +const uint32_t CARD_STATUS_ILLEGAL_COMMAND = 1UL << 22; +/** Card internal ECC was applied but failed to correct the data. */ +const uint32_t CARD_STATUS_CARD_ECC_FAILED = 1UL << 21; +/** Internal card controller error */ +const uint32_t CARD_STATUS_CC_ERROR = 1UL << 20; +/** A general or an unknown error occurred during the operation. */ +const uint32_t CARD_STATUS_ERROR = 1UL << 19; +// bits 19, 18, and 17 reserved. +/** Permanent WP set or attempt to change read only values of CSD. */ +const uint32_t CARD_STATUS_CSD_OVERWRITE = 1UL << 16; +/** partial address space was erased due to write protect. */ +const uint32_t CARD_STATUS_WP_ERASE_SKIP = 1UL << 15; +/** The command has been executed without using the internal ECC. */ +const uint32_t CARD_STATUS_CARD_ECC_DISABLED = 1UL << 14; +/** out of erase sequence command was received. */ +const uint32_t CARD_STATUS_ERASE_RESET = 1UL << 13; +/** The state of the card when receiving the command. + * 0 = idle + * 1 = ready + * 2 = ident + * 3 = stby + * 4 = tran + * 5 = data + * 6 = rcv + * 7 = prg + * 8 = dis + * 9-14 = reserved + * 15 = reserved for I/O mode + */ +const uint32_t CARD_STATUS_CURRENT_STATE = 0XF << 9; +/** Shift for current state. */ +const uint32_t CARD_STATUS_CURRENT_STATE_SHIFT = 9; +/** Corresponds to buffer empty signaling on the bus. */ +const uint32_t CARD_STATUS_READY_FOR_DATA = 1UL << 8; +// bit 7 reserved. +/** Extension Functions may set this bit to get host to deal with events. */ +const uint32_t CARD_STATUS_FX_EVENT = 1UL << 6; +/** The card will expect ACMD, or the command has been interpreted as ACMD */ +const uint32_t CARD_STATUS_APP_CMD = 1UL << 5; +// bit 4 reserved. +/** Error in the sequence of the authentication process. */ +const uint32_t CARD_STATUS_AKE_SEQ_ERROR = 1UL << 3; +// bits 2,1, and 0 reserved for manufacturer test mode. +// ============================================================================== +/** status for card in the ready state */ +const uint8_t R1_READY_STATE = 0X00; +/** status for card in the idle state */ +const uint8_t R1_IDLE_STATE = 0X01; +/** status bit for illegal command */ +const uint8_t R1_ILLEGAL_COMMAND = 0X04; +/** start data token for read or write single sector*/ +const uint8_t DATA_START_SECTOR = 0XFE; +/** stop token for write multiple sectors*/ +const uint8_t STOP_TRAN_TOKEN = 0XFD; +/** start data token for write multiple sectors*/ +const uint8_t WRITE_MULTIPLE_TOKEN = 0XFC; +/** mask for data response tokens after a write sector operation */ +const uint8_t DATA_RES_MASK = 0X1F; +/** write data accepted token */ +const uint8_t DATA_RES_ACCEPTED = 0X05; +// ============================================================================== +/** + * \class cid_t + * \brief Card Identification (CID) register. + */ +struct cid_t { + // byte 0 + /** Manufacturer ID */ + uint8_t mid; + // byte 1-2 + /** OEM/Application ID. */ + char oid[2]; + // byte 3-7 + /** Product name. */ + char pnm[5]; + // byte 8 + /** Product revision - n.m two 4-bit nibbles. */ + uint8_t prv; + // byte 9-12 + /** Product serial 32-bit number Big Endian format. */ + uint8_t psn8[4]; + // byte 13-14 + /** Manufacturing date big endian - four nibbles RYYM Reserved Year Month. */ + uint8_t mdt[2]; + // byte 15 + /** CRC7 bits 1-7 checksum, bit 0 always 1 */ + uint8_t crc; + // Extract big endian fields. + /** \return major revision number. */ + int prvN() const { + return prv >> 4; + } + /** \return minor revision number. */ + int prvM() const { + return prv & 0XF; + } + /** \return Manufacturing Year. */ + int mdtYear() const { + return 2000 + ((mdt[0] & 0XF) << 4) + (mdt[1] >> 4); + } + /** \return Manufacturing Month. */ + int mdtMonth() const { + return mdt[1] & 0XF; + } + /** \return Product Serial Number. */ + uint32_t psn() const { + return static_cast < uint32_t > (psn8[0]) << 24 | + static_cast < uint32_t > (psn8[1]) << 16 | + static_cast < uint32_t > (psn8[2]) << 8 | static_cast < uint32_t > (psn8[3]); + } +} __attribute__((packed)); +// ============================================================================== +/** + * \class csd_t + * \brief Union of old and new style CSD register. + */ +struct csd_t { + /** union of all CSD versions */ + uint8_t csd[16]; + // Extract big endian fields. + /** \return Capacity in sectors */ + uint32_t capacity() const { + uint32_t c_size; + uint8_t ver = csd[0] >> 6; + if (ver == 0) { + c_size = static_cast < uint32_t > (csd[6] & 3) << 10; + c_size |= static_cast < uint32_t > (csd[7]) << 2 | csd[8] >> 6; + uint8_t c_size_mult = (csd[9] & 3) << 1 | csd[10] >> 7; + uint8_t read_bl_len = csd[5] & 15; + return (c_size + 1) << (c_size_mult + read_bl_len + 2 - 9); + } else if (ver == 1) { + c_size = static_cast < uint32_t > (csd[7] & 63) << 16; + c_size |= static_cast < uint32_t > (csd[8]) << 8; + c_size |= csd[9]; + return (c_size + 1) << 10; + } else { + return 0; + } + } + /** \return true if erase granularity is single block. */ + bool eraseSingleBlock() const { + return csd[10] & 0X40; + } + /** \return erase size in 512 byte blocks if eraseSingleBlock is false. */ + int eraseSize() const { + return ((csd[10] & 0X3F) << 1 | csd[11] >> 7) + 1; + } + /** \return true if the contents is copied or true if original. */ + bool copy() const { + return csd[14] & 0X40; + } + /** \return true if the entire card is permanently write protected. */ + bool permWriteProtect() const { + return csd[14] & 0X20; + } + /** \return true if the entire card is temporarily write protected. */ + bool tempWriteProtect() const { + return csd[14] & 0X10; + } +}; +// ============================================================================== +/** + * \class scr_t + * \brief SCR register. + */ +struct scr_t { + /** Bytes 0-3 SD Association, bytes 4-7 reserved for manufacturer. */ + uint8_t scr[8]; + /** \return SCR_STRUCTURE field - must be zero.*/ + uint8_t srcStructure() const { + return scr[0] >> 4; + } + /** \return SD_SPEC field 0 - v1.0 or V1.01, 1 - 1.10, 2 - V2.00 or greater */ + uint8_t sdSpec() const { + return scr[0] & 0XF; + } + /** \return false if all zero, true if all one. */ + bool dataAfterErase() const { + return scr[1] & 0X80; + } + /** \return CPRM Security Version. */ + uint8_t sdSecurity() const { + return (scr[1] >> 4) & 0X7; + } + /** \return 0101b. */ + uint8_t sdBusWidths() const { + return scr[1] & 0XF; + } + /** \return true if V3.0 or greater. */ + bool sdSpec3() const { + return scr[2] & 0X80; + } + /** \return if true and sdSpecX is zero V4.xx. */ + bool sdSpec4() const { + return scr[2] & 0X4; + } + /** \return nonzero for version 5 or greater if sdSpec == 2, + sdSpec3 == true. Version is return plus four.*/ + uint8_t sdSpecX() const { + return (scr[2] & 0X3) << 2 | scr[3] >> 6; + } + /** \return bit map for support CMD58/59, CMD48/49, CMD23, and CMD20 */ + uint8_t cmdSupport() const { + return scr[3] & 0XF; + } + /** \return SD spec version */ + int16_t sdSpecVer() const { + if (sdSpec() > 2) { + return -1; + } else if (sdSpec() < 2) { + return sdSpec() ? 110 : 101; + } else if (!sdSpec3()) { + return 200; + } else if (!sdSpec4() && !sdSpecX()) { + return 300; + } + return 400 + 100 * sdSpecX(); + } +}; +// ============================================================================== +/** + * \class sds_t + * \brief SD Status. + */ +// fields are big endian +struct sds_t { + /** byte 0, bit 7-6 width, bit 5 secured mode, bits 4-0 reserved. */ + uint8_t busWidthSecureMode; + /** byte 1 reserved */ + uint8_t reserved1; + /** byte 2-3 zero for SD rd/wr memory card. */ + uint8_t sdCardType[2]; + /** byte 4-7 size of protected area big endian */ + uint8_t sizeOfProtectedArea[4]; + /** byte 8 speed class. */ + uint8_t speed; + /** byte 9 performance move */ + uint8_t performanceMove; + /** byte 10 AU size code. */ + uint8_t auSize; + /** byte 11-12 erase size big endian */ + uint8_t eraseSize[2]; + /** byte 13 erase timeout and erase offset */ + uint8_t eraseTimeoutOffset; + /** byte 14 */ + uint8_t uhsClassAuSize; + /** byte 15 */ + uint8_t videoSpeedClass; + /** byte 16-17 */ + uint8_t vscAuSize[2]; + /** byte 18-21 */ + uint8_t susAddr[3]; + /** byte 21 */ + uint8_t appPerfClass; + /** byte 22 */ + uint8_t perfEnhance; + /** byte 23 */ + uint8_t discardFule; + /** byte 24 */ + uint8_t reservedManufacturer[40]; + + /** \return appClass. */ + int appClass() { + return appPerfClass; + } + /** \return AU size in KB. or zero for error. */ + uint32_t auSizeKB() { + // 0XF mask and uint16_t array helps compiler optimize size on Uno. + uint8_t val = (auSize >> 4) & 0XF; + static const uint16_t au[] = {0, 16, 32, 64, 128, + 256, 512, 1024, 2048, 4096, + 8192, 12288, 16384, 24576, 32768}; + return val < 0XF ? au[val] : 65536UL; + } + /** \return current bus width or -1 for error. */ + uint8_t busWidth() const { + uint8_t w = busWidthSecureMode >> 6; + return w == 2 ? 4 : w == 0 ? 1 : -1; + } + /** \return true is discard operation is supported else true. */ + bool discard() const { + return discardFule & 2; + } + /** \return eraseSize in AUs. */ + uint16_t eraseSizeAU() const { + return static_cast < uint16_t > (eraseSize[0]) << 8 | + static_cast < uint16_t > (eraseSize[1]); + } + /** \return eraseTimeout seconds. */ + uint8_t eraseTimeout() const { + return eraseTimeoutOffset >> 2; + } + /** \return eraseOffset seconds. */ + uint8_t eraseOffset() const { + return eraseTimeoutOffset & 3; + } + /** \return true if full user logical erase is supported else false. */ + bool file() const { + return discardFule & 1; + } + /** \return true for secure mode else false. */ + bool secureMode() const { + return busWidthSecureMode & 0X20; + } + /** \return speed class or -1 for error. */ + int speedClass() const { + return speed < 4 ? 2 * speed : speed == 4 ? 10 : -1; + } + /** \return UHS Speed Grade. */ + int uhsClass() const { + return uhsClassAuSize >> 4; + } + /** \return Video Speed */ + int videoClass() { + return videoSpeedClass; + } +}; diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/SdCardInterface.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/SdCardInterface.h new file mode 100644 index 00000000000..5d36ae4d043 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/SdCard/SdCardInterface.h @@ -0,0 +1,118 @@ +/** + * Copyright (c) 2011-2025 Bill Greiman, 2026 Tim Cocks for Adafruit Industries + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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. + */ +/** + * \file + * \brief Abstract interface for an SD card. + */ +#pragma once +#include "../common/FsBlockDeviceInterface.h" +#include "SdCardInfo.h" +/** + * \class SdCardInterface + * \brief Abstract interface for an SD card. + */ +class SdCardInterface: public FsBlockDeviceInterface { +public: + /** CMD6 Switch mode: Check Function Set Function. + * \param[in] arg CMD6 argument. + * \param[out] status return status data. + * + * \return true for success or false for failure. + */ + virtual bool cardCMD6(uint32_t arg, uint8_t *status) = 0; + /** Erase a range of sectors. + * + * \param[in] firstSector The address of the first sector in the range. + * \param[in] lastSector The address of the last sector in the range. + * + * \return true for success or false for failure. + */ + virtual bool erase(Sector_t firstSector, Sector_t lastSector) = 0; + /** \return error code. */ + virtual uint8_t errorCode() const = 0; + /** \return error data. */ + virtual uint32_t errorData() const = 0; + /** \return false by default */ + virtual bool hasDedicatedSpi() { + return false; + } + /** \return false by default */ + virtual bool isDedicatedSpi() { + return false; + } + /** \return false by default */ + virtual bool isSpi() { + return false; + } + /** Set SPI sharing state + * \param[in] value desired state. + * \return false by default. + */ + virtual bool setDedicatedSpi(bool value) { + (void)value; + return false; + } + /** + * Read a card's CID register. + * + * \param[out] cid pointer to area for returned data. + * + * \return true for success or false for failure. + */ + virtual bool readCID(cid_t *cid) = 0; + /** + * Read a card's CSD register. + * + * \param[out] csd pointer to area for returned data. + * + * \return true for success or false for failure. + */ + virtual bool readCSD(csd_t *csd) = 0; + /** Read OCR register. + * + * \param[out] ocr Value of OCR register. + * \return true for success or false for failure. + */ + virtual bool readOCR(uint32_t *ocr) = 0; + /** Read SCR register. + * + * \param[out] scr Value of SCR register. + * \return true for success or false for failure. + */ + virtual bool readSCR(scr_t *scr) = 0; + /** Return the 64 byte SD Status register. + * \param[out] sds location for 64 status bytes. + * \return true for success or false for failure. + */ + virtual bool readSDS(sds_t *sds) = 0; + /** \return card status. */ + virtual uint32_t status() { + return 0XFFFFFFFF; + } + /** Return the card type: SD V1, SD V2 or SDHC/SDXC + * \return 0 - SD V1, 1 - SD V2, or 3 - SDHC/SDXC. + */ + virtual uint8_t type() const = 0; +}; diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/common/FsBlockDeviceInterface.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/common/FsBlockDeviceInterface.h new file mode 100644 index 00000000000..f5f5b0a8b0c --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/common/FsBlockDeviceInterface.h @@ -0,0 +1,117 @@ +/** + * Copyright (c) 2011-2025 Bill Greiman + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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. + */ +/** + * \file + * \brief FsBlockDeviceInterface include file. + */ +#pragma once +#include +#include +/** + * \class FsBlockDeviceInterface + * \brief FsBlockDeviceInterface class. + */ +class FsBlockDeviceInterface { +public: + virtual ~FsBlockDeviceInterface() { + } + + /** end use of device */ + virtual void end() { + } + /** + * Check for FsBlockDevice busy. + * + * \return true if busy else false. + */ + virtual bool isBusy() = 0; + /** + * Read a sector. + * + * \param[in] sector Logical sector to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return true for success or false for failure. + */ + virtual bool readSector(Sector_t sector, uint8_t *dst) = 0; + + /** + * Read multiple sectors. + * + * \param[in] sector Logical sector to be read. + * \param[in] ns Number of sectors to be read. + * \param[out] dst Pointer to the location that will receive the data. + * \return true for success or false for failure. + */ + virtual bool readSectors(Sector_t sector, uint8_t *dst, size_t ns) = 0; + + /** \return device size in sectors. */ + virtual Sector_t sectorCount() = 0; + + /** End multi-sector transfer and go to idle state. + * \return true for success or false for failure. + */ + virtual bool syncDevice() = 0; + + /** + * Writes a sector. + * + * \param[in] sector Logical sector to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return true for success or false for failure. + */ + virtual bool writeSector(Sector_t sector, const uint8_t *src) = 0; + + /** + * Write multiple sectors. + * + * \param[in] sector Logical sector to be written. + * \param[in] ns Number of sectors to be written. + * \param[in] src Pointer to the location of the data to be written. + * \return true for success or false for failure. + */ + virtual bool writeSectors(Sector_t sector, const uint8_t *src, size_t ns) = 0; + + // Adafruit SdFat v1 BaseBlockDRiver API for backward-compatible + // maybe removal since v1 is deprecated now + virtual bool syncBlocks() { + return syncDevice(); + } + + virtual bool readBlock(uint32_t block, uint8_t *dst) { + return readSector(block, dst); + } + + virtual bool readBlocks(uint32_t block, uint8_t *dst, size_t nb) { + return readSectors(block, dst, nb); + } + + virtual bool writeBlock(uint32_t block, const uint8_t *src) { + return writeSector(block, src); + } + + virtual bool writeBlocks(uint32_t block, const uint8_t *src, size_t nb) { + return writeSectors(block, src, nb); + } +}; diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/common/SysCall.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/common/SysCall.h new file mode 100644 index 00000000000..e8735ff2fd6 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/common/SysCall.h @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2011-2025 Bill Greiman + * This file is part of the SdFat library for SD memory cards. + * + * MIT License + * + * 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. + */ +/** + * \file + * \brief SysCall class + * + * CircuitPython vendored, trimmed copy. The upstream SysCall.h pulls in + * SdFatConfig.h (and through it Arduino.h / avr/io.h) plus PrintBasic.h. The + * PIO SDIO card driver only needs the Sector_t typedef, nullptr handling, and + * the SD_MAX_INIT_RATE_KHZ tuning constant, so we provide just those here and + * leave the Arduino/Print machinery out of the build. + */ +#pragma once +#include +#include + +#if __cplusplus < 201103 +#warning nullptr defined +/** Define nullptr if not C++11 */ +#define nullptr NULL +#endif // __cplusplus < 201103 +// ------------------------------------------------------------------------------ +/** Type for FsBlockDevice sector */ +typedef uint32_t Sector_t; +// ------------------------------------------------------------------------------ +// SdCardInfo.h declares (but, in this vendored build, never defines) two error +// printing helpers that take a print_t*. Forward declare the type so those +// pointer-only declarations parse without dragging in PrintBasic / Arduino. +class print_t; +// ------------------------------------------------------------------------------ +// Normally supplied by SdFatConfig.h. +#ifndef SD_MAX_INIT_RATE_KHZ +#define SD_MAX_INIT_RATE_KHZ 400 +#endif // SD_MAX_INIT_RATE_KHZ diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/cxx_runtime.cpp b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/cxx_runtime.cpp new file mode 100644 index 00000000000..85a28ed8d95 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/cxx_runtime.cpp @@ -0,0 +1,33 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Minimal freestanding C++ ABI support for the vendored SdFat PIO driver. +// +// CircuitPython links the firmware with gcc and without libstdc++/libsupc++, so +// a few C++ ABI symbols that the driver's class hierarchy makes the compiler +// reference must be provided here: +// * PioSdioCard's vtable contains a deleting destructor slot that names +// `operator delete`, even though we only ever placement-new the object and +// call its destructor explicitly (so it is never actually invoked). +// * The abstract base classes (SdCardInterface / FsBlockDeviceInterface) have +// pure virtuals, so their transient vtables reference `__cxa_pure_virtual`. +// Both are effectively unreachable at run time; they exist only to satisfy the +// linker. + +#include +#include + +extern "C" void __cxa_pure_virtual(void) { + abort(); +} + +void operator delete(void *ptr) noexcept { + free(ptr); +} + +void operator delete(void *ptr, size_t) noexcept { + free(ptr); +} diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/shim.cpp b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/shim.cpp new file mode 100644 index 00000000000..5aeea4c8e94 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/shim.cpp @@ -0,0 +1,80 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// C-callable shim around the vendored C++ PioSdioCard driver. This is the only +// translation unit that includes the C++ class; everything the common-hal C +// code needs is exposed through the extern "C" entry points in shim.h. + +#include + +#include "hardware/clocks.h" + +#include "SdCard/PioSdio/PioSdioCard.h" +#include "shim.h" + +static_assert(sizeof(PioSdioCard) <= SDIOIO_PIO_CARD_STORAGE_SIZE, + "SDIOIO_PIO_CARD_STORAGE_SIZE is too small for PioSdioCard"); +static_assert(alignof(PioSdioCard) <= alignof(sdioio_pio_card_storage_t), + "sdioio_pio_card_storage_t is not aligned enough for PioSdioCard"); + +extern "C" { + +void sdfat_pio_card_new(void *storage) { + new (storage) PioSdioCard(); +} + +void sdfat_pio_card_free(void *storage) { + reinterpret_cast(storage)->~PioSdioCard(); +} + +bool sdfat_pio_card_begin(void *storage, uint32_t clk_pin, uint32_t cmd_pin, + uint32_t dat0_pin, uint32_t frequency, uint32_t *actual_frequency_out) { + PioSdioCard *card = reinterpret_cast(storage); + + // The PIO driver clocks four PIO cycles per SD clock, so the resulting SD + // clock is clk_sys / (4 * clkDiv). Invert that to turn the requested rate + // into a divisor, clamped to the fastest the divisor allows (clkDiv >= 1). + float sys_hz = (float)clock_get_hz(clk_sys); + float clk_div = sys_hz / (4.0f * (float)frequency); + if (clk_div < 1.0f) { + clk_div = 1.0f; + } + + bool ok = card->begin(PioSdioConfig(clk_pin, cmd_pin, dat0_pin, clk_div)); + + if (actual_frequency_out != nullptr) { + *actual_frequency_out = (uint32_t)(sys_hz / (4.0f * clk_div)); + } + return ok; +} + +uint32_t sdfat_pio_card_sector_count(void *storage) { + return reinterpret_cast(storage)->sectorCount(); +} + +bool sdfat_pio_card_read_sectors(void *storage, uint32_t start_sector, + uint8_t *dst, size_t num_sectors) { + return reinterpret_cast(storage)->readSectors(start_sector, dst, num_sectors); +} + +bool sdfat_pio_card_write_sectors(void *storage, uint32_t start_sector, + const uint8_t *src, size_t num_sectors) { + return reinterpret_cast(storage)->writeSectors(start_sector, src, num_sectors); +} + +uint8_t sdfat_pio_card_error_code(void *storage) { + return reinterpret_cast(storage)->errorCode(); +} + +void sdfat_pio_card_end(void *storage) { + reinterpret_cast(storage)->end(); +} + +void sdfat_pio_card_never_reset(void *storage) { + reinterpret_cast(storage)->neverReset(); +} + +} // extern "C" diff --git a/ports/raspberrypi/common-hal/sdioio/sdfat_pio/shim.h b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/shim.h new file mode 100644 index 00000000000..c968ea0f734 --- /dev/null +++ b/ports/raspberrypi/common-hal/sdioio/sdfat_pio/shim.h @@ -0,0 +1,74 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// C-callable shim around the vendored C++ PioSdioCard driver. All use of the +// C++ class is confined to shim.cpp so the common-hal C sources never include +// any C++ headers. + +#pragma once + +#include +#include +#include + +// Size of the opaque storage the C object struct reserves for an in-place +// PioSdioCard instance. shim.cpp static_asserts that the real class fits. The +// real object is well under this (~320 bytes); the slack is intentional so the +// build does not break if the upstream class grows slightly. +#define SDIOIO_PIO_CARD_STORAGE_SIZE 512 + +// Opaque storage for one PioSdioCard, constructed in place by +// sdfat_pio_card_new(). The class's members are at most pointer/word aligned, so +// a pointer member is enough to align the buffer (and matches what the GC heap +// guarantees); shim.cpp static_asserts that this is sufficient. Kept as a plain +// union so the C struct needs no knowledge of the C++ type. +typedef union { + void *for_alignment; + uint8_t bytes[SDIOIO_PIO_CARD_STORAGE_SIZE]; +} sdioio_pio_card_storage_t; + +#ifdef __cplusplus +extern "C" { +#endif + +// Construct a PioSdioCard in place in the given storage buffer. +void sdfat_pio_card_new(void *storage); + +// Run the destructor for the in-place PioSdioCard. +void sdfat_pio_card_free(void *storage); + +// Initialize the card. dat0_pin is the base of four consecutive data GPIOs. +// frequency is the requested SD clock in Hz; the achieved rate is written to +// actual_frequency_out (in Hz) when it is non-NULL. Returns true on success. +bool sdfat_pio_card_begin(void *storage, uint32_t clk_pin, uint32_t cmd_pin, + uint32_t dat0_pin, uint32_t frequency, uint32_t *actual_frequency_out); + +// Number of 512-byte sectors on the card (0 if unknown). +uint32_t sdfat_pio_card_sector_count(void *storage); + +// Read `num_sectors` 512-byte sectors starting at `start_sector` into `dst`. +// Returns true on success. The driver is synchronous/polling, so this blocks. +bool sdfat_pio_card_read_sectors(void *storage, uint32_t start_sector, + uint8_t *dst, size_t num_sectors); + +// Write `num_sectors` 512-byte sectors from `src` starting at `start_sector`. +// Returns true on success. Blocks like the read path. +bool sdfat_pio_card_write_sectors(void *storage, uint32_t start_sector, + const uint8_t *src, size_t num_sectors); + +// Last error code from the driver (see SdCardInfo.h). +uint8_t sdfat_pio_card_error_code(void *storage); + +// Release the card's PIO/state-machine resources. +void sdfat_pio_card_end(void *storage); + +// Mark the card's PIO state machines as surviving a soft reset, so rp2pio's +// reset path leaves them (and their loaded programs) in place. +void sdfat_pio_card_never_reset(void *storage); + +#ifdef __cplusplus +} +#endif diff --git a/ports/raspberrypi/common-hal/socketpool/Socket.c b/ports/raspberrypi/common-hal/socketpool/Socket.c index fb1fdfb5f65..840558d1ac3 100644 --- a/ports/raspberrypi/common-hal/socketpool/Socket.c +++ b/ports/raspberrypi/common-hal/socketpool/Socket.c @@ -35,7 +35,7 @@ #include "lwip/timeouts.h" #include "lwip/udp.h" -#include "sdk/src/rp2_common/pico_cyw43_arch/include/pico/cyw43_arch.h" +#include "pico/cyw43_arch.h" mp_obj_t socketpool_ip_addr_to_str(const ip_addr_t *addr) { char ip_str[IPADDR_STRLEN_MAX]; // big enough for any supported address type @@ -89,7 +89,7 @@ static mp_obj_t socketpool_ip_addr_and_port_to_tuple(const ip_addr_t *addr, int // socket API. // Extension to lwIP error codes -// Matches lwIP 2.0.3 +// Matches lwIP 2.2.1 #undef _ERR_BADF #define _ERR_BADF -17 static const int error_lookup_table[] = { @@ -251,7 +251,7 @@ static void _lwip_tcp_err_unaccepted(void *arg, err_t err) { // because it's only ever used by lwIP if tcp_connect is called on the TCP PCB. socketpool_socket_obj_t *socket = (socketpool_socket_obj_t *)pcb->connected; - // Array is not volatile because thiss callback is executed within the lwIP context + // Array is not volatile because this callback is executed within the lwIP context uint8_t alloc = socket->incoming.connection.alloc; struct tcp_pcb **tcp_array = (struct tcp_pcb **)lwip_socket_incoming_array(socket); @@ -473,7 +473,12 @@ static mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, MICROPY_PY_LWIP_ENTER - u16_t available = tcp_sndbuf(socket->pcb.tcp); + // If the socket is still connecting then don't let data be written to it. + // Otherwise, get the number of available bytes in the output buffer. + u16_t available = 0; + if (socket->state != STATE_CONNECTING) { + available = tcp_sndbuf(socket->pcb.tcp); + } if (available == 0) { // Non-blocking socket @@ -490,7 +495,8 @@ static mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, // If peer fully closed socket, we would have socket->state set to ERR_RST (connection // reset) by error callback. // Avoid sending too small packets, so wait until at least 16 bytes available - while (socket->state >= STATE_CONNECTED && (available = tcp_sndbuf(socket->pcb.tcp)) < 16) { + while (socket->state == STATE_CONNECTING + || (socket->state >= STATE_CONNECTED && (available = tcp_sndbuf(socket->pcb.tcp)) < 16)) { MICROPY_PY_LWIP_EXIT if (socket->timeout != (unsigned)-1 && mp_hal_ticks_ms() - start > socket->timeout) { *_errno = MP_ETIMEDOUT; @@ -531,9 +537,10 @@ static mp_uint_t lwip_tcp_send(socketpool_socket_obj_t *socket, const byte *buf, MICROPY_PY_LWIP_REENTER } - // If the output buffer is getting full then send the data to the lower layers - if (err == ERR_OK && tcp_sndbuf(socket->pcb.tcp) < TCP_SND_BUF / 4) { - err = tcp_output(socket->pcb.tcp); + // Use nagle algorithm to determine when to send segment buffer (can be + // disabled with TCP_NODELAY socket option) + if (err == ERR_OK) { + err = tcp_output_nagle(socket->pcb.tcp); } MICROPY_PY_LWIP_EXIT @@ -551,6 +558,12 @@ static mp_uint_t lwip_tcp_receive(socketpool_socket_obj_t *socket, byte *buf, mp // Check for any pending errors STREAM_ERROR_CHECK(socket); + if (socket->state == STATE_LISTENING) { + // original socket in listening state, not the accepted connection. + *_errno = MP_ENOTCONN; + return -1; + } + if (socket->incoming.pbuf == NULL) { // Non-blocking socket @@ -1071,7 +1084,8 @@ bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *socket, int ba socket->incoming.connection.tcp.item = NULL; } else { socket->incoming.connection.alloc = backlog; - socket->incoming.connection.tcp.array = m_new0(struct tcp_pcb *, backlog); + socket->incoming.connection.tcp.array = m_malloc_without_collect(sizeof(struct tcp_pcb *) * backlog); + memset(socket->incoming.connection.tcp.array, 0, sizeof(struct tcp_pcb *) * backlog); } socket->incoming.connection.iget = 0; socket->incoming.connection.iput = 0; @@ -1212,6 +1226,20 @@ int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int l bool enable = optlen == sizeof(&zero) && memcmp(value, &zero, optlen); switch (level) { + case SOCKETPOOL_IPPROTO_IP: + switch (optname) { + case SOCKETPOOL_IP_MULTICAST_TTL: + if (self->type != SOCKETPOOL_SOCK_DGRAM) { + return -MP_EOPNOTSUPP; + } + if (self->pcb.udp == NULL || optlen < sizeof(uint8_t)) { + return -MP_EINVAL; + } + udp_set_multicast_ttl(self->pcb.udp, *(const uint8_t *)value); + return 0; + } + break; + case SOCKETPOOL_IPPROTO_TCP: switch (optname) { case SOCKETPOOL_TCP_NODELAY: diff --git a/ports/raspberrypi/common-hal/usb_host/Port.c b/ports/raspberrypi/common-hal/usb_host/Port.c index 5fb4506a145..f06e9e5d71d 100644 --- a/ports/raspberrypi/common-hal/usb_host/Port.c +++ b/ports/raspberrypi/common-hal/usb_host/Port.c @@ -11,17 +11,16 @@ #include "supervisor/shared/serial.h" #include "supervisor/usb.h" -#include "src/common/pico_time/include/pico/time.h" -#ifdef PICO_RP2040 -#include "src/rp2040/hardware_structs/include/hardware/structs/mpu.h" -#include "src/rp2_common/cmsis/stub/CMSIS/Device/RP2040/Include/RP2040.h" +#include "pico/time.h" +#include "hardware/structs/mpu.h" +#if PICO_RP2040 +#include "RP2040.h" // (cmsis) #endif -#ifdef PICO_RP2350 -#include "src/rp2350/hardware_structs/include/hardware/structs/mpu.h" -#include "src/rp2_common/cmsis/stub/CMSIS/Device/RP2350/Include/RP2350.h" +#if PICO_RP2350 +#include "RP2350.h" // (cmsis) #endif -#include "src/rp2_common/hardware_dma/include/hardware/dma.h" -#include "src/rp2_common/pico_multicore/include/pico/multicore.h" +#include "hardware/dma.h" +#include "pico/multicore.h" #include "py/runtime.h" @@ -33,9 +32,42 @@ usb_host_port_obj_t usb_host_instance; -static PIO pio_instances[2] = {pio0, pio1}; volatile bool _core1_ready = false; +// Core1 posts TinyUSB events while core0 may hold the queue FIFO mutex. The +// contended wait path calls best_effort_wfe_or_timeout() and time_us_64(), +// which normally live in flash, but core1 must not touch flash (see the MPU +// setup in core1_main below). These RAM-resident replacements are linked in +// with --wrap on USB host builds only (see the port Makefile). Issue #11116. +// +uint64_t __wrap_time_us_64(void); +bool __wrap_best_effort_wfe_or_timeout(absolute_time_t timeout_timestamp); + +// The same hi/lo/hi re-read loop as the SDK's timer_time_us_64, to defeat +// rollover between the two 32-bit halves. +uint64_t __not_in_flash_func(__wrap_time_us_64)(void) { + uint32_t hi = timer_hw->timerawh; + uint32_t lo; + do { + lo = timer_hw->timerawl; + uint32_t next_hi = timer_hw->timerawh; + if (hi == next_hi) { + break; + } + hi = next_hi; + } while (true); + return ((uint64_t)hi << 32) | lo; +} + +// Mirrors the SDK's own PICO_TIME_DEFAULT_ALARM_POOL_DISABLED fallback +// (a poll of the clock with no __wfe): "best effort" explicitly permits +// returning early, and every SDK caller re-checks in a loop. Polling honors +// the timeout exactly and avoids dragging the alarm pool machinery into RAM. +bool __not_in_flash_func(__wrap_best_effort_wfe_or_timeout)(absolute_time_t timeout_timestamp) { + tight_loop_contents(); + return __wrap_time_us_64() >= to_us_since_boot(timeout_timestamp); +} + static void __not_in_flash_func(core1_main)(void) { // The MPU is reset before this starts. SysTick->LOAD = (uint32_t)((common_hal_mcu_processor_get_frequency() / 1000) - 1UL); @@ -75,29 +107,25 @@ static void __not_in_flash_func(core1_main)(void) { } } -static uint8_t _sm_free_count(uint8_t pio_index) { - PIO pio = pio_instances[pio_index]; - uint8_t free_count = 0; - for (size_t j = 0; j < NUM_PIO_STATE_MACHINES; j++) { - if (!pio_sm_is_claimed(pio, j)) { - free_count++; - } +// As of 0.6.1, the PIO resource requirement is 1 PIO with 3 state machines & +// 32 instructions. Since there are only 32 instructions in a state machine, it should +// be impossible to have an allocated state machine but 32 instruction slots available; +// go ahead and check for it anyway. +// +// Since we require ALL state machines to be available, it's not possible for the GPIO +// ranges to mismatch on rp2350b +static size_t get_usb_pio(void) { + size_t pio_index = rp2pio_statemachine_find_pio(32, NUM_PIO_STATE_MACHINES); + if (pio_index == NUM_PIOS) { + mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use")); } - return free_count; + return pio_index; } -static bool _has_program_room(uint8_t pio_index, uint8_t program_size) { - PIO pio = pio_instances[pio_index]; - pio_program_t program_struct = { - .instructions = NULL, - .length = program_size, - .origin = -1 - }; - return pio_can_add_program(pio, &program_struct); -} usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, const mcu_pin_obj_t *dm) { - if (dp->number + 1 != dm->number) { + if ((dp->number + 1 != dm->number) + && (dp->number - 1 != dm->number)) { raise_ValueError_invalid_pins(); } usb_host_port_obj_t *self = &usb_host_instance; @@ -116,39 +144,32 @@ usb_host_port_obj_t *common_hal_usb_host_port_construct(const mcu_pin_obj_t *dp, pio_usb_configuration_t pio_cfg = PIO_USB_DEFAULT_CONFIG; pio_cfg.skip_alarm_pool = true; pio_cfg.pin_dp = dp->number; - // Allocating the peripherals like this works on Pico W, where the - // "preferred PIO" for the cyw43 wifi chip is PIO 1. - pio_cfg.pio_tx_num = 1; // uses 22 instructions and 1 SM - pio_cfg.pio_rx_num = 0; // uses 31 instructions and 2 SM. - if (!_has_program_room(pio_cfg.pio_tx_num, 22) || _sm_free_count(pio_cfg.pio_tx_num) < 1 || - !_has_program_room(pio_cfg.pio_rx_num, 31) || _sm_free_count(pio_cfg.pio_rx_num) < 2) { - mp_raise_RuntimeError(MP_ERROR_TEXT("All state machines in use")); + if (dp->number - 1 == dm->number) { + pio_cfg.pinout = PIO_USB_PINOUT_DMDP; } - pio_cfg.tx_ch = dma_claim_unused_channel(false); // DMA channel - if (pio_cfg.tx_ch < 0) { + pio_cfg.pio_tx_num = get_usb_pio(); + pio_cfg.pio_rx_num = pio_cfg.pio_tx_num; + int dma_ch = dma_claim_unused_channel(false); + if (dma_ch < 0) { mp_raise_RuntimeError(MP_ERROR_TEXT("All dma channels in use")); } + pio_cfg.tx_ch = dma_ch; self->base.type = &usb_host_port_type; self->dp = dp; self->dm = dm; + claim_pin(dp); + claim_pin(dm); - PIO tx_pio = pio_instances[pio_cfg.pio_tx_num]; - pio_cfg.sm_tx = pio_claim_unused_sm(tx_pio, false); - PIO rx_pio = pio_instances[pio_cfg.pio_rx_num]; - pio_cfg.sm_rx = pio_claim_unused_sm(rx_pio, false); - pio_cfg.sm_eop = pio_claim_unused_sm(rx_pio, false); + PIO pio = pio_get_instance(pio_cfg.pio_tx_num); // Unclaim everything so that the library can. dma_channel_unclaim(pio_cfg.tx_ch); - pio_sm_unclaim(tx_pio, pio_cfg.sm_tx); - pio_sm_unclaim(rx_pio, pio_cfg.sm_rx); - pio_sm_unclaim(rx_pio, pio_cfg.sm_eop); // Set all of the state machines to never reset. - rp2pio_statemachine_never_reset(tx_pio, pio_cfg.sm_tx); - rp2pio_statemachine_never_reset(rx_pio, pio_cfg.sm_rx); - rp2pio_statemachine_never_reset(rx_pio, pio_cfg.sm_eop); + rp2pio_statemachine_never_reset(pio, pio_cfg.sm_tx); + rp2pio_statemachine_never_reset(pio, pio_cfg.sm_rx); + rp2pio_statemachine_never_reset(pio, pio_cfg.sm_eop); common_hal_never_reset_pin(dp); common_hal_never_reset_pin(dm); diff --git a/ports/raspberrypi/common-hal/wifi/Radio.c b/ports/raspberrypi/common-hal/wifi/Radio.c index 3250ed4d7c7..73e7794ecc2 100644 --- a/ports/raspberrypi/common-hal/wifi/Radio.c +++ b/ports/raspberrypi/common-hal/wifi/Radio.c @@ -5,6 +5,7 @@ // SPDX-License-Identifier: MIT #include "supervisor/port.h" +#include "shared-bindings/wifi/PowerManagement.h" #include "shared-bindings/wifi/Radio.h" #include "shared-bindings/wifi/Network.h" @@ -47,7 +48,7 @@ static inline void nw_put_le32(uint8_t *buf, uint32_t x) { buf[3] = x >> 24; } -NORETURN static void ro_attribute(qstr attr) { +MP_NORETURN static void ro_attribute(qstr attr) { mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q is read-only for this board"), attr); } @@ -107,6 +108,41 @@ void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t cyw43_ioctl(&cyw43_state, CYW43_IOCTL_SET_VAR, 9 + 4, buf, CYW43_ITF_AP); } +wifi_power_management_t common_hal_wifi_radio_get_power_management(wifi_radio_obj_t *self) { + uint32_t pm_value = cyw43_get_power_management_value(); + + switch (pm_value) { + case CONST_CYW43_PERFORMANCE_PM: + return POWER_MANAGEMENT_MIN; + case CONST_CYW43_AGGRESSIVE_PM: + return POWER_MANAGEMENT_MAX; + case CONST_CYW43_NONE_PM: + return POWER_MANAGEMENT_NONE; + default: + return POWER_MANAGEMENT_UNKNOWN; + } +} + + +void common_hal_wifi_radio_set_power_management(wifi_radio_obj_t *self, wifi_power_management_t power_management) { + uint32_t pm_setting = CONST_CYW43_DEFAULT_PM; + switch (power_management) { + case POWER_MANAGEMENT_MIN: + pm_setting = CONST_CYW43_PERFORMANCE_PM; + break; + case POWER_MANAGEMENT_MAX: + pm_setting = CONST_CYW43_AGGRESSIVE_PM; + break; + case POWER_MANAGEMENT_NONE: + pm_setting = CONST_CYW43_NONE_PM; + break; + default: + // Should not get here. + break; + } + cyw43_set_power_management_value(pm_setting); +} + mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) { return common_hal_wifi_radio_get_mac_address(self); } @@ -121,7 +157,7 @@ mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, u mp_raise_RuntimeError(MP_ERROR_TEXT("Already scanning for wifi networks")); } if (!common_hal_wifi_radio_get_enabled(self)) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Wifi is not enabled")); + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); } wifi_scannednetworks_obj_t *scan = mp_obj_malloc(wifi_scannednetworks_obj_t, &wifi_scannednetworks_type); mp_obj_t args[] = { mp_const_empty_tuple, MP_OBJ_NEW_SMALL_INT(16) }; @@ -157,7 +193,7 @@ void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self) { void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint32_t authmode, uint8_t max_connections) { if (!common_hal_wifi_radio_get_enabled(self)) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Wifi is not enabled")); + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); } /* TODO: If the AP is stopped once it cannot be restarted. @@ -207,7 +243,7 @@ bool common_hal_wifi_radio_get_ap_active(wifi_radio_obj_t *self) { void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) { if (!common_hal_wifi_radio_get_enabled(self)) { - mp_raise_RuntimeError(MP_ERROR_TEXT("wifi is not enabled")); + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); } cyw43_arch_disable_ap_mode(); @@ -285,7 +321,7 @@ static bool connection_unchanged(wifi_radio_obj_t *self, const uint8_t *ssid, si wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t *bssid, size_t bssid_len) { if (!common_hal_wifi_radio_get_enabled(self)) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Wifi is not enabled")); + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); } if (ssid_len > 32) { @@ -574,7 +610,7 @@ void common_hal_wifi_radio_set_dns(wifi_radio_obj_t *self, mp_obj_t dns_addrs_ob addr.addr = IPADDR_NONE; } else { mp_obj_t dns_addr_obj = mp_obj_subscr(dns_addrs_obj, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL); - socketpool_resolve_host_raise(dns_addr_obj, &addr); + socketpool_resolve_host_raise(mp_obj_str_get_str(dns_addr_obj), &addr); } dns_setserver(0, &addr); } diff --git a/ports/raspberrypi/common-hal/wifi/__init__.c b/ports/raspberrypi/common-hal/wifi/__init__.c index 5fbe3fe58d1..84dba581fbf 100644 --- a/ports/raspberrypi/common-hal/wifi/__init__.c +++ b/ports/raspberrypi/common-hal/wifi/__init__.c @@ -15,6 +15,10 @@ #include "py/mpstate.h" #include "py/runtime.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" +#endif + wifi_radio_obj_t common_hal_wifi_radio_obj; #include "supervisor/port.h" @@ -45,6 +49,15 @@ void common_hal_wifi_init(bool user_initiated) { // set station mode to avoid the default SoftAP common_hal_wifi_radio_start_station(self); + + #if CIRCUITPY_SETTINGS_TOML + // Must be set after station starts. + char hostname[sizeof(self->hostname)]; + if (settings_get_str("CIRCUITPY_WIFI_HOSTNAME", hostname, sizeof(hostname)) == SETTINGS_OK) { + common_hal_wifi_radio_set_hostname(self, hostname); + } + #endif + // start wifi common_hal_wifi_radio_set_enabled(self, true); } diff --git a/ports/raspberrypi/common-hal/wifi/__init__.h b/ports/raspberrypi/common-hal/wifi/__init__.h index 73988e84379..4005c48a3cd 100644 --- a/ports/raspberrypi/common-hal/wifi/__init__.h +++ b/ports/raspberrypi/common-hal/wifi/__init__.h @@ -11,7 +11,7 @@ #include "lwip/ip_addr.h" void wifi_reset(void); -NORETURN void raise_cyw_error(int err); +MP_NORETURN void raise_cyw_error(int err); #define CHECK_CYW_RESULT(x) do { int res = (x); if (res != 0) raise_cyw_error(res); } while (0) void ipaddress_ipaddress_to_lwip(mp_obj_t ip_address, ip_addr_t *lwip_ip_address); diff --git a/ports/raspberrypi/common-hal/wiznet/PIO_SPI.c b/ports/raspberrypi/common-hal/wiznet/PIO_SPI.c new file mode 100755 index 00000000000..30fe8c5d25c --- /dev/null +++ b/ports/raspberrypi/common-hal/wiznet/PIO_SPI.c @@ -0,0 +1,123 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "bindings/wiznet/PIO_SPI.h" + +#include "shared/runtime/interrupt_char.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "supervisor/board.h" +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Pin.h" + +#include "hardware/dma.h" +#include "hardware/gpio.h" +#include "hardware/pio.h" +#include "hardware/clocks.h" + +#include "wizchip_pio_spi.h" + +#define NO_INSTANCE 0xff + +#ifndef PIO_SPI_PREFERRED_PIO +#define PIO_SPI_PREFERRED_PIO 1 +#endif + +// All wiznet spi operations must start with writing a 3 byte header + +wiznet_pio_spi_config_t wiznet_pio_spi_config; +wiznet_pio_spi_handle_t wiznet_pio_spi_handle = NULL; + +void common_hal_wiznet_pio_spi_construct(wiznet_pio_spi_obj_t *self, + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, bool half_duplex) { + + if (half_duplex) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_half_duplex); + } + + wiznet_pio_spi_config.data_in_pin = miso->number; + wiznet_pio_spi_config.data_out_pin = mosi->number; + wiznet_pio_spi_config.clock_pin = clock->number; + + if (wiznet_pio_spi_handle != NULL) { + wiznet_pio_spi_close(wiznet_pio_spi_handle); + } + + wiznet_pio_spi_handle = wiznet_pio_spi_open(&wiznet_pio_spi_config); + (*wiznet_pio_spi_handle)->set_active(wiznet_pio_spi_handle); + +} + +bool common_hal_wiznet_pio_spi_deinited(wiznet_pio_spi_obj_t *self) { + return wiznet_pio_spi_config.clock_pin == 0; +} + +void common_hal_wiznet_pio_spi_deinit(wiznet_pio_spi_obj_t *self) { + if (common_hal_wiznet_pio_spi_deinited(self)) { + return; + } + + common_hal_reset_pin(self->clock); + common_hal_reset_pin(self->MOSI); + common_hal_reset_pin(self->MISO); + + wiznet_pio_spi_config.clock_pin = 0; +} + +bool common_hal_wiznet_pio_spi_configure(wiznet_pio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + + uint32_t clock = clock_get_hz(clk_sys); + uint32_t clock_div = clock / baudrate; + + if (clock_div > clock / 4) { + clock_div = clock / 4; + } + + wiznet_pio_spi_config.clock_div_major = clock_div; + wiznet_pio_spi_config.clock_div_minor = 0; + + return true; +} + +bool common_hal_wiznet_pio_spi_try_lock(wiznet_pio_spi_obj_t *self) { + if (common_hal_wiznet_pio_spi_deinited(self)) { + return false; + } + + bool grabbed_lock = false; + if (!self->has_lock) { + grabbed_lock = true; + self->has_lock = true; + } + return grabbed_lock; +} + +bool common_hal_wiznet_pio_spi_has_lock(wiznet_pio_spi_obj_t *self) { + return self->has_lock; +} + +void common_hal_wiznet_pio_spi_unlock(wiznet_pio_spi_obj_t *self) { + self->has_lock = false; +} + +bool common_hal_wiznet_pio_spi_write(wiznet_pio_spi_obj_t *self, + const uint8_t *data, size_t len) { + wiznet_pio_spi_write_buffer(data, len); + return true; +} + +bool common_hal_wiznet_pio_spi_read(wiznet_pio_spi_obj_t *self, + uint8_t *data, size_t len, uint8_t write_value) { + wiznet_pio_spi_read_buffer(data, len); + return true; +} + +bool common_hal_wiznet_pio_spi_transfer(wiznet_pio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len) { + return wiznet_pio_spi_transfer(data_out, len, data_in, len); +} diff --git a/ports/raspberrypi/common-hal/wiznet/PIO_SPI.h b/ports/raspberrypi/common-hal/wiznet/PIO_SPI.h new file mode 100755 index 00000000000..6fcfb452cce --- /dev/null +++ b/ports/raspberrypi/common-hal/wiznet/PIO_SPI.h @@ -0,0 +1,25 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" + +#include "py/obj.h" + +#include "hardware/spi.h" + +#define SPI_HEADER_LEN 3 + +typedef struct { + mp_obj_base_t base; + bool has_lock; + const mcu_pin_obj_t *clock; + const mcu_pin_obj_t *MOSI; + const mcu_pin_obj_t *MISO; +} wiznet_pio_spi_obj_t; + +void reset_spi(void); diff --git a/ports/raspberrypi/common-hal/wiznet/__init__.c b/ports/raspberrypi/common-hal/wiznet/__init__.c new file mode 100755 index 00000000000..b3d5d23882d --- /dev/null +++ b/ports/raspberrypi/common-hal/wiznet/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// No wiznet module functions. diff --git a/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.c b/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.c new file mode 100755 index 00000000000..eb041527209 --- /dev/null +++ b/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.c @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +#include "pico/stdlib.h" +#include "pico/error.h" + +#include "hardware/dma.h" +#include "hardware/clocks.h" + +#include "wizchip_pio_spi.h" +#include "wizchip_pio_spi.pio.h" + +#ifndef PIO_SPI_PREFERRED_PIO +#define PIO_SPI_PREFERRED_PIO 1 +#endif + +#define PADS_DRIVE_STRENGTH PADS_BANK0_GPIO0_DRIVE_VALUE_12MA +#define IRQ_SAMPLE_DELAY_NS 100 + +#define WIZNET_PIO_SPI_PROGRAM_NAME wiznet_pio_spi_write_read +#define WIZNET_PIO_SPI_PROGRAM_FUNC __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _program) +#define WIZNET_PIO_SPI_PROGRAM_GET_DEFAULT_CONFIG_FUNC __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _program_get_default_config) +#define WIZNET_PIO_SPI_OFFSET_WRITE_BITS __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _offset_write_bits) +#define WIZNET_PIO_SPI_OFFSET_WRITE_END __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _offset_write_end) +#define WIZNET_PIO_SPI_OFFSET_READ_END __CONCAT(WIZNET_PIO_SPI_PROGRAM_NAME, _offset_read_end) + +// All wiznet spi operations must start with writing a 3 byte header +#define WIZNET_PIO_SPI_HEADER_LEN 3 + +#ifndef WIZNET_PICO_PIO_SPI_INSTANCE_COUNT +#define WIZNET_PICO_PIO_SPI_INSTANCE_COUNT 1 +#endif + +typedef struct wiznet_pio_spi_state { + wiznet_pio_spi_funcs_t *funcs; + const wiznet_pio_spi_config_t *spi_config; + pio_hw_t *pio; + uint8_t pio_func_sel; + int8_t pio_offset; + int8_t pio_sm; + int8_t dma_out; + int8_t dma_in; + uint8_t spi_header[WIZNET_PIO_SPI_HEADER_LEN]; + uint8_t spi_header_count; +} wiznet_pio_spi_state_t; +static wiznet_pio_spi_state_t wiznet_pio_spi_state[WIZNET_PICO_PIO_SPI_INSTANCE_COUNT]; +static wiznet_pio_spi_state_t *active_state; + +static wiznet_pio_spi_funcs_t *get_wiznet_pio_spi_impl(void); + +// Initialise our gpios +static void wiznet_pio_spi_gpio_setup(wiznet_pio_spi_state_t *state) { + + // Setup MOSI, MISO and IRQ + gpio_init(state->spi_config->data_out_pin); + gpio_set_dir(state->spi_config->data_out_pin, GPIO_OUT); + gpio_put(state->spi_config->data_out_pin, false); + + gpio_init(state->spi_config->data_in_pin); + gpio_set_dir(state->spi_config->data_in_pin, GPIO_IN); + + // Setup CS + gpio_init(state->spi_config->cs_pin); + gpio_set_dir(state->spi_config->cs_pin, GPIO_OUT); + gpio_put(state->spi_config->cs_pin, true); + + // Setup IRQ + gpio_init(state->spi_config->irq_pin); + gpio_set_dir(state->spi_config->irq_pin, GPIO_IN); + gpio_set_pulls(state->spi_config->irq_pin, false, false); +} + +wiznet_pio_spi_handle_t wiznet_pio_spi_open(const wiznet_pio_spi_config_t *wiznet_pio_spi_config) { + wiznet_pio_spi_state_t *state; + for (size_t i = 0; i < count_of(wiznet_pio_spi_state); i++) { + if (!wiznet_pio_spi_state[i].funcs) { + state = &wiznet_pio_spi_state[i]; + break; + } + } + assert(state); + // if (!state) return NULL; + state->spi_config = wiznet_pio_spi_config; + state->funcs = get_wiznet_pio_spi_impl(); + + wiznet_pio_spi_gpio_setup(state); + + pio_hw_t *pios[2] = {pio0, pio1}; + uint pio_index = PIO_SPI_PREFERRED_PIO; + + if (!pio_can_add_program(pios[pio_index], &WIZNET_PIO_SPI_PROGRAM_FUNC)) { + pio_index ^= 1; + if (!pio_can_add_program(pios[pio_index], &WIZNET_PIO_SPI_PROGRAM_FUNC)) { + return NULL; + } + } + + state->pio = pios[pio_index]; + state->dma_in = -1; + state->dma_out = -1; + + static_assert(GPIO_FUNC_PIO1 == GPIO_FUNC_PIO0 + 1, ""); + state->pio_func_sel = GPIO_FUNC_PIO0 + pio_index; + state->pio_sm = (int8_t)pio_claim_unused_sm(state->pio, false); + if (state->pio_sm < 0) { + wiznet_pio_spi_close(&state->funcs); + return NULL; + } + + state->pio_offset = pio_add_program(state->pio, &WIZNET_PIO_SPI_PROGRAM_FUNC); + + pio_sm_config sm_config = WIZNET_PIO_SPI_PROGRAM_GET_DEFAULT_CONFIG_FUNC(state->pio_offset); + + sm_config_set_clkdiv_int_frac(&sm_config, state->spi_config->clock_div_major, state->spi_config->clock_div_minor); + hw_write_masked(&pads_bank0_hw->io[state->spi_config->clock_pin], + (uint)PADS_DRIVE_STRENGTH << PADS_BANK0_GPIO0_DRIVE_LSB, + PADS_BANK0_GPIO0_DRIVE_BITS + ); + hw_write_masked(&pads_bank0_hw->io[state->spi_config->clock_pin], + (uint)1 << PADS_BANK0_GPIO0_SLEWFAST_LSB, + PADS_BANK0_GPIO0_SLEWFAST_BITS + ); + + sm_config_set_out_pins(&sm_config, state->spi_config->data_out_pin, 1); + sm_config_set_in_pins(&sm_config, state->spi_config->data_in_pin); + sm_config_set_set_pins(&sm_config, state->spi_config->data_out_pin, 1); + sm_config_set_sideset(&sm_config, 1, false, false); + sm_config_set_sideset_pins(&sm_config, state->spi_config->clock_pin); + + sm_config_set_in_shift(&sm_config, false, true, 8); + sm_config_set_out_shift(&sm_config, false, true, 8); + hw_set_bits(&state->pio->input_sync_bypass, 1u << state->spi_config->data_in_pin); + pio_sm_set_config(state->pio, state->pio_sm, &sm_config); + pio_sm_set_consecutive_pindirs(state->pio, state->pio_sm, state->spi_config->clock_pin, 1, true); + gpio_set_function(state->spi_config->data_out_pin, state->pio_func_sel); + gpio_set_function(state->spi_config->clock_pin, state->pio_func_sel); + + // Set data pin to pull down and schmitt + gpio_set_pulls(state->spi_config->data_in_pin, false, true); + gpio_set_input_hysteresis_enabled(state->spi_config->data_in_pin, true); + + pio_sm_exec(state->pio, state->pio_sm, pio_encode_set(pio_pins, 1)); + state->dma_out = (int8_t)dma_claim_unused_channel(false); // todo: Should be able to use one dma channel? + state->dma_in = (int8_t)dma_claim_unused_channel(false); + if (state->dma_out < 0 || state->dma_in < 0) { + wiznet_pio_spi_close(&state->funcs); + return NULL; + } + return &state->funcs; +} + +void wiznet_pio_spi_close(wiznet_pio_spi_handle_t handle) { + wiznet_pio_spi_state_t *state = (wiznet_pio_spi_state_t *)handle; + if (state) { + if (state->pio_sm >= 0) { + if (state->pio_offset != -1) { + pio_remove_program(state->pio, &WIZNET_PIO_SPI_PROGRAM_FUNC, state->pio_offset); + } + + pio_sm_unclaim(state->pio, state->pio_sm); + } + if (state->dma_out >= 0) { + dma_channel_unclaim(state->dma_out); + state->dma_out = -1; + } + if (state->dma_in >= 0) { + dma_channel_unclaim(state->dma_in); + state->dma_in = -1; + } + state->funcs = NULL; + } +} + +static void cs_set(wiznet_pio_spi_state_t *state, bool value) { + gpio_put(state->spi_config->cs_pin, value); +} + +static __noinline void ns_delay(uint32_t ns) { + // cycles = ns * clk_sys_hz / 1,000,000,000 + uint32_t cycles = ns * (clock_get_hz(clk_sys) >> 16u) / (1000000000u >> 16u); + busy_wait_at_least_cycles(cycles); +} + +static void wiznet_pio_spi_frame_start(void) { + assert(active_state); + + gpio_set_function(active_state->spi_config->data_out_pin, active_state->pio_func_sel); + gpio_set_function(active_state->spi_config->clock_pin, active_state->pio_func_sel); + gpio_pull_down(active_state->spi_config->clock_pin); + + // Pull CS low + cs_set(active_state, false); +} + +static void wiznet_pio_spi_frame_end(void) { + assert(active_state); + + // from this point a positive edge will cause an IRQ to be pending + cs_set(active_state, true); + + // we need to wait a bit in case the irq line is incorrectly high + #ifdef IRQ_SAMPLE_DELAY_NS + ns_delay(IRQ_SAMPLE_DELAY_NS); + #endif +} + +// send tx then receive rx +// rx can be null if you just want to send, but tx and tx_length must be valid +bool wiznet_pio_spi_transfer(const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length) { + const wiznet_pio_spi_state_t *state = active_state; + if (!state || (tx == NULL)) { + return false; + } + + if (rx != NULL && tx != NULL) { + assert(tx && tx_length && rx_length); + + pio_sm_set_enabled(state->pio, state->pio_sm, false); // disable sm + pio_sm_set_wrap(state->pio, state->pio_sm, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS, state->pio_offset + WIZNET_PIO_SPI_OFFSET_READ_END - 1); + pio_sm_clear_fifos(state->pio, state->pio_sm); // clear fifos from previous run + pio_sm_set_pindirs_with_mask(state->pio, state->pio_sm, 1u << state->spi_config->data_out_pin, 1u << state->spi_config->data_out_pin); + pio_sm_restart(state->pio, state->pio_sm); + pio_sm_clkdiv_restart(state->pio, state->pio_sm); + pio_sm_put(state->pio, state->pio_sm, tx_length * 8 - 1); // set x + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_x, 32)); + pio_sm_put(state->pio, state->pio_sm, rx_length - 1); // set y + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_y, 32)); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_jmp(state->pio_offset)); // setup pc + + dma_channel_abort(state->dma_out); + dma_channel_abort(state->dma_in); + + dma_channel_config out_config = dma_channel_get_default_config(state->dma_out); + channel_config_set_dreq(&out_config, pio_get_dreq(state->pio, state->pio_sm, true)); + channel_config_set_transfer_data_size(&out_config, DMA_SIZE_8); + dma_channel_configure(state->dma_out, &out_config, &state->pio->txf[state->pio_sm], tx, tx_length, true); + + dma_channel_config in_config = dma_channel_get_default_config(state->dma_in); + channel_config_set_dreq(&in_config, pio_get_dreq(state->pio, state->pio_sm, false)); + channel_config_set_write_increment(&in_config, true); + channel_config_set_read_increment(&in_config, false); + channel_config_set_transfer_data_size(&in_config, DMA_SIZE_8); + dma_channel_configure(state->dma_in, &in_config, rx, &state->pio->rxf[state->pio_sm], rx_length, true); + + pio_sm_set_enabled(state->pio, state->pio_sm, true); + __compiler_memory_barrier(); + + dma_channel_wait_for_finish_blocking(state->dma_out); + dma_channel_wait_for_finish_blocking(state->dma_in); + + __compiler_memory_barrier(); + } else if (tx != NULL) { + assert(tx_length); + + pio_sm_set_enabled(state->pio, state->pio_sm, false); + pio_sm_set_wrap(state->pio, state->pio_sm, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS, state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_END - 1); + pio_sm_clear_fifos(state->pio, state->pio_sm); + pio_sm_restart(state->pio, state->pio_sm); + pio_sm_clkdiv_restart(state->pio, state->pio_sm); + pio_sm_put(state->pio, state->pio_sm, tx_length * 8 - 1); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_x, 32)); + pio_sm_put(state->pio, state->pio_sm, tx_length - 1); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_out(pio_y, 32)); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_set(pio_pins, 0)); + pio_sm_set_consecutive_pindirs(state->pio, state->pio_sm, state->spi_config->data_out_pin, 1, true); + pio_sm_exec(state->pio, state->pio_sm, pio_encode_jmp(state->pio_offset + WIZNET_PIO_SPI_OFFSET_WRITE_BITS)); + + dma_channel_abort(state->dma_out); + + dma_channel_config out_config = dma_channel_get_default_config(state->dma_out); + channel_config_set_dreq(&out_config, pio_get_dreq(state->pio, state->pio_sm, true)); + + channel_config_set_transfer_data_size(&out_config, DMA_SIZE_8); + dma_channel_configure(state->dma_out, &out_config, &state->pio->txf[state->pio_sm], tx, tx_length, true); + + const uint32_t fDebugTxStall = 1u << (PIO_FDEBUG_TXSTALL_LSB + state->pio_sm); + state->pio->fdebug = fDebugTxStall; + pio_sm_set_enabled(state->pio, state->pio_sm, true); + while (!(state->pio->fdebug & fDebugTxStall)) { + // printf("WIZNET_PIO_SPI: waiting for tx stall\n"); + tight_loop_contents(); // todo timeout + } + uint32_t timeout = 1000000; + if (timeout == 0) { + printf("ERROR: PIO TXSTALL timeout!\n"); + return false; + } + __compiler_memory_barrier(); + pio_sm_set_enabled(state->pio, state->pio_sm, false); + pio_sm_set_consecutive_pindirs(state->pio, state->pio_sm, state->spi_config->data_in_pin, 1, false); + } else if (rx != NULL) { + panic_unsupported(); // shouldn't be used + } + pio_sm_exec(state->pio, state->pio_sm, pio_encode_mov(pio_pins, pio_null)); // for next time we turn output on + + return true; +} + +// To read a byte we must first have been asked to write a 3 byte spi header +static uint8_t wiznet_pio_spi_read_byte(void) { + assert(active_state); + assert(active_state->spi_header_count == WIZNET_PIO_SPI_HEADER_LEN); + uint8_t ret; + if (!wiznet_pio_spi_transfer(active_state->spi_header, active_state->spi_header_count, &ret, 1)) { + panic("spi failed read"); + } + active_state->spi_header_count = 0; + return ret; +} + +// This is not used when the burst functions are provided +static void wiznet_pio_spi_write_byte(uint8_t wb) { + panic_unsupported(); // shouldn't be used +} + +// To read a buffer we must first have been asked to write a 3 byte spi header +void wiznet_pio_spi_read_buffer(uint8_t *pBuf, uint16_t len) { + assert(active_state); + assert(active_state->spi_header_count == WIZNET_PIO_SPI_HEADER_LEN); + if (!wiznet_pio_spi_transfer(active_state->spi_header, active_state->spi_header_count, pBuf, len)) { + panic("spi failed reading buffer"); + } + active_state->spi_header_count = 0; +} + +// If we have been asked to write a spi header already, then write it and the rest of the buffer +// or else if we've been given enough data for just the spi header, save it until the next call +// or we're writing a byte in which case we're given a buffer including the spi header +void wiznet_pio_spi_write_buffer(const uint8_t *pBuf, uint16_t len) { + assert(active_state); + + if (len < WIZNET_PIO_SPI_HEADER_LEN && active_state->spi_header_count != WIZNET_PIO_SPI_HEADER_LEN) { + memcpy(&active_state->spi_header[active_state->spi_header_count], pBuf, len); // expect another call + active_state->spi_header_count++; + } else if (len == WIZNET_PIO_SPI_HEADER_LEN && active_state->spi_header_count == 0) { + memcpy(active_state->spi_header, pBuf, WIZNET_PIO_SPI_HEADER_LEN); // expect another call + active_state->spi_header_count = WIZNET_PIO_SPI_HEADER_LEN; + } else { + if (active_state->spi_header_count == WIZNET_PIO_SPI_HEADER_LEN) { + if (!wiznet_pio_spi_transfer(active_state->spi_header, WIZNET_PIO_SPI_HEADER_LEN, NULL, 0)) { + panic("spi failed writing header"); + } + active_state->spi_header_count = 0; + } + assert(active_state->spi_header_count == 0); + if (!wiznet_pio_spi_transfer(pBuf, len, NULL, 0)) { + panic("spi failed writing buffer"); + } + } +} + +static void wiznet_pio_spi_set_active(wiznet_pio_spi_handle_t handle) { + active_state = (wiznet_pio_spi_state_t *)handle; +} + +static void wiznet_pio_spi_set_inactive(void) { + active_state = NULL; +} + +static void wiznet_pio_spi_reset(wiznet_pio_spi_handle_t handle) { + wiznet_pio_spi_state_t *state = (wiznet_pio_spi_state_t *)handle; + gpio_set_dir(state->spi_config->reset_pin, GPIO_OUT); + gpio_put(state->spi_config->reset_pin, 0); + sleep_ms(100); + gpio_put(state->spi_config->reset_pin, 1); + sleep_ms(100); +} + +static wiznet_pio_spi_funcs_t *get_wiznet_pio_spi_impl(void) { + static wiznet_pio_spi_funcs_t funcs = { + .close = wiznet_pio_spi_close, + .set_active = wiznet_pio_spi_set_active, + .set_inactive = wiznet_pio_spi_set_inactive, + .frame_start = wiznet_pio_spi_frame_start, + .frame_end = wiznet_pio_spi_frame_end, + .read_byte = wiznet_pio_spi_read_byte, + .write_byte = wiznet_pio_spi_write_byte, + .read_buffer = wiznet_pio_spi_read_buffer, + .write_buffer = wiznet_pio_spi_write_buffer, + .reset = wiznet_pio_spi_reset, + }; + return &funcs; +} diff --git a/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.h b/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.h new file mode 100755 index 00000000000..841eb48c480 --- /dev/null +++ b/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2023 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef _WIZNET_PIO_SPI_H_ +#define _WIZNET_PIO_SPI_H_ + +typedef struct wiznet_pio_spi_config { + uint8_t data_in_pin; + uint8_t data_out_pin; + uint8_t cs_pin; + uint8_t clock_pin; + uint8_t irq_pin; + uint8_t reset_pin; + uint16_t clock_div_major; + uint8_t clock_div_minor; + uint8_t spi_hw_instance; +} wiznet_pio_spi_config_t; + +typedef struct wiznet_pio_spi_funcs **wiznet_pio_spi_handle_t; + +typedef struct wiznet_pio_spi_funcs { + void (*close)(wiznet_pio_spi_handle_t funcs); + void (*set_active)(wiznet_pio_spi_handle_t funcs); + void (*set_inactive)(void); + void (*frame_start)(void); + void (*frame_end)(void); + uint8_t (*read_byte)(void); + void (*write_byte)(uint8_t tx_data); + void (*read_buffer)(uint8_t *pBuf, uint16_t len); + void (*write_buffer)(const uint8_t *pBuf, uint16_t len); + void (*reset)(wiznet_pio_spi_handle_t funcs); +} wiznet_pio_spi_funcs_t; + +wiznet_pio_spi_handle_t wiznet_pio_spi_open(const wiznet_pio_spi_config_t *pio_spi_config); +void wiznet_pio_spi_close(wiznet_pio_spi_handle_t handle); +bool wiznet_pio_spi_transfer(const uint8_t *tx, size_t tx_length, uint8_t *rx, size_t rx_length); +void wiznet_pio_spi_read_buffer(uint8_t *pBuf, uint16_t len); +void wiznet_pio_spi_write_buffer(const uint8_t *pBuf, uint16_t len); + +#endif diff --git a/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.pio b/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.pio new file mode 100755 index 00000000000..97a1c5b73d4 --- /dev/null +++ b/ports/raspberrypi/common-hal/wiznet/wizchip_pio_spi.pio @@ -0,0 +1,24 @@ +; +; Copyright (c) 2023 Raspberry Pi (Trading) Ltd. +; +; SPDX-License-Identifier: BSD-3-Clause +; + +.program wiznet_pio_spi_write_read +.side_set 1 + +public write_bits: + out pins, 1 side 0 + jmp x-- write_bits side 1 + set pins 0 side 0 +public write_end: +read_byte_delay: + set pindirs 0 side 0 +read_byte: + set x 6 side 1 +read_bits: + in pins, 1 side 0 + jmp x-- read_bits side 1 + in pins, 1 side 0 + jmp y-- read_byte side 0 +public read_end: diff --git a/ports/raspberrypi/cyw43_configport.h b/ports/raspberrypi/cyw43_configport.h index 62666bee42c..c1769436ae4 100644 --- a/ports/raspberrypi/cyw43_configport.h +++ b/ports/raspberrypi/cyw43_configport.h @@ -12,7 +12,7 @@ #include "supervisor/port.h" -#include "sdk/src/rp2_common/pico_cyw43_driver/include/cyw43_configport.h" +#include_next "cyw43_configport.h" #define CYW43_NETUTILS (1) diff --git a/ports/raspberrypi/gen_stage2.py b/ports/raspberrypi/gen_stage2.py index 759384e17f3..005994dc107 100644 --- a/ports/raspberrypi/gen_stage2.py +++ b/ports/raspberrypi/gen_stage2.py @@ -45,8 +45,6 @@ def all_match(nvms, key, default=None): quad_ok = quad_enable_status_byte is not None and quad_enable_bit_mask is not None - max_clock_speed_mhz = min((x.get("max_clock_speed_mhz", 1000) for x in flashes["nvm"])) - default_power_of_two = None for nvm in flashes["nvm"]: capacity = nvm.get("capacity", 0) diff --git a/ports/raspberrypi/lib/Pico-PIO-USB b/ports/raspberrypi/lib/Pico-PIO-USB index fe9133fc513..a5a2f5ae919 160000 --- a/ports/raspberrypi/lib/Pico-PIO-USB +++ b/ports/raspberrypi/lib/Pico-PIO-USB @@ -1 +1 @@ -Subproject commit fe9133fc513b82cc3dc62c67cb51f2339cf29ef7 +Subproject commit a5a2f5ae91988449ba576ec9d237e806d5cd4416 diff --git a/ports/raspberrypi/lib/cyw43-driver b/ports/raspberrypi/lib/cyw43-driver index 9f6405f0b32..dd7568229f3 160000 --- a/ports/raspberrypi/lib/cyw43-driver +++ b/ports/raspberrypi/lib/cyw43-driver @@ -1 +1 @@ -Subproject commit 9f6405f0b3260968306d782e1c5ac275a46dc65d +Subproject commit dd7568229f3bf7a37737b9e1ef250c26efe75b23 diff --git a/ports/raspberrypi/lib/lwip b/ports/raspberrypi/lib/lwip index d26459c32c8..bd522fde940 160000 --- a/ports/raspberrypi/lib/lwip +++ b/ports/raspberrypi/lib/lwip @@ -1 +1 @@ -Subproject commit d26459c32c83aa14a6d4e30237d91cee36e0adbd +Subproject commit bd522fde9409398297b4e3244c92576b86ef16ec diff --git a/ports/raspberrypi/link-rp2040.ld b/ports/raspberrypi/link-rp2040.ld index 5f2798623db..189c3d7c338 100644 --- a/ports/raspberrypi/link-rp2040.ld +++ b/ports/raspberrypi/link-rp2040.ld @@ -82,9 +82,9 @@ SECTIONS *(.property_getset) __property_getset_end = .; - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a: *interp.o *divider.o *tusb_fifo.o *mem_ops_aeabi.o *usbh.o) .text*) + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a: *interp.o *divider.o *pico_int64_ops_aeabi.o *tusb_fifo.o *mem_ops_aeabi.o *usbh.o) .text*) /* Allow everything in usbh.o except tuh_task_event_ready because we read it from core 1. */ - *usbh.o (.text.[_uphc]* .text.tuh_[cmvied]* .text.tuh_task_ext*) + *usbh.o (.text.[_uphc]* .text.tuh_[cmved]* .text.tuh_task_ext*) *(.fini) /* Pull all c'tors into .text */ *crtbegin.o(.ctors) diff --git a/ports/raspberrypi/link-rp2350.ld b/ports/raspberrypi/link-rp2350.ld index 19f7f052536..3c339b03fe2 100644 --- a/ports/raspberrypi/link-rp2350.ld +++ b/ports/raspberrypi/link-rp2350.ld @@ -63,9 +63,9 @@ SECTIONS *(.property_getset) __property_getset_end = .; - *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a: *interp.o *divider.o *tusb_fifo.o *mem_ops_aeabi.o *usbh.o *string0.o) .text*) + *(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a: *interp.o *divider.o *pico_int64_ops_aeabi.o *tusb_fifo.o *mem_ops_aeabi.o *usbh.o *string0.o) .text*) /* Allow everything in usbh.o except tuh_task_event_ready because we read it from core 1. */ - *usbh.o (.text.[_uphc]* .text.tuh_[cmvied]* .text.tuh_task_ext*) + *usbh.o (.text.[_uphc]* .text.tuh_[cmved]* .text.tuh_task_ext*) *(.fini) /* Pull all c'tors into .text */ *crtbegin.o(.ctors) diff --git a/ports/raspberrypi/lwip_inc/lwip_mem.h b/ports/raspberrypi/lwip_inc/lwip_mem.h new file mode 100644 index 00000000000..3e5c91a8bb0 --- /dev/null +++ b/ports/raspberrypi/lwip_inc/lwip_mem.h @@ -0,0 +1,13 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +void *lwip_heap_malloc(size_t size); +void lwip_heap_free(void *ptr); +void *lwip_heap_calloc(size_t num, size_t size); diff --git a/ports/raspberrypi/lwip_inc/lwipopts.h b/ports/raspberrypi/lwip_inc/lwipopts.h index 06df7f13181..21d415fad21 100644 --- a/ports/raspberrypi/lwip_inc/lwipopts.h +++ b/ports/raspberrypi/lwip_inc/lwipopts.h @@ -5,6 +5,8 @@ // Common settings used in most of the pico_w examples // (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details) +#include "lwip_mem.h" + // allow override in some examples #ifndef NO_SYS #define NO_SYS 1 @@ -20,14 +22,62 @@ #define MEM_LIBC_MALLOC 0 #endif #define MEM_ALIGNMENT 4 -#define MEM_SIZE 4000 -#define MEMP_NUM_TCP_SEG 32 -#define MEMP_NUM_ARP_QUEUE 10 -#define PBUF_POOL_SIZE 24 +// MEM_USE_POOLS: mem_malloc uses pools of fixed size memory blocks. Default is 0. +#define MEM_USE_POOLS 0 +// MEM_USE_POOLS_TRY_BIGGER_POOL: if one pool is empty, try the next bigger pool. Default is 0. +#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 +// MEMP_USE_CUSTOM_POOLS: Use custom pools defined in lwippools.h. Default is 0. +#define MEMP_USE_CUSTOM_POOLS 0 +// MEMP_MEM_MALLOC: Use mem_malloc() for pool memory. Default is 0. +#define MEMP_MEM_MALLOC 1 +#define MEM_CUSTOM_ALLOCATOR 1 +#define MEM_CUSTOM_FREE lwip_heap_free +#define MEM_CUSTOM_MALLOC lwip_heap_malloc +#define MEM_CUSTOM_CALLOC lwip_heap_calloc + +// MEM_SIZE: The LWIP heap size. Memory for mem_malloc and mem_calloc are allocated from +// this heap. If MEMP_MEM_MALLOC is set to 1, memory for memp_malloc is also allocated from +// this heap; if it is 0, memory is statically pre-allocated for each pool. +// Default is 1600. +#define MEM_SIZE 1600 +// MEMP_NUM_PBUF: memp pbufs used when sending from static memory. Default is 16. +#define MEMP_NUM_PBUF 16 +// MEMP_NUM_RAW_PCB: Number of raw connection PCBs. Default is 4. +#define MEMP_NUM_RAW_PCB 4 +// MEMP_NUM_UDP_PCB: Number of UDP PCBs. Default is 4. +#define MEMP_NUM_UDP_PCB 4 +// MEMP_NUM_TCP_PCB: Number of simultaneously active TCP connections. Default is 5. +#define MEMP_NUM_TCP_PCB 5 +// MEMP_NUM_TCP_PCB_LISTEN: Number of listening TCP PCBs. Default is 8. +#define MEMP_NUM_TCP_PCB_LISTEN 8 +// MEMP_NUM_TCP_SEG: Number of simultaneously queued TCP segments. Default is 16. +#define MEMP_NUM_TCP_SEG 16 +// MEMP_NUM_ALTCP_PCB: Number of simultaneously active altcp connections. Default is 5. +#define MEMP_NUM_ALTCP_PCB 5 +// MEMP_NUM_REASSDATA: Number of simultaneously IP packets queued for reassembly. Default is 5. +#define MEMP_NUM_REASSDATA 5 +// MEMP_NUM_FRAG_PBUF: Number of simultaneously IP fragments. Default is 15. +#define MEMP_NUM_FRAG_PBUF 15 +// MEMP_NUM_ARP_QUEUE: Number of simultaneously queued ARP packets. Default is 30. +#define MEMP_NUM_ARP_QUEUE 30 +// MEMP_NUM_IGMP_GROUP: Number of simultaneously active IGMP groups. Default is 8. +#define MEMP_NUM_IGMP_GROUP 8 +// MEMP_NUM_SYS_TIMEOUT: Number of simultaneously active timeouts. +// Use calculated default based on enabled modules. + +// PBUF_POOL_SIZE: Number of pbufs in the pbuf pool. Default is 16. +#define PBUF_POOL_SIZE 16 + +// LWIP's default 250 ms periodic timer interval is too long, resulting in network +// performance issues. We reduce it to 25 ms giving a slow-timer of 50 ms and a +// fast-timer of 25 ms. +#define TCP_TMR_INTERVAL 25 + #define LWIP_ARP 1 #define LWIP_ETHERNET 1 #define LWIP_ICMP 1 #define LWIP_RAW 1 + #define TCP_WND (8 * TCP_MSS) #define TCP_MSS 1460 #define TCP_SND_BUF (8 * TCP_MSS) @@ -61,6 +111,7 @@ #define LWIP_NETIF_EXT_STATUS_CALLBACK 1 #define MDNS_MAX_SECONDARY_HOSTNAMES 1 #define MEMP_NUM_SYS_TIMEOUT (8 + 3 * (LWIP_IPV4 + LWIP_IPV6)) +#define MDNS_MAX_SERVICES 25 #endif #ifndef NDEBUG diff --git a/ports/raspberrypi/lwip_src/lwip_mem.c b/ports/raspberrypi/lwip_src/lwip_mem.c new file mode 100644 index 00000000000..23b185354b0 --- /dev/null +++ b/ports/raspberrypi/lwip_src/lwip_mem.c @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Bob Abeles +// +// SPDX-License-Identifier: MIT + +#include +#include +#include "lib/tlsf/tlsf.h" +#include "lwip_mem.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "supervisor/port_heap.h" + +void *lwip_heap_malloc(size_t size) { + void *ptr = port_malloc(size, true); + return ptr; +} + +void lwip_heap_free(void *ptr) { + port_free(ptr); +} + +void *lwip_heap_calloc(size_t num, size_t size) { + void *ptr = lwip_heap_malloc(num * size); + if (ptr != NULL) { + memset(ptr, 0, num * size); + } + return ptr; +} diff --git a/ports/raspberrypi/mpconfigport.h b/ports/raspberrypi/mpconfigport.h index 1181517fdf9..d0802b25f00 100644 --- a/ports/raspberrypi/mpconfigport.h +++ b/ports/raspberrypi/mpconfigport.h @@ -8,12 +8,15 @@ #include "hardware/platform_defs.h" -#ifdef PICO_RP2040 +#if PICO_RP2040 #define MICROPY_PY_SYS_PLATFORM "RP2040" #endif -#ifdef PICO_RP2350 +#if PICO_RP2350 #define MICROPY_PY_SYS_PLATFORM "RP2350" + +// PSRAM can require more stack space for GC. +#define MICROPY_ALLOC_GC_STACK_SIZE (128) #endif // Setting a non-default value also requires a non-default link.ld @@ -33,6 +36,9 @@ #define CIRCUITPY_PROCESSOR_COUNT (2) +// For RP2 boards we use a custom way to read BOOTSEL +#define CIRCUITPY_BOOT_BUTTON_NO_GPIO (1) + #if CIRCUITPY_USB_HOST #define CIRCUITPY_USB_HOST_INSTANCE 1 #endif diff --git a/ports/raspberrypi/mpconfigport.mk b/ports/raspberrypi/mpconfigport.mk index 81913bde01a..f4c6e809ba0 100644 --- a/ports/raspberrypi/mpconfigport.mk +++ b/ports/raspberrypi/mpconfigport.mk @@ -11,25 +11,31 @@ CIRCUITPY_FLOPPYIO ?= 1 CIRCUITPY_FRAMEBUFFERIO ?= $(CIRCUITPY_DISPLAYIO) CIRCUITPY_FULL_BUILD ?= 1 CIRCUITPY_AUDIOMP3 ?= 1 +CIRCUITPY_AUDIOSPEED ?= 1 +CIRCUITPY_AUDIOEFFECTS ?= 1 +CIRCUITPY_AUDIOFILEWRITER ?= 1 CIRCUITPY_BITOPS ?= 1 CIRCUITPY_HASHLIB ?= 1 CIRCUITPY_HASHLIB_MBEDTLS ?= 1 CIRCUITPY_IMAGECAPTURE ?= 1 CIRCUITPY_MAX3421E ?= 0 +CIRCUITPY_MCP4822 ?= 0 CIRCUITPY_MEMORYMAP ?= 1 CIRCUITPY_PWMIO ?= 1 CIRCUITPY_RGBMATRIX ?= $(CIRCUITPY_DISPLAYIO) CIRCUITPY_ROTARYIO ?= 1 CIRCUITPY_ROTARYIO_SOFTENCODER = 1 -CIRCUITPY_SYNTHIO_MAX_CHANNELS = 12 +CIRCUITPY_SYNTHIO_MAX_CHANNELS = 24 CIRCUITPY_USB_HOST ?= 1 CIRCUITPY_USB_VIDEO ?= 1 +CIRCUITPY_USB_AUDIO ?= 1 # Things that need to be implemented. CIRCUITPY_FREQUENCYIO = 0 # Use PWM internally CIRCUITPY_I2CTARGET = 1 +CIRCUITPY_I2CIOEXPANDER = 1 CIRCUITPY_NVM = 1 # Use PIO internally CIRCUITPY_PULSEIO ?= 1 @@ -41,6 +47,7 @@ CIRCUITPY_ANALOGBUFIO = 1 # Audio via PWM CIRCUITPY_AUDIOIO = 0 CIRCUITPY_AUDIOBUSIO ?= 1 +CIRCUITPY_AUDIOI2SIN ?= $(CIRCUITPY_AUDIOBUSIO) CIRCUITPY_AUDIOCORE ?= 1 CIRCUITPY_AUDIOPWMIO ?= 1 @@ -53,17 +60,25 @@ CIRCUITPY_ALARM ?= 1 CIRCUITPY_PICODVI ?= 0 CIRCUITPY_TOUCHIO ?= 1 + +# delay in ms before calling cyw43_arch_init_with_country +CIRCUITPY_CYW43_INIT_DELAY ?= 1000 endif ifeq ($(CHIP_VARIANT),RP2350) +# RP2350 has PSRAM that is not DMA-capable +CIRCUITPY_ALL_MEMORY_DMA_CAPABLE = 0 + # This needs to be implemented. CIRCUITPY_ALARM = 0 # Default PICODVI on because it doesn't require much code in RAM to talk to HSTX. CIRCUITPY_PICODVI ?= 1 -# Our generic touchio uses a pull down and RP2350 A2 hardware doesn't work correctly. -# So, turn touchio off because it doesn't work. -CIRCUITPY_TOUCHIO = 0 +# delay in ms before calling cyw43_arch_init_with_country +CIRCUITPY_CYW43_INIT_DELAY ?= 0 + +# Audio effects +CIRCUITPY_AUDIOEFFECTS ?= 1 endif INTERNAL_LIBM = 1 diff --git a/ports/raspberrypi/mphalport.c b/ports/raspberrypi/mphalport.c index 3258c4de4f3..3d322ba6bca 100644 --- a/ports/raspberrypi/mphalport.c +++ b/ports/raspberrypi/mphalport.c @@ -19,7 +19,7 @@ #include "mphalport.h" #include "supervisor/shared/tick.h" -#include "src/rp2_common/hardware_timer/include/hardware/timer.h" +#include "hardware/timer.h" extern uint32_t common_hal_mcu_processor_get_frequency(void); diff --git a/ports/raspberrypi/sdk b/ports/raspberrypi/sdk index efe2103f9b2..a1438dff1d3 160000 --- a/ports/raspberrypi/sdk +++ b/ports/raspberrypi/sdk @@ -1 +1 @@ -Subproject commit efe2103f9b28458a1615ff096054479743ade236 +Subproject commit a1438dff1d38bd9c65dbd693f0e5db4b9ae91779 diff --git a/ports/raspberrypi/sdk_config/pico/version.h b/ports/raspberrypi/sdk_config/pico/version.h index 0596c75dd07..b5803bb98c9 100644 --- a/ports/raspberrypi/sdk_config/pico/version.h +++ b/ports/raspberrypi/sdk_config/pico/version.h @@ -12,8 +12,8 @@ #define _PICO_VERSION_H #define PICO_SDK_VERSION_MAJOR 2 -#define PICO_SDK_VERSION_MINOR 0 +#define PICO_SDK_VERSION_MINOR 1 #define PICO_SDK_VERSION_REVISION 0 -#define PICO_SDK_VERSION_STRING "2.0.0" +#define PICO_SDK_VERSION_STRING "2.1.0" #endif diff --git a/ports/raspberrypi/supervisor/internal_flash.c b/ports/raspberrypi/supervisor/internal_flash.c index 6502aa08b05..07b15564c60 100644 --- a/ports/raspberrypi/supervisor/internal_flash.c +++ b/ports/raspberrypi/supervisor/internal_flash.c @@ -23,12 +23,12 @@ #include "supervisor/flash.h" #include "supervisor/usb.h" -#ifdef PICO_RP2350 -#include "src/rp2350/hardware_structs/include/hardware/structs/qmi.h" +#if PICO_RP2350 +#include "hardware/structs/qmi.h" #endif -#include "src/rp2040/hardware_structs/include/hardware/structs/sio.h" -#include "src/rp2_common/hardware_flash/include/hardware/flash.h" -#include "src/common/pico_binary_info/include/pico/binary_info.h" +#include "hardware/structs/sio.h" +#include "hardware/flash.h" +#include "pico/binary_info.h" #if !defined(TOTAL_FLASH_MINIMUM) #define TOTAL_FLASH_MINIMUM (2 * 1024 * 1024) @@ -40,30 +40,26 @@ static uint8_t _cache[SECTOR_SIZE]; static uint32_t _cache_lba = NO_CACHE; static uint32_t _flash_size = 0; - -#ifdef PICO_RP2350 -static uint32_t m1_rfmt; -static uint32_t m1_timing; +#if CIRCUITPY_AUDIOCORE +static uint32_t _audio_channel_mask; #endif -static void save_psram_settings(void) { - #ifdef PICO_RP2350 - // We're about to invalidate the XIP cache, clean it first to commit any dirty writes to PSRAM - uint8_t *maintenance_ptr = (uint8_t *)XIP_MAINTENANCE_BASE; - for (int i = 1; i < 16 * 1024; i += 8) { - maintenance_ptr[i] = 0; - } - - m1_timing = qmi_hw->m[1].timing; - m1_rfmt = qmi_hw->m[1].rfmt; +void supervisor_flash_pre_write(void) { + // Disable interrupts. XIP accesses will fault during flash writes. + common_hal_mcu_disable_interrupts(); + #if CIRCUITPY_AUDIOCORE + // Pause audio DMA to avoid noise while interrupts are disabled. + _audio_channel_mask = audio_dma_pause_all(); #endif } -static void restore_psram_settings(void) { - #ifdef PICO_RP2350 - qmi_hw->m[1].timing = m1_timing; - qmi_hw->m[1].rfmt = m1_rfmt; +void supervisor_flash_post_write(void) { + #if CIRCUITPY_AUDIOCORE + // Unpause audio DMA. + audio_dma_unpause_mask(_audio_channel_mask); #endif + // Re-enable interrupts. + common_hal_mcu_enable_interrupts(); } void supervisor_flash_init(void) { @@ -80,9 +76,9 @@ void supervisor_flash_init(void) { // Read the RDID register to get the flash capacity. uint8_t cmd[] = {0x9f, 0, 0, 0}; uint8_t data[4]; - save_psram_settings(); + supervisor_flash_pre_write(); flash_do_cmd(cmd, data, 4); - restore_psram_settings(); + supervisor_flash_post_write(); uint8_t power_of_two = FLASH_DEFAULT_POWER_OF_TWO; // Flash must be at least 2MB (1 << 21) because we use the first 1MB for the // CircuitPython core. We validate the range because Adesto Tech flash chips @@ -106,21 +102,11 @@ void port_internal_flash_flush(void) { if (_cache_lba == NO_CACHE) { return; } - // Make sure we don't have an interrupt while we do flash operations. - common_hal_mcu_disable_interrupts(); - // and audio DMA must be paused as well - #if CIRCUITPY_AUDIOCORE - uint32_t channel_mask = audio_dma_pause_all(); - #endif - save_psram_settings(); + supervisor_flash_pre_write(); flash_range_erase(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, SECTOR_SIZE); flash_range_program(CIRCUITPY_CIRCUITPY_DRIVE_START_ADDR + _cache_lba, _cache, SECTOR_SIZE); - restore_psram_settings(); _cache_lba = NO_CACHE; - #if CIRCUITPY_AUDIOCORE - audio_dma_unpause_mask(channel_mask); - #endif - common_hal_mcu_enable_interrupts(); + supervisor_flash_post_write(); } mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { diff --git a/ports/raspberrypi/supervisor/internal_flash.h b/ports/raspberrypi/supervisor/internal_flash.h index 01acbf02b4d..a7941b17c47 100644 --- a/ports/raspberrypi/supervisor/internal_flash.h +++ b/ports/raspberrypi/supervisor/internal_flash.h @@ -9,6 +9,10 @@ #include "mpconfigport.h" +// These must be called before and after doing a low-level flash write. +void supervisor_flash_pre_write(void); +void supervisor_flash_post_write(void); + // #define INTERNAL_FLASH_PART1_NUM_BLOCKS (CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE / FILESYSTEM_BLOCK_SIZE) // #define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms diff --git a/ports/raspberrypi/supervisor/port.c b/ports/raspberrypi/supervisor/port.c index 9a525011963..8a8b9fb052c 100644 --- a/ports/raspberrypi/supervisor/port.c +++ b/ports/raspberrypi/supervisor/port.c @@ -4,16 +4,20 @@ // // SPDX-License-Identifier: MIT +#include +#include +#include #include #include +#include #include "supervisor/background_callback.h" #include "supervisor/board.h" +#include "supervisor/linker.h" #include "supervisor/port.h" #include "bindings/rp2pio/StateMachine.h" #include "genhdr/mpversion.h" -#include "shared-bindings/busio/I2C.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/countio/Counter.h" #include "shared-bindings/microcontroller/__init__.h" @@ -25,6 +29,7 @@ #if CIRCUITPY_SSL #include "shared-module/ssl/__init__.h" +#include "psa/crypto.h" #endif #if CIRCUITPY_WIFI @@ -34,32 +39,83 @@ #include "common-hal/rtc/RTC.h" #include "common-hal/busio/UART.h" +#if CIRCUITPY_SDIOIO +#include "common-hal/sdioio/SDCard.h" +#endif + #include "supervisor/shared/safe_mode.h" #include "supervisor/shared/stack.h" #include "supervisor/shared/tick.h" -#include "src/rp2040/hardware_structs/include/hardware/structs/watchdog.h" -#include "src/rp2_common/hardware_gpio/include/hardware/gpio.h" -#include "src/rp2_common/hardware_uart/include/hardware/uart.h" -#include "src/rp2_common/hardware_sync/include/hardware/sync.h" -#include "src/rp2_common/hardware_timer/include/hardware/timer.h" +#include "hardware/structs/scb.h" +#include "hardware/structs/watchdog.h" +#include "hardware/gpio.h" +#include "hardware/uart.h" +#include "hardware/sync.h" +#include "hardware/timer.h" #if CIRCUITPY_CYW43 #include "py/mphal.h" #include "pico/cyw43_arch.h" #endif -#include "src/common/pico_time/include/pico/time.h" -#include "src/common/pico_binary_info/include/pico/binary_info.h" +#include "pico/time.h" +#include "pico/binary_info.h" #include "pico/bootrom.h" #include "hardware/watchdog.h" +#if PICO_RP2350 +#include "RP2350.h" // CMSIS +#endif + +#if CIRCUITPY_BOOT_BUTTON_NO_GPIO +#include "hardware/gpio.h" +#include "hardware/sync.h" +#include "hardware/structs/ioqspi.h" +#include "hardware/structs/sio.h" +#endif + #include "supervisor/shared/serial.h" #include "tusb.h" #include +#include "lib/tlsf/tlsf.h" critical_section_t background_queue_lock; +// The SDK's panic() lives in flash, but core1 may run with flash access +// disabled by the MPU (usb_host and picodvi lock it out), where a flash call +// hard faults before anything is printed. -Wl,--wrap=panic routes every +// panic here instead: core0 keeps the SDK behavior, core1 halts from RAM. +// Verified by tools/check_core1_flash_calls.py. +void __wrap_panic(const char *fmt, ...) __attribute__((noreturn, format(printf, 1, 2))); +void panic_core0(const char *fmt, va_list args) __attribute__((noreturn, format(printf, 1, 0))); + +// Flash-resident; only ever called from core0 (see __wrap_panic). Mirrors +// the SDK implementation. noinline keeps the flash-calling code out of the +// RAM-resident wrapper below. +__attribute__((noinline)) void panic_core0(const char *fmt, va_list args) { + puts("\n*** PANIC ***\n"); + if (fmt) { + vprintf(fmt, args); + puts(""); + } + _exit(1); +} + +void __not_in_flash_func(__wrap_panic)(const char *fmt, ...) { + if (get_core_num() == 0) { + va_list args; + va_start(args, fmt); + panic_core0(fmt, args); + } + // Flash may be MPU-locked on this core and stdio is core0-only, so the + // message is unprintable here. Halt in RAM: a debugger stops at the + // breakpoint, otherwise spin. + __breakpoint(); + while (1) { + } +} + extern volatile bool mp_msc_enabled; static void _tick_callback(uint alarm_num); @@ -84,20 +140,17 @@ extern uint32_t _ld_itcm_destination; extern uint32_t _ld_itcm_size; extern uint32_t _ld_itcm_flash_copy; -#ifdef CIRCUITPY_PSRAM_CHIP_SELECT - -#include "lib/tlsf/tlsf.h" - -#include "src/rp2350/hardware_regs/include/hardware/regs/qmi.h" -#include "src/rp2350/hardware_regs/include/hardware/regs/xip.h" -#include "src/rp2350/hardware_structs/include/hardware/structs/qmi.h" -#include "src/rp2350/hardware_structs/include/hardware/structs/xip_ctrl.h" - static tlsf_t _heap = NULL; -static pool_t _ram_pool = NULL; -static pool_t _psram_pool = NULL; +static tlsf_t _psram_heap = NULL; static size_t _psram_size = 0; +#ifdef CIRCUITPY_PSRAM_CHIP_SELECT + +#include "hardware/regs/qmi.h" +#include "hardware/regs/xip.h" +#include "hardware/structs/qmi.h" +#include "hardware/structs/xip_ctrl.h" + static void __no_inline_not_in_flash_func(setup_psram)(void) { gpio_set_function(CIRCUITPY_PSRAM_CHIP_SELECT->number, GPIO_FUNC_XIP_CS1); _psram_size = 0; @@ -237,31 +290,74 @@ static void __no_inline_not_in_flash_func(setup_psram)(void) { return; } } +#endif -void port_heap_init(void) { +static void _port_heap_init(void) { uint32_t *heap_bottom = port_heap_get_bottom(); uint32_t *heap_top = port_heap_get_top(); size_t size = (heap_top - heap_bottom) * sizeof(uint32_t); - _heap = tlsf_create_with_pool(heap_bottom, size, 64 * 1024 * 1024); - _ram_pool = tlsf_get_pool(_heap); + _heap = tlsf_create_with_pool(heap_bottom, size, size); if (_psram_size > 0) { - _psram_pool = tlsf_add_pool(_heap, (void *)0x11000004, _psram_size - 4); + _psram_heap = tlsf_create_with_pool((void *)0x11000000, _psram_size, _psram_size); } } +void port_heap_init(void) { + // We call _port_heap_init from port_init to initialize the heap early. +} + void *port_malloc(size_t size, bool dma_capable) { + // Prefer internal RAM for everything: it is much faster than PSRAM + // (data there skips the external bus and the shared XIP cache). PSRAM, when + // present, serves as spillover capacity for allocations that don't need DMA. + common_hal_mcu_disable_interrupts(); void *block = tlsf_malloc(_heap, size); + common_hal_mcu_enable_interrupts(); + if (block == NULL && !dma_capable && _psram_size > 0) { + common_hal_mcu_disable_interrupts(); + block = tlsf_malloc(_psram_heap, size); + common_hal_mcu_enable_interrupts(); + } return block; } void port_free(void *ptr) { - tlsf_free(_heap, ptr); + common_hal_mcu_disable_interrupts(); + if (((size_t)ptr) < SRAM_BASE) { + tlsf_free(_psram_heap, ptr); + } else { + tlsf_free(_heap, ptr); + } + common_hal_mcu_enable_interrupts(); } -void *port_realloc(void *ptr, size_t size) { - return tlsf_realloc(_heap, ptr, size); +void *port_realloc(void *ptr, size_t size, bool dma_capable) { + if (ptr == NULL) { + // Fresh allocation: same internal-first policy as port_malloc. + return port_malloc(size, dma_capable); + } + if (_psram_size > 0 && ((size_t)ptr) < SRAM_BASE) { + common_hal_mcu_disable_interrupts(); + void *block = tlsf_realloc(_psram_heap, ptr, size); + common_hal_mcu_enable_interrupts(); + if (block) { + return block; + } + } + common_hal_mcu_disable_interrupts(); + void *new_ptr = tlsf_realloc(_heap, ptr, size); + common_hal_mcu_enable_interrupts(); + return new_ptr; } +#if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE +bool port_buffer_is_dma_capable(const void *ptr) { + // For RP2350, DMA can only access SRAM, not PSRAM + // PSRAM addresses are below SRAM_BASE + return ptr != NULL && ((size_t)ptr) >= SRAM_BASE; +} +#endif + static bool max_size_walker(void *ptr, size_t size, int used, void *user) { size_t *max_size = (size_t *)user; if (!used && *max_size < size) { @@ -272,14 +368,14 @@ static bool max_size_walker(void *ptr, size_t size, int used, void *user) { size_t port_heap_get_largest_free_size(void) { size_t max_size = 0; - tlsf_walk_pool(_ram_pool, max_size_walker, &max_size); - if (_psram_pool != NULL) { - tlsf_walk_pool(_psram_pool, max_size_walker, &max_size); + tlsf_walk_pool(tlsf_get_pool(_heap), max_size_walker, &max_size); + max_size = tlsf_fit_size(_heap, max_size); + if (_psram_heap != NULL) { + tlsf_walk_pool(tlsf_get_pool(_psram_heap), max_size_walker, &max_size); + max_size = tlsf_fit_size(_psram_heap, max_size); } - // IDF does this. Not sure why. - return tlsf_fit_size(_heap, max_size); + return max_size; } -#endif safe_mode_t port_init(void) { _binary_info(); @@ -288,10 +384,10 @@ safe_mode_t port_init(void) { // Load from the XIP memory space that doesn't cache. That way we don't // evict anything else. The code we're loading is linked to the RAM address // anyway. - #ifdef PICO_RP2040 + #if PICO_RP2040 size_t nocache = 0x03000000; #endif - #ifdef PICO_RP2350 + #if PICO_RP2350 size_t nocache = 0x04000000; #endif @@ -318,30 +414,46 @@ safe_mode_t port_init(void) { critical_section_init(&background_queue_lock); #if CIRCUITPY_CYW43 - never_reset_pin_number(23); - never_reset_pin_number(24); - never_reset_pin_number(25); - never_reset_pin_number(29); + never_reset_pin_number(CYW43_DEFAULT_PIN_WL_REG_ON); + never_reset_pin_number(CYW43_DEFAULT_PIN_WL_DATA_IN); + never_reset_pin_number(CYW43_DEFAULT_PIN_WL_CS); + never_reset_pin_number(CYW43_DEFAULT_PIN_WL_CLOCK); #endif // Reset everything into a known state before board_init. reset_port(); - serial_early_init(); - - #ifdef CIRCUITPY_PSRAM_CHIP_SELECT - setup_psram(); - #endif - // Initialize RTC #if CIRCUITPY_RTC common_hal_rtc_init(); #endif + // Send-event-on-pend, so the WFE in port_idle_until_interrupt wakes on a + // pending interrupt (as WFI did) in addition to waking on SEV — including + // the SEV core 1 sends via port_wake_main_task() when it queues USB host + // work. + #if PICO_RP2040 + scb_hw->scr |= M0PLUS_SCR_SEVONPEND_BITS; + #else + scb_hw->scr |= M33_SCR_SEVONPEND_BITS; + #endif + // For the tick. hardware_alarm_claim(0); hardware_alarm_set_callback(0, _tick_callback); + // RP2 port-specific early serial initialization for psram debug. + // The RTC must already be initialized, otherwise the serial UART + // will hang. + serial_early_init(); + + #ifdef CIRCUITPY_PSRAM_CHIP_SELECT + setup_psram(); + #endif + + // Initialize heap early to allow for early allocation. + _port_heap_init(); + // Check brownout. #if CIRCUITPY_CYW43 @@ -349,7 +461,8 @@ safe_mode_t port_init(void) { // initializing the cyw43 chip. Delays inside cyw43_arch_init_with_country // are intended to meet the power on timing requirements, but apparently // are inadequate. We'll back off this long delay based on future testing. - mp_hal_delay_ms(1000); + mp_hal_delay_ms(CIRCUITPY_CYW43_INIT_DELAY); + // Change this as a placeholder as to how to init with country code. // Default country code is CYW43_COUNTRY_WORLDWIDE) if (cyw43_arch_init_with_country(PICO_CYW43_ARCH_DEFAULT_COUNTRY_CODE)) { @@ -367,8 +480,6 @@ safe_mode_t port_init(void) { void reset_port(void) { #if CIRCUITPY_BUSIO - reset_i2c(); - reset_spi(); reset_uart(); #endif @@ -380,6 +491,10 @@ void reset_port(void) { reset_rp2pio_statemachine(); #endif + #if CIRCUITPY_SDIOIO + sdioio_reset(); + #endif + #if CIRCUITPY_RTC rtc_reset(); #endif @@ -390,6 +505,14 @@ void reset_port(void) { #if CIRCUITPY_SSL ssl_reset(); + + // For raspberrypi, we must free PSA crypto, because there are GC-heap objects + // in the key slots. We can't put this call in ssl_reset() because that's a + // shared-module implementation. Unlike raspberrypi, espressif ESP-IDF inits PSA + // once at boot and would never re-init it. + // common_hal_ssl_sslcontext_construct() re-inits PSA on demand. + // So for raspberrypi, we must call mbedtls_psa_crypto_free() explicitly. + mbedtls_psa_crypto_free(); #endif #if CIRCUITPY_WATCHDOG @@ -399,8 +522,6 @@ void reset_port(void) { #if CIRCUITPY_WIFI wifi_reset(); #endif - - reset_all_pins(); } void reset_to_bootloader(void) { @@ -456,11 +577,11 @@ static volatile bool ticks_enabled; static volatile bool _woken_up; uint64_t port_get_raw_ticks(uint8_t *subticks) { - uint64_t microseconds = time_us_64(); + int64_t all_subticks = time_us_64() * 512 / 15625; if (subticks != NULL) { - *subticks = (uint8_t)(((microseconds % 1000000) % 977) / 31); + *subticks = all_subticks % 32; } - return 1024 * (microseconds / 1000000) + (microseconds % 1000000) / 977; + return all_subticks / 32; } static void _tick_callback(uint alarm_num) { @@ -496,6 +617,7 @@ void port_interrupt_after_ticks(uint32_t ticks) { } void port_idle_until_interrupt(void) { + #if PICO_RP2040 common_hal_mcu_disable_interrupts(); #if CIRCUITPY_USB_HOST if (!background_callback_pending() && !tud_task_event_ready() && !tuh_task_event_ready() && !_woken_up) { @@ -503,15 +625,59 @@ void port_idle_until_interrupt(void) { if (!background_callback_pending() && !tud_task_event_ready() && !_woken_up) { #endif __DSB(); - __WFI(); + // WFE, not WFI: the event register is sticky, so a SEV from core 1 + // (port_wake_main_task, e.g. a USB host event) that lands between the + // checks above and here still terminates the wait. Pending interrupts + // wake it too, via SEVONPEND (set in port_init). + __wfe(); } common_hal_mcu_enable_interrupts(); + #else + // because we use interrupt priority, don't use + // common_hal_mcu_disable_interrupts (because an interrupt masked by + // BASEPRI will not occur) + uint32_t state = save_and_disable_interrupts(); + + // Ensure BASEPRI is at 0... + uint32_t oldBasePri = __get_BASEPRI(); + __set_BASEPRI(0); + __isb(); + #if CIRCUITPY_USB_HOST + if (!background_callback_pending() && !tud_task_event_ready() && !tuh_task_event_ready() && !_woken_up) { + #else + if (!background_callback_pending() && !tud_task_event_ready() && !_woken_up) { + #endif + __DSB(); + // WFE, not WFI: see the RP2040 branch above. + __wfe(); + } + + // and restore basepri before reenabling interrupts + __set_BASEPRI(oldBasePri); + __isb(); + + restore_interrupts(state); + #endif +} + +// Called whenever a background callback is queued, including from core 1 +// (which runs the PIO-USB host and posts its events here). SEV is broadcast +// to both cores and latches in the event register, so it reliably ends the +// WFE in port_idle_until_interrupt even if it arrives before the WFE starts. +// Without this, core 0 sleeps through host events for the remainder of a +// time.sleep(): device removal processing and enumeration stall until the +// next unrelated wakeup. +// PLACE_IN_ITCM: core 1 runs with flash execute-never, so this must live in +// RAM like its background_callback_add_core caller (__sev inlines to a bare +// instruction). +void PLACE_IN_ITCM(port_wake_main_task)(void) { + __sev(); } /** * \brief Default interrupt handler for unused IRQs. */ -extern void isr_hardfault(void); // provide a prototype to avoid a missing-prototypes diagnostic +extern MP_NORETURN void isr_hardfault(void); // provide a prototype to avoid a missing-prototypes diagnostic __attribute__((used)) void __not_in_flash_func(isr_hardfault)(void) { // Only safe mode from core 0 which is running CircuitPython. Core 1 faulting // should not be fatal to CP. (Fingers crossed.) @@ -523,7 +689,7 @@ __attribute__((used)) void __not_in_flash_func(isr_hardfault)(void) { } } -void port_yield() { +void port_task_yield(void) { #if CIRCUITPY_CYW43 cyw43_arch_poll(); #endif @@ -538,3 +704,53 @@ void port_boot_info(void) { mp_printf(&mp_plat_print, "\n"); #endif } + +#if CIRCUITPY_BOOT_BUTTON_NO_GPIO +bool __no_inline_not_in_flash_func(port_boot_button_pressed)(void) { + // Sense the state of the boot button. Because this function + // disables flash, it cannot be safely called once the second + // core has been started. When the BOOTSEL button is sensed as + // pressed, return is delayed until the button is released and + // a delay has passed in order to debounce the button. + const uint32_t CS_PIN_INDEX = 1; + #if PICO_RP2040 + const uint32_t CS_BIT = 1u << 1; + #else + const uint32_t CS_BIT = SIO_GPIO_HI_IN_QSPI_CSN_BITS; + #endif + uint32_t int_state = save_and_disable_interrupts(); + // Wait for any outstanding XIP activity to finish. Flash + // must be quiescent before disabling the chip select. Since + // there's no XIP busy indication we can test, we delay a + // generous 5 ms to allow any XIP activity to finish. + busy_wait_us(5000); + // Float the flash chip select pin. The line will HI-Z due to + // the external 10K pull-up resistor. + hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, + GPIO_OVERRIDE_LOW << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, + IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); + // Delay 100 us to allow the CS line to stabilize. If BOOTSEL is + // pressed, the line will be pulled low by the button and its + // 1K external resistor to ground. + busy_wait_us(100); + bool button_pressed = !(sio_hw->gpio_hi_in & CS_BIT); + // Wait for the button to be released. + if (button_pressed) { + while (!(sio_hw->gpio_hi_in & CS_BIT)) { + tight_loop_contents(); + } + // Wait for 50 ms to debounce the button. + busy_wait_us(50000); + } + // Restore the flash chip select pin to its original state. + hw_write_masked(&ioqspi_hw->io[CS_PIN_INDEX].ctrl, + GPIO_OVERRIDE_NORMAL << IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_LSB, + IO_QSPI_GPIO_QSPI_SS_CTRL_OEOVER_BITS); + // Delay 5 ms to allow the flash chip to re-enable and for the + // flash CS pin to stabilize. + busy_wait_us(5000); + // Restore the interrupt state. + restore_interrupts(int_state); + return button_pressed; +} +#endif diff --git a/ports/raspberrypi/supervisor/rp2_cpu.s b/ports/raspberrypi/supervisor/rp2_cpu.s deleted file mode 100755 index 741bb21358a..00000000000 --- a/ports/raspberrypi/supervisor/rp2_cpu.s +++ /dev/null @@ -1,35 +0,0 @@ -.syntax unified -.cpu cortex-m0 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0, #0] -str r5, [r0, #4] -str r6, [r0, #8] -str r7, [r0, #12] -push {r1} -mov r1, r8 -str r1, [r0, #16] -mov r1, r9 -str r1, [r0, #20] -mov r1, r10 -str r1, [r0, #24] -mov r1, r11 -str r1, [r0, #28] -mov r1, r12 -str r1, [r0, #32] -mov r1, r13 -str r1, [r0, #36] -pop {r1} - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/raspberrypi/supervisor/usb.c b/ports/raspberrypi/supervisor/usb.c index 97933d5651e..244c5bbce9b 100644 --- a/ports/raspberrypi/supervisor/usb.c +++ b/ports/raspberrypi/supervisor/usb.c @@ -6,14 +6,30 @@ #include "lib/tinyusb/src/device/usbd.h" #include "supervisor/background_callback.h" +#include "supervisor/linker.h" #include "supervisor/usb.h" -#include "src/rp2_common/hardware_irq/include/hardware/irq.h" +#include "hardware/irq.h" +#include "hardware/timer.h" #include "pico/platform.h" -#include "src/rp2040/hardware_regs/include/hardware/regs/intctrl.h" +#include "hardware/regs/intctrl.h" void init_usb_hardware(void) { } +// Override the shared implementation with one that is safe to call from core1. +// TinyUSB's tuh_task_event_ready() calls this, and usb_host polls +// tuh_task_event_ready() from core1's PIO-USB frame loop (see +// common-hal/usb_host/Port.c). tuh_task_event_ready() is deliberately placed in +// RAM by link-rp2*.ld, and everything it calls must be RAM-resident too: on +// RP2350, core1 sets an MPU region that makes flash execute-never, and on +// RP2040 flash may be unavailable while core0 writes to it. time_us_32() is a +// static-inline register read. >>10 yields ~1.024 ms units rather than exact +// milliseconds, which is fine because TinyUSB only uses this API for relative +// delay arithmetic and every use goes through this same function. +uint32_t PLACE_IN_ITCM(tusb_time_millis_api)(void) { + return time_us_32() >> 10; +} + static void _usb_irq_wrapper(void) { usb_irq_handler(0); } diff --git a/ports/renode/Makefile b/ports/renode/Makefile index 98fe04f4713..c4ce66194e9 100644 --- a/ports/renode/Makefile +++ b/ports/renode/Makefile @@ -21,7 +21,7 @@ INC += \ CFLAGS += -ggdb3 -Os DISABLE_WARNINGS = -Wno-cast-align -CFLAGS += $(INC) -Wall -Werror -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=missing-prototypes +CFLAGS += $(INC) -Wall -Werror -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT) $(DISABLE_WARNINGS) -Werror=missing-prototypes -Werror=old-style-definition CFLAGS += \ -march=armv6-m \ @@ -45,21 +45,9 @@ SRC_C += \ background.c \ mphalport.c \ +SRC_S = shared/runtime/gchelper_thumb1.s -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - -# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, -# because a few modules have files both in common-hal/ and shared-module/. -# Doing a $(sort ...) removes duplicates as part of sorting. -SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) - -SRC_S = supervisor/$(CPU)_cpu.s +SRC_C += shared/runtime/gchelper_native.c OBJ = $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) @@ -68,14 +56,13 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif OBJ += $(addprefix $(BUILD)/, $(SRC_CIRCUITPY_COMMON:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_S_UPPER:.S=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)) $(BUILD)/%.o: $(BUILD)/%.S $(STEPECHO) "CC $<" $(Q)$(CC) $(CFLAGS) -c -o $@ $< -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) all: $(BUILD)/firmware.elf $(BUILD)/circuitpy.img diff --git a/ports/renode/common-hal/busio/I2C.c b/ports/renode/common-hal/busio/I2C.c index c94f63cb880..41649f180b3 100644 --- a/ports/renode/common-hal/busio/I2C.c +++ b/ports/renode/common-hal/busio/I2C.c @@ -44,19 +44,19 @@ bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return 0; } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { - return MP_EIO; + return -MP_EIO; } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - return MP_EIO; + return -MP_EIO; } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { diff --git a/ports/renode/common-hal/busio/SPI.c b/ports/renode/common-hal/busio/SPI.c index 6f5f6050607..1f66fc5ec4a 100644 --- a/ports/renode/common-hal/busio/SPI.c +++ b/ports/renode/common-hal/busio/SPI.c @@ -21,6 +21,9 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return true; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; diff --git a/ports/renode/common-hal/microcontroller/Processor.c b/ports/renode/common-hal/microcontroller/Processor.c index 3532aa6907a..3a6523338fc 100644 --- a/ports/renode/common-hal/microcontroller/Processor.c +++ b/ports/renode/common-hal/microcontroller/Processor.c @@ -33,5 +33,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_POWER_ON; + return MCU_RESET_REASON_POWER_ON; } diff --git a/ports/renode/common-hal/os/__init__.c b/ports/renode/common-hal/os/__init__.c index 334742bb594..14e22960469 100644 --- a/ports/renode/common-hal/os/__init__.c +++ b/ports/renode/common-hal/os/__init__.c @@ -12,32 +12,6 @@ #include "shared-bindings/os/__init__.h" -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, "renode"); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, "renode"); -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { return false; } diff --git a/ports/renode/supervisor/cortex-m0+_cpu.s b/ports/renode/supervisor/cortex-m0+_cpu.s deleted file mode 100755 index 741bb21358a..00000000000 --- a/ports/renode/supervisor/cortex-m0+_cpu.s +++ /dev/null @@ -1,35 +0,0 @@ -.syntax unified -.cpu cortex-m0 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0, #0] -str r5, [r0, #4] -str r6, [r0, #8] -str r7, [r0, #12] -push {r1} -mov r1, r8 -str r1, [r0, #16] -mov r1, r9 -str r1, [r0, #20] -mov r1, r10 -str r1, [r0, #24] -mov r1, r11 -str r1, [r0, #28] -mov r1, r12 -str r1, [r0, #32] -mov r1, r13 -str r1, [r0, #36] -pop {r1} - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/renode/supervisor/port.c b/ports/renode/supervisor/port.c index dae32b7bb8f..a40e222d34d 100644 --- a/ports/renode/supervisor/port.c +++ b/ports/renode/supervisor/port.c @@ -210,7 +210,7 @@ __attribute__((used)) void HardFault_Handler(void) { } } -void port_yield() { +void port_task_yield(void) { } void port_boot_info(void) { diff --git a/ports/silabs/Makefile b/ports/silabs/Makefile index 8c7663718e3..810ab53f1f3 100644 --- a/ports/silabs/Makefile +++ b/ports/silabs/Makefile @@ -71,7 +71,7 @@ ifeq ($(DEBUG), 1) CFLAGS += -fno-inline -fno-ipa-sra -Og else CFLAGS += -DNDEBUG - OPTIMIZATION_FLAGS ?= -Os -fno-inline-functions + OPTIMIZATION_FLAGS ?= -Os CFLAGS += -g endif @@ -90,20 +90,10 @@ ifneq (,$(wildcard boards/$(BOARD)/sensor.c)) SRC_C += boards/$(BOARD)/sensor.c endif -SRC_S = boards/mp_efr32xg24_gchelper.s +AFLAGS = -mcpu=cortex-m33 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard +SRC_S = shared/runtime/gchelper_thumb1.s -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - -# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, -# because a few modules have files both in common-hal/ and shared-module/. -# Doing a $(sort ...) removes duplicates as part of sorting. -SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) +SRC_C += shared/runtime/gchelper_native.c OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) @@ -118,7 +108,7 @@ $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR += diff --git a/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c b/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c index aaf698a6cb2..1c991a4caaf 100644 --- a/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c +++ b/ports/silabs/boards/devkit_xg24_brd2601b/sensor.c @@ -75,7 +75,7 @@ static mp_obj_t sensor_init(mp_obj_t i2c_in) { return mp_const_true; } -static mp_obj_t sensor_deinit() { +static mp_obj_t sensor_deinit(void) { sl_sensor_hall_deinit(); sl_sensor_lux_deinit(); diff --git a/ports/silabs/common-hal/_bleio/Characteristic.c b/ports/silabs/common-hal/_bleio/Characteristic.c index 37fb792cd4d..9ccc6ad9c36 100644 --- a/ports/silabs/common-hal/_bleio/Characteristic.c +++ b/ports/silabs/common-hal/_bleio/Characteristic.c @@ -249,7 +249,7 @@ size_t common_hal_bleio_characteristic_get_value( return 0; } -// Get max length of charateristic +// Get max length of characteristic size_t common_hal_bleio_characteristic_get_max_length( bleio_characteristic_obj_t *self) { return self->max_length; @@ -373,7 +373,7 @@ void common_hal_bleio_characteristic_add_descriptor( // This indicates the new added descriptor shall be started. sc = sl_bt_gattdb_start_characteristic(gattdb_session, self->handle); if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start characteristic fail.")); return; } @@ -395,7 +395,7 @@ void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, const uint16_t conn_handle = bleio_connection_get_conn_handle( self->service->connection); - common_hal_bleio_check_connected(conn_handle); + bleio_check_connected(conn_handle); notify = 1; indicate = 0; if (notify) { diff --git a/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c index 2acb6b00fca..d08fa765c4f 100644 --- a/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c +++ b/ports/silabs/common-hal/_bleio/CharacteristicBuffer.c @@ -87,7 +87,7 @@ void common_hal_bleio_characteristic_buffer_construct( mp_float_t timeout, size_t buffer_size) { - uint8_t *buffer = m_malloc(buffer_size); + uint8_t *buffer = m_malloc_without_collect(buffer_size); _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, @@ -156,7 +156,7 @@ bool common_hal_bleio_characteristic_buffer_connected( common_hal_bleio_connection_get_connected(self->characteristic->service->connection))); } -void reset_characteristic_buffer_list() { +void reset_characteristic_buffer_list(void) { // Remove characteristic_buffer list memset(bleio_characteristic_buffer_list.data, 0, sizeof(bleio_characteristic_buffer_list.data)); diff --git a/ports/silabs/common-hal/_bleio/Connection.h b/ports/silabs/common-hal/_bleio/Connection.h index 56872024c93..148caecba11 100644 --- a/ports/silabs/common-hal/_bleio/Connection.h +++ b/ports/silabs/common-hal/_bleio/Connection.h @@ -85,6 +85,7 @@ typedef struct void bleio_connection_clear(bleio_connection_internal_t *self); +void bleio_check_connected(uint16_t conn_handle); uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self); mp_obj_t bleio_connection_new_from_internal( diff --git a/ports/silabs/common-hal/_bleio/PacketBuffer.c b/ports/silabs/common-hal/_bleio/PacketBuffer.c index 1e5159fc6a2..881cf1622eb 100644 --- a/ports/silabs/common-hal/_bleio/PacketBuffer.c +++ b/ports/silabs/common-hal/_bleio/PacketBuffer.c @@ -145,7 +145,7 @@ void _common_hal_bleio_packet_buffer_construct( uint32_t *outgoing_buffer1, uint32_t *outgoing_buffer2, size_t max_packet_size, - ble_event_handler_t static_handler_entry) { + ble_event_handler_t *static_handler_entry) { bleio_characteristic_properties_t temp_prop; self->characteristic = characteristic; @@ -223,12 +223,12 @@ void common_hal_bleio_packet_buffer_construct( if (incoming) { incoming_buffer_size = buffer_size * (sizeof(uint16_t) + max_packet_size); - incoming_buffer = m_malloc(incoming_buffer_size); + incoming_buffer = m_malloc_without_collect(incoming_buffer_size); } if (outgoing) { - outgoing1 = m_malloc(max_packet_size); - outgoing2 = m_malloc(max_packet_size); + outgoing1 = m_malloc_without_collect(max_packet_size); + outgoing2 = m_malloc_without_collect(max_packet_size); } _common_hal_bleio_packet_buffer_construct(self, characteristic, incoming_buffer, incoming_buffer_size, @@ -391,7 +391,7 @@ void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { } // Remove packet_buffer list when reload -void reset_packet_buffer_list() { +void reset_packet_buffer_list(void) { // Remove packet_buffer list memset(bleio_packet_buffer_list.data, 0, sizeof(bleio_packet_buffer_list.data)); diff --git a/ports/silabs/common-hal/_bleio/Service.c b/ports/silabs/common-hal/_bleio/Service.c index 694841e6628..50f0c4593a6 100644 --- a/ports/silabs/common-hal/_bleio/Service.c +++ b/ports/silabs/common-hal/_bleio/Service.c @@ -128,7 +128,7 @@ bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { return self->uuid; } -// Get tuple charateristic of service +// Get tuple characteristic of service mp_obj_tuple_t *common_hal_bleio_service_get_characteristics( bleio_service_obj_t *self) { return mp_obj_new_tuple(self->characteristic_list->len, @@ -210,19 +210,19 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, } if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Add charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Add characteristic fail.")); } sc = sl_bt_gattdb_start_characteristic(gattdb_session, characteristic->handle); if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Start characteristic fail.")); return; } sc = sl_bt_gattdb_commit(gattdb_session); if (SL_STATUS_OK != sc) { - mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Commit charateristic fail.")); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Commit characteristic fail.")); return; } mp_obj_list_append(self->characteristic_list, @@ -230,7 +230,7 @@ void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, } // Remove dynamic service when reload -void reset_dynamic_service() { +void reset_dynamic_service(void) { uint16_t gattdb_session; uint8_t svc_index; diff --git a/ports/silabs/common-hal/_bleio/__init__.c b/ports/silabs/common-hal/_bleio/__init__.c index 2905dc41e09..4c5ce1f045d 100644 --- a/ports/silabs/common-hal/_bleio/__init__.c +++ b/ports/silabs/common-hal/_bleio/__init__.c @@ -54,7 +54,7 @@ const osMutexAttr_t bluetooth_connection_mutex_attr = { void common_hal_bleio_init(void) { } -void bleio_user_reset() { +void bleio_user_reset(void) { // Stop any user scanning or advertising. common_hal_bleio_adapter_stop_scan(&common_hal_bleio_adapter_obj); common_hal_bleio_adapter_stop_advertising(&common_hal_bleio_adapter_obj); @@ -63,7 +63,7 @@ void bleio_user_reset() { supervisor_bluetooth_background(); } -void bleio_reset() { +void bleio_reset(void) { reset_dynamic_service(); reset_packet_buffer_list(); reset_characteristic_buffer_list(); @@ -102,7 +102,7 @@ void check_ble_error(int error_code) { } } -void common_hal_bleio_check_connected(uint16_t conn_handle) { +void bleio_check_connected(uint16_t conn_handle) { if (conn_handle == BLEIO_HANDLE_INVALID) { mp_raise_ConnectionError(MP_ERROR_TEXT("Not connected")); } @@ -194,8 +194,7 @@ void sl_bt_on_event(sl_bt_msg_t *evt) { uuid = m_new_obj_maybe(bleio_uuid_obj_t); if (NULL == uuid) { osMutexRelease(bluetooth_connection_mutex_id); - mp_raise_bleio_BluetoothError( - MP_ERROR_TEXT("Create new service uuid obj fail")); + m_malloc_fail(sizeof(bleio_uuid_obj_t)); break; } uuid->base.type = &bleio_uuid_type; diff --git a/ports/silabs/common-hal/busio/I2C.c b/ports/silabs/common-hal/busio/I2C.c index 7934416b127..6c2b04d821d 100644 --- a/ports/silabs/common-hal/busio/I2C.c +++ b/ports/silabs/common-hal/busio/I2C.c @@ -32,15 +32,6 @@ static I2CSPM_Init_TypeDef i2cspm_init; static bool in_used = false; -static bool never_reset = false; - -// Reser I2C peripheral -void i2c_reset(void) { - if ((!never_reset) && in_used) { - I2C_Reset(DEFAULT_I2C_PERIPHERAL); - in_used = false; - } -} // Construct I2C protocol, this function init i2c peripheral void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, @@ -48,6 +39,9 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + if ((scl != NULL) && (sda != NULL)) { if (scl->function_list[ DEFAULT_I2C_PERIPHERAL == I2C1? FN_I2C1_SCL : FN_I2C0_SCL] == 1 && @@ -80,7 +74,6 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, // Never reset I2C obj when reload void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { - never_reset = true; common_hal_never_reset_pin(self->sda); common_hal_never_reset_pin(self->scl); } @@ -98,10 +91,13 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { I2C_Reset(self->i2cspm); common_hal_reset_pin(self->sda); common_hal_reset_pin(self->scl); - self->sda = NULL; - self->scl = NULL; self->i2cspm = NULL; in_used = false; + common_hal_busio_i2c_mark_deinit(self); +} + +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + self->sda = NULL; } // Probe device in I2C bus @@ -149,7 +145,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { } // Write data to the device selected by address -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { I2C_TransferSeq_TypeDef seq; @@ -163,13 +159,13 @@ uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, ret = I2CSPM_Transfer(self->i2cspm, &seq); if (ret != i2cTransferDone) { - return MP_EIO; + return -MP_EIO; } return 0; } // Read into buffer from the device selected by address -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { @@ -184,13 +180,13 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, ret = I2CSPM_Transfer(self->i2cspm, &seq); if (ret != i2cTransferDone) { - return MP_EIO; + return -MP_EIO; } return 0; } // Write the bytes from out_data to the device selected by address, -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { @@ -208,7 +204,7 @@ uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, ret = I2CSPM_Transfer(self->i2cspm, &seq); if (ret != i2cTransferDone) { - return MP_EIO; + return -MP_EIO; } return 0; } diff --git a/ports/silabs/common-hal/busio/I2C.h b/ports/silabs/common-hal/busio/I2C.h index 14f879ee445..a225299280a 100644 --- a/ports/silabs/common-hal/busio/I2C.h +++ b/ports/silabs/common-hal/busio/I2C.h @@ -24,8 +24,7 @@ * THE SOFTWARE. */ -#ifndef MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H -#define MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H +#pragma once #include "common-hal/microcontroller/Pin.h" #include "peripherals/periph.h" @@ -40,7 +39,3 @@ typedef struct { const mcu_pin_obj_t *scl; const mcu_pin_obj_t *sda; } busio_i2c_obj_t; - -void i2c_reset(void); - -#endif // MICROPY_INCLUDED_EFR32_COMMON_HAL_BUSIO_I2C_H diff --git a/ports/silabs/common-hal/busio/SPI.c b/ports/silabs/common-hal/busio/SPI.c index 74cfc69bfb2..fb3b7c4fd20 100644 --- a/ports/silabs/common-hal/busio/SPI.c +++ b/ports/silabs/common-hal/busio/SPI.c @@ -37,16 +37,6 @@ static SPIDRV_HandleData_t spidrv_eusart_handle; static SPIDRV_Init_t spidrv_eusart_init = SPIDRV_MASTER_EUSART1; static bool in_used = false; -static bool never_reset = false; - -// Reset SPI when reload -void spi_reset(void) { - if (!never_reset && in_used) { - SPIDRV_DeInit(&spidrv_eusart_handle); - in_used = false; - } - return; -} // Construct SPI protocol, this function init SPI peripheral void common_hal_busio_spi_construct(busio_spi_obj_t *self, @@ -61,6 +51,9 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, MP_ERROR_TEXT("Half duplex SPI is not implemented")); } + // Ensure the object starts in its deinit state. + common_hal_busio_spi_mark_deinit(self); + if ((sck != NULL) && (mosi != NULL) && (miso != NULL)) { if (sck->function_list[FN_EUSART1_SCLK] == 1 && miso->function_list[FN_EUSART1_RX] == 1 @@ -108,7 +101,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, // Never reset SPI when reload void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset = true; common_hal_never_reset_pin(self->mosi); common_hal_never_reset_pin(self->miso); common_hal_never_reset_pin(self->sck); @@ -119,6 +111,10 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->sck == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->sck = NULL; +} + // Deinit SPI obj void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { @@ -132,13 +128,14 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { } in_used = false; - self->sck = NULL; self->mosi = NULL; self->miso = NULL; self->handle = NULL; common_hal_reset_pin(self->mosi); common_hal_reset_pin(self->miso); common_hal_reset_pin(self->sck); + + common_hal_busio_spi_mark_deinit(self); } // Configures the SPI bus. The SPI object must be locked. diff --git a/ports/silabs/common-hal/digitalio/DigitalInOut.h b/ports/silabs/common-hal/digitalio/DigitalInOut.h index 23a5a235378..a69eb48df33 100644 --- a/ports/silabs/common-hal/digitalio/DigitalInOut.h +++ b/ports/silabs/common-hal/digitalio/DigitalInOut.h @@ -1,29 +1,6 @@ /* * This file is part of Adafruit for EFR32 project - * - * The MIT License (MIT) - * - * Copyright 2023 Silicon Laboratories Inc. www.silabs.com - * - * 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. */ - #ifndef MICROPY_INCLUDED_EFR32_COMMON_HAL_DIGITALIO_DIGITALINOUT_H #define MICROPY_INCLUDED_EFR32_COMMON_HAL_DIGITALIO_DIGITALINOUT_H diff --git a/ports/silabs/common-hal/microcontroller/Processor.c b/ports/silabs/common-hal/microcontroller/Processor.c index 226fe4529fb..741a147d1cf 100644 --- a/ports/silabs/common-hal/microcontroller/Processor.c +++ b/ports/silabs/common-hal/microcontroller/Processor.c @@ -62,5 +62,5 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { } mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } diff --git a/ports/silabs/common-hal/microcontroller/__init__.c b/ports/silabs/common-hal/microcontroller/__init__.c index b1472fcf437..7244af6619d 100644 --- a/ports/silabs/common-hal/microcontroller/__init__.c +++ b/ports/silabs/common-hal/microcontroller/__init__.c @@ -60,6 +60,9 @@ void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { } } +// CHIP_Reset does not return, but is not declared as such in the SDK. +void __attribute__ ((noreturn)) CHIP_Reset(void); + void common_hal_mcu_reset(void) { filesystem_flush(); // TODO: implement as part of flash improvements CHIP_Reset(); diff --git a/ports/silabs/common-hal/os/__init__.c b/ports/silabs/common-hal/os/__init__.c index 42036536e4f..79e79875fd5 100644 --- a/ports/silabs/common-hal/os/__init__.c +++ b/ports/silabs/common-hal/os/__init__.c @@ -35,31 +35,6 @@ #include "peripherals/periph.h" #define RNG_TIMEOUT 5 -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, EFR32_SERIES_LOWER); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, EFR32_SERIES_LOWER); - -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { return false; diff --git a/ports/silabs/mpconfigport.h b/ports/silabs/mpconfigport.h index ce7739cccae..26fe7dfc2f0 100644 --- a/ports/silabs/mpconfigport.h +++ b/ports/silabs/mpconfigport.h @@ -29,9 +29,6 @@ #include -#define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) - // 24kiB stack #define CIRCUITPY_DEFAULT_STACK_SIZE 0x6000 diff --git a/ports/silabs/mpconfigport.mk b/ports/silabs/mpconfigport.mk index 7c00338955f..7192be3f415 100644 --- a/ports/silabs/mpconfigport.mk +++ b/ports/silabs/mpconfigport.mk @@ -3,7 +3,7 @@ INTERNAL_LIBM ?= 1 USB_NUM_ENDPOINT_PAIRS = 0 CIRCUITPY_ANALOGIO ?= 1 -CIRCUITPY_BLEIO ?= 1 +CIRCUITPY_BLEIO_NATIVE ?= 1 CIRCUITPY_BUSDEVICE ?= 1 CIRCUITPY_BUSIO ?= 1 CIRCUITPY_DIGITALIO ?= 1 @@ -15,6 +15,8 @@ CIRCUITPY_RTC ?= 1 CIRCUITPY_USB_DEVICE = 0 CIRCUITPY_WATCHDOG ?=1 +CIRCUITPY_PORT_SERIAL = 1 + ifeq ($(MCU_SERIES),MG24) # Not yet implemented common-hal modules: CIRCUITPY_AUDIOIO ?= 0 diff --git a/ports/silabs/supervisor/port.c b/ports/silabs/supervisor/port.c index d94093b3e1d..85a6e0f92a5 100644 --- a/ports/silabs/supervisor/port.c +++ b/ports/silabs/supervisor/port.c @@ -33,7 +33,6 @@ #include "shared-bindings/microcontroller/__init__.h" #if CIRCUITPY_BUSIO -#include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" #endif @@ -157,11 +156,7 @@ safe_mode_t port_init(void) { } void reset_port(void) { - reset_all_pins(); - #if CIRCUITPY_BUSIO - i2c_reset(); - spi_reset(); uart_reset(); #endif diff --git a/ports/silabs/tools/make_pins.py b/ports/silabs/tools/make_pins.py index da662094b36..9ae370bf6de 100644 --- a/ports/silabs/tools/make_pins.py +++ b/ports/silabs/tools/make_pins.py @@ -124,7 +124,7 @@ def make_pin_function_lists(functions, pins): fcn_list[pin][i] = 1 i += 1 for pin in pins.keys(): - if not pin in fcn_list: + if pin not in fcn_list: fcn_list[pin] = [] decl += make_pin_function_list_decl(pin, fcn_list[pin]) diff --git a/ports/stm/Makefile b/ports/stm/Makefile index d42ebdc7276..5ad0c82654c 100755 --- a/ports/stm/Makefile +++ b/ports/stm/Makefile @@ -38,8 +38,7 @@ ifeq ($(DEBUG), 1) CFLAGS += -fno-inline -fno-ipa-sra else CFLAGS += -DNDEBUG - OPTIMIZATION_FLAGS ?= -O2 -fno-inline-functions - CFLAGS += -ggdb3 + OPTIMIZATION_FLAGS ?= -O2 endif # to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk @@ -48,10 +47,10 @@ CFLAGS += $(OPTIMIZATION_FLAGS) # Add -ftree-vrp optimization and checking to all builds. It's not enabled for -Os by default. CFLAGS += -ftree-vrp -# MCU Series is defined by the HAL package and doesn't need to be specified here -C_DEFS = -D$(MCU_PACKAGE) -DUSE_HAL_DRIVER -DUSE_FULL_LL_DRIVER -D$(MCU_VARIANT) +# STM32 MCU series must be defined. See supervisor/linker.h +C_DEFS = -D$(MCU_PACKAGE) -DUSE_HAL_DRIVER -DUSE_FULL_LL_DRIVER -D$(MCU_VARIANT) -DSTM32$(MCU_SERIES) -CFLAGS += $(INC) -Werror -Wall -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) -nostdlib -nostartfiles +CFLAGS += $(INC) -Werror -Wall -std=gnu11 -fshort-enums $(BASE_CFLAGS) $(C_DEFS) $(CFLAGS_MOD) $(COPT) -nostdlib -nostartfiles -Werror=old-style-definition # Undo some warnings. # STM32 HAL uses undefined preprocessor variables, shadowed variables, casts that change alignment reqs @@ -73,7 +72,7 @@ CFLAGS += -DSTM32_HAL_H="" CFLAGS += -DSTM32_SERIES_LOWER='"stm32$(MCU_SERIES_LOWER)"' # Floating point settings -ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F765xx STM32F767xx STM32F769xx STM32H743xx)) +ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F765xx STM32F767xx STM32F769xx STM32H743xx STM32H750xx)) CFLAGS += -mfpu=fpv5-d16 -mfloat-abi=hard else CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard @@ -165,10 +164,17 @@ endif # Need this to avoid UART linker problems. TODO: rewrite to use registered callbacks. # Does not exist for F4 and lower -ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F765xx STM32F767xx STM32F769xx STM32H743xx STM32L4R5xx)) +ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F765xx STM32F767xx STM32F769xx STM32H743xx STM32H750xx STM32L4R5xx STM32L433xx)) SRC_STM32 += $(HAL_DIR)/Src/stm32$(MCU_SERIES_LOWER)xx_hal_uart_ex.c endif +ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32H750xx)) + C_DEFS += -DHAL_SDRAM_MODULE_ENABLED + SRC_STM32 += st_driver/stm32$(MCU_SERIES_LOWER)xx_hal_driver/Src/stm32h7xx_hal_sdram.c + SRC_STM32 += st_driver/stm32$(MCU_SERIES_LOWER)xx_hal_driver/Src/stm32h7xx_ll_fmc.c + SRC_C += peripherals/sdram.c +endif + SRC_STM32 += boards/system_stm32$(MCU_SERIES_LOWER)xx.c SRC_C += \ @@ -197,21 +203,20 @@ ifneq ($(CIRCUITPY_AUDIOBUSIO_PDMIN),0) endif ifneq ($(CIRCUITPY_USB),0) -SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c + ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32L433xx)) + SRC_C += lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + SRC_C += lib/tinyusb/src/portable/st/stm32_fsdev/fsdev_common.c + else + SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dcd_dwc2.c + SRC_C += lib/tinyusb/src/portable/synopsys/dwc2/dwc2_common.c + endif endif SRC_S = \ - supervisor/cpu.s \ + shared/runtime/gchelper_thumb1.s \ st_driver/cmsis_device_$(MCU_SERIES_LOWER)/Source/Templates/gcc/startup_$(MCU_VARIANT_LOWER).s -SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ - $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ - $(addprefix common-hal/, $(SRC_COMMON_HAL)) - -SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ - $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) - +SRC_C += shared/runtime/gchelper_native.c ifneq ($(FROZEN_MPY_DIR),) FROZEN_MPY_PY_FILES := $(shell find -L $(FROZEN_MPY_DIR) -type f -name '*.py') @@ -220,8 +225,7 @@ endif OBJ += $(PY_O) $(SUPERVISOR_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_STM32:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o)) -OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o)) +OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED:.c=.o)) ifeq ($(INTERNAL_LIBM),1) OBJ += $(addprefix $(BUILD)/, $(SRC_LIBM:.c=.o)) endif @@ -233,12 +237,12 @@ $(BUILD)/$(FATFS_DIR)/ff.o: COPT += -Os $(filter $(PY_BUILD)/../extmod/vfs_fat_%.o, $(PY_O)): COPT += -Os # List of sources for qstr extraction -SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) +SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_SHARED_MODULE_EXPANDED) $(SRC_CIRCUITPY_COMMON) # Sources that only hold QSTRs after pre-processing. SRC_QSTR_PREPROCESSOR += # Bin section settings specific to the STM32H7 -ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32H743xx)) +ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32H743xx STM32H750xx)) MCU_SECTIONS = -j .isr_vector -j .text -j .data -j .itcm -j .dtcm_data $^ $@ else MCU_SECTIONS = $^ $@ diff --git a/ports/stm/boards/STM32H750.ld b/ports/stm/boards/STM32H750.ld new file mode 100644 index 00000000000..e10a2ce91f7 --- /dev/null +++ b/ports/stm/boards/STM32H750.ld @@ -0,0 +1,34 @@ +/* + GNU linker script for STM32H750 +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +_ld_default_stack_size = 24K; + +/* Specify the memory areas -- CircuitPython is loaded on the external QSPI flash */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x90000000, LENGTH = 8M /* 8M */ + FLASH_ISR (rx) : ORIGIN = 0x90000000, LENGTH = 4K /* sector 0 */ + FLASH_FIRMWARE (rx) : ORIGIN = 0x90001000, LENGTH = 8M-4K + DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K + RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K /* AXI SRAM */ + SRAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K /* AHB1 SRAM */ + SRAM_D3 (xrw) : ORIGIN = 0x30040000, LENGTH = 64K /* AHB2 SRAM */ + ITCM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 24K; /*TODO: this can probably be bigger, but how big?*/ +_minimum_heap_size = 16K; + +/* Define tho top end of the stack. The stack is full descending so begins just + above last byte of RAM. Note that EABI requires the stack to be 8-byte + aligned for a call. */ +_estack = ORIGIN(DTCM) + LENGTH(DTCM); + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); diff --git a/ports/stm/boards/STM32L433_boot.ld b/ports/stm/boards/STM32L433_boot.ld new file mode 100644 index 00000000000..686547a8ce6 --- /dev/null +++ b/ports/stm/boards/STM32L433_boot.ld @@ -0,0 +1,27 @@ +/* + GNU linker script for STM32L433 with bootloader +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256k /* entire flash */ + FLASH_ISR (rx) : ORIGIN = 0x08010000, LENGTH = 4K /* ISR vector. Kind of wasteful. */ + FLASH_FIRMWARE (rx) : ORIGIN = 0x08011000, LENGTH = 192K-64K-4K + FLASH_FS (rw) : ORIGIN = 0x08030000, LENGTH = 60K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 640K +} + + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 24K; +_minimum_heap_size = 16K; + +/* Define the top end of the stack. The stack is full descending so begins just + above last byte of RAM. Note that EABI requires the stack to be 8-byte + aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); diff --git a/ports/stm/boards/STM32L433_default.ld b/ports/stm/boards/STM32L433_default.ld new file mode 100644 index 00000000000..886a1b8827a --- /dev/null +++ b/ports/stm/boards/STM32L433_default.ld @@ -0,0 +1,29 @@ +/* + GNU linker script for STM32L433 with filesystem +*/ + +/* Specify the memory areas */ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K /* entire flash */ + FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 16K /* ISR vector. */ + FLASH_FS (rw) : ORIGIN = 0x08004000, LENGTH = 48K + FLASH_FIRMWARE (rx) : ORIGIN = 0x08010000, LENGTH = 256K - 48K - 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 64K +} + +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 24K; +_minimum_heap_size = 16K; + +/* Define the top end of the stack. The stack is full descending so begins just + above last byte of RAM. Note that EABI requires the stack to be 8-byte + aligned for a call. */ +_estack = ORIGIN(RAM) + LENGTH(RAM); + +/* RAM extents for the garbage collector */ +_ram_start = ORIGIN(RAM); +_ram_end = ORIGIN(RAM) + LENGTH(RAM); + +/* ensure the firmware is within bounds */ +ASSERT ( (ORIGIN(FLASH_FIRMWARE) + LENGTH(FLASH_FIRMWARE)) <= (ORIGIN(FLASH)+LENGTH(FLASH)), "FLASH_FIRMWARE out of bounds" ); diff --git a/ports/stm/boards/blues_cygnet/board.c b/ports/stm/boards/blues_cygnet/board.c new file mode 100644 index 00000000000..f6650fb8f9c --- /dev/null +++ b/ports/stm/boards/blues_cygnet/board.c @@ -0,0 +1,79 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/board.h" +#include "mpconfigboard.h" + +#include "stm32l4xx.h" +#include "stm32l433xx.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "board.h" + +digitalio_digitalinout_obj_t power_pin = { .base.type = &digitalio_digitalinout_type }; +digitalio_digitalinout_obj_t discharge_pin = { .base.type = &digitalio_digitalinout_type }; + +void initialize_discharge_pin(void) { + /* Initialize the 3V3 discharge to be OFF and the output power to be ON */ + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + common_hal_digitalio_digitalinout_construct(&power_pin, &pin_PH00); + common_hal_digitalio_digitalinout_construct(&discharge_pin, &pin_PH01); + common_hal_digitalio_digitalinout_never_reset(&power_pin); + common_hal_digitalio_digitalinout_never_reset(&discharge_pin); + + GPIO_InitTypeDef GPIO_InitStruct; + + /* Set DISCHARGE_3V3 as well as the pins we're not initially using to FLOAT */ + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Pin = GPIO_PIN_1; + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); /* PH1 DISCHARGE_3V3 */ + GPIO_InitStruct.Pin = GPIO_PIN_3; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* PB3 is USB_DETECT */ + GPIO_InitStruct.Pin = GPIO_PIN_15; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* PA15 is CHARGE_DETECT */ + GPIO_InitStruct.Pin = GPIO_PIN_4; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* PA4 is BAT_VOLTAGE */ + + /* Turn on the 3V3 regulator */ + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + GPIO_InitStruct.Pin = GPIO_PIN_0; + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); + HAL_GPIO_WritePin(GPIOH, GPIO_InitStruct.Pin, GPIO_PIN_SET); +} + +void board_init(void) { + // enable the debugger while sleeping. Todo move somewhere more central (kind of generally useful in a debug build) + SET_BIT(DBGMCU->CR, DBGMCU_CR_DBG_SLEEP); + + // Set tick interrupt priority, default HAL value is intentionally invalid + // Without this, USB does not function. + HAL_InitTick((1UL << __NVIC_PRIO_BITS) - 1UL); + + __HAL_RCC_GPIOA_CLK_ENABLE(); + GPIO_InitTypeDef GPIO_InitStruct; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + GPIO_InitStruct.Pin = GPIO_PIN_8; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); + HAL_Delay(50); + HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); +} + +void reset_board(void) { + initialize_discharge_pin(); +} + +// Use the MP_WEAK supervisor/shared/board.c versions of routines not defined here. diff --git a/ports/stm/boards/blues_cygnet/board.h b/ports/stm/boards/blues_cygnet/board.h new file mode 100644 index 00000000000..ce199359ba4 --- /dev/null +++ b/ports/stm/boards/blues_cygnet/board.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/digitalio/DigitalInOut.h" + +extern digitalio_digitalinout_obj_t power_pin; +extern digitalio_digitalinout_obj_t discharge_pin; diff --git a/ports/stm/boards/blues_cygnet/mpconfigboard.h b/ports/stm/boards/blues_cygnet/mpconfigboard.h new file mode 100644 index 00000000000..f3b1fcc2eb7 --- /dev/null +++ b/ports/stm/boards/blues_cygnet/mpconfigboard.h @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Blues Wireless Contributors. +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "Cygnet" +#define MICROPY_HW_MCU_NAME "STM32L433CCT6" + +#define MICROPY_PY_SYS_PLATFORM MICROPY_HW_BOARD_NAME + +#define STM32L433XX +#define BOARD_CYGNET + +#define LSE_VALUE ((uint32_t)32768) +#define BOARD_HAS_LOW_SPEED_CRYSTAL (1) +#define BOARD_HAS_HIGH_SPEED_CRYSTAL (0) + +// Increase drive strength of 32kHz external crystal, in line with calculations specified in ST AN2867 sections 3.3, 3.4, and STM32L4 datasheet DS12023 Table 58. LSE oscillator characteristics. +// The drive strength RCC_LSEDRIVE_LOW is marginal for the 32kHz crystal oscillator stability, and RCC_LSEDRIVE_MEDIUMLOW meets the calculated drive strength with a small margin for parasitic capacitance. +#define BOARD_LSE_DRIVE_LEVEL RCC_LSEDRIVE_MEDIUMLOW + +// Bootloader only +#ifdef UF2_BOOTLOADER_ENABLED + #define BOARD_VTOR_DEFER (1) // Leave VTOR relocation to bootloader +#endif + +#define BOARD_NO_VBUS_SENSE (1) +#define BOARD_NO_USB_OTG_ID_SENSE (1) + +#define DEFAULT_I2C_BUS_SCL (&pin_PB06) +#define DEFAULT_I2C_BUS_SDA (&pin_PB07) + +#define DEFAULT_SPI_BUS_SS (&pin_PB08) +#define DEFAULT_SPI_BUS_SCK (&pin_PA05) +#define DEFAULT_SPI_BUS_MOSI (&pin_PB05) +#define DEFAULT_SPI_BUS_MISO (&pin_PB06) + +#define DEFAULT_UART_BUS_RX (&pin_PA10) +#define DEFAULT_UART_BUS_TX (&pin_PA09) + +#define CYGNET_DISCHARGE_3V3 (&pin_PH01) +#define CYGNET_ENABLE_3V3 (&pin_PH00) diff --git a/ports/stm/boards/blues_cygnet/mpconfigboard.mk b/ports/stm/boards/blues_cygnet/mpconfigboard.mk new file mode 100644 index 00000000000..48e8241c7a6 --- /dev/null +++ b/ports/stm/boards/blues_cygnet/mpconfigboard.mk @@ -0,0 +1,105 @@ +USB_VID = 0x30A4 +USB_PID = 0x03 +USB_PRODUCT = "Cygnet" +USB_MANUFACTURER = "Blues Inc." + +MCU_SERIES = L4 +MCU_VARIANT = STM32L433xx +MCU_PACKAGE = LQFP48 + +LD_COMMON = boards/common_default.ld +LD_DEFAULT = boards/STM32L433_default.ld +UF2_OFFSET = 0x8000000 +UF2_BOOTLOADER ?= 0 +CIRCUITPY_BUILD_EXTENSIONS = bin + +INTERNAL_FLASH_FILESYSTEM = 1 +LONGINT_IMPL = NONE +CIRCUITPY_FULL_BUILD = 0 + +CIRCUITPY_AESIO = 0 +CIRCUITPY_ALARM = 0 +CIRCUITPY_ANALOGIO = 1 +CIRCUITPY_ATEXIT = 0 +CIRCUITPY_AUDIOBUSIO = 0 +CIRCUITPY_AUDIOBUSIO_I2SOUT = 0 +CIRCUITPY_AUDIOBUSIO_PDMIN = 0 +CIRCUITPY_AUDIOMIXER = 0 +CIRCUITPY_AUDIOMP3 = 0 +CIRCUITPY_AUDIOPWMIO = 0 +CIRCUITPY_BITBANGIO = 1 +CIRCUITPY_BLEIO = 0 +CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_BINASCII = 0 +CIRCUITPY_BITMAPFILTER = 0 +CIRCUITPY_BITMAPTOOLS = 0 +CIRCUITPY_BUILTINS_POW3 = 0 +CIRCUITPY_BUSDEVICE = 0 +CIRCUITPY_BUSIO = 1 +CIRCUITPY_CANIO = 0 +CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE = 1 +CIRCUITPY_COUNTIO = 0 +CIRCUITPY_DIGITALIO = 1 +CIRCUITPY_DISPLAYIO = 0 +CIRCUITPY_ENABLE_MPY_NATIVE = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 +CIRCUITPY_FREQUENCYIO = 0 +CIRCUITPY_FUTURE= 0 +CIRCUITPY_GETPASS = 0 +CIRCUITPY_GIFIO = 0 +CIRCUITPY_I2CTARGET = 0 +CIRCUITPY_JSON = 0 +CIRCUITPY_KEYPAD = 0 +CIRCUITPY_KEYPAD_DEMUX = 0 +CIRCUITPY_LTO = 1 +CIRCUITPY_MICROCONTROLLER = 1 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_NEOPIXEL_WRITE = 0 +CIRCUITPY_NVM = 0 +CIRCUITPY_ONEWIREIO = 0 +CIRCUITPY_OS = 1 +CIRCUITPY_PIXELBUF = 0 +CIRCUITPY_PIXELMAP = 0 +CIRCUITPY_PULSEIO = 1 +CIRCUITPY_PWMIO = 1 +CIRCUITPY_RANDOM = 0 +CIRCUITPY_RAINBOWIO = 0 +CIRCUITPY_RE = 0 +CIRCUITPY_REQUIRE_I2C_PULLUPS = 0 +CIRCUITPY_ROTARYIO_SOFTENCODER = 1 +CIRCUITPY_RGBMATRIX = 0 +CIRCUITPY_RTC = 0 +CIRCUITPY_SAFEMODE_PY = 0 +CIRCUITPY_SDCARDIO = 0 +CIRCUITPY_STATUS_BAR= 0 +CIRCUITPY_STORAGE = 1 +CIRCUITPY_SUPERVISOR = 1 +CIRCUITPY_SYNTHIO = 0 +CIRCUITPY_TERMINALIO = 0 +CIRCUITPY_TOUCHIO = 0 +CIRCUITPY_TOUCHIO_USE_NATIVE = 1 +CIRCUITPY_TRACEBACK = 0 +CIRCUITPY_ULAB = 0 +CIRCUITPY_USB_CDC = 1 +CIRCUITPY_USB_HID = 0 +CIRCUITPY_USB_IDENTIFICATION = 1 +CIRCUITPY_USB_MIDI = 0 +CIRCUITPY_USB_MIDI_ENABLED_DEFAULT= 0 +CIRCUITPY_USB_MSC = 1 +CIRCUITPY_USB_VENDOR = 0 +CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS= 0 +CIRCUITPY_VECTORIO = 0 +CIRCUITPY_ZLIB = 0 + +MICROPY_PY_ASYNC_AWAIT = 0 + +RELEASE_NEEDS_CLEAN_BUILD = 0 + +SUPEROPT_GC = 0 +SUPEROPT_VM = 0 + +CIRCUITPY_LTO_PARTITION = one + +OPTIMIZATION_FLAGS = -Os + +CFLAGS_BOARD = -fweb -frename-registers diff --git a/ports/stm/boards/blues_cygnet/pins.c b/ports/stm/boards/blues_cygnet/pins.c new file mode 100644 index 00000000000..f644160e4fd --- /dev/null +++ b/ports/stm/boards/blues_cygnet/pins.c @@ -0,0 +1,52 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// #include "py/objtuple.h" +#include "shared-bindings/board/__init__.h" +#include "board.h" + +// Core Feather Pins +static const mp_rom_map_elem_t board_module_globals_table[] = { + CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + + { MP_ROM_QSTR(MP_QSTR_ENABLE_3V3), &power_pin }, + { MP_ROM_QSTR(MP_QSTR_DISCHARGE_3V3), &discharge_pin }, + + { MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PA07) }, + + { MP_ROM_QSTR(MP_QSTR_VOLTAGE_MONITOR), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_BUTTON_USR), MP_ROM_PTR(&pin_PC13) }, + + { MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB15) }, + + { MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB04) }, // ADC, PWM, DAC2 output also + + { MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_PB07) }, // PWM + { MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_PB06) }, // PWM + + { MP_ROM_QSTR(MP_QSTR_SS), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_PA13) }, + { MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_PB05) }, + + { MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_PA09) }, // ADC, PWM + { MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_PA10) }, // PWM + + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) }, +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm/boards/common_tcm.ld b/ports/stm/boards/common_tcm.ld index d7be64d6679..6301dbf315b 100644 --- a/ports/stm/boards/common_tcm.ld +++ b/ports/stm/boards/common_tcm.ld @@ -134,6 +134,16 @@ SECTIONS } > DTCM _ld_stack_top = ORIGIN(DTCM) + LENGTH(DTCM); + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } >FLASH_FIRMWARE + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >FLASH_FIRMWARE .ARM.attributes 0 : { *(.ARM.attributes) } } diff --git a/ports/stm/boards/daisy_seed_with_sdram/board.c b/ports/stm/boards/daisy_seed_with_sdram/board.c new file mode 100644 index 00000000000..f135bcbc2e0 --- /dev/null +++ b/ports/stm/boards/daisy_seed_with_sdram/board.c @@ -0,0 +1,60 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT +#include STM32_HAL_H + +#include "supervisor/board.h" +#include "supervisor/stm.h" +#include "sdram.h" + + +/** SDRAM banks configuration. */ +static const struct stm32_sdram_bank_config bank_config[] = { + { .init = { + .SDBank = FMC_SDRAM_BANK1, + .ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_9, + .RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_13, + .MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_32, + .InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4, + .CASLatency = FMC_SDRAM_CAS_LATENCY_3, + .WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE, + .SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2, + .ReadBurst = FMC_SDRAM_RBURST_ENABLE, + .ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0 + }, + .timing = { + .LoadToActiveDelay = 2, + .ExitSelfRefreshDelay = 8, + .SelfRefreshTime = 5, + .RowCycleDelay = 6, + .WriteRecoveryTime = 3, + .RPDelay = 2, + .RCDDelay = 2 + }} +}; + +/* SDRAM configuration. */ +static const struct stm32_sdram_config config = { + .sdram = FMC_SDRAM_DEVICE, + .power_up_delay = 100, + .num_auto_refresh = 8, + .mode_register = SDRAM_MODEREG_BURST_LENGTH_4 | + SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | + SDRAM_MODEREG_CAS_LATENCY_3 | + SDRAM_MODEREG_WRITEBURST_MODE_SINGLE, + /* Set the device refresh rate based on the RM0433 STM reference manual + refresh_rate = [(SDRAM self refresh time / number of rows) x SDRAM CLK] – 20 + = [(64ms/8192) * 100MHz] - 20 = 781.25 - 20 + */ + .refresh_rate = (64 * 100000 / 8192 - 20), + .banks = bank_config, + .banks_len = 1, +}; + +void board_init(void) { + sdram_init(&config); +// sdram_test(true); + stm_add_sdram_to_heap(); +} diff --git a/ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.h b/ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.h new file mode 100644 index 00000000000..4951072d910 --- /dev/null +++ b/ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.h @@ -0,0 +1,40 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +// Micropython setup + +#define MICROPY_HW_BOARD_NAME "DAISY_SEED" +#define MICROPY_HW_MCU_NAME "STM32H750xx" + +#define MICROPY_HW_LED_STATUS (&pin_PC07) + +// H7 and F7 MPU definitions +#define CPY_FLASH_REGION_SIZE ARM_MPU_REGION_SIZE_8MB +#define CPY_ITCM_REGION_SIZE ARM_MPU_REGION_SIZE_64KB +#define CPY_DTCM_REGION_SIZE ARM_MPU_REGION_SIZE_128KB +#define CPY_SRAM_REGION_SIZE ARM_MPU_REGION_SIZE_512KB +#define CPY_SRAM_SUBMASK 0x00 +#define CPY_SRAM_START_ADDR 0x24000000 + +#define HSE_VALUE ((uint32_t)16000000) +#define BOARD_HSE_SOURCE (RCC_HSE_ON) // use external oscillator +#define BOARD_HAS_LOW_SPEED_CRYSTAL (0) + +#define CIRCUITPY_CONSOLE_UART_TX (&pin_PB09) +#define CIRCUITPY_CONSOLE_UART_RX (&pin_PB08) + +// USB +#define BOARD_NO_USB_OTG_ID_SENSE (1) + +// for RNG not audio +#define CPY_CLK_USB_USES_AUDIOPLL (1) + +// SDRAM and MPU region + +#define CIRCUITPY_HW_SDRAM_SIZE (64 * 1024 * 1024) // 64 MByte + +#define CPY_SDRAM_REGION MPU_REGION_NUMBER10 +#define CPY_SDRAM_REGION_SIZE MPU_REGION_SIZE_64MB diff --git a/ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.mk b/ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.mk new file mode 100644 index 00000000000..a43c4ed177b --- /dev/null +++ b/ports/stm/boards/daisy_seed_with_sdram/mpconfigboard.mk @@ -0,0 +1,18 @@ +USB_VID = 0x0483 +USB_PID = 0x5740 +USB_PRODUCT = "Daisy Seed" +USB_MANUFACTURER = "STMicroelectronics" + +# Small FS created on half of the internal flash -- other half is reserved for the H750 bootloader +INTERNAL_FLASH_FILESYSTEM = 1 + +MCU_SERIES = H7 +MCU_VARIANT = STM32H750xx +MCU_PACKAGE = UFBGA176 + +LD_COMMON = boards/common_tcm.ld +LD_FILE = boards/STM32H750.ld + +CIRCUITPY_SDIOIO = 1 +CIRCUITPY_PWMIO = 1 +CIRCUITPY_AUDIOPWMIO = 1 diff --git a/ports/stm/boards/daisy_seed_with_sdram/pins.c b/ports/stm/boards/daisy_seed_with_sdram/pins.c new file mode 100644 index 00000000000..b8f8f05b901 --- /dev/null +++ b/ports/stm/boards/daisy_seed_with_sdram/pins.c @@ -0,0 +1,61 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/board/__init__.h" + +// See pinout on Daisy Seed product page +// https://electro-smith.com/products/daisy-seed?variant=45234245108004 +static const mp_rom_map_elem_t board_module_globals_table[] = { + {MP_ROM_QSTR(MP_QSTR_LED), MP_ROM_PTR(&pin_PC07)}, + {MP_ROM_QSTR(MP_QSTR_BOOT), MP_ROM_PTR(&pin_PG03)}, + {MP_ROM_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_PB12)}, + {MP_ROM_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_PC11)}, + {MP_ROM_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_PC10)}, + {MP_ROM_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_PC09)}, + {MP_ROM_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_PC08)}, + {MP_ROM_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_PD02)}, + {MP_ROM_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_PC12)}, + {MP_ROM_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_PG10)}, + {MP_ROM_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_PG11)}, + {MP_ROM_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_PB04)}, + {MP_ROM_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_PB05)}, + {MP_ROM_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_PB08)}, + {MP_ROM_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_PB09)}, + {MP_ROM_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_PB06)}, + {MP_ROM_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_PB07)}, + + {MP_ROM_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_PC00)}, + {MP_ROM_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_PC00)}, + {MP_ROM_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_PA03)}, + {MP_ROM_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_PA03)}, + {MP_ROM_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_PB01)}, + {MP_ROM_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_PB01)}, + {MP_ROM_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_PA07)}, + {MP_ROM_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_PA07)}, + {MP_ROM_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_PA06)}, + {MP_ROM_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_PA06)}, + {MP_ROM_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_PC01)}, + {MP_ROM_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_PC01)}, + {MP_ROM_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_PC04)}, + {MP_ROM_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_PC04)}, + {MP_ROM_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_PA05)}, + {MP_ROM_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_PA05)}, + {MP_ROM_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_PA04)}, + {MP_ROM_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_PA04)}, + {MP_ROM_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_PA01)}, + {MP_ROM_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_PA01)}, + {MP_ROM_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_PA00)}, + {MP_ROM_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_PA00)}, + {MP_ROM_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_PD11)}, + {MP_ROM_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_PG09)}, + {MP_ROM_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_PA02)}, + {MP_ROM_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_PA02)}, + {MP_ROM_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_PB14)}, + {MP_ROM_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_PB15)}, + +}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); diff --git a/ports/stm/boards/espruino_pico/README.md b/ports/stm/boards/espruino_pico/README.md index 86df1ad32a3..d930e9aeca3 100644 --- a/ports/stm/boards/espruino_pico/README.md +++ b/ports/stm/boards/espruino_pico/README.md @@ -12,4 +12,4 @@ The Espruino Pico is normally updated via a bootloader activated by the Espruino - Restart the board. -To reinstall Espruino, follow the same steps with the latest Espruino Pico binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to re-use the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. +To reinstall Espruino, follow the same steps with the latest Espruino Pico binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to reuse the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. diff --git a/ports/stm/boards/espruino_wifi/README.MD b/ports/stm/boards/espruino_wifi/README.MD index cc78811f1c7..cebe99bf6d1 100644 --- a/ports/stm/boards/espruino_wifi/README.MD +++ b/ports/stm/boards/espruino_wifi/README.MD @@ -12,4 +12,4 @@ The Espruino Wifi is normally updated via a bootloader activated by the Espruino - Restart the board. -To reinstall Espruino, follow the same steps with the latest Espruino Wifi binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to re-use the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. +To reinstall Espruino, follow the same steps with the latest Espruino Wifi binary from espruino.com/binaries. This will reinstall the usual Espruino bootloader. You must un-short the BOOT0/BTN jumper to reuse the original Espruino Bootloader again. If you used a Pencil mark then you may need to use cleaning fluid and a small brush to totally clear out the graphite. diff --git a/ports/stm/boards/meowbit_v121/board.c b/ports/stm/boards/meowbit_v121/board.c index 181f433a372..c3c745f64a1 100644 --- a/ports/stm/boards/meowbit_v121/board.c +++ b/ports/stm/boards/meowbit_v121/board.c @@ -55,9 +55,9 @@ void board_init(void) { busio_spi_obj_t *internal_spi = &supervisor_flash_spi_bus; common_hal_fourwire_fourwire_construct(bus, internal_spi, - &pin_PA08, // Command or data - &pin_PB12, // Chip select - &pin_PB10, // Reset + MP_OBJ_FROM_PTR(&pin_PA08), // Command or data + MP_OBJ_FROM_PTR(&pin_PB12), // Chip select + MP_OBJ_FROM_PTR(&pin_PB10), // Reset 24000000, // Baudrate 0, // Polarity 0); // Phase diff --git a/ports/stm/boards/meowbit_v121/mpconfigboard.mk b/ports/stm/boards/meowbit_v121/mpconfigboard.mk index 1dfda9a1759..271c4cd775c 100644 --- a/ports/stm/boards/meowbit_v121/mpconfigboard.mk +++ b/ports/stm/boards/meowbit_v121/mpconfigboard.mk @@ -23,12 +23,23 @@ LD_FILE = boards/STM32F401xe_boot.ld # LD_FILE = boards/STM32F401xe_fs.ld CIRCUITPY_AESIO = 0 +CIRCUITPY_CODEOP = 0 CIRCUITPY_BITMAPFILTER = 0 CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_BLEIO_HCI = 0 -CIRCUITPY_GIFIO = 0 +CIRCUITPY_EPAPERDISPLAY = 0 +CIRCUITPY_FRAMEBUFFERIO = 0 +CIRCUITPY_I2CDISPLAYBUS = 0 +CIRCUITPY_KEYPAD_DEMUX = 0 +CIRCUITPY_MSGPACK = 0 +CIRCUITPY_PIXELMAP = 0 +CIRCUITPY_SHARPDISPLAY = 0 +CIRCUITPY_TILEPALETTEMAPPER = 0 CIRCUITPY_ULAB = 0 -CIRCUITPY_STAGE = 1 CIRCUITPY_ZLIB = 0 +CIRCUITPY_STAGE = 1 + +CIRCUITPY_DIGITALINOUT_PROTOCOL = 0 + FROZEN_MPY_DIRS += $(TOP)/frozen/circuitpython-stage/meowbit diff --git a/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk index d1df685c676..31c2b7e2874 100644 --- a/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk +++ b/ports/stm/boards/sparkfun_stm32f405_micromod/mpconfigboard.mk @@ -1,5 +1,5 @@ USB_VID = 0X1B4F -USB_PID = 0x0027 +USB_PID = 0x0029 USB_PRODUCT = "SparkFun STM32 MicroMod Processor" USB_MANUFACTURER = "SparkFun Electronics" diff --git a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk index 64be6f4f142..c46a270df65 100644 --- a/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk +++ b/ports/stm/boards/stm32f411ce_blackpill_with_flash/mpconfigboard.mk @@ -9,6 +9,7 @@ EXTERNAL_FLASH_DEVICES = GD25Q16C,W25Q16JVxQ,W25Q64FV,W25Q32JVxQ,W25Q64JVxQ LONGINT_IMPL = MPZ INTERNAL_FLASH_FILESYSTEM = 0 +OPTIMIZATION_FLAGS = -Os MCU_SERIES = F4 MCU_VARIANT = STM32F411xE diff --git a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk index e17fa4d1b74..98d13f592ff 100644 --- a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk +++ b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk @@ -9,14 +9,18 @@ MCU_SERIES = F4 MCU_VARIANT = STM32F411xE MCU_PACKAGE = LQFP100_f4 +OPTIMIZATION_FLAGS = -Os + LD_COMMON = boards/common_default.ld LD_FILE = boards/STM32F411_fs.ld # Too big for the flash +CIRCUITPY_AESIO = 0 CIRCUITPY_AUDIOCORE = 0 CIRCUITPY_AUDIOPWMIO = 0 CIRCUITPY_BITMAPFILTER = 0 CIRCUITPY_BITMAPTOOLS = 0 CIRCUITPY_BLEIO_HCI = 0 +CIRCUITPY_CODEOP = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_VECTORIO = 0 diff --git a/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.h b/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.h index e771532437f..b068b8e2d51 100644 --- a/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.h +++ b/ports/stm/boards/stm32f412zg_discovery/mpconfigboard.h @@ -9,7 +9,7 @@ // Micropython setup #define MICROPY_HW_BOARD_NAME "STM32F412G_DISCO" -#define MICROPY_HW_MCU_NAME "STM32F412xGS" +#define MICROPY_HW_MCU_NAME "STM32F412xG" #define FLASH_SIZE (0x100000) #define FLASH_PAGE_SIZE (0x4000) diff --git a/ports/stm/boards/swan_r5/mpconfigboard.mk b/ports/stm/boards/swan_r5/mpconfigboard.mk index ea4125e02b8..353f96cca78 100644 --- a/ports/stm/boards/swan_r5/mpconfigboard.mk +++ b/ports/stm/boards/swan_r5/mpconfigboard.mk @@ -24,7 +24,7 @@ CIRCUITPY_AUDIOBUSIO_I2SOUT = 0 CIRCUITPY_AUDIOBUSIO_PDMIN = 1 CIRCUITPY_AUDIOPWMIO = 1 CIRCUITPY_BITBANGIO = 1 -CIRCUITPY_BLEIO = 0 +CIRCUITPY_BLEIO_NATIVE = 0 CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_BUSDEVICE = 0 CIRCUITPY_BUSIO = 1 diff --git a/ports/stm/boards/swan_r5/tests/analog_output.py b/ports/stm/boards/swan_r5/tests/analog_output.py index 6af931e65d6..f2ef97dc2cf 100644 --- a/ports/stm/boards/swan_r5/tests/analog_output.py +++ b/ports/stm/boards/swan_r5/tests/analog_output.py @@ -31,7 +31,7 @@ def test_dac_digital(p_in, p_out): def test_dual(pair1, pair2): # verifies that the DACs can be set independently - print(f"Running pair test\n") + print("Running pair test\n") pin1_in = analogio.AnalogIn(pair1[0]) pin1_out = analogio.AnalogOut(pair1[1]) pin2_in = analogio.AnalogIn(pair2[0]) diff --git a/ports/stm/boards/swan_r5/tests/enable_3v3.py b/ports/stm/boards/swan_r5/tests/enable_3v3.py index c32bbc58b80..fecd05a3c5d 100644 --- a/ports/stm/boards/swan_r5/tests/enable_3v3.py +++ b/ports/stm/boards/swan_r5/tests/enable_3v3.py @@ -13,9 +13,9 @@ # Then the symbol "board.DISCHARGE_3V3" is defined assert board.DISCHARGE_3V3 is not None # And the symbol "board.DISABLE_DISCHARGING" is defined to be "True" -assert board.DISABLE_DISCHARGING is not None and board.DISABLE_DISCHARGING == True +assert board.DISABLE_DISCHARGING is not None and board.DISABLE_DISCHARGING # And the symbol "board.ENABLE_DISCHARGING" is defined to be "False" -assert board.ENABLE_DISCHARGING is not None and board.ENABLE_DISCHARGING == False +assert board.ENABLE_DISCHARGING is not None and not board.ENABLE_DISCHARGING # Scenario: Toggle ENBLE_3V3 # Given I have a LED connected between the 3V3 and GND pins diff --git a/ports/stm/boards/thunderpack_v11/mpconfigboard.mk b/ports/stm/boards/thunderpack_v11/mpconfigboard.mk index 4fede00dc07..0107bbb1c17 100644 --- a/ports/stm/boards/thunderpack_v11/mpconfigboard.mk +++ b/ports/stm/boards/thunderpack_v11/mpconfigboard.mk @@ -13,6 +13,8 @@ MCU_SERIES = F4 MCU_VARIANT = STM32F411xE MCU_PACKAGE = UFQFPN48 +OPTIMIZATION_FLAGS = -Os + LD_COMMON = boards/common_nvm.ld LD_FILE = boards/STM32F411_nvm.ld diff --git a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk index 276cf6d0110..353d0733e64 100644 --- a/ports/stm/boards/thunderpack_v12/mpconfigboard.mk +++ b/ports/stm/boards/thunderpack_v12/mpconfigboard.mk @@ -25,11 +25,7 @@ MCU_SERIES = F4 MCU_VARIANT = STM32F411xE MCU_PACKAGE = UFQFPN48 +OPTIMIZATION_FLAGS = -Os + LD_COMMON = boards/common_nvm.ld LD_FILE = boards/STM32F411_nvm_nofs.ld - -# Disable TERMINALIO on translations with missing characters. -ifneq (,$(filter $(TRANSLATION),ja ko ru)) -CIRCUITPY_TERMINALIO = 0 -RELEASE_NEEDS_CLEAN_BUILD = $(CIRCUITPY_DISPLAYIO) -endif diff --git a/ports/stm/common-hal/alarm/__init__.c b/ports/stm/common-hal/alarm/__init__.c index 3d6c4466882..4cdf01b7f25 100644 --- a/ports/stm/common-hal/alarm/__init__.c +++ b/ports/stm/common-hal/alarm/__init__.c @@ -129,13 +129,10 @@ mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const mp_obj } void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios) { - if (n_dios > 0) { - mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_preserve_dios); - } _setup_sleep_alarms(true, n_alarms, alarms); } -void NORETURN common_hal_alarm_enter_deep_sleep(void) { +void MP_NORETURN common_hal_alarm_enter_deep_sleep(void) { alarm_set_wakeup_reason(STM_WAKEUP_UNDEF); alarm_pin_pinalarm_prepare_for_deep_sleep(); alarm_time_timealarm_prepare_for_deep_sleep(); diff --git a/ports/stm/common-hal/analogio/AnalogOut.h b/ports/stm/common-hal/analogio/AnalogOut.h index 6a8fc2720bf..33c8abc21f8 100644 --- a/ports/stm/common-hal/analogio/AnalogOut.h +++ b/ports/stm/common-hal/analogio/AnalogOut.h @@ -28,3 +28,9 @@ typedef struct { } analogio_analogout_obj_t; void analogout_reset(void); + +// Shared DAC peripheral handle (defined in AnalogOut.c). +// AudioOut reuses this handle for DMA-triggered DAC operation on channel 1. +#if HAS_DAC +extern DAC_HandleTypeDef handle; +#endif diff --git a/ports/stm/common-hal/audioio/AudioOut.c b/ports/stm/common-hal/audioio/AudioOut.c new file mode 100644 index 00000000000..e5dd620521c --- /dev/null +++ b/ports/stm/common-hal/audioio/AudioOut.c @@ -0,0 +1,782 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// DAC-based audio output for STM32F405 / STM32F407. +// +// Architecture: +// TIM6 (basic timer) generates an update event at the sample rate. +// DAC_CHANNEL_1 (PA04) is configured with DAC_TRIGGER_T6_TRGO so each +// TIM6 update latches the next sample from the DMA FIFO. +// DMA1 Stream5 Channel7 operates in circular mode, feeding 16-bit samples +// from a double-buffer. Stereo additionally drives DAC_CHANNEL_2 (PA05) +// via DMA1 Stream6 Channel7, sharing the same TIM6 trigger. +// The DMA half-complete and complete callbacks queue a background_callback +// to refill the idle half from the audio sample source. +// +// The shared DAC handle (declared in AnalogOut.c) is reused here so both +// modules share state consistently and avoid double-init conflicts. Pin +// claims (common_hal_mcu_pin_claim) act as the inter-module mutex: a second +// AudioOut, or an AnalogOut on the same pin, fails at the claim step. + +#include + +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "common-hal/audioio/AudioOut.h" +#include "shared-bindings/audioio/AudioOut.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/audiocore/__init__.h" +#include "supervisor/background_callback.h" + +#include STM32_HAL_H + +// Shared DAC handle declared in common-hal/analogio/AnalogOut.h. +// AudioOut reconfigures channel 1 (and 2 for stereo) for DMA-triggered +// operation and restores the no-trigger config on deinit so AnalogOut can +// resume use of the channel afterwards. +#include "common-hal/analogio/AnalogOut.h" + +// Highest sample rate accepted by play(). 1 MHz mirrors atmel-samd's SAMD51 +// limit and is comfortably above any reasonable audio rate; the real hardware +// ceiling is TIM6_CLK / 2 (~42 MHz on F405) but rates that high would just +// underrun the DMA refill path. +#define AUDIOOUT_MAX_SAMPLE_RATE 1000000u + +// TIM6 handle: only one instance ever active, so file-scope is fine. +static TIM_HandleTypeDef tim6_handle; + +// Pointer to the currently active AudioOut object, used by IRQ handlers. +// Pin claims prevent two instances from existing simultaneously, but this +// pointer is also used to early-out IRQs after stop(). +static audioio_audioout_obj_t *active_audioout = NULL; + +// --------------------------------------------------------------------------- +// Helpers +// --------------------------------------------------------------------------- + +// Return the TIM6 input clock frequency in Hz. +// TIM6 sits on APB1. The clock is doubled when the APB1 prescaler != 1 +// (same logic as stm_peripherals_timer_get_source_freq in timers.c but +// applied directly to APB1 since TIM6 is not in mcu_tim_banks[]). +static uint32_t get_tim6_freq(void) { + uint32_t apb1 = HAL_RCC_GetPCLK1Freq(); + uint32_t ppre1 = (RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos; + #if defined(RCC_DCKCFGR_TIMPRE) + uint32_t timpre = RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE; + if (timpre == 0) { + return (ppre1 >= 0b100) ? apb1 * 2 : apb1; + } else { + return (ppre1 > 0b101) ? apb1 * 4 : HAL_RCC_GetHCLKFreq(); + } + #else + return (ppre1 >= 0b100) ? apb1 * 2 : apb1; + #endif +} + +// Gently ramp the given DAC channel output from from_12 to to_12 (both 12-bit, +// 0-4095) to avoid audible clicks. 64 steps × 100 µs/step = ~6.4 ms total; +// shrink the step count and clicks reappear on the F405 output stage. +static void dac_ramp_channel(uint32_t channel, uint32_t from_12, uint32_t to_12) { + if (from_12 == to_12) { + return; + } + int32_t delta = (int32_t)to_12 - (int32_t)from_12; + int32_t step = delta / 64; + if (step == 0) { + step = (delta > 0) ? 1 : -1; + } + int32_t v = (int32_t)from_12; + while (true) { + v += step; + if (step > 0 && v >= (int32_t)to_12) { + v = (int32_t)to_12; + } else if (step < 0 && v <= (int32_t)to_12) { + v = (int32_t)to_12; + } + HAL_DAC_SetValue(&handle, channel, DAC_ALIGN_12B_R, (uint16_t)v); + HAL_DAC_Start(&handle, channel); + mp_hal_delay_us(100); + if (v == (int32_t)to_12) { + break; + } + } +} + +static inline void dac_ramp(uint32_t from_12, uint32_t to_12) { + dac_ramp_channel(DAC_CHANNEL_1, from_12, to_12); +} + +// Convert a buffer of audio samples into 12-bit unsigned DAC values and write +// them into dest[]. Returns the number of DAC samples written; the caller is +// responsible for padding any remaining dest entries with the quiescent value. +// +// NOTE: ports/espressif/common-hal/audioio/AudioOut.c implements the same +// idea with a CONV_MATCH lookup table dispatching to per-format helpers in +// shared-module/audiocore — a more general-purpose pattern. If a future +// refactor lifts a 12-bit DAC variant into shared-module/audiocore, both +// this driver and any other ARM-DAC port could share it. +// +// src - raw sample bytes from audiosample_get_buffer +// src_len - byte length of src +// dest - output array of 12-bit DAC values (uint16_t) +// dest_count - capacity of dest in samples +// bytes_per_sample - 1 or 2 +// samples_signed - true if source samples are signed +// channel_count - 1 (mono) or 2 (stereo) +// channel_offset - 0 for left/mono, 1 for right channel of a stereo stream +static uint32_t convert_to_dac12( + const uint8_t *src, uint32_t src_len, + uint16_t *dest, uint32_t dest_count, + uint8_t bytes_per_sample, bool samples_signed, + uint8_t channel_count, uint8_t channel_offset) { + + // src_stride: bytes between consecutive samples of the same channel + uint32_t src_stride = (uint32_t)bytes_per_sample * channel_count; + // src_offset: byte offset to the desired channel within each frame + uint32_t src_offset = (uint32_t)bytes_per_sample * channel_offset; + uint32_t src_frames = src_len / src_stride; + uint32_t frames = (src_frames < dest_count) ? src_frames : dest_count; + + if (bytes_per_sample == 1) { + for (uint32_t i = 0; i < frames; i++) { + uint8_t u8 = src[i * src_stride + src_offset]; + int32_t s = samples_signed + ? (int32_t)(int8_t)u8 + : (int32_t)u8 - 128; + dest[i] = (uint16_t)((s + 128) & 0xFF) << 4; + } + } else { + for (uint32_t i = 0; i < frames; i++) { + uint16_t u16; + memcpy(&u16, src + i * src_stride + src_offset, 2); + int32_t s = samples_signed + ? (int32_t)(int16_t)u16 + : (int32_t)u16 - 0x8000; + dest[i] = (uint16_t)((s + 0x8000) & 0xFFFF) >> 4; + } + } + return frames; +} + +// Pad [filled, AUDIOOUT_DMA_HALF_SAMPLES) of dest_l (and dest_r if non-NULL) +// with the quiescent value. Used at end-of-stream and on errors so the DAC +// returns smoothly to its resting voltage. +static void pad_quiescent(uint16_t *dest_l, uint16_t *dest_r, + uint32_t filled, uint16_t quiescent_12) { + for (uint32_t i = filled; i < AUDIOOUT_DMA_HALF_SAMPLES; i++) { + dest_l[i] = quiescent_12; + if (dest_r) { + dest_r[i] = quiescent_12; + } + } +} + +// Load one half of the DMA circular buffer from the audio sample source. +// half: 0 = lower half (indices 0..HALF-1), 1 = upper half (HALF..END-1). +// +// Tracks position within the source buffer (src_ptr / src_remaining_len) +// across calls so that large source buffers (e.g. a 1024-sample RawSample) +// are consumed incrementally rather than re-reading from the start each time. +static void load_dma_buffer_half(audioio_audioout_obj_t *self, uint8_t half) { + uint16_t *dest_l = self->dma_buffer + ((uint32_t)half * AUDIOOUT_DMA_HALF_SAMPLES); + uint16_t *dest_r = self->dma_buffer_r + ? self->dma_buffer_r + ((uint32_t)half * AUDIOOUT_DMA_HALF_SAMPLES) + : NULL; + uint16_t quiescent_12 = self->quiescent_value >> 4; + uint32_t src_stride = (uint32_t)self->bytes_per_sample * self->channel_count; + uint32_t filled = 0; + + while (filled < AUDIOOUT_DMA_HALF_SAMPLES) { + // Fetch new source data when the previous buffer is exhausted. + if (self->src_remaining_len == 0) { + // Handle end-of-stream from previous get_buffer call. + if (self->src_done) { + if (self->loop) { + audiosample_reset_buffer(self->sample, + self->channel_count == 1, 0); + self->src_done = false; + } else { + pad_quiescent(dest_l, dest_r, filled, quiescent_12); + self->stopping = true; + return; + } + } + + uint8_t *buf; + uint32_t len; + audioio_get_buffer_result_t result = + audiosample_get_buffer(self->sample, + self->channel_count == 1, 0, &buf, &len); + + if (result == GET_BUFFER_ERROR) { + pad_quiescent(dest_l, dest_r, filled, quiescent_12); + self->stopping = true; + return; + } + + self->src_ptr = buf; + self->src_remaining_len = len; + self->src_done = (result == GET_BUFFER_DONE); + } + + uint32_t written = convert_to_dac12( + self->src_ptr, self->src_remaining_len, + dest_l + filled, AUDIOOUT_DMA_HALF_SAMPLES - filled, + self->bytes_per_sample, self->samples_signed, + self->channel_count, 0); + + if (dest_r) { + uint8_t r_offset = (self->channel_count >= 2) ? 1 : 0; + convert_to_dac12( + self->src_ptr, self->src_remaining_len, + dest_r + filled, AUDIOOUT_DMA_HALF_SAMPLES - filled, + self->bytes_per_sample, self->samples_signed, + self->channel_count, r_offset); + } + + if (written == 0) { + // src had fewer than src_stride bytes left (e.g. a corrupt WAV + // returned an odd byte count for 16-bit data). Drop the partial + // frame so the next loop iteration calls get_buffer for fresh, + // aligned data — without this the loop spins forever because + // neither filled nor src_remaining_len would advance. + self->src_remaining_len = 0; + continue; + } + + // Advance source position by the amount consumed. + uint32_t bytes_consumed = written * src_stride; + self->src_ptr += bytes_consumed; + self->src_remaining_len -= bytes_consumed; + filled += written; + } +} + +// Background callback: called from the main loop after a DMA half/full event. +static void audioout_fill_callback(void *arg) { + audioio_audioout_obj_t *self = (audioio_audioout_obj_t *)arg; + if (!self || active_audioout != self) { + return; + } + if (self->stopping) { + common_hal_audioio_audioout_stop(self); + return; + } + uint8_t mask; + __disable_irq(); + mask = self->halves_to_fill; + self->halves_to_fill = 0; + __enable_irq(); + if (mask & 0x1) { + load_dma_buffer_half(self, 0); + } + if (mask & 0x2) { + load_dma_buffer_half(self, 1); + } +} + +// --------------------------------------------------------------------------- +// IRQ handlers +// +// DMA1 Stream5/6 are claimed exclusively for DAC use here. If a future port +// change wires another peripheral onto either stream the weak-symbol override +// below will collide silently — add a build-time assertion in that file. +// --------------------------------------------------------------------------- + +void DMA1_Stream5_IRQHandler(void) { + if (active_audioout) { + HAL_DMA_IRQHandler(&active_audioout->dma_handle_l); + } +} + +void DMA1_Stream6_IRQHandler(void) { + if (active_audioout && active_audioout->dma_buffer_r) { + HAL_DMA_IRQHandler(&active_audioout->dma_handle_r); + } +} + +// HAL weak-symbol overrides: called from HAL_DMA_IRQHandler context. +// +// Only the Ch1 (left) callbacks are overridden. The Stream6 IRQ for the +// right channel still calls HAL_DACEx_ConvHalfCpltCallbackCh2 / +// HAL_DACEx_ConvCpltCallbackCh2 (the default empty weak implementations) — +// that is intentional. Both DMA streams are clocked by the same TIM6 trigger +// and started together, so their NDTR counters stay in lock-step. Refilling +// from the left-channel IRQ alone is sufficient and avoids redundant work. + +void HAL_DAC_ConvHalfCpltCallbackCh1(DAC_HandleTypeDef *hdac) { + if (active_audioout && !active_audioout->paused) { + active_audioout->halves_to_fill |= 0x1; + background_callback_add(&active_audioout->callback, + audioout_fill_callback, active_audioout); + } +} + +void HAL_DAC_ConvCpltCallbackCh1(DAC_HandleTypeDef *hdac) { + if (active_audioout && !active_audioout->paused) { + active_audioout->halves_to_fill |= 0x2; + background_callback_add(&active_audioout->callback, + audioout_fill_callback, active_audioout); + } +} + +// --------------------------------------------------------------------------- +// Public API +// --------------------------------------------------------------------------- + +void common_hal_audioio_audioout_construct(audioio_audioout_obj_t *self, + const mcu_pin_obj_t *left_channel, const mcu_pin_obj_t *right_channel, + uint16_t quiescent_value) { + + #if !HAS_DAC + mp_raise_ValueError(MP_ERROR_TEXT("No DAC on chip")); + #else + + // Only PA04 (DAC_CH1) is supported as left channel. + if (left_channel != &pin_PA04) { + raise_ValueError_invalid_pin_name(MP_QSTR_left_channel); + } + + // Right channel must be PA05 (DAC_CH2 / A1) if provided. + if (right_channel != NULL && right_channel != &pin_PA05) { + raise_ValueError_invalid_pin_name(MP_QSTR_right_channel); + } + + // Claim pins first. The pin-claim system is what serialises this driver + // against another AudioOut instance and against AnalogOut on the same + // pins — if either is already using PA04/PA05 the claim raises here, and + // because nothing else is configured yet, no cleanup is needed. + // + // NOTE: ports/atmel-samd/common-hal/audioio/AudioOut.c also claims pins + // first but L242 raises *after* claiming a timer and event channel + // without releasing them on the error path; worth a follow-up there. + common_hal_mcu_pin_claim(left_channel); + if (right_channel != NULL) { + common_hal_mcu_pin_claim(right_channel); + } + + self->left_channel = left_channel; + self->right_channel = right_channel; + self->quiescent_value = quiescent_value; + self->sample = MP_OBJ_NULL; + self->dma_buffer = NULL; + self->dma_buffer_r = NULL; + memset(&self->dma_handle_l, 0, sizeof(self->dma_handle_l)); + memset(&self->dma_handle_r, 0, sizeof(self->dma_handle_r)); + memset(&self->callback, 0, sizeof(self->callback)); + self->stopping = false; + self->paused = false; + self->playing = false; + + // Configure PA04 (and PA05 if stereo) for analog (DAC) mode. + GPIO_InitTypeDef gpio_init = {0}; + gpio_init.Pin = pin_mask(left_channel->number); + gpio_init.Mode = GPIO_MODE_ANALOG; + gpio_init.Pull = GPIO_NOPULL; + HAL_GPIO_Init(pin_port(left_channel->port), &gpio_init); + + if (right_channel != NULL) { + gpio_init.Pin = pin_mask(right_channel->number); + HAL_GPIO_Init(pin_port(right_channel->port), &gpio_init); + } + + // Initialise the shared DAC handle if it hasn't been set up yet + // (i.e. AnalogOut hasn't been used since last reset). __HAL_RCC_DAC_CLK_ENABLE + // is idempotent so calling it unconditionally would be safe too, but + // matching AnalogOut's check keeps the two modules in sync. + if (handle.Instance == NULL || handle.State == HAL_DAC_STATE_RESET) { + __HAL_RCC_DAC_CLK_ENABLE(); + handle.Instance = DAC; + if (HAL_DAC_Init(&handle) != HAL_OK) { + mp_raise_ValueError(MP_ERROR_TEXT("DAC Device Init Error")); + } + } + + // Configure DAC channel 1 with no trigger so the ramp below works + // immediately. play() switches the trigger to TIM6_TRGO. + DAC_ChannelConfTypeDef ch_cfg = {0}; + ch_cfg.DAC_Trigger = DAC_TRIGGER_NONE; + ch_cfg.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + if (HAL_DAC_ConfigChannel(&handle, &ch_cfg, DAC_CHANNEL_1) != HAL_OK) { + mp_raise_ValueError(MP_ERROR_TEXT("DAC Channel Init Error")); + } + + // Ramp DAC output up to quiescent value to prevent an audible pop. + HAL_DAC_SetValue(&handle, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0); + HAL_DAC_Start(&handle, DAC_CHANNEL_1); + dac_ramp(0, quiescent_value >> 4); + #endif +} + +bool common_hal_audioio_audioout_deinited(audioio_audioout_obj_t *self) { + return self->left_channel == NULL; +} + +void common_hal_audioio_audioout_deinit(audioio_audioout_obj_t *self) { + if (common_hal_audioio_audioout_deinited(self)) { + return; + } + + common_hal_audioio_audioout_stop(self); + + // Ramp DAC back to zero before disconnecting. + dac_ramp(self->quiescent_value >> 4, 0); + HAL_DAC_Stop(&handle, DAC_CHANNEL_1); + + // Restore channels to no-trigger mode so AnalogOut can use them again. + DAC_ChannelConfTypeDef ch_cfg = {0}; + ch_cfg.DAC_Trigger = DAC_TRIGGER_NONE; + ch_cfg.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + HAL_DAC_ConfigChannel(&handle, &ch_cfg, DAC_CHANNEL_1); + if (self->right_channel != NULL) { + HAL_DAC_Stop(&handle, DAC_CHANNEL_2); + HAL_DAC_ConfigChannel(&handle, &ch_cfg, DAC_CHANNEL_2); + reset_pin_number(self->right_channel->port, self->right_channel->number); + self->right_channel = NULL; + } + + // Release the left pin. Let AnalogOut manage DAC clock disable. + reset_pin_number(self->left_channel->port, self->left_channel->number); + self->left_channel = NULL; +} + +void common_hal_audioio_audioout_play(audioio_audioout_obj_t *self, + mp_obj_t sample, bool loop) { + // The shared-bindings layer guards every entry point with + // check_for_deinit, so a deinited self can't reach this function. + common_hal_audioio_audioout_stop(self); + + // Extract sample format metadata via the canonical accessors so the + // shared sample-protocol contract is honoured. + audiosample_base_t *base = audiosample_check(sample); + self->bytes_per_sample = audiosample_get_bits_per_sample(base) / 8; + self->samples_signed = base->samples_signed; + self->channel_count = audiosample_get_channel_count(base); + uint32_t sample_rate = audiosample_get_sample_rate(base); + mp_arg_validate_int_min(sample_rate, 1, MP_QSTR_sample_rate); + mp_arg_validate_int_max(sample_rate, AUDIOOUT_MAX_SAMPLE_RATE, MP_QSTR_sample_rate); + + self->sample = sample; + self->loop = loop; + self->stopping = false; + self->paused = false; + self->playing = false; + self->halves_to_fill = 0; + self->src_ptr = NULL; + self->src_remaining_len = 0; + self->src_done = false; + + // Allocate DMA circular buffer(s). m_malloc_without_collect avoids + // triggering a GC cycle while the DAC is mid-configure; m_malloc itself + // raises on failure so no null check is needed. + // + // NOTE: ports/atmel-samd uses plain m_malloc for its audio_dma scratch + // buffers — the same GC-during-fill risk applies and should be migrated + // to m_malloc_without_collect for symmetry with espressif and stm. + self->dma_buffer = (uint16_t *)m_malloc_without_collect( + AUDIOOUT_DMA_BUFFER_SAMPLES * sizeof(uint16_t)); + if (self->right_channel != NULL) { + self->dma_buffer_r = (uint16_t *)m_malloc_without_collect( + AUDIOOUT_DMA_BUFFER_SAMPLES * sizeof(uint16_t)); + } + + // Pre-fill both halves before starting DMA. single_channel_output is + // true when this AudioOut renders only one DAC channel; for stereo + // output we want the audiocore to deliver interleaved frames. + bool single_channel_output = (self->right_channel == NULL); + audiosample_reset_buffer(sample, single_channel_output, 0); + load_dma_buffer_half(self, 0); + load_dma_buffer_half(self, 1); + + // Ramp from quiescent to the first sample so the transition into + // DMA-driven output is glitch-free. The DAC is still in single-mode + // (DAC_TRIGGER_NONE) at this point, set up by construct() / stop(), + // so HAL_DAC_SetValue takes effect immediately. After the ramp the + // pin is sitting at exactly dma_buffer[0], which is also the first + // value the timer-triggered DMA will latch. + uint16_t quiescent_12 = self->quiescent_value >> 4; + dac_ramp_channel(DAC_CHANNEL_1, quiescent_12, self->dma_buffer[0]); + if (self->right_channel != NULL) { + // CH2 was not started in construct(), so it has been outputting + // its reset value (0). Ramp from there. + dac_ramp_channel(DAC_CHANNEL_2, 0, self->dma_buffer_r[0]); + } + + // --- TIM6 setup --- + // TIM6 is a basic timer on APB1. It is not managed by the common timer + // infrastructure (stm_peripherals_find_timer etc.) because it has no GPIO + // pins and is reserved for DAC use (mcu_tim_banks[5] == NULL). + __HAL_RCC_TIM6_CLK_ENABLE(); + + uint32_t tim6_clk = get_tim6_freq(); + // Round to nearest, not truncate, so the realised sample rate is the + // closest TIM6 division to the requested rate. + // NOTE: a sweep audit on atmel-samd (Circuit Playground Express) shows a + // constant -3.4 cent frequency bias across all tones, consistent with a + // truncating period calculation there. The same round-to-nearest fix + // would likely tighten frequency accuracy on that port too. + uint32_t period = (tim6_clk + sample_rate / 2) / sample_rate; + if (period < 2) { + period = 2; + } + period -= 1; + + tim6_handle.Instance = TIM6; + tim6_handle.Init.Prescaler = 0; + tim6_handle.Init.CounterMode = TIM_COUNTERMODE_UP; + tim6_handle.Init.Period = period; + tim6_handle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; + tim6_handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; + if (HAL_TIM_Base_Init(&tim6_handle) != HAL_OK) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_TIM6); + } + + // TRGO = Update event → triggers DAC conversion each period. + TIM_MasterConfigTypeDef master_cfg = {0}; + master_cfg.MasterOutputTrigger = TIM_TRGO_UPDATE; + master_cfg.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; + if (HAL_TIMEx_MasterConfigSynchronization(&tim6_handle, &master_cfg) != HAL_OK) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_TIM6); + } + // NOTE: ports/atmel-samd's audio_dma_setup_playback handles AUDIO_DMA_OK + // and two specific error codes but lets any other non-OK return fall + // through silently — worth tightening there to mirror this raise-on-fail + // pattern. + + // --- DAC channel reconfiguration for DMA-triggered mode --- + // Switch the trigger source to TIM6 *without* disabling the DAC channel. + // HAL_DAC_Stop would disable the channel and momentarily drop the output + // pin to 0 V — audible as a pop between samples. + DAC_ChannelConfTypeDef ch_cfg = {0}; + ch_cfg.DAC_Trigger = DAC_TRIGGER_T6_TRGO; + ch_cfg.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + HAL_DAC_ConfigChannel(&handle, &ch_cfg, DAC_CHANNEL_1); + if (self->right_channel != NULL) { + HAL_DAC_ConfigChannel(&handle, &ch_cfg, DAC_CHANNEL_2); + } + // Reset HAL state from BUSY (set by Start) back to READY so + // HAL_DAC_Start_DMA below doesn't reject the request. + handle.State = HAL_DAC_STATE_READY; + + // --- DMA1 Stream5 Channel7 setup (DAC CH1, left) --- + __HAL_RCC_DMA1_CLK_ENABLE(); + + DMA_HandleTypeDef *hdma = &self->dma_handle_l; + memset(hdma, 0, sizeof(*hdma)); + hdma->Instance = DMA1_Stream5; + hdma->Init.Channel = DMA_CHANNEL_7; + hdma->Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma->Init.PeriphInc = DMA_PINC_DISABLE; + hdma->Init.MemInc = DMA_MINC_ENABLE; + hdma->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma->Init.Mode = DMA_CIRCULAR; + hdma->Init.Priority = DMA_PRIORITY_VERY_HIGH; + hdma->Init.FIFOMode = DMA_FIFOMODE_DISABLE; + if (HAL_DMA_Init(hdma) != HAL_OK) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_DMA); + } + __HAL_LINKDMA(&handle, DMA_Handle1, *hdma); + + HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 6, 0); + NVIC_ClearPendingIRQ(DMA1_Stream5_IRQn); + HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn); + + // --- DMA1 Stream6 Channel7 setup (DAC CH2, right) --- + if (self->right_channel != NULL) { + DMA_HandleTypeDef *hdma_r = &self->dma_handle_r; + memset(hdma_r, 0, sizeof(*hdma_r)); + hdma_r->Instance = DMA1_Stream6; + hdma_r->Init.Channel = DMA_CHANNEL_7; + hdma_r->Init.Direction = DMA_MEMORY_TO_PERIPH; + hdma_r->Init.PeriphInc = DMA_PINC_DISABLE; + hdma_r->Init.MemInc = DMA_MINC_ENABLE; + hdma_r->Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; + hdma_r->Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; + hdma_r->Init.Mode = DMA_CIRCULAR; + hdma_r->Init.Priority = DMA_PRIORITY_VERY_HIGH; + hdma_r->Init.FIFOMode = DMA_FIFOMODE_DISABLE; + if (HAL_DMA_Init(hdma_r) != HAL_OK) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_DMA); + } + __HAL_LINKDMA(&handle, DMA_Handle2, *hdma_r); + + HAL_NVIC_SetPriority(DMA1_Stream6_IRQn, 6, 0); + NVIC_ClearPendingIRQ(DMA1_Stream6_IRQn); + HAL_NVIC_EnableIRQ(DMA1_Stream6_IRQn); + } + + // --- Start DMA transfer(s) then timer --- + active_audioout = self; + + if (HAL_DAC_Start_DMA(&handle, DAC_CHANNEL_1, + (uint32_t *)self->dma_buffer, + AUDIOOUT_DMA_BUFFER_SAMPLES, + DAC_ALIGN_12B_R) != HAL_OK) { + active_audioout = NULL; + HAL_NVIC_DisableIRQ(DMA1_Stream5_IRQn); + if (self->right_channel != NULL) { + HAL_NVIC_DisableIRQ(DMA1_Stream6_IRQn); + m_free(self->dma_buffer_r); + self->dma_buffer_r = NULL; + } + m_free(self->dma_buffer); + self->dma_buffer = NULL; + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_DAC); + } + + if (self->right_channel != NULL) { + if (HAL_DAC_Start_DMA(&handle, DAC_CHANNEL_2, + (uint32_t *)self->dma_buffer_r, + AUDIOOUT_DMA_BUFFER_SAMPLES, + DAC_ALIGN_12B_R) != HAL_OK) { + active_audioout = NULL; + HAL_DAC_Stop_DMA(&handle, DAC_CHANNEL_1); + HAL_NVIC_DisableIRQ(DMA1_Stream5_IRQn); + HAL_NVIC_DisableIRQ(DMA1_Stream6_IRQn); + m_free(self->dma_buffer); + self->dma_buffer = NULL; + m_free(self->dma_buffer_r); + self->dma_buffer_r = NULL; + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_DAC); + } + } + + HAL_TIM_Base_Start(&tim6_handle); + self->playing = true; +} + +void common_hal_audioio_audioout_stop(audioio_audioout_obj_t *self) { + if (active_audioout != self) { + return; + } + + // Stop the sample clock first so no more DMA requests are generated. + TIM6->CR1 &= ~TIM_CR1_CEN; + + // Switch the DAC channels to no-trigger mode while leaving them enabled. + // This is the key to a click-free stop: HAL_DAC_Stop_DMA / HAL_DAC_Stop + // disable the channel, which briefly pulls the output pin to 0 V before + // the ramp can run. Reconfiguring the trigger only keeps the channel + // enabled; the DAC keeps holding its last DHR value while DMA is aborted. + DAC_ChannelConfTypeDef ch_cfg = {0}; + ch_cfg.DAC_Trigger = DAC_TRIGGER_NONE; + ch_cfg.DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE; + HAL_DAC_ConfigChannel(&handle, &ch_cfg, DAC_CHANNEL_1); + if (self->dma_buffer_r) { + HAL_DAC_ConfigChannel(&handle, &ch_cfg, DAC_CHANNEL_2); + } + + // Capture the last DAC output now that no further DMA writes can land. + uint16_t last_l = (uint16_t)(DAC->DOR1 & 0xFFF); + uint16_t last_r = self->dma_buffer_r ? (uint16_t)(DAC->DOR2 & 0xFFF) : 0; + uint16_t quiescent_12 = self->quiescent_value >> 4; + + // Abort DMA without disabling the DAC channels (HAL_DAC_Stop_DMA would). + HAL_DMA_Abort(&self->dma_handle_l); + HAL_NVIC_DisableIRQ(DMA1_Stream5_IRQn); + NVIC_ClearPendingIRQ(DMA1_Stream5_IRQn); + if (self->dma_buffer_r) { + HAL_DMA_Abort(&self->dma_handle_r); + HAL_NVIC_DisableIRQ(DMA1_Stream6_IRQn); + NVIC_ClearPendingIRQ(DMA1_Stream6_IRQn); + m_free(self->dma_buffer_r); + self->dma_buffer_r = NULL; + } + + // Free the left DMA buffer. + if (self->dma_buffer) { + m_free(self->dma_buffer); + self->dma_buffer = NULL; + } + + // Ramp left channel from last sample back to quiescent. + dac_ramp_channel(DAC_CHANNEL_1, last_l, quiescent_12); + + // Ramp right channel back to 0 (its reset value) before disabling it, + // so the next play() can ramp cleanly from 0 again. + if (self->right_channel != NULL) { + dac_ramp_channel(DAC_CHANNEL_2, last_r, 0); + HAL_DAC_Stop(&handle, DAC_CHANNEL_2); + } + + self->sample = MP_OBJ_NULL; + self->stopping = false; + self->paused = false; + self->playing = false; + active_audioout = NULL; + + __HAL_RCC_TIM6_CLK_DISABLE(); +} + +bool common_hal_audioio_audioout_get_playing(audioio_audioout_obj_t *self) { + return active_audioout == self && self->playing; +} + +void common_hal_audioio_audioout_pause(audioio_audioout_obj_t *self) { + if (active_audioout != self) { + return; + } + self->paused = true; + // Pause the sample clock; DMA remains armed but no new triggers fire. + TIM6->CR1 &= ~TIM_CR1_CEN; +} + +void common_hal_audioio_audioout_resume(audioio_audioout_obj_t *self) { + if (active_audioout != self || !self->paused) { + return; + } + self->paused = false; + // Restart the sample clock. + TIM6->CR1 |= TIM_CR1_CEN; +} + +bool common_hal_audioio_audioout_get_paused(audioio_audioout_obj_t *self) { + // Match espressif's convention: paused only reports true while a play() + // session is active, so a stale flag from a previous session can never + // leak through. + // + // NOTE: ports/atmel-samd delegates to audio_dma_get_paused() and does + // not gate on a "playing" state — it relies on the DMA hardware staying + // quiescent after stop. Worth aligning to the espressif/stm convention. + return self->playing && self->paused; +} + +// --------------------------------------------------------------------------- +// Reset hook +// --------------------------------------------------------------------------- + +void audioout_reset(void) { + if (active_audioout != NULL) { + // Emergency stop: halt timer and DMA without ramping. + TIM6->CR1 &= ~TIM_CR1_CEN; + HAL_DAC_Stop_DMA(&handle, DAC_CHANNEL_1); + HAL_NVIC_DisableIRQ(DMA1_Stream5_IRQn); + if (active_audioout->dma_buffer_r) { + HAL_DAC_Stop_DMA(&handle, DAC_CHANNEL_2); + HAL_NVIC_DisableIRQ(DMA1_Stream6_IRQn); + m_free(active_audioout->dma_buffer_r); + active_audioout->dma_buffer_r = NULL; + } + if (active_audioout->dma_buffer) { + m_free(active_audioout->dma_buffer); + active_audioout->dma_buffer = NULL; + } + active_audioout->sample = MP_OBJ_NULL; + active_audioout->stopping = false; + active_audioout->paused = false; + active_audioout->playing = false; + // Mark the object deinited and drop both pin references so the next + // construct() starts from a fully clean state. reset_all_pins (run + // elsewhere in reset_port) releases the actual pin claims. + active_audioout->left_channel = NULL; + active_audioout->right_channel = NULL; + active_audioout = NULL; + } + __HAL_RCC_TIM6_CLK_DISABLE(); +} diff --git a/ports/stm/common-hal/audioio/AudioOut.h b/ports/stm/common-hal/audioio/AudioOut.h new file mode 100644 index 00000000000..340118819a9 --- /dev/null +++ b/ports/stm/common-hal/audioio/AudioOut.h @@ -0,0 +1,72 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" +#include "supervisor/background_callback.h" +#include STM32_HAL_H + +// Total DMA circular buffer size in 16-bit samples. +// Split into two halves; one half plays while the other is refilled. +// 4096-sample halves at 22050 Hz = ~186 ms per half-buffer interrupt, +// giving the background callback enough headroom to absorb SDIO cluster +// reads, NeoPixel updates, and other main-loop stalls without underrun. +#define AUDIOOUT_DMA_BUFFER_SAMPLES 8192 +#define AUDIOOUT_DMA_HALF_SAMPLES (AUDIOOUT_DMA_BUFFER_SAMPLES / 2) + +typedef struct { + mp_obj_base_t base; + + // Left channel pin (PA04 = DAC_CH1). NULL when deinited. + const mcu_pin_obj_t *left_channel; + // Right channel pin (PA05 = DAC_CH2). NULL when mono. + const mcu_pin_obj_t *right_channel; + + // DMA handles. The DAC handle itself is the shared file-scope handle + // from AnalogOut.c; we link these to it via __HAL_LINKDMA. + DMA_HandleTypeDef dma_handle_l; // DMA1 Stream5 Channel7 (DAC CH1, left) + DMA_HandleTypeDef dma_handle_r; // DMA1 Stream6 Channel7 (DAC CH2, right) + + // Circular DMA buffers: AUDIOOUT_DMA_BUFFER_SAMPLES uint16_t elements each, + // allocated on play() and freed on stop(). + uint16_t *dma_buffer; // left (CH1) + uint16_t *dma_buffer_r; // right (CH2), NULL when mono + + // Current audio sample object being played. + mp_obj_t sample; + bool loop; + bool playing; + + // Set from ISR context to request a clean stop via background callback. + volatile bool stopping; + bool paused; + + // Sample format metadata, populated at play() time. + uint8_t bytes_per_sample; // 1 (8-bit) or 2 (16-bit) + bool samples_signed; + uint8_t channel_count; // 1 = mono, 2 = stereo + uint16_t quiescent_value; // 16-bit resting value (default 0x8000) + + // Background callback queued from DMA ISR, processed in main loop. + background_callback_t callback; + + // Bitmask of DMA halves pending refill: bit0 = lower, bit1 = upper. + // Set from half/full IRQ, drained by the background callback. A bitmask + // (not a scalar) so a back-to-back half+full pair queues both fills even + // if the callback hasn't run yet. + volatile uint8_t halves_to_fill; + + // Source buffer position tracking. Allows consuming large source buffers + // (e.g. RawSample > 256 samples) across multiple DMA half-fills. + const uint8_t *src_ptr; // current read position in source buffer + uint32_t src_remaining_len; // bytes remaining in current source buffer + bool src_done; // GET_BUFFER_DONE received for current buffer +} audioio_audioout_obj_t; + +// Called from reset_port() to stop any active playback on soft-reset. +void audioout_reset(void); diff --git a/ports/stm/common-hal/audioio/__init__.c b/ports/stm/common-hal/audioio/__init__.c new file mode 100644 index 00000000000..ebf626832f6 --- /dev/null +++ b/ports/stm/common-hal/audioio/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// No audioio module functions. diff --git a/ports/stm/common-hal/audiopwmio/PWMAudioOut.c b/ports/stm/common-hal/audiopwmio/PWMAudioOut.c index 9a82398aeb6..08ab7eb9bc7 100644 --- a/ports/stm/common-hal/audiopwmio/PWMAudioOut.c +++ b/ports/stm/common-hal/audiopwmio/PWMAudioOut.c @@ -206,6 +206,11 @@ void common_hal_audiopwmio_pwmaudioout_construct(audiopwmio_pwmaudioout_obj_t *s self->buffer[0] = NULL; self->buffer[1] = NULL; + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + self->buffer_size[0] = 0; + self->buffer_size[1] = 0; + #endif + self->quiescent_value = quiescent_value; } @@ -214,9 +219,22 @@ bool common_hal_audiopwmio_pwmaudioout_deinited(audiopwmio_pwmaudioout_obj_t *se } static void free_buffers(audiopwmio_pwmaudioout_obj_t *self) { + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(self->buffer[0], self->buffer_size[0]); + self->buffer_size[0] = 0; + #else m_free(self->buffer[0]); + #endif + self->buffer[0] = NULL; + + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(self->buffer[1], self->buffer_size[1]); + self->buffer_size[1] = 0; + #else m_free(self->buffer[1]); + #endif + self->buffer[1] = NULL; } @@ -237,11 +255,14 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, if (active_audio) { mp_raise_RuntimeError(MP_ERROR_TEXT("Another PWMAudioOut is already active")); // TODO } + + audiosample_check(sample); + self->sample = sample; self->loop = loop; - uint32_t sample_rate = audiosample_sample_rate(sample); - self->bytes_per_sample = audiosample_bits_per_sample(sample) / 8; + uint32_t sample_rate = audiosample_get_sample_rate(sample); + self->bytes_per_sample = audiosample_get_bits_per_sample(sample) / 8; uint32_t max_buffer_length; uint8_t spacing; @@ -249,7 +270,7 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, bool samples_signed; audiosample_get_buffer_structure(sample, /* single channel */ false, &single_buffer, &samples_signed, &max_buffer_length, &spacing); - self->sample_channel_count = audiosample_channel_count(sample); + self->sample_channel_count = audiosample_get_channel_count(sample); self->sample_offset = (samples_signed ? 0x8000 : 0) - self->quiescent_value; free_buffers(self); @@ -257,11 +278,21 @@ void common_hal_audiopwmio_pwmaudioout_play(audiopwmio_pwmaudioout_obj_t *self, if (max_buffer_length > UINT16_MAX) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Buffer length %d too big. It must be less than %d"), max_buffer_length, UINT16_MAX); } + uint16_t buffer_length = (uint16_t)max_buffer_length / self->bytes_per_sample; - self->buffer[0] = m_malloc(buffer_length * sizeof(uint16_t)); + size_t buffer_size = buffer_length * sizeof(uint16_t); + + self->buffer[0] = m_malloc_without_collect(buffer_size); + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + self->buffer_size[0] = buffer_size; + #endif self->buffer_ptr[0] = self->buffer_length[0] = 0; + if (self->pin[1]) { - self->buffer[1] = m_malloc(buffer_length * sizeof(uint16_t)); + self->buffer[1] = m_malloc_without_collect(buffer_size); + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + self->buffer_size[1] = buffer_size; + #endif self->buffer_ptr[1] = self->buffer_length[1] = 0; } @@ -314,7 +345,6 @@ void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) tim_handle.Instance->CR1 &= ~TIM_CR1_CEN; stm_peripherals_timer_free(tim_handle.Instance); - active_audio = NULL; self->stopping = false; self->paused = false; @@ -324,6 +354,8 @@ void common_hal_audiopwmio_pwmaudioout_stop(audiopwmio_pwmaudioout_obj_t *self) set_pin(1, GPIO_PIN_RESET); } + active_audio = NULL; + // Cannot free buffers here because we may be called from // the interrupt handler, and the heap is not reentrant. } diff --git a/ports/stm/common-hal/audiopwmio/PWMAudioOut.h b/ports/stm/common-hal/audiopwmio/PWMAudioOut.h index be31e87d177..b41ef44b17f 100644 --- a/ports/stm/common-hal/audiopwmio/PWMAudioOut.h +++ b/ports/stm/common-hal/audiopwmio/PWMAudioOut.h @@ -14,6 +14,9 @@ typedef struct { uint16_t quiescent_value; uint16_t *buffer[2]; + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + uint16_t buffer_size[2]; // Keeps track of allocated size + #endif uint16_t buffer_length[2]; uint16_t buffer_ptr[2]; diff --git a/ports/stm/common-hal/busio/I2C.c b/ports/stm/common-hal/busio/I2C.c index c58c1883df2..7f7eb990e4d 100644 --- a/ports/stm/common-hal/busio/I2C.c +++ b/ports/stm/common-hal/busio/I2C.c @@ -41,28 +41,18 @@ #define MAX_I2C 4 static bool reserved_i2c[MAX_I2C]; -static bool never_reset_i2c[MAX_I2C]; #define ALL_CLOCKS 0xFF static void i2c_clock_enable(uint8_t mask); static void i2c_clock_disable(uint8_t mask); static void i2c_assign_irq(busio_i2c_obj_t *self, I2C_TypeDef *I2Cx); -void i2c_reset(void) { - uint16_t never_reset_mask = 0x00; - for (int i = 0; i < MAX_I2C; i++) { - if (!never_reset_i2c[i]) { - reserved_i2c[i] = false; - } else { - never_reset_mask |= 1 << i; - } - } - i2c_clock_disable(ALL_CLOCKS & ~(never_reset_mask)); -} - void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, uint32_t timeout) { + // Ensure the object starts in its deinit state. + common_hal_busio_i2c_mark_deinit(self); + // Match pins to I2C objects I2C_TypeDef *I2Cx; uint8_t sda_len = MP_ARRAY_SIZE(mcu_i2c_sda_list); @@ -163,15 +153,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, } void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { - for (size_t i = 0; i < MP_ARRAY_SIZE(mcu_i2c_banks); i++) { - if (self->handle.Instance == mcu_i2c_banks[i]) { - never_reset_i2c[i] = true; - - never_reset_pin_number(self->scl->pin->port, self->scl->pin->number); - never_reset_pin_number(self->sda->pin->port, self->sda->pin->number); - break; - } - } + never_reset_pin_number(self->scl->pin->port, self->scl->pin->number); + never_reset_pin_number(self->sda->pin->port, self->sda->pin->number); } bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { @@ -185,12 +168,14 @@ void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { i2c_clock_disable(1 << (self->sda->periph_index - 1)); reserved_i2c[self->sda->periph_index - 1] = false; - never_reset_i2c[self->sda->periph_index - 1] = false; reset_pin_number(self->sda->pin->port, self->sda->pin->number); reset_pin_number(self->scl->pin->port, self->scl->pin->number); + common_hal_busio_i2c_mark_deinit(self); +} + +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { self->sda = NULL; - self->scl = NULL; } bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { @@ -227,7 +212,7 @@ void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { self->has_lock = false; } -static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +static mp_negative_errno_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { HAL_StatusTypeDef result; if (!transmit_stop_bit) { @@ -249,19 +234,19 @@ static uint8_t _common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, result = HAL_I2C_Master_Transmit(&(self->handle), (uint16_t)(addr << 1), (uint8_t *)data, (uint16_t)len, 500); } - return result == HAL_OK ? 0 : MP_EIO; + return result == HAL_OK ? 0 : -MP_EIO; } -uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len) { return _common_hal_busio_i2c_write(self, addr, data, len, true); } -uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { if (!self->frame_in_prog) { return HAL_I2C_Master_Receive(&(self->handle), (uint16_t)(addr << 1), data, (uint16_t)len, 500) - == HAL_OK ? 0 : MP_EIO; + == HAL_OK ? 0 : -MP_EIO; } else { HAL_StatusTypeDef result = HAL_I2C_Master_Seq_Receive_IT(&(self->handle), (uint16_t)(addr << 1), (uint8_t *)data, @@ -274,9 +259,9 @@ uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, } } -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { - uint8_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); + mp_negative_errno_t result = _common_hal_busio_i2c_write(self, addr, out_data, out_len, false); if (result != 0) { return result; } diff --git a/ports/stm/common-hal/busio/I2C.h b/ports/stm/common-hal/busio/I2C.h index ff78ddb35af..c79a077dcab 100644 --- a/ports/stm/common-hal/busio/I2C.h +++ b/ports/stm/common-hal/busio/I2C.h @@ -22,5 +22,3 @@ typedef struct { const mcu_periph_obj_t *scl; const mcu_periph_obj_t *sda; } busio_i2c_obj_t; - -void i2c_reset(void); diff --git a/ports/stm/common-hal/busio/SPI.c b/ports/stm/common-hal/busio/SPI.c index 98696271ca9..24b65fbf54c 100644 --- a/ports/stm/common-hal/busio/SPI.c +++ b/ports/stm/common-hal/busio/SPI.c @@ -19,7 +19,6 @@ #define MAX_SPI 6 static bool reserved_spi[MAX_SPI]; -static bool never_reset_spi[MAX_SPI]; #define ALL_CLOCKS 0xFF static void spi_clock_enable(uint8_t mask); @@ -76,18 +75,6 @@ static uint32_t stm32_baud_to_spi_div(uint32_t baudrate, uint16_t *prescaler, ui return SPI_BAUDRATEPRESCALER_256; } -void spi_reset(void) { - uint16_t never_reset_mask = 0x00; - for (int i = 0; i < MAX_SPI; i++) { - if (!never_reset_spi[i]) { - reserved_spi[i] = false; - } else { - never_reset_mask |= 1 << i; - } - } - spi_clock_disable(ALL_CLOCKS & ~(never_reset_mask)); -} - static const mcu_periph_obj_t *find_pin_function(const mcu_periph_obj_t *table, size_t sz, const mcu_pin_obj_t *pin, int periph_index) { for (size_t i = 0; i < sz; i++, table++) { if (periph_index == table->periph_index && pin == table->pin) { @@ -149,6 +136,10 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, bool half_duplex) { + // Ensure the object starts in its deinit state before check_pins sets + // self->sck, self->mosi, and self->miso. + common_hal_busio_spi_mark_deinit(self); + int periph_index = check_pins(self, sck, mosi, miso); SPI_TypeDef *SPIx = mcu_spi_banks[periph_index - 1]; @@ -224,7 +215,6 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self, void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { - never_reset_spi[self->sck->periph_index - 1] = true; never_reset_pin_number(self->sck->pin->port, self->sck->pin->number); if (self->mosi != NULL) { never_reset_pin_number(self->mosi->pin->port, self->mosi->pin->number); @@ -238,13 +228,16 @@ bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { return self->sck == NULL; } +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + self->sck = NULL; +} + void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } spi_clock_disable(1 << (self->sck->periph_index - 1)); reserved_spi[self->sck->periph_index - 1] = false; - never_reset_spi[self->sck->periph_index - 1] = false; reset_pin_number(self->sck->pin->port, self->sck->pin->number); if (self->mosi != NULL) { diff --git a/ports/stm/common-hal/microcontroller/Pin.c b/ports/stm/common-hal/microcontroller/Pin.c index e0ff3f138df..bdf5e5fb16c 100644 --- a/ports/stm/common-hal/microcontroller/Pin.c +++ b/ports/stm/common-hal/microcontroller/Pin.c @@ -11,6 +11,8 @@ #if defined(TFBGA216) GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK}; +#elif defined(UFBGA176) +GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH, GPIOI}; #elif defined(LQFP144) || defined(WLCSP144) GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG}; #elif defined(LQFP100_f4) || (LQFP100_x7) @@ -19,6 +21,8 @@ GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC, GPIOD, GPIOE}; GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC, GPIOD}; #elif defined(UFQFPN48) GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC}; +#elif defined(LQFP48) +GPIO_TypeDef *ports[] = {GPIOA, GPIOB, GPIOC}; #else #error Unknown package type #endif diff --git a/ports/stm/common-hal/microcontroller/Processor.c b/ports/stm/common-hal/microcontroller/Processor.c index 0781f422ee1..719d29e1d53 100644 --- a/ports/stm/common-hal/microcontroller/Processor.c +++ b/ports/stm/common-hal/microcontroller/Processor.c @@ -127,8 +127,8 @@ void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { #if CIRCUITPY_ALARM if (alarm_get_wakeup_cause() != STM_WAKEUP_UNDEF) { - return RESET_REASON_DEEP_SLEEP_ALARM; + return MCU_RESET_REASON_DEEP_SLEEP_ALARM; } #endif - return RESET_REASON_UNKNOWN; + return MCU_RESET_REASON_UNKNOWN; } diff --git a/ports/stm/common-hal/microcontroller/__init__.c b/ports/stm/common-hal/microcontroller/__init__.c index 5a0f0ed9294..a9c9b76849d 100644 --- a/ports/stm/common-hal/microcontroller/__init__.c +++ b/ports/stm/common-hal/microcontroller/__init__.c @@ -31,12 +31,14 @@ void common_hal_mcu_delay_us(uint32_t delay) { SysTick->CTRL = 0UL; } -volatile uint32_t nesting_count = 0; +static volatile uint32_t nesting_count = 0; +// 32-bit increments void common_hal_mcu_disable_interrupts(void) { - __disable_irq(); - __DMB(); - nesting_count++; + if (++nesting_count == 1) { + __disable_irq(); + __DMB(); + } } void common_hal_mcu_enable_interrupts(void) { @@ -44,12 +46,10 @@ void common_hal_mcu_enable_interrupts(void) { // This is very very bad because it means there was mismatched disable/enables. reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); } - nesting_count--; - if (nesting_count > 0) { - return; + if (--nesting_count == 0) { + __DMB(); + __enable_irq(); } - __DMB(); - __enable_irq(); } static bool next_reset_to_bootloader = false; diff --git a/ports/stm/common-hal/os/__init__.c b/ports/stm/common-hal/os/__init__.c index b3d9e67d988..d654f844b17 100644 --- a/ports/stm/common-hal/os/__init__.c +++ b/ports/stm/common-hal/os/__init__.c @@ -15,32 +15,6 @@ #include STM32_HAL_H #include "peripherals/periph.h" -static const qstr os_uname_info_fields[] = { - MP_QSTR_sysname, MP_QSTR_nodename, - MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine -}; -static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, STM32_SERIES_LOWER); -static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, STM32_SERIES_LOWER); - -static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); -static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); -static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); - -static MP_DEFINE_ATTRTUPLE( - os_uname_info_obj, - os_uname_info_fields, - 5, - (mp_obj_t)&os_uname_info_sysname_obj, - (mp_obj_t)&os_uname_info_nodename_obj, - (mp_obj_t)&os_uname_info_release_obj, - (mp_obj_t)&os_uname_info_version_obj, - (mp_obj_t)&os_uname_info_machine_obj - ); - -mp_obj_t common_hal_os_uname(void) { - return (mp_obj_t)&os_uname_info_obj; -} - #define RNG_TIMEOUT 5 bool common_hal_os_urandom(uint8_t *buffer, uint32_t length) { diff --git a/ports/stm/common-hal/pulseio/PulseIn.c b/ports/stm/common-hal/pulseio/PulseIn.c index 593e01f9bb9..86d304af5f1 100644 --- a/ports/stm/common-hal/pulseio/PulseIn.c +++ b/ports/stm/common-hal/pulseio/PulseIn.c @@ -84,7 +84,7 @@ void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t *self, const mcu } // Allocate pulse buffer - self->buffer = (uint16_t *)m_malloc(maxlen * sizeof(uint16_t)); + self->buffer = (uint16_t *)m_malloc_without_collect(maxlen * sizeof(uint16_t)); if (self->buffer == NULL) { // TODO: free the EXTI here? m_malloc_fail(maxlen * sizeof(uint16_t)); diff --git a/ports/stm/common-hal/pwmio/PWMOut.c b/ports/stm/common-hal/pwmio/PWMOut.c index ed3bd67e7ec..fe516065fbd 100644 --- a/ports/stm/common-hal/pwmio/PWMOut.c +++ b/ports/stm/common-hal/pwmio/PWMOut.c @@ -74,12 +74,12 @@ pwmout_result_t common_hal_pwmio_pwmout_construct(pwmio_pwmout_obj_t *self, } // If the frequencies are the same it's ok if (tim_frequencies[tim_index] != frequency) { - last_failure = PWMOUT_INVALID_FREQUENCY_ON_PIN; + last_failure = PWMOUT_INTERNAL_RESOURCES_IN_USE; continue; // keep looking } // you can't put a variable frequency on a partially reserved timer if (variable_frequency) { - last_failure = PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE; + last_failure = PWMOUT_INTERNAL_RESOURCES_IN_USE; continue; // keep looking } first_time_setup = false; // skip setting up the timer diff --git a/ports/stm/common-hal/sdioio/SDCard.c b/ports/stm/common-hal/sdioio/SDCard.c index 92c16aef847..ef708248716 100644 --- a/ports/stm/common-hal/sdioio/SDCard.c +++ b/ports/stm/common-hal/sdioio/SDCard.c @@ -6,6 +6,8 @@ #include #include "shared-bindings/sdioio/SDCard.h" + +#include "extmod/vfs.h" #include "py/mperrno.h" #include "py/runtime.h" @@ -104,7 +106,11 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, uint8_t num_data, const mcu_pin_obj_t **data, uint32_t frequency) { int periph_index = check_pins(self, clock, command, num_data, data); + #ifdef STM32H750xx + SDMMC_TypeDef *SDMMCx = mcu_sdio_banks[periph_index - 1]; + #else SDIO_TypeDef *SDIOx = mcu_sdio_banks[periph_index - 1]; + #endif GPIO_InitTypeDef GPIO_InitStruct = {0}; @@ -128,6 +134,25 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, GPIO_InitStruct.Pin = pin_mask(clock->number); HAL_GPIO_Init(pin_port(clock->port), &GPIO_InitStruct); + #ifdef STM32H750xx + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SDMMC; + PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("MMC/SDIO Clock Error %x")); + } + __HAL_RCC_SDMMC1_CLK_ENABLE(); + + self->handle.Init.ClockDiv = SDMMC_NSPEED_CLK_DIV; + self->handle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; + self->handle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; + self->handle.Init.BusWide = SDMMC_BUS_WIDE_1B; + // For the SDMMC controller Hardware Flow Control needs to be enabled + // at the default speed of 25MHz, in order to avoid FIFO underrun (TX mode) + // and overrun (RX mode) errors. + self->handle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE; + self->handle.Instance = SDMMCx; + #else __HAL_RCC_SDIO_CLK_ENABLE(); self->handle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; @@ -137,10 +162,11 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, self->handle.Init.BusWide = SDIO_BUS_WIDE_1B; self->handle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; self->handle.Instance = SDIOx; + #endif HAL_StatusTypeDef r = HAL_SD_Init(&self->handle); if (r != HAL_OK) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("SDIO Init Error %x"), (unsigned int)r); + mp_raise_ValueError_varg(MP_ERROR_TEXT("SDIO Init Error 0x%02x"), (unsigned int)r); } HAL_SD_CardInfoTypeDef info; @@ -150,9 +176,14 @@ void common_hal_sdioio_sdcard_construct(sdioio_sdcard_obj_t *self, } self->num_data = 1; + #ifdef STM32H750xx + uint32_t bus_wide_opt = SDMMC_BUS_WIDE_4B; + #else + uint32_t bus_wide_opt = SDIO_BUS_WIDE_4B; + #endif if (num_data == 4) { - if ((r = HAL_SD_ConfigWideBusOperation(&self->handle, SDIO_BUS_WIDE_4B)) == HAL_SD_ERROR_NONE) { - self->handle.Init.BusWide = SDIO_BUS_WIDE_4B; + if ((r = HAL_SD_ConfigWideBusOperation(&self->handle, bus_wide_opt)) == HAL_SD_ERROR_NONE) { + self->handle.Init.BusWide = bus_wide_opt; self->num_data = 4; } else { } @@ -210,33 +241,90 @@ static void check_for_deinit(sdioio_sdcard_obj_t *self) { } } -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { - check_for_deinit(self); - check_whole_block(bufinfo); +// Native function for VFS blockdev layer +mp_negative_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); self->state_programming = true; common_hal_mcu_disable_interrupts(); - HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000); + #ifdef STM32H750xx + // longer timeouts needed because code executing from QSPI is slower + uint32_t time_out = SDMMC_DATATIMEOUT; + #else + uint32_t time_out = 1000; + #endif + HAL_StatusTypeDef r = HAL_SD_WriteBlocks(&self->handle, buf, start_block, num_blocks, time_out); common_hal_mcu_enable_interrupts(); if (r != HAL_OK) { - return -EIO; + return -MP_EIO; } return 0; } -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { +mp_negative_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { check_for_deinit(self); check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +mp_negative_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, + uint32_t start_block, uint32_t num_blocks) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); wait_write_complete(self); common_hal_mcu_disable_interrupts(); - HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, bufinfo->buf, start_block, bufinfo->len / 512, 1000); + #ifdef STM32H750xx + // longer timeouts needed because code executing from QSPI is slower + uint32_t time_out = SDMMC_DATATIMEOUT; + #else + uint32_t time_out = 1000; + #endif + HAL_StatusTypeDef r = HAL_SD_ReadBlocks(&self->handle, buf, start_block, num_blocks, time_out); common_hal_mcu_enable_interrupts(); if (r != HAL_OK) { - return -EIO; + return -MP_EIO; } return 0; } +mp_negative_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo) { + check_for_deinit(self); + check_whole_block(bufinfo); + + uint32_t num_blocks = bufinfo->len / 512; + return sdioio_sdcard_readblocks(MP_OBJ_FROM_PTR(self), bufinfo->buf, + start_block, num_blocks); +} + +// Native function for VFS blockdev layer +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, + mp_int_t *out_value) { + sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); + *out_value = 0; + + switch (cmd) { + case MP_BLOCKDEV_IOCTL_DEINIT: + case MP_BLOCKDEV_IOCTL_SYNC: + // SDIO operations are synchronous, no action needed + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = common_hal_sdioio_sdcard_get_count(self); + return true; + + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = 512; // SD cards use 512-byte sectors + return true; + + default: + return false; // Unsupported command + } +} + bool common_hal_sdioio_sdcard_configure(sdioio_sdcard_obj_t *self, uint32_t frequency, uint8_t bits) { check_for_deinit(self); return true; @@ -297,7 +385,7 @@ void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self) { } } -void sdioio_reset() { +void sdioio_reset(void) { for (size_t i = 0; i < MP_ARRAY_SIZE(reserved_sdio); i++) { if (!never_reset_sdio[i]) { reserved_sdio[i] = false; diff --git a/ports/stm/mpconfigport.h b/ports/stm/mpconfigport.h index ed36b49ffb9..afa9aa3685c 100644 --- a/ports/stm/mpconfigport.h +++ b/ports/stm/mpconfigport.h @@ -9,9 +9,6 @@ #include -#define MICROPY_PY_FUNCTION_ATTRS (1) -#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1) - extern uint8_t _ld_default_stack_size; // 24kiB stack diff --git a/ports/stm/mpconfigport.mk b/ports/stm/mpconfigport.mk index 32662129627..bd2b2238eef 100644 --- a/ports/stm/mpconfigport.mk +++ b/ports/stm/mpconfigport.mk @@ -3,6 +3,8 @@ INTERNAL_LIBM ?= 1 ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F405xx STM32F407xx)) CIRCUITPY_ALARM = 1 + # ?= so a board reusing TIM6 / PA04 for something else can opt out. + CIRCUITPY_AUDIOIO ?= 1 CIRCUITPY_CANIO = 1 CIRCUITPY_FRAMEBUFFERIO ?= 1 CIRCUITPY_SDIOIO ?= 1 @@ -10,13 +12,17 @@ ifeq ($(MCU_VARIANT),$(filter $(MCU_VARIANT),STM32F405xx STM32F407xx)) USB_NUM_ENDPOINT_PAIRS = 4 endif +ifeq ($(INTERNAL_FLASH_FILESYSTEM),1) + OPTIMIZATION_FLAGS ?= -Os +endif + ifeq ($(MCU_VARIANT),STM32F407xx) UF2_FAMILY_ID ?= 0x6d0922fa endif ifeq ($(MCU_SERIES),F4) - # Audio via PWM - CIRCUITPY_AUDIOIO = 0 + # Audio via PWM (F405/F407 also supports DAC-based audioio; set above) + CIRCUITPY_AUDIOIO ?= 0 CIRCUITPY_AUDIOCORE ?= 1 CIRCUITPY_AUDIOPWMIO ?= 1 @@ -28,6 +34,7 @@ ifeq ($(MCU_SERIES),F4) CIRCUITPY_NVM ?= 0 CIRCUITPY_ROTARYIO ?= 0 CIRCUITPY_RTC ?= 1 + CIRCUITPY_PORT_SERIAL ?= 1 USB_NUM_ENDPOINT_PAIRS = 4 UF2_FAMILY_ID ?= 0x57755a57 endif @@ -80,11 +87,18 @@ ifeq ($(MCU_SERIES),L4) CIRCUITPY_NVM ?= 0 CIRCUITPY_ROTARYIO ?= 0 CIRCUITPY_RTC ?= 1 + UF2_FAMILY_ID ?= 0x00ff6919 +endif + +ifeq ($(MCU_VARIANT),STM32L4R5xx) # todo - this varies between devices in the series # This slide deck https://www.st.com/content/ccc/resource/training/technical/product_training/98/89/c8/6c/3e/e9/49/79/STM32L4_Peripheral_USB.pdf/files/STM32L4_Peripheral_USB.pdf/jcr:content/translations/en.STM32L4_Peripheral_USB.pdf # cites 16 endpoints, 8 endpoint pairs, while section 3.39 of the L4R5 datasheet states 6 endpoint pairs. USB_NUM_ENDPOINT_PAIRS = 6 - UF2_FAMILY_ID ?= 0x00ff6919 +endif + +ifeq ($(MCU_VARIANT),STM32L433xx) + USB_NUM_ENDPOINT_PAIRS = 4 endif CIRCUITPY_PARALLELDISPLAYBUS := 0 diff --git a/ports/stm/mpconfigport_nanbox.h b/ports/stm/mpconfigport_nanbox.h deleted file mode 100644 index 164850112e0..00000000000 --- a/ports/stm/mpconfigport_nanbox.h +++ /dev/null @@ -1,25 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2016 Damien P. George -// -// SPDX-License-Identifier: MIT - -#pragma once - -// select nan-boxing object model -#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_D) - -// native emitters don't work with nan-boxing -#define MICROPY_EMIT_X86 (0) -#define MICROPY_EMIT_X64 (0) -#define MICROPY_EMIT_THUMB (0) -#define MICROPY_EMIT_ARM (0) - -#include - -typedef int64_t mp_int_t; -typedef uint64_t mp_uint_t; -#define UINT_FMT "%llu" -#define INT_FMT "%lld" - -#include diff --git a/ports/stm/packages/LQFP48.c b/ports/stm/packages/LQFP48.c new file mode 100644 index 00000000000..46b737adeb8 --- /dev/null +++ b/ports/stm/packages/LQFP48.c @@ -0,0 +1,63 @@ +#include "shared-bindings/microcontroller/__init__.h" +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +static const mp_rom_map_elem_t mcu_pin_globals_table[] = { +// Pins 1-12 + /* VBAT -------------------------------------------*/ + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, + // PC14 OSC32_IN ----------------------------------*/ + // PC15 OSC32_OUT ---------------------------------*/ + // { MP_ROM_QSTR(MP_QSTR_PH00), MP_ROM_PTR(&pin_PH00) }, PH00 OSC_IN + // { MP_ROM_QSTR(MP_QSTR_PH01), MP_ROM_PTR(&pin_PH01) }, PH01 OSC_OUT + // NRST -------------------------------------------*/ + // VSSA -------------------------------------------*/ + // VDDA -------------------------------------------*/ + { MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) }, + +// Pins 13-24 + { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_PB02), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, + // VSS --------------------------------------------*/ + // VDD --------------------------------------------*/ + +// Pins 25-36 + { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, + { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) }, + { MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) }, + { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) }, + { MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) }, + { MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) }, + { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) }, + // VSS --------------------------------------------*/ + // VDD --------------------------------------------*/ + +// Pins 37-48 + { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, + // BOOT0 ------------------------------------------*/ + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, + // VSS --------------------------------------------*/ + // VDD --------------------------------------------*/ + +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table); diff --git a/ports/stm/packages/UFBGA176.c b/ports/stm/packages/UFBGA176.c new file mode 100644 index 00000000000..2f9c3002f59 --- /dev/null +++ b/ports/stm/packages/UFBGA176.c @@ -0,0 +1,183 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/microcontroller/__init__.h" +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +static const mp_rom_map_elem_t mcu_pin_globals_table[] = { +// Row A + { MP_ROM_QSTR(MP_QSTR_PE03), MP_ROM_PTR(&pin_PE03) }, + { MP_ROM_QSTR(MP_QSTR_PE02), MP_ROM_PTR(&pin_PE02) }, + { MP_ROM_QSTR(MP_QSTR_PE01), MP_ROM_PTR(&pin_PE01) }, + { MP_ROM_QSTR(MP_QSTR_PE00), MP_ROM_PTR(&pin_PE00) }, + { MP_ROM_QSTR(MP_QSTR_PB08), MP_ROM_PTR(&pin_PB08) }, + { MP_ROM_QSTR(MP_QSTR_PB05), MP_ROM_PTR(&pin_PB05) }, + { MP_ROM_QSTR(MP_QSTR_PG14), MP_ROM_PTR(&pin_PG14) }, + { MP_ROM_QSTR(MP_QSTR_PG13), MP_ROM_PTR(&pin_PG13) }, + { MP_ROM_QSTR(MP_QSTR_PB04), MP_ROM_PTR(&pin_PB04) }, + { MP_ROM_QSTR(MP_QSTR_PB03), MP_ROM_PTR(&pin_PB03) }, + { MP_ROM_QSTR(MP_QSTR_PD07), MP_ROM_PTR(&pin_PD07) }, + { MP_ROM_QSTR(MP_QSTR_PC12), MP_ROM_PTR(&pin_PC12) }, + { MP_ROM_QSTR(MP_QSTR_PA15), MP_ROM_PTR(&pin_PA15) }, + { MP_ROM_QSTR(MP_QSTR_PA14), MP_ROM_PTR(&pin_PA14) }, + { MP_ROM_QSTR(MP_QSTR_PA13), MP_ROM_PTR(&pin_PA13) }, + +// Row B + { MP_ROM_QSTR(MP_QSTR_PE04), MP_ROM_PTR(&pin_PE04) }, + { MP_ROM_QSTR(MP_QSTR_PE05), MP_ROM_PTR(&pin_PE05) }, + { MP_ROM_QSTR(MP_QSTR_PE06), MP_ROM_PTR(&pin_PE06) }, + { MP_ROM_QSTR(MP_QSTR_PB09), MP_ROM_PTR(&pin_PB09) }, + { MP_ROM_QSTR(MP_QSTR_PB07), MP_ROM_PTR(&pin_PB07) }, + { MP_ROM_QSTR(MP_QSTR_PB06), MP_ROM_PTR(&pin_PB06) }, + { MP_ROM_QSTR(MP_QSTR_PG15), MP_ROM_PTR(&pin_PG15) }, + { MP_ROM_QSTR(MP_QSTR_PG12), MP_ROM_PTR(&pin_PG12) }, + { MP_ROM_QSTR(MP_QSTR_PG11), MP_ROM_PTR(&pin_PG11) }, + { MP_ROM_QSTR(MP_QSTR_PG10), MP_ROM_PTR(&pin_PG10) }, + { MP_ROM_QSTR(MP_QSTR_PD06), MP_ROM_PTR(&pin_PD06) }, + { MP_ROM_QSTR(MP_QSTR_PD00), MP_ROM_PTR(&pin_PD00) }, + { MP_ROM_QSTR(MP_QSTR_PC11), MP_ROM_PTR(&pin_PC11) }, + { MP_ROM_QSTR(MP_QSTR_PC10), MP_ROM_PTR(&pin_PC10) }, + { MP_ROM_QSTR(MP_QSTR_PA12), MP_ROM_PTR(&pin_PA12) }, + +// Row C + { MP_ROM_QSTR(MP_QSTR_PI07), MP_ROM_PTR(&pin_PI07) }, + { MP_ROM_QSTR(MP_QSTR_PI06), MP_ROM_PTR(&pin_PI06) }, + { MP_ROM_QSTR(MP_QSTR_PI05), MP_ROM_PTR(&pin_PI05) }, + { MP_ROM_QSTR(MP_QSTR_PG09), MP_ROM_PTR(&pin_PG09) }, + { MP_ROM_QSTR(MP_QSTR_PD05), MP_ROM_PTR(&pin_PD05) }, + { MP_ROM_QSTR(MP_QSTR_PD01), MP_ROM_PTR(&pin_PD01) }, + { MP_ROM_QSTR(MP_QSTR_PI03), MP_ROM_PTR(&pin_PI03) }, + { MP_ROM_QSTR(MP_QSTR_PI02), MP_ROM_PTR(&pin_PI02) }, + { MP_ROM_QSTR(MP_QSTR_PA11), MP_ROM_PTR(&pin_PA11) }, + +// Row D + { MP_ROM_QSTR(MP_QSTR_PC13), MP_ROM_PTR(&pin_PC13) }, + { MP_ROM_QSTR(MP_QSTR_PI08), MP_ROM_PTR(&pin_PI08) }, + { MP_ROM_QSTR(MP_QSTR_PI09), MP_ROM_PTR(&pin_PI09) }, + { MP_ROM_QSTR(MP_QSTR_PI04), MP_ROM_PTR(&pin_PI04) }, + { MP_ROM_QSTR(MP_QSTR_PD04), MP_ROM_PTR(&pin_PD04) }, + { MP_ROM_QSTR(MP_QSTR_PD03), MP_ROM_PTR(&pin_PD03) }, + { MP_ROM_QSTR(MP_QSTR_PD02), MP_ROM_PTR(&pin_PD02) }, + { MP_ROM_QSTR(MP_QSTR_PH15), MP_ROM_PTR(&pin_PH15) }, + { MP_ROM_QSTR(MP_QSTR_PI01), MP_ROM_PTR(&pin_PI01) }, + { MP_ROM_QSTR(MP_QSTR_PA10), MP_ROM_PTR(&pin_PA10) }, + +// Row E +// { MP_ROM_QSTR(MP_QSTR_PC14), MP_ROM_PTR(&pin_PC14) }, + { MP_ROM_QSTR(MP_QSTR_PF00), MP_ROM_PTR(&pin_PF00) }, + { MP_ROM_QSTR(MP_QSTR_PI10), MP_ROM_PTR(&pin_PI10) }, + { MP_ROM_QSTR(MP_QSTR_PI11), MP_ROM_PTR(&pin_PI11) }, + { MP_ROM_QSTR(MP_QSTR_PH13), MP_ROM_PTR(&pin_PH13) }, + { MP_ROM_QSTR(MP_QSTR_PH14), MP_ROM_PTR(&pin_PH14) }, + { MP_ROM_QSTR(MP_QSTR_PI00), MP_ROM_PTR(&pin_PI00) }, + { MP_ROM_QSTR(MP_QSTR_PA09), MP_ROM_PTR(&pin_PA09) }, + +// Row F +// { MP_ROM_QSTR(MP_QSTR_PC15), MP_ROM_PTR(&pin_PC15) }, + { MP_ROM_QSTR(MP_QSTR_PH02), MP_ROM_PTR(&pin_PH02) }, + { MP_ROM_QSTR(MP_QSTR_PC09), MP_ROM_PTR(&pin_PC09) }, + { MP_ROM_QSTR(MP_QSTR_PA08), MP_ROM_PTR(&pin_PA08) }, + +// Row G +// { MP_ROM_QSTR(MP_QSTR_PH00), MP_ROM_PTR(&pin_PH00) }, + { MP_ROM_QSTR(MP_QSTR_PH03), MP_ROM_PTR(&pin_PH03) }, + { MP_ROM_QSTR(MP_QSTR_PC08), MP_ROM_PTR(&pin_PC08) }, + { MP_ROM_QSTR(MP_QSTR_PC07), MP_ROM_PTR(&pin_PC07) }, + +// Row H +// { MP_ROM_QSTR(MP_QSTR_PH01), MP_ROM_PTR(&pin_PH01) }, + { MP_ROM_QSTR(MP_QSTR_PF02), MP_ROM_PTR(&pin_PF02) }, + { MP_ROM_QSTR(MP_QSTR_PF01), MP_ROM_PTR(&pin_PF01) }, + { MP_ROM_QSTR(MP_QSTR_PH04), MP_ROM_PTR(&pin_PH04) }, + { MP_ROM_QSTR(MP_QSTR_PG08), MP_ROM_PTR(&pin_PG08) }, + { MP_ROM_QSTR(MP_QSTR_PC06), MP_ROM_PTR(&pin_PC06) }, + +// Row J + { MP_ROM_QSTR(MP_QSTR_PF03), MP_ROM_PTR(&pin_PF03) }, + { MP_ROM_QSTR(MP_QSTR_PF04), MP_ROM_PTR(&pin_PF04) }, + { MP_ROM_QSTR(MP_QSTR_PH05), MP_ROM_PTR(&pin_PH05) }, + { MP_ROM_QSTR(MP_QSTR_PG07), MP_ROM_PTR(&pin_PG07) }, + { MP_ROM_QSTR(MP_QSTR_PG06), MP_ROM_PTR(&pin_PG06) }, + +// Row K + { MP_ROM_QSTR(MP_QSTR_PF07), MP_ROM_PTR(&pin_PF07) }, + { MP_ROM_QSTR(MP_QSTR_PF06), MP_ROM_PTR(&pin_PF06) }, + { MP_ROM_QSTR(MP_QSTR_PF05), MP_ROM_PTR(&pin_PF05) }, + { MP_ROM_QSTR(MP_QSTR_PH12), MP_ROM_PTR(&pin_PH12) }, + { MP_ROM_QSTR(MP_QSTR_PG05), MP_ROM_PTR(&pin_PG05) }, + { MP_ROM_QSTR(MP_QSTR_PG04), MP_ROM_PTR(&pin_PG04) }, + { MP_ROM_QSTR(MP_QSTR_PG03), MP_ROM_PTR(&pin_PG03) }, + +// Row L + { MP_ROM_QSTR(MP_QSTR_PF10), MP_ROM_PTR(&pin_PF10) }, + { MP_ROM_QSTR(MP_QSTR_PF09), MP_ROM_PTR(&pin_PF09) }, + { MP_ROM_QSTR(MP_QSTR_PF08), MP_ROM_PTR(&pin_PF08) }, + { MP_ROM_QSTR(MP_QSTR_PH11), MP_ROM_PTR(&pin_PH11) }, + { MP_ROM_QSTR(MP_QSTR_PH10), MP_ROM_PTR(&pin_PH10) }, + { MP_ROM_QSTR(MP_QSTR_PD15), MP_ROM_PTR(&pin_PD15) }, + { MP_ROM_QSTR(MP_QSTR_PG02), MP_ROM_PTR(&pin_PG02) }, + +// Row M + { MP_ROM_QSTR(MP_QSTR_PC00), MP_ROM_PTR(&pin_PC00) }, + { MP_ROM_QSTR(MP_QSTR_PC01), MP_ROM_PTR(&pin_PC01) }, +// { MP_ROM_QSTR(MP_QSTR_PC02C), MP_ROM_PTR(&pin_PC02C) }, +// { MP_ROM_QSTR(MP_QSTR_PC03C), MP_ROM_PTR(&pin_PC03C) }, + { MP_ROM_QSTR(MP_QSTR_PB02), MP_ROM_PTR(&pin_PB02) }, + { MP_ROM_QSTR(MP_QSTR_PG01), MP_ROM_PTR(&pin_PG01) }, + { MP_ROM_QSTR(MP_QSTR_PH06), MP_ROM_PTR(&pin_PH06) }, + { MP_ROM_QSTR(MP_QSTR_PH08), MP_ROM_PTR(&pin_PH08) }, + { MP_ROM_QSTR(MP_QSTR_PH09), MP_ROM_PTR(&pin_PH09) }, + { MP_ROM_QSTR(MP_QSTR_PD14), MP_ROM_PTR(&pin_PD14) }, + { MP_ROM_QSTR(MP_QSTR_PD13), MP_ROM_PTR(&pin_PD13) }, + +// Row N + { MP_ROM_QSTR(MP_QSTR_PA01), MP_ROM_PTR(&pin_PA01) }, + { MP_ROM_QSTR(MP_QSTR_PA00), MP_ROM_PTR(&pin_PA00) }, + { MP_ROM_QSTR(MP_QSTR_PA04), MP_ROM_PTR(&pin_PA04) }, + { MP_ROM_QSTR(MP_QSTR_PC04), MP_ROM_PTR(&pin_PC04) }, + { MP_ROM_QSTR(MP_QSTR_PF13), MP_ROM_PTR(&pin_PF13) }, + { MP_ROM_QSTR(MP_QSTR_PG00), MP_ROM_PTR(&pin_PG00) }, + { MP_ROM_QSTR(MP_QSTR_PE13), MP_ROM_PTR(&pin_PE13) }, + { MP_ROM_QSTR(MP_QSTR_PH07), MP_ROM_PTR(&pin_PH07) }, + { MP_ROM_QSTR(MP_QSTR_PD12), MP_ROM_PTR(&pin_PD12) }, + { MP_ROM_QSTR(MP_QSTR_PD11), MP_ROM_PTR(&pin_PD11) }, + { MP_ROM_QSTR(MP_QSTR_PD10), MP_ROM_PTR(&pin_PD10) }, + +// Row P + { MP_ROM_QSTR(MP_QSTR_PA02), MP_ROM_PTR(&pin_PA02) }, + { MP_ROM_QSTR(MP_QSTR_PA06), MP_ROM_PTR(&pin_PA06) }, + { MP_ROM_QSTR(MP_QSTR_PA05), MP_ROM_PTR(&pin_PA05) }, + { MP_ROM_QSTR(MP_QSTR_PC05), MP_ROM_PTR(&pin_PC05) }, + { MP_ROM_QSTR(MP_QSTR_PF12), MP_ROM_PTR(&pin_PF12) }, + { MP_ROM_QSTR(MP_QSTR_PF15), MP_ROM_PTR(&pin_PF15) }, + { MP_ROM_QSTR(MP_QSTR_PE08), MP_ROM_PTR(&pin_PE08) }, + { MP_ROM_QSTR(MP_QSTR_PE09), MP_ROM_PTR(&pin_PE09) }, + { MP_ROM_QSTR(MP_QSTR_PE11), MP_ROM_PTR(&pin_PE11) }, + { MP_ROM_QSTR(MP_QSTR_PE14), MP_ROM_PTR(&pin_PE14) }, + { MP_ROM_QSTR(MP_QSTR_PB12), MP_ROM_PTR(&pin_PB12) }, + { MP_ROM_QSTR(MP_QSTR_PB13), MP_ROM_PTR(&pin_PB13) }, + { MP_ROM_QSTR(MP_QSTR_PD09), MP_ROM_PTR(&pin_PD09) }, + { MP_ROM_QSTR(MP_QSTR_PD08), MP_ROM_PTR(&pin_PD08) }, + +// Row R + { MP_ROM_QSTR(MP_QSTR_PA03), MP_ROM_PTR(&pin_PA03) }, + { MP_ROM_QSTR(MP_QSTR_PA07), MP_ROM_PTR(&pin_PA07) }, + { MP_ROM_QSTR(MP_QSTR_PB01), MP_ROM_PTR(&pin_PB01) }, + { MP_ROM_QSTR(MP_QSTR_PB00), MP_ROM_PTR(&pin_PB00) }, + { MP_ROM_QSTR(MP_QSTR_PF11), MP_ROM_PTR(&pin_PF11) }, + { MP_ROM_QSTR(MP_QSTR_PF14), MP_ROM_PTR(&pin_PF14) }, + { MP_ROM_QSTR(MP_QSTR_PE07), MP_ROM_PTR(&pin_PE07) }, + { MP_ROM_QSTR(MP_QSTR_PE10), MP_ROM_PTR(&pin_PE10) }, + { MP_ROM_QSTR(MP_QSTR_PE12), MP_ROM_PTR(&pin_PE12) }, + { MP_ROM_QSTR(MP_QSTR_PE15), MP_ROM_PTR(&pin_PE15) }, + { MP_ROM_QSTR(MP_QSTR_PB10), MP_ROM_PTR(&pin_PB10) }, + { MP_ROM_QSTR(MP_QSTR_PB11), MP_ROM_PTR(&pin_PB11) }, + { MP_ROM_QSTR(MP_QSTR_PB14), MP_ROM_PTR(&pin_PB14) }, + { MP_ROM_QSTR(MP_QSTR_PB15), MP_ROM_PTR(&pin_PB15) }, + +}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table); diff --git a/ports/stm/peripherals/periph.h b/ports/stm/peripherals/periph.h index 438db793867..24ed9966a0a 100644 --- a/ports/stm/peripherals/periph.h +++ b/ports/stm/peripherals/periph.h @@ -30,7 +30,7 @@ typedef struct { // Timer Peripheral typedef struct { - uint8_t tim_index : 4; + uint8_t tim_index : 5; uint8_t altfn_index : 4; uint8_t channel_index : 4; const mcu_pin_obj_t *pin; @@ -84,6 +84,13 @@ typedef struct { #include "stm32l4/stm32l4r5xx/periph.h" #endif +#ifdef STM32L433xx +#define HAS_DAC 1 +#define HAS_TRNG 1 +#define HAS_BASIC_TIM 1 +#include "stm32l4/stm32l433xx/periph.h" +#endif + #ifdef STM32F405xx #define HAS_DAC 1 #define HAS_TRNG 1 @@ -130,3 +137,14 @@ typedef struct { #define HAS_BASIC_TIM 0 #include "stm32h7/stm32h743xx/periph.h" #endif + +#ifdef STM32H750xx +#define HAS_DAC 1 +#define HAS_TRNG 1 +#define HAS_BASIC_TIM 1 +#include "stm32h7/stm32h750xx/periph.h" +#endif + +#if !defined(HAS_DAC) +#error Unknown MCU +#endif diff --git a/ports/stm/peripherals/pins.h b/ports/stm/peripherals/pins.h index 999f8172d97..42ddefdc406 100644 --- a/ports/stm/peripherals/pins.h +++ b/ports/stm/peripherals/pins.h @@ -70,6 +70,9 @@ extern const mp_obj_type_t mcu_pin_type; #ifdef STM32L4R5xx #include "stm32l4/stm32l4r5xx/pins.h" #endif +#ifdef STM32L433xx +#include "stm32l4/stm32l433xx/pins.h" +#endif #ifdef STM32F405xx #include "stm32f4/stm32f405xx/pins.h" #endif @@ -92,3 +95,7 @@ extern const mp_obj_type_t mcu_pin_type; #ifdef STM32H743xx #include "stm32h7/stm32h743xx/pins.h" #endif + +#ifdef STM32H750xx +#include "stm32h7/stm32h750xx/pins.h" +#endif diff --git a/ports/stm/peripherals/sdram.c b/ports/stm/peripherals/sdram.c new file mode 100644 index 00000000000..6179197fa95 --- /dev/null +++ b/ports/stm/peripherals/sdram.c @@ -0,0 +1,293 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 snkYmkrct +// +// based on implementation from https://github.com/micropython/micropython/blob/master/ports/stm32/sdram.c +// +// SPDX-License-Identifier: MIT + +#include +#include +#include +#include +#include STM32_HAL_H +#include "common-hal/microcontroller/Pin.h" +#include "peripherals/periph.h" +#if defined(STM32H7) +#include "stm32h7xx_ll_fmc.h" +#include "stm32h7xx_hal_sdram.h" +#include "stm32h7xx_hal_gpio.h" +#include "stm32h7xx_hal_cortex.h" +#endif +#ifdef STM32H750xx +#include "stm32h7/stm32h750xx/periph.h" +#endif + + +#include "sdram.h" + + +#if MICROPY_DEBUG_VERBOSE // print debugging info +#define DEBUG_PRINT (1) +#define DEBUG_printf DEBUG_printf +#define DEBUG_OP_printf(...) DEBUG_printf(__VA_ARGS__) +#else // don't print debugging info +#define DEBUG_printf(...) (void)0 +#define DEBUG_OP_printf(...) (void)0 +#endif + +#define SDRAM_TIMEOUT ((uint32_t)0xFFFF) +#define CIRCUITPY_HW_SDRAM_STARTUP_TEST (0) + +static uint8_t FMC_Initialized = 0; +static SDRAM_HandleTypeDef hsdram = {0}; +static uint32_t sdram_start_address = 0; + + +static void sdram_init_seq(const struct stm32_sdram_config *config); + +void sdram_init(const struct stm32_sdram_config *config) { + FMC_SDRAM_TimingTypeDef SDRAM_Timing = {0}; + + if (!FMC_Initialized) { + + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + + /** Initializes the peripherals clock + */ + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC; + PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + DEBUG_printf("sdram: %s", "periph init clock error"); + } + /* Peripheral clock enable */ + __HAL_RCC_FMC_CLK_ENABLE(); + FMC_Initialized = 1; + for (uint i = 0; i < MP_ARRAY_SIZE(sdram_pin_list); i++) { + GPIO_InitTypeDef GPIO_InitStruct = {0}; + GPIO_InitStruct.Pin = pin_mask(sdram_pin_list[i].pin->number); + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FMC; + HAL_GPIO_Init(pin_port(sdram_pin_list[i].pin->port), &GPIO_InitStruct); + never_reset_pin_number(sdram_pin_list[i].pin->port, sdram_pin_list[i].pin->number); + } + } + + /* SDRAM device configuration */ + hsdram.Instance = config->sdram; + + for (size_t i = 0U; i < config->banks_len; i++) { + hsdram.State = HAL_SDRAM_STATE_RESET; + + memcpy(&hsdram.Init, &config->banks[i].init, sizeof(hsdram.Init)); + + memcpy(&SDRAM_Timing, &config->banks[i].timing, sizeof(SDRAM_Timing)); + + /* Initialize the SDRAM controller */ + if (HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK) { + DEBUG_printf("sdram bank[%d]: %s", i, "init error"); + } + } + + sdram_init_seq(config); + +} +void sdram_deinit(void) { + FMC_SDRAM_CommandTypeDef command = {0}; + if (FMC_Initialized) { + /* Send the module into powerdown mode */ + command.CommandMode = FMC_SDRAM_CMD_POWERDOWN_MODE; + command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + command.AutoRefreshNumber = 1; + command.ModeRegisterDefinition = 0; + + /* Send the command */ + if (HAL_SDRAM_SendCommand(&hsdram, &command, HAL_MAX_DELAY) != HAL_OK) { + DEBUG_printf("sdram power off error:%s:%d", __func__, __LINE__); + } + } +} + +void *sdram_start(void) { + return (void *)sdram_start_address; +} + +void *sdram_end(void) { + return (void *)(sdram_start_address + CIRCUITPY_HW_SDRAM_SIZE); +} + +uint32_t sdram_size(void) { + return CIRCUITPY_HW_SDRAM_SIZE; +} + +static void sdram_init_seq(const struct stm32_sdram_config *config) { + FMC_SDRAM_CommandTypeDef command = {0}; + /* Program the SDRAM external device */ + + command.AutoRefreshNumber = config->num_auto_refresh; + command.ModeRegisterDefinition = config->mode_register; + if (config->banks_len == 2U) { + command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1_2; + sdram_start_address = 0xC0000000; + } else if (config->banks[0].init.SDBank == FMC_SDRAM_BANK1) { + command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1; + sdram_start_address = 0xC0000000; + } else { + command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2; + sdram_start_address = 0xD0000000; + + } + + /* Configure a clock configuration enable command */ + command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE; + HAL_SDRAM_SendCommand(&hsdram, &command, HAL_MAX_DELAY); + + HAL_Delay(config->power_up_delay); + + /* Configure a PALL (precharge all) command */ + command.CommandMode = FMC_SDRAM_CMD_PALL; + HAL_SDRAM_SendCommand(&hsdram, &command, HAL_MAX_DELAY); + + /* Configure a Auto-Refresh command */ + command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE; + HAL_SDRAM_SendCommand(&hsdram, &command, HAL_MAX_DELAY); + + command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE; + /* load mode */ + HAL_SDRAM_SendCommand(&hsdram, &command, HAL_MAX_DELAY); + + /* program refresh count */ + HAL_SDRAM_ProgramRefreshRate(&hsdram, config->refresh_rate); + + #if defined(STM32F7) || defined(STM32H7) + __disable_irq(); + MPU_Region_InitTypeDef MPU_InitStruct = {0}; + /** Enable caching for SDRAM to support non-alligned access. + */ + MPU_InitStruct.Enable = MPU_REGION_ENABLE; + MPU_InitStruct.Number = CPY_SDRAM_REGION; + MPU_InitStruct.BaseAddress = sdram_start_address; + MPU_InitStruct.Size = CPY_SDRAM_REGION_SIZE; + MPU_InitStruct.SubRegionDisable = 0x0; + MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1; + MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS; + MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; + MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; + MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; + MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; + + HAL_MPU_ConfigRegion(&MPU_InitStruct); + __ISB(); + __DSB(); + __DMB(); + __enable_irq(); + + #endif + +} + +#if defined(CIRCUITPY_HW_SDRAM_STARTUP_TEST) && (CIRCUITPY_HW_SDRAM_STARTUP_TEST == 1) + +bool __attribute__((optimize("Os"))) sdram_test(bool exhaustive) { + uint8_t const pattern = 0xaa; + uint8_t const antipattern = 0x55; + volatile uint8_t *const mem_base = (uint8_t *)sdram_start(); + + char error_buffer[1024]; + + DEBUG_printf("sdram: %s\n", "sdram test started"); + + #if (__DCACHE_PRESENT == 1) + bool i_cache_disabled = false; + bool d_cache_disabled = false; + + // Disable caches for testing. + if (SCB->CCR & (uint32_t)SCB_CCR_IC_Msk) { + SCB_DisableICache(); + i_cache_disabled = true; + } + + if (SCB->CCR & (uint32_t)SCB_CCR_DC_Msk) { + SCB_DisableDCache(); + d_cache_disabled = true; + } + #endif + + // Test data bus + for (uint32_t i = 0; i < hsdram.Init.MemoryDataWidth; i++) { + *((volatile uint32_t *)mem_base) = (1u << i); + __DSB(); + if (*((volatile uint32_t *)mem_base) != (1u << i)) { + snprintf(error_buffer, sizeof(error_buffer), + "Data bus test failed at 0x%p expected 0x%x found 0x%lx", + &mem_base[0], (1 << i), ((volatile uint32_t *)mem_base)[0]); + DEBUG_printf("error: %s\n", error_buffer); + return false; + } + } + + // Test address bus + for (uint32_t i = 1; i < CIRCUITPY_HW_SDRAM_SIZE; i <<= 1) { + mem_base[i] = pattern; + __DSB(); + if (mem_base[i] != pattern) { + snprintf(error_buffer, sizeof(error_buffer), + "Address bus test failed at 0x%p expected 0x%x found 0x%x", + &mem_base[i], pattern, mem_base[i]); + DEBUG_printf("error: %s\n", error_buffer); + return false; + } + } + + // Check for aliasing (overlapping addresses) + mem_base[0] = antipattern; + __DSB(); + for (uint32_t i = 1; i < CIRCUITPY_HW_SDRAM_SIZE; i <<= 1) { + if (mem_base[i] != pattern) { + snprintf(error_buffer, sizeof(error_buffer), + "Address bus overlap at 0x%p expected 0x%x found 0x%x", + &mem_base[i], pattern, mem_base[i]); + DEBUG_printf("error: %s\n", error_buffer); + return false; + } + } + + // Test all RAM cells + if (exhaustive) { + // Write all memory first then compare, so even if the cache + // is enabled, it's not just writing and reading from cache. + // Note: This test should also detect refresh rate issues. + for (uint32_t i = 0; i < CIRCUITPY_HW_SDRAM_SIZE; i++) { + mem_base[i] = ((i % 2) ? pattern : antipattern); + } + + for (uint32_t i = 0; i < CIRCUITPY_HW_SDRAM_SIZE; i++) { + if (mem_base[i] != ((i % 2) ? pattern : antipattern)) { + snprintf(error_buffer, sizeof(error_buffer), + "Address bus slow test failed at 0x%p expected 0x%x found 0x%x", + &mem_base[i], ((i % 2) ? pattern : antipattern), mem_base[i]); + DEBUG_printf("error: %s\n", error_buffer); + return false; + } + } + } + + #if (__DCACHE_PRESENT == 1) + // Re-enable caches if they were enabled before the test started. + if (i_cache_disabled) { + SCB_EnableICache(); + } + + if (d_cache_disabled) { + SCB_EnableDCache(); + } + #endif + + DEBUG_printf("sdram: %s\n", "sdram test successfully!"); + + return true; +} + +#endif // sdram_test diff --git a/ports/stm/peripherals/sdram.h b/ports/stm/peripherals/sdram.h new file mode 100644 index 00000000000..46343b6861e --- /dev/null +++ b/ports/stm/peripherals/sdram.h @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "stm32h7xx_ll_fmc.h" +#include +#include + +#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001) +#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002) +#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004) +#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000) +#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008) +#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020) +#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030) +#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000) +#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200) + +/** FMC SDRAM controller bank configuration fields. */ +struct stm32_sdram_bank_config { + FMC_SDRAM_InitTypeDef init; + FMC_SDRAM_TimingTypeDef timing; +}; + +/** FMC SDRAM controller configuration fields. */ +struct stm32_sdram_config { + FMC_SDRAM_TypeDef *sdram; + uint32_t power_up_delay; + uint8_t num_auto_refresh; + uint16_t mode_register; + uint16_t refresh_rate; + const struct stm32_sdram_bank_config *banks; + size_t banks_len; +}; + +void sdram_init(const struct stm32_sdram_config *config); +void sdram_deinit(void); +void *sdram_start(void); +void *sdram_end(void); +uint32_t sdram_size(void); +bool sdram_test(bool exhaustive); diff --git a/ports/stm/peripherals/stm32h7/clocks.c b/ports/stm/peripherals/stm32h7/clocks.c index 8c63031859c..717840040db 100644 --- a/ports/stm/peripherals/stm32h7/clocks.c +++ b/ports/stm/peripherals/stm32h7/clocks.c @@ -13,6 +13,10 @@ #include "stm32h7/stm32h743xx/clocks.h" #endif +#ifdef STM32H750xx +#include "stm32h7/stm32h750xx/clocks.h" +#endif + void stm32_peripherals_clocks_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; @@ -42,16 +46,16 @@ void stm32_peripherals_clocks_init(void) { RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; #endif RCC_OscInitStruct.HSEState = BOARD_HSE_SOURCE; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLM = HSE_VALUE / 2000000; + RCC_OscInitStruct.PLL.PLLState = BOARD_PLL_STATE; + RCC_OscInitStruct.PLL.PLLSource = BOARD_PLL_SOURCE; + RCC_OscInitStruct.PLL.PLLM = CPY_CLK_PLLM; RCC_OscInitStruct.PLL.PLLN = CPY_CLK_PLLN; RCC_OscInitStruct.PLL.PLLP = CPY_CLK_PLLP; RCC_OscInitStruct.PLL.PLLQ = CPY_CLK_PLLQ; - RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLFRACN = 0; + RCC_OscInitStruct.PLL.PLLR = CPY_CLK_PLLR; + RCC_OscInitStruct.PLL.PLLRGE = CPY_CLK_PLLRGE; + RCC_OscInitStruct.PLL.PLLVCOSEL = CPY_CLK_PLLVCOSEL; + RCC_OscInitStruct.PLL.PLLFRACN = CPY_CLK_PLLFRACN; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { // Clock issues are too problematic to even attempt recovery. // If you end up here, check whether your LSE settings match your board. @@ -88,8 +92,28 @@ void stm32_peripherals_clocks_init(void) { #else PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL; #endif - HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); - + #ifdef STM32H750xx + // USB + PeriphClkInitStruct.PLL3.PLL3M = 1; + PeriphClkInitStruct.PLL3.PLL3N = 12; + PeriphClkInitStruct.PLL3.PLL3P = 2; + PeriphClkInitStruct.PLL3.PLL3Q = 4; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_3; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + // RNG + PeriphClkInitStruct.PeriphClockSelection = PeriphClkInitStruct.PeriphClockSelection | RCC_PERIPHCLK_RNG; + PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_HSI48; + // RTC + PeriphClkInitStruct.PeriphClockSelection = PeriphClkInitStruct.PeriphClockSelection | RCC_PERIPHCLK_RTC; + PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; + #endif + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + while (1) { + ; + } + } // Enable USB Voltage detector HAL_PWREx_EnableUSBVoltageDetector(); } diff --git a/ports/stm/peripherals/stm32h7/stm32h743xx/clocks.h b/ports/stm/peripherals/stm32h7/stm32h743xx/clocks.h index 56bb598ab74..d59e51686de 100644 --- a/ports/stm/peripherals/stm32h7/stm32h743xx/clocks.h +++ b/ports/stm/peripherals/stm32h7/stm32h743xx/clocks.h @@ -16,6 +16,9 @@ #ifndef CPY_CLK_VSCALE #define CPY_CLK_VSCALE (PWR_REGULATOR_VOLTAGE_SCALE0) #endif +#ifndef CPY_CLK_PLLM +#define CPY_CLK_PLLM (HSE_VALUE / 2000000) +#endif #ifndef CPY_CLK_PLLN #define CPY_CLK_PLLN (480) #endif @@ -25,6 +28,18 @@ #ifndef CPY_CLK_PLLQ #define CPY_CLK_PLLQ (20) #endif +#ifndef CPY_CLK_PLLR +#define CPY_CLK_PLLR (2) +#endif +#ifndef CPY_CLK_PLLRGE +#define CPY_CLK_PLLRGE (RCC_PLL1VCIRANGE_1) +#endif +#ifndef CPY_CLK_PLLVCOSEL +#define CPY_CLK_PLLVCOSEL (RCC_PLL1VCOWIDE) +#endif +#ifndef CPY_CLK_PLLFRACN +#define CPY_CLK_PLLFRACN (0) +#endif #ifndef CPY_CLK_AHBDIV #define CPY_CLK_AHBDIV (RCC_HCLK_DIV2) #endif @@ -49,3 +64,9 @@ #ifndef BOARD_HSE_SOURCE #define BOARD_HSE_SOURCE (RCC_HSE_ON) #endif +#ifndef BOARD_PLL_STATE +#define BOARD_PLL_STATE (RCC_PLL_ON) +#endif +#ifndef BOARD_PLL_SOURCE +#define BOARD_PLL_SOURCE (RCC_PLLSOURCE_HSE) +#endif diff --git a/ports/stm/peripherals/stm32h7/stm32h743xx/periph.h b/ports/stm/peripherals/stm32h7/stm32h743xx/periph.h index fa4ec7f6e56..2ff49c8503c 100644 --- a/ports/stm/peripherals/stm32h7/stm32h743xx/periph.h +++ b/ports/stm/peripherals/stm32h7/stm32h743xx/periph.h @@ -30,3 +30,4 @@ extern const mcu_periph_obj_t mcu_uart_rx_list[26]; #define TIM_BANK_ARRAY_LEN 14 #define TIM_PIN_ARRAY_LEN 58 extern TIM_TypeDef *mcu_tim_banks[TIM_BANK_ARRAY_LEN]; +extern const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN]; diff --git a/ports/stm/peripherals/stm32h7/stm32h750xx/clocks.h b/ports/stm/peripherals/stm32h7/stm32h750xx/clocks.h new file mode 100644 index 00000000000..25f4d9cc9a0 --- /dev/null +++ b/ports/stm/peripherals/stm32h7/stm32h750xx/clocks.h @@ -0,0 +1,70 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#include "stm32h7xx_hal.h" + +// Chip: STM32H750 +// Line Type: Single-Core +// Speed: 480MHz (MAX) + +// Defaults: +#ifndef CPY_CLK_VSCALE +#define CPY_CLK_VSCALE (PWR_REGULATOR_VOLTAGE_SCALE0) +#endif +#ifndef CPY_CLK_PLLM +#define CPY_CLK_PLLM (1) +#endif +#ifndef CPY_CLK_PLLN +#define CPY_CLK_PLLN (50) +#endif +#ifndef CPY_CLK_PLLP +#define CPY_CLK_PLLP (2) +#endif +#ifndef CPY_CLK_PLLQ +#define CPY_CLK_PLLQ (4) +#endif +#ifndef CPY_CLK_PLLR +#define CPY_CLK_PLLR (2) +#endif +#ifndef CPY_CLK_PLLRGE +#define CPY_CLK_PLLRGE (RCC_PLL1VCIRANGE_3) +#endif +#ifndef CPY_CLK_PLLVCOSEL +#define CPY_CLK_PLLVCOSEL (RCC_PLL1VCOWIDE) +#endif +#ifndef CPY_CLK_PLLFRACN +#define CPY_CLK_PLLFRACN (0) +#endif +#ifndef CPY_CLK_AHBDIV +#define CPY_CLK_AHBDIV (RCC_HCLK_DIV2) +#endif +#ifndef CPY_CLK_APB1DIV +#define CPY_CLK_APB1DIV (RCC_APB1_DIV2) +#endif +#ifndef CPY_CLK_APB2DIV +#define CPY_CLK_APB2DIV (RCC_APB2_DIV2) +#endif +#ifndef CPY_CLK_APB3DIV +#define CPY_CLK_APB3DIV (RCC_APB3_DIV2) +#endif +#ifndef CPY_CLK_APB4DIV +#define CPY_CLK_APB4DIV (RCC_APB4_DIV2) +#endif +#ifndef CPY_CLK_FLASH_LATENCY +#define CPY_CLK_FLASH_LATENCY (FLASH_LATENCY_2) +#endif +#ifndef CPY_CLK_USB_USES_AUDIOPLL +#define CPY_CLK_USB_USES_AUDIOPLL (0) +#endif +#ifndef BOARD_HSE_SOURCE +#define BOARD_HSE_SOURCE (RCC_HSE_ON) +#endif +#ifndef BOARD_PLL_STATE +#define BOARD_PLL_STATE (RCC_PLL_ON) +#endif +#ifndef BOARD_PLL_SOURCE +#define BOARD_PLL_SOURCE (RCC_PLLSOURCE_HSE) +#endif diff --git a/ports/stm/peripherals/stm32h7/stm32h750xx/gpio.c b/ports/stm/peripherals/stm32h7/stm32h750xx/gpio.c new file mode 100644 index 00000000000..f5ad843c9a6 --- /dev/null +++ b/ports/stm/peripherals/stm32h7/stm32h750xx/gpio.c @@ -0,0 +1,35 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#include "gpio.h" +#include "common-hal/microcontroller/Pin.h" + +void stm32_peripherals_gpio_init(void) { + // Enable all GPIO for now + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOI_CLK_ENABLE(); + +// Never reset pins + never_reset_pin_number(7, 0); // PH00 OSC32_IN + never_reset_pin_number(7, 1); // PH01 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK + // qspi flash pins for the Daisy Seed -- TODO ? + never_reset_pin_number(5, 6); // PF06 QSPI IO3 + never_reset_pin_number(5, 7); // PF07 QSPI IO2 + never_reset_pin_number(5, 8); // PF08 QSPI IO0 + never_reset_pin_number(5, 9); // PF09 QSPI IO1 + never_reset_pin_number(5, 10); // PF10 QSPI CLK + never_reset_pin_number(6, 6); // PG06 QSPI NCS + +} diff --git a/ports/stm/peripherals/stm32h7/stm32h750xx/periph.c b/ports/stm/peripherals/stm32h7/stm32h750xx/periph.c new file mode 100644 index 00000000000..023e06ee322 --- /dev/null +++ b/ports/stm/peripherals/stm32h7/stm32h750xx/periph.c @@ -0,0 +1,385 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/mphal.h" +#include "peripherals/pins.h" +#include "peripherals/periph.h" + +// See alternate functions tables in the STM32H750xx datasheet + +// I2C +I2C_TypeDef *mcu_i2c_banks[MAX_I2C] = {I2C1, I2C2, I2C3, I2C4}; + +const mcu_periph_obj_t mcu_i2c_sda_list[12] = { + PERIPH(1, 4, &pin_PB07), + PERIPH(4, 6, &pin_PB07), + PERIPH(1, 4, &pin_PB09), + PERIPH(4, 6, &pin_PB09), + PERIPH(2, 4, &pin_PB11), + PERIPH(3, 4, &pin_PC09), + PERIPH(4, 4, &pin_PD13), + PERIPH(2, 4, &pin_PF00), + PERIPH(4, 4, &pin_PF15), + PERIPH(2, 4, &pin_PH05), + PERIPH(3, 4, &pin_PH08), + PERIPH(4, 4, &pin_PH12) +}; + +const mcu_periph_obj_t mcu_i2c_scl_list[12] = { + PERIPH(3, 4, &pin_PA08), + PERIPH(1, 4, &pin_PB06), + PERIPH(4, 6, &pin_PB06), + PERIPH(1, 4, &pin_PB08), + PERIPH(4, 6, &pin_PB08), + PERIPH(2, 4, &pin_PB10), + PERIPH(4, 4, &pin_PD12), + PERIPH(2, 4, &pin_PF01), + PERIPH(4, 4, &pin_PF14), + PERIPH(2, 4, &pin_PH04), + PERIPH(3, 4, &pin_PH07), + PERIPH(4, 4, &pin_PH11) +}; + +// SPI + +SPI_TypeDef *mcu_spi_banks[MAX_SPI] = {SPI1, SPI2, SPI3, SPI4, SPI5, SPI6}; + +const mcu_periph_obj_t mcu_spi_sck_list[18] = { + PERIPH(1, 5, &pin_PA05), + PERIPH(6, 8, &pin_PA05), + PERIPH(2, 5, &pin_PA09), + PERIPH(2, 5, &pin_PA12), + PERIPH(1, 5, &pin_PB03), + PERIPH(3, 6, &pin_PB03), + PERIPH(6, 8, &pin_PB03), + PERIPH(2, 5, &pin_PB10), + PERIPH(2, 5, &pin_PB13), + PERIPH(3, 6, &pin_PC10), + PERIPH(2, 5, &pin_PD03), + PERIPH(4, 5, &pin_PE02), + PERIPH(4, 5, &pin_PE12), + PERIPH(5, 5, &pin_PF07), + PERIPH(1, 5, &pin_PG11), + PERIPH(6, 5, &pin_PG13), + PERIPH(5, 5, &pin_PH06), + PERIPH(2, 5, &pin_PI01), +}; + +const mcu_periph_obj_t mcu_spi_mosi_list[18] = { + PERIPH(1, 5, &pin_PA07), + PERIPH(6, 8, &pin_PA07), + PERIPH(3, 7, &pin_PB02), + PERIPH(1, 5, &pin_PB05), + PERIPH(3, 7, &pin_PB05), + PERIPH(6, 8, &pin_PB05), + PERIPH(2, 5, &pin_PB15), + PERIPH(2, 5, &pin_PC01), + PERIPH(2, 5, &pin_PC03), + PERIPH(3, 6, &pin_PC12), + PERIPH(3, 5, &pin_PD06), + PERIPH(1, 5, &pin_PD07), + PERIPH(4, 5, &pin_PE06), + PERIPH(4, 5, &pin_PE14), + PERIPH(5, 5, &pin_PF09), + PERIPH(5, 5, &pin_PF11), + PERIPH(6, 5, &pin_PG14), + PERIPH(2, 5, &pin_PI03), +}; + +const mcu_periph_obj_t mcu_spi_miso_list[15] = { + PERIPH(1, 5, &pin_PA06), + PERIPH(6, 8, &pin_PA06), + PERIPH(1, 5, &pin_PB04), + PERIPH(3, 6, &pin_PB04), + PERIPH(6, 8, &pin_PB04), + PERIPH(2, 5, &pin_PB14), + PERIPH(2, 5, &pin_PC02), + PERIPH(3, 6, &pin_PC11), + PERIPH(4, 5, &pin_PE05), + PERIPH(4, 5, &pin_PE13), + PERIPH(5, 5, &pin_PF08), + PERIPH(1, 5, &pin_PG09), + PERIPH(6, 5, &pin_PG12), + PERIPH(5, 5, &pin_PH07), + PERIPH(2, 5, &pin_PI02), +}; + +// UART + +USART_TypeDef *mcu_uart_banks[MAX_UART] = {USART1, USART2, USART3, UART4, UART5, USART6, UART7, UART8}; +// circuitpython doesn't implement USART +// bool mcu_uart_has_usart[MAX_UART] = {true, true, true, false, false, true, false, false, false}; + +const mcu_periph_obj_t mcu_uart_tx_list[24] = { + PERIPH(4, 8, &pin_PA00), + PERIPH(2, 7, &pin_PA02), + PERIPH(1, 7, &pin_PA09), + PERIPH(4, 6, &pin_PA12), + PERIPH(7, 11, &pin_PA15), + PERIPH(7, 11, &pin_PB04), + PERIPH(1, 7, &pin_PB06), + PERIPH(5, 14, &pin_PB06), + PERIPH(4, 8, &pin_PB09), + PERIPH(3, 7, &pin_PB10), + PERIPH(5, 14, &pin_PB13), + PERIPH(1, 4, &pin_PB14), + PERIPH(6, 7, &pin_PC06), + PERIPH(3, 7, &pin_PC10), + PERIPH(4, 8, &pin_PC10), + PERIPH(5, 8, &pin_PC12), + PERIPH(4, 8, &pin_PD01), + PERIPH(2, 7, &pin_PD05), + PERIPH(3, 7, &pin_PD08), + PERIPH(8, 8, &pin_PE01), + PERIPH(7, 7, &pin_PE08), + PERIPH(7, 7, &pin_PF07), + PERIPH(6, 7, &pin_PG14), + PERIPH(4, 8, &pin_PH13), +}; + +const mcu_periph_obj_t mcu_uart_rx_list[25] = { + PERIPH(4, 8, &pin_PA01), + PERIPH(2, 7, &pin_PA03), + PERIPH(7, 11, &pin_PA08), + PERIPH(1, 7, &pin_PA10), + PERIPH(4, 6, &pin_PA11), + PERIPH(7, 11, &pin_PB03), + PERIPH(5, 14, &pin_PB05), + PERIPH(1, 7, &pin_PB07), + PERIPH(4, 8, &pin_PB08), + PERIPH(3, 7, &pin_PB11), + PERIPH(5, 14, &pin_PB12), + PERIPH(1, 4, &pin_PB15), + PERIPH(6, 7, &pin_PC07), + PERIPH(3, 7, &pin_PC11), + PERIPH(4, 8, &pin_PC11), + PERIPH(4, 8, &pin_PD00), + PERIPH(5, 8, &pin_PD02), + PERIPH(2, 7, &pin_PD06), + PERIPH(3, 7, &pin_PD09), + PERIPH(8, 8, &pin_PE00), + PERIPH(7, 7, &pin_PE07), + PERIPH(7, 7, &pin_PF06), + PERIPH(6, 7, &pin_PG09), + PERIPH(4, 8, &pin_PH14), + PERIPH(4, 8, &pin_PI09), +}; + +// Timers +// TIM6 and TIM7 are basic timers that are only used by DAC, and don't have pins +TIM_TypeDef *mcu_tim_banks[TIM_BANK_ARRAY_LEN] = {TIM1, TIM2, TIM3, TIM4, TIM5, NULL, NULL, TIM8, + NULL, NULL, NULL, TIM12, TIM13, TIM14, TIM15, TIM16, TIM17}; +const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN] = { + TIM(2, 1, 1, &pin_PA00), + TIM(5, 2, 1, &pin_PA00), + TIM(2, 1, 2, &pin_PA01), + TIM(5, 2, 2, &pin_PA01), + TIM(2, 1, 3, &pin_PA02), + TIM(5, 2, 3, &pin_PA02), + TIM(15, 4, 1, &pin_PA02), + TIM(2, 1, 4, &pin_PA03), + TIM(5, 2, 4, &pin_PA03), + TIM(15, 4, 2, &pin_PA03), + TIM(2, 1, 1, &pin_PA05), + TIM(3, 2, 1, &pin_PA06), + TIM(13, 9, 1, &pin_PA06), + TIM(3, 2, 2, &pin_PA07), + TIM(14, 9, 1, &pin_PA07), + TIM(1, 1, 1, &pin_PA08), + TIM(1, 1, 2, &pin_PA09), + TIM(1, 1, 3, &pin_PA10), + TIM(1, 1, 4, &pin_PA11), + TIM(2, 1, 1, &pin_PA15), + TIM(3, 2, 3, &pin_PB00), + TIM(3, 2, 4, &pin_PB01), + TIM(2, 1, 2, &pin_PB03), + TIM(3, 2, 1, &pin_PB04), + TIM(3, 2, 2, &pin_PB05), + TIM(4, 2, 1, &pin_PB06), + TIM(4, 2, 2, &pin_PB07), + TIM(4, 2, 3, &pin_PB08), + TIM(4, 2, 4, &pin_PB09), + TIM(2, 1, 3, &pin_PB10), + TIM(2, 1, 4, &pin_PB11), + TIM(12, 2, 1, &pin_PB14), + TIM(12, 2, 2, &pin_PB15), + TIM(3, 2, 1, &pin_PC06), + TIM(8, 3, 1, &pin_PC06), + TIM(3, 2, 2, &pin_PC07), + TIM(8, 3, 2, &pin_PC07), + TIM(3, 2, 3, &pin_PC08), + TIM(8, 3, 3, &pin_PC08), + TIM(3, 2, 4, &pin_PC09), + TIM(8, 3, 4, &pin_PC09), + TIM(4, 2, 1, &pin_PD12), + TIM(4, 2, 2, &pin_PD13), + TIM(4, 2, 3, &pin_PD14), + TIM(4, 2, 4, &pin_PD15), + TIM(15, 4, 1, &pin_PE05), + TIM(15, 4, 2, &pin_PE06), + TIM(1, 1, 1, &pin_PE09), + TIM(1, 1, 2, &pin_PE11), + TIM(1, 1, 3, &pin_PE13), + TIM(1, 1, 4, &pin_PE14), + TIM(16, 1, 1, &pin_PF06), + TIM(17, 1, 1, &pin_PF07), + TIM(13, 9, 1, &pin_PF08), + TIM(14, 9, 1, &pin_PF09), + TIM(12, 2, 1, &pin_PH06), + TIM(12, 2, 2, &pin_PH09), + TIM(5, 2, 1, &pin_PH10), + TIM(5, 2, 2, &pin_PH11), + TIM(5, 2, 3, &pin_PH12), + TIM(5, 2, 4, &pin_PI00), + TIM(8, 3, 4, &pin_PI02), + TIM(8, 3, 1, &pin_PI05), + TIM(8, 3, 2, &pin_PI06), + TIM(8, 3, 3, &pin_PI07), +}; + +// SDIO - H750 has a MMC interface that includes SDIO +SDMMC_TypeDef *mcu_sdio_banks[1] = {SDMMC1}; + +const mcu_periph_obj_t mcu_sdio_clock_list[1] = { + PERIPH(1, 12, &pin_PC12), +}; +const mcu_periph_obj_t mcu_sdio_command_list[1] = { + PERIPH(1, 12, &pin_PD02), +}; +const mcu_periph_obj_t mcu_sdio_data0_list[1] = { + PERIPH(1, 12, &pin_PC08), +}; +const mcu_periph_obj_t mcu_sdio_data1_list[1] = { + PERIPH(1, 12, &pin_PC09), +}; +const mcu_periph_obj_t mcu_sdio_data2_list[1] = { + PERIPH(1, 12, &pin_PC10), +}; +const mcu_periph_obj_t mcu_sdio_data3_list[1] = { + PERIPH(1, 12, &pin_PC11), +}; + + +/** FMC GPIO Configuration + PE1 ------> FMC_NBL1 + PE0 ------> FMC_NBL0 + PG15 ------> FMC_SDNCAS + PD0 ------> FMC_D2 + PI7 ------> FMC_D29 + PI6 ------> FMC_D28 + PI5 ------> FMC_NBL3 + PD1 ------> FMC_D3 + PI3 ------> FMC_D27 + PI2 ------> FMC_D26 + PI9 ------> FMC_D30 + PI4 ------> FMC_NBL2 + PH15 ------> FMC_D23 + PI1 ------> FMC_D25 + PF0 ------> FMC_A0 + PI10 ------> FMC_D31 + PH13 ------> FMC_D21 + PH14 ------> FMC_D22 + PI0 ------> FMC_D24 + PH2 ------> FMC_SDCKE0 + PH3 ------> FMC_SDNE0 + PF2 ------> FMC_A2 + PF1 ------> FMC_A1 + PG8 ------> FMC_SDCLK + PF3 ------> FMC_A3 + PF4 ------> FMC_A4 + PH5 ------> FMC_SDNWE + PF5 ------> FMC_A5 + PH12 ------> FMC_D20 + PG5 ------> FMC_BA1 + PG4 ------> FMC_BA0 + PH11 ------> FMC_D19 + PH10 ------> FMC_D18 + PD15 ------> FMC_D1 + PG2 ------> FMC_A12 + PG1 ------> FMC_A11 + PH8 ------> FMC_D16 + PH9 ------> FMC_D17 + PD14 ------> FMC_D0 + PF13 ------> FMC_A7 + PG0 ------> FMC_A10 + PE13 ------> FMC_D10 + PD10 ------> FMC_D15 + PF12 ------> FMC_A6 + PF15 ------> FMC_A9 + PE8 ------> FMC_D5 + PE9 ------> FMC_D6 + PE11 ------> FMC_D8 + PE14 ------> FMC_D11 + PD9 ------> FMC_D14 + PD8 ------> FMC_D13 + PF11 ------> FMC_SDNRAS + PF14 ------> FMC_A8 + PE7 ------> FMC_D4 + PE10 ------> FMC_D7 + PE12 ------> FMC_D9 + PE15 ------> FMC_D12 + */ + +const mcu_periph_obj_t sdram_pin_list[57] = { + PERIPH(4, 12, &pin_PE01), + PERIPH(4, 12, &pin_PE00), + PERIPH(6, 12, &pin_PG15), + PERIPH(3, 12, &pin_PD00), + PERIPH(8, 12, &pin_PI07), + PERIPH(8, 12, &pin_PI06), + PERIPH(8, 12, &pin_PI05), + PERIPH(3, 12, &pin_PD01), + PERIPH(8, 12, &pin_PI03), + PERIPH(8, 12, &pin_PI02), + PERIPH(8, 12, &pin_PI09), + PERIPH(8, 12, &pin_PI04), + PERIPH(7, 12, &pin_PH15), + PERIPH(8, 12, &pin_PI01), + PERIPH(5, 12, &pin_PF00), + PERIPH(8, 12, &pin_PI10), + PERIPH(7, 12, &pin_PH13), + PERIPH(7, 12, &pin_PH14), + PERIPH(8, 12, &pin_PI00), + PERIPH(7, 12, &pin_PH02), + PERIPH(7, 12, &pin_PH03), + PERIPH(5, 12, &pin_PF02), + PERIPH(5, 12, &pin_PF01), + PERIPH(6, 12, &pin_PG08), + PERIPH(5, 12, &pin_PF03), + PERIPH(5, 12, &pin_PF04), + PERIPH(7, 12, &pin_PH05), + PERIPH(5, 12, &pin_PF05), + PERIPH(7, 12, &pin_PH12), + PERIPH(6, 12, &pin_PG05), + PERIPH(6, 12, &pin_PG04), + PERIPH(7, 12, &pin_PH11), + PERIPH(7, 12, &pin_PH10), + PERIPH(3, 12, &pin_PD15), + PERIPH(6, 12, &pin_PG02), + PERIPH(6, 12, &pin_PG01), + PERIPH(7, 12, &pin_PH08), + PERIPH(7, 12, &pin_PH09), + PERIPH(3, 12, &pin_PD14), + PERIPH(5, 12, &pin_PF13), + PERIPH(6, 12, &pin_PG00), + PERIPH(4, 12, &pin_PE13), + PERIPH(3, 12, &pin_PD10), + PERIPH(5, 12, &pin_PF12), + PERIPH(5, 12, &pin_PF15), + PERIPH(4, 12, &pin_PE08), + PERIPH(4, 12, &pin_PE09), + PERIPH(4, 12, &pin_PE11), + PERIPH(4, 12, &pin_PE14), + PERIPH(3, 12, &pin_PD09), + PERIPH(3, 12, &pin_PD08), + PERIPH(5, 12, &pin_PF11), + PERIPH(5, 12, &pin_PF14), + PERIPH(4, 12, &pin_PE07), + PERIPH(4, 12, &pin_PE10), + PERIPH(4, 12, &pin_PE12), + PERIPH(4, 12, &pin_PE15), +}; diff --git a/ports/stm/peripherals/stm32h7/stm32h750xx/periph.h b/ports/stm/peripherals/stm32h7/stm32h750xx/periph.h new file mode 100644 index 00000000000..f90f5507180 --- /dev/null +++ b/ports/stm/peripherals/stm32h7/stm32h750xx/periph.h @@ -0,0 +1,45 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#pragma once + +// I2C +extern I2C_TypeDef *mcu_i2c_banks[MAX_I2C]; + +extern const mcu_periph_obj_t mcu_i2c_sda_list[12]; +extern const mcu_periph_obj_t mcu_i2c_scl_list[12]; + +// SPI +extern SPI_TypeDef *mcu_spi_banks[MAX_SPI]; + +extern const mcu_periph_obj_t mcu_spi_sck_list[18]; +extern const mcu_periph_obj_t mcu_spi_mosi_list[18]; +extern const mcu_periph_obj_t mcu_spi_miso_list[15]; + +// UART +extern USART_TypeDef *mcu_uart_banks[MAX_UART]; +extern bool mcu_uart_has_usart[MAX_UART]; + +extern const mcu_periph_obj_t mcu_uart_tx_list[24]; +extern const mcu_periph_obj_t mcu_uart_rx_list[25]; + +// Timers +#define TIM_PIN_ARRAY_LEN 65 +extern const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN]; +#define TIM_BANK_ARRAY_LEN 17 +extern TIM_TypeDef *mcu_tim_banks[TIM_BANK_ARRAY_LEN]; + +// SDIO - H750 has a MMC interface that includes SDIO +extern SDMMC_TypeDef *mcu_sdio_banks[1]; + +extern const mcu_periph_obj_t mcu_sdio_clock_list[1]; +extern const mcu_periph_obj_t mcu_sdio_command_list[1]; +extern const mcu_periph_obj_t mcu_sdio_data0_list[1]; +extern const mcu_periph_obj_t mcu_sdio_data1_list[1]; +extern const mcu_periph_obj_t mcu_sdio_data2_list[1]; +extern const mcu_periph_obj_t mcu_sdio_data3_list[1]; +// SDRam +extern const mcu_periph_obj_t sdram_pin_list[57]; diff --git a/ports/stm/peripherals/stm32h7/stm32h750xx/pins.c b/ports/stm/peripherals/stm32h7/stm32h750xx/pins.c new file mode 100644 index 00000000000..bd0485b03f5 --- /dev/null +++ b/ports/stm/peripherals/stm32h7/stm32h750xx/pins.c @@ -0,0 +1,164 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/mphal.h" +#include "peripherals/pins.h" + +// ADC added only to pins exposed on Daisy Seed board + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 16)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 17)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_12, 14)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_12, 15)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_12, 18)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_12, 19)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_12, 3)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_12, 7)); +const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); +const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); +const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); +const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC); +const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); +const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); +const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); +const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); + +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, NO_ADC); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_12, 5)); +const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); +const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); +const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); +const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC); +const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC); +const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC); +const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC); +const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC); +const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC); +const mcu_pin_obj_t pin_PB11 = PIN(1, 11, NO_ADC); +const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); +const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); +const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); +const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); + +const mcu_pin_obj_t pin_PC00 = PIN(2, 0, ADC_INPUT(ADC_12, 10)); +const mcu_pin_obj_t pin_PC01 = PIN(2, 1, ADC_INPUT(ADC_123, 11)); +const mcu_pin_obj_t pin_PC02 = PIN(2, 2, NO_ADC); +const mcu_pin_obj_t pin_PC03 = PIN(2, 3, NO_ADC); +const mcu_pin_obj_t pin_PC04 = PIN(2, 4, ADC_INPUT(ADC_12, 4)); +const mcu_pin_obj_t pin_PC05 = PIN(2, 5, NO_ADC); +const mcu_pin_obj_t pin_PC06 = PIN(2, 6, NO_ADC); +const mcu_pin_obj_t pin_PC07 = PIN(2, 7, NO_ADC); +const mcu_pin_obj_t pin_PC08 = PIN(2, 8, NO_ADC); +const mcu_pin_obj_t pin_PC09 = PIN(2, 9, NO_ADC); +const mcu_pin_obj_t pin_PC10 = PIN(2, 10, NO_ADC); +const mcu_pin_obj_t pin_PC11 = PIN(2, 11, NO_ADC); +const mcu_pin_obj_t pin_PC12 = PIN(2, 12, NO_ADC); +const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); +const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); +const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); + +const mcu_pin_obj_t pin_PD00 = PIN(3, 0, NO_ADC); +const mcu_pin_obj_t pin_PD01 = PIN(3, 1, NO_ADC); +const mcu_pin_obj_t pin_PD02 = PIN(3, 2, NO_ADC); +const mcu_pin_obj_t pin_PD03 = PIN(3, 3, NO_ADC); +const mcu_pin_obj_t pin_PD04 = PIN(3, 4, NO_ADC); +const mcu_pin_obj_t pin_PD05 = PIN(3, 5, NO_ADC); +const mcu_pin_obj_t pin_PD06 = PIN(3, 6, NO_ADC); +const mcu_pin_obj_t pin_PD07 = PIN(3, 7, NO_ADC); +const mcu_pin_obj_t pin_PD08 = PIN(3, 8, NO_ADC); +const mcu_pin_obj_t pin_PD09 = PIN(3, 9, NO_ADC); +const mcu_pin_obj_t pin_PD10 = PIN(3, 10, NO_ADC); +const mcu_pin_obj_t pin_PD11 = PIN(3, 11, NO_ADC); +const mcu_pin_obj_t pin_PD12 = PIN(3, 12, NO_ADC); +const mcu_pin_obj_t pin_PD13 = PIN(3, 13, NO_ADC); +const mcu_pin_obj_t pin_PD14 = PIN(3, 14, NO_ADC); +const mcu_pin_obj_t pin_PD15 = PIN(3, 15, NO_ADC); + +const mcu_pin_obj_t pin_PE00 = PIN(4, 0, NO_ADC); +const mcu_pin_obj_t pin_PE01 = PIN(4, 1, NO_ADC); +const mcu_pin_obj_t pin_PE02 = PIN(4, 2, NO_ADC); +const mcu_pin_obj_t pin_PE03 = PIN(4, 3, NO_ADC); +const mcu_pin_obj_t pin_PE04 = PIN(4, 4, NO_ADC); +const mcu_pin_obj_t pin_PE05 = PIN(4, 5, NO_ADC); +const mcu_pin_obj_t pin_PE06 = PIN(4, 6, NO_ADC); +const mcu_pin_obj_t pin_PE07 = PIN(4, 7, NO_ADC); +const mcu_pin_obj_t pin_PE08 = PIN(4, 8, NO_ADC); +const mcu_pin_obj_t pin_PE09 = PIN(4, 9, NO_ADC); +const mcu_pin_obj_t pin_PE10 = PIN(4, 10, NO_ADC); +const mcu_pin_obj_t pin_PE11 = PIN(4, 11, NO_ADC); +const mcu_pin_obj_t pin_PE12 = PIN(4, 12, NO_ADC); +const mcu_pin_obj_t pin_PE13 = PIN(4, 13, NO_ADC); +const mcu_pin_obj_t pin_PE14 = PIN(4, 14, NO_ADC); +const mcu_pin_obj_t pin_PE15 = PIN(4, 15, NO_ADC); + +const mcu_pin_obj_t pin_PF00 = PIN(5, 0, NO_ADC); +const mcu_pin_obj_t pin_PF01 = PIN(5, 1, NO_ADC); +const mcu_pin_obj_t pin_PF02 = PIN(5, 2, NO_ADC); +const mcu_pin_obj_t pin_PF03 = PIN(5, 3, NO_ADC); +const mcu_pin_obj_t pin_PF04 = PIN(5, 4, NO_ADC); +const mcu_pin_obj_t pin_PF05 = PIN(5, 5, NO_ADC); +const mcu_pin_obj_t pin_PF06 = PIN(5, 6, NO_ADC); +const mcu_pin_obj_t pin_PF07 = PIN(5, 7, NO_ADC); +const mcu_pin_obj_t pin_PF08 = PIN(5, 8, NO_ADC); +const mcu_pin_obj_t pin_PF09 = PIN(5, 9, NO_ADC); +const mcu_pin_obj_t pin_PF10 = PIN(5, 10, NO_ADC); +const mcu_pin_obj_t pin_PF11 = PIN(5, 11, NO_ADC); +const mcu_pin_obj_t pin_PF12 = PIN(5, 12, NO_ADC); +const mcu_pin_obj_t pin_PF13 = PIN(5, 13, NO_ADC); +const mcu_pin_obj_t pin_PF14 = PIN(5, 14, NO_ADC); +const mcu_pin_obj_t pin_PF15 = PIN(5, 15, NO_ADC); + +const mcu_pin_obj_t pin_PG00 = PIN(6, 0, NO_ADC); +const mcu_pin_obj_t pin_PG01 = PIN(6, 1, NO_ADC); +const mcu_pin_obj_t pin_PG02 = PIN(6, 2, NO_ADC); +const mcu_pin_obj_t pin_PG03 = PIN(6, 3, NO_ADC); +const mcu_pin_obj_t pin_PG04 = PIN(6, 4, NO_ADC); +const mcu_pin_obj_t pin_PG05 = PIN(6, 5, NO_ADC); +const mcu_pin_obj_t pin_PG06 = PIN(6, 6, NO_ADC); +const mcu_pin_obj_t pin_PG07 = PIN(6, 7, NO_ADC); +const mcu_pin_obj_t pin_PG08 = PIN(6, 8, NO_ADC); +const mcu_pin_obj_t pin_PG09 = PIN(6, 9, NO_ADC); +const mcu_pin_obj_t pin_PG10 = PIN(6, 10, NO_ADC); +const mcu_pin_obj_t pin_PG11 = PIN(6, 11, NO_ADC); +const mcu_pin_obj_t pin_PG12 = PIN(6, 12, NO_ADC); +const mcu_pin_obj_t pin_PG13 = PIN(6, 13, NO_ADC); +const mcu_pin_obj_t pin_PG14 = PIN(6, 14, NO_ADC); +const mcu_pin_obj_t pin_PG15 = PIN(6, 15, NO_ADC); + +const mcu_pin_obj_t pin_PH00 = PIN(7, 0, NO_ADC); +const mcu_pin_obj_t pin_PH01 = PIN(7, 1, NO_ADC); +const mcu_pin_obj_t pin_PH02 = PIN(7, 2, NO_ADC); +const mcu_pin_obj_t pin_PH03 = PIN(7, 3, NO_ADC); +const mcu_pin_obj_t pin_PH04 = PIN(7, 4, NO_ADC); +const mcu_pin_obj_t pin_PH05 = PIN(7, 5, NO_ADC); +const mcu_pin_obj_t pin_PH06 = PIN(7, 6, NO_ADC); +const mcu_pin_obj_t pin_PH07 = PIN(7, 7, NO_ADC); +const mcu_pin_obj_t pin_PH08 = PIN(7, 8, NO_ADC); +const mcu_pin_obj_t pin_PH09 = PIN(7, 9, NO_ADC); +const mcu_pin_obj_t pin_PH10 = PIN(7, 10, NO_ADC); +const mcu_pin_obj_t pin_PH11 = PIN(7, 11, NO_ADC); +const mcu_pin_obj_t pin_PH12 = PIN(7, 12, NO_ADC); +const mcu_pin_obj_t pin_PH13 = PIN(7, 13, NO_ADC); +const mcu_pin_obj_t pin_PH14 = PIN(7, 14, NO_ADC); +const mcu_pin_obj_t pin_PH15 = PIN(7, 15, NO_ADC); + +const mcu_pin_obj_t pin_PI00 = PIN(8, 0, NO_ADC); +const mcu_pin_obj_t pin_PI01 = PIN(8, 1, NO_ADC); +const mcu_pin_obj_t pin_PI02 = PIN(8, 2, NO_ADC); +const mcu_pin_obj_t pin_PI03 = PIN(8, 3, NO_ADC); +const mcu_pin_obj_t pin_PI04 = PIN(8, 4, NO_ADC); +const mcu_pin_obj_t pin_PI05 = PIN(8, 5, NO_ADC); +const mcu_pin_obj_t pin_PI06 = PIN(8, 6, NO_ADC); +const mcu_pin_obj_t pin_PI07 = PIN(8, 7, NO_ADC); +const mcu_pin_obj_t pin_PI08 = PIN(8, 8, NO_ADC); +const mcu_pin_obj_t pin_PI09 = PIN(8, 9, NO_ADC); +const mcu_pin_obj_t pin_PI10 = PIN(8, 10, NO_ADC); +const mcu_pin_obj_t pin_PI11 = PIN(8, 11, NO_ADC); +const mcu_pin_obj_t pin_PI12 = PIN(8, 12, NO_ADC); +const mcu_pin_obj_t pin_PI13 = PIN(8, 13, NO_ADC); +const mcu_pin_obj_t pin_PI14 = PIN(8, 14, NO_ADC); +const mcu_pin_obj_t pin_PI15 = PIN(8, 15, NO_ADC); diff --git a/ports/stm/peripherals/stm32h7/stm32h750xx/pins.h b/ports/stm/peripherals/stm32h7/stm32h750xx/pins.h new file mode 100644 index 00000000000..7cd2631f3de --- /dev/null +++ b/ports/stm/peripherals/stm32h7/stm32h750xx/pins.h @@ -0,0 +1,152 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#pragma once + +extern const mcu_pin_obj_t pin_PA00; +extern const mcu_pin_obj_t pin_PA01; +extern const mcu_pin_obj_t pin_PA02; +extern const mcu_pin_obj_t pin_PA03; +extern const mcu_pin_obj_t pin_PA04; +extern const mcu_pin_obj_t pin_PA05; +extern const mcu_pin_obj_t pin_PA06; +extern const mcu_pin_obj_t pin_PA07; +extern const mcu_pin_obj_t pin_PA08; +extern const mcu_pin_obj_t pin_PA09; +extern const mcu_pin_obj_t pin_PA10; +extern const mcu_pin_obj_t pin_PA11; +extern const mcu_pin_obj_t pin_PA12; +extern const mcu_pin_obj_t pin_PA13; +extern const mcu_pin_obj_t pin_PA14; +extern const mcu_pin_obj_t pin_PA15; +extern const mcu_pin_obj_t pin_PB00; +extern const mcu_pin_obj_t pin_PB01; +extern const mcu_pin_obj_t pin_PB02; +extern const mcu_pin_obj_t pin_PB03; +extern const mcu_pin_obj_t pin_PB04; +extern const mcu_pin_obj_t pin_PB05; +extern const mcu_pin_obj_t pin_PB06; +extern const mcu_pin_obj_t pin_PB07; +extern const mcu_pin_obj_t pin_PB08; +extern const mcu_pin_obj_t pin_PB09; +extern const mcu_pin_obj_t pin_PB10; +extern const mcu_pin_obj_t pin_PB11; +extern const mcu_pin_obj_t pin_PB12; +extern const mcu_pin_obj_t pin_PB13; +extern const mcu_pin_obj_t pin_PB14; +extern const mcu_pin_obj_t pin_PB15; +extern const mcu_pin_obj_t pin_PC00; +extern const mcu_pin_obj_t pin_PC01; +extern const mcu_pin_obj_t pin_PC02; +extern const mcu_pin_obj_t pin_PC03; +extern const mcu_pin_obj_t pin_PC04; +extern const mcu_pin_obj_t pin_PC05; +extern const mcu_pin_obj_t pin_PC06; +extern const mcu_pin_obj_t pin_PC07; +extern const mcu_pin_obj_t pin_PC08; +extern const mcu_pin_obj_t pin_PC09; +extern const mcu_pin_obj_t pin_PC10; +extern const mcu_pin_obj_t pin_PC11; +extern const mcu_pin_obj_t pin_PC12; +extern const mcu_pin_obj_t pin_PC13; +extern const mcu_pin_obj_t pin_PC14; +extern const mcu_pin_obj_t pin_PC15; +extern const mcu_pin_obj_t pin_PD00; +extern const mcu_pin_obj_t pin_PD01; +extern const mcu_pin_obj_t pin_PD02; +extern const mcu_pin_obj_t pin_PD03; +extern const mcu_pin_obj_t pin_PD04; +extern const mcu_pin_obj_t pin_PD05; +extern const mcu_pin_obj_t pin_PD06; +extern const mcu_pin_obj_t pin_PD07; +extern const mcu_pin_obj_t pin_PD08; +extern const mcu_pin_obj_t pin_PD09; +extern const mcu_pin_obj_t pin_PD10; +extern const mcu_pin_obj_t pin_PD11; +extern const mcu_pin_obj_t pin_PD12; +extern const mcu_pin_obj_t pin_PD13; +extern const mcu_pin_obj_t pin_PD14; +extern const mcu_pin_obj_t pin_PD15; +extern const mcu_pin_obj_t pin_PE00; +extern const mcu_pin_obj_t pin_PE01; +extern const mcu_pin_obj_t pin_PE02; +extern const mcu_pin_obj_t pin_PE03; +extern const mcu_pin_obj_t pin_PE04; +extern const mcu_pin_obj_t pin_PE05; +extern const mcu_pin_obj_t pin_PE06; +extern const mcu_pin_obj_t pin_PE07; +extern const mcu_pin_obj_t pin_PE08; +extern const mcu_pin_obj_t pin_PE09; +extern const mcu_pin_obj_t pin_PE10; +extern const mcu_pin_obj_t pin_PE11; +extern const mcu_pin_obj_t pin_PE12; +extern const mcu_pin_obj_t pin_PE13; +extern const mcu_pin_obj_t pin_PE14; +extern const mcu_pin_obj_t pin_PE15; +extern const mcu_pin_obj_t pin_PF00; +extern const mcu_pin_obj_t pin_PF01; +extern const mcu_pin_obj_t pin_PF02; +extern const mcu_pin_obj_t pin_PF03; +extern const mcu_pin_obj_t pin_PF04; +extern const mcu_pin_obj_t pin_PF05; +extern const mcu_pin_obj_t pin_PF06; +extern const mcu_pin_obj_t pin_PF07; +extern const mcu_pin_obj_t pin_PF08; +extern const mcu_pin_obj_t pin_PF09; +extern const mcu_pin_obj_t pin_PF10; +extern const mcu_pin_obj_t pin_PF11; +extern const mcu_pin_obj_t pin_PF12; +extern const mcu_pin_obj_t pin_PF13; +extern const mcu_pin_obj_t pin_PF14; +extern const mcu_pin_obj_t pin_PF15; +extern const mcu_pin_obj_t pin_PG00; +extern const mcu_pin_obj_t pin_PG01; +extern const mcu_pin_obj_t pin_PG02; +extern const mcu_pin_obj_t pin_PG03; +extern const mcu_pin_obj_t pin_PG04; +extern const mcu_pin_obj_t pin_PG05; +extern const mcu_pin_obj_t pin_PG06; +extern const mcu_pin_obj_t pin_PG07; +extern const mcu_pin_obj_t pin_PG08; +extern const mcu_pin_obj_t pin_PG09; +extern const mcu_pin_obj_t pin_PG10; +extern const mcu_pin_obj_t pin_PG11; +extern const mcu_pin_obj_t pin_PG12; +extern const mcu_pin_obj_t pin_PG13; +extern const mcu_pin_obj_t pin_PG14; +extern const mcu_pin_obj_t pin_PG15; +extern const mcu_pin_obj_t pin_PH00; +extern const mcu_pin_obj_t pin_PH01; +extern const mcu_pin_obj_t pin_PH02; +extern const mcu_pin_obj_t pin_PH03; +extern const mcu_pin_obj_t pin_PH04; +extern const mcu_pin_obj_t pin_PH05; +extern const mcu_pin_obj_t pin_PH06; +extern const mcu_pin_obj_t pin_PH07; +extern const mcu_pin_obj_t pin_PH08; +extern const mcu_pin_obj_t pin_PH09; +extern const mcu_pin_obj_t pin_PH10; +extern const mcu_pin_obj_t pin_PH11; +extern const mcu_pin_obj_t pin_PH12; +extern const mcu_pin_obj_t pin_PH13; +extern const mcu_pin_obj_t pin_PH14; +extern const mcu_pin_obj_t pin_PH15; +extern const mcu_pin_obj_t pin_PI00; +extern const mcu_pin_obj_t pin_PI01; +extern const mcu_pin_obj_t pin_PI02; +extern const mcu_pin_obj_t pin_PI03; +extern const mcu_pin_obj_t pin_PI04; +extern const mcu_pin_obj_t pin_PI05; +extern const mcu_pin_obj_t pin_PI06; +extern const mcu_pin_obj_t pin_PI07; +extern const mcu_pin_obj_t pin_PI08; +extern const mcu_pin_obj_t pin_PI09; +extern const mcu_pin_obj_t pin_PI10; +extern const mcu_pin_obj_t pin_PI11; +extern const mcu_pin_obj_t pin_PI12; +extern const mcu_pin_obj_t pin_PI13; +extern const mcu_pin_obj_t pin_PI14; +extern const mcu_pin_obj_t pin_PI15; diff --git a/ports/stm/peripherals/stm32l4/clocks.c b/ports/stm/peripherals/stm32l4/clocks.c index a005c2bf790..4a7adc62de7 100644 --- a/ports/stm/peripherals/stm32l4/clocks.c +++ b/ports/stm/peripherals/stm32l4/clocks.c @@ -9,8 +9,10 @@ #include // L4 Series -#ifdef STM32L4R5xx +#if defined(STM32L4R5xx) #include "stm32l4/stm32l4r5xx/clocks.h" +#elif defined(STM32L433xx) +#include "stm32l4/stm32l433xx/clocks.h" #else #error Please add other MCUs here so that they are not silently ignored due to #define typos #endif @@ -44,49 +46,86 @@ void stm32_peripherals_clocks_init(void) { /** Configure the main internal regulator output voltage */ + #if defined(STM32L4R5xx) if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST) != HAL_OK) { Error_Handler(); } - + #elif defined(STM32L433xx) + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { + Error_Handler(); + } + #endif /* Activate PLL with MSI , stabilizied via PLL by LSE */ + #if defined(STM32L4R5xx) RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_MSI; RCC_OscInitStruct.MSIState = RCC_MSI_ON; RCC_OscInitStruct.LSEState = RCC_LSE_ON; - RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; RCC_OscInitStruct.PLL.PLLM = 6; RCC_OscInitStruct.PLL.PLLN = 30; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV5; RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + #elif defined(STM32L433xx) + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_MSI; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.MSIState = RCC_MSI_ON; + RCC_OscInitStruct.LSEState = RCC_LSE_ON; + RCC_OscInitStruct.MSICalibrationValue = 0; + RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 40; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + #else + #error Unknown MCU + #endif + HAL_CHECK(HAL_RCC_OscConfig(&RCC_OscInitStruct)); + #ifdef STM32L4R5xx /* Enable MSI Auto-calibration through LSE */ HAL_RCCEx_EnableMSIPLLMode(); + #endif /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers */ RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2); RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - // Avoid overshoot and start with HCLK 60 MHz RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + #if defined(STM32L4R5xx) HAL_CHECK(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3)); + #elif defined(STM32L433xx) + HAL_CHECK(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4)); + #else + #error Please expand the conditional compilation to set the default flash latency + #endif /* AHB prescaler divider at 1 as second step */ + #ifdef STM32L4R5xx RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; HAL_CHECK(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5)); + #endif /* Select MSI output as USB clock source */ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB | RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_ADC; + #if defined(STM32L4R5xx) PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; + #elif defined(STM32L433xx) + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + #endif PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK; - HAL_CHECK(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct)); + HAL_CHECK(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct)); } diff --git a/ports/stm/peripherals/stm32l4/stm32l433xx/clocks.h b/ports/stm/peripherals/stm32l4/stm32l433xx/clocks.h new file mode 100644 index 00000000000..a01cae704d6 --- /dev/null +++ b/ports/stm/peripherals/stm32l4/stm32l433xx/clocks.h @@ -0,0 +1,49 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Blues Wireless Contributors +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "stm32l4xx_hal.h" + +// Chip: STM32L433 +// Line Type: Foundation Line +// Speed: 80MHz (MAX) + +// Defaults: +#ifndef CPY_CLK_VSCALE +#define CPY_CLK_VSCALE (PWR_REGULATOR_VOLTAGE_SCALE1) // up to 80MHz +#endif +#ifndef CPY_CLK_PLLM +#define CPY_CLK_PLLM (1) +#endif +#ifndef CPY_CLK_PLLN +#define CPY_CLK_PLLN (40) +#endif +#ifndef CPY_CLK_PLLP +#define CPY_CLK_PLLP (RCC_PLLP_DIV7) +#endif +#ifndef CPY_CLK_PLLQ +#define CPY_CLK_PLLQ (2) +#endif +#ifndef CPY_CLK_AHBDIV +#define CPY_CLK_AHBDIV (RCC_SYSCLK_DIV1) +#endif +#ifndef CPY_CLK_APB1DIV +#define CPY_CLK_APB1DIV (RCC_HCLK_DIV1) +#endif +#ifndef CPY_CLK_APB2DIV +#define CPY_CLK_APB2DIV (RCC_HCLK_DIV1) +#endif +#ifndef CPY_CLK_FLASH_LATENCY +#define CPY_CLK_FLASH_LATENCY (FLASH_LATENCY_4) +#endif +#ifndef CPY_CLK_USB_USES_AUDIOPLL +#define CPY_CLK_USB_USES_AUDIOPLL (0) +#endif + +#ifndef BOARD_HAS_HIGH_SPEED_CRYSTAL +#define BOARD_HAS_HIGH_SPEED_CRYSTAL (1) +#endif diff --git a/ports/stm/peripherals/stm32l4/stm32l433xx/gpio.c b/ports/stm/peripherals/stm32l4/stm32l433xx/gpio.c new file mode 100644 index 00000000000..eb8914b5585 --- /dev/null +++ b/ports/stm/peripherals/stm32l4/stm32l433xx/gpio.c @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Blues Wireless Contributors +// +// SPDX-License-Identifier: MIT + +#include "peripherals/gpio.h" +#include "common-hal/microcontroller/Pin.h" + +void stm32_peripherals_gpio_init(void) { + // Enable all GPIO for now + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + + // Never reset pins + never_reset_pin_number(2, 14); // PC14 OSC32_IN + never_reset_pin_number(2, 15); // PC15 OSC32_OUT + never_reset_pin_number(0, 13); // PA13 SWDIO + never_reset_pin_number(0, 14); // PA14 SWCLK +} + +void stm32l4_peripherals_status_led(uint8_t led, uint8_t state) { + +} diff --git a/ports/stm/peripherals/stm32l4/stm32l433xx/periph.c b/ports/stm/peripherals/stm32l4/stm32l433xx/periph.c new file mode 100644 index 00000000000..e98c192c685 --- /dev/null +++ b/ports/stm/peripherals/stm32l4/stm32l433xx/periph.c @@ -0,0 +1,91 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Blues Wireless Contributors +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/mphal.h" +#include "peripherals/pins.h" +#include "peripherals/periph.h" + +I2C_TypeDef *mcu_i2c_banks[I2C_BANK_ARRAY_LEN] = {I2C1, I2C2}; + +const mcu_periph_obj_t mcu_i2c_sda_list[I2C_SDA_ARRAY_LEN] = { + PERIPH(1, 4, &pin_PA10), + PERIPH(2, 4, &pin_PB14), +}; + +const mcu_periph_obj_t mcu_i2c_scl_list[I2C_SCL_ARRAY_LEN] = { + PERIPH(1, 4, &pin_PA09), + PERIPH(2, 4, &pin_PB13), +}; + +SPI_TypeDef *mcu_spi_banks[SPI_BANK_ARRAY_LEN] = {SPI1}; + +const mcu_periph_obj_t mcu_spi_sck_list[SPI_SCK_ARRAY_LEN] = { + PERIPH(1, 5, &pin_PB03), +}; +const mcu_periph_obj_t mcu_spi_mosi_list[SPI_MOSI_ARRAY_LEN] = { + PERIPH(1, 5, &pin_PA12), +}; +const mcu_periph_obj_t mcu_spi_miso_list[SPI_MISO_ARRAY_LEN] = { + PERIPH(1, 5, &pin_PA11), +}; +const mcu_periph_obj_t mcu_spi_nss_list[SPI_NSS_ARRAY_LEN] = { + PERIPH(1, 5, &pin_PA15), +}; + +USART_TypeDef *mcu_uart_banks[MAX_UART] = {USART1, USART2, USART3}; +bool mcu_uart_has_usart[MAX_UART] = {true, true, true, false, false}; + +const mcu_periph_obj_t mcu_uart_tx_list[UART_TX_ARRAY_LEN] = { + PERIPH(2, 7, &pin_PA02), + PERIPH(1, 7, &pin_PA09), + PERIPH(1, 7, &pin_PB06), + PERIPH(3, 7, &pin_PB10), +}; +const mcu_periph_obj_t mcu_uart_rx_list[UART_RX_ARRAY_LEN] = { + PERIPH(2, 7, &pin_PA03), + PERIPH(1, 7, &pin_PA10), + PERIPH(2, 7, &pin_PA15), + PERIPH(1, 7, &pin_PB07), + PERIPH(3, 7, &pin_PB11), +}; + +// Timers +TIM_TypeDef *mcu_tim_banks[TIM_BANK_ARRAY_LEN] = {TIM1, TIM2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, TIM15, TIM16, NULL}; + +const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN] = { + TIM(2, 1, 1, &pin_PA00), + TIM(2, 1, 2, &pin_PA01), + TIM(2, 1, 3, &pin_PA02), + TIM(15, 15, 1, &pin_PA02), + TIM(2, 1, 4, &pin_PA03), + TIM(15, 15, 2, &pin_PA03), + TIM(2, 1, 1, &pin_PA05), + TIM(16, 15, 1, &pin_PA06), + TIM(1, 1, 1, &pin_PA08), + TIM(1, 1, 2, &pin_PA09), + TIM(1, 1, 3, &pin_PA10), + TIM(1, 1, 4, &pin_PA11), + TIM(2, 1, 1, &pin_PA15), + TIM(2, 1, 2, &pin_PB03), + TIM(16, 15, 1, &pin_PB08), + TIM(2, 1, 3, &pin_PB10), + TIM(2, 1, 4, &pin_PB11), + TIM(15, 15, 1, &pin_PB14), + TIM(15, 15, 2, &pin_PB15), +}; + +// CAN +CAN_TypeDef *mcu_can_banks[] = {CAN1}; + +const mcu_periph_obj_t mcu_can_tx_list[2] = { + PERIPH(1, 10, &pin_PA12), + PERIPH(1, 10, &pin_PB09), +}; +const mcu_periph_obj_t mcu_can_rx_list[2] = { + PERIPH(1, 10, &pin_PA11), + PERIPH(1, 10, &pin_PB08), +}; diff --git a/ports/stm/peripherals/stm32l4/stm32l433xx/periph.h b/ports/stm/peripherals/stm32l4/stm32l433xx/periph.h new file mode 100644 index 00000000000..6bf0add01fe --- /dev/null +++ b/ports/stm/peripherals/stm32l4/stm32l433xx/periph.h @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Blues Wireless Contributors +// +// SPDX-License-Identifier: MIT + +#pragma once + +// I2C +#define I2C_BANK_ARRAY_LEN 2 +#define I2C_SDA_ARRAY_LEN 2 +#define I2C_SCL_ARRAY_LEN 2 +extern I2C_TypeDef *mcu_i2c_banks[I2C_BANK_ARRAY_LEN]; +extern const mcu_periph_obj_t mcu_i2c_sda_list[I2C_SDA_ARRAY_LEN]; +extern const mcu_periph_obj_t mcu_i2c_scl_list[I2C_SCL_ARRAY_LEN]; + +// SPI +#define SPI_BANK_ARRAY_LEN 1 +#define SPI_SCK_ARRAY_LEN 1 +#define SPI_MOSI_ARRAY_LEN 1 +#define SPI_MISO_ARRAY_LEN 1 +#define SPI_NSS_ARRAY_LEN 1 +extern SPI_TypeDef *mcu_spi_banks[SPI_BANK_ARRAY_LEN]; +extern const mcu_periph_obj_t mcu_spi_sck_list[SPI_SCK_ARRAY_LEN]; +extern const mcu_periph_obj_t mcu_spi_mosi_list[SPI_MOSI_ARRAY_LEN]; +extern const mcu_periph_obj_t mcu_spi_miso_list[SPI_MISO_ARRAY_LEN]; +extern const mcu_periph_obj_t mcu_spi_nss_list[SPI_NSS_ARRAY_LEN]; + +// UART +#define UART_TX_ARRAY_LEN 4 +#define UART_RX_ARRAY_LEN 5 +extern USART_TypeDef *mcu_uart_banks[MAX_UART]; +extern bool mcu_uart_has_usart[MAX_UART]; +extern const mcu_periph_obj_t mcu_uart_tx_list[UART_TX_ARRAY_LEN]; +extern const mcu_periph_obj_t mcu_uart_rx_list[UART_RX_ARRAY_LEN]; + +// Timers +#define TIM_BANK_ARRAY_LEN 17 +#define TIM_PIN_ARRAY_LEN 19 +extern TIM_TypeDef *mcu_tim_banks[TIM_BANK_ARRAY_LEN]; +extern const mcu_tim_pin_obj_t mcu_tim_pin_list[TIM_PIN_ARRAY_LEN]; + +// CAN +extern CAN_TypeDef *mcu_can_banks[1]; +extern const mcu_periph_obj_t mcu_can_tx_list[2]; +extern const mcu_periph_obj_t mcu_can_rx_list[2]; diff --git a/ports/stm/peripherals/stm32l4/stm32l433xx/pins.c b/ports/stm/peripherals/stm32l4/stm32l433xx/pins.c new file mode 100644 index 00000000000..060f53031bb --- /dev/null +++ b/ports/stm/peripherals/stm32l4/stm32l433xx/pins.c @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Blues Wireless Contributors +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/mphal.h" +#include "peripherals/pins.h" + +#include STM32_HAL_H + +const mcu_pin_obj_t pin_PA00 = PIN(0, 0, ADC_INPUT(ADC_1, 5)); +const mcu_pin_obj_t pin_PA01 = PIN(0, 1, ADC_INPUT(ADC_1, 6)); +const mcu_pin_obj_t pin_PA02 = PIN(0, 2, ADC_INPUT(ADC_1, 7)); +const mcu_pin_obj_t pin_PA03 = PIN(0, 3, ADC_INPUT(ADC_1, 8)); +const mcu_pin_obj_t pin_PA04 = PIN(0, 4, ADC_INPUT(ADC_1, 9)); +const mcu_pin_obj_t pin_PA05 = PIN(0, 5, ADC_INPUT(ADC_1, 10)); +const mcu_pin_obj_t pin_PA06 = PIN(0, 6, ADC_INPUT(ADC_1, 11)); +const mcu_pin_obj_t pin_PA07 = PIN(0, 7, ADC_INPUT(ADC_1, 12)); +const mcu_pin_obj_t pin_PA08 = PIN(0, 8, NO_ADC); +const mcu_pin_obj_t pin_PA09 = PIN(0, 9, NO_ADC); +const mcu_pin_obj_t pin_PA10 = PIN(0, 10, NO_ADC); +const mcu_pin_obj_t pin_PA11 = PIN(0, 11, NO_ADC); +const mcu_pin_obj_t pin_PA12 = PIN(0, 12, NO_ADC); +const mcu_pin_obj_t pin_PA13 = PIN(0, 13, NO_ADC); +const mcu_pin_obj_t pin_PA14 = PIN(0, 14, NO_ADC); +const mcu_pin_obj_t pin_PA15 = PIN(0, 15, NO_ADC); +const mcu_pin_obj_t pin_PB00 = PIN(1, 0, ADC_INPUT(ADC_1, 15)); +const mcu_pin_obj_t pin_PB01 = PIN(1, 1, ADC_INPUT(ADC_1, 16)); +const mcu_pin_obj_t pin_PB02 = PIN(1, 2, NO_ADC); +const mcu_pin_obj_t pin_PB03 = PIN(1, 3, NO_ADC); +const mcu_pin_obj_t pin_PB04 = PIN(1, 4, NO_ADC); +const mcu_pin_obj_t pin_PB05 = PIN(1, 5, NO_ADC); +const mcu_pin_obj_t pin_PB06 = PIN(1, 6, NO_ADC); +const mcu_pin_obj_t pin_PB07 = PIN(1, 7, NO_ADC); +const mcu_pin_obj_t pin_PB08 = PIN(1, 8, NO_ADC); +const mcu_pin_obj_t pin_PB09 = PIN(1, 9, NO_ADC); +const mcu_pin_obj_t pin_PB10 = PIN(1, 10, NO_ADC); +const mcu_pin_obj_t pin_PB11 = PIN(1, 11, NO_ADC); +const mcu_pin_obj_t pin_PB12 = PIN(1, 12, NO_ADC); +const mcu_pin_obj_t pin_PB13 = PIN(1, 13, NO_ADC); +const mcu_pin_obj_t pin_PB14 = PIN(1, 14, NO_ADC); +const mcu_pin_obj_t pin_PB15 = PIN(1, 15, NO_ADC); +const mcu_pin_obj_t pin_PC13 = PIN(2, 13, NO_ADC); +const mcu_pin_obj_t pin_PC14 = PIN(2, 14, NO_ADC); +const mcu_pin_obj_t pin_PC15 = PIN(2, 15, NO_ADC); +const mcu_pin_obj_t pin_PH00 = PIN(5, 0, NO_ADC); +const mcu_pin_obj_t pin_PH01 = PIN(5, 1, NO_ADC); +const mcu_pin_obj_t pin_PH03 = PIN(5, 3, NO_ADC); diff --git a/ports/stm/peripherals/stm32l4/stm32l433xx/pins.h b/ports/stm/peripherals/stm32l4/stm32l433xx/pins.h new file mode 100644 index 00000000000..93a175ddbad --- /dev/null +++ b/ports/stm/peripherals/stm32l4/stm32l433xx/pins.h @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Blues Wireless Contributors +// +// SPDX-License-Identifier: MIT + +#pragma once + +extern const mcu_pin_obj_t pin_PA00; +extern const mcu_pin_obj_t pin_PA01; +extern const mcu_pin_obj_t pin_PA02; +extern const mcu_pin_obj_t pin_PA03; +extern const mcu_pin_obj_t pin_PA04; +extern const mcu_pin_obj_t pin_PA05; +extern const mcu_pin_obj_t pin_PA06; +extern const mcu_pin_obj_t pin_PA07; +extern const mcu_pin_obj_t pin_PA08; +extern const mcu_pin_obj_t pin_PA09; +extern const mcu_pin_obj_t pin_PA10; +extern const mcu_pin_obj_t pin_PA11; +extern const mcu_pin_obj_t pin_PA12; +extern const mcu_pin_obj_t pin_PA13; +extern const mcu_pin_obj_t pin_PA14; +extern const mcu_pin_obj_t pin_PA15; +extern const mcu_pin_obj_t pin_PB00; +extern const mcu_pin_obj_t pin_PB01; +extern const mcu_pin_obj_t pin_PB02; +extern const mcu_pin_obj_t pin_PB03; +extern const mcu_pin_obj_t pin_PB04; +extern const mcu_pin_obj_t pin_PB05; +extern const mcu_pin_obj_t pin_PB06; +extern const mcu_pin_obj_t pin_PB07; +extern const mcu_pin_obj_t pin_PB08; +extern const mcu_pin_obj_t pin_PB09; +extern const mcu_pin_obj_t pin_PB10; +extern const mcu_pin_obj_t pin_PB11; +extern const mcu_pin_obj_t pin_PB12; +extern const mcu_pin_obj_t pin_PB13; +extern const mcu_pin_obj_t pin_PB14; +extern const mcu_pin_obj_t pin_PB15; +extern const mcu_pin_obj_t pin_PC13; +extern const mcu_pin_obj_t pin_PC14; +extern const mcu_pin_obj_t pin_PC15; +extern const mcu_pin_obj_t pin_PH00; +extern const mcu_pin_obj_t pin_PH01; +extern const mcu_pin_obj_t pin_PH03; diff --git a/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c b/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c index 18fe8b760a2..a4adc58e42a 100644 --- a/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c +++ b/ports/stm/peripherals/stm32l4/stm32l4r5xx/gpio.c @@ -17,7 +17,7 @@ void stm32_peripherals_gpio_init(void) { __HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE(); - // These ports are not used on the Swan R5 but may need to be enabeld on other boards + // These ports are not used on the Swan R5 but may need to be enabled on other boards // __HAL_RCC_GPIOH_CLK_ENABLE(); // __HAL_RCC_GPIOI_CLK_ENABLE(); diff --git a/ports/stm/peripherals/timers.c b/ports/stm/peripherals/timers.c index 9d963487a04..25cb9efcde0 100644 --- a/ports/stm/peripherals/timers.c +++ b/ports/stm/peripherals/timers.c @@ -5,14 +5,16 @@ // SPDX-License-Identifier: MIT #include "timers.h" -#include "py/mpconfig.h" #include "py/obj.h" #include "py/runtime.h" +#include "ports/stm/peripherals/periph.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/microcontroller/Pin.h" +#ifdef STM32H7 +#include "stm32h7xx_hal_rcc.h" +#endif -#if !(CPY_STM32H7) #define ALL_CLOCKS 0xFFFF #define NULL_IRQ 0xFF @@ -161,17 +163,29 @@ uint32_t stm_peripherals_timer_get_source_freq(TIM_TypeDef *timer) { // TIM{1,8,9,10,11} are on APB2 source = HAL_RCC_GetPCLK2Freq(); // 0b0xx means not divided; 0b100 is divide by 2; 0b101 by 4; 0b110 by 8; 0b111 by 16. + #ifdef STM32H7 + clk_div = (RCC->D2CFGR & RCC_D2CFGR_D2PPRE2) >> RCC_D2CFGR_D2PPRE2_Pos; + #else clk_div = (RCC->CFGR & RCC_CFGR_PPRE2) >> RCC_CFGR_PPRE2_Pos; + #endif } else { // TIM{2,3,4,5,6,7,12,13,14} are on APB1 source = HAL_RCC_GetPCLK1Freq(); // 0b0xx means not divided; 0b100 is divide by 2; 0b101 by 4; 0b110 by 8; 0b111 by 16. + #ifdef STM32H7 + clk_div = (RCC->D1CFGR & RCC_D1CFGR_D1PPRE) >> RCC_D1CFGR_D1PPRE_Pos; + #else clk_div = (RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos; + #endif } // Only some STM32's have TIMPRE. #if defined(RCC_CFGR_TIMPRE) + #ifdef STM32H7 + uint32_t timpre = RCC->CFGR & RCC_CFGR_TIMPRE; + #else uint32_t timpre = RCC->DCKCFGR & RCC_CFGR_TIMPRE; + #endif if (timpre == 0) { if (clk_div >= 0b100) { source *= 2; @@ -287,7 +301,7 @@ size_t stm_peripherals_timer_get_index(TIM_TypeDef *instance) { return ~(size_t)0; } -void tim_clock_enable(uint16_t mask) { +void tim_clock_enable(uint32_t mask) { #ifdef TIM1 if (mask & (1 << 0)) { __HAL_RCC_TIM1_CLK_ENABLE(); @@ -349,9 +363,28 @@ void tim_clock_enable(uint16_t mask) { __HAL_RCC_TIM14_CLK_ENABLE(); } #endif + + #ifdef STM32H750xx + // only enabled on the H750 board for now + #ifdef TIM15 + if (mask & (1 << 14)) { + __HAL_RCC_TIM15_CLK_ENABLE(); + } + #endif + #ifdef TIM16 + if (mask & (1 << 15)) { + __HAL_RCC_TIM16_CLK_ENABLE(); + } + #endif + #ifdef TIM17 + if (mask & (1 << 16)) { + __HAL_RCC_TIM17_CLK_ENABLE(); + } + #endif + #endif } -void tim_clock_disable(uint16_t mask) { +void tim_clock_disable(uint32_t mask) { #ifdef TIM1 if (mask & (1 << 0)) { __HAL_RCC_TIM1_CLK_DISABLE(); @@ -413,6 +446,26 @@ void tim_clock_disable(uint16_t mask) { __HAL_RCC_TIM14_CLK_DISABLE(); } #endif + + #ifdef STM32H750xx + // only enabled on the H750 board for now + #ifdef TIM15 + if (mask & (1 << 14)) { + __HAL_RCC_TIM15_CLK_DISABLE(); + } + #endif + #ifdef TIM16 + if (mask & (1 << 15)) { + __HAL_RCC_TIM16_CLK_DISABLE(); + } + #endif + #ifdef TIM17 + if (mask & (1 << 16)) { + __HAL_RCC_TIM17_CLK_DISABLE(); + } + #endif + #endif + } static void callback_router(size_t index) { @@ -421,75 +474,108 @@ static void callback_router(size_t index) { } } +#ifdef TIM1 void TIM1_CC_IRQHandler(void) { // Advanced timer callback_router(1); } +#endif +#ifdef TIM2 void TIM2_IRQHandler(void) { callback_router(2); } +#endif +#ifdef TIM3 void TIM3_IRQHandler(void) { callback_router(3); } +#endif +#ifdef TIM4 void TIM4_IRQHandler(void) { callback_router(4); } +#endif +#ifdef TIM5 void TIM5_IRQHandler(void) { callback_router(5); } +#endif +#ifdef TIM6 void TIM6_DAC_IRQHandler(void) { // Basic timer (DAC) callback_router(6); } +#endif +#ifdef TIM7 void TIM7_IRQHandler(void) { // Basic timer callback_router(7); } +#endif +#ifdef TIM8 void TIM8_CC_IRQHandler(void) { // Advanced timer callback_router(8); } +#endif // Advanced timer interrupts are currently unused. +#ifdef TIM9 void TIM1_BRK_TIM9_IRQHandler(void) { callback_router(9); } +#endif +#ifdef TIM10 void TIM1_UP_TIM10_IRQHandler(void) { callback_router(10); } +#endif +#ifdef TIM11 void TIM1_TRG_COM_TIM11_IRQHandler(void) { callback_router(11); } +#endif +#ifdef TIM12 void TIM8_BRK_TIM12_IRQHandler(void) { callback_router(12); } +#endif +#ifdef TIM13 void TIM8_UP_TIM13_IRQHandler(void) { callback_router(13); } +#endif +#ifdef TIM14 void TIM8_TRG_COM_TIM14_IRQHandler(void) { callback_router(14); } +#endif -#if (CPY_STM32H7) +#ifdef STM32H750xx +// only enabled on the H750 board for now +#ifdef TIM15 void TIM15_IRQHandler(void) { callback_router(15); } +#endif +#ifdef TIM16 void TIM16_IRQHandler(void) { callback_router(16); } +#endif +#ifdef TIM17 void TIM17_IRQHandler(void) { callback_router(17); } #endif - #endif diff --git a/ports/stm/peripherals/timers.h b/ports/stm/peripherals/timers.h index db3f9472e1e..00c198250cb 100644 --- a/ports/stm/peripherals/timers.h +++ b/ports/stm/peripherals/timers.h @@ -7,13 +7,12 @@ #pragma once #include -#include "py/mphal.h" -#include "peripherals/periph.h" +#include #include STM32_HAL_H -void tim_clock_enable(uint16_t mask); -void tim_clock_disable(uint16_t mask); +void tim_clock_enable(uint32_t mask); +void tim_clock_disable(uint32_t mask); uint32_t stm_peripherals_timer_get_source_freq(TIM_TypeDef *timer); size_t stm_peripherals_timer_get_irqnum(TIM_TypeDef *instance); void timers_reset(void); diff --git a/ports/stm/supervisor/cpu.s b/ports/stm/supervisor/cpu.s deleted file mode 100755 index 9e6807a5e2e..00000000000 --- a/ports/stm/supervisor/cpu.s +++ /dev/null @@ -1,27 +0,0 @@ -.syntax unified -.cpu cortex-m4 -.thumb -.text -.align 2 - -@ uint cpu_get_regs_and_sp(r0=uint regs[10]) -.global cpu_get_regs_and_sp -.thumb -.thumb_func -.type cpu_get_regs_and_sp, %function -cpu_get_regs_and_sp: -@ store registers into given array -str r4, [r0], #4 -str r5, [r0], #4 -str r6, [r0], #4 -str r7, [r0], #4 -str r8, [r0], #4 -str r9, [r0], #4 -str r10, [r0], #4 -str r11, [r0], #4 -str r12, [r0], #4 -str r13, [r0], #4 - -@ return the sp -mov r0, sp -bx lr diff --git a/ports/stm/supervisor/internal_flash.c b/ports/stm/supervisor/internal_flash.c index 273af300a80..240dbba9960 100644 --- a/ports/stm/supervisor/internal_flash.c +++ b/ports/stm/supervisor/internal_flash.c @@ -64,23 +64,34 @@ static uint8_t _flash_cache[0x8000] __attribute__((aligned(4))); #endif #elif defined(STM32H7) +#if defined(STM32H750xx) +static const flash_layout_t flash_layout[] = { + { 0x08000000, 0x20000, 1 }, +}; +#else static const flash_layout_t flash_layout[] = { { 0x08000000, 0x20000, 16 }, }; +#endif static uint8_t _flash_cache[0x20000] __attribute__((aligned(4))); -#elif defined(STM32L4) +#elif defined(STM32L4R5xx) static const flash_layout_t flash_layout[] = { { 0x08100000, 0x1000, 256 }, }; static uint8_t _flash_cache[0x1000] __attribute__((aligned(4))); +#elif defined(STM32L433xx) +static const flash_layout_t flash_layout[] = { + { 0x08000000, 0x0800, 128 }, +}; +static uint8_t _flash_cache[0x0800] __attribute__((aligned(4))); + #else #error Unsupported processor #endif #define NO_CACHE 0xffffffff -#define MAX_CACHE 0x4000 static uint32_t _cache_flash_addr = NO_CACHE; @@ -88,6 +99,10 @@ static uint32_t _cache_flash_addr = NO_CACHE; #if defined(STM32H7) // get the bank of a given flash address static uint32_t get_bank(uint32_t addr) { + #if defined(STM32H750xx) // H750 only has 1 bank + return FLASH_BANK_1; + #else + if (READ_BIT(FLASH->OPTCR, FLASH_OPTCR_SWAP_BANK) == 0) { // no bank swap if (addr < (FLASH_BASE + FLASH_BANK_SIZE)) { @@ -103,6 +118,7 @@ static uint32_t get_bank(uint32_t addr) { return FLASH_BANK_1; } } + #endif } #endif @@ -175,8 +191,13 @@ void port_internal_flash_flush(void) { // set up for erase FLASH_EraseInitTypeDef EraseInitStruct = {}; #if CPY_STM32L4 + #if defined(STM32L4R5xx) + EraseInitStruct.TypeErase = TYPEERASE_PAGES; + EraseInitStruct.Banks = FLASH_BANK_2; // filesystem stored in upper 1MB of flash in dual bank mode + #elif defined(STM32L433xx) EraseInitStruct.TypeErase = TYPEERASE_PAGES; - EraseInitStruct.Banks = FLASH_BANK_2; // filesystem stored in upper 1MB of flash in dual bank mode + EraseInitStruct.Banks = FLASH_BANK_1; + #endif #else EraseInitStruct.TypeErase = TYPEERASE_SECTORS; EraseInitStruct.VoltageRange = VOLTAGE_RANGE_3; // voltage range needs to be 2.7V to 3.6V @@ -186,6 +207,9 @@ void port_internal_flash_flush(void) { uint32_t sector_start_addr = 0xffffffff; #if defined(STM32H7) EraseInitStruct.Banks = get_bank(_cache_flash_addr); + #if defined(STM32H750xx) + EraseInitStruct.NbSectors = 1; + #endif #endif #if CPY_STM32L4 EraseInitStruct.Page = flash_get_sector_info(_cache_flash_addr, §or_start_addr, §or_size); diff --git a/ports/stm/supervisor/internal_flash.h b/ports/stm/supervisor/internal_flash.h index 68704805f33..473a495cd7c 100644 --- a/ports/stm/supervisor/internal_flash.h +++ b/ports/stm/supervisor/internal_flash.h @@ -81,12 +81,24 @@ #define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08020000 #endif +#ifdef STM32H750xx +#define STM32_FLASH_SIZE 0x20000 +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x10000 +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x8010000 +#endif + #ifdef STM32L4R5xx #define STM32_FLASH_SIZE 0x200000 // 2MB #define INTERNAL_FLASH_FILESYSTEM_SIZE 0x100000 // 1024KiB #define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08100000 #endif +#ifdef STM32L433xx +#define STM32_FLASH_SIZE 0x40000 // 256KiB +#define INTERNAL_FLASH_FILESYSTEM_SIZE 0xC000 // 48KiB +#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08004000 +#endif + #define INTERNAL_FLASH_FILESYSTEM_NUM_BLOCKS (INTERNAL_FLASH_FILESYSTEM_SIZE / FILESYSTEM_BLOCK_SIZE) #define STM32_FLASH_OFFSET 0x8000000 // All STM32 chips map to this flash location diff --git a/ports/stm/supervisor/port.c b/ports/stm/supervisor/port.c index 5b903044b61..1da862cd886 100644 --- a/ports/stm/supervisor/port.c +++ b/ports/stm/supervisor/port.c @@ -14,7 +14,6 @@ #include "shared-bindings/microcontroller/__init__.h" #if CIRCUITPY_BUSIO -#include "common-hal/busio/I2C.h" #include "common-hal/busio/SPI.h" #include "common-hal/busio/UART.h" #endif @@ -33,6 +32,9 @@ #if CIRCUITPY_RTC #include "shared-bindings/rtc/__init__.h" #endif +#if CIRCUITPY_AUDIOIO +#include "common-hal/audioio/AudioOut.h" +#endif #include "peripherals/clocks.h" #include "peripherals/gpio.h" @@ -40,9 +42,18 @@ #include STM32_HAL_H -void NVIC_SystemReset(void) NORETURN; +void NVIC_SystemReset(void) MP_NORETURN; #if (CPY_STM32H7) || (CPY_STM32F7) +#if defined(CIRCUITPY_HW_SDRAM_SIZE) +#include "stm.h" +#include "sdram.h" +#include +#include +#include "lib/tlsf/tlsf.h" +// internal SRAM + external SDRAM +#define CIRCUITPY_RAM_DEVICE_COUNT (2) +#endif // Device memories must be accessed in order. #define DEVICE 2 @@ -135,8 +146,31 @@ __attribute__((used, naked)) void Reset_Handler(void) { for (uint32_t i = 0; i < ((size_t)&_ld_d1_ram_bss_size) / 4; i++) { (&_ld_d1_ram_bss_start)[i] = 0; } + #ifdef STM32H750xx + __DMB(); /* ARM says to use a DMB instruction before relocating VTOR */ + SCB->VTOR = 0x90000000u; /* We relocate vector table to the QSPI sector 1 */ + __DSB(); /* ARM says to use a DSB instruction just after relocating VTOR */ + /* + Since the STM32H750 microcontroller has only 128kB internal flash, + CircuitPython has to run from an external flash (QSPI or FMC). + This means a custom bootloader, like tinyUF2, is needed on the internal + flash to initialize the clocks, PLLs and (QSPI) controller, and to + start execution of the firmware from the external flash. + It also makes the SystemInit() call not necessary for this chip. + */ + #if defined(__ICACHE_PRESENT) && (__ICACHE_PRESENT == 1U) + /* Enable I cache. */ + SCB_EnableICache(); + #endif /* __ICACHE_PRESENT */ + + #if defined(__DCACHE_PRESENT) && (__DCACHE_PRESENT == 1U) + /* Enable D cache. */ + SCB_EnableDCache(); + #endif /* __DCACHE_PRESENT */ + #else SystemInit(); + #endif __enable_irq(); main(); } @@ -145,6 +179,62 @@ __attribute__((used, naked)) void Reset_Handler(void) { // Low power clock variables static volatile uint32_t systick_ms; +#if defined(CIRCUITPY_HW_SDRAM_SIZE) +static tlsf_t _heap = NULL; +static pool_t pools[CIRCUITPY_RAM_DEVICE_COUNT] = {NULL}; + + +void port_heap_init(void) { + // heap init in _port_heap_init called from port_init +} + +void stm_add_sdram_to_heap(void) { + size_t sdram_memory_size = sdram_size(); + pools[1] = tlsf_add_pool(_heap, sdram_start(), sdram_memory_size); +} + +static void _port_heap_init(void) { + uint32_t *heap_bottom = port_heap_get_bottom(); + uint32_t *heap_top = port_heap_get_top(); + size_t size = (heap_top - heap_bottom) * sizeof(uint32_t); + size_t sdram_memory_size = sdram_size(); + + _heap = tlsf_create_with_pool(heap_bottom, size, size + sdram_memory_size); + pools[0] = tlsf_get_pool(_heap); +} + +static bool max_size_walker(void *ptr, size_t size, int used, void *user) { + size_t *max_size = (size_t *)user; + if (!used && *max_size < size) { + *max_size = size; + } + return true; +} + +size_t port_heap_get_largest_free_size(void) { + size_t max_size = 0; + for (size_t i = 0; i < CIRCUITPY_RAM_DEVICE_COUNT; i++) { + if (pools[i]) { + tlsf_walk_pool(pools[i], max_size_walker, &max_size); + } + } + return tlsf_fit_size(_heap, max_size); +} + +void *port_malloc(size_t size, bool dma_capable) { + void *block = tlsf_malloc(_heap, size); + return block; +} + +void port_free(void *ptr) { + tlsf_free(_heap, ptr); +} + +void *port_realloc(void *ptr, size_t size, bool dma_capable) { + return tlsf_realloc(_heap, ptr, size); +} +#endif + safe_mode_t port_init(void) { HAL_Init(); // Turns on SysTick __HAL_RCC_SYSCFG_CLK_ENABLE(); @@ -178,6 +268,9 @@ safe_mode_t port_init(void) { __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); stm32_peripherals_rtc_reset_alarms(); + #if defined(CIRCUITPY_HW_SDRAM_SIZE) + _port_heap_init(); + #endif // Turn off SysTick SysTick->CTRL = 0; @@ -195,7 +288,7 @@ void HAL_Delay(uint32_t delay_ms) { } } -uint32_t HAL_GetTick() { +uint32_t HAL_GetTick(void) { if (SysTick->CTRL != 0) { return systick_ms; } else { @@ -212,15 +305,11 @@ void SysTick_Handler(void) { } void reset_port(void) { - reset_all_pins(); - #if CIRCUITPY_RTC rtc_reset(); #endif #if CIRCUITPY_BUSIO - i2c_reset(); - spi_reset(); uart_reset(); #endif #if CIRCUITPY_SDIOIO @@ -229,6 +318,9 @@ void reset_port(void) { #if CIRCUITPY_ALARM exti_reset(); #endif + #if CIRCUITPY_AUDIOIO + audioout_reset(); + #endif } void reset_to_bootloader(void) { @@ -286,8 +378,9 @@ uint32_t *port_heap_get_bottom(void) { return &_ld_heap_start; } +// heap memory can be set in SRAM and stack can be set in DTCM uint32_t *port_heap_get_top(void) { - return port_stack_get_limit(); + return &_ld_heap_end; } uint32_t *port_stack_get_limit(void) { diff --git a/ports/stm/supervisor/serial.c b/ports/stm/supervisor/serial.c index 2f3dd66b266..380f5ceca59 100644 --- a/ports/stm/supervisor/serial.c +++ b/ports/stm/supervisor/serial.c @@ -16,6 +16,10 @@ UART_HandleTypeDef huart2; #endif +void port_serial_early_init(void) { + +} + void port_serial_init(void) { #if CPY_STM32F4 huart2.Instance = USART2; diff --git a/ports/stm/supervisor/stm.h b/ports/stm/supervisor/stm.h new file mode 100644 index 00000000000..6d3342137fb --- /dev/null +++ b/ports/stm/supervisor/stm.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 snkYmkrct +// +// SPDX-License-Identifier: MIT + +#pragma once + + +void stm_add_sdram_to_heap(void); diff --git a/ports/stm/supervisor/usb.c b/ports/stm/supervisor/usb.c index 61a7d54f08b..7c782f61d0d 100644 --- a/ports/stm/supervisor/usb.c +++ b/ports/stm/supervisor/usb.c @@ -29,7 +29,7 @@ static void init_usb_vbus_sense(void) { // B-peripheral session valid override enable USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; USB_OTG_FS->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; - #else + #elif !defined(STM32L433xx) && !defined(STM32L4R5xx) USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSBSEN; USB_OTG_FS->GCCFG &= ~USB_OTG_GCCFG_VBUSASEN; @@ -56,7 +56,7 @@ void init_usb_hardware(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /**USB_OTG_FS GPIO Configuration - PA10 ------> USB_OTG_FS_ID + PA10 ------> USB_OTG_FS_ID (not present on STM32L433) PA11 ------> USB_OTG_FS_DM PA12 ------> USB_OTG_FS_DP */ @@ -69,10 +69,15 @@ void init_usb_hardware(void) { GPIO_InitStruct.Pull = GPIO_NOPULL; #if CPY_STM32H7 GPIO_InitStruct.Alternate = GPIO_AF10_OTG1_FS; - #elif CPY_STM32F4 || CPY_STM32F7 || CPY_STM32L4 + #elif CPY_STM32F4 || CPY_STM32F7 || defined(STM32L4R5xx) GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + #elif defined(STM32L433xx) + GPIO_InitStruct.Alternate = GPIO_AF10_USB_FS; + #else + #error Unknown MCU #endif HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + never_reset_pin_number(0, 11); never_reset_pin_number(0, 12); claim_pin(0, 11); @@ -117,15 +122,21 @@ void init_usb_hardware(void) { #if CPY_STM32H7 HAL_PWREx_EnableUSBVoltageDetector(); __HAL_RCC_USB2_OTG_FS_CLK_ENABLE(); - #else + #elif CPY_STM32F4 || CPY_STM32F7 || defined(STM32L4R5xx) /* Peripheral clock enable */ __HAL_RCC_USB_OTG_FS_CLK_ENABLE(); + #else + __HAL_RCC_USB_CLK_ENABLE(); #endif - init_usb_vbus_sense(); } -void OTG_FS_IRQHandler(void) { +#if defined(STM32L433xx) +void USB_IRQHandler(void) +#else +void OTG_FS_IRQHandler(void) +#endif +{ usb_irq_handler(0); } diff --git a/ports/unix/Makefile b/ports/unix/Makefile index 526955b1ea5..32e3b44b227 100644 --- a/ports/unix/Makefile +++ b/ports/unix/Makefile @@ -4,8 +4,9 @@ ifdef VARIANT_DIR # the path as the variant name. VARIANT ?= $(notdir $(VARIANT_DIR:/=)) else -# If not given on the command line, then default to standard. -VARIANT ?= standard +# CIRCUITPY-CHANGE: default variant is coverage +# If not given on the command line, then default to coverage. +VARIANT ?= coverage VARIANT_DIR ?= variants/$(VARIANT) endif @@ -26,6 +27,9 @@ FROZEN_MANIFEST ?= variants/manifest.py # This should be configured by the mpconfigvariant.mk PROG ?= micropython +# For use in test rules below +ABS_PROG = $(abspath $(BUILD)/$(PROG)) + # qstr definitions (must come before including py.mk) QSTR_DEFS += qstrdefsport.h QSTR_GLOBAL_DEPENDENCIES += $(VARIANT_DIR)/mpconfigvariant.h @@ -45,9 +49,18 @@ INC += -I$(BUILD) # compiler settings CWARN = -Wall -Werror -CWARN += -Wextra -Wno-unused-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion +// CIRCUITPY-CHANGE: add -Wno-missing-field-initializers +CWARN += -Wextra -Wno-unused-parameter -Wpointer-arith -Wdouble-promotion -Wfloat-conversion -Wno-missing-field-initializers CFLAGS += $(INC) $(CWARN) -std=gnu99 -DUNIX $(COPT) -I$(VARIANT_DIR) $(CFLAGS_EXTRA) +# Force the use of 64-bits for file sizes in C library functions on 32-bit platforms. +# This option has no effect on 64-bit builds. +CFLAGS += -D_FILE_OFFSET_BITS=64 + +# Force the use of 64-bits for time_t in C library functions on 32-bit platforms. +# This option has no effect on 64-bit builds. +CFLAGS += -D_TIME_BITS=64 + # Debugging/Optimization ifdef DEBUG COPT ?= -Og @@ -134,7 +147,11 @@ ifeq ($(MICROPY_PY_SOCKET),1) CFLAGS += -DMICROPY_PY_SOCKET=1 endif ifeq ($(MICROPY_PY_THREAD),1) +ifeq ($(MICROPY_PY_THREAD_GIL),1) +CFLAGS += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=1 +else CFLAGS += -DMICROPY_PY_THREAD=1 -DMICROPY_PY_THREAD_GIL=0 +endif LDFLAGS += $(LIBPTHREAD) endif @@ -168,7 +185,7 @@ ifeq ($(MICROPY_STANDALONE),1) # Build libffi from source. GIT_SUBMODULES += lib/libffi DEPLIBS += libffi -LIBFFI_CFLAGS := -I$(shell ls -1d $(BUILD)/lib/libffi/out/lib/libffi-*/include) +LIBFFI_CFLAGS := -I$(shell ls -1d $(BUILD)/lib/libffi/include) ifeq ($(MICROPY_FORCE_32BIT),1) LIBFFI_LDFLAGS = $(BUILD)/lib/libffi/out/lib32/libffi.a else @@ -203,6 +220,8 @@ SRC_C += \ input.c \ alloc.c \ fatfs_port.c \ + shared-module/os/__init__.c \ + supervisor/shared/settings.c \ supervisor/stub/filesystem.c \ supervisor/stub/safe_mode.c \ supervisor/stub/stack.c \ @@ -218,6 +237,7 @@ $(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.gener SHARED_SRC_C += $(addprefix shared/,\ runtime/gchelper_generic.c \ + runtime/pyexec.c \ timeutils/timeutils.c \ $(SHARED_SRC_C_EXTRA) \ ) @@ -273,7 +293,7 @@ print-failures clean-failures: TEST_ARGS ?= test: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) - cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py $(TEST_ARGS) + cd $(TOP)/tests && MICROPY_MICROPYTHON=../$(DIRNAME)/$(BUILD)/$(PROG) ./run-tests.py test_full: $(BUILD)/$(PROG) $(TOP)/tests/run-tests.py $(eval DIRNAME=ports/$(notdir $(CURDIR))) diff --git a/ports/unix/README.md b/ports/unix/README.md index 61dfd7453e6..ee983a882cc 100644 --- a/ports/unix/README.md +++ b/ports/unix/README.md @@ -1,17 +1,59 @@ -The Unix version -================ +MicroPython Unix port +===================== + +The "unix" port runs in standard Unix-like environments including Linux, BSD, +macOS, and Windows Subsystem for Linux. -The "unix" port requires a standard Unix-like environment with gcc and GNU -make. This includes Linux, BSD, macOS, and Windows Subsystem for Linux. The -x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well as -ARM and MIPS. Making a full-featured port to another architecture requires +The x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well +as ARM and MIPS. Extending the unix port to another architecture requires writing some assembly code for the exception handling and garbage collection. Alternatively, a fallback implementation based on setjmp/longjmp can be used. -To build (see section below for required dependencies): +Building +-------- + +### Dependencies + +To build the unix port locally then you will need: + +* git command line executable, unless you downloaded a source .tar.xz file from + https://micropython.org/download/ +* gcc (or clang for macOS) toolchain +* GNU Make +* Python 3.x + +To build the default "standard" variant and configuration, then you will also +need: + +* `pkg-config` tool +* `libffi` library and headers + +On Debian/Ubuntu/Mint and related Linux distros, you can install all these +dependencies with a command like: + +``` +# apt install build-essential git python3 pkg-config libffi-dev +``` + +(See below for steps to build either a standalone or minimal MicroPython +executable that doesn't require system `libffi` or `pkg-config`.) + +### Default build steps + +To set up the environment for building (not needed every time), starting from +the top-level MicroPython directory: $ cd ports/unix + $ make -C ../../mpy-cross $ make submodules + +The `mpy-cross` step builds the [MicroPython +cross-compiler](https://github.com/micropython/micropython/?tab=readme-ov-file#the-micropython-cross-compiler-mpy-cross). +The `make submodules` step can be skipped if you didn't clone the MicroPython +source from git. + +Next, to build the actual executable (still in the `ports/unix` directory): + $ make Then to give it a try: @@ -30,6 +72,14 @@ To run the complete testsuite, use: $ make test +There are other make targets to interact with the testsuite: + + $ make test//int # Run all tests matching the pattern "int" + $ make test/ports/unix # Run all tests in ports/unix + $ make test-failures # Re-run only the failed tests + $ make print-failures # print the differences for failed tests + $ make clean-failures # delete the .exp and .out files from failed tests + The Unix port comes with a built-in package manager called `mip`, e.g.: $ ./build-standard/micropython -m mip install hmac @@ -45,44 +95,89 @@ Browse available modules at [Package management](https://docs.micropython.org/en/latest/reference/packages.html) for more information about `mip`. -External dependencies -===================== - -The `libffi` library and `pkg-config` tool are required. On Debian/Ubuntu/Mint -derivative Linux distros, install `build-essential`(includes toolchain and -make), `libffi-dev`, and `pkg-config` packages. +### Minimal Variant -Other dependencies can be built together with MicroPython. This may -be required to enable extra features or capabilities, and in recent -versions of MicroPython, these may be enabled by default. To build -these additional dependencies, in the unix port directory first execute: +The "standard" variant of MicroPython is the default. It enables most features, +including external modules interfaced using `libffi`. To instead build the +"minimal" variant, which disables almost all optional features and modules: + $ cd ports/unix $ make submodules + $ make VARIANT=minimal + +The executable will be built at `build-minimal/micropython`. + +Additional variants can be found in the `variants` sub-directory of the port, +although these are mostly of interest to MicroPython maintainers. + +### Standalone build + +By default, the "standard" variant uses `pkg-config` to link to the system's +shared `libffi` library. + +It is possible to instead build a standalone MicroPython where `libffi` is built +from source and linked statically into the `micropython` executable. This is +mostly useful for embedded or cross-compiled applications. + +Building standalone requires `autoconf` and `libtool` to also be installed. + +To build standalone: -This will fetch all the relevant git submodules (sub repositories) that -the port needs. Use the same command to get the latest versions of -submodules as they are updated from time to time. After that execute: + $ export MICROPY_STANDALONE=1 + $ make submodules # fetches libffi submodule + $ make deplibs # build just the external libraries + $ make # build MicroPython itself - $ make deplibs +`make deplibs` causes all supported external libraries (currently only `libffi`) +to be built inside the build directory, so it needs to run again only after +`make clean`. -This will build all available dependencies (regardless whether they are used -or not). If you intend to build MicroPython with additional options -(like cross-compiling), the same set of options should be passed to `make -deplibs`. To actually enable/disable use of dependencies, edit the +If you intend to build MicroPython with additional options (like +cross-compiling), the same set of options should be passed to both `make +deplibs` and `make`. + +### Other dependencies + +To actually enable/disable use of dependencies, edit the `ports/unix/mpconfigport.mk` file, which has inline descriptions of the options. For example, to build the SSL module, `MICROPY_PY_SSL` should be set to 1. -Debug Symbols -============= +### Debug Symbols By default, builds are stripped of symbols and debug information to save size. -To build a debuggable version of the Unix port, there are two options +To build a debuggable version of the Unix port, there are two options: 1. Run `make [other arguments] DEBUG=1`. Note setting `DEBUG` also reduces the - optimisation level, so it's not a good option for builds that also want the - best performance. + optimisation level and enables assertions, so it's not a good option for + builds that also want the best performance. 2. Run `make [other arguments] STRIP=`. Note that the value of `STRIP` is empty. This will skip the build step that strips symbols and debug information, but changes nothing else in the build configuration. + +### Optimisation Level + +The default compiler optimisation level is -Os, or -Og if `DEBUG=1` is set. + +Setting the variable `COPT` will explicitly set the optimisation level. For +example `make [other arguments] COPT=-O0 DEBUG=1` will build a binary with no +optimisations, assertions enabled, and debug symbols. + +### Sanitizers + +Sanitizers are extra runtime checks supported by gcc and clang. The CI process +supports building with the "undefined behavior" (UBSan) or "address" (ASan) +sanitizers. The script `tools/ci.sh` is the source of truth about how to build +and run in these modes. + +Several classes of checks are disabled via compiler flags: + +* In the undefined behavior sanitizer, checks based on the presence of the + `non_null` attribute are disabled because the code makes technically incorrect + calls like `memset(NULL, 0, 0)`. A future C standard is likely to permit such + calls. +* In the address sanitizer, `detect_stack_use_after_return` is disabled. This + check is intended to make sure locals in a "returned from" stack frame are not + used. However, this mode interferes with various assumptions that + MicroPython's stack checking, NLR, and GC rely on. diff --git a/ports/unix/alloc.c b/ports/unix/alloc.c index e9cf521583d..9ab2ca04ebc 100644 --- a/ports/unix/alloc.c +++ b/ports/unix/alloc.c @@ -31,9 +31,8 @@ #include #include "py/mpstate.h" -#include "py/gc.h" -#if MICROPY_EMIT_NATIVE || (MICROPY_PY_FFI && MICROPY_FORCE_PLAT_ALLOC_EXEC) +#if MICROPY_EMIT_NATIVE #if defined(__OpenBSD__) || defined(__MACH__) #define MAP_ANONYMOUS MAP_ANON @@ -79,31 +78,6 @@ void mp_unix_free_exec(void *ptr, size_t size) { } } -void mp_unix_mark_exec(void) { - for (mmap_region_t *rg = MP_STATE_VM(mmap_region_head); rg != NULL; rg = rg->next) { - gc_collect_root(rg->ptr, rg->len / sizeof(mp_uint_t)); - } -} - -#if MICROPY_FORCE_PLAT_ALLOC_EXEC -// Provide implementation of libffi ffi_closure_* functions in terms -// of the functions above. On a normal Linux system, this save a lot -// of code size. -void *ffi_closure_alloc(size_t size, void **code); -void ffi_closure_free(void *ptr); - -void *ffi_closure_alloc(size_t size, void **code) { - size_t dummy; - mp_unix_alloc_exec(size, code, &dummy); - return *code; -} - -void ffi_closure_free(void *ptr) { - (void)ptr; - // TODO -} -#endif - MP_REGISTER_ROOT_POINTER(void *mmap_region_head); -#endif // MICROPY_EMIT_NATIVE || (MICROPY_PY_FFI && MICROPY_FORCE_PLAT_ALLOC_EXEC) +#endif // MICROPY_EMIT_NATIVE diff --git a/ports/unix/coverage.c b/ports/unix/coverage.c index 4308ca6a1d2..49426f0f3e8 100644 --- a/ports/unix/coverage.c +++ b/ports/unix/coverage.c @@ -4,8 +4,10 @@ #include "py/obj.h" #include "py/objfun.h" +#include "py/objint.h" #include "py/objstr.h" #include "py/runtime.h" +#include "py/stackctrl.h" #include "py/gc.h" #include "py/repl.h" #include "py/mpz.h" @@ -95,6 +97,7 @@ static const mp_rom_map_elem_t rawfile_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write1), MP_ROM_PTR(&mp_stream_write1_obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto1), MP_ROM_PTR(&mp_stream_readinto1_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, { MP_ROM_QSTR(MP_QSTR_ioctl), MP_ROM_PTR(&mp_stream_ioctl_obj) }, }; @@ -169,19 +172,34 @@ static void pairheap_test(size_t nops, int *ops) { if (mp_pairheap_is_empty(pairheap_lt, heap)) { mp_printf(&mp_plat_print, " -"); } else { - mp_printf(&mp_plat_print, " %d", mp_pairheap_peek(pairheap_lt, heap) - &node[0]); + mp_printf(&mp_plat_print, " %d", (int)(mp_pairheap_peek(pairheap_lt, heap) - &node[0])); ; } } mp_printf(&mp_plat_print, "\npop all:"); while (!mp_pairheap_is_empty(pairheap_lt, heap)) { - mp_printf(&mp_plat_print, " %d", mp_pairheap_peek(pairheap_lt, heap) - &node[0]); + mp_printf(&mp_plat_print, " %d", (int)(mp_pairheap_peek(pairheap_lt, heap) - &node[0])); ; heap = mp_pairheap_pop(pairheap_lt, heap); } mp_printf(&mp_plat_print, "\n"); } +// CIRCUITPY-CHANGE: not turned on in CircuitPython +#if MICROPY_SCHEDULER_STATIC_NODES +static mp_sched_node_t mp_coverage_sched_node; +static bool coverage_sched_function_continue; + +static void coverage_sched_function(mp_sched_node_t *node) { + (void)node; + mp_printf(&mp_plat_print, "scheduled function\n"); + if (coverage_sched_function_continue) { + // Re-scheduling node will cause it to run again next time scheduled functions are run + mp_sched_schedule_node(&mp_coverage_sched_node, coverage_sched_function); + } +} +#endif + // function to run extra tests for things that can't be checked by scripts static mp_obj_t extra_coverage(void) { // mp_printf (used by ports that don't have a native printf) @@ -189,10 +207,22 @@ static mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "# mp_printf\n"); mp_printf(&mp_plat_print, "%d %+d % d\n", -123, 123, 123); // sign mp_printf(&mp_plat_print, "%05d\n", -123); // negative number with zero padding - mp_printf(&mp_plat_print, "%ld\n", 123); // long - mp_printf(&mp_plat_print, "%lx\n", 0x123); // long hex - mp_printf(&mp_plat_print, "%X\n", 0x1abcdef); // capital hex - mp_printf(&mp_plat_print, "%.2s %.3s '%4.4s' '%5.5q' '%.3q'\n", "abc", "abc", "abc", MP_QSTR_True, MP_QSTR_True); // fixed string precision + mp_printf(&mp_plat_print, "%ld\n", 123l); // long + mp_printf(&mp_plat_print, "%lx\n", 0x123fl); // long hex + mp_printf(&mp_plat_print, "%lX\n", 0x123fl); // capital long hex + if (sizeof(mp_int_t) == 8) { + mp_printf(&mp_plat_print, "%llx\n", LLONG_MAX); // long long hex + mp_printf(&mp_plat_print, "%llX\n", LLONG_MAX); // capital long long hex + mp_printf(&mp_plat_print, "%llu\n", ULLONG_MAX); // unsigned long long + } else { + // fake for platforms without narrower mp_int_t + mp_printf(&mp_plat_print, "7fffffffffffffff\n"); + mp_printf(&mp_plat_print, "7FFFFFFFFFFFFFFF\n"); + mp_printf(&mp_plat_print, "18446744073709551615\n"); + } + mp_printf(&mp_plat_print, "%p\n", (void *)0x789f); // pointer + mp_printf(&mp_plat_print, "%P\n", (void *)0x789f); // pointer uppercase + mp_printf(&mp_plat_print, "%.2s %.3s '%4.4s' '%5.5q' '%.3q'\n", "abc", "abc", "abc", (qstr)MP_QSTR_True, (qstr)MP_QSTR_True); // fixed string precision mp_printf(&mp_plat_print, "%.*s\n", -1, "abc"); // negative string precision mp_printf(&mp_plat_print, "%b %b\n", 0, 1); // bools #ifndef NDEBUG @@ -202,10 +232,36 @@ static mp_obj_t extra_coverage(void) { #endif mp_printf(&mp_plat_print, "%d\n", 0x80000000); // should print signed mp_printf(&mp_plat_print, "%u\n", 0x80000000); // should print unsigned - mp_printf(&mp_plat_print, "%x\n", 0x80000000); // should print unsigned - mp_printf(&mp_plat_print, "%X\n", 0x80000000); // should print unsigned - mp_printf(&mp_plat_print, "abc\n%"); // string ends in middle of format specifier + mp_printf(&mp_plat_print, "%x\n", 0x8000000f); // should print unsigned + mp_printf(&mp_plat_print, "%X\n", 0x8000000f); // should print unsigned + // note: storing the string in a variable is enough to prevent the + // format string checker from checking this format string. Otherwise, + // it would be a compile time diagnostic under the format string + // checker. + const char msg[] = "abc\n%"; + mp_printf(&mp_plat_print, msg); // string ends in middle of format specifier mp_printf(&mp_plat_print, "%%\n"); // literal % character + mp_printf(&mp_plat_print, ".%-3s.\n", "a"); // left adjust + + // Check that all kinds of mp_printf arguments are parsed out + // correctly, by having a char argument before and after each main type + // of value that can be formatted. + mp_printf(&mp_plat_print, "%c%%%c\n", '<', '>'); + mp_printf(&mp_plat_print, "%c%p%c\n", '<', (void *)0xaaaa, '>'); + mp_printf(&mp_plat_print, "%c%b%c\n", '<', true, '>'); + mp_printf(&mp_plat_print, "%c%d%c\n", '<', 0xaaaa, '>'); + mp_printf(&mp_plat_print, "%c%ld%c\n", '<', 0xaaaal, '>'); + mp_printf(&mp_plat_print, "%c" INT_FMT "%c\n", '<', (mp_int_t)0xaaaa, '>'); + mp_printf(&mp_plat_print, "%c%s%c\n", '<', "test", '>'); + mp_printf(&mp_plat_print, "%c%f%c\n", '<', MICROPY_FLOAT_CONST(1000.), '>'); + mp_printf(&mp_plat_print, "%c%q%c\n", '<', (qstr)MP_QSTR_True, '>'); + if (sizeof(mp_int_t) == 8) { + mp_printf(&mp_plat_print, "%c%lld%c\n", '<', LLONG_MAX, '>'); + } else { + mp_printf(&mp_plat_print, "<9223372036854775807>\n"); + } + + } // GC @@ -218,11 +274,11 @@ static mp_obj_t extra_coverage(void) { gc_unlock(); // using gc_realloc to resize to 0, which means free the memory - void *p = gc_alloc(4, false); + void *p = gc_alloc(4, 0); mp_printf(&mp_plat_print, "%p\n", gc_realloc(p, 0, false)); // calling gc_nbytes with a non-heap pointer - mp_printf(&mp_plat_print, "%p\n", gc_nbytes(NULL)); + mp_printf(&mp_plat_print, "%d\n", (int)gc_nbytes(NULL)); } // GC initialisation and allocation stress test, to check the logic behind ALLOC_TABLE_GAP_BYTE @@ -283,7 +339,7 @@ static mp_obj_t extra_coverage(void) { } ptrs[i][j] = j; } - mp_printf(&mp_plat_print, "%d %d\n", i, all_zero); + mp_printf(&mp_plat_print, "%d %d\n", (int)i, (int)all_zero); // hide the pointer from the GC and collect ptrs[i] = FLIP_POINTER(ptrs[i]); @@ -299,7 +355,7 @@ static mp_obj_t extra_coverage(void) { break; } } - mp_printf(&mp_plat_print, "%d %d\n", i, correct_contents); + mp_printf(&mp_plat_print, "%d %d\n", (int)i, (int)correct_contents); } // free the memory blocks @@ -388,7 +444,7 @@ static mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "# str\n"); // intern string - mp_printf(&mp_plat_print, "%d\n", mp_obj_is_qstr(mp_obj_str_intern(mp_obj_new_str("intern me", 9)))); + mp_printf(&mp_plat_print, "%d\n", mp_obj_is_qstr(mp_obj_str_intern(mp_obj_new_str_from_cstr("intern me")))); } // bytearray @@ -398,7 +454,7 @@ static mp_obj_t extra_coverage(void) { // create a bytearray via mp_obj_new_bytearray mp_buffer_info_t bufinfo; mp_get_buffer_raise(mp_obj_new_bytearray(4, "data"), &bufinfo, MP_BUFFER_RW); - mp_printf(&mp_plat_print, "%.*s\n", bufinfo.len, bufinfo.buf); + mp_printf(&mp_plat_print, "%.*s\n", (int)bufinfo.len, bufinfo.buf); } // mpz @@ -455,6 +511,45 @@ static mp_obj_t extra_coverage(void) { mpz_mul_inpl(&mpz, &mpz2, &mpz); mpz_as_uint_checked(&mpz, &value); mp_printf(&mp_plat_print, "%d\n", (int)value); + + // mpz_not_inpl with argument==0, testing ~0 + mpz_set_from_int(&mpz, 0); + mpz_not_inpl(&mpz, &mpz); + mp_int_t value_signed; + mpz_as_int_checked(&mpz, &value_signed); + mp_printf(&mp_plat_print, "%d\n", (int)value_signed); + + // hash the zero mpz integer + mpz_set_from_int(&mpz, 0); + mp_printf(&mp_plat_print, "%d\n", (int)mpz_hash(&mpz)); + + // convert the mpz zero integer to int + mp_printf(&mp_plat_print, "%d\n", mpz_as_int_checked(&mpz, &value_signed)); + mp_printf(&mp_plat_print, "%d\n", (int)value_signed); + + // mpz_set_from_float with 0 as argument + mpz_set_from_float(&mpz, 0); + mp_printf(&mp_plat_print, "%f\n", mpz_as_float(&mpz)); + + // convert a large integer value (stored in a mpz) to mp_uint_t and to ll; + mp_obj_t obj_bigint = mp_obj_new_int_from_uint((mp_uint_t)0xdeadbeef); + mp_printf(&mp_plat_print, "%x\n", (int)mp_obj_get_uint(obj_bigint)); + obj_bigint = mp_obj_new_int_from_ll(0xc0ffee777c0ffeell); + long long value_ll = mp_obj_get_ll(obj_bigint); + mp_printf(&mp_plat_print, "%x%08x\n", (uint32_t)(value_ll >> 32), (uint32_t)value_ll); + + // convert a large integer value (stored via a struct object) to uint and to ll + // `deadbeef` global is an uctypes.struct defined by extra_coverage.py + obj_bigint = mp_load_global(MP_QSTR_deadbeef); + mp_printf(&mp_plat_print, "%x\n", (int)mp_obj_get_uint(obj_bigint)); + value_ll = mp_obj_get_ll(obj_bigint); + mp_printf(&mp_plat_print, "%x%08x\n", (uint32_t)(value_ll >> 32), (uint32_t)value_ll); + + // convert a smaller integer value to mp_uint_t and to ll + obj_bigint = mp_obj_new_int_from_uint(0xc0ffee); + mp_printf(&mp_plat_print, "%x\n", (int)mp_obj_get_uint(obj_bigint)); + value_ll = mp_obj_get_ll(obj_bigint); + mp_printf(&mp_plat_print, "%x%08x\n", (uint32_t)(value_ll >> 32), (uint32_t)value_ll); } // runtime utils @@ -464,12 +559,15 @@ static mp_obj_t extra_coverage(void) { // call mp_call_function_1_protected mp_call_function_1_protected(MP_OBJ_FROM_PTR(&mp_builtin_abs_obj), MP_OBJ_NEW_SMALL_INT(1)); // call mp_call_function_1_protected with invalid args - mp_call_function_1_protected(MP_OBJ_FROM_PTR(&mp_builtin_abs_obj), mp_obj_new_str("abc", 3)); + mp_call_function_1_protected(MP_OBJ_FROM_PTR(&mp_builtin_abs_obj), mp_obj_new_str_from_cstr("abc")); // call mp_call_function_2_protected mp_call_function_2_protected(MP_OBJ_FROM_PTR(&mp_builtin_divmod_obj), MP_OBJ_NEW_SMALL_INT(1), MP_OBJ_NEW_SMALL_INT(1)); // call mp_call_function_2_protected with invalid args - mp_call_function_2_protected(MP_OBJ_FROM_PTR(&mp_builtin_divmod_obj), mp_obj_new_str("abc", 3), mp_obj_new_str("abc", 3)); + mp_call_function_2_protected(MP_OBJ_FROM_PTR(&mp_builtin_divmod_obj), mp_obj_new_str_from_cstr("abc"), mp_obj_new_str_from_cstr("abc")); + + // mp_obj_int_get_checked with mp_obj_int_t that has a value that is a small integer + mp_printf(&mp_plat_print, "%d\n", (int)mp_obj_int_get_checked(MP_OBJ_FROM_PTR(mp_obj_int_new_mpz()))); // mp_obj_int_get_uint_checked with non-negative small-int mp_printf(&mp_plat_print, "%d\n", (int)mp_obj_int_get_uint_checked(MP_OBJ_NEW_SMALL_INT(1))); @@ -494,6 +592,22 @@ static mp_obj_t extra_coverage(void) { mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); } + // mp_obj_get_uint from a non-int object (should raise exception) + if (nlr_push(&nlr) == 0) { + mp_obj_get_uint(mp_const_none); + nlr_pop(); + } else { + mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); + } + + // mp_obj_int_get_ll from a non-int object (should raise exception) + if (nlr_push(&nlr) == 0) { + mp_obj_get_ll(mp_const_none); + nlr_pop(); + } else { + mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); + } + // call mp_obj_new_exception_args (it's a part of the public C API and not used in the core) mp_obj_print_exception(&mp_plat_print, mp_obj_new_exception_args(&mp_type_ValueError, 0, NULL)); } @@ -503,26 +617,6 @@ static mp_obj_t extra_coverage(void) { mp_emitter_warning(MP_PASS_CODE_SIZE, "test"); } - // format float - { - mp_printf(&mp_plat_print, "# format float\n"); - - // format with inadequate buffer size - char buf[5]; - mp_format_float(1, buf, sizeof(buf), 'g', 0, '+'); - mp_printf(&mp_plat_print, "%s\n", buf); - - // format with just enough buffer so that precision must be - // set from 0 to 1 twice - char buf2[8]; - mp_format_float(1, buf2, sizeof(buf2), 'g', 0, '+'); - mp_printf(&mp_plat_print, "%s\n", buf2); - - // format where precision is trimmed to avoid buffer overflow - mp_format_float(1, buf2, sizeof(buf2), 'e', 0, '+'); - mp_printf(&mp_plat_print, "%s\n", buf2); - } - // binary { mp_printf(&mp_plat_print, "# binary\n"); @@ -546,14 +640,26 @@ static mp_obj_t extra_coverage(void) { fun_bc.context = &context; fun_bc.child_table = NULL; fun_bc.bytecode = (const byte *)"\x01"; // just needed for n_state + #if MICROPY_PY_SYS_SETTRACE + struct _mp_raw_code_t rc = {}; + fun_bc.rc = &rc; + #endif mp_code_state_t *code_state = m_new_obj_var(mp_code_state_t, state, mp_obj_t, 1); code_state->fun_bc = &fun_bc; code_state->ip = (const byte *)"\x00"; // just needed for an invalid opcode code_state->sp = &code_state->state[0]; code_state->exc_sp_idx = 0; code_state->old_globals = NULL; + #if MICROPY_STACKLESS + code_state->prev = NULL; + #endif + #if MICROPY_PY_SYS_SETTRACE + code_state->prev_state = NULL; + code_state->frame = NULL; + #endif + mp_vm_return_kind_t ret = mp_execute_bytecode(code_state, MP_OBJ_NULL); - mp_printf(&mp_plat_print, "%d %d\n", ret, mp_obj_get_type(code_state->state[0]) == &mp_type_NotImplementedError); + mp_printf(&mp_plat_print, "%d %d\n", (int)ret, mp_obj_get_type(code_state->state[0]) == &mp_type_NotImplementedError); } // scheduler @@ -610,9 +716,25 @@ static mp_obj_t extra_coverage(void) { mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); } mp_handle_pending(true); + + // CIRCUITPY-CHANGE: not turned on in CircuitPython + #if MICROPY_SCHEDULER_STATIC_NODES + coverage_sched_function_continue = true; + mp_sched_schedule_node(&mp_coverage_sched_node, coverage_sched_function); + for (int i = 0; i < 3; ++i) { + mp_printf(&mp_plat_print, "loop\n"); + mp_handle_pending(true); + } + // Clear this flag to prevent the function scheduling itself again + coverage_sched_function_continue = false; + // Will only run the first time through this loop, then not scheduled again + for (int i = 0; i < 3; ++i) { + mp_handle_pending(true); + } + #endif } - // CIRCUITPY-CHANGE: ringbuf is different + // CIRCUITPY-CHANGE: ringbuf is quite different // ringbuf { #define RINGBUF_SIZE 99 @@ -624,36 +746,36 @@ static mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "# ringbuf\n"); // Single-byte put/get with empty ringbuf. - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); ringbuf_put(&ringbuf, 22); - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); mp_printf(&mp_plat_print, "%d\n", ringbuf_get(&ringbuf)); - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); // Two-byte put/get with empty ringbuf. ringbuf_put16(&ringbuf, 0xaa55); - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf)); - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); // Two-byte put with full ringbuf. for (int i = 0; i < RINGBUF_SIZE; ++i) { ringbuf_put(&ringbuf, i); } - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); mp_printf(&mp_plat_print, "%d\n", ringbuf_put16(&ringbuf, 0x11bb)); // Two-byte put with one byte free. ringbuf_get(&ringbuf); - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); mp_printf(&mp_plat_print, "%d\n", ringbuf_put16(&ringbuf, 0x3377)); ringbuf_get(&ringbuf); - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); mp_printf(&mp_plat_print, "%d\n", ringbuf_put16(&ringbuf, 0xcc99)); for (int i = 0; i < RINGBUF_SIZE - 2; ++i) { ringbuf_get(&ringbuf); } mp_printf(&mp_plat_print, "%04x\n", ringbuf_get16(&ringbuf)); - mp_printf(&mp_plat_print, "%d %d\n", ringbuf_num_empty(&ringbuf), ringbuf_num_filled(&ringbuf)); + mp_printf(&mp_plat_print, "%d %d\n", (int)ringbuf_num_empty(&ringbuf), (int)ringbuf_num_filled(&ringbuf)); // Two-byte put with wrap around on first byte: ringbuf_clear(&ringbuf); @@ -723,12 +845,38 @@ static mp_obj_t extra_coverage(void) { // mp_obj_is_integer accepts ints and booleans mp_printf(&mp_plat_print, "%d %d\n", mp_obj_is_integer(MP_OBJ_NEW_SMALL_INT(1)), mp_obj_is_integer(mp_obj_new_int_from_ll(1))); mp_printf(&mp_plat_print, "%d %d\n", mp_obj_is_integer(mp_const_true), mp_obj_is_integer(mp_const_false)); - mp_printf(&mp_plat_print, "%d %d\n", mp_obj_is_integer(mp_obj_new_str("1", 1)), mp_obj_is_integer(mp_const_none)); + mp_printf(&mp_plat_print, "%d %d\n", mp_obj_is_integer(mp_obj_new_str_from_cstr("1")), mp_obj_is_integer(mp_const_none)); // mp_obj_is_int accepts small int and object ints mp_printf(&mp_plat_print, "%d %d\n", mp_obj_is_int(MP_OBJ_NEW_SMALL_INT(1)), mp_obj_is_int(mp_obj_new_int_from_ll(1))); } + // Legacy stackctrl.h API, this has been replaced by cstack.h + { + mp_printf(&mp_plat_print, "# stackctrl\n"); + char *old_stack_top = MP_STATE_THREAD(stack_top); + size_t old_stack_limit = 0; + size_t new_stack_limit = SIZE_MAX; + #if MICROPY_STACK_CHECK + old_stack_limit = MP_STATE_THREAD(stack_limit); + MP_STACK_CHECK(); + #endif + + mp_stack_ctrl_init(); // Will set stack top incorrectly + mp_stack_set_top(old_stack_top); // ... and restore it + + #if MICROPY_STACK_CHECK + mp_stack_set_limit(MP_STATE_THREAD(stack_limit)); + MP_STACK_CHECK(); + new_stack_limit = MP_STATE_THREAD(stack_limit); + #endif + + // Nothing should have changed + mp_printf(&mp_plat_print, "%d %d\n", + old_stack_top == MP_STATE_THREAD(stack_top), + MICROPY_STACK_CHECK == 0 || old_stack_limit == new_stack_limit); + } + mp_printf(&mp_plat_print, "# end coverage.c\n"); mp_obj_streamtest_t *s = mp_obj_malloc(mp_obj_streamtest_t, &mp_type_stest_fileio); @@ -739,7 +887,7 @@ static mp_obj_t extra_coverage(void) { mp_obj_streamtest_t *s2 = mp_obj_malloc(mp_obj_streamtest_t, &mp_type_stest_textio2); // return a tuple of data for testing on the Python side - mp_obj_t items[] = {(mp_obj_t)&str_no_hash_obj, (mp_obj_t)&bytes_no_hash_obj, MP_OBJ_FROM_PTR(s), MP_OBJ_FROM_PTR(s2)}; + mp_obj_t items[] = {MP_OBJ_FROM_PTR(&str_no_hash_obj), MP_OBJ_FROM_PTR(&bytes_no_hash_obj), MP_OBJ_FROM_PTR(s), MP_OBJ_FROM_PTR(s2)}; return mp_obj_new_tuple(MP_ARRAY_SIZE(items), items); } MP_DEFINE_CONST_FUN_OBJ_0(extra_coverage_obj, extra_coverage); diff --git a/ports/unix/coveragecpp.cpp b/ports/unix/coveragecpp.cpp index 93c1b387fe2..8ba308f6468 100644 --- a/ports/unix/coveragecpp.cpp +++ b/ports/unix/coveragecpp.cpp @@ -1,11 +1,77 @@ extern "C" { -#include "py/obj.h" +// Include the complete public API to verify everything compiles as C++. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include } +// Invoke all (except one, see below) public API macros which initialize structs to make sure +// they are C++-compatible, meaning they explicitly initialize all struct members. +mp_obj_t f0(); +MP_DEFINE_CONST_FUN_OBJ_0(f0_obj, f0); +mp_obj_t f1(mp_obj_t); +MP_DEFINE_CONST_FUN_OBJ_1(f1_obj, f1); +mp_obj_t f2(mp_obj_t, mp_obj_t); +MP_DEFINE_CONST_FUN_OBJ_2(f2_obj, f2); +mp_obj_t f3(mp_obj_t, mp_obj_t, mp_obj_t); +MP_DEFINE_CONST_FUN_OBJ_3(f3_obj, f3); +mp_obj_t fvar(size_t, const mp_obj_t *); +MP_DEFINE_CONST_FUN_OBJ_VAR(fvar_obj, 1, fvar); +mp_obj_t fvarbetween(size_t, const mp_obj_t *); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fvarbetween_obj, 1, 2, fvarbetween); +mp_obj_t fkw(size_t, const mp_obj_t *, mp_map_t *); +MP_DEFINE_CONST_FUN_OBJ_KW(fkw_obj, 1, fkw); + +static const mp_rom_map_elem_t table[] = { + { MP_ROM_QSTR(MP_QSTR_f0), MP_ROM_PTR(&f0_obj) }, +}; +MP_DEFINE_CONST_MAP(map, table); +MP_DEFINE_CONST_DICT(dict, table); + +static const qstr attrtuple_fields[] = { + MP_QSTR_f0, +}; +MP_DEFINE_ATTRTUPLE(attrtuple, attrtuple_fields, 1, MP_ROM_PTR(&f0_obj)); + +void nlr_cb(void *); +void nlr_cb(void *){ +} + +// The MP_DEFINE_CONST_OBJ_TYPE macro is not C++-compatible because each of the +// MP_DEFINE_CONST_OBJ_TYPE_NARGS_X macros only initializes some of _mp_obj_type_t's +// .slot_index_xxx members but that cannot be fixed to be done in a deterministic way. + + #if defined(MICROPY_UNIX_COVERAGE) // Just to test building of C++ code. static mp_obj_t extra_cpp_coverage_impl() { + MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, nlr_cb, (void *) nlr_cb); + + // To avoid 'error: unused variable [-Werror,-Wunused-const-variable]'. + (void) ctx; + (void) f0_obj; + (void) f1_obj; + (void) f2_obj; + (void) f3_obj; + (void) fvar_obj; + (void) fvarbetween_obj; + (void) fkw_obj; + (void) map; + (void) dict; + (void) attrtuple; return mp_const_none; } diff --git a/ports/unix/displayio_min.c b/ports/unix/displayio_min.c index 3d0d5efc3ce..06b57d04df2 100644 --- a/ports/unix/displayio_min.c +++ b/ports/unix/displayio_min.c @@ -74,3 +74,16 @@ const mp_obj_module_t displayio_module = { }; MP_REGISTER_MODULE(MP_QSTR_displayio, displayio_module); + +displayio_buffer_transform_t null_transform = { + .x = 0, + .y = 0, + .dx = 1, + .dy = 1, + .scale = 1, + .width = 0, + .height = 0, + .mirror_x = false, + .mirror_y = false, + .transpose_xy = false +}; diff --git a/ports/unix/gccollect.c b/ports/unix/gccollect.c index 94c9c61ea4d..8f0f5a6769d 100644 --- a/ports/unix/gccollect.c +++ b/ports/unix/gccollect.c @@ -39,9 +39,6 @@ void gc_collect(void) { #if MICROPY_PY_THREAD mp_thread_gc_others(); #endif - #if MICROPY_EMIT_NATIVE - mp_unix_mark_exec(); - #endif gc_collect_end(); } diff --git a/ports/unix/input.c b/ports/unix/input.c index 31926a5a8e1..260e9eac8c9 100644 --- a/ports/unix/input.c +++ b/ports/unix/input.c @@ -104,6 +104,9 @@ void prompt_write_history(void) { #if MICROPY_USE_READLINE == 1 char *home = getenv("HOME"); if (home != NULL) { + if (MP_STATE_THREAD(gc_lock_depth) != 0) { + return; + } vstr_t vstr; vstr_init(&vstr, 50); vstr_printf(&vstr, "%s/.micropython.history", home); diff --git a/ports/unix/main.c b/ports/unix/main.c index 28521c12514..e42400fe5f9 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -44,7 +44,8 @@ #include "py/repl.h" #include "py/gc.h" #include "py/objstr.h" -#include "py/stackctrl.h" +#include "py/cstack.h" +#include "py/mperrno.h" #include "py/mphal.h" #include "py/mpthread.h" #include "extmod/misc.h" @@ -53,38 +54,11 @@ #include "extmod/vfs_posix.h" #include "genhdr/mpversion.h" #include "input.h" - -// CIRCUITPY-CHANGE -#if defined(MICROPY_UNIX_COVERAGE) -#include "py/objstr.h" -typedef int os_getenv_err_t; -mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_); -os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len); -os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); - -static mp_obj_t mod_os_getenv_int(mp_obj_t var_in) { - mp_int_t value; - os_getenv_err_t result = common_hal_os_getenv_int(mp_obj_str_get_str(var_in), &value); - if (result == 0) { - return mp_obj_new_int(value); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_int_obj, mod_os_getenv_int); - -static mp_obj_t mod_os_getenv_str(mp_obj_t var_in) { - char buf[4096]; - os_getenv_err_t result = common_hal_os_getenv_str(mp_obj_str_get_str(var_in), buf, sizeof(buf)); - if (result == 0) { - return mp_obj_new_str_copy(&mp_type_str, (byte *)buf, strlen(buf)); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(mod_os_getenv_str_obj, mod_os_getenv_str); -#endif +#include "stack_size.h" +#include "shared/runtime/pyexec.h" // Command line options, with their defaults -static bool compile_only = false; +bool mp_compile_only = false; static uint emit_opt = MP_EMIT_OPT_NONE; #if MICROPY_ENABLE_GC @@ -118,7 +92,8 @@ static void stderr_print_strn(void *env, const char *str, size_t len) { const mp_print_t mp_stderr_print = {NULL, stderr_print_strn}; -#define FORCED_EXIT (0x100) +// CIRCUITPY-CHANGE: be consistent about using PYEXEC_FORCED_EXIT +// #define FORCED_EXIT (0x100) // If exc is SystemExit, return value where FORCED_EXIT bit set, // and lower 8 bits are SystemExit value. For all other exceptions, // return 1. @@ -131,7 +106,8 @@ static int handle_uncaught_exception(mp_obj_base_t *exc) { if (exit_val != mp_const_none && !mp_obj_get_int_maybe(exit_val, &val)) { val = 1; } - return FORCED_EXIT | (val & 255); + // CIRCUITPY-CHANGE: be consistent about using PYEXEC_FORCED_EXIT + return PYEXEC_FORCED_EXIT | (val & 255); } // Report all other exceptions @@ -140,8 +116,6 @@ static int handle_uncaught_exception(mp_obj_base_t *exc) { } #define LEX_SRC_STR (1) -#define LEX_SRC_VSTR (2) -#define LEX_SRC_FILENAME (3) #define LEX_SRC_STDIN (4) // Returns standard error codes: 0 for success, 1 for all other errors, @@ -157,19 +131,13 @@ static int execute_from_lexer(int source_kind, const void *source, mp_parse_inpu if (source_kind == LEX_SRC_STR) { const char *line = source; lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false); - } else if (source_kind == LEX_SRC_VSTR) { - const vstr_t *vstr = source; - lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, false); - } else if (source_kind == LEX_SRC_FILENAME) { - const char *filename = (const char *)source; - lex = mp_lexer_new_from_file(qstr_from_str(filename)); } else { // LEX_SRC_STDIN lex = mp_lexer_new_from_fd(MP_QSTR__lt_stdin_gt_, 0, false); } qstr source_name = lex->source_name; - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ if (input_kind == MP_PARSE_FILE_INPUT) { mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } @@ -188,7 +156,7 @@ static int execute_from_lexer(int source_kind, const void *source, mp_parse_inpu mp_obj_t module_fun = mp_compile(&parse_tree, source_name, is_repl); - if (!compile_only) { + if (!mp_compile_only) { // execute it mp_call_function_0(module_fun); } @@ -225,92 +193,32 @@ static char *strjoin(const char *s1, int sep_char, const char *s2) { #endif static int do_repl(void) { - mp_hal_stdout_tx_str(MICROPY_BANNER_NAME_AND_VERSION); - mp_hal_stdout_tx_str("; " MICROPY_BANNER_MACHINE); - mp_hal_stdout_tx_str("\nUse Ctrl-D to exit, Ctrl-E for paste mode\n"); - #if MICROPY_USE_READLINE == 1 - // use MicroPython supplied readline + // use MicroPython supplied readline-based REPL - vstr_t line; - vstr_init(&line, 16); + int ret = 0; for (;;) { - mp_hal_stdio_mode_raw(); - - input_restart: - vstr_reset(&line); - int ret = readline(&line, mp_repl_get_ps1()); - mp_parse_input_kind_t parse_input_kind = MP_PARSE_SINGLE_INPUT; - - if (ret == CHAR_CTRL_C) { - // cancel input - mp_hal_stdout_tx_str("\r\n"); - goto input_restart; - } else if (ret == CHAR_CTRL_D) { - // EOF - printf("\n"); - mp_hal_stdio_mode_orig(); - vstr_clear(&line); - return 0; - } else if (ret == CHAR_CTRL_E) { - // paste mode - mp_hal_stdout_tx_str("\npaste mode; Ctrl-C to cancel, Ctrl-D to finish\n=== "); - vstr_reset(&line); - for (;;) { - char c = mp_hal_stdin_rx_chr(); - if (c == CHAR_CTRL_C) { - // cancel everything - mp_hal_stdout_tx_str("\n"); - goto input_restart; - } else if (c == CHAR_CTRL_D) { - // end of input - mp_hal_stdout_tx_str("\n"); - break; - } else { - // add char to buffer and echo - vstr_add_byte(&line, c); - if (c == '\r') { - mp_hal_stdout_tx_str("\n=== "); - } else { - mp_hal_stdout_tx_strn(&c, 1); - } - } - } - parse_input_kind = MP_PARSE_FILE_INPUT; - } else if (line.len == 0) { - if (ret != 0) { - printf("\n"); + if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) { + if ((ret = pyexec_raw_repl()) != 0) { + break; } - goto input_restart; } else { - // got a line with non-zero length, see if it needs continuing - while (mp_repl_continue_with_input(vstr_null_terminated_str(&line))) { - vstr_add_byte(&line, '\n'); - ret = readline(&line, mp_repl_get_ps2()); - if (ret == CHAR_CTRL_C) { - // cancel everything - printf("\n"); - goto input_restart; - } else if (ret == CHAR_CTRL_D) { - // stop entering compound statement - break; - } + if ((ret = pyexec_friendly_repl()) != 0) { + break; } } - - mp_hal_stdio_mode_orig(); - - ret = execute_from_lexer(LEX_SRC_VSTR, &line, parse_input_kind, true); - if (ret & FORCED_EXIT) { - return ret; - } } + return ret; #else // use simple readline + mp_hal_stdout_tx_str(MICROPY_BANNER_NAME_AND_VERSION); + mp_hal_stdout_tx_str("; " MICROPY_BANNER_MACHINE); + mp_hal_stdout_tx_str("\nUse Ctrl-D to exit, Ctrl-E for paste mode\n"); + for (;;) { char *line = prompt((char *)mp_repl_get_ps1()); if (line == NULL) { @@ -330,7 +238,8 @@ static int do_repl(void) { int ret = execute_from_lexer(LEX_SRC_STR, line, MP_PARSE_SINGLE_INPUT, true); free(line); - if (ret & FORCED_EXIT) { + // CIRCUITPY-CHANGE: be consistent about using PYEXEC_FORCED_EXIT + if (ret & PYEXEC_FORCED_EXIT) { return ret; } } @@ -338,18 +247,51 @@ static int do_repl(void) { #endif } +static inline int convert_pyexec_result(int ret) { + #if MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING + // With exit code handling enabled: + // pyexec returns exit code with PYEXEC_FORCED_EXIT flag set for SystemExit + // Unix port expects: 0 for success, non-zero for error/exit + if (ret & PYEXEC_FORCED_EXIT) { + // SystemExit: extract exit code from lower bits + return ret & 0xFF; + } + // Normal execution or exception: return as-is (0 for success, 1 for exception) + return ret; + #else + // pyexec returns 1 for success, 0 for exception, PYEXEC_FORCED_EXIT for SystemExit + // Convert to unix port's expected codes: 0 for success, 1 for exception, FORCED_EXIT|val for SystemExit + if (ret == 1) { + return 0; // success + } else if (ret & PYEXEC_FORCED_EXIT) { + return ret; // SystemExit with exit value in lower 8 bits + } else { + return 1; // exception + } + #endif +} + static int do_file(const char *file) { - return execute_from_lexer(LEX_SRC_FILENAME, file, MP_PARSE_FILE_INPUT, false); + // CIRCUITPY-CHANGE: pyexec_file result arg + pyexec_result_t pyexec_result; + return convert_pyexec_result(pyexec_file(file, &pyexec_result)); } static int do_str(const char *str) { - return execute_from_lexer(LEX_SRC_STR, str, MP_PARSE_FILE_INPUT, false); + vstr_t vstr; + vstr.buf = (char *)str; + vstr.len = strlen(str); + // CIRCUITPY-CHANGE: pyexec_vstr result arg + pyexec_result_t pyexec_result; + int ret = pyexec_vstr(&vstr, true, &pyexec_result); + return convert_pyexec_result(ret); } static void print_help(char **argv) { printf( "usage: %s [] [-X ] [-c | -m | ]\n" "Options:\n" + "--version : show version information\n" "-h : print this help message\n" "-i : enable inspection via REPL after running command/module/file\n" #if MICROPY_DEBUG_PRINTERS @@ -401,13 +343,17 @@ static void pre_process_options(int argc, char **argv) { print_help(argv); exit(0); } + if (strcmp(argv[a], "--version") == 0) { + printf(MICROPY_BANNER_NAME_AND_VERSION "; " MICROPY_BANNER_MACHINE "\n"); + exit(0); + } if (strcmp(argv[a], "-X") == 0) { if (a + 1 >= argc) { exit(invalid_args()); } if (0) { } else if (strcmp(argv[a + 1], "compile-only") == 0) { - compile_only = true; + mp_compile_only = true; } else if (strcmp(argv[a + 1], "emit=bytecode") == 0) { emit_opt = MP_EMIT_OPT_BYTECODE; #if MICROPY_EMIT_NATIVE @@ -479,10 +425,13 @@ static void set_sys_argv(char *argv[], int argc, int start_arg) { #if MICROPY_PY_SYS_EXECUTABLE extern mp_obj_str_t mp_sys_executable_obj; -static char executable_path[MICROPY_ALLOC_PATH_MAX]; +static char *executable_path = NULL; static void sys_set_excecutable(char *argv0) { - if (realpath(argv0, executable_path)) { + if (executable_path == NULL) { + executable_path = realpath(argv0, NULL); + } + if (executable_path != NULL) { mp_obj_str_set_data(&mp_sys_executable_obj, (byte *)executable_path, strlen(executable_path)); } } @@ -500,12 +449,16 @@ int main(int argc, char **argv) { #if MICROPY_PY_THREAD mp_thread_init(); #endif + + // Define a reasonable stack limit to detect stack overflow. + mp_uint_t stack_size = 40000 * UNIX_STACK_MULTIPLIER; + // We should capture stack top ASAP after start, and it should be // captured guaranteedly before any other stack variables are allocated. // For this, actual main (renamed main_) should not be inlined into // this function. main_() itself may have other functions inlined (with // their own stack variables), that's why we need this main/main_ split. - mp_stack_ctrl_init(); + mp_cstack_init_with_sp_here(stack_size); return main_(argc, argv); } @@ -524,14 +477,6 @@ MP_NOINLINE int main_(int argc, char **argv) { signal(SIGPIPE, SIG_IGN); #endif - // Define a reasonable stack limit to detect stack overflow. - mp_uint_t stack_limit = 40000 * (sizeof(void *) / 4); - #if defined(__arm__) && !defined(__thumb2__) - // ARM (non-Thumb) architectures require more stack. - stack_limit *= 2; - #endif - mp_stack_set_limit(stack_limit); - pre_process_options(argc, argv); #if MICROPY_ENABLE_GC @@ -575,7 +520,14 @@ MP_NOINLINE int main_(int argc, char **argv) { MP_OBJ_NEW_QSTR(MP_QSTR__slash_), }; mp_vfs_mount(2, args, (mp_map_t *)&mp_const_empty_map); + + // Make sure the root that was just mounted is the current VFS (it's always at + // the end of the linked list). Can't use chdir('/') because that will change + // the current path within the VfsPosix object. MP_STATE_VM(vfs_cur) = MP_STATE_VM(vfs_mount_table); + while (MP_STATE_VM(vfs_cur)->next != NULL) { + MP_STATE_VM(vfs_cur) = MP_STATE_VM(vfs_cur)->next; + } } #endif @@ -594,7 +546,12 @@ MP_NOINLINE int main_(int argc, char **argv) { // First entry is empty. We've already added an empty entry to sys.path, so skip it. ++path; } - bool path_remaining = *path; + // GCC targeting RISC-V 64 reports a warning about `path_remaining` being clobbered by + // either setjmp or vfork if that variable it is allocated on the stack. This may + // probably be a compiler error as it occurs on a few recent GCC releases (up to 14.1.0) + // but LLVM doesn't report any warnings. + static bool path_remaining; + path_remaining = *path; while (path_remaining) { char *path_entry_end = strchr(path, PATHLIST_SEP_CHAR); if (path_entry_end == NULL) { @@ -627,24 +584,9 @@ MP_NOINLINE int main_(int argc, char **argv) { // CIRCUITPY-CHANGE: test native base classes work as needed by CircuitPython libraries. extern const mp_obj_type_t native_base_class_type; mp_store_global(MP_QSTR_NativeBaseClass, MP_OBJ_FROM_PTR(&native_base_class_type)); - mp_store_global(MP_QSTR_getenv_int, MP_OBJ_FROM_PTR(&mod_os_getenv_int_obj)); - mp_store_global(MP_QSTR_getenv_str, MP_OBJ_FROM_PTR(&mod_os_getenv_str_obj)); } #endif - // Here is some example code to create a class and instance of that class. - // First is the Python, then the C code. - // - // class TestClass: - // pass - // test_obj = TestClass() - // test_obj.attr = 42 - // - // mp_obj_t test_class_type, test_class_instance; - // test_class_type = mp_obj_new_type(qstr_from_str("TestClass"), mp_const_empty_tuple, mp_obj_new_dict(0)); - // mp_store_name(qstr_from_str("test_obj"), test_class_instance = mp_call_function_0(test_class_type)); - // mp_store_attr(test_class_instance, qstr_from_str("attr"), mp_obj_new_int(42)); - /* printf("bytes:\n"); printf(" total %d\n", m_get_total_bytes_allocated()); @@ -676,7 +618,7 @@ MP_NOINLINE int main_(int argc, char **argv) { return invalid_args(); } mp_obj_t import_args[4]; - import_args[0] = mp_obj_new_str(argv[a + 1], strlen(argv[a + 1])); + import_args[0] = mp_obj_new_str_from_cstr(argv[a + 1]); import_args[1] = import_args[2] = mp_const_none; // Ask __import__ to handle imported module specially - set its __name__ // to __main__, and also return this leaf module, not top-level package @@ -698,12 +640,18 @@ MP_NOINLINE int main_(int argc, char **argv) { subpkg_tried = false; reimport: + mp_hal_set_interrupt_char(CHAR_CTRL_C); if (nlr_push(&nlr) == 0) { mod = mp_builtin___import__(MP_ARRAY_SIZE(import_args), import_args); + mp_hal_set_interrupt_char(-1); + mp_handle_pending(true); nlr_pop(); } else { // uncaught exception - return handle_uncaught_exception(nlr.ret_val) & 0xff; + mp_hal_set_interrupt_char(-1); + mp_handle_pending(false); + ret = handle_uncaught_exception(nlr.ret_val) & 0xff; + break; } // If this module is a package, see if it has a `__main__.py`. @@ -740,11 +688,9 @@ MP_NOINLINE int main_(int argc, char **argv) { return invalid_args(); } } else { - char *pathbuf = malloc(PATH_MAX); - char *basedir = realpath(argv[a], pathbuf); + char *basedir = realpath(argv[a], NULL); if (basedir == NULL) { mp_printf(&mp_stderr_print, "%s: can't open file '%s': [Errno %d] %s\n", argv[0], argv[a], errno, strerror(errno)); - free(pathbuf); // CPython exits with 2 in such case ret = 2; break; @@ -753,7 +699,7 @@ MP_NOINLINE int main_(int argc, char **argv) { // Set base dir of the script as first entry in sys.path. char *p = strrchr(basedir, '/'); mp_obj_list_store(mp_sys_path, MP_OBJ_NEW_SMALL_INT(0), mp_obj_new_str_via_qstr(basedir, p - basedir)); - free(pathbuf); + free(basedir); set_sys_argv(argv, argc, a); ret = do_file(argv[a]); @@ -793,7 +739,7 @@ MP_NOINLINE int main_(int argc, char **argv) { #endif #if MICROPY_PY_BLUETOOTH - void mp_bluetooth_deinit(void); + int mp_bluetooth_deinit(void); mp_bluetooth_deinit(); #endif @@ -819,8 +765,20 @@ MP_NOINLINE int main_(int argc, char **argv) { #endif #endif + #if MICROPY_PY_SYS_EXECUTABLE && !defined(NDEBUG) + // Again, make memory leak detector happy + free(executable_path); + #endif + // printf("total bytes = %d\n", m_get_total_bytes_allocated()); - return ret & 0xff; + + // CIRCUITPY-CHANGE: handle PYEXEC_EXCEPTION + if (ret & PYEXEC_EXCEPTION) { + // Return exit status code 1 so the invoker knows there was an uncaught exception. + return 1; + } else { + return ret & 0xff; + } } void nlr_jump_fail(void *val) { @@ -830,3 +788,22 @@ void nlr_jump_fail(void *val) { fprintf(stderr, "FATAL: uncaught NLR %p\n", val); exit(1); } + +#if MICROPY_VFS_ROM_IOCTL + +static uint8_t romfs_buf[4] = { 0xd2, 0xcd, 0x31, 0x00 }; // empty ROMFS +static const MP_DEFINE_MEMORYVIEW_OBJ(romfs_obj, 'B', 0, sizeof(romfs_buf), romfs_buf); + +mp_obj_t mp_vfs_rom_ioctl(size_t n_args, const mp_obj_t *args) { + switch (mp_obj_get_int(args[0])) { + case MP_VFS_ROM_IOCTL_GET_NUMBER_OF_SEGMENTS: + return MP_OBJ_NEW_SMALL_INT(1); + + case MP_VFS_ROM_IOCTL_GET_SEGMENT: + return MP_OBJ_FROM_PTR(&romfs_obj); + } + + return MP_OBJ_NEW_SMALL_INT(-MP_EINVAL); +} + +#endif diff --git a/ports/unix/mbedtls/mbedtls_config_port.h b/ports/unix/mbedtls/mbedtls_config_port.h index c619de9b8b1..aec65e6581e 100644 --- a/ports/unix/mbedtls/mbedtls_config_port.h +++ b/ports/unix/mbedtls/mbedtls_config_port.h @@ -32,7 +32,18 @@ // Enable mbedtls modules #define MBEDTLS_TIMING_C +#if defined(MICROPY_UNIX_COVERAGE) +// Test the "bare metal" memory management in the coverage build +#define MICROPY_MBEDTLS_CONFIG_BARE_METAL (1) +#endif + // Include common mbedtls configuration. #include "extmod/mbedtls/mbedtls_config_common.h" +#if defined(MICROPY_UNIX_COVERAGE) +// See comment above, but fall back to the default platform entropy functions +#undef MBEDTLS_ENTROPY_HARDWARE_ALT +#undef MBEDTLS_NO_PLATFORM_ENTROPY +#endif + #endif /* MICROPY_INCLUDED_MBEDTLS_CONFIG_H */ diff --git a/ports/unix/modffi.c b/ports/unix/modffi.c index b7d03e84dde..b469e932e0d 100644 --- a/ports/unix/modffi.c +++ b/ports/unix/modffi.c @@ -174,7 +174,7 @@ static mp_obj_t return_ffi_value(ffi_union_t *val, char type) { if (!s) { return mp_const_none; } - return mp_obj_new_str(s, strlen(s)); + return mp_obj_new_str_from_cstr(s); } case 'v': return mp_const_none; @@ -190,10 +190,13 @@ static mp_obj_t return_ffi_value(ffi_union_t *val, char type) { case 'h': case 'i': case 'l': - return mp_obj_new_int((signed)val->ffi); + return mp_obj_new_int((ffi_sarg)val->ffi); + case 'I': + // On RV64, 32-bit values are stored as signed integers inside the + // holding register. + return mp_obj_new_int_from_uint(val->ffi & 0xFFFFFFFF); case 'B': case 'H': - case 'I': case 'L': return mp_obj_new_int_from_uint(val->ffi); case 'q': @@ -334,7 +337,8 @@ static mp_obj_t mod_ffi_callback(size_t n_args, const mp_obj_t *pos_args, mp_map const char *rettype = mp_obj_str_get_str(rettype_in); mp_int_t nparams = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(paramtypes_in)); - mp_obj_fficallback_t *o = mp_obj_malloc_var(mp_obj_fficallback_t, params, ffi_type *, nparams, &fficallback_type); + mp_obj_fficallback_t *o = (mp_obj_fficallback_t *)m_tracked_calloc(offsetof(mp_obj_fficallback_t, params) + sizeof(ffi_type *) * nparams, sizeof(uint8_t)); + o->base.type = &fficallback_type; o->clo = ffi_closure_alloc(sizeof(ffi_closure), &o->func); diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index d953e7e0152..dbce61aec11 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -337,7 +337,7 @@ static mp_obj_t new_jobject(jobject jo) { return mp_const_none; } else if (JJ(IsInstanceOf, jo, String_class)) { const char *s = JJ(GetStringUTFChars, jo, NULL); - mp_obj_t ret = mp_obj_new_str(s, strlen(s)); + mp_obj_t ret = mp_obj_new_str_from_cstr(s); JJ(ReleaseStringUTFChars, jo, s); return ret; } else if (JJ(IsInstanceOf, jo, Class_class)) { diff --git a/ports/unix/modmachine.c b/ports/unix/modmachine.c index 6f3ab809440..d1cdbe8619a 100644 --- a/ports/unix/modmachine.c +++ b/ports/unix/modmachine.c @@ -36,9 +36,6 @@ #define MICROPY_PAGE_MASK (MICROPY_PAGE_SIZE - 1) #endif -// This variable is needed for machine.soft_reset(), but the variable is otherwise unused. -int pyexec_system_exit = 0; - uintptr_t mod_machine_mem_get_addr(mp_obj_t addr_o, uint align) { uintptr_t addr = mp_obj_get_int_truncated(addr_o); if ((addr & (align - 1)) != 0) { diff --git a/ports/unix/modos.c b/ports/unix/modos.c index 09d82984310..af8a1cc4da8 100644 --- a/ports/unix/modos.c +++ b/ports/unix/modos.c @@ -32,13 +32,12 @@ #include "py/runtime.h" #include "py/mphal.h" -// CIRCUITPY-CHANGE: enhanced getenv +// CIRCUITPY-CHANGE: use shared-module os getenv #if defined(MICROPY_UNIX_COVERAGE) #include "py/objstr.h" -typedef int os_getenv_err_t; +#include "shared-module/os/__init__.h" +#include "supervisor/shared/settings.h" mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_); -os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len); -os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); #endif static mp_obj_t mp_os_getenv(size_t n_args, const mp_obj_t *args) { @@ -56,32 +55,9 @@ static mp_obj_t mp_os_getenv(size_t n_args, const mp_obj_t *args) { } return mp_const_none; } - return mp_obj_new_str(s, strlen(s)); + return mp_obj_new_str_from_cstr(s); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_os_getenv_obj, 1, 2, mp_os_getenv); - -// CIRCUITPY-CHANGE: getenv differences -#if defined(MICROPY_UNIX_COVERAGE) -static mp_obj_t mp_os_getenv_int(mp_obj_t var_in) { - mp_int_t value; - os_getenv_err_t result = common_hal_os_getenv_int(mp_obj_str_get_str(var_in), &value); - if (result == 0) { - return mp_obj_new_int(value); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(mp_os_getenv_int_obj, mp_os_getenv_int); - -static mp_obj_t mp_os_getenv_str(mp_obj_t var_in) { - char buf[4096]; - os_getenv_err_t result = common_hal_os_getenv_str(mp_obj_str_get_str(var_in), buf, sizeof(buf)); - if (result == 0) { - return mp_obj_new_str_copy(&mp_type_str, (byte *)buf, strlen(buf)); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(mp_os_getenv_str_obj, mp_os_getenv_str); -#endif +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_os_getenv_obj, 1, 2, mp_os_getenv); static mp_obj_t mp_os_putenv(mp_obj_t key_in, mp_obj_t value_in) { const char *key = mp_obj_str_get_str(key_in); diff --git a/ports/unix/modtermios.c b/ports/unix/modtermios.c index b1ad9a450e0..d7b94038aa1 100644 --- a/ports/unix/modtermios.c +++ b/ports/unix/modtermios.c @@ -141,6 +141,27 @@ static const mp_rom_map_elem_t mp_module_termios_globals_table[] = { #ifdef B115200 C(B115200), #endif + #ifdef B230400 + C(B230400), + #endif + #ifdef B460800 + C(B460800), + #endif + #ifdef B500000 + C(B500000), + #endif + #ifdef B576000 + C(B576000), + #endif + #ifdef B921600 + C(B921600), + #endif + #ifdef B1000000 + C(B1000000), + #endif + #ifdef B1152000 + C(B1152000) + #endif #undef C }; diff --git a/ports/unix/modtime.c b/ports/unix/modtime.c index fbd94b5ecd1..4f0550dbea7 100644 --- a/ports/unix/modtime.c +++ b/ports/unix/modtime.c @@ -34,6 +34,7 @@ #include "py/mphal.h" #include "py/runtime.h" +#include "shared/timeutils/timeutils.h" #ifdef _WIN32 static inline int msec_sleep_tv(struct timeval *tv) { @@ -130,12 +131,7 @@ static mp_obj_t mod_time_gm_local_time(size_t n_args, const mp_obj_t *args, stru if (n_args == 0) { t = time(NULL); } else { - #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE - mp_float_t val = mp_obj_get_float(args[0]); - t = (time_t)MICROPY_FLOAT_C_FUN(trunc)(val); - #else - t = mp_obj_get_int(args[0]); - #endif + t = (time_t)timeutils_obj_get_timestamp(args[0]); } struct tm *tm = time_func(&t); @@ -193,10 +189,10 @@ static mp_obj_t mod_time_mktime(mp_obj_t tuple) { time.tm_isdst = -1; // auto-detect } time_t ret = mktime(&time); - if (ret == -1) { + if (ret == (time_t)-1) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("invalid mktime usage")); } - return mp_obj_new_int(ret); + return timeutils_obj_from_timestamp(ret); } MP_DEFINE_CONST_FUN_OBJ_1(mod_time_mktime_obj, mod_time_mktime); diff --git a/ports/unix/mpbthciport.c b/ports/unix/mpbthciport.c index 95c39f55991..765146677e8 100644 --- a/ports/unix/mpbthciport.c +++ b/ports/unix/mpbthciport.c @@ -196,10 +196,7 @@ int mp_bluetooth_hci_uart_init(uint32_t port, uint32_t baudrate) { } // Create a thread to run the polling loop. - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&hci_poll_thread_id, &attr, &hci_poll_thread, NULL); + pthread_create(&hci_poll_thread_id, NULL, &hci_poll_thread, NULL); return 0; } diff --git a/ports/unix/mpbtstackport_usb.c b/ports/unix/mpbtstackport_usb.c index 8b1d1fff218..a924fc3ca91 100644 --- a/ports/unix/mpbtstackport_usb.c +++ b/ports/unix/mpbtstackport_usb.c @@ -110,10 +110,7 @@ static void *btstack_thread(void *arg) { void mp_bluetooth_btstack_port_start(void) { // Create a thread to run the btstack loop. - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&bstack_thread_id, &attr, &btstack_thread, NULL); + pthread_create(&bstack_thread_id, NULL, &btstack_thread, NULL); } #endif // MICROPY_PY_BLUETOOTH && MICROPY_BLUETOOTH_BTSTACK && MICROPY_BLUETOOTH_BTSTACK_USB diff --git a/ports/unix/mpconfigport.h b/ports/unix/mpconfigport.h index afc1c3a38d1..815be76b4e9 100644 --- a/ports/unix/mpconfigport.h +++ b/ports/unix/mpconfigport.h @@ -32,6 +32,9 @@ // features to work on Unix-like systems, see mpconfigvariant.h (and // mpconfigvariant_common.h) for feature enabling. +// For time_t, needed by MICROPY_TIMESTAMP_IMPL_TIME_T. +#include + // For size_t and ssize_t #include @@ -41,6 +44,7 @@ // CIRCUITPY-CHANGE #define CIRCUITPY_MICROPYTHON_ADVANCED (1) #define MICROPY_PY_ASYNC_AWAIT (1) +#define MICROPY_PY_DOUBLE_TYPECODE (1) #define MICROPY_PY_UCTYPES (0) #ifndef MICROPY_CONFIG_ROM_LEVEL @@ -78,21 +82,6 @@ #define MICROPY_EMIT_ARM (1) #endif -// Type definitions for the specific machine based on the word size. -#ifndef MICROPY_OBJ_REPR -#ifdef __LP64__ -typedef long mp_int_t; // must be pointer size -typedef unsigned long mp_uint_t; // must be pointer size -#else -// These are definitions for machines where sizeof(int) == sizeof(void*), -// regardless of actual size. -typedef int mp_int_t; // must be pointer size -typedef unsigned int mp_uint_t; // must be pointer size -#endif -#else -// Assume that if we already defined the obj repr then we also defined types. -#endif - // Cannot include , as it may lead to symbol name clashes #if _FILE_OFFSET_BITS == 64 && !defined(__LP64__) typedef long long mp_off_t; @@ -112,8 +101,10 @@ typedef long mp_off_t; // Always enable GC. #define MICROPY_ENABLE_GC (1) +// CIRCUITPY-CHANGE +#define MICROPY_ENABLE_SELECTIVE_COLLECT (1) -#if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__)) +#if !(defined(MICROPY_GCREGS_SETJMP) || defined(__x86_64__) || defined(__i386__) || defined(__thumb2__) || defined(__thumb__) || defined(__arm__) || (defined(__riscv) && (__riscv_xlen == 64))) // Fall back to setjmp() implementation for discovery of GC pointers in registers. #define MICROPY_GCREGS_SETJMP (1) #endif @@ -125,13 +116,17 @@ typedef long mp_off_t; #define MICROPY_HELPER_LEXER_UNIX (1) #define MICROPY_VFS_POSIX (1) #define MICROPY_READER_POSIX (1) +// CIRCUITPY-CHANGE: define no matter what #ifndef MICROPY_TRACKED_ALLOC -#define MICROPY_TRACKED_ALLOC (MICROPY_BLUETOOTH_BTSTACK) +#define MICROPY_TRACKED_ALLOC (MICROPY_PY_FFI || MICROPY_BLUETOOTH_BTSTACK) #endif // VFS stat functions should return time values relative to 1970/1/1 #define MICROPY_EPOCH_IS_1970 (1) +// port modtime functions use time_t +#define MICROPY_TIMESTAMP_IMPL (MICROPY_TIMESTAMP_IMPL_TIME_T) + // Assume that select() call, interrupted with a signal, and erroring // with EINTR, updates remaining timeout value. #define MICROPY_SELECT_REMAINING_TIME (1) @@ -142,6 +137,9 @@ typedef long mp_off_t; #define MICROPY_STACKLESS_STRICT (0) #endif +// Recursive mutex is needed when threading is enabled, regardless of GIL setting. +#define MICROPY_PY_THREAD_RECURSIVE_MUTEX (MICROPY_PY_THREAD) + // Implementation of the machine module. #define MICROPY_PY_MACHINE_INCLUDEFILE "ports/unix/modmachine.c" @@ -169,6 +167,12 @@ typedef long mp_off_t; // Enable sys.executable. #define MICROPY_PY_SYS_EXECUTABLE (1) +// Enable support for compile-only mode. +#define MICROPY_PYEXEC_COMPILE_ONLY (1) + +// Enable handling of sys.exit() exit codes. +#define MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING (1) + #define MICROPY_PY_SOCKET_LISTEN_BACKLOG_DEFAULT (SOMAXCONN < 128 ? SOMAXCONN : 128) // Bare-metal ports don't have stderr. Printing debug to stderr may give tests @@ -180,14 +184,8 @@ extern const struct _mp_print_t mp_stderr_print; // For the native emitter configure how to mark a region as executable. void mp_unix_alloc_exec(size_t min_size, void **ptr, size_t *size); void mp_unix_free_exec(void *ptr, size_t size); -void mp_unix_mark_exec(void); #define MP_PLAT_ALLOC_EXEC(min_size, ptr, size) mp_unix_alloc_exec(min_size, ptr, size) #define MP_PLAT_FREE_EXEC(ptr, size) mp_unix_free_exec(ptr, size) -#ifndef MICROPY_FORCE_PLAT_ALLOC_EXEC -// Use MP_PLAT_ALLOC_EXEC for any executable memory allocation, including for FFI -// (overriding libffi own implementation) -#define MICROPY_FORCE_PLAT_ALLOC_EXEC (1) -#endif // If enabled, configure how to seed random on init. #ifdef MICROPY_PY_RANDOM_SEED_INIT_FUNC diff --git a/ports/unix/mpconfigport.mk b/ports/unix/mpconfigport.mk index d6b57ca8860..3c844ccef3b 100644 --- a/ports/unix/mpconfigport.mk +++ b/ports/unix/mpconfigport.mk @@ -14,6 +14,7 @@ MICROPY_PY_BTREE = 0 # _thread module using pthreads MICROPY_PY_THREAD = 1 +MICROPY_PY_THREAD_GIL = 0 # Subset of CPython termios module MICROPY_PY_TERMIOS = 1 @@ -41,7 +42,7 @@ MICROPY_PY_JNI = 0 # Avoid using system libraries, use copies bundled with MicroPython # as submodules (currently affects only libffi). -MICROPY_STANDALONE = 0 +MICROPY_STANDALONE ?= 0 # CIRCUITPY-CHANGE: not used MICROPY_ROM_TEXT_COMPRESSION = 0 @@ -54,5 +55,4 @@ MICROPY_VFS_LFS2 = 0 # CIRCUITPY-CHANGE CIRCUITPY_ULAB = 1 CIRCUITPY_MESSAGE_COMPRESSION_LEVEL = 1 -MICROPY_EMIT_NATIVE = 0 CFLAGS += -DCIRCUITPY=1 diff --git a/ports/unix/mphalport.h b/ports/unix/mphalport.h index 7f71217632a..d9cd05b3de8 100644 --- a/ports/unix/mphalport.h +++ b/ports/unix/mphalport.h @@ -25,7 +25,6 @@ */ #include #include -// CIRCUITPY-CHANGE: extra include #include #ifndef CHAR_CTRL_C @@ -38,6 +37,20 @@ #define MICROPY_END_ATOMIC_SECTION(x) (void)x; mp_thread_unix_end_atomic_section() #endif +// In lieu of a WFI(), slow down polling from being a tight loop. +// +// Note that we don't delay for the full TIMEOUT_MS, as execution +// can't be woken from the delay. +#define MICROPY_INTERNAL_WFE(TIMEOUT_MS) \ + do { \ + MP_THREAD_GIL_EXIT(); \ + mp_hal_delay_us(500); \ + MP_THREAD_GIL_ENTER(); \ + } while (0) + +// The port provides `mp_hal_stdio_mode_raw()` and `mp_hal_stdio_mode_orig()`. +#define MICROPY_HAL_HAS_STDIO_MODE_SWITCH (1) + // CIRCUITPY-CHANGE: mp_hal_set_interrupt_char(int) instead of char void mp_hal_set_interrupt_char(int c); bool mp_hal_is_interrupted(void); @@ -110,3 +123,6 @@ enum { void mp_hal_get_mac(int idx, uint8_t buf[6]); #endif + +// Global variable to control compile-only mode. +extern bool mp_compile_only; diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c index 16ac4da8bf5..a41b3ec9f47 100644 --- a/ports/unix/mpthreadport.c +++ b/ports/unix/mpthreadport.c @@ -31,6 +31,7 @@ #include "py/runtime.h" #include "py/mpthread.h" #include "py/gc.h" +#include "stack_size.h" #if MICROPY_PY_THREAD @@ -45,8 +46,14 @@ // potential conflict with other uses of the more commonly used SIGUSR1. #ifdef SIGRTMIN #define MP_THREAD_GC_SIGNAL (SIGRTMIN + 5) +#ifdef __ANDROID__ +#define MP_THREAD_TERMINATE_SIGNAL (SIGRTMIN + 6) +#endif #else #define MP_THREAD_GC_SIGNAL (SIGUSR1) +#ifdef __ANDROID__ +#define MP_THREAD_TERMINATE_SIGNAL (SIGUSR2) +#endif #endif // This value seems to be about right for both 32-bit and 64-bit builds. @@ -65,7 +72,7 @@ static pthread_key_t tls_key; // The mutex is used for any code in this port that needs to be thread safe. // Specifically for thread management, access to the linked list is one example. // But also, e.g. scheduler state. -static pthread_mutex_t thread_mutex; +static mp_thread_recursive_mutex_t thread_mutex; static mp_thread_t *thread; // this is used to synchronise the signal handler of the thread @@ -78,11 +85,11 @@ static sem_t thread_signal_done; #endif void mp_thread_unix_begin_atomic_section(void) { - pthread_mutex_lock(&thread_mutex); + mp_thread_recursive_mutex_lock(&thread_mutex, true); } void mp_thread_unix_end_atomic_section(void) { - pthread_mutex_unlock(&thread_mutex); + mp_thread_recursive_mutex_unlock(&thread_mutex); } // this signal handler is used to scan the regs and stack of a thread @@ -107,16 +114,25 @@ static void mp_thread_gc(int signo, siginfo_t *info, void *context) { } } +// On Android, pthread_cancel and pthread_setcanceltype are not implemented. +// To achieve that result a new signal handler responding on either +// (SIGRTMIN + 6) or SIGUSR2 is installed on every child thread. The sole +// purpose of this new signal handler is to terminate the thread in a safe +// asynchronous manner. + +#ifdef __ANDROID__ +static void mp_thread_terminate(int signo, siginfo_t *info, void *context) { + pthread_exit(NULL); +} +#endif + void mp_thread_init(void) { pthread_key_create(&tls_key, NULL); pthread_setspecific(tls_key, &mp_state_ctx.thread); // Needs to be a recursive mutex to emulate the behavior of // BEGIN_ATOMIC_SECTION on bare metal. - pthread_mutexattr_t thread_mutex_attr; - pthread_mutexattr_init(&thread_mutex_attr); - pthread_mutexattr_settype(&thread_mutex_attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&thread_mutex, &thread_mutex_attr); + mp_thread_recursive_mutex_init(&thread_mutex); // create first entry in linked list of all threads thread = malloc(sizeof(mp_thread_t)); @@ -138,6 +154,14 @@ void mp_thread_init(void) { sa.sa_sigaction = mp_thread_gc; sigemptyset(&sa.sa_mask); sigaction(MP_THREAD_GC_SIGNAL, &sa, NULL); + + // Install a signal handler for asynchronous termination if needed. + #if defined(__ANDROID__) + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = mp_thread_terminate; + sigemptyset(&sa.sa_mask); + sigaction(MP_THREAD_TERMINATE_SIGNAL, &sa, NULL); + #endif } void mp_thread_deinit(void) { @@ -145,7 +169,11 @@ void mp_thread_deinit(void) { while (thread->next != NULL) { mp_thread_t *th = thread; thread = thread->next; + #if defined(__ANDROID__) + pthread_kill(th->id, MP_THREAD_TERMINATE_SIGNAL); + #else pthread_cancel(th->id); + #endif free(th); } mp_thread_unix_end_atomic_section(); @@ -203,7 +231,9 @@ void mp_thread_start(void) { } #endif + #if !defined(__ANDROID__) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + #endif mp_thread_unix_begin_atomic_section(); for (mp_thread_t *th = thread; th != NULL; th = th->next) { if (th->id == pthread_self()) { @@ -215,14 +245,14 @@ void mp_thread_start(void) { } mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) { - // default stack size is 8k machine-words + // default stack size if (*stack_size == 0) { - *stack_size = 8192 * sizeof(void *); + *stack_size = 32768 * UNIX_STACK_MULTIPLIER; } // minimum stack size is set by pthreads - if (*stack_size < PTHREAD_STACK_MIN) { - *stack_size = PTHREAD_STACK_MIN; + if (*stack_size < (size_t)PTHREAD_STACK_MIN) { + *stack_size = (size_t)PTHREAD_STACK_MIN; } // ensure there is enough stack to include a stack-overflow margin @@ -321,6 +351,26 @@ void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex) { // TODO check return value } +#if MICROPY_PY_THREAD_RECURSIVE_MUTEX + +void mp_thread_recursive_mutex_init(mp_thread_recursive_mutex_t *mutex) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(mutex, &attr); + pthread_mutexattr_destroy(&attr); +} + +int mp_thread_recursive_mutex_lock(mp_thread_recursive_mutex_t *mutex, int wait) { + return mp_thread_mutex_lock(mutex, wait); +} + +void mp_thread_recursive_mutex_unlock(mp_thread_recursive_mutex_t *mutex) { + mp_thread_mutex_unlock(mutex); +} + +#endif // MICROPY_PY_THREAD_RECURSIVE_MUTEX + #endif // MICROPY_PY_THREAD // this is used even when MICROPY_PY_THREAD is disabled diff --git a/ports/unix/mpthreadport.h b/ports/unix/mpthreadport.h index b365f200edf..a38223e720b 100644 --- a/ports/unix/mpthreadport.h +++ b/ports/unix/mpthreadport.h @@ -28,6 +28,7 @@ #include typedef pthread_mutex_t mp_thread_mutex_t; +typedef pthread_mutex_t mp_thread_recursive_mutex_t; void mp_thread_init(void); void mp_thread_deinit(void); diff --git a/ports/unix/stack_size.h b/ports/unix/stack_size.h new file mode 100644 index 00000000000..f6159bb69d5 --- /dev/null +++ b/ports/unix/stack_size.h @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2025 Angus Gratton + * + * 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. + */ +#ifndef MICROPY_INCLUDED_UNIX_STACK_SIZE_H +#define MICROPY_INCLUDED_UNIX_STACK_SIZE_H + +#include "py/misc.h" + +// Define scaling factors for the stack size (also applies to main thread) +#ifndef UNIX_STACK_MULTIPLIER + +#if defined(__arm__) && !defined(__thumb2__) +// ARM (non-Thumb) architectures require more stack. +#define UNIX_STACK_MUL_ARM 2 +#else +#define UNIX_STACK_MUL_ARM 1 +#endif + +#if MP_SANITIZER_BUILD +// Sanitizer features consume significant stack in some cases +// This multiplier can probably be removed when using GCC 12 or newer. +#define UNIX_STACK_MUL_SANITIZERS 4 +#else +#define UNIX_STACK_MUL_SANITIZERS 1 +#endif + +// Double the stack size for 64-bit builds, plus additional scaling +#define UNIX_STACK_MULTIPLIER ((sizeof(void *) / 4) * UNIX_STACK_MUL_ARM * UNIX_STACK_MUL_SANITIZERS) + +#endif // UNIX_STACK_MULTIPLIER + +#endif // MICROPY_INCLUDED_UNIX_STACK_SIZE_H diff --git a/ports/unix/variants/coverage/mpconfigvariant.h b/ports/unix/variants/coverage/mpconfigvariant.h index 11f4b2eb4b1..03f77ec14c6 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.h +++ b/ports/unix/variants/coverage/mpconfigvariant.h @@ -39,11 +39,29 @@ // Enable additional features. #define MICROPY_DEBUG_PARSE_RULE_NAME (1) +// CIRCUITPY-CHANGE: off +#define MICROPY_PY_SYS_SETTRACE (0) #define MICROPY_TRACKED_ALLOC (1) #define MICROPY_WARNINGS_CATEGORY (1) +#undef MICROPY_VFS_ROM_IOCTL +#define MICROPY_VFS_ROM_IOCTL (1) +#define MICROPY_PY_CRYPTOLIB_CTR (1) +// CIRCUITPY-CHANGE: off +#define MICROPY_SCHEDULER_STATIC_NODES (0) + +// Enable os.uname for attrtuple coverage test +#define MICROPY_PY_OS_UNAME (1) +#define MICROPY_HW_BOARD_NAME "a machine" +#define MICROPY_HW_MCU_NAME MICROPY_PY_SYS_PLATFORM +// Keep the standard banner message +#define MICROPY_BANNER_MACHINE MICROPY_PY_SYS_PLATFORM " [" MICROPY_PLATFORM_COMPILER "] version" // CIRCUITPY-CHANGE: Disable things never used in circuitpython -#define MICROPY_PY_CRYPTOLIB (0) -#define MICROPY_PY_CRYPTOLIB_CTR (0) +#define MICROPY_PY_CRYPTOLIB (0) +#undef MICROPY_PY_CRYPTOLIB_CTR +#define MICROPY_PY_CRYPTOLIB_CTR (0) +#define MICROPY_PY_MICROPYTHON_RINGIO (0) // CircuitPython uses shared-bindings struct #define MICROPY_PY_STRUCT (0) +#undef MICROPY_VFS_ROM_IOCTL +#define MICROPY_VFS_ROM_IOCTL (0) diff --git a/ports/unix/variants/coverage/mpconfigvariant.mk b/ports/unix/variants/coverage/mpconfigvariant.mk index 9721c2803e2..0dd93b25cf4 100644 --- a/ports/unix/variants/coverage/mpconfigvariant.mk +++ b/ports/unix/variants/coverage/mpconfigvariant.mk @@ -12,7 +12,8 @@ CFLAGS += \ LDFLAGS += -fprofile-arcs -ftest-coverage FROZEN_MANIFEST ?= $(VARIANT_DIR)/manifest.py -USER_C_MODULES = $(TOP)/examples/usercmodule +# CIRCUITPY-CHANGE: don't include user C modules +# USER_C_MODULES = $(TOP)/examples/usercmodule # CIRCUITPY-CHANGE: use CircuitPython bindings and implementations SRC_QRIO := $(patsubst ../../%,%,$(wildcard ../../shared-bindings/qrio/*.c ../../shared-module/qrio/*.c ../../lib/quirc/lib/*.c)) @@ -33,6 +34,19 @@ SRC_BITMAP := \ shared-bindings/audiocore/__init__.c \ shared-bindings/audiocore/RawSample.c \ shared-bindings/audiocore/WaveFile.c \ + shared-bindings/audiodelays/Echo.c \ + shared-bindings/audiodelays/Chorus.c \ + shared-bindings/audiodelays/PitchShift.c \ + shared-bindings/audiodelays/GranularPitchShift.c \ + shared-bindings/audiodelays/MultiTapDelay.c \ + shared-bindings/audiodelays/Flanger.c \ + shared-bindings/audiodelays/__init__.c \ + shared-bindings/audiofilters/Distortion.c \ + shared-bindings/audiofilters/Filter.c \ + shared-bindings/audiofilters/Phaser.c \ + shared-bindings/audiofilters/__init__.c \ + shared-bindings/audiofreeverb/Freeverb.c \ + shared-bindings/audiofreeverb/__init__.c \ shared-bindings/audiomixer/__init__.c \ shared-bindings/audiomixer/Mixer.c \ shared-bindings/audiomixer/MixerVoice.c \ @@ -59,12 +73,30 @@ SRC_BITMAP := \ shared-bindings/synthio/Synthesizer.c \ shared-bindings/traceback/__init__.c \ shared-bindings/util.c \ + shared-bindings/vectorio/Circle.c \ + shared-bindings/vectorio/__init__.c \ + shared-bindings/vectorio/Polygon.c \ + shared-bindings/vectorio/Rectangle.c \ + shared-bindings/vectorio/VectorShape.c \ shared-bindings/zlib/__init__.c \ shared-module/aesio/aes.c \ shared-module/aesio/__init__.c \ shared-module/audiocore/__init__.c \ shared-module/audiocore/RawSample.c \ shared-module/audiocore/WaveFile.c \ + shared-module/audiodelays/Echo.c \ + shared-module/audiodelays/Chorus.c \ + shared-module/audiodelays/PitchShift.c \ + shared-module/audiodelays/GranularPitchShift.c \ + shared-module/audiodelays/MultiTapDelay.c \ + shared-module/audiodelays/Flanger.c \ + shared-module/audiodelays/__init__.c \ + shared-module/audiofilters/Distortion.c \ + shared-module/audiofilters/Filter.c \ + shared-module/audiofilters/Phaser.c \ + shared-module/audiofilters/__init__.c \ + shared-module/audiofreeverb/Freeverb.c \ + shared-module/audiofreeverb/__init__.c \ shared-module/audiomixer/__init__.c \ shared-module/audiomp3/MP3Decoder.c \ shared-module/audiomixer/Mixer.c \ @@ -78,7 +110,6 @@ SRC_BITMAP := \ shared-module/floppyio/__init__.c \ shared-module/jpegio/__init__.c \ shared-module/jpegio/JpegDecoder.c \ - shared-module/os/getenv.c \ shared-module/rainbowio/__init__.c \ shared-module/struct/__init__.c \ shared-module/synthio/__init__.c \ @@ -88,6 +119,12 @@ SRC_BITMAP := \ shared-module/synthio/Note.c \ shared-module/synthio/Biquad.c \ shared-module/synthio/Synthesizer.c \ + shared-bindings/vectorio/Circle.c \ + shared-module/vectorio/Circle.c \ + shared-module/vectorio/__init__.c \ + shared-module/vectorio/Polygon.c \ + shared-module/vectorio/Rectangle.c \ + shared-module/vectorio/VectorShape.c \ shared-module/traceback/__init__.c \ shared-module/zlib/__init__.c \ @@ -116,9 +153,11 @@ $(BUILD)/lib/mp3/src/buffers.o: CFLAGS += -include "shared-module/audiomp3/__ini CFLAGS += \ -DCIRCUITPY_AESIO=1 \ -DCIRCUITPY_AUDIOCORE=1 \ + -DCIRCUITPY_AUDIOEFFECTS=1 \ + -DCIRCUITPY_AUDIODELAYS=1 \ + -DCIRCUITPY_AUDIOFILTERS=1 \ -DCIRCUITPY_AUDIOMIXER=1 \ -DCIRCUITPY_AUDIOMP3=1 \ - -DCIRCUITPY_AUDIOMP3_USE_PORT_ALLOCATOR=0 \ -DCIRCUITPY_AUDIOCORE_DEBUG=1 \ -DCIRCUITPY_BITMAPTOOLS=1 \ -DCIRCUITPY_CODEOP=1 \ @@ -128,12 +167,13 @@ CFLAGS += \ -DCIRCUITPY_GIFIO=1 \ -DCIRCUITPY_JPEGIO=1 \ -DCIRCUITPY_LOCALE=1 \ - -DCIRCUITPY_OS_GETENV=1 \ -DCIRCUITPY_RAINBOWIO=1 \ + -DCIRCUITPY_SETTINGS_TOML=1 \ -DCIRCUITPY_STRUCT=1 \ -DCIRCUITPY_SYNTHIO=1 \ -DCIRCUITPY_SYNTHIO_MAX_CHANNELS=14 \ -DCIRCUITPY_TRACEBACK=1 \ + -DCIRCUITPY_VECTORIO=1 \ -DCIRCUITPY_ZLIB=1 # CIRCUITPY-CHANGE: test native base classes. diff --git a/ports/unix/variants/longlong/mpconfigvariant.h b/ports/unix/variants/longlong/mpconfigvariant.h new file mode 100644 index 00000000000..d50d360b1fe --- /dev/null +++ b/ports/unix/variants/longlong/mpconfigvariant.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * 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 config exists to test that the MICROPY_LONGINT_IMPL_LONGLONG variant +// (i.e. minimal form of "big integer" that's backed by 64-bit int only) builds +// and passes tests. + +#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG) + +// We build it on top of REPR C, which uses memory-efficient floating point +// objects encoded directly mp_obj_t (30 bits only). +// Therefore this variant should be built using MICROPY_FORCE_32BIT=1 + +#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C) +#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) + +// Set base feature level. +#define MICROPY_CONFIG_ROM_LEVEL (MICROPY_CONFIG_ROM_LEVEL_EXTRA_FEATURES) + +// Enable extra Unix features. +#include "../mpconfigvariant_common.h" diff --git a/ports/unix/variants/longlong/mpconfigvariant.mk b/ports/unix/variants/longlong/mpconfigvariant.mk new file mode 100644 index 00000000000..2d2c3706469 --- /dev/null +++ b/ports/unix/variants/longlong/mpconfigvariant.mk @@ -0,0 +1,8 @@ +# build interpreter with "bigints" implemented as "longlong" + +# otherwise, small int is essentially 64-bit +MICROPY_FORCE_32BIT := 1 + +MICROPY_PY_FFI := 0 + +MPY_TOOL_FLAGS = -mlongint-impl longlong diff --git a/ports/unix/variants/minimal/mpconfigvariant.h b/ports/unix/variants/minimal/mpconfigvariant.h index 97ed786b8f4..0e280a8f730 100644 --- a/ports/unix/variants/minimal/mpconfigvariant.h +++ b/ports/unix/variants/minimal/mpconfigvariant.h @@ -49,6 +49,7 @@ #define MICROPY_COMP_DOUBLE_TUPLE_ASSIGN (1) #define MICROPY_ENABLE_COMPILER (1) #define MICROPY_ENABLE_EXTERNAL_IMPORT (1) +#define MICROPY_STACK_CHECK (1) #define MICROPY_FULL_CHECKS (1) #define MICROPY_HELPER_REPL (1) #define MICROPY_KBD_EXCEPTION (1) @@ -61,6 +62,5 @@ #define MICROPY_PY_BUILTINS_RANGE_ATTRS (1) #define MICROPY_PY_GENERATOR_PEND_THROW (1) -// Enable just the sys and os built-in modules. -#define MICROPY_PY_SYS (1) +// Add just the os built-in module. #define MICROPY_PY_OS (1) diff --git a/ports/unix/variants/mpconfigvariant_common.h b/ports/unix/variants/mpconfigvariant_common.h index 2e34055bf77..1ac59c95572 100644 --- a/ports/unix/variants/mpconfigvariant_common.h +++ b/ports/unix/variants/mpconfigvariant_common.h @@ -29,7 +29,7 @@ // Send raise KeyboardInterrupt directly from the signal handler rather than // scheduling it into the VM. -#define MICROPY_ASYNC_KBD_INTR (1) +#define MICROPY_ASYNC_KBD_INTR (!MICROPY_PY_THREAD_GIL) // Enable helpers for printing debugging information. #ifndef MICROPY_DEBUG_PRINTERS @@ -95,7 +95,6 @@ #define MICROPY_PY_OS_INCLUDEFILE "ports/unix/modos.c" #define MICROPY_PY_OS_ERRNO (1) #define MICROPY_PY_OS_GETENV_PUTENV_UNSETENV (1) -#define MICROPY_PY_OS_SEP (1) #define MICROPY_PY_OS_SYSTEM (1) #define MICROPY_PY_OS_URANDOM (1) @@ -105,12 +104,6 @@ #define MICROPY_PY_TIME_CUSTOM_SLEEP (1) #define MICROPY_PY_TIME_INCLUDEFILE "ports/unix/modtime.c" -#if MICROPY_PY_SSL -#define MICROPY_PY_HASHLIB_MD5 (1) -#define MICROPY_PY_HASHLIB_SHA1 (1) -#define MICROPY_PY_CRYPTOLIB (1) -#endif - // The "select" module is enabled by default, but disable select.select(). #define MICROPY_PY_SELECT_POSIX_OPTIMISATIONS (1) #define MICROPY_PY_SELECT_SELECT (0) @@ -122,3 +115,6 @@ #define MICROPY_PY_MACHINE (1) #define MICROPY_PY_MACHINE_PULSE (1) #define MICROPY_PY_MACHINE_PIN_BASE (1) + +#define MICROPY_VFS_ROM (1) +#define MICROPY_VFS_ROM_IOCTL (0) diff --git a/ports/unix/variants/nanbox/mpconfigvariant.h b/ports/unix/variants/nanbox/mpconfigvariant.h index 7b13b7dc6ce..c9e9c1f63d9 100644 --- a/ports/unix/variants/nanbox/mpconfigvariant.h +++ b/ports/unix/variants/nanbox/mpconfigvariant.h @@ -41,10 +41,3 @@ #define MICROPY_EMIT_X64 (0) #define MICROPY_EMIT_THUMB (0) #define MICROPY_EMIT_ARM (0) - -#include - -typedef int64_t mp_int_t; -typedef uint64_t mp_uint_t; -#define UINT_FMT "%llu" -#define INT_FMT "%lld" diff --git a/ports/zephyr-cp/.gitignore b/ports/zephyr-cp/.gitignore new file mode 100644 index 00000000000..65d8deaa722 --- /dev/null +++ b/ports/zephyr-cp/.gitignore @@ -0,0 +1,7 @@ +# West manages these folders. +bootloader +build +modules +tools +zephyr +.west diff --git a/ports/zephyr-cp/AGENTS.md b/ports/zephyr-cp/AGENTS.md new file mode 100644 index 00000000000..58a3912e2ba --- /dev/null +++ b/ports/zephyr-cp/AGENTS.md @@ -0,0 +1,7 @@ +- Build a board by doing `make BOARD=_`. +- The corresponding configuration files are in `boards//` +- The files (not folders) in `boards/` directory are used by Zephyr. +- To flash it on a board do `make BOARD=_ flash`. +- Zephyr board docs are at `zephyr/boards//`. +- Run zephyr-cp tests with `make test`. +- Do not add new translatable error strings (`MP_ERROR_TEXT`). Instead, use `raise_zephyr_error()` or `CHECK_ZEPHYR_RESULT()` from `bindings/zephyr_kernel/__init__.h` to convert Zephyr errno values into Python exceptions. diff --git a/ports/zephyr-cp/CLAUDE.md b/ports/zephyr-cp/CLAUDE.md new file mode 100644 index 00000000000..43c994c2d36 --- /dev/null +++ b/ports/zephyr-cp/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/ports/zephyr-cp/CMakeLists.txt b/ports/zephyr-cp/CMakeLists.txt new file mode 100644 index 00000000000..9d115f1e176 --- /dev/null +++ b/ports/zephyr-cp/CMakeLists.txt @@ -0,0 +1,73 @@ +cmake_minimum_required(VERSION 3.20.0) + +find_package(Zephyr REQUIRED HINTS lib/zephyr) +project(circuitpython) + +target_sources(app PRIVATE zephyr_main.c) + +# Add I2C emulator control for native_sim testing +if(CONFIG_BOARD_NATIVE_SIM) + target_sources(app PRIVATE native_sim_i2c_emul_control.c) +endif() + +if(CONFIG_TRACING_PERFETTO) + zephyr_include_directories(${ZEPHYR_BINARY_DIR}/subsys/tracing/perfetto/proto) +endif() + +# From: https://github.com/zephyrproject-rtos/zephyr/blob/main/samples/application_development/external_lib/CMakeLists.txt +# The external static library that we are linking with does not know +# how to build for this platform so we export all the flags used in +# this zephyr build to the external build system. +# +# Other external build systems may be self-contained enough that they +# do not need any build information from zephyr. Or they may be +# incompatible with certain zephyr options and need them to be +# filtered out. +zephyr_get_include_directories_for_lang_as_string( C includes) +zephyr_get_system_include_directories_for_lang_as_string(C system_includes) +zephyr_get_compile_definitions_for_lang_as_string( C definitions) +zephyr_get_compile_options_for_lang_as_string( C options) + +if(DEFINED CMAKE_C_COMPILER_TARGET) + set(target_flag "--target=${CMAKE_C_COMPILER_TARGET}") +endif() + +set(external_project_cflags + "${target_flag} ${includes} ${definitions} ${options} ${system_includes}" + ) + +zephyr_get(TRANSLATION SYSBUILD GLOBAL) +zephyr_get(CONFIG_LTO SYSBUILD GLOBAL) +zephyr_get(BOARD_ALIAS SYSBUILD GLOBAL) + +ExternalProject_Add(circuitpython + DOWNLOAD_COMMAND "" + CONFIGURE_COMMAND "" + BUILD_COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/cptools/build_circuitpython.py + CC=${CMAKE_C_COMPILER} + AR=${CMAKE_AR} + CFLAGS=${external_project_cflags} + BOARD=${BOARD} + BOARD_ALIAS=${BOARD_ALIAS} + BOARD_REVISION=${BOARD_REVISION} + BOARD_QUALIFIERS=${BOARD_QUALIFIERS} + SOC_DIRECTORIES=${SOC_DIRECTORIES} + OUTPUT_FILE=${CMAKE_CURRENT_BINARY_DIR}/libcircuitpython.a + PORT_SRC_DIR=${CMAKE_CURRENT_SOURCE_DIR} + TRANSLATION=${TRANSLATION} + LTO=${CONFIG_LTO} + BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/libcircuitpython.a + BUILD_JOB_SERVER_AWARE TRUE + BUILD_ALWAYS TRUE + DEPENDS zephyr + INSTALL_COMMAND "" + ) + +add_library(circuitpython_wrapper STATIC IMPORTED GLOBAL) +add_dependencies( + circuitpython_wrapper + circuitpython + ) +set_target_properties(circuitpython_wrapper PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/libcircuitpython.a) +target_link_libraries(circuitpython_wrapper INTERFACE kernel) +target_link_libraries(app PRIVATE circuitpython_wrapper) diff --git a/ports/zephyr-cp/Kconfig b/ports/zephyr-cp/Kconfig new file mode 100644 index 00000000000..015864100ec --- /dev/null +++ b/ports/zephyr-cp/Kconfig @@ -0,0 +1,104 @@ +# CircuitPython Zephyr port — application Kconfig +# +# Sources Zephyr's main Kconfig, then adds CircuitPython-specific defaults. +# Boards can override any of these in their boards/.conf file. + +osource "$(ZEPHYR_BASE)/Kconfig.zephyr" + +# ===== Peripheral defaults — enabled by default, boards can disable ===== + +config I2C + default y + +config SPI + default y + +config SPI_ASYNC + default y + +config I2S + default y + +config UART_LINE_CTRL + default y + +config ENTROPY_GENERATOR + default y + +# ===== Bluetooth defaults ===== + +# Use a variable for the chosen name so the comma isn't parsed as an argument separator +DT_BT_HCI_CHOSEN := zephyr,bt-hci + +config BT + default $(dt_chosen_enabled,$(DT_BT_HCI_CHOSEN)) + +config BT_PERIPHERAL + default y + +config BT_CENTRAL + default y + +config BT_BROADCASTER + default y + +config BT_OBSERVER + default y + +config BT_EXT_ADV + default y + +config BT_DEVICE_APPEARANCE_DYNAMIC + default y + +config BT_DEVICE_NAME_DYNAMIC + default y + +config BT_DEVICE_NAME_MAX + default 28 + +config BT_L2CAP_TX_MTU + default 253 + +# BT Buffers +config BT_BUF_CMD_TX_SIZE + default 255 + +config BT_BUF_EVT_RX_COUNT + default 16 + +config BT_BUF_EVT_RX_SIZE + default 255 + +config BT_BUF_ACL_TX_COUNT + default 3 + +config BT_BUF_ACL_TX_SIZE + default 251 + +config BT_BUF_ACL_RX_COUNT_EXTRA + default 1 + +config BT_BUF_ACL_RX_SIZE + default 255 + +config BT_GATT_DYNAMIC_DB + default y + +config BT_GATT_CLIENT + default y + +config BT_SMP + default y + +config BT_BONDABLE + default y + +config SETTINGS + default y + +config BT_SETTINGS + default y + +config BT_KEYS_OVERWRITE_OLDEST + default y diff --git a/ports/zephyr-cp/Kconfig.sysbuild b/ports/zephyr-cp/Kconfig.sysbuild new file mode 100644 index 00000000000..11b49446f42 --- /dev/null +++ b/ports/zephyr-cp/Kconfig.sysbuild @@ -0,0 +1,16 @@ +# Copyright 2023-2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +source "share/sysbuild/Kconfig" + +config NET_CORE_BOARD + string + default "nrf5340dk/nrf5340/cpunet" if $(BOARD) = "nrf5340dk" + default "nrf7002dk/nrf5340/cpunet" if $(BOARD) = "nrf7002dk" + default "nrf5340_audio_dk/nrf5340/cpunet" if $(BOARD) = "nrf5340_audio_dk" + default "nrf5340bsim/nrf5340/cpunet" if $(BOARD) = "nrf5340bsim" + +config NET_CORE_IMAGE_HCI_IPC + bool "HCI IPC image on network core" + default y + depends on NET_CORE_BOARD != "" diff --git a/ports/zephyr-cp/Makefile b/ports/zephyr-cp/Makefile new file mode 100644 index 00000000000..ab730a8b339 --- /dev/null +++ b/ports/zephyr-cp/Makefile @@ -0,0 +1,102 @@ +ALL_BOARDS_IN_PORT := $($(wildcard boards/*/*):boards/=:/=) +# An incorrect BOARD might have been specified, so check against the list. +# There is deliberately no space after the := +VALID_BOARD :=$(filter $(BOARD),$(ALL_BOARDS_IN_PORT)) + +# If the build directory is not given, make it reflect the board name. +BUILD ?= build-$(BOARD) + +TRANSLATION ?= en_US + +# Compute shield args once. Command-line SHIELD/SHIELDS values override board defaults from circuitpython.toml. +ifneq ($(strip $(BOARD)),) +WEST_SHIELD_ARGS := $(shell SHIELD_ORIGIN="$(origin SHIELD)" SHIELDS_ORIGIN="$(origin SHIELDS)" SHIELD="$(SHIELD)" SHIELDS="$(SHIELDS)" python cptools/get_west_shield_args.py $(BOARD)) +endif + +WEST_CMAKE_ARGS := -DZEPHYR_BOARD_ALIASES=$(CURDIR)/boards/board_aliases.cmake -Dzephyr-cp_TRANSLATION=$(TRANSLATION) + +# When DEBUG=1, apply additional Kconfig fragments for debug-friendly settings. +DEBUG_CONF_FILE ?= $(CURDIR)/debug.conf +ifeq ($(DEBUG),1) +WEST_CMAKE_ARGS += -Dzephyr-cp_EXTRA_CONF_FILE=$(DEBUG_CONF_FILE) +endif + +.PHONY: $(BUILD)/zephyr-cp/zephyr/zephyr.elf flash recover debug debug-jlink debugserver attach run run-sim clean menuconfig all clean-all sim clean-sim test fetch-port-submodules + +export BSIM_COMPONENTS_PATH := $(CURDIR)/tools/bsim/components +export BSIM_OUT_PATH := $(CURDIR)/tools/bsim + +$(BUILD)/zephyr-cp/zephyr/zephyr.elf: + python cptools/pre_zephyr_build_prep.py $(BOARD) + west build -b $(BOARD) -d $(BUILD) $(WEST_SHIELD_ARGS) --sysbuild -- $(WEST_CMAKE_ARGS) + +$(BUILD)/firmware.elf: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + cp $^ $@ + +$(BUILD)/firmware.hex: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + cp $(BUILD)/zephyr-cp/zephyr/zephyr.hex $@ + +$(BUILD)/firmware.exe: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + cp $(BUILD)/zephyr-cp/zephyr/zephyr.exe $@ + +$(BUILD)/firmware.uf2: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + cp $(BUILD)/zephyr-cp/zephyr/zephyr.uf2 $@ + +flash: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + west flash -d $(BUILD) + +recover: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + west flash --recover -d $(BUILD) + +debug: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + west debug -d $(BUILD) + +debug-jlink: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + west debug --runner jlink -d $(BUILD) + +debugserver: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + west debugserver -d $(BUILD) + +attach: $(BUILD)/zephyr-cp/zephyr/zephyr.elf + west attach -d $(BUILD) + +run: $(BUILD)/firmware.exe + $^ + +run-sim: + $(MAKE) BOARD=native_native_sim BUILD=build-native_native_sim build-native_native_sim/firmware.exe + truncate -s 2M build-native_native_sim/flash.bin + mformat -i build-native_native_sim/flash.bin :: + @if [ -d CIRCUITPY ] && [ -n "$$(find CIRCUITPY -mindepth 1 -print -quit)" ]; then \ + echo "Populating build-native_native_sim/flash.bin from ./CIRCUITPY"; \ + mcopy -s -i build-native_native_sim/flash.bin CIRCUITPY/* ::; \ + fi + build-native_native_sim/firmware.exe --flash=build-native_native_sim/flash.bin --flash_rm -wait_uart -rt --i2s_capture=build-native_native_sim/i2s_capture.wav + +menuconfig: + west build $(WEST_SHIELD_ARGS) --sysbuild -d $(BUILD) -t menuconfig -- $(WEST_CMAKE_ARGS) + +clean: + rm -rf $(BUILD) + +fetch-port-submodules: + python ../../tools/ci_fetch_deps.py zephyr-cp + +# Build all boards. The + prefix allows jobserver file descriptors to be passed through. +# This enables parallel builds across all boards when invoked with `make -jN all`. +all: + +python cptools/build_all_boards.py --continue-on-error + +clean-all: + rm -rf build build-* + +# Build all sim boards concurrently using the same jobserver as `make all`. +sim: + +python cptools/build_all_boards.py --vendor native --continue-on-error + +clean-sim: + rm -rf $(wildcard build-native_*) + +test: build-native_native_sim/zephyr-cp/zephyr/zephyr.exe + pytest cptools/tests + pytest tests/ -v diff --git a/ports/zephyr-cp/README.md b/ports/zephyr-cp/README.md new file mode 100644 index 00000000000..162ed90bcc8 --- /dev/null +++ b/ports/zephyr-cp/README.md @@ -0,0 +1,118 @@ +# Zephyr + +This is an initial port of CircuitPython onto Zephyr. We intend on migrating all +existing boards onto Zephyr. To start, we'll only support new boards. Existing +boards will be switched as the Zephyr port reaches parity with the existing +implementation. + +## Getting Started + +First, install Zephyr tools (see [Zephyr's Getting Started Guide](https://docs.zephyrproject.org/4.0.0/develop/getting_started/index.html)). (These are `fish` commands because that's what Scott uses.) + + +```sh +pip install west +west init -l zephyr-config +west update +west zephyr-export +pip install -r zephyr/scripts/requirements.txt +west sdk install +``` + +Now to build from `ports/zephyr-cp`: + +```sh +make BOARD=nordic_nrf7002dk +``` + +This uses Zephyr's cmake to generate Makefiles that then delegate to +`tools/cpbuild/build_circuitpython.py` to build the CircuitPython bits in parallel. + +## Native simulator build container + +Building the native sim requires `libsdl2-dev:i386` and other 32bit dependencies that +can cause conflicts on 64bit systems resulting in the removal of 64bit versions of critical +software such as the display manager and network manager. A Containerfile and a few scripts +are provided to set up a container to make the native sim build inside without affecting the +host system. + +The container automatically mounts this instance of the circuitpython repo inside at +`/home/dev/circuitpython`. Changes made in the repo inside the container and on the host PC +will sync automatically between host and container. + +To use the container file: + +1. Build the container with `podman build -t zephyr-cp-dev -f native_sim_build_Containerfile .` +2. Run/Start the container by running `./native_sim_build_run_container.sh` on the host PC. + The script will automatically run or start based on whether the container has been run before. +3. Init requirements inside the container with `./native_sim_build_init_container.sh` + +To delete the container and cleanup associated files: +```sh +podman ps -a --filter ancestor=zephyr-cp-dev -q | xargs -r podman rm -f +podman rmi zephyr-cp-dev +podman image prune -f +podman rm -f zcp +``` + +## Running the native simulator + +From `ports/zephyr-cp`, run: + +```sh +make run-sim +``` + +`run-sim` starts the native simulator in realtime. +It prints the PTY path to connect to the simulator REPL. +If a local `./CIRCUITPY/` folder exists, its files are used as the simulator's CIRCUITPY drive. + +Edit files in `./CIRCUITPY` (for example `code.py`) and rerun `make run-sim` to test changes. + +## Shields + +Board defaults can be set in `boards///circuitpython.toml`: + +```toml +SHIELDS = ["shield1", "shield2"] +``` + +For example, `boards/renesas/ek_ra8d1/circuitpython.toml` enables: + +```toml +SHIELDS = ["rtkmipilcdb00000be"] +``` + +You can override shield selection from the command line: + +```sh +# Single shield +make BOARD=renesas_ek_ra8d1 SHIELD=rtkmipilcdb00000be + +# Multiple shields (comma, semicolon, or space separated) +make BOARD=my_vendor_my_board SHIELDS="shield1,shield2" +``` + +Behavior and precedence: + +- If `SHIELD` or `SHIELDS` is explicitly provided, it overrides board defaults. +- If neither is provided, defaults from `circuitpython.toml` are used. +- Use `SHIELD=` (empty) to disable a board default shield for one build. + +## Testing other boards + +[Any Zephyr board](https://docs.zephyrproject.org/latest/boards/index.html#) can +be used with CircuitPython. To test a different board, use `west` directly to +build the board. The build will do its best to support as much as possible. By +default the Zephyr console will be used for output. USB support is limited by +initialization support in `supervisor/usb.c`. Only flash regions not used by +Zephyr are used for CIRCUITPY. A manual `circuitpython` partition can be +specified instead. + +For example, to test the `nrf52840dk` board: + +```sh +west build -b nrf52840dk/nrf52840 +``` + +This is already supported in `ports/nordic` as `pca10056`. diff --git a/ports/zephyr-cp/app.overlay b/ports/zephyr-cp/app.overlay new file mode 100644 index 00000000000..bb2be8924f6 --- /dev/null +++ b/ports/zephyr-cp/app.overlay @@ -0,0 +1,22 @@ +&zephyr_udc0 { + cdc_acm_console: cdc_acm_console { + compatible = "zephyr,cdc-acm-uart"; + label = "CircuitPython Console"; + }; + cdc_acm_data: cdc_acm_data { + compatible = "zephyr,cdc-acm-uart"; + label = "CircuitPython Data"; + }; +}; + +/ { + hid_dev_0: hid_dev_0 { + compatible = "zephyr,hid-device"; + label = "HID0"; + protocol-code = "none"; + in-polling-period-us = <1000>; + in-report-size = <64>; + out-polling-period-us = <1000>; + out-report-size = <64>; + }; +}; diff --git a/ports/zephyr-cp/background.c b/ports/zephyr-cp/background.c new file mode 100644 index 00000000000..56e9e98f1f2 --- /dev/null +++ b/ports/zephyr-cp/background.c @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "background.h" + +#include "py/runtime.h" +#include "supervisor/port.h" + +#include + +void port_start_background_tick(void) { +} + +void port_finish_background_tick(void) { +} + +void port_background_tick(void) { + // No, ticks. We use Zephyr threads instead. +} + +void port_background_task(void) { + // Make sure time advances in the simulator. + #if defined(CONFIG_ARCH_POSIX) + k_busy_wait(100); + #endif +} diff --git a/ports/zephyr-cp/background.h b/ports/zephyr-cp/background.h new file mode 100644 index 00000000000..5712b054193 --- /dev/null +++ b/ports/zephyr-cp/background.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +void board_background_task(void); diff --git a/ports/zephyr-cp/bindings/hostnetwork/HostNetwork.c b/ports/zephyr-cp/bindings/hostnetwork/HostNetwork.c new file mode 100644 index 00000000000..fc0fb9ecc4f --- /dev/null +++ b/ports/zephyr-cp/bindings/hostnetwork/HostNetwork.c @@ -0,0 +1,37 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "bindings/hostnetwork/HostNetwork.h" + +#include "py/runtime.h" + +//| class HostNetwork: +//| """Native networking for the host simulator.""" +//| +//| def __init__(self) -> None: +//| """Create a HostNetwork instance.""" +//| ... +//| +static mp_obj_t hostnetwork_hostnetwork_make_new(const mp_obj_type_t *type, + size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 0, 0, false); + + hostnetwork_hostnetwork_obj_t *self = mp_obj_malloc(hostnetwork_hostnetwork_obj_t, &hostnetwork_hostnetwork_type); + common_hal_hostnetwork_hostnetwork_construct(self); + return MP_OBJ_FROM_PTR(self); +} + +static const mp_rom_map_elem_t hostnetwork_hostnetwork_locals_dict_table[] = { +}; +static MP_DEFINE_CONST_DICT(hostnetwork_hostnetwork_locals_dict, hostnetwork_hostnetwork_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + hostnetwork_hostnetwork_type, + MP_QSTR_HostNetwork, + MP_TYPE_FLAG_NONE, + make_new, hostnetwork_hostnetwork_make_new, + locals_dict, &hostnetwork_hostnetwork_locals_dict + ); diff --git a/ports/zephyr-cp/bindings/hostnetwork/HostNetwork.h b/ports/zephyr-cp/bindings/hostnetwork/HostNetwork.h new file mode 100644 index 00000000000..009d8c06087 --- /dev/null +++ b/ports/zephyr-cp/bindings/hostnetwork/HostNetwork.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} hostnetwork_hostnetwork_obj_t; + +extern const mp_obj_type_t hostnetwork_hostnetwork_type; + +void common_hal_hostnetwork_hostnetwork_construct(hostnetwork_hostnetwork_obj_t *self); diff --git a/ports/zephyr-cp/bindings/hostnetwork/__init__.c b/ports/zephyr-cp/bindings/hostnetwork/__init__.c new file mode 100644 index 00000000000..92302b67d0e --- /dev/null +++ b/ports/zephyr-cp/bindings/hostnetwork/__init__.c @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" + +#include "bindings/hostnetwork/__init__.h" +#include "bindings/hostnetwork/HostNetwork.h" + +//| """Host networking support for the native simulator.""" +//| + +static const mp_rom_map_elem_t hostnetwork_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hostnetwork) }, + { MP_ROM_QSTR(MP_QSTR_HostNetwork), MP_ROM_PTR(&hostnetwork_hostnetwork_type) }, +}; +static MP_DEFINE_CONST_DICT(hostnetwork_module_globals, hostnetwork_module_globals_table); + +const mp_obj_module_t hostnetwork_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&hostnetwork_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_hostnetwork, hostnetwork_module); diff --git a/ports/zephyr-cp/bindings/hostnetwork/__init__.h b/ports/zephyr-cp/bindings/hostnetwork/__init__.h new file mode 100644 index 00000000000..a6731546bde --- /dev/null +++ b/ports/zephyr-cp/bindings/hostnetwork/__init__.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "bindings/hostnetwork/HostNetwork.h" + +extern hostnetwork_hostnetwork_obj_t common_hal_hostnetwork_obj; diff --git a/ports/zephyr-cp/bindings/zephyr_display/Display.c b/ports/zephyr-cp/bindings/zephyr_display/Display.c new file mode 100644 index 00000000000..0923618c50a --- /dev/null +++ b/ports/zephyr-cp/bindings/zephyr_display/Display.c @@ -0,0 +1,195 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "bindings/zephyr_display/Display.h" + +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-module/displayio/__init__.h" + +static mp_obj_t zephyr_display_display_make_new(const mp_obj_type_t *type, + size_t n_args, + size_t n_kw, + const mp_obj_t *all_args) { + (void)type; + (void)n_args; + (void)n_kw; + (void)all_args; + mp_raise_NotImplementedError(NULL); + return mp_const_none; +} + +static zephyr_display_display_obj_t *native_display(mp_obj_t display_obj) { + mp_obj_t native = mp_obj_cast_to_native_base(display_obj, &zephyr_display_display_type); + mp_obj_assert_native_inited(native); + return MP_OBJ_TO_PTR(native); +} + +static mp_obj_t zephyr_display_display_obj_show(mp_obj_t self_in, mp_obj_t group_in) { + (void)self_in; + (void)group_in; + mp_raise_AttributeError(MP_ERROR_TEXT(".show(x) removed. Use .root_group = x")); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_show_obj, zephyr_display_display_obj_show); + +static mp_obj_t zephyr_display_display_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { + ARG_target_frames_per_second, + ARG_minimum_frames_per_second, + }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_target_frames_per_second, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + zephyr_display_display_obj_t *self = native_display(pos_args[0]); + + uint32_t maximum_ms_per_real_frame = NO_FPS_LIMIT; + mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int; + if (minimum_frames_per_second > 0) { + maximum_ms_per_real_frame = 1000 / minimum_frames_per_second; + } + + uint32_t target_ms_per_frame; + if (args[ARG_target_frames_per_second].u_obj == mp_const_none) { + target_ms_per_frame = NO_FPS_LIMIT; + } else { + target_ms_per_frame = 1000 / mp_obj_get_int(args[ARG_target_frames_per_second].u_obj); + } + + return mp_obj_new_bool(common_hal_zephyr_display_display_refresh( + self, + target_ms_per_frame, + maximum_ms_per_real_frame)); +} +MP_DEFINE_CONST_FUN_OBJ_KW(zephyr_display_display_refresh_obj, 1, zephyr_display_display_obj_refresh); + +static mp_obj_t zephyr_display_display_obj_get_auto_refresh(mp_obj_t self_in) { + zephyr_display_display_obj_t *self = native_display(self_in); + return mp_obj_new_bool(common_hal_zephyr_display_display_get_auto_refresh(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_auto_refresh_obj, zephyr_display_display_obj_get_auto_refresh); + +static mp_obj_t zephyr_display_display_obj_set_auto_refresh(mp_obj_t self_in, mp_obj_t auto_refresh) { + zephyr_display_display_obj_t *self = native_display(self_in); + common_hal_zephyr_display_display_set_auto_refresh(self, mp_obj_is_true(auto_refresh)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_auto_refresh_obj, zephyr_display_display_obj_set_auto_refresh); + +MP_PROPERTY_GETSET(zephyr_display_display_auto_refresh_obj, + (mp_obj_t)&zephyr_display_display_get_auto_refresh_obj, + (mp_obj_t)&zephyr_display_display_set_auto_refresh_obj); + +static mp_obj_t zephyr_display_display_obj_get_brightness(mp_obj_t self_in) { + zephyr_display_display_obj_t *self = native_display(self_in); + mp_float_t brightness = common_hal_zephyr_display_display_get_brightness(self); + if (brightness < 0) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Brightness not adjustable")); + } + return mp_obj_new_float(brightness); +} +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_brightness_obj, zephyr_display_display_obj_get_brightness); + +static mp_obj_t zephyr_display_display_obj_set_brightness(mp_obj_t self_in, mp_obj_t brightness_obj) { + zephyr_display_display_obj_t *self = native_display(self_in); + mp_float_t brightness = mp_obj_get_float(brightness_obj); + if (brightness < 0.0f || brightness > 1.0f) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be %d-%d"), MP_QSTR_brightness, 0, 1); + } + bool ok = common_hal_zephyr_display_display_set_brightness(self, brightness); + if (!ok) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Brightness not adjustable")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_brightness_obj, zephyr_display_display_obj_set_brightness); + +MP_PROPERTY_GETSET(zephyr_display_display_brightness_obj, + (mp_obj_t)&zephyr_display_display_get_brightness_obj, + (mp_obj_t)&zephyr_display_display_set_brightness_obj); + +static mp_obj_t zephyr_display_display_obj_get_width(mp_obj_t self_in) { + zephyr_display_display_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_zephyr_display_display_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_width_obj, zephyr_display_display_obj_get_width); +MP_PROPERTY_GETTER(zephyr_display_display_width_obj, (mp_obj_t)&zephyr_display_display_get_width_obj); + +static mp_obj_t zephyr_display_display_obj_get_height(mp_obj_t self_in) { + zephyr_display_display_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_zephyr_display_display_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_height_obj, zephyr_display_display_obj_get_height); +MP_PROPERTY_GETTER(zephyr_display_display_height_obj, (mp_obj_t)&zephyr_display_display_get_height_obj); + +static mp_obj_t zephyr_display_display_obj_get_rotation(mp_obj_t self_in) { + zephyr_display_display_obj_t *self = native_display(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_zephyr_display_display_get_rotation(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_rotation_obj, zephyr_display_display_obj_get_rotation); + +static mp_obj_t zephyr_display_display_obj_set_rotation(mp_obj_t self_in, mp_obj_t value) { + zephyr_display_display_obj_t *self = native_display(self_in); + common_hal_zephyr_display_display_set_rotation(self, mp_obj_get_int(value)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_rotation_obj, zephyr_display_display_obj_set_rotation); + +MP_PROPERTY_GETSET(zephyr_display_display_rotation_obj, + (mp_obj_t)&zephyr_display_display_get_rotation_obj, + (mp_obj_t)&zephyr_display_display_set_rotation_obj); + +static mp_obj_t zephyr_display_display_obj_get_root_group(mp_obj_t self_in) { + zephyr_display_display_obj_t *self = native_display(self_in); + return common_hal_zephyr_display_display_get_root_group(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(zephyr_display_display_get_root_group_obj, zephyr_display_display_obj_get_root_group); + +static mp_obj_t zephyr_display_display_obj_set_root_group(mp_obj_t self_in, mp_obj_t group_in) { + zephyr_display_display_obj_t *self = native_display(self_in); + displayio_group_t *group = NULL; + if (group_in != mp_const_none) { + group = MP_OBJ_TO_PTR(native_group(group_in)); + } + + bool ok = common_hal_zephyr_display_display_set_root_group(self, group); + if (!ok) { + mp_raise_ValueError(MP_ERROR_TEXT("Group already used")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(zephyr_display_display_set_root_group_obj, zephyr_display_display_obj_set_root_group); + +MP_PROPERTY_GETSET(zephyr_display_display_root_group_obj, + (mp_obj_t)&zephyr_display_display_get_root_group_obj, + (mp_obj_t)&zephyr_display_display_set_root_group_obj); + +static const mp_rom_map_elem_t zephyr_display_display_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_show), MP_ROM_PTR(&zephyr_display_display_show_obj) }, + { MP_ROM_QSTR(MP_QSTR_refresh), MP_ROM_PTR(&zephyr_display_display_refresh_obj) }, + + { MP_ROM_QSTR(MP_QSTR_auto_refresh), MP_ROM_PTR(&zephyr_display_display_auto_refresh_obj) }, + { MP_ROM_QSTR(MP_QSTR_brightness), MP_ROM_PTR(&zephyr_display_display_brightness_obj) }, + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&zephyr_display_display_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&zephyr_display_display_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_rotation), MP_ROM_PTR(&zephyr_display_display_rotation_obj) }, + { MP_ROM_QSTR(MP_QSTR_root_group), MP_ROM_PTR(&zephyr_display_display_root_group_obj) }, +}; +static MP_DEFINE_CONST_DICT(zephyr_display_display_locals_dict, zephyr_display_display_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + zephyr_display_display_type, + MP_QSTR_Display, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, zephyr_display_display_make_new, + locals_dict, &zephyr_display_display_locals_dict); diff --git a/ports/zephyr-cp/bindings/zephyr_display/Display.h b/ports/zephyr-cp/bindings/zephyr_display/Display.h new file mode 100644 index 00000000000..a50dda8fe8b --- /dev/null +++ b/ports/zephyr-cp/bindings/zephyr_display/Display.h @@ -0,0 +1,37 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/displayio/Group.h" +#include "common-hal/zephyr_display/Display.h" + +extern const mp_obj_type_t zephyr_display_display_type; + +#define NO_FPS_LIMIT 0xffffffff + +void common_hal_zephyr_display_display_construct_from_device(zephyr_display_display_obj_t *self, + const struct device *device, + uint16_t rotation, + bool auto_refresh); + +bool common_hal_zephyr_display_display_refresh(zephyr_display_display_obj_t *self, + uint32_t target_ms_per_frame, + uint32_t maximum_ms_per_real_frame); + +bool common_hal_zephyr_display_display_get_auto_refresh(zephyr_display_display_obj_t *self); +void common_hal_zephyr_display_display_set_auto_refresh(zephyr_display_display_obj_t *self, bool auto_refresh); + +uint16_t common_hal_zephyr_display_display_get_width(zephyr_display_display_obj_t *self); +uint16_t common_hal_zephyr_display_display_get_height(zephyr_display_display_obj_t *self); +uint16_t common_hal_zephyr_display_display_get_rotation(zephyr_display_display_obj_t *self); +void common_hal_zephyr_display_display_set_rotation(zephyr_display_display_obj_t *self, int rotation); + +mp_float_t common_hal_zephyr_display_display_get_brightness(zephyr_display_display_obj_t *self); +bool common_hal_zephyr_display_display_set_brightness(zephyr_display_display_obj_t *self, mp_float_t brightness); + +mp_obj_t common_hal_zephyr_display_display_get_root_group(zephyr_display_display_obj_t *self); +bool common_hal_zephyr_display_display_set_root_group(zephyr_display_display_obj_t *self, displayio_group_t *root_group); diff --git a/ports/zephyr-cp/bindings/zephyr_display/__init__.c b/ports/zephyr-cp/bindings/zephyr_display/__init__.c new file mode 100644 index 00000000000..eecfeeaec58 --- /dev/null +++ b/ports/zephyr-cp/bindings/zephyr_display/__init__.c @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/runtime.h" + +#include "bindings/zephyr_display/Display.h" + +static const mp_rom_map_elem_t zephyr_display_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_zephyr_display) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&zephyr_display_display_type) }, +}; + +static MP_DEFINE_CONST_DICT(zephyr_display_module_globals, zephyr_display_module_globals_table); + +const mp_obj_module_t zephyr_display_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&zephyr_display_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_zephyr_display, zephyr_display_module); diff --git a/ports/zephyr-cp/bindings/zephyr_display/__init__.h b/ports/zephyr-cp/bindings/zephyr_display/__init__.h new file mode 100644 index 00000000000..4256bfac2fe --- /dev/null +++ b/ports/zephyr-cp/bindings/zephyr_display/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/ports/zephyr-cp/bindings/zephyr_kernel/__init__.c b/ports/zephyr-cp/bindings/zephyr_kernel/__init__.c new file mode 100644 index 00000000000..e37bd247495 --- /dev/null +++ b/ports/zephyr-cp/bindings/zephyr_kernel/__init__.c @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/runtime.h" +#include "py/mphal.h" + + +#include "bindings/zephyr_kernel/__init__.h" diff --git a/ports/zephyr-cp/bindings/zephyr_kernel/__init__.h b/ports/zephyr-cp/bindings/zephyr_kernel/__init__.h new file mode 100644 index 00000000000..3215711bbf3 --- /dev/null +++ b/ports/zephyr-cp/bindings/zephyr_kernel/__init__.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/mpconfig.h" +#include "py/obj.h" + +#include "common-hal/zephyr_kernel/__init__.h" + +void raise_zephyr_error(int err); +#define CHECK_ZEPHYR_RESULT(x) do { int res = (x); if (res < 0) raise_zephyr_error(res); } while (0) diff --git a/ports/zephyr-cp/boards/adafruit/clue_nrf52840_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/clue_nrf52840_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..0afea836c10 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/clue_nrf52840_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Adafruit Industries LLC CLUE nRF52840 Express" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has displayio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = true # Zephyr board has zephyr_display +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/adafruit/clue_nrf52840_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/adafruit/clue_nrf52840_zephyr/circuitpython.toml new file mode 100644 index 00000000000..2d7b8c3db48 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/clue_nrf52840_zephyr/circuitpython.toml @@ -0,0 +1,4 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex", "uf2"] +USB_VID=0x239A +USB_PID=0x8072 +NAME="CLUE nRF52840 Express" diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..459ee6a98c2 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Adafruit Industries LLC Feather Bluefruit Sense" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/circuitpython.toml new file mode 100644 index 00000000000..eacb0f9607d --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_sense_zephyr/circuitpython.toml @@ -0,0 +1,4 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] +USB_VID=0x239A +USB_PID=0x8088 +NAME="Feather Bluefruit Sense" diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..654a6c2e01b --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Adafruit Industries LLC Feather nRF52840 Express" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/circuitpython.toml new file mode 100644 index 00000000000..c4d1099a77e --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_nrf52840_zephyr/circuitpython.toml @@ -0,0 +1,4 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] +USB_VID=0x239A +USB_PID=0x802A +NAME="Feather nRF52840 Express" diff --git a/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..17022b4d2c7 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Adafruit Industries LLC Feather RP2040" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/circuitpython.toml new file mode 100644 index 00000000000..9d3c229ed1b --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit/feather_rp2040_zephyr/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] diff --git a/ports/zephyr-cp/boards/adafruit_clue_nrf52840_uf2.conf b/ports/zephyr-cp/boards/adafruit_clue_nrf52840_uf2.conf new file mode 100644 index 00000000000..cfa31e2fdcf --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_clue_nrf52840_uf2.conf @@ -0,0 +1,6 @@ +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n + +# Enable the ST7789V TFT via the Zephyr display subsystem +CONFIG_DISPLAY=y diff --git a/ports/zephyr-cp/boards/adafruit_clue_nrf52840_uf2.overlay b/ports/zephyr-cp/boards/adafruit_clue_nrf52840_uf2.overlay new file mode 100644 index 00000000000..405b65ec8eb --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_clue_nrf52840_uf2.overlay @@ -0,0 +1,49 @@ +/ { + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + }; +}; + +&zephyr_udc0 { + /delete-node/ board_cdc_acm_uart; +}; + + +&gd25q16 { + /delete-node/ partitions; +}; + +/delete-node/ &storage_partition; +/delete-node/ &code_partition; + +&flash0 { + partitions { + code_partition: partition@26000 { + compatible = "zephyr,mapped-partition"; + label = "Application"; + reg = <0x00026000 0x000c4000>; + }; + + storage_partition: partition@ea000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x000ea000 0x00008000>; + }; + + nvm_partition: partition@f2000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x000f2000 0x00002000>; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.conf b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.conf new file mode 100644 index 00000000000..6d7299ec6e6 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.conf @@ -0,0 +1,3 @@ +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n diff --git a/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.overlay b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.overlay new file mode 100644 index 00000000000..405b65ec8eb --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_nrf52840_sense_uf2.overlay @@ -0,0 +1,49 @@ +/ { + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + }; +}; + +&zephyr_udc0 { + /delete-node/ board_cdc_acm_uart; +}; + + +&gd25q16 { + /delete-node/ partitions; +}; + +/delete-node/ &storage_partition; +/delete-node/ &code_partition; + +&flash0 { + partitions { + code_partition: partition@26000 { + compatible = "zephyr,mapped-partition"; + label = "Application"; + reg = <0x00026000 0x000c4000>; + }; + + storage_partition: partition@ea000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x000ea000 0x00008000>; + }; + + nvm_partition: partition@f2000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x000f2000 0x00002000>; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/adafruit_feather_nrf52840_uf2.conf b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_uf2.conf new file mode 100644 index 00000000000..6d7299ec6e6 --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_uf2.conf @@ -0,0 +1,3 @@ +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n diff --git a/ports/zephyr-cp/boards/adafruit_feather_nrf52840_uf2.overlay b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_uf2.overlay new file mode 100644 index 00000000000..405b65ec8eb --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_nrf52840_uf2.overlay @@ -0,0 +1,49 @@ +/ { + chosen { + zephyr,console = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; + }; +}; + +&zephyr_udc0 { + /delete-node/ board_cdc_acm_uart; +}; + + +&gd25q16 { + /delete-node/ partitions; +}; + +/delete-node/ &storage_partition; +/delete-node/ &code_partition; + +&flash0 { + partitions { + code_partition: partition@26000 { + compatible = "zephyr,mapped-partition"; + label = "Application"; + reg = <0x00026000 0x000c4000>; + }; + + storage_partition: partition@ea000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x000ea000 0x00008000>; + }; + + nvm_partition: partition@f2000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x000f2000 0x00002000>; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/adafruit_feather_rp2040.conf b/ports/zephyr-cp/boards/adafruit_feather_rp2040.conf new file mode 100644 index 00000000000..91c3c15b37d --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_rp2040.conf @@ -0,0 +1 @@ +CONFIG_GPIO=y diff --git a/ports/zephyr-cp/boards/adafruit_feather_rp2040.overlay b/ports/zephyr-cp/boards/adafruit_feather_rp2040.overlay new file mode 100644 index 00000000000..a19e2a066db --- /dev/null +++ b/ports/zephyr-cp/boards/adafruit_feather_rp2040.overlay @@ -0,0 +1,43 @@ +&flash0 { + /delete-node/ partitions; + + partitions { + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + code_partition: partition@100 { + compatible = "zephyr,mapped-partition"; + label = "code-partition"; + reg = <0x100 (0x180000 - 0x100)>; + read-only; + }; + + nvm_partition: partition@180000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x180000 0x800>; + }; + + storage_partition: partition@180800 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x180800 0x800>; + }; + + circuitpy_partition: partition@181000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x181000 (DT_SIZE_M(8) - 0x181000)>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/board_aliases.cmake b/ports/zephyr-cp/boards/board_aliases.cmake new file mode 100644 index 00000000000..f9eaca45d8c --- /dev/null +++ b/ports/zephyr-cp/boards/board_aliases.cmake @@ -0,0 +1,57 @@ +# Workaround for Zephyr alias handling with BOARD_QUALIFIERS in newer Zephyr. +# +# Instead of using _BOARD_ALIAS variables, translate BOARD directly so +# we don't end up with a spurious trailing '/' in BOARD_QUALIFIERS. +macro(cp_board_alias alias target) + if(BOARD STREQUAL "${alias}") + if(NOT "${target}" MATCHES "^([^@/]+)(@[^@/]+)?(/([^@]+))?$") + message(FATAL_ERROR "Invalid alias target '${target}'") + endif() + + set(BOARD_ALIAS "${alias}" CACHE STRING "Board alias, provided by user") + set(BOARD "${CMAKE_MATCH_1}") + + if(CMAKE_MATCH_2) + string(REPLACE "@" "" _rev "${CMAKE_MATCH_2}") + set(BOARD_REVISION "${_rev}") + else() + unset(BOARD_REVISION) + endif() + + if(CMAKE_MATCH_4) + set(BOARD_QUALIFIERS "${CMAKE_MATCH_4}") + else() + unset(BOARD_QUALIFIERS) + endif() + endif() +endmacro() + +cp_board_alias(pca10056 nrf52840dk/nrf52840) +cp_board_alias(adafruit_feather_nrf52840_zephyr adafruit_feather_nrf52840/nrf52840/uf2) +cp_board_alias(adafruit_clue_nrf52840_zephyr adafruit_clue_nrf52840/nrf52840/uf2) +cp_board_alias(adafruit_feather_nrf52840_sense_zephyr adafruit_feather_nrf52840/nrf52840/sense/uf2) +cp_board_alias(adafruit_feather_rp2040_zephyr adafruit_feather_rp2040/rp2040) +cp_board_alias(renesas_ek_ra6m5 ek_ra6m5) +cp_board_alias(renesas_ek_ra8d1 ek_ra8d1) +cp_board_alias(renesas_da14695_dk_usb da14695_dk_usb) +cp_board_alias(native_native_sim native_sim/native) +cp_board_alias(native_nrf5340bsim nrf5340bsim/nrf5340/cpuapp) +cp_board_alias(native_nrf54lm20bsim nrf54lm20bsim/nrf54lm20a/cpuapp) +cp_board_alias(nordic_nrf54l15dk nrf54l15dk/nrf54l15/cpuapp) +cp_board_alias(nordic_nrf54l15tag nrf54l15tag/nrf54l15/cpuapp) +cp_board_alias(nordic_nrf54lm20dk nrf54lm20dk/nrf54lm20a/cpuapp) +cp_board_alias(nordic_nrf54h20dk nrf54h20dk/nrf54h20/cpuapp) +cp_board_alias(nordic_nrf5340dk nrf5340dk/nrf5340/cpuapp) +cp_board_alias(nordic_nrf7002dk nrf7002dk/nrf5340/cpuapp) +cp_board_alias(nxp_frdm_mcxn947 frdm_mcxn947/mcxn947/cpu0) +cp_board_alias(nxp_frdm_rw612 frdm_rw612) +cp_board_alias(nxp_mimxrt1170_evk mimxrt1170_evk@A/mimxrt1176/cm7) +cp_board_alias(st_stm32h7b3i_dk stm32h7b3i_dk) +cp_board_alias(st_stm32h750b_dk stm32h750b_dk/stm32h750xx/ext_flash_app) +cp_board_alias(st_stm32wba65i_dk1 stm32wba65i_dk1) +cp_board_alias(st_nucleo_u575zi_q nucleo_u575zi_q/stm32u575xx) +cp_board_alias(raspberrypi_rpi_pico_zephyr rpi_pico/rp2040) +cp_board_alias(raspberrypi_rpi_pico_w_zephyr rpi_pico/rp2040/w) +cp_board_alias(raspberrypi_rpi_pico2_zephyr rpi_pico2/rp2350a/m33) +cp_board_alias(raspberrypi_rpi_pico2_w_zephyr rpi_pico2/rp2350a/m33/w) +cp_board_alias(st_nucleo_n657x0_q nucleo_n657x0_q/stm32n657xx) diff --git a/ports/zephyr-cp/boards/da14695_dk_usb.overlay b/ports/zephyr-cp/boards/da14695_dk_usb.overlay new file mode 100644 index 00000000000..cc3b33ec447 --- /dev/null +++ b/ports/zephyr-cp/boards/da14695_dk_usb.overlay @@ -0,0 +1,19 @@ +/* Remove slot1 (OTA), expand slot0 to use the space. + * CircuitPython doesn't use OTA updates. */ +&slot0_partition { + reg = <0x00010000 DT_SIZE_K(1024)>; +}; + +/delete-node/ &slot1_partition; + +&flash0 { + partitions{ + circuitpy_partition: partition@118000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x118000 (DT_SIZE_M(4) - DT_SIZE_K(1120))>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/ek_ra8d1.conf b/ports/zephyr-cp/boards/ek_ra8d1.conf new file mode 100644 index 00000000000..451f4199116 --- /dev/null +++ b/ports/zephyr-cp/boards/ek_ra8d1.conf @@ -0,0 +1,12 @@ + +# Enable Zephyr display subsystem so DT chosen zephyr,display creates a device. +CONFIG_DISPLAY=y + +# RA8 USB can generate bursts of UDC/USBD events (especially with HS + MSC). +# Keep queues/buffers larger to avoid dropped events that can desynchronize +# control-transfer state (e.g. "udc: Cannot determine the next stage"). +CONFIG_UDC_RENESAS_RA_MAX_QMESSAGES=32 +CONFIG_USBD_MAX_UDC_MSG=32 +CONFIG_USBD_MSG_SLAB_COUNT=32 +CONFIG_UDC_BUF_COUNT=32 +CONFIG_UDC_BUF_POOL_SIZE=2048 diff --git a/ports/zephyr-cp/boards/ek_ra8d1.overlay b/ports/zephyr-cp/boards/ek_ra8d1.overlay new file mode 100644 index 00000000000..c13dfc457f5 --- /dev/null +++ b/ports/zephyr-cp/boards/ek_ra8d1.overlay @@ -0,0 +1,5 @@ +&s28hl512t { + /delete-node/ partitions; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/frdm_mcxn947_mcxn947_cpu0.conf b/ports/zephyr-cp/boards/frdm_mcxn947_mcxn947_cpu0.conf new file mode 100644 index 00000000000..61f2d18ca3c --- /dev/null +++ b/ports/zephyr-cp/boards/frdm_mcxn947_mcxn947_cpu0.conf @@ -0,0 +1 @@ +CONFIG_DMA_TCD_QUEUE_SIZE=4 diff --git a/ports/zephyr-cp/boards/frdm_mcxn947_mcxn947_cpu0.overlay b/ports/zephyr-cp/boards/frdm_mcxn947_mcxn947_cpu0.overlay new file mode 100644 index 00000000000..f1a07471477 --- /dev/null +++ b/ports/zephyr-cp/boards/frdm_mcxn947_mcxn947_cpu0.overlay @@ -0,0 +1,23 @@ +&w25q64jvssiq { + /delete-node/ partitions; + + partitions { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + storage_partition: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x0 DT_SIZE_K(32)>; + }; + + circuitpy_partition: partition@8000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00008000 (DT_SIZE_M(8) - DT_SIZE_K(32))>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/frdm_rw612.conf b/ports/zephyr-cp/boards/frdm_rw612.conf new file mode 100644 index 00000000000..f8d1dfa0ad6 --- /dev/null +++ b/ports/zephyr-cp/boards/frdm_rw612.conf @@ -0,0 +1,25 @@ +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_NET_SOCKETS=y + +CONFIG_WIFI=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_LEGACY_CRYPTO=n +CONFIG_NET_L2_WIFI_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_NET_MGMT_EVENT_INFO=y + +CONFIG_NET_HOSTNAME_ENABLE=y +CONFIG_NET_HOSTNAME_DYNAMIC=y +CONFIG_NET_HOSTNAME="circuitpython" + +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +CONFIG_MBEDTLS_CIPHERSUITE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256=y +CONFIG_MBEDTLS_ENTROPY_C=y +CONFIG_MBEDTLS_CTR_DRBG_C=y + +# Override Kconfig default (3) +CONFIG_BT_BUF_ACL_TX_COUNT=8 + +CONFIG_UDC_WORKQUEUE_STACK_SIZE=1024 diff --git a/ports/zephyr-cp/boards/frdm_rw612.overlay b/ports/zephyr-cp/boards/frdm_rw612.overlay new file mode 100644 index 00000000000..e926394817e --- /dev/null +++ b/ports/zephyr-cp/boards/frdm_rw612.overlay @@ -0,0 +1,17 @@ +&w25q512jvfiq { + partitions { + /delete-node/ partition@620000; + storage_partition: partition@620000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x00620000 DT_SIZE_K(32)>; + }; + circuitpy_partition: partition@628000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00628000 (DT_SIZE_M(58) - DT_SIZE_K(128) - DT_SIZE_K(32))>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/frdm_rw612_rw612_cpu0.overlay b/ports/zephyr-cp/boards/frdm_rw612_rw612_cpu0.overlay new file mode 100644 index 00000000000..e57b5b6d331 --- /dev/null +++ b/ports/zephyr-cp/boards/frdm_rw612_rw612_cpu0.overlay @@ -0,0 +1,18 @@ +&w25q512jvfiq { + partitions { + /delete-node/ storage_partition; + storage_partition: partition@620000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x00620000 DT_SIZE_K(32)>; + }; + circuitpy_partition: partition@628000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00628000 (DT_SIZE_M(58) - DT_SIZE_K(128) - DT_SIZE_K(32))>; + }; + } + +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/mimxrt1170_evk_mimxrt1176_cm7.conf b/ports/zephyr-cp/boards/mimxrt1170_evk_mimxrt1176_cm7.conf new file mode 100644 index 00000000000..61f2d18ca3c --- /dev/null +++ b/ports/zephyr-cp/boards/mimxrt1170_evk_mimxrt1176_cm7.conf @@ -0,0 +1 @@ +CONFIG_DMA_TCD_QUEUE_SIZE=4 diff --git a/ports/zephyr-cp/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay b/ports/zephyr-cp/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay new file mode 100644 index 00000000000..b8f707dac27 --- /dev/null +++ b/ports/zephyr-cp/boards/mimxrt1170_evk_mimxrt1176_cm7.overlay @@ -0,0 +1,21 @@ +&is25wp128 { + partitions { + /delete-node/ partition@e20000; + storage_partition: partition@e20000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x00e20000 DT_SIZE_K(32)>; + }; + circuitpy_partition: partition@e28000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00e28000 (DT_SIZE_M(2) - DT_SIZE_K(128) - DT_SIZE_K(32))>; + }; + }; +}; + +&sai1 { + mclk-output; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/native/native_sim/autogen_board_info.toml b/ports/zephyr-cp/boards/native/native_sim/autogen_board_info.toml new file mode 100644 index 00000000000..1f0486920fb --- /dev/null +++ b/ports/zephyr-cp/boards/native/native_sim/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "POSIX/Native Boards Native simulator - native_sim" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = true # Zephyr board has audiobusio +audiocore = true # Zephyr board has audiobusio +audiodelays = true # Zephyr board has audiobusio +audiofilewriter = false +audiofilters = true # Zephyr board has audiobusio +audiofreeverb = true # Zephyr board has audiobusio +audioi2sin = false +audioio = false +audiomixer = true # Zephyr board has audiobusio +audiomp3 = true # Zephyr board has audiobusio +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has displayio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true # Zephyr networking enabled +hostnetwork = true # Zephyr board has hostnetwork +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = true # Zephyr networking enabled +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = true # Zephyr networking enabled +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = true # Zephyr board has audiobusio +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = false +usb_hid = false +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = true # Zephyr board has zephyr_display +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/native/native_sim/circuitpython.toml b/ports/zephyr-cp/boards/native/native_sim/circuitpython.toml new file mode 100644 index 00000000000..7177c825f17 --- /dev/null +++ b/ports/zephyr-cp/boards/native/native_sim/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["exe"] diff --git a/ports/zephyr-cp/boards/native/nrf5340bsim/autogen_board_info.toml b/ports/zephyr-cp/boards/native/nrf5340bsim/autogen_board_info.toml new file mode 100644 index 00000000000..dc9608542f6 --- /dev/null +++ b/ports/zephyr-cp/boards/native/nrf5340bsim/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "POSIX/Native Boards nRF5340 simulated boards (BabbleSim)" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = false +usb_hid = false +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/native/nrf5340bsim/circuitpython.toml b/ports/zephyr-cp/boards/native/nrf5340bsim/circuitpython.toml new file mode 100644 index 00000000000..7177c825f17 --- /dev/null +++ b/ports/zephyr-cp/boards/native/nrf5340bsim/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["exe"] diff --git a/ports/zephyr-cp/boards/native/nrf54lm20bsim/autogen_board_info.toml b/ports/zephyr-cp/boards/native/nrf54lm20bsim/autogen_board_info.toml new file mode 100644 index 00000000000..6a470b5906b --- /dev/null +++ b/ports/zephyr-cp/boards/native/nrf54lm20bsim/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "POSIX/Native Boards nRF54LM20 simulated boards (BabbleSim)" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = false +usb_hid = false +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/native/nrf54lm20bsim/circuitpython.toml b/ports/zephyr-cp/boards/native/nrf54lm20bsim/circuitpython.toml new file mode 100644 index 00000000000..7177c825f17 --- /dev/null +++ b/ports/zephyr-cp/boards/native/nrf54lm20bsim/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["exe"] diff --git a/ports/zephyr-cp/boards/native_sim.conf b/ports/zephyr-cp/boards/native_sim.conf new file mode 100644 index 00000000000..6ae4c35110b --- /dev/null +++ b/ports/zephyr-cp/boards/native_sim.conf @@ -0,0 +1,46 @@ +# No Bluetooth hardware on native_sim +CONFIG_BT=n + +CONFIG_EMUL=y +CONFIG_GPIO=y +CONFIG_NATIVE_SIM_SLOWDOWN_TO_REAL_TIME=n + +# So we can test safe mode +CONFIG_NATIVE_SIM_REBOOT=y + +CONFIG_TRACING=y +CONFIG_TRACING_PERFETTO=y +CONFIG_TRACING_SYNC=y +CONFIG_TRACING_BACKEND_POSIX=y +CONFIG_TRACING_GPIO=y + +# I2C emulation for testing +CONFIG_I2C_EMUL=y + +# Display emulation for display/terminal golden tests. +CONFIG_DISPLAY=y +CONFIG_SDL_DISPLAY=y + +# EEPROM emulation for testing +CONFIG_EEPROM=y +CONFIG_EEPROM_AT24=y +CONFIG_EEPROM_AT2X_EMUL=y + +# I2S SDL emulation for audio testing +CONFIG_I2S_SDL=y + +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_TCP=y +CONFIG_NET_SOCKETS=y +CONFIG_ETH_NATIVE_TAP=n +CONFIG_NET_DRIVERS=y +CONFIG_NET_SOCKETS_OFFLOAD=y +CONFIG_NET_NATIVE_OFFLOADED_SOCKETS=y +CONFIG_HEAP_MEM_POOL_SIZE=1024 + +CONFIG_NET_LOG=y + +CONFIG_MBEDTLS=y +CONFIG_PSA_WANT_ALG_SHA_1=y +CONFIG_PSA_WANT_ALG_SHA_256=y diff --git a/ports/zephyr-cp/boards/native_sim.overlay b/ports/zephyr-cp/boards/native_sim.overlay new file mode 100644 index 00000000000..f94f71726a8 --- /dev/null +++ b/ports/zephyr-cp/boards/native_sim.overlay @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Device tree overlay for CircuitPython on native_sim. + * Adds simulated SRAM region required by CircuitPython build system. + */ + +#include + +/ { + sram0: memory@20000000 { + device_type = "memory"; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_M(1)>; + zephyr,memory-region = "SRAM"; + }; + + chosen { + zephyr,sram = &sram0; + /delete-property/ zephyr,flash; + /delete-property/ zephyr,code-partition; + }; +}; + +&flash0 { + /delete-node/ partitions; + partitions { + #address-cells = <1>; + #size-cells = <1>; + + circuitpy_partition: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00000000 DT_SIZE_K(2032)>; + }; + + storage_partition: partition@1fc000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x001fc000 DT_SIZE_K(8)>; + }; + + nvm_partition: partition@1fe000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x001fe000 0x00002000>; + }; + }; +}; + +/* Add emulated I2C devices for testing */ +&i2c0 { + at24_eeprom: eeprom@50 { + compatible = "atmel,at24"; + reg = <0x50>; + size = <256>; + pagesize = <8>; + address-width = <8>; + timeout = <5>; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml new file mode 100644 index 00000000000..366d4cd4cb3 --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf5340dk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Nordic Semiconductor nRF5340 DK" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = true # Zephyr board has audiobusio +audiocore = true # Zephyr board has audiobusio +audiodelays = true # Zephyr board has audiobusio +audiofilewriter = false +audiofilters = true # Zephyr board has audiobusio +audiofreeverb = true # Zephyr board has audiobusio +audioi2sin = false +audioio = false +audiomixer = true # Zephyr board has audiobusio +audiomp3 = true # Zephyr board has audiobusio +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = true # Zephyr board has audiobusio +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nordic/nrf5340dk/circuitpython.toml b/ports/zephyr-cp/boards/nordic/nrf5340dk/circuitpython.toml new file mode 100644 index 00000000000..cc7e3ae8c4a --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf5340dk/circuitpython.toml @@ -0,0 +1,3 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] +USB_VID=0x239A +USB_PID=0x8166 diff --git a/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml new file mode 100644 index 00000000000..b3da39f698c --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54h20dk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Nordic Semiconductor nRF54H20 DK" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = false # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = false # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = false # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nordic/nrf54h20dk/circuitpython.toml b/ports/zephyr-cp/boards/nordic/nrf54h20dk/circuitpython.toml new file mode 100644 index 00000000000..7cf2501b2b1 --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54h20dk/circuitpython.toml @@ -0,0 +1,2 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "hex"] +DISABLED_MODULES=["jpegio", "gifio", "tilepalettemapper"] diff --git a/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml new file mode 100644 index 00000000000..51551341199 --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54l15dk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Nordic Semiconductor nRF54L15 DK" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = false +usb_hid = false +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nordic/nrf54l15dk/circuitpython.toml b/ports/zephyr-cp/boards/nordic/nrf54l15dk/circuitpython.toml new file mode 100644 index 00000000000..00c797b1dad --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54l15dk/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "hex"] diff --git a/ports/zephyr-cp/boards/nordic/nrf54l15tag/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54l15tag/autogen_board_info.toml new file mode 100644 index 00000000000..8c19b7801b5 --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54l15tag/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Nordic Semiconductor nRF54L15 TAG" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = false +usb_hid = false +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nordic/nrf54l15tag/circuitpython.toml b/ports/zephyr-cp/boards/nordic/nrf54l15tag/circuitpython.toml new file mode 100644 index 00000000000..83e6bcd39c4 --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54l15tag/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] diff --git a/ports/zephyr-cp/boards/nordic/nrf54lm20dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf54lm20dk/autogen_board_info.toml new file mode 100644 index 00000000000..9da6422265e --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54lm20dk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Nordic Semiconductor nRF54LM20 DK" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nordic/nrf54lm20dk/circuitpython.toml b/ports/zephyr-cp/boards/nordic/nrf54lm20dk/circuitpython.toml new file mode 100644 index 00000000000..83e6bcd39c4 --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf54lm20dk/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] diff --git a/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml new file mode 100644 index 00000000000..9f31476b449 --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf7002dk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Nordic Semiconductor nRF7002 DK" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = false +adafruit_pixelbuf = false +aesio = false +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = false # Zephyr board has busio +gnss = false +hashlib = true # Zephyr networking enabled +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = true # Zephyr networking enabled +is31fl3741 = false +jpegio = false # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = true # Zephyr networking enabled +spitarget = false +ssl = true # Zephyr networking enabled +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = false # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = true # Zephyr board has wifi +zephyr_display = false +zephyr_kernel = false +zlib = false +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nordic/nrf7002dk/circuitpython.toml b/ports/zephyr-cp/boards/nordic/nrf7002dk/circuitpython.toml new file mode 100644 index 00000000000..54f84efe09b --- /dev/null +++ b/ports/zephyr-cp/boards/nordic/nrf7002dk/circuitpython.toml @@ -0,0 +1,5 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] +USB_VID=0x239A +USB_PID=0x8168 +BLOBS=["nrf_wifi"] +DISABLED_MODULES=["aesio", "adafruit_bus_device", "zlib", "jpegio", "tilepalettemapper", "gifio"] diff --git a/ports/zephyr-cp/boards/nrf5340bsim_nrf5340_cpuapp.conf b/ports/zephyr-cp/boards/nrf5340bsim_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..2579bf28d67 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf5340bsim_nrf5340_cpuapp.conf @@ -0,0 +1,20 @@ +# Configuration for nrf5340bsim simulated board +# Mirror settings from native_sim.conf for compatibility + +CONFIG_GPIO=y + +# Enable Bluetooth stack - bsim is for BT simulation +CONFIG_BT_HCI=y +CONFIG_BT_HCI_VS=y + +# Override Kconfig default +CONFIG_BT_BUF_CMD_TX_COUNT=2 + +# Ensure the network core image starts when using native simulator +CONFIG_NATIVE_SIMULATOR_AUTOSTART_MCU=y + +CONFIG_TRACING=y +CONFIG_TRACING_PERFETTO=y +CONFIG_TRACING_SYNC=y +CONFIG_TRACING_BACKEND_POSIX=y +CONFIG_TRACING_GPIO=y diff --git a/ports/zephyr-cp/boards/nrf5340bsim_nrf5340_cpuapp.overlay b/ports/zephyr-cp/boards/nrf5340bsim_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000..5f0c9fd7af8 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf5340bsim_nrf5340_cpuapp.overlay @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/ { + chosen { + zephyr,sram = &sram0; + }; +}; + +&sram0 { + compatible = "zephyr,memory-region", "mmio-sram"; + zephyr,memory-region = "SRAM"; +}; + +&flash0 { + /delete-node/ partitions; + partitions { + #address-cells = <1>; + #size-cells = <1>; + + circuitpy_partition: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00000000 DT_SIZE_K(1008)>; + }; + + storage_partition: partition@fc000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x000fc000 DT_SIZE_K(16)>; + }; + }; +}; + +/* Note: bsim doesn't have USB, so we don't include app.overlay */ diff --git a/ports/zephyr-cp/boards/nrf5340dk_nrf5340_cpuapp.overlay b/ports/zephyr-cp/boards/nrf5340dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000..180d6a23568 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -0,0 +1,32 @@ +&pinctrl { + i2s0_default_alt: i2s0_default_alt { + group1 { + psels = , + , + , + , + ; + }; + }; +}; + +&clock { + hfclkaudio-frequency = <11289600>; +}; + +i2s_rxtx: &i2s0 { + status = "okay"; + pinctrl-0 = <&i2s0_default_alt>; + pinctrl-names = "default"; + clock-source = "ACLK"; +}; + +/* Remove slot1 (OTA), expand slot0 to use the space. + * CircuitPython doesn't use OTA updates. */ +&slot0_partition { + reg = <0x00010000 0x000E0000>; +}; + +/delete-node/ &slot1_partition; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/nrf54h20dk_nrf54h20_cpuapp.conf b/ports/zephyr-cp/boards/nrf54h20dk_nrf54h20_cpuapp.conf new file mode 100644 index 00000000000..3aca8d77007 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54h20dk_nrf54h20_cpuapp.conf @@ -0,0 +1,11 @@ +CONFIG_FLASH_MSPI_NOR_LAYOUT_PAGE_SIZE=4096 + +# BLE overflows flash on this board. +CONFIG_BT=n + +# Reduce flash usage for this board. +CONFIG_LOG=y +CONFIG_LOG_MAX_LEVEL=2 +CONFIG_ASSERT=n +CONFIG_FRAME_POINTER=n +CONFIG_HW_STACK_PROTECTION=n diff --git a/ports/zephyr-cp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/ports/zephyr-cp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 00000000000..10df6b9f282 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,55 @@ +&gpio6 { + status = "okay"; + zephyr,pm-device-runtime-auto; +}; + +&exmif { + status = "okay"; + zephyr,pm-device-runtime-auto; +}; + +&mx25uw63 { + status = "okay"; +}; + +/* + * SDA = P2.11 + * SCL = P2.10 + */ + +&pinctrl { + i2c130_default: i2c130_default { + group1 { + psels = , + ; + }; + }; + + i2c130_sleep: i2c130_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&i2c130 { + clock-frequency = ; + pinctrl-0 = <&i2c130_default>; + pinctrl-1 = <&i2c130_sleep>; + pinctrl-names = "default", "sleep"; + zephyr,concat-buf-size = <256>; + memory-regions = <&cpuapp_dma_region>; + status = "okay"; +}; + +/* Remove slot1 (OTA), expand slot0 to use the space. + * CircuitPython doesn't use OTA updates. */ +&slot0_partition { + reg = <0x40000 DT_SIZE_K(656)>; +}; + +/delete-node/ &slot1_partition; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/ports/zephyr-cp/boards/nrf54l15dk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..7ffd2dec4d6 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -0,0 +1,28 @@ +// nRF54L15 DK doesn't have USB, so no app.overlay for CDC ACM. + +// I2C bus on P1.8 (SDA) and P1.10 (SCL). +&pinctrl { + i2c21_default: i2c21_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c21_sleep: i2c21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&i2c21 { + clock-frequency = ; + pinctrl-0 = <&i2c21_default>; + pinctrl-1 = <&i2c21_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; +}; diff --git a/ports/zephyr-cp/boards/nrf54l15tag_nrf54l15_cpuapp.conf b/ports/zephyr-cp/boards/nrf54l15tag_nrf54l15_cpuapp.conf new file mode 100644 index 00000000000..2627ebe2e5f --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54l15tag_nrf54l15_cpuapp.conf @@ -0,0 +1,4 @@ +# Enable UART console (not enabled in the Zephyr board defconfig) +CONFIG_SERIAL=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/ports/zephyr-cp/boards/nrf54l15tag_nrf54l15_cpuapp.overlay b/ports/zephyr-cp/boards/nrf54l15tag_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..ddf5c8f7e8f --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54l15tag_nrf54l15_cpuapp.overlay @@ -0,0 +1,39 @@ +// No app.overlay because it doesn't have USB. + +// The nrf54l15tag Zephyr board doesn't enable a UART or set zephyr,console, +// unlike the nrf54l15dk. Set up UART30 as the console using available pins. +&uart30 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart30_default>; + pinctrl-1 = <&uart30_sleep>; + pinctrl-names = "default", "sleep"; +}; + +&pinctrl { + uart30_default: uart30_default { + group1 { + psels = ; + }; + group2 { + psels = ; + bias-pull-up; + }; + }; + + uart30_sleep: uart30_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +/ { + chosen { + zephyr,console = &uart30; + zephyr,shell-uart = &uart30; + zephyr,uart-mcumgr = &uart30; + }; +}; diff --git a/ports/zephyr-cp/boards/nrf54lm20bsim_nrf54lm20a_cpuapp.conf b/ports/zephyr-cp/boards/nrf54lm20bsim_nrf54lm20a_cpuapp.conf new file mode 100644 index 00000000000..784cb782b4d --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54lm20bsim_nrf54lm20a_cpuapp.conf @@ -0,0 +1,19 @@ +# Configuration for nrf54lm20bsim simulated board + +CONFIG_GPIO=y + +# Enable Bluetooth stack - bsim is for BT simulation +CONFIG_BT_HCI=y +CONFIG_BT_HCI_VS=y + +# Match nrf54lm20dk hardware: support dynamic TX power control +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y + +# Override Kconfig default +CONFIG_BT_BUF_CMD_TX_COUNT=2 + +CONFIG_TRACING=y +CONFIG_TRACING_PERFETTO=y +CONFIG_TRACING_SYNC=y +CONFIG_TRACING_BACKEND_POSIX=y +CONFIG_TRACING_GPIO=y diff --git a/ports/zephyr-cp/boards/nrf54lm20bsim_nrf54lm20a_cpuapp.overlay b/ports/zephyr-cp/boards/nrf54lm20bsim_nrf54lm20a_cpuapp.overlay new file mode 100644 index 00000000000..ed5831ec5a3 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54lm20bsim_nrf54lm20a_cpuapp.overlay @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: Apache-2.0 */ + +/ { + sram0: memory@20000000 { + device_type = "memory"; + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x20000000 DT_SIZE_K(511)>; + zephyr,memory-region = "SRAM"; + }; + + chosen { + zephyr,sram = &sram0; + }; +}; + +&cpuapp_rram { + /delete-node/ partitions; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + circuitpy_partition: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00000000 (DT_SIZE_K(2036) - DT_SIZE_K(32))>; + }; + + storage_partition: partition@1f5000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x001f5000 DT_SIZE_K(32)>; + }; + }; +}; + +/* Note: bsim doesn't have USB, so we don't include app.overlay */ diff --git a/ports/zephyr-cp/boards/nrf54lm20dk_nrf54lm20a_cpuapp.conf b/ports/zephyr-cp/boards/nrf54lm20dk_nrf54lm20a_cpuapp.conf new file mode 100644 index 00000000000..e6749ae6399 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54lm20dk_nrf54lm20a_cpuapp.conf @@ -0,0 +1 @@ +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/ports/zephyr-cp/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay b/ports/zephyr-cp/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay new file mode 100644 index 00000000000..c1ebea74a70 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf54lm20dk_nrf54lm20a_cpuapp.overlay @@ -0,0 +1,52 @@ +// nRF54LM20 DK has USB. Include the main app overlay for USB CDC ACM console and data. +#include "../app.overlay" + +// Link application starting at 0x0 instead of slot0_partition (no mcuboot yet). +/ { + chosen { + zephyr,code-partition = &cpuapp_rram; + }; +}; + +// Enable the external MX25R6435F 8MB QSPI flash (connected via SPIM00). +&mx25r64 { + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + circuitpy_partition: partition@0 { + label = "circuitpy"; + reg = <0x00000000 DT_SIZE_M(8)>; + }; + }; +}; + +// I2C bus on P1.13 (SDA) and P1.23 (SCL). +&pinctrl { + i2c21_default: i2c21_default { + group1 { + psels = , + ; + bias-pull-up; + }; + }; + + i2c21_sleep: i2c21_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&i2c21 { + clock-frequency = ; + pinctrl-0 = <&i2c21_default>; + pinctrl-1 = <&i2c21_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; +}; diff --git a/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.conf b/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.conf new file mode 100644 index 00000000000..2255bd760d3 --- /dev/null +++ b/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.conf @@ -0,0 +1,10 @@ +CONFIG_NETWORKING=y +CONFIG_WIFI=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_LEGACY_CRYPTO=n + +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y + +CONFIG_LOG=n +CONFIG_ASSERT=n +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_BT=n diff --git a/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.overlay b/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.overlay new file mode 100644 index 00000000000..a02349aa7ad --- /dev/null +++ b/ports/zephyr-cp/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -0,0 +1,14 @@ +/* Remove slot1 (OTA), expand slot0 to use the space. + * CircuitPython doesn't use OTA updates. */ +&slot0_partition { + /* Shrink mcuboot to 48KB, absorb slot1 + gap before storage */ + reg = <0x0000C000 0x000EC000>; +}; + +&boot_partition { + reg = <0x00000000 0x0000C000>; +}; + +/delete-node/ &slot1_partition; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml new file mode 100644 index 00000000000..273aff2376d --- /dev/null +++ b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "NXP Semiconductors FRDM-MCXN947" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = true # Zephyr board has audiobusio +audiocore = true # Zephyr board has audiobusio +audiodelays = true # Zephyr board has audiobusio +audiofilewriter = false +audiofilters = true # Zephyr board has audiobusio +audiofreeverb = true # Zephyr board has audiobusio +audioi2sin = false +audioio = false +audiomixer = true # Zephyr board has audiobusio +audiomp3 = true # Zephyr board has audiobusio +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = true # Zephyr board has audiobusio +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nxp/frdm_mcxn947/circuitpython.toml b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/circuitpython.toml new file mode 100644 index 00000000000..3272dd4c5f3 --- /dev/null +++ b/ports/zephyr-cp/boards/nxp/frdm_mcxn947/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf"] diff --git a/ports/zephyr-cp/boards/nxp/frdm_rw612/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/frdm_rw612/autogen_board_info.toml new file mode 100644 index 00000000000..6efb741df94 --- /dev/null +++ b/ports/zephyr-cp/boards/nxp/frdm_rw612/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "NXP Semiconductors FRDM-RW612" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true # Zephyr networking enabled +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = true # Zephyr networking enabled +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = true # Zephyr networking enabled +spitarget = false +ssl = true # Zephyr networking enabled +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = true # Zephyr board has wifi +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nxp/frdm_rw612/circuitpython.toml b/ports/zephyr-cp/boards/nxp/frdm_rw612/circuitpython.toml new file mode 100644 index 00000000000..9bceea470ca --- /dev/null +++ b/ports/zephyr-cp/boards/nxp/frdm_rw612/circuitpython.toml @@ -0,0 +1,5 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf"] +BLOBS=["hal_nxp"] + +[blob_fetch_args] +hal_nxp = ["--allow-regex", "^rw61x/"] diff --git a/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml new file mode 100644 index 00000000000..cf5c0650015 --- /dev/null +++ b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "NXP Semiconductors MIMXRT1170-EVK" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = true # Zephyr board has audiobusio +audiocore = true # Zephyr board has audiobusio +audiodelays = true # Zephyr board has audiobusio +audiofilewriter = false +audiofilters = true # Zephyr board has audiobusio +audiofreeverb = true # Zephyr board has audiobusio +audioi2sin = false +audioio = false +audiomixer = true # Zephyr board has audiobusio +audiomp3 = true # Zephyr board has audiobusio +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = true # Zephyr board has audiobusio +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/circuitpython.toml b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/circuitpython.toml new file mode 100644 index 00000000000..3272dd4c5f3 --- /dev/null +++ b/ports/zephyr-cp/boards/nxp/mimxrt1170_evk/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf"] diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..e7d3f4502fd --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Raspberry Pi Foundation Raspberry Pi Pico 2" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true # Zephyr networking enabled +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = true # Zephyr networking enabled +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = true # Zephyr networking enabled +spitarget = false +ssl = true # Zephyr networking enabled +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = true # Zephyr board has wifi +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/circuitpython.toml new file mode 100644 index 00000000000..0f901d1149e --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_w_zephyr/circuitpython.toml @@ -0,0 +1,2 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] +BLOBS=["hal_infineon"] diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..95a2873af70 --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Raspberry Pi Foundation Raspberry Pi Pico 2" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/circuitpython.toml new file mode 100644 index 00000000000..9d3c229ed1b --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico2_zephyr/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..e2036293823 --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Raspberry Pi Foundation Raspberry Pi Pico" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true # Zephyr networking enabled +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = true # Zephyr networking enabled +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = true # Zephyr networking enabled +spitarget = false +ssl = true # Zephyr networking enabled +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = true # Zephyr board has wifi +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/circuitpython.toml new file mode 100644 index 00000000000..0f901d1149e --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_w_zephyr/circuitpython.toml @@ -0,0 +1,2 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] +BLOBS=["hal_infineon"] diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/autogen_board_info.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/autogen_board_info.toml new file mode 100644 index 00000000000..3c96b7d4f57 --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Raspberry Pi Foundation Raspberry Pi Pico" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = true # Zephyr board has nvm +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/circuitpython.toml b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/circuitpython.toml new file mode 100644 index 00000000000..9d3c229ed1b --- /dev/null +++ b/ports/zephyr-cp/boards/raspberrypi/rpi_pico_zephyr/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf", "uf2"] diff --git a/ports/zephyr-cp/boards/renesas/da14695_dk_usb/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/da14695_dk_usb/autogen_board_info.toml new file mode 100644 index 00000000000..4c396485d66 --- /dev/null +++ b/ports/zephyr-cp/boards/renesas/da14695_dk_usb/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Renesas Electronics Corporation DA14695 Development Kit USB" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/renesas/da14695_dk_usb/circuitpython.toml b/ports/zephyr-cp/boards/renesas/da14695_dk_usb/circuitpython.toml new file mode 100644 index 00000000000..f7fad6bc444 --- /dev/null +++ b/ports/zephyr-cp/boards/renesas/da14695_dk_usb/circuitpython.toml @@ -0,0 +1,2 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf"] +BLOBS=["hal_renesas"] diff --git a/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml new file mode 100644 index 00000000000..d943b17bf26 --- /dev/null +++ b/ports/zephyr-cp/boards/renesas/ek_ra6m5/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Renesas Electronics Corporation RA6M5 Evaluation Kit" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/renesas/ek_ra6m5/circuitpython.toml b/ports/zephyr-cp/boards/renesas/ek_ra6m5/circuitpython.toml new file mode 100644 index 00000000000..13ff40aa042 --- /dev/null +++ b/ports/zephyr-cp/boards/renesas/ek_ra6m5/circuitpython.toml @@ -0,0 +1,3 @@ +# TX is on pin P411. RX is on pin P410. + +CIRCUITPY_BUILD_EXTENSIONS = ["elf"] diff --git a/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml new file mode 100644 index 00000000000..2291d43c4a1 --- /dev/null +++ b/ports/zephyr-cp/boards/renesas/ek_ra8d1/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "Renesas Electronics Corporation RA8D1 Evaluation Kit" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has displayio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = true # Zephyr board has zephyr_display +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/renesas/ek_ra8d1/circuitpython.toml b/ports/zephyr-cp/boards/renesas/ek_ra8d1/circuitpython.toml new file mode 100644 index 00000000000..0e19d8d7157 --- /dev/null +++ b/ports/zephyr-cp/boards/renesas/ek_ra8d1/circuitpython.toml @@ -0,0 +1,2 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["elf"] +SHIELDS = ["rtkmipilcdb00000be"] diff --git a/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33.overlay b/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33.overlay new file mode 100644 index 00000000000..ca0400b6645 --- /dev/null +++ b/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33.overlay @@ -0,0 +1,33 @@ +&flash0 { + partitions { + #address-cells = <1>; + #size-cells = <1>; + + code_partition: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "code-partition"; + reg = <0x0 0x180000>; + read-only; + }; + + nvm_partition: partition@180000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x180000 0x800>; + }; + + storage_partition: partition@180800 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x180800 0x800>; + }; + + circuitpy_partition: partition@181000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x181000 (DT_SIZE_M(4) - 0x181000)>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33_w.conf b/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33_w.conf new file mode 100644 index 00000000000..8fcc1c0b9ae --- /dev/null +++ b/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33_w.conf @@ -0,0 +1,20 @@ +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_NET_SOCKETS=y + +CONFIG_WIFI=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_LEGACY_CRYPTO=n +CONFIG_NET_L2_WIFI_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_NET_MGMT_EVENT_INFO=y + +CONFIG_NET_HOSTNAME_ENABLE=y +CONFIG_NET_HOSTNAME_DYNAMIC=y +CONFIG_NET_HOSTNAME="circuitpython" + +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +CONFIG_MBEDTLS_CIPHERSUITE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256=y +CONFIG_MBEDTLS_ENTROPY_C=y +CONFIG_MBEDTLS_CTR_DRBG_C=y diff --git a/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33_w.overlay b/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33_w.overlay new file mode 100644 index 00000000000..ca0400b6645 --- /dev/null +++ b/ports/zephyr-cp/boards/rpi_pico2_rp2350a_m33_w.overlay @@ -0,0 +1,33 @@ +&flash0 { + partitions { + #address-cells = <1>; + #size-cells = <1>; + + code_partition: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "code-partition"; + reg = <0x0 0x180000>; + read-only; + }; + + nvm_partition: partition@180000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x180000 0x800>; + }; + + storage_partition: partition@180800 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x180800 0x800>; + }; + + circuitpy_partition: partition@181000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x181000 (DT_SIZE_M(4) - 0x181000)>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/rpi_pico_rp2040.overlay b/ports/zephyr-cp/boards/rpi_pico_rp2040.overlay new file mode 100644 index 00000000000..1cdd4ca2033 --- /dev/null +++ b/ports/zephyr-cp/boards/rpi_pico_rp2040.overlay @@ -0,0 +1,43 @@ +&flash0 { + /delete-node/ partitions; + + partitions { + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + code_partition: partition@100 { + compatible = "zephyr,mapped-partition"; + label = "code-partition"; + reg = <0x100 (0x180000 - 0x100)>; + read-only; + }; + + nvm_partition: partition@180000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x180000 0x800>; + }; + + storage_partition: partition@180800 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x180800 0x800>; + }; + + circuitpy_partition: partition@181000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x181000 (DT_SIZE_M(2) - 0x181000)>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/rpi_pico_rp2040_w.conf b/ports/zephyr-cp/boards/rpi_pico_rp2040_w.conf new file mode 100644 index 00000000000..1e2d7ae1cd2 --- /dev/null +++ b/ports/zephyr-cp/boards/rpi_pico_rp2040_w.conf @@ -0,0 +1,22 @@ +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +CONFIG_NET_DHCPV4=y +CONFIG_NET_SOCKETS=y + +CONFIG_WIFI=y +CONFIG_WIFI_NM_WPA_SUPPLICANT_LEGACY_CRYPTO=n +CONFIG_NET_L2_WIFI_MGMT=y +CONFIG_NET_MGMT_EVENT=y +CONFIG_NET_MGMT_EVENT_INFO=y + +CONFIG_NET_HOSTNAME_ENABLE=y +CONFIG_NET_HOSTNAME_DYNAMIC=y +CONFIG_NET_HOSTNAME="circuitpython" + +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y +CONFIG_MBEDTLS_CIPHERSUITE_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256=y +CONFIG_MBEDTLS_ENTROPY_C=y +CONFIG_MBEDTLS_CTR_DRBG_C=y + +CONFIG_TEST_RANDOM_GENERATOR=y diff --git a/ports/zephyr-cp/boards/rpi_pico_rp2040_w.overlay b/ports/zephyr-cp/boards/rpi_pico_rp2040_w.overlay new file mode 100644 index 00000000000..1cdd4ca2033 --- /dev/null +++ b/ports/zephyr-cp/boards/rpi_pico_rp2040_w.overlay @@ -0,0 +1,43 @@ +&flash0 { + /delete-node/ partitions; + + partitions { + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for the second stage bootloader */ + second_stage_bootloader: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "second_stage_bootloader"; + reg = <0x00000000 0x100>; + read-only; + }; + + code_partition: partition@100 { + compatible = "zephyr,mapped-partition"; + label = "code-partition"; + reg = <0x100 (0x180000 - 0x100)>; + read-only; + }; + + nvm_partition: partition@180000 { + compatible = "zephyr,mapped-partition"; + label = "nvm"; + reg = <0x180000 0x800>; + }; + + storage_partition: partition@180800 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x180800 0x800>; + }; + + circuitpy_partition: partition@181000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x181000 (DT_SIZE_M(2) - 0x181000)>; + }; + }; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml new file mode 100644 index 00000000000..9ee6085d189 --- /dev/null +++ b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "STMicroelectronics Nucleo N657X0-Q" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/st/nucleo_n657x0_q/circuitpython.toml b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/circuitpython.toml new file mode 100644 index 00000000000..83e6bcd39c4 --- /dev/null +++ b/ports/zephyr-cp/boards/st/nucleo_n657x0_q/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] diff --git a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml new file mode 100644 index 00000000000..59a15de0232 --- /dev/null +++ b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "STMicroelectronics Nucleo U575ZI Q" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/st/nucleo_u575zi_q/circuitpython.toml b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/circuitpython.toml new file mode 100644 index 00000000000..3ca45dd798b --- /dev/null +++ b/ports/zephyr-cp/boards/st/nucleo_u575zi_q/circuitpython.toml @@ -0,0 +1,3 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] +USB_VID=0x239A +USB_PID=0x816A diff --git a/ports/zephyr-cp/boards/st/stm32h750b_dk/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32h750b_dk/autogen_board_info.toml new file mode 100644 index 00000000000..3f83a46ec58 --- /dev/null +++ b/ports/zephyr-cp/boards/st/stm32h750b_dk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "STMicroelectronics STM32H750B Discovery Kit" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has displayio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = false +usb_hid = false +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = true # Zephyr board has zephyr_display +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/st/stm32h750b_dk/circuitpython.toml b/ports/zephyr-cp/boards/st/stm32h750b_dk/circuitpython.toml new file mode 100644 index 00000000000..83e6bcd39c4 --- /dev/null +++ b/ports/zephyr-cp/boards/st/stm32h750b_dk/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] diff --git a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml new file mode 100644 index 00000000000..63fac014f17 --- /dev/null +++ b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "STMicroelectronics STM32H7B3I Discovery kit" + +[modules] +__future__ = true +_bleio = false +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has displayio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true # Zephyr board has flash +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = true # Zephyr board has zephyr_display +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/st/stm32h7b3i_dk/circuitpython.toml b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/circuitpython.toml new file mode 100644 index 00000000000..83e6bcd39c4 --- /dev/null +++ b/ports/zephyr-cp/boards/st/stm32h7b3i_dk/circuitpython.toml @@ -0,0 +1 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] diff --git a/ports/zephyr-cp/boards/st/stm32wba65i_dk1/autogen_board_info.toml b/ports/zephyr-cp/boards/st/stm32wba65i_dk1/autogen_board_info.toml new file mode 100644 index 00000000000..10c7a39b60a --- /dev/null +++ b/ports/zephyr-cp/boards/st/stm32wba65i_dk1/autogen_board_info.toml @@ -0,0 +1,129 @@ +# This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info. +name = "STMicroelectronics STM32WBA65I Discovery kit" + +[modules] +__future__ = true +_bleio = true # Zephyr board has _bleio +_eve = false +_pew = false +_pixelmap = false +_stage = false +adafruit_bus_device = true +adafruit_pixelbuf = false +aesio = true +alarm = false +analogbufio = false +analogio = false +atexit = false +audiobusio = false +audiocore = false +audiodelays = false +audiofilewriter = false +audiofilters = false +audiofreeverb = false +audioi2sin = false +audioio = false +audiomixer = false +audiomp3 = false +audiopwmio = false +audiospeed = false +aurora_epaper = false +bitbangio = false +bitmapfilter = true # Zephyr board has busio +bitmaptools = true # Zephyr board has busio +bitops = false +board = false +busdisplay = true # Zephyr board has busio +busio = true # Zephyr board has busio +camera = false +canio = false +codeop = false +countio = false +digitalio = true +displayio = true # Zephyr board has busio +dotclockframebuffer = false +dualbank = false +epaperdisplay = true # Zephyr board has busio +floppyio = false +fontio = true # Zephyr board has busio +fourwire = true # Zephyr board has busio +framebufferio = true # Zephyr board has busio +frequencyio = false +getpass = true +gifio = true # Zephyr board has busio +gnss = false +hashlib = true +hostnetwork = false +i2cdisplaybus = true # Zephyr board has busio +i2cioexpander = false +i2ctarget = false +imagecapture = false +ipaddress = false +is31fl3741 = false +jpegio = true # Zephyr board has busio +keypad = false +keypad_demux = false +locale = false +lvfontio = true # Zephyr board has busio +math = true +max3421e = false +mcp4822 = false +mdns = false +memorymap = false +memorymonitor = false +microcontroller = true +mipidsi = false +msgpack = true +neopixel_write = false +nvm = false +onewireio = false +os = true +paralleldisplaybus = false +ps2io = false +pulseio = false +pwmio = false +qrio = false +qspibus = false +rainbowio = true +random = true +rclcpy = false +rgbmatrix = false +rotaryio = true # Zephyr board has rotaryio +rtc = false +sdcardio = true # Zephyr board has busio +sdioio = false +sharpdisplay = true # Zephyr board has busio +socketpool = false +spitarget = false +ssl = false +storage = true +struct = true +supervisor = true +synthio = false +terminalio = true # Zephyr board has busio +tilepalettemapper = true # Zephyr board has busio +time = true +touchio = false +traceback = true +uheap = false +usb = false +usb_audio = false +usb_cdc = true +usb_hid = true +usb_host = false +usb_midi = false +usb_video = false +ustack = false +vectorio = true # Zephyr board has busio +warnings = true +watchdog = false +wifi = false +zephyr_display = false +zephyr_kernel = false +zlib = true +# extmod modules shared with MicroPython +asyncio = true +binascii = true +json = true +re = true +select = true diff --git a/ports/zephyr-cp/boards/st/stm32wba65i_dk1/circuitpython.toml b/ports/zephyr-cp/boards/st/stm32wba65i_dk1/circuitpython.toml new file mode 100644 index 00000000000..fb3dfea6867 --- /dev/null +++ b/ports/zephyr-cp/boards/st/stm32wba65i_dk1/circuitpython.toml @@ -0,0 +1,2 @@ +CIRCUITPY_BUILD_EXTENSIONS = ["hex"] +BLOBS=["hal_stm32"] diff --git a/ports/zephyr-cp/boards/stm32h750b_dk_stm32h750xx_ext_flash_app.conf b/ports/zephyr-cp/boards/stm32h750b_dk_stm32h750xx_ext_flash_app.conf new file mode 100644 index 00000000000..24afffb8e88 --- /dev/null +++ b/ports/zephyr-cp/boards/stm32h750b_dk_stm32h750xx_ext_flash_app.conf @@ -0,0 +1,2 @@ +# Enable Zephyr display subsystem so the built-in LTDC panel is available. +CONFIG_DISPLAY=y diff --git a/ports/zephyr-cp/boards/stm32h750b_dk_stm32h750xx_ext_flash_app.overlay b/ports/zephyr-cp/boards/stm32h750b_dk_stm32h750xx_ext_flash_app.overlay new file mode 100644 index 00000000000..7e038bb77aa --- /dev/null +++ b/ports/zephyr-cp/boards/stm32h750b_dk_stm32h750xx_ext_flash_app.overlay @@ -0,0 +1,21 @@ +&ext_flash { + partitions { + /delete-node/ partition@7800000; + + storage_partition: partition@7800000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x7800000 DT_SIZE_K(32)>; + }; + + circuitpy_partition: partition@7808000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x7808000 (DT_SIZE_M(8) - DT_SIZE_K(32))>; + }; + }; +}; + +&rng { + status = "okay"; +}; diff --git a/ports/zephyr-cp/boards/stm32h7b3i_dk.conf b/ports/zephyr-cp/boards/stm32h7b3i_dk.conf new file mode 100644 index 00000000000..24afffb8e88 --- /dev/null +++ b/ports/zephyr-cp/boards/stm32h7b3i_dk.conf @@ -0,0 +1,2 @@ +# Enable Zephyr display subsystem so the built-in LTDC panel is available. +CONFIG_DISPLAY=y diff --git a/ports/zephyr-cp/boards/stm32h7b3i_dk.overlay b/ports/zephyr-cp/boards/stm32h7b3i_dk.overlay new file mode 100644 index 00000000000..d871e728e0d --- /dev/null +++ b/ports/zephyr-cp/boards/stm32h7b3i_dk.overlay @@ -0,0 +1,45 @@ +&mx25lm51245 { + /delete-node/ partitions; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + storage_partition: partition@0 { + label = "storage"; + reg = <0x00000000 DT_SIZE_K(32)>; + }; + + circuitpy_partition: partition@8000 { + label = "circuitpy"; + reg = <0x00008000 (DT_SIZE_M(64) - DT_SIZE_K(32))>; + }; + }; +}; + +&sram5 { + status = "disabled"; +}; + +&rng { + status = "okay"; +}; + +&fdcan1 { + status = "disabled"; +}; + +/ { + chosen { + /delete-property/ zephyr,canbus; + }; +}; + +zephyr_udc0: &usbotg_hs { + pinctrl-0 = <&usb_otg_hs_dm_pa11 &usb_otg_hs_dp_pa12>; + pinctrl-names = "default"; + status = "okay"; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/boards/stm32wba65i_dk1.conf b/ports/zephyr-cp/boards/stm32wba65i_dk1.conf new file mode 100644 index 00000000000..d83be8dddb5 --- /dev/null +++ b/ports/zephyr-cp/boards/stm32wba65i_dk1.conf @@ -0,0 +1,10 @@ +# USB OTG on STM32WBA requires VOS Range 1. Keep HCLK > 16 MHz. +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=32000000 + +# Bluetooth doesn't start up for some reason. +# CONFIG_BT=y +# CONFIG_BT_PERIPHERAL=y +# CONFIG_BT_CENTRAL=y + +# Board-specific BT calibration +CONFIG_BT_STM32WBA_USE_TEMP_BASED_CALIB=n diff --git a/ports/zephyr-cp/boards/stm32wba65i_dk1.overlay b/ports/zephyr-cp/boards/stm32wba65i_dk1.overlay new file mode 100644 index 00000000000..25ef6321eab --- /dev/null +++ b/ports/zephyr-cp/boards/stm32wba65i_dk1.overlay @@ -0,0 +1,76 @@ +&flash0 { + /delete-node/ partitions; + + partitions { + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + compatible = "zephyr,mapped-partition"; + label = "mcuboot"; + reg = <0x00000000 DT_SIZE_K(64)>; + }; + + slot0_partition: partition@10000 { + compatible = "zephyr,mapped-partition"; + label = "image-0"; + reg = <0x00010000 DT_SIZE_K(928)>; + }; + + storage_partition: partition@f80000 { + compatible = "zephyr,mapped-partition"; + label = "storage"; + reg = <0x001e0000 DT_SIZE_K(64)>; + }; + + circuitpy_partition: partition@108000 { + compatible = "zephyr,mapped-partition"; + label = "circuitpy"; + reg = <0x00108000 DT_SIZE_K(992)>; + }; + }; +}; + +&rng { + status = "okay"; +}; + +/* + * USB on STM32WBA requires VOS Range 1. Zephyr selects VOS from HCLK, and + * 16 MHz keeps it in Range 2, which trips an assertion in udc_stm32. + * Run SYSCLK from full 32 MHz HSE so VOS is set to Range 1. + */ +&clk_hse { + /delete-property/ hse-div2; +}; + +&rcc { + clock-frequency = ; + ahb5-prescaler = <1>; +}; + +zephyr_udc0: &usbotg_hs { + status = "okay"; +}; + +&otghs_phy { + /* OTG HS clock source is 32 MHz HSE */ + clocks = <&rcc STM32_CLOCK(AHB2, 15)>, + <&rcc STM32_SRC_HSE OTGHS_SEL(0)>; + clock-reference = "SYSCFG_OTG_HS_PHY_CLK_32MHz"; + status = "okay"; +}; + +&bt_hci_wba { + /* Use HASH IRQ to allocate Radio SW Low Process (Warning HASH is not used) */ + interrupts = <66 0>, <61 14>; + interrupt-names = "radio", "radio-sw-low"; +}; + +&ieee802154 { + /* Use HASH IRQ to allocate Radio SW Low Process (Warning HASH is not used) */ + interrupts = <66 0>, <61 14>; + interrupt-names = "radio", "radio-sw-low"; +}; + +#include "../app.overlay" diff --git a/ports/zephyr-cp/common-hal/_bleio/Adapter.c b/ports/zephyr-cp/common-hal/_bleio/Adapter.c new file mode 100644 index 00000000000..ac2b1948eb7 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Adapter.c @@ -0,0 +1,755 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "py/gc.h" +#include "py/runtime.h" +#include "bindings/zephyr_kernel/__init__.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "shared-bindings/_bleio/Address.h" +#include "shared-module/_bleio/Address.h" +#include "shared-module/_bleio/ScanResults.h" +#include "supervisor/shared/tick.h" + +bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; + +static bool scan_callbacks_registered = false; +static bleio_scanresults_obj_t *active_scan_results = NULL; +static struct bt_le_scan_cb scan_callbacks; +static bool ble_advertising = false; +static bool ble_adapter_enabled = true; + +#define BLEIO_ADV_MAX_FIELDS 16 +#define BLEIO_ADV_MAX_DATA_LEN 31 +static struct bt_data adv_data[BLEIO_ADV_MAX_FIELDS]; +static struct bt_data scan_resp_data[BLEIO_ADV_MAX_FIELDS]; +static uint8_t adv_data_storage[BLEIO_ADV_MAX_DATA_LEN]; +static uint8_t scan_resp_storage[BLEIO_ADV_MAX_DATA_LEN]; + +static uint8_t bleio_address_type_from_zephyr(const bt_addr_le_t *addr) { + if (addr == NULL) { + return BLEIO_ADDRESS_TYPE_PUBLIC; + } + + switch (addr->type) { + case BT_ADDR_LE_PUBLIC: + case BT_ADDR_LE_PUBLIC_ID: + return BLEIO_ADDRESS_TYPE_PUBLIC; + case BT_ADDR_LE_RANDOM: + case BT_ADDR_LE_RANDOM_ID: + case BT_ADDR_LE_UNRESOLVED: + if (BT_ADDR_IS_RPA(&addr->a)) { + return BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_RESOLVABLE; + } + if (BT_ADDR_IS_NRPA(&addr->a)) { + return BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE; + } + return BLEIO_ADDRESS_TYPE_RANDOM_STATIC; + default: + return BLEIO_ADDRESS_TYPE_PUBLIC; + } +} + +static uint8_t bleio_address_type_to_zephyr(uint8_t type) { + switch (type) { + case BLEIO_ADDRESS_TYPE_PUBLIC: + return BT_ADDR_LE_PUBLIC; + case BLEIO_ADDRESS_TYPE_RANDOM_STATIC: + case BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_RESOLVABLE: + case BLEIO_ADDRESS_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE: + return BT_ADDR_LE_RANDOM; + default: + return BT_ADDR_LE_PUBLIC; + } +} + +static bleio_connection_internal_t *bleio_connection_find_by_conn(const struct bt_conn *conn) { + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + bleio_connection_internal_t *connection = &bleio_connections[i]; + if (connection->conn == conn) { + return connection; + } + } + + return NULL; +} + +static bleio_connection_internal_t *bleio_connection_track(struct bt_conn *conn) { + bleio_connection_internal_t *connection = bleio_connection_find_by_conn(conn); + if (connection == NULL) { + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + bleio_connection_internal_t *candidate = &bleio_connections[i]; + if (candidate->conn == NULL) { + connection = candidate; + break; + } + } + } + + if (connection == NULL) { + return NULL; + } + + if (connection->conn == NULL) { + connection->conn = bt_conn_ref(conn); + } + + return connection; +} + +static void bleio_connection_clear(bleio_connection_internal_t *self) { + if (self == NULL) { + return; + } + + if (self->conn != NULL) { + bt_conn_unref(self->conn); + self->conn = NULL; + } + + self->connection_obj = mp_const_none; + self->pair_status = PAIR_NOT_PAIRED; + self->sec_err = 0; +} + +static void bleio_connection_release(bleio_connection_internal_t *connection, uint8_t reason) { + if (connection == NULL) { + return; + } + + if (connection->connection_obj != mp_const_none) { + bleio_connection_obj_t *connection_obj = MP_OBJ_TO_PTR(connection->connection_obj); + connection_obj->connection = NULL; + connection_obj->disconnect_reason = reason; + } + + bleio_connection_clear(connection); + common_hal_bleio_adapter_obj.connection_objs = NULL; +} + +static void bleio_connected_cb(struct bt_conn *conn, uint8_t err) { + if (err != 0) { + return; + } + + if (bleio_connection_track(conn) == NULL) { + bt_conn_disconnect(conn, BT_HCI_ERR_CONN_LIMIT_EXCEEDED); + return; + } + + // When connectable advertising results in a connection, the controller + // auto-stops advertising. Clear our flag to match (we cannot call + // stop_advertising() here because this callback runs in Zephyr's BT + // thread context). + ble_advertising = false; + + common_hal_bleio_adapter_obj.connection_objs = NULL; +} + +static void bleio_disconnected_cb(struct bt_conn *conn, uint8_t reason) { + bleio_connection_release(bleio_connection_find_by_conn(conn), reason); +} + +static void bleio_security_changed_cb(struct bt_conn *conn, bt_security_t level, + enum bt_security_err err) { + bleio_connection_internal_t *connection = bleio_connection_find_by_conn(conn); + if (connection == NULL) { + return; + } + + if (err == BT_SECURITY_ERR_SUCCESS && level > BT_SECURITY_L1) { + // Security was established (encryption enabled). + // This happens both on first-time pairing and when reconnecting + // with stored bond keys. + connection->pair_status = PAIR_PAIRED; + } else if (err != BT_SECURITY_ERR_SUCCESS) { + connection->pair_status = PAIR_NOT_PAIRED; + connection->sec_err = (uint8_t)err; + } +} + +BT_CONN_CB_DEFINE(bleio_connection_callbacks) = { + .connected = bleio_connected_cb, + .disconnected = bleio_disconnected_cb, + .security_changed = bleio_security_changed_cb, +}; + +static void scan_recv_cb(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf) { + if (active_scan_results == NULL || info == NULL || buf == NULL) { + return; + } + + const bool connectable = (info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) != 0; + const bool scan_response = (info->adv_props & BT_GAP_ADV_PROP_SCAN_RESPONSE) != 0; + const bt_addr_le_t *addr = info->addr; + + uint8_t addr_bytes[NUM_BLEIO_ADDRESS_BYTES] = {0}; + if (addr != NULL) { + memcpy(addr_bytes, addr->a.val, sizeof(addr_bytes)); + } + + shared_module_bleio_scanresults_append(active_scan_results, + supervisor_ticks_ms64(), + connectable, + scan_response, + info->rssi, + addr_bytes, + bleio_address_type_from_zephyr(addr), + buf->data, + buf->len); +} + +static void scan_timeout_cb(void) { + if (active_scan_results == NULL) { + return; + } + shared_module_bleio_scanresults_set_done(active_scan_results, true); + active_scan_results = NULL; +} + +// We need to disassemble the full advertisement packet because the Zephyr takes +// in each ADT in an array. +static size_t bleio_parse_adv_data(const uint8_t *raw, size_t raw_len, struct bt_data *out, + size_t out_len, uint8_t *storage, size_t storage_len) { + size_t count = 0; + size_t offset = 0; + size_t storage_offset = 0; + + while (offset < raw_len) { + uint8_t field_len = raw[offset]; + if (field_len == 0) { + offset++; + continue; + } + uint8_t data_len = field_len - 1; + if (offset + field_len + 1 > raw_len || + count >= out_len || + storage_offset + data_len > storage_len) { + mp_raise_ValueError(MP_ERROR_TEXT("Invalid advertising data")); + } + uint8_t type = raw[offset + 1]; + memcpy(storage + storage_offset, raw + offset + 2, data_len); + out[count].type = type; + out[count].data_len = data_len; + out[count].data = storage + storage_offset; + storage_offset += data_len; + count++; + offset += field_len + 1; + } + + return count; +} + +static uint16_t bleio_validate_and_convert_timeout(mp_float_t timeout) { + mp_arg_validate_float_range(timeout, 0, UINT16_MAX, MP_QSTR_timeout); + + if (timeout <= 0.0f) { + return 0; + } + + const mp_int_t timeout_units = + mp_arg_validate_int_range((mp_int_t)(timeout * 100.0f + 0.5f), 1, UINT16_MAX, MP_QSTR_timeout); + + return (uint16_t)timeout_units; +} + +void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enabled) { + if (enabled == ble_adapter_enabled) { + return; + } + if (enabled) { + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + bleio_connection_clear(&bleio_connections[i]); + } + if (!bt_is_ready()) { + int err = bt_enable(NULL); + if (err != 0 && err != -EALREADY) { + raise_zephyr_error(err); + } + + // bt_init() returns early without setting BT_DEV_READY when + // CONFIG_BT_SETTINGS=y and no identity is loaded yet. + // Load settings so the BT settings handler fires and calls + // bt_finalize_init() which sets BT_DEV_READY. + settings_load(); + } + ble_adapter_enabled = true; + return; + } + + // On Zephyr bsim + HCI IPC, disabling and immediately re-enabling BLE can + // race endpoint rebinding during soft reload. Keep the controller running, + // but present adapter.enabled=False to CircuitPython code. + common_hal_bleio_adapter_stop_scan(self); + common_hal_bleio_adapter_stop_advertising(self); + ble_adapter_enabled = false; +} + +bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) { + return ble_adapter_enabled; +} + +mp_int_t common_hal_bleio_adapter_get_tx_power(bleio_adapter_obj_t *self) { + struct bt_hci_cp_vs_read_tx_power_level *cp; + struct bt_hci_rp_vs_read_tx_power_level *rp; + struct net_buf *buf, *rsp = NULL; + + buf = bt_hci_cmd_alloc(K_MSEC(1000)); + if (!buf) { + mp_raise_msg(&mp_type_MemoryError, NULL); + } + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle_type = BT_HCI_VS_LL_HANDLE_TYPE_ADV; + cp->handle = 0; + + int err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_READ_TX_POWER_LEVEL, buf, &rsp); + if (err) { + raise_zephyr_error(err); + } + + rp = (void *)rsp->data; + int8_t power = rp->tx_power_level; + net_buf_unref(rsp); + return power; +} + +void common_hal_bleio_adapter_set_tx_power(bleio_adapter_obj_t *self, mp_int_t tx_power) { + struct bt_hci_cp_vs_write_tx_power_level *cp; + struct net_buf *buf, *rsp = NULL; + + buf = bt_hci_cmd_alloc(K_MSEC(3000)); + if (!buf) { + mp_raise_msg(&mp_type_MemoryError, NULL); + } + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle_type = BT_HCI_VS_LL_HANDLE_TYPE_ADV; + cp->handle = 0; + cp->tx_power_level = (int8_t)tx_power; + + int err = bt_hci_cmd_send_sync(BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL, buf, &rsp); + if (err) { + raise_zephyr_error(err); + } + + net_buf_unref(rsp); +} + +bleio_address_obj_t *common_hal_bleio_adapter_get_address(bleio_adapter_obj_t *self) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_bleio_adapter_set_address(bleio_adapter_obj_t *self, bleio_address_obj_t *address) { + mp_raise_NotImplementedError(NULL); +} + +mp_obj_str_t *common_hal_bleio_adapter_get_name(bleio_adapter_obj_t *self) { + (void)self; + const char *name = bt_get_name(); + return mp_obj_new_str(name, strlen(name)); +} + +void common_hal_bleio_adapter_set_name(bleio_adapter_obj_t *self, const char *name) { + (void)self; + size_t len = strlen(name); + int err = 0; + if (len > CONFIG_BT_DEVICE_NAME_MAX) { + char truncated[CONFIG_BT_DEVICE_NAME_MAX + 1]; + memcpy(truncated, name, CONFIG_BT_DEVICE_NAME_MAX); + truncated[CONFIG_BT_DEVICE_NAME_MAX] = '\0'; + err = bt_set_name(truncated); + } else { + err = bt_set_name(name); + } + if (err != 0) { + raise_zephyr_error(err); + } +} + +void common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self, + bool connectable, bool anonymous, uint32_t timeout, mp_float_t interval, + mp_buffer_info_t *advertising_data_bufinfo, + mp_buffer_info_t *scan_response_data_bufinfo, + mp_int_t tx_power, const bleio_address_obj_t *directed_to) { + (void)directed_to; + (void)interval; + + if (advertising_data_bufinfo->len > BLEIO_ADV_MAX_DATA_LEN || + scan_response_data_bufinfo->len > BLEIO_ADV_MAX_DATA_LEN) { + mp_raise_NotImplementedError(NULL); + } + + if (timeout != 0) { + mp_raise_NotImplementedError(NULL); + } + + if (ble_advertising) { + raise_zephyr_error(-EALREADY); + } + + bt_addr_le_t id_addrs[CONFIG_BT_ID_MAX]; + size_t id_count = CONFIG_BT_ID_MAX; + bt_id_get(id_addrs, &id_count); + if (id_count == 0 || bt_addr_le_eq(&id_addrs[BT_ID_DEFAULT], BT_ADDR_LE_ANY)) { + int id = bt_id_create(NULL, NULL); + if (id < 0) { + printk("Failed to create identity address: %d\n", id); + raise_zephyr_error(id); + } + } + + size_t adv_count = bleio_parse_adv_data(advertising_data_bufinfo->buf, + advertising_data_bufinfo->len, + adv_data, + BLEIO_ADV_MAX_FIELDS, + adv_data_storage, + sizeof(adv_data_storage)); + + size_t scan_resp_count = 0; + if (scan_response_data_bufinfo->len > 0) { + scan_resp_count = bleio_parse_adv_data(scan_response_data_bufinfo->buf, + scan_response_data_bufinfo->len, + scan_resp_data, + BLEIO_ADV_MAX_FIELDS, + scan_resp_storage, + sizeof(scan_resp_storage)); + } + + if (anonymous) { + mp_raise_NotImplementedError(NULL); + } + + struct bt_le_adv_param adv_params; + if (connectable) { + adv_params = (struct bt_le_adv_param)BT_LE_ADV_PARAM_INIT( + BT_LE_ADV_OPT_CONN, + BT_GAP_ADV_FAST_INT_MIN_1, + BT_GAP_ADV_FAST_INT_MAX_1, + NULL); + } else if (scan_resp_count > 0) { + adv_params = (struct bt_le_adv_param)BT_LE_ADV_PARAM_INIT( + BT_LE_ADV_OPT_SCANNABLE, + BT_GAP_ADV_FAST_INT_MIN_2, + BT_GAP_ADV_FAST_INT_MAX_2, + NULL); + } else { + adv_params = (struct bt_le_adv_param)BT_LE_ADV_PARAM_INIT( + 0, + BT_GAP_ADV_FAST_INT_MIN_2, + BT_GAP_ADV_FAST_INT_MAX_2, + NULL); + } + + common_hal_bleio_adapter_set_tx_power(self, tx_power); + + raise_zephyr_error(bt_le_adv_start(&adv_params, + adv_data, + adv_count, + scan_resp_count > 0 ? scan_resp_data : NULL, + scan_resp_count)); + + ble_advertising = true; +} + +void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) { + (void)self; + if (!ble_advertising) { + return; + } + bt_le_adv_stop(); + ble_advertising = false; +} + +bool common_hal_bleio_adapter_get_advertising(bleio_adapter_obj_t *self) { + (void)self; + return ble_advertising; +} + +mp_obj_t common_hal_bleio_adapter_start_scan(bleio_adapter_obj_t *self, uint8_t *prefixes, size_t prefix_length, bool extended, mp_int_t buffer_size, mp_float_t timeout, mp_float_t interval, mp_float_t window, mp_int_t minimum_rssi, bool active) { + (void)extended; + + if (self->scan_results != NULL) { + if (!shared_module_bleio_scanresults_get_done(self->scan_results)) { + common_hal_bleio_adapter_stop_scan(self); + } else { + self->scan_results = NULL; + } + } + + int err = 0; + + self->scan_results = shared_module_bleio_new_scanresults(buffer_size, prefixes, prefix_length, minimum_rssi); + active_scan_results = self->scan_results; + + if (!scan_callbacks_registered) { + scan_callbacks.recv = scan_recv_cb; + scan_callbacks.timeout = scan_timeout_cb; + err = bt_le_scan_cb_register(&scan_callbacks); + if (err != 0) { + self->scan_results = NULL; + active_scan_results = NULL; + raise_zephyr_error(err); + } + scan_callbacks_registered = true; + } + + uint16_t interval_units = (uint16_t)((interval / 0.000625f) + 0.5f); + uint16_t window_units = (uint16_t)((window / 0.000625f) + 0.5f); + uint16_t timeout_units = bleio_validate_and_convert_timeout(timeout); + + struct bt_le_scan_param scan_params = { + .type = active ? BT_LE_SCAN_TYPE_ACTIVE : BT_LE_SCAN_TYPE_PASSIVE, + .options = BT_LE_SCAN_OPT_FILTER_DUPLICATE, + .interval = interval_units, + .window = window_units, + .timeout = (uint16_t)timeout_units, + .interval_coded = 0, + .window_coded = 0, + }; + + err = bt_le_scan_start(&scan_params, NULL); + if (err != 0) { + self->scan_results = NULL; + active_scan_results = NULL; + raise_zephyr_error(err); + } + + return MP_OBJ_FROM_PTR(self->scan_results); +} + +void common_hal_bleio_adapter_stop_scan(bleio_adapter_obj_t *self) { + if (self->scan_results == NULL) { + return; + } + bt_le_scan_stop(); + shared_module_bleio_scanresults_set_done(self->scan_results, true); + active_scan_results = NULL; + self->scan_results = NULL; +} + +bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) { + if (!ble_adapter_enabled) { + return false; + } + + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + if (bleio_connections[i].conn != NULL) { + return true; + } + } + + return false; +} + +mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) { + if (!ble_adapter_enabled) { + self->connection_objs = NULL; + return mp_const_empty_tuple; + } + + if (self->connection_objs != NULL) { + return self->connection_objs; + } + + size_t total_connected = 0; + mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT]; + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + bleio_connection_internal_t *connection = &bleio_connections[i]; + if (connection->conn == NULL) { + continue; + } + + if (connection->connection_obj == mp_const_none) { + connection->connection_obj = bleio_connection_new_from_internal(connection); + } + + items[total_connected] = connection->connection_obj; + total_connected++; + } + + self->connection_objs = mp_obj_new_tuple(total_connected, items); + return self->connection_objs; +} + +mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_address_obj_t *address, mp_float_t timeout) { + common_hal_bleio_adapter_stop_scan(self); + + const uint16_t timeout_units = bleio_validate_and_convert_timeout(timeout); + + mp_buffer_info_t address_bufinfo; + mp_get_buffer_raise(address->bytes, &address_bufinfo, MP_BUFFER_READ); + + bt_addr_le_t peer = { + .type = bleio_address_type_to_zephyr(address->type), + }; + memcpy(peer.a.val, address_bufinfo.buf, NUM_BLEIO_ADDRESS_BYTES); + + struct bt_conn_le_create_param create_params = BT_CONN_LE_CREATE_PARAM_INIT( + BT_CONN_LE_OPT_NONE, + BT_GAP_SCAN_FAST_INTERVAL, + BT_GAP_SCAN_FAST_INTERVAL); + create_params.timeout = timeout_units; + + struct bt_conn *conn = NULL; + int err = bt_conn_le_create(&peer, &create_params, BT_LE_CONN_PARAM_DEFAULT, &conn); + if (err != 0) { + raise_zephyr_error(err); + } + + while (true) { + struct bt_conn_info info; + err = bt_conn_get_info(conn, &info); + if (err == 0) { + if (info.state == BT_CONN_STATE_CONNECTED) { + break; + } + + if (info.state == BT_CONN_STATE_DISCONNECTED) { + bt_conn_unref(conn); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Failed to connect: timeout")); + } + } else if (err != -ENOTCONN) { + bt_conn_unref(conn); + raise_zephyr_error(err); + } + + RUN_BACKGROUND_TASKS; + } + + bleio_connection_internal_t *connection = bleio_connection_find_by_conn(conn); + if (connection == NULL) { + connection = bleio_connection_track(conn); + } + + if (connection == NULL) { + bt_conn_unref(conn); + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Failed to connect: internal error")); + } + + // bt_conn_le_create() gave us a ref in `conn`; `connection` keeps its own + // ref via bleio_connection_track(). Drop the create ref now. + bt_conn_unref(conn); + + self->connection_objs = NULL; + return bleio_connection_new_from_internal(connection); +} + +struct bond_collect_ctx { + bt_addr_le_t *addrs; + size_t *count; + size_t max; +}; + +static void bond_iterator_collect(const struct bt_bond_info *info, void *user_data) { + struct bond_collect_ctx *ctx = (struct bond_collect_ctx *)user_data; + if (*ctx->count < ctx->max) { + bt_addr_le_copy(&ctx->addrs[*ctx->count], &info->addr); + (*ctx->count)++; + } +} + +static void bond_iterator_check(const struct bt_bond_info *info, void *user_data) { + (void)info; + bool *has_bonds = (bool *)user_data; + *has_bonds = true; +} + +void common_hal_bleio_adapter_erase_bonding(bleio_adapter_obj_t *self) { + // Unpair all bonded devices for all local identities. + for (uint8_t id = 0; id < CONFIG_BT_ID_MAX; id++) { + // bt_unpair takes an addr; use bt_foreach_bond to iterate and unpair. + // We need to collect addresses first since we can't unpair during iteration. + bt_addr_le_t addrs[CONFIG_BT_MAX_PAIRED]; + size_t addr_count = 0; + + bt_foreach_bond(id, bond_iterator_collect, &(struct bond_collect_ctx) { + .addrs = addrs, + .count = &addr_count, + .max = CONFIG_BT_MAX_PAIRED + }); + + for (size_t i = 0; i < addr_count; i++) { + bt_unpair(id, &addrs[i]); + } + } + + // Reset pairing state on all connections + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + bleio_connections[i].pair_status = PAIR_NOT_PAIRED; + bleio_connections[i].sec_err = 0; + } +} + +bool common_hal_bleio_adapter_is_bonded_to_central(bleio_adapter_obj_t *self) { + // Check if any bond exists for identity 0 + for (uint8_t id = 0; id < CONFIG_BT_ID_MAX; id++) { + bool has_bonds = false; + bt_foreach_bond(id, bond_iterator_check, &has_bonds); + if (has_bonds) { + return true; + } + } + return false; +} + +void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter) { + gc_collect_root((void **)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t)); + gc_collect_root((void **)bleio_connections, sizeof(bleio_connections) / sizeof(size_t)); +} + +void bleio_adapter_reset(bleio_adapter_obj_t *adapter) { + if (adapter == NULL) { + return; + } + + common_hal_bleio_adapter_stop_scan(adapter); + common_hal_bleio_adapter_stop_advertising(adapter); + + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + bleio_connection_internal_t *connection = &bleio_connections[i]; + if (connection->conn != NULL) { + bt_conn_disconnect(connection->conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + } + if (connection->connection_obj != MP_OBJ_NULL && + connection->connection_obj != mp_const_none) { + bleio_connection_obj_t *connection_obj = MP_OBJ_TO_PTR(connection->connection_obj); + connection_obj->connection = NULL; + connection_obj->disconnect_reason = BT_HCI_ERR_REMOTE_USER_TERM_CONN; + } + bleio_connection_clear(connection); + } + + adapter->scan_results = NULL; + adapter->connection_objs = NULL; + active_scan_results = NULL; + ble_advertising = false; + ble_adapter_enabled = bt_is_ready(); +} + +bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void) { + return &common_hal_bleio_adapter_obj; +} + +uint16_t bleio_adapter_get_name(char *buf, uint16_t len) { + const char *name = bt_get_name(); + uint16_t full_len = strlen(name); + if (len > 0) { + uint16_t copy_len = len < full_len ? len : full_len; + memcpy(buf, name, copy_len); + } + return full_len; +} diff --git a/ports/zephyr-cp/common-hal/_bleio/Adapter.h b/ports/zephyr-cp/common-hal/_bleio/Adapter.h new file mode 100644 index 00000000000..c15c698e2a5 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Adapter.h @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "py/objtuple.h" + +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/ScanResults.h" + +#define BLEIO_TOTAL_CONNECTION_COUNT CONFIG_BT_MAX_CONN + +extern bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; + +typedef struct { + mp_obj_base_t base; + bleio_scanresults_obj_t *scan_results; + mp_obj_t name; + mp_obj_tuple_t *connection_objs; + bool user_advertising; +} bleio_adapter_obj_t; + +void bleio_adapter_gc_collect(bleio_adapter_obj_t *adapter); +void bleio_adapter_reset(bleio_adapter_obj_t *adapter); diff --git a/ports/zephyr-cp/common-hal/_bleio/Attribute.c b/ports/zephyr-cp/common-hal/_bleio/Attribute.c new file mode 100644 index 00000000000..6312f3d46b8 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Attribute.c @@ -0,0 +1,8 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Attribute is defined in shared-module, no port-specific implementation needed diff --git a/ports/zephyr-cp/common-hal/_bleio/Attribute.h b/ports/zephyr-cp/common-hal/_bleio/Attribute.h new file mode 100644 index 00000000000..24b0f78a106 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Attribute.h @@ -0,0 +1,10 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/_bleio/Attribute.h" diff --git a/ports/zephyr-cp/common-hal/_bleio/Characteristic.c b/ports/zephyr-cp/common-hal/_bleio/Characteristic.c new file mode 100644 index 00000000000..af315f9f6b0 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Characteristic.c @@ -0,0 +1,390 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include +#include +#include + +#include "py/runtime.h" +#include "bindings/zephyr_kernel/__init__.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" +#include "common-hal/_bleio/__init__.h" +#include "common-hal/_bleio/CharacteristicBuffer.h" +#include "common-hal/_bleio/Connection.h" +#include "common-hal/_bleio/UUID.h" +#include "common-hal/_bleio/PacketBuffer.h" +#include "shared-bindings/_bleio/CharacteristicBuffer.h" +#include "shared-bindings/_bleio/PacketBuffer.h" +#include "supervisor/port_heap.h" + +// CCCD write callback — captures the subscribing connection for PacketBuffer. +ssize_t bleio_ccc_write_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, uint16_t value) { + struct bt_gatt_ccc_managed_user_data *ccc_data = + (struct bt_gatt_ccc_managed_user_data *)attr->user_data; + bleio_characteristic_obj_t *characteristic = + (bleio_characteristic_obj_t *)((char *)ccc_data + - offsetof(bleio_characteristic_obj_t, zephyr_ccc)); + + if (characteristic->observer != mp_const_none && + mp_obj_is_type(characteristic->observer, &bleio_packet_buffer_type)) { + bleio_packet_buffer_set_conn( + MP_OBJ_TO_PTR(characteristic->observer), + value != 0 ? conn : NULL); + } + return sizeof(value); +} + +uint16_t bleio_security_to_zephyr_perm( + bleio_attribute_security_mode_t read_perm, + bleio_attribute_security_mode_t write_perm, + bleio_characteristic_properties_t props) { + uint16_t perm = 0; + + if (props & CHAR_PROP_READ) { + switch (read_perm) { + case SECURITY_MODE_OPEN: + perm |= BT_GATT_PERM_READ; + break; + case SECURITY_MODE_ENC_NO_MITM: + perm |= BT_GATT_PERM_READ_ENCRYPT; + break; + case SECURITY_MODE_ENC_WITH_MITM: + perm |= BT_GATT_PERM_READ_AUTHEN; + break; + case SECURITY_MODE_LESC_ENC_WITH_MITM: + perm |= BT_GATT_PERM_READ_LESC; + break; + default: + break; + } + } + + if (props & (CHAR_PROP_WRITE | CHAR_PROP_WRITE_NO_RESPONSE)) { + switch (write_perm) { + case SECURITY_MODE_OPEN: + perm |= BT_GATT_PERM_WRITE; + break; + case SECURITY_MODE_ENC_NO_MITM: + perm |= BT_GATT_PERM_WRITE_ENCRYPT; + break; + case SECURITY_MODE_ENC_WITH_MITM: + perm |= BT_GATT_PERM_WRITE_AUTHEN; + break; + case SECURITY_MODE_LESC_ENC_WITH_MITM: + perm |= BT_GATT_PERM_WRITE_LESC; + break; + default: + break; + } + } + + return perm; +} + +ssize_t bleio_char_read_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { + bleio_characteristic_obj_t *self = attr->user_data; + return bt_gatt_attr_read(conn, attr, buf, len, offset, + self->current_value, self->current_value_len); +} + +ssize_t bleio_char_write_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, const void *buf, uint16_t len, + uint16_t offset, uint8_t flags) { + bleio_characteristic_obj_t *self = attr->user_data; + if (offset + len > self->max_length) { + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + memcpy(self->current_value + offset, buf, len); + if (offset + len > self->current_value_len) { + self->current_value_len = offset + len; + } + + // Notify any observer (e.g., CharacteristicBuffer, PacketBuffer) of the write. + if (self->observer != mp_const_none) { + if (mp_obj_is_type(self->observer, &bleio_characteristic_buffer_type)) { + bleio_characteristic_buffer_extend(MP_OBJ_TO_PTR(self->observer), buf, len); + } else if (mp_obj_is_type(self->observer, &bleio_packet_buffer_type)) { + bleio_packet_buffer_extend(MP_OBJ_TO_PTR(self->observer), conn, buf, len); + } + } + + return len; +} + +void bleio_ccc_changed_cb(const struct bt_gatt_attr *attr, uint16_t value) { + // Track subscription state if needed in the future. + (void)attr; + (void)value; +} + +bleio_characteristic_properties_t common_hal_bleio_characteristic_get_properties(bleio_characteristic_obj_t *self) { + return self->props; +} + +mp_obj_tuple_t *common_hal_bleio_characteristic_get_descriptors(bleio_characteristic_obj_t *self) { + return mp_obj_new_tuple(self->descriptor_list->len, self->descriptor_list->items); +} + +bleio_service_obj_t *common_hal_bleio_characteristic_get_service(bleio_characteristic_obj_t *self) { + return self->service; +} + +bleio_uuid_obj_t *common_hal_bleio_characteristic_get_uuid(bleio_characteristic_obj_t *self) { + return self->uuid; +} + +size_t common_hal_bleio_characteristic_get_max_length(bleio_characteristic_obj_t *self) { + return self->max_length; +} + +size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *self, uint8_t *buf, size_t len) { + if (self->service != NULL && self->service->is_remote) { + // Remote characteristic: read via GATT client + bleio_connection_obj_t *connection = MP_OBJ_TO_PTR(self->service->connection); + if (connection == NULL || connection->connection == NULL || + connection->connection->conn == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Not connected")); + } + + return bleio_gattc_read_sync(connection->connection->conn, + self->handle, buf, len); + } + + // Local characteristic + size_t copy_len = self->current_value_len; + if (copy_len > len) { + copy_len = len; + } + memcpy(buf, self->current_value, copy_len); + return copy_len; +} + +void common_hal_bleio_characteristic_construct(bleio_characteristic_obj_t *self, + bleio_service_obj_t *service, uint16_t handle, bleio_uuid_obj_t *uuid, + bleio_characteristic_properties_t props, + bleio_attribute_security_mode_t read_perm, + bleio_attribute_security_mode_t write_perm, + mp_int_t max_length, bool fixed_length, + mp_buffer_info_t *initial_value_bufinfo, + const char *user_description) { + + self->service = service; + self->uuid = uuid; + self->handle = handle; + self->props = props; + self->read_perm = read_perm; + self->write_perm = write_perm; + self->max_length = max_length; + self->fixed_length = fixed_length; + self->observer = mp_const_none; + self->descriptor_list = mp_obj_new_list(0, NULL); + + // Allocate value buffer + self->current_value = m_malloc(max_length); + memset(self->current_value, 0, max_length); + self->current_value_alloc = max_length; + self->current_value_len = 0; + + // Copy initial value if provided + if (initial_value_bufinfo != NULL && initial_value_bufinfo->len > 0) { + size_t len = initial_value_bufinfo->len; + if (len > (size_t)max_length) { + len = max_length; + } + memcpy(self->current_value, initial_value_bufinfo->buf, len); + self->current_value_len = len; + } + + // Convert UUID to Zephyr format + bleio_uuid_to_zephyr(uuid, &self->zephyr_uuid); + + if (service->is_remote) { + // Remote characteristic: just add to the service's list + mp_obj_list_append(MP_OBJ_FROM_PTR(service->characteristic_list), + MP_OBJ_FROM_PTR(self)); + } else { + common_hal_bleio_service_add_characteristic(service, self, + initial_value_bufinfo, user_description); + + // Create a Descriptor object for user_description (CUD 0x2901) + if (user_description != NULL && user_description[0] != '\0') { + bleio_uuid_obj_t *desc_uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); + common_hal_bleio_uuid_construct(desc_uuid, 0x2901, NULL); + + bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); + + size_t desc_len = strlen(user_description); + mp_buffer_info_t desc_bufinfo = { + .buf = (void *)user_description, + .len = desc_len, + }; + + common_hal_bleio_descriptor_construct( + descriptor, self, desc_uuid, + SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, + desc_len, false, &desc_bufinfo); + + common_hal_bleio_characteristic_add_descriptor(self, descriptor); + } + } +} + +bool common_hal_bleio_characteristic_deinited(bleio_characteristic_obj_t *self) { + return self->service == NULL; +} + +void common_hal_bleio_characteristic_deinit(bleio_characteristic_obj_t *self) { + // Nothing to do - service handles unregistration +} + +// Struct for tracking GATT notification subscriptions on remote characteristics. +typedef struct { + struct bt_gatt_subscribe_params params; + uint16_t value_handle; + uint16_t ccc_handle; + bleio_characteristic_obj_t *characteristic; + volatile bool subscribed; +} zephyr_subscription_t; + +static uint8_t on_gattc_notify(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params, + const void *data, uint16_t length) { + zephyr_subscription_t *sub = CONTAINER_OF(params, zephyr_subscription_t, params); + if (sub->characteristic != NULL && + sub->characteristic->observer != mp_const_none) { + if (mp_obj_is_type(sub->characteristic->observer, &bleio_characteristic_buffer_type)) { + bleio_characteristic_buffer_extend( + MP_OBJ_TO_PTR(sub->characteristic->observer), data, length); + } else if (mp_obj_is_type(sub->characteristic->observer, &bleio_packet_buffer_type)) { + bleio_packet_buffer_extend( + MP_OBJ_TO_PTR(sub->characteristic->observer), conn, data, length); + } + } + return BT_GATT_ITER_CONTINUE; +} + +void common_hal_bleio_characteristic_set_cccd(bleio_characteristic_obj_t *self, bool notify, bool indicate) { + // Only valid for remote characteristics (client-side). + if (self->service == NULL || !self->service->is_remote) { + return; + } + + bleio_connection_obj_t *connection_obj = MP_OBJ_TO_PTR(self->service->connection); + if (connection_obj == NULL || connection_obj->connection == NULL || + connection_obj->connection->conn == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Not connected")); + } + + struct bt_conn *conn = connection_obj->connection->conn; + + if (!notify && !indicate) { + // Unsubscribe from any existing subscription. + // We don't track subscriptions per-characteristic yet, + // so just return for now. + return; + } + + if (self->cccd_handle == 0) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("No CCCD for this Characteristic")); + } + + // Allocate subscription tracking from port heap (won't move on GC). + // Note: Simplified - we allocate a new subscription each time. + // A production implementation would track and reuse subscriptions. + zephyr_subscription_t *sub = port_malloc(sizeof(zephyr_subscription_t), false); + if (sub == NULL) { + mp_raise_msg(&mp_type_MemoryError, NULL); + } + + // Zero-initialize the entire structure so that unset fields + // (subscribe, flags, discover_params, work_q, node) are NULL/0 + // rather than garbage from the heap. bt_gatt_subscribe checks + // subscribe==NULL to decide whether to do a synchronous write. + memset(sub, 0, sizeof(zephyr_subscription_t)); + + sub->characteristic = self; + sub->value_handle = self->handle; + sub->ccc_handle = self->cccd_handle; + sub->subscribed = false; + + sub->params.notify = on_gattc_notify; + sub->params.value_handle = self->handle; + sub->params.ccc_handle = self->cccd_handle; + sub->params.value = notify ? BT_GATT_CCC_NOTIFY : BT_GATT_CCC_INDICATE; + + int err = bt_gatt_subscribe(conn, &sub->params); + if (err != 0) { + port_free(sub); + raise_zephyr_error(err); + } + sub->subscribed = true; +} + +void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, mp_buffer_info_t *bufinfo) { + if (self->service != NULL && self->service->is_remote) { + // Remote characteristic: write via GATT client + bleio_connection_obj_t *connection = MP_OBJ_TO_PTR(self->service->connection); + if (connection == NULL || connection->connection == NULL || + connection->connection->conn == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Not connected")); + } + + if (self->props & CHAR_PROP_WRITE_NO_RESPONSE) { + int err = bt_gatt_write_without_response( + connection->connection->conn, + self->handle, + bufinfo->buf, bufinfo->len, false); + if (err != 0) { + raise_zephyr_error(err); + } + } else { + bleio_gattc_write_sync(connection->connection->conn, + self->handle, bufinfo->buf, bufinfo->len); + } + return; + } + + // Local characteristic + size_t len = bufinfo->len; + if (len > self->max_length) { + len = self->max_length; + } + memcpy(self->current_value, bufinfo->buf, len); + self->current_value_len = len; + + // If NOTIFY and service is registered, send notification + if ((self->props & CHAR_PROP_NOTIFY) && self->service != NULL && + self->service->registered) { + bt_gatt_notify(NULL, &self->service->attrs[self->value_attr_index], + self->current_value, self->current_value_len); + } +} + +void common_hal_bleio_characteristic_add_descriptor(bleio_characteristic_obj_t *self, + bleio_descriptor_obj_t *descriptor) { + mp_obj_list_append(MP_OBJ_FROM_PTR(self->descriptor_list), + MP_OBJ_FROM_PTR(descriptor)); + // Descriptors added after characteristic construction would need + // service re-registration; for now the common case is handled by + // Service.add_characteristic which adds descriptors at registration time. +} + +void bleio_characteristic_set_observer(bleio_characteristic_obj_t *self, mp_obj_t observer) { + self->observer = observer; +} + +void bleio_characteristic_clear_observer(bleio_characteristic_obj_t *self) { + self->observer = mp_const_none; +} diff --git a/ports/zephyr-cp/common-hal/_bleio/Characteristic.h b/ports/zephyr-cp/common-hal/_bleio/Characteristic.h new file mode 100644 index 00000000000..f4a578c888a --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Characteristic.h @@ -0,0 +1,63 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" +#include "py/objlist.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "shared-module/_bleio/Characteristic.h" +#include "common-hal/_bleio/Descriptor.h" +#include "common-hal/_bleio/Service.h" +#include "common-hal/_bleio/UUID.h" + +typedef struct _bleio_characteristic_obj { + mp_obj_base_t base; + bleio_service_obj_t *service; + bleio_uuid_obj_t *uuid; + mp_obj_t observer; + uint8_t *current_value; + uint16_t current_value_len; + uint16_t current_value_alloc; + uint16_t max_length; + uint16_t def_handle; + uint16_t handle; + bleio_characteristic_properties_t props; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; + mp_obj_list_t *descriptor_list; + uint16_t user_desc_handle; + uint16_t cccd_handle; + uint16_t sccd_handle; + bool fixed_length; + // Zephyr GATT server fields: + struct bt_gatt_chrc zephyr_chrc; + struct bt_uuid_128 zephyr_uuid; + struct bt_gatt_ccc_managed_user_data zephyr_ccc; + size_t value_attr_index; // index in service attrs for notify +} bleio_characteristic_obj_t; + +void bleio_characteristic_set_observer(bleio_characteristic_obj_t *self, mp_obj_t observer); +void bleio_characteristic_clear_observer(bleio_characteristic_obj_t *self); + +// Callbacks used by Service.c when building GATT attr table +ssize_t bleio_char_read_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset); +ssize_t bleio_char_write_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, const void *buf, uint16_t len, + uint16_t offset, uint8_t flags); +void bleio_ccc_changed_cb(const struct bt_gatt_attr *attr, uint16_t value); +ssize_t bleio_ccc_write_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, uint16_t value); + +// Permission mapping helper +uint16_t bleio_security_to_zephyr_perm( + bleio_attribute_security_mode_t read_perm, + bleio_attribute_security_mode_t write_perm, + bleio_characteristic_properties_t props); diff --git a/ports/zephyr-cp/common-hal/_bleio/CharacteristicBuffer.c b/ports/zephyr-cp/common-hal/_bleio/CharacteristicBuffer.c new file mode 100644 index 00000000000..9ce48ac97c4 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/CharacteristicBuffer.c @@ -0,0 +1,136 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include + +#include + +#include "py/runtime.h" +#include "py/stream.h" + +#include "shared/runtime/interrupt_char.h" + +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/CharacteristicBuffer.h" + +#include "supervisor/shared/tick.h" + +#include "common-hal/_bleio/CharacteristicBuffer.h" +#include "common-hal/_bleio/Characteristic.h" + +// Zephyr's ring_buf is safe for single-producer/single-consumer without +// locks. The GATT callbacks (system workqueue) are the sole producer; +// the CircuitPython VM (main thread) is the sole consumer. + +// Called from Zephyr GATT callbacks (system workqueue context). +void bleio_characteristic_buffer_extend(bleio_characteristic_buffer_obj_t *self, + const uint8_t *data, size_t len) { + if (self->watch_for_interrupt_char) { + for (size_t i = 0; i < len; i++) { + if (data[i] == mp_interrupt_char) { + mp_sched_keyboard_interrupt(); + ring_buf_reset(&self->ringbuf); + } else { + ring_buf_put(&self->ringbuf, &data[i], 1); + } + } + } else { + ring_buf_put(&self->ringbuf, data, len); + } +} + +void _common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, + bleio_characteristic_obj_t *characteristic, + mp_float_t timeout, + uint8_t *buffer, size_t buffer_size, + void *static_handler_entry, + bool watch_for_interrupt_char) { + + self->characteristic = characteristic; + self->timeout_ms = timeout * 1000; + self->watch_for_interrupt_char = watch_for_interrupt_char; + self->ringbuf_data = buffer; + ring_buf_init(&self->ringbuf, buffer_size, buffer); + + // Set ourselves as the characteristic's observer so we receive + // incoming writes (local) and notifications (remote). + bleio_characteristic_set_observer(characteristic, MP_OBJ_FROM_PTR(self)); +} + +// Assumes that timeout and buffer_size have been validated before call. +void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffer_obj_t *self, + bleio_characteristic_obj_t *characteristic, + mp_float_t timeout, + size_t buffer_size) { + uint8_t *buffer = m_malloc_without_collect(buffer_size); + _common_hal_bleio_characteristic_buffer_construct(self, characteristic, timeout, + buffer, buffer_size, NULL, false); +} + +uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, + uint8_t *data, size_t len, int *errcode) { + uint64_t start_ticks = supervisor_ticks_ms64(); + + // Wait for all bytes received or timeout + while ((ring_buf_size_get(&self->ringbuf) < len) && + (supervisor_ticks_ms64() - start_ticks < self->timeout_ms)) { + RUN_BACKGROUND_TASKS; + // Allow user to break out of a timeout with a KeyboardInterrupt. + if (mp_hal_is_interrupted()) { + return 0; + } + } + + return ring_buf_get(&self->ringbuf, data, len); +} + +uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available( + bleio_characteristic_buffer_obj_t *self) { + return ring_buf_size_get(&self->ringbuf); +} + +void common_hal_bleio_characteristic_buffer_clear_rx_buffer( + bleio_characteristic_buffer_obj_t *self) { + ring_buf_reset(&self->ringbuf); +} + +bool common_hal_bleio_characteristic_buffer_deinited(bleio_characteristic_buffer_obj_t *self) { + return self->characteristic == NULL; +} + +void common_hal_bleio_characteristic_buffer_deinit(bleio_characteristic_buffer_obj_t *self) { + if (common_hal_bleio_characteristic_buffer_deinited(self)) { + return; + } + bleio_characteristic_clear_observer(self->characteristic); + self->characteristic = NULL; + // ringbuf_data was allocated with m_malloc_without_collect; free it. + m_free(self->ringbuf_data); + self->ringbuf_data = NULL; +} + +bool common_hal_bleio_characteristic_buffer_connected(bleio_characteristic_buffer_obj_t *self) { + bleio_characteristic_obj_t *characteristic = self->characteristic; + if (characteristic == NULL || characteristic->service == NULL) { + return false; + } + + if (!characteristic->service->is_remote) { + // Local service: we're always "connected" as long as the service exists. + return true; + } + + // Remote service: check if the connection is still active. + if (characteristic->service->connection == mp_const_none) { + return false; + } + bleio_connection_obj_t *connection = + MP_OBJ_TO_PTR(characteristic->service->connection); + return common_hal_bleio_connection_get_connected(connection); +} diff --git a/ports/zephyr-cp/common-hal/_bleio/CharacteristicBuffer.h b/ports/zephyr-cp/common-hal/_bleio/CharacteristicBuffer.h new file mode 100644 index 00000000000..85a5d253be2 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/CharacteristicBuffer.h @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +#include "py/obj.h" +#include "shared-bindings/_bleio/Characteristic.h" + +typedef struct { + mp_obj_base_t base; + bleio_characteristic_obj_t *characteristic; + uint32_t timeout_ms; + struct ring_buf ringbuf; + uint8_t *ringbuf_data; + bool watch_for_interrupt_char; +} bleio_characteristic_buffer_obj_t; + +// Called from GATT callbacks (system workqueue context) to push +// data into the CharacteristicBuffer ring buffer. +void bleio_characteristic_buffer_extend(bleio_characteristic_buffer_obj_t *self, + const uint8_t *data, size_t len); diff --git a/ports/zephyr-cp/common-hal/_bleio/Connection.c b/ports/zephyr-cp/common-hal/_bleio/Connection.c new file mode 100644 index 00000000000..8381fe28a24 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Connection.c @@ -0,0 +1,675 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include + +#include +#include +#include +#include + +#include "py/runtime.h" +#include "shared/runtime/interrupt_char.h" +#include "bindings/zephyr_kernel/__init__.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Service.h" +#include "shared-bindings/_bleio/UUID.h" +#include "common-hal/_bleio/__init__.h" +#include "common-hal/_bleio/Characteristic.h" +#include "supervisor/port_heap.h" + +// Discovery context passed through Zephyr callbacks. +typedef struct { + volatile bool done; + volatile int err; +} discovery_context_t; + +// Convert a Zephyr bt_uuid to a CircuitPython bleio UUID object. +// Must be called OUTSIDE Zephyr callback context. +static bleio_uuid_obj_t *bleio_uuid_from_zephyr(const struct bt_uuid *zuuid) { + bleio_uuid_obj_t *uuid = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); + if (zuuid->type == BT_UUID_TYPE_16) { + common_hal_bleio_uuid_construct(uuid, BT_UUID_16(zuuid)->val, NULL); + } else { + // Both Zephyr and CP store UUID bytes in little-endian order. + const struct bt_uuid_128 *uuid128 = BT_UUID_128(zuuid); + common_hal_bleio_uuid_construct(uuid, + (uuid128->val[13] << 8) | uuid128->val[12], uuid128->val); + } + return uuid; +} + +// Temporary storage for discovered services before creating CP objects. +// Each node is port_malloc'd in the callback and appended to a sys_slist. +typedef struct { + sys_snode_t node; + struct bt_uuid_128 uuid; + uint16_t start_handle; + uint16_t end_handle; +} discovered_service_t; + +// Temporary storage for discovered characteristics before creating CP objects. +typedef struct { + sys_snode_t node; + struct bt_uuid_128 uuid; + uint16_t value_handle; + uint16_t decl_handle; + uint8_t properties; +} discovered_char_t; + +// Temporary storage for discovered descriptors. +typedef struct { + sys_snode_t node; + struct bt_uuid_128 uuid; + uint16_t handle; +} discovered_desc_t; + +// File-scope discovery state for synchronous blocking. +static discovery_context_t *active_discovery_ctx; +static sys_slist_t discovered_list; +static struct bt_gatt_discover_params discovery_params; + +static uint8_t on_service_discovered(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + discovery_context_t *ctx = active_discovery_ctx; + + if (attr == NULL) { + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + discovered_service_t *ds = port_malloc(sizeof(discovered_service_t), false); + if (ds == NULL) { + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + struct bt_gatt_service_val *svc_val = (struct bt_gatt_service_val *)attr->user_data; + ds->start_handle = attr->handle; + ds->end_handle = svc_val->end_handle; + + // Copy UUID into our storage + if (svc_val->uuid->type == BT_UUID_TYPE_16) { + ds->uuid.uuid.type = BT_UUID_TYPE_16; + ((struct bt_uuid_16 *)&ds->uuid)->val = BT_UUID_16(svc_val->uuid)->val; + } else { + memcpy(&ds->uuid, svc_val->uuid, sizeof(struct bt_uuid_128)); + } + + sys_slist_append(&discovered_list, &ds->node); + + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t on_characteristic_discovered(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + discovery_context_t *ctx = active_discovery_ctx; + + if (attr == NULL) { + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + discovered_char_t *dc = port_malloc(sizeof(discovered_char_t), false); + if (dc == NULL) { + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; + dc->value_handle = chrc->value_handle; + dc->decl_handle = attr->handle; + dc->properties = chrc->properties; + + // Copy UUID into our storage + if (chrc->uuid->type == BT_UUID_TYPE_16) { + dc->uuid.uuid.type = BT_UUID_TYPE_16; + ((struct bt_uuid_16 *)&dc->uuid)->val = BT_UUID_16(chrc->uuid)->val; + } else { + memcpy(&dc->uuid, chrc->uuid, sizeof(struct bt_uuid_128)); + } + + sys_slist_append(&discovered_list, &dc->node); + + return BT_GATT_ITER_CONTINUE; +} + +// Pairing: characteristic pointer with its declaration handle for descriptor discovery. +typedef struct { + bleio_characteristic_obj_t *characteristic; + uint16_t decl_handle; +} char_with_decl_t; + +// Forward declaration for use by descriptor discovery. +static void free_discovered_list(void); + +// Callback for descriptor discovery. +static uint8_t on_descriptor_discovered(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + discovery_context_t *ctx = active_discovery_ctx; + + if (attr == NULL) { + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + discovered_desc_t *dd = port_malloc(sizeof(discovered_desc_t), false); + if (dd == NULL) { + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + dd->handle = attr->handle; + + // Copy UUID into our storage + if (attr->uuid->type == BT_UUID_TYPE_16) { + dd->uuid.uuid.type = BT_UUID_TYPE_16; + ((struct bt_uuid_16 *)&dd->uuid)->val = BT_UUID_16(attr->uuid)->val; + } else { + memcpy(&dd->uuid, attr->uuid, sizeof(struct bt_uuid_128)); + } + + sys_slist_append(&discovered_list, &dd->node); + + return BT_GATT_ITER_CONTINUE; +} + +// Create descriptors from discovered_list and add them to the characteristic. +// Called OUTSIDE the Zephyr callback context. Drains and frees all nodes. +static void create_descriptors_from_discovered(bleio_characteristic_obj_t *characteristic) { + sys_snode_t *node; + while ((node = sys_slist_get(&discovered_list)) != NULL) { + discovered_desc_t *dd = CONTAINER_OF(node, discovered_desc_t, node); + + bleio_uuid_obj_t *uuid = bleio_uuid_from_zephyr(&dd->uuid.uuid); + + // Remember handles for certain well-known descriptors. + if (dd->uuid.uuid.type == BT_UUID_TYPE_16) { + switch (((struct bt_uuid_16 *)&dd->uuid)->val) { + case 0x2902: + characteristic->cccd_handle = dd->handle; + break; + case 0x2903: + characteristic->sccd_handle = dd->handle; + break; + case 0x2901: + characteristic->user_desc_handle = dd->handle; + break; + default: + break; + } + } + + bleio_descriptor_obj_t *descriptor = + mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); + + // Remote descriptors: set characteristic and UUID only. + // Reads/writes go over GATT via the handle. + descriptor->characteristic = characteristic; + descriptor->uuid = uuid; + descriptor->handle = dd->handle; + descriptor->read_perm = SECURITY_MODE_OPEN; + descriptor->write_perm = SECURITY_MODE_OPEN; + descriptor->max_length = 20; + descriptor->fixed_length = false; + descriptor->value = m_malloc(20); + memset(descriptor->value, 0, 20); + descriptor->value_length = 0; + + common_hal_bleio_characteristic_add_descriptor(characteristic, descriptor); + + port_free(dd); + } +} + +// Discover descriptors for a single characteristic. +static void discover_descriptors_for_characteristic(struct bt_conn *conn, + discovery_context_t *ctx, bleio_characteristic_obj_t *characteristic, + uint16_t end_handle) { + uint16_t start = characteristic->handle + 1; + if (start > end_handle) { + return; + } + + sys_slist_init(&discovered_list); + ctx->done = false; + ctx->err = 0; + + memset(&discovery_params, 0, sizeof(discovery_params)); + discovery_params.uuid = NULL; + discovery_params.start_handle = start; + discovery_params.end_handle = end_handle; + discovery_params.type = BT_GATT_DISCOVER_DESCRIPTOR; + discovery_params.func = on_descriptor_discovered; + + int err = bt_gatt_discover(conn, &discovery_params); + if (err != 0) { + free_discovered_list(); + if (err == -ENOENT) { + return; + } + raise_zephyr_error(err); + } + + while (!ctx->done) { + RUN_BACKGROUND_TASKS; + } + + create_descriptors_from_discovered(characteristic); +} + +// Create CircuitPython characteristic objects from the discovered_list. +// Called OUTSIDE the Zephyr callback context so MP allocations are safe. +// Drains and frees all nodes from the list. +// Returns the number of characteristics created and fills the chars_out array +// (which must be large enough). +static size_t create_characteristics_from_discovered(bleio_service_obj_t *service, + char_with_decl_t *chars_out, size_t max_chars) { + size_t count = 0; + sys_snode_t *node; + while ((node = sys_slist_get(&discovered_list)) != NULL) { + discovered_char_t *dc = CONTAINER_OF(node, discovered_char_t, node); + + bleio_uuid_obj_t *uuid = bleio_uuid_from_zephyr(&dc->uuid.uuid); + + bleio_characteristic_properties_t props = 0; + if (dc->properties & BT_GATT_CHRC_BROADCAST) { + props |= CHAR_PROP_BROADCAST; + } + if (dc->properties & BT_GATT_CHRC_READ) { + props |= CHAR_PROP_READ; + } + if (dc->properties & BT_GATT_CHRC_WRITE_WITHOUT_RESP) { + props |= CHAR_PROP_WRITE_NO_RESPONSE; + } + if (dc->properties & BT_GATT_CHRC_WRITE) { + props |= CHAR_PROP_WRITE; + } + if (dc->properties & BT_GATT_CHRC_NOTIFY) { + props |= CHAR_PROP_NOTIFY; + } + if (dc->properties & BT_GATT_CHRC_INDICATE) { + props |= CHAR_PROP_INDICATE; + } + + bleio_characteristic_obj_t *characteristic = + mp_obj_malloc(bleio_characteristic_obj_t, &bleio_characteristic_type); + + // Use max_length=20 for remote chars - reads go over the wire. + common_hal_bleio_characteristic_construct( + characteristic, service, + dc->value_handle, uuid, props, + SECURITY_MODE_OPEN, SECURITY_MODE_OPEN, + 20, false, NULL, NULL); + + if (count < max_chars) { + chars_out[count].characteristic = characteristic; + chars_out[count].decl_handle = dc->decl_handle; + } + count++; + + port_free(dc); + } + return count; +} + +// Helper to drain and free all nodes from the discovered_list. +static void free_discovered_list(void) { + sys_snode_t *node; + while ((node = sys_slist_get(&discovered_list)) != NULL) { + port_free(node); + } +} + +// Discover characteristics for a single remote service. +static void discover_characteristics_for_service(struct bt_conn *conn, + discovery_context_t *ctx, bleio_service_obj_t *service) { + // Need at least 2 handles: one for the service declaration, one for a characteristic + if (service->end_handle <= service->start_handle) { + return; + } + + sys_slist_init(&discovered_list); + ctx->done = false; + ctx->err = 0; + + memset(&discovery_params, 0, sizeof(discovery_params)); + discovery_params.uuid = NULL; + discovery_params.start_handle = service->start_handle + 1; + discovery_params.end_handle = service->end_handle; + discovery_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + discovery_params.func = on_characteristic_discovered; + + int err = bt_gatt_discover(conn, &discovery_params); + if (err != 0) { + free_discovered_list(); + // -ENOENT means no characteristics found in the range, which is fine. + if (err == -ENOENT) { + return; + } + raise_zephyr_error(err); + } + + while (!ctx->done) { + RUN_BACKGROUND_TASKS; + } + + // Create CP objects outside of callback context where MP allocations are safe. + // This drains and frees the list nodes. + char_with_decl_t chars[16]; + size_t num_chars = create_characteristics_from_discovered(service, chars, 16); + + // Discover descriptors for each characteristic. + // The descriptor range for char[i] is from char[i].handle+1 to + // char[i+1].decl_handle-1 (or service.end_handle for the last). + for (size_t i = 0; i < num_chars && i < 16; i++) { + uint16_t desc_end; + if (i + 1 < num_chars) { + desc_end = chars[i + 1].decl_handle - 1; + } else { + desc_end = service->end_handle; + } + discover_descriptors_for_characteristic(conn, ctx, + chars[i].characteristic, desc_end); + } +} + +// ===== PAIRING / BONDING ===== + +// Auth info callbacks to track pairing completion/failure +static struct bt_conn_auth_info_cb auth_info_cb; +static bool auth_info_cb_registered = false; + +static void on_pairing_complete(struct bt_conn *conn, bool bonded) { + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + if (bleio_connections[i].conn == conn) { + bleio_connections[i].pair_status = PAIR_PAIRED; + bleio_connections[i].sec_err = 0; + break; + } + } +} + +static void on_pairing_failed(struct bt_conn *conn, enum bt_security_err reason) { + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + if (bleio_connections[i].conn == conn) { + bleio_connections[i].pair_status = PAIR_NOT_PAIRED; + bleio_connections[i].sec_err = (uint8_t)reason; + break; + } + } +} + +void bleio_connection_register_auth_callbacks(void) { + if (!auth_info_cb_registered) { + auth_info_cb.pairing_complete = on_pairing_complete; + auth_info_cb.pairing_failed = on_pairing_failed; + bt_conn_auth_info_cb_register(&auth_info_cb); + auth_info_cb_registered = true; + } +} + +void common_hal_bleio_connection_pair(bleio_connection_internal_t *self, bool bond) { + (void)bond; // Bonding is enabled globally via CONFIG_BT_BONDABLE=y + + if (self == NULL || self->conn == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Not connected")); + } + + // Already paired? + if (self->pair_status == PAIR_PAIRED) { + return; + } + + // Ensure auth callbacks are registered + bleio_connection_register_auth_callbacks(); + + self->pair_status = PAIR_WAITING; + self->sec_err = 0; + + int err = bt_conn_set_security(self->conn, BT_SECURITY_L2); + if (err != 0) { + self->pair_status = PAIR_NOT_PAIRED; + raise_zephyr_error(err); + } + + // bt_conn_set_security may return 0 immediately if already encrypted + // (e.g., reconnection with stored bond keys). Check current security level. + if (bt_conn_get_security(self->conn) > BT_SECURITY_L1) { + self->pair_status = PAIR_PAIRED; + return; + } + + // Wait for pairing to complete. Zephyr's SMP reports each attempt via + // pairing_failed before auto-restarting security (smp.c), so a stale-bond + // retry shows up as an intermediate BT_SECURITY_ERR_PIN_OR_KEY_MISSING + // followed by a fresh attempt that can succeed. Ride through those and + // rely on Zephyr to signal the end: success (PAIR_PAIRED), SMP_TIMEOUT + // dropping the link (observed as conn == NULL), or a user interrupt. + while (self->pair_status != PAIR_PAIRED + && self->conn != NULL + && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } + + if (mp_hal_is_interrupted()) { + if (self->conn != NULL) { + bt_conn_auth_cancel(self->conn); + } + self->pair_status = PAIR_NOT_PAIRED; + return; + } + + if (self->pair_status == PAIR_PAIRED) { + return; + } + + // Reuse the messages shared with the nordic _bleio implementation + // (check_sec_status). A dropped link clears sec_err, so it falls through + // to the "unspecified issue" message alongside the explicit UNSPECIFIED + // error code rather than introducing a zephyr-specific "Pairing failed" + // string. + uint8_t sec_err_code = self->sec_err; + if (sec_err_code == BT_SECURITY_ERR_UNSPECIFIED || sec_err_code == 0) { + mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unspecified issue. The pairing request on the other device may have been declined or ignored.")); + } else { + mp_raise_bleio_SecurityError(MP_ERROR_TEXT("Unknown security error: 0x%04x"), sec_err_code); + } +} + +void common_hal_bleio_connection_disconnect(bleio_connection_internal_t *self) { + if (self == NULL || self->conn == NULL) { + return; + } + + int err = bt_conn_disconnect(self->conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err != 0 && err != -ENOTCONN) { + raise_zephyr_error(err); + } + + // The connection may now be disconnecting; force connections tuple rebuild. + common_hal_bleio_adapter_obj.connection_objs = NULL; +} + +bool common_hal_bleio_connection_get_connected(bleio_connection_obj_t *self) { + if (self == NULL || self->connection == NULL) { + return false; + } + + bleio_connection_internal_t *connection = self->connection; + if (connection->conn == NULL) { + return false; + } + + struct bt_conn_info info; + if (bt_conn_get_info(connection->conn, &info) != 0) { + return false; + } + + return info.state == BT_CONN_STATE_CONNECTED || info.state == BT_CONN_STATE_DISCONNECTING; +} + +mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self) { + if (self == NULL || self->conn == NULL) { + return 20; + } + + uint16_t mtu = bt_gatt_get_mtu(self->conn); + if (mtu < 3) { + return 20; + } + return mtu - 3; +} + +bool common_hal_bleio_connection_get_paired(bleio_connection_obj_t *self) { + if (self == NULL || self->connection == NULL) { + return false; + } + return self->connection->pair_status == PAIR_PAIRED; +} + +mp_obj_tuple_t *common_hal_bleio_connection_discover_remote_services(bleio_connection_obj_t *self, mp_obj_t service_uuids_whitelist) { + bleio_connection_internal_t *connection = self->connection; + if (connection == NULL || connection->conn == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Not connected")); + } + + discovery_context_t ctx; + ctx.done = false; + ctx.err = 0; + + active_discovery_ctx = &ctx; + sys_slist_init(&discovered_list); + + // Create the result list for service objects. + mp_obj_list_t *service_list = mp_obj_new_list(0, NULL); + + // Discover primary services (callback appends nodes to discovered_list). + // When a whitelist is given, pass each UUID to Zephyr so filtering happens + // on the remote device — only matching services are returned. + if (service_uuids_whitelist == mp_const_none) { + memset(&discovery_params, 0, sizeof(discovery_params)); + discovery_params.uuid = NULL; + discovery_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discovery_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discovery_params.type = BT_GATT_DISCOVER_PRIMARY; + discovery_params.func = on_service_discovered; + + int err = bt_gatt_discover(connection->conn, &discovery_params); + if (err != 0) { + free_discovered_list(); + active_discovery_ctx = NULL; + raise_zephyr_error(err); + } + + while (!ctx.done) { + RUN_BACKGROUND_TASKS; + } + } else { + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(service_uuids_whitelist, &iter_buf); + mp_obj_t uuid_obj; + while ((uuid_obj = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + bleio_uuid_obj_t *cp_uuid = mp_arg_validate_type(uuid_obj, &bleio_uuid_type, MP_QSTR_uuid); + + memset(&discovery_params, 0, sizeof(discovery_params)); + discovery_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discovery_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discovery_params.type = BT_GATT_DISCOVER_PRIMARY; + discovery_params.func = on_service_discovered; + + // Set the Zephyr UUID filter. Stack variables are safe because + // bt_gatt_discover is synchronous (we spin until ctx.done). + union { + struct bt_uuid_16 u16; + struct bt_uuid_128 u128; + } z_uuid; + if (cp_uuid->size == BT_UUID_SIZE_16) { + z_uuid.u16.uuid.type = BT_UUID_TYPE_16; + z_uuid.u16.val = cp_uuid->uuid16; + discovery_params.uuid = &z_uuid.u16.uuid; + } else { + z_uuid.u128.uuid.type = BT_UUID_TYPE_128; + memcpy(z_uuid.u128.val, cp_uuid->uuid128, 16); + discovery_params.uuid = &z_uuid.u128.uuid; + } + + ctx.done = false; + ctx.err = 0; + + int err = bt_gatt_discover(connection->conn, &discovery_params); + if (err != 0) { + free_discovered_list(); + active_discovery_ctx = NULL; + raise_zephyr_error(err); + } + + while (!ctx.done) { + RUN_BACKGROUND_TASKS; + } + } + } + + // Create CP service objects outside callback context where MP allocations are safe. + // Drain and free the discovered service nodes. + mp_obj_list_t *result_list = service_list; + sys_snode_t *snode; + while ((snode = sys_slist_get(&discovered_list)) != NULL) { + discovered_service_t *ds = CONTAINER_OF(snode, discovered_service_t, node); + bleio_uuid_obj_t *uuid = bleio_uuid_from_zephyr(&ds->uuid.uuid); + bleio_service_obj_t *service = mp_obj_malloc(bleio_service_obj_t, &bleio_service_type); + common_hal_bleio_service_from_remote_service(service, self, uuid, false); + service->start_handle = ds->start_handle; + service->end_handle = ds->end_handle; + mp_obj_list_append(MP_OBJ_FROM_PTR(service_list), MP_OBJ_FROM_PTR(service)); + port_free(ds); + } + + // Discover characteristics for each service + for (size_t i = 0; i < result_list->len; i++) { + bleio_service_obj_t *svc = MP_OBJ_TO_PTR(result_list->items[i]); + if (svc->start_handle < svc->end_handle) { + discover_characteristics_for_service(connection->conn, &ctx, svc); + } + } + + active_discovery_ctx = NULL; + + return mp_obj_new_tuple(result_list->len, result_list->items); +} + +mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_internal_t *self) { + mp_raise_NotImplementedError(NULL); +} + +void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) { + mp_raise_NotImplementedError(NULL); +} + +mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *connection) { + if (connection == NULL) { + return mp_const_none; + } + + if (connection->connection_obj != mp_const_none) { + return connection->connection_obj; + } + + bleio_connection_obj_t *connection_obj = mp_obj_malloc(bleio_connection_obj_t, &bleio_connection_type); + connection_obj->connection = connection; + connection_obj->disconnect_reason = 0; + connection->connection_obj = MP_OBJ_FROM_PTR(connection_obj); + + return connection->connection_obj; +} diff --git a/ports/zephyr-cp/common-hal/_bleio/Connection.h b/ports/zephyr-cp/common-hal/_bleio/Connection.h new file mode 100644 index 00000000000..323e9393103 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Connection.h @@ -0,0 +1,36 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" + +struct bt_conn; + +typedef enum { + PAIR_NOT_PAIRED, + PAIR_WAITING, + PAIR_PAIRED, +} pair_status_t; + +typedef struct { + struct bt_conn *conn; + mp_obj_t connection_obj; + volatile pair_status_t pair_status; + uint8_t sec_err; // Security error code from pairing attempt +} bleio_connection_internal_t; + +typedef struct { + mp_obj_base_t base; + bleio_connection_internal_t *connection; + uint8_t disconnect_reason; +} bleio_connection_obj_t; + +mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t *connection); +void bleio_connection_register_auth_callbacks(void); diff --git a/ports/zephyr-cp/common-hal/_bleio/Descriptor.c b/ports/zephyr-cp/common-hal/_bleio/Descriptor.c new file mode 100644 index 00000000000..a2219d8b5cd --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Descriptor.c @@ -0,0 +1,109 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/runtime.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "common-hal/_bleio/__init__.h" +#include "common-hal/_bleio/Characteristic.h" +#include "common-hal/_bleio/Connection.h" +#include "supervisor/port_heap.h" + +void common_hal_bleio_descriptor_construct(bleio_descriptor_obj_t *self, + bleio_characteristic_obj_t *characteristic, bleio_uuid_obj_t *uuid, + bleio_attribute_security_mode_t read_perm, + bleio_attribute_security_mode_t write_perm, + mp_int_t max_length, bool fixed_length, + mp_buffer_info_t *initial_value_bufinfo) { + + self->characteristic = characteristic; + self->uuid = uuid; + self->read_perm = read_perm; + self->write_perm = write_perm; + self->max_length = max_length; + self->fixed_length = fixed_length; + + // Allocate value buffer + self->value = m_malloc(max_length); + memset(self->value, 0, max_length); + self->value_length = 0; + + // Copy initial value if provided + if (initial_value_bufinfo != NULL && initial_value_bufinfo->len > 0) { + size_t len = initial_value_bufinfo->len; + if (len > (size_t)max_length) { + len = max_length; + } + memcpy(self->value, initial_value_bufinfo->buf, len); + self->value_length = len; + } + + // Convert UUID to Zephyr format + bleio_uuid_to_zephyr(uuid, &self->zephyr_uuid); +} + +bleio_uuid_obj_t *common_hal_bleio_descriptor_get_uuid(bleio_descriptor_obj_t *self) { + return self->uuid; +} + +bleio_characteristic_obj_t *common_hal_bleio_descriptor_get_characteristic(bleio_descriptor_obj_t *self) { + return (bleio_characteristic_obj_t *)self->characteristic; +} + +static bool descriptor_is_remote(bleio_descriptor_obj_t *self) { + return self->characteristic != NULL && + self->characteristic->service != NULL && + self->characteristic->service->is_remote; +} + +size_t common_hal_bleio_descriptor_get_value(bleio_descriptor_obj_t *self, uint8_t *buf, size_t len) { + if (descriptor_is_remote(self)) { + bleio_connection_obj_t *connection = + MP_OBJ_TO_PTR(self->characteristic->service->connection); + if (connection == NULL || connection->connection == NULL || + connection->connection->conn == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Not connected")); + } + + return bleio_gattc_read_sync(connection->connection->conn, + self->handle, buf, len); + } + + // Local descriptor + size_t copy_len = self->value_length; + if (copy_len > len) { + copy_len = len; + } + memcpy(buf, self->value, copy_len); + return copy_len; +} + +void common_hal_bleio_descriptor_set_value(bleio_descriptor_obj_t *self, mp_buffer_info_t *bufinfo) { + if (descriptor_is_remote(self)) { + bleio_connection_obj_t *connection = + MP_OBJ_TO_PTR(self->characteristic->service->connection); + if (connection == NULL || connection->connection == NULL || + connection->connection->conn == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Not connected")); + } + + bleio_gattc_write_sync(connection->connection->conn, + self->handle, bufinfo->buf, bufinfo->len); + return; + } + + // Local descriptor + size_t len = bufinfo->len; + if (len > self->max_length) { + len = self->max_length; + } + memcpy(self->value, bufinfo->buf, len); + self->value_length = len; +} diff --git a/ports/zephyr-cp/common-hal/_bleio/Descriptor.h b/ports/zephyr-cp/common-hal/_bleio/Descriptor.h new file mode 100644 index 00000000000..b6d3ab4452e --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Descriptor.h @@ -0,0 +1,31 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" +#include "shared-bindings/_bleio/Attribute.h" +#include "common-hal/_bleio/UUID.h" + +// Forward declaration to break circular dependency +struct _bleio_characteristic_obj; + +typedef struct _bleio_descriptor_obj { + mp_obj_base_t base; + bleio_uuid_obj_t *uuid; + uint16_t handle; + bleio_attribute_security_mode_t read_perm; + bleio_attribute_security_mode_t write_perm; + uint16_t max_length; + bool fixed_length; + uint8_t *value; + uint16_t value_length; + struct _bleio_characteristic_obj *characteristic; + struct bt_uuid_128 zephyr_uuid; +} bleio_descriptor_obj_t; diff --git a/ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c b/ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c new file mode 100644 index 00000000000..02e593fabfe --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/PacketBuffer.c @@ -0,0 +1,402 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include +#include +#include + +#include "py/runtime.h" +#include "py/stream.h" + +#include "shared/runtime/interrupt_char.h" + +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/PacketBuffer.h" + +#include "supervisor/shared/tick.h" + +#include "common-hal/_bleio/Characteristic.h" +#include "common-hal/_bleio/PacketBuffer.h" + +// Zephyr's ring_buf is safe for single-producer/single-consumer without +// locks. The GATT callbacks (system workqueue) are the sole producer; +// the CircuitPython VM (main thread) is the sole consumer. + +// Forward declarations. +static bool conn_is_valid(bleio_packet_buffer_obj_t *self); +static bool send_pending(bleio_packet_buffer_obj_t *self); + +// Called from Zephyr GATT callbacks (system workqueue context). +// Wraps incoming data with a uint16_t length prefix and pushes into ringbuf. +// Tracks the first connection so notifications target the right peer. +void bleio_packet_buffer_extend(bleio_packet_buffer_obj_t *self, + struct bt_conn *conn, const uint8_t *data, size_t len) { + // Track the first/current connection for notifications. + if (conn != NULL) { + conn_is_valid(self); // clear stale conn if needed + if (self->conn == NULL) { + self->conn = conn; + } + } + if (len > UINT16_MAX) { + return; + } + + uint16_t packet_len = (uint16_t)len; + size_t total = sizeof(uint16_t) + len; + + // If the packet doesn't fit, drop oldest packets to make room. + while (ring_buf_space_get(&self->ringbuf) < total) { + uint16_t old_len; + if (ring_buf_size_get(&self->ringbuf) < sizeof(uint16_t)) { + // Not enough data for a length prefix, just reset. + ring_buf_reset(&self->ringbuf); + break; + } + uint32_t peeked = ring_buf_peek(&self->ringbuf, (uint8_t *)&old_len, sizeof(uint16_t)); + if (peeked < sizeof(uint16_t)) { + ring_buf_reset(&self->ringbuf); + break; + } + // Discard the length prefix + ring_buf_get(&self->ringbuf, (uint8_t *)&old_len, sizeof(uint16_t)); + // Discard the packet data + size_t to_discard = old_len; + if (to_discard > ring_buf_size_get(&self->ringbuf)) { + to_discard = ring_buf_size_get(&self->ringbuf); + } + uint8_t discard_buf[32]; + while (to_discard > 0) { + size_t chunk = to_discard > sizeof(discard_buf) ? sizeof(discard_buf) : to_discard; + ring_buf_get(&self->ringbuf, discard_buf, chunk); + to_discard -= chunk; + } + } + + ring_buf_put(&self->ringbuf, (uint8_t *)&packet_len, sizeof(uint16_t)); + ring_buf_put(&self->ringbuf, data, len); +} + +void bleio_packet_buffer_set_conn(bleio_packet_buffer_obj_t *self, + struct bt_conn *conn) { + self->conn = conn; +} + +// Completion callback for bt_gatt_notify_cb — called when the PDU has been +// sent (or the buffer freed). Drains any accumulated pending data. +static void notify_complete_cb(struct bt_conn *conn, void *user_data) { + bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *)user_data; + self->packet_queued = false; + send_pending(self); +} + +// Returns true if the tracked connection is still connected. +// Clears self->conn if the connection is stale. +static bool conn_is_valid(bleio_packet_buffer_obj_t *self) { + if (self->conn == NULL) { + return false; + } + struct bt_conn_info info; + if (bt_conn_get_info(self->conn, &info) != 0 || + info.state == BT_CONN_STATE_DISCONNECTED) { + self->conn = NULL; + return false; + } + return true; +} + +// Send the pending outgoing buffer via GATT notify. +// Returns true if sent successfully (or terminal failure). +static bool send_pending(bleio_packet_buffer_obj_t *self) { + if (self->pending_size == 0) { + return true; + } + if (self->characteristic == NULL || + self->characteristic->service == NULL || + self->characteristic->service->is_remote) { + self->pending_size = 0; + return true; + } + + bleio_characteristic_obj_t *c = self->characteristic; + if (!(c->props & CHAR_PROP_NOTIFY) || !c->service->registered) { + self->pending_size = 0; + return true; + } + + struct bt_gatt_notify_params params = { + .attr = &c->service->attrs[c->value_attr_index], + .data = self->outgoing_buffer, + .len = self->pending_size, + .func = notify_complete_cb, + .user_data = self, + }; + + // If the tracked connection is stale, clear it. + conn_is_valid(self); + + int err = bt_gatt_notify_cb(self->conn, ¶ms); + if (err == 0) { + self->pending_size = 0; + self->packet_queued = true; + return true; + } + if (err == -ENOTCONN) { + // Peer disconnected — clear tracking, discard pending. + self->conn = NULL; + self->pending_size = 0; + return true; + } + // -ENOMEM (no TX buffer) — leave pending, caller will retry. + return false; +} + +void common_hal_bleio_packet_buffer_construct( + bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, + size_t buffer_size, size_t max_packet_size) { + + self->characteristic = characteristic; + self->timeout_ms = 0; + self->max_packet_size = max_packet_size; + self->conn = NULL; + self->client = (characteristic->service != NULL && characteristic->service->is_remote); + self->pending_size = 0; + self->packet_queued = false; + + // Allocate ring buffer: buffer_size packets, each with 2-byte length prefix + self->ringbuf_size = buffer_size * (sizeof(uint16_t) + max_packet_size); + self->ringbuf_data = m_malloc_without_collect(self->ringbuf_size); + ring_buf_init(&self->ringbuf, self->ringbuf_size, self->ringbuf_data); + + // Allocate outgoing buffer for pending writes + bleio_characteristic_properties_t props = + common_hal_bleio_characteristic_get_properties(characteristic); + if (self->client) { + // Client-side: we write to remote characteristic + self->outgoing_buffer = m_malloc_without_collect(max_packet_size); + } else { + // Server-side: we notify via local characteristic + if (props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) { + self->outgoing_buffer = m_malloc_without_collect(max_packet_size); + } else { + self->outgoing_buffer = NULL; + } + } + + // Set ourselves as the characteristic's observer + bleio_characteristic_set_observer(characteristic, MP_OBJ_FROM_PTR(self)); + + // For client-side characteristics with NOTIFY/INDICATE, subscribe to notifications + if (self->client && (props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE))) { + bool do_notify = (props & CHAR_PROP_NOTIFY) != 0; + bool do_indicate = (props & CHAR_PROP_INDICATE) != 0; + common_hal_bleio_characteristic_set_cccd(characteristic, do_notify, do_indicate); + } +} + +// Allocation-free version for BLE workflow use (not yet implemented for Zephyr). +void _common_hal_bleio_packet_buffer_construct( + bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, + uint32_t *incoming_buffer, size_t incoming_buffer_size, + uint32_t *outgoing_buffer1, uint32_t *outgoing_buffer2, size_t max_packet_size, + ble_event_handler_t *static_handler_entry) { + (void)self; + (void)characteristic; + (void)incoming_buffer; + (void)incoming_buffer_size; + (void)outgoing_buffer1; + (void)outgoing_buffer2; + (void)max_packet_size; + (void)static_handler_entry; + mp_raise_NotImplementedError(NULL); +} + +mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, + uint8_t *data, size_t len) { + // Need at least 2 bytes for the length prefix + if (ring_buf_size_get(&self->ringbuf) < sizeof(uint16_t)) { + return 0; + } + + // Peek at the packet length (don't consume yet) + uint16_t packet_length; + uint32_t peeked = ring_buf_peek(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t)); + if (peeked < sizeof(uint16_t)) { + return 0; + } + + mp_int_t ret; + if (packet_length > len) { + // Packet is longer than requested. Return negative of overrun value. + ret = len - packet_length; + // Discard the packet + ring_buf_get(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t)); + if (packet_length <= ring_buf_size_get(&self->ringbuf)) { + // Discard data in chunks + uint8_t discard[32]; + size_t remaining = packet_length; + while (remaining > 0) { + size_t chunk = remaining > sizeof(discard) ? sizeof(discard) : remaining; + ring_buf_get(&self->ringbuf, discard, chunk); + remaining -= chunk; + } + } + } else { + // Consume the length prefix + ring_buf_get(&self->ringbuf, (uint8_t *)&packet_length, sizeof(uint16_t)); + // Read packet data + ring_buf_get(&self->ringbuf, data, packet_length); + ret = packet_length; + } + + return ret; +} + +mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, + const uint8_t *data, size_t len, uint8_t *header, size_t header_len) { + if (self->outgoing_buffer == NULL) { + mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Writes not supported on Characteristic")); + } + + mp_int_t outgoing_packet_length = + common_hal_bleio_packet_buffer_get_outgoing_packet_length(self); + if (outgoing_packet_length < 0) { + return -1; + } + + mp_int_t total_len = len + header_len; + if (total_len > outgoing_packet_length) { + mp_raise_ValueError_varg( + MP_ERROR_TEXT("Total data to write is larger than %q"), + MP_QSTR_outgoing_packet_length); + } + if (total_len > (mp_int_t)self->max_packet_size) { + mp_raise_ValueError_varg( + MP_ERROR_TEXT("Total data to write is larger than %q"), + MP_QSTR_max_packet_size); + } + + // If no room to append, wait until pending is sent. + if (len + self->pending_size > (size_t)outgoing_packet_length) { + while (self->pending_size != 0 && + !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } + } + if (mp_hal_is_interrupted()) { + return -1; + } + + size_t num_bytes_written = 0; + + if (self->pending_size == 0) { + memcpy(self->outgoing_buffer, header, header_len); + self->pending_size += header_len; + num_bytes_written += header_len; + } + memcpy(self->outgoing_buffer + self->pending_size, data, len); + self->pending_size += len; + num_bytes_written += len; + + // Send immediately if no write is queued. + if (!self->packet_queued) { + send_pending(self); + } + return num_bytes_written; +} + +mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length( + bleio_packet_buffer_obj_t *self) { + if (self->characteristic == NULL) { + return -1; + } + + if (self->characteristic->service != NULL && + self->characteristic->service->is_remote && + self->characteristic->service->connection != mp_const_none && + (common_hal_bleio_characteristic_get_properties(self->characteristic) & + (CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) { + // We are receiving from a remote service via NOTIFY/INDICATE. + bleio_connection_obj_t *connection = + MP_OBJ_TO_PTR(self->characteristic->service->connection); + if (connection != NULL && connection->connection != NULL && + common_hal_bleio_connection_get_connected(connection)) { + return common_hal_bleio_connection_get_max_packet_length(connection->connection); + } + return -1; + } + return self->characteristic->max_length; +} + +mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length( + bleio_packet_buffer_obj_t *self) { + if (self->characteristic == NULL) { + return -1; + } + + if (self->characteristic->service != NULL && + !self->characteristic->service->is_remote && + (common_hal_bleio_characteristic_get_properties(self->characteristic) & + (CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) { + // We are sending to a client via NOTIFY/INDICATE. + // Use max_packet_size since we don't track MTU dynamically here. + return MIN(self->max_packet_size, self->characteristic->max_length); + } + // Writing to remote characteristic or local without NOTIFY + return MIN(self->characteristic->max_length, self->max_packet_size); +} + +void common_hal_bleio_packet_buffer_flush(bleio_packet_buffer_obj_t *self) { + // With the completion callback, writes drain automatically. + // flush() just waits for any queued data to be sent. + while (self->pending_size > 0 && + !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + if (!send_pending(self)) { + // Couldn't send — wait and retry. + RUN_BACKGROUND_TASKS; + } + } +} + +bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) { + return self->characteristic == NULL; +} + +void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { + if (common_hal_bleio_packet_buffer_deinited(self)) { + return; + } + bleio_characteristic_clear_observer(self->characteristic); + self->characteristic = NULL; + // Free ringbuf_data allocated with m_malloc_without_collect + m_free(self->ringbuf_data); + self->ringbuf_data = NULL; + // Free outgoing buffer + m_free(self->outgoing_buffer); + self->outgoing_buffer = NULL; +} + +bool common_hal_bleio_packet_buffer_connected(bleio_packet_buffer_obj_t *self) { + if (common_hal_bleio_packet_buffer_deinited(self)) { + return false; + } + // Check if the characteristic's connection is still active. + if (self->characteristic->service != NULL && + self->characteristic->service->is_remote) { + if (self->characteristic->service->connection == mp_const_none) { + return false; + } + bleio_connection_obj_t *connection = + MP_OBJ_TO_PTR(self->characteristic->service->connection); + return common_hal_bleio_connection_get_connected(connection); + } + return true; +} diff --git a/ports/zephyr-cp/common-hal/_bleio/PacketBuffer.h b/ports/zephyr-cp/common-hal/_bleio/PacketBuffer.h new file mode 100644 index 00000000000..491852ec5fd --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/PacketBuffer.h @@ -0,0 +1,44 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include + +#include "py/obj.h" +#include "shared-bindings/_bleio/Characteristic.h" + +struct bt_conn; + +typedef void *ble_event_handler_t; + +typedef struct { + mp_obj_base_t base; + bleio_characteristic_obj_t *characteristic; + uint32_t timeout_ms; + struct ring_buf ringbuf; + uint8_t *ringbuf_data; + size_t ringbuf_size; + size_t max_packet_size; + // Outgoing pending buffer + uint8_t *outgoing_buffer; + uint16_t pending_size; + bool packet_queued; + struct bt_conn *conn; + bool client; +} bleio_packet_buffer_obj_t; + +// Called from GATT callbacks (system workqueue context) to push +// data into the PacketBuffer ring buffer with length-prefix framing. +void bleio_packet_buffer_extend(bleio_packet_buffer_obj_t *self, + struct bt_conn *conn, const uint8_t *data, size_t len); + +// Called from CCCD write callback to record the subscribing connection. +void bleio_packet_buffer_set_conn(bleio_packet_buffer_obj_t *self, + struct bt_conn *conn); diff --git a/ports/zephyr-cp/common-hal/_bleio/Service.c b/ports/zephyr-cp/common-hal/_bleio/Service.c new file mode 100644 index 00000000000..ee8cf35deee --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Service.c @@ -0,0 +1,258 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// GATT server service implementation for Zephyr. +// +// Each bleio Service owns a dynamically-allocated array of bt_gatt_attr +// (the Zephyr GATT attribute table). When a Characteristic is added, we +// append 2-4 attrs (declaration, value, optional CCC, optional CUD) and +// (re-)register the service with bt_gatt_service_register(). +// +// IMPORTANT: Zephyr's BT_UUID_GATT_PRIMARY / BT_UUID_GATT_CHRC / … macros +// expand to compound-literal pointers. Inside a function those have automatic +// storage duration and become dangling once the function returns. We therefore +// declare file-scope static const UUIDs (_uuid_primary, _uuid_chrc, …) and +// reference those from every bt_gatt_attr we build. + +#include +#include + +#include + +#include "py/gc.h" +#include "py/runtime.h" +#include "bindings/zephyr_kernel/__init__.h" +#include "shared-bindings/_bleio/Characteristic.h" +#include "shared-bindings/_bleio/Service.h" +#include "common-hal/_bleio/__init__.h" +#include "common-hal/_bleio/Characteristic.h" + +#define INITIAL_ATTR_CAPACITY 16 + +// Standard GATT UUIDs with static storage duration. +// BT_UUID_GATT_PRIMARY etc. expand to compound literals which have automatic +// storage when used inside functions - the resulting pointers dangle after the +// function returns. These static constants persist for the lifetime of the +// program. +static const struct bt_uuid_16 _uuid_primary = BT_UUID_INIT_16(BT_UUID_GATT_PRIMARY_VAL); +static const struct bt_uuid_16 _uuid_secondary = BT_UUID_INIT_16(BT_UUID_GATT_SECONDARY_VAL); +static const struct bt_uuid_16 _uuid_chrc = BT_UUID_INIT_16(BT_UUID_GATT_CHRC_VAL); +static const struct bt_uuid_16 _uuid_ccc = BT_UUID_INIT_16(BT_UUID_GATT_CCC_VAL); +static const struct bt_uuid_16 _uuid_cud = BT_UUID_INIT_16(BT_UUID_GATT_CUD_VAL); + +static void service_ensure_capacity(bleio_service_obj_t *self, size_t needed) { + if (self->attr_count + needed <= self->attr_capacity) { + return; + } + size_t new_capacity = self->attr_capacity; + while (new_capacity < self->attr_count + needed) { + new_capacity *= 2; + } + struct bt_gatt_attr *new_attrs = m_realloc(self->attrs, + new_capacity * sizeof(struct bt_gatt_attr)); + self->attrs = new_attrs; + self->attr_capacity = new_capacity; +} + +uint32_t _common_hal_bleio_service_construct(bleio_service_obj_t *self, + bleio_uuid_obj_t *uuid, bool is_secondary, + mp_obj_list_t *characteristic_list) { + self->uuid = uuid; + self->is_secondary = is_secondary; + self->is_remote = false; + self->connection = mp_const_none; + self->characteristic_list = characteristic_list; + self->start_handle = 0; + self->end_handle = 0; + self->registered = false; + + // Convert UUID to Zephyr format + bleio_uuid_to_zephyr(uuid, &self->zephyr_uuid); + + // Allocate attrs array + self->attr_capacity = INITIAL_ATTR_CAPACITY; + self->attrs = m_malloc(self->attr_capacity * sizeof(struct bt_gatt_attr)); + memset(self->attrs, 0, self->attr_capacity * sizeof(struct bt_gatt_attr)); + self->attr_count = 0; + + // Add primary/secondary service declaration at index 0 + const struct bt_uuid *svc_type_uuid = is_secondary + ? (const struct bt_uuid *)&_uuid_secondary + : (const struct bt_uuid *)&_uuid_primary; + self->attrs[0] = (struct bt_gatt_attr) { + .uuid = svc_type_uuid, + .perm = BT_GATT_PERM_READ, + .read = bt_gatt_attr_read_service, + .user_data = (void *)&self->zephyr_uuid, + }; + self->attr_count = 1; + + return 0; +} + +void common_hal_bleio_service_construct(bleio_service_obj_t *self, + bleio_uuid_obj_t *uuid, bool is_secondary) { + mp_obj_list_t *char_list = mp_obj_new_list(0, NULL); + _common_hal_bleio_service_construct(self, uuid, is_secondary, char_list); +} + +void common_hal_bleio_service_deinit(bleio_service_obj_t *self) { + if (self->registered) { + bt_gatt_service_unregister(&self->zephyr_service); + self->registered = false; + } +} + +void common_hal_bleio_service_from_remote_service(bleio_service_obj_t *self, + bleio_connection_obj_t *connection, bleio_uuid_obj_t *uuid, bool is_secondary) { + self->uuid = uuid; + self->is_secondary = is_secondary; + self->is_remote = true; + self->connection = MP_OBJ_FROM_PTR(connection); + self->characteristic_list = mp_obj_new_list(0, NULL); + self->start_handle = 0; + self->end_handle = 0; + self->registered = false; + self->attrs = NULL; + self->attr_count = 0; + self->attr_capacity = 0; + bleio_uuid_to_zephyr(uuid, &self->zephyr_uuid); +} + +bleio_uuid_obj_t *common_hal_bleio_service_get_uuid(bleio_service_obj_t *self) { + return self->uuid; +} + +mp_obj_tuple_t *common_hal_bleio_service_get_characteristics(bleio_service_obj_t *self) { + return mp_obj_new_tuple(self->characteristic_list->len, self->characteristic_list->items); +} + +bool common_hal_bleio_service_get_is_remote(bleio_service_obj_t *self) { + return self->is_remote; +} + +bool common_hal_bleio_service_get_is_secondary(bleio_service_obj_t *self) { + return self->is_secondary; +} + +void common_hal_bleio_service_add_characteristic(bleio_service_obj_t *self, + bleio_characteristic_obj_t *characteristic, + mp_buffer_info_t *initial_value_bufinfo, + const char *user_description) { + + if (self->registered) { + bt_gatt_service_unregister(&self->zephyr_service); + self->registered = false; + } + + // Calculate how many attrs we need: + // 1 = characteristic declaration, 1 = value attr + // +1 if NOTIFY|INDICATE (CCC descriptor) + // +1 if user_description + size_t attrs_needed = 2; + bool needs_ccc = (characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE)) != 0; + bool needs_user_desc = (user_description != NULL && user_description[0] != '\0'); + if (needs_ccc) { + attrs_needed++; + } + if (needs_user_desc) { + attrs_needed++; + } + + service_ensure_capacity(self, attrs_needed); + + // Map CP properties to Zephyr BT spec properties + uint8_t zephyr_props = 0; + if (characteristic->props & CHAR_PROP_BROADCAST) { + zephyr_props |= BT_GATT_CHRC_BROADCAST; + } + if (characteristic->props & CHAR_PROP_READ) { + zephyr_props |= BT_GATT_CHRC_READ; + } + if (characteristic->props & CHAR_PROP_WRITE_NO_RESPONSE) { + zephyr_props |= BT_GATT_CHRC_WRITE_WITHOUT_RESP; + } + if (characteristic->props & CHAR_PROP_WRITE) { + zephyr_props |= BT_GATT_CHRC_WRITE; + } + if (characteristic->props & CHAR_PROP_NOTIFY) { + zephyr_props |= BT_GATT_CHRC_NOTIFY; + } + if (characteristic->props & CHAR_PROP_INDICATE) { + zephyr_props |= BT_GATT_CHRC_INDICATE; + } + + // Set up the Zephyr chrc struct in the characteristic + characteristic->zephyr_chrc.uuid = &characteristic->zephyr_uuid.uuid; + characteristic->zephyr_chrc.value_handle = 0; + characteristic->zephyr_chrc.properties = zephyr_props; + + // Map permissions + uint16_t perm = bleio_security_to_zephyr_perm( + characteristic->read_perm, characteristic->write_perm, characteristic->props); + + // Attr: characteristic declaration + size_t idx = self->attr_count; + self->attrs[idx] = (struct bt_gatt_attr) { + .uuid = (const struct bt_uuid *)&_uuid_chrc, + .perm = BT_GATT_PERM_READ, + .read = bt_gatt_attr_read_chrc, + .user_data = &characteristic->zephyr_chrc, + }; + idx++; + + // Attr: characteristic value (UUID points into characteristic, which persists) + characteristic->value_attr_index = idx; + self->attrs[idx] = (struct bt_gatt_attr) { + .uuid = &characteristic->zephyr_uuid.uuid, + .perm = perm, + .read = (characteristic->props & CHAR_PROP_READ) ? bleio_char_read_cb : NULL, + .write = (characteristic->props & (CHAR_PROP_WRITE | CHAR_PROP_WRITE_NO_RESPONSE)) ? bleio_char_write_cb : NULL, + .user_data = characteristic, + }; + idx++; + + // Attr: CCC descriptor (for NOTIFY/INDICATE) + if (needs_ccc) { + characteristic->zephyr_ccc = (struct bt_gatt_ccc_managed_user_data) + BT_GATT_CCC_MANAGED_USER_DATA_INIT(bleio_ccc_changed_cb, bleio_ccc_write_cb, NULL); + self->attrs[idx] = (struct bt_gatt_attr) { + .uuid = (const struct bt_uuid *)&_uuid_ccc, + .perm = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, + .read = bt_gatt_attr_read_ccc, + .write = bt_gatt_attr_write_ccc, + .user_data = &characteristic->zephyr_ccc, + }; + idx++; + } + + // Attr: user description descriptor + if (needs_user_desc) { + self->attrs[idx] = (struct bt_gatt_attr) { + .uuid = (const struct bt_uuid *)&_uuid_cud, + .perm = BT_GATT_PERM_READ, + .read = bt_gatt_attr_read_cud, + .user_data = (void *)user_description, + }; + idx++; + } + + self->attr_count = idx; + + // Add characteristic to list + mp_obj_list_append(MP_OBJ_FROM_PTR(self->characteristic_list), + MP_OBJ_FROM_PTR(characteristic)); + + // Register the service + self->zephyr_service.attrs = self->attrs; + self->zephyr_service.attr_count = self->attr_count; + int err = bt_gatt_service_register(&self->zephyr_service); + if (err != 0) { + raise_zephyr_error(err); + } + self->registered = true; +} diff --git a/ports/zephyr-cp/common-hal/_bleio/Service.h b/ports/zephyr-cp/common-hal/_bleio/Service.h new file mode 100644 index 00000000000..8c820fd204e --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/Service.h @@ -0,0 +1,32 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" +#include "py/objlist.h" +#include "common-hal/_bleio/UUID.h" + +typedef struct bleio_service_obj { + mp_obj_base_t base; + bleio_uuid_obj_t *uuid; + mp_obj_t connection; + mp_obj_list_t *characteristic_list; + uint16_t start_handle; + uint16_t end_handle; + bool is_remote; + bool is_secondary; + // Zephyr GATT server fields: + struct bt_gatt_service zephyr_service; + struct bt_gatt_attr *attrs; + size_t attr_count; + size_t attr_capacity; + struct bt_uuid_128 zephyr_uuid; + bool registered; +} bleio_service_obj_t; diff --git a/ports/zephyr-cp/common-hal/_bleio/UUID.c b/ports/zephyr-cp/common-hal/_bleio/UUID.c new file mode 100644 index 00000000000..9e963b1b0bc --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/UUID.c @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/runtime.h" +#include "shared-bindings/_bleio/UUID.h" + +void common_hal_bleio_uuid_construct(bleio_uuid_obj_t *self, mp_int_t uuid16, const uint8_t uuid128[16]) { + self->uuid16 = (uint16_t)uuid16; + if (uuid128 == NULL) { + // 16-bit UUID — only bytes 12-13 matter; rest is zero (matching ble_hci). + self->size = BT_UUID_SIZE_16; + memset(self->uuid128, 0, 16); + self->uuid128[12] = uuid16 & 0xff; + self->uuid128[13] = (uuid16 >> 8) & 0xff; + } else { + // 128-bit UUID — uuid128 has bytes 12-13 zeroed, uuid16 is extracted from them + self->size = BT_UUID_SIZE_128; + memcpy(self->uuid128, uuid128, 16); + // Restore the 16-bit portion from uuid16 into bytes 12-13 (little-endian). + self->uuid128[12] = uuid16 & 0xff; + self->uuid128[13] = uuid16 >> 8; + } +} + +uint32_t common_hal_bleio_uuid_get_uuid16(bleio_uuid_obj_t *self) { + return self->uuid16; +} + +void common_hal_bleio_uuid_get_uuid128(bleio_uuid_obj_t *self, uint8_t uuid128[16]) { + memcpy(uuid128, self->uuid128, 16); +} + +uint32_t common_hal_bleio_uuid_get_size(bleio_uuid_obj_t *self) { + return self->size == BT_UUID_SIZE_16 ? 16 : 128; +} + +void common_hal_bleio_uuid_pack_into(bleio_uuid_obj_t *self, uint8_t *buf) { + if (self->size == BT_UUID_SIZE_16) { + buf[0] = self->uuid128[12]; + buf[1] = self->uuid128[13]; + } else { + memcpy(buf, self->uuid128, 16); + } +} diff --git a/ports/zephyr-cp/common-hal/_bleio/UUID.h b/ports/zephyr-cp/common-hal/_bleio/UUID.h new file mode 100644 index 00000000000..9a0743a1b60 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/UUID.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t uuid128[16]; + uint8_t size; // BT_UUID_SIZE_16 (2) or BT_UUID_SIZE_128 (16) + uint16_t uuid16; +} bleio_uuid_obj_t; diff --git a/ports/zephyr-cp/common-hal/_bleio/__init__.c b/ports/zephyr-cp/common-hal/_bleio/__init__.c new file mode 100644 index 00000000000..e3c208a7d1d --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/__init__.c @@ -0,0 +1,182 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/runtime.h" +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Adapter.h" +#include "common-hal/_bleio/Adapter.h" +#include "common-hal/_bleio/__init__.h" +#include "bindings/zephyr_kernel/__init__.h" +#include "common-hal/_bleio/Connection.h" +#include "supervisor/shared/bluetooth/bluetooth.h" +#include "supervisor/shared/tick.h" + +// The singleton _bleio.Adapter object +bleio_adapter_obj_t common_hal_bleio_adapter_obj; + +void common_hal_bleio_init(void) { + common_hal_bleio_adapter_obj.base.type = &bleio_adapter_type; + bleio_adapter_reset(&common_hal_bleio_adapter_obj); + bleio_connection_register_auth_callbacks(); +} + +void bleio_user_reset(void) { + if (common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { + // Stop any user scanning or advertising. + common_hal_bleio_adapter_stop_scan(&common_hal_bleio_adapter_obj); + common_hal_bleio_adapter_stop_advertising(&common_hal_bleio_adapter_obj); + } + + // Maybe start advertising the BLE workflow. + supervisor_bluetooth_background(); +} + +void bleio_reset(void) { + common_hal_bleio_adapter_obj.base.type = &bleio_adapter_type; + if (!common_hal_bleio_adapter_get_enabled(&common_hal_bleio_adapter_obj)) { + return; + } + + supervisor_stop_bluetooth(); + bleio_adapter_reset(&common_hal_bleio_adapter_obj); + common_hal_bleio_adapter_set_enabled(&common_hal_bleio_adapter_obj, false); + supervisor_start_bluetooth(); +} + +void common_hal_bleio_gc_collect(void) { + bleio_adapter_gc_collect(&common_hal_bleio_adapter_obj); +} + +// ======================================================================= +// Shared synchronous GATT helpers +// ======================================================================= + +typedef struct { + uint8_t *buf; + size_t buf_len; + size_t read_len; + volatile bool done; + volatile int err; +} gattc_read_ctx_t; + +typedef struct { + volatile bool done; + volatile int err; +} gattc_write_ctx_t; + +static gattc_read_ctx_t *active_read_ctx; +static gattc_write_ctx_t *active_write_ctx; +static struct bt_gatt_read_params read_params; +static struct bt_gatt_write_params write_params; + +static uint8_t on_gattc_read(struct bt_conn *conn, uint8_t err, + struct bt_gatt_read_params *params, + const void *data, uint16_t length) { + gattc_read_ctx_t *ctx = active_read_ctx; + if (ctx == NULL) { + return BT_GATT_ITER_STOP; + } + + if (err) { + ctx->err = err; + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + if (data == NULL || length == 0) { + ctx->done = true; + return BT_GATT_ITER_STOP; + } + + size_t copy_len = length; + if (ctx->read_len + copy_len > ctx->buf_len) { + copy_len = ctx->buf_len - ctx->read_len; + } + if (copy_len > 0) { + memcpy(ctx->buf + ctx->read_len, data, copy_len); + ctx->read_len += copy_len; + } + + ctx->done = true; + return BT_GATT_ITER_STOP; +} + +static void on_gattc_write(struct bt_conn *conn, uint8_t err, + struct bt_gatt_write_params *params) { + gattc_write_ctx_t *ctx = active_write_ctx; + if (ctx == NULL) { + return; + } + ctx->err = err; + ctx->done = true; +} + +size_t bleio_gattc_read_sync(struct bt_conn *conn, uint16_t handle, + uint8_t *buf, size_t len) { + gattc_read_ctx_t ctx = { + .buf = buf, + .buf_len = len, + .read_len = 0, + .done = false, + .err = 0, + }; + active_read_ctx = &ctx; + + memset(&read_params, 0, sizeof(read_params)); + read_params.func = on_gattc_read; + read_params.handle_count = 1; + read_params.single.handle = handle; + read_params.single.offset = 0; + + int err = bt_gatt_read(conn, &read_params); + if (err != 0) { + active_read_ctx = NULL; + raise_zephyr_error(err); + } + + while (!ctx.done) { + RUN_BACKGROUND_TASKS; + } + active_read_ctx = NULL; + + if (ctx.err != 0) { + raise_zephyr_error(ctx.err); + } + + return ctx.read_len; +} + +void bleio_gattc_write_sync(struct bt_conn *conn, uint16_t handle, + const uint8_t *data, size_t len) { + gattc_write_ctx_t ctx = { + .done = false, + .err = 0, + }; + active_write_ctx = &ctx; + + memset(&write_params, 0, sizeof(write_params)); + write_params.func = on_gattc_write; + write_params.handle = handle; + write_params.offset = 0; + write_params.data = data; + write_params.length = len; + + int err = bt_gatt_write(conn, &write_params); + if (err != 0) { + active_write_ctx = NULL; + raise_zephyr_error(err); + } + + while (!ctx.done) { + RUN_BACKGROUND_TASKS; + } + active_write_ctx = NULL; + + if (ctx.err != 0) { + raise_zephyr_error(ctx.err); + } +} diff --git a/ports/zephyr-cp/common-hal/_bleio/__init__.h b/ports/zephyr-cp/common-hal/_bleio/__init__.h new file mode 100644 index 00000000000..63eec415311 --- /dev/null +++ b/ports/zephyr-cp/common-hal/_bleio/__init__.h @@ -0,0 +1,42 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include +#include +#include + +#include "common-hal/_bleio/UUID.h" + +// Convert a CircuitPython bleio UUID to a Zephyr bt_uuid stored in caller- +// provided bt_uuid_128 storage. For 16-bit UUIDs we reinterpret the storage +// as bt_uuid_16 and write .val (at offset 2, matching Zephyr's struct layout). +// For 128-bit UUIDs the 16-byte value is copied directly into bt_uuid_128.val. +// The result can be used as `&out->uuid` wherever a `const struct bt_uuid *` +// is needed; Zephyr dispatches on the .type field at runtime. +static inline void bleio_uuid_to_zephyr(const bleio_uuid_obj_t *cp_uuid, + struct bt_uuid_128 *out) { + if (cp_uuid->size == BT_UUID_SIZE_16) { + out->uuid.type = BT_UUID_TYPE_16; + ((struct bt_uuid_16 *)out)->val = + (cp_uuid->uuid128[13] << 8) | cp_uuid->uuid128[12]; + } else { + out->uuid.type = BT_UUID_TYPE_128; + // Both CP and Zephyr store UUID bytes in little-endian order. + memcpy(out->val, cp_uuid->uuid128, 16); + } +} + +// Shared synchronous GATT helpers — wrap Zephyr's async bt_gatt_read/write +// into a blocking call with RUN_BACKGROUND_TASKS spinning. +size_t bleio_gattc_read_sync(struct bt_conn *conn, uint16_t handle, + uint8_t *buf, size_t len); +void bleio_gattc_write_sync(struct bt_conn *conn, uint16_t handle, + const uint8_t *data, size_t len); diff --git a/ports/zephyr-cp/common-hal/audiobusio/I2SOut.c b/ports/zephyr-cp/common-hal/audiobusio/I2SOut.c new file mode 100644 index 00000000000..27577b59cd7 --- /dev/null +++ b/ports/zephyr-cp/common-hal/audiobusio/I2SOut.c @@ -0,0 +1,308 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/audiobusio/I2SOut.h" + +#include +#include +#include +#include +#include + +#include "bindings/zephyr_kernel/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-module/audiocore/__init__.h" +#include "py/runtime.h" + +#if CIRCUITPY_AUDIOBUSIO_I2SOUT + +#define AUDIO_THREAD_STACK_SIZE 2048 +#define AUDIO_THREAD_PRIORITY 5 + +// Forward declarations +static void fill_buffer(audiobusio_i2sout_obj_t *self, uint8_t *buffer, size_t buffer_size); +static void audio_thread_func(void *self_in, void *unused1, void *unused2); + +// Helper function for Zephyr-specific initialization from device tree +mp_obj_t common_hal_audiobusio_i2sout_construct_from_device(audiobusio_i2sout_obj_t *self, const struct device *i2s_device) { + self->base.type = &audiobusio_i2sout_type; + self->i2s_dev = i2s_device; + self->left_justified = false; + self->playing = false; + self->paused = false; + self->sample = NULL; + self->slab_buffer = NULL; + self->thread_stack = NULL; + self->thread_id = NULL; + self->block_size = 0; + + return MP_OBJ_FROM_PTR(self); +} + +// Standard audiobusio construct - not used in Zephyr port (devices come from device tree) +void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, + const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, bool left_justified, + bool external_clock) { + if (external_clock) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_external_clock); + } + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("Use device tree to define %q devices"), MP_QSTR_I2S); +} + +bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t *self) { + return self->i2s_dev == NULL; +} + +void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self) { + if (common_hal_audiobusio_i2sout_deinited(self)) { + return; + } + + // Stop playback (which will free buffers) + common_hal_audiobusio_i2sout_stop(self); + + // Note: Pins and I2S device are managed by Zephyr, not released here + self->i2s_dev = NULL; +} + +static void fill_buffer(audiobusio_i2sout_obj_t *self, uint8_t *buffer, size_t buffer_size) { + if (self->sample == NULL || self->paused || self->stopping) { + // Fill with silence + memset(buffer, 0, buffer_size); + return; + } + + uint32_t bytes_filled = 0; + while (bytes_filled < buffer_size) { + uint8_t *sample_buffer; + uint32_t sample_buffer_length; + + audioio_get_buffer_result_t result = audiosample_get_buffer( + self->sample, false, 0, &sample_buffer, &sample_buffer_length); + + if (result == GET_BUFFER_ERROR) { + // Error getting buffer, stop playback + self->stopping = true; + memset(buffer + bytes_filled, 0, buffer_size - bytes_filled); + return; + } + + // Copy the returned data first, even when this is the final buffer + // (GET_BUFFER_DONE). A single-buffer sample returns its entire buffer + // together with GET_BUFFER_DONE on the first call, so handling DONE + // before the copy would drop the audio and produce silence. + uint32_t bytes_to_copy = sample_buffer_length; + if (bytes_filled + bytes_to_copy > buffer_size) { + bytes_to_copy = buffer_size - bytes_filled; + } + + memcpy(buffer + bytes_filled, sample_buffer, bytes_to_copy); + bytes_filled += bytes_to_copy; + + if (result == GET_BUFFER_DONE) { + if (self->loop) { + // Reset to beginning + audiosample_reset_buffer(self->sample, false, 0); + } else { + // Final buffer copied; stop once this block drains. + self->stopping = true; + i2s_trigger(self->i2s_dev, I2S_DIR_TX, I2S_TRIGGER_DRAIN); + memset(buffer + bytes_filled, 0, buffer_size - bytes_filled); + return; + } + } + } +} + +static void audio_thread_func(void *self_in, void *unused1, void *unused2) { + audiobusio_i2sout_obj_t *self = (audiobusio_i2sout_obj_t *)self_in; + + while (!self->stopping) { + uint8_t *next_buffer = NULL; + // Wait until I2S has freed the buffer it is sending. + if (k_mem_slab_alloc(&self->mem_slab, (void **)&next_buffer, K_FOREVER) != 0) { + break; + } + if (self->stopping) { + // Stopping so break. + k_mem_slab_free(&self->mem_slab, next_buffer); + break; + } + fill_buffer(self, next_buffer, self->block_size); + + // Write to I2S + int ret = i2s_write(self->i2s_dev, next_buffer, self->block_size); + if (ret < 0) { + printk("i2s_write failed: %d\n", ret); + k_mem_slab_free(&self->mem_slab, next_buffer); + // Error writing, stop playback + self->playing = false; + break; + } + } +} + +void common_hal_audiobusio_i2sout_play(audiobusio_i2sout_obj_t *self, + mp_obj_t sample, bool loop) { + // Stop any existing playback + if (self->playing) { + common_hal_audiobusio_i2sout_stop(self); + } + + audiosample_check(sample); + + // Get sample information + uint8_t bits_per_sample = audiosample_get_bits_per_sample(sample); + uint32_t sample_rate = audiosample_get_sample_rate(sample); + uint8_t channel_count = audiosample_get_channel_count(sample); + + // Store sample parameters + self->sample = sample; + self->loop = loop; + self->bytes_per_sample = bits_per_sample / 8; + self->channel_count = channel_count; + self->stopping = false; + + // Get buffer structure from the sample + bool single_buffer, samples_signed; + uint32_t max_buffer_length; + uint8_t sample_spacing; + audiosample_get_buffer_structure(sample, /* single_channel_output */ false, + &single_buffer, &samples_signed, &max_buffer_length, &sample_spacing); + + // Use max_buffer_length from the sample as the block size + self->block_size = max_buffer_length; + if (channel_count == 1) { + // Make room for stereo samples. + self->block_size *= 2; + } + size_t block_size = self->block_size; + uint32_t num_blocks = 4; // Use 4 blocks for buffering + + // Allocate memory slab buffer + self->slab_buffer = m_malloc(self->block_size * num_blocks); + + // Initialize memory slab + int ret = k_mem_slab_init(&self->mem_slab, self->slab_buffer, block_size, num_blocks); + CHECK_ZEPHYR_RESULT(ret); + + // Configure I2S + struct i2s_config config; + config.word_size = bits_per_sample; + config.channels = 2; + config.format = self->left_justified ? I2S_FMT_DATA_FORMAT_LEFT_JUSTIFIED : I2S_FMT_DATA_FORMAT_I2S; + config.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER; + config.frame_clk_freq = sample_rate; + config.mem_slab = &self->mem_slab; + config.block_size = block_size; + config.timeout = 1000; // Not a k_timeout_t. In milliseconds. + + // Configure returns EINVAL if the I2S device is not ready. We loop on this + // because it should be ready after it comes to a complete stop. + ret = -EAGAIN; + while (ret == -EAGAIN) { + ret = i2s_configure(self->i2s_dev, I2S_DIR_TX, &config); + } + if (ret != 0) { + common_hal_audiobusio_i2sout_stop(self); + raise_zephyr_error(ret); + } + + // Fill every slab before starting playback to avoid underruns. + for (uint32_t i = 0; i < num_blocks; i++) { + uint8_t *buf = NULL; + k_mem_slab_alloc(&self->mem_slab, (void **)&buf, K_NO_WAIT); + fill_buffer(self, buf, block_size); + ret = i2s_write(self->i2s_dev, buf, block_size); + if (ret < 0) { + printk("i2s_write failed: %d\n", ret); + k_mem_slab_free(&self->mem_slab, buf); + common_hal_audiobusio_i2sout_stop(self); + raise_zephyr_error(ret); + } + } + + // Allocate thread stack with proper MPU alignment for HW stack protection + self->thread_stack = k_thread_stack_alloc(AUDIO_THREAD_STACK_SIZE, 0); + + // Create and start audio processing thread + self->thread_id = k_thread_create(&self->thread, self->thread_stack, + AUDIO_THREAD_STACK_SIZE, + audio_thread_func, + self, NULL, NULL, + AUDIO_THREAD_PRIORITY, 0, K_NO_WAIT); + // Start I2S + ret = i2s_trigger(self->i2s_dev, I2S_DIR_TX, I2S_TRIGGER_START); + if (ret < 0) { + common_hal_audiobusio_i2sout_stop(self); + raise_zephyr_error(ret); + } + + self->playing = true; +} + +void common_hal_audiobusio_i2sout_stop(audiobusio_i2sout_obj_t *self) { + if (!self->playing) { + return; + } + + self->playing = false; + self->paused = false; + self->stopping = true; + + // Stop I2S + i2s_trigger(self->i2s_dev, I2S_DIR_TX, I2S_TRIGGER_DROP); + + // Wait for thread to finish + if (self->thread_id != NULL) { + k_thread_join(self->thread_id, K_FOREVER); + self->thread_id = NULL; + } + + // Free thread stack + if (self->thread_stack != NULL) { + k_thread_stack_free(self->thread_stack); + self->thread_stack = NULL; + } + + // Free buffers + if (self->slab_buffer != NULL) { + m_free(self->slab_buffer); + self->slab_buffer = NULL; + } + + self->sample = NULL; +} + +bool common_hal_audiobusio_i2sout_get_playing(audiobusio_i2sout_obj_t *self) { + return self->playing; +} + +void common_hal_audiobusio_i2sout_pause(audiobusio_i2sout_obj_t *self) { + if (!self->playing || self->paused) { + return; + } + + self->paused = true; + i2s_trigger(self->i2s_dev, I2S_DIR_TX, I2S_TRIGGER_STOP); +} + +void common_hal_audiobusio_i2sout_resume(audiobusio_i2sout_obj_t *self) { + if (!self->playing || !self->paused) { + return; + } + + self->paused = false; + // Thread will automatically resume filling buffers + i2s_trigger(self->i2s_dev, I2S_DIR_TX, I2S_TRIGGER_START); +} + +bool common_hal_audiobusio_i2sout_get_paused(audiobusio_i2sout_obj_t *self) { + return self->paused; +} + +#endif // CIRCUITPY_AUDIOBUSIO_I2SOUT diff --git a/ports/zephyr-cp/common-hal/audiobusio/I2SOut.h b/ports/zephyr-cp/common-hal/audiobusio/I2SOut.h new file mode 100644 index 00000000000..916471fa833 --- /dev/null +++ b/ports/zephyr-cp/common-hal/audiobusio/I2SOut.h @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" +#include "shared-module/audiocore/__init__.h" + +#include +#include +#include + +#if CIRCUITPY_AUDIOBUSIO_I2SOUT + +typedef struct { + mp_obj_base_t base; + const struct device *i2s_dev; + const mcu_pin_obj_t *bit_clock; + const mcu_pin_obj_t *word_select; + const mcu_pin_obj_t *data; + const mcu_pin_obj_t *main_clock; + mp_obj_t sample; + struct k_mem_slab mem_slab; + char *slab_buffer; + struct k_thread thread; + k_thread_stack_t *thread_stack; + k_tid_t thread_id; + size_t block_size; + bool left_justified; + bool playing; + bool paused; + bool loop; + bool stopping; + bool single_buffer; + uint8_t bytes_per_sample; + uint8_t channel_count; +} audiobusio_i2sout_obj_t; + +mp_obj_t common_hal_audiobusio_i2sout_construct_from_device(audiobusio_i2sout_obj_t *self, const struct device *i2s_device); + +void i2sout_reset(void); + +#endif // CIRCUITPY_AUDIOBUSIO_I2SOUT diff --git a/ports/zephyr-cp/common-hal/audiobusio/PDMIn.c b/ports/zephyr-cp/common-hal/audiobusio/PDMIn.c new file mode 100644 index 00000000000..3d3cfef5258 --- /dev/null +++ b/ports/zephyr-cp/common-hal/audiobusio/PDMIn.c @@ -0,0 +1,39 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/audiobusio/PDMIn.h" + +#include "py/runtime.h" + +#if CIRCUITPY_AUDIOBUSIO_PDMIN + +void common_hal_audiobusio_pdmin_construct(audiobusio_pdmin_obj_t *self, + const mcu_pin_obj_t *clock_pin, const mcu_pin_obj_t *data_pin, + uint32_t sample_rate, uint8_t bit_depth, bool mono, uint8_t oversample) { + mp_raise_NotImplementedError(NULL); +} + +bool common_hal_audiobusio_pdmin_deinited(audiobusio_pdmin_obj_t *self) { + return true; +} + +void common_hal_audiobusio_pdmin_deinit(audiobusio_pdmin_obj_t *self) { +} + +uint8_t common_hal_audiobusio_pdmin_get_bit_depth(audiobusio_pdmin_obj_t *self) { + return 0; +} + +uint32_t common_hal_audiobusio_pdmin_get_sample_rate(audiobusio_pdmin_obj_t *self) { + return 0; +} + +uint32_t common_hal_audiobusio_pdmin_record_to_buffer(audiobusio_pdmin_obj_t *self, + uint16_t *output_buffer, uint32_t output_buffer_length) { + return 0; +} + +#endif // CIRCUITPY_AUDIOBUSIO_PDMIN diff --git a/ports/zephyr-cp/common-hal/audiobusio/PDMIn.h b/ports/zephyr-cp/common-hal/audiobusio/PDMIn.h new file mode 100644 index 00000000000..195a436f3cf --- /dev/null +++ b/ports/zephyr-cp/common-hal/audiobusio/PDMIn.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "common-hal/microcontroller/Pin.h" + +#if CIRCUITPY_AUDIOBUSIO_PDMIN + +typedef struct { + mp_obj_base_t base; +} audiobusio_pdmin_obj_t; + +#endif // CIRCUITPY_AUDIOBUSIO_PDMIN diff --git a/ports/zephyr-cp/common-hal/audiobusio/__init__.c b/ports/zephyr-cp/common-hal/audiobusio/__init__.c new file mode 100644 index 00000000000..5d2e802904d --- /dev/null +++ b/ports/zephyr-cp/common-hal/audiobusio/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// No special initialization required for audiobusio diff --git a/ports/zephyr-cp/common-hal/audiobusio/__init__.h b/ports/zephyr-cp/common-hal/audiobusio/__init__.h new file mode 100644 index 00000000000..8ba7882bf94 --- /dev/null +++ b/ports/zephyr-cp/common-hal/audiobusio/__init__.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// No common definitions needed for audiobusio diff --git a/ports/zephyr-cp/common-hal/busio/I2C.c b/ports/zephyr-cp/common-hal/busio/I2C.c new file mode 100644 index 00000000000..84e95721b27 --- /dev/null +++ b/ports/zephyr-cp/common-hal/busio/I2C.c @@ -0,0 +1,152 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/runtime.h" + +#include +#include +#include + +// Helper function for Zephyr-specific initialization from device tree +mp_obj_t common_hal_busio_i2c_construct_from_device(busio_i2c_obj_t *self, const struct device *i2c_device) { + self->base.type = &busio_i2c_type; + self->i2c_device = i2c_device; + k_mutex_init(&self->mutex); + self->has_lock = false; + return MP_OBJ_FROM_PTR(self); +} + +// Standard busio construct - not used in Zephyr port (devices come from device tree) +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, + uint32_t frequency, uint32_t timeout_ms) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("Use device tree to define %q devices"), MP_QSTR_I2C); +} + +bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self) { + // Always leave it active (managed by Zephyr) + return false; +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return; + } + // Always leave it active (managed by Zephyr) +} + +void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self) { + // Not needed for Zephyr port +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + if (common_hal_busio_i2c_deinited(self)) { + return false; + } + + // Try a zero-length write to probe for device + uint8_t dummy; + int ret = i2c_write(self->i2c_device, &dummy, 0, addr); + return ret == 0; +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + if (common_hal_busio_i2c_deinited(self)) { + return false; + } + + self->has_lock = k_mutex_lock(&self->mutex, K_NO_WAIT) == 0; + return self->has_lock; +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; + k_mutex_unlock(&self->mutex); +} + +mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len) { + + if (common_hal_busio_i2c_deinited(self)) { + return -MP_EIO; + } + + int ret = i2c_write(self->i2c_device, data, len, addr); + if (ret != 0) { + // Map Zephyr error codes to errno + if (ret == -ENOTSUP) { + return -MP_EOPNOTSUPP; + } else if (ret == -EIO || ret == -ENXIO) { + return -MP_EIO; + } else if (ret == -EBUSY) { + return -MP_EBUSY; + } + return -MP_EIO; + } + + return 0; +} + +mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *data, size_t len) { + + if (common_hal_busio_i2c_deinited(self)) { + return -MP_EIO; + } + + if (len == 0) { + return 0; + } + + int ret = i2c_read(self->i2c_device, data, len, addr); + if (ret != 0) { + // Map Zephyr error codes to errno + if (ret == -ENOTSUP) { + return -MP_EOPNOTSUPP; + } else if (ret == -EIO || ret == -ENXIO) { + return -MP_EIO; + } else if (ret == -EBUSY) { + return -MP_EBUSY; + } + return -MP_EIO; + } + + return 0; +} + +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len) { + + if (common_hal_busio_i2c_deinited(self)) { + return -MP_EIO; + } + + // Use i2c_write_read for combined transaction with repeated start + int ret = i2c_write_read(self->i2c_device, addr, out_data, out_len, in_data, in_len); + if (ret != 0) { + // Map Zephyr error codes to errno + if (ret == -ENOTSUP) { + return -MP_EOPNOTSUPP; + } else if (ret == -EIO || ret == -ENXIO) { + return -MP_EIO; + } else if (ret == -EBUSY) { + return -MP_EBUSY; + } + return -MP_EIO; + } + + return 0; +} + +void common_hal_busio_i2c_never_reset(busio_i2c_obj_t *self) { + // Not needed for Zephyr port (devices are managed by Zephyr) +} diff --git a/ports/zephyr-cp/common-hal/busio/I2C.h b/ports/zephyr-cp/common-hal/busio/I2C.h new file mode 100644 index 00000000000..4fa877739b7 --- /dev/null +++ b/ports/zephyr-cp/common-hal/busio/I2C.h @@ -0,0 +1,20 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include + +typedef struct { + mp_obj_base_t base; + const struct device *i2c_device; + struct k_mutex mutex; + bool has_lock; +} busio_i2c_obj_t; + +// Helper function to construct from Zephyr device tree device +mp_obj_t common_hal_busio_i2c_construct_from_device(busio_i2c_obj_t *self, const struct device *i2c_device); diff --git a/ports/zephyr-cp/common-hal/busio/SPI.c b/ports/zephyr-cp/common-hal/busio/SPI.c new file mode 100644 index 00000000000..2864c90b490 --- /dev/null +++ b/ports/zephyr-cp/common-hal/busio/SPI.c @@ -0,0 +1,281 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/busio/SPI.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/gc.h" +#include "shared/runtime/interrupt_char.h" +#include "supervisor/port.h" + +#include +#include +#include + +// Helper function for Zephyr-specific initialization from device tree +mp_obj_t common_hal_busio_spi_construct_from_device(busio_spi_obj_t *self, const struct device *spi_device) { + self->base.type = &busio_spi_type; + self->spi_device = spi_device; + k_mutex_init(&self->mutex); + self->has_lock = false; + self->active_config = 0; + + k_poll_signal_init(&self->signal); + + // Default configuration for both config slots + self->config[0].frequency = 100000; + self->config[0].operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_LINES_SINGLE; + self->config[1].frequency = 100000; + self->config[1].operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_LINES_SINGLE; + + return MP_OBJ_FROM_PTR(self); +} + +// Standard busio construct - not used in Zephyr port (devices come from device tree) +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *miso, bool half_duplex) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("Use device tree to define %q devices"), MP_QSTR_SPI); +} + +bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) { + // Always leave it active + return false; +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return; + } + // Always leave it active +} + +void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self) { + // Not needed for Zephyr port +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + if (common_hal_busio_spi_deinited(self)) { + return false; + } + + self->has_lock = k_mutex_lock(&self->mutex, K_NO_WAIT) == 0; + return self->has_lock; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; + k_mutex_unlock(&self->mutex); +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + if (common_hal_busio_spi_deinited(self)) { + return false; + } + + // Set operation mode based on polarity and phase + uint16_t operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(bits) | SPI_LINES_SINGLE; + + if (polarity) { + operation |= SPI_MODE_CPOL; + } + if (phase) { + operation |= SPI_MODE_CPHA; + } + + // Check if settings have changed. We must switch to the other config slot if they have because + // Zephyr drivers are allowed to use the pointer value to know if it has changed. + struct spi_config *current_config = &self->config[self->active_config]; + if (current_config->frequency != baudrate || current_config->operation != operation) { + // Settings changed, switch to the other config slot + self->active_config = 1 - self->active_config; + + // Update the new active configuration + self->config[self->active_config].frequency = baudrate; + self->config[self->active_config].operation = operation; + } + + return true; +} + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len) { + if (common_hal_busio_spi_deinited(self)) { + return false; + } + + if (len == 0) { + return true; + } + + const struct spi_buf tx_buf = { + .buf = (void *)data, + .len = len + }; + const struct spi_buf_set tx = { + .buffers = &tx_buf, + .count = 1 + }; + + // Initialize the signal for async operation + k_poll_signal_reset(&self->signal); + + int ret = spi_transceive_signal(self->spi_device, &self->config[self->active_config], &tx, NULL, &self->signal); + if (ret != 0) { + return false; + } + + // Wait for the transfer to complete while running background tasks + int signaled = 0; + int result = 0; + while (!signaled && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + k_poll_signal_check(&self->signal, &signaled, &result); + } + + return signaled && result == 0; +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value) { + if (common_hal_busio_spi_deinited(self)) { + return false; + } + + if (len == 0) { + return true; + } + + // For read, we need to write dummy bytes + // We'll allocate a temporary buffer if write_value is not 0 + uint8_t *tx_data = NULL; + bool need_free = false; + bool used_port_malloc = false; + + if (write_value != 0) { + // Use port_malloc if GC isn't active, otherwise use m_malloc + if (gc_alloc_possible()) { + tx_data = m_malloc(len); + } else { + tx_data = port_malloc(len, false); + used_port_malloc = true; + } + if (tx_data == NULL) { + return false; + } + memset(tx_data, write_value, len); + need_free = true; + } + + const struct spi_buf tx_buf = { + .buf = tx_data, + .len = tx_data ? len : 0 + }; + const struct spi_buf_set tx = { + .buffers = &tx_buf, + .count = tx_data ? 1 : 0 + }; + + const struct spi_buf rx_buf = { + .buf = data, + .len = len + }; + const struct spi_buf_set rx = { + .buffers = &rx_buf, + .count = 1 + }; + + // Initialize the signal for async operation + k_poll_signal_reset(&self->signal); + + int ret = spi_transceive_signal(self->spi_device, &self->config[self->active_config], &tx, &rx, &self->signal); + + if (need_free) { + if (used_port_malloc) { + port_free(tx_data); + } else { + m_free(tx_data); + } + } + + if (ret != 0) { + return false; + } + + // Wait for the transfer to complete while running background tasks + int signaled = 0; + int result = 0; + while (!signaled && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + k_poll_signal_check(&self->signal, &signaled, &result); + } + + return signaled && result == 0; +} + +bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, const uint8_t *data_out, uint8_t *data_in, size_t len) { + if (common_hal_busio_spi_deinited(self)) { + return false; + } + + if (len == 0) { + return true; + } + + const struct spi_buf tx_buf = { + .buf = (void *)data_out, + .len = len + }; + const struct spi_buf_set tx = { + .buffers = &tx_buf, + .count = 1 + }; + + const struct spi_buf rx_buf = { + .buf = data_in, + .len = len + }; + const struct spi_buf_set rx = { + .buffers = &rx_buf, + .count = 1 + }; + + // Initialize the signal for async operation + k_poll_signal_reset(&self->signal); + + int ret = spi_transceive_signal(self->spi_device, &self->config[self->active_config], &tx, &rx, &self->signal); + if (ret != 0) { + return false; + } + + // Wait for the transfer to complete while running background tasks + int signaled = 0; + int result = 0; + while (!signaled && !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + k_poll_signal_check(&self->signal, &signaled, &result); + } + + return signaled && result == 0; +} + +uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t *self) { + return self->config[self->active_config].frequency; +} + +uint8_t common_hal_busio_spi_get_phase(busio_spi_obj_t *self) { + return (self->config[self->active_config].operation & SPI_MODE_CPHA) ? 1 : 0; +} + +uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self) { + return (self->config[self->active_config].operation & SPI_MODE_CPOL) ? 1 : 0; +} + +void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) { + // Not needed for Zephyr port (devices are managed by Zephyr) +} diff --git a/ports/zephyr-cp/common-hal/busio/SPI.h b/ports/zephyr-cp/common-hal/busio/SPI.h new file mode 100644 index 00000000000..87411c9825c --- /dev/null +++ b/ports/zephyr-cp/common-hal/busio/SPI.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include +#include + +typedef struct { + mp_obj_base_t base; + const struct device *spi_device; + struct k_mutex mutex; + bool has_lock; + struct spi_config config[2]; // Two configs for pointer comparison by driver + uint8_t active_config; // Index of currently active config (0 or 1) + struct k_poll_signal signal; +} busio_spi_obj_t; + +// Helper function for Zephyr-specific initialization from device tree +mp_obj_t common_hal_busio_spi_construct_from_device(busio_spi_obj_t *self, const struct device *spi_device); diff --git a/ports/zephyr-cp/common-hal/busio/UART.c b/ports/zephyr-cp/common-hal/busio/UART.c new file mode 100644 index 00000000000..af1de0e9023 --- /dev/null +++ b/ports/zephyr-cp/common-hal/busio/UART.c @@ -0,0 +1,156 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/busio/UART.h" + +#include "shared/runtime/interrupt_char.h" +#include "py/mpconfig.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include +#include + +#include +#include +LOG_MODULE_REGISTER(busio_uart); + +/* + * Read characters from UART until line end is detected. Afterwards push the + * data to the message queue. + */ +static void serial_cb(const struct device *dev, void *user_data) { + busio_uart_obj_t *self = (busio_uart_obj_t *)user_data; + + uint8_t c; + + uart_irq_update(dev); + + if (!uart_irq_rx_ready(dev)) { + return; + } + + /* read until FIFO empty */ + while (uart_fifo_read(dev, &c, 1) == 1) { + if (mp_interrupt_char == c) { + common_hal_busio_uart_clear_rx_buffer(self); + mp_sched_keyboard_interrupt(); + } else if (!self->rx_paused) { + if (k_msgq_put(&self->msgq, &c, K_NO_WAIT) != 0) { + self->rx_paused = true; + } + } + } +} + +void common_hal_busio_uart_never_reset(busio_uart_obj_t *self) { + // Not needed for Zephyr port (devices are managed by Zephyr) +} + +// Helper function for Zephyr-specific initialization from device tree +mp_obj_t common_hal_busio_uart_construct_from_device(busio_uart_obj_t *self, const struct device *uart_device, uint16_t receiver_buffer_size, byte *receiver_buffer) { + self->base.type = &busio_uart_type; + self->uart_device = uart_device; + int ret = uart_irq_callback_user_data_set(uart_device, serial_cb, self); + + if (ret < 0) { + LOG_ERR("Failed to set UART IRQ callback: %d", ret); + } + + k_msgq_init(&self->msgq, receiver_buffer, 1, receiver_buffer_size); + + self->timeout = K_FOREVER; + self->write_timeout = K_FOREVER; + self->rx_paused = false; + uart_irq_rx_enable(uart_device); + + return MP_OBJ_FROM_PTR(self); +} + +// Standard busio construct - not used in Zephyr port (devices come from device tree) +void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t *tx, const mcu_pin_obj_t *rx, + const mcu_pin_obj_t *rts, const mcu_pin_obj_t *cts, + const mcu_pin_obj_t *rs485_dir, bool rs485_invert, + uint32_t baudrate, uint8_t bits, busio_uart_parity_t parity, uint8_t stop, + mp_float_t timeout, uint16_t receiver_buffer_size, byte *receiver_buffer, + bool sigint_enabled) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("Use device tree to define %q devices"), MP_QSTR_UART); +} + +bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { + return !device_is_ready(self->uart_device); +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + // Leave it active (managed by Zephyr) +} + +// Read characters. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + size_t count = 0; + while (count < len && k_msgq_get(&self->msgq, data + count, self->timeout) == 0) { + count++; + } + if (count > 0) { + self->rx_paused = false; + } + + return count; +} + +// Write characters. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + for (int i = 0; i < len; i++) { + uart_poll_out(self->uart_device, data[i]); + } + + return len; +} + +uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) { + struct uart_config config; + uart_config_get(self->uart_device, &config); + return config.baudrate; +} + +void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) { + struct uart_config config; + uart_config_get(self->uart_device, &config); + config.baudrate = baudrate; + uart_configure(self->uart_device, &config); +} + +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return (mp_float_t)self->timeout.ticks / 1000000.0; +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { + self->timeout = K_USEC((uint64_t)(timeout * 1000000)); +} + +mp_float_t common_hal_busio_uart_get_write_timeout(busio_uart_obj_t *self) { + return (mp_float_t)self->write_timeout.ticks / 1000000.0; +} + +void common_hal_busio_uart_set_write_timeout(busio_uart_obj_t *self, mp_float_t write_timeout) { + self->write_timeout = K_USEC((uint64_t)(write_timeout * 1000000)); +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + return k_msgq_num_used_get(&self->msgq); +} + +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { + k_msgq_purge(&self->msgq); +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + return true; +} diff --git a/ports/zephyr-cp/common-hal/busio/UART.h b/ports/zephyr-cp/common-hal/busio/UART.h new file mode 100644 index 00000000000..be0b7ff83a9 --- /dev/null +++ b/ports/zephyr-cp/common-hal/busio/UART.h @@ -0,0 +1,33 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include + +typedef struct { + mp_obj_base_t base; + + const struct device *uart_device; + struct k_msgq msgq; + + k_timeout_t timeout; + k_timeout_t write_timeout; + + bool rx_paused; // set by irq if no space in rbuf +} busio_uart_obj_t; + +// Helper function for Zephyr-specific initialization from device tree +mp_obj_t common_hal_busio_uart_construct_from_device(busio_uart_obj_t *self, const struct device *uart_device, uint16_t receiver_buffer_size, byte *receiver_buffer); + +// Internal helper for clearing buffer +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self); + +// Zephyr-port-specific write-timeout accessors, used by usb_cdc/Serial.c. +mp_float_t common_hal_busio_uart_get_write_timeout(busio_uart_obj_t *self); +void common_hal_busio_uart_set_write_timeout(busio_uart_obj_t *self, mp_float_t write_timeout); diff --git a/ports/zephyr-cp/common-hal/busio/__init__.c b/ports/zephyr-cp/common-hal/busio/__init__.c new file mode 100644 index 00000000000..135a53f4907 --- /dev/null +++ b/ports/zephyr-cp/common-hal/busio/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// No busio module functions. diff --git a/ports/zephyr-cp/common-hal/digitalio/DigitalInOut.c b/ports/zephyr-cp/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 00000000000..0da16a9b720 --- /dev/null +++ b/ports/zephyr-cp/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,129 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include +#include + +void common_hal_digitalio_digitalinout_never_reset( + digitalio_digitalinout_obj_t *self) { +} + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t *self, const mcu_pin_obj_t *pin) { + claim_pin(pin); + self->pin = pin; + + if (!device_is_ready(pin->port)) { + printk("Port device not ready\n"); + return DIGITALINOUT_PIN_BUSY; + } + + if (gpio_pin_configure(pin->port, pin->number, GPIO_INPUT) != 0) { + return DIGITALINOUT_PIN_BUSY; + } + self->direction = DIRECTION_INPUT; + + return DIGITALINOUT_OK; +} + +bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t *self) { + return self->pin == NULL; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t *self) { + if (common_hal_digitalio_digitalinout_deinited(self)) { + return; + } + + reset_pin(self->pin); + self->pin = NULL; +} + +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + self->direction = DIRECTION_INPUT; + common_hal_digitalio_digitalinout_set_pull(self, pull); + return DIGITALINOUT_OK; +} + +digitalinout_result_t common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t *self, bool value, + digitalio_drive_mode_t drive_mode) { + + self->direction = DIRECTION_OUTPUT; + common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode); + common_hal_digitalio_digitalinout_set_value(self, value); + return DIGITALINOUT_OK; +} + +digitalio_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t *self) { + return self->direction; +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t *self, bool value) { + int res = gpio_pin_set(self->pin->port, self->pin->number, value); + if (res != 0) { + printk("Failed to set value %d\n", res); + } + // Not all MCUs can read back the output value, so store it. + self->value = value; +} + +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t *self) { + if (self->direction == DIRECTION_OUTPUT) { + return self->value; + } + return gpio_pin_get(self->pin->port, self->pin->number) == 1; +} + +digitalinout_result_t common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t *self, + digitalio_drive_mode_t drive_mode) { + // Also INPUT so we can read the value back. + gpio_flags_t flags = GPIO_OUTPUT; + if (drive_mode == DRIVE_MODE_OPEN_DRAIN) { + flags |= GPIO_OPEN_DRAIN; + } + int res = gpio_pin_configure(self->pin->port, self->pin->number, flags); + if (res != 0) { + // TODO: Fake open drain. + printk("Failed to set drive mode %d\n", res); + return DIGITALINOUT_INVALID_DRIVE_MODE; + } + self->drive_mode = drive_mode; + return DIGITALINOUT_OK; +} + +digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t *self) { + return self->drive_mode; +} + +digitalinout_result_t common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t *self, digitalio_pull_t pull) { + gpio_flags_t pull_flags = 0; + if (pull == PULL_UP) { + pull_flags = GPIO_PULL_UP; + } else if (pull == PULL_DOWN) { + pull_flags = GPIO_PULL_DOWN; + } + if (gpio_pin_configure(self->pin->port, self->pin->number, GPIO_INPUT | pull_flags) != 0) { + return DIGITALINOUT_INVALID_PULL; + } + self->pull = pull; + + return DIGITALINOUT_OK; +} + +digitalio_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t *self) { + return self->pull; +} diff --git a/ports/zephyr-cp/common-hal/digitalio/DigitalInOut.h b/ports/zephyr-cp/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 00000000000..9e0c3265268 --- /dev/null +++ b/ports/zephyr-cp/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + digitalio_direction_t direction; + bool value; + digitalio_drive_mode_t drive_mode; + digitalio_pull_t pull; +} digitalio_digitalinout_obj_t; diff --git a/ports/zephyr-cp/common-hal/digitalio/__init__.c b/ports/zephyr-cp/common-hal/digitalio/__init__.c new file mode 100644 index 00000000000..fa222ed01f0 --- /dev/null +++ b/ports/zephyr-cp/common-hal/digitalio/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// No digitalio module functions. diff --git a/ports/zephyr-cp/common-hal/hostnetwork/HostNetwork.c b/ports/zephyr-cp/common-hal/hostnetwork/HostNetwork.c new file mode 100644 index 00000000000..494b21cb02d --- /dev/null +++ b/ports/zephyr-cp/common-hal/hostnetwork/HostNetwork.c @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "bindings/hostnetwork/HostNetwork.h" + +hostnetwork_hostnetwork_obj_t common_hal_hostnetwork_obj = { + .base = { &hostnetwork_hostnetwork_type }, +}; + +void common_hal_hostnetwork_hostnetwork_construct(hostnetwork_hostnetwork_obj_t *self) { + (void)self; +} diff --git a/ports/zephyr-cp/common-hal/hostnetwork/HostNetwork.h b/ports/zephyr-cp/common-hal/hostnetwork/HostNetwork.h new file mode 100644 index 00000000000..a6731546bde --- /dev/null +++ b/ports/zephyr-cp/common-hal/hostnetwork/HostNetwork.h @@ -0,0 +1,11 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "bindings/hostnetwork/HostNetwork.h" + +extern hostnetwork_hostnetwork_obj_t common_hal_hostnetwork_obj; diff --git a/ports/zephyr-cp/common-hal/microcontroller/Pin.c b/ports/zephyr-cp/common-hal/microcontroller/Pin.c new file mode 100644 index 00000000000..66882b6b5f0 --- /dev/null +++ b/ports/zephyr-cp/common-hal/microcontroller/Pin.c @@ -0,0 +1,73 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "py/mphal.h" + +// Bit mask of claimed pins on each of up to two ports. nrf52832 has one port; nrf52840 has two. +// static uint32_t claimed_pins[GPIO_COUNT]; +// static uint32_t never_reset_pins[GPIO_COUNT]; + +void reset_all_pins(void) { + // for (size_t i = 0; i < GPIO_COUNT; i++) { + // claimed_pins[i] = never_reset_pins[i]; + // } + + // for (uint32_t pin = 0; pin < NUMBER_OF_PINS; ++pin) { + // if ((never_reset_pins[nrf_pin_port(pin)] & (1 << nrf_relative_pin_number(pin))) != 0) { + // continue; + // } + // nrf_gpio_cfg_default(pin); + // } + + // // After configuring SWD because it may be shared. + // reset_speaker_enable_pin(); +} + +// Mark pin as free and return it to a quiescent state. +void reset_pin(const mcu_pin_obj_t *pin) { + + // Clear claimed bit. + // claimed_pins[nrf_pin_port(pin_number)] &= ~(1 << nrf_relative_pin_number(pin_number)); + // never_reset_pins[nrf_pin_port(pin_number)] &= ~(1 << nrf_relative_pin_number(pin_number)); +} + + +void never_reset_pin_number(uint8_t pin_number) { + // never_reset_pins[nrf_pin_port(pin_number)] |= 1 << nrf_relative_pin_number(pin_number); +} + +void common_hal_never_reset_pin(const mcu_pin_obj_t *pin) { + never_reset_pin_number(pin->number); +} + +void common_hal_reset_pin(const mcu_pin_obj_t *pin) { + if (pin == NULL) { + return; + } + reset_pin(pin); +} + +void claim_pin(const mcu_pin_obj_t *pin) { + // Set bit in claimed_pins bitmask. + // claimed_pins[nrf_pin_port(pin->number)] |= 1 << nrf_relative_pin_number(pin->number); +} + + +bool pin_number_is_free(uint8_t pin_number) { + return false; // !(claimed_pins[nrf_pin_port(pin_number)] & (1 << nrf_relative_pin_number(pin_number))); +} + +bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t *pin) { + return true; + +} + +void common_hal_mcu_pin_claim(const mcu_pin_obj_t *pin) { + claim_pin(pin); +} diff --git a/ports/zephyr-cp/common-hal/microcontroller/Pin.h b/ports/zephyr-cp/common-hal/microcontroller/Pin.h new file mode 100644 index 00000000000..d38ab9bd200 --- /dev/null +++ b/ports/zephyr-cp/common-hal/microcontroller/Pin.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/mphal.h" +#include "py/obj.h" + +#include + +typedef struct { + mp_obj_base_t base; + const struct device *port; + gpio_pin_t number; +} mcu_pin_obj_t; + +#include "autogen-pins.h" + +void reset_all_pins(void); +void reset_pin(const mcu_pin_obj_t *pin); +void claim_pin(const mcu_pin_obj_t *pin); diff --git a/ports/zephyr-cp/common-hal/microcontroller/Processor.c b/ports/zephyr-cp/common-hal/microcontroller/Processor.c new file mode 100644 index 00000000000..593d73bcc61 --- /dev/null +++ b/ports/zephyr-cp/common-hal/microcontroller/Processor.c @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/runtime.h" + +#include "common-hal/microcontroller/Processor.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include "shared-bindings/microcontroller/ResetReason.h" + +#include +#include + + +float common_hal_mcu_processor_get_temperature(void) { + return 0.0; +} + +extern uint32_t SystemCoreClock; +uint32_t common_hal_mcu_processor_get_frequency(void) { + #ifdef __ARM__ + return SystemCoreClock; + #else + return CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC; + #endif +} + +float common_hal_mcu_processor_get_voltage(void) { + return 3.3f; +} + +void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) { + ssize_t len = hwinfo_get_device_id(raw_id, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH); + if (len < 0) { + printk("UID retrieval failed: %d\n", len); + len = 0; + } + if (len < COMMON_HAL_MCU_PROCESSOR_UID_LENGTH) { + printk("UID shorter %d than defined length %d\n", len, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH); + memset(raw_id + len, 0, COMMON_HAL_MCU_PROCESSOR_UID_LENGTH - len); + } +} + +mcu_reset_reason_t common_hal_mcu_processor_get_reset_reason(void) { + mcu_reset_reason_t r = MCU_RESET_REASON_UNKNOWN; + return r; +} diff --git a/ports/zephyr-cp/common-hal/microcontroller/Processor.h b/ports/zephyr-cp/common-hal/microcontroller/Processor.h new file mode 100644 index 00000000000..f47f582a1ce --- /dev/null +++ b/ports/zephyr-cp/common-hal/microcontroller/Processor.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#if CONFIG_HWINFO_NRF +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 8 +#else +// Extra long and the remainder will be left empty. Will print out the actual length. +#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 32 +#endif + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + // Stores no state currently. +} mcu_processor_obj_t; + +extern uint32_t reset_reason_saved; diff --git a/ports/zephyr-cp/common-hal/microcontroller/__init__.c b/ports/zephyr-cp/common-hal/microcontroller/__init__.c new file mode 100644 index 00000000000..be33cd26c9a --- /dev/null +++ b/ports/zephyr-cp/common-hal/microcontroller/__init__.c @@ -0,0 +1,114 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2016 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/microcontroller/Processor.h" + +#include "shared-bindings/nvm/ByteArray.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/microcontroller/Processor.h" + +#include "supervisor/filesystem.h" +#include "supervisor/port.h" +#include "supervisor/shared/safe_mode.h" + +#include + +// This routine should work even when interrupts are disabled. Used by OneWire +// for precise timing. +void common_hal_mcu_delay_us(uint32_t delay) { +} + +static uint32_t _irq_key; + +static volatile uint32_t nesting_count = 0; +void common_hal_mcu_disable_interrupts() { + if (nesting_count == 0) { + // Unlike __disable_irq(), this should only be called the first time + // "is_nested_critical_region" is sd's equivalent of our nesting count + // so a nested call would store 0 in the global and make the later + // exit call not actually re-enable interrupts + // + // This only disables interrupts of priority 2 through 7; levels 0, 1, + // and 4, are exclusive to softdevice and should never be used, so + // this limitation is not important. + // sd_nvic_critical_region_enter(&is_nested_critical_region); + if (!k_is_in_isr()) { + k_sched_lock(); + } + _irq_key = irq_lock(); + } + nesting_count++; +} + +void common_hal_mcu_enable_interrupts() { + if (nesting_count == 0) { + // This is very very bad because it means there was mismatched disable/enables. + reset_into_safe_mode(SAFE_MODE_INTERRUPT_ERROR); + } + nesting_count--; + if (nesting_count > 0) { + return; + } + irq_unlock(_irq_key); + if (!k_is_in_isr()) { + k_sched_unlock(); + } +} + +void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) { + enum { DFU_MAGIC_UF2_RESET = 0x57 }; + uint8_t new_value = 0; + if (runmode == RUNMODE_BOOTLOADER || runmode == RUNMODE_UF2) { + new_value = DFU_MAGIC_UF2_RESET; + } + // int err_code = sd_power_gpregret_set(0, DFU_MAGIC_UF2_RESET); + // if (err_code != NRF_SUCCESS) { + // // Set it without the soft device if the SD failed. (It may be off.) + // nrf_power_gpregret_set(NRF_POWER, new_value); + // } + if (runmode == RUNMODE_SAFE_MODE) { + safe_mode_on_next_reset(SAFE_MODE_PROGRAMMATIC); + } +} + +void common_hal_mcu_reset(void) { + filesystem_flush(); + reset_cpu(); +} + +// The singleton microcontroller.Processor object, bound to microcontroller.cpu +// It currently only has properties, and no state. +const mcu_processor_obj_t common_hal_mcu_processor_obj = { + .base = { + .type = &mcu_processor_type, + }, +}; + +#if CIRCUITPY_NVM +// The singleton nvm.ByteArray object. +const nvm_bytearray_obj_t common_hal_mcu_nvm_obj = { + .base = { + .type = &nvm_bytearray_type, + }, +}; +#endif + +#if CIRCUITPY_WATCHDOG +// The singleton watchdog.WatchDogTimer object. +watchdog_watchdogtimer_obj_t common_hal_mcu_watchdogtimer_obj = { + .base = { + .type = &watchdog_watchdogtimer_type, + }, + .timeout = 0.0f, + .mode = WATCHDOGMODE_NONE, +}; +#endif diff --git a/ports/zephyr-cp/common-hal/nvm/ByteArray.c b/ports/zephyr-cp/common-hal/nvm/ByteArray.c new file mode 100644 index 00000000000..b8f552d6773 --- /dev/null +++ b/ports/zephyr-cp/common-hal/nvm/ByteArray.c @@ -0,0 +1,103 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/runtime.h" +#include "common-hal/nvm/ByteArray.h" +#include "shared-bindings/nvm/ByteArray.h" + +#include + +#include +#include + +#define NVM_PARTITION nvm_partition + +#if FIXED_PARTITION_EXISTS(NVM_PARTITION) + +static const struct flash_area *nvm_area = NULL; +static size_t nvm_erase_size = 0; + +static bool ensure_nvm_open(void) { + if (nvm_area != NULL) { + return true; + } + int rc = flash_area_open(FIXED_PARTITION_ID(NVM_PARTITION), &nvm_area); + if (rc != 0) { + return false; + } + + const struct device *dev = flash_area_get_device(nvm_area); + struct flash_pages_info info; + flash_get_page_info_by_offs(dev, nvm_area->fa_off, &info); + nvm_erase_size = info.size; + + return true; +} + +uint32_t common_hal_nvm_bytearray_get_length(const nvm_bytearray_obj_t *self) { + if (!ensure_nvm_open()) { + return 0; + } + return nvm_area->fa_size; +} + +bool common_hal_nvm_bytearray_set_bytes(const nvm_bytearray_obj_t *self, + uint32_t start_index, uint8_t *values, uint32_t len) { + if (!ensure_nvm_open()) { + return false; + } + + uint32_t address = start_index; + while (len > 0) { + uint32_t page_offset = address % nvm_erase_size; + uint32_t page_start = address - page_offset; + uint32_t write_len = MIN(len, nvm_erase_size - page_offset); + + uint8_t *buffer = m_malloc(nvm_erase_size); + if (buffer == NULL) { + return false; + } + + // Read the full erase page. + int rc = flash_area_read(nvm_area, page_start, buffer, nvm_erase_size); + if (rc != 0) { + m_free(buffer); + return false; + } + + // Modify the relevant bytes. + memcpy(buffer + page_offset, values, write_len); + + // Erase the page. + rc = flash_area_erase(nvm_area, page_start, nvm_erase_size); + if (rc != 0) { + m_free(buffer); + return false; + } + + // Write the page back. + rc = flash_area_write(nvm_area, page_start, buffer, nvm_erase_size); + m_free(buffer); + if (rc != 0) { + return false; + } + + address += write_len; + values += write_len; + len -= write_len; + } + return true; +} + +void common_hal_nvm_bytearray_get_bytes(const nvm_bytearray_obj_t *self, + uint32_t start_index, uint32_t len, uint8_t *values) { + if (!ensure_nvm_open()) { + return; + } + flash_area_read(nvm_area, start_index, values, len); +} + +#endif // FIXED_PARTITION_EXISTS(NVM_PARTITION) diff --git a/ports/zephyr-cp/common-hal/nvm/ByteArray.h b/ports/zephyr-cp/common-hal/nvm/ByteArray.h new file mode 100644 index 00000000000..9c771aaa3a9 --- /dev/null +++ b/ports/zephyr-cp/common-hal/nvm/ByteArray.h @@ -0,0 +1,13 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} nvm_bytearray_obj_t; diff --git a/ports/zephyr-cp/common-hal/os/__init__.c b/ports/zephyr-cp/common-hal/os/__init__.c new file mode 100644 index 00000000000..2f37ba40f47 --- /dev/null +++ b/ports/zephyr-cp/common-hal/os/__init__.c @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "genhdr/mpversion.h" +#include "py/mpconfig.h" +#include "py/objstr.h" +#include "py/objtuple.h" + +#include "shared-bindings/os/__init__.h" + +#include + +bool common_hal_os_urandom(uint8_t *buffer, mp_uint_t length) { + #if !DT_HAS_CHOSEN(zephyr_entropy) + return false; + #else + return sys_csrand_get(buffer, length) == 0; + #endif +} diff --git a/ports/zephyr-cp/common-hal/rotaryio/IncrementalEncoder.c b/ports/zephyr-cp/common-hal/rotaryio/IncrementalEncoder.c new file mode 100644 index 00000000000..d36b571535a --- /dev/null +++ b/ports/zephyr-cp/common-hal/rotaryio/IncrementalEncoder.c @@ -0,0 +1,129 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include "common-hal/rotaryio/IncrementalEncoder.h" +#include "shared-bindings/rotaryio/IncrementalEncoder.h" +#include "shared-module/rotaryio/IncrementalEncoder.h" + +#include "bindings/zephyr_kernel/__init__.h" +#include "py/runtime.h" + +#include +#include +#include +#include + +static void incrementalencoder_gpio_callback(const struct device *port, + struct gpio_callback *cb, gpio_port_pins_t pins) { + (void)port; + (void)pins; + rotaryio_incrementalencoder_gpio_callback_t *callback = + CONTAINER_OF(cb, rotaryio_incrementalencoder_gpio_callback_t, callback); + rotaryio_incrementalencoder_obj_t *self = callback->encoder; + if (self == NULL || self->pin_a == NULL) { + return; + } + + int a = gpio_pin_get(self->pin_a->port, self->pin_a->number); + int b = gpio_pin_get(self->pin_b->port, self->pin_b->number); + if (a < 0 || b < 0) { + return; + } + uint8_t new_state = ((uint8_t)a << 1) | (uint8_t)b; + shared_module_softencoder_state_update(self, new_state); +} + +void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, + const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b) { + // Ensure object starts in its deinit state. + common_hal_rotaryio_incrementalencoder_mark_deinit(self); + + self->pin_a = pin_a; + self->pin_b = pin_b; + self->divisor = 4; + + if (!device_is_ready(pin_a->port) || !device_is_ready(pin_b->port)) { + common_hal_rotaryio_incrementalencoder_deinit(self); + raise_zephyr_error(-ENODEV); + } + + int result = gpio_pin_configure(pin_a->port, pin_a->number, GPIO_INPUT | GPIO_PULL_UP); + if (result != 0) { + common_hal_rotaryio_incrementalencoder_deinit(self); + raise_zephyr_error(result); + } + + result = gpio_pin_configure(pin_b->port, pin_b->number, GPIO_INPUT | GPIO_PULL_UP); + if (result != 0) { + common_hal_rotaryio_incrementalencoder_deinit(self); + raise_zephyr_error(result); + } + + self->callback_a.encoder = self; + gpio_init_callback(&self->callback_a.callback, incrementalencoder_gpio_callback, + BIT(pin_a->number)); + result = gpio_add_callback(pin_a->port, &self->callback_a.callback); + if (result != 0) { + common_hal_rotaryio_incrementalencoder_deinit(self); + raise_zephyr_error(result); + } + + self->callback_b.encoder = self; + gpio_init_callback(&self->callback_b.callback, incrementalencoder_gpio_callback, + BIT(pin_b->number)); + result = gpio_add_callback(pin_b->port, &self->callback_b.callback); + if (result != 0) { + common_hal_rotaryio_incrementalencoder_deinit(self); + raise_zephyr_error(result); + } + + result = gpio_pin_interrupt_configure(pin_a->port, pin_a->number, GPIO_INT_EDGE_BOTH); + if (result != 0) { + common_hal_rotaryio_incrementalencoder_deinit(self); + raise_zephyr_error(result); + } + + result = gpio_pin_interrupt_configure(pin_b->port, pin_b->number, GPIO_INT_EDGE_BOTH); + if (result != 0) { + common_hal_rotaryio_incrementalencoder_deinit(self); + raise_zephyr_error(result); + } + + int a = gpio_pin_get(pin_a->port, pin_a->number); + int b = gpio_pin_get(pin_b->port, pin_b->number); + uint8_t quiescent_state = ((uint8_t)(a > 0) << 1) | (uint8_t)(b > 0); + shared_module_softencoder_state_init(self, quiescent_state); + + claim_pin(pin_a); + claim_pin(pin_b); +} + +bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self) { + return self->pin_a == NULL; +} + +void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t *self) { + if (common_hal_rotaryio_incrementalencoder_deinited(self)) { + return; + } + + // Best-effort cleanup. During failed construct(), some of these may not be + // initialized yet. Ignore cleanup errors. + gpio_pin_interrupt_configure(self->pin_a->port, self->pin_a->number, GPIO_INT_DISABLE); + gpio_pin_interrupt_configure(self->pin_b->port, self->pin_b->number, GPIO_INT_DISABLE); + gpio_remove_callback(self->pin_a->port, &self->callback_a.callback); + gpio_remove_callback(self->pin_b->port, &self->callback_b.callback); + + reset_pin(self->pin_a); + reset_pin(self->pin_b); + + common_hal_rotaryio_incrementalencoder_mark_deinit(self); +} + +void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self) { + self->pin_a = NULL; + self->pin_b = NULL; +} diff --git a/ports/zephyr-cp/common-hal/rotaryio/IncrementalEncoder.h b/ports/zephyr-cp/common-hal/rotaryio/IncrementalEncoder.h new file mode 100644 index 00000000000..a0d2bb392e2 --- /dev/null +++ b/ports/zephyr-cp/common-hal/rotaryio/IncrementalEncoder.h @@ -0,0 +1,31 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "common-hal/microcontroller/Pin.h" +#include "py/obj.h" + +typedef struct rotaryio_incrementalencoder_obj rotaryio_incrementalencoder_obj_t; + +typedef struct { + struct gpio_callback callback; + rotaryio_incrementalencoder_obj_t *encoder; +} rotaryio_incrementalencoder_gpio_callback_t; + +struct rotaryio_incrementalencoder_obj { + mp_obj_base_t base; + const mcu_pin_obj_t *pin_a; + const mcu_pin_obj_t *pin_b; + rotaryio_incrementalencoder_gpio_callback_t callback_a; + rotaryio_incrementalencoder_gpio_callback_t callback_b; + uint8_t state; // + int8_t sub_count; // count intermediate transitions between detents + int8_t divisor; // Number of quadrature edges required per count + mp_int_t position; +}; diff --git a/ports/zephyr-cp/common-hal/rotaryio/__init__.c b/ports/zephyr-cp/common-hal/rotaryio/__init__.c new file mode 100644 index 00000000000..67cae26a8b7 --- /dev/null +++ b/ports/zephyr-cp/common-hal/rotaryio/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +// No rotaryio module functions. diff --git a/ports/zephyr-cp/common-hal/socketpool/Socket.c b/ports/zephyr-cp/common-hal/socketpool/Socket.c new file mode 100644 index 00000000000..bb626857a98 --- /dev/null +++ b/ports/zephyr-cp/common-hal/socketpool/Socket.c @@ -0,0 +1,672 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Lucian Copeland for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/socketpool/Socket.h" + +#include "shared/runtime/interrupt_char.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "shared-bindings/socketpool/SocketPool.h" +#include "common-hal/socketpool/__init__.h" +#include "common-hal/wifi/__init__.h" +#if CIRCUITPY_SSL +#include "shared-bindings/ssl/SSLSocket.h" +#include "shared-module/ssl/SSLSocket.h" +#endif +#include "supervisor/port.h" +#include "supervisor/shared/tick.h" +#include "supervisor/workflow.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define SOCKETPOOL_IP_STR_LEN 48 + +static mp_obj_t _format_address(const struct sockaddr *addr, int family) { + char ip_str[SOCKETPOOL_IP_STR_LEN]; + const struct sockaddr_in *a = (void *)addr; + + switch (family) { + #if CIRCUITPY_SOCKETPOOL_IPV6 + case AF_INET6: + zsock_inet_ntop(family, &((const struct sockaddr_in6 *)a)->sin6_addr, ip_str, sizeof(ip_str)); + break; + #endif + default: + case AF_INET: + zsock_inet_ntop(family, &((const struct sockaddr_in *)a)->sin_addr, ip_str, sizeof(ip_str)); + break; + } + return mp_obj_new_str(ip_str, strlen(ip_str)); +} + +static mp_obj_t _sockaddr_to_tuple(const struct sockaddr_storage *sockaddr) { + mp_obj_t args[4] = { + _format_address((const struct sockaddr *)sockaddr, sockaddr->ss_family), + }; + int n = 2; + #if CIRCUITPY_SOCKETPOOL_IPV6 + if (sockaddr->ss_family == AF_INET6) { + const struct sockaddr_in6 *addr6 = (const void *)sockaddr; + args[1] = MP_OBJ_NEW_SMALL_INT(ntohs(addr6->sin6_port)); + args[2] = MP_OBJ_NEW_SMALL_INT(addr6->sin6_flowinfo); + args[3] = MP_OBJ_NEW_SMALL_INT(addr6->sin6_scope_id); + n = 4; + } else + #endif + { + const struct sockaddr_in *addr = (const void *)sockaddr; + args[1] = MP_OBJ_NEW_SMALL_INT(ntohs(addr->sin_port)); + } + return mp_obj_new_tuple(n, args); +} + +static void socketpool_resolve_host_or_throw(int family, int type, const char *hostname, struct sockaddr_storage *addr, int port) { + const struct zsock_addrinfo hints = { + .ai_family = family, + .ai_socktype = type, + }; + struct zsock_addrinfo *result_i = NULL; + char service_buf[6]; + + snprintf(service_buf, sizeof(service_buf), "%d", port); + + int error = zsock_getaddrinfo(hostname, service_buf, &hints, &result_i); + if (error != 0 || result_i == NULL) { + // Report what the resolver said. A null result with no error is the + // one case that really is "not found". + if (error == 0) { + error = DNS_EAI_NONAME; + } + common_hal_socketpool_socketpool_raise_gaierror(error); + } + + memcpy(addr, result_i->ai_addr, sizeof(struct sockaddr_storage)); + zsock_freeaddrinfo(result_i); +} + +static void resolve_host_or_throw(socketpool_socket_obj_t *self, const char *hostname, struct sockaddr_storage *addr, int port) { + socketpool_resolve_host_or_throw(self->family, self->type, hostname, addr, port); +} + +// How long to wait between checks for a socket to connect. +#define SOCKET_CONNECT_POLL_INTERVAL_MS 100 + +void socket_user_reset(void) { + // User sockets are heap objects with __del__ bound to close(). + // During VM shutdown/reset, gc_sweep_all() runs finalizers, so sockets + // are closed there rather than being tracked and closed explicitly here. +} + +static struct k_work_delayable socketpool_poll_work; +static bool socketpool_poll_work_initialized; + +static void socketpool_poll_work_handler(struct k_work *work) { + (void)work; + supervisor_workflow_request_background(); +} + +// Unblock select task (ok if not blocked yet) +void socketpool_socket_poll_resume(void) { + if (!socketpool_poll_work_initialized) { + k_work_init_delayable(&socketpool_poll_work, socketpool_poll_work_handler); + socketpool_poll_work_initialized = true; + } + k_work_schedule(&socketpool_poll_work, K_MSEC(10)); +} + +static bool _socketpool_socket(socketpool_socketpool_obj_t *self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, + int proto, + socketpool_socket_obj_t *sock) { + int addr_family; + int ipproto; + + if (family == SOCKETPOOL_AF_INET) { + addr_family = AF_INET; + ipproto = IPPROTO_IP; + #if CIRCUITPY_SOCKETPOOL_IPV6 + } else { // INET6 + addr_family = AF_INET6; + ipproto = IPPROTO_IPV6; + #endif + } + + int socket_type; + if (type == SOCKETPOOL_SOCK_STREAM) { + socket_type = SOCK_STREAM; + } else if (type == SOCKETPOOL_SOCK_DGRAM) { + socket_type = SOCK_DGRAM; + } else { // SOCKETPOOL_SOCK_RAW + socket_type = SOCK_RAW; + ipproto = proto; + } + sock->type = socket_type; + sock->family = addr_family; + sock->ipproto = ipproto; + sock->pool = self; + sock->timeout_ms = (uint)-1; + + int socknum = zsock_socket(sock->family, sock->type, sock->ipproto); + if (socknum < 0) { + return false; + } + + sock->num = socknum; + + // Enable address reuse by default to avoid bind failures on recently-used ports. + int reuseaddr = 1; + if (zsock_setsockopt(socknum, SOL_SOCKET, SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)) < 0) { + // Ignore if SO_REUSEADDR is unsupported. + } + + // Sockets should be nonblocking in most cases. + if (zsock_fcntl(socknum, F_SETFL, ZVFS_O_NONBLOCK) < 0) { + // Ignore if non-blocking is unsupported. + } + + return true; +} + +// special entry for workflow listener (register system socket) +bool socketpool_socket(socketpool_socketpool_obj_t *self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, + int proto, socketpool_socket_obj_t *sock) { + + if (!_socketpool_socket(self, family, type, proto, sock)) { + return false; + } + + return true; +} + +socketpool_socket_obj_t *common_hal_socketpool_socket(socketpool_socketpool_obj_t *self, + socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, int proto) { + switch (family) { + #if CIRCUITPY_SOCKETPOOL_IPV6 + case SOCKETPOOL_AF_INET6: + #endif + case SOCKETPOOL_AF_INET: + break; + default: + mp_raise_NotImplementedError(MP_ERROR_TEXT("Unsupported socket type")); + } + + socketpool_socket_obj_t *sock = mp_obj_malloc_with_finaliser(socketpool_socket_obj_t, &socketpool_socket_type); + + if (!_socketpool_socket(self, family, type, proto, sock)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Out of sockets")); + } + return sock; +} + +int socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out, socketpool_socket_obj_t *accepted) { + struct sockaddr_storage peer_addr; + socklen_t socklen = sizeof(peer_addr); + int newsoc = -1; + bool timed_out = false; + uint64_t start_ticks = supervisor_ticks_ms64(); + + // Allow timeouts and interrupts + while (newsoc == -1 && !timed_out) { + if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { + timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; + } + RUN_BACKGROUND_TASKS; + newsoc = zsock_accept(self->num, (struct sockaddr *)&peer_addr, &socklen); + // In non-blocking mode, fail instead of timing out + if (newsoc == -1 && (self->timeout_ms == 0 || mp_hal_is_interrupted())) { + return -MP_EAGAIN; + } + if (newsoc == -1 && errno != EAGAIN && errno != EWOULDBLOCK) { + return -errno; + } + } + + if (timed_out) { + return -ETIMEDOUT; + } + + if (newsoc < 0) { + return -MP_EBADF; + } + + // We got a socket. New client socket will not be non-blocking by default, so make it non-blocking. + if (zsock_fcntl(newsoc, F_SETFL, ZVFS_O_NONBLOCK) < 0) { + // Ignore if non-blocking is unsupported. + } + + if (accepted != NULL) { + // Error if called with open socket object. + assert(common_hal_socketpool_socket_get_closed(accepted)); + + // Replace the old accepted socket with the new one. + accepted->num = newsoc; + accepted->pool = self->pool; + accepted->connected = true; + accepted->type = self->type; + } + + if (peer_out) { + *peer_out = _sockaddr_to_tuple(&peer_addr); + } + + return newsoc; +} + +socketpool_socket_obj_t *common_hal_socketpool_socket_accept(socketpool_socket_obj_t *self, mp_obj_t *peer_out) { + // Set the socket type only after the socketpool_socket_accept succeeds, so that the + // finaliser is not called on a bad socket. + socketpool_socket_obj_t *sock = mp_obj_malloc_with_finaliser(socketpool_socket_obj_t, NULL); + int newsoc = socketpool_socket_accept(self, peer_out, NULL); + + if (newsoc > 0) { + // Create the socket + sock->base.type = &socketpool_socket_type; + sock->num = newsoc; + sock->pool = self->pool; + sock->connected = true; + sock->type = self->type; + + return sock; + } else { + mp_raise_OSError(-newsoc); + return NULL; + } +} + +size_t common_hal_socketpool_socket_bind(socketpool_socket_obj_t *self, + const char *host, size_t hostlen, uint32_t port) { + struct sockaddr_storage bind_addr; + const char *broadcast = ""; + uint32_t local_port = port; + + memset(&bind_addr, 0, sizeof(bind_addr)); + bind_addr.ss_family = self->family; + + #if CIRCUITPY_SOCKETPOOL_IPV6 + if (self->family == AF_INET6) { + struct sockaddr_in6 *addr6 = (void *)&bind_addr; + addr6->sin6_port = htons(local_port); + // no ipv6 broadcast + if (hostlen == 0) { + memset(&addr6->sin6_addr, 0, sizeof(addr6->sin6_addr)); + } else { + socketpool_resolve_host_or_throw(self->family, self->type, host, &bind_addr, local_port); + } + } else + #endif + { + struct sockaddr_in *addr4 = (void *)&bind_addr; + addr4->sin_port = htons(local_port); + if (hostlen == 0) { + addr4->sin_addr.s_addr = htonl(INADDR_ANY); + } else if (hostlen == strlen(broadcast) && + memcmp(host, broadcast, strlen(broadcast)) == 0) { + addr4->sin_addr.s_addr = htonl(INADDR_BROADCAST); + } else { + socketpool_resolve_host_or_throw(self->family, self->type, host, &bind_addr, local_port); + } + } + + int result = zsock_bind(self->num, (struct sockaddr *)&bind_addr, sizeof(bind_addr)); + if (result == 0) { + return 0; + } + return errno; +} + +void socketpool_socket_close(socketpool_socket_obj_t *self) { + #if CIRCUITPY_SSL + if (self->ssl_socket) { + ssl_sslsocket_obj_t *ssl_socket = self->ssl_socket; + self->ssl_socket = NULL; + common_hal_ssl_sslsocket_close(ssl_socket); + return; + } + #endif + self->connected = false; + int fd = self->num; + if (fd >= 0) { + zsock_shutdown(fd, ZSOCK_SHUT_RDWR); + zsock_close(fd); + } + self->num = -1; +} + +void common_hal_socketpool_socket_close(socketpool_socket_obj_t *self) { + socketpool_socket_close(self); +} + +void common_hal_socketpool_socket_connect(socketpool_socket_obj_t *self, + const char *host, size_t hostlen, uint32_t port) { + (void)hostlen; + struct sockaddr_storage addr; + resolve_host_or_throw(self, host, &addr, port); + + int result = zsock_connect(self->num, (struct sockaddr *)&addr, sizeof(addr)); + + if (result == 0) { + // Connected immediately. + self->connected = true; + return; + } + + if (result < 0 && errno != EINPROGRESS) { + // Some error happened; error is in errno. + mp_raise_OSError(errno); + return; + } + + // Keep checking, using poll(), until timeout expires, at short intervals. + // This allows ctrl-C interrupts to be detected and background tasks to run. + mp_uint_t timeout_left = self->timeout_ms; + + while (timeout_left > 0) { + RUN_BACKGROUND_TASKS; + // Allow ctrl-C interrupt + if (mp_hal_is_interrupted()) { + return; + } + + struct zsock_pollfd fd = { + .fd = self->num, + .events = ZSOCK_POLLOUT, + }; + int poll_timeout = SOCKET_CONNECT_POLL_INTERVAL_MS; + if (self->timeout_ms == (uint)-1) { + poll_timeout = -1; + } else if (timeout_left < SOCKET_CONNECT_POLL_INTERVAL_MS) { + poll_timeout = timeout_left; + } + + result = zsock_poll(&fd, 1, poll_timeout); + if (result == 0) { + if (self->timeout_ms == (uint)-1) { + continue; + } + if (timeout_left < SOCKET_CONNECT_POLL_INTERVAL_MS) { + timeout_left = 0; + } else { + timeout_left -= SOCKET_CONNECT_POLL_INTERVAL_MS; + } + continue; + } + + if (result < 0) { + mp_raise_OSError(errno); + } + + int error_code = 0; + socklen_t socklen = sizeof(error_code); + result = zsock_getsockopt(self->num, SOL_SOCKET, SO_ERROR, &error_code, &socklen); + if (result < 0 || error_code != 0) { + mp_raise_OSError(error_code != 0 ? error_code : errno); + } + self->connected = true; + return; + } + + // No connection after timeout. The connection attempt is not stopped. + // This imitates what happens in Python. + mp_raise_OSError(ETIMEDOUT); +} + +bool common_hal_socketpool_socket_get_closed(socketpool_socket_obj_t *self) { + return self->num < 0; +} + +bool common_hal_socketpool_socket_get_connected(socketpool_socket_obj_t *self) { + return self->connected; +} + +bool common_hal_socketpool_socket_listen(socketpool_socket_obj_t *self, int backlog) { + return zsock_listen(self->num, backlog) == 0; +} + +mp_uint_t common_hal_socketpool_socket_recvfrom_into(socketpool_socket_obj_t *self, + uint8_t *buf, uint32_t len, mp_obj_t *source_out) { + + struct sockaddr_storage source_addr; + socklen_t socklen = sizeof(source_addr); + + uint64_t start_ticks = supervisor_ticks_ms64(); + int received = -1; + bool timed_out = false; + while (received == -1 && + !timed_out && + !mp_hal_is_interrupted()) { + if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { + timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; + } + RUN_BACKGROUND_TASKS; + received = zsock_recvfrom(self->num, buf, len, ZSOCK_MSG_DONTWAIT, (struct sockaddr *)&source_addr, &socklen); + + if (received < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + mp_raise_OSError(errno); + } + + if (received == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + // In non-blocking mode, fail instead of looping + if (self->timeout_ms == 0) { + mp_raise_OSError(MP_EAGAIN); + } + continue; + } + } + + if (timed_out) { + mp_raise_OSError(ETIMEDOUT); + } + + if (received < 0) { + mp_raise_BrokenPipeError(); + return 0; + } + + if (source_out) { + *source_out = _sockaddr_to_tuple(&source_addr); + } + + return received; +} + +int socketpool_socket_recv_into(socketpool_socket_obj_t *self, + const uint8_t *buf, uint32_t len) { + int received = 0; + bool timed_out = false; + + if (self->num != -1) { + uint64_t start_ticks = supervisor_ticks_ms64(); + received = -1; + while (received == -1 && + !timed_out) { + if (self->timeout_ms != (uint)-1 && self->timeout_ms != 0) { + timed_out = supervisor_ticks_ms64() - start_ticks >= self->timeout_ms; + } + RUN_BACKGROUND_TASKS; + received = zsock_recv(self->num, (void *)buf, len, ZSOCK_MSG_DONTWAIT); + if (received < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + return -errno; + } + if (received < 1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { + if (self->timeout_ms == 0) { + return -MP_EAGAIN; + } + continue; + } + // In non-blocking mode, fail instead of looping + if (received < 1 && self->timeout_ms == 0) { + if ((received == 0) || (errno == ENOTCONN)) { + self->connected = false; + return -MP_ENOTCONN; + } + return -MP_EAGAIN; + } + // Check this after going through the loop once so it can make + // progress while interrupted. + if (mp_hal_is_interrupted()) { + if (received == -1) { + return -MP_EAGAIN; + } + break; + } + } + } else { + return -MP_EBADF; + } + + if (timed_out) { + return -ETIMEDOUT; + } + return received; +} + +mp_uint_t common_hal_socketpool_socket_recv_into(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) { + int received = socketpool_socket_recv_into(self, buf, len); + if (received < 0) { + mp_raise_OSError(-received); + } + return received; +} + +int socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) { + int sent = -1; + if (self->num != -1) { + sent = zsock_send(self->num, buf, len, 0); + } else { + sent = -MP_EBADF; + } + + if (sent < 0) { + if (errno == ECONNRESET || errno == ENOTCONN) { + self->connected = false; + } + return -errno; + } + + return sent; +} + +mp_uint_t common_hal_socketpool_socket_send(socketpool_socket_obj_t *self, const uint8_t *buf, uint32_t len) { + int sent = socketpool_socket_send(self, buf, len); + + if (sent < 0) { + mp_raise_OSError(-sent); + } + return sent; +} + +mp_uint_t common_hal_socketpool_socket_sendto(socketpool_socket_obj_t *self, + const char *host, size_t hostlen, uint32_t port, const uint8_t *buf, uint32_t len) { + + (void)hostlen; + struct sockaddr_storage addr; + resolve_host_or_throw(self, host, &addr, port); + + int bytes_sent = zsock_sendto(self->num, buf, len, 0, (struct sockaddr *)&addr, sizeof(addr)); + if (bytes_sent < 0) { + mp_raise_BrokenPipeError(); + return 0; + } + return bytes_sent; +} + +void common_hal_socketpool_socket_settimeout(socketpool_socket_obj_t *self, uint32_t timeout_ms) { + self->timeout_ms = timeout_ms; +} + +mp_int_t common_hal_socketpool_socket_get_type(socketpool_socket_obj_t *self) { + return self->type; +} + + +int common_hal_socketpool_socket_setsockopt(socketpool_socket_obj_t *self, int level, int optname, const void *value, size_t optlen) { + int zephyr_level = level; + int zephyr_optname = optname; + + switch (level) { + case SOCKETPOOL_SOL_SOCKET: + zephyr_level = SOL_SOCKET; + break; + case SOCKETPOOL_IPPROTO_IP: + zephyr_level = IPPROTO_IP; + break; + case SOCKETPOOL_IPPROTO_TCP: + zephyr_level = IPPROTO_TCP; + break; + case SOCKETPOOL_IPPROTO_UDP: + zephyr_level = IPPROTO_UDP; + break; + #if CIRCUITPY_SOCKETPOOL_IPV6 + case SOCKETPOOL_IPPROTO_IPV6: + zephyr_level = IPPROTO_IPV6; + break; + #endif + } + + if (zephyr_level == SOL_SOCKET) { + switch (optname) { + case SOCKETPOOL_SO_REUSEADDR: + zephyr_optname = SO_REUSEADDR; + break; + } + } else if (zephyr_level == IPPROTO_TCP) { + switch (optname) { + case SOCKETPOOL_TCP_NODELAY: + zephyr_optname = TCP_NODELAY; + break; + } + } + + int err = zsock_setsockopt(self->num, zephyr_level, zephyr_optname, value, optlen); + if (err != 0) { + return -errno; + } + return 0; +} + +bool common_hal_socketpool_readable(socketpool_socket_obj_t *self) { + struct zsock_pollfd fd = { + .fd = self->num, + .events = ZSOCK_POLLIN, + }; + + int num_triggered = zsock_poll(&fd, 1, 0); + return num_triggered > 0; +} + +bool common_hal_socketpool_writable(socketpool_socket_obj_t *self) { + struct zsock_pollfd fd = { + .fd = self->num, + .events = ZSOCK_POLLOUT, + }; + + int num_triggered = zsock_poll(&fd, 1, 0); + return num_triggered > 0; +} + +void socketpool_socket_move(socketpool_socket_obj_t *self, socketpool_socket_obj_t *sock) { + *sock = *self; + self->connected = false; + self->num = -1; +} + +void socketpool_socket_reset(socketpool_socket_obj_t *self) { + if (self->base.type == &socketpool_socket_type) { + return; + } + self->base.type = &socketpool_socket_type; + self->connected = false; + self->num = -1; +} diff --git a/ports/zephyr-cp/common-hal/socketpool/Socket.h b/ports/zephyr-cp/common-hal/socketpool/Socket.h new file mode 100644 index 00000000000..a093eea83f6 --- /dev/null +++ b/ports/zephyr-cp/common-hal/socketpool/Socket.h @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include "common-hal/socketpool/SocketPool.h" + +typedef struct ssl_sslsocket_obj ssl_sslsocket_obj_t; + +typedef struct { + mp_obj_base_t base; + int num; + int type; + int family; + int ipproto; + bool connected; + socketpool_socketpool_obj_t *pool; + ssl_sslsocket_obj_t *ssl_socket; + mp_uint_t timeout_ms; +} socketpool_socket_obj_t; + +void socket_user_reset(void); +// Unblock workflow socket select thread (platform specific) +void socketpool_socket_poll_resume(void); diff --git a/ports/zephyr-cp/common-hal/socketpool/SocketPool.c b/ports/zephyr-cp/common-hal/socketpool/SocketPool.c new file mode 100644 index 00000000000..2df1af69187 --- /dev/null +++ b/ports/zephyr-cp/common-hal/socketpool/SocketPool.c @@ -0,0 +1,127 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/socketpool/SocketPool.h" +#include "common-hal/socketpool/Socket.h" + +#include "py/runtime.h" +#if CIRCUITPY_HOSTNETWORK +#include "bindings/hostnetwork/__init__.h" +#endif +#if CIRCUITPY_WIFI +#include "shared-bindings/wifi/__init__.h" +#endif +#include "common-hal/socketpool/__init__.h" + +#include +#include + +#include +#include + +void common_hal_socketpool_socketpool_construct(socketpool_socketpool_obj_t *self, mp_obj_t radio) { + bool is_wifi = false; + #if CIRCUITPY_WIFI + is_wifi = radio == MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj); + #endif + bool is_hostnetwork = false; + #if CIRCUITPY_HOSTNETWORK + is_hostnetwork = mp_obj_is_type(radio, &hostnetwork_hostnetwork_type); + #endif + if (!(is_wifi || is_hostnetwork)) { + mp_raise_ValueError(MP_ERROR_TEXT("SocketPool can only be used with wifi.radio or hostnetwork.HostNetwork")); + } +} + +// common_hal_socketpool_socket is in socketpool/Socket.c to centralize open socket tracking. + +static int socketpool_getaddrinfo_common(const char *host, int service, const struct zsock_addrinfo *hints, struct zsock_addrinfo **res) { + char service_buf[6]; + snprintf(service_buf, sizeof(service_buf), "%d", service); + + return zsock_getaddrinfo(host, service_buf, hints, res); +} + +#define SOCKETPOOL_IP_STR_LEN 48 + +static mp_obj_t format_address(const struct sockaddr *addr, int family) { + char ip_str[SOCKETPOOL_IP_STR_LEN]; + const struct sockaddr_in *a = (void *)addr; + + switch (family) { + #if CIRCUITPY_SOCKETPOOL_IPV6 + case AF_INET6: + zsock_inet_ntop(family, &((const struct sockaddr_in6 *)a)->sin6_addr, ip_str, sizeof(ip_str)); + break; + #endif + default: + case AF_INET: + zsock_inet_ntop(family, &((const struct sockaddr_in *)a)->sin_addr, ip_str, sizeof(ip_str)); + break; + } + return mp_obj_new_str(ip_str, strlen(ip_str)); +} + +static mp_obj_t convert_sockaddr(const struct zsock_addrinfo *ai, int port) { + #if CIRCUITPY_SOCKETPOOL_IPV6 + mp_int_t n_tuple = ai->ai_family == AF_INET6 ? 4 : 2; + #else + mp_int_t n_tuple = 2; + #endif + mp_obj_tuple_t *result = MP_OBJ_TO_PTR(mp_obj_new_tuple(n_tuple, NULL)); + result->items[0] = format_address(ai->ai_addr, ai->ai_family); + result->items[1] = MP_OBJ_NEW_SMALL_INT(port); + #if CIRCUITPY_SOCKETPOOL_IPV6 + if (ai->ai_family == AF_INET6) { + const struct sockaddr_in6 *ai6 = (void *)ai->ai_addr; + result->items[2] = MP_OBJ_NEW_SMALL_INT(ai6->sin6_flowinfo); + result->items[3] = MP_OBJ_NEW_SMALL_INT(ai6->sin6_scope_id); + } + #endif + return result; +} + +static mp_obj_t convert_addrinfo(const struct zsock_addrinfo *ai, int port) { + mp_obj_tuple_t *result = MP_OBJ_TO_PTR(mp_obj_new_tuple(5, NULL)); + result->items[0] = MP_OBJ_NEW_SMALL_INT(ai->ai_family); + result->items[1] = MP_OBJ_NEW_SMALL_INT(ai->ai_socktype); + result->items[2] = MP_OBJ_NEW_SMALL_INT(ai->ai_protocol); + result->items[3] = ai->ai_canonname ? mp_obj_new_str(ai->ai_canonname, strlen(ai->ai_canonname)) : MP_OBJ_NEW_QSTR(MP_QSTR_); + result->items[4] = convert_sockaddr(ai, port); + return result; +} + +mp_obj_t common_hal_socketpool_getaddrinfo_raise(socketpool_socketpool_obj_t *self, const char *host, int port, int family, int type, int proto, int flags) { + const struct zsock_addrinfo hints = { + .ai_flags = flags, + .ai_family = family, + .ai_protocol = proto, + .ai_socktype = type, + }; + + struct zsock_addrinfo *res = NULL; + int err = socketpool_getaddrinfo_common(host, port, &hints, &res); + if (err != 0 || res == NULL) { + if (err == 0) { + err = DNS_EAI_NONAME; + } + common_hal_socketpool_socketpool_raise_gaierror(err); + } + + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t result = mp_obj_new_list(0, NULL); + for (struct zsock_addrinfo *ai = res; ai; ai = ai->ai_next) { + mp_obj_list_append(result, convert_addrinfo(ai, port)); + } + nlr_pop(); + zsock_freeaddrinfo(res); + return result; + } else { + zsock_freeaddrinfo(res); + nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val)); + } +} diff --git a/ports/zephyr-cp/common-hal/socketpool/SocketPool.h b/ports/zephyr-cp/common-hal/socketpool/SocketPool.h new file mode 100644 index 00000000000..7891a8b8e48 --- /dev/null +++ b/ports/zephyr-cp/common-hal/socketpool/SocketPool.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} socketpool_socketpool_obj_t; diff --git a/ports/zephyr-cp/common-hal/socketpool/__init__.c b/ports/zephyr-cp/common-hal/socketpool/__init__.c new file mode 100644 index 00000000000..c8558f9b80a --- /dev/null +++ b/ports/zephyr-cp/common-hal/socketpool/__init__.c @@ -0,0 +1,13 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/socketpool/__init__.h" + +#include "common-hal/socketpool/Socket.h" + +void socketpool_user_reset(void) { + socket_user_reset(); +} diff --git a/ports/zephyr-cp/common-hal/socketpool/__init__.h b/ports/zephyr-cp/common-hal/socketpool/__init__.h new file mode 100644 index 00000000000..f7ccde7f367 --- /dev/null +++ b/ports/zephyr-cp/common-hal/socketpool/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/ports/zephyr-cp/common-hal/usb_cdc/Serial.c b/ports/zephyr-cp/common-hal/usb_cdc/Serial.c new file mode 100644 index 00000000000..715955d6e0f --- /dev/null +++ b/ports/zephyr-cp/common-hal/usb_cdc/Serial.c @@ -0,0 +1,69 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared/runtime/interrupt_char.h" +#include "shared-bindings/usb_cdc/Serial.h" +#include "shared-bindings/busio/UART.h" +#include "common-hal/busio/UART.h" +#include "supervisor/shared/tick.h" + +mp_obj_t common_hal_usb_cdc_serial_construct_from_device(usb_cdc_serial_obj_t *self, const struct device *uart_device, uint16_t receiver_buffer_size, byte *receiver_buffer) { + common_hal_busio_uart_construct_from_device(self, uart_device, receiver_buffer_size, receiver_buffer); + self->base.type = &usb_cdc_serial_type; + return MP_OBJ_FROM_PTR(self); +} + +size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, size_t len, int *errcode) { + return common_hal_busio_uart_read(self, data, len, errcode); +} + +size_t common_hal_usb_cdc_serial_write(usb_cdc_serial_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + return common_hal_busio_uart_write(self, data, len, errcode); +} + +uint32_t common_hal_usb_cdc_serial_get_in_waiting(usb_cdc_serial_obj_t *self) { + return common_hal_busio_uart_rx_characters_available(self); +} + +uint32_t common_hal_usb_cdc_serial_get_out_waiting(usb_cdc_serial_obj_t *self) { + // Return number of FIFO bytes currently occupied. + // return CFG_TUD_CDC_TX_BUFSIZE - tud_cdc_n_write_available(self->idx); + return 0; +} + +void common_hal_usb_cdc_serial_reset_input_buffer(usb_cdc_serial_obj_t *self) { + common_hal_busio_uart_clear_rx_buffer(self); +} + +uint32_t common_hal_usb_cdc_serial_reset_output_buffer(usb_cdc_serial_obj_t *self) { + // return tud_cdc_n_write_clear(self->idx); + return 0; +} + +uint32_t common_hal_usb_cdc_serial_flush(usb_cdc_serial_obj_t *self) { + // return tud_cdc_n_write_flush(self->idx); + return 0; +} + +bool common_hal_usb_cdc_serial_get_connected(usb_cdc_serial_obj_t *self) { + return !common_hal_busio_uart_deinited(self); +} + +mp_float_t common_hal_usb_cdc_serial_get_timeout(usb_cdc_serial_obj_t *self) { + return common_hal_busio_uart_get_timeout(self); +} + +void common_hal_usb_cdc_serial_set_timeout(usb_cdc_serial_obj_t *self, mp_float_t timeout) { + common_hal_busio_uart_set_timeout(self, timeout); +} + +mp_float_t common_hal_usb_cdc_serial_get_write_timeout(usb_cdc_serial_obj_t *self) { + return common_hal_busio_uart_get_write_timeout(self); +} + +void common_hal_usb_cdc_serial_set_write_timeout(usb_cdc_serial_obj_t *self, mp_float_t write_timeout) { + common_hal_busio_uart_set_write_timeout(self, write_timeout); +} diff --git a/ports/zephyr-cp/common-hal/usb_cdc/Serial.h b/ports/zephyr-cp/common-hal/usb_cdc/Serial.h new file mode 100644 index 00000000000..9a110545a37 --- /dev/null +++ b/ports/zephyr-cp/common-hal/usb_cdc/Serial.h @@ -0,0 +1,14 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-bindings/busio/UART.h" + +typedef busio_uart_obj_t usb_cdc_serial_obj_t; + +// Helper function for Zephyr-specific initialization from device tree +mp_obj_t common_hal_usb_cdc_serial_construct_from_device(usb_cdc_serial_obj_t *self, const struct device *uart_device, uint16_t receiver_buffer_size, byte *receiver_buffer); diff --git a/ports/zephyr-cp/common-hal/usb_cdc/__init__.c b/ports/zephyr-cp/common-hal/usb_cdc/__init__.c new file mode 100644 index 00000000000..7bcae396733 --- /dev/null +++ b/ports/zephyr-cp/common-hal/usb_cdc/__init__.c @@ -0,0 +1,40 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/gc.h" +#include "py/obj.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "py/objtuple.h" +#include "shared-bindings/usb_cdc/__init__.h" +#include "shared-bindings/usb_cdc/Serial.h" +#include "supervisor/usb.h" + +static bool usb_cdc_console_is_enabled; +static bool usb_cdc_data_is_enabled; + +void usb_cdc_set_defaults(void) { + common_hal_usb_cdc_enable(true, + false); +} + +bool usb_cdc_console_enabled(void) { + return usb_cdc_console_is_enabled; +} + +bool usb_cdc_data_enabled(void) { + return usb_cdc_data_is_enabled; +} + +bool common_hal_usb_cdc_disable(void) { + return common_hal_usb_cdc_enable(false, false); +} + +bool common_hal_usb_cdc_enable(bool console, bool data) { + usb_cdc_console_is_enabled = console; + usb_cdc_data_is_enabled = data; + return true; +} diff --git a/ports/zephyr-cp/common-hal/usb_cdc/__init__.h b/ports/zephyr-cp/common-hal/usb_cdc/__init__.h new file mode 100644 index 00000000000..daf06d580ad --- /dev/null +++ b/ports/zephyr-cp/common-hal/usb_cdc/__init__.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/mpconfig.h" +#include "py/objtuple.h" +#include "supervisor/usb.h" + +bool usb_cdc_console_enabled(void); +bool usb_cdc_data_enabled(void); + +void usb_cdc_set_defaults(void); diff --git a/ports/zephyr-cp/common-hal/usb_hid/Device.c b/ports/zephyr-cp/common-hal/usb_hid/Device.c new file mode 100644 index 00000000000..ba263d44d74 --- /dev/null +++ b/ports/zephyr-cp/common-hal/usb_hid/Device.c @@ -0,0 +1,150 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 hathach for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/usb_hid/Device.h" +#include "shared-module/usb_hid/__init__.h" +#include "shared-module/usb_hid/Device.h" +#include "shared-module/usb_hid/report_descriptors.h" +#include "common-hal/usb_hid/__init__.h" +#include "supervisor/shared/tick.h" + +const usb_hid_device_obj_t usb_hid_device_keyboard_obj = { + .base = { + .type = &usb_hid_device_type, + }, + .report_descriptor = keyboard_report_descriptor, + .report_descriptor_length = sizeof(keyboard_report_descriptor), + .usage_page = 0x01, + .usage = 0x06, + .num_report_ids = 1, + .report_ids = { 0x01, }, + .in_report_lengths = { 8, }, + .out_report_lengths = { 1, }, +}; + +const usb_hid_device_obj_t usb_hid_device_mouse_obj = { + .base = { + .type = &usb_hid_device_type, + }, + .report_descriptor = mouse_report_descriptor, + .report_descriptor_length = sizeof(mouse_report_descriptor), + .usage_page = 0x01, + .usage = 0x02, + .num_report_ids = 1, + .report_ids = { 0x02, }, + .in_report_lengths = { 4, }, + .out_report_lengths = { 0, }, +}; + +const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = { + .base = { + .type = &usb_hid_device_type, + }, + .report_descriptor = consumer_control_report_descriptor, + .report_descriptor_length = sizeof(consumer_control_report_descriptor), + .usage_page = 0x0C, + .usage = 0x01, + .num_report_ids = 1, + .report_ids = { 0x03 }, + .in_report_lengths = { 2, }, + .out_report_lengths = { 0, }, +}; + +char *custom_usb_hid_interface_name; + +static size_t get_report_id_idx(usb_hid_device_obj_t *self, size_t report_id) { + for (size_t i = 0; i < self->num_report_ids; i++) { + if (report_id == self->report_ids[i]) { + return i; + } + } + return CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR; +} + +uint8_t common_hal_usb_hid_device_validate_report_id(usb_hid_device_obj_t *self, mp_int_t report_id_arg) { + if (report_id_arg == -1 && self->num_report_ids == 1) { + return self->report_ids[0]; + } + if (!(report_id_arg >= 0 && + get_report_id_idx(self, (size_t)report_id_arg) < CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR)) { + mp_arg_error_invalid(MP_QSTR_report_id); + } + return (uint8_t)report_id_arg; +} + +void common_hal_usb_hid_device_construct(usb_hid_device_obj_t *self, mp_obj_t report_descriptor, uint16_t usage_page, uint16_t usage, size_t num_report_ids, uint8_t *report_ids, uint8_t *in_report_lengths, uint8_t *out_report_lengths) { + mp_arg_validate_length_max( + num_report_ids, CIRCUITPY_USB_HID_MAX_REPORT_IDS_PER_DESCRIPTOR, MP_QSTR_report_ids); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(report_descriptor, &bufinfo, MP_BUFFER_READ); + self->report_descriptor_length = bufinfo.len; + + uint8_t *descriptor_bytes = gc_alloc(bufinfo.len, false); + memcpy(descriptor_bytes, bufinfo.buf, bufinfo.len); + self->report_descriptor = descriptor_bytes; + + self->usage_page = usage_page; + self->usage = usage; + self->num_report_ids = num_report_ids; + memcpy(self->report_ids, report_ids, num_report_ids); + memcpy(self->in_report_lengths, in_report_lengths, num_report_ids); + memcpy(self->out_report_lengths, out_report_lengths, num_report_ids); +} + +uint16_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self) { + return self->usage_page; +} + +uint16_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self) { + return self->usage; +} + +void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t *report, uint8_t len, uint8_t report_id) { + size_t id_idx = get_report_id_idx(self, report_id); + + mp_arg_validate_length(len, self->in_report_lengths[id_idx], MP_QSTR_report); + + // Wait until interface is ready, timeout = 2 seconds + uint64_t end_ticks = supervisor_ticks_ms64() + 2000; + while ((supervisor_ticks_ms64() < end_ticks) && !usb_hid_ready()) { + RUN_BACKGROUND_TASKS; + } + + if (!usb_hid_submit_report(report_id, report, len)) { + mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("USB error")); + } +} + +mp_obj_t common_hal_usb_hid_device_get_last_received_report(usb_hid_device_obj_t *self, uint8_t report_id) { + size_t id_idx = get_report_id_idx(self, report_id); + if (!self->out_report_buffers_updated[id_idx]) { + return mp_const_none; + } + self->out_report_buffers_updated[id_idx] = false; + return mp_obj_new_bytes(self->out_report_buffers[id_idx], self->out_report_lengths[id_idx]); +} + +void usb_hid_device_create_report_buffers(usb_hid_device_obj_t *self) { + for (size_t i = 0; i < self->num_report_ids; i++) { + self->in_report_buffers[i] = + self->in_report_lengths[i] > 0 + ? gc_alloc(self->in_report_lengths[i], false) + : NULL; + + self->out_report_buffers[i] = + self->out_report_lengths[i] > 0 + ? gc_alloc(self->out_report_lengths[i], false) + : NULL; + } + memset(self->out_report_buffers_updated, 0, sizeof(self->out_report_buffers_updated)); +} diff --git a/ports/zephyr-cp/common-hal/usb_hid/__init__.c b/ports/zephyr-cp/common-hal/usb_hid/__init__.c new file mode 100644 index 00000000000..552a91e102b --- /dev/null +++ b/ports/zephyr-cp/common-hal/usb_hid/__init__.c @@ -0,0 +1,377 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/usb_hid/__init__.h" +#include "shared-bindings/usb_hid/Device.h" +#include "shared-module/usb_hid/Device.h" +#include "supervisor/port.h" + +#include +#include +#include +#include +#include + +#define MAX_HID_DEVICES 8 + +static usb_hid_device_obj_t hid_devices[MAX_HID_DEVICES]; +// If 0, USB HID is disabled. +static mp_int_t num_hid_devices; +// Which boot device is available? 0: no boot devices, 1: boot keyboard, 2: boot mouse. +static uint8_t hid_boot_device; +// Whether a boot device was requested by a SET_PROTOCOL request from the host. +static bool hid_boot_device_requested; +// This tuple is stored in usb_hid.devices. +static mp_obj_tuple_t *hid_devices_tuple; + +// Whether the HID interface is ready (USB configured). +static bool hid_interface_ready; + +static mp_obj_tuple_t default_hid_devices_tuple = { + .base = { + .type = &mp_type_tuple, + }, + .len = 3, + .items = { + MP_OBJ_FROM_PTR(&usb_hid_device_keyboard_obj), + MP_OBJ_FROM_PTR(&usb_hid_device_mouse_obj), + MP_OBJ_FROM_PTR(&usb_hid_device_consumer_control_obj), + }, +}; + +// These describe the standard descriptors used for boot keyboard and mouse, +// which don't use report IDs. +static const usb_hid_device_obj_t boot_keyboard_obj = { + .base = { + .type = &usb_hid_device_type, + }, + .report_descriptor = NULL, + .report_descriptor_length = 0, + .usage_page = 0x01, + .usage = 0x06, + .num_report_ids = 1, + .report_ids = { 0, }, + .in_report_lengths = { 8, }, + .out_report_lengths = { 1, }, +}; + +static const usb_hid_device_obj_t boot_mouse_obj = { + .base = { + .type = &usb_hid_device_type, + }, + .report_descriptor = NULL, + .report_descriptor_length = 0, + .usage_page = 0x01, + .usage = 0x02, + .num_report_ids = 1, + .report_ids = { 0, }, + .in_report_lengths = { 4, }, + .out_report_lengths = { 0, }, +}; + +bool usb_hid_enabled(void) { + return num_hid_devices > 0; +} + +uint8_t usb_hid_boot_device(void) { + return hid_boot_device; +} + +// Returns 1 or 2 if host requested a boot device and boot protocol was enabled. +uint8_t common_hal_usb_hid_get_boot_device(void) { + return hid_boot_device_requested ? hid_boot_device : 0; +} + +void usb_hid_set_defaults(void) { + hid_boot_device = 0; + hid_boot_device_requested = false; + hid_interface_ready = false; + common_hal_usb_hid_enable( + CIRCUITPY_USB_HID_ENABLED_DEFAULT ? &default_hid_devices_tuple : mp_const_empty_tuple, 0); +} + +// Make up a fresh tuple containing the device objects saved in the static +// devices table. Save the tuple in usb_hid.devices. +static void usb_hid_set_devices_from_hid_devices(void) { + mp_obj_t tuple_items[num_hid_devices]; + for (mp_int_t i = 0; i < num_hid_devices; i++) { + tuple_items[i] = &hid_devices[i]; + } + hid_devices_tuple = mp_obj_new_tuple(num_hid_devices, tuple_items); + usb_hid_set_devices(hid_devices_tuple); +} + +bool common_hal_usb_hid_disable(void) { + return common_hal_usb_hid_enable(mp_const_empty_tuple, 0); +} + +bool common_hal_usb_hid_enable(const mp_obj_t devices, uint8_t boot_device) { + // We can't change the devices once USB is connected. + if (hid_interface_ready) { + return false; + } + + const mp_int_t num_devices = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(devices)); + mp_arg_validate_length_max(num_devices, MAX_HID_DEVICES, MP_QSTR_devices); + + num_hid_devices = num_devices; + hid_boot_device = boot_device; + + // Remember the devices in static storage so they live across VMs. + for (mp_int_t i = 0; i < num_hid_devices; i++) { + usb_hid_device_obj_t *device = + MP_OBJ_TO_PTR(mp_obj_subscr(devices, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL)); + memcpy(&hid_devices[i], device, sizeof(usb_hid_device_obj_t)); + } + + usb_hid_set_devices_from_hid_devices(); + + return true; +} + +// Called when HID devices are ready to be used, when code.py or the REPL starts running. +void usb_hid_setup_devices(void) { + // If the host requested a boot device, replace the current list of devices + // with a single-element tuple containing the proper boot device. + if (hid_boot_device_requested) { + memcpy(&hid_devices[0], + hid_boot_device == 1 ? &boot_keyboard_obj : &boot_mouse_obj, + sizeof(usb_hid_device_obj_t)); + num_hid_devices = 1; + } + + usb_hid_set_devices_from_hid_devices(); + + // Create report buffers on the heap. + for (mp_int_t i = 0; i < num_hid_devices; i++) { + usb_hid_device_create_report_buffers(&hid_devices[i]); + } +} + +// Build the combined HID report descriptor from all devices. +static uint8_t *hid_report_descriptor = NULL; + +size_t usb_hid_report_descriptor_length(void) { + size_t total_hid_report_descriptor_length = 0; + for (mp_int_t i = 0; i < num_hid_devices; i++) { + total_hid_report_descriptor_length += hid_devices[i].report_descriptor_length; + } + return total_hid_report_descriptor_length; +} + +void usb_hid_build_report_descriptor(void) { + if (!usb_hid_enabled()) { + return; + } + size_t report_length = usb_hid_report_descriptor_length(); + hid_report_descriptor = port_malloc(report_length, false); + if (hid_report_descriptor == NULL) { + return; + } + + uint8_t *report_descriptor_start = hid_report_descriptor; + for (mp_int_t i = 0; i < num_hid_devices; i++) { + usb_hid_device_obj_t *device = &hid_devices[i]; + memcpy(report_descriptor_start, device->report_descriptor, device->report_descriptor_length); + report_descriptor_start += device->report_descriptor_length; + // Clear the heap pointer to the bytes of the descriptor. + device->report_descriptor = NULL; + } +} + +void usb_hid_gc_collect(void) { + gc_collect_ptr(hid_devices_tuple); + + for (mp_int_t device_idx = 0; device_idx < num_hid_devices; device_idx++) { + gc_collect_ptr((void *)hid_devices[device_idx].report_descriptor); + + for (size_t id_idx = 0; id_idx < hid_devices[device_idx].num_report_ids; id_idx++) { + gc_collect_ptr(hid_devices[device_idx].in_report_buffers[id_idx]); + gc_collect_ptr(hid_devices[device_idx].out_report_buffers[id_idx]); + } + } +} + +bool usb_hid_get_device_with_report_id(uint8_t report_id, usb_hid_device_obj_t **device_out, size_t *id_idx_out) { + for (uint8_t device_idx = 0; device_idx < num_hid_devices; device_idx++) { + usb_hid_device_obj_t *device = &hid_devices[device_idx]; + for (size_t id_idx = 0; id_idx < device->num_report_ids; id_idx++) { + if (device->report_ids[id_idx] == report_id) { + *device_out = device; + *id_idx_out = id_idx; + return true; + } + } + } + return false; +} + +// ===== Zephyr USBD HID Device Callbacks ===== + +static void hid_iface_ready(const struct device *dev, const bool ready) { + hid_interface_ready = ready; +} + +static int hid_get_report(const struct device *dev, + const uint8_t type, const uint8_t id, + const uint16_t len, uint8_t *const buf) { + // Support Input Report and Feature Report + if (type != HID_REPORT_TYPE_INPUT && type != HID_REPORT_TYPE_FEATURE) { + return -ENOTSUP; + } + + usb_hid_device_obj_t *hid_device; + size_t id_idx; + if (!usb_hid_get_device_with_report_id(id, &hid_device, &id_idx)) { + return 0; + } + if (!hid_device->in_report_buffers[id_idx]) { + return 0; + } + + uint8_t in_len = hid_device->in_report_lengths[id_idx]; + const uint8_t *src = hid_device->in_report_buffers[id_idx]; + + // When the descriptor uses Report IDs (id != 0), the on-wire report is + // prefixed with the Report ID byte. Zephyr sends the buffer verbatim, so + // prepend the ID here. id == 0 means no Report ID item -> no prefix. + if (id != 0) { + if (len == 0) { + return 0; + } + buf[0] = id; + uint16_t copy_len = len - 1; + if (copy_len > in_len) { + copy_len = in_len; + } + memcpy(&buf[1], src, copy_len); + return 1 + copy_len; + } + + uint16_t copy_len = len; + if (copy_len > in_len) { + copy_len = in_len; + } + memcpy(buf, src, copy_len); + return copy_len; +} + +static int hid_set_report(const struct device *dev, + const uint8_t type, const uint8_t id, + const uint16_t len, const uint8_t *const buf) { + uint8_t report_id = id; + const uint8_t *data = buf; + uint16_t data_len = len; + + if (report_id != 0 && len > 0) { + // Descriptor uses Report IDs: the on-wire SET_REPORT data stage is + // prefixed with the Report ID byte. Zephyr passes the raw payload, so + // strip the leading ID byte (it should match the id from wValue). + if (buf[0] == report_id) { + data = &buf[1]; + data_len = len - 1; + } + } else if (report_id == 0 && len > 0) { + // id==0 normally means no Report ID item (no prefix). But if no device + // has report ID 0 with a matching out length, treat the first byte as a + // report ID (host sent a prefixed report despite id==0). + usb_hid_device_obj_t *hid0 = NULL; + size_t idx0; + if (!(usb_hid_get_device_with_report_id(0, &hid0, &idx0) && + hid0 && hid0->out_report_buffers[idx0] && + hid0->out_report_lengths[idx0] == len)) { + report_id = buf[0]; + data = &buf[1]; + data_len = len - 1; + } + } + + // Look up the device for the resolved report_id. + usb_hid_device_obj_t *hid_device = NULL; + size_t id_idx; + if (!usb_hid_get_device_with_report_id(report_id, &hid_device, &id_idx)) { + return -EINVAL; + } + + if (hid_device->out_report_buffers[id_idx] && + hid_device->out_report_lengths[id_idx] == data_len) { + memcpy(hid_device->out_report_buffers[id_idx], data, data_len); + hid_device->out_report_buffers_updated[id_idx] = true; + return 0; + } + + return -EINVAL; +} + +static void hid_set_protocol(const struct device *dev, const uint8_t proto) { + hid_boot_device_requested = (proto == HID_PROTOCOL_BOOT); +} + +static struct hid_device_ops hid_ops = { + .iface_ready = hid_iface_ready, + .get_report = hid_get_report, + .set_report = hid_set_report, + .set_protocol = hid_set_protocol, +}; + +// ===== HID Device Registration ===== + +// Get the Zephyr HID device for submitting reports +static const struct device *hid_zephyr_dev; + +const struct device *usb_hid_get_zephyr_device(void) { + return hid_zephyr_dev; +} + +void usb_hid_init_devices(void) { + if (!usb_hid_enabled()) { + return; + } + + hid_zephyr_dev = DEVICE_DT_GET_ONE(zephyr_hid_device); + if (!device_is_ready(hid_zephyr_dev)) { + return; + } + + usb_hid_build_report_descriptor(); + if (hid_report_descriptor == NULL) { + return; + } + + int ret = hid_device_register(hid_zephyr_dev, + hid_report_descriptor, + usb_hid_report_descriptor_length(), + &hid_ops); + if (ret != 0) { + return; + } +} + +bool usb_hid_ready(void) { + return hid_zephyr_dev != NULL && hid_interface_ready; +} + +// Submit an input report through Zephyr's HID device. +// Called from common_hal_usb_hid_device_send_report(). +bool usb_hid_submit_report(uint8_t report_id, const uint8_t *report, uint8_t len) { + if (hid_zephyr_dev == NULL || !hid_interface_ready) { + return false; + } + + // Send report_id zero without a prefix + if (report_id == 0) { + return hid_device_submit_report(hid_zephyr_dev, len, report) == 0; + } + + uint8_t __attribute__((aligned(sizeof(void *)))) report_buffer[1 + len]; + report_buffer[0] = report_id; + memcpy(&report_buffer[1], report, len); + return hid_device_submit_report(hid_zephyr_dev, len + 1, report_buffer) == 0; +} diff --git a/ports/zephyr-cp/common-hal/usb_hid/__init__.h b/ports/zephyr-cp/common-hal/usb_hid/__init__.h new file mode 100644 index 00000000000..1985ea29549 --- /dev/null +++ b/ports/zephyr-cp/common-hal/usb_hid/__init__.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/usb_hid/Device.h" +#include "supervisor/usb.h" + +extern usb_hid_device_obj_t usb_hid_devices[]; + +bool usb_hid_enabled(void); +uint8_t usb_hid_boot_device(void); +void usb_hid_set_defaults(void); +void usb_hid_setup_devices(void); +size_t usb_hid_report_descriptor_length(void); +void usb_hid_build_report_descriptor(void); +bool usb_hid_get_device_with_report_id(uint8_t report_id, usb_hid_device_obj_t **device_out, size_t *id_idx_out); +void usb_hid_gc_collect(void); + +// For supervisor/usb.c integration +void usb_hid_init_devices(void); + +// For Device.c send_report +bool usb_hid_ready(void); +bool usb_hid_submit_report(uint8_t report_id, const uint8_t *report, uint8_t len); diff --git a/ports/zephyr-cp/common-hal/wifi/Monitor.c b/ports/zephyr-cp/common-hal/wifi/Monitor.c new file mode 100644 index 00000000000..7cacb8b520a --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/Monitor.c @@ -0,0 +1,146 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/mpstate.h" +#include "py/runtime.h" + +#include "shared-bindings/wifi/Monitor.h" +#include "shared-bindings/wifi/Packet.h" + +#define MONITOR_PAYLOAD_FCS_LEN (4) +#define MONITOR_QUEUE_TIMEOUT_TICK (0) + +typedef struct { + void *payload; + unsigned channel; + uint32_t length; + signed rssi; +} monitor_packet_t; + +// static void wifi_monitor_cb(void *recv_buf, wifi_promiscuous_pkt_type_t type) { +// wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)recv_buf; + +// // prepare packet +// monitor_packet_t packet = { +// .channel = pkt->rx_ctrl.channel, +// .length = pkt->rx_ctrl.sig_len, +// .rssi = pkt->rx_ctrl.rssi, +// }; + +// // for now, the monitor only dumps the length of the MISC type frame +// if (type != WIFI_PKT_MISC && !pkt->rx_ctrl.rx_state) { +// packet.length -= MONITOR_PAYLOAD_FCS_LEN; +// packet.payload = malloc(packet.length); +// if (packet.payload) { +// memcpy(packet.payload, pkt->payload, packet.length); +// wifi_monitor_obj_t *self = MP_STATE_VM(wifi_monitor_singleton); +// if (self->queue) { +// // send packet +// if (xQueueSendFromISR(self->queue, &packet, NULL) != pdTRUE) { +// self->lost++; +// free(packet.payload); +// ESP_LOGE(TAG, "packet queue full"); +// } +// } +// } else { +// ESP_LOGE(TAG, "not enough memory for packet"); +// } +// } +// } + +void common_hal_wifi_monitor_construct(wifi_monitor_obj_t *self, uint8_t channel, size_t queue) { + // mp_rom_error_text_t monitor_mode_init_error = MP_ERROR_TEXT("monitor init failed"); + + // self->queue = xQueueCreate(queue, sizeof(monitor_packet_t)); + // if (!self->queue) { + // mp_raise_RuntimeError(monitor_mode_init_error); + // } + + // // start wifi promicuous mode + // wifi_promiscuous_filter_t wifi_filter = { + // .filter_mask = WIFI_PROMIS_FILTER_MASK_MGMT, + // }; + // esp_wifi_set_promiscuous_filter(&wifi_filter); + // esp_wifi_set_promiscuous_rx_cb(wifi_monitor_cb); + // if (esp_wifi_set_promiscuous(true) != ESP_OK) { + // mp_raise_RuntimeError(monitor_mode_init_error); + // } + // esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); + + // self->channel = channel; + // self->queue_length = queue; +} + +bool common_hal_wifi_monitor_deinited(void) { + // bool enabled; + // return (esp_wifi_get_promiscuous(&enabled) == ESP_ERR_WIFI_NOT_INIT) ? true : !enabled; + return true; +} + +void common_hal_wifi_monitor_deinit(wifi_monitor_obj_t *self) { + if (common_hal_wifi_monitor_deinited()) { + return; + } + + // // disable wifi promiscuous mode + // esp_wifi_set_promiscuous(false); + + // // make sure to free all resources in the left items + // UBaseType_t left_items = uxQueueMessagesWaiting(self->queue); + // monitor_packet_t packet; + // while (left_items--) { + // xQueueReceive(self->queue, &packet, MONITOR_QUEUE_TIMEOUT_TICK); + // free(packet.payload); + // } + // vQueueDelete(self->queue); + // self->queue = NULL; +} + +void common_hal_wifi_monitor_set_channel(wifi_monitor_obj_t *self, uint8_t channel) { + self->channel = channel; + // esp_wifi_set_channel(channel, WIFI_SECOND_CHAN_NONE); +} + +mp_obj_t common_hal_wifi_monitor_get_channel(wifi_monitor_obj_t *self) { + return MP_OBJ_NEW_SMALL_INT(self->channel); +} + +mp_obj_t common_hal_wifi_monitor_get_queue(wifi_monitor_obj_t *self) { + return mp_obj_new_int_from_uint(self->queue_length); +} + +mp_obj_t common_hal_wifi_monitor_get_lost(wifi_monitor_obj_t *self) { + size_t lost = self->lost; + self->lost = 0; + return mp_obj_new_int_from_uint(lost); +} + +mp_obj_t common_hal_wifi_monitor_get_queued(wifi_monitor_obj_t *self) { + return mp_obj_new_int_from_uint(0); // uxQueueMessagesWaiting(self->queue)); +} + +mp_obj_t common_hal_wifi_monitor_get_packet(wifi_monitor_obj_t *self) { + monitor_packet_t packet; + + // if (xQueueReceive(self->queue, &packet, MONITOR_QUEUE_TIMEOUT_TICK) != pdTRUE) { + // return (mp_obj_t)&mp_const_empty_dict_obj; + // } + + mp_obj_dict_t *dict = MP_OBJ_TO_PTR(mp_obj_new_dict(4)); + + mp_obj_dict_store(dict, cp_enum_find(&wifi_packet_type, PACKET_CH), MP_OBJ_NEW_SMALL_INT(packet.channel)); + + mp_obj_dict_store(dict, cp_enum_find(&wifi_packet_type, PACKET_LEN), MP_OBJ_NEW_SMALL_INT(packet.length)); + + mp_obj_dict_store(dict, cp_enum_find(&wifi_packet_type, PACKET_RAW), mp_obj_new_bytes(packet.payload, packet.length)); + free(packet.payload); + + mp_obj_dict_store(dict, cp_enum_find(&wifi_packet_type, PACKET_RSSI), MP_OBJ_NEW_SMALL_INT(packet.rssi)); + + return MP_OBJ_FROM_PTR(dict); +} diff --git a/ports/zephyr-cp/common-hal/wifi/Monitor.h b/ports/zephyr-cp/common-hal/wifi/Monitor.h new file mode 100644 index 00000000000..e0cdd7b619f --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/Monitor.h @@ -0,0 +1,17 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2021 microDev +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t channel; + size_t lost; + size_t queue_length; + // QueueHandle_t queue; +} wifi_monitor_obj_t; diff --git a/ports/zephyr-cp/common-hal/wifi/Network.c b/ports/zephyr-cp/common-hal/wifi/Network.c new file mode 100644 index 00000000000..44c049f88c1 --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/Network.c @@ -0,0 +1,75 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/wifi/Network.h" +#include "shared-bindings/wifi/AuthMode.h" + +mp_obj_t common_hal_wifi_network_get_ssid(wifi_network_obj_t *self) { + const char *cstr = (const char *)self->scan_result.ssid; + return mp_obj_new_str(cstr, self->scan_result.ssid_length); +} + +mp_obj_t common_hal_wifi_network_get_bssid(wifi_network_obj_t *self) { + return mp_obj_new_bytes(self->scan_result.mac, self->scan_result.mac_length); +} + +mp_obj_t common_hal_wifi_network_get_rssi(wifi_network_obj_t *self) { + return mp_obj_new_int(self->scan_result.rssi); +} + +mp_obj_t common_hal_wifi_network_get_channel(wifi_network_obj_t *self) { + return mp_obj_new_int(self->scan_result.channel); +} + +mp_obj_t common_hal_wifi_network_get_country(wifi_network_obj_t *self) { + // const char *cstr = (const char *)self->record.country.cc; + // 2 instead of strlen(cstr) as this gives us only the country-code + // return mp_obj_new_str(cstr, 2); + return mp_const_none; +} + +mp_obj_t common_hal_wifi_network_get_authmode(wifi_network_obj_t *self) { + uint32_t authmode_mask = 0; + // switch (self->record.authmode) { + // case WIFI_AUTH_OPEN: + // authmode_mask = AUTHMODE_OPEN; + // break; + // case WIFI_AUTH_WEP: + // authmode_mask = AUTHMODE_WEP; + // break; + // case WIFI_AUTH_WPA_PSK: + // authmode_mask = AUTHMODE_WPA | AUTHMODE_PSK; + // break; + // case WIFI_AUTH_WPA2_PSK: + // authmode_mask = AUTHMODE_WPA2 | AUTHMODE_PSK; + // break; + // case WIFI_AUTH_WPA_WPA2_PSK: + // authmode_mask = AUTHMODE_WPA | AUTHMODE_WPA2 | AUTHMODE_PSK; + // break; + // case WIFI_AUTH_WPA2_ENTERPRISE: + // authmode_mask = AUTHMODE_WPA2 | AUTHMODE_ENTERPRISE; + // break; + // case WIFI_AUTH_WPA3_PSK: + // authmode_mask = AUTHMODE_WPA3 | AUTHMODE_PSK; + // break; + // case WIFI_AUTH_WPA2_WPA3_PSK: + // authmode_mask = AUTHMODE_WPA2 | AUTHMODE_WPA3 | AUTHMODE_PSK; + // break; + // default: + // break; + // } + mp_obj_t authmode_list = mp_obj_new_list(0, NULL); + if (authmode_mask != 0) { + for (uint8_t i = 0; i < 32; i++) { + if ((authmode_mask >> i) & 1) { + mp_obj_list_append(authmode_list, cp_enum_find(&wifi_authmode_type, 1 << i)); + } + } + } + return authmode_list; +} diff --git a/ports/zephyr-cp/common-hal/wifi/Network.h b/ports/zephyr-cp/common-hal/wifi/Network.h new file mode 100644 index 00000000000..bd6bc07ea1e --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/Network.h @@ -0,0 +1,16 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include + +typedef struct { + mp_obj_base_t base; + struct wifi_scan_result scan_result; +} wifi_network_obj_t; diff --git a/ports/zephyr-cp/common-hal/wifi/Radio.c b/ports/zephyr-cp/common-hal/wifi/Radio.c new file mode 100644 index 00000000000..35a0b76a362 --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/Radio.c @@ -0,0 +1,780 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/wifi/Radio.h" +#include "ports/zephyr-cp/common-hal/wifi/ScannedNetworks.h" +#include "shared-bindings/wifi/Network.h" + +#include + +#include "common-hal/wifi/__init__.h" +#include "shared/runtime/interrupt_char.h" +#include "py/gc.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "shared-bindings/ipaddress/IPv4Address.h" +#include "shared-bindings/wifi/ScannedNetworks.h" +#include "shared-bindings/wifi/AuthMode.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/ipaddress/__init__.h" +#include "common-hal/socketpool/__init__.h" + +#include "bindings/zephyr_kernel/__init__.h" + +#include +#include +#include +#include + +#if CIRCUITPY_MDNS +#include "common-hal/mdns/Server.h" +#endif + +#define MAC_ADDRESS_LENGTH 6 + +// static void set_mode_station(wifi_radio_obj_t *self, bool state) { +// wifi_mode_t next_mode; +// if (state) { +// if (self->ap_mode) { +// next_mode = WIFI_MODE_APSTA; +// } else { +// next_mode = WIFI_MODE_STA; +// } +// } else { +// if (self->ap_mode) { +// next_mode = WIFI_MODE_AP; +// } else { +// next_mode = WIFI_MODE_NULL; +// } +// } +// esp_wifi_set_mode(next_mode); +// self->sta_mode = state; +// } + +// static void set_mode_ap(wifi_radio_obj_t *self, bool state) { +// wifi_mode_t next_mode; +// if (state) { +// if (self->sta_mode) { +// next_mode = WIFI_MODE_APSTA; +// } else { +// next_mode = WIFI_MODE_AP; +// } +// } else { +// if (self->sta_mode) { +// next_mode = WIFI_MODE_STA; +// } else { +// next_mode = WIFI_MODE_NULL; +// } +// } +// esp_wifi_set_mode(next_mode); +// self->ap_mode = state; +// } + +bool common_hal_wifi_radio_get_enabled(wifi_radio_obj_t *self) { + return self->started; +} + +void common_hal_wifi_radio_set_enabled(wifi_radio_obj_t *self, bool enabled) { + if (self->started && !enabled) { + if (self->current_scan != NULL) { + common_hal_wifi_radio_stop_scanning_networks(self); + } + // #if CIRCUITPY_MDNS + // mdns_server_deinit_singleton(); + // #endif + printk("net_if_down\n"); + int res = net_if_down(self->sta_netif); + if (res < 0 && res != -EALREADY) { + raise_zephyr_error(res); + } + self->started = false; + return; + } + if (!self->started && enabled) { + printk("net_if_up\n"); + int res = net_if_up(self->sta_netif); + if (res < 0 && res != -EALREADY) { + raise_zephyr_error(res); + } + self->started = true; + self->current_scan = NULL; + // common_hal_wifi_radio_set_tx_power(self, CIRCUITPY_WIFI_DEFAULT_TX_POWER); + return; + } +} + +mp_obj_t common_hal_wifi_radio_get_hostname(wifi_radio_obj_t *self) { + const char *hostname = net_hostname_get(); + return mp_obj_new_str(hostname, strlen(hostname)); +} + +void common_hal_wifi_radio_set_hostname(wifi_radio_obj_t *self, const char *hostname) { + if (net_hostname_set((char *)hostname, strlen(hostname)) != 0) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Failed to set hostname")); + } +} + +mp_obj_t common_hal_wifi_radio_get_mac_address(wifi_radio_obj_t *self) { + uint8_t mac[MAC_ADDRESS_LENGTH]; + // esp_wifi_get_mac(ESP_IF_WIFI_STA, mac); + return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH); +} + +void common_hal_wifi_radio_set_mac_address(wifi_radio_obj_t *self, const uint8_t *mac) { + if (!self->sta_mode) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Interface must be started")); + } + if ((mac[0] & 0b1) == 0b1) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid multicast MAC address")); + } + // esp_wifi_set_mac(ESP_IF_WIFI_STA, mac); +} + +mp_float_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self) { + int8_t tx_power = 0; + // esp_wifi_get_max_tx_power(&tx_power); + return tx_power / 4.0f; +} + +void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t tx_power) { + // esp_wifi_set_max_tx_power(tx_power * 4.0f); +} + +wifi_power_management_t common_hal_wifi_radio_get_power_management(wifi_radio_obj_t *self) { + // wifi_ps_type_t ps; + // esp_err_t ret = esp_wifi_get_ps(&ps); + // if (ret == ESP_OK) { + // switch (ps) { + // case WIFI_PS_MIN_MODEM: + // return POWER_MANAGEMENT_MIN; + // case WIFI_PS_MAX_MODEM: + // return POWER_MANAGEMENT_MAX; + // case WIFI_PS_NONE: + // return POWER_MANAGEMENT_NONE; + // } + // } + return POWER_MANAGEMENT_UNKNOWN; +} + + +void common_hal_wifi_radio_set_power_management(wifi_radio_obj_t *self, wifi_power_management_t power_management) { + // switch (power_management) { + // case POWER_MANAGEMENT_MIN: + // esp_wifi_set_ps(WIFI_PS_MIN_MODEM); + // break; + // case POWER_MANAGEMENT_MAX: { + // // listen_interval is only used in this case. + // wifi_config_t *config = &self->sta_config; + // // This is a typical value seen in various examples. + // config->sta.listen_interval = 3; + // esp_wifi_set_ps(WIFI_PS_MAX_MODEM); + // esp_wifi_set_config(ESP_IF_WIFI_STA, config); + // } + // break; + // case POWER_MANAGEMENT_NONE: + // esp_wifi_set_ps(WIFI_PS_NONE); + // break; + // case POWER_MANAGEMENT_UNKNOWN: + // // This should be prevented in shared-bindings. + // break; + // } +} + +void common_hal_wifi_radio_set_listen_interval(wifi_radio_obj_t *self, const mp_int_t listen_interval) { + // wifi_config_t *config = &self->sta_config; + // config->sta.listen_interval = listen_interval; + // if (listen_interval == 1) { + // esp_wifi_set_ps(WIFI_PS_MIN_MODEM); + // } else if (listen_interval > 1) { + // esp_wifi_set_ps(WIFI_PS_MAX_MODEM); + // } else { + // esp_wifi_set_ps(WIFI_PS_NONE); + // } + + // esp_wifi_set_config(ESP_IF_WIFI_STA, config); +} + +mp_obj_t common_hal_wifi_radio_get_mac_address_ap(wifi_radio_obj_t *self) { + uint8_t mac[MAC_ADDRESS_LENGTH]; + // esp_wifi_get_mac(ESP_IF_WIFI_AP, mac); + return mp_obj_new_bytes(mac, MAC_ADDRESS_LENGTH); +} + +void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, const uint8_t *mac) { + if (!self->ap_mode) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Interface must be started")); + } + if ((mac[0] & 0b1) == 0b1) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Invalid multicast MAC address")); + } + // esp_wifi_set_mac(ESP_IF_WIFI_AP, mac); +} + +mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel) { + printk("common_hal_wifi_radio_start_scanning_networks\n"); + if (self->current_scan != NULL) { + printk("Already scanning for wifi networks\n"); + mp_raise_RuntimeError(MP_ERROR_TEXT("Already scanning for wifi networks")); + } + if (!common_hal_wifi_radio_get_enabled(self)) { + printk("WiFi is not enabled\n"); + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); + } + + wifi_scannednetworks_obj_t *scan = mp_obj_malloc(wifi_scannednetworks_obj_t, &wifi_scannednetworks_type); + self->current_scan = scan; + scan->current_channel_index = 0; + scan->start_channel = start_channel; + scan->end_channel = stop_channel; + scan->done = false; + scan->channel_scan_in_progress = false; + scan->netif = self->sta_netif; + + k_msgq_init(&scan->msgq, scan->msgq_buffer, sizeof(struct wifi_scan_result), MAX_BUFFERED_SCAN_RESULTS); + k_fifo_init(&scan->fifo); + + k_poll_event_init(&scan->events[0], + K_POLL_TYPE_SEM_AVAILABLE, + K_POLL_MODE_NOTIFY_ONLY, + &mp_interrupt_sem); + + k_poll_event_init(&scan->events[1], + K_POLL_TYPE_MSGQ_DATA_AVAILABLE, + K_POLL_MODE_NOTIFY_ONLY, + &scan->msgq); + wifi_scannednetworks_scan_next_channel(scan); + printk("common_hal_wifi_radio_start_scanning_networks done %p\n", scan); + return scan; +} + +void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self) { + printk("common_hal_wifi_radio_stop_scanning_networks\n"); + // Return early if self->current_scan is NULL to avoid hang + if (self->current_scan == NULL) { + return; + } + // Free the memory used to store the found aps. + wifi_scannednetworks_deinit(self->current_scan); + self->current_scan = NULL; +} + +void common_hal_wifi_radio_start_station(wifi_radio_obj_t *self) { + // set_mode_station(self, true); +} + +void common_hal_wifi_radio_stop_station(wifi_radio_obj_t *self) { + // set_mode_station(self, false); +} + +void common_hal_wifi_radio_start_ap(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, uint32_t authmode, uint8_t max_connections) { + // set_mode_ap(self, true); + + // uint8_t esp_authmode = 0; + // switch (authmode) { + // case AUTHMODE_OPEN: + // esp_authmode = WIFI_AUTH_OPEN; + // break; + // case AUTHMODE_WPA | AUTHMODE_PSK: + // esp_authmode = WIFI_AUTH_WPA_PSK; + // break; + // case AUTHMODE_WPA2 | AUTHMODE_PSK: + // esp_authmode = WIFI_AUTH_WPA2_PSK; + // break; + // case AUTHMODE_WPA | AUTHMODE_WPA2 | AUTHMODE_PSK: + // esp_authmode = WIFI_AUTH_WPA_WPA2_PSK; + // break; + // default: + // mp_arg_error_invalid(MP_QSTR_authmode); + // break; + // } + + // wifi_config_t *config = &self->ap_config; + // memcpy(&config->ap.ssid, ssid, ssid_len); + // config->ap.ssid[ssid_len] = 0; + // memcpy(&config->ap.password, password, password_len); + // config->ap.password[password_len] = 0; + // config->ap.channel = channel; + // config->ap.authmode = esp_authmode; + + // mp_arg_validate_int_range(max_connections, 0, 10, MP_QSTR_max_connections); + + // config->ap.max_connection = max_connections; + + // esp_wifi_set_config(WIFI_IF_AP, config); +} + +bool common_hal_wifi_radio_get_ap_active(wifi_radio_obj_t *self) { + // return self->ap_mode && esp_netif_is_netif_up(self->ap_netif); + return false; +} + +void common_hal_wifi_radio_stop_ap(wifi_radio_obj_t *self) { + // set_mode_ap(self, false); +} + +mp_obj_t common_hal_wifi_radio_get_stations_ap(wifi_radio_obj_t *self) { + // wifi_sta_list_t esp_sta_list; + // esp_err_t result; + + // result = esp_wifi_ap_get_sta_list(&esp_sta_list); + // if (result != ESP_OK) { + // return mp_const_none; + // } + + // esp_netif_pair_mac_ip_t mac_ip_pair[esp_sta_list.num]; + // for (int i = 0; i < esp_sta_list.num; i++) { + // memcpy(mac_ip_pair[i].mac, esp_sta_list.sta[i].mac, MAC_ADDRESS_LENGTH); + // mac_ip_pair[i].ip.addr = 0; + // } + + // result = esp_netif_dhcps_get_clients_by_mac(self->ap_netif, esp_sta_list.num, mac_ip_pair); + // if (result != ESP_OK) { + // return mp_const_none; + // } + + mp_obj_t mp_sta_list = mp_obj_new_list(0, NULL); + // for (int i = 0; i < esp_sta_list.num; i++) { + // mp_obj_t elems[3] = { + // mp_obj_new_bytes(esp_sta_list.sta[i].mac, MAC_ADDRESS_LENGTH), + // MP_OBJ_NEW_SMALL_INT(esp_sta_list.sta[i].rssi), + // mp_const_none + // }; + + // if (mac_ip_pair[i].ip.addr) { + // elems[2] = common_hal_ipaddress_new_ipv4address(mac_ip_pair[i].ip.addr); + // } + + // mp_obj_list_append(mp_sta_list, namedtuple_make_new((const mp_obj_type_t *)&wifi_radio_station_type, 3, 0, elems)); + // } + + return mp_sta_list; +} + +wifi_radio_error_t common_hal_wifi_radio_connect(wifi_radio_obj_t *self, uint8_t *ssid, size_t ssid_len, uint8_t *password, size_t password_len, uint8_t channel, mp_float_t timeout, uint8_t *bssid, size_t bssid_len) { + if (!common_hal_wifi_radio_get_enabled(self)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("WiFi is not enabled")); + } + // wifi_config_t *config = &self->sta_config; + + // size_t timeout_ms = timeout * 1000; + // uint32_t start_time = common_hal_time_monotonic_ms(); + // uint32_t end_time = start_time + timeout_ms; + + // EventBits_t bits; + // // can't block since both bits are false after wifi_init + // // both bits are true after an existing connection stops + // bits = xEventGroupWaitBits(self->event_group_handle, + // WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT, + // pdTRUE, + // pdTRUE, + // 0); + // bool connected = ((bits & WIFI_CONNECTED_BIT) != 0) && + // !((bits & WIFI_DISCONNECTED_BIT) != 0); + // if (connected) { + // // SSIDs are up to 32 bytes. Assume it is null terminated if it is less. + // if (memcmp(ssid, config->sta.ssid, ssid_len) == 0 && + // (ssid_len == 32 || strlen((const char *)config->sta.ssid) == ssid_len)) { + // // Already connected to the desired network. + // return WIFI_RADIO_ERROR_NONE; + // } else { + // xEventGroupClearBits(self->event_group_handle, WIFI_DISCONNECTED_BIT); + // // Trying to switch networks so disconnect first. + // esp_wifi_disconnect(); + // do { + // RUN_BACKGROUND_TASKS; + // bits = xEventGroupWaitBits(self->event_group_handle, + // WIFI_DISCONNECTED_BIT, + // pdTRUE, + // pdTRUE, + // 0); + // } while ((bits & WIFI_DISCONNECTED_BIT) == 0 && !mp_hal_is_interrupted()); + // } + // } + // // explicitly clear bits since xEventGroupWaitBits may have timed out + // xEventGroupClearBits(self->event_group_handle, WIFI_CONNECTED_BIT); + // xEventGroupClearBits(self->event_group_handle, WIFI_DISCONNECTED_BIT); + // set_mode_station(self, true); + + // memcpy(&config->sta.ssid, ssid, ssid_len); + // if (ssid_len < 32) { + // config->sta.ssid[ssid_len] = 0; + // } + // memcpy(&config->sta.password, password, password_len); + // config->sta.password[password_len] = 0; + // config->sta.channel = channel; + // // From esp_wifi_types.h: + // // Generally, station_config.bssid_set needs to be 0; and it needs + // // to be 1 only when users need to check the MAC address of the AP + // if (bssid_len > 0) { + // memcpy(&config->sta.bssid, bssid, bssid_len); + // config->sta.bssid[bssid_len] = 0; + // config->sta.bssid_set = true; + // } else { + // config->sta.bssid_set = false; + // } + // // If channel is 0 (default/unset) and BSSID is not given, do a full scan instead of fast scan + // // This will ensure that the best AP in range is chosen automatically + // if ((config->sta.bssid_set == 0) && (config->sta.channel == 0)) { + // config->sta.scan_method = WIFI_ALL_CHANNEL_SCAN; + // } else { + // config->sta.scan_method = WIFI_FAST_SCAN; + // } + // esp_wifi_set_config(ESP_IF_WIFI_STA, config); + // self->starting_retries = 5; + // self->retries_left = 5; + // esp_wifi_connect(); + + // do { + // RUN_BACKGROUND_TASKS; + // bits = xEventGroupWaitBits(self->event_group_handle, + // WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT, + // pdTRUE, + // pdTRUE, + // 0); + // // Don't retry anymore if we're over our time budget. + // if (self->retries_left > 0 && common_hal_time_monotonic_ms() > end_time) { + // self->retries_left = 0; + // } + // } while ((bits & (WIFI_CONNECTED_BIT | WIFI_DISCONNECTED_BIT)) == 0 && !mp_hal_is_interrupted()); + + // if ((bits & WIFI_DISCONNECTED_BIT) != 0) { + // if ( + // (self->last_disconnect_reason == WIFI_REASON_AUTH_FAIL) || + // (self->last_disconnect_reason == WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT) || + // (self->last_disconnect_reason == WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY) || + // (self->last_disconnect_reason == WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD) + // ) { + // return WIFI_RADIO_ERROR_AUTH_FAIL; + // } else if (self->last_disconnect_reason == WIFI_REASON_NO_AP_FOUND) { + // return WIFI_RADIO_ERROR_NO_AP_FOUND; + // } + // return self->last_disconnect_reason; + // } else { + // // We're connected, allow us to retry if we get disconnected. + // self->retries_left = self->starting_retries; + // } + return WIFI_RADIO_ERROR_NONE; +} + +bool common_hal_wifi_radio_get_connected(wifi_radio_obj_t *self) { + // return self->sta_mode && esp_netif_is_netif_up(self->netif); + return false; +} + +mp_obj_t common_hal_wifi_radio_get_ap_info(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->netif)) { + return mp_const_none; + // } + + // // Make sure the interface is in STA mode + // if (!self->sta_mode) { + // return mp_const_none; + // } + + // wifi_network_obj_t *ap_info = mp_obj_malloc(wifi_network_obj_t, &wifi_network_type); + // // From esp_wifi.h, the possible return values (typos theirs): + // // ESP_OK: succeed + // // ESP_ERR_WIFI_CONN: The station interface don't initialized + // // ESP_ERR_WIFI_NOT_CONNECT: The station is in disconnect status + // if (esp_wifi_sta_get_ap_info(&self->ap_info.record) != ESP_OK) { + // return mp_const_none; + // } else { + // if (strlen(self->ap_info.record.country.cc) == 0) { + // // Workaround to fill country related information in ap_info until ESP-IDF carries a fix + // // esp_wifi_sta_get_ap_info does not appear to fill wifi_country_t (e.g. country.cc) details + // // (IDFGH-4437) #6267 + // // Note: It is possible that Wi-Fi APs don't have a CC set, then even after this workaround + // // the element would remain empty. + // memset(&self->ap_info.record.country, 0, sizeof(wifi_country_t)); + // if (esp_wifi_get_country(&self->ap_info.record.country) != ESP_OK) { + // return mp_const_none; + // } + // } + // memcpy(&ap_info->record, &self->ap_info.record, sizeof(wifi_ap_record_t)); + // return MP_OBJ_FROM_PTR(ap_info); + // } +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_gateway(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->netif)) { + return mp_const_none; + // } + // esp_netif_get_ip_info(self->netif, &self->ip_info); + // return common_hal_ipaddress_new_ipv4address(self->ip_info.gw.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_gateway_ap(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->ap_netif)) { + return mp_const_none; + // } + // esp_netif_get_ip_info(self->ap_netif, &self->ap_ip_info); + // return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.gw.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_subnet(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->netif)) { + return mp_const_none; + // } + // esp_netif_get_ip_info(self->netif, &self->ip_info); + // return common_hal_ipaddress_new_ipv4address(self->ip_info.netmask.addr); +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_subnet_ap(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->ap_netif)) { + return mp_const_none; + // } + // esp_netif_get_ip_info(self->ap_netif, &self->ap_ip_info); + // return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.netmask.addr); +} + +// static mp_obj_t common_hal_wifi_radio_get_addresses_netif(wifi_radio_obj_t *self, esp_netif_t *netif) { +// if (!esp_netif_is_netif_up(netif)) { +// return mp_const_empty_tuple; +// } +// esp_netif_ip_info_t ip_info; +// esp_netif_get_ip_info(netif, &ip_info); +// int n_addresses4 = ip_info.ip.addr != INADDR_NONE; + +// #if CIRCUITPY_SOCKETPOOL_IPV6 +// esp_ip6_addr_t addresses[LWIP_IPV6_NUM_ADDRESSES]; +// int n_addresses6 = esp_netif_get_all_ip6(netif, &addresses[0]); +// #else +// int n_addresses6 = 0; +// #endif +// int n_addresses = n_addresses4 + n_addresses6; +// mp_obj_tuple_t *result = MP_OBJ_TO_PTR(mp_obj_new_tuple(n_addresses, NULL)); + +// #if CIRCUITPY_SOCKETPOOL_IPV6 +// for (int i = 0; i < n_addresses6; i++) { +// result->items[i] = espaddr6_to_str(&addresses[i]); +// } +// #endif + +// if (n_addresses4) { +// result->items[n_addresses6] = espaddr4_to_str(&ip_info.ip); +// } + +// return MP_OBJ_FROM_PTR(result); +// return mp_const_empty_tuple; +// } + +mp_obj_t common_hal_wifi_radio_get_addresses(wifi_radio_obj_t *self) { + // return common_hal_wifi_radio_get_addresses_netif(self, self->netif); + return mp_const_none; +} + +mp_obj_t common_hal_wifi_radio_get_addresses_ap(wifi_radio_obj_t *self) { + // return common_hal_wifi_radio_get_addresses_netif(self, self->ap_netif); + return mp_const_none; +} + +uint32_t wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->netif)) { + // return 0; + // } + // esp_netif_get_ip_info(self->netif, &self->ip_info); + // return self->ip_info.ip.addr; + return 0; +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_address(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->netif)) { + // return mp_const_none; + // } + // esp_netif_get_ip_info(self->netif, &self->ip_info); + // return common_hal_ipaddress_new_ipv4address(self->ip_info.ip.addr); + return mp_const_none; +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_address_ap(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->ap_netif)) { + // return mp_const_none; + // } + // esp_netif_get_ip_info(self->ap_netif, &self->ap_ip_info); + // return common_hal_ipaddress_new_ipv4address(self->ap_ip_info.ip.addr); + return mp_const_none; +} + +mp_obj_t common_hal_wifi_radio_get_ipv4_dns(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->netif)) { + // return mp_const_none; + // } + + // esp_netif_get_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &self->dns_info); + + // if (self->dns_info.ip.type != ESP_IPADDR_TYPE_V4) { + // return mp_const_none; + // } + // // dns_info is of type esp_netif_dns_info_t, which is just ever so slightly + // // different than esp_netif_ip_info_t used for + // // common_hal_wifi_radio_get_ipv4_address (includes both ipv4 and 6), + // // so some extra jumping is required to get to the actual address + // return common_hal_ipaddress_new_ipv4address(self->dns_info.ip.u_addr.ip4.addr); + return mp_const_none; +} + +void common_hal_wifi_radio_set_ipv4_dns(wifi_radio_obj_t *self, mp_obj_t ipv4_dns_addr) { + // esp_netif_dns_info_t dns_addr; + // ipaddress_ipaddress_to_esp_idf_ip4(ipv4_dns_addr, &dns_addr.ip.u_addr.ip4); + // esp_netif_set_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &dns_addr); +} + +void common_hal_wifi_radio_start_dhcp_client(wifi_radio_obj_t *self, bool ipv4, bool ipv6) { + // if (ipv4) { + // esp_netif_dhcpc_start(self->netif); + // } else { + // esp_netif_dhcpc_stop(self->netif); + // } + // #if LWIP_IPV6_DHCP6 + // if (ipv6) { + // esp_netif_create_ip6_linklocal(self->netif); + // dhcp6_enable_stateless(esp_netif_get_netif_impl(self->netif)); + // } else { + // dhcp6_disable(esp_netif_get_netif_impl(self->netif)); + // } + // #else + // if (ipv6) { + // mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_ipv6); + // } + // #endif +} + +void common_hal_wifi_radio_stop_dhcp_client(wifi_radio_obj_t *self) { + // esp_netif_dhcpc_stop(self->netif); + // #if LWIP_IPV6_DHCP6 + // dhcp6_disable(esp_netif_get_netif_impl(self->netif)); + // #endif +} + +void common_hal_wifi_radio_start_dhcp_server(wifi_radio_obj_t *self) { + // esp_netif_dhcps_start(self->ap_netif); +} + +void common_hal_wifi_radio_stop_dhcp_server(wifi_radio_obj_t *self) { + // esp_netif_dhcps_stop(self->ap_netif); +} + +void common_hal_wifi_radio_set_ipv4_address(wifi_radio_obj_t *self, mp_obj_t ipv4, mp_obj_t netmask, mp_obj_t gateway, mp_obj_t ipv4_dns) { + // common_hal_wifi_radio_stop_dhcp_client(self); // Must stop station DHCP to set a manual address + + // esp_netif_ip_info_t ip_info; + // ipaddress_ipaddress_to_esp_idf_ip4(ipv4, &ip_info.ip); + // ipaddress_ipaddress_to_esp_idf_ip4(netmask, &ip_info.netmask); + // ipaddress_ipaddress_to_esp_idf_ip4(gateway, &ip_info.gw); + + // esp_netif_set_ip_info(self->netif, &ip_info); + + // if (ipv4_dns != MP_OBJ_NULL) { + // common_hal_wifi_radio_set_ipv4_dns(self, ipv4_dns); + // } +} + +void common_hal_wifi_radio_set_ipv4_address_ap(wifi_radio_obj_t *self, mp_obj_t ipv4, mp_obj_t netmask, mp_obj_t gateway) { + // common_hal_wifi_radio_stop_dhcp_server(self); // Must stop access point DHCP to set a manual address + + // esp_netif_ip_info_t ip_info; + // ipaddress_ipaddress_to_esp_idf_ip4(ipv4, &ip_info.ip); + // ipaddress_ipaddress_to_esp_idf_ip4(netmask, &ip_info.netmask); + // ipaddress_ipaddress_to_esp_idf_ip4(gateway, &ip_info.gw); + + // esp_netif_set_ip_info(self->ap_netif, &ip_info); + + // common_hal_wifi_radio_start_dhcp_server(self); // restart access point DHCP +} + +// static void ping_success_cb(esp_ping_handle_t hdl, void *args) { +// wifi_radio_obj_t *self = (wifi_radio_obj_t *)args; +// esp_ping_get_profile(hdl, ESP_PING_PROF_TIMEGAP, &self->ping_elapsed_time, sizeof(self->ping_elapsed_time)); +// } + +mp_int_t common_hal_wifi_radio_ping(wifi_radio_obj_t *self, mp_obj_t ip_address, mp_float_t timeout) { + // esp_ping_config_t ping_config = ESP_PING_DEFAULT_CONFIG(); + // ipaddress_ipaddress_to_esp_idf(ip_address, &ping_config.target_addr); + // ping_config.count = 1; + + // // We must fetch ping information using the callback mechanism, because the session storage is freed when + // // the ping session is done, even before esp_ping_delete_session(). + // esp_ping_callbacks_t ping_callbacks = { + // .on_ping_success = ping_success_cb, + // .cb_args = (void *)self, + // }; + + // size_t timeout_ms = timeout * 1000; + + // // ESP-IDF creates a task to do the ping session. It shuts down when done, but only after a one second delay. + // // Calling common_hal_wifi_radio_ping() too fast will cause resource exhaustion. + // esp_ping_handle_t ping; + // if (esp_ping_new_session(&ping_config, &ping_callbacks, &ping) != ESP_OK) { + // // Wait for old task to go away and then try again. + // // Empirical testing shows we have to wait at least two seconds, despite the task + // // having a one-second timeout. + // common_hal_time_delay_ms(2000); + // // Return if interrupted now, to show the interruption as KeyboardInterrupt instead of the + // // IDF error. + // if (mp_hal_is_interrupted()) { + // return (uint32_t)(-1); + // } + // CHECK_ESP_RESULT(esp_ping_new_session(&ping_config, &ping_callbacks, &ping)); + // } + + // // Use all ones as a flag that the elapsed time was not set (ping failed or timed out). + // self->ping_elapsed_time = (uint32_t)(-1); + + // esp_ping_start(ping); + + // uint32_t start_time = common_hal_time_monotonic_ms(); + // while ((self->ping_elapsed_time == (uint32_t)(-1)) && + // (common_hal_time_monotonic_ms() - start_time < timeout_ms) && + // !mp_hal_is_interrupted()) { + // RUN_BACKGROUND_TASKS; + // } + // esp_ping_stop(ping); + // esp_ping_delete_session(ping); + + // return (mp_int_t)self->ping_elapsed_time; + return 0; +} + +void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self) { + // Only bother to scan the actual object references. + gc_collect_ptr(self->current_scan); +} + +mp_obj_t common_hal_wifi_radio_get_dns(wifi_radio_obj_t *self) { + // if (!esp_netif_is_netif_up(self->netif)) { + // return mp_const_empty_tuple; + // } + + // esp_netif_get_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &self->dns_info); + + // if (self->dns_info.ip.type == ESP_IPADDR_TYPE_V4 && self->dns_info.ip.u_addr.ip4.addr == INADDR_NONE) { + // return mp_const_empty_tuple; + // } + + // mp_obj_t args[] = { + // espaddr_to_str(&self->dns_info.ip), + // }; + + // return mp_obj_new_tuple(1, args); + return mp_const_empty_tuple; +} + +void common_hal_wifi_radio_set_dns(wifi_radio_obj_t *self, mp_obj_t dns_addrs_obj) { + // mp_int_t len = mp_obj_get_int(mp_obj_len(dns_addrs_obj)); + // mp_arg_validate_length_max(len, 1, MP_QSTR_dns); + // esp_netif_dns_info_t dns_info; + // if (len == 0) { + // // clear DNS server + // dns_info.ip.type = ESP_IPADDR_TYPE_V4; + // dns_info.ip.u_addr.ip4.addr = INADDR_NONE; + // } else { + // mp_obj_t dns_addr_obj = mp_obj_subscr(dns_addrs_obj, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL); + // struct sockaddr_storage addr_storage; + // socketpool_resolve_host_or_throw(AF_UNSPEC, SOCK_STREAM, mp_obj_str_get_str(dns_addr_obj), &addr_storage, 1); + // sockaddr_to_espaddr(&addr_storage, &dns_info.ip); + // } + // esp_netif_set_dns_info(self->netif, ESP_NETIF_DNS_MAIN, &dns_info); +} diff --git a/ports/zephyr-cp/common-hal/wifi/Radio.h b/ports/zephyr-cp/common-hal/wifi/Radio.h new file mode 100644 index 00000000000..f177f493685 --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/Radio.h @@ -0,0 +1,43 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include "shared-bindings/wifi/ScannedNetworks.h" +#include "shared-bindings/wifi/Network.h" + +#include + +// Event bits for the Radio event group. +#define WIFI_SCAN_DONE_BIT BIT0 +#define WIFI_CONNECTED_BIT BIT1 +#define WIFI_DISCONNECTED_BIT BIT2 + +typedef struct { + mp_obj_base_t base; + wifi_scannednetworks_obj_t *current_scan; + // StaticEventGroup_t event_group; + // EventGroupHandle_t event_group_handle; + // wifi_config_t sta_config; + // wifi_network_obj_t ap_info; + // esp_netif_ip_info_t ip_info; + // esp_netif_dns_info_t dns_info; + struct net_if *sta_netif; + // uint32_t ping_elapsed_time; + // wifi_config_t ap_config; + // esp_netif_ip_info_t ap_ip_info; + struct net_if *ap_netif; + bool started; + bool ap_mode; + bool sta_mode; + uint8_t retries_left; + uint8_t starting_retries; + uint8_t last_disconnect_reason; +} wifi_radio_obj_t; + +extern void common_hal_wifi_radio_gc_collect(wifi_radio_obj_t *self); diff --git a/ports/zephyr-cp/common-hal/wifi/ScannedNetworks.c b/ports/zephyr-cp/common-hal/wifi/ScannedNetworks.c new file mode 100644 index 00000000000..725bf1fa7cb --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/ScannedNetworks.c @@ -0,0 +1,128 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2018 Artur Pacholec +// SPDX-FileCopyrightText: Copyright (c) 2017 Glenn Ruben Bakke +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared/runtime/interrupt_char.h" +#include "py/gc.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/wifi/__init__.h" +#include "shared-bindings/wifi/Network.h" +#include "shared-bindings/wifi/Radio.h" +#include "shared-bindings/wifi/ScannedNetworks.h" +#include "bindings/zephyr_kernel/__init__.h" + +#include +#include + + +void wifi_scannednetworks_scan_result(wifi_scannednetworks_obj_t *self, struct wifi_scan_result *result) { + if (k_msgq_put(&self->msgq, result, K_NO_WAIT) != 0) { + printk("Dropping scan result!\n"); + } +} + +static void wifi_scannednetworks_done(wifi_scannednetworks_obj_t *self) { + self->done = true; +} + +static bool wifi_scannednetworks_wait_for_scan(wifi_scannednetworks_obj_t *self) { + + return !mp_hal_is_interrupted(); +} + +mp_obj_t common_hal_wifi_scannednetworks_next(wifi_scannednetworks_obj_t *self) { + if (self->done) { + return mp_const_none; + } + // If we don't have any results queued, then wait until we do. + while (k_fifo_is_empty(&self->fifo) && k_msgq_num_used_get(&self->msgq) == 0) { + k_poll(self->events, ARRAY_SIZE(self->events), K_FOREVER); + if (mp_hal_is_interrupted()) { + wifi_scannednetworks_done(self); + } + if (k_msgq_num_used_get(&self->msgq) > 0) { + // We found something. + break; + } + int signaled; + int result; + k_poll_signal_check(&self->channel_done, &signaled, &result); + if (signaled) { + wifi_scannednetworks_scan_next_channel(self); + } + if (self->done) { + return mp_const_none; + } + } + // Copy everything out of the message queue into the FIFO because it's a + // fixed size. + while (k_msgq_num_used_get(&self->msgq) > 0) { + wifi_network_obj_t *entry = mp_obj_malloc(wifi_network_obj_t, &wifi_network_type); + k_msgq_get(&self->msgq, &entry->scan_result, K_NO_WAIT); + // This will use the base python object space for the linked list. We + // need to reset it before returning this memory as a Python object. + k_fifo_put(&self->fifo, entry); + } + + wifi_network_obj_t *entry = k_fifo_get(&self->fifo, K_NO_WAIT); + entry->base.type = &wifi_network_type; + return MP_OBJ_FROM_PTR(entry); +} + +// We don't do a linear scan so that we look at a variety of spectrum up front. +static uint8_t scan_pattern[] = {6, 1, 11, 3, 9, 13, 2, 4, 8, 12, 5, 7, 10, 14, 0}; + +void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self) { + // There is no channel 0, so use that as a flag to indicate we've run out of channels to scan. + uint8_t next_channel = 0; + while (self->current_channel_index < sizeof(scan_pattern)) { + next_channel = scan_pattern[self->current_channel_index]; + self->current_channel_index++; + // Scan only channels that are in the specified range. + if (self->start_channel <= next_channel && next_channel <= self->end_channel) { + break; + } + } + k_poll_signal_init(&self->channel_done); + k_poll_event_init(&self->events[2], + K_POLL_TYPE_SIGNAL, + K_POLL_MODE_NOTIFY_ONLY, + &self->channel_done); + + struct wifi_scan_params params = { 0 }; + params.band_chan[0].band = WIFI_FREQ_BAND_2_4_GHZ; + params.band_chan[0].channel = next_channel; + if (next_channel == 0) { + wifi_scannednetworks_done(self); + } else { + int res = net_mgmt(NET_REQUEST_WIFI_SCAN, self->netif, ¶ms, sizeof(params)); + if (res != 0) { + printk("Failed to start wifi scan %d\n", res); + raise_zephyr_error(res); + wifi_scannednetworks_done(self); + } else { + self->channel_scan_in_progress = true; + } + } +} + +void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t *self) { + // Free any results we don't need. + while (!k_fifo_is_empty(&self->fifo)) { + wifi_network_obj_t *entry = k_fifo_get(&self->fifo, K_NO_WAIT); + + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(entry, sizeof(wifi_network_obj_t)); + #else + m_free(entry); + #endif + } + wifi_scannednetworks_done(self); +} diff --git a/ports/zephyr-cp/common-hal/wifi/ScannedNetworks.h b/ports/zephyr-cp/common-hal/wifi/ScannedNetworks.h new file mode 100644 index 00000000000..14211f39550 --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/ScannedNetworks.h @@ -0,0 +1,43 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2018 Artur Pacholec +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" + +#include +#include + +#define MAX_BUFFERED_SCAN_RESULTS 10 + +typedef struct { + mp_obj_base_t base; + uint8_t current_channel_index; + struct k_poll_signal channel_done; + struct k_poll_event events[3]; + + // Hold results as they move from the callback to the CP thread. + char msgq_buffer[MAX_BUFFERED_SCAN_RESULTS * sizeof(struct wifi_scan_result)]; + struct k_msgq msgq; + // Buffer the scan results before we return them. They are stored on the CP heap. + struct k_fifo fifo; + + // Limits on what channels to scan. + uint8_t start_channel; + uint8_t end_channel; // Inclusive + + struct net_if *netif; + + bool done; + bool channel_scan_in_progress; +} wifi_scannednetworks_obj_t; + +void wifi_scannednetworks_scan_result(wifi_scannednetworks_obj_t *self, struct wifi_scan_result *result); +void wifi_scannednetworks_scan_next_channel(wifi_scannednetworks_obj_t *self); +void wifi_scannednetworks_deinit(wifi_scannednetworks_obj_t *self); diff --git a/ports/zephyr-cp/common-hal/wifi/__init__.c b/ports/zephyr-cp/common-hal/wifi/__init__.c new file mode 100644 index 00000000000..4b967bc2780 --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/__init__.c @@ -0,0 +1,485 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "common-hal/wifi/__init__.h" +#include "shared-bindings/wifi/__init__.h" + +#include "shared-bindings/ipaddress/IPv4Address.h" +#include "shared-bindings/wifi/Monitor.h" +#include "shared-bindings/wifi/Radio.h" +#include "bindings/zephyr_kernel/__init__.h" +#include "common-hal/socketpool/__init__.h" + +#include "py/gc.h" +#include "py/mpstate.h" +#include "py/runtime.h" + +wifi_radio_obj_t common_hal_wifi_radio_obj; + +#include "supervisor/port.h" +#include "supervisor/workflow.h" + +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" +#endif + +#if CIRCUITPY_STATUS_BAR +#include "supervisor/shared/status_bar.h" +#endif + +#include +#include + +#include + +#define MAC_ADDRESS_LENGTH 6 + +static void schedule_background_on_cp_core(void *arg) { + #if CIRCUITPY_STATUS_BAR + supervisor_status_bar_request_update(false); + #endif + + // CircuitPython's VM is run in a separate FreeRTOS task from wifi callbacks. So, we have to + // notify the main task every time in case it's waiting for us. + port_wake_main_task(); +} + +static struct net_mgmt_event_callback wifi_cb; +static struct net_mgmt_event_callback ipv4_cb; + +static void _event_handler(struct net_mgmt_event_callback *cb, uint64_t mgmt_event, struct net_if *iface) { + wifi_radio_obj_t *self = &common_hal_wifi_radio_obj; + (void)iface; + + switch (mgmt_event) { + case NET_EVENT_WIFI_SCAN_RESULT: { + printk("NET_EVENT_WIFI_SCAN_RESULT\n"); + const struct wifi_scan_result *result = cb->info; + if (result != NULL && self->current_scan != NULL) { + wifi_scannednetworks_scan_result(self->current_scan, result); + } + break; + } + case NET_EVENT_WIFI_SCAN_DONE: + printk("NET_EVENT_WIFI_SCAN_DONE (thread: %s prio=%d)\n", + k_thread_name_get(k_current_get()), + k_thread_priority_get(k_current_get())); + if (self->current_scan != NULL) { + k_poll_signal_raise(&self->current_scan->channel_done, 0); + } + break; + case NET_EVENT_WIFI_CONNECT_RESULT: + printk("NET_EVENT_WIFI_CONNECT_RESULT\n"); + break; + case NET_EVENT_WIFI_DISCONNECT_RESULT: + printk("NET_EVENT_WIFI_DISCONNECT_RESULT\n"); + break; + case NET_EVENT_WIFI_IFACE_STATUS: + printk("NET_EVENT_WIFI_IFACE_STATUS\n"); + break; + case NET_EVENT_WIFI_TWT: + printk("NET_EVENT_WIFI_TWT\n"); + break; + case NET_EVENT_WIFI_TWT_SLEEP_STATE: + printk("NET_EVENT_WIFI_TWT_SLEEP_STATE\n"); + break; + case NET_EVENT_WIFI_RAW_SCAN_RESULT: + printk("NET_EVENT_WIFI_RAW_SCAN_RESULT\n"); + break; + case NET_EVENT_WIFI_DISCONNECT_COMPLETE: + printk("NET_EVENT_WIFI_DISCONNECT_COMPLETE\n"); + break; + case NET_EVENT_WIFI_SIGNAL_CHANGE: + printk("NET_EVENT_WIFI_SIGNAL_CHANGE\n"); + break; + case NET_EVENT_WIFI_NEIGHBOR_REP_COMP: + printk("NET_EVENT_WIFI_NEIGHBOR_REP_COMP\n"); + break; + case NET_EVENT_WIFI_AP_ENABLE_RESULT: + printk("NET_EVENT_WIFI_AP_ENABLE_RESULT\n"); + break; + case NET_EVENT_WIFI_AP_DISABLE_RESULT: + printk("NET_EVENT_WIFI_AP_DISABLE_RESULT\n"); + break; + case NET_EVENT_WIFI_AP_STA_CONNECTED: + printk("NET_EVENT_WIFI_AP_STA_CONNECTED\n"); + break; + case NET_EVENT_WIFI_AP_STA_DISCONNECTED: + printk("NET_EVENT_WIFI_AP_STA_DISCONNECTED\n"); + break; + default: + printk("unhandled net event %x\n", mgmt_event); + break; + } +} + +// static void event_handler(void *arg, esp_event_base_t event_base, +// int32_t event_id, void *event_data) { +// // This runs on the PRO CORE! It cannot share CP interrupt enable/disable +// // directly. +// wifi_radio_obj_t *radio = arg; +// if (event_base == WIFI_EVENT) { +// switch (event_id) { +// case WIFI_EVENT_SCAN_DONE: +// ESP_LOGW(TAG, "scan"); +// xEventGroupSetBits(radio->event_group_handle, WIFI_SCAN_DONE_BIT); +// break; +// case WIFI_EVENT_AP_START: +// ESP_LOGW(TAG, "ap start"); +// break; +// case WIFI_EVENT_AP_STOP: +// ESP_LOGW(TAG, "ap stop"); +// break; +// case WIFI_EVENT_AP_STACONNECTED: +// break; +// case WIFI_EVENT_AP_STADISCONNECTED: +// break; +// case WIFI_EVENT_STA_START: +// ESP_LOGW(TAG, "sta start"); +// break; +// case WIFI_EVENT_STA_STOP: +// ESP_LOGW(TAG, "sta stop"); +// break; +// case WIFI_EVENT_STA_CONNECTED: +// ESP_LOGW(TAG, "connected"); +// break; +// case WIFI_EVENT_STA_DISCONNECTED: { +// ESP_LOGW(TAG, "disconnected"); +// wifi_event_sta_disconnected_t *d = (wifi_event_sta_disconnected_t *)event_data; +// uint8_t reason = d->reason; +// ESP_LOGW(TAG, "reason %d 0x%02x", reason, reason); +// if (radio->retries_left > 0 && +// reason != WIFI_REASON_AUTH_FAIL && +// reason != WIFI_REASON_NO_AP_FOUND && +// reason != WIFI_REASON_ASSOC_LEAVE) { +// radio->retries_left--; +// ESP_LOGI(TAG, "Retrying connect. %d retries remaining", radio->retries_left); +// esp_wifi_connect(); +// return; +// } + +// radio->last_disconnect_reason = reason; +// xEventGroupSetBits(radio->event_group_handle, WIFI_DISCONNECTED_BIT); +// break; +// } + +// // Cases to handle later. +// // case WIFI_EVENT_STA_AUTHMODE_CHANGE: +// default: { +// ESP_LOGW(TAG, "event %ld 0x%02ld", event_id, event_id); +// break; +// } +// } +// } + +// if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { +// ESP_LOGW(TAG, "got ip"); +// radio->retries_left = radio->starting_retries; +// xEventGroupSetBits(radio->event_group_handle, WIFI_CONNECTED_BIT); +// } +// // Use IPC to ensure we run schedule background on the same core as CircuitPython. +// #if defined(CONFIG_FREERTOS_UNICORE) && CONFIG_FREERTOS_UNICORE +// schedule_background_on_cp_core(NULL); +// #else +// // This only blocks until the start of the function. That's ok since the PRO +// // core shouldn't care what we do. +// esp_ipc_call(CONFIG_ESP_MAIN_TASK_AFFINITY, schedule_background_on_cp_core, NULL); +// #endif +// } + +static bool wifi_inited; +static bool wifi_ever_inited; +static bool wifi_user_initiated; + +void common_hal_wifi_init(bool user_initiated) { + wifi_radio_obj_t *self = &common_hal_wifi_radio_obj; + printk("common_hal_wifi_init\n"); + + if (wifi_inited) { + if (user_initiated && !wifi_user_initiated) { + common_hal_wifi_radio_set_enabled(self, true); + } + return; + } + wifi_inited = true; + wifi_user_initiated = user_initiated; + self->base.type = &wifi_radio_type; + + // struct net_if *default_iface = net_if_get_default(); + // printk("default interface %p\n", default_iface); + // printk("listing network interfaces\n"); + // for (int i = 0; i < 10; i++) { + // struct net_if* iface = net_if_get_by_index(i); + // if (iface == NULL) { + // printk("iface %d is NULL\n", i); + // continue; + // } + // char name[32]; + // net_if_get_name(iface, name, 32); + // printk("iface %d %s\n", i, name); + // } + self->sta_netif = net_if_get_wifi_sta(); + self->ap_netif = net_if_get_wifi_sap(); + printk("sta_netif %p\n", self->sta_netif); + printk("ap_netif %p\n", self->ap_netif); + + + struct wifi_iface_status status = { 0 }; + if (self->sta_netif != NULL) { + CHECK_ZEPHYR_RESULT(net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, self->sta_netif, &status, + sizeof(struct wifi_iface_status))); + if (net_if_is_up(self->sta_netif)) { + printk("STA is up\n"); + } else { + printk("STA is down\n"); + } + if (net_if_is_carrier_ok(self->sta_netif)) { + printk("STA carrier is ok\n"); + } else { + printk("STA carrier is not ok\n"); + } + if (net_if_is_dormant(self->sta_netif)) { + printk("STA is dormant\n"); + } else { + printk("STA is not dormant\n"); + } + } + if (self->ap_netif != NULL) { + int res = net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, self->ap_netif, &status, + sizeof(struct wifi_iface_status)); + printk("AP status request response %d\n", res); + if (net_if_is_up(self->ap_netif)) { + printk("AP is up\n"); + } else { + printk("AP is down\n"); + } + if (net_if_is_carrier_ok(self->ap_netif)) { + printk("AP carrier is ok\n"); + } else { + printk("AP carrier is not ok\n"); + } + if (net_if_is_dormant(self->ap_netif)) { + printk("AP is dormant\n"); + } else { + printk("AP is not dormant\n"); + } + } + + // self->started = false; + + // // Even though we just called esp_netif_create_default_wifi_sta, + // // station mode isn't actually ready for use until esp_wifi_set_mode() + // // is called and the configuration is loaded via esp_wifi_set_config(). + // // Set both convenience flags to false so it's not forgotten. + // self->sta_mode = 0; + // self->ap_mode = 0; + + net_mgmt_init_event_callback(&wifi_cb, _event_handler, + NET_EVENT_WIFI_SCAN_DONE | + NET_EVENT_WIFI_CONNECT_RESULT | + NET_EVENT_WIFI_DISCONNECT_RESULT | + NET_EVENT_WIFI_TWT | + NET_EVENT_WIFI_RAW_SCAN_RESULT | + NET_EVENT_WIFI_AP_ENABLE_RESULT | + NET_EVENT_WIFI_AP_DISABLE_RESULT | + NET_EVENT_WIFI_AP_STA_CONNECTED | + NET_EVENT_WIFI_AP_STA_DISCONNECTED); + + net_mgmt_init_event_callback(&ipv4_cb, _event_handler, NET_EVENT_IPV4_ADDR_ADD); + + net_mgmt_add_event_callback(&wifi_cb); + net_mgmt_add_event_callback(&ipv4_cb); + + #if defined(CONFIG_NET_HOSTNAME) + // Set the default hostname capped at NET_HOSTNAME_MAX_LEN characters. We trim off + // the start of the board name (likely manufacturer) because the end is + // often more unique to the board. + size_t board_len = MIN(NET_HOSTNAME_MAX_LEN - ((MAC_ADDRESS_LENGTH * 2) + 6), strlen(CIRCUITPY_BOARD_ID)); + size_t board_trim = strlen(CIRCUITPY_BOARD_ID) - board_len; + // Avoid double _ in the hostname. + if (CIRCUITPY_BOARD_ID[board_trim] == '_') { + board_trim++; + } + + #if CIRCUITPY_SETTINGS_TOML + char hostname[NET_HOSTNAME_MAX_LEN]; + if (settings_get_str("CIRCUITPY_WIFI_HOSTNAME", hostname, sizeof(hostname)) == SETTINGS_OK) { + CHECK_ZEPHYR_RESULT(net_hostname_set(hostname, strlen(hostname))); + } + #else + if (false) { + } + #endif + else { + char cpy_default_hostname[board_len + (MAC_ADDRESS_LENGTH * 2) + 6]; + struct net_linkaddr *mac = net_if_get_link_addr(self->sta_netif); + if (mac->len < MAC_ADDRESS_LENGTH) { + printk("MAC address too short"); + } + snprintf(cpy_default_hostname, sizeof(cpy_default_hostname), "cpy-%s-%02x%02x%02x%02x%02x%02x", CIRCUITPY_BOARD_ID + board_trim, mac->addr[0], mac->addr[1], mac->addr[2], mac->addr[3], mac->addr[4], mac->addr[5]); + + CHECK_ZEPHYR_RESULT(net_hostname_set(cpy_default_hostname, strlen(cpy_default_hostname))); + } + #else + printk("Hostname support disabled in Zephyr config\n"); + #endif + // set station mode to avoid the default SoftAP + common_hal_wifi_radio_start_station(self); + // start wifi + common_hal_wifi_radio_set_enabled(self, true); + + printk("common_hal_wifi_init done\n"); +} + +void wifi_user_reset(void) { + if (wifi_user_initiated) { + wifi_reset(); + wifi_user_initiated = false; + } +} + +void wifi_reset(void) { + printk("wifi_reset\n"); + if (!wifi_inited) { + return; + } + common_hal_wifi_monitor_deinit(MP_STATE_VM(wifi_monitor_singleton)); + wifi_radio_obj_t *radio = &common_hal_wifi_radio_obj; + common_hal_wifi_radio_set_enabled(radio, false); + // #ifndef CONFIG_IDF_TARGET_ESP32 + // ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, + // ESP_EVENT_ANY_ID, + // radio->handler_instance_all_wifi)); + // ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, + // IP_EVENT_STA_GOT_IP, + // radio->handler_instance_got_ip)); + // ESP_ERROR_CHECK(esp_wifi_deinit()); + // esp_netif_destroy(radio->netif); + // radio->netif = NULL; + // esp_netif_destroy(radio->ap_netif); + // radio->ap_netif = NULL; + // wifi_inited = false; + // #endif + supervisor_workflow_request_background(); +} + +// void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t *esp_ip_address) { +// if (mp_obj_is_type(ip_address, &ipaddress_ipv4address_type)) { +// ipaddress_ipaddress_to_esp_idf_ip4(ip_address, (esp_ip4_addr_t *)esp_ip_address); +// #if LWIP_IPV6 +// esp_ip_address->type = IPADDR_TYPE_V4; +// #endif +// } else { +// struct sockaddr_storage addr_storage; +// socketpool_resolve_host_or_throw(AF_UNSPEC, SOCK_STREAM, mp_obj_str_get_str(ip_address), &addr_storage, 1); +// sockaddr_to_espaddr(&addr_storage, (esp_ip_addr_t *)esp_ip_address); +// } +// } + +// void ipaddress_ipaddress_to_esp_idf_ip4(mp_obj_t ip_address, esp_ip4_addr_t *esp_ip_address) { +// if (!mp_obj_is_type(ip_address, &ipaddress_ipv4address_type)) { +// mp_raise_ValueError(MP_ERROR_TEXT("Only IPv4 addresses supported")); +// } +// mp_obj_t packed = common_hal_ipaddress_ipv4address_get_packed(ip_address); +// size_t len; +// const char *bytes = mp_obj_str_get_data(packed, &len); +// esp_netif_set_ip4_addr(esp_ip_address, bytes[0], bytes[1], bytes[2], bytes[3]); +// } + +void common_hal_wifi_gc_collect(void) { + common_hal_wifi_radio_gc_collect(&common_hal_wifi_radio_obj); +} + +// static mp_obj_t espaddrx_to_str(const void *espaddr, uint8_t esptype) { +// char buf[IPADDR_STRLEN_MAX]; +// inet_ntop(esptype == ESP_IPADDR_TYPE_V6 ? AF_INET6 : AF_INET, espaddr, buf, sizeof(buf)); +// return mp_obj_new_str(buf, strlen(buf)); +// } + +// mp_obj_t espaddr_to_str(const esp_ip_addr_t *espaddr) { +// return espaddrx_to_str(espaddr, espaddr->type); +// } + +// mp_obj_t espaddr4_to_str(const esp_ip4_addr_t *espaddr) { +// return espaddrx_to_str(espaddr, ESP_IPADDR_TYPE_V4); +// } + +// mp_obj_t espaddr6_to_str(const esp_ip6_addr_t *espaddr) { +// return espaddrx_to_str(espaddr, ESP_IPADDR_TYPE_V6); +// } + +// mp_obj_t sockaddr_to_str(const struct sockaddr_storage *sockaddr) { +// char buf[IPADDR_STRLEN_MAX]; +// #if CIRCUITPY_SOCKETPOOL_IPV6 +// if (sockaddr->ss_family == AF_INET6) { +// const struct sockaddr_in6 *addr6 = (const void *)sockaddr; +// inet_ntop(AF_INET6, &addr6->sin6_addr, buf, sizeof(buf)); +// } else +// #endif +// { +// const struct sockaddr_in *addr = (const void *)sockaddr; +// inet_ntop(AF_INET, &addr->sin_addr, buf, sizeof(buf)); +// } +// return mp_obj_new_str(buf, strlen(buf)); +// } + +// mp_obj_t sockaddr_to_tuple(const struct sockaddr_storage *sockaddr) { +// mp_obj_t args[4] = { +// sockaddr_to_str(sockaddr), +// }; +// int n = 2; +// #if CIRCUITPY_SOCKETPOOL_IPV6 +// if (sockaddr->ss_family == AF_INET6) { +// const struct sockaddr_in6 *addr6 = (const void *)sockaddr; +// args[1] = MP_OBJ_NEW_SMALL_INT(htons(addr6->sin6_port)); +// args[2] = MP_OBJ_NEW_SMALL_INT(addr6->sin6_flowinfo); +// args[3] = MP_OBJ_NEW_SMALL_INT(addr6->sin6_scope_id); +// n = 4; +// } else +// #endif +// { +// const struct sockaddr_in *addr = (const void *)sockaddr; +// args[1] = MP_OBJ_NEW_SMALL_INT(htons(addr->sin_port)); +// } +// return mp_obj_new_tuple(n, args); +// } + +// void sockaddr_to_espaddr(const struct sockaddr_storage *sockaddr, esp_ip_addr_t *espaddr) { +// #if CIRCUITPY_SOCKETPOOL_IPV6 +// MP_STATIC_ASSERT(IPADDR_TYPE_V4 == ESP_IPADDR_TYPE_V4); +// MP_STATIC_ASSERT(IPADDR_TYPE_V6 == ESP_IPADDR_TYPE_V6); +// MP_STATIC_ASSERT(sizeof(ip_addr_t) == sizeof(esp_ip_addr_t)); +// MP_STATIC_ASSERT(offsetof(ip_addr_t, u_addr) == offsetof(esp_ip_addr_t, u_addr)); +// MP_STATIC_ASSERT(offsetof(ip_addr_t, type) == offsetof(esp_ip_addr_t, type)); +// if (sockaddr->ss_family == AF_INET6) { +// const struct sockaddr_in6 *addr6 = (const void *)sockaddr; +// MP_STATIC_ASSERT(sizeof(espaddr->u_addr.ip6.addr) == sizeof(addr6->sin6_addr)); +// memcpy(&espaddr->u_addr.ip6.addr, &addr6->sin6_addr, sizeof(espaddr->u_addr.ip6.addr)); +// espaddr->u_addr.ip6.zone = addr6->sin6_scope_id; +// espaddr->type = ESP_IPADDR_TYPE_V6; +// } else +// #endif +// { +// const struct sockaddr_in *addr = (const void *)sockaddr; +// MP_STATIC_ASSERT(sizeof(espaddr->u_addr.ip4.addr) == sizeof(addr->sin_addr)); +// memcpy(&espaddr->u_addr.ip4.addr, &addr->sin_addr, sizeof(espaddr->u_addr.ip4.addr)); +// espaddr->type = ESP_IPADDR_TYPE_V4; +// } +// } + +// void espaddr_to_sockaddr(const esp_ip_addr_t *espaddr, struct sockaddr_storage *sockaddr, int port) { +// #if CIRCUITPY_SOCKETPOOL_IPV6 +// if (espaddr->type == ESP_IPADDR_TYPE_V6) { +// struct sockaddr_in6 *addr6 = (void *)sockaddr; +// memcpy(&addr6->sin6_addr, &espaddr->u_addr.ip6.addr, sizeof(espaddr->u_addr.ip6.addr)); +// addr6->sin6_scope_id = espaddr->u_addr.ip6.zone; +// } else +// #endif +// { +// struct sockaddr_in *addr = (void *)sockaddr; +// memcpy(&addr->sin_addr, &espaddr->u_addr.ip4.addr, sizeof(espaddr->u_addr.ip4.addr)); +// } +// } diff --git a/ports/zephyr-cp/common-hal/wifi/__init__.h b/ports/zephyr-cp/common-hal/wifi/__init__.h new file mode 100644 index 00000000000..dab519b1a5f --- /dev/null +++ b/ports/zephyr-cp/common-hal/wifi/__init__.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2020 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +struct sockaddr_storage; + +void wifi_reset(void); + +// void ipaddress_ipaddress_to_esp_idf(mp_obj_t ip_address, ip_addr_t *esp_ip_address); +// void ipaddress_ipaddress_to_esp_idf_ip4(mp_obj_t ip_address, esp_ip4_addr_t *esp_ip_address); + +mp_obj_t sockaddr_to_str(const struct sockaddr_storage *addr); +mp_obj_t sockaddr_to_tuple(const struct sockaddr_storage *addr); +// mp_obj_t espaddr_to_str(const esp_ip_addr_t *espaddr); +// mp_obj_t espaddr4_to_str(const esp_ip4_addr_t *espaddr); +// mp_obj_t espaddr6_to_str(const esp_ip6_addr_t *espaddr); +// void sockaddr_to_espaddr(const struct sockaddr_storage *sockaddr, esp_ip_addr_t *espaddr); +// void espaddr_to_sockaddr(const esp_ip_addr_t *espaddr, struct sockaddr_storage *sockaddr, int port); diff --git a/ports/zephyr-cp/common-hal/zephyr_display/Display.c b/ports/zephyr-cp/common-hal/zephyr_display/Display.c new file mode 100644 index 00000000000..d1585b5f291 --- /dev/null +++ b/ports/zephyr-cp/common-hal/zephyr_display/Display.c @@ -0,0 +1,440 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "bindings/zephyr_display/Display.h" + +#include + +#include "bindings/zephyr_kernel/__init__.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/time/__init__.h" +#include "shared-module/displayio/__init__.h" +#include "supervisor/shared/display.h" +#include "supervisor/shared/tick.h" + +static const displayio_area_t *zephyr_display_get_refresh_areas(zephyr_display_display_obj_t *self) { + if (self->core.full_refresh) { + self->core.area.next = NULL; + return &self->core.area; + } else if (self->core.current_group != NULL) { + return displayio_group_get_refresh_areas(self->core.current_group, NULL); + } + return NULL; +} + +static enum display_pixel_format zephyr_display_select_pixel_format(const struct display_capabilities *caps) { + uint32_t formats = caps->supported_pixel_formats; + + if (formats & PIXEL_FORMAT_RGB_565) { + return PIXEL_FORMAT_RGB_565; + } + if (formats & PIXEL_FORMAT_RGB_888) { + return PIXEL_FORMAT_RGB_888; + } + if (formats & PIXEL_FORMAT_ARGB_8888) { + return PIXEL_FORMAT_ARGB_8888; + } + if (formats & PIXEL_FORMAT_RGB_565X) { + return PIXEL_FORMAT_RGB_565X; + } + if (formats & PIXEL_FORMAT_L_8) { + return PIXEL_FORMAT_L_8; + } + if (formats & PIXEL_FORMAT_AL_88) { + return PIXEL_FORMAT_AL_88; + } + if (formats & PIXEL_FORMAT_MONO01) { + return PIXEL_FORMAT_MONO01; + } + if (formats & PIXEL_FORMAT_MONO10) { + return PIXEL_FORMAT_MONO10; + } + return caps->current_pixel_format; +} + +static void zephyr_display_select_colorspace(zephyr_display_display_obj_t *self, + uint16_t *color_depth, + uint8_t *bytes_per_cell, + bool *grayscale, + bool *pixels_in_byte_share_row, + bool *reverse_pixels_in_byte, + bool *reverse_bytes_in_word) { + *color_depth = 16; + *bytes_per_cell = 2; + *grayscale = false; + *pixels_in_byte_share_row = false; + *reverse_pixels_in_byte = false; + *reverse_bytes_in_word = false; + + if (self->pixel_format == PIXEL_FORMAT_RGB_565X) { + // RGB_565X is big-endian RGB_565, so byte-swap from native LE. + *reverse_bytes_in_word = true; + } else if (self->pixel_format == PIXEL_FORMAT_RGB_888) { + *color_depth = 24; + *bytes_per_cell = 3; + *reverse_bytes_in_word = false; + } else if (self->pixel_format == PIXEL_FORMAT_ARGB_8888) { + *color_depth = 32; + *bytes_per_cell = 4; + *reverse_bytes_in_word = false; + } else if (self->pixel_format == PIXEL_FORMAT_L_8 || + self->pixel_format == PIXEL_FORMAT_AL_88) { + *color_depth = 8; + *bytes_per_cell = 1; + *grayscale = true; + *reverse_bytes_in_word = false; + } else if (self->pixel_format == PIXEL_FORMAT_MONO01 || + self->pixel_format == PIXEL_FORMAT_MONO10) { + bool vtiled = self->capabilities.screen_info & SCREEN_INFO_MONO_VTILED; + bool msb_first = self->capabilities.screen_info & SCREEN_INFO_MONO_MSB_FIRST; + *color_depth = 1; + *bytes_per_cell = 1; + *grayscale = true; + *pixels_in_byte_share_row = !vtiled; + *reverse_pixels_in_byte = msb_first; + *reverse_bytes_in_word = false; + } +} + +void common_hal_zephyr_display_display_construct_from_device(zephyr_display_display_obj_t *self, + const struct device *device, + uint16_t rotation, + bool auto_refresh) { + self->auto_refresh = false; + + if (device == NULL || !device_is_ready(device)) { + raise_zephyr_error(-ENODEV); + } + + self->device = device; + display_get_capabilities(self->device, &self->capabilities); + + self->pixel_format = zephyr_display_select_pixel_format(&self->capabilities); + if (self->pixel_format != self->capabilities.current_pixel_format) { + (void)display_set_pixel_format(self->device, self->pixel_format); + display_get_capabilities(self->device, &self->capabilities); + self->pixel_format = self->capabilities.current_pixel_format; + } + + uint16_t color_depth; + uint8_t bytes_per_cell; + bool grayscale; + bool pixels_in_byte_share_row; + bool reverse_pixels_in_byte; + bool reverse_bytes_in_word; + zephyr_display_select_colorspace(self, &color_depth, &bytes_per_cell, + &grayscale, &pixels_in_byte_share_row, &reverse_pixels_in_byte, + &reverse_bytes_in_word); + + displayio_display_core_construct( + &self->core, + self->capabilities.x_resolution, + self->capabilities.y_resolution, + 0, + color_depth, + grayscale, + pixels_in_byte_share_row, + bytes_per_cell, + reverse_pixels_in_byte, + reverse_bytes_in_word); + + self->native_frames_per_second = 60; + self->native_ms_per_frame = 1000 / self->native_frames_per_second; + self->first_manual_refresh = !auto_refresh; + + if (rotation != 0) { + common_hal_zephyr_display_display_set_rotation(self, rotation); + } + + (void)display_blanking_off(self->device); + + displayio_display_core_set_root_group(&self->core, &circuitpython_splash); + common_hal_zephyr_display_display_set_auto_refresh(self, auto_refresh); +} + +uint16_t common_hal_zephyr_display_display_get_width(zephyr_display_display_obj_t *self) { + return displayio_display_core_get_width(&self->core); +} + +uint16_t common_hal_zephyr_display_display_get_height(zephyr_display_display_obj_t *self) { + return displayio_display_core_get_height(&self->core); +} + +mp_float_t common_hal_zephyr_display_display_get_brightness(zephyr_display_display_obj_t *self) { + (void)self; + return -1; +} + +bool common_hal_zephyr_display_display_set_brightness(zephyr_display_display_obj_t *self, mp_float_t brightness) { + (void)self; + (void)brightness; + return false; +} + +static bool zephyr_display_refresh_area(zephyr_display_display_obj_t *self, const displayio_area_t *area) { + uint16_t buffer_size = CIRCUITPY_DISPLAY_AREA_BUFFER_SIZE / sizeof(uint32_t); + + displayio_area_t clipped; + if (!displayio_display_core_clip_area(&self->core, area, &clipped)) { + return true; + } + + uint16_t rows_per_buffer = displayio_area_height(&clipped); + uint8_t pixels_per_word = (sizeof(uint32_t) * 8) / self->core.colorspace.depth; + // For AL_88, displayio fills at 1 byte/pixel (L_8) but output needs 2 bytes/pixel, + // so halve the effective pixels_per_word for buffer sizing. + uint8_t effective_pixels_per_word = pixels_per_word; + if (self->pixel_format == PIXEL_FORMAT_AL_88) { + effective_pixels_per_word = sizeof(uint32_t) / 2; + } + uint16_t pixels_per_buffer = displayio_area_size(&clipped); + uint16_t subrectangles = 1; + + // When pixels_in_byte_share_row is false (mono vtiled), 8 vertical pixels + // pack into one column byte. The byte layout needs width * ceil(height/8) + // bytes, which can exceed the pixel-count-based buffer size. + bool vtiled = self->core.colorspace.depth < 8 && + !self->core.colorspace.pixels_in_byte_share_row; + + bool needs_subdivision = displayio_area_size(&clipped) > buffer_size * effective_pixels_per_word; + if (vtiled && !needs_subdivision) { + uint16_t width = displayio_area_width(&clipped); + uint16_t height = displayio_area_height(&clipped); + uint32_t vtiled_bytes = (uint32_t)width * ((height + 7) / 8); + needs_subdivision = vtiled_bytes > buffer_size * sizeof(uint32_t); + } + + if (needs_subdivision) { + rows_per_buffer = buffer_size * effective_pixels_per_word / displayio_area_width(&clipped); + if (vtiled) { + rows_per_buffer = (rows_per_buffer / 8) * 8; + if (rows_per_buffer == 0) { + rows_per_buffer = 8; + } + } + if (rows_per_buffer == 0) { + rows_per_buffer = 1; + } + subrectangles = displayio_area_height(&clipped) / rows_per_buffer; + if (displayio_area_height(&clipped) % rows_per_buffer != 0) { + subrectangles++; + } + pixels_per_buffer = rows_per_buffer * displayio_area_width(&clipped); + buffer_size = pixels_per_buffer / pixels_per_word; + if (pixels_per_buffer % pixels_per_word) { + buffer_size += 1; + } + // Ensure buffer is large enough for vtiled packing. + if (vtiled) { + uint16_t width = displayio_area_width(&clipped); + uint16_t vtiled_words = (width * ((rows_per_buffer + 7) / 8) + sizeof(uint32_t) - 1) / sizeof(uint32_t); + if (vtiled_words > buffer_size) { + buffer_size = vtiled_words; + } + } + // Ensure buffer is large enough for AL_88 expansion. + if (self->pixel_format == PIXEL_FORMAT_AL_88) { + uint16_t al88_words = (pixels_per_buffer * 2 + sizeof(uint32_t) - 1) / sizeof(uint32_t); + if (al88_words > buffer_size) { + buffer_size = al88_words; + } + } + } + + uint32_t buffer[buffer_size]; + uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t mask[mask_length]; + + uint16_t remaining_rows = displayio_area_height(&clipped); + + for (uint16_t j = 0; j < subrectangles; j++) { + displayio_area_t subrectangle = { + .x1 = clipped.x1, + .y1 = clipped.y1 + rows_per_buffer * j, + .x2 = clipped.x2, + .y2 = clipped.y1 + rows_per_buffer * (j + 1), + }; + + if (remaining_rows < rows_per_buffer) { + subrectangle.y2 = subrectangle.y1 + remaining_rows; + } + remaining_rows -= rows_per_buffer; + + memset(mask, 0, mask_length * sizeof(mask[0])); + memset(buffer, 0, buffer_size * sizeof(buffer[0])); + + displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + + uint16_t width = displayio_area_width(&subrectangle); + uint16_t height = displayio_area_height(&subrectangle); + size_t pixel_count = (size_t)width * (size_t)height; + + if (self->pixel_format == PIXEL_FORMAT_MONO10) { + uint8_t *bytes = (uint8_t *)buffer; + size_t byte_count = (pixel_count + 7) / 8; + for (size_t i = 0; i < byte_count; i++) { + bytes[i] = ~bytes[i]; + } + } + + if (self->pixel_format == PIXEL_FORMAT_AL_88) { + uint8_t *bytes = (uint8_t *)buffer; + for (size_t i = pixel_count; i > 0; i--) { + bytes[(i - 1) * 2 + 1] = 0xFF; + bytes[(i - 1) * 2] = bytes[i - 1]; + } + } + + // Compute buf_size based on the Zephyr pixel format. + uint32_t buf_size_bytes; + if (self->pixel_format == PIXEL_FORMAT_MONO01 || + self->pixel_format == PIXEL_FORMAT_MONO10) { + buf_size_bytes = (pixel_count + 7) / 8; + } else if (self->pixel_format == PIXEL_FORMAT_AL_88) { + buf_size_bytes = pixel_count * 2; + } else { + buf_size_bytes = pixel_count * (self->core.colorspace.depth / 8); + } + + struct display_buffer_descriptor desc = { + .buf_size = buf_size_bytes, + .width = width, + .height = height, + .pitch = width, + .frame_incomplete = false, + }; + + int err = display_write(self->device, subrectangle.x1, subrectangle.y1, &desc, buffer); + if (err < 0) { + return false; + } + + RUN_BACKGROUND_TASKS; + } + + return true; +} + +static void zephyr_display_refresh(zephyr_display_display_obj_t *self) { + if (!displayio_display_core_start_refresh(&self->core)) { + return; + } + + const displayio_area_t *current_area = zephyr_display_get_refresh_areas(self); + while (current_area != NULL) { + if (!zephyr_display_refresh_area(self, current_area)) { + break; + } + current_area = current_area->next; + } + + displayio_display_core_finish_refresh(&self->core); +} + +void common_hal_zephyr_display_display_set_rotation(zephyr_display_display_obj_t *self, int rotation) { + bool transposed = (self->core.rotation == 90 || self->core.rotation == 270); + bool will_transposed = (rotation == 90 || rotation == 270); + if (transposed != will_transposed) { + int tmp = self->core.width; + self->core.width = self->core.height; + self->core.height = tmp; + } + + displayio_display_core_set_rotation(&self->core, rotation); + + if (self == &displays[0].zephyr_display) { + supervisor_stop_terminal(); + supervisor_start_terminal(self->core.width, self->core.height); + } + + if (self->core.current_group != NULL) { + displayio_group_update_transform(self->core.current_group, &self->core.transform); + } +} + +uint16_t common_hal_zephyr_display_display_get_rotation(zephyr_display_display_obj_t *self) { + return self->core.rotation; +} + +bool common_hal_zephyr_display_display_refresh(zephyr_display_display_obj_t *self, + uint32_t target_ms_per_frame, + uint32_t maximum_ms_per_real_frame) { + if (!self->auto_refresh && !self->first_manual_refresh && (target_ms_per_frame != NO_FPS_LIMIT)) { + uint64_t current_time = supervisor_ticks_ms64(); + uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh; + if (current_ms_since_real_refresh > maximum_ms_per_real_frame) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Below minimum frame rate")); + } + uint32_t current_ms_since_last_call = current_time - self->last_refresh_call; + self->last_refresh_call = current_time; + if (current_ms_since_last_call > target_ms_per_frame) { + return false; + } + uint32_t remaining_time = target_ms_per_frame - (current_ms_since_real_refresh % target_ms_per_frame); + while (supervisor_ticks_ms64() - self->last_refresh_call < remaining_time) { + RUN_BACKGROUND_TASKS; + } + } + self->first_manual_refresh = false; + zephyr_display_refresh(self); + return true; +} + +bool common_hal_zephyr_display_display_get_auto_refresh(zephyr_display_display_obj_t *self) { + return self->auto_refresh; +} + +void common_hal_zephyr_display_display_set_auto_refresh(zephyr_display_display_obj_t *self, bool auto_refresh) { + self->first_manual_refresh = !auto_refresh; + if (auto_refresh != self->auto_refresh) { + if (auto_refresh) { + supervisor_enable_tick(); + } else { + supervisor_disable_tick(); + } + } + self->auto_refresh = auto_refresh; +} + +void zephyr_display_display_background(zephyr_display_display_obj_t *self) { + if (self->auto_refresh && (supervisor_ticks_ms64() - self->core.last_refresh) > self->native_ms_per_frame) { + zephyr_display_refresh(self); + } +} + +void release_zephyr_display(zephyr_display_display_obj_t *self) { + common_hal_zephyr_display_display_set_auto_refresh(self, false); + release_display_core(&self->core); + self->device = NULL; + self->base.type = &mp_type_NoneType; +} + +void zephyr_display_display_collect_ptrs(zephyr_display_display_obj_t *self) { + (void)self; + displayio_display_core_collect_ptrs(&self->core); +} + +void zephyr_display_display_reset(zephyr_display_display_obj_t *self) { + if (self->device != NULL && device_is_ready(self->device)) { + common_hal_zephyr_display_display_set_auto_refresh(self, true); + displayio_display_core_set_root_group(&self->core, &circuitpython_splash); + self->core.full_refresh = true; + } else { + release_zephyr_display(self); + } +} + +mp_obj_t common_hal_zephyr_display_display_get_root_group(zephyr_display_display_obj_t *self) { + if (self->core.current_group == NULL) { + return mp_const_none; + } + return self->core.current_group; +} + +bool common_hal_zephyr_display_display_set_root_group(zephyr_display_display_obj_t *self, displayio_group_t *root_group) { + return displayio_display_core_set_root_group(&self->core, root_group); +} diff --git a/ports/zephyr-cp/common-hal/zephyr_display/Display.h b/ports/zephyr-cp/common-hal/zephyr_display/Display.h new file mode 100644 index 00000000000..bdec1e96ba5 --- /dev/null +++ b/ports/zephyr-cp/common-hal/zephyr_display/Display.h @@ -0,0 +1,31 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "shared-module/displayio/display_core.h" + +typedef struct { + mp_obj_base_t base; + displayio_display_core_t core; + const struct device *device; + struct display_capabilities capabilities; + enum display_pixel_format pixel_format; + uint64_t last_refresh_call; + uint16_t native_frames_per_second; + uint16_t native_ms_per_frame; + bool auto_refresh; + bool first_manual_refresh; +} zephyr_display_display_obj_t; + +void zephyr_display_display_background(zephyr_display_display_obj_t *self); +void zephyr_display_display_collect_ptrs(zephyr_display_display_obj_t *self); +void zephyr_display_display_reset(zephyr_display_display_obj_t *self); +void release_zephyr_display(zephyr_display_display_obj_t *self); diff --git a/ports/zephyr-cp/common-hal/zephyr_kernel/__init__.c b/ports/zephyr-cp/common-hal/zephyr_kernel/__init__.c new file mode 100644 index 00000000000..178f33e028d --- /dev/null +++ b/ports/zephyr-cp/common-hal/zephyr_kernel/__init__.c @@ -0,0 +1,62 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "bindings/zephyr_kernel/__init__.h" +#include "py/runtime.h" +#include + +#include +#include + +void raise_zephyr_error(int err) { + if (err == 0) { + return; + } + switch (-err) { + case EALREADY: + printk("EALREADY\n"); + break; + case EDESTADDRREQ: + printk("EDESTADDRREQ\n"); + break; + case EMSGSIZE: + printk("EMSGSIZE\n"); + break; + case EPROTONOSUPPORT: + printk("EPROTONOSUPPORT\n"); + break; + case EADDRNOTAVAIL: + printk("EADDRNOTAVAIL\n"); + break; + case ENETRESET: + printk("ENETRESET\n"); + break; + case EISCONN: + printk("EISCONN\n"); + break; + case ENOTCONN: + printk("ENOTCONN\n"); + break; + case ENOTSUP: + printk("ENOTSUP\n"); + break; + case EADDRINUSE: + printk("EADDRINUSE\n"); + break; + case EIO: + printk("EIO\n"); + break; + case ENOSYS: + printk("ENOSYS\n"); + break; + case EINVAL: + printk("EINVAL\n"); + break; + default: + printk("Zephyr error %d\n", err); + } + mp_raise_OSError(-err); +} diff --git a/ports/zephyr-cp/common-hal/zephyr_kernel/__init__.h b/ports/zephyr-cp/common-hal/zephyr_kernel/__init__.h new file mode 100644 index 00000000000..d6e483b9d3e --- /dev/null +++ b/ports/zephyr-cp/common-hal/zephyr_kernel/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Jeff Epler for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/ports/zephyr-cp/cptools/board_tools.py b/ports/zephyr-cp/cptools/board_tools.py new file mode 100644 index 00000000000..305abab3f19 --- /dev/null +++ b/ports/zephyr-cp/cptools/board_tools.py @@ -0,0 +1,37 @@ +import tomllib + + +def find_mpconfigboard(portdir, board_id): + next_underscore = board_id.find("_") + while next_underscore != -1: + vendor = board_id[:next_underscore] + board = board_id[next_underscore + 1 :] + p = portdir / f"boards/{vendor}/{board}/circuitpython.toml" + if p.exists(): + return p + next_underscore = board_id.find("_", next_underscore + 1) + return None + + +def load_mpconfigboard(portdir, board_id): + mpconfigboard_path = find_mpconfigboard(portdir, board_id) + if mpconfigboard_path is None or not mpconfigboard_path.exists(): + return None, {} + + with mpconfigboard_path.open("rb") as f: + return mpconfigboard_path, tomllib.load(f) + + +def get_shields(mpconfigboard): + shields = mpconfigboard.get("SHIELDS") + if shields is None: + shields = mpconfigboard.get("SHIELD") + + if shields is None: + return [] + if isinstance(shields, str): + return [shields] + if isinstance(shields, (list, tuple)): + return [str(shield) for shield in shields] + + return [str(shields)] diff --git a/ports/zephyr-cp/cptools/build_all_boards.py b/ports/zephyr-cp/cptools/build_all_boards.py new file mode 100755 index 00000000000..8505e732efe --- /dev/null +++ b/ports/zephyr-cp/cptools/build_all_boards.py @@ -0,0 +1,520 @@ +#!/usr/bin/env python3 +""" +Build all CircuitPython boards for the Zephyr port. + +This script discovers all boards by finding circuitpython.toml files +and builds them in parallel while sharing a single jobserver across +all builds. + +This is agent generated and works. Don't bother reading too closely because it +is just a tool for us. +""" + +import argparse +import concurrent.futures +import os +import pathlib +import shlex +import subprocess +import sys +import time + + +class Jobserver: + def __init__(self, read_fd, write_fd, jobs=None, owns_fds=False): + self.read_fd = read_fd + self.write_fd = write_fd + self.jobs = jobs + self.owns_fds = owns_fds + + def acquire(self): + while True: + try: + os.read(self.read_fd, 1) + return + except InterruptedError: + continue + + def release(self): + while True: + try: + os.write(self.write_fd, b"+") + return + except InterruptedError: + continue + + def pass_fds(self): + return (self.read_fd, self.write_fd) + + def close(self): + if self.owns_fds: + os.close(self.read_fd) + os.close(self.write_fd) + + +def _parse_makeflags_jobserver(makeflags): + jobserver_auth = None + jobs = None + + for token in shlex.split(makeflags): + if token == "-j" or token == "--jobs": + continue + if token.startswith("-j") and token != "-j": + try: + jobs = int(token[2:]) + except ValueError: + pass + elif token.startswith("--jobs="): + try: + jobs = int(token.split("=", 1)[1]) + except ValueError: + pass + elif token.startswith("--jobserver-auth=") or token.startswith("--jobserver-fds="): + jobserver_auth = token.split("=", 1)[1] + + if not jobserver_auth: + return None, jobs, False + + if jobserver_auth.startswith("fifo:"): + fifo_path = jobserver_auth[len("fifo:") :] + read_fd = os.open(fifo_path, os.O_RDONLY) + write_fd = os.open(fifo_path, os.O_WRONLY) + os.set_inheritable(read_fd, True) + os.set_inheritable(write_fd, True) + return (read_fd, write_fd), jobs, True + + if "," in jobserver_auth: + read_fd, write_fd = jobserver_auth.split(",", 1) + return (int(read_fd), int(write_fd)), jobs, False + + return None, jobs, False + + +def _create_jobserver(jobs): + read_fd, write_fd = os.pipe() + os.set_inheritable(read_fd, True) + os.set_inheritable(write_fd, True) + for _ in range(jobs): + os.write(write_fd, b"+") + return Jobserver(read_fd, write_fd, jobs=jobs, owns_fds=True) + + +def _jobserver_from_env(): + makeflags = os.environ.get("MAKEFLAGS", "") + fds, jobs, owns_fds = _parse_makeflags_jobserver(makeflags) + if not fds: + return None, jobs + read_fd, write_fd = fds + os.set_inheritable(read_fd, True) + os.set_inheritable(write_fd, True) + return Jobserver(read_fd, write_fd, jobs=jobs, owns_fds=owns_fds), jobs + + +def discover_boards(port_dir): + """ + Discover all boards by finding circuitpython.toml files. + + Returns a list of (vendor, board) tuples. + """ + boards = [] + boards_dir = port_dir / "boards" + + # Find all circuitpython.toml files + for toml_file in boards_dir.glob("*/*/circuitpython.toml"): + # Extract vendor and board from path: boards/vendor/board/circuitpython.toml + parts = toml_file.relative_to(boards_dir).parts + if len(parts) == 3: + vendor = parts[0] + board = parts[1] + boards.append((vendor, board)) + + return sorted(boards) + + +def build_board( + port_dir, + vendor, + board, + extra_args=None, + jobserver=None, + env=None, + log_dir=None, +): + """ + Build a single board using make. + + Args: + port_dir: Path to the zephyr-cp port directory + vendor: Board vendor name + board: Board name + extra_args: Additional arguments to pass to make + jobserver: Jobserver instance to limit parallel builds + env: Environment variables for the subprocess + log_dir: Directory to write build logs + + Returns: + (success: bool, elapsed_time: float, output: str, log_path: pathlib.Path) + """ + board_id = f"{vendor}_{board}" + start_time = time.time() + log_path = None + + cmd = ["make", f"BOARD={board_id}"] + + # Add extra arguments (like -j) + if extra_args: + cmd.extend(extra_args) + + if jobserver: + jobserver.acquire() + + try: + result = subprocess.run( + cmd, + cwd=port_dir, + # Inherit stdin alongside jobserver file descriptors + stdin=sys.stdin, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + text=True, + env=env, + pass_fds=jobserver.pass_fds() if jobserver else (), + ) + elapsed = time.time() - start_time + output = result.stdout or "" + if log_dir: + log_path = log_dir / f"{board_id}.log" + log_path.write_text(output) + return result.returncode == 0, elapsed, output, log_path + except KeyboardInterrupt: + raise + finally: + if jobserver: + jobserver.release() + + +def _format_status(status): + state = status["state"] + elapsed = status.get("elapsed") + if state == "queued": + return "QUEUED" + if state == "running": + return f"RUNNING {elapsed:.1f}s" + if state == "success": + return f"SUCCESS {elapsed:.1f}s" + if state == "failed": + return f"FAILED {elapsed:.1f}s" + if state == "skipped": + return "SKIPPED" + return state.upper() + + +def _build_status_table(boards, statuses, start_time, stop_submitting): + from rich.table import Table + from rich.text import Text + + elapsed = time.time() - start_time + title = f"Building {len(boards)} boards | Elapsed: {elapsed:.1f}s" + if stop_submitting: + title += " | STOPPING AFTER FAILURE" + + table = Table(title=title) + table.add_column("#", justify="right") + table.add_column("Board", no_wrap=True) + table.add_column("Status", no_wrap=True) + + for i, (vendor, board) in enumerate(boards): + board_id = f"{vendor}_{board}" + status_text = _format_status(statuses[i]) + state = statuses[i]["state"] + style = None + if state == "success": + style = "green" + elif state == "failed": + style = "red" + table.add_row( + f"{i + 1}/{len(boards)}", + board_id, + Text(status_text, style=style) if style else status_text, + ) + + return table + + +def _run_builds_tui( + port_dir, + boards, + extra_args, + jobserver, + env, + log_dir, + max_workers, + continue_on_error, +): + from rich.live import Live + + statuses = [ + {"state": "queued", "elapsed": 0.0, "start": None, "log_path": None} for _ in boards + ] + results = [] + futures = {} + next_index = 0 + stop_submitting = False + start_time = time.time() + + with Live( + _build_status_table(boards, statuses, start_time, stop_submitting), + refresh_per_second=4, + transient=False, + ) as live: + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: + while next_index < len(boards) and len(futures) < max_workers: + vendor, board = boards[next_index] + statuses[next_index]["state"] = "running" + statuses[next_index]["start"] = time.time() + future = executor.submit( + build_board, + port_dir, + vendor, + board, + extra_args, + jobserver, + env, + log_dir, + ) + futures[future] = next_index + next_index += 1 + + while futures: + for status in statuses: + if status["state"] == "running": + status["elapsed"] = time.time() - status["start"] + + live.update(_build_status_table(boards, statuses, start_time, stop_submitting)) + + done, _ = concurrent.futures.wait( + futures, + timeout=0.1, + return_when=concurrent.futures.FIRST_COMPLETED, + ) + for future in done: + index = futures.pop(future) + vendor, board = boards[index] + success, elapsed, _output, log_path = future.result() + statuses[index]["elapsed"] = elapsed + statuses[index]["log_path"] = log_path + statuses[index]["state"] = "success" if success else "failed" + results.append((vendor, board, success, elapsed)) + + if not success and not continue_on_error: + stop_submitting = True + + if not stop_submitting and next_index < len(boards): + vendor, board = boards[next_index] + statuses[next_index]["state"] = "running" + statuses[next_index]["start"] = time.time() + future = executor.submit( + build_board, + port_dir, + vendor, + board, + extra_args, + jobserver, + env, + log_dir, + ) + futures[future] = next_index + next_index += 1 + + if stop_submitting: + for index in range(next_index, len(boards)): + if statuses[index]["state"] == "queued": + statuses[index]["state"] = "skipped" + + live.update(_build_status_table(boards, statuses, start_time, stop_submitting)) + + return results, stop_submitting + + +def _run_builds_plain( + port_dir, + boards, + extra_args, + jobserver, + env, + log_dir, + max_workers, + continue_on_error, +): + results = [] + futures = {} + next_index = 0 + stop_submitting = False + + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: + while next_index < len(boards) and len(futures) < max_workers: + vendor, board = boards[next_index] + future = executor.submit( + build_board, + port_dir, + vendor, + board, + extra_args, + jobserver, + env, + log_dir, + ) + futures[future] = (vendor, board) + next_index += 1 + + while futures: + done, _ = concurrent.futures.wait( + futures, + return_when=concurrent.futures.FIRST_COMPLETED, + ) + for future in done: + vendor, board = futures.pop(future) + success, elapsed, _output, _log_path = future.result() + board_id = f"{vendor}_{board}" + status = "SUCCESS" if success else "FAILURE" + print(f"{board_id}: {status} ({elapsed:.1f}s)") + results.append((vendor, board, success, elapsed)) + + if not success and not continue_on_error: + stop_submitting = True + + if not stop_submitting and next_index < len(boards): + vendor, board = boards[next_index] + future = executor.submit( + build_board, + port_dir, + vendor, + board, + extra_args, + jobserver, + env, + log_dir, + ) + futures[future] = (vendor, board) + next_index += 1 + + return results, stop_submitting + + +def main(): + parser = argparse.ArgumentParser( + description="Build all CircuitPython boards for the Zephyr port", + formatter_class=argparse.RawDescriptionHelpFormatter, + epilog=""" +Examples: + # Build all boards in parallel with 32 jobserver slots + %(prog)s -j32 + + # Build all boards using make's jobserver (recommended) + make -j32 all +""", + ) + parser.add_argument( + "-j", + "--jobs", + type=int, + default=None, + help="Number of shared jobserver slots across all board builds", + ) + parser.add_argument( + "--continue-on-error", + action="store_true", + help="Continue building remaining boards even if one fails", + ) + parser.add_argument( + "--vendor", + type=str, + default=None, + help="Only build boards from this vendor (e.g. 'native' for sim boards)", + ) + + args = parser.parse_args() + + if args.jobs is not None and args.jobs < 1: + print("ERROR: --jobs must be at least 1") + return 2 + + # Get the port directory + port_dir = pathlib.Path(__file__).parent.resolve().parent + + # Discover all boards + boards = discover_boards(port_dir) + + if args.vendor: + boards = [(v, b) for v, b in boards if v == args.vendor] + + if not boards: + print("ERROR: No boards found!") + return 1 + + # Prepare jobserver and extra make arguments + jobserver, detected_jobs = _jobserver_from_env() + env = os.environ.copy() + + extra_args = [] + jobserver_jobs = detected_jobs + + if not jobserver: + jobserver_jobs = args.jobs if args.jobs else (os.cpu_count() or 1) + jobserver = _create_jobserver(jobserver_jobs) + env["MAKEFLAGS"] = ( + f"-j{jobserver_jobs} --jobserver-auth={jobserver.read_fd},{jobserver.write_fd}" + ) + + max_workers = jobserver_jobs + if max_workers is None: + max_workers = min(len(boards), os.cpu_count() or 1) + max_workers = max(1, min(len(boards), max_workers)) + + # Build all boards + log_dir = port_dir / "build-logs" + log_dir.mkdir(parents=True, exist_ok=True) + + try: + use_tui = sys.stdout.isatty() + if use_tui: + try: + import rich # noqa: F401 + except ImportError: + use_tui = False + + if use_tui: + results, stop_submitting = _run_builds_tui( + port_dir, + boards, + extra_args, + jobserver, + env, + log_dir, + max_workers, + args.continue_on_error, + ) + else: + results, stop_submitting = _run_builds_plain( + port_dir, + boards, + extra_args, + jobserver, + env, + log_dir, + max_workers, + args.continue_on_error, + ) + except KeyboardInterrupt: + print("\n\nBuild interrupted by user.") + return 130 # Standard exit code for SIGINT + finally: + if jobserver: + jobserver.close() + + failed = [r for r in results if not r[2]] + return 0 if len(failed) == 0 else 1 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/ports/zephyr-cp/cptools/build_circuitpython.py b/ports/zephyr-cp/cptools/build_circuitpython.py new file mode 100644 index 00000000000..55c069a1ddc --- /dev/null +++ b/ports/zephyr-cp/cptools/build_circuitpython.py @@ -0,0 +1,752 @@ +import asyncio +import logging +import os +import pathlib +import pickle +import sys + +import board_tools +import colorlog +import cpbuild +import tomlkit +import tomllib +import yaml + +logger = logging.getLogger(__name__) + +# print("hello zephyr", sys.argv) + +# print(os.environ) +cmake_args = {} +for var in sys.argv[1:]: + key, value = var.split("=", 1) + cmake_args[key] = value + +# Path to ports/zephyr-cp +portdir = pathlib.Path(cmake_args["PORT_SRC_DIR"]) + +# Path to CP root +srcdir = portdir.parent.parent + +# Path to where CMake wants to put our build output. +builddir = pathlib.Path.cwd() + +zephyrdir = portdir / "zephyr" + +# Path to where CMake puts Zephyr's build output. +zephyrbuilddir = builddir / ".." / ".." / ".." / "zephyr" + +sys.path.append(str(portdir / "zephyr/scripts/dts/python-devicetree/src/")) +from zephyr2cp import zephyr_dts_to_cp_board + +compiler = cpbuild.Compiler(srcdir, builddir, cmake_args) + +ALWAYS_ON_MODULES = ["sys", "collections"] +DEFAULT_MODULES = [ + "__future__", + "time", + "os", + "microcontroller", + "struct", + "array", + "json", + "random", + "digitalio", + "rotaryio", + "rainbowio", + "traceback", + "warnings", + "supervisor", + "errno", + "io", + "math", + "msgpack", + "aesio", + "hashlib", + "zlib", + "adafruit_bus_device", + "getpass", + "storage", + "binascii", + "re", + "asyncio", + "select", +] +# Flags that don't match with with a *bindings module. Some used by adafruit_requests +MPCONFIG_FLAGS = ["array", "errno", "io", "json", "math", "binascii"] + +# extmod-based modules that should appear in the autogen list even though they +# don't have shared-bindings/ or bindings/ directories. +EXTMOD_MODULES = ["asyncio", "binascii", "json", "re", "select"] + +# List of other modules (the value) that can be enabled when another one (the key) is. +REVERSE_DEPENDENCIES = { + "audiobusio": ["audiocore"], + "audiocore": [ + "audiodelays", + "audiofilters", + "audiofreeverb", + "audiomixer", + "audiomp3", + "synthio", + ], + "busio": ["fourwire", "i2cdisplaybus", "sdcardio", "sharpdisplay"], + "fourwire": ["displayio", "busdisplay", "epaperdisplay"], + "i2cdisplaybus": ["displayio", "busdisplay", "epaperdisplay"], + # Zephyr display backends need displayio and, by extension, terminalio so + # the REPL console appears on the display by default. + "zephyr_display": ["displayio"], + "displayio": [ + "vectorio", + "bitmapfilter", + "bitmaptools", + "terminalio", + "lvfontio", + "tilepalettemapper", + "fontio", + "gifio", + "jpegio", + ], + "sharpdisplay": ["framebufferio"], + "framebufferio": ["displayio"], +} + +# Other flags to set when a module is enabled +EXTRA_FLAGS = { + "audiobusio": {"AUDIOBUSIO_I2SOUT": 1, "AUDIOBUSIO_PDMIN": 0}, + "busio": {"BUSIO_SPI": 1, "BUSIO_I2C": 1}, + "rotaryio": {"ROTARYIO_SOFTENCODER": 1}, + "synthio": {"SYNTHIO_MAX_CHANNELS": 12}, +} + +# Library sources. Will be globbed from the top level directory +# No QSTR processing or CIRCUITPY specific flags +LIBRARY_SOURCE = { + "audiomp3": ["lib/mp3/src/*.c"], + "zlib": [ + "lib/uzlib/tinflate.c", + "lib/uzlib/tinfzlib.c", + "lib/uzlib/tinfgzip.c", + "lib/uzlib/adler32.c", + "lib/uzlib/crc32.c", + ], + "jpegio": ["lib/tjpgd/src/tjpgd.c"], + "gifio": ["lib/AnimatedGIF/gif.c"], +} + +SHARED_MODULE_AND_COMMON_HAL = ["_bleio", "os", "rotaryio"] + +# Mapping from module directory name to the flag name used in CIRCUITPY_ +MODULE_FLAG_NAMES = { + "__future__": "FUTURE", + "_bleio": "BLEIO", +} + + +async def preprocess_and_split_defs(compiler, source_file, build_path, flags): + build_file = source_file.with_suffix(".pp") + build_file = build_path / (build_file.relative_to(srcdir)) + await compiler.preprocess(source_file, build_file, flags=flags) + async with asyncio.TaskGroup() as tg: + for mode in ("qstr", "module", "root_pointer"): + split_file = build_file.relative_to(build_path).with_suffix(f".{mode}") + split_file = build_path / "genhdr" / mode / split_file + split_file.parent.mkdir(exist_ok=True, parents=True) + tg.create_task( + cpbuild.run_command( + [ + "python", + srcdir / "py/makeqstrdefs.py", + "split", + mode, + build_file, + build_path / "genhdr" / mode, + split_file, + ], + srcdir, + ) + ) + + +async def collect_defs(mode, build_path): + output_file = build_path / f"{mode}defs.collected" + splitdir = build_path / "genhdr" / mode + to_collect = list(splitdir.glob(f"**/*.{mode}")) + batch_size = 50 + await cpbuild.run_command( + ["cat", "-s", *to_collect[:batch_size], ">", output_file], + splitdir, + ) + for i in range(0, len(to_collect), batch_size): + await cpbuild.run_command( + ["cat", "-s", *to_collect[i : i + batch_size], ">>", output_file], + splitdir, + ) + return output_file + + +async def generate_qstr_headers(build_path, compiler, flags, translation): + collected = await collect_defs("qstr", build_path) + generated = build_path / "genhdr" / "qstrdefs.generated.h" + + await cpbuild.run_command( + ["python", srcdir / "py" / "makeqstrdata.py", collected, ">", generated], + srcdir, + ) + + compression_level = 9 + + # TODO: Do this alongside qstr stuff above. + await cpbuild.run_command( + [ + "python", + srcdir / "tools" / "msgfmt.py", + "-o", + build_path / f"{translation}.mo", + srcdir / "locale" / f"{translation}.po", + ], + srcdir, + ) + + await cpbuild.run_command( + [ + "python", + srcdir / "py" / "maketranslationdata.py", + "--compression_filename", + build_path / "genhdr" / "compressed_translations.generated.h", + "--translation", + build_path / f"{translation}.mo", + "--translation_filename", + build_path / f"translations-{translation}.c", + "--qstrdefs_filename", + generated, + "--compression_level", + compression_level, + generated, + ], + srcdir, + ) + + +async def generate_module_header(build_path): + collected = await collect_defs("module", build_path) + await cpbuild.run_command( + [ + "python", + srcdir / "py" / "makemoduledefs.py", + collected, + ">", + build_path / "genhdr" / "moduledefs.h", + ], + srcdir, + ) + + +async def generate_root_pointer_header(build_path): + collected = await collect_defs("root_pointer", build_path) + await cpbuild.run_command( + [ + "python", + srcdir / "py" / "make_root_pointers.py", + collected, + ">", + build_path / "genhdr" / "root_pointers.h", + ], + srcdir, + ) + + +async def generate_display_resources(output_path, translation, font, extra_characters): + await cpbuild.run_command( + [ + "python", + srcdir / "tools" / "gen_display_resources.py", + "--font", + srcdir / font, + "--sample_file", + srcdir / "locale" / f"{translation}.po", + "--extra_characters", + repr(extra_characters), + "--output_c_file", + output_path, + ], + srcdir, + check_hash=[output_path], + ) + + +async def generate_web_workflow_static(output_path, static_files): + await cpbuild.run_command( + [ + "python", + srcdir / "tools" / "gen_web_workflow_static.py", + "--output_c_file", + output_path, + *static_files, + ], + srcdir, + check_hash=[output_path], + ) + + +def determine_enabled_modules(board_info, portdir, srcdir): + """Determine which CircuitPython modules should be enabled based on board capabilities. + + Args: + board_info: Dictionary containing board hardware capabilities + portdir: Path to the port directory (ports/zephyr-cp) + srcdir: Path to the CircuitPython source root + + Returns: + tuple: (enabled_modules set, module_reasons dict) + """ + enabled_modules = set(DEFAULT_MODULES) + module_reasons = {} + + if board_info["wifi"]: + enabled_modules.add("wifi") + module_reasons["wifi"] = "Zephyr board has wifi" + + if board_info["flash_count"] > 0: + enabled_modules.add("storage") + module_reasons["storage"] = "Zephyr board has flash" + + network_enabled = board_info.get("wifi", False) or board_info.get("hostnetwork", False) + + if network_enabled: + enabled_modules.add("ipaddress") + module_reasons["ipaddress"] = "Zephyr networking enabled" + enabled_modules.add("socketpool") + module_reasons["socketpool"] = "Zephyr networking enabled" + enabled_modules.add("hashlib") + module_reasons["hashlib"] = "Zephyr networking enabled" + + if board_info.get("wifi", False) or board_info.get("ethernet", False): + enabled_modules.add("ssl") + module_reasons["ssl"] = "Zephyr networking enabled" + + for port_module in (portdir / "bindings").iterdir(): + if not board_info.get(port_module.name, False): + continue + enabled_modules.add(port_module.name) + module_reasons[port_module.name] = f"Zephyr board has {port_module.name}" + + for shared_module in (srcdir / "shared-bindings").iterdir(): + if not board_info.get(shared_module.name, False) or not shared_module.glob("*.c"): + continue + enabled_modules.add(shared_module.name) + module_reasons[shared_module.name] = f"Zephyr board has {shared_module.name}" + + more_modules = [] + more_modules.extend(REVERSE_DEPENDENCIES.get(shared_module.name, [])) + while more_modules: + reverse_dependency = more_modules.pop(0) + if reverse_dependency in enabled_modules: + continue + logger.debug(f"Enabling {reverse_dependency} because {shared_module.name} is enabled") + enabled_modules.add(reverse_dependency) + more_modules.extend(REVERSE_DEPENDENCIES.get(reverse_dependency, [])) + module_reasons[reverse_dependency] = f"Zephyr board has {shared_module.name}" + + return enabled_modules, module_reasons + + +async def build_circuitpython(): # noqa: C901 + circuitpython_flags = ["-DCIRCUITPY"] + port_flags = [] + enable_mpy_native = False + full_build = True + usb_host = False + zephyr_board = cmake_args["BOARD"] + board = cmake_args["BOARD_ALIAS"] + if not board: + board = zephyr_board + translation = cmake_args["TRANSLATION"] + if not translation: + translation = "en_US" + for module in ALWAYS_ON_MODULES: + circuitpython_flags.append(f"-DCIRCUITPY_{module.upper()}=1") + lto = cmake_args.get("LTO", "n") == "y" + circuitpython_flags.append(f"-DCIRCUITPY_ENABLE_MPY_NATIVE={1 if enable_mpy_native else 0}") + circuitpython_flags.append(f"-DCIRCUITPY_FULL_BUILD={1 if full_build else 0}") + circuitpython_flags.append(f"-DCIRCUITPY_SETTINGS_TOML={1 if full_build else 0}") + circuitpython_flags.append(f"-DMICROPY_PY_ASYNC_AWAIT={1 if full_build else 0}") + circuitpython_flags.append(f"-DMICROPY_PY_ASYNCIO={1 if full_build else 0}") + circuitpython_flags.append(f"-DMICROPY_PY_SELECT={1 if full_build else 0}") + circuitpython_flags.append(f"-DMICROPY_PY_SELECT_SELECT={1 if full_build else 0}") + circuitpython_flags.append("-DCIRCUITPY_STATUS_BAR=1") + circuitpython_flags.append(f"-DCIRCUITPY_USB_HOST={1 if usb_host else 0}") + circuitpython_flags.append(f"-DCIRCUITPY_BOARD_ID='\"{board}\"'") + circuitpython_flags.append(f"-DCIRCUITPY_TRANSLATE_OBJECT={1 if lto else 0}") + circuitpython_flags.append("-DINTERNAL_FLASH_FILESYSTEM") + circuitpython_flags.append("-DLONGINT_IMPL_MPZ") + circuitpython_flags.append("-DCIRCUITPY_SSL_MBEDTLS") + circuitpython_flags.append("-DFFCONF_H='\"lib/oofatfs/ffconf.h\"'") + circuitpython_flags.append( + "-D_DEFAULT_SOURCE" + ) # To get more from picolibc to match newlib such as M_PI + circuitpython_flags.extend(("-I", srcdir)) + circuitpython_flags.extend(("-I", builddir)) + circuitpython_flags.extend(("-I", portdir)) + + genhdr = builddir / "genhdr" + genhdr.mkdir(exist_ok=True, parents=True) + version_header = genhdr / "mpversion.h" + mpconfigboard_fn = board_tools.find_mpconfigboard(portdir, board) + mpconfigboard = {"USB_VID": 0x1209, "USB_PID": 0x000C, "USB_INTERFACE_NAME": "CircuitPython"} + if mpconfigboard_fn is not None and mpconfigboard_fn.exists(): + with mpconfigboard_fn.open("rb") as f: + mpconfigboard.update(tomllib.load(f)) + async with asyncio.TaskGroup() as tg: + tg.create_task( + cpbuild.run_command( + [ + "python", + srcdir / "py" / "makeversionhdr.py", + version_header, + "&&", + "touch", + version_header, + ], + srcdir, + check_hash=[version_header], + ) + ) + + board_autogen_task = tg.create_task( + zephyr_dts_to_cp_board(zephyr_board, portdir, builddir, zephyrbuilddir, mpconfigboard) + ) + board_info = board_autogen_task.result() + if mpconfigboard_fn is None: + mpconfigboard_fn = ( + portdir / "boards" / board_info["vendor_id"] / board / "circuitpython.toml" + ) + logging.warning( + f"Could not find board config at: boards/{board_info['vendor_id']}/{board}" + ) + + autogen_board_info_fn = mpconfigboard_fn.parent / "autogen_board_info.toml" + + creator_id = mpconfigboard.get("CIRCUITPY_CREATOR_ID", mpconfigboard.get("USB_VID", 0x1209)) + creation_id = mpconfigboard.get("CIRCUITPY_CREATION_ID", mpconfigboard.get("USB_PID", 0x000C)) + circuitpython_flags.append(f"-DCIRCUITPY_CREATOR_ID=0x{creator_id:08x}") + circuitpython_flags.append(f"-DCIRCUITPY_CREATION_ID=0x{creation_id:08x}") + + vendor = mpconfigboard.get("VENDOR", board_info["vendor"]) + name = mpconfigboard.get("NAME", board_info["name"]) + + enabled_modules, module_reasons = determine_enabled_modules(board_info, portdir, srcdir) + for m in mpconfigboard.get("DISABLED_MODULES", []): + enabled_modules.discard(m) + + web_workflow_enabled = board_info.get("wifi", False) or board_info.get("hostnetwork", False) + + circuitpython_flags.extend(board_info["cflags"]) + circuitpython_flags.append(f"-DCIRCUITPY_WEB_WORKFLOW={1 if web_workflow_enabled else 0}") + supervisor_source = [ + "main.c", + "extmod/modjson.c", + "extmod/modbinascii.c", + "extmod/modre.c", + "extmod/modasyncio.c", + "extmod/modselect.c", + "extmod/vfs_fat.c", + "lib/tlsf/tlsf.c", + portdir / "background.c", + portdir / "common-hal/microcontroller/__init__.c", + portdir / "common-hal/microcontroller/Pin.c", + portdir / "common-hal/microcontroller/Processor.c", + portdir / "common-hal/os/__init__.c", + "shared/readline/readline.c", + "shared/runtime/buffer_helper.c", + "shared/runtime/context_manager_helpers.c", + "shared/runtime/gchelper_generic.c", + "shared/runtime/gchelper_native.c", + "shared/runtime/pyexec.c", + "shared/runtime/interrupt_char.c", + "shared/runtime/stdout_helpers.c", + "shared/runtime/sys_stdio_mphal.c", + "shared-bindings/board/__init__.c", + "shared-bindings/supervisor/Runtime.c", + "shared-bindings/microcontroller/Pin.c", + "shared-bindings/util.c", + "shared-module/board/__init__.c", + "extmod/vfs_reader.c", + "extmod/vfs_blockdev.c", + "extmod/vfs_fat_file.c", + ] + top = srcdir + supervisor_source = [pathlib.Path(p) for p in supervisor_source] + supervisor_source.extend(board_info["source_files"]) + supervisor_source.extend(top.glob("supervisor/shared/*.c")) + if "_bleio" in enabled_modules: + supervisor_source.append(top / "supervisor/shared/bluetooth/bluetooth.c") + supervisor_source.append(top / "supervisor/shared/translate/translate.c") + if web_workflow_enabled: + supervisor_source.extend(top.glob("supervisor/shared/web_workflow/*.c")) + + usb_ok = board_info.get("usb_device", False) + circuitpython_flags.append(f"-DCIRCUITPY_USB_DEVICE={1 if usb_ok else 0}") + + if usb_ok: + enabled_modules.add("usb_cdc") + enabled_modules.add("usb_hid") + + usb_num_endpoint_pairs = board_info.get("usb_num_endpoint_pairs", 4) + circuitpython_flags.append(f"-DUSB_NUM_ENDPOINT_PAIRS={usb_num_endpoint_pairs}") + circuitpython_flags.append("-DCIRCUITPY_USB_HID_ENABLED_DEFAULT=1") + + for macro in ("USB_PID", "USB_VID"): + print(f"Setting {macro} to {mpconfigboard.get(macro)}") + circuitpython_flags.append(f"-D{macro}=0x{mpconfigboard.get(macro):04x}") + circuitpython_flags.append( + f"-DUSB_INTERFACE_NAME='\"{mpconfigboard['USB_INTERFACE_NAME']}\"'" + ) + for macro, limit, value in ( + ("USB_PRODUCT", 16, name), + ("USB_MANUFACTURER", 8, vendor), + ): + circuitpython_flags.append(f"-D{macro}='\"{value}\"'") + circuitpython_flags.append(f"-D{macro}_{limit}='\"{value[:limit]}\"'") + + circuitpython_flags.append("-DCIRCUITPY_USB_CDC_CONSOLE_ENABLED_DEFAULT=1") + circuitpython_flags.append("-DCIRCUITPY_USB_CDC_DATA_ENABLED_DEFAULT=0") + + supervisor_source.extend( + (portdir / "supervisor/usb.c", srcdir / "supervisor/shared/usb.c") + ) + + creator_id = mpconfigboard.get("CIRCUITPY_CREATOR_ID", mpconfigboard.get("USB_VID")) + creation_id = mpconfigboard.get("CIRCUITPY_CREATION_ID", mpconfigboard.get("USB_PID")) + if creator_id is not None: + circuitpython_flags.append(f"-DCIRCUITPY_CREATOR_ID=0x{creator_id:08x}") + if creation_id is not None: + circuitpython_flags.append(f"-DCIRCUITPY_CREATION_ID=0x{creation_id:08x}") + + # Always use port serial. It'll switch between USB and UART automatically. + circuitpython_flags.append("-DCIRCUITPY_PORT_SERIAL=1") + + if "hashlib" in enabled_modules: + circuitpython_flags.append("-DCIRCUITPY_HASHLIB_MBEDTLS=1") + if "ssl" not in enabled_modules: + circuitpython_flags.append("-DCIRCUITPY_HASHLIB_MBEDTLS_ONLY=1") + + if "ssl" in enabled_modules or "hashlib" in enabled_modules: + # TODO: Figure out how to get these paths from zephyr + circuitpython_flags.append("-DMBEDTLS_CONFIG_FILE='\"config-mbedtls.h\"'") + circuitpython_flags.extend( + ("-isystem", portdir / "modules" / "crypto" / "mbedtls" / "include") + ) + circuitpython_flags.extend( + ("-isystem", portdir / "modules" / "crypto" / "mbedtls" / "configs") + ) + circuitpython_flags.extend( + ("-isystem", portdir / "modules" / "crypto" / "tf-psa-crypto" / "include") + ) + circuitpython_flags.extend( + ( + "-isystem", + portdir + / "modules" + / "crypto" + / "tf-psa-crypto" + / "drivers" + / "builtin" + / "include", + ) + ) + circuitpython_flags.extend(("-isystem", zephyrdir / "modules" / "mbedtls" / "configs")) + if "ssl" in enabled_modules: + supervisor_source.append(top / "lib" / "mbedtls_config" / "crt_bundle.c") + + # Make sure all modules have a setting by filling in defaults. + hal_source = [] + library_sources = [] + autogen_board_info = tomlkit.document() + autogen_board_info.add( + tomlkit.comment( + "This file is autogenerated when a board is built. Do not edit. Do commit it to git. Other scripts use its info." + ) + ) + autogen_board_info.add("name", vendor + " " + name) + autogen_modules = tomlkit.table() + autogen_board_info.add("modules", autogen_modules) + for module in sorted( + list(top.glob("shared-bindings/*")) + list(portdir.glob("bindings/*")), + key=lambda x: x.name, + ): + # Skip files and directories without C source files (like artifacts from a docs build) + if not module.is_dir() or len(list(module.glob("*.c"))) == 0: + continue + enabled = module.name in enabled_modules + # print(f"Module {module.name} enabled: {enabled}") + v = tomlkit.item(enabled) + if module.name in module_reasons: + v.comment(module_reasons[module.name]) + autogen_modules.add(module.name, v) + flag_name = MODULE_FLAG_NAMES.get(module.name, module.name.upper()) + circuitpython_flags.append(f"-DCIRCUITPY_{flag_name}={1 if enabled else 0}") + + if enabled: + if module.name in EXTRA_FLAGS: + for flag, value in EXTRA_FLAGS[module.name].items(): + circuitpython_flags.append(f"-DCIRCUITPY_{flag}={value}") + + if enabled: + hal_source.extend(portdir.glob(f"bindings/{module.name}/*.c")) + len_before = len(hal_source) + hal_source.extend(top.glob(f"ports/zephyr-cp/common-hal/{module.name}/*.c")) + # Only include shared-module/*.c if no common-hal/*.c files were found + if len(hal_source) == len_before or module.name in SHARED_MODULE_AND_COMMON_HAL: + hal_source.extend(top.glob(f"shared-module/{module.name}/**/*.c")) + # The USB HID report descriptors are shared with the TinyUSB ports and + # have no common-hal override, so always compile them. + if module.name == "usb_hid": + hal_source.append(top / "shared-module/usb_hid/report_descriptors.c") + hal_source.extend(top.glob(f"shared-bindings/{module.name}/**/*.c")) + if module.name in LIBRARY_SOURCE: + for library_source in LIBRARY_SOURCE[module.name]: + library_sources.extend(top.glob(library_source)) + + if os.environ.get("CI", "false") == "true": + # Warn if it isn't up to date. + if ( + not autogen_board_info_fn.exists() + or autogen_board_info_fn.read_text() != tomlkit.dumps(autogen_board_info) + ): + logger.warning( + f"autogen_board_info.toml is missing or out of date. Please run `make BOARD={board}` locally and commit {autogen_board_info_fn}." + ) + autogen_modules.add(tomlkit.comment("extmod modules shared with MicroPython")) + for extmod_module in EXTMOD_MODULES: + enabled = extmod_module in enabled_modules + v = tomlkit.item(enabled) + if extmod_module in module_reasons: + v.comment(module_reasons[extmod_module]) + autogen_modules.add(extmod_module, v) + flag_name = MODULE_FLAG_NAMES.get(extmod_module, extmod_module.upper()) + circuitpython_flags.append(f"-DCIRCUITPY_{flag_name}={1 if enabled else 0}") + + if autogen_board_info_fn.parent.exists(): + autogen_board_info_fn.write_text(tomlkit.dumps(autogen_board_info)) + + for mpflag in MPCONFIG_FLAGS: + enabled = mpflag in DEFAULT_MODULES + circuitpython_flags.append(f"-DCIRCUITPY_{mpflag.upper()}={1 if enabled else 0}") + + source_files = supervisor_source + hal_source + ["extmod/vfs.c"] + assembly_files = [] + for file in top.glob("py/*.c"): + source_files.append(file) + qstr_flags = "-DNO_QSTR" + async with asyncio.TaskGroup() as tg: + for source_file in source_files: + tg.create_task( + preprocess_and_split_defs( + compiler, + top / source_file, + builddir, + [qstr_flags, *circuitpython_flags, *port_flags], + ) + ) + + if "ssl" in enabled_modules: + crt_bundle = builddir / "x509_crt_bundle.S" + roots_pem = srcdir / "lib/certificates/data/roots-full.pem" + generator = srcdir / "tools/gen_crt_bundle.py" + tg.create_task( + cpbuild.run_command( + [ + "python", + generator, + "-i", + roots_pem, + "-o", + crt_bundle, + "--asm", + ], + srcdir, + ) + ) + assembly_files.append(crt_bundle) + + async with asyncio.TaskGroup() as tg: + board_build = builddir + tg.create_task( + generate_qstr_headers( + board_build, compiler, [qstr_flags, *circuitpython_flags, *port_flags], translation + ) + ) + tg.create_task(generate_module_header(board_build)) + tg.create_task(generate_root_pointer_header(board_build)) + + if "terminalio" in enabled_modules: + output_path = board_build / f"autogen_display_resources-{translation}.c" + font_path = srcdir / mpconfigboard.get( + "CIRCUITPY_DISPLAY_FONT", "tools/fonts/ter-u12n.bdf" + ) + extra_characters = mpconfigboard.get("CIRCUITPY_FONT_EXTRA_CHARACTERS", "") + tg.create_task( + generate_display_resources(output_path, translation, font_path, extra_characters) + ) + source_files.append(output_path) + + if web_workflow_enabled: + output_path = board_build / "autogen_web_workflow_static.c" + static_files = sorted((srcdir / "supervisor/shared/web_workflow/static").glob("*")) + tg.create_task(generate_web_workflow_static(output_path, static_files)) + source_files.append(output_path) + + # This file is generated by the QSTR/translation process. + source_files.append(builddir / f"translations-{translation}.c") + # These files don't include unique QSTRs. They just need to be compiled. + source_files.append(portdir / "supervisor" / "flash.c") + source_files.append(portdir / "supervisor" / "port.c") + source_files.append(portdir / "supervisor" / "serial.c") + source_files.append(srcdir / "lib" / "oofatfs" / "ff.c") + source_files.append(srcdir / "lib" / "oofatfs" / "ffunicode.c") + source_files.append(srcdir / "extmod" / "vfs_fat_diskio.c") + source_files.append(srcdir / "shared/timeutils/timeutils.c") + source_files.append(srcdir / "shared-module/time/__init__.c") + source_files.append(srcdir / "shared-module/os/__init__.c") + source_files.append(srcdir / "shared-module/supervisor/__init__.c") + source_files.append(portdir / "bindings/zephyr_kernel/__init__.c") + source_files.append(portdir / "common-hal/zephyr_kernel/__init__.c") + # source_files.append(srcdir / "ports" / port / "peripherals" / "nrf" / "nrf52840" / "pins.c") + + source_files.extend(assembly_files) + + objects = [] + async with asyncio.TaskGroup() as tg: + for source_file in library_sources: + source_file = top / source_file + build_file = source_file.with_suffix(".o") + object_file = builddir / (build_file.relative_to(top)) + objects.append(object_file) + tg.create_task(compiler.compile(source_file, object_file)) + for source_file in source_files: + source_file = top / source_file + build_file = source_file.with_suffix(".o") + object_file = builddir / (build_file.relative_to(top)) + objects.append(object_file) + tg.create_task( + compiler.compile(source_file, object_file, [*circuitpython_flags, *port_flags]) + ) + + await compiler.archive(objects, pathlib.Path(cmake_args["OUTPUT_FILE"])) + + +async def main(): + try: + await build_circuitpython() + except* RuntimeError as e: + logger.error(e) + sys.exit(len(e.exceptions)) + + +handler = colorlog.StreamHandler() +handler.setFormatter(colorlog.ColoredFormatter("%(log_color)s%(levelname)s:%(name)s:%(message)s")) + +logging.basicConfig(level=logging.INFO, handlers=[handler]) + +asyncio.run(main()) diff --git a/ports/zephyr-cp/cptools/compat2driver.py b/ports/zephyr-cp/cptools/compat2driver.py new file mode 100644 index 00000000000..8cd3c248265 --- /dev/null +++ b/ports/zephyr-cp/cptools/compat2driver.py @@ -0,0 +1,3039 @@ +# This file was generated by gen_compat2driver.py +COMPAT_TO_DRIVER = { + # adc + "adi_ad4050_adc": "adc", + "adi_ad4052_adc": "adc", + "adi_ad4114_adc": "adc", + "adi_ad4130_adc": "adc", + "adi_ad4170_adc": "adc", + "adi_ad4190_adc": "adc", + "adi_ad4195_adc": "adc", + "adi_ad559x_adc": "adc", + "adi_ad7124_adc": "adc", + "adi_max32_adc": "adc", + "ambiq_adc": "adc", + "atmel_sam0_adc": "adc", + "atmel_sam_adc": "adc", + "atmel_sam_afec": "adc", + "bflb_adc": "adc", + "ene_kb106x_adc": "adc", + "ene_kb1200_adc": "adc", + "espressif_esp32_adc": "adc", + "gd_gd32_adc": "adc", + "infineon_adc": "adc", + "infineon_autanalog_sar_adc": "adc", + "infineon_hppass_sar_adc": "adc", + "infineon_sar_adc": "adc", + "infineon_xmc4xxx_adc": "adc", + "ite_it51xxx_adc": "adc", + "ite_it8xxx2_adc": "adc", + "lltc_ltc2451": "adc", + "maxim_max11102": "adc", + "maxim_max11103": "adc", + "maxim_max11105": "adc", + "maxim_max11106": "adc", + "maxim_max11110": "adc", + "maxim_max11111": "adc", + "maxim_max11115": "adc", + "maxim_max11116": "adc", + "maxim_max11117": "adc", + "maxim_max11253": "adc", + "maxim_max11254": "adc", + "microchip_adc_g1": "adc", + "microchip_mcp356xr": "adc", + "microchip_xec_adc": "adc", + "nordic_nrf_adc": "adc", + "nordic_nrf_saadc": "adc", + "nuvoton_npcx_adc": "adc", + "nuvoton_numaker_adc": "adc", + "nxp_adc12": "adc", + "nxp_gau_adc": "adc", + "nxp_kinetis_adc16": "adc", + "nxp_lpc_lpadc": "adc", + "nxp_mcux_12b1msps_sar": "adc", + "nxp_s32_adc_sar": "adc", + "nxp_sar_adc": "adc", + "nxp_vf610_adc": "adc", + "raspberrypi_pico_adc": "adc", + "realtek_rts5912_adc": "adc", + "renesas_ra_adc12": "adc", + "renesas_ra_adc16": "adc", + "renesas_rx_adc": "adc", + "renesas_rz_adc": "adc", + "renesas_rz_adc_c": "adc", + "renesas_rz_adc_e": "adc", + "renesas_rza2m_adc": "adc", + "renesas_smartbond_adc": "adc", + "renesas_smartbond_sdadc": "adc", + "sifli_sf32lb_gpadc": "adc", + "silabs_gecko_adc": "adc", + "silabs_iadc": "adc", + "silabs_siwx91x_adc": "adc", + "st_stm32_adc": "adc", + "st_stm32wb0_adc": "adc", + "telink_b91_adc": "adc", + "ti_ads1013": "adc", + "ti_ads1014": "adc", + "ti_ads1015": "adc", + "ti_ads1112": "adc", + "ti_ads1113": "adc", + "ti_ads1114": "adc", + "ti_ads1115": "adc", + "ti_ads1119": "adc", + "ti_ads114s06": "adc", + "ti_ads114s08": "adc", + "ti_ads124s06": "adc", + "ti_ads124s08": "adc", + "ti_ads131m02": "adc", + "ti_ads7052": "adc", + "ti_ads7950": "adc", + "ti_ads7951": "adc", + "ti_ads7952": "adc", + "ti_ads7953": "adc", + "ti_ads7954": "adc", + "ti_ads7955": "adc", + "ti_ads7956": "adc", + "ti_ads7957": "adc", + "ti_ads7958": "adc", + "ti_ads7959": "adc", + "ti_ads7960": "adc", + "ti_ads7961": "adc", + "ti_am335x_adc": "adc", + "ti_cc13xx_cc26xx_adc": "adc", + "ti_cc23x0_adc": "adc", + "ti_cc32xx_adc": "adc", + "ti_lmp90077": "adc", + "ti_lmp90078": "adc", + "ti_lmp90079": "adc", + "ti_lmp90080": "adc", + "ti_lmp90097": "adc", + "ti_lmp90098": "adc", + "ti_lmp90099": "adc", + "ti_lmp90100": "adc", + "ti_tla2021": "adc", + "ti_tla2022": "adc", + "ti_tla2024": "adc", + "vnd_adc": "adc", + "wch_adc": "adc", + "zephyr_adc_emul": "adc", + # + # audio + "ambiq_pdm": "audio", + "cirrus_cs43l22": "audio", + "dlg_da7212": "audio", + "maxim_max98091": "audio", + "nordic_nrf_pdm": "audio", + "nxp_dmic": "audio", + "nxp_micfil": "audio", + "sifli_sf32lb_audcodec": "audio", + "st_mpxxdtyy": "audio", + "ti_pcm1681": "audio", + "ti_tas6422dac": "audio", + "ti_tlv320aic3110": "audio", + "ti_tlv320dac": "audio", + "wolfson_wm8904": "audio", + "wolfson_wm8962": "audio", + # + # audio/mic_privacy/intel + "intel_adsp_mic_privacy": "audio/mic_privacy/intel", + # + # auxdisplay + "gpio_7_segment": "auxdisplay", + "hit_hd44780": "auxdisplay", + "jhd_jhd1313": "auxdisplay", + "noritake_itron": "auxdisplay", + "ptc_pt6314": "auxdisplay", + "sparkfun_serlcd": "auxdisplay", + "titanmec_tm1637": "auxdisplay", + # + # bbram + "ite_it8xxx2_bbram": "bbram", + "microchip_xec_bbram": "bbram", + "motorola_mc146818_bbram": "bbram", + "nuvoton_npcx_bbram": "bbram", + "realtek_rts5912_bbram": "bbram", + "st_stm32_bbram": "bbram", + "zephyr_bbram_emul": "bbram", + # + # biometrics + "adh_tech_gt5x": "biometrics", + "zephyr_biometrics_emul": "biometrics", + "zhiantec_zfm_x0": "biometrics", + # + # bluetooth/hci + "ambiq_bt_hci_spi": "bluetooth/hci", + "espressif_esp32_bt_hci": "bluetooth/hci", + "infineon_bless_hci": "bluetooth/hci", + "infineon_bt_hci_uart": "bluetooth/hci", + "infineon_cyw208xx_hci": "bluetooth/hci", + "nxp_bt_hci_uart": "bluetooth/hci", + "nxp_hci_ble": "bluetooth/hci", + "renesas_bt_hci_da1453x": "bluetooth/hci", + "renesas_bt_hci_da1469x": "bluetooth/hci", + "sifli_sf32lb_mailbox": "bluetooth/hci", + "silabs_bt_hci_efr32": "bluetooth/hci", + "silabs_siwx91x_bt_hci": "bluetooth/hci", + "st_hci_spi_v1": "bluetooth/hci", + "st_hci_spi_v2": "bluetooth/hci", + "st_hci_stm32wb0": "bluetooth/hci", + "st_hci_stm32wba": "bluetooth/hci", + "st_stm32wb_rf": "bluetooth/hci", + "zephyr_bt_hci_3wire_uart": "bluetooth/hci", + "zephyr_bt_hci_ipc": "bluetooth/hci", + "zephyr_bt_hci_spi": "bluetooth/hci", + "zephyr_bt_hci_uart": "bluetooth/hci", + "zephyr_bt_hci_userchan": "bluetooth/hci", + "zephyr_bt_hci_ll_sw_split": "bluetooth/hci", + # + # cache + "bflb_l1c": "cache", + # + # can + "adi_max32_can": "can", + "atmel_sam0_can": "can", + "atmel_sam_can": "can", + "espressif_esp32_twai": "can", + "infineon_xmc4xxx_can_node": "can", + "kvaser_pcican": "can", + "microchip_mcp2515": "can", + "microchip_mcp251xfd": "can", + "nordic_nrf_can": "can", + "nuvoton_numaker_canfd": "can", + "nxp_flexcan": "can", + "nxp_lpc_mcan": "can", + "nxp_s32_canxl": "can", + "renesas_ra_canfd": "can", + "renesas_rcar_can": "can", + "renesas_rz_canfd": "can", + "st_stm32_bxcan": "can", + "st_stm32_fdcan": "can", + "st_stm32h7_fdcan": "can", + "ti_tcan4x5x": "can", + "zephyr_can_loopback": "can", + "zephyr_fake_can": "can", + "zephyr_native_linux_can": "can", + # + # can/transceiver + "can_transceiver_gpio": "can/transceiver", + # + # charger + "maxim_max20335_charger": "charger", + "nxp_pca9422_charger": "charger", + "nxp_pf1550_charger": "charger", + "sbs_sbs_charger": "charger", + "ti_bq24190": "charger", + "ti_bq25180": "charger", + "ti_bq25186": "charger", + "ti_bq25188": "charger", + "ti_bq25713": "charger", + "x_powers_axp2101_charger": "charger", + "zephyr_charger_gpio": "charger", + # + # clock_control + "adi_max32_gcr": "clock_control", + "alif_clockctrl": "clock_control", + "ambiq_clkctrl": "clock_control", + "arm_beetle_syscon": "clock_control", + "arm_scmi_clock": "clock_control", + "aspeed_ast10x0_clock": "clock_control", + "atmel_sam_pmc": "clock_control", + "bflb_bl60x_clock_controller": "clock_control", + "bflb_bl61x_clock_controller": "clock_control", + "bflb_bl70x_clock_controller": "clock_control", + "espressif_esp32_clock": "clock_control", + "fixed_clock": "clock_control", + "focaltech_ft9001_cpm": "clock_control", + "gd_gd32_cctl": "clock_control", + "infineon_fixed_clock": "clock_control", + "infineon_fixed_factor_clock": "clock_control", + "infineon_peri_div": "clock_control", + "intel_agilex5_clock": "clock_control", + "ite_it51xxx_ecpm": "clock_control", + "microchip_pic32cm_jh_clock": "clock_control", + "microchip_pic32cm_pl_clock": "clock_control", + "microchip_pic32cz_ca_clock": "clock_control", + "microchip_sam_d5x_e5x_clock": "clock_control", + "microchip_sam_pmc": "clock_control", + "microchip_sama7g5_sckc": "clock_control", + "microchip_xec_pcr": "clock_control", + "nordic_nrf54h_hfxo": "clock_control", + "nordic_nrf_auxpll": "clock_control", + "nordic_nrf_clock": "clock_control", + "nordic_nrf_fll16m": "clock_control", + "nordic_nrf_hsfll_global": "clock_control", + "nordic_nrf_hsfll_local": "clock_control", + "nordic_nrf_iron_hsfll_local": "clock_control", + "nordic_nrf_lfclk": "clock_control", + "nordic_nrfs_audiopll": "clock_control", + "nuvoton_npcm_pcc": "clock_control", + "nuvoton_npcx_pcc": "clock_control", + "nuvoton_numaker_scc": "clock_control", + "nxp_imx_ccm": "clock_control", + "nxp_imx_ccm_rev2": "clock_control", + "nxp_kinetis_mcg": "clock_control", + "nxp_kinetis_pcc": "clock_control", + "nxp_kinetis_scg": "clock_control", + "nxp_kinetis_sim": "clock_control", + "nxp_lpc11u6x_syscon": "clock_control", + "nxp_lpc_syscon": "clock_control", + "nxp_mc_cgm": "clock_control", + "nxp_s32_clock": "clock_control", + "nxp_scg_k4": "clock_control", + "openisa_rv32m1_pcc": "clock_control", + "pwm_clock": "clock_control", + "raspberrypi_pico_clock_controller": "clock_control", + "realtek_bee_cctl": "clock_control", + "realtek_rts5817_clock": "clock_control", + "realtek_rts5912_sccon": "clock_control", + "renesas_r8a7795_cpg_mssr": "clock_control", + "renesas_r8a779f0_cpg_mssr": "clock_control", + "renesas_ra_cgc_subclk": "clock_control", + "renesas_rx_cgc_pclk": "clock_control", + "renesas_rx_cgc_pll": "clock_control", + "renesas_rx_cgc_root_clock": "clock_control", + "renesas_rz_cgc": "clock_control", + "renesas_rz_cpg": "clock_control", + "renesas_rza2m_cpg": "clock_control", + "sifli_sf32lb_hxt48": "clock_control", + "sifli_sf32lb_rcc_clk": "clock_control", + "silabs_series_clock": "clock_control", + "silabs_si32_ahb": "clock_control", + "silabs_si32_apb": "clock_control", + "silabs_si32_pll": "clock_control", + "silabs_siwx91x_clock": "clock_control", + "smartbond_clock": "clock_control", + "st_stm32_clock_mco": "clock_control", + "st_stm32_clock_mux": "clock_control", + "st_stm32f1_clock_mco": "clock_control", + "ti_k2g_sci_clk": "clock_control", + "wch_rcc": "clock_control", + # + # comparator + "ite_it51xxx_vcmp": "comparator", + "microchip_ac_g1_comparator": "comparator", + "nordic_nrf_comp": "comparator", + "nordic_nrf_lpcomp": "comparator", + "nxp_acomp": "comparator", + "nxp_cmp": "comparator", + "nxp_hscmp": "comparator", + "renesas_ra_acmphs": "comparator", + "renesas_ra_lvd": "comparator", + "renesas_rx_lvd": "comparator", + "silabs_acmp": "comparator", + "st_stm32_comp": "comparator", + "zephyr_fake_comp": "comparator", + # + # coredump + "zephyr_coredump": "coredump", + # + # counter + "adi_max32_counter": "counter", + "adi_max32_rtc_counter": "counter", + "adi_max32_wut": "counter", + "ambiq_counter": "counter", + "andestech_atcpit100": "counter", + "arm_cmsdk_dtimer": "counter", + "arm_cmsdk_timer": "counter", + "atmel_sam0_tc32": "counter", + "atmel_sam_tc": "counter", + "espressif_esp32_counter": "counter", + "espressif_esp32_rtc_timer": "counter", + "gd_gd32_timer": "counter", + "infineon_counter": "counter", + "infineon_tcpwm_counter": "counter", + "ite_it51xxx_counter": "counter", + "ite_it8xxx2_counter": "counter", + "maxim_ds3231": "counter", + "microchip_mcp7940n": "counter", + "microchip_sam_pit64b_counter": "counter", + "microchip_tc_g1_counter": "counter", + "microchip_tcc_g1_counter": "counter", + "microchip_xec_timer": "counter", + "microcrystal_rv3032_counter": "counter", + "neorv32_gptmr": "counter", + "nordic_nrf_rtc": "counter", + "nordic_nrf_timer": "counter", + "nuvoton_npck_lct": "counter", + "nuvoton_npcx_lct_v1": "counter", + "nuvoton_npcx_lct_v2": "counter", + "nxp_ftm": "counter", + "nxp_imx_epit": "counter", + "nxp_imx_gpt": "counter", + "nxp_imx_qtmr": "counter", + "nxp_imx_snvs_rtc": "counter", + "nxp_imx_tmr": "counter", + "nxp_lpc_ctimer": "counter", + "nxp_lpc_rtc": "counter", + "nxp_lpc_rtc_highres": "counter", + "nxp_lpit": "counter", + "nxp_mrt": "counter", + "nxp_pit": "counter", + "nxp_rtc": "counter", + "nxp_rtc_jdp": "counter", + "nxp_s32_sys_timer": "counter", + "nxp_stm": "counter", + "nxp_tpm_timer": "counter", + "raspberrypi_pico_pit": "counter", + "raspberrypi_pico_pit_channel": "counter", + "raspberrypi_pico_timer": "counter", + "realtek_rts5912_slwtimer": "counter", + "realtek_rts5912_timer": "counter", + "renesas_ra_agt_counter": "counter", + "renesas_rz_cmtw_counter": "counter", + "renesas_rz_gtm_counter": "counter", + "renesas_smartbond_timer": "counter", + "silabs_burtc_counter": "counter", + "silabs_gecko_rtcc": "counter", + "silabs_timer_counter": "counter", + "snps_dw_timers": "counter", + "st_stm32_counter": "counter", + "ti_cc23x0_lgpt": "counter", + "ti_cc23x0_rtc": "counter", + "ti_mspm0_timer_counter": "counter", + "xlnx_xps_timer_1_00_a": "counter", + "zephyr_native_sim_counter": "counter", + # + # crc + "nxp_crc": "crc", + "nxp_lpc_crc": "crc", + "renesas_ra_crc": "crc", + "sifli_sf32lb_crc": "crc", + # + # crypto + "atmel_ataes132a": "crypto", + "espressif_esp32_aes": "crypto", + "espressif_esp32_sha": "crypto", + "intel_adsp_sha": "crypto", + "ite_it51xxx_sha": "crypto", + "ite_it8xxx2_sha": "crypto", + "ite_it8xxx2_sha_v2": "crypto", + "microchip_sha_g1_crypto": "crypto", + "microchip_xec_symcr": "crypto", + "nordic_nrf_ecb": "crypto", + "nuvoton_npcx_sha": "crypto", + "nxp_mcux_dcp": "crypto", + "nxp_s32_crypto_hse_mu": "crypto", + "raspberrypi_pico_sha256": "crypto", + "realtek_rts5912_sha": "crypto", + "renesas_smartbond_crypto": "crypto", + "silabs_si32_aes": "crypto", + "st_stm32_aes": "crypto", + "st_stm32_cryp": "crypto", + "st_stm32_hash": "crypto", + "ti_cc23x0_aes": "crypto", + # + # dac + "adi_ad559x_dac": "dac", + "adi_ad5601": "dac", + "adi_ad5611": "dac", + "adi_ad5621": "dac", + "adi_ad5628": "dac", + "adi_ad5648": "dac", + "adi_ad5668": "dac", + "adi_ad5672": "dac", + "adi_ad5674": "dac", + "adi_ad5676": "dac", + "adi_ad5679": "dac", + "adi_ad5684": "dac", + "adi_ad5686": "dac", + "adi_ad5687": "dac", + "adi_ad5689": "dac", + "adi_ad5691": "dac", + "adi_ad5692": "dac", + "adi_ad5693": "dac", + "adi_max22017_dac": "dac", + "atmel_sam0_dac": "dac", + "atmel_sam_dac": "dac", + "atmel_samd5x_dac": "dac", + "espressif_esp32_dac": "dac", + "gd_gd32_dac": "dac", + "microchip_dac_g1": "dac", + "microchip_mcp4725": "dac", + "microchip_mcp4728": "dac", + "nxp_dac12": "dac", + "nxp_gau_dac": "dac", + "nxp_kinetis_dac": "dac", + "nxp_kinetis_dac32": "dac", + "nxp_lpdac": "dac", + "renesas_ra_dac": "dac", + "silabs_vdac": "dac", + "st_stm32_dac": "dac", + "ti_dac161s997": "dac", + "ti_dacx0501": "dac", + "vnd_dac": "dac", + # + # dai/intel/alh + "intel_alh_dai": "dai/intel/alh", + # + # dai/intel/dmic + "intel_dai_dmic": "dai/intel/dmic", + # + # dai/intel/hda + "intel_hda_dai": "dai/intel/hda", + # + # dai/intel/ssp + "intel_ssp_dai": "dai/intel/ssp", + # + # dai/nxp/esai + "nxp_dai_esai": "dai/nxp/esai", + # + # dai/nxp/micfil + "nxp_dai_micfil": "dai/nxp/micfil", + # + # dai/nxp/sai + "nxp_dai_sai": "dai/nxp/sai", + # + # debug + "nordic_coresight_nrf": "debug", + "silabs_pti": "debug", + # + # disk + "st_stm32_sdmmc": "disk", + "zephyr_flash_disk": "disk", + "zephyr_mmc_disk": "disk", + "zephyr_ram_disk": "disk", + "zephyr_sdmmc_disk": "disk", + # + # disk/nvme + "nvme_controller": "disk/nvme", + # + # display + "chipone_co5300": "display", + "frida_nt35510": "display", + "galaxycore_gc9x01x": "display", + "himax_hx8379c": "display", + "himax_hx8394": "display", + "ilitek_ili9806e_dsi": "display", + "intel_multiboot_framebuffer": "display", + "istech_ist3931": "display", + "jdi_lpm013m126": "display", + "led_strip_matrix": "display", + "maxim_max7219": "display", + "nxp_dcnano_lcdif": "display", + "nxp_imx_elcdif": "display", + "nxp_imx_lcdifv3": "display", + "orisetech_otm8009a": "display", + "raydium_rm67162": "display", + "raydium_rm68200": "display", + "renesas_ra_glcdc": "display", + "renesas_smartbond_display": "display", + "sharp_ls0xx": "display", + "sitronix_st75256": "display", + "sitronix_st7701": "display", + "sitronix_st7735r": "display", + "sitronix_st7789v": "display", + "sitronix_st7796s": "display", + "solomon_ssd1322": "display", + "st_stm32_ltdc": "display", + "waveshare_dsi2dpi": "display", + "zephyr_dummy_dc": "display", + "zephyr_hub12": "display", + "zephyr_sdl_dc": "display", + # + # dma + "adi_max32_dma": "dma", + "altr_msgdma": "dma", + "andestech_atcdmacx00": "dma", + "arm_dma_pl330": "dma", + "atmel_sam0_dmac": "dma", + "atmel_sam_xdmac": "dma", + "bflb_dma": "dma", + "brcm_iproc_pax_dma_v1": "dma", + "brcm_iproc_pax_dma_v2": "dma", + "espressif_esp32_gdma": "dma", + "gd_gd32_dma": "dma", + "gd_gd32_dma_v1": "dma", + "infineon_dma": "dma", + "infineon_xmc4xxx_dma": "dma", + "intel_adsp_gpdma": "dma", + "intel_adsp_hda_host_in": "dma", + "intel_adsp_hda_host_out": "dma", + "intel_adsp_hda_link_in": "dma", + "intel_adsp_hda_link_out": "dma", + "intel_lpss": "dma", + "intel_sedi_dma": "dma", + "microchip_dmac_g1_dma": "dma", + "microchip_xec_dmac": "dma", + "nuvoton_npcx_gdma": "dma", + "nxp_4ch_dma": "dma", + "nxp_edma": "dma", + "nxp_lpc_dma": "dma", + "nxp_mcux_edma": "dma", + "nxp_pxp": "dma", + "nxp_sdma": "dma", + "nxp_smartdma": "dma", + "nxp_sof_host_dma": "dma", + "raspberrypi_pico_dma": "dma", + "renesas_ra_dma": "dma", + "renesas_rz_dmac": "dma", + "renesas_rz_dmac_b": "dma", + "renesas_smartbond_dma": "dma", + "sifli_sf32lb_dmac": "dma", + "silabs_gpdma": "dma", + "silabs_ldma": "dma", + "silabs_si32_dma": "dma", + "silabs_siwx91x_dma": "dma", + "snps_designware_dma": "dma", + "snps_designware_dma_axi": "dma", + "st_stm32_bdma": "dma", + "st_stm32_dma_v1": "dma", + "st_stm32_dma_v2": "dma", + "st_stm32_dma_v2bis": "dma", + "st_stm32_dmamux": "dma", + "st_stm32u5_dma": "dma", + "ti_cc23x0_dma": "dma", + "wch_wch_dma": "dma", + "xlnx_axi_dma_1_00_a": "dma", + "xlnx_eth_dma": "dma", + "zephyr_dma_emul": "dma", + # + # dp + "zephyr_swdp_gpio": "dp", + # + # edac + "intel_ibecc": "edac", + "nxp_erm": "edac", + "xlnx_zynqmp_ddrc_2_40a": "edac", + # + # eeprom + "atmel_at24": "eeprom", + "fujitsu_mb85rcxx": "eeprom", + "fujitsu_mb85rsxx": "eeprom", + "infineon_fm25xxx": "eeprom", + "microchip_xec_eeprom": "eeprom", + "nxp_lpc11u6x_eeprom": "eeprom", + "st_stm32_eeprom": "eeprom", + "ti_tmp11x_eeprom": "eeprom", + "zephyr_emu_eeprom": "eeprom", + "zephyr_fake_eeprom": "eeprom", + "zephyr_sim_eeprom": "eeprom", + # + # entropy + "adi_max32_trng": "entropy", + "adi_maxq10xx_trng": "entropy", + "ambiq_puf_trng": "entropy", + "atmel_sam_trng": "entropy", + "brcm_iproc_rng200": "entropy", + "espressif_esp32_trng": "entropy", + "gd_gd32_trng": "entropy", + "litex_prbs": "entropy", + "microchip_trng_g1_entropy": "entropy", + "neorv32_trng": "entropy", + "nordic_nrf_cracen_ctrdrbg": "entropy", + "nordic_nrf_rng": "entropy", + "nuvoton_npcx_drbg": "entropy", + "nxp_ele_trng": "entropy", + "nxp_imx_caam": "entropy", + "nxp_kinetis_rnga": "entropy", + "nxp_kinetis_trng": "entropy", + "nxp_lpc_rng": "entropy", + "openisa_rv32m1_trng": "entropy", + "raspberrypi_pico_rng": "entropy", + "renesas_smartbond_trng": "entropy", + "sensry_sy1xx_trng": "entropy", + "sifli_sf32lb_trng": "entropy", + "silabs_gecko_semailbox": "entropy", + "silabs_gecko_trng": "entropy", + "silabs_siwx91x_rng": "entropy", + "st_stm32_rng": "entropy", + "st_stm32_rng_noirq": "entropy", + "telink_b91_trng": "entropy", + "ti_cc13xx_cc26xx_trng": "entropy", + "ti_mspm0_trng": "entropy", + "virtio_device4": "entropy", + "zephyr_bt_hci_entropy": "entropy", + "zephyr_native_sim_rng": "entropy", + "zephyr_psa_crypto_rng": "entropy", + # + # espi + "ite_it8xxx2_espi": "espi", + "microchip_xec_espi": "espi", + "microchip_xec_espi_host_dev": "espi", + "microchip_xec_espi_saf": "espi", + "microchip_xec_espi_saf_v2": "espi", + "microchip_xec_espi_v2": "espi", + "nuvoton_npcx_espi": "espi", + "nuvoton_npcx_espi_taf": "espi", + "nuvoton_npcx_host_sub": "espi", + "realtek_rts5912_espi": "espi", + "zephyr_espi_emul_controller": "espi", + # + # ethernet + "adi_adin1110": "ethernet", + "adi_adin2111": "ethernet", + "atmel_sam0_gmac": "ethernet", + "atmel_sam_gmac": "ethernet", + "espressif_esp32_eth": "ethernet", + "infineon_xmc4xxx_ethernet": "ethernet", + "intel_e1000": "ethernet", + "litex_liteeth": "ethernet", + "microchip_enc28j60": "ethernet", + "microchip_enc424j600": "ethernet", + "microchip_lan865x": "ethernet", + "microchip_lan9250": "ethernet", + "nuvoton_numaker_ethernet": "ethernet", + "nxp_enet": "ethernet", + "nxp_enet1g": "ethernet", + "nxp_enet_mac": "ethernet", + "nxp_s32_gmac": "ethernet", + "nxp_s32_netc_psi": "ethernet", + "nxp_s32_netc_vsi": "ethernet", + "renesas_ra_ethernet": "ethernet", + "sensry_sy1xx_mac": "ethernet", + "siemens_ivshmem_eth": "ethernet", + "silabs_gecko_ethernet": "ethernet", + "smsc_lan91c111": "ethernet", + "smsc_lan91c111_mdio": "ethernet", + "smsc_lan9220": "ethernet", + "snps_designware_ethernet": "ethernet", + "snps_ethernet_cyclonev": "ethernet", + "st_stm32_ethernet": "ethernet", + "ti_stellaris_ethernet": "ethernet", + "virtio_net": "ethernet", + "vnd_ethernet": "ethernet", + "wiznet_w5500": "ethernet", + "wiznet_w6100": "ethernet", + "xlnx_axi_ethernet_1_00_a": "ethernet", + "xlnx_gem": "ethernet", + "xlnx_xps_ethernetlite_1_00_a_mac": "ethernet", + "xlnx_xps_ethernetlite_3_00_a_mac": "ethernet", + # + # ethernet/dsa + "microchip_ksz8463": "ethernet/dsa", + "microchip_ksz8794": "ethernet/dsa", + "microchip_ksz8863": "ethernet/dsa", + "nxp_netc_switch": "ethernet/dsa", + # + # ethernet/dwc_xgmac + "snps_dwcxgmac": "ethernet/dwc_xgmac", + # + # ethernet/eth_nxp_enet_qos + "nxp_enet_qos": "ethernet/eth_nxp_enet_qos", + "nxp_enet_qos_mac": "ethernet/eth_nxp_enet_qos", + # + # ethernet/intel + "intel_eth_plat": "ethernet/intel", + "intel_igc_mac": "ethernet/intel", + # + # ethernet/mdio + "adi_adin2111_mdio": "ethernet/mdio", + "atmel_sam_mdio": "ethernet/mdio", + "espressif_esp32_mdio": "ethernet/mdio", + "infineon_xmc4xxx_mdio": "ethernet/mdio", + "intel_igc_mdio": "ethernet/mdio", + "litex_liteeth_mdio": "ethernet/mdio", + "microchip_lan865x_mdio": "ethernet/mdio", + "nxp_enet_mdio": "ethernet/mdio", + "nxp_enet_qos_mdio": "ethernet/mdio", + "nxp_imx_netc_emdio": "ethernet/mdio", + "nxp_s32_gmac_mdio": "ethernet/mdio", + "nxp_s32_netc_emdio": "ethernet/mdio", + "renesas_ra_mdio": "ethernet/mdio", + "sensry_sy1xx_mdio": "ethernet/mdio", + "snps_dwcxgmac_mdio": "ethernet/mdio", + "st_stm32_mdio": "ethernet/mdio", + "xlnx_axi_ethernet_1_00_a_mdio": "ethernet/mdio", + "xlnx_xps_ethernetlite_1_00_a_mdio": "ethernet/mdio", + "xlnx_xps_ethernetlite_3_00_a_mdio": "ethernet/mdio", + "zephyr_mdio_gpio": "ethernet/mdio", + # + # ethernet/nxp_imx_netc + "nxp_imx_netc_blk_ctrl": "ethernet/nxp_imx_netc", + "nxp_imx_netc_psi": "ethernet/nxp_imx_netc", + # + # ethernet/phy + "adi_adin1100_phy": "ethernet/phy", + "adi_adin2111_phy": "ethernet/phy", + "davicom_dm8806_phy": "ethernet/phy", + "ethernet_phy": "ethernet/phy", + "ethernet_phy_fixed_link": "ethernet/phy", + "microchip_ksz8081": "ethernet/phy", + "microchip_ksz9131": "ethernet/phy", + "microchip_lan8742": "ethernet/phy", + "microchip_t1s_phy": "ethernet/phy", + "microchip_vsc8541": "ethernet/phy", + "motorcomm_yt8521": "ethernet/phy", + "nxp_tja1103": "ethernet/phy", + "nxp_tja11xx": "ethernet/phy", + "qca_ar8031": "ethernet/phy", + "realtek_rtl8211f": "ethernet/phy", + "ti_dp83825": "ethernet/phy", + "ti_dp83867": "ethernet/phy", + # + # firmware/scmi + "arm_scmi": "firmware/scmi", + "arm_scmi_shmem": "firmware/scmi", + # + # firmware/tisci + "ti_k2g_sci": "firmware/tisci", + # + # flash + "adi_max32_flash_controller": "flash", + "adi_max32_spixf_nor": "flash", + "ambiq_flash_controller": "flash", + "andestech_qspi_nor": "flash", + "andestech_qspi_nor_xip": "flash", + "atmel_at25xv021a": "flash", + "atmel_at45": "flash", + "atmel_sam0_nvmctrl": "flash", + "atmel_sam_flash_controller": "flash", + "bflb_flash_controller": "flash", + "cdns_nand": "flash", + "cdns_qspi_nor": "flash", + "espressif_esp32_flash_controller": "flash", + "gd_gd32_flash_controller": "flash", + "infineon_flash_controller": "flash", + "infineon_qspi_flash": "flash", + "infineon_xmc4xxx_flash_controller": "flash", + "ite_it51xxx_manual_flash_1k": "flash", + "ite_it8xxx2_flash_controller": "flash", + "jedec_mspi_nor": "flash", + "jedec_spi_nand": "flash", + "jedec_spi_nor": "flash", + "microchip_nvmctrl_g1_flash": "flash", + "mspi_atxp032": "flash", + "mspi_is25xx0xx": "flash", + "netsol_s3axx04": "flash", + "nordic_mram": "flash", + "nordic_nrf51_flash_controller": "flash", + "nordic_nrf52_flash_controller": "flash", + "nordic_nrf53_flash_controller": "flash", + "nordic_nrf91_flash_controller": "flash", + "nordic_nrf_mramc": "flash", + "nordic_qspi_nor": "flash", + "nordic_rram_controller": "flash", + "nuvoton_npcx_fiu_nor": "flash", + "nuvoton_npcx_fiu_qspi": "flash", + "nuvoton_numaker_fmc": "flash", + "nuvoton_numaker_rmc": "flash", + "nxp_c40_flash_controller": "flash", + "nxp_iap_fmc11": "flash", + "nxp_iap_fmc54": "flash", + "nxp_iap_fmc55": "flash", + "nxp_iap_fmc553": "flash", + "nxp_imx_flexspi_hyperflash": "flash", + "nxp_imx_flexspi_mx25um51345g": "flash", + "nxp_imx_flexspi_nor": "flash", + "nxp_kinetis_ftfa": "flash", + "nxp_kinetis_ftfc": "flash", + "nxp_kinetis_ftfe": "flash", + "nxp_kinetis_ftfl": "flash", + "nxp_msf1": "flash", + "nxp_s32_qspi_hyperflash": "flash", + "nxp_s32_qspi_nor": "flash", + "nxp_s32_xspi_hyperram": "flash", + "nxp_xspi_nor": "flash", + "openisa_rv32m1_ftfe": "flash", + "raspberrypi_pico_flash_controller": "flash", + "realtek_rts5912_flash_controller": "flash", + "renesas_ra_flash_hp_controller": "flash", + "renesas_ra_flash_lp_controller": "flash", + "renesas_ra_mram_controller": "flash", + "renesas_ra_ospi_b_nor": "flash", + "renesas_ra_qspi_nor": "flash", + "renesas_rx_flash": "flash", + "renesas_rz_qspi_spibsc": "flash", + "renesas_rz_qspi_xspi": "flash", + "renesas_smartbond_flash_controller": "flash", + "sifli_sf32lb_mpi_qspi_nor": "flash", + "silabs_gecko_flash_controller": "flash", + "silabs_series2_flash_controller": "flash", + "silabs_si32_flash_controller": "flash", + "silabs_siwx91x_flash_controller": "flash", + "st_stm32_flash_controller": "flash", + "st_stm32_ospi_nor": "flash", + "st_stm32_qspi_nor": "flash", + "st_stm32_xspi_nor": "flash", + "st_stm32h7_flash_controller": "flash", + "st_stm32wb0_flash_controller": "flash", + "st_stm32wba_flash_controller": "flash", + "telink_b91_flash_controller": "flash", + "ti_cc13xx_cc26xx_flash_controller": "flash", + "ti_cc23x0_flash_controller": "flash", + "zephyr_mspi_emul_flash": "flash", + "zephyr_sim_flash": "flash", + # + # fpga + "altr_socfpga_agilex_bridge": "fpga", + "lattice_ice40_fpga": "fpga", + "lattice_ice40_fpga_bitbang": "fpga", + "microchip_mpfs_mailbox": "fpga", + "renesas_slg47105": "fpga", + "renesas_slg47115": "fpga", + "xlnx_fpga": "fpga", + # + # fuel_gauge/axp2101 + "x_powers_axp2101_fuel_gauge": "fuel_gauge/axp2101", + # + # fuel_gauge/bq27z746 + "ti_bq27z746": "fuel_gauge/bq27z746", + # + # fuel_gauge/bq40z50 + "ti_bq40z50": "fuel_gauge/bq40z50", + # + # fuel_gauge/composite + "zephyr_fuel_gauge_composite": "fuel_gauge/composite", + # + # fuel_gauge/hy4245 + "hycon_hy4245": "fuel_gauge/hy4245", + # + # fuel_gauge/lc709203f + "onnn_lc709203f": "fuel_gauge/lc709203f", + # + # fuel_gauge/ltc2959 + "adi_ltc2959": "fuel_gauge/ltc2959", + # + # fuel_gauge/max17048 + "maxim_max17048": "fuel_gauge/max17048", + # + # fuel_gauge/sbs_gauge + "sbs_sbs_gauge": "fuel_gauge/sbs_gauge", + "sbs_sbs_gauge_new_api": "fuel_gauge/sbs_gauge", + # + # fuel_gauge/sy24561 + "silergy_sy24561": "fuel_gauge/sy24561", + # + # gnss + "gnss_nmea_generic": "gnss", + "luatos_air530z": "gnss", + "quectel_lc26g": "gnss", + "quectel_lc76g": "gnss", + "quectel_lc86g": "gnss", + "zephyr_gnss_emul": "gnss", + # + # gnss/u_blox + "u_blox_f9p": "gnss/u_blox", + "u_blox_m8": "gnss/u_blox", + # + # gpio + "adi_ad559x_gpio": "gpio", + "adi_adp5585_gpio": "gpio", + "adi_max14906_gpio": "gpio", + "adi_max14915_gpio": "gpio", + "adi_max14916_gpio": "gpio", + "adi_max14917_gpio": "gpio", + "adi_max22017_gpio": "gpio", + "adi_max22190_gpio": "gpio", + "adi_max22199_gpio": "gpio", + "adi_max32_gpio": "gpio", + "aesc_gpio": "gpio", + "altr_pio_1_0": "gpio", + "ambiq_gpio_bank": "gpio", + "andestech_atcgpio100": "gpio", + "arm_cmsdk_gpio": "gpio", + "arm_mmio32_gpio": "gpio", + "atmel_sam0_gpio": "gpio", + "atmel_sam4l_gpio": "gpio", + "atmel_sam_gpio": "gpio", + "awinic_aw9523b_gpio": "gpio", + "bflb_bl60x_70x_gpio": "gpio", + "bflb_bl61x_gpio": "gpio", + "brcm_bcm2711_gpio": "gpio", + "brcm_brcmstb_gpio": "gpio", + "brcm_iproc_gpio": "gpio", + "cypress_cy8c95xx_gpio_port": "gpio", + "cypress_psoc6_gpio": "gpio", + "efinix_sapphire_gpio": "gpio", + "ene_kb106x_gpio": "gpio", + "ene_kb1200_gpio": "gpio", + "espressif_esp32_gpio": "gpio", + "espressif_esp32_lpgpio": "gpio", + "fcs_fxl6408": "gpio", + "gaisler_grgpio": "gpio", + "gd_gd32_gpio": "gpio", + "infineon_gpio": "gpio", + "infineon_tle9104_gpio": "gpio", + "infineon_xmc4xxx_gpio": "gpio", + "intel_gpio": "gpio", + "intel_sedi_gpio": "gpio", + "ite_it51xxx_gpio": "gpio", + "ite_it8801_gpio": "gpio", + "ite_it8xxx2_gpio": "gpio", + "ite_it8xxx2_gpio_v2": "gpio", + "ite_it8xxx2_gpiokscan": "gpio", + "litex_gpio": "gpio", + "microchip_mcp23008": "gpio", + "microchip_mcp23009": "gpio", + "microchip_mcp23016": "gpio", + "microchip_mcp23017": "gpio", + "microchip_mcp23018": "gpio", + "microchip_mcp23s08": "gpio", + "microchip_mcp23s09": "gpio", + "microchip_mcp23s17": "gpio", + "microchip_mcp23s18": "gpio", + "microchip_mpfs_gpio": "gpio", + "microchip_port_g1_gpio": "gpio", + "microchip_sam_pio4": "gpio", + "microchip_xec_gpio": "gpio", + "neorv32_gpio": "gpio", + "nordic_npm1300_gpio": "gpio", + "nordic_npm1304_gpio": "gpio", + "nordic_npm2100_gpio": "gpio", + "nordic_npm6001_gpio": "gpio", + "nordic_nrf_gpio": "gpio", + "nuvoton_nct38xx_gpio": "gpio", + "nuvoton_nct38xx_gpio_alert": "gpio", + "nuvoton_nct38xx_gpio_port": "gpio", + "nuvoton_npcx_gpio": "gpio", + "nuvoton_numaker_gpio": "gpio", + "nuvoton_numicro_gpio": "gpio", + "nxp_imx_gpio": "gpio", + "nxp_imx_rgpio": "gpio", + "nxp_kinetis_gpio": "gpio", + "nxp_lpc11u6x_gpio": "gpio", + "nxp_lpc_gpio_port": "gpio", + "nxp_pca6408": "gpio", + "nxp_pca6416": "gpio", + "nxp_pca9538": "gpio", + "nxp_pca9539": "gpio", + "nxp_pca9554": "gpio", + "nxp_pca9555": "gpio", + "nxp_pca95xx": "gpio", + "nxp_pcal6408": "gpio", + "nxp_pcal6408a": "gpio", + "nxp_pcal6416": "gpio", + "nxp_pcal6416a": "gpio", + "nxp_pcal6524": "gpio", + "nxp_pcal6534": "gpio", + "nxp_pcal9538": "gpio", + "nxp_pcal9539": "gpio", + "nxp_pcal9722": "gpio", + "nxp_pcf857x": "gpio", + "nxp_sc18im704_gpio": "gpio", + "nxp_sc18is606_gpio": "gpio", + "nxp_siul2_gpio": "gpio", + "openisa_rv32m1_gpio": "gpio", + "quicklogic_eos_s3_gpio": "gpio", + "raspberrypi_pico_gpio_port": "gpio", + "raspberrypi_rp1_gpio": "gpio", + "realtek_ameba_gpio": "gpio", + "realtek_bee_gpio": "gpio", + "realtek_rts5912_gpio": "gpio", + "renesas_ra_gpio_ioport": "gpio", + "renesas_rcar_gpio": "gpio", + "renesas_rx_gpio": "gpio", + "renesas_rz_gpio": "gpio", + "renesas_rza2m_gpio": "gpio", + "renesas_rzt2m_gpio": "gpio", + "renesas_smartbond_gpio": "gpio", + "richtek_rt1718s": "gpio", + "richtek_rt1718s_gpio_port": "gpio", + "rohm_bd8lb600fs_gpio": "gpio", + "semtech_sx1509b": "gpio", + "sensry_sy1xx_gpio": "gpio", + "sifive_gpio0": "gpio", + "sifli_sf32lb_gpio": "gpio", + "silabs_gecko_gpio_port": "gpio", + "silabs_gpio": "gpio", + "silabs_si32_gpio": "gpio", + "silabs_siwx91x_gpio": "gpio", + "silabs_siwx91x_gpio_uulp": "gpio", + "snps_creg_gpio": "gpio", + "snps_designware_gpio": "gpio", + "st_mfxstm32l152": "gpio", + "st_stm32_gpio": "gpio", + "st_stmpe1600": "gpio", + "telink_b91_gpio": "gpio", + "ti_ads1x4s0x_gpio": "gpio", + "ti_cc13xx_cc26xx_gpio": "gpio", + "ti_cc23x0_gpio": "gpio", + "ti_cc32xx_gpio": "gpio", + "ti_davinci_gpio": "gpio", + "ti_lmp90xxx_gpio": "gpio", + "ti_mspm0_gpio": "gpio", + "ti_sn74hc595": "gpio", + "ti_stellaris_gpio": "gpio", + "ti_tca6424a": "gpio", + "ti_tca9538": "gpio", + "vnd_gpio": "gpio", + "wch_gpio": "gpio", + "x_powers_axp192_gpio": "gpio", + "xlnx_ps_gpio": "gpio", + "xlnx_ps_gpio_bank": "gpio", + "xlnx_xps_gpio_1_00_a": "gpio", + "zephyr_gpio_emul": "gpio", + "zephyr_gpio_emul_sdl": "gpio", + # + # haptics/cirrus + "cirrus_cs40l5x": "haptics/cirrus", + # + # haptics/ti + "ti_drv2605": "haptics/ti", + # + # hdlc_rcp_if + "nxp_hdlc_rcp_if": "hdlc_rcp_if", + "spi_hdlc_rcp_if": "hdlc_rcp_if", + "uart_hdlc_rcp_if": "hdlc_rcp_if", + # + # hwinfo + "atmel_sam0_id": "hwinfo", + "atmel_sam4l_uid": "hwinfo", + "atmel_sam_rstc": "hwinfo", + "cypress_psoc6_uid": "hwinfo", + "litex_dna0": "hwinfo", + "nxp_imx_src": "hwinfo", + "nxp_imx_src_rev2": "hwinfo", + "nxp_lpc_uid": "hwinfo", + # + # hwspinlock + "nxp_sema42": "hwspinlock", + "sqn_hwspinlock": "hwspinlock", + "vnd_hwspinlock": "hwspinlock", + # + # i2c + "adi_max32_i2c": "i2c", + "altr_nios2_i2c": "i2c", + "ambiq_i2c": "i2c", + "andestech_atciic100": "i2c", + "arm_versatile_i2c": "i2c", + "atmel_sam0_i2c": "i2c", + "atmel_sam_i2c_twi": "i2c", + "atmel_sam_i2c_twihs": "i2c", + "atmel_sam_i2c_twim": "i2c", + "bflb_i2c": "i2c", + "brcm_iproc_i2c": "i2c", + "cdns_i2c": "i2c", + "ene_kb1200_i2c": "i2c", + "espressif_esp32_i2c": "i2c", + "fsl_imx21_i2c": "i2c", + "gd_gd32_i2c": "i2c", + "gpio_i2c": "i2c", + "gpio_i2c_switch": "i2c", + "infineon_i2c": "i2c", + "infineon_xmc4xxx_i2c": "i2c", + "intel_sedi_i2c": "i2c", + "ite_enhance_i2c": "i2c", + "ite_it51xxx_i2c": "i2c", + "ite_it8xxx2_i2c": "i2c", + "litex_i2c": "i2c", + "litex_litei2c": "i2c", + "microchip_mpfs_i2c": "i2c", + "microchip_sercom_g1_i2c": "i2c", + "microchip_xec_i2c": "i2c", + "microchip_xec_i2c_v2": "i2c", + "nordic_nrf_twi": "i2c", + "nordic_nrf_twim": "i2c", + "nordic_nrf_twis": "i2c", + "nuvoton_npcx_i2c_ctrl": "i2c", + "nuvoton_npcx_i2c_port": "i2c", + "nuvoton_numaker_i2c": "i2c", + "nxp_ii2c": "i2c", + "nxp_kinetis_i2c": "i2c", + "nxp_lpc11u6x_i2c": "i2c", + "nxp_lpc_i2c": "i2c", + "nxp_lpi2c": "i2c", + "nxp_sc18im704_i2c": "i2c", + "openisa_rv32m1_lpi2c": "i2c", + "realtek_rts5912_i2c": "i2c", + "renesas_ra_i2c_sci": "i2c", + "renesas_ra_i2c_sci_b": "i2c", + "renesas_ra_iic": "i2c", + "renesas_rcar_i2c": "i2c", + "renesas_rx_i2c": "i2c", + "renesas_rz_iic": "i2c", + "renesas_rz_riic": "i2c", + "renesas_rza2m_riic": "i2c", + "renesas_smartbond_i2c": "i2c", + "sensry_sy1xx_i2c": "i2c", + "sifive_i2c0": "i2c", + "sifli_sf32lb_i2c": "i2c", + "silabs_gecko_i2c": "i2c", + "silabs_i2c": "i2c", + "snps_designware_i2c": "i2c", + "st_stm32_i2c_v1": "i2c", + "st_stm32_i2c_v2": "i2c", + "telink_b91_i2c": "i2c", + "ti_cc13xx_cc26xx_i2c": "i2c", + "ti_cc23x0_i2c": "i2c", + "ti_cc32xx_i2c": "i2c", + "ti_omap_i2c": "i2c", + "ti_tca9544a": "i2c", + "ti_tca9546a": "i2c", + "ti_tca9548a": "i2c", + "vnd_i2c": "i2c", + "wch_i2c": "i2c", + "xlnx_xps_iic_2_00_a": "i2c", + "xlnx_xps_iic_2_1": "i2c", + "zephyr_i2c_emul_controller": "i2c", + # + # i2c/target + "zephyr_i2c_target_eeprom": "i2c/target", + # + # i2s + "adi_max32_i2s": "i2s", + "ambiq_i2s": "i2s", + "atmel_sam_ssc": "i2s", + "espressif_esp32_i2s": "i2s", + "infineon_i2s": "i2s", + "nordic_nrf_i2s": "i2s", + "nxp_lpc_i2s": "i2s", + "nxp_mcux_i2s": "i2s", + "renesas_ra_i2s_ssie": "i2s", + "silabs_siwx91x_i2s": "i2s", + "st_stm32_i2s": "i2s", + "st_stm32_sai": "i2s", + "vnd_i2s": "i2s", + "zephyr_i2s_sdl": "i2s", + # + # i3c + "adi_max32_i3c": "i3c", + "cdns_i3c": "i3c", + "ite_it51xxx_i3cm": "i3c", + "ite_it51xxx_i3cs": "i3c", + "nuvoton_npcx_i3c": "i3c", + "nxp_mcux_i3c": "i3c", + "renesas_ra_i3c": "i3c", + "snps_designware_i3c": "i3c", + "st_stm32_i3c": "i3c", + "vnd_i3c": "i3c", + # + # ieee802154 + "atmel_rf2xx": "ieee802154", + "decawave_dw1000": "ieee802154", + "espressif_esp32_ieee802154": "ieee802154", + "nordic_nrf_ieee802154": "ieee802154", + "nxp_kw41z_ieee802154": "ieee802154", + "nxp_mcr20a": "ieee802154", + "nxp_mcxw_ieee802154": "ieee802154", + "st_stm32wba_ieee802154": "ieee802154", + "telink_b91_zb": "ieee802154", + "ti_cc1200": "ieee802154", + "ti_cc13xx_cc26xx_ieee802154": "ieee802154", + "ti_cc13xx_cc26xx_ieee802154_subghz": "ieee802154", + "ti_cc2520": "ieee802154", + "zephyr_ieee802154_uart_pipe": "ieee802154", + # + # input + "adc_keys": "input", + "analog_axis": "input", + "arduino_modulino_buttons": "input", + "bflb_irx": "input", + "chipsemi_chsc5x": "input", + "chipsemi_chsc6x": "input", + "cirque_pinnacle": "input", + "cypress_cy8cmbr3xxx": "input", + "espressif_esp32_touch": "input", + "focaltech_ft5336": "input", + "focaltech_ft6146": "input", + "futaba_sbus": "input", + "goodix_gt911": "input", + "gpio_kbd_matrix": "input", + "gpio_keys": "input", + "gpio_qdec": "input", + "hynitron_cst816s": "input", + "ilitek_ili2132a": "input", + "ite_it51xxx_kbd": "input", + "ite_it8801_kbd": "input", + "ite_it8xxx2_kbd": "input", + "microchip_cap12xx": "input", + "microchip_xec_kbd": "input", + "nintendo_nunchuk": "input", + "nuvoton_npcx_kbd": "input", + "nxp_mcux_kpp": "input", + "parade_tma525b": "input", + "pixart_pat912x": "input", + "pixart_paw32xx": "input", + "pixart_pmw3610": "input", + "realtek_rts5912_kbd": "input", + "renesas_ra_ctsu": "input", + "renesas_ra_ctsu_button": "input", + "renesas_ra_ctsu_slider": "input", + "renesas_ra_ctsu_wheel": "input", + "renesas_rx_ctsu": "input", + "sitronix_cf1133": "input", + "st_stm32_tsc": "input", + "st_stmpe811": "input", + "vishay_vs1838b": "input", + "wch_ch9350l": "input", + "xptek_xpt2046": "input", + "zephyr_input_sdl_touch": "input", + "zephyr_native_linux_evdev": "input", + # + # interrupt_controller + "adi_max32_rv32_intc": "interrupt_controller", + "arm_gic_v1": "interrupt_controller", + "arm_gic_v2": "interrupt_controller", + "arm_gic_v3": "interrupt_controller", + "arm_gic_v3_its": "interrupt_controller", + "atmel_sam0_eic": "interrupt_controller", + "gaisler_irqmp": "interrupt_controller", + "gd_gd32_exti": "interrupt_controller", + "hazard3_hazard3_intc": "interrupt_controller", + "infineon_xmc4xxx_intc": "interrupt_controller", + "intel_ace_intc": "interrupt_controller", + "intel_cavs_intc": "interrupt_controller", + "intel_ioapic": "interrupt_controller", + "intel_loapic": "interrupt_controller", + "intel_vt_d": "interrupt_controller", + "ite_it51xxx_wuc": "interrupt_controller", + "ite_it8xxx2_wuc": "interrupt_controller", + "litex_vexriscv_intc0": "interrupt_controller", + "mediatek_adsp_intc": "interrupt_controller", + "microchip_eic_g1_intc": "interrupt_controller", + "microchip_xec_ecia": "interrupt_controller", + "nuclei_eclic": "interrupt_controller", + "nuvoton_npcx_miwu": "interrupt_controller", + "nxp_gint": "interrupt_controller", + "nxp_irqsteer_intc": "interrupt_controller", + "nxp_pint": "interrupt_controller", + "nxp_s32_wkpu": "interrupt_controller", + "nxp_siul2_eirq": "interrupt_controller", + "openisa_rv32m1_intmux": "interrupt_controller", + "renesas_rx_grp_intc": "interrupt_controller", + "renesas_rx_icu": "interrupt_controller", + "renesas_rz_ext_irq": "interrupt_controller", + "renesas_rz_tint": "interrupt_controller", + "riscv_clic": "interrupt_controller", + "riscv_imsic": "interrupt_controller", + "shared_irq": "interrupt_controller", + "sifive_plic_1_0_0": "interrupt_controller", + "snps_arcv2_intc": "interrupt_controller", + "snps_designware_intc": "interrupt_controller", + "st_stm32wb0_gpio_intc": "interrupt_controller", + "swerv_pic": "interrupt_controller", + "ti_vim": "interrupt_controller", + "wch_exti": "interrupt_controller", + "wch_pfic": "interrupt_controller", + # + # ipm + "arm_mhu": "ipm", + "espressif_esp32_ipm": "ipm", + "intel_sedi_ipm": "ipm", + "linaro_ivshmem_ipm": "ipm", + "nordic_nrf_ipc": "ipm", + "nxp_imx_mu": "ipm", + "nxp_lpc_mailbox": "ipm", + "st_stm32_hsem_mailbox": "ipm", + "st_stm32_ipcc_mailbox": "ipm", + "xlnx_zynqmp_ipi_mailbox": "ipm", + "zephyr_mbox_ipm": "ipm", + # + # led + "arduino_modulino_buttons_leds": "led", + "dac_leds": "led", + "gpio_leds": "led", + "holtek_ht16k33": "led", + "issi_is31fl3194": "led", + "issi_is31fl3216a": "led", + "issi_is31fl3733": "led", + "leds_group_multicolor": "led", + "microchip_xec_bbled": "led", + "nordic_npm1300_led": "led", + "nordic_npm1304_led": "led", + "nxp_pca9533": "led", + "nxp_pca9633": "led", + "onnn_ncp5623": "led", + "pwm_leds": "led", + "sct_sct2024": "led", + "ti_lp3943": "led", + "ti_lp5009": "led", + "ti_lp5012": "led", + "ti_lp5018": "led", + "ti_lp5024": "led", + "ti_lp5030": "led", + "ti_lp5036": "led", + "ti_lp5562": "led", + "ti_lp5569": "led", + "ti_tlc59108": "led", + # + # led_strip + "apa_apa102": "led_strip", + "arduino_modulino_pixels": "led_strip", + "greeled_lpd8803": "led_strip", + "greeled_lpd8806": "led_strip", + "ti_tlc5971": "led_strip", + "ti_tlc59731": "led_strip", + "worldsemi_ws2812_gpio": "led_strip", + "worldsemi_ws2812_i2s": "led_strip", + "worldsemi_ws2812_rpi_pico_pio": "led_strip", + "worldsemi_ws2812_spi": "led_strip", + "worldsemi_ws2812_uart": "led_strip", + # + # lora + "reyax_rylrxxx": "lora", + # + # lora/loramac-node + "semtech_sx1272": "lora/loramac-node", + "semtech_sx1276": "lora/loramac-node", + # + # lora/native/sx126x + "semtech_sx1261": "lora/native/sx126x", + "semtech_sx1262": "lora/native/sx126x", + "st_stm32wl_subghz_radio": "lora/native/sx126x", + # + # mbox + "andestech_mbox_plic_sw": "mbox", + "arm_mhuv3": "mbox", + "espressif_mbox_esp32": "mbox", + "linaro_ivshmem_mbox": "mbox", + "nordic_mbox_nrf_ipc": "mbox", + "nordic_nrf_bellboard_rx": "mbox", + "nordic_nrf_bellboard_tx": "mbox", + "nordic_nrf_vevif_event_rx": "mbox", + "nordic_nrf_vevif_event_tx": "mbox", + "nordic_nrf_vevif_task_rx": "mbox", + "nordic_nrf_vevif_task_tx": "mbox", + "nxp_mbox_imx_mu": "mbox", + "nxp_mbox_mailbox": "mbox", + "nxp_s32_mru": "mbox", + "raspberrypi_pico_mbox": "mbox", + "renesas_ra_ipc_mbox": "mbox", + "renesas_rz_mhu_mbox": "mbox", + "st_mbox_stm32_hsem": "mbox", + "ti_omap_mailbox": "mbox", + "ti_secure_proxy": "mbox", + "xlnx_mbox_versal_ipi_mailbox": "mbox", + # + # memc + "adi_max32_hpb": "memc", + "atmel_sam_smc": "memc", + "bflb_bl61x_psram": "memc", + "mspi_aps6404l": "memc", + "mspi_aps_z8": "memc", + "nxp_imx_flexspi": "memc", + "nxp_imx_flexspi_is66wvs8m8": "memc", + "nxp_imx_flexspi_s27ks0641": "memc", + "nxp_imx_flexspi_w956a8mbya": "memc", + "nxp_s32_qspi": "memc", + "nxp_s32_xspi": "memc", + "nxp_xspi": "memc", + "nxp_xspi_psram": "memc", + "renesas_ra_sdram": "memc", + "renesas_smartbond_nor_psram": "memc", + "sifive_fu740_c000_ddr": "memc", + "silabs_siwx91x_qspi_memory": "memc", + "st_stm32_fmc": "memc", + "st_stm32_fmc_nor_psram": "memc", + "st_stm32_fmc_sdram": "memc", + "st_stm32_ospi_psram": "memc", + "st_stm32_xspi_psram": "memc", + "st_stm32h7_fmc": "memc", + # + # mfd + "adi_ad559x": "mfd", + "adi_adp5585": "mfd", + "adi_max22017": "mfd", + "adi_maxq10xx": "mfd", + "awinic_aw9523b": "mfd", + "infineon_tle9104": "mfd", + "ite_it8801_altctrl": "mfd", + "ite_it8801_mfd": "mfd", + "maxim_ds3231_mfd": "mfd", + "maxim_max20335": "mfd", + "maxim_max31790": "mfd", + "microchip_sam_flexcom": "mfd", + "microcrystal_rv3032_mfd": "mfd", + "motorola_mc146818_mfd": "mfd", + "nordic_npm1300": "mfd", + "nordic_npm1304": "mfd", + "nordic_npm2100": "mfd", + "nordic_npm6001": "mfd", + "nuvoton_nct38xx": "mfd", + "nxp_lp_flexcomm": "mfd", + "nxp_pca9422": "mfd", + "nxp_pf1550": "mfd", + "nxp_sc18is606": "mfd", + "rohm_bd8lb600fs": "mfd", + # + # mipi_dbi + "bflb_dbi": "mipi_dbi", + "espressif_esp32_lcd_cam_mipi_dbi": "mipi_dbi", + "nxp_lcdic": "mipi_dbi", + "nxp_mipi_dbi_dcnano_lcdif": "mipi_dbi", + "nxp_mipi_dbi_flexio_lcdif": "mipi_dbi", + "raspberrypi_pico_mipi_dbi_pio": "mipi_dbi", + "renesas_smartbond_mipi_dbi": "mipi_dbi", + "sifli_sf32lb_lcdc_mipi_dbi": "mipi_dbi", + "st_stm32_fmc_mipi_dbi": "mipi_dbi", + "zephyr_mipi_dbi_bitbang": "mipi_dbi", + "zephyr_mipi_dbi_spi": "mipi_dbi", + # + # mipi_dsi + "nxp_imx_mipi_dsi": "mipi_dsi", + "nxp_mipi_dsi_2l": "mipi_dsi", + "nxp_mipi_dsi_dwc": "mipi_dsi", + "renesas_ra_mipi_dsi": "mipi_dsi", + "st_stm32_mipi_dsi": "mipi_dsi", + "vnd_mipi_dsi": "mipi_dsi", + # + # misc/devmux + "zephyr_devmux": "misc/devmux", + # + # misc/ethos_u + "arm_ethos_u": "misc/ethos_u", + "nuvoton_numaker_npu": "misc/ethos_u", + "renesas_ra_npu": "misc/ethos_u", + # + # misc/ft8xx + "ftdi_ft800": "misc/ft8xx", + # + # misc/grove_lcd_rgb + "seeed_grove_lcd_rgb": "misc/grove_lcd_rgb", + # + # misc/interconn/renesas_elc + "renesas_ra_elc": "misc/interconn/renesas_elc", + # + # misc/mcux_flexio + "nxp_flexio": "misc/mcux_flexio", + # + # misc/nordic_vpr_launcher + "nordic_nrf_vpr_coprocessor": "misc/nordic_vpr_launcher", + # + # misc/nxp_imx93_mediamix + "nxp_imx93_mediamix": "misc/nxp_imx93_mediamix", + # + # misc/nxp_rtxxx_dsp_ctrl + "nxp_rt600_dsp_ctrl": "misc/nxp_rtxxx_dsp_ctrl", + "nxp_rt700_dsp_ctrl_hifi4": "misc/nxp_rtxxx_dsp_ctrl", + # + # misc/nxp_s32_emios + "nxp_s32_emios": "misc/nxp_s32_emios", + # + # misc/pio_rpi_pico + "raspberrypi_pico_pio": "misc/pio_rpi_pico", + # + # misc/renesas_ra_external_interrupt + "renesas_ra_external_interrupt": "misc/renesas_ra_external_interrupt", + # + # misc/renesas_rx_dtc + "renesas_rx_dtc": "misc/renesas_rx_dtc", + # + # misc/renesas_rx_external_interrupt + "renesas_rx_external_interrupt": "misc/renesas_rx_external_interrupt", + # + # misc/stm32n6_axisram + "st_stm32n6_ramcfg": "misc/stm32n6_axisram", + # + # misc/timeaware_gpio + "intel_timeaware_gpio": "misc/timeaware_gpio", + # + # mm + "intel_adsp_mtl_tlb": "mm", + "intel_adsp_tlb": "mm", + # + # modem + "nordic_nrf91_slm": "modem", + "quectel_bg95": "modem", + "quectel_bg96": "modem", + "quectel_bg9x": "modem", + "quectel_eg25_g": "modem", + "quectel_eg800q": "modem", + "simcom_a76xx": "modem", + "sqn_gm02s": "modem", + "st_st87mxx": "modem", + "telit_me310g1": "modem", + "telit_me910g1": "modem", + "u_blox_lara_r6": "modem", + "u_blox_sara_r4": "modem", + "u_blox_sara_r5": "modem", + "wnc_m14a2a": "modem", + # + # modem/hl78xx + "swir_hl7800": "modem/hl78xx", + "swir_hl7800_gnss": "modem/hl78xx", + "swir_hl7800_offload": "modem/hl78xx", + "swir_hl7812": "modem/hl78xx", + "swir_hl7812_gnss": "modem/hl78xx", + "swir_hl7812_offload": "modem/hl78xx", + # + # modem/simcom/sim7080 + "simcom_sim7080": "modem/simcom/sim7080", + # + # mspi + "ambiq_mspi_controller": "mspi", + "snps_designware_ssi": "mspi", + "st_stm32_ospi_controller": "mspi", + "st_stm32_qspi_controller": "mspi", + "st_stm32_xspi_controller": "mspi", + "zephyr_mspi_emul_controller": "mspi", + # + # opamp + "nxp_opamp": "opamp", + "nxp_opamp_fast": "opamp", + "st_stm32_opamp": "opamp", + # + # otp + "nxp_ocotp": "otp", + "sifli_sf32lb_efuse": "otp", + "st_stm32_bsec": "otp", + "zephyr_otp_emul": "otp", + # + # pcie/controller + "brcm_brcmstb_pcie": "pcie/controller", + # + # pcie/endpoint + "brcm_iproc_pcie_ep": "pcie/endpoint", + # + # pcie/host + "pci_host_ecam_generic": "pcie/host", + "pcie_controller": "pcie/host", + "ptm_root": "pcie/host", + # + # peci + "ite_it8xxx2_peci": "peci", + "microchip_xec_peci": "peci", + "nuvoton_npcx_peci": "peci", + # + # pinctrl + "alif_pinctrl": "pinctrl", + "brcm_bcm2711_pinctrl": "pinctrl", + "ene_kb106x_pinctrl": "pinctrl", + "ene_kb1200_pinctrl": "pinctrl", + "infineon_xmc4xxx_pinctrl": "pinctrl", + "ite_it8xxx2_pinctrl_func": "pinctrl", + "microchip_xec_pinctrl": "pinctrl", + "nuvoton_numaker_pinctrl": "pinctrl", + "nuvoton_numicro_pinctrl": "pinctrl", + "nxp_port_pinmux": "pinctrl", + "openisa_rv32m1_pinmux": "pinctrl", + "quicklogic_eos_s3_pinctrl": "pinctrl", + "realtek_rts5912_pinctrl": "pinctrl", + "sensry_sy1xx_pinctrl": "pinctrl", + "sifive_pinctrl": "pinctrl", + "sifli_sf32lb52x_pinmux": "pinctrl", + "silabs_dbus_pinctrl": "pinctrl", + "silabs_siwx91x_pinctrl": "pinctrl", + "snps_emsdp_pinctrl": "pinctrl", + "telink_b91_pinctrl": "pinctrl", + "ti_cc13xx_cc26xx_pinctrl": "pinctrl", + "ti_cc23x0_pinctrl": "pinctrl", + "ti_cc32xx_pinctrl": "pinctrl", + "ti_k3_pinctrl": "pinctrl", + "ti_mspm0_pinctrl": "pinctrl", + "wch_00x_afio": "pinctrl", + "wch_20x_30x_afio": "pinctrl", + "wch_afio": "pinctrl", + "xlnx_pinctrl_zynq": "pinctrl", + "xlnx_pinctrl_zynqmp": "pinctrl", + # + # pinctrl/renesas/rcar + "renesas_rcar_pfc": "pinctrl/renesas/rcar", + # + # pinctrl/renesas/rz + "renesas_rza2m_pinctrl": "pinctrl/renesas/rz", + "renesas_rzt2m_pinctrl": "pinctrl/renesas/rz", + # + # pm_cpu_ops + "arm_fvp_pwrc": "pm_cpu_ops", + "arm_psci_0_2": "pm_cpu_ops", + "arm_psci_1_1": "pm_cpu_ops", + # + # power_domain + "arm_scmi_power_domain": "power_domain", + "intel_adsp_power_domain": "power_domain", + "nordic_nrfs_gdpwr": "power_domain", + "nordic_nrfs_swext": "power_domain", + "nxp_scu_pd": "power_domain", + "power_domain_gpio": "power_domain", + "power_domain_gpio_monitor": "power_domain", + "power_domain_soc_state_change": "power_domain", + "silabs_siwx91x_power_domain": "power_domain", + "ti_sci_pm_domain": "power_domain", + # + # ps2 + "ite_it51xxx_ps2": "ps2", + "microchip_xec_ps2": "ps2", + "nuvoton_npcx_ps2_channel": "ps2", + "nuvoton_npcx_ps2_ctrl": "ps2", + # + # psi5 + "nxp_s32_psi5": "psi5", + # + # ptp_clock + "nxp_enet_ptp_clock": "ptp_clock", + "nxp_netc_ptp_clock": "ptp_clock", + # + # pwm + "adi_max32_pwm": "pwm", + "ambiq_ctimer_pwm": "pwm", + "ambiq_timer_pwm": "pwm", + "atmel_sam0_tc_pwm": "pwm", + "atmel_sam0_tcc_pwm": "pwm", + "atmel_sam_pwm": "pwm", + "bflb_pwm_1": "pwm", + "bflb_pwm_2": "pwm", + "ene_kb106x_pwm": "pwm", + "ene_kb1200_pwm": "pwm", + "espressif_esp32_ledc": "pwm", + "espressif_esp32_mcpwm": "pwm", + "fsl_imx27_pwm": "pwm", + "gd_gd32_pwm": "pwm", + "infineon_tcpwm_pwm": "pwm", + "infineon_xmc4xxx_ccu4_pwm": "pwm", + "infineon_xmc4xxx_ccu8_pwm": "pwm", + "intel_blinky_pwm": "pwm", + "ite_it51xxx_pwm": "pwm", + "ite_it8801_pwm": "pwm", + "ite_it8xxx2_pwm": "pwm", + "litex_pwm": "pwm", + "maxim_max31790_pwm": "pwm", + "microchip_tc_g1_pwm": "pwm", + "microchip_tcc_g1_pwm": "pwm", + "microchip_xec_pwm": "pwm", + "microchip_xec_pwmbbled": "pwm", + "neorv32_pwm": "pwm", + "nordic_nrf_pwm": "pwm", + "nordic_nrf_sw_pwm": "pwm", + "nuvoton_npcx_pwm": "pwm", + "nuvoton_numaker_pwm": "pwm", + "nxp_ctimer_pwm": "pwm", + "nxp_flexio_pwm": "pwm", + "nxp_ftm_pwm": "pwm", + "nxp_imx_pwm": "pwm", + "nxp_kinetis_pwt": "pwm", + "nxp_kinetis_tpm": "pwm", + "nxp_pca9685_pwm": "pwm", + "nxp_qtmr_pwm": "pwm", + "nxp_s32_emios_pwm": "pwm", + "nxp_sctimer_pwm": "pwm", + "openisa_rv32m1_tpm": "pwm", + "raspberrypi_pico_pwm": "pwm", + "realtek_rts5912_pwm": "pwm", + "renesas_pwm_rcar": "pwm", + "renesas_ra_pwm": "pwm", + "renesas_rx_mtu_pwm": "pwm", + "renesas_rz_gpt_pwm": "pwm", + "renesas_rz_mtu_pwm": "pwm", + "renesas_rza2m_gpt_pwm": "pwm", + "sifive_pwm0": "pwm", + "sifli_sf32lb_atim_pwm": "pwm", + "sifli_sf32lb_gpt_pwm": "pwm", + "silabs_gecko_pwm": "pwm", + "silabs_letimer_pwm": "pwm", + "silabs_siwx91x_pwm": "pwm", + "silabs_timer_pwm": "pwm", + "st_stm32_pwm": "pwm", + "telink_b91_pwm": "pwm", + "ti_cc13xx_cc26xx_timer_pwm": "pwm", + "ti_cc23x0_lgpt_pwm": "pwm", + "ti_mspm0_timer_pwm": "pwm", + "vnd_pwm": "pwm", + "wch_gptm_pwm": "pwm", + "xlnx_xps_timer_1_00_a_pwm": "pwm", + "zephyr_fake_pwm": "pwm", + # + # regulator + "adi_adp5360_regulator": "regulator", + "cirrus_cp9314": "regulator", + "maxim_max20335_regulator": "regulator", + "mps_mpm54304": "regulator", + "nordic_npm1100": "regulator", + "nordic_npm1300_regulator": "regulator", + "nordic_npm1304_regulator": "regulator", + "nordic_npm2100_regulator": "regulator", + "nordic_npm6001_regulator": "regulator", + "nxp_pca9420": "regulator", + "nxp_pca9422_regulator": "regulator", + "nxp_pf1550_regulator": "regulator", + "nxp_vref": "regulator", + "nxp_vrefv1": "regulator", + "raspberrypi_core_supply_regulator": "regulator", + "regulator_fixed": "regulator", + "regulator_gpio": "regulator", + "renesas_smartbond_regulator": "regulator", + "st_stm32_vrefbuf": "regulator", + "ti_tps55287": "regulator", + "zephyr_fake_regulator": "regulator", + # + # reset + "aspeed_ast10x0_reset": "reset", + "focaltech_ft9001_cpm_rctl": "reset", + "gd_gd32_rctl": "reset", + "intel_socfpga_reset": "reset", + "microchip_mpfs_reset": "reset", + "microchip_rstc_g1_reset": "reset", + "nuvoton_npcx_rst": "reset", + "nuvoton_numaker_rst": "reset", + "nxp_lpc_syscon_reset": "reset", + "nxp_mrcc_reset": "reset", + "nxp_rstctl": "reset", + "raspberrypi_pico_reset": "reset", + "realtek_rts5817_reset": "reset", + "reset_mmio": "reset", + "sifli_sf32lb_rcc_rctl": "reset", + "st_stm32_rcc_rctl": "reset", + # + # retained_mem + "nordic_nrf_gpregret": "retained_mem", + "silabs_buram": "retained_mem", + "zephyr_retained_ram": "retained_mem", + "zephyr_retained_reg": "retained_mem", + # + # rtc + "adi_max31331": "rtc", + "ambiq_am1805": "rtc", + "ambiq_rtc": "rtc", + "atmel_sam_rtc": "rtc", + "epson_rx8130ce_rtc": "rtc", + "infineon_rtc": "rtc", + "infineon_xmc4xxx_rtc": "rtc", + "maxim_ds1302": "rtc", + "maxim_ds1307": "rtc", + "maxim_ds1337": "rtc", + "maxim_ds3231_rtc": "rtc", + "microchip_rtc_g1": "rtc", + "microchip_rtc_g2": "rtc", + "microcrystal_rv3028": "rtc", + "microcrystal_rv3032": "rtc", + "microcrystal_rv8803": "rtc", + "microcrystal_rv_8263_c8": "rtc", + "motorola_mc146818": "rtc", + "nuvoton_numaker_rtc": "rtc", + "nxp_irtc": "rtc", + "nxp_pcf2123": "rtc", + "nxp_pcf85063a": "rtc", + "nxp_pcf8523": "rtc", + "nxp_pcf8563": "rtc", + "raspberrypi_pico_rtc": "rtc", + "realtek_rts5912_rtc": "rtc", + "renesas_ra_rtc": "rtc", + "renesas_smartbond_rtc": "rtc", + "sifli_sf32lb_rtc": "rtc", + "silabs_siwx91x_rtc": "rtc", + "st_stm32_rtc": "rtc", + "ti_bq32002": "rtc", + "ti_mspm0_rtc": "rtc", + "zephyr_fake_rtc": "rtc", + "zephyr_rtc_counter": "rtc", + "zephyr_rtc_emul": "rtc", + # + # sdhc + "adi_max32_sdhc": "sdhc", + "ambiq_sdio": "sdhc", + "atmel_sam_hsmci": "sdhc", + "cdns_sdhc": "sdhc", + "espressif_esp32_sdhc_slot": "sdhc", + "infineon_sdhc_sdio": "sdhc", + "intel_emmc_host": "sdhc", + "microchip_sama7g5_sdmmc": "sdhc", + "nxp_imx_usdhc": "sdhc", + "nxp_lpc_sdif": "sdhc", + "renesas_ra_sdhc": "sdhc", + "renesas_rcar_mmc": "sdhc", + "st_stm32_sdio": "sdhc", + "xlnx_versal_8_9a": "sdhc", + "zephyr_sdhc_spi_slot": "sdhc", + # + # sensor/a01nyub + "dfrobot_a01nyub": "sensor/a01nyub", + # + # sensor/adi/ad2s1210 + "adi_ad2s1210": "sensor/adi/ad2s1210", + # + # sensor/adi/ade7978 + "adi_ade7978": "sensor/adi/ade7978", + # + # sensor/adi/adltc2990 + "adi_adltc2990": "sensor/adi/adltc2990", + # + # sensor/adi/adt7310 + "adi_adt7310": "sensor/adi/adt7310", + # + # sensor/adi/adt7420 + "adi_adt7420": "sensor/adi/adt7420", + # + # sensor/adi/adxl345 + "adi_adxl345": "sensor/adi/adxl345", + # + # sensor/adi/adxl362 + "adi_adxl362": "sensor/adi/adxl362", + # + # sensor/adi/adxl367 + "adi_adxl366": "sensor/adi/adxl367", + "adi_adxl367": "sensor/adi/adxl367", + # + # sensor/adi/adxl372 + "adi_adxl372": "sensor/adi/adxl372", + # + # sensor/adi/max30210 + "adi_max30210": "sensor/adi/max30210", + # + # sensor/adi/max32664c + "maxim_max32664c": "sensor/adi/max32664c", + # + # sensor/als31300 + "allegro_als31300": "sensor/als31300", + # + # sensor/amd_sb_tsi + "amd_sb_tsi": "sensor/amd_sb_tsi", + # + # sensor/amg88xx + "panasonic_amg88xx": "sensor/amg88xx", + # + # sensor/ams/ams_as5048 + "ams_as5048": "sensor/ams/ams_as5048", + # + # sensor/ams/ams_as5600 + "ams_as5600": "sensor/ams/ams_as5600", + # + # sensor/ams/ams_iAQcore + "ams_iaqcore": "sensor/ams/ams_iAQcore", + # + # sensor/ams/ccs811 + "ams_ccs811": "sensor/ams/ccs811", + # + # sensor/ams/ens210 + "ams_ens210": "sensor/ams/ens210", + # + # sensor/ams/tcs3400 + "ams_tcs3400": "sensor/ams/tcs3400", + # + # sensor/ams/tmd2620 + "ams_tmd2620": "sensor/ams/tmd2620", + # + # sensor/ams/tsl2540 + "ams_tsl2540": "sensor/ams/tsl2540", + # + # sensor/ams/tsl2561 + "ams_tsl2561": "sensor/ams/tsl2561", + # + # sensor/ams/tsl2591 + "ams_tsl2591": "sensor/ams/tsl2591", + # + # sensor/aosong/ags10 + "aosong_ags10": "sensor/aosong/ags10", + # + # sensor/aosong/dht + "aosong_dht": "sensor/aosong/dht", + # + # sensor/aosong/dht20 + "aosong_aht20": "sensor/aosong/dht20", + "aosong_am2301b": "sensor/aosong/dht20", + "aosong_dht20": "sensor/aosong/dht20", + # + # sensor/apds9253 + "avago_apds9253": "sensor/apds9253", + # + # sensor/apds9306 + "avago_apds9306": "sensor/apds9306", + # + # sensor/apds9960 + "avago_apds9960": "sensor/apds9960", + # + # sensor/asahi_kasei/ak8975 + "asahi_kasei_ak8975": "sensor/asahi_kasei/ak8975", + # + # sensor/asahi_kasei/akm09918c + "asahi_kasei_akm09918c": "sensor/asahi_kasei/akm09918c", + # + # sensor/bosch/bma280 + "bosch_bma280": "sensor/bosch/bma280", + # + # sensor/bosch/bma4xx + "bosch_bma4xx": "sensor/bosch/bma4xx", + # + # sensor/bosch/bmc150_magn + "bosch_bmc150_magn": "sensor/bosch/bmc150_magn", + # + # sensor/bosch/bme280 + "bosch_bme280": "sensor/bosch/bme280", + # + # sensor/bosch/bme680 + "bosch_bme680": "sensor/bosch/bme680", + # + # sensor/bosch/bmg160 + "bosch_bmg160": "sensor/bosch/bmg160", + # + # sensor/bosch/bmi08x + "bosch_bmi08x_accel": "sensor/bosch/bmi08x", + "bosch_bmi08x_gyro": "sensor/bosch/bmi08x", + # + # sensor/bosch/bmi160 + "bosch_bmi160": "sensor/bosch/bmi160", + # + # sensor/bosch/bmi270 + "bosch_bmi270": "sensor/bosch/bmi270", + # + # sensor/bosch/bmi323 + "bosch_bmi323": "sensor/bosch/bmi323", + # + # sensor/bosch/bmm150 + "bosch_bmm150": "sensor/bosch/bmm150", + # + # sensor/bosch/bmm350 + "bosch_bmm350": "sensor/bosch/bmm350", + # + # sensor/bosch/bmp180 + "bosch_bmp180": "sensor/bosch/bmp180", + # + # sensor/bosch/bmp388 + "bosch_bmp388": "sensor/bosch/bmp388", + "bosch_bmp390": "sensor/bosch/bmp388", + # + # sensor/bosch/bmp581 + "bosch_bmp581": "sensor/bosch/bmp581", + # + # sensor/broadcom/afbr_s50 + "brcm_afbr_s50": "sensor/broadcom/afbr_s50", + # + # sensor/current_amp + "current_sense_amplifier": "sensor/current_amp", + # + # sensor/ene_tach_kb1200 + "ene_kb1200_tach": "sensor/ene_tach_kb1200", + # + # sensor/ens160 + "sciosense_ens160": "sensor/ens160", + # + # sensor/espressif/esp32_temp + "espressif_esp32_temp": "sensor/espressif/esp32_temp", + # + # sensor/espressif/pcnt_esp32 + "espressif_esp32_pcnt": "sensor/espressif/pcnt_esp32", + # + # sensor/everlight/als_pt19 + "everlight_als_pt19": "sensor/everlight/als_pt19", + # + # sensor/explorir_m + "gss_explorir_m": "sensor/explorir_m", + # + # sensor/f75303 + "fintek_f75303": "sensor/f75303", + # + # sensor/fcx_mldx5 + "ap_fcx_mldx5": "sensor/fcx_mldx5", + # + # sensor/grow_r502a + "hzgrow_r502a": "sensor/grow_r502a", + "hzgrow_r502a_led": "sensor/grow_r502a", + # + # sensor/hc_sr04 + "hc_sr04": "sensor/hc_sr04", + # + # sensor/honeywell/hmc5883l + "honeywell_hmc5883l": "sensor/honeywell/hmc5883l", + # + # sensor/honeywell/mpr + "honeywell_mpr": "sensor/honeywell/mpr", + # + # sensor/honeywell/sm351lt + "honeywell_sm351lt": "sensor/honeywell/sm351lt", + # + # sensor/hp206c + "hoperf_hp206c": "sensor/hp206c", + # + # sensor/infineon/dps310 + "infineon_dps310": "sensor/infineon/dps310", + # + # sensor/infineon/tle9104 + "infineon_tle9104_diagnostics": "sensor/infineon/tle9104", + # + # sensor/infineon/xmc4xxx_temp + "infineon_xmc4xxx_temp": "sensor/infineon/xmc4xxx_temp", + # + # sensor/ist8310 + "isentek_ist8310": "sensor/ist8310", + # + # sensor/ite/ite_tach_it51xxx + "ite_it51xxx_tach": "sensor/ite/ite_tach_it51xxx", + # + # sensor/ite/ite_tach_it8xxx2 + "ite_it8xxx2_tach": "sensor/ite/ite_tach_it8xxx2", + # + # sensor/ite/ite_vcmp_it8xxx2 + "ite_it8xxx2_vcmp": "sensor/ite/ite_vcmp_it8xxx2", + # + # sensor/jedec/jc42 + "jedec_jc_42_4_temp": "sensor/jedec/jc42", + # + # sensor/liteon/ltrf216a + "liteon_ltrf216a": "sensor/liteon/ltrf216a", + # + # sensor/lm35 + "lm35": "sensor/lm35", + # + # sensor/lm75 + "lm75": "sensor/lm75", + # + # sensor/lm77 + "lm77": "sensor/lm77", + # + # sensor/maxim/ds18b20 + "maxim_ds18b20": "sensor/maxim/ds18b20", + "maxim_ds18s20": "sensor/maxim/ds18b20", + # + # sensor/maxim/ds3231 + "maxim_ds3231_sensor": "sensor/maxim/ds3231", + # + # sensor/maxim/max17055 + "maxim_max17055": "sensor/maxim/max17055", + # + # sensor/maxim/max17262 + "maxim_max17262": "sensor/maxim/max17262", + # + # sensor/maxim/max30101 + "maxim_max30101": "sensor/maxim/max30101", + # + # sensor/maxim/max31790 + "maxim_max31790_fan_fault": "sensor/maxim/max31790", + "maxim_max31790_fan_speed": "sensor/maxim/max31790", + # + # sensor/maxim/max31855 + "maxim_max31855": "sensor/maxim/max31855", + # + # sensor/maxim/max31865 + "maxim_max31865": "sensor/maxim/max31865", + # + # sensor/maxim/max31875 + "maxim_max31875": "sensor/maxim/max31875", + # + # sensor/maxim/max44009 + "maxim_max44009": "sensor/maxim/max44009", + # + # sensor/maxim/max6675 + "maxim_max6675": "sensor/maxim/max6675", + # + # sensor/mb7040 + "maxbotix_mb7040": "sensor/mb7040", + # + # sensor/meas/ms5607 + "meas_ms5607": "sensor/meas/ms5607", + # + # sensor/meas/ms5837 + "meas_ms5837_02ba": "sensor/meas/ms5837", + "meas_ms5837_30ba": "sensor/meas/ms5837", + # + # sensor/melexis/mlx90394 + "melexis_mlx90394": "sensor/melexis/mlx90394", + # + # sensor/memsic/mc3419 + "memsic_mc3419": "sensor/memsic/mc3419", + # + # sensor/memsic/mmc56x3 + "memsic_mmc56x3": "sensor/memsic/mmc56x3", + # + # sensor/mhz19b + "winsen_mhz19b": "sensor/mhz19b", + # + # sensor/microchip/mchp_tach_xec + "microchip_xec_tach": "sensor/microchip/mchp_tach_xec", + # + # sensor/microchip/mcp9600 + "microchip_mcp9600": "sensor/microchip/mcp9600", + # + # sensor/microchip/mcp970x + "microchip_mcp970x": "sensor/microchip/mcp970x", + # + # sensor/microchip/mtch9010 + "microchip_mtch9010": "sensor/microchip/mtch9010", + # + # sensor/microchip/tcn75a + "microchip_tcn75a": "sensor/microchip/tcn75a", + # + # sensor/nct75 + "onnn_nct75": "sensor/nct75", + # + # sensor/nordic/npm13xx_charger + "nordic_npm1300_charger": "sensor/nordic/npm13xx_charger", + "nordic_npm1304_charger": "sensor/nordic/npm13xx_charger", + # + # sensor/nordic/npm2100_vbat + "nordic_npm2100_vbat": "sensor/nordic/npm2100_vbat", + # + # sensor/nordic/qdec_nrfx + "nordic_nrf_qdec": "sensor/nordic/qdec_nrfx", + # + # sensor/nordic/temp + "nordic_nrf_temp": "sensor/nordic/temp", + "nordic_nrf_temp_nrfs": "sensor/nordic/temp", + # + # sensor/ntc_thermistor + "epcos_b57861s0103a039": "sensor/ntc_thermistor", + "murata_ncp15wb473": "sensor/ntc_thermistor", + "murata_ncp15xh103": "sensor/ntc_thermistor", + "ntc_thermistor_generic": "sensor/ntc_thermistor", + "tdk_ntcg163jf103ft1": "sensor/ntc_thermistor", + # + # sensor/nuvoton/nuvoton_adc_cmp_npcx + "nuvoton_adc_cmp": "sensor/nuvoton/nuvoton_adc_cmp_npcx", + # + # sensor/nuvoton/nuvoton_adc_v2t_npcx + "nuvoton_npcx_adc_v2t": "sensor/nuvoton/nuvoton_adc_v2t_npcx", + # + # sensor/nuvoton/nuvoton_tach_npcx + "nuvoton_npcx_tach": "sensor/nuvoton/nuvoton_tach_npcx", + # + # sensor/nxp/fxas21002 + "nxp_fxas21002": "sensor/nxp/fxas21002", + # + # sensor/nxp/fxls8974 + "nxp_fxls8974": "sensor/nxp/fxls8974", + # + # sensor/nxp/fxos8700 + "nxp_fxos8700": "sensor/nxp/fxos8700", + # + # sensor/nxp/mcux_acmp + "nxp_kinetis_acmp": "sensor/nxp/mcux_acmp", + # + # sensor/nxp/mcux_lpcmp + "nxp_lpcmp": "sensor/nxp/mcux_lpcmp", + # + # sensor/nxp/nxp_kinetis_temp + "nxp_kinetis_temperature": "sensor/nxp/nxp_kinetis_temp", + # + # sensor/nxp/nxp_lpadc_temp40 + "nxp_lpadc_temp40": "sensor/nxp/nxp_lpadc_temp40", + # + # sensor/nxp/nxp_pmc_tmpsns + "nxp_pmc_tmpsns": "sensor/nxp/nxp_pmc_tmpsns", + # + # sensor/nxp/nxp_tempmon + "nxp_tempmon": "sensor/nxp/nxp_tempmon", + # + # sensor/nxp/nxp_tempsense + "nxp_tempsense": "sensor/nxp/nxp_tempsense", + # + # sensor/nxp/nxp_tmpsns + "nxp_tmpsns": "sensor/nxp/nxp_tmpsns", + # + # sensor/nxp/p3t1755 + "nxp_p3t1755": "sensor/nxp/p3t1755", + # + # sensor/nxp/qdec_mcux + "nxp_mcux_qdec": "sensor/nxp/qdec_mcux", + # + # sensor/nxp/qdec_nxp_s32 + "nxp_qdec_s32": "sensor/nxp/qdec_nxp_s32", + # + # sensor/nxp/qdec_tpm + "nxp_tpm_qdec": "sensor/nxp/qdec_tpm", + # + # sensor/omron/2smpb_02e + "omron_2smpb_02e": "sensor/omron/2smpb_02e", + # + # sensor/omron/d6f + "omron_d6f_p0001": "sensor/omron/d6f", + "omron_d6f_p0010": "sensor/omron/d6f", + # + # sensor/pixart/paa3905 + "pixart_paa3905": "sensor/pixart/paa3905", + # + # sensor/pixart/paj7620 + "pixart_paj7620": "sensor/pixart/paj7620", + # + # sensor/pixart/pat9136 + "pixart_pat9136": "sensor/pixart/pat9136", + # + # sensor/pms7003 + "plantower_pms7003": "sensor/pms7003", + # + # sensor/pni/rm3100 + "pni_rm3100": "sensor/pni/rm3100", + # + # sensor/pzem004t + "peacefair_pzem004t": "sensor/pzem004t", + # + # sensor/qdec_sam + "atmel_sam_tc_qdec": "sensor/qdec_sam", + # + # sensor/realtek/rts5912 + "realtek_rts5912_tach": "sensor/realtek/rts5912", + # + # sensor/renesas/hs300x + "renesas_hs300x": "sensor/renesas/hs300x", + # + # sensor/renesas/hs400x + "renesas_hs400x": "sensor/renesas/hs400x", + # + # sensor/renesas/isl29035 + "isil_isl29035": "sensor/renesas/isl29035", + # + # sensor/rohm/bd8lb600fs + "rohm_bd8lb600fs_diagnostics": "sensor/rohm/bd8lb600fs", + # + # sensor/rohm/bh1730 + "rohm_bh1730": "sensor/rohm/bh1730", + # + # sensor/rohm/bh1750 + "rohm_bh1750": "sensor/rohm/bh1750", + # + # sensor/rohm/bh1790 + "rohm_bh1790": "sensor/rohm/bh1790", + # + # sensor/rpi_pico_temp + "raspberrypi_pico_temp": "sensor/rpi_pico_temp", + # + # sensor/rv3032_temp + "microcrystal_rv3032_temp": "sensor/rv3032_temp", + # + # sensor/s11059 + "hamamatsu_s11059": "sensor/s11059", + # + # sensor/seeed/grove + "seeed_grove_light": "sensor/seeed/grove", + "seeed_grove_temperature": "sensor/seeed/grove", + # + # sensor/seeed/hm330x + "seeed_hm330x": "sensor/seeed/hm330x", + # + # sensor/sensirion/scd4x + "sensirion_scd40": "sensor/sensirion/scd4x", + "sensirion_scd41": "sensor/sensirion/scd4x", + # + # sensor/sensirion/sgp40 + "sensirion_sgp40": "sensor/sensirion/sgp40", + # + # sensor/sensirion/sht3xd + "sensirion_sht3xd": "sensor/sensirion/sht3xd", + # + # sensor/sensirion/sht4x + "sensirion_sht4x": "sensor/sensirion/sht4x", + # + # sensor/sensirion/shtcx + "sensirion_shtcx": "sensor/sensirion/shtcx", + # + # sensor/sensirion/sts4x + "sensirion_sts4x": "sensor/sensirion/sts4x", + # + # sensor/sifli/sf32lb_tsen + "sifli_sf32lb_tsen": "sensor/sifli/sf32lb_tsen", + # + # sensor/silabs/si7006 + "sensirion_sht21": "sensor/silabs/si7006", + "silabs_si7006": "sensor/silabs/si7006", + # + # sensor/silabs/si7055 + "silabs_si7055": "sensor/silabs/si7055", + # + # sensor/silabs/si7060 + "silabs_si7060": "sensor/silabs/si7060", + # + # sensor/silabs/si7210 + "silabs_si7210": "sensor/silabs/si7210", + # + # sensor/st/hts221 + "st_hts221": "sensor/st/hts221", + # + # sensor/st/i3g4250d + "st_i3g4250d": "sensor/st/i3g4250d", + # + # sensor/st/iis2dh + "st_iis2dh": "sensor/st/iis2dh", + # + # sensor/st/iis2dlpc + "st_iis2dlpc": "sensor/st/iis2dlpc", + # + # sensor/st/iis2iclx + "st_iis2iclx": "sensor/st/iis2iclx", + # + # sensor/st/iis2mdc + "st_iis2mdc": "sensor/st/iis2mdc", + # + # sensor/st/iis328dq + "st_iis328dq": "sensor/st/iis328dq", + # + # sensor/st/iis3dhhc + "st_iis3dhhc": "sensor/st/iis3dhhc", + # + # sensor/st/iis3dwb + "st_iis3dwb": "sensor/st/iis3dwb", + # + # sensor/st/ism330dhcx + "st_ism330dhcx": "sensor/st/ism330dhcx", + # + # sensor/st/lis2de12 + "st_lis2de12": "sensor/st/lis2de12", + # + # sensor/st/lis2dh + "st_lis2dh": "sensor/st/lis2dh", + # + # sensor/st/lis2ds12 + "st_lis2ds12": "sensor/st/lis2ds12", + # + # sensor/st/lis2du12 + "st_lis2du12": "sensor/st/lis2du12", + # + # sensor/st/lis2dux12 + "st_lis2dux12": "sensor/st/lis2dux12", + "st_lis2duxs12": "sensor/st/lis2dux12", + # + # sensor/st/lis2dw12 + "st_lis2dw12": "sensor/st/lis2dw12", + # + # sensor/st/lis2mdl + "st_lis2mdl": "sensor/st/lis2mdl", + # + # sensor/st/lis3mdl + "st_lis3mdl_magn": "sensor/st/lis3mdl", + # + # sensor/st/lps22hb + "st_lps22hb_press": "sensor/st/lps22hb", + # + # sensor/st/lps22hh + "st_lps22hh": "sensor/st/lps22hh", + # + # sensor/st/lps25hb + "st_lps25hb_press": "sensor/st/lps25hb", + # + # sensor/st/lps2xdf + "st_ilps22qs": "sensor/st/lps2xdf", + "st_lps22df": "sensor/st/lps2xdf", + "st_lps28dfw": "sensor/st/lps2xdf", + # + # sensor/st/lsm303dlhc_magn + "st_lsm303dlhc_magn": "sensor/st/lsm303dlhc_magn", + # + # sensor/st/lsm6ds0 + "st_lsm6ds0": "sensor/st/lsm6ds0", + # + # sensor/st/lsm6dsl + "st_lsm6dsl": "sensor/st/lsm6dsl", + # + # sensor/st/lsm6dso + "st_lsm6dso": "sensor/st/lsm6dso", + "st_lsm6dso32": "sensor/st/lsm6dso", + # + # sensor/st/lsm6dso16is + "st_lsm6dso16is": "sensor/st/lsm6dso16is", + # + # sensor/st/lsm6dsv16x + "DT_DRV_COMPAT_LSM6DSV16X": "sensor/st/lsm6dsv16x", + "DT_DRV_COMPAT_LSM6DSV32X": "sensor/st/lsm6dsv16x", + "st_lsm6dsv16x": "sensor/st/lsm6dsv16x", + "st_lsm6dsv32x": "sensor/st/lsm6dsv16x", + # + # sensor/st/lsm6dsvxxx + "st_ism6hg256x": "sensor/st/lsm6dsvxxx", + "st_lsm6dsv320x": "sensor/st/lsm6dsvxxx", + "st_lsm6dsv80x": "sensor/st/lsm6dsvxxx", + "st_lsm6dsvxxx": "sensor/st/lsm6dsvxxx", + # + # sensor/st/lsm9ds0_gyro + "st_lsm9ds0_gyro": "sensor/st/lsm9ds0_gyro", + # + # sensor/st/lsm9ds0_mfd + "st_lsm9ds0_mfd": "sensor/st/lsm9ds0_mfd", + # + # sensor/st/lsm9ds1 + "st_lsm9ds1": "sensor/st/lsm9ds1", + # + # sensor/st/lsm9ds1_mag + "st_lsm9ds1_mag": "sensor/st/lsm9ds1_mag", + # + # sensor/st/qdec_stm32 + "st_stm32_qdec": "sensor/st/qdec_stm32", + # + # sensor/st/stm32_digi_temp + "st_stm32_digi_temp": "sensor/st/stm32_digi_temp", + # + # sensor/st/stm32_temp + "st_stm32_temp": "sensor/st/stm32_temp", + "st_stm32_temp_cal": "sensor/st/stm32_temp", + "st_stm32c0_temp_cal": "sensor/st/stm32_temp", + # + # sensor/st/stm32_vbat + "st_stm32_vbat": "sensor/st/stm32_vbat", + # + # sensor/st/stm32_vref + "st_stm32_vref": "sensor/st/stm32_vref", + # + # sensor/st/stts22h + "st_stts22h": "sensor/st/stts22h", + # + # sensor/st/stts751 + "st_stts751": "sensor/st/stts751", + # + # sensor/st/vl53l0x + "st_vl53l0x": "sensor/st/vl53l0x", + # + # sensor/st/vl53l1x + "st_vl53l1x": "sensor/st/vl53l1x", + # + # sensor/sx9500 + "semtech_sx9500": "sensor/sx9500", + # + # sensor/tach_gpio + "zephyr_tach_gpio": "sensor/tach_gpio", + # + # sensor/tdk/icm40627 + "invensense_icm40627": "sensor/tdk/icm40627", + # + # sensor/tdk/icm42605 + "invensense_icm42605": "sensor/tdk/icm42605", + # + # sensor/tdk/icm4268x + "invensense_icm42688": "sensor/tdk/icm4268x", + "invensense_icm4268x": "sensor/tdk/icm4268x", + # + # sensor/tdk/icm42x70 + "invensense_icm42370p": "sensor/tdk/icm42x70", + "invensense_icm42670p": "sensor/tdk/icm42x70", + "invensense_icm42670s": "sensor/tdk/icm42x70", + # + # sensor/tdk/icm45686 + "invensense_icm45605": "sensor/tdk/icm45686", + "invensense_icm45605s": "sensor/tdk/icm45686", + "invensense_icm45686": "sensor/tdk/icm45686", + "invensense_icm45686s": "sensor/tdk/icm45686", + "invensense_icm45688p": "sensor/tdk/icm45686", + # + # sensor/tdk/icp101xx + "invensense_icp101xx": "sensor/tdk/icp101xx", + # + # sensor/tdk/icp201xx + "invensense_icp201xx": "sensor/tdk/icp201xx", + # + # sensor/tdk/mpu6050 + "invensense_mpu6050": "sensor/tdk/mpu6050", + # + # sensor/tdk/mpu9250 + "invensense_mpu9250": "sensor/tdk/mpu9250", + # + # sensor/th02 + "hoperf_th02": "sensor/th02", + # + # sensor/ti/bq274xx + "ti_bq274xx": "sensor/ti/bq274xx", + # + # sensor/ti/fdc2x1x + "ti_fdc2x1x": "sensor/ti/fdc2x1x", + # + # sensor/ti/ina219 + "ti_ina219": "sensor/ti/ina219", + # + # sensor/ti/ina2xx + "ti_ina226": "sensor/ti/ina2xx", + "ti_ina228": "sensor/ti/ina2xx", + "ti_ina230": "sensor/ti/ina2xx", + "ti_ina232": "sensor/ti/ina2xx", + "ti_ina236": "sensor/ti/ina2xx", + "ti_ina237": "sensor/ti/ina2xx", + # + # sensor/ti/ina3221 + "ti_ina3221": "sensor/ti/ina3221", + # + # sensor/ti/ina7xx + "ti_ina7xx": "sensor/ti/ina7xx", + # + # sensor/ti/lm95234 + "national_lm95234": "sensor/ti/lm95234", + # + # sensor/ti/opt300x + "ti_opt3001": "sensor/ti/opt300x", + "ti_opt3004": "sensor/ti/opt300x", + "ti_opt300x": "sensor/ti/opt300x", + # + # sensor/ti/ti_hdc + "ti_hdc": "sensor/ti/ti_hdc", + # + # sensor/ti/ti_hdc302x + "ti_hdc302x": "sensor/ti/ti_hdc302x", + # + # sensor/ti/tmag5170 + "ti_tmag5170": "sensor/ti/tmag5170", + # + # sensor/ti/tmp007 + "ti_tmp007": "sensor/ti/tmp007", + # + # sensor/ti/tmp1075 + "ti_tmp1075": "sensor/ti/tmp1075", + # + # sensor/ti/tmp108 + "ams_as6212": "sensor/ti/tmp108", + "ams_as6221": "sensor/ti/tmp108", + "ti_tmp108": "sensor/ti/tmp108", + # + # sensor/ti/tmp112 + "ti_tmp112": "sensor/ti/tmp112", + # + # sensor/ti/tmp114 + "ti_tmp114": "sensor/ti/tmp114", + # + # sensor/ti/tmp11x + "ti_tmp11x": "sensor/ti/tmp11x", + # + # sensor/ti/tmp435 + "ti_tmp435": "sensor/ti/tmp435", + # + # sensor/tsic_xx6 + "ist_tsic_xx6": "sensor/tsic_xx6", + # + # sensor/veaa_x_3 + "festo_veaa_x_3": "sensor/veaa_x_3", + # + # sensor/vishay/vcnl36825t + "vishay_vcnl36825t": "sensor/vishay/vcnl36825t", + # + # sensor/vishay/vcnl4040 + "vishay_vcnl4040": "sensor/vishay/vcnl4040", + # + # sensor/vishay/veml6031 + "vishay_veml6031": "sensor/vishay/veml6031", + # + # sensor/vishay/veml6046 + "vishay_veml6046": "sensor/vishay/veml6046", + # + # sensor/vishay/veml7700 + "vishay_veml7700": "sensor/vishay/veml7700", + # + # sensor/voltage_divider + "voltage_divider": "sensor/voltage_divider", + # + # sensor/wsen/wsen_hids_2525020210002 + "we_wsen_hids_2525020210002": "sensor/wsen/wsen_hids_2525020210002", + # + # sensor/wsen/wsen_isds_2536030320001 + "we_wsen_isds_2536030320001": "sensor/wsen/wsen_isds_2536030320001", + # + # sensor/wsen/wsen_itds_2533020201601 + "we_wsen_itds_2533020201601": "sensor/wsen/wsen_itds_2533020201601", + # + # sensor/wsen/wsen_pads_2511020213301 + "we_wsen_pads_2511020213301": "sensor/wsen/wsen_pads_2511020213301", + # + # sensor/wsen/wsen_pdms_25131308XXX05 + "we_wsen_pdms_25131308xxx05": "sensor/wsen/wsen_pdms_25131308XXX05", + # + # sensor/wsen/wsen_pdus_25131308XXXXX + "we_wsen_pdus_25131308xxxxx": "sensor/wsen/wsen_pdus_25131308XXXXX", + # + # sensor/wsen/wsen_tids_2521020222501 + "we_wsen_tids_2521020222501": "sensor/wsen/wsen_tids_2521020222501", + # + # sensor/xbr818 + "phosense_xbr818": "sensor/xbr818", + # + # sent + "nxp_s32_sent": "sent", + # + # serial + "SBSA_COMPAT": "serial", + "adi_max32_uart": "serial", + "aesc_uart": "serial", + "altr_jtag_uart": "serial", + "altr_uart": "serial", + "ambiq_uart": "serial", + "arm_cmsdk_uart": "serial", + "arm_pl011": "serial", + "atmel_sam0_uart": "serial", + "atmel_sam_uart": "serial", + "atmel_sam_usart": "serial", + "bflb_uart": "serial", + "brcm_bcm2711_aux_uart": "serial", + "cdns_uart": "serial", + "cypress_psoc6_uart": "serial", + "efinix_sapphire_uart0": "serial", + "ene_kb106x_uart": "serial", + "ene_kb1200_uart": "serial", + "espressif_esp32_lpuart": "serial", + "espressif_esp32_uart": "serial", + "espressif_esp32_usb_serial": "serial", + "focaltech_ft9001_usart": "serial", + "gaisler_apbuart": "serial", + "gd_gd32_usart": "serial", + "infineon_uart": "serial", + "infineon_xmc4xxx_uart": "serial", + "intel_lw_uart": "serial", + "intel_sedi_uart": "serial", + "ite_it51xxx_uart": "serial", + "ite_it8xxx2_uart": "serial", + "litex_uart": "serial", + "lowrisc_opentitan_uart": "serial", + "microchip_coreuart": "serial", + "microchip_sercom_g1_uart": "serial", + "microchip_xec_uart": "serial", + "neorv32_uart": "serial", + "nordic_nrf_uart": "serial", + "ns16550": "serial", + "nuvoton_npcx_uart": "serial", + "nuvoton_numaker_uart": "serial", + "nuvoton_numicro_uart": "serial", + "nxp_imx_iuart": "serial", + "nxp_imx_uart": "serial", + "nxp_kinetis_lpsci": "serial", + "nxp_kinetis_uart": "serial", + "nxp_lpc11u6x_uart": "serial", + "nxp_lpc_usart": "serial", + "nxp_lpuart": "serial", + "nxp_s32_linflexd": "serial", + "openisa_rv32m1_lpuart": "serial", + "quicklogic_usbserialport_s3b": "serial", + "raspberrypi_pico_uart_pio": "serial", + "realtek_ameba_loguart": "serial", + "realtek_bee_uart": "serial", + "realtek_rts5912_uart": "serial", + "renesas_ra8_uart_sci_b": "serial", + "renesas_ra_sci_uart": "serial", + "renesas_rcar_hscif": "serial", + "renesas_rcar_scif": "serial", + "renesas_rx_uart_sci": "serial", + "renesas_rx_uart_sci_qemu": "serial", + "renesas_rz_sci_b_uart": "serial", + "renesas_rz_sci_uart": "serial", + "renesas_rz_scif_uart": "serial", + "renesas_rza2m_scif_uart": "serial", + "renesas_rzt2m_uart": "serial", + "renesas_smartbond_uart": "serial", + "segger_rtt_uart": "serial", + "sensry_sy1xx_uart": "serial", + "sifive_uart0": "serial", + "sifli_sf32lb_usart": "serial", + "silabs_eusart_uart": "serial", + "silabs_gecko_leuart": "serial", + "silabs_gecko_uart": "serial", + "silabs_gecko_usart": "serial", + "silabs_si32_usart": "serial", + "silabs_usart_uart": "serial", + "snps_hostlink_uart": "serial", + "st_stm32_uart": "serial", + "telink_b91_uart": "serial", + "ti_cc13xx_cc26xx_uart": "serial", + "ti_cc23x0_uart": "serial", + "ti_cc32xx_uart": "serial", + "ti_msp432p4xx_uart": "serial", + "ti_mspm0_uart": "serial", + "ti_stellaris_uart": "serial", + "virtio_console": "serial", + "vnd_serial": "serial", + "wch_usart": "serial", + "xen_hvc_consoleio": "serial", + "xlnx_xps_uartlite_1_00_a": "serial", + "xlnx_xuartps": "serial", + "zephyr_native_pty_uart": "serial", + "zephyr_native_tty_uart": "serial", + "zephyr_nus_uart": "serial", + "zephyr_uart_bitbang": "serial", + "zephyr_uart_bridge": "serial", + "zephyr_uart_emul": "serial", + # + # sip_svc + "intel_socfpga_agilex_sip_smc": "sip_svc", + # + # smbus + "intel_pch_smbus": "smbus", + "st_stm32_smbus": "smbus", + # + # spi + "adi_max32_spi": "spi", + "ambiq_spi": "spi", + "ambiq_spi_bleif": "spi", + "ambiq_spid": "spi", + "andestech_atcspi200": "spi", + "arm_pl022": "spi", + "atmel_sam0_spi": "spi", + "atmel_sam_spi": "spi", + "bflb_spi": "spi", + "cdns_spi": "spi", + "cypress_psoc6_spi": "spi", + "egis_et171_spi": "spi", + "espressif_esp32_spi": "spi", + "gaisler_spimctrl": "spi", + "gd_gd32_spi": "spi", + "infineon_spi": "spi", + "infineon_xmc4xxx_spi": "spi", + "intel_penwell_spi": "spi", + "intel_sedi_spi": "spi", + "ite_it51xxx_spi": "spi", + "ite_it8xxx2_spi": "spi", + "litex_spi": "spi", + "litex_spi_litespi": "spi", + "lowrisc_opentitan_spi": "spi", + "microchip_mpfs_qspi": "spi", + "microchip_mpfs_spi": "spi", + "microchip_sercom_g1_spi": "spi", + "microchip_xec_qmspi": "spi", + "microchip_xec_qmspi_ldma": "spi", + "nordic_nrf_spi": "spi", + "nordic_nrf_spim": "spi", + "nuvoton_npcx_spip": "spi", + "nuvoton_numaker_spi": "spi", + "nxp_dspi": "spi", + "nxp_flexio_spi": "spi", + "nxp_imx_ecspi": "spi", + "nxp_lpc_spi": "spi", + "nxp_s32_spi": "spi", + "nxp_sc18is606_spi": "spi", + "opencores_spi_simple": "spi", + "openisa_rv32m1_lpspi": "spi", + "raspberrypi_pico_spi_pio": "spi", + "realtek_rts5912_spi": "spi", + "renesas_ra8_spi_b": "spi", + "renesas_ra_spi": "spi", + "renesas_ra_spi_sci": "spi", + "renesas_ra_spi_sci_b": "spi", + "renesas_rx_rspi": "spi", + "renesas_rz_rspi": "spi", + "renesas_rz_spi": "spi", + "renesas_smartbond_spi": "spi", + "sensry_sy1xx_spi": "spi", + "sifive_spi0": "spi", + "sifli_sf32lb_spi": "spi", + "silabs_eusart_spi": "spi", + "silabs_gspi": "spi", + "silabs_usart_spi": "spi", + "snps_designware_spi": "spi", + "st_stm32_spi": "spi", + "telink_b91_spi": "spi", + "ti_cc13xx_cc26xx_spi": "spi", + "ti_cc23x0_spi": "spi", + "ti_omap_mcspi": "spi", + "vnd_spi": "spi", + "wch_spi": "spi", + "xlnx_xps_spi_2_00_a": "spi", + "zephyr_spi_bitbang": "spi", + "zephyr_spi_emul_controller": "spi", + # + # spi/spi_nxp_lpspi + "nxp_lpspi": "spi/spi_nxp_lpspi", + # + # stepper + "zephyr_fake_stepper_ctrl": "stepper", + "zephyr_fake_stepper_driver": "stepper", + # + # stepper/adi_tmc/tmc22xx + "adi_tmc2209": "stepper/adi_tmc/tmc22xx", + # + # stepper/adi_tmc/tmc50xx + "adi_tmc50xx": "stepper/adi_tmc/tmc50xx", + "adi_tmc50xx_stepper_ctrl": "stepper/adi_tmc/tmc50xx", + "adi_tmc50xx_stepper_driver": "stepper/adi_tmc/tmc50xx", + # + # stepper/adi_tmc/tmc51xx + "adi_tmc51xx": "stepper/adi_tmc/tmc51xx", + "adi_tmc51xx_stepper_ctrl": "stepper/adi_tmc/tmc51xx", + "adi_tmc51xx_stepper_driver": "stepper/adi_tmc/tmc51xx", + # + # stepper/allegro + "allegro_a4979": "stepper/allegro", + # + # stepper/gpio_stepper + "zephyr_gpio_step_dir_stepper_ctrl": "stepper/gpio_stepper", + "zephyr_h_bridge_stepper_ctrl": "stepper/gpio_stepper", + # + # stepper/ti + "ti_drv84xx": "stepper/ti", + # + # syscon + "bflb_efuse": "syscon", + "syscon": "syscon", + # + # tee/optee + "linaro_optee_tz": "tee/optee", + # + # timer + "adi_max32_rv32_sys_timer": "timer", + "ambiq_stimer": "timer", + "atmel_sam0_rtc": "timer", + "gaisler_gptimer": "timer", + "infineon_lp_timer": "timer", + "intel_adsp_timer": "timer", + "intel_hpet": "timer", + "ite_it51xxx_timer": "timer", + "ite_it8xxx2_timer": "timer", + "litex_timer0": "timer", + "microchip_sam_pit64b": "timer", + "microchip_xec_rtos_timer": "timer", + "nuvoton_npcx_itim_timer": "timer", + "nxp_gpt_hw_timer": "timer", + "nxp_lptmr": "timer", + "nxp_os_timer": "timer", + "openisa_rv32m1_lptmr": "timer", + "realtek_rts5912_rtmr": "timer", + "renesas_ra_ulpt_timer": "timer", + "renesas_rcar_cmt": "timer", + "renesas_rx_timer_cmt": "timer", + "renesas_rz_gtm_os_timer": "timer", + "renesas_rza2m_ostm": "timer", + "riscv_machine_timer": "timer", + "silabs_gecko_burtc": "timer", + "st_stm32_lptim": "timer", + "sy1xx_sys_timer": "timer", + "ti_am654_timer": "timer", + "ti_cc13xx_cc26xx_rtc_timer": "timer", + "ti_cc23x0_rtc_timer": "timer", + "ti_cc23x0_systim_timer": "timer", + "wch_systick": "timer", + "xlnx_ttcps": "timer", + # + # usb/bc12 + "diodes_pi3usb9201": "usb/bc12", + # + # usb/common/stm32 + "*/": "usb/common/stm32", + "st_stm32u5_otghs_phy": "usb/common/stm32", + # + # usb/device + "atmel_sam_usbc": "usb/device", + "atmel_sam_usbhs": "usb/device", + # + # usb/udc + "adi_max32_usbhs": "usb/udc", + "ambiq_usb": "usb/udc", + "atmel_sam0_usb": "usb/udc", + "ite_it82xx2_usb": "usb/udc", + "nordic_nrf_usbd": "usb/udc", + "nuvoton_numaker_hsusbd": "usb/udc", + "nuvoton_numaker_usbd": "usb/udc", + "nxp_ehci": "usb/udc", + "nxp_kinetis_usbd": "usb/udc", + "nxp_lpcip3511": "usb/udc", + "raspberrypi_pico_usbd": "usb/udc", + "renesas_ra_udc": "usb/udc", + "renesas_smartbond_usbd": "usb/udc", + "snps_dwc2": "usb/udc", + "st_stm32_otgfs": "usb/udc", + "st_stm32_otghs": "usb/udc", + "st_stm32_usb": "usb/udc", + "zephyr_udc_skeleton": "usb/udc", + "zephyr_udc_virtual": "usb/udc", + # + # usb/uhc + "maxim_max3421e_spi": "usb/uhc", + "nxp_uhc_ehci": "usb/uhc", + "nxp_uhc_ip3516hs": "usb/uhc", + "nxp_uhc_khci": "usb/uhc", + "nxp_uhc_ohci": "usb/uhc", + "zephyr_uhc_virtual": "usb/uhc", + # + # usb_c/ppc + "nuvoton_numaker_ppc": "usb_c/ppc", + "nxp_nx20p3483": "usb_c/ppc", + # + # usb_c/tcpc + "nuvoton_numaker_tcpc": "usb_c/tcpc", + "onnn_fusb307_tcpc": "usb_c/tcpc", + "parade_ps8xxx": "usb_c/tcpc", + "richtek_rt1715": "usb_c/tcpc", + "st_stm32_ucpd": "usb_c/tcpc", + # + # usb_c/vbus + "nuvoton_numaker_vbus": "usb_c/vbus", + "zephyr_usb_c_vbus_adc": "usb_c/vbus", + "zephyr_usb_c_vbus_tcpci": "usb_c/vbus", + # + # video + "aptina_mt9m114": "video", + "espressif_esp32_lcd_cam_dvp": "video", + "galaxycore_gc2145": "video", + "himax_hm01b0": "video", + "himax_hm0360": "video", + "nxp_imx_csi": "video", + "nxp_mipi_csi2rx": "video", + "nxp_video_smartdma": "video", + "ovti_ov2640": "video", + "ovti_ov5640": "video", + "ovti_ov5642": "video", + "ovti_ov7670": "video", + "ovti_ov7675": "video", + "ovti_ov7725": "video", + "ovti_ov9655": "video", + "renesas_ra_ceu": "video", + "sony_imx335": "video", + "st_mipid02": "video", + "st_stm32_dcmi": "video", + "st_stm32_dcmipp": "video", + "st_stm32_jpeg": "video", + "st_stm32_venc": "video", + "zephyr_video_emul_imager": "video", + "zephyr_video_emul_rx": "video", + "zephyr_video_sw_generator": "video", + # + # virtio + "virtio_mmio": "virtio", + "virtio_pci": "virtio", + # + # virtualization + "qemu_ivshmem": "virtualization", + # + # w1 + "adi_max32_w1": "w1", + "maxim_ds2482_800": "w1", + "maxim_ds2482_800_channel": "w1", + "maxim_ds2484": "w1", + "maxim_ds2485": "w1", + "vnd_w1": "w1", + "zephyr_w1_gpio": "w1", + "zephyr_w1_serial": "w1", + # + # watchdog + "adi_max32_watchdog": "watchdog", + "adi_max42500_watchdog": "watchdog", + "ambiq_watchdog": "watchdog", + "andestech_atcwdt200": "watchdog", + "arm_cmsdk_watchdog": "watchdog", + "atmel_sam0_watchdog": "watchdog", + "atmel_sam4l_watchdog": "watchdog", + "atmel_sam_watchdog": "watchdog", + "bflb_wdt": "watchdog", + "ene_kb106x_watchdog": "watchdog", + "ene_kb1200_watchdog": "watchdog", + "espressif_esp32_watchdog": "watchdog", + "espressif_esp32_xt_wdt": "watchdog", + "gd_gd32_fwdgt": "watchdog", + "gd_gd32_wwdgt": "watchdog", + "infineon_watchdog": "watchdog", + "infineon_xmc4xxx_watchdog": "watchdog", + "intel_adsp_watchdog": "watchdog", + "intel_tco_wdt": "watchdog", + "ite_it51xxx_watchdog": "watchdog", + "ite_it8xxx2_watchdog": "watchdog", + "litex_watchdog": "watchdog", + "lowrisc_opentitan_aontimer": "watchdog", + "microchip_wdt_g1": "watchdog", + "microchip_xec_watchdog": "watchdog", + "nordic_npm1300_wdt": "watchdog", + "nordic_npm1304_wdt": "watchdog", + "nordic_npm2100_wdt": "watchdog", + "nordic_npm6001_wdt": "watchdog", + "nordic_nrf_wdt": "watchdog", + "nuvoton_npcx_watchdog": "watchdog", + "nuvoton_numaker_wwdt": "watchdog", + "nxp_cop": "watchdog", + "nxp_ewm": "watchdog", + "nxp_fs26_wdog": "watchdog", + "nxp_imx_wdog": "watchdog", + "nxp_kinetis_wdog": "watchdog", + "nxp_lpc_wwdt": "watchdog", + "nxp_rtwdog": "watchdog", + "nxp_s32_swt": "watchdog", + "nxp_wdog32": "watchdog", + "raspberrypi_pico_watchdog": "watchdog", + "realtek_rts5817_watchdog": "watchdog", + "realtek_rts5912_watchdog": "watchdog", + "renesas_rx_iwdt": "watchdog", + "renesas_rz_wdt": "watchdog", + "renesas_smartbond_watchdog": "watchdog", + "sifive_wdt": "watchdog", + "sifli_sf32lb_wdt": "watchdog", + "silabs_gecko_wdog": "watchdog", + "silabs_siwx91x_wdt": "watchdog", + "snps_designware_watchdog": "watchdog", + "st_stm32_watchdog": "watchdog", + "st_stm32_window_watchdog": "watchdog", + "ti_cc13xx_cc26xx_watchdog": "watchdog", + "ti_cc23x0_wdt": "watchdog", + "ti_cc32xx_watchdog": "watchdog", + "ti_j7_rti_wdt": "watchdog", + "ti_tps382x": "watchdog", + "wch_iwdg": "watchdog", + "xlnx_versal_wwdt": "watchdog", + "xlnx_xps_timebase_wdt_1_00_a": "watchdog", + # + # wifi/esp32/src + "espressif_esp32_wifi": "wifi/esp32/src", + # + # wifi/esp_at + "espressif_esp_at": "wifi/esp_at", + # + # wifi/esp_hosted + "espressif_esp_hosted": "wifi/esp_hosted", + # + # wifi/eswifi + "inventek_eswifi": "wifi/eswifi", + "inventek_eswifi_uart": "wifi/eswifi", + # + # wifi/infineon + "infineon_airoc_wifi": "wifi/infineon", + # + # wifi/nrf_wifi/off_raw_tx/src + "nordic_wlan": "wifi/nrf_wifi/off_raw_tx/src", + # + # wifi/nxp + "nxp_wifi": "wifi/nxp", + # + # wifi/siwx91x + "silabs_siwx91x_wifi": "wifi/siwx91x", + # + # wifi/winc1500 + "atmel_winc1500": "wifi/winc1500", +} diff --git a/ports/zephyr-cp/cptools/cpbuild.py b/ports/zephyr-cp/cptools/cpbuild.py new file mode 100644 index 00000000000..edaf020c264 --- /dev/null +++ b/ports/zephyr-cp/cptools/cpbuild.py @@ -0,0 +1,428 @@ +import asyncio +import atexit +import hashlib +import json +import logging +import os +import pathlib +import re +import tempfile +import time +from typing import Optional + +logger = logging.getLogger(__name__) + +shared_semaphore = None + +trace_entries = [] +LAST_BUILD_TIMES = {} +ALREADY_RUN = {} +_last_build_times = pathlib.Path("last_build_times.json") +if _last_build_times.exists(): + with open(_last_build_times) as f: + LAST_BUILD_TIMES = json.load(f) + logger.info("Build times loaded.") +else: + logger.warning( + "No last build times found. This is normal if you're running this for the first time." + ) + + +def save_trace(): + with open("trace.json", "w") as f: + json.dump(trace_entries, f) + with open("last_build_times.json", "w") as f: + json.dump(LAST_BUILD_TIMES, f) + logger.info("wrote trace %s", pathlib.Path(".").absolute() / "trace.json") + logger.info("wrote build times %s", pathlib.Path(".").absolute() / "last_build_times.json") + + +atexit.register(save_trace) + + +class _TokenProtocol(asyncio.Protocol): + def __init__(self, client): + self.client = client + + def data_received(self, data): + # Data can be multiple tokens at once. + for i, _ in enumerate(data): + self.client.new_token(data[i : i + 1]) + + +class _MakeJobClient: + def __init__(self, fifo_path=None, read_fd=None, write_fd=None): + self.fifo_path = fifo_path + if fifo_path is not None: + self.writer = open(fifo_path, "wb") + self.reader = open(fifo_path, "rb") + self.tokens_in_use = [] + self.pending_futures = [] + + self.read_transport: asyncio.ReadTransport | None = None + self.read_protocol = None + + self.started = None + + def new_token(self, token): + # Keep a token and reuse it. Ignore cancelled Futures. + if self.pending_futures: + future = self.pending_futures.pop(0) + while future.cancelled() and self.pending_futures: + future = self.pending_futures.pop(0) + if not future.cancelled(): + future.set_result(token) + return + self.read_transport.pause_reading() + self.writer.write(token) + self.writer.flush() + + async def __aenter__(self): + loop = asyncio.get_event_loop() + if self.started is None: + self.started = asyncio.Event() + self.read_transport, self.read_protocol = await loop.connect_read_pipe( + lambda: _TokenProtocol(self), self.reader + ) + self.started.set() + await self.started.wait() + future = loop.create_future() + self.pending_futures.append(future) + self.read_transport.resume_reading() + self.tokens_in_use.append(await future) + + async def __aexit__(self, exc_type, exc, tb): + token = self.tokens_in_use.pop() + self.new_token(token) + + +def _create_semaphore(): + match = re.search(r"fifo:([^\s]+)", os.environ.get("MAKEFLAGS", "")) + fifo_path = None + if match: + fifo_path = match.group(1) + return _MakeJobClient(fifo_path=fifo_path) + return asyncio.BoundedSemaphore(1) + + +shared_semaphore = _create_semaphore() +tracks = [] +max_track = 0 + + +async def run_command( + command, + working_directory, + description=None, + check_hash=[], + extradeps=[], + responsefile: Optional[pathlib.Path] = None, +): + """ + Runs a command asynchronously. The command should ideally be a list of strings + and pathlib.Path objects. If all of the paths haven't been modified since the last + time the command was run, then it'll be skipped. (The last time a command was run + is stored based on the hash of the command.) + + The command is run from the working_directory and the paths are made relative to it. + + Description is used for logging only. If None, the command itself is logged. + + Paths in check_hash are hashed before and after the command. If the hash is + the same, then the old mtimes are reset. This is helpful if a command may produce + the same result and you don't want the rest of the build impacted + + responsefile is used to store the command line arguments if they are too long for the OS. + The arguments will be replaced with @ and tried again. + If None, commands that are too long will fail. + """ + paths = [] + responsefile_contents = None + if isinstance(command, list): + for i, part in enumerate(command): + if isinstance(part, pathlib.Path): + paths.append(part) + part = part.relative_to(working_directory, walk_up=True) + + command[i] = str(part) + command_string = " ".join(command) + + # When on windows, use a responsefile if the command string is >= 8192 + if responsefile is not None and os.name == "nt" and len(command_string) >= 8192: + # Escape backslashes + responsefile_contents = "\n".join(part.replace("\\", "\\\\") for part in command[1:]) + responsefile.write_text(responsefile_contents) + command_string = f"{command[0]} -v @{responsefile}" + else: + command_string = command + + command_hash = hashlib.sha3_256(command_string.encode("utf-8")) + command_hash.update(str(working_directory).encode("utf-8")) + command_hash = command_hash.hexdigest() + + # If a command is run multiple times, then wait for the first one to continue. Don't run it again. + if command_hash in ALREADY_RUN: + logger.debug(f"Already running {command_hash} {command_string}") + await ALREADY_RUN[command_hash].wait() + return + ALREADY_RUN[command_hash] = asyncio.Event() + + run_reason = None + # If the path inputs are all older than the last time we ran them, then we don't have anything to do. + if command_hash in LAST_BUILD_TIMES and all((p.exists() for p in paths)): + last_build_time = LAST_BUILD_TIMES[command_hash] + # Check all paths in the command because one must be modified by the command. + newest_file = max((0 if p.is_dir() else p.stat().st_mtime_ns for p in paths)) + nothing_newer = newest_file <= last_build_time + logger.debug(f"Last build time {last_build_time} Newest file {newest_file}") + if nothing_newer: + # Escape early if an extra dep is newer. + for p in extradeps: + if p.stat().st_mtime_ns > last_build_time: + run_reason = f"{p.relative_to(working_directory, walk_up=True)} is newer" + nothing_newer = False + break + else: + for p in paths: + if p.stat().st_mtime_ns == newest_file: + run_reason = f"{p.relative_to(working_directory, walk_up=True)} is newer" + break + if nothing_newer: + logger.debug(f"Nothing newer {command_string[-32:]}") + ALREADY_RUN[command_hash].set() + return + else: + run_reason = "no previous build time" + newest_file = 0 + + file_hashes = {} + for path in check_hash: + if not path.exists(): + continue + with path.open("rb") as f: + digest = hashlib.file_digest(f, "sha256") + stat = path.stat() + mtimes = (stat.st_atime, stat.st_mtime) + mtimes_ns = (stat.st_atime_ns, stat.st_mtime_ns) + file_hashes[path] = (digest, mtimes, mtimes_ns) + + cancellation = None + async with shared_semaphore: + global max_track + if not tracks: + max_track += 1 + tracks.append(max_track) + track = tracks.pop() + start_time = time.perf_counter_ns() // 1000 + process = await asyncio.create_subprocess_shell( + command_string, + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.PIPE, + cwd=working_directory, + ) + + try: + stdout, stderr = await process.communicate() + except asyncio.CancelledError as e: + cancellation = e + stdout, stderr = await process.communicate() + end_time = time.perf_counter_ns() // 1000 + trace_entries.append( + { + "name": command if not description else description, + "ph": "X", + "pid": 0, + "tid": track, + "ts": start_time, + "dur": end_time - start_time, + } + ) + tracks.append(track) + + if process.returncode == 0: + old_newest_file = newest_file + newest_file = max((p.stat().st_mtime_ns for p in paths)) + LAST_BUILD_TIMES[command_hash] = newest_file + ALREADY_RUN[command_hash].set() + + for path in check_hash: + if path not in file_hashes: + continue + with path.open("rb") as f: + digest = hashlib.file_digest(f, "sha256") + old_digest, _, old_mtimes_ns = file_hashes[path] + if old_digest.digest() == digest.digest(): + logger.debug(f"{path} is unchanged") + os.utime(path, ns=old_mtimes_ns) + + # If something has failed and we've been canceled, hide our success so + # the error is clear. + if cancellation: + raise cancellation + if description: + logger.info(f"{description} ({run_reason})") + logger.debug(command_string) + else: + logger.info(f"{command_string} ({run_reason})") + if old_newest_file == newest_file: + logger.error("No files were modified by the command.") + raise RuntimeError() + else: + if command_hash in LAST_BUILD_TIMES: + del LAST_BUILD_TIMES[command_hash] + logger.error(command_string) + if responsefile_contents: + logger.error(f"Response file contents:\n{responsefile_contents}") + logger.error(f"Return code: {process.returncode}") + if stdout: + logger.info(stdout.decode("utf-8").strip()) + if stderr: + logger.warning(stderr.decode("utf-8").strip()) + if not stdout and not stderr: + logger.warning("No output") + if cancellation: + raise cancellation + raise RuntimeError() + + +async def run_function( + function, + positional, + named, + description=None, +): + async with shared_semaphore: + global max_track + if not tracks: + max_track += 1 + tracks.append(max_track) + track = tracks.pop() + start_time = time.perf_counter_ns() // 1000 + result = await asyncio.to_thread(function, *positional, **named) + + end_time = time.perf_counter_ns() // 1000 + trace_entries.append( + { + "name": str(function) if not description else description, + "ph": "X", + "pid": 0, + "tid": track, + "ts": start_time, + "dur": end_time - start_time, + } + ) + tracks.append(track) + + if description: + logger.info(description) + logger.debug(function) + else: + logger.info(function) + return result + + +def run_in_thread(function): + def wrapper(*positional, **named): + return run_function(function, positional, named) + + return wrapper + + +cwd = pathlib.Path.cwd() + + +def parse_depfile(f): + depfile_contents = f.read_text().split() + extradeps = [] + for dep in depfile_contents: + if dep == "\\" or dep[-1] == ":": + continue + if dep.startswith("/"): + extradeps.append(pathlib.Path(dep)) + else: + raise RuntimeError(f"Unexpected depfile entry {dep}") + + +class Compiler: + def __init__(self, srcdir: pathlib.Path, builddir: pathlib.Path, cmake_args): + self.c_compiler = cmake_args["CC"] + self.ar = cmake_args["AR"] + self.cflags = cmake_args.get("CFLAGS", "") + + self.srcdir = srcdir + self.builddir = builddir + + async def preprocess( + self, source_file: pathlib.Path, output_file: pathlib.Path, flags: list[pathlib.Path] + ): + output_file.parent.mkdir(parents=True, exist_ok=True) + depfile = output_file.parent / (output_file.name + ".d") + responsefile = output_file.parent / (output_file.name + ".rsp") + + await run_command( + [ + self.c_compiler, + "-E", + "-MMD", + "-MF", + depfile, + "-c", + source_file, + self.cflags, + *flags, + "-o", + output_file, + ], + description=f"Preprocess {source_file.relative_to(self.srcdir)} -> {output_file.relative_to(self.builddir)}", + working_directory=self.srcdir, + check_hash=[output_file], + responsefile=responsefile, + ) + + async def compile( + self, source_file: pathlib.Path, output_file: pathlib.Path, flags: list[pathlib.Path] = [] + ): + if isinstance(source_file, str): + source_file = self.srcdir / source_file + if isinstance(output_file, str): + output_file = self.builddir / output_file + output_file.parent.mkdir(parents=True, exist_ok=True) + depfile = output_file.with_suffix(".d") + responsefile = output_file.with_suffix(".rsp") + extradeps = [] + if depfile.exists(): + depfile_contents = depfile.read_text().split() + for dep in depfile_contents: + if dep == "\\" or dep[-1] == ":": + continue + if dep.startswith("/"): + extradeps.append(pathlib.Path(dep)) + else: + extradeps.append(self.srcdir / dep) + + await run_command( + [ + self.c_compiler, + self.cflags, + "-MMD", + "-c", + source_file, + *flags, + "-o", + output_file, + ], + description=f"Compile {source_file.relative_to(self.srcdir)} -> {output_file.relative_to(self.builddir)}", + working_directory=self.srcdir, + extradeps=extradeps, + responsefile=responsefile, + ) + + async def archive(self, objects: list[pathlib.Path], output_file: pathlib.Path): + output_file.parent.mkdir(parents=True, exist_ok=True) + responsefile = output_file.with_suffix(".rsp") + await run_command( + [self.ar, "rvs", output_file, *objects], + description=f"Create archive {output_file.relative_to(self.srcdir)}", + working_directory=self.srcdir, + responsefile=responsefile, + ) diff --git a/ports/zephyr-cp/cptools/gen_compat2driver.py b/ports/zephyr-cp/cptools/gen_compat2driver.py new file mode 100644 index 00000000000..ffe8da18596 --- /dev/null +++ b/ports/zephyr-cp/cptools/gen_compat2driver.py @@ -0,0 +1,27 @@ +import pathlib + +mapping = {} + +drivers = pathlib.Path("zephyr/drivers") +for p in drivers.glob("**/*.[ch]"): + for line in p.open(): + if line.startswith("#define DT_DRV_COMPAT"): + compat = line.rsplit(None, 1)[-1].strip() + driver = str(p.parent.relative_to(drivers)) + print(compat, "->", driver) + mapping[compat] = driver + +with open("cptools/compat2driver.py", "w") as f: + f.write("# This file was generated by gen_compat2driver.py\n") + f.write("COMPAT_TO_DRIVER = {\n") + # Replaces make it pass lint. + last_driver = None + for key in sorted(mapping.keys(), key=lambda x: (mapping[x], x)): + driver = mapping[key] + if driver != last_driver: + if last_driver: + f.write(" #\n") + f.write(f" # {driver}\n") + last_driver = driver + f.write(f' "{key}": "{mapping[key]}",\n') + f.write("}\n") diff --git a/ports/zephyr-cp/cptools/get_west_shield_args.py b/ports/zephyr-cp/cptools/get_west_shield_args.py new file mode 100644 index 00000000000..deda6bf5f26 --- /dev/null +++ b/ports/zephyr-cp/cptools/get_west_shield_args.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +"""Resolve shield arguments for west build. + +Priority: +1. SHIELD / SHIELDS make variables (if explicitly provided) +2. SHIELD / SHIELDS from boards///circuitpython.toml +""" + +import argparse +import os +import pathlib +import re +import shlex + +import board_tools + + +def split_shields(raw): + if not raw: + return [] + + return [shield for shield in re.split(r"[,;\s]+", raw.strip()) if shield] + + +def dedupe(values): + deduped = [] + seen = set() + + for value in values: + if value in seen: + continue + seen.add(value) + deduped.append(value) + + return deduped + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("board") + args = parser.parse_args() + + portdir = pathlib.Path(__file__).resolve().parent.parent + + _, mpconfigboard = board_tools.load_mpconfigboard(portdir, args.board) + + shield_origin = os.environ.get("SHIELD_ORIGIN", "undefined") + shields_origin = os.environ.get("SHIELDS_ORIGIN", "undefined") + + shield_override = os.environ.get("SHIELD", "") + shields_override = os.environ.get("SHIELDS", "") + + override_requested = shield_origin != "undefined" or shields_origin != "undefined" + + if override_requested: + shields = split_shields(shield_override) + split_shields(shields_override) + else: + shields = board_tools.get_shields(mpconfigboard) + + shields = dedupe(shields) + + west_shield_args = [] + for shield in shields: + west_shield_args.extend(("--shield", shield)) + + print(shlex.join(west_shield_args)) + + +if __name__ == "__main__": + main() diff --git a/ports/zephyr-cp/cptools/pre_zephyr_build_prep.py b/ports/zephyr-cp/cptools/pre_zephyr_build_prep.py new file mode 100644 index 00000000000..f42fc1a3a85 --- /dev/null +++ b/ports/zephyr-cp/cptools/pre_zephyr_build_prep.py @@ -0,0 +1,28 @@ +# Called by the Makefile before calling out to `west`. +import pathlib +import subprocess +import sys + +import board_tools + +portdir = pathlib.Path(__file__).resolve().parent.parent + +board = sys.argv[-1] + +_, mpconfigboard = board_tools.load_mpconfigboard(portdir, board) +if not mpconfigboard: + # Assume it doesn't need any prep. + sys.exit(0) + +blobs = mpconfigboard.get("BLOBS", []) +blob_fetch_args = mpconfigboard.get("blob_fetch_args", {}) +for blob in blobs: + args = blob_fetch_args.get(blob, []) + subprocess.run(["west", "blobs", "fetch", blob, *args], check=True) + +if board.endswith("bsim"): + subprocess.run( + ["make", "everything", "-j", "8"], + cwd=portdir / "tools" / "bsim", + check=True, + ) diff --git a/ports/zephyr-cp/cptools/tests/README.md b/ports/zephyr-cp/cptools/tests/README.md new file mode 100644 index 00000000000..6bc8aa43ce6 --- /dev/null +++ b/ports/zephyr-cp/cptools/tests/README.md @@ -0,0 +1,28 @@ +# Zephyr2CP Tests + +This directory contains unit tests for the `zephyr2cp.py` module using real device tree parsing and pytest. + +## Running Tests + +To run all tests: +```bash +cd /home/tannewt/repos/circuitpython/ports/zephyr-cp +make test +``` + +For verbose output: +```bash +pytest test_zephyr2cp.py -v +``` + +To run specific test classes: +```bash +pytest test_zephyr2cp.py::TestFindFlashDevices -v +pytest test_zephyr2cp.py::TestFindRAMRegions -v +pytest test_zephyr2cp.py::TestIntegration -v +``` + +To run a specific test: +```bash +pytest test_zephyr2cp.py::TestFindFlashDevices::test_valid_flash_device -v +``` diff --git a/ports/zephyr-cp/cptools/tests/test_zephyr2cp.py b/ports/zephyr-cp/cptools/tests/test_zephyr2cp.py new file mode 100644 index 00000000000..b147ae0605e --- /dev/null +++ b/ports/zephyr-cp/cptools/tests/test_zephyr2cp.py @@ -0,0 +1,589 @@ +import sys +import pathlib +import tempfile + +# Add devicetree library to path +portdir = pathlib.Path(__file__).parent.parent.parent +sys.path.append(str(portdir / "zephyr/scripts/dts/python-devicetree/src/")) + +from devicetree import dtlib + +# Add parent directory to path to import zephyr2cp +sys.path.insert(0, str(pathlib.Path(__file__).parent.parent)) + +# Mock cpbuild before importing +sys.modules["cpbuild"] = type(sys)("cpbuild") +sys.modules["cpbuild"].run_in_thread = lambda x: x + +from zephyr2cp import find_flash_devices, find_ram_regions, BLOCKED_FLASH_COMPAT, MINIMUM_RAM_SIZE + + +def parse_dts_string(dts_content): + """ + Parse a device tree string and return the dtlib.DT object. + + Args: + dts_content: String containing device tree source + + Returns: + dtlib.DT object with parsed device tree + """ + with tempfile.NamedTemporaryFile(mode="w", suffix=".dts", delete=False) as f: + f.write(dts_content) + f.flush() + temp_path = f.name + + try: + dt = dtlib.DT(temp_path) + return dt + finally: + pathlib.Path(temp_path).unlink() + + +class TestFindFlashDevices: + """Test suite for find_flash_devices function.""" + + def test_no_compatible_returns_empty(self): + """Test that device tree with no flash devices returns empty list.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + memory@0 { + reg = <0x0 0x100000>; + }; + + chosen { + }; +}; +""" + dt = parse_dts_string(dts) + result = find_flash_devices(dt) + assert result == [] + + def test_chosen_flash_excluded(self): + """Test that chosen flash nodes are excluded.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 0x100000>; + }; + + chosen { + zephyr,flash = &flash0; + }; +}; +""" + dt = parse_dts_string(dts) + result = find_flash_devices(dt) + assert result == [], "Chosen flash should be excluded" + + def test_blocked_compat_excluded(self): + """Test that blocked compatible strings are excluded.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + qspi0: qspi@40000 { + compatible = "renesas,ra-qspi"; + reg = <0x40000 0x1000>; + }; + + spi0: spi@50000 { + compatible = "nordic,nrf-spim"; + reg = <0x50000 0x1000>; + }; + + chosen { + }; +}; +""" + dt = parse_dts_string(dts) + result = find_flash_devices(dt) + assert result == [], "Blocked flash controllers should be excluded" + + def test_valid_flash_device(self): + """Test that valid flash device is detected.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0 0x100000>; + }; + + chosen { + }; +}; +""" + dt = parse_dts_string(dts) + result = find_flash_devices(dt) + assert len(result) == 1 + assert result[0] == "flash0" + + def test_valid_flash_device_multiple_drivers(self): + """Test that valid flash device is detected.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "other,driver", "jedec,spi-nor"; + reg = <0x0 0x100000>; + }; + + chosen { + }; +}; +""" + dt = parse_dts_string(dts) + result = find_flash_devices(dt) + assert len(result) == 1 + assert result[0] == "flash0" + + def test_external_flash_not_chosen(self): + """Test external flash is included when internal is chosen.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + internal_flash: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 0x100000>; + }; + + external_flash: flash@1000000 { + compatible = "jedec,spi-nor"; + reg = <0x1000000 0x800000>; + }; + + chosen { + zephyr,flash = &internal_flash; + }; +}; +""" + dt = parse_dts_string(dts) + result = find_flash_devices(dt) + + # Should only include external flash, not chosen internal flash + assert len(result) == 1 + assert "external_flash" in result[0] + assert "internal_flash" not in result[0] + + def test_disabled_flash_excluded(self): + """Test that disabled flash devices are excluded.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0 0x100000>; + status = "disabled"; + }; + + chosen { + }; +}; +""" + dt = parse_dts_string(dts) + result = find_flash_devices(dt) + assert result == [], "Disabled flash should be excluded" + + +class TestFindRAMRegions: + """Test suite for find_ram_regions function.""" + + def test_no_ram_returns_empty(self): + """Test that device tree with no RAM returns empty list.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 0x100000>; + }; + + chosen { + }; +}; +""" + dt = parse_dts_string(dts) + result = find_ram_regions(dt) + assert result == [] + + def test_chosen_sram_basic(self): + """Test chosen sram region is detected correctly.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x40000>; + }; + + chosen { + zephyr,sram = &sram0; + }; +}; +""" + dt = parse_dts_string(dts) + result = find_ram_regions(dt) + + assert len(result) == 1 + label, start, end, size, path = result[0] + + assert label == "sram0" + assert start == "z_mapped_end" + assert ( + end + == "(uint32_t*) (DT_REG_ADDR(DT_NODELABEL(sram0)) + DT_REG_SIZE(DT_NODELABEL(sram0)))" + ) + assert size == 0x40000 + + def test_memory_region_with_custom_name(self): + """Test memory region with zephyr,memory-region property.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x40000>; + }; + + reserved_mem: memory@30000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x30000000 0x10000>; + zephyr,memory-region = "CUSTOM_REGION"; + }; + + chosen { + zephyr,sram = &sram0; + }; +}; +""" + dt = parse_dts_string(dts) + result = find_ram_regions(dt) + + # Should have both regions, chosen first + assert len(result) == 2 + + # First should be chosen SRAM + assert result[0][0] == "sram0" + + # Second should be custom region + label, start, end, size, path = result[1] + assert label == "reserved_mem" + assert start == "__CUSTOM_REGION_end" + + def test_memory_region_requires_sram_or_device_type(self): + """Test memory regions require mmio-sram compatibility or device_type=memory.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x40000>; + }; + + reserved_mem: memory@30000000 { + compatible = "zephyr,memory-region"; + reg = <0x30000000 0x10000>; + zephyr,memory-region = "CUSTOM_REGION"; + }; + + external_mem: memory@40000000 { + compatible = "zephyr,memory-region"; + device_type = "memory"; + reg = <0x40000000 0x20000>; + zephyr,memory-region = "EXT_REGION"; + }; + + chosen { + zephyr,sram = &sram0; + }; +}; +""" + dt = parse_dts_string(dts) + result = find_ram_regions(dt) + + assert len(result) == 2 + assert result[0][0] == "sram0" + assert result[1][0] == "external_mem" + + def test_disabled_ram_excluded(self): + """Test that disabled RAM regions are excluded.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x40000>; + }; + + sram1: memory@30000000 { + compatible = "zephyr,memory-region", "mmio-sram"; + reg = <0x30000000 0x10000>; + status = "disabled"; + zephyr,memory-region = "CUSTOM_REGION"; + }; + + chosen { + zephyr,sram = &sram0; + }; +}; +""" + dt = parse_dts_string(dts) + result = find_ram_regions(dt) + + # Should only have chosen SRAM, not disabled one + assert len(result) == 1 + assert result[0][0] == "sram0" + + +class TestIntegration: + """Integration tests with realistic device tree configurations.""" + + def test_typical_nrf_board_configuration(self): + """Test typical Nordic nRF board with internal and external flash.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + + soc { + #address-cells = <1>; + #size-cells = <1>; + + flash0: flash@0 { + compatible = "soc-nv-flash"; + reg = <0x0 0x100000>; + }; + + sram0: memory@20000000 { + compatible = "mmio-sram"; + reg = <0x20000000 0x40000>; + }; + }; + + external_flash: spi_flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0 0x800000>; + }; + + chosen { + zephyr,flash = &flash0; + zephyr,sram = &sram0; + }; +}; +""" + dt = parse_dts_string(dts) + + # Test flash detection + flashes = find_flash_devices(dt) + assert len(flashes) == 1, "Should find external flash only" + assert "external_flash" in flashes[0] + + # Test RAM detection + rams = find_ram_regions(dt) + assert len(rams) == 1, "Should find chosen SRAM only" + assert rams[0][0] == "sram0" + + def test_board_with_nrf5340_regions(self): + """Test that RAM subregions are included with the right addresses.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { + zephyr,sram = &sram0_image; + }; + /* node '/soc/peripheral@50000000/qspi@2b000' defined in zephyr/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi:475 */ + qspi: qspi@2b000 { + compatible = "nordic,nrf-qspi"; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi:476 */ + #address-cells = < 0x1 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi:477 */ + #size-cells = < 0x0 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi:478 */ + reg = < 0x2b000 0x1000 >, + < 0x10000000 0x10000000 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi:479 */ + reg-names = "qspi", + "qspi_mm"; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi:480 */ + interrupts = < 0x2b 0x1 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_peripherals.dtsi:481 */ + status = "okay"; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:118 */ + + /* node '/soc/peripheral@50000000/qspi@2b000/mx25r6435f@0' defined in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:123 */ + mx25r64: mx25r6435f@0 { + compatible = "nordic,qspi-nor"; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:124 */ + reg = < 0x0 >; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:125 */ + writeoc = "pp4io"; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:127 */ + readoc = "read4io"; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:129 */ + sck-frequency = < 0x7a1200 >; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:130 */ + jedec-id = [ C2 28 17 ]; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:131 */ + sfdp-bfp = [ E5 20 F1 FF FF FF FF 03 44 EB 08 6B 08 3B 04 BB EE FF FF FF FF FF 00 FF FF FF 00 + FF 0C 20 0F 52 10 D8 00 FF 23 72 F5 00 82 ED 04 CC 44 83 68 44 30 B0 30 B0 F7 C4 + D5 5C 00 BE 29 FF F0 D0 FF FF ]; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:132 */ + size = < 0x4000000 >; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:136 */ + has-dpd; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:137 */ + t-enter-dpd = < 0x2710 >; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:138 */ + t-exit-dpd = < 0x88b8 >; /* in zephyr/boards/nordic/nrf5340dk/nrf5340_cpuapp_common.dtsi:139 */ + }; + }; + + /* node '/soc/memory@20000000' defined in zephyr/dts/arm/nordic/nrf5340_cpuapp.dtsi:55 */ + sram0: memory@20000000 { + compatible = "mmio-sram"; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp.dtsi:56 */ + #address-cells = < 0x1 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp.dtsi:57 */ + #size-cells = < 0x1 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp.dtsi:58 */ + reg = < 0x20000000 0x80000 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_qkaa.dtsi:15 */ + ranges = < 0x0 0x20000000 0x80000 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_qkaa.dtsi:16 */ + + /* node '/soc/memory@20000000/sram@0' defined in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:16 */ + sram0_image: sram@0 { + reg = < 0x0 0x70000 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:18 */ + ranges = < 0x0 0x0 0x70000 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:19 */ + #address-cells = < 0x1 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:20 */ + #size-cells = < 0x1 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:21 */ + + /* node '/soc/memory@20000000/sram@0/sram0_image@0' defined in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:23 */ + sram0_s: sram0_image@0 { + reg = < 0x0 0x40000 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:25 */ + }; + }; + + /* node '/soc/memory@20000000/sram@40000' defined in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:33 */ + sram0_ns: sram@40000 { + reg = < 0x40000 0x40000 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:35 */ + ranges = < 0x0 0x40000 0x40000 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:36 */ + #address-cells = < 0x1 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:37 */ + #size-cells = < 0x1 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:38 */ + + /* node '/soc/memory@20000000/sram@40000/sram0_ns@0' defined in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:40 */ + sram0_ns_app: sram0_ns@0 { + reg = < 0x0 0x30000 >; /* in zephyr/dts/vendor/nordic/nrf5340_sram_partition.dtsi:42 */ + }; + }; + + /* node '/soc/memory@20000000/sram@70000' defined in zephyr/dts/vendor/nordic/nrf5340_shared_sram_partition.dtsi:27 */ + sram0_shared: sram@70000 { + reg = < 0x70000 0x10000 >; /* in zephyr/dts/vendor/nordic/nrf5340_shared_sram_partition.dtsi:29 */ + phandle = < 0x11 >; /* in zephyr/dts/arm/nordic/nrf5340_cpuapp_ipc.dtsi:9 */ + }; + }; +}; +""" + dt = parse_dts_string(dts) + flashes = find_flash_devices(dt) + rams = find_ram_regions(dt) + + # Should only get chosen SRAM + assert len(rams) == 1 + assert rams[0][0] == "sram0_image" + + assert len(flashes) == 1 + assert flashes[0] == "mx25r64" + + def test_board_with_chosen_memory_region(self): + """Test that RAM subregions are included with the right addresses.""" + dts = """ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + chosen { + zephyr,sram = &axisram2; /* in zephyr/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi:18 */ + }; + + + /* node '/memory@34000000' defined in zephyr/dts/arm/st/n6/stm32n6.dtsi:42 */ + axisram1: memory@34000000 { + compatible = "zephyr,memory-region", + "mmio-sram"; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:43 */ + zephyr,memory-region = "AXISRAM1"; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:44 */ + reg = < 0x34000000 0x200000 >; /* in zephyr/dts/arm/st/n6/stm32n657X0.dtsi:12 */ + }; + + /* node '/memory@34180400' defined in zephyr/dts/arm/st/n6/stm32n6.dtsi:47 */ + axisram2: memory@34180400 { + compatible = "zephyr,memory-region", + "mmio-sram"; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:48 */ + zephyr,memory-region = "AXISRAM2"; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:49 */ + reg = < 0x34180400 0x7fc00 >; /* in zephyr/dts/arm/st/n6/stm32n657X0.dtsi:17 */ + }; + + /* node '/soc/ramcfg@42023100' defined in zephyr/dts/arm/st/n6/stm32n6.dtsi:251 */ + ramcfg_sram3_axi: ramcfg@42023100 { + compatible = "st,stm32n6-ramcfg"; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:252 */ + #address-cells = < 0x1 >; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:253 */ + #size-cells = < 0x1 >; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:254 */ + reg = < 0x42023100 0x80 >; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:255 */ + + /* node '/soc/ramcfg@42023100/memory@34200000' defined in zephyr/dts/arm/st/n6/stm32n6.dtsi:259 */ + axisram3: memory@34200000 { + compatible = "zephyr,memory-region", + "mmio-sram"; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:260 */ + zephyr,memory-region = "AXISRAM3"; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:261 */ + zephyr,memory-attr = < 0x100000 >; /* in zephyr/dts/arm/st/n6/stm32n6.dtsi:262 */ + reg = < 0x34200000 0x70000 >; /* in zephyr/dts/arm/st/n6/stm32n657X0.dtsi:23 */ + status = "disabled"; /* in zephyr/dts/arm/st/n6/stm32n657X0.dtsi:24 */ + }; + }; +}; +""" + dt = parse_dts_string(dts) + rams = find_ram_regions(dt) + + print(rams) + + # Should only get chosen SRAM + assert len(rams) == 2 + assert rams[0][0] == "axisram2" + assert rams[1][0] == "axisram1" diff --git a/ports/zephyr-cp/cptools/update_board_info.py b/ports/zephyr-cp/cptools/update_board_info.py new file mode 100755 index 00000000000..935fc07c17d --- /dev/null +++ b/ports/zephyr-cp/cptools/update_board_info.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python3 + +import pathlib +import sys +import tomlkit + + +def find_modules(top_dir, port_dir): + """Find all available modules in shared-bindings and port bindings.""" + modules = set() + for module in sorted( + list(top_dir.glob("shared-bindings/*")) + list(port_dir.glob("bindings/*")), + key=lambda x: x.name, + ): + if not module.is_dir(): + continue + modules.add(module.name) + return sorted(modules) + + +def find_board_info_files(port_dir): + """Find all autogen_board_info.toml files in the port directory.""" + return list(port_dir.glob("boards/**/autogen_board_info.toml")) + + +def update_board_info(board_info_path, available_modules): + """Update board info file with new modules set to false.""" + if not board_info_path.exists(): + print(f"Error: Board info file {board_info_path} does not exist", file=sys.stderr) + return False + + # Load existing board info + with open(board_info_path, "r", encoding="utf-8") as f: + board_info = tomlkit.load(f) + + # Get current modules + current_modules = set(board_info.get("modules", {})) + + # Find new modules + new_modules = set(available_modules) - current_modules + if not new_modules: + print( + f"No new modules found for {board_info_path.relative_to(board_info_path.parents[3])}" + ) + return True + + # Add new modules as disabled in alphabetical order + modules_table = board_info["modules"] + # Get all modules (existing and new) and sort them + all_modules = list(current_modules | new_modules) + all_modules.sort() + + # Create a new table with sorted modules + sorted_table = tomlkit.table() + for module in all_modules: + if module in modules_table: + # TODO: Use modules_table.item once tomlkit is released with changes from January 2025 + sorted_table[module] = modules_table._value.item(module) + else: + sorted_table[module] = tomlkit.item(False) + + # Replace the modules table with the sorted one + board_info["modules"] = sorted_table + + # Write updated board info + with open(board_info_path, "w", encoding="utf-8") as f: + tomlkit.dump(board_info, f) + + print( + f"Updated {board_info_path.relative_to(board_info_path.parents[3])} with {len(new_modules)} new modules:" + ) + for module in sorted(new_modules): + print(f" - {module}") + return True + + +def main(): + # Get repo paths + script_dir = pathlib.Path(__file__).parent + top_dir = script_dir.parents[2] # circuitpython root + port_dir = script_dir.parent # zephyr-cp directory + + # Get available modules once + available_modules = find_modules(top_dir, port_dir) + + # Update all board info files + board_info_files = find_board_info_files(port_dir) + if not board_info_files: + print("No board info files found") + sys.exit(1) + + success = True + for board_info_path in board_info_files: + if not update_board_info(board_info_path, available_modules): + success = False + + sys.exit(0 if success else 1) + + +if __name__ == "__main__": + main() diff --git a/ports/zephyr-cp/cptools/zephyr2cp.py b/ports/zephyr-cp/cptools/zephyr2cp.py new file mode 100644 index 00000000000..a6e2fa53cdc --- /dev/null +++ b/ports/zephyr-cp/cptools/zephyr2cp.py @@ -0,0 +1,1060 @@ +import logging +import pathlib +import re + +import cpbuild +import yaml +from compat2driver import COMPAT_TO_DRIVER +from devicetree import dtlib + +logger = logging.getLogger(__name__) +logger.setLevel(logging.DEBUG) + +# GPIO flags defined here: include/zephyr/dt-bindings/gpio/gpio.h +GPIO_ACTIVE_LOW = 1 << 0 + +MINIMUM_RAM_SIZE = 1024 + +MANUAL_COMPAT_TO_DRIVER = { + "renesas_ra_nv_flash": "flash", + "soc_nv_flash": "flash", + "nordic_nrf_uarte": "serial", + "nordic_nrf_uart": "serial", + "nordic_nrf_twim": "i2c", + "nordic_nrf_twi": "i2c", + "nordic_nrf_spim": "spi", + "nordic_nrf_spi": "spi", + "nordic_nrf_i2s": "i2s", +} + +# These are controllers, not the flash devices themselves. +BLOCKED_FLASH_COMPAT = ( + "renesas,ra-qspi", + "renesas,ra-ospi-b", + "nordic,nrf-spim", +) + +BUSIO_CLASSES = {"serial": "UART", "i2c": "I2C", "spi": "SPI"} + +AUDIOBUSIO_CLASSES = {"i2s": "I2SOut"} + +CONNECTORS = { + "mikro-bus": [ + "AN", + "RST", + "CS", + "SCK", + "MISO", + "MOSI", + "PWM", + "INT", + "RX", + "TX", + "SCL", + "SDA", + ], + "arduino-header-r3": [ + "A0", + "A1", + "A2", + "A3", + "A4", + "A5", + "D0", + "D1", + "D2", + "D3", + "D4", + "D5", + "D6", + "D7", + "D8", + "D9", + "D10", + "D11", + "D12", + "D13", + "D14", + "D15", + ], + "adafruit-feather-header": [ + "A0", + "A1", + "A2", + "A3", + "A4", + "A5", + "SCK", + "MOSI", + "MISO", + "RX", + "TX", + "D4", + "SDA", + "SCL", + "D5", + "D6", + "D9", + "D10", + "D11", + "D12", + "D13", + ], + "adafruit-clue": [ + ["P0", "D0", "A2", "RX"], + ["P1", "D1", "A3", "TX"], + ["P2", "D2", "A4"], + ["P3", "D3", "A5"], + ["P4", "D4", "A6"], + ["P5", "D5", "BUTTON_A"], + ["P6", "D6"], + ["P7", "D7"], + ["P8", "D8"], + ["P9", "D9"], + ["P10", "D10", "A7"], + ["P11", "D11", "BUTTON_B"], + ["P12", "D12", "A0"], + ["P13", "D13", "SCK"], + ["P14", "D14", "MISO"], + ["P15", "D15", "MOSI"], + ["P16", "D16", "A1"], + ["P17", "D17", "L", "LED"], + ["P18", "D18", "NEOPIXEL"], + ["P19", "D19", "SCL"], + ["P20", "D20", "SDA"], + ], + "nordic,expansion-board-header": [ + "P1_04", + "P1_05", + "P1_06", + "P1_07", + "P1_08", + "P1_09", + "P1_10", + "P1_11", + "P1_12", + "P1_13", + "P1_14", + ], + "arducam,dvp-20pin-connector": [ + "SCL", + "SDA", + "VS", + "HS", + "PCLK", + "XCLK", + "D7", + "D6", + "D5", + "D4", + "D3", + "D2", + "D1", + "D0", + "PEN", + "PDN", + "GPIO0", + "GPIO1", + ], + "nxp,cam-44pins-connector": ["CAM_RESETB", "CAM_PWDN"], + "nxp,lcd-8080": [ + "TOUCH_SCL", + "TOUCH_SDA", + "TOUCH_INT", + "BACKLIGHT", + "RESET", + "LCD_DC", + "LCD_CS", + "LCD_WR", + "LCD_RD", + "LCD_TE", + "LCD_D0", + "LCD_D1", + "LCD_D2", + "LCD_D3", + "LCD_D4", + "LCD_D5", + "LCD_D6", + "LCD_D7", + "LCD_D8", + "LCD_D9", + "LCD_D10", + "LCD_D11", + "LCD_D12", + "LCD_D13", + "LCD_D14", + "LCD_D15", + ], + "nxp,lcd-pmod": [ + "LCD_WR", + "TOUCH_SCL", + "LCD_DC", + "TOUCH_SDA", + "LCD_MOSI", + "TOUCH_RESET", + "LCD_CS", + "TOUCH_INT", + ], + "raspberrypi,csi-connector": [ + "CSI_D0_N", + "CSI_D0_P", + "CSI_D1_N", + "CSI_D1_P", + "CSI_CK_N", + "CSI_CK_P", + "CSI_D2_N", + "CSI_D2_P", + "CSI_D3_N", + "CSI_D3_P", + "IO0", + "IO1", + "I2C_SCL", + "I2C_SDA", + ], + "renesas,ra-gpio-mipi-header": [ + "IIC_SDA", + "DISP_BLEN", + "IIC_SCL", + "DISP_INT", + "DISP_RST", + ], + "renesas,ra-parallel-graphics-header": [ + "DISP_BLEN", + "IIC_SDA", + "DISP_INT", + "IIC_SCL", + "DISP_RST", + "LCDC_TCON0", + "LCDC_CLK", + "LCDC_TCON2", + "LCDC_TCON1", + "LCDC_EXTCLK", + "LCDC_TCON3", + "LCDC_DATA01", + "LCDC_DATA00", + "LCDC_DATA03", + "LCDC_DATA02", + "LCDC_DATA05", + "LCDC_DATA04", + "LCDC_DATA07", + "LCDC_DATA16", + "LCDC_DATA09", + "LCDC_DATA08", + "LCDC_DATA11", + "LCDC_DATA10", + "LCDC_DATA13", + "LCDC_DATA12", + "LCDC_DATA15", + "LCDC_DATA14", + "LCDC_DATA17", + "LCDC_DATA16", + "LCDC_DATA19", + "LCDC_DATA18", + "LCDC_DATA21", + "LCDC_DATA20", + "LCDC_DATA23", + "LCDC_DATA22", + ], + "st,stm32-dcmi-camera-fpu-330zh": [ + "SCL", + "SDA", + "RESET", + "PEN", + "VS", + "HS", + "PCLK", + "D7", + "D6", + "D5", + "D4", + "D3", + "D2", + "D1", + "D0", + ], + "raspberrypi,pico-header": [ + "GP0", + "GP1", + "GP2", + "GP3", + "GP4", + "GP5", + "GP6", + "GP7", + "GP8", + "GP9", + "GP10", + "GP11", + "GP12", + "GP13", + "GP14", + "GP15", + "GP16", + "GP17", + "GP18", + "GP19", + "GP20", + "GP21", + "GP22", + ["GP26_A0", "GP26", "A0"], + ["GP27_A1", "GP27", "A1"], + ["GP28_A2", "GP28", "A2"], + ], +} + +EXCEPTIONAL_DRIVERS = ["entropy", "gpio", "led"] + + +def find_flash_devices(device_tree): + """ + Find all flash devices from a device tree. + + Args: + device_tree: Parsed device tree (dtlib.DT object) + + Returns: + List of device tree flash device reference strings + """ + # Build path2chosen mapping + path2chosen = {} + for k in device_tree.root.nodes["chosen"].props: + value = device_tree.root.nodes["chosen"].props[k] + path2chosen[value.to_path()] = k + + flashes = [] + logger.debug("Flash devices:") + + # Traverse all nodes in the device tree + remaining_nodes = set([device_tree.root]) + while remaining_nodes: + node = remaining_nodes.pop() + remaining_nodes.update(node.nodes.values()) + + # Get compatible strings + compatible = [] + if "compatible" in node.props: + compatible = node.props["compatible"].to_strings() + + # Get status + status = node.props.get("status", None) + if status is None: + status = "okay" + else: + status = status.to_string() + + # Check if this is a flash device + if not compatible or status != "okay": + continue + + # Check for flash driver via compat2driver + drivers = [] + for c in compatible: + underscored = c.replace(",", "_").replace("-", "_") + driver = COMPAT_TO_DRIVER.get(underscored, None) + if not driver: + driver = MANUAL_COMPAT_TO_DRIVER.get(underscored, None) + if driver: + drivers.append(driver) + logger.debug(f" {node.labels[0] if node.labels else node.name} drivers: {drivers}") + + if "flash" not in drivers: + continue + + # Skip chosen nodes because they are used by Zephyr + if node in path2chosen: + logger.debug( + f" skipping flash {node.labels[0] if node.labels else node.name} (chosen)" + ) + continue + + # Skip blocked flash compatibles (controllers, not actual flash devices) + if compatible[0] in BLOCKED_FLASH_COMPAT: + logger.debug( + f" skipping flash {node.labels[0] if node.labels else node.name} (blocked compat)" + ) + continue + + # Skip soc-nv-flash nodes whose parent is itself a flash device — the + # parent is the real Zephyr device (e.g. nxp,imx-flexspi-nor) and the + # child has no driver-instantiated symbol. + if "soc-nv-flash" in compatible and node.parent is not None: + parent_compat = [] + if "compatible" in node.parent.props: + parent_compat = node.parent.props["compatible"].to_strings() + parent_drivers = [] + for c in parent_compat: + underscored = c.replace(",", "_").replace("-", "_") + d = COMPAT_TO_DRIVER.get(underscored) or MANUAL_COMPAT_TO_DRIVER.get(underscored) + if d: + parent_drivers.append(d) + if "flash" in parent_drivers: + logger.debug( + f" skipping flash {node.labels[0] if node.labels else node.name} (parent is flash device)" + ) + continue + + if node.labels: + flashes.append(node.labels[0]) + + logger.debug("Flash devices:") + for flash in flashes: + logger.debug(f" {flash}") + + return flashes + + +def _label_to_end(label): + return f"(uint32_t*) (DT_REG_ADDR(DT_NODELABEL({label})) + DT_REG_SIZE(DT_NODELABEL({label})))" + + +def find_ram_regions(device_tree): + """ + Find all RAM regions from a device tree. Includes the zephyr,sram node and + any zephyr,memory-region nodes. + + Returns: + List of RAM region info tuples: (label, start, end, size, path) + """ + rams = [] + chosen = None + # Get the chosen SRAM node directly + if "zephyr,sram" in device_tree.root.nodes["chosen"].props: + chosen = device_tree.root.nodes["chosen"].props["zephyr,sram"].to_path() + label = chosen.labels[0] + size = chosen.props["reg"].to_nums()[1] + logger.debug(f"Found chosen SRAM node: {label} with size {size}") + rams.append((label, "z_mapped_end", _label_to_end(label), size, chosen.path)) + + # Traverse all nodes in the device tree to find memory-region nodes + remaining_nodes = set([device_tree.root]) + while remaining_nodes: + node = remaining_nodes.pop() + + # Check status first so we don't add child nodes that aren't active. + status = node.props.get("status", None) + if status is None: + status = "okay" + else: + status = status.to_string() + + if status != "okay": + continue + + if node == chosen: + continue + + remaining_nodes.update(node.nodes.values()) + + if "compatible" not in node.props or not node.labels: + continue + + compatible = node.props["compatible"].to_strings() + + if "zephyr,memory-region" not in compatible or "zephyr,memory-region" not in node.props: + continue + + is_mmio_sram = "mmio-sram" in compatible + device_type = node.props.get("device_type") + has_memory_device_type = device_type and device_type.to_string() == "memory" + if not (is_mmio_sram or has_memory_device_type): + continue + + size = node.props["reg"].to_nums()[1] + + start = "__" + node.props["zephyr,memory-region"].to_string() + "_end" + end = _label_to_end(node.labels[0]) + + # Filter by minimum size + if size >= MINIMUM_RAM_SIZE: + logger.debug( + f"Adding extra RAM info: ({node.labels[0]}, {start}, {end}, {size}, {node.path})" + ) + info = (node.labels[0], start, end, size, node.path) + rams.append(info) + + return rams + + +# gpio-keys nodes identify a key with `zephyr,code` rather than the optional and +# deprecated `label`, so the code is the only name a modern board gives. +INPUT_KEY_NAMES = {} + + +def _populate_input_key_names(): + header = ( + pathlib.Path(__file__).parent.parent + / "zephyr" + / "include" + / "zephyr" + / "dt-bindings" + / "input" + / "input-event-codes.h" + ) + if not header.exists(): + return + pattern = re.compile(r"^#define\s+INPUT_(?PKEY_\w+)\s+(?P\d+)") + for line in header.read_text().splitlines(): + match = pattern.match(line) + if match: + INPUT_KEY_NAMES.setdefault(int(match.group("code")), match.group("name")) + + +_populate_input_key_names() + + +@cpbuild.run_in_thread +def zephyr_dts_to_cp_board(board_id, portdir, builddir, zephyrbuilddir, mpconfigboard=None): # noqa: C901 + board_dir = builddir / "board" + # Auto generate board files from device tree. + + board_info = { + "wifi": False, + "usb_device": False, + "_bleio": False, + "hostnetwork": board_id in ["native_sim"], + "audiobusio": False, + } + + config_bt_enabled = False + config_bt_found = False + config_present = True + config = zephyrbuilddir / ".config" + if not config.exists(): + config_present = False + else: + for line in config.read_text().splitlines(): + if line.startswith("CONFIG_BT="): + config_bt_enabled = line.strip().endswith("=y") + config_bt_found = True + break + if line.startswith("# CONFIG_BT is not set"): + config_bt_enabled = False + config_bt_found = True + break + + runners = zephyrbuilddir / "runners.yaml" + runners = yaml.safe_load(runners.read_text()) + zephyr_board_dir = pathlib.Path(runners["config"]["board_dir"]) + board_yaml = zephyr_board_dir / "board.yml" + board_yaml = yaml.safe_load(board_yaml.read_text()) + if "board" not in board_yaml and "boards" in board_yaml: + for board in board_yaml["boards"]: + if board["name"] == board_id: + board_yaml = board + break + else: + board_yaml = board_yaml["board"] + board_info["vendor_id"] = board_yaml["vendor"] + # Most vendors put boards directly in boards//, but some group + # them further, like boards/silabs/dev_kits/. Walk up to the directory + # named for the vendor so we read the vendor's index.rst and not a category's. + vendor_dir = zephyr_board_dir.parent + for parent in zephyr_board_dir.parents: + if parent.name == board_info["vendor_id"]: + vendor_dir = parent + break + vendor_index = vendor_dir / "index.rst" + if vendor_index.exists(): + vendor_index = vendor_index.read_text() + vendor_index = vendor_index.split("\n") + vendor_name = vendor_index[2].strip() + else: + vendor_name = board_info["vendor_id"] + board_info["vendor"] = vendor_name + soc_name = board_yaml["socs"][0]["name"] + board_info["soc"] = soc_name + board_name = board_yaml["full_name"] + if mpconfigboard and "NAME" in mpconfigboard: + board_name = mpconfigboard["NAME"] + board_info["name"] = board_name + # board_id_yaml = zephyr_board_dir / (zephyr_board_dir.name + ".yaml") + # board_id_yaml = yaml.safe_load(board_id_yaml.read_text()) + # print(board_id_yaml) + # board_name = board_id_yaml["name"] + + dts = zephyrbuilddir / "zephyr.dts" + device_tree = dtlib.DT(dts) + node2alias = {} + for alias in device_tree.alias2node: + node = device_tree.alias2node[alias] + if node not in node2alias: + node2alias[node] = [] + node2alias[node].append(alias) + ioports = {} + all_ioports = [] + board_names = {} + status_led = None + status_led_inverted = False + path2chosen = {} + chosen2path = {} + + # Find flash and RAM regions using extracted functions + flashes = find_flash_devices(device_tree) + rams = find_ram_regions(device_tree) # Returns filtered and sorted list + + # Store active Zephyr device labels per-driver so that we can make them available via board. + active_zephyr_devices = {} + usb_num_endpoint_pairs = 0 + ble_hardware_present = False + for k in device_tree.root.nodes["chosen"].props: + value = device_tree.root.nodes["chosen"].props[k] + path2chosen[value.to_path()] = k + chosen2path[k] = value.to_path() + + chosen_display = chosen2path.get("zephyr,display") + if chosen_display is not None: + status = chosen_display.props.get("status", None) + if status is None or status.to_string() == "okay": + board_info["zephyr_display"] = True + board_info["displayio"] = True + + remaining_nodes = set([device_tree.root]) + while remaining_nodes: + node = remaining_nodes.pop() + remaining_nodes.update(node.nodes.values()) + gpio = node.props.get("gpio-controller", False) + gpio_map = node.props.get("gpio-map", []) + status = node.props.get("status", None) + if status is None: + status = "okay" + else: + status = status.to_string() + + compatible = [] + if "compatible" in node.props: + compatible = node.props["compatible"].to_strings() + logger.debug(f"{node.name}: {status}") + logger.debug(f"compatible: {compatible}") + chosen = None + if node in path2chosen: + chosen = path2chosen[node] + logger.debug(f" chosen: {chosen}") + for c in compatible: + underscored = c.replace(",", "_").replace("-", "_") + driver = COMPAT_TO_DRIVER.get(underscored, None) + if not driver: + driver = MANUAL_COMPAT_TO_DRIVER.get(underscored, None) + logger.debug(f" {c} -> {underscored} -> {driver}") + if not driver or status != "okay": + continue + if driver == "flash": + pass # Handled by find_flash_devices() + elif driver == "usb/udc" or "zephyr_udc0" in node.labels: + board_info["usb_device"] = True + props = node.props + if "num-bidir-endpoints" not in props: + props = node.parent.props + usb_num_endpoint_pairs = 0 + if "num-bidir-endpoints" in props: + usb_num_endpoint_pairs = props["num-bidir-endpoints"].to_num() + single_direction_endpoints = [] + for d in ("in", "out"): + eps = f"num-{d}-endpoints" + single_direction_endpoints.append(props[eps].to_num() if eps in props else 0) + # Count separate in/out pairs as bidirectional. + usb_num_endpoint_pairs += min(single_direction_endpoints) + elif driver.startswith("wifi"): + board_info["wifi"] = True + elif driver == "bluetooth/hci": + ble_hardware_present = True + elif driver in AUDIOBUSIO_CLASSES: + # audiobusio driver (i2s, audio/dmic) + board_info["audiobusio"] = True + logger.info(f"Supported audiobusio driver: {driver}") + if driver not in active_zephyr_devices: + active_zephyr_devices[driver] = [] + active_zephyr_devices[driver].append(node.labels) + elif driver in EXCEPTIONAL_DRIVERS: + pass + elif driver in BUSIO_CLASSES: + # busio driver (i2c, spi, uart) + board_info["busio"] = True + logger.info(f"Supported busio driver: {driver}") + if driver not in active_zephyr_devices: + active_zephyr_devices[driver] = [] + active_zephyr_devices[driver].append(node.labels) + else: + logger.warning(f"Unsupported driver: {driver}") + + if gpio: + if "ngpios" in node.props: + ngpios = node.props["ngpios"].to_num() + else: + ngpios = 32 + all_ioports.append(node.labels[0]) + if status == "okay": + ioports[node.labels[0]] = set(range(0, ngpios)) + if gpio_map and compatible and compatible[0] != "gpio-nexus": + connector_pins = CONNECTORS.get(compatible[0], None) + if connector_pins is None: + logger.warning(f"Unsupported connector mapping compatible: {compatible[0]}") + else: + i = 0 + for offset, t, label in gpio_map._markers: + if not label: + continue + if i >= len(connector_pins): + logger.warning( + f"Connector mapping for {compatible[0]} has more pins than names; " + f"stopping at {len(connector_pins)}" + ) + break + num = int.from_bytes(gpio_map.value[offset + 4 : offset + 8], "big") + if (label, num) not in board_names: + board_names[(label, num)] = [] + pin_entry = connector_pins[i] + if isinstance(pin_entry, list): + board_names[(label, num)].extend(pin_entry) + else: + board_names[(label, num)].append(pin_entry) + i += 1 + if "gpio-leds" in compatible: + for led in node.nodes: + led = node.nodes[led] + props = led.props + ioport = props["gpios"]._markers[1][2] + num = int.from_bytes(props["gpios"].value[4:8], "big") + flags = int.from_bytes(props["gpios"].value[8:12], "big") + if "label" in props: + if (ioport, num) not in board_names: + board_names[(ioport, num)] = [] + board_names[(ioport, num)].append(props["label"].to_string()) + if led in node2alias: + if (ioport, num) not in board_names: + board_names[(ioport, num)] = [] + if "led0" in node2alias[led]: + board_names[(ioport, num)].append("LED") + status_led = (ioport, num) + status_led_inverted = flags & GPIO_ACTIVE_LOW + board_names[(ioport, num)].extend(node2alias[led]) + + if "gpio-keys" in compatible: + for key in node.nodes: + props = node.nodes[key].props + ioport = props["gpios"]._markers[1][2] + num = int.from_bytes(props["gpios"].value[4:8], "big") + + if (ioport, num) not in board_names: + board_names[(ioport, num)] = [] + # `label` is optional and deprecated on gpio-keys. Modern + # boards identify keys with `zephyr,code`, so fall back to the + # name of that code. + if "label" in props: + board_names[(ioport, num)].append(props["label"].to_string()) + elif "zephyr,code" in props: + key_code = props["zephyr,code"].to_num() + if key_code in INPUT_KEY_NAMES: + board_names[(ioport, num)].append(INPUT_KEY_NAMES[key_code]) + if key in node2alias: + if "sw0" in node2alias[key]: + board_names[(ioport, num)].append("BUTTON") + board_names[(ioport, num)].extend(node2alias[key]) + + if len(all_ioports) > 1: + a, b = all_ioports[:2] + i = 0 + max_i = min(len(a), len(b)) + while i < max_i and a[i] == b[i]: + i += 1 + shared_prefix = a[:i] + for ioport in ioports: + if not ioport.startswith(shared_prefix): + shared_prefix = "" + break + elif all_ioports: + shared_prefix = all_ioports[0] + else: + shared_prefix = "" + + pin_defs = [] + pin_declarations = ["#pragma once"] + mcu_pin_mapping = [] + board_pin_mapping = [] + for ioport in sorted(ioports.keys()): + for num in ioports[ioport]: + pin_object_name = f"P{ioport[len(shared_prefix) :].upper()}_{num:02d}" + if status_led and (ioport, num) == status_led: + status_led = pin_object_name + pin_defs.append( + f"const mcu_pin_obj_t pin_{pin_object_name} = {{ .base.type = &mcu_pin_type, .port = DEVICE_DT_GET(DT_NODELABEL({ioport})), .number = {num}}};" + ) + pin_declarations.append(f"extern const mcu_pin_obj_t pin_{pin_object_name};") + mcu_pin_mapping.append( + f"{{ MP_ROM_QSTR(MP_QSTR_{pin_object_name}), MP_ROM_PTR(&pin_{pin_object_name}) }}," + ) + board_pin_names = board_names.get((ioport, num), []) + + for board_pin_name in board_pin_names: + board_pin_name = ( + board_pin_name.upper() + .replace(" ", "_") + .replace("-", "_") + .replace("(", "") + .replace(")", "") + ) + board_pin_mapping.append( + f"{{ MP_ROM_QSTR(MP_QSTR_{board_pin_name}), MP_ROM_PTR(&pin_{pin_object_name}) }}," + ) + + pin_defs = "\n".join(pin_defs) + pin_declarations = "\n".join(pin_declarations) + board_pin_mapping = "\n ".join(board_pin_mapping) + mcu_pin_mapping = "\n ".join(mcu_pin_mapping) + + zephyr_binding_headers = [] + zephyr_binding_objects = [] + zephyr_binding_labels = [] + i2sout_instance_names = [] + for driver, instances in active_zephyr_devices.items(): + # Determine if this is busio or audiobusio + if driver in BUSIO_CLASSES: + module = "busio" + driverclass = BUSIO_CLASSES[driver] + elif driver in AUDIOBUSIO_CLASSES: + module = "audiobusio" + driverclass = AUDIOBUSIO_CLASSES[driver] + else: + continue + + zephyr_binding_headers.append(f'#include "shared-bindings/{module}/{driverclass}.h"') + + # Designate a main device such as board.I2C or board.I2S. + if len(instances) == 1: + instances[0].append(driverclass) + else: + # Check to see if a main device has already been designated + found_main = False + for labels in instances: + for label in labels: + if label == driverclass: + found_main = True + if not found_main: + for priority_label in (f"zephyr_{driver}", f"arduino_{driver}"): + for labels in instances: + if priority_label in labels: + labels.append(driverclass) + found_main = True + break + if found_main: + break + for labels in instances: + instance_name = f"{driver.replace('/', '_')}_{labels[0]}" + c_function_name = f"_{instance_name}" + singleton_ptr = f"{c_function_name}_singleton" + function_object = f"{c_function_name}_obj" + obj_type = f"{module}_{driverclass.lower()}" + + # Handle special cases for different drivers + if driver == "serial": + # UART needs a receiver buffer + buffer_decl = f"static byte {instance_name}_buffer[128];" + construct_call = f"common_hal_busio_uart_construct_from_device(&{instance_name}_obj, DEVICE_DT_GET(DT_NODELABEL({labels[0]})), 128, {instance_name}_buffer)" + else: + # Default case (I2C, SPI, I2S) + buffer_decl = "" + construct_call = f"common_hal_{module}_{driverclass.lower()}_construct_from_device(&{instance_name}_obj, DEVICE_DT_GET(DT_NODELABEL({labels[0]})))" + + if driver == "i2s": + i2sout_instance_names.append(instance_name) + + zephyr_binding_objects.append( + f"""{buffer_decl} +static {obj_type}_obj_t {instance_name}_obj; +static mp_obj_t {singleton_ptr} = mp_const_none; +static mp_obj_t {c_function_name}(void) {{ + if ({singleton_ptr} != mp_const_none) {{ + return {singleton_ptr}; + }} + {singleton_ptr} = {construct_call}; + return {singleton_ptr}; +}} +static MP_DEFINE_CONST_FUN_OBJ_0({function_object}, {c_function_name});""".lstrip() + ) + for label in labels: + zephyr_binding_labels.append( + f"{{ MP_ROM_QSTR(MP_QSTR_{label.upper()}), MP_ROM_PTR(&{function_object}) }}," + ) + zephyr_binding_headers = "\n".join(zephyr_binding_headers) + zephyr_binding_objects = "\n".join(zephyr_binding_objects) + zephyr_binding_labels = "\n".join(zephyr_binding_labels) + + # Generate i2sout_reset() that stops all board I2SOut instances + if i2sout_instance_names: + stop_calls = "\n ".join( + f"common_hal_audiobusio_i2sout_stop(&{name}_obj);" for name in i2sout_instance_names + ) + i2sout_reset_func = f""" +void i2sout_reset(void) {{ + {stop_calls} +}}""" + else: + i2sout_reset_func = "" + + zephyr_display_header = "" + zephyr_display_object = "" + zephyr_display_board_entry = "" + if board_info.get("zephyr_display", False): + zephyr_display_header = """ +#include +#include +#include "shared-module/displayio/__init__.h" +#include "bindings/zephyr_display/Display.h" + """.strip() + zephyr_display_object = """ +void board_init(void) { +#if CIRCUITPY_ZEPHYR_DISPLAY && DT_HAS_CHOSEN(zephyr_display) + // Always allocate a display slot so board.DISPLAY is at least a valid + // NoneType object even if the underlying Zephyr display is unavailable. + primary_display_t *display_obj = allocate_display(); + if (display_obj == NULL) { + return; + } + + zephyr_display_display_obj_t *display = &display_obj->zephyr_display; + display->base.type = &mp_type_NoneType; + + const struct device *display_dev = device_get_binding(DEVICE_DT_NAME(DT_CHOSEN(zephyr_display))); + if (display_dev == NULL || !device_is_ready(display_dev)) { + return; + } + + display->base.type = &zephyr_display_display_type; + common_hal_zephyr_display_display_construct_from_device(display, display_dev, 0, true); +#endif +} + """.strip() + zephyr_display_board_entry = ( + "{ MP_ROM_QSTR(MP_QSTR_DISPLAY), MP_ROM_PTR(&displays[0].zephyr_display) }," + ) + + board_dir.mkdir(exist_ok=True, parents=True) + header = board_dir / "mpconfigboard.h" + if status_led: + status_led = f"#define MICROPY_HW_LED_STATUS (&pin_{status_led})\n" + status_led_inverted = ( + f"#define MICROPY_HW_LED_STATUS_INVERTED ({'1' if status_led_inverted else '0'})\n" + ) + else: + status_led = "" + status_led_inverted = "" + ram_list = [] + ram_externs = [] + max_size = 0 + for ram in rams: + device, start, end, size, path = ram + max_size = max(max_size, size) + # We always start at the end of a Zephyr linker section so we need the externs and &. + # Native/simulated boards don't have real memory-mapped RAM, so we allocate static arrays. + if board_id in ["native_sim"] or "bsim" in board_id: + ram_externs.append("// This is a native board so we provide all of RAM for our heaps.") + ram_externs.append(f"static uint32_t _{device}[{size // 4}]; // {path}") + start = f"(const uint32_t *) (_{device})" + end = f"(const uint32_t *)(_{device} + {size // 4})" + else: + ram_externs.append(f"extern uint32_t {start};") + start = "&" + start + ram_list.append(f" {start}, {end}, // {path}") + ram_list = "\n".join(ram_list) + ram_externs = "\n".join(ram_externs) + + flashes = [f"DEVICE_DT_GET(DT_NODELABEL({flash}))" for flash in flashes] + + new_header_content = f"""#pragma once + +#define MICROPY_HW_BOARD_NAME "{board_name}" +#define MICROPY_HW_MCU_NAME "{soc_name}" +#define CIRCUITPY_RAM_DEVICE_COUNT {len(rams)} +{status_led} +{status_led_inverted} + """ + if not header.exists() or header.read_text() != new_header_content: + header.write_text(new_header_content) + + pins = board_dir / "autogen-pins.h" + if not pins.exists() or pins.read_text() != pin_declarations: + pins.write_text(pin_declarations) + + board_c = board_dir / "board.c" + hostnetwork_include = "" + hostnetwork_entry = "" + if board_info.get("hostnetwork", False): + hostnetwork_include = ( + '#if CIRCUITPY_HOSTNETWORK\n#include "bindings/hostnetwork/__init__.h"\n#endif\n' + ) + hostnetwork_entry = ( + "#if CIRCUITPY_HOSTNETWORK\n" + " { MP_ROM_QSTR(MP_QSTR_NETWORK), MP_ROM_PTR(&common_hal_hostnetwork_obj) },\n" + "#endif\n" + ) + + new_board_c_content = f""" + // This file is autogenerated by build_circuitpython.py + +#include "shared-bindings/board/__init__.h" + +{hostnetwork_include} + +#include + +#include "py/obj.h" +#include "py/mphal.h" + +{zephyr_binding_headers} +{zephyr_display_header} + +const struct device* const flashes[] = {{ {", ".join(flashes)} }}; +const int circuitpy_flash_device_count = {len(flashes)}; + +{ram_externs} +const uint32_t* const ram_bounds[] = {{ +{ram_list} +}}; +const size_t circuitpy_max_ram_size = {max_size}; + +{pin_defs} + +{zephyr_binding_objects} +{zephyr_display_object} +{i2sout_reset_func} + +static const mp_rom_map_elem_t mcu_pin_globals_table[] = {{ +{mcu_pin_mapping} +}}; +MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_globals_table); + +static const mp_rom_map_elem_t board_module_globals_table[] = {{ +CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS + +{hostnetwork_entry} +{zephyr_display_board_entry} +{board_pin_mapping} + +{zephyr_binding_labels} + +}}; + +MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table); +""" + board_c.write_text(new_board_c_content) + if ble_hardware_present: + if not config_present: + raise RuntimeError( + "Missing Zephyr .config; CONFIG_BT must be set explicitly when BLE hardware is present." + ) + if not config_bt_found: + raise RuntimeError( + "CONFIG_BT is missing from Zephyr .config; set it explicitly when BLE hardware is present." + ) + + board_info["_bleio"] = ble_hardware_present and config_bt_enabled + board_info["source_files"] = [board_c] + board_info["cflags"] = ("-I", board_dir) + board_info["flash_count"] = len(flashes) + board_info["rotaryio"] = bool(ioports) + board_info["usb_num_endpoint_pairs"] = usb_num_endpoint_pairs + + # Detect NVM partition from the device tree. + nvm_node = device_tree.label2node.get("nvm_partition") + board_info["nvm"] = nvm_node is not None + + return board_info diff --git a/ports/zephyr-cp/debug.conf b/ports/zephyr-cp/debug.conf new file mode 100644 index 00000000000..ab6ae95d416 --- /dev/null +++ b/ports/zephyr-cp/debug.conf @@ -0,0 +1,45 @@ +CONFIG_DEBUG=y +CONFIG_DEBUG_OPTIMIZATIONS=y +CONFIG_LOG_MAX_LEVEL=4 + +CONFIG_STACK_SENTINEL=y +CONFIG_DEBUG_THREAD_INFO=y +CONFIG_EXCEPTION_STACK_TRACE=y + +CONFIG_ASSERT=y +CONFIG_LOG_BLOCK_IN_THREAD=y +CONFIG_FRAME_POINTER=y + +CONFIG_FLASH_LOG_LEVEL_DBG=y +CONFIG_LOG_MODE_IMMEDIATE=y + +# Bluetooth: enable BT host debug logging so success paths print, not just +# LOG_ERR. In particular bt_keys logs "Stored keys for " (LOG_DBG) on a +# successful bt_keys_store(); without this only the failure message +# "Failed to save keys (err -116)" is visible. Also enable the adjacent +# modules (SMP drives pairing, BT_SETTINGS is the NVS backend that returns +# the store err) so the -EALREADY (-116) store-failure context is complete. +CONFIG_BT_KEYS_LOG_LEVEL_DBG=y +CONFIG_BT_SETTINGS_LOG_LEVEL_DBG=y +CONFIG_BT_SMP_LOG_LEVEL_DBG=y + +# Bump stacks for debug build - verbose logging consumes more stack. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 +CONFIG_MAIN_STACK_SIZE=32768 +CONFIG_ISR_STACK_SIZE=4096 +CONFIG_UDC_DWC2_STACK_SIZE=4096 +CONFIG_UDC_NRF_THREAD_STACK_SIZE=4096 +CONFIG_USBD_THREAD_STACK_SIZE=4096 +CONFIG_USBD_MSC_STACK_SIZE=4096 +CONFIG_IDLE_STACK_SIZE=1024 + +# Bluetooth stacks: debug logging + assertions + LOG_MODE_IMMEDIATE consume +# substantial extra stack in the BT host RX workqueue (runs all event callbacks, +# including SMP/pairing) and the long workqueue (deferred SMP/pairing/crypto + +# NVS bond-key store). Zephyr's own SMP/pairing test app +# (tests/bluetooth/tester/prj.conf) uses 4096 for BT_RX_STACK_SIZE. +# (BT_CTLR_RX_PRIO_STACK_SIZE is bumped in the Zephyr controller Kconfig +# default since it's a hidden symbol. BT_HCI_TX/BT_CTLR_RX are also hidden and +# haven't overflowed — left at their defaults.) +CONFIG_BT_RX_STACK_SIZE=4096 +CONFIG_BT_LONG_WQ_STACK_SIZE=4096 diff --git a/ports/zephyr-cp/docs/perfetto-tracing.md b/ports/zephyr-cp/docs/perfetto-tracing.md new file mode 100644 index 00000000000..ff35d361f70 --- /dev/null +++ b/ports/zephyr-cp/docs/perfetto-tracing.md @@ -0,0 +1,150 @@ +# Perfetto Tracing + +The Zephyr port supports Perfetto tracing for performance analysis. This document +describes how to capture, validate, and view traces. + +## Capturing Traces + +Traces are written to `circuitpython.perfetto-trace` in the port directory when +running with tracing enabled (e.g., on native_sim). + +## Validating Traces + +### Using trace_processor + +The Perfetto trace_processor tool can validate and query trace files: + +```bash +~/repos/perfetto/tools/trace_processor circuitpython.perfetto-trace +``` + +This will download the trace_processor binary if needed and open an interactive +SQL shell. If the trace loads successfully, you can query it: + +```sql +SELECT COUNT(*) FROM slice; +``` + +### Using the Perfetto UI + +Open https://ui.perfetto.dev and drag your trace file onto the page. + +## Debugging Invalid Traces + +### Common Error: Packets Skipped Due to Invalid Incremental State + +If trace_processor reports packets being skipped with messages like: + +``` +packet_skipped_seq_needs_incremental_state_invalid +``` + +This means packets have `SEQ_NEEDS_INCREMENTAL_STATE` (value 2) set but no +prior packet set `SEQ_INCREMENTAL_STATE_CLEARED` (value 1) to initialize the +incremental state. + +**Root Cause**: The process descriptor packet (which sets `SEQ_INCREMENTAL_STATE_CLEARED`) +must be emitted before any other trace packets. + +**Diagnosis**: Use protoc to inspect the raw trace: + +```bash +protoc --decode_raw < circuitpython.perfetto-trace | head -100 +``` + +Look for field 13 (sequence_flags) in the first few packets: + +- `13: 1` = SEQ_INCREMENTAL_STATE_CLEARED (good - should be first) +- `13: 2` = SEQ_NEEDS_INCREMENTAL_STATE (requires prior cleared packet) + +A valid trace should have the process descriptor with `13: 1` as one of the +first packets. + +**Fix**: Ensure `perfetto_start()` is called before any trace events are emitted. +The descriptor emit functions in `perfetto_encoder.c` should check: + +```c +if (!started) { + perfetto_start(); +} +``` + +### Analyzing Raw Trace Structure + +To understand the trace structure: + +```bash +# Count total packets +protoc --decode_raw < circuitpython.perfetto-trace | grep -c "^1 {" + +# Find all sequence_flags values +protoc --decode_raw < circuitpython.perfetto-trace | grep "13:" | sort | uniq -c + +# Look for track descriptors (field 60) +protoc --decode_raw < circuitpython.perfetto-trace | grep -A20 "60 {" + +# Look for process descriptors (field 3 inside track_descriptor) +protoc --decode_raw < circuitpython.perfetto-trace | grep -B5 "3 {" +``` + +### Key Protobuf Field Numbers + +TracePacket fields: + +| Field | Description | +|-------|-------------| +| 8 | timestamp | +| 10 | trusted_packet_sequence_id | +| 11 | track_event | +| 12 | interned_data | +| 13 | sequence_flags | +| 60 | track_descriptor | + +TrackDescriptor fields (inside field 60): + +| Field | Description | +|-------|-------------| +| 1 | uuid | +| 2 | name | +| 3 | process (ProcessDescriptor) | +| 4 | thread (ThreadDescriptor) | +| 5 | parent_uuid | + +## Build Verification + +After modifying tracing code, verify the build is updated: + +```bash +# Check source vs object file timestamps +ls -la zephyr/subsys/tracing/perfetto/perfetto_encoder.c +ls -la zephyr/build/zephyr/subsys/tracing/perfetto/CMakeFiles/subsys__tracing__perfetto.dir/perfetto_encoder.c.obj +``` + +The object file timestamp must be newer than the source file timestamp. If not, +rebuild the project before capturing a new trace. + +## Architecture + +The tracing implementation consists of: + +- `perfetto_encoder.c`: Encodes trace packets using nanopb +- `perfetto_top.c`: Implements Zephyr tracing hooks (sys_trace_*) +- `perfetto_encoder.h`: Public API and UUID definitions + +Key UUIDs: + +| Constant | Value | Description | +|----------|-------|-------------| +| PROCESS_UUID | 1 | Root process track | +| ISR_TRACK_UUID | 2 | Interrupt service routine track | +| TRACE_TRACK_UUID | 3 | Top-level trace track | + +### Initialization Flow + +1. `SYS_INIT` calls `perfetto_init()` at POST_KERNEL priority 0 +2. `perfetto_init()` calls `perfetto_encoder_init()` +3. `perfetto_initialized` is set to true +4. Thread hooks start firing +5. First emit function calls `perfetto_start()` +6. `perfetto_start()` emits process descriptor with `SEQ_INCREMENTAL_STATE_CLEARED` +7. Subsequent packets use `SEQ_NEEDS_INCREMENTAL_STATE` diff --git a/ports/zephyr-cp/mpconfigport.h b/ports/zephyr-cp/mpconfigport.h new file mode 100644 index 00000000000..9e7bc62c0fe --- /dev/null +++ b/ports/zephyr-cp/mpconfigport.h @@ -0,0 +1,31 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2015 Glenn Ruben Bakke +// SPDX-FileCopyrightText: Copyright (c) 2019 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// 24kiB stack +#define CIRCUITPY_DEFAULT_STACK_SIZE (24 * 1024) + +#define MICROPY_PY_SYS_PLATFORM "Zephyr" + +#define CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL (1) +#define DIGITALINOUT_INVALID_DRIVE_MODE (1) + +#define CIRCUITPY_DEBUG_TINYUSB 0 + +// NVM size is determined at runtime from the Zephyr partition table. +#define CIRCUITPY_INTERNAL_NVM_SIZE 1 + +// Disable native _Float16 handling for host builds. +#define MICROPY_FLOAT_USE_NATIVE_FLT16 (0) + +#define MICROPY_NLR_THUMB_USE_LONG_JUMP (1) + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +// This also includes mpconfigboard.h. +#include "py/circuitpy_mpconfig.h" diff --git a/ports/zephyr-cp/mphalport.h b/ports/zephyr-cp/mphalport.h new file mode 100644 index 00000000000..ee696a4f043 --- /dev/null +++ b/ports/zephyr-cp/mphalport.h @@ -0,0 +1,24 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2015 Glenn Ruben Bakke +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "shared/runtime/interrupt_char.h" +#include "py/mpconfig.h" +#include "supervisor/shared/tick.h" + +#include + +#define mp_hal_ticks_ms() ((mp_uint_t)supervisor_ticks_ms32()) + +static inline void mp_hal_delay_us(mp_uint_t us) { + k_busy_wait((uint32_t)us); +} + +bool mp_hal_stdin_any(void); diff --git a/ports/zephyr-cp/native_sim_build_Containerfile b/ports/zephyr-cp/native_sim_build_Containerfile new file mode 100644 index 00000000000..3cd1a677da3 --- /dev/null +++ b/ports/zephyr-cp/native_sim_build_Containerfile @@ -0,0 +1,40 @@ +FROM ubuntu:24.04 +ENV DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC +ENV PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig + +RUN dpkg --add-architecture i386 && apt-get update && apt-get install -y --no-install-recommends \ + git cmake ninja-build gperf ccache dfu-util device-tree-compiler \ + wget python3 python3-dev python3-pip python3-venv python3-setuptools \ + python3-tk python3-wheel xz-utils file make gcc \ + gcc-multilib g++-multilib libc6-dev-i386 \ + libsdl2-dev:i386 libsdl2-image-dev:i386 \ + libmagic1 mtools pkg-config ca-certificates unzip \ + protobuf-compiler sudo \ + && rm -rf /var/lib/apt/lists/* + +# Remove the default ubuntu:24.04 'ubuntu' user (UID 1000) so 'dev' can take +# UID 1000 — required for --userns=keep-id to map host UID 1000 to 'dev'. +RUN userdel -r ubuntu 2>/dev/null || true \ + && useradd -m -u 1000 -s /bin/bash dev \ + && echo 'dev ALL=(ALL) NOPASSWD:ALL' > /etc/sudoers.d/dev \ + && chmod 440 /etc/sudoers.d/dev +USER dev +WORKDIR /home/dev + +RUN python3 -m venv /home/dev/.venv +ENV PATH="/home/dev/.venv/bin:${PATH}" +RUN pip install --no-cache-dir west pytest pyelftools pyyaml intelhex protobuf grpcio-tools + +# The repo is expected to be bind-mounted here at runtime: +# podman run -v ~/circuitpython:/home/dev/circuitpython:Z --userns=keep-id ... +# On first run, inside the container do: +# cd ~/circuitpython/ports/zephyr-cp +# west init -l zephyr-config +# west update +# west zephyr-export +# pip install -r zephyr/scripts/requirements.txt +# pip install -r ../../requirements-dev.txt +# west sdk install -t x86_64-zephyr-elf +# python ../../tools/ci_fetch_deps.py zephyr-cp +WORKDIR /home/dev/circuitpython/ports/zephyr-cp +CMD ["/bin/bash"] diff --git a/ports/zephyr-cp/native_sim_build_init_container.sh b/ports/zephyr-cp/native_sim_build_init_container.sh new file mode 100755 index 00000000000..19831e1fcc2 --- /dev/null +++ b/ports/zephyr-cp/native_sim_build_init_container.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash +# One-time setup to run INSIDE the zephyr-cp-dev container on the first +# launch against a fresh bind-mounted circuitpython checkout. +# +# Usage (inside the container): +# cd ~/circuitpython/ports/zephyr-cp +# ./native_sim_build_init_container.sh +# +# Safe to re-run; west/pip/etc. are idempotent. +set -euo pipefail + +git config --global --add safe.directory /home/dev/circuitpython + +cd "$(dirname "${BASH_SOURCE[0]}")" + +echo "==> west init" +if [ ! -d .west ]; then + west init -l zephyr-config +else + echo " (already initialized, skipping)" +fi + +echo "==> west update" +west update + +echo "==> west zephyr-export" +west zephyr-export + +echo "==> pip install Zephyr requirements" +pip install -r zephyr/scripts/requirements.txt + +echo "==> pip install CircuitPython dev requirements" +pip install -r ../../requirements-dev.txt + +echo "==> west sdk install (x86_64-zephyr-elf)" +west sdk install -t x86_64-zephyr-elf + +echo "==> fetch port submodules" +python ../../tools/ci_fetch_deps.py zephyr-cp + +echo +echo "First-run setup complete." +echo "You can now build with: make BOARD=native_native_sim" diff --git a/ports/zephyr-cp/native_sim_build_run_container.sh b/ports/zephyr-cp/native_sim_build_run_container.sh new file mode 100755 index 00000000000..e30aca22b46 --- /dev/null +++ b/ports/zephyr-cp/native_sim_build_run_container.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# Launch (or re-attach to) the zephyr-cp-dev container with the enclosing +# circuitpython checkout bind-mounted at /home/dev/circuitpython. Works from +# any CWD — the mount is resolved relative to this script's location. +# +# On first invocation, creates a persistent container named "zcp". On +# subsequent invocations, re-starts the same container so installed state +# (e.g. the Zephyr SDK under /home/dev/zephyr-sdk-*) survives across sessions. +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +CONTAINER_NAME="zcp" +IMAGE="zephyr-cp-dev" + +if podman container exists "$CONTAINER_NAME"; then + exec podman start -ai "$CONTAINER_NAME" +else + exec podman run -it --name "$CONTAINER_NAME" \ + -v "$REPO_ROOT:/home/dev/circuitpython:Z" \ + --userns=keep-id \ + "$IMAGE" "$@" +fi diff --git a/ports/zephyr-cp/native_sim_i2c_emul_control.c b/ports/zephyr-cp/native_sim_i2c_emul_control.c new file mode 100644 index 00000000000..de467122a7b --- /dev/null +++ b/ports/zephyr-cp/native_sim_i2c_emul_control.c @@ -0,0 +1,169 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Command-line control for enabling/disabling emulated I2C devices + * on native_sim. This allows testing device hot-plug and error scenarios. + */ + +#include +#include +#include +#include +#include +#include + +#include "nsi_cmdline.h" +#include "posix_native_task.h" + +LOG_MODULE_REGISTER(i2c_emul_control, LOG_LEVEL_INF); + +#define MAX_DISABLED_DEVICES 16 + +struct disabled_device { + const char *name; + const struct emul *emul; + struct i2c_emul_api mock_api; + bool disabled; +}; + +static struct disabled_device disabled_devices[MAX_DISABLED_DEVICES]; +static int num_disabled_devices = 0; + +static char *disabled_device_args[MAX_DISABLED_DEVICES]; +static int num_disabled_device_args = 0; + +/* + * Mock transfer function that returns -EIO (NACK) when device is disabled, + * or -ENOSYS to fall back to the real emulator. + */ +static int disabled_device_transfer(const struct emul *target, + struct i2c_msg *msgs, + int num_msgs, + int addr) { + ARG_UNUSED(msgs); + ARG_UNUSED(num_msgs); + ARG_UNUSED(addr); + + for (int i = 0; i < num_disabled_devices; i++) { + if (disabled_devices[i].emul == target) { + if (disabled_devices[i].disabled) { + LOG_DBG("Device %s is disabled, returning -EIO", + disabled_devices[i].name); + return -EIO; + } + break; + } + } + /* Fall back to normal emulator behavior */ + return -ENOSYS; +} + +int i2c_emul_control_disable_device(const char *name) { + const struct emul *emul = emul_get_binding(name); + if (!emul) { + LOG_ERR("Emulator '%s' not found", name); + return -ENODEV; + } + + if (emul->bus_type != EMUL_BUS_TYPE_I2C) { + LOG_ERR("Emulator '%s' is not an I2C device", name); + return -EINVAL; + } + + /* Find existing entry or create new one */ + int idx = -1; + for (int i = 0; i < num_disabled_devices; i++) { + if (disabled_devices[i].emul == emul) { + idx = i; + break; + } + } + + if (idx < 0) { + if (num_disabled_devices >= MAX_DISABLED_DEVICES) { + LOG_ERR("Too many disabled devices"); + return -ENOMEM; + } + idx = num_disabled_devices++; + disabled_devices[idx].name = name; + disabled_devices[idx].emul = emul; + disabled_devices[idx].mock_api.transfer = disabled_device_transfer; + + /* Install our mock_api to intercept transfers */ + emul->bus.i2c->mock_api = &disabled_devices[idx].mock_api; + } + + disabled_devices[idx].disabled = true; + LOG_INF("Disabled I2C emulator: %s", name); + return 0; +} + +int i2c_emul_control_enable_device(const char *name) { + for (int i = 0; i < num_disabled_devices; i++) { + if (strcmp(disabled_devices[i].name, name) == 0) { + disabled_devices[i].disabled = false; + LOG_INF("Enabled I2C emulator: %s", name); + return 0; + } + } + LOG_ERR("Device '%s' not in disabled list", name); + return -ENODEV; +} + +bool i2c_emul_control_is_disabled(const char *name) { + for (int i = 0; i < num_disabled_devices; i++) { + if (strcmp(disabled_devices[i].name, name) == 0) { + return disabled_devices[i].disabled; + } + } + return false; +} + +/* Command-line option handler */ +static void cmd_disable_i2c_device(char *argv, int offset) { + /* The value is at argv + offset (after the '=' in --disable-i2c=value) */ + char *value = argv + offset; + if (num_disabled_device_args < MAX_DISABLED_DEVICES) { + disabled_device_args[num_disabled_device_args++] = value; + } else { + printk("i2c_emul_control: Too many --disable-i2c arguments, ignoring: %s\n", value); + } +} + +static struct args_struct_t i2c_emul_args[] = { + { + .option = "disable-i2c", + .name = "device", + .type = 's', + .call_when_found = cmd_disable_i2c_device, + .descript = "Disable an emulated I2C device by name (can be repeated). " + "Example: --disable-i2c=bmi160" + }, + ARG_TABLE_ENDMARKER +}; + +static void register_cmdline_opts(void) { + nsi_add_command_line_opts(i2c_emul_args); +} + +/* Register command-line options early in boot */ +NATIVE_TASK(register_cmdline_opts, PRE_BOOT_1, 0); + +static int apply_disabled_devices(void) { + LOG_DBG("Applying %d disabled device(s)", num_disabled_device_args); + for (int i = 0; i < num_disabled_device_args; i++) { + int rc = i2c_emul_control_disable_device(disabled_device_args[i]); + if (rc != 0) { + LOG_WRN("Failed to disable I2C device '%s': %d", + disabled_device_args[i], rc); + } + } + return 0; +} + +/* + * Apply after emulators are initialized. + * I2C emulators are registered at POST_KERNEL level, so we need to run + * at APPLICATION level to ensure they exist. + */ +SYS_INIT(apply_disabled_devices, APPLICATION, 99); diff --git a/ports/zephyr-cp/prj.conf b/ports/zephyr-cp/prj.conf new file mode 100644 index 00000000000..abefcb199b9 --- /dev/null +++ b/ports/zephyr-cp/prj.conf @@ -0,0 +1,71 @@ +CONFIG_SYS_HEAP_RUNTIME_STATS=n +CONFIG_FLASH=y +CONFIG_FLASH_MAP=y +CONFIG_USE_DT_CODE_PARTITION=y + +CONFIG_DYNAMIC_INTERRUPTS=y +CONFIG_UART_INTERRUPT_DRIVEN=y + +CONFIG_FLASH_MAP_LABELS=y +CONFIG_MAIN_STACK_SIZE=24288 + +# The system workqueue is used by BT settings delayed store (NVS flash writes +# during bond key save). RRAM flash drivers on nRF54L need more than the +# default 1024 bytes to avoid stack overflow. +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=3072 + +CONFIG_THREAD_STACK_INFO=y +CONFIG_ARCH_POSIX_UPDATE_STACK_INFO=y +CONFIG_STACK_SENTINEL=n +CONFIG_DEBUG_THREAD_INFO=n +CONFIG_EXCEPTION_STACK_TRACE=n + +CONFIG_USB_DEVICE_STACK_NEXT=y +CONFIG_USBD_CDC_ACM_CLASS=y +CONFIG_USBD_HID_SUPPORT=y +CONFIG_USBD_MSC_STACK_SIZE=1536 +CONFIG_CDC_ACM_SERIAL_INITIALIZE_AT_BOOT=n + +CONFIG_USBD_MSC_CLASS=y +CONFIG_USBD_MSC_LUNS_PER_INSTANCE=1 + +CONFIG_HWINFO=y +CONFIG_REBOOT=y +CONFIG_ASSERT=n +CONFIG_LOG_BLOCK_IN_THREAD=y + +CONFIG_EVENTS=y + +CONFIG_SERIAL=y + +CONFIG_LOG=y +CONFIG_LOG_MAX_LEVEL=2 +CONFIG_FRAME_POINTER=n + +CONFIG_NET_HOSTNAME_ENABLE=y +CONFIG_NET_HOSTNAME_DYNAMIC=y +CONFIG_NET_HOSTNAME="circuitpython" + +CONFIG_DYNAMIC_THREAD=y +CONFIG_DYNAMIC_THREAD_ALLOC=y +CONFIG_DYNAMIC_THREAD_PREFER_ALLOC=y + +CONFIG_FPU=y + +CONFIG_MBEDTLS=y + +# Override Kconfig default not taking effect +CONFIG_BT_BUF_ACL_RX_SIZE=255 +CONFIG_BT_RX_STACK_SIZE=2048 +CONFIG_BT_LONG_WQ_STACK_SIZE=3072 +CONFIG_MBEDTLS_BUILTIN=y +CONFIG_PSA_CRYPTO=y +CONFIG_PSA_WANT_ALG_SHA_1=y +CONFIG_PSA_WANT_ALG_SHA_256=y + +# Settings storage backend for BT bond keys +# SECTOR_COUNT is set high — the init code caps it to what fits in the storage +# partition: min(sector_count, partition_size / sector_size) +CONFIG_NVS=y +CONFIG_SETTINGS_NVS=y +CONFIG_SETTINGS_NVS_SECTOR_COUNT=256 diff --git a/ports/zephyr-cp/socs/nrf52840.conf b/ports/zephyr-cp/socs/nrf52840.conf new file mode 100644 index 00000000000..bf70997d83f --- /dev/null +++ b/ports/zephyr-cp/socs/nrf52840.conf @@ -0,0 +1,4 @@ + +CONFIG_NRFX_UARTE0=y +CONFIG_NRFX_UARTE1=y +CONFIG_NRFX_POWER=y diff --git a/ports/zephyr-cp/socs/nrf5340_cpuapp.conf b/ports/zephyr-cp/socs/nrf5340_cpuapp.conf new file mode 100644 index 00000000000..734d26db8e9 --- /dev/null +++ b/ports/zephyr-cp/socs/nrf5340_cpuapp.conf @@ -0,0 +1,3 @@ + +CONFIG_NRFX_UARTE=y +CONFIG_NRFX_POWER=y diff --git a/ports/zephyr-cp/socs/nrf5340_cpunet.conf b/ports/zephyr-cp/socs/nrf5340_cpunet.conf new file mode 100644 index 00000000000..a364a3b5b4b --- /dev/null +++ b/ports/zephyr-cp/socs/nrf5340_cpunet.conf @@ -0,0 +1,10 @@ +CONFIG_BT_ISO_PERIPHERAL=n +CONFIG_BT_ISO_CENTRAL=n +CONFIG_BT_ISO_BROADCASTER=n +CONFIG_BT_ISO_SYNC_RECEIVER=n +CONFIG_BT_PER_ADV=n +CONFIG_BT_PER_ADV_SYNC=n +CONFIG_BT_CTLR_ADV_EXT=n + +CONFIG_LOG=n +CONFIG_CONSOLE=n diff --git a/ports/zephyr-cp/socs/r7fa8d1bhecbd.conf b/ports/zephyr-cp/socs/r7fa8d1bhecbd.conf new file mode 100644 index 00000000000..14a93b52ce8 --- /dev/null +++ b/ports/zephyr-cp/socs/r7fa8d1bhecbd.conf @@ -0,0 +1 @@ +CONFIG_MEMC=y diff --git a/ports/zephyr-cp/socs/stm32h7b3xx.conf b/ports/zephyr-cp/socs/stm32h7b3xx.conf new file mode 100644 index 00000000000..14a93b52ce8 --- /dev/null +++ b/ports/zephyr-cp/socs/stm32h7b3xx.conf @@ -0,0 +1 @@ +CONFIG_MEMC=y diff --git a/ports/zephyr-cp/socs/stm32u575xx.conf b/ports/zephyr-cp/socs/stm32u575xx.conf new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/zephyr-cp/supervisor/flash.c b/ports/zephyr-cp/supervisor/flash.c new file mode 100644 index 00000000000..a13bb3cffcb --- /dev/null +++ b/ports/zephyr-cp/supervisor/flash.c @@ -0,0 +1,591 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George +// +// SPDX-License-Identifier: MIT +#include "supervisor/flash.h" + +#include +#include + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/runtime.h" +#include "lib/oofatfs/ff.h" + +#include +#include +#include +#include + +#define CIRCUITPY_PARTITION circuitpy_partition +static const struct flash_area *filesystem_area = NULL; + +#if !FIXED_PARTITION_EXISTS(CIRCUITPY_PARTITION) +static struct flash_area _dynamic_area; +#endif + +// Auto generated in pins.c +extern const struct device *const flashes[]; +extern const int circuitpy_flash_device_count; + +// Size of an erase page. +static size_t _page_size; + +// The value a flash byte has after being erased (usually 0xFF, but can differ). +static uint8_t _erase_value; + +// Number of FILESYSTEM_BLOCK_SIZE blocks in an erase page. +static size_t _blocks_per_page; +static uint32_t _page_mask; + +#define NO_PAGE_LOADED 0xFFFFFFFF + +// The currently cached sector in the cache, ram or flash based. +static uint32_t _current_page_address; + +static uint32_t _scratch_page_address; + +// Per-block flags packed into a uint8_t array (one byte per block). +#define ROW_LOADED 0x01 // Block data is present in the cache. +#define ROW_DIRTY 0x02 // Block has been modified since last flush. +#define ROW_ERASED 0x04 // Block is all 0xFF; no need to write after erase. + +static uint8_t *_row_flags = NULL; + +static inline void _clear_row_flags(void) { + if (_row_flags != NULL) { + memset(_row_flags, 0, _blocks_per_page); + } +} + +static inline bool _any_dirty(void) { + for (size_t i = 0; i < _blocks_per_page; i++) { + if (_row_flags[i] & ROW_DIRTY) { + return true; + } + } + return false; +} + +// Check if a buffer is entirely the erase value. +static bool _buffer_is_erased(const uint8_t *buf, size_t len) { + for (size_t i = 0; i < len; i++) { + if (buf[i] != _erase_value) { + return false; + } + } + return true; +} + +// Table of pointers to each cached block. Should be zero'd after allocation. +#define FLASH_CACHE_TABLE_NUM_ENTRIES (_blocks_per_page) +#define FLASH_CACHE_TABLE_SIZE (FLASH_CACHE_TABLE_NUM_ENTRIES * sizeof(uint8_t *)) +static uint8_t **flash_cache_table = NULL; + +static K_MUTEX_DEFINE(_mutex); + +static void fa_cb(const struct flash_area *fa, void *user_data) { + bool *covered_by_areas = user_data; + + const char *fa_label = flash_area_label(fa); + + if (fa_label == NULL) { + fa_label = "-"; + } + printk("%s %p %d dev %p\n", fa_label, fa, fa->fa_id, fa->fa_dev); + + for (int i = 0; i < circuitpy_flash_device_count; i++) { + const struct device *d = flashes[i]; + + if (d == fa->fa_dev) { + covered_by_areas[i] = true; + } + } + + uint32_t count = 10; + struct flash_sector sectors[count]; + if (flash_area_get_sectors(fa->fa_id, &count, sectors) != 0) { + printk("Unable to get sectors\n"); + } else { + for (int i = 0; i < count; i++) { + printk(" 0x%lx 0x%x\n", sectors[i].fs_off, sectors[i].fs_size); + } + } +} + +void supervisor_flash_init(void) { + if (filesystem_area != NULL) { + return; + } + + #if FIXED_PARTITION_EXISTS(CIRCUITPY_PARTITION) + int open_res = flash_area_open(FIXED_PARTITION_ID(CIRCUITPY_PARTITION), &filesystem_area); + if (open_res != 0) { + printk("Unable to open CIRCUITPY flash area: %d\n", open_res); + } + #else + // Use spi_nor if it exists and no + // flash_area_open(FIXED_PARTITION_ID(storage_partition), &filesystem_area); + // printk("flash area %d %d\n", filesystem_area->fa_id, filesystem_area->fa_size); + printk("hello from flash init\n"); + bool covered_by_areas[circuitpy_flash_device_count]; + flash_area_foreach(fa_cb, covered_by_areas); + for (int i = 0; i < circuitpy_flash_device_count; i++) { + const struct device *d = flashes[i]; + + printk("flash %p %s\n", d, d->name); + if (!device_is_ready(d)) { + printk(" not ready\n"); + continue; + } + if (covered_by_areas[i]) { + printk(" covered by flash area\n"); + continue; + } + if (d->api == NULL) { + printk(" no api\n"); + continue; + } + size_t page_count = flash_get_page_count(d); + printk(" %d pages\n", page_count); + if (page_count == 0) { + continue; + } + struct flash_pages_info first_info; + flash_get_page_info_by_idx(d, 0, &first_info); + printk(" page 0: %lx %x\n", first_info.start_offset, first_info.size); + struct flash_pages_info last_info; + flash_get_page_info_by_idx(d, page_count - 1, &last_info); + printk(" page %d: %lx %x\n", page_count - 1, last_info.start_offset, last_info.size); + + // Assume uniform page sizes if the first and last are the same size. + size_t uniform_page_count; + if (first_info.size == last_info.size) { + uniform_page_count = page_count; + } else { + for (size_t i = 1; i < page_count; i++) { + struct flash_pages_info info; + flash_get_page_info_by_idx(d, i, &info); + if (info.size != first_info.size) { + uniform_page_count = i; + break; + } + } + } + if (uniform_page_count * first_info.size < 64 * 1024) { + printk("Uniform region too small\n"); + continue; + } + + printk(" %d uniform pages\n", uniform_page_count); + _page_size = first_info.size; + + _dynamic_area.fa_dev = d; + _dynamic_area.fa_id = 0; + _dynamic_area.fa_off = 0; + _dynamic_area.fa_size = uniform_page_count * first_info.size; + filesystem_area = &_dynamic_area; + printk("setup flash\n"); + break; + } + #endif + if (filesystem_area == NULL) { + printk("no flash found for filesystem\n"); + return; + } + + struct flash_pages_info first_info; + const struct device *d = flash_area_get_device(filesystem_area); + const struct flash_parameters *fp = flash_get_parameters(d); + _erase_value = fp->erase_value; + flash_get_page_info_by_offs(d, filesystem_area->fa_off, &first_info); + struct flash_pages_info last_info; + flash_get_page_info_by_offs(d, filesystem_area->fa_off + filesystem_area->fa_size - FILESYSTEM_BLOCK_SIZE, &last_info); + _page_size = first_info.size; + if (_page_size < FILESYSTEM_BLOCK_SIZE) { + _page_size = FILESYSTEM_BLOCK_SIZE; + } + _blocks_per_page = _page_size / FILESYSTEM_BLOCK_SIZE; + _page_mask = ~(_page_size - 1); + printk(" erase page size %d\n", _page_size); + printk(" blocks per page %d\n", _blocks_per_page); + + _row_flags = port_malloc(_blocks_per_page, false); + if (_row_flags == NULL) { + printk("Unable to allocate row flags (%d bytes)\n", _blocks_per_page); + filesystem_area = NULL; + return; + } + memset(_row_flags, 0, _blocks_per_page); + + // The last page is the scratch sector. + _scratch_page_address = last_info.start_offset - filesystem_area->fa_off; + _current_page_address = NO_PAGE_LOADED; +} + +uint32_t supervisor_flash_get_block_size(void) { + return FILESYSTEM_BLOCK_SIZE; +} + +uint32_t supervisor_flash_get_block_count(void) { + if (filesystem_area == NULL) { + return 0; + } + return _scratch_page_address / FILESYSTEM_BLOCK_SIZE; +} + + +// Read data_length's worth of bytes starting at address into data. +static bool read_flash(uint32_t address, uint8_t *data, uint32_t data_length) { + int res = flash_area_read(filesystem_area, address, data, data_length); + if (res != 0) { + printk("flash read failed: %d\n", res); + printk(" address %x length %d\n", address, data_length); + } + return res == 0; +} + +// Writes data_length's worth of bytes starting at address from data. Assumes +// that the sector that address resides in has already been erased. So make sure +// to run erase_page. +static bool write_flash(uint32_t address, const uint8_t *data, uint32_t data_length) { + int res = flash_area_write(filesystem_area, address, data, data_length); + if (res != 0) { + printk("flash write failed: %d\n", res); + printk(" address %x length %d\n", address, data_length); + } + return res == 0; +} + +static bool block_erased(uint32_t sector_address) { + uint8_t short_buffer[4]; + if (read_flash(sector_address, short_buffer, 4)) { + if (!_buffer_is_erased(short_buffer, 4)) { + return false; + } + } else { + return false; + } + + // Now check the full length. + uint8_t full_buffer[FILESYSTEM_BLOCK_SIZE]; + if (read_flash(sector_address, full_buffer, FILESYSTEM_BLOCK_SIZE)) { + if (!_buffer_is_erased(full_buffer, FILESYSTEM_BLOCK_SIZE)) { + return false; + } + } else { + return false; + } + return true; +} + +// Erases the given sector. Make sure you copied all of the data out of it you +// need! Also note, sector_address is really 24 bits. +static bool erase_page(uint32_t sector_address) { + int res = flash_area_erase(filesystem_area, sector_address, _page_size); + if (res != 0) { + printk("Erase of %d failed: %d\n", sector_address, res); + } + return res == 0; +} + +static bool copy_block(uint32_t src_address, uint32_t dest_address) { + uint8_t buffer[FILESYSTEM_BLOCK_SIZE]; + if (!read_flash(src_address, buffer, FILESYSTEM_BLOCK_SIZE)) { + return false; + } + if (!write_flash(dest_address, buffer, FILESYSTEM_BLOCK_SIZE)) { + return false; + } + return true; +} + +// Load a block into the ram cache and set its flags. Returns false on read error. +static bool _load_block_into_cache(size_t block_index) { + if (!read_flash(_current_page_address + block_index * FILESYSTEM_BLOCK_SIZE, + flash_cache_table[block_index], FILESYSTEM_BLOCK_SIZE)) { + return false; + } + _row_flags[block_index] |= ROW_LOADED; + if (_buffer_is_erased(flash_cache_table[block_index], FILESYSTEM_BLOCK_SIZE)) { + _row_flags[block_index] |= ROW_ERASED; + } + return true; +} + +// Flush the cache that was written to the scratch portion of flash. Only used +// when ram is tight. +static bool flush_scratch_flash(void) { + if (_current_page_address == NO_PAGE_LOADED) { + return true; + } + // First, copy out any blocks that we haven't touched from the sector we've + // cached. + bool copy_to_scratch_ok = true; + for (size_t i = 0; i < _blocks_per_page; i++) { + if (!(_row_flags[i] & ROW_DIRTY)) { + copy_to_scratch_ok = copy_to_scratch_ok && + copy_block(_current_page_address + i * FILESYSTEM_BLOCK_SIZE, + _scratch_page_address + i * FILESYSTEM_BLOCK_SIZE); + } + _row_flags[i] |= ROW_LOADED; + } + if (!copy_to_scratch_ok) { + // TODO(tannewt): Do more here. We opted to not erase and copy bad data + // in. We still risk losing the data written to the scratch sector. + return false; + } + // Second, erase the current sector. + erase_page(_current_page_address); + // Finally, copy the new version into it. + for (size_t i = 0; i < _blocks_per_page; i++) { + copy_block(_scratch_page_address + i * FILESYSTEM_BLOCK_SIZE, + _current_page_address + i * FILESYSTEM_BLOCK_SIZE); + } + return true; +} + +// Free all entries in the partially or completely filled flash_cache_table, and then free the table itself. +static void release_ram_cache(void) { + if (flash_cache_table == NULL) { + return; + } + + for (size_t i = 0; i < FLASH_CACHE_TABLE_NUM_ENTRIES; i++) { + // Table may not be completely full. Stop at first NULL entry. + if (flash_cache_table[i] == NULL) { + break; + } + port_free(flash_cache_table[i]); + } + port_free(flash_cache_table); + flash_cache_table = NULL; + _current_page_address = NO_PAGE_LOADED; + _clear_row_flags(); +} + +// Attempts to allocate a new set of page buffers for caching a full sector in +// ram. Each page is allocated separately so that the GC doesn't need to provide +// one huge block. We can free it as we write if we want to also. +static bool allocate_ram_cache(void) { + flash_cache_table = port_malloc(FLASH_CACHE_TABLE_SIZE, false); + if (flash_cache_table == NULL) { + printk("Unable to allocate ram cache table\n"); + return false; + } + + // Clear all the entries so it's easy to find the last entry. + memset(flash_cache_table, 0, FLASH_CACHE_TABLE_SIZE); + + bool success = true; + for (size_t i = 0; i < _blocks_per_page && success; i++) { + uint8_t *block_cache = port_malloc(FILESYSTEM_BLOCK_SIZE, false); + if (block_cache == NULL) { + success = false; + break; + } + flash_cache_table[i] = block_cache; + } + + // We couldn't allocate enough so give back what we got. + if (!success) { + printk("Unable to allocate ram cache pages\n"); + release_ram_cache(); + } + _clear_row_flags(); + _current_page_address = NO_PAGE_LOADED; + return success; +} + +// Flush the cached sector from ram onto the flash. We'll free the cache unless +// keep_cache is true. +static bool flush_ram_cache(bool keep_cache) { + if (flash_cache_table == NULL) { + // Nothing to flush because there is no cache. + return true; + } + + if (_current_page_address == NO_PAGE_LOADED || !_any_dirty()) { + if (!keep_cache) { + release_ram_cache(); + } + return true; + } + // First, copy out any blocks that we haven't touched from the sector + // we've cached. If we don't do this we'll erase the data during the sector + // erase below. + bool copy_to_ram_ok = true; + for (size_t i = 0; i < _blocks_per_page; i++) { + if (!(_row_flags[i] & ROW_LOADED)) { + if (!_load_block_into_cache(i)) { + copy_to_ram_ok = false; + break; + } + } + } + + if (!copy_to_ram_ok) { + return false; + } + // Second, erase the current sector. + erase_page(_current_page_address); + // Lastly, write all the data in ram that we've cached. + for (size_t i = 0; i < _blocks_per_page; i++) { + // Skip blocks that are entirely erased — the page erase already + // set them to 0xFF so writing would be redundant. + if (_row_flags[i] & ROW_ERASED) { + continue; + } + write_flash(_current_page_address + i * FILESYSTEM_BLOCK_SIZE, + flash_cache_table[i], + FILESYSTEM_BLOCK_SIZE); + } + // Nothing is dirty anymore. Clear dirty but keep loaded and erased. + for (size_t i = 0; i < _blocks_per_page; i++) { + _row_flags[i] &= ~ROW_DIRTY; + } + + // We're done with the cache for now so give it back. + if (!keep_cache) { + release_ram_cache(); + } + return true; +} + +// Delegates to the correct flash flush method depending on the existing cache. +// TODO Don't blink the status indicator if we don't actually do any writing (hard to tell right now). +static void _flush_keep_cache(bool keep_cache) { + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, true); + #endif + // If we've cached to the flash itself flush from there. + if (flash_cache_table == NULL) { + flush_scratch_flash(); + } else { + flush_ram_cache(keep_cache); + } + #ifdef MICROPY_HW_LED_MSC + port_pin_set_output_level(MICROPY_HW_LED_MSC, false); + #endif +} + +void port_internal_flash_flush(void) { + if (filesystem_area == NULL) { + return; + } + k_mutex_lock(&_mutex, K_FOREVER); + _flush_keep_cache(true); + k_mutex_unlock(&_mutex); +} + +void supervisor_flash_release_cache(void) { + if (filesystem_area == NULL) { + return; + } + k_mutex_lock(&_mutex, K_FOREVER); + _flush_keep_cache(false); + k_mutex_unlock(&_mutex); +} + +static int32_t convert_block_to_flash_addr(uint32_t block) { + if (0 <= block && block < supervisor_flash_get_block_count()) { + // a block in partition 1 + return block * FILESYSTEM_BLOCK_SIZE; + } + // bad block + return -1; +} + +static bool _flash_read_block(uint8_t *dest, uint32_t block) { + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; + } + + // Mask out the lower bits that designate the address within the sector. + uint32_t page_address = address & _page_mask; + size_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % _blocks_per_page; + // We're reading from the currently cached sector. + if (_current_page_address == page_address && (_row_flags[block_index] & ROW_LOADED)) { + if (flash_cache_table != NULL) { + memcpy(dest, flash_cache_table[block_index], FILESYSTEM_BLOCK_SIZE); + return true; + } + uint32_t scratch_block_address = _scratch_page_address + block_index * FILESYSTEM_BLOCK_SIZE; + return read_flash(scratch_block_address, dest, FILESYSTEM_BLOCK_SIZE); + } + return read_flash(address, dest, FILESYSTEM_BLOCK_SIZE); +} + +static bool _flash_write_block(const uint8_t *data, uint32_t block) { + // Non-MBR block, copy to cache + int32_t address = convert_block_to_flash_addr(block); + if (address == -1) { + // bad block number + return false; + } + // Mask out the lower bits that designate the address within the sector. + uint32_t page_address = address & _page_mask; + size_t block_index = (address / FILESYSTEM_BLOCK_SIZE) % _blocks_per_page; + // Flush the cache if we're moving onto a different page. + if (_current_page_address != page_address) { + // Check to see if we'd write to an erased block and aren't writing to + // our cache. In that case we can write directly. + if (block_erased(address)) { + return write_flash(address, data, FILESYSTEM_BLOCK_SIZE); + } + if (_current_page_address != NO_PAGE_LOADED) { + supervisor_flash_flush(); + } + if (flash_cache_table == NULL && !allocate_ram_cache()) { + erase_page(_scratch_page_address); + } + _current_page_address = page_address; + _clear_row_flags(); + } + _row_flags[block_index] = ROW_DIRTY | ROW_LOADED; + // Copy the block to the appropriate cache. + if (flash_cache_table != NULL) { + memcpy(flash_cache_table[block_index], data, FILESYSTEM_BLOCK_SIZE); + return true; + } else { + uint32_t scratch_block_address = _scratch_page_address + block_index * FILESYSTEM_BLOCK_SIZE; + return write_flash(scratch_block_address, data, FILESYSTEM_BLOCK_SIZE); + } +} + +mp_uint_t supervisor_flash_read_blocks(uint8_t *dest, uint32_t block, uint32_t num_blocks) { + if (filesystem_area == NULL) { + return 1; + } + k_mutex_lock(&_mutex, K_FOREVER); + for (size_t i = 0; i < num_blocks; i++) { + if (!_flash_read_block(dest + i * FILESYSTEM_BLOCK_SIZE, block + i)) { + k_mutex_unlock(&_mutex); + printk("error reading block %04d\n", block + i); + return 1; // error + } + } + k_mutex_unlock(&_mutex); + return 0; // success +} + +mp_uint_t supervisor_flash_write_blocks(const uint8_t *src, uint32_t block, uint32_t num_blocks) { + if (filesystem_area == NULL) { + return 1; + } + k_mutex_lock(&_mutex, K_FOREVER); + for (size_t i = 0; i < num_blocks; i++) { + if (!_flash_write_block(src + i * FILESYSTEM_BLOCK_SIZE, block + i)) { + printk("error writing block %04d\n", block + i); + k_mutex_unlock(&_mutex); + return 1; // error + } + } + k_mutex_unlock(&_mutex); + return 0; // success +} diff --git a/ports/zephyr-cp/supervisor/internal_flash.h b/ports/zephyr-cp/supervisor/internal_flash.h new file mode 100644 index 00000000000..32a77a63a9b --- /dev/null +++ b/ports/zephyr-cp/supervisor/internal_flash.h @@ -0,0 +1,14 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2013, 2014 Damien P. George +// +// SPDX-License-Identifier: MIT +#pragma once + +#include +#include + +#include "py/mpconfig.h" + +#define INTERNAL_FLASH_SYSTICK_MASK (0x1ff) // 512ms +#define INTERNAL_FLASH_IDLE_TICK(tick) (((tick) & INTERNAL_FLASH_SYSTICK_MASK) == 2) diff --git a/ports/zephyr-cp/supervisor/port.c b/ports/zephyr-cp/supervisor/port.c new file mode 100644 index 00000000000..1ecde0b0141 --- /dev/null +++ b/ports/zephyr-cp/supervisor/port.c @@ -0,0 +1,398 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/port.h" + +#include "mpconfigboard.h" +#include "supervisor/shared/tick.h" + +#if CIRCUITPY_AUDIOBUSIO_I2SOUT +#include "common-hal/audiobusio/I2SOut.h" +#endif + +#include + +#include +#include +#include +#include + +#if defined(CONFIG_ARCH_POSIX) +#include + +#include "cmdline.h" +#include "posix_board_if.h" +#include "posix_native_task.h" +#endif + +#include "lib/tlsf/tlsf.h" +#include +#include + +#if defined(CONFIG_TRACING_PERFETTO) && defined(CONFIG_BOARD_NATIVE_SIM) +#include "perfetto_encoder.h" +#include +#define CIRCUITPY_PERFETTO_TRACK_GROUP_UUID 0x3000ULL +#define CIRCUITPY_PERFETTO_VM_HEAP_USED_UUID 0x3001ULL +#define CIRCUITPY_PERFETTO_OUTER_HEAP_USED_UUID 0x3002ULL +#endif + +static tlsf_t heap; +static size_t tlsf_heap_used = 0; + +// Auto generated in pins.c +extern const struct device *const rams[]; +extern const uint32_t *const ram_bounds[]; +extern const size_t circuitpy_max_ram_size; + +static pool_t pools[CIRCUITPY_RAM_DEVICE_COUNT]; +static uint8_t valid_pool_count = 0; +static bool zephyr_malloc_active = false; +static void *zephyr_malloc_top = NULL; +static void *zephyr_malloc_bottom = NULL; + +static K_EVENT_DEFINE(main_needed); + +static struct k_timer tick_timer; + +#if defined(CONFIG_ARCH_POSIX) +// Number of VM runs before exiting. +// <= 0 means run forever. +// INT32_MAX means option was not provided. +static int32_t native_sim_vm_runs = INT32_MAX; +static uint32_t native_sim_reset_port_count = 0; + +static struct args_struct_t native_sim_reset_port_args[] = { + { + .option = "vm-runs", + .name = "count", + .type = 'i', + .dest = &native_sim_vm_runs, + .descript = "Exit native_sim after this many VM runs. " + "Example: --vm-runs=2" + }, + ARG_TABLE_ENDMARKER +}; + +static void native_sim_register_cmdline_opts(void) { + native_add_command_line_opts(native_sim_reset_port_args); +} + +NATIVE_TASK(native_sim_register_cmdline_opts, PRE_BOOT_1, 0); +#endif + +#if defined(CONFIG_TRACING_PERFETTO) && defined(CONFIG_BOARD_NATIVE_SIM) +static bool perfetto_circuitpython_tracks_emitted; + +static void perfetto_emit_outer_heap_stats(void) { + if (!perfetto_start()) { + return; + } + size_t total = tlsf_heap_used; + #if defined(CONFIG_COMMON_LIBC_MALLOC) && defined(CONFIG_SYS_HEAP_RUNTIME_STATS) + extern int malloc_runtime_stats_get(struct sys_memory_stats *stats); + struct sys_memory_stats stats; + if (malloc_runtime_stats_get(&stats) == 0) { + total += stats.allocated_bytes; + } + #endif + perfetto_emit_counter(CIRCUITPY_PERFETTO_OUTER_HEAP_USED_UUID, (int64_t)total); + Z_SPIN_DELAY(1); +} + +static void perfetto_emit_circuitpython_tracks(void) { + if (perfetto_circuitpython_tracks_emitted) { + return; + } + if (!perfetto_start()) { + return; + } + perfetto_emit_track_descriptor(CIRCUITPY_PERFETTO_TRACK_GROUP_UUID, + perfetto_get_process_uuid(), + "CircuitPython"); + perfetto_emit_counter_track_descriptor(CIRCUITPY_PERFETTO_VM_HEAP_USED_UUID, + CIRCUITPY_PERFETTO_TRACK_GROUP_UUID, + "VM Heap Used", + PERFETTO_COUNTER_UNIT_BYTES); + perfetto_emit_counter_track_descriptor(CIRCUITPY_PERFETTO_OUTER_HEAP_USED_UUID, + CIRCUITPY_PERFETTO_TRACK_GROUP_UUID, + "Outer Heap Used", + PERFETTO_COUNTER_UNIT_BYTES); + perfetto_circuitpython_tracks_emitted = true; +} +#else +static inline void perfetto_emit_outer_heap_stats(void) { +} + +static inline void perfetto_emit_circuitpython_tracks(void) { +} +#endif + +static void _tick_function(struct k_timer *timer_id) { + supervisor_tick(); +} + +safe_mode_t port_init(void) { + // We run CircuitPython at the lowest priority (just higher than idle.) + // This allows networking and USB to preempt us. + k_thread_priority_set(k_current_get(), CONFIG_NUM_PREEMPT_PRIORITIES - 1); + k_timer_init(&tick_timer, _tick_function, NULL); + perfetto_emit_circuitpython_tracks(); + return SAFE_MODE_NONE; +} + +// Reset the microcontroller completely. +void reset_cpu(void) { + // Try a warm reboot first. It won't return if it works but isn't always + // implemented. + sys_reboot(SYS_REBOOT_WARM); + sys_reboot(SYS_REBOOT_COLD); + printk("Failed to reboot. Looping.\n"); + while (true) { + } +} + +void reset_port(void) { + #if CIRCUITPY_AUDIOBUSIO_I2SOUT + i2sout_reset(); + #endif + + #if defined(CONFIG_ARCH_POSIX) + native_sim_reset_port_count++; + if (native_sim_vm_runs != INT32_MAX && + native_sim_vm_runs > 0 && + native_sim_reset_port_count >= (uint32_t)(native_sim_vm_runs + 1)) { + printk("posix: exiting after %d VM runs\n", native_sim_vm_runs); + posix_exit(0); + } + #endif +} + +void reset_to_bootloader(void) { + reset_cpu(); +} + +void port_wake_main_task(void) { + k_event_set(&main_needed, 1); +} + +void port_wake_main_task_from_isr(void) { + k_event_set(&main_needed, 1); +} + +void port_task_yield(void) { + k_yield(); +} + +void port_task_sleep_ms(uint32_t msecs) { + k_msleep(msecs); +} + +void port_boot_info(void) { +} + +// Get stack limit address +uint32_t *port_stack_get_limit(void) { + return (uint32_t *)k_current_get()->stack_info.start; +} + +// Get stack top address +uint32_t *port_stack_get_top(void) { + _thread_stack_info_t stack_info = k_current_get()->stack_info; + + return (uint32_t *)(stack_info.start + stack_info.size - stack_info.delta); +} + +// Save and retrieve a word from memory that is preserved over reset. Used for safe mode. +void port_set_saved_word(uint32_t) { + +} +uint32_t port_get_saved_word(void) { + return 0; +} + +uint64_t port_get_raw_ticks(uint8_t *subticks) { + // Make sure time advances in the simulator. + #if defined(CONFIG_ARCH_POSIX) + k_busy_wait(100); + #endif + int64_t uptime = k_uptime_ticks() * 32768 / CONFIG_SYS_CLOCK_TICKS_PER_SEC; + if (subticks != NULL) { + *subticks = uptime % 32; + } + return uptime / 32; +} + +// Enable 1/1024 second tick. +void port_enable_tick(void) { + k_timer_start(&tick_timer, K_USEC(1000000 / 1024), K_USEC(1000000 / 1024)); +} + +// Disable 1/1024 second tick. +void port_disable_tick(void) { + k_timer_stop(&tick_timer); +} + +static k_timeout_t next_timeout; +static k_timepoint_t next_timepoint; + +void port_interrupt_after_ticks(uint32_t ticks) { + size_t zephyr_ticks = ticks * CONFIG_SYS_CLOCK_TICKS_PER_SEC / 1024; + k_timeout_t maybe_next_timeout = K_TIMEOUT_ABS_TICKS(k_uptime_ticks() + zephyr_ticks); + k_timepoint_t maybe_next_timepoint = sys_timepoint_calc(maybe_next_timeout); + if (sys_timepoint_cmp(maybe_next_timepoint, next_timepoint) < 0) { + next_timeout = maybe_next_timeout; + next_timepoint = maybe_next_timepoint; + } +} + +void port_idle_until_interrupt(void) { + k_event_wait(&main_needed, 0xffffffff, true, next_timeout); + next_timeout = K_FOREVER; + next_timepoint = sys_timepoint_calc(next_timeout); +} + +// Zephyr doesn't maintain one multi-heap. So, make our own using TLSF. +void port_heap_init(void) { + // Do a test malloc to determine if Zephyr has an outer heap that may + // overlap with a memory region we've identified in ram_bounds. We'll + // corrupt each other if we both use it. + #ifdef CONFIG_COMMON_LIBC_MALLOC + uint32_t *test_malloc = malloc(32); + free(test_malloc); // Free right away so we don't forget. We don't actually write it anyway. + zephyr_malloc_active = test_malloc != NULL; + #endif + + for (size_t i = 0; i < CIRCUITPY_RAM_DEVICE_COUNT; i++) { + uint32_t *heap_bottom = ram_bounds[2 * i]; + uint32_t *heap_top = ram_bounds[2 * i + 1]; + size_t size = (heap_top - heap_bottom) * sizeof(uint32_t); + // The linker script may fill up a region we thought we could use at + // build time. (The ram_bounds values are sometimes determined by the + // linker.) So, we need to guard against regions that aren't actually + // free. + if (size < 1024) { + printk("Skipping region because the linker filled it up.\n"); + continue; + } + #ifdef CONFIG_COMMON_LIBC_MALLOC + // Skip a ram region if our test malloc is within it. We'll use Zephyr's + // malloc to share that space with Zephyr. + if (heap_bottom <= test_malloc && test_malloc < heap_top) { + zephyr_malloc_top = heap_top; + zephyr_malloc_bottom = heap_bottom; + printk("Skipping region because Zephyr malloc is within bounds\n"); + pools[i] = NULL; + continue; + } + #endif + + printk("Init heap at %p - %p with size %d\n", heap_bottom, heap_top, size); + // If this crashes, then make sure you've enabled all of the Kconfig needed for the drivers. + if (valid_pool_count == 0) { + heap = tlsf_create_with_pool(heap_bottom, size, circuitpy_max_ram_size); + pools[i] = tlsf_get_pool(heap); + } else { + pools[i] = tlsf_add_pool(heap, heap_bottom + 1, size - sizeof(uint32_t)); + } + valid_pool_count++; + } + perfetto_emit_outer_heap_stats(); + #if !DT_HAS_CHOSEN(zephyr_sram) + #error "No SRAM!" + #endif +} + +void *port_malloc(size_t size, bool dma_capable) { + void *block = NULL; + if (valid_pool_count > 0) { + block = tlsf_malloc(heap, size); + } + if (block != NULL) { + tlsf_heap_used += tlsf_block_size(block); + } + #ifdef CONFIG_COMMON_LIBC_MALLOC + if (block == NULL) { + block = malloc(size); + } + #endif + if (block != NULL) { + perfetto_emit_outer_heap_stats(); + } + return block; +} + +void port_free(void *ptr) { + if (ptr == NULL) { + return; + } + if (valid_pool_count > 0 && !(ptr >= zephyr_malloc_bottom && ptr < zephyr_malloc_top)) { + tlsf_heap_used -= tlsf_block_size(ptr); + tlsf_free(heap, ptr); + } else { + #ifdef CONFIG_COMMON_LIBC_MALLOC + free(ptr); + #endif + } + perfetto_emit_outer_heap_stats(); +} + +void *port_realloc(void *ptr, size_t size, bool dma_capable) { + if (ptr == NULL) { + return port_malloc(size, dma_capable); + } + if (valid_pool_count > 0 && !(ptr >= zephyr_malloc_bottom && ptr < zephyr_malloc_top)) { + size_t old_size = tlsf_block_size(ptr); + void *new_block = tlsf_realloc(heap, ptr, size); + if (new_block != NULL) { + tlsf_heap_used = tlsf_heap_used - old_size + tlsf_block_size(new_block); + perfetto_emit_outer_heap_stats(); + } + return new_block; + } + #ifdef CONFIG_COMMON_LIBC_MALLOC + void *new_block = realloc(ptr, size); + if (new_block != NULL) { + perfetto_emit_outer_heap_stats(); + } + return new_block; + #endif + return NULL; +} + +static bool max_size_walker(void *ptr, size_t size, int used, void *user) { + size_t *max_size = (size_t *)user; + if (!used && *max_size < size) { + *max_size = size; + } + return true; +} + +size_t port_heap_get_largest_free_size(void) { + size_t max_size = 0; + if (valid_pool_count > 0) { + for (size_t i = 0; i < CIRCUITPY_RAM_DEVICE_COUNT; i++) { + if (pools[i] == NULL) { + continue; + } + tlsf_walk_pool(pools[i], max_size_walker, &max_size); + } + // IDF does this. Not sure why. + return tlsf_fit_size(heap, max_size); + } + return 64 * 1024; +} + +void assert_post_action(const char *file, unsigned int line) { + // printk("Assertion failed at %s:%u\n", file, line); + // Check that this is arm + #if defined(__arm__) + __asm__ ("bkpt"); + #endif + while (1) { + ; + } +} diff --git a/ports/zephyr-cp/supervisor/serial.c b/ports/zephyr-cp/supervisor/serial.c new file mode 100644 index 00000000000..3ae3e73fa10 --- /dev/null +++ b/ports/zephyr-cp/supervisor/serial.c @@ -0,0 +1,85 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2017 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/shared/serial.h" + +#include "supervisor/zephyr-cp.h" + +#if CIRCUITPY_USB_DEVICE == 1 +#include "shared-bindings/usb_cdc/Serial.h" +usb_cdc_serial_obj_t *usb_console; +#else +#include "shared-bindings/busio/UART.h" +static busio_uart_obj_t uart_console; +static uint8_t buffer[64]; +#endif + +void port_serial_early_init(void) { + #if CIRCUITPY_USB_DEVICE == 0 + uart_console.base.type = &busio_uart_type; + common_hal_busio_uart_construct_from_device(&uart_console, DEVICE_DT_GET(DT_CHOSEN(zephyr_console)), sizeof(buffer), buffer); + #endif +} + +void port_serial_init(void) { + #if CIRCUITPY_USB_DEVICE == 1 + usb_console = usb_cdc_serial_get_console(); + #endif +} + +bool port_serial_connected(void) { + #if CIRCUITPY_USB_DEVICE == 1 + if (usb_console == NULL) { + return false; + } + return common_hal_usb_cdc_serial_get_connected(usb_console); + #else + return true; + #endif +} + +char port_serial_read(void) { + #if CIRCUITPY_USB_DEVICE == 1 + if (usb_console == NULL) { + return -1; + } + char buf[1]; + size_t count = common_hal_usb_cdc_serial_read(usb_console, buf, 1, NULL); + if (count == 0) { + return -1; + } + return buf[0]; + #else + char buf[1]; + size_t count = common_hal_busio_uart_read(&uart_console, buf, 1, NULL); + if (count == 0) { + return -1; + } + return buf[0]; + #endif +} + +uint32_t port_serial_bytes_available(void) { + #if CIRCUITPY_USB_DEVICE == 1 + if (usb_console == NULL) { + return 0; + } + return common_hal_usb_cdc_serial_get_in_waiting(usb_console); + #else + return common_hal_busio_uart_rx_characters_available(&uart_console); + #endif +} + +void port_serial_write_substring(const char *text, uint32_t length) { + #if CIRCUITPY_USB_DEVICE == 1 + if (usb_console == NULL) { + return; + } + common_hal_usb_cdc_serial_write(usb_console, text, length, NULL); + #else + common_hal_busio_uart_write(&uart_console, text, length, NULL); + #endif +} diff --git a/ports/zephyr-cp/supervisor/usb.c b/ports/zephyr-cp/supervisor/usb.c new file mode 100644 index 00000000000..6d3bf3286dd --- /dev/null +++ b/ports/zephyr-cp/supervisor/usb.c @@ -0,0 +1,461 @@ +#include "supervisor/usb.h" + +#include "shared-bindings/usb_cdc/__init__.h" +#include "shared-bindings/usb_cdc/Serial.h" + +#if CIRCUITPY_USB_HID +#include "common-hal/usb_hid/__init__.h" +#endif + +#include "supervisor/zephyr-cp.h" + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" +#include "lib/oofatfs/diskio.h" +#include "lib/oofatfs/ff.h" + +#include +#include +#include +#include +#include +#include +#if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_usbd) +#include +#endif + +#include "shared-module/storage/__init__.h" +#include "supervisor/filesystem.h" +#include "supervisor/shared/reload.h" + +#include +LOG_MODULE_REGISTER(cpusb, CONFIG_LOG_DEFAULT_LEVEL); + +#define USB_DEVICE DT_NODELABEL(zephyr_udc0) + +USBD_DEVICE_DEFINE(main_usbd, + DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)), + USB_VID, USB_PID); + +USBD_DESC_LANG_DEFINE(main_lang); +USBD_DESC_MANUFACTURER_DEFINE(main_mfr, USB_MANUFACTURER); +USBD_DESC_PRODUCT_DEFINE(main_product, USB_PRODUCT); + +USBD_DESC_CONFIG_DEFINE(fs_cfg_desc, "FS Configuration"); +USBD_DESC_CONFIG_DEFINE(hs_cfg_desc, "HS Configuration"); + +/* doc configuration instantiation start */ +static const uint8_t attributes = 0; + +USBD_CONFIGURATION_DEFINE(main_fs_config, + attributes, + 100, &fs_cfg_desc); + +USBD_CONFIGURATION_DEFINE(main_hs_config, + attributes, + 100, &hs_cfg_desc); + +static usb_cdc_serial_obj_t usb_cdc_console_obj; +static usb_cdc_serial_obj_t usb_cdc_data_obj; + +#ifndef USBD_DEFINE_MSC_LUN +#error "MSC not enabled" +#endif + +#define LUN_COUNT 1 +#define MSC_FLASH_BLOCK_SIZE 512 + +// The ellipsis range in the designated initializer of `ejected` is not standard C, +// but it works in both gcc and clang. +static bool locked[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; + +// Set to true if a write was in a file data or metadata area, +// as opposed to in the filesystem metadata area (e.g., dirty bit). +// Used to determine if an auto-reload is warranted. +static bool content_write[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; + +int _zephyr_disk_init(struct disk_info *disk); +int _zephyr_disk_status(struct disk_info *disk); +int _zephyr_disk_read(struct disk_info *disk, uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector); +int _zephyr_disk_write(struct disk_info *disk, const uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector); +int _zephyr_disk_ioctl(struct disk_info *disk, uint8_t cmd, void *buff); + +static const struct disk_operations disk_ops = { + .init = _zephyr_disk_init, + .status = _zephyr_disk_status, + .read = _zephyr_disk_read, + .write = _zephyr_disk_write, + .ioctl = _zephyr_disk_ioctl, +}; + +static struct disk_info circuitpy_disk = { + .name = "CIRCUITPY", + .ops = &disk_ops, + .dev = NULL +}; + +USBD_DEFINE_MSC_LUN(circuitpy_lun, "CIRCUITPY", "Zephyr", "FlashDisk", "0.00"); + + +int _zephyr_disk_init(struct disk_info *disk) { + printk("Initializing disk\n"); + return 0; +} + +int _zephyr_disk_status(struct disk_info *disk) { + fs_user_mount_t *root = filesystem_circuitpy(); + int lun = 0; + if (root == NULL) { + printk("Status: No media\n"); + return DISK_STATUS_NOMEDIA; + } + if (!filesystem_is_writable_by_usb(root)) { + printk("Status: Read-only\n"); + return DISK_STATUS_WR_PROTECT; + } + // Lock the blockdev once we say we're writable. + if (!locked[lun] && !blockdev_lock(root)) { + printk("Status: Locked\n"); + return DISK_STATUS_WR_PROTECT; + } + locked[lun] = true; + return DISK_STATUS_OK; +} + +int _zephyr_disk_read(struct disk_info *disk, uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector) { + fs_user_mount_t *root = filesystem_circuitpy(); + + uint32_t disk_block_count; + disk_ioctl(root, GET_SECTOR_COUNT, &disk_block_count); + + if (start_sector + num_sector > disk_block_count) { + return -EIO; + } + disk_read(root, data_buf, start_sector, num_sector); + return 0; +} + +int _zephyr_disk_write(struct disk_info *disk, const uint8_t *data_buf, uint32_t start_sector, uint32_t num_sector) { + fs_user_mount_t *root = filesystem_circuitpy(); + int lun = 0; + autoreload_suspend(AUTORELOAD_SUSPEND_USB); + disk_write(root, data_buf, start_sector, num_sector); + // Since by getting here we assume the mount is read-only to + // CircuitPython let's update the cached FatFs sector if it's the one + // we just wrote. + if + #if FF_MAX_SS != FF_MIN_SS + (root->fatfs.ssize == MSC_FLASH_BLOCK_SIZE) + #else + // The compiler can optimize this away. + (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE) + #endif + { + if (start_sector == root->fatfs.winsect && start_sector > 0) { + memcpy(root->fatfs.win, + data_buf + MSC_FLASH_BLOCK_SIZE * (root->fatfs.winsect - start_sector), + MSC_FLASH_BLOCK_SIZE); + } + } + + // A write to an lba below fatbase is in the filesystem metadata (BPB) area or the "Reserved Region", + // and is probably setting or clearing the dirty bit. This should not trigger auto-reload. + // All other writes will trigger auto-reload. + if (start_sector >= root->fatfs.fatbase) { + content_write[lun] = true; + } + return 0; +} + +int _zephyr_disk_ioctl(struct disk_info *disk, uint8_t cmd, void *buff) { + + fs_user_mount_t *root = filesystem_circuitpy(); + int lun = 0; + switch (cmd) { + case DISK_IOCTL_GET_SECTOR_COUNT: + disk_ioctl(root, GET_SECTOR_COUNT, buff); + return 0; + case DISK_IOCTL_GET_SECTOR_SIZE: + disk_ioctl(root, GET_SECTOR_SIZE, buff); + return 0; + case DISK_IOCTL_CTRL_SYNC: + disk_ioctl(root, CTRL_SYNC, buff); + autoreload_resume(AUTORELOAD_SUSPEND_USB); + + // This write is complete; initiate an autoreload if this was a file data or metadata write, + // not just a dirty-bit write. + if (content_write[lun] && lun == 0) { + autoreload_trigger(); + content_write[lun] = false; + } + return 0; + default: + printk("Unsupported disk ioctl %02x\n", cmd); + return -ENOTSUP; + } + return 0; +} + +// Tracks whether the USB host has selected a configuration, i.e. the device has +// enumerated. Written from the USBD message callback (USBD thread or system +// workqueue context) and read from the CircuitPython VM thread, so keep it +// volatile to avoid the compiler caching stale values. +static volatile bool usb_configured = false; + +static void _msg_cb(struct usbd_context *const ctx, const struct usbd_msg *msg) { + LOG_INF("USBD message: %s", usbd_msg_type_string(msg->type)); + + if (usbd_can_detect_vbus(ctx)) { + if (msg->type == USBD_MSG_VBUS_READY) { + usb_configured = false; + if (usbd_enable(ctx)) { + LOG_ERR("Failed to enable device support"); + } + } + + if (msg->type == USBD_MSG_VBUS_REMOVED) { + usb_configured = false; + if (usbd_disable(ctx)) { + LOG_ERR("Failed to disable device support"); + } + } + } + + // A non-zero configuration value means the host has enumerated us. + // A value of zero (or a bus reset / VBUS removal) unconfigures us. + if (msg->type == USBD_MSG_CONFIGURATION) { + usb_configured = (msg->status != 0); + } else if (msg->type == USBD_MSG_RESET) { + usb_configured = false; + } +} + +void usb_init(void) { + printk("Initializing USB\n"); + int err; + + printk("Adding language descriptor\n"); + err = usbd_add_descriptor(&main_usbd, &main_lang); + if (err) { + LOG_ERR("Failed to initialize language descriptor (%d)", err); + return; + } + + err = usbd_add_descriptor(&main_usbd, &main_mfr); + if (err) { + LOG_ERR("Failed to initialize manufacturer descriptor (%d)", err); + return; + } + + err = usbd_add_descriptor(&main_usbd, &main_product); + if (err) { + LOG_ERR("Failed to initialize product descriptor (%d)", err); + return; + } + + bool console = usb_cdc_console_enabled(); + if (console) { + uint8_t *receiver_buffer = port_malloc(128, true); + if (receiver_buffer != NULL) { + common_hal_usb_cdc_serial_construct_from_device(&usb_cdc_console_obj, DEVICE_DT_GET(DT_NODELABEL(cdc_acm_console)), 128, receiver_buffer); + } else { + console = false; + } + } + usb_cdc_set_console(console ? MP_OBJ_FROM_PTR(&usb_cdc_console_obj) : mp_const_none); + + bool data = usb_cdc_data_enabled(); + if (data) { + uint8_t *receiver_buffer = port_malloc(128, true); + if (receiver_buffer != NULL) { + common_hal_usb_cdc_serial_construct_from_device(&usb_cdc_data_obj, DEVICE_DT_GET(DT_NODELABEL(cdc_acm_data)), 128, receiver_buffer); + } else { + data = false; + } + } + usb_cdc_set_data(data ? MP_OBJ_FROM_PTR(&usb_cdc_data_obj) : mp_const_none); + + err = disk_access_register(&circuitpy_disk); + if (err) { + printk("Failed to register disk access %d\n", err); + return; + } + + if (USBD_SUPPORTS_HIGH_SPEED && + usbd_caps_speed(&main_usbd) == USBD_SPEED_HS) { + printk("Adding High-Speed configuration\n"); + err = usbd_add_configuration(&main_usbd, USBD_SPEED_HS, + &main_hs_config); + if (err) { + LOG_ERR("Failed to add High-Speed configuration"); + return; + } + + printk("Registering High-Speed cdc_acm class\n"); + if (usb_cdc_console_enabled()) { + err = usbd_register_class(&main_usbd, "cdc_acm_0", USBD_SPEED_HS, 1); + if (err) { + printk("Failed to add register classes %d\n", err); + return; + } + } + + if (usb_cdc_data_enabled()) { + err = usbd_register_class(&main_usbd, "cdc_acm_1", USBD_SPEED_HS, 1); + if (err) { + printk("Failed to add register classes %d\n", err); + return; + } + } + + err = usbd_register_class(&main_usbd, "msc_0", USBD_SPEED_HS, 1); + if (err) { + printk("Failed to add register MSC class %d\n", err); + return; + } else { + printk("Registered MSC class for high speed\n"); + } + + #if CIRCUITPY_USB_HID + if (usb_hid_enabled()) { + printk("Registering High-Speed hid class\n"); + err = usbd_register_class(&main_usbd, "hid_0", USBD_SPEED_HS, 1); + if (err) { + printk("Failed to register HID class (HS) %d\n", err); + return; + } + } + #endif + + usbd_device_set_code_triple(&main_usbd, USBD_SPEED_HS, + USB_BCC_MISCELLANEOUS, 0x02, 0x01); + } + + /* doc configuration register start */ + printk("Adding Full-Speed configuration\n"); + err = usbd_add_configuration(&main_usbd, USBD_SPEED_FS, + &main_fs_config); + if (err) { + LOG_ERR("Failed to add Full-Speed configuration"); + return; + } + /* doc configuration register end */ + + /* doc functions register start */ + + if (usb_cdc_console_enabled()) { + printk("Registering Full-Speed cdc_acm class\n"); + err = usbd_register_class(&main_usbd, "cdc_acm_0", USBD_SPEED_FS, 1); + if (err) { + printk("Failed to add register classes\n"); + return; + } + } + + if (usb_cdc_data_enabled()) { + printk("Registering Full-Speed cdc_acm class\n"); + err = usbd_register_class(&main_usbd, "cdc_acm_1", USBD_SPEED_FS, 1); + if (err) { + printk("Failed to add register classes\n"); + return; + } + } + + err = usbd_register_class(&main_usbd, "msc_0", USBD_SPEED_FS, 1); + if (err) { + printk("Failed to add register MSC class %d\n", err); + return; + } + /* doc functions register end */ + + #if CIRCUITPY_USB_HID + if (usb_hid_enabled()) { + printk("Registering Full-Speed hid class\n"); + err = usbd_register_class(&main_usbd, "hid_0", USBD_SPEED_FS, 1); + if (err) { + printk("Failed to register HID class (FS) %d\n", err); + return; + } + } + #endif + + usbd_device_set_code_triple(&main_usbd, USBD_SPEED_FS, + USB_BCC_MISCELLANEOUS, 0x02, 0x01); + printk("Setting self powered\n"); + usbd_self_powered(&main_usbd, attributes & USB_SCD_SELF_POWERED); + + printk("Registering callback\n"); + err = usbd_msg_register_cb(&main_usbd, _msg_cb); + if (err) { + LOG_ERR("Failed to register message callback"); + return; + } + + #if CIRCUITPY_USB_HID + printk("Initializing HID\n"); + usb_hid_init_devices(); + #endif + + printk("usbd_init\n"); + err = usbd_init(&main_usbd); + if (err) { + LOG_ERR("Failed to initialize device support (%d)", err); + return; + } + + printk("USB initialized\n"); + + if (!usbd_can_detect_vbus(&main_usbd)) { + /* No VBUS detection — just enable unconditionally. */ + err = usbd_enable(&main_usbd); + if (err) { + LOG_ERR("Failed to enable device support (%d)", err); + return; + } + } else { + #if DT_HAS_COMPAT_STATUS_OKAY(nordic_nrf_usbd) + /* + * On nRF52 USBD, the UDC driver enables VBUS detection interrupts + * inside usbd_init(). If USB is already plugged in, the VBUS_READY + * event arrives before usbd_init() sets status.initialized = true, + * causing a __ASSERT in usbd_thread (with CONFIG_ASSERT=y) that kills + * the event-processing thread. Our _msg_cb then never receives + * VBUS_READY, and USB never enumerates. + * + * Work around the race by checking the current VBUS state directly. + * udc_nrf_enable() does not require VBUS to be present, so it's safe + * to call usbd_enable() if VBUS is already up. + */ + nrfx_power_usb_state_t vbus = nrfx_power_usbstatus_get(); + if (vbus != NRFX_POWER_USB_STATE_DISCONNECTED) { + err = usbd_enable(&main_usbd); + if (err) { + LOG_ERR("Failed to enable device support (%d)", err); + return; + } + } + #else + /* + * On nRF54 USBHS, VBUS events arrive via NRFS IPC which has a natural + * startup delay, so the assert race doesn't occur. Additionally, + * udc_enable() blocks until VBUS is ready, so we must NOT call + * usbd_enable() here — let _msg_cb handle it on VBUS_READY. + */ + #endif + } +} + +bool usb_connected(void) { + // Mirrors TinyUSB's tud_ready(): configured (mounted) and not suspended. + return usb_configured && !usbd_is_suspended(&main_usbd); +} + +void usb_disconnect(void) { +} + +usb_cdc_serial_obj_t *usb_cdc_serial_get_console(void) { + if (usb_cdc_console_enabled()) { + return &usb_cdc_console_obj; + } + return NULL; +} diff --git a/ports/zephyr-cp/supervisor/zephyr-cp.h b/ports/zephyr-cp/supervisor/zephyr-cp.h new file mode 100644 index 00000000000..ecf7d42e3b4 --- /dev/null +++ b/ports/zephyr-cp/supervisor/zephyr-cp.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/usb_cdc/Serial.h" + +usb_cdc_serial_obj_t *usb_cdc_serial_get_console(void); diff --git a/ports/zephyr-cp/sysbuild.cmake b/ports/zephyr-cp/sysbuild.cmake new file mode 100644 index 00000000000..bea5c588a2a --- /dev/null +++ b/ports/zephyr-cp/sysbuild.cmake @@ -0,0 +1,23 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +if(SB_CONFIG_NET_CORE_IMAGE_HCI_IPC) + # For builds in the nrf5340, we build the netcore image with the controller + + set(NET_APP hci_ipc) + set(NET_APP_SRC_DIR ${ZEPHYR_BASE}/samples/bluetooth/${NET_APP}) + + ExternalZephyrProject_Add( + APPLICATION ${NET_APP} + SOURCE_DIR ${NET_APP_SRC_DIR} + BOARD ${SB_CONFIG_NET_CORE_BOARD} + ) + + set(${NET_APP}_OVERLAY_CONFIG + ${NET_APP_SRC_DIR}/extra-cis-bt_ll_sw_split.conf + CACHE INTERNAL "" + ) + + native_simulator_set_child_images(${DEFAULT_IMAGE} ${NET_APP}) + native_simulator_set_final_executable(${DEFAULT_IMAGE}) +endif() diff --git a/ports/zephyr-cp/sysbuild.conf b/ports/zephyr-cp/sysbuild.conf new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/zephyr-cp/sysbuild/hci_ipc.conf b/ports/zephyr-cp/sysbuild/hci_ipc.conf new file mode 100644 index 00000000000..20dc067f3e4 --- /dev/null +++ b/ports/zephyr-cp/sysbuild/hci_ipc.conf @@ -0,0 +1,3 @@ +# Enable dynamic TX power control so that BT_HCI_OP_VS_WRITE_TX_POWER_LEVEL +# is supported by the controller. +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y diff --git a/ports/zephyr-cp/tests/TEST_IDEAS.md b/ports/zephyr-cp/tests/TEST_IDEAS.md new file mode 100644 index 00000000000..6ef71d7a5a0 --- /dev/null +++ b/ports/zephyr-cp/tests/TEST_IDEAS.md @@ -0,0 +1,623 @@ +# CircuitPython Simulator Test Ideas + +Test ideas for the native_sim simulator, organized by module/category. + +## Core Python / Interpreter + +### 1. Multiple file priority +Test that boot.py runs before code.py, and main.py is used as fallback when code.py doesn't exist. + +```python +# boot.py +print("boot.py ran") + +# code.py +print("code.py ran") +``` + +Expected output order: "boot.py ran" then "code.py ran" + +### 2. Exception handling +Verify tracebacks print correctly with file/line info, and exception types propagate properly. + +```python +def inner(): + raise ValueError("test error") + +def outer(): + inner() + +outer() +``` + +### 3. Memory / gc module +Test `gc.collect()`, `gc.mem_free()`, `gc.mem_alloc()`, and behavior under memory pressure. + +```python +import gc +gc.collect() +free_before = gc.mem_free() +data = [0] * 1000 +free_after = gc.mem_free() +assert free_after < free_before +del data +gc.collect() +free_final = gc.mem_free() +print("done") +``` + +### 4. Import system +Test importing frozen modules vs filesystem modules, verify import errors are clear. + +```python +import sys +import board +import digitalio +print(f"modules loaded: {len(sys.modules)}") +print("done") +``` + +--- + +## digitalio + +### 5. Input mode +Test reading GPIO input state. May require trace file injection or loopback configuration. + +```python +import board +import digitalio + +pin = digitalio.DigitalInOut(board.D0) +pin.direction = digitalio.Direction.INPUT +value = pin.value +print(f"input value: {value}") +print("done") +``` + +### 6. Pull resistors +Verify pull-up/pull-down configuration affects input readings. + +```python +import board +import digitalio + +pin = digitalio.DigitalInOut(board.D0) +pin.direction = digitalio.Direction.INPUT +pin.pull = digitalio.Pull.UP +value_up = pin.value +pin.pull = digitalio.Pull.DOWN +value_down = pin.value +print(f"pull-up: {value_up}, pull-down: {value_down}") +print("done") +``` + +### 7. Direction switching +Switch same pin between input/output modes multiple times. + +```python +import board +import digitalio + +pin = digitalio.DigitalInOut(board.D0) +pin.direction = digitalio.Direction.OUTPUT +pin.value = True +pin.direction = digitalio.Direction.INPUT +_ = pin.value +pin.direction = digitalio.Direction.OUTPUT +pin.value = False +print("done") +``` + +--- + +## time module + +### 8. time.sleep() precision +Verify sleep timing via Perfetto trace timestamps. Use GPIO transitions as timing markers. + +```python +import time +import board +import digitalio + +led = digitalio.DigitalInOut(board.LED) +led.direction = digitalio.Direction.OUTPUT + +led.value = True +time.sleep(0.05) # 50ms +led.value = False +time.sleep(0.1) # 100ms +led.value = True +time.sleep(0.05) # 50ms +led.value = False +print("done") +``` + +Verify trace shows: 50ms high, 100ms low, 50ms high pattern. + +### 9. time.monotonic() +Test monotonic clock increments correctly and never goes backward. + +```python +import time + +samples = [] +for _ in range(10): + samples.append(time.monotonic()) + time.sleep(0.01) + +# Verify monotonic increase +for i in range(1, len(samples)): + assert samples[i] > samples[i-1], "monotonic went backward!" + +elapsed = samples[-1] - samples[0] +assert 0.08 < elapsed < 0.15, f"unexpected elapsed: {elapsed}" +print("done") +``` + +### 10. time.localtime / struct_time +Test time structure operations if available. + +```python +import time + +t = time.localtime() +print(f"year: {t.tm_year}") +print(f"month: {t.tm_mon}") +print(f"day: {t.tm_mday}") +print("done") +``` + +--- + +## microcontroller + +### 11. microcontroller.cpu properties +Test frequency, temperature, UID properties. + +```python +import microcontroller + +print(f"frequency: {microcontroller.cpu.frequency}") +print(f"uid: {microcontroller.cpu.uid.hex()}") +print("done") +``` + +### 12. Safe mode +Trigger and verify safe mode entry (requires CONFIG_NATIVE_SIM_REBOOT=y). + +```python +import microcontroller +# This would trigger safe mode - test carefully +# microcontroller.on_next_reset(microcontroller.RunMode.SAFE_MODE) +# microcontroller.reset() +print("done") +``` + +### 13. Reset reason +Test microcontroller.reset_reason after various reset types. + +```python +import microcontroller + +reason = microcontroller.reset_reason +print(f"reset reason: {reason}") +print("done") +``` + +--- + +## os module + +### 14. os.uname() +Verify returns correct system info for native_sim. + +```python +import os + +info = os.uname() +print(f"sysname: {info.sysname}") +print(f"machine: {info.machine}") +print(f"release: {info.release}") +print("done") +``` + +### 15. Filesystem operations +Test os.listdir(), os.stat(), os.remove(). + +```python +import os + +# List root +files = os.listdir("/") +print(f"root files: {files}") + +# Stat a file +if "code.py" in files: + stat = os.stat("/code.py") + print(f"code.py size: {stat[6]}") + +print("done") +``` + +### 16. os.getenv() +Test environment variable reading. + +```python +import os + +# May return None if not set +path = os.getenv("PATH") +print(f"PATH exists: {path is not None}") +print("done") +``` + +--- + +## board module + +### 17. board.board_id +Verify board ID matches expected value. + +```python +import board + +print(f"board_id: {board.board_id}") +assert board.board_id == "native_native_sim" +print("done") +``` + +### 18. Pin availability +Test that board.LED and other defined pins exist. + +```python +import board + +assert hasattr(board, "LED"), "board.LED missing" +print(f"LED pin: {board.LED}") +print("done") +``` + +--- + +## Filesystem + +### 19. File read/write +Create, read, and modify files on CIRCUITPY. + +```python +# Write a test file +with open("/test.txt", "w") as f: + f.write("hello world") + +# Read it back +with open("/test.txt", "r") as f: + content = f.read() + +assert content == "hello world" +print("done") +``` + +### 20. Directory operations +Test mkdir, rmdir, nested paths. + +```python +import os + +# Create directory +os.mkdir("/testdir") +assert "testdir" in os.listdir("/") + +# Create file in directory +with open("/testdir/file.txt", "w") as f: + f.write("nested") + +# Clean up +os.remove("/testdir/file.txt") +os.rmdir("/testdir") +assert "testdir" not in os.listdir("/") +print("done") +``` + +### 21. Large file handling +Test with larger files approaching flash limits. + +```python +import gc + +# Write 10KB file +data = "x" * 10240 +with open("/large.txt", "w") as f: + f.write(data) + +# Verify size +import os +stat = os.stat("/large.txt") +assert stat[6] == 10240 + +# Clean up +os.remove("/large.txt") +gc.collect() +print("done") +``` + +--- + +## Error Conditions + +### 22. Syntax error in code.py +Verify graceful error message when code.py has syntax error. + +```python +# code.py with intentional syntax error: +def broken( + print("missing close paren" +``` + +Expected: Clear syntax error message with line number. + +### 23. Runtime error +Verify traceback format shows file, line, and function. + +```python +def cause_error(): + x = 1 / 0 + +cause_error() +``` + +Expected: Traceback showing ZeroDivisionError with line info. + +### 24. Keyboard interrupt +Test Ctrl+C handling via PTY if applicable. + +```python +import time + +print("starting long loop") +for i in range(100): + print(f"iteration {i}") + time.sleep(0.1) +print("done") +``` + +Send Ctrl+C during execution, verify clean KeyboardInterrupt. + +--- + +## busio (if emulation available) + +### 25. busio.UART +Basic UART operations if configured. + +```python +import board +import busio + +# Check if UART pins exist +if hasattr(board, "TX") and hasattr(board, "RX"): + uart = busio.UART(board.TX, board.RX, baudrate=115200) + uart.write(b"test") + uart.deinit() +print("done") +``` + +### 26. busio.I2C scan +Scan for emulated I2C devices. + +```python +import board +import busio + +if hasattr(board, "SCL") and hasattr(board, "SDA"): + i2c = busio.I2C(board.SCL, board.SDA) + while not i2c.try_lock(): + pass + devices = i2c.scan() + print(f"I2C devices: {[hex(d) for d in devices]}") + i2c.unlock() + i2c.deinit() +print("done") +``` + +### 27. busio.SPI +Basic SPI transfer to emulated device. + +```python +import board +import busio + +if hasattr(board, "SCK") and hasattr(board, "MOSI"): + spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=getattr(board, "MISO", None)) + while not spi.try_lock(): + pass + spi.configure(baudrate=1000000) + result = bytearray(4) + spi.write_readinto(b"\x00\x00\x00\x00", result) + spi.unlock() + spi.deinit() +print("done") +``` + +--- + +## Serial/PTY Input + +These tests require extending conftest.py to support writing to the PTY, not just reading. + +### 28. Basic serial input +Test reading single characters from serial via PTY write. + +```python +import sys + +print("ready") +char = sys.stdin.read(1) +print(f"received: {repr(char)}") +print("done") +``` + +**Test harness**: After seeing "ready", write "A" to PTY, verify output shows "received: 'A'". + +### 29. input() function +Test the built-in input() function with PTY input. + +```python +print("ready") +name = input("Enter name: ") +print(f"hello {name}") +print("done") +``` + +**Test harness**: After seeing "Enter name:", write "World\n" to PTY, verify "hello World". + +### 30. Serial line buffering +Test reading a complete line with newline termination. + +```python +import sys + +print("ready") +line = sys.stdin.readline() +print(f"got: {repr(line)}") +print("done") +``` + +**Test harness**: Write "test line\n" to PTY, verify complete line received. + +### 31. usb_cdc.console data read +Test reading from usb_cdc.console.data if available. + +```python +import usb_cdc + +print("ready") +if usb_cdc.console: + while not usb_cdc.console.in_waiting: + pass + data = usb_cdc.console.read(usb_cdc.console.in_waiting) + print(f"console got: {data}") +print("done") +``` + +**Test harness**: Write bytes to PTY, verify they're received via usb_cdc.console. + +### 32. REPL interaction +Test entering REPL mode and executing commands interactively. + +```python +# No code.py - boots to REPL +``` + +**Test harness**: +1. Boot with empty/no code.py to get REPL prompt +2. Write "1 + 1\r\n" to PTY +3. Verify output contains "2" +4. Write "print('hello')\r\n" +5. Verify output contains "hello" + +### 33. Ctrl+C interrupt via PTY +Test sending Ctrl+C (0x03) to interrupt running code. + +```python +import time + +print("starting") +for i in range(100): + print(f"loop {i}") + time.sleep(0.1) +print("completed") # Should not reach this +``` + +**Test harness**: +1. Wait for "loop 5" in output +2. Write b"\x03" (Ctrl+C) to PTY +3. Verify KeyboardInterrupt raised +4. Verify "completed" NOT in output + +### 34. Ctrl+D soft reload via PTY +Test sending Ctrl+D (0x04) to trigger soft reload. + +```python +print("first run") +import time +time.sleep(10) # Long sleep to allow interrupt +print("done") +``` + +**Test harness**: +1. Wait for "first run" +2. Write b"\x04" (Ctrl+D) to PTY +3. Verify code restarts (see "first run" again or reload message) + +### 35. Serial input timeout +Test behavior when waiting for input with timeout. + +```python +import sys +import select + +print("ready") +# Poll for input with timeout +readable, _, _ = select.select([sys.stdin], [], [], 0.5) +if readable: + data = sys.stdin.read(1) + print(f"got: {repr(data)}") +else: + print("timeout") +print("done") +``` + +**Test harness**: Don't send anything, verify "timeout" appears. + +--- + +## Fixture Changes for PTY Input + +The `run_circuitpython` fixture in conftest.py needs to be extended: + +```python +@dataclass +class SimulatorResult: + output: str + trace_file: Path + pty_write_fd: int # New: file descriptor for writing to PTY + +def _run(code: str | None, timeout: float = 5.0, ...) -> SimulatorResult: + # Open PTY for both read AND write + pty_fd = os.open(pty_path, os.O_RDWR | os.O_NONBLOCK) + # ... +``` + +Or provide a callback/queue mechanism: + +```python +def _run(code, timeout=5.0, input_sequence=None): + """ + input_sequence: list of (trigger_text, bytes_to_send) tuples + When trigger_text is seen in output, send bytes_to_send to PTY + """ +``` + +--- + +## Implementation Priority + +Suggested order for implementation: + +### Phase 1: Basic module tests (no fixture changes) +1. **#17 board.board_id** - Quick sanity check +2. **#14 os.uname()** - Tests another module, simple +3. **#9 time.monotonic()** - Core timing functionality +4. **#8 time.sleep() precision** - Builds on GPIO trace infrastructure +5. **#1 Multiple file priority** - Tests interpreter boot sequence +6. **#19 File read/write** - Tests filesystem layer +7. **#3 Memory / gc** - Tests memory management +8. **#2 Exception handling** - Tests error reporting + +### Phase 2: PTY input tests (requires fixture extension) +9. **#28 Basic serial input** - Foundation for all input tests +10. **#33 Ctrl+C interrupt** - Important for interactive use +11. **#29 input() function** - Common user pattern +12. **#32 REPL interaction** - Tests interactive mode diff --git a/ports/zephyr-cp/tests/__init__.py b/ports/zephyr-cp/tests/__init__.py new file mode 100644 index 00000000000..e9039dd88b3 --- /dev/null +++ b/ports/zephyr-cp/tests/__init__.py @@ -0,0 +1,162 @@ +from pathlib import Path + +import serial +import subprocess +import threading +import time + + +class StdSerial: + def __init__(self, stdin, stdout): + self.stdin = stdin + self.stdout = stdout + + def read(self, amount=None): + data = self.stdout.read(amount) + if data == b"": + raise EOFError("stdout closed") + return data + + def write(self, buf): + if self.stdin is None: + return + self.stdin.write(buf) + self.stdin.flush() + + def close(self): + if self.stdin is not None: + self.stdin.close() + self.stdout.close() + + @property + def in_waiting(self): + if self.stdout is None: + return 0 + return len(self.stdout.peek()) + + +class SerialSaver: + """Capture serial output in a background thread so output isn't missed.""" + + def __init__(self, serial_obj, name="serial"): + self.all_output = "" + self.all_input = "" + self.serial = serial_obj + self.name = name + + self._stop = threading.Event() + self._lock = threading.Lock() + self._cv = threading.Condition(self._lock) + self._reader = threading.Thread(target=self._reader_loop, daemon=True) + self._reader.start() + + def _reader_loop(self): + while not self._stop.is_set(): + try: + read = self.serial.read(1) + except Exception: + # Serial port closed or device disconnected. + break + + if read == b"": + # Timeout with no data — keep waiting. Only a real + # exception or an explicit stop should end the loop. + continue + + text = read.decode("utf-8", errors="replace") + with self._cv: + self.all_output += text + self._cv.notify_all() + in_waiting = 0 + try: + in_waiting = self.serial.in_waiting + except OSError: + pass + if in_waiting > 0: + self.all_output += self.serial.read().decode("utf-8", errors="replace") + + def wait_for(self, text, timeout=10): + with self._cv: + while text not in self.all_output and self._reader.is_alive(): + if not self._cv.wait(timeout=timeout): + break + if text not in self.all_output: + tail = self.all_output[-400:] + raise TimeoutError( + f"Timed out waiting for {text!r} on {self.name}. Output tail:\n{tail}" + ) + + def read(self, amount=None): + # Kept for compatibility with existing callers. + return + + def close(self): + if not self.serial: + return + + self._stop.set() + self._reader.join(timeout=1.0) + try: + self.serial.close() + except Exception: + pass + self.serial = None + + def write(self, text): + self.all_input += text + self.serial.write(text.encode("utf-8")) + + +class NativeSimProcess: + def __init__(self, cmd, timeout=5, trace_file=None, env=None, flash_file=None): + if trace_file: + cmd.append(f"--trace-file={trace_file}") + + self._timeout = timeout + self.trace_file = trace_file + self.flash_file = flash_file + print("Running", " ".join(cmd)) + self._proc = subprocess.Popen( + cmd, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=None, + env=env, + ) + if self._proc.stdout is None: + raise RuntimeError("Failed to capture simulator stdout") + + # Discard the test warning + uart_pty_line = self._proc.stdout.readline().decode("utf-8") + if "connected to pseudotty:" not in uart_pty_line: + raise RuntimeError("Failed to connect to UART") + pty_path = uart_pty_line.strip().rsplit(":", maxsplit=1)[1].strip() + self.serial = SerialSaver( + serial.Serial(pty_path, baudrate=115200, timeout=0.05, write_timeout=0), + name="uart0", + ) + self.debug_serial = SerialSaver( + StdSerial(self._proc.stdin, self._proc.stdout), name="debug" + ) + + def shutdown(self): + if self._proc.poll() is None: + self._proc.terminate() + self._proc.wait(timeout=self._timeout) + + self.serial.close() + self.debug_serial.close() + + def display_capture_paths(self) -> list[Path]: + """Return paths to numbered PNG capture files produced by trace-driven capture.""" + pattern = getattr(self, "_capture_png_pattern", None) + count = getattr(self, "_capture_count", 0) + if not pattern or count == 0: + return [] + return [Path(pattern % i) for i in range(count)] + + def wait_until_done(self): + start_time = time.monotonic() + while self._proc.poll() is None and time.monotonic() - start_time < self._timeout: + time.sleep(0.01) + self.shutdown() diff --git a/ports/zephyr-cp/tests/bsim/__init__.py b/ports/zephyr-cp/tests/bsim/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/ports/zephyr-cp/tests/bsim/conftest.py b/ports/zephyr-cp/tests/bsim/conftest.py new file mode 100644 index 00000000000..a0c2c9fca27 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/conftest.py @@ -0,0 +1,273 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Pytest fixtures for CircuitPython bsim testing.""" + +import logging +import os +import shutil +import subprocess +from pathlib import Path + +import pytest + +from .. import SerialSaver, StdSerial + +logger = logging.getLogger(__name__) + +ZEPHYR_CP = Path(__file__).resolve().parents[2] +BSIM_ROOT = ZEPHYR_CP / "tools/bsim" +BSIM_PHY_BINARY = BSIM_ROOT / "bin/bs_2G4_phy_v1" + + +@pytest.fixture +def native_sim_env() -> dict[str, str]: + env = os.environ.copy() + env["BSIM_OUT_PATH"] = str(BSIM_ROOT) + env["BSIM_COMPONENTS_PATH"] = str(BSIM_ROOT / "components") + lib_path = str(BSIM_ROOT / "lib") + existing = env.get("LD_LIBRARY_PATH", "") + env["LD_LIBRARY_PATH"] = f"{lib_path}:{existing}" if existing else lib_path + return env + + +@pytest.fixture(params=["native_nrf5340bsim", "native_nrf54lm20bsim"]) +def board(request): + """Parametrized board fixture for bsim tests. + + Overrides the parent conftest's board fixture to run each test on both + bsim boards. + """ + return request.param + + +@pytest.fixture +def bsim_phy_binary(): + """Return path to BabbleSim PHY binary, skip if not present.""" + if not BSIM_PHY_BINARY.exists(): + pytest.skip(f"bs_2G4_phy_v1 not found: {BSIM_PHY_BINARY}") + return BSIM_PHY_BINARY + + +class BsimPhyInstance: + def __init__(self, proc: subprocess.Popen, serial: SerialSaver, timeout: float): + self.proc = proc + self.serial = serial + self.timeout = timeout + + def finish_sim(self) -> None: + self.serial.wait_for("Cleaning up", timeout=self.timeout + 5) + + def shutdown(self) -> None: + if self.proc.poll() is None: + self.proc.terminate() + self.proc.wait(timeout=2) + self.serial.close() + + +class ZephyrSampleProcess: + def __init__(self, proc: subprocess.Popen, timeout: float): + self._proc = proc + self._timeout = timeout + if proc.stdout is None: + raise RuntimeError("Failed to capture Zephyr sample stdout") + self.serial = SerialSaver(StdSerial(None, proc.stdout), name="zephyr sample") + + def shutdown(self) -> None: + if self._proc.poll() is None: + self._proc.terminate() + self._proc.wait(timeout=self._timeout) + self.serial.close() + + +@pytest.fixture +def bsim_phy(request, bsim_phy_binary, native_sim_env, sim_id): + duration_marker = request.node.get_closest_marker("duration") + duration = float(duration_marker.args[0]) if duration_marker else 20.0 + + devices = 1 + if "circuitpython2" in request.fixturenames or "zephyr_sample" in request.fixturenames: + devices = 2 + + sample_marker = request.node.get_closest_marker("zephyr_sample") + if sample_marker is not None: + sample_device_id = int(sample_marker.kwargs.get("device_id", 1)) + devices = max(devices, sample_device_id + 1) + + # Do not pass -sim_length: if the PHY exits on simulated time, device 0 can + # still be flushing UART output and test output can get truncated. Instead, + # let pytest own process lifetime and terminate the PHY at fixture teardown. + cmd = [ + "stdbuf", + "-oL", + str(bsim_phy_binary), + "-v=9", # Cleaning up level is on 9. Connecting is 7. + f"-s={sim_id}", + f"-D={devices}", + "-argschannel", + "-at=40", # 40 dB attenuation (default 60) so RSSI ~ -40 dBm + ] + print("Running:", " ".join(cmd)) + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + env=native_sim_env, + cwd=BSIM_ROOT / "bin", + ) + if proc.stdout is None: + raise RuntimeError("Failed to capture bsim phy stdout") + + # stdbuf -oL forces line-buffered stdout so SerialSaver can + # stream-read PHY output in real time. Wrapping in StdSerial + # ensures the reader thread exits on EOF when the PHY process + # terminates, rather than spinning on empty timeout reads. + phy_output = SerialSaver(StdSerial(None, proc.stdout), name="bsim phy") + try: + phy_output.wait_for("Connecting", timeout=2) + except TimeoutError: + if proc.poll() is not None: + print(phy_output.all_output) + raise RuntimeError("bsim PHY exited immediately") + # Assume bsim is running + + phy = BsimPhyInstance(proc, phy_output, timeout=duration) + yield phy + phy.shutdown() + + print("bsim phy output:") + print(phy_output.all_output) + + +def _build_zephyr_sample(build_dir: Path, source_dir: Path, board: str) -> Path: + if shutil.which("west") is None: + raise RuntimeError("west not found") + + cmd = [ + "west", + "build", + "-b", + board, + "-d", + str(build_dir), + "-p=auto", + str(source_dir), + ] + logger.info("Building Zephyr sample: %s", " ".join(cmd)) + subprocess.run(cmd, check=True, cwd=ZEPHYR_CP) + + return build_dir / "zephyr/zephyr.exe" + + +@pytest.fixture +def zephyr_sample(request, bsim_phy, native_sim_env, sim_id): + marker = request.node.get_closest_marker("zephyr_sample") + if marker is None or len(marker.args) != 1: + raise RuntimeError( + "zephyr_sample fixture requires @pytest.mark.zephyr_sample('')" + ) + + sample = marker.args[0] + board = marker.kwargs.get("board", "nrf52_bsim") + device_id = int(marker.kwargs.get("device_id", 1)) + timeout = float(marker.kwargs.get("timeout", 10.0)) + + sample_rel = str(sample).removeprefix("zephyr/samples/") + source_dir = ZEPHYR_CP / "zephyr/samples" / sample_rel + if not source_dir.exists(): + source_dir = ZEPHYR_CP / sample # port-local sample + if not source_dir.exists(): + pytest.skip(f"Zephyr sample not found: {source_dir}") + + build_name = f"build-bsim-sample-{sample_rel.replace('/', '_')}-{board}" + build_dir = ZEPHYR_CP / build_name + binary = build_dir / "zephyr/zephyr.exe" + + needs_rebuild = False + if not binary.exists(): + needs_rebuild = True + else: + # Rebuild if any source file is newer than the binary. + binary_mtime = binary.stat().st_mtime + for root, _dirs, files in os.walk(source_dir): + for f in files: + if Path(root, f).stat().st_mtime > binary_mtime: + needs_rebuild = True + break + if needs_rebuild: + break + + if needs_rebuild: + try: + binary = _build_zephyr_sample(build_dir, source_dir, board) + except (subprocess.CalledProcessError, RuntimeError) as exc: + pytest.skip(f"Failed to build Zephyr sample {sample_rel}: {exc}") + + if not binary.exists(): + pytest.skip(f"Zephyr sample binary not found: {binary}") + + cmd = [ + str(binary), + f"-s={sim_id}", + f"-d={device_id}", + "-disconnect_on_exit=1", + ] + logger.info("Running: %s", " ".join(cmd)) + proc = subprocess.Popen( + cmd, + stdin=subprocess.DEVNULL, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + env=native_sim_env, + ) + sample_proc = ZephyrSampleProcess(proc, timeout=timeout) + yield sample_proc + sample_proc.shutdown() + + print("Zephyr sample output:") + print(sample_proc.serial.all_output) + + +FROZEN_ROOT = (ZEPHYR_CP / "../../frozen").resolve() + + +def get_library_files(name: str) -> dict[str, str]: + """Return a dict mapping CIRCUITPY paths to file contents for all + .py files in a frozen library, suitable for circuitpy_drive. + + Looks up ``name`` under the ``frozen/`` directory (e.g. + ``get_library_files("adafruit_ble")`` walks + ``frozen/Adafruit_CircuitPython_BLE/adafruit_ble/``). + """ + files: dict[str, str] = {} + + # Try directory-style library: *//**/*.py + py_files = sorted(FROZEN_ROOT.glob(f"*/{name}/**/*.py")) + if py_files: + repo_dir = py_files[0].relative_to(FROZEN_ROOT).parts[0] + lib_parent = FROZEN_ROOT / repo_dir + for py_file in py_files: + rel = py_file.relative_to(lib_parent) + files[str(rel)] = py_file.read_text(encoding="utf-8") + return files + + # Try single-file module: */.py + py_files = list(FROZEN_ROOT.glob(f"*/{name}.py")) + if py_files: + py_file = py_files[0] + files[name + ".py"] = py_file.read_text(encoding="utf-8") + return files + + raise FileNotFoundError(f"Library {name!r} not found under {FROZEN_ROOT}") + + +# pytest markers are defined inside out meaning the bottom one is first in the +# list and the top is last. So use negative indices to reverse them. +@pytest.fixture +def circuitpython1(circuitpython): + return circuitpython[-1] + + +@pytest.fixture +def circuitpython2(circuitpython): + return circuitpython[-2] diff --git a/ports/zephyr-cp/tests/bsim/samples/central_battery_client/CMakeLists.txt b/ports/zephyr-cp/tests/bsim/samples/central_battery_client/CMakeLists.txt new file mode 100644 index 00000000000..d3635c95059 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/samples/central_battery_client/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(central_battery_client) + +target_sources(app PRIVATE + src/main.c +) diff --git a/ports/zephyr-cp/tests/bsim/samples/central_battery_client/prj.conf b/ports/zephyr-cp/tests/bsim/samples/central_battery_client/prj.conf new file mode 100644 index 00000000000..56a790677be --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/samples/central_battery_client/prj.conf @@ -0,0 +1,4 @@ +CONFIG_BT=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_LOG=y diff --git a/ports/zephyr-cp/tests/bsim/samples/central_battery_client/src/main.c b/ports/zephyr-cp/tests/bsim/samples/central_battery_client/src/main.c new file mode 100644 index 00000000000..34ed2fa09b9 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/samples/central_battery_client/src/main.c @@ -0,0 +1,212 @@ +/* + * SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries + * SPDX-License-Identifier: MIT + * + * Zephyr BLE central that connects to a device named "CPSVC", + * discovers Battery Service (0x180F), reads Battery Level (0x2A19), + * prints the value, and disconnects. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +static struct bt_conn *default_conn; +static struct bt_gatt_discover_params discover_params; +static struct bt_gatt_read_params read_params; + +/* Battery Service UUID: 0x180F */ +static struct bt_uuid_16 bas_uuid = BT_UUID_INIT_16(0x180F); +/* Battery Level Characteristic UUID: 0x2A19 */ +static struct bt_uuid_16 bat_level_uuid = BT_UUID_INIT_16(0x2A19); + +static uint16_t bat_level_handle; + +static void start_scan(void); + +static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) { + if (default_conn) { + return; + } + + /* Only interested in connectable devices */ + if (type != BT_GAP_ADV_TYPE_ADV_IND && + type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) { + return; + } + + /* Clone ad data so we can parse it without affecting the original */ + struct net_buf_simple ad_copy; + uint8_t ad_buf[64]; + size_t copy_len = ad->len < sizeof(ad_buf) ? ad->len : sizeof(ad_buf); + memcpy(ad_buf, ad->data, copy_len); + net_buf_simple_init_with_data(&ad_copy, ad_buf, copy_len); + + char addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Found CPSVC device: %s (RSSI %d)\n", addr_str, rssi); + + if (bt_le_scan_stop()) { + return; + } + + int err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, + BT_LE_CONN_PARAM_DEFAULT, &default_conn); + if (err) { + printk("Create conn failed (%d)\n", err); + start_scan(); + } +} + +static void start_scan(void) { + int err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + if (err) { + printk("Scanning failed to start (err %d)\n", err); + return; + } + printk("Scanning started\n"); +} + +static uint8_t read_battery_level_cb(struct bt_conn *conn, uint8_t err, + struct bt_gatt_read_params *params, + const void *data, uint16_t length) { + if (err) { + printk("Read failed (err %d)\n", err); + } else if (data && length >= 1) { + uint8_t level = ((const uint8_t *)data)[0]; + printk("Battery Level: %d\n", level); + } else { + printk("Read returned no data\n"); + } + + /* Disconnect after reading */ + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + + return BT_GATT_ITER_STOP; +} + +static uint8_t discover_char_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + if (!attr) { + printk("Characteristic discovery complete\n"); + return BT_GATT_ITER_STOP; + } + + struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; + + if (bt_uuid_cmp(chrc->uuid, &bat_level_uuid.uuid) == 0) { + bat_level_handle = chrc->value_handle; + printk("Found Battery Level characteristic, handle: %u\n", bat_level_handle); + + /* Read the battery level */ + read_params.func = read_battery_level_cb; + read_params.handle_count = 1; + read_params.single.handle = bat_level_handle; + read_params.single.offset = 0; + + int err = bt_gatt_read(conn, &read_params); + if (err) { + printk("Read request failed (err %d)\n", err); + } + return BT_GATT_ITER_STOP; + } + + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t discover_service_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + if (!attr) { + printk("Service discovery complete, BAS not found\n"); + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + return BT_GATT_ITER_STOP; + } + + printk("Found Battery Service, handle: %u\n", attr->handle); + + /* Now discover characteristics within this service */ + discover_params.uuid = &bat_level_uuid.uuid; + discover_params.start_handle = attr->handle + 1; + discover_params.end_handle = 0xFFFF; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + discover_params.func = discover_char_cb; + + int err = bt_gatt_discover(conn, &discover_params); + if (err) { + printk("Characteristic discovery failed (err %d)\n", err); + } + + return BT_GATT_ITER_STOP; +} + +static void connected(struct bt_conn *conn, uint8_t err) { + char addr[BT_ADDR_LE_STR_LEN]; + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (err) { + printk("Failed to connect to %s (%u)\n", addr, err); + bt_conn_unref(default_conn); + default_conn = NULL; + start_scan(); + return; + } + + if (conn != default_conn) { + return; + } + + printk("Connected: %s\n", addr); + + /* Discover Battery Service */ + discover_params.uuid = &bas_uuid.uuid; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_PRIMARY; + discover_params.func = discover_service_cb; + + err = bt_gatt_discover(conn, &discover_params); + if (err) { + printk("Service discovery failed (err %d)\n", err); + } +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) { + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != default_conn) { + return; + } + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + printk("Disconnected: %s (reason 0x%02x)\n", addr, reason); + + bt_conn_unref(default_conn); + default_conn = NULL; +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +int main(void) { + int err = bt_enable(NULL); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + return 0; + } + + printk("Bluetooth initialized\n"); + start_scan(); + return 0; +} diff --git a/ports/zephyr-cp/tests/bsim/samples/central_nus_client/CMakeLists.txt b/ports/zephyr-cp/tests/bsim/samples/central_nus_client/CMakeLists.txt new file mode 100644 index 00000000000..d5deacef980 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/samples/central_nus_client/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: MIT + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(central_nus_client) + +target_sources(app PRIVATE + src/main.c +) diff --git a/ports/zephyr-cp/tests/bsim/samples/central_nus_client/prj.conf b/ports/zephyr-cp/tests/bsim/samples/central_nus_client/prj.conf new file mode 100644 index 00000000000..56a790677be --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/samples/central_nus_client/prj.conf @@ -0,0 +1,4 @@ +CONFIG_BT=y +CONFIG_BT_CENTRAL=y +CONFIG_BT_GATT_CLIENT=y +CONFIG_LOG=y diff --git a/ports/zephyr-cp/tests/bsim/samples/central_nus_client/src/main.c b/ports/zephyr-cp/tests/bsim/samples/central_nus_client/src/main.c new file mode 100644 index 00000000000..9825a3e7a5e --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/samples/central_nus_client/src/main.c @@ -0,0 +1,302 @@ +/* + * SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries + * SPDX-License-Identifier: MIT + * + * Zephyr BLE central that connects to a device named "CPNUS", + * discovers Nordic UART Service (NUS), writes to the RX characteristic, + * subscribes to TX notifications, receives data, and disconnects. + * + * NUS UUIDs: + * Service: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E + * TX (peripheral→central, notify): 6E400003-B5A3-F393-E0A9-E50E24DCCA9E + * RX (central→peripheral, write): 6E400002-B5A3-F393-E0A9-E50E24DCCA9E + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +static struct bt_conn *default_conn; +static struct bt_gatt_discover_params discover_params; + +/* Real NUS 128-bit UUIDs in little-endian byte order. + * These match the standard Nordic UART Service UUIDs: + * Service: 6E400001-B5A3-F393-E0A9-E50E24DCCA9E + * TX: 6E400003-B5A3-F393-E0A9-E50E24DCCA9E + * RX: 6E400002-B5A3-F393-E0A9-E50E24DCCA9E + */ +static struct bt_uuid_128 nus_service_uuid = BT_UUID_INIT_128( + 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, + 0x93, 0xF3, 0xA3, 0xB5, 0x01, 0x00, 0x40, 0x6E); +static struct bt_uuid_128 nus_tx_uuid = BT_UUID_INIT_128( + 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, + 0x93, 0xF3, 0xA3, 0xB5, 0x03, 0x00, 0x40, 0x6E); +static struct bt_uuid_128 nus_rx_uuid = BT_UUID_INIT_128( + 0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, + 0x93, 0xF3, 0xA3, 0xB5, 0x02, 0x00, 0x40, 0x6E); + +static uint16_t tx_handle; +static uint16_t rx_handle; +static bool tx_notify_enabled; +static bool rx_written; +static bool received; +static uint8_t received_data[32]; +static uint16_t received_len; + +static void start_scan(void); + +/* Check if advertisement data contains a name */ +static bool ad_has_name(struct net_buf_simple *ad, const char *name) { + size_t name_len = strlen(name); + + while (ad->len > 1) { + uint8_t field_len = net_buf_simple_pull_u8(ad); + if (field_len == 0 || field_len > ad->len) { + break; + } + uint8_t type = net_buf_simple_pull_u8(ad); + field_len--; + + if ((type == BT_DATA_NAME_COMPLETE || type == BT_DATA_NAME_SHORTENED) && + field_len == name_len && + memcmp(ad->data, name, name_len) == 0) { + return true; + } + net_buf_simple_pull(ad, field_len); + } + return false; +} + +static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) { + if (default_conn) { + return; + } + + /* Only interested in connectable devices */ + if (type != BT_GAP_ADV_TYPE_ADV_IND && + type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) { + return; + } + + /* Clone ad data so we can parse it */ + struct net_buf_simple ad_copy; + uint8_t ad_buf[64]; + size_t copy_len = ad->len < sizeof(ad_buf) ? ad->len : sizeof(ad_buf); + memcpy(ad_buf, ad->data, copy_len); + net_buf_simple_init_with_data(&ad_copy, ad_buf, copy_len); + + if (!ad_has_name(&ad_copy, "CPNUS")) { + return; + } + + char addr_str[BT_ADDR_LE_STR_LEN]; + bt_addr_le_to_str(addr, addr_str, sizeof(addr_str)); + printk("Found CPNUS device: %s (RSSI %d)\n", addr_str, rssi); + + if (bt_le_scan_stop()) { + return; + } + + int err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, + BT_LE_CONN_PARAM_DEFAULT, &default_conn); + if (err) { + printk("Create conn failed (%d)\n", err); + start_scan(); + } +} + +static void start_scan(void) { + int err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + if (err) { + printk("Scanning failed to start (err %d)\n", err); + return; + } + printk("Scanning started\n"); +} + +/* TX notification callback */ +static uint8_t on_tx_notify(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params, + const void *data, uint16_t length) { + if (data) { + memcpy(received_data, data, length < sizeof(received_data) ? + length : sizeof(received_data)); + received_len = length; + received = true; + printk("NUS: received '"); + for (uint16_t i = 0; i < received_len; i++) { + printk("%c", received_data[i]); + } + printk("'\n"); + + /* Disconnect after receiving response */ + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + } + return BT_GATT_ITER_CONTINUE; +} + +static struct bt_gatt_subscribe_params tx_subscribe_params; + +/* Step 5: Subscribe to TX notifications */ +static void subscribe_tx(struct bt_conn *conn) { + tx_subscribe_params.notify = on_tx_notify; + tx_subscribe_params.value = BT_GATT_CCC_NOTIFY; + tx_subscribe_params.value_handle = tx_handle; + tx_subscribe_params.ccc_handle = tx_handle + 1; + + int err = bt_gatt_subscribe(conn, &tx_subscribe_params); + if (err) { + printk("TX subscribe failed (err %d)\n", err); + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + } else { + tx_notify_enabled = true; + printk("TX notify enabled\n"); + } +} + +/* Step 4: Write to RX characteristic (central→peripheral) using write-without-response */ +static void write_rx(struct bt_conn *conn) { + static uint8_t data[] = "Hello"; + + int err = bt_gatt_write_without_response(conn, rx_handle, + data, 5, false); + if (err) { + printk("RX write request failed (err %d)\n", err); + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + return; + } + rx_written = true; + printk("RX write complete\n"); + + /* Now subscribe to TX to receive the response */ + subscribe_tx(conn); +} + +/* Step 3: Discover characteristics to find TX and RX handles */ +static uint8_t discover_char_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + if (!attr) { + printk("Characteristic discovery complete\n"); + if (rx_handle == 0 || tx_handle == 0) { + printk("NUS characteristics not found\n"); + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + return BT_GATT_ITER_STOP; + } + if (rx_handle) { + printk("Writing to RX...\n"); + write_rx(conn); + } + return BT_GATT_ITER_STOP; + } + + struct bt_gatt_chrc *chrc = (struct bt_gatt_chrc *)attr->user_data; + + if (bt_uuid_cmp(chrc->uuid, &nus_rx_uuid.uuid) == 0) { + rx_handle = chrc->value_handle; + printk("Found NUS RX, handle: %u\n", rx_handle); + } else if (bt_uuid_cmp(chrc->uuid, &nus_tx_uuid.uuid) == 0) { + tx_handle = chrc->value_handle; + printk("Found NUS TX, handle: %u\n", tx_handle); + } + + return BT_GATT_ITER_CONTINUE; +} + +/* Step 2: Discover characteristics within the NUS service */ +static uint8_t discover_service_cb(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) { + if (!attr) { + printk("Service discovery complete, NUS not found\n"); + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + return BT_GATT_ITER_STOP; + } + + printk("Found NUS, handle: %u\n", attr->handle); + + /* Discover characteristics within this service */ + discover_params.uuid = NULL; + discover_params.start_handle = attr->handle + 1; + discover_params.end_handle = 0xFFFF; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + discover_params.func = discover_char_cb; + + int err = bt_gatt_discover(conn, &discover_params); + if (err) { + printk("Char discovery failed (err %d)\n", err); + } + + return BT_GATT_ITER_STOP; +} + +/* Step 1: Connected - discover NUS */ +static void connected(struct bt_conn *conn, uint8_t err) { + char addr[BT_ADDR_LE_STR_LEN]; + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + + if (err) { + printk("Failed to connect to %s (%u)\n", addr, err); + bt_conn_unref(default_conn); + default_conn = NULL; + start_scan(); + return; + } + + if (conn != default_conn) { + return; + } + + printk("Connected: %s\n", addr); + + /* Discover NUS */ + discover_params.uuid = &nus_service_uuid.uuid; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_PRIMARY; + discover_params.func = discover_service_cb; + + err = bt_gatt_discover(conn, &discover_params); + if (err) { + printk("Service discovery failed (err %d)\n", err); + } +} + +static void disconnected(struct bt_conn *conn, uint8_t reason) { + char addr[BT_ADDR_LE_STR_LEN]; + + if (conn != default_conn) { + return; + } + + bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); + printk("Disconnected: %s (reason 0x%02x)\n", addr, reason); + + bt_conn_unref(default_conn); + default_conn = NULL; +} + +BT_CONN_CB_DEFINE(conn_callbacks) = { + .connected = connected, + .disconnected = disconnected, +}; + +int main(void) { + int err = bt_enable(NULL); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + return 0; + } + + printk("Bluetooth initialized\n"); + start_scan(); + return 0; +} diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_basics.py b/ports/zephyr-cp/tests/bsim/test_bsim_basics.py new file mode 100644 index 00000000000..96f40a86b40 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_basics.py @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Basic BabbleSim connectivity tests for bsim.""" + +import pytest + +from .conftest import get_library_files + +BSIM_CODE = """\ +print("bsim ready") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_CODE}) +@pytest.mark.duration(3) +def test_bsim_dual_instance_connect(bsim_phy, circuitpython1, circuitpython2, board): + """Run two bsim instances on the same sim id and verify UART output.""" + + # Wait for both devices to complete before checking output. + circuitpython1.wait_until_done() + circuitpython2.wait_until_done() + + output0 = circuitpython1.serial.all_output + output1 = circuitpython2.serial.all_output + + assert f"Board ID:{board}" in output0 + assert f"Board ID:{board}" in output1 + assert "bsim ready" in output0 + assert "bsim ready" in output1 + + +# --- adafruit_ble library import --- + +BSIM_BLE_IMPORT_CODE = """\ +import adafruit_ble + +print("adafruit_ble version", adafruit_ble.__version__) +print("adafruit_ble repo", adafruit_ble.__repo__) +print("done") +""" + + +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_BLE_IMPORT_CODE, **get_library_files("adafruit_ble")} +) +def test_bsim_ble_library_import(bsim_phy, circuitpython): + """Import adafruit_ble from CIRCUITPY and verify basic attributes.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "adafruit_ble version" in output + assert "adafruit_ble repo" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_adapter.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_adapter.py new file mode 100644 index 00000000000..5a15bb03d74 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_adapter.py @@ -0,0 +1,140 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE adapter state tests for bsim.""" + +import pytest + + +# --- Enable/disable cycle --- + +BSIM_ENABLE_DISABLE_CODE = """\ +import _bleio + +adapter = _bleio.adapter + +# Check initial state (should be enabled after boot) +print("enabled start", adapter.enabled) + +# Disable +adapter.enabled = False +print("enabled false", adapter.enabled) + +# Re-enable +adapter.enabled = True +print("enabled true", adapter.enabled) + +# Verify it reports as enabled +print("enabled final", adapter.enabled) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_ENABLE_DISABLE_CODE}) +def test_bsim_adapter_enable_disable(bsim_phy, circuitpython): + """Toggle adapter.enabled and verify state.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "enabled start True" in output + assert "enabled false False" in output + assert "enabled true True" in output + assert "enabled final True" in output + assert "done" in output + + +# --- Disable stops advertising --- + +BSIM_DISABLE_STOPS_ADV_CODE = """\ +import _bleio + +adapter = _bleio.adapter + +name = b"CPADV" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +adapter.start_advertising(advertisement, connectable=False) +print("advertising", adapter.advertising) + +adapter.enabled = False +print("advertising after disable", adapter.advertising) + +adapter.enabled = True +print("advertising after enable", adapter.advertising) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_DISABLE_STOPS_ADV_CODE}) +def test_bsim_adapter_disable_stops_advertising(bsim_phy, circuitpython): + """Disabling the adapter stops advertising.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "advertising True" in output + assert "advertising after disable False" in output + assert "advertising after enable False" in output + assert "done" in output + + +# --- Adapter state across soft reload --- + +BSIM_ENABLE_RELOAD_CODE = """\ +import _bleio + +adapter = _bleio.adapter + +print("enabled", adapter.enabled) +print("advertising", adapter.advertising) +print("connected", adapter.connected) +print("done") +""" + + +@pytest.mark.code_py_runs(2) +@pytest.mark.circuitpy_drive({"code.py": BSIM_ENABLE_RELOAD_CODE}) +def test_bsim_adapter_state_after_reload(bsim_phy, circuitpython): + """Adapter state is clean after soft reload.""" + circuitpython.serial.wait_for("done") + circuitpython.serial.wait_for("Press any key to enter the REPL") + circuitpython.serial.write("\x04") + + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert output.count("enabled True") >= 2 + assert output.count("advertising False") >= 2 + assert output.count("connected False") >= 2 + + +# --- Adapter name truncation --- + +BSIM_NAME_TRUNCATION_CODE = """\ +import _bleio + +adapter = _bleio.adapter + +# Set a very long name +long_name = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%" +adapter.name = long_name + +# Read back — should be truncated to fit CONFIG_BT_DEVICE_NAME_MAX +name = adapter.name +print("name len", len(name)) +print("name", name) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_NAME_TRUNCATION_CODE}) +def test_bsim_adapter_name_truncation(bsim_phy, circuitpython): + """Very long adapter.name is truncated to fit Zephyr limit.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "name len" in output + # Should be truncated — length must be less than input (72 chars) + name_line = [l for l in output.split("\n") if "name len" in l][0] + name_len = int(name_line.split()[-1]) + assert name_len < 72 + assert "done" in output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_advertising.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_advertising.py new file mode 100644 index 00000000000..40b74ee854a --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_advertising.py @@ -0,0 +1,174 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE advertising tests for bsim.""" + +import logging +import re + +import pytest + + +logger = logging.getLogger(__name__) + +BSIM_ADV_CODE = """\ +import _bleio +import time + +name = b"CPADV" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +adapter = _bleio.adapter +print("adv start") +adapter.start_advertising(advertisement, connectable=False) +print("adv started") +time.sleep(4) +adapter.stop_advertising() +print("adv stop") +""" + +BSIM_ADV_INTERRUPT_RELOAD_CODE = """\ +import _bleio +import time + +name = b"CPADV" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +adapter = _bleio.adapter +print("adv run start") +adapter.start_advertising(advertisement, connectable=False) +print("adv running") +time.sleep(10) +adapter.stop_advertising() +print("adv run done") +""" + + +BSIM_TX_POWER_DEFAULT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +name = b"CPTXPWR" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +print("advertising default") +adapter.start_advertising(advertisement) +time.sleep(4) +adapter.stop_advertising() +print("done") +""" + +BSIM_TX_POWER_LOW_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +name = b"CPTXPWR" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +print("advertising low") +adapter.start_advertising(advertisement, tx_power=-20) +time.sleep(4) +adapter.stop_advertising() +print("done") +""" + + +@pytest.mark.zephyr_sample("bluetooth/observer") +@pytest.mark.circuitpy_drive({"code.py": BSIM_ADV_CODE}) +def test_bsim_advertise_and_scan(bsim_phy, circuitpython, zephyr_sample): + """Advertise from CircuitPython and verify Zephyr observer sees traffic.""" + observer = zephyr_sample + + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + observer_output = observer.serial.all_output + assert "adv start" in cp_output + assert "adv started" in cp_output + assert "adv stop" in cp_output + assert "Device found:" in observer_output + assert "AD data len 10" in observer_output + + +@pytest.mark.zephyr_sample("bluetooth/observer") +@pytest.mark.code_py_runs(2) +@pytest.mark.duration(25) +@pytest.mark.circuitpy_drive({"code.py": BSIM_ADV_INTERRUPT_RELOAD_CODE}) +def test_bsim_advertise_ctrl_c_reload(bsim_phy, circuitpython, zephyr_sample): + """Ensure advertising resumes after Ctrl-C and a reload.""" + observer = zephyr_sample + + circuitpython.serial.wait_for("adv running") + observer.serial.wait_for("Device found:") + observer_count_before = observer.serial.all_output.count("Device found:") + + circuitpython.serial.write("\x03") + circuitpython.serial.wait_for("KeyboardInterrupt") + + circuitpython.serial.write("\x04") + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + observer_output = observer.serial.all_output + logger.info(observer_output) + logger.info(cp_output) + + assert "adv run start" in cp_output + assert "KeyboardInterrupt" in cp_output + assert cp_output.count("adv running") >= 2 + assert cp_output.count("adv run done") >= 1 + assert observer_output.count("Device found:") >= observer_count_before + 1 + assert "Already advertising" not in cp_output + + +@pytest.mark.zephyr_sample("bluetooth/observer") +@pytest.mark.circuitpy_drive({"code.py": BSIM_TX_POWER_DEFAULT_CODE}) +def test_bsim_tx_power_default_rssi(board, bsim_phy, circuitpython, zephyr_sample): + """Verify default TX power produces expected RSSI.""" + observer = zephyr_sample + + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + obs_output = observer.serial.all_output + + assert "advertising default" in cp_output + assert "done" in cp_output + + # Observer: "Device found: (RSSI ), type , AD data len " + # Advertisement is 12 bytes: flags (3) + name (9). + # With 40 dB channel attenuation and 0 dBm TX → RSSI ~ -39. + expected_rssi = -39 + rssi_pattern = re.compile(r"RSSI (-?\d+)\), type \d+, AD data len 12") + all_rssi = [int(m.group(1)) for m in rssi_pattern.finditer(obs_output)] + logger.info("RSSI values: %s", all_rssi) + + assert len(all_rssi) > 0, "Observer saw no advertisements" + assert all_rssi[0] == expected_rssi, f"Expected RSSI {expected_rssi}, got {all_rssi[0]}" + + +@pytest.mark.zephyr_sample("bluetooth/observer") +@pytest.mark.circuitpy_drive({"code.py": BSIM_TX_POWER_LOW_CODE}) +def test_bsim_tx_power_low_rssi(bsim_phy, circuitpython, zephyr_sample): + """Verify low TX power reduces RSSI.""" + observer = zephyr_sample + + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + obs_output = observer.serial.all_output + + assert "advertising low" in cp_output + assert "done" in cp_output + + # With 40 dB channel attenuation and -20 dBm TX → RSSI ~ -59 + rssi_pattern = re.compile(r"RSSI (-?\d+)\), type \d+, AD data len 12") + all_rssi = [int(m.group(1)) for m in rssi_pattern.finditer(obs_output)] + logger.info("RSSI values: %s", all_rssi) + + assert len(all_rssi) > 0, "Observer saw no advertisements" + assert all_rssi[0] < -39, f"Expected lower RSSI with -20 dBm TX, got {all_rssi[0]}" diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_connect.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_connect.py new file mode 100644 index 00000000000..8d3c1f2594a --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_connect.py @@ -0,0 +1,118 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE central connection tests for bsim.""" + +import pytest + + +BSIM_CONNECT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("connect start") +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable: + target = entry.address + print("found target") + break +adapter.stop_scan() +print("have target", target is not None) + +if target is None: + raise RuntimeError("No connectable target found") + +connection = adapter.connect(target, timeout=5.0) +print("connected", connection.connected, adapter.connected, len(adapter.connections)) +connection.disconnect() + +for _ in range(40): + if not connection.connected and not adapter.connected: + break + time.sleep(0.1) + +print("disconnected", connection.connected, adapter.connected, len(adapter.connections)) +""" + +BSIM_RECONNECT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("run start") +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable: + target = entry.address + print("run found target") + break +adapter.stop_scan() +print("run have target", target is not None) + +if target is None: + raise RuntimeError("No connectable target found") + +connection = adapter.connect(target, timeout=5.0) +print("run connected", connection.connected, adapter.connected, len(adapter.connections)) +connection.disconnect() + +for _ in range(50): + if not connection.connected and not adapter.connected and len(adapter.connections) == 0: + break + time.sleep(0.1) + +print("run disconnected", connection.connected, adapter.connected, len(adapter.connections)) +""" + + +@pytest.mark.zephyr_sample("bluetooth/peripheral") +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_CONNECT_CODE}) +def test_bsim_connect_zephyr_peripheral(bsim_phy, circuitpython, zephyr_sample): + """Connect to the Zephyr peripheral sample and disconnect cleanly.""" + peripheral = zephyr_sample + + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + peripheral_output = peripheral.serial.all_output + + assert "connect start" in cp_output + assert "found target" in cp_output + assert "have target True" in cp_output + assert "connected True True 1" in cp_output + assert "disconnected False False 0" in cp_output + + assert "Advertising successfully started" in peripheral_output + assert "Connected" in peripheral_output + + +@pytest.mark.zephyr_sample("bluetooth/peripheral_sc_only") +@pytest.mark.code_py_runs(2) +@pytest.mark.duration(26) +@pytest.mark.circuitpy_drive({"code.py": BSIM_RECONNECT_CODE}) +def test_bsim_reconnect_zephyr_peripheral(bsim_phy, circuitpython, zephyr_sample): + """Connect/disconnect, soft reload, then connect/disconnect again.""" + peripheral = zephyr_sample + + circuitpython.serial.wait_for("run disconnected") + circuitpython.serial.wait_for("Press any key to enter the REPL") + circuitpython.serial.write("\x04") + + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + peripheral_output = peripheral.serial.all_output + + assert cp_output.count("run start") >= 2 + assert cp_output.count("run found target") >= 2 + assert cp_output.count("run have target True") >= 2 + assert cp_output.count("run connected True True 1") >= 2 + assert cp_output.count("run disconnected False False 0") >= 2 + + assert "Advertising successfully started" in peripheral_output + assert peripheral_output.count("Connected") >= 2 diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_descriptor.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_descriptor.py new file mode 100644 index 00000000000..d1b07859133 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_descriptor.py @@ -0,0 +1,131 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE descriptor tests for bsim.""" + +import pytest + +# =================================================================== +# Server: characteristic with user_description +# =================================================================== + +BSIM_DESC_SERVER_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +svc = _bleio.Service(_bleio.UUID(0x180F)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0x2A19), + properties=_bleio.Characteristic.READ, + read_perm=_bleio.Attribute.OPEN, + write_perm=_bleio.Attribute.NO_ACCESS, + max_length=1, fixed_length=True, initial_value=bytes([75]), + user_description="Battery Level", +) +print("service created") + +# Check local descriptors list +descs = char.descriptors +print("num descriptors", len(descs)) +for d in descs: + print("desc uuid", d.uuid.uuid16) + print("desc value", list(d.value)) + +name = b"CPDESC" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name +adapter.start_advertising(advertisement, connectable=True) + +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected", adapter.connected) + +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("done") +""" + +# =================================================================== +# Client: connects and reads the remote user description +# =================================================================== + +BSIM_DESC_CLIENT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("client start") +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPDESC" in entry.advertisement_bytes: + target = entry.address + print("found server") + break +adapter.stop_scan() +print("have target", target is not None) + +if target is None: + raise RuntimeError("No server found") + +connection = adapter.connect(target, timeout=5.0) +print("connected", connection.connected) + +services = connection.discover_remote_services([_bleio.UUID(0x180F)]) +char = services[0].characteristics[0] + +print("char value", list(char.value)) + +descs = char.descriptors +print("num descriptors", len(descs)) +for d in descs: + print("desc uuid", hex(d.uuid.uuid16)) + print("desc value", list(d.value)) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_DESC_SERVER_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_DESC_CLIENT_CODE}) +def test_bsim_descriptor_user_description(bsim_phy, circuitpython1, circuitpython2): + """Server creates a characteristic with user_description; + client discovers the service and reads the descriptor.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + # Server: user_description creates a CUD descriptor (0x2901) on the characteristic + assert "service created" in server_output + assert "num descriptors 1" in server_output + assert "desc uuid 10497" in server_output # 0x2901 + assert ( + "desc value [66, 97, 116, 116, 101, 114, 121, 32, 76, 101, 118, 101, 108]" in server_output + ) + assert "connected True" in server_output + + # Client: discovers and reads the remote descriptor + assert "found server" in client_output + assert "char value [75]" in client_output + assert "num descriptors 1" in client_output + assert "desc uuid 0x2901" in client_output + assert ( + "desc value [66, 97, 116, 116, 101, 114, 121, 32, 76, 101, 118, 101, 108]" in client_output + ) + assert "done" in client_output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_name.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_name.py new file mode 100644 index 00000000000..c5d2edce123 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_name.py @@ -0,0 +1,24 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE name tests for bsim.""" + +import pytest + + +BSIM_NAME_CODE = """\ +import _bleio + +adapter = _bleio.adapter +adapter.enabled = True +adapter.name = "CPNAME" +print("name", adapter.name) +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_NAME_CODE}) +def test_bsim_set_name(bsim_phy, circuitpython): + """Set the BLE name and read it back on bsim.""" + circuitpython.wait_until_done() + + assert "name CPNAME" in circuitpython.serial.all_output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_nus.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_nus.py new file mode 100644 index 00000000000..bb589cf9d90 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_nus.py @@ -0,0 +1,177 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Nordic UART Service (NUS) tests for bsim — using adafruit_ble library.""" + +import pytest + +from .conftest import get_library_files + +_ADAFRUIT_BLE = get_library_files("adafruit_ble") + +# ---- Test 1: CP peripheral hosts NUS, Zephyr central writes and reads ---- + +BSIM_NUS_PERIPHERAL_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from adafruit_ble.services.nordic import UARTService + +ble = BLERadio() +uart = UARTService() +print("service created") + +advertisement = ProvideServicesAdvertisement(uart) +advertisement.complete_name = "CPNUS" +ble.start_advertising(advertisement) +print("advertising") + +for _ in range(80): + if ble.connected: + break + time.sleep(0.1) +print("connected", ble.connected) + +# Wait for data to arrive from central +data = uart.read(5) +print("received", data) + +# Send a response back +uart.write(b"World") +print("sent response") + +time.sleep(1.0) + +for _ in range(80): + if not ble.connected: + break + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.zephyr_sample("tests/bsim/samples/central_nus_client") +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_NUS_PERIPHERAL_CODE, **_ADAFRUIT_BLE}) +def test_bsim_nus_peripheral(bsim_phy, circuitpython, zephyr_sample): + """CP hosts NUS peripheral; Zephyr central writes to RX, reads TX notifications.""" + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + sample_output = zephyr_sample.serial.all_output + + assert "service created" in cp_output + assert "connected True" in cp_output + assert "received" in cp_output + assert "sent response" in cp_output + assert "NUS: received 'World'" in sample_output + + +# ---- Test 2: CP-to-CP NUS (peripheral + central) ---- + +BSIM_NUS_SERVER_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from adafruit_ble.services.nordic import UARTService + +ble = BLERadio() +uart = UARTService() +print("service created") + +advertisement = ProvideServicesAdvertisement(uart) +advertisement.complete_name = "CP2CP" +ble.start_advertising(advertisement) +print("advertising") + +for _ in range(80): + if ble.connected: + break + time.sleep(0.1) +print("connected", ble.connected) + +# Read incoming data from central +data = uart.read(6) +print("received", data) + +# Respond back +uart.write(b"OK!") +print("sent response") + +for _ in range(80): + if not ble.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_NUS_CLIENT_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from adafruit_ble.services.nordic import UARTService + +ble = BLERadio() + +print("client start") +target = None +for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=8.0): + if adv.connectable and adv.complete_name == "CP2CP": + target = adv + print("found server") + break +ble.stop_scan() +print("have target", target is not None) + +if target is None: + raise RuntimeError("No server found") + +connection = ble.connect(target, timeout=5.0) +print("connected", connection.connected) + +uart = connection[UARTService] +print("discovered services", 1) + +# Write to server +uart.write(b"Hello!") +print("wrote to rx") + +data = uart.read(3) +print("received", data) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_NUS_SERVER_CODE, **_ADAFRUIT_BLE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_NUS_CLIENT_CODE, **_ADAFRUIT_BLE}) +def test_bsim_nus_cp_to_cp(bsim_phy, circuitpython1, circuitpython2): + """CP peripheral hosts NUS; CP central writes to RX, reads TX via notifications.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "connected True" in server_output + assert "received" in server_output + assert "sent response" in server_output + + assert "client start" in client_output + assert "found server" in client_output + assert "have target True" in client_output + assert "connected True" in client_output + assert "discovered services 1" in client_output + assert "wrote to rx" in client_output + assert "received b'OK!'" in client_output + assert "done" in client_output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_packet_buffer.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_packet_buffer.py new file mode 100644 index 00000000000..efda0637aa3 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_packet_buffer.py @@ -0,0 +1,785 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""PacketBuffer tests for bsim.""" + +import pytest + + +# ---- Test 1: Server-side PacketBuffer incoming (WRITE characteristic) ---- + +BSIM_PB_SERVER_IN_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +svc = _bleio.Service(_bleio.UUID(0xFFE0)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0xFFE1), + properties=_bleio.Characteristic.WRITE, + read_perm=_bleio.Attribute.NO_ACCESS, + write_perm=_bleio.Attribute.OPEN, + max_length=20, fixed_length=False, +) + +# Wrap in PacketBuffer for incoming packets +pb = _bleio.PacketBuffer(char, buffer_size=4, max_packet_size=20) +print("service created") + +name = b"CPPBIN" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name +adapter.start_advertising(advertisement, connectable=True) +print("advertising") + +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected", adapter.connected) + +# Read first incoming packet +data = bytearray(20) +n = 0 +deadline = time.monotonic() + 5.0 +while n == 0 and time.monotonic() < deadline: + n = pb.readinto(data) + if n == 0: + time.sleep(0.05) +print("packet1", data[:n]) + +# Read second incoming packet +n2 = 0 +deadline2 = time.monotonic() + 5.0 +while n2 == 0 and time.monotonic() < deadline2: + n2 = pb.readinto(data) + if n2 == 0: + time.sleep(0.05) +print("packet2", data[:n2]) + +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_PB_CLIENT_IN_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPBIN" in entry.advertisement_bytes: + target = entry.address + print("found server") + break +adapter.stop_scan() + +connection = adapter.connect(target, timeout=5.0) +print("connected", connection.connected) + +services = connection.discover_remote_services([_bleio.UUID(0xFFE0)]) +print("discovered services", len(services)) + +remote_char = services[0].characteristics[0] +print("found char") + +# Write two packets +remote_char.value = bytes([0x01, 0x02, 0x03, 0x04]) +print("wrote packet1") + +time.sleep(0.3) + +remote_char.value = bytes([0xAA, 0xBB, 0xCC, 0xDD, 0xEE]) +print("wrote packet2") + +time.sleep(0.5) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_SERVER_IN_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_CLIENT_IN_CODE}) +def test_bsim_packet_buffer_server_incoming(bsim_phy, circuitpython1, circuitpython2): + """PacketBuffer on server-side WRITE characteristic receives framed packets.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "connected True" in server_output + assert "packet1" in server_output + assert "packet2" in server_output + assert "done" in server_output + + assert "found server" in client_output + assert "wrote packet1" in client_output + assert "wrote packet2" in client_output + + +# ---- Test 2: Server-side PacketBuffer write/flush (NOTIFY response) ---- + +BSIM_PB_BIDI_SERVER_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +svc = _bleio.Service(_bleio.UUID(0xFFE0)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0xFFE1), + properties=_bleio.Characteristic.WRITE | _bleio.Characteristic.NOTIFY, + read_perm=_bleio.Attribute.NO_ACCESS, + write_perm=_bleio.Attribute.OPEN, + max_length=20, fixed_length=False, +) + +# Wrap in PacketBuffer for incoming packets and outgoing notifications +pb = _bleio.PacketBuffer(char, buffer_size=4, max_packet_size=20) +print("service created") + +name = b"CPPBBI" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name +adapter.start_advertising(advertisement, connectable=True) +print("advertising") + +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected", adapter.connected) + +# Read incoming packet from client +data = bytearray(20) +n = 0 +deadline = time.monotonic() + 5.0 +while n == 0 and time.monotonic() < deadline: + n = pb.readinto(data) + if n == 0: + time.sleep(0.05) +print("received", data[:n]) + +# Write response back (via NOTIFY) — sends immediately via completion callback +pb.write(bytes([0x52, 0x45, 0x53, 0x50])) # "RESP" +print("sent response") + +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_PB_BIDI_CLIENT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPBBI" in entry.advertisement_bytes: + target = entry.address + print("found server") + break +adapter.stop_scan() + +connection = adapter.connect(target, timeout=5.0) +print("connected", connection.connected) + +services = connection.discover_remote_services([_bleio.UUID(0xFFE0)]) +print("discovered services", len(services)) + +remote_char = services[0].characteristics[0] +print("found char, props", remote_char.properties) + +# Write a packet to the server +remote_char.value = bytes([0x48, 0x45, 0x4C, 0x4C, 0x4F]) # "HELLO" +print("wrote hello") + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(20) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_BIDI_SERVER_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_BIDI_CLIENT_CODE}) +def test_bsim_packet_buffer_bidirectional(bsim_phy, circuitpython1, circuitpython2): + """Bidirectional PacketBuffer: server receives WRITE, sends NOTIFY response.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "connected True" in server_output + assert "received" in server_output + assert "sent response" in server_output + assert "done" in server_output + + assert "found server" in client_output + assert "wrote hello" in client_output + assert "done" in client_output + + +# ---- Test 3: PacketBuffer with multiple queued incoming packets ---- + +BSIM_PB_QUEUE_SERVER_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +svc = _bleio.Service(_bleio.UUID(0xFFE0)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0xFFE1), + properties=_bleio.Characteristic.WRITE, + read_perm=_bleio.Attribute.NO_ACCESS, + write_perm=_bleio.Attribute.OPEN, + max_length=20, fixed_length=False, +) + +# Small buffer: only 1 packet, small max_packet_size +pb = _bleio.PacketBuffer(char, buffer_size=1, max_packet_size=10) +print("service created") + +name = b"CPPBQU" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name +adapter.start_advertising(advertisement, connectable=True) +print("advertising") + +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected", adapter.connected) + +# Wait for client to send all packets +time.sleep(1.0) + +# Read packets - with buffer_size=1, oldest packets are dropped +data = bytearray(20) + +n1 = pb.readinto(data) +print("pkt1", data[:n1]) + +n2 = pb.readinto(data) +print("pkt2", data[:n2]) + +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_PB_QUEUE_CLIENT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPBQU" in entry.advertisement_bytes: + target = entry.address + print("found server") + break +adapter.stop_scan() + +connection = adapter.connect(target, timeout=5.0) +print("connected", connection.connected) + +services = connection.discover_remote_services([_bleio.UUID(0xFFE0)]) +remote_char = services[0].characteristics[0] + +# Write 3 packets quickly (buffer only holds 2, so oldest should be dropped) +remote_char.value = bytes([0x01, 0x02, 0x03]) +print("wrote pkt1") + +time.sleep(0.1) + +remote_char.value = bytes([0x04, 0x05, 0x06]) +print("wrote pkt2") + +time.sleep(0.1) + +remote_char.value = bytes([0x07, 0x08, 0x09]) +print("wrote pkt3") + +time.sleep(0.5) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_QUEUE_SERVER_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_QUEUE_CLIENT_CODE}) +def test_bsim_packet_buffer_queue(bsim_phy, circuitpython1, circuitpython2): + """PacketBuffer queues multiple packets; oldest dropped when buffer full.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "connected True" in server_output + # With buffer_size=1, only the last packet(s) remain + assert "pkt1" in server_output + assert "pkt2" in server_output + assert "done" in server_output + + assert "wrote pkt1" in client_output + assert "wrote pkt2" in client_output + assert "wrote pkt3" in client_output + + +# ---- Test 4: readinto with buffer too small returns negative ---- + +BSIM_PB_OVERFLOW_SERVER_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +svc = _bleio.Service(_bleio.UUID(0xFFE0)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0xFFE1), + properties=_bleio.Characteristic.WRITE, + read_perm=_bleio.Attribute.NO_ACCESS, + write_perm=_bleio.Attribute.OPEN, + max_length=20, fixed_length=False, +) + +pb = _bleio.PacketBuffer(char, buffer_size=4, max_packet_size=20) +print("service created") + +name = b"CPPBOV" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name +adapter.start_advertising(advertisement, connectable=True) + +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected", adapter.connected) + +# Try to read a 5-byte packet into a 3-byte buffer -> ValueError +try: + data = bytearray(3) + n = 0 + deadline = time.monotonic() + 5.0 + while n == 0 and time.monotonic() < deadline: + n = pb.readinto(data) + if n == 0: + time.sleep(0.05) + print("unexpected success", n) +except ValueError as e: + print("valueerror", e) + +time.sleep(0.5) +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_PB_OVERFLOW_CLIENT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPBOV" in entry.advertisement_bytes: + target = entry.address + break +adapter.stop_scan() + +connection = adapter.connect(target, timeout=5.0) + +services = connection.discover_remote_services([_bleio.UUID(0xFFE0)]) +remote_char = services[0].characteristics[0] + +# Write a 5-byte packet, but server only has a 3-byte read buffer +remote_char.value = bytes([0x01, 0x02, 0x03, 0x04, 0x05]) +print("wrote 5 bytes") + +time.sleep(0.5) +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_OVERFLOW_SERVER_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_OVERFLOW_CLIENT_CODE}) +def test_bsim_packet_buffer_readinto_overflow(bsim_phy, circuitpython1, circuitpython2): + """readinto returns negative when packet is larger than buffer.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "valueerror" in server_output + + assert "wrote 5 bytes" in client_output + + +# ---- Test 5: write() with header kwarg ---- + +BSIM_PB_HEADER_SERVER_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +svc = _bleio.Service(_bleio.UUID(0xFFE0)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0xFFE1), + properties=_bleio.Characteristic.WRITE | _bleio.Characteristic.NOTIFY, + read_perm=_bleio.Attribute.NO_ACCESS, + write_perm=_bleio.Attribute.OPEN, + max_length=20, fixed_length=False, +) + +pb = _bleio.PacketBuffer(char, buffer_size=4, max_packet_size=20) +print("service created") + +name = b"CPPBHD" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name +adapter.start_advertising(advertisement, connectable=True) + +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected", adapter.connected) + +# Read an incoming packet +data = bytearray(20) +n = 0 +deadline = time.monotonic() + 5.0 +while n == 0 and time.monotonic() < deadline: + n = pb.readinto(data) + if n == 0: + time.sleep(0.05) +print("received", data[:n]) + +# Response: write body with a header — header goes at start of packet +pb.write(bytes([0x42, 0x4F, 0x44, 0x59]), header=bytes([0x48, 0x44])) # "HD" + "BODY" +print("sent with header") + +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_PB_HEADER_CLIENT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPBHD" in entry.advertisement_bytes: + target = entry.address + break +adapter.stop_scan() + +connection = adapter.connect(target, timeout=5.0) + +services = connection.discover_remote_services([_bleio.UUID(0xFFE0)]) +remote_char = services[0].characteristics[0] + +# Write a packet to trigger the server's response +remote_char.value = bytes([0x47, 0x4F]) +print("wrote trigger") + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_HEADER_SERVER_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_HEADER_CLIENT_CODE}) +def test_bsim_packet_buffer_write_header(bsim_phy, circuitpython1, circuitpython2): + """write() header kwarg prepends to packet body.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "received" in server_output + assert "sent with header" in server_output + + assert "wrote trigger" in client_output + + +# ---- Test 6: incoming_packet_length / outgoing_packet_length ---- + +BSIM_PB_LENGTHS_CODE = """\ +import _bleio + +svc = _bleio.Service(_bleio.UUID(0xFFE0)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0xFFE1), + properties=_bleio.Characteristic.WRITE | _bleio.Characteristic.NOTIFY, + read_perm=_bleio.Attribute.NO_ACCESS, + write_perm=_bleio.Attribute.OPEN, + max_length=20, fixed_length=False, +) + +pb = _bleio.PacketBuffer(char, buffer_size=2, max_packet_size=15) + +# incoming_packet_length reflects the max we can receive (characteristic max_length) +print("incoming", pb.incoming_packet_length) +# outgoing_packet_length is capped by max_packet_size +print("outgoing", pb.outgoing_packet_length) +print("done") +""" + + +@pytest.mark.duration(5) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_LENGTHS_CODE}) +def test_bsim_packet_buffer_packet_lengths(bsim_phy, circuitpython): + """incoming_packet_length and outgoing_packet_length properties.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + + # Server-side local characteristic: + # incoming = max_length = 20 + # outgoing = min(max_packet_size, max_length) = min(15, 20) = 15 + assert "incoming 20" in output + assert "outgoing 15" in output + assert "done" in output + + +# ---- Test 7: disconnect / reconnect, conn tracking ---- + +BSIM_PB_RECONNECT_SERVER_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +svc = _bleio.Service(_bleio.UUID(0xFFE0)) +char = _bleio.Characteristic.add_to_service( + svc, _bleio.UUID(0xFFE1), + properties=_bleio.Characteristic.WRITE | _bleio.Characteristic.NOTIFY, + read_perm=_bleio.Attribute.NO_ACCESS, + write_perm=_bleio.Attribute.OPEN, + max_length=20, fixed_length=False, +) + +pb = _bleio.PacketBuffer(char, buffer_size=4, max_packet_size=20) +print("service created") + +name = b"CPPBRC" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name +adapter.start_advertising(advertisement, connectable=True) + +# First connection +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected1", adapter.connected) + +# Read first packet +data = bytearray(20) +n = 0 +deadline = time.monotonic() + 5.0 +while n == 0 and time.monotonic() < deadline: + n = pb.readinto(data) + if n == 0: + time.sleep(0.05) +print("packet1", data[:n]) + +# Send a response to confirm the tracked conn works +pb.write(bytes([0x41, 0x43, 0x4B])) # "ACK" +print("sent ack1") + +# Wait for disconnect +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("disconnected") + +# Start advertising again for second connection +adapter.start_advertising(advertisement, connectable=True) + +# Second connection +for _ in range(80): + if adapter.connected: + break + time.sleep(0.1) +print("connected2", adapter.connected) + +# Read second packet (should track new conn) +n2 = 0 +deadline2 = time.monotonic() + 5.0 +while n2 == 0 and time.monotonic() < deadline2: + n2 = pb.readinto(data) + if n2 == 0: + time.sleep(0.05) +print("packet2", data[:n2]) + +pb.write(bytes([0x41, 0x43, 0x4B])) # "ACK" +print("sent ack2") + +for _ in range(80): + if not adapter.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_PB_RECONNECT_CLIENT_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +# First connection +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPBRC" in entry.advertisement_bytes: + target = entry.address + break +adapter.stop_scan() + +connection = adapter.connect(target, timeout=5.0) +print("connected1", connection.connected) + +services = connection.discover_remote_services([_bleio.UUID(0xFFE0)]) +remote_char = services[0].characteristics[0] + +# Write first packet +remote_char.value = bytes([0x46, 0x49, 0x52, 0x53, 0x54]) # "FIRST" +print("wrote first") + +time.sleep(0.5) + +# Disconnect +connection.disconnect() +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("disconnected") + +# Wait for server to re-advertise +time.sleep(0.5) + +# Second connection +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPBRC" in entry.advertisement_bytes: + target = entry.address + break +adapter.stop_scan() + +connection = adapter.connect(target, timeout=5.0) +print("connected2", connection.connected) + +services = connection.discover_remote_services([_bleio.UUID(0xFFE0)]) +remote_char = services[0].characteristics[0] + +# Write second packet +remote_char.value = bytes([0x53, 0x45, 0x43, 0x4E, 0x44]) # "SECOND" +print("wrote second") + +time.sleep(0.5) +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(30) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_RECONNECT_SERVER_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PB_RECONNECT_CLIENT_CODE}) +def test_bsim_packet_buffer_reconnect(bsim_phy, circuitpython1, circuitpython2): + """PacketBuffer tracks conn through disconnect / reconnect.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "connected1 True" in server_output + assert "packet1" in server_output + assert "sent ack1" in server_output + assert "disconnected" in server_output + assert "connected2 True" in server_output + assert "packet2" in server_output + assert "sent ack2" in server_output + + assert "wrote first" in client_output + assert "wrote second" in client_output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_pairing.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_pairing.py new file mode 100644 index 00000000000..75f6875ee2e --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_pairing.py @@ -0,0 +1,353 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE pairing tests for nrf5340bsim.""" + +import pytest + +# nrf54lm20bsim LE encryption is not yet functional in bsim. Enable it when it +# does. Real hardware works. +pytestmark = pytest.mark.circuitpython_board("native_nrf5340bsim") + +BSIM_PERIPHERAL_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +name = b"PAIRPERIPH" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +print("peripheral start") +adapter.start_advertising(advertisement, connectable=True) +print("peripheral advertising", adapter.advertising) + +# Wait for connection +timeout = time.monotonic() + 12.0 +while not adapter.connected and time.monotonic() < timeout: + time.sleep(0.01) + +if not adapter.connected: + print("peripheral connect timed out") + raise SystemExit(1) + +print("peripheral connected", adapter.connected) + +# Wait for pairing to complete (central initiates it) +# The peripheral's SMP module responds automatically. +timeout = time.monotonic() + 10.0 +paired = False +while time.monotonic() < timeout: + if adapter.connected and len(adapter.connections) > 0: + conn = adapter.connections[0] + if conn.paired: + paired = True + break + time.sleep(0.1) + +print("peripheral paired", paired) + +# Wait for disconnect +timeout = time.monotonic() + 10.0 +while adapter.connected and time.monotonic() < timeout: + time.sleep(0.1) + +print("peripheral disconnected", adapter.connected, len(adapter.connections)) +""" + +BSIM_CENTRAL_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("central start") +target = None +for entry in adapter.start_scan(timeout=8.0, active=True): + if entry.connectable and b"PAIRPERIPH" in entry.advertisement_bytes: + target = entry.address + print("central found target") + break +adapter.stop_scan() +print("central have target", target is not None) + +if target is None: + raise RuntimeError("No connectable target found") + +connection = adapter.connect(target, timeout=5.0) +print("central connected", connection.connected, adapter.connected, len(adapter.connections)) + +# Pair with the peripheral (Just Works pairing) +connection.pair() +print("central paired", connection.paired) + +# Disconnect cleanly +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while (connection.connected or adapter.connected) and time.monotonic() < timeout: + time.sleep(0.1) + +print("central disconnected", connection.connected, adapter.connected, len(adapter.connections)) +""" + + +@pytest.mark.duration(22) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PERIPHERAL_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_CENTRAL_CODE}) +def test_bsim_pairing_cp_to_cp(bsim_phy, circuitpython1, circuitpython2): + """Two CP instances: device 0 peripheral, device 1 central pairs to it.""" + peripheral = circuitpython1 + central = circuitpython2 + + central.wait_until_done() + peripheral.wait_until_done() + + periph_output = peripheral.serial.all_output + central_output = central.serial.all_output + + # Peripheral assertions + assert "peripheral start" in periph_output + assert "peripheral advertising True" in periph_output + assert "peripheral connected True" in periph_output + assert "peripheral paired True" in periph_output + assert "peripheral disconnected False 0" in periph_output + + # Central assertions + assert "central start" in central_output + assert "central found target" in central_output + assert "central have target True" in central_output + assert "central connected True True 1" in central_output + assert "central paired True" in central_output + assert "central disconnected False False 0" in central_output + + +BSIM_CENTRAL_PAIRED_PROPERTY_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("central start") +target = None +for entry in adapter.start_scan(timeout=8.0, active=True): + if entry.connectable and b"PAIRPERIPH" in entry.advertisement_bytes: + target = entry.address + print("central found target") + break +adapter.stop_scan() + +if target is None: + raise RuntimeError("No connectable target found") + +connection = adapter.connect(target, timeout=5.0) +print("central connected", connection.connected) + +# Check paired is False before pairing +print("central paired before", connection.paired) + +connection.pair() +print("central paired after", connection.paired) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while (connection.connected or adapter.connected) and time.monotonic() < timeout: + time.sleep(0.1) + +print("central disconnected", connection.connected) +""" + + +@pytest.mark.duration(22) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PERIPHERAL_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_CENTRAL_PAIRED_PROPERTY_CODE}) +def test_bsim_pairing_paired_property(bsim_phy, circuitpython1, circuitpython2): + """Verify connection.paired transitions from False to True after pairing.""" + peripheral = circuitpython1 + central = circuitpython2 + + central.wait_until_done() + peripheral.wait_until_done() + + periph_output = peripheral.serial.all_output + central_output = central.serial.all_output + + assert "peripheral paired True" in periph_output + + assert "central paired before False" in central_output + assert "central paired after True" in central_output + assert "central disconnected False" in central_output + + +BSIM_PERIPHERAL_BOND_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +name = b"BONDPERIPH" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +print("peripheral start") + +# First connection - pair +adapter.start_advertising(advertisement, connectable=True) +print("peripheral advertising", adapter.advertising) + +timeout = time.monotonic() + 12.0 +while not adapter.connected and time.monotonic() < timeout: + time.sleep(0.01) + +if not adapter.connected: + print("peripheral connect1 timed out") + raise SystemExit(1) + +print("peripheral connected1", adapter.connected) + +# Wait for pairing +timeout = time.monotonic() + 10.0 +paired = False +while time.monotonic() < timeout: + if adapter.connected and len(adapter.connections) > 0: + conn = adapter.connections[0] + if conn.paired: + paired = True + break + time.sleep(0.1) + +print("peripheral paired1", paired) + +# Wait for disconnect +timeout = time.monotonic() + 10.0 +while adapter.connected and time.monotonic() < timeout: + time.sleep(0.1) + +print("peripheral disconnected1", adapter.connected, len(adapter.connections)) + +# Second connection - bond should persist through storage. +# Calling pair() uses the stored bond keys without re-pairing. +time.sleep(0.5) +adapter.start_advertising(advertisement, connectable=True) +print("peripheral advertising2", adapter.advertising) + +timeout = time.monotonic() + 12.0 +while not adapter.connected and time.monotonic() < timeout: + time.sleep(0.01) + +if not adapter.connected: + print("peripheral connect2 timed out") + raise SystemExit(1) + +print("peripheral connected2", adapter.connected) + +# Request security to restore bond encryption +conn = adapter.connections[0] +conn.pair() +print("peripheral paired2", conn.paired) + +# Wait for disconnect +timeout = time.monotonic() + 10.0 +while adapter.connected and time.monotonic() < timeout: + time.sleep(0.1) + +print("peripheral disconnected2", adapter.connected) +""" + +BSIM_CENTRAL_BOND_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("central start") +target_addr = None +for entry in adapter.start_scan(timeout=8.0, active=True): + if entry.connectable and b"BONDPERIPH" in entry.advertisement_bytes: + target_addr = entry.address + print("central found target") + break +adapter.stop_scan() +print("central have target", target_addr is not None) + +if target_addr is None: + raise RuntimeError("No connectable target found") + +# First connection - pair +connection = adapter.connect(target_addr, timeout=5.0) +print("central connected1", connection.connected, adapter.connected, len(adapter.connections)) + +print("central paired before1", connection.paired) +connection.pair() +print("central paired after1", connection.paired) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while (connection.connected or adapter.connected) and time.monotonic() < timeout: + time.sleep(0.1) + +print("central disconnected1", connection.connected, adapter.connected) + +# Second connection - bond should be restored from storage. +# Calling pair() uses the stored bond keys without re-pairing. +time.sleep(1.0) +connection2 = adapter.connect(target_addr, timeout=5.0) +print("central connected2", connection2.connected, adapter.connected, len(adapter.connections)) + +connection2.pair() +print("central paired bond", connection2.paired) + +connection2.disconnect() + +timeout = time.monotonic() + 4.0 +while (connection2.connected or adapter.connected) and time.monotonic() < timeout: + time.sleep(0.1) + +print("central disconnected2", connection2.connected, adapter.connected) +""" + + +@pytest.mark.duration(35) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PERIPHERAL_BOND_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_CENTRAL_BOND_CODE}) +def test_bsim_bonding_persistence(bsim_phy, circuitpython1, circuitpython2): + """Verify bonds are saved to storage and survive disconnect/reconnect. + + Central pairs with peripheral, disconnects, then reconnects. + On the second connection the bond should be restored from storage + and connection.paired should be True without calling pair() again. + """ + peripheral = circuitpython1 + central = circuitpython2 + + central.wait_until_done() + peripheral.wait_until_done() + + periph_output = peripheral.serial.all_output + central_output = central.serial.all_output + + # Peripheral assertions - first connection + assert "peripheral start" in periph_output + assert "peripheral advertising True" in periph_output + assert "peripheral connected1 True" in periph_output + assert "peripheral paired1 True" in periph_output + assert "peripheral disconnected1 False 0" in periph_output + # Peripheral - second connection (private advertising, bond restored from storage) + assert "peripheral advertising2 True" in periph_output + assert "peripheral connected2 True" in periph_output + assert "peripheral paired2 True" in periph_output + assert "peripheral disconnected2 False" in periph_output + + # Central assertions - first connection + assert "central start" in central_output + assert "central found target" in central_output + assert "central have target True" in central_output + assert "central connected1 True True 1" in central_output + assert "central paired before1 False" in central_output + assert "central paired after1 True" in central_output + assert "central disconnected1 False False" in central_output + # Central - second connection (bond restored from storage) + assert "central connected2 True True 1" in central_output + assert "central paired bond True" in central_output + assert "central disconnected2 False False" in central_output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_peripheral.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_peripheral.py new file mode 100644 index 00000000000..89088fb9f87 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_peripheral.py @@ -0,0 +1,119 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE peripheral connection tests for bsim.""" + +import pytest + + +BSIM_PERIPHERAL_CODE = """\ +import _bleio +import time +import sys + +adapter = _bleio.adapter + +name = b"CPPERIPH" +advertisement = bytes((2, 0x01, 0x06, len(name) + 1, 0x09)) + name + +print("peripheral start") +adapter.start_advertising(advertisement, connectable=True) +print("advertising", adapter.advertising) + +was_connected = False +timeout = time.monotonic() + 8.0 +while not was_connected and time.monotonic() < timeout: + time.sleep(0.01) + was_connected = adapter.connected + +if not was_connected: + print("connect timed out") + sys.exit(-1) + +print("connected", was_connected, "advertising", adapter.advertising) + +if was_connected: + timeout = time.monotonic() + 8.0 + while adapter.connected and time.monotonic() < timeout: + time.sleep(0.1) + +print("disconnected", adapter.connected, len(adapter.connections)) +""" + +BSIM_CENTRAL_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("central start") +target = None +for entry in adapter.start_scan(timeout=6.0, active=True): + if entry.connectable and b"CPPERIPH" in entry.advertisement_bytes: + target = entry.address + print("found peripheral") + break +adapter.stop_scan() +print("have target", target is not None) + +if target is None: + raise RuntimeError("No connectable peripheral found") + +connection = adapter.connect(target, timeout=5.0) +print("connected", connection.connected, adapter.connected, len(adapter.connections)) +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while (connection.connected or adapter.connected) and time.monotonic() < timeout: + time.sleep(0.1) + +print("disconnected", connection.connected, adapter.connected, len(adapter.connections)) +""" + + +@pytest.mark.zephyr_sample("bluetooth/central") +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PERIPHERAL_CODE}) +def test_bsim_peripheral_zephyr_central(bsim_phy, circuitpython, zephyr_sample): + """Advertise as connectable from CP; Zephyr central connects and disconnects.""" + central = zephyr_sample + + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + central_output = central.serial.all_output + + assert "peripheral start" in cp_output + assert "advertising True" in cp_output + assert "connected True advertising False" in cp_output + assert "disconnected False 0" in cp_output + + assert "Scanning successfully started" in central_output + assert "Connected:" in central_output + assert "Disconnected:" in central_output + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive({"code.py": BSIM_PERIPHERAL_CODE}) +@pytest.mark.circuitpy_drive({"code.py": BSIM_CENTRAL_CODE}) +def test_bsim_peripheral_cp_central(bsim_phy, circuitpython1, circuitpython2): + """Two CP instances: device 0 peripheral, device 1 central.""" + peripheral = circuitpython1 + central = circuitpython2 + + central.wait_until_done() + peripheral.wait_until_done() + + periph_output = peripheral.serial.all_output + central_output = central.serial.all_output + + assert "peripheral start" in periph_output + assert "advertising True" in periph_output + assert "connected True advertising False" in periph_output + assert "disconnected False 0" in periph_output + + assert "central start" in central_output + assert "found peripheral" in central_output + assert "have target True" in central_output + assert "connected True True 1" in central_output + assert "disconnected False False 0" in central_output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_scan.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_scan.py new file mode 100644 index 00000000000..a2618a851f2 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_scan.py @@ -0,0 +1,161 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE scanning tests for bsim.""" + +import pytest + + +BSIM_SCAN_CODE = """\ +import _bleio + +adapter = _bleio.adapter +print("scan start") +scan = adapter.start_scan(timeout=4.0, active=True) +found = False +for entry in scan: + if b"zephyrproject" in entry.advertisement_bytes: + print("found beacon") + found = True + break +adapter.stop_scan() +print("scan done", found) +""" + +BSIM_SCAN_RELOAD_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("scan run start") +found = False +for entry in adapter.start_scan(active=True): + if b"zephyrproject" in entry.advertisement_bytes: + print("found beacon run") + found = True + break +adapter.stop_scan() +print("scan run done", found) +""" + +BSIM_SCAN_RELOAD_NO_STOP_CODE = """\ +import _bleio +import time + +adapter = _bleio.adapter + +print("scan run start") +found = False +for entry in adapter.start_scan(active=True): + if b"zephyrproject" in entry.advertisement_bytes: + print("found beacon run") + found = True + break +print("scan run done", found) +""" + +BSIM_SCAN_ENTRY_PROPS_CODE = """\ +import _bleio + +adapter = _bleio.adapter +print("scan start") +found = None +for entry in adapter.start_scan(timeout=4.0, active=True): + if b"zephyrproject" in entry.advertisement_bytes: + found = entry + break +adapter.stop_scan() + +if found is not None: + print("rssi", found.rssi <= 0 and found.rssi > -100) + print("connectable", found.connectable) + print("scan_response", found.scan_response) + print("address_bytes", len(found.address.address_bytes)) + print("address_type", found.address.type in (0, 1, 2, 3)) + print("adv_bytes_type", isinstance(found.advertisement_bytes, bytes)) +else: + print("no entry found") +print("done") +""" + +BSIM_SCAN_PASSIVE_CODE = """\ +import _bleio + +adapter = _bleio.adapter +print("scan passive start") +found = False +for entry in adapter.start_scan(timeout=4.0, active=False): + if b"zephyrproject" in entry.advertisement_bytes: + print("found beacon passive") + found = True + break +adapter.stop_scan() +print("scan passive done", found) +""" + + +@pytest.mark.zephyr_sample("bluetooth/beacon") +@pytest.mark.circuitpy_drive({"code.py": BSIM_SCAN_CODE}) +def test_bsim_scan_zephyr_beacon(bsim_phy, circuitpython, zephyr_sample): + """Scan for Zephyr beacon sample advertisement using bsim.""" + _ = zephyr_sample + + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "scan start" in output + assert "found beacon" in output + assert "scan done True" in output + + +@pytest.mark.zephyr_sample("bluetooth/beacon") +@pytest.mark.code_py_runs(2) +@pytest.mark.duration(4) +@pytest.mark.circuitpy_drive({"code.py": BSIM_SCAN_RELOAD_CODE}) +def test_bsim_scan_zephyr_beacon_reload(bsim_phy, circuitpython, zephyr_sample): + """Scan for Zephyr beacon, soft reload, and scan again.""" + _ = zephyr_sample + + circuitpython.serial.wait_for("scan run done") + circuitpython.serial.wait_for("Press any key to enter the REPL") + circuitpython.serial.write("\x04") + + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert output.count("scan run start") >= 2 + assert output.count("found beacon run") >= 2 + assert output.count("scan run done True") >= 2 + + +@pytest.mark.zephyr_sample("bluetooth/beacon") +@pytest.mark.circuitpy_drive({"code.py": BSIM_SCAN_ENTRY_PROPS_CODE}) +def test_bsim_scan_entry_properties(bsim_phy, circuitpython, zephyr_sample): + """Verify ScanEntry properties: rssi, connectable, scan_response, address, advertisement_bytes.""" + _ = zephyr_sample + + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "rssi True" in output + assert "connectable False" in output # beacon is non-connectable + assert "scan_response False" in output + assert "address_bytes 6" in output + assert "address_type True" in output + assert "adv_bytes_type True" in output + assert "done" in output + + +@pytest.mark.zephyr_sample("bluetooth/beacon") +@pytest.mark.circuitpy_drive({"code.py": BSIM_SCAN_PASSIVE_CODE}) +def test_bsim_scan_passive(bsim_phy, circuitpython, zephyr_sample): + """Passive scan finds Zephyr beacon.""" + _ = zephyr_sample + + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "scan passive start" in output + assert "found beacon passive" in output + assert "scan passive done True" in output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_service.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_service.py new file mode 100644 index 00000000000..eb83c016b3a --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_service.py @@ -0,0 +1,710 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE GATT service tests for bsim.""" + +import pytest + +from .conftest import get_library_files + +_ADAFRUIT_BLE = get_library_files("adafruit_ble") + +# --------------------------------------------------------------------------- +# Shared service libraries +# --------------------------------------------------------------------------- + +BATTERY_LIB = """ +from adafruit_ble.services import Service +from adafruit_ble.characteristics import Characteristic, Attribute +from adafruit_ble.uuid import StandardUUID + + +class BatteryService(Service): + uuid = StandardUUID(0x180F) + level = Characteristic( + uuid=StandardUUID(0x2A19), + properties=Characteristic.READ | Characteristic.WRITE, + read_perm=Attribute.OPEN, + write_perm=Attribute.OPEN, + max_length=1, + fixed_length=True, + initial_value=bytes([75]), + )""" + +HEART_RATE_LIB = """ +from adafruit_ble.services import Service +from adafruit_ble.characteristics import Characteristic, Attribute +from adafruit_ble.uuid import StandardUUID + + +class HeartRateService(Service): + uuid = StandardUUID(0x180D) + measurement = Characteristic( + uuid=StandardUUID(0x2A37), + properties=Characteristic.READ, + read_perm=Attribute.OPEN, + write_perm=Attribute.NO_ACCESS, + max_length=2, + fixed_length=True, + initial_value=bytes([0, 72]), + )""" + +# =================================================================== +# Test 1: Battery Service (Zephyr central) +# =================================================================== + +BSIM_SERVICE_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from battery_service import BatteryService + +ble = BLERadio() +svc = BatteryService() +print("service created") + +advertisement = ProvideServicesAdvertisement(svc) +ble.start_advertising(advertisement) +print("advertising") + +for _ in range(80): + if ble.connected: + break + time.sleep(0.1) +print("connected", ble.connected) + +for _ in range(80): + if not ble.connected: + break + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.zephyr_sample("tests/bsim/samples/central_battery_client") +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_SERVICE_CODE, "battery_service.py": BATTERY_LIB, **_ADAFRUIT_BLE} +) +def test_bsim_service_battery(bsim_phy, circuitpython, zephyr_sample): + """CP hosts BatteryService; Zephyr central reads battery level.""" + circuitpython.wait_until_done() + + cp_output = circuitpython.serial.all_output + sample_output = zephyr_sample.serial.all_output + + assert "service created" in cp_output + assert "connected True" in cp_output + assert "Battery Level: 75" in sample_output + + +# =================================================================== +# Test 2: CP client reads/writes CP peripheral +# =================================================================== + +BSIM_SERVER_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from battery_service import BatteryService + +ble = BLERadio() +svc = BatteryService() +print("service created") + +advertisement = ProvideServicesAdvertisement(svc) +ble.start_advertising(advertisement) +print("advertising") + +for _ in range(80): + if ble.connected: + break + time.sleep(0.1) +print("connected", ble.connected) + +for _ in range(80): + if not ble.connected: + break + time.sleep(0.1) + +print("final value", list(svc.level)) +print("done") +""" + +BSIM_CLIENT_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from battery_service import BatteryService + +ble = BLERadio() + +print("client start") +target = None +for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=6.0): + if adv.connectable: + target = adv + print("found server") + break +ble.stop_scan() +print("have target", target is not None) + +if target is None: + raise RuntimeError("No server found") + +connection = ble.connect(target, timeout=5.0) +print("connected", connection.connected) + +svc = connection[BatteryService] +print("discovered services", 1) +print("discovered chars", 1) # BatteryService has one characteristic + +print("battery level", list(svc.level)) + +# Write a new value +svc.level = bytes([42]) +print("wrote new value") + +time.sleep(0.5) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) + +print("disconnected", not connection.connected) +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_SERVER_CODE, "battery_service.py": BATTERY_LIB, **_ADAFRUIT_BLE} +) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_CLIENT_CODE, "battery_service.py": BATTERY_LIB, **_ADAFRUIT_BLE} +) +def test_bsim_service_cp_client(bsim_phy, circuitpython1, circuitpython2): + """CP peripheral hosts BatteryService; CP central discovers, reads, and writes.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "service created" in server_output + assert "connected True" in server_output + assert "final value [42]" in server_output + + assert "client start" in client_output + assert "found server" in client_output + assert "discovered services 1" in client_output + assert "discovered chars 1" in client_output + assert "battery level [75]" in client_output + assert "wrote new value" in client_output + assert "disconnected True" in client_output + + +# =================================================================== +# Test 3: Discover all services (no whitelist) +# =================================================================== + +BSIM_DISCOVER_ALL_SERVER_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from battery_service import BatteryService +from heart_rate import HeartRateService + +ble = BLERadio() +bas = BatteryService() +hrs = HeartRateService() +print("services created") + +advertisement = ProvideServicesAdvertisement(bas, hrs) +ble.start_advertising(advertisement) + +for _ in range(80): + if ble.connected: + break + time.sleep(0.1) +print("connected", ble.connected) + +for _ in range(80): + if not ble.connected: + break + time.sleep(0.1) +print("done") +""" + +BSIM_DISCOVER_ALL_CLIENT_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from battery_service import BatteryService +from heart_rate import HeartRateService + +ble = BLERadio() + +print("client start") +target = None +for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=8.0): + if adv.connectable: + target = adv + print("found server") + break +ble.stop_scan() +print("have target", target is not None) + +if target is None: + raise RuntimeError("No server found") + +connection = ble.connect(target, timeout=5.0) +print("connected", connection.connected) + +# Discover ALL services (no whitelist) — use _bleio directly. +all_services = connection._bleio_connection.discover_remote_services() +print("total services", len(all_services)) + +# Filter to our two known UUIDs (ignore GATT/GAP services the stack may expose) +user_svcs = [s for s in all_services if s.uuid.uuid16 in (0x180F, 0x180D)] +print("user services", len(user_svcs)) + +uuids = sorted([s.uuid.uuid16 for s in user_svcs]) +print("service uuids", uuids) + +# Now read characteristics via adafruit_ble Service bindings. +if BatteryService in connection: + bas = connection[BatteryService] + print("char", hex(0x2a19), list(bas.level)) + +if HeartRateService in connection: + hrs = connection[HeartRateService] + print("char", hex(0x2a37), list(hrs.measurement)) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive( + { + "code.py": BSIM_DISCOVER_ALL_SERVER_CODE, + "battery_service.py": BATTERY_LIB, + "heart_rate.py": HEART_RATE_LIB, + **_ADAFRUIT_BLE, + } +) +@pytest.mark.circuitpy_drive( + { + "code.py": BSIM_DISCOVER_ALL_CLIENT_CODE, + "battery_service.py": BATTERY_LIB, + "heart_rate.py": HEART_RATE_LIB, + **_ADAFRUIT_BLE, + } +) +def test_bsim_service_discover_all(bsim_phy, circuitpython1, circuitpython2): + """Discover all services without a UUID whitelist, verify two user services found.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + client_output = client.serial.all_output + + assert "user services 2" in client_output + assert "service uuids [6157, 6159]" in client_output # 0x180D=6157, 0x180F=6159 + assert "char 0x2a37 [0, 72]" in client_output + assert "char 0x2a19 [75]" in client_output + + +# =================================================================== +# Test 4: Write-no-response (uses MultiService from multi_service module) +# =================================================================== + +MULTI_LIB = """ +from adafruit_ble.services import Service +from adafruit_ble.characteristics import Characteristic, Attribute +from adafruit_ble.uuid import StandardUUID + + +class MultiService(Service): + uuid = StandardUUID(0x180F) + char_a = Characteristic( + uuid=StandardUUID(0x2A19), + properties=Characteristic.READ, + read_perm=Attribute.OPEN, + write_perm=Attribute.NO_ACCESS, + max_length=1, + fixed_length=True, + initial_value=bytes([10]), + ) + char_b = Characteristic( + uuid=StandardUUID(0x2A1A), + properties=Characteristic.READ | Characteristic.WRITE_NO_RESPONSE, + read_perm=Attribute.OPEN, + write_perm=Attribute.OPEN, + max_length=1, + fixed_length=True, + initial_value=bytes([20]), + ) + char_c = Characteristic( + uuid=StandardUUID(0x2A1B), + properties=Characteristic.READ, + read_perm=Attribute.OPEN, + write_perm=Attribute.NO_ACCESS, + max_length=1, + fixed_length=True, + initial_value=bytes([30]), + )""" + + +BSIM_MULTI_CHAR_SERVER_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from multi_service import MultiService + +ble = BLERadio() +svc = MultiService() +# Force binding +svc.char_a +svc.char_b +svc.char_c +print("service created") + +advertisement = ProvideServicesAdvertisement(svc) +ble.start_advertising(advertisement) + +for _ in range(80): + if ble.connected: + break + time.sleep(0.1) +print("connected", ble.connected) + +for _ in range(80): + if not ble.connected: + break + time.sleep(0.1) + +print("char_b final", list(svc.char_b)) +print("done") +""" + +BSIM_WRITE_NR_CLIENT_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from multi_service import MultiService + +ble = BLERadio() + +target = None +for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=6.0): + if adv.connectable: + target = adv + break +ble.stop_scan() + +if target is None: + raise RuntimeError("No server found") + +connection = ble.connect(target, timeout=5.0) + +svc = connection[MultiService] + +print("initial", list(svc.char_b)) + +# Write-no-response +svc.char_b = bytes([99]) +print("wrote wnr") + +# Give the server time to process the write +time.sleep(0.5) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_MULTI_CHAR_SERVER_CODE, "multi_service.py": MULTI_LIB, **_ADAFRUIT_BLE} +) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_WRITE_NR_CLIENT_CODE, "multi_service.py": MULTI_LIB, **_ADAFRUIT_BLE} +) +def test_bsim_service_write_no_response(bsim_phy, circuitpython1, circuitpython2): + """Client writes a characteristic using WRITE_NO_RESPONSE.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "char_b final [99]" in server_output + assert "initial [20]" in client_output + assert "wrote wnr" in client_output + + +# =================================================================== +# Test 5: Multiple characteristics on one service +# =================================================================== + +BSIM_MULTI_CHAR_CLIENT_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from multi_service import MultiService + +ble = BLERadio() + +target = None +for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=6.0): + if adv.connectable: + target = adv + break +ble.stop_scan() + +if target is None: + raise RuntimeError("No server found") + +connection = ble.connect(target, timeout=5.0) + +svc = connection[MultiService] +print("num chars", 3) + +# Read each characteristic +print("char", hex(0x2A19), list(svc.char_a)) +print("char", hex(0x2A1A), list(svc.char_b)) +print("char", hex(0x2A1B), list(svc.char_c)) + +# Write to the second characteristic +svc.char_b = bytes([77]) +print("wrote 0x2a1a") + +time.sleep(0.5) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_MULTI_CHAR_SERVER_CODE, "multi_service.py": MULTI_LIB, **_ADAFRUIT_BLE} +) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_MULTI_CHAR_CLIENT_CODE, "multi_service.py": MULTI_LIB, **_ADAFRUIT_BLE} +) +def test_bsim_service_multi_char(bsim_phy, circuitpython1, circuitpython2): + """Service with three characteristics: discover all, read each, write one.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "num chars 3" in client_output + assert "char 0x2a19 [10]" in client_output + assert "char 0x2a1a [20]" in client_output + assert "char 0x2a1b [30]" in client_output + assert "wrote 0x2a1a" in client_output + assert "char_b final [77]" in server_output + + +# =================================================================== +# Test 6: 128-bit custom UUID +# =================================================================== + +CUSTOM_LIB = """ +from adafruit_ble.services import Service +from adafruit_ble.characteristics import Characteristic, Attribute +from adafruit_ble.uuid import VendorUUID + + +class CustomService(Service): + uuid = VendorUUID("12345678-1234-5678-1234-56789abcdef0") + data = Characteristic( + uuid=VendorUUID("12345678-1234-5678-1234-56789abcdef1"), + properties=Characteristic.READ | Characteristic.WRITE, + read_perm=Attribute.OPEN, + write_perm=Attribute.OPEN, + max_length=4, + fixed_length=False, + initial_value=bytes([0xDE, 0xAD]), + )""" + +BSIM_CUSTOM_UUID_SERVER_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from custom_service import CustomService + +ble = BLERadio() +svc = CustomService() +print("service created") + +advertisement = ProvideServicesAdvertisement(svc) +ble.start_advertising(advertisement) + +for _ in range(80): + if ble.connected: + break + time.sleep(0.1) +print("connected", ble.connected) + +for _ in range(80): + if not ble.connected: + break + time.sleep(0.1) + +print("final value", list(svc.data)) +print("done") +""" + +BSIM_CUSTOM_UUID_CLIENT_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from custom_service import CustomService + +ble = BLERadio() + +target = None +for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=6.0): + if adv.connectable: + target = adv + break +ble.stop_scan() + +if target is None: + raise RuntimeError("No server found") + +connection = ble.connect(target, timeout=5.0) + +svc = connection[CustomService] +print("discovered services", 1) + +print("char value", list(svc.data)) + +svc.data = bytes([0xBE, 0xEF]) +print("wrote custom") + +time.sleep(0.5) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_CUSTOM_UUID_SERVER_CODE, "custom_service.py": CUSTOM_LIB, **_ADAFRUIT_BLE} +) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_CUSTOM_UUID_CLIENT_CODE, "custom_service.py": CUSTOM_LIB, **_ADAFRUIT_BLE} +) +def test_bsim_service_custom_uuid(bsim_phy, circuitpython1, circuitpython2): + """128-bit custom UUID service: discover, read, and write.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + server_output = server.serial.all_output + client_output = client.serial.all_output + + assert "discovered services 1" in client_output + assert "char value [222, 173]" in client_output # 0xDE, 0xAD + assert "wrote custom" in client_output + assert "final value [190, 239]" in server_output # 0xBE, 0xEF + + +# =================================================================== +# Test 7: Empty discovery result +# =================================================================== + +BSIM_EMPTY_DISC_CLIENT_CODE = """\ +import time +from adafruit_ble import BLERadio +from adafruit_ble.advertising.standard import ProvideServicesAdvertisement +from heart_rate import HeartRateService + +ble = BLERadio() + +target = None +for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=6.0): + if adv.connectable: + target = adv + print("found server") + break +ble.stop_scan() +print("have target", target is not None) + +if target is None: + raise RuntimeError("No server found") + +connection = ble.connect(target, timeout=5.0) +print("connected", connection.connected) + +# Ask for Heart Rate Service which doesn't exist on this server +found = HeartRateService in connection +print("found services", 1 if found else 0) + +connection.disconnect() + +timeout = time.monotonic() + 4.0 +while connection.connected and time.monotonic() < timeout: + time.sleep(0.1) +print("done") +""" + + +@pytest.mark.duration(14) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_CUSTOM_UUID_SERVER_CODE, "custom_service.py": CUSTOM_LIB, **_ADAFRUIT_BLE} +) +@pytest.mark.circuitpy_drive( + {"code.py": BSIM_EMPTY_DISC_CLIENT_CODE, "heart_rate.py": HEART_RATE_LIB, **_ADAFRUIT_BLE} +) +def test_bsim_service_empty_discovery(bsim_phy, circuitpython1, circuitpython2): + """Filter for a UUID that doesn't exist, verify empty tuple returned.""" + server = circuitpython1 + client = circuitpython2 + + client.wait_until_done() + server.wait_until_done() + + client_output = client.serial.all_output + + assert "found services 0" in client_output + assert "done" in client_output diff --git a/ports/zephyr-cp/tests/bsim/test_bsim_ble_uuid.py b/ports/zephyr-cp/tests/bsim/test_bsim_ble_uuid.py new file mode 100644 index 00000000000..9dcf3b13847 --- /dev/null +++ b/ports/zephyr-cp/tests/bsim/test_bsim_ble_uuid.py @@ -0,0 +1,331 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""BLE UUID tests for bsim.""" + +import pytest + + +# --- 16-bit UUIDs --- + +BSIM_UUID_16BIT_CODE = """\ +import _bleio + +u16 = _bleio.UUID(0x180F) +print("uuid16", u16.uuid16) +print("size", u16.size) +print("str", str(u16)) +print("repr", repr(u16)) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_16BIT_CODE}) +def test_bsim_uuid_16bit_basic(bsim_phy, circuitpython): + """Construct a 16-bit UUID and verify all properties.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "uuid16 6159" in output # 0x180F = 6159 + assert "size 16" in output + assert "UUID(0x180f)" in output + assert "done" in output + + +BSIM_UUID_16BIT_EQ_CODE = """\ +import _bleio + +a = _bleio.UUID(0x180F) +b = _bleio.UUID(0x180F) +c = _bleio.UUID(0x180D) + +print("eq_same", a == b) +print("eq_diff", a == c) +print("neq_diff", a != c) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_16BIT_EQ_CODE}) +def test_bsim_uuid_16bit_equality(bsim_phy, circuitpython): + """16-bit UUID equality: same value is equal, different values are not.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "eq_same True" in output + assert "eq_diff False" in output + assert "neq_diff True" in output + assert "done" in output + + +BSIM_UUID_16BIT_HASH_CODE = """\ +import _bleio + +a = _bleio.UUID(0x180F) +b = _bleio.UUID(0x180F) + +# Same UUID should hash the same +print("hash_same", hash(a) == hash(b)) + +# Can be used as dict keys +d = {a: "battery"} +print("dict_lookup", d[_bleio.UUID(0x180F)]) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_16BIT_HASH_CODE}) +def test_bsim_uuid_16bit_hash(bsim_phy, circuitpython): + """16-bit UUID can be hashed and used as dict keys.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "hash_same True" in output + assert "dict_lookup battery" in output + assert "done" in output + + +BSIM_UUID_16BIT_PACK_CODE = """\ +import _bleio + +u16 = _bleio.UUID(0x180F) +buf = bytearray(4) +u16.pack_into(buf) +print("packed", list(buf[:2])) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_16BIT_PACK_CODE}) +def test_bsim_uuid_16bit_pack_into(bsim_phy, circuitpython): + """pack_into for 16-bit UUID writes 2 bytes in little-endian.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + # 0x180F in little-endian: byte[0]=0x0F, byte[1]=0x18 + assert "packed [15, 24]" in output # 0x0F=15, 0x18=24 + assert "done" in output + + +BSIM_UUID_16BIT_PACK_OFFSET_CODE = """\ +import _bleio + +u16 = _bleio.UUID(0x2A19) +buf = bytearray(6) +u16.pack_into(buf, offset=4) +print("packed", list(buf)) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_16BIT_PACK_OFFSET_CODE}) +def test_bsim_uuid_16bit_pack_into_offset(bsim_phy, circuitpython): + """pack_into with offset writes at the correct position.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + # 0x2A19 = 10777, little-endian: [0x19, 0x2A] = [25, 42] + assert "packed [0, 0, 0, 0, 25, 42]" in output + assert "done" in output + + +# --- 128-bit UUID string parsing --- + +BSIM_UUID_128BIT_STR_CODE = """\ +import _bleio + +u128 = _bleio.UUID("12345678-1234-5678-1234-56789abcdef0") +print("uuid16", u128.uuid16) +print("size", u128.size) +print("uuid128_len", len(u128.uuid128)) +# Bytes 12-13 are zeroed by shared-bindings (extracted as uuid16) +# First 4 bytes of uuid128 are [f0, de, bc, 9a] in LE +print("bytes_0_3", list(u128.uuid128[:4])) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_128BIT_STR_CODE}) +def test_bsim_uuid_128bit_string(bsim_phy, circuitpython): + """Construct a 128-bit UUID from a hex string.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "size 128" in output + # uuid16 extracted from bytes 12-13: 0x5678 = 22136 + assert "uuid16 22136" in output + assert "uuid128_len 16" in output + # Bytes 12-13 are restored from uuid16 by common_hal_bleio_uuid_construct + # First 4 bytes of uuid128 are [f0, de, bc, 9a] in LE + assert "bytes_0_3 [240, 222, 188, 154]" in output + assert "done" in output + + +# --- 128-bit UUID bytes construction --- + +BSIM_UUID_128BIT_BYTES_CODE = """\ +import _bleio + +raw = bytes([0xf0, 0xde, 0xbc, 0x9a, 0x78, 0x56, 0x34, 0x12, + 0x34, 0x12, 0x78, 0x56, 0x34, 0x12, 0x78, 0x56]) +u128 = _bleio.UUID(raw) +print("size", u128.size) +# uuid16 extracted from raw[12:14] = [0x34, 0x12] → 0x1234 = 4660 +print("uuid16", u128.uuid16) +print("uuid128_len", len(u128.uuid128)) +# Bytes 12-13 are restored from uuid16 by common_hal_bleio_uuid_construct +print("bytes_12_13", list(u128.uuid128[12:14])) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_128BIT_BYTES_CODE}) +def test_bsim_uuid_128bit_bytes(bsim_phy, circuitpython): + """Construct a 128-bit UUID from a 16-byte buffer.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "size 128" in output + assert "uuid16 4660" in output + assert "uuid128_len 16" in output + # Bytes 12-13 restored from uuid16: 0x1234 → [0x34, 0x12] = [52, 18] + assert "bytes_12_13 [52, 18]" in output + assert "done" in output + + +# --- 128-bit UUID equality --- + +BSIM_UUID_128BIT_EQ_CODE = """\ +import _bleio + +a = _bleio.UUID("12345678-1234-5678-1234-56789abcdef0") +b = _bleio.UUID("12345678-1234-5678-1234-56789abcdef0") +c = _bleio.UUID("00000000-0000-1000-8000-00805f9b34fb") + +print("eq_same", a == b) +print("eq_diff", a == c) +print("neq_diff", a != c) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_128BIT_EQ_CODE}) +def test_bsim_uuid_128bit_equality(bsim_phy, circuitpython): + """128-bit UUID equality: same bytes equal, different not.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "eq_same True" in output + assert "eq_diff False" in output + assert "neq_diff True" in output + assert "done" in output + + +# --- 16-bit vs 128-bit UUID equality (should not be equal even if same value) --- + +BSIM_UUID_CROSS_SIZE_EQ_CODE = """\ +import _bleio + +# 0x180F as 16-bit +u16 = _bleio.UUID(0x180F) + +# 0x180F expanded to 128-bit base UUID +# Bluetooth base: 00000000-0000-1000-8000-00805F9B34FB +# With 0x180F: 0000180F-0000-1000-8000-00805F9B34FB +u128 = _bleio.UUID("0000180f-0000-1000-8000-00805f9b34fb") + +print("size_16", u16.size) +print("size_128", u128.size) +# Per spec, 16-bit and 128-bit are NOT equal even if values match +print("cross_eq", u16 == u128) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_CROSS_SIZE_EQ_CODE}) +def test_bsim_uuid_cross_size_equality(bsim_phy, circuitpython): + """16-bit and 128-bit UUIDs are not equal even with same value.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "size_16 16" in output + assert "size_128 128" in output + assert "cross_eq False" in output + assert "done" in output + + +# --- Invalid UUID string --- + +BSIM_UUID_INVALID_STR_CODE = """\ +import _bleio + +try: + u = _bleio.UUID("not-a-uuid") + print("should not reach") +except ValueError as e: + print("value_error", "not" in str(e) or "UUID" in str(e)) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_INVALID_STR_CODE}) +def test_bsim_uuid_invalid_string(bsim_phy, circuitpython): + """Invalid UUID string raises ValueError.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "value_error True" in output + assert "done" in output + + +# --- UUID 128-bit: uuid128 property works, uuid16 returns 16-bit part --- + +BSIM_UUID_128BIT_PROPS_CODE = """\ +import _bleio + +u128 = _bleio.UUID("12345678-1234-5678-1234-56789abcdef0") +print("size", u128.size) +# uuid128 returns 16 bytes (bytes 12-13 are restored from uuid16) +b = u128.uuid128 +print("uuid128_len", len(b)) +# uuid16 is the 16-bit part from bytes 12-13, extracted and then restored +print("uuid16", u128.uuid16) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_128BIT_PROPS_CODE}) +def test_bsim_uuid_128bit_properties(bsim_phy, circuitpython): + """128-bit UUID exposes uuid128 bytes and uuid16 from bytes 12-13.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "size 128" in output + assert "uuid128_len 16" in output + assert "uuid16 22136" in output + assert "done" in output + + +# --- 16-bit uuid128 raises AttributeError --- + +BSIM_UUID_16BIT_NO_UUID128_CODE = """\ +import _bleio + +u16 = _bleio.UUID(0x180F) +try: + _ = u16.uuid128 + print("should not reach") +except AttributeError: + print("attr_error ok") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BSIM_UUID_16BIT_NO_UUID128_CODE}) +def test_bsim_uuid_16bit_no_uuid128(bsim_phy, circuitpython): + """Accessing uuid128 on a 16-bit UUID raises AttributeError.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "attr_error ok" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/conftest.py b/ports/zephyr-cp/tests/conftest.py new file mode 100644 index 00000000000..0efe3bcc3fe --- /dev/null +++ b/ports/zephyr-cp/tests/conftest.py @@ -0,0 +1,396 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Pytest fixtures for CircuitPython native_sim testing.""" + +import logging +import os +import subprocess +from pathlib import Path + +import pytest +import serial + +from .perfetto_input_trace import write_input_trace + +from perfetto.trace_processor import TraceProcessor + +from . import NativeSimProcess + +logger = logging.getLogger(__name__) + + +def pytest_addoption(parser): + parser.addoption( + "--update-goldens", + action="store_true", + default=False, + help="Overwrite golden images with captured output instead of comparing.", + ) + + +def pytest_configure(config): + config.addinivalue_line( + "markers", "circuitpy_drive(files): run CircuitPython with files in the flash image" + ) + config.addinivalue_line( + "markers", "disable_i2c_devices(*names): disable native_sim I2C emulator devices" + ) + config.addinivalue_line( + "markers", "circuitpython_board(board_id): which board id to use in the test" + ) + config.addinivalue_line( + "markers", + "zephyr_sample(sample, board='nrf52_bsim', device_id=1): build and run a Zephyr sample for bsim tests", + ) + config.addinivalue_line( + "markers", + "duration(seconds): native_sim timeout and bsim PHY simulation duration", + ) + config.addinivalue_line( + "markers", + "code_py_runs(count): stop native_sim after count code.py runs (default: 1)", + ) + config.addinivalue_line( + "markers", + "input_trace(trace): inject input signal trace data into native_sim", + ) + config.addinivalue_line( + "markers", + "native_sim_rt: run native_sim in realtime mode (-rt instead of -no-rt)", + ) + config.addinivalue_line( + "markers", + "display(capture_times_ns=None): run test with SDL display; " + "capture_times_ns is a list of nanosecond timestamps for trace-triggered captures", + ) + config.addinivalue_line( + "markers", + "display_pixel_format(format): override the display pixel format " + "(e.g. 'RGB_565', 'ARGB_8888')", + ) + config.addinivalue_line( + "markers", + "display_mono_vtiled(value): override the mono vtiled screen_info flag (True or False)", + ) + config.addinivalue_line( + "markers", + "flash_config(erase_block_size=N, total_size=N): override flash simulator parameters", + ) + + +ZEPHYR_CP = Path(__file__).parent.parent +BUILD_DIR = ZEPHYR_CP / "build-native_native_sim" +BINARY = BUILD_DIR / "zephyr-cp/zephyr/zephyr.exe" + + +def _iter_uart_tx_slices(trace_file: Path) -> list[tuple[int, int, str, str]]: + """Return UART TX slices as (timestamp_ns, duration_ns, text, device_name).""" + tp = TraceProcessor(file_path=str(trace_file)) + result = tp.query( + """ + SELECT s.ts, s.dur, s.name, dev.name AS device_name + FROM slice s + JOIN track tx ON s.track_id = tx.id + JOIN track dev ON tx.parent_id = dev.id + JOIN track uart ON dev.parent_id = uart.id + WHERE tx.name = "TX" AND uart.name = "UART" + ORDER BY s.ts + """ + ) + return [ + (int(row.ts), int(row.dur or 0), row.name or "", row.device_name or "UART") + for row in result + ] + + +def log_uart_trace_output(trace_file: Path) -> None: + """Log UART TX output from Perfetto trace with timestamps for line starts.""" + if not logger.isEnabledFor(logging.INFO): + return + slices = _iter_uart_tx_slices(trace_file) + if not slices: + return + + buffers: dict[str, list[str]] = {} + line_start_ts: dict[str, int | None] = {} + + for ts, dur, text, device in slices: + if device not in buffers: + buffers[device] = [] + line_start_ts[device] = None + + if not text: + continue + + char_step = dur / max(len(text), 1) if dur > 0 else 0.0 + for idx, ch in enumerate(text): + if line_start_ts[device] is None: + line_start_ts[device] = int(ts + idx * char_step) + buffers[device].append(ch) + if ch == "\n": + line_text = "".join(buffers[device]).rstrip("\n") + logger.info( + "UART trace %s @%d ns: %s", + device, + line_start_ts[device], + repr(line_text), + ) + buffers[device] = [] + line_start_ts[device] = None + + for device, buf in buffers.items(): + if buf: + logger.info( + "UART trace %s @%d ns (partial): %s", + device, + line_start_ts[device] or 0, + repr("".join(buf)), + ) + + +@pytest.fixture +def board(request): + board = request.node.get_closest_marker("circuitpython_board") + if board is not None: + board = board.args[0] + else: + board = "native_native_sim" + return board + + +@pytest.fixture +def native_sim_binary(request, board): + """Return path to native_sim binary, skip if not built.""" + build_dir = ZEPHYR_CP / f"build-{board}" + binary = build_dir / "zephyr-cp/zephyr/zephyr.exe" + + if not binary.exists(): + pytest.skip(f"binary not built: {binary}") + return binary + + +@pytest.fixture +def native_sim_env() -> dict[str, str]: + return {} + + +PIXEL_FORMAT_BITMASK = { + "RGB_888": 1 << 0, + "MONO01": 1 << 1, + "MONO10": 1 << 2, + "ARGB_8888": 1 << 3, + "RGB_565": 1 << 4, + "BGR_565": 1 << 5, + "L_8": 1 << 6, + "AL_88": 1 << 7, +} + + +@pytest.fixture +def pixel_format(request) -> str: + """Indirect-parametrize fixture: adds display_pixel_format marker.""" + fmt = request.param + request.node.add_marker(pytest.mark.display_pixel_format(fmt)) + return fmt + + +@pytest.fixture +def sim_id(request) -> str: + return request.node.nodeid.replace("/", "_") + + +@pytest.fixture +def circuitpython(request, board, sim_id, native_sim_binary, native_sim_env, tmp_path): + """Run CircuitPython with given code string and return PTY output.""" + + instance_count = 1 + if "circuitpython1" in request.fixturenames and "circuitpython2" in request.fixturenames: + instance_count = 2 + + drives = list(request.node.iter_markers_with_node("circuitpy_drive")) + if len(drives) != instance_count: + raise RuntimeError(f"not enough drives for {instance_count} instances") + + input_trace_markers = list(request.node.iter_markers_with_node("input_trace")) + if len(input_trace_markers) > 1: + raise RuntimeError("expected at most one input_trace marker") + + input_trace = None + if input_trace_markers and len(input_trace_markers[0][1].args) == 1: + input_trace = input_trace_markers[0][1].args[0] + + input_trace_file = None + if input_trace is not None: + input_trace_file = tmp_path / "input.perfetto" + write_input_trace(input_trace_file, input_trace) + + marker = request.node.get_closest_marker("duration") + if marker is None: + timeout = 10 + else: + timeout = marker.args[0] + + runs_marker = request.node.get_closest_marker("code_py_runs") + if runs_marker is None: + code_py_runs = 1 + else: + code_py_runs = int(runs_marker.args[0]) + + display_marker = request.node.get_closest_marker("display") + if display_marker is None: + display_marker = request.node.get_closest_marker("display_capture") + + capture_times_ns = None + if display_marker is not None: + capture_times_ns = display_marker.kwargs.get("capture_times_ns", None) + + pixel_format_marker = request.node.get_closest_marker("display_pixel_format") + pixel_format = None + if pixel_format_marker is not None and pixel_format_marker.args: + pixel_format = pixel_format_marker.args[0] + + mono_vtiled_marker = request.node.get_closest_marker("display_mono_vtiled") + mono_vtiled = None + if mono_vtiled_marker is not None and mono_vtiled_marker.args: + mono_vtiled = mono_vtiled_marker.args[0] + + # If capture_times_ns is set, merge display_capture track into input trace. + if capture_times_ns is not None: + if input_trace is None: + input_trace = {} + else: + input_trace = dict(input_trace) + input_trace["display_capture"] = list(capture_times_ns) + if input_trace_file is None: + input_trace_file = tmp_path / "input.perfetto" + write_input_trace(input_trace_file, input_trace) + + use_realtime = request.node.get_closest_marker("native_sim_rt") is not None + + flash_config_marker = request.node.get_closest_marker("flash_config") + flash_total_size = 2 * 1024 * 1024 # default 2MB + flash_erase_block_size = None + flash_write_block_size = None + if flash_config_marker: + flash_total_size = flash_config_marker.kwargs.get("total_size", flash_total_size) + flash_erase_block_size = flash_config_marker.kwargs.get("erase_block_size", None) + flash_write_block_size = flash_config_marker.kwargs.get("write_block_size", None) + + procs = [] + for i in range(instance_count): + flash = tmp_path / f"flash-{i}.bin" + flash.write_bytes(b"\xff" * flash_total_size) + files = None + if len(drives[i][1].args) == 1: + files = drives[i][1].args[0] + if files is not None: + subprocess.run(["mformat", "-i", str(flash), "::"], check=True) + tmp_drive = tmp_path / f"drive{i}" + tmp_drive.mkdir(exist_ok=True) + + fat_dirs_created = set() + for name, content in files.items(): + src = tmp_drive / name + src.parent.mkdir(parents=True, exist_ok=True) + if isinstance(content, bytes): + src.write_bytes(content) + else: + src.write_text(content) + # Create parent directories on the FAT image. + fat_dir = Path(name).parent + for fat_part in [*reversed(fat_dir.parents), fat_dir]: + if fat_part == Path("."): + continue + fat_path = "::" + str(fat_part) + if fat_path not in fat_dirs_created: + subprocess.run(["mmd", "-i", str(flash), fat_path], check=True) + fat_dirs_created.add(fat_path) + subprocess.run(["mcopy", "-i", str(flash), str(src), f"::{name}"], check=True) + + trace_file = tmp_path / f"trace-{i}.perfetto" + + if "bsim" in board: + # nRF54 bsim boards use RRAMC (--flash), others use NVMC (--flash_app) + flash_arg = "--flash" if "nrf54" in board else "--flash_app" + cmd = [str(native_sim_binary), f"{flash_arg}={flash}"] + if instance_count > 1: + cmd.append("-disconnect_on_exit=1") + # nRF54 bsim boards: console UART is SERIAL20 (bsim instance 1), others use instance 0 + uart_n = "1" if "nrf54" in board else "0" + cmd.extend( + ( + f"-s={sim_id}", + f"-d={i}", + f"-uart{uart_n}_pty", + f"-uart{uart_n}_pty_wait_for_readers", + "-uart_pty_wait", + f"--vm-runs={code_py_runs + 1}", + ) + ) + else: + cmd = [str(native_sim_binary), f"--flash={flash}"] + # native_sim vm-runs includes the boot VM setup run. + realtime_flag = "-rt" if use_realtime else "-no-rt" + cmd.extend( + ( + realtime_flag, + "-display_headless", + "-i2s_earless", + "-wait_uart", + f"--vm-runs={code_py_runs + 1}", + ) + ) + + if flash_erase_block_size is not None: + cmd.append(f"--flash_erase_block_size={flash_erase_block_size}") + if flash_write_block_size is not None: + cmd.append(f"--flash_write_block_size={flash_write_block_size}") + if flash_config_marker and "total_size" in flash_config_marker.kwargs: + cmd.append(f"--flash_total_size={flash_total_size}") + + if input_trace_file is not None: + cmd.append(f"--input-trace={input_trace_file}") + + marker = request.node.get_closest_marker("disable_i2c_devices") + if marker and len(marker.args) > 0: + for device in marker.args: + cmd.append(f"--disable-i2c={device}") + + if pixel_format is not None: + cmd.append(f"--display_pixel_format={PIXEL_FORMAT_BITMASK[pixel_format]}") + + if mono_vtiled is not None: + cmd.append(f"--display_mono_vtiled={'true' if mono_vtiled else 'false'}") + + env = os.environ.copy() + env.update(native_sim_env) + + capture_png_pattern = None + if capture_times_ns is not None: + if instance_count == 1: + capture_png_pattern = str(tmp_path / "frame_%d.png") + else: + capture_png_pattern = str(tmp_path / f"frame-{i}_%d.png") + cmd.append(f"--display_capture_png={capture_png_pattern}") + + logger.info("Running: %s", " ".join(cmd)) + proc = NativeSimProcess(cmd, timeout, trace_file, env, flash_file=flash) + proc.display_dump = None + proc._capture_png_pattern = capture_png_pattern + proc._capture_count = len(capture_times_ns) if capture_times_ns is not None else 0 + procs.append(proc) + if instance_count == 1: + yield procs[0] + else: + yield procs + for i, proc in enumerate(procs): + if instance_count > 1: + print(f"---------- Instance {i} -----------") + proc.shutdown() + + print("All serial output:") + print(proc.serial.all_output) + print() + print("All debug serial output:") + print(proc.debug_serial.all_output) diff --git a/ports/zephyr-cp/tests/docs/babblesim.md b/ports/zephyr-cp/tests/docs/babblesim.md new file mode 100644 index 00000000000..75d45079b2e --- /dev/null +++ b/ports/zephyr-cp/tests/docs/babblesim.md @@ -0,0 +1,81 @@ +# BabbleSim testing + +This document describes how to build and run CircuitPython tests against the +BabbleSim (bsim) nRF5340 board. + +## Board target + +We use the Zephyr BabbleSim board for the nRF5340 application core: + +- Zephyr board: `nrf5340bsim/nrf5340/cpuapp` +- CircuitPython board alias: `native_nrf5340bsim` + +The tests expect two bsim instances to run in the same simulation, which allows +future BLE/802.15.4 multi-node tests. + +## Prerequisites + +BabbleSim needs to be available to Zephyr. Either: + +- Use the repo-provided `tools/bsim` checkout (if present) +- Or set environment variables: + +``` +export BSIM_COMPONENTS_PATH=/path/to/bsim/components +export BSIM_OUT_PATH=/path/to/bsim +``` + +## Build + +``` +CCACHE_TEMPDIR=/tmp/ccache-tmp make -j BOARD=native_nrf5340bsim +``` + +If you do not use ccache, you can omit `CCACHE_TEMPDIR`. + +## Run the bsim test + +``` +pytest tests/test_bsim_basics.py -v +``` + +## BLE scan + advertising tests + +The BLE tests run multiple bsim instances and build Zephyr samples on-demand: + +- `tests/test_bsim_ble_scan.py` scans for the Zephyr beacon sample +- `tests/test_bsim_ble_advertising.py` advertises from CircuitPython while the + Zephyr observer sample scans + +The fixtures build the Zephyr samples if missing: + +- Beacon: `zephyr/samples/bluetooth/beacon` (board `nrf52_bsim`) +- Observer: `zephyr/samples/bluetooth/observer` (board `nrf52_bsim`) + +Run the tests with: + +``` +pytest tests/test_bsim_ble_scan.py -v +pytest tests/test_bsim_ble_advertising.py -v +``` + +## Pytest markers + +For bsim-specific test tuning: + +- `@pytest.mark.duration(seconds)` controls simulation runtime/timeout. + +Example: + +```py +pytestmark = pytest.mark.duration(30.0) +``` + +## Notes + +- The bsim test spawns two instances that share a sim id. It only checks UART + output for now, but is the base for BLE/Thread multi-node tests. +- The BLE tests rely on the sysbuild HCI IPC net-core image for the nRF5340 + simulator (enabled via `sysbuild.conf`). +- The board uses a custom devicetree overlay to provide the SRAM region and + CircuitPython flash partition expected by the port. diff --git a/ports/zephyr-cp/tests/docs/i2c_emulator_cmdline_control.md b/ports/zephyr-cp/tests/docs/i2c_emulator_cmdline_control.md new file mode 100644 index 00000000000..8ee2925915c --- /dev/null +++ b/ports/zephyr-cp/tests/docs/i2c_emulator_cmdline_control.md @@ -0,0 +1,306 @@ +# Command-Line Control of Emulated I2C Devices in native_sim + +This document describes an approach for enabling/disabling emulated I2C devices +at runtime via command-line options in Zephyr's native_sim environment. + +## Background + +Zephyr's I2C emulation framework (`zephyr,i2c-emul-controller`) provides: + +1. **Bus emulation** - Fake I2C controller that routes transfers to emulated devices +2. **Device emulators** - Software implementations of I2C peripherals (sensors, etc.) +3. **Backend APIs** - Test interfaces for manipulating emulator state + +However, there's no built-in mechanism to enable/disable emulated devices from the +command line. This capability would be useful for: + +- Testing device hot-plug scenarios +- Simulating hardware failures +- Testing error handling paths in CircuitPython + +## Relevant Zephyr APIs + +### I2C Emulator Structure + +From `include/zephyr/drivers/i2c_emul.h`: + +```c +struct i2c_emul { + sys_snode_t node; + const struct emul *target; + const struct i2c_emul_api *api; + struct i2c_emul_api *mock_api; // If non-NULL, takes precedence + uint16_t addr; +}; + +struct i2c_emul_api { + i2c_emul_transfer_t transfer; +}; +``` + +Key insight: The `mock_api` field allows overriding the normal transfer function. +If `mock_api->transfer()` returns `-ENOSYS`, it falls back to the real API. + +### Command-Line Registration + +From `boards/native/native_sim/cmdline.h`: + +```c +void native_add_command_line_opts(struct args_struct_t *args); +``` + +### Emulator Lookup + +From `include/zephyr/drivers/emul.h`: + +```c +const struct emul *emul_get_binding(const char *name); +``` + +## Implementation Approach + +### 1. Create a Disabled Device Registry + +Track which devices are "disabled" (should NACK all transactions): + +```c +// i2c_emul_cmdline.c + +#include +#include +#include +#include "nsi_cmdline.h" + +#define MAX_DISABLED_DEVICES 16 + +static struct { + const char *name; + const struct emul *emul; + struct i2c_emul_api mock_api; + struct i2c_emul_api *original_mock_api; + bool disabled; +} disabled_devices[MAX_DISABLED_DEVICES]; + +static int num_disabled_devices = 0; +``` + +### 2. Mock Transfer Function + +Return `-EIO` (simulates NACK) when device is disabled: + +```c +static int disabled_device_transfer(const struct emul *target, + struct i2c_msg *msgs, + int num_msgs, + int addr) +{ + // Find this device in our registry + for (int i = 0; i < num_disabled_devices; i++) { + if (disabled_devices[i].emul == target) { + if (disabled_devices[i].disabled) { + // Device is disabled - simulate NACK + return -EIO; + } + break; + } + } + // Fall back to normal emulator behavior + return -ENOSYS; +} +``` + +### 3. Enable/Disable Functions + +```c +int i2c_emul_cmdline_disable_device(const char *name) +{ + const struct emul *emul = emul_get_binding(name); + if (!emul || emul->bus_type != EMUL_BUS_TYPE_I2C) { + return -ENODEV; + } + + // Find or create registry entry + int idx = -1; + for (int i = 0; i < num_disabled_devices; i++) { + if (disabled_devices[i].emul == emul) { + idx = i; + break; + } + } + + if (idx < 0) { + if (num_disabled_devices >= MAX_DISABLED_DEVICES) { + return -ENOMEM; + } + idx = num_disabled_devices++; + disabled_devices[idx].name = name; + disabled_devices[idx].emul = emul; + disabled_devices[idx].mock_api.transfer = disabled_device_transfer; + + // Save and replace mock_api + disabled_devices[idx].original_mock_api = emul->bus.i2c->mock_api; + emul->bus.i2c->mock_api = &disabled_devices[idx].mock_api; + } + + disabled_devices[idx].disabled = true; + return 0; +} + +int i2c_emul_cmdline_enable_device(const char *name) +{ + for (int i = 0; i < num_disabled_devices; i++) { + if (strcmp(disabled_devices[i].name, name) == 0) { + disabled_devices[i].disabled = false; + return 0; + } + } + return -ENODEV; +} +``` + +### 4. Command-Line Option Registration + +```c +static char *disabled_device_args[MAX_DISABLED_DEVICES]; +static int num_disabled_device_args = 0; + +static void cmd_disable_i2c_device(char *argv, int offset) +{ + ARG_UNUSED(offset); + if (num_disabled_device_args < MAX_DISABLED_DEVICES) { + disabled_device_args[num_disabled_device_args++] = argv; + } +} + +static struct args_struct_t i2c_emul_args[] = { + { + .option = "disable-i2c", + .name = "device_name", + .type = 's', + .call_when_found = cmd_disable_i2c_device, + .descript = "Disable an emulated I2C device (can be repeated)" + }, + ARG_TABLE_ENDMARKER +}; + +static void register_cmdline_opts(void) +{ + native_add_command_line_opts(i2c_emul_args); +} + +// Hook into native_sim initialization +NATIVE_TASK(register_cmdline_opts, PRE_BOOT_1, 0); + +static void apply_disabled_devices(void) +{ + for (int i = 0; i < num_disabled_device_args; i++) { + int rc = i2c_emul_cmdline_disable_device(disabled_device_args[i]); + if (rc != 0) { + printk("Warning: Failed to disable I2C device '%s': %d\n", + disabled_device_args[i], rc); + } + } +} + +// Apply after emulators are initialized +NATIVE_TASK(apply_disabled_devices, PRE_BOOT_3, 0); +``` + +### 5. Usage + +After building with this code: + +```bash +# Disable a sensor at startup +./build/zephyr/zephyr.exe --disable-i2c=bmi160@68 + +# Disable multiple devices +./build/zephyr/zephyr.exe --disable-i2c=bmi160@68 --disable-i2c=sht4x@44 +``` + +## Runtime Control Extension + +For runtime enable/disable (not just at startup), you could: + +### Option A: Use a Named Pipe / FIFO + +```c +// Create a FIFO that accepts commands +// "disable bmi160@68" or "enable bmi160@68" +static void *cmdline_control_thread(void *arg) +{ + int fd = open("/tmp/i2c_emul_control", O_RDONLY); + char buf[256]; + while (read(fd, buf, sizeof(buf)) > 0) { + if (strncmp(buf, "disable ", 8) == 0) { + i2c_emul_cmdline_disable_device(buf + 8); + } else if (strncmp(buf, "enable ", 7) == 0) { + i2c_emul_cmdline_enable_device(buf + 7); + } + } + return NULL; +} +``` + +### Option B: Signal Handler + +Use `SIGUSR1`/`SIGUSR2` with a config file that specifies which device to toggle. + +### Option C: Shared Memory + +Map a shared memory region that external tools can write to for device state. + +## Integration with CircuitPython Tests + +For pytest-based tests, you could: + +```python +import subprocess +import os + +class NativeSimProcess: + def __init__(self, exe_path): + self.exe_path = exe_path + self.control_fifo = "/tmp/i2c_emul_control" + + def start(self, disabled_devices=None): + args = [self.exe_path] + if disabled_devices: + for dev in disabled_devices: + args.extend(["--disable-i2c", dev]) + self.proc = subprocess.Popen(args, ...) + + def disable_device(self, name): + """Runtime disable via FIFO""" + with open(self.control_fifo, 'w') as f: + f.write(f"disable {name}\n") + + def enable_device(self, name): + """Runtime enable via FIFO""" + with open(self.control_fifo, 'w') as f: + f.write(f"enable {name}\n") +``` + +## Alternative: Device Tree Approach + +For compile-time configuration, use device tree overlays: + +```dts +// boards/native_sim_no_bmi160.overlay +&bmi160 { + status = "disabled"; +}; +``` + +Build separate variants: +```bash +west build -b native_sim -- -DDTC_OVERLAY_FILE=boards/native_sim_no_bmi160.overlay +``` + +## References + +- Zephyr I2C Emulation: `zephyr/drivers/i2c/i2c_emul.c` +- Emulator Framework: `zephyr/doc/hardware/emulator/bus_emulators.rst` +- Native Sim Docs: `zephyr/boards/native/native_sim/doc/index.rst` +- Command-line handling: `zephyr/boards/native/native_sim/cmdline.c` +- Example mock API usage: `zephyr/tests/drivers/sensor/bmi160/src/i2c.c` diff --git a/ports/zephyr-cp/tests/docs/web_workflow.md b/ports/zephyr-cp/tests/docs/web_workflow.md new file mode 100644 index 00000000000..eb6742b8a3e --- /dev/null +++ b/ports/zephyr-cp/tests/docs/web_workflow.md @@ -0,0 +1,37 @@ +# Web Workflow native_sim Tests + +These tests validate CircuitPython's web workflow support in the Zephyr native_sim port, including filesystem write behavior with and without USB-style write protection. + +## Coverage + +- `test_web_workflow_hostnetwork`: Verifies the web workflow HTTP server responds and enforces authentication (`/edit/` returns `401 Unauthorized`). +- `test_web_workflow_write_code_py_conflict`: Exercises a write attempt while the filesystem is protected (no `boot.py` remount). The DELETE request should return `409 Conflict`. +- `test_web_workflow_write_code_py_remount`: Uses a `boot.py` remount to allow CircuitPython to write. A PUT request updates `code.py`, and a subsequent GET verifies the contents. + +## Filesystem Setup + +The tests create a flash image with: + +- `settings.toml` containing `CIRCUITPY_WEB_API_PASSWORD="testpass"` so the web workflow starts using the on-device settings file. +- `boot.py` (for the remount test only) with: + ```python + import storage + storage.remount("/", readonly=False) + ``` + This disables concurrent write protection so the web workflow can write to CIRCUITPY. + +## Running the Tests + +Build native_sim (if needed): + +```bash +make BOARD=native_native_sim +``` + +Run the tests: + +```bash +pytest -q ports/zephyr-cp/tests/test_web_workflow.py::test_web_workflow_hostnetwork -vv +pytest -q ports/zephyr-cp/tests/test_web_workflow.py::test_web_workflow_write_code_py_conflict -vv +pytest -q ports/zephyr-cp/tests/test_web_workflow.py::test_web_workflow_write_code_py_remount -vv +``` diff --git a/ports/zephyr-cp/tests/perfetto_input_trace.py b/ports/zephyr-cp/tests/perfetto_input_trace.py new file mode 100644 index 00000000000..494c9cdcadf --- /dev/null +++ b/ports/zephyr-cp/tests/perfetto_input_trace.py @@ -0,0 +1,159 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries LLC +# SPDX-License-Identifier: MIT + +"""Utilities for creating Perfetto input trace files for native_sim tests. + +This module can be used directly from Python or from the command line: + + python -m tests.perfetto_input_trace input_trace.json output.perfetto + +Input JSON format — counter tracks use [timestamp, value] pairs, instant +tracks use bare timestamps: + +{ + "gpio_emul.01": [[8000000000, 0], [9000000000, 1], [10000000000, 0]], + "display_capture": [500000000, 1000000000] +} +""" + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +from typing import Mapping, Sequence + +# Counter tracks: list of (timestamp, value) pairs. +# Instant tracks: list of timestamps (bare ints). +InputTraceData = Mapping[str, Sequence[tuple[int, int] | int]] + + +def _load_perfetto_pb2(): + from perfetto.protos.perfetto.trace import perfetto_trace_pb2 as perfetto_pb2 + + return perfetto_pb2 + + +def _is_instant_track(events: Sequence) -> bool: + """Return True if *events* is a list of bare timestamps (instant track).""" + if not events: + return False + return isinstance(events[0], int) + + +def build_input_trace(trace_data: InputTraceData, *, sequence_id: int = 1): + """Build a Perfetto Trace protobuf for input replay counter and instant tracks.""" + perfetto_pb2 = _load_perfetto_pb2() + trace = perfetto_pb2.Trace() + + seq_incremental_state_cleared = 1 + seq_needs_incremental_state = 2 + + for idx, (track_name, events) in enumerate(trace_data.items()): + track_uuid = 1001 + idx + instant = _is_instant_track(events) + + desc_packet = trace.packet.add() + desc_packet.timestamp = 0 + desc_packet.trusted_packet_sequence_id = sequence_id + if idx == 0: + desc_packet.sequence_flags = seq_incremental_state_cleared + desc_packet.track_descriptor.uuid = track_uuid + desc_packet.track_descriptor.name = track_name + if not instant: + desc_packet.track_descriptor.counter.unit = ( + perfetto_pb2.CounterDescriptor.Unit.UNIT_COUNT + ) + + if instant: + for ts in events: + event_packet = trace.packet.add() + event_packet.timestamp = ts + event_packet.trusted_packet_sequence_id = sequence_id + event_packet.sequence_flags = seq_needs_incremental_state + event_packet.track_event.type = perfetto_pb2.TrackEvent.Type.TYPE_INSTANT + event_packet.track_event.track_uuid = track_uuid + else: + for ts, value in events: + event_packet = trace.packet.add() + event_packet.timestamp = ts + event_packet.trusted_packet_sequence_id = sequence_id + event_packet.sequence_flags = seq_needs_incremental_state + event_packet.track_event.type = perfetto_pb2.TrackEvent.Type.TYPE_COUNTER + event_packet.track_event.track_uuid = track_uuid + event_packet.track_event.counter_value = value + + return trace + + +def write_input_trace( + trace_file: Path, trace_data: InputTraceData, *, sequence_id: int = 1 +) -> None: + """Write input replay data to a Perfetto trace file.""" + trace = build_input_trace(trace_data, sequence_id=sequence_id) + trace_file.parent.mkdir(parents=True, exist_ok=True) + trace_file.write_bytes(trace.SerializeToString()) + + +def _parse_trace_json(data: object) -> dict[str, list[tuple[int, int]] | list[int]]: + if not isinstance(data, dict): + raise ValueError("top-level JSON value must be an object") + + parsed: dict[str, list[tuple[int, int]] | list[int]] = {} + for track_name, events in data.items(): + if not isinstance(track_name, str): + raise ValueError("track names must be strings") + if not isinstance(events, list): + raise ValueError(f"track {track_name!r} must map to a list of events") + + if not events: + parsed[track_name] = [] + continue + + # Distinguish instant (bare ints) vs counter ([ts, value] pairs). + if isinstance(events[0], (int, float)): + parsed[track_name] = [int(ts) for ts in events] + else: + parsed_events: list[tuple[int, int]] = [] + for event in events: + if not isinstance(event, (list, tuple)) or len(event) != 2: + raise ValueError( + f"track {track_name!r} events must be [timestamp, value] pairs " + "or bare timestamps" + ) + timestamp_ns, value = event + parsed_events.append((int(timestamp_ns), int(value))) + parsed[track_name] = parsed_events + + return parsed + + +def _build_arg_parser() -> argparse.ArgumentParser: + parser = argparse.ArgumentParser( + description="Generate a Perfetto input trace file used by native_sim --input-trace" + ) + parser.add_argument("input_json", type=Path, help="Path to input trace JSON") + parser.add_argument("output_trace", type=Path, help="Output .perfetto file path") + parser.add_argument( + "--sequence-id", + type=int, + default=1, + help="trusted_packet_sequence_id to use (default: 1)", + ) + return parser + + +def main(argv: Sequence[str] | None = None) -> int: + parser = _build_arg_parser() + args = parser.parse_args(argv) + + trace_json = json.loads(args.input_json.read_text()) + trace_data = _parse_trace_json(trace_json) + write_input_trace(args.output_trace, trace_data, sequence_id=args.sequence_id) + + print(f"Wrote {args.output_trace} ({len(trace_data)} tracks)") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/ports/zephyr-cp/tests/test_adafruit_bus_device.py b/ports/zephyr-cp/tests/test_adafruit_bus_device.py new file mode 100644 index 00000000000..3022838506e --- /dev/null +++ b/ports/zephyr-cp/tests/test_adafruit_bus_device.py @@ -0,0 +1,236 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test adafruit_bus_device.i2c_device.I2CDevice against the AT24 EEPROM emulator.""" + +import pytest + + +PROBE_OK_CODE = """\ +import board +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +device = I2CDevice(i2c, 0x50) +print(f"device created: {type(device).__name__}") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": PROBE_OK_CODE}) +def test_i2cdevice_probe_success(circuitpython): + """Constructing I2CDevice with probe=True succeeds when AT24 is present at 0x50.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "device created: I2CDevice" in output + assert "done" in output + + +PROBE_FAIL_CODE = """\ +import board +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +try: + device = I2CDevice(i2c, 0x51) + print("unexpected_success") +except ValueError as e: + print(f"probe_failed: {e}") +except OSError as e: + print(f"probe_failed: {e}") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": PROBE_FAIL_CODE}) +def test_i2cdevice_probe_failure(circuitpython): + """Constructing I2CDevice with probe=True raises when no device responds.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "probe_failed" in output + assert "unexpected_success" not in output + assert "done" in output + + +PROBE_DISABLED_CODE = """\ +import board +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +# probe=False should not raise even without a device at this address +device = I2CDevice(i2c, 0x51, probe=False) +print(f"device created: {type(device).__name__}") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": PROBE_DISABLED_CODE}) +def test_i2cdevice_probe_disabled(circuitpython): + """Constructing I2CDevice with probe=False succeeds regardless of device presence.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "device created: I2CDevice" in output + assert "done" in output + + +READ_CODE = """\ +import board +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +device = I2CDevice(i2c, 0x50) + +# Read first byte by writing the memory address, then reading. +buf = bytearray(1) +with device: + device.write(bytes([0x00])) + device.readinto(buf) +print(f"AT24 byte 0: 0x{buf[0]:02X}") +if buf[0] == 0xFF: + print("eeprom_valid") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": READ_CODE}) +def test_i2cdevice_write_then_readinto_separate(circuitpython): + """write() followed by readinto() inside a single context manager block reads EEPROM data.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "AT24 byte 0: 0xFF" in output + assert "eeprom_valid" in output + assert "done" in output + + +WRITE_THEN_READINTO_CODE = """\ +import board +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +device = I2CDevice(i2c, 0x50) + +out_buf = bytes([0x00]) +in_buf = bytearray(4) +with device: + device.write_then_readinto(out_buf, in_buf) +print(f"first 4 bytes: {[hex(b) for b in in_buf]}") +if all(b == 0xFF for b in in_buf): + print("eeprom_valid") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": WRITE_THEN_READINTO_CODE}) +def test_i2cdevice_write_then_readinto_atomic(circuitpython): + """write_then_readinto() performs an atomic write+read against the EEPROM.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "first 4 bytes:" in output + assert "eeprom_valid" in output + assert "done" in output + + +WRITE_READBACK_CODE = """\ +import board +import time +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +device = I2CDevice(i2c, 0x50) + +# Write four bytes starting at EEPROM address 0x10. +payload = bytes([0xDE, 0xAD, 0xBE, 0xEF]) +with device: + device.write(bytes([0x10]) + payload) + +# EEPROM needs a moment to commit the write internally. +time.sleep(0.01) + +readback = bytearray(4) +with device: + device.write_then_readinto(bytes([0x10]), readback) +print(f"readback: {[hex(b) for b in readback]}") +if bytes(readback) == payload: + print("readback_ok") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": WRITE_READBACK_CODE}) +def test_i2cdevice_write_then_read_roundtrip(circuitpython): + """Writing bytes to the EEPROM and reading them back returns the written values.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "readback_ok" in output + assert "done" in output + + +SLICE_CODE = """\ +import board +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +device = I2CDevice(i2c, 0x50) + +# Use start/end kwargs to send only a slice of the outgoing buffer. +out = bytearray([0xAA, 0x00, 0xBB]) +dest = bytearray(4) +with device: + # Only send the middle byte (the memory address 0x00). + device.write_then_readinto(out, dest, out_start=1, out_end=2, in_start=0, in_end=2) +print(f"partial read: {[hex(b) for b in dest]}") +# Only the first two entries should have been written by the read. +if dest[0] == 0xFF and dest[1] == 0xFF and dest[2] == 0x00 and dest[3] == 0x00: + print("slice_ok") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": SLICE_CODE}) +def test_i2cdevice_buffer_slices(circuitpython): + """write_then_readinto honors out_start/out_end and in_start/in_end bounds.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "slice_ok" in output + assert "done" in output + + +DISABLED_CODE = """\ +import board +from adafruit_bus_device.i2c_device import I2CDevice + +i2c = board.I2C() +try: + device = I2CDevice(i2c, 0x50) + print("unexpected_success") +except (ValueError, OSError) as e: + print(f"probe_failed: {e}") +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": DISABLED_CODE}) +@pytest.mark.disable_i2c_devices("eeprom@50") +def test_i2cdevice_probe_fails_when_device_disabled(circuitpython): + """Probe fails when the AT24 emulator device is disabled on the bus.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "probe_failed" in output + assert "unexpected_success" not in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_aesio.py b/ports/zephyr-cp/tests/test_aesio.py new file mode 100644 index 00000000000..3ae016ac8e3 --- /dev/null +++ b/ports/zephyr-cp/tests/test_aesio.py @@ -0,0 +1,223 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test the aesio module.""" + +import pytest + +from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes + + +KEY = b"Sixteen byte key" +PLAINTEXT = b"CircuitPython!!!" # 16 bytes + + +ECB_CODE = """\ +import aesio + +key = b'Sixteen byte key' +inp = b'CircuitPython!!!' +outp = bytearray(len(inp)) +cipher = aesio.AES(key, aesio.MODE_ECB) +cipher.encrypt_into(inp, outp) +print(f"ciphertext_hex: {outp.hex()}") + +decrypted = bytearray(len(outp)) +cipher.decrypt_into(bytes(outp), decrypted) +print(f"decrypted: {bytes(decrypted)}") +print(f"match: {bytes(decrypted) == inp}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": ECB_CODE}) +def test_aesio_ecb(circuitpython): + """AES-ECB round-trips and matches CPython cryptography's output.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + encryptor = Cipher(algorithms.AES(KEY), modes.ECB()).encryptor() + expected_hex = (encryptor.update(PLAINTEXT) + encryptor.finalize()).hex() + assert f"ciphertext_hex: {expected_hex}" in output + assert "match: True" in output + assert "done" in output + + +IV = b"InitializationVe" # 16 bytes +CBC_PLAINTEXT = b"CircuitPython!!!" * 2 # 32 bytes, multiple of 16 +CTR_PLAINTEXT = b"CircuitPython is fun to use!" # 28 bytes, arbitrary length + + +CBC_CODE = """\ +import aesio + +key = b'Sixteen byte key' +iv = b'InitializationVe' +inp = b'CircuitPython!!!' * 2 +outp = bytearray(len(inp)) +cipher = aesio.AES(key, aesio.MODE_CBC, iv) +print(f"mode: {cipher.mode}") +cipher.encrypt_into(inp, outp) +print(f"ciphertext_hex: {outp.hex()}") + +# Re-create cipher to reset IV state for decryption. +cipher2 = aesio.AES(key, aesio.MODE_CBC, iv) +decrypted = bytearray(len(outp)) +cipher2.decrypt_into(bytes(outp), decrypted) +print(f"match: {bytes(decrypted) == inp}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CBC_CODE}) +def test_aesio_cbc(circuitpython): + """AES-CBC round-trips and matches CPython cryptography's output.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + encryptor = Cipher(algorithms.AES(KEY), modes.CBC(IV)).encryptor() + expected_hex = (encryptor.update(CBC_PLAINTEXT) + encryptor.finalize()).hex() + assert "mode: 2" in output + assert f"ciphertext_hex: {expected_hex}" in output + assert "match: True" in output + assert "done" in output + + +CTR_CODE = """\ +import aesio + +key = b'Sixteen byte key' +iv = b'InitializationVe' +inp = b'CircuitPython is fun to use!' +outp = bytearray(len(inp)) +cipher = aesio.AES(key, aesio.MODE_CTR, iv) +print(f"mode: {cipher.mode}") +cipher.encrypt_into(inp, outp) +print(f"ciphertext_hex: {outp.hex()}") + +cipher2 = aesio.AES(key, aesio.MODE_CTR, iv) +decrypted = bytearray(len(outp)) +cipher2.decrypt_into(bytes(outp), decrypted) +print(f"decrypted: {bytes(decrypted)}") +print(f"match: {bytes(decrypted) == inp}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CTR_CODE}) +def test_aesio_ctr(circuitpython): + """AES-CTR handles arbitrary-length buffers and matches CPython output.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + encryptor = Cipher(algorithms.AES(KEY), modes.CTR(IV)).encryptor() + expected_hex = (encryptor.update(CTR_PLAINTEXT) + encryptor.finalize()).hex() + assert "mode: 6" in output + assert f"ciphertext_hex: {expected_hex}" in output + assert "match: True" in output + assert "done" in output + + +REKEY_CODE = """\ +import aesio + +key1 = b'Sixteen byte key' +key2 = b'Another 16 byte!' +inp = b'CircuitPython!!!' + +cipher = aesio.AES(key1, aesio.MODE_ECB) +out1 = bytearray(16) +cipher.encrypt_into(inp, out1) +print(f"ct1_hex: {out1.hex()}") + +cipher.rekey(key2) +out2 = bytearray(16) +cipher.encrypt_into(inp, out2) +print(f"ct2_hex: {out2.hex()}") +print(f"different: {bytes(out1) != bytes(out2)}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": REKEY_CODE}) +def test_aesio_rekey(circuitpython): + """rekey() switches the active key; ciphertexts match CPython for both keys.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + enc1 = Cipher(algorithms.AES(b"Sixteen byte key"), modes.ECB()).encryptor() + ct1 = (enc1.update(PLAINTEXT) + enc1.finalize()).hex() + enc2 = Cipher(algorithms.AES(b"Another 16 byte!"), modes.ECB()).encryptor() + ct2 = (enc2.update(PLAINTEXT) + enc2.finalize()).hex() + assert f"ct1_hex: {ct1}" in output + assert f"ct2_hex: {ct2}" in output + assert "different: True" in output + assert "done" in output + + +MODE_PROPERTY_CODE = """\ +import aesio + +key = b'Sixteen byte key' +iv = b'InitializationVe' +cipher = aesio.AES(key, aesio.MODE_ECB) +print(f"initial: {cipher.mode}") +print(f"ECB={aesio.MODE_ECB} CBC={aesio.MODE_CBC} CTR={aesio.MODE_CTR}") + +for name, m in (("ECB", aesio.MODE_ECB), ("CBC", aesio.MODE_CBC), ("CTR", aesio.MODE_CTR)): + cipher.mode = m + print(f"set_{name}: {cipher.mode}") + +try: + cipher.mode = 99 +except NotImplementedError as e: + print(f"bad_mode: NotImplementedError") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": MODE_PROPERTY_CODE}) +def test_aesio_mode_property(circuitpython): + """The mode property is readable, writable, and rejects unsupported values.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "initial: 1" in output + assert "ECB=1 CBC=2 CTR=6" in output + assert "set_ECB: 1" in output + assert "set_CBC: 2" in output + assert "set_CTR: 6" in output + assert "bad_mode: NotImplementedError" in output + assert "done" in output + + +KEY_LENGTHS_CODE = """\ +import aesio + +inp = b'CircuitPython!!!' +for key in (b'A' * 16, b'B' * 24, b'C' * 32): + cipher = aesio.AES(key, aesio.MODE_ECB) + out = bytearray(16) + cipher.encrypt_into(inp, out) + print(f"len{len(key)}: {out.hex()}") + +try: + aesio.AES(b'too short', aesio.MODE_ECB) +except ValueError: + print("bad_key: ValueError") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": KEY_LENGTHS_CODE}) +def test_aesio_key_lengths(circuitpython): + """AES-128/192/256 keys all work and match CPython; bad key length raises.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + for key in (b"A" * 16, b"B" * 24, b"C" * 32): + encryptor = Cipher(algorithms.AES(key), modes.ECB()).encryptor() + expected = (encryptor.update(PLAINTEXT) + encryptor.finalize()).hex() + assert f"len{len(key)}: {expected}" in output + assert "bad_key: ValueError" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_audiobusio.py b/ports/zephyr-cp/tests/test_audiobusio.py new file mode 100644 index 00000000000..8bfa6a5a586 --- /dev/null +++ b/ports/zephyr-cp/tests/test_audiobusio.py @@ -0,0 +1,290 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries LLC +# SPDX-License-Identifier: MIT + +"""Test audiobusio I2SOut functionality on native_sim.""" + +from pathlib import Path + +import pytest +from perfetto.trace_processor import TraceProcessor + + +I2S_PLAY_CODE = """\ +import array +import math +import audiocore +import board +import time + +# Generate a 440 Hz sine wave, 16-bit signed stereo at 16000 Hz +sample_rate = 16000 +length = sample_rate // 440 # ~36 samples per period +values = [] +for i in range(length): + v = int(math.sin(math.pi * 2 * i / length) * 30000) + values.append(v) # left + values.append(v) # right + +sample = audiocore.RawSample( + array.array("h", values), + sample_rate=sample_rate, + channel_count=2, +) + +dac = board.I2S0() +print("playing") +dac.play(sample, loop=True) +time.sleep(0.5) +dac.stop() +print("stopped") +print("done") +""" + + +def parse_i2s_trace(trace_file: Path, track_name: str) -> list[tuple[int, int]]: + """Parse I2S counter trace from Perfetto trace file.""" + tp = TraceProcessor(file_path=str(trace_file)) + result = tp.query( + f""" + SELECT c.ts, c.value + FROM counter c + JOIN track t ON c.track_id = t.id + WHERE t.name LIKE "%{track_name}" + ORDER BY c.ts + """ + ) + return [(int(row.ts), int(row.value)) for row in result] + + +@pytest.mark.duration(10) +@pytest.mark.circuitpy_drive({"code.py": I2S_PLAY_CODE}) +def test_i2s_play_and_stop(circuitpython): + """Test I2SOut play and stop produce expected output and correct waveform traces.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "playing" in output + assert "stopped" in output + assert "done" in output + + # Check that Perfetto trace has I2S counter tracks with data + left_trace = parse_i2s_trace(circuitpython.trace_file, "Left") + right_trace = parse_i2s_trace(circuitpython.trace_file, "Right") + + # Should have counter events (initial zero + audio data) + assert len(left_trace) > 10, f"Expected many Left channel events, got {len(left_trace)}" + assert len(right_trace) > 10, f"Expected many Right channel events, got {len(right_trace)}" + + # Verify timestamps are spread out (not all the same) + left_timestamps = [ts for ts, _ in left_trace] + assert left_timestamps[-1] > left_timestamps[1], "Timestamps should increase over time" + time_span_ns = left_timestamps[-1] - left_timestamps[1] + # We play for 0.5s, so span should be at least 100ms + assert time_span_ns > 100_000_000, f"Expected >100ms time span, got {time_span_ns / 1e6:.1f}ms" + + # Audio data should contain non-zero values (sine wave) + # Skip the initial zero value + left_values = [v for _, v in left_trace if v != 0] + right_values = [v for _, v in right_trace if v != 0] + assert len(left_values) > 5, "Left channel has too few non-zero values" + assert len(right_values) > 5, "Right channel has too few non-zero values" + + # Sine wave should have both positive and negative values + assert any(v > 0 for v in left_values), "Left channel has no positive values" + assert any(v < 0 for v in left_values), "Left channel has no negative values" + + # Verify amplitude is in the expected range (we generate with amplitude 30000) + max_left = max(left_values) + min_left = min(left_values) + assert max_left > 20000, f"Left max {max_left} too low, expected >20000" + assert min_left < -20000, f"Left min {min_left} too high, expected <-20000" + + # Left and right should match (we write the same value to both channels) + # Compare a subset of matching timestamps + left_by_ts = dict(left_trace) + right_by_ts = dict(right_trace) + common_ts = sorted(set(left_by_ts.keys()) & set(right_by_ts.keys())) + mismatches = 0 + for ts in common_ts[:100]: + if left_by_ts[ts] != right_by_ts[ts]: + mismatches += 1 + assert mismatches == 0, ( + f"{mismatches} L/R mismatches in first {min(100, len(common_ts))} common timestamps" + ) + + +I2S_PLAY_NO_STOP_CODE = """\ +import array +import math +import audiocore +import board +import time + +sample_rate = 16000 +length = sample_rate // 440 +values = [] +for i in range(length): + v = int(math.sin(math.pi * 2 * i / length) * 30000) + values.append(v) + values.append(v) + +sample = audiocore.RawSample( + array.array("h", values), + sample_rate=sample_rate, + channel_count=2, +) + +dac = board.I2S0() +dac.play(sample, loop=True) +print("playing") +time.sleep(0.2) +# Exit without calling dac.stop() — reset_port should clean up +print("exiting") +""" + + +@pytest.mark.duration(15) +@pytest.mark.code_py_runs(2) +@pytest.mark.circuitpy_drive({"code.py": I2S_PLAY_NO_STOP_CODE}) +def test_i2s_stops_on_code_exit(circuitpython): + """Test I2S is stopped by reset_port when code.py exits without explicit stop.""" + # First run: plays audio then exits without stopping + circuitpython.serial.wait_for("exiting") + circuitpython.serial.wait_for("Press any key to enter the REPL") + # Trigger soft reload + circuitpython.serial.write("\x04") + + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + # Should see "playing" and "exiting" at least twice (once per run) + assert output.count("playing") >= 2 + assert output.count("exiting") >= 2 + + +I2S_PAUSE_RESUME_CODE = """\ +import array +import math +import audiocore +import board +import time + +sample_rate = 16000 +length = sample_rate // 440 +values = [] +for i in range(length): + v = int(math.sin(math.pi * 2 * i / length) * 30000) + values.append(v) + values.append(v) + +sample = audiocore.RawSample( + array.array("h", values), + sample_rate=sample_rate, + channel_count=2, +) + +dac = board.I2S0() +dac.play(sample, loop=True) +print("playing") +time.sleep(0.2) + +dac.pause() +print("paused") +assert dac.paused +time.sleep(0.1) + +dac.resume() +print("resumed") +assert not dac.paused +time.sleep(0.2) + +dac.stop() +print("done") +""" + + +@pytest.mark.duration(10) +@pytest.mark.circuitpy_drive({"code.py": I2S_PAUSE_RESUME_CODE}) +def test_i2s_pause_resume(circuitpython): + """Test I2SOut pause and resume work correctly.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "playing" in output + assert "paused" in output + assert "resumed" in output + assert "done" in output + + +I2S_PLAY_LOOP_FALSE_CODE = """\ +import array +import math +import audiocore +import board +import time + +# 440 Hz sine, 16-bit signed stereo at 16000 Hz, several periods. +sample_rate = 16000 +length = sample_rate // 440 +periods = 10 +values = [] +for _ in range(periods): + for i in range(length): + v = int(math.sin(math.pi * 2 * i / length) * 30000) + values.append(v) # left + values.append(v) # right + +# Default single_buffer=True: get_buffer returns the whole buffer together with +# GET_BUFFER_DONE on the very first call. With loop=False that buffer used to be +# discarded before being copied, producing silence (issue #10539). +sample = audiocore.RawSample( + array.array("h", values), + sample_rate=sample_rate, + channel_count=2, +) + +dac = board.I2S0() +print("playing") +dac.play(sample, loop=False) +time.sleep(0.5) +# Stop explicitly so this test does not depend on `playing` clearing on its own. +dac.stop() +print("done") +""" + + +@pytest.mark.duration(10) +@pytest.mark.circuitpy_drive({"code.py": I2S_PLAY_LOOP_FALSE_CODE}) +def test_i2s_play_non_looping_single_buffer(circuitpython): + """A single-buffer RawSample played with loop=False must be heard, not dropped. + + Regression test for #10539: the final buffer, returned together with + GET_BUFFER_DONE, was discarded before being copied, so a single-buffer + sample (whole buffer + DONE on the first get_buffer call) produced silence. + """ + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "playing" in output + assert "done" in output + + left_trace = parse_i2s_trace(circuitpython.trace_file, "Left") + right_trace = parse_i2s_trace(circuitpython.trace_file, "Right") + + # The sine wave must actually reach the I2S output. On the bug every value is + # zero (silence) because the sole buffer was dropped. + left_values = [v for _, v in left_trace if v != 0] + right_values = [v for _, v in right_trace if v != 0] + assert len(left_values) > 5, "Left channel is silent; non-looping sample was dropped" + assert len(right_values) > 5, "Right channel is silent; non-looping sample was dropped" + + # A sine wave has both positive and negative excursions at the expected amplitude. + assert max(left_values) > 20000, f"Left max {max(left_values)} too low" + assert min(left_values) < -20000, f"Left min {min(left_values)} too high" + + # We wrote the same value to both channels. + left_by_ts = dict(left_trace) + right_by_ts = dict(right_trace) + common_ts = sorted(set(left_by_ts) & set(right_by_ts)) + mismatches = sum(1 for ts in common_ts[:100] if left_by_ts[ts] != right_by_ts[ts]) + assert mismatches == 0, f"{mismatches} L/R mismatches in first common timestamps" diff --git a/ports/zephyr-cp/tests/test_basics.py b/ports/zephyr-cp/tests/test_basics.py new file mode 100644 index 00000000000..84b31849a8e --- /dev/null +++ b/ports/zephyr-cp/tests/test_basics.py @@ -0,0 +1,117 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test basic native_sim functionality.""" + +import pytest + + +@pytest.mark.circuitpy_drive(None) +def test_blank_flash_hello_world(circuitpython): + """Test that an erased flash shows code.py output header.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "Board ID:native_native_sim" in output + assert "UID:" in output + assert "code.py output:" in output + assert "Hello World" in output + assert "done" in output + + +# --- PTY Input Tests --- + + +INPUT_CODE = """\ +import sys + +print("ready") +char = sys.stdin.read(1) +print(f"received: {repr(char)}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": INPUT_CODE}) +def test_basic_serial_input(circuitpython): + """Test reading single character from serial via PTY write.""" + circuitpython.serial.wait_for("ready") + circuitpython.serial.write("A") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "ready" in output + assert "received: 'A'" in output + assert "done" in output + + +INPUT_FUNC_CODE = """\ +print("ready") +name = input("Enter name: ") +print(f"hello {name}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": INPUT_FUNC_CODE}) +def test_input_function(circuitpython): + """Test the built-in input() function with PTY input.""" + circuitpython.serial.wait_for("Enter name:") + circuitpython.serial.write("World\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "ready" in output + assert "Enter name:" in output + assert "hello World" in output + assert "done" in output + + +INTERRUPT_CODE = """\ +import time + +print("starting") +for i in range(100): + print(f"loop {i}") + time.sleep(0.1) +print("completed") +""" + + +@pytest.mark.circuitpy_drive({"code.py": INTERRUPT_CODE}) +def test_ctrl_c_interrupt(circuitpython): + """Test sending Ctrl+C (0x03) to interrupt running code.""" + circuitpython.serial.wait_for("loop 5") + circuitpython.serial.write("\x03") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "starting" in output + assert "loop 5" in output + assert "KeyboardInterrupt" in output + assert "completed" not in output + + +RELOAD_CODE = """\ +print("first run") +import time +time.sleep(1) +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": RELOAD_CODE}) +@pytest.mark.code_py_runs(2) +def test_ctrl_d_soft_reload(circuitpython): + """Test sending Ctrl+D (0x04) to trigger soft reload.""" + circuitpython.serial.wait_for("first run") + circuitpython.serial.write("\x04") + circuitpython.wait_until_done() + + # Should see "first run" appear multiple times due to reload + # or see a soft reboot message + output = circuitpython.serial.all_output + assert "first run" in output + # The soft reload should restart the code before "done" is printed + assert "done" in output + assert output.count("first run") > 1 diff --git a/ports/zephyr-cp/tests/test_digitalio.py b/ports/zephyr-cp/tests/test_digitalio.py new file mode 100644 index 00000000000..22c64f7b83f --- /dev/null +++ b/ports/zephyr-cp/tests/test_digitalio.py @@ -0,0 +1,171 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries LLC +# SPDX-License-Identifier: MIT + +"""Test digitalio functionality on native_sim.""" + +import re +from pathlib import Path + +import pytest +from perfetto.trace_processor import TraceProcessor + + +DIGITALIO_INPUT_TRACE_READ_CODE = """\ +import time +import digitalio +import microcontroller + +pin = digitalio.DigitalInOut(microcontroller.pin.P_01) +pin.direction = digitalio.Direction.INPUT + +start = time.monotonic() +last = pin.value +print(f"t_abs={time.monotonic():.3f} initial={last}") + +# Poll long enough to observe a high pulse injected through input trace. +while time.monotonic() - start < 8.0: + value = pin.value + if value != last: + print(f"t_abs={time.monotonic():.3f} edge={value}") + last = value + time.sleep(0.05) + +print(f"t_abs={time.monotonic():.3f} done") +""" + + +DIGITALIO_INPUT_TRACE = { + "gpio_emul.01": [ + (8_000_000_000, 0), + (9_000_000_000, 1), + (10_000_000_000, 0), + ], +} + + +@pytest.mark.duration(14.0) +@pytest.mark.circuitpy_drive({"code.py": DIGITALIO_INPUT_TRACE_READ_CODE}) +@pytest.mark.input_trace(DIGITALIO_INPUT_TRACE) +def test_digitalio_reads_input_trace(circuitpython): + """Test DigitalInOut input reads values injected via input trace.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + + initial_match = re.search(r"t_abs=([0-9]+\.[0-9]+) initial=False", output) + edge_match = re.search(r"t_abs=([0-9]+\.[0-9]+) edge=True", output) + done_match = re.search(r"t_abs=([0-9]+\.[0-9]+) done", output) + + assert initial_match is not None + assert edge_match is not None + assert done_match is not None + + initial_abs = float(initial_match.group(1)) + edge_abs = float(edge_match.group(1)) + done_abs = float(done_match.group(1)) + + # Input trace edge is at 9.0s for gpio_emul.01. + assert 8.5 <= edge_abs <= 9.5 + assert initial_abs <= edge_abs <= done_abs + + +BLINK_CODE = """\ +import time +import board +import digitalio + +led = digitalio.DigitalInOut(board.LED) +led.direction = digitalio.Direction.OUTPUT + +for i in range(3): + print(f"LED on {i}") + led.value = True + time.sleep(0.1) + print(f"LED off {i}") + led.value = False + time.sleep(0.1) + +print("done") +""" + + +def parse_gpio_trace(trace_file: Path, pin_name: str = "gpio_emul.00") -> list[tuple[int, int]]: + """Parse GPIO trace from Perfetto trace file.""" + tp = TraceProcessor(file_path=str(trace_file)) + result = tp.query( + f''' + SELECT c.ts, c.value + FROM counter c + JOIN track t ON c.track_id = t.id + WHERE t.name = "{pin_name}" + ORDER BY c.ts + ''' + ) + return [(row.ts, int(row.value)) for row in result] + + +@pytest.mark.circuitpy_drive({"code.py": BLINK_CODE}) +def test_digitalio_blink_output(circuitpython): + """Test blink program produces expected output and GPIO traces.""" + circuitpython.wait_until_done() + + # Check serial output + output = circuitpython.serial.all_output + assert "LED on 0" in output + assert "LED off 0" in output + assert "LED on 2" in output + assert "LED off 2" in output + assert "done" in output + + # Check GPIO traces - LED is on gpio_emul.00 + gpio_trace = parse_gpio_trace(circuitpython.trace_file, "gpio_emul.00") + + # Deduplicate by timestamp (keep last value at each timestamp) + by_timestamp = {} + for ts, val in gpio_trace: + by_timestamp[ts] = val + sorted_trace = sorted(by_timestamp.items()) + + # Find transition points (where value changes), skipping initialization at ts=0 + transitions = [] + for i in range(1, len(sorted_trace)): + prev_ts, prev_val = sorted_trace[i - 1] + curr_ts, curr_val = sorted_trace[i] + if prev_val != curr_val and curr_ts > 0: + transitions.append((curr_ts, curr_val)) + + # We expect at least 6 transitions (3 on + 3 off) from the blink loop + assert len(transitions) >= 6, f"Expected at least 6 transitions, got {len(transitions)}" + + # Verify timing between consecutive transitions + # Each sleep is 0.1s = 100ms = 100,000,000 ns + expected_interval_ns = 100_000_000 + tolerance_ns = 20_000_000 # 20ms tolerance + + # Find a sequence of 6 consecutive transitions with ~100ms intervals (the blink loop) + # This filters out initialization and cleanup noise + blink_transitions = [] + for i in range(len(transitions) - 1): + interval = transitions[i + 1][0] - transitions[i][0] + if abs(interval - expected_interval_ns) < tolerance_ns: + if not blink_transitions: + blink_transitions.append(transitions[i]) + blink_transitions.append(transitions[i + 1]) + elif blink_transitions: + # Found end of blink sequence + break + + assert len(blink_transitions) >= 6, ( + f"Expected at least 6 blink transitions with ~100ms intervals, got {len(blink_transitions)}" + ) + + # Verify timing between blink transitions + for i in range(1, min(6, len(blink_transitions))): + prev_ts = blink_transitions[i - 1][0] + curr_ts = blink_transitions[i][0] + interval = curr_ts - prev_ts + assert abs(interval - expected_interval_ns) < tolerance_ns, ( + f"Transition interval {interval / 1_000_000:.1f}ms deviates from " + f"expected {expected_interval_ns / 1_000_000:.1f}ms by more than " + f"{tolerance_ns / 1_000_000:.1f}ms tolerance" + ) diff --git a/ports/zephyr-cp/tests/test_flash.py b/ports/zephyr-cp/tests/test_flash.py new file mode 100644 index 00000000000..e2e5f4de14f --- /dev/null +++ b/ports/zephyr-cp/tests/test_flash.py @@ -0,0 +1,171 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test flash filesystem with various erase block sizes.""" + +import subprocess + +import pytest + + +def read_file_from_flash(flash_file, path): + """Extract a file from the FAT filesystem in the flash image.""" + result = subprocess.run( + ["mcopy", "-i", str(flash_file), f"::{path}", "-"], + capture_output=True, + ) + if result.returncode != 0: + raise FileNotFoundError( + f"Failed to read ::{path} from {flash_file}: {result.stderr.decode()}" + ) + return result.stdout.decode() + + +WRITE_READ_CODE = """\ +import storage +storage.remount("/", readonly=False) +with open("/test.txt", "w") as f: + f.write("hello flash") +with open("/test.txt", "r") as f: + content = f.read() +print(f"content: {content}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": WRITE_READ_CODE}) +def test_flash_default_erase_size(circuitpython): + """Test filesystem write/read with default 4KB erase blocks.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "content: hello flash" in output + assert "done" in output + + content = read_file_from_flash(circuitpython.flash_file, "test.txt") + assert content == "hello flash" + + +@pytest.mark.circuitpy_drive({"code.py": WRITE_READ_CODE}) +@pytest.mark.flash_config(erase_block_size=65536) +def test_flash_64k_erase_blocks(circuitpython): + """Test filesystem write/read with 64KB erase blocks (128 blocks per page).""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "content: hello flash" in output + assert "done" in output + + content = read_file_from_flash(circuitpython.flash_file, "test.txt") + assert content == "hello flash" + + +@pytest.mark.circuitpy_drive({"code.py": WRITE_READ_CODE}) +@pytest.mark.flash_config(erase_block_size=262144, total_size=4 * 1024 * 1024) +def test_flash_256k_erase_blocks(circuitpython): + """Test filesystem write/read with 256KB erase blocks (like RA8D1 OSPI).""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "content: hello flash" in output + assert "done" in output + + content = read_file_from_flash(circuitpython.flash_file, "test.txt") + assert content == "hello flash" + + +MULTI_FILE_CODE = """\ +import storage +storage.remount("/", readonly=False) +for i in range(5): + name = f"/file{i}.txt" + with open(name, "w") as f: + f.write(f"data{i}" * 100) +print("multi_file_ok") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": MULTI_FILE_CODE}) +@pytest.mark.flash_config(erase_block_size=262144, total_size=4 * 1024 * 1024) +def test_flash_256k_multi_file(circuitpython): + """Test multiple file writes with 256KB erase blocks to exercise cache flushing.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "multi_file_ok" in output + + for i in range(5): + content = read_file_from_flash(circuitpython.flash_file, f"file{i}.txt") + assert content == f"data{i}" * 100, f"file{i}.txt mismatch" + + +EXISTING_DATA_CODE = """\ +import storage +storage.remount("/", readonly=False) + +# Write a file to populate the erase page. +original_data = "A" * 4000 +with open("/original.txt", "w") as f: + f.write(original_data) + +# Force a flush so the data is written to flash. +storage.remount("/", readonly=True) +storage.remount("/", readonly=False) + +# Now write a small new file. This updates FAT metadata and directory +# entries that share an erase page with original.txt, exercising the +# read-modify-write cycle on the cached page. +with open("/small.txt", "w") as f: + f.write("tiny") + +# Read back original to check it survived. +with open("/original.txt", "r") as f: + readback = f.read() +if readback == original_data: + print("existing_data_ok") +else: + print(f"MISMATCH: got {len(readback)} bytes") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": EXISTING_DATA_CODE}) +@pytest.mark.flash_config(erase_block_size=262144, total_size=4 * 1024 * 1024) +def test_flash_256k_existing_data_survives(circuitpython): + """Test that existing data in an erase page survives when new data is written. + + With 256KB erase blocks (512 blocks per page), writing to any block in + the page triggers an erase-rewrite of the entire page. Existing blocks + must be preserved through the read-modify-write cycle. + """ + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "existing_data_ok" in output + + # Verify both files survived on the actual flash image. + original = read_file_from_flash(circuitpython.flash_file, "original.txt") + assert original == "A" * 4000, f"original.txt corrupted: got {len(original)} bytes" + + small = read_file_from_flash(circuitpython.flash_file, "small.txt") + assert small == "tiny" + + +OVERWRITE_CODE = """\ +import storage +storage.remount("/", readonly=False) +with open("/overwrite.txt", "w") as f: + f.write("first version") +with open("/overwrite.txt", "w") as f: + f.write("second version") +print("overwrite_ok") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": OVERWRITE_CODE}) +@pytest.mark.flash_config(erase_block_size=262144, total_size=4 * 1024 * 1024) +def test_flash_256k_overwrite(circuitpython): + """Test overwriting a file with 256KB erase blocks to exercise erase-rewrite cycle.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "overwrite_ok" in output + + content = read_file_from_flash(circuitpython.flash_file, "overwrite.txt") + assert content == "second version" diff --git a/ports/zephyr-cp/tests/test_getpass.py b/ports/zephyr-cp/tests/test_getpass.py new file mode 100644 index 00000000000..541d91078b3 --- /dev/null +++ b/ports/zephyr-cp/tests/test_getpass.py @@ -0,0 +1,182 @@ +# SPDX-FileCopyrightText: 2026 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test the getpass core module.""" + +import pytest + + +DEFAULT_PROMPT_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass() +print(f"got: {pw}") +print(f"length: {len(pw)}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": DEFAULT_PROMPT_CODE}) +def test_getpass_default_prompt(circuitpython): + """getpass() with no args prints 'Password: ' and returns the typed string.""" + circuitpython.serial.wait_for("ready") + circuitpython.serial.wait_for("Password:") + circuitpython.serial.write("hunter2\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "Password:" in output + assert "got: hunter2" in output + assert "length: 7" in output + assert "done" in output + + +CUSTOM_PROMPT_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("Enter secret: ") +print(f"got: {pw}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CUSTOM_PROMPT_CODE}) +def test_getpass_custom_prompt(circuitpython): + """A user-supplied prompt string is written before reading input.""" + circuitpython.serial.wait_for("Enter secret:") + circuitpython.serial.write("s3cr3t\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "Enter secret:" in output + assert "got: s3cr3t" in output + assert "done" in output + + +NO_ECHO_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("Pwd: ") +print("---boundary---") +print(f"got: {pw}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": NO_ECHO_CODE}) +def test_getpass_does_not_echo(circuitpython): + """Characters typed during getpass are not echoed back to the terminal.""" + circuitpython.serial.wait_for("Pwd:") + secret = "TopSecret123" + circuitpython.serial.write(secret + "\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + # Split around the boundary: nothing typed should appear before it, + # but the printed value appears after. + pre, _, post = output.partition("---boundary---") + assert secret not in pre + assert f"got: {secret}" in post + assert "done" in post + + +BACKSPACE_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("P: ") +print(f"got: {pw}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BACKSPACE_CODE}) +def test_getpass_backspace(circuitpython): + """Backspace (0x7f) removes the previous character from the buffer.""" + circuitpython.serial.wait_for("P:") + # Type "abcX", then backspace, then "d" -> "abcd" + circuitpython.serial.write("abcX\x7fd\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "got: abcd" in output + assert "done" in output + + +CTRL_C_CODE = """\ +import getpass + +print("ready") +try: + getpass.getpass("Pwd: ") + print("no exception") +except KeyboardInterrupt: + print("interrupted") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CTRL_C_CODE}) +def test_getpass_ctrl_c_raises_keyboard_interrupt(circuitpython): + """Sending Ctrl+C while getpass is reading raises KeyboardInterrupt.""" + circuitpython.serial.wait_for("Pwd:") + circuitpython.serial.write("\x03") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "interrupted" in output + assert "no exception" not in output + assert "done" in output + + +CTRL_D_EMPTY_CODE = """\ +import getpass + +print("ready") +try: + getpass.getpass("Pwd: ") + print("no exception") +except EOFError: + print("eof") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": CTRL_D_EMPTY_CODE}) +def test_getpass_ctrl_d_empty_raises_eof(circuitpython): + """Ctrl+D with an empty buffer raises EOFError.""" + circuitpython.serial.wait_for("Pwd:") + circuitpython.serial.write("\x04") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "eof" in output + assert "no exception" not in output + assert "done" in output + + +EMPTY_INPUT_CODE = """\ +import getpass + +print("ready") +pw = getpass.getpass("Pwd: ") +print(f"length: {len(pw)}") +print(f"empty: {pw == ''}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": EMPTY_INPUT_CODE}) +def test_getpass_empty_input(circuitpython): + """Pressing return immediately yields an empty string.""" + circuitpython.serial.wait_for("Pwd:") + circuitpython.serial.write("\r") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "length: 0" in output + assert "empty: True" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_hashlib.py b/ports/zephyr-cp/tests/test_hashlib.py new file mode 100644 index 00000000000..94463ba1e99 --- /dev/null +++ b/ports/zephyr-cp/tests/test_hashlib.py @@ -0,0 +1,152 @@ +# SPDX-FileCopyrightText: 2026 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test the hashlib module against CPython hashlib.""" + +import hashlib + +import pytest + + +SHORT_DATA = b"CircuitPython!" +CHUNK_A = b"Hello, " +CHUNK_B = b"CircuitPython world!" +LONG_DATA = b"The quick brown fox jumps over the lazy dog." * 64 + + +SHA256_CODE = """\ +import hashlib + +h = hashlib.new("sha256", b"CircuitPython!") +print(f"digest_size: {h.digest_size}") +print(f"digest_hex: {h.digest().hex()}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": SHA256_CODE}) +def test_hashlib_sha256_basic(circuitpython): + """sha256 digest on a small buffer matches CPython hashlib.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + expected = hashlib.sha256(SHORT_DATA).hexdigest() + assert "digest_size: 32" in output + assert f"digest_hex: {expected}" in output + assert "done" in output + + +SHA1_CODE = """\ +import hashlib + +h = hashlib.new("sha1", b"CircuitPython!") +print(f"digest_size: {h.digest_size}") +print(f"digest_hex: {h.digest().hex()}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": SHA1_CODE}) +def test_hashlib_sha1_basic(circuitpython): + """sha1 digest on a small buffer matches CPython hashlib.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + expected = hashlib.sha1(SHORT_DATA).hexdigest() + assert "digest_size: 20" in output + assert f"digest_hex: {expected}" in output + assert "done" in output + + +UPDATE_CODE = """\ +import hashlib + +h = hashlib.new("sha256") +h.update(b"Hello, ") +h.update(b"CircuitPython world!") +print(f"chunked_hex: {h.digest().hex()}") + +h2 = hashlib.new("sha256", b"Hello, CircuitPython world!") +print(f"oneshot_hex: {h2.digest().hex()}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": UPDATE_CODE}) +def test_hashlib_sha256_update_chunks(circuitpython): + """Multiple update() calls produce the same digest as a single buffer, and match CPython.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + expected = hashlib.sha256(CHUNK_A + CHUNK_B).hexdigest() + assert f"chunked_hex: {expected}" in output + assert f"oneshot_hex: {expected}" in output + assert "done" in output + + +LONG_CODE = """\ +import hashlib + +data = b"The quick brown fox jumps over the lazy dog." * 64 +h = hashlib.new("sha256", data) +print(f"sha256_hex: {h.digest().hex()}") + +h1 = hashlib.new("sha1", data) +print(f"sha1_hex: {h1.digest().hex()}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": LONG_CODE}) +def test_hashlib_long_input(circuitpython): + """Digests of a multi-block input match CPython for both sha1 and sha256.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert f"sha256_hex: {hashlib.sha256(LONG_DATA).hexdigest()}" in output + assert f"sha1_hex: {hashlib.sha1(LONG_DATA).hexdigest()}" in output + assert "done" in output + + +EMPTY_CODE = """\ +import hashlib + +h = hashlib.new("sha256", b"") +print(f"empty256: {h.digest().hex()}") + +h = hashlib.new("sha1", b"") +print(f"empty1: {h.digest().hex()}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": EMPTY_CODE}) +def test_hashlib_empty_input(circuitpython): + """Empty-input digests match CPython well-known values.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert f"empty256: {hashlib.sha256(b'').hexdigest()}" in output + assert f"empty1: {hashlib.sha1(b'').hexdigest()}" in output + assert "done" in output + + +BAD_ALGO_CODE = """\ +import hashlib + +try: + hashlib.new("md5", b"data") +except ValueError: + print("bad_algo: ValueError") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": BAD_ALGO_CODE}) +def test_hashlib_unsupported_algorithm(circuitpython): + """Unsupported algorithm names raise ValueError.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "bad_algo: ValueError" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_i2c.py b/ports/zephyr-cp/tests/test_i2c.py new file mode 100644 index 00000000000..ec5229faa2f --- /dev/null +++ b/ports/zephyr-cp/tests/test_i2c.py @@ -0,0 +1,102 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test I2C functionality on native_sim.""" + +import pytest + +I2C_SCAN_CODE = """\ +import board + +i2c = board.I2C() +while not i2c.try_lock(): + pass +devices = i2c.scan() +print(f"I2C devices: {[hex(d) for d in devices]}") +i2c.unlock() +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": I2C_SCAN_CODE}) +def test_i2c_scan(circuitpython): + """Test I2C bus scanning finds emulated devices. + + The AT24 EEPROM emulator responds to zero-length probe writes, + so it should appear in scan results at address 0x50. + """ + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "I2C devices:" in output + # AT24 EEPROM should be at address 0x50 + assert "0x50" in output + assert "done" in output + + +AT24_READ_CODE = """\ +import board + +i2c = board.I2C() +while not i2c.try_lock(): + pass + +# AT24 EEPROM at address 0x50 +AT24_ADDR = 0x50 + +# Read first byte from address 0 +result = bytearray(1) +try: + i2c.writeto_then_readfrom(AT24_ADDR, bytes([0x00]), result) + value = result[0] + print(f"AT24 byte 0: 0x{value:02X}") + # Fresh EEPROM should be 0xFF + if value == 0xFF: + print("eeprom_valid") + else: + print(f"unexpected value: expected 0xFF, got 0x{value:02X}") +except OSError as e: + print(f"I2C error: {e}") + +i2c.unlock() +i2c.deinit() +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": AT24_READ_CODE}) +def test_i2c_at24_read(circuitpython): + """Test reading from AT24 EEPROM emulator.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "AT24 byte 0: 0xFF" in output + assert "eeprom_valid" in output + assert "done" in output + + +@pytest.mark.circuitpy_drive({"code.py": I2C_SCAN_CODE}) +@pytest.mark.disable_i2c_devices("eeprom@50") +def test_i2c_device_disabled(circuitpython): + """Test that disabled I2C device doesn't appear in scan.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "I2C devices:" in output + # AT24 at 0x50 should NOT appear when disabled + assert "0x50" not in output + assert "done" in output + + +@pytest.mark.circuitpy_drive({"code.py": AT24_READ_CODE}) +@pytest.mark.disable_i2c_devices("eeprom@50") +def test_i2c_device_disabled_communication_fails(circuitpython): + """Test that communication with disabled I2C device fails.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + # Should get an I2C error when trying to communicate + assert "I2C error" in output + assert "eeprom_valid" not in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_msgpack.py b/ports/zephyr-cp/tests/test_msgpack.py new file mode 100644 index 00000000000..09bed35209c --- /dev/null +++ b/ports/zephyr-cp/tests/test_msgpack.py @@ -0,0 +1,137 @@ +# SPDX-FileCopyrightText: 2026 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test the msgpack module.""" + +import pytest + + +ROUNDTRIP_CODE = """\ +import msgpack +from io import BytesIO + +obj = {"list": [True, False, None, 1, 3.125], "str": "blah"} +b = BytesIO() +msgpack.pack(obj, b) +encoded = b.getvalue() +print(f"encoded_len: {len(encoded)}") +print(f"encoded_hex: {encoded.hex()}") + +b.seek(0) +decoded = msgpack.unpack(b) +print(f"decoded: {decoded}") +print(f"match: {decoded == obj}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": ROUNDTRIP_CODE}) +def test_msgpack_roundtrip(circuitpython): + """Pack and unpack a dict containing the basic msgpack types.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "match: True" in output + assert "done" in output + + +USE_LIST_CODE = """\ +import msgpack +from io import BytesIO + +b = BytesIO() +msgpack.pack([1, 2, 3], b) + +b.seek(0) +as_list = msgpack.unpack(b) +print(f"as_list: {as_list} type={type(as_list).__name__}") + +b.seek(0) +as_tuple = msgpack.unpack(b, use_list=False) +print(f"as_tuple: {as_tuple} type={type(as_tuple).__name__}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": USE_LIST_CODE}) +def test_msgpack_use_list(circuitpython): + """use_list=False should return a tuple instead of a list.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "as_list: [1, 2, 3] type=list" in output + assert "as_tuple: (1, 2, 3) type=tuple" in output + assert "done" in output + + +EXTTYPE_CODE = """\ +from msgpack import pack, unpack, ExtType +from io import BytesIO + +class MyClass: + def __init__(self, val): + self.value = val + +data = MyClass(b"my_value") + +def encoder(obj): + if isinstance(obj, MyClass): + return ExtType(1, obj.value) + return f"no encoder for {obj}" + +def decoder(code, data): + if code == 1: + return MyClass(data) + return f"no decoder for type {code}" + +buf = BytesIO() +pack(data, buf, default=encoder) +buf.seek(0) +decoded = unpack(buf, ext_hook=decoder) +print(f"decoded_type: {type(decoded).__name__}") +print(f"decoded_value: {decoded.value}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": EXTTYPE_CODE}) +def test_msgpack_exttype(circuitpython): + """ExtType with a custom encoder/decoder should round-trip.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "decoded_type: MyClass" in output + assert "decoded_value: b'my_value'" in output + assert "done" in output + + +EXTTYPE_PROPS_CODE = """\ +from msgpack import ExtType + +e = ExtType(5, b"hello") +print(f"code: {e.code}") +print(f"data: {e.data}") + +e.code = 10 +print(f"new_code: {e.code}") + +try: + ExtType(128, b"x") +except (ValueError, OverflowError) as ex: + print(f"range_error: {type(ex).__name__}") + +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": EXTTYPE_PROPS_CODE}) +def test_msgpack_exttype_properties(circuitpython): + """ExtType exposes code/data as read/write properties and rejects out-of-range codes.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "code: 5" in output + assert "data: b'hello'" in output + assert "new_code: 10" in output + assert "range_error:" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_nvm.py b/ports/zephyr-cp/tests/test_nvm.py new file mode 100644 index 00000000000..5de304afc1b --- /dev/null +++ b/ports/zephyr-cp/tests/test_nvm.py @@ -0,0 +1,73 @@ +# SPDX-FileCopyrightText: 2025 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test NVM functionality on native_sim.""" + +import pytest + + +NVM_BASIC_CODE = """\ +import microcontroller + +nvm = microcontroller.nvm +print(f"nvm length: {len(nvm)}") + +# Write some bytes +nvm[0] = 42 +nvm[1] = 99 +print(f"nvm[0]: {nvm[0]}") +print(f"nvm[1]: {nvm[1]}") + +# Write a slice +nvm[2:5] = b"\\x01\\x02\\x03" +print(f"nvm[2:5]: {list(nvm[2:5])}") + +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": NVM_BASIC_CODE}) +def test_nvm_read_write(circuitpython): + """Test basic NVM read and write operations.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "nvm length: 8192" in output + assert "nvm[0]: 42" in output + assert "nvm[1]: 99" in output + assert "nvm[2:5]: [1, 2, 3]" in output + assert "done" in output + + +NVM_PERSIST_CODE = """\ +import microcontroller + +nvm = microcontroller.nvm +value = nvm[0] +print(f"nvm[0]: {value}") + +if value == 255: + # First run: write a marker + nvm[0] = 123 + print("wrote marker") +else: + print(f"marker found: {value}") + +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": NVM_PERSIST_CODE}) +@pytest.mark.code_py_runs(2) +def test_nvm_persists_across_reload(circuitpython): + """Test that NVM data persists across soft reloads.""" + circuitpython.serial.wait_for("wrote marker") + # Trigger soft reload + circuitpython.serial.write("\x04") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "nvm[0]: 255" in output + assert "wrote marker" in output + assert "marker found: 123" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_rotaryio.py b/ports/zephyr-cp/tests/test_rotaryio.py new file mode 100644 index 00000000000..e9a5c1913cb --- /dev/null +++ b/ports/zephyr-cp/tests/test_rotaryio.py @@ -0,0 +1,132 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries LLC +# SPDX-License-Identifier: MIT + +"""Test rotaryio functionality on native_sim.""" + +import pytest + + +ROTARY_CODE_5S = """\ +import time +import microcontroller +import rotaryio + +encoder = rotaryio.IncrementalEncoder(microcontroller.pin.P_01, microcontroller.pin.P_02) + +time.sleep(5.0) # Sleep long enough for trace events to complete +print(f"position={encoder.position}") +print("done") +""" + + +ROTARY_CODE_7S = """\ +import time +import microcontroller +import rotaryio + +encoder = rotaryio.IncrementalEncoder(microcontroller.pin.P_01, microcontroller.pin.P_02) + +time.sleep(7.0) # Sleep long enough for trace events to complete +print(f"position={encoder.position}") +print("done") +""" + + +CLOCKWISE_TRACE = { + "gpio_emul.01": [ + (4_000_000_000, 0), # 4.0s: initial state (low) + (4_100_000_000, 1), # 4.1s: A goes high (A leads) + (4_300_000_000, 0), # 4.3s: A goes low + ], + "gpio_emul.02": [ + (4_000_000_000, 0), # 4.0s: initial state (low) + (4_200_000_000, 1), # 4.2s: B goes high (B follows) + (4_400_000_000, 0), # 4.4s: B goes low + ], +} + +COUNTERCLOCKWISE_TRACE = { + "gpio_emul.01": [ + (4_000_000_000, 0), # 4.0s: initial state (low) + (4_200_000_000, 1), # 4.2s: A goes high (A follows) + (4_400_000_000, 0), # 4.4s: A goes low + ], + "gpio_emul.02": [ + (4_000_000_000, 0), # 4.0s: initial state (low) + (4_100_000_000, 1), # 4.1s: B goes high (B leads) + (4_300_000_000, 0), # 4.3s: B goes low + ], +} + +BOTH_DIRECTIONS_TRACE = { + "gpio_emul.01": [ + (4_000_000_000, 0), # Initial state + # First clockwise detent + (4_100_000_000, 1), # A rises (leads) + (4_300_000_000, 0), # A falls + # Second clockwise detent + (4_500_000_000, 1), # A rises (leads) + (4_700_000_000, 0), # A falls + # First counter-clockwise detent + (5_000_000_000, 1), # A rises (follows) + (5_200_000_000, 0), # A falls + # Second counter-clockwise detent + (5_400_000_000, 1), # A rises (follows) + (5_600_000_000, 0), # A falls + # Third counter-clockwise detent + (5_800_000_000, 1), # A rises (follows) + (6_000_000_000, 0), # A falls + ], + "gpio_emul.02": [ + (4_000_000_000, 0), # Initial state + # First clockwise detent + (4_200_000_000, 1), # B rises (follows) + (4_400_000_000, 0), # B falls + # Second clockwise detent + (4_600_000_000, 1), # B rises (follows) + (4_800_000_000, 0), # B falls + # First counter-clockwise detent + (4_900_000_000, 1), # B rises (leads) + (5_100_000_000, 0), # B falls + # Second counter-clockwise detent + (5_300_000_000, 1), # B rises (leads) + (5_500_000_000, 0), # B falls + # Third counter-clockwise detent + (5_700_000_000, 1), # B rises (leads) + (5_900_000_000, 0), # B falls + ], +} + + +@pytest.mark.circuitpy_drive({"code.py": ROTARY_CODE_5S}) +@pytest.mark.input_trace(CLOCKWISE_TRACE) +def test_rotaryio_incrementalencoder_clockwise(circuitpython): + """Test clockwise rotation increments position.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "position=1" in output + assert "done" in output + + +@pytest.mark.circuitpy_drive({"code.py": ROTARY_CODE_5S}) +@pytest.mark.input_trace(COUNTERCLOCKWISE_TRACE) +def test_rotaryio_incrementalencoder_counterclockwise(circuitpython): + """Test counter-clockwise rotation decrements position.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "position=-1" in output + assert "done" in output + + +@pytest.mark.duration(12.0) +@pytest.mark.circuitpy_drive({"code.py": ROTARY_CODE_7S}) +@pytest.mark.input_trace(BOTH_DIRECTIONS_TRACE) +def test_rotaryio_incrementalencoder_both_directions(circuitpython): + """Test rotation in both directions: 2 clockwise, then 3 counter-clockwise.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "position=-1" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_storage.py b/ports/zephyr-cp/tests/test_storage.py new file mode 100644 index 00000000000..33e63e5ea85 --- /dev/null +++ b/ports/zephyr-cp/tests/test_storage.py @@ -0,0 +1,162 @@ +# SPDX-FileCopyrightText: 2026 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test the `storage` core module on native_sim.""" + +import pytest + + +REMOUNT_READWRITE_CODE = """\ +import storage +storage.remount("/", readonly=False) +with open("/rw.txt", "w") as f: + f.write("writable") +with open("/rw.txt", "r") as f: + print(f"content: {f.read()}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": REMOUNT_READWRITE_CODE}) +def test_storage_remount_readwrite(circuitpython): + """remount with readonly=False allows writes to /.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "content: writable" in output + assert "done" in output + + +REMOUNT_READONLY_CODE = """\ +import storage +storage.remount("/", readonly=True) +try: + with open("/should_fail.txt", "w") as f: + f.write("nope") + print("unexpected: write succeeded") +except OSError as e: + print(f"caught OSError: errno={e.errno}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": REMOUNT_READONLY_CODE}) +def test_storage_remount_readonly_blocks_writes(circuitpython): + """remount with readonly=True prevents writes to /.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "caught OSError" in output + assert "unexpected: write succeeded" not in output + assert "done" in output + + +GETMOUNT_CODE = """\ +import storage +mount = storage.getmount("/") +print(f"type: {type(mount).__name__}") +print(f"readonly: {mount.readonly}") +# label attribute should be accessible +print(f"label: {mount.label!r}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": GETMOUNT_CODE}) +def test_storage_getmount(circuitpython): + """getmount('/') returns the VfsFat object for the root mount.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "type: VfsFat" in output + assert "readonly:" in output + assert "label:" in output + assert "done" in output + + +GETMOUNT_MISSING_CODE = """\ +import storage +try: + storage.getmount("/does_not_exist") + print("unexpected: getmount succeeded") +except OSError as e: + print(f"caught OSError: errno={e.errno}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": GETMOUNT_MISSING_CODE}) +def test_storage_getmount_missing(circuitpython): + """getmount on an unmounted path raises OSError.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "caught OSError" in output + assert "unexpected: getmount succeeded" not in output + assert "done" in output + + +REMOUNT_PERSISTS_CODE = """\ +import storage +storage.remount("/", readonly=False) +with open("/persist.txt", "w") as f: + f.write("across-reload") +print("wrote persist.txt") +""" + +REMOUNT_PERSISTS_READ_CODE = """\ +with open("/persist.txt", "r") as f: + print(f"readback: {f.read()}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": REMOUNT_PERSISTS_CODE}) +@pytest.mark.code_py_runs(2) +def test_storage_remount_persists_across_reload(circuitpython): + """Data written after remount(readonly=False) persists across soft reload.""" + circuitpython.serial.wait_for("wrote persist.txt") + # Replace code.py via raw REPL-style approach: write new file then reload. + # Simpler: just trigger a soft reload and check the file is still there. + circuitpython.serial.write("\x04") + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "wrote persist.txt" in output + + +LABEL_CODE = """\ +import storage +storage.remount("/", readonly=False) +mount = storage.getmount("/") +mount.label = "CIRCUITPY" +print(f"label: {mount.label!r}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": LABEL_CODE}) +def test_storage_set_label(circuitpython): + """VfsFat.label can be set when mounted read-write.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "label: 'CIRCUITPY'" in output + assert "done" in output + + +UMOUNT_MISSING_CODE = """\ +import storage +# Unmounting an unmounted path should raise. +try: + storage.umount("/not_mounted") + print("unexpected: umount succeeded") +except OSError as e: + print(f"umount OSError: errno={e.errno}") +print("done") +""" + + +@pytest.mark.circuitpy_drive({"code.py": UMOUNT_MISSING_CODE}) +def test_storage_umount_missing(circuitpython): + """umount on an unmounted path raises OSError.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + assert "umount OSError" in output + assert "unexpected:" not in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/test_web_workflow.py b/ports/zephyr-cp/tests/test_web_workflow.py new file mode 100644 index 00000000000..d3a00782a33 --- /dev/null +++ b/ports/zephyr-cp/tests/test_web_workflow.py @@ -0,0 +1,142 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Tests for web workflow on native_sim.""" + +from __future__ import annotations + +import json +import re + +import pytest +import requests + + +pytestmark = pytest.mark.native_sim_rt + +WEB_WORKFLOW_PORT = 8090 +WEB_WORKFLOW_PASSWORD = "testpass" + +WEB_WORKFLOW_CODE = """\ +import time + +# Keep the VM alive while the web workflow starts. +time.sleep(3) +""" + +WEB_WORKFLOW_UPDATED_CODE = """\ +print("updated") +""" + +WEB_WORKFLOW_SETTINGS = f"""\ +CIRCUITPY_WEB_API_PASSWORD="{WEB_WORKFLOW_PASSWORD}" +CIRCUITPY_WEB_API_PORT={WEB_WORKFLOW_PORT} +""" + +WEB_WORKFLOW_SETTINGS_PORT_80 = f"""\ +CIRCUITPY_WEB_API_PASSWORD="{WEB_WORKFLOW_PASSWORD}" +CIRCUITPY_WEB_API_PORT=80 +""" + +WEB_WORKFLOW_BOOT = """\ +import storage + +storage.remount("/", readonly=False) +""" + + +@pytest.mark.circuitpy_drive( + { + "code.py": WEB_WORKFLOW_CODE, + "settings.toml": WEB_WORKFLOW_SETTINGS, + } +) +def test_web_workflow_hostnetwork(circuitpython): + """Ensure web workflow responds over hostnetwork.""" + circuitpython.serial.wait_for(f"127.0.0.1:{WEB_WORKFLOW_PORT}") + response = requests.get(f"http://127.0.0.1:{WEB_WORKFLOW_PORT}/edit/", timeout=1.0) + + assert response.status_code == 401 + + +@pytest.mark.circuitpy_drive( + { + "code.py": WEB_WORKFLOW_CODE, + "settings.toml": WEB_WORKFLOW_SETTINGS, + } +) +def test_web_workflow_version_json_hostnetwork_ip_and_port(circuitpython): + """Ensure /cp/version.json reports hostnetwork endpoint with configured port.""" + circuitpython.serial.wait_for(f"127.0.0.1:{WEB_WORKFLOW_PORT}") + response = requests.get( + f"http://127.0.0.1:{WEB_WORKFLOW_PORT}/cp/version.json", + auth=("", WEB_WORKFLOW_PASSWORD), + timeout=1.0, + ) + + assert response.status_code == 200 + + payload = json.loads(response.text) + assert payload["ip"] == "127.0.0.1" + assert payload["port"] == WEB_WORKFLOW_PORT + + +@pytest.mark.circuitpy_drive( + { + "code.py": WEB_WORKFLOW_CODE, + "settings.toml": WEB_WORKFLOW_SETTINGS, + } +) +def test_web_workflow_status_line_hostnetwork_non_default_port(circuitpython): + """Status line should include hostnetwork IP and non-default port.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + + # Remove ANSI control sequences before matching. + output = re.sub(r"\x1b\[[0-9;]*[A-Za-z]", "", output) + assert "127.0.0.1:8090" in output + + +@pytest.mark.circuitpy_drive( + { + "code.py": WEB_WORKFLOW_CODE, + "settings.toml": WEB_WORKFLOW_SETTINGS_PORT_80, + } +) +def test_web_workflow_status_line_hostnetwork_default_port(circuitpython): + """Status line should show IP without :80 for default HTTP port.""" + circuitpython.wait_until_done() + output = circuitpython.serial.all_output + + output = re.sub(r"\x1b\[[0-9;]*[A-Za-z]", "", output) + assert "127.0.0.1" in output + assert "127.0.0.1:80" not in output + + +@pytest.mark.circuitpy_drive( + { + "boot.py": WEB_WORKFLOW_BOOT, + "code.py": WEB_WORKFLOW_CODE, + "settings.toml": WEB_WORKFLOW_SETTINGS, + } +) +def test_web_workflow_write_code_py_remount(circuitpython): + """Ensure web workflow can update code.py after remounting.""" + circuitpython.serial.wait_for(f"127.0.0.1:{WEB_WORKFLOW_PORT}") + body = WEB_WORKFLOW_UPDATED_CODE.encode("utf-8") + + response = requests.put( + f"http://127.0.0.1:{WEB_WORKFLOW_PORT}/fs/code.py", + auth=("", WEB_WORKFLOW_PASSWORD), + data=body, + timeout=1.0, + ) + assert response.status_code in (201, 204) + + response = requests.get( + f"http://127.0.0.1:{WEB_WORKFLOW_PORT}/fs/code.py", + auth=("", WEB_WORKFLOW_PASSWORD), + timeout=1.0, + ) + assert response.status_code == 200 + assert WEB_WORKFLOW_UPDATED_CODE in response.text diff --git a/ports/zephyr-cp/tests/test_zlib.py b/ports/zephyr-cp/tests/test_zlib.py new file mode 100644 index 00000000000..bd89d8e1c25 --- /dev/null +++ b/ports/zephyr-cp/tests/test_zlib.py @@ -0,0 +1,110 @@ +# SPDX-FileCopyrightText: 2026 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT + +"""Test the zlib module against CPython zlib. + +CircuitPython's zlib only implements ``decompress``; these tests compress data +with CPython and verify the zephyr-cp port decodes it back to the same bytes. +""" + +import zlib + +import pytest + + +PLAIN_TEXT = b"CircuitPython running on Zephyr says hello!" +REPEATED_TEXT = b"The quick brown fox jumps over the lazy dog. " * 32 +BINARY_BLOB = bytes(range(256)) * 4 + + +def _make_code(compressed: bytes, wbits: int, expected_len: int) -> str: + return ( + "import zlib\n" + f"compressed = {compressed!r}\n" + f"out = zlib.decompress(compressed, {wbits})\n" + f'print(f"out_len: {{len(out)}}")\n' + f'print(f"expected_len: {expected_len}")\n' + 'print(f"out_hex: {out.hex()}")\n' + 'print("done")\n' + ) + + +ZLIB_COMPRESSED = zlib.compress(PLAIN_TEXT) +ZLIB_CODE = _make_code(ZLIB_COMPRESSED, wbits=15, expected_len=len(PLAIN_TEXT)) + + +@pytest.mark.circuitpy_drive({"code.py": ZLIB_CODE}) +def test_zlib_decompress_zlib_format(circuitpython): + """Data produced by CPython zlib.compress() round-trips through CircuitPython zlib.decompress().""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert f"out_len: {len(PLAIN_TEXT)}" in output + assert f"out_hex: {PLAIN_TEXT.hex()}" in output + assert "done" in output + + +REPEATED_COMPRESSED = zlib.compress(REPEATED_TEXT) +REPEATED_CODE = _make_code(REPEATED_COMPRESSED, wbits=15, expected_len=len(REPEATED_TEXT)) + + +@pytest.mark.circuitpy_drive({"code.py": REPEATED_CODE}) +def test_zlib_decompress_repeated(circuitpython): + """Highly-compressible repeated input decompresses correctly (back-references).""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert f"out_len: {len(REPEATED_TEXT)}" in output + # Repeated text has many back-references; shrinks a lot. + assert len(REPEATED_COMPRESSED) < len(REPEATED_TEXT) // 4 + assert f"out_hex: {REPEATED_TEXT.hex()}" in output + assert "done" in output + + +BINARY_COMPRESSED = zlib.compress(BINARY_BLOB) +BINARY_CODE = _make_code(BINARY_COMPRESSED, wbits=15, expected_len=len(BINARY_BLOB)) + + +@pytest.mark.circuitpy_drive({"code.py": BINARY_CODE}) +def test_zlib_decompress_binary_bytes(circuitpython): + """Decompression preserves every byte value (0x00-0xFF).""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert f"out_len: {len(BINARY_BLOB)}" in output + assert f"out_hex: {BINARY_BLOB.hex()}" in output + assert "done" in output + + +# Raw DEFLATE stream (no zlib header/trailer). +_raw_compressor = zlib.compressobj(wbits=-15) +RAW_COMPRESSED = _raw_compressor.compress(PLAIN_TEXT) + _raw_compressor.flush() +RAW_CODE = _make_code(RAW_COMPRESSED, wbits=-15, expected_len=len(PLAIN_TEXT)) + + +@pytest.mark.circuitpy_drive({"code.py": RAW_CODE}) +def test_zlib_decompress_raw_deflate(circuitpython): + """Raw DEFLATE streams (wbits=-15) decompress to the original bytes.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert f"out_len: {len(PLAIN_TEXT)}" in output + assert f"out_hex: {PLAIN_TEXT.hex()}" in output + assert "done" in output + + +# Gzip wrapper (wbits=31). +_gzip_compressor = zlib.compressobj(wbits=31) +GZIP_COMPRESSED = _gzip_compressor.compress(PLAIN_TEXT) + _gzip_compressor.flush() +GZIP_CODE = _make_code(GZIP_COMPRESSED, wbits=31, expected_len=len(PLAIN_TEXT)) + + +@pytest.mark.circuitpy_drive({"code.py": GZIP_CODE}) +def test_zlib_decompress_gzip_format(circuitpython): + """Gzip-wrapped streams (wbits=31) decompress to the original bytes.""" + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert f"out_len: {len(PLAIN_TEXT)}" in output + assert f"out_hex: {PLAIN_TEXT.hex()}" in output + assert "done" in output diff --git a/ports/zephyr-cp/tests/zephyr_display/README.md b/ports/zephyr-cp/tests/zephyr_display/README.md new file mode 100644 index 00000000000..6b502021543 --- /dev/null +++ b/ports/zephyr-cp/tests/zephyr_display/README.md @@ -0,0 +1,45 @@ +# Zephyr Display Golden Tests + +This directory contains native_sim golden-image tests for the Zephyr-specific `zephyr_display` path. + +## What is tested + +- `board.DISPLAY` is present and usable. +- CircuitPython terminal/console tilegrids are attached to the default display root group. +- Deterministic console terminal output matches a checked-in golden image. +- `zephyr_display` pixel format constants are exposed. +- `displayio` rendering produces expected stripe colors at sampled pixel locations. + +## Files + +- `test_zephyr_display.py` – pytest tests. +- `golden/terminal_console_output_320x240.png` – console terminal output golden reference image. + +## How capture works + +These tests use trace-driven SDL display capture triggered by Perfetto instant events: + +- `--input-trace=` provides a Perfetto trace containing a `"display_capture"` track + with instant events at the desired capture timestamps. +- `--display_capture_png=` specifies the output PNG pattern (may contain `%d` for + a sequence number). +- `--display_headless` runs SDL in headless/hidden-window mode (always enabled for native_sim tests). + +The test harness sets these flags automatically when tests use +`@pytest.mark.display(capture_times_ns=[...])`. + +## Regenerating the console golden image + +```bash +rm -rf /tmp/zephyr-display-golden +pytest -q ports/zephyr-cp/tests/zephyr_display/test_zephyr_display.py::test_console_output_golden \ + --basetemp=/tmp/zephyr-display-golden +cp /tmp/zephyr-display-golden/test_console_output_golden0/frame_0.png \ + ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240.png +``` + +## Running the tests + +```bash +pytest -q ports/zephyr-cp/tests/zephyr_display/test_zephyr_display.py +``` diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240.png new file mode 100644 index 00000000000..5739b8ee156 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_AL_88.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_AL_88.png new file mode 100644 index 00000000000..6bdb72b802c Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_AL_88.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_ARGB_8888.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_ARGB_8888.png new file mode 100644 index 00000000000..90b422792db Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_ARGB_8888.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_BGR_565.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_BGR_565.png new file mode 100644 index 00000000000..5739b8ee156 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_BGR_565.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_L_8.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_L_8.png new file mode 100644 index 00000000000..6bdb72b802c Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_L_8.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_MONO01.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_MONO01.png new file mode 100644 index 00000000000..b22de4417ab Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_MONO01.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_MONO10.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_MONO10.png new file mode 100644 index 00000000000..b22de4417ab Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_MONO10.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_RGB_565.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_RGB_565.png new file mode 100644 index 00000000000..5739b8ee156 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_RGB_565.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_RGB_888.png b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_RGB_888.png new file mode 100644 index 00000000000..c4301da47c5 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/color_gradient_320x240_RGB_888.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_00_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_00_320x240.png new file mode 100644 index 00000000000..8f7fc051365 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_00_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_01_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_01_320x240.png new file mode 100644 index 00000000000..67d17856c7d Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_01_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_02_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_02_320x240.png new file mode 100644 index 00000000000..99c832b68ec Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_02_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_03_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_03_320x240.png new file mode 100644 index 00000000000..38f403a2ad3 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_03_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_04_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_04_320x240.png new file mode 100644 index 00000000000..2a6649a0014 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_04_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_05_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_05_320x240.png new file mode 100644 index 00000000000..507a9290937 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_05_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_06_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_06_320x240.png new file mode 100644 index 00000000000..217b98f680b Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_06_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_07_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_07_320x240.png new file mode 100644 index 00000000000..507a9290937 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_07_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_08_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_08_320x240.png new file mode 100644 index 00000000000..2a6649a0014 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_08_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_09_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_09_320x240.png new file mode 100644 index 00000000000..38f403a2ad3 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_09_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_10_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_10_320x240.png new file mode 100644 index 00000000000..99c832b68ec Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_10_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_11_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_11_320x240.png new file mode 100644 index 00000000000..67d17856c7d Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_11_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_12_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_12_320x240.png new file mode 100644 index 00000000000..8f7fc051365 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/gifio_frame_12_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/jpegio_test_pattern_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/jpegio_test_pattern_320x240.png new file mode 100644 index 00000000000..4987b76ff80 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/jpegio_test_pattern_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240.mask.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240.mask.png new file mode 100644 index 00000000000..c675e2e5fa7 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240.mask.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240.png new file mode 100644 index 00000000000..77577a65601 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_AL_88.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_AL_88.png new file mode 100644 index 00000000000..f9ceedebe4a Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_AL_88.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_ARGB_8888.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_ARGB_8888.png new file mode 100644 index 00000000000..90b422792db Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_ARGB_8888.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_BGR_565.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_BGR_565.png new file mode 100644 index 00000000000..77577a65601 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_BGR_565.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_L_8.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_L_8.png new file mode 100644 index 00000000000..f9ceedebe4a Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_L_8.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO01.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO01.png new file mode 100644 index 00000000000..59928bcd107 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO01.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO01_no_vtiled.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO01_no_vtiled.png new file mode 100644 index 00000000000..59928bcd107 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO01_no_vtiled.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO10.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO10.png new file mode 100644 index 00000000000..59928bcd107 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO10.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO10_no_vtiled.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO10_no_vtiled.png new file mode 100644 index 00000000000..59928bcd107 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_MONO10_no_vtiled.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_RGB_565.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_RGB_565.png new file mode 100644 index 00000000000..77577a65601 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_RGB_565.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_RGB_888.png b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_RGB_888.png new file mode 100644 index 00000000000..28d51925cae Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/golden/terminal_console_output_320x240_RGB_888.png differ diff --git a/ports/zephyr-cp/tests/zephyr_display/test.gif b/ports/zephyr-cp/tests/zephyr_display/test.gif new file mode 100644 index 00000000000..4f96816a1f0 Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/test.gif differ diff --git a/ports/zephyr-cp/tests/zephyr_display/test.jpg b/ports/zephyr-cp/tests/zephyr_display/test.jpg new file mode 100644 index 00000000000..488357f506a Binary files /dev/null and b/ports/zephyr-cp/tests/zephyr_display/test.jpg differ diff --git a/ports/zephyr-cp/tests/zephyr_display/test_gifio.py b/ports/zephyr-cp/tests/zephyr_display/test_gifio.py new file mode 100644 index 00000000000..d4a665e2d44 --- /dev/null +++ b/ports/zephyr-cp/tests/zephyr_display/test_gifio.py @@ -0,0 +1,201 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +import shutil +from pathlib import Path + +import pytest +from PIL import Image + + +_TEST_GIF_PATH = Path(__file__).parent / "test.gif" +_TEST_GIF_BYTES = _TEST_GIF_PATH.read_bytes() + + +def _read_image(path: Path) -> tuple[int, int, bytes]: + with Image.open(path) as img: + rgb = img.convert("RGB") + return rgb.width, rgb.height, rgb.tobytes() + + +def _golden_compare_or_update(request, captures, golden_path): + if not captures or not captures[0].exists(): + pytest.skip("display capture was not produced") + + if request.config.getoption("--update-goldens"): + golden_path.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(captures[0], golden_path) + return + + gw, gh, gpx = _read_image(golden_path) + dw, dh, dpx = _read_image(captures[0]) + assert (dw, dh) == (gw, gh) + assert gpx == dpx + + +GIFIO_METADATA_CODE = """\ +import gifio + +odg = gifio.OnDiskGif('/test.gif') +print('size', odg.width, odg.height) +print('frame_count', odg.frame_count) +print('duration', round(odg.duration, 3)) +print('min_delay', round(odg.min_delay, 3)) +print('max_delay', round(odg.max_delay, 3)) + +delay = odg.next_frame() +print('delay', round(delay, 3)) + +bitmap = odg.bitmap +print('bitmap_size', bitmap.width, bitmap.height) + +for i in range(min(odg.width, 8)): + print('px', i, hex(bitmap[i, 0])) + +odg.deinit() +print('deinited') + +try: + odg.next_frame() +except Exception as e: + print('after_deinit', type(e).__name__) + +print('done') +""" + + +GIFIO_DECODE_CODE = """\ +import board +import displayio +import time +from gifio import OnDiskGif + +odg = OnDiskGif('/test.gif') +print('size', odg.width, odg.height) +print('frame_count', odg.frame_count) + +scale = 10 +tg = displayio.TileGrid( + odg.bitmap, + pixel_shader=displayio.ColorConverter( + input_colorspace=displayio.Colorspace.RGB565_SWAPPED + ), +) +g = displayio.Group(scale=scale) +g.x = (board.DISPLAY.width - odg.width * scale) // 2 +g.y = (board.DISPLAY.height - odg.height * scale) // 2 +g.append(tg) + +board.DISPLAY.auto_refresh = False +board.DISPLAY.root_group = g + +# Pin the render loop to a known point in simulated time so that the +# capture_times_ns schedule below lands on each GIF frame while it is on screen. +LOOP_START = 10.0 +FRAME_HOLD = 2.0 +while time.monotonic() < LOOP_START: + time.sleep(0.05) +print('loop_start', round(time.monotonic(), 3)) + +for frame_index in range(odg.frame_count): + odg.next_frame() + board.DISPLAY.refresh() + print('rendered', frame_index, round(time.monotonic(), 3)) + # Hold this frame on screen; the capture for this frame is scheduled + # for the middle of this window. + target = LOOP_START + (frame_index + 1) * FRAME_HOLD + while time.monotonic() < target: + time.sleep(0.05) + +print('done') +while True: + time.sleep(1) +""" + + +# Keep these in sync with LOOP_START / FRAME_HOLD in GIFIO_DECODE_CODE. +_DECODE_LOOP_START_S = 10.0 +_DECODE_FRAME_HOLD_S = 2.0 +_DECODE_FRAME_COUNT = 13 +# Capture at the midpoint of each frame's hold window. +_DECODE_CAPTURE_TIMES_NS = [ + int( + (_DECODE_LOOP_START_S + i * _DECODE_FRAME_HOLD_S + _DECODE_FRAME_HOLD_S / 2) + * 1_000_000_000 + ) + for i in range(_DECODE_FRAME_COUNT) +] + + +GIFIO_WRITER_CODE = """\ +import displayio +import gifio +import os + +width, height = 8, 4 +buf = bytearray(width * height * 2) +for i in range(width * height): + # RGB565 gradient + value = (i * 0x0841) & 0xFFFF + buf[2 * i] = (value >> 8) & 0xFF + buf[2 * i + 1] = value & 0xFF + +path = '/out.gif' +with gifio.GifWriter(path, width, height, displayio.Colorspace.RGB565, loop=True) as writer: + writer.add_frame(buf, 0.1) + writer.add_frame(buf, 0.2) + +size = os.stat(path)[6] +print('wrote_size', size) + +with open(path, 'rb') as f: + header = f.read(6) +print('header', header) + +print('done') +""" + + +_GIFIO_METADATA_DRIVE = {"code.py": GIFIO_METADATA_CODE, "test.gif": _TEST_GIF_BYTES} +_GIFIO_DECODE_DRIVE = {"code.py": GIFIO_DECODE_CODE, "test.gif": _TEST_GIF_BYTES} +_GIFIO_WRITER_DRIVE = {"code.py": GIFIO_WRITER_CODE} + + +@pytest.mark.circuitpy_drive(_GIFIO_METADATA_DRIVE) +def test_gifio_metadata(circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "size 16 16" in output + assert "frame_count 13" in output + assert "bitmap_size 16 16" in output + assert "min_delay 0.08" in output + assert "max_delay 0.08" in output + # 13 frames * 0.08s = 1.04s + assert "duration 1.04" in output + assert "delay 0.08" in output + assert "deinited" in output + # Using a deinited OnDiskGif should raise an exception. + assert "after_deinit" in output + assert "done" in output + + +@pytest.mark.circuitpy_drive(_GIFIO_DECODE_DRIVE) +@pytest.mark.display(capture_times_ns=_DECODE_CAPTURE_TIMES_NS) +@pytest.mark.duration(60) +def test_gifio_decode(request, circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "size 16 16" in output + assert "frame_count 13" in output + for frame_index in range(_DECODE_FRAME_COUNT): + assert f"rendered {frame_index}" in output + assert "done" in output + + captures = circuitpython.display_capture_paths() + assert len(captures) == _DECODE_FRAME_COUNT + golden_dir = Path(__file__).parent / "golden" + for frame_index, capture in enumerate(captures): + golden = golden_dir / f"gifio_frame_{frame_index:02d}_320x240.png" + _golden_compare_or_update(request, [capture], golden) diff --git a/ports/zephyr-cp/tests/zephyr_display/test_jpegio.py b/ports/zephyr-cp/tests/zephyr_display/test_jpegio.py new file mode 100644 index 00000000000..6368be7a5cf --- /dev/null +++ b/ports/zephyr-cp/tests/zephyr_display/test_jpegio.py @@ -0,0 +1,87 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +import shutil +from pathlib import Path + +import pytest +from PIL import Image + + +_TEST_JPG_PATH = Path(__file__).parent / "test.jpg" +_TEST_JPG_BYTES = _TEST_JPG_PATH.read_bytes() + + +def _read_image(path: Path) -> tuple[int, int, bytes]: + with Image.open(path) as img: + rgb = img.convert("RGB") + return rgb.width, rgb.height, rgb.tobytes() + + +def _golden_compare_or_update(request, captures, golden_path): + if not captures or not captures[0].exists(): + pytest.skip("display capture was not produced") + + if request.config.getoption("--update-goldens"): + golden_path.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(captures[0], golden_path) + return + + gw, gh, gpx = _read_image(golden_path) + dw, dh, dpx = _read_image(captures[0]) + assert (dw, dh) == (gw, gh) + assert gpx == dpx + + +JPEGIO_DECODE_CODE = """\ +import board +import displayio +import time +from jpegio import JpegDecoder + +decoder = JpegDecoder() +width, height = decoder.open("/test.jpg") +print('size', width, height) + +bitmap = displayio.Bitmap(width, height, 65535) +decoder.decode(bitmap) + +for i in range(min(width, 8)): + print('px', i, hex(bitmap[i, 0])) + +scale = 10 +tg = displayio.TileGrid( + bitmap, + pixel_shader=displayio.ColorConverter( + input_colorspace=displayio.Colorspace.RGB565_SWAPPED + ), +) +g = displayio.Group(scale=scale) +g.x = (board.DISPLAY.width - width * scale) // 2 +g.y = (board.DISPLAY.height - height * scale) // 2 +g.append(tg) + +board.DISPLAY.auto_refresh = False +board.DISPLAY.root_group = g +board.DISPLAY.refresh() +print('rendered') +while True: + time.sleep(1) +""" + + +_JPEGIO_DRIVE = {"code.py": JPEGIO_DECODE_CODE, "test.jpg": _TEST_JPG_BYTES} + + +@pytest.mark.circuitpy_drive(_JPEGIO_DRIVE) +@pytest.mark.display(capture_times_ns=[14_000_000_000]) +@pytest.mark.duration(18) +def test_jpegio_decode(request, circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "size 20 20" in output + assert "rendered" in output + + golden = Path(__file__).parent / "golden" / "jpegio_test_pattern_320x240.png" + _golden_compare_or_update(request, circuitpython.display_capture_paths(), golden) diff --git a/ports/zephyr-cp/tests/zephyr_display/test_zephyr_display.py b/ports/zephyr-cp/tests/zephyr_display/test_zephyr_display.py new file mode 100644 index 00000000000..6700c42ec4a --- /dev/null +++ b/ports/zephyr-cp/tests/zephyr_display/test_zephyr_display.py @@ -0,0 +1,365 @@ +# SPDX-FileCopyrightText: 2026 Scott Shawcroft for Adafruit Industries +# SPDX-License-Identifier: MIT + +import colorsys +import shutil +import struct +from pathlib import Path + +import pytest +from PIL import Image + + +def _read_image(path: Path) -> tuple[int, int, bytes]: + """Read an image file and return (width, height, RGB bytes).""" + with Image.open(path) as img: + rgb = img.convert("RGB") + return rgb.width, rgb.height, rgb.tobytes() + + +def _read_mask(golden_path: Path) -> bytes | None: + """Load the companion mask PNG for a golden image, if it exists. + + Non-zero pixels are masked (skipped during comparison). + """ + mask_path = golden_path.with_suffix(".mask.png") + if not mask_path.exists(): + return None + with Image.open(mask_path) as img: + return img.convert("L").tobytes() + + +def _assert_pixels_equal_masked( + golden_pixels: bytes, actual_pixels: bytes, mask: bytes | None = None +): + """Assert pixels match, skipping positions where the mask is non-zero.""" + assert len(golden_pixels) == len(actual_pixels) + for i in range(0, len(golden_pixels), 3): + if mask is not None and mask[i // 3] != 0: + continue + if golden_pixels[i : i + 3] != actual_pixels[i : i + 3]: + pixel = i // 3 + assert False, ( + f"Pixel {pixel} mismatch: " + f"golden={tuple(golden_pixels[i : i + 3])} " + f"actual={tuple(actual_pixels[i : i + 3])}" + ) + + +BOARD_DISPLAY_AVAILABLE_CODE = """\ +import board +print(hasattr(board, 'DISPLAY')) +print(type(board.DISPLAY).__name__) +print(board.DISPLAY.width, board.DISPLAY.height) +print('done') +""" + + +@pytest.mark.circuitpy_drive({"code.py": BOARD_DISPLAY_AVAILABLE_CODE}) +@pytest.mark.display +@pytest.mark.duration(8) +def test_board_display_available(circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "True" in output + assert "Display" in output + assert "320 240" in output + assert "done" in output + + +CONSOLE_TERMINAL_PRESENT_CODE = """\ +import board + +root = board.DISPLAY.root_group +has_terminal_tilegrids = ( + type(root).__name__ == 'Group' and + len(root) >= 2 and + type(root[0]).__name__ == 'TileGrid' and + type(root[-1]).__name__ == 'TileGrid' +) +print('has_terminal_tilegrids:', has_terminal_tilegrids) +print('done') +""" + + +@pytest.mark.circuitpy_drive({"code.py": CONSOLE_TERMINAL_PRESENT_CODE}) +@pytest.mark.display +@pytest.mark.duration(8) +def test_console_terminal_present_by_default(circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "has_terminal_tilegrids: True" in output + assert "done" in output + + +CONSOLE_OUTPUT_GOLDEN_CODE = """\ +import time +time.sleep(0.25) +print('done') +while True: + time.sleep(1) +""" + + +def _golden_compare_or_update(request, captures, golden_path, mask_path=None): + """Compare captured PNG against golden, or update golden if --update-goldens. + + mask_path overrides the default companion mask lookup (golden.mask.png). + """ + if not captures or not captures[0].exists(): + pytest.skip("display capture was not produced") + + if request.config.getoption("--update-goldens"): + golden_path.parent.mkdir(parents=True, exist_ok=True) + shutil.copy2(captures[0], golden_path) + return + + gw, gh, gpx = _read_image(golden_path) + dw, dh, dpx = _read_image(captures[0]) + if mask_path is not None: + mask = _read_mask(mask_path) + else: + mask = _read_mask(golden_path) + + assert (dw, dh) == (gw, gh) + _assert_pixels_equal_masked(gpx, dpx, mask) + + +@pytest.mark.circuitpy_drive({"code.py": CONSOLE_OUTPUT_GOLDEN_CODE}) +@pytest.mark.display(capture_times_ns=[4_000_000_000]) +@pytest.mark.duration(8) +def test_console_output_golden(request, circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "done" in output + + golden = Path(__file__).parent / "golden" / "terminal_console_output_320x240.png" + _golden_compare_or_update(request, circuitpython.display_capture_paths(), golden) + + +PIXEL_FORMATS = ["ARGB_8888", "RGB_888", "RGB_565", "BGR_565", "L_8", "AL_88", "MONO01", "MONO10"] + +# Shared mask: the same screen regions vary regardless of pixel format. +_CONSOLE_GOLDEN_MASK = Path(__file__).parent / "golden" / "terminal_console_output_320x240.png" + + +@pytest.mark.circuitpy_drive({"code.py": CONSOLE_OUTPUT_GOLDEN_CODE}) +@pytest.mark.display(capture_times_ns=[4_000_000_000]) +@pytest.mark.duration(8) +@pytest.mark.parametrize( + "pixel_format", + PIXEL_FORMATS, + indirect=True, +) +def test_console_output_golden_pixel_format(pixel_format, request, circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "done" in output + + golden_name = f"terminal_console_output_320x240_{pixel_format}.png" + golden = Path(__file__).parent / "golden" / golden_name + _golden_compare_or_update( + request, circuitpython.display_capture_paths(), golden, _CONSOLE_GOLDEN_MASK + ) + + +MONO_NO_VTILED_FORMATS = ["MONO01", "MONO10"] + + +@pytest.mark.circuitpy_drive({"code.py": CONSOLE_OUTPUT_GOLDEN_CODE}) +@pytest.mark.display(capture_times_ns=[4_000_000_000]) +@pytest.mark.display_mono_vtiled(False) +@pytest.mark.duration(8) +@pytest.mark.parametrize( + "pixel_format", + MONO_NO_VTILED_FORMATS, + indirect=True, +) +def test_console_output_golden_mono_no_vtiled(pixel_format, request, circuitpython): + circuitpython.wait_until_done() + + output = circuitpython.serial.all_output + assert "done" in output + + golden_name = f"terminal_console_output_320x240_{pixel_format}_no_vtiled.png" + golden = Path(__file__).parent / "golden" / golden_name + _golden_compare_or_update( + request, circuitpython.display_capture_paths(), golden, _CONSOLE_GOLDEN_MASK + ) + + +def _generate_gradient_bmp(width, height): + """Generate a 24-bit BMP with HSL color gradient. + + Hue sweeps left to right, lightness goes from black (bottom) to white (top), + saturation is 1.0. + """ + row_size = width * 3 + row_padding = (4 - (row_size % 4)) % 4 + padded_row_size = row_size + row_padding + pixel_data_size = padded_row_size * height + file_size = 14 + 40 + pixel_data_size + + header = struct.pack( + "<2sIHHI", + b"BM", + file_size, + 0, + 0, + 14 + 40, + ) + info = struct.pack( + " + +extern int circuitpython_main(void); + +int main(void) { + // Use a unique name for CP main so that the linker needs to look in libcircuitpython.a + return circuitpython_main(); +} diff --git a/py/argcheck.c b/py/argcheck.c index 9302dec96c3..155e29bdc15 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -170,13 +170,13 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, } #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE -NORETURN void mp_arg_error_terse_mismatch(void) { +MP_NORETURN void mp_arg_error_terse_mismatch(void) { mp_raise_TypeError(MP_ERROR_TEXT("argument num/types mismatch")); } #endif #if MICROPY_CPYTHON_COMPAT -NORETURN void mp_arg_error_unimpl_kw(void) { +MP_NORETURN void mp_arg_error_unimpl_kw(void) { mp_raise_NotImplementedError(MP_ERROR_TEXT("keyword argument(s) not implemented - use normal args instead")); } #endif @@ -312,6 +312,6 @@ mp_int_t mp_arg_validate_type_int(mp_obj_t obj, qstr arg_name) { return an_int; } -NORETURN void mp_arg_error_invalid(qstr arg_name) { +MP_NORETURN void mp_arg_error_invalid(qstr arg_name) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), arg_name); } diff --git a/py/asmarm.c b/py/asmarm.c index 60064907012..15bc73b61ec 100644 --- a/py/asmarm.c +++ b/py/asmarm.c @@ -36,7 +36,7 @@ #include "py/asmarm.h" -#define SIGNED_FIT24(x) (((x) & 0xff800000) == 0) || (((x) & 0xff000000) == 0xff000000) +#define REG_TEMP ASM_ARM_REG_R8 // Insert word into instruction flow static void emit(asm_arm_t *as, uint op) { @@ -168,13 +168,23 @@ void asm_arm_entry(asm_arm_t *as, int num_locals) { emit_al(as, asm_arm_op_push(as->push_reglist | 1 << ASM_ARM_REG_LR)); if (as->stack_adjust > 0) { - emit_al(as, asm_arm_op_sub_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust)); + if (as->stack_adjust < 0x100) { + emit_al(as, asm_arm_op_sub_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust)); + } else { + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, as->stack_adjust); + emit_al(as, asm_arm_op_sub_reg(ASM_ARM_REG_SP, ASM_ARM_REG_SP, REG_TEMP)); + } } } void asm_arm_exit(asm_arm_t *as) { if (as->stack_adjust > 0) { - emit_al(as, asm_arm_op_add_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust)); + if (as->stack_adjust < 0x100) { + emit_al(as, asm_arm_op_add_imm(ASM_ARM_REG_SP, ASM_ARM_REG_SP, as->stack_adjust)); + } else { + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, as->stack_adjust); + emit_al(as, asm_arm_op_add_reg(ASM_ARM_REG_SP, ASM_ARM_REG_SP, REG_TEMP)); + } } emit_al(as, asm_arm_op_pop(as->push_reglist | (1 << ASM_ARM_REG_PC))); @@ -282,8 +292,15 @@ void asm_arm_orr_reg_reg_reg(asm_arm_t *as, uint rd, uint rn, uint rm) { } void asm_arm_mov_reg_local_addr(asm_arm_t *as, uint rd, int local_num) { - // add rd, sp, #local_num*4 - emit_al(as, asm_arm_op_add_imm(rd, ASM_ARM_REG_SP, local_num << 2)); + if (local_num >= 0x40) { + // mov temp, #local_num*4 + // add rd, sp, temp + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, local_num << 2); + emit_al(as, asm_arm_op_add_reg(rd, ASM_ARM_REG_SP, REG_TEMP)); + } else { + // add rd, sp, #local_num*4 + emit_al(as, asm_arm_op_add_imm(rd, ASM_ARM_REG_SP, local_num << 2)); + } } void asm_arm_mov_reg_pcrel(asm_arm_t *as, uint reg_dest, uint label) { @@ -316,39 +333,92 @@ void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs) { emit_al(as, 0x1a00050 | (rd << 12) | (rs << 8) | rd); } -void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn, uint byte_offset) { - // ldr rd, [rn, #off] - emit_al(as, 0x5900000 | (rn << 16) | (rd << 12) | byte_offset); +void asm_arm_ldr_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) { + if (byte_offset < 0x1000) { + // ldr rd, [rn, #off] + emit_al(as, 0x5900000 | (rn << 16) | (rd << 12) | byte_offset); + } else { + // mov temp, #off + // ldr rd, [rn, temp] + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset); + emit_al(as, 0x7900000 | (rn << 16) | (rd << 12) | REG_TEMP); + } } -void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn) { - // ldrh rd, [rn] - emit_al(as, 0x1d000b0 | (rn << 16) | (rd << 12)); +void asm_arm_ldrh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) { + // ldrh doesn't support scaled register index + emit_al(as, 0x1a00080 | (REG_TEMP << 12) | rn); // mov temp, rn, lsl #1 + emit_al(as, 0x19000b0 | (rm << 16) | (rd << 12) | REG_TEMP); // ldrh rd, [rm, temp]; } void asm_arm_ldrh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) { - // ldrh rd, [rn, #off] - emit_al(as, 0x1f000b0 | (rn << 16) | (rd << 12) | ((byte_offset & 0xf0) << 4) | (byte_offset & 0xf)); + if (byte_offset < 0x100) { + // ldrh rd, [rn, #off] + emit_al(as, 0x1d000b0 | (rn << 16) | (rd << 12) | ((byte_offset & 0xf0) << 4) | (byte_offset & 0xf)); + } else { + // mov temp, #off + // ldrh rd, [rn, temp] + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset); + emit_al(as, 0x19000b0 | (rn << 16) | (rd << 12) | REG_TEMP); + } +} + +void asm_arm_ldrb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) { + // ldrb rd, [rm, rn] + emit_al(as, 0x7d00000 | (rm << 16) | (rd << 12) | rn); } -void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn) { - // ldrb rd, [rn] - emit_al(as, 0x5d00000 | (rn << 16) | (rd << 12)); +void asm_arm_ldrb_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) { + if (byte_offset < 0x1000) { + // ldrb rd, [rn, #off] + emit_al(as, 0x5d00000 | (rn << 16) | (rd << 12) | byte_offset); + } else { + // mov temp, #off + // ldrb rd, [rn, temp] + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset); + emit_al(as, 0x7d00000 | (rn << 16) | (rd << 12) | REG_TEMP); + } } -void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm, uint byte_offset) { - // str rd, [rm, #off] - emit_al(as, 0x5800000 | (rm << 16) | (rd << 12) | byte_offset); +void asm_arm_ldr_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) { + // ldr rd, [rm, rn, lsl #2] + emit_al(as, 0x7900100 | (rm << 16) | (rd << 12) | rn); +} + +void asm_arm_str_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset) { + if (byte_offset < 0x1000) { + // str rd, [rm, #off] + emit_al(as, 0x5800000 | (rm << 16) | (rd << 12) | byte_offset); + } else { + // mov temp, #off + // str rd, [rm, temp] + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset); + emit_al(as, 0x7800000 | (rm << 16) | (rd << 12) | REG_TEMP); + } } -void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm) { - // strh rd, [rm] - emit_al(as, 0x1c000b0 | (rm << 16) | (rd << 12)); +void asm_arm_strh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset) { + if (byte_offset < 0x100) { + // strh rd, [rn, #off] + emit_al(as, 0x1c000b0 | (rn << 16) | (rd << 12) | ((byte_offset & 0xf0) << 4) | (byte_offset & 0xf)); + } else { + // mov temp, #off + // strh rd, [rn, temp] + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset); + emit_al(as, 0x18000b0 | (rn << 16) | (rd << 12) | REG_TEMP); + } } -void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm) { - // strb rd, [rm] - emit_al(as, 0x5c00000 | (rm << 16) | (rd << 12)); +void asm_arm_strb_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset) { + if (byte_offset < 0x1000) { + // strb rd, [rm, #off] + emit_al(as, 0x5c00000 | (rm << 16) | (rd << 12) | byte_offset); + } else { + // mov temp, #off + // strb rd, [rm, temp] + asm_arm_mov_reg_i32_optimised(as, REG_TEMP, byte_offset); + emit_al(as, 0x7c00000 | (rm << 16) | (rd << 12) | REG_TEMP); + } } void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) { @@ -358,8 +428,8 @@ void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) { void asm_arm_strh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) { // strh doesn't support scaled register index - emit_al(as, 0x1a00080 | (ASM_ARM_REG_R8 << 12) | rn); // mov r8, rn, lsl #1 - emit_al(as, 0x18000b0 | (rm << 16) | (rd << 12) | ASM_ARM_REG_R8); // strh rd, [rm, r8] + emit_al(as, 0x1a00080 | (REG_TEMP << 12) | rn); // mov temp, rn, lsl #1 + emit_al(as, 0x18000b0 | (rm << 16) | (rd << 12) | REG_TEMP); // strh rd, [rm, temp] } void asm_arm_strb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn) { @@ -374,7 +444,7 @@ void asm_arm_bcc_label(asm_arm_t *as, int cond, uint label) { rel -= 8; // account for instruction prefetch, PC is 8 bytes ahead of this instruction rel >>= 2; // in ARM mode the branch target is 32-bit aligned, so the 2 LSB are omitted - if (SIGNED_FIT24(rel)) { + if (MP_FIT_SIGNED(24, rel)) { emit(as, cond | 0xa000000 | (rel & 0xffffff)); } else { printf("asm_arm_bcc: branch does not fit in 24 bits\n"); diff --git a/py/asmarm.h b/py/asmarm.h index a0e057fce44..f3fd586a375 100644 --- a/py/asmarm.h +++ b/py/asmarm.h @@ -109,13 +109,18 @@ void asm_arm_lsr_reg_reg(asm_arm_t *as, uint rd, uint rs); void asm_arm_asr_reg_reg(asm_arm_t *as, uint rd, uint rs); // memory -void asm_arm_ldr_reg_reg(asm_arm_t *as, uint rd, uint rn, uint byte_offset); -void asm_arm_ldrh_reg_reg(asm_arm_t *as, uint rd, uint rn); +void asm_arm_ldr_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset); void asm_arm_ldrh_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset); -void asm_arm_ldrb_reg_reg(asm_arm_t *as, uint rd, uint rn); -void asm_arm_str_reg_reg(asm_arm_t *as, uint rd, uint rm, uint byte_offset); -void asm_arm_strh_reg_reg(asm_arm_t *as, uint rd, uint rm); -void asm_arm_strb_reg_reg(asm_arm_t *as, uint rd, uint rm); +void asm_arm_ldrb_reg_reg_offset(asm_arm_t *as, uint rd, uint rn, uint byte_offset); +void asm_arm_str_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset); +void asm_arm_strh_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset); +void asm_arm_strb_reg_reg_offset(asm_arm_t *as, uint rd, uint rm, uint byte_offset); + +// load from array +void asm_arm_ldr_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn); +void asm_arm_ldrh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn); +void asm_arm_ldrb_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn); + // store to array void asm_arm_str_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn); void asm_arm_strh_reg_reg_reg(asm_arm_t *as, uint rd, uint rm, uint rn); @@ -160,12 +165,12 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src); // Holds a pointer to mp_fun_table #define REG_FUN_TABLE ASM_ARM_REG_FUN_TABLE -#define ASM_T asm_arm_t -#define ASM_END_PASS asm_arm_end_pass -#define ASM_ENTRY asm_arm_entry -#define ASM_EXIT asm_arm_exit +#define ASM_T asm_arm_t +#define ASM_END_PASS asm_arm_end_pass +#define ASM_ENTRY(as, num_locals, name) asm_arm_entry((as), (num_locals)) +#define ASM_EXIT asm_arm_exit -#define ASM_JUMP asm_arm_b_label +#define ASM_JUMP asm_arm_b_label #define ASM_JUMP_IF_REG_ZERO(as, reg, label, bool_test) \ do { \ asm_arm_cmp_reg_i8(as, reg, 0); \ @@ -203,18 +208,28 @@ void asm_arm_bx_reg(asm_arm_t *as, uint reg_src); #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_arm_sub_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src)) #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_arm_mul_reg_reg_reg((as), (reg_dest), (reg_dest), (reg_src)) -#define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 0) -#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset)) -#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_arm_ldrb_reg_reg((as), (reg_dest), (reg_base)) -#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_arm_ldrh_reg_reg((as), (reg_dest), (reg_base)) -#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_arm_ldrh_reg_reg_offset((as), (reg_dest), (reg_base), 2 * (uint16_offset)) -#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_arm_ldr_reg_reg((as), (reg_dest), (reg_base), 0) - -#define ASM_STORE_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0) -#define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_str_reg_reg((as), (reg_dest), (reg_base), 4 * (word_offset)) -#define ASM_STORE8_REG_REG(as, reg_value, reg_base) asm_arm_strb_reg_reg((as), (reg_value), (reg_base)) -#define ASM_STORE16_REG_REG(as, reg_value, reg_base) asm_arm_strh_reg_reg((as), (reg_value), (reg_base)) -#define ASM_STORE32_REG_REG(as, reg_value, reg_base) asm_arm_str_reg_reg((as), (reg_value), (reg_base), 0) +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset)) +#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) ASM_LOAD8_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD8_REG_REG_OFFSET(as, reg_dest, reg_base, byte_offset) asm_arm_ldrb_reg_reg_offset((as), (reg_dest), (reg_base), (byte_offset)) +#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) ASM_LOAD16_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, halfword_offset) asm_arm_ldrh_reg_reg_offset((as), (reg_dest), (reg_base), 2 * (halfword_offset)) +#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_arm_ldr_reg_reg_offset((as), (reg_dest), (reg_base), 4 * (word_offset)) + +#define ASM_STORE_REG_REG_OFFSET(as, reg_value, reg_base, word_offset) ASM_STORE32_REG_REG_OFFSET((as), (reg_value), (reg_base), (word_offset)) +#define ASM_STORE8_REG_REG(as, reg_value, reg_base) ASM_STORE8_REG_REG_OFFSET((as), (reg_value), (reg_base), 0) +#define ASM_STORE8_REG_REG_OFFSET(as, reg_value, reg_base, byte_offset) asm_arm_strb_reg_reg_offset((as), (reg_value), (reg_base), (byte_offset)) +#define ASM_STORE16_REG_REG(as, reg_value, reg_base) ASM_STORE16_REG_REG_OFFSET((as), (reg_value), (reg_base), 0) +#define ASM_STORE16_REG_REG_OFFSET(as, reg_value, reg_base, halfword_offset) asm_arm_strh_reg_reg_offset((as), (reg_value), (reg_base), 2 * (halfword_offset)) +#define ASM_STORE32_REG_REG(as, reg_value, reg_base) ASM_STORE32_REG_REG_OFFSET((as), (reg_value), (reg_base), 0) +#define ASM_STORE32_REG_REG_OFFSET(as, reg_value, reg_base, word_offset) asm_arm_str_reg_reg_offset((as), (reg_value), (reg_base), 4 * (word_offset)) + +#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrb_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index)) +#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldrh_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index)) +#define ASM_LOAD32_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_arm_ldr_reg_reg_reg((as), (reg_dest), (reg_base), (reg_index)) +#define ASM_STORE8_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_arm_strb_reg_reg_reg((as), (reg_val), (reg_base), (reg_index)) +#define ASM_STORE16_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_arm_strh_reg_reg_reg((as), (reg_val), (reg_base), (reg_index)) +#define ASM_STORE32_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_arm_str_reg_reg_reg((as), (reg_val), (reg_base), (reg_index)) #endif // GENERIC_ASM_API diff --git a/py/asmbase.c b/py/asmbase.c index cf64e3f3d05..07dbf4430f9 100644 --- a/py/asmbase.c +++ b/py/asmbase.c @@ -30,6 +30,7 @@ #include "py/obj.h" #include "py/misc.h" #include "py/asmbase.h" +#include "py/persistentcode.h" #if MICROPY_EMIT_MACHINE_CODE @@ -52,7 +53,7 @@ void mp_asm_base_start_pass(mp_asm_base_t *as, int pass) { } else { // allocating executable RAM is platform specific MP_PLAT_ALLOC_EXEC(as->code_offset, (void **)&as->code_base, &as->code_size); - assert(as->code_base != NULL); + assert(as->code_size == 0 || as->code_base != NULL); } as->pass = pass; as->suppress = false; @@ -91,12 +92,17 @@ void mp_asm_base_label_assign(mp_asm_base_t *as, size_t label) { } else { // ensure label offset has not changed from PASS_COMPUTE to PASS_EMIT assert(as->label_offsets[label] == as->code_offset); + #if MICROPY_DYNAMIC_COMPILER && MICROPY_EMIT_NATIVE_DEBUG + if (mp_dynamic_compiler.native_arch == MP_NATIVE_ARCH_DEBUG) { + mp_printf(MICROPY_EMIT_NATIVE_DEBUG_PRINTER, "label(label_%u)\n", (unsigned int)label); + } + #endif } } // align must be a multiple of 2 void mp_asm_base_align(mp_asm_base_t *as, unsigned int align) { - as->code_offset = (as->code_offset + align - 1) & (~(align - 1)); + as->code_offset = (as->code_offset + align - 1) & (~(size_t)(align - 1)); } // this function assumes a little endian machine diff --git a/py/asmbase.h b/py/asmbase.h index 352d2f54cc8..461393fe77f 100644 --- a/py/asmbase.h +++ b/py/asmbase.h @@ -27,6 +27,7 @@ #define MICROPY_INCLUDED_PY_ASMBASE_H #include +#include #include #define MP_ASM_PASS_COMPUTE (1) diff --git a/py/asmrv32.c b/py/asmrv32.c new file mode 100644 index 00000000000..1d0cea6c026 --- /dev/null +++ b/py/asmrv32.c @@ -0,0 +1,614 @@ +/* + * This file is part of the MicroPython project, https://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +#include +#include +#include + +#include "py/emit.h" +#include "py/misc.h" +#include "py/mpconfig.h" + +// wrapper around everything in this file +#if MICROPY_EMIT_RV32 + +#include "py/asmrv32.h" +#include "py/mpstate.h" +#include "py/persistentcode.h" + +#if MICROPY_DEBUG_VERBOSE +#define DEBUG_PRINT (1) +#define DEBUG_printf DEBUG_printf +#else +#define DEBUG_printf(...) (void)0 +#endif + +#define INTERNAL_TEMPORARY ASM_RV32_REG_S0 + +#define FIT_UNSIGNED(value, bits) (((value) & ~((1U << (bits)) - 1)) == 0) +#define FIT_SIGNED(value, bits) \ + ((((value) & ~((1U << ((bits) - 1)) - 1)) == 0) || \ + (((value) & ~((1U << ((bits) - 1)) - 1)) == ~((1U << ((bits) - 1)) - 1))) + +/////////////////////////////////////////////////////////////////////////////// + +void asm_rv32_emit_word_opcode(asm_rv32_t *state, mp_uint_t word) { + uint8_t *cursor = mp_asm_base_get_cur_to_write_bytes(&state->base, sizeof(uint32_t)); + if (cursor == NULL) { + return; + } + + #if MP_ENDIANNESS_LITTLE + cursor[0] = word & 0xFF; + cursor[1] = (word >> 8) & 0xFF; + cursor[2] = (word >> 16) & 0xFF; + cursor[3] = (word >> 24) & 0xFF; + #else + cursor[0] = (word >> 24) & 0xFF; + cursor[1] = (word >> 16) & 0xFF; + cursor[2] = (word >> 8) & 0xFF; + cursor[3] = word & 0xFF; + #endif +} + +void asm_rv32_emit_halfword_opcode(asm_rv32_t *state, mp_uint_t word) { + uint8_t *cursor = mp_asm_base_get_cur_to_write_bytes(&state->base, sizeof(uint16_t)); + if (cursor == NULL) { + return; + } + + #if MP_ENDIANNESS_LITTLE + cursor[0] = word & 0xFF; + cursor[1] = (word >> 8) & 0xFF; + #else + cursor[0] = (word >> 8) & 0xFF; + cursor[1] = word & 0xFF; + #endif +} + +/////////////////////////////////////////////////////////////////////////////// + +static void split_immediate(mp_int_t immediate, mp_uint_t *upper, mp_uint_t *lower) { + assert(upper != NULL && "Upper pointer is NULL."); + assert(lower != NULL && "Lower pointer is NULL."); + + mp_uint_t unsigned_immediate = *((mp_uint_t *)&immediate); + *upper = unsigned_immediate & 0xFFFFF000; + *lower = unsigned_immediate & 0x00000FFF; + + // Turn the lower half from unsigned to signed. + if ((*lower & 0x800) != 0) { + *upper += 0x1000; + } +} + +static void load_upper_immediate(asm_rv32_t *state, mp_uint_t rd, mp_uint_t immediate) { + // if immediate fits in 17 bits and is ≠ 0: + // c.lui rd, HI(immediate) + // else: + // lui rd, HI(immediate) + if (FIT_SIGNED(immediate, 17) && ((immediate >> 12) != 0)) { + asm_rv32_opcode_clui(state, rd, immediate); + } else { + asm_rv32_opcode_lui(state, rd, immediate); + } +} + +static void load_lower_immediate(asm_rv32_t *state, mp_uint_t rd, mp_uint_t immediate) { + // WARNING: This must be executed on a register that has either been + // previously cleared or was the target of a LUI/C.LUI or + // AUIPC opcode. + + if (immediate == 0) { + return; + } + + // if LO(immediate) fits in 6 bits: + // c.addi rd, LO(immediate) + // else: + // addi rd, rd, LO(immediate) + if (FIT_SIGNED(immediate, 6)) { + asm_rv32_opcode_caddi(state, rd, immediate); + } else { + asm_rv32_opcode_addi(state, rd, rd, immediate); + } +} + +static void load_full_immediate(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(immediate, &upper, &lower); + + // if immediate fits in 17 bits: + // c.lui rd, HI(immediate) + // else: + // lui rd, HI(immediate) + // if LO(immediate) fits in 6 bits && LO(immediate) != 0: + // c.addi rd, LO(immediate) + // else: + // addi rd, rd, LO(immediate) + load_upper_immediate(state, rd, upper); + load_lower_immediate(state, rd, lower); +} + +void asm_rv32_emit_optimised_load_immediate(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + if (FIT_SIGNED(immediate, 6)) { + // c.li rd, immediate + asm_rv32_opcode_cli(state, rd, immediate); + return; + } + + if (FIT_SIGNED(immediate, 12)) { + // addi rd, zero, immediate + asm_rv32_opcode_addi(state, rd, ASM_RV32_REG_ZERO, immediate); + return; + } + + load_full_immediate(state, rd, immediate); +} + +// RV32 does not have dedicated push/pop opcodes, so series of loads and +// stores are generated in their place. + +static void emit_registers_store(asm_rv32_t *state, mp_uint_t registers_mask) { + mp_uint_t offset = 0; + for (mp_uint_t register_index = 0; register_index < RV32_AVAILABLE_REGISTERS_COUNT; register_index++) { + if (registers_mask & (1U << register_index)) { + assert(FIT_UNSIGNED(offset >> 2, 6) && "Registers save stack offset out of range."); + // c.swsp register, offset + asm_rv32_opcode_cswsp(state, register_index, offset); + offset += sizeof(uint32_t); + } + } +} + +static void emit_registers_load(asm_rv32_t *state, mp_uint_t registers_mask) { + mp_uint_t offset = 0; + for (mp_uint_t register_index = 0; register_index < RV32_AVAILABLE_REGISTERS_COUNT; register_index++) { + if (registers_mask & (1U << register_index)) { + assert(FIT_UNSIGNED(offset >> 2, 6) && "Registers load stack offset out of range."); + // c.lwsp register, offset + asm_rv32_opcode_clwsp(state, register_index, offset); + offset += sizeof(uint32_t); + } + } +} + +static void adjust_stack(asm_rv32_t *state, mp_int_t stack_size) { + if (stack_size == 0) { + return; + } + + if (FIT_SIGNED(stack_size, 6)) { + // c.addi sp, stack_size + asm_rv32_opcode_caddi(state, ASM_RV32_REG_SP, stack_size); + return; + } + + if (FIT_SIGNED(stack_size, 12)) { + // addi sp, sp, stack_size + asm_rv32_opcode_addi(state, ASM_RV32_REG_SP, ASM_RV32_REG_SP, stack_size); + return; + } + + // li temporary, stack_size + // c.add sp, temporary + load_full_immediate(state, REG_TEMP0, stack_size); + asm_rv32_opcode_cadd(state, ASM_RV32_REG_SP, REG_TEMP0); +} + +// Generate a generic function entry prologue code sequence, setting up the +// stack to hold all the tainted registers and an arbitrary amount of space +// for locals. +static void emit_function_prologue(asm_rv32_t *state, mp_uint_t registers) { + mp_uint_t registers_count = mp_popcount(registers); + state->stack_size = (registers_count + state->locals_count) * sizeof(uint32_t); + mp_uint_t old_saved_registers_mask = state->saved_registers_mask; + // Move stack pointer up. + adjust_stack(state, -state->stack_size); + // Store registers at the top of the saved stack area. + emit_registers_store(state, registers); + state->locals_stack_offset = registers_count * sizeof(uint32_t); + state->saved_registers_mask = old_saved_registers_mask; +} + +// Restore registers and reset the stack pointer to its initial value. +static void emit_function_epilogue(asm_rv32_t *state, mp_uint_t registers) { + mp_uint_t old_saved_registers_mask = state->saved_registers_mask; + // Restore registers from the top of the stack area. + emit_registers_load(state, registers); + // Move stack pointer down. + adjust_stack(state, state->stack_size); + state->saved_registers_mask = old_saved_registers_mask; +} + +static bool calculate_displacement_for_label(asm_rv32_t *state, mp_uint_t label, ptrdiff_t *displacement) { + assert(displacement != NULL && "Displacement pointer is NULL"); + + mp_uint_t label_offset = state->base.label_offsets[label]; + *displacement = (ptrdiff_t)(label_offset - state->base.code_offset); + return (label_offset != (mp_uint_t)-1) && (*displacement < 0); +} + +/////////////////////////////////////////////////////////////////////////////// + +void asm_rv32_entry(asm_rv32_t *state, mp_uint_t locals) { + state->saved_registers_mask |= (1U << REG_FUN_TABLE) | (1U << REG_LOCAL_1) | \ + (1U << REG_LOCAL_2) | (1U << REG_LOCAL_3); + state->locals_count = locals; + emit_function_prologue(state, state->saved_registers_mask); +} + +void asm_rv32_exit(asm_rv32_t *state) { + emit_function_epilogue(state, state->saved_registers_mask); + // c.jr ra + asm_rv32_opcode_cjr(state, ASM_RV32_REG_RA); +} + +void asm_rv32_end_pass(asm_rv32_t *state) { + (void)state; +} + +void asm_rv32_emit_call_ind(asm_rv32_t *state, mp_uint_t index) { + mp_uint_t offset = index * ASM_WORD_SIZE; + state->saved_registers_mask |= (1U << ASM_RV32_REG_RA); + + if (RV32_IS_IN_C_REGISTER_WINDOW(REG_FUN_TABLE) && RV32_IS_IN_C_REGISTER_WINDOW(INTERNAL_TEMPORARY) && FIT_UNSIGNED(offset, 6)) { + state->saved_registers_mask |= (1U << INTERNAL_TEMPORARY); + // c.lw temporary, offset(fun_table) + // c.jalr temporary + asm_rv32_opcode_clw(state, RV32_MAP_IN_C_REGISTER_WINDOW(INTERNAL_TEMPORARY), RV32_MAP_IN_C_REGISTER_WINDOW(REG_FUN_TABLE), offset); + asm_rv32_opcode_cjalr(state, INTERNAL_TEMPORARY); + return; + } + + if (FIT_UNSIGNED(offset, 11)) { + // lw temporary, offset(fun_table) + // c.jalr temporary + asm_rv32_opcode_lw(state, REG_TEMP2, REG_FUN_TABLE, offset); + asm_rv32_opcode_cjalr(state, REG_TEMP2); + return; + } + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(offset, &upper, &lower); + + // lui temporary, HI(index) ; Or c.lui if possible + // c.add temporary, fun_table + // lw temporary, LO(index)(temporary) + // c.jalr temporary + load_upper_immediate(state, REG_TEMP2, upper); + asm_rv32_opcode_cadd(state, REG_TEMP2, REG_FUN_TABLE); + asm_rv32_opcode_lw(state, REG_TEMP2, REG_TEMP2, lower); + asm_rv32_opcode_cjalr(state, REG_TEMP2); +} + +void asm_rv32_emit_jump_if_reg_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t label) { + ptrdiff_t displacement = 0; + bool can_emit_short_jump = calculate_displacement_for_label(state, label, &displacement); + + if (can_emit_short_jump && FIT_SIGNED(displacement, 13)) { + // beq rs1, rs2, displacement + asm_rv32_opcode_beq(state, rs1, rs2, displacement); + return; + } + + // Compensate for the initial BNE opcode. + displacement -= ASM_WORD_SIZE; + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(displacement, &upper, &lower); + + // bne rs1, rs2, 12 ; PC + 0 + // auipc temporary, HI(displacement) ; PC + 4 + // jalr zero, temporary, LO(displacement) ; PC + 8 + // ... ; PC + 12 + asm_rv32_opcode_bne(state, rs1, rs2, 12); + asm_rv32_opcode_auipc(state, REG_TEMP2, upper); + asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, REG_TEMP2, lower); +} + +void asm_rv32_emit_jump_if_reg_nonzero(asm_rv32_t *state, mp_uint_t rs, mp_uint_t label) { + ptrdiff_t displacement = 0; + bool can_emit_short_jump = calculate_displacement_for_label(state, label, &displacement); + + if (can_emit_short_jump && FIT_SIGNED(displacement, 8) && RV32_IS_IN_C_REGISTER_WINDOW(rs)) { + // c.bnez rs', displacement + asm_rv32_opcode_cbnez(state, RV32_MAP_IN_C_REGISTER_WINDOW(rs), displacement); + return; + } + + if (can_emit_short_jump && FIT_SIGNED(displacement, 13)) { + // bne rs, zero, displacement + asm_rv32_opcode_bne(state, rs, ASM_RV32_REG_ZERO, displacement); + return; + } + + // if rs1 in C window and displacement is negative: + // c.beqz rs', 10 ; PC + 0 + // auipc temporary, HI(displacement) ; PC + 2 + // jalr zero, temporary, LO(displacement) ; PC + 6 + // ... ; PC + 10 + // else: + // beq rs, zero, 12 ; PC + 0 + // auipc temporary, HI(displacement) ; PC + 4 + // jalr zero, temporary, LO(displacement) ; PC + 8 + // ... ; PC + 12 + + if (can_emit_short_jump && RV32_IS_IN_C_REGISTER_WINDOW(rs)) { + asm_rv32_opcode_cbeqz(state, RV32_MAP_IN_C_REGISTER_WINDOW(rs), 10); + // Compensate for the C.BEQZ opcode. + displacement -= ASM_HALFWORD_SIZE; + } else { + asm_rv32_opcode_beq(state, rs, ASM_RV32_REG_ZERO, 12); + // Compensate for the BEQ opcode. + displacement -= ASM_WORD_SIZE; + } + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(displacement, &upper, &lower); + asm_rv32_opcode_auipc(state, REG_TEMP2, upper); + asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, REG_TEMP2, lower); +} + +void asm_rv32_emit_mov_local_reg(asm_rv32_t *state, mp_uint_t local, mp_uint_t rs) { + mp_uint_t offset = state->locals_stack_offset + (local * ASM_WORD_SIZE); + + if (FIT_UNSIGNED(offset >> 2, 6)) { + // c.swsp rs, offset + asm_rv32_opcode_cswsp(state, rs, offset); + return; + } + + if (FIT_UNSIGNED(offset, 11)) { + // sw rs, offset(sp) + asm_rv32_opcode_sw(state, rs, ASM_RV32_REG_SP, offset); + return; + } + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(offset, &upper, &lower); + + // lui temporary, HI(offset) ; Or c.lui if possible + // c.add temporary, sp + // sw rs, LO(offset)(temporary) + load_upper_immediate(state, REG_TEMP2, upper); + asm_rv32_opcode_cadd(state, REG_TEMP2, ASM_RV32_REG_SP); + asm_rv32_opcode_sw(state, rs, REG_TEMP2, lower); +} + +void asm_rv32_emit_mov_reg_local(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local) { + mp_uint_t offset = state->locals_stack_offset + (local * ASM_WORD_SIZE); + + if (FIT_UNSIGNED(offset >> 2, 6)) { + // c.lwsp rd, offset + asm_rv32_opcode_clwsp(state, rd, offset); + return; + } + + if (FIT_UNSIGNED(offset, 11)) { + // lw rd, offset(sp) + asm_rv32_opcode_lw(state, rd, ASM_RV32_REG_SP, offset); + return; + } + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(offset, &upper, &lower); + + // lui rd, HI(offset) ; Or c.lui if possible + // c.add rd, sp + // lw rd, LO(offset)(rd) + load_upper_immediate(state, rd, upper); + asm_rv32_opcode_cadd(state, rd, ASM_RV32_REG_SP); + asm_rv32_opcode_lw(state, rd, rd, lower); +} + +void asm_rv32_emit_mov_reg_local_addr(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local) { + mp_uint_t offset = state->locals_stack_offset + (local * ASM_WORD_SIZE); + + if (FIT_UNSIGNED(offset, 10) && offset != 0 && RV32_IS_IN_C_REGISTER_WINDOW(rd)) { + // c.addi4spn rd', offset + asm_rv32_opcode_caddi4spn(state, RV32_MAP_IN_C_REGISTER_WINDOW(rd), offset); + return; + } + + if (FIT_UNSIGNED(offset, 11)) { + // addi rd, sp, offset + asm_rv32_opcode_addi(state, rd, ASM_RV32_REG_SP, offset); + return; + } + + // li rd, offset + // c.add rd, sp + load_full_immediate(state, rd, offset); + asm_rv32_opcode_cadd(state, rd, ASM_RV32_REG_SP); +} + +static const uint8_t RV32_LOAD_OPCODE_TABLE[3] = { + 0x04, 0x05, 0x02 +}; + +void asm_rv32_emit_load_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, int32_t offset, mp_uint_t operation_size) { + assert(operation_size <= 2 && "Operation size value out of range."); + + int32_t scaled_offset = offset << operation_size; + + if (scaled_offset >= 0 && operation_size == 2 && RV32_IS_IN_C_REGISTER_WINDOW(rd) && RV32_IS_IN_C_REGISTER_WINDOW(rs) && MP_FIT_UNSIGNED(6, scaled_offset)) { + // c.lw rd', offset(rs') + asm_rv32_opcode_clw(state, RV32_MAP_IN_C_REGISTER_WINDOW(rd), RV32_MAP_IN_C_REGISTER_WINDOW(rs), scaled_offset); + return; + } + + if (MP_FIT_SIGNED(12, scaled_offset)) { + // lbu|lhu|lw rd, offset(rs) + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, RV32_LOAD_OPCODE_TABLE[operation_size], rd, rs, scaled_offset)); + return; + } + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(scaled_offset, &upper, &lower); + + // lui rd, HI(offset) ; Or c.lui if possible + // c.add rd, rs + // lbu|lhu|lw rd, LO(offset)(rd) + load_upper_immediate(state, rd, upper); + asm_rv32_opcode_cadd(state, rd, rs); + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, RV32_LOAD_OPCODE_TABLE[operation_size], rd, rd, lower)); +} + +void asm_rv32_emit_jump(asm_rv32_t *state, mp_uint_t label) { + ptrdiff_t displacement = 0; + bool can_emit_short_jump = calculate_displacement_for_label(state, label, &displacement); + + if (can_emit_short_jump && FIT_SIGNED(displacement, 12)) { + // c.j displacement + asm_rv32_opcode_cj(state, displacement); + return; + } + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(displacement, &upper, &lower); + + // auipc temporary, HI(displacement) + // jalr zero, temporary, LO(displacement) + asm_rv32_opcode_auipc(state, REG_TEMP2, upper); + asm_rv32_opcode_jalr(state, ASM_RV32_REG_ZERO, REG_TEMP2, lower); +} + +void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, int32_t offset, mp_uint_t operation_size) { + assert(operation_size <= 2 && "Operation size value out of range."); + + int32_t scaled_offset = offset << operation_size; + + if (scaled_offset >= 0 && operation_size == 2 && RV32_IS_IN_C_REGISTER_WINDOW(rd) && RV32_IS_IN_C_REGISTER_WINDOW(rs) && MP_FIT_UNSIGNED(6, scaled_offset)) { + // c.sw rd', offset(rs') + asm_rv32_opcode_csw(state, RV32_MAP_IN_C_REGISTER_WINDOW(rd), RV32_MAP_IN_C_REGISTER_WINDOW(rs), scaled_offset); + return; + } + + if (MP_FIT_SIGNED(12, scaled_offset)) { + // sb|sh|sw rd, offset(rs) + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_S(0x23, operation_size, rs, rd, scaled_offset)); + return; + } + + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(scaled_offset, &upper, &lower); + + // lui temporary, HI(offset) ; Or c.lui if possible + // c.add temporary, rs + // sb|sh|sw rd, LO(offset)(temporary) + load_upper_immediate(state, REG_TEMP2, upper); + asm_rv32_opcode_cadd(state, REG_TEMP2, rs); + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_S(0x23, operation_size, REG_TEMP2, rd, lower)); +} + +void asm_rv32_emit_mov_reg_pcrel(asm_rv32_t *state, mp_uint_t rd, mp_uint_t label) { + ptrdiff_t displacement = (ptrdiff_t)(state->base.label_offsets[label] - state->base.code_offset); + mp_uint_t upper = 0; + mp_uint_t lower = 0; + split_immediate(displacement, &upper, &lower); + + // auipc rd, HI(relative) + // addi rd, rd, LO(relative) + asm_rv32_opcode_auipc(state, rd, upper); + asm_rv32_opcode_addi(state, rd, rd, lower); +} + +void asm_rv32_emit_optimised_xor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + if (rs == rd) { + // c.li rd, 0 + asm_rv32_opcode_cli(state, rd, 0); + return; + } + + // xor rd, rd, rs + asm_rv32_opcode_xor(state, rd, rd, rs); +} + +static bool asm_rv32_allow_zba_opcodes(void) { + return asm_rv32_allowed_extensions() & RV32_EXT_ZBA; +} + +static void asm_rv32_fix_up_scaled_reg_reg_reg(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t operation_size) { + assert(operation_size <= 2 && "Operation size value out of range."); + + if (operation_size > 0 && asm_rv32_allow_zba_opcodes()) { + // sh{1,2}add rs1, rs2, rs1 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 1 << operation_size, 0x10, rs1, rs2, rs1)); + } else { + if (operation_size > 0) { + asm_rv32_opcode_cslli(state, rs2, operation_size); + } + asm_rv32_opcode_cadd(state, rs1, rs2); + } +} + +void asm_rv32_emit_load_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t operation_size) { + asm_rv32_fix_up_scaled_reg_reg_reg(state, rs1, rs2, operation_size); + asm_rv32_emit_load_reg_reg_offset(state, rd, rs1, 0, operation_size); +} + +void asm_rv32_emit_store_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t operation_size) { + asm_rv32_fix_up_scaled_reg_reg_reg(state, rs1, rs2, operation_size); + asm_rv32_emit_store_reg_reg_offset(state, rd, rs1, 0, operation_size); +} + +void asm_rv32_meta_comparison_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd) { + // sub rd, rs1, rs2 + // sltiu rd, rd, 1 + asm_rv32_opcode_sub(state, rd, rs1, rs2); + asm_rv32_opcode_sltiu(state, rd, rd, 1); +} + +void asm_rv32_meta_comparison_ne(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd) { + // sub rd, rs1, rs2 + // sltu rd, zero, rd + asm_rv32_opcode_sub(state, rd, rs1, rs2); + asm_rv32_opcode_sltu(state, rd, ASM_RV32_REG_ZERO, rd); +} + +void asm_rv32_meta_comparison_lt(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd, bool unsigned_comparison) { + // slt|sltu rd, rs1, rs2 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, (0x02 | (unsigned_comparison ? 1 : 0)), 0x00, rd, rs1, rs2)); +} + +void asm_rv32_meta_comparison_le(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd, bool unsigned_comparison) { + // slt[u] rd, rs2, rs1 + // xori rd, rd, 1 + asm_rv32_meta_comparison_lt(state, rs2, rs1, rd, unsigned_comparison); + asm_rv32_opcode_xori(state, rd, rd, 1); +} + +#endif // MICROPY_EMIT_RV32 diff --git a/py/asmrv32.h b/py/asmrv32.h new file mode 100644 index 00000000000..6f709daa11b --- /dev/null +++ b/py/asmrv32.h @@ -0,0 +1,817 @@ +/* + * This file is part of the MicroPython project, https://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_PY_ASMRV32_H +#define MICROPY_INCLUDED_PY_ASMRV32_H + +#include + +#include "py/asmbase.h" +#include "py/emit.h" +#include "py/misc.h" +#include "py/persistentcode.h" + +#define ASM_RV32_REG_X0 (0) // Zero +#define ASM_RV32_REG_X1 (1) // RA +#define ASM_RV32_REG_X2 (2) // SP +#define ASM_RV32_REG_X3 (3) // GP +#define ASM_RV32_REG_X4 (4) // TP +#define ASM_RV32_REG_X5 (5) // T0 +#define ASM_RV32_REG_X6 (6) // T1 +#define ASM_RV32_REG_X7 (7) // T2 +#define ASM_RV32_REG_X8 (8) // S0 +#define ASM_RV32_REG_X9 (9) // S1 +#define ASM_RV32_REG_X10 (10) // A0 +#define ASM_RV32_REG_X11 (11) // A1 +#define ASM_RV32_REG_X12 (12) // A2 +#define ASM_RV32_REG_X13 (13) // A3 +#define ASM_RV32_REG_X14 (14) // A4 +#define ASM_RV32_REG_X15 (15) // A5 +#define ASM_RV32_REG_X16 (16) // A6 +#define ASM_RV32_REG_X17 (17) // A7 +#define ASM_RV32_REG_X18 (18) // S2 +#define ASM_RV32_REG_X19 (19) // S3 +#define ASM_RV32_REG_X20 (20) // S4 +#define ASM_RV32_REG_X21 (21) // S5 +#define ASM_RV32_REG_X22 (22) // S6 +#define ASM_RV32_REG_X23 (23) // S7 +#define ASM_RV32_REG_X24 (24) // S8 +#define ASM_RV32_REG_X25 (25) // S9 +#define ASM_RV32_REG_X26 (26) // S10 +#define ASM_RV32_REG_X27 (27) // S11 +#define ASM_RV32_REG_X28 (28) // T3 +#define ASM_RV32_REG_X29 (29) // T4 +#define ASM_RV32_REG_X30 (30) // T5 +#define ASM_RV32_REG_X31 (31) // T6 + +// Alternate register names. + +#define ASM_RV32_REG_ZERO (ASM_RV32_REG_X0) +#define ASM_RV32_REG_RA (ASM_RV32_REG_X1) +#define ASM_RV32_REG_SP (ASM_RV32_REG_X2) +#define ASM_RV32_REG_GP (ASM_RV32_REG_X3) +#define ASM_RV32_REG_TP (ASM_RV32_REG_X4) +#define ASM_RV32_REG_A0 (ASM_RV32_REG_X10) +#define ASM_RV32_REG_A1 (ASM_RV32_REG_X11) +#define ASM_RV32_REG_A2 (ASM_RV32_REG_X12) +#define ASM_RV32_REG_A3 (ASM_RV32_REG_X13) +#define ASM_RV32_REG_A4 (ASM_RV32_REG_X14) +#define ASM_RV32_REG_A5 (ASM_RV32_REG_X15) +#define ASM_RV32_REG_A6 (ASM_RV32_REG_X16) +#define ASM_RV32_REG_A7 (ASM_RV32_REG_X17) +#define ASM_RV32_REG_T0 (ASM_RV32_REG_X5) +#define ASM_RV32_REG_T1 (ASM_RV32_REG_X6) +#define ASM_RV32_REG_T2 (ASM_RV32_REG_X7) +#define ASM_RV32_REG_T3 (ASM_RV32_REG_X28) +#define ASM_RV32_REG_T4 (ASM_RV32_REG_X29) +#define ASM_RV32_REG_T5 (ASM_RV32_REG_X30) +#define ASM_RV32_REG_T6 (ASM_RV32_REG_X31) +#define ASM_RV32_REG_FP (ASM_RV32_REG_X8) +#define ASM_RV32_REG_S0 (ASM_RV32_REG_X8) +#define ASM_RV32_REG_S1 (ASM_RV32_REG_X9) +#define ASM_RV32_REG_S2 (ASM_RV32_REG_X18) +#define ASM_RV32_REG_S3 (ASM_RV32_REG_X19) +#define ASM_RV32_REG_S4 (ASM_RV32_REG_X20) +#define ASM_RV32_REG_S5 (ASM_RV32_REG_X21) +#define ASM_RV32_REG_S6 (ASM_RV32_REG_X22) +#define ASM_RV32_REG_S7 (ASM_RV32_REG_X23) +#define ASM_RV32_REG_S8 (ASM_RV32_REG_X24) +#define ASM_RV32_REG_S9 (ASM_RV32_REG_X25) +#define ASM_RV32_REG_S10 (ASM_RV32_REG_X26) +#define ASM_RV32_REG_S11 (ASM_RV32_REG_X27) + +#define RV32_AVAILABLE_REGISTERS_COUNT 32 +#define RV32_MAP_IN_C_REGISTER_WINDOW(register_number) \ + ((register_number) - ASM_RV32_REG_X8) +#define RV32_IS_IN_C_REGISTER_WINDOW(register_number) \ + (((register_number) >= ASM_RV32_REG_X8) && ((register_number) <= ASM_RV32_REG_X15)) + +typedef struct _asm_rv32_t { + // Opaque emitter state. + mp_asm_base_t base; + // Which registers are tainted and need saving/restoring. + mp_uint_t saved_registers_mask; + // How many locals must be stored on the stack. + mp_uint_t locals_count; + // The computed function stack size. + mp_uint_t stack_size; + // The stack offset where stack-based locals start to be stored. + mp_uint_t locals_stack_offset; +} asm_rv32_t; + +enum { + RV32_EXT_NONE = 0, + RV32_EXT_ZBA = 1 << 0, + + RV32_EXT_ALL = RV32_EXT_ZBA +}; + +typedef struct _asm_rv32_backend_options_t { + // This is a bitmask holding a combination of RV32_EXT_* entries. + uint8_t allowed_extensions; +} asm_rv32_backend_options_t; + +void asm_rv32_entry(asm_rv32_t *state, mp_uint_t locals); +void asm_rv32_exit(asm_rv32_t *state); +void asm_rv32_end_pass(asm_rv32_t *state); + +//////////////////////////////////////////////////////////////////////////////// + +#define RV32_ENCODE_TYPE_B(op, ft3, rs1, rs2, imm) \ + ((op & 0x7F) | ((ft3 & 0x07) << 12) | ((imm & 0x800) >> 4) | \ + ((imm & 0x1E) << 7) | ((rs1 & 0x1F) << 15) | ((rs2 & 0x1F) << 20) | \ + ((imm & 0x7E0) << 20) | ((imm & 0x1000) << 19)) + +#define RV32_ENCODE_TYPE_CSRI(op, ft3, rd, csr, imm) \ + ((op & 0x7F) | ((rd & 0x1F) << 7) | ((ft3 & 0x07) << 12) | \ + ((csr & 0xFFF) << 20) | ((imm & 0x1F) << 15)) + +#define RV32_ENCODE_TYPE_I(op, ft3, rd, rs, imm) \ + ((op & 0x7F) | ((rd & 0x1F) << 7) | ((ft3 & 0x07) << 12) | \ + ((rs & 0x1F) << 15) | ((imm & 0xFFF) << 20)) + +#define RV32_ENCODE_TYPE_J(op, rd, imm) \ + ((op & 0x7F) | ((rd & 0x1F) << 7) | (imm & 0xFF000) | \ + ((imm & 0x800) << 9) | ((imm & 0x7FE) << 20) | ((imm & 0x100000) << 11)) + +#define RV32_ENCODE_TYPE_R(op, ft3, ft7, rd, rs1, rs2) \ + ((op & 0x7F) | ((rd & 0x1F) << 7) | ((ft3 & 0x07) << 12) | \ + ((rs1 & 0x1F) << 15) | ((rs2 & 0x1F) << 20) | ((ft7 & 0x7F) << 25)) + +#define RV32_ENCODE_TYPE_S(op, ft3, rs1, rs2, imm) \ + ((op & 0x7F) | ((imm & 0x1F) << 7) | ((ft3 & 0x07) << 12) | \ + ((rs1 & 0x1F) << 15) | ((rs2 & 0x1F) << 20) | ((imm & 0xFE0) << 20)) + +#define RV32_ENCODE_TYPE_CA(op, ft6, ft2, rd, rs) \ + ((op & 0x03) | ((ft6 & 0x3F) << 10) | ((ft2 & 0x03) << 5) | \ + ((rd & 0x03) << 7) | ((rs & 0x03) << 2)) + +#define RV32_ENCODE_TYPE_U(op, rd, imm) \ + ((op & 0x7F) | ((rd & 0x1F) << 7) | (imm & 0xFFFFF000)) + +#define RV32_ENCODE_TYPE_CB(op, ft3, rs, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rs & 0x07) << 7) | \ + (((imm) & 0xE0) << 5) | (((imm) & 0x1F) << 2)) + +#define RV32_ENCODE_TYPE_CI(op, ft3, rd, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rd & 0x1F) << 7) | \ + (((imm) & 0x20) << 7) | (((imm) & 0x1F) << 2)) + +#define RV32_ENCODE_TYPE_CIW(op, ft3, rd, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rd & 0x07) << 2) | \ + ((imm & 0x3C0) << 1) | ((imm & 0x30) << 7) | \ + ((imm & 0x08) << 2) | ((imm & 0x04) << 4)) + +#define RV32_ENCODE_TYPE_CJ(op, ft3, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((imm & 0x0E) << 2) | \ + ((imm & 0x300) << 1) | ((imm & 0x800) << 1) | ((imm & 0x400) >> 2) | \ + ((imm & 0x80) >> 1) | ((imm & 0x40) << 1) | ((imm & 0x20) >> 3) | \ + ((imm & 0x10) << 7)) + +#define RV32_ENCODE_TYPE_CL(op, ft3, rd, rs, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rd & 0x07) << 2) | \ + ((rs & 0x07) << 7) | ((imm & 0x40) >> 1) | ((imm & 0x38) << 7) | \ + ((imm & 0x04) << 4)) + +#define RV32_ENCODE_TYPE_CR(op, ft4, rs1, rs2) \ + ((op & 0x03) | ((rs2 & 0x1F) << 2) | ((rs1 & 0x1F) << 7) | ((ft4 & 0x0F) << 12)) + +#define RV32_ENCODE_TYPE_CS(op, ft3, rd, rs, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rd & 0x07) << 2) | \ + ((rs & 0x07) << 7) | ((imm & 0x40) >> 1) | ((imm & 0x38) << 7) | \ + ((imm & 0x04) << 4)) + +#define RV32_ENCODE_TYPE_CSS(op, ft3, rs, imm) \ + ((op & 0x03) | ((ft3 & 0x07) << 13) | ((rs & 0x1F) << 2) | ((imm) & 0x3F) << 7) + +void asm_rv32_emit_word_opcode(asm_rv32_t *state, mp_uint_t opcode); +void asm_rv32_emit_halfword_opcode(asm_rv32_t *state, mp_uint_t opcode); + +// ADD RD, RS1, RS2 +static inline void asm_rv32_opcode_add(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 000 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x00, 0x00, rd, rs1, rs2)); +} + +// ADDI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_addi(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 000 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x00, rd, rs, immediate)); +} + +// AND RD, RS1, RS2 +static inline void asm_rv32_opcode_and(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 111 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x07, 0x00, rd, rs1, rs2)); +} + +// ANDI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_andi(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 111 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x07, rd, rs, immediate)); +} + +// AUIPC RD, offset +static inline void asm_rv32_opcode_auipc(asm_rv32_t *state, mp_uint_t rd, mp_int_t offset) { + // U: .................... ..... 0010111 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_U(0x17, rd, offset)); +} + +// BEQ RS1, RS2, OFFSET +static inline void asm_rv32_opcode_beq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 000 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x00, rs1, rs2, offset)); +} + +// BGE RS1, RS2, OFFSET +static inline void asm_rv32_opcode_bge(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 101 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x05, rs1, rs2, offset)); +} + +// BGEU RS1, RS2, OFFSET +static inline void asm_rv32_opcode_bgeu(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 111 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x07, rs1, rs2, offset)); +} + +// BLT RS1, RS2, OFFSET +static inline void asm_rv32_opcode_blt(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 100 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x04, rs1, rs2, offset)); +} + +// BLTU RS1, RS2, OFFSET +static inline void asm_rv32_opcode_bltu(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 110 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x06, rs1, rs2, offset)); +} + +// BNE RS1, RS2, OFFSET +static inline void asm_rv32_opcode_bne(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // B: . ...... ..... ..... 001 .... . 1100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_B(0x63, 0x01, rs1, rs2, offset)); +} + +// C.ADD RD, RS +static inline void asm_rv32_opcode_cadd(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CR: 1001 ..... ..... 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CR(0x02, 0x09, rd, rs)); +} + +// C.ADDI RD, IMMEDIATE +static inline void asm_rv32_opcode_caddi(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CI: 000 . ..... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CI(0x01, 0x00, rd, immediate)); +} + +// C.ADDI4SPN RD', IMMEDIATE +static inline void asm_rv32_opcode_caddi4spn(asm_rv32_t *state, mp_uint_t rd, mp_uint_t immediate) { + // CIW: 000 ........ ... 00 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CIW(0x00, 0x00, rd, immediate)); +} + +// C.AND RD', RS' +static inline void asm_rv32_opcode_cand(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 11 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x03, rd, rs)); +} + +// C.ANDI RD', IMMEDIATE +static inline void asm_rv32_opcode_candi(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CB: 100 . 10 ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x04, rd, + (((immediate & 0x20) << 2) | (immediate & 0x1F) | 0x40))); +} + +// C.BEQZ RS', IMMEDIATE +static inline void asm_rv32_opcode_cbeqz(asm_rv32_t *state, mp_uint_t rs, mp_int_t offset) { + // CB: 110 ... ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x06, rs, + (((offset & 0x100) >> 1) | ((offset & 0xC0) >> 3) | ((offset & 0x20) >> 5) | + ((offset & 0x18) << 2) | (offset & 0x06)))); +} + +// C.BNEZ RS', IMMEDIATE +static inline void asm_rv32_opcode_cbnez(asm_rv32_t *state, mp_uint_t rs, mp_int_t offset) { + // CB: 111 ... ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x07, rs, + (((offset & 0x100) >> 1) | ((offset & 0xC0) >> 3) | ((offset & 0x20) >> 5) | + ((offset & 0x18) << 2) | (offset & 0x06)))); +} + +// C.EBREAK +static inline void asm_rv32_opcode_cebreak(asm_rv32_t *state) { + // CA: 100 1 00000 00000 10 + asm_rv32_emit_halfword_opcode(state, 0x9002); +} + +// C.J OFFSET +static inline void asm_rv32_opcode_cj(asm_rv32_t *state, mp_int_t offset) { + // CJ: 101 ........... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CJ(0x01, 0x05, offset)); +} + +// C.JAL OFFSET +static inline void asm_rv32_opcode_cjal(asm_rv32_t *state, mp_int_t offset) { + // CJ: 001 ........... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CJ(0x01, 0x01, offset)); +} + +// C.JALR RS +static inline void asm_rv32_opcode_cjalr(asm_rv32_t *state, mp_uint_t rs) { + // CR: 1001 ..... 00000 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CR(0x02, 0x09, rs, 0)); +} + +// C.JR RS +static inline void asm_rv32_opcode_cjr(asm_rv32_t *state, mp_uint_t rs) { + // CR: 1000 ..... 00000 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CR(0x02, 0x08, rs, 0)); +} + +// C.LI RD, IMMEDIATE +static inline void asm_rv32_opcode_cli(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CI: 010 . ..... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CI(0x01, 0x02, rd, immediate)); +} + +// C.LUI RD, IMMEDIATE +static inline void asm_rv32_opcode_clui(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CI: 011 . ..... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CI(0x01, 0x03, rd, immediate >> 12)); +} + +// C.LW RD', OFFSET(RS') +static inline void asm_rv32_opcode_clw(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // CL: 010 ... ... .. ... 00 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CL(0x00, 0x02, rd, rs, offset)); +} + +// C.LWSP RD, OFFSET +static inline void asm_rv32_opcode_clwsp(asm_rv32_t *state, mp_uint_t rd, mp_uint_t offset) { + // CI: 010 . ..... ..... 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CI(0x02, 0x02, rd, ((offset & 0xC0) >> 6) | (offset & 0x3C))); +} + +// C.MV RD, RS +static inline void asm_rv32_opcode_cmv(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CR: 1000 ..... ..... 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CR(0x02, 0x08, rd, rs)); +} + +// C.NOP +static inline void asm_rv32_opcode_cnop(asm_rv32_t *state) { + // CI: 000 . 00000 ..... 01 + asm_rv32_emit_halfword_opcode(state, 0x0001); +} + +// C.OR RD', RS' +static inline void asm_rv32_opcode_cor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 10 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x02, rd, rs)); +} + +// C.SLLI RD, IMMEDIATE +static inline void asm_rv32_opcode_cslli(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CI: 000 . ..... ..... 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CI(0x02, 0x00, rd, immediate)); +} + +// C.SRAI RD, IMMEDIATE +static inline void asm_rv32_opcode_csrai(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CB: 100 . 01 ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x04, rd, + (((immediate & 0x20) << 2) | (immediate & 0x1F) | 0x20))); +} + +// C.SRLI RD, IMMEDIATE +static inline void asm_rv32_opcode_csrli(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // CB: 100 . 00 ... ..... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CB(0x01, 0x04, rd, + (((immediate & 0x20) << 2) | (immediate & 0x1F)))); +} + +// C.SUB RD', RS' +static inline void asm_rv32_opcode_csub(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 00 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x00, rd, rs)); +} + +// C.SW RS1', OFFSET(RS2') +static inline void asm_rv32_opcode_csw(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_int_t offset) { + // CS: 110 ... ... .. ... 00 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CL(0x00, 0x06, rs1, rs2, offset)); +} + +// C.SWSP RS, OFFSET +static inline void asm_rv32_opcode_cswsp(asm_rv32_t *state, mp_uint_t rs, mp_uint_t offset) { + // CSS: 010 ...... ..... 10 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CSS(0x02, 0x06, rs, ((offset & 0xC0) >> 6) | (offset & 0x3C))); +} + +// C.XOR RD', RS' +static inline void asm_rv32_opcode_cxor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs) { + // CA: 100011 ... 01 ... 01 + asm_rv32_emit_halfword_opcode(state, RV32_ENCODE_TYPE_CA(0x01, 0x23, 0x01, rd, rs)); +} + +// CSRRC RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_csrrc(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 011 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x73, 0x03, rd, rs, immediate)); +} + +// CSRRS RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_csrrs(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 010 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x73, 0x02, rd, rs, immediate)); +} + +// CSRRW RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_csrrw(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 001 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x73, 0x01, rd, rs, immediate)); +} + +// CSRRCI RD, CSR, IMMEDIATE +static inline void asm_rv32_opcode_csrrci(asm_rv32_t *state, mp_uint_t rd, mp_uint_t csr, mp_int_t immediate) { + // CSRI: ............ ..... 111 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_CSRI(0x73, 0x07, rd, csr, immediate)); +} + +// CSRRSI RD, CSR, IMMEDIATE +static inline void asm_rv32_opcode_csrrsi(asm_rv32_t *state, mp_uint_t rd, mp_uint_t csr, mp_int_t immediate) { + // CSRI: ............ ..... 110 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_CSRI(0x73, 0x06, rd, csr, immediate)); +} + +// CSRRWI RD, CSR, IMMEDIATE +static inline void asm_rv32_opcode_csrrwi(asm_rv32_t *state, mp_uint_t rd, mp_uint_t csr, mp_int_t immediate) { + // CSRI: ............ ..... 101 ..... 1110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_CSRI(0x73, 0x05, rd, csr, immediate)); +} + +// DIV RD, RS1, RS2 +static inline void asm_rv32_opcode_div(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 100 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x04, 0x01, rd, rs1, rs2)); +} + +// DIVU RD, RS1, RS2 +static inline void asm_rv32_opcode_divu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 101 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x05, 0x01, rd, rs1, rs2)); +} + +// EBREAK +static inline void asm_rv32_opcode_ebreak(asm_rv32_t *state) { + // I: 000000000001 00000 000 00000 1110011 + asm_rv32_emit_word_opcode(state, 0x100073); +} + +// ECALL +static inline void asm_rv32_opcode_ecall(asm_rv32_t *state) { + // I: 000000000000 00000 000 00000 1110011 + asm_rv32_emit_word_opcode(state, 0x73); +} + +// JAL RD, OFFSET +static inline void asm_rv32_opcode_jal(asm_rv32_t *state, mp_uint_t rd, mp_int_t offset) { + // J: ......................... 1101111 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_J(0x6F, rd, offset)); +} + +// JALR RD, RS, OFFSET +static inline void asm_rv32_opcode_jalr(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 000 ..... 1100111 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x67, 0x00, rd, rs, offset)); +} + +// LB RD, OFFSET(RS) +static inline void asm_rv32_opcode_lb(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 000 ..... 0000011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x00, rd, rs, offset)); +} + +// LBU RD, OFFSET(RS) +static inline void asm_rv32_opcode_lbu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 100 ..... 0000011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x04, rd, rs, offset)); +} + +// LH RD, OFFSET(RS) +static inline void asm_rv32_opcode_lh(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 001 ..... 0000011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x01, rd, rs, offset)); +} + +// LHU RD, OFFSET(RS) +static inline void asm_rv32_opcode_lhu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 101 ..... 0000011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x05, rd, rs, offset)); +} + +// LUI RD, IMMEDIATE +static inline void asm_rv32_opcode_lui(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate) { + // U: .................... ..... 0110111 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_U(0x37, rd, immediate)); +} + +// LW RD, OFFSET(RS) +static inline void asm_rv32_opcode_lw(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t offset) { + // I: ............ ..... 010 ..... 0000011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x03, 0x02, rd, rs, offset)); +} + +// MUL RD, RS1, RS2 +static inline void asm_rv32_opcode_mul(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 000 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x00, 0x01, rd, rs1, rs2)); +} + +// MULH RD, RS1, RS2 +static inline void asm_rv32_opcode_mulh(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 001 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x01, 0x01, rd, rs1, rs2)); +} + +// MULHSU RD, RS1, RS2 +static inline void asm_rv32_opcode_mulhsu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 010 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x02, 0x01, rd, rs1, rs2)); +} + +// MULHU RD, RS1, RS2 +static inline void asm_rv32_opcode_mulhu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 011 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x03, 0x01, rd, rs1, rs2)); +} + +// OR RD, RS1, RS2 +static inline void asm_rv32_opcode_or(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 110 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x06, 0x00, rd, rs1, rs2)); +} + +// ORI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_ori(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 110 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x06, rd, rs, immediate)); +} + +// REM RD, RS1, RS2 +static inline void asm_rv32_opcode_rem(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 110 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x06, 0x01, rd, rs1, rs2)); +} + +// REMU RD, RS1, RS2 +static inline void asm_rv32_opcode_remu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000001 ..... ..... 111 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x07, 0x01, rd, rs1, rs2)); +} + +// SH1ADD RD, RS1, RS2 +static inline void asm_rv32_opcode_sh1add(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0010000 ..... ..... 010 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x02, 0x10, rd, rs1, rs2)); +} + +// SH2ADD RD, RS1, RS2 +static inline void asm_rv32_opcode_sh2add(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0010000 ..... ..... 100 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x04, 0x10, rd, rs1, rs2)); +} + +// SH3ADD RD, RS1, RS2 +static inline void asm_rv32_opcode_sh3add(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0010000 ..... ..... 110 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x06, 0x10, rd, rs1, rs2)); +} + +// SLL RD, RS1, RS2 +static inline void asm_rv32_opcode_sll(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 001 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x01, 0x00, rd, rs1, rs2)); +} + +// SLLI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_slli(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: 0000000..... ..... 001 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x01, rd, rs, immediate & 0x1F)); +} + +// SLT RD, RS1, RS2 +static inline void asm_rv32_opcode_slt(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 010 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x02, 0x00, rd, rs1, rs2)); +} + +// SLTI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_slti(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 010 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x02, rd, rs, immediate)); +} + +// SLTIU RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_sltiu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 011 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x03, rd, rs, immediate)); +} + +// SLTU RD, RS1, RS2 +static inline void asm_rv32_opcode_sltu(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 011 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x03, 0x00, rd, rs1, rs2)); +} + +// SRA RD, RS1, RS2 +static inline void asm_rv32_opcode_sra(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0100000 ..... ..... 101 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x05, 0x20, rd, rs1, rs2)); +} + +// SRAI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_srai(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: 0100000..... ..... 101 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x05, rd, rs, ((immediate & 0x1F) | 0x400))); +} + +// SRL RD, RS1, RS2 +static inline void asm_rv32_opcode_srl(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 101 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x05, 0x00, rd, rs1, rs2)); +} + +// SRLI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_srli(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: 0000000..... ..... 101 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x05, rd, rs, immediate & 0x1F)); +} + +// SUB RD, RS1, RS2 +static inline void asm_rv32_opcode_sub(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0100000 ..... ..... 000 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x00, 0x20, rd, rs1, rs2)); +} + +// SB RS2, OFFSET(RS1) +static inline void asm_rv32_opcode_sb(asm_rv32_t *state, mp_uint_t rs2, mp_uint_t rs1, mp_int_t offset) { + // S: ....... ..... ..... 000 ..... 0100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_S(0x23, 0x00, rs1, rs2, offset)); +} + +// SH RS2, OFFSET(RS1) +static inline void asm_rv32_opcode_sh(asm_rv32_t *state, mp_uint_t rs2, mp_uint_t rs1, mp_int_t offset) { + // S: ....... ..... ..... 001 ..... 0100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_S(0x23, 0x01, rs1, rs2, offset)); +} + +// SW RS2, OFFSET(RS1) +static inline void asm_rv32_opcode_sw(asm_rv32_t *state, mp_uint_t rs2, mp_uint_t rs1, mp_int_t offset) { + // S: ....... ..... ..... 010 ..... 0100011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_S(0x23, 0x02, rs1, rs2, offset)); +} + +// XOR RD, RS1, RS2 +static inline void asm_rv32_opcode_xor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2) { + // R: 0000000 ..... ..... 100 ..... 0110011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_R(0x33, 0x04, 0x00, rd, rs1, rs2)); +} + +// XORI RD, RS, IMMEDIATE +static inline void asm_rv32_opcode_xori(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, mp_int_t immediate) { + // I: ............ ..... 100 ..... 0010011 + asm_rv32_emit_word_opcode(state, RV32_ENCODE_TYPE_I(0x13, 0x04, rd, rs, immediate)); +} + +#define MICROPY_RV32_EXTENSIONS \ + (MICROPY_EMIT_RV32_ZBA ? RV32_EXT_ZBA : 0) + +static inline uint8_t asm_rv32_allowed_extensions(void) { + uint8_t extensions = MICROPY_RV32_EXTENSIONS; + #if MICROPY_DYNAMIC_COMPILER + if (mp_dynamic_compiler.backend_options != NULL) { + extensions |= ((asm_rv32_backend_options_t *)mp_dynamic_compiler.backend_options)->allowed_extensions; + } + #endif + return extensions; +} + +#define ASM_WORD_SIZE (4) +#define ASM_HALFWORD_SIZE (2) + +#define REG_RET ASM_RV32_REG_A0 +#define REG_ARG_1 ASM_RV32_REG_A0 +#define REG_ARG_2 ASM_RV32_REG_A1 +#define REG_ARG_3 ASM_RV32_REG_A2 +#define REG_ARG_4 ASM_RV32_REG_A3 +#define REG_TEMP0 ASM_RV32_REG_T1 +#define REG_TEMP1 ASM_RV32_REG_T2 +#define REG_TEMP2 ASM_RV32_REG_T3 +#define REG_FUN_TABLE ASM_RV32_REG_S1 +#define REG_LOCAL_1 ASM_RV32_REG_S3 +#define REG_LOCAL_2 ASM_RV32_REG_S4 +#define REG_LOCAL_3 ASM_RV32_REG_S5 +#define REG_ZERO ASM_RV32_REG_ZERO + +void asm_rv32_meta_comparison_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd); +void asm_rv32_meta_comparison_ne(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd); +void asm_rv32_meta_comparison_lt(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd, bool unsigned_comparison); +void asm_rv32_meta_comparison_le(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t rd, bool unsigned_comparison); + +void asm_rv32_emit_optimised_load_immediate(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate); +void asm_rv32_emit_load_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t operation_size); +void asm_rv32_emit_store_reg_reg_reg(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t operation_size); + +#ifdef GENERIC_ASM_API + +void asm_rv32_emit_call_ind(asm_rv32_t *state, mp_uint_t index); +void asm_rv32_emit_jump(asm_rv32_t *state, mp_uint_t label); +void asm_rv32_emit_jump_if_reg_eq(asm_rv32_t *state, mp_uint_t rs1, mp_uint_t rs2, mp_uint_t label); +void asm_rv32_emit_jump_if_reg_nonzero(asm_rv32_t *state, mp_uint_t rs, mp_uint_t label); +void asm_rv32_emit_load_reg_reg_offset(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs, int32_t offset, mp_uint_t operation_size); +void asm_rv32_emit_mov_local_reg(asm_rv32_t *state, mp_uint_t local, mp_uint_t rs); +void asm_rv32_emit_mov_reg_local_addr(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local); +void asm_rv32_emit_mov_reg_local(asm_rv32_t *state, mp_uint_t rd, mp_uint_t local); +void asm_rv32_emit_mov_reg_pcrel(asm_rv32_t *state, mp_uint_t rd, mp_uint_t label); +void asm_rv32_emit_optimised_xor(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs); +void asm_rv32_emit_store_reg_reg_offset(asm_rv32_t *state, mp_uint_t source, mp_uint_t base, int32_t offset, mp_uint_t operation_size); + +#define ASM_T asm_rv32_t +#define ASM_ENTRY(state, labels, name) asm_rv32_entry(state, labels) +#define ASM_EXIT(state) asm_rv32_exit(state) +#define ASM_END_PASS(state) asm_rv32_end_pass(state) + +#define ASM_ADD_REG_REG(state, rd, rs) asm_rv32_opcode_cadd(state, rd, rs) +#define ASM_AND_REG_REG(state, rd, rs) asm_rv32_opcode_and(state, rd, rs, rd) +#define ASM_ASR_REG_REG(state, rd, rs) asm_rv32_opcode_sra(state, rd, rd, rs) +#define ASM_CALL_IND(state, index) asm_rv32_emit_call_ind(state, index) +#define ASM_JUMP(state, label) asm_rv32_emit_jump(state, label) +#define ASM_JUMP_IF_REG_EQ(state, rs1, rs2, label) asm_rv32_emit_jump_if_reg_eq(state, rs1, rs2, label) +#define ASM_JUMP_IF_REG_NONZERO(state, rs, label, bool_test) asm_rv32_emit_jump_if_reg_nonzero(state, rs, label) +#define ASM_JUMP_IF_REG_ZERO(state, rs, label, bool_test) asm_rv32_emit_jump_if_reg_eq(state, rs, ASM_RV32_REG_ZERO, label) +#define ASM_JUMP_REG(state, rs) asm_rv32_opcode_cjr(state, rs) +#define ASM_LOAD_REG_REG_OFFSET(state, rd, rs, offset) ASM_LOAD32_REG_REG_OFFSET(state, rd, rs, offset) +#define ASM_LOAD8_REG_REG(state, rd, rs) ASM_LOAD8_REG_REG_OFFSET(state, rd, rs, 0) +#define ASM_LOAD16_REG_REG(state, rd, rs) ASM_LOAD16_REG_REG_OFFSET(state, rd, rs, 0) +#define ASM_LOAD32_REG_REG(state, rd, rs) ASM_LOAD32_REG_REG_OFFSET(state, rd, rs, 0) +#define ASM_LOAD8_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_load_reg_reg_offset(state, rd, rs, offset, 0) +#define ASM_LOAD16_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_load_reg_reg_offset(state, rd, rs, offset, 1) +#define ASM_LOAD32_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_load_reg_reg_offset(state, rd, rs, offset, 2) +#define ASM_LSL_REG_REG(state, rd, rs) asm_rv32_opcode_sll(state, rd, rd, rs) +#define ASM_LSR_REG_REG(state, rd, rs) asm_rv32_opcode_srl(state, rd, rd, rs) +#define ASM_MOV_LOCAL_REG(state, local, rs) asm_rv32_emit_mov_local_reg(state, local, rs) +#define ASM_MOV_REG_IMM(state, rd, imm) asm_rv32_emit_optimised_load_immediate(state, rd, imm) +#define ASM_MOV_REG_LOCAL_ADDR(state, rd, local) asm_rv32_emit_mov_reg_local_addr(state, rd, local) +#define ASM_MOV_REG_LOCAL(state, rd, local) asm_rv32_emit_mov_reg_local(state, rd, local) +#define ASM_MOV_REG_PCREL(state, rd, label) asm_rv32_emit_mov_reg_pcrel(state, rd, label) +#define ASM_MOV_REG_REG(state, rd, rs) asm_rv32_opcode_cmv(state, rd, rs) +#define ASM_MUL_REG_REG(state, rd, rs) asm_rv32_opcode_mul(state, rd, rd, rs) +#define ASM_NEG_REG(state, rd) asm_rv32_opcode_sub(state, rd, ASM_RV32_REG_ZERO, rd) +#define ASM_NOT_REG(state, rd) asm_rv32_opcode_xori(state, rd, rd, -1) +#define ASM_OR_REG_REG(state, rd, rs) asm_rv32_opcode_or(state, rd, rd, rs) +#define ASM_STORE_REG_REG_OFFSET(state, rd, rs, offset) ASM_STORE32_REG_REG_OFFSET(state, rd, rs, offset) +#define ASM_STORE8_REG_REG(state, rs1, rs2) ASM_STORE8_REG_REG_OFFSET(state, rs1, rs2, 0) +#define ASM_STORE16_REG_REG(state, rs1, rs2) ASM_STORE16_REG_REG_OFFSET(state, rs1, rs2, 0) +#define ASM_STORE32_REG_REG(state, rs1, rs2) ASM_STORE32_REG_REG_OFFSET(state, rs1, rs2, 0) +#define ASM_STORE8_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_store_reg_reg_offset(state, rd, rs, offset, 0) +#define ASM_STORE16_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_store_reg_reg_offset(state, rd, rs, offset, 1) +#define ASM_STORE32_REG_REG_OFFSET(state, rd, rs, offset) asm_rv32_emit_store_reg_reg_offset(state, rd, rs, offset, 2) +#define ASM_SUB_REG_REG(state, rd, rs) asm_rv32_opcode_sub(state, rd, rd, rs) +#define ASM_XOR_REG_REG(state, rd, rs) asm_rv32_emit_optimised_xor(state, rd, rs) +#define ASM_CLR_REG(state, rd) +#define ASM_LOAD8_REG_REG_REG(state, rd, rs1, rs2) asm_rv32_emit_load_reg_reg_reg(state, rd, rs1, rs2, 0) +#define ASM_LOAD16_REG_REG_REG(state, rd, rs1, rs2) asm_rv32_emit_load_reg_reg_reg(state, rd, rs1, rs2, 1) +#define ASM_LOAD32_REG_REG_REG(state, rd, rs1, rs2) asm_rv32_emit_load_reg_reg_reg(state, rd, rs1, rs2, 2) +#define ASM_STORE8_REG_REG_REG(state, rd, rs1, rs2) asm_rv32_emit_store_reg_reg_reg(state, rd, rs1, rs2, 0) +#define ASM_STORE16_REG_REG_REG(state, rd, rs1, rs2) asm_rv32_emit_store_reg_reg_reg(state, rd, rs1, rs2, 1) +#define ASM_STORE32_REG_REG_REG(state, rd, rs1, rs2) asm_rv32_emit_store_reg_reg_reg(state, rd, rs1, rs2, 2) + +#endif + +#endif // MICROPY_INCLUDED_PY_ASMRV32_H diff --git a/py/asmthumb.c b/py/asmthumb.c index 0df79e5fd62..58cc7aea880 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -35,25 +35,8 @@ #include "py/mpstate.h" #include "py/asmthumb.h" +#include "py/misc.h" -#ifdef _MSC_VER -#include - -static uint32_t mp_clz(uint32_t x) { - unsigned long lz = 0; - return _BitScanReverse(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; -} - -static uint32_t mp_ctz(uint32_t x) { - unsigned long tz = 0; - return _BitScanForward(&tz, x) ? tz : 0; -} -#else -#define mp_clz(x) __builtin_clz(x) -#define mp_ctz(x) __builtin_ctz(x) -#endif - -#define UNSIGNED_FIT5(x) ((uint32_t)(x) < 32) #define UNSIGNED_FIT7(x) ((uint32_t)(x) < 128) #define UNSIGNED_FIT8(x) (((x) & 0xffffff00) == 0) #define UNSIGNED_FIT16(x) (((x) & 0xffff0000) == 0) @@ -68,12 +51,6 @@ static uint32_t mp_ctz(uint32_t x) { #define OP_SUB_W_RRI_HI(reg_src) (0xf2a0 | (reg_src)) #define OP_SUB_W_RRI_LO(reg_dest, imm11) ((imm11 << 4 & 0x7000) | reg_dest << 8 | (imm11 & 0xff)) -#define OP_LDR_W_HI(reg_base) (0xf8d0 | (reg_base)) -#define OP_LDR_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12)) - -#define OP_LDRH_W_HI(reg_base) (0xf8b0 | (reg_base)) -#define OP_LDRH_W_LO(reg_dest, imm12) ((reg_dest) << 12 | (imm12)) - static inline byte *asm_thumb_get_cur_to_write_bytes(asm_thumb_t *as, int n) { return mp_asm_base_get_cur_to_write_bytes(&as->base, n); } @@ -290,9 +267,8 @@ bool asm_thumb_b_n_label(asm_thumb_t *as, uint label) { #define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff)) -// all these bit-arithmetic operations need coverage testing! -#define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 14) & 0x003f)) -#define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff)) +#define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 12) & 0x003f)) +#define OP_BCC_W_LO(byte_offset) (0x8000 | (((byte_offset) >> 5) & 0x2000) | (((byte_offset) >> 8) & 0x0800) | (((byte_offset) >> 1) & 0x07ff)) bool asm_thumb_bcc_nw_label(asm_thumb_t *as, int cond, uint label, bool wide) { mp_uint_t dest = get_label_dest(as, label); @@ -448,11 +424,6 @@ void asm_thumb_mov_reg_pcrel(asm_thumb_t *as, uint rlo_dest, uint label) { asm_thumb_add_reg_reg(as, rlo_dest, ASM_THUMB_REG_R15); // 2 bytes } -// ARMv7-M only -static inline void asm_thumb_ldr_reg_reg_i12(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) { - asm_thumb_op32(as, OP_LDR_W_HI(reg_base), OP_LDR_W_LO(reg_dest, word_offset * 4)); -} - // emits code for: reg_dest = reg_base + offset << offset_shift static void asm_thumb_add_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint reg_base, uint offset, uint offset_shift) { if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8) { @@ -466,12 +437,12 @@ static void asm_thumb_add_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint re asm_thumb_lsl_rlo_rlo_i5(as, reg_dest, reg_dest, offset_shift); asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_base); } else if (reg_dest != reg_base) { - asm_thumb_mov_rlo_i16(as, reg_dest, offset << offset_shift); - asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_dest); + asm_thumb_mov_reg_i32_optimised(as, reg_dest, offset << offset_shift); + asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_base); } else { uint reg_other = reg_dest ^ 7; asm_thumb_op16(as, OP_PUSH_RLIST((1 << reg_other))); - asm_thumb_mov_rlo_i16(as, reg_other, offset << offset_shift); + asm_thumb_mov_reg_i32_optimised(as, reg_other, offset << offset_shift); asm_thumb_add_rlo_rlo_rlo(as, reg_dest, reg_dest, reg_other); asm_thumb_op16(as, OP_POP_RLIST((1 << reg_other))); } @@ -480,30 +451,50 @@ static void asm_thumb_add_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint re } } -void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset) { - if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8 && UNSIGNED_FIT5(word_offset)) { - asm_thumb_ldr_rlo_rlo_i5(as, reg_dest, reg_base, word_offset); - } else if (asm_thumb_allow_armv7m(as)) { - asm_thumb_ldr_reg_reg_i12(as, reg_dest, reg_base, word_offset); +#define OP_LDR_STR_W_HI(operation_size, reg) ((0xf880 | (operation_size) << 5) | (reg)) +#define OP_LDR_STR_W_LO(reg, imm12) (((reg) << 12) | (imm12)) + +#define OP_LDR 0x01 +#define OP_STR 0x00 + +#define OP_LDR_W 0x10 +#define OP_STR_W 0x00 + +static const uint8_t OP_LDR_STR_TABLE[3] = { + 0x0E, 0x10, 0x0C +}; + +void asm_thumb_load_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint reg_base, uint offset, uint operation_size) { + assert(operation_size <= 2 && "Operation size out of range."); + + if (MP_FIT_UNSIGNED(5, offset) && (reg_dest < ASM_THUMB_REG_R8) && (reg_base < ASM_THUMB_REG_R8)) { + // Can use T1 encoding + asm_thumb_op16(as, ((OP_LDR_STR_TABLE[operation_size] | OP_LDR) << 11) | (offset << 6) | (reg_base << 3) | reg_dest); + } else if (asm_thumb_allow_armv7m(as) && MP_FIT_UNSIGNED(12, offset << operation_size)) { + // Can use T3 encoding + asm_thumb_op32(as, (OP_LDR_STR_W_HI(operation_size, reg_base) | OP_LDR_W), OP_LDR_STR_W_LO(reg_dest, (offset << operation_size))); } else { - asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, word_offset - 31, 2); - asm_thumb_ldr_rlo_rlo_i5(as, reg_dest, reg_dest, 31); + // Must use the generic sequence + asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, offset - 31, operation_size); + asm_thumb_op16(as, ((OP_LDR_STR_TABLE[operation_size] | OP_LDR) << 11) | (31 << 6) | (reg_dest << 3) | (reg_dest)); } } -// ARMv7-M only -static inline void asm_thumb_ldrh_reg_reg_i12(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset) { - asm_thumb_op32(as, OP_LDRH_W_HI(reg_base), OP_LDRH_W_LO(reg_dest, uint16_offset * 2)); -} +void asm_thumb_store_reg_reg_offset(asm_thumb_t *as, uint reg_src, uint reg_base, uint offset, uint operation_size) { + assert(operation_size <= 2 && "Operation size out of range."); -void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset) { - if (reg_dest < ASM_THUMB_REG_R8 && reg_base < ASM_THUMB_REG_R8 && UNSIGNED_FIT5(uint16_offset)) { - asm_thumb_ldrh_rlo_rlo_i5(as, reg_dest, reg_base, uint16_offset); - } else if (asm_thumb_allow_armv7m(as)) { - asm_thumb_ldrh_reg_reg_i12(as, reg_dest, reg_base, uint16_offset); + if (MP_FIT_UNSIGNED(5, offset) && (reg_src < ASM_THUMB_REG_R8) && (reg_base < ASM_THUMB_REG_R8)) { + // Can use T1 encoding + asm_thumb_op16(as, ((OP_LDR_STR_TABLE[operation_size] | OP_STR) << 11) | (offset << 6) | (reg_base << 3) | reg_src); + } else if (asm_thumb_allow_armv7m(as) && MP_FIT_UNSIGNED(12, offset << operation_size)) { + // Can use T3 encoding + asm_thumb_op32(as, (OP_LDR_STR_W_HI(operation_size, reg_base) | OP_STR_W), OP_LDR_STR_W_LO(reg_src, (offset << operation_size))); } else { - asm_thumb_add_reg_reg_offset(as, reg_dest, reg_base, uint16_offset - 31, 1); - asm_thumb_ldrh_rlo_rlo_i5(as, reg_dest, reg_dest, 31); + // Must use the generic sequence + asm_thumb_op16(as, OP_PUSH_RLIST(1 << reg_base)); + asm_thumb_add_reg_reg_offset(as, reg_base, reg_base, offset - 31, operation_size); + asm_thumb_op16(as, ((OP_LDR_STR_TABLE[operation_size] | OP_STR) << 11) | (31 << 6) | (reg_base << 3) | reg_src); + asm_thumb_op16(as, OP_POP_RLIST(1 << reg_base)); } } @@ -511,6 +502,7 @@ void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint r #define OP_BW_HI(byte_offset) (0xf000 | (((byte_offset) >> 12) & 0x07ff)) #define OP_BW_LO(byte_offset) (0xb800 | (((byte_offset) >> 1) & 0x07ff)) +// In Thumb1 mode, this may clobber r1. void asm_thumb_b_label(asm_thumb_t *as, uint label) { mp_uint_t dest = get_label_dest(as, label); mp_int_t rel = dest - as->base.code_offset; @@ -530,19 +522,40 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) { if (asm_thumb_allow_armv7m(as)) { asm_thumb_op32(as, OP_BW_HI(rel), OP_BW_LO(rel)); } else { + // this code path has to be the same instruction size irrespective of the value of rel + bool need_align = as->base.code_offset & 2u; if (SIGNED_FIT12(rel)) { - // this code path has to be the same number of instructions irrespective of rel asm_thumb_op16(as, OP_B_N(rel)); - } else { asm_thumb_op16(as, ASM_THUMB_OP_NOP); - if (dest != (mp_uint_t)-1) { - // we have an actual branch > 12 bits; this is not handled yet - mp_raise_NotImplementedError(MP_ERROR_TEXT("native method too big")); + asm_thumb_op16(as, ASM_THUMB_OP_NOP); + asm_thumb_op16(as, ASM_THUMB_OP_NOP); + if (need_align) { + asm_thumb_op16(as, ASM_THUMB_OP_NOP); } + } else { + // do a large jump using: + // (nop) + // ldr r1, [pc, _data] + // add pc, r1 + // _data: .word rel + // + // note: can't use r0 as a temporary because native code can have the return value + // in that register and use a large jump to get to the exit point of the function + + rel -= 2; // account for the "ldr r1, [pc, _data]" + if (need_align) { + asm_thumb_op16(as, ASM_THUMB_OP_NOP); + rel -= 2; // account for this nop + } + asm_thumb_ldr_rlo_pcrel_i8(as, ASM_THUMB_REG_R1, 0); + asm_thumb_add_reg_reg(as, ASM_THUMB_REG_R15, ASM_THUMB_REG_R1); + asm_thumb_op16(as, rel & 0xffff); + asm_thumb_op16(as, rel >> 16); } } } +// In Thumb1 mode, this may clobber r1. void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { mp_uint_t dest = get_label_dest(as, label); mp_int_t rel = dest - as->base.code_offset; @@ -563,8 +576,15 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { asm_thumb_op32(as, OP_BCC_W_HI(cond, rel), OP_BCC_W_LO(rel)); } else { // reverse the sense of the branch to jump over a longer branch - asm_thumb_op16(as, OP_BCC_N(cond ^ 1, 0)); + size_t code_offset_start = as->base.code_offset; + byte *c = asm_thumb_get_cur_to_write_bytes(as, 2); asm_thumb_b_label(as, label); + size_t bytes_to_skip = as->base.code_offset - code_offset_start; + uint16_t op = OP_BCC_N(cond ^ 1, bytes_to_skip - 4); + if (c != NULL) { + c[0] = op; + c[1] = op >> 8; + } } } @@ -585,7 +605,7 @@ void asm_thumb_b_rel12(asm_thumb_t *as, int rel) { void asm_thumb_bl_ind(asm_thumb_t *as, uint fun_id, uint reg_temp) { // Load ptr to function from table, indexed by fun_id, then call it - asm_thumb_ldr_reg_reg_i12_optimised(as, reg_temp, ASM_THUMB_REG_FUN_TABLE, fun_id); + asm_thumb_load_reg_reg_offset(as, reg_temp, ASM_THUMB_REG_FUN_TABLE, fun_id, 2); asm_thumb_op16(as, OP_BLX(reg_temp)); } diff --git a/py/asmthumb.h b/py/asmthumb.h index 0584ed3227a..cb786694f0b 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -251,6 +251,50 @@ static inline void asm_thumb_bx_reg(asm_thumb_t *as, uint r_src) { asm_thumb_format_5(as, ASM_THUMB_FORMAT_5_BX, 0, r_src); } +// FORMAT 7: load/store with register offset +// FORMAT 8: load/store sign-extended byte/halfword + +#define ASM_THUMB_FORMAT_7_LDR (0x5800) +#define ASM_THUMB_FORMAT_7_STR (0x5000) +#define ASM_THUMB_FORMAT_7_WORD_TRANSFER (0x0000) +#define ASM_THUMB_FORMAT_7_BYTE_TRANSFER (0x0400) +#define ASM_THUMB_FORMAT_8_LDRH (0x5A00) +#define ASM_THUMB_FORMAT_8_STRH (0x5200) + +#define ASM_THUMB_FORMAT_7_8_ENCODE(op, rlo_dest, rlo_base, rlo_index) \ + ((op) | ((rlo_index) << 6) | ((rlo_base) << 3) | ((rlo_dest))) + +static inline void asm_thumb_format_7_8(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint rlo_index) { + assert(rlo_dest < ASM_THUMB_REG_R8); + assert(rlo_base < ASM_THUMB_REG_R8); + assert(rlo_index < ASM_THUMB_REG_R8); + asm_thumb_op16(as, ASM_THUMB_FORMAT_7_8_ENCODE(op, rlo_dest, rlo_base, rlo_index)); +} + +static inline void asm_thumb_ldrb_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint rlo_index) { + asm_thumb_format_7_8(as, ASM_THUMB_FORMAT_7_LDR | ASM_THUMB_FORMAT_7_BYTE_TRANSFER, rlo_dest, rlo_base, rlo_index); +} + +static inline void asm_thumb_ldrh_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint rlo_index) { + asm_thumb_format_7_8(as, ASM_THUMB_FORMAT_8_LDRH, rlo_dest, rlo_base, rlo_index); +} + +static inline void asm_thumb_ldr_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint rlo_index) { + asm_thumb_format_7_8(as, ASM_THUMB_FORMAT_7_LDR | ASM_THUMB_FORMAT_7_WORD_TRANSFER, rlo_dest, rlo_base, rlo_index); +} + +static inline void asm_thumb_strb_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint rlo_index) { + asm_thumb_format_7_8(as, ASM_THUMB_FORMAT_7_STR | ASM_THUMB_FORMAT_7_BYTE_TRANSFER, rlo_src, rlo_base, rlo_index); +} + +static inline void asm_thumb_strh_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint rlo_index) { + asm_thumb_format_7_8(as, ASM_THUMB_FORMAT_8_STRH, rlo_dest, rlo_base, rlo_index); +} + +static inline void asm_thumb_str_rlo_rlo_rlo(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint rlo_index) { + asm_thumb_format_7_8(as, ASM_THUMB_FORMAT_7_STR | ASM_THUMB_FORMAT_7_WORD_TRANSFER, rlo_src, rlo_base, rlo_index); +} + // FORMAT 9: load/store with immediate offset // For word transfers the offset must be aligned, and >>2 @@ -273,24 +317,6 @@ static inline void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest asm_thumb_op16(as, ASM_THUMB_FORMAT_9_10_ENCODE(op, rlo_dest, rlo_base, offset)); } -static inline void asm_thumb_str_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint word_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_src, rlo_base, word_offset); -} -static inline void asm_thumb_strb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint byte_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_STR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER, rlo_src, rlo_base, byte_offset); -} -static inline void asm_thumb_strh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_src, uint rlo_base, uint uint16_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_STRH, rlo_src, rlo_base, uint16_offset); -} -static inline void asm_thumb_ldr_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint word_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, rlo_dest, rlo_base, word_offset); -} -static inline void asm_thumb_ldrb_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint byte_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_BYTE_TRANSFER, rlo_dest, rlo_base, byte_offset); -} -static inline void asm_thumb_ldrh_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_base, uint uint16_offset) { - asm_thumb_format_9_10(as, ASM_THUMB_FORMAT_10_LDRH, rlo_dest, rlo_base, uint16_offset); -} static inline void asm_thumb_lsl_rlo_rlo_i5(asm_thumb_t *as, uint rlo_dest, uint rlo_src, uint shift) { asm_thumb_format_1(as, ASM_THUMB_FORMAT_1_LSL, rlo_dest, rlo_src, shift); } @@ -338,8 +364,10 @@ void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num); // void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num); // convenience void asm_thumb_mov_reg_pcrel(asm_thumb_t *as, uint rlo_dest, uint label); -void asm_thumb_ldr_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint word_offset); // convenience -void asm_thumb_ldrh_reg_reg_i12_optimised(asm_thumb_t *as, uint reg_dest, uint reg_base, uint uint16_offset); // convenience +// Generate optimised load dest, [src, #offset] sequence +void asm_thumb_load_reg_reg_offset(asm_thumb_t *as, uint reg_dest, uint reg_base, uint offset, uint operation_size); +// Generate optimised store src, [dest, #offset] sequence +void asm_thumb_store_reg_reg_offset(asm_thumb_t *as, uint reg_src, uint reg_base, uint offset, uint operation_size); void asm_thumb_b_label(asm_thumb_t *as, uint label); // convenience: picks narrow or wide branch void asm_thumb_bcc_label(asm_thumb_t *as, int cc, uint label); // convenience: picks narrow or wide branch @@ -376,12 +404,12 @@ void asm_thumb_b_rel12(asm_thumb_t *as, int rel); #define REG_FUN_TABLE ASM_THUMB_REG_FUN_TABLE -#define ASM_T asm_thumb_t -#define ASM_END_PASS asm_thumb_end_pass -#define ASM_ENTRY asm_thumb_entry -#define ASM_EXIT asm_thumb_exit +#define ASM_T asm_thumb_t +#define ASM_END_PASS asm_thumb_end_pass +#define ASM_ENTRY(as, num_locals, name) asm_thumb_entry((as), (num_locals)) +#define ASM_EXIT asm_thumb_exit -#define ASM_JUMP asm_thumb_b_label +#define ASM_JUMP asm_thumb_b_label #define ASM_JUMP_IF_REG_ZERO(as, reg, label, bool_test) \ do { \ asm_thumb_cmp_rlo_i8(as, reg, 0); \ @@ -419,18 +447,44 @@ void asm_thumb_b_rel12(asm_thumb_t *as, int rel); #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_thumb_sub_rlo_rlo_rlo((as), (reg_dest), (reg_dest), (reg_src)) #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_thumb_format_4((as), ASM_THUMB_FORMAT_4_MUL, (reg_dest), (reg_src)) -#define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) -#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_thumb_ldr_reg_reg_i12_optimised((as), (reg_dest), (reg_base), (word_offset)) -#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrb_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) -#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_thumb_ldrh_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) -#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_thumb_ldrh_reg_reg_i12_optimised((as), (reg_dest), (reg_base), (uint16_offset)) -#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_thumb_ldr_rlo_rlo_i5((as), (reg_dest), (reg_base), 0) - -#define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0) -#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), (word_offset)) -#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_thumb_strb_rlo_rlo_i5((as), (reg_src), (reg_base), 0) -#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_thumb_strh_rlo_rlo_i5((as), (reg_src), (reg_base), 0) -#define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_thumb_str_rlo_rlo_i5((as), (reg_src), (reg_base), 0) +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset)) +#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) ASM_LOAD8_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD8_REG_REG_OFFSET(as, reg_dest, reg_base, byte_offset) asm_thumb_load_reg_reg_offset((as), (reg_dest), (reg_base), (byte_offset), 0) +#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) ASM_LOAD16_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, halfword_offset) asm_thumb_load_reg_reg_offset((as), (reg_dest), (reg_base), (halfword_offset), 1) +#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_thumb_load_reg_reg_offset((as), (reg_dest), (reg_base), (word_offset), 2) + +#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) ASM_STORE32_REG_REG_OFFSET((as), (reg_src), (reg_base), (word_offset)) +#define ASM_STORE8_REG_REG(as, reg_src, reg_base) ASM_STORE8_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE8_REG_REG_OFFSET(as, reg_src, reg_base, byte_offset) asm_thumb_store_reg_reg_offset((as), (reg_src), (reg_base), (byte_offset), 0) +#define ASM_STORE16_REG_REG(as, reg_src, reg_base) ASM_STORE16_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE16_REG_REG_OFFSET(as, reg_src, reg_base, halfword_offset) asm_thumb_store_reg_reg_offset((as), (reg_src), (reg_base), (halfword_offset), 1) +#define ASM_STORE32_REG_REG(as, reg_src, reg_base) ASM_STORE32_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE32_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_thumb_store_reg_reg_offset((as), (reg_src), (reg_base), (word_offset), 2) + +#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) asm_thumb_ldrb_rlo_rlo_rlo((as), (reg_dest), (reg_base), (reg_index)) +#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) \ + do { \ + asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 1); \ + asm_thumb_ldrh_rlo_rlo_rlo((as), (reg_dest), (reg_base), (reg_index)); \ + } while (0) +#define ASM_LOAD32_REG_REG_REG(as, reg_dest, reg_base, reg_index) \ + do { \ + asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 2); \ + asm_thumb_ldr_rlo_rlo_rlo((as), (reg_dest), (reg_base), (reg_index)); \ + } while (0) +#define ASM_STORE8_REG_REG_REG(as, reg_val, reg_base, reg_index) asm_thumb_strb_rlo_rlo_rlo((as), (reg_val), (reg_base), (reg_index)) +#define ASM_STORE16_REG_REG_REG(as, reg_val, reg_base, reg_index) \ + do { \ + asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 1); \ + asm_thumb_strh_rlo_rlo_rlo((as), (reg_val), (reg_base), (reg_index)); \ + } while (0) +#define ASM_STORE32_REG_REG_REG(as, reg_val, reg_base, reg_index) \ + do { \ + asm_thumb_lsl_rlo_rlo_i5((as), (reg_index), (reg_index), 2); \ + asm_thumb_str_rlo_rlo_rlo((as), (reg_val), (reg_base), (reg_index)); \ + } while (0) #endif // GENERIC_ASM_API diff --git a/py/asmx64.h b/py/asmx64.h index 03070b5f63d..1e8cb0c905f 100644 --- a/py/asmx64.h +++ b/py/asmx64.h @@ -155,12 +155,12 @@ void asm_x64_call_ind(asm_x64_t *as, size_t fun_id, int temp_r32); // Holds a pointer to mp_fun_table #define REG_FUN_TABLE ASM_X64_REG_FUN_TABLE -#define ASM_T asm_x64_t -#define ASM_END_PASS asm_x64_end_pass -#define ASM_ENTRY asm_x64_entry -#define ASM_EXIT asm_x64_exit +#define ASM_T asm_x64_t +#define ASM_END_PASS asm_x64_end_pass +#define ASM_ENTRY(as, num_locals, name) asm_x64_entry((as), (num_locals)) +#define ASM_EXIT asm_x64_exit -#define ASM_JUMP asm_x64_jmp_label +#define ASM_JUMP asm_x64_jmp_label #define ASM_JUMP_IF_REG_ZERO(as, reg, label, bool_test) \ do { \ if (bool_test) { \ @@ -206,18 +206,21 @@ void asm_x64_call_ind(asm_x64_t *as, size_t fun_id, int temp_r32); #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x64_sub_r64_r64((as), (reg_dest), (reg_src)) #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_x64_mul_r64_r64((as), (reg_dest), (reg_src)) -#define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem64_to_r64((as), (reg_base), 0, (reg_dest)) -#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x64_mov_mem64_to_r64((as), (reg_base), 8 * (word_offset), (reg_dest)) -#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem8_to_r64zx((as), (reg_base), 0, (reg_dest)) -#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 0, (reg_dest)) -#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 2 * (uint16_offset), (reg_dest)) -#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_x64_mov_mem32_to_r64zx((as), (reg_base), 0, (reg_dest)) - -#define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 0) -#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 8 * (word_offset)) -#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_x64_mov_r8_to_mem8((as), (reg_src), (reg_base), 0) -#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_x64_mov_r16_to_mem16((as), (reg_src), (reg_base), 0) -#define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_x64_mov_r32_to_mem32((as), (reg_src), (reg_base), 0) +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, qword_offset) asm_x64_mov_mem64_to_r64((as), (reg_base), 8 * (qword_offset), (reg_dest)) +#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) ASM_LOAD8_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD8_REG_REG_OFFSET(as, reg_dest, reg_base, byte_offset) asm_x64_mov_mem8_to_r64zx((as), (reg_base), (byte_offset), (reg_dest)) +#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) ASM_LOAD16_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x64_mov_mem16_to_r64zx((as), (reg_base), 2 * (word_offset), (reg_dest)) +#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, dword_offset) asm_x64_mov_mem32_to_r64zx((as), (reg_base), 4 * (dword_offset), (reg_dest)) + +#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, qword_offset) asm_x64_mov_r64_to_mem64((as), (reg_src), (reg_base), 8 * (qword_offset)) +#define ASM_STORE8_REG_REG(as, reg_src, reg_base) ASM_STORE8_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE8_REG_REG_OFFSET(as, reg_src, reg_base, byte_offset) asm_x64_mov_r8_to_mem8((as), (reg_src), (reg_base), (byte_offset)) +#define ASM_STORE16_REG_REG(as, reg_src, reg_base) ASM_STORE16_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE16_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x64_mov_r16_to_mem16((as), (reg_src), (reg_base), 2 * (word_offset)) +#define ASM_STORE32_REG_REG(as, reg_src, reg_base) ASM_STORE32_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE32_REG_REG_OFFSET(as, reg_src, reg_base, dword_offset) asm_x64_mov_r32_to_mem32((as), (reg_src), (reg_base), 4 * (dword_offset)) #endif // GENERIC_ASM_API diff --git a/py/asmx86.h b/py/asmx86.h index 7796d697626..f5d37228a2f 100644 --- a/py/asmx86.h +++ b/py/asmx86.h @@ -150,12 +150,12 @@ void asm_x86_call_ind(asm_x86_t *as, size_t fun_id, mp_uint_t n_args, int temp_r // Holds a pointer to mp_fun_table #define REG_FUN_TABLE ASM_X86_REG_FUN_TABLE -#define ASM_T asm_x86_t -#define ASM_END_PASS asm_x86_end_pass -#define ASM_ENTRY asm_x86_entry -#define ASM_EXIT asm_x86_exit +#define ASM_T asm_x86_t +#define ASM_END_PASS asm_x86_end_pass +#define ASM_ENTRY(as, num_locals, name) asm_x86_entry((as), (num_locals)) +#define ASM_EXIT asm_x86_exit -#define ASM_JUMP asm_x86_jmp_label +#define ASM_JUMP asm_x86_jmp_label #define ASM_JUMP_IF_REG_ZERO(as, reg, label, bool_test) \ do { \ if (bool_test) { \ @@ -201,18 +201,21 @@ void asm_x86_call_ind(asm_x86_t *as, size_t fun_id, mp_uint_t n_args, int temp_r #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_x86_sub_r32_r32((as), (reg_dest), (reg_src)) #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_x86_mul_r32_r32((as), (reg_dest), (reg_src)) -#define ASM_LOAD_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem32_to_r32((as), (reg_base), 0, (reg_dest)) -#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x86_mov_mem32_to_r32((as), (reg_base), 4 * (word_offset), (reg_dest)) -#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem8_to_r32zx((as), (reg_base), 0, (reg_dest)) -#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem16_to_r32zx((as), (reg_base), 0, (reg_dest)) -#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_x86_mov_mem16_to_r32zx((as), (reg_base), 2 * (uint16_offset), (reg_dest)) -#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_x86_mov_mem32_to_r32((as), (reg_base), 0, (reg_dest)) - -#define ASM_STORE_REG_REG(as, reg_src, reg_base) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 0) -#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 4 * (word_offset)) -#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_x86_mov_r8_to_mem8((as), (reg_src), (reg_base), 0) -#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_x86_mov_r16_to_mem16((as), (reg_src), (reg_base), 0) -#define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 0) +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, dword_offset) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (dword_offset)) +#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) ASM_LOAD8_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD8_REG_REG_OFFSET(as, reg_dest, reg_base, byte_offset) asm_x86_mov_mem8_to_r32zx((as), (reg_base), (byte_offset), (reg_dest)) +#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) ASM_LOAD16_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_x86_mov_mem16_to_r32zx((as), (reg_base), 2 * (word_offset), (reg_dest)) +#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, dword_offset) asm_x86_mov_mem32_to_r32((as), (reg_base), 4 * (dword_offset), (reg_dest)) + +#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, dword_offset) ASM_STORE32_REG_REG_OFFSET((as), (reg_src), (reg_base), (dword_offset)) +#define ASM_STORE8_REG_REG(as, reg_src, reg_base) ASM_STORE8_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE8_REG_REG_OFFSET(as, reg_src, reg_base, byte_offset) asm_x86_mov_r8_to_mem8((as), (reg_src), (reg_base), (byte_offset)) +#define ASM_STORE16_REG_REG(as, reg_src, reg_base) ASM_STORE16_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE16_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) asm_x86_mov_r16_to_mem16((as), (reg_src), (reg_base), 2 * (word_offset)) +#define ASM_STORE32_REG_REG(as, reg_src, reg_base) ASM_STORE32_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE32_REG_REG_OFFSET(as, reg_src, reg_base, dword_offset) asm_x86_mov_r32_to_mem32((as), (reg_src), (reg_base), 4 * (dword_offset)) #endif // GENERIC_ASM_API diff --git a/py/asmxtensa.c b/py/asmxtensa.c index 0fbe351dcf3..bc3e717d9f3 100644 --- a/py/asmxtensa.c +++ b/py/asmxtensa.c @@ -34,9 +34,20 @@ #include "py/asmxtensa.h" +#if N_XTENSAWIN +#define REG_TEMP ASM_XTENSA_REG_TEMPORARY_WIN +#else +#define REG_TEMP ASM_XTENSA_REG_TEMPORARY +#endif + #define WORD_SIZE (4) +#define SIGNED_FIT6(x) ((((x) & 0xffffffe0) == 0) || (((x) & 0xffffffe0) == 0xffffffe0)) #define SIGNED_FIT8(x) ((((x) & 0xffffff80) == 0) || (((x) & 0xffffff80) == 0xffffff80)) #define SIGNED_FIT12(x) ((((x) & 0xfffff800) == 0) || (((x) & 0xfffff800) == 0xfffff800)) +#define SIGNED_FIT18(x) ((((x) & 0xfffe0000) == 0) || (((x) & 0xfffe0000) == 0xfffe0000)) + +#define ET_OUT_OF_RANGE MP_ERROR_TEXT("ERROR: xtensa %q out of range") +#define ET_NOT_ALIGNED MP_ERROR_TEXT("ERROR: %q %q not word-aligned") void asm_xtensa_end_pass(asm_xtensa_t *as) { as->num_const = as->cur_const; @@ -47,9 +58,9 @@ void asm_xtensa_end_pass(asm_xtensa_t *as) { if (as->base.pass == MP_ASM_PASS_EMIT) { uint8_t *d = as->base.code_base; printf("XTENSA ASM:"); - for (int i = 0; i < ((as->base.code_size + 15) & ~15); ++i) { + for (size_t i = 0; i < ((as->base.code_size + 15) & ~15); ++i) { if (i % 16 == 0) { - printf("\n%08x:", (uint32_t)&d[i]); + printf("\n%p:", &d[i]); } if (i % 2 == 0) { printf(" "); @@ -62,10 +73,12 @@ void asm_xtensa_end_pass(asm_xtensa_t *as) { } void asm_xtensa_entry(asm_xtensa_t *as, int num_locals) { - // jump over the constants - asm_xtensa_op_j(as, as->num_const * WORD_SIZE + 4 - 4); - mp_asm_base_get_cur_to_write_bytes(&as->base, 1); // padding/alignment byte - as->const_table = (uint32_t *)mp_asm_base_get_cur_to_write_bytes(&as->base, as->num_const * 4); + if (as->num_const > 0) { + // jump over the constants + asm_xtensa_op_j(as, as->num_const * WORD_SIZE + 4 - 4); + mp_asm_base_get_cur_to_write_bytes(&as->base, 1); // padding/alignment byte + as->const_table = (uint32_t *)mp_asm_base_get_cur_to_write_bytes(&as->base, as->num_const * 4); + } // adjust the stack-pointer to store a0, a12, a13, a14, a15 and locals, 16-byte aligned as->stack_adjust = (((ASM_XTENSA_NUM_REGS_SAVED + num_locals) * WORD_SIZE) + 15) & ~15; @@ -146,22 +159,60 @@ void asm_xtensa_j_label(asm_xtensa_t *as, uint label) { asm_xtensa_op_j(as, rel); } +static bool calculate_branch_displacement(asm_xtensa_t *as, uint label, ptrdiff_t *displacement) { + assert(displacement != NULL && "Displacement pointer is NULL"); + + uint32_t label_offset = get_label_dest(as, label); + *displacement = (ptrdiff_t)(label_offset - as->base.code_offset - 4); + return (label_offset != (uint32_t)-1) && (*displacement < 0); +} + void asm_xtensa_bccz_reg_label(asm_xtensa_t *as, uint cond, uint reg, uint label) { - uint32_t dest = get_label_dest(as, label); - int32_t rel = dest - as->base.code_offset - 4; - if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT12(rel)) { - printf("ERROR: xtensa bccz out of range\n"); + ptrdiff_t rel = 0; + bool can_emit_short_jump = calculate_branch_displacement(as, label, &rel); + + if (can_emit_short_jump && SIGNED_FIT12(rel)) { + // Backwards BCCZ opcodes with an offset that fits in 12 bits can + // be emitted without any change. + asm_xtensa_op_bccz(as, cond, reg, rel); + return; } - asm_xtensa_op_bccz(as, cond, reg, rel); + + // Range is effectively extended to 18 bits, as a more complex jump code + // sequence is emitted. + if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT18(rel - 6)) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_bccz); + } + + // ~BCCZ skip ; +0 <- Condition is flipped here (EQ -> NE, etc.) + // J addr ; +3 + // skip: ; +6 + asm_xtensa_op_bccz(as, cond ^ 1, reg, 6 - 4); + asm_xtensa_op_j(as, rel - 3); } void asm_xtensa_bcc_reg_reg_label(asm_xtensa_t *as, uint cond, uint reg1, uint reg2, uint label) { - uint32_t dest = get_label_dest(as, label); - int32_t rel = dest - as->base.code_offset - 4; - if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT8(rel)) { - printf("ERROR: xtensa bcc out of range\n"); + ptrdiff_t rel = 0; + bool can_emit_short_jump = calculate_branch_displacement(as, label, &rel); + + if (can_emit_short_jump && SIGNED_FIT8(rel)) { + // Backwards BCC opcodes with an offset that fits in 8 bits can + // be emitted without any change. + asm_xtensa_op_bcc(as, cond, reg1, reg2, rel); + return; + } + + // Range is effectively extended to 18 bits, as a more complex jump code + // sequence is emitted. + if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT18(rel - 6)) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_bcc); } - asm_xtensa_op_bcc(as, cond, reg1, reg2, rel); + + // ~BCC skip ; +0 <- Condition is flipped here (EQ -> NE, etc.) + // J addr ; +3 + // skip: ; +6 + asm_xtensa_op_bcc(as, cond ^ 8, reg1, reg2, 6 - 4); + asm_xtensa_op_j(as, rel - 3); } // convenience function; reg_dest must be different from reg_src[12] @@ -179,6 +230,8 @@ size_t asm_xtensa_mov_reg_i32(asm_xtensa_t *as, uint reg_dest, uint32_t i32) { // store the constant in the table if (as->const_table != NULL) { as->const_table[as->cur_const] = i32; + } else { + assert((as->base.pass != MP_ASM_PASS_EMIT) && "Constants table was not built."); } ++as->cur_const; return loc; @@ -240,17 +293,53 @@ void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, u } else if (word_offset < 256) { asm_xtensa_op_l32i(as, reg_dest, reg_base, word_offset); } else { - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow")); + asm_xtensa_mov_reg_i32_optimised(as, reg_dest, word_offset * 4); + asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest); + asm_xtensa_op_l32i_n(as, reg_dest, reg_dest, 0); } } -void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset) { - if (word_offset < 16) { - asm_xtensa_op_s32i_n(as, reg_src, reg_base, word_offset); - } else if (word_offset < 256) { - asm_xtensa_op_s32i(as, reg_src, reg_base, word_offset); +void asm_xtensa_load_reg_reg_offset(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint offset, uint operation_size) { + assert(operation_size <= 2 && "Operation size value out of range."); + + if (operation_size == 2 && MP_FIT_UNSIGNED(4, offset)) { + asm_xtensa_op_l32i_n(as, reg_dest, reg_base, offset); + return; + } + + if (MP_FIT_UNSIGNED(8, offset)) { + asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, operation_size, reg_base, reg_dest, offset)); + return; + } + + asm_xtensa_mov_reg_i32_optimised(as, reg_dest, offset << operation_size); + asm_xtensa_op_add_n(as, reg_dest, reg_base, reg_dest); + if (operation_size == 2) { + asm_xtensa_op_l32i_n(as, reg_dest, reg_dest, 0); } else { - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("asm overflow")); + asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, operation_size, reg_dest, reg_dest, 0)); + } +} + +void asm_xtensa_store_reg_reg_offset(asm_xtensa_t *as, uint reg_src, uint reg_base, uint offset, uint operation_size) { + assert(operation_size <= 2 && "Operation size value out of range."); + + if (operation_size == 2 && MP_FIT_UNSIGNED(4, offset)) { + asm_xtensa_op_s32i_n(as, reg_src, reg_base, offset); + return; + } + + if (MP_FIT_UNSIGNED(8, offset)) { + asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, 0x04 | operation_size, reg_base, reg_src, offset)); + return; + } + + asm_xtensa_mov_reg_i32_optimised(as, REG_TEMP, offset << operation_size); + asm_xtensa_op_add_n(as, REG_TEMP, reg_base, REG_TEMP); + if (operation_size == 2) { + asm_xtensa_op_s32i_n(as, reg_src, REG_TEMP, 0); + } else { + asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, 0x04 | operation_size, REG_TEMP, reg_src, 0)); } } @@ -264,4 +353,47 @@ void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx) { asm_xtensa_op_callx8(as, ASM_XTENSA_REG_A8); } +void asm_xtensa_bit_branch(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t bit, mp_uint_t label, mp_uint_t condition) { + uint32_t dest = get_label_dest(as, label); + int32_t rel = dest - as->base.code_offset - 4; + if (as->base.pass == MP_ASM_PASS_EMIT && !SIGNED_FIT8(rel)) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_bit_branch); + } + asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(7, condition | ((bit >> 4) & 0x01), reg, bit & 0x0F, rel & 0xFF)); +} + +void asm_xtensa_call0(asm_xtensa_t *as, mp_uint_t label) { + uint32_t dest = get_label_dest(as, label); + int32_t rel = dest - as->base.code_offset - 3; + if (as->base.pass == MP_ASM_PASS_EMIT) { + if ((dest & 0x03) != 0) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_NOT_ALIGNED, MP_QSTR_call0, MP_QSTR_target); + } + if ((rel & 0x03) != 0) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_NOT_ALIGNED, MP_QSTR_call0, MP_QSTR_location); + } + if (!SIGNED_FIT18(rel)) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_call0); + } + } + asm_xtensa_op_call0(as, rel); +} + +void asm_xtensa_l32r(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t label) { + uint32_t dest = get_label_dest(as, label); + int32_t rel = dest - as->base.code_offset; + if (as->base.pass == MP_ASM_PASS_EMIT) { + if ((dest & 0x03) != 0) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_NOT_ALIGNED, MP_QSTR_l32r, MP_QSTR_target); + } + if ((rel & 0x03) != 0) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_NOT_ALIGNED, MP_QSTR_l32r, MP_QSTR_location); + } + if (!SIGNED_FIT18(rel) || (rel >= 0)) { + mp_raise_msg_varg(&mp_type_RuntimeError, ET_OUT_OF_RANGE, MP_QSTR_l32r); + } + } + asm_xtensa_op_l32r(as, reg, as->base.code_offset, dest); +} + #endif // MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA || MICROPY_EMIT_XTENSAWIN diff --git a/py/asmxtensa.h b/py/asmxtensa.h index c3c8f225f37..ed98c9d7305 100644 --- a/py/asmxtensa.h +++ b/py/asmxtensa.h @@ -64,9 +64,11 @@ #define ASM_XTENSA_REG_A14 (14) #define ASM_XTENSA_REG_A15 (15) -// for bccz +// for bccz and bcci #define ASM_XTENSA_CCZ_EQ (0) #define ASM_XTENSA_CCZ_NE (1) +#define ASM_XTENSA_CCZ_LT (2) +#define ASM_XTENSA_CCZ_GE (3) // for bcc and setcc #define ASM_XTENSA_CC_NONE (0) @@ -143,6 +145,14 @@ static inline void asm_xtensa_op_addi(asm_xtensa_t *as, uint reg_dest, uint reg_ asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRI8(2, 12, reg_src, reg_dest, imm8 & 0xff)); } +static inline void asm_xtensa_op_addx2(asm_xtensa_t *as, uint reg_dest, uint reg_src_a, uint reg_src_b) { + asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRR(0, 0, 9, reg_dest, reg_src_a, reg_src_b)); +} + +static inline void asm_xtensa_op_addx4(asm_xtensa_t *as, uint reg_dest, uint reg_src_a, uint reg_src_b) { + asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRR(0, 0, 10, reg_dest, reg_src_a, reg_src_b)); +} + static inline void asm_xtensa_op_and(asm_xtensa_t *as, uint reg_dest, uint reg_src_a, uint reg_src_b) { asm_xtensa_op24(as, ASM_XTENSA_ENCODE_RRR(0, 0, 1, reg_dest, reg_src_a, reg_src_b)); } @@ -283,15 +293,24 @@ void asm_xtensa_mov_local_reg(asm_xtensa_t *as, int local_num, uint reg_src); void asm_xtensa_mov_reg_local(asm_xtensa_t *as, uint reg_dest, int local_num); void asm_xtensa_mov_reg_local_addr(asm_xtensa_t *as, uint reg_dest, int local_num); void asm_xtensa_mov_reg_pcrel(asm_xtensa_t *as, uint reg_dest, uint label); -void asm_xtensa_l32i_optimised(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint word_offset); -void asm_xtensa_s32i_optimised(asm_xtensa_t *as, uint reg_src, uint reg_base, uint word_offset); +void asm_xtensa_load_reg_reg_offset(asm_xtensa_t *as, uint reg_dest, uint reg_base, uint offset, uint operation_size); +void asm_xtensa_store_reg_reg_offset(asm_xtensa_t *as, uint reg_src, uint reg_base, uint offset, uint operation_size); void asm_xtensa_call_ind(asm_xtensa_t *as, uint idx); void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx); +void asm_xtensa_bit_branch(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t bit, mp_uint_t label, mp_uint_t condition); +void asm_xtensa_immediate_branch(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t immediate, mp_uint_t label, mp_uint_t cond); +void asm_xtensa_call0(asm_xtensa_t *as, mp_uint_t label); +void asm_xtensa_l32r(asm_xtensa_t *as, mp_uint_t reg, mp_uint_t label); // Holds a pointer to mp_fun_table #define ASM_XTENSA_REG_FUN_TABLE ASM_XTENSA_REG_A15 #define ASM_XTENSA_REG_FUN_TABLE_WIN ASM_XTENSA_REG_A7 +// Internal temporary register (currently aliased to REG_ARG_5 for xtensa, +// and to REG_TEMP2 for xtensawin). +#define ASM_XTENSA_REG_TEMPORARY ASM_XTENSA_REG_A6 +#define ASM_XTENSA_REG_TEMPORARY_WIN ASM_XTENSA_REG_A12 + // CIRCUITPY-CHANGE: prevent #if warning #if defined(GENERIC_ASM_API) && GENERIC_ASM_API @@ -322,9 +341,9 @@ void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx); #define ASM_NUM_REGS_SAVED ASM_XTENSA_NUM_REGS_SAVED #define REG_FUN_TABLE ASM_XTENSA_REG_FUN_TABLE -#define ASM_ENTRY(as, nlocal) asm_xtensa_entry((as), (nlocal)) -#define ASM_EXIT(as) asm_xtensa_exit((as)) -#define ASM_CALL_IND(as, idx) asm_xtensa_call_ind((as), (idx)) +#define ASM_ENTRY(as, nlocal, name) asm_xtensa_entry((as), (nlocal)) +#define ASM_EXIT(as) asm_xtensa_exit((as)) +#define ASM_CALL_IND(as, idx) asm_xtensa_call_ind((as), (idx)) #else // Configuration for windowed calls with window size 8 @@ -352,9 +371,9 @@ void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx); #define ASM_NUM_REGS_SAVED ASM_XTENSA_NUM_REGS_SAVED_WIN #define REG_FUN_TABLE ASM_XTENSA_REG_FUN_TABLE_WIN -#define ASM_ENTRY(as, nlocal) asm_xtensa_entry_win((as), (nlocal)) -#define ASM_EXIT(as) asm_xtensa_exit_win((as)) -#define ASM_CALL_IND(as, idx) asm_xtensa_call_ind_win((as), (idx)) +#define ASM_ENTRY(as, nlocal, name) asm_xtensa_entry_win((as), (nlocal)) +#define ASM_EXIT(as) asm_xtensa_exit_win((as)) +#define ASM_CALL_IND(as, idx) asm_xtensa_call_ind_win((as), (idx)) #endif @@ -400,16 +419,51 @@ void asm_xtensa_call_ind_win(asm_xtensa_t *as, uint idx); #define ASM_SUB_REG_REG(as, reg_dest, reg_src) asm_xtensa_op_sub((as), (reg_dest), (reg_dest), (reg_src)) #define ASM_MUL_REG_REG(as, reg_dest, reg_src) asm_xtensa_op_mull((as), (reg_dest), (reg_dest), (reg_src)) -#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_l32i_optimised((as), (reg_dest), (reg_base), (word_offset)) -#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0) -#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0) -#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), (uint16_offset)) -#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset)) +#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) ASM_LOAD8_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD8_REG_REG_OFFSET(as, reg_dest, reg_base, byte_offset) asm_xtensa_load_reg_reg_offset((as), (reg_dest), (reg_base), (byte_offset), 0) +#define ASM_LOAD8_REG_REG_REG(as, reg_dest, reg_base, reg_index) \ + do { \ + asm_xtensa_op_add_n((as), (reg_base), (reg_index), (reg_base)); \ + asm_xtensa_op_l8ui((as), (reg_dest), (reg_base), 0); \ + } while (0) +#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) ASM_LOAD16_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, halfword_offset) asm_xtensa_load_reg_reg_offset((as), (reg_dest), (reg_base), (halfword_offset), 1) +#define ASM_LOAD16_REG_REG_REG(as, reg_dest, reg_base, reg_index) \ + do { \ + asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \ + asm_xtensa_op_l16ui((as), (reg_dest), (reg_base), 0); \ + } while (0) +#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) ASM_LOAD32_REG_REG_OFFSET((as), (reg_dest), (reg_base), 0) +#define ASM_LOAD32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_load_reg_reg_offset((as), (reg_dest), (reg_base), (word_offset), 2) +#define ASM_LOAD32_REG_REG_REG(as, reg_dest, reg_base, reg_index) \ + do { \ + asm_xtensa_op_addx4((as), (reg_base), (reg_index), (reg_base)); \ + asm_xtensa_op_l32i_n((as), (reg_dest), (reg_base), 0); \ + } while (0) -#define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_s32i_optimised((as), (reg_dest), (reg_base), (word_offset)) -#define ASM_STORE8_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s8i((as), (reg_src), (reg_base), 0) -#define ASM_STORE16_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s16i((as), (reg_src), (reg_base), 0) -#define ASM_STORE32_REG_REG(as, reg_src, reg_base) asm_xtensa_op_s32i_n((as), (reg_src), (reg_base), 0) +#define ASM_STORE_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) ASM_STORE32_REG_REG_OFFSET((as), (reg_dest), (reg_base), (word_offset)) +#define ASM_STORE8_REG_REG(as, reg_src, reg_base) ASM_STORE8_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE8_REG_REG_OFFSET(as, reg_src, reg_base, byte_offset) asm_xtensa_store_reg_reg_offset((as), (reg_src), (reg_base), (byte_offset), 0) +#define ASM_STORE8_REG_REG_REG(as, reg_val, reg_base, reg_index) \ + do { \ + asm_xtensa_op_add_n((as), (reg_base), (reg_index), (reg_base)); \ + asm_xtensa_op_s8i((as), (reg_val), (reg_base), 0); \ + } while (0) +#define ASM_STORE16_REG_REG(as, reg_src, reg_base) ASM_STORE16_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE16_REG_REG_OFFSET(as, reg_src, reg_base, halfword_offset) asm_xtensa_store_reg_reg_offset((as), (reg_src), (reg_base), (halfword_offset), 1) +#define ASM_STORE16_REG_REG_REG(as, reg_val, reg_base, reg_index) \ + do { \ + asm_xtensa_op_addx2((as), (reg_base), (reg_index), (reg_base)); \ + asm_xtensa_op_s16i((as), (reg_val), (reg_base), 0); \ + } while (0) +#define ASM_STORE32_REG_REG(as, reg_src, reg_base) ASM_STORE32_REG_REG_OFFSET((as), (reg_src), (reg_base), 0) +#define ASM_STORE32_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) asm_xtensa_store_reg_reg_offset((as), (reg_dest), (reg_base), (word_offset), 2) +#define ASM_STORE32_REG_REG_REG(as, reg_val, reg_base, reg_index) \ + do { \ + asm_xtensa_op_addx4((as), (reg_base), (reg_index), (reg_base)); \ + asm_xtensa_op_s32i_n((as), (reg_val), (reg_base), 0); \ + } while (0) #endif // GENERIC_ASM_API diff --git a/py/bc.c b/py/bc.c index c2956030e38..4caa022e3d8 100644 --- a/py/bc.c +++ b/py/bc.c @@ -88,7 +88,7 @@ const byte *mp_decode_uint_skip(const byte *ptr) { return ptr; } -static NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, size_t given) { +static MP_NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, size_t given) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE // generic message, used also for other argument issues (void)f; diff --git a/py/bc.h b/py/bc.h index 007897a028e..3b7a6fe1c96 100644 --- a/py/bc.h +++ b/py/bc.h @@ -226,6 +226,7 @@ typedef struct _mp_compiled_module_t { bool has_native; size_t n_qstr; size_t n_obj; + size_t arch_flags; #endif } mp_compiled_module_t; @@ -302,37 +303,49 @@ static inline void mp_module_context_alloc_tables(mp_module_context_t *context, #if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE size_t nq = (n_qstr * sizeof(qstr_short_t) + sizeof(mp_uint_t) - 1) / sizeof(mp_uint_t); size_t no = n_obj; - mp_uint_t *mem = m_new(mp_uint_t, nq + no); + // CIRCUITPY-CHANGE + mp_uint_t *mem = (mp_uint_t *)m_malloc_items(nq + no); context->constants.qstr_table = (qstr_short_t *)mem; context->constants.obj_table = (mp_obj_t *)(mem + nq); #else if (n_obj == 0) { context->constants.obj_table = NULL; } else { - context->constants.obj_table = m_new(mp_obj_t, n_obj); + // CIRCUITPY-CHANGE + context->constants.obj_table = m_malloc_items(n_obj); } #endif } +typedef struct _mp_code_lineinfo_t { + size_t bc_increment; + size_t line_increment; +} mp_code_lineinfo_t; + +static inline mp_code_lineinfo_t mp_bytecode_decode_lineinfo(const byte **line_info) { + mp_code_lineinfo_t result; + size_t c = (*line_info)[0]; + if ((c & 0x80) == 0) { + // 0b0LLBBBBB encoding + result.bc_increment = c & 0x1f; + result.line_increment = c >> 5; + *line_info += 1; + } else { + // 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte) + result.bc_increment = c & 0xf; + result.line_increment = ((c << 4) & 0x700) | (*line_info)[1]; + *line_info += 2; + } + return result; +} + static inline size_t mp_bytecode_get_source_line(const byte *line_info, const byte *line_info_top, size_t bc_offset) { size_t source_line = 1; while (line_info < line_info_top) { - size_t c = *line_info; - size_t b, l; - if ((c & 0x80) == 0) { - // 0b0LLBBBBB encoding - b = c & 0x1f; - l = c >> 5; - line_info += 1; - } else { - // 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte) - b = c & 0xf; - l = ((c << 4) & 0x700) | line_info[1]; - line_info += 2; - } - if (bc_offset >= b) { - bc_offset -= b; - source_line += l; + mp_code_lineinfo_t decoded = mp_bytecode_decode_lineinfo(&line_info); + if (bc_offset >= decoded.bc_increment) { + bc_offset -= decoded.bc_increment; + source_line += decoded.line_increment; } else { // found source line corresponding to bytecode offset break; diff --git a/py/binary.c b/py/binary.c index 75dfc19925f..180a13beec7 100644 --- a/py/binary.c +++ b/py/binary.c @@ -71,8 +71,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, size_t *palign) { case 'Q': size = 8; break; - // CIRCUITPY-CHANGE: non-standard typecodes can be turned off - #if MICROPY_NONSTANDARD_TYPECODES + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES case 'P': case 'O': case 'S': @@ -128,8 +127,7 @@ size_t mp_binary_get_size(char struct_type, char val_type, size_t *palign) { align = alignof(long long); size = sizeof(long long); break; - // CIRCUITPY-CHANGE: non-standard typecodes can be turned off - #if MICROPY_NONSTANDARD_TYPECODES + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES case 'P': case 'O': case 'S': @@ -208,7 +206,7 @@ static float mp_decode_half_float(uint16_t hf) { ++e; } - fpu.i = ((hf & 0x8000) << 16) | (e << 23) | (m << 13); + fpu.i = ((hf & 0x8000u) << 16) | (e << 23) | (m << 13); return fpu.f; } @@ -292,15 +290,14 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, size_t index) { case 'd': return mp_obj_new_float_from_d(((double *)p)[index]); #endif - // CIRCUITPY-CHANGE: non-standard typecodes can be turned off - #if MICROPY_NONSTANDARD_TYPECODES - // Extension to CPython: array of objects + // Extension to CPython: array of objects + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES case 'O': return ((mp_obj_t *)p)[index]; // Extension to CPython: array of pointers case 'P': return mp_obj_new_int((mp_int_t)(uintptr_t)((void **)p)[index]); - #endif + #endif } return MP_OBJ_NEW_SMALL_INT(val); } @@ -350,14 +347,11 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte *p_base, byte * long long val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p); - // CIRCUITPY-CHANGE: non-standard typecodes can be turned off - if (MICROPY_NONSTANDARD_TYPECODES && (val_type == 'O')) { + if (MICROPY_PY_STRUCT_UNSAFE_TYPECODES && val_type == 'O') { return (mp_obj_t)(mp_uint_t)val; - #if MICROPY_NONSTANDARD_TYPECODES - } else if (val_type == 'S') { + } else if (MICROPY_PY_STRUCT_UNSAFE_TYPECODES && val_type == 'S') { const char *s_val = (const char *)(uintptr_t)(mp_uint_t)val; - return mp_obj_new_str(s_val, strlen(s_val)); - #endif + return mp_obj_new_str_from_cstr(s_val); #if MICROPY_PY_BUILTINS_FLOAT } else if (val_type == 'e') { return mp_obj_new_float_from_f(mp_decode_half_float(val)); @@ -426,8 +420,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte *p mp_uint_t val; switch (val_type) { - // CIRCUITPY-CHANGE: non-standard typecodes can be turned off - #if MICROPY_NONSTANDARD_TYPECODES + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES case 'O': val = (mp_uint_t)val_in; break; @@ -445,6 +438,8 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte *p val = fp_sp.i; break; } + // CIRCUITPY-CHANGE + #if MICROPY_PY_DOUBLE_TYPECODE case 'd': { union { uint64_t i64; @@ -463,6 +458,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte *p break; } #endif + #endif default: { // CIRCUITPY-CHANGE: add overflow checks bool signed_type = is_signed(val_type); @@ -505,8 +501,7 @@ void mp_binary_set_val_array(char typecode, void *p, size_t index, mp_obj_t val_ ((double *)p)[index] = mp_obj_get_float_to_d(val_in); break; #endif - // CIRCUITPY-CHANGE: non-standard typecodes can be turned off - #if MICROPY_NONSTANDARD_TYPECODES + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES // Extension to CPython: array of objects case 'O': ((mp_obj_t *)p)[index] = val_in; @@ -578,12 +573,11 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, size_t index, mp_i ((double *)p)[index] = (double)val; break; #endif - // CIRCUITPY-CHANGE: non-standard typecodes can be turned off - #if MICROPY_NONSTANDARD_TYPECODES - // Extension to CPython: array of pointers + // Extension to CPython: array of pointers + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES case 'P': ((void **)p)[index] = (void *)(uintptr_t)val; break; - #endif + #endif } } diff --git a/py/builtin.h b/py/builtin.h index 81d0789802b..388bc847005 100644 --- a/py/builtin.h +++ b/py/builtin.h @@ -126,6 +126,8 @@ MP_DECLARE_CONST_FUN_OBJ_2(mp_op_getitem_obj); MP_DECLARE_CONST_FUN_OBJ_3(mp_op_setitem_obj); MP_DECLARE_CONST_FUN_OBJ_2(mp_op_delitem_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj); + // Modules needed by the runtime. extern const mp_obj_dict_t mp_module_builtins_globals; extern const mp_obj_module_t mp_module___main__; @@ -136,6 +138,7 @@ extern const mp_obj_module_t mp_module_sys; extern const mp_obj_module_t mp_module_errno; extern const mp_obj_module_t mp_module_uctypes; extern const mp_obj_module_t mp_module_machine; +extern const mp_obj_module_t mp_module_math; extern const char MICROPY_PY_BUILTINS_HELP_TEXT[]; diff --git a/py/builtinevex.c b/py/builtinevex.c index e25cbd4d085..74a46404926 100644 --- a/py/builtinevex.c +++ b/py/builtinevex.c @@ -26,6 +26,7 @@ #include +#include "py/objcode.h" #include "py/objfun.h" #include "py/compile.h" #include "py/runtime.h" @@ -33,17 +34,6 @@ #if MICROPY_PY_BUILTINS_COMPILE -typedef struct _mp_obj_code_t { - mp_obj_base_t base; - mp_obj_t module_fun; -} mp_obj_code_t; - -static MP_DEFINE_CONST_OBJ_TYPE( - mp_type_code, - MP_QSTR_code, - MP_TYPE_FLAG_NONE - ); - static mp_obj_t code_execute(mp_obj_code_t *self, mp_obj_dict_t *globals, mp_obj_dict_t *locals) { // save context nlr_jump_callback_node_globals_locals_t ctx; @@ -57,19 +47,28 @@ static mp_obj_t code_execute(mp_obj_code_t *self, mp_obj_dict_t *globals, mp_obj // set exception handler to restore context if an exception is raised nlr_push_jump_callback(&ctx.callback, mp_globals_locals_set_from_nlr_jump_callback); + #if MICROPY_PY_BUILTINS_CODE >= MICROPY_PY_BUILTINS_CODE_BASIC + mp_module_context_t *module_context = m_new_obj(mp_module_context_t); + module_context->module.base.type = &mp_type_module; + module_context->module.globals = globals; + module_context->constants = *mp_code_get_constants(self); + mp_obj_t module_fun = mp_make_function_from_proto_fun(mp_code_get_proto_fun(self), module_context, NULL); + #else // The call to mp_parse_compile_execute() in mp_builtin_compile() below passes // NULL for the globals, so repopulate that entry now with the correct globals. + mp_obj_t module_fun = self->module_fun; if (mp_obj_is_type(self->module_fun, &mp_type_fun_bc) #if MICROPY_EMIT_NATIVE || mp_obj_is_type(self->module_fun, &mp_type_fun_native) #endif ) { - mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(self->module_fun); + mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(module_fun); ((mp_module_context_t *)fun_bc->context)->module.globals = globals; } + #endif // execute code - mp_obj_t ret = mp_call_function_0(self->module_fun); + mp_obj_t ret = mp_call_function_0(module_fun); // deregister exception handler and restore context nlr_pop_jump_callback(true); @@ -108,9 +107,29 @@ static mp_obj_t mp_builtin_compile(size_t n_args, const mp_obj_t *args) { mp_raise_ValueError(MP_ERROR_TEXT("bad compile mode")); } - mp_obj_code_t *code = mp_obj_malloc(mp_obj_code_t, &mp_type_code); - code->module_fun = mp_parse_compile_execute(lex, parse_input_kind, NULL, NULL); - return MP_OBJ_FROM_PTR(code); + #if MICROPY_PY_BUILTINS_CODE >= MICROPY_PY_BUILTINS_CODE_BASIC + + mp_parse_tree_t parse_tree = mp_parse(lex, parse_input_kind); + mp_module_context_t ctx; + ctx.module.globals = NULL; + mp_compiled_module_t cm; + cm.context = &ctx; + mp_compile_to_raw_code(&parse_tree, lex->source_name, parse_input_kind == MP_PARSE_SINGLE_INPUT, &cm); + + #if MICROPY_PY_BUILTINS_CODE >= MICROPY_PY_BUILTINS_CODE_FULL + mp_module_context_t *ctx_ptr = m_new_obj(mp_module_context_t); + *ctx_ptr = ctx; + return mp_obj_new_code(ctx_ptr, cm.rc, true); + #else + return mp_obj_new_code(ctx.constants, cm.rc); + #endif + + #else + + mp_obj_t module_fun = mp_parse_compile_execute(lex, parse_input_kind, NULL, NULL); + return mp_obj_new_code(module_fun); + + #endif } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_compile_obj, 3, 6, mp_builtin_compile); diff --git a/py/builtinhelp.c b/py/builtinhelp.c index d041d6915a6..9ab2a12d214 100644 --- a/py/builtinhelp.c +++ b/py/builtinhelp.c @@ -162,9 +162,8 @@ static void mp_help_print_obj(const mp_obj_t obj) { } if (map != NULL) { for (uint i = 0; i < map->alloc; i++) { - mp_obj_t key = map->table[i].key; - if (key != MP_OBJ_NULL) { - mp_help_print_info_about_object(key, map->table[i].value); + if (mp_map_slot_is_filled(map, i)) { + mp_help_print_info_about_object(map->table[i].key, map->table[i].value); } } } diff --git a/py/builtinimport.c b/py/builtinimport.c index 17b3f11c4a0..5d77ac42859 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -105,7 +105,26 @@ static mp_import_stat_t stat_module(vstr_t *path) { mp_import_stat_t stat = stat_path(path); DEBUG_printf("stat %s: %d\n", vstr_str(path), stat); if (stat == MP_IMPORT_STAT_DIR) { - return stat; + // CIRCUITPY-CHANGE: match CPython import precedence. A regular + // package (directory with __init__.py/.mpy) takes precedence, then a + // sibling .py/.mpy module, and only then a namespace package + // (directory without __init__). See + // https://docs.python.org/3/reference/import.html#regular-packages + size_t orig_len = path->len; + vstr_add_str(path, PATH_SEP_CHAR "__init__.py"); + mp_import_stat_t init_stat = stat_file_py_or_mpy(path); + path->len = orig_len; + if (init_stat == MP_IMPORT_STAT_FILE) { + return MP_IMPORT_STAT_DIR; + } + + vstr_add_str(path, ".py"); + mp_import_stat_t file_stat = stat_file_py_or_mpy(path); + if (file_stat == MP_IMPORT_STAT_FILE) { + return file_stat; + } + path->len = orig_len; + return MP_IMPORT_STAT_DIR; } // Not a directory, add .py and try as a file. @@ -118,7 +137,7 @@ static mp_import_stat_t stat_module(vstr_t *path) { // path (i.e. "/mod_name(.py)"). static mp_import_stat_t stat_top_level(qstr mod_name, vstr_t *dest) { DEBUG_printf("stat_top_level: '%s'\n", qstr_str(mod_name)); - #if MICROPY_PY_SYS + #if MICROPY_PY_SYS && MICROPY_PY_SYS_PATH size_t path_num; mp_obj_t *path_items; mp_obj_get_array(mp_sys_path, &path_num, &path_items); @@ -155,7 +174,7 @@ static mp_import_stat_t stat_top_level(qstr mod_name, vstr_t *dest) { #if MICROPY_MODULE_FROZEN_STR || MICROPY_ENABLE_COMPILER static void do_load_from_lexer(mp_module_context_t *context, mp_lexer_t *lex) { - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ qstr source_name = lex->source_name; mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif @@ -168,7 +187,7 @@ static void do_load_from_lexer(mp_module_context_t *context, mp_lexer_t *lex) { #if (MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD) || MICROPY_MODULE_FROZEN_MPY static void do_execute_proto_fun(const mp_module_context_t *context, mp_proto_fun_t proto_fun, qstr source_name) { - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #else (void)source_name; @@ -227,7 +246,7 @@ static void do_load(mp_module_context_t *module_obj, vstr_t *file) { if (frozen_type == MP_FROZEN_MPY) { const mp_frozen_module_t *frozen = modref; module_obj->constants = frozen->constants; - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ qstr frozen_file_qstr = qstr_from_str(file_str + frozen_path_prefix_len); #else qstr frozen_file_qstr = MP_QSTRnull; @@ -270,7 +289,7 @@ static void do_load(mp_module_context_t *module_obj, vstr_t *file) { // Convert a relative (to the current module) import, going up "level" levels, // into an absolute import. -static void evaluate_relative_import(mp_int_t level, const char **module_name, size_t *module_name_len) { +static void evaluate_relative_import(mp_int_t level, const char **module_name, size_t *module_name_len, mp_obj_t globals) { // What we want to do here is to take the name of the current module, // remove trailing components, and concatenate the passed-in // module name. @@ -279,7 +298,7 @@ static void evaluate_relative_import(mp_int_t level, const char **module_name, s // module's position in the package hierarchy." // http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name - mp_obj_t current_module_name_obj = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___name__)); + mp_obj_t current_module_name_obj = mp_obj_dict_get(globals, MP_OBJ_NEW_QSTR(MP_QSTR___name__)); assert(current_module_name_obj != MP_OBJ_NULL); #if MICROPY_MODULE_OVERRIDE_MAIN_IMPORT && MICROPY_CPYTHON_COMPAT @@ -287,12 +306,12 @@ static void evaluate_relative_import(mp_int_t level, const char **module_name, s // This is a module loaded by -m command-line switch (e.g. unix port), // and so its __name__ has been set to "__main__". Get its real name // that we stored during import in the __main__ attribute. - current_module_name_obj = mp_obj_dict_get(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(MP_QSTR___main__)); + current_module_name_obj = mp_obj_dict_get(globals, MP_OBJ_NEW_QSTR(MP_QSTR___main__)); } #endif // If we have a __path__ in the globals dict, then we're a package. - bool is_pkg = mp_map_lookup(&mp_globals_get()->map, MP_OBJ_NEW_QSTR(MP_QSTR___path__), MP_MAP_LOOKUP); + bool is_pkg = mp_map_lookup(mp_obj_dict_get_map(globals), MP_OBJ_NEW_QSTR(MP_QSTR___path__), MP_MAP_LOOKUP); #if DEBUG_PRINT DEBUG_printf("Current module/package: "); @@ -370,7 +389,7 @@ static mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, // Immediately return if the module at this level is already loaded. mp_map_elem_t *elem; - #if MICROPY_PY_SYS + #if MICROPY_PY_SYS && MICROPY_PY_SYS_PATH // If sys.path is empty, the intention is to force using a built-in. This // means we should also ignore any loaded modules with the same name // which may have come from the filesystem. @@ -406,6 +425,7 @@ static mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, // all the locations in sys.path. stat = stat_top_level(level_mod_name, &path); + #if MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES // If filesystem failed, now try and see if it matches an extensible // built-in module. if (stat == MP_IMPORT_STAT_NO_EXIST) { @@ -414,6 +434,7 @@ static mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, return module_obj; } } + #endif } else { DEBUG_printf("Searching for sub-module\n"); @@ -451,7 +472,9 @@ static mp_obj_t process_import_at_level(qstr full_mod_name, qstr level_mod_name, if (stat == MP_IMPORT_STAT_NO_EXIST) { // Not found -- fail. - #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE + // CIRCUITPY-CHANGE: always the use more verbose error message that names missing module. + // Otherwise `import a` where `a` imports `b`, but `b` is missing will give a confusing error. + #if 0 && (MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE) mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); #else mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), full_mod_name); @@ -575,10 +598,19 @@ mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args) { const char *module_name = mp_obj_str_get_data(module_name_obj, &module_name_len); if (level != 0) { + // This is the dict with all global symbols. + mp_obj_t globals = MP_OBJ_FROM_PTR(mp_globals_get()); + if (n_args >= 2 && args[1] != mp_const_none) { + globals = args[1]; + if (!mp_obj_is_type(globals, &mp_type_dict)) { + mp_raise_TypeError(NULL); + } + } + // Turn "foo.bar" with level=3 into ".foo.bar". // Current module name is extracted from globals().__name__. - evaluate_relative_import(level, &module_name, &module_name_len); // module_name is now an absolute module path. + evaluate_relative_import(level, &module_name, &module_name_len, globals); } if (module_name_len == 0) { @@ -654,11 +686,13 @@ mp_obj_t mp_builtin___import___default(size_t n_args, const mp_obj_t *args) { if (module_obj != MP_OBJ_NULL) { return module_obj; } + #if MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES // Now try as an extensible built-in (e.g. `time`). module_obj = mp_module_get_builtin(module_name_qstr, true); if (module_obj != MP_OBJ_NULL) { return module_obj; } + #endif // Couldn't find the module, so fail #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk old mode 100644 new mode 100755 index 6d7848997ca..b50ab1ee633 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -122,6 +122,9 @@ endif ifeq ($(CIRCUITPY_AUDIOBUSIO),1) SRC_PATTERNS += audiobusio/% endif +ifeq ($(CIRCUITPY_AUDIOI2SIN),1) +SRC_PATTERNS += audioi2sin/% +endif ifeq ($(CIRCUITPY_AUDIOIO),1) SRC_PATTERNS += audioio/% endif @@ -131,12 +134,27 @@ endif ifeq ($(CIRCUITPY_AUDIOCORE),1) SRC_PATTERNS += audiocore/% endif +ifeq ($(CIRCUITPY_AUDIODELAYS),1) +SRC_PATTERNS += audiodelays/% +endif +ifeq ($(CIRCUITPY_AUDIOFILTERS),1) +SRC_PATTERNS += audiofilters/% +endif +ifeq ($(CIRCUITPY_AUDIOFREEVERB),1) +SRC_PATTERNS += audiofreeverb/% +endif ifeq ($(CIRCUITPY_AUDIOMIXER),1) SRC_PATTERNS += audiomixer/% endif ifeq ($(CIRCUITPY_AUDIOMP3),1) SRC_PATTERNS += audiomp3/% endif +ifeq ($(CIRCUITPY_AUDIOSPEED),1) +SRC_PATTERNS += audiospeed/% +endif +ifeq ($(CIRCUITPY_AUDIOFILEWRITER),1) +SRC_PATTERNS += audiofilewriter/% +endif ifeq ($(CIRCUITPY_AURORA_EPAPER),1) SRC_PATTERNS += aurora_epaper/% endif @@ -156,7 +174,7 @@ endif ifeq ($(CIRCUITPY_BITOPS),1) SRC_PATTERNS += bitops/% endif -ifeq ($(CIRCUITPY_BLEIO),1) +ifeq ($(CIRCUITPY_BLEIO_NATIVE),1) SRC_PATTERNS += _bleio/% endif ifeq ($(CIRCUITPY_BOARD),1) @@ -192,6 +210,12 @@ endif ifeq ($(CIRCUITPY_DISPLAYIO),1) SRC_PATTERNS += displayio/% endif +ifeq ($(CIRCUITPY_DOTCLOCKFRAMEBUFFER),1) +SRC_PATTERNS += dotclockframebuffer/% +endif +ifeq ($(CIRCUITPY_DUALBANK),1) +SRC_PATTERNS += dualbank/% +endif ifeq ($(CIRCUITPY__EVE),1) SRC_PATTERNS += _eve/% endif @@ -243,6 +267,9 @@ endif ifeq ($(CIRCUITPY_I2CTARGET),1) SRC_PATTERNS += i2ctarget/% endif +ifeq ($(CIRCUITPY_I2CIOEXPANDER),1) +SRC_PATTERNS += i2cioexpander/% +endif ifeq ($(CIRCUITPY_IMAGECAPTURE),1) SRC_PATTERNS += imagecapture/% endif @@ -270,6 +297,12 @@ endif ifeq ($(CIRCUITPY_MAX3421E),1) SRC_PATTERNS += max3421e/% endif +ifeq ($(CIRCUITPY_MCP4822),1) +SRC_PATTERNS += mcp4822/% +endif +ifeq ($(CIRCUITPY_MDNS),1) +SRC_PATTERNS += mdns/% +endif ifeq ($(CIRCUITPY_MEMORYMAP),1) SRC_PATTERNS += memorymap/% endif @@ -279,8 +312,8 @@ endif ifeq ($(CIRCUITPY_MICROCONTROLLER),1) SRC_PATTERNS += microcontroller/% endif -ifeq ($(CIRCUITPY_MDNS),1) -SRC_PATTERNS += mdns/% +ifeq ($(CIRCUITPY_MIPIDSI),1) +SRC_PATTERNS += mipidsi/% endif ifeq ($(CIRCUITPY_MSGPACK),1) SRC_PATTERNS += msgpack/% @@ -297,9 +330,6 @@ endif ifeq ($(CIRCUITPY_OS),1) SRC_PATTERNS += os/% endif -ifeq ($(CIRCUITPY_DUALBANK),1) -SRC_PATTERNS += dualbank/% -endif ifeq ($(CIRCUITPY_PARALLELDISPLAYBUS),1) SRC_PATTERNS += paralleldisplaybus/% endif @@ -333,11 +363,14 @@ endif ifeq ($(CIRCUITPY_RANDOM),1) SRC_PATTERNS += random/% endif +ifeq ($(CIRCUITPY_RCLCPY),1) +SRC_PATTERNS += rclcpy/% +endif ifeq ($(CIRCUITPY_RGBMATRIX),1) SRC_PATTERNS += rgbmatrix/% endif -ifeq ($(CIRCUITPY_DOTCLOCKFRAMEBUFFER),1) -SRC_PATTERNS += dotclockframebuffer/% +ifeq ($(CIRCUITPY_QSPIBUS),1) +SRC_PATTERNS += qspibus/% endif ifeq ($(CIRCUITPY_RP2PIO),1) SRC_PATTERNS += rp2pio/% @@ -363,6 +396,9 @@ endif ifeq ($(CIRCUITPY_SOCKETPOOL),1) SRC_PATTERNS += socketpool/% endif +ifeq ($(CIRCUITPY_SPITARGET),1) +SRC_PATTERNS += spitarget/% +endif ifeq ($(CIRCUITPY_SSL),1) SRC_PATTERNS += ssl/% endif @@ -387,6 +423,12 @@ endif ifeq ($(CIRCUITPY_FONTIO),1) SRC_PATTERNS += fontio/% endif +ifeq ($(CIRCUITPY_LVFONTIO),1) +SRC_PATTERNS += lvfontio/% +endif +ifeq ($(CIRCUITPY_TILEPALETTEMAPPER),1) +SRC_PATTERNS += tilepalettemapper/% +endif ifeq ($(CIRCUITPY_TIME),1) SRC_PATTERNS += time/% endif @@ -411,6 +453,9 @@ endif ifeq ($(CIRCUITPY_USB_VIDEO),1) SRC_PATTERNS += usb_video/% endif +ifeq ($(CIRCUITPY_USB_AUDIO),1) +SRC_PATTERNS += usb_audio/% +endif ifeq ($(CIRCUITPY_USB_HOST),1) SRC_PATTERNS += usb_host/% endif @@ -438,6 +483,9 @@ endif ifeq ($(CIRCUITPY_WIFI),1) SRC_PATTERNS += wifi/% endif +ifeq ($(CIRCUITPY_WIZNET),1) +SRC_PATTERNS += wiznet/% +endif ifeq ($(CIRCUITPY_ZLIB),1) SRC_PATTERNS += zlib/% endif @@ -469,6 +517,8 @@ SRC_COMMON_HAL_ALL = \ audiobusio/I2SOut.c \ audiobusio/PDMIn.c \ audiobusio/__init__.c \ + audioi2sin/I2SIn.c \ + audioi2sin/__init__.c \ audioio/AudioOut.c \ audioio/__init__.c \ audiopwmio/PWMAudioOut.c \ @@ -502,6 +552,8 @@ SRC_COMMON_HAL_ALL = \ i2ctarget/I2CTarget.c \ i2ctarget/__init__.c \ max3421e/Max3421E.c \ + mcp4822/__init__.c \ + mcp4822/MCP4822.c \ memorymap/__init__.c \ memorymap/AddressRange.c \ microcontroller/__init__.c \ @@ -510,6 +562,9 @@ SRC_COMMON_HAL_ALL = \ mdns/__init__.c \ mdns/Server.c \ mdns/RemoteService.c \ + mipidsi/Bus.c \ + mipidsi/Display.c \ + mipidsi/__init__.c \ neopixel_write/__init__.c \ nvm/ByteArray.c \ nvm/__init__.c \ @@ -522,6 +577,11 @@ SRC_COMMON_HAL_ALL = \ pulseio/__init__.c \ pwmio/PWMOut.c \ pwmio/__init__.c \ + qspibus/QSPIBus.c \ + qspibus/__init__.c \ + rclcpy/__init__.c \ + rclcpy/Node.c \ + rclcpy/Publisher.c \ rgbmatrix/RGBMatrix.c \ rgbmatrix/__init__.c \ rotaryio/IncrementalEncoder.c \ @@ -533,6 +593,8 @@ SRC_COMMON_HAL_ALL = \ socketpool/__init__.c \ socketpool/SocketPool.c \ socketpool/Socket.c \ + spitarget/SPITarget.c \ + spitarget/__init__.c \ usb_host/__init__.c \ usb_host/Port.c \ watchdog/WatchDogMode.c \ @@ -544,16 +606,28 @@ SRC_COMMON_HAL_ALL = \ wifi/ScannedNetworks.c \ wifi/__init__.c \ -ifeq ($(CIRCUITPY_BLEIO_HCI),1) -# Helper code for _bleio HCI. -SRC_C += \ - common-hal/_bleio/att.c \ - common-hal/_bleio/hci.c \ +SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL)) +ifeq ($(CIRCUITPY_BLEIO_HCI),1) +# HCI device-specific HAL and helper sources. +SRC_DEVICES_HAL += \ + _bleio/att.c \ + _bleio/hci.c \ + _bleio/Adapter.c \ + _bleio/Attribute.c \ + _bleio/Characteristic.c \ + _bleio/CharacteristicBuffer.c \ + _bleio/Connection.c \ + _bleio/Descriptor.c \ + _bleio/PacketBuffer.c \ + _bleio/Service.c \ + _bleio/UUID.c \ + _bleio/__init__.c +# HCI device-specific bindings. +SRC_DEVICES_BINDINGS += \ + supervisor/bluetooth.c endif -SRC_COMMON_HAL = $(filter $(SRC_PATTERNS), $(SRC_COMMON_HAL_ALL)) - # These don't have corresponding files in each port but are still located in # shared-bindings to make it clear what the contents of the modules are. # All possible sources are listed here, and are filtered by SRC_PATTERNS. @@ -568,6 +642,7 @@ $(filter $(SRC_PATTERNS), \ canio/Match.c \ codeop/__init__.c \ countio/Edge.c \ + digitalio/DigitalInOutProtocol.c \ digitalio/Direction.c \ digitalio/DriveMode.c \ digitalio/Pull.c \ @@ -588,8 +663,26 @@ $(filter $(SRC_PATTERNS), \ supervisor/StatusBar.c \ wifi/AuthMode.c \ wifi/Packet.c \ + wifi/PowerManagement.c \ ) +ifeq ($(CIRCUITPY_BLEIO_HCI),1) +# Common _bleio bindings used by HCI. +SRC_BINDINGS_ENUMS += \ + _bleio/Address.c \ + _bleio/Adapter.c \ + _bleio/Attribute.c \ + _bleio/Characteristic.c \ + _bleio/CharacteristicBuffer.c \ + _bleio/Connection.c \ + _bleio/Descriptor.c \ + _bleio/PacketBuffer.c \ + _bleio/ScanEntry.c \ + _bleio/Service.c \ + _bleio/UUID.c \ + _bleio/__init__.c +endif + ifeq ($(CIRCUITPY_SAFEMODE_PY),1) SRC_BINDINGS_ENUMS += \ supervisor/SafeModeReason.c @@ -617,6 +710,24 @@ SRC_SHARED_MODULE_ALL = \ audiocore/RawSample.c \ audiocore/WaveFile.c \ audiocore/__init__.c \ + audiospeed/Resampler.c \ + audiospeed/SpeedChanger.c \ + audiospeed/__init__.c \ + audiodelays/Echo.c \ + audiodelays/Chorus.c \ + audiodelays/Flanger.c \ + audiodelays/PitchShift.c \ + audiodelays/GranularPitchShift.c \ + audiodelays/MultiTapDelay.c \ + audiodelays/__init__.c \ + audiofilters/Distortion.c \ + audiofilters/Filter.c \ + audiofilters/Phaser.c \ + audiofilters/__init__.c \ + audiofreeverb/__init__.c \ + audiofreeverb/Freeverb.c \ + audiofilewriter/AudioFileWriter.c \ + audiofilewriter/__init__.c \ audioio/__init__.c \ audiomixer/Mixer.c \ audiomixer/MixerVoice.c \ @@ -652,9 +763,14 @@ SRC_SHARED_MODULE_ALL = \ dotclockframebuffer/__init__.c \ epaperdisplay/__init__.c \ epaperdisplay/EPaperDisplay.c \ + i2cioexpander/IOExpander.c \ + i2cioexpander/IOPin.c \ + i2cioexpander/__init__.c \ floppyio/__init__.c \ fontio/BuiltinFont.c \ fontio/__init__.c \ + lvfontio/OnDiskFont.c\ + lvfontio/__init__.c \ fourwire/__init__.c \ fourwire/FourWire.c \ framebufferio/FramebufferDisplay.c \ @@ -715,12 +831,15 @@ SRC_SHARED_MODULE_ALL = \ synthio/__init__.c \ terminalio/Terminal.c \ terminalio/__init__.c \ + tilepalettemapper/__init__.c \ + tilepalettemapper/TilePaletteMapper.c \ time/__init__.c \ traceback/__init__.c \ uheap/__init__.c \ usb/__init__.c \ usb/core/__init__.c \ usb/core/Device.c \ + usb/util/__init__.c \ ustack/__init__.c \ vectorio/Circle.c \ vectorio/Polygon.c \ @@ -734,6 +853,21 @@ SRC_SHARED_MODULE_ALL = \ # All possible sources are listed here, and are filtered by SRC_PATTERNS. SRC_SHARED_MODULE = $(filter $(SRC_PATTERNS), $(SRC_SHARED_MODULE_ALL)) +SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \ + $(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \ + $(addprefix common-hal/, $(SRC_COMMON_HAL)) \ + $(addprefix devices/ble_hci/common-hal/, $(SRC_DEVICES_HAL)) \ + $(addprefix devices/ble_hci/, $(SRC_DEVICES_BINDINGS)) + +SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE)) \ + $(addprefix shared-module/, $(SRC_SHARED_MODULE_INTERNAL)) + +# There may be duplicates between SRC_COMMON_HAL_EXPANDED and SRC_SHARED_MODULE_EXPANDED, +# because a few modules have files both in common-hal/ and shared-module/. +# Doing a $(sort ...) removes duplicates as part of sorting. +SRC_COMMON_HAL_SHARED_MODULE_EXPANDED = $(sort $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED)) + # Use the native touchio if requested. This flag is set conditionally in, say, mpconfigport.h. # The presence of common-hal/touchio/* does not imply it's available for all chips in a port, # so there is an explicit flag. For example, SAMD21 touchio is native, but SAMD51 is not. @@ -765,11 +899,15 @@ SRC_SHARED_MODULE_ALL += \ keypad_demux/DemuxKeyMatrix.c endif -# If supporting _bleio via HCI, make devices/ble_hci/common-hal/_bleio be includable, -# and use C source files in devices/ble_hci/common-hal. ifeq ($(CIRCUITPY_BLEIO_HCI),1) +# Add HCI device-specific includes to search path. INC += -I$(TOP)/devices/ble_hci -DEVICES_MODULES += $(TOP)/devices/ble_hci +# Add HCI shared modules to build. +SRC_SHARED_MODULE += \ + _bleio/Address.c \ + _bleio/Attribute.c \ + _bleio/ScanEntry.c \ + _bleio/ScanResults.c endif ifeq ($(CIRCUITPY_AUDIOMP3),1) @@ -810,15 +948,58 @@ $(BUILD)/lib/tjpgd/src/tjpgd.o: CFLAGS += -Wno-shadow -Wno-cast-align endif ifeq ($(CIRCUITPY_HASHLIB_MBEDTLS_ONLY),1) -SRC_MOD += $(addprefix lib/mbedtls/library/, \ - sha1.c \ - sha256.c \ - sha512.c \ - platform_util.c \ - ) +# mbedtls 4.x moved the crypto implementations out of lib/mbedtls/library into the +# tf-psa-crypto submodule and made the legacy mbedtls_sha256_*() headers private, so +# hashlib goes through the PSA hash API. That needs the PSA core, whose driver dispatch +# layer is generated rather than shipped -- see the same rule in ports/raspberrypi/Makefile. +SRC_MOD += \ + $(addprefix lib/mbedtls/tf-psa-crypto/core/, \ + psa_crypto.c \ + psa_crypto_client.c \ + psa_crypto_slot_management.c \ + psa_util.c \ + ) \ + $(addprefix lib/mbedtls/tf-psa-crypto/drivers/builtin/src/, \ + psa_crypto_hash.c \ + psa_util_internal.c \ + sha1.c \ + sha256.c \ + ) \ + $(addprefix lib/mbedtls/tf-psa-crypto/platform/, \ + platform.c \ + platform_util.c \ + ) \ + lib/mbedtls/tf-psa-crypto/utilities/constant_time.c \ + lib/mbedtls_config/hashlib_psa_port.c + +MBEDTLS_HASHLIB_GEN := $(BUILD)/tf-psa-crypto +MBEDTLS_HASHLIB_WRAPPERS_H := $(MBEDTLS_HASHLIB_GEN)/psa_crypto_driver_wrappers.h +MBEDTLS_HASHLIB_WRAPPERS_C := $(MBEDTLS_HASHLIB_GEN)/psa_crypto_driver_wrappers_no_static.c +SRC_MOD += $(MBEDTLS_HASHLIB_WRAPPERS_C:$(BUILD)/%=%) + +# The script writes both files at once; naming both as targets would run it twice. +$(MBEDTLS_HASHLIB_WRAPPERS_C): $(MBEDTLS_HASHLIB_WRAPPERS_H) + @true + +$(MBEDTLS_HASHLIB_WRAPPERS_H): $(TOP)/lib/mbedtls/tf-psa-crypto/scripts/generate_driver_wrappers.py + $(STEPECHO) "GEN $@" + $(Q)mkdir -p $(MBEDTLS_HASHLIB_GEN) + $(Q)PYTHONPATH=$(TOP)/lib/mbedtls/framework/scripts $(PYTHON) $< $(MBEDTLS_HASHLIB_GEN) + +# psa_crypto.c and friends #include the generated header. +$(addprefix $(BUILD)/, $(SRC_MOD:.c=.o)): $(MBEDTLS_HASHLIB_WRAPPERS_H) + CFLAGS += \ - -isystem $(TOP)/lib/mbedtls/include \ - -DMBEDTLS_CONFIG_FILE='"$(TOP)/lib/mbedtls_config/mbedtls_config_hashlib.h"' \ + -I$(MBEDTLS_HASHLIB_GEN) \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/include \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/drivers/builtin/include \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/drivers/builtin/src \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/core \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/dispatch \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/extras \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/platform \ + -isystem $(TOP)/lib/mbedtls/tf-psa-crypto/utilities \ + -DTF_PSA_CRYPTO_CONFIG_FILE='"$(TOP)/lib/mbedtls_config/tf_psa_crypto_config_hashlib.h"' \ endif @@ -855,15 +1036,9 @@ SRC_SHARED_MODULE_INTERNAL = \ $(filter $(SRC_PATTERNS), \ displayio/bus_core.c \ displayio/display_core.c \ - os/getenv.c \ usb/utf16le.c \ ) -SRC_COMMON_HAL_INTERNAL = \ -$(filter $(SRC_PATTERNS), \ - _bleio/ \ -) - ifeq ($(INTERNAL_LIBM),1) SRC_LIBM = \ $(addprefix lib/,\ @@ -906,7 +1081,6 @@ endif # Sources used in all ports except unix. SRC_CIRCUITPY_COMMON = \ - shared/libc/string0.c \ shared/readline/readline.c \ lib/oofatfs/ff.c \ lib/oofatfs/ffunicode.c \ @@ -918,9 +1092,13 @@ SRC_CIRCUITPY_COMMON = \ shared/runtime/stdout_helpers.c \ shared/runtime/sys_stdio_mphal.c +ifeq ($(CIRCUITPY_LIBC_STRING0),1) +SRC_CIRCUITPY_COMMON += shared/libc/string0.c +endif + ifeq ($(CIRCUITPY_QRIO),1) SRC_CIRCUITPY_COMMON += lib/quirc/lib/decode.c lib/quirc/lib/identify.c lib/quirc/lib/quirc.c lib/quirc/lib/version_db.c -$(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h +$(BUILD)/lib/quirc/lib/%.o: CFLAGS += -Wno-type-limits -Wno-shadow -Wno-sign-compare -include shared-module/qrio/quirc_alloc.h endif ifdef LD_TEMPLATE_FILE diff --git a/py/circuitpy_mkenv.mk b/py/circuitpy_mkenv.mk index 7bdf943a14d..6416d6bd19c 100644 --- a/py/circuitpy_mkenv.mk +++ b/py/circuitpy_mkenv.mk @@ -43,6 +43,10 @@ ifneq ($(VALID_BOARD),) include boards/$(BOARD)/mpconfigboard.mk endif +# user-specific settings that mpconfigport does not override +# (i.e. mpconfigport.mk uses "foo ?= bar") +-include user_pre_mpconfigport.mk + # Port-specific include mpconfigport.mk @@ -52,6 +56,10 @@ ifneq ($(VALID_BOARD),) include $(TOP)/py/circuitpy_mpconfig.mk endif +# user-specific overrides of hard-coded settings +# (i.e. xxx.mk uses "foo = bar") +-include user_post_mpconfigport.mk + # qstr definitions (must come before including py.mk) QSTR_DEFS = qstrdefsport.h @@ -62,3 +70,6 @@ include $(TOP)/supervisor/supervisor.mk # Include make rules and variables common across CircuitPython builds. include $(TOP)/py/circuitpy_defns.mk + +# user specific +-include user_post_circuitpy_defns.mk diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index adb881ebac2..58d7fe74ea6 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -17,10 +17,8 @@ // Always 1: defined in circuitpy_mpconfig.mk // #define CIRCUITPY (1) -// Can be removed once CircuitPython 10 is released. -// Print warnings or not about deprecated names. See objmodule.c. -#ifndef CIRCUITPY_8_9_WARNINGS -#define CIRCUITPY_8_9_WARNINGS (0) +#ifndef MP_SSIZE_MAX +#define MP_SSIZE_MAX (0x7fffffff) #endif // REPR_C encodes qstrs, 31-bit ints, and 30-bit floats in a single 32-bit word. @@ -43,14 +41,23 @@ extern void common_hal_mcu_enable_interrupts(void); // MicroPython-only options not used by CircuitPython, but present in various files // inherited from MicroPython, especially in extmod/ #define MICROPY_ENABLE_DYNRUNTIME (0) +#define MICROPY_HW_ENABLE_USB (0) #define MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE (0) #define MICROPY_PY_BLUETOOTH (0) #define MICROPY_PY_LWIP_SLIP (0) #define MICROPY_PY_OS_DUPTERM (0) +#define MICROPY_PYEXEC_COMPILE_ONLY (0) #define MICROPY_ROM_TEXT_COMPRESSION (0) #define MICROPY_VFS_LFS1 (0) #define MICROPY_VFS_LFS2 (0) +// Always turn on exit code handling +#define MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING (1) + +#ifndef MICROPY_GCREGS_SETJMP +#define MICROPY_GCREGS_SETJMP (0) +#endif + // Sorted alphabetically for easy finding. // // default is 128; consider raising to reduce fragmentation. @@ -68,9 +75,12 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_EMIT_X64 (0) #define MICROPY_ENABLE_DOC_STRING (0) #define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_ENABLE_SELECTIVE_COLLECT (1) #define MICROPY_ENABLE_GC (1) #define MICROPY_ENABLE_PYSTACK (1) -#define MICROPY_TRACKED_ALLOC (CIRCUITPY_SSL_MBEDTLS) +// mbedtls allocates through m_tracked_calloc/m_tracked_free. hashlib-only ports need +// them too as of mbedtls 4.x: hashlib uses mbedtls_md_*(), which allocates on the heap. +#define MICROPY_TRACKED_ALLOC (CIRCUITPY_SSL_MBEDTLS || CIRCUITPY_HASHLIB_MBEDTLS_ONLY) #define MICROPY_ENABLE_SOURCE_LINE (1) #define MICROPY_EPOCH_IS_1970 (1) #define MICROPY_ERROR_REPORTING (CIRCUITPY_FULL_BUILD ? MICROPY_ERROR_REPORTING_NORMAL : MICROPY_ERROR_REPORTING_TERSE) @@ -88,11 +98,11 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_MEM_STATS (0) #define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_MODULE_BUILTIN_SUBPACKAGES (1) -#define MICROPY_NONSTANDARD_TYPECODES (0) #define MICROPY_OPT_COMPUTED_GOTO (1) #define MICROPY_OPT_COMPUTED_GOTO_SAVE_SPACE (CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE) #define MICROPY_OPT_LOAD_ATTR_FAST_PATH (CIRCUITPY_OPT_LOAD_ATTR_FAST_PATH) #define MICROPY_OPT_MAP_LOOKUP_CACHE (CIRCUITPY_OPT_MAP_LOOKUP_CACHE) +#define MICROPY_OPT_MPZ_BITWISE (0) #define MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE (CIRCUITPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE) #define MICROPY_PERSISTENT_CODE_LOAD (1) @@ -140,13 +150,20 @@ extern void common_hal_mcu_enable_interrupts(void); #define MICROPY_PY_RE (CIRCUITPY_RE) // Supplanted by shared-bindings/struct #define MICROPY_PY_STRUCT (0) +#define MICROPY_PY_STRUCT_UNSAFE_TYPECODES (0) #define MICROPY_PY_SYS (CIRCUITPY_SYS) #define MICROPY_PY_SYS_MAXSIZE (1) #define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_UCTYPES (0) #define MICROPY_PY___FILE__ (1) +#if CIRCUITPY_FULL_BUILD +#ifndef MICROPY_QSTR_BYTES_IN_HASH #define MICROPY_QSTR_BYTES_IN_HASH (1) +#endif +#else +#define MICROPY_QSTR_BYTES_IN_HASH (0) +#endif #define MICROPY_REPL_AUTO_INDENT (1) #define MICROPY_REPL_EVENT_DRIVEN (0) #define MICROPY_STACK_CHECK (1) @@ -186,21 +203,6 @@ extern void common_hal_mcu_enable_interrupts(void); // Track stack usage. Expose results via ustack module. #define MICROPY_MAX_STACK_USAGE (0) -#define UINT_FMT "%u" -#define INT_FMT "%d" -#ifdef __LP64__ -typedef long mp_int_t; // must be pointer size -typedef unsigned long mp_uint_t; // must be pointer size -#else -// These are definitions for machines where sizeof(int) == sizeof(void*), -// regardless of actual size. -typedef int mp_int_t; // must be pointer size -typedef unsigned int mp_uint_t; // must be pointer size -#endif -#if __GNUC__ >= 10 // on recent gcc versions we can check that this is so -_Static_assert(sizeof(mp_int_t) == sizeof(void *)); -_Static_assert(sizeof(mp_uint_t) == sizeof(void *)); -#endif typedef long mp_off_t; #define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len) @@ -224,31 +226,60 @@ typedef long mp_off_t; // Turning off FULL_BUILD removes some functionality to reduce flash size on tiny SAMD21s #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD) + #ifndef MICROPY_CPYTHON_COMPAT #define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD) #endif + #ifndef MICROPY_CPYTHON_EXCEPTION_CHAIN #define MICROPY_CPYTHON_EXCEPTION_CHAIN (CIRCUITPY_FULL_BUILD) #endif + #define MICROPY_PY_BUILTINS_POW3 (CIRCUITPY_BUILTINS_POW3) #define MICROPY_PY_FSTRINGS (1) #define MICROPY_MODULE_WEAK_LINKS (0) #define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD) + #ifndef MICROPY_PY_BUILTINS_COMPLEX #define MICROPY_PY_BUILTINS_COMPLEX (CIRCUITPY_FULL_BUILD) #endif + #define MICROPY_PY_BUILTINS_FROZENSET (CIRCUITPY_FULL_BUILD) + +#ifndef MICROPY_PY_BUILTINS_NOTIMPLEMENTED +#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (CIRCUITPY_FULL_BUILD) +#endif + #define MICROPY_PY_BUILTINS_STR_CENTER (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_BUILTINS_STR_PARTITION (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_BUILTINS_STR_SPLITLINES (CIRCUITPY_FULL_BUILD) + #ifndef MICROPY_PY_COLLECTIONS_ORDEREDDICT #define MICROPY_PY_COLLECTIONS_ORDEREDDICT (CIRCUITPY_FULL_BUILD) #endif + #ifndef MICROPY_PY_COLLECTIONS_DEQUE #define MICROPY_PY_COLLECTIONS_DEQUE (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_COLLECTIONS_DEQUE_ITER (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_COLLECTIONS_DEQUE_SUBSCR (CIRCUITPY_FULL_BUILD) #endif + +#ifndef MICROPY_PY_DELATTR_SETATTR +#define MICROPY_PY_DELATTR_SETATTR (CIRCUITPY_FULL_BUILD) +#endif + +#ifndef MICROPY_PY_DOUBLE_TYPECODE +#define MICROPY_PY_DOUBLE_TYPECODE (CIRCUITPY_FULL_BUILD ? 1 : 0) +#endif + +#ifndef MICROPY_PY_FUNCTION_ATTRS +#define MICROPY_PY_FUNCTION_ATTRS (CIRCUITPY_FULL_BUILD) +#endif + +#ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS +#define MICROPY_PY_REVERSE_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD) +#endif + #define MICROPY_PY_RE_MATCH_GROUPS (CIRCUITPY_RE) #define MICROPY_PY_RE_MATCH_SPAN_START_END (CIRCUITPY_RE) #define MICROPY_PY_RE_SUB (CIRCUITPY_RE) @@ -271,28 +302,33 @@ typedef long mp_off_t; #ifdef LONGINT_IMPL_MPZ #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) -#define MP_SSIZE_MAX (0x7fffffff) #endif #ifdef LONGINT_IMPL_LONGLONG #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_LONGLONG) -#define MP_SSIZE_MAX (0x7fffffff) #endif #ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS #define MICROPY_PY_REVERSE_SPECIAL_METHODS (CIRCUITPY_ULAB || CIRCUITPY_FULL_BUILD) #endif -#if INTERNAL_FLASH_FILESYSTEM == 0 && QSPI_FLASH_FILESYSTEM == 0 && SPI_FLASH_FILESYSTEM == 0 && !DISABLE_FILESYSTEM +#if !defined(__ZEPHYR__) && INTERNAL_FLASH_FILESYSTEM == 0 && QSPI_FLASH_FILESYSTEM == 0 && SPI_FLASH_FILESYSTEM == 0 && !DISABLE_FILESYSTEM #error No *_FLASH_FILESYSTEM set! #endif // Default board buses. +#ifndef CIRCUITPY_MUTABLE_BOARD +#define CIRCUITPY_MUTABLE_BOARD (0) +#endif + #ifndef CIRCUITPY_BOARD_I2C #if defined(DEFAULT_I2C_BUS_SCL) && defined(DEFAULT_I2C_BUS_SDA) #define CIRCUITPY_BOARD_I2C (1) #define CIRCUITPY_BOARD_I2C_PIN {{.scl = DEFAULT_I2C_BUS_SCL, .sda = DEFAULT_I2C_BUS_SDA}} +#ifndef CIRCUITPY_BOARD_I2C_SPEED +#define CIRCUITPY_BOARD_I2C_SPEED (100000) +#endif #else #define CIRCUITPY_BOARD_I2C (0) #endif @@ -317,6 +353,9 @@ typedef long mp_off_t; #endif +// For easy debugging printf's. +#define PLAT_PRINTF(...) mp_printf(&mp_plat_print, __VA_ARGS__) + #if MICROPY_PY_ASYNC_AWAIT && !CIRCUITPY_TRACEBACK #error CIRCUITPY_ASYNCIO requires CIRCUITPY_TRACEBACK #endif @@ -329,8 +368,19 @@ typedef long mp_off_t; #ifndef CIRCUITPY_CONSOLE_UART_BAUDRATE #define CIRCUITPY_CONSOLE_UART_BAUDRATE (115200) #endif +#if !defined(CIRCUITPY_CONSOLE_UART_PRINTF) +#define CIRCUITPY_CONSOLE_UART_PRINTF(...) mp_printf(&console_uart_print, __VA_ARGS__) +#endif +#if !defined(CIRCUITPY_CONSOLE_UART_HEXDUMP) +#define CIRCUITPY_CONSOLE_UART_HEXDUMP(pfx, buf, len) print_hexdump(&console_uart_print, pfx, (const uint8_t *)buf, len) +#endif +#if !defined(CIRCUITPY_CONSOLE_UART_TIMESTAMP) +#define CIRCUITPY_CONSOLE_UART_TIMESTAMP (0) +#endif #else #define CIRCUITPY_CONSOLE_UART (0) +#define CIRCUITPY_CONSOLE_UART_PRINTF(...) (void)0 +#define CIRCUITPY_CONSOLE_UART_HEXDUMP(...) (void)0 #endif // These CIRCUITPY_xxx values should all be defined in the *.mk files as being on or off. @@ -341,9 +391,11 @@ typedef long mp_off_t; #define CIRCUITPY_DISPLAY_LIMIT (1) #endif -// Framebuffer area size in bytes. Rounded down to power of four for alignment. +// Display area buffer size in bytes for _refresh_area() VLA. +// Allocated on stack; boards with larger displays can override per-board. +// Default 512 bytes = 128 uint32_t words. #ifndef CIRCUITPY_DISPLAY_AREA_BUFFER_SIZE -#define CIRCUITPY_DISPLAY_AREA_BUFFER_SIZE (128) +#define CIRCUITPY_DISPLAY_AREA_BUFFER_SIZE (512) #endif #else @@ -414,6 +466,7 @@ void background_callback_run_all(void); #define MICROPY_VM_HOOK_LOOP RUN_BACKGROUND_TASKS; #define MICROPY_VM_HOOK_RETURN RUN_BACKGROUND_TASKS; +#define MICROPY_INTERNAL_EVENT_HOOK (RUN_BACKGROUND_TASKS) // CIRCUITPY_AUTORELOAD_DELAY_MS = 0 will completely disable autoreload. #ifndef CIRCUITPY_AUTORELOAD_DELAY_MS @@ -425,7 +478,7 @@ void background_callback_run_all(void); #endif #ifndef CIRCUITPY_PYSTACK_SIZE -#define CIRCUITPY_PYSTACK_SIZE 1536 +#define CIRCUITPY_PYSTACK_SIZE 2048 #endif // The VM heap starts at this size and doubles in size as needed until it runs @@ -474,6 +527,18 @@ void background_callback_run_all(void); // USB settings +#ifndef CIRCUITPY_SDCARD_USB +#if CIRCUITPY_USB_DEVICE +#define CIRCUITPY_SDCARD_USB (CIRCUITPY_SDCARDIO && CIRCUITPY_USB_MSC) +#else +#define CIRCUITPY_SDCARD_USB (0) +#endif +#endif + +#if CIRCUITPY_SDCARD_USB && !(CIRCUITPY_SDCARDIO) +#error CIRCUITPY_SDCARD_USB requires CIRCUITPY_SDCARDIO +#endif + // Debug level for TinyUSB. Only outputs over debug UART so it doesn't cause // additional USB logging. #ifndef CIRCUITPY_DEBUG_TINYUSB @@ -484,10 +549,18 @@ void background_callback_run_all(void); #define CIRCUITPY_USB_DEVICE_INSTANCE 0 #endif +#ifndef CIRCUITPY_USB_DEVICE_HIGH_SPEED +#define CIRCUITPY_USB_DEVICE_HIGH_SPEED 0 +#endif + #ifndef CIRCUITPY_USB_HOST_INSTANCE #define CIRCUITPY_USB_HOST_INSTANCE -1 #endif +#ifndef CIRCUITPY_USB_HOST_HIGH_SPEED +#define CIRCUITPY_USB_HOST_HIGH_SPEED 0 +#endif + // If the port requires certain USB endpoint numbers, define these in mpconfigport.h. #ifndef USB_CDC_EP_NUM_NOTIFICATION @@ -587,7 +660,7 @@ void background_callback_run_all(void); // Align the internal sector buffer. Useful when it is passed into TinyUSB for // loads. #ifndef MICROPY_FATFS_WINDOW_ALIGNMENT -#define MICROPY_FATFS_WINDOW_ALIGNMENT CIRCUITPY_TUSB_MEM_ALIGN +#define MICROPY_FATFS_WINDOW_ALIGNMENT 64 // Espressif is strictest #endif #define FF_FS_CASE_INSENSITIVE_COMPARISON_ASCII_ONLY (1) @@ -599,3 +672,32 @@ void background_callback_run_all(void); // Enable compiler functionality. #define MICROPY_ENABLE_COMPILER (1) #define MICROPY_PY_BUILTINS_COMPILE (1) + +#ifndef CIRCUITPY_MIN_GCC_VERSION +#define CIRCUITPY_MIN_GCC_VERSION 14 +#endif + +#ifndef CIRCUITPY_SAVES_PARTITION_SIZE +#define CIRCUITPY_SAVES_PARTITION_SIZE 0 +#endif + +// Boards that have a boot button connected to a GPIO pin should set +// CIRCUITPY_BOOT_BUTTON_NO_GPIO to 1. +#ifndef CIRCUITPY_BOOT_BUTTON_NO_GPIO +#define CIRCUITPY_BOOT_BUTTON_NO_GPIO (0) +#endif +#if defined(CIRCUITPY_BOOT_BUTTON) && CIRCUITPY_BOOT_BUTTON_NO_GPIO +#error "CIRCUITPY_BOOT_BUTTON and CIRCUITPY_BOOT_BUTTON_NO_GPIO are mutually exclusive" +#endif + +#if defined(__GNUC__) && !defined(__ZEPHYR__) +#if __GNUC__ < CIRCUITPY_MIN_GCC_VERSION +// (the 3 level scheme here is required to get expansion & stringization +// correct) +#define DO_PRAGMA(x) _Pragma(#x) +#define DO_ERROR_HELPER(x) DO_PRAGMA(GCC error #x) +#define DO_ERROR(x) DO_ERROR_HELPER(Minimum GCC version x \ + -- older versions are known to miscompile CircuitPython) +DO_ERROR(CIRCUITPY_MIN_GCC_VERSION); +#endif +#endif diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk old mode 100644 new mode 100755 index 81d46270f8f..e4e01fcecc8 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -62,6 +62,15 @@ CFLAGS += -DCIRCUITPY_FULL_BUILD=$(CIRCUITPY_FULL_BUILD) # increased build time CIRCUITPY_MESSAGE_COMPRESSION_LEVEL ?= 9 +# By default, use our copy of TLSF. Some vendor SDKs may provide their own +# implementation of TLSF, which can be used instead by setting CIRCUITPY_LIB_TLSF=0. +CIRCUITPY_LIB_TLSF ?= 1 + +# By default, use our copy of string0 (memcpy and friends) because it is optimized. Some vendor SDKs +# or ROMs may provide their own implementation of string0, which can be used instead by setting +# CIRCUITPY_LIBC_STRING0=0. +CIRCUITPY_LIBC_STRING0 ?= 1 + # Reduce the size of in-flash properties. Requires support in the .ld linker # file, so not enabled by default. CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 0 @@ -95,9 +104,18 @@ CFLAGS += -DCIRCUITPY_AESIO=$(CIRCUITPY_AESIO) CIRCUITPY_ALARM ?= 0 CFLAGS += -DCIRCUITPY_ALARM=$(CIRCUITPY_ALARM) +# Whether `alarm.exit_and_deep_sleep_until_alarms()` supports `preserve_dios`. +CIRCUITPY_ALARM_PRESERVE_DIOS ?= 0 +CFLAGS += -DCIRCUITPY_ALARM_PRESERVE_DIOS=$(CIRCUITPY_ALARM_PRESERVE_DIOS) + CIRCUITPY_ALARM_TOUCH ?= $(CIRCUITPY_ALARM) CFLAGS += -DCIRCUITPY_ALARM_TOUCH=$(CIRCUITPY_ALARM_TOUCH) +# Enable DMA buffer management for platforms where not all memory is DMA-capable +# Platforms with PSRAM or other non-DMA memory should set this to 0 +CIRCUITPY_ALL_MEMORY_DMA_CAPABLE ?= 1 +CFLAGS += -DCIRCUITPY_ALL_MEMORY_DMA_CAPABLE=$(CIRCUITPY_ALL_MEMORY_DMA_CAPABLE) + CIRCUITPY_ANALOGBUFIO ?= 0 CFLAGS += -DCIRCUITPY_ANALOGBUFIO=$(CIRCUITPY_ANALOGBUFIO) @@ -121,6 +139,10 @@ CFLAGS += -DCIRCUITPY_AUDIOBUSIO_I2SOUT=$(CIRCUITPY_AUDIOBUSIO_I2SOUT) CIRCUITPY_AUDIOBUSIO_PDMIN ?= $(CIRCUITPY_AUDIOBUSIO) CFLAGS += -DCIRCUITPY_AUDIOBUSIO_PDMIN=$(CIRCUITPY_AUDIOBUSIO_PDMIN) +# I2S audio input (separate core module `audioi2sin`). +CIRCUITPY_AUDIOI2SIN ?= 0 +CFLAGS += -DCIRCUITPY_AUDIOI2SIN=$(CIRCUITPY_AUDIOI2SIN) + CIRCUITPY_AUDIOIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_AUDIOIO=$(CIRCUITPY_AUDIOIO) @@ -141,6 +163,20 @@ CFLAGS += -DCIRCUITPY_AUDIOCORE_DEBUG=$(CIRCUITPY_AUDIOCORE_DEBUG) CIRCUITPY_AUDIOMP3 ?= $(call enable-if-all,$(CIRCUITPY_FULL_BUILD) $(CIRCUITPY_AUDIOCORE)) CFLAGS += -DCIRCUITPY_AUDIOMP3=$(CIRCUITPY_AUDIOMP3) +CIRCUITPY_AUDIOSPEED ?= 0 +CFLAGS += -DCIRCUITPY_AUDIOSPEED=$(CIRCUITPY_AUDIOSPEED) + +CIRCUITPY_AUDIOEFFECTS ?= 0 +CIRCUITPY_AUDIODELAYS ?= $(CIRCUITPY_AUDIOEFFECTS) +CFLAGS += -DCIRCUITPY_AUDIODELAYS=$(CIRCUITPY_AUDIODELAYS) +CIRCUITPY_AUDIOFILTERS ?= $(CIRCUITPY_AUDIOEFFECTS) +CFLAGS += -DCIRCUITPY_AUDIOFILTERS=$(CIRCUITPY_AUDIOFILTERS) +CIRCUITPY_AUDIOFREEVERB ?= $(CIRCUITPY_AUDIOEFFECTS) +CFLAGS += -DCIRCUITPY_AUDIOFREEVERB=$(CIRCUITPY_AUDIOFREEVERB) + +CIRCUITPY_AUDIOFILEWRITER ?= 0 +CFLAGS += -DCIRCUITPY_AUDIOFILEWRITER=$(CIRCUITPY_AUDIOFILEWRITER) + CIRCUITPY_AURORA_EPAPER ?= 0 CFLAGS += -DCIRCUITPY_AURORA_EPAPER=$(CIRCUITPY_AURORA_EPAPER) @@ -156,12 +192,19 @@ CFLAGS += -DCIRCUITPY_BITBANGIO=$(CIRCUITPY_BITBANGIO) CIRCUITPY_BITOPS ?= 0 CFLAGS += -DCIRCUITPY_BITOPS=$(CIRCUITPY_BITOPS) -# _bleio can be supported on most any board via HCI +# _bleio defaults to HCI serial for all full builds. CIRCUITPY_BLEIO_HCI ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_BLEIO_HCI=$(CIRCUITPY_BLEIO_HCI) -# Explicitly enabled for boards that support _bleio. -CIRCUITPY_BLEIO ?= $(CIRCUITPY_BLEIO_HCI) +# Native (i.e., on SoC or board) BLE support is off by default. +CIRCUITPY_BLEIO_NATIVE ?= 0 +CFLAGS += -DCIRCUITPY_BLEIO_NATIVE=$(CIRCUITPY_BLEIO_NATIVE) + +ifeq ($(CIRCUITPY_BLEIO_HCI)$(CIRCUITPY_BLEIO_NATIVE),11) +$(error "CIRCUITPY_BLEIO_HCI and CIRCUITPY_BLEIO_NATIVE cannot both be enabled") +endif + +CIRCUITPY_BLEIO ?= $(call enable-if-any,$(CIRCUITPY_BLEIO_HCI) $(CIRCUITPY_BLEIO_NATIVE)) CFLAGS += -DCIRCUITPY_BLEIO=$(CIRCUITPY_BLEIO) CIRCUITPY_BLE_FILE_SERVICE ?= 0 @@ -212,6 +255,12 @@ CFLAGS += -DCIRCUITPY_CYW43=$(CIRCUITPY_CYW43) CIRCUITPY_DIGITALIO ?= 1 CFLAGS += -DCIRCUITPY_DIGITALIO=$(CIRCUITPY_DIGITALIO) +# Enable the DigitalInOut protocol on the native DigitalInOut type. +# This allows other C code to use DigitalInOut objects polymorphically. +# Disable on small builds to save space. +CIRCUITPY_DIGITALINOUT_PROTOCOL ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_DIGITALINOUT_PROTOCOL=$(CIRCUITPY_DIGITALINOUT_PROTOCOL) + CIRCUITPY_COPROC ?= 0 CFLAGS += -DCIRCUITPY_COPROC=$(CIRCUITPY_COPROC) @@ -227,6 +276,10 @@ CFLAGS += -DCIRCUITPY_BUSDISPLAY=$(CIRCUITPY_BUSDISPLAY) CIRCUITPY_FOURWIRE ?= $(CIRCUITPY_DISPLAYIO) CFLAGS += -DCIRCUITPY_FOURWIRE=$(CIRCUITPY_FOURWIRE) +# QSPI bus protocol for quad-SPI displays (like RM690B0) +CIRCUITPY_QSPIBUS ?= 0 +CFLAGS += -DCIRCUITPY_QSPIBUS=$(CIRCUITPY_QSPIBUS) + CIRCUITPY_EPAPERDISPLAY ?= $(CIRCUITPY_DISPLAYIO) CFLAGS += -DCIRCUITPY_EPAPERDISPLAY=$(CIRCUITPY_EPAPERDISPLAY) @@ -260,9 +313,6 @@ CFLAGS += -DCIRCUITPY_DUALBANK=$(CIRCUITPY_DUALBANK) CIRCUITPY_ENABLE_MPY_NATIVE ?= 0 CFLAGS += -DCIRCUITPY_ENABLE_MPY_NATIVE=$(CIRCUITPY_ENABLE_MPY_NATIVE) -CIRCUITPY_OS_GETENV ?= $(CIRCUITPY_FULL_BUILD) -CFLAGS += -DCIRCUITPY_OS_GETENV=$(CIRCUITPY_OS_GETENV) - CIRCUITPY_ERRNO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ERRNO=$(CIRCUITPY_ERRNO) @@ -314,9 +364,15 @@ CFLAGS += -DCIRCUITPY_HASHLIB_MBEDTLS=$(CIRCUITPY_HASHLIB_MBEDTLS) CIRCUITPY_HASHLIB_MBEDTLS_ONLY ?= $(call enable-if-all,$(CIRCUITPY_HASHLIB_MBEDTLS) $(call enable-if-not,$(CIRCUITPY_SSL))) CFLAGS += -DCIRCUITPY_HASHLIB_MBEDTLS_ONLY=$(CIRCUITPY_HASHLIB_MBEDTLS_ONLY) +# Always zero because it is for Zephyr only +CFLAGS += -DCIRCUITPY_HOSTNETWORK=0 + CIRCUITPY_I2CTARGET ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_I2CTARGET=$(CIRCUITPY_I2CTARGET) +CIRCUITPY_I2CIOEXPANDER ?= 0 +CFLAGS += -DCIRCUITPY_I2CIOEXPANDER=$(CIRCUITPY_I2CIOEXPANDER) + CIRCUITPY_IMAGECAPTURE ?= 0 CFLAGS += -DCIRCUITPY_IMAGECAPTURE=$(CIRCUITPY_IMAGECAPTURE) @@ -364,6 +420,9 @@ CFLAGS += -DCIRCUITPY_MATH=$(CIRCUITPY_MATH) CIRCUITPY_MAX3421E ?= 0 CFLAGS += -DCIRCUITPY_MAX3421E=$(CIRCUITPY_MAX3421E) +CIRCUITPY_MDNS ?= $(CIRCUITPY_WIFI) +CFLAGS += -DCIRCUITPY_MDNS=$(CIRCUITPY_MDNS) + CIRCUITPY_MEMORYMAP ?= 0 CFLAGS += -DCIRCUITPY_MEMORYMAP=$(CIRCUITPY_MEMORYMAP) @@ -373,8 +432,8 @@ CFLAGS += -DCIRCUITPY_MEMORYMONITOR=$(CIRCUITPY_MEMORYMONITOR) CIRCUITPY_MICROCONTROLLER ?= 1 CFLAGS += -DCIRCUITPY_MICROCONTROLLER=$(CIRCUITPY_MICROCONTROLLER) -CIRCUITPY_MDNS ?= $(CIRCUITPY_WIFI) -CFLAGS += -DCIRCUITPY_MDNS=$(CIRCUITPY_MDNS) +CIRCUITPY_MIPIDSI ?= 0 +CFLAGS += -DCIRCUITPY_MIPIDSI=$(CIRCUITPY_MIPIDSI) CIRCUITPY_MSGPACK ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_MSGPACK=$(CIRCUITPY_MSGPACK) @@ -411,6 +470,9 @@ CFLAGS += -DCIRCUITPY_PIXELBUF=$(CIRCUITPY_PIXELBUF) CIRCUITPY_PIXELMAP ?= $(CIRCUITPY_PIXELBUF) CFLAGS += -DCIRCUITPY_PIXELMAP=$(CIRCUITPY_PIXELMAP) +CIRCUITPY_PORT_SERIAL ?= 0 +CFLAGS += -DCIRCUITPY_PORT_SERIAL=$(CIRCUITPY_PORT_SERIAL) + # Only for SAMD boards for the moment CIRCUITPY_PS2IO ?= 0 CFLAGS += -DCIRCUITPY_PS2IO=$(CIRCUITPY_PS2IO) @@ -436,6 +498,9 @@ CFLAGS += -DCIRCUITPY_RAINBOWIO=$(CIRCUITPY_RAINBOWIO) CIRCUITPY_RANDOM ?= 1 CFLAGS += -DCIRCUITPY_RANDOM=$(CIRCUITPY_RANDOM) +CIRCUITPY_RCLCPY ?= 0 +CFLAGS += -DCIRCUITPY_RCLCPY=$(CIRCUITPY_RCLCPY) + CIRCUITPY_RE ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_RE=$(CIRCUITPY_RE) @@ -482,12 +547,15 @@ CFLAGS += -DCIRCUITPY_SDCARDIO=$(CIRCUITPY_SDCARDIO) CIRCUITPY_SDIOIO ?= 0 CFLAGS += -DCIRCUITPY_SDIOIO=$(CIRCUITPY_SDIOIO) -CIRCUITPY_SERIAL_BLE ?= 0 -CFLAGS += -DCIRCUITPY_SERIAL_BLE=$(CIRCUITPY_SERIAL_BLE) +CIRCUITPY_BLE_SERIAL_SERVICE ?= 0 +CFLAGS += -DCIRCUITPY_BLE_SERIAL_SERVICE=$(CIRCUITPY_BLE_SERIAL_SERVICE) CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY?= 0 CFLAGS += -DCIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY=$(CIRCUITPY_SETTABLE_PROCESSOR_FREQUENCY) +CIRCUITPY_SETTINGS_TOML ?= $(CIRCUITPY_FULL_BUILD) +CFLAGS += -DCIRCUITPY_SETTINGS_TOML=$(CIRCUITPY_SETTINGS_TOML) + CIRCUITPY_SHARPDISPLAY ?= $(CIRCUITPY_FRAMEBUFFERIO) CFLAGS += -DCIRCUITPY_SHARPDISPLAY=$(CIRCUITPY_SHARPDISPLAY) @@ -499,6 +567,9 @@ CFLAGS += -DCIRCUITPY_SKIP_SAFE_MODE_WAIT=$(CIRCUITPY_SKIP_SAFE_MODE_WAIT) CIRCUITPY_SOCKETPOOL ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_SOCKETPOOL=$(CIRCUITPY_SOCKETPOOL) +CIRCUITPY_SPITARGET ?= 0 +CFLAGS += -DCIRCUITPY_SPITARGET=$(CIRCUITPY_SPITARGET) + CIRCUITPY_SOCKETPOOL_IPV6 ?= 0 CFLAGS += -DCIRCUITPY_SOCKETPOOL_IPV6=$(CIRCUITPY_SOCKETPOOL_IPV6) @@ -540,9 +611,18 @@ CFLAGS += -DCIRCUITPY_SYS=$(CIRCUITPY_SYS) CIRCUITPY_TERMINALIO ?= $(CIRCUITPY_DISPLAYIO) CFLAGS += -DCIRCUITPY_TERMINALIO=$(CIRCUITPY_TERMINALIO) -CIRCUITPY_FONTIO ?= $(call enable-if-all,$(CIRCUITPY_DISPLAYIO) $(CIRCUITPY_TERMINALIO)) +CIRCUITPY_TERMINALIO_VT100 ?= $(CIRCUITPY_TERMINALIO) +CFLAGS += -DCIRCUITPY_TERMINALIO_VT100=$(CIRCUITPY_TERMINALIO_VT100) + +CIRCUITPY_FONTIO ?= $(CIRCUITPY_TERMINALIO) CFLAGS += -DCIRCUITPY_FONTIO=$(CIRCUITPY_FONTIO) +CIRCUITPY_LVFONTIO ?= $(CIRCUITPY_TERMINALIO) +CFLAGS += -DCIRCUITPY_LVFONTIO=$(CIRCUITPY_LVFONTIO) + +CIRCUITPY_TILEPALETTEMAPPER ?= $(CIRCUITPY_DISPLAYIO) +CFLAGS += -DCIRCUITPY_TILEPALETTEMAPPER=$(CIRCUITPY_TILEPALETTEMAPPER) + CIRCUITPY_TIME ?= 1 CFLAGS += -DCIRCUITPY_TIME=$(CIRCUITPY_TIME) @@ -601,6 +681,9 @@ CFLAGS += -DCIRCUITPY_USB_HID_ENABLED_DEFAULT=$(CIRCUITPY_USB_HID_ENABLED_DEFAUL CIRCUITPY_USB_VIDEO ?= 0 CFLAGS += -DCIRCUITPY_USB_VIDEO=$(CIRCUITPY_USB_VIDEO) +CIRCUITPY_USB_AUDIO ?= 0 +CFLAGS += -DCIRCUITPY_USB_AUDIO=$(CIRCUITPY_USB_AUDIO) + CIRCUITPY_USB_HOST ?= 0 CFLAGS += -DCIRCUITPY_USB_HOST=$(CIRCUITPY_USB_HOST) @@ -644,6 +727,9 @@ CFLAGS += -DCIRCUITPY_USB_KEYBOARD_WORKFLOW=$(CIRCUITPY_USB_KEYBOARD_WORKFLOW) CIRCUITPY_USTACK ?= 0 CFLAGS += -DCIRCUITPY_USTACK=$(CIRCUITPY_USTACK) +# Zephyr display integration is only built by ports/zephyr-cp. +CFLAGS += -DCIRCUITPY_ZEPHYR_DISPLAY=0 + # for decompressing utilities CIRCUITPY_ZLIB ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_ZLIB=$(CIRCUITPY_ZLIB) @@ -671,15 +757,15 @@ CFLAGS += -DCIRCUITPY_WATCHDOG=$(CIRCUITPY_WATCHDOG) CIRCUITPY_WIFI ?= 0 CFLAGS += -DCIRCUITPY_WIFI=$(CIRCUITPY_WIFI) +CIRCUITPY_WIZNET ?= 0 +CFLAGS += -DCIRCUITPY_WIZNET=$(CIRCUITPY_WIZNET) + CIRCUITPY_WEB_WORKFLOW ?= $(CIRCUITPY_WIFI) CFLAGS += -DCIRCUITPY_WEB_WORKFLOW=$(CIRCUITPY_WEB_WORKFLOW) CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS?= 1 CFLAGS += -DCIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS=$(CIRCUITPY_WIFI_RADIO_SETTABLE_MAC_ADDRESS) -CIRCUITPY_WIFI_RADIO_SETTABLE_LISTEN_INTERVAL?= 0 -CFLAGS += -DCIRCUITPY_WIFI_RADIO_SETTABLE_LISTEN_INTERVAL=$(CIRCUITPY_WIFI_RADIO_SETTABLE_LISTEN_INTERVAL) - # tinyusb port tailored configuration CIRCUITPY_TUSB_MEM_ALIGN ?= 4 CFLAGS += -DCIRCUITPY_TUSB_MEM_ALIGN=$(CIRCUITPY_TUSB_MEM_ALIGN) @@ -691,6 +777,10 @@ CFLAGS += -DCIRCUITPY_TUSB_ATTR_USBRAM=$(CIRCUITPY_TUSB_ATTR_USBRAM) CIRCUITPY_SWO_TRACE ?= 0 CFLAGS += -DCIRCUITPY_SWO_TRACE=$(CIRCUITPY_SWO_TRACE) +# Check for a minimum GCC version during build (set to 0 to disable) +CIRCUITPY_MIN_GCC_VERSION ?= 14 +CFLAGS += -DCIRCUITPY_MIN_GCC_VERSION=$(CIRCUITPY_MIN_GCC_VERSION) + # Define an equivalent for MICROPY_LONGINT_IMPL, to pass to $(MPY-TOOL) in py/mkrules.mk # $(MPY-TOOL) needs to know what kind of longint to use (if any) to freeze long integers. # This should correspond to the MICROPY_LONGINT_IMPL definition in mpconfigport.h. diff --git a/py/compile.c b/py/compile.c index 085c342605d..c8704131234 100644 --- a/py/compile.c +++ b/py/compile.c @@ -102,6 +102,9 @@ static const emit_method_table_t *emit_native_table[] = { &emit_native_thumb_method_table, &emit_native_xtensa_method_table, &emit_native_xtensawin_method_table, + &emit_native_rv32_method_table, + NULL, + &emit_native_debug_method_table, }; #elif MICROPY_EMIT_NATIVE @@ -118,6 +121,10 @@ static const emit_method_table_t *emit_native_table[] = { #define NATIVE_EMITTER(f) emit_native_xtensa_##f #elif MICROPY_EMIT_XTENSAWIN #define NATIVE_EMITTER(f) emit_native_xtensawin_##f +#elif MICROPY_EMIT_RV32 +#define NATIVE_EMITTER(f) emit_native_rv32_##f +#elif MICROPY_EMIT_NATIVE_DEBUG +#define NATIVE_EMITTER(f) emit_native_debug_##f #else #error "unknown native emitter" #endif @@ -141,6 +148,7 @@ static const emit_inline_asm_method_table_t *emit_asm_table[] = { &emit_inline_thumb_method_table, &emit_inline_xtensa_method_table, NULL, + &emit_inline_rv32_method_table, }; #elif MICROPY_EMIT_INLINE_ASM @@ -151,6 +159,9 @@ static const emit_inline_asm_method_table_t *emit_asm_table[] = { #elif MICROPY_EMIT_INLINE_XTENSA #define ASM_DECORATOR_QSTR MP_QSTR_asm_xtensa #define ASM_EMITTER(f) emit_inline_xtensa_##f +#elif MICROPY_EMIT_INLINE_RV32 +#define ASM_DECORATOR_QSTR MP_QSTR_asm_rv32 +#define ASM_EMITTER(f) emit_inline_rv32_##f #else #error "unknown asm emitter" #endif @@ -849,6 +860,8 @@ static bool compile_built_in_decorator(compiler_t *comp, size_t name_len, mp_par *emit_options = MP_EMIT_OPT_ASM; } else if (attr == MP_QSTR_asm_xtensa) { *emit_options = MP_EMIT_OPT_ASM; + } else if (attr == MP_QSTR_asm_rv32) { + *emit_options = MP_EMIT_OPT_ASM; #else } else if (attr == ASM_DECORATOR_QSTR) { *emit_options = MP_EMIT_OPT_ASM; @@ -1894,19 +1907,7 @@ static void compile_async_with_stmt_helper(compiler_t *comp, size_t n, mp_parse_ // Handle case 1: call __aexit__ // Stack: (..., ctx_mgr) - EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); // to tell end_finally there's no exception - EMIT(rot_two); - EMIT_ARG(jump, l_aexit_no_exc); // jump to code below to call __aexit__ - - // Start of "finally" block - // At this point we have case 2 or 3, we detect which one by the TOS being an exception or not - EMIT_ARG(label_assign, l_finally_block); - - // Detect if TOS an exception or not - EMIT(dup_top); - EMIT_LOAD_GLOBAL(MP_QSTR_BaseException); - EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH); - EMIT_ARG(pop_jump_if, false, l_ret_unwind_jump); // if not an exception then we have case 3 + EMIT_ARG(async_with_setup_finally, l_aexit_no_exc, l_finally_block, l_ret_unwind_jump); // Handle case 2: call __aexit__ and either swallow or re-raise the exception // Stack: (..., ctx_mgr, exc) @@ -1932,6 +1933,7 @@ static void compile_async_with_stmt_helper(compiler_t *comp, size_t n, mp_parse_ EMIT_ARG(pop_jump_if, false, l_end); EMIT(pop_top); // pop exception EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); // replace with None to swallow exception + // Stack: (..., None) EMIT_ARG(jump, l_end); EMIT_ARG(adjust_stack_size, 2); @@ -1941,6 +1943,8 @@ static void compile_async_with_stmt_helper(compiler_t *comp, size_t n, mp_parse_ EMIT(rot_three); EMIT(rot_three); EMIT_ARG(label_assign, l_aexit_no_exc); + // We arrive here from either case 1 (a jump) or case 3 (fall through) + // Stack: case 1: (..., None, ctx_mgr) or case 3: (..., X, INT, ctx_mgr) EMIT_ARG(load_method, MP_QSTR___aexit__, false); EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); EMIT(dup_top); @@ -1948,6 +1952,7 @@ static void compile_async_with_stmt_helper(compiler_t *comp, size_t n, mp_parse_ EMIT_ARG(call_method, 3, 0, 0); compile_yield_from(comp); EMIT(pop_top); + // Stack: case 1: (..., None) or case 3: (..., X, INT) EMIT_ARG(adjust_stack_size, -1); // End of "finally" block @@ -3291,7 +3296,9 @@ static void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind } // check structure of parse node - assert(MP_PARSE_NODE_IS_STRUCT(pns2->nodes[0])); + if (!MP_PARSE_NODE_IS_STRUCT(pns2->nodes[0])) { + goto not_an_instruction; + } if (!MP_PARSE_NODE_IS_NULL(pns2->nodes[1])) { goto not_an_instruction; } @@ -3481,7 +3488,7 @@ static void scope_compute_things(scope_t *scope) { } } -#if !MICROPY_PERSISTENT_CODE_SAVE +#if !MICROPY_EXPOSE_MP_COMPILE_TO_RAW_CODE static #endif void mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_compiled_module_t *cm) { @@ -3583,6 +3590,13 @@ void mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool case MP_EMIT_OPT_NATIVE_PYTHON: case MP_EMIT_OPT_VIPER: if (emit_native == NULL) { + // The check looks like this to work around a false + // warning in GCC 13 (and possibly later), where it + // assumes that the check will always fail. + if ((uintptr_t)NATIVE_EMITTER_TABLE == (uintptr_t)NULL) { + comp->compile_error = mp_obj_new_exception_msg(&mp_type_NotImplementedError, MP_ERROR_TEXT("cannot emit native code for this architecture")); + goto emit_finished; + } emit_native = NATIVE_EMITTER(new)(&comp->emit_common, &comp->compile_error, &comp->next_label, max_num_labels); } comp->emit_method_table = NATIVE_EMITTER_TABLE; @@ -3615,6 +3629,10 @@ void mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool } } + #if MICROPY_EMIT_NATIVE +emit_finished: + #endif + if (comp->compile_error != MP_OBJ_NULL) { // if there is no line number for the error then use the line // number for the start of this scope diff --git a/py/compile.h b/py/compile.h index f9970a521d6..64afc487d7c 100644 --- a/py/compile.h +++ b/py/compile.h @@ -30,6 +30,9 @@ #include "py/parse.h" #include "py/emitglue.h" +// Whether mp_compile_to_raw_code is exposed as a public function. +#define MICROPY_EXPOSE_MP_COMPILE_TO_RAW_CODE (MICROPY_PY_BUILTINS_CODE >= MICROPY_PY_BUILTINS_CODE_BASIC || MICROPY_PERSISTENT_CODE_SAVE) + #if MICROPY_COMP_ALLOW_TOP_LEVEL_AWAIT // set to `true` to allow top-level await expressions extern bool mp_compile_allow_top_level_await; @@ -40,7 +43,7 @@ extern bool mp_compile_allow_top_level_await; // mp_globals_get() will be used for the context mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl); -#if MICROPY_PERSISTENT_CODE_SAVE +#if MICROPY_EXPOSE_MP_COMPILE_TO_RAW_CODE // this has the same semantics as mp_compile void mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl, mp_compiled_module_t *cm); #endif diff --git a/py/cstack.c b/py/cstack.c new file mode 100644 index 00000000000..fe4b16d652a --- /dev/null +++ b/py/cstack.c @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Paul Sokolovsky + * Copryight (c) 2024 Angus Gratton + * + * 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. + */ + +#include "py/runtime.h" +#include "py/cstack.h" + +void mp_cstack_init_with_sp_here(size_t stack_size) { + #if __GNUC__ >= 13 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdangling-pointer" + #endif + volatile int stack_dummy; + mp_cstack_init_with_top((void *)&stack_dummy, stack_size); + #if __GNUC__ >= 13 + #pragma GCC diagnostic pop + #endif +} + +mp_uint_t mp_cstack_usage(void) { + // Assumes descending stack + volatile int stack_dummy; + return MP_STATE_THREAD(stack_top) - (char *)&stack_dummy; +} + +#if MICROPY_STACK_CHECK + +void mp_cstack_check(void) { + if (mp_cstack_usage() >= MP_STATE_THREAD(stack_limit)) { + mp_raise_recursion_depth(); + } +} + +#endif // MICROPY_STACK_CHECK diff --git a/py/cstack.h b/py/cstack.h new file mode 100644 index 00000000000..bcd919d31f9 --- /dev/null +++ b/py/cstack.h @@ -0,0 +1,63 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2014 Paul Sokolovsky + * Copyright (c) 2024 Angus Gratton + * + * 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. + */ +#ifndef MICROPY_INCLUDED_PY_CSTACK_H +#define MICROPY_INCLUDED_PY_CSTACK_H + +#include "py/mpstate.h" + +// Both init functions below accept the full stack size. Set the +// MICROPY_STACK_CHECK_MARGIN to the number of bytes subtracted to account +// for stack usage between checks. + +void mp_cstack_init_with_sp_here(size_t stack_size); + +static inline void mp_cstack_init_with_top(void *top, size_t stack_size) { + MP_STATE_THREAD(stack_top) = (char *)top; + + #if MICROPY_STACK_CHECK + assert(stack_size > MICROPY_STACK_CHECK_MARGIN); // Should be enforced by port + MP_STATE_THREAD(stack_limit) = stack_size - MICROPY_STACK_CHECK_MARGIN; + #else + (void)stack_size; + #endif +} + +mp_uint_t mp_cstack_usage(void); + +#if MICROPY_STACK_CHECK + +void mp_cstack_check(void); + +#else + +static inline void mp_cstack_check(void) { + // No-op when stack checking is disabled +} + +#endif + +#endif // MICROPY_INCLUDED_PY_CSTACK_H diff --git a/py/dynruntime.h b/py/dynruntime.h index 44f6d05ccb6..9eea5ca6e5c 100644 --- a/py/dynruntime.h +++ b/py/dynruntime.h @@ -28,6 +28,14 @@ // This header file contains definitions to dynamically implement the static // MicroPython runtime API defined in py/obj.h and py/runtime.h. +// +// All of the symbols made available in this header are overriding those defined +// in py/obj.h and py/runtime.h. This is done with macros. For macros that +// would be too complicated (usually more than a single expression), they call a +// static-inline function for the implementation. This function has the same +// name as the macro (hence the same name as a public API function) but with +// "_dyn" appended. For example, the m_malloc() macro calls the m_malloc_dyn() +// static-inline function. #include "py/binary.h" #include "py/nativeglue.h" @@ -39,6 +47,10 @@ #error "dynruntime.h included in non-dynamic-module build." #endif +#if MICROPY_MALLOC_USES_ALLOCATED_SIZE +#error "MICROPY_MALLOC_USES_ALLOCATED_SIZE must be disable in a dynamic-module build." +#endif + #undef MP_ROM_QSTR #undef MP_OBJ_QSTR_VALUE #undef MP_OBJ_NEW_QSTR @@ -52,13 +64,32 @@ /******************************************************************************/ // Memory allocation +#define m_malloc_fail(num_bytes) (m_malloc_fail_dyn((num_bytes))) #define m_malloc(n) (m_malloc_dyn((n))) #define m_free(ptr) (m_free_dyn((ptr))) #define m_realloc(ptr, new_num_bytes) (m_realloc_dyn((ptr), (new_num_bytes))) +#define m_realloc_maybe(ptr, new_num_bytes, allow_move) (m_realloc_maybe_dyn((ptr), (new_num_bytes), (allow_move))) + +static MP_NORETURN inline void m_malloc_fail_dyn(size_t num_bytes) { + mp_fun_table.raise_msg_str( + mp_fun_table.load_global(MP_QSTR_MemoryError), + "memory allocation failed"); +} + +static inline void *m_realloc_maybe_dyn(void *ptr, size_t new_num_bytes, bool allow_move) { + return mp_fun_table.realloc_(ptr, new_num_bytes, allow_move); +} + +static inline void *m_realloc_checked_dyn(void *ptr, size_t new_num_bytes, bool allow_move) { + ptr = m_realloc_maybe(ptr, new_num_bytes, allow_move); + if (ptr == NULL && new_num_bytes != 0) { + m_malloc_fail(new_num_bytes); + } + return ptr; +} static inline void *m_malloc_dyn(size_t n) { - // TODO won't raise on OOM - return mp_fun_table.realloc_(NULL, n, false); + return m_realloc_checked_dyn(NULL, n, false); } static inline void m_free_dyn(void *ptr) { @@ -66,8 +97,7 @@ static inline void m_free_dyn(void *ptr) { } static inline void *m_realloc_dyn(void *ptr, size_t new_num_bytes) { - // TODO won't raise on OOM - return mp_fun_table.realloc_(ptr, new_num_bytes, true); + return m_realloc_checked_dyn(ptr, new_num_bytes, true); } /******************************************************************************/ @@ -259,7 +289,7 @@ static inline void *mp_obj_malloc_helper_dyn(size_t num_bytes, const mp_obj_type #define nlr_raise(o) (mp_raise_dyn(o)) #define mp_raise_type_arg(type, arg) (mp_raise_dyn(mp_obj_new_exception_arg1_dyn((type), (arg)))) -// CIRCUITPY-CHANGE: use str +// CIRCUITPY-CHANGE: use mp_raise_msg_str #define mp_raise_msg(type, msg) (mp_fun_table.raise_msg_str((type), (msg))) #define mp_raise_OSError(er) (mp_raise_OSError_dyn(er)) #define mp_raise_NotImplementedError(msg) (mp_raise_msg(&mp_type_NotImplementedError, (msg))) @@ -271,14 +301,14 @@ static inline mp_obj_t mp_obj_new_exception_arg1_dyn(const mp_obj_type_t *exc_ty return mp_call_function_n_kw(MP_OBJ_FROM_PTR(exc_type), 1, 0, &args[0]); } -static NORETURN inline void mp_raise_dyn(mp_obj_t o) { +static MP_NORETURN inline void mp_raise_dyn(mp_obj_t o) { mp_fun_table.raise(o); for (;;) { } } // CIRCUITPY-CHANGE: new routine -static NORETURN inline void mp_raise_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { +static MP_NORETURN inline void mp_raise_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { mp_fun_table.raise(mp_obj_new_exception_arg1_dyn(exc_type, arg)); for (;;) { } diff --git a/py/dynruntime.mk b/py/dynruntime.mk index 62db43ad149..030728cfc9a 100644 --- a/py/dynruntime.mk +++ b/py/dynruntime.mk @@ -29,15 +29,18 @@ CFLAGS += -Wall -Werror -DNDEBUG CFLAGS += -DNO_QSTR CFLAGS += -DMICROPY_ENABLE_DYNRUNTIME CFLAGS += -DMP_CONFIGFILE='<$(CONFIG_H)>' -CFLAGS += -fpic -fno-common -CFLAGS += -U _FORTIFY_SOURCE # prevent use of __*_chk libc functions -#CFLAGS += -fdata-sections -ffunction-sections + +CFLAGS_ARCH += -fpic -fno-common +CFLAGS_ARCH += -U_FORTIFY_SOURCE # prevent use of __*_chk libc functions +#CFLAGS_ARCH += -fdata-sections -ffunction-sections MPY_CROSS_FLAGS += -march=$(ARCH) SRC_O += $(addprefix $(BUILD)/, $(patsubst %.c,%.o,$(filter %.c,$(SRC))) $(patsubst %.S,%.o,$(filter %.S,$(SRC)))) SRC_MPY += $(addprefix $(BUILD)/, $(patsubst %.py,%.mpy,$(filter %.py,$(SRC)))) +CLEAN_EXTRA += $(MOD).mpy .mpy_ld_cache + ################################################################################ # Architecture configuration @@ -45,66 +48,133 @@ ifeq ($(ARCH),x86) # x86 CROSS = -CFLAGS += -m32 -fno-stack-protector +CFLAGS_ARCH += -m32 -fno-stack-protector MICROPY_FLOAT_IMPL ?= double else ifeq ($(ARCH),x64) # x64 CROSS = -CFLAGS += -fno-stack-protector +CFLAGS_ARCH += -fno-stack-protector MICROPY_FLOAT_IMPL ?= double else ifeq ($(ARCH),armv6m) # thumb CROSS = arm-none-eabi- -CFLAGS += -mthumb -mcpu=cortex-m0 -MICROPY_FLOAT_IMPL ?= none +CFLAGS_ARCH += -mthumb -mcpu=cortex-m0 +MICROPY_FLOAT_IMPL ?= float else ifeq ($(ARCH),armv7m) # thumb CROSS = arm-none-eabi- -CFLAGS += -mthumb -mcpu=cortex-m3 -MICROPY_FLOAT_IMPL ?= none +CFLAGS_ARCH += -mthumb -mcpu=cortex-m3 +MICROPY_FLOAT_IMPL ?= float else ifeq ($(ARCH),armv7emsp) # thumb CROSS = arm-none-eabi- -CFLAGS += -mthumb -mcpu=cortex-m4 -CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=hard +CFLAGS_ARCH += -mthumb -mcpu=cortex-m4 +CFLAGS_ARCH += -mfpu=fpv4-sp-d16 -mfloat-abi=hard MICROPY_FLOAT_IMPL ?= float else ifeq ($(ARCH),armv7emdp) # thumb CROSS = arm-none-eabi- -CFLAGS += -mthumb -mcpu=cortex-m7 -CFLAGS += -mfpu=fpv5-d16 -mfloat-abi=hard +CFLAGS_ARCH += -mthumb -mcpu=cortex-m7 +CFLAGS_ARCH += -mfpu=fpv5-d16 -mfloat-abi=hard MICROPY_FLOAT_IMPL ?= double else ifeq ($(ARCH),xtensa) # xtensa CROSS = xtensa-lx106-elf- -CFLAGS += -mforce-l32 +CFLAGS_ARCH += -mforce-l32 MICROPY_FLOAT_IMPL ?= none else ifeq ($(ARCH),xtensawin) # xtensawin CROSS = xtensa-esp32-elf- -CFLAGS += MICROPY_FLOAT_IMPL ?= float +else ifeq ($(ARCH),rv32imc) + +# rv32imc +CROSS = riscv64-unknown-elf- +CFLAGS_ARCH += -march=rv32imac -mabi=ilp32 -mno-relax +# If Picolibc is available then select it explicitly. Ubuntu 22.04 ships its +# bare metal RISC-V toolchain with Picolibc rather than Newlib, and the default +# is "nosys" so a value must be provided. To avoid having per-distro +# workarounds, always select Picolibc if available. +PICOLIBC_SPECS := $(shell $(CROSS)gcc --print-file-name=picolibc.specs) +ifneq ($(PICOLIBC_SPECS),picolibc.specs) +CFLAGS_ARCH += -specs=$(PICOLIBC_SPECS) +USE_PICOLIBC := 1 +PICOLIBC_ARCH := rv32imac +PICOLIBC_ABI := ilp32 +endif + +MICROPY_FLOAT_IMPL ?= none + else $(error architecture '$(ARCH)' not supported) endif +ifneq ($(findstring -musl,$(shell $(CROSS)gcc -dumpmachine)),) +USE_MUSL := 1 +endif + MICROPY_FLOAT_IMPL_UPPER = $(shell echo $(MICROPY_FLOAT_IMPL) | tr '[:lower:]' '[:upper:]') -CFLAGS += -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_$(MICROPY_FLOAT_IMPL_UPPER) +CFLAGS += $(CFLAGS_ARCH) -DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_$(MICROPY_FLOAT_IMPL_UPPER) + +ifeq ($(LINK_RUNTIME),1) +# All of these picolibc-specific directives are here to work around a +# limitation of Ubuntu 22.04's RISC-V bare metal toolchain. In short, the +# specific version of GCC in use (10.2.0) does not seem to take into account +# extra paths provided by an explicitly passed specs file when performing name +# resolution via `--print-file-name`. +# +# If Picolibc is used and libc.a fails to resolve, then said file's path will +# be computed by searching the Picolibc libraries root for a libc.a file in a +# subdirectory whose path is built using the current `-march` and `-mabi` +# flags that are passed to GCC. The `PICOLIBC_ROOT` environment variable is +# checked to override the starting point for the library file search, and if +# it is not set then the default value is used, assuming that this is running +# on an Ubuntu 22.04 machine. +# +# This should be revised when the CI base image is updated to a newer Ubuntu +# version (that hopefully contains a newer RISC-V compiler) or to another Linux +# distribution. +ifeq ($(USE_PICOLIBC),1) +LIBM_NAME := libc.a +else ifeq ($(USE_MUSL),1) +LIBM_NAME := libc.a +else +LIBM_NAME := libm.a +endif +LIBGCC_PATH := $(realpath $(shell $(CROSS)gcc $(CFLAGS) --print-libgcc-file-name)) +LIBM_PATH := $(realpath $(shell $(CROSS)gcc $(CFLAGS) --print-file-name=$(LIBM_NAME))) +ifeq ($(USE_PICOLIBC),1) +ifeq ($(LIBM_PATH),) +# The CROSS toolchain prefix usually ends with a dash, but that may not be +# always the case. If the prefix ends with a dash it has to be taken out as +# Picolibc's architecture directory won't have it in its name. GNU Make does +# not have any facility to perform character-level text manipulation so we +# shell out to sed. +CROSS_PREFIX := $(shell echo $(CROSS) | sed -e 's/-$$//') +PICOLIBC_ROOT ?= /usr/lib/picolibc/$(CROSS_PREFIX)/lib +LIBM_PATH := $(PICOLIBC_ROOT)/$(PICOLIBC_ARCH)/$(PICOLIBC_ABI)/$(LIBM_NAME) +endif +endif +MPY_LD_FLAGS += $(addprefix -l, $(LIBGCC_PATH) $(LIBM_PATH)) +endif +ifneq ($(MPY_EXTERN_SYM_FILE),) +MPY_LD_FLAGS += --externs "$(realpath $(MPY_EXTERN_SYM_FILE))" +endif CFLAGS += $(CFLAGS_EXTRA) @@ -147,7 +217,7 @@ $(BUILD)/%.mpy: %.py # Build native .mpy from object files $(BUILD)/$(MOD).native.mpy: $(SRC_O) $(ECHO) "LINK $<" - $(Q)$(MPY_LD) --arch $(ARCH) --qstrs $(CONFIG_H) -o $@ $^ + $(Q)$(MPY_LD) --arch $(ARCH) --qstrs $(CONFIG_H) $(MPY_LD_FLAGS) -o $@ $^ # Build final .mpy from all intermediate .mpy files $(MOD).mpy: $(BUILD)/$(MOD).native.mpy $(SRC_MPY) diff --git a/py/emit.h b/py/emit.h index 26f978ba598..033ac9c763b 100644 --- a/py/emit.h +++ b/py/emit.h @@ -144,6 +144,9 @@ typedef struct _emit_method_table_t { void (*unwind_jump)(emit_t *emit, mp_uint_t label, mp_uint_t except_depth); void (*setup_block)(emit_t *emit, mp_uint_t label, int kind); void (*with_cleanup)(emit_t *emit, mp_uint_t label); + #if MICROPY_PY_ASYNC_AWAIT + void (*async_with_setup_finally)(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump); + #endif void (*end_finally)(emit_t *emit); void (*get_iter)(emit_t *emit, bool use_stack); void (*for_iter)(emit_t *emit, mp_uint_t label); @@ -201,6 +204,8 @@ extern const emit_method_table_t emit_native_thumb_method_table; extern const emit_method_table_t emit_native_arm_method_table; extern const emit_method_table_t emit_native_xtensa_method_table; extern const emit_method_table_t emit_native_xtensawin_method_table; +extern const emit_method_table_t emit_native_rv32_method_table; +extern const emit_method_table_t emit_native_debug_method_table; extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops; extern const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops; @@ -213,6 +218,8 @@ emit_t *emit_native_thumb_new(mp_emit_common_t *emit_common, mp_obj_t *error_slo emit_t *emit_native_arm_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); emit_t *emit_native_xtensa_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); emit_t *emit_native_xtensawin_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_native_rv32_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); +emit_t *emit_native_debug_new(mp_emit_common_t *emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels); void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels); @@ -223,6 +230,8 @@ void emit_native_thumb_free(emit_t *emit); void emit_native_arm_free(emit_t *emit); void emit_native_xtensa_free(emit_t *emit); void emit_native_xtensawin_free(emit_t *emit); +void emit_native_rv32_free(emit_t *emit); +void emit_native_debug_free(emit_t *emit); void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope); bool mp_emit_bc_end_pass(emit_t *emit); @@ -258,6 +267,9 @@ void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label); void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth); void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind); void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label); +#if MICROPY_PY_ASYNC_AWAIT +void mp_emit_bc_async_with_setup_finally(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump); +#endif void mp_emit_bc_end_finally(emit_t *emit); void mp_emit_bc_get_iter(emit_t *emit, bool use_stack); void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label); @@ -295,12 +307,15 @@ typedef struct _emit_inline_asm_method_table_t { void (*op)(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args); } emit_inline_asm_method_table_t; +extern const emit_inline_asm_method_table_t emit_inline_rv32_method_table; extern const emit_inline_asm_method_table_t emit_inline_thumb_method_table; extern const emit_inline_asm_method_table_t emit_inline_xtensa_method_table; +emit_inline_asm_t *emit_inline_rv32_new(mp_uint_t max_num_labels); emit_inline_asm_t *emit_inline_thumb_new(mp_uint_t max_num_labels); emit_inline_asm_t *emit_inline_xtensa_new(mp_uint_t max_num_labels); +void emit_inline_rv32_free(emit_inline_asm_t *emit); void emit_inline_thumb_free(emit_inline_asm_t *emit); void emit_inline_xtensa_free(emit_inline_asm_t *emit); diff --git a/py/emitbc.c b/py/emitbc.c index 05754cfabf6..0bcac8a1676 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -83,7 +83,8 @@ emit_t *emit_bc_new(mp_emit_common_t *emit_common) { void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels) { emit->max_num_labels = max_num_labels; - emit->label_offsets = m_new(size_t, emit->max_num_labels); + // CIRCUITPY-CHANGE: Don't collect the label offsets + emit->label_offsets = m_malloc_without_collect(sizeof(size_t) * emit->max_num_labels); } void emit_bc_free(emit_t *emit) { @@ -373,7 +374,8 @@ bool mp_emit_bc_end_pass(emit_t *emit) { // calculate size of total code-info + bytecode, in bytes emit->code_info_size = emit->code_info_offset; emit->bytecode_size = emit->bytecode_offset; - emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size); + // CIRCUITPY-CHANGE: Don't collect the bytecode or code info. + emit->code_base = m_malloc_without_collect(sizeof(byte) * (emit->code_info_size + emit->bytecode_size)); } else if (emit->pass == MP_PASS_EMIT) { // Code info and/or bytecode can shrink during this pass. @@ -666,6 +668,27 @@ void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) { mp_emit_bc_adjust_stack_size(emit, -4); } +#if MICROPY_PY_ASYNC_AWAIT +void mp_emit_bc_async_with_setup_finally(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump) { + // The async-with body has executed and no exception was raised, the execution fell through to this point. + // Stack: (..., ctx_mgr) + + // Finish async-with body and prepare to enter "finally" block. + mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE); // to tell end_finally there's no exception + mp_emit_bc_rot_two(emit); + mp_emit_bc_jump(emit, label_aexit_no_exc); // jump to code to call __aexit__ + + // Start of "finally" block which is entered via one of: an exception propagating out, a return, an unwind jump. + mp_emit_bc_label_assign(emit, label_finally_block); + + // Detect which case we have by the TOS being an exception or not. + mp_emit_bc_dup_top(emit); + mp_emit_bc_load_global(emit, MP_QSTR_BaseException, MP_EMIT_IDOP_GLOBAL_GLOBAL); + mp_emit_bc_binary_op(emit, MP_BINARY_OP_EXCEPTION_MATCH); + mp_emit_bc_pop_jump_if(emit, false, label_ret_unwind_jump); // if not an exception then we have return or unwind jump. +} +#endif + void mp_emit_bc_end_finally(emit_t *emit) { emit_write_bytecode_byte(emit, -1, MP_BC_END_FINALLY); } @@ -773,10 +796,10 @@ static void emit_bc_call_function_method_helper(emit_t *emit, int stack_adj, mp_ // each positional arg is one object, each kwarg is two objects, the key // and the value and one extra object for the star args bitmap. stack_adj -= (int)n_positional + 2 * (int)n_keyword + 1; - emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base + 1, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints? + emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base + 1, (n_keyword << 8) | n_positional); } else { stack_adj -= (int)n_positional + 2 * (int)n_keyword; - emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints? + emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base, (n_keyword << 8) | n_positional); } } @@ -862,6 +885,9 @@ const emit_method_table_t emit_bc_method_table = { mp_emit_bc_unwind_jump, mp_emit_bc_setup_block, mp_emit_bc_with_cleanup, + #if MICROPY_PY_ASYNC_AWAIT + mp_emit_bc_async_with_setup_finally, + #endif mp_emit_bc_end_finally, mp_emit_bc_get_iter, mp_emit_bc_for_iter, diff --git a/py/emitcommon.c b/py/emitcommon.c index a9eb6e2021f..1369c544c54 100644 --- a/py/emitcommon.c +++ b/py/emitcommon.c @@ -25,6 +25,7 @@ */ #include +#include #include "py/emit.h" #include "py/nativeglue.h" @@ -72,7 +73,25 @@ static bool strictly_equal(mp_obj_t a, mp_obj_t b) { } return true; } else { - return mp_obj_equal(a, b); + if (!mp_obj_equal(a, b)) { + return false; + } + #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_COMP_CONST_FLOAT + if (a_type == &mp_type_float) { + mp_float_t a_val = mp_obj_float_get(a); + // CIRCUITPY-CHANGE: ignore float equal warning + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + if (a_val == (mp_float_t)0.0) { + // Although 0.0 == -0.0, they are not strictly_equal and + // must be stored as two different constants in .mpy files + mp_float_t b_val = mp_obj_float_get(b); + return signbit(a_val) == signbit(b_val); + } + #pragma GCC diagnostic pop + } + #endif + return true; } } diff --git a/py/emitglue.c b/py/emitglue.c index 8ab624ee7cf..c6ad3e3bc38 100644 --- a/py/emitglue.c +++ b/py/emitglue.c @@ -32,6 +32,7 @@ #include #include "py/emitglue.h" +#include "py/mphal.h" #include "py/runtime0.h" #include "py/bc.h" #include "py/objfun.h" @@ -122,7 +123,7 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons #endif #elif MICROPY_EMIT_ARM #if (defined(__linux__) && defined(__GNUC__)) || __ARM_ARCH == 7 - __builtin___clear_cache((void *)fun_data, (uint8_t *)fun_data + fun_len); + __builtin___clear_cache((void *)fun_data, (char *)fun_data + fun_len); #elif defined(__arm__) // Flush I-cache and D-cache. asm volatile ( @@ -133,6 +134,9 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons "mcr p15, 0, r0, c7, c7, 0\n" // invalidate I-cache and D-cache : : : "r0", "cc"); #endif + #elif (MICROPY_EMIT_RV32 || MICROPY_EMIT_INLINE_RV32) && defined(MP_HAL_CLEAN_DCACHE) + // Flush the D-cache. + MP_HAL_CLEAN_DCACHE(fun_data, fun_len); #endif rc->kind = kind; @@ -168,7 +172,7 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, cons } DEBUG_printf("\n"); - #ifdef WRITE_CODE + #if WRITE_CODE FILE *fp_write_code = fopen("out-code", "wb"); fwrite(fun_data, fun_len, 1, fp_write_code); fclose(fp_write_code); diff --git a/py/emitinlinerv32.c b/py/emitinlinerv32.c new file mode 100644 index 00000000000..e81b152087d --- /dev/null +++ b/py/emitinlinerv32.c @@ -0,0 +1,767 @@ +/* + * This file is part of the MicroPython project, https://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +#include +#include +#include +#include +#include + +#include "py/emit.h" +#include "py/misc.h" + +#if MICROPY_EMIT_INLINE_RV32 + +#include "py/asmrv32.h" + +typedef enum { +// define rules with a compile function +#define DEF_RULE(rule, comp, kind, ...) PN_##rule, +#define DEF_RULE_NC(rule, kind, ...) + #include "py/grammar.h" +#undef DEF_RULE +#undef DEF_RULE_NC + PN_const_object, // special node for a constant, generic Python object +// define rules without a compile function +#define DEF_RULE(rule, comp, kind, ...) +#define DEF_RULE_NC(rule, kind, ...) PN_##rule, + #include "py/grammar.h" +#undef DEF_RULE +#undef DEF_RULE_NC +} pn_kind_t; + +struct _emit_inline_asm_t { + asm_rv32_t as; + uint16_t pass; + mp_obj_t *error_slot; + mp_uint_t max_num_labels; + qstr *label_lookup; +}; + +static const qstr_short_t REGISTERS_QSTR_TABLE[] = { + MP_QSTR_zero, MP_QSTR_ra, MP_QSTR_sp, MP_QSTR_gp, MP_QSTR_tp, MP_QSTR_t0, MP_QSTR_t1, MP_QSTR_t2, + MP_QSTR_s0, MP_QSTR_s1, MP_QSTR_a0, MP_QSTR_a1, MP_QSTR_a2, MP_QSTR_a3, MP_QSTR_a4, MP_QSTR_a5, + MP_QSTR_a6, MP_QSTR_a7, MP_QSTR_s2, MP_QSTR_s3, MP_QSTR_s4, MP_QSTR_s5, MP_QSTR_s6, MP_QSTR_s7, + MP_QSTR_s8, MP_QSTR_s9, MP_QSTR_s10, MP_QSTR_s11, MP_QSTR_t3, MP_QSTR_t4, MP_QSTR_t5, MP_QSTR_t6, + MP_QSTR_x0, MP_QSTR_x1, MP_QSTR_x2, MP_QSTR_x3, MP_QSTR_x4, MP_QSTR_x5, MP_QSTR_x6, MP_QSTR_x7, + MP_QSTR_x8, MP_QSTR_x9, MP_QSTR_x10, MP_QSTR_x11, MP_QSTR_x12, MP_QSTR_x13, MP_QSTR_x14, MP_QSTR_x15, + MP_QSTR_x16, MP_QSTR_x17, MP_QSTR_x18, MP_QSTR_x19, MP_QSTR_x20, MP_QSTR_x21, MP_QSTR_x22, MP_QSTR_x23, + MP_QSTR_x24, MP_QSTR_x25, MP_QSTR_x26, MP_QSTR_x27, MP_QSTR_x28, MP_QSTR_x29, MP_QSTR_x30, MP_QSTR_x31, +}; + +//////////////////////////////////////////////////////////////////////////////// + +static inline void emit_inline_rv32_error_msg(emit_inline_asm_t *emit, mp_rom_error_text_t msg) { + *emit->error_slot = mp_obj_new_exception_msg(&mp_type_SyntaxError, msg); +} + +static inline void emit_inline_rv32_error_exc(emit_inline_asm_t *emit, mp_obj_t exc) { + *emit->error_slot = exc; +} + +emit_inline_asm_t *emit_inline_rv32_new(mp_uint_t max_num_labels) { + emit_inline_asm_t *emit = m_new_obj(emit_inline_asm_t); + memset(&emit->as, 0, sizeof(emit->as)); + mp_asm_base_init(&emit->as.base, max_num_labels); + emit->max_num_labels = max_num_labels; + emit->label_lookup = m_new(qstr, max_num_labels); + return emit; +} + +void emit_inline_rv32_free(emit_inline_asm_t *emit) { + m_del(qstr, emit->label_lookup, emit->max_num_labels); + mp_asm_base_deinit(&emit->as.base, false); + m_del_obj(emit_inline_asm_t, emit); +} + +static void emit_inline_rv32_start_pass(emit_inline_asm_t *emit, pass_kind_t pass, mp_obj_t *error_slot) { + emit->pass = pass; + emit->error_slot = error_slot; + if (emit->pass == MP_PASS_CODE_SIZE) { + memset(emit->label_lookup, 0, emit->max_num_labels * sizeof(qstr)); + } + mp_asm_base_start_pass(&emit->as.base, pass == MP_PASS_EMIT ? MP_ASM_PASS_EMIT : MP_ASM_PASS_COMPUTE); +} + +static void emit_inline_rv32_end_pass(emit_inline_asm_t *emit, mp_uint_t type_sig) { + // c.jr ra + asm_rv32_opcode_cjr(&emit->as, ASM_RV32_REG_RA); + asm_rv32_end_pass(&emit->as); +} + +static bool parse_register_node(mp_parse_node_t node, mp_uint_t *register_number, bool compressed) { + assert(register_number != NULL && "Register number pointer is NULL."); + + if (!MP_PARSE_NODE_IS_ID(node)) { + return false; + } + + qstr node_qstr = MP_PARSE_NODE_LEAF_ARG(node); + for (mp_uint_t index = 0; index < MP_ARRAY_SIZE(REGISTERS_QSTR_TABLE); index++) { + if (node_qstr == REGISTERS_QSTR_TABLE[index]) { + mp_uint_t number = index % RV32_AVAILABLE_REGISTERS_COUNT; + if (!compressed || (compressed && RV32_IS_IN_C_REGISTER_WINDOW(number))) { + *register_number = compressed ? RV32_MAP_IN_C_REGISTER_WINDOW(number) : number; + return true; + } + break; + } + } + + return false; +} + +static mp_uint_t lookup_label(emit_inline_asm_t *emit, mp_parse_node_t node, qstr *qstring) { + assert(qstring && "qstring pointer is NULL"); + + *qstring = MP_PARSE_NODE_LEAF_ARG(node); + for (mp_uint_t label = 0; label < emit->max_num_labels; label++) { + if (emit->label_lookup[label] == *qstring) { + return label; + } + } + + return emit->max_num_labels; +} + +static inline ptrdiff_t label_code_offset(emit_inline_asm_t *emit, mp_uint_t label_index) { + return emit->as.base.label_offsets[label_index] - emit->as.base.code_offset; +} + +static mp_uint_t emit_inline_rv32_count_params(emit_inline_asm_t *emit, mp_uint_t parameters_count, mp_parse_node_t *parameter_nodes) { + // TODO: Raise this up to 8? RV32I has 8 A-registers that are meant to + // be used for passing arguments. + + if (parameters_count > 4) { + emit_inline_rv32_error_msg(emit, MP_ERROR_TEXT("can only have up to 4 parameters for RV32 assembly")); + return 0; + } + + mp_uint_t register_index = 0; + for (mp_uint_t index = 0; index < parameters_count; index++) { + bool valid_register = parse_register_node(parameter_nodes[index], ®ister_index, false); + if (!valid_register || (register_index != (ASM_RV32_REG_A0 + index))) { + emit_inline_rv32_error_msg(emit, MP_ERROR_TEXT("parameters must be registers in sequence a0 to a3")); + return 0; + } + } + + return parameters_count; +} + +static bool emit_inline_rv32_label(emit_inline_asm_t *emit, mp_uint_t label_num, qstr label_id) { + assert(label_num < emit->max_num_labels); + if (emit->pass == MP_PASS_CODE_SIZE) { + for (mp_uint_t index = 0; index < emit->max_num_labels; index++) { + if (emit->label_lookup[index] == label_id) { + return false; + } + } + } + emit->label_lookup[label_num] = label_id; + mp_asm_base_label_assign(&emit->as.base, label_num); + return true; +} + +typedef enum { + CALL_RRR, // Opcode Register, Register, Register + CALL_RR, // Opcode Register, Register + CALL_RRI, // Opcode Register, Register, Immediate + CALL_RRL, // Opcode Register, Register, Label + CALL_RI, // Opcode Register, Immediate + CALL_L, // Opcode Label + CALL_R, // Opcode Register + CALL_RL, // Opcode Register, Label + CALL_N, // Opcode + CALL_RII, // Opcode Register, Register, Immediate + CALL_RIR, // Opcode Register, Immediate(Register) + CALL_COUNT +} call_convention_t; + +#define N 0 // No argument +#define R 1 // Register +#define I 2 // Immediate +#define L 3 // Label +#define C (1 << 2) // Compressed register +#define U (1 << 2) // Unsigned immediate +#define Z (1 << 3) // Non-zero + +typedef void (*call_ri_t)(asm_rv32_t *state, mp_uint_t rd, mp_int_t immediate); +typedef void (*call_rri_t)(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_int_t immediate); +typedef void (*call_rii_t)(asm_rv32_t *state, mp_uint_t rd, mp_uint_t immediate1, mp_int_t immediate2); +typedef void (*call_rrr_t)(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs1, mp_uint_t rs2); +typedef void (*call_rr_t)(asm_rv32_t *state, mp_uint_t rd, mp_uint_t rs); +typedef void (*call_i_t)(asm_rv32_t *state, mp_int_t immediate); +typedef void (*call_r_t)(asm_rv32_t *state, mp_uint_t rd); +typedef void (*call_n_t)(asm_rv32_t *state); + +typedef struct _opcode_t { + qstr_short_t qstring; + uint16_t argument1_mask : 4; + uint16_t argument2_mask : 4; + uint16_t argument3_mask : 4; + uint16_t parse_nodes : 2; + // 2 bits available here + uint32_t calling_convention : 4; + uint32_t argument1_kind : 4; + uint32_t argument1_shift : 4; + uint32_t argument2_kind : 4; + uint32_t argument2_shift : 4; + uint32_t argument3_kind : 4; + uint32_t argument3_shift : 4; + uint32_t required_extensions : 1; + // 3 bits available here + void *emitter; +} opcode_t; + +#define opcode_li asm_rv32_emit_optimised_load_immediate + +static void opcode_la(asm_rv32_t *state, mp_uint_t rd, mp_int_t displacement) { + // This cannot be optimised for size, otherwise label addresses would move around. + mp_uint_t upper = (mp_uint_t)displacement & 0xFFFFF000; + mp_uint_t lower = (mp_uint_t)displacement & 0x00000FFF; + if ((lower & 0x800) != 0) { + upper += 0x1000; + } + asm_rv32_opcode_auipc(state, rd, upper); + asm_rv32_opcode_addi(state, rd, rd, lower); +} + +#define RC (R | C) +#define IU (I | U) +#define IZ (I | Z) +#define IUZ (I | U | Z) + +#define MASK_NOT_USED 0 + +enum { + MASK_FFFFFFFF, + MASK_00000FFF, + MASK_FFFFF000, + MASK_00001FFE, + MASK_0000001F, + MASK_FFFFFFFE, + MASK_0000003F, + MASK_0000FF00, + MASK_000003FC, + MASK_000001FE, + MASK_00000FFE, + MASK_FFFFFFFA, + MASK_0001F800, + MASK_0000007C, + MASK_000000FC, + MASK_001FFFFE, +}; + +static const uint32_t OPCODE_MASKS[] = { + [MASK_FFFFFFFF] = 0xFFFFFFFF, + [MASK_00000FFF] = 0x00000FFF, + [MASK_FFFFF000] = 0xFFFFF000, + [MASK_00001FFE] = 0x00001FFE, + [MASK_0000001F] = 0x0000001F, + [MASK_FFFFFFFE] = 0xFFFFFFFE, + [MASK_0000003F] = 0x0000003F, + [MASK_0000FF00] = 0x0000FF00, + [MASK_000003FC] = 0x000003FC, + [MASK_000001FE] = 0x000001FE, + [MASK_00000FFE] = 0x00000FFE, + [MASK_FFFFFFFA] = 0xFFFFFFFA, + [MASK_0001F800] = 0x0001F800, + [MASK_0000007C] = 0x0000007C, + [MASK_000000FC] = 0x000000FC, + [MASK_001FFFFE] = 0x001FFFFE, +}; + +static const opcode_t OPCODES[] = { + { MP_QSTR_add, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_add }, + { MP_QSTR_addi, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_addi }, + { MP_QSTR_and_, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_and }, + { MP_QSTR_andi, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_andi }, + { MP_QSTR_auipc, MASK_FFFFFFFF, MASK_FFFFF000, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 12, N, 0, RV32_EXT_NONE, asm_rv32_opcode_auipc }, + { MP_QSTR_beq, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00001FFE, 3, CALL_RRL, R, 0, R, 0, L, 0, RV32_EXT_NONE, asm_rv32_opcode_beq }, + { MP_QSTR_bge, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00001FFE, 3, CALL_RRL, R, 0, R, 0, L, 0, RV32_EXT_NONE, asm_rv32_opcode_bge }, + { MP_QSTR_bgeu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00001FFE, 3, CALL_RRL, R, 0, R, 0, L, 0, RV32_EXT_NONE, asm_rv32_opcode_bgeu }, + { MP_QSTR_blt, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00001FFE, 3, CALL_RRL, R, 0, R, 0, L, 0, RV32_EXT_NONE, asm_rv32_opcode_blt }, + { MP_QSTR_bltu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00001FFE, 3, CALL_RRL, R, 0, R, 0, L, 0, RV32_EXT_NONE, asm_rv32_opcode_bltu }, + { MP_QSTR_bne, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00001FFE, 3, CALL_RRL, R, 0, R, 0, L, 0, RV32_EXT_NONE, asm_rv32_opcode_bne }, + { MP_QSTR_csrrc, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_csrrc }, + { MP_QSTR_csrrs, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_csrrs }, + { MP_QSTR_csrrw, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_csrrw }, + { MP_QSTR_csrrci, MASK_FFFFFFFF, MASK_00000FFF, MASK_0000001F, 3, CALL_RII, R, 0, IU, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_csrrci }, + { MP_QSTR_csrrsi, MASK_FFFFFFFF, MASK_00000FFF, MASK_0000001F, 3, CALL_RII, R, 0, IU, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_csrrsi }, + { MP_QSTR_csrrwi, MASK_FFFFFFFF, MASK_00000FFF, MASK_0000001F, 3, CALL_RII, R, 0, IU, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_csrrwi }, + { MP_QSTR_c_add, MASK_FFFFFFFE, MASK_FFFFFFFE, MASK_NOT_USED, 2, CALL_RR, R, 0, R, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cadd }, + { MP_QSTR_c_addi, MASK_FFFFFFFE, MASK_0000003F, MASK_NOT_USED, 2, CALL_RI, R, 0, IZ, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_caddi }, + { MP_QSTR_c_addi4spn, MASK_0000FF00, MASK_000003FC, MASK_NOT_USED, 2, CALL_RI, R, 0, IUZ, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_caddi4spn }, + { MP_QSTR_c_and, MASK_0000FF00, MASK_0000FF00, MASK_NOT_USED, 2, CALL_RR, RC, 0, RC, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cand }, + { MP_QSTR_c_andi, MASK_0000FF00, MASK_0000003F, MASK_NOT_USED, 2, CALL_RI, RC, 0, I, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_candi }, + { MP_QSTR_c_beqz, MASK_0000FF00, MASK_000001FE, MASK_NOT_USED, 2, CALL_RL, RC, 0, L, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cbeqz }, + { MP_QSTR_c_bnez, MASK_0000FF00, MASK_000001FE, MASK_NOT_USED, 2, CALL_RL, RC, 0, L, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cbnez }, + { MP_QSTR_c_ebreak, MASK_NOT_USED, MASK_NOT_USED, MASK_NOT_USED, 0, CALL_N, N, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cebreak }, + { MP_QSTR_c_j, MASK_00000FFE, MASK_NOT_USED, MASK_NOT_USED, 1, CALL_L, L, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cj }, + { MP_QSTR_c_jal, MASK_00000FFE, MASK_NOT_USED, MASK_NOT_USED, 1, CALL_L, L, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cjal }, + { MP_QSTR_c_jalr, MASK_FFFFFFFE, MASK_NOT_USED, MASK_NOT_USED, 1, CALL_R, R, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cjalr }, + { MP_QSTR_c_jr, MASK_FFFFFFFE, MASK_NOT_USED, MASK_NOT_USED, 1, CALL_R, R, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cjr }, + { MP_QSTR_c_li, MASK_FFFFFFFE, MASK_0000003F, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cli }, + { MP_QSTR_c_lui, MASK_FFFFFFFA, MASK_0001F800, MASK_NOT_USED, 2, CALL_RI, R, 0, IUZ, 12, N, 0, RV32_EXT_NONE, asm_rv32_opcode_clui }, + { MP_QSTR_c_lw, MASK_0000FF00, MASK_0000007C, MASK_0000FF00, 2, CALL_RIR, RC, 0, I, 0, RC, 0, RV32_EXT_NONE, asm_rv32_opcode_clw }, + { MP_QSTR_c_lwsp, MASK_FFFFFFFE, MASK_000000FC, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_clwsp }, + { MP_QSTR_c_mv, MASK_FFFFFFFE, MASK_FFFFFFFE, MASK_NOT_USED, 2, CALL_RR, R, 0, R, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cmv }, + { MP_QSTR_c_nop, MASK_NOT_USED, MASK_NOT_USED, MASK_NOT_USED, 0, CALL_N, N, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cnop }, + { MP_QSTR_c_or, MASK_0000FF00, MASK_0000FF00, MASK_NOT_USED, 2, CALL_RR, RC, 0, RC, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cor }, + { MP_QSTR_c_slli, MASK_FFFFFFFE, MASK_0000001F, MASK_NOT_USED, 2, CALL_RI, R, 0, IU, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cslli }, + { MP_QSTR_c_srai, MASK_0000FF00, MASK_0000001F, MASK_NOT_USED, 2, CALL_RI, RC, 0, IU, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_csrai }, + { MP_QSTR_c_srli, MASK_0000FF00, MASK_0000001F, MASK_NOT_USED, 2, CALL_RI, RC, 0, IU, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_csrli }, + { MP_QSTR_c_sub, MASK_0000FF00, MASK_0000FF00, MASK_NOT_USED, 2, CALL_RR, RC, 0, RC, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_csub }, + { MP_QSTR_c_sw, MASK_0000FF00, MASK_0000007C, MASK_0000FF00, 2, CALL_RIR, RC, 0, I, 0, RC, 0, RV32_EXT_NONE, asm_rv32_opcode_csw }, + { MP_QSTR_c_swsp, MASK_FFFFFFFF, MASK_000000FC, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cswsp }, + { MP_QSTR_c_xor, MASK_0000FF00, MASK_0000FF00, MASK_NOT_USED, 2, CALL_RR, RC, 0, RC, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cxor }, + { MP_QSTR_div, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_div }, + { MP_QSTR_divu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_divu }, + { MP_QSTR_ebreak, MASK_NOT_USED, MASK_NOT_USED, MASK_NOT_USED, 0, CALL_N, N, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_ebreak }, + { MP_QSTR_ecall, MASK_NOT_USED, MASK_NOT_USED, MASK_NOT_USED, 0, CALL_N, N, 0, N, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_ecall }, + { MP_QSTR_jal, MASK_FFFFFFFF, MASK_001FFFFE, MASK_NOT_USED, 2, CALL_RL, R, 0, L, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_jal }, + { MP_QSTR_jalr, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_jalr }, + { MP_QSTR_la, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_NOT_USED, 2, CALL_RL, R, 0, L, 0, N, 0, RV32_EXT_NONE, opcode_la }, + { MP_QSTR_lb, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lb }, + { MP_QSTR_lbu, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lbu }, + { MP_QSTR_lh, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lh }, + { MP_QSTR_lhu, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lhu }, + { MP_QSTR_li, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 0, N, 0, RV32_EXT_NONE, opcode_li }, + { MP_QSTR_lui, MASK_FFFFFFFF, MASK_FFFFF000, MASK_NOT_USED, 2, CALL_RI, R, 0, I, 12, N, 0, RV32_EXT_NONE, asm_rv32_opcode_lui }, + { MP_QSTR_lw, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_lw }, + { MP_QSTR_mv, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_NOT_USED, 2, CALL_RR, R, 0, R, 0, N, 0, RV32_EXT_NONE, asm_rv32_opcode_cmv }, + { MP_QSTR_mul, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_mul }, + { MP_QSTR_mulh, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_mulh }, + { MP_QSTR_mulhsu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_mulhsu }, + { MP_QSTR_mulhu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_mulhu }, + { MP_QSTR_or_, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_or }, + { MP_QSTR_ori, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_ori }, + { MP_QSTR_rem, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_rem }, + { MP_QSTR_remu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_remu }, + { MP_QSTR_sb, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sb }, + { MP_QSTR_sh, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sh }, + { MP_QSTR_sh1add, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_ZBA, asm_rv32_opcode_sh1add }, + { MP_QSTR_sh2add, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_ZBA, asm_rv32_opcode_sh2add }, + { MP_QSTR_sh3add, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_ZBA, asm_rv32_opcode_sh3add }, + { MP_QSTR_sll, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sll }, + { MP_QSTR_slli, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_0000001F, 3, CALL_RRI, R, 0, R, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_slli }, + { MP_QSTR_slt, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_slt }, + { MP_QSTR_slti, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_slti }, + { MP_QSTR_sltiu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_sltiu }, + { MP_QSTR_sltu, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sltu }, + { MP_QSTR_sra, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sra }, + { MP_QSTR_srai, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_0000001F, 3, CALL_RRI, R, 0, R, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_srai }, + { MP_QSTR_srl, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_srl }, + { MP_QSTR_srli, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_0000001F, 3, CALL_RRI, R, 0, R, 0, IU, 0, RV32_EXT_NONE, asm_rv32_opcode_srli }, + { MP_QSTR_sub, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sub }, + { MP_QSTR_sw, MASK_FFFFFFFF, MASK_00000FFF, MASK_FFFFFFFF, 2, CALL_RIR, R, 0, I, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_sw }, + { MP_QSTR_xor, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_FFFFFFFF, 3, CALL_RRR, R, 0, R, 0, R, 0, RV32_EXT_NONE, asm_rv32_opcode_xor }, + { MP_QSTR_xori, MASK_FFFFFFFF, MASK_FFFFFFFF, MASK_00000FFF, 3, CALL_RRI, R, 0, R, 0, I, 0, RV32_EXT_NONE, asm_rv32_opcode_xori }, +}; + +#undef RC +#undef IU +#undef IZ +#undef IUZ + +// These two checks assume the bitmasks are contiguous. + +static bool is_in_signed_mask(uint32_t mask, mp_uint_t value) { + uint32_t leading_zeroes = mp_clz(mask); + if (leading_zeroes == 0) { + return true; + } + mp_uint_t positive_mask = ~(mask & ~(1U << (31 - leading_zeroes))); + if ((value & positive_mask) == 0) { + return true; + } + mp_uint_t negative_mask = ~(mask >> 1); + mp_uint_t trailing_zeroes = mp_ctz(mask); + if (trailing_zeroes > 0) { + mp_uint_t trailing_mask = (1U << trailing_zeroes) - 1; + if ((value & trailing_mask) != 0) { + return false; + } + negative_mask &= ~trailing_mask; + } + return (value & negative_mask) == negative_mask; +} + +static inline bool is_in_unsigned_mask(mp_uint_t mask, mp_uint_t value) { + return (value & ~mask) == 0; +} + +static bool validate_integer(mp_uint_t value, mp_uint_t mask, mp_uint_t flags) { + if (flags & U) { + if (!is_in_unsigned_mask(mask, value)) { + return false; + } + } else { + if (!is_in_signed_mask(mask, value)) { + return false; + } + } + + if ((flags & Z) && (value == 0)) { + return false; + } + + return true; +} + +#define ET_WRONG_ARGUMENT_KIND MP_ERROR_TEXT("opcode '%q' argument %d: expecting %q") +#define ET_WRONG_ARGUMENTS_COUNT MP_ERROR_TEXT("opcode '%q': expecting %d arguments") +#define ET_OUT_OF_RANGE MP_ERROR_TEXT("opcode '%q' argument %d: out of range") + +static bool serialise_argument(emit_inline_asm_t *emit, const opcode_t *opcode, mp_parse_node_t node, mp_uint_t node_index, mp_uint_t *serialised) { + assert((node_index < 3) && "Invalid argument node number."); + assert(serialised && "Serialised value pointer is NULL."); + + uint32_t kind = 0; + uint32_t shift = 0; + uint32_t mask = 0; + + switch (node_index) { + case 0: + kind = opcode->argument1_kind; + shift = opcode->argument1_shift; + mask = OPCODE_MASKS[opcode->argument1_mask]; + break; + + case 1: + kind = opcode->argument2_kind; + shift = opcode->argument2_shift; + mask = OPCODE_MASKS[opcode->argument2_mask]; + break; + + case 2: + kind = opcode->argument3_kind; + shift = opcode->argument3_shift; + mask = OPCODE_MASKS[opcode->argument3_mask]; + break; + + default: + break; + } + + mp_uint_t serialised_value = 0; + + switch (kind & 0x03) { + case N: + assert(mask == OPCODE_MASKS[MASK_NOT_USED] && "Invalid mask index for missing operand."); + break; + + case R: { + mp_uint_t register_index; + if (!parse_register_node(node, ®ister_index, false)) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + ET_WRONG_ARGUMENT_KIND, opcode->qstring, node_index + 1, MP_QSTR_register)); + return false; + } + + if ((mask & (1U << register_index)) == 0) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + MP_ERROR_TEXT("opcode '%q' argument %d: unknown register"), + opcode->qstring, node_index + 1)); + return false; + } + + serialised_value = (kind & C) ? RV32_MAP_IN_C_REGISTER_WINDOW(register_index) : register_index; + } + break; + + case I: { + mp_obj_t object; + if (!mp_parse_node_get_int_maybe(node, &object)) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + ET_WRONG_ARGUMENT_KIND, opcode->qstring, node_index + 1, MP_QSTR_integer)); + return false; + } + + mp_uint_t immediate = mp_obj_get_int_truncated(object) << shift; + if (kind & U) { + if (!is_in_unsigned_mask(mask, immediate)) { + goto out_of_range; + } + } else { + if (!is_in_signed_mask(mask, immediate)) { + goto out_of_range; + } + } + + if ((kind & Z) && (immediate == 0)) { + goto zero_immediate; + } + + serialised_value = immediate; + } + break; + + case L: { + if (!MP_PARSE_NODE_IS_ID(node)) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + ET_WRONG_ARGUMENT_KIND, opcode->qstring, node_index + 1, MP_QSTR_label)); + return false; + } + + qstr qstring; + mp_uint_t label_index = lookup_label(emit, node, &qstring); + if (label_index >= emit->max_num_labels && emit->pass == MP_PASS_EMIT) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + MP_ERROR_TEXT("opcode '%q' argument %d: undefined label '%q'"), + opcode->qstring, node_index + 1, qstring)); + return false; + } + + mp_uint_t displacement = (mp_uint_t)(label_code_offset(emit, label_index)); + if (kind & U) { + if (!is_in_unsigned_mask(mask, displacement)) { + goto out_of_range; + } + } else { + if (!is_in_signed_mask(mask, displacement)) { + goto out_of_range; + } + } + + serialised_value = displacement; + } + break; + + default: + assert(!"Unknown argument kind"); + MP_UNREACHABLE; + break; + } + + *serialised = serialised_value; + return true; + +out_of_range: + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_OUT_OF_RANGE, opcode->qstring, node_index + 1)); + return false; + +zero_immediate: + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + MP_ERROR_TEXT("opcode '%q' argument %d: must not be zero"), + opcode->qstring, node_index + 1)); + return false; +} + +static bool serialise_register_offset_node(emit_inline_asm_t *emit, const opcode_t *opcode_data, mp_parse_node_t node, mp_uint_t node_index, mp_uint_t *offset, mp_uint_t *base) { + assert(offset && "Attempting to store the offset value into NULL."); + assert(base && "Attempting to store the base register into NULL."); + + if (!MP_PARSE_NODE_IS_STRUCT_KIND(node, PN_atom_expr_normal) && !MP_PARSE_NODE_IS_STRUCT_KIND(node, PN_factor_2)) { + goto invalid_structure; + } + mp_parse_node_struct_t *node_struct = (mp_parse_node_struct_t *)node; + bool negative = false; + if (MP_PARSE_NODE_IS_STRUCT_KIND(node, PN_factor_2)) { + if (MP_PARSE_NODE_IS_TOKEN_KIND(node_struct->nodes[0], MP_TOKEN_OP_MINUS)) { + negative = true; + } else { + if (!MP_PARSE_NODE_IS_TOKEN_KIND(node_struct->nodes[0], MP_TOKEN_OP_PLUS)) { + goto invalid_structure; + } + } + if (!MP_PARSE_NODE_IS_STRUCT_KIND(node_struct->nodes[1], PN_atom_expr_normal)) { + goto invalid_structure; + } + node_struct = (mp_parse_node_struct_t *)node_struct->nodes[1]; + } + + if (negative) { + // If the value is negative, RULE_atom_expr_normal's first token will be the + // offset stripped of its negative marker; range check will then fail if the + // default method is used, so a custom check is used instead. + mp_obj_t object; + if (!mp_parse_node_get_int_maybe(node_struct->nodes[0], &object)) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_WRONG_ARGUMENT_KIND, opcode_data->qstring, 2, MP_QSTR_integer)); + return false; + } + mp_uint_t value = mp_obj_get_int_truncated(object); + value = (~value + 1) & (mp_uint_t)-1; + if (!validate_integer(value << opcode_data->argument2_shift, OPCODE_MASKS[opcode_data->argument2_mask], opcode_data->argument2_kind)) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, ET_OUT_OF_RANGE, opcode_data->qstring, 2)); + return false; + } + *offset = value; + } else { + if (!serialise_argument(emit, opcode_data, node_struct->nodes[0], 1, offset)) { + return false; + } + } + + node_struct = (mp_parse_node_struct_t *)node_struct->nodes[1]; + if (!serialise_argument(emit, opcode_data, node_struct->nodes[0], 2, base)) { + return false; + } + return true; + +invalid_structure: + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + ET_WRONG_ARGUMENT_KIND, opcode_data->qstring, node_index + 1, MP_QSTR_offset)); + return false; +} + +static void handle_opcode(emit_inline_asm_t *emit, const opcode_t *opcode_data, mp_uint_t *arguments) { + switch (opcode_data->calling_convention) { + case CALL_RRR: + ((call_rrr_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[1], arguments[2]); + break; + + case CALL_RR: + ((call_rr_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[1]); + break; + + case CALL_RRI: + ((call_rri_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[1], arguments[2]); + break; + + case CALL_RI: + ((call_ri_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[1]); + break; + + case CALL_R: + ((call_r_t)opcode_data->emitter)(&emit->as, arguments[0]); + break; + + case CALL_RRL: + ((call_rri_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[1], (ptrdiff_t)arguments[2]); + break; + + case CALL_RL: + ((call_ri_t)opcode_data->emitter)(&emit->as, arguments[0], (ptrdiff_t)arguments[1]); + break; + + case CALL_L: + ((call_i_t)opcode_data->emitter)(&emit->as, (ptrdiff_t)arguments[0]); + break; + + case CALL_N: + ((call_n_t)opcode_data->emitter)(&emit->as); + break; + + case CALL_RII: + ((call_rii_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[1], arguments[2]); + break; + + case CALL_RIR: + // The last two arguments indices are swapped on purpose. + ((call_rri_t)opcode_data->emitter)(&emit->as, arguments[0], arguments[2], arguments[1]); + break; + + default: + assert(!"Unhandled call convention."); + MP_UNREACHABLE; + break; + } +} + +static void emit_inline_rv32_opcode(emit_inline_asm_t *emit, qstr opcode, mp_uint_t arguments_count, mp_parse_node_t *argument_nodes) { + const opcode_t *opcode_data = NULL; + for (mp_uint_t index = 0; index < MP_ARRAY_SIZE(OPCODES); index++) { + if (OPCODES[index].qstring == opcode) { + opcode_data = &OPCODES[index]; + break; + } + } + + if (!opcode_data || (asm_rv32_allowed_extensions() & opcode_data->required_extensions) != opcode_data->required_extensions) { + emit_inline_rv32_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + MP_ERROR_TEXT("invalid RV32 instruction '%q'"), opcode)); + return; + } + + assert((opcode_data->argument1_mask < MP_ARRAY_SIZE(OPCODE_MASKS)) && "Argument #1 opcode mask index out of bounds."); + assert((opcode_data->argument2_mask < MP_ARRAY_SIZE(OPCODE_MASKS)) && "Argument #2 opcode mask index out of bounds."); + assert((opcode_data->argument3_mask < MP_ARRAY_SIZE(OPCODE_MASKS)) && "Argument #3 opcode mask index out of bounds."); + assert((opcode_data->calling_convention < CALL_COUNT) && "Calling convention index out of bounds."); + mp_uint_t serialised_arguments[3] = { 0 }; + if (arguments_count != opcode_data->parse_nodes) { + emit_inline_rv32_error_exc(emit, + mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, + ET_WRONG_ARGUMENTS_COUNT, opcode, opcode_data->parse_nodes)); + return; + } + + if (opcode_data->parse_nodes >= 1 && !serialise_argument(emit, opcode_data, argument_nodes[0], 0, &serialised_arguments[0])) { + return; + } + if (opcode_data->calling_convention == CALL_RIR) { + // "register, offset(base)" calls require some preprocessing to + // split the offset and base nodes - not to mention that if the offset + // is negative, the parser won't see the offset as a single node but as + // a sequence of the minus sign token followed by the number itself. + + if (!serialise_register_offset_node(emit, opcode_data, argument_nodes[1], 1, &serialised_arguments[1], &serialised_arguments[2])) { + return; + } + } else { + if (opcode_data->parse_nodes >= 2 && !serialise_argument(emit, opcode_data, argument_nodes[1], 1, &serialised_arguments[1])) { + return; + } + if (opcode_data->parse_nodes >= 3 && !serialise_argument(emit, opcode_data, argument_nodes[2], 2, &serialised_arguments[2])) { + return; + } + } + + handle_opcode(emit, opcode_data, serialised_arguments); +} + +#undef N +#undef R +#undef I +#undef L +#undef C +#undef U + +const emit_inline_asm_method_table_t emit_inline_rv32_method_table = { + #if MICROPY_DYNAMIC_COMPILER + emit_inline_rv32_new, + emit_inline_rv32_free, + #endif + + emit_inline_rv32_start_pass, + emit_inline_rv32_end_pass, + emit_inline_rv32_count_params, + emit_inline_rv32_label, + emit_inline_rv32_opcode, +}; + +#endif // MICROPY_EMIT_INLINE_RV32 diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 7818bb4f46d..d6596337ae5 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -150,27 +150,27 @@ typedef struct _reg_name_t { byte reg; byte name[3]; } reg_name_t; static const reg_name_t reg_name_table[] = { - {0, "r0\0"}, - {1, "r1\0"}, - {2, "r2\0"}, - {3, "r3\0"}, - {4, "r4\0"}, - {5, "r5\0"}, - {6, "r6\0"}, - {7, "r7\0"}, - {8, "r8\0"}, - {9, "r9\0"}, - {10, "r10"}, - {11, "r11"}, - {12, "r12"}, - {13, "r13"}, - {14, "r14"}, - {15, "r15"}, - {10, "sl\0"}, - {11, "fp\0"}, - {13, "sp\0"}, - {14, "lr\0"}, - {15, "pc\0"}, + {0, {'r', '0' }}, + {1, {'r', '1' }}, + {2, {'r', '2' }}, + {3, {'r', '3' }}, + {4, {'r', '4' }}, + {5, {'r', '5' }}, + {6, {'r', '6' }}, + {7, {'r', '7' }}, + {8, {'r', '8' }}, + {9, {'r', '9' }}, + {10, {'r', '1', '0' }}, + {11, {'r', '1', '1' }}, + {12, {'r', '1', '2' }}, + {13, {'r', '1', '3' }}, + {14, {'r', '1', '4' }}, + {15, {'r', '1', '5' }}, + {10, {'s', 'l' }}, + {11, {'f', 'p' }}, + {13, {'s', 'p' }}, + {14, {'l', 'r' }}, + {15, {'p', 'c' }}, }; #define MAX_SPECIAL_REGISTER_NAME_LENGTH 7 @@ -368,20 +368,20 @@ typedef struct _cc_name_t { byte cc; byte name[2]; } cc_name_t; static const cc_name_t cc_name_table[] = { - { ASM_THUMB_CC_EQ, "eq" }, - { ASM_THUMB_CC_NE, "ne" }, - { ASM_THUMB_CC_CS, "cs" }, - { ASM_THUMB_CC_CC, "cc" }, - { ASM_THUMB_CC_MI, "mi" }, - { ASM_THUMB_CC_PL, "pl" }, - { ASM_THUMB_CC_VS, "vs" }, - { ASM_THUMB_CC_VC, "vc" }, - { ASM_THUMB_CC_HI, "hi" }, - { ASM_THUMB_CC_LS, "ls" }, - { ASM_THUMB_CC_GE, "ge" }, - { ASM_THUMB_CC_LT, "lt" }, - { ASM_THUMB_CC_GT, "gt" }, - { ASM_THUMB_CC_LE, "le" }, + { ASM_THUMB_CC_EQ, { 'e', 'q' }}, + { ASM_THUMB_CC_NE, { 'n', 'e' }}, + { ASM_THUMB_CC_CS, { 'c', 's' }}, + { ASM_THUMB_CC_CC, { 'c', 'c' }}, + { ASM_THUMB_CC_MI, { 'm', 'i' }}, + { ASM_THUMB_CC_PL, { 'p', 'l' }}, + { ASM_THUMB_CC_VS, { 'v', 's' }}, + { ASM_THUMB_CC_VC, { 'v', 'c' }}, + { ASM_THUMB_CC_HI, { 'h', 'i' }}, + { ASM_THUMB_CC_LS, { 'l', 's' }}, + { ASM_THUMB_CC_GE, { 'g', 'e' }}, + { ASM_THUMB_CC_LT, { 'l', 't' }}, + { ASM_THUMB_CC_GT, { 'g', 't' }}, + { ASM_THUMB_CC_LE, { 'l', 'e' }}, }; typedef struct _format_4_op_t { byte op; @@ -389,21 +389,21 @@ typedef struct _format_4_op_t { byte op; } format_4_op_t; #define X(x) (((x) >> 4) & 0xff) // only need 1 byte to distinguish these ops static const format_4_op_t format_4_op_table[] = { - { X(ASM_THUMB_FORMAT_4_EOR), "eor" }, - { X(ASM_THUMB_FORMAT_4_LSL), "lsl" }, - { X(ASM_THUMB_FORMAT_4_LSR), "lsr" }, - { X(ASM_THUMB_FORMAT_4_ASR), "asr" }, - { X(ASM_THUMB_FORMAT_4_ADC), "adc" }, - { X(ASM_THUMB_FORMAT_4_SBC), "sbc" }, - { X(ASM_THUMB_FORMAT_4_ROR), "ror" }, - { X(ASM_THUMB_FORMAT_4_TST), "tst" }, - { X(ASM_THUMB_FORMAT_4_NEG), "neg" }, - { X(ASM_THUMB_FORMAT_4_CMP), "cmp" }, - { X(ASM_THUMB_FORMAT_4_CMN), "cmn" }, - { X(ASM_THUMB_FORMAT_4_ORR), "orr" }, - { X(ASM_THUMB_FORMAT_4_MUL), "mul" }, - { X(ASM_THUMB_FORMAT_4_BIC), "bic" }, - { X(ASM_THUMB_FORMAT_4_MVN), "mvn" }, + { X(ASM_THUMB_FORMAT_4_EOR), {'e', 'o', 'r' }}, + { X(ASM_THUMB_FORMAT_4_LSL), {'l', 's', 'l' }}, + { X(ASM_THUMB_FORMAT_4_LSR), {'l', 's', 'r' }}, + { X(ASM_THUMB_FORMAT_4_ASR), {'a', 's', 'r' }}, + { X(ASM_THUMB_FORMAT_4_ADC), {'a', 'd', 'c' }}, + { X(ASM_THUMB_FORMAT_4_SBC), {'s', 'b', 'c' }}, + { X(ASM_THUMB_FORMAT_4_ROR), {'r', 'o', 'r' }}, + { X(ASM_THUMB_FORMAT_4_TST), {'t', 's', 't' }}, + { X(ASM_THUMB_FORMAT_4_NEG), {'n', 'e', 'g' }}, + { X(ASM_THUMB_FORMAT_4_CMP), {'c', 'm', 'p' }}, + { X(ASM_THUMB_FORMAT_4_CMN), {'c', 'm', 'n' }}, + { X(ASM_THUMB_FORMAT_4_ORR), {'o', 'r', 'r' }}, + { X(ASM_THUMB_FORMAT_4_MUL), {'m', 'u', 'l' }}, + { X(ASM_THUMB_FORMAT_4_BIC), {'b', 'i', 'c' }}, + { X(ASM_THUMB_FORMAT_4_MVN), {'m', 'v', 'n' }}, }; #undef X @@ -428,10 +428,10 @@ typedef struct _format_vfp_op_t { char name[3]; } format_vfp_op_t; static const format_vfp_op_t format_vfp_op_table[] = { - { 0x30, "add" }, - { 0x34, "sub" }, - { 0x20, "mul" }, - { 0x80, "div" }, + { 0x30, {'a', 'd', 'd' }}, + { 0x34, {'s', 'u', 'b' }}, + { 0x20, {'m', 'u', 'l' }}, + { 0x80, {'d', 'i', 'v' }}, }; // shorthand alias for whether we allow ARMv7-M instructions diff --git a/py/emitinlinextensa.c b/py/emitinlinextensa.c index 57056d597aa..d0eb3d566fc 100644 --- a/py/emitinlinextensa.c +++ b/py/emitinlinextensa.c @@ -115,50 +115,21 @@ static bool emit_inline_xtensa_label(emit_inline_asm_t *emit, mp_uint_t label_nu return true; } -typedef struct _reg_name_t { byte reg; - byte name[3]; -} reg_name_t; -static const reg_name_t reg_name_table[] = { - {0, "a0\0"}, - {1, "a1\0"}, - {2, "a2\0"}, - {3, "a3\0"}, - {4, "a4\0"}, - {5, "a5\0"}, - {6, "a6\0"}, - {7, "a7\0"}, - {8, "a8\0"}, - {9, "a9\0"}, - {10, "a10"}, - {11, "a11"}, - {12, "a12"}, - {13, "a13"}, - {14, "a14"}, - {15, "a15"}, +static const qstr_short_t REGISTERS[16] = { + MP_QSTR_a0, MP_QSTR_a1, MP_QSTR_a2, MP_QSTR_a3, MP_QSTR_a4, MP_QSTR_a5, MP_QSTR_a6, MP_QSTR_a7, + MP_QSTR_a8, MP_QSTR_a9, MP_QSTR_a10, MP_QSTR_a11, MP_QSTR_a12, MP_QSTR_a13, MP_QSTR_a14, MP_QSTR_a15 }; -// return empty string in case of error, so we can attempt to parse the string -// without a special check if it was in fact a string -static const char *get_arg_str(mp_parse_node_t pn) { - if (MP_PARSE_NODE_IS_ID(pn)) { - qstr qst = MP_PARSE_NODE_LEAF_ARG(pn); - return qstr_str(qst); - } else { - return ""; - } -} - static mp_uint_t get_arg_reg(emit_inline_asm_t *emit, const char *op, mp_parse_node_t pn) { - const char *reg_str = get_arg_str(pn); - for (mp_uint_t i = 0; i < MP_ARRAY_SIZE(reg_name_table); i++) { - const reg_name_t *r = ®_name_table[i]; - if (reg_str[0] == r->name[0] - && reg_str[1] == r->name[1] - && reg_str[2] == r->name[2] - && (reg_str[2] == '\0' || reg_str[3] == '\0')) { - return r->reg; + if (MP_PARSE_NODE_IS_ID(pn)) { + qstr node_qstr = MP_PARSE_NODE_LEAF_ARG(pn); + for (size_t i = 0; i < MP_ARRAY_SIZE(REGISTERS); i++) { + if (node_qstr == REGISTERS[i]) { + return i; + } } } + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("'%s' expects a register"), op)); @@ -202,7 +173,7 @@ static int get_arg_label(emit_inline_asm_t *emit, const char *op, mp_parse_node_ #define RRI8_B (2) typedef struct _opcode_table_3arg_t { - uint16_t name; // actually a qstr, which should fit in 16 bits + qstr_short_t name; uint8_t type; uint8_t a0 : 4; uint8_t a1 : 4; @@ -216,6 +187,13 @@ static const opcode_table_3arg_t opcode_table_3arg[] = { {MP_QSTR_add, RRR, 0, 8}, {MP_QSTR_sub, RRR, 0, 12}, {MP_QSTR_mull, RRR, 2, 8}, + {MP_QSTR_addx2, RRR, 0, 9}, + {MP_QSTR_addx4, RRR, 0, 10}, + {MP_QSTR_addx8, RRR, 0, 11}, + {MP_QSTR_subx2, RRR, 0, 13}, + {MP_QSTR_subx4, RRR, 0, 14}, + {MP_QSTR_subx8, RRR, 0, 15}, + {MP_QSTR_src, RRR, 1, 8}, // load/store/addi opcodes: reg, reg, imm // upper nibble of type encodes the range of the immediate arg @@ -237,21 +215,62 @@ static const opcode_table_3arg_t opcode_table_3arg[] = { {MP_QSTR_bge, RRI8_B, ASM_XTENSA_CC_GE, 0}, {MP_QSTR_bgeu, RRI8_B, ASM_XTENSA_CC_GEU, 0}, {MP_QSTR_blt, RRI8_B, ASM_XTENSA_CC_LT, 0}, + {MP_QSTR_bltu, RRI8_B, ASM_XTENSA_CC_LTU, 0}, {MP_QSTR_bnall, RRI8_B, ASM_XTENSA_CC_NALL, 0}, {MP_QSTR_bne, RRI8_B, ASM_XTENSA_CC_NE, 0}, {MP_QSTR_bnone, RRI8_B, ASM_XTENSA_CC_NONE, 0}, }; +// The index of the first four qstrs matches the CCZ condition value to be +// embedded into the opcode. +static const qstr_short_t BCCZ_OPCODES[] = { + MP_QSTR_beqz, MP_QSTR_bnez, MP_QSTR_bltz, MP_QSTR_bgez, + MP_QSTR_beqz_n, MP_QSTR_bnez_n +}; + +#if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES +typedef struct _single_opcode_t { + qstr_short_t name; + uint16_t value; +} single_opcode_t; + +static const single_opcode_t NOARGS_OPCODES[] = { + {MP_QSTR_dsync, 0x2030}, + {MP_QSTR_esync, 0x2020}, + {MP_QSTR_extw, 0x20D0}, + {MP_QSTR_ill, 0x0000}, + {MP_QSTR_isync, 0x2000}, + {MP_QSTR_memw, 0x20C0}, + {MP_QSTR_rsync, 0x2010}, +}; +#endif + static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_args, mp_parse_node_t *pn_args) { size_t op_len; const char *op_str = (const char *)qstr_data(op, &op_len); if (n_args == 0) { - if (op == MP_QSTR_ret_n) { + if (op == MP_QSTR_ret_n || op == MP_QSTR_ret) { asm_xtensa_op_ret_n(&emit->as); - } else { - goto unknown_op; + return; + } else if (op == MP_QSTR_nop) { + asm_xtensa_op24(&emit->as, 0x20F0); + return; + } else if (op == MP_QSTR_nop_n) { + asm_xtensa_op16(&emit->as, 0xF03D); + return; } + #if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES + for (size_t index = 0; index < MP_ARRAY_SIZE(NOARGS_OPCODES); index++) { + const single_opcode_t *opcode = &NOARGS_OPCODES[index]; + if (op == opcode->name) { + asm_xtensa_op24(&emit->as, opcode->value); + return; + } + } + #endif + + goto unknown_op; } else if (n_args == 1) { if (op == MP_QSTR_callx0) { @@ -263,19 +282,45 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_ } else if (op == MP_QSTR_jx) { uint r0 = get_arg_reg(emit, op_str, pn_args[0]); asm_xtensa_op_jx(&emit->as, r0); + } else if (op == MP_QSTR_ssl) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + asm_xtensa_op_ssl(&emit->as, r0); + } else if (op == MP_QSTR_ssr) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + asm_xtensa_op_ssr(&emit->as, r0); + } else if (op == MP_QSTR_ssai) { + mp_uint_t sa = get_arg_i(emit, op_str, pn_args[0], 0, 31); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 4, sa & 0x0F, (sa >> 4) & 0x01)); + } else if (op == MP_QSTR_ssa8b) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 3, r0, 0)); + } else if (op == MP_QSTR_ssa8l) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 2, r0, 0)); + } else if (op == MP_QSTR_call0) { + mp_uint_t label = get_arg_label(emit, op_str, pn_args[0]); + asm_xtensa_call0(&emit->as, label); + #if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES + } else if (op == MP_QSTR_fsync) { + mp_uint_t imm3 = get_arg_i(emit, op_str, pn_args[0], 0, 7); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 0, 2, 8 | imm3, 0)); + } else if (op == MP_QSTR_ill_n) { + asm_xtensa_op16(&emit->as, 0xF06D); + #endif } else { goto unknown_op; } } else if (n_args == 2) { uint r0 = get_arg_reg(emit, op_str, pn_args[0]); - if (op == MP_QSTR_beqz) { - int label = get_arg_label(emit, op_str, pn_args[1]); - asm_xtensa_bccz_reg_label(&emit->as, ASM_XTENSA_CCZ_EQ, r0, label); - } else if (op == MP_QSTR_bnez) { - int label = get_arg_label(emit, op_str, pn_args[1]); - asm_xtensa_bccz_reg_label(&emit->as, ASM_XTENSA_CCZ_NE, r0, label); - } else if (op == MP_QSTR_mov || op == MP_QSTR_mov_n) { + for (size_t index = 0; index < MP_ARRAY_SIZE(BCCZ_OPCODES); index++) { + if (op == BCCZ_OPCODES[index]) { + mp_uint_t label = get_arg_label(emit, op_str, pn_args[1]); + asm_xtensa_bccz_reg_label(&emit->as, index & 0x03, r0, label); + return; + } + } + if (op == MP_QSTR_mov || op == MP_QSTR_mov_n) { // we emit mov.n for both "mov" and "mov_n" opcodes uint r1 = get_arg_reg(emit, op_str, pn_args[1]); asm_xtensa_op_mov_n(&emit->as, r0, r1); @@ -283,7 +328,53 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_ // for convenience we emit l32r if the integer doesn't fit in movi uint32_t imm = get_arg_i(emit, op_str, pn_args[1], 0, 0); asm_xtensa_mov_reg_i32(&emit->as, r0, imm); - } else { + } else if (op == MP_QSTR_abs_) { + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 6, r0, 1, r1)); + } else if (op == MP_QSTR_neg) { + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 6, r0, 0, r1)); + } else if (op == MP_QSTR_sll) { + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 10, r0, r1, 0)); + } else if (op == MP_QSTR_sra) { + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 11, r0, 0, r1)); + } else if (op == MP_QSTR_srl) { + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 9, r0, 0, r1)); + } else if (op == MP_QSTR_nsa) { + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 14, r1, r0)); + } else if (op == MP_QSTR_nsau) { + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 0, 4, 15, r1, r0)); + } else if (op == MP_QSTR_l32r) { + mp_uint_t label = get_arg_label(emit, op_str, pn_args[1]); + asm_xtensa_l32r(&emit->as, r0, label); + } else if (op == MP_QSTR_movi_n) { + mp_int_t imm = get_arg_i(emit, op_str, pn_args[1], -32, 95); + asm_xtensa_op_movi_n(&emit->as, r0, imm); + } else + #if MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES + if (op == MP_QSTR_rsr) { + mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 3, 0, sr, r0)); + } else if (op == MP_QSTR_rur) { + mp_uint_t imm8 = get_arg_i(emit, op_str, pn_args[1], 0, 255); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 3, 14, r0, (imm8 >> 4) & 0x0F, imm8 & 0x0F)); + } else if (op == MP_QSTR_wsr) { + mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 3, 1, sr, r0)); + } else if (op == MP_QSTR_wur) { + mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 3, 15, sr, r0)); + } else if (op == MP_QSTR_xsr) { + mp_uint_t sr = get_arg_i(emit, op_str, pn_args[1], 0, 255); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RSR(0, 1, 6, sr, r0)); + } else + #endif + { goto unknown_op; } @@ -317,7 +408,72 @@ static void emit_inline_xtensa_op(emit_inline_asm_t *emit, qstr op, mp_uint_t n_ return; } } - goto unknown_op; + + if (op == MP_QSTR_add_n) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_uint_t r2 = get_arg_reg(emit, op_str, pn_args[2]); + asm_xtensa_op16(&emit->as, ASM_XTENSA_ENCODE_RRRN(10, r0, r1, r2)); + } else if (op == MP_QSTR_addi_n) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_int_t imm4 = get_arg_i(emit, op_str, pn_args[2], -1, 15); + asm_xtensa_op16(&emit->as, ASM_XTENSA_ENCODE_RRRN(11, r0, r1, (imm4 != 0 ? imm4 : -1))); + } else if (op == MP_QSTR_addmi) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_int_t imm8 = get_arg_i(emit, op_str, pn_args[2], -128 * 256, 127 * 256); + if ((imm8 & 0xFF) != 0) { + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("%d is not a multiple of %d"), imm8, 256)); + } else { + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRI8(2, 13, r1, r0, imm8 >> 8)); + } + } else if (op == MP_QSTR_bbci) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t bit = get_arg_i(emit, op_str, pn_args[1], 0, 31); + mp_int_t label = get_arg_label(emit, op_str, pn_args[2]); + asm_xtensa_bit_branch(&emit->as, r0, bit, label, 6); + } else if (op == MP_QSTR_bbsi) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t bit = get_arg_i(emit, op_str, pn_args[1], 0, 31); + mp_uint_t label = get_arg_label(emit, op_str, pn_args[2]); + asm_xtensa_bit_branch(&emit->as, r0, bit, label, 14); + } else if (op == MP_QSTR_slli) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_uint_t bits = 32 - get_arg_i(emit, op_str, pn_args[2], 1, 31); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 0 | ((bits >> 4) & 0x01), r0, r1, bits & 0x0F)); + } else if (op == MP_QSTR_srai) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_uint_t bits = get_arg_i(emit, op_str, pn_args[2], 0, 31); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 2 | ((bits >> 4) & 0x01), r0, bits & 0x0F, r1)); + } else if (op == MP_QSTR_srli) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_uint_t bits = get_arg_i(emit, op_str, pn_args[2], 0, 15); + asm_xtensa_op24(&emit->as, ASM_XTENSA_ENCODE_RRR(0, 1, 4, r0, bits, r1)); + } else if (op == MP_QSTR_l32i_n) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_uint_t imm = get_arg_i(emit, op_str, pn_args[2], 0, 60); + if ((imm & 0x03) != 0) { + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("%d is not a multiple of %d"), imm, 4)); + } else { + asm_xtensa_op_l32i_n(&emit->as, r0, r1, imm >> 2); + } + } else if (op == MP_QSTR_s32i_n) { + mp_uint_t r0 = get_arg_reg(emit, op_str, pn_args[0]); + mp_uint_t r1 = get_arg_reg(emit, op_str, pn_args[1]); + mp_uint_t imm = get_arg_i(emit, op_str, pn_args[2], 0, 60); + if ((imm & 0x03) != 0) { + emit_inline_xtensa_error_exc(emit, mp_obj_new_exception_msg_varg(&mp_type_SyntaxError, MP_ERROR_TEXT("%d is not a multiple of %d"), imm, 4)); + } else { + asm_xtensa_op_s32i_n(&emit->as, r0, r1, imm >> 2); + } + } else { + goto unknown_op; + } } else { goto unknown_op; diff --git a/py/emitnative.c b/py/emitnative.c index 4789d3f5781..6f12200f7e1 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -60,28 +60,40 @@ #endif // CIRCUITPY-CHANGE: force definitions -#ifndef N_X64 -#define N_X64 (0) +#ifndef N_ARM +#define N_ARM (0) #endif -#ifndef N_X86 -#define N_X86 (0) +#ifndef N_DEBUG +#define N_DEBUG (0) +#endif + +#ifndef N_NLR_SETJMP +#define N_NLR_SETJMP (0) +#endif + +#ifndef N_RV32 +#define N_RV32 (0) #endif #ifndef N_THUMB #define N_THUMB (0) #endif -#ifndef N_ARM -#define N_ARM (0) +#ifndef N_X64 +#define N_X64 (0) +#endif + +#ifndef N_X86 +#define N_X86 (0) #endif #ifndef N_XTENSA #define N_XTENSA (0) #endif -#ifndef N_NLR_SETJMP -#define N_NLR_SETJMP (0) +#ifndef N_XTENSAWIN +#define N_XTENSAWIN (0) #endif #ifndef N_PRELUDE_AS_BYTES_OBJ @@ -89,7 +101,7 @@ #endif // wrapper around everything in this file -#if N_X64 || N_X86 || N_THUMB || N_ARM || N_XTENSA || N_XTENSAWIN +#if N_X64 || N_X86 || N_THUMB || N_ARM || N_XTENSA || N_XTENSAWIN || N_RV32 || N_DEBUG // C stack layout for native functions: // 0: nlr_buf_t [optional] @@ -159,6 +171,7 @@ // Whether a slot is needed to store LOCAL_IDX_EXC_HANDLER_UNWIND #define NEED_EXC_HANDLER_UNWIND(emit) ((emit)->scope->exc_stack_size > 0) +#define NEED_THROW_VAL(emit) ((emit)->scope->scope_flags & MP_SCOPE_FLAG_GENERATOR) // Whether registers can be used to store locals (only true if there are no // exception handlers, because otherwise an nlr_jump will restore registers to @@ -169,6 +182,7 @@ #define LOCAL_IDX_EXC_VAL(emit) (NLR_BUF_IDX_RET_VAL) #define LOCAL_IDX_EXC_HANDLER_PC(emit) (NLR_BUF_IDX_LOCAL_1) #define LOCAL_IDX_EXC_HANDLER_UNWIND(emit) (SIZEOF_NLR_BUF + 1) // this needs a dedicated variable outside nlr_buf_t +#define LOCAL_IDX_THROW_VAL(emit) (SIZEOF_NLR_BUF + 2) // needs a dedicated variable outside nlr_buf_t, following inject_exc in py/vm.c #define LOCAL_IDX_RET_VAL(emit) (SIZEOF_NLR_BUF) // needed when NEED_GLOBAL_EXC_HANDLER is true #define LOCAL_IDX_FUN_OBJ(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_FUN_BC) #define LOCAL_IDX_OLD_GLOBALS(emit) ((emit)->code_state_start + OFFSETOF_CODE_STATE_IP) @@ -310,12 +324,32 @@ struct _emit_t { ASM_T *as; }; +#ifndef REG_ZERO +#define REG_ZERO REG_TEMP0 +#define ASM_CLR_REG(state, rd) ASM_XOR_REG_REG(state, rd, rd) +#endif + +#if N_RV32 +#define ASM_MOV_LOCAL_MP_OBJ_NULL(as, local_num, reg_temp) \ + ASM_MOV_LOCAL_REG(as, local_num, REG_ZERO) +#else +#define ASM_MOV_LOCAL_MP_OBJ_NULL(as, local_num, reg_temp) \ + ASM_MOV_REG_IMM(as, reg_temp, (mp_uint_t)MP_OBJ_NULL); \ + ASM_MOV_LOCAL_REG(as, local_num, reg_temp) +#endif + static void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj); static void emit_native_global_exc_entry(emit_t *emit); static void emit_native_global_exc_exit(emit_t *emit); static void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj); emit_t *EXPORT_FUN(new)(mp_emit_common_t * emit_common, mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels) { + // Generated code performing exception handling assumes that MP_OBJ_NULL + // equals to 0 to simplify some checks, leveraging dedicated opcodes for + // comparisons against 0. If this assumption does not hold true anymore + // then generated code won't work correctly. + MP_STATIC_ASSERT(MP_OBJ_NULL == 0); + emit_t *emit = m_new0(emit_t, 1); emit->emit_common = emit_common; emit->error_slot = error_slot; @@ -372,11 +406,14 @@ static void emit_native_mov_reg_state_addr(emit_t *emit, int reg_dest, int local static void emit_native_mov_reg_qstr(emit_t *emit, int arg_reg, qstr qst) { #if MICROPY_PERSISTENT_CODE_SAVE ASM_LOAD16_REG_REG_OFFSET(emit->as, arg_reg, REG_QSTR_TABLE, mp_emit_common_use_qstr(emit->emit_common, qst)); + #elif defined(ASM_MOV_REG_QSTR) + ASM_MOV_REG_QSTR(emit->as, arg_reg, qst); #else ASM_MOV_REG_IMM(emit->as, arg_reg, qst); #endif } +// This function may clobber REG_TEMP0 (and `reg_dest` can be REG_TEMP0). static void emit_native_mov_reg_qstr_obj(emit_t *emit, int reg_dest, qstr qst) { #if MICROPY_PERSISTENT_CODE_SAVE emit_load_reg_with_object(emit, reg_dest, MP_OBJ_NEW_QSTR(qst)); @@ -439,6 +476,30 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop emit->stack_info[i].vtype = VTYPE_UNBOUND; } + char *qualified_name = NULL; + + #if N_DEBUG + scope_t *current_scope = scope; + vstr_t *qualified_name_vstr = vstr_new(qstr_len(current_scope->simple_name)); + size_t fragment_length = 0; + const byte *fragment_pointer; + for (;;) { + fragment_pointer = qstr_data(current_scope->simple_name, &fragment_length); + vstr_hint_size(qualified_name_vstr, fragment_length); + memmove(qualified_name_vstr->buf + fragment_length, qualified_name_vstr->buf, qualified_name_vstr->len); + memcpy(qualified_name_vstr->buf, fragment_pointer, fragment_length); + qualified_name_vstr->len += fragment_length; + if (current_scope->parent == NULL || current_scope->parent->simple_name == MP_QSTR__lt_module_gt_) { + break; + } + vstr_ins_char(qualified_name_vstr, 0, '.'); + current_scope = current_scope->parent; + } + qualified_name = vstr_null_terminated_str(qualified_name_vstr); + #else + (void)qualified_name; + #endif + mp_asm_base_start_pass(&emit->as->base, pass == MP_PASS_EMIT ? MP_ASM_PASS_EMIT : MP_ASM_PASS_COMPUTE); // generate code for entry to function @@ -448,7 +509,9 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop if (NEED_GLOBAL_EXC_HANDLER(emit)) { emit->code_state_start = SIZEOF_NLR_BUF; // for nlr_buf_t emit->code_state_start += 1; // for return_value - if (NEED_EXC_HANDLER_UNWIND(emit)) { + if (NEED_THROW_VAL(emit)) { + emit->code_state_start += 2; + } else if (NEED_EXC_HANDLER_UNWIND(emit)) { emit->code_state_start += 1; } } @@ -483,7 +546,7 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop } // Entry to function - ASM_ENTRY(emit->as, emit->stack_start + emit->n_state - num_locals_in_regs); + ASM_ENTRY(emit->as, emit->stack_start + emit->n_state - num_locals_in_regs, qualified_name); #if N_X86 asm_x86_mov_arg_to_r32(emit->as, 0, REG_PARENT_ARG_1); @@ -554,7 +617,7 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop if (emit->scope->scope_flags & MP_SCOPE_FLAG_GENERATOR) { mp_asm_base_data(&emit->as->base, ASM_WORD_SIZE, (uintptr_t)emit->start_offset); - ASM_ENTRY(emit->as, emit->code_state_start); + ASM_ENTRY(emit->as, emit->code_state_start, qualified_name); // Reset the state size for the state pointed to by REG_GENERATOR_STATE emit->code_state_start = 0; @@ -567,11 +630,11 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop ASM_MOV_REG_REG(emit->as, REG_GENERATOR_STATE, REG_PARENT_ARG_1); #endif - // Put throw value into LOCAL_IDX_EXC_VAL slot, for yield/yield-from + // Put throw value into LOCAL_IDX_THROW_VAL slot, for yield/yield-from #if N_X86 asm_x86_mov_arg_to_r32(emit->as, 1, REG_PARENT_ARG_2); #endif - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_PARENT_ARG_2); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_PARENT_ARG_2); // Load REG_FUN_TABLE with a pointer to mp_fun_table, found in the const_table ASM_LOAD_REG_REG_OFFSET(emit->as, REG_TEMP0, REG_GENERATOR_STATE, LOCAL_IDX_FUN_OBJ(emit)); @@ -586,7 +649,7 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop emit->stack_start = emit->code_state_start + SIZEOF_CODE_STATE; // Allocate space on C-stack for code_state structure, which includes state - ASM_ENTRY(emit->as, emit->stack_start + emit->n_state); + ASM_ENTRY(emit->as, emit->stack_start + emit->n_state, qualified_name); // Prepare incoming arguments for call to mp_setup_code_state @@ -652,6 +715,10 @@ static void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop } } } + + #if N_DEBUG + vstr_free(qualified_name_vstr); + #endif } static inline void emit_native_write_code_info_byte(emit_t *emit, byte val) { @@ -1135,6 +1202,7 @@ static exc_stack_entry_t *emit_native_pop_exc_stack(emit_t *emit) { return e; } +// This function will clobber REG_TEMP0 (and `reg` can be REG_TEMP0). static void emit_load_reg_with_object(emit_t *emit, int reg, mp_obj_t obj) { emit->scope->scope_flags |= MP_SCOPE_FLAG_HASCONSTS; size_t table_off = mp_emit_common_use_const_obj(emit->emit_common, obj); @@ -1163,7 +1231,7 @@ static void emit_native_label_assign(emit_t *emit, mp_uint_t l) { if (is_finally) { // Label is at start of finally handler: store TOS into exception slot vtype_kind_t vtype; - emit_pre_pop_reg(emit, &vtype, REG_TEMP0); + emit_access_stack(emit, 1, &vtype, REG_TEMP0); ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); } @@ -1216,8 +1284,12 @@ static void emit_native_global_exc_entry(emit_t *emit) { ASM_JUMP_IF_REG_ZERO(emit->as, REG_RET, start_label, true); } else { // Clear the unwind state - ASM_XOR_REG_REG(emit->as, REG_TEMP0, REG_TEMP0); - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_TEMP0); + ASM_CLR_REG(emit->as, REG_ZERO); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_UNWIND(emit), REG_ZERO); + + // clear nlr.ret_val, because it's passed to mp_native_raise regardless + // of whether there was an exception or not + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_ZERO); // Put PC of start code block into REG_LOCAL_1 ASM_MOV_REG_PCREL(emit->as, REG_LOCAL_1, start_label); @@ -1233,8 +1305,8 @@ static void emit_native_global_exc_entry(emit_t *emit) { ASM_JUMP_IF_REG_NONZERO(emit->as, REG_RET, global_except_label, true); // Clear PC of current code block, and jump there to resume execution - ASM_XOR_REG_REG(emit->as, REG_TEMP0, REG_TEMP0); - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_PC(emit), REG_TEMP0); + ASM_CLR_REG(emit->as, REG_ZERO); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_HANDLER_PC(emit), REG_ZERO); ASM_JUMP_REG(emit->as, REG_LOCAL_1); // Global exception handler: check for valid exception handler @@ -1274,8 +1346,9 @@ static void emit_native_global_exc_entry(emit_t *emit) { // This is the first entry of the generator - // Check LOCAL_IDX_EXC_VAL for any injected value - ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit)); + // Check LOCAL_IDX_THROW_VAL for any injected value + ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_THROW_VAL(emit)); + ASM_MOV_LOCAL_MP_OBJ_NULL(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2); emit_call(emit, MP_F_NATIVE_RAISE); } } @@ -1403,9 +1476,9 @@ static void emit_native_load_const_str(emit_t *emit, qstr qst) { static void emit_native_load_const_obj(emit_t *emit, mp_obj_t obj) { emit_native_pre(emit); - need_reg_single(emit, REG_RET, 0); - emit_load_reg_with_object(emit, REG_RET, obj); - emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET); + need_reg_single(emit, REG_TEMP0, 0); + emit_load_reg_with_object(emit, REG_TEMP0, obj); + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_TEMP0); } static void emit_native_load_null(emit_t *emit) { @@ -1483,6 +1556,7 @@ static void emit_native_load_attr(emit_t *emit, qstr qst) { } static void emit_native_load_method(emit_t *emit, qstr qst, bool is_super) { + DEBUG_printf("load_method(%s, %d)\n", qstr_str(qst), is_super); if (is_super) { emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_2, 3); // arg2 = dest ptr emit_get_stack_pointer_to_reg_for_push(emit, REG_ARG_2, 2); // arg2 = dest ptr @@ -1541,57 +1615,50 @@ static void emit_native_load_subscr(emit_t *emit) { switch (vtype_base) { case VTYPE_PTR8: { // pointer to 8-bit memory - // TODO optimise to use thumb ldrb r1, [r2, r3] + #ifdef ASM_LOAD8_REG_REG_OFFSET + ASM_LOAD8_REG_REG_OFFSET(emit->as, REG_RET, reg_base, index_value); + #else if (index_value != 0) { // index is non-zero - #if N_THUMB - if (index_value > 0 && index_value < 32) { - asm_thumb_ldrb_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value); - break; - } - #endif need_reg_single(emit, reg_index, 0); ASM_MOV_REG_IMM(emit->as, reg_index, index_value); ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add index to base reg_base = reg_index; } ASM_LOAD8_REG_REG(emit->as, REG_RET, reg_base); // load from (base+index) + #endif break; } case VTYPE_PTR16: { // pointer to 16-bit memory + #ifdef ASM_LOAD16_REG_REG_OFFSET + ASM_LOAD16_REG_REG_OFFSET(emit->as, REG_RET, reg_base, index_value); + #else if (index_value != 0) { // index is a non-zero immediate - #if N_THUMB - if (index_value > 0 && index_value < 32) { - asm_thumb_ldrh_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value); - break; - } - #endif need_reg_single(emit, reg_index, 0); ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1); ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base reg_base = reg_index; } ASM_LOAD16_REG_REG(emit->as, REG_RET, reg_base); // load from (base+2*index) + #endif break; } case VTYPE_PTR32: { // pointer to 32-bit memory + #ifdef ASM_LOAD32_REG_REG_OFFSET + ASM_LOAD32_REG_REG_OFFSET(emit->as, REG_RET, reg_base, index_value); + #else if (index_value != 0) { // index is a non-zero immediate - #if N_THUMB - if (index_value > 0 && index_value < 32) { - asm_thumb_ldr_rlo_rlo_i5(emit->as, REG_RET, reg_base, index_value); - break; - } - #endif need_reg_single(emit, reg_index, 0); ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 2); ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 4*index to base reg_base = reg_index; } ASM_LOAD32_REG_REG(emit->as, REG_RET, reg_base); // load from (base+4*index) + #endif break; } default: @@ -1612,25 +1679,36 @@ static void emit_native_load_subscr(emit_t *emit) { switch (vtype_base) { case VTYPE_PTR8: { // pointer to 8-bit memory - // TODO optimise to use thumb ldrb r1, [r2, r3] + #ifdef ASM_LOAD8_REG_REG_REG + ASM_LOAD8_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index); + #else ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_LOAD8_REG_REG(emit->as, REG_RET, REG_ARG_1); // store value to (base+index) + #endif break; } case VTYPE_PTR16: { // pointer to 16-bit memory + #ifdef ASM_LOAD16_REG_REG_REG + ASM_LOAD16_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index); + #else ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_LOAD16_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+2*index) + #endif break; } case VTYPE_PTR32: { // pointer to word-size memory + #ifdef ASM_LOAD32_REG_REG_REG + ASM_LOAD32_REG_REG_REG(emit->as, REG_RET, REG_ARG_1, reg_index); + #else ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_LOAD32_REG_REG(emit->as, REG_RET, REG_ARG_1); // load from (base+4*index) + #endif break; } default: @@ -1773,63 +1851,47 @@ static void emit_native_store_subscr(emit_t *emit) { switch (vtype_base) { case VTYPE_PTR8: { // pointer to 8-bit memory - // TODO optimise to use thumb strb r1, [r2, r3] + #ifdef ASM_STORE8_REG_REG_OFFSET + ASM_STORE8_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value); + #else if (index_value != 0) { // index is non-zero - #if N_THUMB - if (index_value > 0 && index_value < 32) { - asm_thumb_strb_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value); - break; - } - #endif ASM_MOV_REG_IMM(emit->as, reg_index, index_value); - #if N_ARM - asm_arm_strb_reg_reg_reg(emit->as, reg_value, reg_base, reg_index); - return; - #endif ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add index to base reg_base = reg_index; } ASM_STORE8_REG_REG(emit->as, reg_value, reg_base); // store value to (base+index) + #endif break; } case VTYPE_PTR16: { // pointer to 16-bit memory + #ifdef ASM_STORE16_REG_REG_OFFSET + ASM_STORE16_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value); + #else if (index_value != 0) { // index is a non-zero immediate - #if N_THUMB - if (index_value > 0 && index_value < 32) { - asm_thumb_strh_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value); - break; - } - #endif ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 1); ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 2*index to base reg_base = reg_index; } ASM_STORE16_REG_REG(emit->as, reg_value, reg_base); // store value to (base+2*index) + #endif break; } case VTYPE_PTR32: { // pointer to 32-bit memory + #ifdef ASM_STORE32_REG_REG_OFFSET + ASM_STORE32_REG_REG_OFFSET(emit->as, reg_value, reg_base, index_value); + #else if (index_value != 0) { // index is a non-zero immediate - #if N_THUMB - if (index_value > 0 && index_value < 32) { - asm_thumb_str_rlo_rlo_i5(emit->as, reg_value, reg_base, index_value); - break; - } - #endif - #if N_ARM - ASM_MOV_REG_IMM(emit->as, reg_index, index_value); - asm_arm_str_reg_reg_reg(emit->as, reg_value, reg_base, reg_index); - return; - #endif ASM_MOV_REG_IMM(emit->as, reg_index, index_value << 2); ASM_ADD_REG_REG(emit->as, reg_index, reg_base); // add 4*index to base reg_base = reg_index; } ASM_STORE32_REG_REG(emit->as, reg_value, reg_base); // store value to (base+4*index) + #endif break; } default: @@ -1860,37 +1922,36 @@ static void emit_native_store_subscr(emit_t *emit) { switch (vtype_base) { case VTYPE_PTR8: { // pointer to 8-bit memory - // TODO optimise to use thumb strb r1, [r2, r3] - #if N_ARM - asm_arm_strb_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index); - break; - #endif + #ifdef ASM_STORE8_REG_REG_REG + ASM_STORE8_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index); + #else ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_STORE8_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+index) + #endif break; } case VTYPE_PTR16: { // pointer to 16-bit memory - #if N_ARM - asm_arm_strh_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index); - break; - #endif + #ifdef ASM_STORE16_REG_REG_REG + ASM_STORE16_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index); + #else ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_STORE16_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+2*index) + #endif break; } case VTYPE_PTR32: { // pointer to 32-bit memory - #if N_ARM - asm_arm_str_reg_reg_reg(emit->as, reg_value, REG_ARG_1, reg_index); - break; - #endif + #ifdef ASM_STORE32_REG_REG_REG + ASM_STORE32_REG_REG_REG(emit->as, reg_value, REG_ARG_1, reg_index); + #else ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_ADD_REG_REG(emit->as, REG_ARG_1, reg_index); // add index to base ASM_STORE32_REG_REG(emit->as, reg_value, REG_ARG_1); // store value to (base+4*index) + #endif break; } default: @@ -2133,6 +2194,7 @@ static void emit_native_setup_with(emit_t *emit, mp_uint_t label) { } static void emit_native_setup_block(emit_t *emit, mp_uint_t label, int kind) { + DEBUG_printf("setup_block(%d, %d)\n", (int)label, kind); if (kind == MP_EMIT_SETUP_BLOCK_WITH) { emit_native_setup_with(emit, label); } else { @@ -2202,14 +2264,39 @@ static void emit_native_with_cleanup(emit_t *emit, mp_uint_t label) { // Replace exception with MP_OBJ_NULL. emit_native_label_assign(emit, *emit->label_slot); - ASM_MOV_REG_IMM(emit->as, REG_TEMP0, (mp_uint_t)MP_OBJ_NULL); - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); + ASM_MOV_LOCAL_MP_OBJ_NULL(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); // end of with cleanup nlr_catch block emit_native_label_assign(emit, *emit->label_slot + 1); // Exception is in nlr_buf.ret_val slot + adjust_stack(emit, 1); +} + +#if MICROPY_PY_ASYNC_AWAIT +static void emit_native_async_with_setup_finally(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump) { + // The async-with body has executed and no exception was raised, the execution fell through to this point. + // Stack: (..., ctx_mgr) + + // Insert a dummy value into the stack so the stack has the same layout to execute the code starting at label_aexit_no_exc + emit_native_adjust_stack_size(emit, 1); // push dummy value, it won't ever be used + emit_native_rot_two(emit); + emit_native_load_const_tok(emit, MP_TOKEN_KW_NONE); // to tell end_finally there's no exception + emit_native_rot_two(emit); + // Stack: (..., , None, ctx_mgr) + emit_native_jump(emit, label_aexit_no_exc); // jump to code to call __aexit__ + emit_native_adjust_stack_size(emit, -1); + + // Start of "finally" block which is entered via one of: an exception propagating out, a return, an unwind jump. + emit_native_label_assign(emit, label_finally_block); + + // Detect which case we have by the local exception slot holding an exception or not. + emit_pre_pop_discard(emit); + ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit)); // get exception + emit_post_push_reg(emit, VTYPE_PYOBJ, REG_ARG_1); + ASM_JUMP_IF_REG_ZERO(emit->as, REG_ARG_1, label_ret_unwind_jump, false); // if not an exception then we have return or unwind jump. } +#endif static void emit_native_end_finally(emit_t *emit) { // logic: @@ -2217,7 +2304,9 @@ static void emit_native_end_finally(emit_t *emit) { // if exc == None: pass // else: raise exc // the check if exc is None is done in the MP_F_NATIVE_RAISE stub - emit_native_pre(emit); + DEBUG_printf("end_finally\n"); + + emit_pre_pop_discard(emit); ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit)); emit_call(emit, MP_F_NATIVE_RAISE); @@ -2241,6 +2330,8 @@ static void emit_native_get_iter(emit_t *emit, bool use_stack) { // perhaps the difficult one, as we want to rewrite for loops using native code // in cases where we iterate over a Python object, can we use normal runtime calls? + DEBUG_printf("get_iter(%d)\n", use_stack); + vtype_kind_t vtype; emit_pre_pop_reg(emit, &vtype, REG_ARG_1); assert(vtype == VTYPE_PYOBJ); @@ -2280,8 +2371,7 @@ static void emit_native_for_iter_end(emit_t *emit) { static void emit_native_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) { if (within_exc_handler) { // Cancel any active exception so subsequent handlers don't see it - ASM_MOV_REG_IMM(emit->as, REG_TEMP0, (mp_uint_t)MP_OBJ_NULL); - ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); + ASM_MOV_LOCAL_MP_OBJ_NULL(emit->as, LOCAL_IDX_EXC_VAL(emit), REG_TEMP0); } else { emit_native_leave_exc_stack(emit, false); } @@ -2429,7 +2519,7 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { #if N_X64 asm_x64_xor_r64_r64(emit->as, REG_RET, REG_RET); asm_x64_cmp_r64_with_r64(emit->as, reg_rhs, REG_ARG_2); - static byte ops[6 + 6] = { + static const byte ops[6 + 6] = { // unsigned ASM_X64_CC_JB, ASM_X64_CC_JA, @@ -2449,7 +2539,7 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { #elif N_X86 asm_x86_xor_r32_r32(emit->as, REG_RET, REG_RET); asm_x86_cmp_r32_with_r32(emit->as, reg_rhs, REG_ARG_2); - static byte ops[6 + 6] = { + static const byte ops[6 + 6] = { // unsigned ASM_X86_CC_JB, ASM_X86_CC_JA, @@ -2469,7 +2559,7 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { #elif N_THUMB asm_thumb_cmp_rlo_rlo(emit->as, REG_ARG_2, reg_rhs); if (asm_thumb_allow_armv7m(emit->as)) { - static uint16_t ops[6 + 6] = { + static const uint16_t ops[6 + 6] = { // unsigned ASM_THUMB_OP_ITE_CC, ASM_THUMB_OP_ITE_HI, @@ -2489,7 +2579,7 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { asm_thumb_mov_rlo_i8(emit->as, REG_RET, 1); asm_thumb_mov_rlo_i8(emit->as, REG_RET, 0); } else { - static uint16_t ops[6 + 6] = { + static const uint16_t ops[6 + 6] = { // unsigned ASM_THUMB_CC_CC, ASM_THUMB_CC_HI, @@ -2512,7 +2602,7 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { } #elif N_ARM asm_arm_cmp_reg_reg(emit->as, REG_ARG_2, reg_rhs); - static uint ccs[6 + 6] = { + static const uint ccs[6 + 6] = { // unsigned ASM_ARM_CC_CC, ASM_ARM_CC_HI, @@ -2530,7 +2620,7 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { }; asm_arm_setcc_reg(emit->as, REG_RET, ccs[op_idx]); #elif N_XTENSA || N_XTENSAWIN - static uint8_t ccs[6 + 6] = { + static const uint8_t ccs[6 + 6] = { // unsigned ASM_XTENSA_CC_LTU, 0x80 | ASM_XTENSA_CC_LTU, // for GTU we'll swap args @@ -2552,6 +2642,38 @@ static void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) { } else { asm_xtensa_setcc_reg_reg_reg(emit->as, cc & ~0x80, REG_RET, reg_rhs, REG_ARG_2); } + #elif N_RV32 + (void)op_idx; + switch (op) { + case MP_BINARY_OP_LESS: + asm_rv32_meta_comparison_lt(emit->as, REG_ARG_2, reg_rhs, REG_RET, vtype_lhs == VTYPE_UINT); + break; + + case MP_BINARY_OP_MORE: + asm_rv32_meta_comparison_lt(emit->as, reg_rhs, REG_ARG_2, REG_RET, vtype_lhs == VTYPE_UINT); + break; + + case MP_BINARY_OP_EQUAL: + asm_rv32_meta_comparison_eq(emit->as, REG_ARG_2, reg_rhs, REG_RET); + break; + + case MP_BINARY_OP_LESS_EQUAL: + asm_rv32_meta_comparison_le(emit->as, REG_ARG_2, reg_rhs, REG_RET, vtype_lhs == VTYPE_UINT); + break; + + case MP_BINARY_OP_MORE_EQUAL: + asm_rv32_meta_comparison_le(emit->as, reg_rhs, REG_ARG_2, REG_RET, vtype_lhs == VTYPE_UINT); + break; + + case MP_BINARY_OP_NOT_EQUAL: + asm_rv32_meta_comparison_ne(emit->as, reg_rhs, REG_ARG_2, REG_RET); + break; + + default: + break; + } + #elif N_DEBUG + asm_debug_setcc_reg_reg_reg(emit->as, op_idx, REG_RET, REG_ARG_2, reg_rhs); #else #error not implemented #endif @@ -2792,6 +2914,7 @@ static void emit_native_call_function(emit_t *emit, mp_uint_t n_positional, mp_u } static void emit_native_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) { + DEBUG_printf("call_method(%d, %d, %d)\n", n_positional, n_keyword, star_flags); if (star_flags) { emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, n_positional + 2 * n_keyword + 3); // pointer to args emit_call_with_2_imm_args(emit, MP_F_CALL_METHOD_N_KW_VAR, 1, REG_ARG_1, n_positional | (n_keyword << 8), REG_ARG_2); @@ -2858,6 +2981,7 @@ static void emit_native_return_value(emit_t *emit) { } static void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) { + DEBUG_printf("raise_varargs(%d)\n", n_args); (void)n_args; assert(n_args == 1); vtype_kind_t vtype_exc; @@ -2873,6 +2997,8 @@ static void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) { static void emit_native_yield(emit_t *emit, int kind) { // Note: 1 (yield) or 3 (yield from) labels are reserved for this function, starting at *emit->label_slot + DEBUG_printf("yield(%d)\n", kind); + if (emit->do_viper_types) { mp_raise_NotImplementedError(MP_ERROR_TEXT("native yield")); } @@ -2928,18 +3054,21 @@ static void emit_native_yield(emit_t *emit, int kind) { emit_native_adjust_stack_size(emit, 1); // send_value if (kind == MP_EMIT_YIELD_VALUE) { - // Check LOCAL_IDX_EXC_VAL for any injected value - ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_EXC_VAL(emit)); + // Check LOCAL_IDX_THROW_VAL for any injected value + ASM_MOV_REG_LOCAL(emit->as, REG_ARG_1, LOCAL_IDX_THROW_VAL(emit)); + ASM_MOV_LOCAL_MP_OBJ_NULL(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2); emit_call(emit, MP_F_NATIVE_RAISE); } else { // Label loop entry emit_native_label_assign(emit, *emit->label_slot + 2); // Get the next item from the delegate generator + ASM_MOV_REG_LOCAL(emit->as, REG_ARG_3, LOCAL_IDX_THROW_VAL(emit)); // throw_value + ASM_MOV_REG_IMM(emit->as, REG_ARG_2, (mp_uint_t)MP_OBJ_NULL); + ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_THROW_VAL(emit), REG_ARG_2); vtype_kind_t vtype; emit_pre_pop_reg(emit, &vtype, REG_ARG_2); // send_value emit_access_stack(emit, 1, &vtype, REG_ARG_1); // generator - ASM_MOV_REG_LOCAL(emit->as, REG_ARG_3, LOCAL_IDX_EXC_VAL(emit)); // throw_value emit_post_push_reg(emit, VTYPE_PYOBJ, REG_ARG_3); emit_get_stack_pointer_to_reg_for_pop(emit, REG_ARG_3, 1); // ret_value emit_call(emit, MP_F_NATIVE_YIELD_FROM); @@ -2963,7 +3092,6 @@ static void emit_native_start_except_handler(emit_t *emit) { } static void emit_native_end_except_handler(emit_t *emit) { - adjust_stack(emit, -1); // pop the exception (end_finally didn't use it) } const emit_method_table_t EXPORT_FUN(method_table) = { @@ -3012,6 +3140,9 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_unwind_jump, emit_native_setup_block, emit_native_with_cleanup, + #if MICROPY_PY_ASYNC_AWAIT + emit_native_async_with_setup_finally, + #endif emit_native_end_finally, emit_native_get_iter, emit_native_for_iter, diff --git a/py/emitndebug.c b/py/emitndebug.c new file mode 100644 index 00000000000..e49c5cdbffa --- /dev/null +++ b/py/emitndebug.c @@ -0,0 +1,281 @@ +// native-debug specific stuff + +#include "py/mpconfig.h" + +#if MICROPY_EMIT_NATIVE_DEBUG + +#include "py/asmbase.h" +#include "py/nativeglue.h" + +#define asm_debug_printf(as, fmt, ...) \ + do { \ + if (as->base.pass == MP_ASM_PASS_EMIT) { \ + if (fmt[0] != 'E') { \ + mp_printf(MICROPY_EMIT_NATIVE_DEBUG_PRINTER, " "); \ + } \ + if (as->base.suppress) { \ + mp_printf(MICROPY_EMIT_NATIVE_DEBUG_PRINTER, "dead_code "); \ + } \ + mp_printf(MICROPY_EMIT_NATIVE_DEBUG_PRINTER, fmt, __VA_ARGS__); \ + } \ + } while (0) + +enum { + ASM_DEBUG_REG_R00, + ASM_DEBUG_REG_R01, + ASM_DEBUG_REG_R02, + ASM_DEBUG_REG_R03, + ASM_DEBUG_REG_R04, + ASM_DEBUG_REG_R05, + ASM_DEBUG_REG_R06, + ASM_DEBUG_REG_R07, + ASM_DEBUG_REG_R08, + ASM_DEBUG_REG_R09, + ASM_DEBUG_REG_R10, + ASM_DEBUG_REG_R11, +}; + +typedef struct _asm_debug_t { + mp_asm_base_t base; +} asm_debug_t; + +static const char *const reg_name_table[] = { + "r_ret", + "r_arg1", + "r_arg2", + "r_arg3", + "r_arg4", + "r_temp0", + "r_temp1", + "r_temp2", + "r_local1", + "r_local2", + "r_local3", + "r_fun_table", +}; + +static const char *const fun_name_table[MP_F_NUMBER_OF] = { + [MP_F_CONVERT_OBJ_TO_NATIVE] = "convert_obj_to_native", + [MP_F_CONVERT_NATIVE_TO_OBJ] = "convert_native_to_obj", + [MP_F_NATIVE_SWAP_GLOBALS] = "native_swap_globals", + [MP_F_LOAD_NAME] = "load_name", + [MP_F_LOAD_GLOBAL] = "load_global", + [MP_F_LOAD_BUILD_CLASS] = "load_build_class", + [MP_F_LOAD_ATTR] = "load_attr", + [MP_F_LOAD_METHOD] = "load_method", + [MP_F_LOAD_SUPER_METHOD] = "load_super_method", + [MP_F_STORE_NAME] = "store_name", + [MP_F_STORE_GLOBAL] = "store_global", + [MP_F_STORE_ATTR] = "store_attr", + [MP_F_OBJ_SUBSCR] = "obj_subscr", + [MP_F_OBJ_IS_TRUE] = "obj_is_true", + [MP_F_UNARY_OP] = "unary_op", + [MP_F_BINARY_OP] = "binary_op", + [MP_F_BUILD_TUPLE] = "build_tuple", + [MP_F_BUILD_LIST] = "build_list", + [MP_F_BUILD_MAP] = "build_map", + [MP_F_BUILD_SET] = "build_set", + [MP_F_STORE_SET] = "store_set", + [MP_F_LIST_APPEND] = "list_append", + [MP_F_STORE_MAP] = "store_map", + [MP_F_MAKE_FUNCTION_FROM_PROTO_FUN] = "make_function_from_proto_fun", + [MP_F_NATIVE_CALL_FUNCTION_N_KW] = "native_call_function_n_kw", + [MP_F_CALL_METHOD_N_KW] = "call_method_n_kw", + [MP_F_CALL_METHOD_N_KW_VAR] = "call_method_n_kw_var", + [MP_F_NATIVE_GETITER] = "native_getiter", + [MP_F_NATIVE_ITERNEXT] = "native_iternext", + [MP_F_NLR_PUSH] = "nlr_push", + [MP_F_NLR_POP] = "nlr_pop", + [MP_F_NATIVE_RAISE] = "native_raise", + [MP_F_IMPORT_NAME] = "import_name", + [MP_F_IMPORT_FROM] = "import_from", + [MP_F_IMPORT_ALL] = "import_all", + [MP_F_NEW_SLICE] = "new_slice", + [MP_F_UNPACK_SEQUENCE] = "unpack_sequence", + [MP_F_UNPACK_EX] = "unpack_ex", + [MP_F_DELETE_NAME] = "delete_name", + [MP_F_DELETE_GLOBAL] = "delete_global", + [MP_F_NEW_CLOSURE] = "new_closure", + [MP_F_ARG_CHECK_NUM_SIG] = "arg_check_num_sig", + [MP_F_SETUP_CODE_STATE] = "setup_code_state", + [MP_F_SMALL_INT_FLOOR_DIVIDE] = "small_int_floor_divide", + [MP_F_SMALL_INT_MODULO] = "small_int_modulo", + [MP_F_NATIVE_YIELD_FROM] = "native_yield_from", + [MP_F_SETJMP] = "setjmp", +}; + +static void asm_debug_end_pass(asm_debug_t *as) { + (void)as; +} + +static void asm_debug_entry(asm_debug_t *as, int num_locals, char *name) { + asm_debug_printf(as, "ENTRY(%s, num_locals=%d)\n", name != NULL ? name : "?", num_locals); +} + +static void asm_debug_exit(asm_debug_t *as) { + asm_debug_printf(as, "EXIT(%u)\n", 0); +} + +static void asm_debug_fun(asm_debug_t *as, const char *op, int fun_idx) { + asm_debug_printf(as, "%s(%s)\n", op, fun_name_table[fun_idx]); +} + +static void asm_debug_reg(asm_debug_t *as, const char *op, int reg) { + asm_debug_printf(as, "%s(%s)\n", op, reg_name_table[reg]); +} + +static void asm_debug_label(asm_debug_t *as, const char *op, unsigned int label) { + asm_debug_printf(as, "%s(label_%u)\n", op, label); +} + +static void asm_debug_reg_imm(asm_debug_t *as, const char *op, int reg, int imm) { + asm_debug_printf(as, "%s(%s, %d=0x%x)\n", op, reg_name_table[reg], imm, imm); +} + +#if !MICROPY_PERSISTENT_CODE_SAVE +static void asm_debug_reg_qstr(asm_debug_t *as, const char *op, int reg, int qst) { + asm_debug_printf(as, "%s(%s, %s)\n", op, reg_name_table[reg], qstr_str(qst)); +} +#endif + +static void asm_debug_reg_reg(asm_debug_t *as, const char *op, int reg1, int reg2) { + asm_debug_printf(as, "%s(%s, %s)\n", op, reg_name_table[reg1], reg_name_table[reg2]); +} + +static void asm_debug_reg_local(asm_debug_t *as, const char *op, int reg, unsigned int local) { + asm_debug_printf(as, "%s(%s, local_%u)\n", op, reg_name_table[reg], local); +} + +static void asm_debug_reg_label(asm_debug_t *as, const char *op, int reg, unsigned int label) { + asm_debug_printf(as, "%s(%s, label_%u)\n", op, reg_name_table[reg], label); +} + +static void asm_debug_local_reg(asm_debug_t *as, const char *op, int local, int reg) { + asm_debug_printf(as, "%s(local_%d, %s)\n", op, local, reg_name_table[reg]); +} + +static void asm_debug_reg_label_bool(asm_debug_t *as, const char *op, int reg, unsigned int label, bool b) { + asm_debug_printf(as, "%s(%s, label_%u, %s)\n", op, reg_name_table[reg], label, b ? "true" : "false"); +} + +static void asm_debug_reg_reg_offset(asm_debug_t *as, const char *op, int reg1, int reg2, int offset) { + asm_debug_printf(as, "%s(%s, %s, %d)\n", op, reg_name_table[reg1], reg_name_table[reg2], offset); +} + +static void asm_debug_reg_reg_label(asm_debug_t *as, const char *op, int reg1, int reg2, unsigned int label) { + asm_debug_printf(as, "%s(%s, %s, label_%u)\n", op, reg_name_table[reg1], reg_name_table[reg2], label); +} + +static void asm_debug_setcc_reg_reg_reg(asm_debug_t *as, int op, int reg1, int reg2, int reg3) { + asm_debug_printf(as, "setcc(%d, %s, %s, %s)\n", op, reg_name_table[reg1], reg_name_table[reg2], reg_name_table[reg3]); +} + +// The following macros provide a (mostly) arch-independent API to +// generate native code, and are used by the native emitter. + +#define ASM_WORD_SIZE (8) + +#define REG_RET ASM_DEBUG_REG_R00 +#define REG_ARG_1 ASM_DEBUG_REG_R01 +#define REG_ARG_2 ASM_DEBUG_REG_R02 +#define REG_ARG_3 ASM_DEBUG_REG_R03 +#define REG_ARG_4 ASM_DEBUG_REG_R04 + +#define REG_TEMP0 ASM_DEBUG_REG_R05 +#define REG_TEMP1 ASM_DEBUG_REG_R06 +#define REG_TEMP2 ASM_DEBUG_REG_R07 + +#define REG_LOCAL_1 ASM_DEBUG_REG_R08 +#define REG_LOCAL_2 ASM_DEBUG_REG_R09 +#define REG_LOCAL_3 ASM_DEBUG_REG_R10 +#define REG_LOCAL_NUM (3) + +// Holds a pointer to mp_fun_table +#define REG_FUN_TABLE ASM_DEBUG_REG_R11 + +#define ASM_T asm_debug_t +#define ASM_END_PASS asm_debug_end_pass +#define ASM_ENTRY(as, num_locals, name) \ + asm_debug_entry(as, num_locals, name) +#define ASM_EXIT(as) \ + asm_debug_exit(as) + +#define ASM_JUMP(as, label) \ + asm_debug_label(as, "jump", label) +#define ASM_JUMP_IF_REG_ZERO(as, reg, label, bool_test) \ + asm_debug_reg_label_bool(as, "jump_if_reg_zero", reg, label, bool_test) +#define ASM_JUMP_IF_REG_NONZERO(as, reg, label, bool_test) \ + asm_debug_reg_label_bool(as, "jump_if_reg_nonzero", reg, label, bool_test) +#define ASM_JUMP_IF_REG_EQ(as, reg1, reg2, label) \ + asm_debug_reg_reg_label(as, "jump_if_reg_eq", reg1, reg2, label) +#define ASM_JUMP_REG(as, reg) \ + asm_debug_reg(as, "jump_reg", reg) +#define ASM_CALL_IND(as, idx) \ + asm_debug_fun(as, "call_ind", idx) + +#define ASM_MOV_LOCAL_REG(as, local_num, reg_src) \ + asm_debug_local_reg(as, "mov_local_reg", local_num, reg_src) +#define ASM_MOV_REG_IMM(as, reg_dest, imm) \ + asm_debug_reg_imm(as, "mov_reg_imm", reg_dest, imm) +#define ASM_MOV_REG_QSTR(as, reg_dest, qst) \ + asm_debug_reg_qstr(as, "mov_reg_qstr", reg_dest, qst) +#define ASM_MOV_REG_LOCAL(as, reg_dest, local_num) \ + asm_debug_reg_local(as, "mov_reg_local", reg_dest, local_num) +#define ASM_MOV_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "mov_reg_reg", reg_dest, reg_src) +#define ASM_MOV_REG_LOCAL_ADDR(as, reg_dest, local_num) \ + asm_debug_reg_local(as, "mov_reg_local_addr", reg_dest, local_num) +#define ASM_MOV_REG_PCREL(as, reg_dest, label) \ + asm_debug_reg_label(as, "mov_reg_pcrel", reg_dest, label) + +#define ASM_NOT_REG(as, reg_dest) \ + asm_debug_reg(as, "not", reg_dest) +#define ASM_NEG_REG(as, reg_dest) \ + asm_debug_reg(as, "neg", reg_dest) +#define ASM_LSL_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "lsl", reg_dest, reg_src) +#define ASM_LSR_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "lsr", reg_dest, reg_src) +#define ASM_ASR_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "asr", reg_dest, reg_src) +#define ASM_OR_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "or", reg_dest, reg_src) +#define ASM_XOR_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "xor", reg_dest, reg_src) +#define ASM_AND_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "and", reg_dest, reg_src) +#define ASM_ADD_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "add", reg_dest, reg_src) +#define ASM_SUB_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "sub", reg_dest, reg_src) +#define ASM_MUL_REG_REG(as, reg_dest, reg_src) \ + asm_debug_reg_reg(as, "mul", reg_dest, reg_src) + +#define ASM_LOAD_REG_REG_OFFSET(as, reg_dest, reg_base, word_offset) \ + asm_debug_reg_reg_offset(as, "load", reg_dest, reg_base, word_offset) +#define ASM_LOAD8_REG_REG(as, reg_dest, reg_base) \ + asm_debug_reg_reg(as, "load8", reg_dest, reg_base) +#define ASM_LOAD16_REG_REG(as, reg_dest, reg_base) \ + asm_debug_reg_reg(as, "load16", reg_dest, reg_base) +#define ASM_LOAD16_REG_REG_OFFSET(as, reg_dest, reg_base, uint16_offset) \ + asm_debug_reg_reg_offset(as, "load16", reg_dest, reg_base, uint16_offset) +#define ASM_LOAD32_REG_REG(as, reg_dest, reg_base) \ + asm_debug_reg_reg(as, "load32", reg_dest, reg_base) + +#define ASM_STORE_REG_REG_OFFSET(as, reg_src, reg_base, word_offset) \ + asm_debug_reg_reg_offset(as, "store", reg_src, reg_base, word_offset) +#define ASM_STORE8_REG_REG(as, reg_src, reg_base) \ + asm_debug_reg_reg(as, "store8", reg_src, reg_base) +#define ASM_STORE16_REG_REG(as, reg_src, reg_base) \ + asm_debug_reg_reg(as, "store16", reg_src, reg_base) +#define ASM_STORE32_REG_REG(as, reg_src, reg_base) \ + asm_debug_reg_reg(as, "store32", reg_src, reg_base) + +// Word indices of REG_LOCAL_x in nlr_buf_t +#define NLR_BUF_IDX_LOCAL_1 (5) // rbx + +#define N_DEBUG (1) +#define EXPORT_FUN(name) emit_native_debug_##name +#include "py/emitnative.c" + +#endif diff --git a/py/emitnrv32.c b/py/emitnrv32.c new file mode 100644 index 00000000000..4a441000931 --- /dev/null +++ b/py/emitnrv32.c @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, https://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +// RISC-V RV32 specific stuff + +#include "py/mpconfig.h" + +#if MICROPY_EMIT_RV32 + +// this is defined so that the assembler exports generic assembler API macros +#define GENERIC_ASM_API (1) +#include "py/asmrv32.h" + +// Word indices of REG_LOCAL_x in nlr_buf_t +#define NLR_BUF_IDX_LOCAL_1 (6) // S3 + +#define N_RV32 (1) +#define EXPORT_FUN(name) emit_native_rv32_##name +#include "py/emitnative.c" + +#endif diff --git a/py/formatfloat.c b/py/formatfloat.c index b4348122ff4..1ea34f84bf7 100644 --- a/py/formatfloat.c +++ b/py/formatfloat.c @@ -33,394 +33,537 @@ #include #include #include "py/formatfloat.h" +#include "py/parsenum.h" /*********************************************************************** Routine for converting a arbitrary floating point number into a string. - The code in this function was inspired from Fred Bayer's pdouble.c. - Since pdouble.c was released as Public Domain, I'm releasing this - code as public domain as well. + The code in this function was inspired from Dave Hylands's previous + version, which was itself inspired from Fred Bayer's pdouble.c. The original code can be found in https://github.com/dhylands/format-float - Dave Hylands - ***********************************************************************/ -#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT -// 1 sign bit, 8 exponent bits, and 23 mantissa bits. -// exponent values 0 and 255 are reserved, exponent can be 1 to 254. -// exponent is stored with a bias of 127. -// The min and max floats are on the order of 1x10^37 and 1x10^-37 - -#define FPTYPE float -#define FPCONST(x) x##F -#define FPROUND_TO_ONE 0.9999995F -#define FPDECEXP 32 -#define FPMIN_BUF_SIZE 6 // +9e+99 +// Float formatting debug code is intended for use in ports/unix only, +// as it uses the libc float printing function as a reference. +#define DEBUG_FLOAT_FORMATTING 0 + +#if DEBUG_FLOAT_FORMATTING +#define DEBUG_PRINTF(...) fprintf(stderr, __VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +#if MICROPY_FLOAT_FORMAT_IMPL == MICROPY_FLOAT_FORMAT_IMPL_EXACT || MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +#define MP_FFUINT_FMT "%lu" +#else +#define MP_FFUINT_FMT "%u" +#endif + +static inline int fp_expval(mp_float_t x) { + mp_float_union_t fb = { x }; + return (int)fb.p.exp - MP_FLOAT_EXP_OFFSET; +} -#define FLT_SIGN_MASK 0x80000000 +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE -static inline int fp_signbit(float x) { - mp_float_union_t fb = {x}; - return fb.i & FLT_SIGN_MASK; +static inline int fp_isless1(mp_float_t x) { + return x < 1.0; } -#define fp_isnan(x) isnan(x) -#define fp_isinf(x) isinf(x) -static inline int fp_iszero(float x) { - mp_float_union_t fb = {x}; - return fb.i == 0; + +static inline int fp_iszero(mp_float_t x) { + return x == 0.0; } -static inline int fp_isless1(float x) { - mp_float_union_t fb = {x}; + +#if MICROPY_FLOAT_FORMAT_IMPL != MICROPY_FLOAT_FORMAT_IMPL_APPROX +static inline int fp_equal(mp_float_t x, mp_float_t y) { + return x == y; +} +#else +static inline mp_float_t fp_diff(mp_float_t x, mp_float_t y) { + return x - y; +} +#endif + +#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT + +// The functions below are roughly equivalent to the ones above, +// but they are optimized to reduce code footprint by skipping +// handling for special values such as nan, inf, +/-0.0 +// for ports where FP support is done in software. +// +// They also take into account lost bits of REPR_C as needed. + +static inline int fp_isless1(mp_float_t x) { + mp_float_union_t fb = { x }; return fb.i < 0x3f800000; } -#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +static inline int fp_iszero(mp_float_t x) { + mp_float_union_t x_check = { x }; + return !x_check.i; // this is valid for REPR_C as well +} -// CIRCUITPY-CHANGE: prevent warnings -#pragma GCC diagnostic ignored "-Wfloat-equal" -#define FPTYPE double -#define FPCONST(x) x -#define FPROUND_TO_ONE 0.999999999995 -#define FPDECEXP 256 -#define FPMIN_BUF_SIZE 7 // +9e+199 -#define fp_signbit(x) signbit(x) -#define fp_isnan(x) isnan(x) -#define fp_isinf(x) isinf(x) -#define fp_iszero(x) (x == 0) -#define fp_isless1(x) (x < 1.0) +#if MICROPY_FLOAT_FORMAT_IMPL != MICROPY_FLOAT_FORMAT_IMPL_APPROX +static inline int fp_equal(mp_float_t x, mp_float_t y) { + mp_float_union_t x_check = { x }; + mp_float_union_t y_check = { y }; + #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C + return (x_check.i & ~3) == (y_check.i & ~3); + #else + return x_check.i == y_check.i; + #endif +} +#else +static inline mp_float_t fp_diff(mp_float_t x, mp_float_t y) { + #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C + mp_float_union_t x_check = { x }; + mp_float_union_t y_check = { y }; + x_check.i &= ~3; + y_check.i &= ~3; + return x_check.f - y_check.f; + #else + return x - y; + #endif +} +#endif -#endif // MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT/DOUBLE +#endif -static inline int fp_expval(FPTYPE x) { - mp_float_union_t fb = {x}; - return (int)((fb.i >> MP_FLOAT_FRAC_BITS) & (~(0xFFFFFFFF << MP_FLOAT_EXP_BITS))) - MP_FLOAT_EXP_OFFSET; +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT +#define FPMIN_BUF_SIZE 6 // +9e+99 +#define MAX_MANTISSA_DIGITS (9) +#define SAFE_MANTISSA_DIGITS (6) +#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +#define FPMIN_BUF_SIZE 7 // +9e+199 +#define MAX_MANTISSA_DIGITS (19) +#define SAFE_MANTISSA_DIGITS (16) +#endif + +// Internal formatting flags +#define FMT_MODE_E 0x01 // render using scientific notation (%e) +#define FMT_MODE_G 0x02 // render using general format (%g) +#define FMT_MODE_F 0x04 // render using using expanded fixed-point format (%f) +#define FMT_E_CASE 0x20 // don't change this value (used for case conversion!) + +static char *mp_prepend_zeros(char *s, int cnt) { + *s++ = '0'; + *s++ = '.'; + while (cnt > 0) { + *s++ = '0'; + cnt--; + } + return s; } -int mp_format_float(FPTYPE f, char *buf, size_t buf_size, char fmt, int prec, char sign) { +// Helper to convert a decimal mantissa (provided as an mp_large_float_uint_t) to string +static int mp_format_mantissa(mp_large_float_uint_t mantissa, mp_large_float_uint_t mantissa_cap, char *buf, char *s, + int num_digits, int max_exp_zeros, int trailing_zeros, int dec, int e, int fmt_flags) { - char *s = buf; + DEBUG_PRINTF("mantissa=" MP_FFUINT_FMT " exp=%d (cap=" MP_FFUINT_FMT "):\n", mantissa, e, mantissa_cap); - if (buf_size <= FPMIN_BUF_SIZE) { - // FPMIN_BUF_SIZE is the minimum size needed to store any FP number. - // If the buffer does not have enough room for this (plus null terminator) - // then don't try to format the float. + if (mantissa) { + // If rounding/searching created an extra digit or removed too many, fix mantissa first + if (mantissa >= mantissa_cap) { + if (fmt_flags & FMT_MODE_F) { + assert(e >= 0); + num_digits++; + dec++; + } else { + mantissa /= 10; + e++; + } + } + } - if (buf_size >= 2) { - *s++ = '?'; + // When 'g' format is used, replace small exponents by explicit zeros + if ((fmt_flags & FMT_MODE_G) && e != 0) { + if (e >= 0) { + // If 0 < e < max_exp_zeros, expand positive exponent into trailing zeros + if (e < max_exp_zeros) { + dec += e; + if (dec >= num_digits) { + trailing_zeros = dec - (num_digits - 1); + } + e = 0; + } + } else { + // If -4 <= e < 0, expand negative exponent without losing significant digits + if (e >= -4) { + int cnt = 0; + while (e < 0 && !(mantissa % 10)) { + mantissa /= 10; + cnt++; + e++; + } + num_digits -= cnt; + s = mp_prepend_zeros(s, cnt - e - 1); + dec = 255; + e = 0; + } } - if (buf_size >= 1) { - *s = '\0'; + } + + // Convert the integer mantissa to string + for (int digit = num_digits - 1; digit >= 0; digit--) { + int digit_ofs = (digit > dec ? digit + 1 : digit); + s[digit_ofs] = '0' + (int)(mantissa % 10); + mantissa /= 10; + } + int dot = (dec >= 255); + if (dec + 1 < num_digits) { + dot = 1; + s++; + s[dec] = '.'; + } + s += num_digits; + #if DEBUG_FLOAT_FORMATTING + *s = 0; + DEBUG_PRINTF(" = %s exp=%d num_digits=%d zeros=%d dec=%d\n", buf, e, num_digits, trailing_zeros, dec); + #endif + + // Append or remove trailing zeros, as required by format + if (trailing_zeros) { + dec -= num_digits - 1; + while (trailing_zeros--) { + if (!dec--) { + *s++ = '.'; + dot = 1; + } + *s++ = '0'; } - return buf_size >= 2; } - if (fp_signbit(f) && !fp_isnan(f)) { - *s++ = '-'; - f = -f; - } else { - if (sign) { - *s++ = sign; + if (fmt_flags & FMT_MODE_G) { + // 'g' format requires to remove trailing zeros after decimal point + if (dot) { + while (s[-1] == '0') { + s--; + } + if (s[-1] == '.') { + s--; + } + } + } + + // Append the exponent if needed + if (((e != 0) || (fmt_flags & FMT_MODE_E)) && !(fmt_flags & FMT_MODE_F)) { + *s++ = 'E' | (fmt_flags & FMT_E_CASE); + if (e >= 0) { + *s++ = '+'; + } else { + *s++ = '-'; + e = -e; } + if (e >= 100) { + *s++ = '0' + (e / 100); + } + *s++ = '0' + ((e / 10) % 10); + *s++ = '0' + (e % 10); } + *s = '\0'; + DEBUG_PRINTF(" ===> %s\n", buf); - // buf_remaining contains bytes available for digits and exponent. - // It is buf_size minus room for the sign and null byte. - int buf_remaining = buf_size - 1 - (s - buf); + return s - buf; +} +// minimal value expected for buf_size, to avoid checking everywhere for overflow +#define MIN_BUF_SIZE (MAX_MANTISSA_DIGITS + 10) + +int mp_format_float(mp_float_t f_entry, char *buf_entry, size_t buf_size, char fmt, int prec, char sign) { + assert(buf_size >= MIN_BUF_SIZE); + + // Handle sign + mp_float_t f = f_entry; + char *buf = buf_entry; + if (signbit(f_entry) && !isnan(f_entry)) { + f = -f; + sign = '-'; + } + if (sign) { + *buf++ = sign; + buf_size--; + } + + // Handle inf/nan + char uc = fmt & 0x20; { - char uc = fmt & 0x20; - if (fp_isinf(f)) { + char *s = buf; + if (isinf(f)) { *s++ = 'I' ^ uc; *s++ = 'N' ^ uc; *s++ = 'F' ^ uc; goto ret; - } else if (fp_isnan(f)) { + } else if (isnan(f)) { *s++ = 'N' ^ uc; *s++ = 'A' ^ uc; *s++ = 'N' ^ uc; ret: *s = '\0'; - return s - buf; + return s - buf_entry; } } + // Decode format character + int fmt_flags = (unsigned char)uc; // setup FMT_E_CASE, clear all other bits + char lofmt = (char)(fmt | 0x20); // fmt in lowercase + if (lofmt == 'f') { + fmt_flags |= FMT_MODE_F; + } else if (lofmt == 'g') { + fmt_flags |= FMT_MODE_G; + } else { + fmt_flags |= FMT_MODE_E; + } + + // When precision is unspecified, default to 6 if (prec < 0) { prec = 6; } - char e_char = 'E' | (fmt & 0x20); // e_char will match case of fmt - fmt |= 0x20; // Force fmt to be lowercase - char org_fmt = fmt; - if (fmt == 'g' && prec == 0) { - prec = 1; + // Use high precision for `repr`, but switch to exponent mode + // after 16 digits in any case to match CPython behaviour + int max_exp_zeros = (prec < (int)buf_size - 3 ? prec : (int)buf_size - 3); + if (prec == MP_FLOAT_REPR_PREC) { + prec = MAX_MANTISSA_DIGITS; + max_exp_zeros = 16; } - int e; - int dec = 0; - char e_sign = '\0'; - int num_digits = 0; - int signed_e = 0; - // Approximate power of 10 exponent from binary exponent. - // abs(e_guess) is lower bound on abs(power of 10 exponent). - int e_guess = (int)(fp_expval(f) * FPCONST(0.3010299956639812)); // 1/log2(10). - if (fp_iszero(f)) { - e = 0; - if (fmt == 'f') { - // Truncate precision to prevent buffer overflow - if (prec + 2 > buf_remaining) { - prec = buf_remaining - 2; - } - num_digits = prec + 1; - } else { - // Truncate precision to prevent buffer overflow - if (prec + 6 > buf_remaining) { - prec = buf_remaining - 6; - } - if (fmt == 'e') { - e_sign = '+'; - } + // Precompute the exact decimal exponent of f, such that + // abs(e) is lower bound on abs(power of 10 exponent). + int e = 0; + if (!fp_iszero(f)) { + // Approximate power of 10 exponent from binary exponent. + e = (int)(fp_expval(f) * MICROPY_FLOAT_CONST(0.3010299956639812)); // 1/log2(10). + int positive_exp = !fp_isless1(f); + mp_float_t u_base = (mp_float_t)mp_decimal_exp((mp_large_float_t)1.0, e + positive_exp); + while ((f >= u_base) == positive_exp) { + e += (positive_exp ? 1 : -1); + u_base = (mp_float_t)mp_decimal_exp((mp_large_float_t)1.0, e + positive_exp); } - } else if (fp_isless1(f)) { - FPTYPE f_entry = f; // Save f in case we go to 'f' format. - // Build negative exponent - e = -e_guess; - FPTYPE u_base = MICROPY_FLOAT_C_FUN(pow)(10, -e); - while (u_base > f) { - ++e; - u_base = MICROPY_FLOAT_C_FUN(pow)(10, -e); - } - // Normalize out the inferred unit. Use divide because - // pow(10, e) * pow(10, -e) is slightly < 1 for some e in float32 - // (e.g. print("%.12f" % ((1e13) * (1e-13)))) - f /= u_base; - - // If the user specified 'g' format, and e is <= 4, then we'll switch - // to the fixed format ('f') - - if (fmt == 'f' || (fmt == 'g' && e <= 4)) { - fmt = 'f'; - dec = 0; + } - if (org_fmt == 'g') { - prec += (e - 1); - } + // For 'e' format, prec is # digits after the decimal + // For 'f' format, prec is # digits after the decimal + // For 'g' format, prec is the max number of significant digits + // + // For 'e' & 'g' format, there will be a single digit before the decimal + // For 'f' format, zeros must be expanded instead of using an exponent. + // Make sure there is enough room in the buffer for them, or switch to format 'g'. + if ((fmt_flags & FMT_MODE_F) && e > 0) { + int req_size = e + prec + 2; + if (req_size > (int)buf_size) { + fmt_flags ^= FMT_MODE_F; + fmt_flags |= FMT_MODE_G; + prec++; + } + } - // truncate precision to prevent buffer overflow - if (prec + 2 > buf_remaining) { - prec = buf_remaining - 2; + // To work independently of the format, we precompute: + // - the max number of significant digits to produce + // - the number of leading zeros to prepend (mode f only) + // - the number of trailing zeros to append + int max_digits = prec; + int lead_zeros = 0; + int trail_zeros = 0; + if (fmt_flags & FMT_MODE_F) { + if (max_digits > (int)buf_size - 3) { + // cannot satisfy requested number of decimals given buf_size, sorry + max_digits = (int)buf_size - 3; + } + if (e < 0) { + if (max_digits > 2 && e < -2) { + // Insert explicit leading zeros + lead_zeros = (-e < max_digits ? -e : max_digits) - 2; + max_digits -= lead_zeros; + } else { + max_digits++; } - - num_digits = prec; - signed_e = 0; - f = f_entry; - ++num_digits; } else { - // For e & g formats, we'll be printing the exponent, so set the - // sign. - e_sign = '-'; - dec = 0; - - if (prec > (buf_remaining - FPMIN_BUF_SIZE)) { - prec = buf_remaining - FPMIN_BUF_SIZE; - if (fmt == 'g') { - prec++; - } - } - signed_e = -e; + max_digits += e + 1; } } else { - // Build positive exponent. - // We don't modify f at this point to avoid inaccuracies from - // scaling it. Instead, we find the product of powers of 10 - // that is not greater than it, and use that to start the - // mantissa. - e = e_guess; - FPTYPE next_u = MICROPY_FLOAT_C_FUN(pow)(10, e + 1); - while (f >= next_u) { - ++e; - next_u = MICROPY_FLOAT_C_FUN(pow)(10, e + 1); + if (!(fmt_flags & FMT_MODE_G) || max_digits == 0) { + max_digits++; } + } + if (max_digits > MAX_MANTISSA_DIGITS) { + // use trailing zeros to avoid overflowing the mantissa + trail_zeros = max_digits - MAX_MANTISSA_DIGITS; + max_digits = MAX_MANTISSA_DIGITS; + } + int overhead = (fmt_flags & FMT_MODE_F ? 3 : FPMIN_BUF_SIZE + 1); + if (trail_zeros > (int)buf_size - max_digits - overhead) { + // cannot satisfy requested number of decimals given buf_size, sorry + trail_zeros = (int)buf_size - max_digits - overhead; + } - // If the user specified fixed format (fmt == 'f') and e makes the - // number too big to fit into the available buffer, then we'll - // switch to the 'e' format. - - if (fmt == 'f') { - if (e >= buf_remaining) { - fmt = 'e'; - } else if ((e + prec + 2) > buf_remaining) { - prec = buf_remaining - e - 2; - if (prec < 0) { - // This means no decimal point, so we can add one back - // for the decimal. - prec++; - } - } - } - if (fmt == 'e' && prec > (buf_remaining - FPMIN_BUF_SIZE)) { - prec = buf_remaining - FPMIN_BUF_SIZE; - } - if (fmt == 'g') { - // Truncate precision to prevent buffer overflow - if (prec + (FPMIN_BUF_SIZE - 1) > buf_remaining) { - prec = buf_remaining - (FPMIN_BUF_SIZE - 1); - } - } - // If the user specified 'g' format, and e is < prec, then we'll switch - // to the fixed format. + // When the caller asks for more precision than available for sure, + // Look for a shorter (rounded) representation first, and only dig + // into more digits if there is no short representation. + int num_digits = (SAFE_MANTISSA_DIGITS < max_digits ? SAFE_MANTISSA_DIGITS : max_digits); +try_again: + ; - if (fmt == 'g' && e < prec) { - fmt = 'f'; - prec -= (e + 1); - } - if (fmt == 'f') { - dec = e; - num_digits = prec + e + 1; + char *s = buf; + int extra_zeros = trail_zeros + (max_digits - num_digits); + int decexp; + int dec = 0; + + if (fp_iszero(f)) { + // no need for scaling 0.0 + decexp = 0; + } else if (fmt_flags & FMT_MODE_F) { + decexp = num_digits - 1; + if (e < 0) { + // Negative exponent: we keep a single leading zero in the mantissa, + // as using more would waste precious digits needed for accuracy. + if (lead_zeros > 0) { + // We are using leading zeros + s = mp_prepend_zeros(s, lead_zeros); + decexp += lead_zeros + 1; + dec = 255; // no decimal dot + } else { + // Small negative exponent, work directly on the mantissa + dec = 0; + } } else { - e_sign = '+'; + // Positive exponent: we will add trailing zeros separately + decexp -= e; + dec = e; } - signed_e = e; + } else { + decexp = num_digits - e - 1; } - if (prec < 0) { - // This can happen when the prec is trimmed to prevent buffer overflow - prec = 0; + DEBUG_PRINTF("input=%.19g e=%d fmt=%c max_d=%d num_d=%d decexp=%d dec=%d l0=%d r0=%d\n", + (double)f, e, lofmt, max_digits, num_digits, decexp, dec, lead_zeros, extra_zeros); + + // At this point, + // - buf points to beginning of output buffer for the unsigned representation + // - num_digits == the number of mantissa digits to add + // - (dec + 1) == the number of digits to print before adding a decimal point + // - decexp == the power of 10 exponent to apply to f to get the decimal mantissa + // - e == the power of 10 exponent to append ('e' or 'g' format) + mp_large_float_uint_t mantissa_cap = 10; + for (int n = 1; n < num_digits; n++) { + mantissa_cap *= 10; } - // At this point e contains the absolute value of the power of 10 exponent. - // (dec + 1) == the number of dgits before the decimal. - - // For e, prec is # digits after the decimal - // For f, prec is # digits after the decimal - // For g, prec is the max number of significant digits - // - // For e & g there will be a single digit before the decimal - // for f there will be e digits before the decimal - - if (fmt == 'e') { - num_digits = prec + 1; - } else if (fmt == 'g') { - if (prec == 0) { - prec = 1; + // Build the decimal mantissa into a large uint + mp_large_float_uint_t mantissa = 1; + if (sizeof(mp_large_float_t) == sizeof(mp_float_t) && num_digits > SAFE_MANTISSA_DIGITS && decexp > 1) { + // if we don't have large floats, use integer multiply to produce the last digits + if (num_digits > SAFE_MANTISSA_DIGITS + 1 && decexp > 2) { + mantissa = 100; + decexp -= 2; + } else { + mantissa = 10; + decexp -= 1; } - num_digits = prec; } - - int d = 0; - for (int digit_index = signed_e; num_digits >= 0; --digit_index) { - FPTYPE u_base = FPCONST(1.0); - if (digit_index > 0) { - // Generate 10^digit_index for positive digit_index. - u_base = MICROPY_FLOAT_C_FUN(pow)(10, digit_index); - } - for (d = 0; d < 9; ++d) { - if (f < u_base) { - break; - } - f -= u_base; - } - // We calculate one more digit than we display, to use in rounding - // below. So only emit the digit if it's one that we display. - if (num_digits > 0) { - // Emit this number (the leading digit). - *s++ = '0' + d; - if (dec == 0 && prec > 0) { - *s++ = '.'; - } - } - --dec; - --num_digits; - if (digit_index <= 0) { - // Once we get below 1.0, we scale up f instead of calculating - // negative powers of 10 in u_base. This provides better - // renditions of exact decimals like 1/16 etc. - f *= FPCONST(10.0); + mp_large_float_t mantissa_f = mp_decimal_exp((mp_large_float_t)f, decexp); + mantissa *= (mp_large_float_uint_t)(mantissa_f + (mp_large_float_t)0.5); + DEBUG_PRINTF("input=%.19g fmt=%c num_digits=%d dec=%d mantissa=" MP_FFUINT_FMT " r0=%d\n", (double)f, lofmt, num_digits, dec, mantissa, extra_zeros); + + // Finally convert the decimal mantissa to a floating-point string, according to formatting rules + int reprlen = mp_format_mantissa(mantissa, mantissa_cap, buf, s, num_digits, max_exp_zeros, extra_zeros, dec, e, fmt_flags); + assert(reprlen + 1 <= (int)buf_size); + + #if MICROPY_FLOAT_FORMAT_IMPL != MICROPY_FLOAT_FORMAT_IMPL_APPROX + + if (num_digits < max_digits) { + // The initial precision might not be sufficient for an exact representation + // for all numbers. If the result is not exact, restart using next precision. + // parse the resulting number and compare against the original + mp_float_t check; + DEBUG_PRINTF("input=%.19g, compare to float('%s')\n", (double)f, buf); + mp_parse_float_internal(buf, reprlen, &check); + if (!fp_equal(check, f)) { + num_digits++; + DEBUG_PRINTF("Not perfect, retry using more digits (%d)\n", num_digits); + goto try_again; } } - // Rounding. If the next digit to print is >= 5, round up. - if (d >= 5) { - char *rs = s; - rs--; - while (1) { - if (*rs == '.') { - rs--; - continue; - } - if (*rs < '0' || *rs > '9') { - // + or - - rs++; // So we sit on the digit to the right of the sign - break; + + #else + + // The initial decimal mantissa might not have been be completely accurate due + // to the previous loating point operations. The best way to verify this is to + // parse the resulting number and compare against the original + mp_float_t check; + DEBUG_PRINTF("input=%.19g, compare to float('%s')\n", (double)f, buf); + mp_parse_float_internal(buf, reprlen, &check); + mp_float_t diff = fp_diff(check, f); + mp_float_t best_diff = diff; + mp_large_float_uint_t best_mantissa = mantissa; + + if (fp_iszero(diff)) { + // we have a perfect match + DEBUG_PRINTF(MP_FFUINT_FMT ": perfect match (direct)\n", mantissa); + } else { + // In order to get the best possible representation, we will perform a + // dichotomic search for a reversible representation. + // This will also provide optimal rounding on the fly. + unsigned err_range = 1; + if (num_digits > SAFE_MANTISSA_DIGITS) { + err_range <<= 3 * (num_digits - SAFE_MANTISSA_DIGITS); + } + int maxruns = 3 + 3 * (MAX_MANTISSA_DIGITS - SAFE_MANTISSA_DIGITS); + while (maxruns-- > 0) { + // update mantissa according to dichotomic search + if (signbit(diff)) { + mantissa += err_range; + } else { + // mantissa is expected to always have more significant digits than err_range + assert(mantissa >= err_range); + mantissa -= err_range; } - if (*rs < '9') { - (*rs)++; + // retry conversion + reprlen = mp_format_mantissa(mantissa, mantissa_cap, buf, s, num_digits, max_exp_zeros, extra_zeros, dec, e, fmt_flags); + assert(reprlen + 1 <= (int)buf_size); + DEBUG_PRINTF("input=%.19g, compare to float('%s')\n", (double)f, buf); + mp_parse_float_internal(buf, reprlen, &check); + DEBUG_PRINTF("check=%.19g num_digits=%d e=%d mantissa=" MP_FFUINT_FMT "\n", (double)check, num_digits, e, mantissa); + diff = fp_diff(check, f); + if (fp_iszero(diff)) { + // we have a perfect match + DEBUG_PRINTF(MP_FFUINT_FMT ": perfect match\n", mantissa); break; } - *rs = '0'; - if (rs == buf) { - break; + // keep track of our best estimate + mp_float_t delta = MICROPY_FLOAT_C_FUN(fabs)(diff) - MICROPY_FLOAT_C_FUN(fabs)(best_diff); + if (signbit(delta) || (fp_iszero(delta) && !(mantissa % 10u))) { + best_diff = diff; + best_mantissa = mantissa; } - rs--; - } - if (*rs == '0') { - // We need to insert a 1 - if (rs[1] == '.' && fmt != 'f') { - // We're going to round 9.99 to 10.00 - // Move the decimal point - rs[0] = '.'; - rs[1] = '0'; - if (e_sign == '-') { - e--; - if (e == 0) { - e_sign = '+'; - } - } else { - e++; - } + // string repr is not perfect: continue a dichotomic improvement + DEBUG_PRINTF(MP_FFUINT_FMT ": %.19g, err_range=%d\n", mantissa, (double)check, err_range); + if (err_range > 1) { + err_range >>= 1; } else { - // Need at extra digit at the end to make room for the leading '1' - // but if we're at the buffer size limit, just drop the final digit. - if ((size_t)(s + 1 - buf) < buf_size) { - s++; + // We have tried all possible mantissa, without finding a reversible repr. + // Check if we have an alternate precision to try. + if (num_digits < max_digits) { + num_digits++; + DEBUG_PRINTF("Failed to find a perfect match, try with more digits (%d)\n", num_digits); + goto try_again; } + // Otherwise, keep the closest one, which is either the first one or the last one. + if (mantissa == best_mantissa) { + // Last guess is the best one + DEBUG_PRINTF(MP_FFUINT_FMT ": last guess was the best one\n", mantissa); + } else { + // We had a better guess earlier + DEBUG_PRINTF(MP_FFUINT_FMT ": use best guess\n", mantissa); + reprlen = mp_format_mantissa(best_mantissa, mantissa_cap, buf, s, num_digits, max_exp_zeros, extra_zeros, dec, e, fmt_flags); + } + break; } - char *ss = s; - while (ss > rs) { - *ss = ss[-1]; - ss--; - } - *rs = '1'; } } + #endif - // verify that we did not overrun the input buffer so far - assert((size_t)(s + 1 - buf) <= buf_size); - - if (org_fmt == 'g' && prec > 0) { - // Remove trailing zeros and a trailing decimal point - while (s[-1] == '0') { - s--; - } - if (s[-1] == '.') { - s--; - } - } - // Append the exponent - if (e_sign) { - *s++ = e_char; - *s++ = e_sign; - if (FPMIN_BUF_SIZE == 7 && e >= 100) { - *s++ = '0' + (e / 100); - } - *s++ = '0' + ((e / 10) % 10); - *s++ = '0' + (e % 10); - } - *s = '\0'; - - // verify that we did not overrun the input buffer - assert((size_t)(s + 1 - buf) <= buf_size); - - return s - buf; + return buf + reprlen - buf_entry; } #endif // MICROPY_FLOAT_IMPL != MICROPY_FLOAT_IMPL_NONE diff --git a/py/formatfloat.h b/py/formatfloat.h index 9a1643b4ddf..7b1414672b7 100644 --- a/py/formatfloat.h +++ b/py/formatfloat.h @@ -29,6 +29,7 @@ #include "py/mpconfig.h" #if MICROPY_PY_BUILTINS_FLOAT +#define MP_FLOAT_REPR_PREC (99) // magic `prec` value for optimal `repr` behaviour int mp_format_float(mp_float_t f, char *buf, size_t bufSize, char fmt, int prec, char sign); #endif diff --git a/py/gc.c b/py/gc.c index 5375218f3e9..757c27e3de6 100644 --- a/py/gc.c +++ b/py/gc.c @@ -32,6 +32,12 @@ #include "py/gc.h" #include "py/runtime.h" +#if defined(__ZEPHYR__) +#include +#include +#include +#endif + #if MICROPY_DEBUG_VALGRIND #include #endif @@ -39,10 +45,18 @@ // CIRCUITPY-CHANGE #include "supervisor/shared/safe_mode.h" +#include "supervisor/shared/serial.h" + #if CIRCUITPY_MEMORYMONITOR #include "shared-module/memorymonitor/__init__.h" #endif +#if defined(__ZEPHYR__) && defined(CONFIG_TRACING_PERFETTO) && defined(CONFIG_BOARD_NATIVE_SIM) +#include "perfetto_encoder.h" +#define CIRCUITPY_PERFETTO_VM_HEAP_USED_UUID 0x3001ULL +#define CIRCUITPY_PERFETTO_VM_HEAP_MAX_FREE_UUID 0x3002ULL +#endif + #if MICROPY_ENABLE_GC #if MICROPY_DEBUG_VERBOSE // print debugging info @@ -123,10 +137,23 @@ #define FTB_CLEAR(area, block) do { area->gc_finaliser_table_start[(block) / BLOCKS_PER_FTB] &= (~(1 << ((block) & 7))); } while (0) #endif +// CIRCUITPY-CHANGE: Add selective collect table to skip scanning large buffers without pointers +// CTB = collect table byte +// if set, then the corresponding block should be collected during GC + +#define BLOCKS_PER_CTB (8) + +#define CTB_GET(area, block) ((area->gc_collect_table_start[(block) / BLOCKS_PER_CTB] >> ((block) & 7)) & 1) +#define CTB_SET(area, block) do { area->gc_collect_table_start[(block) / BLOCKS_PER_CTB] |= (1 << ((block) & 7)); } while (0) +#define CTB_CLEAR(area, block) do { area->gc_collect_table_start[(block) / BLOCKS_PER_CTB] &= (~(1 << ((block) & 7))); } while (0) + #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL -#define GC_ENTER() mp_thread_mutex_lock(&MP_STATE_MEM(gc_mutex), 1) -#define GC_EXIT() mp_thread_mutex_unlock(&MP_STATE_MEM(gc_mutex)) +#define GC_MUTEX_INIT() mp_thread_recursive_mutex_init(&MP_STATE_MEM(gc_mutex)) +#define GC_ENTER() mp_thread_recursive_mutex_lock(&MP_STATE_MEM(gc_mutex), 1) +#define GC_EXIT() mp_thread_recursive_mutex_unlock(&MP_STATE_MEM(gc_mutex)) #else +// Either no threading, or assume callers to gc_collect() hold the GIL +#define GC_MUTEX_INIT() #define GC_ENTER() #define GC_EXIT() #endif @@ -143,48 +170,103 @@ void __attribute__ ((noinline)) gc_log_change(uint32_t start_block, uint32_t len #pragma GCC pop_options #endif +#if defined(__ZEPHYR__) && defined(CONFIG_TRACING_PERFETTO) && defined(CONFIG_BOARD_NATIVE_SIM) +static void gc_perfetto_emit_heap_stats(void) { + if (!perfetto_start()) { + return; + } + gc_info_t info; + gc_info(&info); + perfetto_emit_counter(CIRCUITPY_PERFETTO_VM_HEAP_USED_UUID, (int64_t)info.used); + Z_SPIN_DELAY(1); +} + +static void gc_perfetto_emit_heap_stopped(void) { + if (!perfetto_start()) { + return; + } + perfetto_emit_counter(CIRCUITPY_PERFETTO_VM_HEAP_USED_UUID, 0); + Z_SPIN_DELAY(1); +} +#else +static inline void gc_perfetto_emit_heap_stats(void) { +} + +static inline void gc_perfetto_emit_heap_stopped(void) { +} +#endif + +// Static functions for individual steps of the GC mark/sweep sequence +static void gc_collect_start_common(void); +static void *gc_get_ptr(void **ptrs, int i); +#if MICROPY_GC_SPLIT_HEAP +static void gc_mark_subtree(mp_state_mem_area_t *area, size_t block); +#else +static void gc_mark_subtree(size_t block); +#endif +static void gc_deal_with_stack_overflow(void); +static void gc_sweep_run_finalisers(void); +static void gc_sweep_free_blocks(void); + // TODO waste less memory; currently requires that all entries in alloc_table have a corresponding block in pool static void gc_setup_area(mp_state_mem_area_t *area, void *start, void *end) { - // calculate parameters for GC (T=total, A=alloc table, F=finaliser table, P=pool; all in bytes): - // T = A + F + P + // CIRCUITPY-CHANGE: Updated calculation to include selective collect table + // calculate parameters for GC (T=total, A=alloc table, F=finaliser table, C=collect table, P=pool; all in bytes): + // T = A + F + C + P // F = A * BLOCKS_PER_ATB / BLOCKS_PER_FTB + // C = A * BLOCKS_PER_ATB / BLOCKS_PER_CTB // P = A * BLOCKS_PER_ATB * BYTES_PER_BLOCK - // => T = A * (1 + BLOCKS_PER_ATB / BLOCKS_PER_FTB + BLOCKS_PER_ATB * BYTES_PER_BLOCK) + size_t total_byte_len = (byte *)end - (byte *)start; + + // Calculate the denominator for the alloc table size calculation + size_t bits_per_block = MP_BITS_PER_BYTE / BLOCKS_PER_ATB; // Start with bits for ATB + #if MICROPY_ENABLE_FINALISER - area->gc_alloc_table_byte_len = (total_byte_len - ALLOC_TABLE_GAP_BYTE) - * MP_BITS_PER_BYTE - / ( - MP_BITS_PER_BYTE - + MP_BITS_PER_BYTE * BLOCKS_PER_ATB / BLOCKS_PER_FTB - + MP_BITS_PER_BYTE * BLOCKS_PER_ATB * BYTES_PER_BLOCK - ); - #else - area->gc_alloc_table_byte_len = (total_byte_len - ALLOC_TABLE_GAP_BYTE) / (1 + MP_BITS_PER_BYTE / 2 * BYTES_PER_BLOCK); + bits_per_block += MP_BITS_PER_BYTE / BLOCKS_PER_FTB; // Add bits for FTB + #endif + + #if MICROPY_ENABLE_SELECTIVE_COLLECT + bits_per_block += MP_BITS_PER_BYTE / BLOCKS_PER_CTB; // Add bits for CTB #endif + bits_per_block += MP_BITS_PER_BYTE * BYTES_PER_BLOCK; // Add bits for the block itself + + // Calculate the allocation table size + size_t available_bits = (total_byte_len - ALLOC_TABLE_GAP_BYTE) * MP_BITS_PER_BYTE; + size_t blocks = available_bits / bits_per_block; + area->gc_alloc_table_byte_len = blocks / BLOCKS_PER_ATB; + + // Set up all the table pointers area->gc_alloc_table_start = (byte *)start; + byte *next_table = area->gc_alloc_table_start + area->gc_alloc_table_byte_len + ALLOC_TABLE_GAP_BYTE; + // Total number of blocks in the pool + size_t gc_pool_block_len = area->gc_alloc_table_byte_len * BLOCKS_PER_ATB; + + // Calculate table sizes and set start pointers #if MICROPY_ENABLE_FINALISER - size_t gc_finaliser_table_byte_len = (area->gc_alloc_table_byte_len * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB; - area->gc_finaliser_table_start = area->gc_alloc_table_start + area->gc_alloc_table_byte_len + ALLOC_TABLE_GAP_BYTE; + size_t gc_finaliser_table_byte_len = (gc_pool_block_len + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB; + area->gc_finaliser_table_start = next_table; + next_table += gc_finaliser_table_byte_len; #endif - size_t gc_pool_block_len = area->gc_alloc_table_byte_len * BLOCKS_PER_ATB; + #if MICROPY_ENABLE_SELECTIVE_COLLECT + size_t gc_collect_table_byte_len = (gc_pool_block_len + BLOCKS_PER_CTB - 1) / BLOCKS_PER_CTB; + area->gc_collect_table_start = next_table; + next_table += gc_collect_table_byte_len; + #endif + + // Set pool pointers area->gc_pool_start = (byte *)end - gc_pool_block_len * BYTES_PER_BLOCK; area->gc_pool_end = end; - #if MICROPY_ENABLE_FINALISER - assert(area->gc_pool_start >= area->gc_finaliser_table_start + gc_finaliser_table_byte_len); - #endif + // Verify enough space between last table and start of pool + assert(area->gc_pool_start >= next_table); - #if MICROPY_ENABLE_FINALISER - // clear ATB's and FTB's - memset(area->gc_alloc_table_start, 0, gc_finaliser_table_byte_len + area->gc_alloc_table_byte_len + ALLOC_TABLE_GAP_BYTE); - #else - // clear ATB's - memset(area->gc_alloc_table_start, 0, area->gc_alloc_table_byte_len + ALLOC_TABLE_GAP_BYTE); - #endif + // Clear all tables + size_t tables_size = next_table - area->gc_alloc_table_start; + memset(area->gc_alloc_table_start, 0, tables_size); area->gc_last_free_atb_index = 0; area->gc_last_used_block = 0; @@ -204,6 +286,12 @@ static void gc_setup_area(mp_state_mem_area_t *area, void *start, void *end) { gc_finaliser_table_byte_len, gc_finaliser_table_byte_len * BLOCKS_PER_FTB); #endif + #if MICROPY_ENABLE_SELECTIVE_COLLECT + DEBUG_printf(" collect table at %p, length " UINT_FMT " bytes, " + UINT_FMT " blocks\n", area->gc_collect_table_start, + gc_collect_table_byte_len, + gc_collect_table_byte_len * BLOCKS_PER_CTB); + #endif DEBUG_printf(" pool at %p, length " UINT_FMT " bytes, " UINT_FMT " blocks\n", area->gc_pool_start, gc_pool_block_len * BYTES_PER_BLOCK, gc_pool_block_len); @@ -233,9 +321,8 @@ void gc_init(void *start, void *end) { MP_STATE_MEM(gc_alloc_amount) = 0; #endif - #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL - mp_thread_mutex_init(&MP_STATE_MEM(gc_mutex)); - #endif + GC_MUTEX_INIT(); + gc_perfetto_emit_heap_stats(); } #if MICROPY_GC_SPLIT_HEAP @@ -261,16 +348,46 @@ void gc_add(void *start, void *end) { } #if MICROPY_GC_SPLIT_HEAP_AUTO +// CIRCUITPY-CHANGE: Added function to compute heap size with selective collect table +static size_t compute_heap_size(size_t total_blocks) { + // Round up to the nearest multiple of BLOCKS_PER_ATB. Partial ATB blocks aren't supported and + // will result in a heap that is too small. + total_blocks = ((total_blocks + BLOCKS_PER_ATB - 1) / BLOCKS_PER_ATB) * BLOCKS_PER_ATB; + size_t atb_bytes = (total_blocks + BLOCKS_PER_ATB - 1) / BLOCKS_PER_ATB; + size_t ftb_bytes = 0; + size_t ctb_bytes = 0; + #if MICROPY_ENABLE_FINALISER + ftb_bytes = (total_blocks + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB; + #endif + #if MICROPY_ENABLE_SELECTIVE_COLLECT + ctb_bytes = (total_blocks + BLOCKS_PER_CTB - 1) / BLOCKS_PER_CTB; + #endif + size_t pool_bytes = total_blocks * BYTES_PER_BLOCK; + + // Compute bytes needed to build a heap with total_blocks blocks. + size_t total_heap = + sizeof(mp_state_mem_area_t) + + atb_bytes + + ALLOC_TABLE_GAP_BYTE + + ftb_bytes + + ctb_bytes + + pool_bytes + + BYTES_PER_BLOCK; // Extra block of bytes to account for end pointer alignment + + // Round up size to the nearest multiple of BYTES_PER_BLOCK. + total_heap = (total_heap + BYTES_PER_BLOCK - 1) / BYTES_PER_BLOCK; + total_heap *= BYTES_PER_BLOCK; + return total_heap; +} + // Try to automatically add a heap area large enough to fulfill 'failed_alloc'. static bool gc_try_add_heap(size_t failed_alloc) { // 'needed' is the size of a heap large enough to hold failed_alloc, with // the additional metadata overheads as calculated in gc_setup_area(). - // - // Rather than reproduce all of that logic here, we approximate that adding - // (13/512) is enough overhead for sufficiently large heap areas (the - // overhead converges to 3/128, but there's some fixed overhead and some - // rounding up of partial block sizes). - size_t needed = failed_alloc + MAX(2048, failed_alloc * 13 / 512); + // CIRCUITPY-CHANGE: calculation of how much to grow the heap + size_t total_new_blocks = (failed_alloc + BYTES_PER_BLOCK - 1) / BYTES_PER_BLOCK; + // CIRCUITPY-CHANGE + size_t needed = compute_heap_size(total_new_blocks); size_t avail = gc_get_max_new_split(); @@ -314,18 +431,8 @@ static bool gc_try_add_heap(size_t failed_alloc) { total_blocks += area->gc_alloc_table_byte_len * BLOCKS_PER_ATB; } - // Compute bytes needed to build a heap with total_blocks blocks. - size_t total_heap = - total_blocks / BLOCKS_PER_ATB - #if MICROPY_ENABLE_FINALISER - + total_blocks / BLOCKS_PER_FTB - #endif - + total_blocks * BYTES_PER_BLOCK - + ALLOC_TABLE_GAP_BYTE - + sizeof(mp_state_mem_area_t); - - // Round up size to the nearest multiple of BYTES_PER_BLOCK. - total_heap = (total_heap + BYTES_PER_BLOCK - 1) & (~(BYTES_PER_BLOCK - 1)); + // CIRCUITPY-CHANGE + size_t total_heap = compute_heap_size(total_blocks); DEBUG_printf("total_heap " UINT_FMT " bytes\n", total_heap); @@ -352,11 +459,12 @@ static bool gc_try_add_heap(size_t failed_alloc) { #endif -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: additional function void gc_deinit(void) { // Run any finalisers before we stop using the heap. This will also free // any additional heap areas (but not the first.) gc_sweep_all(); + gc_perfetto_emit_heap_stopped(); memset(&MP_STATE_MEM(area), 0, sizeof(MP_STATE_MEM(area))); } @@ -365,20 +473,20 @@ void gc_lock(void) { // - each thread has its own gc_lock_depth so there are no races between threads; // - a hard interrupt will only change gc_lock_depth during its execution, and // upon return will restore the value of gc_lock_depth. - MP_STATE_THREAD(gc_lock_depth)++; + MP_STATE_THREAD(gc_lock_depth) += (1 << GC_LOCK_DEPTH_SHIFT); } void gc_unlock(void) { // This does not need to be atomic, See comment above in gc_lock. - MP_STATE_THREAD(gc_lock_depth)--; + MP_STATE_THREAD(gc_lock_depth) -= (1 << GC_LOCK_DEPTH_SHIFT); } bool gc_is_locked(void) { return MP_STATE_THREAD(gc_lock_depth) != 0; } -// CIRCUITPY-CHANGE -bool gc_ptr_on_heap(void *ptr) { +// CIRCUITPY-CHANGE: additional function +bool gc_ptr_on_heap(const void *ptr) { for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) { if (ptr >= (void *)area->gc_pool_start // must be above start of pool && ptr < (void *)area->gc_pool_end) { // must be below end of pool @@ -420,11 +528,70 @@ static inline mp_state_mem_area_t *gc_get_ptr_area(const void *ptr) { #endif #endif +void gc_collect_start(void) { + gc_collect_start_common(); + #if MICROPY_GC_ALLOC_THRESHOLD + MP_STATE_MEM(gc_alloc_amount) = 0; + #endif + + // Trace root pointers. This relies on the root pointers being organised + // correctly in the mp_state_ctx structure. We scan nlr_top, dict_locals, + // dict_globals, then the root pointer section of mp_state_vm. + void **ptrs = (void **)(void *)&mp_state_ctx; + size_t root_start = offsetof(mp_state_ctx_t, thread.dict_locals); + size_t root_end = offsetof(mp_state_ctx_t, vm.qstr_last_chunk); + gc_collect_root(ptrs + root_start / sizeof(void *), (root_end - root_start) / sizeof(void *)); + + #if MICROPY_ENABLE_PYSTACK + // Trace root pointers from the Python stack. + ptrs = (void **)(void *)MP_STATE_THREAD(pystack_start); + gc_collect_root(ptrs, (MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start)) / sizeof(void *)); + #endif +} + +static void gc_collect_start_common(void) { + GC_ENTER(); + assert((MP_STATE_THREAD(gc_lock_depth) & GC_COLLECT_FLAG) == 0); + MP_STATE_THREAD(gc_lock_depth) |= GC_COLLECT_FLAG; + MP_STATE_MEM(gc_stack_overflow) = 0; +} + +void gc_collect_root(void **ptrs, size_t len) { + #if !MICROPY_GC_SPLIT_HEAP + mp_state_mem_area_t *area = &MP_STATE_MEM(area); + #endif + for (size_t i = 0; i < len; i++) { + MICROPY_GC_HOOK_LOOP(i); + void *ptr = gc_get_ptr(ptrs, i); + #if MICROPY_GC_SPLIT_HEAP + mp_state_mem_area_t *area = gc_get_ptr_area(ptr); + if (!area) { + continue; + } + #else + if (!VERIFY_PTR(ptr)) { + continue; + } + #endif + size_t block = BLOCK_FROM_PTR(area, ptr); + if (ATB_GET_KIND(area, block) == AT_HEAD) { + // An unmarked head: mark it, and mark all its children + ATB_HEAD_TO_MARK(area, block); + #if MICROPY_GC_SPLIT_HEAP + gc_mark_subtree(area, block); + #else + gc_mark_subtree(block); + #endif + } + } +} + // Take the given block as the topmost block on the stack. Check all it's // children: mark the unmarked child blocks and put those newly marked // blocks on the stack. When all children have been checked, pop off the // topmost block on the stack and repeat with that one. // CIRCUITPY-CHANGE: We don't instrument these functions because they occur a lot during GC and +// fill up the output buffer quickly. #if MICROPY_GC_SPLIT_HEAP static void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark_subtree)(mp_state_mem_area_t * area, size_t block) #else @@ -447,41 +614,52 @@ static void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark_subtree)(size_t block) // check that the consecutive blocks didn't overflow past the end of the area assert(area->gc_pool_start + (block + n_blocks) * BYTES_PER_BLOCK <= area->gc_pool_end); - // check this block's children - void **ptrs = (void **)PTR_FROM_BLOCK(area, block); - for (size_t i = n_blocks * BYTES_PER_BLOCK / sizeof(void *); i > 0; i--, ptrs++) { - MICROPY_GC_HOOK_LOOP(i); - void *ptr = *ptrs; - // If this is a heap pointer that hasn't been marked, mark it and push - // it's children to the stack. - #if MICROPY_GC_SPLIT_HEAP - mp_state_mem_area_t *ptr_area = gc_get_ptr_area(ptr); - if (!ptr_area) { - // Not a heap-allocated pointer (might even be random data). - continue; - } - #else - if (!VERIFY_PTR(ptr)) { - continue; - } - mp_state_mem_area_t *ptr_area = area; - #endif - size_t ptr_block = BLOCK_FROM_PTR(ptr_area, ptr); - if (ATB_GET_KIND(ptr_area, ptr_block) != AT_HEAD) { - // This block is already marked. - continue; - } - // An unmarked head. Mark it, and push it on gc stack. - TRACE_MARK(ptr_block, ptr); - ATB_HEAD_TO_MARK(ptr_area, ptr_block); - if (sp < MICROPY_ALLOC_GC_STACK_SIZE) { - MP_STATE_MEM(gc_block_stack)[sp] = ptr_block; + // CIRCUITPY-CHANGE + // check if this block should be collected + #if MICROPY_ENABLE_SELECTIVE_COLLECT + bool should_scan = CTB_GET(area, block); + #else + bool should_scan = true; + #endif + + // Only scan the block's children if it's not a leaf + if (should_scan) { + // check this block's children + void **ptrs = (void **)PTR_FROM_BLOCK(area, block); + for (size_t i = n_blocks * BYTES_PER_BLOCK / sizeof(void *); i > 0; i--, ptrs++) { + MICROPY_GC_HOOK_LOOP(i); + void *ptr = *ptrs; + // If this is a heap pointer that hasn't been marked, mark it and push + // it's children to the stack. #if MICROPY_GC_SPLIT_HEAP - MP_STATE_MEM(gc_area_stack)[sp] = ptr_area; + mp_state_mem_area_t *ptr_area = gc_get_ptr_area(ptr); + if (!ptr_area) { + // Not a heap-allocated pointer (might even be random data). + continue; + } + #else + if (!VERIFY_PTR(ptr)) { + continue; + } + mp_state_mem_area_t *ptr_area = area; #endif - sp += 1; - } else { - MP_STATE_MEM(gc_stack_overflow) = 1; + size_t ptr_block = BLOCK_FROM_PTR(ptr_area, ptr); + if (ATB_GET_KIND(ptr_area, ptr_block) != AT_HEAD) { + // This block is already marked. + continue; + } + // An unmarked head. Mark it, and push it on gc stack. + TRACE_MARK(ptr_block, ptr); + ATB_HEAD_TO_MARK(ptr_area, ptr_block); + if (sp < MICROPY_ALLOC_GC_STACK_SIZE) { + MP_STATE_MEM(gc_block_stack)[sp] = ptr_block; + #if MICROPY_GC_SPLIT_HEAP + MP_STATE_MEM(gc_area_stack)[sp] = ptr_area; + #endif + sp += 1; + } else { + MP_STATE_MEM(gc_stack_overflow) = 1; + } } } @@ -499,6 +677,26 @@ static void MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_mark_subtree)(size_t block) } } +void gc_sweep_all(void) { + gc_collect_start_common(); + gc_collect_end(); +} + +void gc_collect_end(void) { + gc_deal_with_stack_overflow(); + gc_sweep_run_finalisers(); + gc_sweep_free_blocks(); + #if MICROPY_GC_SPLIT_HEAP + MP_STATE_MEM(gc_last_free_area) = &MP_STATE_MEM(area); + #endif + for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) { + area->gc_last_free_atb_index = 0; + } + MP_STATE_THREAD(gc_lock_depth) &= ~GC_COLLECT_FLAG; + GC_EXIT(); + gc_perfetto_emit_heap_stats(); +} + static void gc_deal_with_stack_overflow(void) { while (MP_STATE_MEM(gc_stack_overflow)) { MP_STATE_MEM(gc_stack_overflow) = 0; @@ -520,29 +718,20 @@ static void gc_deal_with_stack_overflow(void) { } } -static void gc_sweep(void) { - #if MICROPY_PY_GC_COLLECT_RETVAL - MP_STATE_MEM(gc_collected) = 0; - #endif - // free unmarked heads and their tails - int free_tail = 0; - #if MICROPY_GC_SPLIT_HEAP_AUTO - mp_state_mem_area_t *prev_area = NULL; - #endif - for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) { - size_t end_block = area->gc_alloc_table_byte_len * BLOCKS_PER_ATB; - if (area->gc_last_used_block < end_block) { - end_block = area->gc_last_used_block + 1; - } - - size_t last_used_block = 0; - - for (size_t block = 0; block < end_block; block++) { - MICROPY_GC_HOOK_LOOP(block); - switch (ATB_GET_KIND(area, block)) { - case AT_HEAD: - #if MICROPY_ENABLE_FINALISER - if (FTB_GET(area, block)) { +// Run finalisers for all to-be-freed blocks +static void gc_sweep_run_finalisers(void) { + #if MICROPY_ENABLE_FINALISER + for (const mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) { + assert(area->gc_last_used_block <= area->gc_alloc_table_byte_len * BLOCKS_PER_ATB); + // Small speed optimisation: skip over empty FTB blocks + size_t ftb_end = area->gc_last_used_block / BLOCKS_PER_FTB; // index is inclusive + for (size_t ftb_idx = 0; ftb_idx <= ftb_end; ftb_idx++) { + byte ftb = area->gc_finaliser_table_start[ftb_idx]; + size_t block = ftb_idx * BLOCKS_PER_FTB; + while (ftb) { + MICROPY_GC_HOOK_LOOP(block); + if (ftb & 1) { // FTB_GET(area, block) shortcut + if (ATB_GET_KIND(area, block) == AT_HEAD) { mp_obj_base_t *obj = (mp_obj_base_t *)PTR_FROM_BLOCK(area, block); if (obj->type != NULL) { // if the object has a type then see if it has a __del__ method @@ -562,9 +751,35 @@ static void gc_sweep(void) { // clear finaliser flag FTB_CLEAR(area, block); } - #endif + } + ftb >>= 1; + block++; + } + } + } + #endif // MICROPY_ENABLE_FINALISER +} + +// Free unmarked heads and their tails +static void gc_sweep_free_blocks(void) { + #if MICROPY_PY_GC_COLLECT_RETVAL + MP_STATE_MEM(gc_collected) = 0; + #endif + int free_tail = 0; + #if MICROPY_GC_SPLIT_HEAP_AUTO + mp_state_mem_area_t *prev_area = NULL; + #endif + + for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) { + size_t last_used_block = 0; + assert(area->gc_last_used_block <= area->gc_alloc_table_byte_len * BLOCKS_PER_ATB); + + for (size_t block = 0; block <= area->gc_last_used_block; block++) { + MICROPY_GC_HOOK_LOOP(block); + switch (ATB_GET_KIND(area, block)) { + case AT_HEAD: free_tail = 1; - DEBUG_printf("gc_sweep(%p)\n", (void *)PTR_FROM_BLOCK(area, block)); + DEBUG_printf("gc_sweep_free_blocks(%p)\n", (void *)PTR_FROM_BLOCK(area, block)); #if MICROPY_PY_GC_COLLECT_RETVAL MP_STATE_MEM(gc_collected)++; #endif @@ -595,7 +810,7 @@ static void gc_sweep(void) { #if MICROPY_GC_SPLIT_HEAP_AUTO // Free any empty area, aside from the first one if (last_used_block == 0 && prev_area != NULL) { - DEBUG_printf("gc_sweep free empty area %p\n", area); + DEBUG_printf("gc_sweep_free_blocks free empty area %p\n", area); NEXT_AREA(prev_area) = NEXT_AREA(area); MP_PLAT_FREE_HEAP(area); area = prev_area; @@ -605,30 +820,7 @@ static void gc_sweep(void) { } } -void gc_collect_start(void) { - GC_ENTER(); - MP_STATE_THREAD(gc_lock_depth)++; - #if MICROPY_GC_ALLOC_THRESHOLD - MP_STATE_MEM(gc_alloc_amount) = 0; - #endif - MP_STATE_MEM(gc_stack_overflow) = 0; - - // Trace root pointers. This relies on the root pointers being organised - // correctly in the mp_state_ctx structure. We scan nlr_top, dict_locals, - // dict_globals, then the root pointer section of mp_state_vm. - void **ptrs = (void **)(void *)&mp_state_ctx; - size_t root_start = offsetof(mp_state_ctx_t, thread.dict_locals); - size_t root_end = offsetof(mp_state_ctx_t, vm.qstr_last_chunk); - gc_collect_root(ptrs + root_start / sizeof(void *), (root_end - root_start) / sizeof(void *)); - - #if MICROPY_ENABLE_PYSTACK - // Trace root pointers from the Python stack. - ptrs = (void **)(void *)MP_STATE_THREAD(pystack_start); - gc_collect_root(ptrs, (MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start)) / sizeof(void *)); - #endif -} - -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: add function void gc_collect_ptr(void *ptr) { void *ptrs[1] = { ptr }; gc_collect_root(ptrs, 1); @@ -650,56 +842,6 @@ static void *MP_NO_INSTRUMENT PLACE_IN_ITCM(gc_get_ptr)(void **ptrs, int i) { return ptrs[i]; } -void gc_collect_root(void **ptrs, size_t len) { - #if !MICROPY_GC_SPLIT_HEAP - mp_state_mem_area_t *area = &MP_STATE_MEM(area); - #endif - for (size_t i = 0; i < len; i++) { - MICROPY_GC_HOOK_LOOP(i); - void *ptr = gc_get_ptr(ptrs, i); - #if MICROPY_GC_SPLIT_HEAP - mp_state_mem_area_t *area = gc_get_ptr_area(ptr); - if (!area) { - continue; - } - #else - if (!VERIFY_PTR(ptr)) { - continue; - } - #endif - size_t block = BLOCK_FROM_PTR(area, ptr); - if (ATB_GET_KIND(area, block) == AT_HEAD) { - // An unmarked head: mark it, and mark all its children - ATB_HEAD_TO_MARK(area, block); - #if MICROPY_GC_SPLIT_HEAP - gc_mark_subtree(area, block); - #else - gc_mark_subtree(block); - #endif - } - } -} - -void gc_collect_end(void) { - gc_deal_with_stack_overflow(); - gc_sweep(); - #if MICROPY_GC_SPLIT_HEAP - MP_STATE_MEM(gc_last_free_area) = &MP_STATE_MEM(area); - #endif - for (mp_state_mem_area_t *area = &MP_STATE_MEM(area); area != NULL; area = NEXT_AREA(area)) { - area->gc_last_free_atb_index = 0; - } - MP_STATE_THREAD(gc_lock_depth)--; - GC_EXIT(); -} - -void gc_sweep_all(void) { - GC_ENTER(); - MP_STATE_THREAD(gc_lock_depth)++; - MP_STATE_MEM(gc_stack_overflow) = 0; - gc_collect_end(); -} - void gc_info(gc_info_t *info) { GC_ENTER(); info->total = 0; @@ -773,7 +915,8 @@ void gc_info(gc_info_t *info) { GC_EXIT(); } -// CIRCUITPY-CHANGE: C code may be used when the VM heap isn't active. This +// CIRCUITPY-CHANGE: New function. +// C code may be used when the VM heap isn't active. This function // allows that code to test if it is. It can use the outer pool if needed. bool gc_alloc_possible(void) { return MP_STATE_MEM(area).gc_pool_start != 0; @@ -944,6 +1087,20 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) { (void)has_finaliser; #endif + // CIRCUITPY-CHANGE + #if MICROPY_ENABLE_SELECTIVE_COLLECT + bool do_not_collect = (alloc_flags & GC_ALLOC_FLAG_DO_NOT_COLLECT) != 0; + GC_ENTER(); + if (do_not_collect) { + // Mark as not to be collected + CTB_CLEAR(area, start_block); + } else { + // By default, all blocks should be collected + CTB_SET(area, start_block); + } + GC_EXIT(); + #endif + #if EXTENSIVE_HEAP_PROFILING gc_dump_alloc_table(&mp_plat_print); #endif @@ -953,26 +1110,21 @@ void *gc_alloc(size_t n_bytes, unsigned int alloc_flags) { memorymonitor_track_allocation(end_block - start_block + 1); #endif - return ret_ptr; -} - -/* -void *gc_alloc(mp_uint_t n_bytes) { - return _gc_alloc(n_bytes, false); -} + gc_perfetto_emit_heap_stats(); -void *gc_alloc_with_finaliser(mp_uint_t n_bytes) { - return _gc_alloc(n_bytes, true); + return ret_ptr; } -*/ // force the freeing of a piece of memory // TODO: freeing here does not call finaliser void gc_free(void *ptr) { - if (MP_STATE_THREAD(gc_lock_depth) > 0) { - // Cannot free while the GC is locked. However free is an optimisation - // to reclaim the memory immediately, this means it will now be left - // until the next collection. + // Cannot free while the GC is locked, unless we're only doing a gc sweep. + // However free is an optimisation to reclaim the memory immediately, this + // means it will now be left until the next collection. + // + // (We have the optimisation to free immediately from inside a gc sweep so + // that finalisers can free more memory when trying to avoid MemoryError.) + if (MP_STATE_THREAD(gc_lock_depth) & ~GC_COLLECT_FLAG) { return; } @@ -1002,7 +1154,8 @@ void gc_free(void *ptr) { #endif size_t block = BLOCK_FROM_PTR(area, ptr); - assert(ATB_GET_KIND(area, block) == AT_HEAD); + assert(ATB_GET_KIND(area, block) == AT_HEAD + || (ATB_GET_KIND(area, block) == AT_MARK && (MP_STATE_THREAD(gc_lock_depth) & GC_COLLECT_FLAG))); #if MICROPY_ENABLE_FINALISER FTB_CLEAR(area, block); @@ -1040,6 +1193,7 @@ void gc_free(void *ptr) { } while (ATB_GET_KIND(area, block) == AT_TAIL); GC_EXIT(); + gc_perfetto_emit_heap_stats(); #if EXTENSIVE_HEAP_PROFILING gc_dump_alloc_table(&mp_plat_print); @@ -1078,39 +1232,11 @@ size_t gc_nbytes(const void *ptr) { return 0; } -#if 0 -// old, simple realloc that didn't expand memory in place -void *gc_realloc(void *ptr, mp_uint_t n_bytes) { - mp_uint_t n_existing = gc_nbytes(ptr); - if (n_bytes <= n_existing) { - return ptr; - } else { - bool has_finaliser; - if (ptr == NULL) { - has_finaliser = false; - } else { - #if MICROPY_ENABLE_FINALISER - has_finaliser = FTB_GET(BLOCK_FROM_PTR((mp_uint_t)ptr)); - #else - has_finaliser = false; - #endif - } - void *ptr2 = gc_alloc(n_bytes, has_finaliser); - if (ptr2 == NULL) { - return ptr2; - } - memcpy(ptr2, ptr, n_existing); - gc_free(ptr); - return ptr2; - } -} - -#else // Alternative gc_realloc impl - void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { // check for pure allocation if (ptr_in == NULL) { - return gc_alloc(n_bytes, false); + // CIRCUITPY-CHANGE + return gc_alloc(n_bytes, 0); } // check for pure free @@ -1208,6 +1334,8 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { memorymonitor_track_allocation(new_blocks); #endif + gc_perfetto_emit_heap_stats(); + return ptr_in; } @@ -1245,13 +1373,24 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { memorymonitor_track_allocation(new_blocks); #endif + gc_perfetto_emit_heap_stats(); + return ptr_in; } + uint8_t alloc_flags = 0; #if MICROPY_ENABLE_FINALISER - bool ftb_state = FTB_GET(area, block); - #else - bool ftb_state = false; + // CIRCUITPY-CHANGE for selective collect + if (FTB_GET(area, block)) { + alloc_flags |= GC_ALLOC_FLAG_HAS_FINALISER; + } + #endif + + // CIRCUITPY-CHANGE for selective collect + #if MICROPY_ENABLE_SELECTIVE_COLLECT + if (!CTB_GET(area, block)) { + alloc_flags |= GC_ALLOC_FLAG_DO_NOT_COLLECT; + } #endif GC_EXIT(); @@ -1262,7 +1401,8 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { } // can't resize inplace; try to find a new contiguous chain - void *ptr_out = gc_alloc(n_bytes, ftb_state); + // CIRCUITPY-CHANGE + void *ptr_out = gc_alloc(n_bytes, alloc_flags); // check that the alloc succeeded if (ptr_out == NULL) { @@ -1274,7 +1414,6 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { gc_free(ptr_in); return ptr_out; } -#endif // Alternative gc_realloc impl void gc_dump_info(const mp_print_t *print) { gc_info_t info; @@ -1308,7 +1447,7 @@ void gc_dump_alloc_table(const mp_print_t *print) { } if (bl2 - bl >= 2 * DUMP_BYTES_PER_LINE) { // there are at least 2 lines containing only free blocks, so abbreviate their printing - mp_printf(print, "\n (%u lines all free)", (uint)(bl2 - bl) / DUMP_BYTES_PER_LINE); + mp_printf(print, "\n (%u lines all free)", (uint)((bl2 - bl) / DUMP_BYTES_PER_LINE)); bl = bl2 & (~(DUMP_BYTES_PER_LINE - 1)); if (bl >= area->gc_alloc_table_byte_len * BLOCKS_PER_ATB) { // got to end of heap @@ -1351,7 +1490,7 @@ void gc_dump_alloc_table(const mp_print_t *print) { break; } */ - /* this prints the uPy object type of the head block */ + /* this prints the MicroPython object type of the head block */ case AT_HEAD: { // CIRCUITPY-CHANGE: compiler warning avoidance #pragma GCC diagnostic push @@ -1422,41 +1561,4 @@ void gc_dump_alloc_table(const mp_print_t *print) { GC_EXIT(); } -#if 0 -// For testing the GC functions -void gc_test(void) { - mp_uint_t len = 500; - mp_uint_t *heap = malloc(len); - gc_init(heap, heap + len / sizeof(mp_uint_t)); - void *ptrs[100]; - { - mp_uint_t **p = gc_alloc(16, false); - p[0] = gc_alloc(64, false); - p[1] = gc_alloc(1, false); - p[2] = gc_alloc(1, false); - p[3] = gc_alloc(1, false); - mp_uint_t ***p2 = gc_alloc(16, false); - p2[0] = p; - p2[1] = p; - ptrs[0] = p2; - } - for (int i = 0; i < 25; i += 2) { - mp_uint_t *p = gc_alloc(i, false); - printf("p=%p\n", p); - if (i & 3) { - // ptrs[i] = p; - } - } - - printf("Before GC:\n"); - gc_dump_alloc_table(&mp_plat_print); - printf("Starting GC...\n"); - gc_collect_start(); - gc_collect_root(ptrs, sizeof(ptrs) / sizeof(void *)); - gc_collect_end(); - printf("After GC:\n"); - gc_dump_alloc_table(&mp_plat_print); -} -#endif - #endif // MICROPY_ENABLE_GC diff --git a/py/gc.h b/py/gc.h index 5f4b18f7e64..f9028d637c5 100644 --- a/py/gc.h +++ b/py/gc.h @@ -71,8 +71,17 @@ bool gc_alloc_possible(void); // Use this function to sweep the whole heap and run all finalisers void gc_sweep_all(void); +// These functions are used to manage weakrefs. +void gc_weakref_mark(void *ptr); +void gc_weakref_about_to_be_freed(void *ptr); +void gc_weakref_sweep(void); + enum { GC_ALLOC_FLAG_HAS_FINALISER = 1, + // CIRCUITPY-CHANGE + #if MICROPY_ENABLE_SELECTIVE_COLLECT + GC_ALLOC_FLAG_DO_NOT_COLLECT = 2, + #endif }; void *gc_alloc(size_t n_bytes, unsigned int alloc_flags); @@ -83,7 +92,7 @@ void *gc_realloc(void *ptr, size_t n_bytes, bool allow_move); // CIRCUITPY-CHANGE // True if the pointer is on the MP heap. Doesn't require that it is the start // of a block. -bool gc_ptr_on_heap(void *ptr); +bool gc_ptr_on_heap(const void *ptr); typedef struct _gc_info_t { size_t total; diff --git a/py/lexer.c b/py/lexer.c index bff8e637656..98a10c87b2e 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -228,7 +228,6 @@ static const char *const tok_enc = "=e=" // = == "!."; // start of special cases: != . ... -// TODO static assert that number of tokens is less than 256 so we can safely make this table with byte sized entries static const uint8_t tok_enc_kind[] = { MP_TOKEN_DEL_PAREN_OPEN, MP_TOKEN_DEL_PAREN_CLOSE, MP_TOKEN_DEL_BRACKET_OPEN, MP_TOKEN_DEL_BRACKET_CLOSE, @@ -336,8 +335,12 @@ static void parse_string_literal(mp_lexer_t *lex, bool is_raw, bool is_fstring) // assume there's going to be interpolation, so prep the injection data // fstring_args_idx==0 && len(fstring_args)>0 means we're extracting the args. // only when fstring_args_idx>0 will we consume the arg data - // note: lex->fstring_args will be empty already (it's reset when finished) - vstr_add_str(&lex->fstring_args, ".format("); + // lex->fstring_args is reset when finished, so at this point there are two cases: + // - lex->fstring_args is empty: start of a new f-string + // - lex->fstring_args is non-empty: concatenation of adjacent f-strings + if (vstr_len(&lex->fstring_args) == 0) { + vstr_add_str(&lex->fstring_args, ".format("); + } } #endif @@ -657,21 +660,19 @@ void mp_lexer_to_next(mp_lexer_t *lex) { } #if MICROPY_PY_FSTRINGS if (is_char_following(lex, 'f')) { - // raw-f-strings unsupported, immediately return (invalid) token. - lex->tok_kind = MP_TOKEN_FSTRING_RAW; - break; + is_fstring = true; + n_char = 2; } #endif } #if MICROPY_PY_FSTRINGS else if (is_char(lex, 'f')) { + is_fstring = true; + n_char = 1; if (is_char_following(lex, 'r')) { - // raw-f-strings unsupported, immediately return (invalid) token. - lex->tok_kind = MP_TOKEN_FSTRING_RAW; - break; + is_raw = true; + n_char = 2; } - n_char = 1; - is_fstring = true; } #endif @@ -772,6 +773,9 @@ void mp_lexer_to_next(mp_lexer_t *lex) { } else { // search for encoded delimiter or operator + // assert that the token enum value fits in a byte, so they all fit in tok_enc_kind + MP_STATIC_ASSERT(MP_TOKEN_NUMBER_OF <= 256); + const char *t = tok_enc; size_t tok_enc_index = 0; for (; *t != 0 && !is_char(lex, *t); t += 1) { diff --git a/py/lexer.h b/py/lexer.h index 2d9d0447b8b..6e6c3e8f23e 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -46,7 +46,6 @@ typedef enum _mp_token_kind_t { MP_TOKEN_LONELY_STRING_OPEN, #if MICROPY_PY_FSTRINGS MP_TOKEN_MALFORMED_FSTRING, - MP_TOKEN_FSTRING_RAW, #endif MP_TOKEN_NEWLINE, @@ -153,6 +152,8 @@ typedef enum _mp_token_kind_t { MP_TOKEN_DEL_SEMICOLON, MP_TOKEN_DEL_EQUAL, MP_TOKEN_DEL_MINUS_MORE, + + MP_TOKEN_NUMBER_OF, } mp_token_kind_t; // this data structure is exposed for efficiency diff --git a/py/make_root_pointers.py b/py/make_root_pointers.py index efe398b8227..5da343c1270 100644 --- a/py/make_root_pointers.py +++ b/py/make_root_pointers.py @@ -6,8 +6,6 @@ "struct _mp_state_vm_t" in py/mpstate.h """ -from __future__ import print_function - import argparse import io import re diff --git a/py/makecompresseddata.py b/py/makecompresseddata.py index 1bce3e8e837..a6fa7db00b2 100644 --- a/py/makecompresseddata.py +++ b/py/makecompresseddata.py @@ -1,5 +1,3 @@ -from __future__ import print_function - import collections import re import sys diff --git a/py/makemoduledefs.py b/py/makemoduledefs.py index 29162ab387c..c8fdc21f6fb 100644 --- a/py/makemoduledefs.py +++ b/py/makemoduledefs.py @@ -14,8 +14,6 @@ the built-in version. """ -from __future__ import print_function - import sys import re import io @@ -87,19 +85,25 @@ def generate_module_table_header(modules): ) ) + # There should always be at least one module (__main__ in runtime.c) + assert mod_defs + print("\n#define MICROPY_REGISTERED_MODULES \\") for mod_def in sorted(mod_defs): print(" {mod_def} \\".format(mod_def=mod_def)) - print("// MICROPY_REGISTERED_MODULES") - print("\n#define MICROPY_REGISTERED_EXTENSIBLE_MODULES \\") + # There are not necessarily any extensible modules (e.g., bare-arm or minimal x86) + print("\n#define MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES ", len(extensible_mod_defs)) - for mod_def in sorted(extensible_mod_defs): - print(" {mod_def} \\".format(mod_def=mod_def)) + if extensible_mod_defs: + print("\n#define MICROPY_REGISTERED_EXTENSIBLE_MODULES \\") + + for mod_def in sorted(extensible_mod_defs): + print(" {mod_def} \\".format(mod_def=mod_def)) - print("// MICROPY_REGISTERED_EXTENSIBLE_MODULES") + print("// MICROPY_REGISTERED_EXTENSIBLE_MODULES") def generate_module_delegations(delegations): diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py index d778aa48444..3fdb2d5476b 100644 --- a/py/makeqstrdata.py +++ b/py/makeqstrdata.py @@ -1,36 +1,54 @@ """ Process raw qstr file and output qstr data with length, hash and data bytes. -This script works with Python 2.7, 3.3 and 3.4. - -CIRCUITPY-CHANGE: -For documentation about the format of compressed translated strings, see -supervisor/shared/translate/translate.h +This script works with Python 3.3+. """ -from __future__ import print_function - - import re import sys -# CIRCUITPY-CHANGE -if hasattr(sys.stdout, "reconfigure"): - sys.stdout.reconfigure(encoding="utf-8") - sys.stderr.reconfigure(errors="backslashreplace") - -# Python 2/3 compatibility: -# - iterating through bytes is different -# - codepoint2name lives in a different module -import platform - -if platform.python_version_tuple()[0] == "2": - bytes_cons = lambda val, enc=None: bytearray(val) - from htmlentitydefs import codepoint2name -elif platform.python_version_tuple()[0] == "3": - bytes_cons = bytes - from html.entities import codepoint2name -# end compatibility code +bytes_cons = bytes + +# fmt: off +codepoint2name = { + 198: "AElig", 193: "Aacute", 194: "Acirc", 192: "Agrave", 913: "Alpha", 197: "Aring", 195: "Atilde", + 196: "Auml", 914: "Beta", 199: "Ccedil", 935: "Chi", 8225: "Dagger", 916: "Delta", 208: "ETH", + 201: "Eacute", 202: "Ecirc", 200: "Egrave", 917: "Epsilon", 919: "Eta", 203: "Euml", 915: "Gamma", + 205: "Iacute", 206: "Icirc", 204: "Igrave", 921: "Iota", 207: "Iuml", 922: "Kappa", 923: "Lambda", + 924: "Mu", 209: "Ntilde", 925: "Nu", 338: "OElig", 211: "Oacute", 212: "Ocirc", 210: "Ograve", + 937: "Omega", 927: "Omicron", 216: "Oslash", 213: "Otilde", 214: "Ouml", 934: "Phi", 928: "Pi", + 8243: "Prime", 936: "Psi", 929: "Rho", 352: "Scaron", 931: "Sigma", 222: "THORN", 932: "Tau", + 920: "Theta", 218: "Uacute", 219: "Ucirc", 217: "Ugrave", 933: "Upsilon", 220: "Uuml", 926: "Xi", + 221: "Yacute", 376: "Yuml", 918: "Zeta", 225: "aacute", 226: "acirc", 180: "acute", 230: "aelig", + 224: "agrave", 8501: "alefsym", 945: "alpha", 38: "amp", 8743: "and", 8736: "ang", 229: "aring", + 8776: "asymp", 227: "atilde", 228: "auml", 8222: "bdquo", 946: "beta", 166: "brvbar", 8226: "bull", + 8745: "cap", 231: "ccedil", 184: "cedil", 162: "cent", 967: "chi", 710: "circ", 9827: "clubs", + 8773: "cong", 169: "copy", 8629: "crarr", 8746: "cup", 164: "curren", 8659: "dArr", 8224: "dagger", + 8595: "darr", 176: "deg", 948: "delta", 9830: "diams", 247: "divide", 233: "eacute", 234: "ecirc", + 232: "egrave", 8709: "empty", 8195: "emsp", 8194: "ensp", 949: "epsilon", 8801: "equiv", 951: "eta", + 240: "eth", 235: "euml", 8364: "euro", 8707: "exist", 402: "fnof", 8704: "forall", 189: "frac12", + 188: "frac14", 190: "frac34", 8260: "frasl", 947: "gamma", 8805: "ge", 62: "gt", 8660: "hArr", + 8596: "harr", 9829: "hearts", 8230: "hellip", 237: "iacute", 238: "icirc", 161: "iexcl", 236: "igrave", + 8465: "image", 8734: "infin", 8747: "int", 953: "iota", 191: "iquest", 8712: "isin", 239: "iuml", + 954: "kappa", 8656: "lArr", 955: "lambda", 9001: "lang", 171: "laquo", 8592: "larr", 8968: "lceil", + 8220: "ldquo", 8804: "le", 8970: "lfloor", 8727: "lowast", 9674: "loz", 8206: "lrm", 8249: "lsaquo", + 8216: "lsquo", 60: "lt", 175: "macr", 8212: "mdash", 181: "micro", 183: "middot", 8722: "minus", + 956: "mu", 8711: "nabla", 160: "nbsp", 8211: "ndash", 8800: "ne", 8715: "ni", 172: "not", 8713: "notin", # codespell:ignore notin + 8836: "nsub", 241: "ntilde", 957: "nu", 243: "oacute", 244: "ocirc", 339: "oelig", 242: "ograve", + 8254: "oline", 969: "omega", 959: "omicron", 8853: "oplus", 8744: "or", 170: "ordf", 186: "ordm", + 248: "oslash", 245: "otilde", 8855: "otimes", 246: "ouml", 182: "para", 8706: "part", 8240: "permil", + 8869: "perp", 966: "phi", 960: "pi", 982: "piv", 177: "plusmn", 163: "pound", 8242: "prime", + 8719: "prod", 8733: "prop", 968: "psi", 34: "quot", 8658: "rArr", 8730: "radic", 9002: "rang", + 187: "raquo", 8594: "rarr", 8969: "rceil", 8221: "rdquo", 8476: "real", 174: "reg", 8971: "rfloor", + 961: "rho", 8207: "rlm", 8250: "rsaquo", 8217: "rsquo", 8218: "sbquo", 353: "scaron", 8901: "sdot", + 167: "sect", 173: "shy", 963: "sigma", 962: "sigmaf", 8764: "sim", 9824: "spades", 8834: "sub", + 8838: "sube", 8721: "sum", 8835: "sup", 185: "sup1", 178: "sup2", 179: "sup3", 8839: "supe", + 223: "szlig", 964: "tau", 8756: "there4", 952: "theta", 977: "thetasym", 8201: "thinsp", 254: "thorn", + 732: "tilde", 215: "times", 8482: "trade", 8657: "uArr", 250: "uacute", 8593: "uarr", 251: "ucirc", + 249: "ugrave", 168: "uml", 978: "upsih", 965: "upsilon", 252: "uuml", 8472: "weierp", 958: "xi", + 253: "yacute", 165: "yen", 255: "yuml", 950: "zeta", 8205: "zwj", 8204: "zwnj" +} +# fmt: on codepoint2name[ord("-")] = "hyphen" @@ -305,6 +323,9 @@ "", } +# Matches any string that needs no escaping (alphanum + _ only) +RE_NO_ESCAPE = re.compile(r"^[a-zA-Z0-9_]$") + # this must match the equivalent function in qstr.c def compute_hash(qstr, bytes_hash): @@ -317,15 +338,17 @@ def compute_hash(qstr, bytes_hash): def qstr_escape(qst): - def esc_char(m): - c = ord(m.group(0)) + def esc_char(c): + if RE_NO_ESCAPE.match(c): + return c + c = ord(c) try: name = codepoint2name[c] except KeyError: name = "0x%02x" % c return "_" + name + "_" - return re.sub(r"[^A-Za-z0-9_]", esc_char, qst) + return "".join(map(esc_char, qst)) static_qstr_list_ident = list(map(qstr_escape, static_qstr_list)) @@ -386,8 +409,11 @@ def parse_input_headers_with_translations(infiles): qstrs[ident] = (ident, qstr) if not qcfgs: - sys.stderr.write("ERROR: Empty preprocessor output - check for errors above\n") - sys.exit(1) + # CIRCUITPY-CHANGE: These values are hardcoded for CircuitPython so + # don't error if they are missing. + qcfgs = {} + qcfgs["BYTES_IN_LEN"] = 1 + qcfgs["BYTES_IN_HASH"] = 1 # CIRCUITPY-CHANGE return qcfgs, qstrs, translations diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py index 21300efb2c8..8c07899baf8 100644 --- a/py/makeqstrdefs.py +++ b/py/makeqstrdefs.py @@ -2,11 +2,9 @@ This script processes the output from the C preprocessor and extracts all qstr. Each qstr is transformed into a qstr definition of the form 'Q(...)'. -This script works with Python 3.x (CIRCUITPY-CHANGE: not 2.x) +This script works with Python 3.3+. """ -from __future__ import print_function - import io import os import re @@ -139,7 +137,8 @@ def qstr_unescape(qstr): return qstr -def process_file(f): +# CIRCUITPY-CHANGE: output_filename as an arg +def process_file(f, output_filename=None): # match gcc-like output (# n "file") and msvc-like output (#line n "file") re_line = re.compile(r"^#(?:line)?\s+\d+\s\"([^\"]+)\"") if args.mode == _MODE_QSTR: @@ -164,7 +163,7 @@ def process_file(f): fname = m.group(1) if not is_c_source(fname) and not is_cxx_source(fname): continue - if fname != last_fname: + if fname != last_fname and output_filename is None: write_out(last_fname, output) output = [] last_fname = fname @@ -181,7 +180,10 @@ def process_file(f): for match in re_translate.findall(line): output.append('TRANSLATE("' + match[0] + '")') - if last_fname: + if output_filename is not None: + with open(output_filename, "w") as f: + f.write("\n".join(output) + "\n") + elif last_fname: write_out(last_fname, output) return "" @@ -198,6 +200,11 @@ def cat_together(): with open(fname, "rb") as f: lines = f.readlines() all_lines += lines + # CIRCUITPY-CHANGE: Check for subdirectories as well. + for fname in glob.glob(args.output_dir + "/**/*." + args.mode): + with open(fname, "rb") as f: + lines = f.readlines() + all_lines += lines all_lines.sort() all_lines = b"\n".join(all_lines) # CIRCUITPY-CHANGE: added @@ -284,6 +291,9 @@ class Args: args.input_filename = sys.argv[3] # Unused for command=cat args.output_dir = sys.argv[4] args.output_file = None if len(sys.argv) == 5 else sys.argv[5] # Unused for command=split + # CIRCUITPY-CHANGE + if args.output_file == "_": + args.output_file = None if args.mode not in (_MODE_QSTR, _MODE_COMPRESS, _MODE_MODULE, _MODE_ROOT_POINTER): print("error: mode %s unrecognised" % sys.argv[2]) @@ -296,7 +306,8 @@ class Args: if args.command == "split": with io.open(args.input_filename, encoding="utf-8") as infile: - process_file(infile) + # CIRCUITPY-CHANGE: pass output_file + process_file(infile, args.output_file) if args.command == "cat": cat_together() diff --git a/py/maketranslationdata.py b/py/maketranslationdata.py index 0c264f31d68..c3c3442e311 100644 --- a/py/maketranslationdata.py +++ b/py/maketranslationdata.py @@ -90,8 +90,8 @@ def translate(translation_file, i18ns): translations = [] for original in i18ns: unescaped = original - for s in C_ESCAPES: - unescaped = unescaped.replace(C_ESCAPES[s], s) + for s, replacement in C_ESCAPES.items(): + unescaped = unescaped.replace(replacement, s) if original == "en_US": translation = table.info()["language"] else: @@ -527,11 +527,23 @@ def esc_char(m): def parse_qstrs(infile): r = {} - rx = re.compile(r'QDEF[01]\([A-Za-z0-9_]+,\s*\d+,\s*\d+,\s*(?P"(?:[^"\\\\]*|\\.)")\)') + rx = re.compile( + r'QDEF(?P[01])\([A-Za-z0-9_]+,\s*\d+,\s*\d+,\s*(?P"(?:[^"\\\\]|\\.)*")\)' + ) content = infile.read() - for i, mat in enumerate(rx.findall(content, re.M)): - mat = eval(mat) - r[mat] = i + matches = rx.finditer(content) + qdef0_qstrs = [] + qdef1_qstrs = [] + for match in matches: + qstr = eval(match.group("cstr")) + if match.group("pool") == "0": + qdef0_qstrs.append(qstr) + else: + qdef1_qstrs.append(qstr) + for i, qstr in enumerate(qdef0_qstrs): + r[qstr] = i + for i, qstr in enumerate(qdef1_qstrs, start=len(qdef0_qstrs)): + r[qstr] = i return r @@ -543,10 +555,9 @@ def parse_input_headers(infiles): with open(infile, "rt") as f: for line in f: line = line.strip() - - match = re.match(r'^TRANSLATE\("(.*)"\)$', line) + match = re.match(r'^TRANSLAT(E|ION)\("(.*)"(, \d+)?\)$', line) if match: - i18ns.add(match.group(1)) + i18ns.add(match.group(2)) continue return i18ns @@ -594,12 +605,15 @@ def output_translation_data(encoding_table, i18ns, out): total_text_compressed_size += len(compressed) decompressed = decompress(encoding_table, compressed, encoded_length_bits) assert decompressed == translation, (decompressed, translation) - for c in C_ESCAPES: - decompressed = decompressed.replace(c, C_ESCAPES[c]) + for c, replacement in C_ESCAPES.items(): + decompressed = decompressed.replace(c, replacement) formatted = ["{:d}".format(x) for x in compressed] out.write( "const struct compressed_string translation{} = {{ .data = {}, .tail = {{ {} }} }}; // {}\n".format( - i, formatted[0], ", ".join(formatted[1:]), original, decompressed + i, + formatted[0], + ", ".join(formatted[1:]), + original, ) ) total_text_size += len(translation.encode("utf-8")) diff --git a/py/makeversionhdr.py b/py/makeversionhdr.py index e780bc7dca1..94321ef0bad 100644 --- a/py/makeversionhdr.py +++ b/py/makeversionhdr.py @@ -5,8 +5,6 @@ This script works with Python 3.7 and newer """ -from __future__ import print_function - import argparse import sys import os @@ -14,76 +12,8 @@ import datetime import subprocess -# CIRCUITPY-CHANGE: use external script that can override git describe output with an -# environment variable. -tools_describe = str(pathlib.Path(__file__).resolve().parent.parent / "tools/describe") - - -def get_version_info_from_git(repo_path): - # Python 2.6 doesn't have check_output, so check for that - try: - subprocess.check_output - # CIRCUITPY-CHANGE: check for check_call - subprocess.check_call - except AttributeError: - return None - - # Note: git describe doesn't work if no tag is available - try: - git_tag = subprocess.check_output( - # CIRCUITPY-CHANGE - [tools_describe], - cwd=repo_path, - shell=True, - stderr=subprocess.STDOUT, - universal_newlines=True, - ).strip() - # CIRCUITPY-CHANGE - except subprocess.CalledProcessError as er: - if er.returncode == 128: - # git exit code of 128 means no repository found - return None - git_tag = "" - except OSError: - return None - try: - # CIRCUITPY-CHANGE - git_hash = subprocess.check_output( - ["git", "rev-parse", "--short", "HEAD"], - cwd=repo_path, - stderr=subprocess.STDOUT, - universal_newlines=True, - ).strip() - except subprocess.CalledProcessError: - # CIRCUITPY-CHANGE - git_hash = "unknown" - except OSError: - return None - - # CIRCUITPY-CHANGE - try: - # Check if there are any modified files. - subprocess.check_call( - ["git", "diff", "--no-ext-diff", "--quiet", "--exit-code"], - cwd=repo_path, - stderr=subprocess.STDOUT, - ) - # Check if there are any staged files. - subprocess.check_call( - ["git", "diff-index", "--cached", "--quiet", "HEAD", "--"], - cwd=repo_path, - stderr=subprocess.STDOUT, - ) - except subprocess.CalledProcessError: - git_hash += "-dirty" - except OSError: - return None - - # CIRCUITPY-CHANGE - # Try to extract MicroPython version from git tag - ver = git_tag.split("-")[0].split(".") - - return git_tag, git_hash, ver +# CIRCUITPY-CHANGE: Factor out version computation to py/version.py +import version # CIRCUITPY-CHANGE @@ -100,7 +30,7 @@ def cannot_determine_version(): def make_version_header(repo_path, filename): # Get version info using git (required) - info = get_version_info_from_git(repo_path) + info = version.get_version_info_from_git(repo_path) if info is None: cannot_determine_version() git_tag, git_hash, ver = info @@ -111,8 +41,8 @@ def make_version_header(repo_path, filename): build_date = datetime.date.today() if "SOURCE_DATE_EPOCH" in os.environ: - build_date = datetime.datetime.utcfromtimestamp( - int(os.environ["SOURCE_DATE_EPOCH"]) + build_date = datetime.datetime.fromtimestamp( + int(os.environ["SOURCE_DATE_EPOCH"]), datetime.timezone.utc ).date() # Generate the file with the git and version info @@ -133,7 +63,7 @@ def make_version_header(repo_path, filename): """ % ( git_tag, git_hash, - datetime.date.today().strftime("%Y-%m-%d"), + build_date.strftime("%Y-%m-%d"), ver[0].replace("v", ""), ver[1], ver[2], diff --git a/py/malloc.c b/py/malloc.c index 60f0df7455d..fc9795043a8 100644 --- a/py/malloc.c +++ b/py/malloc.c @@ -24,6 +24,7 @@ * THE SOFTWARE. */ +#include #include #include #include @@ -69,6 +70,11 @@ #error MICROPY_ENABLE_FINALISER requires MICROPY_ENABLE_GC #endif +// CIRCUITPY-CHANGE: Add selective collect support to malloc to optimize GC for large buffers +#if MICROPY_ENABLE_SELECTIVE_COLLECT +#error MICROPY_ENABLE_SELECTIVE_COLLECT requires MICROPY_ENABLE_GC +#endif + static void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) { if (allow_move) { return realloc(ptr, n_bytes); @@ -82,9 +88,26 @@ static void *realloc_ext(void *ptr, size_t n_bytes, bool allow_move) { #endif // MICROPY_ENABLE_GC -void *m_malloc(size_t num_bytes) { - void *ptr = malloc(num_bytes); - if (ptr == NULL && num_bytes != 0) { +// CIRCUITPY-CHANGE: Add malloc helper to factor out flag handling and allow combinations. +void *m_malloc_helper(size_t num_bytes, uint8_t flags) { + void *ptr; + #if MICROPY_ENABLE_GC + uint8_t gc_flags = 0; + #if MICROPY_ENABLE_SELECTIVE_COLLECT + if ((flags & M_MALLOC_COLLECT) == 0) { + gc_flags |= GC_ALLOC_FLAG_DO_NOT_COLLECT; + } + #endif + #if MICROPY_ENABLE_FINALISER + if ((flags & M_MALLOC_WITH_FINALISER) != 0) { + gc_flags |= GC_ALLOC_FLAG_HAS_FINALISER; + } + #endif + ptr = gc_alloc(num_bytes, gc_flags); + #else + ptr = malloc(num_bytes); + #endif + if (ptr == NULL && num_bytes != 0 && (flags & M_MALLOC_RAISE_ERROR)) { m_malloc_fail(num_bytes); } #if MICROPY_MEM_STATS @@ -92,44 +115,49 @@ void *m_malloc(size_t num_bytes) { MP_STATE_MEM(current_bytes_allocated) += num_bytes; UPDATE_PEAK(); #endif + // If this config is set then the GC clears all memory, so we don't need to. + #if !MICROPY_GC_CONSERVATIVE_CLEAR + if (flags & M_MALLOC_ENSURE_ZEROED) { + memset(ptr, 0, num_bytes); + } + #endif DEBUG_printf("malloc %d : %p\n", num_bytes, ptr); return ptr; } +void *m_malloc(size_t num_bytes) { + // CIRCUITPY-CHANGE: use helper + return m_malloc_helper(num_bytes, M_MALLOC_RAISE_ERROR | M_MALLOC_COLLECT); +} + void *m_malloc_maybe(size_t num_bytes) { - void *ptr = malloc(num_bytes); - #if MICROPY_MEM_STATS - MP_STATE_MEM(total_bytes_allocated) += num_bytes; - MP_STATE_MEM(current_bytes_allocated) += num_bytes; - UPDATE_PEAK(); - #endif - DEBUG_printf("malloc %d : %p\n", num_bytes, ptr); - return ptr; + // CIRCUITPY-CHANGE: use helper + return m_malloc_helper(num_bytes, M_MALLOC_COLLECT); } #if MICROPY_ENABLE_FINALISER void *m_malloc_with_finaliser(size_t num_bytes) { - void *ptr = malloc_with_finaliser(num_bytes); - if (ptr == NULL && num_bytes != 0) { - m_malloc_fail(num_bytes); - } - #if MICROPY_MEM_STATS - MP_STATE_MEM(total_bytes_allocated) += num_bytes; - MP_STATE_MEM(current_bytes_allocated) += num_bytes; - UPDATE_PEAK(); - #endif - DEBUG_printf("malloc %d : %p\n", num_bytes, ptr); - return ptr; + // CIRCUITPY-CHANGE: use helper + return m_malloc_helper(num_bytes, M_MALLOC_COLLECT | M_MALLOC_WITH_FINALISER); } #endif void *m_malloc0(size_t num_bytes) { - void *ptr = m_malloc(num_bytes); - // If this config is set then the GC clears all memory, so we don't need to. - #if !MICROPY_GC_CONSERVATIVE_CLEAR - memset(ptr, 0, num_bytes); - #endif - return ptr; + // CIRCUITPY-CHANGE: use helper + return m_malloc_helper(num_bytes, + (MICROPY_GC_CONSERVATIVE_CLEAR ? 0 : M_MALLOC_ENSURE_ZEROED) + | M_MALLOC_RAISE_ERROR | M_MALLOC_COLLECT); +} + +// CIRCUITPY-CHANGE: add selective collect +void *m_malloc_without_collect(size_t num_bytes) { + return m_malloc_helper(num_bytes, M_MALLOC_RAISE_ERROR); +} + +// CIRCUITPY-CHANGE: add selective collect +void *m_malloc_maybe_without_collect(size_t num_bytes) { + + return m_malloc_helper(num_bytes, 0); } #if MICROPY_MALLOC_USES_ALLOCATED_SIZE @@ -209,6 +237,31 @@ void m_free(void *ptr) #if MICROPY_TRACKED_ALLOC +#if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL +// If there's no GIL, use the GC recursive mutex to protect the tracked node linked list +// under m_tracked_head. +// +// (For ports with GIL, the expectation is to only call tracked alloc functions +// while holding the GIL.) + +static inline void m_tracked_node_lock(void) { + mp_thread_recursive_mutex_lock(&MP_STATE_MEM(gc_mutex), 1); +} + +static inline void m_tracked_node_unlock(void) { + mp_thread_recursive_mutex_unlock(&MP_STATE_MEM(gc_mutex)); +} + +#else + +static inline void m_tracked_node_lock(void) { +} + +static inline void m_tracked_node_unlock(void) { +} + +#endif + #define MICROPY_TRACKED_ALLOC_STORE_SIZE (!MICROPY_ENABLE_GC) typedef struct _m_tracked_node_t { @@ -222,6 +275,7 @@ typedef struct _m_tracked_node_t { #if MICROPY_DEBUG_VERBOSE static size_t m_tracked_count_links(size_t *nb) { + m_tracked_node_lock(); m_tracked_node_t *node = MP_STATE_VM(m_tracked_head); size_t n = 0; *nb = 0; @@ -234,6 +288,7 @@ static size_t m_tracked_count_links(size_t *nb) { #endif node = node->next; } + m_tracked_node_unlock(); return n; } #endif @@ -248,12 +303,14 @@ void *m_tracked_calloc(size_t nmemb, size_t size) { size_t n = m_tracked_count_links(&nb); DEBUG_printf("m_tracked_calloc(%u, %u) -> (%u;%u) %p\n", (int)nmemb, (int)size, (int)n, (int)nb, node); #endif + m_tracked_node_lock(); if (MP_STATE_VM(m_tracked_head) != NULL) { MP_STATE_VM(m_tracked_head)->prev = node; } node->prev = NULL; node->next = MP_STATE_VM(m_tracked_head); MP_STATE_VM(m_tracked_head) = node; + m_tracked_node_unlock(); #if MICROPY_TRACKED_ALLOC_STORE_SIZE node->size = nmemb * size; #endif @@ -279,7 +336,8 @@ void m_tracked_free(void *ptr_in) { size_t nb; size_t n = m_tracked_count_links(&nb); DEBUG_printf("m_tracked_free(%p, [%p, %p], nbytes=%u, links=%u;%u)\n", node, node->prev, node->next, (int)data_bytes, (int)n, (int)nb); - #endif + #endif // MICROPY_DEBUG_VERBOSE + m_tracked_node_lock(); if (node->next != NULL) { node->next->prev = node->prev; } @@ -288,6 +346,7 @@ void m_tracked_free(void *ptr_in) { } else { MP_STATE_VM(m_tracked_head) = node->next; } + m_tracked_node_unlock(); m_free(node #if MICROPY_MALLOC_USES_ALLOCATED_SIZE #if MICROPY_TRACKED_ALLOC_STORE_SIZE diff --git a/py/map.c b/py/map.c index d40e3dc4d02..c434e0d0cdd 100644 --- a/py/map.c +++ b/py/map.c @@ -86,13 +86,17 @@ static size_t get_hash_alloc_greater_or_equal_to(size_t x) { /******************************************************************************/ /* map */ +// CIRCUITPY-CHANGE: Helper for allocating tables of elements +#define malloc_table(num) m_new0(mp_map_elem_t, num) + void mp_map_init(mp_map_t *map, size_t n) { if (n == 0) { map->alloc = 0; map->table = NULL; } else { map->alloc = n; - map->table = m_new0(mp_map_elem_t, map->alloc); + // CIRCUITPY-CHANGE + map->table = malloc_table(map->alloc); } map->used = 0; map->all_keys_are_qstrs = 1; @@ -133,7 +137,8 @@ static void mp_map_rehash(mp_map_t *map) { size_t new_alloc = get_hash_alloc_greater_or_equal_to(map->alloc + 1); DEBUG_printf("mp_map_rehash(%p): " UINT_FMT " -> " UINT_FMT "\n", map, old_alloc, new_alloc); mp_map_elem_t *old_table = map->table; - mp_map_elem_t *new_table = m_new0(mp_map_elem_t, new_alloc); + // CIRCUITPY-CHANGE + mp_map_elem_t *new_table = malloc_table(new_alloc); // If we reach this point, table resizing succeeded, now we can edit the old map. map->alloc = new_alloc; map->used = 0; @@ -329,7 +334,8 @@ mp_map_elem_t *MICROPY_WRAP_MP_MAP_LOOKUP(mp_map_lookup)(mp_map_t * map, mp_obj_ void mp_set_init(mp_set_t *set, size_t n) { set->alloc = n; set->used = 0; - set->table = m_new0(mp_obj_t, set->alloc); + // CIRCUITPY-CHANGE + set->table = m_malloc_items0(set->alloc); } static void mp_set_rehash(mp_set_t *set) { @@ -337,7 +343,8 @@ static void mp_set_rehash(mp_set_t *set) { mp_obj_t *old_table = set->table; set->alloc = get_hash_alloc_greater_or_equal_to(set->alloc + 1); set->used = 0; - set->table = m_new0(mp_obj_t, set->alloc); + // CIRCUITPY-CHANGE + set->table = m_malloc_items0(set->alloc); for (size_t i = 0; i < old_alloc; i++) { if (old_table[i] != MP_OBJ_NULL && old_table[i] != MP_OBJ_SENTINEL) { mp_set_lookup(set, old_table[i], MP_MAP_LOOKUP_ADD_IF_NOT_FOUND); diff --git a/py/misc.h b/py/misc.h index 769d12ddbee..d5d7950574f 100644 --- a/py/misc.h +++ b/py/misc.h @@ -26,6 +26,8 @@ #ifndef MICROPY_INCLUDED_PY_MISC_H #define MICROPY_INCLUDED_PY_MISC_H +#include "py/mpconfig.h" + // a mini library of useful types and functions /** types *******************************************************/ @@ -33,13 +35,25 @@ #include #include #include - -// CIRCUITPY-CHANGE: include directly instead of depending on previous includes -#include "mpconfig.h" +// CIRCUITPY-CHANGE: #ifdef instead of #if +#ifdef __cplusplus // Required on at least one compiler to get ULLONG_MAX +#include +#else +#include +#endif typedef unsigned char byte; typedef unsigned int uint; +#ifndef __has_builtin +#define __has_builtin(x) (0) +#endif +#ifndef __has_feature +// This macro is supported by Clang and gcc>=14 +#define __has_feature(x) (0) +#endif + + /** generic ops *************************************************/ #ifndef MIN @@ -54,7 +68,15 @@ typedef unsigned int uint; #define MP_STRINGIFY(x) MP_STRINGIFY_HELPER(x) // Static assertion macro +// CIRCUITPY-CHANGE: defined() +#if defined(__cplusplus) +#define MP_STATIC_ASSERT(cond) static_assert((cond), #cond) +#elif __GNUC__ >= 5 || __STDC_VERSION__ >= 201112L +#define MP_STATIC_ASSERT(cond) _Static_assert((cond), #cond) +#else #define MP_STATIC_ASSERT(cond) ((void)sizeof(char[1 - 2 * !(cond)])) +#endif + // In C++ things like comparing extern const pointers are not constant-expressions so cannot be used // in MP_STATIC_ASSERT. Note that not all possible compiler versions will reject this. Some gcc versions // do, others only with -Werror=vla, msvc always does. @@ -63,7 +85,11 @@ typedef unsigned int uint; #if defined(_MSC_VER) || defined(__cplusplus) #define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)1) #else -#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) MP_STATIC_ASSERT(cond) +// CIRCUITPY-CHANGE: defined() +#if defined(__clang__) +#pragma GCC diagnostic ignored "-Wgnu-folding-constant" +#endif +#define MP_STATIC_ASSERT_NONCONSTEXPR(cond) ((void)sizeof(char[1 - 2 * !(cond)])) #endif // Round-up integer division @@ -74,6 +100,15 @@ typedef unsigned int uint; // TODO make a lazy m_renew that can increase by a smaller amount than requested (but by at least 1 more element) +// CIRCUITPY-CHANGE: new wrappers for selective collect, and use of m_malloc_helper() +// The following are convenience wrappers for m_malloc_helper and can save space at the call sites. +// m_malloc and m_new allocate space that is collected and does not have a finaliser. Use +// m_malloc_without_collect() if the space will not contain pointers to other heap allocations. It +// will still be marked and swept but not scanned for other pointers. +// Use m_malloc_items() to allocate space for mp_obj_ts that will be collected. +// Use mp_obj_malloc*() to allocate space for objects (aka structs with a type pointer) that will be +// collected. + #define m_new(type, num) ((type *)(m_malloc(sizeof(type) * (num)))) #define m_new_maybe(type, num) ((type *)(m_malloc_maybe(sizeof(type) * (num)))) #define m_new0(type, num) ((type *)(m_malloc0(sizeof(type) * (num)))) @@ -95,10 +130,25 @@ typedef unsigned int uint; #endif #define m_del_obj(type, ptr) (m_del(type, ptr, 1)) +#define m_malloc_items(num) m_malloc(sizeof(mp_obj_t) * (num)) +#define m_malloc_items0(num) m_malloc0(sizeof(mp_obj_t) * (num)) + +// Flags for m_malloc_helper +#define M_MALLOC_ENSURE_ZEROED (1 << 0) +#define M_MALLOC_RAISE_ERROR (1 << 1) +#define M_MALLOC_COLLECT (1 << 2) +#define M_MALLOC_WITH_FINALISER (1 << 3) + +void *m_malloc_helper(size_t num_bytes, uint8_t flags); void *m_malloc(size_t num_bytes); void *m_malloc_maybe(size_t num_bytes); void *m_malloc_with_finaliser(size_t num_bytes); void *m_malloc0(size_t num_bytes); + +// CIRCUITPY-CHANGE: _without_collect +void *m_malloc_without_collect(size_t num_bytes); +void *m_malloc_maybe_without_collect(size_t num_bytes); + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE void *m_realloc(void *ptr, size_t old_num_bytes, size_t new_num_bytes); void *m_realloc_maybe(void *ptr, size_t old_num_bytes, size_t new_num_bytes, bool allow_move); @@ -108,7 +158,7 @@ void *m_realloc(void *ptr, size_t new_num_bytes); void *m_realloc_maybe(void *ptr, size_t new_num_bytes, bool allow_move); void m_free(void *ptr); #endif -NORETURN void m_malloc_fail(size_t num_bytes); +MP_NORETURN void m_malloc_fail(size_t num_bytes); #if MICROPY_TRACKED_ALLOC // These alloc/free functions track the pointers in a linked list so the GC does not reclaim @@ -131,7 +181,7 @@ size_t m_get_peak_bytes_allocated(void); // align ptr to the nearest multiple of "alignment" #define MP_ALIGN(ptr, alignment) (void *)(((uintptr_t)(ptr) + ((alignment) - 1)) & ~((alignment) - 1)) -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: addition #define sizeof_field(TYPE, MEMBER) sizeof((((TYPE *)0)->MEMBER)) /** unichar / UTF-8 *********************************************/ @@ -278,6 +328,25 @@ typedef union _mp_float_union_t { mp_float_uint_t i; } mp_float_union_t; +#if MICROPY_FLOAT_FORMAT_IMPL == MICROPY_FLOAT_FORMAT_IMPL_EXACT + +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT +// Exact float conversion requires using internally a bigger sort of floating point +typedef double mp_large_float_t; +#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +typedef long double mp_large_float_t; +#endif +// Always use a 64 bit mantissa for formatting and parsing +typedef uint64_t mp_large_float_uint_t; + +#else // MICROPY_FLOAT_FORMAT_IMPL != MICROPY_FLOAT_FORMAT_IMPL_EXACT + +// No bigger floating points +typedef mp_float_t mp_large_float_t; +typedef mp_float_uint_t mp_large_float_uint_t; + +#endif + #endif // MICROPY_PY_BUILTINS_FLOAT /** ROM string compression *************/ @@ -343,4 +412,184 @@ typedef const char *mp_rom_error_text_t; // For now, forward directly to MP_COMPRESSED_ROM_TEXT. #define MP_ERROR_TEXT(x) (mp_rom_error_text_t)MP_COMPRESSED_ROM_TEXT(x) +// Portable implementations of CLZ and CTZ intrinsics +#ifdef _MSC_VER +#include + +static inline uint32_t mp_clz(uint32_t x) { + unsigned long lz = 0; + return _BitScanReverse(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; +} + +static inline uint32_t mp_clzl(unsigned long x) { + unsigned long lz = 0; + return _BitScanReverse(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; +} + +#ifdef _WIN64 +static inline uint32_t mp_clzll(unsigned long long x) { + unsigned long lz = 0; + return _BitScanReverse64(&lz, x) ? (sizeof(x) * 8 - 1) - lz : 0; +} +#else +// Microsoft don't ship _BitScanReverse64 on Win32, so emulate it +static inline uint32_t mp_clzll(unsigned long long x) { + unsigned long h = x >> 32; + return h ? mp_clzl(h) : (mp_clzl((unsigned long)x) + 32); +} +#endif + +static inline uint32_t mp_ctz(uint32_t x) { + unsigned long tz = 0; + return _BitScanForward(&tz, x) ? tz : 0; +} + +// Workaround for 'warning C4127: conditional expression is constant'. +static inline bool mp_check(bool value) { + return value; +} + +static inline uint32_t mp_popcount(uint32_t x) { + return __popcnt(x); +} +#else // _MSC_VER +#define mp_clz(x) __builtin_clz(x) +#define mp_clzl(x) __builtin_clzl(x) +#define mp_clzll(x) __builtin_clzll(x) +#define mp_ctz(x) __builtin_ctz(x) +#define mp_check(x) (x) +#if __has_builtin(__builtin_popcount) +#define mp_popcount(x) __builtin_popcount(x) +#else +static inline uint32_t mp_popcount(uint32_t x) { + x = x - ((x >> 1) & 0x55555555); + x = (x & 0x33333333) + ((x >> 2) & 0x33333333); + x = (x + (x >> 4)) & 0x0F0F0F0F; + return (x * 0x01010101) >> 24; +} +#endif // __has_builtin(__builtin_popcount) +#endif // _MSC_VER + +#define MP_FIT_UNSIGNED(bits, value) (((value) & (~0U << (bits))) == 0) +#define MP_FIT_SIGNED(bits, value) \ + (MP_FIT_UNSIGNED(((bits) - 1), (value)) || \ + (((value) & (~0U << ((bits) - 1))) == (~0U << ((bits) - 1)))) + +// mp_int_t can be larger than long, i.e. Windows 64-bit, nan-box variants +static inline uint32_t mp_clz_mpi(mp_int_t x) { + #ifdef __XC16__ + mp_uint_t mask = MP_OBJ_WORD_MSBIT_HIGH; + mp_uint_t zeroes = 0; + while (mask != 0) { + if (mask & (mp_uint_t)x) { + break; + } + zeroes++; + mask >>= 1; + } + return zeroes; + #else + #if MP_INT_MAX == INT_MAX + return mp_clz((unsigned)x); + #elif MP_INT_MAX == LONG_MAX + return mp_clzl((unsigned long)x); + #elif MP_INT_MAX == LLONG_MAX + return mp_clzll((unsigned long long)x); + #else + #error Unexpected MP_INT_MAX value + #endif + #endif +} + +// Overflow-checked operations + +// Integer overflow builtins were added to GCC 5, but __has_builtin only in GCC 10 +// +// Note that the builtins has a defined result when overflow occurs, whereas the custom +// functions below don't update the result if an overflow would occur (to avoid UB). +#define MP_GCC_HAS_BUILTIN_OVERFLOW (__GNUC__ >= 5) + +#if MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC + +#define mp_mul_ull_overflow __builtin_umulll_overflow +#define mp_mul_ll_overflow __builtin_smulll_overflow +static inline bool mp_mul_mp_int_t_overflow(mp_int_t x, mp_int_t y, mp_int_t *res) { + // __builtin_mul_overflow is a type-generic function, this inline ensures the argument + // types are checked to match mp_int_t. + return __builtin_mul_overflow(x, y, res); +} + +#else + +bool mp_mul_ll_overflow(long long int x, long long int y, long long int *res); +bool mp_mul_mp_int_t_overflow(mp_int_t x, mp_int_t y, mp_int_t *res); +static inline bool mp_mul_ull_overflow(unsigned long long int x, unsigned long long int y, unsigned long long int *res) { + if (y > 0 && x > (ULLONG_MAX / y)) { + return true; // overflow + } + *res = x * y; + return false; +} + +#endif + +#if __has_builtin(__builtin_saddll_overflow) || MP_GCC_HAS_BUILTIN_OVERFLOW +#define mp_add_ll_overflow __builtin_saddll_overflow +#else +static inline bool mp_add_ll_overflow(long long int lhs, long long int rhs, long long int *res) { + bool overflow; + + if (rhs > 0) { + overflow = (lhs > LLONG_MAX - rhs); + } else { + overflow = (lhs < LLONG_MIN - rhs); + } + + if (!overflow) { + *res = lhs + rhs; + } + + return overflow; +} +#endif + +#if __has_builtin(__builtin_ssubll_overflow) || MP_GCC_HAS_BUILTIN_OVERFLOW +#define mp_sub_ll_overflow __builtin_ssubll_overflow +#else +static inline bool mp_sub_ll_overflow(long long int lhs, long long int rhs, long long int *res) { + bool overflow; + + if (rhs > 0) { + overflow = (lhs < LLONG_MIN + rhs); + } else { + overflow = (lhs > LLONG_MAX + rhs); + } + + if (!overflow) { + *res = lhs - rhs; + } + + return overflow; +} +#endif + + +// Helper macros for detecting if sanitizers are enabled +// +// Use sparingly, not for masking issues reported by sanitizers! +// +// Can be detected automatically in Clang and gcc>=14, need to be +// set manually otherwise. +#ifndef MP_UBSAN +#define MP_UBSAN __has_feature(undefined_behavior_sanitizer) +#endif + +#ifndef MP_ASAN +#define MP_ASAN __has_feature(address_sanitizer) +#endif + +#ifndef MP_SANITIZER_BUILD +#define MP_SANITIZER_BUILD (MP_UBSAN || MP_ASAN) +#endif + #endif // MICROPY_INCLUDED_PY_MISC_H diff --git a/py/mkrules.cmake b/py/mkrules.cmake index bfc56abfe80..e3d769cc59b 100644 --- a/py/mkrules.cmake +++ b/py/mkrules.cmake @@ -14,11 +14,34 @@ set(MICROPY_MODULEDEFS "${MICROPY_GENHDR_DIR}/moduledefs.h") set(MICROPY_ROOT_POINTERS_SPLIT "${MICROPY_GENHDR_DIR}/root_pointers.split") set(MICROPY_ROOT_POINTERS_COLLECTED "${MICROPY_GENHDR_DIR}/root_pointers.collected") set(MICROPY_ROOT_POINTERS "${MICROPY_GENHDR_DIR}/root_pointers.h") +set(MICROPY_COMPRESSED_SPLIT "${MICROPY_GENHDR_DIR}/compressed.split") +set(MICROPY_COMPRESSED_COLLECTED "${MICROPY_GENHDR_DIR}/compressed.collected") +set(MICROPY_COMPRESSED_DATA "${MICROPY_GENHDR_DIR}/compressed.data.h") if(NOT MICROPY_PREVIEW_VERSION_2) set(MICROPY_PREVIEW_VERSION_2 0) endif() +# Set the board name. +if(MICROPY_BOARD) + if(MICROPY_BOARD_VARIANT) + set(MICROPY_BOARD_BUILD_NAME ${MICROPY_BOARD}-${MICROPY_BOARD_VARIANT}) + else() + set(MICROPY_BOARD_BUILD_NAME ${MICROPY_BOARD}) + endif() + + target_compile_definitions(${MICROPY_TARGET} PRIVATE + MICROPY_BOARD_BUILD_NAME="${MICROPY_BOARD_BUILD_NAME}" + ) +endif() + +# Need to do this before extracting MICROPY_CPP_DEF below. +if(MICROPY_ROM_TEXT_COMPRESSION) + target_compile_definitions(${MICROPY_TARGET} PUBLIC + MICROPY_ROM_TEXT_COMPRESSION=\(1\) + ) +endif() + # Need to do this before extracting MICROPY_CPP_DEF below. Rest of frozen # manifest handling is at the end of this file. if(MICROPY_FROZEN_MANIFEST) @@ -53,6 +76,15 @@ foreach(_arg ${MICROPY_CPP_DEF}) endforeach() list(APPEND MICROPY_CPP_FLAGS ${MICROPY_CPP_FLAGS_EXTRA}) +# Include anything passed in via CFLAGS_EXTRA +# in both MICROPY_CPP_FLAGS and CMAKE_C_FLAGS +if(DEFINED ENV{CFLAGS_EXTRA}) + set(CFLAGS_EXTRA $ENV{CFLAGS_EXTRA}) + string(APPEND CMAKE_C_FLAGS " ${CFLAGS_EXTRA}") # ... not a list + separate_arguments(CFLAGS_EXTRA) + list(APPEND MICROPY_CPP_FLAGS ${CFLAGS_EXTRA}) # ... a list +endif() + find_package(Python3 REQUIRED COMPONENTS Interpreter) target_sources(${MICROPY_TARGET} PRIVATE @@ -62,6 +94,18 @@ target_sources(${MICROPY_TARGET} PRIVATE ${MICROPY_ROOT_POINTERS} ) +if(MICROPY_ROM_TEXT_COMPRESSION) + target_sources(${MICROPY_TARGET} PRIVATE + ${MICROPY_COMPRESSED_DATA} + ) +endif() + +# Ensure genhdr directory is removed on clean + +set_property(TARGET ${MICROPY_TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES + "${MICROPY_GENHDR_DIR}" +) + # Command to force the build of another command # Generate mpversion.h @@ -175,11 +219,41 @@ add_custom_command( DEPENDS ${MICROPY_ROOT_POINTERS_COLLECTED} ${MICROPY_PY_DIR}/make_root_pointers.py ) +# Generate compressed.data.h + +add_custom_command( + OUTPUT ${MICROPY_COMPRESSED_SPLIT} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py split compress ${MICROPY_QSTRDEFS_LAST} ${MICROPY_GENHDR_DIR}/compress _ + COMMAND touch ${MICROPY_COMPRESSED_SPLIT} + DEPENDS ${MICROPY_QSTRDEFS_LAST} + VERBATIM + COMMAND_EXPAND_LISTS +) + +add_custom_command( + OUTPUT ${MICROPY_COMPRESSED_COLLECTED} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makeqstrdefs.py cat compress _ ${MICROPY_GENHDR_DIR}/compress ${MICROPY_COMPRESSED_COLLECTED} + BYPRODUCTS "${MICROPY_COMPRESSED_COLLECTED}.hash" + DEPENDS ${MICROPY_COMPRESSED_SPLIT} + VERBATIM + COMMAND_EXPAND_LISTS +) + +add_custom_command( + OUTPUT ${MICROPY_COMPRESSED_DATA} + COMMAND ${Python3_EXECUTABLE} ${MICROPY_PY_DIR}/makecompresseddata.py ${MICROPY_COMPRESSED_COLLECTED} > ${MICROPY_COMPRESSED_DATA} + DEPENDS ${MICROPY_COMPRESSED_COLLECTED} ${MICROPY_PY_DIR}/makecompresseddata.py +) + # Build frozen code if enabled if(MICROPY_FROZEN_MANIFEST) set(MICROPY_FROZEN_CONTENT "${CMAKE_BINARY_DIR}/frozen_content.c") + set_property(TARGET ${MICROPY_TARGET} APPEND PROPERTY ADDITIONAL_CLEAN_FILES + "${CMAKE_BINARY_DIR}/frozen_mpy" + ) + target_sources(${MICROPY_TARGET} PRIVATE ${MICROPY_FROZEN_CONTENT} ) @@ -187,16 +261,11 @@ if(MICROPY_FROZEN_MANIFEST) # Note: target_compile_definitions already added earlier. if(NOT MICROPY_LIB_DIR) - string(CONCAT GIT_SUBMODULES "${GIT_SUBMODULES} " lib/micropython-lib) + list(APPEND GIT_SUBMODULES lib/micropython-lib) set(MICROPY_LIB_DIR ${MICROPY_DIR}/lib/micropython-lib) endif() - if(ECHO_SUBMODULES) - # No-op, we're just doing submodule/variant discovery. - # Note: All the following rules are safe to run in discovery mode even - # though the submodule might not be available as they do not directly depend - # on anything from the submodule. - elseif(NOT EXISTS ${MICROPY_LIB_DIR}/README.md) + if(NOT UPDATE_SUBMODULES AND NOT EXISTS ${MICROPY_LIB_DIR}/README.md) message(FATAL_ERROR " micropython-lib not initialized.\n Run 'make BOARD=${MICROPY_BOARD} submodules'") endif() @@ -211,7 +280,7 @@ if(MICROPY_FROZEN_MANIFEST) endif() add_custom_command( OUTPUT ${MICROPY_MPYCROSS_DEPENDENCY} - COMMAND ${MICROPY_MAKE_EXECUTABLE} -C ${MICROPY_DIR}/mpy-cross + COMMAND ${MICROPY_MAKE_EXECUTABLE} -C ${MICROPY_DIR}/mpy-cross USER_C_MODULES= ) endif() @@ -250,12 +319,29 @@ if(MICROPY_FROZEN_MANIFEST) ) endif() -# Update submodules -if(ECHO_SUBMODULES) - # If cmake is run with GIT_SUBMODULES defined on command line, process the port / board - # settings then print the final GIT_SUBMODULES variable and exit. - # Note: the GIT_SUBMODULES is done via echo rather than message, as message splits - # the output onto multiple lines - execute_process(COMMAND ${CMAKE_COMMAND} -E echo "GIT_SUBMODULES=${GIT_SUBMODULES}") - message(FATAL_ERROR "Done") +# Update submodules, this is invoked on some ports via 'make submodules'. +# +# Note: This logic has a Makefile equivalent in py/mkrules.mk +if(UPDATE_SUBMODULES AND GIT_SUBMODULES) + macro(run_git) + execute_process(COMMAND git ${ARGV} WORKING_DIRECTORY ${MICROPY_DIR} + RESULT_VARIABLE RES) + endmacro() + + list(JOIN GIT_SUBMODULES " " GIT_SUBMODULES_MSG) + message("Updating submodules: ${GIT_SUBMODULES_MSG}") + run_git(submodule sync ${GIT_SUBMODULES}) + if(RES EQUAL 0) + # If available, do blobless partial clones of submodules to save time and space. + # A blobless partial clone lazily fetches data as needed, but has all the metadata available (tags, etc.). + run_git(submodule update --init --filter=blob:none ${GIT_SUBMODULES}) + # Fallback to standard submodule update if blobless isn't available (earlier than git 2.36.0) + if (NOT RES EQUAL 0) + run_git(submodule update --init ${GIT_SUBMODULES}) + endif() + endif() + + if (NOT RES EQUAL 0) + message(FATAL_ERROR "Submodule update failed") + endif() endif() diff --git a/py/mkrules.mk b/py/mkrules.mk index 058f5a9ee50..03988996c71 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -11,6 +11,7 @@ ifeq ($(MICROPY_PREVIEW_VERSION_2),1) CFLAGS += -DMICROPY_PREVIEW_VERSION_2=1 endif +# CIRCUITPY-CHANGE: point to CircuitPython documentation HELP_BUILD_ERROR ?= "See \033[1;31mhttps://learn.adafruit.com/building-circuitpython; Adafruit Discord \#circuitpython-dev\033[0m" HELP_MPY_LIB_SUBMODULE ?= "\033[1;31mError: micropython-lib submodule is not initialized.\033[0m Run 'make submodules'" @@ -27,6 +28,17 @@ OBJ_EXTRA_ORDER_DEPS += $(HEADER_BUILD)/compressed.data.h CFLAGS += -DMICROPY_ROM_TEXT_COMPRESSION=1 endif +# Set the variant or board name. +ifneq ($(VARIANT),) +CFLAGS += -DMICROPY_BOARD_BUILD_NAME=\"$(VARIANT)\" +else ifneq ($(BOARD),) +ifeq ($(BOARD_VARIANT),) +CFLAGS += -DMICROPY_BOARD_BUILD_NAME=\"$(BOARD)\" +else +CFLAGS += -DMICROPY_BOARD_BUILD_NAME=\"$(BOARD)-$(BOARD_VARIANT)\" +endif +endif + # QSTR generation uses the same CFLAGS, with these modifications. QSTR_GEN_FLAGS = -DNO_QSTR # Note: := to force evaluation immediately. @@ -87,8 +99,8 @@ $(Q)$(CXX) $(CXXFLAGS) -c -MD -MF $(@:.o=.d) -o $@ $< || (echo -e $(HELP_BUILD_E $(RM) -f $(@:.o=.d) endef -# CIRCUITPY-CHANGE: add $(DEVICES_MODULES) and $(BUILD) -vpath %.c . $(TOP) $(USER_C_MODULES) $(DEVICES_MODULES) $(BUILD) +# CIRCUITPY-CHANGE: add $(BUILD) +vpath %.c . $(TOP) $(USER_C_MODULES) $(BUILD) $(BUILD)/%.o: %.c $(call compile_c) @@ -101,6 +113,14 @@ $(BUILD)/%.pp: %.c $(STEPECHO) "PreProcess $<" $(Q)$(CPP) $(CFLAGS) -Wp,-C,-dD,-dI -o $@ $< +.PHONY: $(BUILD)/%.sz +$(BUILD)/%.sz: $(BUILD)/%.o + $(Q)$(SIZE) $< + +# Special case for compiling auto-generated source files. +$(BUILD)/%.o: $(BUILD)/%.c + $(call compile_c) + # The following rule uses | to create an order only prerequisite. Order only # prerequisites only get built if they don't exist. They don't cause timestamp # checking to be performed. @@ -168,7 +188,7 @@ $(HEADER_BUILD)/compressed.collected: $(HEADER_BUILD)/compressed.split # will be created if they don't exist. OBJ_DIRS = $(sort $(dir $(OBJ))) $(OBJ): | $(OBJ_DIRS) -// CIRCUITPY-CHANGE: use $(Q) +# CIRCUITPY-CHANGE: use $(Q) $(OBJ_DIRS): $(Q)$(MKDIR) -p $@ @@ -178,7 +198,7 @@ $(HEADER_BUILD): ifneq ($(MICROPY_MPYCROSS_DEPENDENCY),) # to automatically build mpy-cross, if needed $(MICROPY_MPYCROSS_DEPENDENCY): - $(MAKE) -C "$(abspath $(dir $@)..)" + $(MAKE) -C "$(abspath $(dir $@)..)" USER_C_MODULES= endif ifneq ($(FROZEN_DIR),) @@ -240,11 +260,17 @@ clean-prog: .PHONY: clean-prog endif +# If available, do blobless partial clones of submodules to save time and space. +# A blobless partial clone lazily fetches data as needed, but has all the metadata available (tags, etc.). +# Fallback to standard submodule update if blobless isn't available (earlier than 2.36.0) +# +# Note: This target has a CMake equivalent in py/mkrules.cmake submodules: $(ECHO) "Updating submodules: $(GIT_SUBMODULES)" ifneq ($(GIT_SUBMODULES),) - $(Q)git submodule sync $(addprefix $(TOP)/,$(GIT_SUBMODULES)) - $(Q)git submodule update --init $(addprefix $(TOP)/,$(GIT_SUBMODULES)) + $(Q)cd $(TOP) && git submodule sync $(GIT_SUBMODULES) + $(Q)cd $(TOP) && git submodule update --init --filter=blob:none $(GIT_SUBMODULES) 2>/dev/null || \ + git submodule update --init $(GIT_SUBMODULES) endif .PHONY: submodules diff --git a/py/moderrno.c b/py/moderrno.c index b5116bcadc7..140ae1cc0a6 100644 --- a/py/moderrno.c +++ b/py/moderrno.c @@ -35,6 +35,7 @@ // This list can be defined per port in mpconfigport.h to tailor it to a // specific port's needs. If it's not defined then we provide a default. #ifndef MICROPY_PY_ERRNO_LIST +// CIRCUITPY-CHANGE: add ENOSPC and EROFS, because they are in mp_common_errno_to_str(). #define MICROPY_PY_ERRNO_LIST \ X(EPERM) \ X(ENOENT) \ @@ -47,6 +48,8 @@ X(ENODEV) \ X(EISDIR) \ X(EINVAL) \ + X(ENOSPC) \ + X(EROFS) \ X(EOPNOTSUPP) \ X(EADDRINUSE) \ X(ECONNABORTED) \ diff --git a/py/modio.c b/py/modio.c index d3e563dbcf4..9aeb42d30aa 100644 --- a/py/modio.c +++ b/py/modio.c @@ -169,12 +169,13 @@ static mp_obj_t bufwriter_flush(mp_obj_t self_in) { int err; mp_uint_t out_sz = mp_stream_write_exactly(self->stream, self->buf, self->len, &err); (void)out_sz; - // TODO: try to recover from a case of non-blocking stream, e.g. move - // remaining chunk to the beginning of buffer. - assert(out_sz == self->len); - self->len = 0; if (err != 0) { mp_raise_OSError(err); + } else { + // TODO: try to recover from a case of non-blocking stream, e.g. move + // remaining chunk to the beginning of buffer. + assert(out_sz == self->len); + self->len = 0; } } diff --git a/py/modmath.c b/py/modmath.c index 701da796bce..2a9ed1b7f22 100644 --- a/py/modmath.c +++ b/py/modmath.c @@ -37,7 +37,7 @@ #define MP_PI_4 MICROPY_FLOAT_CONST(0.78539816339744830962) #define MP_3_PI_4 MICROPY_FLOAT_CONST(2.35619449019234492885) -static NORETURN void math_error(void) { +static MP_NORETURN void math_error(void) { mp_raise_ValueError(MP_ERROR_TEXT("math domain error")); } @@ -99,12 +99,16 @@ mp_float_t MICROPY_FLOAT_C_FUN(log2)(mp_float_t x) { MATH_FUN_1(sqrt, sqrt) // pow(x, y): returns x to the power of y #if MICROPY_PY_MATH_POW_FIX_NAN -mp_float_t pow_func(mp_float_t x, mp_float_t y) { +mp_float_t MICROPY_FLOAT_C_FUN(pow_func)(mp_float_t x, mp_float_t y) { // pow(base, 0) returns 1 for any base, even when base is NaN // pow(+1, exponent) returns 1 for any exponent, even when exponent is NaN if (x == MICROPY_FLOAT_CONST(1.0) || y == MICROPY_FLOAT_CONST(0.0)) { return MICROPY_FLOAT_CONST(1.0); } + // pow(base, NaN) returns NaN for any other value of base + if (isnan(y)) { + return y; + } return MICROPY_FLOAT_C_FUN(pow)(x, y); } MATH_FUN_2(pow, pow_func) @@ -161,6 +165,11 @@ MATH_FUN_2(atan2, atan2) MATH_FUN_1_TO_INT(ceil, ceil) // copysign(x, y) static mp_float_t MICROPY_FLOAT_C_FUN(copysign_func)(mp_float_t x, mp_float_t y) { + #if MICROPY_PY_MATH_COPYSIGN_FIX_NAN + if (isnan(y)) { + y = 0.0; + } + #endif return MICROPY_FLOAT_C_FUN(copysign)(x, y); } MATH_FUN_2(copysign, copysign_func) @@ -196,7 +205,17 @@ MATH_FUN_1(erf, erf) // erfc(x): return the complementary error function of x MATH_FUN_1(erfc, erfc) // gamma(x): return the gamma function of x +#if MICROPY_PY_MATH_GAMMA_FIX_NEGINF +static mp_float_t MICROPY_FLOAT_C_FUN(tgamma_func)(mp_float_t x) { + if (isinf(x) && x < 0) { + math_error(); + } + return MICROPY_FLOAT_C_FUN(tgamma)(x); +} +MATH_FUN_1(gamma, tgamma_func) +#else MATH_FUN_1(gamma, tgamma) +#endif // lgamma(x): return the natural logarithm of the gamma function of x MATH_FUN_1(lgamma, lgamma) #endif diff --git a/py/modmicropython.c b/py/modmicropython.c index 4a0e2cf44ff..67bb32626c3 100644 --- a/py/modmicropython.c +++ b/py/modmicropython.c @@ -27,7 +27,7 @@ #include #include "py/builtin.h" -#include "py/stackctrl.h" +#include "py/cstack.h" #include "py/runtime.h" #include "py/gc.h" #include "py/mphal.h" @@ -78,9 +78,9 @@ mp_obj_t mp_micropython_mem_info(size_t n_args, const mp_obj_t *args) { #endif #if MICROPY_STACK_CHECK mp_printf(&mp_plat_print, "stack: " UINT_FMT " out of " UINT_FMT "\n", - mp_stack_usage(), (mp_uint_t)MP_STATE_THREAD(stack_limit)); + mp_cstack_usage(), (mp_uint_t)MP_STATE_THREAD(stack_limit)); #else - mp_printf(&mp_plat_print, "stack: " UINT_FMT "\n", mp_stack_usage()); + mp_printf(&mp_plat_print, "stack: " UINT_FMT "\n", mp_cstack_usage()); #endif #if MICROPY_ENABLE_GC gc_dump_info(&mp_plat_print); @@ -100,7 +100,7 @@ static mp_obj_t mp_micropython_qstr_info(size_t n_args, const mp_obj_t *args) { size_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes; qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes); mp_printf(&mp_plat_print, "qstr pool: n_pool=%u, n_qstr=%u, n_str_data_bytes=%u, n_total_bytes=%u\n", - n_pool, n_qstr, n_str_data_bytes, n_total_bytes); + (uint)n_pool, (uint)n_qstr, (uint)n_str_data_bytes, (uint)n_total_bytes); if (n_args == 1) { // arg given means dump qstr data qstr_dump_data(); @@ -113,7 +113,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_micropython_qstr_info_obj, 0, 1, m #if MICROPY_PY_MICROPYTHON_STACK_USE static mp_obj_t mp_micropython_stack_use(void) { - return MP_OBJ_NEW_SMALL_INT(mp_stack_usage()); + return MP_OBJ_NEW_SMALL_INT(mp_cstack_usage()); } static MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_stack_use_obj, mp_micropython_stack_use); #endif @@ -136,13 +136,13 @@ static MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_lock_obj, mp_micropython_he static mp_obj_t mp_micropython_heap_unlock(void) { gc_unlock(); - return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth)); + return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth) >> GC_LOCK_DEPTH_SHIFT); } static MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_unlock_obj, mp_micropython_heap_unlock); #if MICROPY_PY_MICROPYTHON_HEAP_LOCKED static mp_obj_t mp_micropython_heap_locked(void) { - return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth)); + return MP_OBJ_NEW_SMALL_INT(MP_STATE_THREAD(gc_lock_depth) >> GC_LOCK_DEPTH_SHIFT); } static MP_DEFINE_CONST_FUN_OBJ_0(mp_micropython_heap_locked_obj, mp_micropython_heap_locked); #endif @@ -213,6 +213,9 @@ static const mp_rom_map_elem_t mp_module_micropython_globals_table[] = { #if CIRCUITPY_MICROPYTHON_ADVANCED && MICROPY_KBD_EXCEPTION { MP_ROM_QSTR(MP_QSTR_kbd_intr), MP_ROM_PTR(&mp_micropython_kbd_intr_obj) }, #endif + #if MICROPY_PY_MICROPYTHON_RINGIO + { MP_ROM_QSTR(MP_QSTR_RingIO), MP_ROM_PTR(&mp_type_ringio) }, + #endif #if MICROPY_ENABLE_SCHEDULER { MP_ROM_QSTR(MP_QSTR_schedule), MP_ROM_PTR(&mp_micropython_schedule_obj) }, #endif diff --git a/py/modsys.c b/py/modsys.c index 2bb2606a062..bbae93d0c3f 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -26,6 +26,7 @@ */ #include "py/builtin.h" +#include "py/objexcept.h" #include "py/objlist.h" #include "py/objmodule.h" #include "py/objtuple.h" @@ -94,13 +95,44 @@ static const MP_DEFINE_STR_OBJ(mp_sys_implementation_machine_obj, MICROPY_BANNER MP_ROM_PTR(&mp_sys_implementation_machine_obj) #if MICROPY_PERSISTENT_CODE_LOAD +// Note: Adding architecture flags to _mpy will break if the flags information +// takes up more bits than what is available in a small-int value. +#if MICROPY_EMIT_RV32 +#include "py/asmrv32.h" +#define MPY_FILE_ARCH_FLAGS (MICROPY_RV32_EXTENSIONS << 16) +#else +#define MPY_FILE_ARCH_FLAGS (0) +#endif #define SYS_IMPLEMENTATION_ELEMS__MPY \ - , MP_ROM_INT(MPY_FILE_HEADER_INT) + , MP_ROM_INT(MPY_FILE_HEADER_INT | MPY_FILE_ARCH_FLAGS) #else #define SYS_IMPLEMENTATION_ELEMS__MPY #endif #if MICROPY_PY_ATTRTUPLE + +#if defined(MICROPY_BOARD_BUILD_NAME) +static const MP_DEFINE_STR_OBJ(mp_sys_implementation__build_obj, MICROPY_BOARD_BUILD_NAME); +#define MICROPY_BOARD_BUILD (1) +#define SYS_IMPLEMENTATION_ELEMS__BUILD \ + , MP_ROM_PTR(&mp_sys_implementation__build_obj) +#else +#define MICROPY_BOARD_BUILD (0) +#define SYS_IMPLEMENTATION_ELEMS__BUILD +#endif + +#if MICROPY_PY_THREAD +#if MICROPY_PY_THREAD_GIL +#define SYS_IMPLEMENTATION_ELEMS__THREAD \ + , MP_ROM_QSTR(MP_QSTR_GIL) +#else +#define SYS_IMPLEMENTATION_ELEMS__THREAD \ + , MP_ROM_QSTR(MP_QSTR_unsafe) +#endif +#else +#define SYS_IMPLEMENTATION_ELEMS__THREAD +#endif + #if MICROPY_PREVIEW_VERSION_2 #define SYS_IMPLEMENTATION_ELEMS__V2 \ , MP_ROM_TRUE @@ -115,6 +147,12 @@ static const qstr impl_fields[] = { #if MICROPY_PERSISTENT_CODE_LOAD MP_QSTR__mpy, #endif + #if defined(MICROPY_BOARD_BUILD_NAME) + MP_QSTR__build, + #endif + #if MICROPY_PY_THREAD + MP_QSTR__thread, + #endif #if MICROPY_PREVIEW_VERSION_2 MP_QSTR__v2, #endif @@ -122,19 +160,21 @@ static const qstr impl_fields[] = { static MP_DEFINE_ATTRTUPLE( mp_sys_implementation_obj, impl_fields, - 3 + MICROPY_PERSISTENT_CODE_LOAD + MICROPY_PREVIEW_VERSION_2, + 3 + MICROPY_PERSISTENT_CODE_LOAD + MICROPY_BOARD_BUILD + MICROPY_PY_THREAD + MICROPY_PREVIEW_VERSION_2, SYS_IMPLEMENTATION_ELEMS_BASE SYS_IMPLEMENTATION_ELEMS__MPY + SYS_IMPLEMENTATION_ELEMS__BUILD + SYS_IMPLEMENTATION_ELEMS__THREAD SYS_IMPLEMENTATION_ELEMS__V2 ); #else static const mp_rom_obj_tuple_t mp_sys_implementation_obj = { {&mp_type_tuple}, 3 + MICROPY_PERSISTENT_CODE_LOAD, - // Do not include SYS_IMPLEMENTATION_ELEMS__V2 because - // SYS_IMPLEMENTATION_ELEMS__MPY may be empty if + // Do not include SYS_IMPLEMENTATION_ELEMS__BUILD, SYS_IMPLEMENTATION_ELEMS__THREAD + // or SYS_IMPLEMENTATION_ELEMS__V2 because SYS_IMPLEMENTATION_ELEMS__MPY may be empty if // MICROPY_PERSISTENT_CODE_LOAD is disabled, which means they'll share - // the same index. Cannot query _v2 if MICROPY_PY_ATTRTUPLE is + // the same index. Cannot query _build, _thread or _v2 if MICROPY_PY_ATTRTUPLE is // disabled. { SYS_IMPLEMENTATION_ELEMS_BASE @@ -170,29 +210,7 @@ static mp_obj_t mp_sys_exit(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit); -static mp_obj_t mp_sys_print_exception(size_t n_args, const mp_obj_t *args) { - // CIRCUITPY-CHANGE - #if CIRCUITPY_WARNINGS - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_print_exception, MP_QSTR_sys, MP_QSTR_traceback); - #endif - - #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES - void *stream_obj = &mp_sys_stdout_obj; - if (n_args > 1) { - mp_get_stream_raise(args[1], MP_STREAM_OP_WRITE); - stream_obj = MP_OBJ_TO_PTR(args[1]); - } - - mp_print_t print = {stream_obj, mp_stream_write_adaptor}; - mp_obj_print_exception(&print, args[0]); - #else - (void)n_args; - mp_obj_print_exception(&mp_plat_print, args[0]); - #endif - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception); +// CIRCUITPY-CHANGE: Removed print_exception because it isn't in CPython. #if MICROPY_PY_SYS_EXC_INFO static mp_obj_t mp_sys_exc_info(void) { @@ -209,7 +227,8 @@ static mp_obj_t mp_sys_exc_info(void) { t->items[0] = MP_OBJ_FROM_PTR(mp_obj_get_type(cur_exc)); t->items[1] = cur_exc; // CIRCUITPY-CHANGE: has traceback obj - t->items[2] = mp_obj_exception_get_traceback_obj(cur_exc); + mp_obj_exception_t *native_exc = mp_obj_exception_get_native(cur_exc); + t->items[2] = native_exc->traceback; return MP_OBJ_FROM_PTR(t); } MP_DEFINE_CONST_FUN_OBJ_0(mp_sys_exc_info_obj, mp_sys_exc_info); @@ -347,8 +366,6 @@ static const mp_rom_map_elem_t mp_module_sys_globals_table[] = { /* * Extensions to CPython */ - - { MP_ROM_QSTR(MP_QSTR_print_exception), MP_ROM_PTR(&mp_sys_print_exception_obj) }, #if MICROPY_PY_SYS_ATEXIT { MP_ROM_QSTR(MP_QSTR_atexit), MP_ROM_PTR(&mp_sys_atexit_obj) }, #endif diff --git a/py/modthread.c b/py/modthread.c index 188449802fd..1b792eaeb77 100644 --- a/py/modthread.c +++ b/py/modthread.c @@ -28,7 +28,6 @@ #include #include "py/runtime.h" -#include "py/stackctrl.h" #if MICROPY_PY_THREAD diff --git a/py/mpconfig.h b/py/mpconfig.h index 60e7afe52f9..0e440066d78 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -26,6 +26,15 @@ #ifndef MICROPY_INCLUDED_PY_MPCONFIG_H #define MICROPY_INCLUDED_PY_MPCONFIG_H +#include +#include + +#if defined(__cplusplus) // Required on at least one compiler to get ULLONG_MAX +#include +#else +#include +#endif + // CIRCUITPY-CHANGE // Is this a CircuitPython build? #ifndef CIRCUITPY @@ -40,7 +49,7 @@ // as well as a fallback to generate MICROPY_GIT_TAG if the git repo or tags // are unavailable. #define MICROPY_VERSION_MAJOR 1 -#define MICROPY_VERSION_MINOR 23 +#define MICROPY_VERSION_MINOR 27 #define MICROPY_VERSION_MICRO 0 #define MICROPY_VERSION_PRERELEASE 0 @@ -173,6 +182,81 @@ #define MICROPY_OBJ_IMMEDIATE_OBJS (MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D) #endif +// Definition of the `mp_int_t` and `mp_uint_t` types and associated macros. +// Normally, it suffices for the platform to do nothing: A type as wide +// as a pointer is chosen, unless nanboxing (REPR_D) is selected, in +// which case a 64-bit type is chosen to match the assumed size of +// double-precision floats. +// +// In the case of exceptions, the port, board, or variant must define +// MP_INT_TYPE as MP_INT_TYPE_OTHER and provide all the typedefs and +// defines. +#define MP_INT_TYPE_INTPTR (0) +#define MP_INT_TYPE_INT64 (1) +#define MP_INT_TYPE_OTHER (2) + +#if !defined(MP_INT_TYPE) +#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D +#define MP_INT_TYPE (MP_INT_TYPE_INT64) +#else +#define MP_INT_TYPE (MP_INT_TYPE_INTPTR) +#endif +#endif + +#if MP_INT_TYPE == MP_INT_TYPE_INTPTR +typedef intptr_t mp_int_t; +// Use size_t so kw-function signatures and other size-typed APIs match without +// triggering -Wincompatible-pointer-types under newer GCCs where size_t and +// uintptr_t are distinct types of the same width (e.g. picolibc on 32-bit ARM). +typedef size_t mp_uint_t; +#define MP_INT_MAX INTPTR_MAX +#define MP_INT_MIN INTPTR_MIN +#define MP_UINT_MAX SIZE_MAX +#elif MP_INT_TYPE == MP_INT_TYPE_INT64 +typedef int64_t mp_int_t; +typedef uint64_t mp_uint_t; +#define MP_INT_MAX INT64_MAX +#define MP_INT_MIN INT64_MIN +#define MP_UINT_MAX INT64_UMAX +#endif + +// mp_printf format support for mp_int_t. In the unusual case that MP_INT_MAX doesn't +// match any of the standard C types (int/long/long long), provide all 3 +// macros. Otherwise, rely on these automatic definitions. +#if !defined(INT_FMT) +#if MP_INT_MAX == INT_MAX +#define INT_FMT "%d" +#define UINT_FMT "%u" +#define HEX_FMT "%x" +#elif MP_INT_MAX == LONG_MAX +#define INT_FMT "%ld" +#define UINT_FMT "%lu" +#define HEX_FMT "%lx" +#elif MP_INT_MAX == LLONG_MAX +#define INT_FMT "%lld" +#define UINT_FMT "%llu" +#define HEX_FMT "%llx" +#else +#error Unexpected MP_INT_MAX value +#endif +#endif + +// mp_printf format support for size_t. In the unusual case that SIZE_MAX doesn't +// match any of the standard C types (int/long/long long), provide a +// macro. Otherwise, rely on these automatic definitions. +#if !defined(SIZE_FMT) +#if SIZE_MAX == UINT_MAX +#define SIZE_FMT "%u" +#elif SIZE_MAX == ULONG_MAX +#define SIZE_FMT "%lu" +#elif SIZE_MAX == ULLONG_MAX +#define SIZE_FMT "%llu" +#else +#error Unexpected SIZE_MAX value +#endif +#endif + + /*****************************************************************************/ /* Memory allocation policy */ @@ -354,6 +438,11 @@ #define MICROPY_PERSISTENT_CODE_SAVE_FILE (0) #endif +// Whether to support converting functions to persistent code (bytes) +#ifndef MICROPY_PERSISTENT_CODE_SAVE_FUN +#define MICROPY_PERSISTENT_CODE_SAVE_FUN (MICROPY_PY_MARSHAL) +#endif + // Whether generated code can persist independently of the VM/runtime instance // This is enabled automatically when needed by other features #ifndef MICROPY_PERSISTENT_CODE @@ -413,13 +502,38 @@ #define MICROPY_EMIT_INLINE_XTENSA (0) #endif +// Whether to support uncommon Xtensa inline assembler opcodes +#ifndef MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES +#define MICROPY_EMIT_INLINE_XTENSA_UNCOMMON_OPCODES (0) +#endif + // Whether to emit Xtensa-Windowed native code #ifndef MICROPY_EMIT_XTENSAWIN #define MICROPY_EMIT_XTENSAWIN (0) #endif +// Whether to emit RISC-V RV32 native code +#ifndef MICROPY_EMIT_RV32 +#define MICROPY_EMIT_RV32 (0) +#endif + +// Whether to emit RISC-V RV32 Zba opcodes in native code +#ifndef MICROPY_EMIT_RV32_ZBA +#define MICROPY_EMIT_RV32_ZBA (0) +#endif + +// Whether to enable the RISC-V RV32 inline assembler +#ifndef MICROPY_EMIT_INLINE_RV32 +#define MICROPY_EMIT_INLINE_RV32 (0) +#endif + +// Whether to enable the human-readable native instructions emitter +#ifndef MICROPY_EMIT_NATIVE_DEBUG +#define MICROPY_EMIT_NATIVE_DEBUG (0) +#endif + // Convenience definition for whether any native emitter is enabled -#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_X86 || MICROPY_EMIT_THUMB || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA || MICROPY_EMIT_XTENSAWIN) +#define MICROPY_EMIT_NATIVE (MICROPY_EMIT_X64 || MICROPY_EMIT_X86 || MICROPY_EMIT_THUMB || MICROPY_EMIT_ARM || MICROPY_EMIT_XTENSA || MICROPY_EMIT_XTENSAWIN || MICROPY_EMIT_RV32 || MICROPY_EMIT_NATIVE_DEBUG) // Some architectures cannot read byte-wise from executable memory. In this case // the prelude for a native function (which usually sits after the machine code) @@ -427,23 +541,11 @@ #define MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE (MICROPY_EMIT_XTENSAWIN) // Convenience definition for whether any inline assembler emitter is enabled -#define MICROPY_EMIT_INLINE_ASM (MICROPY_EMIT_INLINE_THUMB || MICROPY_EMIT_INLINE_XTENSA) +#define MICROPY_EMIT_INLINE_ASM (MICROPY_EMIT_INLINE_THUMB || MICROPY_EMIT_INLINE_XTENSA || MICROPY_EMIT_INLINE_RV32) // Convenience definition for whether any native or inline assembler emitter is enabled #define MICROPY_EMIT_MACHINE_CODE (MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM) -// Whether native relocatable code loaded from .mpy files is explicitly tracked -// so that the GC cannot reclaim it. Needed on architectures that allocate -// executable memory on the MicroPython heap and don't explicitly track this -// data some other way. -#ifndef MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE -#if !MICROPY_EMIT_MACHINE_CODE || defined(MP_PLAT_ALLOC_EXEC) || defined(MP_PLAT_COMMIT_EXEC) -#define MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE (0) -#else -#define MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE (1) -#endif -#endif - /*****************************************************************************/ /* Compiler configuration */ @@ -489,6 +591,13 @@ #define MICROPY_COMP_CONST (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif +// Whether to enable float constant folding like 1.2+3.4 (when MICROPY_COMP_CONST_FOLDING is also enabled) +// and constant optimisation like id = const(1.2) (when MICROPY_COMP_CONST is also enabled) +// and constant lookup like math.inf (when MICROPY_COMP_MODULE_CONST is also enabled) +#ifndef MICROPY_COMP_CONST_FLOAT +#define MICROPY_COMP_CONST_FLOAT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) +#endif + // Whether to enable optimisation of: a, b = c, d // Costs 124 bytes (Thumb2) #ifndef MICROPY_COMP_DOUBLE_TUPLE_ASSIGN @@ -712,6 +821,20 @@ #define MICROPY_STACK_CHECK (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif +// Additional margin between the places in the runtime where Python stack is +// checked and the actual end of the C stack. Needs to be large enough to avoid +// overflows from function calls made between checks. +#ifndef MICROPY_STACK_CHECK_MARGIN +#define MICROPY_STACK_CHECK_MARGIN (0) +#endif + +// The size of a separate stack used for hard IRQ handlers, which should be +// checked instead of the main stack when running a hard callback. 0 implies +// there is no separate ISR stack to check. +#ifndef MICROPY_STACK_SIZE_HARD_IRQ +#define MICROPY_STACK_SIZE_HARD_IRQ (0) +#endif + // Whether to have an emergency exception buffer #ifndef MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF #define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (0) @@ -881,6 +1004,27 @@ typedef double mp_float_t; #define MICROPY_PY_BUILTINS_COMPLEX (MICROPY_PY_BUILTINS_FLOAT) #endif +// Float to string conversion implementations +// +// Note that the EXACT method is only available if the compiler supports +// floating points larger than mp_float_t: +// - with MICROPY_FLOAT_IMPL_FLOAT, the compiler needs to support `double` +// - with MICROPY_FLOAT_IMPL_DOUBLE, the compiler needs to support `long double` +// +#define MICROPY_FLOAT_FORMAT_IMPL_BASIC (0) // smallest code, but inexact +#define MICROPY_FLOAT_FORMAT_IMPL_APPROX (1) // slightly bigger, almost perfect +#define MICROPY_FLOAT_FORMAT_IMPL_EXACT (2) // bigger code, and 100% exact repr + +#ifndef MICROPY_FLOAT_FORMAT_IMPL +#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT +#define MICROPY_FLOAT_FORMAT_IMPL (MICROPY_FLOAT_FORMAT_IMPL_APPROX) +#elif defined(__SIZEOF_LONG_DOUBLE__) && __SIZEOF_LONG_DOUBLE__ > __SIZEOF_DOUBLE__ +#define MICROPY_FLOAT_FORMAT_IMPL (MICROPY_FLOAT_FORMAT_IMPL_EXACT) +#else +#define MICROPY_FLOAT_FORMAT_IMPL (MICROPY_FLOAT_FORMAT_IMPL_APPROX) +#endif +#endif + // Whether to use the native _Float16 for 16-bit float support #ifndef MICROPY_FLOAT_USE_NATIVE_FLT16 #ifdef __FLT16_MAX__ @@ -913,6 +1057,64 @@ typedef double mp_float_t; #define MICROPY_FULL_CHECKS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif +// Ports can choose to use timestamps based on 2000-01-01 or 1970-01-01 +// Default is timestamps based on 2000-01-01 +#if !defined(MICROPY_EPOCH_IS_2000) && !defined(MICROPY_EPOCH_IS_1970) +#define MICROPY_EPOCH_IS_2000 (1) +#define MICROPY_EPOCH_IS_1970 (0) +#elif !defined(MICROPY_EPOCH_IS_1970) +#define MICROPY_EPOCH_IS_1970 (1 - (MICROPY_EPOCH_IS_2000)) +#elif !defined(MICROPY_EPOCH_IS_2000) +#define MICROPY_EPOCH_IS_2000 (1 - (MICROPY_EPOCH_IS_1970)) +#endif + +// To maintain reasonable compatibility with CPython on embedded systems, +// and avoid breaking anytime soon, time functions are defined to work +// at least between 1970 and 2099 (included) on any machine. +// +// Specific ports can enable extended date support +// - after 2099 using MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND +// - before 1970 using MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE +// The largest possible range is year 1600 to year 3000 +// +// By default, extended date support is only enabled for machines using 64 bit pointers, +// but it can be enabled by specific ports +#ifndef MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE +#if MP_SSIZE_MAX > 2147483647 +#define MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE (1) +#else +#define MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE (0) +#endif +#endif + +// When support for dates <1970 is enabled, supporting >=2100 does not cost anything +#ifndef MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND +#define MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND (MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE) +#endif + +// The type to be used to represent platform-specific timestamps depends on the choices above +#define MICROPY_TIMESTAMP_IMPL_LONG_LONG (0) +#define MICROPY_TIMESTAMP_IMPL_UINT (1) +#define MICROPY_TIMESTAMP_IMPL_TIME_T (2) + +#ifndef MICROPY_TIMESTAMP_IMPL +#if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE || MICROPY_EPOCH_IS_2000 +#define MICROPY_TIMESTAMP_IMPL (MICROPY_TIMESTAMP_IMPL_LONG_LONG) +#else +#define MICROPY_TIMESTAMP_IMPL (MICROPY_TIMESTAMP_IMPL_UINT) +#endif +#endif + +// `mp_timestamp_t` is the type that should be used by the port +// to represent timestamps, and is referenced to the platform epoch +#if MICROPY_TIMESTAMP_IMPL == MICROPY_TIMESTAMP_IMPL_LONG_LONG +typedef long long mp_timestamp_t; +#elif MICROPY_TIMESTAMP_IMPL == MICROPY_TIMESTAMP_IMPL_UINT +typedef mp_uint_t mp_timestamp_t; +#elif MICROPY_TIMESTAMP_IMPL == MICROPY_TIMESTAMP_IMPL_TIME_T +typedef time_t mp_timestamp_t; +#endif + // Whether POSIX-semantics non-blocking streams are supported #ifndef MICROPY_STREAMS_NON_BLOCK #define MICROPY_STREAMS_NON_BLOCK (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -924,6 +1126,16 @@ typedef double mp_float_t; #define MICROPY_STREAMS_POSIX_API (0) #endif +// Whether to process __all__ when importing all public symbols from a module. +#ifndef MICROPY_MODULE___ALL__ +#define MICROPY_MODULE___ALL__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_BASIC_FEATURES) +#endif + +// Whether to set __file__ on imported modules. +#ifndef MICROPY_MODULE___FILE__ +#define MICROPY_MODULE___FILE__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) +#endif + // Whether modules can use MP_REGISTER_MODULE_DELEGATION() to delegate failed // attribute lookups to a custom handler function. #ifndef MICROPY_MODULE_ATTR_DELEGATION @@ -1011,6 +1223,16 @@ typedef double mp_float_t; #define MICROPY_ENABLE_VM_ABORT (0) #endif +// Whether to handle abort behavior in pyexec code +#ifndef MICROPY_PYEXEC_ENABLE_VM_ABORT +#define MICROPY_PYEXEC_ENABLE_VM_ABORT (0) +#endif + +// Whether to set exit codes according to the exit reason (keyboard interrupt, crash, normal exit, ...) +#ifndef MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING +#define MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING (0) +#endif + // Support for internal scheduler #ifndef MICROPY_ENABLE_SCHEDULER #define MICROPY_ENABLE_SCHEDULER (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -1031,11 +1253,26 @@ typedef double mp_float_t; #define MICROPY_VFS (0) #endif +// Whether to include support for writable filesystems. +#ifndef MICROPY_VFS_WRITABLE +#define MICROPY_VFS_WRITABLE (1) +#endif + +// Whether to enable the mp_vfs_rom_ioctl C function, and vfs.rom_ioctl Python function +#ifndef MICROPY_VFS_ROM_IOCTL +#define MICROPY_VFS_ROM_IOCTL (MICROPY_VFS_ROM) +#endif + // Support for VFS POSIX component, to mount a POSIX filesystem within VFS #ifndef MICROPY_VFS_POSIX #define MICROPY_VFS_POSIX (0) #endif +// Whether to include support for writable POSIX filesystems. +#ifndef MICROPY_VFS_POSIX_WRITABLE +#define MICROPY_VFS_POSIX_WRITABLE (1) +#endif + // Support for VFS FAT component, to mount a FAT filesystem within VFS #ifndef MICROPY_VFS_FAT #define MICROPY_VFS_FAT (0) @@ -1051,6 +1288,11 @@ typedef double mp_float_t; #define MICROPY_VFS_LFS2 (0) #endif +// Support for ROMFS. +#ifndef MICROPY_VFS_ROM +#define MICROPY_VFS_ROM (0) +#endif + /*****************************************************************************/ /* Fine control over Python builtins, classes, modules, etc */ @@ -1066,7 +1308,20 @@ typedef double mp_float_t; #define MICROPY_PY_FUNCTION_ATTRS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Whether to support the descriptors __get__, __set__, __delete__ +// Whether to implement the __code__ attribute on functions, and function constructor +#ifndef MICROPY_PY_FUNCTION_ATTRS_CODE +#define MICROPY_PY_FUNCTION_ATTRS_CODE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_FULL_FEATURES) +#endif + +// Whether bound_method can just use == (feature disabled), or requires a call to +// mp_obj_equal (feature enabled), to test equality of the self and meth entities. +// This is only needed if objects and functions can be identical without being the +// same thing, eg when using an object proxy. +#ifndef MICROPY_PY_BOUND_METHOD_FULL_EQUALITY_CHECK +#define MICROPY_PY_BOUND_METHOD_FULL_EQUALITY_CHECK (0) +#endif + +// Whether to support the descriptors __get__, __set__, __delete__, __set_name__ // This costs some code size and makes load/store/delete of instance // attributes slower for the classes that use this feature #ifndef MICROPY_PY_DESCRIPTORS @@ -1154,6 +1409,15 @@ typedef double mp_float_t; #define MICROPY_PY_BUILTINS_BYTEARRAY (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif +// Whether to support code objects, and how many features they have +#define MICROPY_PY_BUILTINS_CODE_NONE (0) +#define MICROPY_PY_BUILTINS_CODE_MINIMUM (1) +#define MICROPY_PY_BUILTINS_CODE_BASIC (2) +#define MICROPY_PY_BUILTINS_CODE_FULL (3) +#ifndef MICROPY_PY_BUILTINS_CODE +#define MICROPY_PY_BUILTINS_CODE (MICROPY_PY_SYS_SETTRACE ? MICROPY_PY_BUILTINS_CODE_FULL : (MICROPY_PY_FUNCTION_ATTRS_CODE ? MICROPY_PY_BUILTINS_CODE_BASIC : (MICROPY_PY_BUILTINS_COMPILE ? MICROPY_PY_BUILTINS_CODE_MINIMUM : MICROPY_PY_BUILTINS_CODE_NONE))) +#endif + // Whether to support dict.fromkeys() class method #ifndef MICROPY_PY_BUILTINS_DICT_FROMKEYS #define MICROPY_PY_BUILTINS_DICT_FROMKEYS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) @@ -1216,7 +1480,7 @@ typedef double mp_float_t; // Support for calling next() with second argument #ifndef MICROPY_PY_BUILTINS_NEXT2 -#define MICROPY_PY_BUILTINS_NEXT2 (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) +#define MICROPY_PY_BUILTINS_NEXT2 (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_BASIC_FEATURES) #endif // Whether to support rounding of integers (incl bignum); eg round(123,-1)=120 @@ -1314,11 +1578,6 @@ typedef double mp_float_t; #define MICROPY_PY_BUILTINS_HELP_MODULES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Whether to set __file__ for imported modules -#ifndef MICROPY_PY___FILE__ -#define MICROPY_PY___FILE__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) -#endif - // Whether to provide mem-info related functions in micropython module #ifndef MICROPY_PY_MICROPYTHON_MEM_INFO #define MICROPY_PY_MICROPYTHON_MEM_INFO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -1334,6 +1593,11 @@ typedef double mp_float_t; #define MICROPY_PY_MICROPYTHON_HEAP_LOCKED (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif +// Support for micropython.RingIO() +#ifndef MICROPY_PY_MICROPYTHON_RINGIO +#define MICROPY_PY_MICROPYTHON_RINGIO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether to provide "array" module. Note that large chunk of the // underlying code is shared with "bytearray" builtin type, so to // get real savings, it should be disabled too. @@ -1383,6 +1647,11 @@ typedef double mp_float_t; #define MICROPY_PY_COLLECTIONS_NAMEDTUPLE__ASDICT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) #endif +// Whether to provide "marshal" module +#ifndef MICROPY_PY_MARSHAL +#define MICROPY_PY_MARSHAL (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EVERYTHING) +#endif + // Whether to provide "math" module #ifndef MICROPY_PY_MATH #define MICROPY_PY_MATH (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) @@ -1424,10 +1693,16 @@ typedef double mp_float_t; #endif // Whether to provide fix for pow(1, NaN) and pow(NaN, 0), which both should be 1 not NaN. +// Also fixes pow(base, NaN) to return NaN for other values of base. #ifndef MICROPY_PY_MATH_POW_FIX_NAN #define MICROPY_PY_MATH_POW_FIX_NAN (0) #endif +// Whether to provide fix for gamma(-inf) to raise ValueError +#ifndef MICROPY_PY_MATH_GAMMA_FIX_NEGINF +#define MICROPY_PY_MATH_GAMMA_FIX_NEGINF (0) +#endif + // Whether to provide "cmath" module #ifndef MICROPY_PY_CMATH #define MICROPY_PY_CMATH (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -1455,7 +1730,7 @@ typedef double mp_float_t; // Whether to provide "io.IOBase" class to support user streams #ifndef MICROPY_PY_IO_IOBASE -#define MICROPY_PY_IO_IOBASE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#define MICROPY_PY_IO_IOBASE (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif // Whether to provide "io.BytesIO" class @@ -1473,15 +1748,16 @@ typedef double mp_float_t; #define MICROPY_PY_STRUCT (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) #endif -// CIRCUITPY-CHANGE -// Whether to provide non-standard typecodes in "struct" module -#ifndef MICROPY_NONSTANDARD_TYPECODES -#define MICROPY_NONSTANDARD_TYPECODES (1) +// Whether struct module provides unsafe and non-standard typecodes O, P, S. +// These typecodes are not in CPython and can cause crashes by accessing arbitrary +// memory. +#ifndef MICROPY_PY_STRUCT_UNSAFE_TYPECODES +#define MICROPY_PY_STRUCT_UNSAFE_TYPECODES (1) #endif // Whether to provide "sys" module #ifndef MICROPY_PY_SYS -#define MICROPY_PY_SYS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) +#define MICROPY_PY_SYS (1) #endif // Whether to initialise "sys.path" and "sys.argv" to their defaults in mp_init() @@ -1650,12 +1926,21 @@ typedef double mp_float_t; #define MICROPY_PY_THREAD_GIL_VM_DIVISOR (32) #endif +// Is a recursive mutex type in use? +#ifndef MICROPY_PY_THREAD_RECURSIVE_MUTEX +#define MICROPY_PY_THREAD_RECURSIVE_MUTEX (MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL) +#endif + // Extended modules #ifndef MICROPY_PY_ASYNCIO #define MICROPY_PY_ASYNCIO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif +#ifndef MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK +#define MICROPY_PY_ASYNCIO_TASK_QUEUE_PUSH_CALLBACK (0) +#endif + #ifndef MICROPY_PY_UCTYPES #define MICROPY_PY_UCTYPES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif @@ -1728,11 +2013,11 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_HASHLIB_MD5 -#define MICROPY_PY_HASHLIB_MD5 (0) +#define MICROPY_PY_HASHLIB_MD5 (MICROPY_PY_SSL) #endif #ifndef MICROPY_PY_HASHLIB_SHA1 -#define MICROPY_PY_HASHLIB_SHA1 (0) +#define MICROPY_PY_HASHLIB_SHA1 (MICROPY_PY_SSL) #endif #ifndef MICROPY_PY_HASHLIB_SHA256 @@ -1740,7 +2025,7 @@ typedef double mp_float_t; #endif #ifndef MICROPY_PY_CRYPTOLIB -#define MICROPY_PY_CRYPTOLIB (0) +#define MICROPY_PY_CRYPTOLIB (MICROPY_PY_SSL) #endif // Depends on MICROPY_PY_CRYPTOLIB @@ -1757,6 +2042,7 @@ typedef double mp_float_t; #endif // CIRCUITPY-CHANGE: does not depend on MICROPY_PY_DEFLATE +// Depends on MICROPY_PY_DEFLATE #ifndef MICROPY_PY_BINASCII_CRC32 #define MICROPY_PY_BINASCII_CRC32 (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif @@ -1779,6 +2065,11 @@ typedef double mp_float_t; #define MICROPY_PY_MACHINE_RESET (0) #endif +// Maximum number of arguments for machine.freq() +#ifndef MICROPY_PY_MACHINE_FREQ_NUM_ARGS_MAX +#define MICROPY_PY_MACHINE_FREQ_NUM_ARGS_MAX (1) +#endif + // Whether to include: bitstream #ifndef MICROPY_PY_MACHINE_BITSTREAM #define MICROPY_PY_MACHINE_BITSTREAM (0) @@ -1822,6 +2113,12 @@ typedef double mp_float_t; #define MICROPY_PY_MACHINE_SOFTSPI (0) #endif +// Values of SPI.MSB and SPI.LSB constants +#ifndef MICROPY_PY_MACHINE_SPI_MSB +#define MICROPY_PY_MACHINE_SPI_MSB (0) +#define MICROPY_PY_MACHINE_SPI_LSB (1) +#endif + // Whether to provide the "machine.Timer" class #ifndef MICROPY_PY_MACHINE_TIMER #define MICROPY_PY_MACHINE_TIMER (0) @@ -1836,11 +2133,26 @@ typedef double mp_float_t; #define MICROPY_PY_SSL (0) #endif +// CIRCUITPY-CHANGE: avoid undefined warnings +#ifndef MICROPY_PY_SSL_ECDSA_SIGN_ALT +#define MICROPY_PY_SSL_ECDSA_SIGN_ALT (0) +#endif + // Whether to add finaliser code to ssl objects #ifndef MICROPY_PY_SSL_FINALISER #define MICROPY_PY_SSL_FINALISER (MICROPY_ENABLE_FINALISER) #endif +// Whether to add a root pointer for the current ssl object +#ifndef MICROPY_PY_SSL_MBEDTLS_NEED_ACTIVE_CONTEXT +#define MICROPY_PY_SSL_MBEDTLS_NEED_ACTIVE_CONTEXT (MICROPY_PY_SSL_ECDSA_SIGN_ALT) +#endif + +// Whether to support DTLS protocol (non-CPython feature) +#ifndef MICROPY_PY_SSL_DTLS +#define MICROPY_PY_SSL_DTLS (MICROPY_SSL_MBEDTLS && MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether to provide the "vfs" module #ifndef MICROPY_PY_VFS #define MICROPY_PY_VFS (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES && MICROPY_VFS) @@ -1933,7 +2245,7 @@ typedef double mp_float_t; /*****************************************************************************/ /* Miscellaneous settings */ -// All uPy objects in ROM must be aligned on at least a 4 byte boundary +// All MicroPython objects in ROM must be aligned on at least a 4 byte boundary // so that the small-int/qstr/pointer distinction can be made. For machines // that don't do this (eg 16-bit CPU), define the following macro to something // like __attribute__((aligned(4))). @@ -2008,14 +2320,48 @@ typedef double mp_float_t; #define MICROPY_MAKE_POINTER_CALLABLE(p) (p) #endif -// If these MP_PLAT_*_EXEC macros are overridden then the memory allocated by them -// must be somehow reachable for marking by the GC, since the native code -// generators store pointers to GC managed memory in the code. +// Whether native text/BSS/rodata memory loaded from .mpy files is explicitly tracked +// so that the GC cannot reclaim it. +// +// In general a port should let these options have their defaults, but the defaults here +// can be overridden if needed by defining both MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA +// and MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA. +#ifndef MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA +#if MICROPY_EMIT_MACHINE_CODE && MICROPY_PERSISTENT_CODE_LOAD +// Pointer tracking is required when loading native code is enabled. +#if defined(MP_PLAT_ALLOC_EXEC) || defined(MP_PLAT_COMMIT_EXEC) +// If a port defined a custom allocator or commit function for native text, then the +// text does not need to be tracked (its allocation is managed by the port). But the +// BSS/rodata must be tracked (if there is any) because if there are any pointers to it +// in the function data, they aren't traced by the GC. +#define MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA (0) +#define MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA (1) +#else +// If a port uses the default allocator (the GC heap) then all native text is allocated +// on the GC heap. But it's not guaranteed that a pointer to the head of the block of +// native text (which may contain multiple native functions) will be retained for the GC +// to trace. This is because native functions can start inside the big block of text +// and so it's possible that the only GC-reachable pointers are pointers inside. +// Therefore the big block is explicitly tracked. If there is any BSS/rodata memory, +// then it does not need to be explicitly tracked because a pointer to it is stored into +// the function text via `mp_native_relocate()`. +#define MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA (1) +#define MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA (0) +#endif +#else // MICROPY_EMIT_MACHINE_CODE && MICROPY_PERSISTENT_CODE_LOAD +// Pointer tracking not needed when loading native code is disabled. +#define MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA (0) +#define MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA (0) +#endif +#endif + +// If these macros are defined then the memory allocated by them does not need to be +// traced by the GC. But if they are left undefined then the GC heap will be used as +// the allocator and the memory must be traced by the GC. See also above logic for +// enabling MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA and +// MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA. #ifndef MP_PLAT_ALLOC_EXEC #define MP_PLAT_ALLOC_EXEC(min_size, ptr, size) do { *ptr = m_new(byte, min_size); *size = min_size; } while (0) -#endif - -#ifndef MP_PLAT_FREE_EXEC #define MP_PLAT_FREE_EXEC(ptr, size) m_del(byte, ptr, size) #endif @@ -2038,25 +2384,13 @@ typedef double mp_float_t; #define MP_SSIZE_MAX SSIZE_MAX #endif -// printf format spec to use for mp_int_t and friends -#ifndef INT_FMT -#if defined(__LP64__) -// Archs where mp_int_t == long, long != int -#define UINT_FMT "%lu" -#define INT_FMT "%ld" -#elif defined(_WIN64) -#define UINT_FMT "%llu" -#define INT_FMT "%lld" -#else -// Archs where mp_int_t == int -#define UINT_FMT "%u" -#define INT_FMT "%d" +// Modifier for function which doesn't return +#ifndef MP_NORETURN +#define MP_NORETURN __attribute__((noreturn)) #endif -#endif // INT_FMT -// Modifier for function which doesn't return -#ifndef NORETURN -#define NORETURN __attribute__((noreturn)) +#if !MICROPY_PREVIEW_VERSION_2 +#define NORETURN MP_NORETURN #endif // Modifier for weak functions @@ -2077,6 +2411,12 @@ typedef double mp_float_t; #define MP_INLINE inline MP_NO_INSTRUMENT #endif +// CIRCUITPY-CHANGE +// Modifier for functions whose return value should not be ignored +#ifndef MP_WARN_UNUSED_RESULT +#define MP_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) +#endif + // Modifier for functions which should be never inlined #ifndef MP_NOINLINE #define MP_NOINLINE __attribute__((noinline)) @@ -2151,4 +2491,23 @@ typedef double mp_float_t; #define MP_WARN_CAT(x) (NULL) #endif +// If true, use __builtin_mul_overflow (a gcc intrinsic supported by clang) for +// overflow checking when multiplying two small ints. Otherwise, use a portable +// algorithm. +// +// Most MCUs have a 32x32->64 bit multiply instruction, in which case the +// intrinsic is likely to be faster and generate smaller code. The main exception is +// cortex-m0 with __ARM_ARCH_ISA_THUMB == 1. +// +// The intrinsic is in GCC starting with version 5. +#ifndef MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC +#if defined(__ARM_ARCH_ISA_THUMB) && (__GNUC__ >= 5) +#define MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC (__ARM_ARCH_ISA_THUMB >= 2) +#elif (__GNUC__ >= 5) +#define MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC (1) +#else +#define MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC (0) +#endif +#endif + #endif // MICROPY_INCLUDED_PY_MPCONFIG_H diff --git a/py/mperrno.h b/py/mperrno.h index 9e4ecd9419c..6c675125f4e 100644 --- a/py/mperrno.h +++ b/py/mperrno.h @@ -143,6 +143,9 @@ #endif +// Type for return values where 0 indicates success and negative values are negated MP_E* error codes. +typedef int mp_negative_errno_t; + #if MICROPY_PY_ERRNO #include "py/obj.h" diff --git a/py/mphal.h b/py/mphal.h index a4f222d0b1e..3907641be83 100644 --- a/py/mphal.h +++ b/py/mphal.h @@ -27,6 +27,7 @@ #define MICROPY_INCLUDED_PY_MPHAL_H #include +#include #include "py/mpconfig.h" #ifdef MICROPY_MPHALPORT_H @@ -88,6 +89,8 @@ mp_uint_t mp_hal_ticks_cpu(void); uint64_t mp_hal_time_ns(void); #endif +// CIRCUITPY-CHANGE: extmod/virtpin.* not used by CircuitPython +#if 0 // If port HAL didn't define its own pin API, use generic // "virtual pin" API from the core. #ifndef mp_hal_pin_obj_t @@ -97,6 +100,7 @@ uint64_t mp_hal_time_ns(void); #define mp_hal_pin_write(pin, v) mp_virtual_pin_write(pin, v) #include "extmod/virtpin.h" #endif +#endif // Event handling and wait-for-event functions. diff --git a/py/mpprint.c b/py/mpprint.c index e4e25f5a82e..62e80d1e8e8 100644 --- a/py/mpprint.c +++ b/py/mpprint.c @@ -40,8 +40,20 @@ #include "py/formatfloat.h" #endif -static const char pad_spaces[] = " "; -static const char pad_zeroes[] = "0000000000000000"; +static const char pad_spaces[16] = {' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; +#define pad_spaces_size (sizeof(pad_spaces)) +static const char pad_common[23] = {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '_', '0', '0', '0', ',', '0', '0'}; +// The contents of pad_common is arranged to provide the following padding +// strings with minimal flash size: +// 0000000000000000 <- pad_zeroes +// 0000_000 <- pad_zeroes_underscore (offset: 12, size 5) +// 000,00 <- pad_zeroes_comma (offset: 17, size 4) +#define pad_zeroes (pad_common + 0) +#define pad_zeroes_size (16) +#define pad_zeroes_underscore (pad_common + 12) +#define pad_zeroes_underscore_size (5) +#define pad_zeroes_comma (pad_common + 17) +#define pad_zeroes_comma_size (4) static void plat_print_strn(void *env, const char *str, size_t len) { (void)env; @@ -58,20 +70,37 @@ int mp_print_str(const mp_print_t *print, const char *str) { return len; } -int mp_print_strn(const mp_print_t *print, const char *str, size_t len, int flags, char fill, int width) { +int mp_print_strn(const mp_print_t *print, const char *str, size_t len, unsigned int flags, char fill, int width) { int left_pad = 0; int right_pad = 0; int pad = width - len; int pad_size; int total_chars_printed = 0; const char *pad_chars; + char grouping = flags >> PF_FLAG_SEP_POS; if (!fill || fill == ' ') { pad_chars = pad_spaces; - pad_size = sizeof(pad_spaces) - 1; - } else if (fill == '0') { + pad_size = pad_spaces_size; + } else if (fill == '0' && !grouping) { pad_chars = pad_zeroes; - pad_size = sizeof(pad_zeroes) - 1; + pad_size = pad_zeroes_size; + } else if (fill == '0') { + if (grouping == '_') { + pad_chars = pad_zeroes_underscore; + pad_size = pad_zeroes_underscore_size; + } else { + pad_chars = pad_zeroes_comma; + pad_size = pad_zeroes_comma_size; + } + // The result will never start with a grouping character. An extra leading zero is added. + // width is dead after this so we can use it in calculation + if (width % pad_size == 0) { + pad++; + width++; + } + // position the grouping character correctly within the pad repetition + pad_chars += pad_size - 1 - width % pad_size; } else { // Other pad characters are fairly unusual, so we'll take the hit // and output them 1 at a time. @@ -201,7 +230,7 @@ static int mp_print_int(const mp_print_t *print, mp_uint_t x, int sgn, int base, return len; } -int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec) { +int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, unsigned int base, int base_char, int flags, char fill, int width, int prec) { // These are the only values for "base" that are required to be supported by this // function, since Python only allows the user to format integers in these bases. // If needed this function could be generalised to handle other values. @@ -248,10 +277,7 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char int prefix_len = prefix - prefix_buf; prefix = prefix_buf; - char comma = '\0'; - if (flags & PF_FLAG_SHOW_COMMA) { - comma = ','; - } + char comma = flags >> PF_FLAG_SEP_POS; // The size of this buffer is rather arbitrary. If it's not large // enough, a dynamic one will be allocated. @@ -340,8 +366,8 @@ int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char } #if MICROPY_PY_BUILTINS_FLOAT -int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, int flags, char fill, int width, int prec) { - char buf[32]; +int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, unsigned int flags, char fill, int width, int prec) { + char buf[36]; char sign = '\0'; int chrs = 0; @@ -352,11 +378,17 @@ int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, int flags, c sign = ' '; } - int len = mp_format_float(f, buf, sizeof(buf), fmt, prec, sign); + int len = mp_format_float(f, buf, sizeof(buf) - 3, fmt, prec, sign); char *s = buf; - if ((flags & PF_FLAG_ADD_PERCENT) && (size_t)(len + 1) < sizeof(buf)) { + if ((flags & PF_FLAG_ALWAYS_DECIMAL) && strchr(buf, '.') == NULL && strchr(buf, 'e') == NULL && strchr(buf, 'n') == NULL) { + buf[len++] = '.'; + buf[len++] = '0'; + buf[len] = '\0'; + } + + if (flags & PF_FLAG_ADD_PERCENT) { buf[len++] = '%'; buf[len] = '\0'; } @@ -376,14 +408,6 @@ int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, int flags, c } #endif -// CIRCUITPY-CHANGE -static int print_str_common(const mp_print_t *print, const char *str, int prec, size_t len, int flags, int fill, int width) { - if (prec >= 0 && (size_t)prec < len) { - len = prec; - } - return mp_print_strn(print, str, len, flags, fill, width); -} - int mp_printf(const mp_print_t *print, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -424,8 +448,6 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { flags |= PF_FLAG_SHOW_SIGN; } else if (*fmt == ' ') { flags |= PF_FLAG_SPACE_SIGN; - } else if (*fmt == '!') { - flags |= PF_FLAG_NO_TRAILZ; } else if (*fmt == '0') { flags |= PF_FLAG_PAD_AFTER_SIGN; fill = '0'; @@ -459,16 +481,36 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { } } - // parse long specifiers (only for LP64 model where they make a difference) - #ifndef __LP64__ - const + // parse long and long long specifiers (only where they make a difference) + #if (MP_INT_MAX > INT_MAX && MP_INT_MAX == LONG_MAX) || defined(MICROPY_UNIX_COVERAGE) + #define SUPPORT_L_FORMAT (1) + #else + #define SUPPORT_L_FORMAT (0) #endif + #if SUPPORT_L_FORMAT bool long_arg = false; + #endif + + #if (MP_INT_MAX > LONG_MAX) || defined(MICROPY_UNIX_COVERAGE) + #define SUPPORT_LL_FORMAT (1) + #else + #define SUPPORT_LL_FORMAT (0) + #endif + #if SUPPORT_LL_FORMAT + bool long_long_arg = false; + #endif + if (*fmt == 'l') { ++fmt; - #ifdef __LP64__ + #if SUPPORT_L_FORMAT long_arg = true; #endif + #if SUPPORT_LL_FORMAT + if (*fmt == 'l') { + ++fmt; + long_long_arg = true; + } + #endif } if (*fmt == '\0') { @@ -492,27 +534,19 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { qstr qst = va_arg(args, qstr); size_t len; const char *str = (const char *)qstr_data(qst, &len); - // CIRCUITPY-CHANGE - chrs += print_str_common(print, str, prec, len, flags, fill, width); - break; - } - // CIRCUITPY-CHANGE: new code to print compressed strings - case 'S': { - mp_rom_error_text_t arg = va_arg(args, mp_rom_error_text_t); - size_t len_with_nul = decompress_length(arg); - size_t len = len_with_nul - 1; - char str[len_with_nul]; - decompress(arg, str); - chrs += print_str_common(print, str, prec, len, flags, fill, width); + if (prec >= 0 && (size_t)prec < len) { + len = prec; + } + chrs += mp_print_strn(print, str, len, flags, fill, width); break; } case 's': { const char *str = va_arg(args, const char *); #ifndef NDEBUG // With debugging enabled, catch printing of null string pointers - if (str == NULL) { - // CIRCUITPY-CHANGE - str = "(null)"; + if (prec != 0 && str == NULL) { + chrs += mp_print_strn(print, "(null)", 6, flags, fill, width); + break; } #endif size_t len = strlen(str); @@ -522,41 +556,58 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { chrs += mp_print_strn(print, str, len, flags, fill, width); break; } - case 'd': { - mp_int_t val; - if (long_arg) { - val = va_arg(args, long int); - } else { - val = va_arg(args, int); - } - chrs += mp_print_int(print, val, 1, 10, 'a', flags, fill, width); - break; - } + case 'd': + case 'p': + case 'P': case 'u': case 'x': case 'X': { - int base = 16 - ((*fmt + 1) & 6); // maps char u/x/X to base 10/16/16 - char fmt_c = (*fmt & 0xf0) - 'P' + 'A'; // maps char u/x/X to char a/a/A + char fmt_chr = *fmt; mp_uint_t val; - if (long_arg) { - val = va_arg(args, unsigned long int); + if (fmt_chr == 'p' || fmt_chr == 'P') { + val = va_arg(args, uintptr_t); + } + #if SUPPORT_LL_FORMAT + else if (long_long_arg) { + val = va_arg(args, unsigned long long); + } + #endif + #if SUPPORT_L_FORMAT + else if (long_arg) { + if (sizeof(long) != sizeof(mp_uint_t) && fmt_chr == 'd') { + val = va_arg(args, long); + } else { + val = va_arg(args, unsigned long); + } + } + #endif + else { + if (sizeof(int) != sizeof(mp_uint_t) && fmt_chr == 'd') { + val = va_arg(args, int); + } else { + val = va_arg(args, unsigned); + } + } + int base; + // Map format char x/p/X/P to a/a/A/A for hex letters. + // It doesn't matter what d/u map to. + char fmt_c = (fmt_chr & 0xf0) - 'P' + 'A'; + if (fmt_chr == 'd' || fmt_chr == 'u') { + base = 10; } else { - val = va_arg(args, unsigned int); + base = 16; + } + // CIRCUITPY-CHANGE: include "0x" for 'p' and 'P'. + if (fmt_chr == 'p' || fmt_chr == 'P') { + #if SUPPORT_INT_BASE_PREFIX + chrs += mp_print_int(print, va_arg(args, unsigned long int), 0, 16, 'a', flags | PF_FLAG_SHOW_PREFIX, fill, width); + #else + chrs += mp_print_strn(print, "0x", 2, flags, fill, width); + #endif } - chrs += mp_print_int(print, val, 0, base, fmt_c, flags, fill, width); + chrs += mp_print_int(print, val, fmt_chr == 'd', base, fmt_c, flags, fill, width); break; } - case 'p': - case 'P': // don't bother to handle upcase for 'P' - // Use unsigned long int to work on both ILP32 and LP64 systems - // CIRCUITPY-CHANGE: print 0x prefix - #if SUPPORT_INT_BASE_PREFIX - chrs += mp_print_int(print, va_arg(args, unsigned long int), 0, 16, 'a', flags | PF_FLAG_SHOW_PREFIX, fill, width); - #else - print->print_strn(print->data, "0x", 2); - chrs += mp_print_int(print, va_arg(args, unsigned long int), 0, 16, 'a', flags, fill, width) + 2; - #endif - break; #if MICROPY_PY_BUILTINS_FLOAT case 'e': case 'E': @@ -573,18 +624,21 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { break; } #endif - // Because 'l' is eaten above, another 'l' means %ll. We need to support - // this length specifier for OBJ_REPR_D (64-bit NaN boxing). - // TODO Either enable this unconditionally, or provide a specific config var. - #if (MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D) || defined(_WIN64) - case 'l': { - unsigned long long int arg_value = va_arg(args, unsigned long long int); - ++fmt; - assert(*fmt == 'u' || *fmt == 'd' || !"unsupported fmt char"); - chrs += mp_print_int(print, arg_value, *fmt == 'd', 10, 'a', flags, fill, width); + + // CIRCUITPY-CHANGE: new format code to print compressed strings + case 'S': { + mp_rom_error_text_t arg = va_arg(args, mp_rom_error_text_t); + size_t len_with_nul = decompress_length(arg); + size_t len = len_with_nul - 1; + char str[len_with_nul]; + decompress(arg, str); + if (prec >= 0 && (size_t)prec < len) { + len = prec; + } + chrs += mp_print_strn(print, str, len, flags, fill, width); break; } - #endif + default: // if it's not %% then it's an unsupported format character assert(*fmt == '%' || !"unsupported fmt char"); diff --git a/py/mpprint.h b/py/mpprint.h index e883cc27047..614c61ea415 100644 --- a/py/mpprint.h +++ b/py/mpprint.h @@ -31,13 +31,13 @@ #define PF_FLAG_LEFT_ADJUST (0x001) #define PF_FLAG_SHOW_SIGN (0x002) #define PF_FLAG_SPACE_SIGN (0x004) -#define PF_FLAG_NO_TRAILZ (0x008) -#define PF_FLAG_SHOW_PREFIX (0x010) -#define PF_FLAG_SHOW_COMMA (0x020) -#define PF_FLAG_PAD_AFTER_SIGN (0x040) -#define PF_FLAG_CENTER_ADJUST (0x080) -#define PF_FLAG_ADD_PERCENT (0x100) -#define PF_FLAG_SHOW_OCTAL_LETTER (0x200) +#define PF_FLAG_SHOW_PREFIX (0x008) +#define PF_FLAG_PAD_AFTER_SIGN (0x010) +#define PF_FLAG_CENTER_ADJUST (0x020) +#define PF_FLAG_ADD_PERCENT (0x040) +#define PF_FLAG_SHOW_OCTAL_LETTER (0x080) +#define PF_FLAG_ALWAYS_DECIMAL (0x100) +#define PF_FLAG_SEP_POS (9) // must be above all the above PF_FLAGs #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES #define MP_PYTHON_PRINTER &mp_sys_stdout_print @@ -69,9 +69,9 @@ extern const mp_print_t mp_sys_stdout_print; #endif int mp_print_str(const mp_print_t *print, const char *str); -int mp_print_strn(const mp_print_t *print, const char *str, size_t len, int flags, char fill, int width); +int mp_print_strn(const mp_print_t *print, const char *str, size_t len, unsigned int flags, char fill, int width); #if MICROPY_PY_BUILTINS_FLOAT -int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, int flags, char fill, int width, int prec); +int mp_print_float(const mp_print_t *print, mp_float_t f, char fmt, unsigned int flags, char fill, int width, int prec); #endif int mp_printf(const mp_print_t *print, const char *fmt, ...); diff --git a/py/mpstate.h b/py/mpstate.h index 7308e57b581..7934e843f06 100644 --- a/py/mpstate.h +++ b/py/mpstate.h @@ -71,6 +71,12 @@ enum { // This structure contains dynamic configuration for the compiler. #if MICROPY_DYNAMIC_COMPILER typedef struct mp_dynamic_compiler_t { + // This is used to let mpy-cross pass options to the emitter chosen with + // `native_arch`. The main use case for the time being is to give the + // RV32 emitter extended information about which extensions can be + // optionally used, in order to generate code that's better suited for the + // hardware platform the code will run on. + void *backend_options; uint8_t small_int_bits; // must be <= host small_int_bits uint8_t native_arch; uint8_t nlr_buf_num_regs; @@ -88,6 +94,18 @@ typedef struct _mp_sched_item_t { mp_obj_t arg; } mp_sched_item_t; +// gc_lock_depth field is a combination of the GC_COLLECT_FLAG +// bit and a lock depth shifted GC_LOCK_DEPTH_SHIFT bits left. +#if MICROPY_ENABLE_FINALISER +#define GC_COLLECT_FLAG 1 +#define GC_LOCK_DEPTH_SHIFT 1 +#else +// If finalisers are disabled then this check doesn't matter, as gc_lock() +// is called anywhere else that heap can't be changed. So save some code size. +#define GC_COLLECT_FLAG 0 +#define GC_LOCK_DEPTH_SHIFT 0 +#endif + // This structure holds information about a single contiguous area of // memory reserved for the memory manager. typedef struct _mp_state_mem_area_t { @@ -100,6 +118,10 @@ typedef struct _mp_state_mem_area_t { #if MICROPY_ENABLE_FINALISER byte *gc_finaliser_table_start; #endif + // CIRCUITPY-CHANGE + #if MICROPY_ENABLE_SELECTIVE_COLLECT + byte *gc_collect_table_start; + #endif byte *gc_pool_start; byte *gc_pool_end; @@ -144,7 +166,7 @@ typedef struct _mp_state_mem_t { #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL // This is a global mutex used to make the GC thread-safe. - mp_thread_mutex_t gc_mutex; + mp_thread_recursive_mutex_t gc_mutex; #endif } mp_state_mem_t; @@ -292,6 +314,7 @@ typedef struct _mp_state_thread_t { #endif // Locking of the GC is done per thread. + // See GC_LOCK_DEPTH_SHIFT for an explanation of this field. uint16_t gc_lock_depth; //////////////////////////////////////////////////////////// @@ -318,6 +341,10 @@ typedef struct _mp_state_thread_t { struct _mp_code_state_t *current_code_state; #endif + #if MICROPY_PY_SSL_MBEDTLS_NEED_ACTIVE_CONTEXT + struct _mp_obj_ssl_context_t *tls_ssl_context; + #endif + // CIRCUITPY-CHANGE #if CIRCUITPY_WARNINGS warnings_action_t warnings_action; @@ -348,4 +375,7 @@ extern mp_state_thread_t *mp_thread_get_state(void); #define mp_thread_is_main_thread() (true) #endif +// CIRCUITPY-CHANGE: defined in main.c +bool vm_is_running(void); + #endif // MICROPY_INCLUDED_PY_MPSTATE_H diff --git a/py/mpthread.h b/py/mpthread.h index f335cc02911..795f230bb4a 100644 --- a/py/mpthread.h +++ b/py/mpthread.h @@ -48,6 +48,12 @@ void mp_thread_mutex_init(mp_thread_mutex_t *mutex); int mp_thread_mutex_lock(mp_thread_mutex_t *mutex, int wait); void mp_thread_mutex_unlock(mp_thread_mutex_t *mutex); +#if MICROPY_PY_THREAD_RECURSIVE_MUTEX +void mp_thread_recursive_mutex_init(mp_thread_recursive_mutex_t *mutex); +int mp_thread_recursive_mutex_lock(mp_thread_recursive_mutex_t *mutex, int wait); +void mp_thread_recursive_mutex_unlock(mp_thread_recursive_mutex_t *mutex); +#endif + #endif // MICROPY_PY_THREAD #if MICROPY_PY_THREAD && MICROPY_PY_THREAD_GIL diff --git a/py/mpz.c b/py/mpz.c index 746c9fe5b69..74fd1754636 100644 --- a/py/mpz.c +++ b/py/mpz.c @@ -1541,7 +1541,8 @@ mp_int_t mpz_hash(const mpz_t *z) { mp_uint_t val = 0; mpz_dig_t *d = z->dig + z->len; - while (d-- > z->dig) { + while (d > z->dig) { + d--; val = (val << DIG_SIZE) | *d; } @@ -1556,11 +1557,12 @@ bool mpz_as_int_checked(const mpz_t *i, mp_int_t *value) { mp_uint_t val = 0; mpz_dig_t *d = i->dig + i->len; - while (d-- > i->dig) { + while (d > i->dig) { if (val > (~(MP_OBJ_WORD_MSBIT_HIGH) >> DIG_SIZE)) { // will overflow return false; } + d--; val = (val << DIG_SIZE) | *d; } @@ -1581,11 +1583,12 @@ bool mpz_as_uint_checked(const mpz_t *i, mp_uint_t *value) { mp_uint_t val = 0; mpz_dig_t *d = i->dig + i->len; - while (d-- > i->dig) { + while (d > i->dig) { if (val > (~(MP_OBJ_WORD_MSBIT_HIGH) >> (DIG_SIZE - 1))) { // will overflow return false; } + d--; val = (val << DIG_SIZE) | *d; } @@ -1593,7 +1596,7 @@ bool mpz_as_uint_checked(const mpz_t *i, mp_uint_t *value) { return true; } -void mpz_as_bytes(const mpz_t *z, bool big_endian, size_t len, byte *buf) { +bool mpz_as_bytes(const mpz_t *z, bool big_endian, bool as_signed, size_t len, byte *buf) { byte *b = buf; if (big_endian) { b += len; @@ -1602,6 +1605,8 @@ void mpz_as_bytes(const mpz_t *z, bool big_endian, size_t len, byte *buf) { int bits = 0; mpz_dbl_dig_t d = 0; mpz_dbl_dig_t carry = 1; + size_t olen = len; // bytes in output buffer + bool ok = true; for (size_t zlen = z->len; zlen > 0; --zlen) { bits += DIG_SIZE; d = (d << DIG_SIZE) | *zdig++; @@ -1611,28 +1616,32 @@ void mpz_as_bytes(const mpz_t *z, bool big_endian, size_t len, byte *buf) { val = (~val & 0xff) + carry; carry = val >> 8; } + + if (!olen) { + // Buffer is full, only OK if all remaining bytes are zeroes + ok = ok && ((byte)val == 0); + continue; + } + if (big_endian) { *--b = val; - if (b == buf) { - return; - } } else { *b++ = val; - if (b == buf + len) { - return; - } } + olen--; } } - // fill remainder of buf with zero/sign extension of the integer - if (big_endian) { - len = b - buf; + if (as_signed && olen == 0 && len > 0) { + // If output exhausted then ensure there was enough space for the sign bit + byte most_sig = big_endian ? buf[0] : buf[len - 1]; + ok = ok && (bool)(most_sig & 0x80) == (bool)z->neg; } else { - len = buf + len - b; - buf = b; + // fill remainder of buf with zero/sign extension of the integer + memset(big_endian ? buf : b, z->neg ? 0xff : 0x00, olen); } - memset(buf, z->neg ? 0xff : 0x00, len); + + return ok; } #if MICROPY_PY_BUILTINS_FLOAT @@ -1640,7 +1649,8 @@ mp_float_t mpz_as_float(const mpz_t *i) { mp_float_t val = 0; mpz_dig_t *d = i->dig + i->len; - while (d-- > i->dig) { + while (d > i->dig) { + d--; val = val * DIG_BASE + *d; } @@ -1670,6 +1680,8 @@ size_t mpz_as_str_inpl(const mpz_t *i, unsigned int base, const char *prefix, ch size_t ilen = i->len; + int n_comma = (base == 10) ? 3 : 4; + char *s = str; if (ilen == 0) { if (prefix) { @@ -1715,7 +1727,7 @@ size_t mpz_as_str_inpl(const mpz_t *i, unsigned int base, const char *prefix, ch break; } } - if (comma && (s - last_comma) == 3) { + if (!done && comma && (s - last_comma) == n_comma) { *s++ = comma; last_comma = s; } diff --git a/py/mpz.h b/py/mpz.h index f205e3cd158..0422b014a33 100644 --- a/py/mpz.h +++ b/py/mpz.h @@ -93,9 +93,9 @@ typedef int8_t mpz_dbl_dig_signed_t; typedef struct _mpz_t { // Zero has neg=0, len=0. Negative zero is not allowed. size_t neg : 1; - size_t fixed_dig : 1; - size_t alloc : (8 * sizeof(size_t) - 2); - size_t len; + size_t fixed_dig : 1; // flag, 'dig' buffer cannot be reallocated + size_t alloc : (8 * sizeof(size_t) - 2); // number of entries allocated in 'dig' + size_t len; // number of entries used in 'dig' mpz_dig_t *dig; } mpz_t; @@ -153,7 +153,8 @@ static inline size_t mpz_num_bits(const mpz_t *z) { mp_int_t mpz_hash(const mpz_t *z); bool mpz_as_int_checked(const mpz_t *z, mp_int_t *value); bool mpz_as_uint_checked(const mpz_t *z, mp_uint_t *value); -void mpz_as_bytes(const mpz_t *z, bool big_endian, size_t len, byte *buf); +// Returns true if 'z' fit into 'len' bytes of 'buf' without overflowing, 'buf' is truncated otherwise. +bool mpz_as_bytes(const mpz_t *z, bool big_endian, bool as_signed, size_t len, byte *buf); #if MICROPY_PY_BUILTINS_FLOAT mp_float_t mpz_as_float(const mpz_t *z); #endif diff --git a/py/nativeglue.h b/py/nativeglue.h index 00ed9f3f4fc..01825ac60ed 100644 --- a/py/nativeglue.h +++ b/py/nativeglue.h @@ -143,7 +143,7 @@ typedef struct _mp_fun_table_t { int (*printf_)(const mp_print_t *print, const char *fmt, ...); int (*vprintf_)(const mp_print_t *print, const char *fmt, va_list args); #if defined(__GNUC__) - NORETURN // Only certain compilers support no-return attributes in function pointer declarations + MP_NORETURN // Only certain compilers support no-return attributes in function pointer declarations #endif // CIRCUITPY-CHANGE: raise_msg_str instead of raise_msg void (*raise_msg_str)(const mp_obj_type_t *exc_type, const char *msg); diff --git a/py/nlr.c b/py/nlr.c index 516b8b86276..de2a38ceff3 100644 --- a/py/nlr.c +++ b/py/nlr.c @@ -28,8 +28,7 @@ #if !MICROPY_NLR_SETJMP // When not using setjmp, nlr_push_tail is called from inline asm so needs special care -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_X86) && MICROPY_NLR_X86 && defined(MICROPY_NLR_OS_WINDOWS) && MICROPY_NLR_OS_WINDOWS +#if MICROPY_NLR_X86 && MICROPY_NLR_OS_WINDOWS // On these 32-bit platforms make sure nlr_push_tail doesn't have a leading underscore unsigned int nlr_push_tail(nlr_buf_t *nlr) asm ("nlr_push_tail"); #else @@ -82,7 +81,7 @@ void nlr_call_jump_callbacks(nlr_buf_t *nlr) { } #if MICROPY_ENABLE_VM_ABORT -NORETURN void nlr_jump_abort(void) { +MP_NORETURN void nlr_jump_abort(void) { MP_STATE_THREAD(nlr_top) = MP_STATE_VM(nlr_abort); nlr_jump(NULL); } diff --git a/py/nlr.h b/py/nlr.h index 15f883422f5..446e78c7ebb 100644 --- a/py/nlr.h +++ b/py/nlr.h @@ -44,6 +44,8 @@ #define MICROPY_NLR_NUM_REGS_MIPS (13) #define MICROPY_NLR_NUM_REGS_XTENSA (10) #define MICROPY_NLR_NUM_REGS_XTENSAWIN (17) +#define MICROPY_NLR_NUM_REGS_RV32I (14) +#define MICROPY_NLR_NUM_REGS_RV64I (14) // *FORMAT-OFF* @@ -99,16 +101,65 @@ #elif defined(__mips__) #define MICROPY_NLR_MIPS (1) #define MICROPY_NLR_NUM_REGS (MICROPY_NLR_NUM_REGS_MIPS) +#elif defined(__riscv) + #if __riscv_xlen == 32 + #define MICROPY_NLR_NUM_REGS (MICROPY_NLR_NUM_REGS_RV32I) + #define MICROPY_NLR_RV32I (1) + #elif __riscv_xlen == 64 + #define MICROPY_NLR_NUM_REGS (MICROPY_NLR_NUM_REGS_RV64I) + #define MICROPY_NLR_RV64I (1) + #else + #error Unsupported RISC-V variant. + #endif #else #define MICROPY_NLR_SETJMP (1) //#warning "No native NLR support for this arch, using setjmp implementation" #endif #endif -// CIRCUITPY-CHANGE -// If MICROPY_NLR_SETJMP is not defined above - define/disable it here -#if !defined(MICROPY_NLR_SETJMP) - #define MICROPY_NLR_SETJMP (0) +// CIRCUITPY-CHANGE: Avoid warnings by defining all these MICROPY_PY_NLR_* macros +#ifndef MICROPY_NLR_AARCH64 +#define MICROPY_NLR_AARCH64 (0) +#endif + +#ifndef MICROPY_NLR_MIPS +#define MICROPY_NLR_MIPS (0) +#endif + +#ifndef MICROPY_NLR_OS_WINDOWS +#define MICROPY_NLR_OS_WINDOWS (0) +#endif + +#ifndef MICROPY_NLR_POWERPC +#define MICROPY_NLR_POWERPC (0) +#endif + +#ifndef MICROPY_NLR_RV32I +#define MICROPY_NLR_RV32I (0) +#endif + +#ifndef MICROPY_NLR_RV64I +#define MICROPY_NLR_RV64I (0) +#endif + +#ifndef MICROPY_NLR_SETJMP +#define MICROPY_NLR_SETJMP (0) +#endif + +#ifndef MICROPY_NLR_THUMB +#define MICROPY_NLR_THUMB (0) +#endif + +#ifndef MICROPY_NLR_X64 +#define MICROPY_NLR_X64 (0) +#endif + +#ifndef MICROPY_NLR_X86 +#define MICROPY_NLR_X86 (0) +#endif + +#ifndef MICROPY_NLR_XTENSA +#define MICROPY_NLR_XTENSA (0) #endif // *FORMAT-ON* @@ -182,18 +233,18 @@ unsigned int nlr_push(nlr_buf_t *); unsigned int nlr_push_tail(nlr_buf_t *top); void nlr_pop(void); -NORETURN void nlr_jump(void *val); +MP_NORETURN void nlr_jump(void *val); #if MICROPY_ENABLE_VM_ABORT #define nlr_set_abort(buf) MP_STATE_VM(nlr_abort) = buf #define nlr_get_abort() MP_STATE_VM(nlr_abort) -NORETURN void nlr_jump_abort(void); +MP_NORETURN void nlr_jump_abort(void); #endif // This must be implemented by a port. It's called by nlr_jump // if no nlr buf has been pushed. It must not return, but rather // should bail out with a fatal error. -NORETURN void nlr_jump_fail(void *val); +MP_NORETURN void nlr_jump_fail(void *val); // use nlr_raise instead of nlr_jump so that debugging is easier #ifndef MICROPY_DEBUG_NLR diff --git a/py/nlraarch64.c b/py/nlraarch64.c index 898d9e2a765..3318004b5e0 100644 --- a/py/nlraarch64.c +++ b/py/nlraarch64.c @@ -26,8 +26,7 @@ #include "py/mpstate.h" // needed for NLR defs -// CIRCUITPY-CHANGE: avoid warnings -#if defined(MICROPY_NLR_AARCH64) && MICROPY_NLR_AARCH64 +#if MICROPY_NLR_AARCH64 // AArch64 callee-saved registers are x19-x29. // https://en.wikipedia.org/wiki/Calling_convention#ARM_(A64) @@ -57,7 +56,7 @@ __asm( #endif ); -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) MP_STATIC_ASSERT(offsetof(nlr_buf_t, regs) == 16); // asm assumes it diff --git a/py/nlrmips.c b/py/nlrmips.c index a60c3abd714..5c55db7e268 100644 --- a/py/nlrmips.c +++ b/py/nlrmips.c @@ -26,8 +26,7 @@ #include "py/mpstate.h" -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_MIPS) && MICROPY_NLR_MIPS +#if MICROPY_NLR_MIPS __attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr); @@ -58,7 +57,7 @@ __asm( ".end nlr_push \n" ); -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) __asm( "move $4, %0 \n" diff --git a/py/nlrpowerpc.c b/py/nlrpowerpc.c index ae2f92a0780..cf140400e68 100644 --- a/py/nlrpowerpc.c +++ b/py/nlrpowerpc.c @@ -26,8 +26,7 @@ #include "py/mpstate.h" -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_POWERPC) && MICROPY_NLR_POWERPC +#if MICROPY_NLR_POWERPC #undef nlr_push @@ -79,7 +78,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) { return 0; } -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) __asm__ volatile ( @@ -168,7 +167,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) { return 0; } -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) __asm__ volatile ( diff --git a/py/nlrrv32.c b/py/nlrrv32.c new file mode 100644 index 00000000000..565a8629db5 --- /dev/null +++ b/py/nlrrv32.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +#include "py/mpstate.h" + +#if MICROPY_NLR_RV32I + +#undef nlr_push + +__attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { + __asm volatile ( + "sw x1, 8(x10) \n" // Store RA. + "sw x8, 12(x10) \n" // Store S0. + "sw x9, 16(x10) \n" // Store S1. + "sw x18, 20(x10) \n" // Store S2. + "sw x19, 24(x10) \n" // Store S3. + "sw x20, 28(x10) \n" // Store S4. + "sw x21, 32(x10) \n" // Store S5. + "sw x22, 36(x10) \n" // Store S6. + "sw x23, 40(x10) \n" // Store S7. + "sw x24, 44(x10) \n" // Store S8. + "sw x25, 48(x10) \n" // Store S9. + "sw x26, 52(x10) \n" // Store S10. + "sw x27, 56(x10) \n" // Store S11. + "sw x2, 60(x10) \n" // Store SP. + "jal x0, nlr_push_tail \n" // Jump to the C part. + ); +} + +MP_NORETURN void nlr_jump(void *val) { + MP_NLR_JUMP_HEAD(val, top) + __asm volatile ( + "add x10, x0, %0 \n" // Load nlr_buf address. + "lw x1, 8(x10) \n" // Retrieve RA. + "lw x8, 12(x10) \n" // Retrieve S0. + "lw x9, 16(x10) \n" // Retrieve S1. + "lw x18, 20(x10) \n" // Retrieve S2. + "lw x19, 24(x10) \n" // Retrieve S3. + "lw x20, 28(x10) \n" // Retrieve S4. + "lw x21, 32(x10) \n" // Retrieve S5. + "lw x22, 36(x10) \n" // Retrieve S6. + "lw x23, 40(x10) \n" // Retrieve S7. + "lw x24, 44(x10) \n" // Retrieve S8. + "lw x25, 48(x10) \n" // Retrieve S9. + "lw x26, 52(x10) \n" // Retrieve S10. + "lw x27, 56(x10) \n" // Retrieve S11. + "lw x2, 60(x10) \n" // Retrieve SP. + "addi x10, x0, 1 \n" // Return 1 for a non-local return. + "jalr x0, x1, 0 \n" // Return. + : // Outputs. + : "r" (top) // Inputs. + : "memory" // Clobbered. + ); + + MP_UNREACHABLE +} + +#endif // MICROPY_NLR_RV32I diff --git a/py/nlrrv64.c b/py/nlrrv64.c new file mode 100644 index 00000000000..b7d1467b8f6 --- /dev/null +++ b/py/nlrrv64.c @@ -0,0 +1,81 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +#include "py/mpstate.h" + +#if MICROPY_NLR_RV64I + +#undef nlr_push + +__attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { + __asm volatile ( + "sd x1, 16(x10) \n" // Store RA. + "sd x8, 24(x10) \n" // Store S0. + "sd x9, 32(x10) \n" // Store S1. + "sd x18, 40(x10) \n" // Store S2. + "sd x19, 48(x10) \n" // Store S3. + "sd x20, 56(x10) \n" // Store S4. + "sd x21, 64(x10) \n" // Store S5. + "sd x22, 72(x10) \n" // Store S6. + "sd x23, 80(x10) \n" // Store S7. + "sd x24, 88(x10) \n" // Store S8. + "sd x25, 96(x10) \n" // Store S9. + "sd x26, 104(x10) \n" // Store S10. + "sd x27, 112(x10) \n" // Store S11. + "sd x2, 120(x10) \n" // Store SP. + "jal x0, nlr_push_tail \n" // Jump to the C part. + ); +} + +MP_NORETURN void nlr_jump(void *val) { + MP_NLR_JUMP_HEAD(val, top) + __asm volatile ( + "add x10, x0, %0 \n" // Load nlr_buf address. + "ld x1, 16(x10) \n" // Retrieve RA. + "ld x8, 24(x10) \n" // Retrieve S0. + "ld x9, 32(x10) \n" // Retrieve S1. + "ld x18, 40(x10) \n" // Retrieve S2. + "ld x19, 48(x10) \n" // Retrieve S3. + "ld x20, 56(x10) \n" // Retrieve S4. + "ld x21, 64(x10) \n" // Retrieve S5. + "ld x22, 72(x10) \n" // Retrieve S6. + "ld x23, 80(x10) \n" // Retrieve S7. + "ld x24, 88(x10) \n" // Retrieve S8. + "ld x25, 96(x10) \n" // Retrieve S9. + "ld x26, 104(x10) \n" // Retrieve S10. + "ld x27, 112(x10) \n" // Retrieve S11. + "ld x2, 120(x10) \n" // Retrieve SP. + "addi x10, x0, 1 \n" // Return 1 for a non-local return. + "jalr x0, x1, 0 \n" // Return. + : // Outputs. + : "r" (top) // Inputs. + : "memory" // Clobbered. + ); + + MP_UNREACHABLE +} + +#endif // MICROPY_NLR_RV64I diff --git a/py/nlrthumb.c b/py/nlrthumb.c index de4d69eabd1..1791d8b4929 100644 --- a/py/nlrthumb.c +++ b/py/nlrthumb.c @@ -26,8 +26,7 @@ #include "py/mpstate.h" -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_THUMB) && MICROPY_NLR_THUMB +#if MICROPY_NLR_THUMB #undef nlr_push @@ -37,8 +36,7 @@ // For reference, arm/thumb callee save regs are: // r4-r11, r13=sp -// CIRCUITPY-CHANGE: added returns_twice -__attribute__((naked, returns_twice)) unsigned int nlr_push(nlr_buf_t *nlr) { +__attribute__((naked)) unsigned int nlr_push(nlr_buf_t *nlr) { // If you get a linker error here, indicating that a relocation doesn't // fit, try the following (in that order): @@ -93,6 +91,10 @@ __attribute__((naked, returns_twice)) unsigned int nlr_push(nlr_buf_t *nlr) { "b nlr_push_tail \n" // do the rest in C #endif #endif + // CIRCUITPY-CHANGE: add input and clobbers to prevent smashing registers. + : // output operands + : "r" (nlr) // input operands + : "r1", "r2", "r3" // clobbers ); #if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8)) @@ -102,7 +104,7 @@ __attribute__((naked, returns_twice)) unsigned int nlr_push(nlr_buf_t *nlr) { #endif } -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) __asm volatile ( @@ -142,7 +144,8 @@ NORETURN void nlr_jump(void *val) { "bx lr \n" // return : // output operands : "r" (top) // input operands - : "memory" // clobbered registers + // CIRCUITPY-CHANGE: better comment + : "memory" // clobbers ); MP_UNREACHABLE diff --git a/py/nlrx64.c b/py/nlrx64.c index 63586a2199f..51224729fc9 100644 --- a/py/nlrx64.c +++ b/py/nlrx64.c @@ -26,8 +26,7 @@ #include "py/mpstate.h" -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_X64) && MICROPY_NLR_X64 +#if MICROPY_NLR_X64 #undef nlr_push @@ -101,7 +100,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) { #endif } -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) __asm volatile ( diff --git a/py/nlrx86.c b/py/nlrx86.c index a2ce8424f9c..26bf0dc6ccb 100644 --- a/py/nlrx86.c +++ b/py/nlrx86.c @@ -26,16 +26,14 @@ #include "py/mpstate.h" -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_X86) && MICROPY_NLR_X86 +#if MICROPY_NLR_X86 #undef nlr_push // For reference, x86 callee save regs are: // ebx, esi, edi, ebp, esp, eip -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_OS_WINDOWS) && MICROPY_NLR_OS_WINDOWS +#if MICROPY_NLR_OS_WINDOWS unsigned int nlr_push_tail(nlr_buf_t *nlr) asm ("nlr_push_tail"); #else __attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr); @@ -80,7 +78,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) { #endif } -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) __asm volatile ( diff --git a/py/nlrxtensa.c b/py/nlrxtensa.c index 62e799dbdca..2d1bf35e381 100644 --- a/py/nlrxtensa.c +++ b/py/nlrxtensa.c @@ -26,8 +26,7 @@ #include "py/mpstate.h" -// CIRCUITPY-CHANGE: avoid warning -#if defined(MICROPY_NLR_XTENSA) && MICROPY_NLR_XTENSA +#if MICROPY_NLR_XTENSA #undef nlr_push @@ -56,7 +55,7 @@ unsigned int nlr_push(nlr_buf_t *nlr) { return 0; // needed to silence compiler warning } -NORETURN void nlr_jump(void *val) { +MP_NORETURN void nlr_jump(void *val) { MP_NLR_JUMP_HEAD(val, top) __asm volatile ( diff --git a/py/obj.c b/py/obj.c index afbc62a65fc..ba3e6a9a996 100644 --- a/py/obj.c +++ b/py/obj.c @@ -31,6 +31,7 @@ // CIRCUITPY-CHANGE #include "shared/runtime/interrupt_char.h" +#include "py/misc.h" #include "py/obj.h" #include "py/objtype.h" #include "py/objint.h" @@ -38,7 +39,7 @@ // CIRCUITPY-CHANGE #include "py/qstr.h" #include "py/runtime.h" -#include "py/stackctrl.h" +#include "py/cstack.h" #include "py/stream.h" // for mp_obj_print // CIRCUITPY-CHANGE @@ -46,7 +47,8 @@ // Allocates an object and also sets type, for mp_obj_malloc{,_var} macros. MP_NOINLINE void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type) { - mp_obj_base_t *base = (mp_obj_base_t *)m_malloc(num_bytes); + // CIRCUITPY-CHANGE + mp_obj_base_t *base = (mp_obj_base_t *)m_malloc_helper(num_bytes, M_MALLOC_RAISE_ERROR | M_MALLOC_COLLECT); base->type = type; return base; } @@ -54,7 +56,8 @@ MP_NOINLINE void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *ty #if MICROPY_ENABLE_FINALISER // Allocates an object and also sets type, for mp_obj_malloc{,_var}_with_finaliser macros. MP_NOINLINE void *mp_obj_malloc_with_finaliser_helper(size_t num_bytes, const mp_obj_type_t *type) { - mp_obj_base_t *base = (mp_obj_base_t *)m_malloc_with_finaliser(num_bytes); + // CIRCUITPY-CHANGE + mp_obj_base_t *base = (mp_obj_base_t *)m_malloc_helper(num_bytes, M_MALLOC_RAISE_ERROR | M_MALLOC_COLLECT | M_MALLOC_WITH_FINALISER); base->type = type; return base; } @@ -125,7 +128,7 @@ const char *mp_obj_get_type_str(mp_const_obj_t o_in) { void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { // There can be data structures nested too deep, or just recursive - MP_STACK_CHECK(); + mp_cstack_check(); // CIRCUITPY-CHANGE #ifdef RUN_BACKGROUND_TASKS RUN_BACKGROUND_TASKS; @@ -144,10 +147,17 @@ void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t } #endif const mp_obj_type_t *type = mp_obj_get_type(o_in); + // CIRCUITPY-CHANGE: Diagnose json.dump on invalid types + #if MICROPY_PY_JSON + if (kind == PRINT_JSON && !(type->flags & MP_TYPE_FLAG_PRINT_JSON)) { + mp_raise_msg_varg(&mp_type_TypeError, + MP_ERROR_TEXT("can't convert %q to %q"), type->name, MP_QSTR_json); + } + #endif if (MP_OBJ_TYPE_HAS_SLOT(type, print)) { MP_OBJ_TYPE_GET_SLOT(type, print)((mp_print_t *)print, o_in, kind); } else { - mp_printf(print, "<%q>", type->name); + mp_printf(print, "<%q>", (qstr)type->name); } } @@ -407,6 +417,36 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) { return val; } +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE +mp_uint_t mp_obj_get_uint(mp_const_obj_t arg) { + if (!mp_obj_is_exact_type(arg, &mp_type_int)) { + mp_obj_t as_int = mp_unary_op(MP_UNARY_OP_INT_MAYBE, (mp_obj_t)arg); + if (as_int == MP_OBJ_NULL) { + mp_raise_TypeError_int_conversion(arg); + } + arg = as_int; + } + return mp_obj_int_get_uint_checked(arg); +} + +long long mp_obj_get_ll(mp_const_obj_t arg) { + if (!mp_obj_is_exact_type(arg, &mp_type_int)) { + mp_obj_t as_int = mp_unary_op(MP_UNARY_OP_INT_MAYBE, (mp_obj_t)arg); + if (as_int == MP_OBJ_NULL) { + mp_raise_TypeError_int_conversion(arg); + } + arg = as_int; + } + if (mp_obj_is_small_int(arg)) { + return MP_OBJ_SMALL_INT_VALUE(arg); + } else { + long long res; + mp_obj_int_to_bytes_impl((mp_obj_t)arg, MP_ENDIANNESS_BIG, sizeof(res), (byte *)&res); + return res; + } +} +#endif + mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg) { if (mp_obj_is_int(arg)) { return mp_obj_int_get_truncated(arg); diff --git a/py/obj.h b/py/obj.h index 70fdeeebde4..eb7143bd43f 100644 --- a/py/obj.h +++ b/py/obj.h @@ -184,12 +184,15 @@ static inline bool mp_obj_is_small_int(mp_const_obj_t o) { #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 1) | 1)) #if MICROPY_PY_BUILTINS_FLOAT -#define mp_const_float_e MP_ROM_PTR((mp_obj_t)(((0x402df854 & ~3) | 2) + 0x80800000)) -#define mp_const_float_pi MP_ROM_PTR((mp_obj_t)(((0x40490fdb & ~3) | 2) + 0x80800000)) +#include +// note: MP_OBJ_NEW_CONST_FLOAT should be a MP_ROM_PTR but that macro isn't available yet +#define MP_OBJ_NEW_CONST_FLOAT(f) ((mp_obj_t)((((((uint64_t)f) & ~3) | 2) + 0x80800000) & 0xffffffff)) +#define mp_const_float_e MP_OBJ_NEW_CONST_FLOAT(0x402df854) +#define mp_const_float_pi MP_OBJ_NEW_CONST_FLOAT(0x40490fdb) +#define mp_const_float_nan MP_OBJ_NEW_CONST_FLOAT(0x7fc00000) #if MICROPY_PY_MATH_CONSTANTS -#define mp_const_float_tau MP_ROM_PTR((mp_obj_t)(((0x40c90fdb & ~3) | 2) + 0x80800000)) -#define mp_const_float_inf MP_ROM_PTR((mp_obj_t)(((0x7f800000 & ~3) | 2) + 0x80800000)) -#define mp_const_float_nan MP_ROM_PTR((mp_obj_t)(((0xffc00000 & ~3) | 2) + 0x80800000)) +#define mp_const_float_tau MP_OBJ_NEW_CONST_FLOAT(0x40c90fdb) +#define mp_const_float_inf MP_OBJ_NEW_CONST_FLOAT(0x7f800000) #endif static inline bool mp_obj_is_float(mp_const_obj_t o) { @@ -202,15 +205,23 @@ static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { union { mp_float_t f; mp_uint_t u; - } num = {.u = ((mp_uint_t)o - 0x80800000) & ~3}; + } num = {.u = ((mp_uint_t)o - 0x80800000u) & ~3u}; + // Rather than always truncating toward zero, which creates a strong + // bias, copy the two previous bits to fill in the two missing bits. + // This appears to be a pretty good heuristic. + num.u |= (num.u >> 2) & 3u; return num.f; } static inline mp_obj_t mp_obj_new_float(mp_float_t f) { + if (isnan(f)) { + // prevent creation of bad nanboxed pointers via array.array or struct + return mp_const_float_nan; + } union { mp_float_t f; mp_uint_t u; } num = {.f = f}; - return (mp_obj_t)(((num.u & ~0x3) | 2) + 0x80800000); + return (mp_obj_t)(((num.u & ~0x3u) | 2u) + 0x80800000u); } #endif @@ -256,8 +267,10 @@ static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) { #error MICROPY_OBJ_REPR_D requires MICROPY_FLOAT_IMPL_DOUBLE #endif +#include #define mp_const_float_e {((mp_obj_t)((uint64_t)0x4005bf0a8b145769 + 0x8004000000000000))} #define mp_const_float_pi {((mp_obj_t)((uint64_t)0x400921fb54442d18 + 0x8004000000000000))} +#define mp_const_float_nan {((mp_obj_t)((uint64_t)0x7ff8000000000000 + 0x8004000000000000))} #if MICROPY_PY_MATH_CONSTANTS #define mp_const_float_tau {((mp_obj_t)((uint64_t)0x401921fb54442d18 + 0x8004000000000000))} #define mp_const_float_inf {((mp_obj_t)((uint64_t)0x7ff0000000000000 + 0x8004000000000000))} @@ -275,6 +288,13 @@ static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { return num.f; } static inline mp_obj_t mp_obj_new_float(mp_float_t f) { + if (isnan(f)) { + // prevent creation of bad nanboxed pointers via array.array or struct + struct { + uint64_t r; + } num = mp_const_float_nan; + return num.r; + } union { mp_float_t f; uint64_t r; @@ -370,25 +390,25 @@ typedef struct _mp_rom_obj_t { mp_const_obj_t o; } mp_rom_obj_t; #define MP_DEFINE_CONST_FUN_OBJ_0(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ - {{&mp_type_fun_builtin_0}, .fun._0 = fun_name} + {.base = {.type = &mp_type_fun_builtin_0}, .fun = {._0 = fun_name}} #define MP_DEFINE_CONST_FUN_OBJ_1(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ - {{&mp_type_fun_builtin_1}, .fun._1 = fun_name} + {.base = {.type = &mp_type_fun_builtin_1}, .fun = {._1 = fun_name}} #define MP_DEFINE_CONST_FUN_OBJ_2(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ - {{&mp_type_fun_builtin_2}, .fun._2 = fun_name} + {.base = {.type = &mp_type_fun_builtin_2}, .fun = {._2 = fun_name}} #define MP_DEFINE_CONST_FUN_OBJ_3(obj_name, fun_name) \ const mp_obj_fun_builtin_fixed_t obj_name = \ - {{&mp_type_fun_builtin_3}, .fun._3 = fun_name} + {.base = {.type = &mp_type_fun_builtin_3}, .fun = {._3 = fun_name}} #define MP_DEFINE_CONST_FUN_OBJ_VAR(obj_name, n_args_min, fun_name) \ const mp_obj_fun_builtin_var_t obj_name = \ - {{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, false), .fun.var = fun_name} + {.base = {.type = &mp_type_fun_builtin_var}, .sig = MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, false), .fun = {.var = fun_name}} #define MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(obj_name, n_args_min, n_args_max, fun_name) \ const mp_obj_fun_builtin_var_t obj_name = \ - {{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, false), .fun.var = fun_name} + {.base = {.type = &mp_type_fun_builtin_var}, .sig = MP_OBJ_FUN_MAKE_SIG(n_args_min, n_args_max, false), .fun = {.var = fun_name}} #define MP_DEFINE_CONST_FUN_OBJ_KW(obj_name, n_args_min, fun_name) \ const mp_obj_fun_builtin_var_t obj_name = \ - {{&mp_type_fun_builtin_var}, MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, true), .fun.kw = fun_name} + {.base = {.type = &mp_type_fun_builtin_var}, .sig = MP_OBJ_FUN_MAKE_SIG(n_args_min, MP_OBJ_FUN_ARGS_MAX, true), .fun = {.kw = fun_name}} // CIRCUITPY-CHANGE #define MP_DEFINE_CONST_PROP_GET(obj_name, fun_name) \ @@ -515,9 +535,7 @@ static inline bool mp_map_slot_is_filled(const mp_map_t *map, size_t pos) { void mp_map_init(mp_map_t *map, size_t n); void mp_map_init_fixed_table(mp_map_t *map, size_t n, const mp_obj_t *table); -mp_map_t *mp_map_new(size_t n); void mp_map_deinit(mp_map_t *map); -void mp_map_free(mp_map_t *map); mp_map_elem_t *mp_map_lookup(mp_map_t *map, mp_obj_t index, mp_map_lookup_kind_t lookup_kind); void mp_map_clear(mp_map_t *map); void mp_map_dump(mp_map_t *map); @@ -548,9 +566,16 @@ typedef mp_obj_t (*mp_fun_3_t)(mp_obj_t, mp_obj_t, mp_obj_t); typedef mp_obj_t (*mp_fun_var_t)(size_t n, const mp_obj_t *); // mp_fun_kw_t takes mp_map_t* (and not const mp_map_t*) to ease passing // this arg to mp_map_lookup(). +// Note that the mp_obj_t* array will contain all arguments, positional and keyword, with the keyword +// ones starting at offset n, like: arg0 arg1 ... arg key0 value0 key1 value1 ..., and the mp_map_t* +// gets those same keyword arguments but as a map for convenience; see fun_builtin_var_call. typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); // Flags for type behaviour (mp_obj_type_t.flags) +// If MP_TYPE_FLAG_IS_SUBCLASSED is set, then subclasses of this class have been created. +// Mutations to this class that would require updating all subclasses must be rejected. +// If MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS is set, then attribute lookups involving this +// class need to additionally check for special accessor methods, such as from descriptors. // If MP_TYPE_FLAG_EQ_NOT_REFLEXIVE is clear then __eq__ is reflexive (A==A returns True). // If MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE is clear then the type can't be equal to an // instance of any different class that also clears this flag. If this flag is set @@ -568,6 +593,8 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); // If MP_TYPE_FLAG_ITER_IS_STREAM is set then the type implicitly gets a "return self" // getiter, and mp_stream_unbuffered_iter for iternext. // If MP_TYPE_FLAG_INSTANCE_TYPE is set then this is an instance type (i.e. defined in Python). +// If MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE is set then the "subscr" slot allows a stack +// allocated slice to be passed in (no references to it will be retained after the call). #define MP_TYPE_FLAG_NONE (0x0000) #define MP_TYPE_FLAG_IS_SUBCLASSED (0x0001) #define MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS (0x0002) @@ -581,6 +608,9 @@ typedef mp_obj_t (*mp_fun_kw_t)(size_t n, const mp_obj_t *, mp_map_t *); #define MP_TYPE_FLAG_ITER_IS_CUSTOM (0x0100) #define MP_TYPE_FLAG_ITER_IS_STREAM (MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_ITER_IS_CUSTOM) #define MP_TYPE_FLAG_INSTANCE_TYPE (0x0200) +#define MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE (0x0400) +// CIRCUITPY-CHANGE: check for valid types in json dumps +#define MP_TYPE_FLAG_PRINT_JSON (0x0800) typedef enum { PRINT_STR = 0, @@ -821,7 +851,7 @@ typedef struct _mp_obj_full_type_t { #define MP_DEFINE_CONST_OBJ_TYPE_NARGS(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, N, ...) MP_DEFINE_CONST_OBJ_TYPE_NARGS_##N // This macros is used to define a object type in ROM. -// Invoke as MP_DEFINE_CONST_OBJ_TYPE(_typename, _name, _flags, _make_new [, slot, func]*) +// Invoke as MP_DEFINE_CONST_OBJ_TYPE(_typename, _name, _flags, [, slot, func]*) // It uses the number of arguments to select which MP_DEFINE_CONST_OBJ_TYPE_* // macro to use based on the number of arguments. It works by shifting the // numeric values 12, 11, ... 0 by the number of arguments, such that the @@ -841,7 +871,7 @@ extern const mp_obj_type_t mp_type_bytearray; extern const mp_obj_type_t mp_type_memoryview; extern const mp_obj_type_t mp_type_float; extern const mp_obj_type_t mp_type_complex; -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: add traceback support extern const mp_obj_type_t mp_type_traceback; extern const mp_obj_type_t mp_type_tuple; extern const mp_obj_type_t mp_type_list; @@ -876,6 +906,7 @@ extern const mp_obj_type_t mp_type_fun_bc; extern const mp_obj_type_t mp_type_fun_native; extern const mp_obj_type_t mp_type_fun_viper; extern const mp_obj_type_t mp_type_fun_asm; +extern const mp_obj_type_t mp_type_code; extern const mp_obj_type_t mp_type_module; extern const mp_obj_type_t mp_type_staticmethod; extern const mp_obj_type_t mp_type_classmethod; @@ -883,6 +914,7 @@ extern const mp_obj_type_t mp_type_bound_meth; extern const mp_obj_type_t mp_type_property; extern const mp_obj_type_t mp_type_stringio; extern const mp_obj_type_t mp_type_bytesio; +extern const mp_obj_type_t mp_type_ringio; extern const mp_obj_type_t mp_type_reversed; extern const mp_obj_type_t mp_type_polymorph_iter; #if MICROPY_ENABLE_FINALISER @@ -901,7 +933,7 @@ extern const mp_obj_type_t mp_type_ImportError; extern const mp_obj_type_t mp_type_IndentationError; extern const mp_obj_type_t mp_type_IndexError; extern const mp_obj_type_t mp_type_KeyboardInterrupt; -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: add ReloadException extern const mp_obj_type_t mp_type_ReloadException; extern const mp_obj_type_t mp_type_KeyError; extern const mp_obj_type_t mp_type_LookupError; @@ -909,9 +941,9 @@ extern const mp_obj_type_t mp_type_MemoryError; extern const mp_obj_type_t mp_type_NameError; extern const mp_obj_type_t mp_type_NotImplementedError; extern const mp_obj_type_t mp_type_OSError; -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: add ConnectionError extern const mp_obj_type_t mp_type_ConnectionError; -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: add BrokenPipeError extern const mp_obj_type_t mp_type_BrokenPipeError; extern const mp_obj_type_t mp_type_OverflowError; extern const mp_obj_type_t mp_type_RuntimeError; @@ -919,6 +951,7 @@ extern const mp_obj_type_t mp_type_StopAsyncIteration; extern const mp_obj_type_t mp_type_StopIteration; extern const mp_obj_type_t mp_type_SyntaxError; extern const mp_obj_type_t mp_type_SystemExit; +// CIRCUITPY-CHANGE: add TimeoutError extern const mp_obj_type_t mp_type_TimeoutError; extern const mp_obj_type_t mp_type_TypeError; extern const mp_obj_type_t mp_type_UnicodeError; @@ -983,11 +1016,11 @@ void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); // Object allocation macros for allocating objects that have a finaliser. #if MICROPY_ENABLE_FINALISER #define mp_obj_malloc_with_finaliser(struct_type, obj_type) ((struct_type *)mp_obj_malloc_with_finaliser_helper(sizeof(struct_type), obj_type)) -#define mp_obj_malloc_var_with_finaliser(struct_type, var_type, var_num, obj_type) ((struct_type *)mp_obj_malloc_with_finaliser_helper(sizeof(struct_type) + sizeof(var_type) * (var_num), obj_type)) +#define mp_obj_malloc_var_with_finaliser(struct_type, var_field, var_type, var_num, obj_type) ((struct_type *)mp_obj_malloc_with_finaliser_helper(offsetof(struct_type, var_field) + sizeof(var_type) * (var_num), obj_type)) void *mp_obj_malloc_with_finaliser_helper(size_t num_bytes, const mp_obj_type_t *type); #else #define mp_obj_malloc_with_finaliser(struct_type, obj_type) mp_obj_malloc(struct_type, obj_type) -#define mp_obj_malloc_var_with_finaliser(struct_type, var_type, var_num, obj_type) mp_obj_malloc_var(struct_type, var_type, var_num, obj_type) +#define mp_obj_malloc_var_with_finaliser(struct_type, var_field, var_type, var_num, obj_type) mp_obj_malloc_var(struct_type, var_field, var_type, var_num, obj_type) #endif // These macros are derived from more primitive ones and are used to @@ -1024,7 +1057,6 @@ bool mp_obj_is_dict_or_ordereddict(mp_obj_t o); // type check is done on iter method to allow tuple, namedtuple, attrtuple #define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), iter) == mp_obj_tuple_getiter) -mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); static inline mp_obj_t mp_obj_new_bool(mp_int_t x) { return x ? mp_const_true : mp_const_false; } @@ -1035,6 +1067,7 @@ mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, uns mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a multi-precision integer object (or raise an overflow exception) mp_obj_t mp_obj_new_str(const char *data, size_t len); // will check utf-8 (raises UnicodeError) +mp_obj_t mp_obj_new_str_from_cstr(const char *str); // // accepts null-terminated string, will check utf-8 (raises UnicodeError) mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len); // input data must be valid utf-8 mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr); // will check utf-8 (raises UnicodeError) #if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK @@ -1044,10 +1077,10 @@ mp_obj_t mp_obj_new_str_from_utf8_vstr(vstr_t *vstr); // input data must be vali #endif mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte *data, size_t len); -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: new routine mp_obj_t mp_obj_new_bytes_of_zeros(size_t len); mp_obj_t mp_obj_new_bytearray(size_t n, const void *items); -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: new routine mp_obj_t mp_obj_new_bytearray_of_zeros(size_t n); mp_obj_t mp_obj_new_bytearray_by_ref(size_t n, void *items); #if MICROPY_PY_BUILTINS_FLOAT @@ -1083,7 +1116,7 @@ mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items); const mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in); const char *mp_obj_get_type_str(mp_const_obj_t o_in); -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: new routine #define mp_obj_get_type_qstr(o_in) (mp_obj_get_type((o_in))->name) bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo); // arguments should be type objects mp_obj_t mp_obj_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type); @@ -1091,7 +1124,7 @@ mp_obj_t mp_obj_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_print(mp_obj_t o, mp_print_kind_t kind); void mp_obj_print_exception(const mp_print_t *print, mp_obj_t exc); -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: new routine void mp_obj_print_exception_with_limit(const mp_print_t *print, mp_obj_t exc, mp_int_t limit); bool mp_obj_is_true(mp_obj_t arg); @@ -1105,6 +1138,8 @@ static inline bool mp_obj_is_integer(mp_const_obj_t o) { } mp_int_t mp_obj_get_int(mp_const_obj_t arg); +mp_uint_t mp_obj_get_uint(mp_const_obj_t arg); +long long mp_obj_get_ll(mp_const_obj_t arg); mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg); bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value); #if MICROPY_PY_BUILTINS_FLOAT @@ -1154,7 +1189,7 @@ bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type); void mp_obj_exception_clear_traceback(mp_obj_t self_in); void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block); void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values); -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: new routine mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in); mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in); mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args); @@ -1231,7 +1266,7 @@ void mp_obj_tuple_del(mp_obj_t self_in); mp_int_t mp_obj_tuple_hash(mp_obj_t self_in); // list -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: public routine mp_obj_t mp_obj_list_clear(mp_obj_t self_in); mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg); mp_obj_t mp_obj_list_remove(mp_obj_t self_in, mp_obj_t value); @@ -1327,7 +1362,7 @@ typedef struct _mp_rom_obj_static_class_method_t { } mp_rom_obj_static_class_method_t; // property -// CIRCUITPY-CHANGE +// CIRCUITPY-CHANGE: extra args const mp_obj_t *mp_obj_property_get(mp_obj_t self_in, size_t *n_proxy); // sequence helpers @@ -1345,7 +1380,7 @@ bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, size_t len1, const byte * bool mp_seq_cmp_objs(mp_uint_t op, const mp_obj_t *items1, size_t len1, const mp_obj_t *items2, size_t len2); mp_obj_t mp_seq_index_obj(const mp_obj_t *items, size_t len, size_t n_args, const mp_obj_t *args); mp_obj_t mp_seq_count_obj(const mp_obj_t *items, size_t len, mp_obj_t value); -mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes); +mp_obj_t mp_seq_extract_slice(const mp_obj_t *seq, mp_bound_slice_t *indexes); // Helper to clear stale pointers from allocated, but unused memory, to preclude GC problems #define mp_seq_clear(start, len, alloc_len, item_sz) memset((byte *)(start) + (len) * (item_sz), 0, ((alloc_len) - (len)) * (item_sz)) @@ -1360,6 +1395,8 @@ mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t memmove(((char *)dest) + (beg + slice_len) * (item_sz), ((char *)dest) + (end) * (item_sz), ((dest_len) + (len_adj) - ((beg) + (slice_len))) * (item_sz)); \ memmove(((char *)dest) + (beg) * (item_sz), slice, slice_len * (item_sz)); +#if !MICROPY_PREVIEW_VERSION_2 + // Provide translation for legacy API #define MP_OBJ_IS_SMALL_INT mp_obj_is_small_int #define MP_OBJ_IS_QSTR mp_obj_is_qstr @@ -1372,4 +1409,6 @@ mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t #define MP_MAP_SLOT_IS_FILLED mp_map_slot_is_filled #define MP_SET_SLOT_IS_FILLED mp_set_slot_is_filled +#endif + #endif // MICROPY_INCLUDED_PY_OBJ_H diff --git a/py/objarray.c b/py/objarray.c index 3ab982184f9..1e259a20ac8 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -105,23 +105,40 @@ static mp_obj_array_t *array_new(char typecode, size_t n) { mp_raise_ValueError(MP_ERROR_TEXT("bad typecode")); } int typecode_size = mp_binary_get_size('@', typecode, NULL); - mp_obj_array_t *o = m_new_obj(mp_obj_array_t); + + // CIRCUITPY-CHANGE: refactor to use m_obj_malloc() + const mp_obj_type_t *type; #if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_PY_ARRAY - o->base.type = (typecode == BYTEARRAY_TYPECODE) ? &mp_type_bytearray : &mp_type_array; + type = (typecode == BYTEARRAY_TYPECODE) ? &mp_type_bytearray : &mp_type_array; #elif MICROPY_PY_BUILTINS_BYTEARRAY - o->base.type = &mp_type_bytearray; + type = &mp_type_bytearray; #else - o->base.type = &mp_type_array; + type = &mp_type_array; #endif + mp_obj_array_t *o = mp_obj_malloc(mp_obj_array_t, type); o->typecode = typecode; o->free = 0; o->len = n; - o->items = m_new(byte, typecode_size * o->len); + // CIRCUITPY-CHANGE + o->items = m_malloc_without_collect(typecode_size * o->len); return o; } #endif #if MICROPY_PY_BUILTINS_BYTEARRAY || MICROPY_PY_ARRAY +static void array_extend_impl(mp_obj_array_t *array, mp_obj_t arg, char typecode, size_t len) { + mp_obj_t iterable = mp_getiter(arg, NULL); + mp_obj_t item; + size_t i = 0; + while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { + if (len == 0) { + array_append(MP_OBJ_FROM_PTR(array), item); + } else { + mp_binary_set_val_array(typecode, array->items, i++, item); + } + } +} + static mp_obj_t array_construct(char typecode, mp_obj_t initializer) { // bytearrays can be raw-initialised from anything with the buffer protocol // other arrays can only be raw-initialised from bytes and bytearray objects @@ -154,18 +171,7 @@ static mp_obj_t array_construct(char typecode, mp_obj_t initializer) { } mp_obj_array_t *array = array_new(typecode, len); - - mp_obj_t iterable = mp_getiter(initializer, NULL); - mp_obj_t item; - size_t i = 0; - while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - if (len == 0) { - array_append(MP_OBJ_FROM_PTR(array), item); - } else { - mp_binary_set_val_array(typecode, array->items, i++, item); - } - } - + array_extend_impl(array, initializer, typecode, len); return MP_OBJ_FROM_PTR(array); } #endif @@ -225,7 +231,8 @@ static mp_obj_t bytearray_make_new(const mp_obj_type_t *type_in, size_t n_args, #if MICROPY_PY_BUILTINS_MEMORYVIEW mp_obj_t mp_obj_new_memoryview(byte typecode, size_t nitems, void *items) { - mp_obj_array_t *self = m_new_obj(mp_obj_array_t); + // CIRCUITPY-CHANGE + mp_obj_array_t *self = mp_obj_malloc(mp_obj_array_t, &mp_type_memoryview); mp_obj_memoryview_init(self, typecode, 0, nitems, items); return MP_OBJ_FROM_PTR(self); } @@ -293,7 +300,7 @@ static void memoryview_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_array_t *self = MP_OBJ_TO_PTR(self_in); dest[0] = MP_OBJ_NEW_SMALL_INT(mp_binary_get_size('@', self->typecode & TYPECODE_MASK, NULL)); } - // CIRCUITPY-CHANGE: prevent warning + // CIRCUITPY-CHANGE: add MICROPY_CPYTHON_COMPAT #if MICROPY_PY_BUILTINS_BYTES_HEX || MICROPY_CPYTHON_COMPAT else { // Need to forward to locals dict. @@ -467,8 +474,9 @@ static mp_obj_t array_append(mp_obj_t self_in, mp_obj_t arg) { if (self->free == 0) { size_t item_sz = mp_binary_get_size('@', self->typecode, NULL); // TODO: alloc policy - self->free = 8; - self->items = m_renew(byte, self->items, item_sz * self->len, item_sz * (self->len + self->free)); + size_t add_cnt = 8; + self->items = m_renew(byte, self->items, item_sz * self->len, item_sz * (self->len + add_cnt)); + self->free = add_cnt; mp_seq_clear(self->items, self->len + 1, self->len + self->free, item_sz); } mp_binary_set_val_array(self->typecode, self->items, self->len, arg); @@ -487,39 +495,42 @@ static mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { // allow to extend by anything that has the buffer protocol (extension to CPython) mp_buffer_info_t arg_bufinfo; - // CIRCUITPY-CHANGE: allow appending an iterable - if (mp_get_buffer(arg_in, &arg_bufinfo, MP_BUFFER_READ)) { - size_t sz = mp_binary_get_size('@', self->typecode, NULL); - - // convert byte count to element count - size_t len = arg_bufinfo.len / sz; - - // make sure we have enough room to extend - // TODO: alloc policy; at the moment we go conservative - if (self->free < len) { - self->items = m_renew(byte, self->items, (self->len + self->free) * sz, (self->len + len) * sz); - self->free = 0; - } else { - self->free -= len; - } + if (!mp_get_buffer(arg_in, &arg_bufinfo, MP_BUFFER_READ)) { + array_extend_impl(self, arg_in, 0, 0); + return mp_const_none; + } - // extend - mp_seq_copy((byte *)self->items + self->len * sz, arg_bufinfo.buf, len * sz, byte); - self->len += len; - } else { - // Otherwise argument must be an iterable of items to append - mp_obj_t iterable = mp_getiter(arg_in, NULL); - mp_obj_t item; - while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { - array_append(self_in, item); + size_t sz = mp_binary_get_size('@', self->typecode, NULL); + + // convert byte count to element count + size_t len = arg_bufinfo.len / sz; + + // make sure we have enough room to extend + // TODO: alloc policy; at the moment we go conservative + if (self->free < len) { + self->items = m_renew(byte, self->items, (self->len + self->free) * sz, (self->len + len) * sz); + self->free = 0; + + if (self_in == arg_in) { + // Get arg_bufinfo again in case self->items has moved + // + // (Note not possible to handle case that arg_in is a memoryview into self) + mp_get_buffer_raise(arg_in, &arg_bufinfo, MP_BUFFER_READ); } + } else { + self->free -= len; } + + // extend + mp_seq_copy((byte *)self->items + self->len * sz, arg_bufinfo.buf, len * sz, byte); + self->len += len; + return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(mp_obj_array_extend_obj, array_extend); #endif -// CIRCUITPY-CHANGE: buffer_finder used belo +// CIRCUITPY-CHANGE: buffer_finder used below #if MICROPY_PY_BUILTINS_BYTEARRAY && MICROPY_CPYTHON_COMPAT static mp_obj_t buffer_finder(size_t n_args, const mp_obj_t *args, int direction, bool is_index) { mp_check_self(mp_obj_is_type(args[0], &mp_type_bytearray)); @@ -558,7 +569,6 @@ static mp_obj_t buffer_finder(size_t n_args, const mp_obj_t *args, int direction } return MP_OBJ_NEW_SMALL_INT(p - (const byte *)haystack_bufinfo.buf); } - // CIRCUITPY-CHANGE: provides find, rfind, index static mp_obj_t buffer_find(size_t n_args, const mp_obj_t *args) { return buffer_finder(n_args, args, 1, false); @@ -661,7 +671,7 @@ static mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value mp_seq_replace_slice_no_grow(dest_items, o->len, slice.start, slice.stop, src_items + src_offs, src_len, item_sz); // CIRCUITPY-CHANGE - #if MICROPY_NONSTANDARD_TYPECODES + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES // Clear "freed" elements at the end of list // TODO: This is actually only needed for typecode=='O' mp_seq_clear(dest_items, o->len + len_adj, o->len, item_sz); @@ -684,7 +694,8 @@ static mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value if (slice.start > memview_offset_max) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("memoryview offset too large")); } - res = m_new_obj(mp_obj_array_t); + // CIRCUITPY-CHANGE + res = mp_obj_malloc(mp_obj_array_t, &mp_type_memoryview); *res = *o; res->memview_offset += slice.start; res->len = slice.stop - slice.start; @@ -796,7 +807,7 @@ MP_DEFINE_CONST_OBJ_TYPE( MP_DEFINE_CONST_OBJ_TYPE( mp_type_bytearray, MP_QSTR_bytearray, - MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER | MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE, make_new, bytearray_make_new, print, array_print, iter, array_iterator_new, @@ -835,7 +846,7 @@ MP_DEFINE_CONST_DICT(memoryview_locals_dict, memoryview_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( mp_type_memoryview, MP_QSTR_memoryview, - MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_ITER_IS_GETITER | MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE, make_new, memoryview_make_new, iter, array_iterator_new, unary_op, array_unary_op, diff --git a/py/objarray.h b/py/objarray.h index 4a0e8a983fe..bb7a514b979 100644 --- a/py/objarray.h +++ b/py/objarray.h @@ -53,6 +53,10 @@ typedef struct _mp_obj_array_t { } mp_obj_array_t; #if MICROPY_PY_BUILTINS_MEMORYVIEW + +#define MP_DEFINE_MEMORYVIEW_OBJ(obj_name, typecode, offset, len, ptr) \ + mp_obj_array_t obj_name = {{&mp_type_memoryview}, (typecode), (offset), (len), (ptr)} + static inline void mp_obj_memoryview_init(mp_obj_array_t *self, size_t typecode, size_t offset, size_t len, void *items) { self->base.type = &mp_type_memoryview; self->typecode = typecode; @@ -60,6 +64,7 @@ static inline void mp_obj_memoryview_init(mp_obj_array_t *self, size_t typecode, self->len = len; self->items = items; } + #endif #if MICROPY_PY_ARRAY || MICROPY_PY_BUILTINS_BYTEARRAY diff --git a/py/objbool.c b/py/objbool.c index 5b3e3660e95..990f52bb26f 100644 --- a/py/objbool.c +++ b/py/objbool.c @@ -84,11 +84,12 @@ static mp_obj_t bool_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_ return mp_binary_op(op, MP_OBJ_NEW_SMALL_INT(value), rhs_in); } +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( // can match all numeric types mp_type_bool, MP_QSTR_bool, - MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_PRINT_JSON, make_new, bool_make_new, print, bool_print, unary_op, bool_unary_op, diff --git a/py/objboundmeth.c b/py/objboundmeth.c index e3503ff154a..6df67f7bf9e 100644 --- a/py/objboundmeth.c +++ b/py/objboundmeth.c @@ -102,7 +102,11 @@ static mp_obj_t bound_meth_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_ } mp_obj_bound_meth_t *lhs = MP_OBJ_TO_PTR(lhs_in); mp_obj_bound_meth_t *rhs = MP_OBJ_TO_PTR(rhs_in); + #if MICROPY_PY_BOUND_METHOD_FULL_EQUALITY_CHECK + return mp_obj_new_bool(mp_obj_equal(lhs->self, rhs->self) && mp_obj_equal(lhs->meth, rhs->meth)); + #else return mp_obj_new_bool(lhs->self == rhs->self && lhs->meth == rhs->meth); + #endif } #if MICROPY_PY_FUNCTION_ATTRS diff --git a/py/objcell.c b/py/objcell.c index 95966c7917c..5c030c7405a 100644 --- a/py/objcell.c +++ b/py/objcell.c @@ -30,7 +30,7 @@ static void cell_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_cell_t *o = MP_OBJ_TO_PTR(o_in); - mp_printf(print, "obj); + mp_printf(print, "obj); if (o->obj == MP_OBJ_NULL) { mp_print_str(print, "(nil)"); } else { diff --git a/py/objclosure.c b/py/objclosure.c index 3ba507b9593..5235312b519 100644 --- a/py/objclosure.c +++ b/py/objclosure.c @@ -50,7 +50,8 @@ static mp_obj_t closure_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const return mp_call_function_n_kw(self->fun, self->n_closed + n_args, n_kw, args2); } else { // use heap to allocate temporary args array - mp_obj_t *args2 = m_new(mp_obj_t, n_total); + // CIRCUITPY-CHANGE + mp_obj_t *args2 = m_malloc_items(n_total); memcpy(args2, self->closed, self->n_closed * sizeof(mp_obj_t)); memcpy(args2 + self->n_closed, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t)); mp_obj_t res = mp_call_function_n_kw(self->fun, self->n_closed + n_args, n_kw, args2); diff --git a/py/objcode.c b/py/objcode.c new file mode 100644 index 00000000000..09904f10f36 --- /dev/null +++ b/py/objcode.c @@ -0,0 +1,246 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2025 Damien P. George + * + * 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. + */ + +#include "py/objcode.h" + +#if MICROPY_PY_BUILTINS_CODE == MICROPY_PY_BUILTINS_CODE_NONE + +// Code object not implemented at this configuration level. + +#elif MICROPY_PY_BUILTINS_CODE <= MICROPY_PY_BUILTINS_CODE_BASIC + +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_code, + MP_QSTR_code, + MP_TYPE_FLAG_NONE + ); + +#elif MICROPY_PY_BUILTINS_CODE <= MICROPY_PY_BUILTINS_CODE_FULL + +#include "py/profile.h" + +static void code_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { + (void)kind; + mp_obj_code_t *o = MP_OBJ_TO_PTR(o_in); + const mp_raw_code_t *rc = o->rc; + const mp_bytecode_prelude_t *prelude = &rc->prelude; + mp_printf(print, + "", + MP_CODE_QSTR_MAP(o->context, prelude->qstr_block_name_idx), + o, + MP_CODE_QSTR_MAP(o->context, 0), + rc->line_of_definition + ); +} + +static mp_obj_tuple_t *code_consts(const mp_module_context_t *context, const mp_raw_code_t *rc) { + mp_obj_tuple_t *consts = MP_OBJ_TO_PTR(mp_obj_new_tuple(rc->n_children + 1, NULL)); + + size_t const_no = 0; + for (size_t i = 0; i < rc->n_children; ++i) { + mp_obj_t code = mp_obj_new_code(context, rc->children[i], true); + consts->items[const_no++] = code; + } + consts->items[const_no++] = mp_const_none; + + return consts; +} + +#if !MICROPY_PREVIEW_VERSION_2 +static mp_obj_t raw_code_lnotab(const mp_raw_code_t *rc) { + // const mp_bytecode_prelude_t *prelude = &rc->prelude; + uint start = 0; + uint stop = rc->fun_data_len - start; + + uint last_lineno = mp_prof_bytecode_lineno(rc, start); + uint lasti = 0; + + const uint buffer_chunk_size = (stop - start) >> 2; // heuristic magic + uint buffer_size = buffer_chunk_size; + byte *buffer = m_new(byte, buffer_size); + uint buffer_index = 0; + + for (uint i = start; i < stop; ++i) { + uint lineno = mp_prof_bytecode_lineno(rc, i); + size_t line_diff = lineno - last_lineno; + if (line_diff > 0) { + uint instr_diff = (i - start) - lasti; + + assert(instr_diff < 256); + assert(line_diff < 256); + + if (buffer_index + 2 > buffer_size) { + buffer = m_renew(byte, buffer, buffer_size, buffer_size + buffer_chunk_size); + buffer_size = buffer_size + buffer_chunk_size; + } + last_lineno = lineno; + lasti = i - start; + buffer[buffer_index++] = instr_diff; + buffer[buffer_index++] = line_diff; + } + } + + mp_obj_t o = mp_obj_new_bytes(buffer, buffer_index); + m_del(byte, buffer, buffer_size); + return o; +} +#endif + +static mp_obj_t code_colines_iter(mp_obj_t); +static mp_obj_t code_colines_next(mp_obj_t); +typedef struct _mp_obj_colines_iter_t { + mp_obj_base_t base; + mp_fun_1_t iternext; + const mp_raw_code_t *rc; + mp_uint_t bc; + mp_uint_t source_line; + const byte *ci; +} mp_obj_colines_iter_t; + +static mp_obj_t code_colines_iter(mp_obj_t self_in) { + mp_obj_code_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_colines_iter_t *iter = mp_obj_malloc(mp_obj_colines_iter_t, &mp_type_polymorph_iter); + iter->iternext = code_colines_next; + iter->rc = self->rc; + iter->bc = 0; + iter->source_line = 1; + iter->ci = self->rc->prelude.line_info; + return MP_OBJ_FROM_PTR(iter); +} +static MP_DEFINE_CONST_FUN_OBJ_1(code_colines_obj, code_colines_iter); + +static mp_obj_t code_colines_next(mp_obj_t iter_in) { + mp_obj_colines_iter_t *iter = MP_OBJ_TO_PTR(iter_in); + const byte *ci_end = iter->rc->prelude.line_info_top; + + mp_uint_t start = iter->bc; + mp_uint_t line_no = iter->source_line; + bool another = true; + + while (another && iter->ci < ci_end) { + another = false; + mp_code_lineinfo_t decoded = mp_bytecode_decode_lineinfo(&iter->ci); + iter->bc += decoded.bc_increment; + iter->source_line += decoded.line_increment; + + if (decoded.bc_increment == 0) { + line_no = iter->source_line; + another = true; + } else if (decoded.line_increment == 0) { + another = true; + } + } + + if (another) { + mp_uint_t prelude_size = (iter->rc->prelude.opcodes - (const byte *)iter->rc->fun_data); + mp_uint_t bc_end = iter->rc->fun_data_len - prelude_size; + if (iter->bc >= bc_end) { + return MP_OBJ_STOP_ITERATION; + } else { + iter->bc = bc_end; + } + } + + mp_uint_t end = iter->bc; + mp_obj_t next[3] = {MP_OBJ_NEW_SMALL_INT(start), MP_OBJ_NEW_SMALL_INT(end), MP_OBJ_NEW_SMALL_INT(line_no)}; + + return mp_obj_new_tuple(MP_ARRAY_SIZE(next), next); +} + +static void code_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + if (dest[0] != MP_OBJ_NULL) { + // not load attribute + return; + } + mp_obj_code_t *o = MP_OBJ_TO_PTR(self_in); + const mp_raw_code_t *rc = o->rc; + const mp_bytecode_prelude_t *prelude = &rc->prelude; + switch (attr) { + case MP_QSTR_co_code: + dest[0] = mp_obj_new_bytes( + (void *)prelude->opcodes, + rc->fun_data_len - (prelude->opcodes - (const byte *)rc->fun_data) + ); + break; + case MP_QSTR_co_consts: + dest[0] = MP_OBJ_FROM_PTR(code_consts(o->context, rc)); + break; + case MP_QSTR_co_filename: + dest[0] = MP_OBJ_NEW_QSTR(MP_CODE_QSTR_MAP(o->context, 0)); + break; + case MP_QSTR_co_firstlineno: + dest[0] = MP_OBJ_NEW_SMALL_INT(mp_prof_bytecode_lineno(rc, 0)); + break; + case MP_QSTR_co_name: + dest[0] = MP_OBJ_NEW_QSTR(MP_CODE_QSTR_MAP(o->context, prelude->qstr_block_name_idx)); + break; + case MP_QSTR_co_names: + dest[0] = MP_OBJ_FROM_PTR(o->dict_locals); + break; + #if !MICROPY_PREVIEW_VERSION_2 + case MP_QSTR_co_lnotab: + if (!o->lnotab) { + o->lnotab = raw_code_lnotab(rc); + } + dest[0] = o->lnotab; + break; + #endif + case MP_QSTR_co_lines: + dest[0] = MP_OBJ_FROM_PTR(&code_colines_obj); + dest[1] = self_in; + break; + } +} + +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_code, + MP_QSTR_code, + MP_TYPE_FLAG_NONE, + print, code_print, + attr, code_attr + ); + +mp_obj_t mp_obj_new_code(const mp_module_context_t *context, const mp_raw_code_t *rc, bool result_required) { + mp_obj_code_t *o; + if (result_required) { + o = m_new_obj(mp_obj_code_t); + } else { + o = m_new_obj_maybe(mp_obj_code_t); + if (o == NULL) { + return MP_OBJ_NULL; + } + } + o->base.type = &mp_type_code; + o->context = context; + o->rc = rc; + o->dict_locals = mp_locals_get(); // this is a wrong! how to do this properly? + #if !MICROPY_PREVIEW_VERSION_2 + o->lnotab = MP_OBJ_NULL; + #endif + return MP_OBJ_FROM_PTR(o); +} + +#endif diff --git a/py/objcode.h b/py/objcode.h new file mode 100644 index 00000000000..7be15e23f52 --- /dev/null +++ b/py/objcode.h @@ -0,0 +1,100 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2025 Damien P. George + * + * 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. + */ +#ifndef MICROPY_INCLUDED_PY_OBJCODE_H +#define MICROPY_INCLUDED_PY_OBJCODE_H + +#include "py/bc.h" + +#if MICROPY_PY_BUILTINS_CODE == MICROPY_PY_BUILTINS_CODE_NONE + +// Code object not implemented at this configuration level. + +#elif MICROPY_PY_BUILTINS_CODE <= MICROPY_PY_BUILTINS_CODE_MINIMUM + +typedef struct _mp_obj_code_t { + mp_obj_base_t base; + mp_obj_t module_fun; +} mp_obj_code_t; + +static inline mp_obj_t mp_obj_new_code(mp_obj_t module_fun) { + mp_obj_code_t *code = mp_obj_malloc(mp_obj_code_t, &mp_type_code); + code->module_fun = module_fun; + return MP_OBJ_FROM_PTR(code); +} + +#elif MICROPY_PY_BUILTINS_CODE <= MICROPY_PY_BUILTINS_CODE_BASIC + +typedef struct _mp_obj_code_t { + mp_obj_base_t base; + mp_module_constants_t constants; + const void *proto_fun; +} mp_obj_code_t; + +static inline mp_obj_t mp_obj_new_code(const mp_module_constants_t constants, const void *proto_fun) { + mp_obj_code_t *code = mp_obj_malloc(mp_obj_code_t, &mp_type_code); + code->constants = constants; + code->proto_fun = proto_fun; + return MP_OBJ_FROM_PTR(code); +} + +static inline const mp_module_constants_t *mp_code_get_constants(mp_obj_code_t *self) { + return &self->constants; +} + +static inline const void *mp_code_get_proto_fun(mp_obj_code_t *self) { + return self->proto_fun; +} + +#elif MICROPY_PY_BUILTINS_CODE <= MICROPY_PY_BUILTINS_CODE_FULL + +#include "py/emitglue.h" + +#define MP_CODE_QSTR_MAP(context, idx) ((qstr)(context->constants.qstr_table[idx])) + +typedef struct _mp_obj_code_t { + mp_obj_base_t base; + const mp_module_context_t *context; + const mp_raw_code_t *rc; + mp_obj_dict_t *dict_locals; + #if !MICROPY_PREVIEW_VERSION_2 + mp_obj_t lnotab; + #endif +} mp_obj_code_t; + +mp_obj_t mp_obj_new_code(const mp_module_context_t *context, const mp_raw_code_t *rc, bool result_required); + +static inline const mp_module_constants_t *mp_code_get_constants(mp_obj_code_t *self) { + return &self->context->constants; +} + +static inline const void *mp_code_get_proto_fun(mp_obj_code_t *self) { + // A mp_raw_code_t is always a proto_fun (but not the other way around). + return self->rc; +} + +#endif + +#endif // MICROPY_INCLUDED_PY_OBJCODE_H diff --git a/py/objcomplex.c b/py/objcomplex.c index d7287efdc13..88f4444f09e 100644 --- a/py/objcomplex.c +++ b/py/objcomplex.c @@ -49,29 +49,18 @@ typedef struct _mp_obj_complex_t { static void complex_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_complex_t *o = MP_OBJ_TO_PTR(o_in); - #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT - char buf[16]; - #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C - const int precision = 6; - #else - const int precision = 7; - #endif - #else - char buf[32]; - const int precision = 16; - #endif - if (o->real == 0) { - mp_format_float(o->imag, buf, sizeof(buf), 'g', precision, '\0'); - mp_printf(print, "%sj", buf); + const char *suffix; + int flags = 0; + if (o->real != 0) { + mp_print_str(print, "("); + mp_print_float(print, o->real, 'g', 0, '\0', -1, MP_FLOAT_REPR_PREC); + flags = PF_FLAG_SHOW_SIGN; + suffix = "j)"; } else { - mp_format_float(o->real, buf, sizeof(buf), 'g', precision, '\0'); - mp_printf(print, "(%s", buf); - if (o->imag >= 0 || isnan(o->imag)) { - mp_print_str(print, "+"); - } - mp_format_float(o->imag, buf, sizeof(buf), 'g', precision, '\0'); - mp_printf(print, "%sj)", buf); + suffix = "j"; } + mp_print_float(print, o->imag, 'g', flags, '\0', -1, MP_FLOAT_REPR_PREC); + mp_print_str(print, suffix); } static mp_obj_t complex_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { diff --git a/py/objdeque.c b/py/objdeque.c index 583537017fd..4e1ee82e9d4 100644 --- a/py/objdeque.c +++ b/py/objdeque.c @@ -46,6 +46,11 @@ static mp_obj_t mp_obj_deque_extend(mp_obj_t self_in, mp_obj_t arg_in); static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf); #endif +// CIRCUITPY-CHANGE +static mp_obj_deque_t *native_deque(mp_obj_t self_in) { + return MP_OBJ_TO_PTR(mp_obj_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_deque))); +} + static mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 2, 3, false); @@ -58,7 +63,8 @@ static mp_obj_t deque_make_new(const mp_obj_type_t *type, size_t n_args, size_t mp_obj_deque_t *o = mp_obj_malloc(mp_obj_deque_t, type); o->alloc = maxlen + 1; o->i_get = o->i_put = 0; - o->items = m_new0(mp_obj_t, o->alloc); + // CIRCUITPY-CHANGE + o->items = m_malloc_items(o->alloc); if (n_args > 2) { o->flags = mp_obj_get_int(args[2]); @@ -78,7 +84,8 @@ static size_t deque_len(mp_obj_deque_t *self) { } static mp_obj_t deque_unary_op(mp_unary_op_t op, mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(self->i_get != self->i_put); @@ -97,7 +104,8 @@ static mp_obj_t deque_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } static mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t new_i_put = self->i_put + 1; if (new_i_put == self->alloc) { @@ -122,7 +130,8 @@ static mp_obj_t mp_obj_deque_append(mp_obj_t self_in, mp_obj_t arg) { static MP_DEFINE_CONST_FUN_OBJ_2(deque_append_obj, mp_obj_deque_append); static mp_obj_t mp_obj_deque_appendleft(mp_obj_t self_in, mp_obj_t arg) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t new_i_get = self->i_get - 1; if (self->i_get == 0) { @@ -161,7 +170,8 @@ static mp_obj_t mp_obj_deque_extend(mp_obj_t self_in, mp_obj_t arg_in) { static MP_DEFINE_CONST_FUN_OBJ_2(deque_extend_obj, mp_obj_deque_extend); static mp_obj_t deque_popleft(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); if (self->i_get == self->i_put) { mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty")); @@ -179,7 +189,8 @@ static mp_obj_t deque_popleft(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(deque_popleft_obj, deque_popleft); static mp_obj_t deque_pop(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); if (self->i_get == self->i_put) { mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty")); @@ -204,11 +215,12 @@ static mp_obj_t deque_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { // delete not supported, fall back to mp_obj_subscr() error message return MP_OBJ_NULL; } - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); size_t offset = mp_get_index(self->base.type, deque_len(self), index, false); size_t index_val = self->i_get + offset; - if (index_val > self->alloc) { + if (index_val >= self->alloc) { index_val -= self->alloc; } @@ -225,7 +237,8 @@ static mp_obj_t deque_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if 0 static mp_obj_t deque_clear(mp_obj_t self_in) { - mp_obj_deque_t *self = MP_OBJ_TO_PTR(self_in); + // CIRCUITPY-CHANGE + mp_obj_deque_t *self = native_deque(self_in); self->i_get = self->i_put = 0; mp_seq_clear(self->items, 0, self->alloc, sizeof(*self->items)); return mp_const_none; @@ -263,7 +276,7 @@ static MP_DEFINE_CONST_DICT(deque_locals_dict, deque_locals_dict_table); MP_DEFINE_CONST_OBJ_TYPE( mp_type_deque, MP_QSTR_deque, - MP_TYPE_FLAG_ITER_IS_GETITER, + DEQUE_TYPE_FLAGS, make_new, deque_make_new, unary_op, deque_unary_op, DEQUE_TYPE_SUBSCR @@ -285,7 +298,8 @@ typedef struct _mp_obj_deque_it_t { static mp_obj_t deque_it_iternext(mp_obj_t self_in) { mp_obj_deque_it_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_deque_t *deque = MP_OBJ_TO_PTR(self->deque); + // CIRCUITPY-CHANGE + mp_obj_deque_t *deque = native_deque(self->deque); if (self->cur != deque->i_put) { mp_obj_t o_out = deque->items[self->cur]; if (++self->cur == deque->alloc) { @@ -297,9 +311,10 @@ static mp_obj_t deque_it_iternext(mp_obj_t self_in) { } } -static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque, mp_obj_iter_buf_t *iter_buf) { - mp_obj_deque_t *deque_ = MP_OBJ_TO_PTR(deque); - size_t i_get = deque_->i_get; +static mp_obj_t mp_obj_new_deque_it(mp_obj_t deque_in, mp_obj_iter_buf_t *iter_buf) { + // CIRCUITPY-CHANGE + mp_obj_deque_t *deque = native_deque(deque_in); + size_t i_get = deque->i_get; assert(sizeof(mp_obj_deque_it_t) <= sizeof(mp_obj_iter_buf_t)); mp_obj_deque_it_t *o = (mp_obj_deque_it_t *)iter_buf; o->base.type = &mp_type_polymorph_iter; diff --git a/py/objdict.c b/py/objdict.c index 96a659d36e0..d459d1ae486 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -101,7 +101,7 @@ static void dict_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ #endif } if (MICROPY_PY_COLLECTIONS_ORDEREDDICT && self->base.type != &mp_type_dict && kind != PRINT_JSON) { - mp_printf(print, "%q(", self->base.type->name); + mp_printf(print, "%q(", (qstr)self->base.type->name); } mp_print_str(print, "{"); size_t cur = 0; @@ -616,7 +616,8 @@ static mp_obj_t dict_view_unary_op(mp_unary_op_t op, mp_obj_t o_in) { if (op == MP_UNARY_OP_HASH && o->kind == MP_DICT_VIEW_VALUES) { return MP_OBJ_NEW_SMALL_INT((mp_uint_t)o_in); } - return MP_OBJ_NULL; + // delegate all other ops to dict unary op handler + return dict_unary_op(op, o->dict); } static mp_obj_t dict_view_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { @@ -710,10 +711,11 @@ static const mp_rom_map_elem_t dict_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(dict_locals_dict, dict_locals_dict_table); +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_dict, MP_QSTR_dict, - MP_TYPE_FLAG_ITER_IS_GETITER, + MP_TYPE_FLAG_ITER_IS_GETITER | MP_TYPE_FLAG_PRINT_JSON, make_new, mp_obj_dict_make_new, print, dict_print, unary_op, dict_unary_op, @@ -724,10 +726,11 @@ MP_DEFINE_CONST_OBJ_TYPE( ); #if MICROPY_PY_COLLECTIONS_ORDEREDDICT +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_ordereddict, MP_QSTR_OrderedDict, - MP_TYPE_FLAG_ITER_IS_GETITER, + MP_TYPE_FLAG_ITER_IS_GETITER | MP_TYPE_FLAG_PRINT_JSON, make_new, mp_obj_dict_make_new, print, dict_print, unary_op, dict_unary_op, @@ -745,7 +748,8 @@ void mp_obj_dict_init(mp_obj_dict_t *dict, size_t n_args) { } mp_obj_t mp_obj_new_dict(size_t n_args) { - mp_obj_dict_t *o = m_new_obj(mp_obj_dict_t); + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_obj_dict_t *o = mp_obj_malloc(mp_obj_dict_t, &mp_type_dict); mp_obj_dict_init(o, n_args); return MP_OBJ_FROM_PTR(o); } diff --git a/py/objexcept.c b/py/objexcept.c index e98907946ce..6a6b1e4d4a7 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -31,8 +31,6 @@ #include #include "py/objlist.h" -// CIRCUITPY-CHANGE -#include "py/objnamedtuple.h" #include "py/objstr.h" #include "py/objtuple.h" #include "py/objtype.h" @@ -539,10 +537,14 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_er assert(MP_OBJ_TYPE_GET_SLOT_OR_NULL(exc_type, make_new) == mp_obj_exception_make_new); // Try to allocate memory for the message - mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t); + mp_obj_str_t *o_str = NULL; + byte *o_str_buf = NULL; // CIRCUITPY-CHANGE: here and more below size_t o_str_alloc = decompress_length(fmt); - byte *o_str_buf = m_new_maybe(byte, o_str_alloc); + if (gc_alloc_possible()) { + o_str = m_new_obj_maybe(mp_obj_str_t); + o_str_buf = m_new_maybe(byte, o_str_alloc); + } bool used_emg_buf = false; #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF @@ -725,126 +727,3 @@ void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values *values = self->traceback->data; } } - -// CIRCUITPY-CHANGE: here until end -#if MICROPY_PY_SYS_EXC_INFO -static const mp_obj_namedtuple_type_t code_type_obj = { - NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_code), - .n_fields = 15, - .fields = { - MP_QSTR_co_argcount, - MP_QSTR_co_kwonlyargcount, - MP_QSTR_co_nlocals, - MP_QSTR_co_stacksize, - MP_QSTR_co_flags, - MP_QSTR_co_code, - MP_QSTR_co_consts, - MP_QSTR_co_names, - MP_QSTR_co_varnames, - MP_QSTR_co_freevars, - MP_QSTR_co_cellvars, - MP_QSTR_co_filename, - MP_QSTR_co_name, - MP_QSTR_co_firstlineno, - MP_QSTR_co_lnotab, - }, -}; - -static mp_obj_t code_make_new(qstr file, qstr block) { - mp_obj_t elems[15] = { - mp_obj_new_int(0), // co_argcount - mp_obj_new_int(0), // co_kwonlyargcount - mp_obj_new_int(0), // co_nlocals - mp_obj_new_int(0), // co_stacksize - mp_obj_new_int(0), // co_flags - mp_obj_new_bytearray(0, NULL), // co_code - mp_obj_new_tuple(0, NULL), // co_consts - mp_obj_new_tuple(0, NULL), // co_names - mp_obj_new_tuple(0, NULL), // co_varnames - mp_obj_new_tuple(0, NULL), // co_freevars - mp_obj_new_tuple(0, NULL), // co_cellvars - MP_OBJ_NEW_QSTR(file), // co_filename - MP_OBJ_NEW_QSTR(block), // co_name - mp_obj_new_int(1), // co_firstlineno - mp_obj_new_bytearray(0, NULL), // co_lnotab - }; - - return namedtuple_make_new((const mp_obj_type_t *)&code_type_obj, 15, 0, elems); -} - -static const mp_obj_namedtuple_type_t frame_type_obj = { - NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_frame), - .n_fields = 8, - .fields = { - MP_QSTR_f_back, - MP_QSTR_f_builtins, - MP_QSTR_f_code, - MP_QSTR_f_globals, - MP_QSTR_f_lasti, - MP_QSTR_f_lineno, - MP_QSTR_f_locals, - MP_QSTR_f_trace, - }, -}; - -static mp_obj_t frame_make_new(mp_obj_t f_code, int f_lineno) { - mp_obj_t elems[8] = { - mp_const_none, // f_back - mp_obj_new_dict(0), // f_builtins - f_code, // f_code - mp_obj_new_dict(0), // f_globals - mp_obj_new_int(0), // f_lasti - mp_obj_new_int(f_lineno), // f_lineno - mp_obj_new_dict(0), // f_locals - mp_const_none, // f_trace - }; - - return namedtuple_make_new((const mp_obj_type_t *)&frame_type_obj, 8, 0, elems); -} - -static const mp_obj_namedtuple_type_t traceback_type_obj = { - NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_traceback), - .n_fields = 4, - .fields = { - MP_QSTR_tb_frame, - MP_QSTR_tb_lasti, - MP_QSTR_tb_lineno, - MP_QSTR_tb_next, - }, -}; - -static mp_obj_t traceback_from_values(size_t *values, mp_obj_t tb_next) { - int lineno = values[1]; - - mp_obj_t elems[4] = { - frame_make_new(code_make_new(values[0], values[2]), lineno), - mp_obj_new_int(0), - mp_obj_new_int(lineno), - tb_next, - }; - - return namedtuple_make_new((const mp_obj_type_t *)&traceback_type_obj, 4, 0, elems); -}; - -mp_obj_t mp_obj_exception_get_traceback_obj(mp_obj_t self_in) { - mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in); - - if (!mp_obj_is_exception_instance(self)) { - return mp_const_none; - } - - size_t n, *values; - mp_obj_exception_get_traceback(self, &n, &values); - if (n == 0) { - return mp_const_none; - } - - mp_obj_t tb_next = mp_const_none; - - for (size_t i = 0; i < n; i += 3) { - tb_next = traceback_from_values(&values[i], tb_next); - } - - return tb_next; -} -#endif diff --git a/py/objfloat.c b/py/objfloat.c index b3a1f692594..ecc0f61a6ab 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -34,6 +34,11 @@ #if MICROPY_PY_BUILTINS_FLOAT +// Workaround a bug in Windows SDK version 10.0.26100.0, where NAN is no longer constant. +#if defined(_MSC_VER) && !defined(_UCRT_NOISY_NAN) +#define _UCRT_NOISY_NAN +#endif + #include #include "py/formatfloat.h" @@ -109,23 +114,7 @@ mp_int_t mp_float_hash(mp_float_t src) { static void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_float_t o_val = mp_obj_float_get(o_in); - #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT - char buf[16]; - #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C - const int precision = 6; - #else - const int precision = 7; - #endif - #else - char buf[32]; - const int precision = 16; - #endif - mp_format_float(o_val, buf, sizeof(buf), 'g', precision, '\0'); - mp_print_str(print, buf); - if (strchr(buf, '.') == NULL && strchr(buf, 'e') == NULL && strchr(buf, 'n') == NULL) { - // Python floats always have decimal point (unless inf or nan) - mp_print_str(print, ".0"); - } + mp_print_float(print, o_val, 'g', PF_FLAG_ALWAYS_DECIMAL, '\0', -1, MP_FLOAT_REPR_PREC); } static mp_obj_t float_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { @@ -186,8 +175,9 @@ static mp_obj_t float_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs return mp_obj_float_binary_op(op, lhs_val, rhs_in); } +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( - mp_type_float, MP_QSTR_float, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE, + mp_type_float, MP_QSTR_float, MP_TYPE_FLAG_EQ_NOT_REFLEXIVE | MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE | MP_TYPE_FLAG_PRINT_JSON, make_new, float_make_new, print, float_print, unary_op, float_unary_op, @@ -197,9 +187,8 @@ MP_DEFINE_CONST_OBJ_TYPE( #if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C && MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D mp_obj_t mp_obj_new_float(mp_float_t value) { - // Don't use mp_obj_malloc here to avoid extra function call overhead. - mp_obj_float_t *o = m_new_obj(mp_obj_float_t); - o->base.type = &mp_type_float; + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_obj_float_t *o = mp_obj_malloc(mp_obj_float_t, &mp_type_float); o->value = value; return MP_OBJ_FROM_PTR(o); } @@ -317,6 +306,10 @@ mp_obj_t mp_obj_float_binary_op(mp_binary_op_t op, mp_float_t lhs_val, mp_obj_t lhs_val = MICROPY_FLOAT_CONST(1.0); break; } + if (isnan(rhs_val)) { + lhs_val = rhs_val; + break; + } #endif lhs_val = MICROPY_FLOAT_C_FUN(pow)(lhs_val, rhs_val); break; diff --git a/py/objfun.c b/py/objfun.c index a552c5531b0..34565cf6336 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -28,11 +28,13 @@ #include #include +#include "py/emitglue.h" +#include "py/objcode.h" #include "py/objtuple.h" #include "py/objfun.h" #include "py/runtime.h" #include "py/bc.h" -#include "py/stackctrl.h" +#include "py/cstack.h" #if MICROPY_DEBUG_VERBOSE // print debugging info #define DEBUG_PRINT (1) @@ -110,7 +112,9 @@ static mp_obj_t fun_builtin_var_call(mp_obj_t self_in, size_t n_args, size_t n_k if (self->sig & 1) { // function allows keywords - // we create a map directly from the given args array + // we create a map directly from the given args array; self->fun.kw does still + // expect args to have both positional and keyword arguments, ordered as: + // arg0 arg1 ... arg key0 value0 key1 value1 ... key value mp_map_t kw_args; mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); @@ -152,11 +156,36 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) { return name; } +#if MICROPY_PY_FUNCTION_ATTRS_CODE +static mp_obj_t fun_bc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + (void)type; + mp_arg_check_num(n_args, n_kw, 2, 2, false); + + if (!mp_obj_is_type(args[0], &mp_type_code)) { + mp_raise_TypeError(NULL); + } + if (!mp_obj_is_type(args[1], &mp_type_dict)) { + mp_raise_TypeError(NULL); + } + + mp_obj_code_t *code = MP_OBJ_TO_PTR(args[0]); + mp_obj_t globals = args[1]; + + mp_module_context_t *module_context = m_new_obj(mp_module_context_t); + module_context->module.base.type = &mp_type_module; + module_context->module.globals = MP_OBJ_TO_PTR(globals); + module_context->constants = *mp_code_get_constants(code); + + return mp_make_function_from_proto_fun(mp_code_get_proto_fun(code), module_context, NULL); +} +#endif + #if MICROPY_CPYTHON_COMPAT static void fun_bc_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_fun_bc_t *o = MP_OBJ_TO_PTR(o_in); - mp_printf(print, "", mp_obj_fun_get_name(o_in), o); + // CIRCUITPY-CHANGE: %p already prints "0x", so don't include it explicitly. + mp_printf(print, "", mp_obj_fun_get_name(o_in), o); } #endif @@ -197,7 +226,7 @@ static void dump_args(const mp_obj_t *a, size_t sz) { #if MICROPY_STACKLESS mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - MP_STACK_CHECK(); + mp_cstack_check(); mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); size_t n_state, state_size; @@ -229,7 +258,7 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args // CIRCUITPY-CHANGE: PLACE_IN_ITCM static mp_obj_t PLACE_IN_ITCM(fun_bc_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - MP_STACK_CHECK(); + mp_cstack_check(); DEBUG_printf("Input n_args: " UINT_FMT ", n_kw: " UINT_FMT "\n", n_args, n_kw); DEBUG_printf("Input pos args: "); @@ -342,9 +371,29 @@ void mp_obj_fun_bc_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); dest[0] = MP_OBJ_FROM_PTR(self->context->module.globals); } + #if MICROPY_PY_FUNCTION_ATTRS_CODE + if (attr == MP_QSTR___code__) { + const mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); + if ((self->base.type == &mp_type_fun_bc + || self->base.type == &mp_type_gen_wrap) + && self->child_table == NULL) { + #if MICROPY_PY_BUILTINS_CODE <= MICROPY_PY_BUILTINS_CODE_BASIC + dest[0] = mp_obj_new_code(self->context->constants, self->bytecode); + #else + dest[0] = mp_obj_new_code(self->context, self->rc, true); + #endif + } + } + #endif } #endif +#if MICROPY_PY_FUNCTION_ATTRS_CODE +#define FUN_BC_MAKE_NEW make_new, fun_bc_make_new, +#else +#define FUN_BC_MAKE_NEW +#endif + #if MICROPY_CPYTHON_COMPAT #define FUN_BC_TYPE_PRINT print, fun_bc_print, #else @@ -361,6 +410,7 @@ MP_DEFINE_CONST_OBJ_TYPE( mp_type_fun_bc, MP_QSTR_function, MP_TYPE_FLAG_BINDS_SELF, + FUN_BC_MAKE_NEW FUN_BC_TYPE_PRINT FUN_BC_TYPE_ATTR call, fun_bc_call @@ -402,7 +452,7 @@ mp_obj_t mp_obj_new_fun_bc(const mp_obj_t *def_args, const byte *code, const mp_ // CIRCUITPY-CHANGE: PLACE_IN_ITCM static mp_obj_t PLACE_IN_ITCM(fun_native_call)(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - MP_STACK_CHECK(); + mp_cstack_check(); mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); mp_call_fun_t fun = mp_obj_fun_native_get_function_start(self); return fun(self_in, n_args, n_kw, args); @@ -436,7 +486,7 @@ MP_DEFINE_CONST_OBJ_TYPE( #if MICROPY_EMIT_NATIVE static mp_obj_t fun_viper_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - MP_STACK_CHECK(); + mp_cstack_check(); mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in); mp_call_fun_t fun = MICROPY_MAKE_POINTER_CALLABLE((void *)self->bytecode); return fun(self_in, n_args, n_kw, args); diff --git a/py/objgenerator.c b/py/objgenerator.c index fa59313998f..de063d38458 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -33,7 +33,7 @@ #include "py/objstr.h" #include "py/objgenerator.h" #include "py/objfun.h" -#include "py/stackctrl.h" +#include "py/cstack.h" // Instance of GeneratorExit exception - needed by generator.close() // CIRCUITPY-CHANGE: https://github.com/adafruit/circuitpython/pull/7069 fix @@ -205,7 +205,7 @@ static void coro_instance_print(const mp_print_t *print, mp_obj_t self_in, mp_pr #endif mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) { - MP_STACK_CHECK(); + mp_cstack_check(); // CIRCUITPY-CHANGE // note that self may have as its type either gen or coro, // both of which are stored as an mp_obj_gen_instance_t . diff --git a/py/objint.c b/py/objint.c index 197625ced81..cabbd7b8f0e 100644 --- a/py/objint.c +++ b/py/objint.c @@ -55,7 +55,7 @@ static mp_obj_t mp_obj_int_make_new(const mp_obj_type_t *type_in, size_t n_args, return o; } else if (mp_get_buffer(args[0], &bufinfo, MP_BUFFER_READ)) { // a textual representation, parse it - return mp_parse_num_integer(bufinfo.buf, bufinfo.len, 0, NULL); + return mp_parse_num_integer(bufinfo.buf, bufinfo.len, 10, NULL); #if MICROPY_PY_BUILTINS_FLOAT } else if (mp_obj_is_float(args[0])) { return mp_obj_new_int_from_float(mp_obj_float_get(args[0])); @@ -117,9 +117,15 @@ static mp_fp_as_int_class_t mp_classify_fp_as_int(mp_float_t val) { } // 8 * sizeof(uintptr_t) counts the number of bits for a small int // TODO provide a way to configure this properly + #if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_B + if (e <= ((8 * sizeof(uintptr_t) + MP_FLOAT_EXP_BIAS - 4) << MP_FLOAT_EXP_SHIFT_I32)) { + return MP_FP_CLASS_FIT_SMALLINT; + } + #else if (e <= ((8 * sizeof(uintptr_t) + MP_FLOAT_EXP_BIAS - 3) << MP_FLOAT_EXP_SHIFT_I32)) { return MP_FP_CLASS_FIT_SMALLINT; } + #endif #if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_LONGLONG if (e <= (((sizeof(long long) * MP_BITS_PER_BYTE) + MP_FLOAT_EXP_BIAS - 2) << MP_FLOAT_EXP_SHIFT_I32)) { return MP_FP_CLASS_FIT_LONGINT; @@ -211,7 +217,7 @@ static const uint8_t log_base2_floor[] = { size_t mp_int_format_size(size_t num_bits, int base, const char *prefix, char comma) { assert(2 <= base && base <= 16); size_t num_digits = num_bits / log_base2_floor[base - 1] + 1; - size_t num_commas = comma ? num_digits / 3 : 0; + size_t num_commas = comma ? (base == 10 ? num_digits / 3 : num_digits / 4): 0; size_t prefix_len = prefix ? strlen(prefix) : 0; return num_digits + num_commas + prefix_len + 2; // +1 for sign, +1 for null byte } @@ -249,10 +255,11 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co char sign = '\0'; if (num < 0) { - num = -num; + num = -(fmt_uint_t)num; sign = '-'; } + int n_comma = (base == 10) ? 3 : 4; size_t needed_size = mp_int_format_size(sizeof(fmt_int_t) * 8, base, prefix, comma); if (needed_size > *buf_size) { *buf = m_new(char, needed_size); @@ -277,7 +284,7 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co c += '0'; } *(--b) = c; - if (comma && num != 0 && b > str && (last_comma - b) == 3) { + if (comma && num != 0 && b > str && (last_comma - b) == n_comma) { *(--b) = comma; last_comma = b; } @@ -308,7 +315,7 @@ char *mp_obj_int_formatted(char **buf, size_t *buf_size, size_t *fmt_size, mp_co void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_signed) { if (is_signed) { // self must be < 2**(bits - 1) - mp_obj_t edge = mp_binary_op(MP_BINARY_OP_INPLACE_LSHIFT, + mp_obj_t edge = mp_binary_op(MP_BINARY_OP_LSHIFT, mp_obj_new_int(1), mp_obj_new_int(nbytes * 8 - 1)); @@ -323,7 +330,7 @@ void mp_obj_int_buffer_overflow_check(mp_obj_t self_in, size_t nbytes, bool is_s // self must be >= 0 if (mp_obj_int_sign(self_in) >= 0) { // and < 2**(bits) - mp_obj_t edge = mp_binary_op(MP_BINARY_OP_INPLACE_LSHIFT, + mp_obj_t edge = mp_binary_op(MP_BINARY_OP_LSHIFT, mp_obj_new_int(1), mp_obj_new_int(nbytes * 8)); @@ -490,7 +497,8 @@ static mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *pos_args, mp_map_t enum { ARG_bytes, ARG_byteorder, ARG_signed }; static const mp_arg_t allowed_args[] = { { MP_QSTR_bytes, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = NULL} }, - { MP_QSTR_byteorder, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = NULL} }, + // CIRCUITPY-CHANGE: not required and given a default value. + { MP_QSTR_byteorder, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_big)} }, { MP_QSTR_signed, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -527,15 +535,17 @@ static mp_obj_t int_from_bytes(size_t n_args, const mp_obj_t *pos_args, mp_map_t return mp_obj_new_int_from_uint(value); } -static MP_DEFINE_CONST_FUN_OBJ_KW(int_from_bytes_fun_obj, 3, int_from_bytes); +// CIRCUITPY-CHANGE: only two required args. +static MP_DEFINE_CONST_FUN_OBJ_KW(int_from_bytes_fun_obj, 2, int_from_bytes); static MP_DEFINE_CONST_CLASSMETHOD_OBJ(int_from_bytes_obj, MP_ROM_PTR(&int_from_bytes_fun_obj)); // CIRCUITPY-CHANGE: supports signed static mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_length, ARG_byteorder, ARG_signed }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_length, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_byteorder, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_length, MP_ARG_INT, {.u_int = 1} }, + // CIRCUITPY-CHANGE: not required and given a default value. + { MP_QSTR_byteorder, MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_QSTR(MP_QSTR_big)} }, { MP_QSTR_signed, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -575,7 +585,7 @@ static mp_obj_t int_to_bytes(size_t n_args, const mp_obj_t *pos_args, mp_map_t * return mp_obj_new_bytes_from_vstr(&vstr); } -static MP_DEFINE_CONST_FUN_OBJ_KW(int_to_bytes_obj, 3, int_to_bytes); +static MP_DEFINE_CONST_FUN_OBJ_KW(int_to_bytes_obj, 1, int_to_bytes); static const mp_rom_map_elem_t int_locals_dict_table[] = { // CIRCUITPY-CHANGE @@ -588,10 +598,11 @@ static const mp_rom_map_elem_t int_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(int_locals_dict, int_locals_dict_table); +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_int, MP_QSTR_int, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_PRINT_JSON, make_new, mp_obj_int_make_new, print, mp_obj_int_print, unary_op, mp_obj_int_unary_op, diff --git a/py/objint.h b/py/objint.h index b081d659051..92466bae4e2 100644 --- a/py/objint.h +++ b/py/objint.h @@ -64,7 +64,8 @@ mp_int_t mp_obj_int_hash(mp_obj_t self_in); // CIRCUITPY-CHANGE mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in); mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf); -void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf); +// Returns true if 'self_in' fit into 'len' bytes of 'buf' without overflowing, 'buf' is truncated otherwise. +bool mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf); int mp_obj_int_sign(mp_obj_t self_in); mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in); mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in); diff --git a/py/objint_longlong.c b/py/objint_longlong.c index 70d7e2873c5..f24aa0cc186 100644 --- a/py/objint_longlong.c +++ b/py/objint_longlong.c @@ -43,6 +43,10 @@ const mp_obj_int_t mp_sys_maxsize_obj = {{&mp_type_int}, MP_SSIZE_MAX}; #endif +static void raise_long_long_overflow(void) { + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("result overflows long long storage")); +} + // CIRCUITPY-CHANGE: bit_length mp_obj_t mp_obj_int_bit_length_impl(mp_obj_t self_in) { assert(mp_obj_is_type(self_in, &mp_type_int)); @@ -69,10 +73,27 @@ mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf return mp_obj_new_int_from_ll(value); } -void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { +bool mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { assert(mp_obj_is_exact_type(self_in, &mp_type_int)); mp_obj_int_t *self = self_in; long long val = self->val; + size_t slen; // Number of bytes to represent val + + // This logic has a twin in objint.c + if (val > 0) { + slen = (sizeof(long long) * 8 - mp_clzll(val) + 7) / 8; + } else if (val < -1) { + slen = (sizeof(long long) * 8 - mp_clzll(~val) + 8) / 8; + } else { + // clz of 0 is defined, so 0 and -1 map to 0 and 1 + slen = -val; + } + + if (slen > len) { + return false; // Would overflow + // TODO: Determine whether to copy and truncate, as some callers probably expect this...? + } + if (big_endian) { byte *b = buf + len; while (b > buf) { @@ -85,6 +106,7 @@ void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byt val >>= 8; } } + return true; } int mp_obj_int_sign(mp_obj_t self_in) { @@ -114,7 +136,6 @@ mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in) { // small int if the value fits without truncation case MP_UNARY_OP_HASH: return MP_OBJ_NEW_SMALL_INT((mp_int_t)o->val); - case MP_UNARY_OP_POSITIVE: return o_in; case MP_UNARY_OP_NEGATIVE: @@ -141,6 +162,8 @@ mp_obj_t mp_obj_int_unary_op(mp_unary_op_t op, mp_obj_t o_in) { mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { long long lhs_val; long long rhs_val; + bool overflow = false; + long long result; if (mp_obj_is_small_int(lhs_in)) { lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs_in); @@ -153,21 +176,41 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs_in); } else if (mp_obj_is_exact_type(rhs_in, &mp_type_int)) { rhs_val = ((mp_obj_int_t *)rhs_in)->val; + #if MICROPY_PY_BUILTINS_FLOAT + } else if (mp_obj_is_float(rhs_in)) { + return mp_obj_float_binary_op(op, (mp_float_t)lhs_val, rhs_in); + #endif + #if MICROPY_PY_BUILTINS_COMPLEX + } else if (mp_obj_is_type(rhs_in, &mp_type_complex)) { + return mp_obj_complex_binary_op(op, (mp_float_t)lhs_val, 0, rhs_in); + #endif } else { // delegate to generic function to check for extra cases return mp_obj_int_binary_op_extra_cases(op, lhs_in, rhs_in); } + #if MICROPY_PY_BUILTINS_FLOAT + if (op == MP_BINARY_OP_TRUE_DIVIDE || op == MP_BINARY_OP_INPLACE_TRUE_DIVIDE) { + if (rhs_val == 0) { + goto zero_division; + } + return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val); + } + #endif + switch (op) { case MP_BINARY_OP_ADD: case MP_BINARY_OP_INPLACE_ADD: - return mp_obj_new_int_from_ll(lhs_val + rhs_val); + overflow = mp_add_ll_overflow(lhs_val, rhs_val, &result); + break; case MP_BINARY_OP_SUBTRACT: case MP_BINARY_OP_INPLACE_SUBTRACT: - return mp_obj_new_int_from_ll(lhs_val - rhs_val); + overflow = mp_sub_ll_overflow(lhs_val, rhs_val, &result); + break; case MP_BINARY_OP_MULTIPLY: case MP_BINARY_OP_INPLACE_MULTIPLY: - return mp_obj_new_int_from_ll(lhs_val * rhs_val); + overflow = mp_mul_ll_overflow(lhs_val, rhs_val, &result); + break; case MP_BINARY_OP_FLOOR_DIVIDE: case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: if (rhs_val == 0) { @@ -193,9 +236,21 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i case MP_BINARY_OP_LSHIFT: case MP_BINARY_OP_INPLACE_LSHIFT: - return mp_obj_new_int_from_ll(lhs_val << (int)rhs_val); + if (rhs_val < 0) { + // negative shift not allowed + mp_raise_ValueError(MP_ERROR_TEXT("negative shift count")); + } + overflow = rhs_val >= (sizeof(long long) * MP_BITS_PER_BYTE) + || lhs_val > (LLONG_MAX >> rhs_val) + || lhs_val < (LLONG_MIN >> rhs_val); + result = (unsigned long long)lhs_val << rhs_val; + break; case MP_BINARY_OP_RSHIFT: case MP_BINARY_OP_INPLACE_RSHIFT: + if ((int)rhs_val < 0) { + // negative shift not allowed + mp_raise_ValueError(MP_ERROR_TEXT("negative shift count")); + } return mp_obj_new_int_from_ll(lhs_val >> (int)rhs_val); case MP_BINARY_OP_POWER: @@ -207,18 +262,18 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i mp_raise_ValueError(MP_ERROR_TEXT("negative power with no float support")); #endif } - long long ans = 1; - while (rhs_val > 0) { + result = 1; + while (rhs_val > 0 && !overflow) { if (rhs_val & 1) { - ans *= lhs_val; + overflow = mp_mul_ll_overflow(result, lhs_val, &result); } - if (rhs_val == 1) { + if (rhs_val == 1 || overflow) { break; } rhs_val /= 2; - lhs_val *= lhs_val; + overflow = mp_mul_ll_overflow(lhs_val, lhs_val, &lhs_val); } - return mp_obj_new_int_from_ll(ans); + break; } case MP_BINARY_OP_LESS: @@ -236,50 +291,39 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i return MP_OBJ_NULL; // op not supported } + if (overflow) { + raise_long_long_overflow(); + } + + return mp_obj_new_int_from_ll(result); + zero_division: - mp_raise_ZeroDivisionError(); + mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("divide by zero")); } mp_obj_t mp_obj_new_int(mp_int_t value) { - if (MP_SMALL_INT_FITS(value)) { - return MP_OBJ_NEW_SMALL_INT(value); - } return mp_obj_new_int_from_ll(value); } mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value) { - // SMALL_INT accepts only signed numbers, so make sure the input - // value fits completely in the small-int positive range. - if ((value & ~MP_SMALL_INT_POSITIVE_MASK) == 0) { - return MP_OBJ_NEW_SMALL_INT(value); - } return mp_obj_new_int_from_ll(value); } mp_obj_t mp_obj_new_int_from_ll(long long val) { + if ((long long)(mp_int_t)val == val && MP_SMALL_INT_FITS(val)) { + return MP_OBJ_NEW_SMALL_INT(val); + } + mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); o->val = val; - return o; + return MP_OBJ_FROM_PTR(o); } mp_obj_t mp_obj_new_int_from_ull(unsigned long long val) { - // TODO raise an exception if the unsigned long long won't fit if (val >> (sizeof(unsigned long long) * 8 - 1) != 0) { - mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("ulonglong too large")); + raise_long_long_overflow(); } - mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); - o->val = val; - return o; -} - -mp_obj_t mp_obj_new_int_from_str_len(const char **str, size_t len, bool neg, unsigned int base) { - // TODO this does not honor the given length of the string, but it all cases it should anyway be null terminated - // TODO check overflow - mp_obj_int_t *o = mp_obj_malloc(mp_obj_int_t, &mp_type_int); - char *endptr; - o->val = strtoll(*str, &endptr, base); - *str = endptr; - return o; + return mp_obj_new_int_from_ll(val); } mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) { @@ -292,8 +336,33 @@ mp_int_t mp_obj_int_get_truncated(mp_const_obj_t self_in) { } mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { - // TODO: Check overflow - return mp_obj_int_get_truncated(self_in); + if (mp_obj_is_small_int(self_in)) { + return MP_OBJ_SMALL_INT_VALUE(self_in); + } else { + const mp_obj_int_t *self = self_in; + long long value = self->val; + mp_int_t truncated = (mp_int_t)value; + if ((long long)truncated == value) { + return truncated; + } + } + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word")); +} + +mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) { + if (mp_obj_is_small_int(self_in)) { + if (MP_OBJ_SMALL_INT_VALUE(self_in) >= 0) { + return MP_OBJ_SMALL_INT_VALUE(self_in); + } + } else { + const mp_obj_int_t *self = self_in; + long long value = self->val; + mp_uint_t truncated = (mp_uint_t)value; + if (value >= 0 && (long long)truncated == value) { + return truncated; + } + } + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting long int to machine word")); } #if MICROPY_PY_BUILTINS_FLOAT diff --git a/py/objint_mpz.c b/py/objint_mpz.c index 7bdeb364d87..1bede811a4a 100644 --- a/py/objint_mpz.c +++ b/py/objint_mpz.c @@ -119,10 +119,10 @@ mp_obj_t mp_obj_int_from_bytes_impl(bool big_endian, size_t len, const byte *buf return MP_OBJ_FROM_PTR(o); } -void mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { +bool mp_obj_int_to_bytes_impl(mp_obj_t self_in, bool big_endian, size_t len, byte *buf) { assert(mp_obj_is_exact_type(self_in, &mp_type_int)); mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); - mpz_as_bytes(&self->mpz, big_endian, len, buf); + return mpz_as_bytes(&self->mpz, big_endian, self->mpz.neg, len, buf); } int mp_obj_int_sign(mp_obj_t self_in) { @@ -320,6 +320,14 @@ mp_obj_t mp_obj_int_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i return MP_OBJ_NULL; // op not supported } + // Check if the result fits in a small-int, and if so just return that. + mp_int_t res_small; + if (mpz_as_int_checked(&res->mpz, &res_small)) { + if (MP_SMALL_INT_FITS(res_small)) { + return MP_OBJ_NEW_SMALL_INT(res_small); + } + } + return MP_OBJ_FROM_PTR(res); } else { @@ -356,9 +364,10 @@ static mpz_t *mp_mpz_for_int(mp_obj_t arg, mpz_t *temp) { mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) { if (!mp_obj_is_int(base) || !mp_obj_is_int(exponent) || !mp_obj_is_int(modulus)) { mp_raise_TypeError(MP_ERROR_TEXT("pow() with 3 arguments requires integers")); + } else if (modulus == MP_OBJ_NEW_SMALL_INT(0)) { + mp_raise_ValueError(MP_ERROR_TEXT("divide by zero")); } else { - mp_obj_t result = mp_obj_new_int_from_ull(0); // Use the _from_ull version as this forces an mpz int - mp_obj_int_t *res_p = (mp_obj_int_t *)MP_OBJ_TO_PTR(result); + mp_obj_int_t *res_p = mp_obj_int_new_mpz(); mpz_t l_temp, r_temp, m_temp; mpz_t *lhs = mp_mpz_for_int(base, &l_temp); @@ -381,7 +390,7 @@ mp_obj_t mp_obj_int_pow3(mp_obj_t base, mp_obj_t exponent, mp_obj_t modulus) { if (mod == &m_temp) { mpz_deinit(mod); } - return result; + return MP_OBJ_FROM_PTR(res_p); } } #endif @@ -438,6 +447,10 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) { const mp_obj_int_t *self = MP_OBJ_TO_PTR(self_in); mp_int_t value; if (mpz_as_int_checked(&self->mpz, &value)) { + // mp_obj_int_t objects should always contain a value that is a large + // integer (if the value fits in a small-int then it should have been + // converted to a small-int object), and so this code-path should never + // be taken in normal circumstances. return value; } else { // overflow diff --git a/py/objlist.c b/py/objlist.c index 475002239ca..a29fc51b104 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -29,7 +29,7 @@ #include "py/objlist.h" #include "py/runtime.h" -#include "py/stackctrl.h" +#include "py/cstack.h" static mp_obj_t mp_obj_new_list_iterator(mp_obj_t list, size_t cur, mp_obj_iter_buf_t *iter_buf); static mp_obj_list_t *list_new(size_t n); @@ -118,7 +118,7 @@ static mp_obj_t list_unary_op(mp_unary_op_t op, mp_obj_t self_in) { } static mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: allow subclassing mp_obj_list_t *o = native_list(lhs); switch (op) { case MP_BINARY_OP_ADD: { @@ -142,7 +142,7 @@ static mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { if (n < 0) { n = 0; } - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: overflow check (PR#1279) size_t new_len = mp_seq_multiply_len(o->len, n); mp_obj_list_t *s = list_new(new_len); mp_seq_multiply(o->items, sizeof(*o->items), o->len, n, s->items); @@ -171,76 +171,66 @@ static mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } static mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { - // CIRCUITPY-CHANGE - mp_obj_list_t *self = native_list(self_in); - if (value == MP_OBJ_NULL) { - // delete - #if MICROPY_PY_BUILTINS_SLICE - if (mp_obj_is_type(index, &mp_type_slice)) { - mp_bound_slice_t slice; - if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { - mp_raise_NotImplementedError(NULL); + #if MICROPY_PY_BUILTINS_SLICE + if (mp_obj_is_type(index, &mp_type_slice)) { + // CIRCUITPY-CHANGE: handle subclassing + mp_obj_list_t *self = native_list(self_in); + mp_bound_slice_t slice; + bool fast = mp_seq_get_fast_slice_indexes(self->len, index, &slice); + if (value == MP_OBJ_SENTINEL) { + // load + if (!fast) { + return mp_seq_extract_slice(self->items, &slice); } - - mp_int_t len_adj = slice.start - slice.stop; - assert(len_adj <= 0); - mp_seq_replace_slice_no_grow(self->items, self->len, slice.start, slice.stop, self->items /*NULL*/, 0, sizeof(*self->items)); + mp_obj_list_t *res = list_new(slice.stop - slice.start); + mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t); + return MP_OBJ_FROM_PTR(res); + } + // assign/delete + if (value == MP_OBJ_NULL) { + // delete is equivalent to slice assignment of an empty sequence + value = mp_const_empty_tuple; + } + if (!fast) { + mp_raise_NotImplementedError(NULL); + } + size_t value_len; + mp_obj_t *value_items; + mp_obj_get_array(value, &value_len, &value_items); + mp_int_t len_adj = value_len - (slice.stop - slice.start); + if (len_adj > 0) { + if (self->len + len_adj > self->alloc) { + // TODO: Might optimize memory copies here by checking if block can + // be grown inplace or not + self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + len_adj); + self->alloc = self->len + len_adj; + } + mp_seq_replace_slice_grow_inplace(self->items, self->len, + slice.start, slice.stop, value_items, value_len, len_adj, sizeof(*self->items)); + } else { + mp_seq_replace_slice_no_grow(self->items, self->len, + slice.start, slice.stop, value_items, value_len, sizeof(*self->items)); // Clear "freed" elements at the end of list mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); - self->len += len_adj; - return mp_const_none; + // TODO: apply allocation policy re: alloc_size } - #endif - // CIRCUITPY-CHANGE - mp_obj_t args[2] = {MP_OBJ_FROM_PTR(self), index}; + self->len += len_adj; + return mp_const_none; + } + #endif + if (value == MP_OBJ_NULL) { + // delete + // CIRCUITPY-CHANGE: handle subclassing + mp_obj_t args[2] = {MP_OBJ_FROM_PTR(self_in), index}; list_pop(2, args); return mp_const_none; } else if (value == MP_OBJ_SENTINEL) { // load - #if MICROPY_PY_BUILTINS_SLICE - if (mp_obj_is_type(index, &mp_type_slice)) { - mp_bound_slice_t slice; - if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { - return mp_seq_extract_slice(self->len, self->items, &slice); - } - mp_obj_list_t *res = list_new(slice.stop - slice.start); - mp_seq_copy(res->items, self->items + slice.start, res->len, mp_obj_t); - return MP_OBJ_FROM_PTR(res); - } - #endif + // CIRCUITPY-CHANGE: handle subclassing + mp_obj_list_t *self = native_list(self_in); size_t index_val = mp_get_index(self->base.type, self->len, index, false); return self->items[index_val]; } else { - #if MICROPY_PY_BUILTINS_SLICE - if (mp_obj_is_type(index, &mp_type_slice)) { - size_t value_len; - mp_obj_t *value_items; - mp_obj_get_array(value, &value_len, &value_items); - mp_bound_slice_t slice_out; - if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice_out)) { - mp_raise_NotImplementedError(NULL); - } - mp_int_t len_adj = value_len - (slice_out.stop - slice_out.start); - if (len_adj > 0) { - if (self->len + len_adj > self->alloc) { - // TODO: Might optimize memory copies here by checking if block can - // be grown inplace or not - self->items = m_renew(mp_obj_t, self->items, self->alloc, self->len + len_adj); - self->alloc = self->len + len_adj; - } - mp_seq_replace_slice_grow_inplace(self->items, self->len, - slice_out.start, slice_out.stop, value_items, value_len, len_adj, sizeof(*self->items)); - } else { - mp_seq_replace_slice_no_grow(self->items, self->len, - slice_out.start, slice_out.stop, value_items, value_len, sizeof(*self->items)); - // Clear "freed" elements at the end of list - mp_seq_clear(self->items, self->len + len_adj, self->len, sizeof(*self->items)); - // TODO: apply allocation policy re: alloc_size - } - self->len += len_adj; - return mp_const_none; - } - #endif mp_obj_list_store(self_in, index, value); return mp_const_none; } @@ -252,7 +242,7 @@ static mp_obj_t list_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) { mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: handle subclassing mp_obj_list_t *self = native_list(self_in); if (self->len >= self->alloc) { self->items = m_renew(mp_obj_t, self->items, self->alloc, self->alloc * 2); @@ -266,7 +256,7 @@ mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg) { static mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in) { mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); if (mp_obj_is_type(arg_in, &mp_type_list)) { - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: handle subclassing mp_obj_list_t *self = native_list(self_in); mp_obj_list_t *arg = native_list(arg_in); @@ -285,7 +275,7 @@ static mp_obj_t list_extend(mp_obj_t self_in, mp_obj_t arg_in) { return mp_const_none; // return None, as per CPython } -// CIRCUITPY-CHANGE: used elsewhere so not static; impl is different +// CIRCUITPY-CHANGE: provide version for C use outside this file inline mp_obj_t mp_obj_list_pop(mp_obj_list_t *self, size_t index) { if (self->len == 0) { // CIRCUITPY-CHANGE: more specific mp_raise @@ -303,18 +293,28 @@ inline mp_obj_t mp_obj_list_pop(mp_obj_list_t *self, size_t index) { return ret; } -// CIRCUITPY-CHANGE static mp_obj_t list_pop(size_t n_args, const mp_obj_t *args) { mp_check_self(mp_obj_is_type(args[0], &mp_type_list)); mp_obj_list_t *self = native_list(args[0]); size_t index = mp_get_index(self->base.type, self->len, n_args == 1 ? MP_OBJ_NEW_SMALL_INT(-1) : args[1], false); + // CIRCUITPY-CHANGE: use factored-out pop code return mp_obj_list_pop(self, index); } +// "head" is actually the *exclusive lower bound* of the range to sort. That is, +// the first element to be sorted is `head[1]`, not `head[0]`. Similarly `tail` +// is an *inclusive upper bound* of the range to sort. That is, the final +// element to sort is `tail[0]`, not `tail[-1]`. +// +// The pivot element is always chosen as `tail[0]`. +// +// These unusual choices allows structuring the partitioning +// process as a do/while loop, which generates smaller code than the equivalent +// code with usual C bounds & a while or for loop. static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, mp_obj_t binop_less_result) { - MP_STACK_CHECK(); - while (head < tail) { - mp_obj_t *h = head - 1; + mp_cstack_check(); + while (tail - head > 1) { // So long as at least 2 elements remain + mp_obj_t *h = head; mp_obj_t *t = tail; mp_obj_t v = key_fn == MP_OBJ_NULL ? tail[0] : mp_call_function_1(key_fn, tail[0]); // get pivot using key_fn for (;;) { @@ -325,19 +325,21 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, mp_obj if (h >= t) { break; } + // A pair of objects must be swapped to the other side of the partition mp_obj_t x = h[0]; h[0] = t[0]; t[0] = x; } + // Place the pivot element in the proper position mp_obj_t x = h[0]; h[0] = tail[0]; tail[0] = x; // do the smaller recursive call first, to keep stack within O(log(N)) - if (t - head < tail - h - 1) { + if (t - head < tail - h) { mp_quicksort(head, t, key_fn, binop_less_result); - head = h + 1; + head = h; } else { - mp_quicksort(h + 1, tail, key_fn, binop_less_result); + mp_quicksort(h, tail, key_fn, binop_less_result); tail = t; } } @@ -362,7 +364,7 @@ mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ mp_obj_list_t *self = native_list(pos_args[0]); if (self->len > 1) { - mp_quicksort(self->items, self->items + self->len - 1, + mp_quicksort(self->items - 1, self->items + self->len - 1, args.key.u_obj == mp_const_none ? MP_OBJ_NULL : args.key.u_obj, args.reverse.u_bool ? mp_const_false : mp_const_true); } @@ -370,10 +372,10 @@ mp_obj_t mp_obj_list_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_ return mp_const_none; } -// CIRCUITPY-CHANGE: used elsewhere so not static +// CIRCUITPY-CHANGE: rename and make not static for use elsewhere mp_obj_t mp_obj_list_clear(mp_obj_t self_in) { mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: handle subclassing mp_obj_list_t *self = native_list(self_in); self->len = 0; self->items = m_renew(mp_obj_t, self->items, self->alloc, LIST_MIN_ALLOC); @@ -384,27 +386,28 @@ mp_obj_t mp_obj_list_clear(mp_obj_t self_in) { static mp_obj_t list_copy(mp_obj_t self_in) { mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: handle subclassing mp_obj_list_t *self = native_list(self_in); return mp_obj_new_list(self->len, self->items); } static mp_obj_t list_count(mp_obj_t self_in, mp_obj_t value) { mp_check_self(mp_obj_is_type(self_in, &mp_type_list)); - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: handle subclassing mp_obj_list_t *self = native_list(self_in); return mp_seq_count_obj(self->items, self->len, value); } static mp_obj_t list_index(size_t n_args, const mp_obj_t *args) { mp_check_self(mp_obj_is_type(args[0], &mp_type_list)); - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: handle subclassing mp_obj_list_t *self = native_list(args[0]); return mp_seq_index_obj(self->items, self->len, n_args, args); } -// CIRCUITPY-CHANGE: used elsewhere so not static -inline void mp_obj_list_insert(mp_obj_list_t *self, size_t index, mp_obj_t obj) { +// CIRCUITPY-CHANGE: factor out for C use elsewhere; not meant to emulate Python API +inline void mp_obj_list_insert(mp_obj_list_t *self_in, size_t index, mp_obj_t obj) { + mp_obj_list_t *self = native_list(self_in); mp_obj_list_append(MP_OBJ_FROM_PTR(self), mp_const_none); for (size_t i = self->len - 1; i > index; --i) { @@ -428,7 +431,7 @@ static mp_obj_t list_insert(mp_obj_t self_in, mp_obj_t idx, mp_obj_t obj) { if ((size_t)index > self->len) { index = self->len; } - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: use factored-out insert code mp_obj_list_insert(self, index, obj); return mp_const_none; } @@ -485,10 +488,11 @@ static const mp_rom_map_elem_t list_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(list_locals_dict, list_locals_dict_table); +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_list, MP_QSTR_list, - MP_TYPE_FLAG_ITER_IS_GETITER, + MP_TYPE_FLAG_ITER_IS_GETITER | MP_TYPE_FLAG_PRINT_JSON, make_new, mp_obj_list_make_new, print, list_print, unary_op, list_unary_op, @@ -503,12 +507,14 @@ void mp_obj_list_init(mp_obj_list_t *o, size_t n) { o->base.type = &mp_type_list; o->alloc = n < LIST_MIN_ALLOC ? LIST_MIN_ALLOC : n; o->len = n; - o->items = m_new(mp_obj_t, o->alloc); + // CIRCUITPY-CHANGE: Use m_malloc_items because these are mp_obj_t + o->items = m_malloc_items(o->alloc); mp_seq_clear(o->items, n, o->alloc, sizeof(*o->items)); } static mp_obj_list_t *list_new(size_t n) { - mp_obj_list_t *o = m_new_obj(mp_obj_list_t); + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_obj_list_t *o = mp_obj_malloc(mp_obj_list_t, &mp_type_list); mp_obj_list_init(o, n); return o; } diff --git a/py/objmap.c b/py/objmap.c index 1911a7510ab..d8042f867c7 100644 --- a/py/objmap.c +++ b/py/objmap.c @@ -50,7 +50,8 @@ static mp_obj_t map_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_ static mp_obj_t map_iternext(mp_obj_t self_in) { mp_check_self(mp_obj_is_type(self_in, &mp_type_map)); mp_obj_map_t *self = MP_OBJ_TO_PTR(self_in); - mp_obj_t *nextses = m_new(mp_obj_t, self->n_iters); + // CIRCUITPY-CHANGE: Use m_malloc_items because it is an array of objects + mp_obj_t *nextses = m_malloc_items(self->n_iters); for (size_t i = 0; i < self->n_iters; i++) { mp_obj_t next = mp_iternext(self->iters[i]); diff --git a/py/objmodule.c b/py/objmodule.c index 881ab5e6b25..84b6a10f9ab 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -34,11 +34,6 @@ #include "py/runtime.h" #include "py/builtin.h" -// CIRCUITPY-CHANGE -#if CIRCUITPY_WARNINGS -#include "shared-module/warnings/__init__.h" -#endif - static void module_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); @@ -49,7 +44,7 @@ static void module_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kin module_name = mp_obj_str_get_str(elem->value); } - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ // If we store __file__ to imported modules then try to lookup this // symbol to give more information about the module. elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(MP_QSTR___file__), MP_MAP_LOOKUP); @@ -67,33 +62,6 @@ static void module_attr_try_delegation(mp_obj_t self_in, qstr attr, mp_obj_t *de static void module_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { mp_obj_module_t *self = MP_OBJ_TO_PTR(self_in); if (dest[0] == MP_OBJ_NULL) { - // CIRCUITPY-CHANGE - #if CIRCUITPY_8_9_WARNINGS && CIRCUITPY_DISPLAYIO && CIRCUITPY_WARNINGS - if (self == &displayio_module) { - #if CIRCUITPY_BUSDISPLAY - if (attr == MP_QSTR_Display) { - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_Display, MP_QSTR_displayio, MP_QSTR_busdisplay); - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q renamed %q"), MP_QSTR_Display, MP_QSTR_BusDisplay); - } - #endif - #if CIRCUITPY_EPAPERDISPLAY - if (attr == MP_QSTR_EPaperDisplay) { - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_EPaperDisplay, MP_QSTR_displayio, MP_QSTR_epaperdisplay); - } - #endif - #if CIRCUITPY_FOURWIRE - if (attr == MP_QSTR_FourWire) { - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_FourWire, MP_QSTR_displayio, MP_QSTR_fourwire); - } - #endif - #if CIRCUITPY_I2CDISPLAYBUS - if (attr == MP_QSTR_I2CDisplay) { - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_I2CDisplay, MP_QSTR_displayio, MP_QSTR_i2cdisplaybus); - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q renamed %q"), MP_QSTR_I2CDisplay, MP_QSTR_I2CDisplayBus); - } - #endif - } - #endif // load attribute mp_map_elem_t *elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); if (elem != NULL) { @@ -161,8 +129,8 @@ mp_obj_t mp_obj_new_module(qstr module_name) { } // create new module object - mp_module_context_t *o = m_new_obj(mp_module_context_t); - o->module.base.type = &mp_type_module; + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_module_context_t *o = mp_obj_malloc(mp_module_context_t, &mp_type_module); o->module.globals = MP_OBJ_TO_PTR(mp_obj_new_dict(MICROPY_MODULE_DICT_SIZE)); // store __name__ entry in the module @@ -184,11 +152,13 @@ static const mp_rom_map_elem_t mp_builtin_module_table[] = { }; MP_DEFINE_CONST_MAP(mp_builtin_module_map, mp_builtin_module_table); +#if MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES static const mp_rom_map_elem_t mp_builtin_extensible_module_table[] = { // built-in modules declared with MP_REGISTER_EXTENSIBLE_MODULE() MICROPY_REGISTERED_EXTENSIBLE_MODULES }; MP_DEFINE_CONST_MAP(mp_builtin_extensible_module_map, mp_builtin_extensible_module_table); +#endif #if MICROPY_MODULE_ATTR_DELEGATION && defined(MICROPY_MODULE_DELEGATIONS) typedef struct _mp_module_delegation_entry_t { @@ -205,13 +175,13 @@ static const mp_module_delegation_entry_t mp_builtin_module_delegation_table[] = // Attempts to find (and initialise) a built-in, otherwise returns // MP_OBJ_NULL. mp_obj_t mp_module_get_builtin(qstr module_name, bool extensible) { - // CIRCUITPY-CHANGE - #if CIRCUITPY_PARALLELDISPLAYBUS && CIRCUITPY_WARNINGS - if (module_name == MP_QSTR_paralleldisplay) { - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q renamed %q"), MP_QSTR_paralleldisplay, MP_QSTR_paralleldisplaybus); - } + #if MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES + const mp_map_t *map = extensible ? &mp_builtin_extensible_module_map : &mp_builtin_module_map; + #else + const mp_map_t *map = &mp_builtin_module_map; #endif - mp_map_elem_t *elem = mp_map_lookup((mp_map_t *)(extensible ? &mp_builtin_extensible_module_map : &mp_builtin_module_map), MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); + mp_map_elem_t *elem = mp_map_lookup((mp_map_t *)map, MP_OBJ_NEW_QSTR(module_name), MP_MAP_LOOKUP); + if (!elem) { #if MICROPY_PY_SYS // Special case for sys, which isn't extensible but can always be @@ -221,6 +191,7 @@ mp_obj_t mp_module_get_builtin(qstr module_name, bool extensible) { } #endif + #if MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES if (extensible) { // At this point we've already tried non-extensible built-ins, the // filesystem, and now extensible built-ins. No match, so fail @@ -237,6 +208,7 @@ mp_obj_t mp_module_get_builtin(qstr module_name, bool extensible) { // the old behaviour of the u-prefix being used to force a built-in // import. // CIRCUITPY-CHANGE: Don't look for `ufoo`. + #endif return MP_OBJ_NULL; } diff --git a/py/objmodule.h b/py/objmodule.h index 8b14cd9fc3d..221392ccce4 100644 --- a/py/objmodule.h +++ b/py/objmodule.h @@ -32,10 +32,16 @@ // Only include module definitions when not doing qstr extraction, because the // qstr extraction stage also generates this module definition header file. #include "genhdr/moduledefs.h" +// CIRCUITPY-CHANGE: avoid undef warning +#else +#define MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES (0) #endif extern const mp_map_t mp_builtin_module_map; + +#if MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES extern const mp_map_t mp_builtin_extensible_module_map; +#endif mp_obj_t mp_module_get_builtin(qstr module_name, bool extensible); diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index b6bbe6e05d8..d687dbfda59 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -73,7 +73,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(namedtuple_asdict_obj, namedtuple_asdict); void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_obj_namedtuple_t *o = MP_OBJ_TO_PTR(o_in); - mp_printf(print, "%q", o->tuple.base.type->name); + mp_printf(print, "%q", (qstr)o->tuple.base.type->name); const qstr *fields = ((mp_obj_namedtuple_type_t *)o->tuple.base.type)->fields; mp_obj_attrtuple_print_helper(print, fields, &o->tuple); } diff --git a/py/objnone.c b/py/objnone.c index a8ce8ebfedf..1e2016abd9f 100644 --- a/py/objnone.c +++ b/py/objnone.c @@ -43,10 +43,11 @@ static void none_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_ } } +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_NoneType, MP_QSTR_NoneType, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_PRINT_JSON, print, none_print ); diff --git a/py/objproperty.c b/py/objproperty.c index a3a13a71bb3..96563f6dba3 100644 --- a/py/objproperty.c +++ b/py/objproperty.c @@ -57,7 +57,8 @@ static mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size } static mp_obj_t property_getter(mp_obj_t self_in, mp_obj_t getter) { - mp_obj_property_t *p2 = m_new_obj(mp_obj_property_t); + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_obj_property_t *p2 = mp_obj_malloc(mp_obj_property_t, &mp_type_property); *p2 = *(mp_obj_property_t *)MP_OBJ_TO_PTR(self_in); p2->proxy[0] = getter; return MP_OBJ_FROM_PTR(p2); @@ -66,7 +67,8 @@ static mp_obj_t property_getter(mp_obj_t self_in, mp_obj_t getter) { static MP_DEFINE_CONST_FUN_OBJ_2(property_getter_obj, property_getter); static mp_obj_t property_setter(mp_obj_t self_in, mp_obj_t setter) { - mp_obj_property_t *p2 = m_new_obj(mp_obj_property_t); + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_obj_property_t *p2 = mp_obj_malloc(mp_obj_property_t, &mp_type_property); *p2 = *(mp_obj_property_t *)MP_OBJ_TO_PTR(self_in); p2->proxy[1] = setter; return MP_OBJ_FROM_PTR(p2); @@ -75,7 +77,8 @@ static mp_obj_t property_setter(mp_obj_t self_in, mp_obj_t setter) { static MP_DEFINE_CONST_FUN_OBJ_2(property_setter_obj, property_setter); static mp_obj_t property_deleter(mp_obj_t self_in, mp_obj_t deleter) { - mp_obj_property_t *p2 = m_new_obj(mp_obj_property_t); + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_obj_property_t *p2 = mp_obj_malloc(mp_obj_property_t, &mp_type_property); *p2 = *(mp_obj_property_t *)MP_OBJ_TO_PTR(self_in); p2->proxy[2] = deleter; return MP_OBJ_FROM_PTR(p2); diff --git a/py/objrange.c b/py/objrange.c index 8793040eab0..dea9fe5f296 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -33,7 +33,6 @@ typedef struct _mp_obj_range_it_t { mp_obj_base_t base; - // TODO make these values generic objects or something mp_int_t cur; mp_int_t stop; mp_int_t step; @@ -42,9 +41,9 @@ typedef struct _mp_obj_range_it_t { static mp_obj_t range_it_iternext(mp_obj_t o_in) { mp_obj_range_it_t *o = MP_OBJ_TO_PTR(o_in); if ((o->step > 0 && o->cur < o->stop) || (o->step < 0 && o->cur > o->stop)) { - mp_obj_t o_out = MP_OBJ_NEW_SMALL_INT(o->cur); + mp_int_t cur = o->cur; o->cur += o->step; - return o_out; + return mp_obj_new_int(cur); } else { return MP_OBJ_STOP_ITERATION; } @@ -72,7 +71,6 @@ static mp_obj_t mp_obj_new_range_iterator(mp_int_t cur, mp_int_t stop, mp_int_t typedef struct _mp_obj_range_t { mp_obj_base_t base; - // TODO make these values generic objects or something mp_int_t start; mp_int_t stop; mp_int_t step; @@ -135,7 +133,7 @@ static mp_obj_t range_unary_op(mp_unary_op_t op, mp_obj_t self_in) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len > 0); case MP_UNARY_OP_LEN: - return MP_OBJ_NEW_SMALL_INT(len); + return mp_obj_new_int(len); default: return MP_OBJ_NULL; // op not supported } @@ -167,20 +165,16 @@ static mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { #if MICROPY_PY_BUILTINS_SLICE if (mp_obj_is_type(index, &mp_type_slice)) { mp_bound_slice_t slice; - mp_seq_get_fast_slice_indexes(len, index, &slice); + mp_obj_slice_indices(index, len, &slice); mp_obj_range_t *o = mp_obj_malloc(mp_obj_range_t, &mp_type_range); o->start = self->start + slice.start * self->step; o->stop = self->start + slice.stop * self->step; o->step = slice.step * self->step; - if (slice.step < 0) { - // Negative slice steps have inclusive stop, so adjust for exclusive - o->stop -= self->step; - } return MP_OBJ_FROM_PTR(o); } #endif size_t index_val = mp_get_index(self->base.type, len, index, false); - return MP_OBJ_NEW_SMALL_INT(self->start + index_val * self->step); + return mp_obj_new_int(self->start + index_val * self->step); } else { return MP_OBJ_NULL; // op not supported } diff --git a/py/objringio.c b/py/objringio.c new file mode 100644 index 00000000000..0025b26be3b --- /dev/null +++ b/py/objringio.c @@ -0,0 +1,127 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Andrew Leech + * + * 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. + */ + +#include "ringbuf.h" +#include "py/mpconfig.h" + +#if MICROPY_PY_MICROPYTHON_RINGIO + +#include "py/runtime.h" +#include "py/stream.h" + +typedef struct _micropython_ringio_obj_t { + mp_obj_base_t base; + ringbuf_t ringbuffer; +} micropython_ringio_obj_t; + +static mp_obj_t micropython_ringio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, 1, false); + mp_buffer_info_t bufinfo = {NULL, 0, 0}; + + if (!mp_get_buffer(args[0], &bufinfo, MP_BUFFER_RW)) { + bufinfo.len = mp_obj_get_int(args[0]) + 1; + bufinfo.buf = m_new(uint8_t, bufinfo.len); + } + if (bufinfo.len < 2 || bufinfo.len > UINT16_MAX) { + mp_raise_ValueError(NULL); + } + micropython_ringio_obj_t *self = mp_obj_malloc(micropython_ringio_obj_t, type); + self->ringbuffer.buf = bufinfo.buf; + self->ringbuffer.size = bufinfo.len; + self->ringbuffer.iget = self->ringbuffer.iput = 0; + return MP_OBJ_FROM_PTR(self); +} + +static mp_uint_t micropython_ringio_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + micropython_ringio_obj_t *self = MP_OBJ_TO_PTR(self_in); + size = MIN(size, ringbuf_avail(&self->ringbuffer)); + ringbuf_memcpy_get_internal(&(self->ringbuffer), buf_in, size); + *errcode = 0; + return size; +} + +static mp_uint_t micropython_ringio_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + micropython_ringio_obj_t *self = MP_OBJ_TO_PTR(self_in); + size = MIN(size, ringbuf_free(&self->ringbuffer)); + ringbuf_memcpy_put_internal(&(self->ringbuffer), buf_in, size); + *errcode = 0; + return size; +} + +static mp_uint_t micropython_ringio_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { + micropython_ringio_obj_t *self = MP_OBJ_TO_PTR(self_in); + switch (request) { + case MP_STREAM_POLL: { + mp_uint_t ret = 0; + if ((arg & MP_STREAM_POLL_RD) && ringbuf_avail(&self->ringbuffer) > 0) { + ret |= MP_STREAM_POLL_RD; + } + if ((arg & MP_STREAM_POLL_WR) && ringbuf_free(&self->ringbuffer) > 0) { + ret |= MP_STREAM_POLL_WR; + } + return ret; + } + case MP_STREAM_CLOSE: + return 0; + } + *errcode = MP_EINVAL; + return MP_STREAM_ERROR; +} + +static mp_obj_t micropython_ringio_any(mp_obj_t self_in) { + micropython_ringio_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(ringbuf_avail(&self->ringbuffer)); +} +static MP_DEFINE_CONST_FUN_OBJ_1(micropython_ringio_any_obj, micropython_ringio_any); + +static const mp_rom_map_elem_t micropython_ringio_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(µpython_ringio_any_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_stream_close_obj) }, + +}; +static MP_DEFINE_CONST_DICT(micropython_ringio_locals_dict, micropython_ringio_locals_dict_table); + +static const mp_stream_p_t ringio_stream_p = { + .read = micropython_ringio_read, + .write = micropython_ringio_write, + .ioctl = micropython_ringio_ioctl, + .is_text = false, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + mp_type_ringio, + MP_QSTR_RingIO, + MP_TYPE_FLAG_NONE, + make_new, micropython_ringio_make_new, + protocol, &ringio_stream_p, + locals_dict, µpython_ringio_locals_dict + ); + +#endif // MICROPY_PY_MICROPYTHON_RINGIO diff --git a/py/objstr.c b/py/objstr.c index 0b2517197a0..bd650bbe18a 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -32,7 +32,8 @@ #include "py/objstr.h" #include "py/objlist.h" #include "py/runtime.h" -#include "py/stackctrl.h" +#include "py/cstack.h" +#include "py/objtuple.h" // CIRCUITPY-CHANGE const char nibble_to_hex_upper[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', @@ -46,7 +47,7 @@ static mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ #endif static mp_obj_t mp_obj_new_bytes_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); -static NORETURN void bad_implicit_conversion(mp_obj_t self_in); +static MP_NORETURN void bad_implicit_conversion(mp_obj_t self_in); static mp_obj_t mp_obj_new_str_type_from_vstr(const mp_obj_type_t *type, vstr_t *vstr); @@ -74,6 +75,26 @@ static void check_is_str_or_bytes(mp_obj_t self_in) { mp_check_self(mp_obj_is_str_or_bytes(self_in)); } +static const byte *get_substring_data(const mp_obj_t obj, size_t n_args, const mp_obj_t *args, size_t *len) { + // Get substring data from obj, using args[0,1] to specify start and end indices. + GET_STR_DATA_LEN(obj, str, str_len); + if (n_args > 0) { + const mp_obj_type_t *self_type = mp_obj_get_type(obj); + const byte *end = str + str_len; + if (n_args > 1 && args[1] != mp_const_none) { + end = str_index_to_ptr(self_type, str, str_len, args[1], true); + } + if (args[0] != mp_const_none) { + str = str_index_to_ptr(self_type, str, str_len, args[0], true); + } + str_len = MAX(end - str, 0); + } + if (len) { + *len = str_len; + } + return str; +} + /******************************************************************************/ /* str */ @@ -352,8 +373,7 @@ mp_obj_t mp_obj_str_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_i mp_obj_t *args = &rhs_in; size_t n_args = 1; mp_obj_t dict = MP_OBJ_NULL; - if (mp_obj_is_type(rhs_in, &mp_type_tuple)) { - // TODO: Support tuple subclasses? + if (mp_obj_is_tuple_compatible(rhs_in)) { mp_obj_tuple_get(rhs_in, &n_args, &args); } else if (mp_obj_is_type(rhs_in, &mp_type_dict)) { dict = rhs_in; @@ -819,37 +839,34 @@ static mp_obj_t str_rindex(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_rindex_obj, 2, 4, str_rindex); -// TODO: (Much) more variety in args -static mp_obj_t str_startswith(size_t n_args, const mp_obj_t *args) { - const mp_obj_type_t *self_type = mp_obj_get_type(args[0]); - GET_STR_DATA_LEN(args[0], str, str_len); - size_t prefix_len; - const char *prefix = mp_obj_str_get_data(args[1], &prefix_len); - const byte *start = str; - if (n_args > 2) { - start = str_index_to_ptr(self_type, str, str_len, args[2], true); +static mp_obj_t str_startendswith(size_t n_args, const mp_obj_t *args, bool ends_with) { + size_t str_len; + const byte *str = get_substring_data(args[0], n_args - 2, args + 2, &str_len); + mp_obj_t *prefixes = (mp_obj_t *)&args[1]; + size_t n_prefixes = 1; + if (mp_obj_is_type(args[1], &mp_type_tuple)) { + mp_obj_tuple_get(args[1], &n_prefixes, &prefixes); } - if (prefix_len + (start - str) > str_len) { - return mp_const_false; + size_t prefix_len; + for (size_t i = 0; i < n_prefixes; i++) { + const char *prefix = mp_obj_str_get_data(prefixes[i], &prefix_len); + const byte *s = str + (ends_with ? str_len - prefix_len : 0); + if (prefix_len <= str_len && memcmp(s, prefix, prefix_len) == 0) { + return mp_const_true; + } } - return mp_obj_new_bool(memcmp(start, prefix, prefix_len) == 0); + return mp_const_false; } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj, 2, 3, str_startswith); -static mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) { - GET_STR_DATA_LEN(args[0], str, str_len); - size_t suffix_len; - const char *suffix = mp_obj_str_get_data(args[1], &suffix_len); - if (n_args > 2) { - mp_raise_NotImplementedError(MP_ERROR_TEXT("start/end indices")); - } +static mp_obj_t str_startswith(size_t n_args, const mp_obj_t *args) { + return str_startendswith(n_args, args, false); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_startswith_obj, 2, 4, str_startswith); - if (suffix_len > str_len) { - return mp_const_false; - } - return mp_obj_new_bool(memcmp(str + (str_len - suffix_len), suffix, suffix_len) == 0); +static mp_obj_t str_endswith(size_t n_args, const mp_obj_t *args) { + return str_startendswith(n_args, args, true); } -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 3, str_endswith); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(str_endswith_obj, 2, 4, str_endswith); enum { LSTRIP, RSTRIP, STRIP }; @@ -1001,7 +1018,7 @@ static mp_obj_t arg_as_int(mp_obj_t arg) { #endif #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE -static NORETURN void terse_str_format_value_error(void) { +static MP_NORETURN void terse_str_format_value_error(void) { mp_raise_ValueError(MP_ERROR_TEXT("bad format string")); } #else @@ -1188,7 +1205,7 @@ static vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar int width = -1; int precision = -1; char type = '\0'; - int flags = 0; + unsigned int flags = 0; if (format_spec) { // The format specifier (from http://docs.python.org/2/library/string.html#formatspec) @@ -1202,7 +1219,7 @@ static vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar // type ::= "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%" // recursively call the formatter to format any nested specifiers - MP_STACK_CHECK(); + mp_cstack_check(); vstr_t format_spec_vstr = mp_obj_str_format_helper(format_spec, str, arg_i, n_args, args, kwargs); const char *s = vstr_null_terminated_str(&format_spec_vstr); const char *stop = s + format_spec_vstr.len; @@ -1233,8 +1250,9 @@ static vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } } s = str_to_int(s, stop, &width); - if (*s == ',') { - flags |= PF_FLAG_SHOW_COMMA; + if (*s == ',' || *s == '_') { + MP_STATIC_ASSERT((unsigned)'_' << PF_FLAG_SEP_POS >> PF_FLAG_SEP_POS == '_'); + flags |= (unsigned)*s << PF_FLAG_SEP_POS; s++; } if (*s == '.') { @@ -1307,7 +1325,7 @@ static vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } case '\0': // No explicit format type implies 'd' - case 'n': // I don't think we support locales in uPy so use 'd' + case 'n': // I don't think we support locales in MicroPython so use 'd' case 'd': mp_print_mp_int(&print, arg, 10, 'a', flags, fill, width, 0); continue; @@ -1503,8 +1521,7 @@ static mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ // Dictionary value lookup if (*str == '(') { if (dict == MP_OBJ_NULL) { - // CIRCUITPY-CHANGE: clearer message - mp_raise_TypeError(MP_ERROR_TEXT("format requires a dict")); + mp_raise_TypeError(MP_ERROR_TEXT("format needs a dict")); } arg_i = 1; // we used up the single dict argument const byte *key = ++str; @@ -1585,8 +1602,7 @@ static mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (arg == MP_OBJ_NULL) { if (arg_i >= n_args) { not_enough_args: - // CIRCUITPY-CHANGE: clearer message - mp_raise_TypeError(MP_ERROR_TEXT("not enough arguments for format string")); + mp_raise_TypeError(MP_ERROR_TEXT("format string needs more arguments")); } arg = args[arg_i++]; } @@ -1596,16 +1612,14 @@ static mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ size_t slen; const char *s = mp_obj_str_get_data(arg, &slen); if (slen != 1) { - // CIRCUITPY-CHANGE: clearer message - mp_raise_TypeError(MP_ERROR_TEXT("%%c requires int or char")); + mp_raise_TypeError(MP_ERROR_TEXT("%%c needs int or char")); } mp_print_strn(&print, s, 1, flags, ' ', width); } else if (arg_looks_integer(arg)) { char ch = mp_obj_get_int(arg); mp_print_strn(&print, &ch, 1, flags, ' ', width); } else { - // CIRCUITPY-CHANGE: clearer message - mp_raise_TypeError(MP_ERROR_TEXT("%%c requires int or char")); + mp_raise_TypeError(MP_ERROR_TEXT("%%c needs int or char")); } break; @@ -1677,8 +1691,7 @@ static mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (dict == MP_OBJ_NULL && arg_i != n_args) { // NOTE: if `dict` exists, then `n_args` is 1 and the dict is always consumed; either // positionally, or as a map of named args, even if none were actually referenced. - // CIRCUITPY-CHANGE: clearer message - mp_raise_TypeError(MP_ERROR_TEXT("not all arguments converted during string formatting")); + mp_raise_TypeError(MP_ERROR_TEXT("format string didn't convert all arguments")); } return mp_obj_new_str_type_from_vstr(is_bytes ? &mp_type_bytes : &mp_type_str, &vstr); @@ -2044,27 +2057,21 @@ mp_obj_t mp_obj_bytes_fromhex(mp_obj_t type_in, mp_obj_t data) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ); - if ((bufinfo.len & 1) != 0) { - mp_raise_ValueError(MP_ERROR_TEXT("odd-length string")); - } vstr_t vstr; vstr_init_len(&vstr, bufinfo.len / 2); byte *in = bufinfo.buf, *out = (byte *)vstr.buf; - byte hex_byte = 0; - for (mp_uint_t i = bufinfo.len; i--;) { - byte hex_ch = *in++; - if (unichar_isxdigit(hex_ch)) { - hex_byte += unichar_xdigit_value(hex_ch); - } else { - mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit found")); + byte *in_end = in + bufinfo.len; + mp_uint_t ch1, ch2; + while (in < in_end) { + if (unichar_isspace(ch1 = *in++)) { + continue; // Skip whitespace between hex digit pairs } - if (i & 1) { - hex_byte <<= 4; - } else { - *out++ = hex_byte; - hex_byte = 0; + if (in == in_end || !unichar_isxdigit(ch1) || !unichar_isxdigit(ch2 = *in++)) { + mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit")); } + *out++ = (byte)((unichar_xdigit_value(ch1) << 4) | unichar_xdigit_value(ch2)); } + vstr.len = out - (byte *)vstr.buf; // Length may be shorter due to whitespace in input return mp_obj_new_str_type_from_vstr(MP_OBJ_TO_PTR(type_in), &vstr); } @@ -2203,10 +2210,11 @@ MP_DEFINE_CONST_DICT_WITH_SIZE(mp_obj_memoryview_locals_dict, #if !MICROPY_PY_BUILTINS_STR_UNICODE static mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_buf); +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_str, MP_QSTR_str, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_PRINT_JSON, make_new, mp_obj_str_make_new, print, str_print, binary_op, mp_obj_str_binary_op, @@ -2341,6 +2349,10 @@ mp_obj_t mp_obj_new_str(const char *data, size_t len) { } } +mp_obj_t mp_obj_new_str_from_cstr(const char *str) { + return mp_obj_new_str(str, strlen(str)); +} + mp_obj_t mp_obj_str_intern(mp_obj_t str) { GET_STR_DATA_LEN(str, data, len); return mp_obj_new_str_via_qstr((const char *)data, len); @@ -2384,7 +2396,7 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) { } } -static NORETURN void bad_implicit_conversion(mp_obj_t self_in) { +static MP_NORETURN void bad_implicit_conversion(mp_obj_t self_in) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't convert to str implicitly")); #else diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 203d3858e60..a158b912365 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -236,10 +236,11 @@ static mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { } } +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_str, MP_QSTR_str, - MP_TYPE_FLAG_ITER_IS_GETITER, + MP_TYPE_FLAG_ITER_IS_GETITER | MP_TYPE_FLAG_PRINT_JSON, make_new, mp_obj_str_make_new, print, uni_print, unary_op, uni_unary_op, diff --git a/py/objtuple.c b/py/objtuple.c index afa80799af5..b2ccbbb2990 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -31,9 +31,6 @@ #include "py/objtuple.h" #include "py/runtime.h" -// type check is done on getiter method to allow tuple, namedtuple, attrtuple -#define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), iter) == mp_obj_tuple_getiter) - /******************************************************************************/ /* tuple */ @@ -86,7 +83,8 @@ static mp_obj_t mp_obj_tuple_make_new(const mp_obj_type_t *type_in, size_t n_arg size_t alloc = 4; size_t len = 0; - mp_obj_t *items = m_new(mp_obj_t, alloc); + // CIRCUITPY-CHANGE + mp_obj_t *items = m_malloc_items(alloc); mp_obj_t iterable = mp_getiter(args[0], NULL); mp_obj_t item; @@ -232,10 +230,11 @@ static const mp_rom_map_elem_t tuple_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(tuple_locals_dict, tuple_locals_dict_table); +// CIRCUITPY-CHANGE: Diagnose json.dump on invalid types MP_DEFINE_CONST_OBJ_TYPE( mp_type_tuple, MP_QSTR_tuple, - MP_TYPE_FLAG_ITER_IS_GETITER, + MP_TYPE_FLAG_ITER_IS_GETITER | MP_TYPE_FLAG_PRINT_JSON, make_new, mp_obj_tuple_make_new, print, mp_obj_tuple_print, unary_op, mp_obj_tuple_unary_op, @@ -248,6 +247,9 @@ MP_DEFINE_CONST_OBJ_TYPE( // the zero-length tuple const mp_obj_tuple_t mp_const_empty_tuple_obj = {{&mp_type_tuple}, 0}; +// CIRCUITPY-CHANGE: No change here, but implementation was copied for +// mp_obj_new_port_tuple in supervisor/shared/port.c, which allocates using port_malloc(). +// Change that to match if this changes. mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items) { if (n == 0) { return mp_const_empty_tuple; diff --git a/py/objtuple.h b/py/objtuple.h index e2d010e6c5a..783522a6222 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -57,7 +57,7 @@ extern const mp_obj_type_t mp_type_attrtuple; #define MP_DEFINE_ATTRTUPLE(tuple_obj_name, fields, nitems, ...) \ const mp_rom_obj_tuple_t tuple_obj_name = { \ - .base = {&mp_type_attrtuple}, \ + .base = {.type = &mp_type_attrtuple}, \ .len = nitems, \ .items = { __VA_ARGS__, MP_ROM_PTR((void *)fields) } \ } @@ -68,4 +68,7 @@ void mp_obj_attrtuple_print_helper(const mp_print_t *print, const qstr *fields, mp_obj_t mp_obj_new_attrtuple(const qstr *fields, size_t n, const mp_obj_t *items); +// type check is done on getiter method to allow tuple, namedtuple, attrtuple +#define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), iter) == mp_obj_tuple_getiter) + #endif // MICROPY_INCLUDED_PY_OBJTUPLE_H diff --git a/py/objtype.c b/py/objtype.c index c2ef10ee9ee..b1a984b50e0 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -44,6 +44,8 @@ #define ENABLE_SPECIAL_ACCESSORS \ (MICROPY_PY_DESCRIPTORS || MICROPY_PY_DELATTR_SETATTR || MICROPY_PY_BUILTINS_PROPERTY) +static mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict); +static mp_obj_t mp_obj_is_subclass(mp_obj_t object, mp_obj_t classinfo); static mp_obj_t static_class_method_make_new(const mp_obj_type_t *self_in, size_t n_args, size_t n_kw, const mp_obj_t *args); /******************************************************************************/ @@ -83,7 +85,7 @@ static int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t } // CIRCUITPY-CHANGE: support superclass constructors that take kw args -// This wrapper function is allows a subclass of a native type to call the +// This wrapper function allows a subclass of a native type to call the // __init__() method (corresponding to type->make_new) of the native type. static mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_obj_instance_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -96,7 +98,8 @@ static mp_obj_t native_base_init_wrapper(size_t n_args, const mp_obj_t *pos_args pos_args++; n_args--; - mp_obj_t *args2 = m_new(mp_obj_t, n_args + 2 * n_kw); + // CIRCUITPY-CHANGE + mp_obj_t *args2 = m_malloc_items(n_args + 2 * n_kw); // copy in args memcpy(args2, pos_args, n_args * sizeof(mp_obj_t)); // copy in kwargs @@ -340,7 +343,8 @@ static mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_arg mp_obj_t args2[1] = {MP_OBJ_FROM_PTR(self)}; new_ret = mp_call_function_n_kw(init_fn[0], 1, 0, args2); } else { - mp_obj_t *args2 = m_new(mp_obj_t, 1 + n_args + 2 * n_kw); + // CIRCUITPY-CHANGE + mp_obj_t *args2 = m_malloc_items(1 + n_args + 2 * n_kw); args2[0] = MP_OBJ_FROM_PTR(self); memcpy(args2 + 1, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t)); new_ret = mp_call_function_n_kw(init_fn[0], n_args + 1, n_kw, args2); @@ -371,7 +375,8 @@ static mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_arg if (n_args == 0 && n_kw == 0) { init_ret = mp_call_method_n_kw(0, 0, init_fn); } else { - mp_obj_t *args2 = m_new(mp_obj_t, 2 + n_args + 2 * n_kw); + // CIRCUITPY-CHANGE + mp_obj_t *args2 = m_malloc_items(2 + n_args + 2 * n_kw); args2[0] = init_fn[0]; args2[1] = init_fn[1]; memcpy(args2 + 2, args, (n_args + 2 * n_kw) * sizeof(mp_obj_t)); @@ -685,6 +690,13 @@ static void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des // try __getattr__ if (attr != MP_QSTR___getattr__) { + #if MICROPY_PY_DESCRIPTORS + // With descriptors enabled, don't delegate lookups of __get__/__set__/__delete__/__set_name__. + if (attr == MP_QSTR___get__ || attr == MP_QSTR___set__ || attr == MP_QSTR___delete__ || attr == MP_QSTR___set_name__) { + return; + } + #endif + #if MICROPY_PY_DELATTR_SETATTR // If the requested attr is __setattr__/__delattr__ then don't delegate the lookup // to __getattr__. If we followed CPython's behaviour then __setattr__/__delattr__ @@ -904,7 +916,8 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not callable")); #else - mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object is not callable"), + // CIRCUITPY-CHANGE: use more specific raise + mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object isn't callable"), mp_obj_get_type_qstr(self_in)); #endif } @@ -984,7 +997,7 @@ static bool check_for_special_accessors(mp_obj_t key, mp_obj_t value) { #endif #if MICROPY_PY_DESCRIPTORS static const uint8_t to_check[] = { - MP_QSTR___get__, MP_QSTR___set__, MP_QSTR___delete__, + MP_QSTR___get__, MP_QSTR___set__, MP_QSTR___delete__, // not needed for MP_QSTR___set_name__ though }; for (size_t i = 0; i < MP_ARRAY_SIZE(to_check); ++i) { mp_obj_t dest_temp[2]; @@ -998,10 +1011,52 @@ static bool check_for_special_accessors(mp_obj_t key, mp_obj_t value) { } #endif +#if MICROPY_PY_DESCRIPTORS +// Shared data layout for the __set_name__ call and a linked list of calls to be made. +typedef union _setname_list_t setname_list_t; +union _setname_list_t { + mp_obj_t call[4]; + struct { + mp_obj_t _meth; + mp_obj_t _self; + setname_list_t *next; // can use the "owner" argument position temporarily for the linked list + mp_obj_t _name; + }; +}; + +// Append any `__set_name__` method on `value` to the setname list, with its per-attr args +static setname_list_t *setname_maybe_bind_append(setname_list_t *tail, mp_obj_t name, mp_obj_t value) { + // make certain our type-punning is safe: + MP_STATIC_ASSERT_NONCONSTEXPR(offsetof(setname_list_t, next) == offsetof(setname_list_t, call[2])); + + // tail is a blank list entry + mp_load_method_maybe(value, MP_QSTR___set_name__, tail->call); + if (tail->call[1] != MP_OBJ_NULL) { + // Each time a __set_name__ is found, leave it in-place in the former tail and allocate a new tail + tail->next = m_new_obj(setname_list_t); + tail->next->next = NULL; + tail->call[3] = name; + return tail->next; + } else { + return tail; + } +} + +// Execute the captured `__set_name__` calls, destroying the setname list in the process. +static inline void setname_consume_call_all(setname_list_t *head, mp_obj_t owner) { + setname_list_t *next; + while ((next = head->next) != NULL) { + head->call[2] = owner; + mp_call_method_n_kw(2, 0, head->call); + head = next; + } +} +#endif + static void type_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in); - mp_printf(print, "", self->name); + mp_printf(print, "", (qstr)self->name); } static mp_obj_t type_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { @@ -1031,11 +1086,10 @@ static mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp if (!MP_OBJ_TYPE_HAS_SLOT(self, make_new)) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE - // CIRCUITPY-CHANGE: error message change - mp_raise_TypeError(MP_ERROR_TEXT("cannot create instance")); + mp_raise_TypeError(MP_ERROR_TEXT("can't create instance")); #else - // CIRCUITPY-CHANGE: error message change - mp_raise_TypeError_varg(MP_ERROR_TEXT("cannot create '%q' instances"), self->name); + // CIRCUITPY-CHANGE: more specific mp_raise + mp_raise_TypeError_varg(MP_ERROR_TEXT("can't create '%q' instances"), self->name); #endif } @@ -1148,7 +1202,7 @@ MP_DEFINE_CONST_OBJ_TYPE( attr, type_attr ); -mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) { +static mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) { // Verify input objects have expected type if (!mp_obj_is_type(bases_tuple, &mp_type_tuple)) { mp_raise_TypeError(NULL); @@ -1176,12 +1230,11 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) // TODO: Verify with CPy, tested on function type if (!MP_OBJ_TYPE_HAS_SLOT(t, make_new)) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE - // CIRCUITPY-CHANGE: error message change - mp_raise_TypeError(MP_ERROR_TEXT("type is not an acceptable base type")); + mp_raise_TypeError(MP_ERROR_TEXT("type isn't an acceptable base type")); #else - // CIRCUITPY-CHANGE: error message change + // CIRCUITPY-CHANGE: more specific mp_raise mp_raise_TypeError_varg( - MP_ERROR_TEXT("type '%q' is not an acceptable base type"), t->name); + MP_ERROR_TEXT("type '%q' isn't an acceptable base type"), t->name); #endif } #if ENABLE_SPECIAL_ACCESSORS @@ -1191,6 +1244,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) base_flags |= t->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS; if (mp_obj_is_instance_type(t)) { t->flags |= MP_TYPE_FLAG_IS_SUBCLASSED; + base_flags |= t->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS; } #endif } @@ -1241,20 +1295,38 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) } } + #if MICROPY_PY_DESCRIPTORS + // To avoid any dynamic allocations when no __set_name__ exists, + // the head of this list is kept on the stack (marked blank with `next = NULL`). + setname_list_t setname_list = { .next = NULL }; + setname_list_t *setname_tail = &setname_list; + #endif + #if ENABLE_SPECIAL_ACCESSORS - // Check if the class has any special accessor methods - if (!(o->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) { - for (size_t i = 0; i < locals_ptr->map.alloc; i++) { - if (mp_map_slot_is_filled(&locals_ptr->map, i)) { - const mp_map_elem_t *elem = &locals_ptr->map.table[i]; - if (check_for_special_accessors(elem->key, elem->value)) { - o->flags |= MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS; - break; - } + // Check if the class has any special accessor methods, + // and accumulate bound __set_name__ methods that need to be called + for (size_t i = 0; i < locals_ptr->map.alloc; i++) { + #if !MICROPY_PY_DESCRIPTORS + // __set_name__ needs to scan the entire locals map, can't early-terminate + if (o->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS) { + break; + } + #endif + + if (mp_map_slot_is_filled(&locals_ptr->map, i)) { + const mp_map_elem_t *elem = &locals_ptr->map.table[i]; + + if (!(o->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS) // elidable when the early-termination check is enabled + && check_for_special_accessors(elem->key, elem->value)) { + o->flags |= MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS; } + + #if MICROPY_PY_DESCRIPTORS + setname_tail = setname_maybe_bind_append(setname_tail, elem->key, elem->value); + #endif } } - #endif + #endif // ENABLE_SPECIAL_ACCESSORS const mp_obj_type_t *native_base; size_t num_native_bases = instance_count_native_bases(o, &native_base); @@ -1262,8 +1334,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_raise_TypeError(MP_ERROR_TEXT("multiple bases have instance lay-out conflict")); } - mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(o, locals_dict)->map; - mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); + mp_map_elem_t *elem = mp_map_lookup(&locals_ptr->map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); if (elem != NULL) { // __new__ slot exists; check if it is a function if (mp_obj_is_fun(elem->value)) { @@ -1272,6 +1343,10 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) } } + #if MICROPY_PY_DESCRIPTORS + setname_consume_call_all(&setname_list, MP_OBJ_FROM_PTR(o)); + #endif + return MP_OBJ_FROM_PTR(o); } @@ -1299,10 +1374,20 @@ static mp_obj_t super_make_new(const mp_obj_type_t *type_in, size_t n_args, size // 0 arguments are turned into 2 in the compiler // 1 argument is not yet implemented mp_arg_check_num(n_args, n_kw, 2, 2, false); + + // CIRCUITPY-CHANGE: check type of first arg if (!mp_obj_is_type(args[0], &mp_type_type)) { - // CIRCUITPY-CHANGE: error message mp_raise_TypeError(MP_ERROR_TEXT("first argument to super() must be type")); } + + // Per CPython: "If the second argument is an object, isinstance(obj, type) must be true. + // If the second argument is a type, issubclass(type2, type) must be true (this is useful for classmethods)." + const mp_obj_type_t *second_arg_type = mp_obj_get_type(args[1]); + mp_obj_t second_arg_obj = second_arg_type == &mp_type_type ? args[1] : MP_OBJ_FROM_PTR(second_arg_type); + if (mp_obj_is_subclass(second_arg_obj, args[0]) == mp_const_false) { + mp_raise_TypeError(NULL); + } + mp_obj_super_t *o = m_new_obj(mp_obj_super_t); *o = (mp_obj_super_t) {{type_in}, args[0], args[1]}; return MP_OBJ_FROM_PTR(o); @@ -1513,13 +1598,15 @@ mp_obj_t mp_obj_cast_to_native_base(mp_obj_t self_in, mp_const_obj_t native_type /******************************************************************************/ // staticmethod and classmethod types (probably should go in a different file) -static mp_obj_t static_class_method_make_new(const mp_obj_type_t *self, size_t n_args, size_t n_kw, const mp_obj_t *args) { - assert(self == &mp_type_staticmethod || self == &mp_type_classmethod); +// CIRCUITPY-CHANGE: better arg name +static mp_obj_t static_class_method_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + assert(type == &mp_type_staticmethod || type == &mp_type_classmethod); mp_arg_check_num(n_args, n_kw, 1, 1, false); - mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t); - *o = (mp_obj_static_class_method_t) {{self}, args[0]}; + // CIRCUITPY-CHANGE: Use mp_obj_malloc because it is a Python object + mp_obj_static_class_method_t *o = mp_obj_malloc(mp_obj_static_class_method_t, type); + o->fun = args[0]; return MP_OBJ_FROM_PTR(o); } diff --git a/py/parse.c b/py/parse.c index 9721532afd6..36150ef468b 100644 --- a/py/parse.c +++ b/py/parse.c @@ -341,18 +341,34 @@ static uint8_t peek_rule(parser_t *parser, size_t n) { } #endif -bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o) { +#if MICROPY_COMP_CONST_FOLDING || MICROPY_EMIT_INLINE_ASM +static bool mp_parse_node_get_number_maybe(mp_parse_node_t pn, mp_obj_t *o) { if (MP_PARSE_NODE_IS_SMALL_INT(pn)) { *o = MP_OBJ_NEW_SMALL_INT(MP_PARSE_NODE_LEAF_SMALL_INT(pn)); return true; } else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn, RULE_const_object)) { mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn; *o = mp_parse_node_extract_const_object(pns); - return mp_obj_is_int(*o); + return mp_obj_is_int(*o) + #if MICROPY_COMP_CONST_FLOAT + || mp_obj_is_float(*o) + #endif + ; } else { return false; } } +#endif + +#if MICROPY_EMIT_INLINE_ASM +bool mp_parse_node_get_int_maybe(mp_parse_node_t pn, mp_obj_t *o) { + return mp_parse_node_get_number_maybe(pn, o) + #if MICROPY_COMP_CONST_FLOAT + && mp_obj_is_int(*o) + #endif + ; +} +#endif #if MICROPY_COMP_CONST_TUPLE || MICROPY_COMP_CONST static bool mp_parse_node_is_const(mp_parse_node_t pn) { @@ -647,18 +663,32 @@ static const mp_rom_map_elem_t mp_constants_table[] = { #if MICROPY_PY_UCTYPES { MP_ROM_QSTR(MP_QSTR_uctypes), MP_ROM_PTR(&mp_module_uctypes) }, #endif + #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_MATH && MICROPY_COMP_CONST_FLOAT + { MP_ROM_QSTR(MP_QSTR_math), MP_ROM_PTR(&mp_module_math) }, + #endif // Extra constants as defined by a port MICROPY_PORT_CONSTANTS }; static MP_DEFINE_CONST_MAP(mp_constants_map, mp_constants_table); #endif -// CIRCUITPY-CHANGE: avoid compiler warning -#if defined(MICROPY_COMP_CONST_FOLDING_COMPILER_WORKAROUND) && MICROPY_COMP_CONST_FOLDING_COMPILER_WORKAROUND -// Some versions of the xtensa-esp32-elf-gcc compiler generate wrong code if this -// function is static, so provide a hook for them to work around this problem. -MP_NOINLINE -#endif +static bool binary_op_maybe(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs, mp_obj_t *res) { + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t tmp = mp_binary_op(op, lhs, rhs); + nlr_pop(); + #if MICROPY_PY_BUILTINS_COMPLEX + if (mp_obj_is_type(tmp, &mp_type_complex)) { + return false; + } + #endif + *res = tmp; + return true; + } else { + return false; + } +} + static bool fold_logical_constants(parser_t *parser, uint8_t rule_id, size_t *num_args) { if (rule_id == RULE_or_test || rule_id == RULE_and_test) { @@ -717,7 +747,7 @@ static bool fold_logical_constants(parser_t *parser, uint8_t rule_id, size_t *nu } static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { - // this code does folding of arbitrary integer expressions, eg 1 + 2 * 3 + 4 + // this code does folding of arbitrary numeric expressions, eg 1 + 2 * 3 + 4 // it does not do partial folding, eg 1 + 2 + x -> 3 + x mp_obj_t arg0; @@ -727,7 +757,7 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { || rule_id == RULE_power) { // folding for binary ops: | ^ & ** mp_parse_node_t pn = peek_result(parser, num_args - 1); - if (!mp_parse_node_get_int_maybe(pn, &arg0)) { + if (!mp_parse_node_get_number_maybe(pn, &arg0)) { return false; } mp_binary_op_t op; @@ -743,58 +773,45 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { for (ssize_t i = num_args - 2; i >= 0; --i) { pn = peek_result(parser, i); mp_obj_t arg1; - if (!mp_parse_node_get_int_maybe(pn, &arg1)) { + if (!mp_parse_node_get_number_maybe(pn, &arg1)) { return false; } - if (op == MP_BINARY_OP_POWER && mp_obj_int_sign(arg1) < 0) { - // ** can't have negative rhs + if (!binary_op_maybe(op, arg0, arg1, &arg0)) { return false; } - arg0 = mp_binary_op(op, arg0, arg1); } } else if (rule_id == RULE_shift_expr || rule_id == RULE_arith_expr || rule_id == RULE_term) { // folding for binary ops: << >> + - * @ / % // mp_parse_node_t pn = peek_result(parser, num_args - 1); - if (!mp_parse_node_get_int_maybe(pn, &arg0)) { + if (!mp_parse_node_get_number_maybe(pn, &arg0)) { return false; } for (ssize_t i = num_args - 2; i >= 1; i -= 2) { pn = peek_result(parser, i - 1); mp_obj_t arg1; - if (!mp_parse_node_get_int_maybe(pn, &arg1)) { + if (!mp_parse_node_get_number_maybe(pn, &arg1)) { return false; } mp_token_kind_t tok = MP_PARSE_NODE_LEAF_ARG(peek_result(parser, i)); - if (tok == MP_TOKEN_OP_AT || tok == MP_TOKEN_OP_SLASH) { - // Can't fold @ or / - return false; - } mp_binary_op_t op = MP_BINARY_OP_LSHIFT + (tok - MP_TOKEN_OP_DBL_LESS); - int rhs_sign = mp_obj_int_sign(arg1); - if (op <= MP_BINARY_OP_RSHIFT) { - // << and >> can't have negative rhs - if (rhs_sign < 0) { - return false; - } - } else if (op >= MP_BINARY_OP_FLOOR_DIVIDE) { - // % and // can't have zero rhs - if (rhs_sign == 0) { - return false; - } + if (!binary_op_maybe(op, arg0, arg1, &arg0)) { + return false; } - arg0 = mp_binary_op(op, arg0, arg1); } } else if (rule_id == RULE_factor_2) { // folding for unary ops: + - ~ mp_parse_node_t pn = peek_result(parser, 0); - if (!mp_parse_node_get_int_maybe(pn, &arg0)) { + if (!mp_parse_node_get_number_maybe(pn, &arg0)) { return false; } mp_token_kind_t tok = MP_PARSE_NODE_LEAF_ARG(peek_result(parser, 1)); mp_unary_op_t op; if (tok == MP_TOKEN_OP_TILDE) { + if (!mp_obj_is_int(arg0)) { + return false; + } op = MP_UNARY_OP_INVERT; } else { assert(tok == MP_TOKEN_OP_PLUS || tok == MP_TOKEN_OP_MINUS); // should be @@ -866,7 +883,7 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { return false; } // id1.id2 - // look it up in constant table, see if it can be replaced with an integer + // look it up in constant table, see if it can be replaced with an integer or a float mp_parse_node_struct_t *pns1 = (mp_parse_node_struct_t *)pn1; assert(MP_PARSE_NODE_IS_ID(pns1->nodes[0])); qstr q_base = MP_PARSE_NODE_LEAF_ARG(pn0); @@ -877,7 +894,7 @@ static bool fold_constants(parser_t *parser, uint8_t rule_id, size_t num_args) { } mp_obj_t dest[2]; mp_load_method_maybe(elem->value, q_attr, dest); - if (!(dest[0] != MP_OBJ_NULL && mp_obj_is_int(dest[0]) && dest[1] == MP_OBJ_NULL)) { + if (!(dest[0] != MP_OBJ_NULL && (mp_obj_is_int(dest[0]) || mp_obj_is_float(dest[0])) && dest[1] == MP_OBJ_NULL)) { return false; } arg0 = dest[0]; @@ -1378,9 +1395,6 @@ mp_parse_tree_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind) { } else if (lex->tok_kind == MP_TOKEN_MALFORMED_FSTRING) { exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, MP_ERROR_TEXT("malformed f-string")); - } else if (lex->tok_kind == MP_TOKEN_FSTRING_RAW) { - exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, - MP_ERROR_TEXT("raw f-strings are not supported")); #endif } else { exc = mp_obj_new_exception_msg(&mp_type_SyntaxError, diff --git a/py/parsenum.c b/py/parsenum.c index 67ac12d1907..c52f040e1a2 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -28,6 +28,7 @@ #include #include "py/runtime.h" +#include "py/misc.h" #include "py/parsenumbase.h" #include "py/parsenum.h" #include "py/smallint.h" @@ -36,7 +37,7 @@ #include #endif -static NORETURN void raise_exc(mp_obj_t exc, mp_lexer_t *lex) { +static MP_NORETURN void raise_exc(mp_obj_t exc, mp_lexer_t *lex) { // if lex!=NULL then the parser called us and we need to convert the // exception's type from ValueError to SyntaxError and add traceback info if (lex != NULL) { @@ -46,6 +47,27 @@ static NORETURN void raise_exc(mp_obj_t exc, mp_lexer_t *lex) { nlr_raise(exc); } +#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_LONGLONG +// For the common small integer parsing case, we parse directly to mp_int_t and +// check that the value doesn't overflow a smallint (in which case we fail over +// to bigint parsing if supported) +typedef mp_int_t parsed_int_t; + +#define PARSED_INT_MUL_OVERFLOW mp_mul_mp_int_t_overflow +#define PARSED_INT_FITS MP_SMALL_INT_FITS +#else +// In the special case where bigint support is long long, we save code size by +// parsing directly to long long and then return either a bigint or smallint +// from the same result. +// +// To avoid pulling in (slow) signed 64-bit math routines we do the initial +// parsing to an unsigned long long and only convert to signed at the end. +typedef unsigned long long parsed_int_t; + +#define PARSED_INT_MUL_OVERFLOW mp_mul_ull_overflow +#define PARSED_INT_FITS(I) ((I) <= (unsigned long long)LLONG_MAX + 1) +#endif + mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, mp_lexer_t *lex) { const byte *restrict str = (const byte *)str_; const byte *restrict top = str + len; @@ -77,7 +99,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m str += mp_parse_num_base((const char *)str, top - str, &base); // string should be an integer number - mp_int_t int_val = 0; + parsed_int_t parsed_val = 0; const byte *restrict str_val_start = str; for (; str < top; str++) { // get next digit as a value @@ -99,25 +121,32 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m break; } - // add next digi and check for overflow - if (mp_small_int_mul_overflow(int_val, base)) { + // add next digit and check for overflow + if (PARSED_INT_MUL_OVERFLOW(parsed_val, base, &parsed_val)) { goto overflow; } - int_val = int_val * base + dig; - if (!MP_SMALL_INT_FITS(int_val)) { + parsed_val += dig; + if (!PARSED_INT_FITS(parsed_val)) { goto overflow; } } - // negate value if needed - if (neg) { - int_val = -int_val; + #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_LONGLONG + // The PARSED_INT_FITS check above ensures parsed_val fits in small int representation + ret_val = MP_OBJ_NEW_SMALL_INT(neg ? (-parsed_val) : parsed_val); +have_ret_val: + #else + // The PARSED_INT_FITS check above ensures parsed_val won't overflow signed long long + long long signed_val = -parsed_val; + if (!neg) { + if (signed_val == LLONG_MIN) { + goto overflow; + } + signed_val = -signed_val; } + ret_val = mp_obj_new_int_from_ll(signed_val); // Could be large or small int + #endif - // create the small int - ret_val = MP_OBJ_NEW_SMALL_INT(int_val); - -have_ret_val: // check we parsed something if (str == str_val_start) { goto value_error; @@ -136,6 +165,7 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m return ret_val; overflow: + #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_LONGLONG // reparse using long int { const char *s2 = (const char *)str_val_start; @@ -143,6 +173,9 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m str = (const byte *)s2; goto have_ret_val; } + #else + mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("result overflows long long storage")); + #endif value_error: { @@ -152,13 +185,13 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m raise_exc(exc, lex); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL mp_obj_t exc = mp_obj_new_exception_msg_varg(&mp_type_ValueError, - MP_ERROR_TEXT("invalid syntax for integer with base %d"), base); + MP_ERROR_TEXT("invalid syntax for integer with base %d"), base == 1 ? 0 : base); raise_exc(exc, lex); #else vstr_t vstr; mp_print_t print; vstr_init_print(&vstr, 50, &print); - mp_printf(&print, "invalid syntax for integer with base %d: ", base); + mp_printf(&print, "invalid syntax for integer with base %d: ", base == 1 ? 0 : base); mp_str_print_quoted(&print, str_val_start, top - str_val_start, true); mp_obj_t exc = mp_obj_new_exception_arg1(&mp_type_ValueError, mp_obj_new_str_from_utf8_vstr(&vstr)); @@ -167,6 +200,8 @@ mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, m } } +#if MICROPY_PY_BUILTINS_FLOAT + enum { REAL_IMAG_STATE_START = 0, REAL_IMAG_STATE_HAVE_REAL = 1, @@ -179,41 +214,175 @@ typedef enum { PARSE_DEC_IN_EXP, } parse_dec_in_t; -#if MICROPY_PY_BUILTINS_FLOAT -// DEC_VAL_MAX only needs to be rough and is used to retain precision while not overflowing -// SMALL_NORMAL_VAL is the smallest power of 10 that is still a normal float -// EXACT_POWER_OF_10 is the largest value of x so that 10^x can be stored exactly in a float -// Note: EXACT_POWER_OF_10 is at least floor(log_5(2^mantissa_length)). Indeed, 10^n = 2^n * 5^n -// so we only have to store the 5^n part in the mantissa (the 2^n part will go into the float's -// exponent). +// MANTISSA_MAX is used to retain precision while not overflowing mantissa +#define MANTISSA_MAX (sizeof(mp_large_float_uint_t) == 8 ? 0x1999999999999998ULL : 0x19999998U) + +// MAX_EXACT_POWER_OF_5 is the largest value of x so that 5^x can be stored exactly in a float #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT -#define DEC_VAL_MAX 1e20F -#define SMALL_NORMAL_VAL (1e-37F) -#define SMALL_NORMAL_EXP (-37) -#define EXACT_POWER_OF_10 (9) +#define MAX_EXACT_POWER_OF_5 (10) #elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE -#define DEC_VAL_MAX 1e200 -#define SMALL_NORMAL_VAL (1e-307) -#define SMALL_NORMAL_EXP (-307) -#define EXACT_POWER_OF_10 (22) +#define MAX_EXACT_POWER_OF_5 (22) #endif +// Helper to compute `num * (10.0 ** dec_exp)` +mp_large_float_t mp_decimal_exp(mp_large_float_t num, int dec_exp) { + // CIRCUITPY-CHANGE: ignore float equal warning + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" + if (dec_exp == 0 || num == (mp_large_float_t)(0.0)) { + return num; + } + #pragma GCC diagnostic pop + + #if MICROPY_FLOAT_FORMAT_IMPL == MICROPY_FLOAT_FORMAT_IMPL_EXACT + + // If the assert below fails, it means you have chosen MICROPY_FLOAT_FORMAT_IMPL_EXACT + // manually on a platform where `larger floats` are not supported, which would + // result in inexact conversions. To fix this issue, change your `mpconfigport.h` + // and select MICROPY_FLOAT_FORMAT_IMPL_APPROX instead + assert(sizeof(mp_large_float_t) > sizeof(mp_float_t)); + + // Perform power using simple multiplications, to avoid + // dependency to higher-precision pow() function + int neg_exp = (dec_exp < 0); + if (neg_exp) { + dec_exp = -dec_exp; + } + mp_large_float_t res = num; + mp_large_float_t expo = (mp_large_float_t)10.0; + while (dec_exp) { + if (dec_exp & 1) { + if (neg_exp) { + res /= expo; + } else { + res *= expo; + } + } + dec_exp >>= 1; + if (dec_exp) { + expo *= expo; + } + } + return res; + + #else + // MICROPY_FLOAT_FORMAT_IMPL != MICROPY_FLOAT_FORMAT_IMPL_EXACT + + mp_float_union_t res = {num}; + // Multiply first by (2.0 ** dec_exp) via the exponent + // - this will ensure that the result of `pow()` is always in mp_float_t range + // when the result is expected to be in mp_float_t range (e.g. during format) + // - we don't need to care about p.exp overflow, as (5.0 ** dec_exp) will anyway + // force the final result toward the proper edge if needed (0.0 or inf) + res.p.exp += dec_exp; + // Use positive exponents when they are more precise then negative + if (dec_exp < 0 && dec_exp >= -MAX_EXACT_POWER_OF_5) { + res.f /= MICROPY_FLOAT_C_FUN(pow)(5, -dec_exp); + } else { + res.f *= MICROPY_FLOAT_C_FUN(pow)(5, dec_exp); + } + return (mp_large_float_t)res.f; + + #endif +} + + // Break out inner digit accumulation routine to ease trailing zero deferral. -static void accept_digit(mp_float_t *p_dec_val, int dig, int *p_exp_extra, int in) { +static mp_large_float_uint_t accept_digit(mp_large_float_uint_t p_mantissa, unsigned int dig, int *p_exp_extra, int in) { // Core routine to ingest an additional digit. - if (*p_dec_val < DEC_VAL_MAX) { + if (p_mantissa < MANTISSA_MAX) { // dec_val won't overflow so keep accumulating - *p_dec_val = 10 * *p_dec_val + dig; if (in == PARSE_DEC_IN_FRAC) { --(*p_exp_extra); } + return 10u * p_mantissa + dig; } else { // dec_val might overflow and we anyway can't represent more digits // of precision, so ignore the digit and just adjust the exponent if (in == PARSE_DEC_IN_INTG) { ++(*p_exp_extra); } + return p_mantissa; + } +} + +// Helper to parse an unsigned decimal number into a mp_float_t +const char *mp_parse_float_internal(const char *str, size_t len, mp_float_t *res) { + const char *top = str + len; + + parse_dec_in_t in = PARSE_DEC_IN_INTG; + bool exp_neg = false; + mp_large_float_uint_t mantissa = 0; + int exp_val = 0; + int exp_extra = 0; + int trailing_zeros_intg = 0, trailing_zeros_frac = 0; + while (str < top) { + unsigned int dig = *str++; + if ('0' <= dig && dig <= '9') { + dig -= '0'; + if (in == PARSE_DEC_IN_EXP) { + // don't overflow exp_val when adding next digit, instead just truncate + // it and the resulting float will still be correct, either inf or 0.0 + // (use INT_MAX/2 to allow adding exp_extra at the end without overflow) + if (exp_val < (INT_MAX / 2 - 9) / 10) { + exp_val = 10 * exp_val + dig; + } + } else { + if (dig == 0 || mantissa >= MANTISSA_MAX) { + // Defer treatment of zeros in fractional part. If nothing comes afterwards, ignore them. + // Also, once we reach MANTISSA_MAX, treat every additional digit as a trailing zero. + if (in == PARSE_DEC_IN_INTG) { + ++trailing_zeros_intg; + } else { + ++trailing_zeros_frac; + } + } else { + // Time to un-defer any trailing zeros. Intg zeros first. + while (trailing_zeros_intg) { + mantissa = accept_digit(mantissa, 0, &exp_extra, PARSE_DEC_IN_INTG); + --trailing_zeros_intg; + } + while (trailing_zeros_frac) { + mantissa = accept_digit(mantissa, 0, &exp_extra, PARSE_DEC_IN_FRAC); + --trailing_zeros_frac; + } + mantissa = accept_digit(mantissa, dig, &exp_extra, in); + } + } + } else if (in == PARSE_DEC_IN_INTG && dig == '.') { + in = PARSE_DEC_IN_FRAC; + } else if (in != PARSE_DEC_IN_EXP && ((dig | 0x20) == 'e')) { + in = PARSE_DEC_IN_EXP; + if (str < top) { + if (str[0] == '+') { + str++; + } else if (str[0] == '-') { + str++; + exp_neg = true; + } + } + if (str == top) { + return NULL; + } + } else if (dig == '_') { + continue; + } else { + // unknown character + str--; + break; + } } + + // work out the exponent + if (exp_neg) { + exp_val = -exp_val; + } + exp_val += exp_extra + trailing_zeros_intg; + + // At this point, we just need to multiply the mantissa by its base 10 exponent. + *res = (mp_float_t)mp_decimal_exp(mantissa, exp_val); + + return str; } #endif // MICROPY_PY_BUILTINS_FLOAT @@ -227,13 +396,13 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex const char *top = str + len; mp_float_t dec_val = 0; - bool dec_neg = false; #if MICROPY_PY_BUILTINS_COMPLEX unsigned int real_imag_state = REAL_IMAG_STATE_START; mp_float_t dec_real = 0; -parse_start: +parse_start:; #endif + bool dec_neg = false; // skip leading space for (; str < top && unichar_isspace(*str); str++) { @@ -252,109 +421,23 @@ mp_obj_t mp_parse_num_float(const char *str, size_t len, bool allow_imag, mp_lex const char *str_val_start = str; // determine what the string is - if (str < top && (str[0] | 0x20) == 'i') { - // string starts with 'i', should be 'inf' or 'infinity' (case insensitive) - if (str + 2 < top && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'f') { - // inf - str += 3; - dec_val = (mp_float_t)INFINITY; - if (str + 4 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'i' && (str[3] | 0x20) == 't' && (str[4] | 0x20) == 'y') { - // infinity - str += 5; - } - } - } else if (str < top && (str[0] | 0x20) == 'n') { - // string starts with 'n', should be 'nan' (case insensitive) - if (str + 2 < top && (str[1] | 0x20) == 'a' && (str[2] | 0x20) == 'n') { - // NaN - str += 3; - dec_val = MICROPY_FLOAT_C_FUN(nan)(""); + if (str + 2 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'f') { + // 'inf' or 'infinity' (case insensitive) + str += 3; + dec_val = (mp_float_t)INFINITY; + if (str + 4 < top && (str[0] | 0x20) == 'i' && (str[1] | 0x20) == 'n' && (str[2] | 0x20) == 'i' && (str[3] | 0x20) == 't' && (str[4] | 0x20) == 'y') { + // infinity + str += 5; } + } else if (str + 2 < top && (str[0] | 0x20) == 'n' && (str[1] | 0x20) == 'a' && (str[2] | 0x20) == 'n') { + // 'nan' (case insensitive) + str += 3; + dec_val = MICROPY_FLOAT_C_FUN(nan)(""); } else { // string should be a decimal number - parse_dec_in_t in = PARSE_DEC_IN_INTG; - bool exp_neg = false; - int exp_val = 0; - int exp_extra = 0; - int trailing_zeros_intg = 0, trailing_zeros_frac = 0; - while (str < top) { - unsigned int dig = *str++; - if ('0' <= dig && dig <= '9') { - dig -= '0'; - if (in == PARSE_DEC_IN_EXP) { - // don't overflow exp_val when adding next digit, instead just truncate - // it and the resulting float will still be correct, either inf or 0.0 - // (use INT_MAX/2 to allow adding exp_extra at the end without overflow) - if (exp_val < (INT_MAX / 2 - 9) / 10) { - exp_val = 10 * exp_val + dig; - } - } else { - if (dig == 0 || dec_val >= DEC_VAL_MAX) { - // Defer treatment of zeros in fractional part. If nothing comes afterwards, ignore them. - // Also, once we reach DEC_VAL_MAX, treat every additional digit as a trailing zero. - if (in == PARSE_DEC_IN_INTG) { - ++trailing_zeros_intg; - } else { - ++trailing_zeros_frac; - } - } else { - // Time to un-defer any trailing zeros. Intg zeros first. - while (trailing_zeros_intg) { - accept_digit(&dec_val, 0, &exp_extra, PARSE_DEC_IN_INTG); - --trailing_zeros_intg; - } - while (trailing_zeros_frac) { - accept_digit(&dec_val, 0, &exp_extra, PARSE_DEC_IN_FRAC); - --trailing_zeros_frac; - } - accept_digit(&dec_val, dig, &exp_extra, in); - } - } - } else if (in == PARSE_DEC_IN_INTG && dig == '.') { - in = PARSE_DEC_IN_FRAC; - } else if (in != PARSE_DEC_IN_EXP && ((dig | 0x20) == 'e')) { - in = PARSE_DEC_IN_EXP; - if (str < top) { - if (str[0] == '+') { - str++; - } else if (str[0] == '-') { - str++; - exp_neg = true; - } - } - if (str == top) { - goto value_error; - } - } else if (dig == '_') { - continue; - } else { - // unknown character - str--; - break; - } - } - - // work out the exponent - if (exp_neg) { - exp_val = -exp_val; - } - - // apply the exponent, making sure it's not a subnormal value - exp_val += exp_extra + trailing_zeros_intg; - if (exp_val < SMALL_NORMAL_EXP) { - exp_val -= SMALL_NORMAL_EXP; - dec_val *= SMALL_NORMAL_VAL; - } - - // At this point, we need to multiply the mantissa by its base 10 exponent. If possible, - // we would rather manipulate numbers that have an exact representation in IEEE754. It - // turns out small positive powers of 10 do, whereas small negative powers of 10 don't. - // So in that case, we'll yield a division of exact values rather than a multiplication - // of slightly erroneous values. - if (exp_val < 0 && exp_val >= -EXACT_POWER_OF_10) { - dec_val /= MICROPY_FLOAT_C_FUN(pow)(10, -exp_val); - } else { - dec_val *= MICROPY_FLOAT_C_FUN(pow)(10, exp_val); + str = mp_parse_float_internal(str, top - str, &dec_val); + if (!str) { + goto value_error; } } diff --git a/py/parsenum.h b/py/parsenum.h index f444632d230..d532cb194a5 100644 --- a/py/parsenum.h +++ b/py/parsenum.h @@ -34,6 +34,11 @@ mp_obj_t mp_parse_num_integer(const char *restrict str, size_t len, int base, mp_lexer_t *lex); +#if MICROPY_PY_BUILTINS_FLOAT +mp_large_float_t mp_decimal_exp(mp_large_float_t num, int dec_exp); +const char *mp_parse_float_internal(const char *str, size_t len, mp_float_t *res); +#endif + #if MICROPY_PY_BUILTINS_COMPLEX mp_obj_t mp_parse_num_decimal(const char *str, size_t len, bool allow_imag, bool force_complex, mp_lexer_t *lex); diff --git a/py/parsenumbase.c b/py/parsenumbase.c index 94523a666d3..fbf07a11958 100644 --- a/py/parsenumbase.c +++ b/py/parsenumbase.c @@ -30,35 +30,28 @@ // find real radix base, and strip preceding '0x', '0o' and '0b' // puts base in *base, and returns number of bytes to skip the prefix +// in base-0, puts 1 in *base to indicate a number that starts with 0, to provoke a +// ValueError if it's not all-digits-zero. size_t mp_parse_num_base(const char *str, size_t len, int *base) { const byte *p = (const byte *)str; if (len <= 1) { goto no_prefix; } unichar c = *(p++); - if ((*base == 0 || *base == 16) && c == '0') { - c = *(p++); - if ((c | 32) == 'x') { + if (c == '0') { + c = *(p++) | 32; + int b = *base; + if (c == 'x' && (b == 0 || b == 16)) { *base = 16; - } else if (*base == 0 && (c | 32) == 'o') { + } else if (c == 'o' && (b == 0 || b == 8)) { *base = 8; - } else if (*base == 0 && (c | 32) == 'b') { + } else if (c == 'b' && (b == 0 || b == 2)) { *base = 2; } else { - if (*base == 0) { - *base = 10; - } - p -= 2; - } - } else if (*base == 8 && c == '0') { - c = *(p++); - if ((c | 32) != 'o') { - p -= 2; - } - } else if (*base == 2 && c == '0') { - c = *(p++); - if ((c | 32) != 'b') { p -= 2; + if (b == 0) { + *base = 1; + } } } else { p--; diff --git a/py/persistentcode.c b/py/persistentcode.c index 09beeef4518..5c3de3174bc 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -63,6 +63,10 @@ typedef struct _bytecode_prelude_t { uint code_info_size; } bytecode_prelude_t; +#if MICROPY_EMIT_RV32 +#include "py/asmrv32.h" +#endif + #endif // MICROPY_PERSISTENT_CODE_LOAD || MICROPY_PERSISTENT_CODE_SAVE #if MICROPY_PERSISTENT_CODE_LOAD @@ -74,6 +78,20 @@ static size_t read_uint(mp_reader_t *reader); #if MICROPY_EMIT_MACHINE_CODE +#if MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA || MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA + +// An mp_obj_list_t that tracks native text/BSS/rodata to prevent the GC from reclaiming them. +MP_REGISTER_ROOT_POINTER(mp_obj_t persistent_code_root_pointers); + +static void track_root_pointer(void *ptr) { + if (MP_STATE_PORT(persistent_code_root_pointers) == MP_OBJ_NULL) { + MP_STATE_PORT(persistent_code_root_pointers) = mp_obj_new_list(0, NULL); + } + mp_obj_list_append(MP_STATE_PORT(persistent_code_root_pointers), MP_OBJ_FROM_PTR(ptr)); +} + +#endif + typedef struct _reloc_info_t { mp_reader_t *reader; mp_module_context_t *context; @@ -174,6 +192,15 @@ static qstr load_qstr(mp_reader_t *reader) { return len >> 1; } len >>= 1; + + #if MICROPY_VFS_ROM + // If possible, create the qstr from the memory-mapped string data. + const uint8_t *memmap = mp_reader_try_read_rom(reader, len + 1); + if (memmap != NULL) { + return qstr_from_strn_static((const char *)memmap, len); + } + #endif + char *str = m_new(char, len); read_bytes(reader, (byte *)str, len); read_byte(reader); // read and discard null terminator @@ -182,6 +209,24 @@ static qstr load_qstr(mp_reader_t *reader) { return qst; } +#if MICROPY_VFS_ROM +// Create a str/bytes object that can forever reference the given data. +static mp_obj_t mp_obj_new_str_static(const mp_obj_type_t *type, const byte *data, size_t len) { + if (type == &mp_type_str) { + qstr q = qstr_find_strn((const char *)data, len); + if (q != MP_QSTRnull) { + return MP_OBJ_NEW_QSTR(q); + } + } + assert(data[len] == '\0'); + mp_obj_str_t *o = mp_obj_malloc(mp_obj_str_t, type); + o->len = len; + o->hash = qstr_compute_hash(data, len); + o->data = data; + return MP_OBJ_FROM_PTR(o); +} +#endif + static mp_obj_t load_obj(mp_reader_t *reader) { byte obj_type = read_byte(reader); #if MICROPY_EMIT_MACHINE_CODE @@ -199,6 +244,8 @@ static mp_obj_t load_obj(mp_reader_t *reader) { return MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj); } else { size_t len = read_uint(reader); + + // Handle empty bytes object, and tuple objects. if (len == 0 && obj_type == MP_PERSISTENT_OBJ_BYTES) { read_byte(reader); // skip null terminator return mp_const_empty_bytes; @@ -209,11 +256,31 @@ static mp_obj_t load_obj(mp_reader_t *reader) { } return MP_OBJ_FROM_PTR(tuple); } + + // Read in the object's data, either from ROM or into RAM. + const uint8_t *memmap = NULL; vstr_t vstr; - vstr_init_len(&vstr, len); - read_bytes(reader, (byte *)vstr.buf, len); + #if MICROPY_VFS_ROM + memmap = mp_reader_try_read_rom(reader, len); + vstr.buf = (void *)memmap; + vstr.len = len; + #endif + if (memmap == NULL) { + // Data could not be memory-mapped, so allocate it in RAM and read it in. + vstr_init_len(&vstr, len); + read_bytes(reader, (byte *)vstr.buf, len); + } + + // Create and return the object. if (obj_type == MP_PERSISTENT_OBJ_STR || obj_type == MP_PERSISTENT_OBJ_BYTES) { - read_byte(reader); // skip null terminator + read_byte(reader); // skip null terminator (it needs to be there for ROM str objects) + #if MICROPY_VFS_ROM + if (memmap != NULL) { + // Create a str/bytes that references the memory-mapped data. + const mp_obj_type_t *t = obj_type == MP_PERSISTENT_OBJ_STR ? &mp_type_str : &mp_type_bytes; + return mp_obj_new_str_static(t, memmap, len); + } + #endif if (obj_type == MP_PERSISTENT_OBJ_STR) { return mp_obj_new_str_from_utf8_vstr(&vstr); } else { @@ -250,10 +317,17 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co #endif if (kind == MP_CODE_BYTECODE) { - // Allocate memory for the bytecode - fun_data = m_new(uint8_t, fun_data_len); - // Load bytecode - read_bytes(reader, fun_data, fun_data_len); + #if MICROPY_VFS_ROM + // Try to reference memory-mapped data for the bytecode. + fun_data = (uint8_t *)mp_reader_try_read_rom(reader, fun_data_len); + #endif + + if (fun_data == NULL) { + // Allocate memory for the bytecode. + fun_data = m_new(uint8_t, fun_data_len); + // Load bytecode. + read_bytes(reader, fun_data, fun_data_len); + } #if MICROPY_EMIT_MACHINE_CODE } else { @@ -306,11 +380,10 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co read_bytes(reader, rodata, rodata_size); } - // Viper code with BSS/rodata should not have any children. - // Reuse the children pointer to reference the BSS/rodata - // memory so that it is not reclaimed by the GC. - assert(!has_children); - children = (void *)data; + #if MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA + // Track the BSS/rodata memory so it's not reclaimed by the GC. + track_root_pointer(data); + #endif } } #endif @@ -340,7 +413,7 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co #if MICROPY_EMIT_MACHINE_CODE } else { - const uint8_t *prelude_ptr; + const uint8_t *prelude_ptr = NULL; #if MICROPY_EMIT_NATIVE_PRELUDE_SEPARATE_FROM_MACHINE_CODE if (kind == MP_CODE_NATIVE_PY) { // Executable code cannot be accessed byte-wise on this architecture, so copy @@ -353,22 +426,17 @@ static mp_raw_code_t *load_raw_code(mp_reader_t *reader, mp_module_context_t *co // Relocate and commit code to executable address space reloc_info_t ri = {reader, context, rodata, bss}; + #if MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA + if (native_scope_flags & MP_SCOPE_FLAG_VIPERRELOC) { + // Track the function data memory so it's not reclaimed by the GC. + track_root_pointer(fun_data); + } + #endif #if defined(MP_PLAT_COMMIT_EXEC) void *opt_ri = (native_scope_flags & MP_SCOPE_FLAG_VIPERRELOC) ? &ri : NULL; fun_data = MP_PLAT_COMMIT_EXEC(fun_data, fun_data_len, opt_ri); #else if (native_scope_flags & MP_SCOPE_FLAG_VIPERRELOC) { - #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE - // If native code needs relocations then it's not guaranteed that a pointer to - // the head of `buf` (containing the machine code) will be retained for the GC - // to trace. This is because native functions can start inside `buf` and so - // it's possible that the only GC-reachable pointers are pointers inside `buf`. - // So put this `buf` on a list of reachable root pointers. - if (MP_STATE_PORT(track_reloc_code_list) == MP_OBJ_NULL) { - MP_STATE_PORT(track_reloc_code_list) = mp_obj_new_list(0, NULL); - } - mp_obj_list_append(MP_STATE_PORT(track_reloc_code_list), MP_OBJ_FROM_PTR(fun_data)); - #endif // Do the relocations. mp_native_relocate(&ri, fun_data, (uintptr_t)fun_data); } @@ -409,13 +477,16 @@ void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) { read_bytes(reader, header, sizeof(header)); byte arch = MPY_FEATURE_DECODE_ARCH(header[2]); // CIRCUITPY-CHANGE: 'C', not 'M' + if (header[0] == 'M') { + mp_raise_ValueError(MP_ERROR_TEXT("MicroPython .mpy file; use CircuitPython mpy-cross")); + } if (header[0] != 'C' || header[1] != MPY_VERSION || (arch != MP_NATIVE_ARCH_NONE && MPY_FEATURE_DECODE_SUB_VERSION(header[2]) != MPY_SUB_VERSION) || header[3] > MP_SMALL_INT_BITS) { mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); } - if (MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE) { + if (arch != MP_NATIVE_ARCH_NONE) { if (!MPY_FEATURE_ARCH_TEST(arch)) { if (MPY_FEATURE_ARCH_TEST(MP_NATIVE_ARCH_NONE)) { // On supported ports this can be resolved by enabling feature, eg @@ -427,6 +498,23 @@ void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) { } } + size_t arch_flags = 0; + if (MPY_FEATURE_ARCH_FLAGS_TEST(header[2])) { + #if MICROPY_EMIT_RV32 + arch_flags = read_uint(reader); + + if (MPY_FEATURE_ARCH_TEST(MP_NATIVE_ARCH_RV32IMC)) { + if ((arch_flags & (size_t)asm_rv32_allowed_extensions()) != arch_flags) { + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); + } + } else + #endif + { + (void)arch_flags; + mp_raise_ValueError(MP_ERROR_TEXT("incompatible .mpy file")); + } + } + size_t n_qstr = read_uint(reader); size_t n_obj = read_uint(reader); mp_module_context_alloc_tables(cm->context, n_qstr, n_obj); @@ -448,6 +536,7 @@ void mp_raw_code_load(mp_reader_t *reader, mp_compiled_module_t *cm) { cm->has_native = MPY_FEATURE_DECODE_ARCH(header[2]) != MP_NATIVE_ARCH_NONE; cm->n_qstr = n_qstr; cm->n_obj = n_obj; + cm->arch_flags = arch_flags; #endif // Deregister exception handler and close the reader. @@ -472,7 +561,7 @@ void mp_raw_code_load_file(qstr filename, mp_compiled_module_t *context) { #endif // MICROPY_PERSISTENT_CODE_LOAD -#if MICROPY_PERSISTENT_CODE_SAVE +#if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_PERSISTENT_CODE_SAVE_FUN #include "py/objstr.h" @@ -570,6 +659,10 @@ static void save_obj(mp_print_t *print, mp_obj_t o) { } } +#endif // MICROPY_PERSISTENT_CODE_SAVE || MICROPY_PERSISTENT_CODE_SAVE_FUN + +#if MICROPY_PERSISTENT_CODE_SAVE + static void save_raw_code(mp_print_t *print, const mp_raw_code_t *rc) { // Save function kind and data length mp_print_uint(print, (rc->fun_data_len << 3) | ((rc->n_children != 0) << 2) | (rc->kind - MP_CODE_BYTECODE)); @@ -613,7 +706,7 @@ void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print) { byte header[4] = { 'C', MPY_VERSION, - cm->has_native ? MPY_FEATURE_ENCODE_SUB_VERSION(MPY_SUB_VERSION) | MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH_DYNAMIC) : 0, + (cm->arch_flags != 0 ? MPY_FEATURE_ARCH_FLAGS : 0) | (cm->has_native ? MPY_FEATURE_ENCODE_SUB_VERSION(MPY_SUB_VERSION) | MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH_DYNAMIC) : 0), #if MICROPY_DYNAMIC_COMPILER mp_dynamic_compiler.small_int_bits, #else @@ -622,6 +715,10 @@ void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print) { }; mp_print_bytes(print, header, sizeof(header)); + if (cm->arch_flags) { + mp_print_uint(print, cm->arch_flags); + } + // Number of entries in constant table. mp_print_uint(print, cm->n_qstr); mp_print_uint(print, cm->n_obj); @@ -640,6 +737,8 @@ void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print) { save_raw_code(print, cm->rc); } +#endif // MICROPY_PERSISTENT_CODE_SAVE + #if MICROPY_PERSISTENT_CODE_SAVE_FILE #include @@ -670,7 +769,182 @@ void mp_raw_code_save_file(mp_compiled_module_t *cm, qstr filename) { #endif // MICROPY_PERSISTENT_CODE_SAVE_FILE -#endif // MICROPY_PERSISTENT_CODE_SAVE +#if MICROPY_PERSISTENT_CODE_SAVE_FUN + +#include "py/bc0.h" +#include "py/objfun.h" +#include "py/smallint.h" +#include "py/gc.h" + +#define MP_BC_OPCODE_HAS_SIGNED_OFFSET(opcode) (MP_BC_UNWIND_JUMP <= (opcode) && (opcode) <= MP_BC_POP_JUMP_IF_FALSE) + +typedef struct _bit_vector_t { + size_t max_bit_set; + size_t alloc; + uintptr_t *bits; +} bit_vector_t; + +static void bit_vector_init(bit_vector_t *self) { + self->max_bit_set = 0; + self->alloc = 1; + self->bits = m_new(uintptr_t, self->alloc); +} + +static void bit_vector_clear(bit_vector_t *self) { + m_del(uintptr_t, self->bits, self->alloc); +} + +static bool bit_vector_is_set(bit_vector_t *self, size_t index) { + const size_t bits_size = sizeof(*self->bits) * MP_BITS_PER_BYTE; + return index / bits_size < self->alloc + && (self->bits[index / bits_size] & ((uintptr_t)1 << (index % bits_size))) != 0; +} + +static void bit_vector_set(bit_vector_t *self, size_t index) { + const size_t bits_size = sizeof(*self->bits) * MP_BITS_PER_BYTE; + self->max_bit_set = MAX(self->max_bit_set, index); + if (index / bits_size >= self->alloc) { + size_t new_alloc = self->alloc * 2; + self->bits = m_renew(uintptr_t, self->bits, self->alloc, new_alloc); + self->alloc = new_alloc; + } + self->bits[index / bits_size] |= (uintptr_t)1 << (index % bits_size); +} + +typedef struct _mp_opcode_t { + uint8_t opcode; + uint8_t format; + uint8_t size; + mp_int_t arg; + uint8_t extra_arg; +} mp_opcode_t; + +static mp_opcode_t mp_opcode_decode(const uint8_t *ip) { + const uint8_t *ip_start = ip; + uint8_t opcode = *ip++; + uint8_t opcode_format = MP_BC_FORMAT(opcode); + mp_uint_t arg = 0; + uint8_t extra_arg = 0; + if (opcode_format == MP_BC_FORMAT_QSTR || opcode_format == MP_BC_FORMAT_VAR_UINT) { + arg = *ip & 0x7f; + if (opcode == MP_BC_LOAD_CONST_SMALL_INT && (arg & 0x40) != 0) { + arg |= (mp_uint_t)(-1) << 7; + } + while ((*ip & 0x80) != 0) { + arg = (arg << 7) | (*++ip & 0x7f); + } + ++ip; + } else if (opcode_format == MP_BC_FORMAT_OFFSET) { + if ((*ip & 0x80) == 0) { + arg = *ip++; + if (MP_BC_OPCODE_HAS_SIGNED_OFFSET(opcode)) { + arg -= 0x40; + } + } else { + arg = (ip[0] & 0x7f) | (ip[1] << 7); + ip += 2; + if (MP_BC_OPCODE_HAS_SIGNED_OFFSET(opcode)) { + arg -= 0x4000; + } + } + } + if ((opcode & MP_BC_MASK_EXTRA_BYTE) == 0) { + extra_arg = *ip++; + } + + mp_opcode_t op = { opcode, opcode_format, ip - ip_start, arg, extra_arg }; + return op; +} + +mp_obj_t mp_raw_code_save_fun_to_bytes(const mp_module_constants_t *consts, const uint8_t *bytecode) { + const uint8_t *fun_data = bytecode; + const uint8_t *fun_data_top = fun_data + gc_nbytes(fun_data); + + // Extract function information. + const byte *ip = fun_data; + MP_BC_PRELUDE_SIG_DECODE(ip); + MP_BC_PRELUDE_SIZE_DECODE(ip); + + // Track the qstrs used by the function. + bit_vector_t qstr_table_used; + bit_vector_init(&qstr_table_used); + + // Track the objects used by the function. + bit_vector_t obj_table_used; + bit_vector_init(&obj_table_used); + + const byte *ip_names = ip; + mp_uint_t simple_name = mp_decode_uint(&ip_names); + bit_vector_set(&qstr_table_used, simple_name); + for (size_t i = 0; i < n_pos_args + n_kwonly_args; ++i) { + mp_uint_t arg_name = mp_decode_uint(&ip_names); + bit_vector_set(&qstr_table_used, arg_name); + } + + // Skip pass source code info and cell info. + // Then ip points to the start of the opcodes. + ip += n_info + n_cell; + + // Decode bytecode. + while (ip < fun_data_top) { + mp_opcode_t op = mp_opcode_decode(ip); + if (op.opcode == MP_BC_BASE_RESERVED) { + // End of opcodes. + fun_data_top = ip; + } else if (op.opcode == MP_BC_LOAD_CONST_OBJ) { + bit_vector_set(&obj_table_used, op.arg); + } else if (op.format == MP_BC_FORMAT_QSTR) { + bit_vector_set(&qstr_table_used, op.arg); + } + ip += op.size; + } + + mp_uint_t fun_data_len = fun_data_top - fun_data; + + mp_print_t print; + vstr_t vstr; + vstr_init_print(&vstr, 64, &print); + + // Start with .mpy header. + const uint8_t header[4] = { 'M', MPY_VERSION, 0, MP_SMALL_INT_BITS }; + mp_print_bytes(&print, header, sizeof(header)); + + // Number of entries in constant table. + mp_print_uint(&print, qstr_table_used.max_bit_set + 1); + mp_print_uint(&print, obj_table_used.max_bit_set + 1); + + // Save qstrs. + for (size_t i = 0; i <= qstr_table_used.max_bit_set; ++i) { + if (bit_vector_is_set(&qstr_table_used, i)) { + save_qstr(&print, consts->qstr_table[i]); + } else { + save_qstr(&print, MP_QSTR_); + } + } + + // Save constant objects. + for (size_t i = 0; i <= obj_table_used.max_bit_set; ++i) { + if (bit_vector_is_set(&obj_table_used, i)) { + save_obj(&print, consts->obj_table[i]); + } else { + save_obj(&print, mp_const_none); + } + } + + bit_vector_clear(&qstr_table_used); + bit_vector_clear(&obj_table_used); + + // Save function kind and data length. + mp_print_uint(&print, fun_data_len << 3); + + // Save function code. + mp_print_bytes(&print, fun_data, fun_data_len); + + // Create and return bytes representing the .mpy data. + return mp_obj_new_bytes_from_vstr(&vstr); +} + +#endif // MICROPY_PERSISTENT_CODE_SAVE_FUN #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE // An mp_obj_list_t that tracks relocated native code to prevent the GC from reclaiming them. diff --git a/py/persistentcode.h b/py/persistentcode.h index d2b310f241f..85668e608c8 100644 --- a/py/persistentcode.h +++ b/py/persistentcode.h @@ -30,6 +30,11 @@ #include "py/reader.h" #include "py/emitglue.h" +// CIRCUITPY-CHANGE: Avoid undefined warnings +#ifndef MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE +#define MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE (0) +#endif + // The current version of .mpy files. A bytecode-only .mpy file can be loaded // as long as MPY_VERSION matches, but a native .mpy (i.e. one with an arch // set) must also match MPY_SUB_VERSION. This allows 3 additional updates to @@ -45,7 +50,7 @@ // Macros to encode/decode native architecture to/from the feature byte #define MPY_FEATURE_ENCODE_ARCH(arch) ((arch) << 2) -#define MPY_FEATURE_DECODE_ARCH(feat) ((feat) >> 2) +#define MPY_FEATURE_DECODE_ARCH(feat) (((feat) >> 2) & 0x2F) // Define the host architecture #if MICROPY_EMIT_X86 @@ -71,6 +76,8 @@ #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_XTENSA) #elif MICROPY_EMIT_XTENSAWIN #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_XTENSAWIN) +#elif MICROPY_EMIT_RV32 + #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_RV32IMC) #else #define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_NONE) #endif @@ -83,6 +90,10 @@ #define MPY_FILE_HEADER_INT (MPY_VERSION \ | (MPY_FEATURE_ENCODE_SUB_VERSION(MPY_SUB_VERSION) | MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH)) << 8) +// Architecture-specific flags are present in the .mpy file +#define MPY_FEATURE_ARCH_FLAGS (0x40) +#define MPY_FEATURE_ARCH_FLAGS_TEST(x) (((x) & MPY_FEATURE_ARCH_FLAGS) == MPY_FEATURE_ARCH_FLAGS) + enum { MP_NATIVE_ARCH_NONE = 0, MP_NATIVE_ARCH_X86, @@ -95,6 +106,9 @@ enum { MP_NATIVE_ARCH_ARMV7EMDP, MP_NATIVE_ARCH_XTENSA, MP_NATIVE_ARCH_XTENSAWIN, + MP_NATIVE_ARCH_RV32IMC, + MP_NATIVE_ARCH_RV64IMC, + MP_NATIVE_ARCH_DEBUG, // this entry should always be last }; enum { @@ -117,6 +131,7 @@ void mp_raw_code_load_file(qstr filename, mp_compiled_module_t *ctx); void mp_raw_code_save(mp_compiled_module_t *cm, mp_print_t *print); void mp_raw_code_save_file(mp_compiled_module_t *cm, qstr filename); +mp_obj_t mp_raw_code_save_fun_to_bytes(const mp_module_constants_t *consts, const uint8_t *bytecode); void mp_native_relocate(void *reloc, uint8_t *text, uintptr_t reloc_text); diff --git a/py/profile.c b/py/profile.c index 92f414ace7c..b5a0c54728c 100644 --- a/py/profile.c +++ b/py/profile.c @@ -38,9 +38,8 @@ #endif #define prof_trace_cb MP_STATE_THREAD(prof_trace_callback) -#define QSTR_MAP(context, idx) (context->constants.qstr_table[idx]) -static uint mp_prof_bytecode_lineno(const mp_raw_code_t *rc, size_t bc) { +uint mp_prof_bytecode_lineno(const mp_raw_code_t *rc, size_t bc) { const mp_bytecode_prelude_t *prelude = &rc->prelude; return mp_bytecode_get_source_line(prelude->line_info, prelude->line_info_top, bc); } @@ -68,137 +67,6 @@ void mp_prof_extract_prelude(const byte *bytecode, mp_bytecode_prelude_t *prelud prelude->line_info = ip; } -/******************************************************************************/ -// code object - -static void code_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { - (void)kind; - mp_obj_code_t *o = MP_OBJ_TO_PTR(o_in); - const mp_raw_code_t *rc = o->rc; - const mp_bytecode_prelude_t *prelude = &rc->prelude; - mp_printf(print, - "", - QSTR_MAP(o->context, prelude->qstr_block_name_idx), - o, - QSTR_MAP(o->context, 0), - rc->line_of_definition - ); -} - -static mp_obj_tuple_t *code_consts(const mp_module_context_t *context, const mp_raw_code_t *rc) { - mp_obj_tuple_t *consts = MP_OBJ_TO_PTR(mp_obj_new_tuple(rc->n_children + 1, NULL)); - - size_t const_no = 0; - for (size_t i = 0; i < rc->n_children; ++i) { - mp_obj_t code = mp_obj_new_code(context, rc->children[i]); - if (code == MP_OBJ_NULL) { - m_malloc_fail(sizeof(mp_obj_code_t)); - } - consts->items[const_no++] = code; - } - consts->items[const_no++] = mp_const_none; - - return consts; -} - -static mp_obj_t raw_code_lnotab(const mp_raw_code_t *rc) { - // const mp_bytecode_prelude_t *prelude = &rc->prelude; - uint start = 0; - uint stop = rc->fun_data_len - start; - - uint last_lineno = mp_prof_bytecode_lineno(rc, start); - uint lasti = 0; - - const uint buffer_chunk_size = (stop - start) >> 2; // heuristic magic - uint buffer_size = buffer_chunk_size; - byte *buffer = m_new(byte, buffer_size); - uint buffer_index = 0; - - for (uint i = start; i < stop; ++i) { - uint lineno = mp_prof_bytecode_lineno(rc, i); - size_t line_diff = lineno - last_lineno; - if (line_diff > 0) { - uint instr_diff = (i - start) - lasti; - - assert(instr_diff < 256); - assert(line_diff < 256); - - if (buffer_index + 2 > buffer_size) { - buffer = m_renew(byte, buffer, buffer_size, buffer_size + buffer_chunk_size); - buffer_size = buffer_size + buffer_chunk_size; - } - last_lineno = lineno; - lasti = i - start; - buffer[buffer_index++] = instr_diff; - buffer[buffer_index++] = line_diff; - } - } - - mp_obj_t o = mp_obj_new_bytes(buffer, buffer_index); - m_del(byte, buffer, buffer_size); - return o; -} - -static void code_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { - if (dest[0] != MP_OBJ_NULL) { - // not load attribute - return; - } - mp_obj_code_t *o = MP_OBJ_TO_PTR(self_in); - const mp_raw_code_t *rc = o->rc; - const mp_bytecode_prelude_t *prelude = &rc->prelude; - switch (attr) { - case MP_QSTR_co_code: - dest[0] = mp_obj_new_bytes( - (void *)prelude->opcodes, - rc->fun_data_len - (prelude->opcodes - (const byte *)rc->fun_data) - ); - break; - case MP_QSTR_co_consts: - dest[0] = MP_OBJ_FROM_PTR(code_consts(o->context, rc)); - break; - case MP_QSTR_co_filename: - dest[0] = MP_OBJ_NEW_QSTR(QSTR_MAP(o->context, 0)); - break; - case MP_QSTR_co_firstlineno: - dest[0] = MP_OBJ_NEW_SMALL_INT(mp_prof_bytecode_lineno(rc, 0)); - break; - case MP_QSTR_co_name: - dest[0] = MP_OBJ_NEW_QSTR(QSTR_MAP(o->context, prelude->qstr_block_name_idx)); - break; - case MP_QSTR_co_names: - dest[0] = MP_OBJ_FROM_PTR(o->dict_locals); - break; - case MP_QSTR_co_lnotab: - if (!o->lnotab) { - o->lnotab = raw_code_lnotab(rc); - } - dest[0] = o->lnotab; - break; - } -} - -MP_DEFINE_CONST_OBJ_TYPE( - mp_type_settrace_codeobj, - MP_QSTR_code, - MP_TYPE_FLAG_NONE, - print, code_print, - attr, code_attr - ); - -mp_obj_t mp_obj_new_code(const mp_module_context_t *context, const mp_raw_code_t *rc) { - mp_obj_code_t *o = m_new_obj_maybe(mp_obj_code_t); - if (o == NULL) { - return MP_OBJ_NULL; - } - o->base.type = &mp_type_settrace_codeobj; - o->context = context; - o->rc = rc; - o->dict_locals = mp_locals_get(); // this is a wrong! how to do this properly? - o->lnotab = MP_OBJ_NULL; - return MP_OBJ_FROM_PTR(o); -} - /******************************************************************************/ // frame object @@ -211,9 +79,9 @@ static void frame_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t mp_printf(print, "", frame, - QSTR_MAP(code->context, 0), - frame->lineno, - QSTR_MAP(code->context, prelude->qstr_block_name_idx) + MP_CODE_QSTR_MAP(code->context, 0), + (int)frame->lineno, + MP_CODE_QSTR_MAP(code->context, prelude->qstr_block_name_idx) ); } @@ -265,7 +133,7 @@ mp_obj_t mp_obj_new_frame(const mp_code_state_t *code_state) { return MP_OBJ_NULL; } - mp_obj_code_t *code = o->code = MP_OBJ_TO_PTR(mp_obj_new_code(code_state->fun_bc->context, code_state->fun_bc->rc)); + mp_obj_code_t *code = o->code = MP_OBJ_TO_PTR(mp_obj_new_code(code_state->fun_bc->context, code_state->fun_bc->rc, false)); if (code == NULL) { return MP_OBJ_NULL; } diff --git a/py/profile.h b/py/profile.h index 7f3f9140346..db72b9f0768 100644 --- a/py/profile.h +++ b/py/profile.h @@ -28,20 +28,12 @@ #define MICROPY_INCLUDED_PY_PROFILING_H #include "py/emitglue.h" +#include "py/objcode.h" #if MICROPY_PY_SYS_SETTRACE #define mp_prof_is_executing MP_STATE_THREAD(prof_callback_is_executing) -typedef struct _mp_obj_code_t { - // TODO this was 4 words - mp_obj_base_t base; - const mp_module_context_t *context; - const mp_raw_code_t *rc; - mp_obj_dict_t *dict_locals; - mp_obj_t lnotab; -} mp_obj_code_t; - typedef struct _mp_obj_frame_t { mp_obj_base_t base; const mp_code_state_t *code_state; @@ -53,9 +45,9 @@ typedef struct _mp_obj_frame_t { bool trace_opcodes; } mp_obj_frame_t; +uint mp_prof_bytecode_lineno(const mp_raw_code_t *rc, size_t bc); void mp_prof_extract_prelude(const byte *bytecode, mp_bytecode_prelude_t *prelude); -mp_obj_t mp_obj_new_code(const mp_module_context_t *mc, const mp_raw_code_t *rc); mp_obj_t mp_obj_new_frame(const mp_code_state_t *code_state); // This is the implementation for the sys.settrace diff --git a/py/py.cmake b/py/py.cmake index 1cbbe08f013..b99d2d24b5d 100644 --- a/py/py.cmake +++ b/py/py.cmake @@ -9,6 +9,7 @@ set(MICROPY_SOURCE_PY ${MICROPY_PY_DIR}/argcheck.c ${MICROPY_PY_DIR}/asmarm.c ${MICROPY_PY_DIR}/asmbase.c + ${MICROPY_PY_DIR}/asmrv32.c ${MICROPY_PY_DIR}/asmthumb.c ${MICROPY_PY_DIR}/asmx64.c ${MICROPY_PY_DIR}/asmx86.c @@ -19,12 +20,16 @@ set(MICROPY_SOURCE_PY ${MICROPY_PY_DIR}/builtinhelp.c ${MICROPY_PY_DIR}/builtinimport.c ${MICROPY_PY_DIR}/compile.c + ${MICROPY_PY_DIR}/cstack.c ${MICROPY_PY_DIR}/emitbc.c ${MICROPY_PY_DIR}/emitcommon.c ${MICROPY_PY_DIR}/emitglue.c + ${MICROPY_PY_DIR}/emitinlinerv32.c ${MICROPY_PY_DIR}/emitinlinethumb.c ${MICROPY_PY_DIR}/emitinlinextensa.c ${MICROPY_PY_DIR}/emitnarm.c + ${MICROPY_PY_DIR}/emitndebug.c + ${MICROPY_PY_DIR}/emitnrv32.c ${MICROPY_PY_DIR}/emitnthumb.c ${MICROPY_PY_DIR}/emitnx64.c ${MICROPY_PY_DIR}/emitnx86.c @@ -53,8 +58,11 @@ set(MICROPY_SOURCE_PY ${MICROPY_PY_DIR}/mpz.c ${MICROPY_PY_DIR}/nativeglue.c ${MICROPY_PY_DIR}/nlr.c + ${MICROPY_PY_DIR}/nlraarch64.c ${MICROPY_PY_DIR}/nlrmips.c ${MICROPY_PY_DIR}/nlrpowerpc.c + ${MICROPY_PY_DIR}/nlrrv32.c + ${MICROPY_PY_DIR}/nlrrv64.c ${MICROPY_PY_DIR}/nlrsetjmp.c ${MICROPY_PY_DIR}/nlrthumb.c ${MICROPY_PY_DIR}/nlrx64.c @@ -65,6 +73,7 @@ set(MICROPY_SOURCE_PY ${MICROPY_PY_DIR}/objattrtuple.c ${MICROPY_PY_DIR}/objbool.c ${MICROPY_PY_DIR}/objboundmeth.c + ${MICROPY_PY_DIR}/objcode.c ${MICROPY_PY_DIR}/objcell.c ${MICROPY_PY_DIR}/objclosure.c ${MICROPY_PY_DIR}/objcomplex.c @@ -90,6 +99,7 @@ set(MICROPY_SOURCE_PY ${MICROPY_PY_DIR}/objproperty.c ${MICROPY_PY_DIR}/objrange.c ${MICROPY_PY_DIR}/objreversed.c + ${MICROPY_PY_DIR}/objringio.c ${MICROPY_PY_DIR}/objset.c ${MICROPY_PY_DIR}/objsingleton.c ${MICROPY_PY_DIR}/objslice.c diff --git a/py/py.mk b/py/py.mk index bb5d8d2e91b..21be07c794f 100644 --- a/py/py.mk +++ b/py/py.mk @@ -36,12 +36,16 @@ ifneq ($(USER_C_MODULES),) # pre-define USERMOD variables as expanded so that variables are immediate # expanded as they're added to them +# Confirm the provided path exists, show abspath if not to make it clearer to fix. +$(if $(wildcard $(USER_C_MODULES)/.),,$(error USER_C_MODULES doesn't exist: $(abspath $(USER_C_MODULES)))) + # C/C++ files that are included in the QSTR/module build SRC_USERMOD_C := SRC_USERMOD_CXX := -# Other C/C++ files (e.g. libraries or helpers) +# Other C/C++/Assembly files (e.g. libraries or helpers) SRC_USERMOD_LIB_C := SRC_USERMOD_LIB_CXX := +SRC_USERMOD_LIB_ASM := # Optionally set flags CFLAGS_USERMOD := CXXFLAGS_USERMOD := @@ -63,6 +67,7 @@ SRC_USERMOD_PATHFIX_C += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD_C)) SRC_USERMOD_PATHFIX_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_CXX)) SRC_USERMOD_PATHFIX_LIB_C += $(patsubst $(USER_C_MODULES)/%.c,%.c,$(SRC_USERMOD_LIB_C)) SRC_USERMOD_PATHFIX_LIB_CXX += $(patsubst $(USER_C_MODULES)/%.cpp,%.cpp,$(SRC_USERMOD_LIB_CXX)) +SRC_USERMOD_PATHFIX_LIB_ASM += $(patsubst $(USER_C_MODULES)/%.S,%.S,$(SRC_USERMOD_LIB_ASM)) CFLAGS += $(CFLAGS_USERMOD) CXXFLAGS += $(CXXFLAGS_USERMOD) @@ -100,6 +105,8 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ nlrmips.o \ nlrpowerpc.o \ nlrxtensa.o \ + nlrrv32.o \ + nlrrv64.o \ nlrsetjmp.o \ malloc.o \ gc.o \ @@ -131,6 +138,10 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ emitnxtensa.o \ emitinlinextensa.o \ emitnxtensawin.o \ + asmrv32.o \ + emitnrv32.o \ + emitinlinerv32.o \ + emitndebug.o \ formatfloat.o \ parsenumbase.o \ parsenum.o \ @@ -143,6 +154,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ nativeglue.o \ pairheap.o \ ringbuf.o \ + cstack.o \ stackctrl.o \ argcheck.o \ warning.o \ @@ -155,6 +167,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ objboundmeth.o \ objcell.o \ objclosure.o \ + objcode.o \ objcomplex.o \ objdeque.o \ objdict.o \ @@ -178,6 +191,7 @@ PY_CORE_O_BASENAME = $(addprefix py/,\ objnamedtuple.o \ objrange.o \ objreversed.o \ + objringio.o \ objset.o \ objsingleton.o \ objslice.o \ @@ -276,7 +290,7 @@ $(HEADER_BUILD)/compressed_translations.generated.h: $(PY_SRC)/maketranslationda PY_CORE_O += $(PY_BUILD)/translations-$(TRANSLATION).o # build a list of registered modules for py/objmodule.c. -$(HEADER_BUILD)/moduledefs.h: $(HEADER_BUILD)/moduledefs.collected +$(HEADER_BUILD)/moduledefs.h: $(HEADER_BUILD)/moduledefs.collected $(PY_SRC)/makemoduledefs.py @$(ECHO) "GEN $@" $(Q)$(PYTHON) $(PY_SRC)/makemoduledefs.py $< > $@ diff --git a/py/qstr.c b/py/qstr.c index 6a5896bdaf4..ab9ff4dd67d 100644 --- a/py/qstr.c +++ b/py/qstr.c @@ -338,7 +338,7 @@ qstr qstr_from_str(const char *str) { return qstr_from_strn(str, strlen(str)); } -qstr qstr_from_strn(const char *str, size_t len) { +static qstr qstr_from_strn_helper(const char *str, size_t len, bool data_is_static) { QSTR_ENTER(); qstr q = qstr_find_strn(str, len); if (q == 0) { @@ -350,6 +350,12 @@ qstr qstr_from_strn(const char *str, size_t len) { mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("name too long")); } + if (data_is_static) { + // Given string data will be forever available so use it directly. + assert(str[len] == '\0'); + goto add; + } + // compute number of bytes needed to intern this string size_t n_bytes = len + 1; @@ -372,10 +378,11 @@ qstr qstr_from_strn(const char *str, size_t len) { if (al < MICROPY_ALLOC_QSTR_CHUNK_INIT) { al = MICROPY_ALLOC_QSTR_CHUNK_INIT; } - MP_STATE_VM(qstr_last_chunk) = m_new_maybe(char, al); + // CIRCUITPY-CHANGE: Don't collect the QSTR blocks that only contain a chunk of a string + MP_STATE_VM(qstr_last_chunk) = m_malloc_maybe_without_collect(sizeof(char) * al); if (MP_STATE_VM(qstr_last_chunk) == NULL) { // failed to allocate a large chunk so try with exact size - MP_STATE_VM(qstr_last_chunk) = m_new_maybe(char, n_bytes); + MP_STATE_VM(qstr_last_chunk) = m_malloc_maybe_without_collect(sizeof(char) * n_bytes); if (MP_STATE_VM(qstr_last_chunk) == NULL) { QSTR_EXIT(); m_malloc_fail(n_bytes); @@ -393,12 +400,26 @@ qstr qstr_from_strn(const char *str, size_t len) { // store the interned strings' data memcpy(q_ptr, str, len); q_ptr[len] = '\0'; - q = qstr_add(len, q_ptr); + str = q_ptr; + + add: + q = qstr_add(len, str); } QSTR_EXIT(); return q; } +qstr qstr_from_strn(const char *str, size_t len) { + return qstr_from_strn_helper(str, len, false); +} + +#if MICROPY_VFS_ROM +// Create a new qstr that can forever reference the given string data. +qstr qstr_from_strn_static(const char *str, size_t len) { + return qstr_from_strn_helper(str, len, true); +} +#endif + mp_uint_t qstr_hash(qstr q) { const qstr_pool_t *pool = find_qstr(&q); #if MICROPY_QSTR_BYTES_IN_HASH diff --git a/py/qstr.h b/py/qstr.h index 967990beea3..7dc04a8accb 100644 --- a/py/qstr.h +++ b/py/qstr.h @@ -107,6 +107,9 @@ qstr qstr_find_strn(const char *str, size_t str_len); // returns MP_QSTRnull if qstr qstr_from_str(const char *str); qstr qstr_from_strn(const char *str, size_t len); +#if MICROPY_VFS_ROM +qstr qstr_from_strn_static(const char *str, size_t len); +#endif mp_uint_t qstr_hash(qstr q); const char *qstr_str(qstr q); diff --git a/py/reader.c b/py/reader.c index 151e04cac2c..8feb6d75275 100644 --- a/py/reader.c +++ b/py/reader.c @@ -50,7 +50,7 @@ static mp_uint_t mp_reader_mem_readbyte(void *data) { static void mp_reader_mem_close(void *data) { mp_reader_mem_t *reader = (mp_reader_mem_t *)data; - if (reader->free_len > 0) { + if (reader->free_len > 0 && reader->free_len != MP_READER_IS_ROM) { m_del(char, (char *)reader->beg, reader->free_len); } m_del_obj(mp_reader_mem_t, reader); @@ -67,6 +67,19 @@ void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t reader->close = mp_reader_mem_close; } +const uint8_t *mp_reader_try_read_rom(mp_reader_t *reader, size_t len) { + if (reader->readbyte != mp_reader_mem_readbyte) { + return NULL; + } + mp_reader_mem_t *m = reader->data; + if (m->free_len != MP_READER_IS_ROM) { + return NULL; + } + const uint8_t *data = m->cur; + m->cur += len; + return data; +} + #if MICROPY_READER_POSIX #include diff --git a/py/reader.h b/py/reader.h index 5cb1e67966c..6378457007c 100644 --- a/py/reader.h +++ b/py/reader.h @@ -28,6 +28,10 @@ #include "py/obj.h" +// Pass to the `free_len` argument to `mp_reader_new_mem` to indicate that the data is in ROM. +// This means that the data is addressable and will remain valid at least until a soft reset. +#define MP_READER_IS_ROM ((size_t)-1) + // the readbyte function must return the next byte in the input stream // it must return MP_READER_EOF if end of stream // it can be called again after returning MP_READER_EOF, and in that case must return MP_READER_EOF @@ -43,4 +47,9 @@ void mp_reader_new_mem(mp_reader_t *reader, const byte *buf, size_t len, size_t void mp_reader_new_file(mp_reader_t *reader, qstr filename); void mp_reader_new_file_from_fd(mp_reader_t *reader, int fd, bool close_fd); +// Try to efficiently read the given number of bytes from a ROM-based reader. +// Returns a valid, non-NULL pointer to the requested data if the reader points to ROM. +// Returns NULL if the reader does not point to ROM. +const uint8_t *mp_reader_try_read_rom(mp_reader_t *reader, size_t len); + #endif // MICROPY_INCLUDED_PY_READER_H diff --git a/py/repl.c b/py/repl.c index ed47dbd0c17..bbfdd2ea6a6 100644 --- a/py/repl.c +++ b/py/repl.c @@ -181,8 +181,11 @@ static bool test_qstr(mp_obj_t obj, qstr name) { return dest[0] != MP_OBJ_NULL; } else { // try builtin module - return mp_map_lookup((mp_map_t *)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP) || - mp_map_lookup((mp_map_t *)&mp_builtin_extensible_module_map, MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP); + return mp_map_lookup((mp_map_t *)&mp_builtin_module_map, MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP) + #if MICROPY_HAVE_REGISTERED_EXTENSIBLE_MODULES + || mp_map_lookup((mp_map_t *)&mp_builtin_extensible_module_map, MP_OBJ_NEW_QSTR(name), MP_MAP_LOOKUP) + #endif + ; } } @@ -237,6 +240,10 @@ static void print_completions(const mp_print_t *print, for (qstr q = q_first; q <= q_last; ++q) { size_t d_len; const char *d_str = (const char *)qstr_data(q, &d_len); + // filter out words that begin with underscore unless there's already a partial match + if (s_len == 0 && d_str[0] == '_') { + continue; + } if (s_len <= d_len && strncmp(s_start, d_str, s_len) == 0) { if (test_qstr(obj, q)) { int gap = (line_len + WORD_SLOT_LEN - 1) / WORD_SLOT_LEN * WORD_SLOT_LEN - line_len; @@ -244,7 +251,6 @@ static void print_completions(const mp_print_t *print, gap += WORD_SLOT_LEN; } if (line_len + gap + d_len <= MAX_LINE_LEN) { - // TODO optimise printing of gap? for (int j = 0; j < gap; ++j) { mp_print_str(print, " "); } diff --git a/py/runtime.c b/py/runtime.c index 83aee5bc7b2..81abc3de875 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -45,9 +45,13 @@ #include "py/stream.h" #include "py/runtime.h" #include "py/builtin.h" -#include "py/stackctrl.h" +#include "py/cstack.h" #include "py/gc.h" +#if MICROPY_VFS_ROM && MICROPY_VFS_ROM_IOCTL +#include "extmod/vfs.h" +#endif + // CIRCUITPY-CHANGE #if CIRCUITPY_WARNINGS #include "shared-module/warnings/__init__.h" @@ -130,8 +134,8 @@ void mp_init(void) { MP_STATE_VM(mp_module_builtins_override_dict) = NULL; #endif - #if MICROPY_PERSISTENT_CODE_TRACK_RELOC_CODE - MP_STATE_VM(track_reloc_code_list) = MP_OBJ_NULL; + #if MICROPY_EMIT_MACHINE_CODE && (MICROPY_PERSISTENT_CODE_TRACK_FUN_DATA || MICROPY_PERSISTENT_CODE_TRACK_BSS_RODATA) + MP_STATE_VM(persistent_code_root_pointers) = MP_OBJ_NULL; #endif #if MICROPY_PY_OS_DUPTERM @@ -197,6 +201,11 @@ void mp_init(void) { #endif MP_THREAD_GIL_ENTER(); + + #if MICROPY_VFS_ROM && MICROPY_VFS_ROM_IOCTL + // Mount ROMFS if it exists. + mp_vfs_mount_romfs_protected(); + #endif } void mp_deinit(void) { @@ -251,8 +260,7 @@ mp_obj_t MICROPY_WRAP_MP_LOAD_GLOBAL(mp_load_global)(qstr qst) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_NameError, MP_ERROR_TEXT("name not defined")); #else - // CIRCUITPY-CHANGE: slight message change - mp_raise_msg_varg(&mp_type_NameError, MP_ERROR_TEXT("name '%q' is not defined"), qst); + mp_raise_msg_varg(&mp_type_NameError, MP_ERROR_TEXT("name '%q' isn't defined"), qst); #endif } } @@ -438,7 +446,7 @@ mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs // Operations that can overflow: // + result always fits in mp_int_t, then handled by SMALL_INT check // - result always fits in mp_int_t, then handled by SMALL_INT check - // * checked explicitly + // * checked explicitly for fit in mp_int_t, then handled by SMALL_INT check // / if lhs=MIN and rhs=-1; result always fits in mp_int_t, then handled by SMALL_INT check // % if lhs=MIN and rhs=-1; result always fits in mp_int_t, then handled by SMALL_INT check // << checked explicitly @@ -497,30 +505,16 @@ mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs break; case MP_BINARY_OP_MULTIPLY: case MP_BINARY_OP_INPLACE_MULTIPLY: { - - // If long long type exists and is larger than mp_int_t, then - // we can use the following code to perform overflow-checked multiplication. - // Otherwise (eg in x64 case) we must use mp_small_int_mul_overflow. - #if 0 - // compute result using long long precision - long long res = (long long)lhs_val * (long long)rhs_val; - if (res > MP_SMALL_INT_MAX || res < MP_SMALL_INT_MIN) { - // result overflowed SMALL_INT, so return higher precision integer - return mp_obj_new_int_from_ll(res); - } else { - // use standard precision - lhs_val = (mp_int_t)res; - } - #endif - - if (mp_small_int_mul_overflow(lhs_val, rhs_val)) { + mp_int_t int_res; + if (mp_mul_mp_int_t_overflow(lhs_val, rhs_val, &int_res)) { // use higher precision lhs = mp_obj_new_int_from_ll(lhs_val); goto generic_binary_op; } else { // use standard precision - return MP_OBJ_NEW_SMALL_INT(lhs_val * rhs_val); + lhs_val = int_res; } + break; } case MP_BINARY_OP_FLOOR_DIVIDE: case MP_BINARY_OP_INPLACE_FLOOR_DIVIDE: @@ -560,19 +554,19 @@ mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs mp_int_t ans = 1; while (rhs_val > 0) { if (rhs_val & 1) { - if (mp_small_int_mul_overflow(ans, lhs_val)) { + if (mp_mul_mp_int_t_overflow(ans, lhs_val, &ans)) { goto power_overflow; } - ans *= lhs_val; } if (rhs_val == 1) { break; } rhs_val /= 2; - if (mp_small_int_mul_overflow(lhs_val, lhs_val)) { + mp_int_t int_res; + if (mp_mul_mp_int_t_overflow(lhs_val, lhs_val, &int_res)) { goto power_overflow; } - lhs_val *= lhs_val; + lhs_val = int_res; } lhs_val = ans; } @@ -739,8 +733,8 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not callable")); #else - // CIRCUITPY-CHANGE: use new raise function and different message - mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object is not callable"), mp_obj_get_type_qstr(fun_in)); + // CIRCUITPY-CHANGE: more specific mp_raise + mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object isn't callable"), mp_obj_get_type_qstr(fun_in)); #endif } @@ -968,7 +962,7 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_ob // unpacked items are stored in reverse order into the array pointed to by items // CIRCUITPY-CHANGE: noline -void __attribute__((noinline, )) mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { +MP_NOINLINE void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { size_t seq_len; if (mp_obj_is_type(seq_in, &mp_type_tuple) || mp_obj_is_type(seq_in, &mp_type_list)) { mp_obj_t *seq_items; @@ -1177,6 +1171,10 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t // base type (which is what is passed in the `type` argument to this function). if (self != MP_OBJ_NULL) { type = mp_obj_get_type(self); + if (type == &mp_type_type) { + // `self` is already a type, so use `self` directly. + type = MP_OBJ_TO_PTR(self); + } } dest[0] = ((mp_obj_static_class_method_t *)MP_OBJ_TO_PTR(member))->fun; dest[1] = MP_OBJ_FROM_PTR(type); @@ -1289,6 +1287,19 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) { mp_raise_msg_varg(&mp_type_AttributeError, MP_ERROR_TEXT("type object '%q' has no attribute '%q'"), ((mp_obj_type_t *)MP_OBJ_TO_PTR(base))->name, attr); + #if MICROPY_MODULE___ALL__ && MICROPY_ERROR_REPORTING >= MICROPY_ERROR_REPORTING_DETAILED + } else if (mp_obj_is_type(base, &mp_type_module)) { + // report errors in __all__ as done by CPython + mp_obj_t dest_name[2]; + qstr module_name = MP_QSTR_; + mp_load_method_maybe(base, MP_QSTR___name__, dest_name); + if (mp_obj_is_qstr(dest_name[0])) { + module_name = mp_obj_str_get_qstr(dest_name[0]); + } + mp_raise_msg_varg(&mp_type_AttributeError, + MP_ERROR_TEXT("module '%q' has no attribute '%q'"), + module_name, attr); + #endif } else { mp_raise_msg_varg(&mp_type_AttributeError, MP_ERROR_TEXT("'%s' object has no attribute '%q'"), @@ -1413,9 +1424,9 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not iterable")); #else - // CIRCUITPY-CHANGE: raise function + // CIRCUITPY-CHANGE: more specific mp_raise mp_raise_TypeError_varg( - MP_ERROR_TEXT("'%q' object is not iterable"), mp_obj_get_type_qstr(o_in)); + MP_ERROR_TEXT("'%q' object isn't iterable"), mp_obj_get_type_qstr(o_in)); #endif } @@ -1450,8 +1461,8 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator")); #else - // CIRCUITPY-CHANGE: raise function - mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object is not an iterator"), + // CIRCUITPY-CHANGE: more specific mp_raise + mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object isn't an iterator"), mp_obj_get_type_qstr(o_in)); #endif } @@ -1461,7 +1472,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { // will always return MP_OBJ_STOP_ITERATION instead of raising StopIteration() (or any subclass thereof) // may raise other exceptions mp_obj_t mp_iternext(mp_obj_t o_in) { - MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext + mp_cstack_check(); // enumerate, filter, map and zip can recursively call mp_iternext const mp_obj_type_t *type = mp_obj_get_type(o_in); if (TYPE_HAS_ITERNEXT(type)) { MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; @@ -1488,8 +1499,8 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator")); #else - // CIRCUITPY-CHANGE: raise function - mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object is not an iterator"), + // CIRCUITPY-CHANGE: more specific mp_raise + mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object isn't an iterator"), mp_obj_get_type_qstr(o_in)); #endif } @@ -1607,7 +1618,7 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) { // build args array mp_obj_t args[5]; args[0] = MP_OBJ_NEW_QSTR(name); - args[1] = mp_const_none; // TODO should be globals + args[1] = MP_OBJ_FROM_PTR(mp_globals_get()); // globals of the current context args[2] = mp_const_none; // TODO should be locals args[3] = fromlist; args[4] = level; @@ -1627,20 +1638,17 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) { } // CIRCUITPY-CHANGE: noinline -mp_obj_t __attribute__((noinline, )) mp_import_from(mp_obj_t module, qstr name) { +MP_NOINLINE mp_obj_t mp_import_from(mp_obj_t module, qstr name) { DEBUG_printf("import from %p %s\n", module, qstr_str(name)); mp_obj_t dest[2]; mp_load_method_maybe(module, name, dest); - if (dest[1] != MP_OBJ_NULL) { - // Hopefully we can't import bound method from an object - import_error: - mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("can't import name %q"), name); - } - - if (dest[0] != MP_OBJ_NULL) { + // Importing a bound method from a class instance. + return mp_obj_new_bound_meth(dest[0], dest[1]); + } else if (dest[0] != MP_OBJ_NULL) { + // Importing a function or attribute. return dest[0]; } @@ -1673,33 +1681,36 @@ mp_obj_t __attribute__((noinline, )) mp_import_from(mp_obj_t module, qstr name) goto import_error; #endif + +import_error: + mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("can't import name %q"), name); } void mp_import_all(mp_obj_t module) { DEBUG_printf("import all %p\n", module); - // CIRCUITPY-CHANGE: displayio name changes; remove in 10.0 - #if CIRCUITPY_DISPLAYIO && CIRCUITPY_WARNINGS - if (module == &displayio_module) { - #if CIRCUITPY_BUSDISPLAY - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_Display, MP_QSTR_displayio, MP_QSTR_busdisplay); - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q renamed %q"), MP_QSTR_Display, MP_QSTR_BusDisplay); - #endif - #if CIRCUITPY_EPAPERDISPLAY - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_EPaperDisplay, MP_QSTR_displayio, MP_QSTR_epaperdisplay); - #endif - #if CIRCUITPY_FOURWIRE - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_FourWire, MP_QSTR_displayio, MP_QSTR_fourwire); - #endif - #if CIRCUITPY_I2CDISPLAYBUS - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q moved from %q to %q"), MP_QSTR_I2CDisplay, MP_QSTR_displayio, MP_QSTR_i2cdisplaybus); - warnings_warn(&mp_type_FutureWarning, MP_ERROR_TEXT("%q renamed %q"), MP_QSTR_I2CDisplay, MP_QSTR_I2CDisplayBus); - #endif + mp_map_t *map = &mp_obj_module_get_globals(module)->map; + + #if MICROPY_MODULE___ALL__ + mp_map_elem_t *elem = mp_map_lookup(map, MP_OBJ_NEW_QSTR(MP_QSTR___all__), MP_MAP_LOOKUP); + if (elem != NULL) { + // When __all__ is defined, we must explicitly load all specified + // symbols, possibly invoking the module __getattr__ function + size_t len; + mp_obj_t *items; + mp_obj_get_array(elem->value, &len, &items); + for (size_t i = 0; i < len; i++) { + qstr qname = mp_obj_str_get_qstr(items[i]); + mp_obj_t dest[2]; + mp_load_method(module, qname, dest); + mp_store_name(qname, dest[0]); + } + return; } #endif - // TODO: Support __all__ - mp_map_t *map = &mp_obj_module_get_globals(module)->map; + // By default, the set of public names includes all names found in the module's + // namespace which do not begin with an underscore character ('_') for (size_t i = 0; i < map->alloc; i++) { if (mp_map_slot_is_filled(map, i)) { // Entry in module global scope may be generated programmatically @@ -1734,10 +1745,13 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i mp_obj_t module_fun = mp_compile(&parse_tree, source_name, parse_input_kind == MP_PARSE_SINGLE_INPUT); mp_obj_t ret; - if (MICROPY_PY_BUILTINS_COMPILE && globals == NULL) { + #if MICROPY_PY_BUILTINS_COMPILE && MICROPY_PY_BUILTINS_CODE == MICROPY_PY_BUILTINS_CODE_MINIMUM + if (globals == NULL) { // for compile only, return value is the module function ret = module_fun; - } else { + } else + #endif + { // execute module function and get return value ret = mp_call_function_0(module_fun); } @@ -1752,7 +1766,7 @@ mp_obj_t mp_parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t parse_i #endif // MICROPY_ENABLE_COMPILER // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void m_malloc_fail(size_t num_bytes) { +MP_COLD MP_NORETURN void m_malloc_fail(size_t num_bytes) { DEBUG_printf("memory allocation failed, allocating %u bytes\n", (uint)num_bytes); #if MICROPY_ENABLE_GC if (gc_is_locked()) { @@ -1766,29 +1780,29 @@ NORETURN MP_COLD void m_malloc_fail(size_t num_bytes) { #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_type(const mp_obj_type_t *exc_type) { +MP_COLD MP_NORETURN void mp_raise_type(const mp_obj_type_t *exc_type) { nlr_raise(mp_obj_new_exception(exc_type)); } // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_ValueError_no_msg(void) { +MP_COLD MP_NORETURN void mp_raise_ValueError_no_msg(void) { mp_raise_type(&mp_type_ValueError); } // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_TypeError_no_msg(void) { +MP_COLD MP_NORETURN void mp_raise_TypeError_no_msg(void) { mp_raise_type(&mp_type_TypeError); } // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_NotImplementedError_no_msg(void) { +MP_COLD MP_NORETURN void mp_raise_NotImplementedError_no_msg(void) { mp_raise_type(&mp_type_NotImplementedError); } #else // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); } else { @@ -1797,24 +1811,24 @@ NORETURN MP_COLD void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_t } // CIRCUITPY-CHANGE: new function for use below. -NORETURN MP_COLD void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, va_list argptr) { +MP_COLD MP_NORETURN void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, va_list argptr) { mp_obj_t exception = mp_obj_new_exception_msg_vlist(exc_type, fmt, argptr); nlr_raise(exception); } // CIRCUITPY-CHANGE: MP_COLD and use mp_raise_msg_vlist() -NORETURN MP_COLD void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(exc_type, fmt, argptr); va_end(argptr); } -NORETURN MP_COLD void mp_raise_ValueError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_ValueError, msg); } -NORETURN MP_COLD void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { +MP_COLD MP_NORETURN void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); } else { @@ -1823,17 +1837,17 @@ NORETURN MP_COLD void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_AttributeError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_AttributeError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_AttributeError, msg); } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_RuntimeError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_RuntimeError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_RuntimeError, msg); } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_RuntimeError_varg(mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_RuntimeError_varg(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_RuntimeError, fmt, argptr); @@ -1841,17 +1855,17 @@ NORETURN MP_COLD void mp_raise_RuntimeError_varg(mp_rom_error_text_t fmt, ...) { } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_ImportError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_ImportError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_ImportError, msg); } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_IndexError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_IndexError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_IndexError, msg); } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_IndexError_varg(mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_IndexError_varg(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_IndexError, fmt, argptr); @@ -1859,7 +1873,7 @@ NORETURN MP_COLD void mp_raise_IndexError_varg(mp_rom_error_text_t fmt, ...) { } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_ValueError_varg(mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_ValueError_varg(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_ValueError, fmt, argptr); @@ -1867,12 +1881,12 @@ NORETURN MP_COLD void mp_raise_ValueError_varg(mp_rom_error_text_t fmt, ...) { } // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_TypeError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_TypeError, msg); } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_TypeError_varg(mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_TypeError_varg(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_TypeError, fmt, argptr); @@ -1880,12 +1894,12 @@ NORETURN MP_COLD void mp_raise_TypeError_varg(mp_rom_error_text_t fmt, ...) { } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_OSError_msg(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_OSError_msg(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_OSError, msg); } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { +MP_COLD MP_NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(errno_), str, @@ -1894,7 +1908,7 @@ NORETURN MP_COLD void mp_raise_OSError_errno_str(int errno_, mp_obj_t str) { } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_OSError_msg_varg(mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_OSError_msg_varg(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_OSError, fmt, argptr); @@ -1902,21 +1916,23 @@ NORETURN MP_COLD void mp_raise_OSError_msg_varg(mp_rom_error_text_t fmt, ...) { } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_ConnectionError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_ConnectionError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_ConnectionError, msg); } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_BrokenPipeError(void) { +MP_COLD MP_NORETURN void mp_raise_BrokenPipeError(void) { mp_raise_type_arg(&mp_type_BrokenPipeError, MP_OBJ_NEW_SMALL_INT(MP_EPIPE)); } -NORETURN MP_COLD void mp_raise_NotImplementedError(mp_rom_error_text_t msg) { +MP_COLD MP_NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } +#endif + // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_NotImplementedError_varg(mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_NotImplementedError_varg(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_NotImplementedError, fmt, argptr); @@ -1924,7 +1940,7 @@ NORETURN MP_COLD void mp_raise_NotImplementedError_varg(mp_rom_error_text_t fmt, } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_OverflowError_varg(mp_rom_error_text_t fmt, ...) { +MP_COLD MP_NORETURN void mp_raise_OverflowError_varg(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_raise_msg_vlist(&mp_type_OverflowError, fmt, argptr); @@ -1932,12 +1948,11 @@ NORETURN MP_COLD void mp_raise_OverflowError_varg(mp_rom_error_text_t fmt, ...) } // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg) { +MP_COLD MP_NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg) { nlr_raise(mp_obj_new_exception_arg1(exc_type, arg)); } -// CIRCUITPY-CHANGE: MP_COLD -NORETURN void mp_raise_StopIteration(mp_obj_t arg) { +MP_NORETURN void mp_raise_StopIteration(mp_obj_t arg) { if (arg == MP_OBJ_NULL) { mp_raise_type(&mp_type_StopIteration); } else { @@ -1945,7 +1960,7 @@ NORETURN void mp_raise_StopIteration(mp_obj_t arg) { } } -NORETURN void mp_raise_TypeError_int_conversion(mp_const_obj_t arg) { +MP_NORETURN void mp_raise_TypeError_int_conversion(mp_const_obj_t arg) { #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE (void)arg; mp_raise_TypeError(MP_ERROR_TEXT("can't convert to int")); @@ -1956,12 +1971,12 @@ NORETURN void mp_raise_TypeError_int_conversion(mp_const_obj_t arg) { } // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_OSError(int errno_) { +MP_COLD MP_NORETURN void mp_raise_OSError(int errno_) { mp_raise_type_arg(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_)); } // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_OSError_with_filename(int errno_, const char *filename) { +MP_COLD MP_NORETURN void mp_raise_OSError_with_filename(int errno_, const char *filename) { vstr_t vstr; vstr_init(&vstr, 32); vstr_printf(&vstr, "can't open %s", filename); @@ -1971,13 +1986,12 @@ NORETURN MP_COLD void mp_raise_OSError_with_filename(int errno_, const char *fil } // CIRCUITPY-CHANGE: added -NORETURN MP_COLD void mp_raise_ZeroDivisionError(void) { +MP_COLD MP_NORETURN void mp_raise_ZeroDivisionError(void) { mp_raise_msg(&mp_type_ZeroDivisionError, MP_ERROR_TEXT("division by zero")); } #if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK // CIRCUITPY-CHANGE: MP_COLD -NORETURN MP_COLD void mp_raise_recursion_depth(void) { +MP_COLD MP_NORETURN void mp_raise_recursion_depth(void) { mp_raise_RuntimeError(MP_ERROR_TEXT("maximum recursion depth exceeded")); } #endif -#endif diff --git a/py/runtime.h b/py/runtime.h index b92eb23c9d7..22ed9c3eaf9 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -30,18 +30,19 @@ #include "py/mpstate.h" #include "py/pystack.h" -#include "py/stackctrl.h" +#include "py/cstack.h" // CIRCUITPY-CHANGE #include "supervisor/linker.h" #include "supervisor/shared/translate/translate.h" // For use with mp_call_function_1_from_nlr_jump_callback. +// Initialize an nlr_jump_callback_node_call_function_1_t struct for use with +// nlr_push_jump_callback(&ctx.callback, mp_call_function_1_from_nlr_jump_callback); #define MP_DEFINE_NLR_JUMP_CALLBACK_FUNCTION_1(ctx, f, a) \ - nlr_jump_callback_node_call_function_1_t ctx = { \ - .func = (void (*)(void *))(f), \ - .arg = (a), \ - } + nlr_jump_callback_node_call_function_1_t ctx; \ + ctx.func = (void (*)(void *))(f); \ + ctx.arg = (a) typedef enum { MP_VM_RETURN_NORMAL, @@ -58,6 +59,12 @@ typedef enum { MP_ARG_KW_ONLY = 0x200, } mp_arg_flag_t; +typedef enum { + MP_HANDLE_PENDING_CALLBACKS_ONLY, + MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS, + MP_HANDLE_PENDING_CALLBACKS_AND_CLEAR_EXCEPTIONS, +} mp_handle_pending_behaviour_t; + typedef union _mp_arg_val_t { bool u_bool; mp_int_t u_int; @@ -106,7 +113,14 @@ void mp_sched_keyboard_interrupt(void); #if MICROPY_ENABLE_VM_ABORT void mp_sched_vm_abort(void); #endif -void mp_handle_pending(bool raise_exc); + +void mp_handle_pending_internal(mp_handle_pending_behaviour_t behavior); + +static inline void mp_handle_pending(bool raise_exc) { + mp_handle_pending_internal(raise_exc ? + MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS : + MP_HANDLE_PENDING_CALLBACKS_AND_CLEAR_EXCEPTIONS); +} #if MICROPY_ENABLE_SCHEDULER void mp_sched_lock(void); @@ -134,7 +148,7 @@ void mp_event_wait_indefinite(void); void mp_event_wait_ms(mp_uint_t timeout_ms); // extra printing method specifically for mp_obj_t's which are integral type -int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, int base, int base_char, int flags, char fill, int width, int prec); +int mp_print_mp_int(const mp_print_t *print, mp_obj_t x, unsigned base, int base_char, int flags, char fill, int width, int prec); void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig); static inline void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_min, size_t n_args_max, bool takes_kw) { @@ -142,11 +156,11 @@ static inline void mp_arg_check_num(size_t n_args, size_t n_kw, size_t n_args_mi } void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args, size_t n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); -NORETURN void mp_arg_error_terse_mismatch(void); -NORETURN void mp_arg_error_unimpl_kw(void); +MP_NORETURN void mp_arg_error_terse_mismatch(void); +MP_NORETURN void mp_arg_error_unimpl_kw(void); // CIRCUITPY-CHANGE: arg validation routines -NORETURN void mp_arg_error_invalid(qstr arg_name); +MP_NORETURN void mp_arg_error_invalid(qstr arg_name); mp_int_t mp_arg_validate_int(mp_int_t i, mp_int_t required_i, qstr arg_name); mp_int_t mp_arg_validate_int_min(mp_int_t i, mp_int_t min, qstr arg_name); mp_int_t mp_arg_validate_int_max(mp_int_t i, mp_int_t j, qstr arg_name); @@ -188,16 +202,22 @@ void mp_call_function_1_from_nlr_jump_callback(void *ctx_in); static inline void mp_thread_init_state(mp_state_thread_t *ts, size_t stack_size, mp_obj_dict_t *locals, mp_obj_dict_t *globals) { mp_thread_set_state(ts); - mp_stack_set_top(ts + 1); // need to include ts in root-pointer scan - mp_stack_set_limit(stack_size); + mp_cstack_init_with_top(ts + 1, stack_size); // need to include ts in root-pointer scan // GC starts off unlocked ts->gc_lock_depth = 0; // There are no pending jump callbacks or exceptions yet + ts->nlr_top = NULL; ts->nlr_jump_callback_top = NULL; ts->mp_pending_exception = MP_OBJ_NULL; + #if MICROPY_PY_SYS_SETTRACE + ts->prof_trace_callback = MP_OBJ_NULL; + ts->prof_callback_is_executing = false; + ts->current_code_state = NULL; + #endif + // If locals/globals are not given, inherit from main thread if (locals == NULL) { locals = mp_state_ctx.thread.dict_locals; @@ -275,10 +295,10 @@ mp_obj_t mp_import_from(mp_obj_t module, qstr name); void mp_import_all(mp_obj_t module); #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE -NORETURN void mp_raise_type(const mp_obj_type_t *exc_type); -NORETURN void mp_raise_ValueError_no_msg(void); -NORETURN void mp_raise_TypeError_no_msg(void); -NORETURN void mp_raise_NotImplementedError_no_msg(void); +MP_NORETURN void mp_raise_type(const mp_obj_type_t *exc_type); +MP_NORETURN void mp_raise_ValueError_no_msg(void); +MP_NORETURN void mp_raise_TypeError_no_msg(void); +MP_NORETURN void mp_raise_NotImplementedError_no_msg(void); #define mp_raise_msg(exc_type, msg) mp_raise_type(exc_type) #define mp_raise_msg_varg(exc_type, ...) mp_raise_type(exc_type) #define mp_raise_ValueError(msg) mp_raise_ValueError_no_msg() @@ -286,46 +306,46 @@ NORETURN void mp_raise_NotImplementedError_no_msg(void); #define mp_raise_NotImplementedError(msg) mp_raise_NotImplementedError_no_msg() #else #define mp_raise_type(exc_type) mp_raise_msg(exc_type, NULL) -NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); -NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg); -NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg); -NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg); #endif // CIRCUITPY-CHANGE: new mp_raise routines -NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg); -NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); -NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt +MP_NORETURN void mp_raise_type_arg(const mp_obj_type_t *exc_type, mp_obj_t arg); +MP_NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt , ...); -NORETURN void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, va_list argptr); +MP_NORETURN void mp_raise_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, va_list argptr); // Only use this string version in native mpy files. Otherwise, use the compressed string version. -NORETURN void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg); - -NORETURN void mp_raise_AttributeError(mp_rom_error_text_t msg); -NORETURN void mp_raise_BrokenPipeError(void); -NORETURN void mp_raise_ConnectionError(mp_rom_error_text_t msg); -NORETURN void mp_raise_ImportError(mp_rom_error_text_t msg); -NORETURN void mp_raise_IndexError(mp_rom_error_text_t msg); -NORETURN void mp_raise_IndexError_varg(mp_rom_error_text_t msg, ...); -NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg); -NORETURN void mp_raise_NotImplementedError_varg(mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str); -NORETURN void mp_raise_OSError(int errno_); -NORETURN void mp_raise_OSError_msg(mp_rom_error_text_t msg); -NORETURN void mp_raise_OSError_msg_varg(mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_OSError_with_filename(int errno_, const char *filename); -NORETURN void mp_raise_OverflowError_varg(mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_recursion_depth(void); -NORETURN void mp_raise_RuntimeError(mp_rom_error_text_t msg); -NORETURN void mp_raise_RuntimeError_varg(mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_StopIteration(mp_obj_t arg); -NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg); -NORETURN void mp_raise_TypeError_varg(mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_TypeError_int_conversion(mp_const_obj_t arg); -NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg); -NORETURN void mp_raise_ValueError_varg(mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_ZeroDivisionError(void); +MP_NORETURN void mp_raise_msg_str(const mp_obj_type_t *exc_type, const char *msg); + +MP_NORETURN void mp_raise_AttributeError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_BrokenPipeError(void); +MP_NORETURN void mp_raise_ConnectionError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_ImportError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_IndexError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_IndexError_varg(mp_rom_error_text_t msg, ...); +MP_NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_NotImplementedError_varg(mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_OSError_errno_str(int errno_, mp_obj_t str); +MP_NORETURN void mp_raise_OSError(int errno_); +MP_NORETURN void mp_raise_OSError_msg(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_OSError_msg_varg(mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_OSError_with_filename(int errno_, const char *filename); +MP_NORETURN void mp_raise_OverflowError_varg(mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_recursion_depth(void); +MP_NORETURN void mp_raise_RuntimeError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_RuntimeError_varg(mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_StopIteration(mp_obj_t arg); +MP_NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_TypeError_varg(mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_TypeError_int_conversion(mp_const_obj_t arg); +MP_NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_ValueError_varg(mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_ZeroDivisionError(void); #if MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG #undef mp_check_self diff --git a/py/runtime_utils.c b/py/runtime_utils.c index 98252c31220..33da558e30f 100644 --- a/py/runtime_utils.c +++ b/py/runtime_utils.c @@ -53,3 +53,59 @@ mp_obj_t mp_call_function_2_protected(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2 return MP_OBJ_NULL; } } + +#if !MICROPY_USE_GCC_MUL_OVERFLOW_INTRINSIC +bool mp_mul_ll_overflow(long long int x, long long int y, long long int *res) { + bool overflow; + + // Check for multiply overflow; see CERT INT32-C + if (x > 0) { // x is positive + if (y > 0) { // x and y are positive + overflow = (x > (LLONG_MAX / y)); + } else { // x positive, y nonpositive + overflow = (y < (LLONG_MIN / x)); + } // x positive, y nonpositive + } else { // x is nonpositive + if (y > 0) { // x is nonpositive, y is positive + overflow = (x < (LLONG_MIN / y)); + } else { // x and y are nonpositive + overflow = (x != 0 && y < (LLONG_MAX / x)); + } // End if x and y are nonpositive + } // End if x is nonpositive + + if (!overflow) { + *res = x * y; + } + + return overflow; +} + +bool mp_mul_mp_int_t_overflow(mp_int_t x, mp_int_t y, mp_int_t *res) { + // Check for multiply overflow; see CERT INT32-C + if (x > 0) { // x is positive + if (y > 0) { // x and y are positive + if (x > (MP_INT_MAX / y)) { + return true; + } + } else { // x positive, y nonpositive + if (y < (MP_INT_MIN / x)) { + return true; + } + } // x positive, y nonpositive + } else { // x is nonpositive + if (y > 0) { // x is nonpositive, y is positive + if (x < (MP_INT_MIN / y)) { + return true; + } + } else { // x and y are nonpositive + if (x != 0 && y < (MP_INT_MAX / x)) { + return true; + } + } // End if x and y are nonpositive + } // End if x is nonpositive + + // Result doesn't overflow + *res = x * y; + return false; +} +#endif diff --git a/py/scheduler.c b/py/scheduler.c index cb5f1043cc4..ee9cd96b331 100644 --- a/py/scheduler.c +++ b/py/scheduler.c @@ -29,6 +29,10 @@ #include "py/mphal.h" #include "py/runtime.h" +#ifdef __ZEPHYR__ +#include +#endif + // Schedules an exception on the main thread (for exceptions "thrown" by async // sources such as interrupts and UNIX signal handlers). void MICROPY_WRAP_MP_SCHED_EXCEPTION(mp_sched_exception)(mp_obj_t exc) { @@ -50,6 +54,10 @@ void MICROPY_WRAP_MP_SCHED_KEYBOARD_INTERRUPT(mp_sched_keyboard_interrupt)(void) // CIRCUITPY-CHANGE: traceback differences MP_STATE_VM(mp_kbd_exception).traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; mp_sched_exception(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_kbd_exception))); + + #ifdef __ZEPHYR__ + k_sem_give(&mp_interrupt_sem); + #endif } #endif @@ -89,17 +97,21 @@ static inline void mp_sched_run_pending(void) { #if MICROPY_SCHEDULER_STATIC_NODES // Run all pending C callbacks. - while (MP_STATE_VM(sched_head) != NULL) { - mp_sched_node_t *node = MP_STATE_VM(sched_head); - MP_STATE_VM(sched_head) = node->next; - if (MP_STATE_VM(sched_head) == NULL) { - MP_STATE_VM(sched_tail) = NULL; - } - mp_sched_callback_t callback = node->callback; - node->callback = NULL; - MICROPY_END_ATOMIC_SECTION(atomic_state); - callback(node); - atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + mp_sched_node_t *original_tail = MP_STATE_VM(sched_tail); + if (original_tail != NULL) { + mp_sched_node_t *node; + do { + node = MP_STATE_VM(sched_head); + MP_STATE_VM(sched_head) = node->next; + if (MP_STATE_VM(sched_head) == NULL) { + MP_STATE_VM(sched_tail) = NULL; + } + mp_sched_callback_t callback = node->callback; + node->callback = NULL; + MICROPY_END_ATOMIC_SECTION(atomic_state); + callback(node); + atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); + } while (node != original_tail); // Don't execute any callbacks scheduled during this run } #endif @@ -210,24 +222,27 @@ MP_REGISTER_ROOT_POINTER(mp_sched_item_t sched_queue[MICROPY_SCHEDULER_DEPTH]); // Called periodically from the VM or from "waiting" code (e.g. sleep) to // process background tasks and pending exceptions (e.g. KeyboardInterrupt). -void mp_handle_pending(bool raise_exc) { +void mp_handle_pending_internal(mp_handle_pending_behaviour_t behavior) { + bool handle_exceptions = (behavior != MP_HANDLE_PENDING_CALLBACKS_ONLY); + bool raise_exceptions = (behavior == MP_HANDLE_PENDING_CALLBACKS_AND_EXCEPTIONS); + // Handle pending VM abort. #if MICROPY_ENABLE_VM_ABORT - if (MP_STATE_VM(vm_abort) && mp_thread_is_main_thread()) { + if (handle_exceptions && MP_STATE_VM(vm_abort) && mp_thread_is_main_thread()) { MP_STATE_VM(vm_abort) = false; - if (raise_exc && nlr_get_abort() != NULL) { + if (raise_exceptions && nlr_get_abort() != NULL) { nlr_jump_abort(); } } #endif // Handle any pending exception. - if (MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) { + if (handle_exceptions && MP_STATE_THREAD(mp_pending_exception) != MP_OBJ_NULL) { mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION(); mp_obj_t obj = MP_STATE_THREAD(mp_pending_exception); if (obj != MP_OBJ_NULL) { MP_STATE_THREAD(mp_pending_exception) = MP_OBJ_NULL; - if (raise_exc) { + if (raise_exceptions) { MICROPY_END_ATOMIC_SECTION(atomic_state); nlr_raise(obj); } @@ -237,7 +252,13 @@ void mp_handle_pending(bool raise_exc) { // Handle any pending callbacks. #if MICROPY_ENABLE_SCHEDULER - if (MP_STATE_VM(sched_state) == MP_SCHED_PENDING) { + bool run_scheduler = (MP_STATE_VM(sched_state) == MP_SCHED_PENDING); + #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL + // Avoid races by running the scheduler on the main thread, only. + // (Not needed if GIL enabled, as GIL ensures thread safety here.) + run_scheduler = run_scheduler && mp_thread_is_main_thread(); + #endif + if (run_scheduler) { mp_sched_run_pending(); } #endif @@ -263,10 +284,6 @@ void mp_event_wait_indefinite(void) { MICROPY_EVENT_POLL_HOOK #else mp_event_handle_nowait(); - - // CIRCUITPY-CHANGE: don't starve CircuitPython background tasks - RUN_BACKGROUND_TASKS; - MICROPY_INTERNAL_WFE(-1); #endif } @@ -279,10 +296,6 @@ void mp_event_wait_ms(mp_uint_t timeout_ms) { MICROPY_EVENT_POLL_HOOK #else mp_event_handle_nowait(); - - // CIRCUITPY-CHANGE: don't starve CircuitPython background tasks - RUN_BACKGROUND_TASKS; - MICROPY_INTERNAL_WFE(timeout_ms); #endif } diff --git a/py/sequence.c b/py/sequence.c index cc89d1b0b05..6bbc62f0f7f 100644 --- a/py/sequence.c +++ b/py/sequence.c @@ -34,18 +34,13 @@ #define SWAP(type, var1, var2) { type t = var2; var2 = var1; var1 = t; } // CIRCUITPY-CHANGE: detect sequence overflow -#if __GNUC__ < 5 -// n.b. does not actually detect overflow! -#define __builtin_mul_overflow(a, b, x) (*(x) = (a) * (b), false) -#endif - // Detect when a multiply causes an overflow. size_t mp_seq_multiply_len(size_t item_sz, size_t len) { - size_t new_len; - if (__builtin_mul_overflow(item_sz, len, &new_len)) { + mp_int_t new_len; + if (mp_mul_mp_int_t_overflow(item_sz, len, &new_len)) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("small int overflow")); } - return new_len; + return (size_t)new_len; } // Implements backend of sequence * integer operation. Assumes elements are @@ -78,11 +73,7 @@ bool mp_seq_get_fast_slice_indexes(mp_uint_t len, mp_obj_t slice, mp_bound_slice return indexes->step == 1; } -#endif - -mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t *indexes) { - (void)len; // TODO can we remove len from the arg list? - +mp_obj_t mp_seq_extract_slice(const mp_obj_t *seq, mp_bound_slice_t *indexes) { mp_int_t start = indexes->start, stop = indexes->stop; mp_int_t step = indexes->step; @@ -102,6 +93,8 @@ mp_obj_t mp_seq_extract_slice(size_t len, const mp_obj_t *seq, mp_bound_slice_t return res; } +#endif + // Special-case comparison function for sequences of bytes // Don't pass MP_BINARY_OP_NOT_EQUAL here bool mp_seq_cmp_bytes(mp_uint_t op, const byte *data1, size_t len1, const byte *data2, size_t len2) { diff --git a/py/showbc.c b/py/showbc.c index 6913d18c1ca..792fccd0133 100644 --- a/py/showbc.c +++ b/py/showbc.c @@ -144,17 +144,9 @@ void mp_bytecode_print(const mp_print_t *print, const mp_raw_code_t *rc, size_t mp_uint_t source_line = 1; mp_printf(print, " bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line); for (const byte *ci = code_info; ci < line_info_top;) { - if ((ci[0] & 0x80) == 0) { - // 0b0LLBBBBB encoding - bc += ci[0] & 0x1f; - source_line += ci[0] >> 5; - ci += 1; - } else { - // 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte) - bc += ci[0] & 0xf; - source_line += ((ci[0] << 4) & 0x700) | ci[1]; - ci += 2; - } + mp_code_lineinfo_t decoded = mp_bytecode_decode_lineinfo(&ci); + bc += decoded.bc_increment; + source_line += decoded.line_increment; mp_printf(print, " bc=" INT_FMT " line=" UINT_FMT "\n", bc, source_line); } } diff --git a/py/smallint.c b/py/smallint.c index aa542ca7bf2..eb99b58667a 100644 --- a/py/smallint.c +++ b/py/smallint.c @@ -26,32 +26,6 @@ #include "py/smallint.h" -bool mp_small_int_mul_overflow(mp_int_t x, mp_int_t y) { - // Check for multiply overflow; see CERT INT32-C - if (x > 0) { // x is positive - if (y > 0) { // x and y are positive - if (x > (MP_SMALL_INT_MAX / y)) { - return true; - } - } else { // x positive, y nonpositive - if (y < (MP_SMALL_INT_MIN / x)) { - return true; - } - } // x positive, y nonpositive - } else { // x is nonpositive - if (y > 0) { // x is nonpositive, y is positive - if (x < (MP_SMALL_INT_MIN / y)) { - return true; - } - } else { // x and y are nonpositive - if (x != 0 && y < (MP_SMALL_INT_MAX / x)) { - return true; - } - } // End if x and y are nonpositive - } // End if x is nonpositive - return false; -} - mp_int_t mp_small_int_modulo(mp_int_t dividend, mp_int_t divisor) { // Python specs require that mod has same sign as second operand dividend %= divisor; diff --git a/py/smallint.h b/py/smallint.h index 584e0018d1b..ec5b0af3b28 100644 --- a/py/smallint.h +++ b/py/smallint.h @@ -68,7 +68,6 @@ // The number of bits in a MP_SMALL_INT including the sign bit. #define MP_SMALL_INT_BITS (MP_IMAX_BITS(MP_SMALL_INT_MAX) + 1) -bool mp_small_int_mul_overflow(mp_int_t x, mp_int_t y); mp_int_t mp_small_int_modulo(mp_int_t dividend, mp_int_t divisor); mp_int_t mp_small_int_floor_divide(mp_int_t num, mp_int_t denom); diff --git a/py/stackctrl.c b/py/stackctrl.c index f192fad0534..0372a1db350 100644 --- a/py/stackctrl.c +++ b/py/stackctrl.c @@ -24,7 +24,12 @@ * THE SOFTWARE. */ +// This API is deprecated, please use py/cstack.h instead + #include "py/runtime.h" + +#if !MICROPY_PREVIEW_VERSION_2 + #include "py/stackctrl.h" void mp_stack_ctrl_init(void) { @@ -68,3 +73,5 @@ void PLACE_IN_ITCM(mp_stack_check)(void) { } #endif // MICROPY_STACK_CHECK + +#endif // !MICROPY_PREVIEW_VERSION_2 diff --git a/py/stackctrl.h b/py/stackctrl.h index 63667f8a551..5ff24798103 100644 --- a/py/stackctrl.h +++ b/py/stackctrl.h @@ -26,8 +26,12 @@ #ifndef MICROPY_INCLUDED_PY_STACKCTRL_H #define MICROPY_INCLUDED_PY_STACKCTRL_H +// This API is deprecated, please use py/cstack.h instead + #include "py/mpconfig.h" +#if !MICROPY_PREVIEW_VERSION_2 + void mp_stack_ctrl_init(void); void mp_stack_set_top(void *top); mp_uint_t mp_stack_usage(void); @@ -43,7 +47,9 @@ void mp_stack_check(void); #define mp_stack_set_limit(limit) (void)(limit) #define MP_STACK_CHECK() -#endif +#endif // MICROPY_STACK_CHECK + +#endif // !MICROPY_PREVIEW_VERSION_2 // CIRCUITPY-CHANGE: provide max stack usage #if MICROPY_MAX_STACK_USAGE diff --git a/py/stream.c b/py/stream.c index fbf7fd878a1..520422cc92f 100644 --- a/py/stream.c +++ b/py/stream.c @@ -260,9 +260,14 @@ void mp_stream_write_adaptor(void *self, const char *buf, size_t len) { mp_stream_write(MP_OBJ_FROM_PTR(self), buf, len, MP_STREAM_RW_WRITE); } -static mp_obj_t stream_write_method(size_t n_args, const mp_obj_t *args) { +static mp_obj_t stream_readinto_write_generic(size_t n_args, const mp_obj_t *args, byte flags) { mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); + mp_get_buffer_raise(args[1], &bufinfo, (flags & MP_STREAM_RW_WRITE) ? MP_BUFFER_READ : MP_BUFFER_WRITE); + + // CPython extension, allow optional maximum length and offset: + // - stream.operation(buf, max_len) + // - stream.operation(buf, off, max_len) + // Similar to https://docs.python.org/3/library/socket.html#socket.socket.recv_into size_t max_len = (size_t)-1; size_t off = 0; if (n_args == 3) { @@ -275,45 +280,31 @@ static mp_obj_t stream_write_method(size_t n_args, const mp_obj_t *args) { } } bufinfo.len -= off; - return mp_stream_write(args[0], (byte *)bufinfo.buf + off, MIN(bufinfo.len, max_len), MP_STREAM_RW_WRITE); + + // Perform the readinto or write operation. + return mp_stream_write(args[0], (byte *)bufinfo.buf + off, MIN(bufinfo.len, max_len), flags); +} + +static mp_obj_t stream_write_method(size_t n_args, const mp_obj_t *args) { + return stream_readinto_write_generic(n_args, args, MP_STREAM_RW_WRITE); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_write_obj, 2, 4, stream_write_method); -static mp_obj_t stream_write1_method(mp_obj_t self_in, mp_obj_t arg) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ); - return mp_stream_write(self_in, bufinfo.buf, bufinfo.len, MP_STREAM_RW_WRITE | MP_STREAM_RW_ONCE); +static mp_obj_t stream_write1_method(size_t n_args, const mp_obj_t *args) { + return stream_readinto_write_generic(n_args, args, MP_STREAM_RW_WRITE | MP_STREAM_RW_ONCE); } -MP_DEFINE_CONST_FUN_OBJ_2(mp_stream_write1_obj, stream_write1_method); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_write1_obj, 2, 4, stream_write1_method); static mp_obj_t stream_readinto(size_t n_args, const mp_obj_t *args) { - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_WRITE); - - // CPython extension: if 2nd arg is provided, that's max len to read, - // instead of full buffer. Similar to - // https://docs.python.org/3/library/socket.html#socket.socket.recv_into - mp_uint_t len = bufinfo.len; - if (n_args > 2) { - len = mp_obj_get_int(args[2]); - if (len > bufinfo.len) { - len = bufinfo.len; - } - } - - int error; - mp_uint_t out_sz = mp_stream_read_exactly(args[0], bufinfo.buf, len, &error); - if (error != 0) { - if (mp_is_nonblocking_error(error)) { - return mp_const_none; - } - mp_raise_OSError(error); - } else { - return MP_OBJ_NEW_SMALL_INT(out_sz); - } + return stream_readinto_write_generic(n_args, args, MP_STREAM_RW_READ); } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_readinto_obj, 2, 3, stream_readinto); +static mp_obj_t stream_readinto1(size_t n_args, const mp_obj_t *args) { + return stream_readinto_write_generic(n_args, args, MP_STREAM_RW_READ | MP_STREAM_RW_ONCE); +} +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_readinto1_obj, 2, 3, stream_readinto1); + static mp_obj_t stream_readall(mp_obj_t self_in) { const mp_stream_p_t *stream_p = mp_get_stream(self_in); diff --git a/py/stream.h b/py/stream.h index 5e1cd5d4413..6e60e849b5f 100644 --- a/py/stream.h +++ b/py/stream.h @@ -87,10 +87,11 @@ typedef struct _mp_stream_p_t { MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_read1_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_readinto_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_readinto1_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_unbuffered_readline_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_stream_unbuffered_readlines_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_write_obj); -MP_DECLARE_CONST_FUN_OBJ_2(mp_stream_write1_obj); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_write1_obj); MP_DECLARE_CONST_FUN_OBJ_1(mp_stream_close_obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream___exit___obj); MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_seek_obj); diff --git a/py/usermod.cmake b/py/usermod.cmake index 85327628374..4a8b99ff31b 100644 --- a/py/usermod.cmake +++ b/py/usermod.cmake @@ -5,6 +5,10 @@ function(usermod_gather_sources SOURCES_VARNAME INCLUDE_DIRECTORIES_VARNAME INCL if (NOT ${LIB} IN_LIST ${INCLUDED_VARNAME}) list(APPEND ${INCLUDED_VARNAME} ${LIB}) + if (NOT TARGET ${LIB}) + return() + endif() + # Gather library sources get_target_property(lib_sources ${LIB} INTERFACE_SOURCES) if (lib_sources) @@ -38,6 +42,16 @@ endfunction() # Include CMake files for user modules. if (USER_C_MODULES) foreach(USER_C_MODULE_PATH ${USER_C_MODULES}) + # If a directory is given, append the micropython.cmake to it. + if (IS_DIRECTORY ${USER_C_MODULE_PATH}) + set(USER_C_MODULE_PATH "${USER_C_MODULE_PATH}/micropython.cmake") + endif() + # Confirm the provided path exists, show abspath if not to make it clearer to fix. + if (NOT EXISTS ${USER_C_MODULE_PATH}) + get_filename_component(USER_C_MODULES_ABS "${USER_C_MODULE_PATH}" ABSOLUTE) + message(FATAL_ERROR "USER_C_MODULES doesn't exist: ${USER_C_MODULES_ABS}") + endif() + message("Including User C Module(s) from ${USER_C_MODULE_PATH}") include(${USER_C_MODULE_PATH}) endforeach() diff --git a/py/verbose.mk b/py/verbose.mk new file mode 100644 index 00000000000..734623a21e8 --- /dev/null +++ b/py/verbose.mk @@ -0,0 +1,16 @@ +# Turn on increased build verbosity by defining BUILD_VERBOSE in your main +# Makefile or in your environment. You can also use V=1 on the make command +# line. + +ifeq ("$(origin V)", "command line") +BUILD_VERBOSE=$(V) +endif +ifndef BUILD_VERBOSE +$(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.) +BUILD_VERBOSE = 0 +endif +ifeq ($(BUILD_VERBOSE),0) +Q = @ +else +Q = +endif diff --git a/py/version.py b/py/version.py new file mode 100755 index 00000000000..b9e889b86b6 --- /dev/null +++ b/py/version.py @@ -0,0 +1,84 @@ +import os +import subprocess + + +def get_version_info_from_git(repo_path, extra_args=[]): + if "CP_VERSION" in os.environ: + git_tag = os.environ["CP_VERSION"] + else: + # Note: git describe doesn't work if no tag is available + try: + git_tag = subprocess.check_output( + # CIRCUITPY-CHANGE: Ignore MicroPython tags that start with v. + # Also ignore tags that are on merged in branches. + [ + "git", + "describe", + "--dirty", + "--tags", + "--always", + "--first-parent", + "--match", + "[!v]*", # This is a glob, not a regex + *extra_args, + ], + cwd=repo_path, + stderr=subprocess.STDOUT, + universal_newlines=True, + ).strip() + # CIRCUITPY-CHANGE + except subprocess.CalledProcessError as er: + if er.returncode == 128: + # git exit code of 128 means no repository found + return None + git_tag = "" + except OSError: + return None + try: + # CIRCUITPY-CHANGE + git_hash = subprocess.check_output( + ["git", "rev-parse", "--short", "HEAD"], + cwd=repo_path, + stderr=subprocess.STDOUT, + universal_newlines=True, + ).strip() + except subprocess.CalledProcessError: + # CIRCUITPY-CHANGE + git_hash = "unknown" + except OSError: + return None + + # CIRCUITPY-CHANGE + try: + # Check if there are any modified files. + subprocess.check_call( + ["git", "diff", "--no-ext-diff", "--quiet", "--exit-code"], + cwd=repo_path, + stderr=subprocess.STDOUT, + ) + # Check if there are any staged files. + subprocess.check_call( + ["git", "diff-index", "--cached", "--quiet", "HEAD", "--"], + cwd=repo_path, + stderr=subprocess.STDOUT, + ) + except subprocess.CalledProcessError: + git_hash += "-dirty" + except OSError: + return None + + # CIRCUITPY-CHANGE + # Try to extract MicroPython version from git tag + ver = git_tag.split("-")[0].split(".") + + return git_tag, git_hash, ver + + +if __name__ == "__main__": + import pathlib + import sys + + git_tag, _, _ = get_version_info_from_git(pathlib.Path("."), sys.argv[1:]) + if git_tag is None: + sys.exit(-1) + print(git_tag) diff --git a/py/vm.c b/py/vm.c index 6fd17782619..860aa36e397 100644 --- a/py/vm.c +++ b/py/vm.c @@ -205,6 +205,22 @@ static mp_obj_t get_active_exception(mp_exc_stack_t *exc_sp, mp_exc_stack_t *exc return MP_OBJ_NULL; } +#if MICROPY_PY_BUILTINS_SLICE +// This function is marked "no inline" so it doesn't increase the C stack usage of the main VM function. +MP_NOINLINE static mp_obj_t *build_slice_stack_allocated(byte op, mp_obj_t *sp, mp_obj_t step) { + mp_obj_t stop = sp[2]; + mp_obj_t start = sp[1]; + mp_obj_slice_t slice = { .base = { .type = &mp_type_slice }, .start = start, .stop = stop, .step = step }; + if (op == MP_BC_LOAD_SUBSCR) { + SET_TOP(mp_obj_subscr(TOP(), MP_OBJ_FROM_PTR(&slice), MP_OBJ_SENTINEL)); + } else { // MP_BC_STORE_SUBSCR + mp_obj_subscr(TOP(), MP_OBJ_FROM_PTR(&slice), sp[-1]); + sp -= 2; + } + return sp; +} +#endif + // fastn has items in reverse order (fastn[0] is local[0], fastn[-1] is local[1], etc) // sp points to bottom of stack which grows up // returns: @@ -871,9 +887,20 @@ unwind_jump:; // 3-argument slice includes step step = POP(); } - mp_obj_t stop = POP(); - mp_obj_t start = TOP(); - SET_TOP(mp_obj_new_slice(start, stop, step)); + if ((*ip == MP_BC_LOAD_SUBSCR || *ip == MP_BC_STORE_SUBSCR) + && (mp_obj_get_type(sp[-2])->flags & MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE)) { + // Fast path optimisation for when the BUILD_SLICE is immediately followed + // by a LOAD/STORE_SUBSCR for an accepting type, to avoid needing to allocate + // the slice on the heap. In some cases (e.g. a[1:3] = x) this can result + // in no allocations at all. We can't do this for instance types because + // the get/set/delattr implementation may keep a reference to the slice. + byte op = *ip++; + sp = build_slice_stack_allocated(op, sp - 2, step); + } else { + mp_obj_t stop = POP(); + mp_obj_t start = TOP(); + SET_TOP(mp_obj_new_slice(start, stop, step)); + } DISPATCH(); } #endif diff --git a/py/vstr.c b/py/vstr.c index 00972edf897..522509d0d05 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -51,7 +51,7 @@ void vstr_init(vstr_t *vstr, size_t alloc) { // Init the vstr so it allocs exactly enough ram to hold a null-terminated // string of the given length, and set the length. void vstr_init_len(vstr_t *vstr, size_t len) { - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: check for invalid length if (len == SIZE_MAX) { m_malloc_fail(len); } diff --git a/pyproject.toml b/pyproject.toml index 271171183a4..5f84ca104ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,91 @@ -# SPDX-FileCopyrightText: 2024 Scott Shawcroft for Adafruit Industries -# -# SPDX-License-Identifier: MIT - -[tool.setuptools_scm] # can be empty if no extra settings are needed, presence enables setuptools-scm +[tool.ruff] +target-version = "py312" +line-length = 99 +# Include Python source files that don't end with .py +extend-include = [ "tools/cc1" ] +# Exclude third-party code from linting and formatting +extend-exclude = [ + # CIRCUITPY-CHANGES + "extmod/ulab", + "frozen", + "lib", + "ports/analog/msdk", + "ports/atmel-samd/asf4", + "ports/broadcom/peripherals", + "ports/espress/tools", + "ports/espressif/esp-idf", + "ports/espressif/esp-protocols", + "ports/raspberrypi/sdk", + "ports/silabs/gecko_sdk", + "ports/silabs/tools/slc_cli_linux", + "ports/stm/st_driver", + "tests/cpydiff/syntax_assign_expr.py", # intentionally incorrect CPython code + "tools/adabot", + "tools/bitmap_font", + "tools/cc1", + "tools/huffman", + "tools/msgfmt.py", + "tools/python-semver", + "tools/uf2", +] +# Exclude third-party code, and exclude the following tests: +# basics: needs careful attention before applying automatic formatting +# repl_: not real python files +# viper_args: uses f(*) +format.exclude = [ + "tests/*/repl_*.py", + "tests/basics/*.py", + "tests/cmdline/cmd_compile_only_error.py", + "tests/micropython/test_normalize_newlines.py", + "tests/micropython/viper_args.py", +] +lint.extend-select = [ "C9", "PLC" ] +lint.exclude = [ + # Ruff finds Python SyntaxError in these files + "tests/cmdline/cmd_compile_only_error.py", + "tests/cmdline/repl_autocomplete.py", + "tests/cmdline/repl_autocomplete_underscore.py", + "tests/cmdline/repl_autoindent.py", + "tests/cmdline/repl_basic.py", + "tests/cmdline/repl_cont.py", + "tests/cmdline/repl_emacs_keys.py", + "tests/cmdline/repl_paste.py", + "tests/cmdline/repl_words_move.py", + "tests/feature_check/repl_emacs_check.py", + "tests/feature_check/repl_words_move_check.py", + "tests/micropython/viper_args.py", +] +lint.extend-ignore = [ + "E401", + "E402", + "E722", + "E731", + "E741", + "F401", + "F403", + "F405", + "PLC0206", + "PLC0415", # conditional imports are common in MicroPython +] +# manifest.py files are evaluated with some global names pre-defined +lint.per-file-ignores."**/manifest.py" = [ "F821" ] +lint.per-file-ignores."ports/**/boards/**/manifest_*.py" = [ "F821" ] +lint.per-file-ignores."ports/cc3200/tools/uniflash.py" = [ "E711" ] +# Exclude all tests from linting. +lint.per-file-ignores."tests/**/*.py" = [ "ALL" ] +# Uses assignment expressions. +lint.per-file-ignores."tests/cpydiff/syntax_assign_expr.py" = [ "F821" ] +lint.mccabe.max-complexity = 40 + +[tool.codespell] +count = "" +ignore-regex = "\\b[A-Z]{3}\\b" +# CIRCUITPY-CHANGE: aranges +ignore-words-list = "ans,aranges,asend,deques,dout,emac,extint,hsi,iput,mis,notin,numer,ser,shft,synopsys,technic,ure,curren" +quiet-level = 3 +skip = """\ + */build*,./.git,./drivers/cc3100,./lib,./ports/cc3200/FreeRTOS,./ports/cc3200/bootmgr/sl,./ports/cc3200/hal,./ports/c\ + c3200/simplelink,./ports/cc3200/telnet,./ports/esp32/managed_components,./ports/nrf/drivers/bluetooth/s1*,./ports/stm\ + 32/usbhost,./tests,ACKNOWLEDGEMENTS,\ + """ diff --git a/requirements-dev.txt b/requirements-dev.txt index 050b6122411..a6fedc4b4af 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -3,8 +3,11 @@ cascadetoml jinja2 typer +# for generating mbedtls's PSA driver wrappers (jinja2, above, is also required) +jsonschema + sh -click +click<8.2.0 cpp-coveralls requests @@ -14,7 +17,7 @@ requests-cache polib # For pre-commit -black +ruff==0.9.4 # ruff version must exactly match pre-commit-config.yaml pyyaml pre-commit micropython-uncrustify @@ -24,10 +27,9 @@ intelhex # for building & testing natmods pyelftools +ar -# for mbedtls certificate store -# version limit due to espressif -cryptography<36.1,>=2.1.4 +cryptography # for web workflow minify minify_html @@ -39,3 +41,9 @@ colorama # for silabs builds setuptools + +# For zephyr port +tomlkit +pytest +pytest-rerunfailures +perfetto diff --git a/requirements-doc.txt b/requirements-doc.txt index 15df3b13780..c0ff03ac770 100644 --- a/requirements-doc.txt +++ b/requirements-doc.txt @@ -10,7 +10,7 @@ setuptools>=45 setuptools_scm # For sphinx -sphinx!=5.2.0.post0 +sphinx!=5.2.0.post0,<8.1.0 sphinx-autoapi sphinx-rtd-theme sphinxcontrib-svg2pdfconverter diff --git a/runtime.py b/runtime.py index 28bf98962ed..28193ce590e 100644 --- a/runtime.py +++ b/runtime.py @@ -1,10 +1,11 @@ import pathlib + paths = pathlib.Path(".").glob("**/*.c") -translate_h = "#include \"supervisor/shared/translate/translate.h\"" +translate_h = '#include "supervisor/shared/translate/translate.h"' for p in paths: if "esp-idf" in p: continue lines = p.read_text().split("\n") - if "#include \"py/runtime.h\"" in lines and translate_h in lines: + if '#include "py/runtime.h"' in lines and translate_h in lines: lines.remove(translate_h) p.write_text("\n".join(lines)) diff --git a/setup.py-stubs b/setup.py-stubs index 9cea5f7eeff..68412fd1892 100644 --- a/setup.py-stubs +++ b/setup.py-stubs @@ -45,12 +45,7 @@ setup( packages=list(package_data.keys()), package_data=package_data, package_dir = package_dir, - setup_requires=["setuptools_scm", "setuptools>=38.6.0"], - use_scm_version = { - "root": "..", - "relative_to": __file__, - "local_scheme": local_scheme, - "git_describe_command": "tools/describe --long", - }, + setup_requires=["setuptools>=38.6.0"], + version="__version__", zip_safe=False, ) diff --git a/shared-bindings/_bleio/Adapter.c b/shared-bindings/_bleio/Adapter.c index 7190594c10a..a1f81a063fd 100644 --- a/shared-bindings/_bleio/Adapter.c +++ b/shared-bindings/_bleio/Adapter.c @@ -62,6 +62,7 @@ //| Use `_bleio.adapter` to access the sole instance already available. //| """ //| ... +//| static mp_obj_t bleio_adapter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BLEIO_HCI bleio_adapter_obj_t *self = common_hal_bleio_allocate_adapter_or_raise(); @@ -135,6 +136,7 @@ MP_PROPERTY_GETSET(bleio_adapter_address_obj, //| """name of the BLE adapter used once connected. //| The name is "CIRCUITPY" + the last four hex digits of ``adapter.address``, //| to make it easy to distinguish multiple CircuitPython boards.""" +//| static mp_obj_t _bleio_adapter_get_name(mp_obj_t self) { return MP_OBJ_FROM_PTR(common_hal_bleio_adapter_get_name(self)); } @@ -161,7 +163,7 @@ MP_PROPERTY_GETSET(bleio_adapter_name_obj, //| timeout: int = 0, //| interval: float = 0.1, //| tx_power: int = 0, -//| directed_to: Optional[Address] = None +//| directed_to: Optional[Address] = None, //| ) -> None: //| """Starts advertising until `stop_advertising` is called or if connectable, another device //| connects to us. @@ -181,6 +183,7 @@ MP_PROPERTY_GETSET(bleio_adapter_name_obj, //| :param int tx_power: transmitter power while advertising in dBm //| :param Address directed_to: peer to advertise directly to""" //| ... +//| static mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -212,7 +215,7 @@ static mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t args[ARG_interval].u_obj = mp_obj_new_float(ADV_INTERVAL_DEFAULT); } - const mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj); + const mp_float_t interval = mp_arg_validate_type_float(args[ARG_interval].u_obj, MP_QSTR_interval); if (interval < ADV_INTERVAL_MIN || interval > ADV_INTERVAL_MAX) { mp_raise_ValueError_varg(MP_ERROR_TEXT("interval must be in range %s-%s"), ADV_INTERVAL_MIN_STRING, ADV_INTERVAL_MAX_STRING); @@ -220,7 +223,7 @@ static mp_obj_t bleio_adapter_start_advertising(mp_uint_t n_args, const mp_obj_t bool connectable = args[ARG_connectable].u_bool; bool anonymous = args[ARG_anonymous].u_bool; - uint32_t timeout = args[ARG_timeout].u_int; + const uint32_t timeout = (uint32_t)mp_arg_validate_int_min(args[ARG_timeout].u_int, 0, MP_QSTR_timeout); if (data_bufinfo.len > 31 && connectable && scan_response_bufinfo.len > 0) { mp_raise_bleio_BluetoothError(MP_ERROR_TEXT("Cannot have scan responses for extended, connectable advertisements.")); } @@ -243,6 +246,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_start_advertising_obj, 1, bleio_ //| def stop_advertising(self) -> None: //| """Stop sending advertising packets.""" //| ... +//| static mp_obj_t bleio_adapter_stop_advertising(mp_obj_t self_in) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -262,7 +266,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapt //| interval: float = 0.1, //| window: float = 0.1, //| minimum_rssi: int = -80, -//| active: bool = True +//| active: bool = True, //| ) -> Iterable[ScanEntry]: //| """Starts a BLE scan and returns an iterator of results. Advertisements and scan responses are //| filtered and returned separately. @@ -282,6 +286,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(bleio_adapter_stop_advertising_obj, bleio_adapt //| :returns: an iterable of `_bleio.ScanEntry` objects //| :rtype: iterable""" //| ... +//| static mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_prefixes, ARG_buffer_size, ARG_extended, ARG_timeout, ARG_interval, ARG_window, ARG_minimum_rssi, ARG_active }; static const mp_arg_t allowed_args[] = { @@ -301,7 +306,7 @@ static mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args mp_float_t timeout = 0.0f; if (args[ARG_timeout].u_obj != mp_const_none) { - timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + timeout = mp_arg_validate_obj_float_non_negative(args[ARG_timeout].u_obj, 0.0f, MP_QSTR_timeout); } if (args[ARG_interval].u_obj == MP_OBJ_NULL) { @@ -312,7 +317,7 @@ static mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args args[ARG_window].u_obj = mp_obj_new_float(WINDOW_DEFAULT); } - const mp_float_t interval = mp_obj_get_float(args[ARG_interval].u_obj); + const mp_float_t interval = mp_arg_validate_type_float(args[ARG_interval].u_obj, MP_QSTR_interval); if (interval < INTERVAL_MIN || interval > INTERVAL_MAX) { mp_raise_ValueError_varg(MP_ERROR_TEXT("interval must be in range %s-%s"), INTERVAL_MIN_STRING, INTERVAL_MAX_STRING); } @@ -324,7 +329,7 @@ static mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args } #pragma GCC diagnostic pop - const mp_float_t window = mp_obj_get_float(args[ARG_window].u_obj); + const mp_float_t window = mp_arg_validate_type_float(args[ARG_window].u_obj, MP_QSTR_window); if (window > interval) { mp_raise_ValueError(MP_ERROR_TEXT("window must be <= interval")); } @@ -334,18 +339,21 @@ static mp_obj_t bleio_adapter_start_scan(size_t n_args, const mp_obj_t *pos_args if (args[ARG_prefixes].u_obj != MP_OBJ_NULL) { mp_get_buffer_raise(args[ARG_prefixes].u_obj, &prefix_bufinfo, MP_BUFFER_READ); // An empty buffer may not be on the heap, but that doesn't matter. - if (prefix_bufinfo.len > 0 && gc_nbytes(prefix_bufinfo.buf) == 0) { + if (prefix_bufinfo.len > 0 && !gc_ptr_on_heap(prefix_bufinfo.buf)) { mp_raise_ValueError(MP_ERROR_TEXT("Prefix buffer must be on the heap")); } } - return common_hal_bleio_adapter_start_scan(self, prefix_bufinfo.buf, prefix_bufinfo.len, args[ARG_extended].u_bool, args[ARG_buffer_size].u_int, timeout, interval, window, args[ARG_minimum_rssi].u_int, args[ARG_active].u_bool); + const mp_int_t buffer_size = mp_arg_validate_int_min(args[ARG_buffer_size].u_int, 1, MP_QSTR_buffer_size); + + return common_hal_bleio_adapter_start_scan(self, prefix_bufinfo.buf, prefix_bufinfo.len, args[ARG_extended].u_bool, buffer_size, timeout, interval, window, args[ARG_minimum_rssi].u_int, args[ARG_active].u_bool); } static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_start_scan_obj, 1, bleio_adapter_start_scan); //| def stop_scan(self) -> None: //| """Stop the current scan.""" //| ... +//| static mp_obj_t bleio_adapter_stop_scan(mp_obj_t self_in) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -381,6 +389,7 @@ MP_PROPERTY_GETTER(bleio_adapter_connected_obj, //| connections: Tuple[Connection] //| """Tuple of active connections including those initiated through //| :py:meth:`_bleio.Adapter.connect`. (read-only)""" +//| static mp_obj_t bleio_adapter_get_connections(mp_obj_t self) { return common_hal_bleio_adapter_get_connections(self); } @@ -395,6 +404,7 @@ MP_PROPERTY_GETTER(bleio_adapter_connections_obj, //| :param Address address: The address of the peripheral to connect to //| :param float/int timeout: Try to connect for timeout seconds.""" //| ... +//| static mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -408,7 +418,8 @@ static mp_obj_t bleio_adapter_connect(mp_uint_t n_args, const mp_obj_t *pos_args mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); bleio_address_obj_t *address = mp_arg_validate_type(args[ARG_address].u_obj, &bleio_address_type, MP_QSTR_address); - mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); + const mp_float_t timeout = + mp_arg_validate_obj_float_non_negative(args[ARG_timeout].u_obj, 0.0f, MP_QSTR_timeout); return common_hal_bleio_adapter_connect(self, address, timeout); } @@ -418,6 +429,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_adapter_connect_obj, 1, bleio_adapter_co //| """Erase all bonding information stored in flash memory.""" //| ... //| +//| static mp_obj_t bleio_adapter_erase_bonding(mp_obj_t self_in) { bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/Address.c b/shared-bindings/_bleio/Address.c index 5cedd2b4663..10500bec9cb 100644 --- a/shared-bindings/_bleio/Address.c +++ b/shared-bindings/_bleio/Address.c @@ -26,6 +26,7 @@ //| :param int address_type: one of the integer values: `PUBLIC`, `RANDOM_STATIC`, //| `RANDOM_PRIVATE_RESOLVABLE`, or `RANDOM_PRIVATE_NON_RESOLVABLE`.""" //| ... +//| static mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_address, ARG_address_type }; static const mp_arg_t allowed_args[] = { @@ -36,20 +37,18 @@ static mp_obj_t bleio_address_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - bleio_address_obj_t *self = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); - const mp_obj_t address = args[ARG_address].u_obj; mp_buffer_info_t buf_info; mp_get_buffer_raise(address, &buf_info, MP_BUFFER_READ); - if (buf_info.len != NUM_BLEIO_ADDRESS_BYTES) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("Address must be %d bytes long"), NUM_BLEIO_ADDRESS_BYTES); - } + mp_arg_validate_length(buf_info.len, NUM_BLEIO_ADDRESS_BYTES, MP_QSTR_address); - const mp_int_t address_type = args[ARG_address_type].u_int; - if (address_type < BLEIO_ADDRESS_TYPE_MIN || address_type > BLEIO_ADDRESS_TYPE_MAX) { - mp_arg_error_invalid(MP_QSTR_address_type); - } + const mp_int_t address_type = + mp_arg_validate_int_range(args[ARG_address_type].u_int, + BLEIO_ADDRESS_TYPE_MIN, + BLEIO_ADDRESS_TYPE_MAX, + MP_QSTR_address_type); + bleio_address_obj_t *self = mp_obj_malloc(bleio_address_obj_t, &bleio_address_type); common_hal_bleio_address_construct(self, buf_info.buf, address_type); return MP_OBJ_FROM_PTR(self); @@ -86,6 +85,7 @@ MP_PROPERTY_GETTER(bleio_address_address_bytes_obj, //| //| One of the integer values: `PUBLIC`, `RANDOM_STATIC`, `RANDOM_PRIVATE_RESOLVABLE`, //| or `RANDOM_PRIVATE_NON_RESOLVABLE`.""" +//| static mp_obj_t bleio_address_get_type(mp_obj_t self_in) { bleio_address_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -99,6 +99,7 @@ MP_PROPERTY_GETTER(bleio_address_type_obj, //| def __eq__(self, other: object) -> bool: //| """Two Address objects are equal if their addresses and address types are equal.""" //| ... +//| static mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { switch (op) { // Two Addresses are equal if their address bytes and address_type are equal @@ -124,6 +125,7 @@ static mp_obj_t bleio_address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_o //| def __hash__(self) -> int: //| """Returns a hash for the Address data.""" //| ... +//| static mp_obj_t bleio_address_unary_op(mp_unary_op_t op, mp_obj_t self_in) { switch (op) { // Two Addresses are equal if their address bytes and address_type are equal @@ -166,6 +168,7 @@ static void bleio_address_print(const mp_print_t *print, mp_obj_t self_in, mp_pr //| RANDOM_PRIVATE_NON_RESOLVABLE: int //| """A randomly generated address that changes on every connection.""" //| +//| static const mp_rom_map_elem_t bleio_address_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_address_bytes), MP_ROM_PTR(&bleio_address_address_bytes_obj) }, { MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&bleio_address_type_obj) }, diff --git a/shared-bindings/_bleio/Attribute.c b/shared-bindings/_bleio/Attribute.c index fe890d875e5..f91fa225680 100644 --- a/shared-bindings/_bleio/Attribute.c +++ b/shared-bindings/_bleio/Attribute.c @@ -19,6 +19,7 @@ //| def __init__(self) -> None: //| """You cannot create an instance of :py:class:`~_bleio.Attribute`.""" //| ... +//| static const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = { @@ -42,6 +43,7 @@ static const mp_rom_map_elem_t bleio_attribute_locals_dict_table[] = { //| //| SIGNED_WITH_MITM: int //| """security_mode: authenticated data signing, without man-in-the-middle protection""" +//| //| { MP_ROM_QSTR(MP_QSTR_NO_ACCESS), MP_ROM_INT(SECURITY_MODE_NO_ACCESS) }, { MP_ROM_QSTR(MP_QSTR_OPEN), MP_ROM_INT(SECURITY_MODE_OPEN) }, diff --git a/shared-bindings/_bleio/Characteristic.c b/shared-bindings/_bleio/Characteristic.c index 24ea0b54090..0ed4c2b7eaa 100644 --- a/shared-bindings/_bleio/Characteristic.c +++ b/shared-bindings/_bleio/Characteristic.c @@ -25,6 +25,7 @@ //| Remote Characteristic objects are created by `Connection.discover_remote_services()` //| as part of remote Services.""" //| ... +//| //| @classmethod //| def add_to_service( @@ -38,7 +39,7 @@ //| max_length: int = 20, //| fixed_length: bool = False, //| initial_value: Optional[ReadableBuffer] = None, -//| user_description: Optional[str] = None +//| user_description: Optional[str] = None, //| ) -> Characteristic: //| """Create a new Characteristic object, and add it to this Service. //| @@ -63,6 +64,7 @@ //| //| :return: the new Characteristic.""" //| ... +//| static mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // class is arg[0], which we can ignore. @@ -114,9 +116,10 @@ static mp_obj_t bleio_characteristic_add_to_service(size_t n_args, const mp_obj_ } mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ); - if (initial_value_bufinfo.len > max_length || - (fixed_length && initial_value_bufinfo.len != max_length)) { - mp_raise_ValueError(MP_ERROR_TEXT("initial_value length is wrong")); + if (fixed_length) { + mp_arg_validate_length(initial_value_bufinfo.len, max_length, MP_QSTR_initial_value); + } else { + mp_arg_validate_length_max(initial_value_bufinfo.len, max_length, MP_QSTR_initial_value); } const char *user_description = NULL; @@ -143,6 +146,7 @@ static MP_DEFINE_CONST_CLASSMETHOD_OBJ(bleio_characteristic_add_to_service_obj, //| def deinit(self) -> None: //| """Deinitialises the Characteristic and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t bleio_characteristic_deinit(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_bleio_characteristic_deinit(self); @@ -246,6 +250,7 @@ MP_PROPERTY_GETTER(bleio_characteristic_descriptors_obj, //| service: Service //| """The Service this Characteristic is a part of.""" +//| static mp_obj_t bleio_characteristic_get_service(mp_obj_t self_in) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -264,6 +269,7 @@ MP_PROPERTY_GETTER(bleio_characteristic_service_obj, //| :param float indicate: True if Characteristic should receive indications of remote writes //| """ //| ... +//| static mp_obj_t bleio_characteristic_set_cccd(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_characteristic_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); @@ -312,6 +318,7 @@ static const mp_rom_map_elem_t bleio_characteristic_locals_dict_table[] = { //| //| WRITE_NO_RESPONSE: int //| """property: clients may write this characteristic; no response will be sent back""" +//| //| { MP_ROM_QSTR(MP_QSTR_BROADCAST), MP_ROM_INT(CHAR_PROP_BROADCAST) }, { MP_ROM_QSTR(MP_QSTR_INDICATE), MP_ROM_INT(CHAR_PROP_INDICATE) }, diff --git a/shared-bindings/_bleio/CharacteristicBuffer.c b/shared-bindings/_bleio/CharacteristicBuffer.c index 24b8b146809..07394256933 100644 --- a/shared-bindings/_bleio/CharacteristicBuffer.c +++ b/shared-bindings/_bleio/CharacteristicBuffer.c @@ -37,6 +37,7 @@ static void raise_error_if_not_connected(bleio_characteristic_buffer_obj_t *self //| :param int buffer_size: Size of ring buffer that stores incoming data coming from client. //| Must be >= 1.""" //| ... +//| static mp_obj_t bleio_characteristic_buffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_characteristic, ARG_timeout, ARG_buffer_size, }; static const mp_arg_t allowed_args[] = { @@ -95,6 +96,7 @@ static void check_for_deinit(bleio_characteristic_buffer_obj_t *self) { //| :return: the line read //| :rtype: int or None""" //| ... +//| // These three methods are used by the shared stream methods. static mp_uint_t bleio_characteristic_buffer_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { @@ -116,7 +118,7 @@ static mp_uint_t bleio_characteristic_buffer_write(mp_obj_t self_in, const void return 0; } -static mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +static mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); raise_error_if_not_connected(self); @@ -140,6 +142,7 @@ static mp_uint_t bleio_characteristic_buffer_ioctl(mp_obj_t self_in, mp_uint_t r //| in_waiting: int //| """The number of bytes in the input buffer, available to be read""" +//| static mp_obj_t bleio_characteristic_buffer_obj_get_in_waiting(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -158,6 +161,7 @@ MP_PROPERTY_GETTER(bleio_characteristic_buffer_in_waiting_obj, //| def reset_input_buffer(self) -> None: //| """Discard any unread characters in the input buffer.""" //| ... +//| static mp_obj_t bleio_characteristic_buffer_obj_reset_input_buffer(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -170,6 +174,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(bleio_characteristic_buffer_reset_input_buffer_ //| """Disable permanently.""" //| ... //| +//| static mp_obj_t bleio_characteristic_buffer_deinit(mp_obj_t self_in) { bleio_characteristic_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_bleio_characteristic_buffer_deinit(self); @@ -181,13 +186,13 @@ static const mp_rom_map_elem_t bleio_characteristic_buffer_locals_dict_table[] = { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_characteristic_buffer_deinit_obj) }, // Standard stream methods. - { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, // CharacteristicBuffer is currently read-only. - // { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + // { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&bleio_characteristic_buffer_reset_input_buffer_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&bleio_characteristic_buffer_reset_input_buffer_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&bleio_characteristic_buffer_in_waiting_obj) }, diff --git a/shared-bindings/_bleio/Connection.c b/shared-bindings/_bleio/Connection.c index becd275f761..4a81d753433 100644 --- a/shared-bindings/_bleio/Connection.c +++ b/shared-bindings/_bleio/Connection.c @@ -56,6 +56,7 @@ void bleio_connection_ensure_connected(bleio_connection_obj_t *self) { //| def disconnect(self) -> None: //| """Disconnects from the remote peripheral. Does nothing if already disconnected.""" //| ... +//| static mp_obj_t bleio_connection_disconnect(mp_obj_t self_in) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in); // common_hal_bleio_connection_disconnect() does nothing if already disconnected. @@ -66,8 +67,12 @@ static MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_disconnect_obj, bleio_connecti //| def pair(self, *, bond: bool = True) -> None: -//| """Pair to the peer to improve security.""" +//| """Pair to the peer to improve security. +//| +//| **Limitation**: Currently ``bond``must be ``True``: bonding always occurs. +//| """ //| ... +//| static mp_obj_t bleio_connection_pair(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -79,6 +84,9 @@ static mp_obj_t bleio_connection_pair(mp_uint_t n_args, const mp_obj_t *pos_args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + if (args[ARG_bond].u_bool == false) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q=%q"), MP_QSTR_bond, MP_QSTR_False); + } bleio_connection_ensure_connected(self); common_hal_bleio_connection_pair(self->connection, args[ARG_bond].u_bool); @@ -111,6 +119,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_connection_pair_obj, 1, bleio_connection //| //| :return: A tuple of `_bleio.Service` objects provided by the remote peripheral.""" //| ... +//| static mp_obj_t bleio_connection_discover_remote_services(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -182,6 +191,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(bleio_connection_get_connection_interval_obj, b //| But for a regular characteristic read or write, may be sent in multiple packets, //| so this limit does not apply.""" //| +//| static mp_obj_t bleio_connection_get_max_packet_length(mp_obj_t self_in) { bleio_connection_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/Descriptor.c b/shared-bindings/_bleio/Descriptor.c index f8615fd28ab..9e29f57d8dd 100644 --- a/shared-bindings/_bleio/Descriptor.c +++ b/shared-bindings/_bleio/Descriptor.c @@ -35,7 +35,7 @@ //| write_perm: int = Attribute.OPEN, //| max_length: int = 20, //| fixed_length: bool = False, -//| initial_value: ReadableBuffer = b"" +//| initial_value: ReadableBuffer = b"", //| ) -> Descriptor: //| """Create a new Descriptor object, and add it to this Service. //| @@ -55,6 +55,7 @@ //| //| :return: the new Descriptor.""" //| ... +//| static mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // class is arg[0], which we can ignore. @@ -98,9 +99,10 @@ static mp_obj_t bleio_descriptor_add_to_characteristic(size_t n_args, const mp_o } } mp_get_buffer_raise(initial_value, &initial_value_bufinfo, MP_BUFFER_READ); - if (initial_value_bufinfo.len > max_length || - (fixed_length && initial_value_bufinfo.len != max_length)) { - mp_raise_ValueError(MP_ERROR_TEXT("initial_value length is wrong")); + if (fixed_length) { + mp_arg_validate_length(initial_value_bufinfo.len, max_length, MP_QSTR_initial_value); + } else { + mp_arg_validate_length_max(initial_value_bufinfo.len, max_length, MP_QSTR_initial_value); } bleio_descriptor_obj_t *descriptor = mp_obj_malloc(bleio_descriptor_obj_t, &bleio_descriptor_type); @@ -147,6 +149,7 @@ MP_PROPERTY_GETTER(bleio_descriptor_characteristic_obj, //| value: bytearray //| """The value of this descriptor.""" //| +//| static mp_obj_t bleio_descriptor_get_value(mp_obj_t self_in) { bleio_descriptor_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/PacketBuffer.c b/shared-bindings/_bleio/PacketBuffer.c index dc89d9b33d1..aa1e6e8645a 100644 --- a/shared-bindings/_bleio/PacketBuffer.c +++ b/shared-bindings/_bleio/PacketBuffer.c @@ -21,7 +21,7 @@ //| characteristic: Characteristic, //| *, //| buffer_size: int, -//| max_packet_size: Optional[int] = None +//| max_packet_size: Optional[int] = None, //| ) -> None: //| """Accumulates a Characteristic's incoming packets in a FIFO buffer and facilitates packet aware //| outgoing writes. A packet's size is either the characteristic length or the maximum transmission @@ -39,6 +39,7 @@ //| :param int max_packet_size: Maximum size of packets. Overrides value from the characteristic. //| (Remote characteristics may not have the correct length.)""" //| ... +//| static mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_characteristic, ARG_buffer_size, ARG_max_packet_size }; static const mp_arg_t allowed_args[] = { @@ -56,7 +57,10 @@ static mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n size_t max_packet_size = common_hal_bleio_characteristic_get_max_length(characteristic); if (args[ARG_max_packet_size].u_obj != mp_const_none) { - max_packet_size = mp_obj_get_int(args[ARG_max_packet_size].u_obj); + const mp_int_t max_packet_size_int = + mp_arg_validate_type_int(args[ARG_max_packet_size].u_obj, MP_QSTR_max_packet_size); + max_packet_size = + (size_t)mp_arg_validate_int_min(max_packet_size_int, 1, MP_QSTR_max_packet_size); } bleio_packet_buffer_obj_t *self = mp_obj_malloc(bleio_packet_buffer_obj_t, &bleio_packet_buffer_type); @@ -79,6 +83,7 @@ static void check_for_deinit(bleio_packet_buffer_obj_t *self) { //| :return: number of bytes read and stored into ``buf`` //| :rtype: int""" //| ... +//| static mp_obj_t bleio_packet_buffer_readinto(mp_obj_t self_in, mp_obj_t buffer_obj) { bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -104,6 +109,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(bleio_packet_buffer_readinto_obj, bleio_packet_ //| :return: number of bytes written. May include header bytes when packet is empty. //| :rtype: int""" //| ... +//| // TODO: Add a kwarg `merge=False` to dictate whether subsequent writes are merged into a pending // one. static mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { @@ -149,6 +155,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_packet_buffer_write_obj, 1, bleio_packet //| def deinit(self) -> None: //| """Disable permanently.""" //| ... +//| static mp_obj_t bleio_packet_buffer_deinit(mp_obj_t self_in) { bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_bleio_packet_buffer_deinit(self); @@ -175,6 +182,7 @@ MP_PROPERTY_GETTER(bleio_packet_buffer_incoming_packet_length_obj, //| outgoing_packet_length: int //| """Maximum length in bytes of a packet we are writing.""" //| +//| static mp_obj_t bleio_packet_buffer_get_outgoing_packet_length(mp_obj_t self_in) { bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -193,11 +201,11 @@ static const mp_rom_map_elem_t bleio_packet_buffer_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_packet_buffer_deinit_obj) }, // Standard stream methods. - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_incoming_packet_length), MP_ROM_PTR(&bleio_packet_buffer_incoming_packet_length_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_outgoing_packet_length), MP_ROM_PTR(&bleio_packet_buffer_outgoing_packet_length_obj) }, + { MP_ROM_QSTR(MP_QSTR_incoming_packet_length), MP_ROM_PTR(&bleio_packet_buffer_incoming_packet_length_obj) }, + { MP_ROM_QSTR(MP_QSTR_outgoing_packet_length), MP_ROM_PTR(&bleio_packet_buffer_outgoing_packet_length_obj) }, }; static MP_DEFINE_CONST_DICT(bleio_packet_buffer_locals_dict, bleio_packet_buffer_locals_dict_table); diff --git a/shared-bindings/_bleio/PacketBuffer.h b/shared-bindings/_bleio/PacketBuffer.h index e9e642e2677..24fb24bce78 100644 --- a/shared-bindings/_bleio/PacketBuffer.h +++ b/shared-bindings/_bleio/PacketBuffer.h @@ -6,6 +6,7 @@ #pragma once +#include "shared-bindings/_bleio/Characteristic.h" #include "common-hal/_bleio/PacketBuffer.h" extern const mp_obj_type_t bleio_packet_buffer_type; @@ -21,13 +22,11 @@ void common_hal_bleio_packet_buffer_construct( bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, size_t buffer_size, size_t max_packet_size); // Allocation free version for BLE workflow use. -#if CIRCUITPY_SERIAL_BLE || CIRCUITPY_BLE_FILE_SERVICE void _common_hal_bleio_packet_buffer_construct( bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, uint32_t *incoming_buffer, size_t incoming_buffer_size, - uint32_t *outgoing_buffer1, uint32_t *outgoing_buffer2, size_t outgoing_buffer_size, + uint32_t *outgoing_buffer1, uint32_t *outgoing_buffer2, size_t max_packet_size, ble_event_handler_t *static_handler_entry); -#endif mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, const uint8_t *data, size_t len, uint8_t *header, size_t header_len); mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len); mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self); @@ -35,3 +34,4 @@ mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_ void common_hal_bleio_packet_buffer_flush(bleio_packet_buffer_obj_t *self); bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self); void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self); +bool common_hal_bleio_packet_buffer_connected(bleio_packet_buffer_obj_t *self); diff --git a/shared-bindings/_bleio/ScanEntry.c b/shared-bindings/_bleio/ScanEntry.c index a2c79b557bd..6b1591093ae 100644 --- a/shared-bindings/_bleio/ScanEntry.c +++ b/shared-bindings/_bleio/ScanEntry.c @@ -30,6 +30,7 @@ //| than the scan filtering which accepts any advertisements that match any of the prefixes //| where ``match_all`` is False.""" //| ... +//| static mp_obj_t bleio_scanentry_matches(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -97,6 +98,7 @@ MP_PROPERTY_GETTER(bleio_scanentry_connectable_obj, //| scan_response: bool //| """True if the entry was a scan response. (read-only)""" //| +//| static mp_obj_t scanentry_get_scan_response(mp_obj_t self_in) { bleio_scanentry_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_bleio_scanentry_get_scan_response(self)); diff --git a/shared-bindings/_bleio/ScanResults.c b/shared-bindings/_bleio/ScanResults.c index 81680902e4d..2b52615f816 100644 --- a/shared-bindings/_bleio/ScanResults.c +++ b/shared-bindings/_bleio/ScanResults.c @@ -40,6 +40,7 @@ static mp_obj_t scanresults_iternext(mp_obj_t self_in) { //| """ //| ... //| +//| MP_DEFINE_CONST_OBJ_TYPE( bleio_scanresults_type, diff --git a/shared-bindings/_bleio/Service.c b/shared-bindings/_bleio/Service.c index 6f6e686c705..cea9a68e694 100644 --- a/shared-bindings/_bleio/Service.c +++ b/shared-bindings/_bleio/Service.c @@ -27,6 +27,7 @@ //| //| :return: the new Service""" //| ... +//| static mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_uuid, ARG_secondary }; static const mp_arg_t allowed_args[] = { @@ -51,6 +52,7 @@ static mp_obj_t bleio_service_make_new(const mp_obj_type_t *type, size_t n_args, //| def deinit(self) -> None: //| """Disable and deinitialise the Service.""" //| ... +//| static mp_obj_t bleio_service_deinit(mp_obj_t self_in) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_bleio_service_deinit(self); @@ -99,6 +101,7 @@ MP_PROPERTY_GETTER(bleio_service_secondary_obj, //| //| Will be ``None`` if the 128-bit UUID for this service is not known.""" //| +//| static mp_obj_t bleio_service_get_uuid(mp_obj_t self_in) { bleio_service_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_bleio/UUID.c b/shared-bindings/_bleio/UUID.c index 5dac1b3ecfd..eef8546e253 100644 --- a/shared-bindings/_bleio/UUID.c +++ b/shared-bindings/_bleio/UUID.c @@ -30,23 +30,22 @@ //| :param value: The uuid value to encapsulate //| :type value: int, ~circuitpython_typing.ReadableBuffer or str""" //| ... +//| static mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); - bleio_uuid_obj_t *self = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); - const mp_obj_t value = all_args[0]; uint8_t uuid128[16]; if (mp_obj_is_int(value)) { - mp_int_t uuid16 = mp_obj_get_int(value); - if (uuid16 < 0 || uuid16 > 0xffff) { - mp_raise_ValueError(MP_ERROR_TEXT("UUID integer value must be 0-0xffff")); - } + const mp_int_t uuid16 = + mp_arg_validate_int_range(mp_obj_get_int(value), 0, 0xffff, MP_QSTR_value); // NULL means no 128-bit value. + bleio_uuid_obj_t *self = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); common_hal_bleio_uuid_construct(self, uuid16, NULL); + return MP_OBJ_FROM_PTR(self); } else { if (mp_obj_is_str(value)) { // 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' @@ -81,9 +80,7 @@ static mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si mp_raise_ValueError(MP_ERROR_TEXT("UUID value is not str, int or byte buffer")); } - if (bufinfo.len != 16) { - mp_raise_ValueError(MP_ERROR_TEXT("Byte buffer must be 16 bytes.")); - } + mp_arg_validate_length(bufinfo.len, 16, MP_QSTR_value); memcpy(uuid128, bufinfo.buf, 16); } @@ -92,10 +89,12 @@ static mp_obj_t bleio_uuid_make_new(const mp_obj_type_t *type, size_t n_args, si uint32_t uuid16 = (uuid128[13] << 8) | uuid128[12]; uuid128[12] = 0; uuid128[13] = 0; + + bleio_uuid_obj_t *self = mp_obj_malloc(bleio_uuid_obj_t, &bleio_uuid_type); common_hal_bleio_uuid_construct(self, uuid16, uuid128); - } - return MP_OBJ_FROM_PTR(self); + return MP_OBJ_FROM_PTR(self); + } } //| uuid16: int @@ -138,6 +137,7 @@ MP_PROPERTY_GETTER(bleio_uuid_uuid128_obj, //| 16-bit Bluetooth SIG assigned UUID. (read-only) 32-bit UUIDs are not currently supported. //| //| :type: int""" +//| static mp_obj_t bleio_uuid_get_size(mp_obj_t self_in) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_uuid_get_size(self)); @@ -152,6 +152,7 @@ MP_PROPERTY_GETTER(bleio_uuid_size_obj, //| def pack_into(self, buffer: WriteableBuffer, offset: int = 0) -> None: //| """Packs the UUID into the given buffer at the given offset.""" //| ... +//| static mp_obj_t bleio_uuid_pack_into(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { bleio_uuid_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -168,12 +169,12 @@ static mp_obj_t bleio_uuid_pack_into(mp_uint_t n_args, const mp_obj_t *pos_args, mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - size_t offset = args[ARG_offset].u_int; - if (offset + common_hal_bleio_uuid_get_size(self) / 8 > bufinfo.len) { - mp_raise_ValueError(MP_ERROR_TEXT("Buffer + offset too small %d %d %d")); - } + const mp_int_t offset = + mp_arg_validate_int_range(args[ARG_offset].u_int, 0, (mp_int_t)bufinfo.len, MP_QSTR_offset); + const size_t packed_len = common_hal_bleio_uuid_get_size(self) / 8; + mp_arg_validate_length_min(bufinfo.len - (size_t)offset, packed_len, MP_QSTR_buffer); - common_hal_bleio_uuid_pack_into(self, bufinfo.buf + offset); + common_hal_bleio_uuid_pack_into(self, (uint8_t *)bufinfo.buf + (size_t)offset); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_KW(bleio_uuid_pack_into_obj, 1, bleio_uuid_pack_into); @@ -214,6 +215,7 @@ static mp_obj_t bleio_uuid_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| """Two UUID objects are equal if their values match and they are both 128-bit or both 16-bit.""" //| ... //| +//| static mp_obj_t bleio_uuid_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { switch (op) { // Two UUID's are equal if their uuid16 values match or their uuid128 values match. diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c index c0cd439f7d9..1ec9fd96e76 100644 --- a/shared-bindings/_bleio/__init__.c +++ b/shared-bindings/_bleio/__init__.c @@ -33,20 +33,30 @@ //| `adafruit_ble `_ //| CircuitPython library instead, which builds on `_bleio`, and //| provides higher-level convenience functionality, including predefined beacons, clients, -//| servers.""" +//| servers. +//| +//| .. note:: `_bleio` uses native BLE capability on boards that support it, including Nordic nRF, +//| Espressif (except ESP32-S2 and ESP32-P4), and SiLabs. +//| On other boards, `_bleio`, if present, supports BLE using an AirLift co-processor. +//| Pico W boards do *not* support BLE using the on-board CYW43 co-processor, +//| but do support using an external AirLift. +//| """ +//| //| adapter: Adapter //| """BLE Adapter used to manage device discovery and connections. //| This object is the sole instance of `_bleio.Adapter`.""" //| +//| //| class BluetoothError(Exception): //| """Catchall exception for Bluetooth related errors.""" //| //| ... //| +//| MP_DEFINE_BLEIO_EXCEPTION(BluetoothError, Exception) -NORETURN void mp_raise_bleio_BluetoothError(mp_rom_error_text_t fmt, ...) { +MP_NORETURN void mp_raise_bleio_BluetoothError(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_BluetoothError, fmt, argptr); @@ -60,8 +70,9 @@ NORETURN void mp_raise_bleio_BluetoothError(mp_rom_error_text_t fmt, ...) { //| //| ... //| +//| MP_DEFINE_BLEIO_EXCEPTION(RoleError, bleio_BluetoothError) -NORETURN void mp_raise_bleio_RoleError(mp_rom_error_text_t msg) { +MP_NORETURN void mp_raise_bleio_RoleError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_bleio_RoleError, msg); } @@ -70,8 +81,9 @@ NORETURN void mp_raise_bleio_RoleError(mp_rom_error_text_t msg) { //| //| ... //| +//| MP_DEFINE_BLEIO_EXCEPTION(SecurityError, bleio_BluetoothError) -NORETURN void mp_raise_bleio_SecurityError(mp_rom_error_text_t fmt, ...) { +MP_NORETURN void mp_raise_bleio_SecurityError(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_bleio_SecurityError, fmt, argptr); @@ -101,6 +113,7 @@ static mp_obj_dict_t bleio_module_globals; //| Raises `NotImplementedError` when the adapter is a singleton and cannot be set.""" //| ... //| +//| mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj) { #if CIRCUITPY_BLEIO_HCI (void)mp_arg_validate_type_or_none(adapter_obj, &bleio_adapter_type, MP_QSTR_adapter); diff --git a/shared-bindings/_bleio/__init__.h b/shared-bindings/_bleio/__init__.h index faf11ea1d06..b55db201f2e 100644 --- a/shared-bindings/_bleio/__init__.h +++ b/shared-bindings/_bleio/__init__.h @@ -45,19 +45,10 @@ void common_hal_bleio_init(void); extern mp_obj_t bleio_set_adapter(mp_obj_t adapter_obj); -NORETURN void mp_raise_bleio_BluetoothError(mp_rom_error_text_t msg, ...); -NORETURN void mp_raise_bleio_RoleError(mp_rom_error_text_t msg); -NORETURN void mp_raise_bleio_SecurityError(mp_rom_error_text_t msg, ...); +MP_NORETURN void mp_raise_bleio_BluetoothError(mp_rom_error_text_t msg, ...); +MP_NORETURN void mp_raise_bleio_RoleError(mp_rom_error_text_t msg); +MP_NORETURN void mp_raise_bleio_SecurityError(mp_rom_error_text_t msg, ...); bleio_adapter_obj_t *common_hal_bleio_allocate_adapter_or_raise(void); -void common_hal_bleio_check_connected(uint16_t conn_handle); - -uint16_t common_hal_bleio_device_get_conn_handle(mp_obj_t device); -void common_hal_bleio_device_discover_remote_services(mp_obj_t device, mp_obj_t service_uuids_whitelist); - -size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len); -void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo); -size_t common_hal_bleio_gattc_read(uint16_t handle, uint16_t conn_handle, uint8_t *buf, size_t len); -void common_hal_bleio_gattc_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo, bool write_no_response); void common_hal_bleio_gc_collect(void); diff --git a/shared-bindings/_eve/__init__.c b/shared-bindings/_eve/__init__.c index 25919892e8a..a3914d07f32 100644 --- a/shared-bindings/_eve/__init__.c +++ b/shared-bindings/_eve/__init__.c @@ -25,9 +25,11 @@ //| contains methods for constructing EVE command //| buffers and appending basic graphics commands.""" //| +//| //| class _EVE: //| def __init__(self) -> None: //| """Create an _EVE object""" +//| typedef struct _mp_obj__EVE_t { mp_obj_base_t base; common_hal__eve_t _eve; @@ -38,7 +40,10 @@ static const mp_obj_type_t _EVE_type; #define EVEHAL(s) \ (&((mp_obj__EVE_t *)mp_obj_cast_to_native_base((s), &_EVE_type))->_eve) -//| def register(self, o: object) -> None: ... +//| def register(self, o: object) -> None: +//| """Register an object's ``write()`` function""" +//| ... +//| static mp_obj_t _register(mp_obj_t self, mp_obj_t o) { common_hal__eve_t *eve = EVEHAL(self); mp_load_method(o, MP_QSTR_write, eve->dest); @@ -46,7 +51,11 @@ static mp_obj_t _register(mp_obj_t self, mp_obj_t o) { } static MP_DEFINE_CONST_FUN_OBJ_2(register_obj, _register); -//| def setmodel(self, m: int) -> None: ... +//| +//| def setmodel(self, m: int) -> None: +//| """Set the model number of the EVE chip""" +//| ... +//| static mp_obj_t _setmodel(mp_obj_t self, mp_obj_t m) { common_hal__eve_t *eve = EVEHAL(self); eve->model = mp_obj_get_int_truncated(m); @@ -54,11 +63,13 @@ static mp_obj_t _setmodel(mp_obj_t self, mp_obj_t m) { } static MP_DEFINE_CONST_FUN_OBJ_2(setmodel_obj, _setmodel); +//| //| def flush(self) -> None: //| """Send any queued drawing commands directly to the hardware. //| //| :param int width: The width of the grid in tiles, or 1 for sprites.""" //| ... +//| static mp_obj_t _flush(mp_obj_t self) { common_hal__eve_flush(EVEHAL(self)); return mp_const_none; @@ -70,6 +81,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(flush_obj, _flush); //| //| :param ~circuitpython_typing.ReadableBuffer b: The bytes to add""" //| ... +//| static mp_obj_t _cc(mp_obj_t self, mp_obj_t b) { mp_buffer_info_t buffer_info; mp_get_buffer_raise(b, &buffer_info, MP_BUFFER_READ); @@ -89,6 +101,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(cc_obj, _cc); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _alphafunc(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t func = mp_obj_get_int_truncated(a0); @@ -106,6 +119,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(alphafunc_obj, _alphafunc); //| Valid primitives are ``BITMAPS``, ``POINTS``, ``LINES``, ``LINE_STRIP``, ``EDGE_STRIP_R``, ``EDGE_STRIP_L``, ``EDGE_STRIP_A``, ``EDGE_STRIP_B`` and ``RECTS``. //| """ //| ... +//| static mp_obj_t _begin(mp_obj_t self, mp_obj_t a0) { uint32_t prim = mp_obj_get_int_truncated(a0); @@ -119,6 +133,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(begin_obj, _begin); //| //| :param int format: bitmap pixel format.""" //| ... +//| static mp_obj_t _bitmapextformat(mp_obj_t self, mp_obj_t a0) { uint32_t fmt = mp_obj_get_int_truncated(a0); @@ -135,6 +150,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(bitmapextformat_obj, _bitmapextformat); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _bitmaphandle(mp_obj_t self, mp_obj_t a0) { uint32_t handle = mp_obj_get_int_truncated(a0); @@ -149,6 +165,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(bitmaphandle_obj, _bitmaphandle); //| :param int linestride: high part of bitmap line stride, in bytes. Range 0-7 //| :param int height: high part of bitmap height, in lines. Range 0-3""" //| ... +//| static mp_obj_t _bitmaplayouth(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t linestride = mp_obj_get_int_truncated(a0); @@ -165,6 +182,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(bitmaplayouth_obj, _bitmaplayouth); //| :param int linestride: bitmap line stride, in bytes. Range 0-1023 //| :param int height: bitmap height, in lines. Range 0-511""" //| ... +//| static mp_obj_t _bitmaplayout(size_t n_args, const mp_obj_t *args) { uint32_t format = mp_obj_get_int_truncated(args[1]); @@ -181,6 +199,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmaplayout_obj, 4, 4, _bitmaplayout //| :param int width: high part of drawn bitmap width, in pixels. Range 0-3 //| :param int height: high part of drawn bitmap height, in pixels. Range 0-3""" //| ... +//| static mp_obj_t _bitmapsizeh(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t width = mp_obj_get_int_truncated(a0); @@ -199,6 +218,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(bitmapsizeh_obj, _bitmapsizeh); //| :param int width: drawn bitmap width, in pixels. Range 0-511 //| :param int height: drawn bitmap height, in pixels. Range 0-511""" //| ... +//| static mp_obj_t _bitmapsize(size_t n_args, const mp_obj_t *args) { uint32_t filter = mp_obj_get_int_truncated(args[1]); @@ -217,6 +237,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmapsize_obj, 6, 6, _bitmapsize); //| :param int addr: Bitmap start address, pixel-aligned, low part. //| """ //| ... +//| static mp_obj_t _bitmapsource(mp_obj_t self, mp_obj_t a0) { uint32_t addr = mp_obj_get_int_truncated(a0); @@ -231,6 +252,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(bitmapsource_obj, _bitmapsource); //| :param int addr: Bitmap start address, pixel-aligned, high part. //| """ //| ... +//| static mp_obj_t _bitmapsourceh(mp_obj_t self, mp_obj_t a0) { uint32_t addr = mp_obj_get_int_truncated(a0); @@ -247,6 +269,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(bitmapsourceh_obj, _bitmapsourceh); //| :param int b: blue component source channel. Range 0-7 //| :param int a: alpha component source channel. Range 0-7""" //| ... +//| static mp_obj_t _bitmapswizzle(size_t n_args, const mp_obj_t *args) { uint32_t r = mp_obj_get_int_truncated(args[1]); @@ -268,6 +291,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmapswizzle_obj, 5, 5, _bitmapswizz //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static void _transform1(uint32_t *p, uint32_t *v, size_t n_args, const mp_obj_t *args) { common_hal__eve_t *eve = EVEHAL(args[0]); @@ -313,6 +337,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmaptransforma_obj, 2, 3, _bitmaptr //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _bitmaptransformb(size_t n_args, const mp_obj_t *args) { uint32_t p, v; @@ -332,6 +357,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmaptransformb_obj, 2, 3, _bitmaptr //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _bitmaptransformc(mp_obj_t self, mp_obj_t a0) { common_hal__eve_t *eve = EVEHAL(self); @@ -357,6 +383,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(bitmaptransformc_obj, _bitmaptransformc); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _bitmaptransformd(size_t n_args, const mp_obj_t *args) { uint32_t p, v; @@ -376,6 +403,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmaptransformd_obj, 2, 3, _bitmaptr //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _bitmaptransforme(size_t n_args, const mp_obj_t *args) { uint32_t p, v; @@ -395,6 +423,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitmaptransforme_obj, 2, 3, _bitmaptr //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _bitmaptransformf(mp_obj_t self, mp_obj_t a0) { common_hal__eve_t *eve = EVEHAL(self); @@ -419,6 +448,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(bitmaptransformf_obj, _bitmaptransformf); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _blendfunc(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t src = mp_obj_get_int_truncated(a0); @@ -433,6 +463,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(blendfunc_obj, _blendfunc); //| //| :param int dest: display list address. Range 0-65535""" //| ... +//| static mp_obj_t _call(mp_obj_t self, mp_obj_t a0) { uint32_t dest = mp_obj_get_int_truncated(a0); @@ -449,6 +480,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(call_obj, _call); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _cell(mp_obj_t self, mp_obj_t a0) { uint32_t cell = mp_obj_get_int_truncated(a0); @@ -465,6 +497,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(cell_obj, _cell); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _clearcolora(mp_obj_t self, mp_obj_t a0) { uint32_t alpha = mp_obj_get_int_truncated(a0); @@ -483,6 +516,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(clearcolora_obj, _clearcolora); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _clearcolorrgb(size_t n_args, const mp_obj_t *args) { uint32_t red = mp_obj_get_int_truncated(args[1]); @@ -500,6 +534,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(clearcolorrgb_obj, 4, 4, _clearcolorr //| :param int s: clear stencil buffer. Range 0-1 //| :param int t: clear tag buffer. Range 0-1""" //| ... +//| static mp_obj_t _clear(size_t n_args, const mp_obj_t *args) { uint32_t c = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 1; @@ -518,6 +553,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(clear_obj, 1, 4, _clear); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _clearstencil(mp_obj_t self, mp_obj_t a0) { uint32_t s = mp_obj_get_int_truncated(a0); @@ -533,6 +569,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(clearstencil_obj, _clearstencil); //| //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ +//| static mp_obj_t _cleartag(mp_obj_t self, mp_obj_t a0) { uint32_t s = mp_obj_get_int_truncated(a0); @@ -549,6 +586,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(cleartag_obj, _cleartag); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _colora(mp_obj_t self, mp_obj_t a0) { uint32_t alpha = mp_obj_get_int_truncated(a0); @@ -568,6 +606,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(colora_obj, _colora); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _colormask(size_t n_args, const mp_obj_t *args) { uint32_t r = mp_obj_get_int_truncated(args[1]); @@ -589,6 +628,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(colormask_obj, 5, 5, _colormask); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _colorrgb(size_t n_args, const mp_obj_t *args) { uint32_t red = mp_obj_get_int_truncated(args[1]); @@ -602,6 +642,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(colorrgb_obj, 4, 4, _colorrgb); //| def Display(self) -> None: //| """End the display list""" //| ... +//| static mp_obj_t _display(mp_obj_t self) { @@ -616,6 +657,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(display_obj, _display); //| :meth:`Vertex2ii` and :meth:`Vertex2f` calls are ignored until the next :meth:`Begin`. //| """ //| ... +//| static mp_obj_t _end(mp_obj_t self) { @@ -629,6 +671,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(end_obj, _end); //| //| :param int dest: display list address. Range 0-65535""" //| ... +//| static mp_obj_t _jump(mp_obj_t self, mp_obj_t a0) { uint32_t dest = mp_obj_get_int_truncated(a0); @@ -642,6 +685,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(jump_obj, _jump); //| //| :param int m: macro register to read. Range 0-1""" //| ... +//| static mp_obj_t _macro(mp_obj_t self, mp_obj_t a0) { uint32_t m = mp_obj_get_int_truncated(a0); @@ -653,6 +697,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(macro_obj, _macro); //| def Nop(self) -> None: //| """No operation""" //| ... +//| static mp_obj_t _nop(mp_obj_t self) { @@ -669,6 +714,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(nop_obj, _nop); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _palettesource(mp_obj_t self, mp_obj_t a0) { uint32_t addr = mp_obj_get_int_truncated(a0); @@ -685,6 +731,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(palettesource_obj, _palettesource); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _palettesourceh(mp_obj_t self, mp_obj_t a0) { uint32_t addr = mp_obj_get_int_truncated(a0); @@ -696,6 +743,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(palettesourceh_obj, _palettesourceh); //| def RestoreContext(self) -> None: //| """Restore the current graphics context from the context stack""" //| ... +//| static mp_obj_t _restorecontext(mp_obj_t self) { @@ -707,6 +755,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(restorecontext_obj, _restorecontext); //| def Return(self) -> None: //| """Return from a previous call command""" //| ... +//| static mp_obj_t _return(mp_obj_t self) { @@ -718,6 +767,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(return_obj, _return); //| def SaveContext(self) -> None: //| """Push the current graphics context on the context stack""" //| ... +//| static mp_obj_t _savecontext(mp_obj_t self) { @@ -735,6 +785,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(savecontext_obj, _savecontext); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _scissorsize(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t width = mp_obj_get_int_truncated(a0); @@ -753,6 +804,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(scissorsize_obj, _scissorsize); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _scissorxy(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t x = mp_obj_get_int_truncated(a0); @@ -772,6 +824,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(scissorxy_obj, _scissorxy); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _stencilfunc(size_t n_args, const mp_obj_t *args) { uint32_t func = mp_obj_get_int_truncated(args[1]); @@ -790,6 +843,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stencilfunc_obj, 4, 4, _stencilfunc); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _stencilmask(mp_obj_t self, mp_obj_t a0) { uint32_t mask = mp_obj_get_int_truncated(a0); @@ -807,6 +861,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(stencilmask_obj, _stencilmask); //| These values are part of the graphics context and are saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _stencilop(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { uint32_t sfail = mp_obj_get_int_truncated(a0); @@ -824,6 +879,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(stencilop_obj, _stencilop); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _tagmask(mp_obj_t self, mp_obj_t a0) { uint32_t mask = mp_obj_get_int_truncated(a0); @@ -840,6 +896,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(tagmask_obj, _tagmask); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _tag(mp_obj_t self, mp_obj_t a0) { uint32_t s = mp_obj_get_int_truncated(a0); @@ -863,6 +920,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(vertexformat_obj, _vertexformat); //| //| This method is an alternative to :meth:`Vertex2f`.""" //| ... +//| static mp_obj_t _vertex2ii(size_t n_args, const mp_obj_t *args) { uint32_t x = mp_obj_get_int_truncated(args[1]); @@ -912,6 +970,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(vertex2ii_obj, 3, 5, _vertex2ii); { MP_ROM_QSTR(MP_QSTR_PaletteSource), MP_ROM_PTR(&palettesource_obj) }, \ { MP_ROM_QSTR(MP_QSTR_PaletteSourceH), MP_ROM_PTR(&palettesourceh_obj) }, \ { MP_ROM_QSTR(MP_QSTR_PointSize), MP_ROM_PTR(&pointsize_obj) }, \ + { MP_ROM_QSTR(MP_QSTR_Region), MP_ROM_PTR(®ion_obj) }, \ { MP_ROM_QSTR(MP_QSTR_RestoreContext), MP_ROM_PTR(&restorecontext_obj) }, \ { MP_ROM_QSTR(MP_QSTR_Return), MP_ROM_PTR(&return_obj) }, \ { MP_ROM_QSTR(MP_QSTR_SaveContext), MP_ROM_PTR(&savecontext_obj) }, \ @@ -950,6 +1009,7 @@ static bool is_vector(mp_obj_t a) { //| :param float x: pixel x-coordinate //| :param float y: pixel y-coordinate""" //| ... +//| static mp_obj_t _vertex2f(mp_obj_t self, mp_obj_t a0, mp_obj_t a1) { #if CIRCUITPY_ULAB if (is_vector(a0) && is_vector(a1)) { @@ -978,6 +1038,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(vertex2f_obj, _vertex2f); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _linewidth(mp_obj_t self, mp_obj_t a0) { mp_float_t width = mp_obj_get_float(a0); @@ -994,14 +1055,36 @@ static MP_DEFINE_CONST_FUN_OBJ_2(linewidth_obj, _linewidth); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _pointsize(mp_obj_t self, mp_obj_t a0) { mp_float_t size = mp_obj_get_float(a0); common_hal__eve_PointSize(EVEHAL(self), size); return mp_const_none; } + static MP_DEFINE_CONST_FUN_OBJ_2(pointsize_obj, _pointsize); +//| def Region(self, y: int, h: int, dest: int) -> None: +//| """Specify a cull region in the display list +//| +//| :param int y: Starting Y band in the render buffer. Range 0-63 +//| :param int h: Y height in the render buffer. Range 0-63 +//| :param int dest: destination address in the display list if the raster is outside the region +//| +//| """ +//| ... +//| + +static mp_obj_t _region(size_t n_args, const mp_obj_t *args) { + uint32_t y = mp_obj_get_int_truncated(args[1]); + uint32_t h = mp_obj_get_int_truncated(args[2]); + uint32_t dest = mp_obj_get_int_truncated(args[3]); + common_hal__eve_Region(EVEHAL(args[0]), y, h, dest); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(region_obj, 4, 4, _region); + //| def VertexTranslateX(self, x: float) -> None: //| """Set the vertex transformation's x translation component //| @@ -1010,6 +1093,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(pointsize_obj, _pointsize); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _vertextranslatex(mp_obj_t self, mp_obj_t a0) { mp_float_t x = mp_obj_get_float(a0); @@ -1026,6 +1110,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatex_obj, _vertextranslatex); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| static mp_obj_t _vertextranslatey(mp_obj_t self, mp_obj_t a0) { @@ -1043,6 +1128,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey); //| This value is part of the graphics context and is saved and restored by :meth:`SaveContext` and :meth:`RestoreContext`. //| """ //| ... +//| // } @@ -1058,6 +1144,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(vertextranslatey_obj, _vertextranslatey); //| This method is used by the ``eve`` module to efficiently add //| commands to the FIFO.""" //| ... +//| static mp_obj_t _cmd0(mp_obj_t self, mp_obj_t n) { uint32_t code = 0xffffff00 | mp_obj_get_int_truncated(n); @@ -1080,6 +1167,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(cmd0_obj, _cmd0); //| commands to the FIFO.""" //| ... //| +//| static mp_obj_t _cmd(size_t n_args, const mp_obj_t *args) { mp_obj_t self = args[0]; mp_obj_t num = args[1]; diff --git a/shared-bindings/_eve/__init__.h b/shared-bindings/_eve/__init__.h index e75f8db7928..13ae1b8a6cb 100644 --- a/shared-bindings/_eve/__init__.h +++ b/shared-bindings/_eve/__init__.h @@ -49,6 +49,7 @@ void common_hal__eve_Nop(common_hal__eve_t *eve); void common_hal__eve_PaletteSource(common_hal__eve_t *eve, uint32_t addr); void common_hal__eve_PaletteSourceH(common_hal__eve_t *eve, uint32_t addr); void common_hal__eve_PointSize(common_hal__eve_t *eve, mp_float_t size); +void common_hal__eve_Region(common_hal__eve_t *eve, uint32_t y, uint32_t h, uint32_t dest); void common_hal__eve_RestoreContext(common_hal__eve_t *eve); void common_hal__eve_Return(common_hal__eve_t *eve); void common_hal__eve_SaveContext(common_hal__eve_t *eve); diff --git a/shared-bindings/_pew/PewPew.c b/shared-bindings/_pew/PewPew.c index af10b47ca67..42e7f4d372b 100644 --- a/shared-bindings/_pew/PewPew.c +++ b/shared-bindings/_pew/PewPew.c @@ -41,6 +41,7 @@ //| buttons are connected to rows of the matrix).""" //| ... //| +//| static mp_obj_t pewpew_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_buffer, ARG_rows, ARG_cols, ARG_buttons }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/_pew/__init__.c b/shared-bindings/_pew/__init__.c index 002255f1154..cfcf627bbcf 100644 --- a/shared-bindings/_pew/__init__.c +++ b/shared-bindings/_pew/__init__.c @@ -31,9 +31,9 @@ static MP_DEFINE_CONST_FUN_OBJ_0(get_ticks_obj, get_ticks); //| """LED matrix driver""" static const mp_rom_map_elem_t pew_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__pew) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PewPew), MP_ROM_PTR(&pewpew_type)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&get_pressed_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_get_ticks), MP_ROM_PTR(&get_ticks_obj)}, + { MP_ROM_QSTR(MP_QSTR_PewPew), MP_ROM_PTR(&pewpew_type)}, + { MP_ROM_QSTR(MP_QSTR_get_pressed), MP_ROM_PTR(&get_pressed_obj)}, + { MP_ROM_QSTR(MP_QSTR_get_ticks), MP_ROM_PTR(&get_ticks_obj)}, }; static MP_DEFINE_CONST_DICT(pew_module_globals, pew_module_globals_table); diff --git a/shared-bindings/_pixelmap/PixelMap.c b/shared-bindings/_pixelmap/PixelMap.c index 6bddeaac9c3..9e3b9bb0a8d 100644 --- a/shared-bindings/_pixelmap/PixelMap.c +++ b/shared-bindings/_pixelmap/PixelMap.c @@ -15,9 +15,11 @@ //| from adafruit_pixelbuf import PixelBuf, PixelReturnType, PixelSequence, PixelType //| +//| //| class PixelMap: //| def __init__(self, pixelbuf: PixelBuf, indices: Tuple[Union[int, Tuple[int]]]) -> None: //| """Construct a PixelMap object that uses the given indices of the underlying pixelbuf""" +//| static mp_obj_t pixelmap_pixelmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pixelbuf, ARG_indices }; @@ -116,6 +118,7 @@ MP_PROPERTY_GETTER(pixelmap_pixelmap_byteorder_obj, //| //| def fill(self, color: PixelType) -> None: //| """Fill all the pixels in the map with the given color""" +//| static mp_obj_t pixelmap_pixelmap_fill(const mp_obj_t self_in, const mp_obj_t color) { pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -127,6 +130,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_fill_obj, pixelmap_pixelmap_fill); //| //| def indices(self, index: int) -> Tuple[int]: //| """Return the PixelBuf indices for a PixelMap index""" +//| static mp_obj_t pixelmap_pixelmap_indices(const mp_obj_t self_in, const mp_obj_t index) { pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -148,6 +152,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_indices_obj, pixelmap_pixelmap_indic //| //| @overload //| def __setitem__(self, index: slice, value: PixelSequence) -> None: ... +//| //| @overload //| def __setitem__(self, index: int, value: PixelType) -> None: //| """Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are @@ -156,6 +161,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(pixelmap_pixelmap_indices_obj, pixelmap_pixelmap_indic //| For RGBW byteorders, if given only RGB values either as an int or as a tuple, the white value //| is used instead when the red, green, and blue values are the same.""" //| ... +//| static mp_obj_t pixelmap_pixelmap_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); if (value == MP_OBJ_NULL) { @@ -200,6 +206,7 @@ static mp_obj_t pixelmap_pixelmap_subscr(mp_obj_t self_in, mp_obj_t index_in, mp //| def __len__(self) -> int: //| """Length of the map""" +//| static mp_obj_t pixelmap_pixelmap_unary_op(mp_unary_op_t op, mp_obj_t self_in) { pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); switch (op) { @@ -217,6 +224,7 @@ static mp_obj_t pixelmap_pixelmap_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| when `auto_write` is True.""" //| ... //| +//| static mp_obj_t pixelmap_pixelmap_show(mp_obj_t self_in) { pixelmap_pixelmap_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_stage/Layer.c b/shared-bindings/_stage/Layer.c index 3958b4c7f1c..0d7a1bfbd5e 100644 --- a/shared-bindings/_stage/Layer.c +++ b/shared-bindings/_stage/Layer.c @@ -33,48 +33,50 @@ //| This class is intended for internal use in the ``stage`` library and //| it shouldn't be used on its own.""" //| ... +//| static mp_obj_t layer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 4, 5, false); - layer_obj_t *self = mp_obj_malloc(layer_obj_t, type); + mp_uint_t width = mp_arg_validate_int_min(mp_obj_get_int(args[0]), 0, MP_QSTR_width); + mp_uint_t height = mp_arg_validate_int_min(mp_obj_get_int(args[1]), 0, MP_QSTR_height); - self->width = mp_obj_get_int(args[0]); - self->height = mp_obj_get_int(args[1]); - self->x = 0; - self->y = 0; - self->frame = 0; - self->rotation = false; - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); - self->graphic = bufinfo.buf; - if (bufinfo.len != 2048) { - mp_raise_ValueError(MP_ERROR_TEXT("graphic must be 2048 bytes long")); - } + mp_buffer_info_t graphic_bufinfo; + mp_get_buffer_raise(args[2], &graphic_bufinfo, MP_BUFFER_READ); + mp_arg_validate_length(graphic_bufinfo.len, 2048, MP_QSTR_graphic); - mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); - self->palette = bufinfo.buf; - if (bufinfo.len != 32) { - mp_raise_ValueError(MP_ERROR_TEXT("palette must be 32 bytes long")); - } + mp_buffer_info_t palette_bufinfo; + mp_get_buffer_raise(args[3], &palette_bufinfo, MP_BUFFER_READ); + mp_arg_validate_length(palette_bufinfo.len, 32, MP_QSTR_palette); + mp_buffer_info_t map_bufinfo = { .buf = NULL }; if (n_args > 4) { - mp_get_buffer_raise(args[4], &bufinfo, MP_BUFFER_READ); - self->map = bufinfo.buf; - if (bufinfo.len < (self->width * self->height) / 2) { + mp_get_buffer_raise(args[4], &map_bufinfo, MP_BUFFER_READ); + if (map_bufinfo.len < (width * height) / 2) { mp_raise_ValueError(MP_ERROR_TEXT("map buffer too small")); } - } else { - self->map = NULL; } + // Only allocate after validation is finished. + layer_obj_t *self = mp_obj_malloc(layer_obj_t, type); + + self->width = width; + self->height = height; + self->x = 0; + self->y = 0; + self->frame = 0; + self->rotation = false; + self->graphic = graphic_bufinfo.buf; + self->palette = palette_bufinfo.buf; + self->map = map_bufinfo.buf; + return MP_OBJ_FROM_PTR(self); } //| def move(self, x: int, y: int) -> None: //| """Set the offset of the layer to the specified values.""" //| ... +//| static mp_obj_t layer_move(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) { layer_obj_t *self = MP_OBJ_TO_PTR(self_in); self->x = mp_obj_get_int(x_in); @@ -88,6 +90,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(layer_move_obj, layer_move); //| graphic.""" //| ... //| +//| static mp_obj_t layer_frame(mp_obj_t self_in, mp_obj_t frame_in, mp_obj_t rotation_in) { layer_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/_stage/Text.c b/shared-bindings/_stage/Text.c index 53abf03b773..0013ffb6697 100644 --- a/shared-bindings/_stage/Text.c +++ b/shared-bindings/_stage/Text.c @@ -33,36 +33,37 @@ //| This class is intended for internal use in the ``stage`` library and //| it shouldn't be used on its own.""" //| ... +//| static mp_obj_t text_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 5, 5, false); - text_obj_t *self = mp_obj_malloc(text_obj_t, type); - - self->width = mp_obj_get_int(args[0]); - self->height = mp_obj_get_int(args[1]); - self->x = 0; - self->y = 0; + mp_uint_t width = mp_arg_validate_int_min(mp_obj_get_int(args[0]), 0, MP_QSTR_width); + mp_uint_t height = mp_arg_validate_int_min(mp_obj_get_int(args[1]), 0, MP_QSTR_height); - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ); - self->font = bufinfo.buf; - if (bufinfo.len != 2048) { - mp_raise_ValueError(MP_ERROR_TEXT("font must be 2048 bytes long")); - } + mp_buffer_info_t font_bufinfo; + mp_get_buffer_raise(args[2], &font_bufinfo, MP_BUFFER_READ); + mp_arg_validate_length(font_bufinfo.len, 2048, MP_QSTR_font); - mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); - self->palette = bufinfo.buf; - if (bufinfo.len != 32) { - mp_raise_ValueError(MP_ERROR_TEXT("palette must be 32 bytes long")); - } + mp_buffer_info_t palette_bufinfo; + mp_get_buffer_raise(args[3], &palette_bufinfo, MP_BUFFER_READ); + mp_arg_validate_length(palette_bufinfo.len, 32, MP_QSTR_palette); - mp_get_buffer_raise(args[4], &bufinfo, MP_BUFFER_READ); - self->chars = bufinfo.buf; - if (bufinfo.len < self->width * self->height) { + mp_buffer_info_t chars_bufinfo; + mp_get_buffer_raise(args[4], &chars_bufinfo, MP_BUFFER_READ); + if (chars_bufinfo.len < width * height) { mp_raise_ValueError(MP_ERROR_TEXT("chars buffer too small")); } + text_obj_t *self = mp_obj_malloc(text_obj_t, type); + self->width = width; + self->height = height; + self->x = 0; + self->y = 0; + self->font = font_bufinfo.buf; + self->palette = palette_bufinfo.buf; + self->chars = chars_bufinfo.buf; + return MP_OBJ_FROM_PTR(self); } @@ -70,6 +71,7 @@ static mp_obj_t text_make_new(const mp_obj_type_t *type, size_t n_args, //| """Set the offset of the text to the specified values.""" //| ... //| +//| static mp_obj_t text_move(mp_obj_t self_in, mp_obj_t x_in, mp_obj_t y_in) { text_obj_t *self = MP_OBJ_TO_PTR(self_in); self->x = mp_obj_get_int(x_in); diff --git a/shared-bindings/_stage/__init__.c b/shared-bindings/_stage/__init__.c index 06e103e2441..bd5e89b5a67 100644 --- a/shared-bindings/_stage/__init__.c +++ b/shared-bindings/_stage/__init__.c @@ -16,8 +16,9 @@ //| """C-level helpers for animation of sprites on a stage //| -//| The `_stage` module contains native code to speed-up the ```stage`` Library -//| `_.""" +//| The `_stage` module contains native code to speed-up the ``stage`` +//| `library `_.""" +//| //| //| def render( //| x0: int, @@ -50,6 +51,7 @@ //| This function is intended for internal use in the ``stage`` library //| and all the necessary checks are performed there.""" //| +//| static mp_obj_t stage_render(size_t n_args, const mp_obj_t *args) { uint16_t x0 = mp_obj_get_int(args[0]); uint16_t y0 = mp_obj_get_int(args[1]); diff --git a/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c b/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c index 737ff419dda..5fb821ceade 100644 --- a/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c +++ b/shared-bindings/adafruit_bus_device/i2c_device/I2CDevice.c @@ -43,10 +43,10 @@ //| with device: //| device.write(bytes_read) //| """ +//| //| ... +//| static mp_obj_t adafruit_bus_device_i2cdevice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - adafruit_bus_device_i2cdevice_obj_t *self = - mp_obj_malloc(adafruit_bus_device_i2cdevice_obj_t, &adafruit_bus_device_i2cdevice_type); enum { ARG_i2c, ARG_device_address, ARG_probe }; static const mp_arg_t allowed_args[] = { { MP_QSTR_i2c, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -58,17 +58,20 @@ static mp_obj_t adafruit_bus_device_i2cdevice_make_new(const mp_obj_type_t *type mp_obj_t *i2c = args[ARG_i2c].u_obj; + adafruit_bus_device_i2cdevice_obj_t *self = + mp_obj_malloc(adafruit_bus_device_i2cdevice_obj_t, &adafruit_bus_device_i2cdevice_type); common_hal_adafruit_bus_device_i2cdevice_construct(MP_OBJ_TO_PTR(self), i2c, args[ARG_device_address].u_int); if (args[ARG_probe].u_bool == true) { common_hal_adafruit_bus_device_i2cdevice_probe_for_device(self); } - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); } //| def __enter__(self) -> I2CDevice: //| """Context manager entry to lock bus.""" //| ... +//| static mp_obj_t adafruit_bus_device_i2cdevice_obj___enter__(mp_obj_t self_in) { adafruit_bus_device_i2cdevice_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_adafruit_bus_device_i2cdevice_lock(self); @@ -79,6 +82,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(adafruit_bus_device_i2cdevice___enter___obj, ad //| def __exit__(self) -> None: //| """Automatically unlocks the bus on exit.""" //| ... +//| static mp_obj_t adafruit_bus_device_i2cdevice_obj___exit__(size_t n_args, const mp_obj_t *args) { common_hal_adafruit_bus_device_i2cdevice_unlock(MP_OBJ_TO_PTR(args[0])); return mp_const_none; @@ -86,6 +90,7 @@ static mp_obj_t adafruit_bus_device_i2cdevice_obj___exit__(size_t n_args, const static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit___obj, 4, 4, adafruit_bus_device_i2cdevice_obj___exit__); //| import sys +//| //| def readinto( //| self, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize //| ) -> None: @@ -100,6 +105,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(adafruit_bus_device_i2cdevice___exit_ //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... +//| static mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -134,6 +140,7 @@ static mp_obj_t adafruit_bus_device_i2cdevice_readinto(size_t n_args, const mp_o static MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_readinto_obj, 1, adafruit_bus_device_i2cdevice_readinto); //| import sys +//| //| def write(self, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: //| """Write the bytes from ``buffer`` to the device, then transmit a stop bit. //| @@ -146,6 +153,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_readinto_obj, 1, //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... +//| static mp_obj_t adafruit_bus_device_i2cdevice_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -180,6 +188,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_write_obj, 1, adafruit_ //| import sys +//| //| def write_then_readinto( //| self, //| out_buffer: ReadableBuffer, @@ -188,7 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_write_obj, 1, adafruit_ //| out_start: int = 0, //| out_end: int = sys.maxsize, //| in_start: int = 0, -//| in_end: int = sys.maxsize +//| in_end: int = sys.maxsize, //| ) -> None: //| """Write the bytes from ``out_buffer`` to the device, then immediately //| reads into ``in_buffer`` from the device. @@ -210,6 +219,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(adafruit_bus_device_i2cdevice_write_obj, 1, adafruit_ //| """ //| ... //| +//| static mp_obj_t adafruit_bus_device_i2cdevice_write_then_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c index 6336b0cd122..2f4895e38ce 100644 --- a/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c +++ b/shared-bindings/adafruit_bus_device/spi_device/SPIDevice.c @@ -27,7 +27,7 @@ //| baudrate: int = 100000, //| polarity: int = 0, //| phase: int = 0, -//| extra_clocks: int = 0 +//| extra_clocks: int = 0, //| ) -> None: //| """ //| Represents a single SPI device and manages locking the bus and the device address. @@ -55,10 +55,10 @@ //| # A second transaction //| with device as spi: //| spi.write(bytes_read)""" +//| //| ... +//| static mp_obj_t adafruit_bus_device_spidevice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - adafruit_bus_device_spidevice_obj_t *self = - mp_obj_malloc(adafruit_bus_device_spidevice_obj_t, &adafruit_bus_device_spidevice_type); enum { ARG_spi, ARG_chip_select, ARG_cs_active_value, ARG_baudrate, ARG_polarity, ARG_phase, ARG_extra_clocks }; static const mp_arg_t allowed_args[] = { { MP_QSTR_spi, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -76,12 +76,11 @@ static mp_obj_t adafruit_bus_device_spidevice_make_new(const mp_obj_type_t *type mp_arg_validate_type_or_none(args[ARG_chip_select].u_obj, &digitalio_digitalinout_type, MP_QSTR_chip_select); - common_hal_adafruit_bus_device_spidevice_construct(MP_OBJ_TO_PTR(self), spi, args[ARG_chip_select].u_obj, args[ARG_cs_active_value].u_bool, args[ARG_baudrate].u_int, args[ARG_polarity].u_int, - args[ARG_phase].u_int, args[ARG_extra_clocks].u_int); - if (args[ARG_chip_select].u_obj != mp_const_none) { - digitalinout_result_t result = common_hal_digitalio_digitalinout_switch_to_output(MP_OBJ_TO_PTR(args[ARG_chip_select].u_obj), - true, DRIVE_MODE_PUSH_PULL); + digitalinout_result_t result = + common_hal_digitalio_digitalinout_switch_to_output(MP_OBJ_TO_PTR(args[ARG_chip_select].u_obj), + true, + DRIVE_MODE_PUSH_PULL); #if CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY if (result == DIGITALINOUT_INPUT_ONLY) { mp_raise_NotImplementedError(MP_ERROR_TEXT("Pin is input only")); @@ -91,12 +90,25 @@ static mp_obj_t adafruit_bus_device_spidevice_make_new(const mp_obj_type_t *type #endif } - return (mp_obj_t)self; + adafruit_bus_device_spidevice_obj_t *self = + mp_obj_malloc(adafruit_bus_device_spidevice_obj_t, &adafruit_bus_device_spidevice_type); + common_hal_adafruit_bus_device_spidevice_construct(MP_OBJ_TO_PTR(self), + spi, + args[ARG_chip_select].u_obj, + args[ARG_cs_active_value].u_bool, + args[ARG_baudrate].u_int, + args[ARG_polarity].u_int, + args[ARG_phase].u_int, + args[ARG_extra_clocks].u_int); + + + return MP_OBJ_FROM_PTR(self); } //| def __enter__(self) -> busio.SPI: //| """Starts a SPI transaction by configuring the SPI and asserting chip select.""" //| ... +//| static mp_obj_t adafruit_bus_device_spidevice_obj___enter__(mp_obj_t self_in) { adafruit_bus_device_spidevice_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_adafruit_bus_device_spidevice_enter(self); @@ -109,6 +121,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(adafruit_bus_device_spidevice___enter___obj, ad //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... //| +//| static mp_obj_t adafruit_bus_device_spidevice_obj___exit__(size_t n_args, const mp_obj_t *args) { common_hal_adafruit_bus_device_spidevice_exit(MP_OBJ_TO_PTR(args[0])); return mp_const_none; diff --git a/shared-bindings/adafruit_pixelbuf/PixelBuf.c b/shared-bindings/adafruit_pixelbuf/PixelBuf.c index 95b353611f7..4144f086b98 100644 --- a/shared-bindings/adafruit_pixelbuf/PixelBuf.c +++ b/shared-bindings/adafruit_pixelbuf/PixelBuf.c @@ -24,7 +24,7 @@ #include "extmod/ulab/code/ndarray.h" #endif -static NORETURN void invalid_byteorder(void) { +static MP_NORETURN void invalid_byteorder(void) { mp_arg_error_invalid(MP_QSTR_byteorder); } @@ -41,7 +41,7 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t //| brightness: float = 0, //| auto_write: bool = False, //| header: ReadableBuffer = b"", -//| trailer: ReadableBuffer = b"" +//| trailer: ReadableBuffer = b"", //| ) -> None: //| """Create a PixelBuf object of the specified size, byteorder, and bits per pixel. //| @@ -61,6 +61,7 @@ static void parse_byteorder(mp_obj_t byteorder_obj, pixelbuf_byteorder_details_t //| :param ~circuitpython_typing.ReadableBuffer trailer: Sequence of bytes to always send after pixel values. //| """ //| ... +//| static mp_obj_t pixelbuf_pixelbuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_size, ARG_byteorder, ARG_brightness, ARG_auto_write, ARG_header, ARG_trailer }; static const mp_arg_t allowed_args[] = { @@ -201,6 +202,7 @@ MP_PROPERTY_GETSET(pixelbuf_pixelbuf_auto_write_obj, //| byteorder: str //| """byteorder string for the buffer (read-only)""" +//| static mp_obj_t pixelbuf_pixelbuf_obj_get_byteorder(mp_obj_t self_in) { return common_hal_adafruit_pixelbuf_pixelbuf_get_byteorder_string(self_in); } @@ -224,6 +226,7 @@ static mp_obj_t pixelbuf_pixelbuf_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| """Transmits the color data to the pixels so that they are shown. This is done automatically //| when `auto_write` is True.""" //| ... +//| static mp_obj_t pixelbuf_pixelbuf_show(mp_obj_t self_in) { common_hal_adafruit_pixelbuf_pixelbuf_show(self_in); @@ -234,6 +237,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_s //| def fill(self, color: PixelType) -> None: //| """Fills the given pixelbuf with the given color.""" //| ... +//| static mp_obj_t pixelbuf_pixelbuf_fill(mp_obj_t self_in, mp_obj_t value) { common_hal_adafruit_pixelbuf_pixelbuf_fill(self_in, value); @@ -258,6 +262,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_f //| //| @overload //| def __setitem__(self, index: slice, value: PixelSequence) -> None: ... +//| //| @overload //| def __setitem__(self, index: int, value: PixelType) -> None: //| """Sets the pixel value at the given index. Value can either be a tuple or integer. Tuples are @@ -267,6 +272,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_f //| is used instead when the red, green, and blue values are the same.""" //| ... //| +//| static mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item diff --git a/shared-bindings/aesio/aes.c b/shared-bindings/aesio/aes.c index 33f2a335632..75f2850a7ef 100644 --- a/shared-bindings/aesio/aes.c +++ b/shared-bindings/aesio/aes.c @@ -19,6 +19,7 @@ //| MODE_CBC: int //| MODE_CTR: int //| +//| //| class AES: //| """Encrypt and decrypt AES streams""" //| @@ -50,11 +51,10 @@ //| cipher.encrypt_into(inp, outp) //| hexlify(outp)""" //| ... +//| static mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - aesio_aes_obj_t *self = mp_obj_malloc(aesio_aes_obj_t, &aesio_aes_type); - enum { ARG_key, ARG_mode, ARG_IV, ARG_counter, ARG_segment_size }; static const mp_arg_t allowed_args[] = { {MP_QSTR_key, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, @@ -98,8 +98,10 @@ static mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, iv = bufinfo.buf; } + aesio_aes_obj_t *self = mp_obj_malloc(aesio_aes_obj_t, &aesio_aes_type); common_hal_aesio_aes_construct(self, key, key_length, iv, mode, args[ARG_counter].u_int); + return MP_OBJ_FROM_PTR(self); } @@ -114,6 +116,7 @@ static mp_obj_t aesio_aes_make_new(const mp_obj_type_t *type, size_t n_args, //| :param ~circuitpython_typing.ReadableBuffer IV: Initialization vector to use //| for CBC or CTR mode""" //| ... +//| static mp_obj_t aesio_aes_rekey(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { aesio_aes_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); enum { ARG_key, ARG_IV }; @@ -174,9 +177,12 @@ static void validate_length(aesio_aes_obj_t *self, size_t src_length, //| """Encrypt the buffer from ``src`` into ``dest``. //| //| For ECB mode, the buffers must be 16 bytes long. For CBC mode, the -//| buffers must be a multiple of 16 bytes, and must be equal length. For -//| CTR mode, there are no restrictions.""" +//| buffers must be a multiple of 16 bytes, and must be equal length. +//| Any included padding must conform to the required padding style for the given mode. +//| For CTR mode, there are no restrictions. +//| """ //| ... +//| static mp_obj_t aesio_aes_encrypt_into(mp_obj_t self_in, mp_obj_t src, mp_obj_t dest) { aesio_aes_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -200,6 +206,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(aesio_aes_encrypt_into_obj, aesio_aes_encrypt_i //| CTR mode, there are no restrictions.""" //| ... //| +//| static mp_obj_t aesio_aes_decrypt_into(mp_obj_t self_in, mp_obj_t src, mp_obj_t dest) { aesio_aes_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -247,7 +254,7 @@ MP_PROPERTY_GETSET(aesio_aes_mode_obj, static const mp_rom_map_elem_t aesio_locals_dict_table[] = { // Methods - {MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_AES)}, + {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_AES)}, {MP_ROM_QSTR(MP_QSTR_encrypt_into), (mp_obj_t)&aesio_aes_encrypt_into_obj}, {MP_ROM_QSTR(MP_QSTR_decrypt_into), (mp_obj_t)&aesio_aes_decrypt_into_obj}, {MP_ROM_QSTR(MP_QSTR_rekey), (mp_obj_t)&aesio_aes_rekey_obj}, diff --git a/shared-bindings/alarm/SleepMemory.c b/shared-bindings/alarm/SleepMemory.c index cf1b211c685..383c2a4e613 100644 --- a/shared-bindings/alarm/SleepMemory.c +++ b/shared-bindings/alarm/SleepMemory.c @@ -12,16 +12,16 @@ #include "shared-bindings/alarm/SleepMemory.h" //| class SleepMemory: -//| """Store raw bytes in RAM that persists during deep sleep. +//| """Store raw bytes in RAM that persists across deep sleep and software resets. //| The class acts as a ``bytearray``. -//| If power is lost, the memory contents are lost. +//| Contents are preserved across ``microcontroller.reset()``, watchdog resets, +//| and deep sleep wake. Contents are lost when power is removed and restored, +//| or on brown-out reset. //| //| Note that this class can't be imported and used directly. The sole //| instance of :class:`SleepMemory` is available at //| :attr:`alarm.sleep_memory`. //| -//| **Limitations:** Not supported on RP2040. -//| //| Usage:: //| //| import alarm @@ -43,6 +43,7 @@ //| def __len__(self) -> int: //| """Return the length. This is used by (`len`)""" //| ... +//| static mp_obj_t alarm_sleep_memory_unary_op(mp_unary_op_t op, mp_obj_t self_in) { alarm_sleep_memory_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_alarm_sleep_memory_get_length(self); @@ -75,6 +76,7 @@ static MP_DEFINE_CONST_DICT(alarm_sleep_memory_locals_dict, alarm_sleep_memory_l //| """Set the value at the given index.""" //| ... //| +//| static mp_obj_t alarm_sleep_memory_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item diff --git a/shared-bindings/alarm/__init__.c b/shared-bindings/alarm/__init__.c index 7cdc2f7750e..ff3aa2f02f6 100644 --- a/shared-bindings/alarm/__init__.c +++ b/shared-bindings/alarm/__init__.c @@ -44,6 +44,7 @@ //| For more information about working with alarms and light/deep sleep in CircuitPython, //| see `this Learn guide `_. //| """ +//| //| sleep_memory: SleepMemory //| """Memory that persists during deep sleep. @@ -54,6 +55,7 @@ //| If no alarm occurred since the last hard reset or soft restart, value is ``None``. //| """ //| +//| // wake_alarm is implemented as a dictionary entry, so there's no code here. @@ -90,6 +92,7 @@ static void validate_objs_are_alarms(size_t n_args, const mp_obj_t *objs) { //| """ //| ... //| +//| static mp_obj_t alarm_light_sleep_until_alarms(size_t n_args, const mp_obj_t *args) { if (n_args == 0) { return mp_const_none; @@ -119,6 +122,9 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OB //| //| If no alarms are specified, the microcontroller will deep sleep until reset. //| +//| You cannot initiate a deep sleep from the REPL. +//| You must call `exit_and_deep_sleep_until_alarms()` from a program file. +//| //| :param circuitpython_typing.Alarm alarms: the alarms that can wake the microcontroller. //| :param Sequence[digitalio.DigitalInOut] preserve_dios: A sequence of `DigitalInOut` objects //| whose state should be preserved during deep sleep. @@ -131,6 +137,8 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OB //| //| Preserving `DigitalInOut` states during deep sleep can be used to ensure that //| external or on-board devices are powered or unpowered during sleep, among other purposes. +//| Once the board wakes up from deep sleep, the `DigitalInOut` states are no longer preserved +//| and must be restored by your code. //| //| On some microcontrollers, some pins cannot remain in their original state for hardware reasons. //| @@ -172,6 +180,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(alarm_light_sleep_until_alarms_obj, 1, MP_OB //| """ //| ... //| +//| static mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_preserve_dios }; static const mp_arg_t allowed_args[] = { @@ -186,6 +195,11 @@ static mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o mp_obj_t preserve_dios = args[ARG_preserve_dios].u_obj; const size_t num_dios = (size_t)MP_OBJ_SMALL_INT_VALUE(mp_obj_len(preserve_dios)); + #if !CIRCUITPY_ALARM_PRESERVE_DIOS + if (num_dios > 0) { + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_preserve_dios); + } + #endif digitalio_digitalinout_obj_t *dios_array[num_dios]; for (mp_uint_t i = 0; i < num_dios; i++) { @@ -196,7 +210,7 @@ static mp_obj_t alarm_exit_and_deep_sleep_until_alarms(size_t n_args, const mp_o common_hal_alarm_set_deep_sleep_alarms(n_args, pos_args, num_dios, dios_array); // Raise an exception, which will be processed in main.c. - mp_raise_type_arg(&mp_type_DeepSleepRequest, NULL); + mp_raise_type(&mp_type_DeepSleepRequest); // Doesn't get here. return mp_const_none; diff --git a/shared-bindings/alarm/__init__.h b/shared-bindings/alarm/__init__.h index af92b381137..5b8823162cc 100644 --- a/shared-bindings/alarm/__init__.h +++ b/shared-bindings/alarm/__init__.h @@ -24,7 +24,14 @@ extern mp_obj_t common_hal_alarm_light_sleep_until_alarms(size_t n_alarms, const // it will exit idle as if deep sleep was exited extern void common_hal_alarm_set_deep_sleep_alarms(size_t n_alarms, const mp_obj_t *alarms, size_t n_dios, digitalio_digitalinout_obj_t **preserve_dios); -extern NORETURN void common_hal_alarm_enter_deep_sleep(void); +extern MP_NORETURN void common_hal_alarm_enter_deep_sleep(void); + +#if CIRCUITPY_ALARM_PRESERVE_DIOS +// Clear any pin preservations set up for deep sleep (real or fake), releasing +// held pins so they can be reset. Only declared on ports that implement +// `preserve_dios`. +extern void common_hal_alarm_clear_pin_preservations(void); +#endif // May be used to re-initialize peripherals like GPIO, if the VM reset returned // them to a default state diff --git a/shared-bindings/alarm/pin/PinAlarm.c b/shared-bindings/alarm/pin/PinAlarm.c index 9c786766f6c..4633fdb233c 100644 --- a/shared-bindings/alarm/pin/PinAlarm.c +++ b/shared-bindings/alarm/pin/PinAlarm.c @@ -40,8 +40,8 @@ //| pulls it high. //| """ //| ... +//| static mp_obj_t alarm_pin_pinalarm_make_new(const mp_obj_type_t *type, mp_uint_t n_args, size_t n_kw, const mp_obj_t *all_args) { - alarm_pin_pinalarm_obj_t *self = mp_obj_malloc(alarm_pin_pinalarm_obj_t, &alarm_pin_pinalarm_type); enum { ARG_pin, ARG_value, ARG_edge, ARG_pull }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -54,6 +54,7 @@ static mp_obj_t alarm_pin_pinalarm_make_new(const mp_obj_type_t *type, mp_uint_t const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); + alarm_pin_pinalarm_obj_t *self = mp_obj_malloc(alarm_pin_pinalarm_obj_t, &alarm_pin_pinalarm_type); common_hal_alarm_pin_pinalarm_construct(self, pin, args[ARG_value].u_bool, @@ -81,6 +82,7 @@ MP_PROPERTY_GETTER(alarm_pin_pinalarm_pin_obj, //| value: bool //| """The value on which to trigger.""" //| +//| static mp_obj_t alarm_pin_pinalarm_obj_get_value(mp_obj_t self_in) { alarm_pin_pinalarm_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_alarm_pin_pinalarm_get_value(self)); diff --git a/shared-bindings/alarm/time/TimeAlarm.c b/shared-bindings/alarm/time/TimeAlarm.c index 012ca602a11..a3df6ddf7fd 100644 --- a/shared-bindings/alarm/time/TimeAlarm.c +++ b/shared-bindings/alarm/time/TimeAlarm.c @@ -35,12 +35,17 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { //| If the given time is already in the past, then an exception is raised. //| If the sleep happens after the given time, then it will wake immediately //| due to this time alarm. +//| +//| Example:: +//| +//| # Deep sleep for 30 seconds. +//| time_alarm = alarm.time.TimeAlarm(monotonic_time=time.monotonic() + 30) +//| alarm.exit_and_deep_sleep_until_alarms(time_alarm) //| """ //| ... +//| static mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - alarm_time_timealarm_obj_t *self = mp_obj_malloc(alarm_time_timealarm_obj_t, &alarm_time_timealarm_type); - enum { ARG_monotonic_time, ARG_epoch_time }; static const mp_arg_t allowed_args[] = { { MP_QSTR_monotonic_time, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, @@ -85,6 +90,7 @@ static mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type, mp_raise_ValueError(MP_ERROR_TEXT("Time is in the past.")); } + alarm_time_timealarm_obj_t *self = mp_obj_malloc(alarm_time_timealarm_obj_t, &alarm_time_timealarm_type); common_hal_alarm_time_timealarm_construct(self, monotonic_time); return MP_OBJ_FROM_PTR(self); @@ -96,6 +102,7 @@ static mp_obj_t alarm_time_timealarm_make_new(const mp_obj_type_t *type, //| by this property only as a `time.monotonic()` time. //| """ //| +//| static mp_obj_t alarm_time_timealarm_obj_get_monotonic_time(mp_obj_t self_in) { alarm_time_timealarm_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_float(common_hal_alarm_time_timealarm_get_monotonic_time(self)); diff --git a/shared-bindings/alarm/touch/TouchAlarm.c b/shared-bindings/alarm/touch/TouchAlarm.c index c4fd595efea..eac3f37b8f4 100644 --- a/shared-bindings/alarm/touch/TouchAlarm.c +++ b/shared-bindings/alarm/touch/TouchAlarm.c @@ -21,12 +21,12 @@ //| may be limited due to hardware restrictions, particularly for deep-sleep alarms. //| //| **Limitations:** Not available on SAMD, Nordic, or RP2040. +//| On Espressif, only available on ESP32, ESP32-S2, ESP32-S3, and ESP32-P4. //| """ //| ... +//| static mp_obj_t alarm_touch_touchalarm_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - alarm_touch_touchalarm_obj_t *self = mp_obj_malloc(alarm_touch_touchalarm_obj_t, &alarm_touch_touchalarm_type); - enum { ARG_pin }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -37,6 +37,7 @@ static mp_obj_t alarm_touch_touchalarm_make_new(const mp_obj_type_t *type, const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); + alarm_touch_touchalarm_obj_t *self = mp_obj_malloc(alarm_touch_touchalarm_obj_t, &alarm_touch_touchalarm_type); common_hal_alarm_touch_touchalarm_construct(self, pin); return MP_OBJ_FROM_PTR(self); @@ -45,6 +46,7 @@ static mp_obj_t alarm_touch_touchalarm_make_new(const mp_obj_type_t *type, //| pin: microcontroller.Pin //| """The trigger pin.""" //| +//| static mp_obj_t alarm_touch_touchalarm_obj_get_pin(mp_obj_t self_in) { alarm_touch_touchalarm_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_FROM_PTR(self->pin); diff --git a/shared-bindings/analogbufio/BufferedIn.c b/shared-bindings/analogbufio/BufferedIn.c index e5a5d3600ab..2c42ee1f325 100644 --- a/shared-bindings/analogbufio/BufferedIn.c +++ b/shared-bindings/analogbufio/BufferedIn.c @@ -40,8 +40,14 @@ //| """Create a `BufferedIn` on the given pin and given sample rate. //| //| :param ~microcontroller.Pin pin: the pin to read from -//| :param ~int sample_rate: rate: sampling frequency, in samples per second""" +//| :param ~int sample_rate: rate: sampling frequency, in samples per second +//| +//| **Limitations**: On many boards with a CYW43 radio module, such as Pico W, +//| GPIO29 (often ``board.A3``) is also used to control the CYW43, +//| and is therefore not available to use as the `BufferedIn` pin. +//| """ //| ... +//| static mp_obj_t analogbufio_bufferedin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { @@ -54,10 +60,8 @@ static mp_obj_t analogbufio_bufferedin_make_new(const mp_obj_type_t *type, size_ // Validate Pin const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); - // Create local object - analogbufio_bufferedin_obj_t *self = mp_obj_malloc_with_finaliser(analogbufio_bufferedin_obj_t, &analogbufio_bufferedin_type); - - // Call local interface in ports/common-hal/analogbufio + analogbufio_bufferedin_obj_t *self = + mp_obj_malloc_with_finaliser(analogbufio_bufferedin_obj_t, &analogbufio_bufferedin_type); common_hal_analogbufio_bufferedin_construct(self, pin, args[ARG_sample_rate].u_int); return MP_OBJ_FROM_PTR(self); @@ -66,6 +70,7 @@ static mp_obj_t analogbufio_bufferedin_make_new(const mp_obj_type_t *type, size_ //| def deinit(self) -> None: //| """Shut down the `BufferedIn` and release the pin for other use.""" //| ... +//| static mp_obj_t analogbufio_bufferedin_deinit(mp_obj_t self_in) { analogbufio_bufferedin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_analogbufio_bufferedin_deinit(self); @@ -81,18 +86,15 @@ static void check_for_deinit(analogbufio_bufferedin_obj_t *self) { //| def __enter__(self) -> BufferedIn: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t analogbufio_bufferedin___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_analogbufio_bufferedin_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogbufio_bufferedin___exit___obj, 4, 4, analogbufio_bufferedin___exit__); +//| +// Provided by context manager helper. //| def readinto(self, buffer: WriteableBuffer, loop: bool = False) -> int: //| """Fills the provided buffer with ADC voltage values. @@ -110,6 +112,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogbufio_bufferedin___exit___obj, //| """ //| ... //| +//| static mp_obj_t analogbufio_bufferedin_obj_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -139,7 +142,7 @@ static const mp_rom_map_elem_t analogbufio_bufferedin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&analogbufio_bufferedin_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogbufio_bufferedin_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogbufio_bufferedin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&analogbufio_bufferedin_readinto_obj)}, }; diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c index f56ce600c24..b68b044ab52 100644 --- a/shared-bindings/analogio/AnalogIn.c +++ b/shared-bindings/analogio/AnalogIn.c @@ -46,6 +46,7 @@ MP_WEAK const mcu_pin_obj_t *common_hal_analogio_analogin_validate_pin(mp_obj_t //| when you read a value. You can retry the read. //| """ //| ... +//| static mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, mp_uint_t n_args, size_t n_kw, const mp_obj_t *args) { // check number of arguments @@ -62,6 +63,7 @@ static mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Turn off the AnalogIn and release the pin for other use.""" //| ... +//| static mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_analogio_analogin_deinit(self); @@ -77,18 +79,15 @@ static void check_for_deinit(analogio_analogin_obj_t *self) { //| def __enter__(self) -> AnalogIn: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t analogio_analogin___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_analogio_analogin_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4, analogio_analogin___exit__); +//| +// Provided by context manager helper. //| value: int //| """The value on the analog pin between 0 and 65535 inclusive (16-bit). (read-only) @@ -110,6 +109,7 @@ MP_PROPERTY_GETTER(analogio_analogin_value_obj, //| ``float`` in Volts. Note the ADC value may not scale to the actual voltage linearly //| at ends of the analog range.""" //| +//| static mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -130,7 +130,7 @@ MP_PROPERTY_GETTER(analogio_analogin_reference_voltage_obj, static const mp_rom_map_elem_t analogio_analogin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogio_analogin_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogio_analogin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&analogio_analogin_value_obj)}, { MP_ROM_QSTR(MP_QSTR_reference_voltage), MP_ROM_PTR(&analogio_analogin_reference_voltage_obj)}, }; diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c index ab0b018a237..b9e5824f978 100644 --- a/shared-bindings/analogio/AnalogOut.c +++ b/shared-bindings/analogio/AnalogOut.c @@ -20,6 +20,9 @@ //| //| **Limitations:** Not available on Nordic, RP2040, Spresense, as there is no on-chip DAC. //| On Espressif, available only on ESP32 and ESP32-S2; other chips do not have a DAC. +//| On ESP32-S2 boards, GPIO18 (DAC2) is often connected to a pull-up resistor, which causes +//| `unexpected output values in the lower part of the output range +//| `_. //| //| Example usage:: //| @@ -36,6 +39,7 @@ //| //| """ //| ... +//| static mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, size_t n_kw, const mp_obj_t *args) { // check arguments mp_arg_check_num(n_args, n_kw, 1, 1, false); @@ -51,6 +55,7 @@ static mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t //| def deinit(self) -> None: //| """Turn off the AnalogOut and release the pin for other use.""" //| ... +//| static mp_obj_t analogio_analogout_deinit(mp_obj_t self_in) { analogio_analogout_obj_t *self = self_in; @@ -63,18 +68,15 @@ static MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogout_deinit_obj, analogio_analogo //| def __enter__(self) -> AnalogOut: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t analogio_analogout___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_analogio_analogout_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4, analogio_analogout___exit__); +//| +// Provided by context manager helper. //| value: int //| """The value on the analog pin between 0 and 65535 inclusive (16-bit). (write-only) @@ -82,6 +84,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4 //| Even if the underlying digital to analog converter (DAC) is lower //| resolution, the value is 16-bit.""" //| +//| static mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_analogio_analogout_deinited(self)) { @@ -100,12 +103,12 @@ MP_PROPERTY_GETSET(analogio_analogout_value_obj, static const mp_rom_map_elem_t analogio_analogout_locals_dict_table[] = { // instance methods - { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogio_analogout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogio_analogout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogio_analogout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Properties - { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&analogio_analogout_value_obj }, + { MP_ROM_QSTR(MP_QSTR_value), (mp_obj_t)&analogio_analogout_value_obj }, }; static MP_DEFINE_CONST_DICT(analogio_analogout_locals_dict, analogio_analogout_locals_dict_table); diff --git a/shared-bindings/atexit/__init__.c b/shared-bindings/atexit/__init__.c index b18e26f2476..11d142bbf35 100644 --- a/shared-bindings/atexit/__init__.c +++ b/shared-bindings/atexit/__init__.c @@ -16,8 +16,10 @@ //| //| |see_cpython_module| :mod:`cpython:atexit`. //| """ +//| //| ... //| +//| //| def register( //| func: Callable[..., Any], *args: Optional[Any], **kwargs: Optional[Any] @@ -38,6 +40,7 @@ //| """ //| ... //| +//| static mp_obj_t atexit_register(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { shared_module_atexit_register(pos_args[0], (n_args - 1), ((n_args > 1) ? &pos_args[1] : NULL), kw_args); return pos_args[0]; @@ -53,6 +56,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(atexit_register_obj, 1, atexit_register); //| """ //| ... //| +//| static mp_obj_t atexit_unregister(const mp_obj_t self_in) { shared_module_atexit_unregister(&self_in); return mp_const_none; diff --git a/shared-bindings/audiobusio/I2SOut.c b/shared-bindings/audiobusio/I2SOut.c index 7c24e8a9efe..a104b20b9da 100644 --- a/shared-bindings/audiobusio/I2SOut.c +++ b/shared-bindings/audiobusio/I2SOut.c @@ -24,7 +24,8 @@ //| data: microcontroller.Pin, //| *, //| main_clock: Optional[microcontroller.Pin] = None, -//| left_justified: bool = False +//| left_justified: bool = False, +//| external_clock: bool = False, //| ) -> None: //| """Create a I2SOut object associated with the given pins. //| @@ -34,6 +35,15 @@ //| :param ~microcontroller.Pin main_clock: The main clock pin //| :param bool left_justified: True when data bits are aligned with the word select clock. False //| when they are shifted by one to match classic I2S protocol. +//| :param bool external_clock: True when this object follows an externally supplied clock: +//| ``bit_clock`` and ``word_select`` are inputs driven by something else, another I2S +//| object (the clock source), or a codec, rather than generated by this object. Not +//| supported on all ports. +//| +//| In external clock mode ``bit_clock`` and ``word_select`` do not have to be sequential +//| GPIOs, and they may be shared with another I2S object. `play` cannot retime the bus, so +//| the sample's ``sample_rate`` must equal the external frame rate or the pitch will be +//| wrong. If the incoming clock stops, output stalls with its last sample held. //| //| Simple 8ksps 440 Hz sine wave on `Metro M0 Express `_ //| using `UDA1334 Breakout `_:: @@ -76,29 +86,41 @@ //| pass //| print("stopped")""" //| ... +//| static mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if !CIRCUITPY_AUDIOBUSIO_I2SOUT mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_I2SOut); return NULL; // Not reachable. #else - enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_main_clock, ARG_left_justified }; + enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_main_clock, ARG_left_justified, ARG_external_clock }; static const mp_arg_t allowed_args[] = { { MP_QSTR_bit_clock, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_word_select, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_main_clock, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_left_justified, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_external_clock, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *bit_clock = validate_obj_is_free_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock); - const mcu_pin_obj_t *word_select = validate_obj_is_free_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select); + bool external_clock = args[ARG_external_clock].u_bool; + + // In external clock mode the clock pins are only read, so they may already + // be owned by whatever is driving them; let the port decide if the sharing + // is legal. + const mcu_pin_obj_t *bit_clock = external_clock + ? validate_obj_is_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock) + : validate_obj_is_free_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock); + const mcu_pin_obj_t *word_select = external_clock + ? validate_obj_is_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select) + : validate_obj_is_free_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select); const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj, MP_QSTR_data); const mcu_pin_obj_t *main_clock = validate_obj_is_free_pin_or_none(args[ARG_main_clock].u_obj, MP_QSTR_main_clock); audiobusio_i2sout_obj_t *self = mp_obj_malloc_with_finaliser(audiobusio_i2sout_obj_t, &audiobusio_i2sout_type); - common_hal_audiobusio_i2sout_construct(self, bit_clock, word_select, data, main_clock, args[ARG_left_justified].u_bool); + common_hal_audiobusio_i2sout_construct(self, bit_clock, word_select, data, main_clock, + args[ARG_left_justified].u_bool, external_clock); return MP_OBJ_FROM_PTR(self); #endif @@ -109,6 +131,7 @@ static mp_obj_t audiobusio_i2sout_make_new(const mp_obj_type_t *type, size_t n_a //| def deinit(self) -> None: //| """Deinitialises the I2SOut and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t audiobusio_i2sout_deinit(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiobusio_i2sout_deinit(self); @@ -125,18 +148,15 @@ static void check_for_deinit(audiobusio_i2sout_obj_t *self) { //| def __enter__(self) -> I2SOut: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t audiobusio_i2sout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audiobusio_i2sout_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4, audiobusio_i2sout_obj___exit__); +//| +// Provided by context manager helper. //| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: @@ -145,8 +165,11 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_i2sout___exit___obj, 4, 4, //| //| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, `audiomixer.Mixer` or `audiomp3.MP3Decoder`. //| +//| Mono samples will be converted to stereo by copying value to both the left channel and the right channel. +//| //| The sample itself should consist of 8 bit or 16 bit samples.""" //| ... +//| static mp_obj_t audiobusio_i2sout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -168,6 +191,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiobusio_i2sout_play_obj, 1, audiobusio_i2sout_obj_ //| def stop(self) -> None: //| """Stops playback.""" //| ... +//| static mp_obj_t audiobusio_i2sout_obj_stop(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -178,6 +202,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_stop_obj, audiobusio_i2sout_obj_stop //| playing: bool //| """True when the audio sample is being output. (read-only)""" +//| static mp_obj_t audiobusio_i2sout_obj_get_playing(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -191,6 +216,7 @@ MP_PROPERTY_GETTER(audiobusio_i2sout_playing_obj, //| def pause(self) -> None: //| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" //| ... +//| static mp_obj_t audiobusio_i2sout_obj_pause(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -206,6 +232,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_pause_obj, audiobusio_i2sout_obj_pau //| def resume(self) -> None: //| """Resumes sample playback after :py:func:`pause`.""" //| ... +//| static mp_obj_t audiobusio_i2sout_obj_resume(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -221,6 +248,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiobusio_i2sout_resume_obj, audiobusio_i2sout_obj_re //| paused: bool //| """True when playback is paused. (read-only)""" //| +//| static mp_obj_t audiobusio_i2sout_obj_get_paused(mp_obj_t self_in) { audiobusio_i2sout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -238,7 +266,7 @@ static const mp_rom_map_elem_t audiobusio_i2sout_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audiobusio_i2sout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiobusio_i2sout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiobusio_i2sout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiobusio_i2sout_play_obj) }, { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiobusio_i2sout_stop_obj) }, { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&audiobusio_i2sout_pause_obj) }, diff --git a/shared-bindings/audiobusio/I2SOut.h b/shared-bindings/audiobusio/I2SOut.h index a53997ef91b..bc3c944b08d 100644 --- a/shared-bindings/audiobusio/I2SOut.h +++ b/shared-bindings/audiobusio/I2SOut.h @@ -16,7 +16,7 @@ extern const mp_obj_type_t audiobusio_i2sout_type; void common_hal_audiobusio_i2sout_construct(audiobusio_i2sout_obj_t *self, const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, const mcu_pin_obj_t *data, - const mcu_pin_obj_t *main_clock, bool left_justified); + const mcu_pin_obj_t *main_clock, bool left_justified, bool external_clock); void common_hal_audiobusio_i2sout_deinit(audiobusio_i2sout_obj_t *self); bool common_hal_audiobusio_i2sout_deinited(audiobusio_i2sout_obj_t *self); diff --git a/shared-bindings/audiobusio/PDMIn.c b/shared-bindings/audiobusio/PDMIn.c index 12428e20034..aba8a019f35 100644 --- a/shared-bindings/audiobusio/PDMIn.c +++ b/shared-bindings/audiobusio/PDMIn.c @@ -27,7 +27,7 @@ //| bit_depth: int = 8, //| mono: bool = True, //| oversample: int = 64, -//| startup_delay: float = 0.11 +//| startup_delay: float = 0.11, //| ) -> None: //| """Create a PDMIn object associated with the given pins. This allows you to //| record audio signals from the given pins. Individual ports may put further @@ -48,7 +48,7 @@ //| //| **Limitations:** On SAMD and RP2040, supports only 8 or 16 bit mono input, with 64x oversampling. //| On nRF52840, supports only 16 bit mono input at 16 kHz; oversampling is fixed at 64x. Not provided -//| on nRF52833 for space reasons. Not available on Espressif. +//| on nRF52833 for space reasons. On Espressif, only available on ESP32, ESP32-S3, and ESP32-P4. //| //| For example, to record 8-bit unsigned samples to a buffer:: //| @@ -70,7 +70,9 @@ //| with audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16) as mic: //| mic.record(b, len(b)) //| """ +//| //| ... +//| static mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if !CIRCUITPY_AUDIOBUSIO_PDMIN mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_PDMIn); @@ -94,9 +96,6 @@ static mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar const mcu_pin_obj_t *clock_pin = validate_obj_is_free_pin(args[ARG_clock_pin].u_obj, MP_QSTR_clock_pin); const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj, MP_QSTR_data_pin); - // create PDMIn object from the given pin - audiobusio_pdmin_obj_t *self = mp_obj_malloc(audiobusio_pdmin_obj_t, &audiobusio_pdmin_type); - uint32_t sample_rate = args[ARG_sample_rate].u_int; uint8_t bit_depth = args[ARG_bit_depth].u_int; if (bit_depth % 8 != 0) { @@ -113,6 +112,7 @@ static mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar : mp_obj_get_float(args[ARG_startup_delay].u_obj); mp_arg_validate_float_range(startup_delay, 0.0f, 1.0f, MP_QSTR_startup_delay); + audiobusio_pdmin_obj_t *self = mp_obj_malloc_with_finaliser(audiobusio_pdmin_obj_t, &audiobusio_pdmin_type); common_hal_audiobusio_pdmin_construct(self, clock_pin, data_pin, sample_rate, bit_depth, mono, oversample); @@ -127,6 +127,7 @@ static mp_obj_t audiobusio_pdmin_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the PDMIn and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t audiobusio_pdmin_deinit(mp_obj_t self_in) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiobusio_pdmin_deinit(self); @@ -142,30 +143,28 @@ static void check_for_deinit(audiobusio_pdmin_obj_t *self) { //| def __enter__(self) -> PDMIn: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context.""" //| ... -static mp_obj_t audiobusio_pdmin_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audiobusio_pdmin_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiobusio_pdmin___exit___obj, 4, 4, audiobusio_pdmin_obj___exit__); +//| +// Provided by context manager helper. -//| def record(self, destination: WriteableBuffer, destination_length: int) -> None: +//| def record(self, destination: WriteableBuffer, destination_length: int) -> int: //| """Records destination_length bytes of samples to destination. This is //| blocking. //| -//| An IOError may be raised when the destination is too slow to record the +//| An OSError may be raised when the destination is too slow to record the //| audio at the given rate. For internal flash, writing all 1s to the file //| before recording is recommended to speed up writes. //| //| :return: The number of samples recorded. If this is less than ``destination_length``, //| some samples were missed due to processing time.""" //| ... +//| static mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_obj); check_for_deinit(self); @@ -175,22 +174,22 @@ static mp_obj_t audiobusio_pdmin_obj_record(mp_obj_t self_obj, mp_obj_t destinat mp_buffer_info_t bufinfo; if (mp_obj_is_type(destination, &mp_type_fileio)) { mp_raise_NotImplementedError(MP_ERROR_TEXT("Cannot record to a file")); - } else if (mp_get_buffer(destination, &bufinfo, MP_BUFFER_WRITE)) { - if (bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL) < length) { - mp_raise_ValueError(MP_ERROR_TEXT("Destination capacity is smaller than destination_length.")); - } - uint8_t bit_depth = common_hal_audiobusio_pdmin_get_bit_depth(self); - if (bufinfo.typecode != 'H' && bit_depth == 16) { - mp_raise_ValueError(MP_ERROR_TEXT("destination buffer must be an array of type 'H' for bit_depth = 16")); - } else if (bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE && bit_depth == 8) { - mp_raise_ValueError(MP_ERROR_TEXT("destination buffer must be a bytearray or array of type 'B' for bit_depth = 8")); - } - // length is the buffer length in slots, not bytes. - uint32_t length_written = - common_hal_audiobusio_pdmin_record_to_buffer(self, bufinfo.buf, length); - return MP_OBJ_NEW_SMALL_INT(length_written); } - return mp_const_none; + + mp_get_buffer_raise(destination, &bufinfo, MP_BUFFER_WRITE); + if (bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL) < length) { + mp_raise_ValueError(MP_ERROR_TEXT("Destination capacity is smaller than destination_length.")); + } + uint8_t bit_depth = common_hal_audiobusio_pdmin_get_bit_depth(self); + if (bufinfo.typecode != 'H' && bit_depth == 16) { + mp_raise_ValueError(MP_ERROR_TEXT("destination buffer must be an array of type 'H' for bit_depth = 16")); + } else if (bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE && bit_depth == 8) { + mp_raise_ValueError(MP_ERROR_TEXT("destination buffer must be a bytearray or array of type 'B' for bit_depth = 8")); + } + // length is the buffer length in slots, not bytes. + uint32_t length_written = + common_hal_audiobusio_pdmin_record_to_buffer(self, bufinfo.buf, length); + return MP_OBJ_NEW_SMALL_INT(length_written); } MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_record); @@ -198,6 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(audiobusio_pdmin_record_obj, audiobusio_pdmin_obj_reco //| """The actual sample_rate of the recording. This may not match the constructed //| sample rate due to internal clock limitations.""" //| +//| static mp_obj_t audiobusio_pdmin_obj_get_sample_rate(mp_obj_t self_in) { audiobusio_pdmin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -210,9 +210,10 @@ MP_PROPERTY_GETTER(audiobusio_pdmin_sample_rate_obj, static const mp_rom_map_elem_t audiobusio_pdmin_locals_dict_table[] = { // Methods + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audiobusio_pdmin_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiobusio_pdmin_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiobusio_pdmin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_record), MP_ROM_PTR(&audiobusio_pdmin_record_obj) }, { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiobusio_pdmin_sample_rate_obj) } }; diff --git a/shared-bindings/audiocore/RawSample.c b/shared-bindings/audiocore/RawSample.c index 8da693b7c59..8dc57903286 100644 --- a/shared-bindings/audiocore/RawSample.c +++ b/shared-bindings/audiocore/RawSample.c @@ -12,6 +12,7 @@ #include "py/runtime.h" #include "shared-bindings/util.h" #include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/__init__.h" //| class RawSample: //| """A raw audio sample buffer in memory""" @@ -22,7 +23,7 @@ //| *, //| channel_count: int = 1, //| sample_rate: int = 8000, -//| single_buffer: bool = True +//| single_buffer: bool = True, //| ) -> None: //| """Create a RawSample based on the given buffer of values. If channel_count is more than //| 1 then each channel's samples should alternate. In other words, for a two channel buffer, the @@ -77,6 +78,7 @@ //| pwm.stop() //| pwm.deinit()""" //| ... +//| static mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_buffer, ARG_channel_count, ARG_sample_rate, ARG_single_buffer }; static const mp_arg_t allowed_args[] = { @@ -88,7 +90,6 @@ static mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - audioio_rawsample_obj_t *self = mp_obj_malloc(audioio_rawsample_obj_t, &audioio_rawsample_type); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); uint8_t bytes_per_sample = 1; @@ -101,9 +102,16 @@ static mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a if (!args[ARG_single_buffer].u_bool && bufinfo.len % (bytes_per_sample * args[ARG_channel_count].u_int * 2) != 0) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Length of %q must be an even multiple of channel_count * type_size"), MP_QSTR_buffer); } - common_hal_audioio_rawsample_construct(self, ((uint8_t *)bufinfo.buf), bufinfo.len, - bytes_per_sample, signed_samples, args[ARG_channel_count].u_int, - args[ARG_sample_rate].u_int, args[ARG_single_buffer].u_bool); + + audioio_rawsample_obj_t *self = mp_obj_malloc(audioio_rawsample_obj_t, &audioio_rawsample_type); + common_hal_audioio_rawsample_construct(self, + ((uint8_t *)bufinfo.buf), + bufinfo.len, + bytes_per_sample, + signed_samples, + args[ARG_channel_count].u_int, + args[ARG_sample_rate].u_int, + args[ARG_single_buffer].u_bool); return MP_OBJ_FROM_PTR(self); } @@ -111,6 +119,7 @@ static mp_obj_t audioio_rawsample_make_new(const mp_obj_type_t *type, size_t n_a //| def deinit(self) -> None: //| """Deinitialises the RawSample and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) { audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audioio_rawsample_deinit(self); @@ -118,27 +127,18 @@ static mp_obj_t audioio_rawsample_deinit(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_deinit_obj, audioio_rawsample_deinit); -static void check_for_deinit(audioio_rawsample_obj_t *self) { - if (common_hal_audioio_rawsample_deinited(self)) { - raise_deinited_error(); - } -} - //| def __enter__(self) -> RawSample: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t audioio_rawsample_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audioio_rawsample_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_rawsample___exit___obj, 4, 4, audioio_rawsample_obj___exit__); +//| +// Provided by context manager helper. //| sample_rate: Optional[int] //| """32 bit value that dictates how quickly samples are played in Hertz (cycles per second). @@ -146,44 +146,23 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_rawsample___exit___obj, 4, 4, //| sample. This will not change the sample rate of any active playback. Call ``play`` again to //| change it.""" //| -static mp_obj_t audioio_rawsample_obj_get_sample_rate(mp_obj_t self_in) { - audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_rawsample_get_sample_rate(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audioio_rawsample_get_sample_rate_obj, audioio_rawsample_obj_get_sample_rate); - -static mp_obj_t audioio_rawsample_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { - audioio_rawsample_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_audioio_rawsample_set_sample_rate(self, mp_obj_get_int(sample_rate)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(audioio_rawsample_set_sample_rate_obj, audioio_rawsample_obj_set_sample_rate); - -MP_PROPERTY_GETSET(audioio_rawsample_sample_rate_obj, - (mp_obj_t)&audioio_rawsample_get_sample_rate_obj, - (mp_obj_t)&audioio_rawsample_set_sample_rate_obj); +//| static const mp_rom_map_elem_t audioio_rawsample_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_rawsample_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_rawsample___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_rawsample_sample_rate_obj) }, + AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(audioio_rawsample_locals_dict, audioio_rawsample_locals_dict_table); static const audiosample_p_t audioio_rawsample_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) - .sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_rawsample_get_sample_rate, - .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_rawsample_get_bits_per_sample, - .channel_count = (audiosample_channel_count_fun)common_hal_audioio_rawsample_get_channel_count, .reset_buffer = (audiosample_reset_buffer_fun)audioio_rawsample_reset_buffer, .get_buffer = (audiosample_get_buffer_fun)audioio_rawsample_get_buffer, - .get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_rawsample_get_buffer_structure, }; MP_DEFINE_CONST_OBJ_TYPE( diff --git a/shared-bindings/audiocore/RawSample.h b/shared-bindings/audiocore/RawSample.h index 1f4ca7f8ec5..a5b9b06e797 100644 --- a/shared-bindings/audiocore/RawSample.h +++ b/shared-bindings/audiocore/RawSample.h @@ -15,8 +15,3 @@ void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t *self, uint8_t channel_count, uint32_t sample_rate, bool single_buffer); void common_hal_audioio_rawsample_deinit(audioio_rawsample_obj_t *self); -bool common_hal_audioio_rawsample_deinited(audioio_rawsample_obj_t *self); -uint32_t common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t *self); -uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t *self); -uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t *self); -void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t *self, uint32_t sample_rate); diff --git a/shared-bindings/audiocore/WaveFile.c b/shared-bindings/audiocore/WaveFile.c index 372330577f9..c93bedd4213 100644 --- a/shared-bindings/audiocore/WaveFile.c +++ b/shared-bindings/audiocore/WaveFile.c @@ -10,6 +10,7 @@ #include "py/objproperty.h" #include "py/runtime.h" #include "shared-bindings/audiocore/WaveFile.h" +#include "shared-bindings/audiocore/__init__.h" #include "shared-bindings/util.h" #include "extmod/vfs_posix.h" @@ -50,6 +51,7 @@ //| print("stopped") //| """ //| ... +//| static mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 2, false); mp_obj_t arg = args[0]; @@ -58,7 +60,6 @@ static mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_ar arg = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), arg, MP_ROM_QSTR(MP_QSTR_rb)); } - audioio_wavefile_obj_t *self = mp_obj_malloc(audioio_wavefile_obj_t, &audioio_wavefile_type); if (!mp_obj_is_type(arg, &mp_type_vfs_fat_fileio)) { mp_raise_TypeError(MP_ERROR_TEXT("file must be a file opened in byte mode")); } @@ -70,6 +71,8 @@ static mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_ar buffer = bufinfo.buf; buffer_size = mp_arg_validate_length_range(bufinfo.len, 8, 1024, MP_QSTR_buffer); } + + audioio_wavefile_obj_t *self = mp_obj_malloc(audioio_wavefile_obj_t, &audioio_wavefile_type); common_hal_audioio_wavefile_construct(self, MP_OBJ_TO_PTR(arg), buffer, buffer_size); @@ -79,6 +82,7 @@ static mp_obj_t audioio_wavefile_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the WaveFile and releases all memory resources for reuse.""" //| ... +//| static mp_obj_t audioio_wavefile_deinit(mp_obj_t self_in) { audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audioio_wavefile_deinit(self); @@ -86,97 +90,47 @@ static mp_obj_t audioio_wavefile_deinit(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_deinit_obj, audioio_wavefile_deinit); -static void check_for_deinit(audioio_wavefile_obj_t *self) { - if (common_hal_audioio_wavefile_deinited(self)) { - raise_deinited_error(); - } -} - //| def __enter__(self) -> WaveFile: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t audioio_wavefile_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audioio_wavefile_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_wavefile___exit___obj, 4, 4, audioio_wavefile_obj___exit__); +//| +// Provided by context manager helper. //| sample_rate: int //| """32 bit value that dictates how quickly samples are loaded into the DAC //| in Hertz (cycles per second). When the sample is looped, this can change //| the pitch output without changing the underlying sample.""" -static mp_obj_t audioio_wavefile_obj_get_sample_rate(mp_obj_t self_in) { - audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_sample_rate(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_sample_rate_obj, audioio_wavefile_obj_get_sample_rate); - -static mp_obj_t audioio_wavefile_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { - audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_audioio_wavefile_set_sample_rate(self, mp_obj_get_int(sample_rate)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(audioio_wavefile_set_sample_rate_obj, audioio_wavefile_obj_set_sample_rate); - -MP_PROPERTY_GETSET(audioio_wavefile_sample_rate_obj, - (mp_obj_t)&audioio_wavefile_get_sample_rate_obj, - (mp_obj_t)&audioio_wavefile_set_sample_rate_obj); //| bits_per_sample: int //| """Bits per sample. (read only)""" -static mp_obj_t audioio_wavefile_obj_get_bits_per_sample(mp_obj_t self_in) { - audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_bits_per_sample(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_bits_per_sample_obj, audioio_wavefile_obj_get_bits_per_sample); - -MP_PROPERTY_GETTER(audioio_wavefile_bits_per_sample_obj, - (mp_obj_t)&audioio_wavefile_get_bits_per_sample_obj); +// //| channel_count: int //| """Number of audio channels. (read only)""" //| -static mp_obj_t audioio_wavefile_obj_get_channel_count(mp_obj_t self_in) { - audioio_wavefile_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audioio_wavefile_get_channel_count(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audioio_wavefile_get_channel_count_obj, audioio_wavefile_obj_get_channel_count); - -MP_PROPERTY_GETTER(audioio_wavefile_channel_count_obj, - (mp_obj_t)&audioio_wavefile_get_channel_count_obj); - +//| static const mp_rom_map_elem_t audioio_wavefile_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_wavefile_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_wavefile___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audioio_wavefile_sample_rate_obj) }, - { MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&audioio_wavefile_bits_per_sample_obj) }, - { MP_ROM_QSTR(MP_QSTR_channel_count), MP_ROM_PTR(&audioio_wavefile_channel_count_obj) }, + AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(audioio_wavefile_locals_dict, audioio_wavefile_locals_dict_table); static const audiosample_p_t audioio_wavefile_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) - .sample_rate = (audiosample_sample_rate_fun)common_hal_audioio_wavefile_get_sample_rate, - .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audioio_wavefile_get_bits_per_sample, - .channel_count = (audiosample_channel_count_fun)common_hal_audioio_wavefile_get_channel_count, .reset_buffer = (audiosample_reset_buffer_fun)audioio_wavefile_reset_buffer, .get_buffer = (audiosample_get_buffer_fun)audioio_wavefile_get_buffer, - .get_buffer_structure = (audiosample_get_buffer_structure_fun)audioio_wavefile_get_buffer_structure, }; diff --git a/shared-bindings/audiocore/WaveFile.h b/shared-bindings/audiocore/WaveFile.h index 7c847bbced7..5249959a1cc 100644 --- a/shared-bindings/audiocore/WaveFile.h +++ b/shared-bindings/audiocore/WaveFile.h @@ -17,8 +17,3 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t *self, pyb_file_obj_t *file, uint8_t *buffer, size_t buffer_size); void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t *self); -bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t *self); -uint32_t common_hal_audioio_wavefile_get_sample_rate(audioio_wavefile_obj_t *self); -void common_hal_audioio_wavefile_set_sample_rate(audioio_wavefile_obj_t *self, uint32_t sample_rate); -uint8_t common_hal_audioio_wavefile_get_bits_per_sample(audioio_wavefile_obj_t *self); -uint8_t common_hal_audioio_wavefile_get_channel_count(audioio_wavefile_obj_t *self); diff --git a/shared-bindings/audiocore/__init__.c b/shared-bindings/audiocore/__init__.c index 4eff83bcfdb..b2b6c4da0f3 100644 --- a/shared-bindings/audiocore/__init__.c +++ b/shared-bindings/audiocore/__init__.c @@ -7,12 +7,14 @@ #include #include "py/obj.h" +#include "py/objproperty.h" #include "py/gc.h" #include "py/runtime.h" #include "shared-bindings/audiocore/__init__.h" #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" +#include "shared-bindings/util.h" // #include "shared-bindings/audiomixer/Mixer.h" //| """Support for audio samples""" @@ -24,6 +26,9 @@ static mp_obj_t audiocore_get_buffer(mp_obj_t sample_in) { uint32_t buffer_length = 0; audioio_get_buffer_result_t gbr = audiosample_get_buffer(sample_in, false, 0, &buffer, &buffer_length); + // audiosample_get_buffer checked that we're a sample so this is a safe cast + audiosample_base_t *sample = MP_OBJ_TO_PTR(sample_in); + mp_obj_t result[2] = {mp_obj_new_int_from_uint(gbr), mp_const_none}; if (gbr != GET_BUFFER_ERROR) { @@ -31,10 +36,10 @@ static mp_obj_t audiocore_get_buffer(mp_obj_t sample_in) { uint32_t max_buffer_length; uint8_t spacing; - uint8_t bits_per_sample = audiosample_bits_per_sample(sample_in); - audiosample_get_buffer_structure(sample_in, false, &single_buffer, &samples_signed, &max_buffer_length, &spacing); + uint8_t bits_per_sample = audiosample_get_bits_per_sample(sample); + audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, &max_buffer_length, &spacing); // copies the data because the gc semantics of get_buffer are unclear - void *result_buf = m_malloc(buffer_length); + void *result_buf = m_malloc_without_collect(buffer_length); memcpy(result_buf, buffer, buffer_length); char typecode = (bits_per_sample == 8 && samples_signed) ? 'b' : @@ -55,7 +60,7 @@ static mp_obj_t audiocore_get_structure(mp_obj_t sample_in) { uint32_t max_buffer_length; uint8_t spacing; - audiosample_get_buffer_structure(sample_in, false, &single_buffer, &samples_signed, &max_buffer_length, &spacing); + audiosample_get_buffer_structure_checked(sample_in, false, &single_buffer, &samples_signed, &max_buffer_length, &spacing); mp_obj_t result[4] = { mp_obj_new_int_from_uint(single_buffer), mp_obj_new_int_from_uint(samples_signed), @@ -92,4 +97,61 @@ const mp_obj_module_t audiocore_module = { .globals = (mp_obj_dict_t *)&audiocore_module_globals, }; +bool audiosample_deinited(const audiosample_base_t *self) { + return self->channel_count == 0; +} + +void audiosample_check_for_deinit(const audiosample_base_t *self) { + if (audiosample_deinited(self)) { + raise_deinited_error(); + } +} + +void audiosample_mark_deinit(audiosample_base_t *self) { + self->channel_count = 0; +} + +// common implementation of channel_count property for audio samples +static mp_obj_t audiosample_obj_get_channel_count(mp_obj_t self_in) { + audiosample_base_t *self = MP_OBJ_TO_PTR(self_in); + audiosample_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(audiosample_get_channel_count(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiosample_get_channel_count_obj, audiosample_obj_get_channel_count); + +MP_PROPERTY_GETTER(audiosample_channel_count_obj, + (mp_obj_t)&audiosample_get_channel_count_obj); + + +// common implementation of bits_per_sample property for audio samples +static mp_obj_t audiosample_obj_get_bits_per_sample(mp_obj_t self_in) { + audiosample_base_t *self = MP_OBJ_TO_PTR(self_in); + audiosample_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(audiosample_get_bits_per_sample(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiosample_get_bits_per_sample_obj, audiosample_obj_get_bits_per_sample); + +MP_PROPERTY_GETTER(audiosample_bits_per_sample_obj, + (mp_obj_t)&audiosample_get_bits_per_sample_obj); + +// common implementation of sample_rate property for audio samples +static mp_obj_t audiosample_obj_get_sample_rate(mp_obj_t self_in) { + audiosample_base_t *self = MP_OBJ_TO_PTR(self_in); + audiosample_check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(audiosample_get_sample_rate(audiosample_check(self_in))); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiosample_get_sample_rate_obj, audiosample_obj_get_sample_rate); + +static mp_obj_t audiosample_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { + audiosample_base_t *self = MP_OBJ_TO_PTR(self_in); + audiosample_check_for_deinit(self); + audiosample_set_sample_rate(audiosample_check(self_in), mp_obj_get_int(sample_rate)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiosample_set_sample_rate_obj, audiosample_obj_set_sample_rate); + +MP_PROPERTY_GETSET(audiosample_sample_rate_obj, + (mp_obj_t)&audiosample_get_sample_rate_obj, + (mp_obj_t)&audiosample_set_sample_rate_obj); + MP_REGISTER_MODULE(MP_QSTR_audiocore, audiocore_module); diff --git a/shared-bindings/audiocore/__init__.h b/shared-bindings/audiocore/__init__.h index 2c669f638b6..defa3d6c8dc 100644 --- a/shared-bindings/audiocore/__init__.h +++ b/shared-bindings/audiocore/__init__.h @@ -5,3 +5,18 @@ // SPDX-License-Identifier: MIT #pragma once + +#include "py/objproperty.h" + +#define AUDIOSAMPLE_FIELDS \ + { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiosample_sample_rate_obj) }, \ + { MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&audiosample_bits_per_sample_obj) }, \ + { MP_ROM_QSTR(MP_QSTR_channel_count), MP_ROM_PTR(&audiosample_channel_count_obj) } + +typedef struct audiosample_base audiosample_base_t; +extern const mp_obj_property_getset_t audiosample_sample_rate_obj; +extern const mp_obj_property_getter_t audiosample_bits_per_sample_obj; +extern const mp_obj_property_getter_t audiosample_channel_count_obj; +void audiosample_check_for_deinit(const audiosample_base_t *self); +bool audiosample_deinited(const audiosample_base_t *self); +void audiosample_mark_deinit(audiosample_base_t *self); diff --git a/shared-bindings/audiodelays/Chorus.c b/shared-bindings/audiodelays/Chorus.c new file mode 100644 index 00000000000..41bcbb7ef93 --- /dev/null +++ b/shared-bindings/audiodelays/Chorus.c @@ -0,0 +1,282 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiodelays/Chorus.h" +#include "shared-module/audiodelays/Chorus.h" +#include "shared-bindings/audiocore/__init__.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class Chorus: +//| """An Chorus effect""" +//| +//| def __init__( +//| self, +//| max_delay_ms: int = 50, +//| delay_ms: synthio.BlockInput = 50.0, +//| voices: synthio.BlockInput = 1.0, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a Chorus effect by playing the current sample along with one or more samples +//| (the voices) from the delay buffer. The voices played are evenly spaced across the delay +//| buffer. So for 2 voices you would hear the current sample and the one delay milliseconds back. +//| The delay timing of the chorus can be changed at runtime with the delay_ms parameter but the delay +//| can never exceed the max_delay_ms parameter. The maximum delay you can set is limited by available +//| memory. +//| +//| :param int max_delay_ms: The maximum time the chorus can be in milliseconds +//| :param synthio.BlockInput delay_ms: The current time of the chorus delay in milliseconds. Must be less the max_delay_ms. +//| :param synthio.BlockInput voices: The number of voices playing split evenly over the delay buffer. +//| :param synthio.BlockInput mix: How much of the wet audio to include along with the original signal. +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| +//| Playing adding an chorus to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiodelays +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| chorus = audiodelays.Chorus(max_delay_ms=50, voices=4, delay_ms=5, buffer_size=1024, channel_count=1, sample_rate=44100) +//| chorus.play(synth) +//| audio.play(chorus) +//| +//| note = synthio.Note(261) +//| while True: +//| synth.press(note) +//| time.sleep(0.25) +//| synth.release(note) +//| time.sleep(5)""" +//| ... +//| +static mp_obj_t audiodelays_chorus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_max_delay_ms, ARG_delay_ms, ARG_voices, ARG_mix, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_max_delay_ms, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 50 } }, + { MP_QSTR_delay_ms, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_voices, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t max_delay_ms = mp_arg_validate_int_range(args[ARG_max_delay_ms].u_int, 1, 4000, MP_QSTR_max_delay_ms); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiodelays_chorus_obj_t *self = mp_obj_malloc(audiodelays_chorus_obj_t, &audiodelays_chorus_type); + common_hal_audiodelays_chorus_construct(self, max_delay_ms, args[ARG_delay_ms].u_obj, args[ARG_voices].u_obj, args[ARG_mix].u_obj, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Chorus.""" +//| ... +//| +static mp_obj_t audiodelays_chorus_deinit(mp_obj_t self_in) { + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_chorus_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_deinit_obj, audiodelays_chorus_deinit); + +static void check_for_deinit(audiodelays_chorus_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> Chorus: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +static mp_obj_t audiodelays_chorus_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audiodelays_chorus_deinit(args[0]); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiodelays_chorus___exit___obj, 4, 4, audiodelays_chorus_obj___exit__); + + +//| delay_ms: synthio.BlockInput +//| """The current time of the chorus delay in milliseconds. Must be less the max_delay_ms.""" +//| +static mp_obj_t audiodelays_chorus_obj_get_delay_ms(mp_obj_t self_in) { + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_audiodelays_chorus_get_delay_ms(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_get_delay_ms_obj, audiodelays_chorus_obj_get_delay_ms); + +static mp_obj_t audiodelays_chorus_obj_set_delay_ms(mp_obj_t self_in, mp_obj_t delay_ms_in) { + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_chorus_set_delay_ms(self, delay_ms_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_chorus_set_delay_ms_obj, audiodelays_chorus_obj_set_delay_ms); + +MP_PROPERTY_GETSET(audiodelays_chorus_delay_ms_obj, + (mp_obj_t)&audiodelays_chorus_get_delay_ms_obj, + (mp_obj_t)&audiodelays_chorus_set_delay_ms_obj); + +//| voices: synthio.BlockInput +//| """The number of voices playing split evenly over the delay buffer.""" +static mp_obj_t audiodelays_chorus_obj_get_voices(mp_obj_t self_in) { + return common_hal_audiodelays_chorus_get_voices(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_get_voices_obj, audiodelays_chorus_obj_get_voices); + +static mp_obj_t audiodelays_chorus_obj_set_voices(mp_obj_t self_in, mp_obj_t voices_in) { + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_chorus_set_voices(self, voices_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_chorus_set_voices_obj, audiodelays_chorus_obj_set_voices); + +MP_PROPERTY_GETSET(audiodelays_chorus_voices_obj, + (mp_obj_t)&audiodelays_chorus_get_voices_obj, + (mp_obj_t)&audiodelays_chorus_set_voices_obj); + +//| mix: synthio.BlockInput +//| """The rate the echo mix between 0 and 1 where 0 is only sample and 1 is all effect.""" +static mp_obj_t audiodelays_chorus_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiodelays_chorus_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_get_mix_obj, audiodelays_chorus_obj_get_mix); + +static mp_obj_t audiodelays_chorus_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_chorus_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_chorus_set_mix_obj, audiodelays_chorus_obj_set_mix); + +MP_PROPERTY_GETSET(audiodelays_chorus_mix_obj, + (mp_obj_t)&audiodelays_chorus_get_mix_obj, + (mp_obj_t)&audiodelays_chorus_set_mix_obj); + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiodelays_chorus_obj_get_playing(mp_obj_t self_in) { + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiodelays_chorus_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_get_playing_obj, audiodelays_chorus_obj_get_playing); + +MP_PROPERTY_GETTER(audiodelays_chorus_playing_obj, + (mp_obj_t)&audiodelays_chorus_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Chorus: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Chorus""" +//| ... +//| +static mp_obj_t audiodelays_chorus_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiodelays_chorus_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_chorus_play_obj, 1, audiodelays_chorus_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample.""" +//| ... +//| +//| +static mp_obj_t audiodelays_chorus_obj_stop(mp_obj_t self_in) { + audiodelays_chorus_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiodelays_chorus_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_chorus_stop_obj, audiodelays_chorus_obj_stop); + +static const mp_rom_map_elem_t audiodelays_chorus_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiodelays_chorus_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiodelays_chorus___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiodelays_chorus_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiodelays_chorus_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_chorus_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_delay_ms), MP_ROM_PTR(&audiodelays_chorus_delay_ms_obj) }, + { MP_ROM_QSTR(MP_QSTR_voices), MP_ROM_PTR(&audiodelays_chorus_voices_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_chorus_mix_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiodelays_chorus_locals_dict, audiodelays_chorus_locals_dict_table); + +static const audiosample_p_t audiodelays_chorus_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiodelays_chorus_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiodelays_chorus_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiodelays_chorus_type, + MP_QSTR_Chorus, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiodelays_chorus_make_new, + locals_dict, &audiodelays_chorus_locals_dict, + protocol, &audiodelays_chorus_proto + ); diff --git a/shared-bindings/audiodelays/Chorus.h b/shared-bindings/audiodelays/Chorus.h new file mode 100644 index 00000000000..63e9ba9c28d --- /dev/null +++ b/shared-bindings/audiodelays/Chorus.h @@ -0,0 +1,32 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiodelays/Chorus.h" + +extern const mp_obj_type_t audiodelays_chorus_type; + +void common_hal_audiodelays_chorus_construct(audiodelays_chorus_obj_t *self, uint32_t max_delay_ms, + mp_obj_t delay_ms, mp_obj_t voices, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiodelays_chorus_deinit(audiodelays_chorus_obj_t *self); +bool common_hal_audiodelays_chorus_deinited(audiodelays_chorus_obj_t *self); + +mp_obj_t common_hal_audiodelays_chorus_get_delay_ms(audiodelays_chorus_obj_t *self); +void common_hal_audiodelays_chorus_set_delay_ms(audiodelays_chorus_obj_t *self, mp_obj_t delay_ms); + +mp_obj_t common_hal_audiodelays_chorus_get_voices(audiodelays_chorus_obj_t *self); +void common_hal_audiodelays_chorus_set_voices(audiodelays_chorus_obj_t *self, mp_obj_t voices); + +mp_obj_t common_hal_audiodelays_chorus_get_mix(audiodelays_chorus_obj_t *self); +void common_hal_audiodelays_chorus_set_mix(audiodelays_chorus_obj_t *self, mp_obj_t arg); + +bool common_hal_audiodelays_chorus_get_playing(audiodelays_chorus_obj_t *self); +void common_hal_audiodelays_chorus_play(audiodelays_chorus_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiodelays_chorus_stop(audiodelays_chorus_obj_t *self); diff --git a/shared-bindings/audiodelays/Echo.c b/shared-bindings/audiodelays/Echo.c new file mode 100644 index 00000000000..f1c79de0e13 --- /dev/null +++ b/shared-bindings/audiodelays/Echo.c @@ -0,0 +1,334 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiodelays/Echo.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiodelays/Echo.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class Echo: +//| """An Echo effect""" +//| +//| def __init__( +//| self, +//| max_delay_ms: int = 500, +//| delay_ms: synthio.BlockInput = 250.0, +//| decay: synthio.BlockInput = 0.7, +//| filter: Optional[synthio.Biquad | Tuple[synthio.Biquad]] = None, +//| mix: synthio.BlockInput = 0.25, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a Echo effect where you hear the original sample play back, at a lesser volume after +//| a set number of millisecond delay. The delay timing of the echo can be changed at runtime +//| with the delay_ms parameter but the delay can never exceed the max_delay_ms parameter. The +//| maximum delay you can set is limited by available memory. +//| +//| Each time the echo plays back the volume is reduced by the decay setting (echo * decay). +//| +//| The mix parameter allows you to change how much of the unchanged sample passes through to +//| the output to how much of the effect audio you hear as the output. +//| +//| :param int max_delay_ms: The maximum time the echo can be in milliseconds +//| :param synthio.BlockInput delay_ms: The current time of the echo delay in milliseconds. Must be less the max_delay_ms +//| :param synthio.BlockInput decay: The rate the echo fades. 0.0 = instant; 1.0 = never. +//| :param Optional[synthio.Biquad|Tuple[synthio.Biquad]] filter: A normalized biquad filter object or tuple of normalized biquad filter objects. A copy of the samples are processed sequentially by each filter before writing into the echo buffer. The original samples are not affected by this argument. +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0). +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| :param bool freq_shift: Do echos change frequency as the echo delay changes +//| +//| Playing adding an echo to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiodelays +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| echo = audiodelays.Echo(max_delay_ms=1000, delay_ms=850, decay=0.65, buffer_size=1024, channel_count=1, sample_rate=44100, mix=0.7, freq_shift=False) +//| echo.play(synth) +//| audio.play(echo) +//| +//| note = synthio.Note(261) +//| while True: +//| synth.press(note) +//| time.sleep(0.25) +//| synth.release(note) +//| time.sleep(5)""" +//| ... +//| +static mp_obj_t audiodelays_echo_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_max_delay_ms, ARG_delay_ms, ARG_decay, ARG_filter, ARG_mix, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, ARG_freq_shift, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_max_delay_ms, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 500 } }, + { MP_QSTR_delay_ms, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_decay, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_filter, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + { MP_QSTR_freq_shift, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t max_delay_ms = mp_arg_validate_int_range(args[ARG_max_delay_ms].u_int, 1, 4000, MP_QSTR_max_delay_ms); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiodelays_echo_obj_t *self = mp_obj_malloc(audiodelays_echo_obj_t, &audiodelays_echo_type); + common_hal_audiodelays_echo_construct(self, max_delay_ms, args[ARG_delay_ms].u_obj, args[ARG_decay].u_obj, args[ARG_filter].u_obj, args[ARG_mix].u_obj, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate, args[ARG_freq_shift].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Echo.""" +//| ... +//| +static mp_obj_t audiodelays_echo_deinit(mp_obj_t self_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_echo_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_deinit_obj, audiodelays_echo_deinit); + +static void check_for_deinit(audiodelays_echo_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> Echo: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + + +//| delay_ms: synthio.BlockInput +//| """Delay of the echo in milliseconds. (read-only)""" +//| +static mp_obj_t audiodelays_echo_obj_get_delay_ms(mp_obj_t self_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_audiodelays_echo_get_delay_ms(self); + +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_delay_ms_obj, audiodelays_echo_obj_get_delay_ms); + +static mp_obj_t audiodelays_echo_obj_set_delay_ms(mp_obj_t self_in, mp_obj_t delay_ms_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_echo_set_delay_ms(self, delay_ms_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_echo_set_delay_ms_obj, audiodelays_echo_obj_set_delay_ms); + +MP_PROPERTY_GETSET(audiodelays_echo_delay_ms_obj, + (mp_obj_t)&audiodelays_echo_get_delay_ms_obj, + (mp_obj_t)&audiodelays_echo_set_delay_ms_obj); + +//| decay: synthio.BlockInput +//| """The rate the echo fades between 0 and 1 where 0 is instant and 1 is never.""" +static mp_obj_t audiodelays_echo_obj_get_decay(mp_obj_t self_in) { + return common_hal_audiodelays_echo_get_decay(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_decay_obj, audiodelays_echo_obj_get_decay); + +static mp_obj_t audiodelays_echo_obj_set_decay(mp_obj_t self_in, mp_obj_t decay_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_echo_set_decay(self, decay_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_echo_set_decay_obj, audiodelays_echo_obj_set_decay); + +MP_PROPERTY_GETSET(audiodelays_echo_decay_obj, + (mp_obj_t)&audiodelays_echo_get_decay_obj, + (mp_obj_t)&audiodelays_echo_set_decay_obj); + + +//| filter: synthio.Biquad | Tuple[synthio.Biquad] | None +//| """A normalized biquad filter object or tuple of normalized biquad filter objects. A copy of the samples are processed sequentially by each filter before writing into the echo buffer. The original samples are not affected by this property.""" +//| +static mp_obj_t audiodelays_echo_obj_get_filter(mp_obj_t self_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_audiodelays_echo_get_filter(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_filter_obj, audiodelays_echo_obj_get_filter); + +static mp_obj_t audiodelays_echo_obj_set_filter(mp_obj_t self_in, mp_obj_t filter_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_echo_set_filter(self, filter_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_echo_set_filter_obj, audiodelays_echo_obj_set_filter); + +MP_PROPERTY_GETSET(audiodelays_echo_filter_obj, + (mp_obj_t)&audiodelays_echo_get_filter_obj, + (mp_obj_t)&audiodelays_echo_set_filter_obj); + + +//| mix: synthio.BlockInput +//| """The rate the echo mix between 0 and 1 where 0 is only sample, 0.5 is an equal mix of the sample and the effect and 1 is all effect.""" +static mp_obj_t audiodelays_echo_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiodelays_echo_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_mix_obj, audiodelays_echo_obj_get_mix); + +static mp_obj_t audiodelays_echo_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_echo_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_echo_set_mix_obj, audiodelays_echo_obj_set_mix); + +MP_PROPERTY_GETSET(audiodelays_echo_mix_obj, + (mp_obj_t)&audiodelays_echo_get_mix_obj, + (mp_obj_t)&audiodelays_echo_set_mix_obj); + + + +//| freq_shift: bool +//| """Does the echo change frequencies as the delay changes.""" +static mp_obj_t audiodelays_echo_obj_get_freq_shift(mp_obj_t self_in) { + return mp_obj_new_bool(common_hal_audiodelays_echo_get_freq_shift(self_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_freq_shift_obj, audiodelays_echo_obj_get_freq_shift); + +static mp_obj_t audiodelays_echo_obj_set_freq_shift(mp_obj_t self_in, mp_obj_t freq_shift_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_echo_set_freq_shift(self, mp_obj_is_true(freq_shift_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_echo_set_freq_shift_obj, audiodelays_echo_obj_set_freq_shift); + +MP_PROPERTY_GETSET(audiodelays_echo_freq_shift_obj, + (mp_obj_t)&audiodelays_echo_get_freq_shift_obj, + (mp_obj_t)&audiodelays_echo_set_freq_shift_obj); + + + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiodelays_echo_obj_get_playing(mp_obj_t self_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiodelays_echo_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_get_playing_obj, audiodelays_echo_obj_get_playing); + +MP_PROPERTY_GETTER(audiodelays_echo_playing_obj, + (mp_obj_t)&audiodelays_echo_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Echo: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Echo""" +//| ... +//| +static mp_obj_t audiodelays_echo_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiodelays_echo_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_echo_play_obj, 1, audiodelays_echo_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample. The echo continues playing.""" +//| ... +//| +//| +static mp_obj_t audiodelays_echo_obj_stop(mp_obj_t self_in) { + audiodelays_echo_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiodelays_echo_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_echo_stop_obj, audiodelays_echo_obj_stop); + +static const mp_rom_map_elem_t audiodelays_echo_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiodelays_echo_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiodelays_echo_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiodelays_echo_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_echo_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_delay_ms), MP_ROM_PTR(&audiodelays_echo_delay_ms_obj) }, + { MP_ROM_QSTR(MP_QSTR_decay), MP_ROM_PTR(&audiodelays_echo_decay_obj) }, + { MP_ROM_QSTR(MP_QSTR_filter), MP_ROM_PTR(&audiodelays_echo_filter_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_echo_mix_obj) }, + { MP_ROM_QSTR(MP_QSTR_freq_shift), MP_ROM_PTR(&audiodelays_echo_freq_shift_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiodelays_echo_locals_dict, audiodelays_echo_locals_dict_table); + +static const audiosample_p_t audiodelays_echo_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiodelays_echo_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiodelays_echo_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiodelays_echo_type, + MP_QSTR_Echo, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiodelays_echo_make_new, + locals_dict, &audiodelays_echo_locals_dict, + protocol, &audiodelays_echo_proto + ); diff --git a/shared-bindings/audiodelays/Echo.h b/shared-bindings/audiodelays/Echo.h new file mode 100644 index 00000000000..67b7436b896 --- /dev/null +++ b/shared-bindings/audiodelays/Echo.h @@ -0,0 +1,37 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiodelays/Echo.h" + +extern const mp_obj_type_t audiodelays_echo_type; + +void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_t max_delay_ms, + mp_obj_t delay_ms, mp_obj_t decay, mp_obj_t filter, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate, bool freq_shift); + +void common_hal_audiodelays_echo_deinit(audiodelays_echo_obj_t *self); + +mp_obj_t common_hal_audiodelays_echo_get_delay_ms(audiodelays_echo_obj_t *self); +void common_hal_audiodelays_echo_set_delay_ms(audiodelays_echo_obj_t *self, mp_obj_t delay_ms); + +bool common_hal_audiodelays_echo_get_freq_shift(audiodelays_echo_obj_t *self); +void common_hal_audiodelays_echo_set_freq_shift(audiodelays_echo_obj_t *self, bool freq_shift); + +mp_obj_t common_hal_audiodelays_echo_get_decay(audiodelays_echo_obj_t *self); +void common_hal_audiodelays_echo_set_decay(audiodelays_echo_obj_t *self, mp_obj_t decay); + +mp_obj_t common_hal_audiodelays_echo_get_filter(audiodelays_echo_obj_t *self); +void common_hal_audiodelays_echo_set_filter(audiodelays_echo_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiodelays_echo_get_mix(audiodelays_echo_obj_t *self); +void common_hal_audiodelays_echo_set_mix(audiodelays_echo_obj_t *self, mp_obj_t arg); + +bool common_hal_audiodelays_echo_get_playing(audiodelays_echo_obj_t *self); +void common_hal_audiodelays_echo_play(audiodelays_echo_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiodelays_echo_stop(audiodelays_echo_obj_t *self); diff --git a/shared-bindings/audiodelays/Flanger.c b/shared-bindings/audiodelays/Flanger.c new file mode 100644 index 00000000000..7c16e164944 --- /dev/null +++ b/shared-bindings/audiodelays/Flanger.c @@ -0,0 +1,389 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiodelays/Flanger.h" +#include "shared-module/audiodelays/Flanger.h" +#include "shared-bindings/audiocore/__init__.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class Flanger: +//| """A Flanger effect""" +//| +//| def __init__( +//| self, +//| max_delay_ms: int = 10, +//| min_delay_ms: synthio.BlockInput = 1.0, +//| rate: synthio.BlockInput = 0.5, +//| depth: synthio.BlockInput = 0.5, +//| feedback: synthio.BlockInput = 0.5, +//| mix: synthio.BlockInput = 0.5, +//| invert: bool = False, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a Flanger effect by mixing the sample with a copy of itself taken from a very +//| short delay whose length is continuously swept up and down by an internal low frequency +//| oscillator. The moving delay creates a comb filter whose notches sweep through the +//| spectrum, and the ``feedback`` path routes the delayed signal back into the delay line +//| to sharpen those notches into resonant peaks. +//| +//| The delay is swept upwards from ``min_delay_ms`` towards ``max_delay_ms``:: +//| +//| sweep_top = min_delay_ms + depth * (max_delay_ms - min_delay_ms) +//| current_delay = min_delay_ms + triangle_lfo() * (sweep_top - min_delay_ms) +//| +//| where ``triangle_lfo()`` ranges from 0.0 to 1.0 at ``rate`` Hz. Because the sweep runs +//| upwards from a floor rather than around a centre, no combination of ``min_delay_ms`` and +//| ``depth`` can push the delay outside of the buffer. +//| +//| +//| :param int max_delay_ms: The maximum delay the flanger can sweep to in milliseconds, valid range is 1-100. +//| :param synthio.BlockInput min_delay_ms: The shortest delay of the sweep in milliseconds. Clamped between the length of one sample and max_delay_ms. +//| :param synthio.BlockInput rate: The frequency of the sweep in hertz. Clamped between 0.0 and 20.0. A rate of 0.0 holds the delay still. +//| :param synthio.BlockInput depth: How much of the range above min_delay_ms is swept, from 0.0 to 1.0. +//| :param synthio.BlockInput feedback: How much of the delayed signal is fed back into the delay line, from -0.95 to 0.95. Negative values invert the polarity of the feedback. +//| :param synthio.BlockInput mix: How much of the wet audio to include along with the original signal, from 0.0 to 1.0. +//| :param bool invert: Subtract the wet signal from the dry signal instead of adding it, which flips which frequencies cancel. +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| +//| Adding a flanger to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiodelays +//| +//| audio = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WS, board.I2S_DOUT) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| flanger = audiodelays.Flanger(max_delay_ms=10, min_delay_ms=1.0, rate=0.3, depth=0.8, +//| feedback=0.7, mix=1.0, buffer_size=1024, +//| channel_count=1, sample_rate=44100) +//| audio.play(flanger.play(synth)) +//| +//| note = synthio.Note(261) +//| while True: +//| synth.press(note) +//| time.sleep(3) +//| synth.release(note) +//| time.sleep(1)""" +//| ... +//| +static mp_obj_t audiodelays_flanger_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_max_delay_ms, ARG_min_delay_ms, ARG_rate, ARG_depth, ARG_feedback, ARG_mix, ARG_invert, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_max_delay_ms, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 10 } }, + { MP_QSTR_min_delay_ms, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_rate, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_depth, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_feedback, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_invert, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t max_delay_ms = mp_arg_validate_int_range(args[ARG_max_delay_ms].u_int, 1, 100, MP_QSTR_max_delay_ms); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiodelays_flanger_obj_t *self = mp_obj_malloc(audiodelays_flanger_obj_t, &audiodelays_flanger_type); + common_hal_audiodelays_flanger_construct(self, max_delay_ms, args[ARG_min_delay_ms].u_obj, args[ARG_rate].u_obj, args[ARG_depth].u_obj, args[ARG_feedback].u_obj, args[ARG_mix].u_obj, args[ARG_invert].u_bool, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Flanger.""" +//| ... +//| +static mp_obj_t audiodelays_flanger_deinit(mp_obj_t self_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_flanger_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_deinit_obj, audiodelays_flanger_deinit); + +static void check_for_deinit(audiodelays_flanger_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> Flanger: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +static mp_obj_t audiodelays_flanger_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audiodelays_flanger_deinit(args[0]); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiodelays_flanger___exit___obj, 4, 4, audiodelays_flanger_obj___exit__); + + +//| min_delay_ms: synthio.BlockInput +//| """The shortest delay of the sweep in milliseconds. This is the floor that the sweep runs +//| upwards from. Clamped between the length of a single sample and ``max_delay_ms``.""" +//| +static mp_obj_t audiodelays_flanger_obj_get_min_delay_ms(mp_obj_t self_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_audiodelays_flanger_get_min_delay_ms(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_min_delay_ms_obj, audiodelays_flanger_obj_get_min_delay_ms); + +static mp_obj_t audiodelays_flanger_obj_set_min_delay_ms(mp_obj_t self_in, mp_obj_t min_delay_ms_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_flanger_set_min_delay_ms(self, min_delay_ms_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_flanger_set_min_delay_ms_obj, audiodelays_flanger_obj_set_min_delay_ms); + +MP_PROPERTY_GETSET(audiodelays_flanger_min_delay_ms_obj, + (mp_obj_t)&audiodelays_flanger_get_min_delay_ms_obj, + (mp_obj_t)&audiodelays_flanger_set_min_delay_ms_obj); + +//| rate: synthio.BlockInput +//| """The frequency of the delay sweep in hertz. Clamped between 0.0 and 20.0. A rate of 0.0 +//| holds the delay still, which leaves a fixed comb filter.""" +//| +static mp_obj_t audiodelays_flanger_obj_get_rate(mp_obj_t self_in) { + return common_hal_audiodelays_flanger_get_rate(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_rate_obj, audiodelays_flanger_obj_get_rate); + +static mp_obj_t audiodelays_flanger_obj_set_rate(mp_obj_t self_in, mp_obj_t rate_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_flanger_set_rate(self, rate_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_flanger_set_rate_obj, audiodelays_flanger_obj_set_rate); + +MP_PROPERTY_GETSET(audiodelays_flanger_rate_obj, + (mp_obj_t)&audiodelays_flanger_get_rate_obj, + (mp_obj_t)&audiodelays_flanger_set_rate_obj); + +//| depth: synthio.BlockInput +//| """How much of the range between ``min_delay_ms`` and ``max_delay_ms`` the sweep covers, from +//| 0.0 to 1.0. A depth of 0.0 leaves a static short delay.""" +//| +static mp_obj_t audiodelays_flanger_obj_get_depth(mp_obj_t self_in) { + return common_hal_audiodelays_flanger_get_depth(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_depth_obj, audiodelays_flanger_obj_get_depth); + +static mp_obj_t audiodelays_flanger_obj_set_depth(mp_obj_t self_in, mp_obj_t depth_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_flanger_set_depth(self, depth_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_flanger_set_depth_obj, audiodelays_flanger_obj_set_depth); + +MP_PROPERTY_GETSET(audiodelays_flanger_depth_obj, + (mp_obj_t)&audiodelays_flanger_get_depth_obj, + (mp_obj_t)&audiodelays_flanger_set_depth_obj); + +//| feedback: synthio.BlockInput +//| """How much of the delayed signal is fed back into the delay line, clamped between -0.95 and +//| 0.95. Larger magnitudes give a more resonant, ringing sweep. Negative values invert the +//| polarity of the feedback for the hollower variant.""" +//| +static mp_obj_t audiodelays_flanger_obj_get_feedback(mp_obj_t self_in) { + return common_hal_audiodelays_flanger_get_feedback(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_feedback_obj, audiodelays_flanger_obj_get_feedback); + +static mp_obj_t audiodelays_flanger_obj_set_feedback(mp_obj_t self_in, mp_obj_t feedback_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_flanger_set_feedback(self, feedback_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_flanger_set_feedback_obj, audiodelays_flanger_obj_set_feedback); + +MP_PROPERTY_GETSET(audiodelays_flanger_feedback_obj, + (mp_obj_t)&audiodelays_flanger_get_feedback_obj, + (mp_obj_t)&audiodelays_flanger_set_feedback_obj); + +//| mix: synthio.BlockInput +//| """How much of the wet audio to include along with the original signal, clamped between 0.0 +//| and 1.0 where 0.0 is only the sample and 1.0 is the full effect.""" +//| +static mp_obj_t audiodelays_flanger_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiodelays_flanger_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_mix_obj, audiodelays_flanger_obj_get_mix); + +static mp_obj_t audiodelays_flanger_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_flanger_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_flanger_set_mix_obj, audiodelays_flanger_obj_set_mix); + +MP_PROPERTY_GETSET(audiodelays_flanger_mix_obj, + (mp_obj_t)&audiodelays_flanger_get_mix_obj, + (mp_obj_t)&audiodelays_flanger_set_mix_obj); + +//| invert: bool +//| """Whether the wet signal is subtracted from the dry signal instead of added to it. This +//| flips which frequencies the comb filter cancels, the same as the polarity switch on a +//| flanger pedal.""" +//| +static mp_obj_t audiodelays_flanger_obj_get_invert(mp_obj_t self_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_audiodelays_flanger_get_invert(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_invert_obj, audiodelays_flanger_obj_get_invert); + +static mp_obj_t audiodelays_flanger_obj_set_invert(mp_obj_t self_in, mp_obj_t invert_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_flanger_set_invert(self, mp_obj_is_true(invert_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_flanger_set_invert_obj, audiodelays_flanger_obj_set_invert); + +MP_PROPERTY_GETSET(audiodelays_flanger_invert_obj, + (mp_obj_t)&audiodelays_flanger_get_invert_obj, + (mp_obj_t)&audiodelays_flanger_set_invert_obj); + +//| lfo_value: float +//| """The current value of the internal LFO that sweeps the delay time, from 0.0 at +//| `min_delay_ms` to 1.0 at the top of the sweep. The LFO only advances while audio is being +//| played. (read-only)""" +//| +static mp_obj_t audiodelays_flanger_obj_get_lfo_value(mp_obj_t self_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_float(common_hal_audiodelays_flanger_get_lfo_value(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_lfo_value_obj, audiodelays_flanger_obj_get_lfo_value); + +MP_PROPERTY_GETTER(audiodelays_flanger_lfo_value_obj, + (mp_obj_t)&audiodelays_flanger_get_lfo_value_obj); + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiodelays_flanger_obj_get_playing(mp_obj_t self_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiodelays_flanger_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_get_playing_obj, audiodelays_flanger_obj_get_playing); + +MP_PROPERTY_GETTER(audiodelays_flanger_playing_obj, + (mp_obj_t)&audiodelays_flanger_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Flanger: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Flanger""" +//| ... +//| +static mp_obj_t audiodelays_flanger_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiodelays_flanger_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_flanger_play_obj, 1, audiodelays_flanger_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample.""" +//| ... +//| +//| +static mp_obj_t audiodelays_flanger_obj_stop(mp_obj_t self_in) { + audiodelays_flanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiodelays_flanger_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_flanger_stop_obj, audiodelays_flanger_obj_stop); + +static const mp_rom_map_elem_t audiodelays_flanger_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiodelays_flanger_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiodelays_flanger___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiodelays_flanger_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiodelays_flanger_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_flanger_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_min_delay_ms), MP_ROM_PTR(&audiodelays_flanger_min_delay_ms_obj) }, + { MP_ROM_QSTR(MP_QSTR_rate), MP_ROM_PTR(&audiodelays_flanger_rate_obj) }, + { MP_ROM_QSTR(MP_QSTR_depth), MP_ROM_PTR(&audiodelays_flanger_depth_obj) }, + { MP_ROM_QSTR(MP_QSTR_feedback), MP_ROM_PTR(&audiodelays_flanger_feedback_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_flanger_mix_obj) }, + { MP_ROM_QSTR(MP_QSTR_invert), MP_ROM_PTR(&audiodelays_flanger_invert_obj) }, + { MP_ROM_QSTR(MP_QSTR_lfo_value), MP_ROM_PTR(&audiodelays_flanger_lfo_value_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiodelays_flanger_locals_dict, audiodelays_flanger_locals_dict_table); + +static const audiosample_p_t audiodelays_flanger_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiodelays_flanger_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiodelays_flanger_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiodelays_flanger_type, + MP_QSTR_Flanger, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiodelays_flanger_make_new, + locals_dict, &audiodelays_flanger_locals_dict, + protocol, &audiodelays_flanger_proto + ); diff --git a/shared-bindings/audiodelays/Flanger.h b/shared-bindings/audiodelays/Flanger.h new file mode 100644 index 00000000000..f139e842dbd --- /dev/null +++ b/shared-bindings/audiodelays/Flanger.h @@ -0,0 +1,43 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiodelays/Flanger.h" + +extern const mp_obj_type_t audiodelays_flanger_type; + +void common_hal_audiodelays_flanger_construct(audiodelays_flanger_obj_t *self, uint32_t max_delay_ms, + mp_obj_t min_delay_ms, mp_obj_t rate, mp_obj_t depth, mp_obj_t feedback, mp_obj_t mix, bool invert, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiodelays_flanger_deinit(audiodelays_flanger_obj_t *self); +bool common_hal_audiodelays_flanger_deinited(audiodelays_flanger_obj_t *self); + +mp_obj_t common_hal_audiodelays_flanger_get_min_delay_ms(audiodelays_flanger_obj_t *self); +void common_hal_audiodelays_flanger_set_min_delay_ms(audiodelays_flanger_obj_t *self, mp_obj_t min_delay_ms); + +mp_obj_t common_hal_audiodelays_flanger_get_rate(audiodelays_flanger_obj_t *self); +void common_hal_audiodelays_flanger_set_rate(audiodelays_flanger_obj_t *self, mp_obj_t rate); + +mp_obj_t common_hal_audiodelays_flanger_get_depth(audiodelays_flanger_obj_t *self); +void common_hal_audiodelays_flanger_set_depth(audiodelays_flanger_obj_t *self, mp_obj_t depth); + +mp_obj_t common_hal_audiodelays_flanger_get_feedback(audiodelays_flanger_obj_t *self); +void common_hal_audiodelays_flanger_set_feedback(audiodelays_flanger_obj_t *self, mp_obj_t feedback); + +mp_obj_t common_hal_audiodelays_flanger_get_mix(audiodelays_flanger_obj_t *self); +void common_hal_audiodelays_flanger_set_mix(audiodelays_flanger_obj_t *self, mp_obj_t arg); + +mp_float_t common_hal_audiodelays_flanger_get_lfo_value(audiodelays_flanger_obj_t *self); + +bool common_hal_audiodelays_flanger_get_invert(audiodelays_flanger_obj_t *self); +void common_hal_audiodelays_flanger_set_invert(audiodelays_flanger_obj_t *self, bool invert); + +bool common_hal_audiodelays_flanger_get_playing(audiodelays_flanger_obj_t *self); +void common_hal_audiodelays_flanger_play(audiodelays_flanger_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiodelays_flanger_stop(audiodelays_flanger_obj_t *self); diff --git a/shared-bindings/audiodelays/GranularPitchShift.c b/shared-bindings/audiodelays/GranularPitchShift.c new file mode 100644 index 00000000000..afbda30156a --- /dev/null +++ b/shared-bindings/audiodelays/GranularPitchShift.c @@ -0,0 +1,315 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiodelays/GranularPitchShift.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiodelays/GranularPitchShift.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class GranularPitchShift: +//| """A granular-synthesis pitch shift effect""" +//| +//| def __init__( +//| self, +//| semitones: synthio.BlockInput = 0.0, +//| mix: synthio.BlockInput = 1.0, +//| grain_size: int = 1024, +//| density: int = 2, +//| spread: float = 0.0, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a pitch shift effect that shifts pitch using granular synthesis: a cloud of +//| short, overlapping, individually-enveloped grains resampled from a capture buffer. Unlike +//| `PitchShift` (a single crossfaded window), the overlapping grains tend to sound smoother +//| and less "robotic" at large shifts. This effect introduces a slight delay in the output +//| proportional to ``grain_size``. +//| +//| The mix parameter allows you to change how much of the unchanged sample passes through to +//| the output to how much of the effect audio you hear as the output. +//| +//| :param synthio.BlockInput semitones: The amount of pitch shifting in semitones (1/12th of an octave) +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0) +//| :param int grain_size: The length in samples of each grain +//| :param int density: The number of overlapping grains (overlap factor). Must be between 1 and 8. +//| :param float spread: The amount of random jitter applied to each grain's start position, +//| from 0.0 (deterministic; every grain starts at the same offset) to 1.0 (maximum jitter). +//| Higher values give the classic granular "cloud" texture. Jitter is always backward in +//| time, so it never introduces additional latency beyond ``grain_size``. +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| +//| Shifting the pitch of a synth by 5 semitones:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiodelays +//| from pwmio import PWMOut +//| import adafruit_tlv320 +//| +//| mclk_pwm = PWMOut(board.I2S_MCLK, frequency=15_000_000, duty_cycle=2**15) +//| i2c = board.I2C() +//| dac = adafruit_tlv320.TLV320DAC3100(i2c) +//| dac.configure_clocks(sample_rate=44100, bit_depth=16, mclk_freq=15_000_000) +//| dac.headphone_output = True +//| audio = audiobusio.I2SOut(board.I2S_BCLK, board.I2S_WS, board.I2S_DIN) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| pitch_shift = audiodelays.GranularPitchShift(semitones=5.0, mix=1.0, spread=0.25, grain_size=2048, density=2, buffer_size=1024, channel_count=1, sample_rate=44100) +//| pitch_shift.play(synth) +//| audio.play(pitch_shift) +//| +//| while True: +//| for notenum in (60, 64, 67, 71): +//| synth.press(notenum) +//| time.sleep(0.25) +//| synth.release_all()""" +//| ... +//| +static mp_obj_t audiodelays_granular_pitch_shift_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_semitones, ARG_mix, ARG_grain_size, ARG_density, ARG_spread, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_semitones, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0)} }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1)} }, + { MP_QSTR_grain_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1024} }, + { MP_QSTR_density, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 2} }, + { MP_QSTR_spread, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0)} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t grain_size = mp_arg_validate_int_min(args[ARG_grain_size].u_int, 2, MP_QSTR_grain_size); + mp_int_t density = mp_arg_validate_int_range(args[ARG_density].u_int, 1, GRANULAR_MAX_GRAINS, MP_QSTR_density); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiodelays_granular_pitch_shift_obj_t *self = + mp_obj_malloc(audiodelays_granular_pitch_shift_obj_t, &audiodelays_granular_pitch_shift_type); + common_hal_audiodelays_granular_pitch_shift_construct(self, + args[ARG_semitones].u_obj, + args[ARG_mix].u_obj, + grain_size, + density, + mp_obj_get_float(args[ARG_spread].u_obj), + args[ARG_buffer_size].u_int, + bits_per_sample, + args[ARG_samples_signed].u_bool, + channel_count, + sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + + +//| def deinit(self) -> None: +//| """Deinitialises the GranularPitchShift.""" +//| ... +//| +static mp_obj_t audiodelays_granular_pitch_shift_deinit(mp_obj_t self_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_granular_pitch_shift_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_granular_pitch_shift_deinit_obj, audiodelays_granular_pitch_shift_deinit); + +static void check_for_deinit(audiodelays_granular_pitch_shift_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + + +//| def __enter__(self) -> GranularPitchShift: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +static mp_obj_t audiodelays_granular_pitch_shift_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audiodelays_granular_pitch_shift_deinit(args[0]); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiodelays_granular_pitch_shift___exit___obj, 4, 4, audiodelays_granular_pitch_shift_obj___exit__); + + +//| semitones: synthio.BlockInput +//| """The amount of pitch shifting in semitones (1/12th of an octave).""" +//| +static mp_obj_t audiodelays_granular_pitch_shift_obj_get_semitones(mp_obj_t self_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_audiodelays_granular_pitch_shift_get_semitones(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_granular_pitch_shift_get_semitones_obj, audiodelays_granular_pitch_shift_obj_get_semitones); + +static mp_obj_t audiodelays_granular_pitch_shift_obj_set_semitones(mp_obj_t self_in, mp_obj_t semitones_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_granular_pitch_shift_set_semitones(self, semitones_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_granular_pitch_shift_set_semitones_obj, audiodelays_granular_pitch_shift_obj_set_semitones); + +MP_PROPERTY_GETSET(audiodelays_granular_pitch_shift_semitones_obj, + (mp_obj_t)&audiodelays_granular_pitch_shift_get_semitones_obj, + (mp_obj_t)&audiodelays_granular_pitch_shift_set_semitones_obj); + + +//| mix: synthio.BlockInput +//| """The output mix between 0 and 1 where 0 is only sample and 1 is all effect.""" +static mp_obj_t audiodelays_granular_pitch_shift_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiodelays_granular_pitch_shift_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_granular_pitch_shift_get_mix_obj, audiodelays_granular_pitch_shift_obj_get_mix); + +static mp_obj_t audiodelays_granular_pitch_shift_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_granular_pitch_shift_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_granular_pitch_shift_set_mix_obj, audiodelays_granular_pitch_shift_obj_set_mix); + +MP_PROPERTY_GETSET(audiodelays_granular_pitch_shift_mix_obj, + (mp_obj_t)&audiodelays_granular_pitch_shift_get_mix_obj, + (mp_obj_t)&audiodelays_granular_pitch_shift_set_mix_obj); + + +//| spread: float +//| """The amount of random jitter applied to each grain's start position, from 0.0 +//| (deterministic) to 1.0 (maximum jitter). Higher values give a thicker granular texture.""" +static mp_obj_t audiodelays_granular_pitch_shift_obj_get_spread(mp_obj_t self_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_float(common_hal_audiodelays_granular_pitch_shift_get_spread(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_granular_pitch_shift_get_spread_obj, audiodelays_granular_pitch_shift_obj_get_spread); + +static mp_obj_t audiodelays_granular_pitch_shift_obj_set_spread(mp_obj_t self_in, mp_obj_t spread_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_granular_pitch_shift_set_spread(self, mp_obj_get_float(spread_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_granular_pitch_shift_set_spread_obj, audiodelays_granular_pitch_shift_obj_set_spread); + +MP_PROPERTY_GETSET(audiodelays_granular_pitch_shift_spread_obj, + (mp_obj_t)&audiodelays_granular_pitch_shift_get_spread_obj, + (mp_obj_t)&audiodelays_granular_pitch_shift_set_spread_obj); + + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiodelays_granular_pitch_shift_obj_get_playing(mp_obj_t self_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiodelays_granular_pitch_shift_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_granular_pitch_shift_get_playing_obj, audiodelays_granular_pitch_shift_obj_get_playing); + +MP_PROPERTY_GETTER(audiodelays_granular_pitch_shift_playing_obj, + (mp_obj_t)&audiodelays_granular_pitch_shift_get_playing_obj); + + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> GranularPitchShift: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: GranularPitchShift""" +//| ... +//| +static mp_obj_t audiodelays_granular_pitch_shift_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiodelays_granular_pitch_shift_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_granular_pitch_shift_play_obj, 1, audiodelays_granular_pitch_shift_obj_play); + + +//| def stop(self) -> None: +//| """Stops playback of the sample.""" +//| ... +//| +//| +static mp_obj_t audiodelays_granular_pitch_shift_obj_stop(mp_obj_t self_in) { + audiodelays_granular_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_granular_pitch_shift_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_granular_pitch_shift_stop_obj, audiodelays_granular_pitch_shift_obj_stop); + + +static const mp_rom_map_elem_t audiodelays_granular_pitch_shift_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiodelays_granular_pitch_shift_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiodelays_granular_pitch_shift___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiodelays_granular_pitch_shift_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiodelays_granular_pitch_shift_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_granular_pitch_shift_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_semitones), MP_ROM_PTR(&audiodelays_granular_pitch_shift_semitones_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_granular_pitch_shift_mix_obj) }, + { MP_ROM_QSTR(MP_QSTR_spread), MP_ROM_PTR(&audiodelays_granular_pitch_shift_spread_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiodelays_granular_pitch_shift_locals_dict, audiodelays_granular_pitch_shift_locals_dict_table); + +static const audiosample_p_t audiodelays_granular_pitch_shift_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiodelays_granular_pitch_shift_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiodelays_granular_pitch_shift_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiodelays_granular_pitch_shift_type, + MP_QSTR_GranularPitchShift, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiodelays_granular_pitch_shift_make_new, + locals_dict, &audiodelays_granular_pitch_shift_locals_dict, + protocol, &audiodelays_granular_pitch_shift_proto + ); diff --git a/shared-bindings/audiodelays/GranularPitchShift.h b/shared-bindings/audiodelays/GranularPitchShift.h new file mode 100644 index 00000000000..e5a518110bd --- /dev/null +++ b/shared-bindings/audiodelays/GranularPitchShift.h @@ -0,0 +1,31 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiodelays/GranularPitchShift.h" + +extern const mp_obj_type_t audiodelays_granular_pitch_shift_type; + +void common_hal_audiodelays_granular_pitch_shift_construct(audiodelays_granular_pitch_shift_obj_t *self, + mp_obj_t semitones, mp_obj_t mix, uint32_t grain_size, uint32_t density, + mp_float_t spread, uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiodelays_granular_pitch_shift_deinit(audiodelays_granular_pitch_shift_obj_t *self); + +mp_obj_t common_hal_audiodelays_granular_pitch_shift_get_semitones(audiodelays_granular_pitch_shift_obj_t *self); +void common_hal_audiodelays_granular_pitch_shift_set_semitones(audiodelays_granular_pitch_shift_obj_t *self, mp_obj_t semitones); + +mp_obj_t common_hal_audiodelays_granular_pitch_shift_get_mix(audiodelays_granular_pitch_shift_obj_t *self); +void common_hal_audiodelays_granular_pitch_shift_set_mix(audiodelays_granular_pitch_shift_obj_t *self, mp_obj_t arg); + +mp_float_t common_hal_audiodelays_granular_pitch_shift_get_spread(audiodelays_granular_pitch_shift_obj_t *self); +void common_hal_audiodelays_granular_pitch_shift_set_spread(audiodelays_granular_pitch_shift_obj_t *self, mp_float_t spread); + +bool common_hal_audiodelays_granular_pitch_shift_get_playing(audiodelays_granular_pitch_shift_obj_t *self); +void common_hal_audiodelays_granular_pitch_shift_play(audiodelays_granular_pitch_shift_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiodelays_granular_pitch_shift_stop(audiodelays_granular_pitch_shift_obj_t *self); diff --git a/shared-bindings/audiodelays/MultiTapDelay.c b/shared-bindings/audiodelays/MultiTapDelay.c new file mode 100644 index 00000000000..2126dbf9904 --- /dev/null +++ b/shared-bindings/audiodelays/MultiTapDelay.c @@ -0,0 +1,310 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiodelays/MultiTapDelay.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiodelays/MultiTapDelay.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class MultiTapDelay: +//| """A delay with multiple buffer positions to create a rhythmic effect.""" +//| +//| def __init__( +//| self, +//| max_delay_ms: int = 500, +//| delay_ms: synthio.BlockInput = 250.0, +//| decay: synthio.BlockInput = 0.7, +//| mix: synthio.BlockInput = 0.25, +//| taps: Optional[Tuple[float|Tuple[float, float], ...]] = None, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a delay effect where you hear the original sample play back at varying times, or "taps". +//| These tap positions and levels can be used to create rhythmic effects. +//| The timing of the delay can be changed at runtime with the delay_ms parameter but the delay can +//| never exceed the max_delay_ms parameter. The maximum delay you can set is limited by available +//| memory. +//| +//| Each time the delay plays back the volume is reduced by the decay setting (delay * decay). +//| +//| The mix parameter allows you to change how much of the unchanged sample passes through to +//| the output to how much of the effect audio you hear as the output. +//| +//| :param int max_delay_ms: The maximum time the delay can be in milliseconds. +//| :param float delay_ms: The current time of the delay in milliseconds. Must be less than max_delay_ms. +//| :param synthio.BlockInput decay: The rate the delay fades. 0.0 = instant; 1.0 = never. +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0). +//| :param tuple taps: The positions and levels to tap into the delay buffer. +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use. +//| :param int sample_rate: The sample rate to be used. +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect. +//| :param bool samples_signed: Effect is signed (True) or unsigned (False). +//| +//| Playing adding a multi-tap delay to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiodelays +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| effect = audiodelays.MultiTapDelay(max_delay_ms=500, delay_ms=500, decay=0.65, mix=0.5, taps=((2/3, 0.7), 1), buffer_size=1024, channel_count=1, sample_rate=44100) +//| effect.play(synth) +//| audio.play(effect) +//| +//| note = synthio.Note(261) +//| while True: +//| synth.press(note) +//| time.sleep(0.05) +//| synth.release(note) +//| time.sleep(5)""" +//| ... +//| +static mp_obj_t audiodelays_multi_tap_delay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_max_delay_ms, ARG_delay_ms, ARG_decay, ARG_mix, ARG_taps, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_max_delay_ms, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 500 } }, + { MP_QSTR_delay_ms, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(250) } }, + { MP_QSTR_decay, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_taps, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t max_delay_ms = mp_arg_validate_int_range(args[ARG_max_delay_ms].u_int, 1, 4000, MP_QSTR_max_delay_ms); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiodelays_multi_tap_delay_obj_t *self = mp_obj_malloc(audiodelays_multi_tap_delay_obj_t, &audiodelays_multi_tap_delay_type); + common_hal_audiodelays_multi_tap_delay_construct(self, max_delay_ms, args[ARG_delay_ms].u_obj, args[ARG_decay].u_obj, args[ARG_mix].u_obj, args[ARG_taps].u_obj, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the MultiTapDelay.""" +//| ... +//| +static mp_obj_t audiodelays_multi_tap_delay_deinit(mp_obj_t self_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_multi_tap_delay_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_deinit_obj, audiodelays_multi_tap_delay_deinit); + +static void check_for_deinit(audiodelays_multi_tap_delay_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> MultiTapDelay: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + + +//| delay_ms: float +//| """Time to delay the incoming signal in milliseconds. Must be less than max_delay_ms.""" +//| +static mp_obj_t audiodelays_multi_tap_delay_obj_get_delay_ms(mp_obj_t self_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_float(common_hal_audiodelays_multi_tap_delay_get_delay_ms(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_delay_ms_obj, audiodelays_multi_tap_delay_obj_get_delay_ms); + +static mp_obj_t audiodelays_multi_tap_delay_obj_set_delay_ms(mp_obj_t self_in, mp_obj_t delay_ms_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_multi_tap_delay_set_delay_ms(self, delay_ms_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_delay_ms_obj, audiodelays_multi_tap_delay_obj_set_delay_ms); + +MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_delay_ms_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_get_delay_ms_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_set_delay_ms_obj); + +//| decay: synthio.BlockInput +//| """The rate the echo fades between 0 and 1 where 0 is instant and 1 is never.""" +static mp_obj_t audiodelays_multi_tap_delay_obj_get_decay(mp_obj_t self_in) { + return common_hal_audiodelays_multi_tap_delay_get_decay(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_decay_obj, audiodelays_multi_tap_delay_obj_get_decay); + +static mp_obj_t audiodelays_multi_tap_delay_obj_set_decay(mp_obj_t self_in, mp_obj_t decay_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_multi_tap_delay_set_decay(self, decay_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_decay_obj, audiodelays_multi_tap_delay_obj_set_decay); + +MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_decay_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_get_decay_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_set_decay_obj); + +//| mix: synthio.BlockInput +//| """The mix of the effect between 0 and 1 where 0 is only sample, 0.5 is an equal mix of the sample and the effect and 1 is all effect.""" +static mp_obj_t audiodelays_multi_tap_delay_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiodelays_multi_tap_delay_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_mix_obj, audiodelays_multi_tap_delay_obj_get_mix); + +static mp_obj_t audiodelays_multi_tap_delay_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_multi_tap_delay_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_mix_obj, audiodelays_multi_tap_delay_obj_set_mix); + +MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_mix_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_get_mix_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_set_mix_obj); + +//| taps: Tuple[float|int|Tuple[float|int, float|int], ...] +//| """The position or position and level of delay taps. +//| The position is a number from 0 (start) to 1 (end) as a relative position in the delay buffer. +//| The level is a number from 0 (silence) to 1 (full volume). +//| If only a float or integer is provided as an element of the tuple, the level is assumed to be 1. +//| When retrieving the value of this property, the level will always be included.""" +//| +static mp_obj_t audiodelays_multi_tap_delay_obj_get_taps(mp_obj_t self_in) { + return common_hal_audiodelays_multi_tap_delay_get_taps(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_taps_obj, audiodelays_multi_tap_delay_obj_get_taps); + +static mp_obj_t audiodelays_multi_tap_delay_obj_set_taps(mp_obj_t self_in, mp_obj_t taps_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_multi_tap_delay_set_taps(self, taps_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_multi_tap_delay_set_taps_obj, audiodelays_multi_tap_delay_obj_set_taps); + +MP_PROPERTY_GETSET(audiodelays_multi_tap_delay_taps_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_get_taps_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_set_taps_obj); + + + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiodelays_multi_tap_delay_obj_get_playing(mp_obj_t self_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiodelays_multi_tap_delay_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_get_playing_obj, audiodelays_multi_tap_delay_obj_get_playing); + +MP_PROPERTY_GETTER(audiodelays_multi_tap_delay_playing_obj, + (mp_obj_t)&audiodelays_multi_tap_delay_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> MultiTapDelay: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: MultiTapDelay""" +//| ... +//| +static mp_obj_t audiodelays_multi_tap_delay_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiodelays_multi_tap_delay_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_multi_tap_delay_play_obj, 1, audiodelays_multi_tap_delay_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample. The echo continues playing.""" +//| ... +//| +//| +static mp_obj_t audiodelays_multi_tap_delay_obj_stop(mp_obj_t self_in) { + audiodelays_multi_tap_delay_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiodelays_multi_tap_delay_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_multi_tap_delay_stop_obj, audiodelays_multi_tap_delay_obj_stop); + +static const mp_rom_map_elem_t audiodelays_multi_tap_delay_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiodelays_multi_tap_delay_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiodelays_multi_tap_delay_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiodelays_multi_tap_delay_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_multi_tap_delay_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_delay_ms), MP_ROM_PTR(&audiodelays_multi_tap_delay_delay_ms_obj) }, + { MP_ROM_QSTR(MP_QSTR_decay), MP_ROM_PTR(&audiodelays_multi_tap_delay_decay_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_multi_tap_delay_mix_obj) }, + { MP_ROM_QSTR(MP_QSTR_taps), MP_ROM_PTR(&audiodelays_multi_tap_delay_taps_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiodelays_multi_tap_delay_locals_dict, audiodelays_multi_tap_delay_locals_dict_table); + +static const audiosample_p_t audiodelays_multi_tap_delay_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiodelays_multi_tap_delay_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiodelays_multi_tap_delay_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiodelays_multi_tap_delay_type, + MP_QSTR_MultiTapDelay, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiodelays_multi_tap_delay_make_new, + locals_dict, &audiodelays_multi_tap_delay_locals_dict, + protocol, &audiodelays_multi_tap_delay_proto + ); diff --git a/shared-bindings/audiodelays/MultiTapDelay.h b/shared-bindings/audiodelays/MultiTapDelay.h new file mode 100644 index 00000000000..6684c16b63f --- /dev/null +++ b/shared-bindings/audiodelays/MultiTapDelay.h @@ -0,0 +1,34 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiodelays/MultiTapDelay.h" + +extern const mp_obj_type_t audiodelays_multi_tap_delay_type; + +void common_hal_audiodelays_multi_tap_delay_construct(audiodelays_multi_tap_delay_obj_t *self, uint32_t max_delay_ms, + mp_obj_t delay_ms, mp_obj_t decay, mp_obj_t mix, mp_obj_t taps, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiodelays_multi_tap_delay_deinit(audiodelays_multi_tap_delay_obj_t *self); + +mp_float_t common_hal_audiodelays_multi_tap_delay_get_delay_ms(audiodelays_multi_tap_delay_obj_t *self); +void common_hal_audiodelays_multi_tap_delay_set_delay_ms(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t delay_ms); + +mp_obj_t common_hal_audiodelays_multi_tap_delay_get_decay(audiodelays_multi_tap_delay_obj_t *self); +void common_hal_audiodelays_multi_tap_delay_set_decay(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t decay); + +mp_obj_t common_hal_audiodelays_multi_tap_delay_get_mix(audiodelays_multi_tap_delay_obj_t *self); +void common_hal_audiodelays_multi_tap_delay_set_mix(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t mix); + +mp_obj_t common_hal_audiodelays_multi_tap_delay_get_taps(audiodelays_multi_tap_delay_obj_t *self); +void common_hal_audiodelays_multi_tap_delay_set_taps(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t taps); + +bool common_hal_audiodelays_multi_tap_delay_get_playing(audiodelays_multi_tap_delay_obj_t *self); +void common_hal_audiodelays_multi_tap_delay_play(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiodelays_multi_tap_delay_stop(audiodelays_multi_tap_delay_obj_t *self); diff --git a/shared-bindings/audiodelays/PitchShift.c b/shared-bindings/audiodelays/PitchShift.c new file mode 100644 index 00000000000..ee3bf5afdd7 --- /dev/null +++ b/shared-bindings/audiodelays/PitchShift.c @@ -0,0 +1,275 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiodelays/PitchShift.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiodelays/PitchShift.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class PitchShift: +//| """A pitch shift effect""" +//| +//| def __init__( +//| self, +//| semitones: synthio.BlockInput = 0.0, +//| mix: synthio.BlockInput = 1.0, +//| window: int = 1024, +//| overlap: int = 128, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a pitch shift effect where the original sample play back is altered to change the +//| the perceived pitch by a factor of semi-tones (1/12th of an octave). This effect will cause +//| a slight delay in the output depending on the size of the window and overlap buffers. +//| +//| The mix parameter allows you to change how much of the unchanged sample passes through to +//| the output to how much of the effect audio you hear as the output. +//| +//| :param synthio.BlockInput semitones: The amount of pitch shifting in semitones (1/12th of an octave) +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0) +//| :param int window: The total size in bytes of the window buffer used alter the playback pitch +//| :param int overlap: The total size in bytes of the overlap buffer used to prevent popping in the output. If set as 0, no overlap will be used. +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| +//| Shifting the pitch of a synth by 5 semitones:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiodelays +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP0, word_select=board.GP1, data=board.GP2) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| pitch_shift = audiodelays.PitchShift(semitones=5.0, mix=0.5, window=2048, overlap=256, buffer_size=1024, channel_count=1, sample_rate=44100) +//| pitch_shift.play(synth) +//| audio.play(pitch_shift) +//| +//| while True: +//| for notenum in (60, 64, 67, 71): +//| synth.press(notenum) +//| time.sleep(0.25) +//| synth.release_all()""" +//| ... +//| +static mp_obj_t audiodelays_pitch_shift_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_semitones, ARG_mix, ARG_window, ARG_overlap, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_semitones, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0)} }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1)} }, + { MP_QSTR_window, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1024} }, + { MP_QSTR_overlap, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 128} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiodelays_pitch_shift_obj_t *self = + mp_obj_malloc(audiodelays_pitch_shift_obj_t, &audiodelays_pitch_shift_type); + common_hal_audiodelays_pitch_shift_construct(self, + args[ARG_semitones].u_obj, + args[ARG_mix].u_obj, + args[ARG_window].u_int, + args[ARG_overlap].u_int, + args[ARG_buffer_size].u_int, + bits_per_sample, + args[ARG_samples_signed].u_bool, + channel_count, + sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + + +//| def deinit(self) -> None: +//| """Deinitialises the PitchShift.""" +//| ... +//| +static mp_obj_t audiodelays_pitch_shift_deinit(mp_obj_t self_in) { + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_pitch_shift_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_pitch_shift_deinit_obj, audiodelays_pitch_shift_deinit); + +static void check_for_deinit(audiodelays_pitch_shift_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + + +//| def __enter__(self) -> PitchShift: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +static mp_obj_t audiodelays_pitch_shift_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_audiodelays_pitch_shift_deinit(args[0]); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiodelays_pitch_shift___exit___obj, 4, 4, audiodelays_pitch_shift_obj___exit__); + + +//| semitones: synthio.BlockInput +//| """The amount of pitch shifting in semitones (1/12th of an octave).""" +//| +static mp_obj_t audiodelays_pitch_shift_obj_get_semitones(mp_obj_t self_in) { + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_audiodelays_pitch_shift_get_semitones(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_pitch_shift_get_semitones_obj, audiodelays_pitch_shift_obj_get_semitones); + +static mp_obj_t audiodelays_pitch_shift_obj_set_semitones(mp_obj_t self_in, mp_obj_t semitones_in) { + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_pitch_shift_set_semitones(self, semitones_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_pitch_shift_set_semitones_obj, audiodelays_pitch_shift_obj_set_semitones); + +MP_PROPERTY_GETSET(audiodelays_pitch_shift_semitones_obj, + (mp_obj_t)&audiodelays_pitch_shift_get_semitones_obj, + (mp_obj_t)&audiodelays_pitch_shift_set_semitones_obj); + + +//| mix: synthio.BlockInput +//| """The output mix between 0 and 1 where 0 is only sample and 1 is all effect.""" +static mp_obj_t audiodelays_pitch_shift_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiodelays_pitch_shift_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_pitch_shift_get_mix_obj, audiodelays_pitch_shift_obj_get_mix); + +static mp_obj_t audiodelays_pitch_shift_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_pitch_shift_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiodelays_pitch_shift_set_mix_obj, audiodelays_pitch_shift_obj_set_mix); + +MP_PROPERTY_GETSET(audiodelays_pitch_shift_mix_obj, + (mp_obj_t)&audiodelays_pitch_shift_get_mix_obj, + (mp_obj_t)&audiodelays_pitch_shift_set_mix_obj); + + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiodelays_pitch_shift_obj_get_playing(mp_obj_t self_in) { + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiodelays_pitch_shift_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_pitch_shift_get_playing_obj, audiodelays_pitch_shift_obj_get_playing); + +MP_PROPERTY_GETTER(audiodelays_pitch_shift_playing_obj, + (mp_obj_t)&audiodelays_pitch_shift_get_playing_obj); + + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> PitchShift: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: PitchShift""" +//| ... +//| +static mp_obj_t audiodelays_pitch_shift_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiodelays_pitch_shift_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiodelays_pitch_shift_play_obj, 1, audiodelays_pitch_shift_obj_play); + + +//| def stop(self) -> None: +//| """Stops playback of the sample.""" +//| ... +//| +//| +static mp_obj_t audiodelays_pitch_shift_obj_stop(mp_obj_t self_in) { + audiodelays_pitch_shift_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiodelays_pitch_shift_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiodelays_pitch_shift_stop_obj, audiodelays_pitch_shift_obj_stop); + + +static const mp_rom_map_elem_t audiodelays_pitch_shift_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiodelays_pitch_shift_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiodelays_pitch_shift___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiodelays_pitch_shift_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiodelays_pitch_shift_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiodelays_pitch_shift_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_semitones), MP_ROM_PTR(&audiodelays_pitch_shift_semitones_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiodelays_pitch_shift_mix_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiodelays_pitch_shift_locals_dict, audiodelays_pitch_shift_locals_dict_table); + +static const audiosample_p_t audiodelays_pitch_shift_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiodelays_pitch_shift_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiodelays_pitch_shift_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiodelays_pitch_shift_type, + MP_QSTR_PitchShift, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiodelays_pitch_shift_make_new, + locals_dict, &audiodelays_pitch_shift_locals_dict, + protocol, &audiodelays_pitch_shift_proto + ); diff --git a/shared-bindings/audiodelays/PitchShift.h b/shared-bindings/audiodelays/PitchShift.h new file mode 100644 index 00000000000..78c78b5ea82 --- /dev/null +++ b/shared-bindings/audiodelays/PitchShift.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiodelays/PitchShift.h" + +extern const mp_obj_type_t audiodelays_pitch_shift_type; + +void common_hal_audiodelays_pitch_shift_construct(audiodelays_pitch_shift_obj_t *self, + mp_obj_t semitones, mp_obj_t mix, uint32_t window, uint32_t overlap, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiodelays_pitch_shift_deinit(audiodelays_pitch_shift_obj_t *self); + +mp_obj_t common_hal_audiodelays_pitch_shift_get_semitones(audiodelays_pitch_shift_obj_t *self); +void common_hal_audiodelays_pitch_shift_set_semitones(audiodelays_pitch_shift_obj_t *self, mp_obj_t semitones); + +mp_obj_t common_hal_audiodelays_pitch_shift_get_mix(audiodelays_pitch_shift_obj_t *self); +void common_hal_audiodelays_pitch_shift_set_mix(audiodelays_pitch_shift_obj_t *self, mp_obj_t arg); + +bool common_hal_audiodelays_pitch_shift_get_playing(audiodelays_pitch_shift_obj_t *self); +void common_hal_audiodelays_pitch_shift_play(audiodelays_pitch_shift_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiodelays_pitch_shift_stop(audiodelays_pitch_shift_obj_t *self); diff --git a/shared-bindings/audiodelays/__init__.c b/shared-bindings/audiodelays/__init__.c new file mode 100644 index 00000000000..6ee7a82ab79 --- /dev/null +++ b/shared-bindings/audiodelays/__init__.c @@ -0,0 +1,43 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/audiodelays/__init__.h" +#include "shared-bindings/audiodelays/Echo.h" +#include "shared-bindings/audiodelays/Chorus.h" +#include "shared-bindings/audiodelays/Flanger.h" +#include "shared-bindings/audiodelays/PitchShift.h" +#include "shared-bindings/audiodelays/GranularPitchShift.h" +#include "shared-bindings/audiodelays/MultiTapDelay.h" + +//| """Support for audio delay effects +//| +//| The `audiodelays` module contains classes to provide access to audio delay effects. +//| +//| """ + +static const mp_rom_map_elem_t audiodelays_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiodelays) }, + { MP_ROM_QSTR(MP_QSTR_Echo), MP_ROM_PTR(&audiodelays_echo_type) }, + { MP_ROM_QSTR(MP_QSTR_Chorus), MP_ROM_PTR(&audiodelays_chorus_type) }, + { MP_ROM_QSTR(MP_QSTR_Flanger), MP_ROM_PTR(&audiodelays_flanger_type) }, + { MP_ROM_QSTR(MP_QSTR_PitchShift), MP_ROM_PTR(&audiodelays_pitch_shift_type) }, + { MP_ROM_QSTR(MP_QSTR_GranularPitchShift), MP_ROM_PTR(&audiodelays_granular_pitch_shift_type) }, + { MP_ROM_QSTR(MP_QSTR_MultiTapDelay), MP_ROM_PTR(&audiodelays_multi_tap_delay_type) }, +}; + +static MP_DEFINE_CONST_DICT(audiodelays_module_globals, audiodelays_module_globals_table); + +const mp_obj_module_t audiodelays_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&audiodelays_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_audiodelays, audiodelays_module); diff --git a/shared-bindings/audiodelays/__init__.h b/shared-bindings/audiodelays/__init__.h new file mode 100644 index 00000000000..3bc9246e5bb --- /dev/null +++ b/shared-bindings/audiodelays/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/audiofilewriter/AudioFileWriter.c b/shared-bindings/audiofilewriter/AudioFileWriter.c new file mode 100644 index 00000000000..8dbdba5d448 --- /dev/null +++ b/shared-bindings/audiofilewriter/AudioFileWriter.c @@ -0,0 +1,183 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared/runtime/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/audiofilewriter/AudioFileWriter.h" +#include "shared-bindings/util.h" + +// ~1 s of 16 kHz mono 16-bit PCM. Sized to absorb a worst-case SD-write stall. +#define AUDIOFILEWRITER_DEFAULT_BUFFER_SIZE (32 * 1024) + +//| class AudioFileWriter: +//| """Streams an audio source to a ``.wav`` file in the background. +//| +//| ``AudioFileWriter`` is the inverse of `audiocore.WaveFile`: rather than being +//| an audio *source* played by an `audioio.AudioOut`, it is a *sink* that +//| drives an audio source (a microphone, ``synthio``, or an ``audiofilters``/ +//| ``audiodelays``/``audiofreeverb``/``audiospeed`` effect chain) and writes +//| the resulting PCM to a file as a WAV. +//| +//| Recording runs on a background pump paced to the source's real-time rate, +//| so it does not block and does not require a Python read loop.""" +//| +//| def __init__(self, file: typing.BinaryIO, *, buffer_size: int = 32768) -> None: +//| """Create an ``AudioFileWriter`` that writes to ``file``. +//| +//| :param typing.BinaryIO file: An already-open writable binary stream +//| (a file opened in ``"wb"`` mode, or an `io.BytesIO`). The stream must +//| support seeking so the WAV header sizes can be patched when recording +//| stops. ``AudioFileWriter`` does not close it; the caller owns it. +//| :param int buffer_size: Size in bytes of the internal RAM ring that +//| decouples file-write latency from the source. Larger values tolerate +//| longer write stalls (e.g. a slow SD card) at the cost of RAM. +//| Minimum valid value, and default, is ``512``. Must be at least the +//| size of the source buffer. +//| +//| The audio format (sample rate, channel count, bit depth) is taken from +//| the source at `play()` time, so there are no format arguments here. +//| +//| Recording synthio to SD:: +//| +//| import time +//| import synthio +//| from audiofilewriter import AudioFileWriter +//| import storage +//| +//| SAMPLE_RATE = 16000 +//| OUTPUT_PATH = "/sd/demo_file.wav" +//| +//| C_major_scale = [60, 62, 64, 65, 67, 69, 71, 72, 71, 69, 67, 65, 64, 62, 60] +//| synth = synthio.Synthesizer(sample_rate=SAMPLE_RATE) +//| +//| with open(OUTPUT_PATH, "wb") as f: +//| writer = AudioFileWriter(f) +//| writer.play(synth) +//| for note in C_major_scale: +//| synth.press(note) +//| time.sleep(0.1) +//| synth.release(note) +//| time.sleep(0.10) +//| writer.stop() +//| print("Done ->", OUTPUT_PATH) +//| """ +//| ... +//| +static mp_obj_t audiofilewriter_audiofilewriter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_file, ARG_buffer_size }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = AUDIOFILEWRITER_DEFAULT_BUFFER_SIZE} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // A buffer smaller than one source buffer is useless; require a sane floor. + mp_int_t buffer_size = mp_arg_validate_int_min(args[ARG_buffer_size].u_int, 512, MP_QSTR_buffer_size); + + audiofilewriter_audiofilewriter_obj_t *self = mp_obj_malloc(audiofilewriter_audiofilewriter_obj_t, &audiofilewriter_audiofilewriter_type); + common_hal_audiofilewriter_audiofilewriter_construct(self, args[ARG_file].u_obj, (uint32_t)buffer_size); + + return MP_OBJ_FROM_PTR(self); +} + +static void check_for_deinit(audiofilewriter_audiofilewriter_obj_t *self) { + if (common_hal_audiofilewriter_audiofilewriter_deinited(self)) { + raise_deinited_error(); + } +} + +//| def deinit(self) -> None: +//| """Stops recording (patching the WAV header) and releases resources.""" +//| ... +//| +static mp_obj_t audiofilewriter_audiofilewriter_deinit(mp_obj_t self_in) { + audiofilewriter_audiofilewriter_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilewriter_audiofilewriter_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiofilewriter_audiofilewriter_deinit_obj, audiofilewriter_audiofilewriter_deinit); + +//| def __enter__(self) -> AudioFileWriter: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + +//| def play(self, sample: circuitpython_typing.AudioSample) -> None: +//| """Begin recording ``sample`` to the file. Does not block. +//| +//| Writes a WAV header (in the format of ``sample``) and starts the +//| background pump. ``sample`` must be an 8-bit or 16-bit mono or stereo +//| audio source. Use `playing` to tell when a finite source has finished, +//| or call `stop()` to end recording of a continuous source (e.g. a mic).""" +//| ... +//| +static mp_obj_t audiofilewriter_audiofilewriter_obj_play(mp_obj_t self_in, mp_obj_t sample_in) { + audiofilewriter_audiofilewriter_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_audiofilewriter_audiofilewriter_play(self, sample_in); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_2(audiofilewriter_audiofilewriter_play_obj, audiofilewriter_audiofilewriter_obj_play); + +//| def stop(self) -> None: +//| """Stop recording, flush the RAM ring to the file, and patch the WAV +//| header sizes. The file is left open for the caller to close.""" +//| ... +//| +static mp_obj_t audiofilewriter_audiofilewriter_obj_stop(mp_obj_t self_in) { + audiofilewriter_audiofilewriter_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_audiofilewriter_audiofilewriter_stop(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiofilewriter_audiofilewriter_stop_obj, audiofilewriter_audiofilewriter_obj_stop); + +//| playing: bool +//| """True while recording is in progress. Becomes False on its own when a +//| finite source finishes, or after `stop()`. (read-only)""" +//| +static mp_obj_t audiofilewriter_audiofilewriter_obj_get_playing(mp_obj_t self_in) { + audiofilewriter_audiofilewriter_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiofilewriter_audiofilewriter_get_playing(self)); +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiofilewriter_audiofilewriter_get_playing_obj, audiofilewriter_audiofilewriter_obj_get_playing); + +MP_PROPERTY_GETTER(audiofilewriter_audiofilewriter_playing_obj, + (mp_obj_t)&audiofilewriter_audiofilewriter_get_playing_obj); + +static const mp_rom_map_elem_t audiofilewriter_audiofilewriter_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiofilewriter_audiofilewriter_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiofilewriter_audiofilewriter_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiofilewriter_audiofilewriter_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiofilewriter_audiofilewriter_playing_obj) }, +}; +static MP_DEFINE_CONST_DICT(audiofilewriter_audiofilewriter_locals_dict, audiofilewriter_audiofilewriter_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + audiofilewriter_audiofilewriter_type, + MP_QSTR_AudioFileWriter, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiofilewriter_audiofilewriter_make_new, + locals_dict, &audiofilewriter_audiofilewriter_locals_dict + ); diff --git a/shared-bindings/audiofilewriter/AudioFileWriter.h b/shared-bindings/audiofilewriter/AudioFileWriter.h new file mode 100644 index 00000000000..22d456979b9 --- /dev/null +++ b/shared-bindings/audiofilewriter/AudioFileWriter.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiofilewriter/AudioFileWriter.h" + +extern const mp_obj_type_t audiofilewriter_audiofilewriter_type; + +void common_hal_audiofilewriter_audiofilewriter_construct(audiofilewriter_audiofilewriter_obj_t *self, + mp_obj_t file, uint32_t buffer_size); + +void common_hal_audiofilewriter_audiofilewriter_deinit(audiofilewriter_audiofilewriter_obj_t *self); +bool common_hal_audiofilewriter_audiofilewriter_deinited(audiofilewriter_audiofilewriter_obj_t *self); + +void common_hal_audiofilewriter_audiofilewriter_play(audiofilewriter_audiofilewriter_obj_t *self, mp_obj_t sample); +void common_hal_audiofilewriter_audiofilewriter_stop(audiofilewriter_audiofilewriter_obj_t *self); +bool common_hal_audiofilewriter_audiofilewriter_get_playing(audiofilewriter_audiofilewriter_obj_t *self); diff --git a/shared-bindings/audiofilewriter/__init__.c b/shared-bindings/audiofilewriter/__init__.c new file mode 100644 index 00000000000..e67a74b9451 --- /dev/null +++ b/shared-bindings/audiofilewriter/__init__.c @@ -0,0 +1,29 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/audiofilewriter/__init__.h" +#include "shared-bindings/audiofilewriter/AudioFileWriter.h" + +//| """Support for streaming audio to a WAV file""" + +static const mp_rom_map_elem_t audiofilewriter_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiofilewriter) }, + { MP_ROM_QSTR(MP_QSTR_AudioFileWriter), MP_ROM_PTR(&audiofilewriter_audiofilewriter_type) }, +}; + +static MP_DEFINE_CONST_DICT(audiofilewriter_module_globals, audiofilewriter_module_globals_table); + +const mp_obj_module_t audiofilewriter_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&audiofilewriter_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_audiofilewriter, audiofilewriter_module); diff --git a/shared-bindings/audiofilewriter/__init__.h b/shared-bindings/audiofilewriter/__init__.h new file mode 100644 index 00000000000..779b49ffd8d --- /dev/null +++ b/shared-bindings/audiofilewriter/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/audiofilters/Distortion.c b/shared-bindings/audiofilters/Distortion.c new file mode 100644 index 00000000000..bed28f5ed49 --- /dev/null +++ b/shared-bindings/audiofilters/Distortion.c @@ -0,0 +1,401 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiofilters/Distortion.h" +#include "shared-bindings/audiocore/__init__.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/enum.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class DistortionMode: +//| """The method of distortion used by the `audiofilters.Distortion` effect.""" +//| +//| CLIP: DistortionMode +//| """Digital distortion effect which cuts off peaks at the top and bottom of the waveform.""" +//| +//| LOFI: DistortionMode +//| """Low-resolution digital distortion effect (bit depth reduction). You can use it to emulate the sound of early digital audio devices.""" +//| +//| OVERDRIVE: DistortionMode +//| """Emulates the warm distortion produced by a field effect transistor, which is commonly used in solid-state musical instrument amplifiers. The `audiofilters.Distortion.drive` property has no effect in this mode.""" +//| +//| WAVESHAPE: DistortionMode +//| """Waveshaper distortions are used mainly by electronic musicians to achieve an extra-abrasive sound.""" +//| +//| + +MAKE_ENUM_VALUE(audiofilters_distortion_mode_type, distortion_mode, CLIP, DISTORTION_MODE_CLIP); +MAKE_ENUM_VALUE(audiofilters_distortion_mode_type, distortion_mode, LOFI, DISTORTION_MODE_LOFI); +MAKE_ENUM_VALUE(audiofilters_distortion_mode_type, distortion_mode, OVERDRIVE, DISTORTION_MODE_OVERDRIVE); +MAKE_ENUM_VALUE(audiofilters_distortion_mode_type, distortion_mode, WAVESHAPE, DISTORTION_MODE_WAVESHAPE); + +MAKE_ENUM_MAP(audiofilters_distortion_mode) { + MAKE_ENUM_MAP_ENTRY(distortion_mode, CLIP), + MAKE_ENUM_MAP_ENTRY(distortion_mode, LOFI), + MAKE_ENUM_MAP_ENTRY(distortion_mode, OVERDRIVE), + MAKE_ENUM_MAP_ENTRY(distortion_mode, WAVESHAPE), +}; + +static MP_DEFINE_CONST_DICT(audiofilters_distortion_mode_locals_dict, audiofilters_distortion_mode_locals_table); + +MAKE_PRINTER(audiofilters, audiofilters_distortion_mode); + +MAKE_ENUM_TYPE(audiofilters, DistortionMode, audiofilters_distortion_mode); + +static audiofilters_distortion_mode validate_distortion_mode(mp_obj_t obj, qstr arg_name) { + return cp_enum_value(&audiofilters_distortion_mode_type, obj, arg_name); +} + +//| class Distortion: +//| """A Distortion effect""" +//| +//| def __init__( +//| self, +//| drive: synthio.BlockInput = 0.0, +//| pre_gain: synthio.BlockInput = 0.0, +//| post_gain: synthio.BlockInput = 0.0, +//| mode: DistortionMode = DistortionMode.CLIP, +//| soft_clip: bool = False, +//| mix: synthio.BlockInput = 1.0, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a Distortion effect where the original sample is manipulated to create a distorted +//| sound according to the DistortionMode. +//| +//| The mix parameter allows you to change how much of the unchanged sample passes through to +//| the output to how much of the effect audio you hear as the output. +//| +//| :param synthio.BlockInput drive: Distortion power. Value can range from 0.0 to 1.0. +//| :param synthio.BlockInput pre_gain: Increases or decreases the volume before the effect, in decibels. Value can range from -60 to 60. +//| :param synthio.BlockInput post_gain: Increases or decreases the volume after the effect, in decibels. Value can range from -80 to 24. +//| :param DistortionMode mode: Distortion type. +//| :param bool soft_clip: Whether or not to soft clip (True) or hard clip (False) the output. +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0). +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| +//| Playing adding a distortion to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiofilters +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| effect = audiofilters.Distortion(drive=0.5, mix=1.0, buffer_size=1024, channel_count=1, sample_rate=44100) +//| effect.play(synth) +//| audio.play(effect) +//| +//| note = synthio.Note(261) +//| while True: +//| synth.press(note) +//| time.sleep(0.25) +//| synth.release(note) +//| time.sleep(5)""" +//| ... +//| + +static mp_obj_t audiofilters_distortion_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_drive, ARG_pre_gain, ARG_post_gain, ARG_mode, ARG_soft_clip, ARG_mix, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_drive, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0)} }, + { MP_QSTR_pre_gain, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0)} }, + { MP_QSTR_post_gain, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0)} }, + { MP_QSTR_mode, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_soft_clip, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1)} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiofilters_distortion_mode mode = DISTORTION_MODE_CLIP; + if (args[ARG_mode].u_obj != MP_OBJ_NULL) { + mode = validate_distortion_mode(args[ARG_mode].u_obj, MP_QSTR_mode); + } + + audiofilters_distortion_obj_t *self = + mp_obj_malloc(audiofilters_distortion_obj_t, &audiofilters_distortion_type); + common_hal_audiofilters_distortion_construct(self, + args[ARG_drive].u_obj, + args[ARG_pre_gain].u_obj, + args[ARG_post_gain].u_obj, + mode, + args[ARG_soft_clip].u_obj, + args[ARG_mix].u_obj, + args[ARG_buffer_size].u_int, + bits_per_sample, + args[ARG_samples_signed].u_bool, + channel_count, + sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Distortion.""" +//| ... +//| +static mp_obj_t audiofilters_distortion_deinit(mp_obj_t self_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_distortion_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_deinit_obj, audiofilters_distortion_deinit); + +static void check_for_deinit(audiofilters_distortion_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> Distortion: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + + +//| drive: synthio.BlockInput +//| """Distortion power. Value can range from 0.0 to 1.0.""" +static mp_obj_t audiofilters_distortion_obj_get_drive(mp_obj_t self_in) { + return common_hal_audiofilters_distortion_get_drive(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_drive_obj, audiofilters_distortion_obj_get_drive); + +static mp_obj_t audiofilters_distortion_obj_set_drive(mp_obj_t self_in, mp_obj_t drive_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_distortion_set_drive(self, drive_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_distortion_set_drive_obj, audiofilters_distortion_obj_set_drive); + +MP_PROPERTY_GETSET(audiofilters_distortion_drive_obj, + (mp_obj_t)&audiofilters_distortion_get_drive_obj, + (mp_obj_t)&audiofilters_distortion_set_drive_obj); + + +//| pre_gain: synthio.BlockInput +//| """Increases or decreases the volume before the effect, in decibels. Value can range from -60 to 60.""" +static mp_obj_t audiofilters_distortion_obj_get_pre_gain(mp_obj_t self_in) { + return common_hal_audiofilters_distortion_get_pre_gain(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_pre_gain_obj, audiofilters_distortion_obj_get_pre_gain); + +static mp_obj_t audiofilters_distortion_obj_set_pre_gain(mp_obj_t self_in, mp_obj_t pre_gain_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_distortion_set_pre_gain(self, pre_gain_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_distortion_set_pre_gain_obj, audiofilters_distortion_obj_set_pre_gain); + +MP_PROPERTY_GETSET(audiofilters_distortion_pre_gain_obj, + (mp_obj_t)&audiofilters_distortion_get_pre_gain_obj, + (mp_obj_t)&audiofilters_distortion_set_pre_gain_obj); + + +//| post_gain: synthio.BlockInput +//| """Increases or decreases the volume after the effect, in decibels. Value can range from -80 to 24.""" +static mp_obj_t audiofilters_distortion_obj_get_post_gain(mp_obj_t self_in) { + return common_hal_audiofilters_distortion_get_post_gain(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_post_gain_obj, audiofilters_distortion_obj_get_post_gain); + +static mp_obj_t audiofilters_distortion_obj_set_post_gain(mp_obj_t self_in, mp_obj_t post_gain_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_distortion_set_post_gain(self, post_gain_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_distortion_set_post_gain_obj, audiofilters_distortion_obj_set_post_gain); + +MP_PROPERTY_GETSET(audiofilters_distortion_post_gain_obj, + (mp_obj_t)&audiofilters_distortion_get_post_gain_obj, + (mp_obj_t)&audiofilters_distortion_set_post_gain_obj); + + +//| mode: DistortionMode +//| """Distortion type.""" +static mp_obj_t audiofilters_distortion_obj_get_mode(mp_obj_t self_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return cp_enum_find(&audiofilters_distortion_mode_type, common_hal_audiofilters_distortion_get_mode(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_mode_obj, audiofilters_distortion_obj_get_mode); + +static mp_obj_t audiofilters_distortion_obj_set_mode(mp_obj_t self_in, mp_obj_t mode_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + audiofilters_distortion_mode mode = validate_distortion_mode(mode_in, MP_QSTR_mode); + common_hal_audiofilters_distortion_set_mode(self, mode); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_distortion_set_mode_obj, audiofilters_distortion_obj_set_mode); + +MP_PROPERTY_GETSET(audiofilters_distortion_mode_obj, + (mp_obj_t)&audiofilters_distortion_get_mode_obj, + (mp_obj_t)&audiofilters_distortion_set_mode_obj); + + +//| soft_clip: bool +//| """Whether or not to soft clip (True) or hard clip (False) the output.""" +static mp_obj_t audiofilters_distortion_obj_get_soft_clip(mp_obj_t self_in) { + return mp_obj_new_bool(common_hal_audiofilters_distortion_get_soft_clip(self_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_soft_clip_obj, audiofilters_distortion_obj_get_soft_clip); + +static mp_obj_t audiofilters_distortion_obj_set_soft_clip(mp_obj_t self_in, mp_obj_t soft_clip_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_distortion_set_soft_clip(self, mp_obj_is_true(soft_clip_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_distortion_set_soft_clip_obj, audiofilters_distortion_obj_set_soft_clip); + +MP_PROPERTY_GETSET(audiofilters_distortion_soft_clip_obj, + (mp_obj_t)&audiofilters_distortion_get_soft_clip_obj, + (mp_obj_t)&audiofilters_distortion_set_soft_clip_obj); + + +//| mix: synthio.BlockInput +//| """The rate the filtered signal mix between 0 and 1 where 0 is only sample and 1 is all effect.""" +static mp_obj_t audiofilters_distortion_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiofilters_distortion_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_mix_obj, audiofilters_distortion_obj_get_mix); + +static mp_obj_t audiofilters_distortion_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_distortion_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_distortion_set_mix_obj, audiofilters_distortion_obj_set_mix); + +MP_PROPERTY_GETSET(audiofilters_distortion_mix_obj, + (mp_obj_t)&audiofilters_distortion_get_mix_obj, + (mp_obj_t)&audiofilters_distortion_set_mix_obj); + + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiofilters_distortion_obj_get_playing(mp_obj_t self_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiofilters_distortion_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_get_playing_obj, audiofilters_distortion_obj_get_playing); + +MP_PROPERTY_GETTER(audiofilters_distortion_playing_obj, + (mp_obj_t)&audiofilters_distortion_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Distortion: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Distortion""" +//| ... +//| +static mp_obj_t audiofilters_distortion_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiofilters_distortion_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_distortion_play_obj, 1, audiofilters_distortion_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample.""" +//| ... +//| +//| +static mp_obj_t audiofilters_distortion_obj_stop(mp_obj_t self_in) { + audiofilters_distortion_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiofilters_distortion_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_distortion_stop_obj, audiofilters_distortion_obj_stop); + +static const mp_rom_map_elem_t audiofilters_distortion_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiofilters_distortion_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiofilters_distortion_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiofilters_distortion_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiofilters_distortion_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_drive), MP_ROM_PTR(&audiofilters_distortion_drive_obj) }, + { MP_ROM_QSTR(MP_QSTR_pre_gain), MP_ROM_PTR(&audiofilters_distortion_pre_gain_obj) }, + { MP_ROM_QSTR(MP_QSTR_post_gain), MP_ROM_PTR(&audiofilters_distortion_post_gain_obj) }, + { MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&audiofilters_distortion_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_soft_clip), MP_ROM_PTR(&audiofilters_distortion_soft_clip_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiofilters_distortion_mix_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiofilters_distortion_locals_dict, audiofilters_distortion_locals_dict_table); + +static const audiosample_p_t audiofilters_distortion_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiofilters_distortion_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiofilters_distortion_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiofilters_distortion_type, + MP_QSTR_Distortion, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiofilters_distortion_make_new, + locals_dict, &audiofilters_distortion_locals_dict, + protocol, &audiofilters_distortion_proto + ); diff --git a/shared-bindings/audiofilters/Distortion.h b/shared-bindings/audiofilters/Distortion.h new file mode 100644 index 00000000000..ded32eada30 --- /dev/null +++ b/shared-bindings/audiofilters/Distortion.h @@ -0,0 +1,42 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiofilters/Distortion.h" + +extern const mp_obj_type_t audiofilters_distortion_type; +extern const mp_obj_type_t audiofilters_distortion_mode_type; + +void common_hal_audiofilters_distortion_construct(audiofilters_distortion_obj_t *self, + mp_obj_t drive, mp_obj_t pre_gain, mp_obj_t post_gain, + audiofilters_distortion_mode mode, bool soft_clip, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiofilters_distortion_deinit(audiofilters_distortion_obj_t *self); + +mp_obj_t common_hal_audiofilters_distortion_get_drive(audiofilters_distortion_obj_t *self); +void common_hal_audiofilters_distortion_set_drive(audiofilters_distortion_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiofilters_distortion_get_pre_gain(audiofilters_distortion_obj_t *self); +void common_hal_audiofilters_distortion_set_pre_gain(audiofilters_distortion_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiofilters_distortion_get_post_gain(audiofilters_distortion_obj_t *self); +void common_hal_audiofilters_distortion_set_post_gain(audiofilters_distortion_obj_t *self, mp_obj_t arg); + +audiofilters_distortion_mode common_hal_audiofilters_distortion_get_mode(audiofilters_distortion_obj_t *self); +void common_hal_audiofilters_distortion_set_mode(audiofilters_distortion_obj_t *self, audiofilters_distortion_mode mode); + +bool common_hal_audiofilters_distortion_get_soft_clip(audiofilters_distortion_obj_t *self); +void common_hal_audiofilters_distortion_set_soft_clip(audiofilters_distortion_obj_t *self, bool soft_clip); + +mp_obj_t common_hal_audiofilters_distortion_get_mix(audiofilters_distortion_obj_t *self); +void common_hal_audiofilters_distortion_set_mix(audiofilters_distortion_obj_t *self, mp_obj_t arg); + +bool common_hal_audiofilters_distortion_get_playing(audiofilters_distortion_obj_t *self); +void common_hal_audiofilters_distortion_play(audiofilters_distortion_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiofilters_distortion_stop(audiofilters_distortion_obj_t *self); diff --git a/shared-bindings/audiofilters/Filter.c b/shared-bindings/audiofilters/Filter.c new file mode 100644 index 00000000000..2d0d12b226a --- /dev/null +++ b/shared-bindings/audiofilters/Filter.c @@ -0,0 +1,261 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiofilters/Filter.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiofilters/Filter.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class Filter: +//| """A Filter effect""" +//| +//| def __init__( +//| self, +//| filter: Optional[synthio.Biquad | Tuple[synthio.Biquad]] = None, +//| mix: synthio.BlockInput = 1.0, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a Filter effect where the original sample is processed through a biquad filter +//| created by a synthio.Synthesizer object. This can be used to generate a low-pass, +//| high-pass, or band-pass filter. +//| +//| The mix parameter allows you to change how much of the unchanged sample passes through to +//| the output to how much of the effect audio you hear as the output. +//| +//| :param Optional[synthio.Biquad|Tuple[synthio.Biquad]] filter: A normalized biquad filter object or tuple of normalized biquad filter objects. The sample is processed sequentially by each filter to produce the output samples. +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0). +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| +//| Playing adding a filter to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiofilters +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| effect = audiofilters.Filter(buffer_size=1024, channel_count=1, sample_rate=44100, mix=1.0) +//| effect.filter = synth.low_pass_filter(frequency=2000, Q=1.25) +//| effect.play(synth) +//| audio.play(effect) +//| +//| note = synthio.Note(261) +//| while True: +//| synth.press(note) +//| time.sleep(0.25) +//| synth.release(note) +//| time.sleep(5)""" +//| ... +//| +static mp_obj_t audiofilters_filter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_filter, ARG_mix, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_filter, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1)} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiofilters_filter_obj_t *self = mp_obj_malloc(audiofilters_filter_obj_t, &audiofilters_filter_type); + common_hal_audiofilters_filter_construct(self, + args[ARG_filter].u_obj, + args[ARG_mix].u_obj, + args[ARG_buffer_size].u_int, + bits_per_sample, + args[ARG_samples_signed].u_bool, + channel_count, + sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Filter.""" +//| ... +//| +static mp_obj_t audiofilters_filter_deinit(mp_obj_t self_in) { + audiofilters_filter_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_filter_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_filter_deinit_obj, audiofilters_filter_deinit); + +static void check_for_deinit(audiofilters_filter_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> Filter: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + + +//| filter: synthio.Biquad | Tuple[synthio.Biquad] | None +//| """A normalized biquad filter object or tuple of normalized biquad filter objects. The sample is processed sequentially by each filter to produce the output samples.""" +//| +static mp_obj_t audiofilters_filter_obj_get_filter(mp_obj_t self_in) { + audiofilters_filter_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_audiofilters_filter_get_filter(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_filter_get_filter_obj, audiofilters_filter_obj_get_filter); + +static mp_obj_t audiofilters_filter_obj_set_filter(mp_obj_t self_in, mp_obj_t filter_in) { + audiofilters_filter_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_filter_set_filter(self, filter_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_filter_set_filter_obj, audiofilters_filter_obj_set_filter); + +MP_PROPERTY_GETSET(audiofilters_filter_filter_obj, + (mp_obj_t)&audiofilters_filter_get_filter_obj, + (mp_obj_t)&audiofilters_filter_set_filter_obj); + + +//| mix: synthio.BlockInput +//| """The rate the filtered signal mix between 0 and 1 where 0 is only sample and 1 is all effect.""" +static mp_obj_t audiofilters_filter_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiofilters_filter_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_filter_get_mix_obj, audiofilters_filter_obj_get_mix); + +static mp_obj_t audiofilters_filter_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiofilters_filter_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_filter_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_filter_set_mix_obj, audiofilters_filter_obj_set_mix); + +MP_PROPERTY_GETSET(audiofilters_filter_mix_obj, + (mp_obj_t)&audiofilters_filter_get_mix_obj, + (mp_obj_t)&audiofilters_filter_set_mix_obj); + + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiofilters_filter_obj_get_playing(mp_obj_t self_in) { + audiofilters_filter_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiofilters_filter_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_filter_get_playing_obj, audiofilters_filter_obj_get_playing); + +MP_PROPERTY_GETTER(audiofilters_filter_playing_obj, + (mp_obj_t)&audiofilters_filter_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Filter: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Filter""" +//| ... +//| +static mp_obj_t audiofilters_filter_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiofilters_filter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiofilters_filter_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_filter_play_obj, 1, audiofilters_filter_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample.""" +//| ... +//| +//| +static mp_obj_t audiofilters_filter_obj_stop(mp_obj_t self_in) { + audiofilters_filter_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiofilters_filter_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_filter_stop_obj, audiofilters_filter_obj_stop); + +static const mp_rom_map_elem_t audiofilters_filter_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiofilters_filter_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiofilters_filter_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiofilters_filter_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiofilters_filter_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_filter), MP_ROM_PTR(&audiofilters_filter_filter_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiofilters_filter_mix_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiofilters_filter_locals_dict, audiofilters_filter_locals_dict_table); + +static const audiosample_p_t audiofilters_filter_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiofilters_filter_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiofilters_filter_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiofilters_filter_type, + MP_QSTR_Filter, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiofilters_filter_make_new, + locals_dict, &audiofilters_filter_locals_dict, + protocol, &audiofilters_filter_proto + ); diff --git a/shared-bindings/audiofilters/Filter.h b/shared-bindings/audiofilters/Filter.h new file mode 100644 index 00000000000..e8dac00ba9f --- /dev/null +++ b/shared-bindings/audiofilters/Filter.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiofilters/Filter.h" + +extern const mp_obj_type_t audiofilters_filter_type; + +void common_hal_audiofilters_filter_construct(audiofilters_filter_obj_t *self, + mp_obj_t filter, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiofilters_filter_deinit(audiofilters_filter_obj_t *self); + +mp_obj_t common_hal_audiofilters_filter_get_filter(audiofilters_filter_obj_t *self); +void common_hal_audiofilters_filter_set_filter(audiofilters_filter_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiofilters_filter_get_mix(audiofilters_filter_obj_t *self); +void common_hal_audiofilters_filter_set_mix(audiofilters_filter_obj_t *self, mp_obj_t arg); + +bool common_hal_audiofilters_filter_get_playing(audiofilters_filter_obj_t *self); +void common_hal_audiofilters_filter_play(audiofilters_filter_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiofilters_filter_stop(audiofilters_filter_obj_t *self); diff --git a/shared-bindings/audiofilters/Phaser.c b/shared-bindings/audiofilters/Phaser.c new file mode 100644 index 00000000000..2aed9623b72 --- /dev/null +++ b/shared-bindings/audiofilters/Phaser.c @@ -0,0 +1,300 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiofilters/Phaser.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiofilters/Phaser.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class Phaser: +//| """A Phaser effect""" +//| +//| def __init__( +//| self, +//| frequency: synthio.BlockInput = 1000.0, +//| feedback: synthio.BlockInput = 0.7, +//| mix: synthio.BlockInput = 1.0, +//| stages: int = 6, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a Phaser effect where the original sample is processed through a variable +//| number of all-pass filter stages. This slightly delays the signal so that it is out +//| of phase with the original signal. When the amount of phase is modulated and mixed +//| back into the original signal with the mix parameter, it creates a distinctive +//| phasing sound. +//| +//| :param synthio.BlockInput frequency: The target frequency which is affected by the effect in hz. +//| :param int stages: The number of all-pass filters which will be applied to the signal. +//| :param synthio.BlockInput feedback: The amount that the previous output of the filters is mixed back into their input along with the unprocessed signal. +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0). +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect +//| :param bool samples_signed: Effect is signed (True) or unsigned (False) +//| +//| Playing adding a phaser to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import audiofilters +//| import synthio +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| effect = audiofilters.Phaser(channel_count=1, sample_rate=44100) +//| effect.frequency = synthio.LFO(offset=1000.0, scale=600.0, rate=0.5) +//| effect.play(synth) +//| audio.play(effect) +//| +//| synth.press(48)""" +//| ... +//| +static mp_obj_t audiofilters_phaser_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_frequency, ARG_feedback, ARG_mix, ARG_stages, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_frequency, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1000) } }, + { MP_QSTR_feedback, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1)} }, + { MP_QSTR_stages, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 6 } }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 8 && bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 8 or 16")); + } + + audiofilters_phaser_obj_t *self = mp_obj_malloc(audiofilters_phaser_obj_t, &audiofilters_phaser_type); + common_hal_audiofilters_phaser_construct(self, + args[ARG_frequency].u_obj, + args[ARG_feedback].u_obj, + args[ARG_mix].u_obj, + args[ARG_stages].u_int, + args[ARG_buffer_size].u_int, + bits_per_sample, + args[ARG_samples_signed].u_bool, + channel_count, + sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Phaser.""" +//| ... +//| +static mp_obj_t audiofilters_phaser_deinit(mp_obj_t self_in) { + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_phaser_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_deinit_obj, audiofilters_phaser_deinit); + +static void check_for_deinit(audiofilters_phaser_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> Phaser: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + + +//| frequency: synthio.BlockInput +//| """The target frequency in hertz at which the phaser is delaying the signal.""" +static mp_obj_t audiofilters_phaser_obj_get_frequency(mp_obj_t self_in) { + return common_hal_audiofilters_phaser_get_frequency(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_get_frequency_obj, audiofilters_phaser_obj_get_frequency); + +static mp_obj_t audiofilters_phaser_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency_in) { + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_phaser_set_frequency(self, frequency_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_phaser_set_frequency_obj, audiofilters_phaser_obj_set_frequency); + +MP_PROPERTY_GETSET(audiofilters_phaser_frequency_obj, + (mp_obj_t)&audiofilters_phaser_get_frequency_obj, + (mp_obj_t)&audiofilters_phaser_set_frequency_obj); + + +//| feedback: synthio.BlockInput +//| """The amount of which the incoming signal is fed back into the phasing filters from 0.1 to 0.9.""" +static mp_obj_t audiofilters_phaser_obj_get_feedback(mp_obj_t self_in) { + return common_hal_audiofilters_phaser_get_feedback(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_get_feedback_obj, audiofilters_phaser_obj_get_feedback); + +static mp_obj_t audiofilters_phaser_obj_set_feedback(mp_obj_t self_in, mp_obj_t feedback_in) { + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_phaser_set_feedback(self, feedback_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_phaser_set_feedback_obj, audiofilters_phaser_obj_set_feedback); + +MP_PROPERTY_GETSET(audiofilters_phaser_feedback_obj, + (mp_obj_t)&audiofilters_phaser_get_feedback_obj, + (mp_obj_t)&audiofilters_phaser_set_feedback_obj); + + +//| mix: synthio.BlockInput +//| """The amount that the effect signal is mixed into the output between 0 and 1 where 0 is only the original sample and 1 is all effect.""" +static mp_obj_t audiofilters_phaser_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiofilters_phaser_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_get_mix_obj, audiofilters_phaser_obj_get_mix); + +static mp_obj_t audiofilters_phaser_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_phaser_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_phaser_set_mix_obj, audiofilters_phaser_obj_set_mix); + +MP_PROPERTY_GETSET(audiofilters_phaser_mix_obj, + (mp_obj_t)&audiofilters_phaser_get_mix_obj, + (mp_obj_t)&audiofilters_phaser_set_mix_obj); + + +//| stages: int +//| """The number of allpass filters to pass the signal through. More stages requires more processing but produces a more pronounced effect. Requires a minimum value of 1.""" +static mp_obj_t audiofilters_phaser_obj_get_stages(mp_obj_t self_in) { + return MP_OBJ_NEW_SMALL_INT(common_hal_audiofilters_phaser_get_stages(self_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_get_stages_obj, audiofilters_phaser_obj_get_stages); + +static mp_obj_t audiofilters_phaser_obj_set_stages(mp_obj_t self_in, mp_obj_t stages_in) { + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofilters_phaser_set_stages(self, mp_obj_get_int(stages_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofilters_phaser_set_stages_obj, audiofilters_phaser_obj_set_stages); + +MP_PROPERTY_GETSET(audiofilters_phaser_stages_obj, + (mp_obj_t)&audiofilters_phaser_get_stages_obj, + (mp_obj_t)&audiofilters_phaser_set_stages_obj); + + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiofilters_phaser_obj_get_playing(mp_obj_t self_in) { + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiofilters_phaser_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_get_playing_obj, audiofilters_phaser_obj_get_playing); + +MP_PROPERTY_GETTER(audiofilters_phaser_playing_obj, + (mp_obj_t)&audiofilters_phaser_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Phaser: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Phaser""" +//| ... +//| +static mp_obj_t audiofilters_phaser_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiofilters_phaser_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiofilters_phaser_play_obj, 1, audiofilters_phaser_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample.""" +//| ... +//| +//| +static mp_obj_t audiofilters_phaser_obj_stop(mp_obj_t self_in) { + audiofilters_phaser_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiofilters_phaser_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofilters_phaser_stop_obj, audiofilters_phaser_obj_stop); + +static const mp_rom_map_elem_t audiofilters_phaser_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiofilters_phaser_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiofilters_phaser_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiofilters_phaser_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiofilters_phaser_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&audiofilters_phaser_frequency_obj) }, + { MP_ROM_QSTR(MP_QSTR_feedback), MP_ROM_PTR(&audiofilters_phaser_feedback_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiofilters_phaser_mix_obj) }, + { MP_ROM_QSTR(MP_QSTR_stages), MP_ROM_PTR(&audiofilters_phaser_stages_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiofilters_phaser_locals_dict, audiofilters_phaser_locals_dict_table); + +static const audiosample_p_t audiofilters_phaser_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiofilters_phaser_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiofilters_phaser_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiofilters_phaser_type, + MP_QSTR_Phaser, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiofilters_phaser_make_new, + locals_dict, &audiofilters_phaser_locals_dict, + protocol, &audiofilters_phaser_proto + ); diff --git a/shared-bindings/audiofilters/Phaser.h b/shared-bindings/audiofilters/Phaser.h new file mode 100644 index 00000000000..dbab22f5710 --- /dev/null +++ b/shared-bindings/audiofilters/Phaser.h @@ -0,0 +1,34 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiofilters/Phaser.h" + +extern const mp_obj_type_t audiofilters_phaser_type; + +void common_hal_audiofilters_phaser_construct(audiofilters_phaser_obj_t *self, + mp_obj_t frequency, mp_obj_t feedback, mp_obj_t mix, uint8_t stages, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiofilters_phaser_deinit(audiofilters_phaser_obj_t *self); + +mp_obj_t common_hal_audiofilters_phaser_get_frequency(audiofilters_phaser_obj_t *self); +void common_hal_audiofilters_phaser_set_frequency(audiofilters_phaser_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiofilters_phaser_get_feedback(audiofilters_phaser_obj_t *self); +void common_hal_audiofilters_phaser_set_feedback(audiofilters_phaser_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiofilters_phaser_get_mix(audiofilters_phaser_obj_t *self); +void common_hal_audiofilters_phaser_set_mix(audiofilters_phaser_obj_t *self, mp_obj_t arg); + +uint8_t common_hal_audiofilters_phaser_get_stages(audiofilters_phaser_obj_t *self); +void common_hal_audiofilters_phaser_set_stages(audiofilters_phaser_obj_t *self, uint8_t arg); + +bool common_hal_audiofilters_phaser_get_playing(audiofilters_phaser_obj_t *self); +void common_hal_audiofilters_phaser_play(audiofilters_phaser_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiofilters_phaser_stop(audiofilters_phaser_obj_t *self); diff --git a/shared-bindings/audiofilters/__init__.c b/shared-bindings/audiofilters/__init__.c new file mode 100644 index 00000000000..ae43af9bfef --- /dev/null +++ b/shared-bindings/audiofilters/__init__.c @@ -0,0 +1,40 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/audiofilters/__init__.h" +#include "shared-bindings/audiofilters/Distortion.h" +#include "shared-bindings/audiofilters/Filter.h" +#include "shared-bindings/audiofilters/Phaser.h" + +//| """Support for audio filter effects +//| +//| The `audiofilters` module contains classes to provide access to audio filter effects. +//| +//| """ + +static const mp_rom_map_elem_t audiofilters_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiofilters) }, + { MP_ROM_QSTR(MP_QSTR_Filter), MP_ROM_PTR(&audiofilters_filter_type) }, + { MP_ROM_QSTR(MP_QSTR_Distortion), MP_ROM_PTR(&audiofilters_distortion_type) }, + { MP_ROM_QSTR(MP_QSTR_Phaser), MP_ROM_PTR(&audiofilters_phaser_type) }, + + // Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_DistortionMode), MP_ROM_PTR(&audiofilters_distortion_mode_type) }, +}; + +static MP_DEFINE_CONST_DICT(audiofilters_module_globals, audiofilters_module_globals_table); + +const mp_obj_module_t audiofilters_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&audiofilters_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_audiofilters, audiofilters_module); diff --git a/shared-bindings/audiofilters/__init__.h b/shared-bindings/audiofilters/__init__.h new file mode 100644 index 00000000000..29d2f672655 --- /dev/null +++ b/shared-bindings/audiofilters/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/audiofreeverb/Freeverb.c b/shared-bindings/audiofreeverb/Freeverb.c new file mode 100644 index 00000000000..83c9eb7c01f --- /dev/null +++ b/shared-bindings/audiofreeverb/Freeverb.c @@ -0,0 +1,325 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/audiofreeverb/Freeverb.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiofreeverb/Freeverb.h" + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-module/synthio/block.h" + +//| class Freeverb: +//| """An Freeverb effect""" +//| +//| def __init__( +//| self, +//| roomsize: synthio.BlockInput = 0.5, +//| damp: synthio.BlockInput = 0.5, +//| pre_filter: Optional[synthio.Biquad | Tuple[synthio.Biquad]] = None, +//| post_filter: Optional[synthio.Biquad | Tuple[synthio.Biquad]] = None, +//| mix: synthio.BlockInput = 0.5, +//| buffer_size: int = 512, +//| sample_rate: int = 8000, +//| bits_per_sample: int = 16, +//| samples_signed: bool = True, +//| channel_count: int = 1, +//| ) -> None: +//| """Create a Reverb effect simulating the audio taking place in a large room where you get echos +//| off of various surfaces at various times. The size of the room can be adjusted as well as how +//| much the higher frequencies get absorbed by the walls. +//| +//| The mix parameter allows you to change how much of the unchanged sample passes through to +//| the output to how much of the effect audio you hear as the output. +//| +//| :param synthio.BlockInput roomsize: The size of the room. 0.0 = smallest; 1.0 = largest. +//| :param synthio.BlockInput damp: How much the walls absorb. 0.0 = least; 1.0 = most. +//| :param Optional[synthio.Biquad|Tuple[synthio.Biquad]] pre_filter: A normalized biquad filter object or tuple of normalized biquad filter objects. The sample is processed sequentially by each "Pre-EQ" filter before being fed to the reverb effect. +//| :param Optional[synthio.Biquad|Tuple[synthio.Biquad]] post_filter: A normalized biquad filter object or tuple of normalized biquad filter objects. The output of the reverb effect is processed sequentially by each "Post-EQ" filter before being mixed with the original sample. +//| :param synthio.BlockInput mix: The mix as a ratio of the sample (0.0) to the effect (1.0). +//| :param int buffer_size: The total size in bytes of each of the two playback buffers to use +//| :param int sample_rate: The sample rate to be used +//| :param int channel_count: The number of channels the source samples contain. 1 = mono; 2 = stereo. +//| :param int bits_per_sample: The bits per sample of the effect. Freeverb requires 16 bits. +//| :param bool samples_signed: Effect is signed (True) or unsigned (False). Freeverb requires signed (True). +//| +//| Playing adding reverb to a synth:: +//| +//| import time +//| import board +//| import audiobusio +//| import synthio +//| import audiofreeverb +//| +//| audio = audiobusio.I2SOut(bit_clock=board.GP20, word_select=board.GP21, data=board.GP22) +//| synth = synthio.Synthesizer(channel_count=1, sample_rate=44100) +//| reverb = audiofreeverb.Freeverb(roomsize=0.7, damp=0.3, buffer_size=1024, channel_count=1, sample_rate=44100, mix=0.7) +//| reverb.play(synth) +//| audio.play(reverb) +//| +//| note = synthio.Note(261) +//| while True: +//| synth.press(note) +//| time.sleep(0.55) +//| synth.release(note) +//| time.sleep(5)""" +//| ... +//| +static mp_obj_t audiofreeverb_freeverb_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_roomsize, ARG_damp, ARG_pre_filter, ARG_post_filter, ARG_mix, ARG_buffer_size, ARG_sample_rate, ARG_bits_per_sample, ARG_samples_signed, ARG_channel_count, }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_roomsize, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_damp, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_pre_filter, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, + { MP_QSTR_post_filter, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, + { MP_QSTR_mix, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_buffer_size, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 512} }, + { MP_QSTR_sample_rate, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 8000} }, + { MP_QSTR_bits_per_sample, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 16} }, + { MP_QSTR_samples_signed, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + { MP_QSTR_channel_count, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1 } }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, 2, MP_QSTR_channel_count); + mp_int_t sample_rate = mp_arg_validate_int_min(args[ARG_sample_rate].u_int, 1, MP_QSTR_sample_rate); + if (args[ARG_samples_signed].u_bool != true) { + mp_raise_ValueError(MP_ERROR_TEXT("samples_signed must be true")); + } + mp_int_t bits_per_sample = args[ARG_bits_per_sample].u_int; + if (bits_per_sample != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("bits_per_sample must be 16")); + } + + audiofreeverb_freeverb_obj_t *self = mp_obj_malloc(audiofreeverb_freeverb_obj_t, &audiofreeverb_freeverb_type); + common_hal_audiofreeverb_freeverb_construct(self, args[ARG_roomsize].u_obj, args[ARG_damp].u_obj, args[ARG_pre_filter].u_obj, args[ARG_post_filter].u_obj, args[ARG_mix].u_obj, args[ARG_buffer_size].u_int, bits_per_sample, args[ARG_samples_signed].u_bool, channel_count, sample_rate); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Freeverb.""" +//| ... +//| +static mp_obj_t audiofreeverb_freeverb_deinit(mp_obj_t self_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofreeverb_freeverb_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_deinit_obj, audiofreeverb_freeverb_deinit); + +static void check_for_deinit(audiofreeverb_freeverb_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def __enter__(self) -> Freeverb: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + +//| roomsize: synthio.BlockInput +//| """Apparent size of the room 0.0-1.0""" +static mp_obj_t audiofreeverb_freeverb_obj_get_roomsize(mp_obj_t self_in) { + return common_hal_audiofreeverb_freeverb_get_roomsize(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_roomsize_obj, audiofreeverb_freeverb_obj_get_roomsize); + +static mp_obj_t audiofreeverb_freeverb_obj_set_roomsize(mp_obj_t self_in, mp_obj_t roomsize) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofreeverb_freeverb_set_roomsize(self, roomsize); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofreeverb_freeverb_set_roomsize_obj, audiofreeverb_freeverb_obj_set_roomsize); + +MP_PROPERTY_GETSET(audiofreeverb_freeverb_roomsize_obj, + (mp_obj_t)&audiofreeverb_freeverb_get_roomsize_obj, + (mp_obj_t)&audiofreeverb_freeverb_set_roomsize_obj); + +//| damp: synthio.BlockInput +//| """How much the high frequencies are dampened in the area. 0.0-1.0""" +static mp_obj_t audiofreeverb_freeverb_obj_get_damp(mp_obj_t self_in) { + return common_hal_audiofreeverb_freeverb_get_damp(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_damp_obj, audiofreeverb_freeverb_obj_get_damp); + +static mp_obj_t audiofreeverb_freeverb_obj_set_damp(mp_obj_t self_in, mp_obj_t damp) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofreeverb_freeverb_set_damp(self, damp); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofreeverb_freeverb_set_damp_obj, audiofreeverb_freeverb_obj_set_damp); + +MP_PROPERTY_GETSET(audiofreeverb_freeverb_damp_obj, + (mp_obj_t)&audiofreeverb_freeverb_get_damp_obj, + (mp_obj_t)&audiofreeverb_freeverb_set_damp_obj); + + +//| pre_filter: synthio.Biquad | Tuple[synthio.Biquad] | None +//| """A normalized biquad filter object or tuple of normalized biquad filter objects. The sample is processed sequentially by each "Pre-EQ" filter before being fed to the reverb effect.""" +//| +static mp_obj_t audiofreeverb_freeverb_obj_get_pre_filter(mp_obj_t self_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_audiofreeverb_freeverb_get_pre_filter(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_pre_filter_obj, audiofreeverb_freeverb_obj_get_pre_filter); + +static mp_obj_t audiofreeverb_freeverb_obj_set_pre_filter(mp_obj_t self_in, mp_obj_t filter_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofreeverb_freeverb_set_pre_filter(self, filter_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofreeverb_freeverb_set_pre_filter_obj, audiofreeverb_freeverb_obj_set_pre_filter); + +MP_PROPERTY_GETSET(audiofreeverb_freeverb_pre_filter_obj, + (mp_obj_t)&audiofreeverb_freeverb_get_pre_filter_obj, + (mp_obj_t)&audiofreeverb_freeverb_set_pre_filter_obj); + + +//| post_filter: synthio.Biquad | Tuple[synthio.Biquad] | None +//| """A normalized biquad filter object or tuple of normalized biquad filter objects. The output of the reverb effect is processed sequentially by each "Post-EQ" filter before being mixed with the original sample.""" +//| +static mp_obj_t audiofreeverb_freeverb_obj_get_post_filter(mp_obj_t self_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_audiofreeverb_freeverb_get_post_filter(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_post_filter_obj, audiofreeverb_freeverb_obj_get_post_filter); + +static mp_obj_t audiofreeverb_freeverb_obj_set_post_filter(mp_obj_t self_in, mp_obj_t filter_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofreeverb_freeverb_set_post_filter(self, filter_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofreeverb_freeverb_set_post_filter_obj, audiofreeverb_freeverb_obj_set_post_filter); + +MP_PROPERTY_GETSET(audiofreeverb_freeverb_post_filter_obj, + (mp_obj_t)&audiofreeverb_freeverb_get_post_filter_obj, + (mp_obj_t)&audiofreeverb_freeverb_set_post_filter_obj); + + +//| mix: synthio.BlockInput +//| """The rate the reverb mix between 0 and 1 where 0 is only sample and 1 is all effect.""" +static mp_obj_t audiofreeverb_freeverb_obj_get_mix(mp_obj_t self_in) { + return common_hal_audiofreeverb_freeverb_get_mix(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_mix_obj, audiofreeverb_freeverb_obj_get_mix); + +static mp_obj_t audiofreeverb_freeverb_obj_set_mix(mp_obj_t self_in, mp_obj_t mix_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiofreeverb_freeverb_set_mix(self, mix_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiofreeverb_freeverb_set_mix_obj, audiofreeverb_freeverb_obj_set_mix); + +MP_PROPERTY_GETSET(audiofreeverb_freeverb_mix_obj, + (mp_obj_t)&audiofreeverb_freeverb_get_mix_obj, + (mp_obj_t)&audiofreeverb_freeverb_set_mix_obj); + +//| playing: bool +//| """True when the effect is playing a sample. (read-only)""" +//| +static mp_obj_t audiofreeverb_freeverb_obj_get_playing(mp_obj_t self_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audiofreeverb_freeverb_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_get_playing_obj, audiofreeverb_freeverb_obj_get_playing); + +MP_PROPERTY_GETTER(audiofreeverb_freeverb_playing_obj, + (mp_obj_t)&audiofreeverb_freeverb_get_playing_obj); + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> Freeverb: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| The sample must match the encoding settings given in the constructor. +//| +//| :return: The effect object itself. Can be used for chaining, ie: +//| ``audio.play(effect.play(sample))``. +//| :rtype: Freeverb""" +//| ... +//| +static mp_obj_t audiofreeverb_freeverb_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_audiofreeverb_freeverb_play(self, sample, args[ARG_loop].u_bool); + + return MP_OBJ_FROM_PTR(self); +} +MP_DEFINE_CONST_FUN_OBJ_KW(audiofreeverb_freeverb_play_obj, 1, audiofreeverb_freeverb_obj_play); + +//| def stop(self) -> None: +//| """Stops playback of the sample. The reverb continues playing.""" +//| ... +//| +//| +static mp_obj_t audiofreeverb_freeverb_obj_stop(mp_obj_t self_in) { + audiofreeverb_freeverb_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_audiofreeverb_freeverb_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiofreeverb_freeverb_stop_obj, audiofreeverb_freeverb_obj_stop); + +static const mp_rom_map_elem_t audiofreeverb_freeverb_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiofreeverb_freeverb_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiofreeverb_freeverb_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiofreeverb_freeverb_stop_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiofreeverb_freeverb_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_roomsize), MP_ROM_PTR(&audiofreeverb_freeverb_roomsize_obj) }, + { MP_ROM_QSTR(MP_QSTR_damp), MP_ROM_PTR(&audiofreeverb_freeverb_damp_obj) }, + { MP_ROM_QSTR(MP_QSTR_pre_filter), MP_ROM_PTR(&audiofreeverb_freeverb_pre_filter_obj) }, + { MP_ROM_QSTR(MP_QSTR_post_filter), MP_ROM_PTR(&audiofreeverb_freeverb_post_filter_obj) }, + { MP_ROM_QSTR(MP_QSTR_mix), MP_ROM_PTR(&audiofreeverb_freeverb_mix_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiofreeverb_freeverb_locals_dict, audiofreeverb_freeverb_locals_dict_table); + +static const audiosample_p_t audiofreeverb_freeverb_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiofreeverb_freeverb_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiofreeverb_freeverb_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiofreeverb_freeverb_type, + MP_QSTR_freeverb, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiofreeverb_freeverb_make_new, + locals_dict, &audiofreeverb_freeverb_locals_dict, + protocol, &audiofreeverb_freeverb_proto + ); diff --git a/shared-bindings/audiofreeverb/Freeverb.h b/shared-bindings/audiofreeverb/Freeverb.h new file mode 100644 index 00000000000..7eed9775006 --- /dev/null +++ b/shared-bindings/audiofreeverb/Freeverb.h @@ -0,0 +1,38 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiofreeverb/Freeverb.h" + +extern const mp_obj_type_t audiofreeverb_freeverb_type; + +void common_hal_audiofreeverb_freeverb_construct(audiofreeverb_freeverb_obj_t *self, + mp_obj_t roomsize, mp_obj_t damp, mp_obj_t pre_filter, mp_obj_t post_filter, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate); + +void common_hal_audiofreeverb_freeverb_deinit(audiofreeverb_freeverb_obj_t *self); +bool common_hal_audiofreeverb_freeverb_deinited(audiofreeverb_freeverb_obj_t *self); + +mp_obj_t common_hal_audiofreeverb_freeverb_get_roomsize(audiofreeverb_freeverb_obj_t *self); +void common_hal_audiofreeverb_freeverb_set_roomsize(audiofreeverb_freeverb_obj_t *self, mp_obj_t feedback); + +mp_obj_t common_hal_audiofreeverb_freeverb_get_damp(audiofreeverb_freeverb_obj_t *self); +void common_hal_audiofreeverb_freeverb_set_damp(audiofreeverb_freeverb_obj_t *self, mp_obj_t damp); + +mp_obj_t common_hal_audiofreeverb_freeverb_get_pre_filter(audiofreeverb_freeverb_obj_t *self); +void common_hal_audiofreeverb_freeverb_set_pre_filter(audiofreeverb_freeverb_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiofreeverb_freeverb_get_post_filter(audiofreeverb_freeverb_obj_t *self); +void common_hal_audiofreeverb_freeverb_set_post_filter(audiofreeverb_freeverb_obj_t *self, mp_obj_t arg); + +mp_obj_t common_hal_audiofreeverb_freeverb_get_mix(audiofreeverb_freeverb_obj_t *self); +void common_hal_audiofreeverb_freeverb_set_mix(audiofreeverb_freeverb_obj_t *self, mp_obj_t mix); + +bool common_hal_audiofreeverb_freeverb_get_playing(audiofreeverb_freeverb_obj_t *self); +void common_hal_audiofreeverb_freeverb_play(audiofreeverb_freeverb_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiofreeverb_freeverb_stop(audiofreeverb_freeverb_obj_t *self); diff --git a/shared-bindings/audiofreeverb/__init__.c b/shared-bindings/audiofreeverb/__init__.c new file mode 100644 index 00000000000..cb8c979c8cf --- /dev/null +++ b/shared-bindings/audiofreeverb/__init__.c @@ -0,0 +1,34 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/audiofreeverb/__init__.h" +#include "shared-bindings/audiofreeverb/Freeverb.h" + + +//| """Support for audio freeverb effect +//| +//| The `audiofreeverb` module contains classes to provide access to audio freeverb effects. +//| +//| """ + +static const mp_rom_map_elem_t audiofreeverb_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiofreeverb) }, + { MP_ROM_QSTR(MP_QSTR_Freeverb), MP_ROM_PTR(&audiofreeverb_freeverb_type) }, +}; + +static MP_DEFINE_CONST_DICT(audiofreeverb_module_globals, audiofreeverb_module_globals_table); + +const mp_obj_module_t audiofreeverb_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&audiofreeverb_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_audiofreeverb, audiofreeverb_module); diff --git a/shared-bindings/audiofreeverb/__init__.h b/shared-bindings/audiofreeverb/__init__.h new file mode 100644 index 00000000000..66463561f54 --- /dev/null +++ b/shared-bindings/audiofreeverb/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/audioi2sin/I2SIn.c b/shared-bindings/audioi2sin/I2SIn.c new file mode 100644 index 00000000000..22f1fb2aaad --- /dev/null +++ b/shared-bindings/audioi2sin/I2SIn.c @@ -0,0 +1,361 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "extmod/vfs_fat.h" +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audioi2sin/I2SIn.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiocore/__init__.h" +#include "shared-bindings/util.h" + +//| class I2SIn: +//| """Record an input I2S audio stream from an external I2S source such as a MEMS microphone.""" +//| +//| def __init__( +//| self, +//| bit_clock: microcontroller.Pin, +//| word_select: microcontroller.Pin, +//| data: microcontroller.Pin, +//| *, +//| main_clock: Optional[microcontroller.Pin] = None, +//| sample_rate: int = 16000, +//| bit_depth: int = 16, +//| output_bit_depth: Optional[int] = None, +//| mono: bool = True, +//| left_justified: bool = False, +//| samples_signed: bool = True, +//| external_clock: bool = False, +//| ) -> None: +//| """Create an I2SIn object associated with the given pins. This allows you to +//| record audio signals from an external I2S source (e.g. an I2S MEMS microphone +//| like the SPH0645LM4H or INMP441). +//| +//| The pin signature mirrors `audiobusio.I2SOut` so users can swap classes; +//| recording parameters mirror `audiobusio.PDMIn`. +//| +//| :param ~microcontroller.Pin bit_clock: The bit clock (or serial clock) pin +//| :param ~microcontroller.Pin word_select: The word select (or left/right clock) pin +//| :param ~microcontroller.Pin data: The data input pin +//| :param ~microcontroller.Pin main_clock: The main clock pin. Not all ports support this. +//| :param int sample_rate: Target sample rate of the resulting samples. Check `sample_rate` for actual value. +//| :param int bit_depth: Number of bits per sample on the I2S bus. Must be 8, 16, 24, or +//| 32. 8-bit only supported on espressif. The destination buffer typecode is determined +//| by ``output_bit_depth`` (or ``bit_depth`` when ``output_bit_depth`` is ``None``): +//| +//| +----------------+------------------+----------------------+ +//| | samples_signed | output_bit_depth | Required typecode(s) | +//| +================+==================+======================+ +//| | True | 24 or 32 | ``'i'`` | +//| +----------------+------------------+----------------------+ +//| | True | 16 | ``'h'`` | +//| +----------------+------------------+----------------------+ +//| | True | 8 | ``'b'`` or BYTEARRAY | +//| +----------------+------------------+----------------------+ +//| | False | 24 or 32 | ``'I'`` | +//| +----------------+------------------+----------------------+ +//| | False | 16 | ``'H'`` | +//| +----------------+------------------+----------------------+ +//| | False | 8 | ``'B'`` or BYTEARRAY | +//| +----------------+------------------+----------------------+ +//| +//| Note that 24-bit samples from mics like the SPH0645LM4H / INMP441 are +//| transported in 32-bit slots, so use ``bit_depth=32`` and an ``'I'`` buffer. +//| :param int output_bit_depth: If set, recorded samples are rescaled from +//| ``bit_depth`` to this width before being written to the destination buffer +//| (8, 16, 24, or 32). Widening bit-replicates so full-scale input maps to +//| full-scale output (e.g. 16-bit ``0xFFFF`` -> 24-bit ``0xFFFFFF``); narrowing +//| arithmetic-shifts the value right (sign-preserving when ``samples_signed`` is +//| True). When ``None`` (the default) the destination buffer holds samples at +//| ``bit_depth`` (a 24-bit sample still occupies a 32-bit ``'i'``/``'I'`` slot, +//| sign-extended without rescaling). +//| :param bool mono: True when capturing a single channel of audio, captures two channels otherwise. +//| :param bool left_justified: True when data bits are aligned with the word select clock. False +//| when they are shifted by one to match classic I2S protocol. Set True for mics like the SPH0645LM4H. +//| :param bool samples_signed: Samples are signed (True) or unsigned (False). I2S mics deliver signed +//| two's-complement PCM natively; set False to have the recorded samples converted to unsigned PCM +//| (the top/sign bit is flipped, matching the WAV convention for unsigned samples). +//| :param bool external_clock: True when this object follows an externally supplied clock: +//| ``bit_clock`` and ``word_select`` are inputs driven by something else. Like an +//| `audiobusio.I2SOut` object (the clock source), or a codec, rather than generated by +//| this object. Not supported on all ports. +//| +//| In external clock mode ``bit_clock`` and ``word_select`` do not have to be sequential +//| GPIOs, and they may be shared with another I2S object. ``sample_rate`` becomes a +//| declaration rather than a measurement: the real rate is whatever the external word select +//| runs at, and `sample_rate` still reports the declared value. If the incoming clock stops, +//| `record` blocks (interruptible with Ctrl-C). +//| +//| Example, recording 16-bit mono samples from an INMP441:: +//| +//| import array +//| import audioi2sin +//| import board +//| +//| buf = array.array("h", [0] * 16000) +//| with audioi2sin.I2SIn(board.D9, board.D10, board.D11, +//| sample_rate=16000, bit_depth=16) as mic: +//| mic.record(buf, len(buf)) +//| +//| """ +//| ... +//| +static mp_obj_t audioi2sin_i2sin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + #if !CIRCUITPY_AUDIOI2SIN + mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_I2SIn); + return NULL; // Not reachable. + #else + enum { ARG_bit_clock, ARG_word_select, ARG_data, ARG_main_clock, + ARG_sample_rate, ARG_bit_depth, ARG_output_bit_depth, + ARG_mono, ARG_left_justified, ARG_samples_signed, + ARG_external_clock }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bit_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_word_select, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_main_clock, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_sample_rate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16000} }, + { MP_QSTR_bit_depth, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16} }, + { MP_QSTR_output_bit_depth, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_mono, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_left_justified, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_samples_signed, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_external_clock, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + bool external_clock = args[ARG_external_clock].u_bool; + + // In external clock mode the clock pins are only read, so they may already + // be owned by whatever is driving them; let the port decide if the sharing + // is legal. + const mcu_pin_obj_t *bit_clock = external_clock + ? validate_obj_is_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock) + : validate_obj_is_free_pin(args[ARG_bit_clock].u_obj, MP_QSTR_bit_clock); + const mcu_pin_obj_t *word_select = external_clock + ? validate_obj_is_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select) + : validate_obj_is_free_pin(args[ARG_word_select].u_obj, MP_QSTR_word_select); + const mcu_pin_obj_t *data = validate_obj_is_free_pin(args[ARG_data].u_obj, MP_QSTR_data); + const mcu_pin_obj_t *main_clock = validate_obj_is_free_pin_or_none(args[ARG_main_clock].u_obj, MP_QSTR_main_clock); + + uint32_t sample_rate = args[ARG_sample_rate].u_int; + uint8_t bit_depth = args[ARG_bit_depth].u_int; + if (bit_depth != 8 && bit_depth != 16 && bit_depth != 24 && bit_depth != 32) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be 8, 16, 24, or 32"), MP_QSTR_bit_depth); + } + uint8_t output_bit_depth; + mp_obj_t output_bit_depth_obj = args[ARG_output_bit_depth].u_obj; + if (output_bit_depth_obj == mp_const_none) { + output_bit_depth = bit_depth; + } else { + mp_int_t v = mp_obj_get_int(output_bit_depth_obj); + if (v != 8 && v != 16 && v != 24 && v != 32) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q must be 8, 16, 24, or 32"), MP_QSTR_output_bit_depth); + } + output_bit_depth = (uint8_t)v; + } + bool mono = args[ARG_mono].u_bool; + bool left_justified = args[ARG_left_justified].u_bool; + bool samples_signed = args[ARG_samples_signed].u_bool; + + audioi2sin_i2sin_obj_t *self = mp_obj_malloc_with_finaliser(audioi2sin_i2sin_obj_t, &audioi2sin_i2sin_type); + common_hal_audioi2sin_i2sin_construct(self, bit_clock, word_select, data, main_clock, + sample_rate, bit_depth, output_bit_depth, mono, left_justified, samples_signed, + external_clock); + + return MP_OBJ_FROM_PTR(self); + #endif +} + +#if CIRCUITPY_AUDIOI2SIN +//| def deinit(self) -> None: +//| """Deinitialises the I2SIn and releases any hardware resources for reuse.""" +//| ... +//| +static mp_obj_t audioi2sin_i2sin_deinit(mp_obj_t self_in) { + audioi2sin_i2sin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audioi2sin_i2sin_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audioi2sin_i2sin_deinit_obj, audioi2sin_i2sin_deinit); + +static void check_for_deinit(audioi2sin_i2sin_obj_t *self) { + if (common_hal_audioi2sin_i2sin_deinited(self)) { + raise_deinited_error(); + } +} + +//| def __enter__(self) -> I2SIn: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + +//| def record(self, destination: WriteableBuffer, destination_length: int) -> int: +//| """Records destination_length samples to destination. This is blocking. +//| +//| :return: The number of samples recorded. If this is less than ``destination_length``, +//| some samples were missed due to processing time.""" +//| ... +//| +static mp_obj_t audioi2sin_i2sin_obj_record(mp_obj_t self_obj, mp_obj_t destination, mp_obj_t destination_length) { + audioi2sin_i2sin_obj_t *self = MP_OBJ_TO_PTR(self_obj); + check_for_deinit(self); + uint32_t length = mp_arg_validate_type_int(destination_length, MP_QSTR_length); + mp_arg_validate_length_min(length, 0, MP_QSTR_length); + + mp_buffer_info_t bufinfo; + if (mp_obj_is_type(destination, &mp_type_fileio)) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("Cannot record to a file")); + } + mp_get_buffer_raise(destination, &bufinfo, MP_BUFFER_WRITE); + if (bufinfo.len / mp_binary_get_size('@', bufinfo.typecode, NULL) < length) { + mp_raise_ValueError(MP_ERROR_TEXT("Destination capacity is smaller than destination_length.")); + } + uint8_t output_bit_depth = self->base.bits_per_sample; + char error_type = ' '; + bool samples_signed = common_hal_audioi2sin_i2sin_get_samples_signed(self); + if (samples_signed) { + if ((output_bit_depth == 24 || output_bit_depth == 32) && bufinfo.typecode != 'i') { + error_type = 'i'; + } else if (output_bit_depth == 16 && bufinfo.typecode != 'h') { + error_type = 'h'; + } else if (output_bit_depth == 8 && bufinfo.typecode != 'b' && bufinfo.typecode != BYTEARRAY_TYPECODE) { + error_type = 'b'; // NOTE: Not identifying as bytearray + } + } else { + if ((output_bit_depth == 24 || output_bit_depth == 32) && bufinfo.typecode != 'I') { + error_type = 'I'; + } else if (output_bit_depth == 16 && bufinfo.typecode != 'H') { + error_type = 'H'; + } else if (output_bit_depth == 8 && bufinfo.typecode != 'B' && bufinfo.typecode != BYTEARRAY_TYPECODE) { + error_type = 'B'; + } + } + if (error_type != ' ') { + mp_raise_TypeError_varg( + MP_ERROR_TEXT("invalid destination buffer, must be an array of type: %c"), + error_type + ); + } + uint32_t length_written = + common_hal_audioi2sin_i2sin_record_to_buffer(self, bufinfo.buf, length); + return MP_OBJ_NEW_SMALL_INT(length_written); +} +MP_DEFINE_CONST_FUN_OBJ_3(audioi2sin_i2sin_record_obj, audioi2sin_i2sin_obj_record); + +//| sample_rate: int +//| """The configured (nominal) sample rate, in Hz. This is the rate reported to +//| the audio pipeline so it matches the output/consumer it is played into. The +//| true capture rate may differ from this by a fraction of a Hz due to internal +//| clock limitations.""" +//| +//| bits_per_sample: int +//| """The number of bits per sample as it is streamed through the audio pipeline. +//| (read-only)""" +//| +//| channel_count: int +//| """The number of channels (1 for mono, 2 for stereo). (read-only)""" +//| + +//| bit_depth: int +//| """The actual bit depth of the recording. (read-only)""" +//| +//| +static mp_obj_t audioi2sin_i2sin_obj_get_bit_depth(mp_obj_t self_in) { + audioi2sin_i2sin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_audioi2sin_i2sin_get_bit_depth(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioi2sin_i2sin_get_bit_depth_obj, audioi2sin_i2sin_obj_get_bit_depth); + +MP_PROPERTY_GETTER(audioi2sin_i2sin_bit_depth_obj, + (mp_obj_t)&audioi2sin_i2sin_get_bit_depth_obj); + + +//| samples_signed: bool +//| """True if recorded samples are signed PCM, False for unsigned. (read-only)""" +//| +//| +static mp_obj_t audioi2sin_i2sin_obj_get_samples_signed(mp_obj_t self_in) { + audioi2sin_i2sin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audioi2sin_i2sin_get_samples_signed(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioi2sin_i2sin_get_samples_signed_obj, audioi2sin_i2sin_obj_get_samples_signed); + +MP_PROPERTY_GETTER(audioi2sin_i2sin_samples_signed_obj, + (mp_obj_t)&audioi2sin_i2sin_get_samples_signed_obj); + + +//| overflow: bool +//| """True if samples were dropped because they were not read fast enough, +//| since the last time this was checked. (read-only) +//| +//| Reading this clears the flag, so it reports whether an overflow happened +//| in the interval since the previous read rather than at any time in the +//| past. `record` and streaming playback both set it; a streaming consumer +//| has no other way to notice it is falling behind. +//| +//| Not all ports can detect overflow; those report False always.""" +//| +//| +static mp_obj_t audioi2sin_i2sin_obj_get_overflow(mp_obj_t self_in) { + audioi2sin_i2sin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_audioi2sin_i2sin_get_overflow(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audioi2sin_i2sin_get_overflow_obj, audioi2sin_i2sin_obj_get_overflow); + +MP_PROPERTY_GETTER(audioi2sin_i2sin_overflow_obj, + (mp_obj_t)&audioi2sin_i2sin_get_overflow_obj); + +static const mp_rom_map_elem_t audioi2sin_i2sin_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audioi2sin_i2sin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioi2sin_i2sin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_record), MP_ROM_PTR(&audioi2sin_i2sin_record_obj) }, + // sample_rate / bits_per_sample / channel_count come from the audiosample + // protocol's shared property getters. + AUDIOSAMPLE_FIELDS, + { MP_ROM_QSTR(MP_QSTR_bit_depth), MP_ROM_PTR(&audioi2sin_i2sin_bit_depth_obj) }, + { MP_ROM_QSTR(MP_QSTR_samples_signed), MP_ROM_PTR(&audioi2sin_i2sin_samples_signed_obj) }, + { MP_ROM_QSTR(MP_QSTR_overflow), MP_ROM_PTR(&audioi2sin_i2sin_overflow_obj) }, +}; +static MP_DEFINE_CONST_DICT(audioi2sin_i2sin_locals_dict, audioi2sin_i2sin_locals_dict_table); + +static const audiosample_p_t audioi2sin_i2sin_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)common_hal_audioi2sin_i2sin_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)common_hal_audioi2sin_i2sin_get_buffer, +}; +#endif // CIRCUITPY_AUDIOI2SIN + +MP_DEFINE_CONST_OBJ_TYPE( + audioi2sin_i2sin_type, + MP_QSTR_I2SIn, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audioi2sin_i2sin_make_new + #if CIRCUITPY_AUDIOI2SIN + , locals_dict, &audioi2sin_i2sin_locals_dict + , protocol, &audioi2sin_i2sin_proto + #endif + ); diff --git a/shared-bindings/audioi2sin/I2SIn.h b/shared-bindings/audioi2sin/I2SIn.h new file mode 100644 index 00000000000..25f5489015d --- /dev/null +++ b/shared-bindings/audioi2sin/I2SIn.h @@ -0,0 +1,45 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-bindings/microcontroller/Pin.h" + +#if CIRCUITPY_AUDIOI2SIN +#include "common-hal/audioi2sin/I2SIn.h" +#include "shared-module/audiocore/__init__.h" +#endif + +extern const mp_obj_type_t audioi2sin_i2sin_type; + +#if CIRCUITPY_AUDIOI2SIN +void common_hal_audioi2sin_i2sin_construct(audioi2sin_i2sin_obj_t *self, + const mcu_pin_obj_t *bit_clock, const mcu_pin_obj_t *word_select, + const mcu_pin_obj_t *data, const mcu_pin_obj_t *main_clock, + uint32_t sample_rate, uint8_t bit_depth, uint8_t output_bit_depth, + bool mono, bool left_justified, bool samples_signed, + bool external_clock); +void common_hal_audioi2sin_i2sin_deinit(audioi2sin_i2sin_obj_t *self); +bool common_hal_audioi2sin_i2sin_deinited(audioi2sin_i2sin_obj_t *self); +uint32_t common_hal_audioi2sin_i2sin_record_to_buffer(audioi2sin_i2sin_obj_t *self, + void *buffer, uint32_t length); +uint8_t common_hal_audioi2sin_i2sin_get_bit_depth(audioi2sin_i2sin_obj_t *self); +uint32_t common_hal_audioi2sin_i2sin_get_sample_rate(audioi2sin_i2sin_obj_t *self); +bool common_hal_audioi2sin_i2sin_get_samples_signed(audioi2sin_i2sin_obj_t *self); +// Reads and clears the sticky "samples were dropped" flag. +bool common_hal_audioi2sin_i2sin_get_overflow(audioi2sin_i2sin_obj_t *self); + +// audiosample protocol: streaming source support. fill_buffer converts the +// frames currently available from the live mic into `buffer` (output depth, +// interleaved), padding with silence on underrun; it never blocks. +void common_hal_audioi2sin_i2sin_fill_buffer(audioi2sin_i2sin_obj_t *self, + uint8_t *buffer, uint32_t frames); +void common_hal_audioi2sin_i2sin_reset_buffer(audioi2sin_i2sin_obj_t *self, + bool single_channel_output, uint8_t channel); +audioio_get_buffer_result_t common_hal_audioi2sin_i2sin_get_buffer( + audioi2sin_i2sin_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length); +#endif diff --git a/shared-bindings/audioi2sin/__init__.c b/shared-bindings/audioi2sin/__init__.c new file mode 100644 index 00000000000..45ba16cb01a --- /dev/null +++ b/shared-bindings/audioi2sin/__init__.c @@ -0,0 +1,38 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/audioi2sin/__init__.h" +#include "shared-bindings/audioi2sin/I2SIn.h" + +//| """Support for recording audio from an I2S input source. +//| +//| The `audioi2sin` module contains the `I2SIn` class for recording audio +//| from an external I2S source such as a MEMS microphone (e.g. SPH0645LM4H +//| or INMP441). +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager.""" + +static const mp_rom_map_elem_t audioi2sin_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioi2sin) }, + { MP_ROM_QSTR(MP_QSTR_I2SIn), MP_ROM_PTR(&audioi2sin_i2sin_type) }, +}; + +static MP_DEFINE_CONST_DICT(audioi2sin_module_globals, audioi2sin_module_globals_table); + +const mp_obj_module_t audioi2sin_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&audioi2sin_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_audioi2sin, audioi2sin_module); diff --git a/shared-bindings/audioi2sin/__init__.h b/shared-bindings/audioi2sin/__init__.h new file mode 100644 index 00000000000..779b49ffd8d --- /dev/null +++ b/shared-bindings/audioi2sin/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/audioio/AudioOut.c b/shared-bindings/audioio/AudioOut.c index 4d5765aa210..8ea068ceb8f 100644 --- a/shared-bindings/audioio/AudioOut.c +++ b/shared-bindings/audioio/AudioOut.c @@ -23,16 +23,21 @@ //| left_channel: microcontroller.Pin, //| *, //| right_channel: Optional[microcontroller.Pin] = None, -//| quiescent_value: int = 0x8000 +//| quiescent_value: int = 0x8000, //| ) -> None: //| """Create a AudioOut object associated with the given pin(s). This allows you to //| play audio signals out on the given pin(s). //| -//| :param ~microcontroller.Pin left_channel: The pin to output the left channel to -//| :param ~microcontroller.Pin right_channel: The pin to output the right channel to +//| :param ~microcontroller.Pin left_channel: Output left channel data to this pin +//| :param ~microcontroller.Pin right_channel: Output right channel data to this pin. May be ``None``. //| :param int quiescent_value: The output value when no signal is present. Samples should start //| and end with this value to prevent audible popping. //| +//| .. note:: On ESP32 and ESP32-S2, the DAC channels are usually designated +//| as ``DAC_1`` (right stereo channel) and DAC_2 (left stereo channel). +//| These pins are sometimes labelled as ``A0`` and ``A1``, but they may be assigned +//| in either order. Check your board's pinout to verify which pin is which channel. +//| //| Simple 8ksps 440 Hz sin wave:: //| //| import audiocore @@ -74,6 +79,7 @@ //| pass //| print("stopped")""" //| ... +//| static mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; static const mp_arg_t allowed_args[] = { @@ -89,9 +95,18 @@ static mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar const mcu_pin_obj_t *right_channel_pin = validate_obj_is_free_pin_or_none(args[ARG_right_channel].u_obj, MP_QSTR_right_channel); + // Can't use the same pin for both left and right channels. + if (left_channel_pin == right_channel_pin) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q and %q must be different"), + MP_QSTR_left_channel, MP_QSTR_right_channel); + } + // create AudioOut object from the given pin audioio_audioout_obj_t *self = mp_obj_malloc_with_finaliser(audioio_audioout_obj_t, &audioio_audioout_type); - common_hal_audioio_audioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); + common_hal_audioio_audioout_construct(self, + left_channel_pin, + right_channel_pin, + args[ARG_quiescent_value].u_int); return MP_OBJ_FROM_PTR(self); } @@ -99,6 +114,7 @@ static mp_obj_t audioio_audioout_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the AudioOut and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t audioio_audioout_deinit(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audioio_audioout_deinit(self); @@ -114,19 +130,15 @@ static void check_for_deinit(audioio_audioout_obj_t *self) { //| def __enter__(self) -> AudioOut: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t audioio_audioout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audioio_audioout_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, audioio_audioout_obj___exit__); - +//| +// Provided by context manager helper. //| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: //| """Plays the sample once when loop=False and continuously when loop=True. @@ -138,6 +150,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audioio_audioout___exit___obj, 4, 4, //| resolution will use the highest order bits to output. For example, the SAMD21 has a 10 bit //| DAC that ignores the lowest 6 bits when playing 16 bit samples.""" //| ... +//| static mp_obj_t audioio_audioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -159,6 +172,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audioio_audioout_play_obj, 1, audioio_audioout_obj_pl //| def stop(self) -> None: //| """Stops playback and resets to the start of the sample.""" //| ... +//| static mp_obj_t audioio_audioout_obj_stop(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -169,6 +183,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_stop_obj, audioio_audioout_obj_stop); //| playing: bool //| """True when an audio sample is being output even if `paused`. (read-only)""" +//| static mp_obj_t audioio_audioout_obj_get_playing(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -182,6 +197,7 @@ MP_PROPERTY_GETTER(audioio_audioout_playing_obj, //| def pause(self) -> None: //| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" //| ... +//| static mp_obj_t audioio_audioout_obj_pause(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -197,6 +213,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_pause_obj, audioio_audioout_obj_pause //| def resume(self) -> None: //| """Resumes sample playback after :py:func:`pause`.""" //| ... +//| static mp_obj_t audioio_audioout_obj_resume(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -212,6 +229,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audioio_audioout_resume_obj, audioio_audioout_obj_resu //| paused: bool //| """True when playback is paused. (read-only)""" //| +//| static mp_obj_t audioio_audioout_obj_get_paused(mp_obj_t self_in) { audioio_audioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -227,7 +245,7 @@ static const mp_rom_map_elem_t audioio_audioout_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audioio_audioout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audioio_audioout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audioio_audioout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audioio_audioout_play_obj) }, { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audioio_audioout_stop_obj) }, { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&audioio_audioout_pause_obj) }, diff --git a/shared-bindings/audioio/__init__.c b/shared-bindings/audioio/__init__.c index ac8a85f1d65..88109d5d521 100644 --- a/shared-bindings/audioio/__init__.c +++ b/shared-bindings/audioio/__init__.c @@ -27,11 +27,7 @@ //| `_. //| //| Since CircuitPython 5, `RawSample` and `WaveFile` are moved -//| to :mod:`audiocore`, and `Mixer` is moved to :mod:`audiomixer`. -//| -//| For compatibility with CircuitPython 4.x, some builds allow the items in -//| `audiocore` to be imported from `audioio`. This will be removed for all -//| boards in a future build of CircuitPython.""" +//| to :mod:`audiocore`, and `Mixer` is moved to :mod:`audiomixer`.""" static const mp_rom_map_elem_t audioio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audioio) }, diff --git a/shared-bindings/audiomixer/Mixer.c b/shared-bindings/audiomixer/Mixer.c index 4f38b2b7baf..516d079cd2a 100644 --- a/shared-bindings/audiomixer/Mixer.c +++ b/shared-bindings/audiomixer/Mixer.c @@ -5,6 +5,7 @@ // SPDX-License-Identifier: MIT #include "shared-bindings/audiomixer/Mixer.h" #include "shared-bindings/audiomixer/MixerVoice.h" +#include "shared-bindings/audiocore/__init__.h" #include "shared-module/audiomixer/MixerVoice.h" #include @@ -62,6 +63,7 @@ //| time.sleep(1) //| print("stopped")""" //| ... +//| static mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_voice_count, ARG_buffer_size, ARG_channel_count, ARG_bits_per_sample, ARG_samples_signed, ARG_sample_rate }; static const mp_arg_t allowed_args[] = { @@ -98,6 +100,7 @@ static mp_obj_t audiomixer_mixer_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the Mixer and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t audiomixer_mixer_deinit(mp_obj_t self_in) { audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiomixer_mixer_deinit(self); @@ -106,26 +109,21 @@ static mp_obj_t audiomixer_mixer_deinit(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_deinit_obj, audiomixer_mixer_deinit); static void check_for_deinit(audiomixer_mixer_obj_t *self) { - if (common_hal_audiomixer_mixer_deinited(self)) { - raise_deinited_error(); - } + audiosample_check_for_deinit(&self->base); } //| def __enter__(self) -> Mixer: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t audiomixer_mixer_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audiomixer_mixer_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomixer_mixer___exit___obj, 4, 4, audiomixer_mixer_obj___exit__); +//| +// Provided by context manager helper. //| playing: bool //| """True when any voice is being output. (read-only)""" @@ -141,15 +139,6 @@ MP_PROPERTY_GETTER(audiomixer_mixer_playing_obj, //| sample_rate: int //| """32 bit value that dictates how quickly samples are played in Hertz (cycles per second).""" -static mp_obj_t audiomixer_mixer_obj_get_sample_rate(mp_obj_t self_in) { - audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audiomixer_mixer_get_sample_rate(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixer_get_sample_rate_obj, audiomixer_mixer_obj_get_sample_rate); - -MP_PROPERTY_GETTER(audiomixer_mixer_sample_rate_obj, - (mp_obj_t)&audiomixer_mixer_get_sample_rate_obj); //| voice: Tuple[MixerVoice, ...] //| """A tuple of the mixer's `audiomixer.MixerVoice` object(s). @@ -158,6 +147,7 @@ MP_PROPERTY_GETTER(audiomixer_mixer_sample_rate_obj, //| //| >>> mixer.voice //| (,)""" +//| static mp_obj_t audiomixer_mixer_obj_get_voice(mp_obj_t self_in) { audiomixer_mixer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -170,14 +160,19 @@ MP_PROPERTY_GETTER(audiomixer_mixer_voice_obj, //| def play( //| self, sample: circuitpython_typing.AudioSample, *, voice: int = 0, loop: bool = False -//| ) -> None: +//| ) -> Mixer: //| """Plays the sample once when loop=False and continuously when loop=True. //| Does not block. Use `playing` to block. //| //| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, `audiomixer.Mixer` or `audiomp3.MP3Decoder`. //| -//| The sample must match the Mixer's encoding settings given in the constructor.""" +//| The sample must match the Mixer's encoding settings given in the constructor. +//| +//| :return: The mixer object itself. Can be used for chaining, ie: +//| ``audio.play(mixer.play(sample))``. +//| :rtype: Chorus""" //| ... +//| static mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_voice, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -198,7 +193,7 @@ static mp_obj_t audiomixer_mixer_obj_play(size_t n_args, const mp_obj_t *pos_arg mp_obj_t sample = args[ARG_sample].u_obj; common_hal_audiomixer_mixervoice_play(voice, sample, args[ARG_loop].u_bool); - return mp_const_none; + return MP_OBJ_FROM_PTR(self); } MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_play); @@ -206,6 +201,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixer_play_obj, 1, audiomixer_mixer_obj_pl //| """Stops playback of the sample on the given voice.""" //| ... //| +//| static mp_obj_t audiomixer_mixer_obj_stop_voice(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_voice }; static const mp_arg_t allowed_args[] = { @@ -231,25 +227,21 @@ static const mp_rom_map_elem_t audiomixer_mixer_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiomixer_mixer_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiomixer_mixer___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiomixer_mixer_play_obj) }, { MP_ROM_QSTR(MP_QSTR_stop_voice), MP_ROM_PTR(&audiomixer_mixer_stop_voice_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiomixer_mixer_playing_obj) }, - { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiomixer_mixer_sample_rate_obj) }, - { MP_ROM_QSTR(MP_QSTR_voice), MP_ROM_PTR(&audiomixer_mixer_voice_obj) } + { MP_ROM_QSTR(MP_QSTR_voice), MP_ROM_PTR(&audiomixer_mixer_voice_obj) }, + AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(audiomixer_mixer_locals_dict, audiomixer_mixer_locals_dict_table); static const audiosample_p_t audiomixer_mixer_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) - .sample_rate = (audiosample_sample_rate_fun)common_hal_audiomixer_mixer_get_sample_rate, - .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audiomixer_mixer_get_bits_per_sample, - .channel_count = (audiosample_channel_count_fun)common_hal_audiomixer_mixer_get_channel_count, .reset_buffer = (audiosample_reset_buffer_fun)audiomixer_mixer_reset_buffer, .get_buffer = (audiosample_get_buffer_fun)audiomixer_mixer_get_buffer, - .get_buffer_structure = (audiosample_get_buffer_structure_fun)audiomixer_mixer_get_buffer_structure, }; MP_DEFINE_CONST_OBJ_TYPE( diff --git a/shared-bindings/audiomixer/Mixer.h b/shared-bindings/audiomixer/Mixer.h index 29577b0a61b..3e6e5890f44 100644 --- a/shared-bindings/audiomixer/Mixer.h +++ b/shared-bindings/audiomixer/Mixer.h @@ -20,9 +20,5 @@ void common_hal_audiomixer_mixer_construct(audiomixer_mixer_obj_t *self, uint32_t sample_rate); void common_hal_audiomixer_mixer_deinit(audiomixer_mixer_obj_t *self); -bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t *self); bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t *self); -uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t *self); -uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t *self); -uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t *self); diff --git a/shared-bindings/audiomixer/MixerVoice.c b/shared-bindings/audiomixer/MixerVoice.c index eed877bc789..4957fab3884 100644 --- a/shared-bindings/audiomixer/MixerVoice.c +++ b/shared-bindings/audiomixer/MixerVoice.c @@ -13,6 +13,9 @@ #include "py/objproperty.h" #include "py/runtime.h" #include "shared-bindings/util.h" +#if CIRCUITPY_SYNTHIO +#include "shared-module/synthio/block.h" +#endif //| class MixerVoice: //| """Voice objects used with Mixer @@ -22,11 +25,12 @@ //| def __init__(self) -> None: //| """MixerVoice instance object(s) created by `audiomixer.Mixer`.""" //| ... +//| // TODO: support mono or stereo voices static mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 0, 0, false); - audiomixer_mixervoice_obj_t *self = mp_obj_malloc(audiomixer_mixervoice_obj_t, &audiomixer_mixervoice_type); + audiomixer_mixervoice_obj_t *self = mp_obj_malloc(audiomixer_mixervoice_obj_t, &audiomixer_mixervoice_type); common_hal_audiomixer_mixervoice_construct(self); return MP_OBJ_FROM_PTR(self); @@ -41,6 +45,7 @@ static mp_obj_t audiomixer_mixervoice_make_new(const mp_obj_type_t *type, size_t //| The sample must match the `audiomixer.Mixer`'s encoding settings given in the constructor. //| """ //| ... +//| static mp_obj_t audiomixer_mixervoice_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -60,6 +65,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_play_obj, 1, audiomixer_mixervo //| def stop(self) -> None: //| """Stops playback of the sample on this voice.""" //| ... +//| static mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_voice }; static const mp_arg_t allowed_args[] = { @@ -75,41 +81,87 @@ static mp_obj_t audiomixer_mixervoice_obj_stop(size_t n_args, const mp_obj_t *po } MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_stop_obj, 1, audiomixer_mixervoice_obj_stop); -//| level: float -//| """The volume level of a voice, as a floating point number between 0 and 1.""" +//| def end(self) -> None: +//| """ Sets looping to False if sample is playing. This allows the looped +//| sample to complete its current playback and end further looping """ +//| ... +//| +static mp_obj_t audiomixer_mixervoice_obj_end(mp_obj_t self_in) { + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiomixer_mixervoice_end(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_end_obj, audiomixer_mixervoice_obj_end); + + +//| level: synthio.BlockInput +//| """The volume level of a voice, as a floating point number between 0 and 1. If your board +//| does not support synthio, this property will only accept a float value. +//| """ static mp_obj_t audiomixer_mixervoice_obj_get_level(mp_obj_t self_in) { - return mp_obj_new_float(common_hal_audiomixer_mixervoice_get_level(self_in)); + return common_hal_audiomixer_mixervoice_get_level(self_in); } MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_level_obj, audiomixer_mixervoice_obj_get_level); -static mp_obj_t audiomixer_mixervoice_obj_set_level(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_level }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_level, MP_ARG_OBJ | MP_ARG_REQUIRED, {} }, - }; - audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); +static mp_obj_t audiomixer_mixervoice_obj_set_level(mp_obj_t self_in, mp_obj_t level_in) { + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiomixer_mixervoice_set_level(self, level_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiomixer_mixervoice_set_level_obj, audiomixer_mixervoice_obj_set_level); + +MP_PROPERTY_GETSET(audiomixer_mixervoice_level_obj, + (mp_obj_t)&audiomixer_mixervoice_get_level_obj, + (mp_obj_t)&audiomixer_mixervoice_set_level_obj); + +//| panning: synthio.BlockInput +//| """Defines the channel(s) in which the voice appears, as a floating point number between +//| -1 and 1. If your board does not support synthio, this property will only accept a float +//| value. This property is ignored if ``audiomixer.Mixer.channel_count=1``. +//| +//| -1 is left channel only, 0 is both channels, and 1 is right channel. For fractional values, +//| the note plays at full amplitude in one channel and partial amplitude in the other channel. +//| For instance -.5 plays at full amplitude in the left channel and 1/2 amplitude in the right +//| channel.""" +static mp_obj_t audiomixer_mixervoice_obj_get_panning(mp_obj_t self_in) { + return common_hal_audiomixer_mixervoice_get_panning(self_in); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_panning_obj, audiomixer_mixervoice_obj_get_panning); - mp_float_t level = mp_obj_get_float(args[ARG_level].u_obj); +static mp_obj_t audiomixer_mixervoice_obj_set_panning(mp_obj_t self_in, mp_obj_t panning_in) { + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiomixer_mixervoice_set_panning(self, panning_in); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiomixer_mixervoice_set_panning_obj, audiomixer_mixervoice_obj_set_panning); - if (level > 1 || level < 0) { - mp_raise_ValueError(MP_ERROR_TEXT("level must be between 0 and 1")); - } +MP_PROPERTY_GETSET(audiomixer_mixervoice_panning_obj, + (mp_obj_t)&audiomixer_mixervoice_get_panning_obj, + (mp_obj_t)&audiomixer_mixervoice_set_panning_obj); - common_hal_audiomixer_mixervoice_set_level(self, level); +//| loop: bool +//| """Get or set the loop status of the currently playing sample.""" +static mp_obj_t audiomixer_mixervoice_obj_get_loop(mp_obj_t self_in) { + return mp_obj_new_bool(common_hal_audiomixer_mixervoice_get_loop(self_in)); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiomixer_mixervoice_get_loop_obj, audiomixer_mixervoice_obj_get_loop); +static mp_obj_t audiomixer_mixervoice_obj_set_loop(mp_obj_t self_in, mp_obj_t loop_in) { + audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); + bool loop = mp_obj_is_true(loop_in); + common_hal_audiomixer_mixervoice_set_loop(self, loop); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_KW(audiomixer_mixervoice_set_level_obj, 1, audiomixer_mixervoice_obj_set_level); +MP_DEFINE_CONST_FUN_OBJ_2(audiomixer_mixervoice_set_loop_obj, audiomixer_mixervoice_obj_set_loop); -MP_PROPERTY_GETSET(audiomixer_mixervoice_level_obj, - (mp_obj_t)&audiomixer_mixervoice_get_level_obj, - (mp_obj_t)&audiomixer_mixervoice_set_level_obj); +MP_PROPERTY_GETSET(audiomixer_mixervoice_loop_obj, + (mp_obj_t)&audiomixer_mixervoice_get_loop_obj, + (mp_obj_t)&audiomixer_mixervoice_set_loop_obj); //| playing: bool //| """True when this voice is being output. (read-only)""" //| +//| static mp_obj_t audiomixer_mixervoice_obj_get_playing(mp_obj_t self_in) { audiomixer_mixervoice_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -126,10 +178,13 @@ static const mp_rom_map_elem_t audiomixer_mixervoice_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiomixer_mixervoice_play_obj) }, { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiomixer_mixervoice_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_end), MP_ROM_PTR(&audiomixer_mixervoice_end_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&audiomixer_mixervoice_playing_obj) }, { MP_ROM_QSTR(MP_QSTR_level), MP_ROM_PTR(&audiomixer_mixervoice_level_obj) }, + { MP_ROM_QSTR(MP_QSTR_panning), MP_ROM_PTR(&audiomixer_mixervoice_panning_obj) }, + { MP_ROM_QSTR(MP_QSTR_loop), MP_ROM_PTR(&audiomixer_mixervoice_loop_obj) }, }; static MP_DEFINE_CONST_DICT(audiomixer_mixervoice_locals_dict, audiomixer_mixervoice_locals_dict_table); diff --git a/shared-bindings/audiomixer/MixerVoice.h b/shared-bindings/audiomixer/MixerVoice.h index 1f5311edf41..89c87218e7c 100644 --- a/shared-bindings/audiomixer/MixerVoice.h +++ b/shared-bindings/audiomixer/MixerVoice.h @@ -14,8 +14,15 @@ extern const mp_obj_type_t audiomixer_mixervoice_type; void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self); void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *self, audiomixer_mixer_obj_t *parent); void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_audiomixer_mixervoice_reset_buffer(audiomixer_mixervoice_obj_t *self); void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t *self); -mp_float_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self); -void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_float_t gain); +void common_hal_audiomixer_mixervoice_end(audiomixer_mixervoice_obj_t *self); +mp_obj_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_obj_t gain); +mp_obj_t common_hal_audiomixer_mixervoice_get_panning(audiomixer_mixervoice_obj_t *self); +void common_hal_audiomixer_mixervoice_set_panning(audiomixer_mixervoice_obj_t *self, mp_obj_t value); bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t *self); + +void common_hal_audiomixer_mixervoice_set_loop(audiomixer_mixervoice_obj_t *self, bool loop); +bool common_hal_audiomixer_mixervoice_get_loop(audiomixer_mixervoice_obj_t *self); diff --git a/shared-bindings/audiomp3/MP3Decoder.c b/shared-bindings/audiomp3/MP3Decoder.c index 8e6df36462e..433b308c156 100644 --- a/shared-bindings/audiomp3/MP3Decoder.c +++ b/shared-bindings/audiomp3/MP3Decoder.c @@ -8,6 +8,7 @@ #include #include "shared/runtime/context_manager_helpers.h" +#include "shared-bindings/audiocore/__init__.h" #include "py/objproperty.h" #include "py/runtime.h" #include "py/stream.h" @@ -80,6 +81,7 @@ //| that the socket closes when the stream ends. //| """ //| ... +//| static mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 2, false); @@ -89,8 +91,6 @@ static mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar stream = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), stream, MP_ROM_QSTR(MP_QSTR_rb)); } - audiomp3_mp3file_obj_t *self = mp_obj_malloc_with_finaliser(audiomp3_mp3file_obj_t, &audiomp3_mp3file_type); - const mp_stream_p_t *stream_p = mp_get_stream_raise(stream, MP_STREAM_OP_READ); if (stream_p->is_text) { @@ -104,6 +104,8 @@ static mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar buffer = bufinfo.buf; buffer_size = bufinfo.len; } + + audiomp3_mp3file_obj_t *self = mp_obj_malloc_with_finaliser(audiomp3_mp3file_obj_t, &audiomp3_mp3file_type); common_hal_audiomp3_mp3file_construct(self, stream, buffer, buffer_size); return MP_OBJ_FROM_PTR(self); @@ -112,6 +114,7 @@ static mp_obj_t audiomp3_mp3file_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the MP3 and releases all memory resources for reuse.""" //| ... +//| static mp_obj_t audiomp3_mp3file_deinit(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiomp3_mp3file_deinit(self); @@ -120,29 +123,25 @@ static mp_obj_t audiomp3_mp3file_deinit(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_deinit_obj, audiomp3_mp3file_deinit); static void check_for_deinit(audiomp3_mp3file_obj_t *self) { - if (common_hal_audiomp3_mp3file_deinited(self)) { - raise_deinited_error(); - } + audiosample_check_for_deinit(&self->base); } //| def __enter__(self) -> MP3Decoder: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t audiomp3_mp3file_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audiomp3_mp3file_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiomp3_mp3file___exit___obj, 4, 4, audiomp3_mp3file_obj___exit__); +//| +// Provided by context manager helper. //| file: typing.BinaryIO //| """File to play back.""" +//| static mp_obj_t audiomp3_mp3file_obj_get_file(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -166,6 +165,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(audiomp3_mp3file_set_file_obj, audiomp3_mp3file_obj_se //| def open(self, filepath: str) -> None: //| """Takes in the name of a mp3 file, opens it, and replaces the old playback file.""" //| ... +//| static mp_obj_t audiomp3_mp3file_obj_open(mp_obj_t self_in, mp_obj_t path) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -187,48 +187,12 @@ MP_PROPERTY_GETSET(audiomp3_mp3file_file_obj, //| """32 bit value that dictates how quickly samples are loaded into the DAC //| in Hertz (cycles per second). When the sample is looped, this can change //| the pitch output without changing the underlying sample.""" -static mp_obj_t audiomp3_mp3file_obj_get_sample_rate(mp_obj_t self_in) { - audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audiomp3_mp3file_get_sample_rate(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_get_sample_rate_obj, audiomp3_mp3file_obj_get_sample_rate); - -static mp_obj_t audiomp3_mp3file_obj_set_sample_rate(mp_obj_t self_in, mp_obj_t sample_rate) { - audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - common_hal_audiomp3_mp3file_set_sample_rate(self, mp_obj_get_int(sample_rate)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(audiomp3_mp3file_set_sample_rate_obj, audiomp3_mp3file_obj_set_sample_rate); - -MP_PROPERTY_GETSET(audiomp3_mp3file_sample_rate_obj, - (mp_obj_t)&audiomp3_mp3file_get_sample_rate_obj, - (mp_obj_t)&audiomp3_mp3file_set_sample_rate_obj); //| bits_per_sample: int //| """Bits per sample. (read only)""" -static mp_obj_t audiomp3_mp3file_obj_get_bits_per_sample(mp_obj_t self_in) { - audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audiomp3_mp3file_get_bits_per_sample(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_get_bits_per_sample_obj, audiomp3_mp3file_obj_get_bits_per_sample); - -MP_PROPERTY_GETTER(audiomp3_mp3file_bits_per_sample_obj, - (mp_obj_t)&audiomp3_mp3file_get_bits_per_sample_obj); //| channel_count: int //| """Number of audio channels. (read only)""" -static mp_obj_t audiomp3_mp3file_obj_get_channel_count(mp_obj_t self_in) { - audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_audiomp3_mp3file_get_channel_count(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(audiomp3_mp3file_get_channel_count_obj, audiomp3_mp3file_obj_get_channel_count); - -MP_PROPERTY_GETTER(audiomp3_mp3file_channel_count_obj, - (mp_obj_t)&audiomp3_mp3file_get_channel_count_obj); //| rms_level: float //| """The RMS audio level of a recently played moment of audio. (read only)""" @@ -245,6 +209,7 @@ MP_PROPERTY_GETTER(audiomp3_mp3file_rms_level_obj, //| samples_decoded: int //| """The number of audio samples decoded from the current file. (read only)""" //| +//| static mp_obj_t audiomp3_mp3file_obj_get_samples_decoded(mp_obj_t self_in) { audiomp3_mp3file_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -261,26 +226,20 @@ static const mp_rom_map_elem_t audiomp3_mp3file_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiomp3_mp3file_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audiomp3_mp3file_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiomp3_mp3file___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_file), MP_ROM_PTR(&audiomp3_mp3file_file_obj) }, - { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&audiomp3_mp3file_sample_rate_obj) }, - { MP_ROM_QSTR(MP_QSTR_bits_per_sample), MP_ROM_PTR(&audiomp3_mp3file_bits_per_sample_obj) }, - { MP_ROM_QSTR(MP_QSTR_channel_count), MP_ROM_PTR(&audiomp3_mp3file_channel_count_obj) }, { MP_ROM_QSTR(MP_QSTR_rms_level), MP_ROM_PTR(&audiomp3_mp3file_rms_level_obj) }, { MP_ROM_QSTR(MP_QSTR_samples_decoded), MP_ROM_PTR(&audiomp3_mp3file_samples_decoded_obj) }, + AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(audiomp3_mp3file_locals_dict, audiomp3_mp3file_locals_dict_table); static const audiosample_p_t audiomp3_mp3file_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) - .sample_rate = (audiosample_sample_rate_fun)common_hal_audiomp3_mp3file_get_sample_rate, - .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_audiomp3_mp3file_get_bits_per_sample, - .channel_count = (audiosample_channel_count_fun)common_hal_audiomp3_mp3file_get_channel_count, .reset_buffer = (audiosample_reset_buffer_fun)audiomp3_mp3file_reset_buffer, .get_buffer = (audiosample_get_buffer_fun)audiomp3_mp3file_get_buffer, - .get_buffer_structure = (audiosample_get_buffer_structure_fun)audiomp3_mp3file_get_buffer_structure, }; MP_DEFINE_CONST_OBJ_TYPE( diff --git a/shared-bindings/audiomp3/MP3Decoder.h b/shared-bindings/audiomp3/MP3Decoder.h index 4381430c228..0b485b4bca1 100644 --- a/shared-bindings/audiomp3/MP3Decoder.h +++ b/shared-bindings/audiomp3/MP3Decoder.h @@ -19,10 +19,5 @@ void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t *self, void common_hal_audiomp3_mp3file_set_file(audiomp3_mp3file_obj_t *self, mp_obj_t stream); void common_hal_audiomp3_mp3file_deinit(audiomp3_mp3file_obj_t *self); -bool common_hal_audiomp3_mp3file_deinited(audiomp3_mp3file_obj_t *self); -uint32_t common_hal_audiomp3_mp3file_get_sample_rate(audiomp3_mp3file_obj_t *self); -void common_hal_audiomp3_mp3file_set_sample_rate(audiomp3_mp3file_obj_t *self, uint32_t sample_rate); -uint8_t common_hal_audiomp3_mp3file_get_bits_per_sample(audiomp3_mp3file_obj_t *self); -uint8_t common_hal_audiomp3_mp3file_get_channel_count(audiomp3_mp3file_obj_t *self); float common_hal_audiomp3_mp3file_get_rms_level(audiomp3_mp3file_obj_t *self); uint32_t common_hal_audiomp3_mp3file_get_samples_decoded(audiomp3_mp3file_obj_t *self); diff --git a/shared-bindings/audiopwmio/PWMAudioOut.c b/shared-bindings/audiopwmio/PWMAudioOut.c index deb60bd420e..5b8d071924b 100644 --- a/shared-bindings/audiopwmio/PWMAudioOut.c +++ b/shared-bindings/audiopwmio/PWMAudioOut.c @@ -23,7 +23,7 @@ //| left_channel: microcontroller.Pin, //| *, //| right_channel: Optional[microcontroller.Pin] = None, -//| quiescent_value: int = 0x8000 +//| quiescent_value: int = 0x8000, //| ) -> None: //| """Create a PWMAudioOut object associated with the given pin(s). This allows you to //| play audio signals out on the given pin(s). In contrast to mod:`audioio`, @@ -81,6 +81,7 @@ //| pass //| print("stopped")""" //| ... +//| static mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_left_channel, ARG_right_channel, ARG_quiescent_value }; static const mp_arg_t allowed_args[] = { @@ -99,8 +100,10 @@ static mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_ // create AudioOut object from the given pin // The object is created with a finaliser as some ports use these (rather than 'reset' functions) // to ensure resources are collected at interpreter shutdown. - audiopwmio_pwmaudioout_obj_t *self = mp_obj_malloc_with_finaliser(audiopwmio_pwmaudioout_obj_t, &audiopwmio_pwmaudioout_type); - common_hal_audiopwmio_pwmaudioout_construct(self, left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); + audiopwmio_pwmaudioout_obj_t *self = + mp_obj_malloc_with_finaliser(audiopwmio_pwmaudioout_obj_t, &audiopwmio_pwmaudioout_type); + common_hal_audiopwmio_pwmaudioout_construct(self, + left_channel_pin, right_channel_pin, args[ARG_quiescent_value].u_int); return MP_OBJ_FROM_PTR(self); } @@ -108,6 +111,7 @@ static mp_obj_t audiopwmio_pwmaudioout_make_new(const mp_obj_type_t *type, size_ //| def deinit(self) -> None: //| """Deinitialises the PWMAudioOut and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t audiopwmio_pwmaudioout_deinit(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_audiopwmio_pwmaudioout_deinit(self); @@ -123,18 +127,15 @@ static void check_for_deinit(audiopwmio_pwmaudioout_obj_t *self) { //| def __enter__(self) -> PWMAudioOut: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t audiopwmio_pwmaudioout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_audiopwmio_pwmaudioout_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiopwmio_pwmaudioout___exit___obj, 4, 4, audiopwmio_pwmaudioout_obj___exit__); +//| +// Provided by context manager helper. //| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: @@ -146,6 +147,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(audiopwmio_pwmaudioout___exit___obj, //| The sample itself should consist of 16 bit samples. Microcontrollers with a lower output //| resolution will use the highest order bits to output.""" //| ... +//| static mp_obj_t audiopwmio_pwmaudioout_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sample, ARG_loop }; static const mp_arg_t allowed_args[] = { @@ -167,6 +169,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(audiopwmio_pwmaudioout_play_obj, 1, audiopwmio_pwmaud //| def stop(self) -> None: //| """Stops playback and resets to the start of the sample.""" //| ... +//| static mp_obj_t audiopwmio_pwmaudioout_obj_stop(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -177,6 +180,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_stop_obj, audiopwmio_pwmaudioou //| playing: bool //| """True when an audio sample is being output even if `paused`. (read-only)""" +//| static mp_obj_t audiopwmio_pwmaudioout_obj_get_playing(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -190,6 +194,7 @@ MP_PROPERTY_GETTER(audiopwmio_pwmaudioout_playing_obj, //| def pause(self) -> None: //| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" //| ... +//| static mp_obj_t audiopwmio_pwmaudioout_obj_pause(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -205,6 +210,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_pause_obj, audiopwmio_pwmaudioo //| def resume(self) -> None: //| """Resumes sample playback after :py:func:`pause`.""" //| ... +//| static mp_obj_t audiopwmio_pwmaudioout_obj_resume(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -220,6 +226,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(audiopwmio_pwmaudioout_resume_obj, audiopwmio_pwmaudio //| paused: bool //| """True when playback is paused. (read-only)""" //| +//| static mp_obj_t audiopwmio_pwmaudioout_obj_get_paused(mp_obj_t self_in) { audiopwmio_pwmaudioout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -235,7 +242,7 @@ static const mp_rom_map_elem_t audiopwmio_pwmaudioout_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiopwmio_pwmaudioout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&audiopwmio_pwmaudioout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&audiopwmio_pwmaudioout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&audiopwmio_pwmaudioout_play_obj) }, { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&audiopwmio_pwmaudioout_stop_obj) }, { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&audiopwmio_pwmaudioout_pause_obj) }, diff --git a/shared-bindings/audiospeed/Resampler.c b/shared-bindings/audiospeed/Resampler.c new file mode 100644 index 00000000000..8abf52905d4 --- /dev/null +++ b/shared-bindings/audiospeed/Resampler.c @@ -0,0 +1,113 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared/runtime/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/audiospeed/Resampler.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/audiospeed/Resampler.h" + +//| class Resampler: +//| """Wraps an audio sample to match it to the destination sample rate.""" +//| +//| def __init__(self) -> None: +//| """Create a Resampler that wraps ``source``. +//| +//| :param audiosample source: The audio source to resample. +//| +//| Playing a wave file through a mixer with half the sample rate:: +//| +//| import board +//| import audiocore +//| import audiomixer +//| import audiospeed +//| import audioio +//| +//| wav = audiocore.WaveFile("sample.wav") +//| resampler = audiospeed.Resampler(wav) +//| mixer = audiomixer.Mixer( +//| channel_count=wav.channel_count, +//| bits_per_sample=wav.bits_per_sample, +//| sample_rate=wav.sample_rate // 2, +//| ) +//| audio = audioio.AudioOut(board.A0) +//| audio.play(mixer) +//| mixer.play(resampler) +//| """ +//| ... +//| +static mp_obj_t audiospeed_resampler_make_new(const mp_obj_type_t *type, + size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_source }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_source, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Validate source implements audiosample protocol + mp_obj_t source = args[ARG_source].u_obj; + audiosample_check(source); + + audiospeed_resampler_obj_t *self = mp_obj_malloc(audiospeed_resampler_obj_t, &audiospeed_resampler_type); + common_hal_audiospeed_resampler_construct(self, source); + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the Resampler and releases all memory resources for reuse.""" +//| ... +//| +static mp_obj_t audiospeed_resampler_deinit(mp_obj_t self_in) { + audiospeed_resampler_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiospeed_resampler_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiospeed_resampler_deinit_obj, audiospeed_resampler_deinit); + +//| rate: float +//| """Playback speed multiplier.""" +//| +static mp_obj_t audiospeed_resampler_obj_get_rate(mp_obj_t self_in) { + audiospeed_resampler_obj_t *self = MP_OBJ_TO_PTR(self_in); + audiosample_check_for_deinit(&self->base.base); + return common_hal_audiospeed_resampler_get_rate(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiospeed_resampler_get_rate_obj, audiospeed_resampler_obj_get_rate); + +MP_PROPERTY_GETTER(audiospeed_resampler_rate_obj, + (mp_obj_t)&audiospeed_resampler_get_rate_obj); + +static const mp_rom_map_elem_t audiospeed_resampler_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiospeed_resampler_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_rate), MP_ROM_PTR(&audiospeed_resampler_rate_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiospeed_resampler_locals_dict, audiospeed_resampler_locals_dict_table); + +static const audiosample_p_t audiospeed_resampler_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiospeed_resampler_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiospeed_resampler_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiospeed_resampler_type, + MP_QSTR_Resampler, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiospeed_resampler_make_new, + locals_dict, &audiospeed_resampler_locals_dict, + protocol, &audiospeed_resampler_proto + ); diff --git a/shared-bindings/audiospeed/Resampler.h b/shared-bindings/audiospeed/Resampler.h new file mode 100644 index 00000000000..7a744474bd1 --- /dev/null +++ b/shared-bindings/audiospeed/Resampler.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiospeed/Resampler.h" + +extern const mp_obj_type_t audiospeed_resampler_type; + +void common_hal_audiospeed_resampler_construct(audiospeed_resampler_obj_t *self, mp_obj_t source); +void common_hal_audiospeed_resampler_deinit(audiospeed_resampler_obj_t *self); + +mp_obj_t common_hal_audiospeed_resampler_get_rate(audiospeed_resampler_obj_t *self); + +void audiospeed_resampler_set_sample_rate(audiospeed_resampler_obj_t *self, uint32_t sample_rate); diff --git a/shared-bindings/audiospeed/SpeedChanger.c b/shared-bindings/audiospeed/SpeedChanger.c new file mode 100644 index 00000000000..bcac6b7ff20 --- /dev/null +++ b/shared-bindings/audiospeed/SpeedChanger.c @@ -0,0 +1,123 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared/runtime/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/audiospeed/SpeedChanger.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/audiospeed/__init__.h" +#include "shared-module/audiospeed/SpeedChanger.h" + +//| class SpeedChanger: +//| """Wraps an audio sample to play it back at a different speed. +//| +//| Uses nearest-neighbor resampling with a fixed-point phase accumulator +//| for CPU-efficient variable-speed playback.""" +//| +//| def __init__(self, source: circuitpython_typing.AudioSample, rate: float = 1.0) -> None: +//| """Create a SpeedChanger that wraps ``source``. +//| +//| :param audiosample source: The audio source to resample. +//| :param float rate: Playback speed multiplier. 1.0 = normal, 2.0 = double speed, +//| 0.5 = half speed. Must be positive. +//| +//| Playing a wave file at 1.5x speed:: +//| +//| import board +//| import audiocore +//| import audiospeed +//| import audioio +//| +//| wav = audiocore.WaveFile("drum.wav") +//| fast = audiospeed.SpeedChanger(wav, rate=1.5) +//| audio = audioio.AudioOut(board.A0) +//| audio.play(fast) +//| +//| # Change speed during playback: +//| fast.rate = 2.0 # double speed +//| fast.rate = 0.5 # half speed +//| """ +//| ... +//| +static mp_obj_t audiospeed_speedchanger_make_new(const mp_obj_type_t *type, + size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_source, ARG_rate }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_source, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_rate, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Validate source implements audiosample protocol + mp_obj_t source = args[ARG_source].u_obj; + audiosample_check(source); + + audiospeed_speedchanger_obj_t *self = mp_obj_malloc(audiospeed_speedchanger_obj_t, &audiospeed_speedchanger_type); + common_hal_audiospeed_speedchanger_construct(self, source, args[ARG_rate].u_obj); + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialises the SpeedChanger and releases all memory resources for reuse.""" +//| ... +//| +static mp_obj_t audiospeed_speedchanger_deinit(mp_obj_t self_in) { + audiospeed_speedchanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_audiospeed_speedchanger_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(audiospeed_speedchanger_deinit_obj, audiospeed_speedchanger_deinit); + +//| rate: float +//| """Playback speed multiplier. Can be changed during playback.""" +//| +static mp_obj_t audiospeed_speedchanger_obj_get_rate(mp_obj_t self_in) { + audiospeed_speedchanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + audiosample_check_for_deinit(&self->base); + return common_hal_audiospeed_speedchanger_get_rate(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(audiospeed_speedchanger_get_rate_obj, audiospeed_speedchanger_obj_get_rate); + +static mp_obj_t audiospeed_speedchanger_obj_set_rate(mp_obj_t self_in, mp_obj_t rate_obj) { + audiospeed_speedchanger_obj_t *self = MP_OBJ_TO_PTR(self_in); + audiosample_check_for_deinit(&self->base); + common_hal_audiospeed_speedchanger_set_rate(self, rate_obj); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(audiospeed_speedchanger_set_rate_obj, audiospeed_speedchanger_obj_set_rate); + +MP_PROPERTY_GETSET(audiospeed_speedchanger_rate_obj, + (mp_obj_t)&audiospeed_speedchanger_get_rate_obj, + (mp_obj_t)&audiospeed_speedchanger_set_rate_obj); + +static const mp_rom_map_elem_t audiospeed_speedchanger_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&audiospeed_speedchanger_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_rate), MP_ROM_PTR(&audiospeed_speedchanger_rate_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(audiospeed_speedchanger_locals_dict, audiospeed_speedchanger_locals_dict_table); + +static const audiosample_p_t audiospeed_speedchanger_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)audiospeed_speedchanger_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)audiospeed_speedchanger_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + audiospeed_speedchanger_type, + MP_QSTR_SpeedChanger, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, audiospeed_speedchanger_make_new, + locals_dict, &audiospeed_speedchanger_locals_dict, + protocol, &audiospeed_speedchanger_proto + ); diff --git a/shared-bindings/audiospeed/SpeedChanger.h b/shared-bindings/audiospeed/SpeedChanger.h new file mode 100644 index 00000000000..bc0b166b612 --- /dev/null +++ b/shared-bindings/audiospeed/SpeedChanger.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/audiospeed/SpeedChanger.h" + +extern const mp_obj_type_t audiospeed_speedchanger_type; + +void common_hal_audiospeed_speedchanger_construct(audiospeed_speedchanger_obj_t *self, + mp_obj_t source, mp_obj_t rate_obj); +void common_hal_audiospeed_speedchanger_deinit(audiospeed_speedchanger_obj_t *self); + +void common_hal_audiospeed_speedchanger_set_rate(audiospeed_speedchanger_obj_t *self, mp_obj_t rate_obj); +mp_obj_t common_hal_audiospeed_speedchanger_get_rate(audiospeed_speedchanger_obj_t *self); diff --git a/shared-bindings/audiospeed/__init__.c b/shared-bindings/audiospeed/__init__.c new file mode 100644 index 00000000000..3eca41e6467 --- /dev/null +++ b/shared-bindings/audiospeed/__init__.c @@ -0,0 +1,30 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/audiospeed/Resampler.h" +#include "shared-bindings/audiospeed/SpeedChanger.h" + +//| """Audio processing tools""" + +static const mp_rom_map_elem_t audiospeed_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_audiospeed) }, + { MP_ROM_QSTR(MP_QSTR_Resampler), MP_ROM_PTR(&audiospeed_resampler_type) }, + { MP_ROM_QSTR(MP_QSTR_SpeedChanger), MP_ROM_PTR(&audiospeed_speedchanger_type) }, +}; + +static MP_DEFINE_CONST_DICT(audiospeed_module_globals, audiospeed_module_globals_table); + +const mp_obj_module_t audiospeed_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&audiospeed_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_audiospeed, audiospeed_module); diff --git a/shared-bindings/audiospeed/__init__.h b/shared-bindings/audiospeed/__init__.h new file mode 100644 index 00000000000..c4a52e5819d --- /dev/null +++ b/shared-bindings/audiospeed/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/aurora_epaper/aurora_framebuffer.c b/shared-bindings/aurora_epaper/aurora_framebuffer.c index 0b15d45e7da..49e0b34a856 100644 --- a/shared-bindings/aurora_epaper/aurora_framebuffer.c +++ b/shared-bindings/aurora_epaper/aurora_framebuffer.c @@ -64,7 +64,7 @@ //| ) -> None: //| """Create a framebuffer for the Aurora CoG display. //| -//| .. note:: Displays of size 1.9" and 2.6" are not tested, and may exibit unexpected behavior. +//| .. note:: Displays of size 1.9" and 2.6" are not tested, and may exhibit unexpected behavior. //| //| :param busio.SPI spi_bus: The SPI bus that the display is connected to //| :param microcontroller.Pin chip_select: The pin connected to the displays chip select input @@ -77,6 +77,7 @@ //| :param bool free_bus: Determines whether the SPI bus passed in will be freed when the frame buffer is freed (optional). //| """ //| ... +//| static mp_obj_t aurora_epaper_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_spi_bus, ARG_chip_select, ARG_reset, ARG_busy, ARG_discharge, ARG_width, ARG_height, ARG_power, ARG_free_bus, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -124,6 +125,7 @@ static mp_int_t aurora_epaper_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer //| AuroraMemoryFramebuffer instance. After deinitialization, no further operations //| may be performed.""" //| ... +//| static mp_obj_t aurora_epaper_framebuffer_deinit(mp_obj_t self_in) { aurora_epaper_framebuffer_obj_t *self = (aurora_epaper_framebuffer_obj_t *)self_in; common_hal_aurora_epaper_framebuffer_deinit(self); @@ -137,6 +139,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(aurora_epaper_framebuffer_deinit_obj, aurora_ep //| Higher temperature means faster update speed. //| """ //| ... +//| static mp_obj_t aurora_epaper_frambuffer_set_temperature(mp_obj_t self_in, mp_obj_t temperature) { aurora_epaper_framebuffer_obj_t *self = (aurora_epaper_framebuffer_obj_t *)self_in; @@ -151,6 +154,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(aurora_epaper_frambuffer_set_temperature_obj, a //| If you have multiple displays this could be used to keep the other active on soft reset.""" //| ... //| +//| static mp_obj_t aurora_epaper_framebuffer_get_free_bus(mp_obj_t self_in) { aurora_epaper_framebuffer_obj_t *self = (aurora_epaper_framebuffer_obj_t *)self_in; return mp_obj_new_bool(self->free_bus); diff --git a/shared-bindings/bitbangio/I2C.c b/shared-bindings/bitbangio/I2C.c index 491833c27d4..e1413392699 100644 --- a/shared-bindings/bitbangio/I2C.c +++ b/shared-bindings/bitbangio/I2C.c @@ -22,11 +22,11 @@ //| //| def __init__( //| self, -//| scl: microcontroller.Pin, -//| sda: microcontroller.Pin, +//| scl: Union[microcontroller.Pin, digitalio.DigitalInOutProtocol], +//| sda: Union[microcontroller.Pin, digitalio.DigitalInOutProtocol], //| *, //| frequency: int = 400000, -//| timeout: int = 255 +//| timeout: int = 255, //| ) -> None: //| """I2C is a two-wire protocol for communicating between devices. At the //| physical level it consists of 2 wires: SCL and SDA, the clock and data @@ -40,11 +40,12 @@ //| bit unpacking. Instead, use an existing driver or make one with //| :ref:`Register ` data descriptors. //| -//| :param ~microcontroller.Pin scl: The clock pin -//| :param ~microcontroller.Pin sda: The data pin +//| :param ~microcontroller.Pin scl: The clock pin or DigitalInOut object +//| :param ~microcontroller.Pin sda: The data pin or DigitalInOut object //| :param int frequency: The clock frequency of the bus //| :param int timeout: The maximum clock stretching timeout in microseconds""" //| ... +//| static mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -56,17 +57,16 @@ static mp_obj_t bitbangio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl); - const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda); + bitbangio_i2c_obj_t *self = mp_obj_malloc_with_finaliser(bitbangio_i2c_obj_t, &bitbangio_i2c_type); + shared_module_bitbangio_i2c_construct(self, args[ARG_scl].u_obj, args[ARG_sda].u_obj, args[ARG_frequency].u_int, args[ARG_timeout].u_int); - bitbangio_i2c_obj_t *self = mp_obj_malloc(bitbangio_i2c_obj_t, &bitbangio_i2c_type); - shared_module_bitbangio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: //| """Releases control of the underlying hardware so other classes can use it.""" //| ... +//| static mp_obj_t bitbangio_i2c_obj_deinit(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); shared_module_bitbangio_i2c_deinit(self); @@ -83,18 +83,15 @@ static void check_for_deinit(bitbangio_i2c_obj_t *self) { //| def __enter__(self) -> I2C: //| """No-op used in Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware on context exit. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t bitbangio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - shared_module_bitbangio_i2c_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_i2c_obj___exit___obj, 4, 4, bitbangio_i2c_obj___exit__); +//| +// Provided by context manager helper. static void check_lock(bitbangio_i2c_obj_t *self) { if (!shared_module_bitbangio_i2c_has_lock(self)) { @@ -102,11 +99,30 @@ static void check_lock(bitbangio_i2c_obj_t *self) { } } +//| def probe(self, address: int) -> List[int]: +//| """Check if a device at the specified address responds. +//| +//| :param int address: 7-bit device address +//| :return: ``True`` if a device at ``address`` responds; ``False`` otherwise +//| :rtype: bool""" +//| ... +//| +static mp_obj_t bitbangio_i2c_probe(mp_obj_t self_in, mp_obj_t address_obj) { + bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + check_lock(self); + + const uint16_t addr = mp_obj_get_int(address_obj); + return mp_obj_new_bool(shared_module_bitbangio_i2c_probe(self, addr)); +} +MP_DEFINE_CONST_FUN_OBJ_2(bitbangio_i2c_probe_obj, bitbangio_i2c_probe); + //| def scan(self) -> List[int]: //| """Scan all I2C addresses between 0x08 and 0x77 inclusive and return a list of //| those that respond. A device responds if it pulls the SDA line low after //| its address (including a read bit) is sent on the bus.""" //| ... +//| static mp_obj_t bitbangio_i2c_scan(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -126,6 +142,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_scan_obj, bitbangio_i2c_scan); //| def try_lock(self) -> bool: //| """Attempts to grab the I2C lock. Returns True on success.""" //| ... +//| static mp_obj_t bitbangio_i2c_obj_try_lock(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -136,6 +153,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_try_lock_obj, bitbangio_i2c_obj_try_lock //| def unlock(self) -> None: //| """Releases the I2C lock.""" //| ... +//| static mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) { bitbangio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -145,6 +163,7 @@ static mp_obj_t bitbangio_i2c_obj_unlock(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); //| import sys +//| //| def readfrom_into( //| self, address: int, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize //| ) -> None: @@ -161,6 +180,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_i2c_unlock_obj, bitbangio_i2c_obj_unlock); //| :param int start: Index to start writing at //| :param int end: Index to write up to but not include""" //| ... +//| // Shared arg parsing for readfrom_into and writeto_then_readfrom. static void readfrom(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end) { mp_buffer_info_t bufinfo; @@ -202,6 +222,7 @@ static mp_obj_t bitbangio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_a MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 1, bitbangio_i2c_readfrom_into); //| import sys +//| //| def writeto( //| self, address: int, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize //| ) -> None: @@ -222,6 +243,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_readfrom_into_obj, 1, bitbangio_i2c_rea //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... +//| // Shared arg parsing for writeto and writeto_then_readfrom. static void writeto(bitbangio_i2c_obj_t *self, mp_int_t address, mp_obj_t buffer, int32_t start, mp_int_t end, bool stop) { // get the buffer to write the data from @@ -267,6 +289,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_obj, 1, bitbangio_i2c_wr //| import sys +//| //| def writeto_then_readfrom( //| self, //| address: int, @@ -276,7 +299,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_obj, 1, bitbangio_i2c_wr //| out_start: int = 0, //| out_end: int = sys.maxsize, //| in_start: int = 0, -//| in_end: int = sys.maxsize +//| in_end: int = sys.maxsize, //| ) -> None: //| """Write the bytes from ``out_buffer`` to the device selected by ``address``, generate no stop //| bit, generate a repeated start and read into ``in_buffer``. ``out_buffer`` and @@ -300,6 +323,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_obj, 1, bitbangio_i2c_wr //| """ //| ... //| +//| static mp_obj_t bitbangio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; static const mp_arg_t allowed_args[] = { @@ -329,7 +353,8 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_i2c_writeto_then_readfrom_obj, 1, bitbangio static const mp_rom_map_elem_t bitbangio_i2c_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bitbangio_i2c_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&bitbangio_i2c_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_probe), MP_ROM_PTR(&bitbangio_i2c_probe_obj) }, { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&bitbangio_i2c_scan_obj) }, { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&bitbangio_i2c_try_lock_obj) }, diff --git a/shared-bindings/bitbangio/I2C.h b/shared-bindings/bitbangio/I2C.h index 022be3692a6..cc9cd21b601 100644 --- a/shared-bindings/bitbangio/I2C.h +++ b/shared-bindings/bitbangio/I2C.h @@ -16,8 +16,8 @@ extern const mp_obj_type_t bitbangio_i2c_type; // Initializes the hardware peripheral. extern void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, - const mcu_pin_obj_t *scl, - const mcu_pin_obj_t *sda, + mp_obj_t scl, + mp_obj_t sda, uint32_t frequency, uint32_t us_timeout); diff --git a/shared-bindings/bitbangio/SPI.c b/shared-bindings/bitbangio/SPI.c index 62fb1e5a2b3..de021867f3c 100644 --- a/shared-bindings/bitbangio/SPI.c +++ b/shared-bindings/bitbangio/SPI.c @@ -33,9 +33,9 @@ //| //| def __init__( //| self, -//| clock: microcontroller.Pin, -//| MOSI: Optional[microcontroller.Pin] = None, -//| MISO: Optional[microcontroller.Pin] = None, +//| clock: Union[microcontroller.Pin, digitalio.DigitalInOutProtocol], +//| MOSI: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, +//| MISO: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, //| ) -> None: //| """Construct an SPI object on the given pins. //| @@ -48,10 +48,11 @@ //| :ref:`Register ` data descriptors. //| //| -//| :param ~microcontroller.Pin clock: the pin to use for the clock. -//| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin. -//| :param ~microcontroller.Pin MISO: the Main In Selected Out pin.""" +//| :param ~microcontroller.Pin clock: the pin to use for the clock or DigitalInOut object +//| :param ~microcontroller.Pin MOSI: the Main Out Selected In pin or DigitalInOut object +//| :param ~microcontroller.Pin MISO: the Main In Selected Out pin or DigitalInOut object""" //| ... +//| // TODO(tannewt): Support LSB SPI. static mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { @@ -64,18 +65,15 @@ static mp_obj_t bitbangio_spi_make_new(const mp_obj_type_t *type, size_t n_args, mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); - const mcu_pin_obj_t *mosi = validate_obj_is_free_pin_or_none(args[ARG_MOSI].u_obj, MP_QSTR_mosi); - const mcu_pin_obj_t *miso = validate_obj_is_free_pin_or_none(args[ARG_MISO].u_obj, MP_QSTR_miso); - bitbangio_spi_obj_t *self = mp_obj_malloc(bitbangio_spi_obj_t, &bitbangio_spi_type); - shared_module_bitbangio_spi_construct(self, clock, mosi, miso); - return (mp_obj_t)self; + shared_module_bitbangio_spi_construct(self, args[ARG_clock].u_obj, args[ARG_MOSI].u_obj, args[ARG_MISO].u_obj); + return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: //| """Turn off the SPI bus.""" //| ... +//| static mp_obj_t bitbangio_spi_obj_deinit(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); shared_module_bitbangio_spi_deinit(self); @@ -92,18 +90,15 @@ static void check_for_deinit(bitbangio_spi_obj_t *self) { //| def __enter__(self) -> SPI: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t bitbangio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - shared_module_bitbangio_spi_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(bitbangio_spi_obj___exit___obj, 4, 4, bitbangio_spi_obj___exit__); +//| +// Provided by context manager helper. static void check_lock(bitbangio_spi_obj_t *self) { @@ -123,6 +118,7 @@ static void check_lock(bitbangio_spi_obj_t *self) { //| or second (1). Rising or falling depends on clock polarity. //| :param int bits: the number of bits per word""" //| ... +//| static mp_obj_t bitbangio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; static const mp_arg_t allowed_args[] = { @@ -153,6 +149,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_configure_obj, 1, bitbangio_spi_configu //| :return: True when lock has been grabbed //| :rtype: bool""" //| ... +//| static mp_obj_t bitbangio_spi_obj_try_lock(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -163,6 +160,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_try_lock_obj, bitbangio_spi_obj_try_lock //| def unlock(self) -> None: //| """Releases the SPI lock.""" //| ... +//| static mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) { bitbangio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -172,6 +170,7 @@ static mp_obj_t bitbangio_spi_obj_unlock(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); //| import sys +//| //| def write(self, buf: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: //| """Write the data contained in ``buf``. Requires the SPI being locked. //| If the buffer is empty, nothing happens. @@ -185,6 +184,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(bitbangio_spi_unlock_obj, bitbangio_spi_obj_unlock); //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... +//| static mp_obj_t bitbangio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -224,13 +224,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_write_obj, 1, bitbangio_spi_write); //| import sys +//| //| def readinto( //| self, //| buffer: WriteableBuffer, //| *, //| start: int = 0, //| end: int = sys.maxsize, -//| write_value: int = 0 +//| write_value: int = 0, //| ) -> None: //| """Read into ``buffer`` while writing ``write_value`` for each byte read. //| The SPI object must be locked. @@ -246,6 +247,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_write_obj, 1, bitbangio_spi_write); //| :param int write_value: value to write while reading //| """ //| ... +//| static mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; static const mp_arg_t allowed_args[] = { @@ -285,6 +287,7 @@ static mp_obj_t bitbangio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_readinto_obj, 1, bitbangio_spi_readinto); //| import sys +//| //| def write_readinto( //| self, //| out_buffer: ReadableBuffer, @@ -293,7 +296,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_readinto_obj, 1, bitbangio_spi_readinto //| out_start: int = 0, //| out_end: int = sys.maxsize, //| in_start: int = 0, -//| in_end: int = sys.maxsize +//| in_end: int = sys.maxsize, //| ) -> None: //| """Write out the data in ``out_buffer`` while simultaneously reading data into ``in_buffer``. //| The SPI object must be locked. @@ -319,6 +322,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_readinto_obj, 1, bitbangio_spi_readinto //| """ //| ... //| +//| static mp_obj_t bitbangio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; static const mp_arg_t allowed_args[] = { @@ -378,7 +382,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitbangio_spi_write_readinto_obj, 1, bitbangio_spi_wr static const mp_rom_map_elem_t bitbangio_spi_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bitbangio_spi_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&bitbangio_spi_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&bitbangio_spi_configure_obj) }, { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&bitbangio_spi_try_lock_obj) }, diff --git a/shared-bindings/bitbangio/SPI.h b/shared-bindings/bitbangio/SPI.h index dbe821683b0..19ec05152ad 100644 --- a/shared-bindings/bitbangio/SPI.h +++ b/shared-bindings/bitbangio/SPI.h @@ -16,8 +16,7 @@ extern const mp_obj_type_t bitbangio_spi_type; // Construct an underlying SPI object. extern void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso); + mp_obj_t clock, mp_obj_t mosi, mp_obj_t miso); extern void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self); extern bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self); diff --git a/shared-bindings/bitmapfilter/__init__.c b/shared-bindings/bitmapfilter/__init__.c index 9a3c23c6a37..7c5344dde11 100644 --- a/shared-bindings/bitmapfilter/__init__.c +++ b/shared-bindings/bitmapfilter/__init__.c @@ -12,6 +12,7 @@ #include "shared-bindings/displayio/Palette.h" #include "shared-bindings/bitmapfilter/__init__.h" +//| //| //| def morph( //| bitmap: displayio.Bitmap, @@ -79,6 +80,7 @@ //| bitmapfilter.morph(bitmap, kernel_gauss_3, 1/sum(kernel_gauss_3)) //| """ //| +//| static mp_float_t get_m(mp_obj_t mul_obj, int sum) { @@ -165,6 +167,7 @@ static mp_float_t float_subscr(mp_obj_t o, int i) { //| The ``r`` parameter gives the scale factor for the red channel of //| pixels, and so forth.""" //| +//| static const mp_obj_namedtuple_type_t bitmapfilter_channel_scale_type = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_ChannelScale), .n_fields = 3, @@ -198,6 +201,7 @@ static const mp_obj_namedtuple_type_t bitmapfilter_channel_scale_type = { //| ) -> None: //| """Construct a ChannelScaleOffset object""" //| +//| static const mp_obj_namedtuple_type_t bitmapfilter_channel_scale_offset_type = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_ChannelScaleOffset), .n_fields = 6, @@ -253,6 +257,7 @@ static const mp_obj_namedtuple_type_t bitmapfilter_channel_scale_offset_type = { //| ) -> None: //| """Construct a ChannelMixer object""" //| +//| static const mp_obj_namedtuple_type_t bitmapfilter_channel_mixer_type = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_ChannelMixer), .n_fields = 9, @@ -305,6 +310,7 @@ static const mp_obj_namedtuple_type_t bitmapfilter_channel_mixer_type = { //| ) -> None: //| """Construct a ChannelMixerOffset object""" //| +//| static const mp_obj_namedtuple_type_t bitmapfilter_channel_mixer_offset_type = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_ChannelMixerOffset), .n_fields = 12, @@ -351,6 +357,7 @@ static const mp_obj_namedtuple_type_t bitmapfilter_channel_mixer_offset_type = { //| Only pixels set to a non-zero value in the mask are modified. //| """ //| +//| static mp_obj_t bitmapfilter_mix(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_weights, ARG_mask }; static const mp_arg_t allowed_args[] = { @@ -424,6 +431,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_mix_obj, 0, bitmapfilter_mix); //| PIL and ImageMagic both call this "solarize". //| """ //| +//| static mp_obj_t bitmapfilter_solarize(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_threshold, ARG_mask }; static const mp_arg_t allowed_args[] = { @@ -458,6 +466,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_solarize_obj, 0, bitmapfilter_solarize); //| ThreeLookupFunctions = Tuple[LookupFunction, LookupFunction, LookupFunction] //| """Any sequenceof three `LookupFunction` objects""" //| +//| //| def lookup( //| bitmap: displayio.Bitmap, //| lookup: LookupFunction | ThreeLookupFunctions, @@ -487,6 +496,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_solarize_obj, 0, bitmapfilter_solarize); //| Only pixels set to a non-zero value in the mask are modified. //| """ //| +//| static int scaled_lut(int maxval, mp_obj_t func, int i) { mp_obj_t obj = mp_call_function_1(func, mp_obj_new_float(i / (mp_float_t)maxval)); @@ -566,6 +576,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_lookup_obj, 0, bitmapfilter_lookup); //| Only pixels set to a non-zero value in the mask are modified. //| """ //| +//| static mp_obj_t bitmapfilter_false_color(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_palette, ARG_mask }; static const mp_arg_t allowed_args[] = { @@ -612,6 +623,7 @@ static uint8_t *get_blend_table(mp_obj_t lookup, int mode) { //| There is not actually a BlendTable type. The real type is actually any //| buffer 4096 bytes in length.""" //| +//| //| def blend_precompute(lookup: BlendFunction, table: BlendTable | None = None) -> BlendTable: //| """Precompute a BlendTable from a BlendFunction //| @@ -628,6 +640,7 @@ static uint8_t *get_blend_table(mp_obj_t lookup, int mode) { //| return a * .33 + b * .67 //| """ //| +//| static mp_obj_t blend_precompute(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_lookup, ARG_table }; static const mp_arg_t allowed_args[] = { @@ -652,6 +665,7 @@ static mp_obj_t blend_precompute(size_t n_args, const mp_obj_t *pos_args, mp_map } MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_blend_precompute_obj, 0, blend_precompute); +//| //| //| def blend( //| dest: displayio.Bitmap, @@ -673,6 +687,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmapfilter_blend_precompute_obj, 0, blend_precomput //| The destination bitmap is returned. //| """ //| +//| static mp_obj_t bitmapfilter_blend(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_dest, ARG_src1, ARG_src2, ARG_lookup, ARG_mask }; diff --git a/shared-bindings/bitmaptools/__init__.c b/shared-bindings/bitmaptools/__init__.c index de44b5164bb..a56075344e8 100644 --- a/shared-bindings/bitmaptools/__init__.c +++ b/shared-bindings/bitmaptools/__init__.c @@ -52,6 +52,7 @@ bitmaptools_rect_t bitmaptools_validate_coord_range_pair(const mp_arg_val_t in[4 //| for information about using the :py:mod:`displayio` module. //| """ //| +//| static int16_t validate_point(mp_obj_t point, int16_t default_value) { // Checks if point is None and returns default_value, otherwise decodes integer value @@ -141,7 +142,7 @@ static void validate_clip_region(displayio_bitmap_t *bitmap, mp_obj_t clip0_tupl //| source_clip1: Tuple[int, int], //| angle: float, //| scale: float, -//| skip_index: int +//| skip_index: int, //| ) -> None: //| """Inserts the source bitmap region into the destination bitmap with rotation //| (angle), scale and clipping (both on source and destination bitmaps). @@ -176,6 +177,7 @@ static void validate_clip_region(displayio_bitmap_t *bitmap, mp_obj_t clip0_tupl //| set to None to copy all pixels""" //| ... //| +//| static mp_obj_t bitmaptools_obj_rotozoom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_source_bitmap, ARG_ox, ARG_oy, ARG_dest_clip0, ARG_dest_clip1, @@ -183,8 +185,8 @@ static mp_obj_t bitmaptools_obj_rotozoom(size_t n_args, const mp_obj_t *pos_args ARG_angle, ARG_scale, ARG_skip_index}; static const mp_arg_t allowed_args[] = { - {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, {MP_QSTR_ox, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to destination->width / 2 {MP_QSTR_oy, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, // None convert to destination->height / 2 @@ -204,9 +206,9 @@ static mp_obj_t bitmaptools_obj_rotozoom(size_t n_args, const mp_obj_t *pos_args mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_dest_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap)); // the destination bitmap - displayio_bitmap_t *source = MP_OBJ_TO_PTR(args[ARG_source_bitmap].u_obj); // the source bitmap + displayio_bitmap_t *source = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_source_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_source_bitmap)); // the source bitmap // ensure that the destination bitmap has at least as many `bits_per_value` as the source if (destination->bits_per_value < source->bits_per_value) { @@ -284,6 +286,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_rotozoom_obj, 0, bitmaptools_obj_rotozoom //| Screen: BlendMode //| """Blend based on the value in each color channel. The result keeps the lighter colors and discards darker colors.""" //| +//| MAKE_ENUM_VALUE(bitmaptools_blendmode_type, bitmaptools_blendmode, Normal, BITMAPTOOLS_BLENDMODE_NORMAL); MAKE_ENUM_VALUE(bitmaptools_blendmode_type, bitmaptools_blendmode, Screen, BITMAPTOOLS_BLENDMODE_SCREEN); @@ -308,6 +311,7 @@ MAKE_ENUM_TYPE(bitmaptools, BlendMode, bitmaptools_blendmode); //| blendmode: Optional[BlendMode] = BlendMode.Normal, //| skip_source1_index: Union[int, None] = None, //| skip_source2_index: Union[int, None] = None, +//| mask: Optional[displayio.Bitmap] = None, //| ) -> None: //| """Alpha blend the two source bitmaps into the destination. //| @@ -323,13 +327,19 @@ MAKE_ENUM_TYPE(bitmaptools, BlendMode, bitmaptools_blendmode); //| :param bitmaptools.BlendMode blendmode: The blend mode to use. Default is Normal. //| :param int skip_source1_index: Bitmap palette or luminance index in source_bitmap_1 that will not be blended, set to None to blend all pixels //| :param int skip_source2_index: Bitmap palette or luminance index in source_bitmap_2 that will not be blended, set to None to blend all pixels +//| :param displayio.Bitmap mask: Optional 8-bits-per-value grayscale mask bitmap controlling per-pixel opacity of ``source_bitmap_2``. +//| The mask must have the same width and height as the other bitmaps and a ``bits_per_value`` of 8. A mask value of 0 +//| means ``source_bitmap_2`` is fully transparent at that pixel (only ``source_bitmap_1`` contributes); a value of 255 means +//| ``source_bitmap_2`` is fully opaque at that pixel (subject to ``factor2``). Intermediate values scale ``factor2`` linearly. +//| Pass ``None`` to disable per-pixel masking. //| //| For the L8 colorspace, the bitmaps must have a bits-per-value of 8. //| For the RGB colorspaces, they must have a bits-per-value of 16.""" //| +//| static mp_obj_t bitmaptools_alphablend(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum {ARG_dest_bitmap, ARG_source_bitmap_1, ARG_source_bitmap_2, ARG_colorspace, ARG_factor_1, ARG_factor_2, ARG_blendmode, ARG_skip_source1_index, ARG_skip_source2_index}; + enum {ARG_dest_bitmap, ARG_source_bitmap_1, ARG_source_bitmap_2, ARG_colorspace, ARG_factor_1, ARG_factor_2, ARG_blendmode, ARG_skip_source1_index, ARG_skip_source2_index, ARG_mask}; static const mp_arg_t allowed_args[] = { {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = NULL}}, @@ -341,6 +351,7 @@ static mp_obj_t bitmaptools_alphablend(size_t n_args, const mp_obj_t *pos_args, {MP_QSTR_blendmode, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = (void *)&bitmaptools_blendmode_Normal_obj}}, {MP_QSTR_skip_source1_index, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, {MP_QSTR_skip_source2_index, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + {MP_QSTR_mask, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -407,13 +418,64 @@ static mp_obj_t bitmaptools_alphablend(size_t n_args, const mp_obj_t *pos_args, skip_source2_index_none = false; } + displayio_bitmap_t *mask = NULL; + if (args[ARG_mask].u_obj != mp_const_none) { + mask = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_mask].u_obj, &displayio_bitmap_type, MP_QSTR_mask)); + if (mask->width != destination->width || mask->height != destination->height) { + mp_raise_ValueError(MP_ERROR_TEXT("Mask bitmap size must match the other bitmaps")); + } + if (mask->bits_per_value != 8) { + mp_raise_ValueError(MP_ERROR_TEXT("Mask bitmap must have 8 bits per pixel")); + } + } + common_hal_bitmaptools_alphablend(destination, source1, source2, colorspace, factor1, factor2, blendmode, skip_source1_index, - skip_source1_index_none, skip_source2_index, skip_source2_index_none); + skip_source1_index_none, skip_source2_index, skip_source2_index_none, mask); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_alphablend_obj, 0, bitmaptools_alphablend); +//| def replace_color( +//| dest_bitmap: displayio.Bitmap, old_color: int, new_color: int +//| ) -> None: +//| """Replace any pixels of ``old_color`` with ``new_color`` in the ``bitmap`` +//| +//| :param displayio.Bitmap bitmap: Bitmap that will be changed +//| :param int old_color: Bitmap palette index that will overwritten +//| :param int new_color: Bitmap palette index that will get put in the bitmap""" +//| ... +//| +//| +static mp_obj_t bitmaptools_obj_replace_color(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum {ARG_bitmap, ARG_old_color, ARG_new_color}; + + static const mp_arg_t allowed_args[] = { + {MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_old_color, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_new_color, MP_ARG_REQUIRED | MP_ARG_INT}, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_bitmap)); + + uint32_t old_color, new_color, color_depth; + old_color = args[ARG_old_color].u_int; + new_color = args[ARG_new_color].u_int; + + color_depth = (1 << destination->bits_per_value); + if (color_depth <= old_color || color_depth <= new_color) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q out of range"), MP_QSTR_color); + } + + common_hal_bitmaptools_replace_color(destination, old_color, new_color); + + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_replace_color_obj, 0, bitmaptools_obj_replace_color); + //| def fill_region( //| dest_bitmap: displayio.Bitmap, x1: int, y1: int, x2: int, y2: int, value: int //| ) -> None: @@ -429,18 +491,19 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_alphablend_obj, 0, bitmaptools_alphablend //| fill region in the destination bitmap""" //| ... //| +//| static mp_obj_t bitmaptools_obj_fill_region(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARGS_X1_Y1_X2_Y2, ARG_value}; static const mp_arg_t allowed_args[] = { - {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, ALLOWED_ARGS_X1_Y1_X2_Y2(MP_ARG_REQUIRED, MP_ARG_REQUIRED), - {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT}, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_dest_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap)); // the destination bitmap uint32_t value, color_depth; value = args[ARG_value].u_int; @@ -477,14 +540,15 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_fill_region_obj, 0, bitmaptools_obj_fill_ //| value color in the enclosed area in the destination bitmap""" //| ... //| +//| static mp_obj_t bitmaptools_obj_boundary_fill(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_x, ARG_y, ARG_fill_color_value, ARG_replaced_color_value}; static const mp_arg_t allowed_args[] = { - {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_fill_color_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_fill_color_value, MP_ARG_REQUIRED | MP_ARG_INT}, {MP_QSTR_replaced_color_value, MP_ARG_INT, {.u_int = INT_MAX} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -537,21 +601,22 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_boundary_fill_obj, 0, bitmaptools_obj_bou //| line in the destination bitmap""" //| ... //| +//| static mp_obj_t bitmaptools_obj_draw_line(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_value}; static const mp_arg_t allowed_args[] = { - {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_x1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_y1, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_x2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_y2, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_x1, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_y1, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_x2, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_y2, MP_ARG_REQUIRED | MP_ARG_INT}, + {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT}, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_dest_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap)); // the destination bitmap uint32_t value, color_depth; value = args[ARG_value].u_int; @@ -623,20 +688,21 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_line_obj, 0, bitmaptools_obj_draw_li //| """ //| ... //| +//| static mp_obj_t bitmaptools_obj_draw_polygon(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_xs, ARG_ys, ARG_value, ARG_close}; static const mp_arg_t allowed_args[] = { - {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_xs, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_ys, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, - {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL}}, + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_xs, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_ys, MP_ARG_REQUIRED | MP_ARG_OBJ}, + {MP_QSTR_value, MP_ARG_REQUIRED | MP_ARG_INT}, {MP_QSTR_close, MP_ARG_BOOL, {.u_bool = true}}, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_dest_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap)); // the destination bitmap mp_buffer_info_t xs_buf, ys_buf; mp_get_buffer_raise(args[ARG_xs].u_obj, &xs_buf, MP_BUFFER_READ); @@ -683,7 +749,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_polygon_obj, 0, bitmaptools_obj_draw //| available in the destination bitmap. //| //| If x1 or y1 are not specified, they are taken as 0. If x2 or y2 -//| are not specified, or are given as -1, they are taken as the width +//| are not specified, or are given as None, they are taken as the width //| and height of the image. //| //| The coordinates affected by the blit are ``x1 <= x < x2`` and ``y1 <= y < y2``. @@ -705,12 +771,13 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_polygon_obj, 0, bitmaptools_obj_draw //| """ //| ... //| +//| static mp_obj_t bitmaptools_arrayblit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_data, ARGS_X1_Y1_X2_Y2, ARG_skip_index }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - ALLOWED_ARGS_X1_Y1_X2_Y2(0, MP_ARG_REQUIRED), + { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, + ALLOWED_ARGS_X1_Y1_X2_Y2(0, 0), { MP_QSTR_skip_index, MP_ARG_OBJ, {.u_obj = mp_const_none } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -768,13 +835,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_arrayblit_obj, 0, bitmaptools_arrayblit); //| """ //| ... //| +//| static mp_obj_t bitmaptools_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_file, ARG_bits_per_pixel, ARG_element_size, ARG_reverse_pixels_in_element, ARG_swap_bytes_in_element, ARG_reverse_rows }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_file, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_bits_per_pixel, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_file, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_bits_per_pixel, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_element_size, MP_ARG_INT, { .u_int = 1 } }, { MP_QSTR_reverse_pixels_in_element, MP_ARG_BOOL, { .u_bool = false } }, { MP_QSTR_swap_bytes_in_element, MP_ARG_BOOL, { .u_bool = false } }, @@ -830,6 +898,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_readinto_obj, 0, bitmaptools_readinto); //| FloydStenberg: "DitherAlgorithm" //| """The Floyd-Stenberg dither""" //| +//| MAKE_ENUM_VALUE(bitmaptools_dither_algorithm_type, dither_algorithm, Atkinson, DITHER_ALGORITHM_ATKINSON); MAKE_ENUM_VALUE(bitmaptools_dither_algorithm_type, dither_algorithm, FloydStenberg, DITHER_ALGORITHM_FLOYD_STENBERG); @@ -858,12 +927,13 @@ MAKE_ENUM_TYPE(bitmaptools, DitherAlgorithm, bitmaptools_dither_algorithm); //| """ //| ... //| +//| static mp_obj_t bitmaptools_dither(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_dest_bitmap, ARG_source_bitmap, ARG_source_colorspace, ARG_algorithm }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_source_colorspace, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_source_colorspace, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_algorithm, MP_ARG_OBJ, { .u_obj = MP_ROM_PTR((void *)&dither_algorithm_Atkinson_obj) } }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -951,6 +1021,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_dither_obj, 0, bitmaptools_dither); //| //| ... //| +//| static mp_obj_t bitmaptools_obj_draw_circle(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_dest_bitmap, ARG_x, ARG_y, ARG_radius, ARG_value}; @@ -964,7 +1035,7 @@ static mp_obj_t bitmaptools_obj_draw_circle(size_t n_args, const mp_obj_t *pos_a mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - displayio_bitmap_t *destination = MP_OBJ_TO_PTR(args[ARG_dest_bitmap].u_obj); // the destination bitmap + displayio_bitmap_t *destination = MP_OBJ_TO_PTR(mp_arg_validate_type(args[ARG_dest_bitmap].u_obj, &displayio_bitmap_type, MP_QSTR_dest_bitmap)); // the destination bitmap uint32_t value, color_depth; value = args[ARG_value].u_int; @@ -1000,7 +1071,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_circle_obj, 0, bitmaptools_obj_draw_ //| x2: int | None = None, //| y2: int | None = None, //| skip_source_index: int | None = None, -//| skip_dest_index: int | None = None +//| skip_dest_index: int | None = None, //| ) -> None: //| """Inserts the source_bitmap region defined by rectangular boundaries //| (x1,y1) and (x2,y2) into the bitmap at the specified (x,y) location. @@ -1021,13 +1092,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(bitmaptools_draw_circle_obj, 0, bitmaptools_obj_draw_ //| by the pixels from the source""" //| ... //| +//| static mp_obj_t bitmaptools_obj_blit(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum {ARG_destination, ARG_source, ARG_x, ARG_y, ARG_x1, ARG_y1, ARG_x2, ARG_y2, ARG_skip_source_index, ARG_skip_dest_index}; static const mp_arg_t allowed_args[] = { - {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - {MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL} }, - {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT, {.u_obj = MP_OBJ_NULL} }, + {MP_QSTR_dest_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + {MP_QSTR_source_bitmap, MP_ARG_REQUIRED | MP_ARG_OBJ }, + {MP_QSTR_x, MP_ARG_REQUIRED | MP_ARG_INT }, + {MP_QSTR_y, MP_ARG_REQUIRED | MP_ARG_INT }, ALLOWED_ARGS_X1_Y1_X2_Y2(0, 0), {MP_QSTR_skip_source_index, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, {MP_QSTR_skip_dest_index, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, @@ -1089,6 +1161,7 @@ static const mp_rom_map_elem_t bitmaptools_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_rotozoom), MP_ROM_PTR(&bitmaptools_rotozoom_obj) }, { MP_ROM_QSTR(MP_QSTR_arrayblit), MP_ROM_PTR(&bitmaptools_arrayblit_obj) }, { MP_ROM_QSTR(MP_QSTR_alphablend), MP_ROM_PTR(&bitmaptools_alphablend_obj) }, + { MP_ROM_QSTR(MP_QSTR_replace_color), MP_ROM_PTR(&bitmaptools_replace_color_obj) }, { MP_ROM_QSTR(MP_QSTR_fill_region), MP_ROM_PTR(&bitmaptools_fill_region_obj) }, { MP_ROM_QSTR(MP_QSTR_boundary_fill), MP_ROM_PTR(&bitmaptools_boundary_fill_obj) }, { MP_ROM_QSTR(MP_QSTR_draw_line), MP_ROM_PTR(&bitmaptools_draw_line_obj) }, diff --git a/shared-bindings/bitmaptools/__init__.h b/shared-bindings/bitmaptools/__init__.h index 2d9b22e216e..20236983bac 100644 --- a/shared-bindings/bitmaptools/__init__.h +++ b/shared-bindings/bitmaptools/__init__.h @@ -42,6 +42,9 @@ void common_hal_bitmaptools_fill_region(displayio_bitmap_t *destination, int16_t x2, int16_t y2, uint32_t value); +void common_hal_bitmaptools_replace_color(displayio_bitmap_t *destination, + uint32_t old_color, uint32_t new_color); + void common_hal_bitmaptools_boundary_fill(displayio_bitmap_t *destination, int16_t x, int16_t y, uint32_t fill_color_value, uint32_t replaced_color_value); @@ -66,7 +69,8 @@ void common_hal_bitmaptools_arrayblit(displayio_bitmap_t *self, void *data, int void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bitmap_t *source_bitmap, displayio_colorspace_t colorspace, bitmaptools_dither_algorithm_t algorithm); void common_hal_bitmaptools_alphablend(displayio_bitmap_t *destination, displayio_bitmap_t *source1, displayio_bitmap_t *source2, displayio_colorspace_t colorspace, mp_float_t factor1, mp_float_t factor2, - bitmaptools_blendmode_t blendmode, uint32_t skip_source1_index, bool skip_source1_index_none, uint32_t skip_source2_index, bool skip_source2_index_none); + bitmaptools_blendmode_t blendmode, uint32_t skip_source1_index, bool skip_source1_index_none, uint32_t skip_source2_index, bool skip_source2_index_none, + displayio_bitmap_t *mask); typedef struct { union { @@ -80,8 +84,8 @@ typedef struct { #define ARGS_X1_Y1_X2_Y2 ARG_x1, ARG_y1, ARG_x2, ARG_y2 #define ALLOWED_ARGS_X1_Y1_X2_Y2(if_required1, if_required2) \ {MP_QSTR_x1, if_required1 | MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0)}}, \ - {MP_QSTR_y1, if_required2 | MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0)}}, \ - {MP_QSTR_x2, if_required1 | MP_ARG_OBJ, {.u_obj = MP_ROM_NONE}}, \ + {MP_QSTR_y1, if_required1 | MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0)}}, \ + {MP_QSTR_x2, if_required2 | MP_ARG_OBJ, {.u_obj = MP_ROM_NONE}}, \ {MP_QSTR_y2, if_required2 | MP_ARG_OBJ, {.u_obj = MP_ROM_NONE}} bitmaptools_rect_t bitmaptools_validate_coord_range_pair(const mp_arg_val_t in[4], int width, int height); diff --git a/shared-bindings/bitops/__init__.c b/shared-bindings/bitops/__init__.c index dc07436866a..088aa260e97 100644 --- a/shared-bindings/bitops/__init__.c +++ b/shared-bindings/bitops/__init__.c @@ -11,6 +11,7 @@ //| """Routines for low-level manipulation of binary data""" //| +//| //| def bit_transpose( //| input: ReadableBuffer, output: WriteableBuffer, width: int = 8 @@ -35,6 +36,7 @@ //| Returns the output buffer.""" //| ... //| +//| static mp_obj_t bit_transpose(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_input, ARG_output, ARG_width }; diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c index 1a2721a91c4..c985d852175 100644 --- a/shared-bindings/board/__init__.c +++ b/shared-bindings/board/__init__.c @@ -33,12 +33,14 @@ //| //| .. warning:: The board module varies by board. The APIs documented here may or may not be //| available on a specific board.""" +//| //| board_id: str //| """Board ID string. The unique identifier for the board model in //| circuitpython, as well as on circuitpython.org. //| Example: "hallowing_m0_express".""" //| +//| //| def I2C() -> busio.I2C: //| """Returns the `busio.I2C` object for the board's designated I2C bus(es). @@ -46,6 +48,7 @@ //| """ //| ... //| +//| #if CIRCUITPY_BOARD_I2C static mp_obj_t board_i2c_0(void) { return common_hal_board_create_i2c(0); @@ -64,6 +67,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c_0); //| """ //| ... //| +//| #if CIRCUITPY_BOARD_SPI static mp_obj_t board_spi_0(void) { return common_hal_board_create_spi(0); @@ -82,6 +86,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi_0); //| """ //| ... //| +//| #if CIRCUITPY_BOARD_UART static mp_obj_t board_uart_0(void) { return common_hal_board_create_uart(0); diff --git a/shared-bindings/board/__init__.h b/shared-bindings/board/__init__.h index 7c9a59d2dbd..43343099730 100644 --- a/shared-bindings/board/__init__.h +++ b/shared-bindings/board/__init__.h @@ -11,22 +11,23 @@ #include "shared-bindings/microcontroller/Pin.h" // for the pin definitions +#if CIRCUITPY_MUTABLE_BOARD +extern mp_obj_dict_t board_module_globals; +#else extern const mp_obj_dict_t board_module_globals; +#endif static const MP_DEFINE_STR_OBJ(board_module_id_obj, CIRCUITPY_BOARD_ID); -bool common_hal_board_is_i2c(mp_obj_t obj); mp_obj_t common_hal_board_get_i2c(const mp_int_t instance); mp_obj_t common_hal_board_create_i2c(const mp_int_t instance); mp_obj_t board_i2c(size_t n_args, const mp_obj_t *args); MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj); -bool common_hal_board_is_spi(mp_obj_t obj); mp_obj_t common_hal_board_get_spi(const mp_int_t instance); mp_obj_t common_hal_board_create_spi(const mp_int_t instance); mp_obj_t board_spi(size_t n_args, const mp_obj_t *args); MP_DECLARE_CONST_FUN_OBJ_0(board_spi_obj); -bool common_hal_board_is_uart(mp_obj_t obj); mp_obj_t common_hal_board_get_uart(const mp_int_t instance); mp_obj_t common_hal_board_create_uart(const mp_int_t instance); mp_obj_t board_uart(size_t n_args, const mp_obj_t *args); @@ -41,3 +42,7 @@ MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj); #define CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS \ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_board) }, \ { MP_ROM_QSTR(MP_QSTR_board_id), MP_ROM_PTR(&board_module_id_obj) }, + +#define CIRCUITPYTHON_MUTABLE_BOARD_DICT_STANDARD_ITEMS \ + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_board) }, \ + { MP_ROM_QSTR(MP_QSTR_board_id), MP_OBJ_FROM_PTR(&board_module_id_obj) }, diff --git a/shared-bindings/busdisplay/BusDisplay.c b/shared-bindings/busdisplay/BusDisplay.c index 1b9a1a70c7e..0bf171a5d08 100644 --- a/shared-bindings/busdisplay/BusDisplay.c +++ b/shared-bindings/busdisplay/BusDisplay.c @@ -28,6 +28,7 @@ //| ] //| """:py:class:`fourwire.FourWire`, :py:class:`paralleldisplaybus.ParallelBus` or :py:class:`i2cdisplaybus.I2CDisplayBus`""" //| +//| //| class BusDisplay: //| """Manage updating a display over a display bus @@ -65,7 +66,7 @@ //| auto_refresh: bool = True, //| native_frames_per_second: int = 60, //| backlight_on_high: bool = True, -//| SH1107_addressing: bool = False +//| SH1107_addressing: bool = False, //| ) -> None: //| r"""Create a Display object on the given display bus (`FourWire`, `paralleldisplaybus.ParallelBus` or `I2CDisplayBus`). //| @@ -99,8 +100,8 @@ //| :param ~circuitpython_typing.ReadableBuffer init_sequence: Byte-packed initialization sequence. //| :param int width: Width in pixels //| :param int height: Height in pixels -//| :param int colstart: The index if the first visible column -//| :param int rowstart: The index if the first visible row +//| :param int colstart: The index of the first visible column +//| :param int rowstart: The index of the first visible row //| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) //| :param int color_depth: The number of bits of color per pixel transmitted. (Some displays //| support 18 bit but 16 is easier to transmit. The last bit is extrapolated.) @@ -121,17 +122,17 @@ //| :param int native_frames_per_second: Number of display refreshes per second that occur with the given init_sequence. //| :param bool backlight_on_high: If True, pulling the backlight pin high turns the backlight on. //| :param bool SH1107_addressing: Special quirk for SH1107, use upper/lower column set and page set -//| :param int set_vertical_scroll: This parameter is accepted but ignored for backwards compatibility. It will be removed in a future release. //| :param int backlight_pwm_frequency: The frequency to use to drive the PWM for backlight brightness control. Default is 50000. //| """ //| ... +//| static mp_obj_t busdisplay_busdisplay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_color_depth, ARG_grayscale, ARG_pixels_in_byte_share_row, ARG_bytes_per_cell, ARG_reverse_pixels_in_byte, ARG_reverse_bytes_in_word, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command, - ARG_set_vertical_scroll, ARG_backlight_pin, ARG_brightness_command, + ARG_backlight_pin, ARG_brightness_command, ARG_brightness, ARG_single_byte_bounds, ARG_data_as_commands, ARG_auto_refresh, ARG_native_frames_per_second, ARG_backlight_on_high, ARG_SH1107_addressing, ARG_backlight_pwm_frequency }; @@ -152,7 +153,6 @@ static mp_obj_t busdisplay_busdisplay_make_new(const mp_obj_type_t *type, size_t { MP_QSTR_set_column_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2a} }, { MP_QSTR_set_row_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2b} }, { MP_QSTR_write_ram_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x2c} }, - { MP_QSTR_set_vertical_scroll, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x0} }, { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_brightness_command, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = NO_BRIGHTNESS_COMMAND} }, { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, @@ -236,7 +236,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(busdisplay_busdisplay_show_obj, busdisplay_busdisplay_ //| self, //| *, //| target_frames_per_second: Optional[int] = None, -//| minimum_frames_per_second: int = 0 +//| minimum_frames_per_second: int = 0, //| ) -> bool: //| """When auto_refresh is off, and :py:attr:`target_frames_per_second` is not `None` this waits //| for the target frame rate and then refreshes the display, @@ -258,6 +258,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(busdisplay_busdisplay_show_obj, busdisplay_busdisplay_ //| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. //| """ //| ... +//| static mp_obj_t busdisplay_busdisplay_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; static const mp_arg_t allowed_args[] = { @@ -395,6 +396,7 @@ MP_PROPERTY_GETTER(busdisplay_busdisplay_bus_obj, //| If the root group is set to `displayio.CIRCUITPYTHON_TERMINAL`, the default CircuitPython terminal will be shown. //| If the root group is set to ``None``, no output will be shown. //| """ +//| static mp_obj_t busdisplay_busdisplay_obj_get_root_group(mp_obj_t self_in) { busdisplay_busdisplay_obj_t *self = native_display(self_in); return common_hal_busdisplay_busdisplay_get_root_group(self); @@ -426,6 +428,7 @@ MP_PROPERTY_GETSET(busdisplay_busdisplay_root_group_obj, //| """ //| ... //| +//| static mp_obj_t busdisplay_busdisplay_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_y, ARG_buffer }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c index 8a1b832a7a8..5fa62f9df38 100644 --- a/shared-bindings/busio/I2C.c +++ b/shared-bindings/busio/I2C.c @@ -25,7 +25,7 @@ //| sda: microcontroller.Pin, //| *, //| frequency: int = 100000, -//| timeout: int = 255 +//| timeout: int = 255, //| ) -> None: //| """I2C is a two-wire protocol for communicating between devices. At the //| physical level it consists of 2 wires: SCL and SDA, the clock and data @@ -39,16 +39,19 @@ //| bit unpacking. Instead, use an existing driver or make one with //| :ref:`Register ` data descriptors. //| +//| .. seealso:: This class provides an I2C controller, which controls I2C targets (peripherals). +//| To act as an I2C target, use `i2ctarget.I2CTarget`. +//| //| :param ~microcontroller.Pin scl: The clock pin //| :param ~microcontroller.Pin sda: The data pin //| :param int frequency: The clock frequency in Hertz -//| :param int timeout: The maximum clock stretching timeut - (used only for +//| :param int timeout: The maximum clock stretching timeout - (used only for //| :class:`bitbangio.I2C`; ignored for :class:`busio.I2C`) //| """ //| ... +//| static mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BUSIO_I2C - busio_i2c_obj_t *self = mp_obj_malloc(busio_i2c_obj_t, &busio_i2c_type); enum { ARG_scl, ARG_sda, ARG_frequency, ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -62,8 +65,9 @@ static mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz const mcu_pin_obj_t *scl = validate_obj_is_free_pin(args[ARG_scl].u_obj, MP_QSTR_scl); const mcu_pin_obj_t *sda = validate_obj_is_free_pin(args[ARG_sda].u_obj, MP_QSTR_sda); + busio_i2c_obj_t *self = mp_obj_malloc_with_finaliser(busio_i2c_obj_t, &busio_i2c_type); common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int, args[ARG_timeout].u_int); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); #else mp_raise_NotImplementedError(NULL); #endif // CIRCUITPY_BUSIO_I2C @@ -74,6 +78,7 @@ static mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, siz //| def deinit(self) -> None: //| """Releases control of the underlying hardware so other classes can use it.""" //| ... +//| static mp_obj_t busio_i2c_obj_deinit(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_busio_i2c_deinit(self); @@ -90,26 +95,41 @@ static void check_for_deinit(busio_i2c_obj_t *self) { //| def __enter__(self) -> I2C: //| """No-op used in Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware on context exit. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t busio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_busio_i2c_deinit(MP_OBJ_TO_PTR(args[0])); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_i2c___exit___obj, 4, 4, busio_i2c_obj___exit__); +//| +// Provided by context manager helper. static void check_lock(busio_i2c_obj_t *self) { - asm (""); + __asm__ (""); if (!common_hal_busio_i2c_has_lock(self)) { mp_raise_RuntimeError(MP_ERROR_TEXT("Function requires lock")); } } +//| def probe(self, address: int) -> bool: +//| """Check if a device at the specified address responds. +//| +//| :param int address: 7-bit device address +//| :return: ``True`` if a device at ``address`` responds; ``False`` otherwise +//| :rtype: bool""" +//| ... +//| +static mp_obj_t busio_i2c_probe(mp_obj_t self_in, mp_obj_t address_obj) { + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + check_lock(self); + + const uint16_t addr = mp_obj_get_int(address_obj); + return mp_obj_new_bool(common_hal_busio_i2c_probe(self, addr)); +} +MP_DEFINE_CONST_FUN_OBJ_2(busio_i2c_probe_obj, busio_i2c_probe); + //| def scan(self) -> List[int]: //| """Scan all I2C addresses between 0x08 and 0x77 inclusive and return a //| list of those that respond. @@ -117,6 +137,7 @@ static void check_lock(busio_i2c_obj_t *self) { //| :return: List of device ids on the I2C bus //| :rtype: list""" //| ... +//| static mp_obj_t busio_i2c_scan(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -139,6 +160,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan); //| :return: True when lock has been grabbed //| :rtype: bool""" //| ... +//| static mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -149,6 +171,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock); //| def unlock(self) -> None: //| """Releases the I2C lock.""" //| ... +//| static mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -158,6 +181,7 @@ static mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); //| import sys +//| //| def readfrom_into( //| self, address: int, buffer: WriteableBuffer, *, start: int = 0, end: int = sys.maxsize //| ) -> None: @@ -173,6 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); //| :param int start: beginning of buffer slice //| :param int end: end of buffer slice; if not specified, use ``len(buffer)``""" //| ... +//| static mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -203,10 +228,10 @@ static mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, start *= stride_in_bytes; length *= stride_in_bytes; - uint8_t status = + mp_negative_errno_t status = common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); if (status != 0) { - mp_raise_OSError(status); + mp_raise_OSError(-status); } return mp_const_none; @@ -214,6 +239,7 @@ static mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 1, busio_i2c_readfrom_into); //| import sys +//| //| def writeto( //| self, address: int, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize //| ) -> None: @@ -233,6 +259,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 1, busio_i2c_readfrom_in //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... +//| static mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; static const mp_arg_t allowed_args[] = { @@ -263,11 +290,11 @@ static mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma length *= stride_in_bytes; // do the transfer - uint8_t status = + mp_negative_errno_t status = common_hal_busio_i2c_write(self, args[ARG_address].u_int, ((uint8_t *)bufinfo.buf) + start, length); if (status != 0) { - mp_raise_OSError(status); + mp_raise_OSError(-status); } return mp_const_none; @@ -275,6 +302,7 @@ static mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_ma static MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); //| import sys +//| //| def writeto_then_readfrom( //| self, //| address: int, @@ -284,7 +312,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); //| out_start: int = 0, //| out_end: int = sys.maxsize, //| in_start: int = 0, -//| in_end: int = sys.maxsize +//| in_end: int = sys.maxsize, //| ) -> None: //| """Write the bytes from ``out_buffer`` to the device selected by ``address``, generate no stop //| bit, generate a repeated start and read into ``in_buffer``. ``out_buffer`` and @@ -308,6 +336,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); //| """ //| ... //| +//| static mp_obj_t busio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_address, ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; static const mp_arg_t allowed_args[] = { @@ -348,10 +377,10 @@ static mp_obj_t busio_i2c_writeto_then_readfrom(size_t n_args, const mp_obj_t *p in_start *= in_stride_in_bytes; in_length *= in_stride_in_bytes; - uint8_t status = common_hal_busio_i2c_write_read(self, args[ARG_address].u_int, + mp_negative_errno_t status = common_hal_busio_i2c_write_read(self, args[ARG_address].u_int, ((uint8_t *)out_bufinfo.buf) + out_start, out_length, ((uint8_t *)in_bufinfo.buf) + in_start, in_length); if (status != 0) { - mp_raise_OSError(status); + mp_raise_OSError(-status); } return mp_const_none; @@ -362,8 +391,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_then_readfrom_obj, 1, busio_i2c_wri static const mp_rom_map_elem_t busio_i2c_locals_dict_table[] = { #if CIRCUITPY_BUSIO_I2C { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_i2c_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&busio_i2c_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_i2c___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_probe), MP_ROM_PTR(&busio_i2c_probe_obj) }, { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&busio_i2c_scan_obj) }, { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&busio_i2c_try_lock_obj) }, diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h index da505436b08..2978a907544 100644 --- a/shared-bindings/busio/I2C.h +++ b/shared-bindings/busio/I2C.h @@ -7,6 +7,7 @@ #pragma once #include "py/obj.h" +#include "py/mperrno.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/busio/I2C.h" @@ -19,11 +20,15 @@ extern void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t *scl, const mcu_pin_obj_t *sda, uint32_t frequency, - uint32_t timeout); + uint32_t timeout_ms); extern void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self); extern bool common_hal_busio_i2c_deinited(busio_i2c_obj_t *self); +// Mark as deinit without deiniting. This is used by displayio after copying the +// object elsewhere and prevents the heap from deiniting the object. +extern void common_hal_busio_i2c_mark_deinit(busio_i2c_obj_t *self); + extern bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self); extern bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self); extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self); @@ -31,17 +36,17 @@ extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self); // Probe the bus to see if a device acknowledges the given address. extern bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr); -// Write to the device and return 0 on success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, +// Write to the device and return 0 on success or a negative error code from mperrno.h +extern mp_negative_errno_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, const uint8_t *data, size_t len); // Reads memory of the i2c device picking up where it left off and return 0 on -// success or an appropriate error code from mperrno.h -extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, +// success or a negative error code from mperrno.h +extern mp_negative_errno_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *data, size_t len); // Do a write and then a read in the same I2C transaction. -uint8_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t address, +mp_negative_errno_t common_hal_busio_i2c_write_read(busio_i2c_obj_t *self, uint16_t address, uint8_t *out_data, size_t out_len, uint8_t *in_data, size_t in_len); // This is used by the supervisor to claim I2C devices indefinitely. diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c index 2e52486cabe..6ff74880266 100644 --- a/shared-bindings/busio/SPI.c +++ b/shared-bindings/busio/SPI.c @@ -9,17 +9,17 @@ #include +#include "py/binary.h" +#include "py/mperrno.h" +#include "py/objproperty.h" +#include "py/runtime.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/util.h" - #include "shared/runtime/buffer_helper.h" #include "shared/runtime/context_manager_helpers.h" -#include "py/binary.h" -#include "py/mperrno.h" -#include "py/objproperty.h" -#include "py/runtime.h" - +#include "shared/runtime/interrupt_char.h" +#include "supervisor/shared/tick.h" //| class SPI: //| """A 3-4 wire serial protocol @@ -28,7 +28,7 @@ //| main device. It is typically faster than :py:class:`~bitbangio.I2C` because a //| separate pin is used to select a device rather than a transmitted //| address. This class only manages three of the four SPI lines: `!clock`, -//| `!MOSI`, `!MISO`. Its up to the client to manage the appropriate +//| `!MOSI`, `!MISO`. It is up to the client to manage the appropriate //| select line, often abbreviated `!CS` or `!SS`. (This is common because //| multiple secondaries can share the `!clock`, `!MOSI` and `!MISO` lines //| and therefore the hardware.) @@ -46,6 +46,8 @@ //| //|

//| +//| .. seealso:: This class acts as an SPI main (controller). +//| To act as an SPI secondary (target), use `spitarget.SPITarget`. //| """ //| //| def __init__( @@ -80,18 +82,18 @@ //| **Limitations:** ``half_duplex`` is available only on STM; other chips do not have the hardware support. //| """ //| ... +//| // TODO(tannewt): Support LSB SPI. static mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_BUSIO_SPI - busio_spi_obj_t *self = mp_obj_malloc(busio_spi_obj_t, &busio_spi_type); enum { ARG_clock, ARG_MOSI, ARG_MISO, ARG_half_duplex }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_half_duplex, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_half_duplex, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, }; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -104,6 +106,7 @@ static mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz mp_raise_ValueError(MP_ERROR_TEXT("Must provide MISO or MOSI pin")); } + busio_spi_obj_t *self = mp_obj_malloc_with_finaliser(busio_spi_obj_t, &busio_spi_type); common_hal_busio_spi_construct(self, clock, mosi, miso, args[ARG_half_duplex].u_bool); return MP_OBJ_FROM_PTR(self); #else @@ -115,6 +118,7 @@ static mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, siz //| def deinit(self) -> None: //| """Turn off the SPI bus.""" //| ... +//| static mp_obj_t busio_spi_obj_deinit(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_busio_spi_deinit(self); @@ -126,20 +130,17 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit); //| """No-op used by Context Managers. //| Provided by context manager helper.""" //| ... +//| //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_busio_spi_deinit(MP_OBJ_TO_PTR(args[0])); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_spi_obj___exit___obj, 4, 4, busio_spi_obj___exit__); +//| +// Provided by context manager helper. static void check_lock(busio_spi_obj_t *self) { - asm (""); + __asm__ (""); if (!common_hal_busio_spi_has_lock(self)) { mp_raise_RuntimeError(MP_ERROR_TEXT("Function requires lock")); } @@ -156,9 +157,12 @@ static void check_for_deinit(busio_spi_obj_t *self) { //| ) -> None: //| """Configures the SPI bus. The SPI object must be locked. //| -//| :param int baudrate: the desired clock rate in Hertz. The actual clock rate may be higher or lower -//| due to the granularity of available clock settings. +//| :param int baudrate: the desired clock rate in Hertz. The value is treated as a ceiling: +//| the actual clock rate may be lower due to the granularity of available clock settings, +//| but it will not exceed the given value. //| Check the `frequency` attribute for the actual clock rate. +//| **Limitations**: On Zephyr, the ceiling behavior may be violated, and +//| the `frequency` value does not reflect the actual baudrate. //| :param int polarity: the base state of the clock line (0 or 1) //| :param int phase: the edge of the clock that data is captured. First (0) //| or second (1). Rising or falling depends on clock polarity. @@ -167,14 +171,9 @@ static void check_for_deinit(busio_spi_obj_t *self) { //| .. note:: On the SAMD21, it is possible to set the baudrate to 24 MHz, but that //| speed is not guaranteed to work. 12 MHz is the next available lower speed, and is //| within spec for the SAMD21. -//| -//| .. note:: On the nRF52840, these baudrates are available: 125kHz, 250kHz, 1MHz, 2MHz, 4MHz, -//| and 8MHz. -//| If you pick a a baudrate other than one of these, the nearest lower -//| baudrate will be chosen, with a minimum of 125kHz. -//| Two SPI objects may be created, except on the Circuit Playground Bluefruit, -//| which allows only one (to allow for an additional I2C object).""" +//| """ //| ... +//| static mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; @@ -208,6 +207,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure); //| :return: True when lock has been grabbed //| :rtype: bool""" //| ... +//| static mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -218,6 +218,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock); //| def unlock(self) -> None: //| """Releases the SPI lock.""" //| ... +//| static mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) { busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -228,6 +229,7 @@ static mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); //| import sys +//| //| def write(self, buffer: ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) -> None: //| """Write the data contained in ``buffer``. The SPI object must be locked. //| If the buffer is empty, nothing happens. @@ -241,6 +243,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); //| :param int end: end of buffer slice; if not specified, use ``len(buffer)`` //| """ //| ... +//| static mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end }; @@ -281,13 +284,14 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 1, busio_spi_write); //| import sys +//| //| def readinto( //| self, //| buffer: WriteableBuffer, //| *, //| start: int = 0, //| end: int = sys.maxsize, -//| write_value: int = 0 +//| write_value: int = 0, //| ) -> None: //| """Read into ``buffer`` while writing ``write_value`` for each byte read. //| The SPI object must be locked. @@ -305,6 +309,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 1, busio_spi_write); //| :param int write_value: value to write while reading //| """ //| ... +//| static mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; @@ -345,6 +350,7 @@ static mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_m MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 1, busio_spi_readinto); //| import sys +//| //| def write_readinto( //| self, //| out_buffer: ReadableBuffer, @@ -353,7 +359,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 1, busio_spi_readinto); //| out_start: int = 0, //| out_end: int = sys.maxsize, //| in_start: int = 0, -//| in_end: int = sys.maxsize +//| in_end: int = sys.maxsize, //| ) -> None: //| """Write out the data in ``out_buffer`` while simultaneously reading data into ``in_buffer``. //| The SPI object must be locked. @@ -378,6 +384,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 1, busio_spi_readinto); //| :param int in_end: end of ``in_buffer slice``; if not specified, use ``len(in_buffer)`` //| """ //| ... +//| static mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_out_buffer, ARG_in_buffer, ARG_out_start, ARG_out_end, ARG_in_start, ARG_in_end }; @@ -435,8 +442,14 @@ static mp_obj_t busio_spi_write_readinto(size_t n_args, const mp_obj_t *pos_args MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_readinto_obj, 1, busio_spi_write_readinto); //| frequency: int -//| """The actual SPI bus frequency. This may not match the frequency requested -//| due to internal limitations.""" +//| """The actual SPI bus frequency. This may be lower than the frequency requested +//| due to internal limitations, but it will not be higher. +//| +//| **Limitations**: On Zephyr, the returned value does not reflect the actual baudrate, +//| because there is `no way to fetch the actual chosen frequency +//| `_. +//| In addition, on Zephyr, the ceiling behavior described in `configure` may be violated. +//| """ //| static mp_obj_t busio_spi_obj_get_frequency(mp_obj_t self_in) { @@ -448,14 +461,16 @@ MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_get_frequency_obj, busio_spi_obj_get_frequen MP_PROPERTY_GETTER(busio_spi_frequency_obj, (mp_obj_t)&busio_spi_get_frequency_obj); + #endif // CIRCUITPY_BUSIO_SPI static const mp_rom_map_elem_t busio_spi_locals_dict_table[] = { #if CIRCUITPY_BUSIO_SPI { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_spi_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&busio_spi_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_spi_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&busio_spi_configure_obj) }, { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&busio_spi_try_lock_obj) }, @@ -465,6 +480,7 @@ static const mp_rom_map_elem_t busio_spi_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&busio_spi_write_obj) }, { MP_ROM_QSTR(MP_QSTR_write_readinto), MP_ROM_PTR(&busio_spi_write_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&busio_spi_frequency_obj) } + #endif // CIRCUITPY_BUSIO_SPI }; static MP_DEFINE_CONST_DICT(busio_spi_locals_dict, busio_spi_locals_dict_table); @@ -480,3 +496,17 @@ MP_DEFINE_CONST_OBJ_TYPE( busio_spi_obj_t *validate_obj_is_spi_bus(mp_obj_t obj, qstr arg_name) { return mp_arg_validate_type(obj, &busio_spi_type, arg_name); } + +// Wait as long as needed for the lock. This is used by SD card access from USB. +// The default implementation is to busy-wait while running the background tasks. espressif is different. +bool common_hal_busio_spi_wait_for_lock(busio_spi_obj_t *self, uint32_t timeout_ms) { + uint64_t deadline = supervisor_ticks_ms64() + timeout_ms; + while (supervisor_ticks_ms64() < deadline && + !mp_hal_is_interrupted()) { + if (common_hal_busio_spi_try_lock(self)) { + return true; + } + RUN_BACKGROUND_TASKS; + } + return false; +} diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h index 69e582411a1..76ed697d665 100644 --- a/shared-bindings/busio/SPI.h +++ b/shared-bindings/busio/SPI.h @@ -22,6 +22,10 @@ extern void common_hal_busio_spi_construct(busio_spi_obj_t *self, extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self); extern bool common_hal_busio_spi_deinited(busio_spi_obj_t *self); +// Mark as deinit without deiniting. This is used by displayio after copying the +// object elsewhere and prevents the heap from deiniting the object. +extern void common_hal_busio_spi_mark_deinit(busio_spi_obj_t *self); + extern bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); extern bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self); @@ -50,3 +54,7 @@ uint8_t common_hal_busio_spi_get_polarity(busio_spi_obj_t *self); extern void common_hal_busio_spi_never_reset(busio_spi_obj_t *self); extern busio_spi_obj_t *validate_obj_is_spi_bus(mp_obj_t obj_in, qstr arg_name); + +// Wait as long as needed for the lock. This is used by SD card access from USB. +// For most ports, busy-wait while running the background tasks. +MP_WEAK bool common_hal_busio_spi_wait_for_lock(busio_spi_obj_t *self, uint32_t timeout_ms); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index eb918fc7531..81e970a98f4 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -54,7 +54,7 @@ //| parity: Optional[Parity] = None, //| stop: int = 1, //| timeout: float = 1, -//| receiver_buffer_size: int = 64 +//| receiver_buffer_size: int = 64, //| ) -> None: //| """A common bidirectional serial protocol that uses an an agreed upon speed //| rather than a shared clock line. @@ -83,6 +83,7 @@ //| RS485 specifications intermittently. //| """ //| ... +//| typedef struct { mp_obj_base_t base; } busio_uart_parity_obj_t; @@ -156,7 +157,7 @@ static mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, si common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, args[ARG_baudrate].u_int, bits, parity, stop, timeout, buffer_size, NULL, false); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); #else mp_raise_NotImplementedError(NULL); #endif // CIRCUITPY_BUSIO_UART @@ -178,6 +179,7 @@ static busio_uart_obj_t *native_uart(mp_obj_t uart_obj) { //| def deinit(self) -> None: //| """Deinitialises the UART and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) { busio_uart_obj_t *self = native_uart(self_in); common_hal_busio_uart_deinit(self); @@ -194,18 +196,15 @@ static void check_for_deinit(busio_uart_obj_t *self) { //| def __enter__(self) -> UART: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t busio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_busio_uart_deinit(MP_OBJ_TO_PTR(args[0])); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_uart_obj___exit__); +//| +// Provided by context manager helper. // These are standard stream methods. Code is in py/stream.c. // @@ -222,6 +221,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ //| :return: Data read //| :rtype: bytes or None""" //| ... +//| //| def readinto(self, buf: WriteableBuffer) -> Optional[int]: //| """Read bytes into the ``buf``. Read at most ``len(buf)`` bytes. @@ -231,6 +231,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ //| //| *New in CircuitPython 4.0:* No length parameter is permitted.""" //| ... +//| //| def readline(self) -> bytes: //| """Read a line, ending in a newline character, or @@ -241,6 +242,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ //| :return: the line read //| :rtype: bytes or None""" //| ... +//| //| def write(self, buf: ReadableBuffer) -> Optional[int]: //| """Write the buffer of bytes to the bus. @@ -250,6 +252,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_ //| :return: the number of bytes written //| :rtype: int or None""" //| ... +//| // These three methods are used by the shared stream methods. static mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { @@ -274,7 +277,7 @@ static mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_ return common_hal_busio_uart_write(self, buf, size, errcode); } -static mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +static mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { busio_uart_obj_t *self = native_uart(self_in); check_for_deinit(self); mp_uint_t ret; @@ -330,6 +333,7 @@ MP_PROPERTY_GETTER(busio_uart_in_waiting_obj, //| timeout: float //| """The current timeout, in seconds (float).""" +//| static mp_obj_t busio_uart_obj_get_timeout(mp_obj_t self_in) { busio_uart_obj_t *self = native_uart(self_in); check_for_deinit(self); @@ -356,6 +360,7 @@ MP_PROPERTY_GETSET(busio_uart_timeout_obj, //| """Discard any unread characters in the input buffer.""" //| ... //| +//| static mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { busio_uart_obj_t *self = native_uart(self_in); check_for_deinit(self); @@ -363,14 +368,15 @@ static mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer); -//| class Parity: -//| """Enum-like class to define the parity used to verify correct data transfer.""" +//| class Parity: +//| """Enum-like class to define the parity used to verify correct data transfer.""" +//| +//| ODD: int +//| """Total number of ones should be odd.""" //| -//| ODD: int -//| """Total number of ones should be odd.""" +//| EVEN: int +//| """Total number of ones should be even.""" //| -//| EVEN: int -//| """Total number of ones should be even.""" //| const mp_obj_type_t busio_uart_parity_type; @@ -411,15 +417,15 @@ static const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&busio_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_uart_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_uart___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Standard stream methods. - { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) }, diff --git a/shared-bindings/camera/Camera.c b/shared-bindings/camera/Camera.c index a0be953222b..f0991082e50 100644 --- a/shared-bindings/camera/Camera.c +++ b/shared-bindings/camera/Camera.c @@ -39,11 +39,12 @@ //| def __init__(self) -> None: //| """Initialize camera.""" //| ... +//| static mp_obj_t camera_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - camera_obj_t *self = mp_obj_malloc(camera_obj_t, &camera_type); // No arguments mp_arg_check_num(n_args, n_kw, 0, 0, false); + camera_obj_t *self = mp_obj_malloc(camera_obj_t, &camera_type); common_hal_camera_construct(self); return MP_OBJ_FROM_PTR(self); } @@ -51,6 +52,7 @@ static mp_obj_t camera_make_new(const mp_obj_type_t *type, size_t n_args, size_t //| def deinit(self) -> None: //| """De-initialize camera.""" //| ... +//| static mp_obj_t camera_obj_deinit(mp_obj_t self_in) { camera_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_camera_deinit(self); @@ -72,6 +74,7 @@ static void check_for_deinit(camera_obj_t *self) { //| :rtype: int""" //| ... //| +//| static mp_obj_t camera_obj_take_picture(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_width, ARG_height, ARG_format }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/camera/ImageFormat.c b/shared-bindings/camera/ImageFormat.c index ad436b4b39e..86ea2741243 100644 --- a/shared-bindings/camera/ImageFormat.c +++ b/shared-bindings/camera/ImageFormat.c @@ -11,12 +11,14 @@ //| //| def __init__(self) -> None: //| """Enum-like class to define the image format.""" +//| //| JPG: ImageFormat //| """JPG format.""" //| //| RGB565: ImageFormat //| """RGB565 format.""" //| +//| const camera_imageformat_obj_t camera_imageformat_jpg_obj = { { &camera_imageformat_type }, diff --git a/shared-bindings/canio/CAN.c b/shared-bindings/canio/CAN.c index 82bf86dd97b..ff46eb26da2 100644 --- a/shared-bindings/canio/CAN.c +++ b/shared-bindings/canio/CAN.c @@ -42,6 +42,7 @@ //| :param bool auto_restart: If True, will restart communications after entering bus-off state //| """ //| ... +//| static mp_obj_t canio_can_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_loopback, ARG_silent, ARG_auto_restart, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -132,6 +133,7 @@ MP_PROPERTY_GETTER(canio_can_receive_error_count_obj, //| state: BusState //| """The current state of the bus. (read-only)""" +//| static mp_obj_t canio_can_state_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -147,6 +149,7 @@ MP_PROPERTY_GETTER(canio_can_state_obj, //| def restart(self) -> None: //| """If the device is in the bus off state, restart it.""" //| ... +//| static mp_obj_t canio_can_restart(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -187,8 +190,13 @@ static MP_DEFINE_CONST_FUN_OBJ_1(canio_can_restart_obj, canio_can_restart); //| //| ESP32S2 supports one Listener. There is a single filter block, which can either match a //| standard address with mask or an extended address with mask. +//| +//| i.MX RT10xx supports one Listener and 8 filter blocks per CAN interface. +//| Each interface is fully independent from the other. A filter block can match +//| either a single address or a mask of addresses, both standard or extended. //| """ //| ... +//| static mp_obj_t canio_can_listen(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { canio_can_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); common_hal_canio_can_check_for_deinit(self); @@ -226,6 +234,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(canio_can_listen_obj, 1, canio_can_listen); //| loopback: bool //| """True if the device was created in loopback mode, False //| otherwise (read-only)""" +//| static mp_obj_t canio_can_loopback_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -242,6 +251,7 @@ MP_PROPERTY_GETTER(canio_can_loopback_obj, //| If the message could not be sent due to a full fifo or a bus error condition, RuntimeError is raised. //| """ //| ... +//| static mp_obj_t canio_can_send(mp_obj_t self_in, mp_obj_t message_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -259,6 +269,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(canio_can_send_obj, canio_can_send); //| silent: bool //| """True if the device was created in silent mode, False //| otherwise (read-only)""" +//| static mp_obj_t canio_can_silent_get(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -273,6 +284,7 @@ MP_PROPERTY_GETTER(canio_can_silent_obj, //| def deinit(self) -> None: //| """Deinitialize this object, freeing its hardware resources""" //| ... +//| static mp_obj_t canio_can_deinit(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_deinit(self); @@ -283,6 +295,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(canio_can_deinit_obj, canio_can_deinit); //| def __enter__(self) -> CAN: //| """Returns self, to allow the object to be used in a `with` statement for resource control""" //| ... +//| static mp_obj_t canio_can_enter(mp_obj_t self_in) { canio_can_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_can_check_for_deinit(self); @@ -299,6 +312,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(canio_can_enter_obj, canio_can_enter); //| """Calls deinit()""" //| ... //| +//| static mp_obj_t canio_can_exit(size_t num_args, const mp_obj_t args[]) { canio_can_obj_t *self = MP_OBJ_TO_PTR(args[0]); common_hal_canio_can_deinit(self); diff --git a/shared-bindings/canio/Listener.c b/shared-bindings/canio/Listener.c index 26b5fb2cbb2..0fd53eecbef 100644 --- a/shared-bindings/canio/Listener.c +++ b/shared-bindings/canio/Listener.c @@ -29,6 +29,7 @@ //| If no message is received in time, `None` is returned. Otherwise, //| a `Message` or `RemoteTransmissionRequest` is returned.""" //| ... +//| static mp_obj_t canio_listener_receive(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); @@ -47,6 +48,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_receive_obj, canio_listener_rece //| """Returns the number of messages (including remote //| transmission requests) waiting""" //| ... +//| static mp_obj_t canio_listener_in_waiting(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); @@ -70,6 +72,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_in_waiting_obj, canio_listener_i //| This method enables the `Listener` to be used as an //| iterable, for instance in a for-loop.""" //| ... +//| static mp_obj_t canio_iternext(mp_obj_t self_in) { mp_obj_t result = canio_listener_receive(self_in); if (result == mp_const_none) { @@ -81,6 +84,7 @@ static mp_obj_t canio_iternext(mp_obj_t self_in) { //| def deinit(self) -> None: //| """Deinitialize this object, freeing its hardware resources""" //| ... +//| static mp_obj_t canio_listener_deinit(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_deinit(self); @@ -91,6 +95,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_deinit_obj, canio_listener_deini //| def __enter__(self) -> CAN: //| """Returns self, to allow the object to be used in a `with` statement for resource control""" //| ... +//| static mp_obj_t canio_listener_enter(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); @@ -106,6 +111,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(canio_listener_enter_obj, canio_listener_enter) //| ) -> None: //| """Calls deinit()""" //| ... +//| static mp_obj_t canio_listener_exit(size_t num_args, const mp_obj_t args[]) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(args[0]); common_hal_canio_listener_deinit(self); @@ -116,6 +122,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(canio_listener_exit_obj, 4, 4, canio_ //| timeout: float //| +//| static mp_obj_t canio_listener_timeout_get(mp_obj_t self_in) { canio_listener_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_canio_listener_check_for_deinit(self); diff --git a/shared-bindings/canio/Match.c b/shared-bindings/canio/Match.c index 7594b03ee93..e7c3dba42aa 100644 --- a/shared-bindings/canio/Match.c +++ b/shared-bindings/canio/Match.c @@ -19,6 +19,7 @@ //| the nonzero bits in mask. Otherwise, it matches exactly the given id. //| If extended is true then only extended ids are matched, otherwise //| only standard ids are matched.""" +//| static mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_mask, ARG_extended, NUM_ARGS }; @@ -46,7 +47,8 @@ static mp_obj_t canio_match_make_new(const mp_obj_type_t *type, size_t n_args, s canio_match_obj_t *self = mp_obj_malloc(canio_match_obj_t, &canio_match_type); common_hal_canio_match_construct(self, id, mask, args[ARG_extended].u_bool); - return self; + + return MP_OBJ_FROM_PTR(self); } //| id: int @@ -76,6 +78,7 @@ MP_PROPERTY_GETTER(canio_match_mask_obj, //| extended: bool //| """True to match extended ids, False to match standard ides""" //| +//| static mp_obj_t canio_match_extended_get(mp_obj_t self_in) { canio_match_obj_t *self = self_in; diff --git a/shared-bindings/canio/Message.c b/shared-bindings/canio/Message.c index 78665f91d2a..848b5b15e43 100644 --- a/shared-bindings/canio/Message.c +++ b/shared-bindings/canio/Message.c @@ -21,6 +21,7 @@ //| In CAN, messages can have a length from 0 to 8 bytes. //| """ //| ... +//| static mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_data, ARG_extended, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -40,7 +41,8 @@ static mp_obj_t canio_message_make_new(const mp_obj_type_t *type, size_t n_args, canio_message_obj_t *self = mp_obj_malloc(canio_message_obj_t, &canio_message_type); common_hal_canio_message_construct(self, args[ARG_id].u_int, data.buf, data.len, args[ARG_extended].u_bool); - return self; + + return MP_OBJ_FROM_PTR(self); } //| id: int @@ -91,6 +93,7 @@ MP_PROPERTY_GETSET(canio_message_data_obj, //| extended: bool //| """True if the message's id is an extended id""" //| +//| static mp_obj_t canio_message_extended_get(const mp_obj_t self_in) { canio_message_obj_t *self = self_in; return mp_obj_new_bool(common_hal_canio_message_get_extended(self)); diff --git a/shared-bindings/canio/RemoteTransmissionRequest.c b/shared-bindings/canio/RemoteTransmissionRequest.c index ba936b9a949..bdc91c494a4 100644 --- a/shared-bindings/canio/RemoteTransmissionRequest.c +++ b/shared-bindings/canio/RemoteTransmissionRequest.c @@ -21,6 +21,7 @@ //| In CAN, messages can have a length from 0 to 8 bytes. //| """ //| ... +//| static mp_obj_t canio_remote_transmission_request_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_id, ARG_length, ARG_extended, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -41,7 +42,8 @@ static mp_obj_t canio_remote_transmission_request_make_new(const mp_obj_type_t * canio_remote_transmission_request_obj_t *self = mp_obj_malloc(canio_remote_transmission_request_obj_t, &canio_remote_transmission_request_type); common_hal_canio_remote_transmission_request_construct(self, args[ARG_id].u_int, length, args[ARG_extended].u_bool); - return self; + + return MP_OBJ_FROM_PTR(self); } @@ -87,6 +89,7 @@ MP_PROPERTY_GETSET(canio_remote_transmission_request_extended_obj, //| length: int //| """The length of the requested message.""" //| +//| static mp_obj_t canio_remote_transmission_request_length_get(const mp_obj_t self_in) { canio_remote_transmission_request_obj_t *self = self_in; return MP_OBJ_NEW_SMALL_INT(common_hal_canio_remote_transmission_request_get_length(self)); diff --git a/shared-bindings/canio/__init__.c b/shared-bindings/canio/__init__.c index 991d37c8d25..2300a6652dd 100644 --- a/shared-bindings/canio/__init__.c +++ b/shared-bindings/canio/__init__.c @@ -36,12 +36,13 @@ //| //| Other implementations of the CAN device may exist (for instance, attached //| via an SPI bus). If so their constructor arguments may differ, but -//| otherwise we encourage implementors to follow the API that the core uses. +//| otherwise we encourage implementers to follow the API that the core uses. //| //| For more information on working with this module, refer to //| `this Learn Guide on using it `_. //| """ //| +//| #include "py/obj.h" #include "py/enum.h" @@ -81,6 +82,7 @@ MAKE_ENUM_VALUE(canio_bus_state_type, bus_state, BUS_OFF, BUS_STATE_OFF); //| occurred recently. It must be restarted before it will send or receive //| packets. This device will neither send or acknowledge packets on the bus.""" //| +//| MAKE_ENUM_MAP(canio_bus_state) { MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_ACTIVE), MAKE_ENUM_MAP_ENTRY(bus_state, ERROR_PASSIVE), diff --git a/shared-bindings/codeop/__init__.c b/shared-bindings/codeop/__init__.c index 6defe6b5897..dd675f551ed 100644 --- a/shared-bindings/codeop/__init__.c +++ b/shared-bindings/codeop/__init__.c @@ -18,6 +18,7 @@ static const char *get_arg_str(mp_obj_t arg, qstr name) { //| //| from types import CodeType //| +//| //| def compile_command( //| source: str, filename: str = "", symbol: str = "single" @@ -29,6 +30,7 @@ static const char *get_arg_str(mp_obj_t arg, qstr name) { //| In particular, it's important that the code not end with a newline character //| or it is likely to be treated as a complete command.""" //| +//| static mp_obj_t compile_command(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_source, ARG_filename, ARG_symbol }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/countio/Counter.c b/shared-bindings/countio/Counter.c index 7ca09c7df6e..9f8bd00645c 100644 --- a/shared-bindings/countio/Counter.c +++ b/shared-bindings/countio/Counter.c @@ -23,7 +23,7 @@ //| pin: microcontroller.Pin, //| *, //| edge: Edge = Edge.FALL, -//| pull: Optional[digitalio.Pull] = None +//| pull: Optional[digitalio.Pull] = None, //| ) -> None: //| """Create a Counter object associated with the given pin that counts //| rising- and/or falling-edge transitions. At least one of ``rise`` and ``fall`` must be True. @@ -52,6 +52,7 @@ //| See the pin assignments for your board to see which pins can be used. //| """ //| ... +//| static mp_obj_t countio_counter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin, ARG_edge, ARG_pull }; static const mp_arg_t allowed_args[] = { @@ -65,8 +66,8 @@ static mp_obj_t countio_counter_make_new(const mp_obj_type_t *type, size_t n_arg const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); const countio_edge_t edge = validate_edge(args[ARG_edge].u_obj, MP_QSTR_edge); const digitalio_pull_t pull = validate_pull(args[ARG_pull].u_obj, MP_QSTR_pull); - countio_counter_obj_t *self = mp_obj_malloc_with_finaliser(countio_counter_obj_t, &countio_counter_type); + countio_counter_obj_t *self = mp_obj_malloc_with_finaliser(countio_counter_obj_t, &countio_counter_type); common_hal_countio_counter_construct(self, pin, edge, pull); return MP_OBJ_FROM_PTR(self); @@ -74,6 +75,7 @@ static mp_obj_t countio_counter_make_new(const mp_obj_type_t *type, size_t n_arg //| def deinit(self) -> None: //| """Deinitializes the Counter and releases any hardware resources for reuse.""" +//| static mp_obj_t countio_counter_deinit(mp_obj_t self_in) { countio_counter_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_countio_counter_deinit(self); @@ -89,21 +91,19 @@ static void check_for_deinit(countio_counter_obj_t *self) { //| def __enter__(self) -> Counter: //| """No-op used by Context Managers.""" +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" -static mp_obj_t countio_counter_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_countio_counter_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(countio_counter___exit___obj, 4, 4, countio_counter_obj___exit__); +//| +// Provided by context manager helper. //| count: int //| """The current count in terms of pulses.""" +//| static mp_obj_t countio_counter_obj_get_count(mp_obj_t self_in) { countio_counter_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -128,6 +128,7 @@ MP_PROPERTY_GETSET(countio_counter_count_obj, //| def reset(self) -> None: //| """Resets the count back to 0.""" //| +//| static mp_obj_t countio_counter_reset(mp_obj_t self_in) { countio_counter_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -143,7 +144,7 @@ static const mp_rom_map_elem_t countio_counter_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&countio_counter_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&countio_counter_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&countio_counter___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&countio_counter_count_obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&countio_counter_reset_obj) }, }; diff --git a/shared-bindings/countio/Edge.c b/shared-bindings/countio/Edge.c index b7ec25078ae..9ace6a923ff 100644 --- a/shared-bindings/countio/Edge.c +++ b/shared-bindings/countio/Edge.c @@ -20,6 +20,7 @@ MAKE_ENUM_VALUE(countio_edge_type, edge, RISE_AND_FALL, EDGE_RISE_AND_FALL); //| def __init__(self) -> None: //| """Enum-like class to define which signal transitions to count.""" //| ... +//| //| RISE: Edge //| """Count the rising edges.""" //| @@ -32,6 +33,7 @@ MAKE_ENUM_VALUE(countio_edge_type, edge, RISE_AND_FALL, EDGE_RISE_AND_FALL); //| **Limitations:** ``RISE_AND_FALL`` is not available to RP2040 due to hardware limitations. //| """ //| +//| MAKE_ENUM_MAP(countio_edge) { MAKE_ENUM_MAP_ENTRY(edge, RISE), MAKE_ENUM_MAP_ENTRY(edge, FALL), diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c index 6bbdc68be52..58f90b0b141 100644 --- a/shared-bindings/digitalio/DigitalInOut.c +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -17,6 +17,7 @@ #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" #include "shared-bindings/digitalio/Direction.h" #include "shared-bindings/digitalio/DriveMode.h" #include "shared-bindings/digitalio/Pull.h" @@ -65,13 +66,14 @@ MP_WEAK const mcu_pin_obj_t *common_hal_digitalio_validate_pin(mp_obj_t obj) { //| //| :param ~microcontroller.Pin pin: The pin to control""" //| ... +//| static mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); - digitalio_digitalinout_obj_t *self = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); - const mcu_pin_obj_t *pin = common_hal_digitalio_validate_pin(args[0]); + + digitalio_digitalinout_obj_t *self = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(self, pin); return MP_OBJ_FROM_PTR(self); @@ -80,6 +82,7 @@ static mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Turn off the DigitalInOut and release the pin for other use.""" //| ... +//| static mp_obj_t digitalio_digitalinout_obj_deinit(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_digitalio_digitalinout_deinit(self); @@ -90,18 +93,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_deinit_obj, digitalio_digitalin //| def __enter__(self) -> DigitalInOut: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_digitalio_digitalinout_deinit(MP_OBJ_TO_PTR(args[0])); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__); +//| +// Provided by context manager helper. static inline void check_for_deinit(digitalio_digitalinout_obj_t *self) { if (common_hal_digitalio_digitalinout_deinited(self)) { @@ -119,6 +119,7 @@ static inline void check_for_deinit(digitalio_digitalinout_obj_t *self) { //| :param ~digitalio.DriveMode drive_mode: drive mode for the output //| """ //| ... +//| static mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_value, ARG_drive_mode }; static const mp_arg_t allowed_args[] = { @@ -156,6 +157,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_output_obj, 1, digit //| switch.pull = digitalio.Pull.UP //| print(switch.value)""" //| ... +//| static mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_pull }; static const mp_arg_t allowed_args[] = { @@ -189,9 +191,9 @@ static mp_obj_t digitalio_digitalinout_obj_get_direction(mp_obj_t self_in) { check_for_deinit(self); digitalio_direction_t direction = common_hal_digitalio_digitalinout_get_direction(self); if (direction == DIRECTION_INPUT) { - return (mp_obj_t)&digitalio_direction_input_obj; + return MP_OBJ_FROM_PTR(&digitalio_direction_input_obj); } - return (mp_obj_t)&digitalio_direction_output_obj; + return MP_OBJ_FROM_PTR(&digitalio_direction_output_obj); } MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_direction_obj, digitalio_digitalinout_obj_get_direction); @@ -253,9 +255,9 @@ static mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) { } digitalio_drive_mode_t drive_mode = common_hal_digitalio_digitalinout_get_drive_mode(self); if (drive_mode == DRIVE_MODE_PUSH_PULL) { - return (mp_obj_t)&digitalio_drive_mode_push_pull_obj; + return MP_OBJ_FROM_PTR(&digitalio_drive_mode_push_pull_obj); } - return (mp_obj_t)&digitalio_drive_mode_open_drain_obj; + return MP_OBJ_FROM_PTR(&digitalio_drive_mode_open_drain_obj); } MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_drive_mode_obj, digitalio_digitalinout_obj_get_drive_mode); @@ -288,6 +290,7 @@ MP_PROPERTY_GETSET(digitalio_digitalio_drive_mode_obj, //| //| :raises AttributeError: if `direction` is :py:data:`~digitalio.Direction.OUTPUT`.""" //| +//| static mp_obj_t digitalio_digitalinout_obj_get_pull(mp_obj_t self_in) { digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -326,7 +329,7 @@ static const mp_rom_map_elem_t digitalio_digitalinout_locals_dict_table[] = { // instance methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&digitalio_digitalinout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&digitalio_digitalinout_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_switch_to_output), MP_ROM_PTR(&digitalio_digitalinout_switch_to_output_obj) }, { MP_ROM_QSTR(MP_QSTR_switch_to_input), MP_ROM_PTR(&digitalio_digitalinout_switch_to_input_obj) }, @@ -339,12 +342,91 @@ static const mp_rom_map_elem_t digitalio_digitalinout_locals_dict_table[] = { static MP_DEFINE_CONST_DICT(digitalio_digitalinout_locals_dict, digitalio_digitalinout_locals_dict_table); +// Protocol implementation - thin wrappers to match protocol signature +void digitalinout_deinit(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_digitalio_digitalinout_deinit(self); +} + +bool digitalinout_deinited(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_deinited(self); +} + +digitalinout_result_t digitalinout_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_switch_to_input(self, pull); +} + +digitalinout_result_t digitalinout_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_switch_to_output(self, value, drive_mode); +} + +digitalio_direction_t digitalinout_get_direction(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_get_direction(self); +} + +mp_negative_errno_t digitalinout_set_value(mp_obj_t self_in, bool value) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_digitalio_digitalinout_set_value(self, value); + return 0; +} + +mp_negative_errno_t digitalinout_get_value(mp_obj_t self_in, bool *value) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + *value = common_hal_digitalio_digitalinout_get_value(self); + return 0; +} + +digitalinout_result_t digitalinout_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_set_drive_mode(self, drive_mode); +} + +digitalio_drive_mode_t digitalinout_get_drive_mode(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_get_drive_mode(self); +} + +digitalinout_result_t digitalinout_set_pull(mp_obj_t self_in, digitalio_pull_t pull) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +digitalio_pull_t digitalinout_get_pull(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_digitalio_digitalinout_get_pull(self); +} + +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +static const digitalinout_p_t digitalinout_digitalinout_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut) + .deinit = digitalinout_deinit, + .deinited = digitalinout_deinited, + .switch_to_input = digitalinout_switch_to_input, + .switch_to_output = digitalinout_switch_to_output, + .get_direction = digitalinout_get_direction, + .get_value = digitalinout_get_value, + .set_value = digitalinout_set_value, + .get_drive_mode = digitalinout_get_drive_mode, + .set_drive_mode = digitalinout_set_drive_mode, + .get_pull = digitalinout_get_pull, + .set_pull = digitalinout_set_pull, +}; +#endif + MP_DEFINE_CONST_OBJ_TYPE( digitalio_digitalinout_type, MP_QSTR_DigitalInOut, MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, make_new, digitalio_digitalinout_make_new, locals_dict, &digitalio_digitalinout_locals_dict + #if CIRCUITPY_DIGITALINOUT_PROTOCOL + , + protocol, &digitalinout_digitalinout_proto + #endif ); // Helper for validating digitalio.DigitalInOut arguments diff --git a/shared-bindings/digitalio/DigitalInOut.h b/shared-bindings/digitalio/DigitalInOut.h index f030e27a60b..8d3fe8c00a2 100644 --- a/shared-bindings/digitalio/DigitalInOut.h +++ b/shared-bindings/digitalio/DigitalInOut.h @@ -28,6 +28,9 @@ typedef enum { #endif } digitalinout_result_t; +// Include protocol after types are defined +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" + typedef enum { DIGITALINOUT_REG_READ, DIGITALINOUT_REG_WRITE, @@ -54,3 +57,16 @@ digitalio_digitalinout_obj_t *assert_digitalinout(mp_obj_t obj); volatile uint32_t *common_hal_digitalio_digitalinout_get_reg(digitalio_digitalinout_obj_t *self, digitalinout_reg_op_t op, uint32_t *mask); bool common_hal_digitalio_has_reg_op(digitalinout_reg_op_t op); + +// Protocol wrapper functions - always available for direct calls +void digitalinout_deinit(mp_obj_t self_in); +bool digitalinout_deinited(mp_obj_t self_in); +digitalinout_result_t digitalinout_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull); +digitalinout_result_t digitalinout_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode); +digitalio_direction_t digitalinout_get_direction(mp_obj_t self_in); +mp_negative_errno_t digitalinout_set_value(mp_obj_t self_in, bool value); +mp_negative_errno_t digitalinout_get_value(mp_obj_t self_in, bool *value); +digitalinout_result_t digitalinout_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode); +digitalio_drive_mode_t digitalinout_get_drive_mode(mp_obj_t self_in); +digitalinout_result_t digitalinout_set_pull(mp_obj_t self_in, digitalio_pull_t pull); +digitalio_pull_t digitalinout_get_pull(mp_obj_t self_in); diff --git a/shared-bindings/digitalio/DigitalInOutProtocol.c b/shared-bindings/digitalio/DigitalInOutProtocol.c new file mode 100644 index 00000000000..48b428ad463 --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOutProtocol.c @@ -0,0 +1,397 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" + +#include "py/obj.h" +#include "py/objtype.h" +#include "py/proto.h" +#include "py/runtime.h" +#include "py/nlr.h" +#include "py/gc.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/util.h" +#include "supervisor/port_heap.h" + +//| from typing import Protocol, Optional +//| +//| class DigitalInOutProtocol(Protocol): +//| """Protocol for digital input/output pin control. +//| +//| Any object that implements this protocol can be used as a digital pin, +//| providing compatibility with code expecting a `digitalio.DigitalInOut`. +//| """ +//| +//| def deinit(self) -> None: +//| """Deinitialize the pin and release hardware resources.""" +//| ... +//| +//| def deinited(self) -> bool: +//| """Check whether the pin has been deinitialized. +//| +//| :return: True if deinitialized, False otherwise +//| """ +//| ... +//| +//| def switch_to_input(self, pull: Optional[digitalio.Pull] = None) -> None: +//| """Configure the pin as a digital input. +//| +//| :param pull: Pull resistor configuration (UP, DOWN, or None) +//| """ +//| ... +//| +//| def switch_to_output( +//| self, +//| value: bool = False, +//| drive_mode: digitalio.DriveMode = digitalio.DriveMode.PUSH_PULL +//| ) -> None: +//| """Configure the pin as a digital output. +//| +//| :param value: Initial output value (default False) +//| :param drive_mode: Output drive mode (PUSH_PULL or OPEN_DRAIN) +//| """ +//| ... +//| +//| @property +//| def direction(self) -> digitalio.Direction: +//| """The pin direction (INPUT or OUTPUT).""" +//| ... +//| +//| @direction.setter +//| def direction(self, value: digitalio.Direction) -> None: +//| ... +//| +//| @property +//| def value(self) -> bool: +//| """The digital logic level of the pin.""" +//| ... +//| +//| @value.setter +//| def value(self, val: bool) -> None: +//| ... +//| +//| @property +//| def pull(self) -> Optional[digitalio.Pull]: +//| """The pull resistor configuration for inputs (UP, DOWN, or None).""" +//| ... +//| +//| @pull.setter +//| def pull(self, pul: Optional[digitalio.Pull]) -> None: +//| ... +//| +//| @property +//| def drive_mode(self) -> digitalio.DriveMode: +//| """The drive mode for outputs (PUSH_PULL or OPEN_DRAIN).""" +//| ... +//| +//| @drive_mode.setter +//| def drive_mode(self, mode: digitalio.DriveMode) -> None: +//| ... +//| +// C Implementation Notes: +// ----------------------- +// For C implementations, define a digitalinout_p_t protocol structure and assign it +// to your type's protocol field in MP_DEFINE_CONST_OBJ_TYPE. +// +// Example: +// static const digitalinout_p_t my_type_proto = { +// MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut) +// .construct = my_construct_func, +// .deinit = my_deinit_func, +// .deinited = my_deinited_func, +// .switch_to_input = my_switch_to_input_func, +// .switch_to_output = my_switch_to_output_func, +// .get_direction = my_get_direction_func, +// .get_value = my_get_value_func, +// .set_value = my_set_value_func, +// .get_drive_mode = my_get_drive_mode_func, +// .set_drive_mode = my_set_drive_mode_func, +// .get_pull = my_get_pull_func, +// .set_pull = my_set_pull_func, +// }; +// +// MP_DEFINE_CONST_OBJ_TYPE( +// my_type, +// MP_QSTR_MyType, +// MP_TYPE_FLAG_NONE, +// make_new, my_make_new, +// protocol, &my_type_proto +// ); +// +// See shared-bindings/digitalio/DigitalInOut.c for a complete example. +// + +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +static void check_object_has_method(mp_obj_t obj, qstr method_name) { + mp_obj_t dest[2]; + mp_load_method_protected(obj, method_name, dest, true); + if (dest[0] == MP_OBJ_NULL) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q object missing '%q' method"), MP_OBJ_TO_PTR(obj), method_name); + } +} + +static void check_object_has_attr(mp_obj_t obj, qstr attr_name) { + mp_obj_t dest[2]; + mp_load_method_protected(obj, attr_name, dest, true); + if (dest[0] == MP_OBJ_NULL) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q object missing '%q' attribute"), MP_OBJ_TO_PTR(obj), attr_name); + } +} +#endif + +mp_obj_t digitalinout_protocol_from_pin( + mp_obj_t pin_or_dio, + qstr arg_name, + bool allow_none, + bool use_port_allocation, + bool *out_owns_pin) { + + *out_owns_pin = false; + + // Handle None case + if (allow_none && pin_or_dio == mp_const_none) { + return mp_const_none; + } + + // Check if it's a Pin + if (mp_obj_is_type(pin_or_dio, &mcu_pin_type)) { + // Validate the pin is free + const mcu_pin_obj_t *pin; + if (allow_none) { + pin = validate_obj_is_free_pin_or_none(pin_or_dio, arg_name); + if (pin == NULL) { + return mp_const_none; + } + } else { + pin = validate_obj_is_free_pin(pin_or_dio, arg_name); + } + + // Allocate and construct a DigitalInOut object + // Use port_malloc if GC is not available or if forced + digitalio_digitalinout_obj_t *dio; + if (use_port_allocation) { + dio = port_malloc(sizeof(digitalio_digitalinout_obj_t), false); + } else { + dio = m_malloc(sizeof(digitalio_digitalinout_obj_t)); + } + dio->base.type = &digitalio_digitalinout_type; + mp_obj_t dio_obj = MP_OBJ_FROM_PTR(dio); + *out_owns_pin = true; + + digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(dio_obj, pin); + if (result != DIGITALINOUT_OK) { + // Free the allocation on error + if (use_port_allocation) { + port_free(dio); + } + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), arg_name); + } + return dio_obj; + } + + #if CIRCUITPY_DIGITALINOUT_PROTOCOL + // Check if it natively implements the DigitalInOutProtocol + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, pin_or_dio); + if (proto != NULL) { + // Native protocol support - use it directly + return pin_or_dio; + } + + // Verify the object has the required methods/attributes + check_object_has_method(pin_or_dio, MP_QSTR_deinit); + check_object_has_method(pin_or_dio, MP_QSTR_switch_to_input); + check_object_has_method(pin_or_dio, MP_QSTR_switch_to_output); + check_object_has_attr(pin_or_dio, MP_QSTR_deinited); + check_object_has_attr(pin_or_dio, MP_QSTR_direction); + check_object_has_attr(pin_or_dio, MP_QSTR_value); + check_object_has_attr(pin_or_dio, MP_QSTR_drive_mode); + check_object_has_attr(pin_or_dio, MP_QSTR_pull); + + // Object has all required attributes - use it as DigitalInOutProtocol + return pin_or_dio; + #else + mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object does not support '%q'"), + mp_obj_get_type_qstr(pin_or_dio), MP_QSTR_DigitalInOut); + #endif +} + +// These functions are only used when CIRCUITPY_DIGITALINOUT_PROTOCOL is enabled. +// Otherwise, the digitalinout_* functions are called directly. +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +void digitalinout_protocol_deinit(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_protocol_digitalinout, self); + if (proto && proto->deinit) { + proto->deinit(self); + return; + } + + // Fallback to Python method call + mp_obj_t dest[2]; + mp_load_method_maybe(self, MP_QSTR_deinit, dest); + if (dest[0] != MP_OBJ_NULL) { + mp_call_method_n_kw(0, 0, dest); + return; + } +} + +bool digitalinout_protocol_deinited(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->deinited) { + return proto->deinited(self); + } + + // Try as attribute + mp_obj_t attr = mp_load_attr(self, MP_QSTR_deinited); + return mp_obj_is_true(attr); +} + +digitalinout_result_t digitalinout_protocol_switch_to_input(mp_obj_t self, digitalio_pull_t pull) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->switch_to_input) { + return proto->switch_to_input(self, pull); + } + + // Fallback to Python method call + mp_obj_t dest[3]; + mp_load_method_maybe(self, MP_QSTR_switch_to_input, dest); + if (dest[0] != MP_OBJ_NULL) { + mp_obj_t pull_obj = mp_const_none; + if (pull == PULL_UP) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_up_obj); + } else if (pull == PULL_DOWN) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_down_obj); + } + dest[2] = pull_obj; + mp_call_method_n_kw(1, 0, dest); + return DIGITALINOUT_OK; + } + + return DIGITALINOUT_PIN_BUSY; +} + +digitalinout_result_t digitalinout_protocol_switch_to_output(mp_obj_t self, bool value, digitalio_drive_mode_t drive_mode) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->switch_to_output) { + return proto->switch_to_output(self, value, drive_mode); + } + + // Fallback to Python method call + mp_obj_t dest[4]; + mp_load_method_maybe(self, MP_QSTR_switch_to_output, dest); + if (dest[0] != MP_OBJ_NULL) { + dest[2] = mp_obj_new_bool(value); + dest[3] = (drive_mode == DRIVE_MODE_PUSH_PULL) ? + MP_OBJ_FROM_PTR(&digitalio_drive_mode_push_pull_obj) : + MP_OBJ_FROM_PTR(&digitalio_drive_mode_open_drain_obj); + mp_call_method_n_kw(2, 0, dest); + return DIGITALINOUT_OK; + } + + mp_raise_TypeError(MP_ERROR_TEXT("object does not support DigitalInOut protocol")); +} + +digitalio_direction_t digitalinout_protocol_get_direction(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_direction) { + return proto->get_direction(self); + } + + // Fallback to Python attribute access + mp_obj_t direction = mp_load_attr(self, MP_QSTR_direction); + if (direction == MP_ROM_PTR(&digitalio_direction_input_obj)) { + return DIRECTION_INPUT; + } + return DIRECTION_OUTPUT; +} + +mp_negative_errno_t digitalinout_protocol_set_value(mp_obj_t self, bool value) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->set_value) { + return proto->set_value(self, value); + } + + // Fallback to Python attribute assignment + mp_store_attr(self, MP_QSTR_value, mp_obj_new_bool(value)); + return 0; +} + +mp_negative_errno_t digitalinout_protocol_get_value(mp_obj_t self, bool *value) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_value) { + return proto->get_value(self, value); + } + + // Fallback to Python attribute access + *value = mp_obj_is_true(mp_load_attr(self, MP_QSTR_value)); + return 0; +} + +digitalinout_result_t digitalinout_protocol_set_drive_mode(mp_obj_t self, digitalio_drive_mode_t drive_mode) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->set_drive_mode) { + return proto->set_drive_mode(self, drive_mode); + } + + // Fallback to Python attribute assignment + mp_obj_t drive_mode_obj = (drive_mode == DRIVE_MODE_PUSH_PULL) ? + MP_OBJ_FROM_PTR(&digitalio_drive_mode_push_pull_obj) : + MP_OBJ_FROM_PTR(&digitalio_drive_mode_open_drain_obj); + mp_store_attr(self, MP_QSTR_drive_mode, drive_mode_obj); + return DIGITALINOUT_OK; +} + +digitalio_drive_mode_t digitalinout_protocol_get_drive_mode(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_drive_mode) { + return proto->get_drive_mode(self); + } + + // Fallback to Python attribute access + mp_obj_t drive_mode = mp_load_attr(self, MP_QSTR_drive_mode); + if (drive_mode == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { + return DRIVE_MODE_OPEN_DRAIN; + } + return DRIVE_MODE_PUSH_PULL; +} + +digitalinout_result_t digitalinout_protocol_set_pull(mp_obj_t self, digitalio_pull_t pull) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->set_pull) { + return proto->set_pull(self, pull); + } + + // Fallback to Python attribute assignment + mp_obj_t pull_obj = mp_const_none; + if (pull == PULL_UP) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_up_obj); + } else if (pull == PULL_DOWN) { + pull_obj = MP_OBJ_FROM_PTR(&digitalio_pull_down_obj); + } + mp_store_attr(self, MP_QSTR_pull, pull_obj); + return DIGITALINOUT_OK; +} + +digitalio_pull_t digitalinout_protocol_get_pull(mp_obj_t self) { + const digitalinout_p_t *proto = mp_proto_get(MP_QSTR_DigitalInOut, self); + if (proto && proto->get_pull) { + return proto->get_pull(self); + } + + // Fallback to Python attribute access + mp_obj_t pull = mp_load_attr(self, MP_QSTR_pull); + if (pull == MP_OBJ_FROM_PTR(&digitalio_pull_up_obj)) { + return PULL_UP; + } else if (pull == MP_OBJ_FROM_PTR(&digitalio_pull_down_obj)) { + return PULL_DOWN; + } + return PULL_NONE; +} + +#endif // CIRCUITPY_DIGITALINOUT_PROTOCOL diff --git a/shared-bindings/digitalio/DigitalInOutProtocol.h b/shared-bindings/digitalio/DigitalInOutProtocol.h new file mode 100644 index 00000000000..6cb92a3735f --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOutProtocol.h @@ -0,0 +1,83 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "py/proto.h" +#include "py/mperrno.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" + +// Protocol structure for DigitalInOut implementations +// Note: mcu_pin_obj_t and digitalinout_result_t are defined by files that include this header +typedef struct _digitalinout_p_t { + MP_PROTOCOL_HEAD // MP_QSTR_DigitalInOut + void (*deinit)(mp_obj_t self); + bool (*deinited)(mp_obj_t self); + digitalinout_result_t (*switch_to_input)(mp_obj_t self, digitalio_pull_t pull); + digitalinout_result_t (*switch_to_output)(mp_obj_t self, bool value, digitalio_drive_mode_t drive_mode); + digitalio_direction_t (*get_direction)(mp_obj_t self); + mp_negative_errno_t (*set_value)(mp_obj_t self, bool value); // Return 0 if ok + mp_negative_errno_t (*get_value)(mp_obj_t self, bool *value); // Return 0 if ok + digitalinout_result_t (*set_drive_mode)(mp_obj_t self, digitalio_drive_mode_t drive_mode); + digitalio_drive_mode_t (*get_drive_mode)(mp_obj_t self); + digitalinout_result_t (*set_pull)(mp_obj_t self, digitalio_pull_t pull); + digitalio_pull_t (*get_pull)(mp_obj_t self); +} digitalinout_p_t; + +// Protocol helper functions +// These functions work with any object that implements the DigitalInOut protocol, +// either through native C protocol or Python attributes/methods. + +// Converts a Pin or DigitalInOutProtocol to a DigitalInOutProtocol object. +// If pin_or_dio is a Pin, allocates and initializes a DigitalInOut object. +// If pin_or_dio is already a DigitalInOutProtocol, returns it directly. +// If allow_none is true and pin_or_dio is None, returns None. +// If force_port_allocation is true, uses port_malloc instead of GC allocation. +// Sets *out_owns_pin to true if a new DigitalInOut was allocated (caller must deinit and free). +// Returns the DigitalInOutProtocol object to use. +// Raises an exception on error. +// Note: To free allocated objects, deinit first, then use gc_ptr_on_heap() to determine +// if port_free() should be called (if not on heap) or let GC handle it (if on heap). +mp_obj_t digitalinout_protocol_from_pin( + mp_obj_t pin_or_dio, + qstr arg_name, + bool allow_none, + bool force_port_allocation, + bool *out_owns_pin); + +#if CIRCUITPY_DIGITALINOUT_PROTOCOL +// Protocol helper functions that do protocol lookup or Python fallback +void digitalinout_protocol_deinit(mp_obj_t self); +bool digitalinout_protocol_deinited(mp_obj_t self); +digitalinout_result_t digitalinout_protocol_switch_to_input(mp_obj_t self, digitalio_pull_t pull); +digitalinout_result_t digitalinout_protocol_switch_to_output(mp_obj_t self, bool value, digitalio_drive_mode_t drive_mode); +digitalio_direction_t digitalinout_protocol_get_direction(mp_obj_t self); +mp_negative_errno_t digitalinout_protocol_set_value(mp_obj_t self, bool value); +mp_negative_errno_t digitalinout_protocol_get_value(mp_obj_t self, bool *value); +digitalinout_result_t digitalinout_protocol_set_drive_mode(mp_obj_t self, digitalio_drive_mode_t drive_mode); +digitalio_drive_mode_t digitalinout_protocol_get_drive_mode(mp_obj_t self); +digitalinout_result_t digitalinout_protocol_set_pull(mp_obj_t self, digitalio_pull_t pull); +digitalio_pull_t digitalinout_protocol_get_pull(mp_obj_t self); +#else +// When protocol is disabled, map directly to native DigitalInOut functions +#define digitalinout_protocol_deinit digitalinout_deinit +#define digitalinout_protocol_deinited digitalinout_deinited +#define digitalinout_protocol_switch_to_input digitalinout_switch_to_input +#define digitalinout_protocol_switch_to_output digitalinout_switch_to_output +#define digitalinout_protocol_get_direction digitalinout_get_direction +#define digitalinout_protocol_set_value digitalinout_set_value +#define digitalinout_protocol_get_value digitalinout_get_value +#define digitalinout_protocol_set_drive_mode digitalinout_set_drive_mode +#define digitalinout_protocol_get_drive_mode digitalinout_get_drive_mode +#define digitalinout_protocol_set_pull digitalinout_set_pull +#define digitalinout_protocol_get_pull digitalinout_get_pull +#endif diff --git a/shared-bindings/digitalio/Direction.c b/shared-bindings/digitalio/Direction.c index 442d2dcd359..35c36600354 100644 --- a/shared-bindings/digitalio/Direction.c +++ b/shared-bindings/digitalio/Direction.c @@ -25,12 +25,14 @@ //| """Enum-like class to define which direction the digital values are //| going.""" //| ... +//| //| INPUT: Direction //| """Read digital data in""" //| //| OUTPUT: Direction //| """Write digital data out""" //| +//| const mp_obj_type_t digitalio_direction_type; const digitalio_direction_obj_t digitalio_direction_input_obj = { diff --git a/shared-bindings/digitalio/DriveMode.c b/shared-bindings/digitalio/DriveMode.c index 78ced01df25..5fbee20526c 100644 --- a/shared-bindings/digitalio/DriveMode.c +++ b/shared-bindings/digitalio/DriveMode.c @@ -13,6 +13,7 @@ //| """Enum-like class to define the drive mode used when outputting //| digital values.""" //| ... +//| //| PUSH_PULL: DriveMode //| """Output both high and low digital values""" //| @@ -20,6 +21,7 @@ //| """Output low digital values but go into high z for digital high. This is //| useful for i2c and other protocols that share a digital line.""" //| +//| const mp_obj_type_t digitalio_drive_mode_type; const digitalio_drive_mode_obj_t digitalio_drive_mode_push_pull_obj = { diff --git a/shared-bindings/digitalio/Pull.c b/shared-bindings/digitalio/Pull.c index 7a02564354a..6886699d127 100644 --- a/shared-bindings/digitalio/Pull.c +++ b/shared-bindings/digitalio/Pull.c @@ -14,6 +14,7 @@ //| """Enum-like class to define the pull value, if any, used while reading //| digital values in.""" //| ... +//| //| UP: Pull //| """When the input line isn't being driven the pull up can pull the state //| of the line high so it reads as true.""" @@ -22,6 +23,7 @@ //| """When the input line isn't being driven the pull down can pull the //| state of the line low so it reads as false.""" //| +//| const mp_obj_type_t digitalio_pull_type; const digitalio_pull_obj_t digitalio_pull_up_obj = { diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 4c8fc97345c..e543687901a 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -39,6 +39,7 @@ //| :param int height: The number of values high //| :param int value_count: The number of possible pixel values.""" //| ... +//| static mp_obj_t displayio_bitmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 3, 3, false); uint32_t width = mp_arg_validate_int_range(mp_obj_get_int(all_args[0]), 0, 32767, MP_QSTR_width); @@ -96,6 +97,7 @@ MP_PROPERTY_GETTER(displayio_bitmap_height_obj, //| bits_per_value: int //| """Bits per Pixel of the bitmap. (read only)""" +//| static mp_obj_t displayio_bitmap_obj_get_bits_per_value(mp_obj_t self_in) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); @@ -126,6 +128,7 @@ MP_PROPERTY_GETTER(displayio_bitmap_bits_per_value_obj, //| //| bitmap[0,1] = 3""" //| ... +//| static mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { if (value_obj == mp_const_none) { // delete item @@ -183,6 +186,7 @@ static mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t val //| def fill(self, value: int) -> None: //| """Fills the bitmap with the supplied palette index value.""" //| ... +//| static mp_obj_t displayio_bitmap_obj_fill(mp_obj_t self_in, mp_obj_t value_obj) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -213,6 +217,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_bitmap_fill_obj, displayio_bitmap_obj_fill); //| notified of the "dirty rectangle" that encloses all modified //| pixels.""" //| ... +//| static mp_obj_t displayio_bitmap_obj_dirty(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); @@ -244,6 +249,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(displayio_bitmap_dirty_obj, 0, displayio_bitmap_obj_d //| """Release resources allocated by Bitmap.""" //| ... //| +//| static mp_obj_t displayio_bitmap_obj_deinit(mp_obj_t self_in) { displayio_bitmap_t *self = MP_OBJ_TO_PTR(self_in); common_hal_displayio_bitmap_deinit(self); diff --git a/shared-bindings/displayio/ColorConverter.c b/shared-bindings/displayio/ColorConverter.c index 1f973b5a42a..bfd037016d4 100644 --- a/shared-bindings/displayio/ColorConverter.c +++ b/shared-bindings/displayio/ColorConverter.c @@ -26,6 +26,7 @@ //| :param Colorspace colorspace: The source colorspace, one of the Colorspace constants //| :param bool dither: Adds random noise to dither the output image""" //| ... +//| static mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_dither, ARG_input_colorspace }; @@ -38,7 +39,6 @@ static mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); displayio_colorconverter_t *self = mp_obj_malloc(displayio_colorconverter_t, &displayio_colorconverter_type); - common_hal_displayio_colorconverter_construct(self, args[ARG_dither].u_bool, (displayio_colorspace_t)cp_enum_value(&displayio_colorspace_type, args[ARG_input_colorspace].u_obj, MP_QSTR_input_colorspace)); return MP_OBJ_FROM_PTR(self); @@ -47,6 +47,7 @@ static mp_obj_t displayio_colorconverter_make_new(const mp_obj_type_t *type, siz //| def convert(self, color: int) -> int: //| """Converts the given color to RGB565 according to the Colorspace""" //| ... +//| static mp_obj_t displayio_colorconverter_obj_convert(mp_obj_t self_in, mp_obj_t color_obj) { displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); @@ -60,6 +61,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_convert_obj, displayio_colorc //| dither: bool //| """When `True` the ColorConverter dithers the output by adding random noise when //| truncating to display bitdepth""" +//| static mp_obj_t displayio_colorconverter_obj_get_dither(mp_obj_t self_in) { displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_displayio_colorconverter_get_dither(self)); @@ -84,6 +86,7 @@ MP_PROPERTY_GETSET(displayio_colorconverter_dither_obj, //| raise an Exception if there is already a selected transparent index. //| //| :param int color: The color to be transparent""" +//| static mp_obj_t displayio_colorconverter_make_transparent(mp_obj_t self_in, mp_obj_t transparent_color_obj) { displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); @@ -98,6 +101,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_colorconverter_make_transparent_obj, display //| //| :param int color: [IGNORED] Use any value""" //| +//| static mp_obj_t displayio_colorconverter_make_opaque(mp_obj_t self_in, mp_obj_t transparent_color_obj) { displayio_colorconverter_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/displayio/Colorspace.c b/shared-bindings/displayio/Colorspace.c index f4677b25a90..f6592024fa3 100644 --- a/shared-bindings/displayio/Colorspace.c +++ b/shared-bindings/displayio/Colorspace.c @@ -39,6 +39,7 @@ MAKE_ENUM_VALUE(displayio_colorspace_type, displayio_colorspace, L8, DISPLAYIO_C //| RGB555_SWAPPED: Colorspace //| """The swapped 15-bit colorspace. First, the high and low 8 bits of the number are swapped, then they are interpreted as for RGB555""" //| +//| MAKE_ENUM_MAP(displayio_colorspace) { MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB888), MAKE_ENUM_MAP_ENTRY(displayio_colorspace, RGB565), diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 73c3d06988c..94ee2e58de1 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -25,6 +25,7 @@ //| :param int x: Initial x position within the parent. //| :param int y: Initial y position within the parent.""" //| ... +//| static mp_obj_t displayio_group_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_scale, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { @@ -120,6 +121,7 @@ MP_PROPERTY_GETSET(displayio_group_x_obj, //| y: int //| """Y position of the Group in the parent.""" +//| static mp_obj_t displayio_group_obj_get_y(mp_obj_t self_in) { displayio_group_t *self = native_group(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_displayio_group_get_y(self)); @@ -145,6 +147,7 @@ MP_PROPERTY_GETSET(displayio_group_y_obj, //| ) -> None: //| """Append a layer to the group. It will be drawn above other layers.""" //| ... +//| static mp_obj_t displayio_group_obj_append(mp_obj_t self_in, mp_obj_t layer) { displayio_group_t *self = native_group(self_in); common_hal_displayio_group_insert(self, common_hal_displayio_group_get_len(self), layer); @@ -159,6 +162,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_append_obj, displayio_group_obj_append //| ) -> None: //| """Insert a layer into the group.""" //| ... +//| static mp_obj_t displayio_group_obj_insert(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t layer) { displayio_group_t *self = native_group(self_in); if ((size_t)MP_OBJ_SMALL_INT_VALUE(index_obj) == common_hal_displayio_group_get_len(self)) { @@ -177,6 +181,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(displayio_group_insert_obj, displayio_group_obj_insert //| ) -> int: //| """Returns the index of the first copy of layer. Raises ValueError if not found.""" //| ... +//| static mp_obj_t displayio_group_obj_index(mp_obj_t self_in, mp_obj_t layer) { displayio_group_t *self = native_group(self_in); mp_int_t index = common_hal_displayio_group_index(self, layer); @@ -192,6 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_index_obj, displayio_group_obj_index); //| ) -> Union[vectorio.Circle, vectorio.Rectangle, vectorio.Polygon, Group, TileGrid]: //| """Remove the ith item and return it.""" //| ... +//| static mp_obj_t displayio_group_obj_pop(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_i }; static const mp_arg_t allowed_args[] = { @@ -217,6 +223,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(displayio_group_pop_obj, 1, displayio_group_obj_pop); //| ) -> None: //| """Remove the first copy of layer. Raises ValueError if it is not present.""" //| ... +//| static mp_obj_t displayio_group_obj_remove(mp_obj_t self_in, mp_obj_t layer) { mp_obj_t index = displayio_group_obj_index(self_in, layer); displayio_group_t *self = native_group(self_in); @@ -239,6 +246,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(displayio_group_remove_obj, displayio_group_obj_remove //| def __len__(self) -> int: //| """Returns the number of layers in a Group""" //| ... +//| static mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { displayio_group_t *self = native_group(self_in); uint16_t len = common_hal_displayio_group_get_len(self); @@ -281,6 +289,7 @@ static mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| //| del group[0]""" //| ... +//| static mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { displayio_group_t *self = native_group(self_in); @@ -305,14 +314,17 @@ static mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t valu //| """Sort the members of the group.""" //| ... //| +//| static mp_obj_t displayio_group_obj_sort(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { displayio_group_t *self = native_group(pos_args[0]); - mp_obj_t *args = m_new(mp_obj_t, n_args); + mp_obj_t *args = m_malloc_items(n_args); for (size_t i = 1; i < n_args; ++i) { args[i] = pos_args[i]; } args[0] = MP_OBJ_FROM_PTR(self->members); - return mp_obj_list_sort(n_args, args, kw_args); + mp_obj_t res = mp_obj_list_sort(n_args, args, kw_args); + m_del(mp_obj_t, args, n_args); + return res; } MP_DEFINE_CONST_FUN_OBJ_KW(displayio_group_sort_obj, 1, displayio_group_obj_sort); diff --git a/shared-bindings/displayio/OnDiskBitmap.c b/shared-bindings/displayio/OnDiskBitmap.c index fea3763657e..cd2161fd3b0 100644 --- a/shared-bindings/displayio/OnDiskBitmap.c +++ b/shared-bindings/displayio/OnDiskBitmap.c @@ -58,6 +58,7 @@ //| of CircuitPython will remove the ability to pass in an opened file. //| """ //| ... +//| static mp_obj_t displayio_ondiskbitmap_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); mp_obj_t arg = all_args[0]; @@ -106,6 +107,7 @@ MP_PROPERTY_GETTER(displayio_ondiskbitmap_height_obj, //| bitmap's structure. The pixel shader can be modified (e.g., to set the //| transparent pixel or, for palette shaded images, to update the palette.)""" //| +//| static mp_obj_t displayio_ondiskbitmap_obj_get_pixel_shader(mp_obj_t self_in) { displayio_ondiskbitmap_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_displayio_ondiskbitmap_get_pixel_shader(self); @@ -113,13 +115,8 @@ static mp_obj_t displayio_ondiskbitmap_obj_get_pixel_shader(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(displayio_ondiskbitmap_get_pixel_shader_obj, displayio_ondiskbitmap_obj_get_pixel_shader); -const mp_obj_property_t displayio_ondiskbitmap_pixel_shader_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&displayio_ondiskbitmap_get_pixel_shader_obj, - (mp_obj_t)MP_ROM_NONE, - (mp_obj_t)MP_ROM_NONE}, -}; - +MP_PROPERTY_GETTER(displayio_ondiskbitmap_pixel_shader_obj, + (mp_obj_t)&displayio_ondiskbitmap_get_pixel_shader_obj); static const mp_rom_map_elem_t displayio_ondiskbitmap_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&displayio_ondiskbitmap_height_obj) }, diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index 528df88ec4e..c69c8d11f25 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -25,6 +25,7 @@ //| :param bool dither: When true, dither the RGB color before converting to the display's color space //| """ //| ... +//| // TODO(tannewt): Add support for other color formats. // TODO(tannewt): Add support for 8-bit alpha blending. //| @@ -46,6 +47,7 @@ static mp_obj_t displayio_palette_make_new(const mp_obj_type_t *type, size_t n_a //| dither: bool //| """When `True` the Palette dithers the output color by adding random //| noise when truncating to display bitdepth""" +//| static mp_obj_t displayio_palette_obj_get_dither(mp_obj_t self_in) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_displayio_palette_get_dither(self)); @@ -69,6 +71,7 @@ MP_PROPERTY_GETSET(displayio_palette_dither_obj, //| def __len__(self) -> int: //| """Returns the number of colors in a Palette""" //| ... +//| static mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); switch (op) { @@ -102,6 +105,7 @@ static mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes //| palette[4] = (10, 20, 30) # set using a tuple of 3 integers""" //| ... +//| static mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item @@ -149,7 +153,10 @@ static mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t val return mp_const_none; } -//| def make_transparent(self, palette_index: int) -> None: ... +//| def make_transparent(self, palette_index: int) -> None: +//| """Makes the palette index transparent. The color is ignored.""" +//| ... +//| static mp_obj_t displayio_palette_obj_make_transparent(mp_obj_t self_in, mp_obj_t palette_index_obj) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); @@ -161,7 +168,11 @@ static mp_obj_t displayio_palette_obj_make_transparent(mp_obj_t self_in, mp_obj_ } MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_make_transparent_obj, displayio_palette_obj_make_transparent); -//| def make_opaque(self, palette_index: int) -> None: ... +//| +//| def make_opaque(self, palette_index: int) -> None: +//| """Mark the given palette index as opaque.""" +//| ... +//| static mp_obj_t displayio_palette_obj_make_opaque(mp_obj_t self_in, mp_obj_t palette_index_obj) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); @@ -173,10 +184,12 @@ static mp_obj_t displayio_palette_obj_make_opaque(mp_obj_t self_in, mp_obj_t pal } MP_DEFINE_CONST_FUN_OBJ_2(displayio_palette_make_opaque_obj, displayio_palette_obj_make_opaque); +//| //| def is_transparent(self, palette_index: int) -> bool: //| """Returns `True` if the palette index is transparent. Returns `False` if opaque.""" //| ... //| +//| static mp_obj_t displayio_palette_obj_is_transparent(mp_obj_t self_in, mp_obj_t palette_index_obj) { displayio_palette_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index 9800480b22a..fb5cabf05bf 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -17,6 +17,25 @@ #include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#if CIRCUITPY_TILEPALETTEMAPPER +#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h" +#endif + + +void displayio_tilegrid_validate_pixel_shader(mp_obj_t pixel_shader) { + bool valid_type = true; + if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) { + valid_type = false; + } + #if CIRCUITPY_TILEPALETTEMAPPER + if (mp_obj_is_type(pixel_shader, &tilepalettemapper_tilepalettemapper_type)) { + valid_type = true; + } + #endif + if (!valid_type) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader); + } +} //| class TileGrid: //| """A grid of tiles sourced out of one bitmap @@ -30,25 +49,26 @@ //| self, //| bitmap: Union[Bitmap, OnDiskBitmap], //| *, -//| pixel_shader: Union[ColorConverter, Palette], +//| pixel_shader: Union[ColorConverter, Palette, tilepalettemapper.TilePaletteMapper], //| width: int = 1, //| height: int = 1, //| tile_width: Optional[int] = None, //| tile_height: Optional[int] = None, //| default_tile: int = 0, //| x: int = 0, -//| y: int = 0 +//| y: int = 0, //| ) -> None: //| """Create a TileGrid object. The bitmap is source for 2d pixels. The pixel_shader is used to //| convert the value and its location to a display native pixel color. This may be a simple color //| palette lookup, a gradient, a pattern or a color transformer. //| -//| To save RAM usage, tile values are only allowed in the range from 0 to 255 inclusive (single byte values). +//| When the total number of tiles is 256 or less, tile values are stored as single bytes (uint8_t). +//| When the total number of tiles is more than 256, tile values are stored as double bytes (uint16_t). //| //| tile_width and tile_height match the height of the bitmap by default. //| //| :param Bitmap,OnDiskBitmap bitmap: The bitmap storing one or more tiles. -//| :param ColorConverter,Palette pixel_shader: The pixel shader that produces colors from values +//| :param ColorConverter,Palette,tilepalettemapper.TilePaletteMapper pixel_shader: The pixel shader that produces colors from values //| :param int width: Width of the grid in tiles. //| :param int height: Height of the grid in tiles. //| :param int tile_width: Width of a single tile in pixels. Defaults to the full Bitmap and must evenly divide into the Bitmap's dimensions. @@ -56,6 +76,7 @@ //| :param int default_tile: Default tile index to show. //| :param int x: Initial x position of the left edge within the parent. //| :param int y: Initial y position of the top edge within the parent.""" +//| static mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_bitmap, ARG_pixel_shader, ARG_width, ARG_height, ARG_tile_width, ARG_tile_height, ARG_default_tile, ARG_x, ARG_y }; static const mp_arg_t allowed_args[] = { @@ -88,10 +109,7 @@ static mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_ mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_bitmap); } mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; - if (!mp_obj_is_type(pixel_shader, &displayio_colorconverter_type) && - !mp_obj_is_type(pixel_shader, &displayio_palette_type)) { - mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader); - } + displayio_tilegrid_validate_pixel_shader(pixel_shader); uint16_t tile_width = args[ARG_tile_width].u_int; if (tile_width == 0) { tile_width = bitmap_width; @@ -115,6 +133,7 @@ static mp_obj_t displayio_tilegrid_make_new(const mp_obj_type_t *type, size_t n_ bitmap_width / tile_width, bitmap_height / tile_height, pixel_shader, args[ARG_width].u_int, args[ARG_height].u_int, tile_width, tile_height, x, y, args[ARG_default_tile].u_int); + return MP_OBJ_FROM_PTR(self); } @@ -275,6 +294,7 @@ MP_PROPERTY_GETSET(displayio_tilegrid_flip_y_obj, //| transpose_xy: bool //| """If true, the TileGrid's axis will be swapped. When combined with mirroring, any 90 degree //| rotation can be achieved along with the corresponding mirrored version.""" +//| static mp_obj_t displayio_tilegrid_obj_get_transpose_xy(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return mp_obj_new_bool(common_hal_displayio_tilegrid_get_transpose_xy(self)); @@ -296,8 +316,9 @@ MP_PROPERTY_GETSET(displayio_tilegrid_transpose_xy_obj, //| def contains(self, touch_tuple: tuple) -> bool: //| """Returns True if the first two values in ``touch_tuple`` represent an x,y coordinate //| inside the tilegrid rectangle bounds.""" +//| static mp_obj_t displayio_tilegrid_obj_contains(mp_obj_t self_in, mp_obj_t touch_tuple) { - displayio_tilegrid_t *self = MP_OBJ_TO_PTR(self_in); + displayio_tilegrid_t *self = native_tilegrid(self_in); mp_obj_t *touch_tuple_items; mp_obj_get_array_fixed_n(touch_tuple, 3, &touch_tuple_items); @@ -310,7 +331,7 @@ static mp_obj_t displayio_tilegrid_obj_contains(mp_obj_t self_in, mp_obj_t touch } MP_DEFINE_CONST_FUN_OBJ_2(displayio_tilegrid_contains_obj, displayio_tilegrid_obj_contains); -//| pixel_shader: Union[ColorConverter, Palette] +//| pixel_shader: Union[ColorConverter, Palette, tilepalettemapper.TilePaletteMapper] //| """The pixel shader of the tilegrid.""" static mp_obj_t displayio_tilegrid_obj_get_pixel_shader(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); @@ -320,10 +341,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(displayio_tilegrid_get_pixel_shader_obj, displayio_til static mp_obj_t displayio_tilegrid_obj_set_pixel_shader(mp_obj_t self_in, mp_obj_t pixel_shader) { displayio_tilegrid_t *self = native_tilegrid(self_in); - if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) { - mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader); - } - + displayio_tilegrid_validate_pixel_shader(pixel_shader); common_hal_displayio_tilegrid_set_pixel_shader(self, pixel_shader); return mp_const_none; @@ -336,6 +354,7 @@ MP_PROPERTY_GETSET(displayio_tilegrid_pixel_shader_obj, //| bitmap: Union[Bitmap, OnDiskBitmap] //| """The bitmap of the tilegrid.""" +//| static mp_obj_t displayio_tilegrid_obj_get_bitmap(mp_obj_t self_in) { displayio_tilegrid_t *self = native_tilegrid(self_in); return common_hal_displayio_tilegrid_get_bitmap(self); @@ -403,6 +422,7 @@ MP_PROPERTY_GETSET(displayio_tilegrid_bitmap_obj, //| grid[0,0] = 10""" //| ... //| +//| static mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { displayio_tilegrid_t *self = native_tilegrid(self_in); @@ -435,7 +455,7 @@ static mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t v return MP_OBJ_NULL; // op not supported } else { mp_int_t value = mp_obj_get_int(value_obj); - mp_arg_validate_int_range(value, 0, 255, MP_QSTR_tile); + mp_arg_validate_int_range(value, 0, self->tiles_in_bitmap - 1, MP_QSTR_tile); common_hal_displayio_tilegrid_set_tile(self, x, y, value); } diff --git a/shared-bindings/displayio/TileGrid.h b/shared-bindings/displayio/TileGrid.h index 19af39fadeb..35b2b2fd00c 100644 --- a/shared-bindings/displayio/TileGrid.h +++ b/shared-bindings/displayio/TileGrid.h @@ -13,7 +13,7 @@ extern const mp_obj_type_t displayio_tilegrid_type; void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height, - uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile); + uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint16_t default_tile); bool common_hal_displayio_tilegrid_get_hidden(displayio_tilegrid_t *self); void common_hal_displayio_tilegrid_set_hidden(displayio_tilegrid_t *self, bool hidden); @@ -43,9 +43,9 @@ uint16_t common_hal_displayio_tilegrid_get_height(displayio_tilegrid_t *self); uint16_t common_hal_displayio_tilegrid_get_tile_width(displayio_tilegrid_t *self); uint16_t common_hal_displayio_tilegrid_get_tile_height(displayio_tilegrid_t *self); -uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y); -void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index); +uint16_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y); +void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint16_t tile_index); // Private API for scrolling the TileGrid. void common_hal_displayio_tilegrid_set_top_left(displayio_tilegrid_t *self, uint16_t x, uint16_t y); -void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint8_t tile_index); +void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint16_t tile_index); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index acd48f5ea3c..970c4826476 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -43,7 +43,25 @@ //| refer to `this Learn guide //| `_. //| """ +//| +//| AnyDisplayBus = fourwire.FourWire | i2cdisplaybus.I2CDisplayBus | is31fl3741.IS31FL3741 +//| """Type-checking shorthand for any kind of display bus. Not actually defined in CircuitPython.""" +//| +//| AnyFramebuffer = ( +//| rgbmatrix.RGBMatrix +//| | is31fl3741.IS31FL3741_FrameBuffer +//| | sharpdisplay.SharpMemoryFramebuffer +//| | videocore.Framebuffer +//| | picodvi.Framebuffer +//| | aurora_epaper.AuroraMemoryFramebuffer +//| ) +//| """Type-checking shorthand for any kind of framebuffer. Not actually defined in CircuitPython.""" +//| +//| AnyDisplay = ( +//| busdisplay.BusDisplay | epaperdisplay.EPaperDisplay | framebufferio.FramebufferDisplay +//| ) +//| """Type-checking shorthand for any kind of display. Not actually defined in CircuitPython.""" //| CIRCUITPYTHON_TERMINAL: Group //| """The `displayio.Group` that is the displayed serial terminal (REPL).""" //| @@ -53,6 +71,7 @@ //| from fourwire import FourWire //| from i2cdisplaybus import I2CDisplayBus as I2CDisplay //| +//| //| def release_displays() -> None: //| """Releases any actively used displays so their buses and pins can be used again. This will also @@ -60,9 +79,15 @@ //| afterwards. This may take seconds to complete if an active EPaperDisplay is refreshing. //| //| Use this once in your code.py if you initialize a display. Place it right before the -//| initialization so the display is active as long as possible.""" +//| initialization so the display is active as long as possible. +//| +//| Once you release a builtin display (one that is initialized automatically, not by user code), +//| the display will remain released even if you restart the CircuitPython VM, for instance by typing ctrl-D. +//| The display is not re-initialized until you do a hard reset or manually initialize it again. +//| """ //| ... //| +//| static mp_obj_t displayio_release_displays(void) { common_hal_displayio_release_displays(); return mp_const_none; @@ -80,21 +105,8 @@ static const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, { MP_ROM_QSTR(MP_QSTR_TileGrid), MP_ROM_PTR(&displayio_tilegrid_type) }, - // Remove these in CircuitPython 10 - #if CIRCUITPY_BUSDISPLAY - { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&busdisplay_busdisplay_type) }, - #endif - #if CIRCUITPY_EPAPERDISPLAY - { MP_ROM_QSTR(MP_QSTR_EPaperDisplay), MP_ROM_PTR(&epaperdisplay_epaperdisplay_type) }, - #endif - #if CIRCUITPY_FOURWIRE - { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&fourwire_fourwire_type) }, - #endif - #if CIRCUITPY_I2CDISPLAYBUS - { MP_ROM_QSTR(MP_QSTR_I2CDisplay), MP_ROM_PTR(&i2cdisplaybus_i2cdisplaybus_type) }, - #endif - { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, + { MP_ROM_QSTR(MP_QSTR_CIRCUITPYTHON_TERMINAL), MP_ROM_PTR(&circuitpython_splash) }, }; static MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); diff --git a/shared-bindings/displayio/__init__.h b/shared-bindings/displayio/__init__.h index 33987ebe38a..583f6b217fa 100644 --- a/shared-bindings/displayio/__init__.h +++ b/shared-bindings/displayio/__init__.h @@ -23,6 +23,9 @@ typedef enum displayio_colorspace { } displayio_colorspace_t; void common_hal_displayio_release_displays(void); +mp_obj_t common_hal_displayio_get_primary_display(void); +void common_hal_displayio_set_primary_display(mp_obj_t o); +void common_hal_displayio_auto_primary_display(void); extern const mp_obj_type_t displayio_colorspace_type; extern const cp_enum_obj_t displayio_colorspace_RGB888_obj; @@ -46,4 +49,5 @@ typedef bool (*display_bus_begin_transaction)(mp_obj_t bus); typedef void (*display_bus_send)(mp_obj_t bus, display_byte_type_t byte_type, display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length); typedef void (*display_bus_end_transaction)(mp_obj_t bus); +typedef void (*display_bus_flush)(mp_obj_t bus); typedef void (*display_bus_collect_ptrs)(mp_obj_t bus); diff --git a/shared-bindings/dotclockframebuffer/DotClockFramebuffer.c b/shared-bindings/dotclockframebuffer/DotClockFramebuffer.c index 6b7aeefcfb7..beee1f07a5b 100644 --- a/shared-bindings/dotclockframebuffer/DotClockFramebuffer.c +++ b/shared-bindings/dotclockframebuffer/DotClockFramebuffer.c @@ -54,13 +54,6 @@ //| When a board has dedicated dot clock framebuffer pins and/or timings, they are intended to be used in the constructor with ``**`` dictionary unpacking like so: //| ``DotClockFramebuffer(**board.TFT_PINS, **board.TFT_TIMINGS)`` //| -//| On Espressif-family microcontrollers, this driver requires that the -//| ``CIRCUITPY_RESERVED_PSRAM`` in ``settings.toml`` be large enough to hold the -//| framebuffer. Generally, boards with built-in displays or display connectors -//| will have a default setting that is large enough for typical use. If the -//| constructor raises a MemoryError or an IDFError, this probably indicates the -//| setting is too small and should be increased. -//| //| TFT connection parameters: //| //| :param microcontroller.Pin de: The "data enable" input to the display @@ -93,6 +86,7 @@ //| #:param int overscan_right: Allocate additional non-visible columns right of the last display column //| #:param int overscan_bottom: Allocate additional non-visible rows below the last display row //| ... +//| static mp_obj_t dotclockframebuffer_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_de, ARG_vsync, ARG_hsync, ARG_dclk, ARG_red, ARG_green, ARG_blue, ARG_frequency, ARG_width, ARG_height, @@ -176,6 +170,7 @@ static void check_for_deinit(dotclockframebuffer_framebuffer_obj_t *self) { //| If this function is not called, the results are unpredictable; updates may be partially shown. //| """ //| ... +//| static mp_obj_t dotclockframebuffer_framebuffer_refresh(mp_obj_t self_in) { dotclockframebuffer_framebuffer_obj_t *self = (dotclockframebuffer_framebuffer_obj_t *)self_in; check_for_deinit(self); @@ -257,6 +252,7 @@ MP_PROPERTY_GETTER(dotclockframebuffer_framebuffer_row_stride_obj, //| //| On Espressif this value is **guaranteed** to be a multiple of the 2 (i.e., it is a whole number of pixels)""" //| +//| static mp_obj_t dotclockframebuffer_framebuffer_get_first_pixel_offset(mp_obj_t self_in) { dotclockframebuffer_framebuffer_obj_t *self = (dotclockframebuffer_framebuffer_obj_t *)self_in; check_for_deinit(self); diff --git a/shared-bindings/dotclockframebuffer/__init__.c b/shared-bindings/dotclockframebuffer/__init__.c index 7c24ff7fc77..700cd067178 100644 --- a/shared-bindings/dotclockframebuffer/__init__.c +++ b/shared-bindings/dotclockframebuffer/__init__.c @@ -17,6 +17,7 @@ //| //| Length = typing.Literal[1, 2] //| +//| //| def ioexpander_send_init_sequence( //| bus: busio.I2C, //| init_sequence: ReadableBuffer, @@ -61,6 +62,7 @@ //| :param Optional[ReadableBuffer] i2c_init_sequence: An initialization sequence to send to the I2C expander //| """ //| +//| static mp_obj_t ioexpander_send_init_sequence(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bus, ARG_init_sequence, ARG_i2c_address, ARG_gpio_address, ARG_gpio_data_len, ARG_gpio_data, ARG_cs_bit, ARG_mosi_bit, ARG_clk_bit, ARG_reset_bit, ARG_i2c_init_sequence, NUM_ARGS }; @@ -102,7 +104,7 @@ static mp_obj_t ioexpander_send_init_sequence(size_t n_args, const mp_obj_t *pos mp_arg_validate_int_range(cs_bit, 0, max_bit, MP_QSTR_cs_bit); mp_arg_validate_int_range(mosi_bit, 0, max_bit, MP_QSTR_mosi_bit); mp_arg_validate_int_range(clk_bit, 0, max_bit, MP_QSTR_clk_bit); - mp_arg_validate_int_range(gpio_data, 0, (1 << (max_bit * 8)) - 1, MP_QSTR_gpio_data); + mp_arg_validate_int_range(gpio_data, 0, (1 << (gpio_data_len * 8)) - 1, MP_QSTR_gpio_data); mp_int_t reset_mask = 0; if (args[ARG_reset_bit].u_obj != MP_ROM_NONE) { mp_int_t reset_bit = mp_arg_validate_int_range(mp_arg_validate_type_int(args[ARG_reset_bit].u_obj, MP_QSTR_reset_bit), 0, max_bit, MP_QSTR_reset_bit); diff --git a/shared-bindings/dualbank/__init__.c b/shared-bindings/dualbank/__init__.c index 2f7f5776d68..160ce4947a7 100644 --- a/shared-bindings/dualbank/__init__.c +++ b/shared-bindings/dualbank/__init__.c @@ -34,7 +34,7 @@ //| This module is unavailable as the flash is only large enough for one app partition. //| //| Boards with flash ``>2MB``: -//| This module is enabled/disabled at runtime based on whether the ``CIRCUITPY`` drive +//| This module is enabled/disabled at runtime based on whether the **CIRCUITPY** drive //| is extended or not. See `storage.erase_filesystem()` for more information. //| //| .. code-block:: python @@ -44,8 +44,10 @@ //| dualbank.flash(buffer, offset) //| dualbank.switch() //| """ +//| //| ... //| +//| #if CIRCUITPY_STORAGE_EXTEND static void raise_error_if_storage_extended(void) { @@ -65,6 +67,7 @@ static void raise_error_if_storage_extended(void) { //| """ //| ... //| +//| static mp_obj_t dualbank_flash(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_offset }; static const mp_arg_t allowed_args[] = { @@ -98,6 +101,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(dualbank_flash_obj, 0, dualbank_flash); //| """ //| ... //| +//| static mp_obj_t dualbank_switch(void) { #if CIRCUITPY_STORAGE_EXTEND raise_error_if_storage_extended(); diff --git a/shared-bindings/epaperdisplay/EPaperDisplay.c b/shared-bindings/epaperdisplay/EPaperDisplay.c index ea7296920e2..cd9c18e27d5 100644 --- a/shared-bindings/epaperdisplay/EPaperDisplay.c +++ b/shared-bindings/epaperdisplay/EPaperDisplay.c @@ -20,6 +20,7 @@ //| from busdisplay import _DisplayBus //| +//| //| class EPaperDisplay: //| """Manage updating an epaper display over a display bus //| @@ -28,7 +29,8 @@ //| is called. This is done so that CircuitPython can use the display itself. //| //| Most people should not use this class directly. Use a specific display driver instead that will -//| contain the startup and shutdown sequences at minimum.""" +//| contain the startup and shutdown sequences at minimum. +//| """ //| //| def __init__( //| self, @@ -52,6 +54,7 @@ //| write_color_ram_command: Optional[int] = None, //| color_bits_inverted: bool = False, //| highlight_color: int = 0x000000, +//| highlight_color2: int = 0x000000, //| refresh_display_command: Union[int, circuitpython_typing.ReadableBuffer], //| refresh_time: float = 40, //| busy_pin: Optional[microcontroller.Pin] = None, @@ -60,9 +63,10 @@ //| always_toggle_chip_select: bool = False, //| grayscale: bool = False, //| advanced_color_epaper: bool = False, +//| spectra6: bool = False, //| two_byte_sequence_length: bool = False, //| start_up_time: float = 0, -//| address_little_endian: bool = False +//| address_little_endian: bool = False, //| ) -> None: //| """Create a EPaperDisplay object on the given display bus (`fourwire.FourWire` or `paralleldisplaybus.ParallelBus`). //| @@ -94,6 +98,7 @@ //| :param int write_color_ram_command: Command used to write pixels values into the update region //| :param bool color_bits_inverted: True if 0 bits are used to show the color. Otherwise, 1 means to show color. //| :param int highlight_color: RGB888 of source color to highlight with third ePaper color. +//| :param int highlight_color2: RGB888 of source color to highlight with fourth ePaper color. //| :param int refresh_display_command: Command used to start a display refresh. Single int or byte-packed command sequence //| :param float refresh_time: Time it takes to refresh the display before the stop_sequence should be sent. Ignored when busy_pin is provided. //| :param microcontroller.Pin busy_pin: Pin used to signify the display is busy @@ -102,19 +107,21 @@ //| :param bool always_toggle_chip_select: When True, chip select is toggled every byte //| :param bool grayscale: When true, the color ram is the low bit of 2-bit grayscale //| :param bool advanced_color_epaper: When true, the display is a 7-color advanced color epaper (ACeP) +//| :param bool spectra6: When true, the display is a 6-color spectra6 epaper //| :param bool two_byte_sequence_length: When true, use two bytes to define sequence length //| :param float start_up_time: Time to wait after reset before sending commands //| :param bool address_little_endian: Send the least significant byte (not bit) of multi-byte addresses first. Ignored when ram is addressed with one byte //| """ //| ... +//| static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_display_bus, ARG_start_sequence, ARG_stop_sequence, ARG_width, ARG_height, ARG_ram_width, ARG_ram_height, ARG_colstart, ARG_rowstart, ARG_rotation, ARG_set_column_window_command, ARG_set_row_window_command, ARG_set_current_column_command, ARG_set_current_row_command, ARG_write_black_ram_command, ARG_black_bits_inverted, - ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, + ARG_write_color_ram_command, ARG_color_bits_inverted, ARG_highlight_color, ARG_highlight_color2, ARG_refresh_display_command, ARG_refresh_time, ARG_busy_pin, ARG_busy_state, - ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper, + ARG_seconds_per_frame, ARG_always_toggle_chip_select, ARG_grayscale, ARG_advanced_color_epaper, ARG_spectra6, ARG_two_byte_sequence_length, ARG_start_up_time, ARG_address_little_endian }; static const mp_arg_t allowed_args[] = { { MP_QSTR_display_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -136,6 +143,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, { MP_QSTR_write_color_ram_command, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, { MP_QSTR_color_bits_inverted, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_highlight_color, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} }, + { MP_QSTR_highlight_color2, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0x000000} }, { MP_QSTR_refresh_display_command, MP_ARG_OBJ | MP_ARG_REQUIRED }, { MP_QSTR_refresh_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(40)} }, { MP_QSTR_busy_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, @@ -144,6 +152,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, { MP_QSTR_always_toggle_chip_select, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_grayscale, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_advanced_color_epaper, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + { MP_QSTR_spectra6, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_two_byte_sequence_length, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, { MP_QSTR_start_up_time, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(0)} }, { MP_QSTR_address_little_endian, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, @@ -175,6 +184,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, mp_int_t write_color_ram_command = NO_COMMAND; mp_int_t highlight_color = args[ARG_highlight_color].u_int; + mp_int_t highlight_color2 = args[ARG_highlight_color2].u_int; if (args[ARG_write_color_ram_command].u_obj != mp_const_none) { write_color_ram_command = mp_obj_get_int(args[ARG_write_color_ram_command].u_obj); } @@ -187,7 +197,7 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, size_t refresh_buf_len = 0; mp_int_t refresh_command; if (mp_obj_get_int_maybe(refresh_obj, &refresh_command)) { - uint8_t *command_buf = m_malloc(3); + uint8_t *command_buf = m_malloc_without_collect(3); command_buf[0] = refresh_command; command_buf[1] = 0; command_buf[2] = 0; @@ -201,20 +211,43 @@ static mp_obj_t epaperdisplay_epaperdisplay_make_new(const mp_obj_type_t *type, } self->base.type = &epaperdisplay_epaperdisplay_type; - common_hal_epaperdisplay_epaperdisplay_construct( - self, - display_bus, - start_bufinfo.buf, start_bufinfo.len, start_up_time, stop_bufinfo.buf, stop_bufinfo.len, - args[ARG_width].u_int, args[ARG_height].u_int, args[ARG_ram_width].u_int, args[ARG_ram_height].u_int, - args[ARG_colstart].u_int, args[ARG_rowstart].u_int, rotation, - args[ARG_set_column_window_command].u_int, args[ARG_set_row_window_command].u_int, - args[ARG_set_current_column_command].u_int, args[ARG_set_current_row_command].u_int, - args[ARG_write_black_ram_command].u_int, args[ARG_black_bits_inverted].u_bool, write_color_ram_command, - args[ARG_color_bits_inverted].u_bool, highlight_color, refresh_buf, refresh_buf_len, refresh_time, - busy_pin, args[ARG_busy_state].u_bool, seconds_per_frame, - args[ARG_always_toggle_chip_select].u_bool, args[ARG_grayscale].u_bool, args[ARG_advanced_color_epaper].u_bool, - two_byte_sequence_length, args[ARG_address_little_endian].u_bool - ); + epaperdisplay_construct_args_t construct_args = EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS; + construct_args.bus = display_bus; + construct_args.start_sequence = start_bufinfo.buf; + construct_args.start_sequence_len = start_bufinfo.len; + construct_args.start_up_time = start_up_time; + construct_args.stop_sequence = stop_bufinfo.buf; + construct_args.stop_sequence_len = stop_bufinfo.len; + construct_args.width = args[ARG_width].u_int; + construct_args.height = args[ARG_height].u_int; + construct_args.ram_width = args[ARG_ram_width].u_int; + construct_args.ram_height = args[ARG_ram_height].u_int; + construct_args.colstart = args[ARG_colstart].u_int; + construct_args.rowstart = args[ARG_rowstart].u_int; + construct_args.rotation = rotation; + construct_args.set_column_window_command = args[ARG_set_column_window_command].u_int; + construct_args.set_row_window_command = args[ARG_set_row_window_command].u_int; + construct_args.set_current_column_command = args[ARG_set_current_column_command].u_int; + construct_args.set_current_row_command = args[ARG_set_current_row_command].u_int; + construct_args.write_black_ram_command = args[ARG_write_black_ram_command].u_int; + construct_args.black_bits_inverted = args[ARG_black_bits_inverted].u_bool; + construct_args.write_color_ram_command = write_color_ram_command; + construct_args.color_bits_inverted = args[ARG_color_bits_inverted].u_bool; + construct_args.highlight_color = highlight_color; + construct_args.highlight_color2 = highlight_color2; + construct_args.refresh_sequence = refresh_buf; + construct_args.refresh_sequence_len = refresh_buf_len; + construct_args.refresh_time = refresh_time; + construct_args.busy_pin = busy_pin; + construct_args.busy_state = args[ARG_busy_state].u_bool; + construct_args.seconds_per_frame = seconds_per_frame; + construct_args.always_toggle_chip_select = args[ARG_always_toggle_chip_select].u_bool; + construct_args.grayscale = args[ARG_grayscale].u_bool; + construct_args.acep = args[ARG_advanced_color_epaper].u_bool; + construct_args.spectra6 = args[ARG_spectra6].u_bool; + construct_args.two_byte_sequence_length = two_byte_sequence_length; + construct_args.address_little_endian = args[ARG_address_little_endian].u_bool; + common_hal_epaperdisplay_epaperdisplay_construct(self, &construct_args); return self; } @@ -238,6 +271,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(epaperdisplay_epaperdisplay_show_obj, epaperdisplay_ep //| ) -> None: //| """Updates the ``start_sequence`` and ``seconds_per_frame`` parameters to enable //| varying the refresh mode of the display.""" +//| static mp_obj_t epaperdisplay_epaperdisplay_update_refresh_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_start_sequence, ARG_seconds_per_frame }; static const mp_arg_t allowed_args[] = { @@ -263,6 +297,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(epaperdisplay_epaperdisplay_update_refresh_mode_obj, //| """Refreshes the display immediately or raises an exception if too soon. Use //| ``time.sleep(display.time_to_refresh)`` to sleep until a refresh can occur.""" //| ... +//| static mp_obj_t epaperdisplay_epaperdisplay_obj_refresh(mp_obj_t self_in) { epaperdisplay_epaperdisplay_obj_t *self = native_display(self_in); bool ok = common_hal_epaperdisplay_epaperdisplay_refresh(self); @@ -360,6 +395,7 @@ MP_PROPERTY_GETTER(epaperdisplay_epaperdisplay_bus_obj, //| If the root group is set to ``None``, no output will be shown. //| """ //| +//| static mp_obj_t epaperdisplay_epaperdisplay_obj_get_root_group(mp_obj_t self_in) { epaperdisplay_epaperdisplay_obj_t *self = native_display(self_in); return common_hal_epaperdisplay_epaperdisplay_get_root_group(self); diff --git a/shared-bindings/epaperdisplay/EPaperDisplay.h b/shared-bindings/epaperdisplay/EPaperDisplay.h index d4475e0a6aa..83f0b0377fe 100644 --- a/shared-bindings/epaperdisplay/EPaperDisplay.h +++ b/shared-bindings/epaperdisplay/EPaperDisplay.h @@ -15,19 +15,84 @@ extern const mp_obj_type_t epaperdisplay_epaperdisplay_type; #define NO_COMMAND 0x100 +typedef struct { + mp_obj_t bus; + const uint8_t *start_sequence; + uint16_t start_sequence_len; + mp_float_t start_up_time; + const uint8_t *stop_sequence; + uint16_t stop_sequence_len; + uint16_t width; + uint16_t height; + uint16_t ram_width; + uint16_t ram_height; + int16_t colstart; + int16_t rowstart; + uint16_t rotation; + uint16_t set_column_window_command; + uint16_t set_row_window_command; + uint16_t set_current_column_command; + uint16_t set_current_row_command; + uint16_t write_black_ram_command; + bool black_bits_inverted; + uint16_t write_color_ram_command; + bool color_bits_inverted; + uint32_t highlight_color; + uint32_t highlight_color2; + const uint8_t *refresh_sequence; + uint16_t refresh_sequence_len; + mp_float_t refresh_time; + const mcu_pin_obj_t *busy_pin; + bool busy_state; + mp_float_t seconds_per_frame; + bool always_toggle_chip_select; + bool grayscale; + bool acep; + bool spectra6; + bool two_byte_sequence_length; + bool address_little_endian; +} epaperdisplay_construct_args_t; + +#define EPAPERDISPLAY_CONSTRUCT_ARGS_DEFAULTS { \ + .bus = mp_const_none, \ + .start_sequence = NULL, \ + .start_sequence_len = 0, \ + .start_up_time = 0.0, \ + .stop_sequence = NULL, \ + .stop_sequence_len = 0, \ + .width = 0, \ + .height = 0, \ + .ram_width = 0, \ + .ram_height = 0, \ + .colstart = 0, \ + .rowstart = 0, \ + .rotation = 0, \ + .set_column_window_command = NO_COMMAND, \ + .set_row_window_command = NO_COMMAND, \ + .set_current_column_command = NO_COMMAND, \ + .set_current_row_command = NO_COMMAND, \ + .write_black_ram_command = NO_COMMAND, \ + .black_bits_inverted = false, \ + .write_color_ram_command = NO_COMMAND, \ + .color_bits_inverted = false, \ + .highlight_color = 0x000000, \ + .highlight_color2 = 0x000000, \ + .refresh_sequence = NULL, \ + .refresh_sequence_len = 0, \ + .refresh_time = 0.0, \ + .busy_pin = NULL, \ + .busy_state = false, \ + .seconds_per_frame = 0.0, \ + .always_toggle_chip_select = false, \ + .grayscale = false, \ + .acep = false, \ + .spectra6 = false, \ + .two_byte_sequence_length = false, \ + .address_little_endian = false \ +} + void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdisplay_obj_t *self, - mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time, - const uint8_t *stop_sequence, uint16_t stop_sequence_len, - uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, - int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t set_column_window_command, uint16_t set_row_window_command, - uint16_t set_current_column_command, uint16_t set_current_row_command, - uint16_t write_black_ram_command, bool black_bits_inverted, - uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, - const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, - const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, - bool always_toggle_chip_select, bool grayscale, bool acep, bool two_byte_sequence_length, - bool address_little_endian); + const epaperdisplay_construct_args_t *args); bool common_hal_epaperdisplay_epaperdisplay_refresh(epaperdisplay_epaperdisplay_obj_t *self); diff --git a/shared-bindings/epaperdisplay/__init__.c b/shared-bindings/epaperdisplay/__init__.c index 1b18212a35a..eff31cb01b3 100644 --- a/shared-bindings/epaperdisplay/__init__.c +++ b/shared-bindings/epaperdisplay/__init__.c @@ -13,9 +13,7 @@ #include "shared-bindings/epaperdisplay/__init__.h" #include "shared-bindings/epaperdisplay/EPaperDisplay.h" -//| """Displays a `displayio` object tree on an e-paper display -//| -//| """ +//| """Displays a `displayio` object tree on an e-paper display""" static const mp_rom_map_elem_t epaperdisplay_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) }, diff --git a/shared-bindings/floppyio/__init__.c b/shared-bindings/floppyio/__init__.c index 09f2dc0e860..09034b4675d 100644 --- a/shared-bindings/floppyio/__init__.c +++ b/shared-bindings/floppyio/__init__.c @@ -40,6 +40,7 @@ //| """ //| ... //| +//| static mp_obj_t floppyio_flux_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { #if CIRCUITPY_DIGITALIO enum { ARG_buffer, ARG_data, ARG_index, ARG_index_wait }; @@ -119,6 +120,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(floppyio_flux_readinto_obj, 0, floppyio_flux_readinto //| """ //| ... //| +//| static mp_obj_t floppyio_mfm_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_flux, ARG_t2_max, ARG_t3_max, ARG_validity, ARG_clear_validity }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/fontio/BuiltinFont.c b/shared-bindings/fontio/BuiltinFont.c index 9d3f30675b9..4969aed637d 100644 --- a/shared-bindings/fontio/BuiltinFont.c +++ b/shared-bindings/fontio/BuiltinFont.c @@ -17,6 +17,7 @@ //| from typing_extensions import Protocol # for compat with python < 3.8 //| +//| //| class FontProtocol(Protocol): //| """A protocol shared by `BuiltinFont` and classes in ``adafruit_bitmap_font``""" //| @@ -34,6 +35,7 @@ //| If the code point is not present in the font, `None` is returned.""" //| pass //| +//| //| class BuiltinFont: //| """A font built into CircuitPython""" @@ -43,11 +45,13 @@ //| `Adafruit_CircuitPython_Bitmap_Font `_ //| library for dynamically loaded fonts.""" //| ... +//| //| bitmap: displayio.Bitmap //| """Bitmap containing all font glyphs starting with ASCII and followed by unicode. Use //| `get_glyph` in most cases. This is useful for use with `displayio.TileGrid` and //| `terminalio.Terminal`.""" +//| static mp_obj_t fontio_builtinfont_obj_get_bitmap(mp_obj_t self_in) { fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_fontio_builtinfont_get_bitmap(self); @@ -60,6 +64,7 @@ MP_PROPERTY_GETTER(fontio_builtinfont_bitmap_obj, //| def get_bounding_box(self) -> Tuple[int, int]: //| """Returns the maximum bounds of all glyphs in the font in a tuple of two values: width, height.""" //| ... +//| static mp_obj_t fontio_builtinfont_obj_get_bounding_box(mp_obj_t self_in) { fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); @@ -72,6 +77,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(fontio_builtinfont_get_bounding_box_obj, fontio_builti //| """Returns a `fontio.Glyph` for the given codepoint or None if no glyph is available.""" //| ... //| +//| static mp_obj_t fontio_builtinfont_obj_get_glyph(mp_obj_t self_in, mp_obj_t codepoint_obj) { fontio_builtinfont_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/fontio/Glyph.c b/shared-bindings/fontio/Glyph.c index 009fcb06060..5651cb3d0f2 100644 --- a/shared-bindings/fontio/Glyph.c +++ b/shared-bindings/fontio/Glyph.c @@ -34,6 +34,7 @@ //| :param shift_y: the y difference to the next glyph""" //| ... //| +//| const mp_obj_namedtuple_type_t fontio_glyph_type = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_Glyph), .n_fields = 8, diff --git a/shared-bindings/fourwire/FourWire.c b/shared-bindings/fourwire/FourWire.c index bddd772c2e6..608645aaebf 100644 --- a/shared-bindings/fourwire/FourWire.c +++ b/shared-bindings/fourwire/FourWire.c @@ -20,18 +20,22 @@ //| class FourWire: //| """Manage updating a display over SPI four wire protocol in the background while Python code runs. -//| It doesn't handle display initialization.""" +//| It doesn't handle display initialization. +//| +//| .. seealso:: See `busdisplay.BusDisplay` and `epaperdisplay.EPaperDisplay` +//| for how to initialize a display, given a `FourWire` bus. +//| """ //| //| def __init__( //| self, //| spi_bus: busio.SPI, //| *, -//| command: Optional[microcontroller.Pin], -//| chip_select: Optional[microcontroller.Pin], -//| reset: Optional[microcontroller.Pin] = None, +//| command: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, +//| chip_select: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, +//| reset: Optional[Union[microcontroller.Pin, digitalio.DigitalInOutProtocol]] = None, //| baudrate: int = 24000000, //| polarity: int = 0, -//| phase: int = 0 +//| phase: int = 0, //| ) -> None: //| """Create a FourWire object associated with the given pins. //| @@ -54,6 +58,7 @@ //| :param int phase: the edge of the clock that data is captured. First (0) //| or second (1). Rising or falling depends on clock polarity.""" //| ... +//| static mp_obj_t fourwire_fourwire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_spi_bus, ARG_command, ARG_chip_select, ARG_reset, ARG_baudrate, ARG_polarity, ARG_phase }; static const mp_arg_t allowed_args[] = { @@ -68,10 +73,6 @@ static mp_obj_t fourwire_fourwire_make_new(const mp_obj_type_t *type, size_t n_a mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - const mcu_pin_obj_t *command = validate_obj_is_free_pin_or_none(args[ARG_command].u_obj, MP_QSTR_command); - const mcu_pin_obj_t *chip_select = validate_obj_is_free_pin_or_none(args[ARG_chip_select].u_obj, MP_QSTR_chip_select); - const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj, MP_QSTR_reset); - mp_obj_t spi = mp_arg_validate_type(args[ARG_spi_bus].u_obj, &busio_spi_type, MP_QSTR_spi_bus); fourwire_fourwire_obj_t *self = &allocate_display_bus_or_raise()->fourwire_bus; @@ -81,7 +82,7 @@ static mp_obj_t fourwire_fourwire_make_new(const mp_obj_type_t *type, size_t n_a uint8_t phase = (uint8_t)mp_arg_validate_int_range(args[ARG_phase].u_int, 0, 1, MP_QSTR_phase); common_hal_fourwire_fourwire_construct(self, - MP_OBJ_TO_PTR(spi), command, chip_select, reset, args[ARG_baudrate].u_int, polarity, phase); + MP_OBJ_TO_PTR(spi), args[ARG_command].u_obj, args[ARG_chip_select].u_obj, args[ARG_reset].u_obj, args[ARG_baudrate].u_int, polarity, phase); return self; } @@ -89,6 +90,7 @@ static mp_obj_t fourwire_fourwire_make_new(const mp_obj_type_t *type, size_t n_a //| """Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin //| is available.""" //| ... +//| static mp_obj_t fourwire_fourwire_obj_reset(mp_obj_t self_in) { fourwire_fourwire_obj_t *self = self_in; @@ -106,6 +108,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(fourwire_fourwire_reset_obj, fourwire_fourwire_obj_res //| vertical scroll, set via ``send`` may or may not be reset once the code is done.""" //| ... //| +//| static mp_obj_t fourwire_fourwire_obj_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_command, ARG_data, ARG_toggle_every_byte }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/fourwire/FourWire.h b/shared-bindings/fourwire/FourWire.h index 515a466b4b9..3e77c25434d 100644 --- a/shared-bindings/fourwire/FourWire.h +++ b/shared-bindings/fourwire/FourWire.h @@ -16,8 +16,8 @@ extern const mp_obj_type_t fourwire_fourwire_type; void common_hal_fourwire_fourwire_construct(fourwire_fourwire_obj_t *self, - busio_spi_obj_t *spi, const mcu_pin_obj_t *command, - const mcu_pin_obj_t *chip_select, const mcu_pin_obj_t *reset, uint32_t baudrate, + busio_spi_obj_t *spi, mp_obj_t command, + mp_obj_t chip_select, mp_obj_t reset, uint32_t baudrate, uint8_t polarity, uint8_t phase); void common_hal_fourwire_fourwire_deinit(fourwire_fourwire_obj_t *self); diff --git a/shared-bindings/fourwire/__init__.c b/shared-bindings/fourwire/__init__.c index 34542db97a7..659d9482cb5 100644 --- a/shared-bindings/fourwire/__init__.c +++ b/shared-bindings/fourwire/__init__.c @@ -13,9 +13,7 @@ #include "shared-bindings/fourwire/__init__.h" #include "shared-bindings/fourwire/FourWire.h" -//| """Connects to a BusDisplay over a four wire bus -//| -//| """ +//| """Connects to a BusDisplay over a four wire bus""" static const mp_rom_map_elem_t fourwire_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_fourwire) }, diff --git a/shared-bindings/framebufferio/FramebufferDisplay.c b/shared-bindings/framebufferio/FramebufferDisplay.c index 29242d3a632..71ce18a1b4b 100644 --- a/shared-bindings/framebufferio/FramebufferDisplay.c +++ b/shared-bindings/framebufferio/FramebufferDisplay.c @@ -31,7 +31,7 @@ //| framebuffer: circuitpython_typing.FrameBuffer, //| *, //| rotation: int = 0, -//| auto_refresh: bool = True +//| auto_refresh: bool = True, //| ) -> None: //| """Create a Display object with the given framebuffer (a buffer, array, ulab.array, etc) //| @@ -40,6 +40,7 @@ //| :param int rotation: The rotation of the display in degrees clockwise. Must be in 90 degree increments (0, 90, 180, 270) //| """ //| ... +//| static mp_obj_t framebufferio_framebufferdisplay_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_framebuffer, ARG_rotation, ARG_auto_refresh, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -89,7 +90,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_show_obj, framebuffer //| self, //| *, //| target_frames_per_second: Optional[int] = None, -//| minimum_frames_per_second: int = 0 +//| minimum_frames_per_second: int = 0, //| ) -> bool: //| """When auto_refresh is off, and :py:attr:`target_frames_per_second` is not `None` this waits //| for the target frame rate and then refreshes the display, @@ -111,6 +112,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(framebufferio_framebufferdisplay_show_obj, framebuffer //| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. //| """ //| ... +//| static mp_obj_t framebufferio_framebufferdisplay_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; static const mp_arg_t allowed_args[] = { @@ -232,6 +234,7 @@ MP_PROPERTY_GETSET(framebufferio_framebufferdisplay_rotation_obj, //| framebuffer: circuitpython_typing.FrameBuffer //| """The framebuffer being used by the display""" +//| static mp_obj_t framebufferio_framebufferdisplay_obj_get_framebuffer(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return common_hal_framebufferio_framebufferdisplay_get_framebuffer(self); @@ -249,6 +252,7 @@ MP_PROPERTY_GETTER(framebufferio_framebufferframebuffer_obj, //| :param ~circuitpython_typing.WriteableBuffer buffer: The buffer in which to place the pixel data //| """ //| ... +//| static mp_obj_t framebufferio_framebufferdisplay_obj_fill_row(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_y, ARG_buffer }; static const mp_arg_t allowed_args[] = { @@ -309,6 +313,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_fill_row_obj, 1, fra //| If the root group is set to ``None``, no output will be shown. //| """ //| +//| static mp_obj_t framebufferio_framebufferdisplay_obj_get_root_group(mp_obj_t self_in) { framebufferio_framebufferdisplay_obj_t *self = native_display(self_in); return common_hal_framebufferio_framebufferdisplay_get_root_group(self); diff --git a/shared-bindings/frequencyio/FrequencyIn.c b/shared-bindings/frequencyio/FrequencyIn.c index 6d76d00d0fa..d742655b11d 100644 --- a/shared-bindings/frequencyio/FrequencyIn.c +++ b/shared-bindings/frequencyio/FrequencyIn.c @@ -49,6 +49,7 @@ //| # as the value. //| frequency.clear()""" //| ... +//| static mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_check_num(n_args, n_kw, 1, 1, true); @@ -73,6 +74,7 @@ static mp_obj_t frequencyio_frequencyin_make_new(const mp_obj_type_t *type, size //| def deinit(self) -> None: //| """Deinitialises the FrequencyIn and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t frequencyio_frequencyin_deinit(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_frequencyio_frequencyin_deinit(self); @@ -89,22 +91,20 @@ static void check_for_deinit(frequencyio_frequencyin_obj_t *self) { //| def __enter__(self) -> FrequencyIn: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t frequencyio_frequencyin_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_frequencyio_frequencyin_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(frequencyio_frequencyin___exit___obj, 4, 4, frequencyio_frequencyin_obj___exit__); +//| +// Provided by context manager helper. //| def pause(self) -> None: //| """Pause frequency capture.""" //| ... +//| static mp_obj_t frequencyio_frequencyin_obj_pause(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -117,6 +117,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_pause_obj, frequencyio_frequen //| def resume(self) -> None: //| """Resumes frequency capture.""" //| ... +//| static mp_obj_t frequencyio_frequencyin_obj_resume(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -129,6 +130,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_resume_obj, frequencyio_freque //| def clear(self) -> None: //| """Clears the last detected frequency capture value.""" //| ... +//| static mp_obj_t frequencyio_frequencyin_obj_clear(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -146,6 +148,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(frequencyio_frequencyin_clear_obj, frequencyio_frequen //| //| .. note:: When setting a new ``capture_period``, all previous capture information is //| cleared with a call to ``clear()``.""" +//| static mp_obj_t frequencyio_frequencyin_obj_get_capture_period(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -171,6 +174,7 @@ MP_PROPERTY_GETSET(frequencyio_frequencyin_capture_period_obj, //| """Returns the value of the last frequency captured.""" //| ... //| +//| static mp_obj_t frequencyio_frequencyin_obj_get_value(mp_obj_t self_in) { frequencyio_frequencyin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -188,7 +192,7 @@ static const mp_rom_map_elem_t frequencyio_frequencyin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&frequencyio_frequencyin_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&frequencyio_frequencyin_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&frequencyio_frequencyin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&frequencyio_frequencyin_value_obj) }, { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&frequencyio_frequencyin_pause_obj) }, { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&frequencyio_frequencyin_resume_obj) }, diff --git a/shared-bindings/getpass/__init__.c b/shared-bindings/getpass/__init__.c index b779311f5fc..54a860aa569 100644 --- a/shared-bindings/getpass/__init__.c +++ b/shared-bindings/getpass/__init__.c @@ -12,8 +12,10 @@ //| This module provides a way to get input from user without echoing it. //| //| """ +//| //| ... //| +//| //| def getpass(prompt: Optional[str] = "Password: ", stream: Optional[io.FileIO] = None) -> str: //| """Prompt the user without echoing. @@ -24,6 +26,7 @@ //| """ //| ... //| +//| static mp_obj_t getpass_getpass(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_prompt, ARG_stream }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/gifio/GifWriter.c b/shared-bindings/gifio/GifWriter.c index c1a2c69c599..f649a9299c0 100644 --- a/shared-bindings/gifio/GifWriter.c +++ b/shared-bindings/gifio/GifWriter.c @@ -33,6 +33,7 @@ //| :param dither: If True, and the image is in color, a simple ordered dither is applied. //| """ //| ... +//| static mp_obj_t gifio_gifwriter_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_file, ARG_width, ARG_height, ARG_colorspace, ARG_loop, ARG_dither }; static const mp_arg_t allowed_args[] = { @@ -71,12 +72,14 @@ static mp_obj_t gifio_gifwriter_make_new(const mp_obj_type_t *type, size_t n_arg //| def __enter__(self) -> GifWriter: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... +//| static mp_obj_t gifio_gifwriter___exit__(size_t n_args, const mp_obj_t *args) { gifio_gifwriter_t *self = MP_OBJ_TO_PTR(args[0]); shared_module_gifio_gifwriter_deinit(self); @@ -87,6 +90,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gifio_gifwriter___exit___obj, 4, 4, gifio_gi //| def deinit(self) -> None: //| """Close the underlying file.""" //| ... +//| static mp_obj_t gifio_gifwriter_deinit(mp_obj_t self_in) { gifio_gifwriter_t *self = MP_OBJ_TO_PTR(self_in); shared_module_gifio_gifwriter_deinit(self); @@ -102,6 +106,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(gifio_gifwriter_deinit_obj, gifio_gifwriter_deinit); //| """ //| ... //| +//| static mp_obj_t gifio_gifwriter_add_frame(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bitmap, ARG_delay }; static const mp_arg_t allowed_args[] = { @@ -131,7 +136,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(gifio_gifwriter_add_frame_obj, 1, gifio_gifwriter_add static const mp_rom_map_elem_t gifio_gifwriter_locals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_GifWriter) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&gifio_gifwriter___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gifio_gifwriter_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_add_frame), MP_ROM_PTR(&gifio_gifwriter_add_frame_obj) }, }; diff --git a/shared-bindings/gifio/OnDiskGif.c b/shared-bindings/gifio/OnDiskGif.c index 10913233f87..092d9dd19cf 100644 --- a/shared-bindings/gifio/OnDiskGif.c +++ b/shared-bindings/gifio/OnDiskGif.c @@ -101,6 +101,7 @@ //| is not limited but images that are too large will cause a memory exception. //| """ //| ... +//| static mp_obj_t gifio_ondiskgif_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_filename, ARG_use_palette, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -135,18 +136,15 @@ static void check_for_deinit(gifio_ondiskgif_t *self) { //| def __enter__(self) -> OnDiskGif: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the GIF when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t gifio_ondiskgif_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_gifio_ondiskgif_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gifio_ondiskgif___exit___obj, 4, 4, gifio_ondiskgif_obj___exit__); +//| +// Provided by context manager helper. //| width: int //| """Width of the gif. (read only)""" @@ -192,6 +190,7 @@ MP_PROPERTY_GETTER(gifio_ondiskgif_bitmap_obj, //| palette: Optional[displayio.Palette] //| """The palette for the current frame if it exists.""" +//| static mp_obj_t gifio_ondiskgif_obj_get_palette(mp_obj_t self_in) { gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); @@ -206,6 +205,7 @@ MP_PROPERTY_GETTER(gifio_ondiskgif_palette_obj, //| def next_frame(self) -> float: //| """Loads the next frame. Returns expected delay before the next frame in seconds.""" +//| static mp_obj_t gifio_ondiskgif_obj_next_frame(mp_obj_t self_in) { gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); @@ -277,6 +277,7 @@ MP_PROPERTY_GETTER(gifio_ondiskgif_max_delay_obj, //| """Release resources allocated by OnDiskGif.""" //| ... //| +//| static mp_obj_t gifio_ondiskgif_obj_deinit(mp_obj_t self_in) { gifio_ondiskgif_t *self = MP_OBJ_TO_PTR(self_in); common_hal_gifio_ondiskgif_deinit(self); @@ -287,7 +288,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(gifio_ondiskgif_deinit_obj, gifio_ondiskgif_obj_deinit static const mp_rom_map_elem_t gifio_ondiskgif_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&gifio_ondiskgif_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&gifio_ondiskgif___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&gifio_ondiskgif_height_obj) }, { MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&gifio_ondiskgif_bitmap_obj) }, { MP_ROM_QSTR(MP_QSTR_palette), MP_ROM_PTR(&gifio_ondiskgif_palette_obj) }, diff --git a/shared-bindings/gifio/__init__.c b/shared-bindings/gifio/__init__.c index 057d18ce82d..2c1d5c89246 100644 --- a/shared-bindings/gifio/__init__.c +++ b/shared-bindings/gifio/__init__.c @@ -10,11 +10,10 @@ #include "shared-bindings/gifio/OnDiskGif.h" #include "shared-bindings/util.h" -//| """Access GIF-format images -//| """ +//| """Access GIF-format images""" static const mp_rom_map_elem_t gifio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_gifio) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_GifWriter), MP_ROM_PTR(&gifio_gifwriter_type)}, + { MP_ROM_QSTR(MP_QSTR_GifWriter), MP_ROM_PTR(&gifio_gifwriter_type)}, { MP_ROM_QSTR(MP_QSTR_OnDiskGif), MP_ROM_PTR(&gifio_ondiskgif_type) }, }; diff --git a/shared-bindings/gnss/GNSS.c b/shared-bindings/gnss/GNSS.c index 39d6aba682c..3df23979c9e 100644 --- a/shared-bindings/gnss/GNSS.c +++ b/shared-bindings/gnss/GNSS.c @@ -36,8 +36,8 @@ //| //| :param system: satellite system to use""" //| ... +//| static mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - gnss_obj_t *self = mp_obj_malloc(gnss_obj_t, &gnss_type); enum { ARG_system }; static const mp_arg_t allowed_args[] = { { MP_QSTR_system, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -62,13 +62,16 @@ static mp_obj_t gnss_make_new(const mp_obj_type_t *type, size_t n_args, size_t n mp_raise_TypeError(MP_ERROR_TEXT("System entry must be gnss.SatelliteSystem")); } + gnss_obj_t *self = mp_obj_malloc(gnss_obj_t, &gnss_type); common_hal_gnss_construct(self, selection); + return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: //| """Turn off the GNSS.""" //| ... +//| static mp_obj_t gnss_obj_deinit(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_gnss_deinit(self); @@ -85,6 +88,7 @@ static void check_for_deinit(gnss_obj_t *self) { //| def update(self) -> None: //| """Update GNSS positioning information.""" //| ... +//| static mp_obj_t gnss_obj_update(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -147,6 +151,7 @@ MP_PROPERTY_GETTER(gnss_timestamp_obj, //| fix: PositionFix //| """Fix mode.""" //| +//| static mp_obj_t gnss_obj_get_fix(mp_obj_t self_in) { gnss_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); diff --git a/shared-bindings/gnss/PositionFix.c b/shared-bindings/gnss/PositionFix.c index cd108a612cf..1b85befd89b 100644 --- a/shared-bindings/gnss/PositionFix.c +++ b/shared-bindings/gnss/PositionFix.c @@ -9,6 +9,7 @@ //| //| def __init__(self) -> None: //| """Enum-like class to define the position fix mode.""" +//| //| INVALID: PositionFix //| """No measurement.""" //| @@ -18,6 +19,7 @@ //| FIX_3D: PositionFix //| """3D fix.""" //| +//| const mp_obj_type_t gnss_positionfix_type; const gnss_positionfix_obj_t gnss_positionfix_invalid_obj = { diff --git a/shared-bindings/gnss/SatelliteSystem.c b/shared-bindings/gnss/SatelliteSystem.c index 0c870cbf815..1d6168f61f9 100644 --- a/shared-bindings/gnss/SatelliteSystem.c +++ b/shared-bindings/gnss/SatelliteSystem.c @@ -9,6 +9,7 @@ //| //| def __init__(self) -> None: //| """Enum-like class to define the satellite system type.""" +//| //| GPS: SatelliteSystem //| """Global Positioning System.""" //| @@ -24,6 +25,7 @@ //| QZSS_L1S: SatelliteSystem //| """Quasi-Zenith Satellite System L1S.""" //| +//| const mp_obj_type_t gnss_satellitesystem_type; const gnss_satellitesystem_obj_t gnss_satellitesystem_gps_obj = { diff --git a/shared-bindings/hashlib/Hash.c b/shared-bindings/hashlib/Hash.c index 68930b137e4..a82698432ae 100644 --- a/shared-bindings/hashlib/Hash.c +++ b/shared-bindings/hashlib/Hash.c @@ -18,6 +18,7 @@ //| digest_size: int //| """Digest size in bytes""" +//| static mp_obj_t hashlib_hash_digest_size_get(mp_obj_t self_in) { mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type)); hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -32,6 +33,7 @@ MP_PROPERTY_GETTER(hashlib_hash_digest_size_obj, (mp_obj_t)&hashlib_hash_digest_ //| :param ~circuitpython_typing.ReadableBuffer data: Update the hash from data in this buffer //| """ //| ... +//| mp_obj_t hashlib_hash_update(mp_obj_t self_in, mp_obj_t buf_in) { mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type)); hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -48,6 +50,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(hashlib_hash_update_obj, hashlib_hash_update); //| """Returns the current digest as bytes() with a length of `hashlib.Hash.digest_size`.""" //| ... //| +//| static mp_obj_t hashlib_hash_digest(mp_obj_t self_in) { mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type)); hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/hashlib/__init__.c b/shared-bindings/hashlib/__init__.c index fa3b1b18725..354529cfa77 100644 --- a/shared-bindings/hashlib/__init__.c +++ b/shared-bindings/hashlib/__init__.c @@ -17,14 +17,16 @@ //| |see_cpython_module| :mod:`cpython:hashlib`. //| """ //| +//| //| def new(name: str, data: bytes = b"") -> hashlib.Hash: //| """Returns a Hash object setup for the named algorithm. Raises ValueError when the named -//| algorithm is unsupported. +//| algorithm is unsupported. Supported algorithms for ``name`` are ``'sha1'`` and ``'sha256'``. //| //| :return: a hash object for the given algorithm //| :rtype: hashlib.Hash""" //| ... //| +//| static mp_obj_t hashlib_new(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_name, ARG_data }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/i2cdisplaybus/I2CDisplayBus.c b/shared-bindings/i2cdisplaybus/I2CDisplayBus.c index 065baa782fc..8633f166805 100644 --- a/shared-bindings/i2cdisplaybus/I2CDisplayBus.c +++ b/shared-bindings/i2cdisplaybus/I2CDisplayBus.c @@ -19,14 +19,18 @@ //| class I2CDisplayBus: //| """Manage updating a display over I2C in the background while Python code runs. -//| It doesn't handle display initialization.""" +//| It doesn't handle display initialization. +//| +//| .. seealso:: See `busdisplay.BusDisplay` and `epaperdisplay.EPaperDisplay` +//| for how to initialize a display, given an `I2CDisplayBus`. +//| """ //| //| def __init__( //| self, //| i2c_bus: busio.I2C, //| *, //| device_address: int, -//| reset: Optional[microcontroller.Pin] = None +//| reset: Optional[microcontroller.Pin] = None, //| ) -> None: //| """Create a I2CDisplayBus object associated with the given I2C bus and reset pin. //| @@ -40,6 +44,7 @@ //| :param microcontroller.Pin reset: Reset pin. When None only software reset can be used //| """ //| ... +//| static mp_obj_t i2cdisplaybus_i2cdisplaybus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_i2c_bus, ARG_device_address, ARG_reset }; static const mp_arg_t allowed_args[] = { @@ -65,6 +70,7 @@ static mp_obj_t i2cdisplaybus_i2cdisplaybus_make_new(const mp_obj_type_t *type, //| """Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin //| is available.""" //| ... +//| static mp_obj_t i2cdisplaybus_i2cdisplaybus_obj_reset(mp_obj_t self_in) { i2cdisplaybus_i2cdisplaybus_obj_t *self = self_in; @@ -80,6 +86,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(i2cdisplaybus_i2cdisplaybus_reset_obj, i2cdisplaybus_i //| vertical scroll, set via ``send`` may or may not be reset once the code is done.""" //| ... //| +//| static mp_obj_t i2cdisplaybus_i2cdisplaybus_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) { mp_int_t command_int = mp_obj_get_int(command_obj); mp_arg_validate_int_range(command_int, 0, 255, MP_QSTR_command); diff --git a/shared-bindings/i2cdisplaybus/__init__.c b/shared-bindings/i2cdisplaybus/__init__.c index 45be89668f0..dc255717583 100644 --- a/shared-bindings/i2cdisplaybus/__init__.c +++ b/shared-bindings/i2cdisplaybus/__init__.c @@ -13,9 +13,7 @@ #include "shared-bindings/i2cdisplaybus/__init__.h" #include "shared-bindings/i2cdisplaybus/I2CDisplayBus.h" -//| """Communicates to a display IC over I2C -//| -//| """ +//| """Communicates to a display IC over I2C""" static const mp_rom_map_elem_t i2cdisplaybus_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cdisplaybus) }, diff --git a/shared-bindings/i2cioexpander/IOExpander.c b/shared-bindings/i2cioexpander/IOExpander.c new file mode 100644 index 00000000000..3efa0fd1868 --- /dev/null +++ b/shared-bindings/i2cioexpander/IOExpander.c @@ -0,0 +1,247 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/util.h" +#include "shared/runtime/context_manager_helpers.h" + +//| class IOExpander: +//| """Control a generic I2C-based GPIO expander +//| +//| IOExpander provides a simple interface to I2C-based GPIO expanders that +//| use basic register reads and writes for control. The expander provides +//| individual pins through the `pins` attribute that implement the +//| DigitalInOutProtocol. +//| """ +//| +//| def __init__( +//| self, +//| i2c: busio.I2C, +//| address: int, +//| num_pins: int, +//| set_value_reg: Optional[int] = None, +//| get_value_reg: Optional[int] = None, +//| set_direction_reg: Optional[int] = None, +//| ) -> None: +//| """Initialize an I2C GPIO expander +//| +//| :param busio.I2C i2c: The I2C bus the expander is connected to +//| :param int address: The I2C device address +//| :param int num_pins: The number of GPIO pins (8 or 16) +//| :param int set_value_reg: Register address to write pin values (optional) +//| :param int get_value_reg: Register address to read pin values (optional) +//| :param int set_direction_reg: Register address to set pin directions (optional) +//| """ +//| ... + +static mp_obj_t i2cioexpander_ioexpander_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_i2c, ARG_address, ARG_num_pins, ARG_set_value_reg, ARG_get_value_reg, ARG_set_direction_reg }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_i2c, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_num_pins, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_set_value_reg, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_get_value_reg, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_set_direction_reg, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Validate I2C object + mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c); + + // Validate address + int address = args[ARG_address].u_int; + if (address < 0 || address > 0x7F) { + mp_raise_ValueError(MP_ERROR_TEXT("address out of range")); + } + + // Validate num_pins + int num_pins = args[ARG_num_pins].u_int; + if (num_pins != 8 && num_pins != 16) { + mp_raise_ValueError(MP_ERROR_TEXT("num_pins must be 8 or 16")); + } + + // Convert and validate register parameters + uint16_t set_value_reg = NO_REGISTER; + if (args[ARG_set_value_reg].u_obj != mp_const_none) { + mp_int_t reg = mp_obj_get_int(args[ARG_set_value_reg].u_obj); + mp_arg_validate_int_range(reg, 0, 255, MP_QSTR_set_value_reg); + set_value_reg = reg; + } + + uint16_t get_value_reg = NO_REGISTER; + if (args[ARG_get_value_reg].u_obj != mp_const_none) { + mp_int_t reg = mp_obj_get_int(args[ARG_get_value_reg].u_obj); + mp_arg_validate_int_range(reg, 0, 255, MP_QSTR_get_value_reg); + get_value_reg = reg; + } + + uint16_t set_direction_reg = NO_REGISTER; + if (args[ARG_set_direction_reg].u_obj != mp_const_none) { + mp_int_t reg = mp_obj_get_int(args[ARG_set_direction_reg].u_obj); + mp_arg_validate_int_range(reg, 0, 255, MP_QSTR_set_direction_reg); + set_direction_reg = reg; + } + + i2cioexpander_ioexpander_obj_t *self = + mp_obj_malloc(i2cioexpander_ioexpander_obj_t, &i2cioexpander_ioexpander_type); + common_hal_i2cioexpander_ioexpander_construct( + self, + i2c, + address, + num_pins, + set_value_reg, + get_value_reg, + set_direction_reg); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitialize the expander. No further operations are possible.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander_deinit(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_i2cioexpander_ioexpander_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_deinit_obj, i2cioexpander_ioexpander_deinit); + +//| def __enter__(self) -> IOExpander: +//| """No-op used by Context Managers.""" +//| ... +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_i2cioexpander_ioexpander_deinit(MP_OBJ_TO_PTR(args[0])); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2cioexpander_ioexpander___exit___obj, 4, 4, i2cioexpander_ioexpander___exit__); + +//| @property +//| def input_value(self) -> int: +//| """Read the live value of all pins at once. Returns an integer where each +//| bit represents a pin's current state.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_input_value(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + size_t value; + if (!common_hal_i2cioexpander_ioexpander_get_input_value(self, &value)) { + mp_raise_OSError(MP_EIO); + } + return MP_OBJ_NEW_SMALL_INT(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_input_value_obj, i2cioexpander_ioexpander_obj_get_input_value); + +MP_PROPERTY_GETTER(i2cioexpander_ioexpander_input_value_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_input_value_obj); + +//| @property +//| def output_value(self) -> int: +//| """Get or set the cached output value. Reading returns the last value written, +//| not the live pin state. Writing updates the output pins.""" +//| ... +//| @output_value.setter +//| def output_value(self, val: int) -> None: ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_output_value(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + size_t value; + common_hal_i2cioexpander_ioexpander_get_output_value(self, &value); + return mp_obj_new_int(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_output_value_obj, i2cioexpander_ioexpander_obj_get_output_value); + +static mp_obj_t i2cioexpander_ioexpander_obj_set_output_value(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_negative_errno_t result = common_hal_i2cioexpander_ioexpander_set_output_value(self, mp_obj_get_int(value)); + if (result != 0) { + mp_raise_OSError(result); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_ioexpander_set_output_value_obj, i2cioexpander_ioexpander_obj_set_output_value); + +MP_PROPERTY_GETSET(i2cioexpander_ioexpander_output_value_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_output_value_obj, + (mp_obj_t)&i2cioexpander_ioexpander_set_output_value_obj); + +//| @property +//| def output_mask(self) -> int: +//| """Get or set which pins are configured as outputs. Each bit in the mask +//| represents a pin: 1 for output, 0 for input.""" +//| ... +//| @output_mask.setter +//| def output_mask(self, val: int) -> None: ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_output_mask(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + size_t output_mask; + common_hal_i2cioexpander_ioexpander_get_output_mask(self, &output_mask); + return mp_obj_new_int(output_mask); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_output_mask_obj, i2cioexpander_ioexpander_obj_get_output_mask); + +static mp_obj_t i2cioexpander_ioexpander_obj_set_output_mask(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_negative_errno_t result = common_hal_i2cioexpander_ioexpander_set_output_mask(self, mp_obj_get_int(value)); + if (result != 0) { + mp_raise_OSError(result); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_ioexpander_set_output_mask_obj, i2cioexpander_ioexpander_obj_set_output_mask); + +MP_PROPERTY_GETSET(i2cioexpander_ioexpander_output_mask_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_output_mask_obj, + (mp_obj_t)&i2cioexpander_ioexpander_set_output_mask_obj); + +//| @property +//| def pins(self) -> Tuple[IOPin, ...]: +//| """A tuple of `IOPin` objects that implement the DigitalInOutProtocol. +//| Each pin can be used like a digitalio.DigitalInOut object.""" +//| ... +static mp_obj_t i2cioexpander_ioexpander_obj_get_pins(mp_obj_t self_in) { + i2cioexpander_ioexpander_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_ioexpander_get_pins(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_ioexpander_get_pins_obj, i2cioexpander_ioexpander_obj_get_pins); + +MP_PROPERTY_GETTER(i2cioexpander_ioexpander_pins_obj, + (mp_obj_t)&i2cioexpander_ioexpander_get_pins_obj); + +static const mp_rom_map_elem_t i2cioexpander_ioexpander_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2cioexpander_ioexpander_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2cioexpander_ioexpander___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_input_value), MP_ROM_PTR(&i2cioexpander_ioexpander_input_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_output_value), MP_ROM_PTR(&i2cioexpander_ioexpander_output_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_output_mask), MP_ROM_PTR(&i2cioexpander_ioexpander_output_mask_obj) }, + { MP_ROM_QSTR(MP_QSTR_pins), MP_ROM_PTR(&i2cioexpander_ioexpander_pins_obj) }, +}; +static MP_DEFINE_CONST_DICT(i2cioexpander_ioexpander_locals_dict, i2cioexpander_ioexpander_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + i2cioexpander_ioexpander_type, + MP_QSTR_IOExpander, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, i2cioexpander_ioexpander_make_new, + locals_dict, &i2cioexpander_ioexpander_locals_dict + ); diff --git a/shared-bindings/i2cioexpander/IOExpander.h b/shared-bindings/i2cioexpander/IOExpander.h new file mode 100644 index 00000000000..5c93c6250cc --- /dev/null +++ b/shared-bindings/i2cioexpander/IOExpander.h @@ -0,0 +1,34 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/i2cioexpander/IOExpander.h" + +extern const mp_obj_type_t i2cioexpander_ioexpander_type; + +void common_hal_i2cioexpander_ioexpander_construct( + i2cioexpander_ioexpander_obj_t *self, + mp_obj_t i2c, + uint8_t address, + uint8_t num_pins, + uint16_t set_value_reg, + uint16_t get_value_reg, + uint16_t set_direction_reg); + +void common_hal_i2cioexpander_ioexpander_deinit(i2cioexpander_ioexpander_obj_t *self); +bool common_hal_i2cioexpander_ioexpander_deinited(i2cioexpander_ioexpander_obj_t *self); + +mp_negative_errno_t common_hal_i2cioexpander_ioexpander_get_input_value(i2cioexpander_ioexpander_obj_t *self, size_t *value); +// No error return because this returns a cached value. +void common_hal_i2cioexpander_ioexpander_get_output_value(i2cioexpander_ioexpander_obj_t *self, size_t *value); +mp_negative_errno_t common_hal_i2cioexpander_ioexpander_set_output_value(i2cioexpander_ioexpander_obj_t *self, size_t value); + +void common_hal_i2cioexpander_ioexpander_get_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t *mask); +mp_negative_errno_t common_hal_i2cioexpander_ioexpander_set_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t mask); + +mp_obj_t common_hal_i2cioexpander_ioexpander_get_pins(i2cioexpander_ioexpander_obj_t *self); diff --git a/shared-bindings/i2cioexpander/IOPin.c b/shared-bindings/i2cioexpander/IOPin.c new file mode 100644 index 00000000000..bba229bd31e --- /dev/null +++ b/shared-bindings/i2cioexpander/IOPin.c @@ -0,0 +1,326 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-module/i2cioexpander/IOPin.h" + +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/util.h" + +static void check_result(digitalinout_result_t result) { + switch (result) { + case DIGITALINOUT_OK: + return; + case DIGITALINOUT_PIN_BUSY: + mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_Pin); + #if CIRCUITPY_DIGITALIO_HAVE_INPUT_ONLY + case DIGITALINOUT_INPUT_ONLY: + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_direction); + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + case DIGITALINOUT_INVALID_PULL: + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_pull); + #endif + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + case DIGITALINOUT_INVALID_DRIVE_MODE: + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_drive_mode); + #endif + } +} + +static inline void check_for_deinit(i2cioexpander_iopin_obj_t *self) { + if (common_hal_i2cioexpander_iopin_deinited(self)) { + raise_deinited_error(); + } +} +//| class IOPin: +//| """Control a single pin on an `IOExpander` in the same way as `DigitalInOut`. +//| +//| Not constructed directly. Get from `IOExpander.pins` instead. +//| """ +//| + +//| def switch_to_output( +//| self, value: bool = False, drive_mode: digitalio.DriveMode = digitalio.DriveMode.PUSH_PULL +//| ) -> None: +//| """Set the drive mode and value and then switch to writing out digital values. +//| +//| :param bool value: default value to set upon switching +//| :param digitalio.DriveMode drive_mode: drive mode for the output""" +//| ... +static mp_obj_t i2cioexpander_iopin_switch_to_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_value, ARG_drive_mode }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_value, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&digitalio_drive_mode_push_pull_obj)} }, + }; + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + digitalio_drive_mode_t drive_mode = DRIVE_MODE_PUSH_PULL; + if (args[ARG_drive_mode].u_rom_obj == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { + drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + check_result(common_hal_i2cioexpander_iopin_switch_to_output(self, args[ARG_value].u_bool, drive_mode)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(i2cioexpander_iopin_switch_to_output_obj, 1, i2cioexpander_iopin_switch_to_output); + +//| def switch_to_input(self, pull: Optional[digitalio.Pull] = None) -> None: +//| """Set the pull and then switch to read in digital values. +//| +//| :param digitalio.Pull pull: pull configuration for the input""" +//| ... +static mp_obj_t i2cioexpander_iopin_switch_to_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + }; + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + check_result(common_hal_i2cioexpander_iopin_switch_to_input(self, validate_pull(args[ARG_pull].u_rom_obj, MP_QSTR_pull))); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(i2cioexpander_iopin_switch_to_input_obj, 1, i2cioexpander_iopin_switch_to_input); + +//| direction: digitalio.Direction +//| """The direction of the pin.""" +static mp_obj_t i2cioexpander_iopin_obj_get_direction(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + digitalio_direction_t direction = common_hal_i2cioexpander_iopin_get_direction(self); + if (direction == DIRECTION_INPUT) { + return MP_OBJ_FROM_PTR(&digitalio_direction_input_obj); + } + return MP_OBJ_FROM_PTR(&digitalio_direction_output_obj); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_direction_obj, i2cioexpander_iopin_obj_get_direction); + +static mp_obj_t i2cioexpander_iopin_obj_set_direction(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (value == MP_ROM_PTR(&digitalio_direction_input_obj)) { + check_result(common_hal_i2cioexpander_iopin_switch_to_input(self, PULL_NONE)); + } else if (value == MP_ROM_PTR(&digitalio_direction_output_obj)) { + check_result(common_hal_i2cioexpander_iopin_switch_to_output(self, false, DRIVE_MODE_PUSH_PULL)); + } else { + mp_arg_error_invalid(MP_QSTR_direction); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_direction_obj, i2cioexpander_iopin_obj_set_direction); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_direction_obj, + (mp_obj_t)&i2cioexpander_iopin_get_direction_obj, + (mp_obj_t)&i2cioexpander_iopin_set_direction_obj); + +//| value: bool +//| """The digital logic level of the pin.""" +static mp_obj_t i2cioexpander_iopin_obj_get_value(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + bool value; + mp_negative_errno_t res = common_hal_i2cioexpander_iopin_get_value(self, &value); + if (res != 0) { + mp_raise_OSError(-res); + } + return mp_obj_new_bool(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_value_obj, i2cioexpander_iopin_obj_get_value); + +static mp_obj_t i2cioexpander_iopin_obj_set_value(mp_obj_t self_in, mp_obj_t value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Cannot set value when direction is input.")); + return mp_const_none; + } + mp_negative_errno_t res = common_hal_i2cioexpander_iopin_set_value(self, mp_obj_is_true(value)); + if (res != 0) { + mp_raise_OSError(-res); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_value_obj, i2cioexpander_iopin_obj_set_value); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_value_obj, + (mp_obj_t)&i2cioexpander_iopin_get_value_obj, + (mp_obj_t)&i2cioexpander_iopin_set_value_obj); + +//| drive_mode: digitalio.DriveMode +//| """The pin drive mode.""" +static mp_obj_t i2cioexpander_iopin_obj_get_drive_mode(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Drive mode not used when direction is input.")); + return mp_const_none; + } + digitalio_drive_mode_t drive_mode = common_hal_i2cioexpander_iopin_get_drive_mode(self); + if (drive_mode == DRIVE_MODE_PUSH_PULL) { + return MP_OBJ_FROM_PTR(&digitalio_drive_mode_push_pull_obj); + } + return MP_OBJ_FROM_PTR(&digitalio_drive_mode_open_drain_obj); +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_drive_mode_obj, i2cioexpander_iopin_obj_get_drive_mode); + +static mp_obj_t i2cioexpander_iopin_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_INPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Drive mode not used when direction is input.")); + return mp_const_none; + } + digitalio_drive_mode_t c_drive_mode = DRIVE_MODE_PUSH_PULL; + if (drive_mode == MP_ROM_PTR(&digitalio_drive_mode_open_drain_obj)) { + c_drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + check_result(common_hal_i2cioexpander_iopin_set_drive_mode(self, c_drive_mode)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_drive_mode_obj, i2cioexpander_iopin_obj_set_drive_mode); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_drive_mode_obj, + (mp_obj_t)&i2cioexpander_iopin_get_drive_mode_obj, + (mp_obj_t)&i2cioexpander_iopin_set_drive_mode_obj); + +//| pull: Optional[digitalio.Pull] +//| """The pin pull direction.""" +static mp_obj_t i2cioexpander_iopin_obj_get_pull(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_OUTPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Pull not used when direction is output.")); + return mp_const_none; + } + digitalio_pull_t pull = common_hal_i2cioexpander_iopin_get_pull(self); + if (pull == PULL_UP) { + return MP_OBJ_FROM_PTR(&digitalio_pull_up_obj); + } else if (pull == PULL_DOWN) { + return MP_OBJ_FROM_PTR(&digitalio_pull_down_obj); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(i2cioexpander_iopin_get_pull_obj, i2cioexpander_iopin_obj_get_pull); + +static mp_obj_t i2cioexpander_iopin_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (common_hal_i2cioexpander_iopin_get_direction(self) == DIRECTION_OUTPUT) { + mp_raise_AttributeError(MP_ERROR_TEXT("Pull not used when direction is output.")); + return mp_const_none; + } + check_result(common_hal_i2cioexpander_iopin_set_pull(self, validate_pull(pull_obj, MP_QSTR_pull))); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(i2cioexpander_iopin_set_pull_obj, i2cioexpander_iopin_obj_set_pull); + +MP_PROPERTY_GETSET(i2cioexpander_iopin_pull_obj, + (mp_obj_t)&i2cioexpander_iopin_get_pull_obj, + (mp_obj_t)&i2cioexpander_iopin_set_pull_obj); + +// Protocol implementation for DigitalInOutProtocol +static void iopin_protocol_deinit(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_i2cioexpander_iopin_deinit(self); +} + +static bool iopin_protocol_deinited(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_deinited(self); +} + +static digitalinout_result_t iopin_protocol_switch_to_input(mp_obj_t self_in, digitalio_pull_t pull) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_switch_to_input(self, pull); +} + +static digitalinout_result_t iopin_protocol_switch_to_output(mp_obj_t self_in, bool value, digitalio_drive_mode_t drive_mode) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_switch_to_output(self, value, drive_mode); +} + +static digitalio_direction_t iopin_protocol_get_direction(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_direction(self); +} + +static mp_negative_errno_t iopin_protocol_get_value(mp_obj_t self_in, bool *value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_value(self, value); +} + +static mp_negative_errno_t iopin_protocol_set_value(mp_obj_t self_in, bool value) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_set_value(self, value); +} + +static digitalio_drive_mode_t iopin_protocol_get_drive_mode(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_drive_mode(self); +} + +static digitalinout_result_t iopin_protocol_set_drive_mode(mp_obj_t self_in, digitalio_drive_mode_t drive_mode) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_set_drive_mode(self, drive_mode); +} + +static digitalio_pull_t iopin_protocol_get_pull(mp_obj_t self_in) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_get_pull(self); +} + +static digitalinout_result_t iopin_protocol_set_pull(mp_obj_t self_in, digitalio_pull_t pull) { + i2cioexpander_iopin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_i2cioexpander_iopin_set_pull(self, pull); +} + +static const digitalinout_p_t iopin_digitalinout_p = { + MP_PROTO_IMPLEMENT(MP_QSTR_DigitalInOut) + .deinit = iopin_protocol_deinit, + .deinited = iopin_protocol_deinited, + .switch_to_input = iopin_protocol_switch_to_input, + .switch_to_output = iopin_protocol_switch_to_output, + .get_direction = iopin_protocol_get_direction, + .get_value = iopin_protocol_get_value, + .set_value = iopin_protocol_set_value, + .get_drive_mode = iopin_protocol_get_drive_mode, + .set_drive_mode = iopin_protocol_set_drive_mode, + .get_pull = iopin_protocol_get_pull, + .set_pull = iopin_protocol_set_pull, +}; + +static const mp_rom_map_elem_t i2cioexpander_iopin_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_switch_to_input), MP_ROM_PTR(&i2cioexpander_iopin_switch_to_input_obj) }, + { MP_ROM_QSTR(MP_QSTR_switch_to_output), MP_ROM_PTR(&i2cioexpander_iopin_switch_to_output_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_direction), MP_ROM_PTR(&i2cioexpander_iopin_direction_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&i2cioexpander_iopin_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_drive_mode), MP_ROM_PTR(&i2cioexpander_iopin_drive_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_pull), MP_ROM_PTR(&i2cioexpander_iopin_pull_obj) }, +}; +static MP_DEFINE_CONST_DICT(i2cioexpander_iopin_locals_dict, i2cioexpander_iopin_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + i2cioexpander_iopin_type, + MP_QSTR_IOPin, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + protocol, &iopin_digitalinout_p, + locals_dict, &i2cioexpander_iopin_locals_dict + ); diff --git a/shared-bindings/i2cioexpander/IOPin.h b/shared-bindings/i2cioexpander/IOPin.h new file mode 100644 index 00000000000..c8155c71aa1 --- /dev/null +++ b/shared-bindings/i2cioexpander/IOPin.h @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/i2cioexpander/IOPin.h" + +extern const mp_obj_type_t i2cioexpander_iopin_type; + +mp_negative_errno_t i2cioexpander_iopin_construct( + i2cioexpander_iopin_obj_t *self, + i2cioexpander_ioexpander_obj_t *expander, + uint8_t pin_number); + +void common_hal_i2cioexpander_iopin_deinit(i2cioexpander_iopin_obj_t *self); +bool common_hal_i2cioexpander_iopin_deinited(i2cioexpander_iopin_obj_t *self); + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_input( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull); + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_output( + i2cioexpander_iopin_obj_t *self, + bool value, + digitalio_drive_mode_t drive_mode); + +digitalio_direction_t common_hal_i2cioexpander_iopin_get_direction(i2cioexpander_iopin_obj_t *self); + +mp_negative_errno_t common_hal_i2cioexpander_iopin_set_value(i2cioexpander_iopin_obj_t *self, bool value); +mp_negative_errno_t common_hal_i2cioexpander_iopin_get_value(i2cioexpander_iopin_obj_t *self, bool *value); + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_drive_mode( + i2cioexpander_iopin_obj_t *self, + digitalio_drive_mode_t drive_mode); + +digitalio_drive_mode_t common_hal_i2cioexpander_iopin_get_drive_mode(i2cioexpander_iopin_obj_t *self); + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_pull( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull); + +digitalio_pull_t common_hal_i2cioexpander_iopin_get_pull(i2cioexpander_iopin_obj_t *self); diff --git a/shared-bindings/i2cioexpander/__init__.c b/shared-bindings/i2cioexpander/__init__.c new file mode 100644 index 00000000000..106c45c3768 --- /dev/null +++ b/shared-bindings/i2cioexpander/__init__.c @@ -0,0 +1,49 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/i2cioexpander/__init__.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" + +//| """Support for I2C-based GPIO expanders +//| +//| The `i2cioexpander` module contains classes to support I2C-based GPIO expanders +//| that can be controlled via simple register reads and writes. +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed if the program continues after use. To do so, either +//| call :py:meth:`!deinit` or use a context manager. See +//| :ref:`lifetime-and-contextmanagers` for more info. +//| +//| Example:: +//| +//| import board +//| import busio +//| import i2cioexpander +//| +//| i2c = busio.I2C(board.SCL, board.SDA) +//| expander = i2cioexpander.IOExpander(i2c, 0x20, 8, 0x01, 0x00, 0x03) +//| pin0 = expander.pins[0] +//| pin0.switch_to_output(value=True) +//| """ + +static const mp_rom_map_elem_t i2cioexpander_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_i2cioexpander) }, + { MP_ROM_QSTR(MP_QSTR_IOExpander), MP_ROM_PTR(&i2cioexpander_ioexpander_type) }, +}; + +static MP_DEFINE_CONST_DICT(i2cioexpander_module_globals, i2cioexpander_module_globals_table); + +const mp_obj_module_t i2cioexpander_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&i2cioexpander_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_i2cioexpander, i2cioexpander_module); diff --git a/shared-bindings/i2cioexpander/__init__.h b/shared-bindings/i2cioexpander/__init__.h new file mode 100644 index 00000000000..e0d06686868 --- /dev/null +++ b/shared-bindings/i2cioexpander/__init__.h @@ -0,0 +1,9 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +// Nothing now. diff --git a/shared-bindings/i2ctarget/I2CTarget.c b/shared-bindings/i2ctarget/I2CTarget.c index 2a3749fdb28..94dbf4e8be4 100644 --- a/shared-bindings/i2ctarget/I2CTarget.c +++ b/shared-bindings/i2ctarget/I2CTarget.c @@ -21,12 +21,13 @@ static mp_obj_t mp_obj_new_i2ctarget_i2c_target_request(i2ctarget_i2c_target_obj_t *target, uint8_t address, bool is_read, bool is_restart) { i2ctarget_i2c_target_request_obj_t *self = - mp_obj_malloc(i2ctarget_i2c_target_request_obj_t, &i2ctarget_i2c_target_request_type); + mp_obj_malloc_with_finaliser(i2ctarget_i2c_target_request_obj_t, &i2ctarget_i2c_target_request_type); self->target = target; self->address = address; self->is_read = is_read; self->is_restart = is_restart; - return (mp_obj_t)self; + + return MP_OBJ_FROM_PTR(self); } //| class I2CTarget: @@ -48,8 +49,8 @@ static mp_obj_t mp_obj_new_i2ctarget_i2c_target_request(i2ctarget_i2c_target_obj //| :type addresses: list[int] //| :param bool smbus: Use SMBUS timings if the hardware supports it""" //| ... +//| static mp_obj_t i2ctarget_i2c_target_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - i2ctarget_i2c_target_obj_t *self = mp_obj_malloc(i2ctarget_i2c_target_obj_t, &i2ctarget_i2c_target_type); enum { ARG_scl, ARG_sda, ARG_addresses, ARG_smbus }; static const mp_arg_t allowed_args[] = { { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -77,37 +78,41 @@ static mp_obj_t i2ctarget_i2c_target_make_new(const mp_obj_type_t *type, size_t mp_raise_ValueError(MP_ERROR_TEXT("addresses is empty")); } + i2ctarget_i2c_target_obj_t *self = mp_obj_malloc_with_finaliser(i2ctarget_i2c_target_obj_t, &i2ctarget_i2c_target_type); common_hal_i2ctarget_i2c_target_construct(self, scl, sda, addresses, i, args[ARG_smbus].u_bool); - return (mp_obj_t)self; + + return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: //| """Releases control of the underlying hardware so other classes can use it.""" //| ... +//| static mp_obj_t i2ctarget_i2c_target_obj_deinit(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_type)); i2ctarget_i2c_target_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_i2ctarget_i2c_target_deinit(self); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_1(i2ctarget_i2c_target_deinit_obj, i2ctarget_i2c_target_obj_deinit); +static void check_for_deinit(i2ctarget_i2c_target_obj_t *self) { + if (common_hal_i2ctarget_i2c_target_deinited(self)) { + raise_deinited_error(); + } +} + //| def __enter__(self) -> I2CTarget: //| """No-op used in Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware on context exit. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t i2ctarget_i2c_target_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_type(args[0], &i2ctarget_i2c_target_type)); - i2ctarget_i2c_target_obj_t *self = MP_OBJ_TO_PTR(args[0]); - common_hal_i2ctarget_i2c_target_deinit(self); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target___exit___obj, 4, 4, i2ctarget_i2c_target_obj___exit__); +//| +// Provided by context manager helper. //| def request(self, *, timeout: float = -1) -> I2CTargetRequest: //| """Wait for an I2C request. @@ -116,12 +121,11 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target___exit___obj, 4, //| :return: I2CTargetRequest or None if timeout=-1 and there's no request //| :rtype: ~i2ctarget.I2CTargetRequest""" //| +//| static mp_obj_t i2ctarget_i2c_target_request(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(mp_obj_is_type(pos_args[0], &i2ctarget_i2c_target_type)); i2ctarget_i2c_target_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - if (common_hal_i2ctarget_i2c_target_deinited(self)) { - raise_deinited_error(); - } + check_for_deinit(self); + enum { ARG_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, @@ -186,8 +190,9 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(i2ctarget_i2c_target_request_obj, 1, i2ctarget static const mp_rom_map_elem_t i2ctarget_i2c_target_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2ctarget_i2c_target_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&i2ctarget_i2c_target_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2ctarget_i2c_target___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_request), MP_ROM_PTR(&i2ctarget_i2c_target_request_obj) }, }; @@ -197,7 +202,7 @@ static MP_DEFINE_CONST_DICT(i2ctarget_i2c_target_locals_dict, i2ctarget_i2c_targ MP_DEFINE_CONST_OBJ_TYPE( i2ctarget_i2c_target_type, MP_QSTR_I2CTarget, - MP_TYPE_FLAG_NONE, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, make_new, i2ctarget_i2c_target_make_new, locals_dict, &i2ctarget_i2c_target_locals_dict ); @@ -213,32 +218,45 @@ MP_DEFINE_CONST_OBJ_TYPE( //| :param address: I2C address //| :param is_read: True if the main target is requesting data //| :param is_restart: Repeated Start Condition""" +//| static mp_obj_t i2ctarget_i2c_target_request_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 4, 4, false); return mp_obj_new_i2ctarget_i2c_target_request(args[0], mp_obj_get_int(args[1]), mp_obj_is_true(args[2]), mp_obj_is_true(args[3])); } -//| def __enter__(self) -> I2CTargetRequest: -//| """No-op used in Context Managers.""" -//| ... -// Provided by context manager helper. +static void target_request_check_for_deinit(i2ctarget_i2c_target_request_obj_t *self) { + if (self->target == NULL) { + raise_deinited_error(); + } + check_for_deinit(self->target); +} -//| def __exit__(self) -> None: -//| """Close the request.""" +//| def deinit(self) -> None: +//| """Disconnects from parent `I2CTarget`. +//| Called by `__exit__()` to indicate the `I2CTargetRequest` is no longer useful.""" //| ... -static mp_obj_t i2ctarget_i2c_target_request_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_type(args[0], &i2ctarget_i2c_target_request_type)); - i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); - common_hal_i2ctarget_i2c_target_close(self->target); +//| +static mp_obj_t i2ctarget_i2c_target_request_deinit(mp_obj_t self_in) { + i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + target_request_check_for_deinit(self); + + i2ctarget_i2c_target_obj_t *target = self->target; + + // Deinit I2CTargetRequest first in case _close() fails. + self->target = NULL; + + common_hal_i2ctarget_i2c_target_close(target); + return mp_const_none; } -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target_request___exit___obj, 4, 4, i2ctarget_i2c_target_request_obj___exit__); +MP_DEFINE_CONST_FUN_OBJ_1(i2ctarget_i2c_target_request_deinit_obj, i2ctarget_i2c_target_request_deinit); //| address: int //| """The I2C address of the request.""" static mp_obj_t i2ctarget_i2c_target_request_get_address(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + target_request_check_for_deinit(self); + return mp_obj_new_int(self->address); } MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_address_obj, i2ctarget_i2c_target_request_get_address); @@ -246,17 +264,20 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_address_obj, i2ctarget_i2c //| is_read: bool //| """The I2C main controller is reading from this target.""" static mp_obj_t i2ctarget_i2c_target_request_get_is_read(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + target_request_check_for_deinit(self); + return mp_obj_new_bool(self->is_read); } MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_read_obj, i2ctarget_i2c_target_request_get_is_read); //| is_restart: bool //| """Is Repeated Start Condition.""" +//| static mp_obj_t i2ctarget_i2c_target_request_get_is_restart(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + target_request_check_for_deinit(self); + return mp_obj_new_bool(self->is_restart); } MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_restart_obj, i2ctarget_i2c_target_request_get_is_restart); @@ -269,9 +290,11 @@ MP_DEFINE_CONST_PROP_GET(i2ctarget_i2c_target_request_is_restart_obj, i2ctarget_ //| :param ack: Whether or not to send an ACK after the n'th byte //| :return: Bytes read""" //| ... +//| static mp_obj_t i2ctarget_i2c_target_request_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_check_self(mp_obj_is_type(pos_args[0], &i2ctarget_i2c_target_request_type)); i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + target_request_check_for_deinit(self); + enum { ARG_n, ARG_ack }; static const mp_arg_t allowed_args[] = { { MP_QSTR_n, MP_ARG_INT, {.u_int = -1} }, @@ -326,9 +349,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(i2ctarget_i2c_target_request_read_obj, 1, i2ctarget_i //| :param ~circuitpython_typing.ReadableBuffer buffer: Write out the data in this buffer //| :return: Number of bytes written""" //| ... +//| static mp_obj_t i2ctarget_i2c_target_request_write(mp_obj_t self_in, mp_obj_t buf_in) { - mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); + target_request_check_for_deinit(self); if (!self->is_read) { mp_raise_OSError(MP_EACCES); @@ -360,9 +384,11 @@ static MP_DEFINE_CONST_FUN_OBJ_2(i2ctarget_i2c_target_request_write_obj, i2ctarg //| :param ack: Whether to send an ACK or NACK""" //| ... //| +//| static mp_obj_t i2ctarget_i2c_target_request_ack(uint n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_type(args[0], &i2ctarget_i2c_target_request_type)); i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(args[0]); + target_request_check_for_deinit(self); + bool ack = (n_args == 1) ? true : mp_obj_is_true(args[1]); if (self->is_read) { @@ -374,25 +400,29 @@ static mp_obj_t i2ctarget_i2c_target_request_ack(uint n_args, const mp_obj_t *ar } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(i2ctarget_i2c_target_request_ack_obj, 1, 2, i2ctarget_i2c_target_request_ack); -static mp_obj_t i2ctarget_i2c_target_request_close(mp_obj_t self_in) { - mp_check_self(mp_obj_is_type(self_in, &i2ctarget_i2c_target_request_type)); - i2ctarget_i2c_target_request_obj_t *self = MP_OBJ_TO_PTR(self_in); +//| def __enter__(self) -> I2CTargetRequest: +//| """No-op used in Context Managers.""" +//| ... +//| +// Provided by context manager helper. - common_hal_i2ctarget_i2c_target_close(self->target); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_1(i2ctarget_i2c_target_request_close_obj, i2ctarget_i2c_target_request_close); +//| def __exit__(self) -> None: +//| """Close and deinit the request.""" +//| ... +//| +// Provided by context manager helper. static const mp_rom_map_elem_t i2ctarget_i2c_target_request_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&i2ctarget_i2c_target_request___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&i2ctarget_i2c_target_request_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR__del__), MP_ROM_PTR(&i2ctarget_i2c_target_request_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&i2ctarget_i2c_target_request_address_obj) }, { MP_ROM_QSTR(MP_QSTR_is_read), MP_ROM_PTR(&i2ctarget_i2c_target_request_is_read_obj) }, { MP_ROM_QSTR(MP_QSTR_is_restart), MP_ROM_PTR(&i2ctarget_i2c_target_request_is_restart_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&i2ctarget_i2c_target_request_read_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&i2ctarget_i2c_target_request_write_obj) }, { MP_ROM_QSTR(MP_QSTR_ack), MP_ROM_PTR(&i2ctarget_i2c_target_request_ack_obj) }, - { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&i2ctarget_i2c_target_request_close_obj) }, }; static MP_DEFINE_CONST_DICT(i2ctarget_i2c_target_request_locals_dict, i2ctarget_i2c_target_request_locals_dict_table); diff --git a/shared-bindings/imagecapture/ParallelImageCapture.c b/shared-bindings/imagecapture/ParallelImageCapture.c index d1964c71753..427eaeb3793 100644 --- a/shared-bindings/imagecapture/ParallelImageCapture.c +++ b/shared-bindings/imagecapture/ParallelImageCapture.c @@ -34,6 +34,7 @@ //| :param microcontroller.Pin href: The horizontal reference input, which is high whenever the camera is transmitting valid pixel information. //| """ //| ... +//| static mp_obj_t imagecapture_parallelimagecapture_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_data_pins, ARG_clock, ARG_vsync, ARG_href, NUM_ARGS }; @@ -57,7 +58,6 @@ static mp_obj_t imagecapture_parallelimagecapture_make_new(const mp_obj_type_t * imagecapture_parallelimagecapture_obj_t *self = mp_obj_malloc(imagecapture_parallelimagecapture_obj_t, &imagecapture_parallelimagecapture_type); - common_hal_imagecapture_parallelimagecapture_construct(self, pins, pin_count, clock, vsync, href); return self; @@ -68,6 +68,7 @@ static mp_obj_t imagecapture_parallelimagecapture_make_new(const mp_obj_type_t * //| //| This will stop a continuous-mode capture, if one is in progress.""" //| ... +//| static mp_obj_t imagecapture_parallelimagecapture_capture(mp_obj_t self_in, mp_obj_t buffer) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_singleshot_capture(self, buffer); @@ -88,6 +89,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(imagecapture_parallelimagecapture_capture_obj, //| `ParallelImageCapture` object keeps references to ``buffer1`` and //| ``buffer2``, so the objects will not be garbage collected.""" //| ... +//| static mp_obj_t imagecapture_parallelimagecapture_continuous_capture_start(mp_obj_t self_in, mp_obj_t buffer1, mp_obj_t buffer2) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_continuous_capture_start(self, buffer1, buffer2); @@ -99,6 +101,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(imagecapture_parallelimagecapture_continuous_ca //| def continuous_capture_get_frame(self) -> WriteableBuffer: //| """Return the next available frame, one of the two buffers passed to `continuous_capture_start`""" //| ... +//| static mp_obj_t imagecapture_parallelimagecapture_continuous_capture_get_frame(mp_obj_t self_in) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; return common_hal_imagecapture_parallelimagecapture_continuous_capture_get_frame(self); @@ -114,6 +117,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_continuous_ca //| references to the buffers passed to `continuous_capture_start`, //| potentially allowing the objects to be garbage collected.""" //| ... +//| static mp_obj_t imagecapture_parallelimagecapture_continuous_capture_stop(mp_obj_t self_in) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_continuous_capture_stop(self); @@ -128,6 +132,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_continuous_ca //| def deinit(self) -> None: //| """Deinitialize this instance""" //| ... +//| static mp_obj_t imagecapture_parallelimagecapture_deinit(mp_obj_t self_in) { imagecapture_parallelimagecapture_obj_t *self = (imagecapture_parallelimagecapture_obj_t *)self_in; common_hal_imagecapture_parallelimagecapture_deinit(self); @@ -139,6 +144,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_deinit_obj, i //| def __enter__(self) -> ParallelImageCapture: //| """No-op used in Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: @@ -146,19 +152,14 @@ static MP_DEFINE_CONST_FUN_OBJ_1(imagecapture_parallelimagecapture_deinit_obj, i //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... //| -static mp_obj_t imagecapture_parallelimagecapture___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_imagecapture_parallelimagecapture_deinit(args[0]); - return mp_const_none; -} - -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(imagecapture_parallelimagecapture___exit___obj, 4, 4, imagecapture_parallelimagecapture___exit__); +//| +// Provided by context manager helper. static const mp_rom_map_elem_t imagecapture_parallelimagecapture_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&imagecapture_parallelimagecapture_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&imagecapture_parallelimagecapture___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_capture), MP_ROM_PTR(&imagecapture_parallelimagecapture_capture_obj) }, { MP_ROM_QSTR(MP_QSTR_continuous_capture_start), MP_ROM_PTR(&imagecapture_parallelimagecapture_continuous_capture_start_obj) }, diff --git a/shared-bindings/index.rst b/shared-bindings/index.rst index bf04ae18b13..6d3e4d68842 100644 --- a/shared-bindings/index.rst +++ b/shared-bindings/index.rst @@ -15,6 +15,12 @@ a list of modules supported on each board. Modules --------- +.. note:: Some modules are documented in :doc:`/docs/library/index`, not here: + `builtins`, `heapq`, `array`, `binascii`, `collections`, `errno`, `gc`, + `io`, `json`, `re`, `sys`, `select`. + + The documentation for :func:`help` is at the end of this page. + .. toctree:: :glob: :maxdepth: 2 diff --git a/shared-bindings/ipaddress/IPv4Address.c b/shared-bindings/ipaddress/IPv4Address.c index bf18eda0f79..7705e500e7e 100644 --- a/shared-bindings/ipaddress/IPv4Address.c +++ b/shared-bindings/ipaddress/IPv4Address.c @@ -24,6 +24,7 @@ //| //| The value itself can either be bytes or a string formatted address.""" //| ... +//| static mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_address }; static const mp_arg_t allowed_args[] = { @@ -58,7 +59,6 @@ static mp_obj_t ipaddress_ipv4address_make_new(const mp_obj_type_t *type, size_t ipaddress_ipv4address_obj_t *self = mp_obj_malloc(ipaddress_ipv4address_obj_t, &ipaddress_ipv4address_type); - common_hal_ipaddress_ipv4address_construct(self, buf, 4); return MP_OBJ_FROM_PTR(self); @@ -78,6 +78,7 @@ MP_PROPERTY_GETTER(ipaddress_ipv4address_packed_obj, //| version: int //| """4 for IPv4, 6 for IPv6""" +//| static mp_obj_t ipaddress_ipv4address_get_version(mp_obj_t self_in) { ipaddress_ipv4address_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t buf_info; @@ -98,6 +99,7 @@ MP_PROPERTY_GETTER(ipaddress_ipv4address_version_obj, //| def __eq__(self, other: object) -> bool: //| """Two Address objects are equal if their addresses and address types are equal.""" //| ... +//| static mp_obj_t ipaddress_ipv4address_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { switch (op) { // Two Addresses are equal if their address bytes and address_type are equal @@ -122,6 +124,7 @@ static mp_obj_t ipaddress_ipv4address_binary_op(mp_binary_op_t op, mp_obj_t lhs_ //| """Returns a hash for the IPv4Address data.""" //| ... //| +//| static mp_obj_t ipaddress_ipv4address_unary_op(mp_unary_op_t op, mp_obj_t self_in) { switch (op) { // Two Addresses are equal if their address bytes and address_type are equal diff --git a/shared-bindings/ipaddress/__init__.c b/shared-bindings/ipaddress/__init__.c index 75892f6f2ea..60bc6226ba1 100644 --- a/shared-bindings/ipaddress/__init__.c +++ b/shared-bindings/ipaddress/__init__.c @@ -16,6 +16,7 @@ //| module. //| """ //| +//| bool ipaddress_parse_ipv4address(const char *str_data, size_t str_len, uint32_t *ip_out) { @@ -60,6 +61,7 @@ bool ipaddress_parse_ipv4address(const char *str_data, size_t str_len, uint32_t //| """Return a corresponding IP address object or raise ValueError if not possible.""" //| ... //| +//| static mp_obj_t ipaddress_ip_address(mp_obj_t ip_in) { uint32_t value; diff --git a/shared-bindings/is31fl3741/FrameBuffer.c b/shared-bindings/is31fl3741/FrameBuffer.c index b197f4447cb..b59c7360f8b 100644 --- a/shared-bindings/is31fl3741/FrameBuffer.c +++ b/shared-bindings/is31fl3741/FrameBuffer.c @@ -29,7 +29,7 @@ //| *, //| framebuffer: Optional[WriteableBuffer] = None, //| scale: bool = False, -//| gamma: bool = False +//| gamma: bool = False, //| ) -> None: //| """Create a IS31FL3741_FrameBuffer object with the given attributes. //| @@ -51,6 +51,7 @@ //| :param bool scale: if True display is scaled down by 3 when displayed //| :param bool gamma: if True apply gamma correction to all LEDs""" //| ... +//| static mp_obj_t is31fl3741_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_is31, ARG_width, ARG_height, ARG_mapping, ARG_framebuffer, ARG_scale, ARG_gamma }; static const mp_arg_t allowed_args[] = { @@ -111,6 +112,7 @@ static mp_obj_t is31fl3741_framebuffer_make_new(const mp_obj_type_t *type, size_ //| IS31FL3741 instance. After deinitialization, no further operations //| may be performed.""" //| ... +//| static mp_obj_t is31fl3741_framebuffer_deinit(mp_obj_t self_in) { is31fl3741_framebuffer_obj_t *self = (is31fl3741_framebuffer_obj_t *)self_in; common_hal_is31fl3741_framebuffer_deinit(self); @@ -127,6 +129,7 @@ static void check_for_deinit(is31fl3741_framebuffer_obj_t *self) { //| brightness: float //| """In the current implementation, 0.0 turns the display off entirely //| and any other value up to 1.0 turns the display on fully.""" +//| static mp_obj_t is31fl3741_framebuffer_get_brightness(mp_obj_t self_in) { is31fl3741_framebuffer_obj_t *self = (is31fl3741_framebuffer_obj_t *)self_in; check_for_deinit(self); @@ -160,6 +163,7 @@ MP_PROPERTY_GETSET(is31fl3741_framebuffer_brightness_obj, //| """Transmits the color data in the buffer to the pixels so that //| they are shown.""" //| ... +//| static mp_obj_t is31fl3741_framebuffer_refresh(mp_obj_t self_in) { is31fl3741_framebuffer_obj_t *self = (is31fl3741_framebuffer_obj_t *)self_in; check_for_deinit(self); @@ -182,6 +186,7 @@ MP_PROPERTY_GETTER(is31fl3741_framebuffer_width_obj, //| height: int //| """The height of the display, in pixels""" //| +//| static mp_obj_t is31fl3741_framebuffer_get_height(mp_obj_t self_in) { is31fl3741_framebuffer_obj_t *self = (is31fl3741_framebuffer_obj_t *)self_in; check_for_deinit(self); diff --git a/shared-bindings/is31fl3741/IS31FL3741.c b/shared-bindings/is31fl3741/IS31FL3741.c index 7815a2ac809..71c4437a1d2 100644 --- a/shared-bindings/is31fl3741/IS31FL3741.c +++ b/shared-bindings/is31fl3741/IS31FL3741.c @@ -25,6 +25,7 @@ //| :param ~busio.I2C i2c: I2C bus the IS31FL3741 is on //| :param int addr: device address""" //| ... +//| static mp_obj_t is31fl3741_IS31FL3741_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_i2c, ARG_addr }; static const mp_arg_t allowed_args[] = { @@ -37,7 +38,6 @@ static mp_obj_t is31fl3741_IS31FL3741_make_new(const mp_obj_type_t *type, size_t mp_obj_t i2c = mp_arg_validate_type(args[ARG_i2c].u_obj, &busio_i2c_type, MP_QSTR_i2c_bus); is31fl3741_IS31FL3741_obj_t *self = mp_obj_malloc(is31fl3741_IS31FL3741_obj_t, &is31fl3741_IS31FL3741_type); - common_hal_is31fl3741_IS31FL3741_construct(self, MP_OBJ_TO_PTR(i2c), args[ARG_addr].u_int @@ -52,6 +52,7 @@ static mp_obj_t is31fl3741_IS31FL3741_make_new(const mp_obj_type_t *type, size_t //| may be performed.""" //| ... //| +//| static mp_obj_t is31fl3741_IS31FL3741_deinit(mp_obj_t self_in) { is31fl3741_IS31FL3741_obj_t *self = (is31fl3741_IS31FL3741_obj_t *)self_in; common_hal_is31fl3741_IS31FL3741_deinit(self); @@ -63,6 +64,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_deinit_obj, is31fl3741_IS //| """Resets the IS31FL3741 chip.""" //| ... //| +//| static mp_obj_t is31fl3741_IS31FL3741_reset(mp_obj_t self_in) { is31fl3741_IS31FL3741_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_is31fl3741_send_reset(self); @@ -74,6 +76,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_reset_obj, is31fl3741_IS31FL3741 //| """Enables the IS31FL3741 chip.""" //| ... //| +//| static mp_obj_t is31fl3741_IS31FL3741_enable(mp_obj_t self_in) { is31fl3741_IS31FL3741_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_is31fl3741_send_enable(self); @@ -87,6 +90,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(is31fl3741_IS31FL3741_enable_obj, is31fl3741_IS31FL374 //| :param int current: global current value 0x00 to 0xFF""" //| ... //| +//| static mp_obj_t is31fl3741_IS31FL3741_set_global_current(mp_obj_t self_in, mp_obj_t value) { is31fl3741_IS31FL3741_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_int_t current = mp_obj_get_int(value); @@ -105,6 +109,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(is31fl3741_IS31FL3741_set_global_current_obj, is31fl37 //| of 0 or 2)""" //| ... //| +//| static mp_obj_t is31fl3741_IS31FL3741_set_led(size_t n_args, const mp_obj_t *args) { is31fl3741_IS31FL3741_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_int_t led = mp_obj_get_int(args[1]); @@ -123,6 +128,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(is31fl3741_IS31FL3741_set_led_obj, 4, 4, is3 //| """ //| ... //| +//| static mp_obj_t is31fl3741_IS31FL3741_write(mp_obj_t self_in, mp_obj_t mapping, mp_obj_t buffer) { is31fl3741_IS31FL3741_obj_t *self = MP_OBJ_TO_PTR(self_in); if (!mp_obj_is_tuple_compatible(mapping)) { @@ -143,11 +149,11 @@ MP_DEFINE_CONST_FUN_OBJ_3(is31fl3741_IS31FL3741_write_obj, is31fl3741_IS31FL3741 static const mp_rom_map_elem_t is31fl3741_IS31FL3741_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&is31fl3741_IS31FL3741_deinit_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&is31fl3741_IS31FL3741_write_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_reset), (mp_obj_t)&is31fl3741_IS31FL3741_reset_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&is31fl3741_IS31FL3741_enable_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_set_global_current), (mp_obj_t)&is31fl3741_IS31FL3741_set_global_current_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_set_led), (mp_obj_t)&is31fl3741_IS31FL3741_set_led_obj }, + { MP_ROM_QSTR(MP_QSTR_write), (mp_obj_t)&is31fl3741_IS31FL3741_write_obj }, + { MP_ROM_QSTR(MP_QSTR_reset), (mp_obj_t)&is31fl3741_IS31FL3741_reset_obj }, + { MP_ROM_QSTR(MP_QSTR_enable), (mp_obj_t)&is31fl3741_IS31FL3741_enable_obj }, + { MP_ROM_QSTR(MP_QSTR_set_global_current), (mp_obj_t)&is31fl3741_IS31FL3741_set_global_current_obj }, + { MP_ROM_QSTR(MP_QSTR_set_led), (mp_obj_t)&is31fl3741_IS31FL3741_set_led_obj }, }; static MP_DEFINE_CONST_DICT(is31fl3741_IS31FL3741_locals_dict, is31fl3741_IS31FL3741_locals_dict_table); diff --git a/shared-bindings/jpegio/JpegDecoder.c b/shared-bindings/jpegio/JpegDecoder.c index d045e178bdd..d55de7b67e0 100644 --- a/shared-bindings/jpegio/JpegDecoder.c +++ b/shared-bindings/jpegio/JpegDecoder.c @@ -23,16 +23,23 @@ //| Example:: //| //| from jpegio import JpegDecoder -//| from displayio import Bitmap +//| from displayio import Bitmap, TileGrid, ColorConverter, Colorspace +//| import supervisor //| //| decoder = JpegDecoder() //| width, height = decoder.open("/sd/example.jpg") //| bitmap = Bitmap(width, height, 65535) //| decoder.decode(bitmap) -//| # .. do something with bitmap +//| tg = TileGrid(bitmap, pixel_shader=ColorConverter(input_colorspace=Colorspace.RGB565_SWAPPED)) +//| supervisor.runtime.display.root_group = tg +//| while True: +//| pass +//| //| """ //| -//| def __init__(self) -> None: ... +//| def __init__(self) -> None: +//| """Create a JpegDecoder""" +//| ... //| static mp_obj_t jpegio_jpegdecoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { static const mp_arg_t allowed_args[] = { @@ -41,12 +48,12 @@ static mp_obj_t jpegio_jpegdecoder_make_new(const mp_obj_type_t *type, size_t n_ mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); jpegio_jpegdecoder_obj_t *self = mp_obj_malloc(jpegio_jpegdecoder_obj_t, &jpegio_jpegdecoder_type); - self->base.type = &jpegio_jpegdecoder_type; common_hal_jpegio_jpegdecoder_construct(self); return MP_OBJ_FROM_PTR(self); } +//| //| @overload //| def open(self, filename: str) -> Tuple[int, int]: ... //| @overload @@ -62,6 +69,7 @@ static mp_obj_t jpegio_jpegdecoder_make_new(const mp_obj_type_t *type, size_t n_ //| not shown in the function signature in the documentation. //| //| Returns the image size as the tuple ``(width, height)``.""" +//| static mp_obj_t jpegio_jpegdecoder_open(mp_obj_t self_in, mp_obj_t arg) { jpegio_jpegdecoder_obj_t *self = MP_OBJ_TO_PTR(self_in); if (mp_obj_is_str(arg)) { @@ -132,7 +140,8 @@ MP_DEFINE_CONST_FUN_OBJ_2(jpegio_jpegdecoder_open_obj, jpegio_jpegdecoder_open); //| by the pixels from the source //| """ //| -static mp_obj_t jpegio_jpegdecoder_decode(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { +//| +static mp_obj_t jpegio_jpegdecoder_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { jpegio_jpegdecoder_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); enum { ARG_bitmap, ARG_scale, ARG_x, ARG_y, ARGS_X1_Y1_X2_Y2, ARG_skip_source_index, ARG_skip_dest_index }; diff --git a/shared-bindings/keypad/Event.c b/shared-bindings/keypad/Event.c index 53c36a76dfb..f83e01e785e 100644 --- a/shared-bindings/keypad/Event.c +++ b/shared-bindings/keypad/Event.c @@ -24,8 +24,8 @@ //| :param int timestamp: The time in milliseconds that the keypress occurred in the `supervisor.ticks_ms` time system. If specified as None, the current value of `supervisor.ticks_ms` is used. //| """ //| ... +//| static mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - keypad_event_obj_t *self = mp_obj_malloc(keypad_event_obj_t, &keypad_event_type); enum { ARG_key_number, ARG_pressed, ARG_timestamp }; static const mp_arg_t allowed_args[] = { { MP_QSTR_key_number, MP_ARG_INT, {.u_int = 0} }, @@ -44,7 +44,9 @@ static mp_obj_t keypad_event_make_new(const mp_obj_type_t *type, size_t n_args, } (void)mp_obj_get_int_truncated(timestamp); // ensure that timestamp is an integer + keypad_event_obj_t *self = mp_obj_malloc(keypad_event_obj_t, &keypad_event_type); common_hal_keypad_event_construct(self, key_number, args[ARG_pressed].u_bool, timestamp); + return MP_OBJ_FROM_PTR(self); } @@ -87,6 +89,7 @@ MP_PROPERTY_GETTER(keypad_event_released_obj, //| timestamp: int //| """The timestamp.""" +//| static mp_obj_t keypad_event_get_timestamp(mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_keypad_event_get_timestamp(self); @@ -103,6 +106,7 @@ MP_PROPERTY_GETTER(keypad_event_timestamp_obj, //| Note that this does not compare the event timestamps. //| """ //| ... +//| static mp_obj_t keypad_event_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) { switch (op) { case MP_BINARY_OP_EQUAL: @@ -131,6 +135,7 @@ static mp_obj_t keypad_event_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_ob //| """ //| ... //| +//| static mp_obj_t keypad_event_unary_op(mp_unary_op_t op, mp_obj_t self_in) { keypad_event_obj_t *self = MP_OBJ_TO_PTR(self_in); switch (op) { diff --git a/shared-bindings/keypad/EventQueue.c b/shared-bindings/keypad/EventQueue.c index e15b19df3b8..a899c652bc5 100644 --- a/shared-bindings/keypad/EventQueue.c +++ b/shared-bindings/keypad/EventQueue.c @@ -20,9 +20,11 @@ //| """ //| //| ... +//| //| def get(self) -> Optional[Event]: -//| """Return the next key transition event. Return ``None`` if no events are pending. +//| """Remove the next key transition event from the `EventQueue` and return it. +//| Return ``None`` if no events are pending. //| //| Note that the queue size is limited; see ``max_events`` in the constructor of //| a scanner such as `Keys` or `KeyMatrix`. @@ -33,6 +35,7 @@ //| :rtype: Optional[Event] //| """ //| ... +//| static mp_obj_t keypad_eventqueue_get(mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -41,7 +44,7 @@ static mp_obj_t keypad_eventqueue_get(mp_obj_t self_in) { MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_get_obj, keypad_eventqueue_get); //| def get_into(self, event: Event) -> bool: -//| """Store the next key transition event in the supplied event, if available, +//| """Remove the next key transition event from the ``EventQueue`, store it in ``event``, //| and return ``True``. //| If there are no queued events, do not touch ``event`` and return ``False``. //| @@ -55,6 +58,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_get_obj, keypad_eventqueue_get); //| :rtype: bool //| """ //| ... +//| static mp_obj_t keypad_eventqueue_get_into(mp_obj_t self_in, mp_obj_t event_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -67,6 +71,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(keypad_eventqueue_get_into_obj, keypad_eventqueue_get_ //| def clear(self) -> None: //| """Clear any queued key transition events. Also sets `overflowed` to ``False``.""" //| ... +//| static mp_obj_t keypad_eventqueue_clear(mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -84,6 +89,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_eventqueue_clear_obj, keypad_eventqueue_clear); //| def __len__(self) -> int: //| """Return the number of events currently in the queue. Used to implement ``len()``.""" //| ... +//| static mp_obj_t keypad_eventqueue_unary_op(mp_unary_op_t op, mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_keypad_eventqueue_get_length(self); @@ -102,6 +108,7 @@ static mp_obj_t keypad_eventqueue_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| Set to ``False`` by `clear()`. //| """ //| +//| static mp_obj_t keypad_eventqueue_get_overflowed(mp_obj_t self_in) { keypad_eventqueue_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_bool(common_hal_keypad_eventqueue_get_overflowed(self)); diff --git a/shared-bindings/keypad/EventQueue.h b/shared-bindings/keypad/EventQueue.h index 893165e3220..02c3414b076 100644 --- a/shared-bindings/keypad/EventQueue.h +++ b/shared-bindings/keypad/EventQueue.h @@ -11,7 +11,7 @@ extern const mp_obj_type_t keypad_eventqueue_type; -void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events); +void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events, bool use_gc_allocator); void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self); size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self); diff --git a/shared-bindings/keypad/KeyMatrix.c b/shared-bindings/keypad/KeyMatrix.c index 7a8bb97247a..01416a2f8a1 100644 --- a/shared-bindings/keypad/KeyMatrix.c +++ b/shared-bindings/keypad/KeyMatrix.c @@ -67,12 +67,20 @@ //| in the respective state for ``debounce_threshold`` times on average. //| Successive measurements are spaced apart by ``interval`` seconds. //| The default is 1, which resolves immediately. The maximum is 127. +//| +//| .. warning:: On Raspberry Pi RP2350, using ``columns_to_anodes=False`` +//| normally depends on the internal pull-down resistors. +//| This will not work, due to an RP2350 issue. +//| The easiest fix is simply to swap the ``row_pins`` and ```column_pins`` and to set +//| ``columns_to_anodes=True``. This requires no external components. +//| An alternative is to add external pull-downs of 8.2 kohms or less, but that will draw more current. +//| See the Warning in `digitalio` for more information. //| """ //| ... +//| static mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_KEYPAD_KEYMATRIX - keypad_keymatrix_obj_t *self = mp_obj_malloc(keypad_keymatrix_obj_t, &keypad_keymatrix_type); enum { ARG_row_pins, ARG_column_pins, ARG_columns_to_anodes, ARG_interval, ARG_max_events, ARG_debounce_threshold }; static const mp_arg_t allowed_args[] = { { MP_QSTR_row_pins, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -114,7 +122,9 @@ static mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar column_pins_array[column] = pin; } + keypad_keymatrix_obj_t *self = mp_obj_malloc(keypad_keymatrix_obj_t, &keypad_keymatrix_type); common_hal_keypad_keymatrix_construct(self, num_row_pins, row_pins_array, num_column_pins, column_pins_array, args[ARG_columns_to_anodes].u_bool, interval, max_events, debounce_threshold); + return MP_OBJ_FROM_PTR(self); #else mp_raise_NotImplementedError_varg(MP_ERROR_TEXT("%q"), MP_QSTR_KeyMatrix); @@ -126,6 +136,7 @@ static mp_obj_t keypad_keymatrix_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... +//| static mp_obj_t keypad_keymatrix_deinit(mp_obj_t self_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_keypad_keymatrix_deinit(self); @@ -136,18 +147,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_keymatrix_deinit_obj, keypad_keymatrix_deinit); //| def __enter__(self) -> KeyMatrix: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t keypad_keymatrix___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_keypad_keymatrix_deinit(args[0]); - return MP_ROM_NONE; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_keymatrix___exit___obj, 4, 4, keypad_keymatrix___exit__); +//| +// Provided by context manager helper. static void check_for_deinit(keypad_keymatrix_obj_t *self) { if (common_hal_keypad_deinited(self)) { @@ -159,12 +167,17 @@ static void check_for_deinit(keypad_keymatrix_obj_t *self) { //| """Reset the internal state of the scanner to assume that all keys are now released. //| Any key that is already pressed at the time of this call will therefore immediately cause //| a new key-pressed event to occur. +//| For instance, if you call `reset()` immediately after creating a `KeyMatrix` object +//| at the beginning of your program, the events it generates will let you determine which keys +//| were being held down at program start. //| """ //| ... +//| //| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ +//| //| def key_number_to_row_column(self, key_number: int) -> Tuple[int]: //| """Return the row and column for the given key number. @@ -175,6 +188,7 @@ static void check_for_deinit(keypad_keymatrix_obj_t *self) { //| :rtype: Tuple[int] //| """ //| ... +//| static mp_obj_t keypad_keymatrix_key_number_to_row_column(mp_obj_t self_in, mp_obj_t key_number_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -201,6 +215,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(keypad_keymatrix_key_number_to_row_column_obj, keypad_ //| The key number is ``row * len(column_pins) + column``. //| """ //| ... +//| static mp_obj_t keypad_keymatrix_row_column_to_key_number(mp_obj_t self_in, mp_obj_t row_in, mp_obj_t column_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -220,11 +235,12 @@ MP_DEFINE_CONST_FUN_OBJ_3(keypad_keymatrix_row_column_to_key_number_obj, keypad_ //| """The `EventQueue` associated with this `Keys` object. (read-only) //| """ //| +//| static const mp_rom_map_elem_t keypad_keymatrix_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&keypad_keymatrix_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_keymatrix___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_generic_events_obj) }, { MP_ROM_QSTR(MP_QSTR_key_count), MP_ROM_PTR(&keypad_generic_key_count_obj) }, diff --git a/shared-bindings/keypad/Keys.c b/shared-bindings/keypad/Keys.c index 208bc0a62d4..5fd065fc627 100644 --- a/shared-bindings/keypad/Keys.c +++ b/shared-bindings/keypad/Keys.c @@ -69,12 +69,18 @@ //| in the respective state for ``debounce_threshold`` times on average. //| Successive measurements are spaced apart by ``interval`` seconds. //| The default is 1, which resolves immediately. The maximum is 127. +//| +//| .. warning:: On Raspberry Pi RP2350, using ``value_when_pressed=True`` and ``pull=True``, +//| to enable using the internal pull-down resistor, will not work, due to an RP2350 +//| hardware issue. Instead, wire the switch to be ``value_when_pressed=False``, or add +//| an external pull-down resistor of 8.2 kohms or less. +//| See the Warning in `digitalio` for more information. //| """ //| ... +//| static mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_KEYPAD_KEYS - keypad_keys_obj_t *self = mp_obj_malloc(keypad_keys_obj_t, &keypad_keys_type); enum { ARG_pins, ARG_value_when_pressed, ARG_pull, ARG_interval, ARG_max_events, ARG_debounce_threshold }; static const mp_arg_t allowed_args[] = { { MP_QSTR_pins, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -105,6 +111,7 @@ static mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, s validate_obj_is_free_pin(mp_obj_subscr(pins, MP_OBJ_NEW_SMALL_INT(i), MP_OBJ_SENTINEL), MP_QSTR_pin); } + keypad_keys_obj_t *self = mp_obj_malloc(keypad_keys_obj_t, &keypad_keys_type); common_hal_keypad_keys_construct(self, num_pins, pins_array, value_when_pressed, args[ARG_pull].u_bool, interval, max_events, debounce_threshold); return MP_OBJ_FROM_PTR(self); @@ -118,6 +125,7 @@ static mp_obj_t keypad_keys_make_new(const mp_obj_type_t *type, size_t n_args, s //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... +//| static mp_obj_t keypad_keys_deinit(mp_obj_t self_in) { keypad_keys_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -129,26 +137,27 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_keys_deinit_obj, keypad_keys_deinit); //| def __enter__(self) -> Keys: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t keypad_keys___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_keypad_keys_deinit(args[0]); - return MP_ROM_NONE; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_keys___exit___obj, 4, 4, keypad_keys___exit__); +//| +// Provided by context manager helper. //| def reset(self) -> None: //| """Reset the internal state of the scanner to assume that all keys are now released. //| Any key that is already pressed at the time of this call will therefore immediately cause //| a new key-pressed event to occur. +//| For instance, if you call `reset()` immediately after creating a `Keys` object +//| at the beginning of your program, the events it generates will let you determine which keys +//| were being held down at program start. //| """ //| ... +//| //| key_count: int //| """The number of keys that are being scanned. (read-only) @@ -158,10 +167,11 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_keys___exit___obj, 4, 4, keypa //| """The `EventQueue` associated with this `Keys` object. (read-only) //| """ //| +//| static const mp_rom_map_elem_t keypad_keys_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&keypad_keys_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_keys___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_generic_events_obj) }, { MP_ROM_QSTR(MP_QSTR_key_count), MP_ROM_PTR(&keypad_generic_key_count_obj) }, diff --git a/shared-bindings/keypad/ShiftRegisterKeys.c b/shared-bindings/keypad/ShiftRegisterKeys.c index a0bcde96e94..7f89a11ecf1 100644 --- a/shared-bindings/keypad/ShiftRegisterKeys.c +++ b/shared-bindings/keypad/ShiftRegisterKeys.c @@ -53,13 +53,14 @@ //| //| Key number 0 is the first (or more properly, the zero-th) bit read. In the //| 74HC165, this bit is labeled ``Q7``. Key number 1 will be the value of ``Q6``, etc. -//| With multiple data pins, key numbers of the next pin are sequentially to the current pin. +//| Key numbers are sequenced such that there are ``key_count[0]`` values read from ``data[0]``, followed by ``key_count[1]`` values read from ``data[1]``, etc. //| //| An `EventQueue` is created when this object is created and is available in the `events` attribute. //| //| :param microcontroller.Pin clock: The shift register clock pin. //| The shift register should clock on a low-to-high transition. -//| :param Union[microcontroller.Pin, Sequence[microcontroller.Pin]] data: the incoming shift register data pin(s) +//| :param Union[microcontroller.Pin, Sequence[microcontroller.Pin]] data: the incoming shift register data pin(s). +//| When a ``microcontroller.Pin`` argument is given, it is logically equivalent to a one-element sequence. //| :param microcontroller.Pin latch: //| Pin used to latch parallel data going into the shift register. //| :param bool value_to_latch: Pin state to latch data being read. @@ -68,6 +69,7 @@ //| The default is ``True``, which is how the 74HC165 operates. The CD4021 latch is the opposite. //| Once the data is latched, it will be shifted out by toggling the clock pin. //| :param Union[int, Sequence[int]] key_count: number of data lines to clock in (per data pin) +//| When an ``int`` argument is given, it is logically equivalent to a one-element sequence. //| :param bool value_when_pressed: ``True`` if the pin reads high when the key is pressed. //| ``False`` if the pin reads low (is grounded) when the key is pressed. //| :param float interval: Scan keys no more often than ``interval`` to allow for debouncing. @@ -82,11 +84,10 @@ //| The default is 1, which resolves immediately. The maximum is 127. //| """ //| ... +//| static mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_KEYPAD_SHIFTREGISTERKEYS - keypad_shiftregisterkeys_obj_t *self = - mp_obj_malloc(keypad_shiftregisterkeys_obj_t, &keypad_shiftregisterkeys_type); enum { ARG_clock, ARG_data, ARG_latch, ARG_value_to_latch, ARG_key_count, ARG_value_when_pressed, ARG_interval, ARG_max_events, ARG_debounce_threshold }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -136,7 +137,8 @@ static mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz size_t key_count_array[num_key_counts]; if (mp_obj_is_int(args[ARG_key_count].u_obj)) { - const size_t key_count = (size_t)mp_arg_validate_int_min(args[ARG_key_count].u_int, 1, MP_QSTR_key_count); + const size_t key_count = + (size_t)mp_arg_validate_int_min(mp_obj_get_int(args[ARG_key_count].u_obj), 1, MP_QSTR_key_count); key_count_array[0] = key_count; } else { for (size_t kc = 0; kc < num_key_counts; kc++) { @@ -156,6 +158,8 @@ static mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz const size_t max_events = (size_t)mp_arg_validate_int_min(args[ARG_max_events].u_int, 1, MP_QSTR_max_events); const uint8_t debounce_threshold = (uint8_t)mp_arg_validate_int_range(args[ARG_debounce_threshold].u_int, 1, 127, MP_QSTR_debounce_threshold); + keypad_shiftregisterkeys_obj_t *self = + mp_obj_malloc(keypad_shiftregisterkeys_obj_t, &keypad_shiftregisterkeys_type); common_hal_keypad_shiftregisterkeys_construct( self, clock, num_data_pins, data_pins_array, latch, value_to_latch, num_key_counts, key_count_array, value_when_pressed, interval, max_events, debounce_threshold); @@ -170,6 +174,7 @@ static mp_obj_t keypad_shiftregisterkeys_make_new(const mp_obj_type_t *type, siz //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... +//| static mp_obj_t keypad_shiftregisterkeys_deinit(mp_obj_t self_in) { keypad_shiftregisterkeys_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -181,25 +186,26 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_shiftregisterkeys_deinit_obj, keypad_shiftregis //| def __enter__(self) -> Keys: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t keypad_shiftregisterkeys___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_keypad_shiftregisterkeys_deinit(args[0]); - return MP_ROM_NONE; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_shiftregisterkeys___exit___obj, 4, 4, keypad_shiftregisterkeys___exit__); +//| +// Provided by context manager helper. //| def reset(self) -> None: //| """Reset the internal state of the scanner to assume that all keys are now released. //| Any key that is already pressed at the time of this call will therefore immediately cause //| a new key-pressed event to occur. +//| For instance, if you call `reset()` immediately after creating a `ShiftRegisterKeys` object +//| at the beginning of your program, the events it generates will let you determine which keys +//| were being held down at program start. //| """ //| ... +//| //| key_count: int //| """The total number of keys that are being scanned. (read-only) @@ -209,11 +215,12 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_shiftregisterkeys___exit___obj //| """The `EventQueue` associated with this `Keys` object. (read-only) //| """ //| +//| static const mp_rom_map_elem_t keypad_shiftregisterkeys_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&keypad_shiftregisterkeys_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_shiftregisterkeys___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_generic_events_obj) }, { MP_ROM_QSTR(MP_QSTR_key_count), MP_ROM_PTR(&keypad_generic_key_count_obj) }, diff --git a/shared-bindings/keypad/__init__.c b/shared-bindings/keypad/__init__.c index 1a7151c61ea..b182e977829 100644 --- a/shared-bindings/keypad/__init__.c +++ b/shared-bindings/keypad/__init__.c @@ -37,12 +37,8 @@ static mp_obj_t keypad_generic_get_key_count(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(keypad_generic_get_key_count_obj, keypad_generic_get_key_count); -const mp_obj_property_t keypad_generic_key_count_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&keypad_generic_get_key_count_obj, - MP_ROM_NONE, - MP_ROM_NONE}, -}; +MP_PROPERTY_GETTER(keypad_generic_key_count_obj, + (mp_obj_t)&keypad_generic_get_key_count_obj); static mp_obj_t keypad_generic_get_events(mp_obj_t self_in) { keypad_keymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -52,13 +48,8 @@ static mp_obj_t keypad_generic_get_events(mp_obj_t self_in) { } MP_DEFINE_CONST_FUN_OBJ_1(keypad_generic_get_events_obj, keypad_generic_get_events); -const mp_obj_property_t keypad_generic_events_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&keypad_generic_get_events_obj, - MP_ROM_NONE, - MP_ROM_NONE}, -}; - +MP_PROPERTY_GETTER(keypad_generic_events_obj, + (mp_obj_t)&keypad_generic_get_events_obj); //| """Support for scanning keys and key matrices //| @@ -74,7 +65,7 @@ const mp_obj_property_t keypad_generic_events_obj = { //| due to a GPIO hardware issue that causes excessive leakage current (~120uA). //| A pin can read as high even when driven or pulled low, if the input signal is high //| impedance or if an attached pull-down resistor is too weak (has too high a value). -//| See the warning in `digitalio` for more information. +//| See the warnings in `keypad.Keys`, `keypad.KeyMatrix`, and `digitalio` for workarounds and more information. //| //| .. jinja //| """ diff --git a/shared-bindings/keypad/__init__.h b/shared-bindings/keypad/__init__.h index 7f8079ecdc9..fd193cee217 100644 --- a/shared-bindings/keypad/__init__.h +++ b/shared-bindings/keypad/__init__.h @@ -17,5 +17,5 @@ mp_obj_t common_hal_keypad_generic_get_events(void *self); MP_DECLARE_CONST_FUN_OBJ_1(keypad_generic_reset_obj); -extern const mp_obj_property_t keypad_generic_events_obj; -extern const mp_obj_property_t keypad_generic_key_count_obj; +extern const mp_obj_property_getter_t keypad_generic_events_obj; +extern const mp_obj_property_getter_t keypad_generic_key_count_obj; diff --git a/shared-bindings/keypad_demux/DemuxKeyMatrix.c b/shared-bindings/keypad_demux/DemuxKeyMatrix.c index 9f6d65c3dd3..554e461c228 100644 --- a/shared-bindings/keypad_demux/DemuxKeyMatrix.c +++ b/shared-bindings/keypad_demux/DemuxKeyMatrix.c @@ -36,6 +36,8 @@ //| self, //| row_addr_pins: Sequence[microcontroller.Pin], //| column_pins: Sequence[microcontroller.Pin], +//| columns_to_anodes: bool = True, +//| transpose: bool = False, //| interval: float = 0.020, //| max_events: int = 64, //| debounce_threshold: int = 1, @@ -51,7 +53,18 @@ //| An `keypad.EventQueue` is created when this object is created and is available in the `events` attribute. //| //| :param Sequence[microcontroller.Pin] row_addr_pins: The pins attached to the rows demultiplexer. +//| If your columns are multiplexed, set ``transpose`` to ``True``. //| :param Sequence[microcontroller.Pin] column_pins: The pins attached to the columns. +//| :param bool columns_to_anodes: Default ``True``. +//| If the matrix uses diodes, the diode anodes are typically connected to the column pins +//| with the cathodes connected to the row pins. This implies an inverting multiplexer that drives +//| the selected row pin low. If your diodes are reversed, with a non-inverting multiplexer +//| that drives the selected row high, set ``columns_to_anodes`` to ``False``. +//| If ``transpose`` is ``True`` the sense of columns and rows are reversed here. +//| :param bool transpose: Default ``False``. +//| If your matrix is multiplexed on columns rather than rows, set ``transpose`` to ``True``. +//| This swaps the meaning of ``row_addr_pins`` to ``column_addr_pins``; +//| ``column_pins`` to ``row_pins``; and ``columns_to_anodes`` to ``rows_to_anodes``. //| :param float interval: Scan keys no more often than ``interval`` to allow for debouncing. //| ``interval`` is in float seconds. The default is 0.020 (20 msecs). //| :param int max_events: maximum size of `events` `keypad.EventQueue`: @@ -64,13 +77,15 @@ //| The default is 1, which resolves immediately. The maximum is 127. //| """ //| ... +//| static mp_obj_t keypad_demux_demuxkeymatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - keypad_demux_demuxkeymatrix_obj_t *self = mp_obj_malloc(keypad_demux_demuxkeymatrix_obj_t, &keypad_demux_demuxkeymatrix_type); - enum { ARG_row_addr_pins, ARG_column_pins, ARG_interval, ARG_max_events, ARG_debounce_threshold }; + enum { ARG_row_addr_pins, ARG_column_pins, ARG_columns_to_anodes, ARG_transpose, ARG_interval, ARG_max_events, ARG_debounce_threshold }; static const mp_arg_t allowed_args[] = { { MP_QSTR_row_addr_pins, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_column_pins, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_columns_to_anodes, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + { MP_QSTR_transpose, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_interval, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_max_events, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, { MP_QSTR_debounce_threshold, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, @@ -107,13 +122,17 @@ static mp_obj_t keypad_demux_demuxkeymatrix_make_new(const mp_obj_type_t *type, column_pins_array[column] = pin; } - common_hal_keypad_demux_demuxkeymatrix_construct(self, num_row_addr_pins, row_addr_pins_array, num_column_pins, column_pins_array, interval, max_events, debounce_threshold); + keypad_demux_demuxkeymatrix_obj_t *self = mp_obj_malloc(keypad_demux_demuxkeymatrix_obj_t, &keypad_demux_demuxkeymatrix_type); + // Last arg is use_gc_allocator, true during VM use. + common_hal_keypad_demux_demuxkeymatrix_construct(self, num_row_addr_pins, row_addr_pins_array, num_column_pins, column_pins_array, args[ARG_columns_to_anodes].u_bool, args[ARG_transpose].u_bool, interval, max_events, debounce_threshold, true); + return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: //| """Stop scanning and release the pins.""" //| ... +//| static mp_obj_t keypad_demux_demuxkeymatrix_deinit(mp_obj_t self_in) { keypad_demux_demuxkeymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_keypad_demux_demuxkeymatrix_deinit(self); @@ -124,18 +143,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(keypad_demux_demuxkeymatrix_deinit_obj, keypad_demux_d //| def __enter__(self) -> DemuxKeyMatrix: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t keypad_demux_demuxkeymatrix___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_keypad_demux_demuxkeymatrix_deinit(args[0]); - return MP_ROM_NONE; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(keypad_demux_demuxkeymatrix___exit___obj, 4, 4, keypad_demux_demuxkeymatrix___exit__); +//| +// Provided by context manager helper. static void check_for_deinit(keypad_demux_demuxkeymatrix_obj_t *self) { if (common_hal_keypad_deinited(self)) { @@ -147,12 +163,17 @@ static void check_for_deinit(keypad_demux_demuxkeymatrix_obj_t *self) { //| """Reset the internal state of the scanner to assume that all keys are now released. //| Any key that is already pressed at the time of this call will therefore immediately cause //| a new key-pressed event to occur. +//| For instance, if you call `reset()` immediately after creating a `DemuxKeyMatrix` object +//| at the beginning of your program, the events it generates will let you determine which keys +//| were being held down at program start. //| """ //| ... +//| //| key_count: int //| """The number of keys that are being scanned. (read-only) //| """ +//| //| def key_number_to_row_column(self, key_number: int) -> Tuple[int]: //| """Return the row and column for the given key number. @@ -163,6 +184,7 @@ static void check_for_deinit(keypad_demux_demuxkeymatrix_obj_t *self) { //| :rtype: Tuple[int] //| """ //| ... +//| static mp_obj_t keypad_demux_demuxkeymatrix_key_number_to_row_column(mp_obj_t self_in, mp_obj_t key_number_in) { keypad_demux_demuxkeymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -189,6 +211,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(keypad_demux_demuxkeymatrix_key_number_to_row_column_o //| The key number is ``row * len(column_pins) + column``. //| """ //| ... +//| static mp_obj_t keypad_demux_demuxkeymatrix_row_column_to_key_number(mp_obj_t self_in, mp_obj_t row_in, mp_obj_t column_in) { keypad_demux_demuxkeymatrix_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -208,11 +231,12 @@ MP_DEFINE_CONST_FUN_OBJ_3(keypad_demux_demuxkeymatrix_row_column_to_key_number_o //| """The `keypad.EventQueue` associated with this `keypad.Keys` object. (read-only) //| """ //| +//| static const mp_rom_map_elem_t keypad_demux_demuxkeymatrix_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&keypad_demux_demuxkeymatrix_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&keypad_demux_demuxkeymatrix___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_events), MP_ROM_PTR(&keypad_generic_events_obj) }, { MP_ROM_QSTR(MP_QSTR_key_count), MP_ROM_PTR(&keypad_generic_key_count_obj) }, diff --git a/shared-bindings/keypad_demux/DemuxKeyMatrix.h b/shared-bindings/keypad_demux/DemuxKeyMatrix.h index fc7a11a0d37..25d36283e90 100644 --- a/shared-bindings/keypad_demux/DemuxKeyMatrix.h +++ b/shared-bindings/keypad_demux/DemuxKeyMatrix.h @@ -11,7 +11,7 @@ extern const mp_obj_type_t keypad_demux_demuxkeymatrix_type; -void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], mp_float_t interval, size_t max_events, uint8_t debounce_threshold); +void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, bool transpose, mp_float_t interval, size_t max_events, uint8_t debounce_threshold, bool use_gc_allocator); void common_hal_keypad_demux_demuxkeymatrix_deinit(keypad_demux_demuxkeymatrix_obj_t *self); diff --git a/shared-bindings/keypad_demux/__init__.c b/shared-bindings/keypad_demux/__init__.c index c1359b25159..30ef1234823 100644 --- a/shared-bindings/keypad_demux/__init__.c +++ b/shared-bindings/keypad_demux/__init__.c @@ -11,8 +11,14 @@ //| """Support for scanning key matrices that use a demultiplexer //| -//| The `keypad_demux` module provides native support to scan sets of keys or buttons, -//| connected in a row-and-column matrix. +//| The `keypad_demux` module provides native support to scan a matrix of keys or buttons +//| where either the row or column axis is controlled by a demultiplexer or decoder IC +//| such as the 74LS138 or 74LS238. In this arrangement a binary input value +//| determines which column (or row) to select, thereby reducing the number of input pins. +//| For example the input 101 would select line 5 in the matrix. +//| Set ``columns_to_anodes`` to ``False`` with a non-inverting demultiplexer +//| which drives the selected line high. +//| Set ``transpose`` to ``True`` if columns are multiplexed rather than rows. //| //| .. jinja //| """ diff --git a/shared-bindings/locale/__init__.c b/shared-bindings/locale/__init__.c index e3201c13a19..66b9e9762a1 100644 --- a/shared-bindings/locale/__init__.c +++ b/shared-bindings/locale/__init__.c @@ -9,6 +9,7 @@ //| """Locale support module""" //| +//| //| def getlocale() -> None: //| """Returns the current locale setting as a tuple ``(language code, "utf-8")`` //| @@ -18,6 +19,7 @@ //| Differences from CPython: No ``LC_*`` argument is permitted. //| """ //| +//| static mp_obj_t getlocale(void) { mp_rom_error_text_t locale_msg = MP_ERROR_TEXT("en_US"); diff --git a/shared-bindings/lvfontio/OnDiskFont.c b/shared-bindings/lvfontio/OnDiskFont.c new file mode 100644 index 00000000000..3a50ea9aedf --- /dev/null +++ b/shared-bindings/lvfontio/OnDiskFont.c @@ -0,0 +1,98 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/lvfontio/OnDiskFont.h" + +#include + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" + +//| class OnDiskFont: +//| """A font built into CircuitPython for use with LVGL. +//| +//| There is an in-browser converter here: https://lvgl.io/tools/fontconverter +//| +//| The format is documented here: https://github.com/lvgl/lv_font_conv/tree/master/doc""" +//| +//| def __init__(self, file_path: str, max_glyphs: int = 100) -> None: +//| """Create a OnDiskFont by loading an LVGL font file from the filesystem. +//| +//| :param str file_path: The path to the font file +//| :param int max_glyphs: Maximum number of glyphs to cache at once +//| """ +//| ... +//| + +//| bitmap: displayio.Bitmap +//| """Bitmap containing all font glyphs starting with ASCII and followed by unicode. This is useful for use with LVGL.""" +//| +static mp_obj_t lvfontio_ondiskfont_obj_get_bitmap(mp_obj_t self_in) { + lvfontio_ondiskfont_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_lvfontio_ondiskfont_get_bitmap(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(lvfontio_ondiskfont_get_bitmap_obj, lvfontio_ondiskfont_obj_get_bitmap); + +MP_PROPERTY_GETTER(lvfontio_ondiskfont_bitmap_obj, + (mp_obj_t)&lvfontio_ondiskfont_get_bitmap_obj); + +//| def get_bounding_box(self) -> Tuple[int, int]: +//| """Returns the maximum bounds of all glyphs in the font in a tuple of two values: width, height.""" +//| ... +//| +//| +static mp_obj_t lvfontio_ondiskfont_obj_get_bounding_box(mp_obj_t self_in) { + lvfontio_ondiskfont_t *self = MP_OBJ_TO_PTR(self_in); + + return common_hal_lvfontio_ondiskfont_get_bounding_box(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(lvfontio_ondiskfont_get_bounding_box_obj, lvfontio_ondiskfont_obj_get_bounding_box); + +static const mp_rom_map_elem_t lvfontio_ondiskfont_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_bitmap), MP_ROM_PTR(&lvfontio_ondiskfont_bitmap_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_bounding_box), MP_ROM_PTR(&lvfontio_ondiskfont_get_bounding_box_obj) }, +}; +static MP_DEFINE_CONST_DICT(lvfontio_ondiskfont_locals_dict, lvfontio_ondiskfont_locals_dict_table); + +static mp_obj_t lvfontio_ondiskfont_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_file_path, ARG_max_glyphs }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_file_path, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_max_glyphs, MP_ARG_INT, {.u_int = 100} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // Allocate the BuiltinFont object + lvfontio_ondiskfont_t *self = m_new_obj(lvfontio_ondiskfont_t); + self->base.type = &lvfontio_ondiskfont_type; + + // Extract arguments + mp_obj_t file_path_obj = args[ARG_file_path].u_obj; + mp_uint_t max_glyphs = args[ARG_max_glyphs].u_int; + + // Get the C string from the Python string + const char *file_path = mp_obj_str_get_str(file_path_obj); + + // Always use GC allocator for Python-created objects + common_hal_lvfontio_ondiskfont_construct(self, file_path, max_glyphs, true); + + return MP_OBJ_FROM_PTR(self); +} + +MP_DEFINE_CONST_OBJ_TYPE( + lvfontio_ondiskfont_type, + MP_QSTR_OnDiskFont, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, lvfontio_ondiskfont_make_new, + locals_dict, &lvfontio_ondiskfont_locals_dict + ); diff --git a/shared-bindings/lvfontio/OnDiskFont.h b/shared-bindings/lvfontio/OnDiskFont.h new file mode 100644 index 00000000000..d7dac6ac678 --- /dev/null +++ b/shared-bindings/lvfontio/OnDiskFont.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/lvfontio/OnDiskFont.h" + +extern const mp_obj_type_t lvfontio_ondiskfont_type; + +mp_obj_t common_hal_lvfontio_ondiskfont_get_bitmap(const lvfontio_ondiskfont_t *self); +mp_obj_t common_hal_lvfontio_ondiskfont_get_bounding_box(const lvfontio_ondiskfont_t *self); +void common_hal_lvfontio_ondiskfont_get_dimensions(const lvfontio_ondiskfont_t *self, uint16_t *width, uint16_t *height); + +// Function prototypes +void common_hal_lvfontio_ondiskfont_construct(lvfontio_ondiskfont_t *self, const char *file_path, uint16_t max_glyphs, bool use_gc_allocator); +void common_hal_lvfontio_ondiskfont_deinit(lvfontio_ondiskfont_t *self); +bool common_hal_lvfontio_ondiskfont_deinited(lvfontio_ondiskfont_t *self); +int16_t common_hal_lvfontio_ondiskfont_cache_glyph(lvfontio_ondiskfont_t *self, uint32_t codepoint, bool *is_full_width); +void common_hal_lvfontio_ondiskfont_release_glyph(lvfontio_ondiskfont_t *self, uint32_t slot); diff --git a/shared-bindings/lvfontio/__init__.c b/shared-bindings/lvfontio/__init__.c new file mode 100644 index 00000000000..ec5f3522799 --- /dev/null +++ b/shared-bindings/lvfontio/__init__.c @@ -0,0 +1,33 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/lvfontio/__init__.h" +#include "shared-bindings/lvfontio/OnDiskFont.h" + +//| """Core font related data structures for LVGL +//| +//| .. note:: This module is intended only for low-level usage with LVGL. +//| +//| """ + +static const mp_rom_map_elem_t lvfontio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_lvfontio) }, + { MP_ROM_QSTR(MP_QSTR_OnDiskFont), MP_ROM_PTR(&lvfontio_ondiskfont_type) }, +}; + +static MP_DEFINE_CONST_DICT(lvfontio_module_globals, lvfontio_module_globals_table); + +const mp_obj_module_t lvfontio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&lvfontio_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_lvfontio, lvfontio_module); diff --git a/shared-bindings/lvfontio/__init__.h b/shared-bindings/lvfontio/__init__.h new file mode 100644 index 00000000000..b56388fa8ae --- /dev/null +++ b/shared-bindings/lvfontio/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/math/__init__.c b/shared-bindings/math/__init__.c index 6a2dd1b3e16..49ca2958d8c 100644 --- a/shared-bindings/math/__init__.c +++ b/shared-bindings/math/__init__.c @@ -24,8 +24,9 @@ //| //| |see_cpython_module| :mod:`cpython:math`. //| """ +//| -static NORETURN void math_error(void) { +static MP_NORETURN void math_error(void) { mp_raise_ValueError(MP_ERROR_TEXT("math domain error")); } @@ -66,55 +67,68 @@ static NORETURN void math_error(void) { //| pi: float //| """the ratio of a circle's circumference to its diameter""" //| +//| //| def acos(x: float) -> float: //| """Return the inverse cosine of ``x``.""" //| ... //| +//| //| def asin(x: float) -> float: //| """Return the inverse sine of ``x``.""" //| ... //| +//| //| def atan(x: float) -> float: //| """Return the inverse tangent of ``x``.""" //| ... //| +//| //| def atan2(y: float, x: float) -> float: //| """Return the principal value of the inverse tangent of ``y/x``.""" //| ... //| +//| //| def ceil(x: float) -> int: //| """Return an integer, being ``x`` rounded towards positive infinity.""" //| ... //| +//| //| def copysign(x: float, y: float) -> float: //| """Return ``x`` with the sign of ``y``.""" //| ... //| +//| //| def cos(x: float) -> float: //| """Return the cosine of ``x``.""" //| ... //| +//| //| def degrees(x: float) -> float: //| """Return radians ``x`` converted to degrees.""" //| ... //| +//| //| def exp(x: float) -> float: //| """Return the exponential of ``x``.""" //| ... //| +//| //| def fabs(x: float) -> float: //| """Return the absolute value of ``x``.""" //| ... //| +//| //| def floor(x: float) -> int: //| """Return an integer, being ``x`` rounded towards negative infinity.""" //| ... //| +//| //| def fmod(x: float, y: float) -> int: //| """Return the remainder of ``x/y``.""" //| ... //| +//| //| def frexp(x: float) -> Tuple[int, int]: //| """Decomposes a floating-point number into its mantissa and exponent. //| The returned value is the tuple ``(m, e)`` such that ``x == m * 2**e`` @@ -122,54 +136,67 @@ static NORETURN void math_error(void) { //| the relation ``0.5 <= abs(m) < 1`` holds.""" //| ... //| +//| //| def isfinite(x: float) -> bool: //| """Return ``True`` if ``x`` is finite.""" //| ... //| +//| //| def isinf(x: float) -> bool: //| """Return ``True`` if ``x`` is infinite.""" //| ... //| +//| //| def isnan(x: float) -> bool: //| """Return ``True`` if ``x`` is not-a-number""" //| ... //| +//| //| def ldexp(x: float, exp: float) -> float: //| """Return ``x * (2**exp)``.""" //| ... //| +//| //| def log(x: float, base: float = e) -> float: //| """Return the logarithm of x to the given base. If base is not specified, //| returns the natural logarithm (base e) of x""" //| ... //| +//| //| def modf(x: float) -> Tuple[float, float]: //| """Return a tuple of two floats, being the fractional and integral parts of //| ``x``. Both return values have the same sign as ``x``.""" //| ... //| +//| //| def pow(x: float, y: float) -> float: //| """Returns ``x`` to the power of ``y``.""" //| +//| //| def radians(x: float) -> float: //| """Return degrees ``x`` converted to radians.""" //| +//| //| def sin(x: float) -> float: //| """Return the sine of ``x``.""" //| ... //| +//| //| def sqrt(x: float) -> float: //| """Returns the square root of ``x``.""" //| ... //| +//| //| def tan(x: float) -> float: //| """Return the tangent of ``x``.""" //| ... //| +//| //| def trunc(x: float) -> int: //| """Return an integer, being ``x`` rounded towards 0.""" //| ... //| +//| MATH_FUN_1_ERRCOND(sqrt, sqrt, (x < (mp_float_t)0.0)) MATH_FUN_2(pow, pow) @@ -183,6 +210,7 @@ MATH_FUN_1(exp, exp) //| """ //| ... //| +//| MATH_FUN_1(expm1, expm1) //| def log2(x: float) -> float: @@ -192,6 +220,7 @@ MATH_FUN_1(expm1, expm1) //| """ //| ... //| +//| MATH_FUN_1_ERRCOND(log2, log2, (x <= (mp_float_t)0.0)) //| def log10(x: float) -> float: @@ -201,6 +230,7 @@ MATH_FUN_1_ERRCOND(log2, log2, (x <= (mp_float_t)0.0)) //| """ //| ... //| +//| MATH_FUN_1_ERRCOND(log10, log10, (x <= (mp_float_t)0.0)) //| def cosh(x: float) -> float: @@ -210,6 +240,7 @@ MATH_FUN_1_ERRCOND(log10, log10, (x <= (mp_float_t)0.0)) //| """ //| ... //| +//| MATH_FUN_1(cosh, cosh) //| def sinh(x: float) -> float: @@ -219,6 +250,7 @@ MATH_FUN_1(cosh, cosh) //| """ //| ... //| +//| MATH_FUN_1(sinh, sinh) //| def tanh(x: float) -> float: @@ -228,6 +260,7 @@ MATH_FUN_1(sinh, sinh) //| """ //| ... //| +//| MATH_FUN_1(tanh, tanh) //| def acosh(x: float) -> float: @@ -237,6 +270,7 @@ MATH_FUN_1(tanh, tanh) //| """ //| ... //| +//| MATH_FUN_1(acosh, acosh) //| def asinh(x: float) -> float: @@ -246,6 +280,7 @@ MATH_FUN_1(acosh, acosh) //| """ //| ... //| +//| MATH_FUN_1(asinh, asinh) //| def atanh(x: float) -> float: @@ -255,6 +290,7 @@ MATH_FUN_1(asinh, asinh) //| """ //| ... //| +//| MATH_FUN_1(atanh, atanh) #endif @@ -300,6 +336,7 @@ MATH_FUN_2(ldexp, ldexp) //| """ //| ... //| +//| MATH_FUN_1(erf, erf) //| def erfc(x: float) -> float: @@ -309,6 +346,7 @@ MATH_FUN_1(erf, erf) //| """ //| ... //| +//| MATH_FUN_1(erfc, erfc) //| def gamma(x: float) -> float: @@ -318,6 +356,7 @@ MATH_FUN_1(erfc, erfc) //| """ //| ... //| +//| MATH_FUN_1(gamma, tgamma) //| def lgamma(x: float) -> float: @@ -327,6 +366,7 @@ MATH_FUN_1(gamma, tgamma) //| """ //| ... //| +//| MATH_FUN_1(lgamma, lgamma) //| def dist(p: tuple, q: tuple) -> float: @@ -336,6 +376,7 @@ MATH_FUN_1(lgamma, lgamma) //| """ //| ... //| +//| static mp_obj_t mp_math_dist(mp_obj_t p_obj, mp_obj_t q_obj) { mp_obj_t *p_items; mp_obj_get_array_fixed_n(p_obj, 2, &p_items); diff --git a/shared-bindings/max3421e/Max3421E.c b/shared-bindings/max3421e/Max3421E.c index e5c2963fa01..ed3453efeb3 100644 --- a/shared-bindings/max3421e/Max3421E.c +++ b/shared-bindings/max3421e/Max3421E.c @@ -19,7 +19,7 @@ //| *, //| chip_select: microcontroller.Pin, //| irq: microcontroller.Pin, -//| baudrate: int = 26000000 +//| baudrate: int = 26000000, //| ) -> None: //| """Create a Max3421E object associated with the given pins. //| @@ -31,6 +31,7 @@ //| :param microcontroller.Pin irq: Interrupt pin //| :param int baudrate: Maximum baudrate to talk to the Max chip in Hz""" //| ... +//| static mp_obj_t max3421e_max3421e_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_spi_bus, ARG_chip_select, ARG_irq, ARG_baudrate }; static const mp_arg_t allowed_args[] = { @@ -57,6 +58,7 @@ static mp_obj_t max3421e_max3421e_make_new(const mp_obj_type_t *type, size_t n_a //| """Shuts down USB host functionality and releases chip_select and irq pins.""" //| ... //| +//| static mp_obj_t max3421e_max3421e_obj_deinit(mp_obj_t self_in) { max3421e_max3421e_obj_t *self = self_in; if (common_hal_max3421e_max3421e_deinited(self)) { diff --git a/shared-bindings/mcp4822/MCP4822.c b/shared-bindings/mcp4822/MCP4822.c new file mode 100644 index 00000000000..f192caf4052 --- /dev/null +++ b/shared-bindings/mcp4822/MCP4822.c @@ -0,0 +1,243 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/mcp4822/MCP4822.h" +#include "shared-bindings/util.h" + +//| class MCP4822: +//| """Output audio to an MCP4822 dual-channel 12-bit SPI DAC.""" +//| +//| def __init__( +//| self, +//| clock: microcontroller.Pin, +//| mosi: microcontroller.Pin, +//| cs: microcontroller.Pin, +//| *, +//| gain: int = 1, +//| ) -> None: +//| """Create an MCP4822 object associated with the given SPI pins. +//| +//| :param ~microcontroller.Pin clock: The SPI clock (SCK) pin +//| :param ~microcontroller.Pin mosi: The SPI data (SDI/MOSI) pin +//| :param ~microcontroller.Pin cs: The chip select (CS) pin +//| :param int gain: DAC output gain, 1 for 1x (0-2.048V) or 2 for 2x (0-4.096V). Default 1. +//| +//| Simple 8ksps 440 Hz sine wave:: +//| +//| import mcp4822 +//| import audiocore +//| import board +//| import array +//| import time +//| import math +//| +//| length = 8000 // 440 +//| sine_wave = array.array("H", [0] * length) +//| for i in range(length): +//| sine_wave[i] = int(math.sin(math.pi * 2 * i / length) * (2 ** 15) + 2 ** 15) +//| +//| sine_wave = audiocore.RawSample(sine_wave, sample_rate=8000) +//| dac = mcp4822.MCP4822(clock=board.GP18, mosi=board.GP19, cs=board.GP21) +//| dac.play(sine_wave, loop=True) +//| time.sleep(1) +//| dac.stop() +//| +//| Playing a wave file from flash:: +//| +//| import board +//| import audiocore +//| import mcp4822 +//| +//| f = open("sound.wav", "rb") +//| wav = audiocore.WaveFile(f) +//| +//| dac = mcp4822.MCP4822(clock=board.GP18, mosi=board.GP19, cs=board.GP21) +//| dac.play(wav) +//| while dac.playing: +//| pass""" +//| ... +//| +static mp_obj_t mcp4822_mcp4822_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_clock, ARG_mosi, ARG_cs, ARG_gain }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_mosi, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_cs, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_gain, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 1} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *mosi = validate_obj_is_free_pin(args[ARG_mosi].u_obj, MP_QSTR_mosi); + const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj, MP_QSTR_cs); + const mp_int_t gain = mp_arg_validate_int_range(args[ARG_gain].u_int, 1, 2, MP_QSTR_gain); + + mcp4822_mcp4822_obj_t *self = mp_obj_malloc_with_finaliser(mcp4822_mcp4822_obj_t, &mcp4822_mcp4822_type); + common_hal_mcp4822_mcp4822_construct(self, clock, mosi, cs, (uint8_t)gain); + + return MP_OBJ_FROM_PTR(self); +} + +static void check_for_deinit(mcp4822_mcp4822_obj_t *self) { + if (common_hal_mcp4822_mcp4822_deinited(self)) { + raise_deinited_error(); + } +} + +//| def deinit(self) -> None: +//| """Deinitialises the MCP4822 and releases any hardware resources for reuse.""" +//| ... +//| +static mp_obj_t mcp4822_mcp4822_deinit(mp_obj_t self_in) { + mcp4822_mcp4822_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_mcp4822_mcp4822_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(mcp4822_mcp4822_deinit_obj, mcp4822_mcp4822_deinit); + +//| def __enter__(self) -> MCP4822: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| """Plays the sample once when loop=False and continuously when loop=True. +//| Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, `audiomixer.Mixer` or `audiomp3.MP3Decoder`. +//| +//| The sample itself should consist of 8 bit or 16 bit samples.""" +//| ... +//| +static mp_obj_t mcp4822_mcp4822_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + mcp4822_mcp4822_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_obj_t sample = args[ARG_sample].u_obj; + common_hal_mcp4822_mcp4822_play(self, sample, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(mcp4822_mcp4822_play_obj, 1, mcp4822_mcp4822_obj_play); + +//| def stop(self) -> None: +//| """Stops playback.""" +//| ... +//| +static mp_obj_t mcp4822_mcp4822_obj_stop(mp_obj_t self_in) { + mcp4822_mcp4822_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_mcp4822_mcp4822_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mcp4822_mcp4822_stop_obj, mcp4822_mcp4822_obj_stop); + +//| playing: bool +//| """True when the audio sample is being output. (read-only)""" +//| +static mp_obj_t mcp4822_mcp4822_obj_get_playing(mp_obj_t self_in) { + mcp4822_mcp4822_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_mcp4822_mcp4822_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mcp4822_mcp4822_get_playing_obj, mcp4822_mcp4822_obj_get_playing); + +MP_PROPERTY_GETTER(mcp4822_mcp4822_playing_obj, + (mp_obj_t)&mcp4822_mcp4822_get_playing_obj); + +//| def pause(self) -> None: +//| """Stops playback temporarily while remembering the position. Use `resume` to resume playback.""" +//| ... +//| +static mp_obj_t mcp4822_mcp4822_obj_pause(mp_obj_t self_in) { + mcp4822_mcp4822_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (!common_hal_mcp4822_mcp4822_get_playing(self)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Not playing")); + } + common_hal_mcp4822_mcp4822_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mcp4822_mcp4822_pause_obj, mcp4822_mcp4822_obj_pause); + +//| def resume(self) -> None: +//| """Resumes sample playback after :py:func:`pause`.""" +//| ... +//| +static mp_obj_t mcp4822_mcp4822_obj_resume(mp_obj_t self_in) { + mcp4822_mcp4822_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (common_hal_mcp4822_mcp4822_get_paused(self)) { + common_hal_mcp4822_mcp4822_resume(self); + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(mcp4822_mcp4822_resume_obj, mcp4822_mcp4822_obj_resume); + +//| paused: bool +//| """True when playback is paused. (read-only)""" +//| +//| +static mp_obj_t mcp4822_mcp4822_obj_get_paused(mp_obj_t self_in) { + mcp4822_mcp4822_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_mcp4822_mcp4822_get_paused(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mcp4822_mcp4822_get_paused_obj, mcp4822_mcp4822_obj_get_paused); + +MP_PROPERTY_GETTER(mcp4822_mcp4822_paused_obj, + (mp_obj_t)&mcp4822_mcp4822_get_paused_obj); + +static const mp_rom_map_elem_t mcp4822_mcp4822_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mcp4822_mcp4822_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mcp4822_mcp4822_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&mcp4822_mcp4822_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&mcp4822_mcp4822_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&mcp4822_mcp4822_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&mcp4822_mcp4822_resume_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&mcp4822_mcp4822_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&mcp4822_mcp4822_paused_obj) }, +}; +static MP_DEFINE_CONST_DICT(mcp4822_mcp4822_locals_dict, mcp4822_mcp4822_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + mcp4822_mcp4822_type, + MP_QSTR_MCP4822, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, mcp4822_mcp4822_make_new, + locals_dict, &mcp4822_mcp4822_locals_dict + ); diff --git a/shared-bindings/mcp4822/MCP4822.h b/shared-bindings/mcp4822/MCP4822.h new file mode 100644 index 00000000000..b129aec3061 --- /dev/null +++ b/shared-bindings/mcp4822/MCP4822.h @@ -0,0 +1,25 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/mcp4822/MCP4822.h" +#include "common-hal/microcontroller/Pin.h" + +extern const mp_obj_type_t mcp4822_mcp4822_type; + +void common_hal_mcp4822_mcp4822_construct(mcp4822_mcp4822_obj_t *self, + const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, + const mcu_pin_obj_t *cs, uint8_t gain); + +void common_hal_mcp4822_mcp4822_deinit(mcp4822_mcp4822_obj_t *self); +bool common_hal_mcp4822_mcp4822_deinited(mcp4822_mcp4822_obj_t *self); +void common_hal_mcp4822_mcp4822_play(mcp4822_mcp4822_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_mcp4822_mcp4822_stop(mcp4822_mcp4822_obj_t *self); +bool common_hal_mcp4822_mcp4822_get_playing(mcp4822_mcp4822_obj_t *self); +void common_hal_mcp4822_mcp4822_pause(mcp4822_mcp4822_obj_t *self); +void common_hal_mcp4822_mcp4822_resume(mcp4822_mcp4822_obj_t *self); +bool common_hal_mcp4822_mcp4822_get_paused(mcp4822_mcp4822_obj_t *self); diff --git a/shared-bindings/mcp4822/__init__.c b/shared-bindings/mcp4822/__init__.c new file mode 100644 index 00000000000..bac2136d9e7 --- /dev/null +++ b/shared-bindings/mcp4822/__init__.c @@ -0,0 +1,36 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/mcp4822/__init__.h" +#include "shared-bindings/mcp4822/MCP4822.h" + +//| """Audio output via MCP4822 dual-channel 12-bit SPI DAC. +//| +//| The `mcp4822` module provides the `MCP4822` class for non-blocking +//| audio playback through the Microchip MCP4822 SPI DAC using PIO and DMA. +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager.""" + +static const mp_rom_map_elem_t mcp4822_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mcp4822) }, + { MP_ROM_QSTR(MP_QSTR_MCP4822), MP_ROM_PTR(&mcp4822_mcp4822_type) }, +}; + +static MP_DEFINE_CONST_DICT(mcp4822_module_globals, mcp4822_module_globals_table); + +const mp_obj_module_t mcp4822_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mcp4822_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_mcp4822, mcp4822_module); diff --git a/shared-bindings/mcp4822/__init__.h b/shared-bindings/mcp4822/__init__.h new file mode 100644 index 00000000000..c4a52e5819d --- /dev/null +++ b/shared-bindings/mcp4822/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/mdns/RemoteService.c b/shared-bindings/mdns/RemoteService.c index d1eddc69611..b00313729fc 100644 --- a/shared-bindings/mdns/RemoteService.c +++ b/shared-bindings/mdns/RemoteService.c @@ -20,6 +20,7 @@ //| def __init__(self) -> None: //| """Cannot be instantiated directly. Use `mdns.Server.find`.""" //| ... +//| //| hostname: str //| """The hostname of the device (read-only),.""" @@ -82,6 +83,7 @@ MP_PROPERTY_GETTER(mdns_remoteservice_port_obj, //| ipv4_address: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the remote service. None if no A records are found.""" +//| static mp_obj_t _mdns_remoteservice_get_ipv4_address(mp_obj_t self) { return common_hal_mdns_remoteservice_get_ipv4_address(self); @@ -91,17 +93,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(mdns_remoteservice_get_ipv4_address_obj, _mdns_remotes MP_PROPERTY_GETTER(mdns_remoteservice_ipv4_address_obj, (mp_obj_t)&mdns_remoteservice_get_ipv4_address_obj); -//| def __del__(self) -> None: -//| """Deletes the RemoteService object.""" -//| ... -//| -static mp_obj_t mdns_remoteservice_obj_deinit(mp_obj_t self_in) { - mdns_remoteservice_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_mdns_remoteservice_deinit(self); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_1(mdns_remoteservice_deinit_obj, mdns_remoteservice_obj_deinit); - static const mp_rom_map_elem_t mdns_remoteservice_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_hostname), MP_ROM_PTR(&mdns_remoteservice_hostname_obj) }, { MP_ROM_QSTR(MP_QSTR_instance_name), MP_ROM_PTR(&mdns_remoteservice_instance_name_obj) }, @@ -109,8 +100,6 @@ static const mp_rom_map_elem_t mdns_remoteservice_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_protocol), MP_ROM_PTR(&mdns_remoteservice_protocol_obj) }, { MP_ROM_QSTR(MP_QSTR_port), MP_ROM_PTR(&mdns_remoteservice_port_obj) }, { MP_ROM_QSTR(MP_QSTR_ipv4_address), MP_ROM_PTR(&mdns_remoteservice_ipv4_address_obj) }, - - { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mdns_remoteservice_deinit_obj) }, }; static MP_DEFINE_CONST_DICT(mdns_remoteservice_locals_dict, mdns_remoteservice_locals_dict_table); diff --git a/shared-bindings/mdns/RemoteService.h b/shared-bindings/mdns/RemoteService.h index a5ffe897e4e..c7efa64083d 100644 --- a/shared-bindings/mdns/RemoteService.h +++ b/shared-bindings/mdns/RemoteService.h @@ -19,7 +19,6 @@ const char *common_hal_mdns_remoteservice_get_instance_name(mdns_remoteservice_o const char *common_hal_mdns_remoteservice_get_hostname(mdns_remoteservice_obj_t *self); mp_int_t common_hal_mdns_remoteservice_get_port(mdns_remoteservice_obj_t *self); mp_obj_t common_hal_mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self); -void common_hal_mdns_remoteservice_deinit(mdns_remoteservice_obj_t *self); // For internal use. uint32_t mdns_remoteservice_get_ipv4_address(mdns_remoteservice_obj_t *self); diff --git a/shared-bindings/mdns/Server.c b/shared-bindings/mdns/Server.c index c4670fccc23..1c16348d425 100644 --- a/shared-bindings/mdns/Server.c +++ b/shared-bindings/mdns/Server.c @@ -30,6 +30,7 @@ //| may already be using it.) Only native interfaces are currently supported. //| """ //| ... +//| static mp_obj_t mdns_server_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_network_interface }; static const mp_arg_t allowed_args[] = { @@ -55,6 +56,7 @@ static mp_obj_t mdns_server_make_new(const mp_obj_type_t *type, size_t n_args, s //| def deinit(self) -> None: //| """Stops the server""" //| ... +//| static mp_obj_t mdns_server_obj_deinit(mp_obj_t self_in) { mdns_server_obj_t *self = (mdns_server_obj_t *)self_in; common_hal_mdns_server_deinit(self); @@ -93,6 +95,7 @@ MP_PROPERTY_GETSET(mdns_server_hostname_obj, //| instance_name: str //| """Human readable name to describe the device.""" +//| static mp_obj_t mdns_server_get_instance_name(mp_obj_t self) { check_for_deinit(self); const char *instance_name = common_hal_mdns_server_get_instance_name(self); @@ -124,6 +127,7 @@ MP_PROPERTY_GETSET(mdns_server_instance_name_obj, //| :param str protocol: The service protocol such as "_tcp" //| :param float/int timeout: Time to wait for responses""" //| ... +//| static mp_obj_t _mdns_server_find(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mdns_server_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); @@ -146,7 +150,14 @@ static mp_obj_t _mdns_server_find(mp_uint_t n_args, const mp_obj_t *pos_args, mp } static MP_DEFINE_CONST_FUN_OBJ_KW(mdns_server_find_obj, 1, _mdns_server_find); -//| def advertise_service(self, *, service_type: str, protocol: str, port: int) -> None: +//| def advertise_service( +//| self, +//| *, +//| service_type: str, +//| protocol: str, +//| port: int, +//| txt_records: Optional[Sequence[str]] = None, +//| ) -> None: //| """Respond to queries for the given service with the given port. //| //| ``service_type`` and ``protocol`` can only occur on one port. Any call after the first @@ -154,8 +165,8 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(mdns_server_find_obj, 1, _mdns_server_find); //| //| If web workflow is active, the port it uses can't also be used to advertise a service. //| -//| **Limitations**: Publishing up to 32 TXT records is only supported on the RP2040 Pico W board at -//| this time. +//| **Limitations**: Publishing TXT records (up to 32) is supported only on RP2xxx. +//| There is currently no TXT record support on Espressif boards. //| //| :param str service_type: The service type such as "_http" //| :param str protocol: The service protocol such as "_tcp" @@ -164,6 +175,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(mdns_server_find_obj, 1, _mdns_server_find); //| """ //| ... //| +//| static mp_obj_t mdns_server_advertise_service(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mdns_server_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); check_for_deinit(self); diff --git a/shared-bindings/memorymap/AddressRange.c b/shared-bindings/memorymap/AddressRange.c index 821609bb933..5f7ee0deb95 100644 --- a/shared-bindings/memorymap/AddressRange.c +++ b/shared-bindings/memorymap/AddressRange.c @@ -63,6 +63,7 @@ //| ``start + length``. An exception will be raised if any of the //| addresses are invalid or protected.""" //| ... +//| static mp_obj_t memorymap_addressrange_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_start, ARG_length }; static const mp_arg_t allowed_args[] = { @@ -91,7 +92,6 @@ static mp_obj_t memorymap_addressrange_make_new(const mp_obj_type_t *type, size_ } memorymap_addressrange_obj_t *self = mp_obj_malloc(memorymap_addressrange_obj_t, &memorymap_addressrange_type); - common_hal_memorymap_addressrange_construct(self, (uint8_t *)start, length); return MP_OBJ_FROM_PTR(self); @@ -101,6 +101,7 @@ static mp_obj_t memorymap_addressrange_make_new(const mp_obj_type_t *type, size_ //| def __len__(self) -> int: //| """Return the length. This is used by (`len`)""" //| ... +//| static mp_obj_t memorymap_addressrange_unary_op(mp_unary_op_t op, mp_obj_t self_in) { memorymap_addressrange_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_memorymap_addressrange_get_length(self); @@ -132,6 +133,7 @@ static MP_DEFINE_CONST_DICT(memorymap_addressrange_locals_dict, memorymap_addres //| //| @overload //| def __setitem__(self, index: slice, value: ReadableBuffer) -> None: ... +//| //| @overload //| def __setitem__(self, index: int, value: int) -> None: //| """Set the value(s) at the given index. @@ -141,6 +143,7 @@ static MP_DEFINE_CONST_DICT(memorymap_addressrange_locals_dict, memorymap_addres //| All others may use multiple transactions.""" //| ... //| +//| static mp_obj_t memorymap_addressrange_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item diff --git a/shared-bindings/memorymonitor/AllocationAlarm.c b/shared-bindings/memorymonitor/AllocationAlarm.c index 9fa07376b2c..00cfbbd9fe1 100644 --- a/shared-bindings/memorymonitor/AllocationAlarm.c +++ b/shared-bindings/memorymonitor/AllocationAlarm.c @@ -33,6 +33,7 @@ //| //| """ //| ... +//| static mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { enum { ARG_minimum_block_count }; static const mp_arg_t allowed_args[] = { @@ -47,7 +48,6 @@ static mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type memorymonitor_allocationalarm_obj_t *self = mp_obj_malloc(memorymonitor_allocationalarm_obj_t, &memorymonitor_allocationalarm_type); - common_hal_memorymonitor_allocationalarm_construct(self, minimum_block_count); return MP_OBJ_FROM_PTR(self); @@ -64,6 +64,7 @@ static mp_obj_t memorymonitor_allocationalarm_make_new(const mp_obj_type_t *type //| x = bytearray(20) //| """ //| ... +//| static mp_obj_t memorymonitor_allocationalarm_obj_ignore(mp_obj_t self_in, mp_obj_t count_obj) { mp_int_t count = mp_obj_get_int(count_obj); mp_arg_validate_int_min(count, 0, MP_QSTR_count); @@ -76,6 +77,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(memorymonitor_allocationalarm_ignore_obj, memorymonito //| def __enter__(self) -> AllocationAlarm: //| """Enables the alarm.""" //| ... +//| static mp_obj_t memorymonitor_allocationalarm_obj___enter__(mp_obj_t self_in) { common_hal_memorymonitor_allocationalarm_resume(self_in); return self_in; @@ -87,6 +89,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationalarm___enter___obj, memorymon //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... //| +//| static mp_obj_t memorymonitor_allocationalarm_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_memorymonitor_allocationalarm_set_ignore(args[0], 0); diff --git a/shared-bindings/memorymonitor/AllocationSize.c b/shared-bindings/memorymonitor/AllocationSize.c index 34f1d3e3f3b..3113d6ed191 100644 --- a/shared-bindings/memorymonitor/AllocationSize.c +++ b/shared-bindings/memorymonitor/AllocationSize.c @@ -40,6 +40,7 @@ //| //| """ //| ... +//| static mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) { memorymonitor_allocationsize_obj_t *self = m_new_obj(memorymonitor_allocationsize_obj_t, &memorymonitor_allocationsize_type); @@ -52,6 +53,7 @@ static mp_obj_t memorymonitor_allocationsize_make_new(const mp_obj_type_t *type, //| def __enter__(self) -> AllocationSize: //| """Clears counts and resumes tracking.""" //| ... +//| static mp_obj_t memorymonitor_allocationsize_obj___enter__(mp_obj_t self_in) { common_hal_memorymonitor_allocationsize_clear(self_in); common_hal_memorymonitor_allocationsize_resume(self_in); @@ -63,6 +65,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(memorymonitor_allocationsize___enter___obj, memorymoni //| """Automatically pauses allocation tracking when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... +//| static mp_obj_t memorymonitor_allocationsize_obj___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_memorymonitor_allocationsize_pause(args[0]); @@ -72,6 +75,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(memorymonitor_allocationsize___exit__ //| bytes_per_block: int //| """Number of bytes per block""" +//| static mp_obj_t memorymonitor_allocationsize_obj_get_bytes_per_block(mp_obj_t self_in) { memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -90,6 +94,7 @@ MP_PROPERTY_GETTER(memorymonitor_allocationsize_bytes_per_block_obj, //| mm = memorymonitor.AllocationSize() //| print(len(mm))""" //| ... +//| static mp_obj_t memorymonitor_allocationsize_unary_op(mp_unary_op_t op, mp_obj_t self_in) { memorymonitor_allocationsize_obj_t *self = MP_OBJ_TO_PTR(self_in); uint16_t len = common_hal_memorymonitor_allocationsize_get_len(self); @@ -112,6 +117,7 @@ static mp_obj_t memorymonitor_allocationsize_unary_op(mp_unary_op_t op, mp_obj_t //| print(mm[0])""" //| ... //| +//| static mp_obj_t memorymonitor_allocationsize_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { if (value == mp_const_none) { // delete item diff --git a/shared-bindings/memorymonitor/__init__.c b/shared-bindings/memorymonitor/__init__.c index e925eb54e74..e364344b363 100644 --- a/shared-bindings/memorymonitor/__init__.c +++ b/shared-bindings/memorymonitor/__init__.c @@ -15,15 +15,17 @@ //| """Memory monitoring helpers""" //| +//| //| class AllocationError(Exception): //| """Catchall exception for allocation related errors.""" //| //| ... //| +//| MP_DEFINE_MEMORYMONITOR_EXCEPTION(AllocationError, Exception) -NORETURN void mp_raise_memorymonitor_AllocationError(mp_rom_error_text_t fmt, ...) { +MP_NORETURN void mp_raise_memorymonitor_AllocationError(mp_rom_error_text_t fmt, ...) { va_list argptr; va_start(argptr, fmt); mp_obj_t exception = mp_obj_new_exception_msg_vlist(&mp_type_memorymonitor_AllocationError, fmt, argptr); diff --git a/shared-bindings/memorymonitor/__init__.h b/shared-bindings/memorymonitor/__init__.h index 28480bea7b5..5f141b924d0 100644 --- a/shared-bindings/memorymonitor/__init__.h +++ b/shared-bindings/memorymonitor/__init__.h @@ -23,4 +23,4 @@ void memorymonitor_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_pr extern const mp_obj_type_t mp_type_memorymonitor_AllocationError; -NORETURN void mp_raise_memorymonitor_AllocationError(mp_rom_error_text_t msg, ...); +MP_NORETURN void mp_raise_memorymonitor_AllocationError(mp_rom_error_text_t msg, ...); diff --git a/shared-bindings/microcontroller/Pin.c b/shared-bindings/microcontroller/Pin.c index b0260a22954..1fcde50e060 100644 --- a/shared-bindings/microcontroller/Pin.c +++ b/shared-bindings/microcontroller/Pin.c @@ -20,11 +20,13 @@ //| hardware so they cannot be constructed on demand. Instead, use //| :mod:`board` or :mod:`microcontroller.pin` to reference the desired pin.""" //| ... +//| //| def __hash__(self) -> int: //| """Returns a hash for the Pin.""" //| ... //| +//| // Provided inherently. // See https://github.com/micropython/micropython/pull/10348. @@ -173,14 +175,14 @@ void validate_pins(qstr what, uint8_t *pin_nos, mp_int_t max_pins, mp_obj_t seq, } } -NORETURN void raise_ValueError_invalid_pin(void) { +MP_NORETURN void raise_ValueError_invalid_pin(void) { mp_arg_error_invalid(MP_QSTR_pin); } -NORETURN void raise_ValueError_invalid_pins(void) { +MP_NORETURN void raise_ValueError_invalid_pins(void) { mp_arg_error_invalid(MP_QSTR_pins); } -NORETURN void raise_ValueError_invalid_pin_name(qstr pin_name) { +MP_NORETURN void raise_ValueError_invalid_pin_name(qstr pin_name) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q pin"), pin_name); } diff --git a/shared-bindings/microcontroller/Pin.h b/shared-bindings/microcontroller/Pin.h index 1245b5f23e4..8ddca71bfbb 100644 --- a/shared-bindings/microcontroller/Pin.h +++ b/shared-bindings/microcontroller/Pin.h @@ -21,9 +21,9 @@ void validate_no_duplicate_pins(mp_obj_t seq, qstr arg_name); void validate_no_duplicate_pins_2(mp_obj_t seq1, mp_obj_t seq2, qstr arg_name1, qstr arg_name2); void validate_list_is_free_pins(qstr what, const mcu_pin_obj_t **pins_out, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out); void validate_pins(qstr what, uint8_t *pin_nos, mp_int_t max_pins, mp_obj_t seq, uint8_t *count_out); -NORETURN void raise_ValueError_invalid_pin(void); -NORETURN void raise_ValueError_invalid_pins(void); -NORETURN void raise_ValueError_invalid_pin_name(qstr pin_name); +MP_NORETURN void raise_ValueError_invalid_pin(void); +MP_NORETURN void raise_ValueError_invalid_pins(void); +MP_NORETURN void raise_ValueError_invalid_pin_name(qstr pin_name); void assert_pin_free(const mcu_pin_obj_t *pin); diff --git a/shared-bindings/microcontroller/Processor.c b/shared-bindings/microcontroller/Processor.c index 0a140597832..a3518ab754f 100644 --- a/shared-bindings/microcontroller/Processor.c +++ b/shared-bindings/microcontroller/Processor.c @@ -42,6 +42,7 @@ //| """You cannot create an instance of `microcontroller.Processor`. //| Use `microcontroller.cpu` to access the sole instance available.""" //| ... +//| //| frequency: int //| """The CPU operating frequency in Hertz. @@ -130,6 +131,7 @@ MP_PROPERTY_GETTER(mcu_processor_uid_obj, //| //| Is `None` if the voltage is not available.""" //| +//| static mp_obj_t mcu_processor_get_voltage(mp_obj_t self) { float voltage = common_hal_mcu_processor_get_voltage(); return isnan(voltage) ? mp_const_none : mp_obj_new_float(voltage); diff --git a/shared-bindings/microcontroller/ResetReason.c b/shared-bindings/microcontroller/ResetReason.c index 301205d84f3..46eb23e36aa 100644 --- a/shared-bindings/microcontroller/ResetReason.c +++ b/shared-bindings/microcontroller/ResetReason.c @@ -9,14 +9,14 @@ #include "shared-bindings/microcontroller/ResetReason.h" -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, POWER_ON, RESET_REASON_POWER_ON); -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, BROWNOUT, RESET_REASON_BROWNOUT); -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, SOFTWARE, RESET_REASON_SOFTWARE); -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, RESET_REASON_DEEP_SLEEP_ALARM); -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESET_PIN, RESET_REASON_RESET_PIN); -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, RESET_REASON_WATCHDOG); -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, UNKNOWN, RESET_REASON_UNKNOWN); -MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESCUE_DEBUG, RESET_REASON_RESCUE_DEBUG); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, POWER_ON, MCU_RESET_REASON_POWER_ON); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, BROWNOUT, MCU_RESET_REASON_BROWNOUT); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, SOFTWARE, MCU_RESET_REASON_SOFTWARE); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, DEEP_SLEEP_ALARM, MCU_RESET_REASON_DEEP_SLEEP_ALARM); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESET_PIN, MCU_RESET_REASON_RESET_PIN); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, WATCHDOG, MCU_RESET_REASON_WATCHDOG); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, UNKNOWN, MCU_RESET_REASON_UNKNOWN); +MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESCUE_DEBUG, MCU_RESET_REASON_RESCUE_DEBUG); //| class ResetReason: //| """The reason the microcontroller was last reset""" @@ -45,6 +45,7 @@ MAKE_ENUM_VALUE(mcu_reset_reason_type, reset_reason, RESCUE_DEBUG, RESET_REASON_ //| RESCUE_DEBUG: object //| """The microcontroller was reset by the rescue debug port.""" //| +//| MAKE_ENUM_MAP(mcu_reset_reason) { MAKE_ENUM_MAP_ENTRY(reset_reason, POWER_ON), MAKE_ENUM_MAP_ENTRY(reset_reason, BROWNOUT), diff --git a/shared-bindings/microcontroller/ResetReason.h b/shared-bindings/microcontroller/ResetReason.h index 61ff80639a6..772d7ff4ba4 100644 --- a/shared-bindings/microcontroller/ResetReason.h +++ b/shared-bindings/microcontroller/ResetReason.h @@ -10,14 +10,14 @@ #include "py/enum.h" typedef enum { - RESET_REASON_POWER_ON, - RESET_REASON_BROWNOUT, - RESET_REASON_SOFTWARE, - RESET_REASON_DEEP_SLEEP_ALARM, - RESET_REASON_RESET_PIN, - RESET_REASON_WATCHDOG, - RESET_REASON_UNKNOWN, - RESET_REASON_RESCUE_DEBUG, + MCU_RESET_REASON_POWER_ON, + MCU_RESET_REASON_BROWNOUT, + MCU_RESET_REASON_SOFTWARE, + MCU_RESET_REASON_DEEP_SLEEP_ALARM, + MCU_RESET_REASON_RESET_PIN, + MCU_RESET_REASON_WATCHDOG, + MCU_RESET_REASON_UNKNOWN, + MCU_RESET_REASON_RESCUE_DEBUG, } mcu_reset_reason_t; extern const mp_obj_type_t mcu_reset_reason_type; diff --git a/shared-bindings/microcontroller/RunMode.c b/shared-bindings/microcontroller/RunMode.c index 95979e5533c..ac5ffd62136 100644 --- a/shared-bindings/microcontroller/RunMode.c +++ b/shared-bindings/microcontroller/RunMode.c @@ -12,6 +12,7 @@ //| def __init__(self) -> None: //| """Enum-like class to define the run mode of the microcontroller and //| CircuitPython.""" +//| //| NORMAL: RunMode //| """Run CircuitPython as normal. //| @@ -33,6 +34,7 @@ //| //| :type microcontroller.RunMode:""" //| +//| const mp_obj_type_t mcu_runmode_type; const mcu_runmode_obj_t mcu_runmode_uf2_obj = { diff --git a/shared-bindings/microcontroller/__init__.c b/shared-bindings/microcontroller/__init__.c index eb2fc79ec33..55e36356a53 100644 --- a/shared-bindings/microcontroller/__init__.c +++ b/shared-bindings/microcontroller/__init__.c @@ -39,6 +39,7 @@ //| (clock frequency) on chips with more than 1 cpu. The index selects which cpu. //| This object is an instance of `microcontroller.Processor`.""" //| +//| //| def delay_us(delay: int) -> None: //| """Dedicated delay method used for very short delays. **Do not** do long delays @@ -49,6 +50,7 @@ //| `time.sleep()`.""" //| ... //| +//| static mp_obj_t mcu_delay_us(mp_obj_t delay_obj) { uint32_t delay = mp_obj_get_int(delay_obj); @@ -62,6 +64,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(mcu_delay_us_obj, mcu_delay_us); //| """Disable all interrupts. Be very careful, this can stall everything.""" //| ... //| +//| static mp_obj_t mcu_disable_interrupts(void) { common_hal_mcu_disable_interrupts(); return mp_const_none; @@ -72,6 +75,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(mcu_disable_interrupts_obj, mcu_disable_interru //| """Enable the interrupts that were enabled at the last disable.""" //| ... //| +//| static mp_obj_t mcu_enable_interrupts(void) { common_hal_mcu_enable_interrupts(); return mp_const_none; @@ -85,6 +89,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(mcu_enable_interrupts_obj, mcu_enable_interrupt //| :param ~microcontroller.RunMode run_mode: The next run mode""" //| ... //| +//| static mp_obj_t mcu_on_next_reset(mp_obj_t run_mode_obj) { mcu_runmode_t run_mode; if (run_mode_obj == MP_OBJ_FROM_PTR(&mcu_runmode_uf2_obj)) { @@ -112,6 +117,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(mcu_on_next_reset_obj, mcu_on_next_reset); //| "Safely removed" on Windows or "ejected" on Mac OSX and Linux.""" //| ... //| +//| static mp_obj_t mcu_reset(void) { common_hal_mcu_reset(); // We won't actually get here because we're resetting. diff --git a/shared-bindings/microcontroller/__init__.h b/shared-bindings/microcontroller/__init__.h index a94cca7b697..5c5902ff965 100644 --- a/shared-bindings/microcontroller/__init__.h +++ b/shared-bindings/microcontroller/__init__.h @@ -20,7 +20,7 @@ extern void common_hal_mcu_disable_interrupts(void); extern void common_hal_mcu_enable_interrupts(void); extern void common_hal_mcu_on_next_reset(mcu_runmode_t runmode); -extern void common_hal_mcu_reset(void); +MP_NORETURN extern void common_hal_mcu_reset(void); extern const mp_obj_dict_t mcu_pin_globals; diff --git a/shared-bindings/mipidsi/Bus.c b/shared-bindings/mipidsi/Bus.c new file mode 100644 index 00000000000..bac3cd3c75e --- /dev/null +++ b/shared-bindings/mipidsi/Bus.c @@ -0,0 +1,84 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-bindings/mipidsi/Bus.h" +#include "shared-bindings/util.h" +#include "shared/runtime/context_manager_helpers.h" + +//| class Bus: +//| def __init__( +//| self, +//| *, +//| frequency: int = 500_000_000, +//| num_lanes: int = 2, +//| ) -> None: +//| """Create a MIPI DSI Bus object. +//| +//| This creates a DSI bus interface. The specific pins used are determined by the board. +//| DSI supports 1-4 data lanes. +//| +//| :param int frequency: the high speed clock frequency in Hz (default 500 MHz) +//| :param int num_lanes: the number of data lanes to use (default 2, range 1-4) +//| """ +//| +// +// +// All MCUs we support only have one DSI bus but it can be shared between multiple displays. One +// display may live longer than the VM, so we need to allocate the bus outside the VM. To simplify +// memory tracking, we use a global object for the bus. +// +static mipidsi_bus_obj_t _mipidsi_bus_obj; + +static mp_obj_t mipidsi_bus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_frequency, ARG_num_lanes }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 500000000} }, + { MP_QSTR_num_lanes, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 2} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + _mipidsi_bus_obj.base.type = &mipidsi_bus_type; + mipidsi_bus_obj_t *self = &_mipidsi_bus_obj; + + mp_uint_t frequency = (mp_uint_t)mp_arg_validate_int_min(args[ARG_frequency].u_int, 1, MP_QSTR_frequency); + uint8_t num_lanes = (uint8_t)mp_arg_validate_int_range(args[ARG_num_lanes].u_int, 1, 4, MP_QSTR_num_lanes); + + common_hal_mipidsi_bus_construct(self, frequency, num_lanes); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Free the resources (pins, timers, etc.) associated with this +//| `mipidsi.Bus` instance. After deinitialization, no further operations +//| may be performed.""" +//| ... +//| +static mp_obj_t mipidsi_bus_deinit(mp_obj_t self_in) { + mipidsi_bus_obj_t *self = (mipidsi_bus_obj_t *)self_in; + common_hal_mipidsi_bus_deinit(self); + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_bus_deinit_obj, mipidsi_bus_deinit); + +static const mp_rom_map_elem_t mipidsi_bus_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mipidsi_bus_deinit_obj) }, +}; +static MP_DEFINE_CONST_DICT(mipidsi_bus_locals_dict, mipidsi_bus_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + mipidsi_bus_type, + MP_QSTR_Bus, + MP_TYPE_FLAG_NONE, + make_new, mipidsi_bus_make_new, + locals_dict, &mipidsi_bus_locals_dict + ); diff --git a/shared-bindings/mipidsi/Bus.h b/shared-bindings/mipidsi/Bus.h new file mode 100644 index 00000000000..f2fd13f7fc1 --- /dev/null +++ b/shared-bindings/mipidsi/Bus.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/mipidsi/Bus.h" + +extern const mp_obj_type_t mipidsi_bus_type; + +void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequency, uint8_t num_lanes); +void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self); +bool common_hal_mipidsi_bus_deinited(mipidsi_bus_obj_t *self); diff --git a/shared-bindings/mipidsi/Display.c b/shared-bindings/mipidsi/Display.c new file mode 100644 index 00000000000..149d31e52a9 --- /dev/null +++ b/shared-bindings/mipidsi/Display.c @@ -0,0 +1,300 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/objtype.h" + +#include "shared-bindings/mipidsi/Display.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" +#include "shared-module/framebufferio/FramebufferDisplay.h" + +//| class Display: +//| def __init__( +//| self, +//| bus: Bus, +//| init_sequence: ReadableBuffer, +//| *, +//| width: int, +//| height: int, +//| hsync_pulse_width: int, +//| hsync_back_porch: int, +//| hsync_front_porch: int, +//| vsync_pulse_width: int, +//| vsync_back_porch: int, +//| vsync_front_porch: int, +//| pixel_clock_frequency: int, +//| virtual_channel: int = 0, +//| rotation: int = 0, +//| color_depth: int = 16, +//| backlight_pin: Optional[microcontroller.Pin] = None, +//| brightness: float = 1.0, +//| native_frames_per_second: int = 60, +//| backlight_on_high: bool = True, +//| ) -> None: +//| """Create a MIPI DSI Display object connected to the given bus. +//| +//| This allocates a framebuffer and configures the DSI display to use the +//| specified virtual channel for communication. +//| +//| The framebuffer pixel format varies depending on color_depth: +//| +//| * 16 - Each two bytes is a pixel in RGB565 format. +//| * 24 - Each three bytes is a pixel in RGB888 format. +//| +//| A Display is often used in conjunction with a +//| `framebufferio.FramebufferDisplay`. +//| +//| :param Bus bus: the DSI bus to use +//| :param ~circuitpython_typing.ReadableBuffer init_sequence: Byte-packed initialization sequence for the display +//| :param int width: the width of the framebuffer in pixels +//| :param int height: the height of the framebuffer in pixels +//| :param int hsync_pulse_width: horizontal sync pulse width in pixel clocks +//| :param int hsync_back_porch: horizontal back porch in pixel clocks +//| :param int hsync_front_porch: horizontal front porch in pixel clocks +//| :param int vsync_pulse_width: vertical sync pulse width in lines +//| :param int vsync_back_porch: vertical back porch in lines +//| :param int vsync_front_porch: vertical front porch in lines +//| :param int pixel_clock_frequency: pixel clock frequency in Hz +//| :param int virtual_channel: the DSI virtual channel (0-3) +//| :param int rotation: the rotation of the display in degrees clockwise (0, 90, 180, 270) +//| :param int color_depth: the color depth of the framebuffer in bits (16 or 24) +//| :param microcontroller.Pin backlight_pin: Pin connected to the display's backlight +//| :param float brightness: Initial display brightness (0.0 to 1.0) +//| :param int native_frames_per_second: Number of display refreshes per second +//| :param bool backlight_on_high: If True, pulling the backlight pin high turns the backlight on +//| """ +//| + +static mp_obj_t mipidsi_display_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_hsync_pulse_width, ARG_hsync_back_porch, + ARG_hsync_front_porch, ARG_vsync_pulse_width, ARG_vsync_back_porch, ARG_vsync_front_porch, + ARG_pixel_clock_frequency, ARG_virtual_channel, ARG_rotation, + ARG_color_depth, ARG_backlight_pin, ARG_brightness, ARG_native_frames_per_second, + ARG_backlight_on_high }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_bus, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_init_sequence, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_width, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_height, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_hsync_pulse_width, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_hsync_back_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_hsync_front_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_vsync_pulse_width, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_vsync_back_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_vsync_front_porch, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_pixel_clock_frequency, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_virtual_channel, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_rotation, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_color_depth, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 16} }, + { MP_QSTR_backlight_pin, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} }, + { MP_QSTR_brightness, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_OBJ_NEW_SMALL_INT(1)} }, + { MP_QSTR_native_frames_per_second, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 60} }, + { MP_QSTR_backlight_on_high, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = true} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mipidsi_display_obj_t *self = &allocate_display_bus_or_raise()->mipidsi; + self->base.type = &mipidsi_display_type; + + mipidsi_bus_obj_t *bus = mp_arg_validate_type(args[ARG_bus].u_obj, &mipidsi_bus_type, MP_QSTR_bus); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); + + const mcu_pin_obj_t *backlight_pin = + validate_obj_is_free_pin_or_none(args[ARG_backlight_pin].u_obj, MP_QSTR_backlight_pin); + + mp_float_t brightness = mp_obj_get_float(args[ARG_brightness].u_obj); + + mp_int_t rotation = args[ARG_rotation].u_int; + if (rotation % 90 != 0) { + mp_raise_ValueError(MP_ERROR_TEXT("Display rotation must be in 90 degree increments")); + } + + mp_uint_t virtual_channel = (mp_uint_t)mp_arg_validate_int_range(args[ARG_virtual_channel].u_int, 0, 3, MP_QSTR_virtual_channel); + mp_uint_t width = (mp_uint_t)mp_arg_validate_int_min(args[ARG_width].u_int, 0, MP_QSTR_width); + mp_uint_t height = (mp_uint_t)mp_arg_validate_int_min(args[ARG_height].u_int, 0, MP_QSTR_height); + mp_uint_t color_depth = args[ARG_color_depth].u_int; + + if (color_depth != 16 && color_depth != 24) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth); + } + + common_hal_mipidsi_display_construct(self, bus, bufinfo.buf, bufinfo.len, virtual_channel, width, height, + rotation, color_depth, MP_OBJ_TO_PTR(backlight_pin), brightness, + args[ARG_native_frames_per_second].u_int, + args[ARG_backlight_on_high].u_bool, + args[ARG_hsync_pulse_width].u_int, + args[ARG_hsync_back_porch].u_int, + args[ARG_hsync_front_porch].u_int, + args[ARG_vsync_pulse_width].u_int, + args[ARG_vsync_back_porch].u_int, + args[ARG_vsync_front_porch].u_int, + args[ARG_pixel_clock_frequency].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +// Helper to ensure we have the native super class instead of a subclass. +static mipidsi_display_obj_t *native_display(mp_obj_t display_obj) { + mp_obj_t native_display = mp_obj_cast_to_native_base(display_obj, &mipidsi_display_type); + mp_obj_assert_native_inited(native_display); + return MP_OBJ_TO_PTR(native_display); +} + +//| def deinit(self) -> None: +//| """Free the resources (pins, timers, etc.) associated with this +//| `mipidsi.Display` instance. After deinitialization, no further operations +//| may be performed.""" +//| ... +//| +static mp_obj_t mipidsi_display_deinit(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + common_hal_mipidsi_display_deinit(self); + return mp_const_none; +} + +static MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_deinit_obj, mipidsi_display_deinit); + +static void check_for_deinit(mipidsi_display_obj_t *self) { + if (common_hal_mipidsi_display_deinited(self)) { + raise_deinited_error(); + } +} + +//| width: int +//| """The width of the framebuffer, in pixels.""" +static mp_obj_t mipidsi_display_get_width(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_mipidsi_display_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_get_width_obj, mipidsi_display_get_width); +MP_PROPERTY_GETTER(mipidsi_display_width_obj, + (mp_obj_t)&mipidsi_display_get_width_obj); + +//| height: int +//| """The height of the framebuffer, in pixels.""" +//| +//| +static mp_obj_t mipidsi_display_get_height(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_mipidsi_display_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_get_height_obj, mipidsi_display_get_height); + +MP_PROPERTY_GETTER(mipidsi_display_height_obj, + (mp_obj_t)&mipidsi_display_get_height_obj); + +//| color_depth: int +//| """The color depth of the framebuffer.""" +static mp_obj_t mipidsi_display_get_color_depth(mp_obj_t self_in) { + mipidsi_display_obj_t *self = native_display(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_mipidsi_display_get_color_depth(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_display_get_color_depth_obj, mipidsi_display_get_color_depth); +MP_PROPERTY_GETTER(mipidsi_display_color_depth_obj, + (mp_obj_t)&mipidsi_display_get_color_depth_obj); + + +static const mp_rom_map_elem_t mipidsi_display_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mipidsi_display_deinit_obj) }, + + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&mipidsi_display_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&mipidsi_display_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_color_depth), MP_ROM_PTR(&mipidsi_display_color_depth_obj) }, +}; +static MP_DEFINE_CONST_DICT(mipidsi_display_locals_dict, mipidsi_display_locals_dict_table); + +static void mipidsi_display_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) { + common_hal_mipidsi_display_get_buffer(self_in, bufinfo, 0); +} + +static float mipidsi_display_get_brightness_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_brightness(self_in); +} + +static bool mipidsi_display_set_brightness_proto(mp_obj_t self_in, mp_float_t value) { + common_hal_mipidsi_display_set_brightness(self_in, value); + return true; +} + +// These versions exist so that the prototype matches the protocol, +// avoiding a type cast that can hide errors +static void mipidsi_display_swapbuffers(mp_obj_t self_in, uint8_t *dirty_row_bitmap) { + (void)dirty_row_bitmap; + common_hal_mipidsi_display_refresh(self_in); +} + +static void mipidsi_display_deinit_proto(mp_obj_t self_in) { + common_hal_mipidsi_display_deinit(self_in); +} + +static int mipidsi_display_get_width_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_width(self_in); +} + +static int mipidsi_display_get_height_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_height(self_in); +} + +static int mipidsi_display_get_color_depth_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_color_depth(self_in); +} + +static bool mipidsi_display_get_grayscale_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_grayscale(self_in); +} + +static int mipidsi_display_get_bytes_per_cell_proto(mp_obj_t self_in) { + return 1; +} + +static int mipidsi_display_get_native_frames_per_second_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_native_frames_per_second(self_in); +} + +static bool mipidsi_display_get_pixels_in_byte_share_row_proto(mp_obj_t self_in) { + return true; +} + +static int mipidsi_display_get_row_stride_proto(mp_obj_t self_in) { + return common_hal_mipidsi_display_get_row_stride(self_in); +} + +static const framebuffer_p_t mipidsi_display_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuffer) + .get_bufinfo = mipidsi_display_get_bufinfo, + .set_brightness = mipidsi_display_set_brightness_proto, + .get_brightness = mipidsi_display_get_brightness_proto, + .get_width = mipidsi_display_get_width_proto, + .get_height = mipidsi_display_get_height_proto, + .get_color_depth = mipidsi_display_get_color_depth_proto, + .get_grayscale = mipidsi_display_get_grayscale_proto, + .get_row_stride = mipidsi_display_get_row_stride_proto, + .get_bytes_per_cell = mipidsi_display_get_bytes_per_cell_proto, + .get_native_frames_per_second = mipidsi_display_get_native_frames_per_second_proto, + .get_pixels_in_byte_share_row = mipidsi_display_get_pixels_in_byte_share_row_proto, + .swapbuffers = mipidsi_display_swapbuffers, + .deinit = mipidsi_display_deinit_proto, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + mipidsi_display_type, + MP_QSTR_Display, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + locals_dict, &mipidsi_display_locals_dict, + make_new, mipidsi_display_make_new, + buffer, common_hal_mipidsi_display_get_buffer, + protocol, &mipidsi_display_proto + ); diff --git a/shared-bindings/mipidsi/Display.h b/shared-bindings/mipidsi/Display.h new file mode 100644 index 00000000000..09cf130bf4a --- /dev/null +++ b/shared-bindings/mipidsi/Display.h @@ -0,0 +1,46 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "common-hal/mipidsi/Display.h" +#include "shared-bindings/mipidsi/Bus.h" +#include "common-hal/microcontroller/Pin.h" + +extern const mp_obj_type_t mipidsi_display_type; + +void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self, + mipidsi_bus_obj_t *bus, + const uint8_t *init_sequence, + size_t init_sequence_len, + mp_uint_t virtual_channel, + mp_uint_t width, + mp_uint_t height, + mp_int_t rotation, + mp_uint_t color_depth, + const mcu_pin_obj_t *backlight_pin, + mp_float_t brightness, + mp_uint_t native_frames_per_second, + bool backlight_on_high, + mp_uint_t hsync_pulse_width, + mp_uint_t hsync_back_porch, + mp_uint_t hsync_front_porch, + mp_uint_t vsync_pulse_width, + mp_uint_t vsync_back_porch, + mp_uint_t vsync_front_porch, + mp_uint_t pixel_clock_frequency); +void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self); +bool common_hal_mipidsi_display_deinited(mipidsi_display_obj_t *self); +void common_hal_mipidsi_display_refresh(mipidsi_display_obj_t *self); +mp_float_t common_hal_mipidsi_display_get_brightness(mipidsi_display_obj_t *self); +bool common_hal_mipidsi_display_set_brightness(mipidsi_display_obj_t *self, mp_float_t brightness); +int common_hal_mipidsi_display_get_width(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_height(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_row_stride(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_color_depth(mipidsi_display_obj_t *self); +int common_hal_mipidsi_display_get_native_frames_per_second(mipidsi_display_obj_t *self); +bool common_hal_mipidsi_display_get_grayscale(mipidsi_display_obj_t *self); +mp_int_t common_hal_mipidsi_display_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags); diff --git a/shared-bindings/mipidsi/__init__.c b/shared-bindings/mipidsi/__init__.c new file mode 100644 index 00000000000..0b6b8565929 --- /dev/null +++ b/shared-bindings/mipidsi/__init__.c @@ -0,0 +1,30 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/mipidsi/Bus.h" +#include "shared-bindings/mipidsi/Display.h" + +//| """Low-level routines for interacting with MIPI DSI""" + +static const mp_rom_map_elem_t mipidsi_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_mipidsi) }, + { MP_ROM_QSTR(MP_QSTR_Bus), MP_ROM_PTR(&mipidsi_bus_type) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&mipidsi_display_type) }, +}; + +static MP_DEFINE_CONST_DICT(mipidsi_module_globals, mipidsi_module_globals_table); + +const mp_obj_module_t mipidsi_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&mipidsi_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_mipidsi, mipidsi_module); diff --git a/shared-bindings/mipidsi/__init__.h b/shared-bindings/mipidsi/__init__.h new file mode 100644 index 00000000000..972a7c082fd --- /dev/null +++ b/shared-bindings/mipidsi/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-bindings/msgpack/ExtType.c b/shared-bindings/msgpack/ExtType.c index 7cee4b9b0d3..c69416f9773 100644 --- a/shared-bindings/msgpack/ExtType.c +++ b/shared-bindings/msgpack/ExtType.c @@ -16,8 +16,8 @@ //| """Constructor //| :param int code: type code in range 0~127. //| :param bytes data: representation.""" +//| static mp_obj_t mod_msgpack_exttype_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - mod_msgpack_extype_obj_t *self = mp_obj_malloc(mod_msgpack_extype_obj_t, &mod_msgpack_exttype_type); enum { ARG_code, ARG_data }; static const mp_arg_t allowed_args[] = { { MP_QSTR_code, MP_ARG_INT | MP_ARG_REQUIRED }, @@ -27,11 +27,12 @@ static mp_obj_t mod_msgpack_exttype_make_new(const mp_obj_type_t *type, size_t n mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); int code = mp_arg_validate_int_range(args[ARG_code].u_int, 0, 127, MP_QSTR_code); + mp_obj_t data = args[ARG_data].u_obj; + mod_msgpack_extype_obj_t *self = mp_obj_malloc(mod_msgpack_extype_obj_t, &mod_msgpack_exttype_type); self->code = code; - - mp_obj_t data = args[ARG_data].u_obj; self->data = data; + return MP_OBJ_FROM_PTR(self); } @@ -64,6 +65,7 @@ MP_PROPERTY_GETSET(mod_msgpack_exttype_code_obj, //| """Data.""" //| ... //| +//| static mp_obj_t mod_msgpack_exttype_get_data(mp_obj_t self_in) { mod_msgpack_extype_obj_t *self = MP_OBJ_TO_PTR(self_in); return self->data; diff --git a/shared-bindings/msgpack/__init__.c b/shared-bindings/msgpack/__init__.c index eaa1cfb98ba..a3e31f23ca6 100644 --- a/shared-bindings/msgpack/__init__.c +++ b/shared-bindings/msgpack/__init__.c @@ -65,12 +65,13 @@ //| //| """ //| +//| //| def pack( //| obj: object, //| stream: circuitpython_typing.ByteStream, //| *, -//| default: Union[Callable[[object], None], None] = None +//| default: Union[Callable[[object], None], None] = None, //| ) -> None: //| """Output object to stream in msgpack format. //| @@ -82,6 +83,7 @@ //| """ //| ... //| +//| static mp_obj_t mod_msgpack_pack(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_obj, ARG_buffer, ARG_default }; static const mp_arg_t allowed_args[] = { @@ -107,7 +109,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mod_msgpack_pack_obj, 0, mod_msgpack_pack); //| stream: circuitpython_typing.ByteStream, //| *, //| ext_hook: Union[Callable[[int, bytes], object], None] = None, -//| use_list: bool = True +//| use_list: bool = True, //| ) -> object: //| """Unpack and return one object from stream. //| @@ -120,6 +122,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(mod_msgpack_pack_obj, 0, mod_msgpack_pack); //| """ //| ... //| +//| static mp_obj_t mod_msgpack_unpack(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_buffer, ARG_ext_hook, ARG_use_list }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c index 9f221ddd5ac..3768b70c772 100644 --- a/shared-bindings/neopixel_write/__init__.c +++ b/shared-bindings/neopixel_write/__init__.c @@ -84,6 +84,7 @@ static void check_for_deinit(digitalio_digitalinout_obj_t *self) { //| //| """ //| +//| //| def neopixel_write(digitalinout: digitalio.DigitalInOut, buf: ReadableBuffer) -> None: //| """Write buf out on the given DigitalInOut. //| @@ -92,6 +93,7 @@ static void check_for_deinit(digitalio_digitalinout_obj_t *self) { //| """ //| ... //| +//| static mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) { const digitalio_digitalinout_obj_t *digitalinout = mp_arg_validate_type(digitalinout_obj, &digitalio_digitalinout_type, MP_QSTR_digitalinout); @@ -108,8 +110,8 @@ static mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj static MP_DEFINE_CONST_FUN_OBJ_2(neopixel_write_neopixel_write_obj, neopixel_write_neopixel_write_); static const mp_rom_map_elem_t neopixel_write_module_globals_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write), (mp_obj_t)&neopixel_write_neopixel_write_obj }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write) }, + { MP_ROM_QSTR(MP_QSTR_neopixel_write), (mp_obj_t)&neopixel_write_neopixel_write_obj }, }; static MP_DEFINE_CONST_DICT(neopixel_write_module_globals, neopixel_write_module_globals_table); diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c index 7549023247e..b2783006267 100644 --- a/shared-bindings/nvm/ByteArray.c +++ b/shared-bindings/nvm/ByteArray.c @@ -26,14 +26,16 @@ //| def __init__(self) -> None: //| """Not currently dynamically supported. Access the sole instance through `microcontroller.nvm`.""" //| ... +//| //| def __bool__(self) -> bool: ... //| def __len__(self) -> int: //| """Return the length. This is used by (`len`)""" //| ... +//| static mp_obj_t nvm_bytearray_unary_op(mp_unary_op_t op, mp_obj_t self_in) { nvm_bytearray_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint16_t len = common_hal_nvm_bytearray_get_length(self); + uint32_t len = common_hal_nvm_bytearray_get_length(self); switch (op) { case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); @@ -63,6 +65,7 @@ static MP_DEFINE_CONST_DICT(nvm_bytearray_locals_dict, nvm_bytearray_locals_dict //| """Set the value at the given index.""" //| ... //| +//| static mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item diff --git a/shared-bindings/onewireio/OneWire.c b/shared-bindings/onewireio/OneWire.c index d2cb379ab4f..2f69424cc23 100644 --- a/shared-bindings/onewireio/OneWire.c +++ b/shared-bindings/onewireio/OneWire.c @@ -32,6 +32,7 @@ //| onewire.write_bit(False) //| print(onewire.read_bit())""" //| ... +//| static mp_obj_t onewireio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin }; static const mp_arg_t allowed_args[] = { @@ -42,14 +43,15 @@ static mp_obj_t onewireio_onewire_make_new(const mp_obj_type_t *type, size_t n_a const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); onewireio_onewire_obj_t *self = mp_obj_malloc(onewireio_onewire_obj_t, &onewireio_onewire_type); - common_hal_onewireio_onewire_construct(self, pin); + return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: //| """Deinitialize the OneWire bus and release any hardware resources for reuse.""" //| ... +//| static mp_obj_t onewireio_onewire_deinit(mp_obj_t self_in) { onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_onewireio_onewire_deinit(self); @@ -66,18 +68,15 @@ static void check_for_deinit(onewireio_onewire_obj_t *self) { //| def __enter__(self) -> OneWire: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t onewireio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_onewireio_onewire_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(onewireio_onewire___exit___obj, 4, 4, onewireio_onewire_obj___exit__); +//| +// Provided by context manager helper. //| def reset(self) -> bool: //| """Reset the OneWire bus and read presence @@ -85,6 +84,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(onewireio_onewire___exit___obj, 4, 4, //| :returns: False when at least one device is present //| :rtype: bool""" //| ... +//| static mp_obj_t onewireio_onewire_obj_reset(mp_obj_t self_in) { onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -99,6 +99,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(onewireio_onewire_reset_obj, onewireio_onewire_obj_res //| :returns: bit state read //| :rtype: bool""" //| ... +//| static mp_obj_t onewireio_onewire_obj_read_bit(mp_obj_t self_in) { onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -111,6 +112,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(onewireio_onewire_read_bit_obj, onewireio_onewire_obj_ //| """Write out a bit based on value.""" //| ... //| +//| static mp_obj_t onewireio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { onewireio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -124,7 +126,7 @@ static const mp_rom_map_elem_t onewireio_onewire_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&onewireio_onewire_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&onewireio_onewire___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&onewireio_onewire_reset_obj) }, { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&onewireio_onewire_read_bit_obj) }, { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&onewireio_onewire_write_bit_obj) }, diff --git a/shared-bindings/onewireio/__init__.c b/shared-bindings/onewireio/__init__.c index bce56326b1a..9af86ae8211 100644 --- a/shared-bindings/onewireio/__init__.c +++ b/shared-bindings/onewireio/__init__.c @@ -17,7 +17,7 @@ //| """Low-level bit primitives for Maxim (formerly Dallas Semi) one-wire protocol. //| -//| Protocol definition is here: https://www.analog.com/en/technical-articles/1wire-communication-through-software.html""" +//| Protocol definition is here: https://www.analog.com/en/technical-articles/1wire-communication-through-software.html""" static const mp_rom_map_elem_t onewireio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_onewireio) }, diff --git a/shared-bindings/os/__init__.c b/shared-bindings/os/__init__.c index 37dea429075..bbf5a5025c1 100644 --- a/shared-bindings/os/__init__.c +++ b/shared-bindings/os/__init__.c @@ -26,12 +26,14 @@ //| //| import typing //| +//| //| def uname() -> _Uname: //| """Returns a named tuple of operating specific and CircuitPython port //| specific information.""" //| ... //| +//| //| class _Uname(typing.NamedTuple): //| """The type of values that :py:func:`.uname()` returns""" //| @@ -41,8 +43,31 @@ //| version: str //| machine: str //| +//| +static const qstr os_uname_info_fields[] = { + MP_QSTR_sysname, MP_QSTR_nodename, + MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine +}; +static const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_HW_MCU_NAME); +static const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_HW_MCU_NAME); +static const MP_DEFINE_STR_OBJ(os_uname_info_release_obj, MICROPY_VERSION_STRING); +static const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE); +static const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME); + + +static MP_DEFINE_ATTRTUPLE( + os_uname_info_obj, + os_uname_info_fields, + 5, + (mp_obj_t)&os_uname_info_sysname_obj, + (mp_obj_t)&os_uname_info_nodename_obj, + (mp_obj_t)&os_uname_info_release_obj, + (mp_obj_t)&os_uname_info_version_obj, + (mp_obj_t)&os_uname_info_machine_obj + ); + static mp_obj_t os_uname(void) { - return common_hal_os_uname(); + return MP_OBJ_FROM_PTR(&os_uname_info_obj); } static MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname); @@ -50,6 +75,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(os_uname_obj, os_uname); //| """Change current directory.""" //| ... //| +//| static mp_obj_t os_chdir(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); common_hal_os_chdir(path); @@ -61,17 +87,27 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_chdir_obj, os_chdir); //| """Get the current directory.""" //| ... //| +//| static mp_obj_t os_getcwd(void) { return common_hal_os_getcwd(); } MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd); //| def getenv(key: str, default: Optional[str] = None) -> Optional[str]: -//| """Get the environment variable value for the given key or return ``default``. +//| """Get the environment variable value for the given ``key`` from the +//| ``/settings.toml`` file. +//| If ``key`` is not present or the value is ill-formed, return the ``default`` value. +//| The value is returned as a string even if it can be parsed as an integer or boolean. +//| No errors are raised if the value is not a valid TOML value; instead the original +//| string is returned, or ``default`` if no value can be retrieved at all. //| -//| This may load values from disk so cache the result instead of calling this often. +//| If you want to retrieve the value as a ``str``, ``bool``, or ``int``, use `supervisor.get_setting()`. //| -//| On boards that do not support ``settings.toml`` reading in the core, this function will raise NotImplementedError. +//| The ``settings.toml`` file is re-scanned on every call, +//| so cache the result instead of calling `getenv()` frequently. +//| +//| On boards that do not support ``settings.toml`` reading in the core, +//| this function will raise NotImplementedError. //| //| .. raw:: html //| @@ -89,8 +125,9 @@ MP_DEFINE_CONST_FUN_OBJ_0(os_getcwd_obj, os_getcwd); //| """ //| ... //| +//| static mp_obj_t os_getenv(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_SETTINGS_TOML enum { ARG_key, ARG_default }; static const mp_arg_t allowed_args[] = { { MP_QSTR_key, MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -110,6 +147,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(os_getenv_obj, 1, os_getenv); //| """With no argument, list the current directory. Otherwise list the given directory.""" //| ... //| +//| static mp_obj_t os_listdir(size_t n_args, const mp_obj_t *args) { const char *path; if (n_args == 1) { @@ -125,6 +163,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(os_listdir_obj, 0, 1, os_listdir); //| """Create a new directory.""" //| ... //| +//| static mp_obj_t os_mkdir(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); common_hal_os_mkdir(path); @@ -136,6 +175,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_mkdir_obj, os_mkdir); //| """Remove a file.""" //| ... //| +//| static mp_obj_t os_remove(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); common_hal_os_remove(path); @@ -147,6 +187,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_remove_obj, os_remove); //| """Remove a directory.""" //| ... //| +//| static mp_obj_t os_rename(mp_obj_t old_path_in, mp_obj_t new_path_in) { const char *old_path = mp_obj_str_get_str(old_path_in); const char *new_path = mp_obj_str_get_str(new_path_in); @@ -159,6 +200,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(os_rename_obj, os_rename); //| """Rename a file.""" //| ... //| +//| static mp_obj_t os_rmdir(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); common_hal_os_rmdir(path); @@ -189,6 +231,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_rmdir_obj, os_rmdir); //| which is the number of seconds corresponding to 1999-12-31.""" //| ... //| +//| static mp_obj_t os_stat(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); return common_hal_os_stat(path); @@ -216,6 +259,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_stat_obj, os_stat); //| in a port-specific implementation.""" //| ... //| +//| static mp_obj_t os_statvfs(mp_obj_t path_in) { const char *path = mp_obj_str_get_str(path_in); return common_hal_os_statvfs(path); @@ -226,6 +270,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_statvfs_obj, os_statvfs); //| """Sync all filesystems.""" //| ... //| +//| static mp_obj_t os_sync(void) { for (mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) { // this assumes that vfs->obj is fs_user_mount_t with block device functions @@ -243,6 +288,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(os_sync_obj, os_sync); //| """ //| ... //| +//| static mp_obj_t os_urandom(mp_obj_t size_in) { mp_int_t size = mp_obj_get_int(size_in); mp_obj_str_t *result = MP_OBJ_TO_PTR(mp_obj_new_bytes_of_zeros(size)); @@ -257,6 +303,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(os_urandom_obj, os_urandom); //| """Change the timestamp of a file.""" //| ... //| +//| static mp_obj_t os_utime(mp_obj_t path_in, mp_obj_t times_in) { const char *path = mp_obj_str_get_str(path_in); common_hal_os_utime(path, times_in); diff --git a/shared-bindings/os/__init__.h b/shared-bindings/os/__init__.h index f273708cf4e..3729f43d5b6 100644 --- a/shared-bindings/os/__init__.h +++ b/shared-bindings/os/__init__.h @@ -10,10 +10,8 @@ #include #include "py/objtuple.h" +#include "shared-module/os/__init__.h" -extern const mp_rom_obj_tuple_t common_hal_os_uname_info_obj; - -mp_obj_t common_hal_os_uname(void); void common_hal_os_chdir(const char *path); mp_obj_t common_hal_os_getcwd(void); mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_); diff --git a/shared-bindings/paralleldisplaybus/ParallelBus.c b/shared-bindings/paralleldisplaybus/ParallelBus.c index 0a674920a0c..7f8749501fb 100644 --- a/shared-bindings/paralleldisplaybus/ParallelBus.c +++ b/shared-bindings/paralleldisplaybus/ParallelBus.c @@ -18,7 +18,11 @@ //| class ParallelBus: //| """Manage updating a display over 8-bit parallel bus in the background while Python code runs. This //| protocol may be referred to as 8080-I Series Parallel Interface in datasheets. It doesn't handle -//| display initialization.""" +//| display initialization. +//| +//| .. seealso:: See `busdisplay.BusDisplay` and `epaperdisplay.EPaperDisplay` +//| for how to initialize a display, given a `ParallelBus`. +//| """ //| //| def __init__( //| self, @@ -49,6 +53,7 @@ //| :param microcontroller.Pin reset: Reset pin, optional //| :param int frequency: The communication frequency in Hz for the display on the bus""" //| ... +//| static mp_obj_t paralleldisplaybus_parallelbus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_data0, ARG_data_pins, ARG_command, ARG_chip_select, ARG_write, ARG_read, ARG_reset, ARG_frequency }; static const mp_arg_t allowed_args[] = { @@ -80,14 +85,16 @@ static mp_obj_t paralleldisplaybus_parallelbus_make_new(const mp_obj_type_t *typ mp_raise_ValueError(MP_ERROR_TEXT("Specify exactly one of data0 or data_pins")); } + uint32_t frequency = (uint32_t)mp_arg_validate_int_min(args[ARG_frequency].u_int, 1, MP_QSTR_frequency); + if (specified_data0) { const mcu_pin_obj_t *data0 = validate_obj_is_free_pin(args[ARG_data0].u_obj, MP_QSTR_data0); - common_hal_paralleldisplaybus_parallelbus_construct(self, data0, command, chip_select, write, read, reset, args[ARG_frequency].u_int); + common_hal_paralleldisplaybus_parallelbus_construct(self, data0, command, chip_select, write, read, reset, frequency); } else { uint8_t num_pins; const mcu_pin_obj_t *data_pins[16]; validate_list_is_free_pins(MP_QSTR_data_pins, data_pins, (mp_int_t)MP_ARRAY_SIZE(data_pins), args[ARG_data_pins].u_obj, &num_pins); - common_hal_paralleldisplaybus_parallelbus_construct_nonsequential(self, num_pins, data_pins, command, chip_select, write, read, reset, args[ARG_frequency].u_int); + common_hal_paralleldisplaybus_parallelbus_construct_nonsequential(self, num_pins, data_pins, command, chip_select, write, read, reset, frequency); } return self; } @@ -96,6 +103,7 @@ static mp_obj_t paralleldisplaybus_parallelbus_make_new(const mp_obj_type_t *typ //| """Performs a hardware reset via the reset pin. Raises an exception if called when no reset pin //| is available.""" //| ... +//| static mp_obj_t paralleldisplaybus_parallelbus_obj_reset(mp_obj_t self_in) { paralleldisplaybus_parallelbus_obj_t *self = self_in; @@ -112,6 +120,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(paralleldisplaybus_parallelbus_reset_obj, paralleldisp //| vertical scroll, set via ``send`` may or may not be reset once the code is done.""" //| ... //| +//| static mp_obj_t paralleldisplaybus_parallelbus_obj_send(mp_obj_t self, mp_obj_t command_obj, mp_obj_t data_obj) { mp_int_t command_int = mp_arg_validate_int_range(mp_obj_get_int(command_obj), 0, 255, MP_QSTR_command); diff --git a/shared-bindings/paralleldisplaybus/__init__.c b/shared-bindings/paralleldisplaybus/__init__.c index 24d968c9e31..19a381570ba 100644 --- a/shared-bindings/paralleldisplaybus/__init__.c +++ b/shared-bindings/paralleldisplaybus/__init__.c @@ -29,6 +29,3 @@ const mp_obj_module_t paralleldisplaybus_module = { }; MP_REGISTER_MODULE(MP_QSTR_paralleldisplaybus, paralleldisplaybus_module); - -// Remove in CircuitPython 10 -MP_REGISTER_MODULE(MP_QSTR_paralleldisplay, paralleldisplaybus_module); diff --git a/shared-bindings/ps2io/Ps2.c b/shared-bindings/ps2io/Ps2.c index f92d5f0dd88..90e6b0b6045 100644 --- a/shared-bindings/ps2io/Ps2.c +++ b/shared-bindings/ps2io/Ps2.c @@ -44,6 +44,7 @@ //| print(kbd.sendcmd(0xed)) //| print(kbd.sendcmd(0x01))""" //| ... +//| static mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_data_pin, ARG_clock_pin }; static const mp_arg_t allowed_args[] = { @@ -57,7 +58,6 @@ static mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, siz const mcu_pin_obj_t *data_pin = validate_obj_is_free_pin(args[ARG_data_pin].u_obj, MP_QSTR_data_pin); ps2io_ps2_obj_t *self = mp_obj_malloc(ps2io_ps2_obj_t, &ps2io_ps2_type); - common_hal_ps2io_ps2_construct(self, data_pin, clock_pin); return MP_OBJ_FROM_PTR(self); @@ -66,6 +66,7 @@ static mp_obj_t ps2io_ps2_make_new(const mp_obj_type_t *type, size_t n_args, siz //| def deinit(self) -> None: //| """Deinitialises the Ps2 and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t ps2io_ps2_deinit(mp_obj_t self_in) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_ps2io_ps2_deinit(self); @@ -82,24 +83,21 @@ static void check_for_deinit(ps2io_ps2_obj_t *self) { //| def __enter__(self) -> Ps2: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t ps2io_ps2_obj___exit__(size_t n_args, const mp_obj_t *args) { - mp_check_self(mp_obj_is_type(args[0], &ps2io_ps2_type)); - ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(args[0]); - common_hal_ps2io_ps2_deinit(self); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ps2io_ps2___exit___obj, 4, 4, ps2io_ps2_obj___exit__); +//| +// Provided by context manager helper. //| def popleft(self) -> int: //| """Removes and returns the oldest received byte. When buffer //| is empty, raises an IndexError exception.""" //| ... +//| static mp_obj_t ps2io_ps2_obj_popleft(mp_obj_t self_in) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -124,6 +122,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_popleft_obj, ps2io_ps2_obj_popleft); //| //| :param int byte: byte value of the command""" //| ... +//| static mp_obj_t ps2io_ps2_obj_sendcmd(mp_obj_t self_in, mp_obj_t ob) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -165,6 +164,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(ps2io_ps2_sendcmd_obj, ps2io_ps2_obj_sendcmd); //| //| 0x2000: device didn't send a response byte in time""" //| ... +//| static mp_obj_t ps2io_ps2_obj_clear_errors(mp_obj_t self_in) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -179,6 +179,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(ps2io_ps2_clear_errors_obj, ps2io_ps2_obj_clear_errors //| to :py:func:`popleft()`.""" //| ... //| +//| static mp_obj_t ps2_unary_op(mp_unary_op_t op, mp_obj_t self_in) { ps2io_ps2_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -197,7 +198,7 @@ static const mp_rom_map_elem_t ps2io_ps2_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&ps2io_ps2_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&ps2io_ps2___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&ps2io_ps2_popleft_obj) }, { MP_ROM_QSTR(MP_QSTR_sendcmd), MP_ROM_PTR(&ps2io_ps2_sendcmd_obj) }, { MP_ROM_QSTR(MP_QSTR_clear_errors), MP_ROM_PTR(&ps2io_ps2_clear_errors_obj) }, diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index e44c2b273c7..830f7b7c62c 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -56,6 +56,7 @@ //| # Resume with an 80 microsecond active pulse //| pulses.resume(80)""" //| ... +//| static mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin, ARG_maxlen, ARG_idle_state }; static const mp_arg_t allowed_args[] = { @@ -68,7 +69,6 @@ static mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); pulseio_pulsein_obj_t *self = mp_obj_malloc_with_finaliser(pulseio_pulsein_obj_t, &pulseio_pulsein_type); - common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, args[ARG_idle_state].u_bool); @@ -78,6 +78,7 @@ static mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_arg //| def deinit(self) -> None: //| """Deinitialises the PulseIn and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t pulseio_pulsein_deinit(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_pulseio_pulsein_deinit(self); @@ -94,22 +95,20 @@ static void check_for_deinit(pulseio_pulsein_obj_t *self) { //| def __enter__(self) -> PulseIn: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t pulseio_pulsein_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_pulseio_pulsein_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, pulseio_pulsein_obj___exit__); +//| +// Provided by context manager helper. //| def pause(self) -> None: //| """Pause pulse capture""" //| ... +//| static mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -129,6 +128,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_pause_obj, pulseio_pulsein_obj_pause); //| //| :param int trigger_duration: trigger pulse duration in microseconds""" //| ... +//| static mp_obj_t pulseio_pulsein_obj_resume(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_trigger_duration }; static const mp_arg_t allowed_args[] = { @@ -148,6 +148,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(pulseio_pulsein_resume_obj, 1, pulseio_pulsein_obj_re //| def clear(self) -> None: //| """Clears all captured pulses""" //| ... +//| static mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -160,6 +161,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear); //| def popleft(self) -> int: //| """Removes and returns the oldest read pulse duration in microseconds.""" //| ... +//| static mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -185,6 +187,7 @@ MP_PROPERTY_GETTER(pulseio_pulsein_maxlen_obj, //| paused: bool //| """True when pulse capture is paused as a result of :py:func:`pause` or an error during capture //| such as a signal that is too fast.""" +//| static mp_obj_t pulseio_pulsein_obj_get_paused(mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -205,6 +208,7 @@ MP_PROPERTY_GETTER(pulseio_pulsein_paused_obj, //| pulses = pulseio.PulseIn(pin) //| print(len(pulses))""" //| ... +//| static mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) { pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -228,6 +232,7 @@ static mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| print(pulses[0])""" //| ... //| +//| static mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { if (value == mp_const_none) { // delete item @@ -256,7 +261,7 @@ static const mp_rom_map_elem_t pulseio_pulsein_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pulsein_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&pulseio_pulsein_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pulsein___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&pulseio_pulsein_pause_obj) }, { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&pulseio_pulsein_resume_obj) }, { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&pulseio_pulsein_clear_obj) }, diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c index 92775ff59fd..58c98b8e2cc 100644 --- a/shared-bindings/pulseio/PulseOut.c +++ b/shared-bindings/pulseio/PulseOut.c @@ -44,6 +44,7 @@ //| pulses[0] = 200 //| pulse.send(pulses)""" //| ... +//| static mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { #if CIRCUITPY_PULSEIO_PULSEOUT enum { ARG_pin, ARG_frequency, ARG_duty_cycle}; @@ -61,6 +62,7 @@ static mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar pulseio_pulseout_obj_t *self = mp_obj_malloc_with_finaliser(pulseio_pulseout_obj_t, &pulseio_pulseout_type); common_hal_pulseio_pulseout_construct(self, pin, frequency, duty_cycle); + return MP_OBJ_FROM_PTR(self); #else mp_raise_NotImplementedError(NULL); @@ -71,6 +73,7 @@ static mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_ar //| def deinit(self) -> None: //| """Deinitialises the PulseOut and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t pulseio_pulseout_deinit(mp_obj_t self_in) { pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_pulseio_pulseout_deinit(self); @@ -81,18 +84,15 @@ static MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulseout_deinit_obj, pulseio_pulseout_d //| def __enter__(self) -> PulseOut: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t pulseio_pulseout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_pulseio_pulseout_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4, pulseio_pulseout_obj___exit__); +//| +// Provided by context manager helper. //| def send(self, pulses: ReadableBuffer) -> None: //| """Pulse alternating on and off durations in microseconds starting with on. @@ -105,6 +105,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4, //| :param array.array pulses: pulse durations in microseconds""" //| ... //| +//| static mp_obj_t pulseio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) { pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_pulseio_pulseout_deinited(self)) { @@ -128,7 +129,7 @@ static const mp_rom_map_elem_t pulseio_pulseout_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pulseout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&pulseio_pulseout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pulseout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pulseio_pulseout_send_obj) }, #endif // CIRCUITPY_PULSEIO_PULSEOUT }; diff --git a/shared-bindings/pwmio/PWMOut.c b/shared-bindings/pwmio/PWMOut.c index 0504454bd4a..9619b4b9d6c 100644 --- a/shared-bindings/pwmio/PWMOut.c +++ b/shared-bindings/pwmio/PWMOut.c @@ -25,14 +25,8 @@ void common_hal_pwmio_pwmout_raise_error(pwmout_result_t result) { case PWMOUT_INVALID_FREQUENCY: mp_arg_error_invalid(MP_QSTR_frequency); break; - case PWMOUT_INVALID_FREQUENCY_ON_PIN: - mp_arg_error_invalid(MP_QSTR_frequency); - break; - case PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE: - mp_arg_error_invalid(MP_QSTR_variable_frequency); - break; case PWMOUT_INTERNAL_RESOURCES_IN_USE: - mp_raise_RuntimeError(MP_ERROR_TEXT("Internal resource(s) in use")); + mp_raise_RuntimeError(MP_ERROR_TEXT("Conflicting settings for shared resource")); break; default: case PWMOUT_INITIALIZATION_ERROR: @@ -70,7 +64,7 @@ void common_hal_pwmio_pwmout_raise_error(pwmout_result_t result) { //| *, //| duty_cycle: int = 0, //| frequency: int = 500, -//| variable_frequency: bool = False +//| variable_frequency: bool = False, //| ) -> None: //| """Create a PWM object associated with the given pin. This allows you to //| write PWM signals out on the given pin. Frequency is fixed after init @@ -131,6 +125,7 @@ void common_hal_pwmio_pwmout_raise_error(pwmout_result_t result) { //| //| """ //| ... +//| static mp_obj_t pwmio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { enum { ARG_pin, ARG_duty_cycle, ARG_frequency, ARG_variable_frequency }; static const mp_arg_t allowed_args[] = { @@ -159,6 +154,7 @@ static mp_obj_t pwmio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, //| def deinit(self) -> None: //| """Deinitialises the PWMOut and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t pwmio_pwmout_deinit(mp_obj_t self_in) { pwmio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_pwmio_pwmout_deinit(self); @@ -175,18 +171,15 @@ static void check_for_deinit(pwmio_pwmout_obj_t *self) { //| def __enter__(self) -> PWMOut: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t pwmio_pwmout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_pwmio_pwmout_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pwmio_pwmout___exit___obj, 4, 4, pwmio_pwmout_obj___exit__); +//| +// Provided by context manager helper. //| duty_cycle: int //| """16 bit value that dictates how much of one cycle is high (1) versus low @@ -231,6 +224,7 @@ MP_PROPERTY_GETSET(pwmio_pwmout_duty_cycle_obj, //| to manually re-set the duty cycle. However, an output glitch may occur during the adjustment. //| """ //| +//| static mp_obj_t pwmio_pwmout_obj_get_frequency(mp_obj_t self_in) { pwmio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -262,7 +256,7 @@ static const mp_rom_map_elem_t pwmio_pwmout_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pwmio_pwmout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&pwmio_pwmout_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pwmio_pwmout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_duty_cycle), MP_ROM_PTR(&pwmio_pwmout_duty_cycle_obj) }, diff --git a/shared-bindings/pwmio/PWMOut.h b/shared-bindings/pwmio/PWMOut.h index d8bab978228..3c3093ae628 100644 --- a/shared-bindings/pwmio/PWMOut.h +++ b/shared-bindings/pwmio/PWMOut.h @@ -15,8 +15,6 @@ typedef enum pwmout_result_t { PWMOUT_OK, PWMOUT_INVALID_PIN, PWMOUT_INVALID_FREQUENCY, - PWMOUT_INVALID_FREQUENCY_ON_PIN, - PWMOUT_VARIABLE_FREQUENCY_NOT_AVAILABLE, PWMOUT_INTERNAL_RESOURCES_IN_USE, PWMOUT_INITIALIZATION_ERROR, } pwmout_result_t; diff --git a/shared-bindings/qrio/PixelPolicy.c b/shared-bindings/qrio/PixelPolicy.c index b8a422c40fd..6acce4984a1 100644 --- a/shared-bindings/qrio/PixelPolicy.c +++ b/shared-bindings/qrio/PixelPolicy.c @@ -25,6 +25,7 @@ //| RGB565: PixelPolicy //| """The input buffer to `QRDecoder.decode` consists of RGB565 values in native order. The green component is used.""" //| +//| MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, EVERY_BYTE, QRIO_EVERY_BYTE); MAKE_ENUM_VALUE(qrio_pixel_policy_type, qrio_pixel_policy, RGB565, QRIO_RGB565); diff --git a/shared-bindings/qrio/QRDecoder.c b/shared-bindings/qrio/QRDecoder.c index d9a7b31708d..e8977bc1efe 100644 --- a/shared-bindings/qrio/QRDecoder.c +++ b/shared-bindings/qrio/QRDecoder.c @@ -20,6 +20,7 @@ //| :param int height: The pixel height of the image to decode //| """ //| ... +//| static mp_obj_t qrio_qrdecoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args_in) { enum { ARG_width, ARG_height }; @@ -33,7 +34,7 @@ static mp_obj_t qrio_qrdecoder_make_new(const mp_obj_type_t *type, size_t n_args qrio_qrdecoder_obj_t *self = mp_obj_malloc(qrio_qrdecoder_obj_t, &qrio_qrdecoder_type_obj); shared_module_qrio_qrdecoder_construct(self, args[ARG_width].u_int, args[ARG_height].u_int); - return self; + return MP_OBJ_FROM_PTR(self); } @@ -53,6 +54,7 @@ static void verify_buffer_size(qrio_qrdecoder_obj_t *self, mp_obj_t *buffer, siz //| self, buffer: ReadableBuffer, pixel_policy: PixelPolicy = PixelPolicy.EVERY_BYTE //| ) -> List[QRInfo]: //| """Decode zero or more QR codes from the given image. The size of the buffer must be at least ``length``×``width`` bytes for `EVERY_BYTE`, and 2×``length``×``width`` bytes for `EVEN_BYTES` or `ODD_BYTES`.""" +//| static mp_obj_t qrio_qrdecoder_decode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -78,6 +80,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(qrio_qrdecoder_decode_obj, 1, qrio_qrdecoder_decode); //| self, buffer: ReadableBuffer, pixel_policy: PixelPolicy = PixelPolicy.EVERY_BYTE //| ) -> List[QRPosition]: //| """Find all visible QR codes from the given image. The size of the buffer must be at least ``length``×``width`` bytes for `EVERY_BYTE`, and 2×``length``×``width`` bytes for `EVEN_BYTES` or `ODD_BYTES`.""" +//| static mp_obj_t qrio_qrdecoder_find(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -122,6 +125,7 @@ MP_PROPERTY_GETSET(qrio_qrdecoder_width_obj, //| height: int //| """The height of image the decoder expects""" //| +//| static mp_obj_t qrio_qrdecoder_get_height(mp_obj_t self_in) { qrio_qrdecoder_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(shared_module_qrio_qrdecoder_get_height(self)); diff --git a/shared-bindings/qrio/QRInfo.c b/shared-bindings/qrio/QRInfo.c index 3f63c21e3ce..351ee322105 100644 --- a/shared-bindings/qrio/QRInfo.c +++ b/shared-bindings/qrio/QRInfo.c @@ -18,6 +18,7 @@ //| data_type: Union[str, int] //| """The encoding of the payload as a string (if a standard encoding) or int (if not standard)""" //| +//| const mp_obj_namedtuple_type_t qrio_qrinfo_type_obj = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_QRInfo), @@ -58,6 +59,7 @@ const mp_obj_namedtuple_type_t qrio_qrinfo_type_obj = { //| size: int //| """The number of bits the code contains""" //| +//| const mp_obj_namedtuple_type_t qrio_qrposition_type_obj = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS(MP_QSTR_QRPosition), diff --git a/shared-bindings/qspibus/QSPIBus.c b/shared-bindings/qspibus/QSPIBus.c new file mode 100644 index 00000000000..24c3089213f --- /dev/null +++ b/shared-bindings/qspibus/QSPIBus.c @@ -0,0 +1,199 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/qspibus/QSPIBus.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "shared-module/displayio/__init__.h" + +#include "py/binary.h" +#include "py/obj.h" +#include "py/runtime.h" + +static void check_for_deinit(qspibus_qspibus_obj_t *self) { + if (common_hal_qspibus_qspibus_deinited(self)) { + raise_deinited_error(); + } +} + +//| class QSPIBus: +//| """QSPI bus for quad-SPI displays.""" +//| +//| def __init__( +//| self, +//| *, +//| clock: microcontroller.Pin, +//| data0: microcontroller.Pin, +//| data1: microcontroller.Pin, +//| data2: microcontroller.Pin, +//| data3: microcontroller.Pin, +//| cs: microcontroller.Pin, +//| dcx: Optional[microcontroller.Pin] = None, +//| reset: Optional[microcontroller.Pin] = None, +//| frequency: int = 80_000_000, +//| ) -> None: +//| """Create a QSPIBus object for quad-SPI display communication. +//| +//| :param ~microcontroller.Pin clock: QSPI clock pin +//| :param ~microcontroller.Pin data0: QSPI data line 0 +//| :param ~microcontroller.Pin data1: QSPI data line 1 +//| :param ~microcontroller.Pin data2: QSPI data line 2 +//| :param ~microcontroller.Pin data3: QSPI data line 3 +//| :param ~microcontroller.Pin cs: Chip select pin +//| :param ~microcontroller.Pin dcx: Optional data/command select pin. +//| Reserved for future hardware paths. Current ESP32-S3 implementation +//| uses encoded QSPI command words and does not require explicit DCX. +//| :param ~microcontroller.Pin reset: Optional reset pin +//| :param int frequency: Bus frequency in Hz (1-80MHz) +//| """ +//| ... +//| +static mp_obj_t qspibus_qspibus_make_new(const mp_obj_type_t *type, size_t n_args, + size_t n_kw, const mp_obj_t *all_args) { + + enum { ARG_clock, ARG_data0, ARG_data1, ARG_data2, ARG_data3, ARG_cs, ARG_dcx, ARG_reset, ARG_frequency }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_KW_ONLY | MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_data0, MP_ARG_KW_ONLY | MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_data1, MP_ARG_KW_ONLY | MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_data2, MP_ARG_KW_ONLY | MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_data3, MP_ARG_KW_ONLY | MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_cs, MP_ARG_KW_ONLY | MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_dcx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 80000000} }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t *clock = validate_obj_is_free_pin(args[ARG_clock].u_obj, MP_QSTR_clock); + const mcu_pin_obj_t *data0 = validate_obj_is_free_pin(args[ARG_data0].u_obj, MP_QSTR_data0); + const mcu_pin_obj_t *data1 = validate_obj_is_free_pin(args[ARG_data1].u_obj, MP_QSTR_data1); + const mcu_pin_obj_t *data2 = validate_obj_is_free_pin(args[ARG_data2].u_obj, MP_QSTR_data2); + const mcu_pin_obj_t *data3 = validate_obj_is_free_pin(args[ARG_data3].u_obj, MP_QSTR_data3); + const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj, MP_QSTR_cs); + const mcu_pin_obj_t *dcx = validate_obj_is_free_pin_or_none(args[ARG_dcx].u_obj, MP_QSTR_dcx); + const mcu_pin_obj_t *reset = validate_obj_is_free_pin_or_none(args[ARG_reset].u_obj, MP_QSTR_reset); + + uint32_t frequency = (uint32_t)mp_arg_validate_int_range(args[ARG_frequency].u_int, 1, 80000000, MP_QSTR_frequency); + + qspibus_qspibus_obj_t *self = &allocate_display_bus_or_raise()->qspi_bus; + self->base.type = &qspibus_qspibus_type; + common_hal_qspibus_qspibus_construct(self, clock, data0, data1, data2, data3, cs, dcx, reset, frequency); + + return MP_OBJ_FROM_PTR(self); +} + +//| def reset(self) -> None: +//| """Perform a hardware reset using the reset pin. +//| +//| :raises RuntimeError: if no reset pin was provided at construction. +//| """ +//| ... +//| +static mp_obj_t qspibus_qspibus_obj_reset(mp_obj_t self_in) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + if (!common_hal_qspibus_qspibus_reset(MP_OBJ_FROM_PTR(self))) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("No %q pin"), MP_QSTR_reset); + } + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(qspibus_qspibus_reset_obj, qspibus_qspibus_obj_reset); + +//| def send( +//| self, command: int, data: ReadableBuffer, *, toggle_every_byte: bool = False +//| ) -> None: +//| """Sends the given command value followed by the full set of data. Display state, such as +//| vertical scroll, set via ``send`` may or may not be reset once the code is done.""" +//| ... +//| +static mp_obj_t qspibus_qspibus_send(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_command, ARG_data }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_command, MP_ARG_INT | MP_ARG_REQUIRED }, + { MP_QSTR_data, MP_ARG_OBJ | MP_ARG_REQUIRED }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + + uint8_t command = (uint8_t)mp_arg_validate_int_range(args[ARG_command].u_int, 0, 255, MP_QSTR_command); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_data].u_obj, &bufinfo, MP_BUFFER_READ); + + // Flush any pending command from a prior write_command() call. + // begin_transaction() returns false while has_pending_command is set, + // so entering the wait loop without flushing would spin forever. + if (self->has_pending_command) { + common_hal_qspibus_qspibus_write_data(self, NULL, 0); + } + + // Wait for display bus to be available, then acquire transaction. + while (!common_hal_qspibus_qspibus_begin_transaction(MP_OBJ_FROM_PTR(self))) { + RUN_BACKGROUND_TASKS; + } + common_hal_qspibus_qspibus_send(MP_OBJ_FROM_PTR(self), DISPLAY_COMMAND, CHIP_SELECT_UNTOUCHED, &command, 1); + common_hal_qspibus_qspibus_send(MP_OBJ_FROM_PTR(self), DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, ((uint8_t *)bufinfo.buf), bufinfo.len); + common_hal_qspibus_qspibus_end_transaction(MP_OBJ_FROM_PTR(self)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(qspibus_qspibus_send_obj, 1, qspibus_qspibus_send); + +//| def write_command(self, command: int) -> None: +//| """Stage a command byte for subsequent :py:meth:`write_data`. +//| +//| If a previously staged command had no data, it is sent as +//| a command-only transaction before staging the new one. +//| """ +//| ... +//| +static mp_obj_t qspibus_qspibus_write_command(mp_obj_t self_in, mp_obj_t command_obj) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + uint8_t command = (uint8_t)mp_arg_validate_int_range(mp_obj_get_int(command_obj), 0, 255, MP_QSTR_command); + common_hal_qspibus_qspibus_write_command(self, command); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(qspibus_qspibus_write_command_obj, qspibus_qspibus_write_command); + +//| def write_data(self, data: ReadableBuffer) -> None: +//| """Send payload bytes for the most recently staged command.""" +//| ... +//| +static mp_obj_t qspibus_qspibus_write_data(mp_obj_t self_in, mp_obj_t data_obj) { + qspibus_qspibus_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_obj, &bufinfo, MP_BUFFER_READ); + common_hal_qspibus_qspibus_write_data(self, (const uint8_t *)bufinfo.buf, bufinfo.len); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(qspibus_qspibus_write_data_obj, qspibus_qspibus_write_data); + +static const mp_rom_map_elem_t qspibus_qspibus_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&qspibus_qspibus_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&qspibus_qspibus_send_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_command), MP_ROM_PTR(&qspibus_qspibus_write_command_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_data), MP_ROM_PTR(&qspibus_qspibus_write_data_obj) }, +}; +static MP_DEFINE_CONST_DICT(qspibus_qspibus_locals_dict, qspibus_qspibus_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + qspibus_qspibus_type, + MP_QSTR_QSPIBus, + MP_TYPE_FLAG_NONE, + make_new, qspibus_qspibus_make_new, + locals_dict, &qspibus_qspibus_locals_dict + ); diff --git a/shared-bindings/qspibus/QSPIBus.h b/shared-bindings/qspibus/QSPIBus.h new file mode 100644 index 00000000000..140b639279d --- /dev/null +++ b/shared-bindings/qspibus/QSPIBus.h @@ -0,0 +1,53 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" + +#include "shared-bindings/displayio/__init__.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/qspibus/QSPIBus.h" + +extern const mp_obj_type_t qspibus_qspibus_type; + +void common_hal_qspibus_qspibus_construct( + qspibus_qspibus_obj_t *self, + const mcu_pin_obj_t *clock, + const mcu_pin_obj_t *data0, + const mcu_pin_obj_t *data1, + const mcu_pin_obj_t *data2, + const mcu_pin_obj_t *data3, + const mcu_pin_obj_t *cs, + const mcu_pin_obj_t *dcx, + const mcu_pin_obj_t *reset, + uint32_t frequency); + +void common_hal_qspibus_qspibus_deinit(qspibus_qspibus_obj_t *self); +bool common_hal_qspibus_qspibus_deinited(qspibus_qspibus_obj_t *self); + +void common_hal_qspibus_qspibus_write_command( + qspibus_qspibus_obj_t *self, + uint8_t command); +void common_hal_qspibus_qspibus_write_data( + qspibus_qspibus_obj_t *self, + const uint8_t *data, + size_t len); + +bool common_hal_qspibus_qspibus_reset(mp_obj_t obj); +bool common_hal_qspibus_qspibus_bus_free(mp_obj_t obj); +bool common_hal_qspibus_qspibus_begin_transaction(mp_obj_t obj); +void common_hal_qspibus_qspibus_send( + mp_obj_t obj, + display_byte_type_t data_type, + display_chip_select_behavior_t chip_select, + const uint8_t *data, + uint32_t data_length); +void common_hal_qspibus_qspibus_end_transaction(mp_obj_t obj); +void common_hal_qspibus_qspibus_flush(mp_obj_t obj); +void common_hal_qspibus_qspibus_collect_ptrs(mp_obj_t obj); diff --git a/shared-bindings/qspibus/__init__.c b/shared-bindings/qspibus/__init__.c new file mode 100644 index 00000000000..0281c41c804 --- /dev/null +++ b/shared-bindings/qspibus/__init__.c @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/qspibus/__init__.h" +#include "shared-bindings/qspibus/QSPIBus.h" + +//| """QSPI bus protocol for quad-SPI displays +//| +//| The `qspibus` module provides a low-level QSPI bus interface for displays +//| that use four data lines. It is analogous to `fourwire` for standard SPI. +//| +//| Use :class:`qspibus.QSPIBus` to create a bus instance. +//| +//| Example usage:: +//| +//| import board +//| import qspibus +//| import displayio +//| +//| displayio.release_displays() +//| +//| bus = qspibus.QSPIBus( +//| clock=board.LCD_CLK, +//| data0=board.LCD_D0, +//| data1=board.LCD_D1, +//| data2=board.LCD_D2, +//| data3=board.LCD_D3, +//| cs=board.LCD_CS, +//| reset=board.LCD_RESET, +//| frequency=80_000_000, +//| ) +//| """ + +static const mp_rom_map_elem_t qspibus_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_qspibus) }, + { MP_ROM_QSTR(MP_QSTR_QSPIBus), MP_ROM_PTR(&qspibus_qspibus_type) }, +}; + +static MP_DEFINE_CONST_DICT(qspibus_module_globals, qspibus_module_globals_table); + +const mp_obj_module_t qspibus_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&qspibus_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_qspibus, qspibus_module); diff --git a/shared-bindings/qspibus/__init__.h b/shared-bindings/qspibus/__init__.h new file mode 100644 index 00000000000..9b4ca243327 --- /dev/null +++ b/shared-bindings/qspibus/__init__.h @@ -0,0 +1,8 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// SPDX-FileCopyrightText: Copyright (c) 2026 Przemyslaw Patrick Socha +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-bindings/qspibus/QSPIBus.h" diff --git a/shared-bindings/rainbowio/__init__.c b/shared-bindings/rainbowio/__init__.c index a5a941e2a78..e02df713eeb 100644 --- a/shared-bindings/rainbowio/__init__.c +++ b/shared-bindings/rainbowio/__init__.c @@ -13,12 +13,15 @@ //| //| Provides the `colorwheel()` function.""" //| +//| //| def colorwheel(n: float) -> int: //| """C implementation of the common colorwheel() function found in many examples. -//| Returns the colorwheel RGB value as an integer value for n (usable in neopixel and dotstar). +//| Takes a hue, a value between 0-255, and returns an RGB tuple encoded as an +//| integer value (usable in neopixel and dotstar). //| """ //| ... //| +//| static mp_obj_t rainbowio_colorwheel(mp_obj_t n) { mp_float_t f = mp_obj_get_float(n); return MP_OBJ_NEW_SMALL_INT(colorwheel(f)); diff --git a/shared-bindings/random/__init__.c b/shared-bindings/random/__init__.c index e255174fc1b..81201e6f8ab 100644 --- a/shared-bindings/random/__init__.c +++ b/shared-bindings/random/__init__.c @@ -27,12 +27,14 @@ //| //| _T = TypeVar("_T") //| +//| //| def seed(seed: int) -> None: //| """Sets the starting seed of the random number generation. Further calls to //| `random` will return deterministic results afterwards.""" //| ... //| +//| static mp_obj_t random_seed(mp_obj_t seed_in) { mp_uint_t seed = mp_obj_get_int_truncated(seed_in); shared_modules_random_seed(seed); @@ -44,6 +46,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(random_seed_obj, random_seed); //| """Returns an integer with *k* random bits.""" //| ... //| +//| static mp_obj_t random_getrandbits(mp_obj_t num_in) { mp_int_t n = mp_obj_get_int(num_in); if (n > 32 || n < 0) { @@ -62,6 +65,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(random_getrandbits_obj, random_getrandbits); //| """Returns a randomly selected integer from ``range(start[, stop[, step]])``.""" //| ... //| +//| static mp_obj_t random_randrange(size_t n_args, const mp_obj_t *args) { mp_int_t start = 0; mp_int_t stop = mp_obj_get_int(args[0]); @@ -105,6 +109,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(random_randrange_obj, 1, 3, random_ra //| to ``randrange(a, b + 1, 1)``""" //| ... //| +//| static mp_obj_t random_randint(mp_obj_t a_in, mp_obj_t b_in) { mp_int_t a = mp_obj_get_int(a_in); mp_int_t b = mp_obj_get_int(b_in); @@ -120,6 +125,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(random_randint_obj, random_randint); //| IndexError when the sequence is empty.""" //| ... //| +//| static mp_obj_t random_choice(mp_obj_t seq) { mp_int_t len = mp_obj_get_int(mp_obj_len(seq)); if (len == 0) { @@ -133,6 +139,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(random_choice_obj, random_choice); //| """Returns a random float between 0 and 1.0.""" //| ... //| +//| static mp_obj_t random_random(void) { return mp_obj_new_float(shared_modules_random_random()); } @@ -143,6 +150,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(random_random_obj, random_random); //| depending on float rounding.""" //| ... //| +//| static mp_obj_t random_uniform(mp_obj_t a_in, mp_obj_t b_in) { mp_float_t a = mp_obj_get_float(a_in); mp_float_t b = mp_obj_get_float(b_in); diff --git a/shared-bindings/rclcpy/Node.c b/shared-bindings/rclcpy/Node.c new file mode 100644 index 00000000000..4097fbc1515 --- /dev/null +++ b/shared-bindings/rclcpy/Node.c @@ -0,0 +1,146 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#include +#include "shared-bindings/rclcpy/Node.h" +#include "shared-bindings/rclcpy/Publisher.h" +#include "shared-bindings/util.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" + + +//| class Node: +//| """A ROS2 Node""" +//| +//| def __init__( +//| self, +//| node_name: str, +//| *, +//| namespace: str | None = None, +//| ) -> None: +//| """Create a Node. +//| +//| Creates an instance of a ROS2 Node. Nodes can be used to create other ROS +//| entities like publishers or subscribers. Nodes must have a unique name, and +//| may also be constructed from their class. +//| +//| :param str node_name: The name of the node. Must be a valid ROS 2 node name +//| :param str namespace: The namespace for the node. If None, the node will be +//| created in the root namespace +//| """ +//| ... +//| +static mp_obj_t rclcpy_node_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_node_name, ARG_namespace }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_node_name, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_namespace, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + const char *node_name = mp_obj_str_get_str(args[ARG_node_name].u_obj); + const char *namespace = ""; + if (args[ARG_namespace].u_obj != mp_const_none) { + namespace = mp_obj_str_get_str(args[ARG_namespace].u_obj); + } + + rclcpy_node_obj_t *self = mp_obj_malloc_with_finaliser(rclcpy_node_obj_t, &rclcpy_node_type); + common_hal_rclcpy_node_construct(self, node_name, namespace); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Deinitializes the node and frees any hardware or remote agent resources +//| used by it. Deinitialized nodes cannot be used again. +//| """ +//| ... +//| +static mp_obj_t rclcpy_node_obj_deinit(mp_obj_t self_in) { + rclcpy_node_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_rclcpy_node_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(rclcpy_node_deinit_obj, rclcpy_node_obj_deinit); + +static void check_for_deinit(rclcpy_node_obj_t *self) { + if (common_hal_rclcpy_node_deinited(self)) { + raise_deinited_error(); + } +} + +//| def create_publisher(self, topic: str) -> Publisher: +//| """Create a publisher for a given topic string. +//| +//| Creates an instance of a ROS2 Publisher. +//| +//| :param str topic: The name of the topic +//| :return: A new Publisher object for the specified topic +//| :rtype: Publisher +//| """ +//| ... +//| +static mp_obj_t rclcpy_node_create_publisher(mp_obj_t self_in, mp_obj_t topic) { + rclcpy_node_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + const char *topic_name = mp_obj_str_get_str(topic); + + rclcpy_publisher_obj_t *publisher = mp_obj_malloc_with_finaliser(rclcpy_publisher_obj_t, &rclcpy_publisher_type); + common_hal_rclcpy_publisher_construct(publisher, self, topic_name); + return MP_OBJ_FROM_PTR(publisher); +} +static MP_DEFINE_CONST_FUN_OBJ_2(rclcpy_node_create_publisher_obj, rclcpy_node_create_publisher); + +//| def get_name(self) -> str: +//| """Get the name of the node. +//| +//| :return: The node's name +//| :rtype: str +//| """ +//| ... +//| +static mp_obj_t rclcpy_node_get_name(mp_obj_t self_in) { + rclcpy_node_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + const char *name_str = common_hal_rclcpy_node_get_name(self); + return mp_obj_new_str(name_str, strlen(name_str)); +} +static MP_DEFINE_CONST_FUN_OBJ_1(rclcpy_node_get_name_obj, rclcpy_node_get_name); + +//| def get_namespace(self) -> str: +//| """Get the namespace of the node. +//| +//| :return: The node's namespace +//| :rtype: str +//| """ +//| ... +//| +static mp_obj_t rclcpy_node_get_namespace(mp_obj_t self_in) { + rclcpy_node_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + const char *namespace_str = common_hal_rclcpy_node_get_namespace(self); + return mp_obj_new_str(namespace_str, strlen(namespace_str)); +} +static MP_DEFINE_CONST_FUN_OBJ_1(rclcpy_node_get_namespace_obj, rclcpy_node_get_namespace); + +static const mp_rom_map_elem_t rclcpy_node_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rclcpy_node_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&rclcpy_node_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_create_publisher), MP_ROM_PTR(&rclcpy_node_create_publisher_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_name), MP_ROM_PTR(&rclcpy_node_get_name_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_namespace), MP_ROM_PTR(&rclcpy_node_get_namespace_obj) }, +}; +static MP_DEFINE_CONST_DICT(rclcpy_node_locals_dict, rclcpy_node_locals_dict_table); + + +MP_DEFINE_CONST_OBJ_TYPE( + rclcpy_node_type, + MP_QSTR_Node, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, rclcpy_node_make_new, + locals_dict, &rclcpy_node_locals_dict + ); diff --git a/shared-bindings/rclcpy/Node.h b/shared-bindings/rclcpy/Node.h new file mode 100644 index 00000000000..be0230846f6 --- /dev/null +++ b/shared-bindings/rclcpy/Node.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#pragma once +#include "common-hal/rclcpy/Node.h" + + +extern const mp_obj_type_t rclcpy_node_type; + +void common_hal_rclcpy_node_construct(rclcpy_node_obj_t *self, + const char *node_name, const char *namespace); +bool common_hal_rclcpy_node_deinited(rclcpy_node_obj_t *self); +void common_hal_rclcpy_node_deinit(rclcpy_node_obj_t *self); +const char *common_hal_rclcpy_node_get_name(rclcpy_node_obj_t *self); +const char *common_hal_rclcpy_node_get_namespace(rclcpy_node_obj_t *self); diff --git a/shared-bindings/rclcpy/Publisher.c b/shared-bindings/rclcpy/Publisher.c new file mode 100644 index 00000000000..be1e229cce4 --- /dev/null +++ b/shared-bindings/rclcpy/Publisher.c @@ -0,0 +1,99 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#include +#include "shared-bindings/rclcpy/Publisher.h" +#include "shared-bindings/util.h" +#include "py/objproperty.h" +#include "py/objtype.h" +#include "py/runtime.h" + + +//| class Publisher: +//| """A ROS2 publisher""" +//| +//| def __init__(self) -> None: +//| """Publishers cannot be created directly. +//| +//| Use :meth:`Node.create_publisher` to create a publisher from a node. +//| +//| :raises NotImplementedError: Always, as direct instantiation is not supported +//| """ +//| ... +//| +static mp_obj_t rclcpy_publisher_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("Publishers can only be created from a parent node")); +} + +//| def deinit(self) -> None: +//| """Deinitializes the publisher and frees any hardware or remote agent resources +//| used by it. Deinitialized publishers cannot be used again. +//| """ +//| ... +//| +static mp_obj_t rclcpy_publisher_obj_deinit(mp_obj_t self_in) { + rclcpy_publisher_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_rclcpy_publisher_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(rclcpy_publisher_deinit_obj, rclcpy_publisher_obj_deinit); + +static void check_for_deinit(rclcpy_publisher_obj_t *self) { + if (common_hal_rclcpy_publisher_deinited(self)) { + raise_deinited_error(); + } +} + +//| def publish_int32(self, message: int) -> None: +//| """Publish a 32-bit signed integer message to the topic. +//| +//| :param int message: The integer value to publish. Must be within the range +//| of a 32-bit signed integer (-2,147,483,648 to 2,147,483,647) +//| """ +//| ... +//| +static mp_obj_t rclcpy_publisher_publish_int32(mp_obj_t self_in, mp_obj_t in_msg) { + rclcpy_publisher_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + int32_t msg = mp_obj_get_int(in_msg); + common_hal_rclcpy_publisher_publish_int32(self, msg); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_2(rclcpy_publisher_publish_int32_obj, rclcpy_publisher_publish_int32); + +//| def get_topic_name(self) -> str: +//| """Get the name of the topic this publisher publishes to. +//| +//| :return: The topic name as specified when the publisher was created +//| :rtype: str +//| """ +//| ... +//| +static mp_obj_t rclcpy_publisher_get_topic_name(mp_obj_t self_in) { + rclcpy_publisher_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + const char *topic_str = common_hal_rclcpy_publisher_get_topic_name(self); + return mp_obj_new_str(topic_str, strlen(topic_str)); +} +static MP_DEFINE_CONST_FUN_OBJ_1(rclcpy_publisher_get_topic_name_obj, rclcpy_publisher_get_topic_name); + + +static const mp_rom_map_elem_t rclcpy_publisher_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rclcpy_publisher_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&rclcpy_publisher_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_publish_int32), MP_ROM_PTR(&rclcpy_publisher_publish_int32_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_topic_name), MP_ROM_PTR(&rclcpy_publisher_get_topic_name_obj) }, +}; +static MP_DEFINE_CONST_DICT(rclcpy_publisher_locals_dict, rclcpy_publisher_locals_dict_table); + + +MP_DEFINE_CONST_OBJ_TYPE( + rclcpy_publisher_type, + MP_QSTR_Publisher, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, rclcpy_publisher_make_new, + locals_dict, &rclcpy_publisher_locals_dict + ); diff --git a/shared-bindings/rclcpy/Publisher.h b/shared-bindings/rclcpy/Publisher.h new file mode 100644 index 00000000000..21909fe12be --- /dev/null +++ b/shared-bindings/rclcpy/Publisher.h @@ -0,0 +1,18 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#pragma once +#include "common-hal/rclcpy/Publisher.h" + + +extern const mp_obj_type_t rclcpy_publisher_type; + +void common_hal_rclcpy_publisher_construct(rclcpy_publisher_obj_t *self, rclcpy_node_obj_t *node, + const char *topic_name); +bool common_hal_rclcpy_publisher_deinited(rclcpy_publisher_obj_t *self); +void common_hal_rclcpy_publisher_deinit(rclcpy_publisher_obj_t *self); +void common_hal_rclcpy_publisher_publish_int32(rclcpy_publisher_obj_t *self, int32_t data); +const char *common_hal_rclcpy_publisher_get_topic_name(rclcpy_publisher_obj_t *self); diff --git a/shared-bindings/rclcpy/__init__.c b/shared-bindings/rclcpy/__init__.c new file mode 100644 index 00000000000..e195294cde6 --- /dev/null +++ b/shared-bindings/rclcpy/__init__.c @@ -0,0 +1,135 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/rclcpy/__init__.h" +#include "shared-bindings/rclcpy/Node.h" +#include "shared-bindings/rclcpy/Publisher.h" + +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/objstr.h" +#include "py/runtime.h" + +//| """Robot Operating System (ROS2) connectivity through micro-ROS +//| +//| The `rclcpy` module contains basic classes and connectivity options for +//| communicating with a ROS network running on a linux machine, using the +//| eProsima's `micro-ROS client API `_. +//| +//| The underlying micro-ROS system uses a resource-constrained middleware layer +//| (XRCE-DDS) that must be connected to an agent running within ROS2 on a host +//| Linux computer. The API exposed by Circuitpython aims to be close to the +//| standard Python API for ROS2, ``rclpy`` with minor additions to support +//| connecting to this agent. +//| +//| Wifi must be connected before calling any `rclcpy` functions. As with +//| ``rclpy``, the `rclcpy.init()` function must be run before creating any ROS +//| objects. Child objects, such as publishers, must be created by their parent +//| objects. For example:: +//| +//| import os, wifi, time +//| import rclcpy +//| wifi.radio.connect(ssid=os.getenv('CIRCUITPY_WIFI_SSID'), +//| password=os.getenv('CIRCUITPY_WIFI_PASSWORD')) +//| rclcpy.init("192.168.10.111","8888") +//| mynode = rclcpy.Node("foo") +//| mypub = mynode.create_publisher("bar") +//| mypub.publish_int32(42) +//| """ + +//| def init( +//| agent_ip: str, +//| agent_port: str, +//| *, +//| domain_id: int = 0, +//| ) -> None: +//| """Initialize micro-ROS and connect to a micro-ROS agent. +//| +//| This function starts ROS communications and connects to the micro-ROS agent +//| on a linux computer. It must be called before creating ROS objects. +//| +//| :param str agent_ip: The IP address of the micro-ROS agent +//| :param str agent_port: The port number of the micro-ROS agent as a string +//| :param int domain_id: The ROS 2 domain ID for network isolation and organization. +//| Devices with the same domain ID can communicate with each other. +//| """ +//| ... +//| +static mp_obj_t rclcpy_init(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_agent_ip, ARG_agent_port, ARG_domain_id}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_agent_ip, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_agent_port, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_domain_id, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + const char *agent_ip = mp_obj_str_get_str(args[ARG_agent_ip].u_obj); + const char *agent_port = mp_obj_str_get_str(args[ARG_agent_port].u_obj); + int16_t domain_id = args[ARG_domain_id].u_int; + + common_hal_rclcpy_init(agent_ip, agent_port, domain_id); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(rclcpy_init_obj, 2, rclcpy_init); + + +//| def create_node( +//| node_name: str, +//| *, +//| namespace: str | None = None +//| ) -> Node: +//| """Create a Node. +//| +//| Creates an instance of a ROS2 Node. Nodes can be used to create other ROS +//| entities like publishers or subscribers. Nodes must have a unique name, and +//| may also be constructed from their class. +//| +//| :param str node_name: The name of the node. Must be a valid ROS 2 node name. +//| :param str namespace: The namespace for the node. If None, the node will be +//| created in the root namespace. +//| :return: A new Node object +//| :rtype: Node +//| """ +//| ... +//| +static mp_obj_t rclcpy_create_node(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_node_name, ARG_namespace }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_node_name, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_namespace, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + const char *node_name = mp_obj_str_get_str(args[ARG_node_name].u_obj); + const char *namespace = ""; + if (args[ARG_namespace].u_obj != mp_const_none) { + namespace = mp_obj_str_get_str(args[ARG_namespace].u_obj); + } + + rclcpy_node_obj_t *self = mp_obj_malloc_with_finaliser(rclcpy_node_obj_t, &rclcpy_node_type); + common_hal_rclcpy_node_construct(self, node_name, namespace); + + return MP_OBJ_FROM_PTR(self); +} +static MP_DEFINE_CONST_FUN_OBJ_KW(rclcpy_create_node_obj, 2, rclcpy_create_node); + +static const mp_rom_map_elem_t rclcpy_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_rclcpy) }, + { MP_ROM_QSTR(MP_QSTR_Node), MP_ROM_PTR(&rclcpy_node_type) }, + { MP_ROM_QSTR(MP_QSTR_Publisher), MP_ROM_PTR(&rclcpy_publisher_type) }, + { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&rclcpy_init_obj) }, + { MP_ROM_QSTR(MP_QSTR_create_node), MP_ROM_PTR(&rclcpy_create_node_obj) }, +}; + +static MP_DEFINE_CONST_DICT(rclcpy_module_globals, rclcpy_module_globals_table); + +const mp_obj_module_t rclcpy_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&rclcpy_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_rclcpy, rclcpy_module); diff --git a/shared-bindings/rclcpy/__init__.h b/shared-bindings/rclcpy/__init__.h new file mode 100644 index 00000000000..1b473421688 --- /dev/null +++ b/shared-bindings/rclcpy/__init__.h @@ -0,0 +1,12 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Lucian Copeland +// +// SPDX-License-Identifier: MIT + +#pragma once +#include "common-hal/rclcpy/__init__.h" + +void common_hal_rclcpy_init(const char *agent_ip, const char *agent_port, int16_t domain_id); +rclcpy_context_t *common_hal_rclcpy_get_default_context(void); +bool common_hal_rclcpy_default_context_is_initialized(void); diff --git a/shared-bindings/rgbmatrix/RGBMatrix.c b/shared-bindings/rgbmatrix/RGBMatrix.c index bb4b5093330..6242f981fdf 100644 --- a/shared-bindings/rgbmatrix/RGBMatrix.c +++ b/shared-bindings/rgbmatrix/RGBMatrix.c @@ -130,7 +130,7 @@ static void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| framebuffer: Optional[WriteableBuffer] = None, //| height: int = 0, //| tile: int = 1, -//| serpentine: bool = True +//| serpentine: bool = True, //| ) -> None: //| """Create a RGBMatrix object with the given attributes. The height of //| the display is determined by the number of rgb and address pins and the number of tiles: @@ -193,6 +193,7 @@ static void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_ //| :param Optional[WriteableBuffer] framebuffer: A pre-allocated framebuffer to use. If unspecified, a framebuffer is allocated //| :param int height: The optional overall height of the whole matrix in pixels. This value is not required because it can be calculated as described above. //| """ +//| static mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_width, ARG_bit_depth, ARG_rgb_list, ARG_addr_list, @@ -269,6 +270,7 @@ static mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n //| rgbmatrix instance. After deinitialization, no further operations //| may be performed.""" //| ... +//| static mp_obj_t rgbmatrix_rgbmatrix_deinit(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; common_hal_rgbmatrix_rgbmatrix_deinit(self); @@ -286,6 +288,7 @@ static void check_for_deinit(rgbmatrix_rgbmatrix_obj_t *self) { //| brightness: float //| """In the current implementation, 0.0 turns the display off entirely //| and any other value up to 1.0 turns the display on fully.""" +//| static mp_obj_t rgbmatrix_rgbmatrix_get_brightness(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; check_for_deinit(self); @@ -314,6 +317,7 @@ MP_PROPERTY_GETSET(rgbmatrix_rgbmatrix_brightness_obj, //| """Transmits the color data in the buffer to the pixels so that //| they are shown.""" //| ... +//| static mp_obj_t rgbmatrix_rgbmatrix_refresh(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; check_for_deinit(self); @@ -336,6 +340,7 @@ MP_PROPERTY_GETTER(rgbmatrix_rgbmatrix_width_obj, //| height: int //| """The height of the display, in pixels""" //| +//| static mp_obj_t rgbmatrix_rgbmatrix_get_height(mp_obj_t self_in) { rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in; check_for_deinit(self); diff --git a/shared-bindings/rotaryio/IncrementalEncoder.c b/shared-bindings/rotaryio/IncrementalEncoder.c index 6cd137dd71f..0cd94c07562 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.c +++ b/shared-bindings/rotaryio/IncrementalEncoder.c @@ -42,8 +42,15 @@ //| position = enc.position //| if last_position == None or position != last_position: //| print(position) -//| last_position = position""" +//| last_position = position +//| +//| .. warning:: On RP2350 boards, any pulldowns used must be 8.2 kohms or less, +//| to overcome a hardware issue. +//| See the RP2350 warning in `digitalio` for more information. +//| """ +//| //| ... +//| static mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pin_a, ARG_pin_b, ARG_divisor }; static const mp_arg_t allowed_args[] = { @@ -68,6 +75,7 @@ static mp_obj_t rotaryio_incrementalencoder_make_new(const mp_obj_type_t *type, //| def deinit(self) -> None: //| """Deinitializes the IncrementalEncoder and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t rotaryio_incrementalencoder_deinit(mp_obj_t self_in) { rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_rotaryio_incrementalencoder_deinit(self); @@ -84,18 +92,15 @@ static void check_for_deinit(rotaryio_incrementalencoder_obj_t *self) { //| def __enter__(self) -> IncrementalEncoder: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t rotaryio_incrementalencoder_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_rotaryio_incrementalencoder_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(rotaryio_incrementalencoder___exit___obj, 4, 4, rotaryio_incrementalencoder_obj___exit__); +//| +// Provided by context manager helper. //| divisor: int @@ -127,6 +132,7 @@ MP_PROPERTY_GETSET(rotaryio_incrementalencoder_divisor_obj, //| """The current position in terms of pulses. The number of pulses per rotation is defined by the //| specific hardware and by the divisor.""" //| +//| static mp_obj_t rotaryio_incrementalencoder_obj_get_position(mp_obj_t self_in) { rotaryio_incrementalencoder_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -153,7 +159,7 @@ static const mp_rom_map_elem_t rotaryio_incrementalencoder_locals_dict_table[] = { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&rotaryio_incrementalencoder_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&rotaryio_incrementalencoder_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&rotaryio_incrementalencoder___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_position), MP_ROM_PTR(&rotaryio_incrementalencoder_position_obj) }, { MP_ROM_QSTR(MP_QSTR_divisor), MP_ROM_PTR(&rotaryio_incrementalencoder_divisor_obj) }, }; diff --git a/shared-bindings/rotaryio/IncrementalEncoder.h b/shared-bindings/rotaryio/IncrementalEncoder.h index 1c60dd69a19..b3ceb3eeb15 100644 --- a/shared-bindings/rotaryio/IncrementalEncoder.h +++ b/shared-bindings/rotaryio/IncrementalEncoder.h @@ -13,11 +13,15 @@ extern const mp_obj_type_t rotaryio_incrementalencoder_type; extern void common_hal_rotaryio_incrementalencoder_construct(rotaryio_incrementalencoder_obj_t *self, const mcu_pin_obj_t *pin_a, const mcu_pin_obj_t *pin_b); + extern void common_hal_rotaryio_incrementalencoder_deinit(rotaryio_incrementalencoder_obj_t *self); extern bool common_hal_rotaryio_incrementalencoder_deinited(rotaryio_incrementalencoder_obj_t *self); +extern void common_hal_rotaryio_incrementalencoder_mark_deinit(rotaryio_incrementalencoder_obj_t *self); + extern mp_int_t common_hal_rotaryio_incrementalencoder_get_position(rotaryio_incrementalencoder_obj_t *self); extern void common_hal_rotaryio_incrementalencoder_set_position(rotaryio_incrementalencoder_obj_t *self, mp_int_t new_position); + extern mp_int_t common_hal_rotaryio_incrementalencoder_get_divisor(rotaryio_incrementalencoder_obj_t *self); extern void common_hal_rotaryio_incrementalencoder_set_divisor(rotaryio_incrementalencoder_obj_t *self, mp_int_t new_divisor); diff --git a/shared-bindings/rtc/RTC.c b/shared-bindings/rtc/RTC.c index 01686a75d9f..d732ee94d7e 100644 --- a/shared-bindings/rtc/RTC.c +++ b/shared-bindings/rtc/RTC.c @@ -23,6 +23,7 @@ const rtc_rtc_obj_t rtc_rtc_obj = {{&rtc_rtc_type}}; //| def __init__(self) -> None: //| """This class represents the onboard Real Time Clock. It is a singleton and will always return the same instance.""" //| ... +//| static mp_obj_t rtc_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // No arguments mp_arg_check_num(n_args, n_kw, 0, 0, false); @@ -73,7 +74,7 @@ MP_PROPERTY_GETSET(rtc_rtc_datetime_obj, //| //| A positive value speeds up the clock and a negative value slows it down. //| -//| **Limitations:** Calibration not supported on SAMD, Nordic, RP240, Spresense, and STM. +//| **Limitations:** Calibration not supported on SAMD, Nordic, RP2040, Spresense, and STM. //| //| Range and value is hardware specific, but one step is often approximately 1 ppm:: //| @@ -83,6 +84,7 @@ MP_PROPERTY_GETSET(rtc_rtc_datetime_obj, //| r = rtc.RTC() //| r.calibration = 1""" //| +//| static mp_obj_t rtc_rtc_obj_get_calibration(mp_obj_t self_in) { int calibration = common_hal_rtc_get_calibration(); return mp_obj_new_int(calibration); diff --git a/shared-bindings/rtc/__init__.c b/shared-bindings/rtc/__init__.c index 16158413d18..d719ec8441d 100644 --- a/shared-bindings/rtc/__init__.c +++ b/shared-bindings/rtc/__init__.c @@ -17,6 +17,7 @@ //| RTC using :class:`rtc.RTC`. It also backs the :func:`time.time` and :func:`time.localtime` //| functions using the onboard RTC if present.""" //| +//| void rtc_reset(void) { MP_STATE_VM(rtc_time_source) = (mp_obj_t)&rtc_rtc_obj; @@ -47,6 +48,7 @@ mp_obj_t rtc_get_time_source_time(void) { //| rtc.set_time_source(r)""" //| ... //| +//| static mp_obj_t rtc_set_time_source(mp_obj_t time_source) { MP_STATE_VM(rtc_time_source) = time_source; diff --git a/shared-bindings/sdcardio/SDCard.c b/shared-bindings/sdcardio/SDCard.c index 97bd51c0019..506009f64d6 100644 --- a/shared-bindings/sdcardio/SDCard.c +++ b/shared-bindings/sdcardio/SDCard.c @@ -9,7 +9,8 @@ #include "py/objarray.h" #include "shared-bindings/sdcardio/SDCard.h" -#include "shared-module/sdcardio/SDCard.h" +#include "shared-bindings/util.h" + #include "common-hal/busio/SPI.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/microcontroller/Pin.h" @@ -24,7 +25,10 @@ //| with ``storage.VfsFat`` to allow file I/O to an SD card.""" //| //| def __init__( -//| self, bus: busio.SPI, cs: microcontroller.Pin, baudrate: int = 8000000 +//| self, +//| bus: busio.SPI, +//| cs: Union[microcontroller.Pin, digitalio.DigitalInOutProtocol], +//| baudrate: int = 8000000 //| ) -> None: //| """Construct an SPI SD Card object with the given properties //| @@ -37,10 +41,18 @@ //| the microcontroller) //| //| .. important:: -//| If the same SPI bus is shared with other peripherals, it is important that -//| the SD card be initialized before accessing any other peripheral on the bus. -//| Failure to do so can prevent the SD card from being recognized until it is -//| powered off or re-inserted. +//| When the SPI bus is shared with other peripherals, every CS pin on +//| the bus must be in a known HIGH (deselected) state before any SPI +//| transaction occurs. This is normally guaranteed by a hardware +//| pull-up on each CS line, but on boards where a co-resident +//| peripheral's CS floats (for example the Feather RP2040 RFM, whose +//| ``RFM_CS`` has no pull-up), that CS must be driven HIGH in +//| software before the SD card is initialized. If any CS is allowed +//| to float low, the SPI bus can be corrupted during SD card init +//| and the card may not be recognized until it is powered off or +//| re-inserted. The order in which peripherals are constructed is +//| secondary; what matters is that all CS lines are HIGH (deselected) +//| before any SPI transaction. //| //| Example usage: //| @@ -52,10 +64,19 @@ //| import sdcardio //| import storage //| +//| # Make sure to make an "sd" folder on CIRCUITPY +//| //| sd = sdcardio.SDCard(board.SPI(), board.SD_CS) //| vfs = storage.VfsFat(sd) //| storage.mount(vfs, '/sd') -//| os.listdir('/sd')""" +//| print(os.listdir('/sd'))""" +//| + +static void check_for_deinit(sdcardio_sdcard_obj_t *self) { + if (common_hal_sdcardio_sdcard_deinited(self)) { + raise_deinited_error(); + } +} static mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_spi, ARG_cs, ARG_baudrate, NUM_ARGS }; @@ -69,13 +90,11 @@ static mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_arg mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); busio_spi_obj_t *spi = validate_obj_is_spi_bus(args[ARG_spi].u_obj, MP_QSTR_spi); - const mcu_pin_obj_t *cs = validate_obj_is_free_pin(args[ARG_cs].u_obj, MP_QSTR_cs); - - sdcardio_sdcard_obj_t *self = mp_obj_malloc(sdcardio_sdcard_obj_t, &sdcardio_SDCard_type); - common_hal_sdcardio_sdcard_construct(self, spi, cs, args[ARG_baudrate].u_int); + sdcardio_sdcard_obj_t *self = mp_obj_malloc_with_finaliser(sdcardio_sdcard_obj_t, &sdcardio_SDCard_type); + common_hal_sdcardio_sdcard_construct(self, spi, args[ARG_cs].u_obj, args[ARG_baudrate].u_int); - return self; + return MP_OBJ_FROM_PTR(self); } @@ -85,8 +104,10 @@ static mp_obj_t sdcardio_sdcard_make_new(const mp_obj_type_t *type, size_t n_arg //| Due to technical limitations, this is a function and not a property. //| //| :return: The number of 512-byte blocks, as a number""" +//| static mp_obj_t sdcardio_sdcard_count(mp_obj_t self_in) { sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); return mp_obj_new_int_from_ull(common_hal_sdcardio_sdcard_get_blockcount(self)); } MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_count_obj, sdcardio_sdcard_count); @@ -95,6 +116,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_count_obj, sdcardio_sdcard_count); //| """Disable permanently. //| //| :return: None""" +//| static mp_obj_t sdcardio_sdcard_deinit(mp_obj_t self_in) { sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; common_hal_sdcardio_sdcard_deinit(self); @@ -110,12 +132,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_deinit_obj, sdcardio_sdcard_deinit); //| :param ~circuitpython_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512. //| //| :return: None""" +//| static mp_obj_t _sdcardio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); + uint32_t start_block = mp_obj_get_int(start_block_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; int result = common_hal_sdcardio_sdcard_readblocks(self, start_block, &bufinfo); if (result < 0) { mp_raise_OSError(-result); @@ -130,8 +155,10 @@ MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_readblocks_obj, _sdcardio_sdcard_readb //| //| :return: None""" //| ... +//| static mp_obj_t sdcardio_sdcard_sync(mp_obj_t self_in) { sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); int result = common_hal_sdcardio_sdcard_sync(self); if (result < 0) { mp_raise_OSError(-result); @@ -150,12 +177,15 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdcardio_sdcard_sync_obj, sdcardio_sdcard_sync); //| //| :return: None""" //| +//| static mp_obj_t _sdcardio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { + sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; + check_for_deinit(self); + uint32_t start_block = mp_obj_get_int(start_block_in); mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); - sdcardio_sdcard_obj_t *self = (sdcardio_sdcard_obj_t *)self_in; int result = common_hal_sdcardio_sdcard_writeblocks(self, start_block, &bufinfo); if (result < 0) { mp_raise_OSError(-result); @@ -167,6 +197,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(sdcardio_sdcard_writeblocks_obj, _sdcardio_sdcard_writ static const mp_rom_map_elem_t sdcardio_sdcard_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_count), MP_ROM_PTR(&sdcardio_sdcard_count_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sdcardio_sdcard_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&sdcardio_sdcard_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&sdcardio_sdcard_readblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_sync), MP_ROM_PTR(&sdcardio_sdcard_sync_obj) }, { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&sdcardio_sdcard_writeblocks_obj) }, diff --git a/shared-bindings/sdcardio/SDCard.h b/shared-bindings/sdcardio/SDCard.h index ac27b47aa4d..4251575f8fd 100644 --- a/shared-bindings/sdcardio/SDCard.h +++ b/shared-bindings/sdcardio/SDCard.h @@ -7,17 +7,20 @@ #pragma once +#include "py/mperrno.h" #include "shared-module/sdcardio/SDCard.h" extern const mp_obj_type_t sdcardio_SDCard_type; -void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, const mcu_pin_obj_t *cs, int baudrate); +void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *spi, mp_obj_t cs, int baudrate); void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self); +bool common_hal_sdcardio_sdcard_deinited(sdcardio_sdcard_obj_t *self); void common_hal_sdcardio_sdcard_check_for_deinit(sdcardio_sdcard_obj_t *self); +void common_hal_sdcardio_sdcard_mark_deinit(sdcardio_sdcard_obj_t *self); int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self); -int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); -int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self); -int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); +mp_negative_errno_t common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); +mp_negative_errno_t common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self); +mp_negative_errno_t common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf); // Used by native vfs blockdev. mp_uint_t sdcardio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen); diff --git a/shared-bindings/sdioio/SDCard.c b/shared-bindings/sdioio/SDCard.c index 98a9ef6c858..baf1e1660e8 100644 --- a/shared-bindings/sdioio/SDCard.c +++ b/shared-bindings/sdioio/SDCard.c @@ -55,15 +55,18 @@ //| sd = sdioio.SDCard( //| clock=board.SDIO_CLOCK, //| command=board.SDIO_COMMAND, -//| data=[board.SDIO_DATA], +//| # Note that board.SDIO_DATA is a tuple of four pins, not an individual pin. +//| data=board.SDIO_DATA, +//| # On some boards, the data pins are named individually. Use this line instead. +//| #data=(board.SDIO_DATA0, board.SDIO_DATA1, board.SDIO_DATA2, board.SDIO_DATA3), //| frequency=25000000) //| vfs = storage.VfsFat(sd) //| storage.mount(vfs, '/sd') //| os.listdir('/sd')""" //| ... +//| static mp_obj_t sdioio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - sdioio_sdcard_obj_t *self = mp_obj_malloc(sdioio_sdcard_obj_t, &sdioio_SDCard_type); enum { ARG_clock, ARG_command, ARG_data, ARG_frequency, NUM_ARGS }; static const mp_arg_t allowed_args[] = { { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_KW_ONLY | MP_ARG_OBJ }, @@ -82,6 +85,7 @@ static mp_obj_t sdioio_sdcard_make_new(const mp_obj_type_t *type, size_t n_args, uint8_t num_data; validate_list_is_free_pins(MP_QSTR_data, data_pins, MP_ARRAY_SIZE(data_pins), args[ARG_data].u_obj, &num_data); + sdioio_sdcard_obj_t *self = mp_obj_malloc(sdioio_sdcard_obj_t, &sdioio_SDCard_type); common_hal_sdioio_sdcard_construct(self, clock, command, num_data, data_pins, args[ARG_frequency].u_int); return MP_OBJ_FROM_PTR(self); } @@ -99,6 +103,7 @@ static void check_for_deinit(sdioio_sdcard_obj_t *self) { //| :param int width: the number of data lines to use. Must be 1 or 4 and must also not exceed the number of data lines at construction //| //| .. note:: Leaving a value unspecified or 0 means the current setting is kept""" +//| static mp_obj_t sdioio_sdcard_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_frequency, ARG_width, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -130,6 +135,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(sdioio_sdcard_configure_obj, 1, sdioio_sdcard_configu //| Due to technical limitations, this is a function and not a property. //| //| :return: The number of 512-byte blocks, as a number""" +//| static mp_obj_t sdioio_sdcard_count(mp_obj_t self_in) { sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -144,6 +150,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_count_obj, sdioio_sdcard_count); //| :param ~circuitpython_typing.WriteableBuffer buf: The buffer to write into. Length must be multiple of 512. //| //| :return: None""" +//| static mp_obj_t _sdioio_sdcard_readblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { uint32_t start_block = mp_obj_get_int(start_block_in); mp_buffer_info_t bufinfo; @@ -165,6 +172,7 @@ MP_DEFINE_CONST_FUN_OBJ_3(sdioio_sdcard_readblocks_obj, _sdioio_sdcard_readblock //| :param ~circuitpython_typing.ReadableBuffer buf: The buffer to read from. Length must be multiple of 512. //| //| :return: None""" +//| static mp_obj_t _sdioio_sdcard_writeblocks(mp_obj_t self_in, mp_obj_t start_block_in, mp_obj_t buf_in) { uint32_t start_block = mp_obj_get_int(start_block_in); mp_buffer_info_t bufinfo; @@ -194,6 +202,7 @@ MP_PROPERTY_GETTER(sdioio_sdcard_frequency_obj, //| width: int //| """The actual SDIO bus width, in bits""" +//| static mp_obj_t sdioio_sdcard_obj_get_width(mp_obj_t self_in) { sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -208,6 +217,7 @@ MP_PROPERTY_GETTER(sdioio_sdcard_width_obj, //| """Disable permanently. //| //| :return: None""" +//| static mp_obj_t sdioio_sdcard_obj_deinit(mp_obj_t self_in) { sdioio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_sdioio_sdcard_deinit(self); @@ -219,23 +229,20 @@ MP_DEFINE_CONST_FUN_OBJ_1(sdioio_sdcard_deinit_obj, sdioio_sdcard_obj_deinit); //| """No-op used by Context Managers. //| Provided by context manager helper.""" //| ... +//| //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... //| -static mp_obj_t sdioio_sdcard_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_sdioio_sdcard_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(sdioio_sdcard_obj___exit___obj, 4, 4, sdioio_sdcard_obj___exit__); +//| +// Provided by context manager helper. static const mp_rom_map_elem_t sdioio_sdcard_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&sdioio_sdcard_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&sdioio_sdcard_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&sdioio_sdcard_configure_obj) }, { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&sdioio_sdcard_frequency_obj) }, diff --git a/shared-bindings/sdioio/SDCard.h b/shared-bindings/sdioio/SDCard.h index dfeaf8fca89..042521aea50 100644 --- a/shared-bindings/sdioio/SDCard.h +++ b/shared-bindings/sdioio/SDCard.h @@ -7,6 +7,7 @@ #pragma once #include "py/obj.h" +#include "py/mperrno.h" #include "common-hal/microcontroller/Pin.h" #include "common-hal/sdioio/SDCard.h" @@ -35,9 +36,14 @@ uint8_t common_hal_sdioio_sdcard_get_width(sdioio_sdcard_obj_t *self); // Return number of device blocks uint32_t common_hal_sdioio_sdcard_get_count(sdioio_sdcard_obj_t *self); -// Read or write blocks -int common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); -int common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); +// Read or write blocks - returns 0 on success or negative error code from mperrno.h +mp_negative_errno_t common_hal_sdioio_sdcard_readblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); +mp_negative_errno_t common_hal_sdioio_sdcard_writeblocks(sdioio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *bufinfo); + +// Used by native vfs blockdev. +mp_negative_errno_t sdioio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen); +mp_negative_errno_t sdioio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t buflen); +bool sdioio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value); // This is used by the supervisor to claim SDIO devices indefinitely. extern void common_hal_sdioio_sdcard_never_reset(sdioio_sdcard_obj_t *self); diff --git a/shared-bindings/sdioio/__init__.c b/shared-bindings/sdioio/__init__.c index 45f1219f95a..d2e66f9633d 100644 --- a/shared-bindings/sdioio/__init__.c +++ b/shared-bindings/sdioio/__init__.c @@ -15,7 +15,7 @@ //| """Interface to an SD card via the SDIO bus""" static const mp_rom_map_elem_t sdioio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sdio) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_sdioio) }, { MP_ROM_QSTR(MP_QSTR_SDCard), MP_ROM_PTR(&sdioio_SDCard_type) }, }; diff --git a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c index 3dd4e2717e2..e1e2469e361 100644 --- a/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c +++ b/shared-bindings/sharpdisplay/SharpMemoryFramebuffer.c @@ -40,6 +40,7 @@ //| :param bool jdi_display: When True, work with an 8-color JDI display. Otherwise, a monochrome Sharp display. //| """ //| ... +//| static mp_obj_t sharpdisplay_framebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_spi_bus, ARG_chip_select, ARG_width, ARG_height, ARG_baudrate, ARG_jdi_display, NUM_ARGS }; static const mp_arg_t allowed_args[] = { @@ -83,6 +84,7 @@ static mp_int_t sharpdisplay_framebuffer_get_buffer(mp_obj_t self_in, mp_buffer_ //| may be performed.""" //| ... //| +//| static mp_obj_t sharpdisplay_framebuffer_deinit(mp_obj_t self_in) { sharpdisplay_framebuffer_obj_t *self = (sharpdisplay_framebuffer_obj_t *)self_in; common_hal_sharpdisplay_framebuffer_deinit(self); diff --git a/shared-bindings/socketpool/Socket.c b/shared-bindings/socketpool/Socket.c index 25d10c29482..35adb20bbfb 100644 --- a/shared-bindings/socketpool/Socket.c +++ b/shared-bindings/socketpool/Socket.c @@ -32,18 +32,21 @@ //| def __hash__(self) -> int: //| """Returns a hash for the Socket.""" //| ... +//| // Provided inherently. // See https://github.com/micropython/micropython/pull/10348. //| def __enter__(self) -> Socket: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically closes the Socket when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... +//| static mp_obj_t socketpool_socket___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_socketpool_socket_close(args[0]); @@ -55,6 +58,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket___exit___obj, 4, 4, //| """Accept a connection on a listening socket of type SOCK_STREAM, //| creating a new socket of type SOCK_STREAM. //| Returns a tuple of (new_socket, remote_address)""" +//| static mp_obj_t _socketpool_socket_accept(mp_obj_t self_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -70,6 +74,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_accept_obj, _socketpool_socke //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... +//| static mp_obj_t socketpool_socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -94,6 +99,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_bind_obj, socketpool_socket_b //| def close(self) -> None: //| """Closes this Socket and makes its resources available to its SocketPool.""" +//| static mp_obj_t _socketpool_socket_close(mp_obj_t self_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_socketpool_socket_close(self); @@ -106,6 +112,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(socketpool_socket_close_obj, _socketpool_socket //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... +//| static mp_obj_t socketpool_socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -130,6 +137,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_connect_obj, socketpool_socke //| //| :param ~int backlog: length of backlog queue for waiting connections""" //| ... +//| static mp_obj_t socketpool_socket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -149,6 +157,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_listen_obj, socketpool_socket //| //| :param object buffer: buffer to read into""" //| ... +//| static mp_obj_t socketpool_socket_recvfrom_into(mp_obj_t self_in, mp_obj_t data_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_buffer_info_t bufinfo; @@ -174,6 +183,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_recvfrom_into_obj, socketpool //| :param bytearray buffer: buffer to receive into //| :param int bufsize: optionally, a maximum number of bytes to read.""" //| ... +//| static mp_obj_t _socketpool_socket_recv_into(size_t n_args, const mp_obj_t *args) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (common_hal_socketpool_socket_get_closed(self)) { @@ -212,6 +222,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_recv_into_obj, 2, 3 //| //| :param ~bytes bytes: some bytes to send""" //| ... +//| static mp_obj_t _socketpool_socket_send(mp_obj_t self_in, mp_obj_t buf_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_socketpool_socket_get_closed(self)) { @@ -241,6 +252,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_send_obj, _socketpool_socket_ //| //| :param ~bytes bytes: some bytes to send""" //| ... +//| static mp_obj_t _socketpool_socket_sendall(mp_obj_t self_in, mp_obj_t buf_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_socketpool_socket_get_closed(self)) { @@ -278,6 +290,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_sendall_obj, _socketpool_sock //| :param ~bytes bytes: some bytes to send //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... +//| static mp_obj_t socketpool_socket_sendto(mp_obj_t self_in, mp_obj_t data_in, mp_obj_t addr_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -306,6 +319,7 @@ static MP_DEFINE_CONST_FUN_OBJ_3(socketpool_socket_sendto_obj, socketpool_socket //| //| :param ~bool flag: False means non-blocking, True means block indefinitely.""" //| ... +//| // method socket.setblocking(flag) static mp_obj_t socketpool_socket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -321,6 +335,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_setblocking_obj, socketpool_s //| def setsockopt(self, level: int, optname: int, value: int) -> None: //| """Sets socket options""" //| ... +//| static mp_obj_t socketpool_socket_setsockopt(size_t n_args, const mp_obj_t *args) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(args[0]); mp_int_t level = mp_obj_get_int(args[1]); @@ -356,6 +371,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(socketpool_socket_setsockopt_obj, 4, //| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. //| """ //| ... +//| static mp_obj_t socketpool_socket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t timeout_ms; @@ -376,6 +392,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(socketpool_socket_settimeout_obj, socketpool_so //| type: int //| """Read-only access to the socket type""" //| +//| static mp_obj_t socketpool_socket_obj_get_type(mp_obj_t self_in) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_socketpool_socket_get_type(self)); @@ -429,7 +446,7 @@ static mp_uint_t socket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, return ret; } -static mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +static mp_uint_t socket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { socketpool_socket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; if (request == MP_STREAM_POLL) { diff --git a/shared-bindings/socketpool/Socket.h b/shared-bindings/socketpool/Socket.h index a883ebd5054..295f86e7371 100644 --- a/shared-bindings/socketpool/Socket.h +++ b/shared-bindings/socketpool/Socket.h @@ -6,6 +6,7 @@ #pragma once +#include "py/mperrno.h" #include "common-hal/socketpool/Socket.h" extern const mp_obj_type_t socketpool_socket_type; diff --git a/shared-bindings/socketpool/SocketPool.c b/shared-bindings/socketpool/SocketPool.c index b37d02dc57a..f50a7a5fcfe 100644 --- a/shared-bindings/socketpool/SocketPool.c +++ b/shared-bindings/socketpool/SocketPool.c @@ -24,21 +24,20 @@ //| a pool of sockets provided by the underlying OS. //| """ //| -//| def __init__(self, radio: wifi.Radio) -> None: +//| def __init__(self, radio: Union[wifi.Radio, hostnetwork.HostNetwork]) -> None: //| """Create a new SocketPool object for the provided radio //| -//| :param wifi.Radio radio: The (connected) network hardware to associate -//| with this SocketPool; currently, this will always be the object -//| returned by :py:attr:`wifi.radio` +//| :param radio: The (connected) network interface to associate with this +//| SocketPool, such as :py:attr:`wifi.radio` or :py:attr:`board.NETWORK`. //| """ //| ... //| static mp_obj_t socketpool_socketpool_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 1, 1, false); - socketpool_socketpool_obj_t *s = mp_obj_malloc_with_finaliser(socketpool_socketpool_obj_t, &socketpool_socketpool_type); mp_obj_t radio = args[0]; + socketpool_socketpool_obj_t *s = mp_obj_malloc_with_finaliser(socketpool_socketpool_obj_t, &socketpool_socketpool_type); common_hal_socketpool_socketpool_construct(s, radio); return MP_OBJ_FROM_PTR(s); @@ -86,6 +85,7 @@ MP_DEFINE_EXCEPTION(gaierror, OSError) //| in CPython is not supported. //| """ //| ... +//| static mp_obj_t socketpool_socketpool_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_family, ARG_type, ARG_proto }; static const mp_arg_t allowed_args[] = { @@ -102,10 +102,6 @@ static mp_obj_t socketpool_socketpool_socket(size_t n_args, const mp_obj_t *pos_ socketpool_socketpool_sock_t type = args[ARG_type].u_int; socketpool_socketpool_ipproto_t proto = args[ARG_proto].u_int; - if (proto < 0) { - proto = 0; - } - return common_hal_socketpool_socket(self, family, type, proto); } MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_socket_obj, 1, socketpool_socketpool_socket); @@ -126,6 +122,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(socketpool_socketpool_socket_obj, 1, socketpool_socke //| as a tuple.""" //| ... //| +//| static mp_obj_t socketpool_socketpool_getaddrinfo(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_host, ARG_port, ARG_family, ARG_type, ARG_proto, ARG_flags }; static const mp_arg_t allowed_args[] = { @@ -192,16 +189,28 @@ MP_DEFINE_CONST_OBJ_TYPE( locals_dict, &socketpool_socketpool_locals_dict ); -MP_WEAK NORETURN -void common_hal_socketpool_socketpool_raise_gaierror_noname(void) { +MP_WEAK MP_NORETURN +void common_hal_socketpool_socketpool_raise_gaierror(int err) { vstr_t vstr; mp_print_t print; vstr_init_print(&vstr, 64, &print); - mp_printf(&print, "%S", MP_ERROR_TEXT("Name or service not known")); + // Only EAI_NONAME means the name was not found. Other codes cover + // unrelated failures, such as an unsupported family, so use the generic + // message for those rather than one that would be misleading. + if (err == SOCKETPOOL_EAI_NONAME) { + mp_printf(&print, "%S", MP_ERROR_TEXT("Name or service not known")); + } else { + mp_cprintf(&print, MP_ERROR_TEXT("%q failure: %d"), MP_QSTR_getaddrinfo, err); + } mp_obj_t exc_args[] = { - MP_OBJ_NEW_SMALL_INT(SOCKETPOOL_EAI_NONAME), + MP_OBJ_NEW_SMALL_INT(err), mp_obj_new_str_from_vstr(&vstr), }; nlr_raise(mp_obj_new_exception_args(&mp_type_gaierror, MP_ARRAY_SIZE(exc_args), exc_args)); } + +MP_WEAK MP_NORETURN +void common_hal_socketpool_socketpool_raise_gaierror_noname(void) { + common_hal_socketpool_socketpool_raise_gaierror(SOCKETPOOL_EAI_NONAME); +} diff --git a/shared-bindings/socketpool/SocketPool.h b/shared-bindings/socketpool/SocketPool.h index 36035ed00e1..1d0a3bbccff 100644 --- a/shared-bindings/socketpool/SocketPool.h +++ b/shared-bindings/socketpool/SocketPool.h @@ -25,6 +25,7 @@ bool socketpool_socket(socketpool_socketpool_obj_t *self, socketpool_socketpool_addressfamily_t family, socketpool_socketpool_sock_t type, int proto, socketpool_socket_obj_t *sock); -NORETURN void common_hal_socketpool_socketpool_raise_gaierror_noname(void); +MP_NORETURN void common_hal_socketpool_socketpool_raise_gaierror_noname(void); +MP_NORETURN void common_hal_socketpool_socketpool_raise_gaierror(int err); mp_obj_t common_hal_socketpool_getaddrinfo_raise(socketpool_socketpool_obj_t *self, const char *host, int port, int family, int type, int proto, int flags); diff --git a/shared-bindings/spitarget/SPITarget.c b/shared-bindings/spitarget/SPITarget.c new file mode 100644 index 00000000000..08f6d554f3a --- /dev/null +++ b/shared-bindings/spitarget/SPITarget.c @@ -0,0 +1,190 @@ +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/spitarget/SPITarget.h" +#include "shared-bindings/time/__init__.h" +#include "shared-bindings/util.h" + +#include "shared/runtime/buffer_helper.h" +#include "shared/runtime/context_manager_helpers.h" +#include "shared/runtime/interrupt_char.h" + +#include "py/mperrno.h" +#include "py/mphal.h" +#include "py/obj.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +//| class SPITarget: +//| """Serial Peripheral Interface protocol target""" +//| +//| def __init__( +//| self, +//| sck: microcontroller.Pin, +//| mosi: microcontroller.Pin, +//| miso: microcontroller.Pin, +//| ss: microcontroller.Pin, +//| ) -> None: +//| """SPI is a four-wire protocol for communicating between devices. +//| This implements the secondary (aka target or peripheral) side. +//| +//| :param ~microcontroller.Pin sck: The SPI clock pin +//| :param ~microcontroller.Pin mosi: The pin transferring data from the main to the secondary +//| :param ~microcontroller.Pin miso: The pin transferring data from the secondary to the main +//| :param ~microcontroller.Pin ss: The secondary selection pin""" +//| ... +//| +static mp_obj_t spitarget_spi_target_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_sck, ARG_mosi, ARG_miso, ARG_ss }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sck, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_mosi, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_miso, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_ss, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mcu_pin_obj_t *sck = validate_obj_is_free_pin(args[ARG_sck].u_obj, MP_QSTR_sck); + const mcu_pin_obj_t *mosi = validate_obj_is_free_pin(args[ARG_mosi].u_obj, MP_QSTR_mosi); + const mcu_pin_obj_t *miso = validate_obj_is_free_pin(args[ARG_miso].u_obj, MP_QSTR_miso); + const mcu_pin_obj_t *ss = validate_obj_is_free_pin(args[ARG_ss].u_obj, MP_QSTR_ss); + + spitarget_spi_target_obj_t *self = mp_obj_malloc(spitarget_spi_target_obj_t, &spitarget_spi_target_type); + common_hal_spitarget_spi_target_construct(self, sck, mosi, miso, ss); + + return MP_OBJ_FROM_PTR(self); +} + +//| def deinit(self) -> None: +//| """Releases control of the underlying hardware so other classes can use it.""" +//| ... +//| +static mp_obj_t spitarget_spi_target_obj_deinit(mp_obj_t self_in) { + mp_check_self(mp_obj_is_type(self_in, &spitarget_spi_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_spitarget_spi_target_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(spitarget_spi_target_deinit_obj, spitarget_spi_target_obj_deinit); + +//| def __enter__(self) -> SPITarget: +//| """No-op used in Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware on context exit. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +static mp_obj_t spitarget_spi_target_obj___exit__(size_t n_args, const mp_obj_t *args) { + mp_check_self(mp_obj_is_type(args[0], &spitarget_spi_target_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(args[0]); + common_hal_spitarget_spi_target_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(spitarget_spi_target___exit___obj, 4, 4, spitarget_spi_target_obj___exit__); + +//| def load_packet(self, mosi_packet: bytearray, miso_packet: bytearray) -> None: +//| """Queue data for the next SPI transfer from the main device. +//| If a packet has already been queued for this SPI bus but has not yet been transferred, an error will be raised. +//| +//| :param bytearray miso_packet: Packet data to be sent from secondary to main on next request. +//| :param bytearray mosi_packet: Packet to be filled with data from main on next request. +//| """ +//| +static mp_obj_t spitarget_spi_target_load_packet(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(mp_obj_is_type(pos_args[0], &spitarget_spi_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (common_hal_spitarget_spi_target_deinited(self)) { + raise_deinited_error(); + } + enum { ARG_mosi_packet, ARG_miso_packet }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_mosi_packet, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_miso_packet, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t mosi_bufinfo; + mp_get_buffer_raise(args[ARG_mosi_packet].u_obj, &mosi_bufinfo, MP_BUFFER_WRITE); + + mp_buffer_info_t miso_bufinfo; + mp_get_buffer_raise(args[ARG_miso_packet].u_obj, &miso_bufinfo, MP_BUFFER_READ); + + if (miso_bufinfo.len != mosi_bufinfo.len) { + mp_raise_ValueError(MP_ERROR_TEXT("Packet buffers for an SPI transfer must have the same length.")); + } + + common_hal_spitarget_spi_target_transfer_start(self, ((uint8_t *)mosi_bufinfo.buf), ((uint8_t *)miso_bufinfo.buf), mosi_bufinfo.len); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(spitarget_spi_target_load_packet_obj, 1, spitarget_spi_target_load_packet); + +//| def wait_transfer(self, *, timeout: float = -1) -> bool: +//| """Wait for an SPI transfer from the main device. +//| +//| :param float timeout: Timeout in seconds. Zero means wait forever, a negative value means check once +//| :return: True if the transfer is complete, or False if no response received before the timeout +//| """ +//| +//| +static mp_obj_t spitarget_spi_target_wait_transfer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + mp_check_self(mp_obj_is_type(pos_args[0], &spitarget_spi_target_type)); + spitarget_spi_target_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + if (common_hal_spitarget_spi_target_deinited(self)) { + raise_deinited_error(); + } + enum { ARG_timeout }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NEW_SMALL_INT(-1)} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + #if MICROPY_PY_BUILTINS_FLOAT + float f = mp_obj_get_float(args[ARG_timeout].u_obj) * 1000; + int timeout_ms = (int)f; + #else + int timeout_ms = mp_obj_get_int(args[ARG_timeout].u_obj) * 1000; + #endif + + bool forever = false; + uint64_t timeout_end = 0; + if (timeout_ms == 0) { + forever = true; + } else if (timeout_ms > 0) { + timeout_end = common_hal_time_monotonic_ms() + timeout_ms; + } + + do { + if (common_hal_spitarget_spi_target_transfer_is_finished(self)) { + common_hal_spitarget_spi_target_transfer_close(self); // implicitly discards error indicator code + return mp_const_true; + } + mp_hal_delay_us(10); + } while (forever || common_hal_time_monotonic_ms() < timeout_end); + + return mp_const_false; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(spitarget_spi_target_wait_transfer_obj, 1, spitarget_spi_target_wait_transfer); + +static const mp_rom_map_elem_t spitarget_spi_target_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&spitarget_spi_target_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&spitarget_spi_target___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_load_packet), MP_ROM_PTR(&spitarget_spi_target_load_packet_obj) }, + { MP_ROM_QSTR(MP_QSTR_wait_transfer), MP_ROM_PTR(&spitarget_spi_target_wait_transfer_obj) }, + +}; + +static MP_DEFINE_CONST_DICT(spitarget_spi_target_locals_dict, spitarget_spi_target_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + spitarget_spi_target_type, + MP_QSTR_SPITarget, + MP_TYPE_FLAG_NONE, + make_new, spitarget_spi_target_make_new, + locals_dict, &spitarget_spi_target_locals_dict + ); diff --git a/shared-bindings/spitarget/SPITarget.h b/shared-bindings/spitarget/SPITarget.h new file mode 100644 index 00000000000..a8501976a7f --- /dev/null +++ b/shared-bindings/spitarget/SPITarget.h @@ -0,0 +1,21 @@ +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_TARGET_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_TARGET_H + +#include "py/obj.h" + +#include "common-hal/microcontroller/Pin.h" +#include "common-hal/spitarget/SPITarget.h" + +extern const mp_obj_type_t spitarget_spi_target_type; + +extern void common_hal_spitarget_spi_target_construct(spitarget_spi_target_obj_t *self, + const mcu_pin_obj_t *sck, const mcu_pin_obj_t *mosi, const mcu_pin_obj_t *miso, const mcu_pin_obj_t *ss); +extern void common_hal_spitarget_spi_target_deinit(spitarget_spi_target_obj_t *self); +extern bool common_hal_spitarget_spi_target_deinited(spitarget_spi_target_obj_t *self); + +extern void common_hal_spitarget_spi_target_transfer_start(spitarget_spi_target_obj_t *self, + uint8_t *mosi_packet, const uint8_t *miso_packet, size_t len); +extern bool common_hal_spitarget_spi_target_transfer_is_finished(spitarget_spi_target_obj_t *self); +extern int common_hal_spitarget_spi_target_transfer_close(spitarget_spi_target_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_TARGET_H diff --git a/shared-bindings/spitarget/__init__.c b/shared-bindings/spitarget/__init__.c new file mode 100644 index 00000000000..0fcf90ea34b --- /dev/null +++ b/shared-bindings/spitarget/__init__.c @@ -0,0 +1,89 @@ +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/spitarget/SPITarget.h" + +#include "py/runtime.h" + +//| """Serial Peripheral Interface protocol target +//| +//| The `spitarget` module contains classes to support an SPI target. +//| +//| Example that emulates an SPI analog-to-digital converter:: +//| +//| import board +//| import analogio +//| from spitarget import SPITarget +//| +//| ain0 = analogio.AnalogIn(board.A0) +//| ain1 = analogio.AnalogIn(board.A1) +//| selected_channel = ain0 +//| +//| def map_adc_channel(index): +//| return ain0 if (index == 0) else ain1 +//| +//| mosi_buffer = bytearray(2) +//| miso_buffer = bytearray(2) +//| with SPITarget(sck=board.D12, mosi=board.D13, miso=board.D11, ss=board.D10) as device: +//| while True: +//| # Convert analog signal to array of bytes +//| reading = selected_channel.value +//| miso_buffer[0] = (reading >> 8) & 0xFF +//| miso_buffer[1] = (reading) & 0xFF +//| # Send array of bytes over SPI to main +//| device.load_packet(mosi_buffer, miso_buffer) +//| while not device.wait_transfer(timeout=-1): +//| pass +//| # Handle command from main, which sets the ADC channel +//| selected_channel = map_adc_channel((mosi_buffer[0] << 8) | mosi_buffer[1]) +//| +//| Communicating with the ADC emulator from the REPL of an attached CircuitPython board might look like :: +//| +//| >>> import board +//| >>> import digitalio +//| >>> import busio +//| >>> import time +//| >>> +//| >>> ## setup +//| >>> spi = busio.SPI(board.SCK, board.MOSI, board.MISO) +//| >>> cs = digitalio.DigitalInOut(board.CS) +//| >>> cs.direction = digitalio.Direction.OUTPUT +//| >>> cs.value = True +//| >>> spi.try_lock() +//| True +//| >>> +//| >>> ## ADC command: read from A0 +//| >>> cs.value = False +//| >>> spi.write(bytearray([0, 0])) +//| >>> cs.value = True +//| >>> +//| >>> # wait for ADC to read a value +//| >>> +//| >>> ## get two-byte output from ADC +//| >>> adc_result = bytearray(2) +//| >>> cs.value = False +//| >>> spi.readinto(adc_result, write_value=1) +//| >>> cs.value = True +//| >>> list(adc_result) +//| [0, 255] +//| +//| """ + + + +static const mp_rom_map_elem_t spitarget_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_spitarget) }, + { MP_ROM_QSTR(MP_QSTR_SPITarget), MP_ROM_PTR(&spitarget_spi_target_type) }, +}; + +static MP_DEFINE_CONST_DICT(spitarget_module_globals, spitarget_module_globals_table); + +const mp_obj_module_t spitarget_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&spitarget_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_spitarget, spitarget_module); diff --git a/shared-bindings/ssl/SSLContext.c b/shared-bindings/ssl/SSLContext.c index 9c7f098cc4a..9546c50ed7c 100644 --- a/shared-bindings/ssl/SSLContext.c +++ b/shared-bindings/ssl/SSLContext.c @@ -26,7 +26,6 @@ static mp_obj_t ssl_sslcontext_make_new(const mp_obj_type_t *type, size_t n_args mp_arg_check_num(n_args, n_kw, 0, 1, false); ssl_sslcontext_obj_t *s = mp_obj_malloc(ssl_sslcontext_obj_t, &ssl_sslcontext_type); - common_hal_ssl_sslcontext_construct(s); return MP_OBJ_FROM_PTR(s); @@ -40,6 +39,7 @@ static mp_obj_t ssl_sslcontext_make_new(const mp_obj_type_t *type, size_t n_args //| needed to establish the certificate's authenticity. The keyfile string //| must point to a file containing the private key. //| """ +//| static void get_file_contents(mp_obj_t name_obj, mp_buffer_info_t *bufinfo) { mp_obj_t file = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), name_obj, MP_OBJ_NEW_QSTR(MP_QSTR_rb)); @@ -88,6 +88,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_load_cert_chain_obj, 1, ssl_ssl //| :param str cadata: A single CA certificate in PEM format. **Limitation**: CPython allows one //| or more certificates, but this implementation is limited to one. //| """ +//| static mp_obj_t ssl_sslcontext_load_verify_locations(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_cafile, ARG_capath, ARG_cadata }; static const mp_arg_t allowed_args[] = { @@ -117,6 +118,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_load_verify_locations_obj, 1, s //| def set_default_verify_paths(self) -> None: //| """Load a set of default certification authority (CA) certificates.""" +//| static mp_obj_t ssl_sslcontext_set_default_verify_paths(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { ssl_sslcontext_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -128,6 +130,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(ssl_sslcontext_set_default_verify_paths_obj, 1 //| check_hostname: bool //| """Whether to match the peer certificate's hostname.""" +//| static mp_obj_t ssl_sslcontext_get_check_hostname(mp_obj_t self_in) { ssl_sslcontext_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -153,11 +156,12 @@ MP_PROPERTY_GETSET(ssl_sslcontext_check_hostname_obj, //| sock: socketpool.Socket, //| *, //| server_side: bool = False, -//| server_hostname: Optional[str] = None +//| server_hostname: Optional[str] = None, //| ) -> ssl.SSLSocket: //| """Wraps the socket into a socket-compatible class that handles SSL negotiation. //| The socket must be of type SOCK_STREAM.""" //| +//| static mp_obj_t ssl_sslcontext_wrap_socket(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_sock, ARG_server_side, ARG_server_hostname }; diff --git a/shared-bindings/ssl/SSLSocket.c b/shared-bindings/ssl/SSLSocket.c index 3ed4fa36624..98f67878d04 100644 --- a/shared-bindings/ssl/SSLSocket.c +++ b/shared-bindings/ssl/SSLSocket.c @@ -29,18 +29,21 @@ //| def __hash__(self) -> int: //| """Returns a hash for the Socket.""" //| ... +//| // Provided by automatic inclusion of hash() // https://github.com/micropython/micropython/pull/10348 //| def __enter__(self) -> SSLSocket: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically closes the Socket when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... +//| static mp_obj_t ssl_sslsocket___exit__(size_t n_args, const mp_obj_t *args) { (void)n_args; common_hal_ssl_sslsocket_close(args[0]); @@ -52,6 +55,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket___exit___obj, 4, 4, ssl //| """Accept a connection on a listening socket of type SOCK_STREAM, //| creating a new socket of type SOCK_STREAM. //| Returns a tuple of (new_socket, remote_address)""" +//| static mp_obj_t ssl_sslsocket_accept(mp_obj_t self_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); return common_hal_ssl_sslsocket_accept(self); @@ -63,6 +67,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_accept_obj, ssl_sslsocket_accept) //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... +//| static mp_obj_t ssl_sslsocket_bind(mp_obj_t self_in, mp_obj_t addr_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -76,6 +81,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_bind_obj, ssl_sslsocket_bind); //| def close(self) -> None: //| """Closes this Socket""" +//| static mp_obj_t ssl_sslsocket_close(mp_obj_t self_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_ssl_sslsocket_close(self); @@ -88,6 +94,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(ssl_sslsocket_close_obj, ssl_sslsocket_close); //| //| :param ~tuple address: tuple of (remote_address, remote_port)""" //| ... +//| static mp_obj_t ssl_sslsocket_connect(mp_obj_t self_in, mp_obj_t addr_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_ssl_sslsocket_connect(self, addr_in); @@ -99,8 +106,9 @@ static MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_connect_obj, ssl_sslsocket_connec //| def listen(self, backlog: int) -> None: //| """Set socket to listen for incoming connections //| -//| :param ~int backlog: length of backlog queue for waiting connetions""" +//| :param ~int backlog: length of backlog queue for waiting connections""" //| ... +//| static mp_obj_t ssl_sslsocket_listen(mp_obj_t self_in, mp_obj_t backlog_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -124,6 +132,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_listen_obj, ssl_sslsocket_listen) //| :param bytearray buffer: buffer to receive into //| :param int bufsize: optionally, a maximum number of bytes to read.""" //| ... +//| static mp_obj_t ssl_sslsocket_recv_into(size_t n_args, const mp_obj_t *args) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(args[0]); if (common_hal_ssl_sslsocket_get_closed(self)) { @@ -162,6 +171,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket_recv_into_obj, 2, 3, ss //| //| :param ~bytes bytes: some bytes to send""" //| ... +//| static mp_obj_t ssl_sslsocket_send(mp_obj_t self_in, mp_obj_t buf_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_ssl_sslsocket_get_closed(self)) { @@ -204,6 +214,7 @@ static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(ssl_sslsocket_setsockopt_obj, 4, 4, s //| :param ~int value: timeout in seconds. 0 means non-blocking. None means block indefinitely. //| """ //| ... +//| static mp_obj_t ssl_sslsocket_settimeout(mp_obj_t self_in, mp_obj_t timeout_in) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_ssl_sslsocket_settimeout(self, timeout_in); @@ -217,6 +228,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(ssl_sslsocket_settimeout_obj, ssl_sslsocket_set //| :param ~bool flag: False means non-blocking, True means block indefinitely.""" //| ... //| +//| // method socket.setblocking(flag) static mp_obj_t ssl_sslsocket_setblocking(mp_obj_t self_in, mp_obj_t blocking) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -279,7 +291,7 @@ static mp_uint_t sslsocket_write(mp_obj_t self_in, const void *buf, mp_uint_t si return readwrite_common(self_in, common_hal_ssl_sslsocket_send, buf, size, errorcode); } -static mp_uint_t sslsocket_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +static mp_uint_t sslsocket_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { ssl_sslsocket_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; if (request == MP_STREAM_POLL) { diff --git a/shared-bindings/ssl/__init__.c b/shared-bindings/ssl/__init__.c index 9a5f94636a8..51a3ad3cfc4 100644 --- a/shared-bindings/ssl/__init__.c +++ b/shared-bindings/ssl/__init__.c @@ -17,17 +17,19 @@ //| |see_cpython_module| :mod:`cpython:ssl`. //| """ //| +//| //| def create_default_context() -> ssl.SSLContext: //| """Return the default SSLContext.""" //| ... //| +//| static mp_obj_t ssl_create_default_context(void) { ssl_sslcontext_obj_t *s = mp_obj_malloc(ssl_sslcontext_obj_t, &ssl_sslcontext_type); - common_hal_ssl_create_default_context(s); - return s; + + return MP_OBJ_FROM_PTR(s); } MP_DEFINE_CONST_FUN_OBJ_0(ssl_create_default_context_obj, ssl_create_default_context); diff --git a/shared-bindings/storage/__init__.c b/shared-bindings/storage/__init__.c index e046c118797..b5f19529be1 100644 --- a/shared-bindings/storage/__init__.c +++ b/shared-bindings/storage/__init__.c @@ -27,6 +27,7 @@ //| `_. //| """ //| +//| //| def mount(filesystem: VfsFat, mount_path: str, *, readonly: bool = False) -> None: //| """Mounts the given filesystem object at the given path. //| @@ -38,6 +39,7 @@ //| """ //| ... //| +//| static mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_filesystem, ARG_mount_path, ARG_readonly }; static const mp_arg_t allowed_args[] = { @@ -52,15 +54,11 @@ static mp_obj_t storage_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t // get the mount point const char *mnt_str = mp_obj_str_get_str(args[ARG_mount_path].u_obj); - // Make sure we're given an object we can mount. - // TODO(tannewt): Make sure we have all the methods we need to operating it - // as a file system. + mp_obj_t vfs_obj = args[ARG_filesystem].u_obj; - mp_obj_t dest[2]; - mp_load_method_maybe(vfs_obj, MP_QSTR_mount, dest); - if (dest[0] == MP_OBJ_NULL) { - mp_raise_ValueError(MP_ERROR_TEXT("filesystem must provide mount method")); - } + + // Currently, the only supported filesystem is VfsFat. + mp_arg_validate_type(vfs_obj, &mp_fat_vfs_type, MP_QSTR_filesystem); common_hal_storage_mount(vfs_obj, mnt_str, args[ARG_readonly].u_bool); @@ -75,6 +73,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(storage_mount_obj, 0, storage_mount); //| This is the CircuitPython analog to the UNIX ``umount`` command.""" //| ... //| +//| static mp_obj_t storage_umount(mp_obj_t mnt_in) { if (mp_obj_is_str(mnt_in)) { common_hal_storage_umount_path(mp_obj_str_get_str(mnt_in)); @@ -90,10 +89,18 @@ MP_DEFINE_CONST_FUN_OBJ_1(storage_umount_obj, storage_umount); //| mount_path: str, //| readonly: bool = False, //| *, -//| disable_concurrent_write_protection: bool = False +//| disable_concurrent_write_protection: bool = False, //| ) -> None: //| """Remounts the given path with new parameters. //| +//| This can always be done from ``boot.py``. After boot, it can only be done when the host computer +//| doesn't have write access and CircuitPython isn't currently writing to the filesystem. An +//| exception will be raised if this is the case. Some host OSes allow you to eject a drive which +//| will allow for remounting. +//| +//| Remounting after USB is active may take a little time because it "ejects" the drive for one +//| query from the host. These queries happen every second or so. +//| //| :param str mount_path: The path to remount. //| :param bool readonly: True when the filesystem should be readonly to CircuitPython. //| :param bool disable_concurrent_write_protection: When True, the check that makes sure the @@ -102,6 +109,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(storage_umount_obj, storage_umount); //| filesystem will be corrupted.""" //| ... //| +//| static mp_obj_t storage_remount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_mount_path, ARG_readonly, ARG_disable_concurrent_write_protection }; static const mp_arg_t allowed_args[] = { @@ -125,33 +133,35 @@ MP_DEFINE_CONST_FUN_OBJ_KW(storage_remount_obj, 0, storage_remount); //| """Retrieves the mount object associated with the mount path""" //| ... //| +//| static mp_obj_t storage_getmount(const mp_obj_t mnt_in) { return common_hal_storage_getmount(mp_obj_str_get_str(mnt_in)); } MP_DEFINE_CONST_FUN_OBJ_1(storage_getmount_obj, storage_getmount); //| def erase_filesystem(extended: Optional[bool] = None) -> None: -//| """Erase and re-create the ``CIRCUITPY`` filesystem. +//| """Erase and re-create the **CIRCUITPY** filesystem. //| -//| On boards that present USB-visible ``CIRCUITPY`` drive (e.g., SAMD21 and SAMD51), +//| On boards that present USB-visible **CIRCUITPY** drive (e.g., SAMD21 and SAMD51), //| then call `microcontroller.reset()` to restart CircuitPython and have the -//| host computer remount CIRCUITPY. +//| host computer remount **CIRCUITPY**. //| -//| This function can be called from the REPL when ``CIRCUITPY`` +//| This function can be called from the REPL when **CIRCUITPY** //| has become corrupted. //| //| :param bool extended: On boards that support ``dualbank`` module -//| and the ``extended`` parameter, the ``CIRCUITPY`` storage can be +//| and the ``extended`` parameter, the **CIRCUITPY** storage can be //| extended by setting this to `True`. If this isn't provided or //| set to `None` (default), the existing configuration will be used. //| //| .. note:: New firmware starts with storage extended. In case of an existing //| filesystem (e.g. uf2 load), the existing extension setting is preserved. //| -//| .. warning:: All the data on ``CIRCUITPY`` will be lost, and +//| .. warning:: All the data on **CIRCUITPY** will be lost, and //| CircuitPython will restart on certain boards.""" //| ... //| +//| static mp_obj_t storage_erase_filesystem(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_extended }; @@ -177,11 +187,14 @@ static mp_obj_t storage_erase_filesystem(size_t n_args, const mp_obj_t *pos_args MP_DEFINE_CONST_FUN_OBJ_KW(storage_erase_filesystem_obj, 0, storage_erase_filesystem); //| def disable_usb_drive() -> None: -//| """Disable presenting ``CIRCUITPY`` as a USB mass storage device. -//| By default, the device is enabled and ``CIRCUITPY`` is visible. -//| Can be called in ``boot.py``, before USB is connected.""" +//| """Disable presenting **CIRCUITPY** as a USB mass storage device. +//| By default, the device is enabled and **CIRCUITPY** is visible, if USB is available. +//| Must called in ``boot.py``, before USB is connected. +// If you want to disable the USB drive after `boot.py` has run, see `unsafe_disable_usb_drive()`. +//| """ //| ... //| +//| static mp_obj_t storage_disable_usb_drive(void) { #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC if (!common_hal_storage_disable_usb_drive()) { @@ -194,19 +207,87 @@ static mp_obj_t storage_disable_usb_drive(void) { } MP_DEFINE_CONST_FUN_OBJ_0(storage_disable_usb_drive_obj, storage_disable_usb_drive); +//| def unsafe_disable_usb_drive() -> None: +//| """Disable presenting **CIRCUITPY** as a USB mass storage device even if in use. +//| By default, the device is enabled and **CIRCUITPY** is visible. +//| After the call, **CIRCUITPY** will be read/write to your code and from the REPL but not appear over USB. +//| +//| Unlike `disable_usb_drive()`, `unsafe_disable_usb_drive()` can be called +//| after ``code.py`` starts or from the REPL, after USB has started. +//| +//| .. warning:: If ``unsafe_disable_usb_drive()`` is called when the host is in the middle of writing **CIRCUITPY**, +//| filesystem corruption can occur. +//| It is similar to the sudden physical removal of a USB drive. +//| Before calling ``unsafe_disable_usb_drive()``, +//| make sure the host has finished any writes to **CIRCUITPY**. +//| +//| * On Windows, do one of these: +//| +//| * Eject ("Safely Remove") the **CIRCUITPY** drive. +//| * Use a "sync" program, such as `Sysinternals Sync `__. +//| * Programmatically call ``_commit()`` or ``_flushall()`` or similar. +//| +//| * On Linux or macOS, do one of these: +//| +//| * Eject (unmount) the **CIRCUITPY** drive. +//| * Type ``sync`` in a terminal. +//| * Programmatically call ``sync()`` or ``fsync()``. +//| +//| * If none of the above are possible or convenient, wait several seconds to allow any writes to complete. +//| This can be unreliable, as the interval to wait depends on the host operating system +//| and how the drive is mounted. +//| In some operating systems, you can specify that the drive be mounted as "sync on write", +//| so that all writes happen immediately. +//| +//| When `unsafe_disable_usb_drive()` is called after USB has started, +//| the **CIRCUITPY** USB drive logical unit (LUN) will report as "not ready", +//| causing the host to unmount it. +//| The drive can be made ready and available again by calling `enable_usb_drive()`. +//| When `disable_usb_drive` is called after ``code.py`` starts or in the REPL, +//| the call will delay 2.5 seconds before returning, +//| so that host has time to detect that the drive is not ready. +//| The host polls the device approximately every one or two seconds. +//| +//| When the USB drive is disabled, **CIRCUITPY** becomes read/write, and can be written +//| from user code or the REPL. This is easier than arranging for a `remount()` in ``boot.py``. +//| Code editors and file uploaders can use this feature to write files via the REPL. +//| +//| If `unsafe_disable_usb_drive()` is called in ``boot.py``, it is identical to calling +//| `disable_usb_drive()`. +//| """ +//| ... +//| +//| +static mp_obj_t storage_unsafe_disable_usb_drive(void) { + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC + if (!common_hal_storage_unsafe_disable_usb_drive()) { + #else + if (true) { + #endif + mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot change USB devices now")); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(storage_unsafe_disable_usb_drive_obj, storage_unsafe_disable_usb_drive); + //| def enable_usb_drive() -> None: -//| """Enabled presenting ``CIRCUITPY`` as a USB mass storage device. -//| By default, the device is enabled and ``CIRCUITPY`` is visible, -//| so you do not normally need to call this function. -//| Can be called in ``boot.py``, before USB is connected. +//| """Enable presenting **CIRCUITPY** as a USB mass storage device. +//| By default, the device is enabled and **CIRCUITPY** is visible, +//| so you do not normally need to call this function in ``boot.py``. +//| +//| If you call `enable_usb_drive()` after ``code.py`` starts or in the REPL, +//| you can reverse the effect of a previous `unsafe_disable_usb_drive()`. +//| The **CIRCUITPY** drive will reappear to the host, and become read-only again +//| if it was previously read-only. //| -//| If you enable too many devices at once, you will run out of USB endpoints. +//| If you enable too many USB devices at once, you will run out of USB endpoints. //| The number of available endpoints varies by microcontroller. -//| CircuitPython will go into safe mode after running boot.py to inform you if +//| CircuitPython will go into safe mode after running ``boot.py`` to inform you if //| not enough endpoints are available. //| """ //| ... //| +//| static mp_obj_t storage_enable_usb_drive(void) { #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC if (!common_hal_storage_enable_usb_drive()) { @@ -222,19 +303,21 @@ MP_DEFINE_CONST_FUN_OBJ_0(storage_enable_usb_drive_obj, storage_enable_usb_drive static const mp_rom_map_elem_t storage_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_storage) }, - { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&storage_mount_obj) }, - { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&storage_umount_obj) }, - { MP_ROM_QSTR(MP_QSTR_remount), MP_ROM_PTR(&storage_remount_obj) }, - { MP_ROM_QSTR(MP_QSTR_getmount), MP_ROM_PTR(&storage_getmount_obj) }, - { MP_ROM_QSTR(MP_QSTR_erase_filesystem), MP_ROM_PTR(&storage_erase_filesystem_obj) }, - { MP_ROM_QSTR(MP_QSTR_disable_usb_drive), MP_ROM_PTR(&storage_disable_usb_drive_obj) }, - { MP_ROM_QSTR(MP_QSTR_enable_usb_drive), MP_ROM_PTR(&storage_enable_usb_drive_obj) }, + { MP_ROM_QSTR(MP_QSTR_mount), MP_ROM_PTR(&storage_mount_obj) }, + { MP_ROM_QSTR(MP_QSTR_umount), MP_ROM_PTR(&storage_umount_obj) }, + { MP_ROM_QSTR(MP_QSTR_remount), MP_ROM_PTR(&storage_remount_obj) }, + { MP_ROM_QSTR(MP_QSTR_getmount), MP_ROM_PTR(&storage_getmount_obj) }, + { MP_ROM_QSTR(MP_QSTR_erase_filesystem), MP_ROM_PTR(&storage_erase_filesystem_obj) }, + { MP_ROM_QSTR(MP_QSTR_disable_usb_drive), MP_ROM_PTR(&storage_disable_usb_drive_obj) }, + { MP_ROM_QSTR(MP_QSTR_enable_usb_drive), MP_ROM_PTR(&storage_enable_usb_drive_obj) }, + { MP_ROM_QSTR(MP_QSTR_unsafe_disable_usb_drive), MP_ROM_PTR(&storage_unsafe_disable_usb_drive_obj) }, //| class VfsFat: //| def __init__(self, block_device: BlockDevice) -> None: //| """Create a new VfsFat filesystem around the given block device. //| //| :param block_device: Block device the the filesystem lives on""" +//| //| label: str //| """The filesystem label, up to 11 case-insensitive bytes. Note that //| this property can only be set when the device is writable by the @@ -290,6 +373,7 @@ static const mp_rom_map_elem_t storage_module_globals_table[] = { //| def umount(self) -> None: //| """Don't call this directly, call `storage.umount`.""" //| ... +//| //| { MP_ROM_QSTR(MP_QSTR_VfsFat), MP_ROM_PTR(&mp_fat_vfs_type) }, }; diff --git a/shared-bindings/storage/__init__.h b/shared-bindings/storage/__init__.h index 7ab5fc97bd7..0e53c78b153 100644 --- a/shared-bindings/storage/__init__.h +++ b/shared-bindings/storage/__init__.h @@ -16,7 +16,8 @@ void common_hal_storage_umount_path(const char *path); void common_hal_storage_umount_object(mp_obj_t vfs_obj); void common_hal_storage_remount(const char *path, bool readonly, bool disable_concurrent_write_protection); mp_obj_t common_hal_storage_getmount(const char *path); -void common_hal_storage_erase_filesystem(bool extended); +MP_NORETURN void common_hal_storage_erase_filesystem(bool extended); bool common_hal_storage_disable_usb_drive(void); +bool common_hal_storage_unsafe_disable_usb_drive(void); bool common_hal_storage_enable_usb_drive(void); diff --git a/shared-bindings/struct/__init__.c b/shared-bindings/struct/__init__.c index eded8b1a3da..3f9fd40895e 100644 --- a/shared-bindings/struct/__init__.c +++ b/shared-bindings/struct/__init__.c @@ -26,12 +26,14 @@ //| Supported format codes: *b*, *B*, *x*, *h*, *H*, *i*, *I*, *l*, *L*, *q*, *Q*, //| *s*, *P*, *f*, *d* (the latter 2 depending on the floating-point support).""" //| +//| //| def calcsize(fmt: str) -> int: //| """Return the number of bytes needed to store the given fmt.""" //| ... //| +//| static mp_obj_t struct_calcsize(mp_obj_t fmt_in) { @@ -44,6 +46,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(struct_calcsize_obj, struct_calcsize); //| The return value is a bytes object encoding the values.""" //| ... //| +//| static mp_obj_t struct_pack(size_t n_args, const mp_obj_t *args) { mp_int_t size = MP_OBJ_SMALL_INT_VALUE(struct_calcsize(args[0])); @@ -62,6 +65,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_obj, 1, MP_OBJ_FUN_ARGS_MAX, str //| starting at offset. offset may be negative to count from the end of buffer.""" //| ... //| +//| static mp_obj_t struct_pack_into(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; @@ -89,6 +93,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_pack_into_obj, 3, MP_OBJ_FUN_ARGS_MAX //| required by the format.""" //| ... //| +//| static mp_obj_t struct_unpack(size_t n_args, const mp_obj_t *args) { mp_buffer_info_t bufinfo; @@ -108,6 +113,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(struct_unpack_obj, 2, 3, struct_unpack); //| as the size required by the form.""" //| ... //| +//| static mp_obj_t struct_unpack_from(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_format, ARG_buffer, ARG_offset }; diff --git a/shared-bindings/supervisor/RunReason.c b/shared-bindings/supervisor/RunReason.c index 5fc29fa27b6..3a0005a3dd3 100644 --- a/shared-bindings/supervisor/RunReason.c +++ b/shared-bindings/supervisor/RunReason.c @@ -29,6 +29,7 @@ MAKE_ENUM_VALUE(supervisor_run_reason_type, run_reason, REPL_RELOAD, RUN_REASON_ //| REPL_RELOAD: object //| """CircuitPython started due to the user typing CTRL-D in the REPL.""" //| +//| MAKE_ENUM_MAP(supervisor_run_reason) { MAKE_ENUM_MAP_ENTRY(run_reason, STARTUP), MAKE_ENUM_MAP_ENTRY(run_reason, AUTO_RELOAD), diff --git a/shared-bindings/supervisor/Runtime.c b/shared-bindings/supervisor/Runtime.c index 5c4754b85f2..5b2885f26c0 100644 --- a/shared-bindings/supervisor/Runtime.c +++ b/shared-bindings/supervisor/Runtime.c @@ -20,8 +20,12 @@ #include "supervisor/shared/status_leds.h" #include "supervisor/shared/bluetooth/bluetooth.h" -#if CIRCUITPY_TINYUSB -#include "tusb.h" +#if CIRCUITPY_USB_DEVICE +#include "supervisor/usb.h" +#endif + +#if CIRCUITPY_DISPLAYIO +#include "shared-bindings/displayio/__init__.h" #endif static supervisor_run_reason_t _run_reason; @@ -42,12 +46,13 @@ static supervisor_run_reason_t _run_reason; //| """You cannot create an instance of `supervisor.Runtime`. //| Use `supervisor.runtime` to access the sole instance available.""" //| ... +//| //| usb_connected: bool //| """Returns the USB enumeration status (read-only).""" static mp_obj_t supervisor_runtime_get_usb_connected(mp_obj_t self) { #if CIRCUITPY_USB_DEVICE - return mp_obj_new_bool(tud_ready()); + return mp_obj_new_bool(usb_connected()); #else return mp_const_false; #endif @@ -148,10 +153,13 @@ MP_PROPERTY_GETSET(supervisor_runtime_autoreload_obj, //| ble_workflow: bool //| """Enable/Disable ble workflow until a reset. This prevents BLE advertising outside of the VM and -//| the services used for it.""" +//| the services used for it. +//| If ``CIRCUITPY_BLE_WORKFLOW=false`` is present in ``settings.toml``, setting `ble_workflow` +//| to ``True`` has no effect. +//| """ //| static mp_obj_t supervisor_runtime_get_ble_workflow(mp_obj_t self) { - #if CIRCUITPY_BLE_FILE_SERVICE && CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE && CIRCUITPY_BLE_SERIAL_SERVICE return mp_obj_new_bool(supervisor_bluetooth_workflow_is_enabled()); #else return mp_const_false; @@ -160,7 +168,7 @@ static mp_obj_t supervisor_runtime_get_ble_workflow(mp_obj_t self) { MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_ble_workflow_obj, supervisor_runtime_get_ble_workflow); static mp_obj_t supervisor_runtime_set_ble_workflow(mp_obj_t self, mp_obj_t state_in) { - #if CIRCUITPY_BLE_FILE_SERVICE && CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE && CIRCUITPY_BLE_SERIAL_SERVICE if (mp_obj_is_true(state_in)) { supervisor_bluetooth_enable_workflow(); } else { @@ -202,6 +210,39 @@ MP_PROPERTY_GETSET(supervisor_runtime_rgb_status_brightness_obj, (mp_obj_t)&supervisor_runtime_get_rgb_status_brightness_obj, (mp_obj_t)&supervisor_runtime_set_rgb_status_brightness_obj); +#if CIRCUITPY_DISPLAYIO +//| display: displayio.AnyDisplay | None +//| """The primary configured displayio display, if any. +//| +//| If the board has a display that is hard coded, or that was explicitly set +//| in boot.py or code.py (including a previous run of code.py), it is +//| available here until it is released with ``displayio.release_displays()``. +//| +//| The display can be of any supported display type, such as `busdisplay.BusDisplay`. +//| +//| If no display is configured, this property is `None`. +//| +//| In a future release of CircuitPython, any display that is not the primary display +//| will be automatically released at the end of running a code file. +//| +//| On boards without displayio, this property is present but the value is always `None`.""" +//| +//| +static mp_obj_t supervisor_runtime_get_display(mp_obj_t self) { + return common_hal_displayio_get_primary_display(); +} +MP_DEFINE_CONST_FUN_OBJ_1(supervisor_runtime_get_display_obj, supervisor_runtime_get_display); +static mp_obj_t supervisor_runtime_set_display(mp_obj_t self, mp_obj_t new_primary_display) { + common_hal_displayio_set_primary_display(new_primary_display); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(supervisor_runtime_set_display_obj, supervisor_runtime_set_display); + +MP_PROPERTY_GETSET(supervisor_runtime_display_obj, + (mp_obj_t)&supervisor_runtime_get_display_obj, + (mp_obj_t)&supervisor_runtime_set_display_obj); +#endif + static const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_usb_connected), MP_ROM_PTR(&supervisor_runtime_usb_connected_obj) }, { MP_ROM_QSTR(MP_QSTR_serial_connected), MP_ROM_PTR(&supervisor_runtime_serial_connected_obj) }, @@ -211,6 +252,11 @@ static const mp_rom_map_elem_t supervisor_runtime_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_autoreload), MP_ROM_PTR(&supervisor_runtime_autoreload_obj) }, { MP_ROM_QSTR(MP_QSTR_ble_workflow), MP_ROM_PTR(&supervisor_runtime_ble_workflow_obj) }, { MP_ROM_QSTR(MP_QSTR_rgb_status_brightness), MP_ROM_PTR(&supervisor_runtime_rgb_status_brightness_obj) }, + #if CIRCUITPY_DISPLAYIO + { MP_ROM_QSTR(MP_QSTR_display), MP_ROM_PTR(&supervisor_runtime_display_obj) }, + #else + { MP_ROM_QSTR(MP_QSTR_display), MP_ROM_NONE }, + #endif }; static MP_DEFINE_CONST_DICT(supervisor_runtime_locals_dict, supervisor_runtime_locals_dict_table); diff --git a/shared-bindings/supervisor/SafeModeReason.c b/shared-bindings/supervisor/SafeModeReason.c index e2cbac3b9a7..ff85d8a3d5c 100644 --- a/shared-bindings/supervisor/SafeModeReason.c +++ b/shared-bindings/supervisor/SafeModeReason.c @@ -127,6 +127,7 @@ MAKE_ENUM_MAP(supervisor_safe_mode_reason) { //| WATCHDOG: object //| """An internal watchdog timer expired.""" +//| //| MAKE_ENUM_MAP_ENTRY(safe_mode_reason, WATCHDOG), }; diff --git a/shared-bindings/supervisor/StatusBar.c b/shared-bindings/supervisor/StatusBar.c index 46e7962cf05..be109a6e221 100644 --- a/shared-bindings/supervisor/StatusBar.c +++ b/shared-bindings/supervisor/StatusBar.c @@ -26,6 +26,7 @@ //| """You cannot create an instance of `supervisor.StatusBar`. //| Use `supervisor.status_bar` to access the sole instance available.""" //| ... +//| //| console: bool //| """Whether status bar information is sent over the console (REPL) serial connection, @@ -65,6 +66,7 @@ MP_PROPERTY_GETSET(supervisor_status_bar_console_obj, //| Not available if `terminalio` is not available. //| """ //| +//| static mp_obj_t supervisor_status_bar_get_display(mp_obj_t self_in) { #if CIRCUITPY_STATUS_BAR && CIRCUITPY_TERMINALIO supervisor_status_bar_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/shared-bindings/supervisor/__init__.c b/shared-bindings/supervisor/__init__.c index e09094ff88e..a331249998a 100644 --- a/shared-bindings/supervisor/__init__.c +++ b/shared-bindings/supervisor/__init__.c @@ -3,6 +3,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2016-2017 Scott Shawcroft for Adafruit Industries // // SPDX-License-Identifier: MIT +#include #include #include "py/obj.h" @@ -20,13 +21,19 @@ #include "supervisor/usb.h" #endif +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" +#endif + #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/time/__init__.h" #include "shared-bindings/supervisor/Runtime.h" #include "shared-bindings/supervisor/StatusBar.h" +#include "shared-bindings/util.h" //| """Supervisor settings""" +//| //| runtime: Runtime //| """Runtime information, such as ``runtime.serial_connected`` @@ -40,11 +47,13 @@ //| the last exception name and location, and firmware version information. //| This object is the sole instance of `supervisor.StatusBar`.""" //| +//| //| def reload() -> None: //| """Reload the main Python code and run it (equivalent to hitting Ctrl-D at the REPL).""" //| ... //| +//| static mp_obj_t supervisor_reload(void) { reload_initiate(RUN_REASON_SUPERVISOR_RELOAD); return mp_const_none; @@ -54,11 +63,12 @@ MP_DEFINE_CONST_FUN_OBJ_0(supervisor_reload_obj, supervisor_reload); //| def set_next_code_file( //| filename: Optional[str], //| *, +//| working_directory: Optional[str] = None, //| reload_on_success: bool = False, //| reload_on_error: bool = False, //| sticky_on_success: bool = False, //| sticky_on_error: bool = False, -//| sticky_on_reload: bool = False +//| sticky_on_reload: bool = False, //| ) -> None: //| """Set what file to run on the next vm run. //| @@ -92,9 +102,11 @@ MP_DEFINE_CONST_FUN_OBJ_0(supervisor_reload_obj, supervisor_reload); //| reset to the standard search sequence.""" //| ... //| +//| static mp_obj_t supervisor_set_next_code_file(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { static const mp_arg_t allowed_args[] = { { MP_QSTR_filename, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + { MP_QSTR_working_directory, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, { MP_QSTR_reload_on_success, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_reload_on_error, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, { MP_QSTR_sticky_on_success, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, @@ -103,6 +115,7 @@ static mp_obj_t supervisor_set_next_code_file(size_t n_args, const mp_obj_t *pos }; struct { mp_arg_val_t filename; + mp_arg_val_t working_directory; mp_arg_val_t reload_on_success; mp_arg_val_t reload_on_error; mp_arg_val_t sticky_on_success; @@ -114,6 +127,11 @@ static mp_obj_t supervisor_set_next_code_file(size_t n_args, const mp_obj_t *pos if (!mp_obj_is_str_or_bytes(filename_obj) && filename_obj != mp_const_none) { mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), MP_QSTR_filename, MP_QSTR_str, MP_QSTR_None, mp_obj_get_type(filename_obj)->name); } + + mp_obj_t working_directory_obj = args.working_directory.u_obj; + if (!mp_obj_is_str_or_bytes(working_directory_obj) && working_directory_obj != mp_const_none) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), MP_QSTR_working_directory, MP_QSTR_str, MP_QSTR_None, mp_obj_get_type(working_directory_obj)->name); + } if (filename_obj == mp_const_none) { filename_obj = mp_const_empty_bytes; } @@ -135,18 +153,50 @@ static mp_obj_t supervisor_set_next_code_file(size_t n_args, const mp_obj_t *pos } size_t len; const char *filename = mp_obj_str_get_data(filename_obj, &len); + if (!path_exists(filename)) { + mp_raise_ValueError(MP_ERROR_TEXT("File not found")); + } + + size_t working_directory_len = 0; + const char *working_directory = NULL; + if (working_directory_obj != mp_const_none) { + working_directory = mp_obj_str_get_data(working_directory_obj, &working_directory_len); + if (!path_exists(working_directory)) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_working_directory); + } + } if (next_code_configuration != NULL) { port_free(next_code_configuration); next_code_configuration = NULL; } if (options != 0 || len != 0) { - next_code_configuration = port_malloc(sizeof(supervisor_next_code_info_t) + len + 1, false); + + size_t next_code_size = sizeof(supervisor_next_code_info_t) + len + 1; + if (working_directory_len > 0) { + next_code_size += working_directory_len + 1; + } + next_code_configuration = port_malloc(next_code_size, false); if (next_code_configuration == NULL) { - m_malloc_fail(sizeof(supervisor_next_code_info_t) + len + 1); + m_malloc_fail(next_code_size); + } + char *filename_ptr = (char *)next_code_configuration + sizeof(supervisor_next_code_info_t); + + // Copy filename + memcpy(filename_ptr, filename, len); + filename_ptr[len] = '\0'; + + char *working_directory_ptr = NULL; + // Copy working directory after filename if present + if (working_directory_len > 0) { + working_directory_ptr = filename_ptr + len + 1; + memcpy(working_directory_ptr, working_directory, working_directory_len); + working_directory_ptr[working_directory_len] = '\0'; } + // Set everything up last. We may have raised an exception early and we + // don't want to free the memory if we failed. + next_code_configuration->filename = filename_ptr; + next_code_configuration->working_directory = working_directory_ptr; next_code_configuration->options = options | SUPERVISOR_NEXT_CODE_OPT_NEWLY_SET; - memcpy(&next_code_configuration->filename, filename, len); - next_code_configuration->filename[len] = '\0'; } return mp_const_none; } @@ -194,6 +244,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_set_next_code_file_obj, 0, supervisor_set_ //| """ //| ... //| +//| mp_obj_t supervisor_ticks_ms(void) { uint64_t ticks_ms = common_hal_time_monotonic_ms(); return mp_obj_new_int((ticks_ms + 0x1fff0000) % (1 << 29)); @@ -210,6 +261,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(supervisor_ticks_ms_obj, supervisor_ticks_ms); //| Only code (main or boot) runs are considered, not REPL runs.""" //| ... //| +//| static mp_obj_t supervisor_get_previous_traceback(void) { if (prev_traceback_string) { size_t len = strlen(prev_traceback_string); @@ -230,6 +282,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(supervisor_get_previous_traceback_obj, supervisor_get_ //| """Reset the CircuitPython serial terminal with new dimensions.""" //| ... //| +//| static mp_obj_t supervisor_reset_terminal(mp_obj_t x_pixels, mp_obj_t y_pixels) { #if CIRCUITPY_DISPLAYIO supervisor_stop_terminal(); @@ -258,6 +311,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(supervisor_reset_terminal_obj, supervisor_reset_termin //| """ //| ... //| +//| static mp_obj_t supervisor_set_usb_identification(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_IDENTIFICATION static const mp_arg_t allowed_args[] = { @@ -310,6 +364,71 @@ static mp_obj_t supervisor_set_usb_identification(size_t n_args, const mp_obj_t } MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_set_usb_identification_obj, 0, supervisor_set_usb_identification); +//| def get_setting(key: str, default: object=None) -> int | float | str | bool: +//| """ +//| Get and parse the value for the given ``key`` from the ``/settings.toml`` file. +//| If ``key`` is not found or ``settings.toml`` is not present, return the ``default`` value. +//| +//| :param str key: The setting key to retrieve +//| :return: The setting value as an ``int``, ``float``, ``str``, or ``bool`` depending on the value in the file +//| +//| :raises ValueError: If the value cannot be parsed as a valid TOML value. +//| +//| The value must be parseable as one of these types: +//| +//| - ``str``: Double-quoted string. +//| The string may include Unicode characters, and ``\\u`` Unicode escapes. Backslash-escaped characters +//| ``\\b``, ``\\r``, ``\\n``, ``\\t``, ``\\v``, ``\\v`` are also allowed. +//| - ``int``: signed or unsigned integer. +//| - ``bool``: lower-case ``true`` or ``false``. +//| The values are returned as Python ``True`` or ``False`` values. +//| - ``float``: signed or unsigned decimal number with a ``.`` or exponent, or ``inf``, ``inf``, ``nan``. +//| +//| Example:: +//| +//| # settings.toml: +//| WIDTH = 42 +//| color = "red" +//| DEBUG = true +//| RATIO = 1.5 +//| +//| import supervisor +//| print(supervisor.get_setting("WIDTH")) # prints 42 +//| print(supervisor.get_setting("color")) # prints 'red' +//| print(supervisor.get_setting("DEBUG")) # prints True +//| print(supervisor.get_setting("RATIO")) # prints 1.5 +//| """ +//| ... +//| +static mp_obj_t supervisor_get_setting(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + #if CIRCUITPY_SETTINGS_TOML + enum { ARG_key, ARG_default }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_key, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_default, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, (mp_arg_val_t *)&args); + + const char *key = mp_obj_str_get_str(args[ARG_key].u_obj); + mp_obj_t value; + settings_err_t result = settings_get_obj(key, &value); + + switch (result) { + case SETTINGS_OK: + return value; + case SETTINGS_ERR_NOT_FOUND: + case SETTINGS_ERR_OPEN: + return args[ARG_default].u_obj; + default: + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_value); + } + #else + mp_raise_NotImplementedError(NULL); + #endif +} +MP_DEFINE_CONST_FUN_OBJ_KW(supervisor_get_setting_obj, 1, supervisor_get_setting); + static const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_supervisor) }, { MP_ROM_QSTR(MP_QSTR_runtime), MP_ROM_PTR(&common_hal_supervisor_runtime_obj) }, @@ -323,6 +442,7 @@ static const mp_rom_map_elem_t supervisor_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_set_next_code_file), MP_ROM_PTR(&supervisor_set_next_code_file_obj) }, { MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&supervisor_ticks_ms_obj) }, { MP_ROM_QSTR(MP_QSTR_get_previous_traceback), MP_ROM_PTR(&supervisor_get_previous_traceback_obj) }, + { MP_ROM_QSTR(MP_QSTR_get_setting), MP_ROM_PTR(&supervisor_get_setting_obj) }, { MP_ROM_QSTR(MP_QSTR_reset_terminal), MP_ROM_PTR(&supervisor_reset_terminal_obj) }, { MP_ROM_QSTR(MP_QSTR_set_usb_identification), MP_ROM_PTR(&supervisor_set_usb_identification_obj) }, { MP_ROM_QSTR(MP_QSTR_status_bar), MP_ROM_PTR(&shared_module_supervisor_status_bar_obj) }, diff --git a/shared-bindings/supervisor/__init__.h b/shared-bindings/supervisor/__init__.h index c442534072a..4be9667ef56 100644 --- a/shared-bindings/supervisor/__init__.h +++ b/shared-bindings/supervisor/__init__.h @@ -6,6 +6,8 @@ #pragma once +#include +#include // #include "py/mpconfig.h" #include "py/obj.h" @@ -18,7 +20,8 @@ typedef struct { uint8_t options; - char filename[]; + const char *working_directory; + const char *filename; } supervisor_next_code_info_t; extern const super_runtime_obj_t common_hal_supervisor_runtime_obj; diff --git a/shared-bindings/synthio/Biquad.c b/shared-bindings/synthio/Biquad.c index 79a9fa4593f..55465fae024 100644 --- a/shared-bindings/synthio/Biquad.c +++ b/shared-bindings/synthio/Biquad.c @@ -1,74 +1,210 @@ // This file is part of the CircuitPython project: https://circuitpython.org // -// SPDX-FileCopyrightText: Copyright (c) 2021 Artyom Skrobov +// SPDX-FileCopyrightText: Copyright (c) 2023 Jeff Epler for Adafruit Industries // // SPDX-License-Identifier: MIT -#include -#include - #include "py/enum.h" -#include "py/mperrno.h" -#include "py/obj.h" -#include "py/objnamedtuple.h" +#include "py/objproperty.h" #include "py/runtime.h" +#include "shared-bindings/synthio/Biquad.h" +#include "shared-bindings/util.h" -#include "shared-bindings/synthio/__init__.h" -#include "shared-bindings/synthio/LFO.h" -#include "shared-bindings/synthio/Math.h" -#include "shared-bindings/synthio/MidiTrack.h" -#include "shared-bindings/synthio/Note.h" -#include "shared-bindings/synthio/Synthesizer.h" - -#include "shared-module/synthio/LFO.h" +//| class FilterMode: +//| """The type of filter""" +//| +//| LOW_PASS: FilterMode +//| """A low-pass filter""" +//| HIGH_PASS: FilterMode +//| """A high-pass filter""" +//| BAND_PASS: FilterMode +//| """A band-pass filter""" +//| NOTCH: FilterMode +//| """A notch filter""" +//| LOW_SHELF: FilterMode +//| """A low shelf filter""" +//| HIGH_SHELF: FilterMode +//| """A high shelf filter""" +//| PEAKING_EQ: FilterMode +//| """A peaking equalizer filter""" +//| +//| -#define default_attack_time (MICROPY_FLOAT_CONST(0.1)) -#define default_decay_time (MICROPY_FLOAT_CONST(0.05)) -#define default_release_time (MICROPY_FLOAT_CONST(0.2)) -#define default_attack_level (MICROPY_FLOAT_CONST(1.)) -#define default_sustain_level (MICROPY_FLOAT_CONST(0.8)) +MAKE_ENUM_VALUE(synthio_filter_mode_type, mode, LOW_PASS, SYNTHIO_LOW_PASS); +MAKE_ENUM_VALUE(synthio_filter_mode_type, mode, HIGH_PASS, SYNTHIO_HIGH_PASS); +MAKE_ENUM_VALUE(synthio_filter_mode_type, mode, BAND_PASS, SYNTHIO_BAND_PASS); +MAKE_ENUM_VALUE(synthio_filter_mode_type, mode, NOTCH, SYNTHIO_NOTCH); +MAKE_ENUM_VALUE(synthio_filter_mode_type, mode, LOW_SHELF, SYNTHIO_LOW_SHELF); +MAKE_ENUM_VALUE(synthio_filter_mode_type, mode, HIGH_SHELF, SYNTHIO_HIGH_SHELF); +MAKE_ENUM_VALUE(synthio_filter_mode_type, mode, PEAKING_EQ, SYNTHIO_PEAKING_EQ); -static const mp_arg_t biquad_properties[] = { - { MP_QSTR_a1, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_ROM_NONE} }, - { MP_QSTR_a2, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_ROM_NONE} }, - { MP_QSTR_b0, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_ROM_NONE} }, - { MP_QSTR_b1, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_ROM_NONE} }, - { MP_QSTR_b2, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_ROM_NONE} }, +MAKE_ENUM_MAP(synthio_filter_mode) { + MAKE_ENUM_MAP_ENTRY(mode, LOW_PASS), + MAKE_ENUM_MAP_ENTRY(mode, HIGH_PASS), + MAKE_ENUM_MAP_ENTRY(mode, BAND_PASS), + MAKE_ENUM_MAP_ENTRY(mode, NOTCH), + MAKE_ENUM_MAP_ENTRY(mode, LOW_SHELF), + MAKE_ENUM_MAP_ENTRY(mode, HIGH_SHELF), + MAKE_ENUM_MAP_ENTRY(mode, PEAKING_EQ), }; +static MP_DEFINE_CONST_DICT(synthio_filter_mode_locals_dict, synthio_filter_mode_locals_table); + +MAKE_PRINTER(synthio, synthio_filter_mode); + +MAKE_ENUM_TYPE(synthio, FilterMode, synthio_filter_mode); + +static synthio_filter_mode validate_synthio_filter_mode(mp_obj_t obj, qstr arg_name) { + return cp_enum_value(&synthio_filter_mode_type, obj, arg_name); +} + //| class Biquad: -//| def __init__(self, b0: float, b1: float, b2: float, a1: float, a2: float) -> None: -//| """Construct a normalized biquad filter object. +//| def __init__( +//| self, +//| mode: FilterMode, +//| frequency: BlockInput, +//| Q: BlockInput = 0.7071067811865475, +//| A: BlockInput = None, +//| ) -> None: +//| """Construct a biquad filter object with given settings. +//| +//| ``frequency`` gives the center frequency or corner frequency of the filter, +//| depending on the mode. //| -//| This implements the "direct form 1" biquad filter, where each coefficient -//| has been pre-divided by a0. +//| ``Q`` gives the gain or sharpness of the filter. //| -//| Biquad objects are usually constructed via one of the related methods on a `Synthesizer` object -//| rather than directly from coefficients. +//| ``A`` controls the gain of peaking and shelving filters according to the +//| formula ``A = 10^(dBgain/40)``. For other filter types it is ignored. //| -//| https://github.com/WebAudio/Audio-EQ-Cookbook/blob/main/Audio-EQ-Cookbook.txt -//| """ +//| Since ``frequency`` and ``Q`` are `BlockInput` objects, they can +//| be varied dynamically. Internally, this is evaluated as "direct form 1" +//| biquad filter. //| +//| The internal filter state x[] and y[] is not updated when the filter +//| coefficients change, and there is no theoretical justification for why +//| this should result in a stable filter output. However, in practice, +//| slowly varying the filter's characteristic frequency and sharpness +//| appears to work as you'd expect.""" +//| + +static const mp_arg_t biquad_properties[] = { + { MP_QSTR_mode, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL } }, + { MP_QSTR_frequency, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_OBJ_NULL } }, + { MP_QSTR_Q, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL } }, + { MP_QSTR_A, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE } }, +}; + static mp_obj_t synthio_biquad_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_mode, ARG_frequency, ARG_Q }; + mp_arg_val_t args[MP_ARRAY_SIZE(biquad_properties)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(biquad_properties), biquad_properties, args); - for (size_t i = 0; i < MP_ARRAY_SIZE(biquad_properties); i++) { - args[i].u_obj = mp_obj_new_float(mp_arg_validate_type_float(args[i].u_obj, biquad_properties[i].qst)); + if (args[ARG_Q].u_obj == MP_OBJ_NULL) { + args[ARG_Q].u_obj = mp_obj_new_float(MICROPY_FLOAT_CONST(0.7071067811865475)); } - MP_STATIC_ASSERT(sizeof(mp_arg_val_t) == sizeof(mp_obj_t)); - return namedtuple_make_new(type_in, MP_ARRAY_SIZE(args), 0, &args[0].u_obj); + synthio_filter_mode mode = validate_synthio_filter_mode(args[ARG_mode].u_obj, MP_QSTR_mode); + mp_obj_t result = common_hal_synthio_biquad_new(mode); + properties_construct_helper(result, biquad_properties + 1, args + 1, MP_ARRAY_SIZE(biquad_properties) - 1); + return result; } -const mp_obj_namedtuple_type_t synthio_biquad_type_obj = { - NAMEDTUPLE_TYPE_BASE_AND_SLOTS_MAKE_NEW(MP_QSTR_Biquad, synthio_biquad_make_new), - .n_fields = 5, - .fields = { - MP_QSTR_a1, - MP_QSTR_a2, - MP_QSTR_b0, - MP_QSTR_b1, - MP_QSTR_b2, - }, +//| +//| mode: FilterMode +//| """The mode of filter (read-only)""" +static mp_obj_t synthio_biquad_get_mode(mp_obj_t self_in) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + return cp_enum_find(&synthio_filter_mode_type, common_hal_synthio_biquad_get_mode(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_biquad_get_mode_obj, synthio_biquad_get_mode); + +MP_PROPERTY_GETTER(synthio_biquad_mode_obj, + (mp_obj_t)&synthio_biquad_get_mode_obj); + +//| +//| frequency: BlockInput +//| """The central frequency (in Hz) of the filter""" +static mp_obj_t synthio_biquad_get_frequency(mp_obj_t self_in) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_synthio_biquad_get_frequency(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_biquad_get_frequency_obj, synthio_biquad_get_frequency); + +static mp_obj_t synthio_biquad_set_frequency(mp_obj_t self_in, mp_obj_t arg) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_synthio_biquad_set_frequency(self, arg); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(synthio_biquad_set_frequency_obj, synthio_biquad_set_frequency); +MP_PROPERTY_GETSET(synthio_biquad_frequency_obj, + (mp_obj_t)&synthio_biquad_get_frequency_obj, + (mp_obj_t)&synthio_biquad_set_frequency_obj); + + +//| +//| Q: BlockInput +//| """The sharpness (Q) of the filter""" +//| +static mp_obj_t synthio_biquad_get_Q(mp_obj_t self_in) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_synthio_biquad_get_Q(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_biquad_get_Q_obj, synthio_biquad_get_Q); + +static mp_obj_t synthio_biquad_set_Q(mp_obj_t self_in, mp_obj_t arg) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_synthio_biquad_set_Q(self, arg); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(synthio_biquad_set_Q_obj, synthio_biquad_set_Q); +MP_PROPERTY_GETSET(synthio_biquad_Q_obj, + (mp_obj_t)&synthio_biquad_get_Q_obj, + (mp_obj_t)&synthio_biquad_set_Q_obj); + +//| +//| A: BlockInput +//| """The gain (A) of the filter +//| +//| This setting only has an effect for peaking and shelving EQ filters. It is related +//| to the filter gain according to the formula ``A = 10^(dBgain/40)``. +//| """ +//| +//| +static mp_obj_t synthio_biquad_get_A(mp_obj_t self_in) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_synthio_biquad_get_A(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(synthio_biquad_get_A_obj, synthio_biquad_get_A); + +static mp_obj_t synthio_biquad_set_A(mp_obj_t self_in, mp_obj_t arg) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_synthio_biquad_set_A(self, arg); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(synthio_biquad_set_A_obj, synthio_biquad_set_A); +MP_PROPERTY_GETSET(synthio_biquad_A_obj, + (mp_obj_t)&synthio_biquad_get_A_obj, + (mp_obj_t)&synthio_biquad_set_A_obj); + +static const mp_rom_map_elem_t synthio_biquad_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&synthio_biquad_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&synthio_biquad_frequency_obj) }, + { MP_ROM_QSTR(MP_QSTR_Q), MP_ROM_PTR(&synthio_biquad_Q_obj) }, + { MP_ROM_QSTR(MP_QSTR_A), MP_ROM_PTR(&synthio_biquad_A_obj) }, }; +static MP_DEFINE_CONST_DICT(synthio_biquad_locals_dict, synthio_biquad_locals_dict_table); + +static void biquad_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + (void)kind; + properties_print_helper(print, self_in, biquad_properties, MP_ARRAY_SIZE(biquad_properties)); +} + +MP_DEFINE_CONST_OBJ_TYPE( + synthio_biquad_type_obj, + MP_QSTR_Biquad, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, synthio_biquad_make_new, + locals_dict, &synthio_biquad_locals_dict, + print, biquad_print + ); diff --git a/shared-bindings/synthio/Biquad.h b/shared-bindings/synthio/Biquad.h index 2b40960fc5d..616488525f2 100644 --- a/shared-bindings/synthio/Biquad.h +++ b/shared-bindings/synthio/Biquad.h @@ -7,9 +7,27 @@ #pragma once #include "py/obj.h" -#include "py/objnamedtuple.h" -extern const mp_obj_namedtuple_type_t synthio_biquad_type_obj; -mp_obj_t common_hal_synthio_new_lpf(mp_float_t w0, mp_float_t Q); -mp_obj_t common_hal_synthio_new_hpf(mp_float_t w0, mp_float_t Q); -mp_obj_t common_hal_synthio_new_bpf(mp_float_t w0, mp_float_t Q); +extern const mp_obj_type_t synthio_biquad_type_obj; +extern const mp_obj_type_t synthio_filter_mode_type; +typedef struct synthio_biquad synthio_biquad_t; + +typedef enum { + SYNTHIO_LOW_PASS, SYNTHIO_HIGH_PASS, SYNTHIO_BAND_PASS, SYNTHIO_NOTCH, + // filters beyond this line use the "A" parameter (in addition to f0 and Q) + SYNTHIO_PEAKING_EQ, SYNTHIO_LOW_SHELF, SYNTHIO_HIGH_SHELF +} synthio_filter_mode; + + +mp_obj_t common_hal_synthio_biquad_get_A(synthio_biquad_t *self); +void common_hal_synthio_biquad_set_A(synthio_biquad_t *self, mp_obj_t A); + +mp_obj_t common_hal_synthio_biquad_get_Q(synthio_biquad_t *self); +void common_hal_synthio_biquad_set_Q(synthio_biquad_t *self, mp_obj_t Q); + +mp_obj_t common_hal_synthio_biquad_get_frequency(synthio_biquad_t *self); +void common_hal_synthio_biquad_set_frequency(synthio_biquad_t *self, mp_obj_t frequency); + +synthio_filter_mode common_hal_synthio_biquad_get_mode(synthio_biquad_t *self); + +mp_obj_t common_hal_synthio_biquad_new(synthio_filter_mode mode); diff --git a/shared-bindings/synthio/LFO.c b/shared-bindings/synthio/LFO.c index 9bf4ae9010c..2dfae22a577 100644 --- a/shared-bindings/synthio/LFO.c +++ b/shared-bindings/synthio/LFO.c @@ -34,7 +34,7 @@ static const uint16_t triangle[] = {0, 32767, 0, -32767}; //| including indirectly via a `Note` or another intermediate LFO. //| //| Using the same LFO as an input to multiple other LFOs or Notes is OK, but -//| the result if an LFO is tied to multiple Synthtesizer objects is undefined. +//| the result if an LFO is tied to multiple `Synthesizer` objects is undefined. //| //| In the current implementation, LFOs are updated every 256 samples. This //| should be considered an implementation detail, though it affects how LFOs @@ -43,7 +43,7 @@ static const uint16_t triangle[] = {0, 32767, 0, -32767}; //| An LFO's ``value`` property is computed once when it is constructed, and then //| when its associated synthesizer updates it. //| -//| This means that for instance an LFO **created** with ``offset=1`` has ```value==1`` +//| This means that for instance an LFO **created** with ``offset=1`` has ``value==1`` //| immediately, but **updating** the ``offset`` property alone does not //| change ``value``; it only updates through an association with an active synthesizer. //| @@ -78,6 +78,7 @@ static const uint16_t triangle[] = {0, 32767, 0, -32767}; //| interpolate: bool = True, //| ) -> None: //| pass +//| static const mp_arg_t lfo_properties[] = { { MP_QSTR_waveform, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE } }, { MP_QSTR_rate, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1) } }, @@ -102,17 +103,17 @@ static mp_obj_t synthio_lfo_make_new(const mp_obj_type_t *type_in, size_t n_args } self->waveform_obj = args[ARG_waveform].u_obj; - mp_obj_t result = MP_OBJ_FROM_PTR(self); - properties_construct_helper(result, lfo_properties + 1, args + 1, MP_ARRAY_SIZE(lfo_properties) - 1); + mp_obj_t self_obj = MP_OBJ_FROM_PTR(self); + properties_construct_helper(self_obj, lfo_properties + 1, args + 1, MP_ARRAY_SIZE(lfo_properties) - 1); // Force computation of the LFO's initial output synthio_global_rate_scale = 0; self->base.last_tick = synthio_global_tick - 1; synthio_block_slot_t slot; - synthio_block_assign_slot(MP_OBJ_FROM_PTR(result), &slot, MP_QSTR_self); + synthio_block_assign_slot(self_obj, &slot, MP_QSTR_self); (void)synthio_block_slot_get(&slot); - return result; + return self_obj; }; //| waveform: Optional[ReadableBuffer] @@ -271,6 +272,7 @@ MP_PROPERTY_GETTER(synthio_lfo_value_obj, //| def retrigger(self) -> None: //| """Reset the LFO's internal index to the start of the waveform. Most useful when it its `once` property is `True`.""" //| +//| static mp_obj_t synthio_lfo_retrigger(mp_obj_t self_in) { synthio_lfo_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_synthio_lfo_retrigger(self); diff --git a/shared-bindings/synthio/Math.c b/shared-bindings/synthio/Math.c index 14f9b59de6d..96857fb3513 100644 --- a/shared-bindings/synthio/Math.c +++ b/shared-bindings/synthio/Math.c @@ -36,6 +36,7 @@ MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, ABS, OP_ABS); //| //| def __call__(self, a: BlockInput, b: BlockInput = 0.0, c: BlockInput = 1.0) -> Math: //| """A MathOperation enumeration value can be called to construct a Math block that performs that operation""" +//| //| SUM: "MathOperation" //| """Computes ``a+b+c``. For 2-input sum, set one argument to ``0.0``. To hold a control value for multiple subscribers, set two arguments to ``0.0``.""" //| @@ -78,6 +79,7 @@ MAKE_ENUM_VALUE(synthio_math_operation_type, math_op, ABS, OP_ABS); //| ABS: "MathOperation" //| """Returns the absolute value of ``a``.""" //| +//| MAKE_ENUM_MAP(synthio_math_operation) { MAKE_ENUM_MAP_ENTRY(math_op, SUM), MAKE_ENUM_MAP_ENTRY(math_op, ADD_SUB), @@ -121,7 +123,7 @@ MAKE_ENUM_TYPE(synthio, MathOperation, synthio_math_operation, //| including indirectly via a `Note` or another intermediate Math. //| //| Using the same Math as an input to multiple other Maths or Notes is OK, but -//| the result if an Math is tied to multiple Synthtesizer objects is undefined. +//| the result if an Math is tied to multiple `Synthesizer` objects is undefined. //| //| In the current implementation, Maths are updated every 256 samples. This //| should be considered an implementation detail. @@ -135,6 +137,7 @@ MAKE_ENUM_TYPE(synthio, MathOperation, synthio_math_operation, //| c: BlockInput = 1.0, //| ) -> None: //| pass +//| static const mp_arg_t math_properties[] = { { MP_QSTR_operation, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL } }, { MP_QSTR_a, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = NULL } }, @@ -154,10 +157,10 @@ static mp_obj_t synthio_math_make_new_common(mp_arg_val_t args[MP_ARRAY_SIZE(mat self->base.last_tick = synthio_global_tick; - mp_obj_t result = MP_OBJ_FROM_PTR(self); - properties_construct_helper(result, math_properties, args, MP_ARRAY_SIZE(math_properties)); + mp_obj_t self_obj = MP_OBJ_FROM_PTR(self); + properties_construct_helper(self_obj, math_properties, args, MP_ARRAY_SIZE(math_properties)); - return result; + return self_obj; }; //| a: BlockInput @@ -241,6 +244,7 @@ MP_PROPERTY_GETSET(synthio_math_operation_obj, //| value: float //| """The value of the oscillator (read-only)""" //| +//| static mp_obj_t synthio_math_get_value(mp_obj_t self_in) { synthio_math_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_float(common_hal_synthio_math_get_value(self)); diff --git a/shared-bindings/synthio/MidiTrack.c b/shared-bindings/synthio/MidiTrack.c index dee42770630..0304df12a81 100644 --- a/shared-bindings/synthio/MidiTrack.c +++ b/shared-bindings/synthio/MidiTrack.c @@ -13,6 +13,7 @@ #include "shared-bindings/util.h" #include "shared-bindings/synthio/MidiTrack.h" #include "shared-bindings/synthio/__init__.h" +#include "shared-bindings/audiocore/__init__.h" //| class MidiTrack: //| """Simple MIDI synth""" @@ -52,6 +53,7 @@ //| pass //| print("stopped")""" //| ... +//| static mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_buffer, ARG_tempo, ARG_sample_rate, ARG_waveform, ARG_envelope }; static const mp_arg_t allowed_args[] = { @@ -68,7 +70,6 @@ static mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_a mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); synthio_miditrack_obj_t *self = mp_obj_malloc(synthio_miditrack_obj_t, &synthio_miditrack_type); - common_hal_synthio_miditrack_construct(self, (uint8_t *)bufinfo.buf, bufinfo.len, args[ARG_tempo].u_int, @@ -84,6 +85,7 @@ static mp_obj_t synthio_miditrack_make_new(const mp_obj_type_t *type, size_t n_a //| def deinit(self) -> None: //| """Deinitialises the MidiTrack and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t synthio_miditrack_deinit(mp_obj_t self_in) { synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_synthio_miditrack_deinit(self); @@ -92,43 +94,51 @@ static mp_obj_t synthio_miditrack_deinit(mp_obj_t self_in) { static MP_DEFINE_CONST_FUN_OBJ_1(synthio_miditrack_deinit_obj, synthio_miditrack_deinit); static void check_for_deinit(synthio_miditrack_obj_t *self) { - if (common_hal_synthio_miditrack_deinited(self)) { - raise_deinited_error(); - } + audiosample_check_for_deinit(&self->synth.base); } //| def __enter__(self) -> MidiTrack: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t synthio_miditrack_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_synthio_miditrack_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(synthio_miditrack___exit___obj, 4, 4, synthio_miditrack_obj___exit__); +//| +// Provided by context manager helper. //| sample_rate: int //| """32 bit value that tells how quickly samples are played in Hertz (cycles per second).""" //| -static mp_obj_t synthio_miditrack_obj_get_sample_rate(mp_obj_t self_in) { + +//| tempo: int +//| """Tempo of the streamed events, in MIDI ticks per second.""" +//| +static mp_obj_t synthio_miditrack_obj_get_tempo(mp_obj_t self_in) { synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_synthio_miditrack_get_sample_rate(self)); + return mp_obj_new_int(common_hal_synthio_miditrack_get_tempo(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(synthio_miditrack_get_sample_rate_obj, synthio_miditrack_obj_get_sample_rate); +MP_DEFINE_CONST_FUN_OBJ_1(synthio_miditrack_get_tempo_obj, synthio_miditrack_obj_get_tempo); -MP_PROPERTY_GETTER(synthio_miditrack_sample_rate_obj, - (mp_obj_t)&synthio_miditrack_get_sample_rate_obj); +static mp_obj_t synthio_miditrack_obj_set_tempo(mp_obj_t self_in, mp_obj_t arg) { + synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_synthio_miditrack_set_tempo(self, mp_obj_get_int(arg)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(synthio_miditrack_set_tempo_obj, synthio_miditrack_obj_set_tempo); +MP_PROPERTY_GETSET(synthio_miditrack_tempo_obj, + (mp_obj_t)&synthio_miditrack_get_tempo_obj, + (mp_obj_t)&synthio_miditrack_set_tempo_obj); //| error_location: Optional[int] //| """Offset, in bytes within the midi data, of a decoding error""" //| +//| static mp_obj_t synthio_miditrack_obj_get_error_location(mp_obj_t self_in) { synthio_miditrack_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -147,22 +157,19 @@ static const mp_rom_map_elem_t synthio_miditrack_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&synthio_miditrack_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&synthio_miditrack___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&synthio_miditrack_sample_rate_obj) }, { MP_ROM_QSTR(MP_QSTR_error_location), MP_ROM_PTR(&synthio_miditrack_error_location_obj) }, + { MP_ROM_QSTR(MP_QSTR_tempo), MP_ROM_PTR(&synthio_miditrack_tempo_obj) }, + AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(synthio_miditrack_locals_dict, synthio_miditrack_locals_dict_table); static const audiosample_p_t synthio_miditrack_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) - .sample_rate = (audiosample_sample_rate_fun)common_hal_synthio_miditrack_get_sample_rate, - .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_synthio_miditrack_get_bits_per_sample, - .channel_count = (audiosample_channel_count_fun)common_hal_synthio_miditrack_get_channel_count, .reset_buffer = (audiosample_reset_buffer_fun)synthio_miditrack_reset_buffer, .get_buffer = (audiosample_get_buffer_fun)synthio_miditrack_get_buffer, - .get_buffer_structure = (audiosample_get_buffer_structure_fun)synthio_miditrack_get_buffer_structure, }; MP_DEFINE_CONST_OBJ_TYPE( diff --git a/shared-bindings/synthio/MidiTrack.h b/shared-bindings/synthio/MidiTrack.h index 50a6c921cb6..cb154d3996b 100644 --- a/shared-bindings/synthio/MidiTrack.h +++ b/shared-bindings/synthio/MidiTrack.h @@ -14,8 +14,7 @@ extern const mp_obj_type_t synthio_miditrack_type; void common_hal_synthio_miditrack_construct(synthio_miditrack_obj_t *self, const uint8_t *buffer, uint32_t len, uint32_t tempo, uint32_t sample_rate, mp_obj_t waveform_obj, mp_obj_t filter_obj, mp_obj_t envelope_obj); void common_hal_synthio_miditrack_deinit(synthio_miditrack_obj_t *self); -bool common_hal_synthio_miditrack_deinited(synthio_miditrack_obj_t *self); -uint32_t common_hal_synthio_miditrack_get_sample_rate(synthio_miditrack_obj_t *self); -uint8_t common_hal_synthio_miditrack_get_bits_per_sample(synthio_miditrack_obj_t *self); -uint8_t common_hal_synthio_miditrack_get_channel_count(synthio_miditrack_obj_t *self); mp_int_t common_hal_synthio_miditrack_get_error_location(synthio_miditrack_obj_t *self); + +mp_int_t common_hal_synthio_miditrack_get_tempo(synthio_miditrack_obj_t *self); +void common_hal_synthio_miditrack_set_tempo(synthio_miditrack_obj_t *self, mp_int_t value); diff --git a/shared-bindings/synthio/Note.c b/shared-bindings/synthio/Note.c index c886f106a4c..183c59d5fbd 100644 --- a/shared-bindings/synthio/Note.c +++ b/shared-bindings/synthio/Note.c @@ -20,15 +20,15 @@ static const mp_arg_t note_properties[] = { { MP_QSTR_amplitude, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(1) } }, { MP_QSTR_bend, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } }, { MP_QSTR_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, - { MP_QSTR_waveform_loop_start, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } }, - { MP_QSTR_waveform_loop_end, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } }, + { MP_QSTR_waveform_loop_start, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } }, + { MP_QSTR_waveform_loop_end, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } }, { MP_QSTR_envelope, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, { MP_QSTR_filter, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, - { MP_QSTR_ring_frequency, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } }, - { MP_QSTR_ring_bend, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } }, + { MP_QSTR_ring_frequency, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } }, + { MP_QSTR_ring_bend, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } }, { MP_QSTR_ring_waveform, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_NONE } }, - { MP_QSTR_ring_waveform_loop_start, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(0) } }, - { MP_QSTR_ring_waveform_loop_end, MP_ARG_OBJ, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } }, + { MP_QSTR_ring_waveform_loop_start, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(0) } }, + { MP_QSTR_ring_waveform_loop_end, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = MP_ROM_INT(SYNTHIO_WAVEFORM_SIZE) } }, }; //| class Note: //| def __init__( @@ -37,17 +37,17 @@ static const mp_arg_t note_properties[] = { //| frequency: float, //| panning: BlockInput = 0.0, //| waveform: Optional[ReadableBuffer] = None, -//| waveform_loop_start: int = 0, -//| waveform_loop_end: int = waveform_max_length, +//| waveform_loop_start: BlockInput = 0, +//| waveform_loop_end: BlockInput = waveform_max_length, //| envelope: Optional[Envelope] = None, -//| amplitude: BlockInput = 0.0, +//| amplitude: BlockInput = 1.0, //| bend: BlockInput = 0.0, //| filter: Optional[Biquad] = None, //| ring_frequency: float = 0.0, //| ring_bend: float = 0.0, //| ring_waveform: Optional[ReadableBuffer] = None, -//| ring_waveform_loop_start: int = 0, -//| ring_waveform_loop_end: int = waveform_max_length, +//| ring_waveform_loop_start: BlockInput = 0, +//| ring_waveform_loop_end: BlockInput = waveform_max_length, //| ) -> None: //| """Construct a Note object, with a frequency in Hz, and optional panning, waveform, envelope, tremolo (volume change) and bend (frequency change). //| @@ -55,16 +55,17 @@ static const mp_arg_t note_properties[] = { //| //| If the same Note object is played on multiple Synthesizer objects, the result is undefined. //| """ +//| static mp_obj_t synthio_note_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_val_t args[MP_ARRAY_SIZE(note_properties)]; mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(note_properties), note_properties, args); synthio_note_obj_t *self = mp_obj_malloc(synthio_note_obj_t, &synthio_note_type); + mp_obj_t self_obj = MP_OBJ_FROM_PTR(self); - mp_obj_t result = MP_OBJ_FROM_PTR(self); - properties_construct_helper(result, note_properties, args, MP_ARRAY_SIZE(note_properties)); + properties_construct_helper(self_obj, note_properties, args, MP_ARRAY_SIZE(note_properties)); - return result; + return self_obj; }; //| frequency: float @@ -198,21 +199,21 @@ MP_PROPERTY_GETSET(synthio_note_waveform_obj, (mp_obj_t)&synthio_note_get_waveform_obj, (mp_obj_t)&synthio_note_set_waveform_obj); -//| waveform_loop_start: int + + +//| waveform_loop_start: BlockInput //| """The sample index of where to begin looping waveform data. //| -//| Values outside the range ``0`` to ``waveform_max_length-1`` (inclusive) are rejected with a `ValueError`. -//| -//| Values greater than or equal to the actual waveform length are treated as 0.""" +//| The value is limited to the range ``0`` to ``len(waveform)-1`` (inclusive).""" static mp_obj_t synthio_note_get_waveform_loop_start(mp_obj_t self_in) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(common_hal_synthio_note_get_waveform_loop_start(self)); + return common_hal_synthio_note_get_waveform_loop_start(self); } MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_waveform_loop_start_obj, synthio_note_get_waveform_loop_start); static mp_obj_t synthio_note_set_waveform_loop_start(mp_obj_t self_in, mp_obj_t arg) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_synthio_note_set_waveform_loop_start(self, mp_obj_get_int(arg)); + common_hal_synthio_note_set_waveform_loop_start(self, arg); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_waveform_loop_start_obj, synthio_note_set_waveform_loop_start); @@ -220,24 +221,22 @@ MP_PROPERTY_GETSET(synthio_note_waveform_loop_start_obj, (mp_obj_t)&synthio_note_get_waveform_loop_start_obj, (mp_obj_t)&synthio_note_set_waveform_loop_start_obj); -//| waveform_loop_end: int +//| waveform_loop_end: BlockInput //| """The sample index of where to end looping waveform data. //| -//| Values outside the range ``1`` to ``waveform_max_length`` (inclusive) are rejected with a `ValueError`. -//| -//| If the value is greater than the actual waveform length, or less than or equal to the loop start, the loop will occur at the end of the waveform. +//| The value is limited to the range ``waveform_loop_start+1`` to ``len(waveform)`` (inclusive). //| //| Use the `synthio.waveform_max_length` constant to set the loop point at the end of the wave form, no matter its length.""" //| static mp_obj_t synthio_note_get_waveform_loop_end(mp_obj_t self_in) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(common_hal_synthio_note_get_waveform_loop_end(self)); + return common_hal_synthio_note_get_waveform_loop_end(self); } MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_waveform_loop_end_obj, synthio_note_get_waveform_loop_end); static mp_obj_t synthio_note_set_waveform_loop_end(mp_obj_t self_in, mp_obj_t arg) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_synthio_note_set_waveform_loop_end(self, mp_obj_get_int(arg)); + common_hal_synthio_note_set_waveform_loop_end(self, arg); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_waveform_loop_end_obj, synthio_note_set_waveform_loop_end); @@ -331,21 +330,19 @@ MP_PROPERTY_GETSET(synthio_note_ring_waveform_obj, (mp_obj_t)&synthio_note_get_ring_waveform_obj, (mp_obj_t)&synthio_note_set_ring_waveform_obj); -//| ring_waveform_loop_start: int +//| ring_waveform_loop_start: BlockInput //| """The sample index of where to begin looping waveform data. //| -//| Values outside the range ``0`` to ``waveform_max_length-1`` (inclusive) are rejected with a `ValueError`. -//| -//| Values greater than or equal to the actual waveform length are treated as 0.""" +//| The value is limited to the range ``0`` to ``len(ring_waveform)-1`` (inclusive).""" static mp_obj_t synthio_note_get_ring_waveform_loop_start(mp_obj_t self_in) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(common_hal_synthio_note_get_ring_waveform_loop_start(self)); + return common_hal_synthio_note_get_ring_waveform_loop_start(self); } MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_ring_waveform_loop_start_obj, synthio_note_get_ring_waveform_loop_start); static mp_obj_t synthio_note_set_ring_waveform_loop_start(mp_obj_t self_in, mp_obj_t arg) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_synthio_note_set_ring_waveform_loop_start(self, mp_obj_get_int(arg)); + common_hal_synthio_note_set_ring_waveform_loop_start(self, arg); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_ring_waveform_loop_start_obj, synthio_note_set_ring_waveform_loop_start); @@ -353,24 +350,23 @@ MP_PROPERTY_GETSET(synthio_note_ring_waveform_loop_start_obj, (mp_obj_t)&synthio_note_get_ring_waveform_loop_start_obj, (mp_obj_t)&synthio_note_set_ring_waveform_loop_start_obj); -//| ring_waveform_loop_end: int +//| ring_waveform_loop_end: BlockInput //| """The sample index of where to end looping waveform data. //| -//| Values outside the range ``1`` to ``waveform_max_length`` (inclusive) are rejected with a `ValueError`. -//| -//| If the value is greater than the actual waveform length, or less than or equal to the loop start, the loop will occur at the end of the waveform. +//| The value is limited to the range ``ring_waveform_loop_start+1`` to ``len(ring_waveform)`` (inclusive). //| //| Use the `synthio.waveform_max_length` constant to set the loop point at the end of the wave form, no matter its length.""" //| +//| static mp_obj_t synthio_note_get_ring_waveform_loop_end(mp_obj_t self_in) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(common_hal_synthio_note_get_ring_waveform_loop_end(self)); + return common_hal_synthio_note_get_ring_waveform_loop_end(self); } MP_DEFINE_CONST_FUN_OBJ_1(synthio_note_get_ring_waveform_loop_end_obj, synthio_note_get_ring_waveform_loop_end); static mp_obj_t synthio_note_set_ring_waveform_loop_end(mp_obj_t self_in, mp_obj_t arg) { synthio_note_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_synthio_note_set_ring_waveform_loop_end(self, mp_obj_get_int(arg)); + common_hal_synthio_note_set_ring_waveform_loop_end(self, arg); return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_2(synthio_note_set_ring_waveform_loop_end_obj, synthio_note_set_ring_waveform_loop_end); diff --git a/shared-bindings/synthio/Note.h b/shared-bindings/synthio/Note.h index 0ee450acfe4..707b9f2e104 100644 --- a/shared-bindings/synthio/Note.h +++ b/shared-bindings/synthio/Note.h @@ -31,11 +31,11 @@ void common_hal_synthio_note_set_bend(synthio_note_obj_t *self, mp_obj_t value); mp_obj_t common_hal_synthio_note_get_waveform_obj(synthio_note_obj_t *self); void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t value); -mp_int_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self); -void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in); +mp_obj_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self); +void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value); -mp_int_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self); -void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in); +mp_obj_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self); +void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value); mp_float_t common_hal_synthio_note_get_ring_frequency(synthio_note_obj_t *self); void common_hal_synthio_note_set_ring_frequency(synthio_note_obj_t *self, mp_float_t value); @@ -46,11 +46,11 @@ void common_hal_synthio_note_set_ring_bend(synthio_note_obj_t *self, mp_obj_t va mp_obj_t common_hal_synthio_note_get_ring_waveform_obj(synthio_note_obj_t *self); void common_hal_synthio_note_set_ring_waveform(synthio_note_obj_t *self, mp_obj_t value); -mp_int_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self); -void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in); +mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self); +void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value); -mp_int_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self); -void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in); +mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self); +void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value); mp_obj_t common_hal_synthio_note_get_envelope_obj(synthio_note_obj_t *self); void common_hal_synthio_note_set_envelope(synthio_note_obj_t *self, mp_obj_t value); diff --git a/shared-bindings/synthio/Synthesizer.c b/shared-bindings/synthio/Synthesizer.c index 87ea44de694..35cc42a2037 100644 --- a/shared-bindings/synthio/Synthesizer.c +++ b/shared-bindings/synthio/Synthesizer.c @@ -17,6 +17,7 @@ #include "shared-bindings/synthio/Synthesizer.h" #include "shared-bindings/synthio/LFO.h" #include "shared-bindings/synthio/__init__.h" +#include "shared-bindings/audiocore/__init__.h" //| NoteSequence = Sequence[Union[int, Note]] //| """A sequence of notes, which can each be integer MIDI note numbers or `Note` objects""" @@ -25,6 +26,7 @@ //| LFOOrLFOSequence = Union["LFO", Sequence["LFO"]] //| """An LFO or a sequence of LFOs""" //| +//| //| class Synthesizer: //| def __init__( //| self, @@ -47,6 +49,7 @@ //| :param ReadableBuffer waveform: A single-cycle waveform. Default is a 50% duty cycle square wave. If specified, must be a ReadableBuffer of type 'h' (signed 16 bit) //| :param Optional[Envelope] envelope: An object that defines the loudness of a note over time. The default envelope, `None` provides no ramping, voices turn instantly on and off. //| """ +//| static mp_obj_t synthio_synthesizer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_sample_rate, ARG_channel_count, ARG_waveform, ARG_envelope }; static const mp_arg_t allowed_args[] = { @@ -59,7 +62,6 @@ static mp_obj_t synthio_synthesizer_make_new(const mp_obj_type_t *type, size_t n mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); synthio_synthesizer_obj_t *self = mp_obj_malloc(synthio_synthesizer_obj_t, &synthio_synthesizer_type); - common_hal_synthio_synthesizer_construct(self, args[ARG_sample_rate].u_int, args[ARG_channel_count].u_int, @@ -70,9 +72,7 @@ static mp_obj_t synthio_synthesizer_make_new(const mp_obj_type_t *type, size_t n } static void check_for_deinit(synthio_synthesizer_obj_t *self) { - if (common_hal_synthio_synthesizer_deinited(self)) { - raise_deinited_error(); - } + audiosample_check_for_deinit(&self->synth.base); } //| def press(self, /, press: NoteOrNoteSequence = ()) -> None: @@ -81,6 +81,7 @@ static void check_for_deinit(synthio_synthesizer_obj_t *self) { //| Pressing a note that was already pressed has no effect. //| //| :param NoteOrNoteSequence press: Any sequence of notes.""" +//| static mp_obj_t synthio_synthesizer_press(mp_obj_t self_in, mp_obj_t press) { synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -94,6 +95,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(synthio_synthesizer_press_obj, synthio_synthesi //| Releasing a note that was already released has no effect. //| //| :param NoteOrNoteSequence release: Any sequence of notes.""" +//| static mp_obj_t synthio_synthesizer_release(mp_obj_t self_in, mp_obj_t release) { synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -127,6 +129,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(synthio_synthesizer_release_obj, synthio_synthe //| //| Note: for compatibility, ``release_then_press`` may be used as an alias //| for this function. This compatibility name will be removed in 9.0.""" +//| static mp_obj_t synthio_synthesizer_change(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_release, ARG_press, ARG_retrigger }; static const mp_arg_t allowed_args[] = { @@ -155,6 +158,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(synthio_synthesizer_change_obj, 1, synthio_syn //| attack phase with an initial amplitude of 0. //| //| :param NoteOrNoteSequence press: Any sequence of notes.""" +//| static mp_obj_t synthio_synthesizer_release_all_then_press(mp_obj_t self_in, mp_obj_t press) { synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -167,6 +171,7 @@ static MP_DEFINE_CONST_FUN_OBJ_2(synthio_synthesizer_release_all_then_press_obj, // //| def release_all(self) -> None: //| """Turn any currently-playing notes off""" +//| static mp_obj_t synthio_synthesizer_release_all(mp_obj_t self_in) { synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -178,6 +183,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_release_all_obj, synthio_sy //| def deinit(self) -> None: //| """Deinitialises the object and releases any memory resources for reuse.""" //| ... +//| static mp_obj_t synthio_synthesizer_deinit(mp_obj_t self_in) { synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_synthio_synthesizer_deinit(self); @@ -188,18 +194,15 @@ static MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_deinit_obj, synthio_synthes //| def __enter__(self) -> Synthesizer: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t synthio_synthesizer_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_synthio_synthesizer_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(synthio_synthesizer___exit___obj, 4, 4, synthio_synthesizer_obj___exit__); +//| +// Provided by context manager helper. //| envelope: Optional[Envelope] //| """The envelope to apply to all notes. `None`, the default envelope, instantly turns notes on and off. The envelope may be changed dynamically, but it affects all notes (even currently playing notes)""" @@ -224,15 +227,6 @@ MP_PROPERTY_GETSET(synthio_synthesizer_envelope_obj, //| sample_rate: int //| """32 bit value that tells how quickly samples are played in Hertz (cycles per second).""" -static mp_obj_t synthio_synthesizer_obj_get_sample_rate(mp_obj_t self_in) { - synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_for_deinit(self); - return MP_OBJ_NEW_SMALL_INT(common_hal_synthio_synthesizer_get_sample_rate(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_get_sample_rate_obj, synthio_synthesizer_obj_get_sample_rate); - -MP_PROPERTY_GETTER(synthio_synthesizer_sample_rate_obj, - (mp_obj_t)&synthio_synthesizer_get_sample_rate_obj); //| pressed: NoteSequence //| """A sequence of the currently pressed notes (read-only property). @@ -255,6 +249,7 @@ MP_PROPERTY_GETTER(synthio_synthesizer_pressed_obj, //| If the note is currently playing (including in the release phase), the returned value gives the current envelope state and the current envelope value. //| //| If the note is not playing on this synthesizer, returns the tuple ``(None, 0.0)``.""" +//| static mp_obj_t synthio_synthesizer_obj_note_info(mp_obj_t self_in, mp_obj_t note) { synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -273,6 +268,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(synthio_synthesizer_note_info_obj, synthio_synthesizer //| //| This property is read-only but its contents may be modified by e.g., calling ``synth.blocks.append()`` or ``synth.blocks.remove()``. It is initially an empty list.""" //| +//| static mp_obj_t synthio_synthesizer_obj_get_blocks(mp_obj_t self_in) { synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -283,118 +279,6 @@ MP_DEFINE_CONST_FUN_OBJ_1(synthio_synthesizer_get_blocks_obj, synthio_synthesize MP_PROPERTY_GETTER(synthio_synthesizer_blocks_obj, (mp_obj_t)&synthio_synthesizer_get_blocks_obj); -//| max_polyphony: int -//| """Maximum polyphony of the synthesizer (read-only class property)""" -//| - -//| def low_pass_filter(cls, frequency: float, q_factor: float = 0.7071067811865475) -> Biquad: -//| """Construct a low-pass filter with the given parameters. -//| -//| ``frequency``, called f0 in the cookbook, is the corner frequency in Hz -//| of the filter. -//| -//| ``q_factor``, called ``Q`` in the cookbook. Controls how peaked the response will be at the cutoff frequency. A large value makes the response more peaked. -//| """ - -enum passfilter_arg_e { ARG_f0, ARG_Q }; - -// M_PI is not part of the math.h standard and may not be defined -// And by defining our own we can ensure it uses the correct const format. -#define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846) - -static const mp_arg_t passfilter_properties[] = { - { MP_QSTR_frequency, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_obj = MP_ROM_NONE} }, - { MP_QSTR_Q, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL } }, -}; - -static mp_obj_t synthio_synthesizer_lpf(size_t n_pos, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_arg_val_t args[MP_ARRAY_SIZE(passfilter_properties)]; - - mp_obj_t self_in = pos_args[0]; - synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_arg_parse_all(n_pos - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(passfilter_properties), passfilter_properties, args); - - mp_float_t f0 = mp_arg_validate_type_float(args[ARG_f0].u_obj, MP_QSTR_f0); - mp_float_t Q = - args[ARG_Q].u_obj == MP_OBJ_NULL ? MICROPY_FLOAT_CONST(0.7071067811865475) : - mp_arg_validate_type_float(args[ARG_Q].u_obj, MP_QSTR_Q); - - mp_float_t w0 = f0 / self->synth.sample_rate * 2 * MP_PI; - - return common_hal_synthio_new_lpf(w0, Q); - -} - -MP_DEFINE_CONST_FUN_OBJ_KW(synthio_synthesizer_lpf_fun_obj, 1, synthio_synthesizer_lpf); - -//| def high_pass_filter( -//| cls, frequency: float, q_factor: float = 0.7071067811865475 -//| ) -> Biquad: -//| """Construct a high-pass filter with the given parameters. -//| -//| ``frequency``, called f0 in the cookbook, is the corner frequency in Hz -//| of the filter. -//| -//| ``q_factor``, called ``Q`` in the cookbook. Controls how peaked the response will be at the cutoff frequency. A large value makes the response more peaked. -//| """ - -static mp_obj_t synthio_synthesizer_hpf(size_t n_pos, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_arg_val_t args[MP_ARRAY_SIZE(passfilter_properties)]; - - mp_obj_t self_in = pos_args[0]; - synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_arg_parse_all(n_pos - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(passfilter_properties), passfilter_properties, args); - - mp_float_t f0 = mp_arg_validate_type_float(args[ARG_f0].u_obj, MP_QSTR_f0); - mp_float_t Q = - args[ARG_Q].u_obj == MP_OBJ_NULL ? MICROPY_FLOAT_CONST(0.7071067811865475) : - mp_arg_validate_type_float(args[ARG_Q].u_obj, MP_QSTR_Q); - - mp_float_t w0 = f0 / self->synth.sample_rate * 2 * MP_PI; - - return common_hal_synthio_new_hpf(w0, Q); - -} - -//| def band_pass_filter( -//| cls, frequency: float, q_factor: float = 0.7071067811865475 -//| ) -> Biquad: -//| """Construct a band-pass filter with the given parameters. -//| -//| ``frequency``, called f0 in the cookbook, is the center frequency in Hz -//| of the filter. -//| -//| ``q_factor``, called ``Q`` in the cookbook. Controls how peaked the response will be at the cutoff frequency. A large value makes the response more peaked. -//| -//| The coefficients are scaled such that the filter has a 0dB peak gain. -//| """ -//| - -MP_DEFINE_CONST_FUN_OBJ_KW(synthio_synthesizer_hpf_fun_obj, 1, synthio_synthesizer_hpf); - -static mp_obj_t synthio_synthesizer_bpf(size_t n_pos, const mp_obj_t *pos_args, mp_map_t *kw_args) { - mp_arg_val_t args[MP_ARRAY_SIZE(passfilter_properties)]; - - mp_obj_t self_in = pos_args[0]; - synthio_synthesizer_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_arg_parse_all(n_pos - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(passfilter_properties), passfilter_properties, args); - - mp_float_t f0 = mp_arg_validate_type_float(args[ARG_f0].u_obj, MP_QSTR_f0); - mp_float_t Q = - args[ARG_Q].u_obj == MP_OBJ_NULL ? MICROPY_FLOAT_CONST(0.7071067811865475) : - mp_arg_validate_type_float(args[ARG_Q].u_obj, MP_QSTR_Q); - - mp_float_t w0 = f0 / self->synth.sample_rate * 2 * MP_PI; - - return common_hal_synthio_new_bpf(w0, Q); - -} - -MP_DEFINE_CONST_FUN_OBJ_KW(synthio_synthesizer_bpf_fun_obj, 1, synthio_synthesizer_bpf); - static const mp_rom_map_elem_t synthio_synthesizer_locals_dict_table[] = { // Methods { MP_ROM_QSTR(MP_QSTR_press), MP_ROM_PTR(&synthio_synthesizer_press_obj) }, @@ -405,29 +289,22 @@ static const mp_rom_map_elem_t synthio_synthesizer_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_release_all_then_press), MP_ROM_PTR(&synthio_synthesizer_release_all_then_press_obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&synthio_synthesizer_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&synthio_synthesizer___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_low_pass_filter), MP_ROM_PTR(&synthio_synthesizer_lpf_fun_obj) }, - { MP_ROM_QSTR(MP_QSTR_high_pass_filter), MP_ROM_PTR(&synthio_synthesizer_hpf_fun_obj) }, - { MP_ROM_QSTR(MP_QSTR_band_pass_filter), MP_ROM_PTR(&synthio_synthesizer_bpf_fun_obj) }, // Properties { MP_ROM_QSTR(MP_QSTR_envelope), MP_ROM_PTR(&synthio_synthesizer_envelope_obj) }, - { MP_ROM_QSTR(MP_QSTR_sample_rate), MP_ROM_PTR(&synthio_synthesizer_sample_rate_obj) }, { MP_ROM_QSTR(MP_QSTR_max_polyphony), MP_ROM_INT(CIRCUITPY_SYNTHIO_MAX_CHANNELS) }, { MP_ROM_QSTR(MP_QSTR_pressed), MP_ROM_PTR(&synthio_synthesizer_pressed_obj) }, { MP_ROM_QSTR(MP_QSTR_note_info), MP_ROM_PTR(&synthio_synthesizer_note_info_obj) }, { MP_ROM_QSTR(MP_QSTR_blocks), MP_ROM_PTR(&synthio_synthesizer_blocks_obj) }, + AUDIOSAMPLE_FIELDS, }; static MP_DEFINE_CONST_DICT(synthio_synthesizer_locals_dict, synthio_synthesizer_locals_dict_table); static const audiosample_p_t synthio_synthesizer_proto = { MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) - .sample_rate = (audiosample_sample_rate_fun)common_hal_synthio_synthesizer_get_sample_rate, - .bits_per_sample = (audiosample_bits_per_sample_fun)common_hal_synthio_synthesizer_get_bits_per_sample, - .channel_count = (audiosample_channel_count_fun)common_hal_synthio_synthesizer_get_channel_count, .reset_buffer = (audiosample_reset_buffer_fun)synthio_synthesizer_reset_buffer, .get_buffer = (audiosample_get_buffer_fun)synthio_synthesizer_get_buffer, - .get_buffer_structure = (audiosample_get_buffer_structure_fun)synthio_synthesizer_get_buffer_structure, }; MP_DEFINE_CONST_OBJ_TYPE( diff --git a/shared-bindings/synthio/Synthesizer.h b/shared-bindings/synthio/Synthesizer.h index 65e15ae88ad..ffadb433047 100644 --- a/shared-bindings/synthio/Synthesizer.h +++ b/shared-bindings/synthio/Synthesizer.h @@ -15,10 +15,6 @@ void common_hal_synthio_synthesizer_construct(synthio_synthesizer_obj_t *self, uint32_t sample_rate, int channel_count, mp_obj_t waveform_obj, mp_obj_t envelope_obj); void common_hal_synthio_synthesizer_deinit(synthio_synthesizer_obj_t *self); -bool common_hal_synthio_synthesizer_deinited(synthio_synthesizer_obj_t *self); -uint32_t common_hal_synthio_synthesizer_get_sample_rate(synthio_synthesizer_obj_t *self); -uint8_t common_hal_synthio_synthesizer_get_bits_per_sample(synthio_synthesizer_obj_t *self); -uint8_t common_hal_synthio_synthesizer_get_channel_count(synthio_synthesizer_obj_t *self); void common_hal_synthio_synthesizer_release(synthio_synthesizer_obj_t *self, mp_obj_t to_release); void common_hal_synthio_synthesizer_press(synthio_synthesizer_obj_t *self, mp_obj_t to_press); void common_hal_synthio_synthesizer_retrigger(synthio_synthesizer_obj_t *self, mp_obj_t to_retrigger); diff --git a/shared-bindings/synthio/__init__.c b/shared-bindings/synthio/__init__.c index fbc5cd559af..6a21834751b 100644 --- a/shared-bindings/synthio/__init__.c +++ b/shared-bindings/synthio/__init__.c @@ -32,6 +32,8 @@ //| """ //| +//| +//| //| class EnvelopeState: //| ATTACK: EnvelopeState //| """The note is in its attack phase""" @@ -42,6 +44,7 @@ //| RELEASE: EnvelopeState //| """The note is in its release phase""" //| +//| MAKE_ENUM_VALUE(synthio_note_state_type, note_state, ATTACK, SYNTHIO_ENVELOPE_STATE_ATTACK); MAKE_ENUM_VALUE(synthio_note_state_type, note_state, DECAY, SYNTHIO_ENVELOPE_STATE_DECAY); MAKE_ENUM_VALUE(synthio_note_state_type, note_state, SUSTAIN, SYNTHIO_ENVELOPE_STATE_SUSTAIN); @@ -78,6 +81,7 @@ static const mp_arg_t envelope_properties[] = { //| A BlockInput can be any of the following types: `Math`, `LFO`, `builtins.float`, `None` (treated same as 0). //| """ //| +//| //| class Envelope: //| def __init__( //| self, @@ -102,6 +106,7 @@ static const mp_arg_t envelope_properties[] = { //| :param float attack_level: The level, in the range ``0.0`` to ``1.0`` of the peak volume of the attack phase //| :param float sustain_level: The level, in the range ``0.0`` to ``1.0`` of the volume of the sustain phase relative to the attack level //| """ +//| //| attack_time: float //| """The time in seconds it takes to ramp from 0 volume to attack_volume""" //| @@ -117,6 +122,7 @@ static const mp_arg_t envelope_properties[] = { //| sustain_level: float //| """The level, in the range ``0.0`` to ``1.0`` of the volume of the sustain phase relative to the attack level""" //| +//| static mp_obj_t synthio_envelope_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { mp_arg_val_t args[MP_ARRAY_SIZE(envelope_properties)]; @@ -194,6 +200,7 @@ const mp_obj_namedtuple_type_t synthio_envelope_type_obj = { //| print("stopped")""" //| ... //| +//| static mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_file, ARG_sample_rate, ARG_waveform, ARG_envelope }; static const mp_arg_t allowed_args[] = { @@ -236,7 +243,7 @@ static mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma } uint32_t track_size = (chunk_header[4] << 24) | (chunk_header[5] << 16) | (chunk_header[6] << 8) | chunk_header[7]; - uint8_t *buffer = m_malloc(track_size); + uint8_t *buffer = m_malloc_without_collect(track_size); if (f_read(&file->fp, buffer, track_size, &bytes_read) != FR_OK) { mp_raise_OSError(MP_EIO); } @@ -245,7 +252,6 @@ static mp_obj_t synthio_from_file(size_t n_args, const mp_obj_t *pos_args, mp_ma } synthio_miditrack_obj_t *result = mp_obj_malloc(synthio_miditrack_obj_t, &synthio_miditrack_type); - common_hal_synthio_miditrack_construct(result, buffer, track_size, tempo, args[ARG_sample_rate].u_int, args[ARG_waveform].u_obj, mp_const_none, @@ -265,6 +271,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(synthio_from_file_obj, 1, synthio_from_file); //| def midi_to_hz(midi_note: float) -> float: //| """Converts the given midi note (60 = middle C, 69 = concert A) to Hz""" //| +//| static mp_obj_t midi_to_hz(mp_obj_t arg) { mp_float_t note = mp_arg_validate_type_float(arg, MP_QSTR_note); @@ -277,6 +284,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(synthio_midi_to_hz_obj, midi_to_hz); //| //| 24/12 (2.0) corresponds to middle C, 33/12 (2.75) is concert A.""" //| +//| static mp_obj_t voct_to_hz(mp_obj_t arg) { mp_float_t note = mp_arg_validate_obj_float_range(arg, -11, 11, MP_QSTR_ctrl); @@ -291,7 +299,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(synthio_voct_to_hz_obj, voct_to_hz); #if CIRCUITPY_AUDIOCORE_DEBUG static mp_obj_t synthio_lfo_tick(size_t n, const mp_obj_t *args) { - shared_bindings_synthio_lfo_tick(48000); + shared_bindings_synthio_lfo_tick(48000, SYNTHIO_MAX_DUR); mp_obj_t result[n]; for (size_t i = 0; i < n; i++) { synthio_block_slot_t slot; @@ -307,6 +315,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR(synthio_lfo_tick_obj, 1, synthio_lfo_tick); static const mp_rom_map_elem_t synthio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_synthio) }, { MP_ROM_QSTR(MP_QSTR_Biquad), MP_ROM_PTR(&synthio_biquad_type_obj) }, + { MP_ROM_QSTR(MP_QSTR_FilterMode), MP_ROM_PTR(&synthio_filter_mode_type) }, { MP_ROM_QSTR(MP_QSTR_Math), MP_ROM_PTR(&synthio_math_type) }, { MP_ROM_QSTR(MP_QSTR_MathOperation), MP_ROM_PTR(&synthio_math_operation_type) }, { MP_ROM_QSTR(MP_QSTR_MidiTrack), MP_ROM_PTR(&synthio_miditrack_type) }, diff --git a/shared-bindings/terminalio/Terminal.c b/shared-bindings/terminalio/Terminal.c index 1173cbbe244..320d4cc667a 100644 --- a/shared-bindings/terminalio/Terminal.c +++ b/shared-bindings/terminalio/Terminal.c @@ -16,23 +16,114 @@ #include "py/stream.h" #include "shared-bindings/fontio/BuiltinFont.h" +#if CIRCUITPY_LVFONTIO +#include "shared-bindings/lvfontio/OnDiskFont.h" +#endif + //| class Terminal: -//| """Display a character stream with a TileGrid +//| """Terminal manages tile indices and cursor position based on VT100 commands. The ``font`` should be +//| a `fontio.BuiltinFont` and the ``scroll_area`` TileGrid's bitmap should match the font's bitmap. +//| +//| Display a character stream with a TileGrid //| //| ASCII control: +//| //| * ``\\r`` - Move cursor to column 1 //| * ``\\n`` - Move cursor down a row //| * ``\\b`` - Move cursor left one if possible //| //| OSC control sequences: +//| //| * ``ESC ] 0; ESC \\`` - Set title bar to //| * ``ESC ] ####; ESC \\`` - Ignored //| //| VT100 control sequences: +//| //| * ``ESC [ K`` - Clear the remainder of the line +//| * ``ESC [ 0 K`` - Clear the remainder of the line +//| * ``ESC [ 1 K`` - Clear start of the line to cursor +//| * ``ESC [ 2 K`` - Clear the entire line //| * ``ESC [ #### D`` - Move the cursor to the left by #### //| * ``ESC [ 2 J`` - Erase the entire display //| * ``ESC [ nnnn ; mmmm H`` - Move the cursor to mmmm, nnnn. +//| * ``ESC [ H`` - Move the cursor to 0,0. +//| * ``ESC M`` - Move the cursor up one line, scrolling if necessary. +//| * ``ESC D`` - Move the cursor down one line, scrolling if necessary. +//| * ``ESC [ r`` - Disable scrolling range (set to fullscreen). +//| * ``ESC [ nnnn ; mmmm r`` - Set scrolling range between rows nnnn and mmmm. +//| * ``ESC [ ## m`` - Set the terminal display attributes. +//| * ``ESC [ ## ; ## m`` - Set the terminal display attributes. +//| * ``ESC [ ## ; ## ; ## m`` - Set the terminal display attributes. +//| +//| Supported Display attributes: +//| +//| +--------+------------+------------+ +//| | Color | Foreground | Background | +//| +========+============+============+ +//| | Reset | 0 | 0 | +//| +--------+------------+------------+ +//| | Black | 30 | 40 | +//| +--------+------------+------------+ +//| | Red | 31 | 41 | +//| +--------+------------+------------+ +//| | Green | 32 | 42 | +//| +--------+------------+------------+ +//| | Yellow | 33 | 43 | +//| +--------+------------+------------+ +//| | Blue | 34 | 44 | +//| +--------+------------+------------+ +//| | Magenta| 35 | 45 | +//| +--------+------------+------------+ +//| | Cyan | 36 | 46 | +//| +--------+------------+------------+ +//| | White | 37 | 47 | +//| +--------+------------+------------+ +//| +//| Example Usage: +//| +//| .. code-block:: python +//| +//| import time +//| import displayio +//| import supervisor +//| from displayio import Group, TileGrid +//| from terminalio import FONT, Terminal +//| +//| main_group = Group() +//| display = supervisor.runtime.display +//| font_bb = FONT.get_bounding_box() +//| screen_size = (display.width // font_bb[0], display.height // font_bb[1]) +//| char_size = FONT.get_bounding_box() +//| +//| palette = displayio.Palette(2) +//| palette[0] = 0x000000 +//| palette[1] = 0xffffff +//| +//| tilegrid = TileGrid( +//| bitmap=FONT.bitmap, width=screen_size[0], height=screen_size[1], +//| tile_width=char_size[0], tile_height=char_size[1], pixel_shader=palette) +//| +//| terminal = Terminal(tilegrid, FONT) +//| +//| main_group.append(tilegrid) +//| display.root_group = main_group +//| +//| message = "Hello World\\n" +//| terminal.write(message) +//| +//| print(terminal.cursor_x, terminal.cursor_y) +//| move_cursor = chr(27) + "[10;10H" +//| terminal.write(f"Moving the cursor\\n{move_cursor} To here") +//| +//| cursor_home = chr(27) + f"[{screen_size[1]};0H" +//| terminal.write(cursor_home) +//| i = 1 +//| while True: +//| terminal.write(f"Writing again {i}\\n") +//| i = i + 1 +//| time.sleep(1) +//| +//| //| """ //| //| def __init__( @@ -40,11 +131,10 @@ //| scroll_area: displayio.TileGrid, //| font: fontio.BuiltinFont, //| *, -//| status_bar: Optional[displayio.TileGrid] = None +//| status_bar: Optional[displayio.TileGrid] = None, //| ) -> None: -//| """Terminal manages tile indices and cursor position based on VT100 commands. The font should be -//| a `fontio.BuiltinFont` and the TileGrid's bitmap should match the font's bitmap.""" //| ... +//| static mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_scroll_area, ARG_font, ARG_status_bar }; @@ -62,14 +152,32 @@ static mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n status_bar = mp_arg_validate_type(args[ARG_status_bar].u_obj, &displayio_tilegrid_type, MP_QSTR_status_bar); } - fontio_builtinfont_t *font = mp_arg_validate_type(args[ARG_font].u_obj, &fontio_builtinfont_type, MP_QSTR_font); + mp_obj_t font = args[ARG_font].u_obj; - mp_arg_validate_int_min(scroll_area->width_in_tiles, 2, MP_QSTR_scroll_area_width); - mp_arg_validate_int_min(scroll_area->height_in_tiles, 2, MP_QSTR_scroll_area_height); + // Ensure the font is one of the supported types + bool valid_font = false; - terminalio_terminal_obj_t *self = mp_obj_malloc(terminalio_terminal_obj_t, &terminalio_terminal_type); + #if CIRCUITPY_FONTIO + if (mp_obj_is_type(font, &fontio_builtinfont_type)) { + valid_font = true; + } + #endif + + #if CIRCUITPY_LVFONTIO + if (mp_obj_is_type(font, &lvfontio_ondiskfont_type)) { + valid_font = true; + } + #endif + + if (!valid_font) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_font); + } + + mp_arg_validate_int_min(scroll_area->width_in_tiles * scroll_area->height_in_tiles, 2, MP_QSTR_scroll_area_area); + terminalio_terminal_obj_t *self = mp_obj_malloc(terminalio_terminal_obj_t, &terminalio_terminal_type); common_hal_terminalio_terminal_construct(self, scroll_area, font, status_bar); + return MP_OBJ_FROM_PTR(self); } @@ -82,6 +190,7 @@ static mp_obj_t terminalio_terminal_make_new(const mp_obj_type_t *type, size_t n //| :rtype: int or None""" //| ... //| +//| static mp_uint_t terminalio_terminal_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); const byte *buf = buf_in; @@ -89,7 +198,31 @@ static mp_uint_t terminalio_terminal_write(mp_obj_t self_in, const void *buf_in, return common_hal_terminalio_terminal_write(self, buf, size, errcode); } -static mp_uint_t terminalio_terminal_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +//| cursor_x: int +//| """The x position of the cursor.""" +//| +static mp_obj_t terminalio_terminal_obj_get_cursor_x(mp_obj_t self_in) { + terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_terminalio_terminal_get_cursor_x(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(terminalio_terminal_get_cursor_x_obj, terminalio_terminal_obj_get_cursor_x); + +MP_PROPERTY_GETTER(terminalio_terminal_cursor_x_obj, + (mp_obj_t)&terminalio_terminal_get_cursor_x_obj); + +//| cursor_y: int +//| """The y position of the cursor.""" +//| +static mp_obj_t terminalio_terminal_obj_get_cursor_y(mp_obj_t self_in) { + terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_terminalio_terminal_get_cursor_y(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(terminalio_terminal_get_cursor_y_obj, terminalio_terminal_obj_get_cursor_y); + +MP_PROPERTY_GETTER(terminalio_terminal_cursor_y_obj, + (mp_obj_t)&terminalio_terminal_get_cursor_y_obj); + +static mp_uint_t terminalio_terminal_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { terminalio_terminal_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; if (request == MP_STREAM_POLL) { @@ -107,7 +240,9 @@ static mp_uint_t terminalio_terminal_ioctl(mp_obj_t self_in, mp_uint_t request, static const mp_rom_map_elem_t terminalio_terminal_locals_dict_table[] = { // Standard stream methods. - { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_cursor_x), MP_ROM_PTR(&terminalio_terminal_cursor_x_obj) }, + { MP_ROM_QSTR(MP_QSTR_cursor_y), MP_ROM_PTR(&terminalio_terminal_cursor_y_obj) }, }; static MP_DEFINE_CONST_DICT(terminalio_terminal_locals_dict, terminalio_terminal_locals_dict_table); @@ -121,7 +256,7 @@ static const mp_stream_p_t terminalio_terminal_stream_p = { MP_DEFINE_CONST_OBJ_TYPE( terminalio_terminal_type, MP_QSTR_Terminal, - MP_TYPE_FLAG_ITER_IS_ITERNEXT, + MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, make_new, terminalio_terminal_make_new, locals_dict, (mp_obj_dict_t *)&terminalio_terminal_locals_dict, iter, mp_stream_unbuffered_iter, diff --git a/shared-bindings/terminalio/Terminal.h b/shared-bindings/terminalio/Terminal.h index 893db4d1311..6613500ac2e 100644 --- a/shared-bindings/terminalio/Terminal.h +++ b/shared-bindings/terminalio/Terminal.h @@ -13,10 +13,13 @@ extern const mp_obj_type_t terminalio_terminal_type; extern void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, - displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, displayio_tilegrid_t *status_bar); + displayio_tilegrid_t *scroll_area, mp_obj_t font, displayio_tilegrid_t *status_bar); // Write characters. len is in characters NOT bytes! extern size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const uint8_t *data, size_t len, int *errcode); +extern uint16_t common_hal_terminalio_terminal_get_cursor_x(terminalio_terminal_obj_t *self); +extern uint16_t common_hal_terminalio_terminal_get_cursor_y(terminalio_terminal_obj_t *self); + extern bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self); diff --git a/shared-bindings/tilepalettemapper/TilePaletteMapper.c b/shared-bindings/tilepalettemapper/TilePaletteMapper.c new file mode 100644 index 00000000000..c22ea47bf26 --- /dev/null +++ b/shared-bindings/tilepalettemapper/TilePaletteMapper.c @@ -0,0 +1,180 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT +#include +#include +#include "shared/runtime/context_manager_helpers.h" +#include "py/binary.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/util.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/TileGrid.h" +#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h" + +//| class TilePaletteMapper: +//| """Remaps color indices from the source bitmap to alternate indices on a +//| per-tile basis. This allows for altering coloring of tiles based on +//| their tilegrid location. It also allows for using a limited color +//| bitmap with a wider array of colors.""" +//| +//| def __init__( +//| self, palette: displayio.Palette, input_color_count: int +//| ) -> None: +//| """Create a TilePaletteMApper object to store a set of color mappings for tiles. +//| +//| :param Union[displayio.Palette, displayio.ColorConverter] pixel_shader: +//| The palette or ColorConverter to get mapped colors from. +//| :param int input_color_count: The number of colors in in the input bitmap.""" +//| + +static mp_obj_t tilepalettemapper_tilepalettemapper_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + enum { ARG_pixel_shader, ARG_input_color_count }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_input_color_count, MP_ARG_INT | MP_ARG_REQUIRED }, + + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + mp_obj_t pixel_shader = args[ARG_pixel_shader].u_obj; + if (!mp_obj_is_type(pixel_shader, &displayio_palette_type) && !mp_obj_is_type(pixel_shader, &displayio_colorconverter_type)) { + mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_pixel_shader); + } + + tilepalettemapper_tilepalettemapper_t *self = mp_obj_malloc(tilepalettemapper_tilepalettemapper_t, &tilepalettemapper_tilepalettemapper_type); + common_hal_tilepalettemapper_tilepalettemapper_construct(self, pixel_shader, args[ARG_input_color_count].u_int); + + return MP_OBJ_FROM_PTR(self); +} + +//| width: int +//| """Width of the tile palette mapper in tiles.""" +static mp_obj_t tilepalettemapper_tilepalettemapper_obj_get_width(mp_obj_t self_in) { + tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_tilepalettemapper_tilepalettemapper_get_width(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(tilepalettemapper_tilepalettemapper_get_width_obj, tilepalettemapper_tilepalettemapper_obj_get_width); + +MP_PROPERTY_GETTER(tilepalettemapper_tilepalettemapper_width_obj, + (mp_obj_t)&tilepalettemapper_tilepalettemapper_get_width_obj); + +//| height: int +//| """Height of the tile palette mapper in tiles.""" +static mp_obj_t tilepalettemapper_tilepalettemapper_obj_get_height(mp_obj_t self_in) { + tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_tilepalettemapper_tilepalettemapper_get_height(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(tilepalettemapper_tilepalettemapper_get_height_obj, tilepalettemapper_tilepalettemapper_obj_get_height); + +MP_PROPERTY_GETTER(tilepalettemapper_tilepalettemapper_height_obj, + (mp_obj_t)&tilepalettemapper_tilepalettemapper_get_height_obj); + + +//| pixel_shader: Union[displayio.Palette, displayio.ColorConverter] +//| """The palette or ColorConverter that the mapper uses.""" +//| +static mp_obj_t tilepalettemapper_tilepalettemapper_obj_get_pixel_shader(mp_obj_t self_in) { + tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_tilepalettemapper_tilepalettemapper_get_pixel_shader(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(tilepalettemapper_tilepalettemapper_get_pixel_shader_obj, tilepalettemapper_tilepalettemapper_obj_get_pixel_shader); + +MP_PROPERTY_GETTER(tilepalettemapper_tilepalettemapper_pixel_shader_obj, + (mp_obj_t)&tilepalettemapper_tilepalettemapper_get_pixel_shader_obj); + +//| tilegrid: displayio.TileGrid +//| """The TileGrid that the TilePaletteMapper is used with.""" +//| +static mp_obj_t tilepalettemapper_tilepalettemapper_obj_get_tilegrid(mp_obj_t self_in) { + tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in); + return common_hal_tilepalettemapper_tilepalettemapper_get_tilegrid(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(tilepalettemapper_tilepalettemapper_get_tilegrid_obj, tilepalettemapper_tilepalettemapper_obj_get_tilegrid); + +MP_PROPERTY_GETTER(tilepalettemapper_tilepalettemapper_tilegrid_obj, + (mp_obj_t)&tilepalettemapper_tilepalettemapper_get_tilegrid_obj); + +//| def __getitem__(self, index: Union[Tuple[int, int], int]) -> Tuple[int]: +//| """Returns the mapping for the given index. The index can either be an x,y tuple or an int equal +//| to ``y * width + x``. +//| +//| This allows you to:: +//| +//| print(tpm[0])""" +//| ... +//| +//| def __setitem__(self, index: Union[Tuple[int, int], int], value: List[int]) -> None: +//| """Sets the mapping at the given tile index. The index can either be an x,y tuple or an int equal +//| to ``y * width + x``. +//| +//| This allows you to:: +//| +//| tpm[0] = [1,0] +//| +//| or:: +//| +//| tpm[0,0] = [1,0]""" +//| ... +//| +//| +static mp_obj_t tilepalettemapper_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { + tilepalettemapper_tilepalettemapper_t *self = MP_OBJ_TO_PTR(self_in); + if (mp_obj_is_type(index_obj, &mp_type_slice)) { + mp_raise_NotImplementedError(MP_ERROR_TEXT("Slices not supported")); + } else { + uint16_t x = 0; + uint16_t y = 0; + if (mp_obj_is_small_int(index_obj)) { + mp_int_t i = MP_OBJ_SMALL_INT_VALUE(index_obj); + uint16_t width = common_hal_tilepalettemapper_tilepalettemapper_get_width(self); + x = i % width; + y = i / width; + } else { + mp_obj_t *items; + mp_obj_get_array_fixed_n(index_obj, 2, &items); + x = mp_obj_get_int(items[0]); + y = mp_obj_get_int(items[1]); + } + if (x >= common_hal_tilepalettemapper_tilepalettemapper_get_width(self) || + y >= common_hal_tilepalettemapper_tilepalettemapper_get_height(self)) { + mp_raise_IndexError(MP_ERROR_TEXT("Tile index out of bounds")); + } + + if (value_obj == MP_OBJ_SENTINEL) { + // load + return common_hal_tilepalettemapper_tilepalettemapper_get_mapping(self, x, y); + } else if (value_obj == mp_const_none) { + return MP_OBJ_NULL; // op not supported + } else { + size_t len = 0; + mp_obj_t *items; + mp_obj_list_get(value_obj, &len, &items); + mp_arg_validate_int_range(len, 0, self->input_color_count, MP_QSTR_mapping_length); + common_hal_tilepalettemapper_tilepalettemapper_set_mapping(self, x, y, len, items); + } + } + return mp_const_none; +} + + +static const mp_rom_map_elem_t tilepalettemapper_tilepalettemapper_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_width_obj) }, + { MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_height_obj) }, + { MP_ROM_QSTR(MP_QSTR_pixel_shader), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_pixel_shader_obj) }, + { MP_ROM_QSTR(MP_QSTR_tilegrid), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_tilegrid_obj) }, +}; +static MP_DEFINE_CONST_DICT(tilepalettemapper_tilepalettemapper_locals_dict, tilepalettemapper_tilepalettemapper_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + tilepalettemapper_tilepalettemapper_type, + MP_QSTR_TilePaletteMapper, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + make_new, tilepalettemapper_tilepalettemapper_make_new, + locals_dict, &tilepalettemapper_tilepalettemapper_locals_dict, + subscr, tilepalettemapper_subscr, + iter, mp_obj_generic_subscript_getiter + ); diff --git a/shared-bindings/tilepalettemapper/TilePaletteMapper.h b/shared-bindings/tilepalettemapper/TilePaletteMapper.h new file mode 100644 index 00000000000..ef0d9495917 --- /dev/null +++ b/shared-bindings/tilepalettemapper/TilePaletteMapper.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT +#include "shared-module/tilepalettemapper/TilePaletteMapper.h" + +extern const mp_obj_type_t tilepalettemapper_tilepalettemapper_type; + +void common_hal_tilepalettemapper_tilepalettemapper_construct(tilepalettemapper_tilepalettemapper_t *self, + mp_obj_t paltte, uint16_t input_color_count); + + +uint16_t common_hal_tilepalettemapper_tilepalettemapper_get_width(tilepalettemapper_tilepalettemapper_t *self); +uint16_t common_hal_tilepalettemapper_tilepalettemapper_get_height(tilepalettemapper_tilepalettemapper_t *self); +mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_pixel_shader(tilepalettemapper_tilepalettemapper_t *self); +mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_tilegrid(tilepalettemapper_tilepalettemapper_t *self); +mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_mapping(tilepalettemapper_tilepalettemapper_t *self, uint16_t x, uint16_t y); +void common_hal_tilepalettemapper_tilepalettemapper_set_mapping(tilepalettemapper_tilepalettemapper_t *self, uint16_t x, uint16_t y, size_t len, mp_obj_t *items); diff --git a/shared-bindings/tilepalettemapper/__init__.c b/shared-bindings/tilepalettemapper/__init__.c new file mode 100644 index 00000000000..966de950766 --- /dev/null +++ b/shared-bindings/tilepalettemapper/__init__.c @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks +// +// SPDX-License-Identifier: MIT +#include "py/obj.h" +#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h" + + +static const mp_rom_map_elem_t tilepalettemapper_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_tilepalettemapper) }, + { MP_ROM_QSTR(MP_QSTR_TilePaletteMapper), MP_ROM_PTR(&tilepalettemapper_tilepalettemapper_type) }, +}; +static MP_DEFINE_CONST_DICT(tilepalettemapper_module_globals, tilepalettemapper_module_globals_table); + +const mp_obj_module_t tilepalettemapper_module = { + .base = {&mp_type_module }, + .globals = (mp_obj_dict_t *)&tilepalettemapper_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_tilepalettemapper, tilepalettemapper_module); diff --git a/shared-bindings/time/__init__.c b/shared-bindings/time/__init__.c index dbf62618035..b6d36baeb5f 100644 --- a/shared-bindings/time/__init__.c +++ b/shared-bindings/time/__init__.c @@ -20,13 +20,14 @@ //| |see_cpython_module| :mod:`cpython:time`. //| """ //| +//| //| def monotonic() -> float: -//| """Returns an always increasing value of time with an unknown reference +//| """Returns an always increasing value of time, in fractional seconds, with an unknown reference //| point. Only use it to compare against other values from `time.monotonic()` //| during the same code run. //| //| On most boards, `time.monotonic()` converts a 64-bit millisecond tick counter -//| to a float. Floats on most boards are encoded in 30 bits internally, with +//| to seconds, as a float. Floats on most boards are encoded in 30 bits internally, with //| effectively 22 bits of precision. The float returned by `time.monotonic()` will //| accurately represent time to millisecond precision only up to 2**22 milliseconds //| (about 1.165 hours). @@ -43,6 +44,7 @@ //| :rtype: float""" //| ... //| +//| static mp_obj_t time_monotonic(void) { uint64_t ticks_ms = common_hal_time_monotonic_ms(); return mp_obj_new_float(uint64_to_float(ticks_ms) / MICROPY_FLOAT_CONST(1000.0)); @@ -55,6 +57,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_obj, time_monotonic); //| :param float seconds: the time to sleep in fractional seconds""" //| ... //| +//| static mp_obj_t time_sleep(mp_obj_t seconds_o) { #if MICROPY_PY_BUILTINS_FLOAT mp_float_t seconds = mp_obj_get_float(seconds_o); @@ -80,6 +83,16 @@ static mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, s } //| class struct_time: +//| tm_year: int +//| tm_mon: int +//| tm_mday: int +//| tm_hour: int +//| tm_min: int +//| tm_sec: int +//| tm_wday: int +//| tm_yday: int +//| tm_isdst: int +//| //| def __init__(self, time_tuple: Sequence[int]) -> None: //| """Structure used to capture a date and time. Can be constructed from a `struct_time`, `tuple`, `list`, or `namedtuple` with 9 elements. //| @@ -96,6 +109,7 @@ static mp_obj_t struct_time_make_new(const mp_obj_type_t *type, size_t n_args, s //| * ``tm_isdst``: 1 when in daylight savings, 0 when not, -1 if unknown.""" //| ... //| +//| const mp_obj_namedtuple_type_t struct_time_type_obj = { NAMEDTUPLE_TYPE_BASE_AND_SLOTS_MAKE_NEW(MP_QSTR_struct_time, struct_time_make_new), .n_fields = 9, @@ -179,6 +193,7 @@ mp_obj_t MP_WEAK rtc_get_time_source_time(void) { //| :rtype: int""" //| ... //| +//| static mp_obj_t time_time(void) { timeutils_struct_time_t tm; struct_time_to_tm(rtc_get_time_source_time(), &tm); @@ -191,20 +206,21 @@ MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time); //| def monotonic_ns() -> int: //| """Return the time of the monotonic clock, which cannot go backward, in nanoseconds. //| Not available on boards without long integer support. -//| Only use it to compare against other values from `time.monotonic()` +//| Only use it to compare against other values from `time.monotonic_ns()` //| during a single code run. //| //| :return: the current time //| :rtype: int""" //| ... //| +//| static mp_obj_t time_monotonic_ns(void) { uint64_t time64 = common_hal_time_monotonic_ns(); return mp_obj_new_int_from_ll((long long)time64); } MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns); -//| def localtime(secs: int) -> struct_time: +//| def localtime(secs: Optional[int] = None) -> struct_time: //| """Convert a time expressed in seconds since Jan 1, 1970 to a struct_time in //| local time. If secs is not provided or None, the current time as returned //| by time() is used. @@ -214,6 +230,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(time_monotonic_ns_obj, time_monotonic_ns); //| :rtype: time.struct_time""" //| ... //| +//| static mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) { if (n_args == 0 || args[0] == mp_const_none) { return rtc_get_time_source_time(); @@ -251,6 +268,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime); //| :rtype: int""" //| ... //| +//| static mp_obj_t time_mktime(mp_obj_t t) { mp_obj_t *elem; size_t len; diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c index d435ae250c8..2250e88f599 100644 --- a/shared-bindings/touchio/TouchIn.c +++ b/shared-bindings/touchio/TouchIn.c @@ -31,28 +31,38 @@ //| print("touched!")""" //| -//| def __init__(self, pin: microcontroller.Pin) -> None: +//| def __init__(self, pin: microcontroller.Pin, pull: Optional[digitalio.Pull] = None) -> None: //| """Use the TouchIn on the given pin. //| -//| :param ~microcontroller.Pin pin: the pin to read from""" +//| :param ~microcontroller.Pin pin: the pin to read from +//| :param Optional[digitalio.Pull] pull: specify external pull resistor type. If None, assume pull-down or chip-specific implementation that does not require a pull. +//| """ //| ... +//| static mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, - size_t n_args, size_t n_kw, const mp_obj_t *args) { - // check number of arguments - mp_arg_check_num(n_args, n_kw, 1, 1, false); + size_t n_args, size_t n_kw, const mp_obj_t *all_args) { + + enum { ARG_pin, ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - // 1st argument is the pin - const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[0], MP_QSTR_pin); + const mcu_pin_obj_t *pin = validate_obj_is_free_pin(args[ARG_pin].u_obj, MP_QSTR_pin); + const digitalio_pull_t pull = validate_pull(args[ARG_pull].u_obj, MP_QSTR_pull); touchio_touchin_obj_t *self = mp_obj_malloc(touchio_touchin_obj_t, &touchio_touchin_type); - common_hal_touchio_touchin_construct(self, pin); + common_hal_touchio_touchin_construct(self, pin, pull); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); } //| def deinit(self) -> None: //| """Deinitialises the TouchIn and releases any hardware resources for reuse.""" //| ... +//| static mp_obj_t touchio_touchin_deinit(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_touchio_touchin_deinit(self); @@ -69,18 +79,15 @@ static void check_for_deinit(touchio_touchin_obj_t *self) { //| def __enter__(self) -> TouchIn: //| """No-op used by Context Managers.""" //| ... +//| // Provided by context manager helper. //| def __exit__(self) -> None: //| """Automatically deinitializes the hardware when exiting a context. See //| :ref:`lifetime-and-contextmanagers` for more info.""" //| ... -static mp_obj_t touchio_touchin_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_touchio_touchin_deinit(args[0]); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, touchio_touchin_obj___exit__); +//| +// Provided by context manager helper. //| value: bool //| """Whether the touch pad is being touched or not. (read-only) @@ -125,6 +132,7 @@ MP_PROPERTY_GETTER(touchio_touchin_raw_value_obj, //| touch = touchio.TouchIn(board.A1) //| touch.threshold = 7300""" //| +//| static mp_obj_t touchio_touchin_obj_get_threshold(mp_obj_t self_in) { touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); check_for_deinit(self); @@ -151,12 +159,12 @@ MP_PROPERTY_GETSET(touchio_touchin_threshold_obj, static const mp_rom_map_elem_t touchio_touchin_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&touchio_touchin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&touchio_touchin_deinit_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&touchio_touchin_value_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_raw_value), MP_ROM_PTR(&touchio_touchin_raw_value_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_threshold), MP_ROM_PTR(&touchio_touchin_threshold_obj)}, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&touchio_touchin_value_obj)}, + { MP_ROM_QSTR(MP_QSTR_raw_value), MP_ROM_PTR(&touchio_touchin_raw_value_obj)}, + { MP_ROM_QSTR(MP_QSTR_threshold), MP_ROM_PTR(&touchio_touchin_threshold_obj)}, }; static MP_DEFINE_CONST_DICT(touchio_touchin_locals_dict, touchio_touchin_locals_dict_table); diff --git a/shared-bindings/touchio/TouchIn.h b/shared-bindings/touchio/TouchIn.h index 0ab51039479..d9b34aa74e5 100644 --- a/shared-bindings/touchio/TouchIn.h +++ b/shared-bindings/touchio/TouchIn.h @@ -7,6 +7,7 @@ #pragma once #include "common-hal/microcontroller/Pin.h" +#include "shared-bindings/digitalio/Pull.h" #if CIRCUITPY_TOUCHIO_USE_NATIVE #include "common-hal/touchio/TouchIn.h" @@ -16,7 +17,7 @@ extern const mp_obj_type_t touchio_touchin_type; -void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin); +void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin, digitalio_pull_t pull); void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t *self); bool common_hal_touchio_touchin_deinited(touchio_touchin_obj_t *self); bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self); diff --git a/shared-bindings/touchio/__init__.c b/shared-bindings/touchio/__init__.c index 82e855b81d3..8f9e56d4bdb 100644 --- a/shared-bindings/touchio/__init__.c +++ b/shared-bindings/touchio/__init__.c @@ -28,8 +28,9 @@ //| For more information about working with the `touchio` module in CircuitPython, //| see `this Learn guide page `_. //| -//| **Limitations**: `touchio` is available on Raspberry Pi RP2040 builds, -//| but not on RP2350, due to GPIO hardware limitations. +//| **Limitations**: `touchio` on RP2350 must have a pull-up resistor to 3.3V +//| instead of ground and set the ``pull=Pull.UP`` parameter when constructing +//| a `TouchIn` object, due to GPIO hardware limitations. //| //| Example:: //| @@ -40,7 +41,8 @@ //| print(touch_pin.value) //| //| This example will initialize the the device, and print the -//| :py:data:`~touchio.TouchIn.value`.""" +//| :py:data:`~touchio.TouchIn.value`. +//| """ static const mp_rom_map_elem_t touchio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_touchio) }, diff --git a/shared-bindings/traceback/__init__.c b/shared-bindings/traceback/__init__.c index d1cf3307050..651ec2c0142 100644 --- a/shared-bindings/traceback/__init__.c +++ b/shared-bindings/traceback/__init__.c @@ -16,8 +16,10 @@ //| //| |see_cpython_module| :mod:`cpython:traceback`. //| """ +//| //| ... //| +//| static void traceback_exception_common(bool is_print_exception, mp_print_t *print, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_exc, ARG_value, ARG_tb, ARG_limit, ARG_file, ARG_chain }; @@ -34,10 +36,18 @@ static void traceback_exception_common(bool is_print_exception, mp_print_t *prin mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_obj_t value = args[ARG_value].u_obj; + mp_obj_t tb_obj = args[ARG_tb].u_obj; + + // Both or neither of value and tb must be supplied. + if ((value != MP_OBJ_NULL && tb_obj == MP_OBJ_NULL) || + (value == MP_OBJ_NULL && tb_obj != MP_OBJ_NULL)) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Supply both or neither of %q and %q"), MP_QSTR_value, MP_QSTR_tb); + } + if (value == MP_OBJ_NULL) { value = args[ARG_exc].u_obj; } - mp_obj_t tb_obj = args[ARG_tb].u_obj; + mp_obj_t limit_obj = args[ARG_limit].u_obj; #if MICROPY_CPYTHON_EXCEPTION_CHAIN bool chain = args[ARG_chain].u_bool; @@ -103,21 +113,21 @@ static void traceback_exception_common(bool is_print_exception, mp_print_t *prin //| def format_exception( //| exc: BaseException | Type[BaseException], //| /, -//| value: Optional[BaseException] = None, +//| value: BaseException, //| tb: Optional[TracebackType] = None, //| limit: Optional[int] = None, //| chain: Optional[bool] = True, //| ) -> List[str]: //| """Format a stack trace and the exception information. //| -//| If the exception value is passed in ``exc``, then this exception value and its -//| associated traceback are used. This is compatible with CPython 3.10 and newer. +//| If the exception value is passed in ``exc``, and ``value`` and ``tb`` are not supplied, +//| then this exception value and its associated traceback are used. +//| This is compatible with CPython 3.10 and newer. //| -//| If the exception value is passed in ``value``, then any value passed in for -//| ``exc`` is ignored. ``value`` is used as the exception value and the -//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None, -//| no traceback will be shown. This is compatible with CPython 3.5 and -//| newer. +//| If the exception value is passed in ``value``, then both ``value`` and ``tb`` must be supplied. +//| Any value passed in for ``exc`` is *ignored*. ``value`` is used as the exception value and the +//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is `None`, +//| no traceback will be shown. This is compatible with CPython 3.5 and newer. //| //| The arguments have the same meaning as the corresponding arguments //| to print_exception(). The return value is a list of strings, each @@ -126,13 +136,14 @@ static void traceback_exception_common(bool is_print_exception, mp_print_t *prin //| printed as does print_exception(). //| //| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified. -//| :param value: If specified, is used in place of ``exc``. -//| :param TracebackType tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed. +//| :param value: If specified, is used in place of ``exc``, and ``tb`` must also be specified. +//| :param tb: When ``value`` is also specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed. //| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive. //| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed. //| :param bool chain: If `True` then chained exceptions will be printed. //| """ //| +//| static mp_obj_t traceback_format_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_print_t print; vstr_t vstr; @@ -147,7 +158,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_f //| def print_exception( //| exc: BaseException | Type[BaseException], //| /, -//| value: Optional[BaseException] = None, +//| value: BaseException, //| tb: Optional[TracebackType] = None, //| limit: Optional[int] = None, //| file: Optional[io.FileIO] = None, @@ -155,18 +166,18 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_f //| ) -> None: //| """Prints exception information and stack trace entries. //| -//| If the exception value is passed in ``exc``, then this exception value and its -//| associated traceback are used. This is compatible with CPython 3.10 and newer. +//| If the exception value is passed in ``exc``, and ``value`` and ``tb`` are not supplied, +//| then this exception value and its associated traceback are used. +//| This is compatible with CPython 3.10 and newer. //| -//| If the exception value is passed in ``value``, then any value passed in for -//| ``exc`` is ignored. ``value`` is used as the exception value and the -//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None, -//| no traceback will be shown. This is compatible with CPython 3.5 and -//| newer. +//| If the exception value is passed in ``value``, then both ``value`` and ``tb`` must be supplied. +//| Any value passed in for ``exc`` is *ignored*. ``value`` is used as the exception value and the +//| traceback in the ``tb`` argument is used. In this case, if ``tb`` is `None`, +//| no traceback will be shown. This is compatible with CPython 3.5 and newer. //| //| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified. -//| :param value: If specified, is used in place of ``exc``. -//| :param tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed. +//| :param value: If specified, is used in place of ``exc``, and ``tb`` must also be specified. +//| :param tb: When ``value`` is also specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed. //| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive. //| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed. //| :param io.FileIO file: If file is omitted or `None`, the output goes to `sys.stderr`; otherwise it should be an open @@ -176,6 +187,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_f //| """ //| ... //| +//| static mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { mp_print_t print = mp_plat_print; diff --git a/shared-bindings/uheap/__init__.c b/shared-bindings/uheap/__init__.c index 0170c56c04b..a46ff762597 100644 --- a/shared-bindings/uheap/__init__.c +++ b/shared-bindings/uheap/__init__.c @@ -13,12 +13,14 @@ //| """Heap size analysis""" //| +//| //| def info(object: object) -> int: //| """Prints memory debugging info for the given object and returns the //| estimated size.""" //| ... //| +//| static mp_obj_t uheap_info(mp_obj_t obj) { uint32_t size = shared_module_uheap_info(obj); diff --git a/shared-bindings/usb/__init__.c b/shared-bindings/usb/__init__.c index d1a61be7bc4..ea05229984c 100644 --- a/shared-bindings/usb/__init__.c +++ b/shared-bindings/usb/__init__.c @@ -10,6 +10,7 @@ #include "shared-bindings/usb/__init__.h" #include "shared-bindings/usb/core/__init__.h" +#include "shared-bindings/usb/util/__init__.h" #include "supervisor/usb.h" //| """PyUSB-compatible USB host API @@ -21,6 +22,7 @@ static mp_rom_map_elem_t usb_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usb) }, { MP_ROM_QSTR(MP_QSTR_core), MP_OBJ_FROM_PTR(&usb_core_module) }, + { MP_ROM_QSTR(MP_QSTR_util), MP_OBJ_FROM_PTR(&usb_util_module) }, }; static MP_DEFINE_CONST_DICT(usb_module_globals, usb_module_globals_table); diff --git a/shared-bindings/usb/core/Device.c b/shared-bindings/usb/core/Device.c index 07795f003dc..bc6c6296899 100644 --- a/shared-bindings/usb/core/Device.c +++ b/shared-bindings/usb/core/Device.c @@ -39,6 +39,7 @@ #include "py/objproperty.h" #include "shared-bindings/usb/core/Device.h" +#include "shared-bindings/util.h" #include "py/runtime.h" //| class Device: @@ -47,11 +48,30 @@ //| `usb.core.find`. //| """ //| ... +//| + +static void check_for_deinit(usb_core_device_obj_t *self) { + if (common_hal_usb_core_device_deinited(self)) { + raise_deinited_error(); + } +} + +//| def __del__(self) -> None: +//| """Closes any resources used for this device.""" +//| ... +//| +static mp_obj_t usb_core_device_deinit(mp_obj_t self_in) { + usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_usb_core_device_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_deinit_obj, usb_core_device_deinit); //| idVendor: int //| """The USB vendor ID of the device""" static mp_obj_t usb_core_device_obj_get_idVendor(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_get_idVendor(self)); } MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_idVendor_obj, usb_core_device_obj_get_idVendor); @@ -63,6 +83,7 @@ MP_PROPERTY_GETTER(usb_core_device_idVendor_obj, //| """The USB product ID of the device""" static mp_obj_t usb_core_device_obj_get_idProduct(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_get_idProduct(self)); } MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_idProduct_obj, usb_core_device_obj_get_idProduct); @@ -74,6 +95,7 @@ MP_PROPERTY_GETTER(usb_core_device_idProduct_obj, //| """The USB device's serial number string.""" static mp_obj_t usb_core_device_obj_get_serial_number(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); return common_hal_usb_core_device_get_serial_number(self); } MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_serial_number_obj, usb_core_device_obj_get_serial_number); @@ -85,6 +107,7 @@ MP_PROPERTY_GETTER(usb_core_device_serial_number_obj, //| """The USB device's product string.""" static mp_obj_t usb_core_device_obj_get_product(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); return common_hal_usb_core_device_get_product(self); } MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_product_obj, usb_core_device_obj_get_product); @@ -94,8 +117,10 @@ MP_PROPERTY_GETTER(usb_core_device_product_obj, //| manufacturer: str //| """The USB device's manufacturer string.""" +//| static mp_obj_t usb_core_device_obj_get_manufacturer(mp_obj_t self_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); return common_hal_usb_core_device_get_manufacturer(self); } MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_manufacturer_obj, usb_core_device_obj_get_manufacturer); @@ -103,6 +128,47 @@ MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_manufacturer_obj, usb_core_device_ MP_PROPERTY_GETTER(usb_core_device_manufacturer_obj, (mp_obj_t)&usb_core_device_get_manufacturer_obj); +//| bus: int +//| """The bus number of the root hub this device is connected to.""" +//| +static mp_obj_t usb_core_device_obj_get_bus(mp_obj_t self_in) { + usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_get_bus(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_bus_obj, usb_core_device_obj_get_bus); + +MP_PROPERTY_GETTER(usb_core_device_bus_obj, + (mp_obj_t)&usb_core_device_get_bus_obj); + +//| port_numbers: tuple[int] | None +//| """The port topology of the devices location. None when connected to the +//| root port (aka bus).""" +//| +static mp_obj_t usb_core_device_obj_get_port_numbers(mp_obj_t self_in) { + usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return common_hal_usb_core_device_get_port_numbers(self); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_port_numbers_obj, usb_core_device_obj_get_port_numbers); + +MP_PROPERTY_GETTER(usb_core_device_port_numbers_obj, + (mp_obj_t)&usb_core_device_get_port_numbers_obj); + + +//| speed: int +//| """The speed of the device. One of `usb.util.SPEED_LOW`, `usb.util.SPEED_FULL`, `usb.util.SPEED_HIGH` or 0 for unknown.""" +//| +static mp_obj_t usb_core_device_obj_get_speed(mp_obj_t self_in) { + usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_get_speed(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_core_device_get_speed_obj, usb_core_device_obj_get_speed); + +MP_PROPERTY_GETTER(usb_core_device_speed_obj, + (mp_obj_t)&usb_core_device_get_speed_obj); + //| def set_configuration(self, configuration: int = 1) -> None: //| """Set the active configuration. //| @@ -113,12 +179,14 @@ MP_PROPERTY_GETTER(usb_core_device_manufacturer_obj, //| without arguments is enough to get the device ready. //| """ //| ... +//| static mp_obj_t usb_core_device_set_configuration(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_configuration }; static const mp_arg_t allowed_args[] = { { MP_QSTR_configuration, MP_ARG_INT, {.u_int = 1} }, }; usb_core_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -136,6 +204,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_set_configuration_obj, 1, usb_core_de //| :returns: the number of bytes written //| """ //| ... +//| static mp_obj_t usb_core_device_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_endpoint, ARG_data, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -144,6 +213,7 @@ static mp_obj_t usb_core_device_write(size_t n_args, const mp_obj_t *pos_args, m { MP_QSTR_timeout, MP_ARG_INT, {.u_int = 0} }, }; usb_core_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -156,31 +226,45 @@ MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_write_obj, 2, usb_core_device_write); //| def read( -//| self, endpoint: int, size_or_buffer: array.array, timeout: Optional[int] = None +//| self, +//| endpoint: int, +//| size_or_buffer: array.array, +//| timeout: Optional[int] = None, +//| *, +//| raise_on_timeout: bool = True, //| ) -> int: //| """Read data from the endpoint. //| //| :param int endpoint: the bEndpointAddress you want to communicate with. //| :param array.array size_or_buffer: the array to read data into. PyUSB also allows size but CircuitPython only support array to force deliberate memory use. //| :param int timeout: Time to wait specified in milliseconds. (Different from most CircuitPython!) +//| :param bool raise_on_timeout: when False, an elapsed timeout returns ``0`` +//| instead of raising `usb.core.USBTimeoutError`. Polling an interrupt +//| endpoint every frame (e.g. a HID gamepad in a game loop) treats "no +//| new report yet" as a normal outcome; the exception object each such +//| poll would otherwise allocate is measurable garbage-collector +//| pressure on small heaps. //| :returns: the number of bytes read //| """ //| ... +//| static mp_obj_t usb_core_device_read(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_endpoint, ARG_size_or_buffer, ARG_timeout }; + enum { ARG_endpoint, ARG_size_or_buffer, ARG_timeout, ARG_raise_on_timeout }; static const mp_arg_t allowed_args[] = { { MP_QSTR_endpoint, MP_ARG_REQUIRED | MP_ARG_INT }, { MP_QSTR_size_or_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ }, { MP_QSTR_timeout, MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_raise_on_timeout, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, }; usb_core_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_size_or_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_read(self, args[ARG_endpoint].u_int, bufinfo.buf, bufinfo.len, args[ARG_timeout].u_int)); + return MP_OBJ_NEW_SMALL_INT(common_hal_usb_core_device_read(self, args[ARG_endpoint].u_int, bufinfo.buf, bufinfo.len, args[ARG_timeout].u_int, args[ARG_raise_on_timeout].u_bool)); } MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_read_obj, 2, usb_core_device_read); @@ -211,6 +295,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_read_obj, 2, usb_core_device_read); //| number of bytes read. //| """ //| ... +//| static mp_obj_t usb_core_device_ctrl_transfer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_bmRequestType, ARG_bRequest, ARG_wValue, ARG_wIndex, ARG_data_or_wLength, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -222,6 +307,7 @@ static mp_obj_t usb_core_device_ctrl_transfer(size_t n_args, const mp_obj_t *pos { MP_QSTR_timeout, MP_ARG_INT, {.u_int = 0} }, }; usb_core_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); @@ -252,8 +338,10 @@ MP_DEFINE_CONST_FUN_OBJ_KW(usb_core_device_ctrl_transfer_obj, 2, usb_core_device //| :param int interface: the device interface number to check //| """ //| ... +//| static mp_obj_t usb_core_device_is_kernel_driver_active(mp_obj_t self_in, mp_obj_t interface_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); mp_int_t interface = mp_obj_get_int(interface_in); bool active = common_hal_usb_core_device_is_kernel_driver_active(self, interface); return mp_obj_new_bool(active); @@ -268,8 +356,10 @@ MP_DEFINE_CONST_FUN_OBJ_2(usb_core_device_is_kernel_driver_active_obj, usb_core_ //| :param int interface: the device interface number to stop CircuitPython on //| """ //| ... +//| static mp_obj_t usb_core_device_detach_kernel_driver(mp_obj_t self_in, mp_obj_t interface_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); mp_int_t interface = mp_obj_get_int(interface_in); common_hal_usb_core_device_detach_kernel_driver(self, interface); return mp_const_none; @@ -283,8 +373,10 @@ MP_DEFINE_CONST_FUN_OBJ_2(usb_core_device_detach_kernel_driver_obj, usb_core_dev //| """ //| ... //| +//| static mp_obj_t usb_core_device_attach_kernel_driver(mp_obj_t self_in, mp_obj_t interface_in) { usb_core_device_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); mp_int_t interface = mp_obj_get_int(interface_in); common_hal_usb_core_device_attach_kernel_driver(self, interface); return mp_const_none; @@ -293,11 +385,16 @@ MP_DEFINE_CONST_FUN_OBJ_2(usb_core_device_attach_kernel_driver_obj, usb_core_dev static const mp_rom_map_elem_t usb_core_device_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&usb_core_device_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&usb_core_device_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_idVendor), MP_ROM_PTR(&usb_core_device_idVendor_obj) }, { MP_ROM_QSTR(MP_QSTR_idProduct), MP_ROM_PTR(&usb_core_device_idProduct_obj) }, { MP_ROM_QSTR(MP_QSTR_serial_number), MP_ROM_PTR(&usb_core_device_serial_number_obj) }, { MP_ROM_QSTR(MP_QSTR_product), MP_ROM_PTR(&usb_core_device_product_obj) }, { MP_ROM_QSTR(MP_QSTR_manufacturer), MP_ROM_PTR(&usb_core_device_manufacturer_obj) }, + { MP_ROM_QSTR(MP_QSTR_bus), MP_ROM_PTR(&usb_core_device_bus_obj) }, + { MP_ROM_QSTR(MP_QSTR_port_numbers), MP_ROM_PTR(&usb_core_device_port_numbers_obj) }, + { MP_ROM_QSTR(MP_QSTR_speed), MP_ROM_PTR(&usb_core_device_speed_obj) }, { MP_ROM_QSTR(MP_QSTR_set_configuration), MP_ROM_PTR(&usb_core_device_set_configuration_obj) }, { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&usb_core_device_write_obj) }, diff --git a/shared-bindings/usb/core/Device.h b/shared-bindings/usb/core/Device.h index 232d16bdabf..51338f61228 100644 --- a/shared-bindings/usb/core/Device.h +++ b/shared-bindings/usb/core/Device.h @@ -13,14 +13,20 @@ extern const mp_obj_type_t usb_core_device_type; bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t device_number); +bool common_hal_usb_core_device_deinited(usb_core_device_obj_t *self); +void common_hal_usb_core_device_deinit(usb_core_device_obj_t *self); uint16_t common_hal_usb_core_device_get_idVendor(usb_core_device_obj_t *self); uint16_t common_hal_usb_core_device_get_idProduct(usb_core_device_obj_t *self); mp_obj_t common_hal_usb_core_device_get_serial_number(usb_core_device_obj_t *self); mp_obj_t common_hal_usb_core_device_get_product(usb_core_device_obj_t *self); mp_obj_t common_hal_usb_core_device_get_manufacturer(usb_core_device_obj_t *self); +mp_int_t common_hal_usb_core_device_get_bus(usb_core_device_obj_t *self); +mp_obj_t common_hal_usb_core_device_get_port_numbers(usb_core_device_obj_t *self); +mp_int_t common_hal_usb_core_device_get_speed(usb_core_device_obj_t *self); + void common_hal_usb_core_device_set_configuration(usb_core_device_obj_t *self, mp_int_t configuration); mp_int_t common_hal_usb_core_device_write(usb_core_device_obj_t *self, mp_int_t endpoint, const uint8_t *buffer, mp_int_t len, mp_int_t timeout); -mp_int_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t endpoint, uint8_t *buffer, mp_int_t len, mp_int_t timeout); +mp_int_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t endpoint, uint8_t *buffer, mp_int_t len, mp_int_t timeout, bool raise_on_timeout); mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, mp_int_t bmRequestType, mp_int_t bRequest, mp_int_t wValue, mp_int_t wIndex, diff --git a/shared-bindings/usb/core/__init__.c b/shared-bindings/usb/core/__init__.c index 99be3888bf8..29dab285084 100644 --- a/shared-bindings/usb/core/__init__.c +++ b/shared-bindings/usb/core/__init__.c @@ -21,14 +21,16 @@ //| This is a subset of the PyUSB core module. //| """ //| +//| //| class USBError(OSError): //| """Catchall exception for USB related errors.""" //| //| ... //| +//| MP_DEFINE_USB_CORE_EXCEPTION(USBError, OSError) -NORETURN void mp_raise_usb_core_USBError(mp_rom_error_text_t fmt, ...) { +MP_NORETURN void mp_raise_usb_core_USBError(mp_rom_error_text_t fmt, ...) { mp_obj_t exception; if (fmt == NULL) { exception = mp_obj_new_exception(&mp_type_usb_core_USBError); @@ -46,8 +48,9 @@ NORETURN void mp_raise_usb_core_USBError(mp_rom_error_text_t fmt, ...) { //| //| ... //| +//| MP_DEFINE_USB_CORE_EXCEPTION(USBTimeoutError, usb_core_USBError) -NORETURN void mp_raise_usb_core_USBTimeoutError(void) { +MP_NORETURN void mp_raise_usb_core_USBTimeoutError(void) { mp_raise_type(&mp_type_usb_core_USBTimeoutError); } @@ -61,6 +64,7 @@ NORETURN void mp_raise_usb_core_USBTimeoutError(void) { //| Returns None if no device matches. //| """ //| +//| typedef struct { mp_obj_base_t base; mp_int_t vid; @@ -86,9 +90,10 @@ static mp_obj_t _next_device(usb_core_devices_obj_t *iter) { // We passed the filters. Now make a properly allocated object to // return to the user. usb_core_device_obj_t *self = mp_obj_malloc(usb_core_device_obj_t, &usb_core_device_type); - common_hal_usb_core_device_construct(self, i); + iter->next_index = i + 1; + return MP_OBJ_FROM_PTR(self); } // Iter is done. diff --git a/shared-bindings/usb/core/__init__.h b/shared-bindings/usb/core/__init__.h index 0dc08fae532..adb8430a6c3 100644 --- a/shared-bindings/usb/core/__init__.h +++ b/shared-bindings/usb/core/__init__.h @@ -25,8 +25,8 @@ void usb_core_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_k extern const mp_obj_type_t mp_type_usb_core_USBError; extern const mp_obj_type_t mp_type_usb_core_USBTimeoutError; -NORETURN void mp_raise_usb_core_USBError(mp_rom_error_text_t fmt, ...); -NORETURN void mp_raise_usb_core_USBTimeoutError(void); +MP_NORETURN void mp_raise_usb_core_USBError(mp_rom_error_text_t fmt, ...); +MP_NORETURN void mp_raise_usb_core_USBTimeoutError(void); // Find is all Python object oriented so we don't need a separate common-hal API // for it. It uses the device common-hal instead. diff --git a/shared-bindings/usb/util/__init__.c b/shared-bindings/usb/util/__init__.c new file mode 100644 index 00000000000..20405827abe --- /dev/null +++ b/shared-bindings/usb/util/__init__.c @@ -0,0 +1,48 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include + +#include "py/obj.h" +#include "py/objexcept.h" +#include "py/misc.h" +#include "py/mphal.h" +#include "py/runtime.h" + +#include "shared-bindings/usb/util/__init__.h" + +//| """USB Util +//| +//| This is a subset of the PyUSB util module. +//| """ +//| +//| SPEED_LOW: int = ... +//| """A low speed, 1.5 Mbit/s device.""" +//| +//| SPEED_FULL: int = ... +//| """A full speed, 12 Mbit/s device.""" +//| +//| SPEED_HIGH: int = ... +//| """A high speed, 480 Mbit/s device.""" +//| + +static mp_rom_map_elem_t usb_util_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_usb_dot_util) }, + // Speed constants + { MP_ROM_QSTR(MP_QSTR_SPEED_LOW), MP_OBJ_NEW_SMALL_INT(PYUSB_SPEED_LOW) }, + { MP_ROM_QSTR(MP_QSTR_SPEED_FULL), MP_OBJ_NEW_SMALL_INT(PYUSB_SPEED_FULL) }, + { MP_ROM_QSTR(MP_QSTR_SPEED_HIGH), MP_OBJ_NEW_SMALL_INT(PYUSB_SPEED_HIGH) }, +}; + +static MP_DEFINE_CONST_DICT(usb_util_module_globals, usb_util_module_globals_table); + +const mp_obj_module_t usb_util_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&usb_util_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_usb_dot_util, usb_util_module); diff --git a/shared-bindings/usb/util/__init__.h b/shared-bindings/usb/util/__init__.h new file mode 100644 index 00000000000..446bdf41e8a --- /dev/null +++ b/shared-bindings/usb/util/__init__.h @@ -0,0 +1,17 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/obj.h" + +extern const mp_obj_module_t usb_util_module; + +#define PYUSB_SPEED_LOW 1 +#define PYUSB_SPEED_FULL 2 +#define PYUSB_SPEED_HIGH 3 diff --git a/shared-bindings/usb_audio/USBMicrophone.c b/shared-bindings/usb_audio/USBMicrophone.c new file mode 100644 index 00000000000..c66c78942dd --- /dev/null +++ b/shared-bindings/usb_audio/USBMicrophone.c @@ -0,0 +1,178 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared/runtime/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/usb_audio/USBMicrophone.h" +#include "shared-bindings/util.h" +#include "shared-module/usb_audio/__init__.h" +#include "shared-module/usb_audio/usb_audio_descriptors.h" + +//| class USBMicrophone: +//| """Streams an audio sample to the host computer as a USB Audio Class microphone. +//| +//| A ``USBMicrophone`` is a *consumer* of an audio sample, exactly like +//| `audioio.AudioOut`, `audiobusio.I2SOut` and `audiopwmio.PWMAudioOut`. The +//| samples it pulls are streamed to the host PC over USB rather than to a pin, +//| so the board appears as a microphone. +//| +//| You cannot create an instance of `usb_audio.USBMicrophone`. +//| +//| There is a single shared instance, available as ``usb_audio.usb_microphone`` +//| once ``usb_audio.enable()`` has configured an input (microphone) stream in +//| ``boot.py``. Until then ``usb_audio.usb_microphone`` is ``None``.""" +//| + + + +static mp_obj_t usb_audio_usbmicrophone_deinit(mp_obj_t self_in) { + usb_audio_usbmicrophone_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_usb_audio_usbmicrophone_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbmicrophone_deinit_obj, usb_audio_usbmicrophone_deinit); + +static void check_for_deinit(usb_audio_usbmicrophone_obj_t *self) { + if (common_hal_usb_audio_usbmicrophone_deinited(self)) { + raise_deinited_error(); + } +} + +//| def __enter__(self) -> USBMicrophone: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + +//| def play(self, sample: circuitpython_typing.AudioSample, *, loop: bool = False) -> None: +//| """Streams the sample to the host once when loop=False and continuously when +//| loop=True. Does not block. Use `playing` to block. +//| +//| Sample must be an `audiocore.WaveFile`, `audiocore.RawSample`, `audiomixer.Mixer`, +//| `audiomp3.MP3Decoder` or `synthio.Synthesizer`.""" +//| ... +//| +static mp_obj_t usb_audio_usbmicrophone_obj_play(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample, ARG_loop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample, MP_ARG_OBJ | MP_ARG_REQUIRED }, + { MP_QSTR_loop, MP_ARG_BOOL | MP_ARG_KW_ONLY, {.u_bool = false} }, + }; + usb_audio_usbmicrophone_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + common_hal_usb_audio_usbmicrophone_play(self, args[ARG_sample].u_obj, args[ARG_loop].u_bool); + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(usb_audio_usbmicrophone_play_obj, 1, usb_audio_usbmicrophone_obj_play); + +//| def stop(self) -> None: +//| """Stops streaming and resets to the start of the sample.""" +//| ... +//| +static mp_obj_t usb_audio_usbmicrophone_obj_stop(mp_obj_t self_in) { + usb_audio_usbmicrophone_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + common_hal_usb_audio_usbmicrophone_stop(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbmicrophone_stop_obj, usb_audio_usbmicrophone_obj_stop); + +//| playing: bool +//| """True when an audio sample is being streamed even if `paused`. (read-only)""" +//| +static mp_obj_t usb_audio_usbmicrophone_obj_get_playing(mp_obj_t self_in) { + usb_audio_usbmicrophone_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_usb_audio_usbmicrophone_get_playing(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbmicrophone_get_playing_obj, usb_audio_usbmicrophone_obj_get_playing); + +MP_PROPERTY_GETTER(usb_audio_usbmicrophone_playing_obj, + (mp_obj_t)&usb_audio_usbmicrophone_get_playing_obj); + +//| def pause(self) -> None: +//| """Stops streaming temporarily while remembering the position. Use `resume` to resume.""" +//| ... +//| +static mp_obj_t usb_audio_usbmicrophone_obj_pause(mp_obj_t self_in) { + usb_audio_usbmicrophone_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (!common_hal_usb_audio_usbmicrophone_get_playing(self)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Not playing")); + } + common_hal_usb_audio_usbmicrophone_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbmicrophone_pause_obj, usb_audio_usbmicrophone_obj_pause); + +//| def resume(self) -> None: +//| """Resumes streaming after :py:func:`pause`.""" +//| ... +//| +static mp_obj_t usb_audio_usbmicrophone_obj_resume(mp_obj_t self_in) { + usb_audio_usbmicrophone_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + if (common_hal_usb_audio_usbmicrophone_get_paused(self)) { + common_hal_usb_audio_usbmicrophone_resume(self); + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbmicrophone_resume_obj, usb_audio_usbmicrophone_obj_resume); + +//| paused: bool +//| """True when streaming is paused. (read-only)""" +//| +//| +static mp_obj_t usb_audio_usbmicrophone_obj_get_paused(mp_obj_t self_in) { + usb_audio_usbmicrophone_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_usb_audio_usbmicrophone_get_paused(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbmicrophone_get_paused_obj, usb_audio_usbmicrophone_obj_get_paused); + +MP_PROPERTY_GETTER(usb_audio_usbmicrophone_paused_obj, + (mp_obj_t)&usb_audio_usbmicrophone_get_paused_obj); + +static const mp_rom_map_elem_t usb_audio_usbmicrophone_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&usb_audio_usbmicrophone_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&usb_audio_usbmicrophone_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_play), MP_ROM_PTR(&usb_audio_usbmicrophone_play_obj) }, + { MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&usb_audio_usbmicrophone_stop_obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&usb_audio_usbmicrophone_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&usb_audio_usbmicrophone_resume_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_playing), MP_ROM_PTR(&usb_audio_usbmicrophone_playing_obj) }, + { MP_ROM_QSTR(MP_QSTR_paused), MP_ROM_PTR(&usb_audio_usbmicrophone_paused_obj) }, +}; +static MP_DEFINE_CONST_DICT(usb_audio_usbmicrophone_locals_dict, usb_audio_usbmicrophone_locals_dict_table); + +MP_DEFINE_CONST_OBJ_TYPE( + usb_audio_USBMicrophone_type, + MP_QSTR_USBMicrophone, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + locals_dict, &usb_audio_usbmicrophone_locals_dict + ); diff --git a/shared-bindings/usb_audio/USBMicrophone.h b/shared-bindings/usb_audio/USBMicrophone.h new file mode 100644 index 00000000000..4fe096778bc --- /dev/null +++ b/shared-bindings/usb_audio/USBMicrophone.h @@ -0,0 +1,21 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/usb_audio/USBMicrophone.h" + +extern const mp_obj_type_t usb_audio_USBMicrophone_type; + +void common_hal_usb_audio_usbmicrophone_construct(usb_audio_usbmicrophone_obj_t *self); +void common_hal_usb_audio_usbmicrophone_deinit(usb_audio_usbmicrophone_obj_t *self); +bool common_hal_usb_audio_usbmicrophone_deinited(usb_audio_usbmicrophone_obj_t *self); +void common_hal_usb_audio_usbmicrophone_play(usb_audio_usbmicrophone_obj_t *self, mp_obj_t sample, bool loop); +void common_hal_usb_audio_usbmicrophone_stop(usb_audio_usbmicrophone_obj_t *self); +bool common_hal_usb_audio_usbmicrophone_get_playing(usb_audio_usbmicrophone_obj_t *self); +void common_hal_usb_audio_usbmicrophone_pause(usb_audio_usbmicrophone_obj_t *self); +void common_hal_usb_audio_usbmicrophone_resume(usb_audio_usbmicrophone_obj_t *self); +bool common_hal_usb_audio_usbmicrophone_get_paused(usb_audio_usbmicrophone_obj_t *self); diff --git a/shared-bindings/usb_audio/USBSpeaker.c b/shared-bindings/usb_audio/USBSpeaker.c new file mode 100644 index 00000000000..78c5e6099b9 --- /dev/null +++ b/shared-bindings/usb_audio/USBSpeaker.c @@ -0,0 +1,167 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared/runtime/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/usb_audio/USBSpeaker.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-bindings/util.h" +#include "shared-module/usb_audio/__init__.h" + +//| class USBSpeaker: +//| """Plays audio streamed from the host computer as a USB Audio Class speaker. +//| +//| A ``USBSpeaker`` is a *source* of audio samples, exactly like +//| `audiocore.RawSample` or `audiocore.WaveFile`. The host PC streams audio to +//| the board over USB, and the ``USBSpeaker`` hands that audio to a consumer +//| such as `audiobusio.I2SOut`, `audiopwmio.PWMAudioOut` or `audioio.AudioOut` +//| (optionally through the effect modules), so the board appears as a speaker. +//| +//| You cannot create an instance of `usb_audio.USBSpeaker`. +//| +//| There is a single shared instance, available as ``usb_audio.usb_speaker`` +//| once ``usb_audio.enable()`` has configured an output (speaker) stream in +//| ``boot.py``. Until then ``usb_audio.usb_speaker`` is ``None``. +//| +//| .. code-block:: py +//| +//| # boot.py +//| import usb_audio +//| usb_audio.enable(sample_rate=16000, channel_count=1, +//| microphone=False, speaker=True) +//| +//| .. code-block:: py +//| +//| # code.py +//| import board +//| import usb_audio +//| import audiobusio +//| +//| spk = usb_audio.usb_speaker +//| out = audiobusio.I2SOut(board.I2S_BIT_CLOCK, board.I2S_WORD_SELECT, board.I2S_DATA) +//| out.play(spk, loop=True) +//| while True: +//| pass +//| +//| """ + +static mp_obj_t usb_audio_usbspeaker_deinit(mp_obj_t self_in) { + usb_audio_usbspeaker_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_usb_audio_usbspeaker_deinit(self); + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbspeaker_deinit_obj, usb_audio_usbspeaker_deinit); + +static void check_for_deinit(usb_audio_usbspeaker_obj_t *self) { + audiosample_check_for_deinit(&self->base); +} + +//| def read(self, destination: circuitpython_typing.WriteableBuffer, destination_length: int) -> int: +//| """Copies up to ``destination_length`` of the most recent samples streamed +//| from the host into ``destination``, for analysis such as an audio-reactive +//| effect or VU meter. This does not block: it returns whatever the host has +//| delivered so far, which may be fewer than ``destination_length`` samples +//| (or zero when the host is not streaming). +//| +//| ``destination`` must be an ``array.array`` of 16-bit signed samples +//| (typecode ``"h"``), matching the negotiated speaker format. +//| +//| Reading consumes the samples, so a ``USBSpeaker`` being read this way +//| should not also be passed to an output backend's ``play()`` at the same +//| time. +//| +//| :return: The number of samples copied into ``destination``.""" +//| ... +//| +static mp_obj_t usb_audio_usbspeaker_obj_read(mp_obj_t self_in, mp_obj_t destination, mp_obj_t destination_length) { + usb_audio_usbspeaker_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + uint32_t length = mp_arg_validate_type_int(destination_length, MP_QSTR_length); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(destination, &bufinfo, MP_BUFFER_WRITE); + // The negotiated speaker format is 16-bit signed PCM, so require a matching + // 'h' array. This keeps the copy a straight memcpy with no conversion. + if (bufinfo.typecode != 'h') { + mp_raise_TypeError(MP_ERROR_TEXT("destination must be an array of type 'h'")); + } + size_t capacity = bufinfo.len / sizeof(int16_t); + if (capacity < length) { + length = capacity; + } + + uint32_t length_read = common_hal_usb_audio_usbspeaker_read(self, bufinfo.buf, length); + return MP_OBJ_NEW_SMALL_INT(length_read); +} +static MP_DEFINE_CONST_FUN_OBJ_3(usb_audio_usbspeaker_read_obj, usb_audio_usbspeaker_obj_read); + +//| def __enter__(self) -> USBSpeaker: +//| """No-op used by Context Managers.""" +//| ... +//| +// Provided by context manager helper. + +//| def __exit__(self) -> None: +//| """Automatically deinitializes the hardware when exiting a context. See +//| :ref:`lifetime-and-contextmanagers` for more info.""" +//| ... +//| +// Provided by context manager helper. + +//| connected: bool +//| """True while the host is streaming audio to this speaker. (read-only)""" +//| +//| +static mp_obj_t usb_audio_usbspeaker_obj_get_connected(mp_obj_t self_in) { + usb_audio_usbspeaker_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_bool(common_hal_usb_audio_usbspeaker_get_connected(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(usb_audio_usbspeaker_get_connected_obj, usb_audio_usbspeaker_obj_get_connected); + +MP_PROPERTY_GETTER(usb_audio_usbspeaker_connected_obj, + (mp_obj_t)&usb_audio_usbspeaker_get_connected_obj); + +//| sample_rate: int +//| """The sample rate negotiated with the host in ``boot.py``. (read-only)""" +//| +//| bits_per_sample: int +//| """The bit depth negotiated with the host in ``boot.py``. (read-only)""" +//| +//| channel_count: int +//| """The number of channels negotiated with the host in ``boot.py``. (read-only)""" +//| +//| +static const mp_rom_map_elem_t usb_audio_usbspeaker_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&usb_audio_usbspeaker_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&usb_audio_usbspeaker_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&usb_audio_usbspeaker_read_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&default___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&usb_audio_usbspeaker_connected_obj) }, + AUDIOSAMPLE_FIELDS, +}; +static MP_DEFINE_CONST_DICT(usb_audio_usbspeaker_locals_dict, usb_audio_usbspeaker_locals_dict_table); + +static const audiosample_p_t usb_audio_usbspeaker_proto = { + MP_PROTO_IMPLEMENT(MP_QSTR_protocol_audiosample) + .reset_buffer = (audiosample_reset_buffer_fun)usb_audio_usbspeaker_reset_buffer, + .get_buffer = (audiosample_get_buffer_fun)usb_audio_usbspeaker_get_buffer, +}; + +MP_DEFINE_CONST_OBJ_TYPE( + usb_audio_USBSpeaker_type, + MP_QSTR_USBSpeaker, + MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS, + locals_dict, &usb_audio_usbspeaker_locals_dict, + protocol, &usb_audio_usbspeaker_proto + ); diff --git a/shared-bindings/usb_audio/USBSpeaker.h b/shared-bindings/usb_audio/USBSpeaker.h new file mode 100644 index 00000000000..30d2b0862a3 --- /dev/null +++ b/shared-bindings/usb_audio/USBSpeaker.h @@ -0,0 +1,17 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "shared-module/usb_audio/USBSpeaker.h" + +extern const mp_obj_type_t usb_audio_USBSpeaker_type; + +void common_hal_usb_audio_usbspeaker_construct(usb_audio_usbspeaker_obj_t *self); +void common_hal_usb_audio_usbspeaker_deinit(usb_audio_usbspeaker_obj_t *self); +bool common_hal_usb_audio_usbspeaker_deinited(usb_audio_usbspeaker_obj_t *self); +bool common_hal_usb_audio_usbspeaker_get_connected(usb_audio_usbspeaker_obj_t *self); +uint32_t common_hal_usb_audio_usbspeaker_read(usb_audio_usbspeaker_obj_t *self, void *buffer, uint32_t length); diff --git a/shared-bindings/usb_audio/__init__.c b/shared-bindings/usb_audio/__init__.c new file mode 100644 index 00000000000..31d3ab549fd --- /dev/null +++ b/shared-bindings/usb_audio/__init__.c @@ -0,0 +1,155 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_audio/__init__.h" +#include "shared-bindings/usb_audio/USBMicrophone.h" +#include "shared-bindings/usb_audio/USBSpeaker.h" +#include "shared-module/usb_audio/__init__.h" +#include "shared-module/usb_audio/usb_audio_descriptors.h" + +//| """Stream audio to a host computer via USB +//| +//| This makes your CircuitPython device identify to the host computer as a USB +//| Audio Class (UAC2) microphone: the board is the audio *source* and streams +//| samples to the host over a USB isochronous IN endpoint. +//| +//| This mode requires 2 IN endpoints and 2 interfaces. +//| Generally, microcontrollers have a limit on the number of endpoints. If you exceed the number +//| of endpoints, CircuitPython will automatically enter Safe Mode. Even in this case, you may be +//| able to enable USB audio by also disabling other USB functions, such as +//| `usb_hid` or `usb_midi`. +//| +//| To enable this mode, you must configure the audio format in ``boot.py`` and then +//| use the `usb_microphone` singleton instance in ``code.py``. +//| +//| .. code-block:: py +//| +//| # boot.py +//| import usb_audio +//| usb_audio.enable(sample_rate=16000) +//| +//| .. code-block:: py +//| +//| # code.py +//| import time +//| import usb_audio +//| import synthio +//| +//| # usb_audio.usb_microphone is a singleton instance (created by enable() above), +//| # not a class you construct. It is a consumer of an audio sample, just like +//| # audioio.AudioOut: the samples it pulls are streamed to the host PC instead +//| # of to a pin. +//| mic = usb_audio.usb_microphone +//| synth = synthio.Synthesizer(sample_rate=16000, channel_count=1) +//| mic.play(synth, loop=True) +//| +//| c_major_scale = [60, 62, 64, 65, 67, 69, 71, 72] +//| try: +//| while True: +//| for note in c_major_scale: +//| synth.press(note) +//| time.sleep(0.1) +//| synth.release(note) +//| time.sleep(0.05) +//| except KeyboardInterrupt: +//| pass +//| mic.stop() +//| +//| The ``sample_rate`` and ``channel_count`` of the sample played must match the values passed to `enable`, +//| and the sample must be 16-bit signed; otherwise ``play`` raises a ``ValueError``. +//| +//| This interface is experimental and may change without notice even in stable +//| versions of CircuitPython.""" +//| +//| + +//| usb_microphone: Optional[USBMicrophone] +//| """The shared `USBMicrophone` singleton instance, or ``None`` until +//| ``usb_audio.enable()`` has configured an input (microphone) stream in ``boot.py``. +//| `USBMicrophone` is exposed only as a type; you do not construct it.""" +//| +//| usb_speaker: Optional[USBSpeaker] +//| """The shared `USBSpeaker` singleton instance, or ``None`` until +//| ``usb_audio.enable()`` has configured an output (speaker) stream in ``boot.py``. +//| `USBSpeaker` is exposed only as a type; you do not construct it.""" +//| + +//| def enable( +//| sample_rate: int = 16000, +//| channel_count: int = 1, +//| microphone: bool = True, +//| speaker: bool = False, +//| ) -> None: +//| """Enable the USB audio interface with the given PCM format. +//| +//| This function may only be used from ``boot.py``. +//| +//| :param int sample_rate: Samples per second of the streamed audio. +//| :param int channel_count: Number of channels. Either mono (1) or stereo (2) is supported. +//| :param bool microphone: Present a microphone (audio flows board -> host). Enabled by default. +//| :param bool speaker: Present a speaker (audio flows host -> board). +//| +//| Enabling both ``microphone`` and ``speaker`` presents a combined headset. At +//| least one of the two must be enabled.""" +//| +//| +static mp_obj_t usb_audio_enable(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_sample_rate, ARG_channel_count, ARG_microphone, ARG_speaker }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_sample_rate, MP_ARG_INT, { .u_int = 16000 } }, + { MP_QSTR_channel_count, MP_ARG_INT, { .u_int = 1 } }, + { MP_QSTR_microphone, MP_ARG_BOOL, { .u_bool = true } }, + { MP_QSTR_speaker, MP_ARG_BOOL, { .u_bool = false } }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_int_t sample_rate = mp_arg_validate_int_range(args[ARG_sample_rate].u_int, 1, USB_AUDIO_MAX_SAMPLE_RATE, MP_QSTR_sample_rate); + mp_int_t channel_count = mp_arg_validate_int_range(args[ARG_channel_count].u_int, 1, USB_AUDIO_N_CHANNELS, MP_QSTR_channel_count); + bool microphone = args[ARG_microphone].u_bool; + bool speaker = args[ARG_speaker].u_bool; + + if (!microphone && !speaker) { + mp_raise_ValueError(MP_ERROR_TEXT("At least one of microphone and speaker must be enabled")); + } + + if (!shared_module_usb_audio_enable(sample_rate, channel_count, microphone, speaker)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot change USB devices now")); + } + + return mp_const_none; +} +static MP_DEFINE_CONST_FUN_OBJ_KW(usb_audio_enable_obj, 0, usb_audio_enable); + +mp_map_elem_t usb_audio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_usb_audio) }, + // USBMicrophone and USBSpeaker are the classes, exposed only for typing and + // isinstance() checks; you do not construct them. The usable objects are the + // pre-made singleton instances installed at the usb_microphone / usb_speaker + // attributes below. + { MP_ROM_QSTR(MP_QSTR_USBMicrophone), MP_OBJ_FROM_PTR(&usb_audio_USBMicrophone_type) }, + { MP_ROM_QSTR(MP_QSTR_USBSpeaker), MP_OBJ_FROM_PTR(&usb_audio_USBSpeaker_type) }, + // usb_microphone and usb_speaker are the singleton instances, like + // usb_midi.ports. usb_audio_setup_singletons() replaces these None + // placeholders with the real instances at the start of each VM when the + // matching direction was enabled in boot.py. + { MP_ROM_QSTR(MP_QSTR_usb_microphone), MP_ROM_NONE }, + { MP_ROM_QSTR(MP_QSTR_usb_speaker), MP_ROM_NONE }, + { MP_ROM_QSTR(MP_QSTR_enable), MP_OBJ_FROM_PTR(&usb_audio_enable_obj) }, +}; + +// This isn't const so the singleton instances can be installed dynamically. +MP_DEFINE_MUTABLE_DICT(usb_audio_module_globals, usb_audio_module_globals_table); + +const mp_obj_module_t usb_audio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t *)&usb_audio_module_globals, +}; + +MP_REGISTER_MODULE(MP_QSTR_usb_audio, usb_audio_module); diff --git a/shared-bindings/usb_audio/__init__.h b/shared-bindings/usb_audio/__init__.h new file mode 100644 index 00000000000..f9ad0eeeb78 --- /dev/null +++ b/shared-bindings/usb_audio/__init__.h @@ -0,0 +1,15 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +#include "shared-module/usb_audio/__init__.h" + +// The module globals dict is mutable so the USBMicrophone and USBSpeaker +// singleton instances can be installed at runtime (see usb_audio_setup_singletons). +extern mp_obj_dict_t usb_audio_module_globals; diff --git a/shared-bindings/usb_cdc/Serial.c b/shared-bindings/usb_cdc/Serial.c index 9fc5de21bcd..9bbc2b78f35 100644 --- a/shared-bindings/usb_cdc/Serial.c +++ b/shared-bindings/usb_cdc/Serial.c @@ -22,11 +22,15 @@ //| The available instances are in the ``usb_cdc.serials`` tuple.""" //| ... //| -//| def read(self, size: int = 1) -> bytes: -//| """Read at most ``size`` bytes. If ``size`` exceeds the internal buffer size -//| only the bytes in the buffer will be read. If `timeout` is > 0 or ``None``, -//| and fewer than ``size`` bytes are available, keep waiting until the timeout -//| expires or ``size`` bytes are available. +//| def read(self, size: int = -1) -> bytes: +//| """Read at most ``size`` bytes. If ``size`` exceeds the internal buffer size, +//| only the bytes in the buffer will be read. If ``size`` is not specified or is ``-1``, +//| read as many bytes as possible, until the timeout expires. +//| If `timeout` is > 0 or ``None``, and fewer than ``size`` bytes are available, +//| keep waiting until the timeout expires or ``size`` bytes are available. +//| +//| If no bytes are read, return ``b''``. This is unlike, say, `busio.UART.read()`, which +//| would return ``None``. //| //| :return: Data read //| :rtype: bytes""" @@ -74,6 +78,7 @@ //| def flush(self) -> None: //| """Force out any unwritten bytes, waiting until they are written.""" //| ... +//| // These three methods are used by the shared stream methods. static mp_uint_t usb_cdc_serial_read_stream(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { @@ -95,7 +100,7 @@ static mp_uint_t usb_cdc_serial_write_stream(mp_obj_t self_in, const void *buf_i return common_hal_usb_cdc_serial_write(self, buf, size, errcode); } -static mp_uint_t usb_cdc_serial_ioctl_stream(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +static mp_uint_t usb_cdc_serial_ioctl_stream(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret = 0; switch (request) { @@ -151,6 +156,7 @@ MP_PROPERTY_GETTER(usb_cdc_serial_in_waiting_obj, //| out_waiting: int //| """Returns the number of bytes waiting to be written on the USB serial output. (read-only)""" +//| static mp_obj_t usb_cdc_serial_get_out_waiting(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); return mp_obj_new_int(common_hal_usb_cdc_serial_get_out_waiting(self)); @@ -163,6 +169,7 @@ MP_PROPERTY_GETTER(usb_cdc_serial_out_waiting_obj, //| def reset_input_buffer(self) -> None: //| """Clears any unread bytes.""" //| ... +//| static mp_obj_t usb_cdc_serial_reset_input_buffer(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_usb_cdc_serial_reset_input_buffer(self); @@ -173,6 +180,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_input_buffer_obj, usb_cdc_serial_ //| def reset_output_buffer(self) -> None: //| """Clears any unwritten bytes.""" //| ... +//| static mp_obj_t usb_cdc_serial_reset_output_buffer(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); common_hal_usb_cdc_serial_reset_output_buffer(self); @@ -186,7 +194,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_reset_output_buffer_obj, usb_cdc_serial static mp_obj_t usb_cdc_serial_get_timeout(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_float_t timeout = common_hal_usb_cdc_serial_get_timeout(self); - return (timeout < 0.0f) ? mp_const_none : mp_obj_new_float(self->timeout); + return (timeout < 0.0f) ? mp_const_none : mp_obj_new_float(timeout); } MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_timeout_obj, usb_cdc_serial_get_timeout); @@ -207,10 +215,11 @@ MP_PROPERTY_GETSET(usb_cdc_serial_timeout_obj, //| writing all the bytes passed to ``write()``.If 0, do not wait. //| If > 0, wait only ``write_timeout`` seconds.""" //| +//| static mp_obj_t usb_cdc_serial_get_write_timeout(mp_obj_t self_in) { usb_cdc_serial_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_float_t write_timeout = common_hal_usb_cdc_serial_get_write_timeout(self); - return (write_timeout < 0.0f) ? mp_const_none : mp_obj_new_float(self->write_timeout); + return (write_timeout < 0.0f) ? mp_const_none : mp_obj_new_float(write_timeout); } MP_DEFINE_CONST_FUN_OBJ_1(usb_cdc_serial_get_write_timeout_obj, usb_cdc_serial_get_write_timeout); @@ -230,22 +239,22 @@ MP_PROPERTY_GETSET(usb_cdc_serial_write_timeout_obj, static const mp_rom_map_elem_t usb_cdc_serial_locals_dict_table[] = { // Standard stream methods. { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, // Other pyserial-inspired attributes. - { MP_OBJ_NEW_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&usb_cdc_serial_in_waiting_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_out_waiting), MP_ROM_PTR(&usb_cdc_serial_out_waiting_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_input_buffer_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_reset_output_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_output_buffer_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&usb_cdc_serial_timeout_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write_timeout), MP_ROM_PTR(&usb_cdc_serial_write_timeout_obj) }, + { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&usb_cdc_serial_in_waiting_obj) }, + { MP_ROM_QSTR(MP_QSTR_out_waiting), MP_ROM_PTR(&usb_cdc_serial_out_waiting_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_input_buffer_obj) }, + { MP_ROM_QSTR(MP_QSTR_reset_output_buffer), MP_ROM_PTR(&usb_cdc_serial_reset_output_buffer_obj) }, + { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&usb_cdc_serial_timeout_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_timeout), MP_ROM_PTR(&usb_cdc_serial_write_timeout_obj) }, // Not in pyserial protocol. - { MP_OBJ_NEW_QSTR(MP_QSTR_connected), MP_ROM_PTR(&usb_cdc_serial_connected_obj) }, + { MP_ROM_QSTR(MP_QSTR_connected), MP_ROM_PTR(&usb_cdc_serial_connected_obj) }, diff --git a/shared-bindings/usb_cdc/Serial.h b/shared-bindings/usb_cdc/Serial.h index 30249cef389..091f7514a4f 100644 --- a/shared-bindings/usb_cdc/Serial.h +++ b/shared-bindings/usb_cdc/Serial.h @@ -6,7 +6,11 @@ #pragma once +#if defined(__ZEPHYR__) && __ZEPHYR__ == 1 +#include "common-hal/usb_cdc/Serial.h" +#else #include "shared-module/usb_cdc/Serial.h" +#endif extern const mp_obj_type_t usb_cdc_serial_type; diff --git a/shared-bindings/usb_cdc/__init__.c b/shared-bindings/usb_cdc/__init__.c index 3a2c43c3e92..65d343b0351 100644 --- a/shared-bindings/usb_cdc/__init__.c +++ b/shared-bindings/usb_cdc/__init__.c @@ -40,6 +40,7 @@ //| the host. //| Note that `data` is *disabled* by default. ``data`` is ``None`` if disabled.""" //| +//| //| def disable() -> None: //| """Do not present any USB CDC device to the host. @@ -47,6 +48,7 @@ //| Equivalent to ``usb_cdc.enable(console=False, data=False)``.""" //| ... //| +//| static mp_obj_t usb_cdc_disable(void) { if (!common_hal_usb_cdc_disable()) { mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot change USB devices now")); @@ -70,6 +72,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_cdc_disable_obj, usb_cdc_disable); //| """ //| ... //| +//| static mp_obj_t usb_cdc_enable(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_console, ARG_data }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/usb_cdc/__init__.h b/shared-bindings/usb_cdc/__init__.h index 34099f7e8fd..154f259f410 100644 --- a/shared-bindings/usb_cdc/__init__.h +++ b/shared-bindings/usb_cdc/__init__.h @@ -6,7 +6,11 @@ #pragma once +#if defined(__ZEPHYR__) && __ZEPHYR__ == 1 +#include "common-hal/usb_cdc/__init__.h" +#else #include "shared-module/usb_cdc/__init__.h" +#endif // Set the module dict entries. void usb_cdc_set_console(mp_obj_t serial_obj); diff --git a/shared-bindings/usb_hid/Device.c b/shared-bindings/usb_hid/Device.c index 1afdda509f4..66c9c01ad6e 100644 --- a/shared-bindings/usb_hid/Device.c +++ b/shared-bindings/usb_hid/Device.c @@ -19,7 +19,7 @@ //| usage: int, //| report_ids: Sequence[int], //| in_report_lengths: Sequence[int], -//| out_report_lengths: Sequence[int] +//| out_report_lengths: Sequence[int], //| ) -> None: //| """Create a description of a USB HID device. The actual device is created when you //| pass a `Device` to `usb_hid.enable()`. @@ -57,6 +57,7 @@ //| See `send_report()` for details. //| """ //| ... +//| //| KEYBOARD: Device //| """Standard keyboard device supporting keycodes 0x00-0xDD, modifiers 0xE-0xE7, and five LED indicators. //| Uses Report ID 1 for its IN and OUT reports. @@ -71,9 +72,9 @@ //| CONSUMER_CONTROL: Device //| """Consumer Control device supporting sent values from 1-652, with no rollover. //| Uses Report ID 3 for its IN report.""" +//| static mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { - usb_hid_device_obj_t *self = mp_obj_malloc(usb_hid_device_obj_t, &usb_hid_device_type); enum { ARG_report_descriptor, ARG_usage_page, ARG_usage, ARG_report_ids, ARG_in_report_lengths, ARG_out_report_lengths }; static const mp_arg_t allowed_args[] = { { MP_QSTR_report_descriptor, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ }, @@ -96,7 +97,7 @@ static mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args const uint16_t usage_page = usage_page_arg; const mp_int_t usage_arg = args[ARG_usage].u_int; - mp_arg_validate_int_range(usage_arg, 1, 0xFFFF, MP_QSTR_usage); + mp_arg_validate_int_range(usage_arg, 0, 0xFFFF, MP_QSTR_usage); const uint16_t usage = usage_arg; mp_obj_t report_ids = args[ARG_report_ids].u_obj; @@ -139,9 +140,10 @@ static mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args mp_raise_ValueError_varg(MP_ERROR_TEXT("%q length must be %d"), MP_QSTR_report_id_space_0, 1); } + usb_hid_device_obj_t *self = mp_obj_malloc(usb_hid_device_obj_t, &usb_hid_device_type); common_hal_usb_hid_device_construct( self, descriptor, usage_page, usage, report_ids_count, report_ids_array, in_report_lengths_array, out_report_lengths_array); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); } @@ -161,6 +163,7 @@ static mp_obj_t usb_hid_device_make_new(const mp_obj_type_t *type, size_t n_args //| In addition, there may be USB wakeup settings in the host computer BIOS/UEFI. //| """ //| ... +//| static mp_obj_t usb_hid_device_send_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -195,6 +198,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_device_send_report_obj, 1, usb_hid_device_sen //| will return `None` until next report is received. //| """ //| ... +//| static mp_obj_t usb_hid_device_get_last_received_report(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -233,6 +237,7 @@ MP_PROPERTY_GETTER(usb_hid_device_usage_page_obj, //| For example, Keyboard is 0x06 within the generic desktop usage page 0x01. //| Mouse is 0x02 within the same usage page.""" //| +//| static mp_obj_t usb_hid_device_obj_get_usage(mp_obj_t self_in) { usb_hid_device_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_NEW_SMALL_INT(common_hal_usb_hid_device_get_usage(self)); diff --git a/shared-bindings/usb_hid/__init__.c b/shared-bindings/usb_hid/__init__.c index 49a9662c956..47f7f03c493 100644 --- a/shared-bindings/usb_hid/__init__.c +++ b/shared-bindings/usb_hid/__init__.c @@ -14,6 +14,7 @@ //| """USB Human Interface Device //| //| The `usb_hid` module allows you to output data as a HID device.""" +//| //| devices: Tuple[Device, ...] //| """Tuple of all active HID device interfaces. @@ -26,6 +27,7 @@ //| The request for a boot device overrides any other HID devices. //| """ //| +//| //| def disable() -> None: //| """Do not present any USB HID devices to the host computer. @@ -36,6 +38,7 @@ //| as `usb_cdc` or `storage` to free up endpoints for use by `usb_hid`. //| """ //| +//| static mp_obj_t usb_hid_disable(void) { if (!common_hal_usb_hid_disable()) { mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot change USB devices now")); @@ -65,15 +68,16 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_hid_disable_obj, usb_hid_disable); //| //| **Boot Devices** //| -//| Boot devices implement a fixed, predefined report descriptor, defined in -//| https://www.usb.org/sites/default/files/hid1_12.pdf, Appendix B. A USB host -//| can request to use the boot device if the USB device says it is available. -//| Usually only a BIOS or other kind of limited-functionality -//| host needs boot keyboard support. +//| A USB HID boot device implements a fixed, predefined report descriptor, +//| as defined in https://www.usb.org/sites/default/files/hid1_12.pdf, Appendix B. +//| Currently the only HID boot devices defined in the USB specification are a keyboard and a mouse. +//| A USB host can ask a USB device to use a boot device if the USB device says it is available. +//| Usually only a limited-functionality host like a BIOS or other boot-time software +//| needs boot device support. //| //| For example, to make a boot keyboard available, you can use this code:: //| -//| usb_hid.enable((Device.KEYBOARD), boot_device=1) # 1 for a keyboard +//| usb_hid.enable((Device.KEYBOARD,), boot_device=1) # 1 for a keyboard, 2 for a mouse //| //| If the host requests the boot keyboard, the report descriptor provided by `Device.KEYBOARD` //| will be ignored, and the predefined report descriptor will be used. @@ -88,6 +92,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_hid_disable_obj, usb_hid_disable); //| """ //| ... //| +//| static mp_obj_t usb_hid_enable(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_devices, ARG_boot_device }; static const mp_arg_t allowed_args[] = { @@ -130,6 +135,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(usb_hid_enable_obj, 1, usb_hid_enable); //| :rtype int: //| """ //| +//| static mp_obj_t usb_hid_get_boot_device(void) { return MP_OBJ_NEW_SMALL_INT(common_hal_usb_hid_get_boot_device()); } @@ -147,6 +153,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_hid_get_boot_device_obj, usb_hid_get_boot_device); //| """ //| ... //| +//| static mp_obj_t usb_hid_set_interface_name(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { static const mp_arg_t allowed_args[] = { { MP_QSTR_interface_name, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = mp_const_none} } diff --git a/shared-bindings/usb_host/Port.c b/shared-bindings/usb_host/Port.c index 10e38c8f3a6..2c61e641a05 100644 --- a/shared-bindings/usb_host/Port.c +++ b/shared-bindings/usb_host/Port.c @@ -28,6 +28,7 @@ //| """ //| ... //| +//| static mp_obj_t usb_host_port_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { // check number of arguments @@ -41,7 +42,7 @@ static mp_obj_t usb_host_port_make_new(const mp_obj_type_t *type, usb_host_port_obj_t *self = common_hal_usb_host_port_construct(dp, dm); - return (mp_obj_t)self; + return MP_OBJ_FROM_PTR(self); } static const mp_rom_map_elem_t usb_host_port_locals_dict_table[] = { diff --git a/shared-bindings/usb_host/__init__.c b/shared-bindings/usb_host/__init__.c index d71231aef15..a42c688b6af 100644 --- a/shared-bindings/usb_host/__init__.c +++ b/shared-bindings/usb_host/__init__.c @@ -18,6 +18,7 @@ //| with devices use the `usb` module that is a subset of PyUSB's API. //| """ //| +//| //| def set_user_keymap(keymap: ReadableBuffer, /) -> None: //| """Set the keymap used by a USB HID keyboard in kernel mode //| @@ -40,6 +41,7 @@ //| This function is a CircuitPython extension not present in PyUSB //| """ //| +//| static mp_obj_t usb_set_user_keymap(mp_obj_t buf_in) { mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ); diff --git a/shared-bindings/usb_midi/PortIn.c b/shared-bindings/usb_midi/PortIn.c index 38662a4468c..3f4b19fdec2 100644 --- a/shared-bindings/usb_midi/PortIn.c +++ b/shared-bindings/usb_midi/PortIn.c @@ -23,6 +23,7 @@ //| PortIn objects are constructed for every corresponding entry in the USB //| descriptor and added to the ``usb_midi.ports`` tuple.""" //| ... +//| // These are standard stream methods. Code is in py/stream.c. // @@ -44,6 +45,7 @@ //| :rtype: bytes or None""" //| ... //| +//| // These three methods are used by the shared stream methods. static mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { @@ -58,7 +60,7 @@ static mp_uint_t usb_midi_portin_read(mp_obj_t self_in, void *buf_in, mp_uint_t return common_hal_usb_midi_portin_read(self, buf, size, errcode); } -static mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +static mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { usb_midi_portin_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; if (request == MP_STREAM_POLL) { @@ -76,8 +78,8 @@ static mp_uint_t usb_midi_portin_ioctl(mp_obj_t self_in, mp_uint_t request, mp_u static const mp_rom_map_elem_t usb_midi_portin_locals_dict_table[] = { // Standard stream methods. - { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, }; static MP_DEFINE_CONST_DICT(usb_midi_portin_locals_dict, usb_midi_portin_locals_dict_table); diff --git a/shared-bindings/usb_midi/PortOut.c b/shared-bindings/usb_midi/PortOut.c index c39683c3f09..35856ff25fa 100644 --- a/shared-bindings/usb_midi/PortOut.c +++ b/shared-bindings/usb_midi/PortOut.c @@ -22,6 +22,7 @@ //| //| PortOut objects are constructed for every corresponding entry in the USB //| descriptor and added to the ``usb_midi.ports`` tuple.""" +//| // These are standard stream methods. Code is in py/stream.c. // @@ -32,6 +33,7 @@ //| :rtype: int or None""" //| ... //| +//| static mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -40,7 +42,7 @@ static mp_uint_t usb_midi_portout_write(mp_obj_t self_in, const void *buf_in, mp return common_hal_usb_midi_portout_write(self, buf, size, errcode); } -static mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { +static mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) { usb_midi_portout_obj_t *self = MP_OBJ_TO_PTR(self_in); mp_uint_t ret; if (request == MP_STREAM_POLL) { @@ -58,7 +60,7 @@ static mp_uint_t usb_midi_portout_ioctl(mp_obj_t self_in, mp_uint_t request, mp_ static const mp_rom_map_elem_t usb_midi_portout_locals_dict_table[] = { // Standard stream methods. - { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, }; static MP_DEFINE_CONST_DICT(usb_midi_portout_locals_dict, usb_midi_portout_locals_dict_table); diff --git a/shared-bindings/usb_midi/__init__.c b/shared-bindings/usb_midi/__init__.c index c29cb3b4414..fc10f89c31f 100644 --- a/shared-bindings/usb_midi/__init__.c +++ b/shared-bindings/usb_midi/__init__.c @@ -22,6 +22,7 @@ //| ports: Tuple[Union[PortIn, PortOut], ...] //| """Tuple of all MIDI ports. Each item is ether `PortIn` or `PortOut`.""" //| +//| //| def disable() -> None: //| """Disable presenting a USB MIDI device to the host. @@ -30,6 +31,7 @@ //| Can be called in ``boot.py``, before USB is connected.""" //| ... //| +//| static mp_obj_t usb_midi_disable(void) { if (!common_hal_usb_midi_disable()) { mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot change USB devices now")); @@ -50,6 +52,7 @@ MP_DEFINE_CONST_FUN_OBJ_0(usb_midi_disable_obj, usb_midi_disable); //| """ //| ... //| +//| static mp_obj_t usb_midi_enable(void) { if (!common_hal_usb_midi_enable()) { mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot change USB devices now")); @@ -81,7 +84,7 @@ static void set_name(mp_obj_t name_obj, qstr arg_name_qstr, char **custom_name_p //| streaming_interface_name: Optional[str] = None, //| audio_control_interface_name: Optional[str] = None, //| in_jack_name: Optional[str] = None, -//| out_jack_name: Optional[str] = None +//| out_jack_name: Optional[str] = None, //| ) -> None: //| """Override the MIDI interface names in the USB Interface Descriptor. //| @@ -93,9 +96,13 @@ static void set_name(mp_obj_t name_obj, qstr arg_name_qstr, char **custom_name_p //| This method must be called in boot.py to have any effect. //| //| Not available on boards without native USB support. +//| +//| .. warning:: On Windows, if ``audio_control_interface_name`` is more than 31 characters long, Windows +//| will not recognize the device. This issue is not present on macOS or Linux. //| """ //| ... //| +//| static mp_obj_t usb_midi_set_names(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_streaming_interface_name, ARG_audio_control_interface_name, ARG_in_jack_name, ARG_out_jack_name }; static const mp_arg_t allowed_args[] = { diff --git a/shared-bindings/usb_video/USBFramebuffer.c b/shared-bindings/usb_video/USBFramebuffer.c index c980784c850..25151809df5 100644 --- a/shared-bindings/usb_video/USBFramebuffer.c +++ b/shared-bindings/usb_video/USBFramebuffer.c @@ -33,6 +33,7 @@ static void check_for_deinit(usb_video_uvcframebuffer_obj_t *self) { //| //| def __init__(self) -> None: //| """Returns the singleton framebuffer object, if USB video is enabled""" +//| static mp_obj_t usb_video_uvcframebuffer_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { static const mp_arg_t allowed_args[] = {}; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; @@ -45,6 +46,7 @@ static mp_obj_t usb_video_uvcframebuffer_make_new(const mp_obj_type_t *type, siz //| """Transmits the color data in the buffer to the pixels so that //| they are shown.""" //| ... +//| static mp_obj_t usb_video_uvcframebuffer_refresh(mp_obj_t self_in) { usb_video_uvcframebuffer_obj_t *self = (usb_video_uvcframebuffer_obj_t *)self_in; check_for_deinit(self); @@ -67,6 +69,7 @@ MP_PROPERTY_GETTER(usb_video_uvcframebuffer_width_obj, //| height: int //| """The height of the display, in pixels""" //| +//| static mp_obj_t usb_video_uvcframebuffer_get_height(mp_obj_t self_in) { usb_video_uvcframebuffer_obj_t *self = (usb_video_uvcframebuffer_obj_t *)self_in; check_for_deinit(self); diff --git a/shared-bindings/usb_video/__init__.c b/shared-bindings/usb_video/__init__.c index 189acd9109c..06050188d66 100644 --- a/shared-bindings/usb_video/__init__.c +++ b/shared-bindings/usb_video/__init__.c @@ -46,6 +46,7 @@ //| This interface is experimental and may change without notice even in stable //| versions of CircuitPython.""" //| +//| //| def enable_framebuffer(width: int, height: int) -> None: //| """Enable a USB video framebuffer, setting the given width & height @@ -59,6 +60,7 @@ //| for Python objects. If the allocation fails, a MemoryError is raised. //| This message can be seen in ``boot_out.txt``.""" //| +//| static mp_obj_t usb_video_enable_framebuffer(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_width, ARG_height }; diff --git a/shared-bindings/ustack/__init__.c b/shared-bindings/ustack/__init__.c index 3002254db25..9676c517a62 100644 --- a/shared-bindings/ustack/__init__.c +++ b/shared-bindings/ustack/__init__.c @@ -16,12 +16,14 @@ //| """Stack information and analysis""" //| +//| #if MICROPY_MAX_STACK_USAGE //| def max_stack_usage() -> int: //| """Return the maximum excursion of the stack so far.""" //| ... //| +//| static mp_obj_t max_stack_usage(void) { return MP_OBJ_NEW_SMALL_INT(shared_module_ustack_max_stack_usage()); } @@ -35,6 +37,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(max_stack_usage_obj, max_stack_usage); //| of just printing it.""" //| ... //| +//| static mp_obj_t stack_size(void) { return MP_OBJ_NEW_SMALL_INT(shared_module_ustack_stack_size()); } @@ -45,6 +48,7 @@ static MP_DEFINE_CONST_FUN_OBJ_0(stack_size_obj, stack_size); //| Same as micropython.stack_use(); duplicated here for convenience.""" //| ... //| +//| static mp_obj_t stack_usage(void) { return MP_OBJ_NEW_SMALL_INT(shared_module_ustack_stack_usage()); } diff --git a/shared-bindings/util.c b/shared-bindings/util.c index 0711428b4de..0bcaa2eef41 100644 --- a/shared-bindings/util.c +++ b/shared-bindings/util.c @@ -8,6 +8,8 @@ #include "shared-bindings/util.h" +#include "shared-bindings/os/__init__.h" + // If so, deinit() has already been called on the object, so complain. void raise_deinited_error(void) { mp_raise_ValueError(MP_ERROR_TEXT("Object has been deinitialized and can no longer be used. Create a new object.")); @@ -33,3 +35,16 @@ void properties_construct_helper(mp_obj_t self_in, const mp_arg_t *args, const m } } } + +bool path_exists(const char *path) { + // Use common_hal_os_stat to check if path exists + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + common_hal_os_stat(path); + nlr_pop(); + return true; + } else { + // Path doesn't exist + return false; + } +} diff --git a/shared-bindings/util.h b/shared-bindings/util.h index f1e4dca13aa..11f0a00db71 100644 --- a/shared-bindings/util.h +++ b/shared-bindings/util.h @@ -9,6 +9,7 @@ #include "py/mpprint.h" #include "py/runtime.h" -void raise_deinited_error(void); +MP_NORETURN void raise_deinited_error(void); void properties_print_helper(const mp_print_t *print, mp_obj_t self_in, const mp_arg_t *properties, size_t n_properties); void properties_construct_helper(mp_obj_t self_in, const mp_arg_t *args, const mp_arg_val_t *vals, size_t n_properties); +bool path_exists(const char *path); diff --git a/shared-bindings/vectorio/Circle.c b/shared-bindings/vectorio/Circle.c index d2f31d6b86d..7fb20b59b4d 100644 --- a/shared-bindings/vectorio/Circle.c +++ b/shared-bindings/vectorio/Circle.c @@ -31,11 +31,12 @@ //| :param int y: Initial y position of the axis. //| :param int color_index: Initial color_index to use when selecting color from the palette. //| """ +//| static mp_obj_t vectorio_circle_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pixel_shader, ARG_radius, ARG_x, ARG_y, ARG_color_index }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, { .u_obj = NULL } }, + { MP_QSTR_radius, MP_ARG_REQUIRED | MP_ARG_INT, { .u_obj = NULL } }, { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_index, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, @@ -123,6 +124,7 @@ MP_PROPERTY_GETSET(vectorio_circle_color_index_obj, //| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] //| """The pixel shader of the circle.""" //| +//| static const mp_rom_map_elem_t vectorio_circle_locals_dict_table[] = { // Functions diff --git a/shared-bindings/vectorio/Polygon.c b/shared-bindings/vectorio/Polygon.c index 05228465f6c..0f45da21e61 100644 --- a/shared-bindings/vectorio/Polygon.c +++ b/shared-bindings/vectorio/Polygon.c @@ -39,10 +39,11 @@ //| :param int y: Initial screen y position of the 0,0 origin in the points list. //| :param int color_index: Initial color_index to use when selecting color from the palette. //| """ +//| static mp_obj_t vectorio_polygon_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pixel_shader, ARG_points_list, ARG_x, ARG_y, ARG_color_index }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, { .u_obj = NULL } }, { MP_QSTR_points, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, @@ -132,6 +133,7 @@ MP_PROPERTY_GETSET(vectorio_polygon_color_index_obj, //| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] //| """The pixel shader of the polygon.""" //| +//| static const mp_rom_map_elem_t vectorio_polygon_locals_dict_table[] = { // Functions diff --git a/shared-bindings/vectorio/Rectangle.c b/shared-bindings/vectorio/Rectangle.c index d1f2e6193ce..3582b010149 100644 --- a/shared-bindings/vectorio/Rectangle.c +++ b/shared-bindings/vectorio/Rectangle.c @@ -32,12 +32,13 @@ //| :param int y: Initial y position of the top left corner. //| :param int color_index: Initial color_index to use when selecting color from the palette. //| """ +//| static mp_obj_t vectorio_rectangle_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_pixel_shader, ARG_width, ARG_height, ARG_x, ARG_y, ARG_color_index }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED }, - { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT }, - { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT }, + { MP_QSTR_pixel_shader, MP_ARG_OBJ | MP_ARG_KW_ONLY | MP_ARG_REQUIRED, {.u_obj = NULL } }, + { MP_QSTR_width, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0 } }, + { MP_QSTR_height, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0 } }, { MP_QSTR_x, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_y, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, { MP_QSTR_color_index, MP_ARG_INT | MP_ARG_KW_ONLY, {.u_int = 0} }, @@ -85,12 +86,9 @@ static mp_obj_t vectorio_rectangle_obj_set_width(mp_obj_t self_in, mp_obj_t widt } MP_DEFINE_CONST_FUN_OBJ_2(vectorio_rectangle_set_width_obj, vectorio_rectangle_obj_set_width); -const mp_obj_property_t vectorio_rectangle_width_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&vectorio_rectangle_get_width_obj, - (mp_obj_t)&vectorio_rectangle_set_width_obj, - MP_ROM_NONE}, -}; +MP_PROPERTY_GETSET(vectorio_rectangle_width_obj, + (mp_obj_t)&vectorio_rectangle_get_width_obj, + (mp_obj_t)&vectorio_rectangle_set_width_obj); //| height: int //| """The height of the rectangle in pixels.""" @@ -107,12 +105,9 @@ static mp_obj_t vectorio_rectangle_obj_set_height(mp_obj_t self_in, mp_obj_t hei } MP_DEFINE_CONST_FUN_OBJ_2(vectorio_rectangle_set_height_obj, vectorio_rectangle_obj_set_height); -const mp_obj_property_t vectorio_rectangle_height_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&vectorio_rectangle_get_height_obj, - (mp_obj_t)&vectorio_rectangle_set_height_obj, - MP_ROM_NONE}, -}; +MP_PROPERTY_GETSET(vectorio_rectangle_height_obj, + (mp_obj_t)&vectorio_rectangle_get_height_obj, + (mp_obj_t)&vectorio_rectangle_set_height_obj); //| color_index: int //| """The color_index of the rectangle in 1 based index of the palette.""" @@ -129,12 +124,9 @@ static mp_obj_t vectorio_rectangle_obj_set_color_index(mp_obj_t self_in, mp_obj_ } MP_DEFINE_CONST_FUN_OBJ_2(vectorio_rectangle_set_color_index_obj, vectorio_rectangle_obj_set_color_index); -const mp_obj_property_t vectorio_rectangle_color_index_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&vectorio_rectangle_get_color_index_obj, - (mp_obj_t)&vectorio_rectangle_set_color_index_obj, - MP_ROM_NONE}, -}; +MP_PROPERTY_GETSET(vectorio_rectangle_color_index_obj, + (mp_obj_t)&vectorio_rectangle_get_color_index_obj, + (mp_obj_t)&vectorio_rectangle_set_color_index_obj); // Documentation for properties inherited from VectorShape. @@ -153,6 +145,7 @@ const mp_obj_property_t vectorio_rectangle_color_index_obj = { //| pixel_shader: Union[displayio.ColorConverter, displayio.Palette] //| """The pixel shader of the rectangle.""" //| +//| static const mp_rom_map_elem_t vectorio_rectangle_locals_dict_table[] = { // Functions diff --git a/shared-bindings/vectorio/VectorShape.c b/shared-bindings/vectorio/VectorShape.c index 041600bff4e..834f1fbff50 100644 --- a/shared-bindings/vectorio/VectorShape.c +++ b/shared-bindings/vectorio/VectorShape.c @@ -69,7 +69,7 @@ mp_obj_t vectorio_vector_shape_make_new(const mp_obj_t shape, const mp_obj_t pix } else if (mp_obj_is_type(shape, &vectorio_circle_type)) { common_hal_vectorio_circle_set_on_dirty(self->ishape.shape, on_dirty); } else { - mp_raise_TypeError_varg(MP_ERROR_TEXT("unsupported %q type"), MP_QSTR_shape); + // Already excluded due to previous else-if chain. } return MP_OBJ_FROM_PTR(self); @@ -82,6 +82,7 @@ vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl = { .draw_finish_refresh = (draw_finish_refresh_fun)vectorio_vector_shape_finish_refresh, .draw_get_refresh_areas = (draw_get_refresh_areas_fun)vectorio_vector_shape_get_refresh_areas, .draw_set_dirty = (draw_set_dirty_fun)common_hal_vectorio_vector_shape_set_dirty, + .draw_set_in_group = (draw_set_in_group_fun)vectorio_vector_shape_set_in_group, }; // Stub checker does not approve of these shared properties. diff --git a/shared-bindings/vectorio/VectorShape.h b/shared-bindings/vectorio/VectorShape.h index 9e06a0c146e..7924eb07ba2 100644 --- a/shared-bindings/vectorio/VectorShape.h +++ b/shared-bindings/vectorio/VectorShape.h @@ -43,6 +43,7 @@ mp_obj_t common_hal_vectorio_vector_shape_get_pixel_shader(vectorio_vector_shape void common_hal_vectorio_vector_shape_set_pixel_shader(vectorio_vector_shape_t *self, mp_obj_t pixel_shader); void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displayio_buffer_transform_t *group_transform); +bool vectorio_vector_shape_set_in_group(vectorio_vector_shape_t *self, bool in_group); // Composable property definition for shapes that use VectorShape extern vectorio_draw_protocol_impl_t vectorio_vector_shape_draw_protocol_impl; diff --git a/shared-bindings/vectorio/__init__.h b/shared-bindings/vectorio/__init__.h index c982f63815b..c5dcc026567 100644 --- a/shared-bindings/vectorio/__init__.h +++ b/shared-bindings/vectorio/__init__.h @@ -23,6 +23,7 @@ typedef bool (*draw_get_dirty_area_fun)(mp_obj_t draw_protocol_self, displayio_a typedef void (*draw_update_transform_fun)(mp_obj_t draw_protocol_self, displayio_buffer_transform_t *group_transform); typedef void (*draw_finish_refresh_fun)(mp_obj_t draw_protocol_self); typedef void (*draw_set_dirty_fun)(mp_obj_t draw_protocol_self); +typedef bool (*draw_set_in_group_fun)(mp_obj_t draw_protocol_self, bool in_group); typedef displayio_area_t *(*draw_get_refresh_areas_fun)(mp_obj_t draw_protocol_self, displayio_area_t *tail); typedef struct _vectorio_draw_protocol_impl_t { @@ -32,6 +33,7 @@ typedef struct _vectorio_draw_protocol_impl_t { draw_finish_refresh_fun draw_finish_refresh; draw_get_refresh_areas_fun draw_get_refresh_areas; draw_set_dirty_fun draw_set_dirty; + draw_set_in_group_fun draw_set_in_group; } vectorio_draw_protocol_impl_t; // Draw protocol diff --git a/shared-bindings/warnings/__init__.c b/shared-bindings/warnings/__init__.c index 1d726bc61a8..3984bb31758 100644 --- a/shared-bindings/warnings/__init__.c +++ b/shared-bindings/warnings/__init__.c @@ -25,6 +25,7 @@ //| //| import typing //| +//| //| def warn(message: str, category: type = Warning) -> None: //| """Issue a warning with an optional category. Use `simplefilter()` to @@ -33,6 +34,7 @@ //| """ //| ... //| +//| static mp_obj_t warnings_warn(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_message, ARG_category }; static const mp_arg_t allowed_args[] = { @@ -58,6 +60,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(warnings_warn_obj, 1, warnings_warn); //| behavior because it allows for per-category changes.""" //| ... //| +//| static mp_obj_t warnings_simplefilter(mp_obj_t action_in) { const char *action_str = mp_obj_str_get_str(action_in); warnings_action_t action; diff --git a/shared-bindings/watchdog/WatchDogMode.c b/shared-bindings/watchdog/WatchDogMode.c index 3aee1203d38..c049c051709 100644 --- a/shared-bindings/watchdog/WatchDogMode.c +++ b/shared-bindings/watchdog/WatchDogMode.c @@ -20,6 +20,7 @@ MAKE_ENUM_VALUE(watchdog_watchdogmode_type, watchdogmode, RESET, WATCHDOGMODE_RE //| RESET: WatchDogMode //| """Reset the system when the `WatchDogTimer` expires.""" //| +//| MAKE_ENUM_MAP(watchdog_watchdogmode) { MAKE_ENUM_MAP_ENTRY(watchdogmode, RAISE), MAKE_ENUM_MAP_ENTRY(watchdogmode, RESET), diff --git a/shared-bindings/watchdog/WatchDogTimer.c b/shared-bindings/watchdog/WatchDogTimer.c index 8ff8ba2f9c2..dbb91311345 100644 --- a/shared-bindings/watchdog/WatchDogTimer.c +++ b/shared-bindings/watchdog/WatchDogTimer.c @@ -32,11 +32,13 @@ //| def __init__(self) -> None: //| """Access the sole instance through `microcontroller.watchdog`.""" //| ... +//| //| def feed(self) -> None: //| """Feed the watchdog timer. This must be called regularly, otherwise //| the timer will expire. Silently does nothing if the watchdog isn't active.""" //| ... +//| static mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); if (common_hal_watchdog_get_mode(self) != WATCHDOGMODE_NONE) { @@ -46,23 +48,6 @@ static mp_obj_t watchdog_watchdogtimer_feed(mp_obj_t self_in) { } static MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_feed_obj, watchdog_watchdogtimer_feed); -//| def deinit(self) -> None: -//| """Stop the watchdog timer. -//| -//| :raises RuntimeError: if the watchdog timer cannot be disabled on this platform. -//| -//| .. note:: This is deprecated in ``9.0.0`` and will be removed in ``10.0.0``. -//| Set watchdog `mode` to `None` instead. -//| -//| """ -//| ... -static mp_obj_t watchdog_watchdogtimer_deinit(mp_obj_t self_in) { - watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_watchdog_deinit(self); - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_1(watchdog_watchdogtimer_deinit_obj, watchdog_watchdogtimer_deinit); - //| timeout: float //| """The maximum number of seconds that can elapse between calls //| to `feed()`. Setting the timeout will also feed the watchdog.""" @@ -102,6 +87,7 @@ MP_PROPERTY_GETSET(watchdog_watchdogtimer_timeout_obj, //| //| Once set, the `WatchDogTimer` will perform the specified action if the timer expires.""" //| +//| static mp_obj_t watchdog_watchdogtimer_obj_get_mode(mp_obj_t self_in) { watchdog_watchdogtimer_obj_t *self = MP_OBJ_TO_PTR(self_in); return cp_enum_find(&watchdog_watchdogmode_type, common_hal_watchdog_get_mode(self)); @@ -122,7 +108,6 @@ MP_PROPERTY_GETSET(watchdog_watchdogtimer_mode_obj, static const mp_rom_map_elem_t watchdog_watchdogtimer_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&watchdog_watchdogtimer_feed_obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&watchdog_watchdogtimer_deinit_obj) }, { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&watchdog_watchdogtimer_timeout_obj) }, { MP_ROM_QSTR(MP_QSTR_mode), MP_ROM_PTR(&watchdog_watchdogtimer_mode_obj) }, }; diff --git a/shared-bindings/watchdog/__init__.c b/shared-bindings/watchdog/__init__.c index 4e338844a0a..8ae7633f1f3 100644 --- a/shared-bindings/watchdog/__init__.c +++ b/shared-bindings/watchdog/__init__.c @@ -30,6 +30,7 @@ //| w.mode = WatchDogMode.RAISE //| w.feed()""" //| +//| //| class WatchDogTimeout(Exception): //| """Exception raised when the watchdog timer is set to @@ -58,6 +59,7 @@ //| print("Exited loop") //| """ //| +//| MP_DEFINE_CONST_OBJ_TYPE( mp_type_WatchDogTimeout, diff --git a/shared-bindings/wifi/AuthMode.c b/shared-bindings/wifi/AuthMode.c index c2c653727d6..d7f3af80bef 100644 --- a/shared-bindings/wifi/AuthMode.c +++ b/shared-bindings/wifi/AuthMode.c @@ -40,6 +40,7 @@ MAKE_ENUM_VALUE(wifi_authmode_type, authmode, ENTERPRISE, AUTHMODE_ENTERPRISE); //| ENTERPRISE: object //| """Each user has a unique credential.""" //| +//| MAKE_ENUM_MAP(wifi_authmode) { MAKE_ENUM_MAP_ENTRY(authmode, OPEN), MAKE_ENUM_MAP_ENTRY(authmode, WEP), diff --git a/shared-bindings/wifi/Monitor.c b/shared-bindings/wifi/Monitor.c index a2e91dca4b4..fb09c4b4f77 100644 --- a/shared-bindings/wifi/Monitor.c +++ b/shared-bindings/wifi/Monitor.c @@ -24,6 +24,7 @@ //| //| """ //| ... +//| static mp_obj_t wifi_monitor_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) { enum { ARG_channel, ARG_queue }; static const mp_arg_t allowed_args[] = { @@ -70,6 +71,7 @@ MP_PROPERTY_GETSET(wifi_monitor_channel_obj, //| queue: int //| """The queue size for buffering the packet.""" +//| static mp_obj_t wifi_monitor_obj_get_queue(mp_obj_t self_in) { return common_hal_wifi_monitor_get_queue(self_in); } @@ -81,6 +83,7 @@ MP_PROPERTY_GETTER(wifi_monitor_queue_obj, //| def deinit(self) -> None: //| """De-initialize `wifi.Monitor` singleton.""" //| ... +//| static mp_obj_t wifi_monitor_obj_deinit(mp_obj_t self_in) { common_hal_wifi_monitor_deinit(self_in); return mp_const_none; @@ -90,6 +93,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(wifi_monitor_deinit_obj, wifi_monitor_obj_deini //| def lost(self) -> int: //| """Returns the packet loss count. The counter resets after each poll.""" //| ... +//| static mp_obj_t wifi_monitor_obj_get_lost(mp_obj_t self_in) { return common_hal_wifi_monitor_get_lost(self_in); } @@ -98,6 +102,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_monitor_lost_obj, wifi_monitor_obj_get_lost); //| def queued(self) -> int: //| """Returns the packet queued count.""" //| ... +//| static mp_obj_t wifi_monitor_obj_get_queued(mp_obj_t self_in) { if (common_hal_wifi_monitor_deinited()) { return mp_obj_new_int_from_uint(0); @@ -110,6 +115,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_monitor_queued_obj, wifi_monitor_obj_get_queued); //| """Returns the monitor packet.""" //| ... //| +//| static mp_obj_t wifi_monitor_obj_get_packet(mp_obj_t self_in) { if (common_hal_wifi_monitor_deinited()) { raise_deinited_error(); diff --git a/shared-bindings/wifi/Network.c b/shared-bindings/wifi/Network.c index 3b9c0b6116c..93a483930e8 100644 --- a/shared-bindings/wifi/Network.c +++ b/shared-bindings/wifi/Network.c @@ -17,6 +17,7 @@ //| def __init__(self) -> None: //| """You cannot create an instance of `wifi.Network`. They are returned by `wifi.Radio.start_scanning_networks`.""" //| ... +//| //| ssid: str //| """String id of the network""" @@ -76,8 +77,9 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_network_get_country_obj, wifi_network_get_country MP_PROPERTY_GETTER(wifi_network_country_obj, (mp_obj_t)&wifi_network_get_country_obj); -//| authmode: str -//| """String id of the authmode""" +//| authmode: Sequence[wifi.AuthMode] +//| """List of authmodes (wifi.AuthMode) used by the network """ +//| //| static mp_obj_t wifi_network_get_authmode(mp_obj_t self) { return common_hal_wifi_network_get_authmode(self); diff --git a/shared-bindings/wifi/Packet.c b/shared-bindings/wifi/Packet.c index 9d7befa7a8a..85dd8cc25b1 100644 --- a/shared-bindings/wifi/Packet.c +++ b/shared-bindings/wifi/Packet.c @@ -28,6 +28,7 @@ MAKE_ENUM_VALUE(wifi_packet_type, packet, RSSI, PACKET_RSSI); //| RSSI: object //| """The packet's rssi.""" //| +//| MAKE_ENUM_MAP(wifi_packet) { MAKE_ENUM_MAP_ENTRY(packet, CH), MAKE_ENUM_MAP_ENTRY(packet, LEN), diff --git a/shared-bindings/wifi/PowerManagement.c b/shared-bindings/wifi/PowerManagement.c new file mode 100644 index 00000000000..659144b024d --- /dev/null +++ b/shared-bindings/wifi/PowerManagement.c @@ -0,0 +1,50 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "py/enum.h" + +#include "shared-bindings/wifi/PowerManagement.h" + +//| class PowerManagement: +//| """Power-saving options for wifi +//| +//| .. note:: On boards using the CYW43 radio module, the choices below correspond to the +//| power management values defined in the `cyw43` module: +//| `PowerManagement.MIN` is the same as `cyw43.PM_PERFORMANCE`, `PowerManagement.MAX` +//| is the same as `cyw43.PM_AGGRESSIVE`, and `PowerManagement.NONE` is the same as +//| `cyw43.PM_DISABLED`. If a custom value was set with `cyw43.set_power_management()` +//| not corresponding to one of these three values, then `PowerManagement.UNKNOWN` will be returned. +//| """ +//| +//| MIN: PowerManagement +//| """Minimum power management (default). The WiFi station wakes up to receive a beacon every DTIM period. +//| The DTIM period is set by the access point.""" +//| MAX: PowerManagement +//| """Maximum power management, at the expense of some performance. The WiFi station wakes up less often than `MIN`.""" +//| NONE: PowerManagement +//| """No power management: the WiFi station does not sleep.""" +//| UNKNOWN: PowerManagement +//| """Power management setting cannot be determined.""" +//| + +// In order of the enum type. +MAKE_ENUM_VALUE(wifi_power_management_type, power_management, NONE, POWER_MANAGEMENT_NONE); +MAKE_ENUM_VALUE(wifi_power_management_type, power_management, MIN, POWER_MANAGEMENT_MIN); +MAKE_ENUM_VALUE(wifi_power_management_type, power_management, MAX, POWER_MANAGEMENT_MAX); +MAKE_ENUM_VALUE(wifi_power_management_type, power_management, UNKNOWN, POWER_MANAGEMENT_UNKNOWN); + +MAKE_ENUM_MAP(wifi_power_management) { + MAKE_ENUM_MAP_ENTRY(power_management, NONE), + MAKE_ENUM_MAP_ENTRY(power_management, MIN), + MAKE_ENUM_MAP_ENTRY(power_management, MAX), + MAKE_ENUM_MAP_ENTRY(power_management, UNKNOWN), +}; + +static MP_DEFINE_CONST_DICT(wifi_power_management_locals_dict, wifi_power_management_locals_table); + +MAKE_PRINTER(wifi, wifi_power_management); + +MAKE_ENUM_TYPE(wifi, PowerManagement, wifi_power_management); diff --git a/shared-bindings/wifi/PowerManagement.h b/shared-bindings/wifi/PowerManagement.h new file mode 100644 index 00000000000..c933e36df15 --- /dev/null +++ b/shared-bindings/wifi/PowerManagement.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/enum.h" + +typedef enum { + POWER_MANAGEMENT_NONE = 0, + POWER_MANAGEMENT_MIN = 1, + POWER_MANAGEMENT_MAX = 2, + // Value can't be determined. + POWER_MANAGEMENT_UNKNOWN = 3, +} wifi_power_management_t; + +extern const mp_obj_type_t wifi_power_management_type; diff --git a/shared-bindings/wifi/Radio.c b/shared-bindings/wifi/Radio.c index 34e48925d3e..9a7d445fd04 100644 --- a/shared-bindings/wifi/Radio.c +++ b/shared-bindings/wifi/Radio.c @@ -6,9 +6,11 @@ #include "shared-bindings/wifi/__init__.h" #include "shared-bindings/wifi/AuthMode.h" +#include "shared-bindings/wifi/PowerManagement.h" #include +#include "py/enum.h" #include "py/unicode.h" #include "py/runtime.h" #include "py/objproperty.h" @@ -73,6 +75,7 @@ static void validate_hex_password(const uint8_t *buf, size_t len) { //| """You cannot create an instance of `wifi.Radio`. //| Use `wifi.radio` to access the sole instance available.""" //| ... +//| //| enabled: bool //| """``True`` when the wifi radio is enabled. @@ -96,7 +99,7 @@ MP_PROPERTY_GETSET(wifi_radio_enabled_obj, (mp_obj_t)&wifi_radio_get_enabled_obj, (mp_obj_t)&wifi_radio_set_enabled_obj); -//| hostname: Union[str | ReadableBuffer] +//| hostname: Union[str, ReadableBuffer] //| """Hostname for wifi interface. When the hostname is altered after interface started/connected //| the changes would only be reflected once the interface restarts/reconnects.""" static mp_obj_t wifi_radio_get_hostname(mp_obj_t self_in) { @@ -186,33 +189,30 @@ MP_PROPERTY_GETSET(wifi_radio_tx_power_obj, (mp_obj_t)&wifi_radio_get_tx_power_obj, (mp_obj_t)&wifi_radio_set_tx_power_obj); -//| listen_interval: int -//| """Wifi power save listen interval, in DTIM periods, or 100ms intervals if TWT is supported.""" -static mp_obj_t wifi_radio_get_listen_interval(mp_obj_t self_in) { - #if CIRCUITPY_WIFI_RADIO_SETTABLE_LISTEN_INTERVAL +//| power_management: PowerManagement +//| """Wifi power management setting. See `wifi.PowerManagement`. The default is `wifi.PowerManagement.MIN`. +//| """ +static mp_obj_t wifi_radio_get_power_management(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(common_hal_wifi_radio_get_listen_interval(self)); - #else - return mp_obj_new_int(0); - #endif + return cp_enum_find(&wifi_power_management_type, common_hal_wifi_radio_get_power_management(self)); } -MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_listen_interval_obj, wifi_radio_get_listen_interval); +MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_power_management_obj, wifi_radio_get_power_management); -static mp_obj_t wifi_radio_set_listen_interval(mp_obj_t self_in, mp_obj_t listen_interval_in) { - #if CIRCUITPY_WIFI_RADIO_SETTABLE_LISTEN_INTERVAL - mp_int_t listen_interval = mp_obj_get_int(listen_interval_in); +static mp_obj_t wifi_radio_set_power_management(mp_obj_t self_in, mp_obj_t power_management_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_wifi_radio_set_listen_interval(self, listen_interval); - #else - mp_raise_NotImplementedError(NULL); - #endif + wifi_power_management_t power_management = + cp_enum_value(&wifi_power_management_type, power_management_in, MP_QSTR_power_management); + if (power_management == POWER_MANAGEMENT_UNKNOWN) { + mp_arg_error_invalid(MP_QSTR_power_management); + } + common_hal_wifi_radio_set_power_management(self, power_management); return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_listen_interval_obj, wifi_radio_set_listen_interval); +MP_DEFINE_CONST_FUN_OBJ_2(wifi_radio_set_power_management_obj, wifi_radio_set_power_management); -MP_PROPERTY_GETSET(wifi_radio_listen_interval_obj, - (mp_obj_t)&wifi_radio_get_listen_interval_obj, - (mp_obj_t)&wifi_radio_set_listen_interval_obj); +MP_PROPERTY_GETSET(wifi_radio_power_management_obj, + (mp_obj_t)&wifi_radio_get_power_management_obj, + (mp_obj_t)&wifi_radio_set_power_management_obj); //| mac_address_ap: ReadableBuffer //| """MAC address for the AP. When the address is altered after interface is started @@ -220,6 +220,7 @@ MP_PROPERTY_GETSET(wifi_radio_listen_interval_obj, //| //| **Limitations:** Not settable on RP2040 CYW43 boards, such as Pi Pico W. //| """ +//| static mp_obj_t wifi_radio_get_mac_address_ap(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); return MP_OBJ_FROM_PTR(common_hal_wifi_radio_get_mac_address_ap(self)); @@ -262,6 +263,7 @@ MP_PROPERTY_GETTER(wifi_radio_mac_address_ap_obj, //| In the raspberrypi port (RP2040 CYW43), ``start_channel`` and ``stop_channel`` are ignored. //| """ //| ... +//| static mp_obj_t wifi_radio_start_scanning_networks(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_start_channel, ARG_stop_channel }; static const mp_arg_t allowed_args[] = { @@ -291,6 +293,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_scanning_networks_obj, 1, wif //| def stop_scanning_networks(self) -> None: //| """Stop scanning for Wifi networks and free any resources used to do it.""" //| ... +//| static mp_obj_t wifi_radio_stop_scanning_networks(mp_obj_t self_in) { wifi_radio_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -303,6 +306,7 @@ static MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_scanning_networks_obj, wifi_rad //| def start_station(self) -> None: //| """Starts a Station.""" //| ... +//| static mp_obj_t wifi_radio_start_station(mp_obj_t self) { common_hal_wifi_radio_start_station(self); return mp_const_none; @@ -312,6 +316,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_start_station_obj, wifi_radio_start_station //| def stop_station(self) -> None: //| """Stops the Station.""" //| ... +//| static mp_obj_t wifi_radio_stop_station(mp_obj_t self) { common_hal_wifi_radio_stop_station(self); return mp_const_none; @@ -320,8 +325,8 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_station_obj, wifi_radio_stop_station); //| def start_ap( //| self, -//| ssid: Union[str | ReadableBuffer], -//| password: Union[str | ReadableBuffer] = b"", +//| ssid: Union[str, ReadableBuffer], +//| password: Union[str, ReadableBuffer] = b"", //| *, //| channel: int = 1, //| authmode: Iterable[AuthMode] = (), @@ -355,6 +360,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_station_obj, wifi_radio_stop_station); //| In the raspberrypi port (RP2040 CYW43), ``max_connections`` is ignored. //| """ //| ... +//| static mp_obj_t wifi_radio_start_ap(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ssid, ARG_password, ARG_channel, ARG_authmode, ARG_max_connections }; static const mp_arg_t allowed_args[] = { @@ -412,6 +418,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_ap_obj, 1, wifi_radio_start_a //| def stop_ap(self) -> None: //| """Stops the access point.""" //| ... +//| static mp_obj_t wifi_radio_stop_ap(mp_obj_t self) { common_hal_wifi_radio_stop_ap(self); return mp_const_none; @@ -420,6 +427,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_ap_obj, wifi_radio_stop_ap); //| ap_active: bool //| """True if running as an access point. (read-only)""" +//| static mp_obj_t wifi_radio_get_ap_active(mp_obj_t self) { return mp_obj_new_bool(common_hal_wifi_radio_get_ap_active(self)); } @@ -430,11 +438,11 @@ MP_PROPERTY_GETTER(wifi_radio_ap_active_obj, //| def connect( //| self, -//| ssid: Union[str | ReadableBuffer], -//| password: Union[str | ReadableBuffer] = b"", +//| ssid: Union[str, ReadableBuffer], +//| password: Union[str, ReadableBuffer] = b"", //| *, //| channel: int = 0, -//| bssid: Optional[Union[str | ReadableBuffer]] = None, +//| bssid: Optional[Union[str, ReadableBuffer]] = None, //| timeout: Optional[float] = None, //| ) -> None: //| """Connects to the given ssid and waits for an ip address. Reconnections are handled @@ -453,6 +461,7 @@ MP_PROPERTY_GETTER(wifi_radio_ap_active_obj, //| If ``bssid`` is given and not None, the scan will start at the first channel or the one given and //| connect to the AP with the given ``bssid`` and ``ssid``.""" //| ... +//| static mp_obj_t wifi_radio_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ssid, ARG_password, ARG_channel, ARG_bssid, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -556,6 +565,7 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_subnet_obj, //| ipv4_subnet_ap: Optional[ipaddress.IPv4Address] //| """IP v4 Address of the access point subnet, when enabled. None otherwise. (read-only)""" +//| static mp_obj_t wifi_radio_get_ipv4_subnet_ap(mp_obj_t self) { return common_hal_wifi_radio_get_ipv4_subnet_ap(self); } @@ -580,6 +590,7 @@ MP_PROPERTY_GETTER(wifi_radio_ipv4_subnet_ap_obj, //| In the raspberrypi port (RP2040 CYW43), the access point needs to be started before the IP v4 address can be set. //| """ //| ... +//| static mp_obj_t wifi_radio_set_ipv4_address(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ipv4, ARG_netmask, ARG_gateway, ARG_ipv4_dns }; static const mp_arg_t allowed_args[] = { @@ -607,6 +618,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_set_ipv4_address_obj, 1, wifi_radio //| ) -> None: //| """Sets the IP v4 address of the access point. Must include the netmask and gateway.""" //| ... +//| static mp_obj_t wifi_radio_set_ipv4_address_ap(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ipv4, ARG_netmask, ARG_gateway }; static const mp_arg_t allowed_args[] = { @@ -712,6 +724,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_get_ap_info_obj, wifi_radio_get_ap_info); //| mac: bytearray (read-only) //| rssi: int (read-only, None on Raspberry Pi Pico W) //| ipv4_address: ipv4_address (read-only, None if station connected but no address assigned yet or self-assigned address)""" +//| static mp_obj_t wifi_radio_get_stations_ap(mp_obj_t self) { return common_hal_wifi_radio_get_stations_ap(self); } @@ -729,11 +742,12 @@ MP_PROPERTY_GETTER(wifi_radio_stations_ap_obj, //| then the corresponding DHCP client is stopped if it was active. //| """ //| ... +//| static mp_obj_t wifi_radio_start_dhcp_client(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ipv4, ARG_ipv6 }; static const mp_arg_t allowed_args[] = { - { MP_QSTR_ipv4, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = MP_ROM_TRUE } }, - { MP_QSTR_ipv6, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = MP_ROM_FALSE } }, + { MP_QSTR_ipv4, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = true } }, + { MP_QSTR_ipv6, MP_ARG_KW_ONLY | MP_ARG_BOOL, { .u_bool = false } }, }; wifi_radio_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); @@ -748,6 +762,7 @@ static MP_DEFINE_CONST_FUN_OBJ_KW(wifi_radio_start_dhcp_client_obj, 1, wifi_radi //| def stop_dhcp(self) -> None: //| """Stops the station DHCP client. Needed to assign a static IP address.""" //| ... +//| static mp_obj_t wifi_radio_stop_dhcp_client(mp_obj_t self) { common_hal_wifi_radio_stop_dhcp_client(self); return mp_const_none; @@ -757,6 +772,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_stop_dhcp_client_obj, wifi_radio_stop_dhcp_ //| def start_dhcp_ap(self) -> None: //| """Starts the access point DHCP server.""" //| ... +//| static mp_obj_t wifi_radio_start_dhcp_server(mp_obj_t self) { common_hal_wifi_radio_start_dhcp_server(self); return mp_const_none; @@ -766,6 +782,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(wifi_radio_start_dhcp_server_obj, wifi_radio_start_dhc //| def stop_dhcp_ap(self) -> None: //| """Stops the access point DHCP server. Needed to assign a static IP address.""" //| ... +//| static mp_obj_t wifi_radio_stop_dhcp_server(mp_obj_t self) { common_hal_wifi_radio_stop_dhcp_server(self); return mp_const_none; @@ -787,6 +804,7 @@ MP_PROPERTY_GETTER(wifi_radio_ap_info_obj, //| """ //| ... //| +//| static mp_obj_t wifi_radio_ping(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_ip, ARG_timeout }; static const mp_arg_t allowed_args[] = { @@ -849,6 +867,7 @@ static const mp_rom_map_elem_t wifi_radio_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_ipv4_subnet_ap), MP_ROM_PTR(&wifi_radio_ipv4_subnet_ap_obj) }, { MP_ROM_QSTR(MP_QSTR_ipv4_address), MP_ROM_PTR(&wifi_radio_ipv4_address_obj) }, { MP_ROM_QSTR(MP_QSTR_ipv4_address_ap), MP_ROM_PTR(&wifi_radio_ipv4_address_ap_obj) }, + { MP_ROM_QSTR(MP_QSTR_power_management), MP_ROM_PTR(&wifi_radio_power_management_obj) }, { MP_ROM_QSTR(MP_QSTR_set_ipv4_address), MP_ROM_PTR(&wifi_radio_set_ipv4_address_obj) }, { MP_ROM_QSTR(MP_QSTR_set_ipv4_address_ap), MP_ROM_PTR(&wifi_radio_set_ipv4_address_ap_obj) }, diff --git a/shared-bindings/wifi/Radio.h b/shared-bindings/wifi/Radio.h index ac352626dcc..d3c12344b87 100644 --- a/shared-bindings/wifi/Radio.h +++ b/shared-bindings/wifi/Radio.h @@ -8,6 +8,8 @@ #include +#include "shared-bindings/wifi/PowerManagement.h" + #include "common-hal/wifi/Radio.h" #include "py/objstr.h" @@ -75,8 +77,8 @@ extern void common_hal_wifi_radio_set_mac_address_ap(wifi_radio_obj_t *self, con extern mp_float_t common_hal_wifi_radio_get_tx_power(wifi_radio_obj_t *self); extern void common_hal_wifi_radio_set_tx_power(wifi_radio_obj_t *self, const mp_float_t power); -extern void common_hal_wifi_radio_set_listen_interval(wifi_radio_obj_t *self, const mp_int_t listen_interval); -extern mp_int_t common_hal_wifi_radio_get_listen_interval(wifi_radio_obj_t *self); +extern wifi_power_management_t common_hal_wifi_radio_get_power_management(wifi_radio_obj_t *self); +extern void common_hal_wifi_radio_set_power_management(wifi_radio_obj_t *self, wifi_power_management_t power_management); extern mp_obj_t common_hal_wifi_radio_start_scanning_networks(wifi_radio_obj_t *self, uint8_t start_channel, uint8_t stop_channel); extern void common_hal_wifi_radio_stop_scanning_networks(wifi_radio_obj_t *self); diff --git a/shared-bindings/wifi/ScannedNetworks.c b/shared-bindings/wifi/ScannedNetworks.c index dea3474d423..2fb5c2a5787 100644 --- a/shared-bindings/wifi/ScannedNetworks.c +++ b/shared-bindings/wifi/ScannedNetworks.c @@ -40,6 +40,7 @@ static mp_obj_t scannednetworks_iternext(mp_obj_t self_in) { //| Raises `StopIteration` if scanning is finished and no other results are available.""" //| ... //| +//| MP_DEFINE_CONST_OBJ_TYPE( wifi_scannednetworks_type, diff --git a/shared-bindings/wifi/__init__.c b/shared-bindings/wifi/__init__.c index 3b09255052e..2a1c0097080 100644 --- a/shared-bindings/wifi/__init__.c +++ b/shared-bindings/wifi/__init__.c @@ -15,6 +15,7 @@ //| The `wifi` module provides necessary low-level functionality for managing //| wifi connections. Use `socketpool` for communicating over the network. //| """ +//| //| radio: Radio //| """Wifi radio used to manage both station and AP modes. @@ -29,21 +30,22 @@ static MP_DEFINE_CONST_FUN_OBJ_0(wifi___init___obj, wifi___init__); static const mp_rom_map_elem_t wifi_module_globals_table[] = { // Name - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wifi) }, + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_wifi) }, // Initialization - { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&wifi___init___obj) }, + { MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&wifi___init___obj) }, // Classes - { MP_ROM_QSTR(MP_QSTR_AuthMode), MP_ROM_PTR(&wifi_authmode_type) }, - { MP_ROM_QSTR(MP_QSTR_Monitor), MP_ROM_PTR(&wifi_monitor_type) }, - { MP_ROM_QSTR(MP_QSTR_Network), MP_ROM_PTR(&wifi_network_type) }, - { MP_ROM_QSTR(MP_QSTR_Packet), MP_ROM_PTR(&wifi_packet_type) }, - { MP_ROM_QSTR(MP_QSTR_Radio), MP_ROM_PTR(&wifi_radio_type) }, - { MP_ROM_QSTR(MP_QSTR_Station), MP_ROM_PTR(&wifi_radio_station_type) }, + { MP_ROM_QSTR(MP_QSTR_AuthMode), MP_ROM_PTR(&wifi_authmode_type) }, + { MP_ROM_QSTR(MP_QSTR_Monitor), MP_ROM_PTR(&wifi_monitor_type) }, + { MP_ROM_QSTR(MP_QSTR_Network), MP_ROM_PTR(&wifi_network_type) }, + { MP_ROM_QSTR(MP_QSTR_Packet), MP_ROM_PTR(&wifi_packet_type) }, + { MP_ROM_QSTR(MP_QSTR_PowerManagement), MP_ROM_PTR(&wifi_power_management_type) }, + { MP_ROM_QSTR(MP_QSTR_Radio), MP_ROM_PTR(&wifi_radio_type) }, + { MP_ROM_QSTR(MP_QSTR_Station), MP_ROM_PTR(&wifi_radio_station_type) }, // Properties - { MP_ROM_QSTR(MP_QSTR_radio), MP_ROM_PTR(&common_hal_wifi_radio_obj) }, + { MP_ROM_QSTR(MP_QSTR_radio), MP_ROM_PTR(&common_hal_wifi_radio_obj) }, }; static MP_DEFINE_CONST_DICT(wifi_module_globals, wifi_module_globals_table); diff --git a/shared-bindings/zlib/__init__.c b/shared-bindings/zlib/__init__.c index f9db723c4fc..a17694d8a2e 100644 --- a/shared-bindings/zlib/__init__.c +++ b/shared-bindings/zlib/__init__.c @@ -25,6 +25,7 @@ //| This module allows to decompress binary data compressed with DEFLATE algorithm //| (commonly used in zlib library and gzip archiver). Compression is not yet implemented.""" //| +//| //| def decompress(data: bytes, wbits: Optional[int] = 0, bufsize: Optional[int] = 0) -> bytes: //| """Return decompressed *data* as bytes. *wbits* is DEFLATE dictionary window @@ -48,6 +49,7 @@ //| """ //| ... //| +//| static mp_obj_t zlib_decompress(size_t n_args, const mp_obj_t *args) { mp_int_t wbits = 0; if (n_args > 1) { diff --git a/shared-module/_eve/__init__.c b/shared-module/_eve/__init__.c index ecd310b55a3..ca084d9b43b 100644 --- a/shared-module/_eve/__init__.c +++ b/shared-module/_eve/__init__.c @@ -246,6 +246,11 @@ void common_hal__eve_PointSize(common_hal__eve_t *eve, mp_float_t size) { } +void common_hal__eve_Region(common_hal__eve_t *eve, uint32_t y, uint32_t h, uint32_t dest) { + C4(eve, ((52 << 24) | ((y & 0x3f) << 18) | ((h & 0x3f) << 12) | (dest & 0xfff))); +} + + void common_hal__eve_RestoreContext(common_hal__eve_t *eve) { C4(eve, ((35 << 24))); } diff --git a/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c b/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c index 0795e29f382..e01875452b1 100644 --- a/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c +++ b/shared-module/adafruit_bus_device/i2c_device/I2CDevice.c @@ -41,30 +41,14 @@ void common_hal_adafruit_bus_device_i2cdevice_unlock(adafruit_bus_device_i2cdevi void common_hal_adafruit_bus_device_i2cdevice_probe_for_device(adafruit_bus_device_i2cdevice_obj_t *self) { common_hal_adafruit_bus_device_i2cdevice_lock(self); - mp_buffer_info_t write_bufinfo; - mp_obj_t write_buffer = mp_obj_new_bytearray_of_zeros(0); - mp_get_buffer_raise(write_buffer, &write_bufinfo, MP_BUFFER_READ); + mp_obj_t dest[3]; + mp_load_method(self->i2c, MP_QSTR_probe, dest); + dest[2] = MP_OBJ_NEW_SMALL_INT(self->device_address); + const bool found = mp_obj_is_true(mp_call_method_n_kw(1, 0, dest)); - mp_obj_t dest[4]; - - /* catch exceptions that may be thrown while probing for the device */ - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_load_method(self->i2c, MP_QSTR_writeto, dest); - dest[2] = MP_OBJ_NEW_SMALL_INT(self->device_address); - dest[3] = write_buffer; - mp_call_method_n_kw(2, 0, dest); - nlr_pop(); - } else { - common_hal_adafruit_bus_device_i2cdevice_unlock(self); + common_hal_adafruit_bus_device_i2cdevice_unlock(self); - if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_OSError))) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("No I2C device at address: 0x%x"), self->device_address); - } else { - /* In case we receive an unrelated exception pass it up */ - nlr_raise(MP_OBJ_FROM_PTR(nlr.ret_val)); - } + if (!found) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("No I2C device at address: 0x%x"), self->device_address); } - - common_hal_adafruit_bus_device_i2cdevice_unlock(self); } diff --git a/shared-module/adafruit_pixelbuf/PixelBuf.c b/shared-module/adafruit_pixelbuf/PixelBuf.c index 0eb1afe9adb..155862f17a3 100644 --- a/shared-module/adafruit_pixelbuf/PixelBuf.c +++ b/shared-module/adafruit_pixelbuf/PixelBuf.c @@ -30,13 +30,10 @@ void common_hal_adafruit_pixelbuf_pixelbuf_construct(pixelbuf_pixelbuf_obj_t *se self->auto_write = false; size_t pixel_len = self->pixel_count * self->bytes_per_pixel; - self->transmit_buffer_obj = mp_obj_new_bytes_of_zeros(header_len + pixel_len + trailer_len); - mp_obj_str_t *o = MP_OBJ_TO_PTR(self->transmit_buffer_obj); + self->transmit_buffer_obj = mp_obj_new_bytearray_of_zeros(header_len + pixel_len + trailer_len); + mp_obj_array_t *o = MP_OBJ_TO_PTR(self->transmit_buffer_obj); - // Abuse the bytes object a bit by mutating it's data by dropping the const. If the user's - // Python code holds onto it, they'll find out that it changes. At least this way it isn't - // mutable by the code itself. - uint8_t *transmit_buffer = (uint8_t *)o->data; + uint8_t *transmit_buffer = o->items; memcpy(transmit_buffer, header, header_len); memcpy(transmit_buffer + header_len + pixel_len, trailer, trailer_len); self->post_brightness_buffer = transmit_buffer + header_len; @@ -103,7 +100,7 @@ void common_hal_adafruit_pixelbuf_pixelbuf_set_brightness(mp_obj_t self_in, mp_f return; } else { if (self->pre_brightness_buffer == NULL) { - self->pre_brightness_buffer = m_malloc(pixel_len); + self->pre_brightness_buffer = m_malloc_without_collect(pixel_len); memcpy(self->pre_brightness_buffer, self->post_brightness_buffer, pixel_len); } for (size_t i = 0; i < pixel_len; i++) { diff --git a/shared-module/atexit/__init__.c b/shared-module/atexit/__init__.c index ff369e83c77..537a2a9d969 100644 --- a/shared-module/atexit/__init__.c +++ b/shared-module/atexit/__init__.c @@ -12,8 +12,13 @@ static size_t callback_len = 0; static atexit_callback_t *callback = NULL; void atexit_reset(void) { - callback_len = 0; + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(callback, callback_len * sizeof(atexit_callback_t)); + #else m_free(callback); + #endif + + callback_len = 0; callback = NULL; } @@ -23,14 +28,14 @@ void atexit_gc_collect(void) { void shared_module_atexit_register(mp_obj_t *func, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { if (!mp_obj_is_callable(func)) { - mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object is not callable"), mp_obj_get_type_qstr(func)); + mp_raise_TypeError_varg(MP_ERROR_TEXT("'%q' object isn't callable"), mp_obj_get_type_qstr(func)); } size_t n_kw_args = (kw_args) ? kw_args->used : 0; atexit_callback_t cb = { .n_pos = 0, .n_kw = 0, .func = func, - .args = (n_args + n_kw_args) ? m_malloc((n_args + (n_kw_args * 2)) * sizeof(mp_obj_t)) : NULL + .args = (n_args + n_kw_args) ? m_malloc_items(n_args + (n_kw_args * 2)) : NULL }; for (; cb.n_pos < n_args; cb.n_pos++) { cb.args[cb.n_pos] = pos_args[cb.n_pos]; @@ -39,7 +44,13 @@ void shared_module_atexit_register(mp_obj_t *func, size_t n_args, const mp_obj_t cb.args[i] = kw_args->table[cb.n_kw].key; cb.args[i += 1] = kw_args->table[cb.n_kw].value; } - callback = (atexit_callback_t *)m_realloc(callback, (callback_len + 1) * sizeof(cb)); + + callback = (atexit_callback_t *)m_realloc(callback, + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + callback_len *sizeof(cb), // Old size + #endif + (callback_len + 1) * sizeof(cb)); + callback[callback_len++] = cb; } diff --git a/shared-module/audiocore/RawSample.c b/shared-module/audiocore/RawSample.c index 9944597d08f..900b42c3c3e 100644 --- a/shared-module/audiocore/RawSample.c +++ b/shared-module/audiocore/RawSample.c @@ -7,6 +7,7 @@ // SPDX-License-Identifier: MIT #include "shared-bindings/audiocore/RawSample.h" +#include "shared-bindings/audiocore/__init__.h" #include @@ -22,34 +23,18 @@ void common_hal_audioio_rawsample_construct(audioio_rawsample_obj_t *self, bool single_buffer) { self->buffer = buffer; - self->bits_per_sample = bytes_per_sample * 8; - self->samples_signed = samples_signed; - self->len = len; - self->channel_count = channel_count; - self->sample_rate = sample_rate; - self->single_buffer = single_buffer; + self->base.bits_per_sample = bytes_per_sample * 8; + self->base.samples_signed = samples_signed; + self->base.max_buffer_length = len; + self->base.channel_count = channel_count; + self->base.sample_rate = sample_rate; + self->base.single_buffer = single_buffer; self->buffer_index = 0; } void common_hal_audioio_rawsample_deinit(audioio_rawsample_obj_t *self) { self->buffer = NULL; -} -bool common_hal_audioio_rawsample_deinited(audioio_rawsample_obj_t *self) { - return self->buffer == NULL; -} - -uint32_t common_hal_audioio_rawsample_get_sample_rate(audioio_rawsample_obj_t *self) { - return self->sample_rate; -} -void common_hal_audioio_rawsample_set_sample_rate(audioio_rawsample_obj_t *self, - uint32_t sample_rate) { - self->sample_rate = sample_rate; -} -uint8_t common_hal_audioio_rawsample_get_bits_per_sample(audioio_rawsample_obj_t *self) { - return self->bits_per_sample; -} -uint8_t common_hal_audioio_rawsample_get_channel_count(audioio_rawsample_obj_t *self) { - return self->channel_count; + audiosample_mark_deinit(&self->base); } void audioio_rawsample_reset_buffer(audioio_rawsample_obj_t *self, @@ -63,37 +48,23 @@ audioio_get_buffer_result_t audioio_rawsample_get_buffer(audioio_rawsample_obj_t uint8_t **buffer, uint32_t *buffer_length) { - if (self->single_buffer) { - *buffer_length = self->len; + if (self->base.single_buffer) { + *buffer_length = self->base.max_buffer_length; if (single_channel_output) { - *buffer = self->buffer + (channel % self->channel_count) * (self->bits_per_sample / 8); + *buffer = self->buffer + (channel % self->base.channel_count) * (self->base.bits_per_sample / 8); } else { *buffer = self->buffer; } return GET_BUFFER_DONE; } else { - *buffer_length = self->len / 2; + *buffer_length = self->base.max_buffer_length / 2; if (single_channel_output) { - *buffer = self->buffer + (channel % self->channel_count) * (self->bits_per_sample / 8) + \ - self->len / 2 * self->buffer_index; + *buffer = self->buffer + (channel % self->base.channel_count) * (self->base.bits_per_sample / 8) + \ + self->base.max_buffer_length / 2 * self->buffer_index; } else { - *buffer = self->buffer + self->len / 2 * self->buffer_index; + *buffer = self->buffer + self->base.max_buffer_length / 2 * self->buffer_index; } self->buffer_index = 1 - self->buffer_index; return GET_BUFFER_DONE; } } - -void audioio_rawsample_get_buffer_structure(audioio_rawsample_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing) { - - *single_buffer = self->single_buffer; - *samples_signed = self->samples_signed; - *max_buffer_length = self->len; - if (single_channel_output) { - *spacing = self->channel_count; - } else { - *spacing = 1; - } -} diff --git a/shared-module/audiocore/RawSample.h b/shared-module/audiocore/RawSample.h index 3fa94404f1c..1489bc3f504 100644 --- a/shared-module/audiocore/RawSample.h +++ b/shared-module/audiocore/RawSample.h @@ -11,14 +11,8 @@ #include "shared-module/audiocore/__init__.h" typedef struct { - mp_obj_base_t base; + audiosample_base_t base; uint8_t *buffer; - uint32_t len; - uint8_t bits_per_sample; - bool samples_signed; - uint8_t channel_count; - uint32_t sample_rate; - bool single_buffer; uint8_t buffer_index; } audioio_rawsample_obj_t; @@ -32,6 +26,3 @@ audioio_get_buffer_result_t audioio_rawsample_get_buffer(audioio_rawsample_obj_t uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); // length in bytes -void audioio_rawsample_get_buffer_structure(audioio_rawsample_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing); diff --git a/shared-module/audiocore/WaveFile.c b/shared-module/audiocore/WaveFile.c index 50f56303e95..77ca2445edb 100644 --- a/shared-module/audiocore/WaveFile.c +++ b/shared-module/audiocore/WaveFile.c @@ -13,6 +13,7 @@ #include "py/runtime.h" #include "shared-module/audiocore/WaveFile.h" +#include "shared-bindings/audiocore/__init__.h" struct wave_format_chunk { uint16_t audio_format; @@ -21,7 +22,11 @@ struct wave_format_chunk { uint32_t byte_rate; uint16_t block_align; uint16_t bits_per_sample; - uint16_t extra_params; // Assumed to be zero below. + uint16_t extra_params; + uint16_t valid_bits_per_sample; + uint32_t channel_mask; + uint16_t extended_audio_format; + uint8_t extended_guid[14]; }; void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t *self, @@ -56,37 +61,54 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t *self, if (bytes_read != format_size) { } - if (format.audio_format != 1 || + if ((format_size != 40 && format.audio_format != 1) || format.num_channels > 2 || format.bits_per_sample > 16 || - (format_size == 18 && - format.extra_params != 0)) { - mp_raise_ValueError(MP_ERROR_TEXT("Unsupported format")); + (format_size == 18 && format.extra_params != 0) || + (format_size == 40 && + (format.audio_format != 0xfffe || + format.extended_audio_format != 1 || + format.valid_bits_per_sample != format.bits_per_sample))) { + mp_raise_ValueError(MP_ERROR_TEXT("Format not supported")); } // Get the sample_rate - self->sample_rate = format.sample_rate; - self->channel_count = format.num_channels; - self->bits_per_sample = format.bits_per_sample; + self->base.sample_rate = format.sample_rate; + self->base.channel_count = format.num_channels; + self->base.bits_per_sample = format.bits_per_sample; + self->base.samples_signed = format.bits_per_sample > 8; + self->base.max_buffer_length = 512; + self->base.single_buffer = false; + + uint8_t chunk_tag[4]; + uint32_t chunk_length; + bool found_data_chunk = false; + + while (!found_data_chunk) { + if (f_read(&self->file->fp, &chunk_tag, 4, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 4) { + mp_raise_OSError(MP_EIO); + } + if (memcmp((uint8_t *)chunk_tag, "data", 4) == 0) { + found_data_chunk = true; + } - // TODO(tannewt): Skip any extra chunks that occur before the data section. + if (f_read(&self->file->fp, &chunk_length, 4, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + if (bytes_read != 4) { + mp_raise_OSError(MP_EIO); + } - uint8_t data_tag[4]; - if (f_read(&self->file->fp, &data_tag, 4, &bytes_read) != FR_OK) { - mp_raise_OSError(MP_EIO); - } - if (bytes_read != 4 || - memcmp((uint8_t *)data_tag, "data", 4) != 0) { - mp_raise_ValueError(MP_ERROR_TEXT("Data chunk must follow fmt chunk")); + if (!found_data_chunk) { + if (f_lseek(&self->file->fp, f_tell(&self->file->fp) + chunk_length) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + } } - uint32_t data_length; - if (f_read(&self->file->fp, &data_length, 4, &bytes_read) != FR_OK) { - mp_raise_OSError(MP_EIO); - } - if (bytes_read != 4) { - mp_arg_error_invalid(MP_QSTR_file); - } - self->file_length = data_length; + self->file_length = chunk_length; self->data_start = self->file->fp.fptr; // Try to allocate two buffers, one will be loaded from file and the other @@ -97,13 +119,13 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t *self, self->second_buffer = buffer + self->len; } else { self->len = 256; - self->buffer = m_malloc(self->len); + self->buffer = m_malloc_without_collect(self->len); if (self->buffer == NULL) { common_hal_audioio_wavefile_deinit(self); m_malloc_fail(self->len); } - self->second_buffer = m_malloc(self->len); + self->second_buffer = m_malloc_without_collect(self->len); if (self->second_buffer == NULL) { common_hal_audioio_wavefile_deinit(self); m_malloc_fail(self->len); @@ -114,27 +136,7 @@ void common_hal_audioio_wavefile_construct(audioio_wavefile_obj_t *self, void common_hal_audioio_wavefile_deinit(audioio_wavefile_obj_t *self) { self->buffer = NULL; self->second_buffer = NULL; -} - -bool common_hal_audioio_wavefile_deinited(audioio_wavefile_obj_t *self) { - return self->buffer == NULL; -} - -uint32_t common_hal_audioio_wavefile_get_sample_rate(audioio_wavefile_obj_t *self) { - return self->sample_rate; -} - -void common_hal_audioio_wavefile_set_sample_rate(audioio_wavefile_obj_t *self, - uint32_t sample_rate) { - self->sample_rate = sample_rate; -} - -uint8_t common_hal_audioio_wavefile_get_bits_per_sample(audioio_wavefile_obj_t *self) { - return self->bits_per_sample; -} - -uint8_t common_hal_audioio_wavefile_get_channel_count(audioio_wavefile_obj_t *self) { - return self->channel_count; + audiosample_mark_deinit(&self->base); } void audioio_wavefile_reset_buffer(audioio_wavefile_obj_t *self, @@ -193,11 +195,11 @@ audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t * if (self->bytes_remaining == 0 && length_read % sizeof(uint32_t) != 0) { uint32_t pad = length_read % sizeof(uint32_t); length_read += pad; - if (self->bits_per_sample == 8) { + if (self->base.bits_per_sample == 8) { for (uint32_t i = 0; i < pad; i++) { ((uint8_t *)(*buffer))[length_read / sizeof(uint8_t) - i - 1] = 0x80; } - } else if (self->bits_per_sample == 16) { + } else if (self->base.bits_per_sample == 16) { // We know the buffer is aligned because we allocated it onto the heap ourselves. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align" @@ -228,22 +230,8 @@ audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t * self->left_read_count += 1; } else if (channel == 1) { self->right_read_count += 1; - *buffer = *buffer + self->bits_per_sample / 8; + *buffer = *buffer + self->base.bits_per_sample / 8; } return self->bytes_remaining == 0 ? GET_BUFFER_DONE : GET_BUFFER_MORE_DATA; } - -void audioio_wavefile_get_buffer_structure(audioio_wavefile_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing) { - *single_buffer = false; - // In WAV files, 8-bit samples are always unsigned, and larger samples are always signed. - *samples_signed = self->bits_per_sample > 8; - *max_buffer_length = 512; - if (single_channel_output) { - *spacing = self->channel_count; - } else { - *spacing = 1; - } -} diff --git a/shared-module/audiocore/WaveFile.h b/shared-module/audiocore/WaveFile.h index a86c1409abc..74e25ffebfe 100644 --- a/shared-module/audiocore/WaveFile.h +++ b/shared-module/audiocore/WaveFile.h @@ -12,20 +12,16 @@ #include "shared-module/audiocore/__init__.h" typedef struct { - mp_obj_base_t base; + audiosample_base_t base; uint8_t *buffer; uint32_t buffer_length; uint8_t *second_buffer; uint32_t second_buffer_length; uint32_t file_length; // In bytes uint16_t data_start; // Where the data values start - uint8_t bits_per_sample; uint16_t buffer_index; uint32_t bytes_remaining; - uint8_t channel_count; - uint32_t sample_rate; - uint32_t len; pyb_file_obj_t *file; @@ -43,6 +39,3 @@ audioio_get_buffer_result_t audioio_wavefile_get_buffer(audioio_wavefile_obj_t * uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); // length in bytes -void audioio_wavefile_get_buffer_structure(audioio_wavefile_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing); diff --git a/shared-module/audiocore/__init__.c b/shared-module/audiocore/__init__.c index ff3c9652807..9cd561208f3 100644 --- a/shared-module/audiocore/__init__.c +++ b/shared-module/audiocore/__init__.c @@ -7,31 +7,25 @@ #include "shared-module/audioio/__init__.h" #include "py/obj.h" +#include "py/runtime.h" +#include "shared-bindings/audiocore/__init__.h" #include "shared-bindings/audiocore/RawSample.h" #include "shared-bindings/audiocore/WaveFile.h" #include "shared-module/audiocore/RawSample.h" #include "shared-module/audiocore/WaveFile.h" +#if CIRCUITPY_AUDIOSPEED +#include "shared-bindings/audiospeed/Resampler.h" +#endif + #include "shared-bindings/audiomixer/Mixer.h" #include "shared-module/audiomixer/Mixer.h" -uint32_t audiosample_sample_rate(mp_obj_t sample_obj) { - const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj); - return proto->sample_rate(MP_OBJ_TO_PTR(sample_obj)); -} - -uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj) { - const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj); - return proto->bits_per_sample(MP_OBJ_TO_PTR(sample_obj)); -} - -uint8_t audiosample_channel_count(mp_obj_t sample_obj) { - const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj); - return proto->channel_count(MP_OBJ_TO_PTR(sample_obj)); -} - void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel_output, uint8_t audio_channel) { const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj); + if (audiosample_deinited(audiosample_cast_obj(sample_obj))) { + return; + } proto->reset_buffer(MP_OBJ_TO_PTR(sample_obj), single_channel_output, audio_channel); } @@ -40,17 +34,14 @@ audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj); + if (audiosample_deinited(audiosample_cast_obj(sample_obj))) { + *buffer = NULL; + *buffer_length = 0; + return GET_BUFFER_ERROR; + } return proto->get_buffer(MP_OBJ_TO_PTR(sample_obj), single_channel_output, channel, buffer, buffer_length); } -void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing) { - const audiosample_p_t *proto = mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, sample_obj); - proto->get_buffer_structure(MP_OBJ_TO_PTR(sample_obj), single_channel_output, single_buffer, - samples_signed, max_buffer_length, spacing); -} - void audiosample_convert_u8m_s16s(int16_t *buffer_out, const uint8_t *buffer_in, size_t nframes) { for (; nframes--;) { int16_t sample = (*buffer_in++ - 0x80) << 8; @@ -59,7 +50,6 @@ void audiosample_convert_u8m_s16s(int16_t *buffer_out, const uint8_t *buffer_in, } } - void audiosample_convert_u8s_s16s(int16_t *buffer_out, const uint8_t *buffer_in, size_t nframes) { size_t nsamples = 2 * nframes; for (; nsamples--;) { @@ -76,7 +66,6 @@ void audiosample_convert_s8m_s16s(int16_t *buffer_out, const int8_t *buffer_in, } } - void audiosample_convert_s8s_s16s(int16_t *buffer_out, const int8_t *buffer_in, size_t nframes) { size_t nsamples = 2 * nframes; for (; nsamples--;) { @@ -85,7 +74,6 @@ void audiosample_convert_s8s_s16s(int16_t *buffer_out, const int8_t *buffer_in, } } - void audiosample_convert_u16m_s16s(int16_t *buffer_out, const uint16_t *buffer_in, size_t nframes) { for (; nframes--;) { int16_t sample = *buffer_in++ - 0x8000; @@ -94,7 +82,6 @@ void audiosample_convert_u16m_s16s(int16_t *buffer_out, const uint16_t *buffer_i } } - void audiosample_convert_u16s_s16s(int16_t *buffer_out, const uint16_t *buffer_in, size_t nframes) { size_t nsamples = 2 * nframes; for (; nsamples--;) { @@ -110,3 +97,142 @@ void audiosample_convert_s16m_s16s(int16_t *buffer_out, const int16_t *buffer_in *buffer_out++ = sample; } } + + +void audiosample_convert_u8s_u8m(uint8_t *buffer_out, const uint8_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = *buffer_in++ + 0x80; + *buffer_out++ = sample; + buffer_in++; + } +} + +void audiosample_convert_s8m_u8m(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = *buffer_in++ + 0x80; + *buffer_out++ = sample; + } +} + +void audiosample_convert_s8s_u8m(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = *buffer_in++ + 0x80; + *buffer_out++ = sample; + buffer_in++; + } +} + +void audiosample_convert_u16m_u8m(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = (*buffer_in++) >> 8; + *buffer_out++ = sample; + } +} + +void audiosample_convert_u16s_u8m(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = (*buffer_in++) >> 8; + *buffer_out++ = sample; + buffer_in++; + } +} + +void audiosample_convert_s16m_u8m(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = (*buffer_in++ + 0x8000) >> 8; + *buffer_out++ = sample; + } +} + +void audiosample_convert_s16s_u8m(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = (*buffer_in++ + 0x8000) >> 8; + *buffer_out++ = sample; + buffer_in++; + } +} + + +void audiosample_convert_u8m_u8s(uint8_t *buffer_out, const uint8_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = *buffer_in++; + *buffer_out++ = sample; + *buffer_out++ = sample; + } +} + +void audiosample_convert_s8m_u8s(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = *buffer_in++ + 0x80; + *buffer_out++ = sample; + *buffer_out++ = sample; + } +} + +void audiosample_convert_s8s_u8s(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes) { + size_t nsamples = 2 * nframes; + for (; nsamples--;) { + uint8_t sample = *buffer_in++ + 0x80; + *buffer_out++ = sample; + } +} + +void audiosample_convert_u16m_u8s(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = (*buffer_in++) >> 8; + *buffer_out++ = sample; + *buffer_out++ = sample; + } +} + +void audiosample_convert_u16s_u8s(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes) { + size_t nsamples = 2 * nframes; + for (; nsamples--;) { + uint8_t sample = (*buffer_in++) >> 8; + *buffer_out++ = sample; + } +} + +void audiosample_convert_s16m_u8s(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes) { + for (; nframes--;) { + uint8_t sample = (*buffer_in++ + 0x8000) >> 8; + *buffer_out++ = sample; + *buffer_out++ = sample; + } +} + +void audiosample_convert_s16s_u8s(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes) { + size_t nsamples = 2 * nframes; + for (; nsamples--;) { + uint8_t sample = (*buffer_in++ + 0x8000) >> 8; + *buffer_out++ = sample; + } +} + +void audiosample_must_match(audiosample_base_t *self, mp_obj_t other_in, bool allow_mono_to_stereo) { + const audiosample_base_t *other = audiosample_check(other_in); + audiosample_check_for_deinit(other); + #if !CIRCUITPY_AUDIOSPEED + if (other->sample_rate != self->sample_rate) { + #else + if (other->sample_rate != self->sample_rate && !mp_obj_is_type(other_in, &audiospeed_resampler_type)) { + #endif + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_sample_rate); + } + if ((!allow_mono_to_stereo || (allow_mono_to_stereo && self->channel_count != 2)) && other->channel_count != self->channel_count) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_channel_count); + } + if (other->bits_per_sample != self->bits_per_sample) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_bits_per_sample); + } + if (other->samples_signed != self->samples_signed) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_signedness); + } + + #if CIRCUITPY_AUDIOSPEED + if (mp_obj_is_type(other_in, &audiospeed_resampler_type)) { + audiospeed_resampler_obj_t *other_resampler = MP_OBJ_TO_PTR(other_in); + audiospeed_resampler_set_sample_rate(other_resampler, self->sample_rate); + } + #endif +} diff --git a/shared-module/audiocore/__init__.h b/shared-module/audiocore/__init__.h index 0e5b38d7b14..d135ee6c9e9 100644 --- a/shared-module/audiocore/__init__.h +++ b/shared-module/audiocore/__init__.h @@ -18,40 +18,78 @@ typedef enum { GET_BUFFER_ERROR, // Error while reading data. } audioio_get_buffer_result_t; -typedef uint32_t (*audiosample_sample_rate_fun)(mp_obj_t); -typedef uint8_t (*audiosample_bits_per_sample_fun)(mp_obj_t); -typedef uint8_t (*audiosample_channel_count_fun)(mp_obj_t); +typedef struct audiosample_base { + mp_obj_base_t self; + uint32_t sample_rate; + uint32_t max_buffer_length; + uint8_t bits_per_sample; + uint8_t channel_count; + uint8_t samples_signed; + bool single_buffer; +} audiosample_base_t; + typedef void (*audiosample_reset_buffer_fun)(mp_obj_t, bool single_channel_output, uint8_t audio_channel); typedef audioio_get_buffer_result_t (*audiosample_get_buffer_fun)(mp_obj_t, bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); -typedef void (*audiosample_get_buffer_structure_fun)(mp_obj_t, - bool single_channel_output, bool *single_buffer, - bool *samples_signed, uint32_t *max_buffer_length, - uint8_t *spacing); typedef struct _audiosample_p_t { MP_PROTOCOL_HEAD // MP_QSTR_protocol_audiosample - audiosample_sample_rate_fun sample_rate; - audiosample_bits_per_sample_fun bits_per_sample; - audiosample_channel_count_fun channel_count; audiosample_reset_buffer_fun reset_buffer; audiosample_get_buffer_fun get_buffer; - audiosample_get_buffer_structure_fun get_buffer_structure; } audiosample_p_t; -uint32_t audiosample_sample_rate(mp_obj_t sample_obj); -uint8_t audiosample_bits_per_sample(mp_obj_t sample_obj); -uint8_t audiosample_channel_count(mp_obj_t sample_obj); +static inline uint32_t audiosample_get_bits_per_sample(audiosample_base_t *self) { + return self->bits_per_sample; +} + +static inline uint32_t audiosample_get_sample_rate(audiosample_base_t *self) { + return self->sample_rate; +} + +static inline void audiosample_set_sample_rate(audiosample_base_t *self, uint32_t sample_rate) { + self->sample_rate = sample_rate; +} + +static inline uint8_t audiosample_get_channel_count(audiosample_base_t *self) { + return self->channel_count; +} + void audiosample_reset_buffer(mp_obj_t sample_obj, bool single_channel_output, uint8_t audio_channel); audioio_get_buffer_result_t audiosample_get_buffer(mp_obj_t sample_obj, bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); -void audiosample_get_buffer_structure(mp_obj_t sample_obj, bool single_channel_output, + +static inline void audiosample_get_buffer_structure(audiosample_base_t *self, bool single_channel_output, bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing); + uint32_t *max_buffer_length, uint8_t *spacing) { + + *single_buffer = self->single_buffer; + *samples_signed = self->samples_signed; + *max_buffer_length = self->max_buffer_length; + + if (single_channel_output) { + *spacing = self->channel_count; + } else { + *spacing = 1; + } +} + +static inline audiosample_base_t *audiosample_check(mp_obj_t self_in) { + // called for side effect + (void)mp_proto_get_or_throw(MP_QSTR_protocol_audiosample, self_in); + return MP_OBJ_TO_PTR(self_in); +} + +static inline void audiosample_get_buffer_structure_checked(mp_obj_t self_in, bool single_channel_output, + bool *single_buffer, bool *samples_signed, + uint32_t *max_buffer_length, uint8_t *spacing) { + audiosample_get_buffer_structure(audiosample_check(self_in), single_channel_output, single_buffer, samples_signed, max_buffer_length, spacing); +} + +void audiosample_must_match(audiosample_base_t *self, mp_obj_t other, bool allow_mono_to_stereo); void audiosample_convert_u8m_s16s(int16_t *buffer_out, const uint8_t *buffer_in, size_t nframes); void audiosample_convert_u8s_s16s(int16_t *buffer_out, const uint8_t *buffer_in, size_t nframes); @@ -60,3 +98,21 @@ void audiosample_convert_s8s_s16s(int16_t *buffer_out, const int8_t *buffer_in, void audiosample_convert_u16m_s16s(int16_t *buffer_out, const uint16_t *buffer_in, size_t nframes); void audiosample_convert_u16s_s16s(int16_t *buffer_out, const uint16_t *buffer_in, size_t nframes); void audiosample_convert_s16m_s16s(int16_t *buffer_out, const int16_t *buffer_in, size_t nframes); + +void audiosample_convert_u8s_u8m(uint8_t *buffer_out, const uint8_t *buffer_in, size_t nframes); +void audiosample_convert_s8m_u8m(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes); +void audiosample_convert_s8s_u8m(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes); +void audiosample_convert_u16m_u8m(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes); +void audiosample_convert_u16s_u8m(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes); +void audiosample_convert_s16m_u8m(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes); +void audiosample_convert_s16s_u8m(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes); + +void audiosample_convert_u8m_u8s(uint8_t *buffer_out, const uint8_t *buffer_in, size_t nframes); +void audiosample_convert_s8m_u8s(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes); +void audiosample_convert_s8s_u8s(uint8_t *buffer_out, const int8_t *buffer_in, size_t nframes); +void audiosample_convert_u16m_u8s(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes); +void audiosample_convert_u16s_u8s(uint8_t *buffer_out, const uint16_t *buffer_in, size_t nframes); +void audiosample_convert_s16m_u8s(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes); +void audiosample_convert_s16s_u8s(uint8_t *buffer_out, const int16_t *buffer_in, size_t nframes); + +#define audiosample_cast_obj(obj) ((audiosample_base_t *)MP_OBJ_TO_PTR(obj)) diff --git a/shared-module/audiodelays/Chorus.c b/shared-module/audiodelays/Chorus.c new file mode 100644 index 00000000000..f9dd627c375 --- /dev/null +++ b/shared-module/audiodelays/Chorus.c @@ -0,0 +1,346 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiodelays/Chorus.h" +#include "shared-bindings/audiocore/__init__.h" + +#include +#include +#include "py/runtime.h" + +void common_hal_audiodelays_chorus_construct(audiodelays_chorus_obj_t *self, uint32_t max_delay_ms, + mp_obj_t delay_ms, mp_obj_t voices, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiodelays_chorus_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiodelays_chorus_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the chorus effect's starting values. For a different effect this section will change + + // If we did not receive a BlockInput we need to create a default float value + if (voices == MP_OBJ_NULL) { + voices = mp_obj_new_float(MICROPY_FLOAT_CONST(1.0)); + } + synthio_block_assign_slot(voices, &self->voices, MP_QSTR_voices); + + if (delay_ms == MP_OBJ_NULL) { + delay_ms = mp_obj_new_float(MICROPY_FLOAT_CONST(50.0)); + } + synthio_block_assign_slot(delay_ms, &self->delay_ms, MP_QSTR_delay_ms); + + if (mix == MP_OBJ_NULL) { + mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + // Many effects may need buffers of what was played this shows how it was done for the chorus + // A maximum length buffer was created and then the current chorus length can be dynamically changes + // without having to reallocate a large chunk of memory. + + // Allocate the chorus buffer for the max possible delay, chorus is always 16-bit + self->max_delay_ms = max_delay_ms; + self->max_chorus_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * max_delay_ms * (self->base.channel_count * sizeof(uint16_t))); // bytes + self->chorus_buffer = m_malloc_without_collect(self->max_chorus_buffer_len); + if (self->chorus_buffer == NULL) { + common_hal_audiodelays_chorus_deinit(self); + m_malloc_fail(self->max_chorus_buffer_len); + } + memset(self->chorus_buffer, 0, self->max_chorus_buffer_len); + + // calculate the length of a single sample in milliseconds + self->sample_ms = MICROPY_FLOAT_CONST(1000.0) / self->base.sample_rate; + + // calculate everything needed for the current delay + mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms); + chorus_recalculate_delay(self, f_delay_ms); + + // where we are storing the next chorus sample + self->chorus_buffer_pos = 0; +} + +bool common_hal_audiodelays_chorus_deinited(audiodelays_chorus_obj_t *self) { + if (self->chorus_buffer == NULL) { + return true; + } + return false; +} + +void common_hal_audiodelays_chorus_deinit(audiodelays_chorus_obj_t *self) { + audiosample_mark_deinit(&self->base); + self->chorus_buffer = NULL; + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +mp_obj_t common_hal_audiodelays_chorus_get_delay_ms(audiodelays_chorus_obj_t *self) { + return self->delay_ms.obj; +} + +void common_hal_audiodelays_chorus_set_delay_ms(audiodelays_chorus_obj_t *self, mp_obj_t delay_ms) { + synthio_block_assign_slot(delay_ms, &self->delay_ms, MP_QSTR_delay_ms); + + mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms); + + chorus_recalculate_delay(self, f_delay_ms); +} + +void chorus_recalculate_delay(audiodelays_chorus_obj_t *self, mp_float_t f_delay_ms) { + // Require that delay is at least 1 sample long + f_delay_ms = MAX(f_delay_ms, self->sample_ms); + + // Calculate the current chorus buffer length in bytes + uint32_t new_chorus_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * f_delay_ms) * (self->base.channel_count * sizeof(uint16_t)); + + self->chorus_buffer_len = new_chorus_buffer_len; + + self->current_delay_ms = f_delay_ms; +} + +mp_obj_t common_hal_audiodelays_chorus_get_voices(audiodelays_chorus_obj_t *self) { + return self->voices.obj; +} + +void common_hal_audiodelays_chorus_set_voices(audiodelays_chorus_obj_t *self, mp_obj_t voices) { + synthio_block_assign_slot(voices, &self->voices, MP_QSTR_voices); +} + +void audiodelays_chorus_reset_buffer(audiodelays_chorus_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->chorus_buffer, 0, self->chorus_buffer_len); +} + +mp_obj_t common_hal_audiodelays_chorus_get_mix(audiodelays_chorus_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiodelays_chorus_set_mix(audiodelays_chorus_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +bool common_hal_audiodelays_chorus_get_playing(audiodelays_chorus_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiodelays_chorus_play(audiodelays_chorus_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiodelays_chorus_stop(audiodelays_chorus_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + // For chorus we clear the sample but the chorus continues until the object reading our effect stops + self->sample = NULL; + return; +} + +audioio_get_buffer_result_t audiodelays_chorus_get_buffer(audiodelays_chorus_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // The chorus buffer is always stored as a 16-bit value internally + int16_t *chorus_buffer = (int16_t *)self->chorus_buffer; + uint32_t chorus_buf_len = self->chorus_buffer_len / sizeof(uint16_t); + uint32_t max_chorus_buf_len = self->max_chorus_buffer_len / sizeof(uint16_t); + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it but we still need to play the chorus + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n; + if (self->sample == NULL) { + n = MIN(length, SYNTHIO_MAX_DUR * self->base.channel_count); + } else { + n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + + int32_t voices = (int32_t)MAX(synthio_block_slot_get(&self->voices), 1.0); + int32_t mix_down_scale = SYNTHIO_MIX_DOWN_SCALE(voices); + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + + mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms); + if (MICROPY_FLOAT_C_FUN(fabs)(self->current_delay_ms - f_delay_ms) >= self->sample_ms) { + chorus_recalculate_delay(self, f_delay_ms); + } + + if (self->sample == NULL) { + if (self->base.samples_signed) { + memset(word_buffer, 0, n * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + uint16_t *uword_buffer = (uint16_t *)word_buffer; + for (uint32_t i = 0; i < n; i++) { + *uword_buffer++ = 32768; + } + } else { + memset(hword_buffer, 128, n * (self->base.bits_per_sample / 8)); + } + } + } else { + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + for (uint32_t i = 0; i < n; i++) { + int32_t sample_word = 0; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + + chorus_buffer[self->chorus_buffer_pos++] = (int16_t)sample_word; + + int32_t word = 0; + if (voices == 1) { + word = sample_word; + } else { + int32_t step = chorus_buf_len / (voices - 1) - 1; + int32_t c_pos = self->chorus_buffer_pos - 1; + + for (int32_t v = 0; v < voices; v++) { + if (c_pos < 0) { + c_pos += max_chorus_buf_len; + } + word += chorus_buffer[c_pos]; + + c_pos -= step; + } + + // Dividing would get an average but does not sound as good + // Leaving this here in case someone wants to try an average instead + // word = word / voices; + + word = synthio_mix_down_sample(word, mix_down_scale); + } + + // Add original sample + effect + word = sample_word + (int32_t)(word * mix); + word = synthio_mix_down_sample(word, 2); + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + int8_t out = word; + if (self->base.samples_signed) { + hword_buffer[i] = out; + } else { + hword_buffer[i] = (uint8_t)out ^ 0x80; + } + } + + if (self->chorus_buffer_pos >= max_chorus_buf_len) { + self->chorus_buffer_pos = 0; + } + } + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // Chorus always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiodelays/Chorus.h b/shared-module/audiodelays/Chorus.h new file mode 100644 index 00000000000..c2602866ef7 --- /dev/null +++ b/shared-module/audiodelays/Chorus.h @@ -0,0 +1,53 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/synthio/block.h" + +extern const mp_obj_type_t audiodelays_chorus_type; + +typedef struct { + audiosample_base_t base; + uint32_t max_delay_ms; + synthio_block_slot_t delay_ms; + mp_float_t current_delay_ms; + mp_float_t sample_ms; + synthio_block_slot_t voices; + synthio_block_slot_t mix; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + int8_t *chorus_buffer; + uint32_t chorus_buffer_len; // bytes + uint32_t max_chorus_buffer_len; // bytes + + uint32_t chorus_buffer_pos; // words + + mp_obj_t sample; +} audiodelays_chorus_obj_t; + +void chorus_recalculate_delay(audiodelays_chorus_obj_t *self, mp_float_t f_delay_ms); + +void audiodelays_chorus_reset_buffer(audiodelays_chorus_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiodelays_chorus_get_buffer(audiodelays_chorus_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiodelays/Echo.c b/shared-module/audiodelays/Echo.c new file mode 100644 index 00000000000..a57ed237c48 --- /dev/null +++ b/shared-module/audiodelays/Echo.c @@ -0,0 +1,497 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus, Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiodelays/Echo.h" +#include "shared-bindings/audiocore/__init__.h" + +#include +#include "py/runtime.h" +#include + +void common_hal_audiodelays_echo_construct(audiodelays_echo_obj_t *self, uint32_t max_delay_ms, + mp_obj_t delay_ms, mp_obj_t decay, mp_obj_t filter, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate, bool freq_shift) { + + // Set whether the echo shifts frequencies as the delay changes like a doppler effect + self->freq_shift = freq_shift; + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiodelays_echo_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiodelays_echo_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the echo effect's starting values. For a different effect this section will change + + common_hal_audiodelays_echo_set_filter(self, filter); + + // If we did not receive a BlockInput we need to create a default float value + if (decay == MP_OBJ_NULL) { + decay = mp_obj_new_float(MICROPY_FLOAT_CONST(0.7)); + } + synthio_block_assign_slot(decay, &self->decay, MP_QSTR_decay); + + if (delay_ms == MP_OBJ_NULL) { + delay_ms = mp_obj_new_float(MICROPY_FLOAT_CONST(250.0)); + } + synthio_block_assign_slot(delay_ms, &self->delay_ms, MP_QSTR_delay_ms); + + if (mix == MP_OBJ_NULL) { + mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.25)); + } + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + // Many effects may need buffers of what was played this shows how it was done for the echo + // A maximum length buffer was created and then the current echo length can be dynamically changes + // without having to reallocate a large chunk of memory. + + // Allocate the echo buffer for the max possible delay, echo is always 16-bit + self->max_delay_ms = max_delay_ms; + self->max_echo_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * max_delay_ms) * (self->base.channel_count * sizeof(uint16_t)); // bytes + self->echo_buffer = m_malloc_without_collect(self->max_echo_buffer_len); + if (self->echo_buffer == NULL) { + common_hal_audiodelays_echo_deinit(self); + m_malloc_fail(self->max_echo_buffer_len); + } + memset(self->echo_buffer, 0, self->max_echo_buffer_len); + + // calculate the length of a single sample in milliseconds + self->sample_ms = MICROPY_FLOAT_CONST(1000.0) / self->base.sample_rate; + + // calculate everything needed for the current delay + mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms); + recalculate_delay(self, f_delay_ms); + + // read is where we read previous echo from delay_ms ago to play back now + // write is where the store the latest playing sample to echo back later + self->echo_buffer_left_pos = 0; + + // use a separate buffer position for the right channel + self->echo_buffer_right_pos = 0; +} + +void common_hal_audiodelays_echo_deinit(audiodelays_echo_obj_t *self) { + audiosample_mark_deinit(&self->base); + audiofilters_deinit_filter_chain(&self->filter); + self->echo_buffer = NULL; + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +mp_obj_t common_hal_audiodelays_echo_get_delay_ms(audiodelays_echo_obj_t *self) { + return self->delay_ms.obj; +} + +void common_hal_audiodelays_echo_set_delay_ms(audiodelays_echo_obj_t *self, mp_obj_t delay_ms) { + synthio_block_assign_slot(delay_ms, &self->delay_ms, MP_QSTR_delay_ms); + + mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms); + + recalculate_delay(self, f_delay_ms); +} + +void recalculate_delay(audiodelays_echo_obj_t *self, mp_float_t f_delay_ms) { + // Require that delay is at least 1 sample long + f_delay_ms = MAX(f_delay_ms, self->sample_ms); + + // Calculate the maximum buffer size per channel in bytes + uint32_t max_echo_buffer_len = self->max_echo_buffer_len >> (self->base.channel_count - 1); + + if (self->freq_shift) { + // Calculate the rate of iteration over the echo buffer with 8 sub-bits + self->echo_buffer_rate = (uint32_t)MAX(self->max_delay_ms / f_delay_ms * MICROPY_FLOAT_CONST(256.0), MICROPY_FLOAT_CONST(1.0)); + // Only use half of the buffer per channel if stereo + self->echo_buffer_len = max_echo_buffer_len; + } else { + // Calculate the current echo buffer length in bytes + uint32_t new_echo_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * f_delay_ms) * sizeof(uint16_t); + + // Limit to valid range + if (new_echo_buffer_len > max_echo_buffer_len) { + new_echo_buffer_len = max_echo_buffer_len; + } else if (new_echo_buffer_len < self->buffer_len) { + // If the echo buffer is smaller than our audio buffer, weird things happen + new_echo_buffer_len = self->buffer_len; + } + + self->echo_buffer_len = new_echo_buffer_len; + + // Clear the now unused part of the buffer or some weird artifacts appear + for (uint32_t i = 0; i < self->base.channel_count; i++) { + memset(self->echo_buffer + (i * max_echo_buffer_len) + self->echo_buffer_len, 0, max_echo_buffer_len - self->echo_buffer_len); + } + } + + self->current_delay_ms = f_delay_ms; +} + +mp_obj_t common_hal_audiodelays_echo_get_decay(audiodelays_echo_obj_t *self) { + return self->decay.obj; +} + +void common_hal_audiodelays_echo_set_decay(audiodelays_echo_obj_t *self, mp_obj_t decay) { + synthio_block_assign_slot(decay, &self->decay, MP_QSTR_decay); +} + +mp_obj_t common_hal_audiodelays_echo_get_filter(audiodelays_echo_obj_t *self) { + return self->filter.obj; +} + +void common_hal_audiodelays_echo_set_filter(audiodelays_echo_obj_t *self, mp_obj_t filter_in) { + audiofilters_assign_filter_chain(&self->filter, filter_in, self->base.channel_count); +} + +mp_obj_t common_hal_audiodelays_echo_get_mix(audiodelays_echo_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiodelays_echo_set_mix(audiodelays_echo_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +bool common_hal_audiodelays_echo_get_freq_shift(audiodelays_echo_obj_t *self) { + return self->freq_shift; +} + +void common_hal_audiodelays_echo_set_freq_shift(audiodelays_echo_obj_t *self, bool freq_shift) { + // Clear the echo buffer and reset buffer position if changing freq_shift modes + if (self->freq_shift != freq_shift) { + memset(self->echo_buffer, 0, self->max_echo_buffer_len); + self->echo_buffer_left_pos = 0; + self->echo_buffer_right_pos = 0; + } + self->freq_shift = freq_shift; + uint32_t delay_ms = (uint32_t)synthio_block_slot_get(&self->delay_ms); + recalculate_delay(self, delay_ms); +} + +void audiodelays_echo_reset_buffer(audiodelays_echo_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->echo_buffer, 0, self->max_echo_buffer_len); + + audiofilters_reset_filter_chain(&self->filter, self->base.channel_count); +} + +bool common_hal_audiodelays_echo_get_playing(audiodelays_echo_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiodelays_echo_play(audiodelays_echo_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiodelays_echo_stop(audiodelays_echo_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + // For echo we clear the sample but the echo continues until the object reading our effect stops + self->sample = NULL; + return; +} + +audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + if (!single_channel_output) { + channel = 0; + } + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // The echo buffer is always stored as a 16-bit value internally + int16_t *echo_buffer = (int16_t *)self->echo_buffer; + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it but we still need to play the echo + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n; + if (self->sample == NULL) { + n = MIN(length, SYNTHIO_MAX_DUR * self->base.channel_count); + } else { + n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * MICROPY_FLOAT_CONST(2.0); + mp_float_t decay = synthio_block_slot_get_limited(&self->decay, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + + mp_float_t f_delay_ms = synthio_block_slot_get(&self->delay_ms); + if (MICROPY_FLOAT_C_FUN(fabs)(self->current_delay_ms - f_delay_ms) >= self->sample_ms) { + recalculate_delay(self, f_delay_ms); + } + + // Tick biquad filters + audiofilters_tick_filter_chain(&self->filter); + + uint32_t echo_buf_len = self->echo_buffer_len / sizeof(uint16_t); + uint32_t max_echo_buf_len = (self->max_echo_buffer_len >> (self->base.channel_count - 1)) / sizeof(uint16_t); + + // If we have no sample keep the echo echoing + if (self->sample == NULL) { + if (mix <= MICROPY_FLOAT_CONST(0.01)) { // Mix of 0 is pure sample sound. We have no sample so no sound + if (self->base.samples_signed) { + memset(word_buffer, 0, length * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + uint16_t *uword_buffer = (uint16_t *)word_buffer; + while (length--) { + *uword_buffer++ = 32768; + } + } else { + memset(hword_buffer, 128, length * (self->base.bits_per_sample / 8)); + } + } + } else { + // Since we have no sample we can just iterate over the our entire remaining buffer and finish + for (uint32_t i = 0; i < length; i++) { + int16_t echo, word = 0; + uint32_t next_buffer_pos = 0; + + // Get our echo buffer position and offset depending on current channel + uint32_t echo_buffer_offset = max_echo_buf_len * ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1)); + uint32_t echo_buffer_pos = echo_buffer_offset ? self->echo_buffer_right_pos : self->echo_buffer_left_pos; + + if (self->freq_shift) { + echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; + next_buffer_pos = echo_buffer_pos + self->echo_buffer_rate; + + for (uint32_t j = echo_buffer_pos >> 8; j < next_buffer_pos >> 8; j++) { + word = (int16_t)(echo_buffer[(j % echo_buf_len) + echo_buffer_offset] * decay); + echo_buffer[(j % echo_buf_len) + echo_buffer_offset] = (int16_t)audiofilters_process_filter_chain(&self->filter, self->base.channel_count, !!echo_buffer_offset, word); + } + } else { + echo = echo_buffer[echo_buffer_pos + echo_buffer_offset]; + word = (int16_t)(echo * decay); + echo_buffer[echo_buffer_pos++ + echo_buffer_offset] = (int16_t)audiofilters_process_filter_chain(&self->filter, self->base.channel_count, !!echo_buffer_offset, word); + } + + word = (int16_t)(echo * MIN(mix, MICROPY_FLOAT_CONST(1.0))); + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + hword_buffer[i] = (int8_t)word; + if (!self->base.samples_signed) { + hword_buffer[i] ^= 0x80; + } + } + + if (self->freq_shift) { + echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); + } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { + echo_buffer_pos = 0; + } + + // Update buffer position + if (echo_buffer_offset) { + self->echo_buffer_right_pos = echo_buffer_pos; + } else { + self->echo_buffer_left_pos = echo_buffer_pos; + } + } + } + + length = 0; + } else { + // we have a sample to play and echo + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + if (mix <= MICROPY_FLOAT_CONST(0.01)) { // if mix is zero pure sample only + for (uint32_t i = 0; i < n; i++) { + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = sample_src[i]; + } else { + hword_buffer[i] = sample_hsrc[i]; + } + } + } else { + for (uint32_t i = 0; i < n; i++) { + int32_t sample_word = 0; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + + int32_t echo, word = 0; + uint32_t next_buffer_pos = 0; + + // Get our echo buffer position and offset depending on current channel + uint32_t echo_buffer_offset = max_echo_buf_len * ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1)); + uint32_t echo_buffer_pos = echo_buffer_offset ? self->echo_buffer_right_pos : self->echo_buffer_left_pos; + + if (self->freq_shift) { + echo = echo_buffer[(echo_buffer_pos >> 8) + echo_buffer_offset]; + next_buffer_pos = echo_buffer_pos + self->echo_buffer_rate; + } else { + echo = echo_buffer[echo_buffer_pos + echo_buffer_offset]; + word = (int32_t)(echo * decay + sample_word); + } + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + if (self->freq_shift) { + for (uint32_t j = echo_buffer_pos >> 8; j < next_buffer_pos >> 8; j++) { + word = (int32_t)(echo_buffer[(j % echo_buf_len) + echo_buffer_offset] * decay + sample_word); + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + echo_buffer[(j % echo_buf_len) + echo_buffer_offset] = (int16_t)audiofilters_process_filter_chain(&self->filter, self->base.channel_count, !!echo_buffer_offset, word); + } + } else { + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + echo_buffer[echo_buffer_pos++ + echo_buffer_offset] = (int16_t)audiofilters_process_filter_chain(&self->filter, self->base.channel_count, !!echo_buffer_offset, word); + } + } else { + if (self->freq_shift) { + for (uint32_t j = echo_buffer_pos >> 8; j < next_buffer_pos >> 8; j++) { + word = (int32_t)(echo_buffer[(j % echo_buf_len) + echo_buffer_offset] * decay + sample_word); + // Do not have mix_down for 8 bit so just hard cap samples into 1 byte + word = MIN(MAX(word, -128), 127); + echo_buffer[(j % echo_buf_len) + echo_buffer_offset] = (int8_t)audiofilters_process_filter_chain(&self->filter, self->base.channel_count, !!echo_buffer_offset, word); + } + } else { + // Do not have mix_down for 8 bit so just hard cap samples into 1 byte + word = MIN(MAX(word, -128), 127); + echo_buffer[echo_buffer_pos++ + echo_buffer_offset] = (int8_t)audiofilters_process_filter_chain(&self->filter, self->base.channel_count, !!echo_buffer_offset, word); + } + } + + word = (int32_t)((sample_word * MIN(MICROPY_FLOAT_CONST(2.0) - mix, MICROPY_FLOAT_CONST(1.0))) + + (echo * MIN(mix, MICROPY_FLOAT_CONST(1.0)))); + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = (int16_t)word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + int8_t mixed = (int16_t)word; + if (self->base.samples_signed) { + hword_buffer[i] = mixed; + } else { + hword_buffer[i] = (uint8_t)mixed ^ 0x80; + } + } + + if (self->freq_shift) { + echo_buffer_pos = next_buffer_pos % (echo_buf_len << 8); + } else if (!self->freq_shift && echo_buffer_pos >= echo_buf_len) { + echo_buffer_pos = 0; + } + + // Update buffer position + if (echo_buffer_offset) { + self->echo_buffer_right_pos = echo_buffer_pos; + } else { + self->echo_buffer_left_pos = echo_buffer_pos; + } + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // Echo always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiodelays/Echo.h b/shared-module/audiodelays/Echo.h new file mode 100644 index 00000000000..be01563b85a --- /dev/null +++ b/shared-module/audiodelays/Echo.h @@ -0,0 +1,60 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus, Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/audiofilters/__init__.h" +#include "shared-module/synthio/__init__.h" +#include "shared-module/synthio/block.h" +#include "shared-module/synthio/Biquad.h" + +extern const mp_obj_type_t audiodelays_echo_type; + +typedef struct { + audiosample_base_t base; + uint32_t max_delay_ms; + synthio_block_slot_t delay_ms; + mp_float_t current_delay_ms; + mp_float_t sample_ms; + synthio_block_slot_t decay; + audiofilters_filter_chain_t filter; + synthio_block_slot_t mix; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + bool freq_shift; // does the echo shift frequencies if delay changes + + int8_t *echo_buffer; + uint32_t echo_buffer_len; // bytes + uint32_t max_echo_buffer_len; // bytes + + uint32_t echo_buffer_left_pos; // words (<< 8 when freq_shift=True) + uint32_t echo_buffer_right_pos; // words (<< 8 when freq_shift=True) + uint32_t echo_buffer_rate; // words << 8 + + mp_obj_t sample; +} audiodelays_echo_obj_t; + +void recalculate_delay(audiodelays_echo_obj_t *self, mp_float_t f_delay_ms); + +void audiodelays_echo_reset_buffer(audiodelays_echo_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiodelays_echo_get_buffer(audiodelays_echo_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiodelays/Flanger.c b/shared-module/audiodelays/Flanger.c new file mode 100644 index 00000000000..f0d1bb1e33f --- /dev/null +++ b/shared-module/audiodelays/Flanger.c @@ -0,0 +1,414 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiodelays/Flanger.h" +#include "shared-bindings/audiocore/__init__.h" + +#include +#include "py/runtime.h" + +// The largest delay we will ever read, in frames. +#define FLANGER_MAX_DELAY_FRAMES (65535u) + +// Convert a delay in milliseconds to a Q16.16 count of frames, clamped so that both interpolation +// taps always land inside the delay line. +static uint32_t flanger_ms_to_frames_q16(audiodelays_flanger_obj_t *self, mp_float_t ms) { + mp_float_t frames = ms * self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0); + mp_float_t max_frames = (mp_float_t)MIN(self->delay_buffer_frames - 2, FLANGER_MAX_DELAY_FRAMES); + + // A delay of less than one frame would read the frame we are about to overwrite + frames = MIN(MAX(frames, MICROPY_FLOAT_CONST(1.0)), max_frames); + + return (uint32_t)(frames * MICROPY_FLOAT_CONST(65536.0)); +} + +void common_hal_audiodelays_flanger_construct(audiodelays_flanger_obj_t *self, uint32_t max_delay_ms, + mp_obj_t min_delay_ms, mp_obj_t rate, mp_obj_t depth, mp_obj_t feedback, mp_obj_t mix, bool invert, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate) { + + // Basic format settings every effect and audio sample has + self->base.bits_per_sample = bits_per_sample; + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_maybe(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiodelays_flanger_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_maybe(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiodelays_flanger_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the flanger effect's starting values. + + // If we did not receive a BlockInput we need to create a default float value + if (min_delay_ms == MP_OBJ_NULL) { + min_delay_ms = mp_obj_new_float(MICROPY_FLOAT_CONST(1.0)); + } + synthio_block_assign_slot(min_delay_ms, &self->min_delay_ms, MP_QSTR_min_delay_ms); + + if (rate == MP_OBJ_NULL) { + rate = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(rate, &self->rate, MP_QSTR_rate); + + if (depth == MP_OBJ_NULL) { + depth = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(depth, &self->depth, MP_QSTR_depth); + + if (feedback == MP_OBJ_NULL) { + feedback = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(feedback, &self->feedback, MP_QSTR_feedback); + + if (mix == MP_OBJ_NULL) { + mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + self->invert = invert; + self->max_delay_ms = max_delay_ms; + + // calculate the length of a single sample in milliseconds + self->sample_ms = MICROPY_FLOAT_CONST(1000.0) / self->base.sample_rate; + + // Allocate the delay line for the largest delay we can sweep to. It is always 16-bit and each + // channel gets its own contiguous region. The two extra frames are interpolation headroom: at + // the top of the sweep the two taps sit at the far end of the line and without the extra room + // the older of the two would alias onto the frame we are about to write. + self->delay_buffer_frames = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * max_delay_ms) + 2; + size_t delay_buffer_size = self->delay_buffer_frames * self->base.channel_count * sizeof(int16_t); + self->delay_buffer = m_malloc_maybe(delay_buffer_size); + if (self->delay_buffer == NULL) { + common_hal_audiodelays_flanger_deinit(self); + m_malloc_fail(delay_buffer_size); + } + memset(self->delay_buffer, 0, delay_buffer_size); + + self->delay_buffer_pos[0] = self->delay_buffer_pos[1] = 0; + self->lfo_phase[0] = self->lfo_phase[1] = 0; + self->lfo_phase_inc = 0; +} + +bool common_hal_audiodelays_flanger_deinited(audiodelays_flanger_obj_t *self) { + if (self->delay_buffer == NULL) { + return true; + } + return false; +} + +void common_hal_audiodelays_flanger_deinit(audiodelays_flanger_obj_t *self) { + audiosample_mark_deinit(&self->base); + self->delay_buffer = NULL; + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +mp_obj_t common_hal_audiodelays_flanger_get_min_delay_ms(audiodelays_flanger_obj_t *self) { + return self->min_delay_ms.obj; +} + +void common_hal_audiodelays_flanger_set_min_delay_ms(audiodelays_flanger_obj_t *self, mp_obj_t min_delay_ms) { + synthio_block_assign_slot(min_delay_ms, &self->min_delay_ms, MP_QSTR_min_delay_ms); +} + +mp_obj_t common_hal_audiodelays_flanger_get_rate(audiodelays_flanger_obj_t *self) { + return self->rate.obj; +} + +void common_hal_audiodelays_flanger_set_rate(audiodelays_flanger_obj_t *self, mp_obj_t rate) { + synthio_block_assign_slot(rate, &self->rate, MP_QSTR_rate); +} + +mp_obj_t common_hal_audiodelays_flanger_get_depth(audiodelays_flanger_obj_t *self) { + return self->depth.obj; +} + +void common_hal_audiodelays_flanger_set_depth(audiodelays_flanger_obj_t *self, mp_obj_t depth) { + synthio_block_assign_slot(depth, &self->depth, MP_QSTR_depth); +} + +mp_obj_t common_hal_audiodelays_flanger_get_feedback(audiodelays_flanger_obj_t *self) { + return self->feedback.obj; +} + +void common_hal_audiodelays_flanger_set_feedback(audiodelays_flanger_obj_t *self, mp_obj_t feedback) { + synthio_block_assign_slot(feedback, &self->feedback, MP_QSTR_feedback); +} + +mp_obj_t common_hal_audiodelays_flanger_get_mix(audiodelays_flanger_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiodelays_flanger_set_mix(audiodelays_flanger_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +// Fold the sawtooth phase accumulator into a triangle in the range 0 to 65535 +static uint32_t flanger_phase_to_triangle(uint32_t phase) { + uint32_t tri = phase >> 15; + if (tri > 65535) { + tri = 131071 - tri; + } + return tri; +} + +mp_float_t common_hal_audiodelays_flanger_get_lfo_value(audiodelays_flanger_obj_t *self) { + return (mp_float_t)flanger_phase_to_triangle(self->lfo_phase[0]) / MICROPY_FLOAT_CONST(65535.0); +} + +bool common_hal_audiodelays_flanger_get_invert(audiodelays_flanger_obj_t *self) { + return self->invert; +} + +void common_hal_audiodelays_flanger_set_invert(audiodelays_flanger_obj_t *self, bool invert) { + self->invert = invert; +} + +void audiodelays_flanger_reset_buffer(audiodelays_flanger_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->delay_buffer, 0, self->delay_buffer_frames * self->base.channel_count * sizeof(int16_t)); + self->delay_buffer_pos[0] = self->delay_buffer_pos[1] = 0; + self->lfo_phase[0] = self->lfo_phase[1] = 0; +} + +bool common_hal_audiodelays_flanger_get_playing(audiodelays_flanger_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiodelays_flanger_play(audiodelays_flanger_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; +} + +void common_hal_audiodelays_flanger_stop(audiodelays_flanger_obj_t *self) { + self->sample = NULL; +} + +audioio_get_buffer_result_t audiodelays_flanger_get_buffer(audiodelays_flanger_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + if (!single_channel_output) { + channel = 0; + } + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + uint8_t channel_count = self->base.channel_count; + uint32_t frames = self->delay_buffer_frames; + + // For single channel output every word in this call belongs to `channel`. Otherwise the + // channels are interleaved and alternate with every word. + bool single_right = single_channel_output && channel == 1 && channel_count == 2; + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + + if (self->sample == NULL) { + // tick all block inputs so that anything attached to them stays in sync + shared_bindings_synthio_lfo_tick(self->base.sample_rate, length / channel_count); + (void)synthio_block_slot_get(&self->min_delay_ms); + (void)synthio_block_slot_get(&self->rate); + (void)synthio_block_slot_get(&self->depth); + (void)synthio_block_slot_get(&self->feedback); + (void)synthio_block_slot_get(&self->mix); + + if (self->base.samples_signed) { + memset(word_buffer, 0, length * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + uint16_t *uword_buffer = (uint16_t *)word_buffer; + while (length--) { + *uword_buffer++ = 32768; + } + } else { + memset(hword_buffer, 128, length * (self->base.bits_per_sample / 8)); + } + } + + length = 0; + } else { + // we have a sample to play and flange + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t num_bytes = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * channel_count); + + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + // get the effect values we need from the BlockInput + shared_bindings_synthio_lfo_tick(self->base.sample_rate, num_bytes / channel_count); + mp_float_t f_min_delay_ms = synthio_block_slot_get_limited(&self->min_delay_ms, self->sample_ms, (mp_float_t)self->max_delay_ms); + mp_float_t f_rate = synthio_block_slot_get_limited(&self->rate, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(20.0)); + mp_float_t f_depth = synthio_block_slot_get_limited(&self->depth, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + int32_t feedback = (int32_t)(synthio_block_slot_get_limited(&self->feedback, MICROPY_FLOAT_CONST(-0.95), MICROPY_FLOAT_CONST(0.95)) * 32767); + int32_t mix = (int32_t)(synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * 32767); + + // The sweep runs upward from min_delay_ms towards max_delay_ms rather than around a + // centre, so no combination of min_delay_ms and depth can push it out of the delay line. + mp_float_t sweep_top_ms = f_min_delay_ms + f_depth * ((mp_float_t)self->max_delay_ms - f_min_delay_ms); + uint32_t delay_min_q16 = flanger_ms_to_frames_q16(self, f_min_delay_ms); + uint32_t delay_span_q16 = flanger_ms_to_frames_q16(self, sweep_top_ms) - delay_min_q16; + + // How far the LFO advances each frame. A rate at or above half the sample rate is + // meaningless, and clamping there also keeps the conversion inside a uint32_t. + mp_float_t phase_inc = MIN(f_rate / self->base.sample_rate, MICROPY_FLOAT_CONST(0.5)); + self->lfo_phase_inc = (uint32_t)(phase_inc * MICROPY_FLOAT_CONST(4294967296.0)); + + for (uint32_t i = 0; i < num_bytes; i++) { + bool right_channel = single_channel_output ? single_right : ((i % channel_count) == 1); + + int32_t sample_word = 0; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + + // Advance this channel's LFO by one frame. Each channel has its own accumulator so + // that the sweep runs at `rate` whether the channels arrive interleaved (both + // accumulators step once per frame) or one channel per call. + self->lfo_phase[right_channel] += self->lfo_phase_inc; + + uint32_t tri = flanger_phase_to_triangle(self->lfo_phase[right_channel]); + + // The delay for this frame, in Q16.16 frames + uint32_t delay_q16 = delay_min_q16 + (uint32_t)(((uint64_t)delay_span_q16 * tri) >> 16); + uint32_t delay_int = delay_q16 >> 16; + uint32_t delay_frac = delay_q16 & 0xffff; + + int16_t *line = self->delay_buffer + (right_channel ? frames : 0); + uint32_t w = self->delay_buffer_pos[right_channel]; + + // Two taps straddling the fractional delay, counted back from the write head. + // delay_int is at most frames - 2 so neither index can escape the region. + uint32_t r0 = w + frames - delay_int; + if (r0 >= frames) { + r0 -= frames; + } + uint32_t r1 = r0 ? r0 - 1 : frames - 1; + + // Linear interpolation between them + int32_t s0 = line[r0]; + int32_t s1 = line[r1]; + int32_t wet = s0 + (((s1 - s0) * (int32_t)delay_frac) >> 16); + + // Write the input plus the regenerated signal back into the line + line[w] = synthio_sat16(sample_word + synthio_sat16(wet * feedback, 15), 0); + self->delay_buffer_pos[right_channel] = (w + 1 == frames) ? 0 : w + 1; + + int32_t word; + if (mix <= 328) { // if mix is zero (0.01 in fixed point), pure sample only + // Note that we still ran the delay line above. + word = sample_word; + } else { + int32_t wet_word = synthio_sat16(wet * mix, 15); + // Add (or, inverted, subtract) original sample + effect + word = self->invert ? sample_word - wet_word : sample_word + wet_word; + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + } + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + // 8-bit samples have no headroom for synthio_mix_down_sample to work with, so + // clamp instead or the sum of the dry and wet signals wraps around + int8_t out = MIN(MAX(word, -128), 127); + if (self->base.samples_signed) { + hword_buffer[i] = out; + } else { + hword_buffer[i] = (uint8_t)out ^ 0x80; + } + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= num_bytes; + word_buffer += num_bytes; + hword_buffer += num_bytes; + self->sample_remaining_buffer += (num_bytes * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= num_bytes; + } + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // Flanger always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiodelays/Flanger.h b/shared-module/audiodelays/Flanger.h new file mode 100644 index 00000000000..6e8a37f51e2 --- /dev/null +++ b/shared-module/audiodelays/Flanger.h @@ -0,0 +1,62 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/synthio/block.h" + +extern const mp_obj_type_t audiodelays_flanger_type; + +typedef struct { + audiosample_base_t base; + + // Effect parameters. + synthio_block_slot_t min_delay_ms; // floor of the sweep + synthio_block_slot_t rate; // LFO frequency in Hz + synthio_block_slot_t depth; // 0 to 1, portion of the available range swept + synthio_block_slot_t feedback; // -0.95 to 0.95, regeneration + synthio_block_slot_t mix; // 0 to 1, dry to wet + + uint32_t max_delay_ms; + mp_float_t sample_ms; // length of a single sample in milliseconds + + bool invert; // subtract the wet signal instead of adding it + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + // The delay line is always 16-bit and is split into one contiguous region per channel so + // that read/write positions are plain frame counts and wrapping is a single modulo. + int16_t *delay_buffer; + uint32_t delay_buffer_frames; // frames in each per channel region + uint32_t delay_buffer_pos[2]; // write position in frames, per channel + + // Internal LFO. One phase accumulator per channel so that the sweep advances once per frame + // whether the channels are interleaved in one call or requested one channel at a time. + uint32_t lfo_phase[2]; // Q0.32, wraps naturally + uint32_t lfo_phase_inc; // Q0.32 step per frame, recalculated per chunk from rate + + mp_obj_t sample; +} audiodelays_flanger_obj_t; + +void audiodelays_flanger_reset_buffer(audiodelays_flanger_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiodelays_flanger_get_buffer(audiodelays_flanger_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiodelays/GranularPitchShift.c b/shared-module/audiodelays/GranularPitchShift.c new file mode 100644 index 00000000000..0408dd45b27 --- /dev/null +++ b/shared-module/audiodelays/GranularPitchShift.c @@ -0,0 +1,476 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiodelays/GranularPitchShift.h" +#include "shared-bindings/audiocore/__init__.h" + +#include +#include "py/runtime.h" +#include + +void common_hal_audiodelays_granular_pitch_shift_construct(audiodelays_granular_pitch_shift_obj_t *self, + mp_obj_t semitones, mp_obj_t mix, uint32_t grain_size, uint32_t density, + mp_float_t spread, uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effect's values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiodelays_granular_pitch_shift_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiodelays_granular_pitch_shift_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the effect's starting values. + + synthio_block_assign_slot(semitones, &self->semitones, MP_QSTR_semitones); + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + // Grain scheduling parameters. `density` (number of overlapping grains) is + // clamped to the fixed grain pool size so allocation stays deterministic. + self->grain_size = grain_size; + if (density < 1) { + density = 1; + } + if (density > GRANULAR_MAX_GRAINS) { + density = GRANULAR_MAX_GRAINS; + } + self->density = density; + + // Grain-start jitter amount and the PRNG that drives it. Seeded with a fixed + // nonzero constant so xorshift32 never degenerates to the all-zero state and + // the jitter sequence is reproducible from run to run. + common_hal_audiodelays_granular_pitch_shift_set_spread(self, spread); + self->rng_state = 0x1234abcdu; + + // Normalization for the overlap-add gain of the grain envelopes. A Hann + // window overlapped at hop = grain_size / density sums to a constant gain of + // density/2, so we scale the summed grains by 2/density in Q15 to keep the + // output at ~unity. Cap at 1.0 so the degenerate density==1 case (a single + // windowed grain, no overlap partner) is never amplified. + self->grain_gain = (1 << 15) * 2 / density; // 2/density in Q15 + if (self->grain_gain > (1 << 15)) { + self->grain_gain = (1 << 15); + } + + // Capture buffer (the delay line grains read from), stored as 16-bit, + // planar per channel. Length is grain_size * 2 words per channel so a grain + // starting grain_size words behind the write pointer never overruns the live + // write cursor even when reading ahead at a raised pitch + self->capture_len = self->grain_size * 2; // words per channel + uint32_t capture_bytes = self->capture_len * self->base.channel_count * sizeof(int16_t); + self->capture_buffer = m_malloc_without_collect(capture_bytes); + if (self->capture_buffer == NULL) { + common_hal_audiodelays_granular_pitch_shift_deinit(self); + m_malloc_fail(capture_bytes); + } + memset(self->capture_buffer, 0, capture_bytes); + self->write_index = 0; + + // Precompute the grain amplitude envelope: a raised-cosine (Hann) window in + // Q15 (0..32767), indexed directly by a grain's phase. + self->envelope_len = self->grain_size; + uint32_t envelope_bytes = self->envelope_len * sizeof(int16_t); + self->envelope_table = m_malloc_without_collect(envelope_bytes); + if (self->envelope_table == NULL) { + common_hal_audiodelays_granular_pitch_shift_deinit(self); + m_malloc_fail(envelope_bytes); + } + mp_float_t denom = (self->envelope_len > 1) ? (mp_float_t)(self->envelope_len - 1) : MICROPY_FLOAT_CONST(1.0); + for (uint32_t n = 0; n < self->envelope_len; n++) { + mp_float_t w = MICROPY_FLOAT_CONST(0.5) * + (MICROPY_FLOAT_CONST(1.0) - MICROPY_FLOAT_C_FUN(cos)( + MICROPY_FLOAT_CONST(2.0) * MICROPY_FLOAT_CONST(3.14159265358979323846) * (mp_float_t)n / denom)); + self->envelope_table[n] = (int16_t)(w * MICROPY_FLOAT_CONST(32767.0)); + } + + // Deactivate all grains and prime the scheduler so the first grain launches + // immediately on the first output sample. + for (uint32_t i = 0; i < GRANULAR_MAX_GRAINS; i++) { + self->grains[i].active = false; + } + self->samples_until_next_grain = 0; + + // Calculate the fixed-point read-rate increment applied to launched grains. + mp_float_t f_semitones = synthio_block_slot_get(&self->semitones); + granular_pitch_shift_recalculate_rate(self, f_semitones); +} + +void common_hal_audiodelays_granular_pitch_shift_deinit(audiodelays_granular_pitch_shift_obj_t *self) { + audiosample_mark_deinit(&self->base); + self->envelope_table = NULL; + self->capture_buffer = NULL; + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +mp_obj_t common_hal_audiodelays_granular_pitch_shift_get_semitones(audiodelays_granular_pitch_shift_obj_t *self) { + return self->semitones.obj; +} + +void common_hal_audiodelays_granular_pitch_shift_set_semitones(audiodelays_granular_pitch_shift_obj_t *self, mp_obj_t semitones_in) { + synthio_block_assign_slot(semitones_in, &self->semitones, MP_QSTR_semitones); + mp_float_t semitones = synthio_block_slot_get(&self->semitones); + granular_pitch_shift_recalculate_rate(self, semitones); +} + +void granular_pitch_shift_recalculate_rate(audiodelays_granular_pitch_shift_obj_t *self, mp_float_t semitones) { + self->read_rate = (uint32_t)(MICROPY_FLOAT_C_FUN(pow)(2.0, semitones / MICROPY_FLOAT_CONST(12.0)) * (1 << GRANULAR_PITCH_READ_SHIFT)); + self->current_semitones = semitones; +} + +mp_obj_t common_hal_audiodelays_granular_pitch_shift_get_mix(audiodelays_granular_pitch_shift_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiodelays_granular_pitch_shift_set_mix(audiodelays_granular_pitch_shift_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +mp_float_t common_hal_audiodelays_granular_pitch_shift_get_spread(audiodelays_granular_pitch_shift_obj_t *self) { + return self->spread; +} + +void common_hal_audiodelays_granular_pitch_shift_set_spread(audiodelays_granular_pitch_shift_obj_t *self, mp_float_t spread) { + if (spread < MICROPY_FLOAT_CONST(0.0)) { + spread = MICROPY_FLOAT_CONST(0.0); + } else if (spread > MICROPY_FLOAT_CONST(1.0)) { + spread = MICROPY_FLOAT_CONST(1.0); + } + self->spread = spread; +} + +void audiodelays_granular_pitch_shift_reset_buffer(audiodelays_granular_pitch_shift_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->capture_buffer, 0, self->capture_len * self->base.channel_count * sizeof(int16_t)); + + // Deactivate all grains and reset the scheduler/write cursor. + for (uint32_t i = 0; i < GRANULAR_MAX_GRAINS; i++) { + self->grains[i].active = false; + } + self->samples_until_next_grain = 0; + self->write_index = 0; +} + +bool common_hal_audiodelays_granular_pitch_shift_get_playing(audiodelays_granular_pitch_shift_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiodelays_granular_pitch_shift_play(audiodelays_granular_pitch_shift_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiodelays_granular_pitch_shift_stop(audiodelays_granular_pitch_shift_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + self->sample = NULL; + return; +} + +// xorshift32 PRNG for grain-start jitter. Kept local to this module so the +// effect doesn't depend on the `random` module being enabled in a build. +static uint32_t granular_pitch_shift_rand(audiodelays_granular_pitch_shift_obj_t *self) { + uint32_t x = self->rng_state; + x ^= x << 13; + x ^= x >> 17; + x ^= x << 5; + self->rng_state = x; + return x; +} + +// Launch a grain into the first free pool slot, seeded to read from the capture +// buffer starting grain_size words behind the current write cursor (so it reads +// already-captured audio) at the current pitch-shift read rate. When `spread` is +// nonzero the start is jittered up to a further grain_size words backward, which +// is what gives granular synthesis its characteristic "cloud" texture. Jitter is +// always backward (further behind the write cursor), so a grain never reads ahead +// of captured audio and the capture buffer (capture_len == grain_size * 2) is +// never overrun. Grain read state (read_index/phase) is per-frame / +// channel-independent; the per-channel plane offset is applied at read time. +static void granular_pitch_shift_launch_grain(audiodelays_granular_pitch_shift_obj_t *self) { + for (uint32_t g = 0; g < GRANULAR_MAX_GRAINS; g++) { + if (!self->grains[g].active) { + // Backward jitter in [0, spread * grain_size]. Capped at grain_size + // so grain_size + jitter <= capture_len (== grain_size * 2). + uint32_t jitter = 0; + if (self->spread > MICROPY_FLOAT_CONST(0.0)) { + uint32_t max_jitter = (uint32_t)(self->spread * (mp_float_t)self->grain_size); + if (max_jitter > 0) { + jitter = granular_pitch_shift_rand(self) % (max_jitter + 1); + } + } + uint32_t start = (self->write_index + self->capture_len - self->grain_size - jitter) % self->capture_len; + self->grains[g].active = true; + self->grains[g].read_index = start << GRANULAR_PITCH_READ_SHIFT; + self->grains[g].read_rate = self->read_rate; + self->grains[g].phase = 0; + self->grains[g].length = self->grain_size; + return; + } + } +} + +audioio_get_buffer_result_t audiodelays_granular_pitch_shift_get_buffer(audiodelays_granular_pitch_shift_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + // Grain scheduler + enveloped grain playback with dry/wet `mix` blending. + // Grains are launched at a fixed spacing (grain_size / density) and each + // active grain reads the capture buffer at its own pitch-shifted (fractional, + // linearly interpolated) read rate, scaled by a Hann amplitude envelope so + // overlapping grains fade in/out and add without seam clicks. The summed + // grains are normalized by grain_gain for ~unity overlap-add gain, then + // crossfaded against the dry input via the `mix` slot. The 8/16-bit, + // signed/unsigned, and mono/stereo (planar capture, buf_offset) paths are all + // handled below, mirroring PitchShift. + + if (!single_channel_output) { + channel = 0; + } + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // The capture buffer (delay line) is always stored as 16-bit, planar per + // channel: channel c occupies capture_buffer[c * capture_len .. ). + int16_t *capture_buffer = self->capture_buffer; + + // Grains are launched this many frames apart (overlap factor `density`). + uint32_t grain_spacing = self->grain_size / self->density; + if (grain_spacing == 0) { + grain_spacing = 1; + } + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + if (self->sample == NULL) { + if (self->base.samples_signed) { + memset(word_buffer, 0, length * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + memset(word_buffer, 32768, length * (self->base.bits_per_sample / 8)); + } else { + memset(hword_buffer, 128, length * (self->base.bits_per_sample / 8)); + } + } + + // tick all block inputs + shared_bindings_synthio_lfo_tick(self->base.sample_rate, length / self->base.channel_count); + (void)synthio_block_slot_get(&self->semitones); + (void)synthio_block_slot_get(&self->mix); + + length = 0; + } else { + // we have a sample to play and apply effect + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + // get the effect values we need from the BlockInput. + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t semitones = synthio_block_slot_get(&self->semitones); + // Doubled (0.0..2.0) so the crossfade below can hold both dry and wet + // at full gain around the midpoint, matching PitchShift's mix curve. + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * MICROPY_FLOAT_CONST(2.0); + + // Only recalculate rate if semitones has changed + if (memcmp(&semitones, &self->current_semitones, sizeof(mp_float_t))) { + granular_pitch_shift_recalculate_rate(self, semitones); + } + + for (uint32_t i = 0; i < n; i++) { + bool buf_offset = (channel == 1 || i % self->base.channel_count == 1); + + int32_t sample_word = 0; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // Changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + + // Write the incoming sample into the capture buffer (the delay + // line grains read from) at the per-channel write cursor. + capture_buffer[self->write_index + self->capture_len * buf_offset] = (int16_t)sample_word; + + // Sum all active grains. Each grain reads the capture buffer at + // its own fractional read cursor (linearly interpolated between + // adjacent words), which is what produces the pitch shift, then + // is scaled by its amplitude envelope (Hann, indexed by the + // grain's phase) so grains fade in/out and overlap-add without + // seam clicks. + int32_t word = 0; + for (uint32_t g = 0; g < GRANULAR_MAX_GRAINS; g++) { + if (!self->grains[g].active) { + continue; + } + uint32_t read_index_fp = self->grains[g].read_index; + uint32_t ipart = read_index_fp >> GRANULAR_PITCH_READ_SHIFT; + uint32_t frac = read_index_fp & ((1 << GRANULAR_PITCH_READ_SHIFT) - 1); + uint32_t index_lo = ipart % self->capture_len; + uint32_t index_hi = (ipart + 1) % self->capture_len; + int32_t sample_lo = capture_buffer[index_lo + self->capture_len * buf_offset]; + int32_t sample_hi = capture_buffer[index_hi + self->capture_len * buf_offset]; + int32_t grain_out = sample_lo + (((sample_hi - sample_lo) * (int32_t)frac) >> GRANULAR_PITCH_READ_SHIFT); + // Apply the grain envelope (Q15). phase < length == envelope_len. + int32_t env = self->envelope_table[self->grains[g].phase]; + word += (grain_out * env) >> 15; + } + + // Normalize the overlap-add gain of the enveloped grains back to + // ~unity (int64 guards the Q15 multiply against overflow). This is + // the fully-wet (pitch-shifted) sample. + word = (int32_t)(((int64_t)word * (int64_t)self->grain_gain) >> 15); + + // Dry/wet crossfade: `mix` is doubled to 0.0..2.0 so both terms + // sit at full gain around the midpoint, then synthio_mix_down_sample + // scales/soft-clips the summed pair back into range (same curve as + // PitchShift). mix=0.0 -> dry input, mix=1.0 -> fully wet. + word = (int32_t)((sample_word * MIN(MICROPY_FLOAT_CONST(2.0) - mix, MICROPY_FLOAT_CONST(1.0))) + (word * MIN(mix, MICROPY_FLOAT_CONST(1.0)))); + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = (int16_t)word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + int8_t mixed = (int8_t)word; + if (self->base.samples_signed) { + hword_buffer[i] = mixed; + } else { + hword_buffer[i] = (uint8_t)mixed ^ 0x80; + } + } + + // Per-frame shared work (once per frame: mono every sample, + // interleaved stereo on the right-channel sample) so both + // channels read consistent grain state before it advances. + if (self->base.channel_count == 1 || buf_offset) { + // Advance and retire active grains (they were read above). + for (uint32_t g = 0; g < GRANULAR_MAX_GRAINS; g++) { + if (!self->grains[g].active) { + continue; + } + self->grains[g].read_index += self->grains[g].read_rate; + self->grains[g].phase++; + if (self->grains[g].phase >= self->grains[g].length) { + self->grains[g].active = false; + } + } + + // Launch a new grain when the scheduler counter elapses. + if (self->samples_until_next_grain == 0) { + granular_pitch_shift_launch_grain(self); + self->samples_until_next_grain = grain_spacing; + } else { + self->samples_until_next_grain--; + } + + // Advance the per-channel write cursor. + self->write_index++; + if (self->write_index >= self->capture_len) { + self->write_index = 0; + } + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiodelays/GranularPitchShift.h b/shared-module/audiodelays/GranularPitchShift.h new file mode 100644 index 00000000000..26ee4804f36 --- /dev/null +++ b/shared-module/audiodelays/GranularPitchShift.h @@ -0,0 +1,104 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/synthio/__init__.h" +#include "shared-module/synthio/block.h" + +// Fixed-point fractional bits for grain read cursors and read rate. A grain's +// read_index and read_rate are stored as (words << GRANULAR_PITCH_READ_SHIFT), +// mirroring PITCH_READ_SHIFT from PitchShift.h. +#define GRANULAR_PITCH_READ_SHIFT (8) + +// Maximum number of concurrently active grains. `density` is clamped to this at +// construction so the grain pool is a fixed, deterministic allocation. +#define GRANULAR_MAX_GRAINS (8) + +extern const mp_obj_type_t audiodelays_granular_pitch_shift_type; + +// A single grain: a short, independently-scheduled, enveloped read of the +// capture buffer. Retired when `phase` reaches `length`. +typedef struct { + bool active; + uint32_t read_index; // words << GRANULAR_PITCH_READ_SHIFT into the capture buffer + uint32_t read_rate; // words << GRANULAR_PITCH_READ_SHIFT, the pitch-shift increment + uint32_t phase; // samples elapsed since the grain launched + uint32_t length; // grain length in samples (== grain_size) +} audiodelays_granular_grain_t; + +typedef struct { + audiosample_base_t base; + synthio_block_slot_t semitones; + mp_float_t current_semitones; + synthio_block_slot_t mix; + + // Double playback buffers (what we hand back to the audio component). + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + // Current sample source bookkeeping. + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + // Capture buffer (the delay line grains read from). Always stored as 16-bit + // internally, planar per channel: channel c occupies + // capture_buffer[c * capture_len .. (c + 1) * capture_len). + int16_t *capture_buffer; + uint32_t capture_len; // words per channel + uint32_t write_index; // words, per-channel write cursor (0 .. capture_len) + + // Grain pool + scheduler. + audiodelays_granular_grain_t grains[GRANULAR_MAX_GRAINS]; + uint32_t samples_until_next_grain; + + uint32_t grain_size; // samples per grain + uint32_t density; // number of overlapping grains (<= GRANULAR_MAX_GRAINS) + + // Granular jitter: randomizes each grain's start position within the capture + // buffer. 0.0 is fully deterministic (grains always start grain_size words + // behind the write cursor); 1.0 spreads the start up to a further grain_size + // words backward, giving the classic granular "cloud" texture. Jitter is + // always backward (further behind the write cursor) so it never reads ahead + // of captured audio. + mp_float_t spread; + uint32_t rng_state; // xorshift32 state for grain-start jitter + + // Q15 (0..32768) normalization applied to the enveloped grain sum so the + // overlap-add gain of `density` Hann grains stays ~unity (Hann satisfies + // COLA at these hops with a summed gain of density/2, so the factor is + // 2/density, capped at 1.0 so a single grain is never amplified). + uint32_t grain_gain; + + // Precomputed amplitude envelope (raised-cosine / Hann), Q15 (0..32767), + // indexed directly by a grain's phase (envelope_len == grain_size). + int16_t *envelope_table; + uint32_t envelope_len; + + // Fixed-point read-rate increment computed from `semitones`, applied to each + // launched grain's read_rate. + uint32_t read_rate; // words << GRANULAR_PITCH_READ_SHIFT + + mp_obj_t sample; +} audiodelays_granular_pitch_shift_obj_t; + +void granular_pitch_shift_recalculate_rate(audiodelays_granular_pitch_shift_obj_t *self, mp_float_t semitones); + +void audiodelays_granular_pitch_shift_reset_buffer(audiodelays_granular_pitch_shift_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiodelays_granular_pitch_shift_get_buffer(audiodelays_granular_pitch_shift_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiodelays/MultiTapDelay.c b/shared-module/audiodelays/MultiTapDelay.c new file mode 100644 index 00000000000..39887832764 --- /dev/null +++ b/shared-module/audiodelays/MultiTapDelay.c @@ -0,0 +1,484 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiodelays/MultiTapDelay.h" +#include "shared-bindings/audiocore/__init__.h" + +#include +#include "py/runtime.h" +#include + +void common_hal_audiodelays_multi_tap_delay_construct(audiodelays_multi_tap_delay_obj_t *self, uint32_t max_delay_ms, + mp_obj_t delay_ms, mp_obj_t decay, mp_obj_t mix, mp_obj_t taps, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_maybe(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiodelays_multi_tap_delay_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_maybe(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiodelays_multi_tap_delay_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the multi-tap delay effect's starting values. For a different effect this section will change + + // If we did not receive a BlockInput we need to create a default float value + if (decay == MP_OBJ_NULL) { + decay = mp_obj_new_float(MICROPY_FLOAT_CONST(0.7)); + } + synthio_block_assign_slot(decay, &self->decay, MP_QSTR_decay); + + if (mix == MP_OBJ_NULL) { + mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.25)); + } + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + // Allocate the delay buffer for the max possible delay, delay is always 16-bit + self->max_delay_ms = max_delay_ms; + self->max_delay_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * max_delay_ms) * (self->base.channel_count * sizeof(uint16_t)); // bytes + self->delay_buffer = m_malloc_maybe(self->max_delay_buffer_len); + if (self->delay_buffer == NULL) { + common_hal_audiodelays_multi_tap_delay_deinit(self); + m_malloc_fail(self->max_delay_buffer_len); + } + memset(self->delay_buffer, 0, self->max_delay_buffer_len); + + // calculate the length of a single sample in milliseconds + self->sample_ms = MICROPY_FLOAT_CONST(1000.0) / self->base.sample_rate; + + // calculate everything needed for the current delay + common_hal_audiodelays_multi_tap_delay_set_delay_ms(self, delay_ms); + self->delay_buffer_pos = 0; + self->delay_buffer_right_pos = 0; + + // Initialize our tap values + self->tap_positions = NULL; + self->tap_levels = NULL; + self->tap_offsets = NULL; + self->tap_len = 0; + common_hal_audiodelays_multi_tap_delay_set_taps(self, taps); +} + +void common_hal_audiodelays_multi_tap_delay_deinit(audiodelays_multi_tap_delay_obj_t *self) { + audiosample_mark_deinit(&self->base); + self->delay_buffer = NULL; + self->buffer[0] = NULL; + self->buffer[1] = NULL; + + self->tap_positions = NULL; + self->tap_levels = NULL; + self->tap_offsets = NULL; +} + +mp_float_t common_hal_audiodelays_multi_tap_delay_get_delay_ms(audiodelays_multi_tap_delay_obj_t *self) { + return self->delay_ms; +} + +void common_hal_audiodelays_multi_tap_delay_set_delay_ms(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t delay_ms) { + self->delay_ms = mp_obj_get_float(delay_ms); + + // Require that delay is at least 1 sample long + self->delay_ms = MAX(self->delay_ms, self->sample_ms); + + // Calculate the current delay buffer length in bytes + self->delay_buffer_len = (uint32_t)(self->base.sample_rate / MICROPY_FLOAT_CONST(1000.0) * self->delay_ms) * (self->base.channel_count * sizeof(uint16_t)); + + // Limit to valid range + if (self->delay_buffer_len > self->max_delay_buffer_len) { + self->delay_buffer_len = self->max_delay_buffer_len; + } else if (self->delay_buffer_len < self->buffer_len) { + // If the delay buffer is smaller than our audio buffer, weird things happen + self->delay_buffer_len = self->buffer_len; + } + + // Clear the now unused part of the buffer or some weird artifacts appear + memset(self->delay_buffer + self->delay_buffer_len, 0, self->max_delay_buffer_len - self->delay_buffer_len); + + // Update tap offsets if we have any + recalculate_tap_offsets(self); +} + +mp_obj_t common_hal_audiodelays_multi_tap_delay_get_decay(audiodelays_multi_tap_delay_obj_t *self) { + return self->decay.obj; +} + +void common_hal_audiodelays_multi_tap_delay_set_decay(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t decay) { + synthio_block_assign_slot(decay, &self->decay, MP_QSTR_decay); +} + +mp_obj_t common_hal_audiodelays_multi_tap_delay_get_mix(audiodelays_multi_tap_delay_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiodelays_multi_tap_delay_set_mix(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t mix) { + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); +} + +mp_obj_t common_hal_audiodelays_multi_tap_delay_get_taps(audiodelays_multi_tap_delay_obj_t *self) { + if (!self->tap_len) { + return mp_const_none; + } else { + mp_obj_tuple_t *taps = mp_obj_new_tuple(self->tap_len, NULL); + for (size_t i = 0; i < self->tap_len; i++) { + mp_obj_tuple_t *pair = mp_obj_new_tuple(2, NULL); + pair->items[0] = mp_obj_new_float(self->tap_positions[i]); + pair->items[1] = mp_obj_new_float(self->tap_levels[i]); + taps->items[i] = pair; + } + return taps; + } +} + +void validate_tap_value(mp_obj_t item, qstr arg_name) { + if (mp_obj_is_small_int(item)) { + mp_arg_validate_int_range(mp_obj_get_int(item), 0, 1, arg_name); + } else { + mp_arg_validate_obj_float_range(item, 0, 1, arg_name); + } +} + +mp_float_t get_tap_value(mp_obj_t item) { + mp_float_t value; + if (mp_obj_is_small_int(item)) { + value = (mp_float_t)mp_obj_get_int(item); + } else { + value = mp_obj_float_get(item); + } + return value; +} + +void common_hal_audiodelays_multi_tap_delay_set_taps(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t taps_in) { + if (taps_in != mp_const_none && !MP_OBJ_TYPE_HAS_SLOT(mp_obj_get_type(taps_in), iter)) { + mp_raise_TypeError_varg( + MP_ERROR_TEXT("%q must be of type %q, not %q"), + MP_QSTR_taps, MP_QSTR_iterable, mp_obj_get_type(taps_in)->name); + } + + size_t len, i; + mp_obj_t *items; + + if (taps_in == mp_const_none) { + len = 0; + items = NULL; + } else { + // convert object to tuple if it wasn't before + taps_in = MP_OBJ_TYPE_GET_SLOT(&mp_type_tuple, make_new)( + &mp_type_tuple, 1, 0, &taps_in); + + mp_obj_tuple_get(taps_in, &len, &items); + mp_arg_validate_length_min(len, 1, MP_QSTR_items); + + for (i = 0; i < len; i++) { + mp_obj_t item = items[i]; + if (mp_obj_is_tuple_compatible(item)) { + size_t len1; + mp_obj_t *items1; + mp_obj_tuple_get(item, &len1, &items1); + mp_arg_validate_length(len1, 2, MP_QSTR_items); + + for (size_t j = 0; j < len1; j++) { + validate_tap_value(items1[j], j ? MP_QSTR_level : MP_QSTR_position); + } + } else if (mp_obj_is_float(item) || mp_obj_is_small_int(item)) { + validate_tap_value(item, MP_QSTR_position); + } else { + mp_raise_TypeError_varg( + MP_ERROR_TEXT("%q in %q must be of type %q or %q, not %q"), + MP_QSTR_object, + MP_QSTR_taps, + MP_QSTR_iterable, + MP_QSTR_float, + mp_obj_get_type(item)->name); + } + + } + } + + self->tap_positions = m_renew(mp_float_t, + self->tap_positions, + self->tap_len, + len); + self->tap_levels = m_renew(mp_float_t, + self->tap_levels, + self->tap_len, + len); + self->tap_offsets = m_renew(uint32_t, + self->tap_offsets, + self->tap_len, + len); + self->tap_len = len; + + for (i = 0; i < len; i++) { + mp_obj_t item = items[i]; + if (mp_obj_is_tuple_compatible(item)) { + size_t len1; + mp_obj_t *items1; + mp_obj_tuple_get(item, &len1, &items1); + + self->tap_positions[i] = get_tap_value(items1[0]); + self->tap_levels[i] = get_tap_value(items1[1]); + } else { + self->tap_positions[i] = get_tap_value(item); + self->tap_levels[i] = MICROPY_FLOAT_CONST(1.0); + } + } + + recalculate_tap_offsets(self); +} + +void recalculate_tap_offsets(audiodelays_multi_tap_delay_obj_t *self) { + if (!self->tap_len) { + return; + } + + uint32_t delay_buffer_len = self->delay_buffer_len / self->base.channel_count / sizeof(uint16_t); + for (size_t i = 0; i < self->tap_len; i++) { + self->tap_offsets[i] = (uint32_t)(delay_buffer_len * self->tap_positions[i]); + } +} + +void audiodelays_multi_tap_delay_reset_buffer(audiodelays_multi_tap_delay_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->delay_buffer, 0, self->max_delay_buffer_len); +} + +bool common_hal_audiodelays_multi_tap_delay_get_playing(audiodelays_multi_tap_delay_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiodelays_multi_tap_delay_play(audiodelays_multi_tap_delay_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiodelays_multi_tap_delay_stop(audiodelays_multi_tap_delay_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + // For delay we clear the sample but the delay continues until the object reading our effect stops + self->sample = NULL; + return; +} + +audioio_get_buffer_result_t audiodelays_multi_tap_delay_get_buffer(audiodelays_multi_tap_delay_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + if (!single_channel_output) { + channel = 0; + } + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // The delay buffer is always stored as a 16-bit value internally + int16_t *delay_buffer = (int16_t *)self->delay_buffer; + uint32_t delay_buffer_len = self->delay_buffer_len / self->base.channel_count / sizeof(uint16_t); + + uint32_t delay_buffer_pos = self->delay_buffer_pos; + if (single_channel_output && channel == 1) { + delay_buffer_pos = self->delay_buffer_right_pos; + } + + int32_t mix_down_scale = SYNTHIO_MIX_DOWN_SCALE(self->tap_len); + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it but we still need to play the delay + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n; + if (self->sample == NULL) { + n = MIN(length, SYNTHIO_MAX_DUR * self->base.channel_count); + } else { + n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * MICROPY_FLOAT_CONST(2.0); + mp_float_t decay = synthio_block_slot_get_limited(&self->decay, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + + int16_t *sample_src = NULL; + int8_t *sample_hsrc = NULL; + if (self->sample != NULL) { + // we have a sample to play and delay + sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + } + + for (uint32_t i = 0; i < n; i++) { + uint32_t delay_buffer_offset = delay_buffer_len * ((single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1)); + + int32_t sample_word = 0; + if (self->sample != NULL) { + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + } + + // Pull words from delay buffer at tap positions, apply level and mix down + int32_t word = 0; + int32_t delay_word; + if (self->tap_len) { + size_t tap_pos; + for (size_t j = 0; j < self->tap_len; j++) { + tap_pos = (delay_buffer_pos + delay_buffer_len - self->tap_offsets[j]) % delay_buffer_len; + delay_word = delay_buffer[tap_pos + delay_buffer_offset]; + word += (int32_t)(delay_word * self->tap_levels[j]); + } + + if (self->tap_len > 1) { + word = synthio_mix_down_sample(word, mix_down_scale); + } + } + + // Update delay buffer with sample and decay + delay_word = delay_buffer[delay_buffer_pos + delay_buffer_offset]; + + // If no taps are provided, use as standard delay + if (!self->tap_len) { + word = delay_word; + } + + // Apply decay and add sample + delay_word = (int32_t)(delay_word * decay) + sample_word; + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + delay_word = synthio_mix_down_sample(delay_word, SYNTHIO_MIX_DOWN_SCALE(2)); + delay_buffer[delay_buffer_pos + delay_buffer_offset] = (int16_t)delay_word; + } else { + // Do not have mix_down for 8 bit so just hard cap samples into 1 byte + delay_word = MIN(MAX(delay_word, -128), 127); + delay_buffer[delay_buffer_pos + delay_buffer_offset] = (int8_t)delay_word; + } + + // Mix sample with tap output + word = (int32_t)((sample_word * MIN(MICROPY_FLOAT_CONST(2.0) - mix, MICROPY_FLOAT_CONST(1.0))) + + (word * MIN(mix, MICROPY_FLOAT_CONST(1.0)))); + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = (int16_t)word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + int8_t mixed = (int16_t)word; + if (self->base.samples_signed) { + hword_buffer[i] = mixed; + } else { + hword_buffer[i] = (uint8_t)mixed ^ 0x80; + } + } + + if ((self->base.channel_count == 1 || single_channel_output || (!single_channel_output && (i % self->base.channel_count) == 1)) + && ++delay_buffer_pos >= delay_buffer_len) { + delay_buffer_pos = 0; + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + if (self->sample != NULL) { + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + } + + if (single_channel_output && channel == 1) { + self->delay_buffer_right_pos = delay_buffer_pos; + } else { + self->delay_buffer_pos = delay_buffer_pos; + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // MultiTapDelay always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiodelays/MultiTapDelay.h b/shared-module/audiodelays/MultiTapDelay.h new file mode 100644 index 00000000000..ebe310b05f7 --- /dev/null +++ b/shared-module/audiodelays/MultiTapDelay.h @@ -0,0 +1,60 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/synthio/__init__.h" +#include "shared-module/synthio/block.h" + +extern const mp_obj_type_t audiodelays_multi_tap_delay_type; + +typedef struct { + audiosample_base_t base; + uint32_t max_delay_ms; + mp_float_t delay_ms; + mp_float_t sample_ms; + synthio_block_slot_t decay; + synthio_block_slot_t mix; + + mp_float_t *tap_positions; + mp_float_t *tap_levels; + uint32_t *tap_offsets; + size_t tap_len; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + int8_t *delay_buffer; + uint32_t delay_buffer_len; // bytes + uint32_t max_delay_buffer_len; // bytes + uint32_t delay_buffer_pos; + uint32_t delay_buffer_right_pos; + + mp_obj_t sample; +} audiodelays_multi_tap_delay_obj_t; + +void validate_tap_value(mp_obj_t item, qstr arg_name); +mp_float_t get_tap_value(mp_obj_t item); +void recalculate_tap_offsets(audiodelays_multi_tap_delay_obj_t *self); + +void audiodelays_multi_tap_delay_reset_buffer(audiodelays_multi_tap_delay_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiodelays_multi_tap_delay_get_buffer(audiodelays_multi_tap_delay_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiodelays/PitchShift.c b/shared-module/audiodelays/PitchShift.c new file mode 100644 index 00000000000..2c5d646aafb --- /dev/null +++ b/shared-module/audiodelays/PitchShift.c @@ -0,0 +1,356 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiodelays/PitchShift.h" +#include "shared-bindings/audiocore/__init__.h" + +#include +#include "py/runtime.h" +#include + +void common_hal_audiodelays_pitch_shift_construct(audiodelays_pitch_shift_obj_t *self, + mp_obj_t semitones, mp_obj_t mix, uint32_t window, uint32_t overlap, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiodelays_pitch_shift_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiodelays_pitch_shift_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the effect's starting values. + + synthio_block_assign_slot(semitones, &self->semitones, MP_QSTR_semitones); + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + // Allocate the window buffer + self->window_len = window; // bytes + self->window_buffer = m_malloc_without_collect(self->window_len); + if (self->window_buffer == NULL) { + common_hal_audiodelays_pitch_shift_deinit(self); + m_malloc_fail(self->window_len); + } + memset(self->window_buffer, 0, self->window_len); + + // Allocate the overlap buffer + self->overlap_len = overlap; // bytes + if (self->overlap_len) { + self->overlap_buffer = m_malloc_without_collect(self->overlap_len); + if (self->overlap_buffer == NULL) { + common_hal_audiodelays_pitch_shift_deinit(self); + m_malloc_fail(self->overlap_len); + } + memset(self->overlap_buffer, 0, self->overlap_len); + } else { + self->overlap_buffer = NULL; + } + + // The current position that the end of the overlap buffer will be written to the window buffer + self->window_index = 0; + + // The position that the current sample will be written to the overlap buffer + self->overlap_index = 0; + + // The position that the window buffer will be read from and written to the output + self->read_index = 0; + + // Calculate the rate to increment the read index + mp_float_t f_semitones = synthio_block_slot_get(&self->semitones); + recalculate_rate(self, f_semitones); +} + +void common_hal_audiodelays_pitch_shift_deinit(audiodelays_pitch_shift_obj_t *self) { + audiosample_mark_deinit(&self->base); + self->window_buffer = NULL; + self->overlap_buffer = NULL; + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +mp_obj_t common_hal_audiodelays_pitch_shift_get_semitones(audiodelays_pitch_shift_obj_t *self) { + return self->semitones.obj; +} + +void common_hal_audiodelays_pitch_shift_set_semitones(audiodelays_pitch_shift_obj_t *self, mp_obj_t delay_ms) { + synthio_block_assign_slot(delay_ms, &self->semitones, MP_QSTR_semitones); + mp_float_t semitones = synthio_block_slot_get(&self->semitones); + recalculate_rate(self, semitones); +} + +void recalculate_rate(audiodelays_pitch_shift_obj_t *self, mp_float_t semitones) { + self->read_rate = (uint32_t)(MICROPY_FLOAT_C_FUN(pow)(2.0, semitones / MICROPY_FLOAT_CONST(12.0)) * (1 << PITCH_READ_SHIFT)); + self->current_semitones = semitones; +} + +mp_obj_t common_hal_audiodelays_pitch_shift_get_mix(audiodelays_pitch_shift_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiodelays_pitch_shift_set_mix(audiodelays_pitch_shift_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +void audiodelays_pitch_shift_reset_buffer(audiodelays_pitch_shift_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->window_buffer, 0, self->window_len); + if (self->overlap_len) { + memset(self->overlap_buffer, 0, self->overlap_len); + } +} + +bool common_hal_audiodelays_pitch_shift_get_playing(audiodelays_pitch_shift_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiodelays_pitch_shift_play(audiodelays_pitch_shift_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiodelays_pitch_shift_stop(audiodelays_pitch_shift_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + self->sample = NULL; + return; +} + +audioio_get_buffer_result_t audiodelays_pitch_shift_get_buffer(audiodelays_pitch_shift_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + if (!single_channel_output) { + channel = 0; + } + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // The window and overlap buffers are always stored as a 16-bit value internally + int16_t *window_buffer = (int16_t *)self->window_buffer; + uint32_t window_size = self->window_len / sizeof(uint16_t) / self->base.channel_count; + + int16_t *overlap_buffer = NULL; + uint32_t overlap_size = 0; + if (self->overlap_len) { + overlap_buffer = (int16_t *)self->overlap_buffer; + overlap_size = self->overlap_len / sizeof(uint16_t) / self->base.channel_count; + } + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + if (self->sample == NULL) { + if (self->base.samples_signed) { + memset(word_buffer, 0, length * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + memset(word_buffer, 32768, length * (self->base.bits_per_sample / 8)); + } else { + memset(hword_buffer, 128, length * (self->base.bits_per_sample / 8)); + } + } + + // tick all block inputs + shared_bindings_synthio_lfo_tick(self->base.sample_rate, length / self->base.channel_count); + (void)synthio_block_slot_get(&self->semitones); + (void)synthio_block_slot_get(&self->mix); + + length = 0; + } else { + // we have a sample to play and apply effect + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t semitones = synthio_block_slot_get(&self->semitones); + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * MICROPY_FLOAT_CONST(2.0); + + // Only recalculate rate if semitones has changes + if (memcmp(&semitones, &self->current_semitones, sizeof(mp_float_t))) { + recalculate_rate(self, semitones); + } + + for (uint32_t i = 0; i < n; i++) { + bool buf_offset = (channel == 1 || i % self->base.channel_count == 1); + + int32_t sample_word = 0; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + + if (overlap_size) { + // Copy last sample from overlap and store in buffer + window_buffer[self->window_index + window_size * buf_offset] = overlap_buffer[self->overlap_index + overlap_size * buf_offset]; + + // Save current sample in overlap + overlap_buffer[self->overlap_index + overlap_size * buf_offset] = (int16_t)sample_word; + } else { + // Write sample to buffer + window_buffer[self->window_index + window_size * buf_offset] = (int16_t)sample_word; + } + + // Determine how far we are into the overlap + uint32_t read_index = self->read_index >> PITCH_READ_SHIFT; + uint32_t read_overlap_offset = read_index + window_size * (read_index < self->window_index) - self->window_index; + + // Read sample from buffer + int32_t word = (int32_t)window_buffer[read_index + window_size * buf_offset]; + + // Check if we're within the overlap range and mix buffer sample with overlap sample + if (overlap_size && read_overlap_offset > 0 && read_overlap_offset <= overlap_size) { + // Apply volume based on overlap position to buffer sample + word *= (int32_t)read_overlap_offset; + + // Add overlap with volume based on overlap position + word += (int32_t)overlap_buffer[((self->overlap_index + read_overlap_offset) % overlap_size) + overlap_size * buf_offset] * (int32_t)(overlap_size - read_overlap_offset); + + // Scale down + word /= (int32_t)overlap_size; + } + + word = (int32_t)((sample_word * MIN(MICROPY_FLOAT_CONST(2.0) - mix, MICROPY_FLOAT_CONST(1.0))) + (word * MIN(mix, MICROPY_FLOAT_CONST(1.0)))); + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = (int16_t)word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + int8_t mixed = (int8_t)word; + if (self->base.samples_signed) { + hword_buffer[i] = mixed; + } else { + hword_buffer[i] = (uint8_t)mixed ^ 0x80; + } + } + + if (self->base.channel_count == 1 || buf_offset) { + // Increment window buffer write pointer + self->window_index++; + if (self->window_index >= window_size) { + self->window_index = 0; + } + + // Increment overlap buffer pointer + if (overlap_size) { + self->overlap_index++; + if (self->overlap_index >= overlap_size) { + self->overlap_index = 0; + } + } + + // Increment window buffer read pointer by rate + self->read_index += self->read_rate; + if (self->read_index >= window_size << PITCH_READ_SHIFT) { + self->read_index -= window_size << PITCH_READ_SHIFT; + } + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // PitchShift always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiodelays/PitchShift.h b/shared-module/audiodelays/PitchShift.h new file mode 100644 index 00000000000..dddcfa4efc0 --- /dev/null +++ b/shared-module/audiodelays/PitchShift.h @@ -0,0 +1,58 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/synthio/__init__.h" +#include "shared-module/synthio/block.h" + +#define PITCH_READ_SHIFT (8) + +extern const mp_obj_type_t audiodelays_pitch_shift_type; + +typedef struct { + audiosample_base_t base; + synthio_block_slot_t semitones; + mp_float_t current_semitones; + synthio_block_slot_t mix; + uint32_t window_len; + uint32_t overlap_len; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + int8_t *window_buffer; + uint32_t window_index; // words + + int8_t *overlap_buffer; + uint32_t overlap_index; // words + + uint32_t read_index; // words << PITCH_READ_SHIFT + uint32_t read_rate; // words << PITCH_READ_SHIFT + + mp_obj_t sample; +} audiodelays_pitch_shift_obj_t; + +void recalculate_rate(audiodelays_pitch_shift_obj_t *self, mp_float_t semitones); + +void audiodelays_pitch_shift_reset_buffer(audiodelays_pitch_shift_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiodelays_pitch_shift_get_buffer(audiodelays_pitch_shift_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiodelays/__init__.c b/shared-module/audiodelays/__init__.c new file mode 100644 index 00000000000..7b5abdb4ff3 --- /dev/null +++ b/shared-module/audiodelays/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus +// +// SPDX-License-Identifier: MIT diff --git a/shared-module/audiodelays/__init__.h b/shared-module/audiodelays/__init__.h new file mode 100644 index 00000000000..3bc9246e5bb --- /dev/null +++ b/shared-module/audiodelays/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Mark Komus +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-module/audiofilewriter/AudioFileWriter.c b/shared-module/audiofilewriter/AudioFileWriter.c new file mode 100644 index 00000000000..099345888a0 --- /dev/null +++ b/shared-module/audiofilewriter/AudioFileWriter.c @@ -0,0 +1,403 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/audiofilewriter/AudioFileWriter.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/audiocore/__init__.h" + +#include + +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include "supervisor/background_callback.h" +#include "supervisor/shared/tick.h" + +// --------------------------------------------------------------------------- +// Little-endian header helpers +// --------------------------------------------------------------------------- + +static void put_u16le(uint8_t *p, uint16_t v) { + p[0] = (uint8_t)v; + p[1] = (uint8_t)(v >> 8); +} + +static void put_u32le(uint8_t *p, uint32_t v) { + p[0] = (uint8_t)v; + p[1] = (uint8_t)(v >> 8); + p[2] = (uint8_t)(v >> 16); + p[3] = (uint8_t)(v >> 24); +} + +// --------------------------------------------------------------------------- +// Active-writer registry, walked once per supervisor tick. +// +// The list head lives in MP_STATE_VM (see MP_REGISTER_ROOT_POINTER below) so +// that (a) active writers and their reg_next chain are GC-rooted while +// recording, and (b) the list is wiped automatically when the VM heap is +// recreated on soft reset. +// --------------------------------------------------------------------------- + +#define REGISTRY_HEAD ((audiofilewriter_audiofilewriter_obj_t *)MP_STATE_VM(audiofilewriter_linked_list)) + +// Add self to the registry. Called from Python (play()) context, so it must +// guard against a background tick walking the list mid-mutation. +static void audiofilewriter_register(audiofilewriter_audiofilewriter_obj_t *self) { + background_callback_prevent(); + // Avoid double-linking if already present. + bool present = false; + for (audiofilewriter_audiofilewriter_obj_t *w = REGISTRY_HEAD; w != NULL; w = w->reg_next) { + if (w == self) { + present = true; + break; + } + } + if (!present) { + self->reg_next = REGISTRY_HEAD; + MP_STATE_VM(audiofilewriter_linked_list) = self; + } + background_callback_allow(); +} + +// Remove self from the registry. Callers must ensure no background tick is +// walking the list concurrently: either they are the background tick itself +// (single-threaded, so safe), or they wrap the call in prevent/allow. +static void audiofilewriter_unregister(audiofilewriter_audiofilewriter_obj_t *self) { + audiofilewriter_audiofilewriter_obj_t **pp = (audiofilewriter_audiofilewriter_obj_t **)&MP_STATE_VM(audiofilewriter_linked_list); + while (*pp != NULL) { + if (*pp == self) { + *pp = self->reg_next; + self->reg_next = NULL; + return; + } + pp = &(*pp)->reg_next; + } +} + +// --------------------------------------------------------------------------- +// RAM ring +// --------------------------------------------------------------------------- + +// Copy len bytes from src into the ring. The caller guarantees there is room. +// 8-bit signed PCM is flipped to unsigned to match the WAV convention. +static void audiofilewriter_ring_write(audiofilewriter_audiofilewriter_obj_t *self, const uint8_t *src, uint32_t len) { + bool flip = (self->bits_per_sample == 8 && self->samples_signed); + uint32_t i = 0; + while (i < len) { + uint32_t span = self->ring_size - self->ring_head; + if (span > (len - i)) { + span = len - i; + } + if (flip) { + for (uint32_t j = 0; j < span; j++) { + self->ring[self->ring_head + j] = src[i + j] ^ 0x80; + } + } else { + memcpy(self->ring + self->ring_head, src + i, span); + } + self->ring_head += span; + if (self->ring_head == self->ring_size) { + self->ring_head = 0; + } + i += span; + } + self->ring_count += len; +} + +// Drain the ring to the file. Returns false on a write error. Non-raising: +// safe to call from background-task context. +static bool audiofilewriter_flush(audiofilewriter_audiofilewriter_obj_t *self) { + while (self->ring_count > 0) { + uint32_t span = self->ring_size - self->ring_tail; + if (span > self->ring_count) { + span = self->ring_count; + } + int err = 0; + mp_uint_t wrote = mp_stream_write_exactly(self->file, self->ring + self->ring_tail, span, &err); + if (err != 0 || wrote != span) { + return false; + } + self->ring_tail += span; + if (self->ring_tail == self->ring_size) { + self->ring_tail = 0; + } + self->ring_count -= span; + self->data_bytes += span; + } + return true; +} + +// --------------------------------------------------------------------------- +// Header patching + finalize +// --------------------------------------------------------------------------- + +static void audiofilewriter_patch_header(audiofilewriter_audiofilewriter_obj_t *self) { + uint8_t sz[4]; + int err = 0; + + // RIFF chunk size lives at header_offset + 4. + put_u32le(sz, 36 + self->data_bytes); + if (mp_stream_seek(self->file, self->header_offset + 4, MP_SEEK_SET, &err) == (mp_off_t)-1) { + return; + } + mp_stream_write_exactly(self->file, sz, 4, &err); + + // data chunk size lives at header_offset + 40. + put_u32le(sz, self->data_bytes); + if (mp_stream_seek(self->file, self->header_offset + 40, MP_SEEK_SET, &err) == (mp_off_t)-1) { + return; + } + mp_stream_write_exactly(self->file, sz, 4, &err); + + // Leave the cursor at the end of the PCM so the caller can keep appending + // or simply close the file. + mp_stream_seek(self->file, self->header_offset + 44 + self->data_bytes, MP_SEEK_SET, &err); +} + +// Stop pumping, drain, patch the header, and release the source. Idempotent: +// only the first call (while playing) does work. Non-raising. +static void audiofilewriter_finalize(audiofilewriter_audiofilewriter_obj_t *self) { + if (!self->playing) { + return; + } + // Stop the pump first so a background tick can't re-enter us. + self->playing = false; + + audiofilewriter_flush(self); + audiofilewriter_patch_header(self); + + supervisor_disable_tick(); + audiofilewriter_unregister(self); + self->sample = MP_OBJ_NULL; +} + +// --------------------------------------------------------------------------- +// The pump: one real-time-paced step per supervisor tick +// --------------------------------------------------------------------------- + +static void audiofilewriter_pump(audiofilewriter_audiofilewriter_obj_t *self) { + if (!self->playing) { + return; + } + + // The pull granularity through the chain is one source buffer, so we pace + // in whole-buffer units. + int64_t frames_per_pull = (int64_t)(self->source_max_buffer / self->bytes_per_frame); + if (frames_per_pull < 1) { + frames_per_pull = 1; + } + + // Accrue a real-time sample budget from elapsed ticks. + uint64_t now = supervisor_ticks_ms64(); + uint64_t elapsed = now - self->last_tick_ms; + self->last_tick_ms = now; + // Ignore long gaps (GC pause, SD stall) so we don't try to catch up an + // unbounded backlog all at once. + if (elapsed > 100) { + elapsed = 100; + } + self->budget_frames += (int64_t)((elapsed * self->sample_rate) / 1000); + // Never bank more than a single buffer of catch-up. For a LIVE source the + // captured audio sits in the source's own bounded ring; once we fall more + // than that behind, the surplus is already gone, so a large banked budget + // cannot recover it -- it would only burst-drain the source on consecutive + // ticks and then silence-pad, stretching one stall into a long glitch. + // Capping at one buffer yields at most one brief discontinuity per stall. + if (self->budget_frames > frames_per_pull) { + self->budget_frames = frames_per_pull; + } + + // Pull one buffer only once a full buffer of real time has elapsed: strict + // real-time pacing so we never pull ahead of a live source (which would + // only hand back silence). Also require room for a full source buffer. + if (!self->source_done && self->budget_frames >= frames_per_pull && + (self->ring_size - self->ring_count) >= self->source_max_buffer) { + uint8_t *buf = NULL; + uint32_t len = 0; + audioio_get_buffer_result_t res = + audiosample_get_buffer(self->sample, false, 0, &buf, &len); + if (res == GET_BUFFER_ERROR) { + self->source_done = true; + } else { + if (len > 0 && buf != NULL) { + // Defend against a source that hands back more than it advertised. + if (len > self->source_max_buffer) { + len = self->source_max_buffer; + } + audiofilewriter_ring_write(self, buf, len); + self->budget_frames -= (int64_t)(len / self->bytes_per_frame); + } + if (res == GET_BUFFER_DONE) { + self->source_done = true; + } + } + } + + if (!audiofilewriter_flush(self)) { + // File write failed; give up gracefully rather than spin. + self->source_done = true; + } + + if (self->source_done && self->ring_count == 0) { + audiofilewriter_finalize(self); + } +} + +void audiofilewriter_background(void) { + audiofilewriter_audiofilewriter_obj_t *self = REGISTRY_HEAD; + while (self != NULL) { + // Capture next before pumping: pump() may finalize self, which unlinks + // it from the registry (but leaves our saved next pointer valid). + audiofilewriter_audiofilewriter_obj_t *next = self->reg_next; + audiofilewriter_pump(self); + self = next; + } +} + +// Called during soft reset (VM teardown). Any writer still active is abandoned: +// we don't try to touch its file (it may already be gone), we just balance the +// tick-enable count and drop it from the list. +void audiofilewriter_reset(void) { + audiofilewriter_audiofilewriter_obj_t *self = REGISTRY_HEAD; + while (self != NULL) { + audiofilewriter_audiofilewriter_obj_t *next = self->reg_next; + if (self->playing) { + self->playing = false; + supervisor_disable_tick(); + } + self->reg_next = NULL; + self = next; + } + MP_STATE_VM(audiofilewriter_linked_list) = NULL; +} + +// --------------------------------------------------------------------------- +// common-hal surface +// --------------------------------------------------------------------------- + +void common_hal_audiofilewriter_audiofilewriter_construct(audiofilewriter_audiofilewriter_obj_t *self, + mp_obj_t file, uint32_t buffer_size) { + // The file must be a writable, seekable binary stream (a file or BytesIO). + mp_get_stream_raise(file, MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL); + + self->file = file; + self->sample = MP_OBJ_NULL; + self->ring_size = buffer_size; + self->ring = m_malloc(buffer_size); + self->ring_head = 0; + self->ring_tail = 0; + self->ring_count = 0; + self->playing = false; + self->source_done = false; + self->reg_next = NULL; +} + +bool common_hal_audiofilewriter_audiofilewriter_deinited(audiofilewriter_audiofilewriter_obj_t *self) { + return self->ring == NULL; +} + +void common_hal_audiofilewriter_audiofilewriter_deinit(audiofilewriter_audiofilewriter_obj_t *self) { + if (self->playing) { + common_hal_audiofilewriter_audiofilewriter_stop(self); + } + self->ring = NULL; + self->file = MP_OBJ_NULL; + self->sample = MP_OBJ_NULL; +} + +void common_hal_audiofilewriter_audiofilewriter_play(audiofilewriter_audiofilewriter_obj_t *self, mp_obj_t sample_obj) { + if (self->playing) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Already in progress")); + } + + audiosample_base_t *sample = audiosample_check(sample_obj); + uint32_t rate = audiosample_get_sample_rate(sample); + uint8_t channels = audiosample_get_channel_count(sample); + uint8_t bits = audiosample_get_bits_per_sample(sample); + bool single_buffer, samples_signed; + uint32_t max_buffer_length; + uint8_t spacing; + audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, + &max_buffer_length, &spacing); + + if ((bits != 8 && bits != 16) || channels < 1 || channels > 2) { + mp_raise_ValueError(MP_ERROR_TEXT("Only 8/16-bit mono/stereo is supported")); + } + if (max_buffer_length == 0 || self->ring_size < max_buffer_length) { + mp_raise_ValueError(MP_ERROR_TEXT("buffer_size too small for source")); + } + + self->sample_rate = rate; + self->channel_count = channels; + self->bits_per_sample = bits; + self->samples_signed = samples_signed; + self->bytes_per_frame = (uint8_t)(channels * (bits / 8)); + self->source_max_buffer = max_buffer_length; + + // Remember where the header starts so stop() can patch its size fields, + // then write a placeholder header with zeroed sizes. + int err = 0; + mp_off_t off = mp_stream_seek(self->file, 0, MP_SEEK_CUR, &err); + if (off == (mp_off_t)-1) { + mp_raise_OSError(err ? err : MP_EIO); + } + self->header_offset = (uint32_t)off; + + uint32_t block_align = self->bytes_per_frame; + uint32_t byte_rate = rate * block_align; + uint8_t hdr[44]; + memcpy(hdr + 0, "RIFF", 4); + put_u32le(hdr + 4, 36); // RIFF size (patched at stop) + memcpy(hdr + 8, "WAVE", 4); + memcpy(hdr + 12, "fmt ", 4); + put_u32le(hdr + 16, 16); // fmt chunk size + put_u16le(hdr + 20, 1); // PCM + put_u16le(hdr + 22, channels); + put_u32le(hdr + 24, rate); + put_u32le(hdr + 28, byte_rate); + put_u16le(hdr + 32, (uint16_t)block_align); + put_u16le(hdr + 34, bits); + memcpy(hdr + 36, "data", 4); + put_u32le(hdr + 40, 0); // data size (patched at stop) + + err = 0; + mp_uint_t wrote = mp_stream_write_exactly(self->file, hdr, sizeof(hdr), &err); + if (err != 0 || wrote != sizeof(hdr)) { + mp_raise_OSError(err ? err : MP_EIO); + } + + audiosample_reset_buffer(sample_obj, false, 0); + + self->sample = sample_obj; + self->ring_head = 0; + self->ring_tail = 0; + self->ring_count = 0; + self->budget_frames = 0; + self->data_bytes = 0; + self->source_done = false; + self->last_tick_ms = supervisor_ticks_ms64(); + self->playing = true; + + audiofilewriter_register(self); + supervisor_enable_tick(); +} + +void common_hal_audiofilewriter_audiofilewriter_stop(audiofilewriter_audiofilewriter_obj_t *self) { + if (!self->playing) { + return; + } + // Keep the background pump out while we finalize from Python context. + background_callback_prevent(); + audiofilewriter_finalize(self); + background_callback_allow(); +} + +bool common_hal_audiofilewriter_audiofilewriter_get_playing(audiofilewriter_audiofilewriter_obj_t *self) { + return self->playing; +} + +MP_REGISTER_ROOT_POINTER(mp_obj_t audiofilewriter_linked_list); diff --git a/shared-module/audiofilewriter/AudioFileWriter.h b/shared-module/audiofilewriter/AudioFileWriter.h new file mode 100644 index 00000000000..0e99e90e915 --- /dev/null +++ b/shared-module/audiofilewriter/AudioFileWriter.h @@ -0,0 +1,67 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" + +// A streaming WAV *sink*: it consumes an audiosample source (a mic, synthio, +// or an effect chain) and writes the resulting PCM to a file. Unlike WaveFile +// it is NOT an audiosample, it is the thing that drives a source, playing the +// role an AudioOut would. +typedef struct _audiofilewriter_audiofilewriter_obj_t { + mp_obj_base_t base; + + // Output stream (anything with write + MP_STREAM_SEEK ioctl: a file or a + // BytesIO). Held so it stays referenced while recording. + mp_obj_t file; + // The source being recorded. Only valid (and referenced) while playing. + mp_obj_t sample; + + // Format, captured from the source at play() time. AudioFileWriter is the + // format authority for the WAV header. + uint32_t sample_rate; + uint8_t channel_count; + uint8_t bits_per_sample; + bool samples_signed; + uint8_t bytes_per_frame; // channel_count * bits_per_sample / 8 + uint32_t source_max_buffer; // largest buffer the source can hand back, bytes + + // RAM ring that decouples SD-write latency from the source. Written by the + // pump, drained to the file by the pump. Only touched from background-task + // context (never an ISR), so no locking is needed. + uint8_t *ring; + uint32_t ring_size; // capacity in bytes + uint32_t ring_head; // write cursor + uint32_t ring_tail; // read cursor + uint32_t ring_count; // bytes currently buffered + + // Real-time pacing: budget accrues sample_rate frames per second of elapsed + // supervisor ticks; a buffer is pulled only when budget is positive. + int64_t budget_frames; + uint64_t last_tick_ms; + + // Absolute file offset of the RIFF header start, so stop() can seek back and + // patch the two size fields once the final length is known. + uint32_t header_offset; + uint32_t data_bytes; // total PCM bytes handed to the file + + bool playing; + bool source_done; // source returned DONE/ERROR; drain then finalize + + // Intrusive linked list of active writers, walked once per supervisor tick. + struct _audiofilewriter_audiofilewriter_obj_t *reg_next; +} audiofilewriter_audiofilewriter_obj_t; + +// Called once per supervisor tick (from supervisor_background_tick), in +// background-task context. Pumps every active writer. +void audiofilewriter_background(void); + +// Called during soft reset to abandon any writer left recording. +void audiofilewriter_reset(void); diff --git a/shared-module/audiofilewriter/__init__.c b/shared-module/audiofilewriter/__init__.c new file mode 100644 index 00000000000..584c821b996 --- /dev/null +++ b/shared-module/audiofilewriter/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT diff --git a/shared-module/audiofilters/Distortion.c b/shared-module/audiofilters/Distortion.c new file mode 100644 index 00000000000..cf7125c5cee --- /dev/null +++ b/shared-module/audiofilters/Distortion.c @@ -0,0 +1,362 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include +#include "py/obj.h" +#include "py/runtime.h" +#include +#include "shared-bindings/audiofilters/Distortion.h" +#include "shared-module/audiofilters/Distortion.h" +#include "shared-bindings/audiocore/__init__.h" + +/** + * Based on Godot's AudioEffectDistortion + * - https://docs.godotengine.org/en/stable/classes/class_audioeffectdistortion.html + * - https://github.com/godotengine/godot/blob/master/servers/audio/effects/audio_effect_distortion.cpp + */ + +void common_hal_audiofilters_distortion_construct(audiofilters_distortion_obj_t *self, + mp_obj_t drive, mp_obj_t pre_gain, mp_obj_t post_gain, + audiofilters_distortion_mode mode, bool soft_clip, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, bool samples_signed, + uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiofilters_distortion_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_without_collect(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiofilters_distortion_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the effect's starting values. + + synthio_block_assign_slot(drive, &self->drive, MP_QSTR_drive); + synthio_block_assign_slot(pre_gain, &self->pre_gain, MP_QSTR_pre_gain); + synthio_block_assign_slot(post_gain, &self->post_gain, MP_QSTR_post_gain); + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + self->mode = mode; + self->soft_clip = soft_clip; +} + +void common_hal_audiofilters_distortion_deinit(audiofilters_distortion_obj_t *self) { + audiosample_mark_deinit(&self->base); + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +mp_obj_t common_hal_audiofilters_distortion_get_drive(audiofilters_distortion_obj_t *self) { + return self->drive.obj; +} + +void common_hal_audiofilters_distortion_set_drive(audiofilters_distortion_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->drive, MP_QSTR_drive); +} + +mp_obj_t common_hal_audiofilters_distortion_get_pre_gain(audiofilters_distortion_obj_t *self) { + return self->pre_gain.obj; +} + +void common_hal_audiofilters_distortion_set_pre_gain(audiofilters_distortion_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->pre_gain, MP_QSTR_pre_gain); +} + +mp_obj_t common_hal_audiofilters_distortion_get_post_gain(audiofilters_distortion_obj_t *self) { + return self->post_gain.obj; +} + +void common_hal_audiofilters_distortion_set_post_gain(audiofilters_distortion_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->post_gain, MP_QSTR_post_gain); +} + +audiofilters_distortion_mode common_hal_audiofilters_distortion_get_mode(audiofilters_distortion_obj_t *self) { + return self->mode; +} + +void common_hal_audiofilters_distortion_set_mode(audiofilters_distortion_obj_t *self, audiofilters_distortion_mode arg) { + self->mode = arg; +} + +bool common_hal_audiofilters_distortion_get_soft_clip(audiofilters_distortion_obj_t *self) { + return self->soft_clip; +} + +void common_hal_audiofilters_distortion_set_soft_clip(audiofilters_distortion_obj_t *self, bool soft_clip) { + self->soft_clip = soft_clip; +} + +mp_obj_t common_hal_audiofilters_distortion_get_mix(audiofilters_distortion_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiofilters_distortion_set_mix(audiofilters_distortion_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +void audiofilters_distortion_reset_buffer(audiofilters_distortion_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); +} + +bool common_hal_audiofilters_distortion_get_playing(audiofilters_distortion_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiofilters_distortion_play(audiofilters_distortion_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiofilters_distortion_stop(audiofilters_distortion_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + self->sample = NULL; + return; +} + +static mp_float_t db_to_linear(mp_float_t value) { + return MICROPY_FLOAT_C_FUN(exp)(value * MICROPY_FLOAT_CONST(0.11512925464970228420089957273422)); +} + +audioio_get_buffer_result_t audiofilters_distortion_get_buffer(audiofilters_distortion_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + if (self->sample == NULL) { + if (self->base.samples_signed) { + memset(word_buffer, 0, length * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + memset(word_buffer, 32768, length * (self->base.bits_per_sample / 8)); + } else { + memset(hword_buffer, 128, length * (self->base.bits_per_sample / 8)); + } + } + + // tick all block inputs + shared_bindings_synthio_lfo_tick(self->base.sample_rate, length / self->base.channel_count); + (void)synthio_block_slot_get(&self->drive); + (void)synthio_block_slot_get(&self->pre_gain); + (void)synthio_block_slot_get(&self->post_gain); + (void)synthio_block_slot_get(&self->mix); + + length = 0; + } else { + // we have a sample to play and apply effect + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t drive = synthio_block_slot_get_limited(&self->drive, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + mp_float_t pre_gain = db_to_linear(synthio_block_slot_get_limited(&self->pre_gain, MICROPY_FLOAT_CONST(-60.0), MICROPY_FLOAT_CONST(60.0))); + mp_float_t post_gain = db_to_linear(synthio_block_slot_get_limited(&self->post_gain, MICROPY_FLOAT_CONST(-80.0), MICROPY_FLOAT_CONST(24.0))); + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + + // Modify drive value depending on mode + uint32_t word_mask = 0; + if (self->mode == DISTORTION_MODE_CLIP) { + drive = MICROPY_FLOAT_CONST(1.0001) - drive; + } else if (self->mode == DISTORTION_MODE_WAVESHAPE) { + drive = MICROPY_FLOAT_CONST(2.0) * drive / (MICROPY_FLOAT_CONST(1.0001) - drive); + } else if (self->mode == DISTORTION_MODE_LOFI) { + word_mask = 0xFFFFFFFF ^ ((1 << (uint32_t)MICROPY_FLOAT_C_FUN(round)(drive * MICROPY_FLOAT_CONST(14.0))) - 1); + } + + if (mix <= MICROPY_FLOAT_CONST(0.01)) { // if mix is zero pure sample only + for (uint32_t i = 0; i < n; i++) { + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = sample_src[i]; + } else { + hword_buffer[i] = sample_hsrc[i]; + } + } + } else { + for (uint32_t i = 0; i < n; i++) { + int32_t sample_word = 0; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + + // Apply pre-gain + int32_t word = (int32_t)(sample_word * pre_gain); + + // Apply bit mask before converting to float + if (self->mode == DISTORTION_MODE_LOFI) { + word = word & word_mask; + } + + if (self->mode != DISTORTION_MODE_LOFI || self->soft_clip) { + // Convert sample to float + mp_float_t wordf = word / MICROPY_FLOAT_CONST(32768.0); + + switch (self->mode) { + case DISTORTION_MODE_CLIP: { + wordf = MICROPY_FLOAT_C_FUN(pow)(MICROPY_FLOAT_C_FUN(fabs)(wordf), drive); + if (word < 0) { + wordf *= MICROPY_FLOAT_CONST(-1.0); + } + } break; + case DISTORTION_MODE_LOFI: + break; + case DISTORTION_MODE_OVERDRIVE: { + wordf *= MICROPY_FLOAT_CONST(0.686306); + mp_float_t z = MICROPY_FLOAT_CONST(1.0) + MICROPY_FLOAT_C_FUN(exp)(MICROPY_FLOAT_C_FUN(sqrt)(MICROPY_FLOAT_C_FUN(fabs)(wordf)) * MICROPY_FLOAT_CONST(-0.75)); + mp_float_t word_exp = MICROPY_FLOAT_C_FUN(exp)(wordf); + wordf *= MICROPY_FLOAT_CONST(-1.0); + wordf = (word_exp - MICROPY_FLOAT_C_FUN(exp)(wordf * z)) / (word_exp + MICROPY_FLOAT_C_FUN(exp)(wordf)); + } break; + case DISTORTION_MODE_WAVESHAPE: { + wordf = (MICROPY_FLOAT_CONST(1.0) + drive) * wordf / (MICROPY_FLOAT_CONST(1.0) + drive * MICROPY_FLOAT_C_FUN(fabs)(wordf)); + } break; + } + + // Apply post-gain + wordf = wordf * post_gain; + + // Soft clip + if (self->soft_clip) { + if (wordf > 0) { + wordf = MICROPY_FLOAT_CONST(1.0) - MICROPY_FLOAT_C_FUN(exp)(-wordf); + } else { + wordf = MICROPY_FLOAT_CONST(-1.0) + MICROPY_FLOAT_C_FUN(exp)(wordf); + } + } + + // Convert sample back to signed integer + word = (int32_t)(wordf * MICROPY_FLOAT_CONST(32767.0)); + } else { + // Apply post-gain + word = (int32_t)(word * post_gain); + } + + // Hard clip + if (!self->soft_clip) { + word = MIN(MAX(word, -32767), 32768); + } + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = (int16_t)((sample_word * (MICROPY_FLOAT_CONST(1.0) - mix)) + (word * mix)); + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + int8_t mixed = (int8_t)((sample_word * (MICROPY_FLOAT_CONST(1.0) - mix)) + (word * mix)); + if (self->base.samples_signed) { + hword_buffer[i] = mixed; + } else { + hword_buffer[i] = (uint8_t)mixed ^ 0x80; + } + } + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // Distortion always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiofilters/Distortion.h b/shared-module/audiofilters/Distortion.h new file mode 100644 index 00000000000..ddfa1231e64 --- /dev/null +++ b/shared-module/audiofilters/Distortion.h @@ -0,0 +1,51 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-bindings/audiofilters/Distortion.h" +#include "shared-module/audiocore/__init__.h" +#include "shared-module/synthio/block.h" + +typedef enum { + DISTORTION_MODE_CLIP, + DISTORTION_MODE_LOFI, + DISTORTION_MODE_OVERDRIVE, + DISTORTION_MODE_WAVESHAPE, +} audiofilters_distortion_mode; + +extern const mp_obj_type_t audiofilters_distortion_type; + +typedef struct { + audiosample_base_t base; + synthio_block_slot_t drive; + synthio_block_slot_t pre_gain; + synthio_block_slot_t post_gain; + audiofilters_distortion_mode mode; + bool soft_clip; + synthio_block_slot_t mix; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + mp_obj_t sample; +} audiofilters_distortion_obj_t; + +void audiofilters_distortion_reset_buffer(audiofilters_distortion_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiofilters_distortion_get_buffer(audiofilters_distortion_obj_t *self, + bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length); diff --git a/shared-module/audiofilters/Filter.c b/shared-module/audiofilters/Filter.c new file mode 100644 index 00000000000..a5351edecc4 --- /dev/null +++ b/shared-module/audiofilters/Filter.c @@ -0,0 +1,273 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiofilters/Filter.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/synthio/Biquad.h" + +#include +#include "py/runtime.h" + +void common_hal_audiofilters_filter_construct(audiofilters_filter_obj_t *self, + mp_obj_t filter, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_without_collect(self->buffer_len); + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_without_collect(self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // This buffer will be used to process samples through the biquad filter + self->filter_buffer = m_malloc_without_collect(SYNTHIO_MAX_DUR * self->base.channel_count * sizeof(int32_t)); + memset(self->filter_buffer, 0, SYNTHIO_MAX_DUR * self->base.channel_count * sizeof(int32_t)); + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the effect's starting values. + + common_hal_audiofilters_filter_set_filter(self, filter); + + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); +} + +void common_hal_audiofilters_filter_deinit(audiofilters_filter_obj_t *self) { + audiosample_mark_deinit(&self->base); + audiofilters_deinit_filter_chain(&self->filter); + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +void common_hal_audiofilters_filter_set_filter(audiofilters_filter_obj_t *self, mp_obj_t filter_in) { + audiofilters_assign_filter_chain(&self->filter, filter_in, self->base.channel_count); +} + +mp_obj_t common_hal_audiofilters_filter_get_filter(audiofilters_filter_obj_t *self) { + return self->filter.obj; +} + +mp_obj_t common_hal_audiofilters_filter_get_mix(audiofilters_filter_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiofilters_filter_set_mix(audiofilters_filter_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +void audiofilters_filter_reset_buffer(audiofilters_filter_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->filter_buffer, 0, SYNTHIO_MAX_DUR * self->base.channel_count * sizeof(int32_t)); + + audiofilters_reset_filter_chain(&self->filter, self->base.channel_count); +} + +bool common_hal_audiofilters_filter_get_playing(audiofilters_filter_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiofilters_filter_play(audiofilters_filter_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiofilters_filter_stop(audiofilters_filter_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + self->sample = NULL; + return; +} + +audioio_get_buffer_result_t audiofilters_filter_get_buffer(audiofilters_filter_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + (void)channel; + + if (!single_channel_output) { + channel = 0; + } + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + if (self->sample == NULL) { + // tick all block inputs + shared_bindings_synthio_lfo_tick(self->base.sample_rate, length / self->base.channel_count); + (void)synthio_block_slot_get(&self->mix); + + // Tick biquad filters + audiofilters_tick_filter_chain(&self->filter); + + if (self->base.samples_signed) { + memset(word_buffer, 0, length * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + uint16_t *uword_buffer = (uint16_t *)word_buffer; + while (length--) { + *uword_buffer++ = 32768; + } + } else { + memset(hword_buffer, 128, length * (self->base.bits_per_sample / 8)); + } + } + + length = 0; + } else { + // we have a sample to play and filter + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + + if (mix <= MICROPY_FLOAT_CONST(0.01) || !self->filter.states) { // if mix is zero pure sample only or no biquad filter objects are provided + for (uint32_t i = 0; i < n; i++) { + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = sample_src[i]; + } else { + hword_buffer[i] = sample_hsrc[i]; + } + } + } else { + uint32_t i = 0; + while (i < n) { + uint32_t n_samples = MIN(SYNTHIO_MAX_DUR, (n - i) >> (self->base.channel_count - 1)); + + // Fill filter buffer with samples + for (uint32_t j = 0; j < n_samples * self->base.channel_count; j++) { + bool buf_offset = (j % self->base.channel_count) == 1; + uint32_t k = j / self->base.channel_count; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + self->filter_buffer[k + SYNTHIO_MAX_DUR * buf_offset] = sample_src[i + j]; + } else { + if (self->base.samples_signed) { + self->filter_buffer[k + SYNTHIO_MAX_DUR * buf_offset] = sample_hsrc[i + j]; + } else { + // Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed + self->filter_buffer[k + SYNTHIO_MAX_DUR * buf_offset] = (int8_t)(((uint8_t)sample_hsrc[i + j]) ^ 0x80); + } + } + } + + // Process biquad filters + for (uint8_t j = 0; j < self->filter.objs_len; j++) { + mp_obj_t filter_obj = self->filter.objs[j]; + common_hal_synthio_biquad_tick(filter_obj); + for (uint8_t k = 0; k < self->base.channel_count; k++) { + synthio_biquad_filter_samples(filter_obj, &self->filter.states[j * self->base.channel_count + k], self->filter_buffer + k * SYNTHIO_MAX_DUR, n_samples); + } + } + + // Mix processed signal with original sample and transfer to output buffer + for (uint32_t j = 0; j < n_samples * self->base.channel_count; j++) { + bool buf_offset = (j % self->base.channel_count) == 1; + uint32_t k = j / self->base.channel_count; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i + j] = synthio_mix_down_sample((int32_t)((sample_src[i + j] * (MICROPY_FLOAT_CONST(1.0) - mix)) + (self->filter_buffer[k + SYNTHIO_MAX_DUR * buf_offset] * mix)), SYNTHIO_MIX_DOWN_SCALE(2)); + if (!self->base.samples_signed) { + word_buffer[i + j] ^= 0x8000; + } + } else { + if (self->base.samples_signed) { + hword_buffer[i + j] = (int8_t)((sample_hsrc[i + j] * (MICROPY_FLOAT_CONST(1.0) - mix)) + (self->filter_buffer[k + SYNTHIO_MAX_DUR * buf_offset] * mix)); + } else { + hword_buffer[i + j] = (uint8_t)(((int8_t)(((uint8_t)sample_hsrc[i + j]) ^ 0x80) * (MICROPY_FLOAT_CONST(1.0) - mix)) + (self->filter_buffer[k + SYNTHIO_MAX_DUR * buf_offset] * mix)) ^ 0x80; + } + } + } + + i += n_samples * self->base.channel_count; + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // Filter always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiofilters/Filter.h b/shared-module/audiofilters/Filter.h new file mode 100644 index 00000000000..6cb352d4273 --- /dev/null +++ b/shared-module/audiofilters/Filter.h @@ -0,0 +1,47 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-bindings/synthio/Biquad.h" +#include "shared-module/audiocore/__init__.h" +#include "shared-module/audiofilters/__init__.h" +#include "shared-module/synthio/__init__.h" +#include "shared-module/synthio/block.h" +#include "shared-module/synthio/Biquad.h" + +extern const mp_obj_type_t audiofilters_filter_type; + +typedef struct { + audiosample_base_t base; + audiofilters_filter_chain_t filter; + synthio_block_slot_t mix; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + int32_t *filter_buffer; + + bool loop; + bool more_data; + + mp_obj_t sample; +} audiofilters_filter_obj_t; + +void audiofilters_filter_reset_buffer(audiofilters_filter_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiofilters_filter_get_buffer(audiofilters_filter_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiofilters/Phaser.c b/shared-module/audiofilters/Phaser.c new file mode 100644 index 00000000000..368824b4b43 --- /dev/null +++ b/shared-module/audiofilters/Phaser.c @@ -0,0 +1,308 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#include "shared-bindings/audiofilters/Phaser.h" +#include "shared-bindings/audiocore/__init__.h" + +#include +#include "py/runtime.h" + +void common_hal_audiofilters_phaser_construct(audiofilters_phaser_obj_t *self, + mp_obj_t frequency, mp_obj_t feedback, mp_obj_t mix, uint8_t stages, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_without_collect(self->buffer_len); + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_without_collect(self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the effect's starting values. + + // Create buffer to hold the last processed word + self->word_buffer = m_malloc_without_collect(self->base.channel_count * sizeof(int16_t)); + memset(self->word_buffer, 0, self->base.channel_count * sizeof(int16_t)); + + self->nyquist = (mp_float_t)self->base.sample_rate / 2; + + if (feedback == mp_const_none) { + feedback = mp_obj_new_float(MICROPY_FLOAT_CONST(0.7)); + } + + synthio_block_assign_slot(frequency, &self->frequency, MP_QSTR_frequency); + synthio_block_assign_slot(feedback, &self->feedback, MP_QSTR_feedback); + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + + common_hal_audiofilters_phaser_set_stages(self, stages); +} + +void common_hal_audiofilters_phaser_deinit(audiofilters_phaser_obj_t *self) { + audiosample_mark_deinit(&self->base); + self->buffer[0] = NULL; + self->buffer[1] = NULL; + self->word_buffer = NULL; + self->allpass_buffer = NULL; +} + +mp_obj_t common_hal_audiofilters_phaser_get_frequency(audiofilters_phaser_obj_t *self) { + return self->frequency.obj; +} + +void common_hal_audiofilters_phaser_set_frequency(audiofilters_phaser_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->frequency, MP_QSTR_frequency); +} + +mp_obj_t common_hal_audiofilters_phaser_get_feedback(audiofilters_phaser_obj_t *self) { + return self->feedback.obj; +} + +void common_hal_audiofilters_phaser_set_feedback(audiofilters_phaser_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->feedback, MP_QSTR_feedback); +} + +mp_obj_t common_hal_audiofilters_phaser_get_mix(audiofilters_phaser_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiofilters_phaser_set_mix(audiofilters_phaser_obj_t *self, mp_obj_t arg) { + synthio_block_assign_slot(arg, &self->mix, MP_QSTR_mix); +} + +uint8_t common_hal_audiofilters_phaser_get_stages(audiofilters_phaser_obj_t *self) { + return self->stages; +} + +void common_hal_audiofilters_phaser_set_stages(audiofilters_phaser_obj_t *self, uint8_t arg) { + if (!arg) { + arg = 1; + } + + self->allpass_buffer = (int16_t *)m_realloc(self->allpass_buffer, + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + self->base.channel_count * self->stages * sizeof(int16_t), // Old size + #endif + self->base.channel_count * arg * sizeof(int16_t)); + self->stages = arg; + + memset(self->allpass_buffer, 0, self->base.channel_count * self->stages * sizeof(int16_t)); +} + +void audiofilters_phaser_reset_buffer(audiofilters_phaser_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + memset(self->word_buffer, 0, self->base.channel_count * sizeof(int16_t)); + memset(self->allpass_buffer, 0, self->base.channel_count * self->stages * sizeof(int16_t)); +} + +bool common_hal_audiofilters_phaser_get_playing(audiofilters_phaser_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiofilters_phaser_play(audiofilters_phaser_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiofilters_phaser_stop(audiofilters_phaser_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + self->sample = NULL; + return; +} + +audioio_get_buffer_result_t audiofilters_phaser_get_buffer(audiofilters_phaser_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + (void)channel; + + if (!single_channel_output) { + channel = 0; + } + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // If we are using 16 bit samples we need a 16 bit pointer, 8 bit needs an 8 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + int8_t *hword_buffer = self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + if (self->sample == NULL) { + // tick all block inputs + shared_bindings_synthio_lfo_tick(self->base.sample_rate, length / self->base.channel_count); + (void)synthio_block_slot_get(&self->frequency); + (void)synthio_block_slot_get(&self->feedback); + (void)synthio_block_slot_get(&self->mix); + + if (self->base.samples_signed) { + memset(word_buffer, 0, length * (self->base.bits_per_sample / 8)); + } else { + // For unsigned samples set to the middle which is "quiet" + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + uint16_t *uword_buffer = (uint16_t *)word_buffer; + while (length--) { + *uword_buffer++ = 32768; + } + } else { + memset(hword_buffer, 128, length * (self->base.bits_per_sample / 8)); + } + } + + length = 0; + } else { + // we have a sample to play and filter + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; // for 16-bit samples + int8_t *sample_hsrc = (int8_t *)self->sample_remaining_buffer; // for 8-bit samples + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t frequency = synthio_block_slot_get_limited(&self->frequency, MICROPY_FLOAT_CONST(0.0), self->nyquist); + int16_t feedback = (int16_t)(synthio_block_slot_get_limited(&self->feedback, MICROPY_FLOAT_CONST(0.1), MICROPY_FLOAT_CONST(0.9)) * 32767); + int16_t mix = (int16_t)(synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * 32767); + + if (mix <= 328) { // if mix is zero (0.01 in fixed point), pure sample only + for (uint32_t i = 0; i < n; i++) { + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = sample_src[i]; + } else { + hword_buffer[i] = sample_hsrc[i]; + } + } + } else { + // Update all-pass filter coefficient + frequency /= self->nyquist; // scale relative to frequency range + int16_t allpasscoef = (int16_t)((MICROPY_FLOAT_CONST(1.0) - frequency) / (MICROPY_FLOAT_CONST(1.0) + frequency) * 32767); + + for (uint32_t i = 0; i < n; i++) { + bool right_channel = (single_channel_output && channel == 1) || (!single_channel_output && (i % self->base.channel_count) == 1); + uint32_t allpass_buffer_offset = self->stages * right_channel; + + int32_t sample_word = 0; + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + sample_word = sample_src[i]; + } else { + if (self->base.samples_signed) { + sample_word = sample_hsrc[i]; + } else { + // Be careful here changing from an 8 bit unsigned to signed into a 32-bit signed + sample_word = (int8_t)(((uint8_t)sample_hsrc[i]) ^ 0x80); + } + } + + int32_t word = synthio_sat16(sample_word + synthio_sat16((int32_t)self->word_buffer[right_channel] * feedback, 15), 0); + int32_t allpass_word = 0; + + // Update all-pass filters + for (uint32_t j = 0; j < self->stages; j++) { + allpass_word = synthio_sat16(synthio_sat16(word * -allpasscoef, 15) + self->allpass_buffer[j + allpass_buffer_offset], 0); + self->allpass_buffer[j + allpass_buffer_offset] = synthio_sat16(synthio_sat16(allpass_word * allpasscoef, 15) + word, 0); + word = allpass_word; + } + self->word_buffer[(bool)allpass_buffer_offset] = (int16_t)word; + + // Add original sample + effect + word = sample_word + (int32_t)(synthio_sat16(word * mix, 15)); + word = synthio_mix_down_sample(word, 2); + + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + word_buffer[i] = word; + if (!self->base.samples_signed) { + word_buffer[i] ^= 0x8000; + } + } else { + int8_t out = word; + if (self->base.samples_signed) { + hword_buffer[i] = out; + } else { + hword_buffer[i] = (uint8_t)out ^ 0x80; + } + } + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + hword_buffer += n; + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // Phaser always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiofilters/Phaser.h b/shared-module/audiofilters/Phaser.h new file mode 100644 index 00000000000..f627b147014 --- /dev/null +++ b/shared-module/audiofilters/Phaser.h @@ -0,0 +1,49 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/synthio/__init__.h" +#include "shared-module/synthio/block.h" + +extern const mp_obj_type_t audiofilters_phaser_type; + +typedef struct { + audiosample_base_t base; + synthio_block_slot_t frequency; + synthio_block_slot_t feedback; + synthio_block_slot_t mix; + uint8_t stages; + + mp_float_t nyquist; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + int16_t *allpass_buffer; + int16_t *word_buffer; + + mp_obj_t sample; +} audiofilters_phaser_obj_t; + +void audiofilters_phaser_reset_buffer(audiofilters_phaser_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiofilters_phaser_get_buffer(audiofilters_phaser_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes diff --git a/shared-module/audiofilters/__init__.c b/shared-module/audiofilters/__init__.c new file mode 100644 index 00000000000..4b2ec0ed063 --- /dev/null +++ b/shared-module/audiofilters/__init__.c @@ -0,0 +1,76 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include "shared-module/audiofilters/__init__.h" + +void audiofilters_assign_filter_chain(audiofilters_filter_chain_t *self, mp_obj_t filter_in, uint8_t channel_count) { + size_t n_items; + mp_obj_t *items; + + if (filter_in == mp_const_none) { + n_items = 0; + items = NULL; + } else if (mp_obj_is_type(filter_in, &mp_type_tuple)) { + mp_obj_tuple_get(filter_in, &n_items, &items); + for (size_t i = 0; i < n_items; i++) { + if (!mp_obj_is_type(items[i], &synthio_biquad_type_obj)) { + mp_raise_TypeError_varg( + MP_ERROR_TEXT("%q in %q must be of type %q, not %q"), + MP_QSTR_object, + MP_QSTR_filter, + MP_QSTR_Biquad, + mp_obj_get_type(items[i])->name); + } + } + } else { + n_items = 1; + if (!mp_obj_is_type(filter_in, &synthio_biquad_type_obj)) { + mp_raise_TypeError_varg( + MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), + MP_QSTR_filter, MP_QSTR_Biquad, MP_QSTR_tuple, mp_obj_get_type(filter_in)->name); + } + items = &self->obj; + } + + // everything has been checked, so we can do the following without fear + + self->obj = filter_in; + self->states = m_renew(biquad_filter_state, + self->states, + self->objs_len * channel_count, + n_items * channel_count); + self->objs = items; + self->objs_len = n_items; +} + +void audiofilters_reset_filter_chain(audiofilters_filter_chain_t *self, uint8_t channel_count) { + if (self->states) { + for (uint8_t i = 0; i < self->objs_len * channel_count; i++) { + synthio_biquad_filter_reset(&self->states[i]); + } + } +} + +void audiofilters_tick_filter_chain(audiofilters_filter_chain_t *self) { + for (uint8_t j = 0; j < self->objs_len; j++) { + common_hal_synthio_biquad_tick(self->objs[j]); + } +} + +int32_t audiofilters_process_filter_chain(audiofilters_filter_chain_t *self, uint8_t channel_count, uint8_t channel, int32_t word) { + // Process biquad filters + for (uint8_t j = 0; j < self->objs_len; j++) { + word = synthio_biquad_filter_sample(self->objs[j], &self->states[j * channel_count + channel], word); + } + return word; +} + +void audiofilters_deinit_filter_chain(audiofilters_filter_chain_t *self) { + self->obj = mp_const_none; + self->objs = NULL; + self->objs_len = 0; + self->states = NULL; +} diff --git a/shared-module/audiofilters/__init__.h b/shared-module/audiofilters/__init__.h new file mode 100644 index 00000000000..2a5a933d96f --- /dev/null +++ b/shared-module/audiofilters/__init__.h @@ -0,0 +1,23 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/synthio/Biquad.h" + +typedef struct audiofilters_filter_chain { + mp_obj_t obj; + mp_obj_t *objs; + size_t objs_len; + biquad_filter_state *states; +} audiofilters_filter_chain_t; + +void audiofilters_assign_filter_chain(audiofilters_filter_chain_t *filter_chain, mp_obj_t filter_in, uint8_t channel_count); +void audiofilters_reset_filter_chain(audiofilters_filter_chain_t *filter_chain, uint8_t channel_count); +void audiofilters_tick_filter_chain(audiofilters_filter_chain_t *filter_chain); +int32_t audiofilters_process_filter_chain(audiofilters_filter_chain_t *filter_chain, uint8_t channel_count, uint8_t channel, int32_t word); +void audiofilters_deinit_filter_chain(audiofilters_filter_chain_t *self); diff --git a/shared-module/audiofreeverb/Freeverb.c b/shared-module/audiofreeverb/Freeverb.c new file mode 100644 index 00000000000..85aefb6fc61 --- /dev/null +++ b/shared-module/audiofreeverb/Freeverb.c @@ -0,0 +1,377 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT +// +// Based on FreeVerb - https://github.com/sinshu/freeverb/tree/main +// Fixed point ideas from - Paul Stoffregen in the Teensy audio library https://github.com/PaulStoffregen/Audio/blob/master/effect_freeverb.cpp +// +#include "shared-bindings/audiofreeverb/Freeverb.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-module/synthio/__init__.h" + +#include +#include "py/runtime.h" +#include + +void common_hal_audiofreeverb_freeverb_construct(audiofreeverb_freeverb_obj_t *self, mp_obj_t roomsize, mp_obj_t damp, mp_obj_t pre_filter, mp_obj_t post_filter, mp_obj_t mix, + uint32_t buffer_size, uint8_t bits_per_sample, + bool samples_signed, uint8_t channel_count, uint32_t sample_rate) { + + // Basic settings every effect and audio sample has + // These are the effects values, not the source sample(s) + self->base.bits_per_sample = bits_per_sample; // Most common is 16, but 8 is also supported in many places + self->base.samples_signed = samples_signed; // Are the samples we provide signed (common is true) + self->base.channel_count = channel_count; // Channels can be 1 for mono or 2 for stereo + self->base.sample_rate = sample_rate; // Sample rate for the effect, this generally needs to match all audio objects + self->base.single_buffer = false; + self->base.max_buffer_length = buffer_size; + + // To smooth things out as CircuitPython is doing other tasks most audio objects have a buffer + // A double buffer is set up here so the audio output can use DMA on buffer 1 while we + // write to and create buffer 2. + // This buffer is what is passed to the audio component that plays the effect. + // Samples are set sequentially. For stereo audio they are passed L/R/L/R/... + self->buffer_len = buffer_size; // in bytes + + self->buffer[0] = m_malloc_maybe(self->buffer_len); + if (self->buffer[0] == NULL) { + common_hal_audiofreeverb_freeverb_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[0], 0, self->buffer_len); + + self->buffer[1] = m_malloc_maybe(self->buffer_len); + if (self->buffer[1] == NULL) { + common_hal_audiofreeverb_freeverb_deinit(self); + m_malloc_fail(self->buffer_len); + } + memset(self->buffer[1], 0, self->buffer_len); + + self->last_buf_idx = 1; // Which buffer to use first, toggle between 0 and 1 + + // Initialize other values most effects will need. + self->sample = NULL; // The current playing sample + self->sample_remaining_buffer = NULL; // Pointer to the start of the sample buffer we have not played + self->sample_buffer_length = 0; // How many samples do we have left to play (these may be 16 bit!) + self->loop = false; // When the sample is done do we loop to the start again or stop (e.g. in a wav file) + self->more_data = false; // Is there still more data to read from the sample or did we finish + + // The below section sets up the reverb effect's starting values. For a different effect this section will change + common_hal_audiofreeverb_freeverb_set_pre_filter(self, pre_filter); + common_hal_audiofreeverb_freeverb_set_post_filter(self, post_filter); + + if (roomsize == MP_OBJ_NULL) { + roomsize = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(roomsize, &self->roomsize, MP_QSTR_roomsize); + common_hal_audiofreeverb_freeverb_set_roomsize(self, roomsize); + + if (damp == MP_OBJ_NULL) { + damp = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(damp, &self->damp, MP_QSTR_damp); + common_hal_audiofreeverb_freeverb_set_damp(self, damp); + + if (mix == MP_OBJ_NULL) { + mix = mp_obj_new_float(MICROPY_FLOAT_CONST(0.5)); + } + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); + common_hal_audiofreeverb_freeverb_set_mix(self, mix); + + // Set up the comb filters + // These values come from FreeVerb and are selected for the best reverb sound + self->combbuffersizes[0] = self->combbuffersizes[8] = 1116; + self->combbuffersizes[1] = self->combbuffersizes[9] = 1188; + self->combbuffersizes[2] = self->combbuffersizes[10] = 1277; + self->combbuffersizes[3] = self->combbuffersizes[11] = 1356; + self->combbuffersizes[4] = self->combbuffersizes[12] = 1422; + self->combbuffersizes[5] = self->combbuffersizes[13] = 1491; + self->combbuffersizes[6] = self->combbuffersizes[14] = 1557; + self->combbuffersizes[7] = self->combbuffersizes[15] = 1617; + for (uint32_t i = 0; i < 8 * channel_count; i++) { + self->combbuffers[i] = m_malloc_maybe(self->combbuffersizes[i] * sizeof(uint16_t)); + if (self->combbuffers[i] == NULL) { + common_hal_audiofreeverb_freeverb_deinit(self); + m_malloc_fail(self->combbuffersizes[i]); + } + memset(self->combbuffers[i], 0, self->combbuffersizes[i]); + + self->combbufferindex[i] = 0; + self->combfitlers[i] = 0; + } + + // Set up the allpass filters + // These values come from FreeVerb and are selected for the best reverb sound + self->allpassbuffersizes[0] = self->allpassbuffersizes[4] = 556; + self->allpassbuffersizes[1] = self->allpassbuffersizes[5] = 441; + self->allpassbuffersizes[2] = self->allpassbuffersizes[6] = 341; + self->allpassbuffersizes[3] = self->allpassbuffersizes[7] = 225; + for (uint32_t i = 0; i < 4 * channel_count; i++) { + self->allpassbuffers[i] = m_malloc_maybe(self->allpassbuffersizes[i] * sizeof(uint16_t)); + if (self->allpassbuffers[i] == NULL) { + common_hal_audiofreeverb_freeverb_deinit(self); + m_malloc_fail(self->allpassbuffersizes[i]); + } + memset(self->allpassbuffers[i], 0, self->allpassbuffersizes[i]); + + self->allpassbufferindex[i] = 0; + } +} + +bool common_hal_audiofreeverb_freeverb_deinited(audiofreeverb_freeverb_obj_t *self) { + if (self->buffer[0] == NULL) { + return true; + } + return false; +} + +void common_hal_audiofreeverb_freeverb_deinit(audiofreeverb_freeverb_obj_t *self) { + audiosample_mark_deinit(&self->base); + audiofilters_deinit_filter_chain(&self->pre_filter); + audiofilters_deinit_filter_chain(&self->post_filter); + self->buffer[0] = NULL; + self->buffer[1] = NULL; +} + +mp_obj_t common_hal_audiofreeverb_freeverb_get_roomsize(audiofreeverb_freeverb_obj_t *self) { + return self->roomsize.obj; +} + +void common_hal_audiofreeverb_freeverb_set_roomsize(audiofreeverb_freeverb_obj_t *self, mp_obj_t roomsize_obj) { + synthio_block_assign_slot(roomsize_obj, &self->roomsize, MP_QSTR_roomsize); +} + +int16_t audiofreeverb_freeverb_get_roomsize_fixedpoint(mp_float_t n) { + if (n > (mp_float_t)MICROPY_FLOAT_CONST(1.0)) { + n = MICROPY_FLOAT_CONST(1.0); + } else if (n < (mp_float_t)MICROPY_FLOAT_CONST(0.0)) { + n = MICROPY_FLOAT_CONST(0.0); + } + + return (int16_t)(n * (mp_float_t)MICROPY_FLOAT_CONST(9175.04)) + 22937; // 9175.04 = 0.28f in fixed point 22937 = 0.7f +} + +mp_obj_t common_hal_audiofreeverb_freeverb_get_damp(audiofreeverb_freeverb_obj_t *self) { + return self->damp.obj; +} + +void common_hal_audiofreeverb_freeverb_set_damp(audiofreeverb_freeverb_obj_t *self, mp_obj_t damp) { + synthio_block_assign_slot(damp, &self->damp, MP_QSTR_damp); +} + +void audiofreeverb_freeverb_get_damp_fixedpoint(mp_float_t n, int16_t *damp1, int16_t *damp2) { + if (n > (mp_float_t)MICROPY_FLOAT_CONST(1.0)) { + n = MICROPY_FLOAT_CONST(1.0); + } else if (n < (mp_float_t)MICROPY_FLOAT_CONST(0.0)) { + n = MICROPY_FLOAT_CONST(0.0); + } + + *damp1 = (int16_t)(n * (mp_float_t)MICROPY_FLOAT_CONST(13107.2)); // 13107.2 = 0.4f scaling factor + *damp2 = (int16_t)(32768 - *damp1); // inverse of x1 damp2 = 1.0 - damp1 +} + +mp_obj_t common_hal_audiofreeverb_freeverb_get_pre_filter(audiofreeverb_freeverb_obj_t *self) { + return self->pre_filter.obj; +} + +void common_hal_audiofreeverb_freeverb_set_pre_filter(audiofreeverb_freeverb_obj_t *self, mp_obj_t filter_in) { + audiofilters_assign_filter_chain(&self->pre_filter, filter_in, self->base.channel_count); +} + +mp_obj_t common_hal_audiofreeverb_freeverb_get_post_filter(audiofreeverb_freeverb_obj_t *self) { + return self->post_filter.obj; +} + +void common_hal_audiofreeverb_freeverb_set_post_filter(audiofreeverb_freeverb_obj_t *self, mp_obj_t filter_in) { + audiofilters_assign_filter_chain(&self->post_filter, filter_in, self->base.channel_count); +} + +mp_obj_t common_hal_audiofreeverb_freeverb_get_mix(audiofreeverb_freeverb_obj_t *self) { + return self->mix.obj; +} + +void common_hal_audiofreeverb_freeverb_set_mix(audiofreeverb_freeverb_obj_t *self, mp_obj_t mix) { + synthio_block_assign_slot(mix, &self->mix, MP_QSTR_mix); +} + +void audiofreeverb_freeverb_get_mix_fixedpoint(mp_float_t mix, int16_t *mix_sample, int16_t *mix_effect) { + mix = mix * (mp_float_t)MICROPY_FLOAT_CONST(2.0); + *mix_sample = (int16_t)(MIN((mp_float_t)MICROPY_FLOAT_CONST(2.0) - mix, (mp_float_t)MICROPY_FLOAT_CONST(1.0)) * 32767); + *mix_effect = (int16_t)(MIN(mix, (mp_float_t)MICROPY_FLOAT_CONST(1.0)) * 32767); +} + +void audiofreeverb_freeverb_reset_buffer(audiofreeverb_freeverb_obj_t *self, + bool single_channel_output, + uint8_t channel) { + + memset(self->buffer[0], 0, self->buffer_len); + memset(self->buffer[1], 0, self->buffer_len); + + audiofilters_reset_filter_chain(&self->pre_filter, self->base.channel_count); + audiofilters_reset_filter_chain(&self->post_filter, self->base.channel_count); +} + +bool common_hal_audiofreeverb_freeverb_get_playing(audiofreeverb_freeverb_obj_t *self) { + return self->sample != NULL; +} + +void common_hal_audiofreeverb_freeverb_play(audiofreeverb_freeverb_obj_t *self, mp_obj_t sample, bool loop) { + audiosample_must_match(&self->base, sample, false); + + self->sample = sample; + self->loop = loop; + + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + + // Track remaining sample length in terms of bytes per sample + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + // Store if we have more data in the sample to retrieve + self->more_data = result == GET_BUFFER_MORE_DATA; + + return; +} + +void common_hal_audiofreeverb_freeverb_stop(audiofreeverb_freeverb_obj_t *self) { + // When the sample is set to stop playing do any cleanup here + // For reverb we clear the sample but the reverb continues until the object reading our effect stops + self->sample = NULL; + return; +} + +audioio_get_buffer_result_t audiofreeverb_freeverb_get_buffer(audiofreeverb_freeverb_obj_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + // Switch our buffers to the other buffer + self->last_buf_idx = !self->last_buf_idx; + + // 16 bit samples we need a 16 bit pointer + int16_t *word_buffer = (int16_t *)self->buffer[self->last_buf_idx]; + uint32_t length = self->buffer_len / (self->base.bits_per_sample / 8); + + // Loop over the entire length of our buffer to fill it, this may require several calls to get data from the sample + while (length != 0) { + // Check if there is no more sample to play, we will either load more data, reset the sample if loop is on or clear the sample + if (self->sample_buffer_length == 0) { + if (!self->more_data) { // The sample has indicated it has no more data to play + if (self->loop && self->sample) { // If we are supposed to loop reset the sample to the start + audiosample_reset_buffer(self->sample, false, 0); + } else { // If we were not supposed to loop the sample, stop playing it but we still need to play the reverb + self->sample = NULL; + } + } + if (self->sample) { + // Load another sample buffer to play + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->sample_remaining_buffer, &self->sample_buffer_length); + if (result == GET_BUFFER_ERROR) { + self->sample = NULL; + self->sample_buffer_length = 0; + self->more_data = false; + } else { + // Track length in terms of words. + self->sample_buffer_length /= (self->base.bits_per_sample / 8); + self->more_data = result == GET_BUFFER_MORE_DATA; + } + } + } + + // Determine how many bytes we can process to our buffer, the less of the sample we have left and our buffer remaining + uint32_t n; + if (self->sample == NULL) { + n = MIN(length, SYNTHIO_MAX_DUR * self->base.channel_count); + } else { + n = MIN(MIN(self->sample_buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } + + // get the effect values we need from the BlockInput. These may change at run time so you need to do bounds checking if required + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + mp_float_t damp = synthio_block_slot_get_limited(&self->damp, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + int16_t damp1, damp2; + audiofreeverb_freeverb_get_damp_fixedpoint(damp, &damp1, &damp2); + + mp_float_t mix = synthio_block_slot_get_limited(&self->mix, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + int16_t mix_sample, mix_effect; + audiofreeverb_freeverb_get_mix_fixedpoint(mix, &mix_sample, &mix_effect); + + mp_float_t roomsize = synthio_block_slot_get_limited(&self->roomsize, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)); + int16_t feedback = audiofreeverb_freeverb_get_roomsize_fixedpoint(roomsize); + + // Tick biquad filters + audiofilters_tick_filter_chain(&self->pre_filter); + audiofilters_tick_filter_chain(&self->post_filter); + + int16_t *sample_src = (int16_t *)self->sample_remaining_buffer; + + for (uint32_t i = 0; i < n; i++) { + int32_t sample_word = 0; + if (self->sample != NULL) { + sample_word = sample_src[i]; + } + + int32_t word, sum; + int16_t input, bufout, output; + uint32_t channel_comb_offset = 0, channel_allpass_offset = 0; + + // Apply filters as Pre-EQ + input = (int16_t)audiofilters_process_filter_chain(&self->pre_filter, self->base.channel_count, n % self->base.channel_count, sample_word); + + input = synthio_sat16((int32_t)input * 8738, 17); // Initial input scaled down so we can add reverb + sum = 0; + + // Calculate each of the 8 comb buffers + for (uint32_t j = 0 + channel_comb_offset; j < 8 + channel_comb_offset; j++) { + bufout = self->combbuffers[j][self->combbufferindex[j]]; + sum += bufout; + self->combfitlers[j] = synthio_sat16(bufout * damp2 + self->combfitlers[j] * damp1, 15); + self->combbuffers[j][self->combbufferindex[j]] = synthio_sat16(input + synthio_sat16(self->combfitlers[j] * feedback, 15), 0); + if (++self->combbufferindex[j] >= self->combbuffersizes[j]) { + self->combbufferindex[j] = 0; + } + } + + output = synthio_sat16(sum * 31457, 17); // 31457 = 0.24f with shift of 17 + + // Calculate each of the 4 all pass buffers + for (uint32_t j = 0 + channel_allpass_offset; j < 4 + channel_allpass_offset; j++) { + bufout = self->allpassbuffers[j][self->allpassbufferindex[j]]; + self->allpassbuffers[j][self->allpassbufferindex[j]] = output + (bufout >> 1); // bufout >> 1 same as bufout*0.5f + output = synthio_sat16(bufout - output, 1); + if (++self->allpassbufferindex[j] >= self->allpassbuffersizes[j]) { + self->allpassbufferindex[j] = 0; + } + } + + // Apply filters as Post-EQ + output = (int16_t)audiofilters_process_filter_chain(&self->post_filter, self->base.channel_count, n % self->base.channel_count, (int32_t)output); + + word = output * 30; // Add some volume back don't have to saturate as next step will + + word = synthio_sat16(sample_word * mix_sample, 15) + synthio_sat16(word * mix_effect, 15); + word = synthio_mix_down_sample(word, SYNTHIO_MIX_DOWN_SCALE(2)); + word_buffer[i] = (int16_t)word; + + if ((self->base.channel_count == 2) && (channel_comb_offset == 0)) { + channel_comb_offset = 8; + channel_allpass_offset = 4; + } else { + channel_comb_offset = 0; + channel_allpass_offset = 0; + } + } + + // Update the remaining length and the buffer positions based on how much we wrote into our buffer + length -= n; + word_buffer += n; + self->sample_remaining_buffer += (n * (self->base.bits_per_sample / 8)); + self->sample_buffer_length -= n; + } + + // Finally pass our buffer and length to the calling audio function + *buffer = (uint8_t *)self->buffer[self->last_buf_idx]; + *buffer_length = self->buffer_len; + + // Reverb always returns more data but some effects may return GET_BUFFER_DONE or GET_BUFFER_ERROR (see audiocore/__init__.h) + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiofreeverb/Freeverb.h b/shared-module/audiofreeverb/Freeverb.h new file mode 100644 index 00000000000..1a60a64d39e --- /dev/null +++ b/shared-module/audiofreeverb/Freeverb.h @@ -0,0 +1,60 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT +#pragma once + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/audiofilters/__init__.h" +#include "shared-module/synthio/__init__.h" +#include "shared-module/synthio/block.h" +#include "shared-module/synthio/Biquad.h" + +extern const mp_obj_type_t audiofreeverb_freeverb_type; + +typedef struct { + audiosample_base_t base; + synthio_block_slot_t roomsize; + synthio_block_slot_t damp; + audiofilters_filter_chain_t pre_filter; + audiofilters_filter_chain_t post_filter; + synthio_block_slot_t mix; + + int8_t *buffer[2]; + uint8_t last_buf_idx; + uint32_t buffer_len; // max buffer in bytes + + uint8_t *sample_remaining_buffer; + uint32_t sample_buffer_length; + + bool loop; + bool more_data; + + int16_t combbuffersizes[16]; + int16_t *combbuffers[16]; + int16_t combbufferindex[16]; + int16_t combfitlers[16]; + + int16_t allpassbuffersizes[8]; + int16_t *allpassbuffers[8]; + int16_t allpassbufferindex[8]; + + mp_obj_t sample; +} audiofreeverb_freeverb_obj_t; + +void audiofreeverb_freeverb_reset_buffer(audiofreeverb_freeverb_obj_t *self, + bool single_channel_output, + uint8_t channel); + +audioio_get_buffer_result_t audiofreeverb_freeverb_get_buffer(audiofreeverb_freeverb_obj_t *self, + bool single_channel_output, + uint8_t channel, + uint8_t **buffer, + uint32_t *buffer_length); // length in bytes + +int16_t audiofreeverb_freeverb_get_roomsize_fixedpoint(mp_float_t n); +void audiofreeverb_freeverb_get_damp_fixedpoint(mp_float_t n, int16_t *damp1, int16_t *damp2); +void audiofreeverb_freeverb_get_mix_fixedpoint(mp_float_t mix, int16_t *mix_sample, int16_t *mix_effect); diff --git a/shared-module/audiofreeverb/__init__.c b/shared-module/audiofreeverb/__init__.c new file mode 100644 index 00000000000..94cd4caa3bd --- /dev/null +++ b/shared-module/audiofreeverb/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT diff --git a/shared-module/audiofreeverb/__init__.h b/shared-module/audiofreeverb/__init__.h new file mode 100644 index 00000000000..66463561f54 --- /dev/null +++ b/shared-module/audiofreeverb/__init__.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Mark Komus +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-module/audioi2sin/__init__.h b/shared-module/audioi2sin/__init__.h new file mode 100644 index 00000000000..852616ee3a7 --- /dev/null +++ b/shared-module/audioi2sin/__init__.h @@ -0,0 +1,71 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +// Rescale an already-normalized signed sample and write it to `buffer` at sample +// index `idx`. `s` is the sign-extended int32 value of the sample at `in_depth` +// scale (the per-port `i2sin_normalize_signed` produces it from the raw FIFO +// word, handling wire-format details like left-justification). This helper does +// the depth conversion + unsigned-WAV flip + container store, which is identical +// across ports. +// +// This path runs only when the caller set `output_bit_depth`, i.e. asked for a +// real bit-depth rescale: upscaling bit-replicates so full-scale input maps to +// full-scale output (e.g. 16-bit 0xFFFF -> 24-bit 0xFFFFFF) and downscaling +// arithmetic-shifts right. This is distinct from the implicit container width +// set by the array typecode (e.g. a 24-bit sample carried in a 32-bit 'i' slot), +// which only sign-extends and is handled by the default (non-converting) path. +// Output element size follows `out_depth`: 1 byte at 8, 2 bytes at 16, 4 bytes +// at 24 or 32. +static inline void shared_audioi2sin_write_converted(void *buffer, uint32_t idx, + int32_t s, uint8_t in_depth, uint8_t out_depth, bool samples_signed) { + int32_t shifted; + if (out_depth > in_depth) { + // Explicit upscale: left-justify the in_depth-bit sample at the top of a + // 32-bit word and replicate the pattern downward so full-scale input + // maps to full-scale output (e.g. 16-bit 0xFFFF -> 24-bit 0xFFFFFF). Two + // steps cover every supported ratio (widest is 8 -> 32); the guard skips + // the second step (and the resulting shift-by->=32 UB) when one suffices. + uint32_t top = (uint32_t)s << (32 - in_depth); + top |= top >> in_depth; + if (in_depth * 2 < out_depth) { + top |= top >> (in_depth * 2); + } + // Arithmetic-shift the high out_depth bits down, sign-extending to int32 + // so a 24-bit value in a 32-bit slot decodes correctly (no-op at 32). + shifted = (int32_t)top >> (32 - out_depth); + } else if (out_depth == in_depth) { + shifted = s; + } else { + shifted = s >> (in_depth - out_depth); + } + uint32_t u = (uint32_t)shifted; + if (!samples_signed) { + // I2S delivers signed PCM; flip the sign bit to match the WAV unsigned + // convention, at the output bit width. + if (out_depth >= 32) { + u ^= 0x80000000u; + } else { + uint32_t mask = (1u << out_depth) - 1u; + u = (u & mask) ^ (1u << (out_depth - 1)); + } + } + switch (out_depth) { + case 8: + ((uint8_t *)buffer)[idx] = (uint8_t)(u & 0xffu); + break; + case 16: + ((uint16_t *)buffer)[idx] = (uint16_t)(u & 0xffffu); + break; + default: // 24 or 32 + ((uint32_t *)buffer)[idx] = u; + break; + } +} diff --git a/shared-module/audiomixer/Mixer.c b/shared-module/audiomixer/Mixer.c index f086e78323b..a6c4397e8bf 100644 --- a/shared-module/audiomixer/Mixer.c +++ b/shared-module/audiomixer/Mixer.c @@ -11,6 +11,7 @@ #include "py/runtime.h" #include "shared-module/audiocore/__init__.h" +#include "shared-bindings/audiocore/__init__.h" #if defined(__arm__) && __arm__ #include "cmsis_compiler.h" @@ -25,46 +26,33 @@ void common_hal_audiomixer_mixer_construct(audiomixer_mixer_obj_t *self, uint32_t sample_rate) { self->len = buffer_size / 2 / sizeof(uint32_t) * sizeof(uint32_t); - self->first_buffer = m_malloc(self->len); + self->first_buffer = m_malloc_without_collect(self->len); if (self->first_buffer == NULL) { common_hal_audiomixer_mixer_deinit(self); m_malloc_fail(self->len); } - self->second_buffer = m_malloc(self->len); + self->second_buffer = m_malloc_without_collect(self->len); if (self->second_buffer == NULL) { common_hal_audiomixer_mixer_deinit(self); m_malloc_fail(self->len); } - self->bits_per_sample = bits_per_sample; - self->samples_signed = samples_signed; - self->channel_count = channel_count; - self->sample_rate = sample_rate; + self->base.bits_per_sample = bits_per_sample; + self->base.samples_signed = samples_signed; + self->base.channel_count = channel_count; + self->base.sample_rate = sample_rate; + self->base.single_buffer = false; self->voice_count = voice_count; + self->base.max_buffer_length = buffer_size; } void common_hal_audiomixer_mixer_deinit(audiomixer_mixer_obj_t *self) { + audiosample_mark_deinit(&self->base); self->first_buffer = NULL; self->second_buffer = NULL; } -bool common_hal_audiomixer_mixer_deinited(audiomixer_mixer_obj_t *self) { - return self->first_buffer == NULL; -} - -uint32_t common_hal_audiomixer_mixer_get_sample_rate(audiomixer_mixer_obj_t *self) { - return self->sample_rate; -} - -uint8_t common_hal_audiomixer_mixer_get_channel_count(audiomixer_mixer_obj_t *self) { - return self->channel_count; -} - -uint8_t common_hal_audiomixer_mixer_get_bits_per_sample(audiomixer_mixer_obj_t *self) { - return self->bits_per_sample; -} - bool common_hal_audiomixer_mixer_get_playing(audiomixer_mixer_obj_t *self) { for (uint8_t v = 0; v < self->voice_count; v++) { if (common_hal_audiomixer_mixervoice_get_playing(MP_OBJ_TO_PTR(self->voice[v]))) { @@ -78,7 +66,7 @@ void audiomixer_mixer_reset_buffer(audiomixer_mixer_obj_t *self, bool single_channel_output, uint8_t channel) { for (uint8_t i = 0; i < self->voice_count; i++) { - common_hal_audiomixer_mixervoice_stop(self->voice[i]); + common_hal_audiomixer_mixervoice_reset_buffer(self->voice[i]); } } @@ -104,22 +92,23 @@ static inline uint32_t add16signed(uint32_t a, uint32_t b) { } __attribute__((always_inline)) -static inline uint32_t mult16signed(uint32_t val, int32_t mul) { +static inline uint32_t mult16signed(uint32_t val, int32_t lomul, int32_t himul) { #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) - mul <<= 16; + lomul <<= 16; + himul <<= 16; int32_t hi, lo; enum { bits = 16 }; // saturate to 16 bits enum { shift = 15 }; // shift is done automatically - asm volatile ("smulwb %0, %1, %2" : "=r" (lo) : "r" (mul), "r" (val)); - asm volatile ("smulwt %0, %1, %2" : "=r" (hi) : "r" (mul), "r" (val)); - asm volatile ("ssat %0, %1, %2, asr %3" : "=r" (lo) : "I" (bits), "r" (lo), "I" (shift)); - asm volatile ("ssat %0, %1, %2, asr %3" : "=r" (hi) : "I" (bits), "r" (hi), "I" (shift)); - asm volatile ("pkhbt %0, %1, %2, lsl #16" : "=r" (val) : "r" (lo), "r" (hi)); // pack + __asm__ volatile ("smulwb %0, %1, %2" : "=r" (lo) : "r" (lomul), "r" (val)); + __asm__ volatile ("smulwt %0, %1, %2" : "=r" (hi) : "r" (himul), "r" (val)); + __asm__ volatile ("ssat %0, %1, %2, asr %3" : "=r" (lo) : "I" (bits), "r" (lo), "I" (shift)); + __asm__ volatile ("ssat %0, %1, %2, asr %3" : "=r" (hi) : "I" (bits), "r" (hi), "I" (shift)); + __asm__ volatile ("pkhbt %0, %1, %2, lsl #16" : "=r" (val) : "r" (lo), "r" (hi)); // pack return val; #else uint32_t result = 0; - float mod_mul = (float)mul / (float)((1 << 15) - 1); for (int8_t i = 0; i < 2; i++) { + float mod_mul = (float)(i ? himul : lomul) / (float)((1 << 15) - 1); int16_t ai = (val >> (sizeof(uint16_t) * 8 * i)); int32_t intermediate = (int32_t)(ai * mod_mul); if (intermediate > SHRT_MAX) { @@ -166,9 +155,57 @@ static inline uint32_t pack8(uint32_t val) { return ((val & 0xff000000) >> 16) | ((val & 0xff00) >> 8); } +static inline uint32_t copy16lsb(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) + return __PKHBT(val, val, 16); + #else + val &= 0x0000ffff; + return val | (val << 16); + #endif +} + +static inline uint32_t copy16msb(uint32_t val) { + #if (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) + return __PKHTB(val, val, 16); + #else + val &= 0xffff0000; + return val | (val >> 16); + #endif +} + +// Rather than immediately changing the loudness of audio playback, we keep a separate buffer of +// the "active" loudness and wait until we meet the conditions of a "zero crossing". A zero crossing +// occurs when either the current value is 0 or the value changes from negative to positive or +// vice-versa. This is detected by keeping a copy of the previous frame of audio data and checking +// to see if the sign of the value has changed. By only changing loudness during zero crossings, we +// avoid audible pops/clicks which can be unpleasant. +static void assignmul(uint32_t word, uint32_t *last_word, int32_t *active_lomul, int32_t *active_himul, int32_t pending_lomul, int32_t pending_himul) { + // If the active loudness already matches the pending loudness, exit early. + if (MP_LIKELY(*active_lomul == pending_lomul) && MP_LIKELY(*active_himul == pending_himul)) { + return; + } + + // Check for a zero crossing: current value is 0 or has changed sign from the previous value. + // We check for the sign change by bitmasking only the top bits of each 16-bit signed value + // packed into the 32-bit word (two's complement). If either bit doesn't match the previous + // value, a sign change has occurred on either the left or right channel. + if ((word & 0xffff0000) == 0 || (word & 0x0000ffff) == 0 || (*last_word != 0 && ((*last_word) & 0x80008000) != (word & 0x80008000))) { + // Copy over our pending loudness. Will cause future calls to `assignmul` to exit early. + *active_lomul = pending_lomul; + *active_himul = pending_himul; + } else { + // Update our copy of the previous word for future comparisons (an initial value of 0 is + // ignored). + *last_word = word; + } +} + +#define ALMOST_ONE (MICROPY_FLOAT_CONST(32767.) / 32768) + static void mix_down_one_voice(audiomixer_mixer_obj_t *self, audiomixer_mixervoice_obj_t *voice, bool voices_active, uint32_t *word_buffer, uint32_t length) { + audiosample_base_t *sample = MP_OBJ_TO_PTR(voice->sample); while (length != 0) { if (voice->buffer_length == 0) { if (!voice->more_data) { @@ -182,75 +219,219 @@ static void mix_down_one_voice(audiomixer_mixer_obj_t *self, if (voice->sample) { // Load another buffer audioio_get_buffer_result_t result = audiosample_get_buffer(voice->sample, false, 0, (uint8_t **)&voice->remaining_buffer, &voice->buffer_length); + if (result == GET_BUFFER_ERROR) { + voice->sample = NULL; + voice->buffer_length = 0; + voice->more_data = false; + break; + } // Track length in terms of words. voice->buffer_length /= sizeof(uint32_t); voice->more_data = result == GET_BUFFER_MORE_DATA; } } - uint32_t n = MIN(voice->buffer_length, length); uint32_t *src = voice->remaining_buffer; + + #if CIRCUITPY_SYNTHIO + uint32_t n; + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + n = MIN(MIN(voice->buffer_length, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } else { + n = MIN(MIN(voice->buffer_length << 1, length), SYNTHIO_MAX_DUR * self->base.channel_count); + } + + // Get the current level from the BlockInput. These may change at run time so you need to do bounds checking if required. + shared_bindings_synthio_lfo_tick(self->base.sample_rate, n / self->base.channel_count); + uint16_t level = (uint16_t)(synthio_block_slot_get_limited(&voice->level, MICROPY_FLOAT_CONST(0.0), MICROPY_FLOAT_CONST(1.0)) * (1 << 15)); + int16_t panning = synthio_block_slot_get_scaled(&voice->panning, -ALMOST_ONE, ALMOST_ONE); + #else + uint32_t n; + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + n = MIN(voice->buffer_length, length); + } else { + n = MIN(voice->buffer_length << 1, length); + } uint16_t level = voice->level; + int16_t panning = voice->panning; + #endif + + uint16_t left_panning_scaled = 32768, right_panning_scaled = 32768; + if (MP_LIKELY(self->base.channel_count == 2)) { + if (panning >= 0) { + left_panning_scaled = 32767 - panning; + } else { + right_panning_scaled = 32767 + panning; + } + } + + int32_t pending_lo_level = level; + int32_t pending_hi_level = level; + if (MP_LIKELY(self->base.channel_count == 2)) { + pending_lo_level = (left_panning_scaled * pending_lo_level) >> 15; + pending_hi_level = (right_panning_scaled * pending_hi_level) >> 15; + } + + int32_t active_lo_level = voice->active_lo_level; + int32_t active_hi_level = voice->active_hi_level; + uint32_t last_word = 0; // First active voice gets copied over verbatim. if (!voices_active) { - if (MP_LIKELY(self->bits_per_sample == 16)) { - if (MP_LIKELY(self->samples_signed)) { - for (uint32_t i = 0; i < n; i++) { - uint32_t v = src[i]; - word_buffer[i] = mult16signed(v, level); + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + if (MP_LIKELY(self->base.samples_signed)) { + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t word = src[i]; + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = mult16signed(word, active_lo_level, active_hi_level); + } + } else { + for (uint32_t i = 0; i < n; i += 2) { + uint32_t word = src[i >> 1]; + uint32_t word_lsb = copy16lsb(word); + assignmul(word_lsb, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = mult16signed(word_lsb, active_lo_level, active_hi_level); + word = copy16msb(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i + 1] = mult16signed(word, active_lo_level, active_hi_level); + } } } else { - for (uint32_t i = 0; i < n; i++) { - uint32_t v = src[i]; - v = tosigned16(v); - word_buffer[i] = mult16signed(v, level); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t word = src[i]; + word = tosigned16(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = mult16signed(word, active_lo_level, active_hi_level); + } + } else { + for (uint32_t i = 0; i + 1 < n; i += 2) { + uint32_t word = src[i >> 1]; + word = tosigned16(word); + uint32_t word_lsb = copy16lsb(word); + assignmul(word_lsb, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = mult16signed(word_lsb, active_lo_level, active_hi_level); + word = copy16msb(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i + 1] = mult16signed(word, active_lo_level, active_hi_level); + } } } } else { uint16_t *hword_buffer = (uint16_t *)word_buffer; uint16_t *hsrc = (uint16_t *)src; - for (uint32_t i = 0; i < n * 2; i++) { - uint32_t word = unpack8(hsrc[i]); - if (MP_LIKELY(!self->samples_signed)) { - word = tosigned16(word); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n * 2; i++) { + uint32_t word = unpack8(hsrc[i]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word = mult16signed(word, active_lo_level, active_hi_level); + hword_buffer[i] = pack8(word); + } + } else { + for (uint32_t i = 0; i + 1 < n * 2; i += 2) { + uint32_t word = unpack8(hsrc[i >> 1]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + uint32_t word_lsb = copy16lsb(word); + assignmul(word_lsb, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + hword_buffer[i] = pack8(mult16signed(word_lsb, active_lo_level, active_hi_level)); + word = copy16msb(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + hword_buffer[i + 1] = pack8(mult16signed(word, active_lo_level, active_hi_level)); } - word = mult16signed(word, level); - hword_buffer[i] = pack8(word); } } } else { - if (MP_LIKELY(self->bits_per_sample == 16)) { - if (MP_LIKELY(self->samples_signed)) { - for (uint32_t i = 0; i < n; i++) { - uint32_t word = src[i]; - word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + if (MP_LIKELY(self->base.bits_per_sample == 16)) { + if (MP_LIKELY(self->base.samples_signed)) { + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t word = src[i]; + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = add16signed(mult16signed(word, active_lo_level, active_hi_level), word_buffer[i]); + } + } else { + for (uint32_t i = 0; i + 1 < n; i += 2) { + uint32_t word = src[i >> 1]; + uint32_t word_lsb = copy16lsb(word); + assignmul(word_lsb, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = add16signed(mult16signed(word_lsb, active_lo_level, active_hi_level), word_buffer[i]); + word = copy16msb(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i + 1] = add16signed(mult16signed(word, active_lo_level, active_hi_level), word_buffer[i + 1]); + } } } else { - for (uint32_t i = 0; i < n; i++) { - uint32_t word = src[i]; - word = tosigned16(word); - word_buffer[i] = add16signed(mult16signed(word, level), word_buffer[i]); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n; i++) { + uint32_t word = src[i]; + word = tosigned16(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = add16signed(mult16signed(word, active_lo_level, active_hi_level), word_buffer[i]); + } + } else { + for (uint32_t i = 0; i + 1 < n; i += 2) { + uint32_t word = src[i >> 1]; + word = tosigned16(word); + uint32_t word_lsb = copy16lsb(word); + assignmul(word_lsb, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i] = add16signed(mult16signed(word_lsb, active_lo_level, active_hi_level), word_buffer[i]); + word = copy16msb(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word_buffer[i + 1] = add16signed(mult16signed(word, active_lo_level, active_hi_level), word_buffer[i + 1]); + } } } } else { uint16_t *hword_buffer = (uint16_t *)word_buffer; uint16_t *hsrc = (uint16_t *)src; - for (uint32_t i = 0; i < n * 2; i++) { - uint32_t word = unpack8(hsrc[i]); - if (MP_LIKELY(!self->samples_signed)) { - word = tosigned16(word); + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + for (uint32_t i = 0; i < n * 2; i++) { + uint32_t word = unpack8(hsrc[i]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + word = mult16signed(word, active_lo_level, active_hi_level); + word = add16signed(word, unpack8(hword_buffer[i])); + hword_buffer[i] = pack8(word); + } + } else { + for (uint32_t i = 0; i + 1 < n * 2; i += 2) { + uint32_t word = unpack8(hsrc[i >> 1]); + if (MP_LIKELY(!self->base.samples_signed)) { + word = tosigned16(word); + } + uint32_t word_lsb = copy16lsb(word); + assignmul(word_lsb, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + hword_buffer[i] = pack8(add16signed(mult16signed(word_lsb, active_lo_level, active_hi_level), unpack8(hword_buffer[i]))); + word = copy16msb(word); + assignmul(word, &last_word, &active_lo_level, &active_hi_level, pending_lo_level, pending_hi_level); + hword_buffer[i + 1] = pack8(add16signed(mult16signed(word, active_lo_level, active_hi_level), unpack8(hword_buffer[i + 1]))); } - word = mult16signed(word, level); - word = add16signed(word, unpack8(hword_buffer[i])); - hword_buffer[i] = pack8(word); } } } length -= n; word_buffer += n; - voice->remaining_buffer += n; - voice->buffer_length -= n; + if (MP_LIKELY(self->base.channel_count == sample->channel_count)) { + voice->remaining_buffer += n; + voice->buffer_length -= n; + } else { + voice->remaining_buffer += n >> 1; + voice->buffer_length -= n >> 1; + } + + // Force the active level to match the pending level in the case that the conditions of a + // zero crossing weren't met within the last `SYNTHIO_MAX_DUR` frames. Will ensure minimal + // delay in level or panning changes at the potential expensive of an audible pop. + voice->active_lo_level = pending_lo_level; + voice->active_hi_level = pending_hi_level; } if (length && !voices_active) { @@ -303,8 +484,8 @@ audioio_get_buffer_result_t audiomixer_mixer_get_buffer(audiomixer_mixer_obj_t * } } - if (!self->samples_signed) { - if (self->bits_per_sample == 16) { + if (!self->base.samples_signed) { + if (self->base.bits_per_sample == 16) { for (uint32_t i = 0; i < length; i++) { word_buffer[i] = tounsigned16(word_buffer[i]); } @@ -327,20 +508,7 @@ audioio_get_buffer_result_t audiomixer_mixer_get_buffer(audiomixer_mixer_obj_t * self->left_read_count += 1; } else if (channel == 1) { self->right_read_count += 1; - *buffer = *buffer + self->bits_per_sample / 8; + *buffer = *buffer + self->base.bits_per_sample / 8; } return GET_BUFFER_MORE_DATA; } - -void audiomixer_mixer_get_buffer_structure(audiomixer_mixer_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing) { - *single_buffer = false; - *samples_signed = self->samples_signed; - *max_buffer_length = self->len; - if (single_channel_output) { - *spacing = self->channel_count; - } else { - *spacing = 1; - } -} diff --git a/shared-module/audiomixer/Mixer.h b/shared-module/audiomixer/Mixer.h index 771b3969719..b793fa12a2d 100644 --- a/shared-module/audiomixer/Mixer.h +++ b/shared-module/audiomixer/Mixer.h @@ -12,15 +12,11 @@ #include "shared-module/audiocore/__init__.h" typedef struct { - mp_obj_base_t base; + audiosample_base_t base; uint32_t *first_buffer; uint32_t *second_buffer; uint32_t len; // in words - uint8_t bits_per_sample; bool use_first_buffer; - bool samples_signed; - uint8_t channel_count; - uint32_t sample_rate; uint32_t read_count; uint32_t left_read_count; @@ -41,6 +37,3 @@ audioio_get_buffer_result_t audiomixer_mixer_get_buffer(audiomixer_mixer_obj_t * uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); // length in bytes -void audiomixer_mixer_get_buffer_structure(audiomixer_mixer_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing); diff --git a/shared-module/audiomixer/MixerVoice.c b/shared-module/audiomixer/MixerVoice.c index c32d37cdec2..af015fc46f1 100644 --- a/shared-module/audiomixer/MixerVoice.c +++ b/shared-module/audiomixer/MixerVoice.c @@ -15,48 +15,72 @@ void common_hal_audiomixer_mixervoice_construct(audiomixer_mixervoice_obj_t *self) { self->sample = NULL; - self->level = 1 << 15; + common_hal_audiomixer_mixervoice_set_level(self, mp_obj_new_float(1.0)); + common_hal_audiomixer_mixervoice_set_panning(self, mp_obj_new_float(0.0)); } void common_hal_audiomixer_mixervoice_set_parent(audiomixer_mixervoice_obj_t *self, audiomixer_mixer_obj_t *parent) { self->parent = parent; } -mp_float_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self) { - return (mp_float_t)self->level / (1 << 15); +mp_obj_t common_hal_audiomixer_mixervoice_get_level(audiomixer_mixervoice_obj_t *self) { + #if CIRCUITPY_SYNTHIO + return self->level.obj; + #else + return mp_obj_new_float((mp_float_t)self->level / (1 << 15)); + #endif } -void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_float_t level) { - self->level = (uint16_t)(level * (1 << 15)); +void common_hal_audiomixer_mixervoice_set_level(audiomixer_mixervoice_obj_t *self, mp_obj_t arg) { + #if CIRCUITPY_SYNTHIO + synthio_block_assign_slot(arg, &self->level, MP_QSTR_level); + #else + self->level = (uint16_t)(mp_arg_validate_obj_float_range(arg, 0, 1, MP_QSTR_level) * (1 << 15)); + #endif } -void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t *self, mp_obj_t sample, bool loop) { - if (audiosample_sample_rate(sample) != self->parent->sample_rate) { - mp_raise_ValueError(MP_ERROR_TEXT("The sample's sample rate does not match the mixer's")); - } - if (audiosample_channel_count(sample) != self->parent->channel_count) { - mp_raise_ValueError(MP_ERROR_TEXT("The sample's channel count does not match the mixer's")); - } - if (audiosample_bits_per_sample(sample) != self->parent->bits_per_sample) { - mp_raise_ValueError(MP_ERROR_TEXT("The sample's bits_per_sample does not match the mixer's")); - } - bool single_buffer; - bool samples_signed; - uint32_t max_buffer_length; - uint8_t spacing; - audiosample_get_buffer_structure(sample, false, &single_buffer, &samples_signed, - &max_buffer_length, &spacing); - if (samples_signed != self->parent->samples_signed) { - mp_raise_ValueError(MP_ERROR_TEXT("The sample's signedness does not match the mixer's")); - } +mp_obj_t common_hal_audiomixer_mixervoice_get_panning(audiomixer_mixervoice_obj_t *self) { + #if CIRCUITPY_SYNTHIO + return self->panning.obj; + #else + return mp_obj_new_float((mp_float_t)self->panning / ((1 << 15) - 1)); + #endif +} + +void common_hal_audiomixer_mixervoice_set_panning(audiomixer_mixervoice_obj_t *self, mp_obj_t arg) { + #if CIRCUITPY_SYNTHIO + synthio_block_assign_slot(arg, &self->panning, MP_QSTR_panning); + #else + self->panning = (int16_t)(mp_arg_validate_obj_float_range(arg, -1, 1, MP_QSTR_panning) * ((1 << 15) - 1)); + #endif +} + +bool common_hal_audiomixer_mixervoice_get_loop(audiomixer_mixervoice_obj_t *self) { + return self->loop; +} + +void common_hal_audiomixer_mixervoice_set_loop(audiomixer_mixervoice_obj_t *self, bool loop) { + self->loop = loop; +} + +void common_hal_audiomixer_mixervoice_play(audiomixer_mixervoice_obj_t *self, mp_obj_t sample_in, bool loop) { + audiosample_must_match(&self->parent->base, sample_in, true); + // cast is safe, checked by must_match + audiosample_base_t *sample = MP_OBJ_TO_PTR(sample_in); self->sample = sample; self->loop = loop; - audiosample_reset_buffer(sample, false, 0); - audioio_get_buffer_result_t result = audiosample_get_buffer(sample, false, 0, (uint8_t **)&self->remaining_buffer, &self->buffer_length); - // Track length in terms of words. - self->buffer_length /= sizeof(uint32_t); - self->more_data = result == GET_BUFFER_MORE_DATA; + common_hal_audiomixer_mixervoice_reset_buffer(self); +} + +void common_hal_audiomixer_mixervoice_reset_buffer(audiomixer_mixervoice_obj_t *self) { + if (self->sample != NULL) { + audiosample_reset_buffer(self->sample, false, 0); + audioio_get_buffer_result_t result = audiosample_get_buffer(self->sample, false, 0, (uint8_t **)&self->remaining_buffer, &self->buffer_length); + // Track length in terms of words. + self->buffer_length /= sizeof(uint32_t); + self->more_data = result == GET_BUFFER_MORE_DATA; + } } bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t *self) { @@ -66,3 +90,9 @@ bool common_hal_audiomixer_mixervoice_get_playing(audiomixer_mixervoice_obj_t *s void common_hal_audiomixer_mixervoice_stop(audiomixer_mixervoice_obj_t *self) { self->sample = NULL; } + +void common_hal_audiomixer_mixervoice_end(audiomixer_mixervoice_obj_t *self) { + if (self->sample != NULL) { + self->loop = false; + } +} diff --git a/shared-module/audiomixer/MixerVoice.h b/shared-module/audiomixer/MixerVoice.h index ad70f64b6e1..db5cac1ca27 100644 --- a/shared-module/audiomixer/MixerVoice.h +++ b/shared-module/audiomixer/MixerVoice.h @@ -9,6 +9,9 @@ #include "shared-module/audiomixer/__init__.h" #include "shared-module/audiomixer/Mixer.h" +#if CIRCUITPY_SYNTHIO +#include "shared-module/synthio/block.h" +#endif typedef struct { mp_obj_base_t base; @@ -18,5 +21,13 @@ typedef struct { bool more_data; uint32_t *remaining_buffer; uint32_t buffer_length; + #if CIRCUITPY_SYNTHIO + synthio_block_slot_t level; + synthio_block_slot_t panning; + #else uint16_t level; + int16_t panning; + #endif + int32_t active_lo_level; + int32_t active_hi_level; } audiomixer_mixervoice_obj_t; diff --git a/shared-module/audiomp3/MP3Decoder.c b/shared-module/audiomp3/MP3Decoder.c index b135af75869..6f0b5d4723f 100644 --- a/shared-module/audiomp3/MP3Decoder.c +++ b/shared-module/audiomp3/MP3Decoder.c @@ -6,6 +6,7 @@ // SPDX-License-Identifier: MIT #include "shared-bindings/audiomp3/MP3Decoder.h" +#include "shared-bindings/audiocore/__init__.h" #include #include @@ -20,6 +21,7 @@ #include "shared-module/audiomp3/MP3Decoder.h" #include "supervisor/background_callback.h" #include "lib/mp3/src/mp3common.h" +#include "lib/mp3/src/coder.h" #define MAX_BUFFER_LEN (MAX_NSAMP * MAX_NGRAN * MAX_NCHAN * sizeof(int16_t)) @@ -118,8 +120,13 @@ static void stream_set_blocking(audiomp3_mp3file_obj_t *self, bool block_ok) { * Sets self->eof if any read of the file returns 0 bytes */ static bool mp3file_update_inbuf_always(audiomp3_mp3file_obj_t *self, bool block_ok) { + // Every return from this function must be preceded by background_callback_allow(); + background_callback_prevent(); + if (self->eof || INPUT_BUFFER_SPACE(self->inbuf) == 0) { - return INPUT_BUFFER_AVAILABLE(self->inbuf) > 0; + bool result = INPUT_BUFFER_AVAILABLE(self->inbuf) > 0; + background_callback_allow(); + return result; } stream_set_blocking(self, block_ok); @@ -133,7 +140,8 @@ static bool mp3file_update_inbuf_always(audiomp3_mp3file_obj_t *self, bool block self->inbuf.read_off = 0; } - for (size_t to_read; !self->eof && (to_read = INPUT_BUFFER_SPACE(self->inbuf)) > 0;) { + for (size_t to_read; !self->eof && INPUT_BUFFER_SPACE(self->inbuf) > 0 && + (to_read = (size_t)INPUT_BUFFER_SPACE(self->inbuf)) > 0;) { uint8_t *write_ptr = self->inbuf.buf + self->inbuf.write_off; ssize_t n_read = stream_read(self->stream, write_ptr, to_read); @@ -143,6 +151,7 @@ static bool mp3file_update_inbuf_always(audiomp3_mp3file_obj_t *self, bool block break; } self->eof = true; + background_callback_allow(); mp_raise_OSError(errcode); } @@ -158,7 +167,10 @@ static bool mp3file_update_inbuf_always(audiomp3_mp3file_obj_t *self, bool block } // Return true iff there are at least some useful bytes in the buffer - return INPUT_BUFFER_AVAILABLE(self->inbuf) > 0; + bool result = INPUT_BUFFER_AVAILABLE(self->inbuf) > 0; + + background_callback_allow(); + return result; } /** Update the inbuf from a background callback. @@ -167,7 +179,7 @@ static bool mp3file_update_inbuf_always(audiomp3_mp3file_obj_t *self, bool block */ static void mp3file_update_inbuf_cb(void *self_in) { audiomp3_mp3file_obj_t *self = self_in; - if (common_hal_audiomp3_mp3file_deinited(self_in)) { + if (audiosample_deinited(&self->base)) { return; } if (!self->eof && stream_readable(self->stream)) { @@ -303,7 +315,7 @@ void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t *self, self->inbuf.size = buffer_size - 2 * MAX_BUFFER_LEN; } else { self->inbuf.size = DEFAULT_INPUT_BUFFER_SIZE; - self->inbuf.buf = m_malloc(DEFAULT_INPUT_BUFFER_SIZE); + self->inbuf.buf = m_malloc_without_collect(DEFAULT_INPUT_BUFFER_SIZE); if (self->inbuf.buf == NULL) { common_hal_audiomp3_mp3file_deinit(self); m_malloc_fail(DEFAULT_INPUT_BUFFER_SIZE); @@ -313,13 +325,13 @@ void common_hal_audiomp3_mp3file_construct(audiomp3_mp3file_obj_t *self, self->pcm_buffer[0] = (int16_t *)(void *)buffer; self->pcm_buffer[1] = (int16_t *)(void *)(buffer + MAX_BUFFER_LEN); } else { - self->pcm_buffer[0] = m_malloc(MAX_BUFFER_LEN); + self->pcm_buffer[0] = m_malloc_without_collect(MAX_BUFFER_LEN); if (self->pcm_buffer[0] == NULL) { common_hal_audiomp3_mp3file_deinit(self); m_malloc_fail(MAX_BUFFER_LEN); } - self->pcm_buffer[1] = m_malloc(MAX_BUFFER_LEN); + self->pcm_buffer[1] = m_malloc_without_collect(MAX_BUFFER_LEN); if (self->pcm_buffer[1] == NULL) { common_hal_audiomp3_mp3file_deinit(self); m_malloc_fail(MAX_BUFFER_LEN); @@ -360,6 +372,17 @@ void common_hal_audiomp3_mp3file_set_file(audiomp3_mp3file_obj_t *self, mp_obj_t // get_buffer() that I didn't understand. memset(self->pcm_buffer[0], 0, MAX_BUFFER_LEN); memset(self->pcm_buffer[1], 0, MAX_BUFFER_LEN); + + /* important to do this - DSP primitives assume a bunch of state variables are 0 on first use */ + struct _MP3DecInfo *decoder = self->decoder; + memset(decoder->FrameHeaderPS, 0, sizeof(FrameHeader)); + memset(decoder->SideInfoPS, 0, sizeof(SideInfo)); + memset(decoder->ScaleFactorInfoPS, 0, sizeof(ScaleFactorInfo)); + memset(decoder->HuffmanInfoPS, 0, sizeof(HuffmanInfo)); + memset(decoder->DequantInfoPS, 0, sizeof(DequantInfo)); + memset(decoder->IMDCTInfoPS, 0, sizeof(IMDCTInfo)); + memset(decoder->SubbandInfoPS, 0, sizeof(SubbandInfo)); + MP3FrameInfo fi; bool result = mp3file_get_next_frame_info(self, &fi, true); background_callback_allow(); @@ -368,14 +391,18 @@ void common_hal_audiomp3_mp3file_set_file(audiomp3_mp3file_obj_t *self, mp_obj_t MP_ERROR_TEXT("Failed to parse MP3 file")); } - self->sample_rate = fi.samprate; - self->channel_count = fi.nChans; - self->frame_buffer_size = fi.outputSamps * sizeof(int16_t); - self->len = 2 * self->frame_buffer_size; + self->base.sample_rate = fi.samprate; + self->base.channel_count = fi.nChans; + self->base.single_buffer = false; + self->base.bits_per_sample = 16; + self->base.samples_signed = true; + self->base.max_buffer_length = fi.outputSamps * sizeof(int16_t); + self->len = 2 * self->base.max_buffer_length; self->samples_decoded = 0; } void common_hal_audiomp3_mp3file_deinit(audiomp3_mp3file_obj_t *self) { + audiosample_mark_deinit(&self->base); if (self->decoder) { MP3FreeDecoder(self->decoder); } @@ -388,27 +415,6 @@ void common_hal_audiomp3_mp3file_deinit(audiomp3_mp3file_obj_t *self) { self->samples_decoded = 0; } -bool common_hal_audiomp3_mp3file_deinited(audiomp3_mp3file_obj_t *self) { - return self->pcm_buffer[0] == NULL; -} - -uint32_t common_hal_audiomp3_mp3file_get_sample_rate(audiomp3_mp3file_obj_t *self) { - return self->sample_rate; -} - -void common_hal_audiomp3_mp3file_set_sample_rate(audiomp3_mp3file_obj_t *self, - uint32_t sample_rate) { - self->sample_rate = sample_rate; -} - -uint8_t common_hal_audiomp3_mp3file_get_bits_per_sample(audiomp3_mp3file_obj_t *self) { - return 16; -} - -uint8_t common_hal_audiomp3_mp3file_get_channel_count(audiomp3_mp3file_obj_t *self) { - return self->channel_count; -} - void audiomp3_mp3file_reset_buffer(audiomp3_mp3file_obj_t *self, bool single_channel_output, uint8_t channel) { @@ -445,7 +451,7 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * channel = 0; } - size_t frame_buffer_size_bytes = self->frame_buffer_size; + size_t frame_buffer_size_bytes = self->base.max_buffer_length; *buffer_length = frame_buffer_size_bytes; if (channel == self->other_channel) { @@ -467,7 +473,7 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * mp3file_skip_id3v2(self, false); if (!mp3file_find_sync_word(self, false)) { - memset(buffer, 0, self->frame_buffer_size); + memset(buffer, 0, self->base.max_buffer_length); *buffer_length = 0; return self->eof ? GET_BUFFER_DONE : GET_BUFFER_ERROR; } @@ -483,7 +489,7 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * mp_printf(&mp_plat_print, "%s:%d err=%d\n", __FILE__, __LINE__, err); } if (self->eof || (err != ERR_MP3_INDATA_UNDERFLOW && err != ERR_MP3_MAINDATA_UNDERFLOW)) { - memset(buffer, 0, self->frame_buffer_size); + memset(buffer, 0, self->base.max_buffer_length); *buffer_length = 0; self->eof = true; return GET_BUFFER_ERROR; @@ -511,27 +517,14 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * return result; } -void audiomp3_mp3file_get_buffer_structure(audiomp3_mp3file_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing) { - *single_buffer = false; - *samples_signed = true; - *max_buffer_length = self->frame_buffer_size; - if (single_channel_output) { - *spacing = self->channel_count; - } else { - *spacing = 1; - } -} - float common_hal_audiomp3_mp3file_get_rms_level(audiomp3_mp3file_obj_t *self) { float sumsq = 0.f; // Assumes no DC component to the audio. Is that a safe assumption? int16_t *buffer = (int16_t *)(void *)self->pcm_buffer[self->buffer_index]; - for (size_t i = 0; i < self->frame_buffer_size / sizeof(int16_t); i++) { + for (size_t i = 0; i < self->base.max_buffer_length / sizeof(int16_t); i++) { sumsq += (float)buffer[i] * buffer[i]; } - return sqrtf(sumsq) / (self->frame_buffer_size / sizeof(int16_t)); + return sqrtf(sumsq) / (self->base.max_buffer_length / sizeof(int16_t)); } uint32_t common_hal_audiomp3_mp3file_get_samples_decoded(audiomp3_mp3file_obj_t *self) { diff --git a/shared-module/audiomp3/MP3Decoder.h b/shared-module/audiomp3/MP3Decoder.h index 9f1b97a5a51..9af3300047b 100644 --- a/shared-module/audiomp3/MP3Decoder.h +++ b/shared-module/audiomp3/MP3Decoder.h @@ -21,19 +21,16 @@ typedef struct { } mp3_input_buffer_t; typedef struct { - mp_obj_base_t base; + audiosample_base_t base; struct _MP3DecInfo *decoder; background_callback_t inbuf_fill_cb; mp3_input_buffer_t inbuf; int16_t *pcm_buffer[2]; uint32_t len; - uint32_t frame_buffer_size; - uint32_t sample_rate; mp_obj_t stream; uint8_t buffer_index; - uint8_t channel_count; bool eof; bool block_ok; mp_obj_t settimeout_args[3]; @@ -53,9 +50,6 @@ audioio_get_buffer_result_t audiomp3_mp3file_get_buffer(audiomp3_mp3file_obj_t * uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); // length in bytes -void audiomp3_mp3file_get_buffer_structure(audiomp3_mp3file_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing); float audiomp3_mp3file_get_rms_level(audiomp3_mp3file_obj_t *self); diff --git a/shared-module/audiospeed/Resampler.c b/shared-module/audiospeed/Resampler.c new file mode 100644 index 00000000000..cd1ac681246 --- /dev/null +++ b/shared-module/audiospeed/Resampler.c @@ -0,0 +1,44 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/audiospeed/Resampler.h" + +static void calculate_rate(audiospeed_base_t *self, uint32_t sample_rate) { + if (self->source != NULL && sample_rate) { + self->speed.rate_fp = (uint32_t)((mp_float_t)self->base.sample_rate / sample_rate * (1 << SPEED_SHIFT)); + } else { + audiospeed_set_rate(&self->speed, mp_const_none); + } +} + +void common_hal_audiospeed_resampler_construct(audiospeed_resampler_obj_t *self, mp_obj_t source) { + audiospeed_construct(&self->base, source, mp_const_none); // default rate 1.0 + self->sample_rate = 0; +} + +void common_hal_audiospeed_resampler_deinit(audiospeed_resampler_obj_t *self) { + audiospeed_deinit(&self->base); +} + +mp_obj_t common_hal_audiospeed_resampler_get_rate(audiospeed_resampler_obj_t *self) { + return audiospeed_get_rate(&self->base.speed); +} + +void audiospeed_resampler_set_sample_rate(audiospeed_resampler_obj_t *self, uint32_t sample_rate) { + self->sample_rate = sample_rate; + calculate_rate(&self->base, self->sample_rate); +} + +void audiospeed_resampler_reset_buffer(audiospeed_resampler_obj_t *self, + bool single_channel_output, uint8_t channel) { + audiospeed_reset_buffer(&self->base, single_channel_output, channel); +} + +audioio_get_buffer_result_t audiospeed_resampler_get_buffer(audiospeed_resampler_obj_t *self, + bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + return audiospeed_get_buffer(&self->base, single_channel_output, channel, buffer, buffer_length); +} diff --git a/shared-module/audiospeed/Resampler.h b/shared-module/audiospeed/Resampler.h new file mode 100644 index 00000000000..a105c5c2ab9 --- /dev/null +++ b/shared-module/audiospeed/Resampler.h @@ -0,0 +1,22 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Cooper Dalrymple +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/audiocore/__init__.h" +#include "shared-module/audiospeed/__init__.h" + +typedef struct { + audiospeed_base_t base; + uint32_t sample_rate; +} audiospeed_resampler_obj_t; + +void audiospeed_resampler_reset_buffer(audiospeed_resampler_obj_t *self, + bool single_channel_output, uint8_t channel); +audioio_get_buffer_result_t audiospeed_resampler_get_buffer(audiospeed_resampler_obj_t *self, + bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length); diff --git a/shared-module/audiospeed/SpeedChanger.c b/shared-module/audiospeed/SpeedChanger.c new file mode 100644 index 00000000000..1bf21dfab7a --- /dev/null +++ b/shared-module/audiospeed/SpeedChanger.c @@ -0,0 +1,42 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/audiospeed/SpeedChanger.h" + +#include +#include "py/runtime.h" +#include "py/gc.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-bindings/audiocore/__init__.h" + +void common_hal_audiospeed_speedchanger_construct(audiospeed_speedchanger_obj_t *self, + mp_obj_t source, mp_obj_t rate_obj) { + audiospeed_construct(self, source, rate_obj); +} + +void common_hal_audiospeed_speedchanger_deinit(audiospeed_speedchanger_obj_t *self) { + audiospeed_deinit(self); +} + +void common_hal_audiospeed_speedchanger_set_rate(audiospeed_speedchanger_obj_t *self, mp_obj_t rate_obj) { + audiospeed_set_rate(&self->speed, rate_obj); +} + +mp_obj_t common_hal_audiospeed_speedchanger_get_rate(audiospeed_speedchanger_obj_t *self) { + return audiospeed_get_rate(&self->speed); +} + +void audiospeed_speedchanger_reset_buffer(audiospeed_speedchanger_obj_t *self, + bool single_channel_output, uint8_t channel) { + audiospeed_reset_buffer(self, single_channel_output, channel); +} + +audioio_get_buffer_result_t audiospeed_speedchanger_get_buffer(audiospeed_speedchanger_obj_t *self, + bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + return audiospeed_get_buffer(self, single_channel_output, channel, buffer, buffer_length); +} diff --git a/shared-module/audiospeed/SpeedChanger.h b/shared-module/audiospeed/SpeedChanger.h new file mode 100644 index 00000000000..34969e42bd6 --- /dev/null +++ b/shared-module/audiospeed/SpeedChanger.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/audiocore/__init__.h" +#include "shared-module/audiospeed/__init__.h" + +typedef audiospeed_base_t audiospeed_speedchanger_obj_t; + +void audiospeed_speedchanger_reset_buffer(audiospeed_speedchanger_obj_t *self, + bool single_channel_output, uint8_t channel); +audioio_get_buffer_result_t audiospeed_speedchanger_get_buffer(audiospeed_speedchanger_obj_t *self, + bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length); diff --git a/shared-module/audiospeed/__init__.c b/shared-module/audiospeed/__init__.c new file mode 100644 index 00000000000..19c4c9bf20d --- /dev/null +++ b/shared-module/audiospeed/__init__.c @@ -0,0 +1,176 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/gc.h" +#include "py/objproperty.h" +#include "py/runtime.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/audiospeed/__init__.h" +#include "shared-bindings/audiocore/__init__.h" + +// Convert a Python float to 16.16 fixed-point rate +uint32_t audiospeed_rate_to_fp(mp_obj_t rate_obj) { + mp_float_t rate = mp_arg_validate_obj_float_range(rate_obj, 0.001, 1000.0, MP_QSTR_rate); + return (uint32_t)(rate * (1 << SPEED_SHIFT)); +} + +// Convert 16.16 fixed-point rate to Python float +mp_obj_t audiospeed_fp_to_rate(uint32_t rate_fp) { + return mp_obj_new_float((mp_float_t)rate_fp / (1 << SPEED_SHIFT)); +} + +void audiospeed_construct(audiospeed_base_t *self, mp_obj_t source, mp_obj_t rate_obj) { + audiosample_base_t *src_base = audiosample_check(source); + + self->source = source; + self->src_buffer = NULL; + self->src_buffer_length = 0; + self->src_sample_count = 0; + self->source_done = false; + self->source_exhausted = false; + + + // Copy format from source + self->base.sample_rate = src_base->sample_rate; + self->base.channel_count = src_base->channel_count; + self->base.bits_per_sample = src_base->bits_per_sample; + self->base.samples_signed = src_base->samples_signed; + self->base.single_buffer = false; + + audiospeed_set_rate(&self->speed, rate_obj); + audiospeed_reset_phase(&self->speed); + + uint8_t bytes_per_frame = (src_base->bits_per_sample / 8) * src_base->channel_count; + self->output_buffer_length = OUTPUT_BUFFER_FRAMES * bytes_per_frame; + self->base.max_buffer_length = self->output_buffer_length; + + self->output_buffer = m_malloc_without_collect(self->output_buffer_length); + if (self->output_buffer == NULL) { + m_malloc_fail(self->output_buffer_length); + } +} + +void audiospeed_deinit(audiospeed_base_t *self) { + self->output_buffer = NULL; + self->source = MP_OBJ_NULL; + audiosample_mark_deinit(&self->base); +} + +// Fetch the next buffer from the source. Returns false if no data available. +bool audiospeed_fetch_source_buffer(audiospeed_base_t *self) { + if (self->source_exhausted || self->source == NULL) { + return false; + } + uint8_t *buf = NULL; + uint32_t len = 0; + audioio_get_buffer_result_t result = audiosample_get_buffer(self->source, false, 0, &buf, &len); + if (result == GET_BUFFER_ERROR) { + self->source_exhausted = true; + return false; + } + if (len == 0) { + self->source_exhausted = true; + return false; + } + self->src_buffer = buf; + self->src_buffer_length = len; + uint8_t bytes_per_frame = (self->base.bits_per_sample / 8) * self->base.channel_count; + self->src_sample_count = len / bytes_per_frame; + self->source_done = (result == GET_BUFFER_DONE); + // Reset phase to index within this new buffer + audiospeed_reset_phase(&self->speed); + return true; +} + +void audiospeed_reset_buffer(audiospeed_base_t *self, bool single_channel_output, uint8_t channel) { + if (single_channel_output && channel == 1) { + return; + } + audiosample_reset_buffer(self->source, false, 0); + audiospeed_reset_phase(&self->speed); + self->src_buffer = NULL; + self->src_buffer_length = 0; + self->src_sample_count = 0; + self->source_done = false; + self->source_exhausted = false; +} + +audioio_get_buffer_result_t audiospeed_get_buffer(audiospeed_base_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length) { + + // Ensure we have a source buffer + if (self->src_buffer == NULL) { + if (!audiospeed_fetch_source_buffer(self)) { + *buffer = NULL; + *buffer_length = 0; + return GET_BUFFER_DONE; + } + } + + uint8_t bytes_per_sample = self->base.bits_per_sample / 8; + uint8_t channels = self->base.channel_count; + uint8_t bytes_per_frame = bytes_per_sample * channels; + uint32_t out_frames = 0; + uint32_t max_out_frames = self->output_buffer_length / bytes_per_frame; + + if (bytes_per_sample == 1) { + // 8-bit samples + uint8_t *out = self->output_buffer; + while (out_frames < max_out_frames) { + uint32_t src_index = audiospeed_get_index(&self->speed); + // Advance to next source buffer if needed + if (src_index >= self->src_sample_count) { + if (self->source_done) { + self->source_exhausted = true; + break; + } + if (!audiospeed_fetch_source_buffer(self)) { + break; + } + src_index = 0; // phase was reset by fetch + } + uint8_t *src = self->src_buffer + src_index * bytes_per_frame; + for (uint8_t c = 0; c < channels; c++) { + *out++ = src[c]; + } + out_frames++; + audiospeed_increment_phase(&self->speed); + } + } else { + // 16-bit samples + int16_t *out = (int16_t *)self->output_buffer; + while (out_frames < max_out_frames) { + uint32_t src_index = audiospeed_get_index(&self->speed); + if (src_index >= self->src_sample_count) { + if (self->source_done) { + self->source_exhausted = true; + break; + } + if (!audiospeed_fetch_source_buffer(self)) { + break; + } + src_index = 0; + } + int16_t *src = (int16_t *)(self->src_buffer + src_index * bytes_per_frame); + for (uint8_t c = 0; c < channels; c++) { + *out++ = src[c]; + } + out_frames++; + audiospeed_increment_phase(&self->speed); + } + } + + *buffer = self->output_buffer; + *buffer_length = out_frames * bytes_per_frame; + + if (out_frames == 0) { + return GET_BUFFER_DONE; + } + return self->source_exhausted ? GET_BUFFER_DONE : GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/audiospeed/__init__.h b/shared-module/audiospeed/__init__.h new file mode 100644 index 00000000000..4a36a8b79b7 --- /dev/null +++ b/shared-module/audiospeed/__init__.h @@ -0,0 +1,72 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tod Kurt +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +#include "py/objproperty.h" +#include "shared-module/audiocore/__init__.h" + +// Fixed-point 16.16 format +#define SPEED_SHIFT 16 +#define SPEED_DEFAULT (1 << SPEED_SHIFT) // default 1.0 + +typedef struct { + // Phase accumulator and rate in 16.16 fixed-point (units: source frames) + uint32_t phase; + uint32_t rate_fp; // 16.16 fixed-point rate +} audiospeed_speed_t; + +uint32_t audiospeed_rate_to_fp(mp_obj_t rate_obj); +mp_obj_t audiospeed_fp_to_rate(uint32_t rate_fp); + +static inline void audiospeed_set_rate(audiospeed_speed_t *self, mp_obj_t rate_obj) { + if (rate_obj != mp_const_none) { + self->rate_fp = audiospeed_rate_to_fp(rate_obj); + } else { + self->rate_fp = SPEED_DEFAULT; + } +} + +static inline mp_obj_t audiospeed_get_rate(audiospeed_speed_t *self) { + return audiospeed_fp_to_rate(self->rate_fp); +} + +static inline void audiospeed_reset_phase(audiospeed_speed_t *self) { + self->phase = 0; +} + +static inline void audiospeed_increment_phase(audiospeed_speed_t *self) { + self->phase += self->rate_fp; +} + +static inline uint32_t audiospeed_get_index(audiospeed_speed_t *self) { + return self->phase >> SPEED_SHIFT; +} + +#define OUTPUT_BUFFER_FRAMES 128 + +typedef struct { + audiosample_base_t base; + mp_obj_t source; + uint8_t *output_buffer; + uint32_t output_buffer_length; // in bytes, allocated size + // Source buffer cache + uint8_t *src_buffer; + uint32_t src_buffer_length; // in bytes + uint32_t src_sample_count; // in frames + audiospeed_speed_t speed; + bool source_done; // source returned DONE on last get_buffer + bool source_exhausted; // source DONE and we consumed all of it +} audiospeed_base_t; + +void audiospeed_construct(audiospeed_base_t *self, mp_obj_t source, mp_obj_t rate_obj); +void audiospeed_deinit(audiospeed_base_t *self); +bool audiospeed_fetch_source_buffer(audiospeed_base_t *self); +void audiospeed_reset_buffer(audiospeed_base_t *self, bool single_channel_output, uint8_t channel); +audioio_get_buffer_result_t audiospeed_get_buffer(audiospeed_base_t *self, bool single_channel_output, uint8_t channel, + uint8_t **buffer, uint32_t *buffer_length); diff --git a/shared-module/bitbangio/I2C.c b/shared-module/bitbangio/I2C.c index 0089bdc1e1e..d88455729e2 100644 --- a/shared-module/bitbangio/I2C.c +++ b/shared-module/bitbangio/I2C.c @@ -8,10 +8,15 @@ #include "py/mperrno.h" #include "py/obj.h" #include "py/runtime.h" +#include "py/gc.h" #include "common-hal/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" +#include "shared-bindings/util.h" +#include "supervisor/port.h" static void delay(bitbangio_i2c_obj_t *self) { // We need to use an accurate delay to get acceptable I2C @@ -19,61 +24,81 @@ static void delay(bitbangio_i2c_obj_t *self) { common_hal_mcu_delay_us(self->us_delay); } -static void scl_low(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->scl, false); +static bool scl_low(bitbangio_i2c_obj_t *self) { + return digitalinout_protocol_set_value(self->scl, false) == 0; } -static void scl_release(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->scl, true); +static bool scl_release(bitbangio_i2c_obj_t *self) { + if (digitalinout_protocol_set_value(self->scl, true) != 0) { + return false; + } uint32_t count = self->us_timeout; delay(self); // For clock stretching, wait for the SCL pin to be released, with timeout. - common_hal_digitalio_digitalinout_switch_to_input(&self->scl, PULL_UP); - for (; !common_hal_digitalio_digitalinout_get_value(&self->scl) && count; --count) { + digitalinout_protocol_switch_to_input(self->scl, PULL_UP); + bool value; + for (; count; --count) { + if (digitalinout_protocol_get_value(self->scl, &value) != 0) { + return false; + } + if (value) { + break; + } common_hal_mcu_delay_us(1); } - common_hal_digitalio_digitalinout_switch_to_output(&self->scl, true, DRIVE_MODE_OPEN_DRAIN); + digitalinout_protocol_switch_to_output(self->scl, true, DRIVE_MODE_OPEN_DRAIN); // raise exception on timeout if (count == 0) { mp_raise_msg_varg(&mp_type_TimeoutError, MP_ERROR_TEXT("%q too long"), MP_QSTR_timeout); } + return true; } -static void sda_low(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->sda, false); +static bool sda_low(bitbangio_i2c_obj_t *self) { + return digitalinout_protocol_set_value(self->sda, false) == 0; } -static void sda_release(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_set_value(&self->sda, true); +static bool sda_release(bitbangio_i2c_obj_t *self) { + return digitalinout_protocol_set_value(self->sda, true) == 0; } -static bool sda_read(bitbangio_i2c_obj_t *self) { - common_hal_digitalio_digitalinout_switch_to_input(&self->sda, PULL_UP); - bool value = common_hal_digitalio_digitalinout_get_value(&self->sda); - common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); - return value; +static bool sda_read(bitbangio_i2c_obj_t *self, bool *value) { + digitalinout_protocol_switch_to_input(self->sda, PULL_UP); + if (digitalinout_protocol_get_value(self->sda, value) != 0) { + return false; + } + digitalinout_protocol_switch_to_output(self->sda, true, DRIVE_MODE_OPEN_DRAIN); + return true; } -static void start(bitbangio_i2c_obj_t *self) { - sda_release(self); +static bool start(bitbangio_i2c_obj_t *self) { + if (!sda_release(self)) { + return false; + } delay(self); scl_release(self); sda_low(self); delay(self); + return true; } -static void stop(bitbangio_i2c_obj_t *self) { +static bool stop(bitbangio_i2c_obj_t *self) { delay(self); - sda_low(self); + if (!sda_low(self)) { + return false; + } delay(self); scl_release(self); sda_release(self); delay(self); + return true; } static int write_byte(bitbangio_i2c_obj_t *self, uint8_t val) { delay(self); - scl_low(self); + if (!scl_low(self)) { + return -1; + } for (int i = 7; i >= 0; i--) { if ((val >> i) & 1) { @@ -90,7 +115,10 @@ static int write_byte(bitbangio_i2c_obj_t *self, uint8_t val) { delay(self); scl_release(self); - int ret = sda_read(self); + bool ret; + if (!sda_read(self, &ret)) { + return -1; + } delay(self); scl_low(self); @@ -99,13 +127,17 @@ static int write_byte(bitbangio_i2c_obj_t *self, uint8_t val) { static bool read_byte(bitbangio_i2c_obj_t *self, uint8_t *val, bool ack) { delay(self); - scl_low(self); + if (!scl_low(self)) { + return false; + } delay(self); uint8_t data = 0; for (int i = 7; i >= 0; i--) { scl_release(self); - data = (data << 1) | sda_read(self); + bool bit; + sda_read(self, &bit); + data = (data << 1) | bit; scl_low(self); delay(self); } @@ -124,8 +156,8 @@ static bool read_byte(bitbangio_i2c_obj_t *self, uint8_t *val, bool ack) { } void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, - const mcu_pin_obj_t *scl, - const mcu_pin_obj_t *sda, + mp_obj_t scl, + mp_obj_t sda, uint32_t frequency, uint32_t us_timeout) { @@ -134,32 +166,42 @@ void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, if (self->us_delay == 0) { self->us_delay = 1; } - digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->scl, scl); - if (result != DIGITALINOUT_OK) { - return; - } - result = common_hal_digitalio_digitalinout_construct(&self->sda, sda); - if (result != DIGITALINOUT_OK) { - common_hal_digitalio_digitalinout_deinit(&self->scl); - return; - } - common_hal_digitalio_digitalinout_switch_to_output(&self->scl, true, DRIVE_MODE_OPEN_DRAIN); - common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); - stop(self); + // Allocate the pins in the same place as self. + bool use_port_allocation = !gc_alloc_possible() || !gc_ptr_on_heap(self); + + // Convert scl from Pin to DigitalInOutProtocol + self->scl = digitalinout_protocol_from_pin(scl, MP_QSTR_scl, false, use_port_allocation, &self->own_scl); + + // Convert sda from Pin to DigitalInOutProtocol + self->sda = digitalinout_protocol_from_pin(sda, MP_QSTR_sda, false, use_port_allocation, &self->own_sda); + + digitalinout_protocol_switch_to_output(self->scl, true, DRIVE_MODE_OPEN_DRAIN); + digitalinout_protocol_switch_to_output(self->sda, true, DRIVE_MODE_OPEN_DRAIN); + + if (!stop(self)) { + mp_raise_OSError(MP_EIO); + } } bool shared_module_bitbangio_i2c_deinited(bitbangio_i2c_obj_t *self) { // If one is deinited, both will be. - return common_hal_digitalio_digitalinout_deinited(&self->scl); + return digitalinout_protocol_deinited(self->scl); } void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self) { if (shared_module_bitbangio_i2c_deinited(self)) { return; } - common_hal_digitalio_digitalinout_deinit(&self->scl); - common_hal_digitalio_digitalinout_deinit(&self->sda); + // Only deinit and free the pins if we own them + if (self->own_scl) { + digitalinout_protocol_deinit(self->scl); + circuitpy_free_obj(self->scl); + } + if (self->own_sda) { + digitalinout_protocol_deinit(self->sda); + circuitpy_free_obj(self->sda); + } } bool shared_module_bitbangio_i2c_try_lock(bitbangio_i2c_obj_t *self) { @@ -182,18 +224,28 @@ void shared_module_bitbangio_i2c_unlock(bitbangio_i2c_obj_t *self) { } bool shared_module_bitbangio_i2c_probe(bitbangio_i2c_obj_t *self, uint8_t addr) { - start(self); - bool ok = write_byte(self, addr << 1); + if (!start(self)) { + mp_raise_OSError(MP_EIO); + } + int result = write_byte(self, addr << 1); stop(self); - return ok; + if (result < 0) { + mp_raise_OSError(MP_EIO); + } + return result; } uint8_t shared_module_bitbangio_i2c_write(bitbangio_i2c_obj_t *self, uint16_t addr, const uint8_t *data, size_t len, bool transmit_stop_bit) { // start the I2C transaction - start(self); + if (!start(self)) { + return MP_EIO; + } uint8_t status = 0; - if (!write_byte(self, addr << 1)) { + int result = write_byte(self, addr << 1); + if (result < 0) { + status = MP_EIO; + } else if (!result) { status = MP_ENODEV; } @@ -215,7 +267,9 @@ uint8_t shared_module_bitbangio_i2c_write(bitbangio_i2c_obj_t *self, uint16_t ad uint8_t shared_module_bitbangio_i2c_read(bitbangio_i2c_obj_t *self, uint16_t addr, uint8_t *data, size_t len) { // start the I2C transaction - start(self); + if (!start(self)) { + return MP_EIO; + } uint8_t status = 0; if (!write_byte(self, (addr << 1) | 1)) { status = MP_ENODEV; diff --git a/shared-module/bitbangio/I2C.h b/shared-module/bitbangio/I2C.h index 3908a3dd374..0cec9186e9b 100644 --- a/shared-module/bitbangio/I2C.h +++ b/shared-module/bitbangio/I2C.h @@ -12,9 +12,11 @@ typedef struct { mp_obj_base_t base; - digitalio_digitalinout_obj_t scl; - digitalio_digitalinout_obj_t sda; + mp_obj_t scl; + mp_obj_t sda; uint32_t us_delay; uint32_t us_timeout; volatile bool locked; + bool own_scl; + bool own_sda; } bitbangio_i2c_obj_t; diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c index 56e978985ed..9b89d1d4a1b 100644 --- a/shared-module/bitbangio/SPI.c +++ b/shared-module/bitbangio/SPI.c @@ -7,64 +7,66 @@ #include "py/mpconfig.h" #include "py/obj.h" #include "py/runtime.h" +#include "py/gc.h" #include "common-hal/microcontroller/Pin.h" #include "shared-bindings/bitbangio/SPI.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" #include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/util.h" +#include "supervisor/port.h" #define MAX_BAUDRATE (common_hal_mcu_get_clock_frequency() / 48) void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, - const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi, - const mcu_pin_obj_t *miso) { - digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->clock, clock); - if (result != DIGITALINOUT_OK) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_clock); - } - common_hal_digitalio_digitalinout_switch_to_output(&self->clock, self->polarity == 1, DRIVE_MODE_PUSH_PULL); + mp_obj_t clock, mp_obj_t mosi, mp_obj_t miso) { - if (mosi != NULL) { - result = common_hal_digitalio_digitalinout_construct(&self->mosi, mosi); - if (result != DIGITALINOUT_OK) { - common_hal_digitalio_digitalinout_deinit(&self->clock); - mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_mosi); - } - self->has_mosi = true; - common_hal_digitalio_digitalinout_switch_to_output(&self->mosi, false, DRIVE_MODE_PUSH_PULL); - } + // Allocate the pins in the same place as self. + bool use_port_allocation = !gc_alloc_possible() || !gc_ptr_on_heap(self); - if (miso != NULL) { - // Starts out as input by default, no need to change. - result = common_hal_digitalio_digitalinout_construct(&self->miso, miso); - if (result != DIGITALINOUT_OK) { - common_hal_digitalio_digitalinout_deinit(&self->clock); - if (mosi != NULL) { - common_hal_digitalio_digitalinout_deinit(&self->mosi); - } - mp_raise_ValueError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_miso); - } - self->has_miso = true; + // Convert clock from Pin to DigitalInOutProtocol + self->clock = digitalinout_protocol_from_pin(clock, MP_QSTR_clock, false, use_port_allocation, &self->own_clock); + digitalinout_protocol_switch_to_output(self->clock, self->polarity == 1, DRIVE_MODE_PUSH_PULL); + + // Convert mosi from Pin to DigitalInOutProtocol (optional) + self->mosi = digitalinout_protocol_from_pin(mosi, MP_QSTR_mosi, true, use_port_allocation, &self->own_mosi); + self->has_mosi = (self->mosi != mp_const_none); + if (self->has_mosi) { + digitalinout_protocol_switch_to_output(self->mosi, false, DRIVE_MODE_PUSH_PULL); } + + // Convert miso from Pin to DigitalInOutProtocol (optional) + self->miso = digitalinout_protocol_from_pin(miso, MP_QSTR_miso, true, use_port_allocation, &self->own_miso); + self->has_miso = (self->miso != mp_const_none); + // MISO starts out as input by default, no need to change + self->delay_half = 5; self->polarity = 0; self->phase = 0; } bool shared_module_bitbangio_spi_deinited(bitbangio_spi_obj_t *self) { - return common_hal_digitalio_digitalinout_deinited(&self->clock); + return digitalinout_protocol_deinited(self->clock); } void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self) { if (shared_module_bitbangio_spi_deinited(self)) { return; } - common_hal_digitalio_digitalinout_deinit(&self->clock); - if (self->has_mosi) { - common_hal_digitalio_digitalinout_deinit(&self->mosi); + // Only deinit and free the pins if we own them + if (self->own_clock) { + digitalinout_protocol_deinit(self->clock); + circuitpy_free_obj(self->clock); + } + if (self->has_mosi && self->own_mosi) { + digitalinout_protocol_deinit(self->mosi); + circuitpy_free_obj(self->mosi); } - if (self->has_miso) { - common_hal_digitalio_digitalinout_deinit(&self->miso); + if (self->has_miso && self->own_miso) { + digitalinout_protocol_deinit(self->miso); + circuitpy_free_obj(self->miso); } } @@ -80,7 +82,7 @@ void shared_module_bitbangio_spi_configure(bitbangio_spi_obj_t *self, // If the polarity has changed, make sure we re-initialize the idle state // of the clock as well. self->polarity = polarity; - common_hal_digitalio_digitalinout_switch_to_output(&self->clock, polarity == 1, DRIVE_MODE_PUSH_PULL); + digitalinout_protocol_switch_to_output(self->clock, polarity == 1, DRIVE_MODE_PUSH_PULL); } self->phase = phase; } @@ -121,9 +123,15 @@ bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t for (size_t i = 0; i < len; ++i) { uint8_t data_out = data[i]; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + if (i == 0 && j == 0) { + if (digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1) != 0) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } if (dest != NULL) { dest[i] = data_in; @@ -136,16 +144,22 @@ bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t for (size_t i = 0; i < len; ++i) { uint8_t data_out = data[i]; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + if (i == 0 && j == 0) { + if (!digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1)) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } @@ -176,14 +190,18 @@ bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, if (delay_half <= MICROPY_PY_MACHINE_SPI_MIN_DELAY) { // Clock out zeroes while we read. if (self->has_mosi) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, false); + if (digitalinout_protocol_set_value(self->mosi, false) != 0) { + return false; + } } for (size_t i = 0; i < len; ++i) { uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; + digitalinout_protocol_set_value(self->clock, self->polarity); } data[i] = data_in; } @@ -191,28 +209,32 @@ bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, } #endif if (self->has_mosi) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, false); + if (!digitalinout_protocol_set_value(self->mosi, false)) { + return false; + } } for (size_t i = 0; i < len; ++i) { uint8_t data_out = write_data; uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { if (self->has_mosi) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); } if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); } - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } @@ -248,10 +270,18 @@ bool shared_module_bitbangio_spi_transfer(bitbangio_spi_obj_t *self, const uint8 uint8_t data_out = dout[i]; uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + if (i == 0 && j == 0) { + if (digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1) != 0) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; + digitalinout_protocol_set_value(self->clock, self->polarity); } din[i] = data_in; @@ -267,20 +297,28 @@ bool shared_module_bitbangio_spi_transfer(bitbangio_spi_obj_t *self, const uint8 uint8_t data_out = dout[i]; uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + if (i == 0 && j == 0) { + if (!digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1)) { + return false; + } + } else { + digitalinout_protocol_set_value(self->mosi, (data_out >> 7) & 1); + } if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + digitalinout_protocol_set_value(self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); } - data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + bool bit; + digitalinout_protocol_get_value(self->miso, &bit); + data_in = (data_in << 1) | bit; if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); } else { - common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); + digitalinout_protocol_set_value(self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } diff --git a/shared-module/bitbangio/SPI.h b/shared-module/bitbangio/SPI.h index c19170af7c4..5f3c109b7f6 100644 --- a/shared-module/bitbangio/SPI.h +++ b/shared-module/bitbangio/SPI.h @@ -12,13 +12,16 @@ typedef struct { mp_obj_base_t base; - digitalio_digitalinout_obj_t clock; - digitalio_digitalinout_obj_t mosi; - digitalio_digitalinout_obj_t miso; + mp_obj_t clock; + mp_obj_t mosi; + mp_obj_t miso; uint32_t delay_half; bool has_miso : 1; bool has_mosi : 1; uint8_t polarity : 1; uint8_t phase : 1; volatile bool locked : 1; + bool own_clock; + bool own_mosi; + bool own_miso; } bitbangio_spi_obj_t; diff --git a/shared-module/bitmapfilter/__init__.c b/shared-module/bitmapfilter/__init__.c index cdce674628c..2a54ab7443b 100644 --- a/shared-module/bitmapfilter/__init__.c +++ b/shared-module/bitmapfilter/__init__.c @@ -21,7 +21,7 @@ #include #define port_free free #define port_malloc(sz, hint) (malloc(sz)) -#define port_realloc realloc +#define port_realloc(ptr, size, dma_capable) realloc(ptr, size) #else #include "supervisor/port_heap.h" #endif @@ -48,7 +48,7 @@ static void *scratchpad_alloc(size_t sz) { } else { if (scratchpad) { if (sz > scratchpad_size) { - void *tmp = port_realloc(scratchpad, sz); + void *tmp = port_realloc(scratchpad, sz, false); if (!tmp) { port_free(scratchpad); scratchpad = NULL; diff --git a/shared-module/bitmaptools/__init__.c b/shared-module/bitmaptools/__init__.c index 8a41e387e51..e51881aa5bb 100644 --- a/shared-module/bitmaptools/__init__.c +++ b/shared-module/bitmaptools/__init__.c @@ -204,6 +204,21 @@ void common_hal_bitmaptools_rotozoom(displayio_bitmap_t *self, int16_t ox, int16 } } +void common_hal_bitmaptools_replace_color(displayio_bitmap_t *destination, + uint32_t old_color, + uint32_t new_color) { + + int16_t x, y; + for (x = 0; x < destination->width; x++) { + for (y = 0; y < destination->height; y++) { + uint32_t pixel_val = common_hal_displayio_bitmap_get_pixel(destination, x, y); + if (pixel_val == old_color) { + displayio_bitmap_write_pixel(destination, x, y, new_color); + } + } + } +} + void common_hal_bitmaptools_fill_region(displayio_bitmap_t *destination, int16_t x1, int16_t y1, int16_t x2, int16_t y2, @@ -842,12 +857,15 @@ void common_hal_bitmaptools_dither(displayio_bitmap_t *dest_bitmap, displayio_bi } void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitmap_t *source1, displayio_bitmap_t *source2, displayio_colorspace_t colorspace, mp_float_t factor1, mp_float_t factor2, - bitmaptools_blendmode_t blendmode, uint32_t skip_source1_index, bool skip_source1_index_none, uint32_t skip_source2_index, bool skip_source2_index_none) { + bitmaptools_blendmode_t blendmode, uint32_t skip_source1_index, bool skip_source1_index_none, uint32_t skip_source2_index, bool skip_source2_index_none, + displayio_bitmap_t *mask) { displayio_area_t a = {0, 0, dest->width, dest->height, NULL}; displayio_bitmap_set_dirty_area(dest, &a); - int ifactor1 = (int)(factor1 * 256); - int ifactor2 = (int)(factor2 * 256); + int ifactor1_base = (int)(factor1 * 256); + int ifactor2_base = (int)(factor2 * 256); + int ifactor1 = ifactor1_base; + int ifactor2 = ifactor2_base; bool blend_source1, blend_source2; if (colorspace == DISPLAYIO_COLORSPACE_L8) { @@ -855,10 +873,20 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma uint8_t *dptr = (uint8_t *)(dest->data + y * dest->stride); uint8_t *sptr1 = (uint8_t *)(source1->data + y * source1->stride); uint8_t *sptr2 = (uint8_t *)(source2->data + y * source2->stride); + uint8_t *mptr = mask ? (uint8_t *)(mask->data + y * mask->stride) : NULL; int pixel; for (int x = 0; x < dest->width; x++) { blend_source1 = skip_source1_index_none || *sptr1 != (uint8_t)skip_source1_index; blend_source2 = skip_source2_index_none || *sptr2 != (uint8_t)skip_source2_index; + if (mptr) { + uint8_t m = *mptr; + // Scale source2's contribution by the mask (0..255) + ifactor2 = (ifactor2_base * m + 127) / 255; + if (m == 0) { + // Mask says fully transparent: drop source2 entirely + blend_source2 = false; + } + } if (blend_source1 && blend_source2) { // Premultiply by the alpha factor int sda = *sptr1++ *ifactor1; @@ -871,7 +899,8 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma blend = sca + sda * (256 - ifactor2) / 256; } // Divide by the alpha factor - pixel = (blend / (ifactor1 + ifactor2 - ifactor1 * ifactor2 / 256)); + int denom = ifactor1 + ifactor2 - ifactor1 * ifactor2 / 256; + pixel = (denom > 0) ? (blend / denom) : 0; } else if (blend_source1) { // Apply iFactor1 to source1 only pixel = *sptr1++ *ifactor1 / 256; @@ -883,6 +912,9 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma pixel = *dptr; } *dptr++ = MIN(255, MAX(0, pixel)); + if (mptr) { + mptr++; + } } } } else { @@ -892,6 +924,7 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma uint16_t *dptr = (uint16_t *)(dest->data + y * dest->stride); uint16_t *sptr1 = (uint16_t *)(source1->data + y * source1->stride); uint16_t *sptr2 = (uint16_t *)(source2->data + y * source2->stride); + uint8_t *mptr = mask ? (uint8_t *)(mask->data + y * mask->stride) : NULL; for (int x = 0; x < dest->width; x++) { int spix1 = *sptr1++; int spix2 = *sptr2++; @@ -907,11 +940,24 @@ void common_hal_bitmaptools_alphablend(displayio_bitmap_t *dest, displayio_bitma blend_source1 = skip_source1_index_none || spix1 != (int)skip_source1_index; blend_source2 = skip_source2_index_none || spix2 != (int)skip_source2_index; + if (mptr) { + uint8_t m = *mptr++; + ifactor2 = (ifactor2_base * m + 127) / 255; + if (m == 0) { + blend_source2 = false; + } + } + if (blend_source1 && blend_source2) { // Blend based on the SVG alpha compositing specs // https://dev.w3.org/SVG/modules/compositing/master/#alphaCompositing int ifactor_blend = ifactor1 + ifactor2 - ifactor1 * ifactor2 / 256; + if (ifactor_blend <= 0) { + // Both factors are zero at this pixel; keep destination. + dptr++; + continue; + } // Premultiply the colors by the alpha factor int red_dca = ((spix1 & r_mask) >> 8) * ifactor1; diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 96735c8dbaa..6bfc0bbf0f1 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -43,15 +43,6 @@ static const board_i2c_pin_t i2c_pin[CIRCUITPY_BOARD_I2C] = CIRCUITPY_BOARD_I2C_ static busio_i2c_obj_t i2c_obj[CIRCUITPY_BOARD_I2C]; static bool i2c_obj_created[CIRCUITPY_BOARD_I2C]; -bool common_hal_board_is_i2c(mp_obj_t obj) { - for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) { - if (obj == &i2c_obj[instance]) { - return true; - } - } - return false; -} - mp_obj_t common_hal_board_get_i2c(const mp_int_t instance) { return i2c_obj_created[instance] ? &i2c_obj[instance] : NULL; } @@ -89,15 +80,6 @@ static const board_spi_pin_t spi_pin[CIRCUITPY_BOARD_SPI] = CIRCUITPY_BOARD_SPI_ static busio_spi_obj_t spi_obj[CIRCUITPY_BOARD_SPI]; static bool spi_obj_created[CIRCUITPY_BOARD_SPI]; -bool common_hal_board_is_spi(mp_obj_t obj) { - for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_SPI; instance++) { - if (obj == &spi_obj[instance]) { - return true; - } - } - return false; -} - mp_obj_t common_hal_board_get_spi(const mp_int_t instance) { return spi_obj_created[instance] ? &spi_obj[instance] : NULL; } @@ -136,15 +118,6 @@ static const board_uart_pin_t uart_pin[CIRCUITPY_BOARD_UART] = CIRCUITPY_BOARD_U static busio_uart_obj_t uart_obj[CIRCUITPY_BOARD_UART]; static bool uart_obj_created[CIRCUITPY_BOARD_UART]; -bool common_hal_board_is_uart(mp_obj_t obj) { - for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_UART; instance++) { - if (obj == &uart_obj[instance]) { - return true; - } - } - return false; -} - mp_obj_t common_hal_board_get_uart(const mp_int_t instance) { return uart_obj_created[instance] ? &uart_obj[instance] : NULL; } @@ -183,6 +156,10 @@ void reset_board_buses(void) { } } #endif + #if CIRCUITPY_I2CIOEXPANDER + // Assume the native I2C bus is used for IO Expander pins. + display_using_i2c = true; + #endif if (i2c_obj_created[instance]) { // make sure I2C lock is not held over a soft reset common_hal_busio_i2c_unlock(&i2c_obj[instance]); diff --git a/shared-module/busdisplay/BusDisplay.c b/shared-module/busdisplay/BusDisplay.c index 001f2f20c03..01e0f7a7896 100644 --- a/shared-module/busdisplay/BusDisplay.c +++ b/shared-module/busdisplay/BusDisplay.c @@ -6,6 +6,7 @@ #include "shared-bindings/busdisplay/BusDisplay.h" +#include "py/mphal.h" #include "py/runtime.h" #if CIRCUITPY_FOURWIRE #include "shared-bindings/fourwire/FourWire.h" @@ -16,6 +17,7 @@ #if CIRCUITPY_PARALLELDISPLAYBUS #include "shared-bindings/paralleldisplaybus/ParallelBus.h" #endif +#include "shared/runtime/interrupt_char.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/time/__init__.h" #include "shared-module/displayio/__init__.h" @@ -73,6 +75,9 @@ void common_hal_busdisplay_busdisplay_construct(busdisplay_busdisplay_obj_t *sel uint8_t *data = cmd + 2; while (!displayio_display_bus_begin_transaction(&self->bus)) { RUN_BACKGROUND_TASKS; + if (mp_hal_is_interrupted()) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_display); + } } if (self->bus.data_as_commands) { uint8_t full_command[data_size + 1]; @@ -80,7 +85,7 @@ void common_hal_busdisplay_busdisplay_construct(busdisplay_busdisplay_obj_t *sel memcpy(full_command + 1, data, data_size); self->bus.send(self->bus.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, full_command, data_size + 1); } else { - self->bus.send(self->bus.bus, DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, cmd, 1); + self->bus.send(self->bus.bus, DISPLAY_COMMAND, data_size > 0 ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED, cmd, 1); self->bus.send(self->bus.bus, DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, data, data_size); } displayio_display_bus_end_transaction(&self->bus); @@ -214,7 +219,7 @@ static void _send_pixels(busdisplay_busdisplay_obj_t *self, uint8_t *pixels, uin } static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_area_t *area) { - uint16_t buffer_size = 128; // In uint32_ts + uint16_t buffer_size = CIRCUITPY_DISPLAY_AREA_BUFFER_SIZE / sizeof(uint32_t); // In uint32_ts displayio_area_t clipped; // Clip the area to the display by overlapping the areas. If there is no overlap then we're done. @@ -256,9 +261,10 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are // Allocated and shared as a uint32_t array so the compiler knows the // alignment everywhere. - uint32_t buffer[buffer_size]; uint32_t mask_length = (pixels_per_buffer / 32) + 1; + uint32_t buffer[buffer_size]; uint32_t mask[mask_length]; + uint16_t remaining_rows = displayio_area_height(&clipped); for (uint16_t j = 0; j < subrectangles; j++) { @@ -273,8 +279,6 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are } remaining_rows -= rows_per_buffer; - displayio_display_bus_set_region_to_update(&self->bus, &self->core, &subrectangle); - uint16_t subrectangle_size_bytes; if (self->core.colorspace.depth >= 8) { subrectangle_size_bytes = displayio_area_size(&subrectangle) * (self->core.colorspace.depth / 8); @@ -287,21 +291,28 @@ static bool _refresh_area(busdisplay_busdisplay_obj_t *self, const displayio_are displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); + displayio_display_bus_set_region_to_update(&self->bus, &self->core, &subrectangle); + // Can't acquire display bus; skip the rest of the data. - if (!displayio_display_bus_is_free(&self->bus)) { + if (!displayio_display_bus_begin_transaction(&self->bus)) { return false; } - - displayio_display_bus_begin_transaction(&self->bus); _send_pixels(self, (uint8_t *)buffer, subrectangle_size_bytes); displayio_display_bus_end_transaction(&self->bus); - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. + // Run background tasks so they can run during an explicit refresh. + // Auto-refresh won't run background tasks here because it is a background task itself. + RUN_BACKGROUND_TASKS; + + // Run USB background tasks so they can run during an implicit refresh. #if CIRCUITPY_TINYUSB usb_background(); #endif } + + // Drain any remaining asynchronous transfers. + displayio_display_bus_flush(&self->bus); + return true; } @@ -310,7 +321,11 @@ static void _refresh_display(busdisplay_busdisplay_obj_t *self) { // A refresh on this bus is already in progress. Try next display. return; } - displayio_display_core_start_refresh(&self->core); + if (!displayio_display_core_start_refresh(&self->core)) { + // Refresh for this display already in progress. + return; + } + const displayio_area_t *current_area = _get_refresh_areas(self); while (current_area != NULL) { _refresh_area(self, current_area); diff --git a/shared-module/displayio/Bitmap.c b/shared-module/displayio/Bitmap.c index d5236f6b4f6..acc41b9eef6 100644 --- a/shared-module/displayio/Bitmap.c +++ b/shared-module/displayio/Bitmap.c @@ -31,7 +31,7 @@ void common_hal_displayio_bitmap_construct_from_buffer(displayio_bitmap_t *self, self->stride = stride(width, bits_per_value); self->data_alloc = false; if (!data) { - data = m_malloc(self->stride * height * sizeof(uint32_t)); + data = m_malloc_without_collect(self->stride * height * sizeof(uint32_t)); self->data_alloc = true; } self->data = data; diff --git a/shared-module/displayio/ColorConverter.c b/shared-module/displayio/ColorConverter.c index 512d45108eb..d4e64ee286e 100644 --- a/shared-module/displayio/ColorConverter.c +++ b/shared-module/displayio/ColorConverter.c @@ -91,6 +91,40 @@ uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888) { return hue; } +uint8_t displayio_colorconverter_compute_sixcolor(uint32_t color_rgb888) { + // This is DDX=1, the default for the displays. + uint8_t chroma = displayio_colorconverter_compute_chroma(color_rgb888); + if (chroma >= 64) { + uint8_t hue = displayio_colorconverter_compute_hue(color_rgb888); + // Red 0 + if (hue < 10) { + return 0x3; + } + // Yellow 42 + if (hue < 42 + 21) { + return 0x2; + } + // Green 85 + if (hue < 85 + 42) { + return 0x6; + } + // Blue 170 + if (hue < 170 + 42) { + return 0x5; + } + + // The rest is red to 255 + return 0x3; + } else { + uint8_t luma = displayio_colorconverter_compute_luma(color_rgb888); + if (luma >= 128) { + return 0x1; // White + } else { + return 0x0; // Black + } + } +} + uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888) { // This is DDX=1, the default for the displays. uint8_t chroma = displayio_colorconverter_compute_chroma(color_rgb888); @@ -129,8 +163,13 @@ uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888) { } } -void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color) { - +void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) { + if (pixel_chroma <= 16) { + if (!colorspace->grayscale) { + *color = 0; + } + return; + } int16_t hue_diff = colorspace->tricolor_hue - pixel_hue; if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) { if (colorspace->grayscale) { @@ -143,6 +182,21 @@ void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *co } } +void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color) { + *color >>= 1; + if (pixel_chroma <= 16) { + return; + } + int16_t hue_diff = colorspace->tricolor_hue - pixel_hue; + if ((-10 <= hue_diff && hue_diff <= 10) || hue_diff <= -220 || hue_diff >= 220) { + *color = 2; + } + int16_t hue_diff2 = colorspace->fourcolor_hue - pixel_hue; + if ((-10 <= hue_diff2 && hue_diff2 <= 10) || hue_diff2 <= -220 || hue_diff2 >= 220) { + *color = 3; + } +} + void common_hal_displayio_colorconverter_convert(displayio_colorconverter_t *self, const _displayio_colorspace_t *colorspace, uint32_t input_color, uint32_t *output_color) { displayio_input_pixel_t input_pixel; input_pixel.pixel = input_color; @@ -197,9 +251,12 @@ uint32_t displayio_colorconverter_convert_pixel(displayio_colorspace_t colorspac pixel = __builtin_bswap16(pixel); MP_FALLTHROUGH; case DISPLAYIO_COLORSPACE_RGB555: { - uint32_t r8 = (pixel >> 10) << 3; - uint32_t g8 = ((pixel >> 5) << 3) & 0xff; - uint32_t b8 = (pixel << 3) & 0xff; + uint32_t r8 = (pixel >> 10) & 0x1f; + uint32_t g8 = (pixel >> 5) & 0x1f; + uint32_t b8 = pixel & 0x1f; + r8 = (r8 << 3) | ((r8 >> 2) & 0b111); + g8 = (g8 << 3) | ((g8 >> 2) & 0b111); + b8 = (b8 << 3) | ((b8 >> 2) & 0b111); pixel = (r8 << 16) | (g8 << 8) | b8; } break; @@ -219,9 +276,12 @@ uint32_t displayio_colorconverter_convert_pixel(displayio_colorspace_t colorspac pixel = __builtin_bswap16(pixel); MP_FALLTHROUGH; case DISPLAYIO_COLORSPACE_BGR555: { - uint32_t b8 = (pixel >> 10) << 3; - uint32_t g8 = ((pixel >> 5) << 3) & 0xff; - uint32_t r8 = (pixel << 3) & 0xff; + uint32_t b8 = (pixel >> 10) & 0x1f; + uint32_t g8 = (pixel >> 5) & 0x1f; + uint32_t r8 = pixel & 0x1f; + r8 = (r8 << 3) | ((r8 >> 2) & 0b111); + g8 = (g8 << 3) | ((g8 >> 2) & 0b111); + b8 = (b8 << 3) | ((b8 >> 2) & 0b111); pixel = (r8 << 16) | (g8 << 8) | b8; } break; @@ -273,18 +333,17 @@ void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dit output_color->pixel = packed; output_color->opaque = true; return; - } else if (colorspace->tricolor) { + } else if (colorspace->tricolor || colorspace->fourcolor) { uint8_t luma = displayio_colorconverter_compute_luma(pixel); + uint8_t pixel_chroma = displayio_colorconverter_compute_chroma(pixel); output_color->pixel = luma >> (8 - colorspace->depth); - if (displayio_colorconverter_compute_chroma(pixel) <= 16) { - if (!colorspace->grayscale) { - output_color->pixel = 0; - } - output_color->opaque = true; - return; - } uint8_t pixel_hue = displayio_colorconverter_compute_hue(pixel); - displayio_colorconverter_compute_tricolor(colorspace, pixel_hue, &output_color->pixel); + if (colorspace->tricolor) { + displayio_colorconverter_compute_tricolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel); + } else if (colorspace->fourcolor) { + displayio_colorconverter_compute_fourcolor(colorspace, pixel_chroma, pixel_hue, &output_color->pixel); + } + output_color->opaque = true; return; } else if (colorspace->grayscale && colorspace->depth <= 8) { uint8_t luma = displayio_colorconverter_compute_luma(pixel); @@ -292,7 +351,7 @@ void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dit output_color->pixel = (luma >> colorspace->grayscale_bit) & bitmask; output_color->opaque = true; return; - } else if (colorspace->depth == 32) { + } else if (colorspace->depth == 32 || colorspace->depth == 24) { output_color->pixel = pixel; output_color->opaque = true; return; @@ -303,7 +362,9 @@ void displayio_convert_color(const _displayio_colorspace_t *colorspace, bool dit return; } else if (colorspace->depth == 4) { uint8_t packed; - if (colorspace->sevencolor) { + if (colorspace->sixcolor) { + packed = displayio_colorconverter_compute_sixcolor(pixel); + } else if (colorspace->sevencolor) { packed = displayio_colorconverter_compute_sevencolor(pixel); } else { packed = displayio_colorconverter_compute_rgbd(pixel); diff --git a/shared-module/displayio/ColorConverter.h b/shared-module/displayio/ColorConverter.h index 60efc132f9a..304004d566a 100644 --- a/shared-module/displayio/ColorConverter.h +++ b/shared-module/displayio/ColorConverter.h @@ -41,5 +41,7 @@ uint8_t displayio_colorconverter_compute_rgbd(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_luma(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_chroma(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_hue(uint32_t color_rgb888); +uint8_t displayio_colorconverter_compute_sixcolor(uint32_t color_rgb888); uint8_t displayio_colorconverter_compute_sevencolor(uint32_t color_rgb888); -void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_hue, uint32_t *color); +void displayio_colorconverter_compute_tricolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color); +void displayio_colorconverter_compute_fourcolor(const _displayio_colorspace_t *colorspace, uint8_t pixel_chroma, uint8_t pixel_hue, uint32_t *color); diff --git a/shared-module/displayio/Group.c b/shared-module/displayio/Group.c index e2a1a527062..a2bf685d0f7 100644 --- a/shared-module/displayio/Group.c +++ b/shared-module/displayio/Group.c @@ -251,7 +251,11 @@ static void _add_layer(displayio_group_t *self, mp_obj_t layer) { #if CIRCUITPY_VECTORIO const vectorio_draw_protocol_t *draw_protocol = mp_proto_get(MP_QSTR_protocol_draw, layer); if (draw_protocol != NULL) { - draw_protocol->draw_protocol_impl->draw_update_transform(draw_protocol->draw_get_protocol_self(layer), &self->absolute_transform); + mp_obj_t protocol_self = draw_protocol->draw_get_protocol_self(layer); + if (draw_protocol->draw_protocol_impl->draw_set_in_group(protocol_self, true)) { + mp_raise_ValueError(MP_ERROR_TEXT("Layer already in a group")); + } + draw_protocol->draw_protocol_impl->draw_update_transform(protocol_self, &self->absolute_transform); return; } #endif @@ -296,6 +300,7 @@ static void _remove_layer(displayio_group_t *self, size_t index) { bool has_dirty_area = draw_protocol->draw_protocol_impl->draw_get_dirty_area(layer, &layer_area); rendered_last_frame = has_dirty_area; draw_protocol->draw_protocol_impl->draw_update_transform(layer, NULL); + draw_protocol->draw_protocol_impl->draw_set_in_group(layer, false); } #endif layer = mp_obj_cast_to_native_base( diff --git a/shared-module/displayio/OnDiskBitmap.c b/shared-module/displayio/OnDiskBitmap.c index 6777bd738a9..9abe8cf4fe1 100644 --- a/shared-module/displayio/OnDiskBitmap.c +++ b/shared-module/displayio/OnDiskBitmap.c @@ -1,6 +1,7 @@ // This file is part of the CircuitPython project: https://circuitpython.org // // SPDX-FileCopyrightText: Copyright (c) 2018 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 SamantazFox // // SPDX-License-Identifier: MIT @@ -15,6 +16,11 @@ #include "py/mperrno.h" #include "py/runtime.h" + +#define DISPLAYIO_ODBMP_DEBUG(...) (void)0 +// #define DISPLAYIO_ODBMP_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__) + + static uint32_t read_word(uint16_t *bmp_header, uint16_t index) { return bmp_header[index] | bmp_header[index + 1] << 16; } @@ -25,39 +31,63 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, uint16_t bmp_header[69]; f_rewind(&self->file->fp); UINT bytes_read; - if (f_read(&self->file->fp, bmp_header, 138, &bytes_read) != FR_OK) { + + // Read the minimum amount of bytes required to parse a BITMAPCOREHEADER. + // If needed, we will read more bytes down below. + if (f_read(&self->file->fp, bmp_header, 26, &bytes_read) != FR_OK) { mp_raise_OSError(MP_EIO); } - if (bytes_read != 138 || - memcmp(bmp_header, "BM", 2) != 0) { + DISPLAYIO_ODBMP_DEBUG("bytes_read: %d\n", bytes_read); + if (bytes_read != 26 || memcmp(bmp_header, "BM", 2) != 0) { mp_arg_error_invalid(MP_QSTR_file); } - // We can't cast because we're not aligned. - self->data_offset = read_word(bmp_header, 5); - + // Read header size to determine if more header bytes needs to be read. uint32_t header_size = read_word(bmp_header, 7); - uint16_t bits_per_pixel = bmp_header[14]; + DISPLAYIO_ODBMP_DEBUG("header_size: %d\n", header_size); + + if (header_size == 40 || header_size == 108 || header_size == 124) { + // Read the remaining header bytes + if (f_read(&self->file->fp, bmp_header + 13, header_size - 12, &bytes_read) != FR_OK) { + mp_raise_OSError(MP_EIO); + } + DISPLAYIO_ODBMP_DEBUG("bytes_read: %d\n", bytes_read); + if (bytes_read != (header_size - 12)) { + mp_arg_error_invalid(MP_QSTR_file); + } + } else if (header_size != 12) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Only Windows format, uncompressed BMP supported: given header size is %d"), header_size); + } + + uint32_t compression = read_word(bmp_header, 15); - uint32_t number_of_colors = read_word(bmp_header, 23); + DISPLAYIO_ODBMP_DEBUG("compression: %d\n", compression); // 0 is uncompressed; 3 is bitfield compressed. 1 and 2 are RLE compression. if (compression != 0 && compression != 3) { mp_raise_ValueError(MP_ERROR_TEXT("RLE-compressed BMP not supported")); } - bool indexed = bits_per_pixel <= 8; + // We can't cast because we're not aligned. + self->data_offset = read_word(bmp_header, 5); + self->bitfield_compressed = (compression == 3); - self->bits_per_pixel = bits_per_pixel; + self->bits_per_pixel = bmp_header[14]; self->width = read_word(bmp_header, 9); self->height = read_word(bmp_header, 11); + DISPLAYIO_ODBMP_DEBUG("data offset: %d\n", self->data_offset); + DISPLAYIO_ODBMP_DEBUG("width: %d\n", self->width); + DISPLAYIO_ODBMP_DEBUG("height: %d\n", self->height); + DISPLAYIO_ODBMP_DEBUG("bpp: %d\n", self->bits_per_pixel); + + displayio_colorconverter_t *colorconverter = mp_obj_malloc(displayio_colorconverter_t, &displayio_colorconverter_type); common_hal_displayio_colorconverter_construct(colorconverter, false, DISPLAYIO_COLORSPACE_RGB888); self->colorconverter = colorconverter; - if (bits_per_pixel == 16) { + if (self->bits_per_pixel == 16) { if (((header_size >= 56)) || (self->bitfield_compressed)) { self->r_bitmask = read_word(bmp_header, 27); self->g_bitmask = read_word(bmp_header, 29); @@ -68,9 +98,13 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, self->g_bitmask = 0x3e0; self->b_bitmask = 0x1f; } - } else if (indexed) { + } else if (self->bits_per_pixel <= 8) { // indexed + uint32_t number_of_colors = 0; + if (header_size >= 40) { + number_of_colors = read_word(bmp_header, 23); + } if (number_of_colors == 0) { - number_of_colors = 1 << bits_per_pixel; + number_of_colors = 1 << self->bits_per_pixel; } displayio_palette_t *palette = mp_obj_malloc(displayio_palette_t, &displayio_palette_type); @@ -80,7 +114,7 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, uint16_t palette_size = number_of_colors * sizeof(uint32_t); uint16_t palette_offset = 0xe + header_size; - uint32_t *palette_data = m_malloc(palette_size); + uint32_t *palette_data = m_malloc_without_collect(palette_size); f_rewind(&self->file->fp); f_lseek(&self->file->fp, palette_offset); @@ -95,19 +129,17 @@ void common_hal_displayio_ondiskbitmap_construct(displayio_ondiskbitmap_t *self, for (uint16_t i = 0; i < number_of_colors; i++) { common_hal_displayio_palette_set_color(palette, i, palette_data[i]); } + + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(palette_data, palette_size); + #else m_free(palette_data); + #endif } else { common_hal_displayio_palette_set_color(palette, 0, 0x0); common_hal_displayio_palette_set_color(palette, 1, 0xffffff); } self->palette = palette; - - } else if (!(header_size == 12 || header_size == 40 || header_size == 108 || header_size == 124)) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("Only Windows format, uncompressed BMP supported: given header size is %d"), header_size); - } - - if (bits_per_pixel == 8 && number_of_colors == 0) { - mp_raise_ValueError_varg(MP_ERROR_TEXT("Only monochrome, indexed 4bpp or 8bpp, and 16bpp or greater BMPs supported: %d bpp given"), bits_per_pixel); } uint8_t bytes_per_pixel = (self->bits_per_pixel / 8) ? (self->bits_per_pixel / 8) : 1; diff --git a/shared-module/displayio/Palette.c b/shared-module/displayio/Palette.c index d80f1c47da1..968296c69f1 100644 --- a/shared-module/displayio/Palette.c +++ b/shared-module/displayio/Palette.c @@ -10,7 +10,7 @@ void common_hal_displayio_palette_construct(displayio_palette_t *self, uint16_t color_count, bool dither) { self->color_count = color_count; - self->colors = (_displayio_color_t *)m_malloc(color_count * sizeof(_displayio_color_t)); + self->colors = (_displayio_color_t *)m_malloc_without_collect(color_count * sizeof(_displayio_color_t)); self->dither = dither; } diff --git a/shared-module/displayio/Palette.h b/shared-module/displayio/Palette.h index 092b934b66a..24ae5c4b7a5 100644 --- a/shared-module/displayio/Palette.h +++ b/shared-module/displayio/Palette.h @@ -15,10 +15,12 @@ typedef struct { uint8_t depth; uint8_t bytes_per_cell; uint8_t tricolor_hue; - uint8_t tricolor_luma; + uint8_t fourcolor_hue; uint8_t grayscale_bit; // The lowest grayscale bit. Normally 8 - depth. bool grayscale; bool tricolor; + bool fourcolor; + bool sixcolor; // Spectra6 e-ink screens. bool sevencolor; // Acep e-ink screens. bool pixels_in_byte_share_row; bool reverse_pixels_in_byte; diff --git a/shared-module/displayio/Shape.c b/shared-module/displayio/Shape.c deleted file mode 100644 index f36e9e32ac1..00000000000 --- a/shared-module/displayio/Shape.c +++ /dev/null @@ -1,126 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries -// -// SPDX-License-Identifier: MIT - -#include "shared-bindings/displayio/Shape.h" - -#include - -#include "py/runtime.h" -#include "py/misc.h" - -void common_hal_displayio_shape_construct(displayio_shape_t *self, uint32_t width, - uint32_t height, bool mirror_x, bool mirror_y) { - self->mirror_x = mirror_x; - self->mirror_y = mirror_y; - self->width = width; - if (self->mirror_x) { - width /= 2; - width += self->width % 2; - } - self->half_width = width; - - self->height = height; - if (self->mirror_y) { - height /= 2; - height += self->height % 2; - } - self->half_height = height; - - self->data = m_malloc(height * sizeof(uint32_t)); - - for (uint16_t i = 0; i < height; i++) { - self->data[2 * i] = 0; - self->data[2 * i + 1] = width; - } - - self->dirty_area.x1 = 0; - self->dirty_area.x2 = width; - self->dirty_area.y1 = 0; - self->dirty_area.y2 = height; -} - -void common_hal_displayio_shape_set_boundary(displayio_shape_t *self, uint16_t y, uint16_t start_x, uint16_t end_x) { - uint16_t max_y = self->height - 1; - if (self->mirror_y) { - max_y = self->half_height - 1; - } - mp_arg_validate_int_range(y, 0, max_y, MP_QSTR_y); - uint16_t max_x = self->width - 1; - if (self->mirror_x) { - max_x = self->half_width - 1; - } - mp_arg_validate_int_range(start_x, 0, max_x, MP_QSTR_start_x); - mp_arg_validate_int_range(end_x, 0, max_x, MP_QSTR_end_x); - - uint16_t lower_x, upper_x, lower_y, upper_y; - - // find x-boundaries for updating based on current data and start_x, end_x, and mirror_x - lower_x = MIN(start_x, self->data[2 * y]); - - if (self->mirror_x) { - upper_x = self->width - lower_x + 1; // dirty rectangles are treated with max value exclusive - } else { - upper_x = MAX(end_x, self->data[2 * y + 1]) + 1; // dirty rectangles are treated with max value exclusive - } - - // find y-boundaries based on y and mirror_y - lower_y = y; - - if (self->mirror_y) { - upper_y = self->height - lower_y + 1; // dirty rectangles are treated with max value exclusive - } else { - upper_y = y + 1; // dirty rectangles are treated with max value exclusive - } - - self->data[2 * y] = start_x; // update the data array with the new boundaries - self->data[2 * y + 1] = end_x; - - if (self->dirty_area.x1 == self->dirty_area.x2) { // Dirty region is empty - self->dirty_area.x1 = lower_x; - self->dirty_area.x2 = upper_x; - self->dirty_area.y1 = lower_y; - self->dirty_area.y2 = upper_y; - - } else { // Dirty region is not empty - self->dirty_area.x1 = MIN(lower_x, self->dirty_area.x1); - self->dirty_area.x2 = MAX(upper_x, self->dirty_area.x2); - - self->dirty_area.y1 = MIN(lower_y, self->dirty_area.y1); - self->dirty_area.y2 = MAX(upper_y, self->dirty_area.y2); - } -} - -uint32_t common_hal_displayio_shape_get_pixel(void *obj, int16_t x, int16_t y) { - displayio_shape_t *self = obj; - if (x >= self->width || x < 0 || y >= self->height || y < 0) { - return 0; - } - if (self->mirror_x && x >= self->half_width) { - x = self->width - x - 1; - } - if (self->mirror_y && y >= self->half_height) { - y = self->height - y - 1; - } - uint16_t start_x = self->data[2 * y]; - uint16_t end_x = self->data[2 * y + 1]; - if (x < start_x || x > end_x) { - return 0; - } - return 1; -} - -displayio_area_t *displayio_shape_get_refresh_areas(displayio_shape_t *self, displayio_area_t *tail) { - if (self->dirty_area.x1 == self->dirty_area.x2) { - return tail; - } - self->dirty_area.next = tail; - return &self->dirty_area; -} - -void displayio_shape_finish_refresh(displayio_shape_t *self) { - self->dirty_area.x1 = 0; - self->dirty_area.x2 = 0; -} diff --git a/shared-module/displayio/Shape.h b/shared-module/displayio/Shape.h deleted file mode 100644 index 20ee182023f..00000000000 --- a/shared-module/displayio/Shape.h +++ /dev/null @@ -1,28 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2019 Scott Shawcroft for Adafruit Industries -// -// SPDX-License-Identifier: MIT - -#pragma once - -#include -#include - -#include "py/obj.h" -#include "shared-module/displayio/area.h" - -typedef struct { - mp_obj_base_t base; - uint16_t width; - uint16_t height; - uint16_t half_width; - uint16_t half_height; - uint16_t *data; - bool mirror_x; - bool mirror_y; - displayio_area_t dirty_area; -} displayio_shape_t; - -void displayio_shape_finish_refresh(displayio_shape_t *self); -displayio_area_t *displayio_shape_get_refresh_areas(displayio_shape_t *self, displayio_area_t *tail); diff --git a/shared-module/displayio/TileGrid.c b/shared-module/displayio/TileGrid.c index 137dc02250e..b5c691ccbd6 100644 --- a/shared-module/displayio/TileGrid.c +++ b/shared-module/displayio/TileGrid.c @@ -11,30 +11,57 @@ #include "shared-bindings/displayio/ColorConverter.h" #include "shared-bindings/displayio/OnDiskBitmap.h" #include "shared-bindings/displayio/Palette.h" +#if CIRCUITPY_TILEPALETTEMAPPER +#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h" +#endif + +#include "supervisor/shared/serial.h" void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_t bitmap, uint16_t bitmap_width_in_tiles, uint16_t bitmap_height_in_tiles, mp_obj_t pixel_shader, uint16_t width, uint16_t height, - uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint8_t default_tile) { + uint16_t tile_width, uint16_t tile_height, uint16_t x, uint16_t y, uint16_t default_tile) { + uint32_t total_tiles = width * height; + self->bitmap_width_in_tiles = bitmap_width_in_tiles; + self->tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles; + + // Determine if we need uint16_t or uint8_t for tile indices + bool use_uint16 = self->tiles_in_bitmap > 255; + // Sprites will only have one tile so save a little memory by inlining values in the pointer. - uint8_t inline_tiles = sizeof(uint8_t *); + uint8_t inline_tiles = sizeof(void *) / (use_uint16 ? sizeof(uint16_t) : sizeof(uint8_t)); + if (total_tiles <= inline_tiles) { self->tiles = 0; // Pack values into the pointer since there are only a few. - for (uint32_t i = 0; i < inline_tiles; i++) { - ((uint8_t *)&self->tiles)[i] = default_tile; + if (use_uint16) { + for (uint32_t i = 0; i < inline_tiles && i < total_tiles; i++) { + ((uint16_t *)&self->tiles)[i] = default_tile; + } + } else { + for (uint32_t i = 0; i < inline_tiles && i < total_tiles; i++) { + ((uint8_t *)&self->tiles)[i] = (uint8_t)default_tile; + } } self->inline_tiles = true; } else { - self->tiles = (uint8_t *)m_malloc(total_tiles); - for (uint32_t i = 0; i < total_tiles; i++) { - self->tiles[i] = default_tile; + if (use_uint16) { + uint16_t *tiles16 = (uint16_t *)m_malloc_without_collect(total_tiles * sizeof(uint16_t)); + for (uint32_t i = 0; i < total_tiles; i++) { + tiles16[i] = default_tile; + } + self->tiles = tiles16; + } else { + uint8_t *tiles8 = (uint8_t *)m_malloc_without_collect(total_tiles); + for (uint32_t i = 0; i < total_tiles; i++) { + tiles8[i] = (uint8_t)default_tile; + } + self->tiles = tiles8; } self->inline_tiles = false; } - self->bitmap_width_in_tiles = bitmap_width_in_tiles; - self->tiles_in_bitmap = bitmap_width_in_tiles * bitmap_height_in_tiles; + self->width_in_tiles = width; self->height_in_tiles = height; self->x = x; @@ -54,6 +81,11 @@ void common_hal_displayio_tilegrid_construct(displayio_tilegrid_t *self, mp_obj_ self->flip_y = false; self->transpose_xy = false; self->absolute_transform = NULL; + #if CIRCUITPY_TILEPALETTEMAPPER + if (mp_obj_is_type(self->pixel_shader, &tilepalettemapper_tilepalettemapper_type)) { + tilepalettemapper_tilepalettemapper_bind(self->pixel_shader, self); + } + #endif } @@ -204,6 +236,11 @@ mp_obj_t common_hal_displayio_tilegrid_get_pixel_shader(displayio_tilegrid_t *se void common_hal_displayio_tilegrid_set_pixel_shader(displayio_tilegrid_t *self, mp_obj_t pixel_shader) { self->pixel_shader = pixel_shader; self->full_change = true; + #if CIRCUITPY_TILEPALETTEMAPPER + if (mp_obj_is_type(self->pixel_shader, &tilepalettemapper_tilepalettemapper_type)) { + tilepalettemapper_tilepalettemapper_bind(self->pixel_shader, self); + } + #endif } mp_obj_t common_hal_displayio_tilegrid_get_bitmap(displayio_tilegrid_t *self) { @@ -231,29 +268,24 @@ uint16_t common_hal_displayio_tilegrid_get_tile_height(displayio_tilegrid_t *sel return self->tile_height; } -uint8_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y) { - uint8_t *tiles = self->tiles; +uint16_t common_hal_displayio_tilegrid_get_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y) { + void *tiles = self->tiles; if (self->inline_tiles) { - tiles = (uint8_t *)&self->tiles; + tiles = &self->tiles; } if (tiles == NULL) { return 0; } - return tiles[y * self->width_in_tiles + x]; -} -void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint8_t tile_index) { - if (tile_index >= self->tiles_in_bitmap) { - mp_raise_ValueError(MP_ERROR_TEXT("Tile index out of bounds")); - } - uint8_t *tiles = self->tiles; - if (self->inline_tiles) { - tiles = (uint8_t *)&self->tiles; - } - if (tiles == NULL) { - return; + uint32_t index = y * self->width_in_tiles + x; + if (self->tiles_in_bitmap > 255) { + return ((uint16_t *)tiles)[index]; + } else { + return ((uint8_t *)tiles)[index]; } - tiles[y * self->width_in_tiles + x] = tile_index; +} + +void displayio_tilegrid_mark_tile_dirty(displayio_tilegrid_t *self, uint16_t x, uint16_t y) { displayio_area_t temp_area; displayio_area_t *tile_area; if (!self->partial_change) { @@ -277,25 +309,57 @@ void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t if (self->partial_change) { displayio_area_union(&self->dirty_area, &temp_area, &self->dirty_area); } - self->partial_change = true; } -void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint8_t tile_index) { +void common_hal_displayio_tilegrid_set_tile(displayio_tilegrid_t *self, uint16_t x, uint16_t y, uint16_t tile_index) { + if (tile_index >= self->tiles_in_bitmap) { + mp_raise_ValueError(MP_ERROR_TEXT("Tile index out of bounds")); + } + + void *tiles = self->tiles; + if (self->inline_tiles) { + tiles = &self->tiles; + } + if (tiles == NULL) { + return; + } + + uint32_t index = y * self->width_in_tiles + x; + if (self->tiles_in_bitmap > 255) { + ((uint16_t *)tiles)[index] = tile_index; + } else { + ((uint8_t *)tiles)[index] = (uint8_t)tile_index; + } + displayio_tilegrid_mark_tile_dirty(self, x, y); +} + +void common_hal_displayio_tilegrid_set_all_tiles(displayio_tilegrid_t *self, uint16_t tile_index) { if (tile_index >= self->tiles_in_bitmap) { mp_raise_ValueError(MP_ERROR_TEXT("Tile index out of bounds")); } - uint8_t *tiles = self->tiles; + + void *tiles = self->tiles; if (self->inline_tiles) { - tiles = (uint8_t *)&self->tiles; + tiles = &self->tiles; } if (tiles == NULL) { return; } - for (uint16_t x = 0; x < self->width_in_tiles; x++) { + if (self->tiles_in_bitmap > 255) { + uint16_t *tiles16 = (uint16_t *)tiles; for (uint16_t y = 0; y < self->height_in_tiles; y++) { - tiles[y * self->width_in_tiles + x] = tile_index; + for (uint16_t x = 0; x < self->width_in_tiles; x++) { + tiles16[y * self->width_in_tiles + x] = tile_index; + } + } + } else { + uint8_t *tiles8 = (uint8_t *)tiles; + for (uint16_t y = 0; y < self->height_in_tiles; y++) { + for (uint16_t x = 0; x < self->width_in_tiles; x++) { + tiles8[y * self->width_in_tiles + x] = (uint8_t)tile_index; + } } } @@ -365,9 +429,9 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, const _displayio_colorspace_t *colorspace, const displayio_area_t *area, uint32_t *mask, uint32_t *buffer) { // If no tiles are present we have no impact. - uint8_t *tiles = self->tiles; + void *tiles = self->tiles; if (self->inline_tiles) { - tiles = (uint8_t *)&self->tiles; + tiles = &self->tiles; } if (tiles == NULL) { return false; @@ -448,8 +512,6 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, y_shift = temp_shift; } - uint8_t pixels_per_byte = 8 / colorspace->depth; - displayio_input_pixel_t input_pixel; displayio_output_pixel_t output_pixel; @@ -470,8 +532,15 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, continue; } int16_t local_x = input_pixel.x / self->absolute_transform->scale; - uint16_t tile_location = ((local_y / self->tile_height + self->top_left_y) % self->height_in_tiles) * self->width_in_tiles + (local_x / self->tile_width + self->top_left_x) % self->width_in_tiles; - input_pixel.tile = tiles[tile_location]; + uint16_t x_tile_index = (local_x / self->tile_width + self->top_left_x) % self->width_in_tiles; + uint16_t y_tile_index = (local_y / self->tile_height + self->top_left_y) % self->height_in_tiles; + uint16_t tile_location = y_tile_index * self->width_in_tiles + x_tile_index; + + if (self->tiles_in_bitmap > 255) { + input_pixel.tile = ((uint16_t *)tiles)[tile_location]; + } else { + input_pixel.tile = ((uint8_t *)tiles)[tile_location]; + } input_pixel.tile_x = (input_pixel.tile % self->bitmap_width_in_tiles) * self->tile_width + local_x % self->tile_width; input_pixel.tile_y = (input_pixel.tile / self->bitmap_width_in_tiles) * self->tile_height + local_y % self->tile_height; @@ -487,6 +556,11 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, } output_pixel.opaque = true; + #if CIRCUITPY_TILEPALETTEMAPPER + if (mp_obj_is_type(self->pixel_shader, &tilepalettemapper_tilepalettemapper_type)) { + tilepalettemapper_tilepalettemapper_get_color(self->pixel_shader, colorspace, &input_pixel, &output_pixel, x_tile_index, y_tile_index); + } + #endif if (self->pixel_shader == mp_const_none) { output_pixel.pixel = input_pixel.pixel; } else if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { @@ -503,9 +577,13 @@ bool displayio_tilegrid_fill_area(displayio_tilegrid_t *self, *(((uint16_t *)buffer) + offset) = output_pixel.pixel; } else if (colorspace->depth == 32) { *(((uint32_t *)buffer) + offset) = output_pixel.pixel; + } else if (colorspace->depth == 24) { + memcpy(((uint8_t *)buffer) + offset * 3, &output_pixel.pixel, 3); } else if (colorspace->depth == 8) { *(((uint8_t *)buffer) + offset) = output_pixel.pixel; } else if (colorspace->depth < 8) { + uint8_t pixels_per_byte = 8 / colorspace->depth; + // Reorder the offsets to pack multiple rows into a byte (meaning they share a column). if (!colorspace->pixels_in_byte_share_row) { uint16_t width = displayio_area_width(area); @@ -601,6 +679,7 @@ displayio_area_t *displayio_tilegrid_get_refresh_areas(displayio_tilegrid_t *sel displayio_palette_needs_refresh(self->pixel_shader)) || (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type) && displayio_colorconverter_needs_refresh(self->pixel_shader)); + if (self->full_change || first_draw) { self->current_area.next = tail; return &self->current_area; diff --git a/shared-module/displayio/TileGrid.h b/shared-module/displayio/TileGrid.h index c9c31696bf8..0051cc0ebf1 100644 --- a/shared-module/displayio/TileGrid.h +++ b/shared-module/displayio/TileGrid.h @@ -30,7 +30,7 @@ typedef struct { uint16_t tile_height; uint16_t top_left_x; uint16_t top_left_y; - uint8_t *tiles; + void *tiles; // Can be either uint8_t* or uint16_t* depending on tiles_in_bitmap const displayio_buffer_transform_t *absolute_transform; displayio_area_t dirty_area; // Stored as a relative area until the refresh area is fetched. displayio_area_t previous_area; // Stored as an absolute area. @@ -67,3 +67,6 @@ bool displayio_tilegrid_get_previous_area(displayio_tilegrid_t *self, displayio_ void displayio_tilegrid_finish_refresh(displayio_tilegrid_t *self); bool displayio_tilegrid_get_rendered_hidden(displayio_tilegrid_t *self); +void displayio_tilegrid_validate_pixel_shader(mp_obj_t pixel_shader); + +void displayio_tilegrid_mark_tile_dirty(displayio_tilegrid_t *self, uint16_t x, uint16_t y); diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 8b3c9556f48..c1309ee0972 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -10,8 +10,11 @@ #include "shared-bindings/displayio/__init__.h" #include "shared/runtime/interrupt_char.h" +#include "py/gc.h" #include "py/runtime.h" #include "shared-bindings/board/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/busio/SPI.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" @@ -39,10 +42,20 @@ #include "shared-module/aurora_epaper/aurora_framebuffer.h" #endif +#if CIRCUITPY_MIPIDSI +#include "shared-bindings/mipidsi/Display.h" +#endif +#if CIRCUITPY_ZEPHYR_DISPLAY +#include "bindings/zephyr_display/Display.h" +#endif + #ifdef BOARD_USE_INTERNAL_SPI #include "supervisor/spi_flash_api.h" #endif +// The default indicates no primary display +static int primary_display_number = -1; + primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; @@ -59,7 +72,7 @@ displayio_buffer_transform_t null_transform = { .transpose_xy = false }; -#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI +#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI || CIRCUITPY_MIPIDSI static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) { @@ -102,15 +115,25 @@ void displayio_background(void) { } else if (display_type == &epaperdisplay_epaperdisplay_type) { epaperdisplay_epaperdisplay_background(&displays[i].epaper_display); #endif + #if CIRCUITPY_ZEPHYR_DISPLAY + } else if (display_type == &zephyr_display_display_type) { + zephyr_display_display_background(&displays[i].zephyr_display); + #endif } } } -void common_hal_displayio_release_displays(void) { +static void common_hal_displayio_release_displays_impl(bool keep_primary) { // Release displays before busses so that they can send any final commands to turn the display // off properly. + if (!keep_primary) { + primary_display_number = -1; + } for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (i == primary_display_number) { + continue; + } mp_const_obj_t display_type = displays[i].display_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { continue; @@ -126,10 +149,17 @@ void common_hal_displayio_release_displays(void) { } else if (display_type == &framebufferio_framebufferdisplay_type) { release_framebufferdisplay(&displays[i].framebuffer_display); #endif + #if CIRCUITPY_ZEPHYR_DISPLAY + } else if (display_type == &zephyr_display_display_type) { + release_zephyr_display(&displays[i].zephyr_display); + #endif } displays[i].display_base.type = &mp_type_NoneType; } for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (i == primary_display_number) { + continue; + } mp_const_obj_t bus_type = display_buses[i].bus_base.type; if (bus_type == NULL || bus_type == &mp_type_NoneType) { continue; @@ -169,18 +199,37 @@ void common_hal_displayio_release_displays(void) { } else if (bus_type == &picodvi_framebuffer_type) { common_hal_picodvi_framebuffer_deinit(&display_buses[i].picodvi); #endif + #if CIRCUITPY_MIPIDSI + } else if (bus_type == &mipidsi_display_type) { + common_hal_mipidsi_display_deinit(&display_buses[i].mipidsi); + #endif + #if CIRCUITPY_QSPIBUS + } else if (bus_type == &qspibus_qspibus_type) { + common_hal_qspibus_qspibus_deinit(&display_buses[i].qspi_bus); + #endif } display_buses[i].bus_base.type = &mp_type_NoneType; } - supervisor_stop_terminal(); + if (!keep_primary) { + supervisor_stop_terminal(); + } +} + +void common_hal_displayio_release_displays(void) { + common_hal_displayio_release_displays_impl(false); } void reset_displays(void) { + // TODO: In CircuitPython 11, uncomment the call. + // Release secondary displays. + // common_hal_displayio_release_displays_impl(/*keep_primary*/ true); + // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { + display_buses[i].bus_base.type = &mp_type_NoneType; continue; #if CIRCUITPY_FOURWIRE } else if (display_bus_type == &fourwire_fourwire_type) { @@ -188,21 +237,12 @@ void reset_displays(void) { if (((size_t)fourwire->bus) < ((size_t)&display_buses) || ((size_t)fourwire->bus) > ((size_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT * sizeof(primary_display_bus_t))) { busio_spi_obj_t *original_spi = fourwire->bus; - #if CIRCUITPY_BOARD_SPI - // We don't need to move original_spi if it is a board.SPI object because it is - // statically allocated already. (Doing so would also make it impossible to reference in - // a subsequent VM run.) - if (common_hal_board_is_spi(original_spi)) { + if (!gc_ptr_on_heap(original_spi)) { continue; } - #endif - #ifdef BOARD_USE_INTERNAL_SPI - if (original_spi == (mp_obj_t)(&supervisor_flash_spi_bus)) { - continue; - } - #endif memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); fourwire->bus = &fourwire->inline_bus; + // Check for other display buses that use the same spi bus and swap them too. for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { if (display_buses[j].fourwire_bus.base.type == &fourwire_fourwire_type && @@ -210,6 +250,8 @@ void reset_displays(void) { display_buses[j].fourwire_bus.bus = &fourwire->inline_bus; } } + // Mark the old SPI object so it is considered deinit. + common_hal_busio_spi_mark_deinit(original_spi); } #endif #if CIRCUITPY_I2CDISPLAYBUS @@ -219,14 +261,9 @@ void reset_displays(void) { if (((size_t)i2c->bus) < ((size_t)&display_buses) || ((size_t)i2c->bus) > ((size_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT * sizeof(primary_display_bus_t))) { busio_i2c_obj_t *original_i2c = i2c->bus; - #if CIRCUITPY_BOARD_I2C - // We don't need to move original_i2c if it is a board.I2C object because it is - // statically allocated already. (Doing so would also make it impossible to reference in - // a subsequent VM run.) - if (common_hal_board_is_i2c(original_i2c)) { + if (!gc_ptr_on_heap(original_i2c)) { continue; } - #endif memcpy(&i2c->inline_bus, original_i2c, sizeof(busio_i2c_obj_t)); i2c->bus = &i2c->inline_bus; // Check for other displays that use the same i2c bus and swap them too. @@ -236,6 +273,8 @@ void reset_displays(void) { display_buses[j].i2cdisplay_bus.bus = &i2c->inline_bus; } } + // Mark the old i2c object so it is considered deinit. + common_hal_busio_i2c_mark_deinit(original_i2c); } #endif #if CIRCUITPY_RGBMATRIX @@ -253,22 +292,17 @@ void reset_displays(void) { if (((uint32_t)is31fb->is31fl3741->i2c) < ((uint32_t)&display_buses) || ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT)) { - #if CIRCUITPY_BOARD_I2C - // We don't need to move original_i2c if it is the board.I2C object because it is - // statically allocated already. (Doing so would also make it impossible to reference in - // a subsequent VM run.) - if (common_hal_board_is_i2c(is31fb->is31fl3741->i2c)) { - continue; - } - #endif - is31fl3741_IS31FL3741_obj_t *original_is31 = is31fb->is31fl3741; - memcpy(&is31fb->inline_is31fl3741, original_is31, sizeof(is31fl3741_IS31FL3741_obj_t)); - is31fb->is31fl3741 = &is31fb->inline_is31fl3741; + if (gc_ptr_on_heap(original_is31)) { + memcpy(&is31fb->inline_is31fl3741, original_is31, sizeof(is31fl3741_IS31FL3741_obj_t)); + is31fb->is31fl3741 = &is31fb->inline_is31fl3741; + } busio_i2c_obj_t *original_i2c = is31fb->is31fl3741->i2c; - memcpy(&is31fb->is31fl3741->inline_i2c, original_i2c, sizeof(busio_i2c_obj_t)); - is31fb->is31fl3741->i2c = &is31fb->is31fl3741->inline_i2c; + if (gc_ptr_on_heap(original_i2c)) { + memcpy(&is31fb->is31fl3741->inline_i2c, original_i2c, sizeof(busio_i2c_obj_t)); + is31fb->is31fl3741->i2c = &is31fb->is31fl3741->inline_i2c; + } } if (!any_display_uses_this_framebuffer(&is31fb->base)) { @@ -300,15 +334,20 @@ void reset_displays(void) { #endif #if CIRCUITPY_AURORA_EPAPER } else if (display_bus_type == &aurora_framebuffer_type) { - #if CIRCUITPY_BOARD_SPI aurora_epaper_framebuffer_obj_t *aurora = &display_buses[i].aurora_epaper; - if (common_hal_board_is_spi(aurora->bus)) { + if (gc_ptr_on_heap(aurora->bus)) { common_hal_aurora_epaper_framebuffer_set_free_bus(false); } - #endif // Set to None, gets deinit'd up by display_base display_buses[i].bus_base.type = &mp_type_NoneType; #endif + #if CIRCUITPY_MIPIDSI + } else if (display_bus_type == &mipidsi_display_type) { + mipidsi_display_obj_t *display = &display_buses[i].mipidsi; + if (!any_display_uses_this_framebuffer(&display->base)) { + common_hal_mipidsi_display_deinit(display); + } + #endif } else { // Not an active display bus. continue; @@ -334,6 +373,10 @@ void reset_displays(void) { } else if (display_type == &framebufferio_framebufferdisplay_type) { framebufferio_framebufferdisplay_reset(&displays[i].framebuffer_display); #endif + #if CIRCUITPY_ZEPHYR_DISPLAY + } else if (display_type == &zephyr_display_display_type) { + zephyr_display_display_reset(&displays[i].zephyr_display); + #endif } } } @@ -385,14 +428,21 @@ void displayio_gc_collect(void) { } else if (display_type == &epaperdisplay_epaperdisplay_type) { epaperdisplay_epaperdisplay_collect_ptrs(&displays[i].epaper_display); #endif + #if CIRCUITPY_ZEPHYR_DISPLAY + } else if (display_type == &zephyr_display_display_type) { + zephyr_display_display_collect_ptrs(&displays[i].zephyr_display); + #endif } } } +static bool is_display_active(mp_obj_base_t *display_maybe) { + return display_maybe->type != &mp_type_NoneType && display_maybe->type != NULL; +} + primary_display_t *allocate_display(void) { for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - mp_const_obj_t display_type = displays[i].display_base.type; - if (display_type == NULL || display_type == &mp_type_NoneType) { + if (!is_display_active(&displays[i].display_base)) { // Clear this memory so it is in a known state before init. memset(&displays[i], 0, sizeof(displays[i])); // Default to None so that it works as board.DISPLAY. @@ -431,3 +481,42 @@ primary_display_bus_t *allocate_display_bus_or_raise(void) { } mp_raise_RuntimeError(MP_ERROR_TEXT("Too many display busses; forgot displayio.release_displays() ?")); } + +mp_obj_t common_hal_displayio_get_primary_display(void) { + if (primary_display_number == -1 || primary_display_number >= CIRCUITPY_DISPLAY_LIMIT) { + return mp_const_none; + } + mp_obj_base_t *primary_display = &displays[primary_display_number].display_base; + if (is_display_active(primary_display)) { + return MP_OBJ_FROM_PTR(primary_display); + } + return mp_const_none; +} + +void common_hal_displayio_set_primary_display(mp_obj_t new_primary_display) { + if (new_primary_display == mp_const_none) { + primary_display_number = -1; + return; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_obj_t display = MP_OBJ_FROM_PTR(&displays[i]); + if (new_primary_display == display && is_display_active(display)) { + primary_display_number = i; + return; + } + } + // object was not a display after all... + mp_raise_TypeError_varg(MP_ERROR_TEXT("%q must be of type %q or %q, not %q"), MP_QSTR_Display, MP_QSTR_AnyDisplay, MP_QSTR_None, mp_obj_get_type(new_primary_display)->name); +} + +void common_hal_displayio_auto_primary_display(void) { + if (primary_display_number != -1) { + return; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (is_display_active(&displays[i].display_base)) { + primary_display_number = i; + return; + } + } +} diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 29b8c64c972..eabff662782 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -38,6 +38,15 @@ #if CIRCUITPY_DOTCLOCKFRAMEBUFFER #include "common-hal/dotclockframebuffer/DotClockFramebuffer.h" #endif +#if CIRCUITPY_MIPIDSI +#include "shared-bindings/mipidsi/Display.h" +#endif +#if CIRCUITPY_QSPIBUS +#include "shared-bindings/qspibus/QSPIBus.h" +#endif +#if CIRCUITPY_ZEPHYR_DISPLAY +#include "bindings/zephyr_display/Display.h" +#endif // Port unique frame buffers. #if CIRCUITPY_VIDEOCORE #include "bindings/videocore/Framebuffer.h" @@ -81,6 +90,12 @@ typedef struct { #if CIRCUITPY_AURORA_EPAPER aurora_epaper_framebuffer_obj_t aurora_epaper; #endif + #if CIRCUITPY_MIPIDSI + mipidsi_display_obj_t mipidsi; + #endif + #if CIRCUITPY_QSPIBUS + qspibus_qspibus_obj_t qspi_bus; + #endif }; } primary_display_bus_t; @@ -96,6 +111,9 @@ typedef struct { #if CIRCUITPY_FRAMEBUFFERIO framebufferio_framebufferdisplay_obj_t framebuffer_display; #endif + #if CIRCUITPY_ZEPHYR_DISPLAY + zephyr_display_display_obj_t zephyr_display; + #endif }; } primary_display_t; diff --git a/shared-module/displayio/bus_core.c b/shared-module/displayio/bus_core.c index e01b9d9eef6..9b3fb426217 100644 --- a/shared-module/displayio/bus_core.c +++ b/shared-module/displayio/bus_core.c @@ -17,6 +17,9 @@ #if CIRCUITPY_PARALLELDISPLAYBUS #include "shared-bindings/paralleldisplaybus/ParallelBus.h" #endif +#if CIRCUITPY_QSPIBUS +#include "shared-bindings/qspibus/QSPIBus.h" +#endif #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/time/__init__.h" #include "shared-module/displayio/__init__.h" @@ -49,6 +52,8 @@ void displayio_display_bus_construct(displayio_display_bus_t *self, self->SH1107_addressing = SH1107_addressing; self->address_little_endian = address_little_endian; + self->flush = NULL; + #if CIRCUITPY_PARALLELDISPLAYBUS if (mp_obj_is_type(bus, ¶lleldisplaybus_parallelbus_type)) { self->bus_reset = common_hal_paralleldisplaybus_parallelbus_reset; @@ -79,17 +84,33 @@ void displayio_display_bus_construct(displayio_display_bus_t *self, self->collect_ptrs = common_hal_i2cdisplaybus_i2cdisplaybus_collect_ptrs; } else #endif + #if CIRCUITPY_QSPIBUS + if (mp_obj_is_type(bus, &qspibus_qspibus_type)) { + self->bus_reset = common_hal_qspibus_qspibus_reset; + self->bus_free = common_hal_qspibus_qspibus_bus_free; + self->begin_transaction = common_hal_qspibus_qspibus_begin_transaction; + self->send = common_hal_qspibus_qspibus_send; + self->end_transaction = common_hal_qspibus_qspibus_end_transaction; + self->flush = common_hal_qspibus_qspibus_flush; + self->collect_ptrs = common_hal_qspibus_qspibus_collect_ptrs; + } else + #endif { mp_raise_ValueError(MP_ERROR_TEXT("Unsupported display bus type")); } self->bus = bus; } +// This is just a hint, and is not a reliable result, since the bus could be grabbed in between this called +// and the attempt to use the bus. Use displayio_display_bus_begin_transaction(), which is atomic. bool displayio_display_bus_is_free(displayio_display_bus_t *self) { return !self->bus || self->bus_free(self->bus); } -bool displayio_display_bus_begin_transaction(displayio_display_bus_t *self) { +MP_WARN_UNUSED_RESULT bool displayio_display_bus_begin_transaction(displayio_display_bus_t *self) { + if (!self->bus) { + return false; + } mp_obj_base_t *bus_base = MP_OBJ_TO_PTR(self->bus); if (bus_base->type == &mp_type_NoneType) { return false; @@ -128,7 +149,9 @@ void displayio_display_bus_set_region_to_update(displayio_display_bus_t *self, d } // Set column. - displayio_display_bus_begin_transaction(self); + if (!displayio_display_bus_begin_transaction(self)) { + return; + } uint8_t data[5]; data[0] = self->column_command; uint8_t data_length = 1; @@ -167,7 +190,9 @@ void displayio_display_bus_set_region_to_update(displayio_display_bus_t *self, d if (self->set_current_column_command != NO_COMMAND) { uint8_t command = self->set_current_column_command; - displayio_display_bus_begin_transaction(self); + if (!displayio_display_bus_begin_transaction(self)) { + return; + } self->send(self->bus, DISPLAY_COMMAND, chip_select, &command, 1); // Only send the first half of data because it is the first coordinate. self->send(self->bus, DISPLAY_DATA, chip_select, data, data_length / 2); @@ -176,7 +201,9 @@ void displayio_display_bus_set_region_to_update(displayio_display_bus_t *self, d // Set row. - displayio_display_bus_begin_transaction(self); + if (!displayio_display_bus_begin_transaction(self)) { + return; + } data[0] = self->row_command; data_length = 1; if (!self->data_as_commands) { @@ -211,7 +238,9 @@ void displayio_display_bus_set_region_to_update(displayio_display_bus_t *self, d if (self->set_current_row_command != NO_COMMAND) { uint8_t command = self->set_current_row_command; - displayio_display_bus_begin_transaction(self); + if (!displayio_display_bus_begin_transaction(self)) { + return; + } self->send(self->bus, DISPLAY_COMMAND, chip_select, &command, 1); // Only send the first half of data because it is the first coordinate. self->send(self->bus, DISPLAY_DATA, chip_select, data, data_length / 2); @@ -219,6 +248,12 @@ void displayio_display_bus_set_region_to_update(displayio_display_bus_t *self, d } } +void displayio_display_bus_flush(displayio_display_bus_t *self) { + if (self->flush != NULL) { + self->flush(self->bus); + } +} + void displayio_display_bus_collect_ptrs(displayio_display_bus_t *self) { self->collect_ptrs(self->bus); } diff --git a/shared-module/displayio/bus_core.h b/shared-module/displayio/bus_core.h index 838454c92e6..75d03d7f284 100644 --- a/shared-module/displayio/bus_core.h +++ b/shared-module/displayio/bus_core.h @@ -21,6 +21,7 @@ typedef struct { display_bus_begin_transaction begin_transaction; display_bus_send send; display_bus_end_transaction end_transaction; + display_bus_flush flush; display_bus_collect_ptrs collect_ptrs; uint16_t ram_width; uint16_t ram_height; @@ -49,6 +50,10 @@ void displayio_display_bus_end_transaction(displayio_display_bus_t *self); void displayio_display_bus_set_region_to_update(displayio_display_bus_t *self, displayio_display_core_t *display, displayio_area_t *area); +// Drain any pending asynchronous transfers on the bus. +// No-op for synchronous buses (FourWire, I2C, ParallelBus). +void displayio_display_bus_flush(displayio_display_bus_t *self); + void release_display_bus(displayio_display_bus_t *self); void displayio_display_bus_collect_ptrs(displayio_display_bus_t *self); diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index 9f43195b8cf..d34be9d5c7c 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -26,70 +26,73 @@ #define DELAY 0x80 void common_hal_epaperdisplay_epaperdisplay_construct(epaperdisplay_epaperdisplay_obj_t *self, - mp_obj_t bus, const uint8_t *start_sequence, uint16_t start_sequence_len, mp_float_t start_up_time, - const uint8_t *stop_sequence, uint16_t stop_sequence_len, - uint16_t width, uint16_t height, uint16_t ram_width, uint16_t ram_height, - int16_t colstart, int16_t rowstart, uint16_t rotation, - uint16_t set_column_window_command, uint16_t set_row_window_command, - uint16_t set_current_column_command, uint16_t set_current_row_command, - uint16_t write_black_ram_command, bool black_bits_inverted, - uint16_t write_color_ram_command, bool color_bits_inverted, uint32_t highlight_color, - const uint8_t *refresh_sequence, uint16_t refresh_sequence_len, mp_float_t refresh_time, - const mcu_pin_obj_t *busy_pin, bool busy_state, mp_float_t seconds_per_frame, - bool chip_select, bool grayscale, bool acep, bool two_byte_sequence_length, bool address_little_endian) { + const epaperdisplay_construct_args_t *args) { uint16_t color_depth = 1; bool core_grayscale = true; - if (highlight_color != 0x000000) { + if (args->highlight_color != 0x000000) { self->core.colorspace.tricolor = true; - self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(highlight_color); - self->core.colorspace.tricolor_luma = displayio_colorconverter_compute_luma(highlight_color); + self->core.colorspace.tricolor_hue = displayio_colorconverter_compute_hue(args->highlight_color); } else { self->core.colorspace.tricolor = false; } - self->acep = acep; - self->core.colorspace.sevencolor = acep; - if (acep) { + if (args->highlight_color != 0x000000 && args->highlight_color2 != 0x000000) { + self->core.colorspace.tricolor = false; + self->core.colorspace.fourcolor = true; + self->core.colorspace.fourcolor_hue = displayio_colorconverter_compute_hue(args->highlight_color2); + } else { + self->core.colorspace.fourcolor = false; + } + self->acep = args->acep || args->spectra6; + self->core.colorspace.sixcolor = args->spectra6; + self->core.colorspace.sevencolor = args->acep; + bool grayscale = args->grayscale; + if (self->acep) { color_depth = 4; // bits. 7 colors + clean grayscale = false; core_grayscale = false; } + if ((args->highlight_color != 0x000000 || args->highlight_color2 != 0x000000) && args->write_color_ram_command == NO_COMMAND) { + color_depth = 2; + core_grayscale = false; + grayscale = false; + } - displayio_display_core_construct(&self->core, width, height, rotation, color_depth, core_grayscale, true, 1, true, true); - displayio_display_bus_construct(&self->bus, bus, ram_width, ram_height, - colstart, rowstart, - set_column_window_command, set_row_window_command, set_current_column_command, set_current_row_command, - false /* data_as_commands */, chip_select, - false /* SH1107_addressing */, address_little_endian); + displayio_display_core_construct(&self->core, args->width, args->height, args->rotation, color_depth, core_grayscale, true, 1, true, true); + displayio_display_bus_construct(&self->bus, args->bus, args->ram_width, args->ram_height, + args->colstart, args->rowstart, + args->set_column_window_command, args->set_row_window_command, args->set_current_column_command, args->set_current_row_command, + false /* data_as_commands */, args->always_toggle_chip_select, + false /* SH1107_addressing */, args->address_little_endian); - self->write_black_ram_command = write_black_ram_command; - self->black_bits_inverted = black_bits_inverted; - self->write_color_ram_command = write_color_ram_command; - self->color_bits_inverted = color_bits_inverted; - self->refresh_time = refresh_time * 1000; - self->busy_state = busy_state; + self->write_black_ram_command = args->write_black_ram_command; + self->black_bits_inverted = args->black_bits_inverted; + self->write_color_ram_command = args->write_color_ram_command; + self->color_bits_inverted = args->color_bits_inverted; + self->refresh_time = args->refresh_time * 1000; + self->busy_state = args->busy_state; self->refreshing = false; - self->milliseconds_per_frame = seconds_per_frame * 1000; - self->chip_select = chip_select ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED; + self->milliseconds_per_frame = args->seconds_per_frame * 1000; + self->chip_select = args->always_toggle_chip_select ? CHIP_SELECT_TOGGLE_EVERY_BYTE : CHIP_SELECT_UNTOUCHED; self->grayscale = grayscale; - self->start_sequence = start_sequence; - self->start_sequence_len = start_sequence_len; - self->start_up_time_ms = start_up_time * 1000; - self->stop_sequence = stop_sequence; - self->stop_sequence_len = stop_sequence_len; - self->refresh_sequence = refresh_sequence; - self->refresh_sequence_len = refresh_sequence_len; + self->start_sequence = args->start_sequence; + self->start_sequence_len = args->start_sequence_len; + self->start_up_time_ms = args->start_up_time * 1000; + self->stop_sequence = args->stop_sequence; + self->stop_sequence_len = args->stop_sequence_len; + self->refresh_sequence = args->refresh_sequence; + self->refresh_sequence_len = args->refresh_sequence_len; self->busy.base.type = &mp_type_NoneType; - self->two_byte_sequence_length = two_byte_sequence_length; - if (busy_pin != NULL) { + self->two_byte_sequence_length = args->two_byte_sequence_length; + if (args->busy_pin != NULL) { self->busy.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->busy, busy_pin); - common_hal_never_reset_pin(busy_pin); + common_hal_digitalio_digitalinout_construct(&self->busy, args->busy_pin); + common_hal_never_reset_pin(args->busy_pin); } // Clear the color memory if it isn't in use. - if (highlight_color == 0x00 && write_color_ram_command != NO_COMMAND) { + if (args->highlight_color == 0x00 && args->highlight_color2 == 0x00 && args->write_color_ram_command != NO_COMMAND) { // TODO: Clear } @@ -150,14 +153,17 @@ static void send_command_sequence(epaperdisplay_epaperdisplay_obj_t *self, data_size = ((data_size & ~DELAY) << 8) + *(cmd + 2); data = cmd + 3; } - displayio_display_bus_begin_transaction(&self->bus); + while (!displayio_display_bus_begin_transaction(&self->bus) && + !mp_hal_is_interrupted()) { + RUN_BACKGROUND_TASKS; + } self->bus.send(self->bus.bus, DISPLAY_COMMAND, self->chip_select, cmd, 1); self->bus.send(self->bus.bus, DISPLAY_DATA, self->chip_select, data, data_size); displayio_display_bus_end_transaction(&self->bus); uint16_t delay_length_ms = 0; if (delay) { data_size++; - delay_length_ms = *(cmd + 1 + data_size); + delay_length_ms = *(cmd + 1 + data_size + self->two_byte_sequence_length); if (delay_length_ms == 255) { delay_length_ms = 500; } @@ -188,6 +194,10 @@ static void epaperdisplay_epaperdisplay_start_refresh(epaperdisplay_epaperdispla // Can't acquire display bus; skip updating this display. Try next display. return; } + if (!displayio_display_core_start_refresh(&self->core)) { + // Refresh on this display already in progress. + return; + } // run start sequence self->bus.bus_reset(self->bus.bus); @@ -198,7 +208,6 @@ static void epaperdisplay_epaperdisplay_start_refresh(epaperdisplay_epaperdispla if (mp_hal_is_interrupted()) { return; } - displayio_display_core_start_refresh(&self->core); } uint32_t common_hal_epaperdisplay_epaperdisplay_get_time_to_refresh(epaperdisplay_epaperdisplay_obj_t *self) { @@ -305,7 +314,10 @@ static bool epaperdisplay_epaperdisplay_refresh_area(epaperdisplay_epaperdisplay if (pass == 1) { write_command = self->write_color_ram_command; } - displayio_display_bus_begin_transaction(&self->bus); + if (!displayio_display_bus_begin_transaction(&self->bus)) { + // Display bus not available now. + return false; + } self->bus.send(self->bus.bus, DISPLAY_COMMAND, self->chip_select, &write_command, 1); displayio_display_bus_end_transaction(&self->bus); @@ -338,7 +350,7 @@ static bool epaperdisplay_epaperdisplay_refresh_area(epaperdisplay_epaperdisplay } else if (self->core.colorspace.tricolor) { self->core.colorspace.grayscale = false; displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); - } else if (self->core.colorspace.sevencolor) { + } else if (self->core.colorspace.sixcolor || self->core.colorspace.sevencolor) { displayio_display_core_fill_area(&self->core, &subrectangle, mask, buffer); } } else { @@ -360,8 +372,11 @@ static bool epaperdisplay_epaperdisplay_refresh_area(epaperdisplay_epaperdisplay self->bus.send(self->bus.bus, DISPLAY_DATA, self->chip_select, (uint8_t *)buffer, subrectangle_size_bytes); displayio_display_bus_end_transaction(&self->bus); - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. + // Run background tasks so they can run during an explicit refresh. + // Auto-refresh won't run background tasks here because it is a background task itself. + RUN_BACKGROUND_TASKS; + + // Run USB background tasks so they can run during an implicit refresh. #if CIRCUITPY_TINYUSB usb_background(); #endif @@ -379,7 +394,9 @@ static bool _clean_area(epaperdisplay_epaperdisplay_obj_t *self) { memset(buffer, 0x77, width / 2); uint8_t write_command = self->write_black_ram_command; - displayio_display_bus_begin_transaction(&self->bus); + if (displayio_display_bus_begin_transaction(&self->bus)) { + return false; + } self->bus.send(self->bus.bus, DISPLAY_COMMAND, self->chip_select, &write_command, 1); displayio_display_bus_end_transaction(&self->bus); diff --git a/shared-module/fontio/BuiltinFont.c b/shared-module/fontio/BuiltinFont.c index e24fe9c7f37..03ef933c55c 100644 --- a/shared-module/fontio/BuiltinFont.c +++ b/shared-module/fontio/BuiltinFont.c @@ -16,7 +16,8 @@ mp_obj_t common_hal_fontio_builtinfont_get_bitmap(const fontio_builtinfont_t *se } mp_obj_t common_hal_fontio_builtinfont_get_bounding_box(const fontio_builtinfont_t *self) { - mp_obj_t *items = m_new(mp_obj_t, 2); + // Stack allocation is ok because tuple copies the values out. + mp_obj_t items[2]; items[0] = MP_OBJ_NEW_SMALL_INT(self->width); items[1] = MP_OBJ_NEW_SMALL_INT(self->height); return mp_obj_new_tuple(2, items); diff --git a/shared-module/fourwire/FourWire.c b/shared-module/fourwire/FourWire.c index 0a168fa1563..d87cb0cec0f 100644 --- a/shared-module/fourwire/FourWire.c +++ b/shared-module/fourwire/FourWire.c @@ -11,13 +11,15 @@ #include "py/gc.h" #include "shared-bindings/busio/SPI.h" #include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOutProtocol.h" #include "shared-bindings/microcontroller/Pin.h" #include "shared-bindings/microcontroller/__init__.h" #include "shared-bindings/time/__init__.h" +#include "supervisor/port.h" void common_hal_fourwire_fourwire_construct(fourwire_fourwire_obj_t *self, - busio_spi_obj_t *spi, const mcu_pin_obj_t *command, - const mcu_pin_obj_t *chip_select, const mcu_pin_obj_t *reset, uint32_t baudrate, + busio_spi_obj_t *spi, mp_obj_t command, + mp_obj_t chip_select, mp_obj_t reset, uint32_t baudrate, uint8_t polarity, uint8_t phase) { self->bus = spi; @@ -27,31 +29,27 @@ void common_hal_fourwire_fourwire_construct(fourwire_fourwire_obj_t *self, self->polarity = polarity; self->phase = phase; + // Allocate the pins in the same place as self. + bool use_port_allocation = !gc_alloc_possible() || !gc_ptr_on_heap(self); - self->command.base.type = &mp_type_NoneType; - if (command != NULL) { - self->command.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->command, command); - common_hal_digitalio_digitalinout_switch_to_output(&self->command, true, DRIVE_MODE_PUSH_PULL); + self->command = digitalinout_protocol_from_pin(command, MP_QSTR_command, true, use_port_allocation, &self->own_command); + if (self->command != mp_const_none) { + digitalinout_protocol_switch_to_output(self->command, true, DRIVE_MODE_PUSH_PULL); common_hal_never_reset_pin(command); } - self->reset.base.type = &mp_type_NoneType; - if (reset != NULL) { - self->reset.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->reset, reset); - common_hal_digitalio_digitalinout_switch_to_output(&self->reset, true, DRIVE_MODE_PUSH_PULL); + + self->reset = digitalinout_protocol_from_pin(reset, MP_QSTR_reset, true, use_port_allocation, &self->own_reset); + if (self->reset != mp_const_none) { + digitalinout_protocol_switch_to_output(self->reset, true, DRIVE_MODE_PUSH_PULL); common_hal_never_reset_pin(reset); common_hal_fourwire_fourwire_reset(self); } - self->chip_select.base.type = &mp_type_NoneType; - if (chip_select != NULL) { - self->chip_select.base.type = &digitalio_digitalinout_type; - common_hal_digitalio_digitalinout_construct(&self->chip_select, chip_select); - common_hal_digitalio_digitalinout_switch_to_output(&self->chip_select, true, DRIVE_MODE_PUSH_PULL); + self->chip_select = digitalinout_protocol_from_pin(chip_select, MP_QSTR_chip_select, true, use_port_allocation, &self->own_chip_select); + if (self->chip_select != mp_const_none) { + digitalinout_protocol_switch_to_output(self->chip_select, true, DRIVE_MODE_PUSH_PULL); common_hal_never_reset_pin(chip_select); } - } void common_hal_fourwire_fourwire_deinit(fourwire_fourwire_obj_t *self) { @@ -59,19 +57,33 @@ void common_hal_fourwire_fourwire_deinit(fourwire_fourwire_obj_t *self) { common_hal_busio_spi_deinit(self->bus); } - common_hal_reset_pin(self->command.pin); - common_hal_reset_pin(self->chip_select.pin); - common_hal_reset_pin(self->reset.pin); + // Only deinit and free the pins if we own them + if (self->command != mp_const_none && self->own_command) { + digitalinout_protocol_deinit(self->command); + circuitpy_free_obj(self->command); + } + if (self->chip_select != mp_const_none && self->own_chip_select) { + digitalinout_protocol_deinit(self->chip_select); + circuitpy_free_obj(self->chip_select); + } + if (self->reset != mp_const_none && self->own_reset) { + digitalinout_protocol_deinit(self->reset); + circuitpy_free_obj(self->reset); + } } bool common_hal_fourwire_fourwire_reset(mp_obj_t obj) { fourwire_fourwire_obj_t *self = MP_OBJ_TO_PTR(obj); - if (self->reset.base.type == &mp_type_NoneType) { + if (self->reset == mp_const_none) { + return false; + } + if (digitalinout_protocol_set_value(self->reset, false) != 0) { return false; } - common_hal_digitalio_digitalinout_set_value(&self->reset, false); common_hal_mcu_delay_us(1000); - common_hal_digitalio_digitalinout_set_value(&self->reset, true); + if (digitalinout_protocol_set_value(self->reset, true) != 0) { + return false; + } common_hal_mcu_delay_us(1000); return true; } @@ -92,16 +104,23 @@ bool common_hal_fourwire_fourwire_begin_transaction(mp_obj_t obj) { } common_hal_busio_spi_configure(self->bus, self->frequency, self->polarity, self->phase, 8); - if (self->chip_select.base.type != &mp_type_NoneType) { - common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + if (self->chip_select != mp_const_none) { + // IO Expander CS can fail due to an I2C lock. + if (digitalinout_protocol_set_value(self->chip_select, false) != 0) { + common_hal_busio_spi_unlock(self->bus); + return false; + } } return true; } void common_hal_fourwire_fourwire_send(mp_obj_t obj, display_byte_type_t data_type, display_chip_select_behavior_t chip_select, const uint8_t *data, uint32_t data_length) { + if (data_length == 0) { + return; + } fourwire_fourwire_obj_t *self = MP_OBJ_TO_PTR(obj); - if (self->command.base.type == &mp_type_NoneType) { + if (self->command == mp_const_none) { // When the data/command pin is not specified, we simulate a 9-bit SPI mode, by // adding a data/command bit to every byte, and then splitting the resulting data back // into 8-bit chunks for transmission. If the length of the data being transmitted @@ -133,24 +152,24 @@ void common_hal_fourwire_fourwire_send(mp_obj_t obj, display_byte_type_t data_ty if (bits > 0) { buffer = buffer << (8 - bits); common_hal_busio_spi_write(self->bus, &buffer, 1); - if (self->chip_select.base.type != &mp_type_NoneType) { + if (self->chip_select != mp_const_none) { // toggle CS to discard superfluous bits - common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + digitalinout_protocol_set_value(self->chip_select, true); common_hal_mcu_delay_us(1); - common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + digitalinout_protocol_set_value(self->chip_select, false); } } } else { - common_hal_digitalio_digitalinout_set_value(&self->command, data_type == DISPLAY_DATA); + digitalinout_protocol_set_value(self->command, data_type == DISPLAY_DATA); if (chip_select == CHIP_SELECT_TOGGLE_EVERY_BYTE) { // Toggle chip select after each command byte in case the display driver // IC latches commands based on it. for (size_t i = 0; i < data_length; i++) { common_hal_busio_spi_write(self->bus, &data[i], 1); - if (self->chip_select.base.type != &mp_type_NoneType) { - common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + if (self->chip_select != mp_const_none) { + digitalinout_protocol_set_value(self->chip_select, true); common_hal_mcu_delay_us(1); - common_hal_digitalio_digitalinout_set_value(&self->chip_select, false); + digitalinout_protocol_set_value(self->chip_select, false); } } } else { @@ -161,8 +180,8 @@ void common_hal_fourwire_fourwire_send(mp_obj_t obj, display_byte_type_t data_ty void common_hal_fourwire_fourwire_end_transaction(mp_obj_t obj) { fourwire_fourwire_obj_t *self = MP_OBJ_TO_PTR(obj); - if (self->chip_select.base.type != &mp_type_NoneType) { - common_hal_digitalio_digitalinout_set_value(&self->chip_select, true); + if (self->chip_select != mp_const_none) { + digitalinout_protocol_set_value(self->chip_select, true); } common_hal_busio_spi_unlock(self->bus); } diff --git a/shared-module/fourwire/FourWire.h b/shared-module/fourwire/FourWire.h index 629a426b3b0..c239a3dfde3 100644 --- a/shared-module/fourwire/FourWire.h +++ b/shared-module/fourwire/FourWire.h @@ -6,6 +6,8 @@ #pragma once +#include + #include "common-hal/busio/SPI.h" #include "common-hal/digitalio/DigitalInOut.h" #include "shared-module/displayio/Group.h" @@ -14,10 +16,13 @@ typedef struct { mp_obj_base_t base; busio_spi_obj_t *bus; busio_spi_obj_t inline_bus; - digitalio_digitalinout_obj_t command; - digitalio_digitalinout_obj_t chip_select; - digitalio_digitalinout_obj_t reset; + mp_obj_t command; + mp_obj_t chip_select; + mp_obj_t reset; uint32_t frequency; uint8_t polarity; uint8_t phase; + bool own_command; + bool own_chip_select; + bool own_reset; } fourwire_fourwire_obj_t; diff --git a/shared-module/framebufferio/FramebufferDisplay.c b/shared-module/framebufferio/FramebufferDisplay.c index c9fe52e0e40..8116f4b0347 100644 --- a/shared-module/framebufferio/FramebufferDisplay.c +++ b/shared-module/framebufferio/FramebufferDisplay.c @@ -200,9 +200,11 @@ static bool _refresh_area(framebufferio_framebufferdisplay_obj_t *self, const di dest += rowstride; src += rowsize; } + // Run background tasks so they can run during an explicit refresh. + // Auto-refresh won't run background tasks here because it is a background task itself. + RUN_BACKGROUND_TASKS; - // TODO(tannewt): Make refresh displays faster so we don't starve other - // background tasks. + // Run USB background tasks so they can run during an implicit refresh. #if CIRCUITPY_TINYUSB usb_background(); #endif @@ -215,7 +217,10 @@ static void _refresh_display(framebufferio_framebufferdisplay_obj_t *self) { if (!self->bufinfo.buf) { return; } - displayio_display_core_start_refresh(&self->core); + if (!displayio_display_core_start_refresh(&self->core)) { + // Refresh on this display already in progress. + return; + } const displayio_area_t *current_area = _get_refresh_areas(self); if (current_area) { bool transposed = (self->core.rotation == 90 || self->core.rotation == 270); diff --git a/shared-module/gifio/GifWriter.c b/shared-module/gifio/GifWriter.c index 8747f4a486c..bf0b33836cf 100644 --- a/shared-module/gifio/GifWriter.c +++ b/shared-module/gifio/GifWriter.c @@ -70,7 +70,7 @@ void shared_module_gifio_gifwriter_construct(gifio_gifwriter_t *self, mp_obj_t * size_t nblocks = (width * height + 125) / 126; self->size = nblocks * 128 + 4; - self->data = m_malloc(self->size); + self->data = m_malloc_without_collect(self->size); self->cur = 0; self->error = 0; diff --git a/shared-module/hashlib/Hash.c b/shared-module/hashlib/Hash.c index a454966d993..4b46198ac5d 100644 --- a/shared-module/hashlib/Hash.c +++ b/shared-module/hashlib/Hash.c @@ -7,32 +7,23 @@ #include "shared-bindings/hashlib/Hash.h" #include "shared-module/hashlib/__init__.h" -#include "mbedtls/ssl.h" +#include "psa/crypto.h" void common_hal_hashlib_hash_update(hashlib_hash_obj_t *self, const uint8_t *data, size_t datalen) { - if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) { - mbedtls_sha1_update_ret(&self->sha1, data, datalen); - return; - } + psa_hash_update(&self->hash_op, data, datalen); } void common_hal_hashlib_hash_digest(hashlib_hash_obj_t *self, uint8_t *data, size_t datalen) { if (datalen < common_hal_hashlib_hash_get_digest_size(self)) { return; } - if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) { - // We copy the sha1 state so we can continue to update if needed or get - // the digest a second time. - mbedtls_sha1_context copy; - mbedtls_sha1_clone(©, &self->sha1); - mbedtls_sha1_finish_ret(&self->sha1, data); - mbedtls_sha1_clone(&self->sha1, ©); - } + // Clone the operation so we can continue to update or get digest again. + psa_hash_operation_t clone = PSA_HASH_OPERATION_INIT; + psa_hash_clone(&self->hash_op, &clone); + size_t hash_len; + psa_hash_finish(&clone, data, datalen, &hash_len); } size_t common_hal_hashlib_hash_get_digest_size(hashlib_hash_obj_t *self) { - if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) { - return 20; - } - return 0; + return PSA_HASH_LENGTH(self->hash_alg); } diff --git a/shared-module/hashlib/Hash.h b/shared-module/hashlib/Hash.h index ccc82037cb7..961335eea7a 100644 --- a/shared-module/hashlib/Hash.h +++ b/shared-module/hashlib/Hash.h @@ -6,13 +6,10 @@ #pragma once -#include "mbedtls/sha1.h" +#include "psa/crypto.h" typedef struct { mp_obj_base_t base; - union { - mbedtls_sha1_context sha1; - }; - // Of MBEDTLS_SSL_HASH_* - uint8_t hash_type; + psa_hash_operation_t hash_op; + psa_algorithm_t hash_alg; } hashlib_hash_obj_t; diff --git a/shared-module/hashlib/__init__.c b/shared-module/hashlib/__init__.c index be3a9f18959..50477a4dc2d 100644 --- a/shared-module/hashlib/__init__.c +++ b/shared-module/hashlib/__init__.c @@ -7,15 +7,22 @@ #include "shared-bindings/hashlib/__init__.h" #include "shared-module/hashlib/__init__.h" -#include "mbedtls/ssl.h" - +#include "psa/crypto.h" bool common_hal_hashlib_new(hashlib_hash_obj_t *self, const char *algorithm) { if (strcmp(algorithm, "sha1") == 0) { - self->hash_type = MBEDTLS_SSL_HASH_SHA1; - mbedtls_sha1_init(&self->sha1); - mbedtls_sha1_starts_ret(&self->sha1); - return true; + self->hash_alg = PSA_ALG_SHA_1; + } else if (strcmp(algorithm, "sha256") == 0) { + self->hash_alg = PSA_ALG_SHA_256; + } else { + return false; + } + // PSA has to be initialized before any of it is used. OK to psa_crypto_init() + // multiple times. On espressif, ESP-IDF has already done this during its own system + // init and this call is a no-op. + if (psa_crypto_init() != PSA_SUCCESS) { + return false; } - return false; + self->hash_op = psa_hash_operation_init(); + return psa_hash_setup(&self->hash_op, self->hash_alg) == PSA_SUCCESS; } diff --git a/shared-module/hashlib/__init__.h b/shared-module/hashlib/__init__.h index f72882a1c03..2088d352f20 100644 --- a/shared-module/hashlib/__init__.h +++ b/shared-module/hashlib/__init__.h @@ -6,11 +6,3 @@ // SPDX-License-Identifier: MIT #pragma once - -#include "mbedtls/version.h" - -#if MBEDTLS_VERSION_NUMBER < 0x02070000 || MBEDTLS_VERSION_NUMBER >= 0x03000000 -#define mbedtls_sha1_starts_ret mbedtls_sha1_starts -#define mbedtls_sha1_update_ret mbedtls_sha1_update -#define mbedtls_sha1_finish_ret mbedtls_sha1_finish -#endif diff --git a/shared-module/i2cioexpander/IOExpander.c b/shared-module/i2cioexpander/IOExpander.c new file mode 100644 index 00000000000..f4aac5c0532 --- /dev/null +++ b/shared-module/i2cioexpander/IOExpander.c @@ -0,0 +1,196 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/i2cioexpander/IOExpander.h" +#include "shared-bindings/i2cioexpander/IOPin.h" + +#include + +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/busio/I2C.h" +#include "supervisor/port.h" + +void common_hal_i2cioexpander_ioexpander_construct( + i2cioexpander_ioexpander_obj_t *self, + mp_obj_t i2c, + uint8_t address, + uint8_t num_pins, + uint16_t set_value_reg, + uint16_t get_value_reg, + uint16_t set_direction_reg) { + + // Store the I2C bus + self->i2c = (busio_i2c_obj_t *)i2c; + self->address = address; + self->num_pins = num_pins; + self->output_value = 0; + self->output_mask = 0; + + // Parse optional register addresses + self->has_set_value = (set_value_reg != NO_REGISTER); + if (self->has_set_value) { + self->set_value_reg = set_value_reg; + } + + self->has_get_value = (get_value_reg != NO_REGISTER); + if (self->has_get_value) { + self->get_value_reg = get_value_reg; + } + + self->has_set_direction = (set_direction_reg != NO_REGISTER); + if (self->has_set_direction) { + self->set_direction_reg = set_direction_reg; + } + + bool allocate_in_port_heap = !gc_alloc_possible() || !gc_ptr_on_heap(self); + + // Allocate tuple with space for pin objects in items[] + size_t tuple_size = offsetof(mp_obj_tuple_t, items) + sizeof(mp_obj_t) * num_pins; + mp_obj_tuple_t *pins_tuple = allocate_in_port_heap ? port_malloc(tuple_size, false) : m_malloc(tuple_size); + pins_tuple->base.type = &mp_type_tuple; + pins_tuple->len = num_pins; + + // Create IOPin objects for each pin + size_t pin_size = sizeof(i2cioexpander_iopin_obj_t); + for (uint8_t i = 0; i < num_pins; i++) { + i2cioexpander_iopin_obj_t *pin = allocate_in_port_heap ? port_malloc(pin_size, false) : m_malloc(pin_size); + pin->base.type = &i2cioexpander_iopin_type; + i2cioexpander_iopin_construct(pin, self, i); + pins_tuple->items[i] = MP_OBJ_FROM_PTR(pin); + } + + self->pins = pins_tuple; +} + +void common_hal_i2cioexpander_ioexpander_deinit(i2cioexpander_ioexpander_obj_t *self) { + if (gc_alloc_possible() && !gc_ptr_on_heap(self)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot deinitialize board IOExpander")); + } + for (uint8_t i = 0; i < self->num_pins; i++) { + circuitpy_free_obj(self->pins->items[i]); + } + circuitpy_free_obj(self->pins); + self->i2c = NULL; +} + +bool common_hal_i2cioexpander_ioexpander_deinited(i2cioexpander_ioexpander_obj_t *self) { + return self->i2c == NULL; +} + +mp_negative_errno_t common_hal_i2cioexpander_ioexpander_get_input_value(i2cioexpander_ioexpander_obj_t *self, size_t *value) { + uint8_t buffer[2]; + uint8_t num_bytes = (self->num_pins > 8) ? 2 : 1; + + while (!common_hal_busio_i2c_try_lock(self->i2c)) { + RUN_BACKGROUND_TASKS; + } + + mp_negative_errno_t result; + if (self->has_get_value) { + // Send register address then read + result = common_hal_busio_i2c_write_read( + self->i2c, self->address, &self->get_value_reg, 1, buffer, num_bytes); + } else { + // Read directly without register address + result = common_hal_busio_i2c_read(self->i2c, self->address, buffer, num_bytes); + } + common_hal_busio_i2c_unlock(self->i2c); + + if (result != 0) { + return result; + } + + if (num_bytes == 2) { + *value = buffer[0] | (buffer[1] << 8); + } else { + *value = buffer[0]; + } + return 0; +} + +void common_hal_i2cioexpander_ioexpander_get_output_value(i2cioexpander_ioexpander_obj_t *self, size_t *value) { + *value = self->output_value; +} + +mp_negative_errno_t common_hal_i2cioexpander_ioexpander_set_output_value(i2cioexpander_ioexpander_obj_t *self, size_t value) { + uint8_t buffer[5]; + uint8_t num_bytes = 0; + + // Add register address if provided + if (self->has_set_value) { + buffer[num_bytes++] = self->set_value_reg; + } + + size_t current_value = self->output_value; + if (current_value == value) { + return 0; + } + size_t diff = current_value ^ value; + + // Add value byte(s) but only if a high bit is changed + buffer[num_bytes++] = value & 0xFF; + if (self->num_pins > 8 && (diff >> 8) != 0) { + buffer[num_bytes++] = (value >> 8) & 0xFF; + } + if (self->num_pins > 16 && (diff >> 16) != 0) { + buffer[num_bytes++] = (value >> 16) & 0xFF; + } + if (self->num_pins > 24 && (diff >> 24) != 0) { + buffer[num_bytes++] = (value >> 24) & 0xFF; + } + + if (!common_hal_busio_i2c_try_lock(self->i2c)) { + return -MP_EBUSY; + } + + mp_negative_errno_t result = common_hal_busio_i2c_write(self->i2c, self->address, buffer, num_bytes); + common_hal_busio_i2c_unlock(self->i2c); + if (result == 0) { + self->output_value = value; + } + return result; +} + +void common_hal_i2cioexpander_ioexpander_get_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t *mask) { + *mask = self->output_mask; +} + +mp_negative_errno_t common_hal_i2cioexpander_ioexpander_set_output_mask(i2cioexpander_ioexpander_obj_t *self, size_t mask) { + self->output_mask = mask; + + // Only write to device if direction register is provided + if (!self->has_set_direction) { + return 0; + } + + uint8_t buffer[3]; + uint8_t num_bytes = 0; + + // Add register address + buffer[num_bytes++] = self->set_direction_reg; + + // Invert the mask so 0 indicates output. We taken 1 for output to match output enable. + size_t inverted_mask = ~mask; + + // Add mask byte(s) + buffer[num_bytes++] = inverted_mask & 0xFF; + if (self->num_pins > 8) { + buffer[num_bytes++] = (inverted_mask >> 8) & 0xFF; + } + + if (!common_hal_busio_i2c_try_lock(self->i2c)) { + return -MP_EBUSY; + } + + mp_negative_errno_t result = common_hal_busio_i2c_write(self->i2c, self->address, buffer, num_bytes); + common_hal_busio_i2c_unlock(self->i2c); + return result; +} + +mp_obj_t common_hal_i2cioexpander_ioexpander_get_pins(i2cioexpander_ioexpander_obj_t *self) { + return MP_OBJ_FROM_PTR(self->pins); +} diff --git a/shared-module/i2cioexpander/IOExpander.h b/shared-module/i2cioexpander/IOExpander.h new file mode 100644 index 00000000000..e225bfc75c7 --- /dev/null +++ b/shared-module/i2cioexpander/IOExpander.h @@ -0,0 +1,41 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "py/objtuple.h" +#include "shared-bindings/busio/I2C.h" + +#define NO_REGISTER (0x100) + +typedef struct { + mp_obj_base_t base; + busio_i2c_obj_t *i2c; + uint8_t address; + uint8_t num_pins; + uint8_t set_value_reg; + uint8_t get_value_reg; + uint8_t set_direction_reg; + size_t output_value; + size_t output_mask; + bool has_set_value; + bool has_get_value; + bool has_set_direction; + mp_obj_tuple_t *pins; +} i2cioexpander_ioexpander_obj_t; + +void common_hal_i2cioexpander_ioexpander_construct( + i2cioexpander_ioexpander_obj_t *self, + mp_obj_t i2c, + uint8_t address, + uint8_t num_pins, + uint16_t set_value_reg, + uint16_t get_value_reg, + uint16_t set_direction_reg); diff --git a/shared-module/i2cioexpander/IOPin.c b/shared-module/i2cioexpander/IOPin.c new file mode 100644 index 00000000000..04642623b3d --- /dev/null +++ b/shared-module/i2cioexpander/IOPin.c @@ -0,0 +1,148 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/i2cioexpander/IOPin.h" +#include "shared-bindings/i2cioexpander/IOExpander.h" + +#include "py/runtime.h" + +mp_negative_errno_t i2cioexpander_iopin_construct( + i2cioexpander_iopin_obj_t *self, + i2cioexpander_ioexpander_obj_t *expander, + uint8_t pin_number) { + + if (pin_number >= expander->num_pins) { + return MP_EINVAL; // Reusing this for "invalid pin" + } + + self->expander = expander; + self->pin_number = pin_number; + self->direction = DIRECTION_INPUT; + + return 0; +} + +void common_hal_i2cioexpander_iopin_deinit(i2cioexpander_iopin_obj_t *self) { + // Switch to input on deinit. + common_hal_i2cioexpander_iopin_switch_to_input(self, PULL_NONE); +} + +bool common_hal_i2cioexpander_iopin_deinited(i2cioexpander_iopin_obj_t *self) { + return self->expander == NULL || common_hal_i2cioexpander_ioexpander_deinited(self->expander); +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_input( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull) { + + if (pull != PULL_NONE) { + // IO expanders typically don't support pull resistors + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + return DIGITALINOUT_INVALID_PULL; + #endif + } + + self->direction = DIRECTION_INPUT; + + // Clear the output mask bit for this pin + size_t new_mask = self->expander->output_mask & ~(1 << self->pin_number); + common_hal_i2cioexpander_ioexpander_set_output_mask(self->expander, new_mask); + + return DIGITALINOUT_OK; +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_switch_to_output( + i2cioexpander_iopin_obj_t *self, + bool value, + digitalio_drive_mode_t drive_mode) { + + if (drive_mode != DRIVE_MODE_PUSH_PULL) { + // IO expanders typically only support push-pull + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + return DIGITALINOUT_INVALID_DRIVE_MODE; + #endif + } + + self->direction = DIRECTION_OUTPUT; + + // Set the value first + size_t new_value = self->expander->output_value; + if (value) { + new_value |= (1 << self->pin_number); + } else { + new_value &= ~(1 << self->pin_number); + } + common_hal_i2cioexpander_ioexpander_set_output_value(self->expander, new_value); + + // Set the output mask bit for this pin + size_t new_mask = self->expander->output_mask | (1 << self->pin_number); + common_hal_i2cioexpander_ioexpander_set_output_mask(self->expander, new_mask); + + return DIGITALINOUT_OK; +} + +digitalio_direction_t common_hal_i2cioexpander_iopin_get_direction(i2cioexpander_iopin_obj_t *self) { + return self->direction; +} + +mp_negative_errno_t common_hal_i2cioexpander_iopin_set_value(i2cioexpander_iopin_obj_t *self, bool value) { + size_t current_value; + common_hal_i2cioexpander_ioexpander_get_output_value(self->expander, ¤t_value); + size_t new_value; + if (value) { + new_value = current_value | (1 << self->pin_number); + } else { + new_value = current_value & ~(1 << self->pin_number); + } + if (new_value != current_value) { + return common_hal_i2cioexpander_ioexpander_set_output_value(self->expander, new_value); + } + return 0; +} + +mp_negative_errno_t common_hal_i2cioexpander_iopin_get_value(i2cioexpander_iopin_obj_t *self, bool *value) { + size_t full_value; + mp_negative_errno_t result = common_hal_i2cioexpander_ioexpander_get_input_value(self->expander, &full_value); + if (result != 0) { + return result; + } + *value = (full_value & (1 << self->pin_number)) != 0; + return 0; +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_drive_mode( + i2cioexpander_iopin_obj_t *self, + digitalio_drive_mode_t drive_mode) { + + if (drive_mode != DRIVE_MODE_PUSH_PULL) { + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_DRIVE_MODE + return DIGITALINOUT_INVALID_DRIVE_MODE; + #endif + } + + return DIGITALINOUT_OK; +} + +digitalio_drive_mode_t common_hal_i2cioexpander_iopin_get_drive_mode(i2cioexpander_iopin_obj_t *self) { + return DRIVE_MODE_PUSH_PULL; +} + +digitalinout_result_t common_hal_i2cioexpander_iopin_set_pull( + i2cioexpander_iopin_obj_t *self, + digitalio_pull_t pull) { + + if (pull != PULL_NONE) { + #if CIRCUITPY_DIGITALIO_HAVE_INVALID_PULL + return DIGITALINOUT_INVALID_PULL; + #endif + } + + return DIGITALINOUT_OK; +} + +digitalio_pull_t common_hal_i2cioexpander_iopin_get_pull(i2cioexpander_iopin_obj_t *self) { + return PULL_NONE; +} diff --git a/shared-module/i2cioexpander/IOPin.h b/shared-module/i2cioexpander/IOPin.h new file mode 100644 index 00000000000..0c4da8a0213 --- /dev/null +++ b/shared-module/i2cioexpander/IOPin.h @@ -0,0 +1,26 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "shared-bindings/digitalio/Direction.h" +#include "shared-bindings/digitalio/DriveMode.h" +#include "shared-bindings/digitalio/Pull.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-module/i2cioexpander/IOExpander.h" + +typedef struct { + mp_obj_base_t base; + i2cioexpander_ioexpander_obj_t *expander; + uint8_t pin_number; + digitalio_direction_t direction; +} i2cioexpander_iopin_obj_t; + +extern const mp_obj_type_t i2cioexpander_iopin_type; diff --git a/shared-module/i2cioexpander/__init__.c b/shared-module/i2cioexpander/__init__.c new file mode 100644 index 00000000000..43e652db897 --- /dev/null +++ b/shared-module/i2cioexpander/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Nothing now. diff --git a/shared-module/jpegio/JpegDecoder.c b/shared-module/jpegio/JpegDecoder.c index 484ba8e7ccd..89cb624a8d0 100644 --- a/shared-module/jpegio/JpegDecoder.c +++ b/shared-module/jpegio/JpegDecoder.c @@ -46,7 +46,7 @@ static void check_jresult(JRESULT j) { msg = MP_ERROR_TEXT("Right format but not supported"); break; case JDR_FMT3: - msg = MP_ERROR_TEXT("Not supported JPEG standard"); + msg = MP_ERROR_TEXT("Unsupported JPEG (may be progressive)"); break; } mp_raise_RuntimeError(msg); diff --git a/shared-module/keypad/EventQueue.c b/shared-module/keypad/EventQueue.c index 8d831d7a38e..3130d8b59a1 100644 --- a/shared-module/keypad/EventQueue.c +++ b/shared-module/keypad/EventQueue.c @@ -13,9 +13,16 @@ #define EVENT_PRESSED (1 << 15) #define EVENT_KEY_NUM_MASK ((1 << 15) - 1) -void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events) { +#define EVENT_SIZE_BYTES (sizeof(uint16_t) + sizeof(mp_obj_t)) + +void common_hal_keypad_eventqueue_construct(keypad_eventqueue_obj_t *self, size_t max_events, bool use_gc_allocator) { // Event queue is 16-bit values. - ringbuf_alloc(&self->encoded_events, max_events * (sizeof(uint16_t) + sizeof(mp_obj_t))); + const size_t size = max_events * EVENT_SIZE_BYTES; + if (use_gc_allocator) { + ringbuf_alloc(&self->encoded_events, size); + } else { + ringbuf_init(&self->encoded_events, port_malloc(size, false), size); + } self->overflowed = false; self->event_handler = NULL; } @@ -39,7 +46,13 @@ mp_obj_t common_hal_keypad_eventqueue_get(keypad_eventqueue_obj_t *self) { if (result) { return event; } + + #if MICROPY_MALLOC_USES_ALLOCATED_SIZE + m_free(event, sizeof(keypad_event_obj_t)); + #else m_free(event); + #endif + return MP_ROM_NONE; } @@ -57,7 +70,7 @@ void common_hal_keypad_eventqueue_clear(keypad_eventqueue_obj_t *self) { } size_t common_hal_keypad_eventqueue_get_length(keypad_eventqueue_obj_t *self) { - return ringbuf_num_filled(&self->encoded_events); + return ringbuf_num_filled(&self->encoded_events) / EVENT_SIZE_BYTES; } void common_hal_keypad_eventqueue_set_event_handler(keypad_eventqueue_obj_t *self, void (*event_handler)(keypad_eventqueue_obj_t *)) { diff --git a/shared-module/keypad/KeyMatrix.c b/shared-module/keypad/KeyMatrix.c index 67a55468535..28830f591b1 100644 --- a/shared-module/keypad/KeyMatrix.c +++ b/shared-module/keypad/KeyMatrix.c @@ -56,7 +56,7 @@ void common_hal_keypad_keymatrix_construct(keypad_keymatrix_obj_t *self, mp_uint self->columns_to_anodes = columns_to_anodes; self->funcs = &keymatrix_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, true); } void common_hal_keypad_keymatrix_deinit(keypad_keymatrix_obj_t *self) { diff --git a/shared-module/keypad/Keys.c b/shared-module/keypad/Keys.c index 39d50f95e32..80dcf36e163 100644 --- a/shared-module/keypad/Keys.c +++ b/shared-module/keypad/Keys.c @@ -41,7 +41,7 @@ void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pin self->value_when_pressed = value_when_pressed; self->funcs = &keys_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, true); } diff --git a/shared-module/keypad/ShiftRegisterKeys.c b/shared-module/keypad/ShiftRegisterKeys.c index f65c9a0532f..aa0c14dd36b 100644 --- a/shared-module/keypad/ShiftRegisterKeys.c +++ b/shared-module/keypad/ShiftRegisterKeys.c @@ -32,9 +32,7 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ common_hal_digitalio_digitalinout_switch_to_output(clock, false, DRIVE_MODE_PUSH_PULL); self->clock = clock; - digitalio_digitalinout_obj_t *latch = m_new_obj(digitalio_digitalinout_obj_t); - latch->base.type = &digitalio_digitalinout_type; - + digitalio_digitalinout_obj_t *latch = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(latch, latch_pin); common_hal_digitalio_digitalinout_switch_to_output(latch, true, DRIVE_MODE_PUSH_PULL); self->latch = latch; @@ -42,8 +40,7 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ mp_obj_t dios[num_data_pins]; for (size_t i = 0; i < num_data_pins; i++) { - digitalio_digitalinout_obj_t *dio = m_new_obj(digitalio_digitalinout_obj_t); - dio->base.type = &digitalio_digitalinout_type; + digitalio_digitalinout_obj_t *dio = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(dio, data_pins[i]); common_hal_digitalio_digitalinout_switch_to_input(dio, PULL_NONE); dios[i] = dio; @@ -52,7 +49,7 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ // Allocate a tuple object with the data pins self->data_pins = mp_obj_new_tuple(num_data_pins, dios); - self->key_counts = (mp_uint_t *)m_malloc(sizeof(mp_uint_t) * num_key_counts); + self->key_counts = (mp_uint_t *)m_malloc_without_collect(sizeof(mp_uint_t) * num_key_counts); self->num_key_counts = num_key_counts; // copy to an m_malloc() and on the fly record pin with largest Shift register @@ -74,7 +71,7 @@ void common_hal_keypad_shiftregisterkeys_construct(keypad_shiftregisterkeys_obj_ self->value_when_pressed = value_when_pressed; self->funcs = &shiftregisterkeys_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, true); } void common_hal_keypad_shiftregisterkeys_deinit(keypad_shiftregisterkeys_obj_t *self) { diff --git a/shared-module/keypad/__init__.c b/shared-module/keypad/__init__.c index e43c7bce4fb..f1d5d395df7 100644 --- a/shared-module/keypad/__init__.c +++ b/shared-module/keypad/__init__.c @@ -85,14 +85,20 @@ void keypad_deregister_scanner(keypad_scanner_obj_t *scanner) { supervisor_release_lock(&keypad_scanners_linked_list_lock); } -void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) { +void keypad_construct_common(keypad_scanner_obj_t *self, mp_float_t interval, size_t max_events, uint8_t debounce_threshold, bool use_gc_allocator) { size_t key_count = common_hal_keypad_generic_get_key_count(self); - self->debounce_counter = (int8_t *)m_malloc(sizeof(int8_t) * key_count); + self->debounce_counter = + use_gc_allocator + ? (int8_t *)m_malloc_without_collect(sizeof(int8_t) * key_count) + : (int8_t *)port_malloc_zero(sizeof(int8_t) * key_count, false); self->interval_ticks = (mp_uint_t)(interval * 1024); // interval * 1000 * (1024/1000) - keypad_eventqueue_obj_t *events = mp_obj_malloc(keypad_eventqueue_obj_t, &keypad_eventqueue_type); - common_hal_keypad_eventqueue_construct(events, max_events); + keypad_eventqueue_obj_t *events = + use_gc_allocator + ? mp_obj_malloc(keypad_eventqueue_obj_t, &keypad_eventqueue_type) + : mp_obj_port_malloc(keypad_eventqueue_obj_t, &keypad_eventqueue_type); + common_hal_keypad_eventqueue_construct(events, max_events, use_gc_allocator); self->events = events; self->debounce_threshold = debounce_threshold; @@ -140,7 +146,7 @@ void keypad_never_reset(keypad_scanner_obj_t *self) { void common_hal_keypad_generic_reset(void *self_in) { keypad_scanner_obj_t *self = self_in; size_t key_count = common_hal_keypad_generic_get_key_count(self); - memset(self->debounce_counter, self->debounce_threshold, key_count); + memset(self->debounce_counter, -self->debounce_threshold, key_count); keypad_scan_now(self, port_get_raw_ticks(NULL)); } diff --git a/shared-module/keypad/__init__.h b/shared-module/keypad/__init__.h index a7d21753f66..66fea487854 100644 --- a/shared-module/keypad/__init__.h +++ b/shared-module/keypad/__init__.h @@ -39,7 +39,7 @@ void keypad_reset(void); void keypad_register_scanner(keypad_scanner_obj_t *scanner); void keypad_deregister_scanner(keypad_scanner_obj_t *scanner); -void keypad_construct_common(keypad_scanner_obj_t *scanner, mp_float_t interval, size_t max_events, uint8_t debounce_cycles); +void keypad_construct_common(keypad_scanner_obj_t *scanner, mp_float_t interval, size_t max_events, uint8_t debounce_cycles, bool use_gc_allocator); bool keypad_debounce(keypad_scanner_obj_t *self, mp_uint_t key_number, bool current); void keypad_never_reset(keypad_scanner_obj_t *self); diff --git a/shared-module/keypad_demux/DemuxKeyMatrix.c b/shared-module/keypad_demux/DemuxKeyMatrix.c index 42a0a0e68cc..329f7679d3f 100644 --- a/shared-module/keypad_demux/DemuxKeyMatrix.c +++ b/shared-module/keypad_demux/DemuxKeyMatrix.c @@ -7,6 +7,7 @@ #include #include "py/gc.h" +#include "py/mphal.h" #include "py/runtime.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/keypad/EventQueue.h" @@ -26,35 +27,49 @@ static keypad_scanner_funcs_t keymatrix_funcs = { }; static mp_uint_t row_column_to_key_number(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t row, mp_uint_t column) { - return row * self->column_digitalinouts->len + column; + // return the key index in the user's coordinate system + return row * common_hal_keypad_demux_demuxkeymatrix_get_column_count(self) + column; } -void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], mp_float_t interval, size_t max_events, uint8_t debounce_threshold) { - +void common_hal_keypad_demux_demuxkeymatrix_construct(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t num_row_addr_pins, const mcu_pin_obj_t *row_addr_pins[], mp_uint_t num_column_pins, const mcu_pin_obj_t *column_pins[], bool columns_to_anodes, bool transpose, mp_float_t interval, size_t max_events, uint8_t debounce_threshold, bool use_gc_allocator) { + // the multiplexed pins are outputs so we can set the address for the target row + // the sense of the address pins themselves doesn't change with columns_to_anodes + // but the value output on the selected row line will be !columns_to_anodes mp_obj_t row_addr_dios[num_row_addr_pins]; for (size_t row = 0; row < num_row_addr_pins; row++) { digitalio_digitalinout_obj_t *dio = - mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); + use_gc_allocator + ? mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type) + : mp_obj_port_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(dio, row_addr_pins[row]); common_hal_digitalio_digitalinout_switch_to_output(dio, false, DRIVE_MODE_PUSH_PULL); row_addr_dios[row] = dio; } - self->row_addr_digitalinouts = mp_obj_new_tuple(num_row_addr_pins, row_addr_dios); + self->row_addr_digitalinouts = + use_gc_allocator + ? mp_obj_new_tuple(num_row_addr_pins, row_addr_dios) + : mp_obj_new_port_tuple(num_row_addr_pins, row_addr_dios); + // the column pins are always inputs, with default state based on columns_to_anodes mp_obj_t column_dios[num_column_pins]; for (size_t column = 0; column < num_column_pins; column++) { digitalio_digitalinout_obj_t *dio = - mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); - dio->base.type = &digitalio_digitalinout_type; + use_gc_allocator + ? mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type) + : mp_obj_port_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(dio, column_pins[column]); - common_hal_digitalio_digitalinout_switch_to_input(dio, PULL_UP); + common_hal_digitalio_digitalinout_switch_to_input(dio, columns_to_anodes ? PULL_UP : PULL_DOWN); column_dios[column] = dio; } - self->column_digitalinouts = mp_obj_new_tuple(num_column_pins, column_dios); - + self->column_digitalinouts = + use_gc_allocator + ? mp_obj_new_tuple(num_column_pins, column_dios) + : mp_obj_new_port_tuple(num_column_pins, column_dios); + self->columns_to_anodes = columns_to_anodes; + self->transpose = transpose; self->funcs = &keymatrix_funcs; - keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold); + keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold, use_gc_allocator); } void common_hal_keypad_demux_demuxkeymatrix_deinit(keypad_demux_demuxkeymatrix_obj_t *self) { @@ -78,11 +93,15 @@ void common_hal_keypad_demux_demuxkeymatrix_deinit(keypad_demux_demuxkeymatrix_o } size_t common_hal_keypad_demux_demuxkeymatrix_get_row_count(keypad_demux_demuxkeymatrix_obj_t *self) { - return 1 << self->row_addr_digitalinouts->len; + return self->transpose + ? self->column_digitalinouts->len + : (size_t)(1 << self->row_addr_digitalinouts->len); } size_t common_hal_keypad_demux_demuxkeymatrix_get_column_count(keypad_demux_demuxkeymatrix_obj_t *self) { - return self->column_digitalinouts->len; + return self->transpose + ? (size_t)(1 << self->row_addr_digitalinouts->len) + : self->column_digitalinouts->len; } mp_uint_t common_hal_keypad_demux_demuxkeymatrix_row_column_to_key_number(keypad_demux_demuxkeymatrix_obj_t *self, mp_uint_t row, mp_uint_t column) { @@ -102,9 +121,13 @@ static size_t demuxkeymatrix_get_key_count(void *self_in) { static void demuxkeymatrix_scan_now(void *self_in, mp_obj_t timestamp) { keypad_demux_demuxkeymatrix_obj_t *self = self_in; - - for (size_t row = 0; row < common_hal_keypad_demux_demuxkeymatrix_get_row_count(self); row++) { - // Set the row address on demultiplexer + // We always scan through the multiplexed lines using the array sizes directly + // and apply transposition only when translating to key number. + for (int row = 0; row < (1 << self->row_addr_digitalinouts->len); row++) { + // Set the row address on the demultiplexer. + // When columns_to_anodes is True (default) we've got an inverting demux + // so the selected line is pulled low, and we look for rows that get pulled low. + // When columns_to_anodes is False we do the reverse. size_t mask = 0b00000001; for (size_t row_addr_pin = 0; row_addr_pin < self->row_addr_digitalinouts->len; row_addr_pin++) { digitalio_digitalinout_obj_t *dio = self->row_addr_digitalinouts->items[row_addr_pin]; @@ -112,12 +135,24 @@ static void demuxkeymatrix_scan_now(void *self_in, mp_obj_t timestamp) { mask = mask << 1; } - for (size_t column = 0; column < common_hal_keypad_demux_demuxkeymatrix_get_column_count(self); column++) { - mp_uint_t key_number = row_column_to_key_number(self, row, column); - - // Get the current state, by reading whether the column got pulled to the row value or not. - // If low, the key is pressed. - const bool current = !common_hal_digitalio_digitalinout_get_value(self->column_digitalinouts->items[column]); + // Wait a moment to let the columns settle. + // The normal KeyMatrix uses a 1us delay but that still gave echoes on my + // nullbitsco nibble 65% (16 x 5 matrix). For example when key (row, col) is pressed + // both (row, col) and (row+1, col) (and sometimes row+2) are registered, + // especially when row+1 is a power of 2 (all mux bits change) and col is 0. + // The QMK implementation for this keyboard uses a 5us delay which works here too + mp_hal_delay_us(5); + + for (size_t column = 0; column < self->column_digitalinouts->len; column++) { + mp_uint_t key_number = self->transpose + ? row_column_to_key_number(self, column, row) + : row_column_to_key_number(self, row, column); + + // Get the current state, by reading whether the column got pulled to the row value or not, + // which is the opposite of columns_to_anodes. + const bool current = + common_hal_digitalio_digitalinout_get_value(self->column_digitalinouts->items[column]) != + self->columns_to_anodes; // Record any transitions. if (keypad_debounce((keypad_scanner_obj_t *)self, key_number, current)) { diff --git a/shared-module/keypad_demux/DemuxKeyMatrix.h b/shared-module/keypad_demux/DemuxKeyMatrix.h index 45afa93a844..fe315775dd2 100644 --- a/shared-module/keypad_demux/DemuxKeyMatrix.h +++ b/shared-module/keypad_demux/DemuxKeyMatrix.h @@ -17,6 +17,8 @@ typedef struct { KEYPAD_SCANNER_COMMON_FIELDS; mp_obj_tuple_t *row_addr_digitalinouts; mp_obj_tuple_t *column_digitalinouts; + bool columns_to_anodes; + bool transpose; } keypad_demux_demuxkeymatrix_obj_t; void keypad_demux_demuxkeymatrix_scan(keypad_demux_demuxkeymatrix_obj_t *self); diff --git a/shared-module/lvfontio/OnDiskFont.c b/shared-module/lvfontio/OnDiskFont.c new file mode 100644 index 00000000000..efffed63074 --- /dev/null +++ b/shared-module/lvfontio/OnDiskFont.c @@ -0,0 +1,885 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include + +#include "shared-bindings/lvfontio/OnDiskFont.h" +#include "py/runtime.h" +#include "py/mperrno.h" +#include "py/stream.h" +#include "py/objstr.h" +#include "py/gc.h" +#include "shared-bindings/displayio/Bitmap.h" +#include "extmod/vfs_fat.h" +#include "lib/oofatfs/ff.h" +#include "supervisor/shared/translate/translate.h" +#include "supervisor/port.h" +#include "supervisor/shared/serial.h" +#include "supervisor/filesystem.h" + +// Helper functions for memory allocation +static inline void *allocate_memory(lvfontio_ondiskfont_t *self, size_t size) { + void *ptr; + if (self->use_gc_allocator) { + ptr = m_malloc_maybe(size); + } else { + ptr = port_malloc(size, false); + } + if (ptr != NULL) { + return ptr; + } + common_hal_lvfontio_ondiskfont_deinit(self); + if (self->use_gc_allocator) { + m_malloc_fail(size); + } + return NULL; +} + +static inline void free_memory(lvfontio_ondiskfont_t *self, void *ptr) { + if (self->use_gc_allocator) { + m_free(ptr); + } else { + port_free(ptr); + } +} + +// Forward declarations for helper functions +static int16_t find_codepoint_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint); +static bool slot_has_active_full_width_partner(lvfontio_ondiskfont_t *self, uint16_t slot); +static uint16_t find_free_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint); +static FRESULT read_bits(FIL *file, size_t num_bits, uint8_t *byte_val, uint8_t *remaining_bits, uint32_t *result); +static FRESULT read_glyph_dimensions(FIL *file, lvfontio_ondiskfont_t *self, uint32_t *advance_width, int32_t *bbox_x, int32_t *bbox_y, uint32_t *bbox_w, uint32_t *bbox_h, uint8_t *byte_val, uint8_t *remaining_bits); + +// Load font header data from file +static bool load_font_header(lvfontio_ondiskfont_t *self, FIL *file, size_t *max_slots) { + UINT bytes_read; + FRESULT res; + + // Start at the beginning of the file + res = f_lseek(file, 0); + if (res != FR_OK) { + return false; + } + + uint8_t buffer[8]; + bool found_head = false; + bool found_cmap = false; + bool found_loca = false; + bool found_glyf = false; + + + size_t current_position = 0; + + // Read sections until we find all the sections we need or reach end of file + while (true) { + // Read section size (4 bytes) + res = f_read(file, buffer, 4, &bytes_read); + if (res != FR_OK || bytes_read < 4) { + break; // Read error or end of file + } + + uint32_t section_size = buffer[0] | (buffer[1] << 8) | + (buffer[2] << 16) | (buffer[3] << 24); + + if (section_size == 0) { + break; // End of sections marker + } + + // Read section marker (4 bytes) + res = f_read(file, buffer, 4, &bytes_read); + if (res != FR_OK || bytes_read < 4) { + break; // Read error or unexpected end of file + } + + + // Make a null-terminated copy of the section marker for debug printing + char section_marker[5] = {0}; + memcpy(section_marker, buffer, 4); + + // Process different section types + if (memcmp(buffer, "head", 4) == 0) { + // Read head section data (35 bytes) + uint8_t head_buf[35]; + res = f_read(file, head_buf, 35, &bytes_read); + if (res != FR_OK || bytes_read < 35) { + break; + } + + // Skip version (4 bytes) and padding (1 byte) + // Parse font metrics at offset 6 + self->header.font_size = head_buf[6] | (head_buf[7] << 8); + self->header.ascent = head_buf[8] | (head_buf[9] << 8); + self->header.default_advance_width = head_buf[22] | (head_buf[23] << 8); + + // Parse format information + self->header.index_to_loc_format = head_buf[26]; + self->header.bits_per_pixel = head_buf[29]; + self->header.glyph_bbox_xy_bits = head_buf[30]; + self->header.glyph_bbox_wh_bits = head_buf[31]; + self->header.glyph_advance_bits = head_buf[32]; + + // Calculate derived values + self->header.glyph_header_bits = self->header.glyph_advance_bits + + 2 * self->header.glyph_bbox_xy_bits + + 2 * self->header.glyph_bbox_wh_bits; + self->header.glyph_header_bytes = (self->header.glyph_header_bits + 7) / 8; + + found_head = true; + } else if (memcmp(buffer, "cmap", 4) == 0) { + // Read subtable count + uint8_t cmap_header[4]; + res = f_read(file, cmap_header, 4, &bytes_read); + if (res != FR_OK || bytes_read < 4) { + break; + } + + uint32_t subtable_count = cmap_header[0] | (cmap_header[1] << 8) | + (cmap_header[2] << 16) | (cmap_header[3] << 24); + + // Allocate memory for cmap ranges + self->cmap_range_count = subtable_count; + self->cmap_ranges = allocate_memory(self, sizeof(lvfontio_cmap_range_t) * subtable_count); + if (self->cmap_ranges == NULL) { + return false; + } + + // Read each subtable + for (uint16_t i = 0; i < subtable_count; i++) { + uint8_t subtable_buf[16]; + res = f_read(file, subtable_buf, 16, &bytes_read); + if (res != FR_OK || bytes_read < 16) { + break; + } + + // Read data_offset (4 bytes) + uint32_t data_offset = subtable_buf[0] | (subtable_buf[1] << 8) | + (subtable_buf[2] << 16) | (subtable_buf[3] << 24); + + // Read range_start, range_length, glyph_offset + uint32_t range_start = subtable_buf[4] | (subtable_buf[5] << 8) | + (subtable_buf[6] << 16) | (subtable_buf[7] << 24); + uint16_t range_length = subtable_buf[8] | (subtable_buf[9] << 8); + uint16_t glyph_offset = subtable_buf[10] | (subtable_buf[11] << 8); + uint16_t entries_count = subtable_buf[12] | (subtable_buf[13] << 8); + + // Get format type (0=sparse mapping, 1=range mapping, 2=range to range, 3=direct mapping) + uint8_t format_type = subtable_buf[14]; + // Check for supported format types (0, 2, and 3) + if (format_type != 0 && format_type != 2 && format_type != 3) { + continue; + } + + // Store the range information + self->cmap_ranges[i].range_start = range_start; + self->cmap_ranges[i].range_end = range_start + range_length; + self->cmap_ranges[i].glyph_offset = glyph_offset; + self->cmap_ranges[i].format_type = format_type; + self->cmap_ranges[i].data_offset = current_position + data_offset; + self->cmap_ranges[i].entries_count = entries_count; + } + + found_cmap = true; + } else if (memcmp(buffer, "loca", 4) == 0) { + // Read max_cid + uint8_t loca_header[4]; + res = f_read(file, loca_header, 4, &bytes_read); + if (res != FR_OK || bytes_read < 4) { + break; + } + + // Store max_cid value + self->max_cid = loca_header[0] | (loca_header[1] << 8) | + (loca_header[2] << 16) | (loca_header[3] << 24); + + // Store location of the loca table offset data + self->loca_table_offset = current_position + 12; + + found_loca = true; + } else if (memcmp(buffer, "glyf", 4) == 0) { + // Store start of glyf table + self->glyf_table_offset = current_position; + size_t advances[2] = {0, 0}; + size_t advance_count[2] = {0, 0}; + + if (self->header.default_advance_width != 0) { + advances[0] = self->header.default_advance_width; + } + + // Set the default advance width based on the first character in the + // file. + size_t cid = 0; + while (cid < self->max_cid - 1) { + // Read glyph header fields + uint32_t glyph_advance; + int32_t bbox_x, bbox_y; + uint32_t bbox_w, bbox_h; + + uint8_t byte_val = 0; + uint8_t remaining_bits = 0; + + // Use the helper function to read glyph dimensions + read_glyph_dimensions(file, self, &glyph_advance, &bbox_x, &bbox_y, &bbox_w, &bbox_h, &byte_val, &remaining_bits); + + // Throw away the bitmap bits. + read_bits(file, self->header.bits_per_pixel * bbox_w * bbox_h, &byte_val, &remaining_bits, NULL); + + if (glyph_advance == 0) { + // Ignore zero-advance glyphs when inferring the terminal cell width. + // Some fonts include placeholders/control glyphs with zero advance, + // which would otherwise skew default_advance_width too small. + } else if (advances[0] == glyph_advance) { + advance_count[0]++; + } else if (advances[1] == glyph_advance) { + advance_count[1]++; + } else if (advance_count[0] == 0) { + advances[0] = glyph_advance; + advance_count[0] = 1; + } else if (advance_count[1] == 0) { + advances[1] = glyph_advance; + advance_count[1] = 1; + } else { + break; + } + cid++; + } + + if (self->header.default_advance_width == 0) { + if (advance_count[1] == 0) { + self->header.default_advance_width = advances[0]; + *max_slots = advance_count[0]; + } else { + if (advances[0] > advances[1]) { + self->header.default_advance_width = advances[0] / 2; + *max_slots = advance_count[0] * 2 + advance_count[1]; + } else { + self->header.default_advance_width = advances[1] / 2; + *max_slots = advance_count[1] * 2 + advance_count[0]; + } + } + } else { + *max_slots = advance_count[0] + advance_count[1]; + } + + if (self->header.default_advance_width == 0) { + self->header.default_advance_width = 1; + } + if (*max_slots == 0) { + *max_slots = 1; + } + found_glyf = true; + } + + current_position += section_size; + + // Skip to the end of the section + res = f_lseek(file, current_position); + if (res != FR_OK) { + break; + } + + // If we found all needed sections, we can stop + if (found_head && found_cmap && found_loca && found_glyf) { + break; + } + } + + // Check if we found all required sections + if (!found_head || !found_cmap || !found_loca || !found_glyf) { + return false; + } + + return true; +} + +// Get character ID (glyph index) for a codepoint +static int32_t get_char_id(lvfontio_ondiskfont_t *self, uint32_t codepoint) { + // Find codepoint in cmap ranges + for (uint16_t i = 0; i < self->cmap_range_count; i++) { + // Check if codepoint is in range for this subtable + if (codepoint >= self->cmap_ranges[i].range_start && + codepoint < self->cmap_ranges[i].range_end) { + + // Handle according to format type + switch (self->cmap_ranges[i].format_type) { + case 0: { // Sparse mapping - need to look up in a sparse table + if (!self->file_is_open) { + return -1; + } + + // Calculate the relative position within the range + uint32_t idx = codepoint - self->cmap_ranges[i].range_start; + + if (idx >= self->cmap_ranges[i].entries_count) { + return -1; + } + + // Calculate the absolute data position in the file + uint32_t data_pos = self->cmap_ranges[i].data_offset + idx; // 1 byte per entry + FRESULT res = f_lseek(&self->file, data_pos); + if (res != FR_OK) { + return -1; + } + + // Read the glyph ID (1 byte) + uint8_t glyph_id; + UINT bytes_read; + res = f_read(&self->file, &glyph_id, 1, &bytes_read); + + if (res != FR_OK || bytes_read < 1) { + return -1; + } + + + return self->cmap_ranges[i].glyph_offset + glyph_id; + } + + case 2: // Range to range - calculate based on offset within range + uint16_t idx = codepoint - self->cmap_ranges[i].range_start; + uint16_t glyph_id = self->cmap_ranges[i].glyph_offset + idx; + return glyph_id; + + case 3: { // Direct mapping - need to look up in the table + if (!self->file_is_open) { + return -1; + } + + FRESULT res; + res = f_lseek(&self->file, self->cmap_ranges[i].data_offset); + if (res != FR_OK) { + return -1; + } + uint16_t codepoint_delta = codepoint - self->cmap_ranges[i].range_start; + + for (size_t j = 0; j < self->cmap_ranges[i].entries_count; j++) { + // Read code point at the index + uint16_t candidate_codepoint_delta; + UINT bytes_read; + res = f_read(&self->file, &candidate_codepoint_delta, 2, &bytes_read); + if (res != FR_OK || bytes_read < 2) { + return -1; + } + + if (candidate_codepoint_delta == codepoint_delta) { + return self->cmap_ranges[i].glyph_offset + j; + } + } + return -1; + } + + default: + return -1; + } + } + } + + return -1; // Not found +} + +// Load glyph bitmap data into a slot +// This function assumes the file is already open and positioned after reading the glyph dimensions +static bool load_glyph_bitmap(FIL *file, lvfontio_ondiskfont_t *self, uint32_t codepoint, uint16_t slot, + uint32_t glyph_advance, int32_t bbox_x, int32_t bbox_y, uint32_t bbox_w, uint32_t bbox_h, + uint8_t *byte_val, uint8_t *remaining_bits) { + // Store codepoint at slot + self->codepoints[slot] = codepoint; + self->reference_counts[slot] = 1; + + // Read bitmap data pixel by pixel + uint16_t x_offset = slot * self->header.default_advance_width; + uint16_t y_offset = self->header.ascent - bbox_y - bbox_h; + for (uint16_t y = 0; y < bbox_h; y++) { + for (uint16_t x = 0; x < bbox_w; x++) { + uint32_t pixel_value; + FRESULT res = read_bits(file, self->header.bits_per_pixel, byte_val, remaining_bits, &pixel_value); + if (res != FR_OK) { + return false; + } + + // Adjust for bbox position within the glyph bounding box + int16_t bitmap_x = x_offset + x + bbox_x; + int16_t bitmap_y = y_offset + y; + + // Make sure we're in bounds + if (bitmap_x >= 0 && + bitmap_x < self->header.default_advance_width * self->max_glyphs && + bitmap_y >= 0 && + bitmap_y < self->header.font_size) { + common_hal_displayio_bitmap_set_pixel( + self->bitmap, + bitmap_x, + bitmap_y, + pixel_value + ); + } + } + } + + return true; +} + +// Constructor +void common_hal_lvfontio_ondiskfont_construct(lvfontio_ondiskfont_t *self, + const char *file_path, + uint16_t max_glyphs, + bool use_gc_allocator) { + + // Store the allocation mode + self->use_gc_allocator = use_gc_allocator; + // Store parameters + self->file_path = file_path; // Store the provided path string directly + self->max_glyphs = max_glyphs; + self->cmap_ranges = NULL; + self->file_is_open = false; + + // Determine which filesystem to use based on the path + const char *path_under_mount; + fs_user_mount_t *vfs = filesystem_for_path(file_path, &path_under_mount); + + if (vfs == NULL) { + if (self->use_gc_allocator) { + mp_raise_ValueError(MP_ERROR_TEXT("File not found")); + } + return; + } + + // Open the file and keep it open for the lifetime of the object + FRESULT res = f_open(&vfs->fatfs, &self->file, path_under_mount, FA_READ); + + if (res != FR_OK) { + if (self->use_gc_allocator) { + mp_raise_ValueError(MP_ERROR_TEXT("File not found")); + } + return; + } + + self->file_is_open = true; + + // Load font headers + size_t max_slots; + if (!load_font_header(self, &self->file, &max_slots)) { + f_close(&self->file); + self->file_is_open = false; + if (self->use_gc_allocator) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_file); + } + return; + } + // Cap the number of slots to the number of slots needed by the font. That way + // small font files don't need a bunch of extra cache space. + max_glyphs = MIN(max_glyphs, max_slots); + + // Allocate codepoints array. allocate_memory will raise an exception if + // allocation fails and the VM is active. + self->codepoints = allocate_memory(self, sizeof(uint32_t) * max_glyphs); + if (self->codepoints == NULL) { + return; + } + + // Initialize codepoints to invalid + for (uint16_t i = 0; i < max_glyphs; i++) { + self->codepoints[i] = LVFONTIO_INVALID_CODEPOINT; + } + + // Allocate reference counts + self->reference_counts = allocate_memory(self, sizeof(uint16_t) * max_glyphs); + if (self->reference_counts == NULL) { + return; + } + + // Initialize reference counts to 0 + memset(self->reference_counts, 0, sizeof(uint16_t) * max_glyphs); + + self->half_width_px = self->header.default_advance_width; + + // Create bitmap for glyph cache + displayio_bitmap_t *bitmap = allocate_memory(self, sizeof(displayio_bitmap_t)); + bitmap->base.type = &displayio_bitmap_type; + if (bitmap == NULL) { + return; + } + + // Calculate bitmap stride + uint32_t bits_per_pixel = 1 << self->header.bits_per_pixel; + uint32_t width = self->header.default_advance_width * max_glyphs; + uint32_t row_width = width * bits_per_pixel; + uint16_t stride = (row_width + 31) / 32; // Align to uint32_t (32 bits) + + // Allocate buffer for bitmap data + uint32_t buffer_size = stride * self->header.font_size * sizeof(uint32_t); + uint32_t *bitmap_buffer = allocate_memory(self, buffer_size); + if (bitmap_buffer == NULL) { + return; + } + + // Zero out bitmap buffer + memset(bitmap_buffer, 0, buffer_size); + + // Construct bitmap with allocated buffer + common_hal_displayio_bitmap_construct_from_buffer(bitmap, + self->header.default_advance_width * max_glyphs, + self->header.font_size, + 1 << self->header.bits_per_pixel, + bitmap_buffer, + false); + self->bitmap = bitmap; +} + +void common_hal_lvfontio_ondiskfont_deinit(lvfontio_ondiskfont_t *self) { + if (!self->file_is_open) { + return; + } + + if (self->bitmap != NULL) { + common_hal_displayio_bitmap_deinit(self->bitmap); + self->bitmap = NULL; + } + + if (self->codepoints != NULL) { + free_memory(self, self->codepoints); + self->codepoints = NULL; + } + + if (self->reference_counts != NULL) { + free_memory(self, self->reference_counts); + self->reference_counts = NULL; + } + + + + if (self->cmap_ranges != NULL) { + free_memory(self, self->cmap_ranges); + self->cmap_ranges = NULL; + } + + f_close(&self->file); + self->file_is_open = false; +} + +bool common_hal_lvfontio_ondiskfont_deinited(lvfontio_ondiskfont_t *self) { + return !self->file_is_open; +} + +mp_obj_t common_hal_lvfontio_ondiskfont_get_bitmap(const lvfontio_ondiskfont_t *self) { + return MP_OBJ_FROM_PTR(self->bitmap); +} + +mp_obj_t common_hal_lvfontio_ondiskfont_get_bounding_box(const lvfontio_ondiskfont_t *self) { + mp_obj_t bbox[2]; + bbox[0] = MP_OBJ_NEW_SMALL_INT(self->header.default_advance_width); + bbox[1] = MP_OBJ_NEW_SMALL_INT(self->header.font_size); + return mp_obj_new_tuple(2, bbox); +} + +void common_hal_lvfontio_ondiskfont_get_dimensions(const lvfontio_ondiskfont_t *self, + uint16_t *width, uint16_t *height) { + if (width != NULL) { + *width = self->header.default_advance_width; + } + if (height != NULL) { + *height = self->header.font_size; + } +} + +int16_t common_hal_lvfontio_ondiskfont_cache_glyph(lvfontio_ondiskfont_t *self, uint32_t codepoint, bool *is_full_width) { + // Check if already cached + int16_t existing_slot = find_codepoint_slot(self, codepoint); + if (existing_slot >= 0) { + // Glyph is already cached, increment reference count(s). + self->reference_counts[existing_slot]++; + + // Check if this is a full-width character by looking for a second slot + // with the same codepoint right after this one, wrapping at the end. + uint16_t next_slot = (existing_slot + 1) % self->max_glyphs; + bool cached_is_full_width = self->codepoints[next_slot] == codepoint; + + if (cached_is_full_width) { + self->reference_counts[next_slot]++; + } + + if (is_full_width != NULL) { + *is_full_width = cached_is_full_width; + } + + return existing_slot; + } + + // First check if the glyph is full-width before allocating slots + // This way we know if we need one or two slots before committing + bool is_full_width_glyph = false; + + // Check if file is already open + if (!self->file_is_open) { + + return -1; + } + + // Find character ID from codepoint + int32_t char_id = get_char_id(self, codepoint); + if (char_id < 0 || (uint32_t)char_id >= self->max_cid) { + return -1; // Invalid character + } + + // Get glyph offset from location table + uint32_t glyph_offset = 0; + uint32_t loca_offset = self->loca_table_offset + char_id * + (self->header.index_to_loc_format == 1 ? 4 : 2); + + FRESULT res = f_lseek(&self->file, loca_offset); + if (res != FR_OK) { + return -1; + } + + UINT bytes_read; + if (self->header.index_to_loc_format == 1) { + // 4-byte offset + uint8_t offset_buf[4]; + res = f_read(&self->file, offset_buf, 4, &bytes_read); + if (res != FR_OK || bytes_read < 4) { + return -1; + } + glyph_offset = offset_buf[0] | (offset_buf[1] << 8) | + (offset_buf[2] << 16) | (offset_buf[3] << 24); + } else { + // 2-byte offset + uint8_t offset_buf[2]; + res = f_read(&self->file, offset_buf, 2, &bytes_read); + if (res != FR_OK || bytes_read < 2) { + return -1; + } + glyph_offset = offset_buf[0] | (offset_buf[1] << 8); + } + // Seek to glyph data + res = f_lseek(&self->file, self->glyf_table_offset + glyph_offset); + if (res != FR_OK) { + return -1; + } + + // Read glyph header fields to determine width + uint32_t glyph_advance; + int32_t bbox_x, bbox_y; + uint32_t bbox_w, bbox_h; + + // Initialize bit reading state + uint8_t byte_val = 0; + uint8_t remaining_bits = 0; + + // Use the helper function to read glyph dimensions + res = read_glyph_dimensions(&self->file, self, &glyph_advance, &bbox_x, &bbox_y, &bbox_w, &bbox_h, &byte_val, &remaining_bits); + if (res != FR_OK) { + return -1; + } + + // Check if the glyph is full-width based on its advance width + // Full-width characters typically have an advance width close to or greater than the font height + is_full_width_glyph = glyph_advance > self->half_width_px; + + // Now we know if we need one or two slots + uint16_t slots_needed = is_full_width_glyph ? 2 : 1; + + // Find an appropriate slot (or consecutive slots for full-width) + uint16_t slot = UINT16_MAX; + + if (slots_needed == 1) { + // For regular width, find a free slot starting at codepoint's position + slot = find_free_slot(self, codepoint); + } else { + // For full-width, find two consecutive free slots + for (uint16_t i = 0; i < self->max_glyphs - 1; i++) { + if (self->codepoints[i] == LVFONTIO_INVALID_CODEPOINT && + self->reference_counts[i] == 0 && + self->codepoints[i + 1] == LVFONTIO_INVALID_CODEPOINT && + self->reference_counts[i + 1] == 0) { + slot = i; + break; + } + } + } + + // Check if we found appropriate slot(s) + if (slot == UINT16_MAX) { + return -1; // No slots available + } + + // Load glyph into the slot + if (!load_glyph_bitmap(&self->file, self, codepoint, slot, glyph_advance, + bbox_x, bbox_y, bbox_w, bbox_h, &byte_val, &remaining_bits)) { + return -1; // Failed to load glyph + } + + // For full-width characters, mark both slots with the same codepoint + if (is_full_width_glyph && slot + 1 < self->max_glyphs) { + self->codepoints[slot + 1] = codepoint; + self->reference_counts[slot + 1] = 1; + } + + if (is_full_width != NULL) { + *is_full_width = is_full_width_glyph; + } + + return slot; +} + +void common_hal_lvfontio_ondiskfont_release_glyph(lvfontio_ondiskfont_t *self, uint32_t slot) { + if (slot >= self->max_glyphs) { + return; + } + + if (self->reference_counts[slot] > 0) { + self->reference_counts[slot]--; + } +} + +static int16_t find_codepoint_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint) { + size_t offset = codepoint % self->max_glyphs; + for (uint16_t i = 0; i < self->max_glyphs; i++) { + int16_t slot = (i + offset) % self->max_glyphs; + if (self->codepoints[slot] == codepoint) { + // If this is the second slot of a full-width glyph pair, return the + // first slot so callers always get a canonical index. + if (slot > 0 && self->codepoints[slot - 1] == codepoint) { + return slot - 1; + } + return slot; + } + } + return -1; +} + +static bool slot_has_active_full_width_partner(lvfontio_ondiskfont_t *self, uint16_t slot) { + uint32_t codepoint = self->codepoints[slot]; + if (codepoint == LVFONTIO_INVALID_CODEPOINT) { + return false; + } + + // Don't evict one half of a full-width pair while the other half is still in use. + uint16_t prev_slot = (slot + self->max_glyphs - 1) % self->max_glyphs; + uint16_t next_slot = (slot + 1) % self->max_glyphs; + + if (self->codepoints[prev_slot] == codepoint && self->reference_counts[prev_slot] > 0) { + return true; + } + if (self->codepoints[next_slot] == codepoint && self->reference_counts[next_slot] > 0) { + return true; + } + + return false; +} + +static uint16_t find_free_slot(lvfontio_ondiskfont_t *self, uint32_t codepoint) { + size_t offset = codepoint % self->max_glyphs; + + // First look for completely unused slots, starting at the offset + for (uint16_t i = 0; i < self->max_glyphs; i++) { + int16_t slot = (i + offset) % self->max_glyphs; + if (self->codepoints[slot] == LVFONTIO_INVALID_CODEPOINT && self->reference_counts[slot] == 0) { + return slot; + } + } + + // If none found, look for slots with zero reference count, starting at the offset. + // Avoid reusing one half of an active full-width glyph pair. + for (uint16_t i = 0; i < self->max_glyphs; i++) { + int16_t slot = (i + offset) % self->max_glyphs; + if (self->reference_counts[slot] == 0 && !slot_has_active_full_width_partner(self, slot)) { + return slot; + } + } + + // No slots available + return UINT16_MAX; +} + +static FRESULT read_glyph_dimensions(FIL *file, lvfontio_ondiskfont_t *self, + uint32_t *advance_width, int32_t *bbox_x, int32_t *bbox_y, + uint32_t *bbox_w, uint32_t *bbox_h, + uint8_t *byte_val, uint8_t *remaining_bits) { + FRESULT res; + uint32_t temp_value; + + // Read glyph_advance + res = read_bits(file, self->header.glyph_advance_bits, byte_val, remaining_bits, &temp_value); + if (res != FR_OK) { + return res; + } + *advance_width = temp_value; + + // Read bbox_x (signed) + res = read_bits(file, self->header.glyph_bbox_xy_bits, byte_val, remaining_bits, &temp_value); + if (res != FR_OK) { + return res; + } + // Convert to signed value if needed + if (temp_value & (1 << (self->header.glyph_bbox_xy_bits - 1))) { + *bbox_x = temp_value - (1 << self->header.glyph_bbox_xy_bits); + } else { + *bbox_x = temp_value; + } + + // Read bbox_y (signed) + res = read_bits(file, self->header.glyph_bbox_xy_bits, byte_val, remaining_bits, &temp_value); + if (res != FR_OK) { + return res; + } + // Convert to signed value if needed + if (temp_value & (1 << (self->header.glyph_bbox_xy_bits - 1))) { + *bbox_y = temp_value - (1 << self->header.glyph_bbox_xy_bits); + } else { + *bbox_y = temp_value; + } + + // Read bbox_w + res = read_bits(file, self->header.glyph_bbox_wh_bits, byte_val, remaining_bits, &temp_value); + if (res != FR_OK) { + return res; + } + *bbox_w = temp_value; + + // Read bbox_h + res = read_bits(file, self->header.glyph_bbox_wh_bits, byte_val, remaining_bits, &temp_value); + if (res != FR_OK) { + return res; + } + *bbox_h = temp_value; + + return FR_OK; +} + +static FRESULT read_bits(FIL *file, size_t num_bits, uint8_t *byte_val, uint8_t *remaining_bits, uint32_t *result) { + FRESULT res = FR_OK; + UINT bytes_read; + + uint32_t value = 0; + // Bits will be lost when num_bits > 32. However, this is good for skipping bits. + size_t bits_needed = num_bits; + + while (bits_needed > 0) { + // If no bits remaining, read a new byte + if (*remaining_bits == 0) { + res = f_read(file, byte_val, 1, &bytes_read); + if (res != FR_OK || bytes_read < 1) { + return FR_DISK_ERR; + } + *remaining_bits = 8; + } + + // Calculate how many bits to take from current byte + uint8_t bits_to_take = (*remaining_bits < bits_needed) ? *remaining_bits : bits_needed; + value = (value << bits_to_take) | (*byte_val >> (8 - bits_to_take)); + + // Update state + *remaining_bits -= bits_to_take; + bits_needed -= bits_to_take; + + // Shift byte for next read + *byte_val <<= bits_to_take; + *byte_val &= 0xFF; + } + + if (result != NULL) { + *result = value; + } + return FR_OK; +} diff --git a/shared-module/lvfontio/OnDiskFont.h b/shared-module/lvfontio/OnDiskFont.h new file mode 100644 index 00000000000..db68126e9f4 --- /dev/null +++ b/shared-module/lvfontio/OnDiskFont.h @@ -0,0 +1,75 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" +#include "shared-module/displayio/Bitmap.h" + +#include "lib/oofatfs/ff.h" + +#define LVFONTIO_INVALID_CODEPOINT 0xFFFFFFFF + +// LV Font header information +typedef struct { + // Font size and metrics + uint16_t font_size; + uint16_t ascent; + uint16_t default_advance_width; + + // Encoding formats + uint8_t index_to_loc_format; + uint8_t bits_per_pixel; + uint8_t glyph_bbox_xy_bits; + uint8_t glyph_bbox_wh_bits; + uint8_t glyph_advance_bits; + + // Calculated values + uint8_t glyph_header_bits; + uint8_t glyph_header_bytes; +} lvfontio_header_t; + +// Mapping of codepoint ranges to glyph IDs +typedef struct { + uint32_t range_start; // Start of codepoint range + uint32_t range_end; // End of codepoint range (exclusive) + uint16_t glyph_offset; // Offset to apply to codepoint + uint8_t format_type; // Format type: 0=sparse mapping, 2=range to range, 3=direct mapping + uint16_t entries_count; // Number of entries in sparse data + uint32_t data_offset; // File offset to the cmap data +} lvfontio_cmap_range_t; + +typedef struct { + mp_obj_base_t base; + // Bitmap containing cached glyphs + displayio_bitmap_t *bitmap; + // Source of font file path (either a const char* or a copied string) + const char *file_path; + // Array mapping glyph indices to codepoints + uint32_t *codepoints; + // Array of reference counts for each glyph slot + uint16_t *reference_counts; // Use uint16_t to handle higher reference counts + // Maximum number of glyphs to cache at once + uint16_t max_glyphs; + // Flag indicating whether to use m_malloc (true) or port_malloc (false) + bool use_gc_allocator; + uint8_t half_width_px; + + FIL file; + bool file_is_open; + + // Font metrics information loaded from file + lvfontio_header_t header; + + // CMAP information + lvfontio_cmap_range_t *cmap_ranges; + uint16_t cmap_range_count; + + // Offsets for tables in the file + uint32_t loca_table_offset; + uint32_t glyf_table_offset; + uint32_t max_cid; +} lvfontio_ondiskfont_t; diff --git a/shared-module/lvfontio/__init__.c b/shared-module/lvfontio/__init__.c new file mode 100644 index 00000000000..d0eee6d0a52 --- /dev/null +++ b/shared-module/lvfontio/__init__.c @@ -0,0 +1,5 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2024 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT diff --git a/shared-module/max3421e/Max3421E.c b/shared-module/max3421e/Max3421E.c index 4946e4e7d8d..3448cdd4c75 100644 --- a/shared-module/max3421e/Max3421E.c +++ b/shared-module/max3421e/Max3421E.c @@ -83,7 +83,7 @@ void common_hal_max3421e_max3421e_deinit(max3421e_max3421e_obj_t *self) { // anyway. Don't run background tasks because this function is used by // tuh_task() which is run as a background task. #if CFG_TUSB_OS == OPT_OS_NONE -void osal_task_delay(uint32_t msec) { +void tusb_time_delay_ms_api(uint32_t msec) { uint32_t end_time = common_hal_time_monotonic_ms() + msec; while (common_hal_time_monotonic_ms() < end_time) { if (tuh_callback.prev != NULL) { diff --git a/shared-module/msgpack/__init__.c b/shared-module/msgpack/__init__.c index a98fb02de39..7c3e664bb6c 100644 --- a/shared-module/msgpack/__init__.c +++ b/shared-module/msgpack/__init__.c @@ -394,7 +394,9 @@ static mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list) { size_t len = code & 0b1111; mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(len)); for (size_t i = 0; i < len; i++) { - mp_obj_dict_store(d, unpack(s, ext_hook, use_list), unpack(s, ext_hook, use_list)); + mp_obj_t key = unpack(s, ext_hook, use_list); + mp_obj_t value = unpack(s, ext_hook, use_list); + mp_obj_dict_store(d, key, value); } return MP_OBJ_FROM_PTR(d); } @@ -462,7 +464,9 @@ static mp_obj_t unpack(msgpack_stream_t *s, mp_obj_t ext_hook, bool use_list) { size_t len = read_size(s, code - 0xde + 1); mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(len)); for (size_t i = 0; i < len; i++) { - mp_obj_dict_store(d, unpack(s, ext_hook, use_list), unpack(s, ext_hook, use_list)); + mp_obj_t key = unpack(s, ext_hook, use_list); + mp_obj_t value = unpack(s, ext_hook, use_list); + mp_obj_dict_store(d, key, value); } return MP_OBJ_FROM_PTR(d); } diff --git a/shared-module/os/__init__.c b/shared-module/os/__init__.c index 81296db854c..2090dcbcdc4 100644 --- a/shared-module/os/__init__.c +++ b/shared-module/os/__init__.c @@ -6,6 +6,7 @@ // // SPDX-License-Identifier: MIT +#include #include #include "extmod/vfs.h" @@ -16,8 +17,12 @@ #include "py/runtime.h" #include "shared-bindings/os/__init__.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" +#endif + // This provides all VFS related OS functions so that ports can share the code -// as needed. It does not provide uname. +// as needed. // Version of mp_vfs_lookup_path that takes and returns uPy string objects. static mp_vfs_mount_t *lookup_path(const char *path, mp_obj_t *path_out) { @@ -63,9 +68,86 @@ static mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_ return mp_call_method_n_kw(n_args, 0, meth); } +const char *common_hal_os_path_abspath(const char *path) { + const char *cwd; + if (path[0] == '/') { + cwd = ""; + } else { + cwd = MP_STATE_VM(cwd_path); + if (cwd == NULL) { + char *new_cwd = m_malloc_without_collect(2); + strcpy(new_cwd, "/"); + MP_STATE_VM(cwd_path) = new_cwd; + cwd = new_cwd; + } + } + + // Store the current output length for previous components so we can rewind to before them. + char *full_path = m_malloc_without_collect(strlen(cwd) + strlen(path) + 2); + size_t full_path_len = 0; + memcpy(full_path, cwd, strlen(cwd)); + full_path_len += strlen(cwd); + if (full_path_len > 0 && full_path[full_path_len - 1] != '/') { + full_path[full_path_len++] = '/'; + } + memcpy(full_path + full_path_len, path, strlen(path) + 1); + + // Scan to see if the path has any `..` in it and return the same string if it doesn't + bool found_dot_dot = false; + size_t slash_count = 0; + for (size_t i = 0; i < strlen(full_path); i++) { + if (full_path[i] == '/') { + slash_count++; + } + if (i + 2 < strlen(full_path) && full_path[i] == '/' && full_path[i + 1] == '.' && full_path[i + 2] == '.' && (i + 3 == strlen(full_path) || full_path[i + 3] == '/')) { + found_dot_dot = true; + } + } + if (!found_dot_dot) { + return full_path; + } + + size_t slashes[slash_count]; + size_t output_len = 0; + size_t component_len = 0; + slash_count = 0; + + // Remove `..` and `.` + size_t original_len = strlen(full_path); + for (size_t i = 0; i <= original_len; i++) { + full_path[output_len++] = full_path[i]; + // Treat the final nul character as a slash. + if (full_path[i] == '/' || full_path[i] == '\0') { + if (component_len == 1 && full_path[i - 1] == '.') { + // Remove the dot + output_len = slashes[slash_count - 1]; + } else if (component_len == 2 && full_path[i - 1] == '.' && full_path[i - 2] == '.') { + // Remove the double dot and the previous component if it exists. + // Never rewind past the root: if the root is the only recorded + // boundary (slash_count == 1), ".." at the root is a no-op instead of + // underflowing slash_count to SIZE_MAX and reading slashes[SIZE_MAX] + // out of bounds (matches POSIX "cd .. from / stays at /" semantics). + if (slash_count > 1) { + slash_count--; + } + output_len = slashes[slash_count - 1]; + } else { + slashes[slash_count] = output_len; + slash_count++; + } + component_len = 0; + } else { + component_len++; + } + } + full_path[output_len] = '\0'; + return full_path; +} + void common_hal_os_chdir(const char *path) { + MP_STATE_VM(cwd_path) = common_hal_os_path_abspath(path); mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_dir_path(MP_STATE_VM(cwd_path), &path_out); MP_STATE_VM(vfs_cur) = vfs; if (vfs == MP_VFS_ROOT) { // If we change to the root dir and a VFS is mounted at the root then @@ -84,27 +166,30 @@ void common_hal_os_chdir(const char *path) { } mp_obj_t common_hal_os_getcwd(void) { - return mp_vfs_getcwd(); + const char *cwd = MP_STATE_VM(cwd_path); + if (cwd == NULL) { + return MP_OBJ_NEW_QSTR(MP_QSTR__slash_); + } + return mp_obj_new_str_of_type(&mp_type_str, (const byte *)cwd, strlen(cwd)); } mp_obj_t common_hal_os_listdir(const char *path) { + const char *abspath = common_hal_os_path_abspath(path); mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); - - mp_vfs_ilistdir_it_t iter; - mp_obj_t iter_obj = MP_OBJ_FROM_PTR(&iter); - + mp_vfs_mount_t *vfs = lookup_dir_path(abspath, &path_out); if (vfs == MP_VFS_ROOT) { - // list the root directory - iter.base.type = &mp_type_polymorph_iter; - iter.iternext = mp_vfs_ilistdir_it_iternext; - iter.cur.vfs = MP_STATE_VM(vfs_mount_table); - iter.is_str = true; - iter.is_iter = false; - } else { - iter_obj = mp_vfs_proxy_call(vfs, MP_QSTR_ilistdir, 1, &path_out); + vfs = MP_STATE_VM(vfs_mount_table); + while (vfs != NULL) { + if (vfs->len == 1) { + break; + } + vfs = vfs->next; + } + path_out = MP_OBJ_NEW_QSTR(MP_QSTR__slash_); } + mp_obj_t iter_obj = mp_vfs_proxy_call(vfs, MP_QSTR_ilistdir, 1, &path_out); + mp_obj_t dir_list = mp_obj_new_list(0, NULL); mp_obj_t next; while ((next = mp_iternext(iter_obj)) != MP_OBJ_STOP_ITERATION) { @@ -116,8 +201,9 @@ mp_obj_t common_hal_os_listdir(const char *path) { } void common_hal_os_mkdir(const char *path) { + const char *abspath = common_hal_os_path_abspath(path); mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_dir_path(abspath, &path_out); if (vfs == MP_VFS_ROOT || (vfs != MP_VFS_NONE && !strcmp(mp_obj_str_get_str(path_out), "/"))) { mp_raise_OSError(MP_EEXIST); } @@ -125,8 +211,9 @@ void common_hal_os_mkdir(const char *path) { } void common_hal_os_remove(const char *path) { + const char *abspath = common_hal_os_path_abspath(path); mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_path(abspath, &path_out); mp_vfs_proxy_call(vfs, MP_QSTR_remove, 1, &path_out); } @@ -142,14 +229,16 @@ void common_hal_os_rename(const char *old_path, const char *new_path) { } void common_hal_os_rmdir(const char *path) { + const char *abspath = common_hal_os_path_abspath(path); mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_dir_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_dir_path(abspath, &path_out); mp_vfs_proxy_call(vfs, MP_QSTR_rmdir, 1, &path_out); } mp_obj_t common_hal_os_stat(const char *path) { + const char *abspath = common_hal_os_path_abspath(path); mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_path(abspath, &path_out); if (vfs == MP_VFS_ROOT) { mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(10, NULL)); t->items[0] = MP_OBJ_NEW_SMALL_INT(MP_S_IFDIR); // st_mode @@ -162,8 +251,9 @@ mp_obj_t common_hal_os_stat(const char *path) { } mp_obj_t common_hal_os_statvfs(const char *path) { + const char *abspath = common_hal_os_path_abspath(path); mp_obj_t path_out; - mp_vfs_mount_t *vfs = lookup_path(path, &path_out); + mp_vfs_mount_t *vfs = lookup_path(abspath, &path_out); if (vfs == MP_VFS_ROOT) { // statvfs called on the root directory, see if there's anything mounted there for (vfs = MP_STATE_VM(vfs_mount_table); vfs != NULL; vfs = vfs->next) { @@ -194,8 +284,24 @@ mp_obj_t common_hal_os_statvfs(const char *path) { } void common_hal_os_utime(const char *path, mp_obj_t times) { + const char *abspath = common_hal_os_path_abspath(path); mp_obj_t args[2]; - mp_vfs_mount_t *vfs = lookup_path(path, &args[0]); + mp_vfs_mount_t *vfs = lookup_path(abspath, &args[0]); args[1] = times; mp_vfs_proxy_call(vfs, MP_QSTR_utime, 2, args); } + +#if CIRCUITPY_SETTINGS_TOML +mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_) { + vstr_t vstr; + vstr_init(&vstr, 64); + + settings_err_t result = settings_get_raw_vstr(key, &vstr); + if (result == SETTINGS_OK) { + return mp_obj_new_str_from_vstr(&vstr); + } + return default_; +} +#endif + +MP_REGISTER_ROOT_POINTER(const char *cwd_path); diff --git a/shared-module/os/__init__.h b/shared-module/os/__init__.h index be9c077b200..830f7629509 100644 --- a/shared-module/os/__init__.h +++ b/shared-module/os/__init__.h @@ -6,23 +6,5 @@ #pragma once -typedef enum { - GETENV_OK = 0, - GETENV_ERR_OPEN, - GETENV_ERR_UNICODE, - GETENV_ERR_LENGTH, - GETENV_ERR_NOT_FOUND, - GETENV_ERR_UNEXPECTED = 0xff00, // logical or'd with the byte value -} os_getenv_err_t; - -// Allocation free version that returns the full length of the value. -// If it fits, the return value is 0-terminated. The passed in buffer -// may be modified even if an error is returned. Allocation free. -// An error that is not 'open' or 'not found' is printed on the repl. -os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len); - -// Returns GETENV_OK and sets value to the read value. Returns -// GETENV_ERR_... if the value was not numeric. allocation-free. -// If any error code is returned, value is guaranteed not modified -// An error that is not 'open' or 'not found' is printed on the repl. -os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value); +// Not made available to the VM but used by other modules to normalize paths. +const char *common_hal_os_path_abspath(const char *path); diff --git a/shared-module/os/getenv.c b/shared-module/os/getenv.c deleted file mode 100644 index 39c3b4cee4a..00000000000 --- a/shared-module/os/getenv.c +++ /dev/null @@ -1,414 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries -// -// SPDX-License-Identifier: MIT - -// These functions are separate from __init__.c so that os.getenv() can be -// tested in the unix "coverage" build, without bringing in "our" os module - -#include -#include -#include - -#include "shared-bindings/os/__init__.h" -#include "shared-module/os/__init__.h" - -#include "py/gc.h" -#include "py/misc.h" -#include "py/mpstate.h" -#include "py/mpprint.h" -#include "py/objstr.h" -#include "py/parsenum.h" -#include "py/runtime.h" -#include "supervisor/filesystem.h" - -#define GETENV_PATH "/settings.toml" - -#include "extmod/vfs.h" -#include "extmod/vfs_fat.h" -typedef FIL file_arg; -static bool open_file(const char *name, file_arg *active_file) { - #if defined(UNIX) - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_obj_t file_obj = mp_call_function_2(MP_OBJ_FROM_PTR(&mp_builtin_open_obj), mp_obj_new_str(name, strlen(name)), MP_ROM_QSTR(MP_QSTR_rb)); - mp_arg_validate_type(file_obj, &mp_type_vfs_fat_fileio, MP_QSTR_file); - pyb_file_obj_t *file = MP_OBJ_TO_PTR(file_obj); - *active_file = file->fp; - nlr_pop(); - return true; - } else { - return false; - } - #else - fs_user_mount_t *fs_mount = filesystem_circuitpy(); - if (fs_mount == NULL) { - return false; - } - FATFS *fatfs = &fs_mount->fatfs; - FRESULT result = f_open(fatfs, active_file, name, FA_READ); - return result == FR_OK; - #endif -} -static void close_file(file_arg *active_file) { - // nothing -} -static bool is_eof(file_arg *active_file) { - return f_eof(active_file) || f_error(active_file); -} - -// Return 0 if there is no next character (EOF). -static uint8_t get_next_byte(FIL *active_file) { - uint8_t character = 0; - UINT quantity_read; - // If there's an error or quantity_read is 0, character will remain 0. - f_read(active_file, &character, 1, &quantity_read); - return character; -} -static void seek_eof(file_arg *active_file) { - f_lseek(active_file, f_size(active_file)); -} - -// For a fixed buffer, record the required size rather than throwing -static void vstr_add_byte_nonstd(vstr_t *vstr, byte b) { - if (!vstr->fixed_buf || vstr->alloc > vstr->len) { - vstr_add_byte(vstr, b); - } else { - vstr->len++; - } -} - -// For a fixed buffer, record the required size rather than throwing -static void vstr_add_char_nonstd(vstr_t *vstr, unichar c) { - size_t ulen = - (c < 0x80) ? 1 : - (c < 0x800) ? 2 : - (c < 0x10000) ? 3 : 4; - if (!vstr->fixed_buf || vstr->alloc > vstr->len + ulen) { - vstr_add_char(vstr, c); - } else { - vstr->len += ulen; - } -} - -static void next_line(file_arg *active_file) { - uint8_t character; - do { - character = get_next_byte(active_file); - } while (character != 0 && character != '\n'); -} - -// Discard whitespace, except for newlines, returning the next character after the whitespace. -// Return 0 if there is no next character (EOF). -static uint8_t consume_whitespace(file_arg *active_file) { - uint8_t character; - do { - character = get_next_byte(active_file); - } while (character != '\n' && character != 0 && unichar_isspace(character)); - return character; -} - -// Starting at the start of a new line, determines if the key matches the given -// key. -// -// If result is true, the key matches and file pointer is pointing just after the "=". -// If the result is false, the key does NOT match and the file pointer is -// pointing at the start of the next line, if any -static bool key_matches(file_arg *active_file, const char *key) { - uint8_t character; - character = consume_whitespace(active_file); - if (character == '[' || character == 0) { - seek_eof(active_file); - return false; - } - while (*key) { - if (character != *key++) { - // A character didn't match the key, so it's not a match - // If the non-matching char was not the end of the line, - // then consume the rest of the line - if (character != '\n') { - next_line(active_file); - } - return false; - } - character = get_next_byte(active_file); - } - // the next character could be whitespace; consume if necessary - if (unichar_isspace(character)) { - character = consume_whitespace(active_file); - } - // If we're not looking at the "=" then the key didn't match - if (character != '=') { - // A character didn't match the key, so it's not a match - // If the non-matching char was not the end of the line, - // then consume the rest of the line - if (character != '\n') { - next_line(active_file); - } - return false; - } - return true; -} - -static os_getenv_err_t read_unicode_escape(file_arg *active_file, int sz, vstr_t *buf) { - char hex_buf[sz + 1]; - for (int i = 0; i < sz; i++) { - hex_buf[i] = get_next_byte(active_file); - } - hex_buf[sz] = 0; - char *end; - unsigned long c = strtoul(hex_buf, &end, 16); - if (end != &hex_buf[sz]) { - return GETENV_ERR_UNEXPECTED | *end; - } - if (c >= 0x110000) { - return GETENV_ERR_UNICODE; - } - vstr_add_char_nonstd(buf, c); - return GETENV_OK; -} - -// Read a quoted string -static os_getenv_err_t read_string_value(file_arg *active_file, vstr_t *buf) { - while (true) { - int character = get_next_byte(active_file); - switch (character) { - case 0: - case '\n': - return GETENV_ERR_UNEXPECTED | character; - - case '"': - character = consume_whitespace(active_file); - switch (character) { - case '#': - next_line(active_file); - MP_FALLTHROUGH; - case 0: - case '\n': - return GETENV_OK; - default: - return GETENV_ERR_UNEXPECTED | character; - } - - case '\\': - character = get_next_byte(active_file); - switch (character) { - case 0: - case '\n': - return GETENV_ERR_UNEXPECTED | character; - case 'b': - character = '\b'; - break; - case 'r': - character = '\r'; - break; - case 'n': - character = '\n'; - break; - case 't': - character = '\t'; - break; - case 'v': - character = '\v'; - break; - case 'f': - character = '\f'; - break; - case 'U': - case 'u': { - int sz = (character == 'u') ? 4 : 8; - os_getenv_err_t res; - res = read_unicode_escape(active_file, sz, buf); - if (res != GETENV_OK) { - return res; - } - continue; - } - // default falls through, other escaped characters - // represent themselves - } - MP_FALLTHROUGH; - default: - vstr_add_byte_nonstd(buf, character); - } - } -} - -// Read a numeric value (non-quoted value) as a string -static os_getenv_err_t read_bare_value(file_arg *active_file, vstr_t *buf, int first_character) { - int character = first_character; - while (true) { - switch (character) { - case 0: - case '\n': - return GETENV_OK; - case '#': - next_line(active_file); - return GETENV_OK; - default: - vstr_add_byte_nonstd(buf, character); - } - character = get_next_byte(active_file); - } -} - -static mp_int_t read_value(file_arg *active_file, vstr_t *buf, bool *quoted) { - uint8_t character; - character = consume_whitespace(active_file); - *quoted = (character == '"'); - - if (*quoted) { - return read_string_value(active_file, buf); - } else { - return read_bare_value(active_file, buf, character); - } -} - -static os_getenv_err_t os_getenv_vstr(const char *path, const char *key, vstr_t *buf, bool *quoted) { - file_arg active_file; - if (!open_file(path, &active_file)) { - return GETENV_ERR_OPEN; - } - - os_getenv_err_t result = GETENV_ERR_NOT_FOUND; - while (!is_eof(&active_file)) { - if (key_matches(&active_file, key)) { - result = read_value(&active_file, buf, quoted); - break; - } - } - close_file(&active_file); - return result; -} - -static os_getenv_err_t os_getenv_buf_terminated(const char *key, char *value, size_t value_len, bool *quoted) { - vstr_t buf; - vstr_init_fixed_buf(&buf, value_len, value); - os_getenv_err_t result = os_getenv_vstr(GETENV_PATH, key, &buf, quoted); - - if (result == GETENV_OK) { - vstr_add_byte_nonstd(&buf, 0); - memcpy(value, buf.buf, MIN(buf.len, value_len)); - if (buf.len > value_len) { // this length includes trailing NUL - result = GETENV_ERR_LENGTH; - } - } - return result; -} - -static void print_dont_raise(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...) { - va_list argptr; - va_start(argptr, fmt); - mp_vcprintf(&mp_plat_print, fmt, argptr); - mp_printf(&mp_plat_print, "\n"); - va_end(argptr); -} - -static void handle_getenv_error(os_getenv_err_t error, void (*handle)(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...)) { - if (error == GETENV_OK) { - return; - } - if (error & GETENV_ERR_UNEXPECTED) { - byte character = (error & 0xff); - char buf[8]; - vstr_t vstr; - vstr_init_fixed_buf(&vstr, sizeof(buf), buf); - mp_print_t print = { .data = &vstr, .print_strn = (mp_print_strn_t)vstr_add_strn }; - - if (character) { - mp_str_print_quoted(&print, &character, 1, true); - } else { - mp_str_print_quoted(&print, (byte *)"EOF", 3, true); - } - handle(&mp_type_ValueError, MP_ERROR_TEXT("Invalid byte %.*s"), vstr.len, vstr.buf); - } else { - switch (error) { - case GETENV_ERR_OPEN: - handle(&mp_type_ValueError, MP_ERROR_TEXT("%S"), MP_ERROR_TEXT("File not found")); - break; - case GETENV_ERR_UNICODE: - handle(&mp_type_ValueError, MP_ERROR_TEXT("%S"), MP_ERROR_TEXT("Invalid unicode escape")); - break; - case GETENV_ERR_NOT_FOUND: - handle(&mp_type_ValueError, MP_ERROR_TEXT("%S"), MP_ERROR_TEXT("Key not found")); - break; - default: - handle(&mp_type_RuntimeError, MP_ERROR_TEXT("%S"), MP_ERROR_TEXT("Internal error")); - break; - } - } -} - -static void common_hal_os_getenv_showerr(const char *key, os_getenv_err_t result) { - if (result != GETENV_OK && result != GETENV_ERR_OPEN && result != GETENV_ERR_NOT_FOUND) { - mp_cprintf(&mp_plat_print, MP_ERROR_TEXT("An error occurred while retrieving '%s':\n"), key); - handle_getenv_error(result, print_dont_raise); - } -} - -static -os_getenv_err_t common_hal_os_getenv_str_inner(const char *key, char *value, size_t value_len) { - bool quoted; - os_getenv_err_t result = os_getenv_buf_terminated(key, value, value_len, "ed); - if (result == GETENV_OK && !quoted) { - result = GETENV_ERR_UNEXPECTED | value[0]; - } - return result; -} - -os_getenv_err_t common_hal_os_getenv_str(const char *key, char *value, size_t value_len) { - os_getenv_err_t result = common_hal_os_getenv_str_inner(key, value, value_len); - common_hal_os_getenv_showerr(key, result); - return result; -} - -mp_obj_t common_hal_os_getenv_path(const char *path, const char *key, mp_obj_t default_) { - vstr_t buf; - bool quoted; - - vstr_init(&buf, 64); - os_getenv_err_t result = os_getenv_vstr(path, key, &buf, "ed); - if (result == GETENV_ERR_NOT_FOUND || result == GETENV_ERR_OPEN) { - return default_; - } - handle_getenv_error(result, mp_raise_msg_varg); - - if (quoted) { - return mp_obj_new_str_from_vstr(&buf); - } else { - return mp_parse_num_integer(buf.buf, buf.len, 0, NULL); - } -} - -mp_obj_t common_hal_os_getenv(const char *key, mp_obj_t default_) { - return common_hal_os_getenv_path(GETENV_PATH, key, default_); -} - -static os_getenv_err_t common_hal_os_getenv_int_inner(const char *key, mp_int_t *value) { - char buf[16]; - bool quoted; - os_getenv_err_t result = os_getenv_buf_terminated(key, buf, sizeof(buf), "ed); - if (result != GETENV_OK) { - return result; - } - if (quoted) { - return GETENV_ERR_UNEXPECTED | '"'; - } - char *end; - long num = strtol(buf, &end, 0); - while (unichar_isspace(*end)) { - end++; - } - if (end == buf || *end) { // If the whole buffer was not consumed it's an error - return GETENV_ERR_UNEXPECTED | *end; - } - *value = (mp_int_t)num; - return GETENV_OK; -} - -os_getenv_err_t common_hal_os_getenv_int(const char *key, mp_int_t *value) { - os_getenv_err_t result = common_hal_os_getenv_int_inner(key, value); - common_hal_os_getenv_showerr(key, result); - return result; -} diff --git a/shared-module/sdcardio/SDCard.c b/shared-module/sdcardio/SDCard.c index a8e6248577a..40d09aa99ca 100644 --- a/shared-module/sdcardio/SDCard.c +++ b/shared-module/sdcardio/SDCard.c @@ -7,15 +7,18 @@ // This implementation largely follows the structure of adafruit_sdcard.py #include "extmod/vfs.h" - #include "shared-bindings/busio/SPI.h" #include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/sdcardio/SDCard.h" #include "shared-bindings/time/__init__.h" #include "shared-bindings/util.h" #include "shared-module/sdcardio/SDCard.h" +#include "supervisor/shared/tick.h" #include "py/mperrno.h" +#include "py/mphal.h" +#include "py/gc.h" +#include "supervisor/port.h" #if 0 #define DEBUG_PRINT(...) ((void)mp_printf(&mp_plat_print,##__VA_ARGS__)) @@ -23,7 +26,17 @@ #define DEBUG_PRINT(...) ((void)0) #endif -#define CMD_TIMEOUT (200) +// https://nodeloop.org/guides/sd-card-spi-init-guide/ is an excellent source of info for SPI card use. + +// https://www.taterli.com/wp-content/uploads/2017/05/Physical-Layer-Simplified-SpecificationV6.0.pdf +// specifies timeouts for read (100 ms), write (250 ms), erase (depends on size), and other operations. +// cmd timeout was 250, but did not work on some cards. +// See https://github.com/adafruit/circuitpython/issues/10954 +#define CMD_TIMEOUT_MS (500) +#define SPI_TIMEOUT_MS (250) +// Init ready timeout. +#define READY_TIMEOUT_MS (300) + #define R1_IDLE_STATE (1 << 0) #define R1_ILLEGAL_COMMAND (1 << 2) @@ -32,20 +45,42 @@ #define TOKEN_STOP_TRAN (0xFD) #define TOKEN_DATA (0xFE) +bool common_hal_sdcardio_sdcard_deinited(sdcardio_sdcard_obj_t *self) { + // Also check SPI bus was deinited out from under us. + if (!self->bus || common_hal_busio_spi_deinited(self->bus)) { + return true; + } + return false; +} + +void common_hal_sdcardio_sdcard_mark_deinit(sdcardio_sdcard_obj_t *self) { + self->bus = NULL; +} + static void common_hal_sdcardio_check_for_deinit(sdcardio_sdcard_obj_t *self) { - if (!self->bus) { + if (common_hal_sdcardio_sdcard_deinited(self)) { raise_deinited_error(); } } static bool lock_and_configure_bus(sdcardio_sdcard_obj_t *self) { - common_hal_sdcardio_check_for_deinit(self); + if (common_hal_sdcardio_sdcard_deinited(self)) { + return false; + } + + if (!common_hal_busio_spi_wait_for_lock(self->bus, SPI_TIMEOUT_MS)) { + return false; + } - if (!common_hal_busio_spi_try_lock(self->bus)) { + // Make sure we can still use the SPI bus after grabbing the lock. + // The VM might be in the process of shutting down, and there could be a race. + if (!vm_is_running() && !self->persistent_mount) { + common_hal_busio_spi_unlock(self->bus); return false; } + common_hal_busio_spi_configure(self->bus, self->baudrate, 0, 0, 8); - common_hal_digitalio_digitalinout_set_value(&self->cs, false); + digitalinout_protocol_set_value(self->cs, false); return true; } @@ -56,11 +91,10 @@ static void lock_bus_or_throw(sdcardio_sdcard_obj_t *self) { } static void clock_card(sdcardio_sdcard_obj_t *self, int bytes) { - uint8_t buf[] = {0xff}; - common_hal_digitalio_digitalinout_set_value(&self->cs, true); - for (int i = 0; i < bytes; i++) { - common_hal_busio_spi_write(self->bus, buf, 1); - } + uint8_t buf[bytes]; + memset(buf, 0xff, bytes); + digitalinout_protocol_set_value(self->cs, true); + common_hal_busio_spi_write(self->bus, buf, bytes); } static void extraclock_and_unlock_bus(sdcardio_sdcard_obj_t *self) { @@ -83,21 +117,35 @@ static uint8_t CRC7(const uint8_t *data, uint8_t n) { return (crc << 1) | 1; } -#define READY_TIMEOUT_NS (300 * 1000 * 1000) // 300ms -static int wait_for_ready(sdcardio_sdcard_obj_t *self) { - uint64_t deadline = common_hal_time_monotonic_ns() + READY_TIMEOUT_NS; - while (common_hal_time_monotonic_ns() < deadline) { +// Assumes that the spi lock has been acquired. +// +// Mask the incoming value with mask. Use 0xff to not mask. +// if not_match is true, wait for something NOT matching the value. +// Return the response as an int32_t (which is always >= 0), or -1 if timed out. +static int32_t wait_for_masked_response(sdcardio_sdcard_obj_t *self, uint8_t mask, uint8_t response, bool not_match, uint32_t timeout_ms) { + uint64_t deadline = supervisor_ticks_ms64() + timeout_ms; + while (supervisor_ticks_ms64() < deadline) { uint8_t b; common_hal_busio_spi_read(self->bus, &b, 1, 0xff); - if (b == 0xff) { - return 0; + if (((b & mask) == response) ^ not_match) { + return b; } } - return -ETIMEDOUT; + return -1; +} + +// Wait for the given response byte. +static bool wait_for_response(sdcardio_sdcard_obj_t *self, uint8_t response) { + return wait_for_masked_response(self, 0xff, response, false, CMD_TIMEOUT_MS) != -1; +} + +// Wait for 0xff, with a specific timeout. +static bool wait_for_ready(sdcardio_sdcard_obj_t *self) { + return wait_for_masked_response(self, 0xff, 0xff, false, READY_TIMEOUT_MS) != -1; } // Note: this is never called while "in cmd25" (in fact, it's only used by `exit_cmd25`) -static bool cmd_nodata(sdcardio_sdcard_obj_t *self, int cmd, int response) { +static mp_negative_errno_t cmd_nodata(sdcardio_sdcard_obj_t *self, int cmd, int response) { uint8_t cmdbuf[2] = {cmd, 0xff}; assert(!self->in_cmd25); @@ -105,17 +153,14 @@ static bool cmd_nodata(sdcardio_sdcard_obj_t *self, int cmd, int response) { common_hal_busio_spi_write(self->bus, cmdbuf, sizeof(cmdbuf)); // Wait for the response (response[7] == response) - for (int i = 0; i < CMD_TIMEOUT; i++) { - common_hal_busio_spi_read(self->bus, cmdbuf, 1, 0xff); - if (cmdbuf[0] == response) { - return 0; - } + if (wait_for_response(self, response)) { + return 0; } - return -EIO; + return -MP_EIO; } -static int exit_cmd25(sdcardio_sdcard_obj_t *self) { +static mp_negative_errno_t exit_cmd25(sdcardio_sdcard_obj_t *self) { if (self->in_cmd25) { DEBUG_PRINT("exit cmd25\n"); self->in_cmd25 = false; @@ -126,7 +171,7 @@ static int exit_cmd25(sdcardio_sdcard_obj_t *self) { // In Python API, defaults are response=None, data_block=True, wait=True static int cmd(sdcardio_sdcard_obj_t *self, int cmd, int arg, void *response_buf, size_t response_len, bool data_block, bool wait) { - int r = exit_cmd25(self); + mp_negative_errno_t r = exit_cmd25(self); if (r < 0) { return r; } @@ -141,48 +186,43 @@ static int cmd(sdcardio_sdcard_obj_t *self, int cmd, int arg, void *response_buf cmdbuf[5] = CRC7(cmdbuf, 5); if (wait) { - r = wait_for_ready(self); - if (r < 0) { - return r; + if (!wait_for_ready(self)) { + return -MP_ETIMEDOUT; } } common_hal_busio_spi_write(self->bus, cmdbuf, sizeof(cmdbuf)); // Wait for the response (response[7] == 0) - bool response_received = false; - for (int i = 0; i < CMD_TIMEOUT; i++) { - common_hal_busio_spi_read(self->bus, cmdbuf, 1, 0xff); - if ((cmdbuf[0] & 0x80) == 0) { - response_received = true; - break; - } - } - - if (!response_received) { - return -EIO; + // Now wait for cmd response, which is the high bit being 0. + int32_t response = wait_for_masked_response(self, 0x80, 0, false, CMD_TIMEOUT_MS); + if (response == -1) { + return -MP_EIO; } if (response_buf) { if (data_block) { cmdbuf[1] = 0xff; - do { - // Wait for the start block byte - common_hal_busio_spi_read(self->bus, cmdbuf + 1, 1, 0xff); - } while (cmdbuf[1] != 0xfe); + if (!wait_for_response(self, 0xfe)) { + return -MP_EIO; + } } - common_hal_busio_spi_read(self->bus, response_buf, response_len, 0xff); + if (!common_hal_busio_spi_read(self->bus, response_buf, response_len, 0xff)) { + return -MP_EIO; + } if (data_block) { // Read and discard the CRC-CCITT checksum - common_hal_busio_spi_read(self->bus, cmdbuf + 1, 2, 0xff); + if (!common_hal_busio_spi_read(self->bus, cmdbuf + 1, 2, 0xff)) { + return -MP_EIO; + } } } - return cmdbuf[0]; + return response; } static int block_cmd(sdcardio_sdcard_obj_t *self, int cmd_, int block, void *response_buf, size_t response_len, bool data_block, bool wait) { @@ -190,7 +230,8 @@ static int block_cmd(sdcardio_sdcard_obj_t *self, int cmd_, int block, void *res } static mp_rom_error_text_t init_card_v1(sdcardio_sdcard_obj_t *self) { - for (int i = 0; i < CMD_TIMEOUT; i++) { + uint64_t deadline = supervisor_ticks_ms64() + CMD_TIMEOUT_MS; + while (supervisor_ticks_ms64() < deadline) { if (cmd(self, 41, 0, NULL, 0, true, true) == 0) { return NULL; } @@ -199,7 +240,8 @@ static mp_rom_error_text_t init_card_v1(sdcardio_sdcard_obj_t *self) { } static mp_rom_error_text_t init_card_v2(sdcardio_sdcard_obj_t *self) { - for (int i = 0; i < CMD_TIMEOUT; i++) { + uint64_t deadline = supervisor_ticks_ms64() + CMD_TIMEOUT_MS; + while (supervisor_ticks_ms64() < deadline) { uint8_t ocr[4]; common_hal_time_delay_ms(50); cmd(self, 58, 0, ocr, sizeof(ocr), false, true); @@ -216,9 +258,11 @@ static mp_rom_error_text_t init_card_v2(sdcardio_sdcard_obj_t *self) { } static mp_rom_error_text_t init_card(sdcardio_sdcard_obj_t *self) { + // https://nodeloop.org/guides/sd-card-spi-init-guide/ recommends at least 74 bit clocks + // and says 80 bit clocks(10*8) is common. Value below is bytes, not bits. clock_card(self, 10); - common_hal_digitalio_digitalinout_set_value(&self->cs, false); + digitalinout_protocol_set_value(self->cs, false); assert(!self->in_cmd25); self->in_cmd25 = false; // should be false already @@ -294,13 +338,20 @@ static mp_rom_error_text_t init_card(sdcardio_sdcard_obj_t *self) { return NULL; } -void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, const mcu_pin_obj_t *cs, int baudrate) { +mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, mp_obj_t cs, int baudrate, bool persistent_mount) { self->bus = bus; - common_hal_digitalio_digitalinout_construct(&self->cs, cs); - common_hal_digitalio_digitalinout_switch_to_output(&self->cs, true, DRIVE_MODE_PUSH_PULL); + self->persistent_mount = persistent_mount; + + // Allocate the pins in the same place as self. + bool use_port_allocation = !gc_alloc_possible() || !gc_ptr_on_heap(self); + + self->cs = digitalinout_protocol_from_pin(cs, MP_QSTR_cs, false, use_port_allocation, &self->own_cs); + digitalinout_protocol_switch_to_output(self->cs, true, DRIVE_MODE_PUSH_PULL); self->cdv = 512; self->sectors = 0; + + // During initialization, talk to the SPI card between 100 khZ and 400 kHz. After that, can use full speed. self->baudrate = 250000; lock_bus_or_throw(self); @@ -308,20 +359,36 @@ void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi extraclock_and_unlock_bus(self); if (result != NULL) { - common_hal_digitalio_digitalinout_deinit(&self->cs); - mp_raise_OSError_msg(result); + if (self->own_cs) { + digitalinout_protocol_deinit(self->cs); + circuitpy_free_obj(self->cs); + } + return result; } self->baudrate = baudrate; + return NULL; +} + + +void common_hal_sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, mp_obj_t cs, int baudrate) { + // User mounted, so persistent_mount=false. + mp_rom_error_text_t result = sdcardio_sdcard_construct(self, bus, cs, baudrate, false); + if (result != NULL) { + mp_raise_OSError_msg(result); + } } void common_hal_sdcardio_sdcard_deinit(sdcardio_sdcard_obj_t *self) { - if (!self->bus) { + if (common_hal_sdcardio_sdcard_deinited(self)) { return; } common_hal_sdcardio_sdcard_sync(self); - self->bus = 0; - common_hal_digitalio_digitalinout_deinit(&self->cs); + common_hal_sdcardio_sdcard_mark_deinit(self); + if (self->own_cs) { + digitalinout_protocol_deinit(self->cs); + circuitpy_free_obj(self->cs); + } } int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self) { @@ -330,23 +397,25 @@ int common_hal_sdcardio_sdcard_get_blockcount(sdcardio_sdcard_obj_t *self) { } static int readinto(sdcardio_sdcard_obj_t *self, void *buf, size_t size) { - uint8_t aux[2] = {0, 0}; - while (aux[0] != 0xfe) { - common_hal_busio_spi_read(self->bus, aux, 1, 0xff); + + if (!wait_for_response(self, 0xfe)) { + return -MP_EIO; } common_hal_busio_spi_read(self->bus, buf, size, 0xff); // Read checksum and throw it away - common_hal_busio_spi_read(self->bus, aux, sizeof(aux), 0xff); + uint8_t checksum[2]; + common_hal_busio_spi_read(self->bus, checksum, sizeof(checksum), 0xff); return 0; } +// The mp_uint_t is misleading; negative errors can be returned. mp_uint_t sdcardio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t start_block, uint32_t nblocks) { // deinit check is in lock_and_configure_bus() sdcardio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); if (!lock_and_configure_bus(self)) { - return MP_EAGAIN; + return -MP_ETIMEDOUT; } int r = 0; size_t buflen = 512 * nblocks; @@ -379,6 +448,7 @@ mp_uint_t sdcardio_sdcard_readblocks(mp_obj_t self_in, uint8_t *buf, uint32_t st } } extraclock_and_unlock_bus(self); + // No caller actually uses this value. return r; } @@ -391,7 +461,9 @@ int common_hal_sdcardio_sdcard_readblocks(sdcardio_sdcard_obj_t *self, uint32_t } static int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t size) { - wait_for_ready(self); + if (!wait_for_ready(self)) { + return -MP_ETIMEDOUT; + } uint8_t cmd[2]; cmd[0] = token; @@ -414,12 +486,12 @@ static int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t // with STATUS 010 indicating "data accepted", and other status bit // combinations indicating failure. // In practice, I was seeing cmd[0] as 0xe5, indicating success - for (int i = 0; i < CMD_TIMEOUT; i++) { + uint64_t deadline = supervisor_ticks_ms64() + CMD_TIMEOUT_MS; + while (supervisor_ticks_ms64() < deadline) { common_hal_busio_spi_read(self->bus, cmd, 1, 0xff); - DEBUG_PRINT("i=%02d cmd[0] = 0x%02x\n", i, cmd[0]); if ((cmd[0] & 0b00010001) == 0b00000001) { if ((cmd[0] & 0x1f) != 0x5) { - return -EIO; + return -MP_EIO; } else { break; } @@ -427,9 +499,11 @@ static int _write(sdcardio_sdcard_obj_t *self, uint8_t token, void *buf, size_t } // Wait for the write to finish - do { - common_hal_busio_spi_read(self->bus, cmd, 1, 0xff); - } while (cmd[0] == 0); + + // Wait for a non-zero value. + if (wait_for_masked_response(self, 0xff /*mask*/, 0, true /*not_match*/, CMD_TIMEOUT_MS) == -1) { + return -MP_EIO; + } // Success return 0; @@ -439,7 +513,7 @@ mp_uint_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t s // deinit check is in lock_and_configure_bus() sdcardio_sdcard_obj_t *self = MP_OBJ_TO_PTR(self_in); if (!lock_and_configure_bus(self)) { - return MP_EAGAIN; + return -MP_ETIMEDOUT; } if (!self->in_cmd25 || start_block != self->next_block) { @@ -471,23 +545,21 @@ mp_uint_t sdcardio_sdcard_writeblocks(mp_obj_t self_in, uint8_t *buf, uint32_t s return 0; } -int common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self) { +mp_negative_errno_t common_hal_sdcardio_sdcard_sync(sdcardio_sdcard_obj_t *self) { // deinit check is in lock_and_configure_bus() - lock_and_configure_bus(self); + if (!lock_and_configure_bus(self)) { + return -MP_ETIMEDOUT; + } int r = exit_cmd25(self); extraclock_and_unlock_bus(self); return r; } -int common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { - // deinit check is in lock_and_configure_bus() +mp_negative_errno_t common_hal_sdcardio_sdcard_writeblocks(sdcardio_sdcard_obj_t *self, uint32_t start_block, mp_buffer_info_t *buf) { if (buf->len % 512 != 0) { mp_raise_ValueError_varg(MP_ERROR_TEXT("Buffer must be a multiple of %d bytes"), 512); } - lock_and_configure_bus(self); - int r = sdcardio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), buf->buf, start_block, buf->len / 512); - extraclock_and_unlock_bus(self); - return r; + return sdcardio_sdcard_writeblocks(MP_OBJ_FROM_PTR(self), buf->buf, start_block, buf->len / 512); } bool sdcardio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value) { @@ -495,11 +567,8 @@ bool sdcardio_sdcard_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *o *out_value = 0; switch (cmd) { case MP_BLOCKDEV_IOCTL_DEINIT: - common_hal_sdcardio_sdcard_sync(self); - break; // TODO properly case MP_BLOCKDEV_IOCTL_SYNC: - common_hal_sdcardio_sdcard_sync(self); - break; + return common_hal_sdcardio_sdcard_sync(self) == 0; case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: *out_value = common_hal_sdcardio_sdcard_get_blockcount(self); break; diff --git a/shared-module/sdcardio/SDCard.h b/shared-module/sdcardio/SDCard.h index 0b315395aad..6af68c274cd 100644 --- a/shared-module/sdcardio/SDCard.h +++ b/shared-module/sdcardio/SDCard.h @@ -17,10 +17,16 @@ typedef struct { mp_obj_base_t base; busio_spi_obj_t *bus; - digitalio_digitalinout_obj_t cs; + mp_obj_t cs; int cdv; int baudrate; uint32_t sectors; uint32_t next_block; bool in_cmd25; + // Automounted SD cards are usually persistent across VM's. Note this as needed to allow access + // when the VM is not running. + bool persistent_mount; + bool own_cs; } sdcardio_sdcard_obj_t; + +mp_rom_error_text_t sdcardio_sdcard_construct(sdcardio_sdcard_obj_t *self, busio_spi_obj_t *bus, mp_obj_t cs, int baudrate, bool persistent_mount); diff --git a/shared-module/sdcardio/__init__.c b/shared-module/sdcardio/__init__.c index 72d32ef2b2c..d53f7a3fabd 100644 --- a/shared-module/sdcardio/__init__.c +++ b/shared-module/sdcardio/__init__.c @@ -3,3 +3,146 @@ // SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC // // SPDX-License-Identifier: MIT + +#include "shared-module/sdcardio/__init__.h" + +#include "py/obj.h" + +#include "extmod/vfs_fat.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/sdcardio/SDCard.h" + +#include "supervisor/filesystem.h" +#include "supervisor/shared/settings.h" + +#ifdef DEFAULT_SD_CARD_DETECT +static digitalio_digitalinout_obj_t sd_card_detect_pin; +static sdcardio_sdcard_obj_t sdcard; + +static mp_vfs_mount_t _sdcard_vfs; +fs_user_mount_t _sdcard_usermount; + +static bool _init_error = false; +static bool _automounted = false; + +#ifdef DEFAULT_SD_MOSI +static busio_spi_obj_t busio_spi_obj; +#else +#include "shared-bindings/board/__init__.h" +#endif +#endif + +void sdcardio_init(void) { + #ifdef DEFAULT_SD_CARD_DETECT + sd_card_detect_pin.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&sd_card_detect_pin, DEFAULT_SD_CARD_DETECT); + common_hal_digitalio_digitalinout_switch_to_input(&sd_card_detect_pin, PULL_UP); + common_hal_digitalio_digitalinout_never_reset(&sd_card_detect_pin); + #endif +} + +void automount_sd_card(void) { + #ifdef DEFAULT_SD_CARD_DETECT + #if CIRCUITPY_SETTINGS_TOML + // Honor the runtime CIRCUITPY_SDCARD_USB setting. When disabled, never + // claim the shared SD pins (SCK/MOSI/MISO/CS) via SPI, so they remain free + // for other uses such as sdioio, which drives the same physical pins. + // Read once and cache, matching usb_msc_flash.c's handling. + static int8_t _sdcard_usb_enabled = -1; // -1 unknown, 0 false, 1 true + if (_sdcard_usb_enabled < 0) { + bool setting = true; + (void)settings_get_bool("CIRCUITPY_SDCARD_USB", &setting); + _sdcard_usb_enabled = setting ? 1 : 0; + } + if (!_sdcard_usb_enabled) { + return; + } + #endif + if (common_hal_digitalio_digitalinout_get_value(&sd_card_detect_pin) != DEFAULT_SD_CARD_INSERTED) { + // No card. + _init_error = false; + if (_automounted) { + // Unmount the card. + mp_vfs_mount_t *cur = MP_STATE_VM(vfs_mount_table); + if (cur == &_sdcard_vfs) { + MP_STATE_VM(vfs_mount_table) = cur->next; + } else { + while (cur->next != &_sdcard_vfs && cur != NULL) { + cur = cur->next; + } + if (cur != NULL) { + cur->next = _sdcard_vfs.next; + } + } + _sdcard_vfs.next = NULL; + + #ifdef DEFAULT_SD_MOSI + common_hal_busio_spi_deinit(&busio_spi_obj); + #endif + _automounted = false; + } + return; + } else if (_init_error || _automounted) { + // We've already tried and failed to init the card, or it's still mounted. Don't try again. + return; + } + + busio_spi_obj_t *spi_obj; + #ifndef DEFAULT_SD_MOSI + spi_obj = MP_OBJ_TO_PTR(common_hal_board_create_spi(0)); + #else + spi_obj = &busio_spi_obj; + spi_obj->base.type = &busio_spi_type; + common_hal_busio_spi_construct(spi_obj, DEFAULT_SD_SCK, DEFAULT_SD_MOSI, DEFAULT_SD_MISO, false); + common_hal_busio_spi_never_reset(spi_obj); + #endif + sdcard.base.type = &sdcardio_SDCard_type; + mp_obj_t cs_obj = MP_OBJ_FROM_PTR(DEFAULT_SD_CS); + mp_rom_error_text_t error = sdcardio_sdcard_construct(&sdcard, spi_obj, cs_obj, 25000000, true); + if (error != NULL) { + // Failed to communicate with the card. + _automounted = false; + _init_error = true; + #ifdef DEFAULT_SD_MOSI + common_hal_busio_spi_deinit(spi_obj); + #endif + return; + } + if (mp_obj_is_type(cs_obj, &mcu_pin_type)) { + common_hal_digitalio_digitalinout_never_reset(MP_OBJ_TO_PTR(sdcard.cs)); + } + fs_user_mount_t *vfs = &_sdcard_usermount; + vfs->base.type = &mp_fat_vfs_type; + vfs->fatfs.drv = vfs; + + // Initialise underlying block device + vfs->blockdev.block_size = FF_MIN_SS; // default, will be populated by call to MP_BLOCKDEV_IOCTL_BLOCK_SIZE + mp_vfs_blockdev_init(&vfs->blockdev, &sdcard); + + // mount the block device so the VFS methods can be used + FRESULT res = f_mount(&vfs->fatfs); + if (res != FR_OK) { + _automounted = false; + _init_error = true; + common_hal_sdcardio_sdcard_deinit(&sdcard); + #ifdef DEFAULT_SD_MOSI + common_hal_busio_spi_deinit(spi_obj); + #endif + return; + } + + filesystem_set_concurrent_write_protection(vfs, true); + filesystem_set_writable_by_usb(vfs, false); + + mp_vfs_mount_t *sdcard_vfs = &_sdcard_vfs; + sdcard_vfs->str = "/sd"; + sdcard_vfs->len = 3; + sdcard_vfs->obj = MP_OBJ_FROM_PTR(&_sdcard_usermount); + sdcard_vfs->next = MP_STATE_VM(vfs_mount_table); + MP_STATE_VM(vfs_mount_table) = sdcard_vfs; + _automounted = true; + #endif // DEFAULT_SD_CARD_DETECT +} diff --git a/shared-module/sdcardio/__init__.h b/shared-module/sdcardio/__init__.h index c9069db9fd7..59b4cf892f2 100644 --- a/shared-module/sdcardio/__init__.h +++ b/shared-module/sdcardio/__init__.h @@ -5,3 +5,6 @@ // SPDX-License-Identifier: MIT #pragma once + +void sdcardio_init(void); +void automount_sd_card(void); diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c index 3c6eaf065df..8b9629b002f 100644 --- a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c +++ b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c @@ -54,11 +54,7 @@ static bool common_hal_sharpdisplay_framebuffer_get_pixels_in_byte_share_row(sha } void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self) { - if (self->bus != &self->inline_bus - #if CIRCUITPY_BOARD_SPI - && !common_hal_board_is_spi(self->bus) - #endif - ) { + if (self->bus != &self->inline_bus && gc_ptr_on_heap(self->bus)) { memcpy(&self->inline_bus, self->bus, sizeof(busio_spi_obj_t)); self->bus = &self->inline_bus; } diff --git a/shared-module/ssl/SSLContext.c b/shared-module/ssl/SSLContext.c index e58074ea3ea..47e8b9f3149 100644 --- a/shared-module/ssl/SSLContext.c +++ b/shared-module/ssl/SSLContext.c @@ -12,7 +12,15 @@ #include "lib/mbedtls_config/crt_bundle.h" +#include "psa/crypto.h" + void common_hal_ssl_sslcontext_construct(ssl_sslcontext_obj_t *self) { + // TLS is built on PSA crypto, which has to be initialized before any of it is + // used. OK to psa_crypto_init() multiple times. On espressif, ESP-IDF has already done this during + // its own system init and this call is a no-op. + if (psa_crypto_init() != PSA_SUCCESS) { + mp_raise_RuntimeError_varg(MP_ERROR_TEXT("%q init failed"), MP_QSTR_ssl); + } common_hal_ssl_sslcontext_set_default_verify_paths(self); } diff --git a/shared-module/ssl/SSLSocket.c b/shared-module/ssl/SSLSocket.c index 129a48d00d6..a9969505509 100644 --- a/shared-module/ssl/SSLSocket.c +++ b/shared-module/ssl/SSLSocket.c @@ -13,7 +13,7 @@ #include "shared/netutils/netutils.h" #include "py/mperrno.h" #include "py/mphal.h" -#include "py/objstr.h" +#include "py/objarray.h" #include "py/runtime.h" #include "py/stream.h" #include "supervisor/shared/tick.h" @@ -28,23 +28,21 @@ #include "../../lib/mbedtls_errors/mp_mbedtls_errors.c" #endif -#if MBEDTLS_VERSION_MAJOR >= 3 -#include "shared-bindings/os/__init__.h" -#endif - #ifdef MBEDTLS_DEBUG_C #include "mbedtls/debug.h" static void mbedtls_debug(void *ctx, int level, const char *file, int line, const char *str) { (void)ctx; (void)level; - mp_printf(&mp_plat_print, "DBG:%s:%04d: %s\n", file, line, str); + mp_printf(&mp_plat_print, "DBG:%s:%04d: %s", file, line, str); } #define DEBUG_PRINT(fmt, ...) mp_printf(&mp_plat_print, "DBG:%s:%04d: " fmt "\n", __FILE__, __LINE__,##__VA_ARGS__) #else #define DEBUG_PRINT(...) do {} while (0) #endif -static NORETURN void mbedtls_raise_error(int err) { +// Raise an OSError for an mbedtls error code. +// `flags` is a bitmask from mbedtls_ssl_get_verify_result(), or 0 if not a verify error. +static MP_NORETURN void mbedtls_raise_error_flags(int err, uint32_t flags) { // _mbedtls_ssl_send and _mbedtls_ssl_recv (below) turn positive error codes from the // underlying socket into negative codes to pass them through mbedtls. Here we turn them // positive again so they get interpreted as the OSError they really are. The @@ -57,37 +55,78 @@ static NORETURN void mbedtls_raise_error(int err) { mp_raise_OSError(MP_EWOULDBLOCK); } + // All ones means mbedtls says it has nothing to report: it set to all ones + // when a verify callback fails, and mbedtls_ssl_get_verify_result() returns + // this when there is no session at all. + if (flags == UINT32_MAX) { + flags = 0; + } + #if defined(MBEDTLS_ERROR_C) // Including mbedtls_strerror takes about 1.5KB due to the error strings. // MBEDTLS_ERROR_C is the define used by mbedtls to conditionally include mbedtls_strerror. // It is set/unset in the MBEDTLS_CONFIG_FILE which is defined in the Makefile. - // Try to allocate memory for the message - #define ERR_STR_MAX 80 // mbedtls_strerror truncates if it doesn't fit - mp_obj_str_t *o_str = m_new_obj_maybe(mp_obj_str_t); - byte *o_str_buf = m_new_maybe(byte, ERR_STR_MAX); - if (o_str == NULL || o_str_buf == NULL) { + // Large enough for the longest mbedtls_strerror() output, which is about 100 + // characters when it joins a high-level and a low-level name with '+', and for + // the longest certificate verification failure name, which is 81 characters. + #define ERR_STR_MAX 128 // mbedtls_strerror truncates if it doesn't fit + // One byte larger than the bound passed to mbedtls_strerror(), so that the + // strncpy() inside it has a bound smaller than the size of buf. Truncation + // there is safe and deliberate, but an equal bound trips -Wstringop-truncation. + char buf[ERR_STR_MAX + 1]; + + // Assemble the error message in a vstr. + // If we run out of heap, catch the MemoryError and fall back to just the error number. + mp_obj_t exc; + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + vstr_t vstr; + vstr_init(&vstr, ERR_STR_MAX); + + mbedtls_strerror(err, buf, ERR_STR_MAX); + vstr_add_str(&vstr, buf); + + #if !defined(MBEDTLS_X509_REMOVE_INFO) + // Call mbedtls_x509_crt_verify_info() to get the error string + // for each individual verify error bit. + // This allows for easier string management. + // Several verify errorbits are often set at once: + // mbedtls or's together the error flags of every certificate in the chain. + // For instance, a cert served under the wrong name and signed by an + // unknown CA reports CN_MISMATCH and NOT_TRUSTED together. + for (uint32_t bit = 1; bit != 0; bit <<= 1) { + if ((flags & bit) == 0) { + continue; + } + // The prefix is added to the beginning of the message. + // We drop the supplied trailing newline. + int info_len = mbedtls_x509_crt_verify_info(buf, ERR_STR_MAX, "; ", bit); + if (info_len > 1) { + // -1 to drop the newline. + vstr_add_strn(&vstr, buf, info_len - 1); + } + } + #endif + + mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(err), mp_obj_new_str_from_utf8_vstr(&vstr) }; + exc = mp_obj_exception_make_new(&mp_type_OSError, 2, 0, args); + nlr_pop(); + } else { + // Could not build the message, so report the number by itself. mp_raise_OSError(err); } - - // print the error message into the allocated buffer - mbedtls_strerror(err, (char *)o_str_buf, ERR_STR_MAX); - size_t len = strlen((char *)o_str_buf); - - // Put the exception object together - o_str->base.type = &mp_type_str; - o_str->data = o_str_buf; - o_str->len = len; - o_str->hash = qstr_compute_hash(o_str->data, o_str->len); - // raise - mp_obj_t args[2] = { MP_OBJ_NEW_SMALL_INT(err), MP_OBJ_FROM_PTR(o_str)}; - nlr_raise(mp_obj_exception_make_new(&mp_type_OSError, 2, 0, args)); + nlr_raise(exc); #else - // mbedtls is compiled without error strings so we simply return the err number + // mbedtls is compiled without error strings, so just return the err number mp_raise_OSError(err); // err is typically a large negative number #endif } +static MP_NORETURN void mbedtls_raise_error(int err) { + mbedtls_raise_error_flags(err, 0); +} + // Because ssl_socket_send and ssl_socket_recv_into are callbacks from mbedtls code, // it is not OK to exit them by raising an exception (nlr_jump'ing through // foreign code is not permitted). Instead, preserve the error number of any OSError @@ -200,16 +239,6 @@ static int _mbedtls_ssl_recv(void *ctx, byte *buf, size_t len) { } -#if MBEDTLS_VERSION_MAJOR >= 3 -static int urandom_adapter(void *unused, unsigned char *buf, size_t n) { - int result = common_hal_os_urandom(buf, n); - if (result) { - return 0; - } - return MBEDTLS_ERR_SSL_INTERNAL_ERROR; -} -#endif - ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t *self, mp_obj_t socket, bool server_side, const char *server_hostname) { @@ -238,20 +267,12 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t mbedtls_x509_crt_init(&o->cacert); mbedtls_x509_crt_init(&o->cert); mbedtls_pk_init(&o->pkey); - mbedtls_ctr_drbg_init(&o->ctr_drbg); #ifdef MBEDTLS_DEBUG_C // Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose mbedtls_debug_set_threshold(4); #endif - mbedtls_entropy_init(&o->entropy); - const byte seed[] = "upy"; - int ret = mbedtls_ctr_drbg_seed(&o->ctr_drbg, mbedtls_entropy_func, &o->entropy, seed, sizeof(seed)); - if (ret != 0) { - goto cleanup; - } - - ret = mbedtls_ssl_config_defaults(&o->conf, + int ret = mbedtls_ssl_config_defaults(&o->conf, server_side ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); @@ -273,7 +294,6 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t } else { mbedtls_ssl_conf_authmode(&o->conf, MBEDTLS_SSL_VERIFY_NONE); } - mbedtls_ssl_conf_rng(&o->conf, mbedtls_ctr_drbg_random, &o->ctr_drbg); #ifdef MBEDTLS_DEBUG_C mbedtls_ssl_conf_dbg(&o->conf, mbedtls_debug, NULL); #endif @@ -293,11 +313,7 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t mbedtls_ssl_set_bio(&o->ssl, o, _mbedtls_ssl_send, _mbedtls_ssl_recv, NULL); if (self->cert_buf.buf != NULL) { - #if MBEDTLS_VERSION_MAJOR >= 3 - ret = mbedtls_pk_parse_key(&o->pkey, self->key_buf.buf, self->key_buf.len + 1, NULL, 0, urandom_adapter, NULL); - #else ret = mbedtls_pk_parse_key(&o->pkey, self->key_buf.buf, self->key_buf.len + 1, NULL, 0); - #endif if (ret != 0) { goto cleanup; } @@ -318,8 +334,6 @@ ssl_sslsocket_obj_t *common_hal_ssl_sslcontext_wrap_socket(ssl_sslcontext_obj_t mbedtls_x509_crt_free(&o->cacert); mbedtls_ssl_free(&o->ssl); mbedtls_ssl_config_free(&o->conf); - mbedtls_ctr_drbg_free(&o->ctr_drbg); - mbedtls_entropy_free(&o->entropy); if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) { mp_raise_type(&mp_type_MemoryError); @@ -382,8 +396,6 @@ void common_hal_ssl_sslsocket_close(ssl_sslsocket_obj_t *self) { mbedtls_x509_crt_free(&self->cacert); mbedtls_ssl_free(&self->ssl); mbedtls_ssl_config_free(&self->conf); - mbedtls_ctr_drbg_free(&self->ctr_drbg); - mbedtls_entropy_free(&self->entropy); } static void do_handshake(ssl_sslsocket_obj_t *self) { @@ -403,13 +415,20 @@ static void do_handshake(ssl_sslsocket_obj_t *self) { cleanup: self->closed = true; + + // Verification flags are only valid for CERT_VERIFY_FAILED. + // Read them before mbedtls_ssl_free() below: they live in the ssl context's + // session_negotiate and are gone once it is freed. + uint32_t verify_flags = 0; + if (ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) { + verify_flags = mbedtls_ssl_get_verify_result(&self->ssl); + } + mbedtls_pk_free(&self->pkey); mbedtls_x509_crt_free(&self->cert); mbedtls_x509_crt_free(&self->cacert); mbedtls_ssl_free(&self->ssl); mbedtls_ssl_config_free(&self->conf); - mbedtls_ctr_drbg_free(&self->ctr_drbg); - mbedtls_entropy_free(&self->entropy); if (ret == MBEDTLS_ERR_SSL_ALLOC_FAILED) { mp_raise_type(&mp_type_MemoryError); @@ -418,7 +437,7 @@ static void do_handshake(ssl_sslsocket_obj_t *self) { } else if (ret == MBEDTLS_ERR_X509_BAD_INPUT_DATA) { mp_raise_ValueError(MP_ERROR_TEXT("invalid cert")); } else { - mbedtls_raise_error(ret); + mbedtls_raise_error_flags(ret, verify_flags); } } diff --git a/shared-module/ssl/SSLSocket.h b/shared-module/ssl/SSLSocket.h index f7f3d1ae83c..f3bb858a00d 100644 --- a/shared-module/ssl/SSLSocket.h +++ b/shared-module/ssl/SSLSocket.h @@ -15,15 +15,11 @@ #include "mbedtls/ssl.h" #include "mbedtls/x509_crt.h" #include "mbedtls/pk.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" typedef struct ssl_sslsocket_obj { mp_obj_base_t base; mp_obj_t sock_obj; ssl_sslcontext_obj_t *ssl_context; - mbedtls_entropy_context entropy; - mbedtls_ctr_drbg_context ctr_drbg; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt cacert; diff --git a/shared-module/storage/__init__.c b/shared-module/storage/__init__.c index 12486aff752..1522136332a 100644 --- a/shared-module/storage/__init__.c +++ b/shared-module/storage/__init__.c @@ -26,49 +26,8 @@ #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC #include "tusb.h" -static const uint8_t usb_msc_descriptor_template[] = { - // MSC Interface Descriptor - 0x09, // 0 bLength - 0x04, // 1 bDescriptorType (Interface) - 0xFF, // 2 bInterfaceNumber [SET AT RUNTIME] -#define MSC_INTERFACE_INDEX (2) - 0x00, // 3 bAlternateSetting - 0x02, // 4 bNumEndpoints 2 - 0x08, // 5 bInterfaceClass: MSC - 0x06, // 6 bInterfaceSubClass: TRANSPARENT - 0x50, // 7 bInterfaceProtocol: BULK - 0xFF, // 8 iInterface (String Index) [SET AT RUNTIME] -#define MSC_INTERFACE_STRING_INDEX (8) - - // MSC Endpoint IN Descriptor - 0x07, // 9 bLength - 0x05, // 10 bDescriptorType (Endpoint) - 0xFF, // 11 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number] -#define MSC_IN_ENDPOINT_INDEX (11) - 0x02, // 12 bmAttributes (Bulk) - #if USB_HIGHSPEED - 0x00, 0x02, // 13,14 wMaxPacketSize 512 - #else - 0x40, 0x00, // 13,14 wMaxPacketSize 64 - #endif - 0x00, // 15 bInterval 0 (unit depends on device speed) - - // MSC Endpoint OUT Descriptor - 0x07, // 16 bLength - 0x05, // 17 bDescriptorType (Endpoint) - 0xFF, // 18 bEndpointAddress (OUT/H2D) [SET AT RUNTIME] -#define MSC_OUT_ENDPOINT_INDEX (18) - 0x02, // 19 bmAttributes (Bulk) - #if USB_HIGHSPEED - 0x00, 0x02, // 20,21 wMaxPacketSize 512 - #else - 0x40, 0x00, // 20,21 wMaxPacketSize 64 - #endif - 0x00, // 22 bInterval 0 (unit depends on device speed) -}; - // Is the MSC device enabled? -bool storage_usb_is_enabled; +static volatile bool storage_usb_is_enabled; void storage_usb_set_defaults(void) { storage_usb_is_enabled = CIRCUITPY_USB_MSC_ENABLED_DEFAULT; @@ -78,43 +37,30 @@ bool storage_usb_enabled(void) { return storage_usb_is_enabled; } -size_t storage_usb_descriptor_length(void) { - return sizeof(usb_msc_descriptor_template); -} - -static const char storage_interface_name[] = USB_INTERFACE_NAME " Mass Storage"; - -size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { - memcpy(descriptor_buf, usb_msc_descriptor_template, sizeof(usb_msc_descriptor_template)); - descriptor_buf[MSC_INTERFACE_INDEX] = descriptor_counts->current_interface; - descriptor_counts->current_interface++; - - descriptor_buf[MSC_IN_ENDPOINT_INDEX] = - 0x80 | (USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : descriptor_counts->current_endpoint); - descriptor_counts->num_in_endpoints++; - descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = - USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : descriptor_counts->current_endpoint; - descriptor_counts->num_out_endpoints++; - descriptor_counts->current_endpoint++; - - usb_add_interface_string(*current_interface_string, storage_interface_name); - descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string; - (*current_interface_string)++; - - return sizeof(usb_msc_descriptor_template); -} - static bool usb_drive_set_enabled(bool enabled) { - // We can't change the descriptors once we're connected. + // We can't change the descriptors once we're connected, but we can make the LUN be ready or not ready. + storage_usb_is_enabled = enabled; if (tud_connected()) { - return false; + // The TEST UNIT READY callback in usb_msc_flash.c checks the value of storage_usb_is_enabled. + // If it's false, TEST UNIT READY will report "not ready" + // Linux and macOS send a TEST UNIT READY poll about every 1.1 seconds or faster. + // Windows polls every 2.1 seconds or so. + // So wait long enough for host to send a TEST UNIT READY and receive a reply. + mp_hal_delay_ms(2500); } filesystem_set_internal_writable_by_usb(enabled); - storage_usb_is_enabled = enabled; return true; } bool common_hal_storage_disable_usb_drive(void) { + if (tud_connected()) { + // Complain if already connected. Use `storage.unsafe_disable_usb_drive()` in that case. + return false; + } + return usb_drive_set_enabled(false); +} + +bool common_hal_storage_unsafe_disable_usb_drive(void) { return usb_drive_set_enabled(false); } @@ -126,6 +72,10 @@ bool common_hal_storage_disable_usb_drive(void) { return false; } +bool common_hal_storage_unsafe_disable_usb_drive(void) { + return false; +} + bool common_hal_storage_enable_usb_drive(void) { return false; } @@ -149,10 +99,11 @@ static mp_obj_t mp_vfs_proxy_call(mp_vfs_mount_t *vfs, qstr meth_name, size_t n_ } void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool readonly) { + const char *abs_mount_path = common_hal_os_path_abspath(mount_path); // create new object mp_vfs_mount_t *vfs = m_new_obj(mp_vfs_mount_t); - vfs->str = mount_path; - vfs->len = strlen(mount_path); + vfs->str = abs_mount_path; + vfs->len = strlen(abs_mount_path); vfs->obj = vfs_obj; vfs->next = NULL; @@ -165,7 +116,7 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool rea if (strcmp(vfs->str, "/") != 0) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - mp_obj_t mount_point_stat = common_hal_os_stat(mount_path); + mp_obj_t mount_point_stat = common_hal_os_stat(abs_mount_path); nlr_pop(); mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mount_point_stat); if ((MP_OBJ_SMALL_INT_VALUE(t->items[0]) & MP_S_IFDIR) == 0) { @@ -179,7 +130,7 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool rea // check that the destination mount point is unused const char *path_out; - mp_vfs_mount_t *existing_mount = mp_vfs_lookup_path(mount_path, &path_out); + mp_vfs_mount_t *existing_mount = mp_vfs_lookup_path(abs_mount_path, &path_out); if (existing_mount != MP_VFS_NONE && existing_mount != MP_VFS_ROOT) { if (vfs->len != 1 && existing_mount->len == 1) { // if root dir is mounted, still allow to mount something within a subdir of root @@ -192,6 +143,11 @@ void common_hal_storage_mount(mp_obj_t vfs_obj, const char *mount_path, bool rea // call the underlying object to do any mounting operation mp_vfs_proxy_call(vfs, MP_QSTR_mount, 2, (mp_obj_t *)&args); + fs_user_mount_t *vfs_fat = MP_OBJ_TO_PTR(vfs_obj); + // Filesystem is read-only to USB if writable by CircuitPython, and vice versa. + filesystem_set_writable_by_usb(vfs_fat, readonly); + filesystem_set_concurrent_write_protection(vfs_fat, true); + // Insert the vfs into the mount table by pushing it onto the front of the // mount table. mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); @@ -224,8 +180,9 @@ void common_hal_storage_umount_object(mp_obj_t vfs_obj) { } static mp_obj_t storage_object_from_path(const char *mount_path) { + const char *abs_mount_path = common_hal_os_path_abspath(mount_path); for (mp_vfs_mount_t **vfsp = &MP_STATE_VM(vfs_mount_table); *vfsp != NULL; vfsp = &(*vfsp)->next) { - if (strcmp(mount_path, (*vfsp)->str) == 0) { + if (strcmp(abs_mount_path, (*vfsp)->str) == 0) { return (*vfsp)->obj; } } @@ -241,18 +198,26 @@ mp_obj_t common_hal_storage_getmount(const char *mount_path) { } void common_hal_storage_remount(const char *mount_path, bool readonly, bool disable_concurrent_write_protection) { - if (strcmp(mount_path, "/") != 0) { + const char *path_under_mount; + const char *abs_mount_path = common_hal_os_path_abspath(mount_path); + fs_user_mount_t *fs_usermount = filesystem_for_path(abs_mount_path, &path_under_mount); + if (path_under_mount[0] != 0 && strcmp(abs_mount_path, "/") != 0) { mp_raise_OSError(MP_EINVAL); } #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC - if (!usb_msc_ejected() && storage_usb_is_enabled) { - mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot remount '/' when visible via USB.")); + if (!blockdev_lock(fs_usermount)) { + mp_raise_RuntimeError(MP_ERROR_TEXT("Cannot remount path when visible via USB.")); } #endif - filesystem_set_internal_writable_by_usb(readonly); - filesystem_set_internal_concurrent_write_protection(!disable_concurrent_write_protection); + filesystem_set_writable_by_usb(fs_usermount, readonly); + filesystem_set_concurrent_write_protection(fs_usermount, !disable_concurrent_write_protection); + blockdev_unlock(fs_usermount); + + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC + usb_msc_remount(fs_usermount); + #endif } void common_hal_storage_erase_filesystem(bool extended) { @@ -264,6 +229,7 @@ void common_hal_storage_erase_filesystem(bool extended) { supervisor_flash_set_extended(extended); #endif (void)filesystem_init(false, true); // Force a re-format. Ignore failure. + common_hal_mcu_on_next_reset(RUNMODE_NORMAL); common_hal_mcu_reset(); // We won't actually get here, since we're resetting. } diff --git a/shared-module/storage/__init__.h b/shared-module/storage/__init__.h index 3adda2c2f71..03503f4e802 100644 --- a/shared-module/storage/__init__.h +++ b/shared-module/storage/__init__.h @@ -11,6 +11,4 @@ bool storage_usb_enabled(void); void storage_usb_set_defaults(void); -size_t storage_usb_descriptor_length(void); -size_t storage_usb_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string); #endif diff --git a/shared-module/struct/__init__.c b/shared-module/struct/__init__.c index 715b5043021..4b6b2b589ef 100644 --- a/shared-module/struct/__init__.c +++ b/shared-module/struct/__init__.c @@ -14,7 +14,8 @@ #include "shared-bindings/struct/__init__.h" static void struct_validate_format(char fmt) { - #if MICROPY_NONSTANDARD_TYPECODES + #if MICROPY_PY_STRUCT_UNSAFE_TYPECODES + if (fmt == 'S' || fmt == 'O') { mp_raise_RuntimeError(MP_ERROR_TEXT("'S' and 'O' are not supported format types")); } diff --git a/shared-module/synthio/Biquad.c b/shared-module/synthio/Biquad.c index 366d5164552..edefd071403 100644 --- a/shared-module/synthio/Biquad.c +++ b/shared-module/synthio/Biquad.c @@ -1,3 +1,4 @@ + // This file is part of the CircuitPython project: https://circuitpython.org // // SPDX-FileCopyrightText: Copyright (c) 2023 Jeff Epler for Adafruit Industries @@ -7,99 +8,207 @@ #include #include "shared-bindings/synthio/Biquad.h" #include "shared-module/synthio/Biquad.h" +#include "shared-module/synthio/block.h" +#include "shared-bindings/synthio/__init__.h" + +typedef struct { + mp_float_t s, c; +} sincos_result_t; + +#include // uint32_t + +// The famous Quake approximate square root function +static mp_float_t Q_rsqrt(mp_float_t number_in) { + float number = (float)number_in; + union { + float f; + uint32_t i; + } conv = { .f = (float)number }; + conv.i = 0x5f3759df - (conv.i >> 1); + conv.f *= 1.5F - (number * 0.5F * conv.f * conv.f); + return (mp_float_t)conv.f; +} + +static mp_float_t fast_sqrt(mp_float_t number) { + return number * Q_rsqrt(number); +} + +#define FOUR_OVER_PI (4 / M_PI) +static void fast_sincos(mp_float_t theta, sincos_result_t *result) { + mp_float_t x = (theta * FOUR_OVER_PI) - 1; + mp_float_t x2 = x * x, x3 = x2 * x, x4 = x2 * x2, x5 = x2 * x3; + mp_float_t c0 = 0.70708592, + c1x = -0.55535724 * x, + c2x2 = -0.21798592 * x2, + c3x3 = 0.05707685 * x3, + c4x4 = 0.0109 * x4, + c5x5 = -0.00171961 * x5; + + mp_float_t evens = c4x4 + c2x2 + c0, odds = c5x5 + c3x3 + c1x; + result->c = evens + odds; + result->s = evens - odds; +} + +mp_obj_t common_hal_synthio_biquad_new(synthio_filter_mode mode) { + synthio_biquad_t *self = mp_obj_malloc(synthio_biquad_t, &synthio_biquad_type_obj); + self->mode = mode; + return MP_OBJ_FROM_PTR(self); +} + +synthio_filter_mode common_hal_synthio_biquad_get_mode(synthio_biquad_t *self) { + return self->mode; +} + +mp_obj_t common_hal_synthio_biquad_get_Q(synthio_biquad_t *self) { + return self->Q.obj; +} + +void common_hal_synthio_biquad_set_Q(synthio_biquad_t *self, mp_obj_t Q) { + synthio_block_assign_slot(Q, &self->Q, MP_QSTR_Q); +} + +mp_obj_t common_hal_synthio_biquad_get_A(synthio_biquad_t *self) { + return self->A.obj; +} + +void common_hal_synthio_biquad_set_A(synthio_biquad_t *self, mp_obj_t A) { + synthio_block_assign_slot(A, &self->A, MP_QSTR_A); +} + +mp_obj_t common_hal_synthio_biquad_get_frequency(synthio_biquad_t *self) { + return self->f0.obj; +} -mp_obj_t common_hal_synthio_new_lpf(mp_float_t w0, mp_float_t Q) { - mp_float_t s = MICROPY_FLOAT_C_FUN(sin)(w0); - mp_float_t c = MICROPY_FLOAT_C_FUN(cos)(w0); - mp_float_t alpha = s / (2 * Q); - mp_float_t a0 = 1 + alpha; - mp_float_t a1 = -2 * c; - mp_float_t a2 = 1 - alpha; - mp_float_t b0 = (1 - c) / 2; - mp_float_t b1 = 1 - c; - mp_float_t b2 = (1 - c) / 2; - - mp_obj_t out_args[] = { - mp_obj_new_float(a1 / a0), - mp_obj_new_float(a2 / a0), - mp_obj_new_float(b0 / a0), - mp_obj_new_float(b1 / a0), - mp_obj_new_float(b2 / a0), - }; - - return namedtuple_make_new((const mp_obj_type_t *)&synthio_biquad_type_obj, MP_ARRAY_SIZE(out_args), 0, out_args); -} - -mp_obj_t common_hal_synthio_new_hpf(mp_float_t w0, mp_float_t Q) { - mp_float_t s = MICROPY_FLOAT_C_FUN(sin)(w0); - mp_float_t c = MICROPY_FLOAT_C_FUN(cos)(w0); - mp_float_t alpha = s / (2 * Q); - mp_float_t a0 = 1 + alpha; - mp_float_t a1 = -2 * c; - mp_float_t a2 = 1 - alpha; - mp_float_t b0 = (1 + c) / 2; - mp_float_t b1 = -(1 + c); - mp_float_t b2 = (1 + c) / 2; - - mp_obj_t out_args[] = { - mp_obj_new_float(a1 / a0), - mp_obj_new_float(a2 / a0), - mp_obj_new_float(b0 / a0), - mp_obj_new_float(b1 / a0), - mp_obj_new_float(b2 / a0), - }; - - return namedtuple_make_new((const mp_obj_type_t *)&synthio_biquad_type_obj, MP_ARRAY_SIZE(out_args), 0, out_args); -} - -mp_obj_t common_hal_synthio_new_bpf(mp_float_t w0, mp_float_t Q) { - mp_float_t s = MICROPY_FLOAT_C_FUN(sin)(w0); - mp_float_t c = MICROPY_FLOAT_C_FUN(cos)(w0); - mp_float_t alpha = s / (2 * Q); - mp_float_t a0 = 1 + alpha; - mp_float_t a1 = -2 * c; - mp_float_t a2 = 1 - alpha; - mp_float_t b0 = alpha; - mp_float_t b1 = 0; - mp_float_t b2 = -alpha; - - mp_obj_t out_args[] = { - mp_obj_new_float(a1 / a0), - mp_obj_new_float(a2 / a0), - mp_obj_new_float(b0 / a0), - mp_obj_new_float(b1 / a0), - mp_obj_new_float(b2 / a0), - }; - - return namedtuple_make_new((const mp_obj_type_t *)&synthio_biquad_type_obj, MP_ARRAY_SIZE(out_args), 0, out_args); -} - -#define BIQUAD_SHIFT (15) -static int32_t biquad_scale_arg_obj(mp_obj_t arg) { - return (int32_t)MICROPY_FLOAT_C_FUN(round)(MICROPY_FLOAT_C_FUN(ldexp)(mp_obj_get_float(arg), BIQUAD_SHIFT)); -} -void synthio_biquad_filter_assign(biquad_filter_state *st, mp_obj_t biquad_obj) { - if (biquad_obj != mp_const_none) { - mp_arg_validate_type(biquad_obj, (const mp_obj_type_t *)&synthio_biquad_type_obj, MP_QSTR_filter); - mp_obj_tuple_t *biquad = (mp_obj_tuple_t *)MP_OBJ_TO_PTR(biquad_obj); - st->a1 = biquad_scale_arg_obj(biquad->items[0]); - st->a2 = biquad_scale_arg_obj(biquad->items[1]); - st->b0 = biquad_scale_arg_obj(biquad->items[2]); - st->b1 = biquad_scale_arg_obj(biquad->items[3]); - st->b2 = biquad_scale_arg_obj(biquad->items[4]); +void common_hal_synthio_biquad_set_frequency(synthio_biquad_t *self, mp_obj_t frequency) { + synthio_block_assign_slot(frequency, &self->f0, MP_QSTR_frequency); +} + +static int32_t biquad_scale_arg_float(mp_float_t arg) { + return (int32_t)MICROPY_FLOAT_C_FUN(round)(MICROPY_FLOAT_C_FUN(ldexp)(arg, BIQUAD_SHIFT)); +} + +static int float_equal_or_update( + mp_float_t *cached, + mp_float_t new) { + // uses memcmp to avoid error about equality float comparison + if (memcmp(cached, &new, sizeof(mp_float_t))) { + *cached = new; + return false; + } + return true; +} + +void common_hal_synthio_biquad_tick(mp_obj_t self_in) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + + mp_float_t W0 = synthio_block_slot_get(&self->f0) * synthio_global_W_scale; + mp_float_t Q = synthio_block_slot_get(&self->Q); + mp_float_t A = + (self->mode >= SYNTHIO_PEAKING_EQ) ? synthio_block_slot_get(&self->A) : 0; + + // n.b., assumes that the `mode` field is read-only + // n.b., use of `&` is deliberate, avoids short-circuiting behavior + if (float_equal_or_update(&self->cached_W0, W0) + & float_equal_or_update(&self->cached_Q, Q) + & float_equal_or_update(&self->cached_A, A)) { + return; + } + + sincos_result_t sc; + fast_sincos(W0, &sc); + + mp_float_t alpha = sc.s / (2 * Q); + + mp_float_t a0, a1, a2, b0, b1, b2; + + switch (self->mode) { + default: + a0 = 1 + alpha; + a1 = -2 * sc.c; + a2 = 1 - alpha; + + switch (self->mode) { + default: + case SYNTHIO_LOW_PASS: + b2 = b0 = (1 - sc.c) * .5; + b1 = 1 - sc.c; + break; + + case SYNTHIO_HIGH_PASS: + b2 = b0 = (1 + sc.c) * .5; + b1 = -(1 + sc.c); + break; + + case SYNTHIO_BAND_PASS: + b0 = alpha; + b1 = 0; + b2 = -b0; + break; + + case SYNTHIO_NOTCH: + b0 = 1; + b1 = -2 * sc.c; + b2 = 1; + } + + break; + + case SYNTHIO_PEAKING_EQ: + b0 = 1 + alpha * A; + b1 = -2 * sc.c; + b2 = 1 + alpha * A; + a0 = 1 + alpha / A; + a1 = -2 * sc.c; + a2 = 1 - alpha / A; + break; + + case SYNTHIO_LOW_SHELF: { + mp_float_t sqrt_A = fast_sqrt(A); + b0 = A * ((A + 1) - (A - 1) * sc.c + 2 * sqrt_A * alpha); + b1 = 2 * A * ((A - 1) - (A + 1) * sc.c); + b2 = A * ((A + 1) - (A - 1) * sc.c - 2 * sqrt_A * alpha); + a0 = (A + 1) + (A - 1) * sc.c + 2 * sqrt_A * alpha; + a1 = -2 * ((A - 1) + (A + 1) * sc.c); + a2 = (A + 1) + (A - 1) * sc.c - 2 * sqrt_A * alpha; + } + break; + + case SYNTHIO_HIGH_SHELF: { + mp_float_t sqrt_A = fast_sqrt(A); + b0 = A * ((A + 1) + (A - 1) * sc.c + 2 * sqrt_A * alpha); + b1 = -2 * A * ((A - 1) + (A + 1) * sc.c); + b2 = A * ((A + 1) + (A - 1) * sc.c - 2 * sqrt_A * alpha); + a0 = (A + 1) - (A - 1) * sc.c + 2 * sqrt_A * alpha; + a1 = 2 * ((A - 1) - (A + 1) * sc.c); + a2 = (A + 1) - (A - 1) * sc.c - 2 * sqrt_A * alpha; + } + break; } + mp_float_t recip_a0 = 1 / a0; + + self->a1 = biquad_scale_arg_float(a1 * recip_a0); + self->a2 = biquad_scale_arg_float(a2 * recip_a0); + self->b0 = biquad_scale_arg_float(b0 * recip_a0); + self->b1 = biquad_scale_arg_float(b1 * recip_a0); + self->b2 = biquad_scale_arg_float(b2 * recip_a0); } void synthio_biquad_filter_reset(biquad_filter_state *st) { memset(&st->x, 0, 4 * sizeof(int16_t)); } -void synthio_biquad_filter_samples(biquad_filter_state *st, int32_t *buffer, size_t n_samples) { - int32_t a1 = st->a1; - int32_t a2 = st->a2; - int32_t b0 = st->b0; - int32_t b1 = st->b1; - int32_t b2 = st->b2; +static inline int32_t biquad_filter_sample(int32_t input, int32_t a1, int32_t a2, int32_t b0, int32_t b1, int32_t b2, int32_t x0, int32_t x1, int32_t y0, int32_t y1) { + return synthio_sat16((b0 * input + b1 * x0 + b2 * x1 - a1 * y0 - a2 * y1 + (1 << (BIQUAD_SHIFT - 1))), BIQUAD_SHIFT); +} + +void synthio_biquad_filter_samples(mp_obj_t self_in, biquad_filter_state *st, int32_t *buffer, size_t n_samples) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + + int32_t a1 = self->a1; + int32_t a2 = self->a2; + int32_t b0 = self->b0; + int32_t b1 = self->b1; + int32_t b2 = self->b2; int32_t x0 = st->x[0]; int32_t x1 = st->x[1]; @@ -108,7 +217,7 @@ void synthio_biquad_filter_samples(biquad_filter_state *st, int32_t *buffer, siz for (size_t n = n_samples; n; --n, ++buffer) { int32_t input = *buffer; - int32_t output = (b0 * input + b1 * x0 + b2 * x1 - a1 * y0 - a2 * y1 + (1 << (BIQUAD_SHIFT - 1))) >> BIQUAD_SHIFT; + int32_t output = biquad_filter_sample(input, a1, a2, b0, b1, b2, x0, x1, y0, y1); x1 = x0; x0 = input; @@ -121,3 +230,16 @@ void synthio_biquad_filter_samples(biquad_filter_state *st, int32_t *buffer, siz st->y[0] = y0; st->y[1] = y1; } + +int32_t synthio_biquad_filter_sample(mp_obj_t self_in, biquad_filter_state *st, int32_t input) { + synthio_biquad_t *self = MP_OBJ_TO_PTR(self_in); + + int32_t output = biquad_filter_sample(input, self->a1, self->a2, self->b0, self->b1, self->b2, st->x[0], st->x[1], st->y[0], st->y[1]); + + st->x[1] = st->x[0]; + st->x[0] = input; + st->y[1] = st->y[0]; + st->y[0] = output; + + return output; +} diff --git a/shared-module/synthio/Biquad.h b/shared-module/synthio/Biquad.h index b33a6230caf..cc9b4f53b0e 100644 --- a/shared-module/synthio/Biquad.h +++ b/shared-module/synthio/Biquad.h @@ -1,3 +1,4 @@ + // This file is part of the CircuitPython project: https://circuitpython.org // // SPDX-FileCopyrightText: Copyright (c) 2023 Jeff Epler for Adafruit Industries @@ -6,13 +7,24 @@ #pragma once -#include "py/obj.h" +#include "shared-bindings/synthio/Biquad.h" +#include "shared-module/synthio/block.h" -typedef struct { +#define BIQUAD_SHIFT (15) + +typedef struct synthio_biquad { + mp_obj_base_t base; + synthio_filter_mode mode; + synthio_block_slot_t f0, Q, A; + mp_float_t cached_W0, cached_Q, cached_A; int32_t a1, a2, b0, b1, b2; +} synthio_biquad_t; + +typedef struct { int32_t x[2], y[2]; } biquad_filter_state; -void synthio_biquad_filter_assign(biquad_filter_state *st, mp_obj_t biquad_obj); +void common_hal_synthio_biquad_tick(mp_obj_t self_in); void synthio_biquad_filter_reset(biquad_filter_state *st); -void synthio_biquad_filter_samples(biquad_filter_state *st, int32_t *buffer, size_t n_samples); +void synthio_biquad_filter_samples(mp_obj_t self_in, biquad_filter_state *st, int32_t *buffer, size_t n_samples); +int32_t synthio_biquad_filter_sample(mp_obj_t self_in, biquad_filter_state *st, int32_t input); diff --git a/shared-module/synthio/MidiTrack.c b/shared-module/synthio/MidiTrack.c index 2391a8bb7c7..1cccd440fad 100644 --- a/shared-module/synthio/MidiTrack.c +++ b/shared-module/synthio/MidiTrack.c @@ -6,6 +6,7 @@ #include "py/runtime.h" #include "shared-bindings/synthio/MidiTrack.h" +#include "shared-bindings/audiocore/__init__.h" static void record_midi_stream_error(synthio_miditrack_obj_t *self) { @@ -42,7 +43,7 @@ static int decode_duration(synthio_miditrack_obj_t *self) { self->pos = self->track.len; record_midi_stream_error(self); } - return delta * self->synth.sample_rate / self->tempo; + return delta * self->synth.base.sample_rate / self->tempo; } // invariant: pointing at a MIDI message @@ -111,22 +112,18 @@ void common_hal_synthio_miditrack_deinit(synthio_miditrack_obj_t *self) { synthio_synth_deinit(&self->synth); } -bool common_hal_synthio_miditrack_deinited(synthio_miditrack_obj_t *self) { - return synthio_synth_deinited(&self->synth); -} - mp_int_t common_hal_synthio_miditrack_get_error_location(synthio_miditrack_obj_t *self) { return self->error_location; } -uint32_t common_hal_synthio_miditrack_get_sample_rate(synthio_miditrack_obj_t *self) { - return self->synth.sample_rate; -} -uint8_t common_hal_synthio_miditrack_get_bits_per_sample(synthio_miditrack_obj_t *self) { - return SYNTHIO_BITS_PER_SAMPLE; +mp_int_t common_hal_synthio_miditrack_get_tempo(synthio_miditrack_obj_t *self) { + return self->tempo; } -uint8_t common_hal_synthio_miditrack_get_channel_count(synthio_miditrack_obj_t *self) { - return 1; + +void common_hal_synthio_miditrack_set_tempo(synthio_miditrack_obj_t *self, mp_int_t value) { + mp_int_t val = mp_arg_validate_int_min(value, 1, MP_QSTR_tempo); + self->synth.span.dur = (uint32_t)self->synth.span.dur * self->tempo / val; + self->tempo = val; } void synthio_miditrack_reset_buffer(synthio_miditrack_obj_t *self, @@ -137,7 +134,7 @@ void synthio_miditrack_reset_buffer(synthio_miditrack_obj_t *self, audioio_get_buffer_result_t synthio_miditrack_get_buffer(synthio_miditrack_obj_t *self, bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { - if (common_hal_synthio_miditrack_deinited(self)) { + if (audiosample_deinited(&self->synth.base)) { *buffer_length = 0; return GET_BUFFER_ERROR; } @@ -152,8 +149,3 @@ audioio_get_buffer_result_t synthio_miditrack_get_buffer(synthio_miditrack_obj_t } return GET_BUFFER_MORE_DATA; } - -void synthio_miditrack_get_buffer_structure(synthio_miditrack_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { - return synthio_synth_get_buffer_structure(&self->synth, single_channel_output, single_buffer, samples_signed, max_buffer_length, spacing); -} diff --git a/shared-module/synthio/MidiTrack.h b/shared-module/synthio/MidiTrack.h index 816c0be6958..1e4d5cba2da 100644 --- a/shared-module/synthio/MidiTrack.h +++ b/shared-module/synthio/MidiTrack.h @@ -11,7 +11,6 @@ #include "shared-module/synthio/__init__.h" typedef struct { - mp_obj_base_t base; synthio_synth_t synth; mp_buffer_info_t track; // invariant: after initial startup, pos always points just after an encoded duration, i.e., at a midi message (or at EOF) @@ -31,7 +30,3 @@ audioio_get_buffer_result_t synthio_miditrack_get_buffer(synthio_miditrack_obj_t uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); // length in bytes - -void synthio_miditrack_get_buffer_structure(synthio_miditrack_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing); diff --git a/shared-module/synthio/Note.c b/shared-module/synthio/Note.c index 49dfbb7f429..01c7e4ba487 100644 --- a/shared-module/synthio/Note.c +++ b/shared-module/synthio/Note.c @@ -25,7 +25,11 @@ mp_obj_t common_hal_synthio_note_get_filter_obj(synthio_note_obj_t *self) { } void common_hal_synthio_note_set_filter(synthio_note_obj_t *self, mp_obj_t filter_in) { - synthio_biquad_filter_assign(&self->filter_state, filter_in); + if (filter_in != mp_const_none && !mp_obj_is_type(filter_in, &synthio_biquad_type_obj)) { + mp_raise_TypeError_varg( + MP_ERROR_TEXT("%q must be of type %q, not %q"), + MP_QSTR_filter, MP_QSTR_Biquad, mp_obj_get_type(filter_in)->name); + } self->filter_obj = filter_in; } @@ -100,22 +104,20 @@ void common_hal_synthio_note_set_waveform(synthio_note_obj_t *self, mp_obj_t wav self->waveform_obj = waveform_in; } -mp_int_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self) { - return self->waveform_loop_start; +mp_obj_t common_hal_synthio_note_get_waveform_loop_start(synthio_note_obj_t *self) { + return self->waveform_loop_start.obj; } -void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in) { - mp_int_t val = mp_arg_validate_int_range(value_in, 0, SYNTHIO_WAVEFORM_SIZE - 1, MP_QSTR_waveform_loop_start); - self->waveform_loop_start = val; +void common_hal_synthio_note_set_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value_in) { + synthio_block_assign_slot(value_in, &self->waveform_loop_start, MP_QSTR_waveform_loop_start); } -mp_int_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self) { - return self->waveform_loop_end; +mp_obj_t common_hal_synthio_note_get_waveform_loop_end(synthio_note_obj_t *self) { + return self->waveform_loop_end.obj; } -void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in) { - mp_int_t val = mp_arg_validate_int_range(value_in, 1, SYNTHIO_WAVEFORM_SIZE, MP_QSTR_waveform_loop_end); - self->waveform_loop_end = val; +void common_hal_synthio_note_set_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value_in) { + synthio_block_assign_slot(value_in, &self->waveform_loop_end, MP_QSTR_waveform_loop_end); } mp_obj_t common_hal_synthio_note_get_ring_waveform_obj(synthio_note_obj_t *self) { @@ -133,22 +135,20 @@ void common_hal_synthio_note_set_ring_waveform(synthio_note_obj_t *self, mp_obj_ self->ring_waveform_obj = ring_waveform_in; } -mp_int_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self) { - return self->ring_waveform_loop_start; +mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_start(synthio_note_obj_t *self) { + return self->ring_waveform_loop_start.obj; } -void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_int_t value_in) { - mp_int_t val = mp_arg_validate_int_range(value_in, 0, SYNTHIO_WAVEFORM_SIZE - 1, MP_QSTR_ring_waveform_loop_start); - self->ring_waveform_loop_start = val; +void common_hal_synthio_note_set_ring_waveform_loop_start(synthio_note_obj_t *self, mp_obj_t value_in) { + synthio_block_assign_slot(value_in, &self->ring_waveform_loop_start, MP_QSTR_ring_waveform_loop_start); } -mp_int_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self) { - return self->ring_waveform_loop_end; +mp_obj_t common_hal_synthio_note_get_ring_waveform_loop_end(synthio_note_obj_t *self) { + return self->ring_waveform_loop_end.obj; } -void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_int_t value_in) { - mp_int_t val = mp_arg_validate_int_range(value_in, 1, SYNTHIO_WAVEFORM_SIZE, MP_QSTR_ring_waveform_loop_end); - self->ring_waveform_loop_end = val; +void common_hal_synthio_note_set_ring_waveform_loop_end(synthio_note_obj_t *self, mp_obj_t value_in) { + synthio_block_assign_slot(value_in, &self->ring_waveform_loop_end, MP_QSTR_ring_waveform_loop_end); } void synthio_note_recalculate(synthio_note_obj_t *self, int32_t sample_rate) { @@ -196,13 +196,11 @@ static uint32_t pitch_bend(uint32_t frequency_scaled, int32_t bend_value) { uint32_t synthio_note_step(synthio_note_obj_t *self, int32_t sample_rate, int16_t dur, int16_t loudness[2]) { int panning = synthio_block_slot_get_scaled(&self->panning, -ALMOST_ONE, ALMOST_ONE); - int left_panning_scaled, right_panning_scaled; + int left_panning_scaled = 32768, right_panning_scaled = 32768; if (panning >= 0) { - left_panning_scaled = 32768; - right_panning_scaled = 32767 - panning; + left_panning_scaled = 32767 - panning; } else { - right_panning_scaled = 32768; - left_panning_scaled = 32767 + panning; + right_panning_scaled = 32767 + panning; } int amplitude = synthio_block_slot_get_scaled(&self->amplitude, -ALMOST_ONE, ALMOST_ONE); diff --git a/shared-module/synthio/Note.h b/shared-module/synthio/Note.h index dc4e5557fd3..9d9deb42ac8 100644 --- a/shared-module/synthio/Note.h +++ b/shared-module/synthio/Note.h @@ -28,9 +28,9 @@ typedef struct synthio_note_obj { int32_t ring_frequency_scaled, ring_frequency_bent; mp_buffer_info_t waveform_buf; - uint32_t waveform_loop_start, waveform_loop_end; + synthio_block_slot_t waveform_loop_start, waveform_loop_end; mp_buffer_info_t ring_waveform_buf; - uint32_t ring_waveform_loop_start, ring_waveform_loop_end; + synthio_block_slot_t ring_waveform_loop_start, ring_waveform_loop_end; synthio_envelope_definition_t envelope_def; } synthio_note_obj_t; diff --git a/shared-module/synthio/Synthesizer.c b/shared-module/synthio/Synthesizer.c index e4b343f6ba2..39eb4a02e6a 100644 --- a/shared-module/synthio/Synthesizer.c +++ b/shared-module/synthio/Synthesizer.c @@ -7,6 +7,7 @@ #include "py/runtime.h" #include "shared-bindings/synthio/LFO.h" #include "shared-bindings/synthio/Note.h" +#include "shared-bindings/audiocore/__init__.h" #include "shared-bindings/synthio/Synthesizer.h" #include "shared-module/synthio/Note.h" @@ -23,19 +24,6 @@ void common_hal_synthio_synthesizer_construct(synthio_synthesizer_obj_t *self, void common_hal_synthio_synthesizer_deinit(synthio_synthesizer_obj_t *self) { synthio_synth_deinit(&self->synth); } -bool common_hal_synthio_synthesizer_deinited(synthio_synthesizer_obj_t *self) { - return synthio_synth_deinited(&self->synth); -} - -uint32_t common_hal_synthio_synthesizer_get_sample_rate(synthio_synthesizer_obj_t *self) { - return self->synth.sample_rate; -} -uint8_t common_hal_synthio_synthesizer_get_bits_per_sample(synthio_synthesizer_obj_t *self) { - return SYNTHIO_BITS_PER_SAMPLE; -} -uint8_t common_hal_synthio_synthesizer_get_channel_count(synthio_synthesizer_obj_t *self) { - return self->synth.channel_count; -} void synthio_synthesizer_reset_buffer(synthio_synthesizer_obj_t *self, bool single_channel_output, uint8_t channel) { @@ -44,7 +32,7 @@ void synthio_synthesizer_reset_buffer(synthio_synthesizer_obj_t *self, audioio_get_buffer_result_t synthio_synthesizer_get_buffer(synthio_synthesizer_obj_t *self, bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { - if (common_hal_synthio_synthesizer_deinited(self)) { + if (audiosample_deinited(&self->synth.base)) { *buffer_length = 0; return GET_BUFFER_ERROR; } @@ -67,11 +55,6 @@ audioio_get_buffer_result_t synthio_synthesizer_get_buffer(synthio_synthesizer_o return GET_BUFFER_MORE_DATA; } -void synthio_synthesizer_get_buffer_structure(synthio_synthesizer_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { - return synthio_synth_get_buffer_structure(&self->synth, single_channel_output, single_buffer, samples_signed, max_buffer_length, spacing); -} - void common_hal_synthio_synthesizer_release_all(synthio_synthesizer_obj_t *self) { for (size_t i = 0; i < CIRCUITPY_SYNTHIO_MAX_CHANNELS; i++) { if (self->synth.span.note_obj[i] != SYNTHIO_SILENCE) { @@ -114,7 +97,7 @@ void common_hal_synthio_synthesizer_press(synthio_synthesizer_obj_t *self, mp_ob if (is_note(to_press)) { if (!mp_obj_is_small_int(to_press)) { synthio_note_obj_t *note = MP_OBJ_TO_PTR(to_press); - synthio_note_start(note, self->synth.sample_rate); + synthio_note_start(note, self->synth.base.sample_rate); } synthio_span_change_note(&self->synth, SYNTHIO_SILENCE, validate_note(to_press)); return; @@ -127,7 +110,7 @@ void common_hal_synthio_synthesizer_press(synthio_synthesizer_obj_t *self, mp_ob note_obj = validate_note(note_obj); if (!mp_obj_is_small_int(note_obj)) { synthio_note_obj_t *note = MP_OBJ_TO_PTR(note_obj); - synthio_note_start(note, self->synth.sample_rate); + synthio_note_start(note, self->synth.base.sample_rate); } synthio_span_change_note(&self->synth, SYNTHIO_SILENCE, note_obj); } diff --git a/shared-module/synthio/Synthesizer.h b/shared-module/synthio/Synthesizer.h index 4fd5012cdcd..a4dac7c25c6 100644 --- a/shared-module/synthio/Synthesizer.h +++ b/shared-module/synthio/Synthesizer.h @@ -12,7 +12,6 @@ #include "shared-module/synthio/__init__.h" typedef struct { - mp_obj_base_t base; synthio_synth_t synth; mp_obj_t blocks; } synthio_synthesizer_obj_t; @@ -28,7 +27,3 @@ audioio_get_buffer_result_t synthio_synthesizer_get_buffer(synthio_synthesizer_o uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); // length in bytes - -void synthio_synthesizer_get_buffer_structure(synthio_synthesizer_obj_t *self, bool single_channel_output, - bool *single_buffer, bool *samples_signed, - uint32_t *max_buffer_length, uint8_t *spacing); diff --git a/shared-module/synthio/__init__.c b/shared-module/synthio/__init__.c index 630c3de8698..b30b5f35b5f 100644 --- a/shared-module/synthio/__init__.c +++ b/shared-module/synthio/__init__.c @@ -6,6 +6,7 @@ // SPDX-License-Identifier: MIT #include "shared-module/synthio/__init__.h" +#include "shared-bindings/audiocore/__init__.h" #include "shared-bindings/synthio/__init__.h" #include "shared-module/synthio/Biquad.h" #include "shared-module/synthio/Note.h" @@ -13,7 +14,9 @@ #include #include -mp_float_t synthio_global_rate_scale; +#define MP_PI MICROPY_FLOAT_CONST(3.14159265358979323846) + +mp_float_t synthio_global_rate_scale, synthio_global_W_scale; uint8_t synthio_global_tick; static const int16_t square_wave[] = {-32768, 32767}; @@ -21,6 +24,26 @@ static const int16_t square_wave[] = {-32768, 32767}; static const uint16_t notes[] = {8372, 8870, 9397, 9956, 10548, 11175, 11840, 12544, 13290, 14080, 14917, 15804}; // 9th octave +// cleaner sat16 by http://www.moseleyinstruments.com/ +int16_t synthio_sat16(int32_t n, int rshift) { + // we should always round towards 0 + // to avoid recirculating round-off noise + // + // a 2s complement positive number is always + // rounded down, so we only need to take + // care of negative numbers + if (n < 0) { + n = n + (~(0xFFFFFFFFUL << rshift)); + } + n = n >> rshift; + if (n > 32767) { + return 32767; + } + if (n < -32768) { + return -32768; + } + return n; +} static int64_t round_float_to_int64(mp_float_t f) { return (int64_t)(f + MICROPY_FLOAT_CONST(0.5)); @@ -126,28 +149,24 @@ static synthio_envelope_definition_t *synthio_synth_get_note_envelope(synthio_sy } -#define RANGE_LOW (-28000) -#define RANGE_HIGH (28000) #define RANGE_SHIFT (16) -#define RANGE_SCALE (0xfffffff / (32768 * CIRCUITPY_SYNTHIO_MAX_CHANNELS - RANGE_HIGH)) // dynamic range compression via a downward compressor with hard knee // // When the output value is within the range +-28000 (about 85% of full scale), // it is unchanged. Otherwise, it undergoes a gain reduction so that the -// largest possible values, (+32768,-32767) * CIRCUITPY_SYNTHIO_MAX_CHANNELS, +// largest possible values, (+32768,-32767) * count, // still fit within the output range // // This produces a much louder overall volume with multiple voices, without // much additional processing. // // https://en.wikipedia.org/wiki/Dynamic_range_compression -static -int16_t mix_down_sample(int32_t sample) { - if (sample < RANGE_LOW) { - sample = (((sample - RANGE_LOW) * RANGE_SCALE) >> RANGE_SHIFT) + RANGE_LOW; - } else if (sample > RANGE_HIGH) { - sample = (((sample - RANGE_HIGH) * RANGE_SCALE) >> RANGE_SHIFT) + RANGE_HIGH; +int16_t synthio_mix_down_sample(int32_t sample, int32_t scale) { + if (sample < SYNTHIO_MIX_DOWN_RANGE_LOW) { + sample = (((sample - SYNTHIO_MIX_DOWN_RANGE_LOW) * scale) >> RANGE_SHIFT) + SYNTHIO_MIX_DOWN_RANGE_LOW; + } else if (sample > SYNTHIO_MIX_DOWN_RANGE_HIGH) { + sample = (((sample - SYNTHIO_MIX_DOWN_RANGE_HIGH) * scale) >> RANGE_SHIFT) + SYNTHIO_MIX_DOWN_RANGE_HIGH; } return sample; } @@ -155,7 +174,7 @@ int16_t mix_down_sample(int32_t sample) { static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *out_buffer32, int16_t dur, int16_t loudness[2]) { mp_obj_t note_obj = synth->span.note_obj[chan]; - int32_t sample_rate = synth->sample_rate; + int32_t sample_rate = synth->base.sample_rate; uint32_t dds_rate; @@ -184,23 +203,15 @@ static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou if (note->waveform_buf.buf) { waveform = note->waveform_buf.buf; waveform_length = note->waveform_buf.len; - if (note->waveform_loop_start > 0 && note->waveform_loop_start < waveform_length) { - waveform_start = note->waveform_loop_start; - } - if (note->waveform_loop_end > waveform_start && note->waveform_loop_end < waveform_length) { - waveform_length = note->waveform_loop_end; - } + waveform_start = (uint32_t)synthio_block_slot_get_limited(¬e->waveform_loop_start, 0, waveform_length - 1); + waveform_length = (uint32_t)synthio_block_slot_get_limited(¬e->waveform_loop_end, waveform_start + 1, waveform_length); } dds_rate = synthio_frequency_convert_scaled_to_dds((uint64_t)frequency_scaled * (waveform_length - waveform_start), sample_rate); if (note->ring_frequency_scaled != 0 && note->ring_waveform_buf.buf) { ring_waveform = note->ring_waveform_buf.buf; ring_waveform_length = note->ring_waveform_buf.len; - if (note->ring_waveform_loop_start > 0 && note->ring_waveform_loop_start < ring_waveform_length) { - ring_waveform_start = note->waveform_loop_start; - } - if (note->ring_waveform_loop_end > ring_waveform_start && note->ring_waveform_loop_end < ring_waveform_length) { - ring_waveform_length = note->ring_waveform_loop_end; - } + ring_waveform_start = (uint32_t)synthio_block_slot_get_limited(¬e->ring_waveform_loop_start, 0, ring_waveform_length - 1); + ring_waveform_length = (uint32_t)synthio_block_slot_get_limited(¬e->ring_waveform_loop_end, ring_waveform_start + 1, ring_waveform_length); ring_dds_rate = synthio_frequency_convert_scaled_to_dds((uint64_t)note->ring_frequency_bent * (ring_waveform_length - ring_waveform_start), sample_rate); uint32_t lim = ring_waveform_length << SYNTHIO_FREQUENCY_SHIFT; if (ring_dds_rate > lim / sizeof(int16_t)) { @@ -259,7 +270,7 @@ static bool synth_note_into_buffer(synthio_synth_t *synth, int chan, int32_t *ou accum = accum - lim + offset; } int16_t idx = accum >> SYNTHIO_FREQUENCY_SHIFT; - int16_t wi = (ring_waveform[idx] * out_buffer32[i]) / 32768; + int16_t wi = (ring_waveform[idx] * out_buffer32[i]) / 32768; // consider for synthio_sat16 but had a weird artificat out_buffer32[i] = wi; } synth->ring_accum[chan] = accum; @@ -278,17 +289,54 @@ static mp_obj_t synthio_synth_get_note_filter(mp_obj_t note_obj) { return mp_const_none; } -static void sum_with_loudness(int32_t *out_buffer32, int32_t *tmp_buffer32, int16_t loudness[2], size_t dur, int synth_chan) { +// Rather than immediately changing the loudness of audio playback, we keep a separate buffer of +// the "active" loudness and wait until we meet the conditions of a "zero crossing". A zero crossing +// occurs when either the current value is 0 or the value changes from negative to positive or +// vice-versa. This is detected by keeping a copy of the previous frame of audio data and checking +// to see if the sign of the value has changed. By only changing loudness during zero crossings, we +// avoid audible pops/clicks which can be unpleasant. +static void assign_loudness(int32_t word, int32_t *last_word, int16_t active_loudness[2], int16_t pending_loudness[2]) { + // If the active loudness already matches the pending loudness, exit early. + if (MP_LIKELY(active_loudness[0] == pending_loudness[0]) && MP_LIKELY(active_loudness[1] == pending_loudness[1])) { + return; + } + + // Check for a zero crossing: current value is 0 or has changed sign from the previous value. + if (word == 0 || (*last_word != 0 && ((*last_word > 0) == (word < 0) || (*last_word < 0) == (word > 0)))) { + // Copy over our pending loudness. Will cause future calls to `assign_loudness` to exit + // early. + active_loudness[0] = pending_loudness[0]; + active_loudness[1] = pending_loudness[1]; + } else { + // Update our copy of the previous word for future comparisons (an initial value of 0 is + // ignored). + *last_word = word; + } +} + +static void sum_with_loudness(int32_t *out_buffer32, int32_t *tmp_buffer32, int16_t active_loudness[2], int16_t pending_loudness[2], size_t dur, int synth_chan) { + int32_t word, last_word = 0; if (synth_chan == 1) { for (size_t i = 0; i < dur; i++) { - *out_buffer32++ += (*tmp_buffer32++ *loudness[0]) >> 16; + word = *tmp_buffer32++; + assign_loudness(word, &last_word, active_loudness, pending_loudness); + *out_buffer32++ += synthio_sat16((word * active_loudness[0]), 16); } } else { for (size_t i = 0; i < dur; i++) { - *out_buffer32++ += (*tmp_buffer32 * loudness[0]) >> 16; - *out_buffer32++ += (*tmp_buffer32++ *loudness[1]) >> 16; + word = *tmp_buffer32; + assign_loudness(word, &last_word, active_loudness, pending_loudness); + *out_buffer32++ += synthio_sat16((word * active_loudness[0]), 16); + *out_buffer32++ += synthio_sat16((word * active_loudness[1]), 16); + tmp_buffer32++; } } + + // Force the active loudness to match the pending loudness just in case the conditions of a + // zero crossing weren't met within the last `SYNTHIO_MAX_DUR` frames. Will ensure minimal + // delay in amplitude or panning changes at the potential expensive of an audible pop. + active_loudness[0] = pending_loudness[0]; + active_loudness[1] = pending_loudness[1]; } void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t *buffer_length, uint8_t channel) { @@ -299,7 +347,7 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t return; } - shared_bindings_synthio_lfo_tick(synth->sample_rate); + shared_bindings_synthio_lfo_tick(synth->base.sample_rate, SYNTHIO_MAX_DUR); synth->buffer_index = !synth->buffer_index; synth->other_channel = 1 - channel; @@ -308,9 +356,9 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t uint16_t dur = MIN(SYNTHIO_MAX_DUR, synth->span.dur); synth->span.dur -= dur; - int32_t out_buffer32[SYNTHIO_MAX_DUR * synth->channel_count]; + int32_t out_buffer32[SYNTHIO_MAX_DUR * synth->base.channel_count]; int32_t tmp_buffer32[SYNTHIO_MAX_DUR]; - memset(out_buffer32, 0, synth->channel_count * dur * sizeof(int32_t)); + memset(out_buffer32, 0, synth->base.channel_count * dur * sizeof(int32_t)); for (int chan = 0; chan < CIRCUITPY_SYNTHIO_MAX_CHANNELS; chan++) { mp_obj_t note_obj = synth->span.note_obj[chan]; @@ -335,19 +383,20 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t mp_obj_t filter_obj = synthio_synth_get_note_filter(note_obj); if (filter_obj != mp_const_none) { synthio_note_obj_t *note = MP_OBJ_TO_PTR(note_obj); - synthio_biquad_filter_samples(¬e->filter_state, tmp_buffer32, dur); + common_hal_synthio_biquad_tick(filter_obj); + synthio_biquad_filter_samples(filter_obj, ¬e->filter_state, tmp_buffer32, dur); } // adjust loudness by envelope - sum_with_loudness(out_buffer32, tmp_buffer32, loudness, dur, synth->channel_count); + sum_with_loudness(out_buffer32, tmp_buffer32, synth->active_loudness[chan], loudness, dur, synth->base.channel_count); } int16_t *out_buffer16 = (int16_t *)(void *)synth->buffers[synth->buffer_index]; // mix down audio - for (size_t i = 0; i < dur * synth->channel_count; i++) { + for (size_t i = 0; i < dur * synth->base.channel_count; i++) { int32_t sample = out_buffer32[i]; - out_buffer16[i] = mix_down_sample(sample); + out_buffer16[i] = synthio_mix_down_sample(sample, SYNTHIO_MIX_DOWN_SCALE(CIRCUITPY_SYNTHIO_MAX_CHANNELS)); } // advance envelope states @@ -359,7 +408,7 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **bufptr, uint32_t synthio_envelope_state_step(&synth->envelope_state[chan], synthio_synth_get_note_envelope(synth, note_obj), dur); } - *buffer_length = synth->last_buffer_length = dur * SYNTHIO_BYTES_PER_SAMPLE * synth->channel_count; + *buffer_length = synth->last_buffer_length = dur * SYNTHIO_BYTES_PER_SAMPLE * synth->base.channel_count; *bufptr = (uint8_t *)out_buffer16; } @@ -370,17 +419,14 @@ void synthio_synth_reset_buffer(synthio_synth_t *synth, bool single_channel_outp synth->other_channel = -1; } -bool synthio_synth_deinited(synthio_synth_t *synth) { - return synth->buffers[0] == NULL; -} - void synthio_synth_deinit(synthio_synth_t *synth) { synth->buffers[0] = NULL; synth->buffers[1] = NULL; + audiosample_mark_deinit(&synth->base); } void synthio_synth_envelope_set(synthio_synth_t *synth, mp_obj_t envelope_obj) { - synthio_envelope_definition_set(&synth->global_envelope_definition, envelope_obj, synth->sample_rate); + synthio_envelope_definition_set(&synth->global_envelope_definition, envelope_obj, synth->base.sample_rate); synth->envelope_obj = envelope_obj; } @@ -392,12 +438,16 @@ void synthio_synth_init(synthio_synth_t *synth, uint32_t sample_rate, int channe synthio_synth_parse_waveform(&synth->waveform_bufinfo, waveform_obj); mp_arg_validate_int_range(channel_count, 1, 2, MP_QSTR_channel_count); synth->buffer_length = SYNTHIO_MAX_DUR * SYNTHIO_BYTES_PER_SAMPLE * channel_count; - synth->buffers[0] = m_malloc(synth->buffer_length); - synth->buffers[1] = m_malloc(synth->buffer_length); - synth->channel_count = channel_count; + synth->buffers[0] = m_malloc_without_collect(synth->buffer_length); + synth->buffers[1] = m_malloc_without_collect(synth->buffer_length); + synth->base.channel_count = channel_count; + synth->base.single_buffer = false; synth->other_channel = -1; synth->waveform_obj = waveform_obj; - synth->sample_rate = sample_rate; + synth->base.sample_rate = sample_rate; + synth->base.bits_per_sample = 16; + synth->base.samples_signed = true; + synth->base.max_buffer_length = synth->buffer_length; synthio_synth_envelope_set(synth, envelope_obj); for (size_t i = 0; i < CIRCUITPY_SYNTHIO_MAX_CHANNELS; i++) { @@ -405,18 +455,6 @@ void synthio_synth_init(synthio_synth_t *synth, uint32_t sample_rate, int channe } } -void synthio_synth_get_buffer_structure(synthio_synth_t *synth, bool single_channel_output, - bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing) { - *single_buffer = false; - *samples_signed = true; - *max_buffer_length = synth->buffer_length; - if (single_channel_output) { - *spacing = synth->channel_count; - } else { - *spacing = 1; - } -} - static void parse_common(mp_buffer_info_t *bufinfo, mp_obj_t o, int16_t what, mp_int_t max_len) { if (o != mp_const_none) { mp_get_buffer_raise(o, bufinfo, MP_BUFFER_READ); @@ -489,8 +527,10 @@ uint32_t synthio_frequency_convert_scaled_to_dds(uint64_t frequency_scaled, int3 return (sample_rate / 2 + frequency_scaled) / sample_rate; } -void shared_bindings_synthio_lfo_tick(uint32_t sample_rate) { - synthio_global_rate_scale = (mp_float_t)SYNTHIO_MAX_DUR / sample_rate; +void shared_bindings_synthio_lfo_tick(uint32_t sample_rate, uint16_t num_samples) { + mp_float_t recip_sample_rate = MICROPY_FLOAT_CONST(1.) / sample_rate; + synthio_global_rate_scale = num_samples * recip_sample_rate; + synthio_global_W_scale = (2 * MP_PI) * recip_sample_rate; synthio_global_tick++; } diff --git a/shared-module/synthio/__init__.h b/shared-module/synthio/__init__.h index b0bca1efcff..0335831f80f 100644 --- a/shared-module/synthio/__init__.h +++ b/shared-module/synthio/__init__.h @@ -14,8 +14,13 @@ #define SYNTHIO_NOTE_IS_PLAYING(synth, i) ((synth)->envelope_state[(i)].state != SYNTHIO_ENVELOPE_STATE_RELEASE) #define SYNTHIO_FREQUENCY_SHIFT (16) +#define SYNTHIO_MIX_DOWN_RANGE_LOW (-28000) +#define SYNTHIO_MIX_DOWN_RANGE_HIGH (28000) +#define SYNTHIO_MIX_DOWN_SCALE(x) (0xfffffff / (32768 * x - SYNTHIO_MIX_DOWN_RANGE_HIGH)) + #include "shared-module/audiocore/__init__.h" #include "shared-bindings/synthio/__init__.h" +#include "shared-bindings/synthio/Biquad.h" typedef struct { uint16_t dur; @@ -37,10 +42,9 @@ typedef struct { } synthio_envelope_state_t; typedef struct synthio_synth { - uint32_t sample_rate; + audiosample_base_t base; uint32_t total_envelope; int16_t *buffers[2]; - uint8_t channel_count; uint16_t buffer_length; uint16_t last_buffer_length; uint8_t other_channel, buffer_index, other_buffer_index; @@ -51,6 +55,7 @@ typedef struct synthio_synth { uint32_t accum[CIRCUITPY_SYNTHIO_MAX_CHANNELS]; uint32_t ring_accum[CIRCUITPY_SYNTHIO_MAX_CHANNELS]; synthio_envelope_state_t envelope_state[CIRCUITPY_SYNTHIO_MAX_CHANNELS]; + int16_t active_loudness[CIRCUITPY_SYNTHIO_MAX_CHANNELS][2]; } synthio_synth_t; typedef struct { @@ -67,8 +72,6 @@ void synthio_synth_synthesize(synthio_synth_t *synth, uint8_t **buffer, uint32_t void synthio_synth_deinit(synthio_synth_t *synth); bool synthio_synth_deinited(synthio_synth_t *synth); void synthio_synth_init(synthio_synth_t *synth, uint32_t sample_rate, int channel_count, mp_obj_t waveform_obj, mp_obj_t envelope); -void synthio_synth_get_buffer_structure(synthio_synth_t *synth, bool single_channel_output, - bool *single_buffer, bool *samples_signed, uint32_t *max_buffer_length, uint8_t *spacing); void synthio_synth_reset_buffer(synthio_synth_t *synth, bool single_channel_output, uint8_t channel); void synthio_synth_parse_waveform(mp_buffer_info_t *bufinfo_waveform, mp_obj_t waveform_obj); void synthio_synth_parse_filter(mp_buffer_info_t *bufinfo_filter, mp_obj_t filter_obj); @@ -79,6 +82,8 @@ bool synthio_span_change_note(synthio_synth_t *synth, mp_obj_t old_note, mp_obj_ void synthio_envelope_step(synthio_envelope_definition_t *definition, synthio_envelope_state_t *state, int n_samples); void synthio_envelope_definition_set(synthio_envelope_definition_t *envelope, mp_obj_t obj, uint32_t sample_rate); +int16_t synthio_mix_down_sample(int32_t sample, int32_t scale); + uint64_t synthio_frequency_convert_float_to_scaled(mp_float_t frequency_hz); uint32_t synthio_frequency_convert_float_to_dds(mp_float_t frequency_hz, int32_t sample_rate); uint32_t synthio_frequency_convert_scaled_to_dds(uint64_t frequency_scaled, int32_t sample_rate); @@ -88,6 +93,8 @@ int synthio_lfo_step(synthio_lfo_state_t *state, uint16_t dur); int synthio_sweep_step(synthio_lfo_state_t *state, uint16_t dur); int synthio_sweep_in_step(synthio_lfo_state_t *state, uint16_t dur); -extern mp_float_t synthio_global_rate_scale; +extern mp_float_t synthio_global_rate_scale, synthio_global_W_scale; extern uint8_t synthio_global_tick; -void shared_bindings_synthio_lfo_tick(uint32_t sample_rate); +void shared_bindings_synthio_lfo_tick(uint32_t sample_rate, uint16_t num_samples); + +int16_t synthio_sat16(int32_t n, int rshift); diff --git a/shared-module/terminalio/Terminal.c b/shared-module/terminalio/Terminal.c index e6f1cb23111..6e73804ea3a 100644 --- a/shared-module/terminalio/Terminal.c +++ b/shared-module/terminalio/Terminal.c @@ -8,21 +8,152 @@ #include "shared-module/fontio/BuiltinFont.h" #include "shared-bindings/displayio/TileGrid.h" +#include "shared-bindings/displayio/Palette.h" #include "shared-bindings/terminalio/Terminal.h" +#include "shared-bindings/fontio/BuiltinFont.h" +#if CIRCUITPY_LVFONTIO +#include "shared-bindings/lvfontio/OnDiskFont.h" +#endif #if CIRCUITPY_STATUS_BAR #include "shared-bindings/supervisor/__init__.h" #include "shared-bindings/supervisor/StatusBar.h" #endif +#include "supervisor/shared/serial.h" + +uint16_t terminalio_terminal_get_glyph_index(mp_obj_t font, mp_uint_t codepoint, bool *is_full_width) { + if (is_full_width != NULL) { + *is_full_width = false; // Default to not full width + } + + #if CIRCUITPY_LVFONTIO + if (mp_obj_is_type(font, &lvfontio_ondiskfont_type)) { + // For LV fonts, we need to cache the glyph first + lvfontio_ondiskfont_t *lv_font = MP_OBJ_TO_PTR(font); + bool full_width = false; + int16_t slot = common_hal_lvfontio_ondiskfont_cache_glyph(lv_font, codepoint, &full_width); + + if (is_full_width != NULL) { + *is_full_width = full_width; + } + + if (slot == -1) { + // Not found or couldn't cache + return 0xffff; + } + return (uint16_t)slot; + } + #endif + + #if CIRCUITPY_FONTIO + if (mp_obj_is_type(font, &fontio_builtinfont_type)) { + // Use the standard fontio function + fontio_builtinfont_t *fontio_font = MP_OBJ_TO_PTR(font); + uint8_t index = fontio_builtinfont_get_glyph_index(fontio_font, codepoint); + if (index == 0xff) { + return 0xffff; + } + return index; + } + #endif + + // Unsupported font type + return 0xffff; +} + +static void wrap_cursor(uint16_t width, uint16_t height, uint16_t *cursor_x, uint16_t *cursor_y) { + if (*cursor_x >= width) { + *cursor_y = *cursor_y + 1; + *cursor_x %= width; + } + if (*cursor_y >= height) { + *cursor_y %= height; + } +} + +static void release_current_glyph(displayio_tilegrid_t *tilegrid, mp_obj_t font, uint16_t x, uint16_t y) { + #if CIRCUITPY_LVFONTIO + if (!mp_obj_is_type(font, &lvfontio_ondiskfont_type)) { + return; + } + uint16_t current_tile = common_hal_displayio_tilegrid_get_tile(tilegrid, x, y); + if (current_tile == 0) { + } + common_hal_lvfontio_ondiskfont_release_glyph(MP_OBJ_TO_PTR(font), current_tile); + #endif +} + +static void terminalio_terminal_set_tile(terminalio_terminal_obj_t *self, bool status_bar, mp_uint_t character, bool release_glyphs) { + displayio_tilegrid_t *tilegrid = self->scroll_area; + uint16_t *x = &self->cursor_x; + uint16_t *y = &self->cursor_y; + uint16_t w = self->scroll_area->width_in_tiles; + uint16_t h = self->scroll_area->height_in_tiles; + if (status_bar) { + tilegrid = self->status_bar; + x = &self->status_x; + y = &self->status_y; + w = self->status_bar->width_in_tiles; + h = self->status_bar->height_in_tiles; + } + if (release_glyphs) { + release_current_glyph(tilegrid, self->font, *x, *y); + } + bool is_full_width; + uint16_t new_tile = terminalio_terminal_get_glyph_index(self->font, character, &is_full_width); + if (new_tile == 0xffff) { + // Missing glyph. + return; + } + // If there is only half width left, then fill it with a space and wrap to the next line. + if (is_full_width && *x == w - 1) { + uint16_t space = terminalio_terminal_get_glyph_index(self->font, ' ', NULL); + common_hal_displayio_tilegrid_set_tile(tilegrid, *x, *y, space); + *x = *x + 1; + wrap_cursor(w, h, x, y); + if (release_glyphs) { + release_current_glyph(tilegrid, self->font, *x, *y); + } + } + common_hal_displayio_tilegrid_set_tile(tilegrid, *x, *y, new_tile); + *x = *x + 1; + wrap_cursor(w, h, x, y); + if (is_full_width) { + if (release_glyphs) { + release_current_glyph(tilegrid, self->font, *x, *y); + } + common_hal_displayio_tilegrid_set_tile(tilegrid, *x, *y, new_tile + 1); + *x = *x + 1; + wrap_cursor(w, h, x, y); + } +} + +// Helper function to set all tiles in a tilegrid with optional glyph release +static void terminalio_terminal_set_all_tiles(terminalio_terminal_obj_t *self, bool status_bar, mp_uint_t character, bool release_glyphs) { + uint16_t *x = &self->cursor_x; + uint16_t *y = &self->cursor_y; + if (status_bar) { + x = &self->status_x; + y = &self->status_y; + } + *x = 0; + *y = 0; + terminalio_terminal_set_tile(self, status_bar, character, release_glyphs); + while (*x != 0 || *y != 0) { + terminalio_terminal_set_tile(self, status_bar, character, release_glyphs); + } +} + void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self) { if (self->status_bar) { - common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0); + terminalio_terminal_set_all_tiles(self, true, ' ', true); } } + void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, - displayio_tilegrid_t *scroll_area, const fontio_builtinfont_t *font, + displayio_tilegrid_t *scroll_area, mp_obj_t font, displayio_tilegrid_t *status_bar) { self->cursor_x = 0; self->cursor_y = 0; @@ -32,20 +163,43 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self, self->status_x = 0; self->status_y = 0; self->first_row = 0; - common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0); + self->vt_scroll_top = 0; + self->vt_scroll_end = self->scroll_area->height_in_tiles - 1; + terminalio_terminal_set_all_tiles(self, false, ' ', false); if (self->status_bar) { - common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0); + terminalio_terminal_set_all_tiles(self, true, ' ', false); } common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 1); } size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) { + #define SCRNMOD(x) (((x) + (self->scroll_area->top_left_y)) % (self->scroll_area->height_in_tiles)) + // Make sure the terminal is initialized before we do anything with it. if (self->scroll_area == NULL) { return len; } + #if CIRCUITPY_TERMINALIO_VT100 + uint32_t _select_color(uint16_t ascii_color) { + uint32_t color_value = 0; + if ((ascii_color & 1) > 0) { + color_value += 0xff0000; + } + if ((ascii_color & 2) > 0) { + color_value += 0x00ff00; + } + if ((ascii_color & 4) > 0) { + color_value += 0x0000ff; + } + + return color_value; + } + + displayio_palette_t *terminal_palette = self->scroll_area->pixel_shader; + #endif + const byte *i = data; uint16_t start_y = self->cursor_y; while (i < data + len) { @@ -61,30 +215,21 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con self->osc_command == 0 && self->status_bar != NULL && self->status_y < self->status_bar->height_in_tiles) { - uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c); - if (tile_index != 0xff) { - // Clear the tile grid before we start putting new info. - if (self->status_x == 0 && self->status_y == 0) { - common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0); - } - common_hal_displayio_tilegrid_set_tile(self->status_bar, self->status_x, self->status_y, tile_index); - self->status_x++; - if (self->status_x >= self->status_bar->width_in_tiles) { - self->status_y++; - self->status_x %= self->status_bar->width_in_tiles; - } + // Clear the tile grid before we start putting new info. + if (self->status_x == 0 && self->status_y == 0) { + terminalio_terminal_set_all_tiles(self, true, ' ', true); } + terminalio_terminal_set_tile(self, true, c, true); } continue; } - // Always handle ASCII. - if (c < 128) { - if (c >= 0x20 && c <= 0x7e) { - uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c); - common_hal_displayio_tilegrid_set_tile(self->scroll_area, self->cursor_x, self->cursor_y, tile_index); - self->cursor_x++; - } else if (c == '\r') { + if (c < 0x20) { + if (c == '\r') { self->cursor_x = 0; + } else if (c == '\t') { + for (uint8_t space_i = 0; space_i < 4; space_i++) { + terminalio_terminal_set_tile(self, false, ' ', true); + } } else if (c == '\n') { self->cursor_y++; // Commands below are used by MicroPython in the REPL @@ -94,84 +239,179 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con } } else if (c == 0x1b) { // Handle commands of the form [ESC]. where . is not yet known. - uint16_t n = 0; + int16_t vt_args[3] = {0, 0, 0}; uint8_t j = 1; + #if CIRCUITPY_TERMINALIO_VT100 + uint8_t n_args = 1; + #endif for (; j < 6; j++) { if ('0' <= i[j] && i[j] <= '9') { - n = n * 10 + (i[j] - '0'); + vt_args[0] = vt_args[0] * 10 + (i[j] - '0'); } else { c = i[j]; break; } } if (i[0] == '[') { - if (i[1] == 'K') { - // Clear the rest of the line. - for (uint16_t k = self->cursor_x; k < self->scroll_area->width_in_tiles; k++) { - common_hal_displayio_tilegrid_set_tile(self->scroll_area, k, self->cursor_y, 0); + for (uint8_t i_args = 1; i_args < 3 && c == ';'; i_args++) { + vt_args[i_args] = 0; + for (++j; j < 12; j++) { + if ('0' <= i[j] && i[j] <= '9') { + vt_args[i_args] = vt_args[i_args] * 10 + (i[j] - '0'); + #if CIRCUITPY_TERMINALIO_VT100 + n_args = i_args + 1; + #endif + } else { + c = i[j]; + break; + } } - i += 2; + } + if (c == '?') { + #if CIRCUITPY_TERMINALIO_VT100 + if (i[2] == '2' && i[3] == '5') { + // cursor visibility commands + if (i[4] == 'h') { + // make cursor visible + // not implemented yet + } else if (i[4] == 'l') { + // make cursor invisible + // not implemented yet + } + } + i += 5; + #endif } else { - if (c == 'D') { - if (n > self->cursor_x) { + if (c == 'K') { + int16_t original_cursor_x = self->cursor_x; + int16_t original_cursor_y = self->cursor_y; + int16_t clr_start = self->cursor_x; + int16_t clr_end = self->scroll_area->width_in_tiles; + #if CIRCUITPY_TERMINALIO_VT100 + if (vt_args[0] == 1) { + clr_start = 0; + clr_end = self->cursor_x; + } else if (vt_args[0] == 2) { + clr_start = 0; + } + self->cursor_x = clr_start; + #endif + // Clear the (start/rest/all) of the line. + for (uint16_t k = clr_start; k < clr_end; k++) { + terminalio_terminal_set_tile(self, false, ' ', true); + } + self->cursor_x = original_cursor_x; + self->cursor_y = original_cursor_y; + } else if (c == 'D') { + if (vt_args[0] > self->cursor_x) { self->cursor_x = 0; } else { - self->cursor_x -= n; + self->cursor_x -= vt_args[0]; } - } - if (c == 'J') { - if (n == 2) { + } else if (c == 'J') { + if (vt_args[0] == 2) { common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, 0); self->cursor_x = self->cursor_y = start_y = 0; - n = 0; - common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0); + terminalio_terminal_set_all_tiles(self, false, ' ', true); } - } - if (c == ';') { - uint16_t m = 0; - for (++j; j < 9; j++) { - if ('0' <= i[j] && i[j] <= '9') { - m = m * 10 + (i[j] - '0'); - } else { - c = i[j]; - break; - } + } else if (c == 'H') { + if (vt_args[0] > 0) { + vt_args[0]--; } - if (c == 'H') { - if (n > 0) { - n--; - } - if (m > 0) { - m--; - } - if (n >= self->scroll_area->height_in_tiles) { - n = self->scroll_area->height_in_tiles - 1; + if (vt_args[1] > 0) { + vt_args[1]--; + } + if (vt_args[0] >= self->scroll_area->height_in_tiles) { + vt_args[0] = self->scroll_area->height_in_tiles - 1; + } + if (vt_args[1] >= self->scroll_area->width_in_tiles) { + vt_args[1] = self->scroll_area->width_in_tiles - 1; + } + vt_args[0] = SCRNMOD(vt_args[0]); + self->cursor_x = vt_args[1]; + self->cursor_y = vt_args[0]; + start_y = self->cursor_y; + #if CIRCUITPY_TERMINALIO_VT100 + } else if (c == 'm') { + for (uint8_t i_args = 0; i_args < n_args; i_args++) { + if ((vt_args[i_args] >= 40 && vt_args[i_args] <= 47) || (vt_args[i_args] >= 30 && vt_args[i_args] <= 37)) { + common_hal_displayio_palette_set_color(terminal_palette, 1 - (vt_args[i_args] / 40), _select_color(vt_args[i_args] % 10)); } - if (m >= self->scroll_area->width_in_tiles) { - m = self->scroll_area->width_in_tiles - 1; + if (vt_args[i_args] == 0) { + common_hal_displayio_palette_set_color(terminal_palette, 0, 0x000000); + common_hal_displayio_palette_set_color(terminal_palette, 1, 0xffffff); } - n = (n + self->scroll_area->top_left_y) % self->scroll_area->height_in_tiles; - self->cursor_x = m; - self->cursor_y = n; - start_y = self->cursor_y; } + } else if (c == 'r') { + if (vt_args[0] < vt_args[1] && vt_args[0] >= 1 && vt_args[1] <= self->scroll_area->height_in_tiles) { + self->vt_scroll_top = vt_args[0] - 1; + self->vt_scroll_end = vt_args[1] - 1; + } else { + self->vt_scroll_top = 0; + self->vt_scroll_end = self->scroll_area->height_in_tiles - 1; + } + self->cursor_x = 0; + self->cursor_y = self->scroll_area->top_left_y % self->scroll_area->height_in_tiles; + start_y = self->cursor_y; + #endif } i += j + 1; - continue; } + #if CIRCUITPY_TERMINALIO_VT100 + } else if (i[0] == 'M') { + if (self->cursor_y != SCRNMOD(self->vt_scroll_top)) { + if (self->cursor_y > 0) { + self->cursor_y = self->cursor_y - 1; + } else { + self->cursor_y = self->scroll_area->height_in_tiles - 1; + } + } else { + if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles - 1) { + // Scroll range defined, manually move tiles to perform scroll + for (int16_t irow = self->vt_scroll_end - 1; irow >= self->vt_scroll_top; irow--) { + for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) { + common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, SCRNMOD(irow + 1), common_hal_displayio_tilegrid_get_tile(self->scroll_area, icol, SCRNMOD(irow))); + } + } + self->cursor_x = 0; + int16_t old_y = self->cursor_y; + // Fill the row with spaces. + for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) { + terminalio_terminal_set_tile(self, false, ' ', true); + } + self->cursor_y = old_y; + } else { + // Full screen scroll, just set new top_y pointer and clear row + if (self->cursor_y > 0) { + common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, self->cursor_y - 1); + } else { + common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, self->scroll_area->height_in_tiles - 1); + } + + self->cursor_x = 0; + self->cursor_y = self->scroll_area->top_left_y; + // Fill the row with spaces. + for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) { + terminalio_terminal_set_tile(self, false, ' ', true); + } + self->cursor_y = self->scroll_area->top_left_y; + } + self->cursor_x = 0; + } + start_y = self->cursor_y; + i++; + } else if (i[0] == 'D') { + self->cursor_y++; + i++; + #endif } else if (i[0] == ']' && c == ';') { self->in_osc_command = true; - self->osc_command = n; + self->osc_command = vt_args[0]; i += j + 1; } } } else { - uint8_t tile_index = fontio_builtinfont_get_glyph_index(self->font, c); - if (tile_index != 0xff) { - common_hal_displayio_tilegrid_set_tile(self->scroll_area, self->cursor_x, self->cursor_y, tile_index); - self->cursor_x++; - - } + terminalio_terminal_set_tile(self, false, c, true); } if (self->cursor_x >= self->scroll_area->width_in_tiles) { self->cursor_y++; @@ -181,12 +421,31 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con self->cursor_y %= self->scroll_area->height_in_tiles; } if (self->cursor_y != start_y) { - // clear the new row in case of scroll up - if (self->cursor_y == self->scroll_area->top_left_y) { - for (uint16_t j = 0; j < self->scroll_area->width_in_tiles; j++) { - common_hal_displayio_tilegrid_set_tile(self->scroll_area, j, self->cursor_y, 0); + if (((self->cursor_y + self->scroll_area->height_in_tiles) - 1) % self->scroll_area->height_in_tiles == SCRNMOD(self->vt_scroll_end)) { + #if CIRCUITPY_TERMINALIO_VT100 + if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles - 1) { + // Scroll range defined, manually move tiles to perform scroll + self->cursor_y = SCRNMOD(self->vt_scroll_end); + + for (int16_t irow = self->vt_scroll_top; irow < self->vt_scroll_end; irow++) { + for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) { + common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, SCRNMOD(irow), common_hal_displayio_tilegrid_get_tile(self->scroll_area, icol, SCRNMOD(irow + 1))); + } + } + } + #endif + if (self->vt_scroll_top == 0 && self->vt_scroll_end == self->scroll_area->height_in_tiles - 1) { + // Full screen scroll, just set new top_y pointer + common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, (self->cursor_y + self->scroll_area->height_in_tiles + 1) % self->scroll_area->height_in_tiles); } - common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, (self->cursor_y + self->scroll_area->height_in_tiles + 1) % self->scroll_area->height_in_tiles); + // clear the new row in case of scroll up + self->cursor_x = 0; + int16_t old_y = self->cursor_y; + for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) { + terminalio_terminal_set_tile(self, false, ' ', true); + } + self->cursor_x = 0; + self->cursor_y = old_y; } start_y = self->cursor_y; } @@ -194,6 +453,13 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con return i - data; } +uint16_t common_hal_terminalio_terminal_get_cursor_x(terminalio_terminal_obj_t *self) { + return self->cursor_x; +} +uint16_t common_hal_terminalio_terminal_get_cursor_y(terminalio_terminal_obj_t *self) { + return self->cursor_y; +} + bool common_hal_terminalio_terminal_ready_to_tx(terminalio_terminal_obj_t *self) { return self->scroll_area != NULL; } diff --git a/shared-module/terminalio/Terminal.h b/shared-module/terminalio/Terminal.h index 17230a74066..8bf294cb27f 100644 --- a/shared-module/terminalio/Terminal.h +++ b/shared-module/terminalio/Terminal.h @@ -15,7 +15,7 @@ typedef struct { mp_obj_base_t base; - const fontio_builtinfont_t *font; + mp_obj_t font; // Can be fontio_builtinfont_t or lvfontio_ondiskfont_t uint16_t cursor_x; uint16_t cursor_y; displayio_tilegrid_t *scroll_area; @@ -23,8 +23,11 @@ typedef struct { uint16_t status_x; uint16_t status_y; uint16_t first_row; + uint16_t vt_scroll_top; + uint16_t vt_scroll_end; uint16_t osc_command; bool in_osc_command; } terminalio_terminal_obj_t; extern void terminalio_terminal_clear_status_bar(terminalio_terminal_obj_t *self); +uint16_t terminalio_terminal_get_glyph_index(mp_obj_t font, mp_uint_t codepoint, bool *is_full_width); diff --git a/shared-module/tilepalettemapper/TilePaletteMapper.c b/shared-module/tilepalettemapper/TilePaletteMapper.c new file mode 100644 index 00000000000..13711b2c253 --- /dev/null +++ b/shared-module/tilepalettemapper/TilePaletteMapper.c @@ -0,0 +1,104 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT +#include +#include "py/runtime.h" +#include "shared-bindings/tilepalettemapper/TilePaletteMapper.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/TileGrid.h" + +void common_hal_tilepalettemapper_tilepalettemapper_construct(tilepalettemapper_tilepalettemapper_t *self, + mp_obj_t pixel_shader, uint16_t input_color_count) { + self->pixel_shader = pixel_shader; + self->input_color_count = input_color_count; + self->tilegrid = mp_const_none; +} + +uint16_t common_hal_tilepalettemapper_tilepalettemapper_get_width(tilepalettemapper_tilepalettemapper_t *self) { + return self->width_in_tiles; +} + +uint16_t common_hal_tilepalettemapper_tilepalettemapper_get_height(tilepalettemapper_tilepalettemapper_t *self) { + return self->height_in_tiles; +} + +mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_pixel_shader(tilepalettemapper_tilepalettemapper_t *self) { + return self->pixel_shader; +} + +mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_tilegrid(tilepalettemapper_tilepalettemapper_t *self) { + return self->tilegrid; +} + +mp_obj_t common_hal_tilepalettemapper_tilepalettemapper_get_mapping(tilepalettemapper_tilepalettemapper_t *self, uint16_t x, uint16_t y) { + int index = x + y * self->width_in_tiles; + mp_obj_t result[self->input_color_count]; + for (uint32_t i = 0; i < self->input_color_count; i++) { + result[i] = mp_obj_new_int(self->tile_mappings[index][i]); + } + return mp_obj_new_tuple(self->input_color_count, result); +} + +void common_hal_tilepalettemapper_tilepalettemapper_set_mapping(tilepalettemapper_tilepalettemapper_t *self, uint16_t x, uint16_t y, size_t len, mp_obj_t *items) { + uint32_t palette_max; + if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { + palette_max = common_hal_displayio_palette_get_len(self->pixel_shader) - 1; + } else { // colorconverter type + palette_max = 0xFFFFFF; + } + + for (uint16_t i = 0; i < MIN(len, self->input_color_count); i++) { + int mapping_val = mp_arg_validate_type_int(items[i], MP_QSTR_mapping_value); + mp_arg_validate_int_range(mapping_val, 0, palette_max, MP_QSTR_mapping_value); + self->tile_mappings[y * self->width_in_tiles + x][i] = mapping_val; + } + displayio_tilegrid_mark_tile_dirty(self->tilegrid, x, y); +} + +void tilepalettemapper_tilepalettemapper_get_color(tilepalettemapper_tilepalettemapper_t *self, const _displayio_colorspace_t *colorspace, displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color, uint16_t x_tile_index, uint16_t y_tile_index) { + if (x_tile_index >= self->width_in_tiles || y_tile_index >= self->height_in_tiles) { + if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { + displayio_palette_get_color(self->pixel_shader, colorspace, input_pixel, output_color); + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { + displayio_colorconverter_convert(self->pixel_shader, colorspace, input_pixel, output_color); + } + return; + } + uint16_t tile_index = y_tile_index * self->width_in_tiles + x_tile_index; + uint32_t mapped_index = self->tile_mappings[tile_index][input_pixel->pixel]; + displayio_input_pixel_t tmp_pixel; + tmp_pixel.pixel = mapped_index; + if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { + displayio_palette_get_color(self->pixel_shader, colorspace, &tmp_pixel, output_color); + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { + displayio_colorconverter_convert(self->pixel_shader, colorspace, &tmp_pixel, output_color); + } + +} + +void tilepalettemapper_tilepalettemapper_bind(tilepalettemapper_tilepalettemapper_t *self, displayio_tilegrid_t *tilegrid) { + if (self->tilegrid != mp_const_none) { + mp_raise_RuntimeError(MP_ERROR_TEXT("TilePaletteMapper may only be bound to a TileGrid once")); + } + self->tilegrid = tilegrid; + self->width_in_tiles = common_hal_displayio_tilegrid_get_width(tilegrid); + self->height_in_tiles = common_hal_displayio_tilegrid_get_height(tilegrid); + + int mappings_len = self->width_in_tiles * self->height_in_tiles; + self->tile_mappings = (uint32_t **)m_malloc(mappings_len * sizeof(uint32_t *)); + for (int i = 0; i < mappings_len; i++) { + self->tile_mappings[i] = (uint32_t *)m_malloc_without_collect(self->input_color_count * sizeof(uint32_t)); + if (mp_obj_is_type(self->pixel_shader, &displayio_palette_type)) { + for (uint16_t j = 0; j < self->input_color_count; j++) { + self->tile_mappings[i][j] = j; + } + } else if (mp_obj_is_type(self->pixel_shader, &displayio_colorconverter_type)) { + for (uint16_t j = 0; j < self->input_color_count; j++) { + self->tile_mappings[i][j] = 0; + } + } + } +} diff --git a/shared-module/tilepalettemapper/TilePaletteMapper.h b/shared-module/tilepalettemapper/TilePaletteMapper.h new file mode 100644 index 00000000000..d1f535eda11 --- /dev/null +++ b/shared-module/tilepalettemapper/TilePaletteMapper.h @@ -0,0 +1,28 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Tim Cocks for Adafruit Industries +// +// SPDX-License-Identifier: MIT + + +#pragma once + +#include +#include + +#include "py/obj.h" +#include "shared-module/displayio/Palette.h" +#include "shared-module/displayio/TileGrid.h" + +typedef struct { + mp_obj_base_t base; + mp_obj_t pixel_shader; + mp_obj_t tilegrid; + uint16_t width_in_tiles; + uint16_t height_in_tiles; + uint16_t input_color_count; + uint32_t **tile_mappings; +} tilepalettemapper_tilepalettemapper_t; + +void tilepalettemapper_tilepalettemapper_get_color(tilepalettemapper_tilepalettemapper_t *self, const _displayio_colorspace_t *colorspace, displayio_input_pixel_t *input_pixel, displayio_output_pixel_t *output_color, uint16_t x_tile_index, uint16_t y_tile_index); +void tilepalettemapper_tilepalettemapper_bind(tilepalettemapper_tilepalettemapper_t *self, displayio_tilegrid_t *tilegrid); diff --git a/shared-module/tilepalettemapper/__init__.c b/shared-module/tilepalettemapper/__init__.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/shared-module/touchio/TouchIn.c b/shared-module/touchio/TouchIn.c index 9334b369f65..268055d14bf 100644 --- a/shared-module/touchio/TouchIn.c +++ b/shared-module/touchio/TouchIn.c @@ -12,15 +12,18 @@ #include "py/mphal.h" #include "shared-bindings/touchio/TouchIn.h" #include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/Pull.h" -// This is a capacitive touch sensing routine using a single digital -// pin. The pin should be connected to the sensing pad, and to ground +// This is a capacitive touch sensing routine using a single digital pin. +// For pull==PULL_DOWN, the pin should be connected to the sensing pad and to ground // via a 1Mohm or thereabout drain resistor. When a reading is taken, // the pin's capacitance is charged by setting it to a digital output // 'high' for a few microseconds, and then it is changed to a high // impedance input. We measure how long it takes to discharge through // the resistor (around 50us), using a busy-waiting loop, and average // over N_SAMPLES cycles to reduce the effects of noise. +// For the pull=PULL_UP case, the 1M resistor is connected to 3v3, the pin is +// driven 'low' then measure how long it takes to go 'high'. #define N_SAMPLES 10 #define TIMEOUT_TICKS 10000 @@ -28,18 +31,19 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { uint16_t ticks = 0; - + // state to charge pin to: if pull-down or None, pull HIGH, if pull-up, pull LOW + bool pincharge = !(self->pull == PULL_UP); for (uint16_t i = 0; i < N_SAMPLES; i++) { - // set pad to digital output high for 10us to charge it + // set pad to digital output 'pincharge' for 10us to charge it - common_hal_digitalio_digitalinout_switch_to_output(self->digitalinout, true, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_switch_to_output(self->digitalinout, pincharge, DRIVE_MODE_PUSH_PULL); mp_hal_delay_us(10); // set pad back to an input and take some samples common_hal_digitalio_digitalinout_switch_to_input(self->digitalinout, PULL_NONE); - while (common_hal_digitalio_digitalinout_get_value(self->digitalinout)) { + while (common_hal_digitalio_digitalinout_get_value(self->digitalinout) == pincharge) { if (ticks >= TIMEOUT_TICKS) { return TIMEOUT_TICKS; } @@ -49,16 +53,22 @@ static uint16_t get_raw_reading(touchio_touchin_obj_t *self) { return ticks; } -void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin) { +void common_hal_touchio_touchin_construct(touchio_touchin_obj_t *self, const mcu_pin_obj_t *pin, const digitalio_pull_t pull) { common_hal_mcu_pin_claim(pin); self->digitalinout = mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type); common_hal_digitalio_digitalinout_construct(self->digitalinout, pin); + self->pull = pull; + uint16_t raw_reading = get_raw_reading(self); if (raw_reading == TIMEOUT_TICKS) { common_hal_touchio_touchin_deinit(self); - mp_raise_ValueError(MP_ERROR_TEXT("No pulldown on pin; 1Mohm recommended")); + if (self->pull == PULL_UP) { + mp_raise_ValueError(MP_ERROR_TEXT("No pullup on pin; 1Mohm recommended")); + } else { + mp_raise_ValueError(MP_ERROR_TEXT("No pulldown on pin; 1Mohm recommended")); + } } self->threshold = raw_reading * 1.05 + 100; } @@ -76,7 +86,7 @@ void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t *self) { self->digitalinout = MP_OBJ_NULL; } -void touchin_reset() { +void touchin_reset(void) { } bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) { diff --git a/shared-module/touchio/TouchIn.h b/shared-module/touchio/TouchIn.h index a03811a1823..1d35b904f35 100644 --- a/shared-module/touchio/TouchIn.h +++ b/shared-module/touchio/TouchIn.h @@ -15,6 +15,7 @@ typedef struct { mp_obj_base_t base; digitalio_digitalinout_obj_t *digitalinout; + digitalio_pull_t pull; uint16_t threshold; } touchio_touchin_obj_t; diff --git a/shared-module/usb/core/Device.c b/shared-module/usb/core/Device.c index 4ed0d410523..a3bb449e87e 100644 --- a/shared-module/usb/core/Device.c +++ b/shared-module/usb/core/Device.c @@ -1,17 +1,22 @@ // This file is part of the CircuitPython project: https://circuitpython.org // // SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2025 Sam Blenny // // SPDX-License-Identifier: MIT #include "shared-bindings/usb/core/Device.h" #include "tusb_config.h" +#include "supervisor/port.h" +#include "supervisor/port_heap.h" +#include "lib/tinyusb/src/host/hcd.h" #include "lib/tinyusb/src/host/usbh.h" #include "py/runtime.h" #include "shared/runtime/interrupt_char.h" #include "shared-bindings/usb/core/__init__.h" +#include "shared-bindings/usb/util/__init__.h" #include "shared-module/usb/utf16le.h" #include "supervisor/shared/tick.h" #include "supervisor/usb.h" @@ -30,34 +35,78 @@ void tuh_umount_cb(uint8_t dev_addr) { static xfer_result_t _xfer_result; static size_t _actual_len; -bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t device_number) { + +#if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE +// Helper to ensure buffer is DMA-capable for transfer operations +static uint8_t *_ensure_dma_buffer(usb_core_device_obj_t *self, const uint8_t *buffer, size_t len, bool for_write) { + if (port_buffer_is_dma_capable(buffer)) { + return (uint8_t *)buffer; // Already DMA-capable, use directly + } + + uint8_t *dma_buffer = port_malloc(len, true); // true = DMA capable + if (dma_buffer == NULL) { + return NULL; // Allocation failed + } + + // Copy data to DMA buffer if writing + if (for_write && buffer != NULL) { + memcpy(dma_buffer, buffer, len); + } + + return dma_buffer; +} + +#endif +bool common_hal_usb_core_device_construct(usb_core_device_obj_t *self, uint8_t device_address) { if (!tuh_inited()) { mp_raise_RuntimeError(MP_ERROR_TEXT("No usb host port initialized")); } - if (device_number == 0 || device_number > CFG_TUH_DEVICE_MAX + CFG_TUH_HUB) { + if (device_address == 0 || device_address > CFG_TUH_DEVICE_MAX + CFG_TUH_HUB) { return false; } - if ((_mounted_devices & (1 << device_number)) == 0) { + if ((_mounted_devices & (1 << device_address)) == 0) { return false; } - self->device_number = device_number; + self->device_address = device_address; self->first_langid = 0; - _xfer_result = 0xff; + _xfer_result = XFER_RESULT_INVALID; return true; } +bool common_hal_usb_core_device_deinited(usb_core_device_obj_t *self) { + return self->device_address == 0; +} + +void common_hal_usb_core_device_deinit(usb_core_device_obj_t *self) { + if (common_hal_usb_core_device_deinited(self)) { + return; + } + size_t open_size = sizeof(self->open_endpoints); + for (size_t i = 0; i < open_size; i++) { + if (self->open_endpoints[i] != 0) { + tuh_edpt_close(self->device_address, self->open_endpoints[i]); + self->open_endpoints[i] = 0; + } + } + self->device_address = 0; +} + uint16_t common_hal_usb_core_device_get_idVendor(usb_core_device_obj_t *self) { uint16_t vid; uint16_t pid; - tuh_vid_pid_get(self->device_number, &vid, &pid); + if (!tuh_vid_pid_get(self->device_address, &vid, &pid)) { + mp_raise_usb_core_USBError(NULL); + } return vid; } uint16_t common_hal_usb_core_device_get_idProduct(usb_core_device_obj_t *self) { uint16_t vid; uint16_t pid; - tuh_vid_pid_get(self->device_number, &vid, &pid); + if (!tuh_vid_pid_get(self->device_address, &vid, &pid)) { + mp_raise_usb_core_USBError(NULL); + } return pid; } @@ -71,14 +120,124 @@ static void _transfer_done_cb(tuh_xfer_t *xfer) { static bool _wait_for_callback(void) { while (!mp_hal_is_interrupted() && - _xfer_result == 0xff) { + _xfer_result == XFER_RESULT_INVALID) { + // The background tasks include TinyUSB which will call the function + // we provided above. In other words, the callback isn't in an interrupt. + RUN_BACKGROUND_TASKS; + } + if (mp_hal_is_interrupted()) { + // Handle case of VM being interrupted by Ctrl-C or autoreload + return false; + } + // Handle callback result code from TinyUSB + xfer_result_t result = _xfer_result; + _xfer_result = XFER_RESULT_INVALID; + switch (result) { + case XFER_RESULT_SUCCESS: + return true; + case XFER_RESULT_ABORTED: + case XFER_RESULT_FAILED: + mp_raise_usb_core_USBError(NULL); + break; + case XFER_RESULT_STALLED: + mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); + break; + case XFER_RESULT_TIMEOUT: + case XFER_RESULT_INVALID: + mp_raise_usb_core_USBTimeoutError(); + break; + } + return false; +} + +static void _prepare_for_transfer(void) { + // Prepare for transfer. Unless there is a timeout, these static globals will + // get modified by the _transfer_done_cb() callback when tinyusb finishes the + // transfer or encounters an error condition. + _xfer_result = XFER_RESULT_INVALID; + _actual_len = 0; +} + +static void _abort_transfer(tuh_xfer_t *xfer) { + bool aborted = tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); + if (aborted) { + // If the transfer was aborted, then we can continue. + return; + } + uint32_t start_time = supervisor_ticks_ms32(); + // If not, we need to wait for it to finish, otherwise we may free memory out from under it. + // Limit the wait time to 10 milliseconds to avoid blocking indefinitely. + while (_xfer_result == XFER_RESULT_INVALID && (supervisor_ticks_ms32() - start_time < 10)) { + // The background tasks include TinyUSB which will call the function + // we provided above. In other words, the callback isn't in an interrupt. + RUN_BACKGROUND_TASKS; + } +} + +// Only frees the transfer buffer on error. +static size_t _handle_timed_transfer_callback(tuh_xfer_t *xfer, mp_int_t timeout, bool our_buffer, bool raise_on_timeout) { + if (xfer == NULL) { + mp_raise_usb_core_USBError(NULL); + return 0; + } + uint32_t start_time = supervisor_ticks_ms32(); + while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && + !mp_hal_is_interrupted() && + _xfer_result == XFER_RESULT_INVALID) { // The background tasks include TinyUSB which will call the function // we provided above. In other words, the callback isn't in an interrupt. RUN_BACKGROUND_TASKS; } + if (mp_hal_is_interrupted()) { + // Handle case of VM being interrupted by Ctrl-C or autoreload + _abort_transfer(xfer); + return 0; + } + // Handle transfer result code from TinyUSB xfer_result_t result = _xfer_result; - _xfer_result = 0xff; - return result == XFER_RESULT_SUCCESS; + _xfer_result = XFER_RESULT_INVALID; + // Free the bounce buffer only on paths that raise: raising unwinds past + // the caller's cleanup, so it must be freed here. Paths that return + // normally leave ownership with the caller, which copies out of and + // frees the buffer itself (freeing on both sides would be a double free). + bool will_raise = result == XFER_RESULT_ABORTED || result == XFER_RESULT_FAILED || + result == XFER_RESULT_STALLED || + (result == XFER_RESULT_TIMEOUT && raise_on_timeout); + if (our_buffer && will_raise) { + port_free(xfer->buffer); + } + switch (result) { + case XFER_RESULT_SUCCESS: + return _actual_len; + case XFER_RESULT_ABORTED: + case XFER_RESULT_FAILED: + mp_raise_usb_core_USBError(NULL); + break; + case XFER_RESULT_STALLED: + mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); + break; + case XFER_RESULT_TIMEOUT: + // This timeout comes from TinyUSB, so assume that it has stopped the + // transfer (note: timeout logic may be unimplemented on TinyUSB side) + if (!raise_on_timeout) { + return 0; + } + mp_raise_usb_core_USBTimeoutError(); + break; + case XFER_RESULT_INVALID: + // This timeout comes from CircuitPython, not TinyUSB, so tell TinyUSB + // to stop the transfer. + _abort_transfer(xfer); + if (!raise_on_timeout) { + return 0; // the caller owns (and frees) the buffer + } + if (our_buffer) { + port_free(xfer->buffer); + } + mp_raise_usb_core_USBTimeoutError(); + break; + } + return 0; } static mp_obj_t _get_string(const uint16_t *temp_buf) { @@ -95,41 +254,124 @@ static void _get_langid(usb_core_device_obj_t *self) { } // Two control bytes and one uint16_t language code. uint16_t temp_buf[2]; - if (!tuh_descriptor_get_string(self->device_number, 0, 0, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { - return; + _prepare_for_transfer(); + if (!tuh_descriptor_get_string(self->device_address, 0, 0, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + self->first_langid = temp_buf[1]; } - self->first_langid = temp_buf[1]; } mp_obj_t common_hal_usb_core_device_get_serial_number(usb_core_device_obj_t *self) { uint16_t temp_buf[127]; - _get_langid(self); - if (!tuh_descriptor_get_serial_string(self->device_number, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { + tusb_desc_device_t descriptor; + // First, be sure not to ask TinyUSB for a non-existent string (avoid error) + if (!tuh_descriptor_get_device_local(self->device_address, &descriptor)) { + return mp_const_none; + } + if (descriptor.iSerialNumber == 0) { return mp_const_none; } - return _get_string(temp_buf); + // Device does provide this string, so continue + _get_langid(self); + _prepare_for_transfer(); + if (!tuh_descriptor_get_serial_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + return _get_string(temp_buf); + } + return mp_const_none; } mp_obj_t common_hal_usb_core_device_get_product(usb_core_device_obj_t *self) { uint16_t temp_buf[127]; - _get_langid(self); - if (!tuh_descriptor_get_product_string(self->device_number, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { + tusb_desc_device_t descriptor; + // First, be sure not to ask TinyUSB for a non-existent string (avoid error) + if (!tuh_descriptor_get_device_local(self->device_address, &descriptor)) { + return mp_const_none; + } + if (descriptor.iProduct == 0) { return mp_const_none; } - return _get_string(temp_buf); + // Device does provide this string, so continue + _get_langid(self); + _prepare_for_transfer(); + if (!tuh_descriptor_get_product_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + return _get_string(temp_buf); + } + return mp_const_none; } mp_obj_t common_hal_usb_core_device_get_manufacturer(usb_core_device_obj_t *self) { uint16_t temp_buf[127]; + tusb_desc_device_t descriptor; + // First, be sure not to ask TinyUSB for a non-existent string (avoid error) + if (!tuh_descriptor_get_device_local(self->device_address, &descriptor)) { + return mp_const_none; + } + if (descriptor.iManufacturer == 0) { + return mp_const_none; + } + // Device does provide this string, so continue _get_langid(self); - if (!tuh_descriptor_get_manufacturer_string(self->device_number, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0) || - !_wait_for_callback()) { + _prepare_for_transfer(); + if (!tuh_descriptor_get_manufacturer_string(self->device_address, self->first_langid, temp_buf, sizeof(temp_buf), _transfer_done_cb, 0)) { + mp_raise_usb_core_USBError(NULL); + } else if (_wait_for_callback()) { + return _get_string(temp_buf); + } + return mp_const_none; +} + + +mp_int_t common_hal_usb_core_device_get_bus(usb_core_device_obj_t *self) { + tuh_bus_info_t bus_info; + if (!tuh_bus_info_get(self->device_address, &bus_info)) { + return 0; + } + return bus_info.rhport; +} + +mp_obj_t common_hal_usb_core_device_get_port_numbers(usb_core_device_obj_t *self) { + tuh_bus_info_t bus_info; + if (!tuh_bus_info_get(self->device_address, &bus_info)) { + return mp_const_none; + } + if (bus_info.hub_addr == 0) { return mp_const_none; } - return _get_string(temp_buf); + // USB allows for 5 hubs deep chaining. So we're at most 5 ports deep. + mp_obj_t ports[5]; + size_t port_count = 0; + tuh_bus_info_t current_bus_info = bus_info; + while (current_bus_info.hub_addr != 0 && port_count < MP_ARRAY_SIZE(ports)) { + // Reverse the order of the ports so most downstream comes last. + ports[MP_ARRAY_SIZE(ports) - 1 - port_count] = MP_OBJ_NEW_SMALL_INT(current_bus_info.hub_port); + port_count++; + if (!tuh_bus_info_get(current_bus_info.hub_addr, ¤t_bus_info)) { + break; + } + } + return mp_obj_new_tuple(port_count, ports + (MP_ARRAY_SIZE(ports) - port_count)); +} + +mp_int_t common_hal_usb_core_device_get_speed(usb_core_device_obj_t *self) { + tuh_bus_info_t bus_info; + if (!tuh_bus_info_get(self->device_address, &bus_info)) { + return 0; + } + switch (bus_info.speed) { + case TUSB_SPEED_HIGH: + return PYUSB_SPEED_HIGH; + case TUSB_SPEED_FULL: + return PYUSB_SPEED_FULL; + case TUSB_SPEED_LOW: + return PYUSB_SPEED_LOW; + default: + return 0; + } } void common_hal_usb_core_device_set_configuration(usb_core_device_obj_t *self, mp_int_t configuration) { @@ -140,53 +382,33 @@ void common_hal_usb_core_device_set_configuration(usb_core_device_obj_t *self, m // Get only the config descriptor first. tusb_desc_configuration_t desc; - if (!tuh_descriptor_get_configuration(self->device_number, config_index, &desc, sizeof(desc), _transfer_done_cb, 0) || + if (!tuh_descriptor_get_configuration(self->device_address, config_index, &desc, sizeof(desc), _transfer_done_cb, 0) || !_wait_for_callback()) { return; } // Get the config descriptor plus interfaces and endpoints. self->configuration_descriptor = m_realloc(self->configuration_descriptor, desc.wTotalLength); - if (!tuh_descriptor_get_configuration(self->device_number, config_index, self->configuration_descriptor, desc.wTotalLength, _transfer_done_cb, 0) || + if (!tuh_descriptor_get_configuration(self->device_address, config_index, self->configuration_descriptor, desc.wTotalLength, _transfer_done_cb, 0) || !_wait_for_callback()) { return; } - tuh_configuration_set(self->device_number, configuration, _transfer_done_cb, 0); + tuh_configuration_set(self->device_address, configuration, _transfer_done_cb, 0); _wait_for_callback(); } -static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout) { - _xfer_result = 0xff; +// Raises an exception on failure. Returns the number of bytes transferred (maybe zero) on success. +static size_t _xfer(tuh_xfer_t *xfer, mp_int_t timeout, bool our_buffer, bool raise_on_timeout) { + _prepare_for_transfer(); xfer->complete_cb = _transfer_done_cb; if (!tuh_edpt_xfer(xfer)) { + if (our_buffer) { + port_free(xfer->buffer); + } mp_raise_usb_core_USBError(NULL); - } - uint32_t start_time = supervisor_ticks_ms32(); - while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && - !mp_hal_is_interrupted() && - _xfer_result == 0xff) { - // The background tasks include TinyUSB which will call the function - // we provided above. In other words, the callback isn't in an interrupt. - RUN_BACKGROUND_TASKS; - } - if (mp_hal_is_interrupted()) { - tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); return 0; } - xfer_result_t result = _xfer_result; - _xfer_result = 0xff; - if (result == XFER_RESULT_STALLED) { - mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); - } - if (result == 0xff) { - tuh_edpt_abort_xfer(xfer->daddr, xfer->ep_addr); - mp_raise_usb_core_USBTimeoutError(); - } - if (result == XFER_RESULT_SUCCESS) { - return _actual_len; - } - - return 0; + return _handle_timed_transfer_callback(xfer, timeout, our_buffer, raise_on_timeout); } static bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) { @@ -206,6 +428,7 @@ static bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) { if (self->configuration_descriptor == NULL) { mp_raise_usb_core_USBError(MP_ERROR_TEXT("No configuration set")); + return false; } tusb_desc_configuration_t *desc_cfg = (tusb_desc_configuration_t *)self->configuration_descriptor; @@ -230,7 +453,7 @@ static bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) { } tusb_desc_endpoint_t const *desc_ep = (tusb_desc_endpoint_t const *)p_desc; - bool open = tuh_edpt_open(self->device_number, desc_ep); + bool open = tuh_edpt_open(self->device_address, desc_ep); if (open) { self->open_endpoints[first_free] = endpoint; } @@ -240,25 +463,67 @@ static bool _open_endpoint(usb_core_device_obj_t *self, mp_int_t endpoint) { mp_int_t common_hal_usb_core_device_write(usb_core_device_obj_t *self, mp_int_t endpoint, const uint8_t *buffer, mp_int_t len, mp_int_t timeout) { if (!_open_endpoint(self, endpoint)) { mp_raise_usb_core_USBError(NULL); + return 0; } + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Ensure buffer is in DMA-capable memory + uint8_t *dma_buffer = _ensure_dma_buffer(self, buffer, len, true); // true = for write + if (dma_buffer == NULL) { + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Could not allocate DMA capable buffer")); + return 0; + } + #else + uint8_t *dma_buffer = (uint8_t *)buffer; // All memory is DMA-capable + #endif + tuh_xfer_t xfer; - xfer.daddr = self->device_number; + xfer.daddr = self->device_address; xfer.ep_addr = endpoint; - xfer.buffer = (uint8_t *)buffer; + xfer.buffer = dma_buffer; xfer.buflen = len; - return _xfer(&xfer, timeout); + size_t result = _xfer(&xfer, timeout, dma_buffer != buffer, true); + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + if (dma_buffer != buffer) { + port_free(dma_buffer); + } + #endif + return result; } -mp_int_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t endpoint, uint8_t *buffer, mp_int_t len, mp_int_t timeout) { +mp_int_t common_hal_usb_core_device_read(usb_core_device_obj_t *self, mp_int_t endpoint, uint8_t *buffer, mp_int_t len, mp_int_t timeout, bool raise_on_timeout) { if (!_open_endpoint(self, endpoint)) { mp_raise_usb_core_USBError(NULL); + return 0; + } + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Ensure buffer is in DMA-capable memory + uint8_t *dma_buffer = _ensure_dma_buffer(self, buffer, len, false); // false = for read + if (dma_buffer == NULL) { + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Could not allocate DMA capable buffer")); + return 0; } + #else + uint8_t *dma_buffer = buffer; // All memory is DMA-capable + #endif + tuh_xfer_t xfer; - xfer.daddr = self->device_number; + xfer.daddr = self->device_address; xfer.ep_addr = endpoint; - xfer.buffer = buffer; + xfer.buffer = dma_buffer; xfer.buflen = len; - return _xfer(&xfer, timeout); + mp_int_t result = _xfer(&xfer, timeout, dma_buffer != buffer, raise_on_timeout); + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Copy data back to original buffer if needed + if (dma_buffer != buffer) { + memcpy(buffer, dma_buffer, result); + port_free(dma_buffer); + } + #endif + + return result; } mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, @@ -267,6 +532,23 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, uint8_t *buffer, mp_int_t len, mp_int_t timeout) { // Timeout is in ms. + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + // Determine if this is a write (host-to-device) or read (device-to-host) transfer + bool is_write = (bmRequestType & 0x80) == 0; // Bit 7: 0=host-to-device, 1=device-to-host + + // Ensure buffer is in DMA-capable memory + uint8_t *dma_buffer = NULL; + if (len > 0 && buffer != NULL) { + dma_buffer = _ensure_dma_buffer(self, buffer, len, is_write); + if (dma_buffer == NULL) { + mp_raise_msg(&mp_type_MemoryError, MP_ERROR_TEXT("Could not allocate DMA capable buffer")); + return 0; + } + } + #else + uint8_t *dma_buffer = buffer; // All memory is DMA-capable + #endif + tusb_control_request_t request = { .bmRequestType = bmRequestType, .bRequest = bRequest, @@ -275,49 +557,36 @@ mp_int_t common_hal_usb_core_device_ctrl_transfer(usb_core_device_obj_t *self, .wLength = len }; tuh_xfer_t xfer = { - .daddr = self->device_number, + .daddr = self->device_address, .ep_addr = 0, .setup = &request, - .buffer = buffer, + .buffer = dma_buffer, .complete_cb = _transfer_done_cb, }; - _xfer_result = 0xff; - + _prepare_for_transfer(); if (!tuh_control_xfer(&xfer)) { mp_raise_usb_core_USBError(NULL); - } - uint32_t start_time = supervisor_ticks_ms32(); - while ((timeout == 0 || supervisor_ticks_ms32() - start_time < (uint32_t)timeout) && - !mp_hal_is_interrupted() && - _xfer_result == 0xff) { - // The background tasks include TinyUSB which will call the function - // we provided above. In other words, the callback isn't in an interrupt. - RUN_BACKGROUND_TASKS; - } - if (mp_hal_is_interrupted()) { - tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); return 0; } - xfer_result_t result = _xfer_result; - _xfer_result = 0xff; - if (result == XFER_RESULT_STALLED) { - mp_raise_usb_core_USBError(MP_ERROR_TEXT("Pipe error")); - } - if (result == 0xff) { - tuh_edpt_abort_xfer(xfer.daddr, xfer.ep_addr); - mp_raise_usb_core_USBTimeoutError(); - } - if (result == XFER_RESULT_SUCCESS) { - return len; + mp_int_t result = (mp_int_t)_handle_timed_transfer_callback(&xfer, timeout, dma_buffer != buffer, true); + + #if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE + if (dma_buffer != buffer) { + // Copy data back to original buffer if this was a read transfer + if (buffer != NULL && !is_write) { + memcpy(buffer, dma_buffer, result); + } + port_free(dma_buffer); } + #endif - return 0; + return result; } bool common_hal_usb_core_device_is_kernel_driver_active(usb_core_device_obj_t *self, mp_int_t interface) { #if CIRCUITPY_USB_KEYBOARD_WORKFLOW - if (usb_keyboard_in_use(self->device_number, interface)) { + if (usb_keyboard_in_use(self->device_address, interface)) { return true; } #endif @@ -326,12 +595,12 @@ bool common_hal_usb_core_device_is_kernel_driver_active(usb_core_device_obj_t *s void common_hal_usb_core_device_detach_kernel_driver(usb_core_device_obj_t *self, mp_int_t interface) { #if CIRCUITPY_USB_KEYBOARD_WORKFLOW - usb_keyboard_detach(self->device_number, interface); + usb_keyboard_detach(self->device_address, interface); #endif } void common_hal_usb_core_device_attach_kernel_driver(usb_core_device_obj_t *self, mp_int_t interface) { #if CIRCUITPY_USB_KEYBOARD_WORKFLOW - usb_keyboard_attach(self->device_number, interface); + usb_keyboard_attach(self->device_address, interface); #endif } diff --git a/shared-module/usb/core/Device.h b/shared-module/usb/core/Device.h index 2b628e05cf6..c7392a04ba7 100644 --- a/shared-module/usb/core/Device.h +++ b/shared-module/usb/core/Device.h @@ -10,7 +10,7 @@ typedef struct { mp_obj_base_t base; - uint8_t device_number; + uint8_t device_address; uint8_t configuration_index; // not bConfigurationValue uint8_t *configuration_descriptor; // Contains the length of the all descriptors. uint8_t open_endpoints[8]; diff --git a/shared-module/usb/util/__init__.c b/shared-module/usb/util/__init__.c new file mode 100644 index 00000000000..d3f12eb42bb --- /dev/null +++ b/shared-module/usb/util/__init__.c @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Nothing implementation specific. diff --git a/shared-module/usb_audio/USBMicrophone.c b/shared-module/usb_audio/USBMicrophone.c new file mode 100644 index 00000000000..26a185ff0e9 --- /dev/null +++ b/shared-module/usb_audio/USBMicrophone.c @@ -0,0 +1,174 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/misc.h" +#include "py/runtime.h" + +#include "shared-bindings/usb_audio/USBMicrophone.h" +#include "shared-module/usb_audio/__init__.h" +#include "shared-module/usb_audio/usb_audio_descriptors.h" +#include "shared-module/audiocore/__init__.h" + +// Only one microphone may feed the single USB IN endpoint at a time. This points +// at the USBMicrophone whose play() was called most recently, or NULL when none +// is streaming. The USB background task pulls from it via +// usb_audio_usbmicrophone_background_fill(). +static usb_audio_usbmicrophone_obj_t *active_microphone = NULL; + +void common_hal_usb_audio_usbmicrophone_construct(usb_audio_usbmicrophone_obj_t *self) { + self->sample = MP_OBJ_NULL; + self->buffer = NULL; + self->buffer_length = 0; + self->loop = false; + self->playing = false; + self->paused = false; + self->deinited = false; + self->more_data = false; +} + +void common_hal_usb_audio_usbmicrophone_deinit(usb_audio_usbmicrophone_obj_t *self) { + common_hal_usb_audio_usbmicrophone_stop(self); + self->deinited = true; +} + +bool common_hal_usb_audio_usbmicrophone_deinited(usb_audio_usbmicrophone_obj_t *self) { + return self->deinited; +} + +void common_hal_usb_audio_usbmicrophone_play(usb_audio_usbmicrophone_obj_t *self, mp_obj_t sample, bool loop) { + // The negotiated USB format is fixed 16-bit signed LE PCM at the rate/channel + // count chosen by usb_audio.enable() in boot.py. Resampling and format + // conversion are out of scope, so the source must already match exactly. This + // mirrors how audiocore's audiosample_must_match() validates an output's input + // (and reuses its error messages), but checks against the USB format rather + // than another audiosample. + audiosample_base_t *sample_base = audiosample_check(sample); + if (audiosample_get_sample_rate(sample_base) != usb_audio_sample_rate) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_sample_rate); + } + if (audiosample_get_channel_count(sample_base) != usb_audio_channel_count) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_channel_count); + } + if (audiosample_get_bits_per_sample(sample_base) != USB_AUDIO_BITS_PER_SAMPLE) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_bits_per_sample); + } + if (!sample_base->samples_signed) { + mp_raise_ValueError_varg(MP_ERROR_TEXT("The sample's %q does not match"), MP_QSTR_signedness); + } + + // Start at the beginning and arm the pull loop to request the first chunk. + audiosample_reset_buffer(sample, false, 0); + self->sample = sample; + self->buffer = NULL; + self->buffer_length = 0; + self->loop = loop; + self->playing = true; + self->paused = false; + self->more_data = true; + // Take over the single USB IN endpoint from any other microphone. + active_microphone = self; +} + +void common_hal_usb_audio_usbmicrophone_stop(usb_audio_usbmicrophone_obj_t *self) { + self->sample = MP_OBJ_NULL; + self->buffer = NULL; + self->buffer_length = 0; + self->playing = false; + self->paused = false; + self->more_data = false; + if (active_microphone == self) { + active_microphone = NULL; + } +} + +bool common_hal_usb_audio_usbmicrophone_get_playing(usb_audio_usbmicrophone_obj_t *self) { + return self->playing && !self->paused; +} + +void common_hal_usb_audio_usbmicrophone_pause(usb_audio_usbmicrophone_obj_t *self) { + self->paused = true; +} + +void common_hal_usb_audio_usbmicrophone_resume(usb_audio_usbmicrophone_obj_t *self) { + self->paused = false; +} + +bool common_hal_usb_audio_usbmicrophone_get_paused(usb_audio_usbmicrophone_obj_t *self) { + return self->playing && self->paused; +} + +size_t usb_audio_usbmicrophone_background_fill(uint8_t *out, size_t max_bytes) { + usb_audio_usbmicrophone_obj_t *self = active_microphone; + if (self == NULL || !self->playing || self->paused || self->sample == MP_OBJ_NULL) { + return 0; + } + + // The negotiated USB format is 16-bit signed PCM. For this step the + // bound sample is assumed to already be in that format (e.g. a 16-bit signed + // audiocore.RawSample), so its bytes are copied straight through. + size_t filled = 0; + while (filled < max_bytes) { + if (self->buffer_length == 0) { + if (!self->more_data) { + // The previous chunk was the sample's last and we've played it + // out. Loop back to the start or stop. + if (self->loop) { + audiosample_reset_buffer(self->sample, false, 0); + self->more_data = true; + } else { + common_hal_usb_audio_usbmicrophone_stop(self); + break; + } + } + audioio_get_buffer_result_t result = + audiosample_get_buffer(self->sample, false, 0, &self->buffer, &self->buffer_length); + if (result == GET_BUFFER_ERROR) { + common_hal_usb_audio_usbmicrophone_stop(self); + break; + } + self->more_data = (result == GET_BUFFER_MORE_DATA); + if (self->buffer_length == 0) { + // No samples available right now (underrun); the caller fills the + // rest of the frame with silence and we retry next tick. + break; + } + } + + // Bytes written to out, and bytes consumed from the sample's chunk. They + // differ when a mono sample feeds the always-stereo USB stream. + size_t written; + size_t consumed; + if (MP_LIKELY(usb_audio_channel_count == USB_AUDIO_N_CHANNELS)) { + written = consumed = MIN(self->buffer_length, max_bytes - filled); + memcpy(out + filled, self->buffer, written); + } else { + // Mono source: duplicate each sample into both USB channels. Work in + // whole stereo frames so a partial frame can never be emitted, and + // cap by both what the chunk holds and what still fits in out. + size_t frames = MIN(self->buffer_length / USB_AUDIO_N_BYTES_PER_SAMPLE, + (max_bytes - filled) / USB_AUDIO_BYTES_PER_FRAME); + const int16_t *in = (const int16_t *)(const void *)self->buffer; + int16_t *dest = (int16_t *)(void *)(out + filled); + for (size_t i = 0; i < frames; i++) { + dest[2 * i] = dest[2 * i + 1] = in[i]; + } + written = frames * USB_AUDIO_BYTES_PER_FRAME; + consumed = frames * USB_AUDIO_N_BYTES_PER_SAMPLE; + } + if (written == 0) { + // Less than one whole frame of room left in out (or nothing to copy): + // stop rather than spin. The caller pads the remainder with silence. + break; + } + self->buffer += consumed; + self->buffer_length -= consumed; + filled += written; + } + + return filled; +} diff --git a/shared-module/usb_audio/USBMicrophone.h b/shared-module/usb_audio/USBMicrophone.h new file mode 100644 index 00000000000..74f167e8e43 --- /dev/null +++ b/shared-module/usb_audio/USBMicrophone.h @@ -0,0 +1,33 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +typedef struct usb_audio_usbmicrophone_obj { + mp_obj_base_t base; + // The audiosample currently bound for streaming, or MP_OBJ_NULL. + mp_obj_t sample; + // Cursor into the chunk last returned by audiosample_get_buffer(): the next + // unread byte and the number of bytes still unread in that chunk. + uint8_t *buffer; + uint32_t buffer_length; + bool loop; + bool playing; + bool paused; + bool deinited; + // False once audiosample_get_buffer() reported GET_BUFFER_DONE for the + // current chunk; the chunk is still played out, then we loop or stop. + bool more_data; +} usb_audio_usbmicrophone_obj_t; + +// Pull up to max_bytes of audio (in the negotiated USB PCM format) from whichever +// USBMicrophone is currently playing, writing it into out. Returns the number of +// bytes written, which is < max_bytes (possibly 0) when nothing is streaming or +// the source underruns; the caller pads the remainder with silence. Called from +// the USB background task in shared-module/usb_audio/__init__.c. +size_t usb_audio_usbmicrophone_background_fill(uint8_t *out, size_t max_bytes); diff --git a/shared-module/usb_audio/USBSpeaker.c b/shared-module/usb_audio/USBSpeaker.c new file mode 100644 index 00000000000..c04ee9b280d --- /dev/null +++ b/shared-module/usb_audio/USBSpeaker.c @@ -0,0 +1,267 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include + +#include "py/misc.h" + +#include "shared-bindings/usb_audio/USBSpeaker.h" +#include "shared-bindings/audiocore/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-module/usb_audio/__init__.h" + +#include "tusb.h" + +// The ring is sized independently of the TinyUSB headers (see USBSpeaker.h); +// check it still matches the OUT endpoint's software FIFO so the push side can be +// reasoned about against the USB plumbing. +MP_STATIC_ASSERT(USB_AUDIO_SPEAKER_RING_SIZE == CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ); + +// Only one speaker can be fed by the single USB OUT endpoint at a time. This +// points at the most recently constructed USBSpeaker, or NULL when none exists, +// mirroring active_microphone in USBMicrophone.c. The USB background task pushes +// received bytes into it via usb_audio_usbspeaker_background_drain(). +static usb_audio_usbspeaker_obj_t *active_speaker = NULL; + +void common_hal_usb_audio_usbspeaker_construct(usb_audio_usbspeaker_obj_t *self) { + // The pipeline treats the speaker as an ordinary audiosample source, so + // populate base from the format negotiated by usb_audio.enable(). The UAC2 + // format we present is 16-bit signed LE PCM, which is exactly what the + // CircuitPython audio pipeline carries, so no conversion is needed. + self->base.sample_rate = usb_audio_sample_rate; + self->base.bits_per_sample = USB_AUDIO_BITS_PER_SAMPLE; + self->base.channel_count = usb_audio_channel_count; + self->base.samples_signed = true; + self->base.single_buffer = false; + self->base.max_buffer_length = USB_AUDIO_SPEAKER_OUTPUT_BUFFER_SIZE; + + self->ring_head = 0; + self->ring_tail = 0; + self->ring_count = 0; + self->output_index = 0; + + // The most recently created speaker receives the host's OUT stream. + active_speaker = self; +} + +void common_hal_usb_audio_usbspeaker_deinit(usb_audio_usbspeaker_obj_t *self) { + // Stop directing USB OUT data at this object. The producer (drain) and this + // deinit both run in non-interrupt context, so the pointer swap needs no + // interrupt guard. + if (active_speaker == self) { + active_speaker = NULL; + } + audiosample_mark_deinit(&self->base); +} + +bool common_hal_usb_audio_usbspeaker_deinited(usb_audio_usbspeaker_obj_t *self) { + return audiosample_deinited(&self->base); +} + +bool common_hal_usb_audio_usbspeaker_get_connected(usb_audio_usbspeaker_obj_t *self) { + (void)self; + // True while the host has opened the OUT streaming interface, i.e. it is + // actively sending audio. Speaker-specific so it stays correct when a mic + // shares the same headset function. + return usb_audio_speaker_streaming(); +} + +// --------------------------------------------------------------------+ +// Receive ring (push side, producer = USB background task) +// --------------------------------------------------------------------+ +// +// The ring decouples the two independently clocked stages from +// usb_audio_output_plan.md: USB push (paced by the host's SOF clock, in the +// background task) and the audiosample pull (paced by the output backend's +// sample clock, in its refill interrupt). It is a single-producer/ +// single-consumer ring across an interrupt boundary: +// +// * Producer: usb_audio_usbspeaker_background_drain(), task context. +// * Consumer: usb_audio_usbspeaker_get_buffer(), output DMA/refill ISR. +// +// The consumer is an interrupt, so it can never be preempted by the producer and +// needs no guard of its own. The producer can be preempted by the consumer, and +// its drop-oldest overrun handling touches both cursors, so it does its whole +// read-modify-write with interrupts disabled. + +void usb_audio_usbspeaker_streaming_reset(void) { + usb_audio_usbspeaker_obj_t *self = active_speaker; + if (self == NULL) { + return; + } + common_hal_mcu_disable_interrupts(); + self->ring_head = 0; + self->ring_tail = 0; + self->ring_count = 0; + common_hal_mcu_enable_interrupts(); +} + +void usb_audio_usbspeaker_background_drain(const uint8_t *in, size_t n) { + usb_audio_usbspeaker_obj_t *self = active_speaker; + if (self == NULL || n == 0) { + return; + } + if (n >= USB_AUDIO_SPEAKER_RING_SIZE) { + // A single chunk larger than the whole ring can only contribute its + // newest tail. (Cannot happen with USB packets << ring size, but keep + // the copies provably in-bounds.) + in += n - USB_AUDIO_SPEAKER_RING_SIZE; + n = USB_AUDIO_SPEAKER_RING_SIZE; + } + + common_hal_mcu_disable_interrupts(); + + size_t free_space = USB_AUDIO_SPEAKER_RING_SIZE - self->ring_count; + if (n > free_space) { + // Overrun: advance the read cursor past the oldest bytes we're about to + // overwrite, keeping latency bounded and following the newest host audio. + size_t drop = n - free_space; + self->ring_tail = (self->ring_tail + drop) % USB_AUDIO_SPEAKER_RING_SIZE; + self->ring_count -= drop; + } + + // Copy in one or two segments, wrapping at the end of the ring. + size_t first = MIN(n, USB_AUDIO_SPEAKER_RING_SIZE - self->ring_head); + memcpy(&self->ring[self->ring_head], in, first); + if (n > first) { + memcpy(&self->ring[0], in + first, n - first); + } + self->ring_head = (self->ring_head + n) % USB_AUDIO_SPEAKER_RING_SIZE; + self->ring_count += n; + + common_hal_mcu_enable_interrupts(); +} + +uint32_t common_hal_usb_audio_usbspeaker_read(usb_audio_usbspeaker_obj_t *self, + void *buffer, uint32_t length) { + // Hand the most recent host audio to Python so it can be analysed (e.g. an + // audio-reactive effect or VU meter). This drains the ring just like the + // output backend's get_buffer() does, so it is an alternative *consumer*: + // a USBSpeaker being read this way must not also be play()ed to an output + // backend at the same time, or the two consumers would race on the single + // SPSC ring. + // + // Unlike get_buffer() (which runs in the output refill ISR and so needs no + // guard) this runs in VM/task context and can be preempted by the USB + // producer, so it brackets its read-modify-write with interrupts disabled, + // mirroring usb_audio_usbspeaker_background_drain(). + // The ring holds wire-format frames (always USB_AUDIO_N_CHANNELS channels). + // `length` and the return value count entries in `buffer`, i.e. 16-bit + // samples: a stereo speaker writes one per channel of each frame, a mono one + // keeps only each frame's left channel. + bool mono = usb_audio_channel_count != USB_AUDIO_N_CHANNELS; + size_t samples_per_frame = mono ? 1 : USB_AUDIO_N_CHANNELS; + size_t want = (size_t)(length / samples_per_frame) * USB_AUDIO_BYTES_PER_FRAME; + + common_hal_mcu_disable_interrupts(); + size_t to_copy = MIN(self->ring_count, want); + // Never split a frame across calls (the ring always holds whole UAC2 frames, + // but stay defensive so the returned count is always a whole number). + to_copy -= to_copy % USB_AUDIO_BYTES_PER_FRAME; + + size_t first = MIN(to_copy, USB_AUDIO_SPEAKER_RING_SIZE - self->ring_tail); + if (MP_LIKELY(!mono)) { + memcpy(buffer, &self->ring[self->ring_tail], first); + if (to_copy > first) { + memcpy((uint8_t *)buffer + first, &self->ring[0], to_copy - first); + } + } else { + int16_t *word_out = (int16_t *)buffer; + const int16_t *word_ring = (const int16_t *)(const void *)self->ring; + size_t base = self->ring_tail / USB_AUDIO_N_BYTES_PER_SAMPLE; + size_t written = 0; + for (size_t i = 0; i < first / USB_AUDIO_N_BYTES_PER_SAMPLE; i += USB_AUDIO_N_CHANNELS) { + word_out[written++] = word_ring[base + i]; + } + for (size_t i = 0; i < (to_copy - first) / USB_AUDIO_N_BYTES_PER_SAMPLE; i += USB_AUDIO_N_CHANNELS) { + word_out[written++] = word_ring[i]; + } + } + self->ring_tail = (self->ring_tail + to_copy) % USB_AUDIO_SPEAKER_RING_SIZE; + self->ring_count -= to_copy; + common_hal_mcu_enable_interrupts(); + + return to_copy / USB_AUDIO_BYTES_PER_FRAME * samples_per_frame; +} + +// --------------------------------------------------------------------+ +// audiosample protocol (pull side, consumer = output backend) +// --------------------------------------------------------------------+ + +void usb_audio_usbspeaker_reset_buffer(usb_audio_usbspeaker_obj_t *self, + bool single_channel_output, uint8_t channel) { + (void)single_channel_output; + (void)channel; + // Begin playback from live audio rather than whatever was buffered before: + // drop the ring and restart the double-buffer. Guarded because some ports may + // call reset_buffer outside the initial setup. + common_hal_mcu_disable_interrupts(); + self->ring_head = 0; + self->ring_tail = 0; + self->ring_count = 0; + common_hal_mcu_enable_interrupts(); + self->output_index = 0; +} + +audioio_get_buffer_result_t usb_audio_usbspeaker_get_buffer(usb_audio_usbspeaker_obj_t *self, + bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length) { + + uint32_t half = self->base.max_buffer_length / 2; + uint8_t *out = self->output_buffer + half * self->output_index; + self->output_index = 1 - self->output_index; + + // Consumer side of the SPSC ring (runs in the output backend's refill ISR). + // It is never preempted by the producer, so no interrupt guard is required. + size_t to_copy = MIN(self->ring_count, (size_t)half); + + // Bytes produced in out. The ring always holds wire-format (stereo) frames; + // a mono sample keeps only the left channel of each, so it produces half. + bool mono = usb_audio_channel_count != USB_AUDIO_N_CHANNELS; + size_t produced = mono ? to_copy / 2 : to_copy; + + size_t first = MIN(to_copy, USB_AUDIO_SPEAKER_RING_SIZE - self->ring_tail); + if (MP_LIKELY(!mono)) { + memcpy(out, &self->ring[self->ring_tail], first); + if (to_copy > first) { + memcpy(out + first, &self->ring[0], to_copy - first); + } + } else { + // Take the left sample of each stereo frame, across up to two ring + // segments. Indices are in int16 units, counted from the segment start. + int16_t *word_out = (int16_t *)(void *)out; + const int16_t *word_ring = (const int16_t *)(const void *)self->ring; + size_t base = self->ring_tail / USB_AUDIO_N_BYTES_PER_SAMPLE; + size_t written = 0; + for (size_t i = 0; i < first / USB_AUDIO_N_BYTES_PER_SAMPLE; i += USB_AUDIO_N_CHANNELS) { + word_out[written++] = word_ring[base + i]; + } + for (size_t i = 0; i < (to_copy - first) / USB_AUDIO_N_BYTES_PER_SAMPLE; i += USB_AUDIO_N_CHANNELS) { + word_out[written++] = word_ring[i]; + } + } + self->ring_tail = (self->ring_tail + to_copy) % USB_AUDIO_SPEAKER_RING_SIZE; + self->ring_count -= to_copy; + + // Bytes the caller will be handed, which is all a mono sample can fill. + uint32_t out_length = mono ? half / 2 : half; + if (produced < out_length) { + // Underrun: pad the remainder with silence. Samples are signed, so + // silence is 0. This is the consume-side of the pacing failure mode + // tracked in the usb-audio-artifact-pacing memory: we never spin. + memset(out + produced, 0, out_length - produced); + } + + // Computed the same way as audiocore.RawSample so stereo (interleaved ring) + // can extend it. + if (single_channel_output) { + out += (channel % self->base.channel_count) * (self->base.bits_per_sample / 8); + } + + *buffer = out; + *buffer_length = out_length; + // A live USB stream is infinite; never report DONE or the backend would stop. + return GET_BUFFER_MORE_DATA; +} diff --git a/shared-module/usb_audio/USBSpeaker.h b/shared-module/usb_audio/USBSpeaker.h new file mode 100644 index 00000000000..0760676b53a --- /dev/null +++ b/shared-module/usb_audio/USBSpeaker.h @@ -0,0 +1,73 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include + +#include "py/obj.h" + +#include "shared-module/audiocore/__init__.h" +#include "shared-module/usb_audio/usb_audio_descriptors.h" + +// One half-buffer of the audiosample double-buffer holds this many frames. The +// output backend pulls a half each get_buffer() call, so this sets the pull +// granularity and the silence-pad chunk on underrun. It is deliberately +// independent of the USB OUT software FIFO (the ring below) so the push and pull +// stages can be tuned separately, and small enough that two halves sit +// comfortably inside the ring. +#define USB_AUDIO_SPEAKER_FRAMES_PER_BUFFER (128) + +// Bytes per audio frame in the negotiated UAC2 format (stereo 16-bit). +#define USB_AUDIO_SPEAKER_BYTES_PER_FRAME (USB_AUDIO_N_BYTES_PER_SAMPLE * USB_AUDIO_N_CHANNELS) + +// Full owned double-buffer: two halves of FRAMES_PER_BUFFER frames each. Matches +// audiocore.RawSample's convention where base.max_buffer_length is the whole +// buffer and get_buffer() returns half of it. +#define USB_AUDIO_SPEAKER_OUTPUT_BUFFER_SIZE (2 * USB_AUDIO_SPEAKER_FRAMES_PER_BUFFER * USB_AUDIO_SPEAKER_BYTES_PER_FRAME) + +// Host -> board receive ring size. Mirrors CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ +// (16 * the full-speed OUT wMaxPacketSize) but is spelled out from the format +// constants so this struct definition stays free of the TinyUSB headers. A +// MP_STATIC_ASSERT in USBSpeaker.c checks the two stay equal. +#define USB_AUDIO_SPEAKER_OUT_PACKET_SIZE ((USB_AUDIO_MAX_SAMPLE_RATE / 1000 + 1) * USB_AUDIO_SPEAKER_BYTES_PER_FRAME) +#define USB_AUDIO_SPEAKER_RING_SIZE (16 * USB_AUDIO_SPEAKER_OUT_PACKET_SIZE) + +typedef struct usb_audio_usbspeaker_obj { + // First member so the object can be used directly as an audiosample source. + audiosample_base_t base; + + // Host -> board receive ring (the "push" stage). Filled by the USB + // background task via usb_audio_usbspeaker_background_drain() and drained by + // get_buffer(). Single producer (task), single consumer (output DMA ISR); + // see the concurrency notes in USBSpeaker.c. + uint8_t ring[USB_AUDIO_SPEAKER_RING_SIZE]; + size_t ring_head; // next write offset + size_t ring_tail; // next read offset + size_t ring_count; // valid bytes currently in the ring + + // Owned double-buffer returned to the output backend by get_buffer(). + uint8_t output_buffer[USB_AUDIO_SPEAKER_OUTPUT_BUFFER_SIZE]; + uint8_t output_index; // 0 or 1: which half get_buffer() fills next +} usb_audio_usbspeaker_obj_t; + +// audiosample protocol implementation. Not exposed to Python because get_buffer() +// runs in the output backend's refill interrupt. +void usb_audio_usbspeaker_reset_buffer(usb_audio_usbspeaker_obj_t *self, + bool single_channel_output, uint8_t channel); +audioio_get_buffer_result_t usb_audio_usbspeaker_get_buffer(usb_audio_usbspeaker_obj_t *self, + bool single_channel_output, uint8_t channel, uint8_t **buffer, uint32_t *buffer_length); + +// Push n bytes received on the USB OUT endpoint into the active speaker's ring. +// Called from the USB background task (see usb_audio_task()). No-op when no +// speaker is active. Overrun policy: drop the oldest buffered bytes. +void usb_audio_usbspeaker_background_drain(const uint8_t *in, size_t n); + +// Drop anything buffered in the active speaker's ring so a (re)opened stream +// starts from live audio. Called when the host opens/closes the OUT streaming +// interface. +void usb_audio_usbspeaker_streaming_reset(void); diff --git a/shared-module/usb_audio/__init__.c b/shared-module/usb_audio/__init__.c new file mode 100644 index 00000000000..78eac9fdb5b --- /dev/null +++ b/shared-module/usb_audio/__init__.c @@ -0,0 +1,714 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#include "shared-bindings/usb_audio/__init__.h" +#include "shared-bindings/usb_audio/USBMicrophone.h" +#include "shared-bindings/usb_audio/USBSpeaker.h" +#include "shared-module/usb_audio/__init__.h" +#include "shared-module/usb_audio/USBMicrophone.h" +#include "shared-module/usb_audio/USBSpeaker.h" +#include "shared-module/usb_audio/usb_audio_descriptors.h" + +#include + +#include "py/misc.h" +#include "py/mphal.h" +#include "py/runtime.h" +#include "supervisor/port.h" +#include "supervisor/shared/tick.h" +#include "supervisor/usb.h" +#include "tusb.h" + +// Scratch chunk the microphone task hands to TinyUSB. It is written from the USB +// background task for as long as the device is enabled, which outlives every VM, +// so it comes from the port heap rather than the MicroPython heap. Sized by +// enable() for 1 ms at the negotiated rate, in the wire format (always +// USB_AUDIO_N_CHANNELS channels), so a board that never calls enable() pays +// nothing for it. +static int16_t *usb_audio_mic_samples; +static size_t usb_audio_mic_samples_len; + +static bool usb_audio_is_enabled = false; + +// The host opens each AudioStreaming interface independently (alt 0 = idle, alt 1 +// = streaming), so the two directions of a headset are tracked separately. For +// the single-direction microphone/speaker only the matching flag is ever set. +static bool usb_audio_mic_streaming = false; +static bool usb_audio_spk_streaming = false; + +// AudioStreaming interface numbers assigned when the descriptor is built, used to +// route the host's set-interface requests to the right direction. 0xff until a +// descriptor that includes that direction has been emitted. +static uint8_t usb_audio_mic_as_itf = 0xff; +static uint8_t usb_audio_spk_as_itf = 0xff; + +uint32_t usb_audio_sample_rate; +uint8_t usb_audio_channel_count; +bool usb_audio_microphone_enabled; +bool usb_audio_speaker_enabled; + +// Audio control state surfaced to the host. One extra entry for the master channel 0. +static int8_t usb_audio_mute[USB_AUDIO_N_CHANNELS + 1]; +static int16_t usb_audio_volume[USB_AUDIO_N_CHANNELS + 1]; + +bool shared_module_usb_audio_enable(mp_int_t sample_rate, mp_int_t channel_count, bool microphone, bool speaker) { + if (tud_connected()) { + return false; + } + + // One scratch chunk (1 ms at the sample rate); we loop until the FIFO reaches + // the setpoint. enable() may be called more than once, so release any chunk + // sized for a previous rate before taking a new one. + port_free(usb_audio_mic_samples); + usb_audio_mic_samples_len = sample_rate / 1000 * USB_AUDIO_BYTES_PER_FRAME; + usb_audio_mic_samples = port_malloc_zero(usb_audio_mic_samples_len, false); + if (usb_audio_mic_samples == NULL) { + usb_audio_mic_samples_len = 0; + return false; + } + + usb_audio_sample_rate = sample_rate; + usb_audio_channel_count = channel_count; + usb_audio_microphone_enabled = microphone; + usb_audio_speaker_enabled = speaker; + usb_audio_is_enabled = true; + + return true; +} + +bool shared_module_usb_audio_disable(void) { + if (tud_connected()) { + return false; + } + usb_audio_is_enabled = false; + port_free(usb_audio_mic_samples); + usb_audio_mic_samples = NULL; + usb_audio_mic_samples_len = 0; + return true; +} + +bool usb_audio_enabled(void) { + return usb_audio_is_enabled; +} + +bool usb_audio_streaming(void) { + return usb_audio_mic_streaming || usb_audio_spk_streaming; +} + +// True while the host has the speaker (OUT) stream open, i.e. it is actively +// sending audio. Used by USBSpeaker.connected so it reflects the speaker +// direction specifically even when a mic shares the same headset function. +bool usb_audio_speaker_streaming(void) { + return usb_audio_spk_streaming; +} + +void usb_audio_setup_singletons(void) { + // USBMicrophone and USBSpeaker are singletons rather than constructible + // classes (like usb_midi.ports). The host-facing format and direction are + // fixed by usb_audio.enable() in boot.py and persist in C globals, but the + // instances themselves live on the GC heap, which is reset between boot.py + // and code.py, so they are rebuilt here once per VM. Each is created only + // when its direction was enabled; otherwise it is left as None. + // + // The objects are held in MP_STATE_VM root pointers so the GC keeps them + // alive for the whole VM (the module globals table is static data and is not + // a GC root, so a reference from there alone would be swept). Rooting the + // microphone also traces its bound audiosample (self->sample). They are then + // installed in the module globals so they are reachable as the + // usb_audio.usb_microphone / usb_audio.usb_speaker attributes. + mp_obj_t microphone = mp_const_none; + mp_obj_t speaker = mp_const_none; + + if (usb_audio_is_enabled) { + const bool has_input = usb_audio_microphone_enabled; + const bool has_output = usb_audio_speaker_enabled; + + if (has_input) { + usb_audio_usbmicrophone_obj_t *self = + mp_obj_malloc_with_finaliser(usb_audio_usbmicrophone_obj_t, &usb_audio_USBMicrophone_type); + common_hal_usb_audio_usbmicrophone_construct(self); + microphone = MP_OBJ_FROM_PTR(self); + } + if (has_output) { + usb_audio_usbspeaker_obj_t *self = + mp_obj_malloc_with_finaliser(usb_audio_usbspeaker_obj_t, &usb_audio_USBSpeaker_type); + common_hal_usb_audio_usbspeaker_construct(self); + speaker = MP_OBJ_FROM_PTR(self); + } + } + + MP_STATE_VM(usb_audio_microphone_singleton) = microphone; + MP_STATE_VM(usb_audio_speaker_singleton) = speaker; + + mp_map_lookup(&usb_audio_module_globals.map, MP_ROM_QSTR(MP_QSTR_usb_microphone), MP_MAP_LOOKUP)->value = + microphone; + mp_map_lookup(&usb_audio_module_globals.map, MP_ROM_QSTR(MP_QSTR_usb_speaker), MP_MAP_LOOKUP)->value = + speaker; +} + +// Hand-rolled UAC2 speaker (host -> board) descriptor WITHOUT an async +// feedback endpoint. This mirrors TinyUSB's TUD_AUDIO20_SPEAKER_STEREO_FB_DESCRIPTOR +// (lib/tinyusb/src/device/usbd.h) but drops the trailing feedback endpoint, so +// the streaming alt-setting declares a single OUT endpoint (_nEPs = 0x01). The +// entity IDs match the mic descriptor (see usb_audio_descriptors.h); only the +// terminal roles reverse: the input terminal is the USB-streaming side and the +// output terminal is the desktop speaker, and the AS interface links the input +// terminal (0x01). Async feedback for true clock matching is a later step. +#define USB_AUDIO_SPEAKER_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epsize) \ + /* Standard Interface Association Descriptor (IAD) */ \ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00), \ + /* Standard AC Interface Descriptor(4.7.1) */ \ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx), \ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */ \ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_DESKTOP_SPEAKER, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN + TUD_AUDIO20_DESC_INPUT_TERM_LEN + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS), \ + /* Clock Source Descriptor(4.7.2.1) */ \ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ USB_AUDIO_ENTITY_CLOCK_SOURCE, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_stridx*/ 0x00), \ + /* Input Terminal Descriptor(4.7.2.4) -- USB streaming in from the host */ \ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ USB_AUDIO_ENTITY_CLOCK_SOURCE, /*_nchannelslogical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00), \ + /* Output Terminal Descriptor(4.7.2.5) -- desktop speaker */ \ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ USB_AUDIO_ENTITY_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_srcid*/ USB_AUDIO_ENTITY_FEATURE_UNIT, /*_clkid*/ USB_AUDIO_ENTITY_CLOCK_SOURCE, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00), \ + /* Feature Unit Descriptor(4.7.2.8) */ \ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ USB_AUDIO_ENTITY_FEATURE_UNIT, /*_srcid*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), \ + /* Standard AS Interface Descriptor(4.9.1) -- alt 0, zero bandwidth */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) -- alt 1, one OUT endpoint */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) -- linked to the input terminal */ \ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t)((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + +// Hand-rolled UAC2 microphone (board -> host) descriptor WITHOUT an async +// feedback endpoint. This mirrors TinyUSB's TUD_AUDIO20_MIC_ONE_CH_DESCRIPTOR +// (lib/tinyusb/src/device/usbd.h) but drops the trailing feedback endpoint, so +// the streaming alt-setting declares a single IN endpoint (_nEPs = 0x00). Async +// feedback for true clock matching is a later step. +#define USB_AUDIO_MIC_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epin, _epsize) \ + /* Standard Interface Association Descriptor (IAD) */ \ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x02, /*_stridx*/ 0x00), \ + /* Standard AC Interface Descriptor(4.7.1) */ \ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx), \ + /* Class-Specific AC Interface Header Descriptor(4.7.2) */ \ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_MICROPHONE, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN + TUD_AUDIO20_DESC_INPUT_TERM_LEN + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS), \ + /* Clock Source Descriptor(4.7.2.1) */ \ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ USB_AUDIO_ENTITY_CLOCK_SOURCE, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_stridx*/ 0x00), \ + /* Input Terminal Descriptor(4.7.2.4) -- microphone */ \ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ USB_AUDIO_ENTITY_OUTPUT_TERMINAL, /*_clkid*/ USB_AUDIO_ENTITY_CLOCK_SOURCE, /*_nchannelslogical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00), \ + /* Output Terminal Descriptor(4.7.2.5) -- USB streaming */ \ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ USB_AUDIO_ENTITY_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_srcid*/ USB_AUDIO_ENTITY_FEATURE_UNIT, /*_clkid*/ USB_AUDIO_ENTITY_CLOCK_SOURCE, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00), \ + /* Feature Unit Descriptor(4.7.2.8) */ \ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ USB_AUDIO_ENTITY_FEATURE_UNIT, /*_srcid*/ USB_AUDIO_ENTITY_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 0 - default alternate setting with 0 bandwidth */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) */ \ + /* Interface 1, Alternate 1 - alternate interface for data streaming */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) */ \ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ USB_AUDIO_ENTITY_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t)((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + +// Hand-rolled UAC2 headset (microphone + speaker both enabled): one audio function +// presenting both a speaker (host -> board OUT) and a microphone (board -> host +// IN) at once. This combines USB_AUDIO_SPEAKER_DESCRIPTOR's speaker chain with +// USB_AUDIO_MIC_DESCRIPTOR's mic chain under a single IAD. The two chains +// must use distinct entity IDs (USB_AUDIO_HS_ENTITY_*; see usb_audio_descriptors.h) +// because they live in the same AudioControl interface, and they share one clock +// source. The function spans three interfaces: AudioControl (_itfnum), the +// speaker AudioStreaming interface (_itfnum + 1, OUT endpoint), and the mic +// AudioStreaming interface (_itfnum + 2, IN endpoint). Neither stream has an +// async feedback endpoint, matching the single-direction descriptors. +#define USB_AUDIO_HEADSET_DESCRIPTOR(_itfnum, _stridx, _nBytesPerSample, _nBitsUsedPerSample, _epout, _epin, _epsize) \ + /* Standard Interface Association Descriptor (IAD) -- 3 interfaces */ \ + TUD_AUDIO20_DESC_IAD(/*_firstitf*/ _itfnum, /*_nitfs*/ 0x03, /*_stridx*/ 0x00), \ + /* Standard AC Interface Descriptor(4.7.1) */ \ + TUD_AUDIO20_DESC_STD_AC(/*_itfnum*/ _itfnum, /*_nEPs*/ 0x00, /*_stridx*/ _stridx), \ + /* Class-Specific AC Interface Header Descriptor(4.7.2) -- clock + both chains */ \ + TUD_AUDIO20_DESC_CS_AC(/*_bcdADC*/ 0x0200, /*_category*/ AUDIO20_FUNC_HEADSET, /*_totallen*/ TUD_AUDIO20_DESC_CLK_SRC_LEN + 2 * (TUD_AUDIO20_DESC_INPUT_TERM_LEN + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2) + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN), /*_ctrl*/ AUDIO20_CS_AS_INTERFACE_CTRL_LATENCY_POS), \ + /* Clock Source Descriptor(4.7.2.1) -- shared by both chains */ \ + TUD_AUDIO20_DESC_CLK_SRC(/*_clkid*/ USB_AUDIO_HS_ENTITY_CLOCK_SOURCE, /*_attr*/ AUDIO20_CLOCK_SOURCE_ATT_INT_FIX_CLK, /*_ctrl*/ (AUDIO20_CTRL_R << AUDIO20_CLOCK_SOURCE_CTRL_CLK_FRQ_POS), /*_assocTerm*/ 0x00, /*_stridx*/ 0x00), \ + /* --- Speaker chain (host -> board) --- */ \ + /* Input Terminal Descriptor(4.7.2.4) -- USB streaming in from the host */ \ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ USB_AUDIO_HS_ENTITY_SPK_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_clkid*/ USB_AUDIO_HS_ENTITY_CLOCK_SOURCE, /*_nchannelslogical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ 0 * (AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS), /*_stridx*/ 0x00), \ + /* Feature Unit Descriptor(4.7.2.8) */ \ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ USB_AUDIO_HS_ENTITY_SPK_FEATURE_UNIT, /*_srcid*/ USB_AUDIO_HS_ENTITY_SPK_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), \ + /* Output Terminal Descriptor(4.7.2.5) -- desktop speaker */ \ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ USB_AUDIO_HS_ENTITY_SPK_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_OUT_DESKTOP_SPEAKER, /*_assocTerm*/ 0x00, /*_srcid*/ USB_AUDIO_HS_ENTITY_SPK_FEATURE_UNIT, /*_clkid*/ USB_AUDIO_HS_ENTITY_CLOCK_SOURCE, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00), \ + /* --- Mic chain (board -> host) --- */ \ + /* Input Terminal Descriptor(4.7.2.4) -- generic microphone */ \ + TUD_AUDIO20_DESC_INPUT_TERM(/*_termid*/ USB_AUDIO_HS_ENTITY_MIC_INPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_IN_GENERIC_MIC, /*_assocTerm*/ 0x00, /*_clkid*/ USB_AUDIO_HS_ENTITY_CLOCK_SOURCE, /*_nchannelslogical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_idxchannelnames*/ 0x00, /*_ctrl*/ AUDIO20_CTRL_R << AUDIO20_IN_TERM_CTRL_CONNECTOR_POS, /*_stridx*/ 0x00), \ + /* Feature Unit Descriptor(4.7.2.8) */ \ + TUD_AUDIO20_DESC_FEATURE_UNIT(/*_unitid*/ USB_AUDIO_HS_ENTITY_MIC_FEATURE_UNIT, /*_srcid*/ USB_AUDIO_HS_ENTITY_MIC_INPUT_TERMINAL, /*_stridx*/ 0x00, /*_ctrlch0master*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch1*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS, /*_ctrlch2*/ AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_MUTE_POS | AUDIO20_CTRL_RW << AUDIO20_FEATURE_UNIT_CTRL_VOLUME_POS), \ + /* Output Terminal Descriptor(4.7.2.5) -- USB streaming out to the host */ \ + TUD_AUDIO20_DESC_OUTPUT_TERM(/*_termid*/ USB_AUDIO_HS_ENTITY_MIC_OUTPUT_TERMINAL, /*_termtype*/ AUDIO_TERM_TYPE_USB_STREAMING, /*_assocTerm*/ 0x00, /*_srcid*/ USB_AUDIO_HS_ENTITY_MIC_FEATURE_UNIT, /*_clkid*/ USB_AUDIO_HS_ENTITY_CLOCK_SOURCE, /*_ctrl*/ 0x0000, /*_stridx*/ 0x00), \ + /* --- Speaker AudioStreaming interface (_itfnum + 1) --- */ \ + /* Standard AS Interface Descriptor(4.9.1) -- alt 0, zero bandwidth */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) -- alt 1, one OUT endpoint */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 1), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) -- linked to the speaker input terminal */ \ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ USB_AUDIO_HS_ENTITY_SPK_INPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epout, /*_attr*/ (uint8_t)((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000), \ + /* --- Mic AudioStreaming interface (_itfnum + 2) --- */ \ + /* Standard AS Interface Descriptor(4.9.1) -- alt 0, zero bandwidth */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 2), /*_altset*/ 0x00, /*_nEPs*/ 0x00, /*_stridx*/ 0x00), \ + /* Standard AS Interface Descriptor(4.9.1) -- alt 1, one IN endpoint */ \ + TUD_AUDIO20_DESC_STD_AS_INT(/*_itfnum*/ (uint8_t)((_itfnum) + 2), /*_altset*/ 0x01, /*_nEPs*/ 0x01, /*_stridx*/ 0x00), \ + /* Class-Specific AS Interface Descriptor(4.9.2) -- linked to the mic output terminal */ \ + TUD_AUDIO20_DESC_CS_AS_INT(/*_termid*/ USB_AUDIO_HS_ENTITY_MIC_OUTPUT_TERMINAL, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_formattype*/ AUDIO20_FORMAT_TYPE_I, /*_formats*/ AUDIO20_DATA_FORMAT_TYPE_I_PCM, /*_nchannelsphysical*/ USB_AUDIO_N_CHANNELS, /*_channelcfg*/ AUDIO20_CHANNEL_CONFIG_NON_PREDEFINED, /*_stridx*/ 0x00), \ + /* Type I Format Type Descriptor(2.3.1.6 - Audio Formats) */ \ + TUD_AUDIO20_DESC_TYPE_I_FORMAT(_nBytesPerSample, _nBitsUsedPerSample), \ + /* Standard AS Isochronous Audio Data Endpoint Descriptor(4.10.1.1) */ \ + TUD_AUDIO20_DESC_STD_AS_ISO_EP(/*_ep*/ _epin, /*_attr*/ (uint8_t)((uint8_t)TUSB_XFER_ISOCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_ASYNCHRONOUS | (uint8_t)TUSB_ISO_EP_ATT_DATA), /*_maxEPsize*/ _epsize, /*_interval*/ 0x01), \ + /* Class-Specific AS Isochronous Audio Data Endpoint Descriptor(4.10.1.2) */ \ + TUD_AUDIO20_DESC_CS_AS_ISO_EP(/*_attr*/ AUDIO20_CS_AS_ISO_DATA_EP_ATT_NON_MAX_PACKETS_OK, /*_ctrl*/ AUDIO20_CTRL_NONE, /*_lockdelayunit*/ AUDIO20_CS_AS_ISO_DATA_EP_LOCK_DELAY_UNIT_UNDEFINED, /*_lockdelay*/ 0x0000) + +// Combined headset: both a microphone (board -> host IN) and a speaker +// (host -> board OUT) under one audio function. +static bool usb_audio_direction_is_input_output(void) { + return usb_audio_microphone_enabled && usb_audio_speaker_enabled; +} + +// Speaker only (host -> board OUT), no microphone. +static bool usb_audio_direction_is_output(void) { + return usb_audio_speaker_enabled && !usb_audio_microphone_enabled; +} + +size_t usb_audio_descriptor_length(void) { + if (usb_audio_direction_is_input_output()) { + return USB_AUDIO_HEADSET_DESC_LEN; + } + if (usb_audio_direction_is_output()) { + return USB_AUDIO_SPEAKER_DESC_LEN; + } + return USB_AUDIO_MIC_DESC_LEN; +} + +size_t usb_audio_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { + // Pick the isochronous endpoint number. By default it follows the same + // sequential allocation as every other interface. On ports that pin ISO to a + // fixed, dedicated endpoint (USB_AUDIO_ISO_EP_NUM != 0; see the header for the + // nRF52 case), we use that number instead and leave the sequential counters + // untouched: the dedicated ISO endpoint is a separate hardware resource, so + // it must not consume one of the regular endpoint numbers the other + // interfaces draw from. + const bool forced_iso_ep = (USB_AUDIO_ISO_EP_NUM != 0); + const uint8_t iso_ep_num = forced_iso_ep ? USB_AUDIO_ISO_EP_NUM : descriptor_counts->current_endpoint; + + if (usb_audio_direction_is_input_output()) { + // Combined headset: a speaker AudioStreaming interface (OUT) and a mic + // AudioStreaming interface (IN) under one AudioControl interface, so one + // isochronous endpoint in each direction. + // + // Sequential-allocation ports (e.g. RP2) take a distinct number for each + // direction. Ports that pin ISO to a dedicated endpoint number + // (forced_iso_ep, e.g. nRF52) use that one number for BOTH directions: + // the constraint there is the endpoint *number*, not the direction. The + // nRF52 USBD has a separate ISOIN and ISOOUT on endpoint 8, and TinyUSB + // splits the ISO buffer (ISOSPLIT = HalfIN) when both are open, so 0x08 + // and 0x88 can run at the same time. As in the single-direction branches + // below, the dedicated ISO endpoint is separate hardware and must not + // consume the sequential endpoint numbers the other interfaces draw from. + const uint8_t ep_out = forced_iso_ep ? iso_ep_num : descriptor_counts->current_endpoint; + const uint8_t ep_in = forced_iso_ep ? iso_ep_num : (descriptor_counts->current_endpoint + 1); + + usb_add_interface_string(*current_interface_string, "CircuitPython Headset"); + + const uint8_t usb_audio_descriptor[] = { + USB_AUDIO_HEADSET_DESCRIPTOR( + /*_itfnum*/ descriptor_counts->current_interface, + /*_stridx*/ *current_interface_string, + /*_nBytesPerSample*/ USB_AUDIO_N_BYTES_PER_SAMPLE, + /*_nBitsUsedPerSample*/ USB_AUDIO_BITS_PER_SAMPLE, + /*_epout*/ ep_out, + /*_epin*/ ep_in | 0x80, + /*_epsize*/ CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX) + }; + + // Speaker AS is the first interface after AudioControl, mic AS the second. + usb_audio_spk_as_itf = descriptor_counts->current_interface + 1; + usb_audio_mic_as_itf = descriptor_counts->current_interface + 2; + + (*current_interface_string)++; + // One IAD wrapping an AudioControl + two AudioStreaming interfaces, plus a + // single isochronous endpoint in each direction. On sequential-allocation + // ports the two directions take separate endpoint numbers, consuming two of + // the port's endpoint pairs. On forced_iso_ep ports both directions share + // the dedicated ISO endpoint, which is separate hardware and consumes none. + descriptor_counts->current_interface += 3; + if (!forced_iso_ep) { + descriptor_counts->num_out_endpoints += 1; + descriptor_counts->num_in_endpoints += 1; + descriptor_counts->current_endpoint += 2; + } + + memcpy(descriptor_buf, usb_audio_descriptor, sizeof(usb_audio_descriptor)); + + return sizeof(usb_audio_descriptor); + } + + if (usb_audio_direction_is_output()) { + usb_add_interface_string(*current_interface_string, "CircuitPython Speaker"); + + // The AudioStreaming interface follows the AudioControl interface. + usb_audio_spk_as_itf = descriptor_counts->current_interface + 1; + + const uint8_t usb_audio_descriptor[] = { + USB_AUDIO_SPEAKER_DESCRIPTOR( + /*_itfnum*/ descriptor_counts->current_interface, + /*_stridx*/ *current_interface_string, + /*_nBytesPerSample*/ USB_AUDIO_N_BYTES_PER_SAMPLE, + /*_nBitsUsedPerSample*/ USB_AUDIO_BITS_PER_SAMPLE, + /*_epout*/ iso_ep_num, + /*_epsize*/ CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX) + }; + + (*current_interface_string)++; + // One IAD wrapping an AudioControl + an AudioStreaming interface, plus a + // single isochronous OUT endpoint. + descriptor_counts->current_interface += 2; + if (!forced_iso_ep) { + descriptor_counts->num_out_endpoints += 1; + descriptor_counts->current_endpoint += 1; + } + + memcpy(descriptor_buf, usb_audio_descriptor, sizeof(usb_audio_descriptor)); + + return sizeof(usb_audio_descriptor); + } + + usb_add_interface_string(*current_interface_string, "CircuitPython Microphone"); + + // The AudioStreaming interface follows the AudioControl interface. + usb_audio_mic_as_itf = descriptor_counts->current_interface + 1; + + const uint8_t usb_audio_descriptor[] = { + USB_AUDIO_MIC_DESCRIPTOR( + /*_itfnum*/ descriptor_counts->current_interface, + /*_stridx*/ *current_interface_string, + /*_nBytesPerSample*/ USB_AUDIO_N_BYTES_PER_SAMPLE, + /*_nBitsUsedPerSample*/ USB_AUDIO_BITS_PER_SAMPLE, + /*_epin*/ iso_ep_num | 0x80, + /*_epsize*/ CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX) + }; + + (*current_interface_string)++; + // One IAD wrapping an AudioControl + an AudioStreaming interface, plus a + // single isochronous IN endpoint. + descriptor_counts->current_interface += 2; + if (!forced_iso_ep) { + descriptor_counts->num_in_endpoints += 1; + descriptor_counts->current_endpoint += 1; + } + + memcpy(descriptor_buf, usb_audio_descriptor, sizeof(usb_audio_descriptor)); + + return sizeof(usb_audio_descriptor); +} + +// --------------------------------------------------------------------+ +// Speaker (host -> board) receive task +// --------------------------------------------------------------------+ + +// Drain everything the host has delivered to the OUT endpoint since the last +// pass into the active USBSpeaker's ring. TinyUSB's weak rx-done handler has +// already moved the isochronous data into ep_out_ff; we copy it out here, in +// task (non-ISR) context, matching the project's "defer ISR work" rule. The ring +// itself, and the overrun/underrun handling, live in USBSpeaker.c so the data +// sits in the audiosample source the output backend pulls from. +static void usb_audio_speaker_task(void) { + // One USB packet of scratch; we loop until ep_out_ff is empty. + static uint8_t chunk[CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX]; + + while (tud_audio_available() > 0) { + uint16_t got = tud_audio_read(chunk, sizeof(chunk)); + if (got == 0) { + break; + } + // tud_audio_read() never returns more than the buffer it was given, but + // clamp so the compiler can prove the drain copies stay within chunk[] + // once this loop is inlined into it. + if (got > sizeof(chunk)) { + got = sizeof(chunk); + } + usb_audio_usbspeaker_background_drain(chunk, got); + } +} + +// --------------------------------------------------------------------+ +// Microphone (board -> host) transmit task +// --------------------------------------------------------------------+ + +static void usb_audio_microphone_task(void) { + // Pace production by the IN FIFO level. Each pass we top the software FIFO + // back up to its half-full setpoint, generating only the samples the host has + // actually drained since the last pass. This limits our production rate to the + // host's true consumption rate (its USB SOF / audio clock), keeps the FIFO + // around the level TinyUSB's flow control targets so it can send steady + // nominal-size packets, and automatically catches up after any scheduling gap + // (GCpause, other background work) in a single pass instead of underrunning. + // Underruns here showed up to the host as discrete sample-drop/insert splices, + // i.e. the erratic ticking on a held tone. + tu_fifo_t *ep_in_ff = tud_audio_get_ep_in_ff(); + uint16_t const target = tu_fifo_depth(ep_in_ff) / 2; + + uint16_t count; + while ((count = tu_fifo_count(ep_in_ff)) < target) { + size_t want = target - count; + if (want > usb_audio_mic_samples_len) { + want = usb_audio_mic_samples_len; + } + + // Pull the next chunk from whichever USBMicrophone is playing. + bool underran = false; + size_t filled = usb_audio_usbmicrophone_background_fill((uint8_t *)usb_audio_mic_samples, want); + if (filled == 0) { + // No source attached, paused, or fully drained: keep the endpoint + // alive with silence so the host never sees a starved stream. + memset((uint8_t *)usb_audio_mic_samples, 0, want); + } else if (filled < want) { + // The source momentarily underran. Send just what it produced and + // let the FIFO cushion ride until it catches up next pass, rather + // than flooding the stream with a burst of silence. + want = filled; + underran = true; + } + + if (tud_audio_write((uint8_t *)usb_audio_mic_samples, (uint16_t)want) == 0) { + break; // FIFO unexpectedly full / host not ready + } + if (underran) { + break; + } + } +} + +void usb_audio_task(void) { + // Each direction is gated on the host having opened its AudioStreaming + // interface. For a headset both run in the same pass: drain the host's + // speaker audio and refill the mic stream independently. The single-direction + // modes simply never have the other flag set. + if (usb_audio_spk_streaming) { + usb_audio_speaker_task(); + } + if (usb_audio_mic_streaming) { + usb_audio_microphone_task(); + } +} + +// --------------------------------------------------------------------+ +// TinyUSB audio class callbacks (weak symbols overridden here) +// --------------------------------------------------------------------+ + +// Host opened/closed the AudioStreaming alternate setting. The host selects each +// direction's interface independently (a headset has two), so route by interface +// number to the matching streaming flag rather than assuming a single stream. +bool tud_audio_set_itf_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void)rhport; + uint8_t const itf = (uint8_t)tu_u16_low(p_request->wIndex); + bool const streaming = (tu_u16_low(p_request->wValue) != 0); + + if (itf == usb_audio_spk_as_itf) { + usb_audio_spk_streaming = streaming; + // Start each speaker streaming session from live audio: drop anything + // left in the OUT FIFO/ring from a previous session. + tud_audio_clear_ep_out_ff(); + usb_audio_usbspeaker_streaming_reset(); + } else if (itf == usb_audio_mic_as_itf) { + usb_audio_mic_streaming = streaming; + if (streaming) { + // Prime the FIFO for the first frame; after that each completed + // transfer schedules the next refill via tud_audio_tx_done_isr(). + usb_background_schedule(); + } + } + return true; +} + +// Invoked from the audio class transfer-complete path once the next packet has +// been loaded into the EP IN buffer. TinyUSB services audio completions in ISR +// context, so they never queue a USB event. A port that pumps the optional class +// tasks from a task loop sitting behind tud_task() therefore never refills the +// microphone FIFO. Scheduling the refill here keeps usb_audio independent of how +// a port drives TinyUSB. +bool tud_audio_tx_done_isr(uint8_t rhport, uint16_t n_bytes_sent, uint8_t func_id, + uint8_t ep_in, uint8_t cur_alt_setting) { + (void)rhport; + (void)n_bytes_sent; + (void)func_id; + (void)ep_in; + (void)cur_alt_setting; + + usb_background_schedule(); + return true; +} + +bool tud_audio_set_itf_close_ep_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void)rhport; + uint8_t const itf = (uint8_t)tu_u16_low(p_request->wIndex); + + if (itf == usb_audio_spk_as_itf) { + usb_audio_spk_streaming = false; + tud_audio_clear_ep_out_ff(); + usb_audio_usbspeaker_streaming_reset(); + } else if (itf == usb_audio_mic_as_itf) { + usb_audio_mic_streaming = false; + } + return true; +} + +// Class-specific SET requests for an entity (we accept mute/volume on the feature unit). +bool tud_audio_set_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request, uint8_t *pBuff) { + (void)rhport; + + uint8_t const channelNum = (uint8_t)tu_u16_low(p_request->wValue); + uint8_t const ctrlSel = (uint8_t)tu_u16_high(p_request->wValue); + uint8_t const entityID = (uint8_t)tu_u16_high(p_request->wIndex); + + // Only current-value requests are supported. + TU_VERIFY(p_request->bRequest == AUDIO20_CS_REQ_CUR); + + // A headset exposes a feature unit per direction; the speaker's id matches the + // single-direction USB_AUDIO_ENTITY_FEATURE_UNIT, the mic adds a second one. + // Mute/volume state is shared across them. + if (entityID == USB_AUDIO_ENTITY_FEATURE_UNIT || + entityID == USB_AUDIO_HS_ENTITY_MIC_FEATURE_UNIT) { + if (channelNum > USB_AUDIO_N_CHANNELS) { + return false; + } + switch (ctrlSel) { + case AUDIO20_FU_CTRL_MUTE: + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_1_t)); + usb_audio_mute[channelNum] = ((audio20_control_cur_1_t *)pBuff)->bCur; + return true; + + case AUDIO20_FU_CTRL_VOLUME: + TU_VERIFY(p_request->wLength == sizeof(audio20_control_cur_2_t)); + usb_audio_volume[channelNum] = ((audio20_control_cur_2_t *)pBuff)->bCur; + return true; + + default: + return false; + } + } + return false; +} + +// Class-specific GET requests for an entity (clock source, feature unit, input terminal). +bool tud_audio_get_req_entity_cb(uint8_t rhport, tusb_control_request_t const *p_request) { + (void)rhport; + + uint8_t const channelNum = (uint8_t)tu_u16_low(p_request->wValue); + uint8_t const ctrlSel = (uint8_t)tu_u16_high(p_request->wValue); + uint8_t const entityID = (uint8_t)tu_u16_high(p_request->wIndex); + + // Input terminal connector control. The single-mic descriptor uses + // USB_AUDIO_ENTITY_INPUT_TERMINAL; the headset's microphone input terminal is + // a distinct id. (The USB-streaming input terminals don't advertise a readable + // connector control, so the host won't query them here.) + if (entityID == USB_AUDIO_ENTITY_INPUT_TERMINAL || + entityID == USB_AUDIO_HS_ENTITY_MIC_INPUT_TERMINAL) { + switch (ctrlSel) { + case AUDIO20_TE_CTRL_CONNECTOR: { + audio20_desc_channel_cluster_t ret; + ret.bNrChannels = USB_AUDIO_N_CHANNELS; + ret.bmChannelConfig = (audio20_channel_config_t)0; + ret.iChannelNames = 0; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &ret, sizeof(ret)); + } + default: + return false; + } + } + + // Feature unit (mute/volume) for either the speaker or mic chain. + if (entityID == USB_AUDIO_ENTITY_FEATURE_UNIT || + entityID == USB_AUDIO_HS_ENTITY_MIC_FEATURE_UNIT) { + if (channelNum > USB_AUDIO_N_CHANNELS) { + return false; + } + switch (ctrlSel) { + case AUDIO20_FU_CTRL_MUTE: + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &usb_audio_mute[channelNum], sizeof(usb_audio_mute[channelNum])); + + case AUDIO20_FU_CTRL_VOLUME: + switch (p_request->bRequest) { + case AUDIO20_CS_REQ_CUR: + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &usb_audio_volume[channelNum], sizeof(usb_audio_volume[channelNum])); + + case AUDIO20_CS_REQ_RANGE: { + audio20_control_range_2_n_t(1) ret; + ret.wNumSubRanges = 1; + ret.subrange[0].bMin = -90 * 256; // -90 dB + ret.subrange[0].bMax = 90 * 256; // +90 dB + ret.subrange[0].bRes = 256; // 1 dB steps + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &ret, sizeof(ret)); + } + + default: + return false; + } + + default: + return false; + } + } + + // Clock source (sample rate set in usb_audio.enable()). + if (entityID == USB_AUDIO_ENTITY_CLOCK_SOURCE) { + switch (ctrlSel) { + case AUDIO20_CS_CTRL_SAM_FREQ: + switch (p_request->bRequest) { + case AUDIO20_CS_REQ_CUR: { + audio20_control_cur_4_t cur = { .bCur = (int32_t)usb_audio_sample_rate }; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &cur, sizeof(cur)); + } + + case AUDIO20_CS_REQ_RANGE: { + audio20_control_range_4_n_t(1) ret; + ret.wNumSubRanges = 1; + ret.subrange[0].bMin = (int32_t)usb_audio_sample_rate; + ret.subrange[0].bMax = (int32_t)usb_audio_sample_rate; + ret.subrange[0].bRes = 0; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &ret, sizeof(ret)); + } + + default: + return false; + } + + case AUDIO20_CS_CTRL_CLK_VALID: { + audio20_control_cur_1_t cur = { .bCur = 1 }; + return tud_audio_buffer_and_schedule_control_xfer(rhport, p_request, &cur, sizeof(cur)); + } + + default: + return false; + } + } + + return false; +} + +// Keep the per-VM singleton instances (and, for the microphone, its bound +// audiosample) alive for the GC. Installed in the module globals by +// usb_audio_setup_singletons() and reset to NULL at each VM start. +MP_REGISTER_ROOT_POINTER(mp_obj_t usb_audio_microphone_singleton); +MP_REGISTER_ROOT_POINTER(mp_obj_t usb_audio_speaker_singleton); diff --git a/shared-module/usb_audio/__init__.h b/shared-module/usb_audio/__init__.h new file mode 100644 index 00000000000..5730e6ef60b --- /dev/null +++ b/shared-module/usb_audio/__init__.h @@ -0,0 +1,59 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include +#include +#include + +#include "py/obj.h" +#include "supervisor/usb.h" + +// Enable/disable the USB Audio Class (UAC2) interface. These may only be +// called before USB is connected (i.e. from boot.py); they return false +// otherwise. At least one of microphone/speaker must be true; enabling both +// presents a combined headset. +bool shared_module_usb_audio_enable(mp_int_t sample_rate, mp_int_t channel_count, bool microphone, bool speaker); +bool shared_module_usb_audio_disable(void); + +// True once enable() has been called successfully. +bool usb_audio_enabled(void); + +// True while the host has opened either AudioStreaming alternate setting, i.e. it +// is actively listening or sending. This is the real "stream the audio now" +// signal. +bool usb_audio_streaming(void); + +// True while the host has the speaker (host -> board OUT) stream open. Distinct +// from usb_audio_streaming() so USBSpeaker can report its own direction even when +// it shares a headset function with a microphone. +bool usb_audio_speaker_streaming(void); + +// Negotiated audio format, valid when usb_audio_enabled() is true. +extern uint32_t usb_audio_sample_rate; +extern uint8_t usb_audio_channel_count; + +// Which streams were requested in enable(), valid when usb_audio_enabled() is +// true. Both true presents a combined headset. +extern bool usb_audio_microphone_enabled; +extern bool usb_audio_speaker_enabled; + +// Descriptor injection hooks, called from supervisor/shared/usb/usb_desc.c. +size_t usb_audio_descriptor_length(void); +size_t usb_audio_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string); + +// Background task that streams samples to the host, called from +// supervisor/shared/usb/usb.c. +void usb_audio_task(void); + +// (Re)create the USBMicrophone and USBSpeaker singleton instances for the +// current VM and install them as the usb_audio.usb_microphone and +// usb_audio.usb_speaker module attributes (or None when that direction was not +// enabled in boot.py). Called once per VM from usb_setup_with_vm(), mirroring +// usb_midi_setup_ports(): the instances live on the GC heap, which is reset +// between boot.py and code.py, so they must be rebuilt each time. +void usb_audio_setup_singletons(void); diff --git a/shared-module/usb_audio/tusb_config.h b/shared-module/usb_audio/tusb_config.h new file mode 100644 index 00000000000..d7bfb65b148 --- /dev/null +++ b/shared-module/usb_audio/tusb_config.h @@ -0,0 +1,7 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once diff --git a/shared-module/usb_audio/usb_audio_descriptors.h b/shared-module/usb_audio/usb_audio_descriptors.h new file mode 100644 index 00000000000..8fba956a2a6 --- /dev/null +++ b/shared-module/usb_audio/usb_audio_descriptors.h @@ -0,0 +1,147 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries LLC +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include + +// Fixed audio format for the UAC2 microphone profile. These must have no other +// dependencies because this header is included from the TinyUSB tusb_config.h +// (to size the IN endpoint) as well as from the descriptor/binding code. + +// Actual length, in bytes, of the audio function descriptor emitted for the +// current direction (mic, speaker, or headset). usb_desc.c reads this while +// assembling the configuration descriptor, adding it to total_descriptor_length +// so wTotalLength covers the exact bytes the audio function emits. That value +// MUST equal the descriptor we actually emitted: the three directions differ in +// length, so a compile-time maximum would over-report for the shorter ones and +// make the host swallow the interfaces that follow audio (CDC/MSC), breaking +// their enumeration. The full definition lives in __init__.c (also declared in +// __init__.h for the descriptor builder). +size_t usb_audio_descriptor_length(void); + +// The isochronous IN endpoint's wMaxPacketSize in the USB descriptor is computed +// for this rate, so it is the highest rate usb_audio.enable() will accept. +#define USB_AUDIO_MAX_SAMPLE_RATE (48000) +#define USB_AUDIO_N_CHANNELS (2) + +// 16-bit signed LE PCM. +#define USB_AUDIO_N_BYTES_PER_SAMPLE (2) +#define USB_AUDIO_BITS_PER_SAMPLE (USB_AUDIO_N_BYTES_PER_SAMPLE * 8) + +// Bytes per audio frame on the wire. The descriptors always declare +// USB_AUDIO_N_CHANNELS channels, whatever channel_count the sample has, so this +// is the granularity every buffer handed to/from TinyUSB must be a multiple of. +#define USB_AUDIO_BYTES_PER_FRAME (USB_AUDIO_N_BYTES_PER_SAMPLE * USB_AUDIO_N_CHANNELS) + +// Endpoint number for the single isochronous audio data endpoint. Most device +// controllers accept an ISO endpoint on any number, so the descriptor builder +// just takes the next sequential one (signalled by 0 here). The nRF52 USBD, +// however, implements isochronous transfers only on a fixed, dedicated endpoint +// number (8): its dcd_edpt_open() rejects any other number for an ISO endpoint, +// so the stream silently never opens and the host sees a mic/speaker that +// transfers no data. Such ports override this (e.g. -DUSB_AUDIO_ISO_EP_NUM=8 in +// the port's mpconfigport.mk) to force the audio endpoint onto that number. +#ifndef USB_AUDIO_ISO_EP_NUM +#define USB_AUDIO_ISO_EP_NUM (0) +#endif + +// Fixed UAC2 entity IDs baked into USB_AUDIO_MIC_DESCRIPTOR and the +// hand-rolled speaker descriptor (USB_AUDIO_SPEAKER_DESCRIPTOR in __init__.c). +// The speaker reuses the same IDs as the mic; only the terminal roles reverse +// (input terminal = USB streaming, output terminal = desktop speaker). +#define USB_AUDIO_ENTITY_INPUT_TERMINAL (0x01) +#define USB_AUDIO_ENTITY_FEATURE_UNIT (0x02) +#define USB_AUDIO_ENTITY_OUTPUT_TERMINAL (0x03) +#define USB_AUDIO_ENTITY_CLOCK_SOURCE (0x04) + +// Combined headset (microphone + speaker both enabled) topology. A single audio function +// carries both a speaker chain (host -> board) and a mic chain (board -> host), +// so every unit/terminal needs an ID unique across the whole function -- unlike +// the single-direction descriptors above, which can reuse the same small set. +// The clock source is shared by both chains. (USB_AUDIO_HEADSET_DESCRIPTOR in +// __init__.c bakes these in.) +#define USB_AUDIO_HS_ENTITY_CLOCK_SOURCE (0x04) +#define USB_AUDIO_HS_ENTITY_SPK_INPUT_TERMINAL (0x01) // USB streaming in from host +#define USB_AUDIO_HS_ENTITY_SPK_FEATURE_UNIT (0x02) +#define USB_AUDIO_HS_ENTITY_SPK_OUTPUT_TERMINAL (0x03) // desktop speaker +#define USB_AUDIO_HS_ENTITY_MIC_INPUT_TERMINAL (0x05) // generic microphone +#define USB_AUDIO_HS_ENTITY_MIC_FEATURE_UNIT (0x06) +#define USB_AUDIO_HS_ENTITY_MIC_OUTPUT_TERMINAL (0x07) // USB streaming out to host + +// Length of the no-feedback speaker descriptor. It uses the same set of +// sub-descriptors as USB_AUDIO_MIC_DESCRIPTOR (except one isochronous data +// endpoint, no feedback endpoint), so this is identical to +// USB_AUDIO_MIC_DESC_LEN -- but spell it out independently so the two +// can diverge later (e.g. stereo) without silently mis-sizing the descriptor. +// These TUD_AUDIO20_DESC_*_LEN macros come from TinyUSB's usbd.h; this expression +// is only expanded where that header is already included (never at the point +// tusb_config.h includes us), so the header stays dependency-free. +#define USB_AUDIO_SPEAKER_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN \ + + TUD_AUDIO20_DESC_STD_AC_LEN \ + + TUD_AUDIO20_DESC_CS_AC_LEN \ + + TUD_AUDIO20_DESC_CLK_SRC_LEN \ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN \ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN \ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2) \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN \ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN \ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN \ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) + +#define USB_AUDIO_MIC_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN \ + + TUD_AUDIO20_DESC_STD_AC_LEN \ + + TUD_AUDIO20_DESC_CS_AC_LEN \ + + TUD_AUDIO20_DESC_CLK_SRC_LEN \ + /* mic chain: microphone input terminal -> feature unit -> USB-streaming out */ \ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN \ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN \ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2) \ + /* mic AudioStreaming interface (alt 0 + alt 1 with IN endpoint) */ \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN \ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN \ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN \ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) + +// Length of the combined headset descriptor (microphone + speaker both enabled): one IAD +// wrapping a single AudioControl interface plus two AudioStreaming interfaces +// (speaker OUT + mic IN). The AC interface declares one shared clock, plus an +// input terminal / feature unit / output terminal for each of the two chains; +// each AS interface contributes a zero-bandwidth alt 0 and a streaming alt 1 +// with one isochronous data endpoint (no feedback endpoint, matching the +// single-direction descriptors). See USB_AUDIO_HEADSET_DESCRIPTOR in __init__.c. +// Expanded only where TinyUSB's usbd.h is already included (never at the point +// tusb_config.h includes us), so this header stays dependency-free. +#define USB_AUDIO_HEADSET_DESC_LEN (TUD_AUDIO20_DESC_IAD_LEN \ + + TUD_AUDIO20_DESC_STD_AC_LEN \ + + TUD_AUDIO20_DESC_CS_AC_LEN \ + + TUD_AUDIO20_DESC_CLK_SRC_LEN \ + /* speaker chain: USB-streaming input terminal -> feature unit -> speaker */ \ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN \ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2) \ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN \ + /* mic chain: microphone input terminal -> feature unit -> USB-streaming out */ \ + + TUD_AUDIO20_DESC_INPUT_TERM_LEN \ + + TUD_AUDIO20_DESC_FEATURE_UNIT_LEN(2) \ + + TUD_AUDIO20_DESC_OUTPUT_TERM_LEN \ + /* speaker AudioStreaming interface (alt 0 + alt 1 with OUT endpoint) */ \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN \ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN \ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN \ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN \ + /* mic AudioStreaming interface (alt 0 + alt 1 with IN endpoint) */ \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_STD_AS_LEN \ + + TUD_AUDIO20_DESC_CS_AS_INT_LEN \ + + TUD_AUDIO20_DESC_TYPE_I_FORMAT_LEN \ + + TUD_AUDIO20_DESC_STD_AS_ISO_EP_LEN \ + + TUD_AUDIO20_DESC_CS_AS_ISO_EP_LEN) diff --git a/shared-module/usb_cdc/Serial.c b/shared-module/usb_cdc/Serial.c index 3c67103afce..348729365c2 100644 --- a/shared-module/usb_cdc/Serial.c +++ b/shared-module/usb_cdc/Serial.c @@ -19,9 +19,7 @@ size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, // Read up to len bytes immediately. // The number of bytes read will not be larger than what is already in the TinyUSB FIFO. uint32_t total_num_read = 0; - if (tud_cdc_n_connected(self->idx)) { - total_num_read = tud_cdc_n_read(self->idx, data, len); - } + total_num_read = tud_cdc_n_read(self->idx, data, len); if (wait_forever || wait_for_timeout) { // Continue filling the buffer past what we already read. @@ -48,9 +46,7 @@ size_t common_hal_usb_cdc_serial_read(usb_cdc_serial_obj_t *self, uint8_t *data, data += num_read; // Try to read another batch of bytes. - if (tud_cdc_n_connected(self->idx)) { - num_read = tud_cdc_n_read(self->idx, data, len); - } + num_read = tud_cdc_n_read(self->idx, data, len); total_num_read += num_read; } } diff --git a/shared-module/usb_cdc/__init__.c b/shared-module/usb_cdc/__init__.c index 502d8fa620e..644c4ccae79 100644 --- a/shared-module/usb_cdc/__init__.c +++ b/shared-module/usb_cdc/__init__.c @@ -105,7 +105,7 @@ static const uint8_t usb_cdc_descriptor_template[] = { 0xFF, // 54 bEndpointAddress (OUT/H2D) [SET AT RUNTIME] #define CDC_DATA_OUT_ENDPOINT_INDEX 54 0x02, // 55 bmAttributes (Bulk) - #if USB_HIGHSPEED + #if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 0x00, 0x02, // 56,57 wMaxPacketSize 512 #else 0x40, 0x00, // 56,57 wMaxPacketSize 64 @@ -118,7 +118,7 @@ static const uint8_t usb_cdc_descriptor_template[] = { 0xFF, // 61 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number] #define CDC_DATA_IN_ENDPOINT_INDEX 61 0x02, // 62 bmAttributes (Bulk) - #if USB_HIGHSPEED + #if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 0x00, 0x02, // 63,64 wMaxPacketSize 512 #else 0x40, 0x00, // 63,64 wMaxPacketSize 64 @@ -192,6 +192,11 @@ size_t usb_cdc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *desc ? (USB_CDC_EP_NUM_DATA_IN ? USB_CDC_EP_NUM_DATA_IN : descriptor_counts->current_endpoint) : (USB_CDC2_EP_NUM_DATA_IN ? USB_CDC2_EP_NUM_DATA_IN : descriptor_counts->current_endpoint)); descriptor_counts->num_in_endpoints++; + // Some TinyUSB devices have issues with bi-directional endpoints + #ifdef TUD_ENDPOINT_ONE_DIRECTION_ONLY + descriptor_counts->current_endpoint++; + #endif + descriptor_buf[CDC_DATA_OUT_ENDPOINT_INDEX] = console ? (USB_CDC_EP_NUM_DATA_OUT ? USB_CDC_EP_NUM_DATA_OUT : descriptor_counts->current_endpoint) @@ -321,7 +326,7 @@ static const uint8_t usb_vendor_descriptor_template[] = { 0xFF, // 11 bEndpointAddress (IN/D2H) [SET AT RUNTIME: number] #define VENDOR_OUT_ENDPOINT_INDEX 11 0x02, // 12 bmAttributes (Bulk) - #if USB_HIGHSPEED + #if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 0x00, 0x02, // 13,14 wMaxPacketSize 512 #else 0x40, 0x00, // 13,14 wMaxPacketSize 64 @@ -351,10 +356,10 @@ size_t usb_vendor_descriptor_length(void) { static uint8_t *ms_os_20_descriptor = NULL; -size_t vendor_ms_os_20_descriptor_length() { +size_t vendor_ms_os_20_descriptor_length(void) { return ms_os_20_descriptor != NULL ? sizeof(ms_os_20_descriptor_template) : 0; } -uint8_t const *vendor_ms_os_20_descriptor() { +uint8_t const *vendor_ms_os_20_descriptor(void) { return ms_os_20_descriptor; } diff --git a/shared-module/usb_hid/Device.c b/shared-module/usb_hid/Device.c index d6c4697210f..42f5790123e 100644 --- a/shared-module/usb_hid/Device.c +++ b/shared-module/usb_hid/Device.c @@ -12,45 +12,10 @@ #include "shared-bindings/usb_hid/Device.h" #include "shared-module/usb_hid/__init__.h" #include "shared-module/usb_hid/Device.h" +#include "shared-module/usb_hid/report_descriptors.h" #include "supervisor/shared/tick.h" #include "tusb.h" -static const uint8_t keyboard_report_descriptor[] = { - 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) - 0x09, 0x06, // Usage (Keyboard) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x01, // Report ID (1) - 0x05, 0x07, // Usage Page (Kbrd/Keypad) - 0x19, 0xE0, // Usage Minimum (0xE0) - 0x29, 0xE7, // Usage Maximum (0xE7) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x75, 0x01, // Report Size (1) - 0x95, 0x08, // Report Count (8) - 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x95, 0x01, // Report Count (1) - 0x75, 0x08, // Report Size (8) - 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x95, 0x05, // Report Count (5) - 0x75, 0x01, // Report Size (1) - 0x05, 0x08, // Usage Page (LEDs) - 0x19, 0x01, // Usage Minimum (Num Lock) - 0x29, 0x05, // Usage Maximum (Kana) - 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - 0x95, 0x01, // Report Count (1) - 0x75, 0x03, // Report Size (3) - 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) - 0x95, 0x06, // Report Count (6) - 0x75, 0x08, // Report Size (8) - 0x15, 0x00, // Logical Minimum (0) - 0x26, 0xFF, 0x00, // Logical Maximum (255) - 0x05, 0x07, // Usage Page (Kbrd/Keypad) - 0x19, 0x00, // Usage Minimum (0x00) - 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) - 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, // End Collection -}; - const usb_hid_device_obj_t usb_hid_device_keyboard_obj = { .base = { .type = &usb_hid_device_type, @@ -65,42 +30,6 @@ const usb_hid_device_obj_t usb_hid_device_keyboard_obj = { .out_report_lengths = { 1, }, }; -static const uint8_t mouse_report_descriptor[] = { - 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) - 0x09, 0x02, // Usage (Mouse) - 0xA1, 0x01, // Collection (Application) - 0x09, 0x01, // Usage (Pointer) - 0xA1, 0x00, // Collection (Physical) - 0x85, 0x02, // 10, 11 Report ID (2) - 0x05, 0x09, // Usage Page (Button) - 0x19, 0x01, // Usage Minimum (0x01) - 0x29, 0x05, // Usage Maximum (0x05) - 0x15, 0x00, // Logical Minimum (0) - 0x25, 0x01, // Logical Maximum (1) - 0x95, 0x05, // Report Count (5) - 0x75, 0x01, // Report Size (1) - 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x95, 0x01, // Report Count (1) - 0x75, 0x03, // Report Size (3) - 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) - 0x09, 0x30, // Usage (X) - 0x09, 0x31, // Usage (Y) - 0x15, 0x81, // Logical Minimum (-127) - 0x25, 0x7F, // Logical Maximum (127) - 0x75, 0x08, // Report Size (8) - 0x95, 0x02, // Report Count (2) - 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) - 0x09, 0x38, // Usage (Wheel) - 0x15, 0x81, // Logical Minimum (-127) - 0x25, 0x7F, // Logical Maximum (127) - 0x75, 0x08, // Report Size (8) - 0x95, 0x01, // Report Count (1) - 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, // End Collection - 0xC0, // End Collection -}; - const usb_hid_device_obj_t usb_hid_device_mouse_obj = { .base = { .type = &usb_hid_device_type, @@ -115,21 +44,6 @@ const usb_hid_device_obj_t usb_hid_device_mouse_obj = { .out_report_lengths = { 0, }, }; -static const uint8_t consumer_control_report_descriptor[] = { - 0x05, 0x0C, // Usage Page (Consumer) - 0x09, 0x01, // Usage (Consumer Control) - 0xA1, 0x01, // Collection (Application) - 0x85, 0x03, // Report ID (3) - 0x75, 0x10, // Report Size (16) - 0x95, 0x01, // Report Count (1) - 0x15, 0x01, // Logical Minimum (1) - 0x26, 0x8C, 0x02, // Logical Maximum (652) - 0x19, 0x01, // Usage Minimum (Consumer Control) - 0x2A, 0x8C, 0x02, // Usage Maximum (AC Send) - 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) - 0xC0, // End Collection -}; - const usb_hid_device_obj_t usb_hid_device_consumer_control_obj = { .base = { .type = &usb_hid_device_type, diff --git a/shared-module/usb_hid/__init__.c b/shared-module/usb_hid/__init__.c index b007bc3ac2d..4d0d5fc2e3d 100644 --- a/shared-module/usb_hid/__init__.c +++ b/shared-module/usb_hid/__init__.c @@ -172,6 +172,12 @@ size_t usb_hid_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *desc descriptor_buf[HID_IN_ENDPOINT_INDEX] = 0x80 | (USB_HID_EP_NUM_IN ? USB_HID_EP_NUM_IN : descriptor_counts->current_endpoint); descriptor_counts->num_in_endpoints++; + + // Some TinyUSB devices have issues with bi-directional endpoints + #ifdef TUD_ENDPOINT_ONE_DIRECTION_ONLY + descriptor_counts->current_endpoint++; + #endif + descriptor_buf[HID_OUT_ENDPOINT_INDEX] = USB_HID_EP_NUM_OUT ? USB_HID_EP_NUM_OUT : descriptor_counts->current_endpoint; descriptor_counts->num_out_endpoints++; diff --git a/shared-module/usb_hid/report_descriptors.c b/shared-module/usb_hid/report_descriptors.c new file mode 100644 index 00000000000..fe629153c78 --- /dev/null +++ b/shared-module/usb_hid/report_descriptors.c @@ -0,0 +1,96 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 hathach for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Standard HID report descriptors shared between ports. + +#include "shared-module/usb_hid/report_descriptors.h" + +const uint8_t keyboard_report_descriptor[] = { + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x06, // Usage (Keyboard) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x01, // Report ID (1) + 0x05, 0x07, // Usage Page (Kbrd/Keypad) + 0x19, 0xE0, // Usage Minimum (0xE0) + 0x29, 0xE7, // Usage Maximum (0xE7) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x08, // Report Count (8) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x01, // Report Count (1) + 0x75, 0x08, // Report Size (8) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x05, // Report Count (5) + 0x75, 0x01, // Report Size (1) + 0x05, 0x08, // Usage Page (LEDs) + 0x19, 0x01, // Usage Minimum (Num Lock) + 0x29, 0x05, // Usage Maximum (Kana) + 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0x95, 0x01, // Report Count (1) + 0x75, 0x03, // Report Size (3) + 0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) + 0x95, 0x06, // Report Count (6) + 0x75, 0x08, // Report Size (8) + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x00, // Logical Maximum (255) + 0x05, 0x07, // Usage Page (Kbrd/Keypad) + 0x19, 0x00, // Usage Minimum (0x00) + 0x2A, 0xFF, 0x00, // Usage Maximum (0xFF) + 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection +}; + +const uint8_t mouse_report_descriptor[] = { + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x02, // Usage (Mouse) + 0xA1, 0x01, // Collection (Application) + 0x09, 0x01, // Usage (Pointer) + 0xA1, 0x00, // Collection (Physical) + 0x85, 0x02, // 10, 11 Report ID (2) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (0x01) + 0x29, 0x05, // Usage Maximum (0x05) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x95, 0x05, // Report Count (5) + 0x75, 0x01, // Report Size (1) + 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x95, 0x01, // Report Count (1) + 0x75, 0x03, // Report Size (3) + 0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7F, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x95, 0x02, // Report Count (2) + 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) + 0x09, 0x38, // Usage (Wheel) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7F, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x95, 0x01, // Report Count (1) + 0x81, 0x06, // Input (Data,Var,Rel,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection + 0xC0, // End Collection +}; + +const uint8_t consumer_control_report_descriptor[] = { + 0x05, 0x0C, // Usage Page (Consumer) + 0x09, 0x01, // Usage (Consumer Control) + 0xA1, 0x01, // Collection (Application) + 0x85, 0x03, // Report ID (3) + 0x75, 0x10, // Report Size (16) + 0x95, 0x01, // Report Count (1) + 0x15, 0x01, // Logical Minimum (1) + 0x26, 0x8C, 0x02, // Logical Maximum (652) + 0x19, 0x01, // Usage Minimum (Consumer Control) + 0x2A, 0x8C, 0x02, // Usage Maximum (AC Send) + 0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position) + 0xC0, // End Collection +}; diff --git a/shared-module/usb_hid/report_descriptors.h b/shared-module/usb_hid/report_descriptors.h new file mode 100644 index 00000000000..94a9a752f6a --- /dev/null +++ b/shared-module/usb_hid/report_descriptors.h @@ -0,0 +1,19 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2018 hathach for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +// Standard HID report descriptors shared between ports. These are plain byte +// arrays with no dependencies, so ports using TinyUSB and ports using other +// USB stacks can both use them. They are defined in report_descriptors.c. +// The explicit sizes let callers use sizeof() and are checked by the compiler +// against the definitions. + +#pragma once + +#include + +extern const uint8_t keyboard_report_descriptor[67]; +extern const uint8_t mouse_report_descriptor[64]; +extern const uint8_t consumer_control_report_descriptor[25]; diff --git a/shared-module/usb_midi/__init__.c b/shared-module/usb_midi/__init__.c index e0853e4e2a7..1722911536f 100644 --- a/shared-module/usb_midi/__init__.c +++ b/shared-module/usb_midi/__init__.c @@ -106,7 +106,7 @@ static const uint8_t usb_midi_descriptor_template[] = { 0xFF, // 66 bEndpointAddress (OUT/H2D) [SET AT RUNTIME] #define MIDI_STREAMING_OUT_ENDPOINT_INDEX (66) 0x02, // 67 bmAttributes (Bulk) - #if USB_HIGHSPEED + #if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 0x00, 0x02, // 68,69 wMaxPacketSize (512) #else 0x40, 0x00, // 68,69 wMaxPacketSize (64) @@ -126,7 +126,7 @@ static const uint8_t usb_midi_descriptor_template[] = { 0xFF, // 78 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number] #define MIDI_STREAMING_IN_ENDPOINT_INDEX (78) 0x02, // 79 bmAttributes (Bulk) - #if USB_HIGHSPEED + #if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 0x00, 0x02, // 80, 81 wMaxPacketSize (512) #else 0x40, 0x00, // 80, 81 wMaxPacketSize (64) @@ -176,6 +176,12 @@ size_t usb_midi_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *des descriptor_buf[MIDI_STREAMING_IN_ENDPOINT_INDEX] = 0x80 | (USB_MIDI_EP_NUM_IN ? USB_MIDI_EP_NUM_IN : descriptor_counts->current_endpoint); descriptor_counts->num_in_endpoints++; + + // Some TinyUSB devices have issues with bi-directional endpoints + #ifdef TUD_ENDPOINT_ONE_DIRECTION_ONLY + descriptor_counts->current_endpoint++; + #endif + descriptor_buf[MIDI_STREAMING_OUT_ENDPOINT_INDEX] = USB_MIDI_EP_NUM_OUT ? USB_MIDI_EP_NUM_OUT : descriptor_counts->current_endpoint; descriptor_counts->num_out_endpoints++; diff --git a/shared-module/vectorio/VectorShape.c b/shared-module/vectorio/VectorShape.c index ca6a68adb6d..3ac752f327c 100644 --- a/shared-module/vectorio/VectorShape.c +++ b/shared-module/vectorio/VectorShape.c @@ -96,10 +96,12 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou x = self->absolute_transform->x + self->absolute_transform->dx * self->y; y = self->absolute_transform->y + self->absolute_transform->dy * self->x; if (self->absolute_transform->dx < 1) { + x -= 1; out_area->y1 = out_area->y1 * -1 + 1; out_area->y2 = out_area->y2 * -1 + 1; } if (self->absolute_transform->dy < 1) { + y -= 1; out_area->x1 = out_area->x1 * -1 + 1; out_area->x2 = out_area->x2 * -1 + 1; } @@ -109,10 +111,12 @@ static void _get_screen_area(vectorio_vector_shape_t *self, displayio_area_t *ou y = self->absolute_transform->y + self->absolute_transform->dy * self->y; if (self->absolute_transform->dx < 1) { + x -= 1; out_area->x1 = out_area->x1 * -1 + 1; out_area->x2 = out_area->x2 * -1 + 1; } if (self->absolute_transform->dy < 1) { + y -= 1; out_area->y1 = out_area->y1 * -1 + 1; out_area->y2 = out_area->y2 * -1 + 1; } @@ -132,11 +136,12 @@ static void screen_to_shape_coordinates(vectorio_vector_shape_t *self, uint16_t VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", *out_shape_x, *out_shape_y); if (self->absolute_transform->dx < 1) { *out_shape_y *= -1; + *out_shape_y -= 1; } if (self->absolute_transform->dy < 1) { *out_shape_x *= -1; + *out_shape_x -= 1; } - VECTORIO_SHAPE_PIXEL_DEBUG(" b(%3d, %3d)", *out_shape_x, *out_shape_y); } else { *out_shape_x = x - self->absolute_transform->x - self->absolute_transform->dx * self->x; *out_shape_y = y - self->absolute_transform->y - self->absolute_transform->dy * self->y; @@ -144,12 +149,12 @@ static void screen_to_shape_coordinates(vectorio_vector_shape_t *self, uint16_t VECTORIO_SHAPE_PIXEL_DEBUG(" a(%3d, %3d)", *out_shape_x, *out_shape_y); if (self->absolute_transform->dx < 1) { *out_shape_x *= -1; + *out_shape_x -= 1; } if (self->absolute_transform->dy < 1) { *out_shape_y *= -1; + *out_shape_y -= 1; } - VECTORIO_SHAPE_PIXEL_DEBUG(" b(%3d, %3d)", *out_shape_x, *out_shape_y); - // It's mirrored via dx. Maybe we need to add support for also separately mirroring? // if (self->absolute_transform->mirror_x) { // pixel_to_get_x = (shape_area.x2 - shape_area.x1) - (pixel_to_get_x - shape_area.x1) + shape_area.x1 - 1; @@ -158,6 +163,7 @@ static void screen_to_shape_coordinates(vectorio_vector_shape_t *self, uint16_t // pixel_to_get_y = (shape_area.y2 - shape_area.y1) - (pixel_to_get_y - shape_area.y1) + +shape_area.y1 - 1; // } } + VECTORIO_SHAPE_PIXEL_DEBUG(" b(%3d, %3d)", *out_shape_x, *out_shape_y); } static void check_bounds_and_set_x(vectorio_vector_shape_t *self, mp_int_t x) { @@ -533,6 +539,7 @@ displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_ self->ephemeral_dirty_area.next = tail; tail = &self->ephemeral_dirty_area; } else { + self->current_area_dirty = true; self->current_area.next = tail; tail = &self->current_area; VECTORIO_SHAPE_DEBUG("%p get_refresh_area: redrawing current: {(%3d,%3d), (%3d,%3d)}\n", self, self->current_area.x1, self->current_area.y1, self->current_area.x2, self->current_area.y2); @@ -549,3 +556,9 @@ void vectorio_vector_shape_update_transform(vectorio_vector_shape_t *self, displ self->absolute_transform = group_transform == NULL ? &null_transform : group_transform; common_hal_vectorio_vector_shape_set_dirty(self); } + +bool vectorio_vector_shape_set_in_group(vectorio_vector_shape_t *self, bool in_group) { + bool was_in_group = self->in_group; + self->in_group = in_group; + return was_in_group; +} diff --git a/shared-module/vectorio/VectorShape.h b/shared-module/vectorio/VectorShape.h index db77fc0acb9..f66569f97d4 100644 --- a/shared-module/vectorio/VectorShape.h +++ b/shared-module/vectorio/VectorShape.h @@ -43,6 +43,7 @@ typedef struct { displayio_area_t current_area; bool current_area_dirty; bool hidden; + bool in_group; } vectorio_vector_shape_t; displayio_area_t *vectorio_vector_shape_get_refresh_areas(vectorio_vector_shape_t *self, displayio_area_t *tail); diff --git a/shared-module/zlib/__init__.c b/shared-module/zlib/__init__.c index 031432a215f..7becb6faf73 100644 --- a/shared-module/zlib/__init__.c +++ b/shared-module/zlib/__init__.c @@ -37,7 +37,7 @@ mp_obj_t common_hal_zlib_decompress(mp_obj_t data, mp_int_t wbits) { DEBUG_printf("sizeof(TINF_DATA)=" UINT_FMT "\n", sizeof(*decomp)); uzlib_uncompress_init(decomp, NULL, 0); mp_uint_t dest_buf_size = (bufinfo.len + 15) & ~15; - byte *dest_buf = m_new(byte, dest_buf_size); + byte *dest_buf = m_malloc_without_collect(dest_buf_size); decomp->dest = dest_buf; decomp->dest_limit = dest_buf + dest_buf_size; diff --git a/shared/libc/abort_.c b/shared/libc/abort_.c index 3051eae81e0..54eab67d3fb 100644 --- a/shared/libc/abort_.c +++ b/shared/libc/abort_.c @@ -1,7 +1,7 @@ #include -NORETURN void abort_(void); +MP_NORETURN void abort_(void); -NORETURN void abort_(void) { +MP_NORETURN void abort_(void) { mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("abort() called")); } diff --git a/shared/memzip/make-memzip.py b/shared/memzip/make-memzip.py index 92a5d6168bb..e406c55a43c 100755 --- a/shared/memzip/make-memzip.py +++ b/shared/memzip/make-memzip.py @@ -7,8 +7,6 @@ # This is somewhat like frozen modules in python, but allows arbitrary files # to be used. -from __future__ import print_function - import argparse import os import subprocess diff --git a/shared/netutils/netutils.c b/shared/netutils/netutils.c index 84b4405c41d..cd1422f7c80 100644 --- a/shared/netutils/netutils.c +++ b/shared/netutils/netutils.c @@ -63,7 +63,13 @@ void netutils_parse_ipv4_addr(mp_obj_t addr_in, uint8_t *out_ip, netutils_endian return; } const char *s = addr_str; - const char *s_top = addr_str + addr_len; + const char *s_top; + // Scan for the end of valid address characters + for (s_top = addr_str; s_top < addr_str + addr_len; s_top++) { + if (!(*s_top == '.' || (*s_top >= '0' && *s_top <= '9'))) { + break; + } + } for (mp_uint_t i = 3; ; i--) { mp_uint_t val = 0; for (; s < s_top && *s != '.'; s++) { diff --git a/shared/netutils/trace.c b/shared/netutils/trace.c index a6dfb42c28f..24af4d5ca31 100644 --- a/shared/netutils/trace.c +++ b/shared/netutils/trace.c @@ -56,7 +56,7 @@ static const char *ethertype_str(uint16_t type) { } void netutils_ethernet_trace(const mp_print_t *print, size_t len, const uint8_t *buf, unsigned int flags) { - mp_printf(print, "[% 8d] ETH%cX len=%u", mp_hal_ticks_ms(), flags & NETUTILS_TRACE_IS_TX ? 'T' : 'R', len); + mp_printf(print, "[% 8u] ETH%cX len=%u", (unsigned)mp_hal_ticks_ms(), flags & NETUTILS_TRACE_IS_TX ? 'T' : 'R', len); mp_printf(print, " dst=%02x:%02x:%02x:%02x:%02x:%02x", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); mp_printf(print, " src=%02x:%02x:%02x:%02x:%02x:%02x", buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]); diff --git a/shared/runtime/context_manager_helpers.c b/shared/runtime/context_manager_helpers.c index 56955da089c..5b025209ff7 100644 --- a/shared/runtime/context_manager_helpers.c +++ b/shared/runtime/context_manager_helpers.c @@ -7,8 +7,12 @@ #include "shared/runtime/context_manager_helpers.h" #include "py/obj.h" +#include "py/runtime.h" -static mp_obj_t default___enter__(mp_obj_t self_in) { - return self_in; +static mp_obj_t default___exit__(size_t n_args, const mp_obj_t *args) { + mp_obj_t dest[2]; + mp_load_method(args[0], MP_QSTR_deinit, dest); + mp_call_method_n_kw(0, 0, dest); + return mp_const_none; } -MP_DEFINE_CONST_FUN_OBJ_1(default___enter___obj, default___enter__); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(default___exit___obj, 4, 4, default___exit__); diff --git a/shared/runtime/context_manager_helpers.h b/shared/runtime/context_manager_helpers.h index d8ec102ac5a..10970ce1a1a 100644 --- a/shared/runtime/context_manager_helpers.h +++ b/shared/runtime/context_manager_helpers.h @@ -8,4 +8,13 @@ #include "py/obj.h" -MP_DECLARE_CONST_FUN_OBJ_1(default___enter___obj); +// An object that has a `deinit` method can use `default___enter___obj` and +// `default___exit___obj` to define the `__enter__` and `__exit__` members in +// its object table. +// +// `__enter__` returns the object itself, and `__exit__` calls its `deinit`. +// +// If enter/exit do anything else, such as taking & releasing a lock, these are +// not suitable. +#define default___enter___obj (mp_identity_obj) +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(default___exit___obj); diff --git a/shared/runtime/gchelper.h b/shared/runtime/gchelper.h index 645ee837f51..1e85e06f46e 100644 --- a/shared/runtime/gchelper.h +++ b/shared/runtime/gchelper.h @@ -41,6 +41,8 @@ typedef uintptr_t gc_helper_regs_t[4]; typedef uintptr_t gc_helper_regs_t[10]; #elif defined(__aarch64__) typedef uintptr_t gc_helper_regs_t[11]; // x19-x29 +#elif defined(__riscv) && (__riscv_xlen <= 64) +typedef uintptr_t gc_helper_regs_t[12]; // S0-S11 #endif #endif diff --git a/shared/runtime/gchelper_generic.c b/shared/runtime/gchelper_generic.c index 4ef2e73f7a2..230a2444005 100644 --- a/shared/runtime/gchelper_generic.c +++ b/shared/runtime/gchelper_generic.c @@ -42,13 +42,14 @@ // stack already by the caller. #if defined(__x86_64__) +// CIRCUITPY-CHANGE: use __asm__ instead of asm static void gc_helper_get_regs(gc_helper_regs_t arr) { - register long rbx asm ("rbx"); - register long rbp asm ("rbp"); - register long r12 asm ("r12"); - register long r13 asm ("r13"); - register long r14 asm ("r14"); - register long r15 asm ("r15"); + register long rbx __asm__ ("rbx"); + register long rbp __asm__ ("rbp"); + register long r12 __asm__ ("r12"); + register long r13 __asm__ ("r13"); + register long r14 __asm__ ("r14"); + register long r15 __asm__ ("r15"); #ifdef __clang__ // TODO: // This is dirty workaround for Clang. It tries to get around @@ -56,12 +57,12 @@ static void gc_helper_get_regs(gc_helper_regs_t arr) { // Application of this patch here is random, and done only to unbreak // MacOS build. Better, cross-arch ways to deal with Clang issues should // be found. - asm ("" : "=r" (rbx)); - asm ("" : "=r" (rbp)); - asm ("" : "=r" (r12)); - asm ("" : "=r" (r13)); - asm ("" : "=r" (r14)); - asm ("" : "=r" (r15)); + __asm__ ("" : "=r" (rbx)); + __asm__ ("" : "=r" (rbp)); + __asm__ ("" : "=r" (r12)); + __asm__ ("" : "=r" (r13)); + __asm__ ("" : "=r" (r14)); + __asm__ ("" : "=r" (r15)); #endif arr[0] = rbx; arr[1] = rbp; @@ -74,10 +75,10 @@ static void gc_helper_get_regs(gc_helper_regs_t arr) { #elif defined(__i386__) static void gc_helper_get_regs(gc_helper_regs_t arr) { - register long ebx asm ("ebx"); - register long esi asm ("esi"); - register long edi asm ("edi"); - register long ebp asm ("ebp"); + register long ebx __asm__ ("ebx"); + register long esi __asm__ ("esi"); + register long edi __asm__ ("edi"); + register long ebp __asm__ ("ebp"); #ifdef __clang__ // TODO: // This is dirty workaround for Clang. It tries to get around @@ -85,10 +86,10 @@ static void gc_helper_get_regs(gc_helper_regs_t arr) { // Application of this patch here is random, and done only to unbreak // MacOS build. Better, cross-arch ways to deal with Clang issues should // be found. - asm ("" : "=r" (ebx)); - asm ("" : "=r" (esi)); - asm ("" : "=r" (edi)); - asm ("" : "=r" (ebp)); + __asm__ ("" : "=r" (ebx)); + __asm__ ("" : "=r" (esi)); + __asm__ ("" : "=r" (edi)); + __asm__ ("" : "=r" (ebp)); #endif arr[0] = ebx; arr[1] = esi; @@ -101,16 +102,20 @@ static void gc_helper_get_regs(gc_helper_regs_t arr) { // Fallback implementation, prefer gchelper_thumb1.s or gchelper_thumb2.s static void gc_helper_get_regs(gc_helper_regs_t arr) { - register long r4 asm ("r4"); - register long r5 asm ("r5"); - register long r6 asm ("r6"); - register long r7 asm ("r7"); - register long r8 asm ("r8"); - register long r9 asm ("r9"); - register long r10 asm ("r10"); - register long r11 asm ("r11"); - register long r12 asm ("r12"); - register long r13 asm ("r13"); + #ifdef __clang__ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wuninitialized" + #endif + register long r4 __asm__ ("r4"); + register long r5 __asm__ ("r5"); + register long r6 __asm__ ("r6"); + register long r7 __asm__ ("r7"); + register long r8 __asm__ ("r8"); + register long r9 __asm__ ("r9"); + register long r10 __asm__ ("r10"); + register long r11 __asm__ ("r11"); + register long r12 __asm__ ("r12"); + register long r13 __asm__ ("r13"); arr[0] = r4; arr[1] = r5; arr[2] = r6; @@ -121,22 +126,25 @@ static void gc_helper_get_regs(gc_helper_regs_t arr) { arr[7] = r11; arr[8] = r12; arr[9] = r13; + #ifdef __clang__ + #pragma clang diagnostic pop + #endif } #elif defined(__aarch64__) static void gc_helper_get_regs(gc_helper_regs_t arr) { - const register long x19 asm ("x19"); - const register long x20 asm ("x20"); - const register long x21 asm ("x21"); - const register long x22 asm ("x22"); - const register long x23 asm ("x23"); - const register long x24 asm ("x24"); - const register long x25 asm ("x25"); - const register long x26 asm ("x26"); - const register long x27 asm ("x27"); - const register long x28 asm ("x28"); - const register long x29 asm ("x29"); + const register long x19 __asm__ ("x19"); + const register long x20 __asm__ ("x20"); + const register long x21 __asm__ ("x21"); + const register long x22 __asm__ ("x22"); + const register long x23 __asm__ ("x23"); + const register long x24 __asm__ ("x24"); + const register long x25 __asm__ ("x25"); + const register long x26 __asm__ ("x26"); + const register long x27 __asm__ ("x27"); + const register long x28 __asm__ ("x28"); + const register long x29 __asm__ ("x29"); arr[0] = x19; arr[1] = x20; arr[2] = x21; @@ -150,6 +158,38 @@ static void gc_helper_get_regs(gc_helper_regs_t arr) { arr[10] = x29; } +#elif defined(__riscv) && (__riscv_xlen <= 64) + +// Fallback implementation for RV32I and RV64I, prefer gchelper_rv32i.s +// for RV32I targets or gchelper_rv64i.s for RV64I targets. + +static void gc_helper_get_regs(gc_helper_regs_t arr) { + register uintptr_t s0 __asm__ ("x8"); + register uintptr_t s1 __asm__ ("x9"); + register uintptr_t s2 __asm__ ("x18"); + register uintptr_t s3 __asm__ ("x19"); + register uintptr_t s4 __asm__ ("x20"); + register uintptr_t s5 __asm__ ("x21"); + register uintptr_t s6 __asm__ ("x22"); + register uintptr_t s7 __asm__ ("x23"); + register uintptr_t s8 __asm__ ("x24"); + register uintptr_t s9 __asm__ ("x25"); + register uintptr_t s10 __asm__ ("x26"); + register uintptr_t s11 __asm__ ("x27"); + arr[0] = s0; + arr[1] = s1; + arr[2] = s2; + arr[3] = s3; + arr[4] = s4; + arr[5] = s5; + arr[6] = s6; + arr[7] = s7; + arr[8] = s8; + arr[9] = s9; + arr[10] = s10; + arr[11] = s11; +} + #else #error "Architecture not supported for gc_helper_get_regs. Set MICROPY_GCREGS_SETJMP to use the fallback implementation." diff --git a/shared/runtime/gchelper_rv32i.s b/shared/runtime/gchelper_rv32i.s new file mode 100644 index 00000000000..64248e771a8 --- /dev/null +++ b/shared/runtime/gchelper_rv32i.s @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + + .global gc_helper_get_regs_and_sp + .type gc_helper_get_regs_and_sp, @function + +gc_helper_get_regs_and_sp: + + /* Store registers into the given array. */ + + sw x8, 0(x10) /* Save S0. */ + sw x9, 4(x10) /* Save S1. */ + sw x18, 8(x10) /* Save S2. */ + sw x19, 12(x10) /* Save S3. */ + sw x20, 16(x10) /* Save S4. */ + sw x21, 20(x10) /* Save S5. */ + sw x22, 24(x10) /* Save S6. */ + sw x23, 28(x10) /* Save S7. */ + sw x24, 32(x10) /* Save S8. */ + sw x25, 36(x10) /* Save S9. */ + sw x26, 40(x10) /* Save S10. */ + sw x27, 44(x10) /* Save S11. */ + + /* Return the stack pointer. */ + + add x10, x0, x2 + jalr x0, x1, 0 + + .size gc_helper_get_regs_and_sp, .-gc_helper_get_regs_and_sp diff --git a/shared/runtime/gchelper_rv64i.s b/shared/runtime/gchelper_rv64i.s new file mode 100644 index 00000000000..147a0e2bf5b --- /dev/null +++ b/shared/runtime/gchelper_rv64i.s @@ -0,0 +1,52 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + + .global gc_helper_get_regs_and_sp + .type gc_helper_get_regs_and_sp, @function + +gc_helper_get_regs_and_sp: + + /* Store registers into the given array. */ + + sd x8, 0(x10) /* Save S0. */ + sd x9, 8(x10) /* Save S1. */ + sd x18, 16(x10) /* Save S2. */ + sd x19, 24(x10) /* Save S3. */ + sd x20, 32(x10) /* Save S4. */ + sd x21, 40(x10) /* Save S5. */ + sd x22, 48(x10) /* Save S6. */ + sd x23, 56(x10) /* Save S7. */ + sd x24, 64(x10) /* Save S8. */ + sd x25, 72(x10) /* Save S9. */ + sd x26, 80(x10) /* Save S10. */ + sd x27, 88(x10) /* Save S11. */ + + /* Return the stack pointer. */ + + add x10, x0, x2 + jalr x0, x1, 0 + + .size gc_helper_get_regs_and_sp, .-gc_helper_get_regs_and_sp diff --git a/shared/runtime/interrupt_char.c b/shared/runtime/interrupt_char.c index 1dfccc4b5c8..1f270201719 100644 --- a/shared/runtime/interrupt_char.c +++ b/shared/runtime/interrupt_char.c @@ -31,6 +31,16 @@ #if MICROPY_KBD_EXCEPTION +// CIRCUITPY-CHANGE +#ifdef __ZEPHYR__ +#include + +// This semaphore is released when an interrupt character is seen. Core CP code +// can wait for this release but shouldn't take it. They should return instead +// after cancelling what they were doing. +K_SEM_DEFINE(mp_interrupt_sem, 0, 1); +#endif + int mp_interrupt_char = -1; void mp_hal_set_interrupt_char(int c) { diff --git a/shared/runtime/interrupt_char.h b/shared/runtime/interrupt_char.h index f15036545c1..44fd4b45a61 100644 --- a/shared/runtime/interrupt_char.h +++ b/shared/runtime/interrupt_char.h @@ -29,6 +29,17 @@ // CIRCUITPY-CHANGE #include +// CIRCUITPY-CHANGE +#ifdef __ZEPHYR__ +#include + +// This semaphore is released when an interrupt character is seen. Core CP code +// can wait for this release but shouldn't take it. They should return instead +// after cancelling what they were doing. +extern struct k_sem mp_interrupt_sem; +#endif + + extern int mp_interrupt_char; void mp_hal_set_interrupt_char(int c); // CIRCUITPY-CHANGE diff --git a/shared/runtime/mpirq.c b/shared/runtime/mpirq.c deleted file mode 100644 index 6111b9b10cf..00000000000 --- a/shared/runtime/mpirq.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2015 Daniel Campora - * 2018 Tobias Badertscher - * - * 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. - */ - -#include - -#include "py/runtime.h" -#include "py/gc.h" -#include "shared/runtime/mpirq.h" - -#if MICROPY_ENABLE_SCHEDULER - -/****************************************************************************** - DECLARE PUBLIC DATA - ******************************************************************************/ - -const mp_arg_t mp_irq_init_args[] = { - { MP_QSTR_handler, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_NONE} }, - { MP_QSTR_trigger, MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} }, -}; - -/****************************************************************************** - DECLARE PRIVATE DATA - ******************************************************************************/ - -/****************************************************************************** - DEFINE PUBLIC FUNCTIONS - ******************************************************************************/ - -mp_irq_obj_t *mp_irq_new(const mp_irq_methods_t *methods, mp_obj_t parent) { - mp_irq_obj_t *self = m_new0(mp_irq_obj_t, 1); - mp_irq_init(self, methods, parent); - return self; -} - -void mp_irq_init(mp_irq_obj_t *self, const mp_irq_methods_t *methods, mp_obj_t parent) { - self->base.type = &mp_irq_type; - self->methods = (mp_irq_methods_t *)methods; - self->parent = parent; - self->handler = mp_const_none; - self->ishard = false; -} - -void mp_irq_handler(mp_irq_obj_t *self) { - if (self->handler != mp_const_none) { - if (self->ishard) { - // When executing code within a handler we must lock the scheduler to - // prevent any scheduled callbacks from running, and lock the GC to - // prevent any memory allocations. - mp_sched_lock(); - gc_lock(); - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_call_function_1(self->handler, self->parent); - nlr_pop(); - } else { - // Uncaught exception; disable the callback so that it doesn't run again - self->methods->trigger(self->parent, 0); - self->handler = mp_const_none; - mp_printf(MICROPY_ERROR_PRINTER, "Uncaught exception in IRQ callback handler\n"); - mp_obj_print_exception(MICROPY_ERROR_PRINTER, MP_OBJ_FROM_PTR(nlr.ret_val)); - } - gc_unlock(); - mp_sched_unlock(); - } else { - // Schedule call to user function - mp_sched_schedule(self->handler, self->parent); - } - } -} - -/******************************************************************************/ -// MicroPython bindings - -static mp_obj_t mp_irq_flags(mp_obj_t self_in) { - mp_irq_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_int(self->methods->info(self->parent, MP_IRQ_INFO_FLAGS)); -} -static MP_DEFINE_CONST_FUN_OBJ_1(mp_irq_flags_obj, mp_irq_flags); - -static mp_obj_t mp_irq_trigger(size_t n_args, const mp_obj_t *args) { - mp_irq_obj_t *self = MP_OBJ_TO_PTR(args[0]); - mp_obj_t ret_obj = mp_obj_new_int(self->methods->info(self->parent, MP_IRQ_INFO_TRIGGERS)); - if (n_args == 2) { - // Set trigger - self->methods->trigger(self->parent, mp_obj_get_int(args[1])); - } - return ret_obj; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_irq_trigger_obj, 1, 2, mp_irq_trigger); - -static mp_obj_t mp_irq_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 0, 0, false); - mp_irq_handler(MP_OBJ_TO_PTR(self_in)); - return mp_const_none; -} - -static const mp_rom_map_elem_t mp_irq_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_flags), MP_ROM_PTR(&mp_irq_flags_obj) }, - { MP_ROM_QSTR(MP_QSTR_trigger), MP_ROM_PTR(&mp_irq_trigger_obj) }, -}; -static MP_DEFINE_CONST_DICT(mp_irq_locals_dict, mp_irq_locals_dict_table); - -MP_DEFINE_CONST_OBJ_TYPE( - mp_irq_type, - MP_QSTR_irq, - MP_TYPE_FLAG_NONE, - call, mp_irq_call, - locals_dict, &mp_irq_locals_dict - ); - -#endif // MICROPY_ENABLE_SCHEDULER diff --git a/shared/runtime/mpirq.h b/shared/runtime/mpirq.h deleted file mode 100644 index dd423c01011..00000000000 --- a/shared/runtime/mpirq.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2015 Daniel Campora - * - * 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. - */ -#ifndef MICROPY_INCLUDED_LIB_UTILS_MPIRQ_H -#define MICROPY_INCLUDED_LIB_UTILS_MPIRQ_H - -#include "py/runtime.h" - -/****************************************************************************** - DEFINE CONSTANTS - ******************************************************************************/ - -enum { - MP_IRQ_ARG_INIT_handler = 0, - MP_IRQ_ARG_INIT_trigger, - MP_IRQ_ARG_INIT_hard, - MP_IRQ_ARG_INIT_NUM_ARGS, -}; - -/****************************************************************************** - DEFINE TYPES - ******************************************************************************/ - -typedef mp_uint_t (*mp_irq_trigger_fun_t)(mp_obj_t self, mp_uint_t trigger); -typedef mp_uint_t (*mp_irq_info_fun_t)(mp_obj_t self, mp_uint_t info_type); - -enum { - MP_IRQ_INFO_FLAGS, - MP_IRQ_INFO_TRIGGERS, -}; - -typedef struct _mp_irq_methods_t { - mp_irq_trigger_fun_t trigger; - mp_irq_info_fun_t info; -} mp_irq_methods_t; - -typedef struct _mp_irq_obj_t { - mp_obj_base_t base; - mp_irq_methods_t *methods; - mp_obj_t parent; - mp_obj_t handler; - bool ishard; -} mp_irq_obj_t; - -/****************************************************************************** - DECLARE EXPORTED DATA - ******************************************************************************/ - -extern const mp_arg_t mp_irq_init_args[]; -extern const mp_obj_type_t mp_irq_type; - -/****************************************************************************** - DECLARE PUBLIC FUNCTIONS - ******************************************************************************/ - -mp_irq_obj_t *mp_irq_new(const mp_irq_methods_t *methods, mp_obj_t parent); -void mp_irq_init(mp_irq_obj_t *self, const mp_irq_methods_t *methods, mp_obj_t parent); -void mp_irq_handler(mp_irq_obj_t *self); - -#endif // MICROPY_INCLUDED_LIB_UTILS_MPIRQ_H diff --git a/shared/runtime/pyexec.c b/shared/runtime/pyexec.c index 050a14ef82e..bc5f89bdc81 100644 --- a/shared/runtime/pyexec.c +++ b/shared/runtime/pyexec.c @@ -31,28 +31,24 @@ // CIRCUITPY-CHANGE: add #include "py/mphal.h" + #include "py/compile.h" #include "py/runtime.h" #include "py/repl.h" #include "py/gc.h" #include "py/frozenmod.h" #include "py/mphal.h" -// CIRCUITPY-CHANGE: prevent undefined warning -#if defined(MICROPY_HW_ENABLE_USB) && MICROPY_HW_ENABLE_USB -#include "irq.h" -#include "usb.h" -#endif #include "shared/readline/readline.h" #include "shared/runtime/pyexec.h" +#include "extmod/modplatform.h" #include "genhdr/mpversion.h" -// CIRCUITPY-CHANGE: atexit support +// CIRCUITPY-CHANGE: add atexit support #if CIRCUITPY_ATEXIT #include "shared-module/atexit/__init__.h" #endif pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; -int pyexec_system_exit = 0; #if MICROPY_REPL_INFO static bool repl_display_debugging_info = 0; @@ -85,62 +81,74 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input MICROPY_BOARD_BEFORE_PYTHON_EXEC(input_kind, exec_flags); #endif - // by default a SystemExit exception returns 0 - pyexec_system_exit = 0; - nlr_buf_t nlr; nlr.ret_val = NULL; if (nlr_push(&nlr) == 0) { - mp_obj_t module_fun; - // CIRCUITPY-CHANGE + #if MICROPY_PYEXEC_ENABLE_VM_ABORT + nlr_set_abort(&nlr); + #endif + + // CIRCUITPY-CHANGE: move declaration for easier handling of atexit #if. + // Also make it possible to determine if module_fun was set. + mp_obj_t module_fun = NULL; + + // CIRCUITPY-CHANGE: add atexit support #if CIRCUITPY_ATEXIT - if (!(exec_flags & EXEC_FLAG_SOURCE_IS_ATEXIT)) + if (exec_flags & EXEC_FLAG_SOURCE_IS_ATEXIT) { + atexit_callback_t *callback = (atexit_callback_t *)source; + mp_call_function_n_kw(callback->func, callback->n_pos, callback->n_kw, callback->args); + } else #endif - // CIRCUITPY-CHANGE: multiple code changes - { - #if MICROPY_MODULE_FROZEN_MPY - if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) { - // source is a raw_code object, create the function - const mp_frozen_module_t *frozen = source; - mp_module_context_t *ctx = m_new_obj(mp_module_context_t); - ctx->module.globals = mp_globals_get(); - ctx->constants = frozen->constants; - module_fun = mp_make_function_from_proto_fun(frozen->proto_fun, ctx, NULL); - } else - #endif - { - #if MICROPY_ENABLE_COMPILER - mp_lexer_t *lex; - if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) { - const vstr_t *vstr = source; - lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0); - } else if (exec_flags & EXEC_FLAG_SOURCE_IS_READER) { - lex = mp_lexer_new(MP_QSTR__lt_stdin_gt_, *(mp_reader_t *)source); - } else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) { - lex = mp_lexer_new_from_file(qstr_from_str(source)); - } else { - lex = (mp_lexer_t *)source; - } - // source is a lexer, parse and compile the script - qstr source_name = lex->source_name; - // CIRCUITPY-CHANGE - #if MICROPY_PY___FILE__ - if (input_kind == MP_PARSE_FILE_INPUT) { - mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); - } - #endif - mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); - module_fun = mp_compile(&parse_tree, source_name, exec_flags & EXEC_FLAG_IS_REPL); - #else - mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("script compilation not supported")); - #endif + #if MICROPY_MODULE_FROZEN_MPY + if (exec_flags & EXEC_FLAG_SOURCE_IS_RAW_CODE) { + // source is a raw_code object, create the function + const mp_frozen_module_t *frozen = source; + mp_module_context_t *ctx = m_new_obj(mp_module_context_t); + ctx->module.globals = mp_globals_get(); + ctx->constants = frozen->constants; + module_fun = mp_make_function_from_proto_fun(frozen->proto_fun, ctx, NULL); + } else + #endif + { + #if MICROPY_ENABLE_COMPILER + mp_lexer_t *lex; + if (exec_flags & EXEC_FLAG_SOURCE_IS_VSTR) { + const vstr_t *vstr = source; + lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr->buf, vstr->len, 0); + } else if (exec_flags & EXEC_FLAG_SOURCE_IS_READER) { + lex = mp_lexer_new(MP_QSTR__lt_stdin_gt_, *(mp_reader_t *)source); + } else if (exec_flags & EXEC_FLAG_SOURCE_IS_FILENAME) { + lex = mp_lexer_new_from_file(qstr_from_str(source)); + } else { + lex = (mp_lexer_t *)source; } - - // If the code was loaded from a file, collect any garbage before running. + // source is a lexer, parse and compile the script + qstr source_name = lex->source_name; + #if MICROPY_MODULE___FILE__ if (input_kind == MP_PARSE_FILE_INPUT) { - gc_collect(); + mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } + #endif + mp_parse_tree_t parse_tree = mp_parse(lex, input_kind); + #if defined(MICROPY_UNIX_COVERAGE) + // allow to print the parse tree in the coverage build + if (mp_verbose_flag >= 3) { + printf("----------------\n"); + mp_parse_node_print(&mp_plat_print, parse_tree.root, 0); + printf("----------------\n"); + } + #endif + module_fun = mp_compile(&parse_tree, source_name, exec_flags & EXEC_FLAG_IS_REPL); + #else + mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("script compilation not supported")); + #endif + } + + // CIRCUITPY-CHANGE: garbage collect after loading + // If the code was loaded from a file, collect any garbage before running. + if (input_kind == MP_PARSE_FILE_INPUT) { + gc_collect(); } // execute code @@ -150,21 +158,19 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input #if MICROPY_REPL_INFO start = mp_hal_ticks_ms(); #endif - // CIRCUITPY-CHANGE - #if CIRCUITPY_ATEXIT - if (exec_flags & EXEC_FLAG_SOURCE_IS_ATEXIT) { - atexit_callback_t *callback = (atexit_callback_t *)source; - mp_call_function_n_kw(callback->func, callback->n_pos, callback->n_kw, callback->args); - } else + #if MICROPY_PYEXEC_COMPILE_ONLY + if (!mp_compile_only) #endif { - mp_call_function_0(module_fun); + // CIRCUITPY-CHANGE: if atexit function was called, there is nothing to call. + if (module_fun != NULL) { + mp_call_function_0(module_fun); + } } mp_hal_set_interrupt_char(-1); // disable interrupt mp_handle_pending(true); // handle any pending exceptions (and any callbacks) nlr_pop(); - // CIRCUITPY-CHANGE - ret = 0; + ret = PYEXEC_NORMAL_EXIT; if (exec_flags & EXEC_FLAG_PRINT_EOF) { mp_hal_stdout_tx_strn("\x04", 1); } @@ -183,36 +189,65 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input mp_hal_stdout_tx_strn("\x04", 1); } - // check for SystemExit - - // CIRCUITPY-CHANGE + // CIRCUITPY-CHANGE: Name and use some values. // nlr.ret_val is an exception object. mp_obj_t exception_obj = (mp_obj_t)nlr.ret_val; + const mp_obj_type_t *exception_obj_type = mp_obj_get_type(exception_obj); + + #if MICROPY_PYEXEC_ENABLE_VM_ABORT + if (nlr.ret_val == NULL) { // abort + ret = PYEXEC_ABORT; + } else + #endif - if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(exception_obj)), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { - // at the moment, the value of SystemExit is unused - ret = pyexec_system_exit; - // CIRCUITPY-CHANGE + if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(exception_obj_type), MP_OBJ_FROM_PTR(&mp_type_SystemExit))) { // system exit + #if MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING + // None is an exit value of 0; an int is its value; anything else is 1 + mp_obj_t val = mp_obj_exception_get_value(MP_OBJ_FROM_PTR(nlr.ret_val)); + if (val != mp_const_none) { + if (mp_obj_is_int(val)) { + ret = (int)mp_obj_int_get_truncated(val); + } else { + mp_obj_print_helper(MICROPY_ERROR_PRINTER, val, PRINT_STR); + mp_print_str(MICROPY_ERROR_PRINTER, "\n"); + ret = PYEXEC_UNHANDLED_EXCEPTION; + } + } else { + ret = PYEXEC_NORMAL_EXIT; + } + // Set PYEXEC_FORCED_EXIT flag so REPL knows to exit + ret |= PYEXEC_FORCED_EXIT; + #else + ret = PYEXEC_FORCED_EXIT; + #endif + // CIRCUITPY-CHANGE: support DeepSleepRequest #if CIRCUITPY_ALARM - } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(exception_obj)), MP_OBJ_FROM_PTR(&mp_type_DeepSleepRequest))) { + } else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(exception_obj_type), MP_OBJ_FROM_PTR(&mp_type_DeepSleepRequest))) { ret = PYEXEC_DEEP_SLEEP; #endif + // CIRCUITPY-CHANGE: support ReloadException } else if (exception_obj == MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_reload_exception))) { ret = PYEXEC_RELOAD; - } else { - mp_obj_print_exception(&mp_plat_print, exception_obj); - ret = PYEXEC_EXCEPTION; + } else { // other exception + mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val)); + ret = PYEXEC_UNHANDLED_EXCEPTION; + #if MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING + if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_KeyboardInterrupt))) { // keyboard interrupt + ret = PYEXEC_KEYBOARD_INTERRUPT; + } + #endif } - } + + // CIRCUITPY_CHANGE: Fill in result out argument. if (result != NULL) { result->return_code = ret; - #if CIRCUITPY_ALARM // Don't set the exception object if we exited for deep sleep. - if (ret != 0 && ret != PYEXEC_DEEP_SLEEP) { - #else - if (ret != 0) { + if (ret != 0 + #if CIRCUITPY_ALARM + && ret != PYEXEC_DEEP_SLEEP #endif + ) { mp_obj_t return_value = (mp_obj_t)nlr.ret_val; result->exception = return_value; result->exception_line = -1; @@ -229,6 +264,10 @@ static int parse_compile_execute(const void *source, mp_parse_input_kind_t input } } + #if MICROPY_PYEXEC_ENABLE_VM_ABORT + nlr_set_abort(NULL); + #endif + #if MICROPY_REPL_INFO // display debugging info if wanted if ((exec_flags & EXEC_FLAG_ALLOW_DEBUGGING) && repl_display_debugging_info) { @@ -486,7 +525,10 @@ static int pyexec_friendly_repl_process_char(int c) { // CIRCUITPY-CHANGE: print CircuitPython-style banner. mp_hal_stdout_tx_str(MICROPY_FULL_VERSION_INFO); mp_hal_stdout_tx_str("\r\n"); + #if MICROPY_PY_BUILTINS_HELP + // CIRCUITPY-CHANGE: don't print help info // mp_hal_stdout_tx_str("Type \"help()\" for more information.\r\n"); + #endif goto input_restart; } else if (ret == CHAR_CTRL_C) { // break @@ -572,10 +614,21 @@ MP_REGISTER_ROOT_POINTER(vstr_t * repl_line); #else // MICROPY_REPL_EVENT_DRIVEN +// CIRCUITPY-CHANGE: avoid warnings +#if !defined(MICROPY_HAL_HAS_STDIO_MODE_SWITCH) || !MICROPY_HAL_HAS_STDIO_MODE_SWITCH +// If the port doesn't need any stdio mode switching calls then provide trivial ones. +static inline void mp_hal_stdio_mode_raw(void) { +} +static inline void mp_hal_stdio_mode_orig(void) { +} +#endif + int pyexec_raw_repl(void) { vstr_t line; vstr_init(&line, 32); + mp_hal_stdio_mode_raw(); + raw_repl_reset: mp_hal_stdout_tx_str("raw REPL; CTRL-B to exit\r\n"); @@ -589,6 +642,7 @@ int pyexec_raw_repl(void) { if (vstr_len(&line) == 2 && vstr_str(&line)[0] == CHAR_CTRL_E) { int ret = do_reader_stdin(vstr_str(&line)[1]); if (ret & PYEXEC_FORCED_EXIT) { + mp_hal_stdio_mode_orig(); return ret; } vstr_reset(&line); @@ -601,6 +655,7 @@ int pyexec_raw_repl(void) { mp_hal_stdout_tx_str("\r\n"); vstr_clear(&line); pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL; + mp_hal_stdio_mode_orig(); return 0; } else if (c == CHAR_CTRL_C) { // clear line @@ -621,14 +676,18 @@ int pyexec_raw_repl(void) { // exit for a soft reset mp_hal_stdout_tx_str("\r\n"); vstr_clear(&line); + mp_hal_stdio_mode_orig(); return PYEXEC_FORCED_EXIT; } + // Switch to original terminal mode to execute code, eg to support keyboard interrupt (SIGINT). + mp_hal_stdio_mode_orig(); // CIRCUITPY-CHANGE: add last arg, handle reload int ret = parse_compile_execute(&line, MP_PARSE_FILE_INPUT, EXEC_FLAG_PRINT_EOF | EXEC_FLAG_SOURCE_IS_VSTR, NULL); if (ret & (PYEXEC_FORCED_EXIT | PYEXEC_RELOAD)) { return ret; } + mp_hal_stdio_mode_raw(); } } @@ -636,6 +695,8 @@ int pyexec_friendly_repl(void) { vstr_t line; vstr_init(&line, 32); + mp_hal_stdio_mode_raw(); + friendly_repl_reset: // CIRCUITPY-CHANGE: CircuitPython-style banner. mp_hal_stdout_tx_str("\r\n"); @@ -663,21 +724,6 @@ int pyexec_friendly_repl(void) { for (;;) { input_restart: - - // CIRCUITPY-CHANGE: prevent undef warning - #if defined(MICROPY_HW_ENABLE_USB) && MICROPY_HW_ENABLE_USB - if (usb_vcp_is_enabled()) { - // If the user gets to here and interrupts are disabled then - // they'll never see the prompt, traceback etc. The USB REPL needs - // interrupts to be enabled or no transfers occur. So we try to - // do the user a favor and re-enable interrupts. - if (query_irq() == IRQ_STATE_DISABLED) { - enable_irq(IRQ_STATE_ENABLED); - mp_hal_stdout_tx_str("MPY: enabling IRQs\r\n"); - } - } - #endif - // If the GC is locked at this point there is no way out except a reset, // so force the GC to be unlocked to help the user debug what went wrong. if (MP_STATE_THREAD(gc_lock_depth) != 0) { @@ -708,6 +754,7 @@ int pyexec_friendly_repl(void) { mp_hal_stdout_tx_str("\r\n"); vstr_clear(&line); pyexec_mode_kind = PYEXEC_MODE_RAW_REPL; + mp_hal_stdio_mode_orig(); return 0; } else if (ret == CHAR_CTRL_B) { // reset friendly REPL @@ -721,6 +768,7 @@ int pyexec_friendly_repl(void) { // exit for a soft reset mp_hal_stdout_tx_str("\r\n"); vstr_clear(&line); + mp_hal_stdio_mode_orig(); return PYEXEC_FORCED_EXIT; } else if (ret == CHAR_CTRL_E) { // paste mode @@ -765,11 +813,14 @@ int pyexec_friendly_repl(void) { } } + // Switch to original terminal mode to execute code, eg to support keyboard interrupt (SIGINT). + mp_hal_stdio_mode_orig(); // CIRCUITPY-CHANGE: add last arg ret = parse_compile_execute(&line, parse_input_kind, EXEC_FLAG_ALLOW_DEBUGGING | EXEC_FLAG_IS_REPL | EXEC_FLAG_SOURCE_IS_VSTR, NULL); if (ret & (PYEXEC_FORCED_EXIT | PYEXEC_RELOAD)) { return ret; } + mp_hal_stdio_mode_raw(); } } @@ -832,6 +883,11 @@ int pyexec_exit_handler(const void *source, pyexec_result_t *result) { } #endif +int pyexec_vstr(vstr_t *str, bool allow_keyboard_interrupt, pyexec_result_t *result) { + mp_uint_t exec_flags = allow_keyboard_interrupt ? 0 : EXEC_FLAG_NO_INTERRUPT; + return parse_compile_execute(str, MP_PARSE_FILE_INPUT, exec_flags | EXEC_FLAG_SOURCE_IS_VSTR, result); +} + #if MICROPY_REPL_INFO mp_obj_t pyb_set_repl_info(mp_obj_t o_value) { repl_display_debugging_info = mp_obj_get_int(o_value); diff --git a/shared/runtime/pyexec.h b/shared/runtime/pyexec.h index 762b926c9c3..9d1ef2a3cb0 100644 --- a/shared/runtime/pyexec.h +++ b/shared/runtime/pyexec.h @@ -45,23 +45,30 @@ typedef struct { extern pyexec_mode_kind_t pyexec_mode_kind; -// Set this to the value (eg PYEXEC_FORCED_EXIT) that will be propagated through -// the pyexec functions if a SystemExit exception is raised by the running code. -// It will reset to 0 at the start of each execution (eg each REPL entry). -extern int pyexec_system_exit; - #define PYEXEC_FORCED_EXIT (0x100) // CIRCUITPY-CHANGE: additional flags #define PYEXEC_EXCEPTION (0x200) #define PYEXEC_DEEP_SLEEP (0x400) #define PYEXEC_RELOAD (0x800) +#if MICROPY_PYEXEC_ENABLE_EXIT_CODE_HANDLING +#define PYEXEC_NORMAL_EXIT (0) +#define PYEXEC_UNHANDLED_EXCEPTION (1) +#define PYEXEC_KEYBOARD_INTERRUPT (128 + 2) // same as SIG INT exit code +#define PYEXEC_ABORT (128 + 9) // same as SIG KILL exit code +#else +#define PYEXEC_NORMAL_EXIT (1) +#define PYEXEC_UNHANDLED_EXCEPTION (0) +#define PYEXEC_ABORT PYEXEC_FORCED_EXIT +#endif + int pyexec_raw_repl(void); int pyexec_friendly_repl(void); // CIRCUITPY-CHANGE: result out argument int pyexec_file(const char *filename, pyexec_result_t *result); int pyexec_file_if_exists(const char *filename, pyexec_result_t *result); int pyexec_frozen_module(const char *name, bool allow_keyboard_interrupt, pyexec_result_t *result); +int pyexec_vstr(vstr_t *str, bool allow_keyboard_interrupt, pyexec_result_t *result); void pyexec_event_repl_init(void); int pyexec_event_repl_process_char(int c); extern uint8_t pyexec_repl_active; diff --git a/shared/runtime/semihosting.c b/shared/runtime/semihosting.c deleted file mode 100644 index 18c7f5d57a3..00000000000 --- a/shared/runtime/semihosting.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Ayke van Laethem - * - * 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. - */ - -#include "semihosting.h" - -// Resources: -// http://embed.rs/articles/2016/semi-hosting-rust/ -// https://wiki.dlang.org/Minimal_semihosted_ARM_Cortex-M_%22Hello_World%22 -// https://github.com/arduino/OpenOCD/blob/master/src/target/arm_semihosting.c - -#define SYS_OPEN 0x01 -#define SYS_WRITEC 0x03 -#define SYS_WRITE 0x05 -#define SYS_READC 0x07 - -// Constants: -#define OPEN_MODE_READ (0) // mode "r" -#define OPEN_MODE_WRITE (4) // mode "w" - -#ifndef __thumb__ -#error Semihosting is only implemented for ARM microcontrollers. -#endif - -static int mp_semihosting_stdout; - -static uint32_t mp_semihosting_call(uint32_t num, const void *arg) { - // A semihosting call works as follows, similar to a SVCall: - // * the call is invoked by a special breakpoint: 0xAB - // * the command is placed in r0 - // * a pointer to the arguments is placed in r1 - // * the return value is placed in r0 - // Note that because it uses the breakpoint instruction, applications - // will hang if they're not connected to a debugger. And they'll be - // stuck in a breakpoint if semihosting is not specifically enabled in - // the debugger. - // Also note that semihosting is extremely slow (sometimes >100ms per - // call). - register uint32_t num_reg __asm__ ("r0") = num; - register const void *args_reg __asm__ ("r1") = arg; - __asm__ __volatile__ ( - "bkpt 0xAB\n" // invoke semihosting call - : "+r" (num_reg) // call number and result - : "r" (args_reg) // arguments - : "memory"); // make sure args aren't optimized away - return num_reg; // r0, which became the result -} - -static int mp_semihosting_open_console(uint32_t mode) { - struct { - char *name; - uint32_t mode; - uint32_t name_len; - } args = { - .name = ":tt", // magic path to console - .mode = mode, // e.g. "r", "w" (see OPEN_MODE_* constants) - .name_len = 3, // strlen(":tt") - }; - return mp_semihosting_call(SYS_OPEN, &args); -} - -void mp_semihosting_init() { - mp_semihosting_stdout = mp_semihosting_open_console(OPEN_MODE_WRITE); -} - -int mp_semihosting_rx_char() { - return mp_semihosting_call(SYS_READC, NULL); -} - -static void mp_semihosting_tx_char(char c) { - mp_semihosting_call(SYS_WRITEC, &c); -} - -uint32_t mp_semihosting_tx_strn(const char *str, size_t len) { - if (len == 0) { - return 0; // nothing to do - } - if (len == 1) { - mp_semihosting_tx_char(*str); // maybe faster? - return 0; - } - - struct { - uint32_t fd; - const char *str; - uint32_t len; - } args = { - .fd = mp_semihosting_stdout, - .str = str, - .len = len, - }; - return mp_semihosting_call(SYS_WRITE, &args); -} - -uint32_t mp_semihosting_tx_strn_cooked(const char *str, size_t len) { - // Write chunks of data until (excluding) the first '\n' character, - // insert a '\r' character, and then continue with the next chunk - // (starting with '\n'). - // Doing byte-by-byte writes would be easier to implement but is far - // too slow. - size_t start = 0; - for (size_t i = 0; i < len; i++) { - if (str[i] == '\n') { - mp_semihosting_tx_strn(str + start, i - start); - mp_semihosting_tx_char('\r'); - start = i; - } - } - return mp_semihosting_tx_strn(str + start, len - start); -} diff --git a/shared/runtime/semihosting.h b/shared/runtime/semihosting.h deleted file mode 100644 index d053a03edaa..00000000000 --- a/shared/runtime/semihosting.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2018 Ayke van Laethem - * - * 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. - */ -#ifndef MICROPY_INCLUDED_LIB_UTILS_SEMIHOSTING_H -#define MICROPY_INCLUDED_LIB_UTILS_SEMIHOSTING_H - -/* - -To use semi-hosting for a replacement UART: -- Add lib/semihosting/semihosting.c to the Makefile sources. -- Call mp_semihosting_init() in main(), around the time UART is initialized. -- Replace mp_hal_stdin_rx_chr and similar in mphalport.c with the semihosting equivalent. -- Include lib/semihosting/semihosting.h in the relevant files. - -Then make sure the debugger is attached and enables semihosting. In OpenOCD this is -done with ARM semihosting enable followed by reset. The terminal will need further -configuration to work with MicroPython (bash: stty raw -echo). - -*/ - -#include -#include - -void mp_semihosting_init(); -int mp_semihosting_rx_char(); -uint32_t mp_semihosting_tx_strn(const char *str, size_t len); -uint32_t mp_semihosting_tx_strn_cooked(const char *str, size_t len); - -#endif // MICROPY_INCLUDED_LIB_UTILS_SEMIHOSTING_H diff --git a/shared/runtime/semihosting_arm.c b/shared/runtime/semihosting_arm.c new file mode 100644 index 00000000000..f4d168f79bc --- /dev/null +++ b/shared/runtime/semihosting_arm.c @@ -0,0 +1,157 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Ayke van Laethem + * + * 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. + */ + +#include "semihosting_arm.h" + +// Resources: +// http://embed.rs/articles/2016/semi-hosting-rust/ +// https://wiki.dlang.org/Minimal_semihosted_ARM_Cortex-M_%22Hello_World%22 +// https://github.com/arduino/OpenOCD/blob/master/src/target/arm_semihosting.c + +#define SYS_OPEN 0x01 +#define SYS_WRITEC 0x03 +#define SYS_WRITE 0x05 +#define SYS_READ 0x06 +#define SYS_READC 0x07 +#define SYS_EXIT 0x18 + +// Constants: +#define OPEN_MODE_READ (0) // mode "r" +#define OPEN_MODE_WRITE (4) // mode "w" + +static int mp_semihosting_stdout; + +static uint32_t mp_semihosting_call(uint32_t num, const void *arg) { + // A semihosting call works as follows, similar to a SVCall: + // * the call is invoked by a special breakpoint: 0xAB + // * the command is placed in r0 + // * a pointer to the arguments is placed in r1 + // * the return value is placed in r0 + // Note that because it uses the breakpoint instruction, applications + // will hang if they're not connected to a debugger. And they'll be + // stuck in a breakpoint if semihosting is not specifically enabled in + // the debugger. + // Also note that semihosting is extremely slow (sometimes >100ms per + // call). + register uint32_t num_reg __asm__ ("r0") = num; + register const void *args_reg __asm__ ("r1") = arg; + __asm__ __volatile__ ( + #if defined(__ARM_ARCH_ISA_ARM) + "svc 0x00123456\n" // invoke semihosting call + #elif defined(__ARM_ARCH_ISA_THUMB) + "bkpt 0xAB\n" // invoke semihosting call + #else + #error Unknown architecture + #endif + : "+r" (num_reg) // call number and result + : "r" (args_reg) // arguments + : "memory"); // make sure args aren't optimized away + return num_reg; // r0, which became the result +} + +static int mp_semihosting_open_console(uint32_t mode) { + struct { + char *name; + uint32_t mode; + uint32_t name_len; + } args = { + .name = ":tt", // magic path to console + .mode = mode, // e.g. "r", "w" (see OPEN_MODE_* constants) + .name_len = 3, // strlen(":tt") + }; + return mp_semihosting_call(SYS_OPEN, &args); +} + +void mp_semihosting_init() { + mp_semihosting_stdout = mp_semihosting_open_console(OPEN_MODE_WRITE); +} + +void mp_semihosting_exit(int status) { + if (status == 0) { + status = 0x20026; + } + mp_semihosting_call(SYS_EXIT, (void *)(uintptr_t)status); +} + +int mp_semihosting_rx_char() { + return mp_semihosting_call(SYS_READC, NULL); +} + +// Returns 0 on success. +int mp_semihosting_rx_chars(char *str, size_t len) { + struct { + uint32_t fd; + const char *str; + uint32_t len; + } args = { + .fd = mp_semihosting_stdout, + .str = str, + .len = len, + }; + return mp_semihosting_call(SYS_READ, &args); +} + +static void mp_semihosting_tx_char(char c) { + mp_semihosting_call(SYS_WRITEC, &c); +} + +uint32_t mp_semihosting_tx_strn(const char *str, size_t len) { + if (len == 0) { + return 0; // nothing to do + } + if (len == 1) { + mp_semihosting_tx_char(*str); // maybe faster? + return 0; + } + + struct { + uint32_t fd; + const char *str; + uint32_t len; + } args = { + .fd = mp_semihosting_stdout, + .str = str, + .len = len, + }; + return mp_semihosting_call(SYS_WRITE, &args); +} + +uint32_t mp_semihosting_tx_strn_cooked(const char *str, size_t len) { + // Write chunks of data until (excluding) the first '\n' character, + // insert a '\r' character, and then continue with the next chunk + // (starting with '\n'). + // Doing byte-by-byte writes would be easier to implement but is far + // too slow. + size_t start = 0; + for (size_t i = 0; i < len; i++) { + if (str[i] == '\n') { + mp_semihosting_tx_strn(str + start, i - start); + mp_semihosting_tx_char('\r'); + start = i; + } + } + return mp_semihosting_tx_strn(str + start, len - start); +} diff --git a/shared/runtime/semihosting_arm.h b/shared/runtime/semihosting_arm.h new file mode 100644 index 00000000000..08fb66578ac --- /dev/null +++ b/shared/runtime/semihosting_arm.h @@ -0,0 +1,55 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2018 Ayke van Laethem + * + * 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. + */ +#ifndef MICROPY_INCLUDED_SHARED_RUNTIME_SEMIHOSTING_ARM_H +#define MICROPY_INCLUDED_SHARED_RUNTIME_SEMIHOSTING_ARM_H + +/* + +To use semi-hosting for a replacement UART: +- Add shared/runtime/semihosting_arm.c to the Makefile sources. +- Call mp_semihosting_init() in main(), around the time UART is initialized. +- Replace mp_hal_stdin_rx_chr and similar in mphalport.c with the semihosting equivalent. +- Include shared/runtime/semihosting_arm.h in the relevant files. + +Then make sure the debugger is attached and enables semihosting. In OpenOCD this is +done with ARM semihosting enable followed by reset. The terminal will need further +configuration to work with MicroPython (bash: stty raw -echo). + +If mp_semihosting_rx_char() doesn't work then try mp_semihosting_rx_chars(str, 1). + +*/ + +#include +#include + +void mp_semihosting_init(); +void mp_semihosting_exit(int status); +int mp_semihosting_rx_char(); +int mp_semihosting_rx_chars(char *str, size_t len); +uint32_t mp_semihosting_tx_strn(const char *str, size_t len); +uint32_t mp_semihosting_tx_strn_cooked(const char *str, size_t len); + +#endif // MICROPY_INCLUDED_SHARED_RUNTIME_SEMIHOSTING_ARM_H diff --git a/shared/runtime/semihosting_rv32.c b/shared/runtime/semihosting_rv32.c new file mode 100644 index 00000000000..1d02b69b23e --- /dev/null +++ b/shared/runtime/semihosting_rv32.c @@ -0,0 +1,481 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +#include + +#include "semihosting_rv32.h" + +#if !defined(__riscv) || !defined(__riscv_xlen) || (__riscv_xlen != 32) +#error "This semihosting support code is only available for RV32 targets." +#endif + +// Features file magic header. +#define MAGIC_SIZE 4 +#define MAGIC_0 0x53 // 'S' +#define MAGIC_1 0x48 // 'H' +#define MAGIC_2 0x46 // 'B' +#define MAGIC_3 0x42 // 'F' + +#define CMDLINE_MIN_BUFFER_SIZE 80 + +#define SYS_OPEN 0x01 +#define SYS_CLOSE 0x02 +#define SYS_WRITEC 0x03 +#define SYS_WRITE0 0x04 +#define SYS_WRITE 0x05 +#define SYS_READ 0x06 +#define SYS_READC 0x07 +#define SYS_ISERROR 0x08 +#define SYS_ISTTY 0x09 +#define SYS_SEEK 0x0A +#define SYS_FLEN 0x0C +#define SYS_TMPNAM 0x0D +#define SYS_REMOVE 0x0E +#define SYS_RENAME 0x0F +#define SYS_CLOCK 0x10 +#define SYS_TIME 0x11 +#define SYS_SYSTEM 0x12 +#define SYS_ERRNO 0x13 +#define SYS_GET_CMDLINE 0x15 +#define SYS_HEAPINFO 0x16 +#define SYS_EXIT 0x18 +#define SYS_EXIT_EXTENDED 0x20 +#define SYS_ELAPSED 0x30 +#define SYS_TICKFREQ 0x31 + +// Extended features availability flags. +static bool exit_extended_available = false; +static bool split_stdout_stderr = false; + +// Perform a semihosting call with the given call number and using the given +// parameters block. +int mp_semihosting_call(uint32_t num, void *arg); + +// Convert the given fopen(3) open mode string into the appropriate integer +// value required by SYS_OPEN. If the mode is invalid, it will return -1. +static int mp_lookup_open_mode(const char *mode); + +// Computes the length of the given string. If it gets passed a NULL pointer +// it will return -1. +static int mp_strlen(const char *string); + +// Check which extended features are advertised by the host system. +static void mp_check_extended_features_availability(void); + +// Write the given string to the host system's debug console. +static int mp_write_to_debug_console(const char *string, size_t length); + +// The host system's STDOUT file handle. +int mp_semihosting_stdout = -1; + +// The host system's STDERR file handle. +int mp_semihosting_stderr = -1; + +int mp_semihosting_open(const char *file_name, const char *file_mode) { + if (file_name == NULL || file_mode == NULL) { + return -1; + } + + int file_name_length = mp_strlen(file_name); + if (file_name_length <= 0) { + return -1; + } + int file_open_mode = mp_lookup_open_mode(file_mode); + if (file_open_mode < 0) { + return -1; + } + + uint32_t arguments[3] = { (uintptr_t)file_name, file_open_mode, file_name_length }; + return mp_semihosting_call(SYS_OPEN, arguments); +} + +int mp_semihosting_close(int handle) { + uint32_t arguments[] = { handle }; + return mp_semihosting_call(SYS_CLOSE, arguments); +} + +void mp_semihosting_writec(char character) { + uint32_t arguments[] = { character }; + mp_semihosting_call(SYS_WRITEC, arguments); +} + +void mp_semihosting_write0(const char *string) { + if (string == NULL) { + return; + } + uint32_t arguments[] = { (uintptr_t)string }; + mp_semihosting_call(SYS_WRITE0, arguments); +} + +int mp_semihosting_write(int handle, const void *data, size_t length) { + if (data == NULL) { + return length; + } + if (length == 0) { + return 0; + } + + uint32_t arguments[] = { handle, (uintptr_t)data, length }; + return mp_semihosting_call(SYS_WRITE, arguments); +} + +int mp_semihosting_read(int handle, void *data, size_t length) { + if (data == NULL) { + return -1; + } + if (length == 0) { + return 0; + } + + uint32_t arguments[] = { handle, (uintptr_t)data, length }; + return mp_semihosting_call(SYS_READ, arguments); +} + +inline int mp_semihosting_readc(void) { + return mp_semihosting_call(SYS_READC, NULL); +} + +int mp_semihosting_iserror(int code) { + uint32_t arguments[] = { code }; + return mp_semihosting_call(SYS_ISERROR, arguments); +} + +int mp_semihosting_istty(int handle) { + uint32_t arguments[] = { handle }; + return mp_semihosting_call(SYS_ISTTY, arguments); +} + +int mp_semihosting_seek(int handle, uint32_t offset) { + uint32_t arguments[] = { handle, offset }; + return mp_semihosting_call(SYS_SEEK, arguments); +} + +int mp_semihosting_flen(int handle) { + uint32_t arguments[] = { handle }; + return mp_semihosting_call(SYS_FLEN, arguments); +} + +int mp_semihosting_tmpnam(uint8_t identifier, void *buffer, size_t buffer_length) { + if (buffer == NULL || buffer_length == 0) { + return -1; + } + + uint32_t arguments[] = { (uintptr_t)buffer, identifier, buffer_length }; + return mp_semihosting_call(SYS_TMPNAM, arguments); +} + +int mp_semihosting_remove(const char *file_name) { + if (file_name == NULL) { + return -1; + } + + int file_name_length = mp_strlen(file_name); + if (file_name_length <= 0) { + return -1; + } + + uint32_t arguments[] = { (uintptr_t)file_name, file_name_length }; + return mp_semihosting_call(SYS_REMOVE, arguments); +} + +int mp_semihosting_rename(const char *old_name, const char *new_name) { + if (old_name == NULL || new_name == NULL) { + return -1; + } + + int old_name_length = mp_strlen(old_name); + if (old_name_length <= 0) { + return -1; + } + + int new_name_length = mp_strlen(new_name); + if (new_name_length <= 0) { + return -1; + } + + uint32_t arguments[] = { + (uintptr_t)old_name, old_name_length, (uintptr_t)new_name, new_name_length + }; + return mp_semihosting_call(SYS_RENAME, arguments); +} + +inline int mp_semihosting_clock(void) { + return mp_semihosting_call(SYS_CLOCK, NULL); +} + +inline int mp_semihosting_time(void) { + return mp_semihosting_call(SYS_TIME, NULL); +} + +int mp_semihosting_system(const char *command) { + if (command == NULL) { + return -1; + } + + int command_length = mp_strlen(command); + if (command_length <= 0) { + return -1; + } + + uint32_t arguments[] = { (uintptr_t)command, command_length }; + return mp_semihosting_call(SYS_SYSTEM, arguments); +} + +inline int mp_semihosting_errno(void) { + return mp_semihosting_call(SYS_ERRNO, NULL); +} + +int mp_semihosting_get_cmdline(void *buffer, size_t buffer_length) { + if (buffer == NULL || buffer_length < CMDLINE_MIN_BUFFER_SIZE) { + return -1; + } + + uint32_t arguments[] = { (uintptr_t)buffer, buffer_length }; + return mp_semihosting_call(SYS_GET_CMDLINE, arguments); +} + +void mp_semihosting_heapinfo(mp_semihosting_heap_info_t *block) { + if (block == NULL) { + return; + } + + uint32_t arguments[] = { (uintptr_t)block }; + mp_semihosting_call(SYS_HEAPINFO, arguments); +} + +void mp_semihosting_exit(uint32_t code, uint32_t subcode) { + uint32_t arguments[] = { code, subcode }; + mp_semihosting_call(SYS_EXIT, arguments); + for (;;) {} +} + +void mp_semihosting_exit_extended(uint32_t code, uint32_t subcode) { + uint32_t arguments[] = { code, subcode }; + mp_semihosting_call(SYS_EXIT_EXTENDED, arguments); + for (;;) {} +} + +int mp_semihosting_elapsed(mp_semihosting_elapsed_ticks_t *ticks) { + if (ticks == NULL) { + return -1; + } + + uint32_t arguments[] = { (uintptr_t)ticks }; + return mp_semihosting_call(SYS_ELAPSED, arguments); +} + +inline int mp_semihosting_tickfreq(void) { + return mp_semihosting_call(SYS_TICKFREQ, NULL); +} + +void mp_semihosting_init() { + mp_check_extended_features_availability(); + mp_semihosting_stdout = mp_semihosting_open(":tt", "w"); + if (split_stdout_stderr) { + mp_semihosting_stderr = mp_semihosting_open(":tt", "a"); + } else { + mp_semihosting_stderr = mp_semihosting_stdout; + } +} + +void mp_check_extended_features_availability(void) { + int features_handle = mp_semihosting_open(":semihosting-features", "r"); + if (features_handle < 0) { + return; + } + + uint8_t magic_buffer[MAGIC_SIZE]; + if (mp_semihosting_flen(features_handle) < sizeof(magic_buffer)) { + mp_semihosting_close(features_handle); + return; + } + + if (mp_semihosting_read(features_handle, magic_buffer, sizeof(magic_buffer)) != 0) { + mp_semihosting_close(features_handle); + return; + } + + if (magic_buffer[0] != MAGIC_0 || + magic_buffer[1] != MAGIC_1 || + magic_buffer[2] != MAGIC_2 || + magic_buffer[3] != MAGIC_3) { + mp_semihosting_close(features_handle); + return; + } + + uint8_t features_byte = 0; + if (mp_semihosting_read(features_handle, &features_byte, sizeof(features_byte)) != 0) { + mp_semihosting_close(features_handle); + return; + } + + mp_semihosting_close(features_handle); + + exit_extended_available = (features_byte & 0x01) != 0; + split_stdout_stderr = (features_byte & 0x02) != 0; +} + +int mp_strlen(const char *string) { + int length = 0; + while (*string++ != 0) { + length += 1; + } + return length; +} + +int mp_lookup_open_mode(const char *mode) { + if (mode == NULL) { + return -1; + } + + int mode_found; + + switch (mode[0]) { + case 'r': + mode_found = 0x00; + break; + case 'w': + mode_found = 0x04; + break; + case 'a': + mode_found = 0x08; + break; + default: + return -1; + } + + switch (mode[1]) { + case 'b': + mode_found |= 0x01; + break; + case '+': + mode_found |= 0x02; + break; + case '\0': + return mode_found; + default: + return -1; + } + + switch (mode[2]) { + case 'b': + if (mode_found & 0x01) { + // 'b' was already seen. + return -1; + } + mode_found |= 1; + break; + case '+': + if (mode_found & 0x02) { + // '+' was already seen. + return -1; + } + mode_found |= 2; + break; + case '\0': + return mode_found; + default: + return -1; + } + + return mode[3] == '\0' ? mode_found : -1; +} + +int mp_semihosting_call(uint32_t num, void *arg) { + register uint32_t call_number_register __asm__ ("x10") = num; + register void *arguments_register __asm__ ("x11") = arg; + + __asm volatile ( + ".option push \n" // Transient options + ".option norvc \n" // Do not emit compressed instructions + ".align 4 \n" // 16 bytes alignment + "slli zero, zero, 0x1F \n" // Entry NOP + "ebreak \n" // Give control to the debugger + "srai zero, zero, 7 \n" // Semihosting call + ".option pop \n" // Restore previous options set + : "+r" (call_number_register) + : "r" (arguments_register) + : "memory" + ); + + return call_number_register; +} + +inline int mp_semihosting_rx_char() { + return mp_semihosting_call(SYS_READC, NULL); +} + +int mp_write_to_debug_console(const char *string, size_t length) { + if (length == 0) { + return 0; + } + + if (length == 1) { + mp_semihosting_writec(*string); + return 0; + } + + return mp_semihosting_write(mp_semihosting_stdout, string, length); +} + +void mp_semihosting_terminate(uint32_t code, uint32_t subcode) { + if (exit_extended_available) { + mp_semihosting_exit_extended(code, subcode); + } else { + mp_semihosting_exit(code, subcode); + } +} + +int mp_semihosting_tx_strn(const char *string, size_t length) { + if (string == NULL) { + return -1; + } + + return mp_write_to_debug_console(string, length); +} + +int mp_semihosting_tx_strn_cooked(const char *string, size_t length) { + if (string == NULL) { + return -1; + } + + if (length == 0) { + return 0; + } + + size_t current_offset = 0; + for (size_t index = 0; index < length; index++) { + if (string[index] != '\n') { + continue; + } + + mp_write_to_debug_console(string + current_offset, index - current_offset); + mp_semihosting_writec('\r'); + current_offset = index; + } + + return mp_write_to_debug_console(string + current_offset, length - current_offset); +} diff --git a/shared/runtime/semihosting_rv32.h b/shared/runtime/semihosting_rv32.h new file mode 100644 index 00000000000..7cabd1692c1 --- /dev/null +++ b/shared/runtime/semihosting_rv32.h @@ -0,0 +1,247 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2024 Alessandro Gatti + * + * 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. + */ + +#ifndef MICROPY_INCLUDED_SHARED_RUNTIME_SEMIHOSTING_RV32_H +#define MICROPY_INCLUDED_SHARED_RUNTIME_SEMIHOSTING_RV32_H + +/* + * To integrate semihosting, make sure to call mp_semihosting_init() first. + * Then, if the host system's STDOUT should be used instead of a UART, replace + * mp_hal_stdin_rx_chr and similar calls in mphalport.c with the semihosting + * equivalents. + * + * At runtime, make sure that the debugger is attached and semihosting is + * enabled on its end. The terminal must be configured in raw mode with local + * echo disabled, on Linux this can be done with "stty raw -echo" on the + * command line. + */ + +/* + * This follows the RISC-V Semihosting specification version 0.3. + * + * That document can be downloaded from + * https://github.com/riscv-non-isa/riscv-semihosting/releases/ + * + * Version 0.3 claims that the current RISC-V Semihosting implementation + * should follow Arm's, and more precisely the "Semihosting for AArch32 + * and AArch64" document, revision 2023Q3. + */ + +#include +#include +#include + +// A container for heap and stack pointers as returned by SYS_HEAPINFO. +typedef struct { + void *heap_base; + void *heap_limit; + void *stack_base; + void *stack_limit; +} mp_semihosting_heap_info_t; + +// A 64-bits value indicating how many ticks were counted since the target +// image's execution started. +typedef struct { + uint32_t low; + uint32_t high; +} mp_semihosting_elapsed_ticks_t; + +// The host system's STDOUT file handle. +extern int mp_semihosting_stdout; + +// The host system's STDERR file handle. If the host system does not support +// explicit STDOUT and STDERR handles, this handle will be aliased to STDOUT +// instead. +extern int mp_semihosting_stderr; + +/* + * Even though exit codes from 0x20000 to 0x20007 are part of the original Arm + * specification document, they are omitted due to them being tied to hardware + * events. Whilst some of them may still have a meaning on the RISC-V + * platform, it is not yet clear which ones are available and which ones are + * not. Thus, only "soft" error codes are provided here although the SYS_EXIT + * and SYS_EXIT_EXTENDED semihosting calls accept any 32-bits integer as an + * exit code. + */ + +enum { + MP_SEMIHOSTING_EXIT_BREAKPOINT = 0x20020, + MP_SEMIHOSTING_EXIT_WATCHPOINT, + MP_SEMIHOSTING_EXIT_STEP_COMPLETE, + MP_SEMIHOSTING_EXIT_RUNTIME_ERROR_UNKNOWN, + MP_SEMIHOSTING_EXIT_INTERNAL_ERROR, + MP_SEMIHOSTING_EXIT_USER_INTERRUPTION, + MP_SEMIHOSTING_EXIT_APPLICATION_EXIT, + MP_SEMIHOSTING_EXIT_STACK_OVERFLOW, + MP_SEMIHOSTING_EXIT_DIVISION_BY_ZERO, + MP_SEMIHOSTING_EXIT_OS_SPECIFIC +}; + +// Initialises semihosting support. +void mp_semihosting_init(); + +// Read a character from the host system's STDIN stream. +int mp_semihosting_rx_char(); + +// Write the given string to the host system's STDOUT stream. +int mp_semihosting_tx_strn(const char *string, size_t length); + +// Write the given string to the host system's STDOUT stream, writing a CR byte +// before each LF byte to be written. +int mp_semihosting_tx_strn_cooked(const char *string, size_t length); + +// Terminates execution with the given code and an optional subcode. This +// will choose the appropriate semihosting call (either SYS_EXIT or +// SYS_EXIT_EXTENDED) depending on the host system's reported capabilities. +noreturn void mp_semihosting_terminate(uint32_t code, uint32_t subcode); + +// Direct semihosting calls access. + +// Open a file on the host system with the given name and file mode. +// The file mode follows fopen(3)'s syntax. The function will return -1 if it +// failed to open the required file, or a file handle number if the operation +// succeeded. To see why the operation failed, call mp_semihosting_errno. +int mp_semihosting_open(const char *file_name, const char *file_mode); + +// Close a file previously opened with mp_semihosting_open. If the file cannot +// be closed, the function will return -1, otherwise it will return 0. To see +// why the operation failed, call mp_semihosting_errno. +int mp_semihosting_close(int handle); + +// Write the given character to the host system's STDOUT file handle. +void mp_semihosting_writec(char character); + +// Write the given NULL-terminated string to the host system's STDOUT file +// handle. +void mp_semihosting_write0(const char *string); + +// Write the given buffer to the given host system file handle. The function +// will return how many characters were left to be written (0 if the operation +// wrote the whole buffer), or -1 if the input buffer pointer is NULL. +int mp_semihosting_write(int handle, const void *data, size_t length); + +// Read from the given host system file handle into the given buffer. The +// function will return how many characters were left to be read (0 if the +// operation read whole buffer), or -1 if the input buffer pointer is NULL. +int mp_semihosting_read(int handle, void *data, size_t length); + +// Read a single character from the host system's STDIN file handle. +int mp_semihosting_readc(void); + +// Check whether the given result code represents an error. The function will +// return a non-zero value if the code is indeed an error, or zero otherwise. +int mp_semihosting_iserror(int code); + +// Check whether the given host system file handle is mapped to an interactive +// device. The function will return 1 if the handle is mapped to an +// interactive device, 0 if it is mapped to a regular file, and anything else +// if an error occurred. +int mp_semihosting_istty(int handle); + +// Move the file pointer on the given host system's file handle to the given +// absolute offset (in bytes). The function will return 0 if the file pointer +// was moved to the requested position, or a negative value if it was not +// possible to do so. To see why the operation failed, call +// mp_semihosting_errno. +int mp_semihosting_seek(int handle, uint32_t offset); + +// Get the length (in bytes) of the host system's file mapped to the given +// handle. The function will return a negative value if an error occurred, or +// the requested file's length (in bytes). +int mp_semihosting_flen(int handle); + +// Create a temporary file on the host system. The function requires a file +// identifier between 0 and 255 (inclusive) that will be bound to the requested +// temporary file. Subsequent calls to mp_semihosting_tmpnam with the same +// identifier will always return the same host system file name. On success, +// the function will fill the given buffer with the host system's file name, +// and will return 0. If the buffer pointer is NULL, the buffer name area is +// too small, or the operation failed on the host system's end, the function +// will return -1 instead. Make sure that the buffer is big enough to contain +// a host system's full path name. +int mp_semihosting_tmpnam(uint8_t identifier, void *buffer, size_t buffer_length); + +// Delete a file on the host system's matching the given file name. The +// function will return 0 if the deletion operation succeeded, or a host system +// dependent error code instead. +int mp_semihosting_remove(const char *file_name); + +// Rename a file on the host system's name matching the given file name to the +// new chosen name. The function will return 0 if the rename operation +// succeeded, or a host system dependent error code instead. +int mp_semihosting_rename(const char *old_name, const char *new_name); + +// Get how many hundredths of a second passed since execution started. If an +// error occurred whilst retrieving clock value, the function will return -1. +int mp_semihosting_clock(void); + +// Get the host system's clock in seconds since midnight of January 1st, 1970 +// at UTC. +int mp_semihosting_time(void); + +// Execute the given command on the host system. The function will return the +// command's result code retrieved on the host system. +int mp_semihosting_system(const char *command); + +// Get the last operation's status code. The function will return the host +// system's errno variable contents, and can be used to see the exact result +// code for failed I/O operations. +int mp_semihosting_errno(void); + +// Get the host system's command line that started execution of the target +// image. The function will fill the given buffer with the command line +// arguments passed to the target executable. The function will return 0 on +// success, or -1 if it failed. Make sure that the buffer can contain at +// least 80 bytes, as it is the minimum supported size defined by the +// specifications document. +int mp_semihosting_get_cmdline(void *buffer, size_t buffer_length); + +// Fill the given heap info structure with the system's stack and heap +// start/end addresses. +void mp_semihosting_heapinfo(mp_semihosting_heap_info_t *block); + +// Terminate the execution with the given reason code and optional subcode. +// This should be preferred over mp_semihosting_exit_extended if the host +// system does not support the SYS_EXIT_EXTENDED semihosting call. In doubt +// use mp_semihosting_terminate instead. +noreturn void mp_semihosting_exit(uint32_t code, uint32_t subcode); + +// Terminate the execution with the given reason code and optional subcode. +// This should be preferred over mp_semihosting_exit if the host system +// supports this semihosting call. In doubt use mp_semihosting_terminate +// instead. +noreturn void mp_semihosting_exit_extended(uint32_t code, uint32_t subcode); + +// Fill the given structure with how many ticks were counted since execution +// started. On success, the function will return 0, or -1 if it was not +// possible to compute the ticks count. +int mp_semihosting_elapsed(mp_semihosting_elapsed_ticks_t *ticks); + +// Get the system's tick frequency. If this value is not known, the function +// will return -1 instead. +int mp_semihosting_tickfreq(void); + +#endif // MICROPY_INCLUDED_SHARED_SEMIHOSTING_RUNTIME_RV32_H diff --git a/shared/timeutils/timeutils.c b/shared/timeutils/timeutils.c index 4282a0178dd..0c6916e06dd 100644 --- a/shared/timeutils/timeutils.c +++ b/shared/timeutils/timeutils.c @@ -29,12 +29,27 @@ #include "shared/timeutils/timeutils.h" -// LEAPOCH corresponds to 2000-03-01, which is a mod-400 year, immediately -// after Feb 29. We calculate seconds as a signed integer relative to that. +// To maintain reasonable compatibility with CPython on embedded systems, +// and avoid breaking anytime soon, timeutils functions are required to +// work properly between 1970 and 2099 on all ports. // -// Our timebase is relative to 2000-01-01. - -#define LEAPOCH ((31 + 29) * 86400) +// During that period of time, leap years occur every 4 years without +// exception, so we can keep the code short for 32 bit machines. + +// The last leap day before the required period is Feb 29, 1968. +// This is the number of days to add to get to that date. +#define PREV_LEAP_DAY ((mp_uint_t)(365 + 366 - (31 + 29))) +#define PREV_LEAP_YEAR 1968 + +// On ports where either MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND or +// MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE is enabled, we include extra +// code to support leap years outside of the 'easy' period. +// Computation is then made based on 1600 (a mod-400 year). +// This is the number of days between 1600 and 1968. +#define QC_BASE_DAY 134409 +#define QC_LEAP_YEAR 1600 +// This is the number of leap days between 1600 and 1970 +#define QC_LEAP_DAYS 89 #define DAYS_PER_400Y (365 * 400 + 97) #define DAYS_PER_100Y (365 * 100 + 24) @@ -42,8 +57,20 @@ static const uint16_t days_since_jan1[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }; +// type used internally to count small integers relative to epoch +// (using uint when possible produces smaller code on some platforms) +#if MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE +typedef mp_int_t relint_t; +#else +typedef mp_uint_t relint_t; +#endif + bool timeutils_is_leap_year(mp_uint_t year) { + #if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; + #else + return year % 4 == 0; + #endif } // month is one based @@ -65,67 +92,67 @@ mp_uint_t timeutils_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date) { return yday; } -void timeutils_seconds_since_2000_to_struct_time(mp_uint_t t, timeutils_struct_time_t *tm) { - // The following algorithm was adapted from musl's __secs_to_tm and adapted - // for differences in MicroPython's timebase. - - mp_int_t seconds = t - LEAPOCH; +void timeutils_seconds_since_1970_to_struct_time(timeutils_timestamp_t seconds, timeutils_struct_time_t *tm) { + // The following algorithm was inspired from musl's __secs_to_tm + // and simplified to reduce code footprint in the simple case - mp_int_t days = seconds / 86400; + relint_t days = seconds / 86400; seconds %= 86400; + #if MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE if (seconds < 0) { seconds += 86400; days -= 1; } + #endif tm->tm_hour = seconds / 3600; tm->tm_min = seconds / 60 % 60; tm->tm_sec = seconds % 60; - mp_int_t wday = (days + 2) % 7; // Mar 1, 2000 was a Wednesday (2) + relint_t wday = (days + 3) % 7; // Jan 1, 1970 was a Thursday (3) + #if MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE if (wday < 0) { wday += 7; } + #endif tm->tm_wday = wday; - mp_int_t qc_cycles = days / DAYS_PER_400Y; + days += PREV_LEAP_DAY; + + #if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE + // rebase day to the oldest supported date (=> always positive) + mp_uint_t base_year = QC_LEAP_YEAR; + days += QC_BASE_DAY; + mp_uint_t qc_cycles = days / DAYS_PER_400Y; days %= DAYS_PER_400Y; - if (days < 0) { - days += DAYS_PER_400Y; - qc_cycles--; - } - mp_int_t c_cycles = days / DAYS_PER_100Y; + mp_uint_t c_cycles = days / DAYS_PER_100Y; if (c_cycles == 4) { c_cycles--; } days -= (c_cycles * DAYS_PER_100Y); - - mp_int_t q_cycles = days / DAYS_PER_4Y; + #else + mp_uint_t base_year = PREV_LEAP_YEAR; + mp_uint_t qc_cycles = 0; + mp_uint_t c_cycles = 0; + #endif + + mp_uint_t q_cycles = days / DAYS_PER_4Y; + #if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE if (q_cycles == 25) { q_cycles--; } + #endif days -= q_cycles * DAYS_PER_4Y; - mp_int_t years = days / 365; + relint_t years = days / 365; if (years == 4) { years--; } days -= (years * 365); - /* We will compute tm_yday at the very end - mp_int_t leap = !years && (q_cycles || !c_cycles); - - tm->tm_yday = days + 31 + 28 + leap; - if (tm->tm_yday >= 365 + leap) { - tm->tm_yday -= 365 + leap; - } - - tm->tm_yday++; // Make one based - */ - - tm->tm_year = 2000 + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles; + tm->tm_year = base_year + years + 4 * q_cycles + 100 * c_cycles + 400 * qc_cycles; // Note: days_in_month[0] corresponds to March - static const int8_t days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29}; + static const uint8_t days_in_month[] = {31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 29}; mp_int_t month; for (month = 0; days_in_month[month] <= days; month++) { @@ -144,21 +171,28 @@ void timeutils_seconds_since_2000_to_struct_time(mp_uint_t t, timeutils_struct_t } // returns the number of seconds, as an integer, since 2000-01-01 -mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month, +timeutils_timestamp_t timeutils_seconds_since_1970(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { - return - second - + minute * 60 - + hour * 3600 - + (timeutils_year_day(year, month, date) - 1 - + ((year - 2000 + 3) / 4) // add a day each 4 years starting with 2001 - - ((year - 2000 + 99) / 100) // subtract a day each 100 years starting with 2001 - + ((year - 2000 + 399) / 400) // add a day each 400 years starting with 2001 - ) * 86400 - + (year - 2000) * 31536000; + #if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE + mp_uint_t ref_year = QC_LEAP_YEAR; + #else + mp_uint_t ref_year = PREV_LEAP_YEAR; + #endif + timeutils_timestamp_t res; + res = ((relint_t)year - 1970) * 365; + res += (year - (ref_year + 1)) / 4; // add a day each 4 years + #if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE + res -= (year - (ref_year + 1)) / 100; // subtract a day each 100 years + res += (year - (ref_year + 1)) / 400; // add a day each 400 years + res -= QC_LEAP_DAYS; + #endif + res += timeutils_year_day(year, month, date) - 1; + res *= 86400; + res += hour * 3600 + minute * 60 + second; + return res; } -mp_uint_t timeutils_mktime_2000(mp_uint_t year, mp_int_t month, mp_int_t mday, +timeutils_timestamp_t timeutils_mktime_1970(mp_uint_t year, mp_int_t month, mp_int_t mday, mp_int_t hours, mp_int_t minutes, mp_int_t seconds) { // Normalize the tuple. This allows things like: @@ -211,12 +245,16 @@ mp_uint_t timeutils_mktime_2000(mp_uint_t year, mp_int_t month, mp_int_t mday, year++; } } - return timeutils_seconds_since_2000(year, month, mday, hours, minutes, seconds); + return timeutils_seconds_since_1970(year, month, mday, hours, minutes, seconds); } // Calculate the weekday from the date. // The result is zero based with 0 = Monday. // by Michael Keith and Tom Craver, 1990. int timeutils_calc_weekday(int y, int m, int d) { - return ((d += m < 3 ? y-- : y - 2, 23 * m / 9 + d + 4 + y / 4 - y / 100 + y / 400) + 6) % 7; + return ((d += m < 3 ? y-- : y - 2, 23 * m / 9 + d + 4 + y / 4 + #if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE + - y / 100 + y / 400 + #endif + ) + 6) % 7; } diff --git a/shared/timeutils/timeutils.h b/shared/timeutils/timeutils.h index e2a2666e910..35356b462aa 100644 --- a/shared/timeutils/timeutils.h +++ b/shared/timeutils/timeutils.h @@ -27,12 +27,23 @@ #ifndef MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H #define MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H -// CIRCUITPY-CHANGE: MICROPY_EPOCH_IS_1970 -#include "mpconfigport.h" +#include "py/obj.h" +#if MICROPY_PY_BUILTINS_FLOAT && MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE +#include // required for trunc() +#endif + +// `timeutils_timestamp_t` is the type used internally by timeutils to +// represent timestamps, and is always referenced to 1970. +// It may not match the platform-specific `mp_timestamp_t`. +#if MICROPY_TIME_SUPPORT_Y2100_AND_BEYOND || MICROPY_TIME_SUPPORT_Y1969_AND_BEFORE +typedef long long timeutils_timestamp_t; +#else +typedef mp_uint_t timeutils_timestamp_t; +#endif // The number of seconds between 1970/1/1 and 2000/1/1 is calculated using: // time.mktime((2000,1,1,0,0,0,0,0,0)) - time.mktime((1970,1,1,0,0,0,0,0,0)) -#define TIMEUTILS_SECONDS_1970_TO_2000 (946684800ULL) +#define TIMEUTILS_SECONDS_1970_TO_2000 (946684800LL) typedef struct _timeutils_struct_time_t { uint16_t tm_year; // i.e. 2014 @@ -48,62 +59,116 @@ typedef struct _timeutils_struct_time_t { bool timeutils_is_leap_year(mp_uint_t year); mp_uint_t timeutils_days_in_month(mp_uint_t year, mp_uint_t month); mp_uint_t timeutils_year_day(mp_uint_t year, mp_uint_t month, mp_uint_t date); +int timeutils_calc_weekday(int y, int m, int d); -void timeutils_seconds_since_2000_to_struct_time(mp_uint_t t, +void timeutils_seconds_since_1970_to_struct_time(timeutils_timestamp_t t, timeutils_struct_time_t *tm); -mp_uint_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month, +// Year is absolute, month/date are 1-based, hour/minute/second are 0-based. +timeutils_timestamp_t timeutils_seconds_since_1970(mp_uint_t year, mp_uint_t month, mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second); -mp_uint_t timeutils_mktime_2000(mp_uint_t year, mp_int_t month, mp_int_t mday, +// Year is absolute, month/mday are 1-based, hours/minutes/seconds are 0-based. +timeutils_timestamp_t timeutils_mktime_1970(mp_uint_t year, mp_int_t month, mp_int_t mday, mp_int_t hours, mp_int_t minutes, mp_int_t seconds); +static inline mp_timestamp_t timeutils_obj_get_timestamp(mp_obj_t o_in) { + #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE + mp_float_t val = mp_obj_get_float(o_in); + return (mp_timestamp_t)MICROPY_FLOAT_C_FUN(trunc)(val); + #elif MICROPY_TIMESTAMP_IMPL == MICROPY_TIMESTAMP_IMPL_UINT + return mp_obj_get_uint(o_in); + #else + return mp_obj_get_ll(o_in); + #endif +} + +static inline mp_obj_t timeutils_obj_from_timestamp(mp_timestamp_t t) { + #if MICROPY_TIMESTAMP_IMPL == MICROPY_TIMESTAMP_IMPL_UINT + return mp_obj_new_int_from_uint(t); + #else + return mp_obj_new_int_from_ll(t); + #endif +} + +static inline void timeutils_seconds_since_2000_to_struct_time(mp_timestamp_t t, timeutils_struct_time_t *tm) { + timeutils_seconds_since_1970_to_struct_time((timeutils_timestamp_t)(t + TIMEUTILS_SECONDS_1970_TO_2000), tm); +} + +// Year is absolute, month/date are 1-based, hour/minute/second are 0-based. +static inline mp_timestamp_t timeutils_seconds_since_2000(mp_uint_t year, mp_uint_t month, mp_uint_t date, + mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { + return (mp_timestamp_t)timeutils_seconds_since_1970(year, month, date, hour, minute, second) - TIMEUTILS_SECONDS_1970_TO_2000; +} + +// Year is absolute, month/mday are 1-based, hours/minutes/seconds are 0-based. +static inline mp_timestamp_t timeutils_mktime_2000(mp_uint_t year, mp_int_t month, mp_int_t mday, + mp_int_t hours, mp_int_t minutes, mp_int_t seconds) { + return (mp_timestamp_t)timeutils_mktime_1970(year, month, mday, hours, minutes, seconds) - TIMEUTILS_SECONDS_1970_TO_2000; +} + + // Select the Epoch used by the port. #if MICROPY_EPOCH_IS_1970 -static inline void timeutils_seconds_since_epoch_to_struct_time(uint64_t t, timeutils_struct_time_t *tm) { - // TODO this will give incorrect results for dates before 2000/1/1 - timeutils_seconds_since_2000_to_struct_time(t - TIMEUTILS_SECONDS_1970_TO_2000, tm); +static inline void timeutils_seconds_since_epoch_to_struct_time(mp_timestamp_t t, timeutils_struct_time_t *tm) { + timeutils_seconds_since_1970_to_struct_time(t, tm); +} + +// Year is absolute, month/date are 1-based, hour/minute/second are 0-based. +static inline mp_timestamp_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date, + mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { + return timeutils_seconds_since_1970(year, month, date, hour, minute, second); } -static inline uint64_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday, mp_int_t hours, mp_int_t minutes, mp_int_t seconds) { - return timeutils_mktime_2000(year, month, mday, hours, minutes, seconds) + TIMEUTILS_SECONDS_1970_TO_2000; +// Year is absolute, month/mday are 1-based, hours/minutes/seconds are 0-based. +static inline mp_timestamp_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday, + mp_int_t hours, mp_int_t minutes, mp_int_t seconds) { + return timeutils_mktime_1970(year, month, mday, hours, minutes, seconds); } -static inline uint64_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, - mp_uint_t date, mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { - // TODO this will give incorrect results for dates before 2000/1/1 - return timeutils_seconds_since_2000(year, month, date, hour, minute, second) + TIMEUTILS_SECONDS_1970_TO_2000; +static inline mp_timestamp_t timeutils_seconds_since_epoch_from_nanoseconds_since_1970(int64_t ns) { + return (mp_timestamp_t)(ns / 1000000000LL); } -static inline mp_uint_t timeutils_seconds_since_epoch_from_nanoseconds_since_1970(uint64_t ns) { - return ns / 1000000000ULL; +static inline int64_t timeutils_seconds_since_epoch_to_nanoseconds_since_1970(mp_timestamp_t s) { + return (int64_t)s * 1000000000LL; } -static inline uint64_t timeutils_nanoseconds_since_epoch_to_nanoseconds_since_1970(uint64_t ns) { +static inline int64_t timeutils_nanoseconds_since_epoch_to_nanoseconds_since_1970(int64_t ns) { return ns; } #else // Epoch is 2000 -#define timeutils_seconds_since_epoch_to_struct_time timeutils_seconds_since_2000_to_struct_time -#define timeutils_seconds_since_epoch timeutils_seconds_since_2000 -#define timeutils_mktime timeutils_mktime_2000 +static inline void timeutils_seconds_since_epoch_to_struct_time(mp_timestamp_t t, timeutils_struct_time_t *tm) { + timeutils_seconds_since_2000_to_struct_time(t, tm); +} + +// Year is absolute, month/date are 1-based, hour/minute/second are 0-based. +static inline mp_timestamp_t timeutils_seconds_since_epoch(mp_uint_t year, mp_uint_t month, mp_uint_t date, + mp_uint_t hour, mp_uint_t minute, mp_uint_t second) { + return timeutils_seconds_since_2000(year, month, date, hour, minute, second); +} + +// Year is absolute, month/mday are 1-based, hours/minutes/seconds are 0-based. +static inline mp_timestamp_t timeutils_mktime(mp_uint_t year, mp_int_t month, mp_int_t mday, + mp_int_t hours, mp_int_t minutes, mp_int_t seconds) { + return timeutils_mktime_2000(year, month, mday, hours, minutes, seconds); +} -static inline uint64_t timeutils_seconds_since_epoch_to_nanoseconds_since_1970(mp_uint_t s) { - return ((uint64_t)s + TIMEUTILS_SECONDS_1970_TO_2000) * 1000000000ULL; +static inline mp_timestamp_t timeutils_seconds_since_epoch_from_nanoseconds_since_1970(int64_t ns) { + return (mp_timestamp_t)(ns / 1000000000LL - TIMEUTILS_SECONDS_1970_TO_2000); } -static inline mp_uint_t timeutils_seconds_since_epoch_from_nanoseconds_since_1970(uint64_t ns) { - return ns / 1000000000ULL - TIMEUTILS_SECONDS_1970_TO_2000; +static inline int64_t timeutils_seconds_since_epoch_to_nanoseconds_since_1970(mp_timestamp_t s) { + return ((int64_t)s + TIMEUTILS_SECONDS_1970_TO_2000) * 1000000000LL; } static inline int64_t timeutils_nanoseconds_since_epoch_to_nanoseconds_since_1970(int64_t ns) { - return ns + TIMEUTILS_SECONDS_1970_TO_2000 * 1000000000ULL; + return ns + TIMEUTILS_SECONDS_1970_TO_2000 * 1000000000LL; } #endif -int timeutils_calc_weekday(int y, int m, int d); - #endif // MICROPY_INCLUDED_LIB_TIMEUTILS_TIMEUTILS_H diff --git a/shared/upytesthelper/upytesthelper.c b/shared/upytesthelper/upytesthelper.c deleted file mode 100644 index ba20037f7ac..00000000000 --- a/shared/upytesthelper/upytesthelper.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Linaro Limited - * - * 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. - */ -#include - -#include "py/mphal.h" -#include "py/gc.h" -#include "py/runtime.h" -#include "py/compile.h" -#include "upytesthelper.h" - -#if !MICROPY_PY_SYS_PATH -#error "upytesthelper requires MICROPY_PY_SYS_PATH=1" -#endif - -#if !MICROPY_PY_SYS_ARGV -#error "upytesthelper requires MICROPY_PY_SYS_ARGV=1" -#endif - -static const char *test_exp_output; -static int test_exp_output_len, test_rem_output_len; -static int test_failed; -static void *heap_start, *heap_end; - -void upytest_set_heap(void *start, void *end) { - heap_start = start; - heap_end = end; -} - -void upytest_set_expected_output(const char *output, unsigned len) { - test_exp_output = output; - test_exp_output_len = test_rem_output_len = len; - test_failed = false; -} - -bool upytest_is_failed(void) { - if (test_failed) { - return true; - } - #if 0 - if (test_rem_output_len != 0) { - printf("remaining len: %d\n", test_rem_output_len); - } - #endif - return test_rem_output_len != 0; -} - -// MP_PLAT_PRINT_STRN() should be redirected to this function. -// It will pass-through any content to mp_hal_stdout_tx_strn_cooked() -// (the default value of MP_PLAT_PRINT_STRN), but will also match -// it to the expected output as set by upytest_set_expected_output(). -// If mismatch happens, upytest_is_failed() returns true. -void upytest_output(const char *str, mp_uint_t len) { - if (!test_failed) { - if (len > test_rem_output_len) { - test_failed = true; - } else { - test_failed = memcmp(test_exp_output, str, len); - #if 0 - if (test_failed) { - printf("failed after char %u, within %d chars, res: %d\n", - test_exp_output_len - test_rem_output_len, (int)len, test_failed); - for (int i = 0; i < len; i++) { - if (str[i] != test_exp_output[i]) { - printf("%d %02x %02x\n", i, str[i], test_exp_output[i]); - } - } - } - #endif - test_exp_output += len; - test_rem_output_len -= len; - } - } - mp_hal_stdout_tx_strn_cooked(str, len); -} - -void upytest_execute_test(const char *src) { - // To provide clean room for each test, interpreter and heap are - // reinitialized before running each. - gc_init(heap_start, heap_end); - mp_init(); - mp_sys_path = mp_obj_new_list(0, NULL); - #if MICROPY_MODULE_FROZEN - mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__dot_frozen)); - #endif - mp_obj_list_init(mp_sys_argv, 0); - - nlr_buf_t nlr; - if (nlr_push(&nlr) == 0) { - mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, src, strlen(src), 0); - qstr source_name = lex->source_name; - mp_parse_tree_t parse_tree = mp_parse(lex, MP_PARSE_FILE_INPUT); - mp_obj_t module_fun = mp_compile(&parse_tree, source_name, false); - mp_call_function_0(module_fun); - nlr_pop(); - } else { - mp_obj_t exc = (mp_obj_t)nlr.ret_val; - if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_SystemExit)) { - // Assume that sys.exit() is called to skip the test. - // TODO: That can be always true, we should set up convention to - // use specific exit code as skip indicator. - tinytest_set_test_skipped_(); - goto end; - } - mp_obj_print_exception(&mp_plat_print, exc); - tt_abort_msg("Uncaught exception\n"); - } - - if (upytest_is_failed()) { - tinytest_set_test_failed_(); - } - -end: - mp_deinit(); -} diff --git a/shared/upytesthelper/upytesthelper.h b/shared/upytesthelper/upytesthelper.h deleted file mode 100644 index 3a292befd77..00000000000 --- a/shared/upytesthelper/upytesthelper.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Linaro Limited - * - * 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. - */ - -#include -#include -#include "py/mpconfig.h" -#include "lib/tinytest/tinytest.h" -#include "lib/tinytest/tinytest_macros.h" - -void upytest_set_heap(void *start, void *end); -void upytest_set_expected_output(const char *output, unsigned len); -void upytest_execute_test(const char *src); -void upytest_output(const char *str, mp_uint_t len); -bool upytest_is_failed(void); diff --git a/stubs/micropython/__init__.pyi b/stubs/micropython/__init__.pyi new file mode 100644 index 00000000000..1bcde6ae813 --- /dev/null +++ b/stubs/micropython/__init__.pyi @@ -0,0 +1,20 @@ +"""Access and control MicroPython internals""" + +def const[T](expr: T) -> T: + """Used to declare that the expression is a constant so that the compiler + can optimise it. The use of this function should be as follows:: + + from micropython import const + + CONST_X = const(123) + CONST_Y = const(2 * CONST_X + 1) + + Constants declared this way are still accessible as global variables from + outside the module they are declared in. On the other hand, if a constant + begins with an underscore then it is hidden, it is not available as a global + variable, and does not take up any memory during execution. + + This `const` function is recognised directly by the MicroPython parser and is + provided as part of the :mod:`micropython` module mainly so that scripts can be + written which run under both CPython and MicroPython, by following the above + pattern.""" diff --git a/supervisor/filesystem.h b/supervisor/filesystem.h index a0445b0510d..30cd83d4438 100644 --- a/supervisor/filesystem.h +++ b/supervisor/filesystem.h @@ -21,6 +21,7 @@ void filesystem_set_internal_writable_by_usb(bool usb_writable); void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection); void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable); void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection); +void filesystem_set_ignore_write_protection(fs_user_mount_t *vfs, bool ignore_write_protection); // Whether user code can modify the filesystem. It doesn't depend on the state // of USB. Don't use this for a workflow. In workflows, grab the shared file diff --git a/supervisor/linker.h b/supervisor/linker.h index 5b6895d5b49..6f05d93bb69 100644 --- a/supervisor/linker.h +++ b/supervisor/linker.h @@ -8,11 +8,16 @@ #pragma once -#if defined(IMXRT1XXX) || defined(FOMU) || defined(STM32H7) || defined(RASPBERRYPI) +#if !defined(__ZEPHYR__) && (defined(IMXRT1XXX) || defined(FOMU) || defined(RASPBERRYPI)) #define PLACE_IN_DTCM_DATA(name) name __attribute__((section(".dtcm_data." #name))) #define PLACE_IN_DTCM_BSS(name) name __attribute__((section(".dtcm_bss." #name))) // Don't inline ITCM functions because that may pull them out of ITCM into other sections. #define PLACE_IN_ITCM(name) __attribute__((section(".itcm." #name), noinline, aligned(4))) name +#elif !defined(__ZEPHYR__) && defined(STM32H7) +#define PLACE_IN_DTCM_DATA(name) name __attribute__((section(".dtcm_data." #name))) +#define PLACE_IN_DTCM_BSS(name) name __attribute__((section(".dtcm_bss." #name))) +// using ITCM on the H7 generates hard fault exception +#define PLACE_IN_ITCM(name) name #else #define PLACE_IN_DTCM_DATA(name) name #define PLACE_IN_DTCM_BSS(name) name diff --git a/supervisor/port.h b/supervisor/port.h index 29c071515c1..2437edafb14 100644 --- a/supervisor/port.h +++ b/supervisor/port.h @@ -9,6 +9,7 @@ #include #include +#include "py/obj.h" #include "supervisor/shared/safe_mode.h" // Provided by the linker; @@ -23,13 +24,16 @@ extern uint32_t _ebss; safe_mode_t port_init(void); // Reset the microcontroller completely. -void reset_cpu(void) NORETURN; +void reset_cpu(void) MP_NORETURN; + +// Reset port state that must be torn down before anything else is reset. +void reset_port_early(void); // Reset the microcontroller state. void reset_port(void); // Reset to the bootloader -void reset_to_bootloader(void) NORETURN; +void reset_to_bootloader(void) MP_NORETURN; // Get stack limit address uint32_t *port_stack_get_limit(void); @@ -91,15 +95,17 @@ void port_wake_main_task(void); void port_wake_main_task_from_isr(void); // Some ports may use real RTOS tasks besides the background task framework of -// CircuitPython. Calling this will yield to other tasks and then return to the -// CircuitPython task when others are done. -void port_yield(void); - -// Some ports need special handling just after completing boot.py execution. -// This function is called once while boot.py's VM is still valid, and -// then a second time after the VM is finalized. -// A default weak implementation is provided that does nothing. -void port_post_boot_py(bool heap_valid); +// CircuitPython. Calling this will yield to other tasks at the same priority level +// (or higher priority level if pre-emption is not immediate in the RTOS) +// and then return to the CircuitPython task when others are done. +// Note that this does NOT yield to lower priority tasks. Use port_task_sleep_ms() instead. +void port_task_yield(void); + +// On ports using real RTOS tasks, yield to other tasks for at least msecs. +// This will allow lower priority tasks to run. +// On non-RTOS implementations, this just sleeps for msecs and will run CircuitPython +// background tasks. +void port_task_sleep_ms(uint32_t msecs); // Some ports want to add information to boot_out.txt. // A default weak implementation is provided that does nothing. @@ -108,3 +114,20 @@ void port_boot_info(void); // Some ports want to mark additional pointers as gc roots. // A default weak implementation is provided that does nothing. void port_gc_collect(void); + +// Most ports that implement CIRCUITPY_BOOT_BUTTON use a generic version of +// this function to sense the button. Ports that need to can override this +// function to provide their own implementation. +bool port_boot_button_pressed(void); + +// Allocating objects on the port heap, not the VM heap. +#define mp_obj_port_malloc(struct_type, obj_type) ((struct_type *)mp_obj_port_malloc_helper(sizeof(struct_type), obj_type)) +#define mp_obj_port_malloc_var(struct_type, var_field, var_type, var_num, obj_type) ((struct_type *)mp_obj_port_malloc_helper(offsetof(struct_type, var_field) + sizeof(var_type) * (var_num), obj_type)) + +void *mp_obj_port_malloc_helper(size_t num_bytes, const mp_obj_type_t *type); +mp_obj_t mp_obj_new_port_tuple(size_t n, const mp_obj_t *items); + +// Safely free an object that may have been allocated from either the GC heap or port heap. +// If the pointer is on the GC heap, it will be freed by the GC automatically. +// If the pointer is not on the GC heap, it will be freed with port_free. +void circuitpy_free_obj(mp_obj_t obj); diff --git a/supervisor/port_heap.h b/supervisor/port_heap.h index f035cc2409e..3e6b5a660fa 100644 --- a/supervisor/port_heap.h +++ b/supervisor/port_heap.h @@ -21,9 +21,16 @@ void port_heap_init(void); void *port_malloc(size_t size, bool dma_capable); +void *port_malloc_zero(size_t size, bool dma_capable); void port_free(void *ptr); -void *port_realloc(void *ptr, size_t size); +void *port_realloc(void *ptr, size_t size, bool dma_capable); + +#if !CIRCUITPY_ALL_MEMORY_DMA_CAPABLE +// Check if a buffer pointer is in DMA-capable memory. DMA-capable memory is also accessible during +// flash operations. +bool port_buffer_is_dma_capable(const void *ptr); +#endif size_t port_heap_get_largest_free_size(void); diff --git a/supervisor/shared/background_callback.c b/supervisor/shared/background_callback.c index 309210b7a12..ffeb78bbb83 100644 --- a/supervisor/shared/background_callback.c +++ b/supervisor/shared/background_callback.c @@ -58,7 +58,7 @@ inline bool background_callback_pending(void) { static int background_prevention_count; -void PLACE_IN_ITCM(background_callback_run_all)() { +void PLACE_IN_ITCM(background_callback_run_all)(void) { port_background_task(); if (!background_callback_pending()) { return; @@ -89,13 +89,13 @@ void PLACE_IN_ITCM(background_callback_run_all)() { CALLBACK_CRITICAL_END; } -void background_callback_prevent() { +void background_callback_prevent(void) { CALLBACK_CRITICAL_BEGIN; ++background_prevention_count; CALLBACK_CRITICAL_END; } -void background_callback_allow() { +void background_callback_allow(void) { CALLBACK_CRITICAL_BEGIN; --background_prevention_count; CALLBACK_CRITICAL_END; @@ -103,7 +103,7 @@ void background_callback_allow() { // Filter out queued callbacks if they are allocated on the heap. -void background_callback_reset() { +void background_callback_reset(void) { background_callback_t *new_head = NULL; background_callback_t **previous_next = &new_head; background_callback_t *new_tail = NULL; diff --git a/supervisor/shared/bluetooth/bluetooth.c b/supervisor/shared/bluetooth/bluetooth.c index 2fe97f9f0b0..263aba7cbc9 100644 --- a/supervisor/shared/bluetooth/bluetooth.c +++ b/supervisor/shared/bluetooth/bluetooth.c @@ -10,16 +10,13 @@ #include "shared-bindings/_bleio/__init__.h" #include "shared-bindings/_bleio/Adapter.h" -#if defined(CIRCUITPY_BOOT_BUTTON) -#include "shared-bindings/digitalio/DigitalInOut.h" -#include "shared-bindings/time/__init__.h" -#endif #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" #include "shared-module/storage/__init__.h" #include "common-hal/_bleio/__init__.h" +#include "supervisor/port.h" #include "supervisor/shared/serial.h" #include "supervisor/shared/status_leds.h" #include "supervisor/shared/tick.h" @@ -31,7 +28,7 @@ #include "supervisor/shared/bluetooth/file_transfer.h" #endif -#if CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_BLE_SERIAL_SERVICE #include "supervisor/shared/bluetooth/serial.h" #endif @@ -39,36 +36,38 @@ #include "supervisor/shared/status_bar.h" #endif -#if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI && CIRCUITPY_OS_GETENV -#include "shared-module/os/__init__.h" +#if (CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE || (CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI)) && CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" #endif // This standard advertisement advertises the CircuitPython editing service and a CIRCUITPY short name. -const uint8_t public_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags - 0x02, 0x0a, 0xec, // 3-5 TX power level -20 - #if CIRCUITPY_BLE_FILE_SERVICE - 0x03, 0x02, 0xbb, 0xfe, // 6 - 9 Incomplete service list (File Transfer service) - #endif - 0x0e, 0xff, 0x22, 0x08, // 10 - 13 Adafruit Manufacturer Data - 0x0a, 0x04, 0x00, // 14 - 16 Creator ID / Creation ID - CIRCUITPY_CREATOR_ID & 0xff, // 17 - 20 Creator ID - (CIRCUITPY_CREATOR_ID >> 8) & 0xff, - (CIRCUITPY_CREATOR_ID >> 16) & 0xff, - (CIRCUITPY_CREATOR_ID >> 24) & 0xff, - CIRCUITPY_CREATION_ID & 0xff, // 21 - 24 Creation ID - (CIRCUITPY_CREATION_ID >> 8) & 0xff, - (CIRCUITPY_CREATION_ID >> 16) & 0xff, - (CIRCUITPY_CREATION_ID >> 24) & 0xff, - 0x05, 0x08, 0x43, 0x49, 0x52, 0x43 // 25 - 31 - Short name +const uint8_t public_advertising_data[] = { + 0x02, 0x01, 0x06, // 0-2 Flags + 0x02, 0x0a, 0xec, // 3-5 TX power level -20 + #if CIRCUITPY_BLE_FILE_SERVICE + 0x03, 0x02, 0xbb, 0xfe, // 6 - 9 Incomplete service list (File Transfer service) + #endif + 0x0e, 0xff, 0x22, 0x08, // 10 - 13 Adafruit Manufacturer Data + 0x0a, 0x04, 0x00, // 14 - 16 Creator ID / Creation ID + CIRCUITPY_CREATOR_ID & 0xff, // 17 - 20 Creator ID + (CIRCUITPY_CREATOR_ID >> 8) & 0xff, + (CIRCUITPY_CREATOR_ID >> 16) & 0xff, + (CIRCUITPY_CREATOR_ID >> 24) & 0xff, + CIRCUITPY_CREATION_ID & 0xff, // 21 - 24 Creation ID + (CIRCUITPY_CREATION_ID >> 8) & 0xff, + (CIRCUITPY_CREATION_ID >> 16) & 0xff, + (CIRCUITPY_CREATION_ID >> 24) & 0xff, + 0x05, 0x08, 0x43, 0x49, 0x52, 0x43 // 25 - 31 - Short name }; -const uint8_t private_advertising_data[] = { 0x02, 0x01, 0x06, // 0-2 Flags - 0x02, 0x0a, 0x00 // 3-5 TX power level 0 +const uint8_t private_advertising_data[] = { + 0x02, 0x01, 0x06, // 0-2 Flags + 0x02, 0x0a, 0x00 // 3-5 TX power level 0 }; // This scan response advertises the full device name (if it fits.) uint8_t circuitpython_scan_response_data[31]; -#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE static bool boot_in_discovery_mode = false; static bool advertising = false; static bool _private_advertising = false; @@ -78,6 +77,11 @@ static bool ble_started = false; #define WORKFLOW_ENABLED 1 #define WORKFLOW_DISABLED 2 +// Value of CIRCUITPY_BLE_WORKFLOW in settings.toml. Defaults to true. +static bool ble_workflow_setting = true; + +// Has BLE workflow been enabled, because it was allow and we've bonded to the workflow host? +// Also controlled by supervisor.runtime.ble_workflow. static uint8_t workflow_state = WORKFLOW_UNSET; static bool was_connected = false; @@ -176,13 +180,23 @@ static void supervisor_bluetooth_start_advertising(void) { advertising = status == 0; } -#endif // CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE +#endif // CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE #define BLE_DISCOVERY_DATA_GUARD 0xbb0000bb #define BLE_DISCOVERY_DATA_GUARD_MASK 0xff0000ff void supervisor_bluetooth_init(void) { - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if (CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE) + + #if CIRCUITPY_SETTINGS_TOML + // Check if the user disabled BLE workflow in settings.toml. The default is that it's enabled. + ble_workflow_setting = true; + settings_get_bool("CIRCUITPY_BLE_WORKFLOW", &ble_workflow_setting); + if (!ble_workflow_setting) { + return; + } + #endif // CIRCUITPY_SETTINGS_TOML + uint32_t reset_state = port_get_saved_word(); uint32_t ble_mode = 0; if ((reset_state & BLE_DISCOVERY_DATA_GUARD_MASK) == BLE_DISCOVERY_DATA_GUARD) { @@ -190,14 +204,17 @@ void supervisor_bluetooth_init(void) { } const mcu_reset_reason_t reset_reason = common_hal_mcu_processor_get_reset_reason(); boot_in_discovery_mode = false; - if (reset_reason != RESET_REASON_POWER_ON && - reset_reason != RESET_REASON_RESET_PIN && - reset_reason != RESET_REASON_UNKNOWN && - reset_reason != RESET_REASON_SOFTWARE) { + + // These are error resets reflecting a problem and should not initiate discovery mode. + if (reset_reason == MCU_RESET_REASON_BROWNOUT || + reset_reason == MCU_RESET_REASON_WATCHDOG || + reset_reason == MCU_RESET_REASON_RESCUE_DEBUG) { return; } + // Same as what is done by `import _bleio`. common_hal_bleio_init(); + if (ble_mode == 0) { port_set_saved_word(BLE_DISCOVERY_DATA_GUARD | (0x01 << 8)); } @@ -213,48 +230,49 @@ void supervisor_bluetooth_init(void) { reset_state = 0x0; } bool bonded = common_hal_bleio_adapter_is_bonded_to_central(&common_hal_bleio_adapter_obj); - #if !CIRCUITPY_USB_DEVICE - // Boot into discovery if USB isn't available and we aren't bonded already. - // Checking here allows us to have the status LED solidly on even if no button was - // pressed. - bool wifi_workflow_active = false; - #if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI && CIRCUITPY_OS_GETENV - char _api_password[64]; - const size_t api_password_len = sizeof(_api_password) - 1; - os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_WEB_API_PASSWORD", _api_password + 1, api_password_len); - wifi_workflow_active = result == GETENV_OK; - #endif - if (!bonded && !wifi_workflow_active) { - boot_in_discovery_mode = true; - } - #endif - while (diff < 1000) { - #ifdef CIRCUITPY_STATUS_LED - // Blink on for 50 and off for 100 - bool led_on = boot_in_discovery_mode || (diff % 150) <= 50; - if (led_on) { - new_status_color(0x0000ff); - } else { - new_status_color(BLACK); - } + + // Don't go into discovery mode when waking from deep sleep. But if we're already bonded, + // BLE workflow can continue after deep sleep. + if (reset_reason != MCU_RESET_REASON_DEEP_SLEEP_ALARM) { + #if !CIRCUITPY_USB_DEVICE + // Boot into discovery if USB isn't available and we aren't bonded already. + // Checking here allows us to have the status LED solidly on even if no button was + // pressed. + + bool wifi_workflow_active = false; + #if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI && CIRCUITPY_SETTINGS_TOML + char _api_password[64]; + const size_t api_password_len = sizeof(_api_password) - 1; + settings_err_t result = settings_get_str("CIRCUITPY_WEB_API_PASSWORD", _api_password + 1, api_password_len); + wifi_workflow_active = result == SETTINGS_OK; #endif - // Init the boot button every time in case it is used for LEDs. - #ifdef CIRCUITPY_BOOT_BUTTON - digitalio_digitalinout_obj_t boot_button; - common_hal_digitalio_digitalinout_construct(&boot_button, CIRCUITPY_BOOT_BUTTON); - common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP); - common_hal_time_delay_ms(1); - bool button_pressed = !common_hal_digitalio_digitalinout_get_value(&boot_button); - common_hal_digitalio_digitalinout_deinit(&boot_button); - if (button_pressed) { + + if (!bonded && !wifi_workflow_active) { boot_in_discovery_mode = true; } - #endif - diff = supervisor_ticks_ms64() - start_ticks; - } - if (boot_in_discovery_mode) { - common_hal_bleio_adapter_erase_bonding(&common_hal_bleio_adapter_obj); + #endif // !CIRCUITPY_USB_DEVICE + + while (diff < 1000) { + #if CIRCUITPY_STATUS_LED + // Blink on for 50 and off for 100 + bool led_on = boot_in_discovery_mode || (diff % 150) <= 50; + if (led_on) { + new_status_color(0x0000ff); + } else { + new_status_color(BLACK); + } + #endif + if (port_boot_button_pressed()) { + boot_in_discovery_mode = true; + break; + } + diff = supervisor_ticks_ms64() - start_ticks; + } + if (boot_in_discovery_mode) { + common_hal_bleio_adapter_erase_bonding(&common_hal_bleio_adapter_obj); + } } + if (boot_in_discovery_mode || bonded) { workflow_state = WORKFLOW_ENABLED; } else { @@ -269,7 +287,7 @@ void supervisor_bluetooth_init(void) { } void supervisor_bluetooth_background(void) { - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE if (!ble_started) { return; } @@ -301,7 +319,7 @@ void supervisor_bluetooth_background(void) { } void supervisor_start_bluetooth(void) { - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE if (workflow_state != WORKFLOW_ENABLED || ble_started) { return; @@ -313,7 +331,7 @@ void supervisor_start_bluetooth(void) { supervisor_start_bluetooth_file_transfer(); #endif - #if CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE supervisor_start_bluetooth_serial(); #endif @@ -331,7 +349,7 @@ void supervisor_start_bluetooth(void) { } void supervisor_stop_bluetooth(void) { - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE if (!ble_started && workflow_state != WORKFLOW_ENABLED) { return; @@ -343,7 +361,7 @@ void supervisor_stop_bluetooth(void) { supervisor_stop_bluetooth_file_transfer(); #endif - #if CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE supervisor_stop_bluetooth_serial(); #endif @@ -351,8 +369,8 @@ void supervisor_stop_bluetooth(void) { } void supervisor_bluetooth_enable_workflow(void) { - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE - if (workflow_state == WORKFLOW_DISABLED) { + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE + if (!ble_workflow_setting || workflow_state == WORKFLOW_DISABLED) { return; } workflow_state = WORKFLOW_ENABLED; @@ -360,13 +378,13 @@ void supervisor_bluetooth_enable_workflow(void) { } void supervisor_bluetooth_disable_workflow(void) { - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE workflow_state = WORKFLOW_DISABLED; #endif } bool supervisor_bluetooth_workflow_is_enabled(void) { - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE if (workflow_state == WORKFLOW_ENABLED) { return true; } diff --git a/supervisor/shared/bluetooth/serial.c b/supervisor/shared/bluetooth/serial.c index 42c9b4bb387..86ff1738a2a 100644 --- a/supervisor/shared/bluetooth/serial.c +++ b/supervisor/shared/bluetooth/serial.c @@ -156,7 +156,7 @@ void supervisor_stop_bluetooth_serial(void) { } bool ble_serial_connected(void) { - return _tx_packet_buffer.conn_handle != BLEIO_HANDLE_INVALID; + return common_hal_bleio_packet_buffer_connected(&_tx_packet_buffer); } uint32_t ble_serial_available(void) { diff --git a/supervisor/shared/display.c b/supervisor/shared/display.c index f6788af0a8d..1352c76b006 100644 --- a/supervisor/shared/display.c +++ b/supervisor/shared/display.c @@ -7,8 +7,10 @@ #include "supervisor/shared/display.h" #include +#include "supervisor/port.h" #include "py/mpstate.h" +#include "py/gc.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/Palette.h" @@ -36,6 +38,82 @@ #if CIRCUITPY_TERMINALIO #include "supervisor/port.h" + +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" +#endif + +#if CIRCUITPY_LVFONTIO +#include "shared-bindings/lvfontio/OnDiskFont.h" +#include "supervisor/filesystem.h" +#include "extmod/vfs_fat.h" +#include "lib/oofatfs/ff.h" + +#include "supervisor/shared/serial.h" + +// Check if a custom font file exists and return its path if found +// Returns true if font file exists, false otherwise +static bool check_for_custom_font(const char **font_path_out) { + if (!filesystem_present()) { + return false; + } + + fs_user_mount_t *vfs = filesystem_circuitpy(); + if (vfs == NULL) { + return false; + } + + // Use FATFS directly to check if file exists + FILINFO file_info; + const char *default_font_path = "/fonts/terminal.lvfontbin"; + const char *font_path = default_font_path; + + #if CIRCUITPY_SETTINGS_TOML + // Buffer for storing custom font path + static char custom_font_path[128]; + if (settings_get_str("CIRCUITPY_TERMINAL_FONT", custom_font_path, sizeof(custom_font_path)) == SETTINGS_OK) { + // Use custom font path from environment variable + font_path = custom_font_path; + } + #endif + + FRESULT result = f_stat(&vfs->fatfs, font_path, &file_info); + if (result == FR_OK) { + if (font_path_out != NULL) { + *font_path_out = font_path; + } + return true; + } + + // If custom font path doesn't exist, use default font + font_path = default_font_path; + result = f_stat(&vfs->fatfs, font_path, &file_info); + + if (result == FR_OK) { + if (font_path_out != NULL) { + *font_path_out = font_path; + } + return true; + } + + return false; +} + +// Initialize a BuiltinFont object with the specified font file and max_slots +// Returns true on success, false on failure +static bool init_lvfont(lvfontio_ondiskfont_t *font, const char *font_path, uint16_t max_slots) { + if (font == NULL) { + return false; + } + + font->base.type = &lvfontio_ondiskfont_type; + + // Pass false for use_gc_allocator during startup when garbage collector isn't fully initialized + common_hal_lvfontio_ondiskfont_construct(font, font_path, max_slots, false); + + return !common_hal_lvfontio_ondiskfont_deinited(font); +} +#endif #endif #if CIRCUITPY_REPL_LOGO @@ -49,26 +127,66 @@ static uint8_t *tilegrid_tiles = NULL; static size_t tilegrid_tiles_size = 0; #endif +#if CIRCUITPY_LVFONTIO && CIRCUITPY_TERMINALIO +static lvfontio_ondiskfont_t *lvfont = NULL; +#endif + void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { if (supervisor_terminal_started()) { return; } + + #if CIRCUITPY_TERMINALIO // Default the scale to 2 because we may show blinka without the terminal for // languages that don't have font support. - uint8_t scale = 2; + mp_int_t scale = 2; - #if CIRCUITPY_TERMINALIO displayio_tilegrid_t *scroll_area = &supervisor_terminal_scroll_area_text_grid; displayio_tilegrid_t *status_bar = &supervisor_terminal_status_bar_text_grid; - bool reset_tiles = false; - uint16_t width_in_tiles = width_px / scroll_area->tile_width; + bool reset_tiles = tilegrid_tiles == NULL; + + uint16_t glyph_width = 0; + uint16_t glyph_height = 0; + + #if CIRCUITPY_LVFONTIO + // Check if we have a custom terminal font in the filesystem + bool use_lv_font = false; + const char *font_path = NULL; + + if (check_for_custom_font(&font_path)) { + // Initialize a temporary font just to get dimensions + lvfontio_ondiskfont_t temp_font; + if (init_lvfont(&temp_font, font_path, 1)) { + // Get the font dimensions + common_hal_lvfontio_ondiskfont_get_dimensions(&temp_font, &glyph_width, &glyph_height); + + // Clean up the temp font - we'll create a proper one later + common_hal_lvfontio_ondiskfont_deinit(&temp_font); + use_lv_font = true; + reset_tiles = true; + // TODO: We may want to detect when the files modified time hasn't changed. + } + } + #endif + #if CIRCUITPY_FONTIO + if (glyph_width == 0) { + glyph_width = supervisor_terminal_font.width; + glyph_height = supervisor_terminal_font.height; + } + #endif + + uint16_t width_in_tiles = width_px / glyph_width; + // determine scale based on width - if (width_in_tiles <= 80) { + if (width_in_tiles <= 120) { scale = 1; } + #if CIRCUITPY_SETTINGS_TOML + (void)settings_get_int("CIRCUITPY_TERMINAL_SCALE", &scale); + #endif - width_in_tiles = MAX(1, width_px / (scroll_area->tile_width * scale)); - uint16_t height_in_tiles = MAX(2, height_px / (scroll_area->tile_height * scale)); + width_in_tiles = MAX(1, width_px / (glyph_width * scale)); + uint16_t height_in_tiles = MAX(2, height_px / (glyph_height * scale)); uint16_t total_tiles = width_in_tiles * height_in_tiles; @@ -77,69 +195,121 @@ void supervisor_start_terminal(uint16_t width_px, uint16_t height_px) { (scroll_area->height_in_tiles != height_in_tiles - 1)) { reset_tiles = true; } - // Reuse the previous allocation if possible - if (tilegrid_tiles) { - if (tilegrid_tiles_size != total_tiles) { + + circuitpython_splash.scale = scale; + if (!reset_tiles) { + return; + } + + // Adjust the display dimensions to account for scale of the outer group. + width_px /= scale; + height_px /= scale; + + // Number of tiles from the left edge to inset the status bar. + size_t min_left_padding = 0; + status_bar->tile_width = glyph_width; + status_bar->tile_height = glyph_height; + #if CIRCUITPY_REPL_LOGO + // Blinka + 1 px padding minimum + min_left_padding = supervisor_blinka_sprite.pixel_width + 1; + // Align the status bar to the bottom of the logo. + status_bar->y = supervisor_blinka_sprite.pixel_height - status_bar->tile_height; + #else + status_bar->y = 0; + #endif + status_bar->width_in_tiles = (width_px - min_left_padding) / status_bar->tile_width; + status_bar->height_in_tiles = 1; + status_bar->pixel_width = status_bar->width_in_tiles * status_bar->tile_width; + status_bar->pixel_height = status_bar->tile_height; + // Right align the status bar. + status_bar->x = width_px - status_bar->pixel_width; + status_bar->top_left_y = 0; + status_bar->full_change = true; + + scroll_area->tile_width = glyph_width; + scroll_area->tile_height = glyph_height; + scroll_area->width_in_tiles = width_in_tiles; + // Leave space for the status bar, no matter if we have logo or not. + scroll_area->height_in_tiles = height_in_tiles - 1; + scroll_area->pixel_width = scroll_area->width_in_tiles * scroll_area->tile_width; + scroll_area->pixel_height = scroll_area->height_in_tiles * scroll_area->tile_height; + // Right align the scroll area to give margin to the start of each line. + scroll_area->x = width_px - scroll_area->pixel_width; + scroll_area->top_left_y = 0; + // Align the scroll area to the bottom so that the newest line isn't cutoff. The top line + // may be clipped by the status bar and that's ok. + scroll_area->y = height_px - scroll_area->pixel_height; + scroll_area->full_change = true; + + mp_obj_t new_bitmap = mp_const_none; + mp_obj_t new_font = mp_const_none; + + #if CIRCUITPY_LVFONTIO + if (lvfont != NULL) { + common_hal_lvfontio_ondiskfont_deinit(lvfont); + // This will also free internal buffers that may change size. + port_free(lvfont); + lvfont = NULL; + } + + if (use_lv_font) { + // We found a custom terminal font file, use it instead of the built-in font + + lvfont = port_malloc(sizeof(lvfontio_ondiskfont_t), false); + if (lvfont != NULL) { + // Use the number of tiles in the terminal and status bar for the number of slots + // This ensures we have enough slots to display all characters that could appear on screen + uint16_t num_slots = width_in_tiles * height_in_tiles; + + // Initialize the font with our helper function + if (init_lvfont(lvfont, font_path, num_slots)) { + // Get the bitmap from the font + new_bitmap = common_hal_lvfontio_ondiskfont_get_bitmap(lvfont); + new_font = MP_OBJ_FROM_PTR(lvfont); + } else { + // If font initialization failed, free the memory and fall back to built-in font + port_free(lvfont); + lvfont = NULL; + use_lv_font = false; + } + } + } + #endif + #if CIRCUITPY_FONTIO + if (new_font == mp_const_none) { + new_bitmap = MP_OBJ_FROM_PTR(supervisor_terminal_font.bitmap); + new_font = MP_OBJ_FROM_PTR(&supervisor_terminal_font); + } + #endif + + if (new_font != mp_const_none) { + size_t total_values = common_hal_displayio_bitmap_get_width(new_bitmap) / glyph_width; + if (tilegrid_tiles) { port_free(tilegrid_tiles); tilegrid_tiles = NULL; - tilegrid_tiles_size = 0; - reset_tiles = true; } - } - if (!tilegrid_tiles) { - tilegrid_tiles = port_malloc(total_tiles, false); - reset_tiles = true; + size_t bytes_per_tile = 1; + if (total_tiles > 255) { + // Two bytes per tile. + bytes_per_tile = 2; + } + tilegrid_tiles = port_malloc(total_tiles * bytes_per_tile, false); if (!tilegrid_tiles) { return; } - } - - if (reset_tiles) { - // Adjust the display dimensions to account for scale of the outer group. - width_px /= scale; - height_px /= scale; - - // Number of tiles from the left edge to inset the status bar. - size_t min_left_padding = 0; - #if CIRCUITPY_REPL_LOGO - // Blinka + 1 px padding minimum - min_left_padding = supervisor_blinka_sprite.pixel_width + 1; - // Align the status bar to the bottom of the logo. - status_bar->y = supervisor_blinka_sprite.pixel_height - status_bar->tile_height; - #else - status_bar->y = 0; - #endif - status_bar->width_in_tiles = (width_px - min_left_padding) / status_bar->tile_width; - status_bar->height_in_tiles = 1; - status_bar->pixel_width = status_bar->width_in_tiles * status_bar->tile_width; - status_bar->pixel_height = status_bar->tile_height; - // Right align the status bar. - status_bar->x = width_px - status_bar->pixel_width; - status_bar->top_left_y = 0; status_bar->tiles = tilegrid_tiles; - status_bar->full_change = true; - - scroll_area->width_in_tiles = width_in_tiles; - // Leave space for the status bar, no matter if we have logo or not. - scroll_area->height_in_tiles = height_in_tiles - 1; - scroll_area->pixel_width = scroll_area->width_in_tiles * scroll_area->tile_width; - scroll_area->pixel_height = scroll_area->height_in_tiles * scroll_area->tile_height; - // Right align the scroll area to give margin to the start of each line. - scroll_area->x = width_px - scroll_area->pixel_width; - scroll_area->top_left_y = 0; - // Align the scroll area to the bottom so that the newest line isn't cutoff. The top line - // may be clipped by the status bar and that's ok. - scroll_area->y = height_px - scroll_area->pixel_height; - scroll_area->tiles = tilegrid_tiles + width_in_tiles; - scroll_area->full_change = true; - - common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, &supervisor_terminal_font, status_bar); - - // Do not update status bar until after boot.py has run, in case it is disabled. + status_bar->tiles_in_bitmap = total_values; + status_bar->bitmap_width_in_tiles = total_values; + scroll_area->tiles = tilegrid_tiles + width_in_tiles * bytes_per_tile; + scroll_area->tiles_in_bitmap = total_values; + scroll_area->bitmap_width_in_tiles = total_values; + + common_hal_displayio_tilegrid_set_bitmap(scroll_area, new_bitmap); + common_hal_displayio_tilegrid_set_bitmap(status_bar, new_bitmap); + common_hal_terminalio_terminal_construct(&supervisor_terminal, scroll_area, + new_font, status_bar); } #endif - - circuitpython_splash.scale = scale; } void supervisor_stop_terminal(void) { diff --git a/supervisor/shared/external_flash/common_commands.h b/supervisor/shared/external_flash/common_commands.h index 539f679d766..f2853e6b509 100644 --- a/supervisor/shared/external_flash/common_commands.h +++ b/supervisor/shared/external_flash/common_commands.h @@ -23,3 +23,4 @@ #define CMD_ENABLE_RESET 0x66 #define CMD_RESET 0x99 #define CMD_WAKE 0xab +#define CMD_GLOBAL_BLOCK_PROTECTION_UNLOCK 0x98 diff --git a/supervisor/shared/external_flash/device.h b/supervisor/shared/external_flash/device.h index 869f7b7a244..d35a84d9c32 100644 --- a/supervisor/shared/external_flash/device.h +++ b/supervisor/shared/external_flash/device.h @@ -24,8 +24,12 @@ typedef struct { // status register. uint8_t quad_enable_bit_mask; + // Device has sector-level write protection bool has_sector_protection : 1; + // Device uses global block protection lock instead of status register bits to enable sector writes + bool use_global_block_protection_lock : 1; + // Supports the 0x0b fast read command with 8 dummy cycles. bool supports_fast_read : 1; diff --git a/supervisor/shared/external_flash/devices.h.jinja b/supervisor/shared/external_flash/devices.h.jinja index 3859559d2b3..3d24b674fed 100644 --- a/supervisor/shared/external_flash/devices.h.jinja +++ b/supervisor/shared/external_flash/devices.h.jinja @@ -17,6 +17,7 @@ .max_clock_speed_mhz = {{ device.max_clock_speed_mhz }}, \ .quad_enable_bit_mask = {{ device.quad_enable_bit_mask }}, \ .has_sector_protection = {{ device.has_sector_protection | lower() }}, \ + .use_global_block_protection_lock = {{ device.use_global_block_protection_lock | lower() }}, \ .supports_fast_read = {{ device.supports_fast_read | lower() }}, \ .supports_qspi = {{ device["6b_quad_read"] | lower() }}, \ .supports_qspi_writes = {{ device["32_qspi_write"] | lower() }}, \ diff --git a/supervisor/shared/external_flash/external_flash.c b/supervisor/shared/external_flash/external_flash.c index b029286fa41..abf232c0d18 100644 --- a/supervisor/shared/external_flash/external_flash.c +++ b/supervisor/shared/external_flash/external_flash.c @@ -268,8 +268,12 @@ void supervisor_flash_init(void) { write_enable(); // Turn off sector protection - uint8_t data[1] = {0x00}; - spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, data, 1); + if (flash_device->use_global_block_protection_lock) { + spi_flash_command(CMD_GLOBAL_BLOCK_PROTECTION_UNLOCK); + } else { + uint8_t data[1] = {0x00}; + spi_flash_write_command(CMD_WRITE_STATUS_BYTE1, data, 1); + } } // Turn off writes in case this is a microcontroller only reset. diff --git a/supervisor/shared/filesystem.c b/supervisor/shared/filesystem.c index e5edb148e41..3998c304b7f 100644 --- a/supervisor/shared/filesystem.c +++ b/supervisor/shared/filesystem.c @@ -15,8 +15,17 @@ #include "supervisor/flash.h" #include "supervisor/linker.h" -static mp_vfs_mount_t _mp_vfs; -static fs_user_mount_t _internal_vfs; +#if CIRCUITPY_SDCARDIO +#include "shared-module/sdcardio/__init__.h" +#endif + +static mp_vfs_mount_t _circuitpy_vfs; +static fs_user_mount_t _circuitpy_usermount; + +#if CIRCUITPY_SAVES_PARTITION_SIZE > 0 +static mp_vfs_mount_t _saves_vfs; +static fs_user_mount_t _saves_usermount; +#endif static volatile uint32_t filesystem_flush_interval_ms = CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS; volatile bool filesystem_flush_requested = false; @@ -73,15 +82,29 @@ static void make_file_with_contents(FATFS *fatfs, const char *filename, const by // want it to be executed without using stack within main() function bool filesystem_init(bool create_allowed, bool force_create) { // init the vfs object - fs_user_mount_t *vfs_fat = &_internal_vfs; - vfs_fat->blockdev.flags = 0; - supervisor_flash_init_vfs(vfs_fat); + fs_user_mount_t *circuitpy = &_circuitpy_usermount; + circuitpy->blockdev.flags = 0; + supervisor_flash_init_vfs(circuitpy); + + #if CIRCUITPY_SAVES_PARTITION_SIZE > 0 + // SAVES is placed before CIRCUITPY so that CIRCUITPY takes up the remaining space. + circuitpy->blockdev.offset = CIRCUITPY_SAVES_PARTITION_SIZE; + circuitpy->blockdev.size = -1; + + fs_user_mount_t *saves = &_saves_usermount; + saves->blockdev.flags = 0; + saves->blockdev.offset = 0; + saves->blockdev.size = CIRCUITPY_SAVES_PARTITION_SIZE; + supervisor_flash_init_vfs(saves); + filesystem_set_concurrent_write_protection(saves, true); + filesystem_set_writable_by_usb(saves, false); + #endif - mp_vfs_mount_t *vfs = &_mp_vfs; - vfs->len = 0; + mp_vfs_mount_t *circuitpy_vfs = &_circuitpy_vfs; + circuitpy_vfs->len = 0; // try to mount the flash - FRESULT res = f_mount(&vfs_fat->fatfs); + FRESULT res = f_mount(&circuitpy->fatfs); if ((res == FR_NO_FILESYSTEM && create_allowed) || force_create) { // No filesystem so create a fresh one, or reformat has been requested. uint8_t working_buf[FF_MAX_SS]; @@ -89,7 +112,7 @@ bool filesystem_init(bool create_allowed, bool force_create) { #if FF_FS_EXFAT formats |= FM_EXFAT | FM_FAT32; #endif - res = f_mkfs(&vfs_fat->fatfs, formats, 0, working_buf, sizeof(working_buf)); + res = f_mkfs(&circuitpy->fatfs, formats, 0, working_buf, sizeof(working_buf)); if (res != FR_OK) { return false; } @@ -98,9 +121,9 @@ bool filesystem_init(bool create_allowed, bool force_create) { // set label #ifdef CIRCUITPY_DRIVE_LABEL - res = f_setlabel(&vfs_fat->fatfs, CIRCUITPY_DRIVE_LABEL); + res = f_setlabel(&circuitpy->fatfs, CIRCUITPY_DRIVE_LABEL); #else - res = f_setlabel(&vfs_fat->fatfs, "CIRCUITPY"); + res = f_setlabel(&circuitpy->fatfs, "CIRCUITPY"); #endif if (res != FR_OK) { return false; @@ -108,36 +131,55 @@ bool filesystem_init(bool create_allowed, bool force_create) { #if CIRCUITPY_USB_DEVICE // inhibit file indexing on MacOS - res = f_mkdir(&vfs_fat->fatfs, "/.fseventsd"); + res = f_mkdir(&circuitpy->fatfs, "/.fseventsd"); if (res != FR_OK) { return false; } - make_empty_file(&vfs_fat->fatfs, "/.fseventsd/no_log"); - make_empty_file(&vfs_fat->fatfs, "/.metadata_never_index"); + make_empty_file(&circuitpy->fatfs, "/.fseventsd/no_log"); + make_empty_file(&circuitpy->fatfs, "/.metadata_never_index"); // Prevent storing trash on all OSes. - make_empty_file(&vfs_fat->fatfs, "/.Trashes"); // MacOS - make_empty_file(&vfs_fat->fatfs, "/.Trash-1000"); // Linux, XDG trash spec: + make_empty_file(&circuitpy->fatfs, "/.Trashes"); // MacOS + make_empty_file(&circuitpy->fatfs, "/.Trash-1000"); // Linux, XDG trash spec: // https://specifications.freedesktop.org/trash-spec/trashspec-latest.html #endif #if CIRCUITPY_SDCARDIO || CIRCUITPY_SDIOIO - res = f_mkdir(&vfs_fat->fatfs, "/sd"); + res = f_mkdir(&circuitpy->fatfs, "/sd"); #if CIRCUITPY_FULL_BUILD - MAKE_FILE_WITH_OPTIONAL_CONTENTS(&vfs_fat->fatfs, "/sd/placeholder.txt", - "SD cards mounted at /sd will hide this file from Python." - " SD cards are not visible via USB CIRCUITPY.\n"); + MAKE_FILE_WITH_OPTIONAL_CONTENTS(&circuitpy->fatfs, "/sd/placeholder.txt", + "SD cards mounted at /sd will hide this file from Python.\n"); #endif #endif - #if CIRCUITPY_OS_GETENV - make_empty_file(&vfs_fat->fatfs, "/settings.toml"); + #if CIRCUITPY_SAVES_PARTITION_SIZE > 0 + res = f_mkfs(&saves->fatfs, formats, 0, working_buf, sizeof(working_buf)); + if (res == FR_OK) { + // Flush the new file system to make sure it's repaired immediately. + supervisor_flash_flush(); + res = f_setlabel(&saves->fatfs, "CPSAVES"); + } + + if (res == FR_OK) { + res = f_mkdir(&circuitpy->fatfs, "/saves"); + } + #if CIRCUITPY_FULL_BUILD + if (res == FR_OK) { + MAKE_FILE_WITH_OPTIONAL_CONTENTS(&circuitpy->fatfs, "/saves/placeholder.txt", + "A separate filesystem mounted at /saves will hide this file from Python." + " Saves are visible via USB CPSAVES.\n"); + } + #endif + #endif + + #if CIRCUITPY_SETTINGS_TOML + make_empty_file(&circuitpy->fatfs, "/settings.toml"); #endif // make a sample code.py file - MAKE_FILE_WITH_OPTIONAL_CONTENTS(&vfs_fat->fatfs, "/code.py", "print(\"Hello World!\")\n"); + MAKE_FILE_WITH_OPTIONAL_CONTENTS(&circuitpy->fatfs, "/code.py", "print(\"Hello World!\")\n"); // create empty lib directory - res = f_mkdir(&vfs_fat->fatfs, "/lib"); + res = f_mkdir(&circuitpy->fatfs, "/lib"); if (res != FR_OK) { return false; } @@ -148,21 +190,46 @@ bool filesystem_init(bool create_allowed, bool force_create) { return false; } - vfs->str = "/"; - vfs->len = 1; - vfs->obj = MP_OBJ_FROM_PTR(vfs_fat); - vfs->next = NULL; - - MP_STATE_VM(vfs_mount_table) = vfs; + circuitpy_vfs->str = "/"; + circuitpy_vfs->len = 1; + circuitpy_vfs->obj = MP_OBJ_FROM_PTR(circuitpy); + circuitpy_vfs->next = NULL; + + MP_STATE_VM(vfs_mount_table) = circuitpy_vfs; + + #if CIRCUITPY_SAVES_PARTITION_SIZE > 0 + res = f_mount(&saves->fatfs); + if (res == FR_OK) { + mp_vfs_mount_t *saves_vfs = &_saves_vfs; + saves_vfs->str = "/saves"; + saves_vfs->len = 6; + saves_vfs->obj = MP_OBJ_FROM_PTR(&_saves_usermount); + saves_vfs->next = MP_STATE_VM(vfs_mount_table); + MP_STATE_VM(vfs_mount_table) = saves_vfs; + } + #endif // The current directory is used as the boot up directory. // It is set to the internal flash filesystem by default. - MP_STATE_PORT(vfs_cur) = vfs; + MP_STATE_PORT(vfs_cur) = circuitpy_vfs; #if CIRCUITPY_STORAGE_EXTEND supervisor_flash_update_extended(); #endif + #if CIRCUITPY_SDCARDIO + sdcardio_init(); + #if defined(DEFAULT_SD_CARD_DETECT) && CIRCUITPY_SDCARD_USB + // Mount the SD card now so it's ready when USB enumerates. + // Lazy mount from tud_msc_test_unit_ready_cb can lose races with + // macOS's probe timing. Gated on CIRCUITPY_SDCARD_USB to match the + // existing call site in usb_msc_flash.c (guarded by SDCARD_LUN). + // automount_sd_card() itself honors the runtime CIRCUITPY_SDCARD_USB + // setting and is a no-op when it is disabled. + automount_sd_card(); + #endif + #endif + return true; } @@ -175,7 +242,7 @@ void PLACE_IN_ITCM(filesystem_flush)(void) { } void filesystem_set_internal_writable_by_usb(bool writable) { - fs_user_mount_t *vfs = &_internal_vfs; + fs_user_mount_t *vfs = &_circuitpy_usermount; filesystem_set_writable_by_usb(vfs, writable); } @@ -189,17 +256,19 @@ void filesystem_set_writable_by_usb(fs_user_mount_t *vfs, bool usb_writable) { } bool filesystem_is_writable_by_python(fs_user_mount_t *vfs) { - return (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0 || - (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) == 0; + return ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) == 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION) != 0); } bool filesystem_is_writable_by_usb(fs_user_mount_t *vfs) { - return (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0 || - (vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) != 0; + return ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_CONCURRENT_WRITE_PROTECTED) == 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_USB_WRITABLE) != 0) || + ((vfs->blockdev.flags & MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION) != 0); } void filesystem_set_internal_concurrent_write_protection(bool concurrent_write_protection) { - filesystem_set_concurrent_write_protection(&_internal_vfs, concurrent_write_protection); + filesystem_set_concurrent_write_protection(&_circuitpy_usermount, concurrent_write_protection); } void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concurrent_write_protection) { @@ -210,15 +279,23 @@ void filesystem_set_concurrent_write_protection(fs_user_mount_t *vfs, bool concu } } +void filesystem_set_ignore_write_protection(fs_user_mount_t *vfs, bool ignore_write_protection) { + if (ignore_write_protection) { + vfs->blockdev.flags |= MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION; + } else { + vfs->blockdev.flags &= ~MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION; + } +} + bool filesystem_present(void) { - return _mp_vfs.len > 0; + return _circuitpy_vfs.len > 0; } fs_user_mount_t *filesystem_circuitpy(void) { if (!filesystem_present()) { return NULL; } - return &_internal_vfs; + return &_circuitpy_usermount; } fs_user_mount_t *filesystem_for_path(const char *path_in, const char **path_under_mount) { @@ -237,7 +314,7 @@ fs_user_mount_t *filesystem_for_path(const char *path_in, const char **path_unde // because otherwise the path will be adjusted by os.getcwd() when it's looked up. if (strlen(vfs->str) != 1) { // Remove the mount point directory name, such as "/sd". - path_under_mount += strlen(vfs->str); + *path_under_mount += strlen(vfs->str); } } return fs_mount; @@ -252,12 +329,23 @@ bool filesystem_lock(fs_user_mount_t *fs_mount) { return false; } fs_mount->lock_count += 1; + // CIRCUITPY-CHANGE: while a non-USB-MSC writer (BLE file transfer, web + // workflow, storage.remount) holds the filesystem lock, allow the + // FatFS f_open(FA_WRITE) path to bypass STA_PROTECT. Without this, the + // disk_ioctl(IOCTL_STATUS) -> filesystem_is_writable_by_python() check + // added by #10659 always sets STA_PROTECT on USB-device-capable boards, + // so even after the lock is held, f_open returns FR_WRITE_PROTECTED. + // USB MSC takes the lock via blockdev_lock() directly, NOT via + // filesystem_lock(), so this flag is never set on its behalf. + fs_mount->blockdev.flags |= MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION; return true; } void filesystem_unlock(fs_user_mount_t *fs_mount) { fs_mount->lock_count -= 1; if (fs_mount->lock_count == 0) { + // CIRCUITPY-CHANGE: clear the bypass when releasing the lock. + fs_mount->blockdev.flags &= ~MP_BLOCKDEV_FLAG_IGNORE_WRITE_PROTECTION; blockdev_unlock(fs_mount); } } diff --git a/supervisor/shared/flash.c b/supervisor/shared/flash.c index 37fba60ae8b..ccb60efe321 100644 --- a/supervisor/shared/flash.c +++ b/supervisor/shared/flash.c @@ -7,6 +7,7 @@ #include "extmod/vfs_fat.h" #include "py/runtime.h" +#include "lib/oofatfs/diskio.h" #include "lib/oofatfs/ff.h" #include "supervisor/flash.h" #include "supervisor/shared/tick.h" @@ -27,9 +28,54 @@ static mp_obj_t supervisor_flash_obj_make_new(const mp_obj_type_t *type, size_t return (mp_obj_t)&supervisor_flash_obj; } -static uint32_t flash_get_block_count(void) { - return PART1_START_BLOCK + supervisor_flash_get_block_count(); + +static bool flash_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value) { + if (out_value != NULL) { + *out_value = 0; + } + + mp_vfs_blockdev_t *self = (mp_vfs_blockdev_t *)self_in; + switch (cmd) { + case MP_BLOCKDEV_IOCTL_INIT: + supervisor_flash_init(); + break; + case MP_BLOCKDEV_IOCTL_DEINIT: + supervisor_flash_flush(); + break; // TODO properly + case MP_BLOCKDEV_IOCTL_SYNC: + supervisor_flash_flush(); + break; + case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: + *out_value = PART1_START_BLOCK; + #if CIRCUITPY_SAVES_PARTITION_SIZE > 0 + if (self->size > 0) { + *out_value += self->size / self->block_size; + } else { + *out_value += supervisor_flash_get_block_count() - (self->offset / self->block_size); + } + #else + *out_value += supervisor_flash_get_block_count(); + #endif + break; + case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: + *out_value = self->block_size; + break; + default: + return false; + } + return true; +} + +static mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { + mp_int_t cmd = mp_obj_get_int(cmd_in); + mp_int_t arg = mp_obj_get_int(arg_in); + mp_int_t out_value; + if (flash_ioctl(self, cmd, arg, &out_value)) { + return MP_OBJ_NEW_SMALL_INT(out_value); + } + return mp_const_none; } +static MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_ioctl_obj, supervisor_flash_obj_ioctl); static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_block, uint32_t num_blocks) { buf[0] = boot; @@ -67,7 +113,7 @@ static void build_partition(uint8_t *buf, int boot, int type, uint32_t start_blo buf[15] = num_blocks >> 24; } -static mp_uint_t flash_read_blocks(mp_obj_t self, uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { +static mp_uint_t flash_read_blocks(mp_obj_t self_in, uint8_t *dest, uint32_t block_num, uint32_t num_blocks) { if (block_num == 0) { // fake the MBR so we can decide on our own partition table @@ -75,8 +121,11 @@ static mp_uint_t flash_read_blocks(mp_obj_t self, uint8_t *dest, uint32_t block_ dest[i] = 0; } + mp_int_t block_count; + flash_ioctl(self_in, MP_BLOCKDEV_IOCTL_BLOCK_COUNT, 0, &block_count); + // Specifying "Big FAT12/16 CHS" allows mounting by Android - build_partition(dest + 446, 0, 0x06 /* Big FAT12/16 CHS */, PART1_START_BLOCK, supervisor_flash_get_block_count()); + build_partition(dest + 446, 0, 0x06 /* Big FAT12/16 CHS */, PART1_START_BLOCK, block_count - PART1_START_BLOCK); build_partition(dest + 462, 0, 0, 0, 0); build_partition(dest + 478, 0, 0, 0, 0); build_partition(dest + 494, 0, 0, 0, 0); @@ -92,12 +141,17 @@ static mp_uint_t flash_read_blocks(mp_obj_t self, uint8_t *dest, uint32_t block_ return 0; // Done and ok. } } - return supervisor_flash_read_blocks(dest, block_num - PART1_START_BLOCK, num_blocks); + block_num -= PART1_START_BLOCK; + #if CIRCUITPY_SAVES_PARTITION_SIZE > 0 + mp_vfs_blockdev_t *self = (mp_vfs_blockdev_t *)self_in; + block_num += self->offset / self->block_size; + #endif + return supervisor_flash_read_blocks(dest, block_num, num_blocks); } static volatile bool filesystem_dirty = false; -static mp_uint_t flash_write_blocks(mp_obj_t self, const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { +static mp_uint_t flash_write_blocks(mp_obj_t self_in, const uint8_t *src, uint32_t block_num, uint32_t num_blocks) { if (block_num == 0) { if (num_blocks > 1) { return 1; // error @@ -110,7 +164,12 @@ static mp_uint_t flash_write_blocks(mp_obj_t self, const uint8_t *src, uint32_t supervisor_enable_tick(); filesystem_dirty = true; } - return supervisor_flash_write_blocks(src, block_num - PART1_START_BLOCK, num_blocks); + block_num -= PART1_START_BLOCK; + #if CIRCUITPY_SAVES_PARTITION_SIZE > 0 + mp_vfs_blockdev_t *self = (mp_vfs_blockdev_t *)self_in; + block_num += self->offset / self->block_size; + #endif + return supervisor_flash_write_blocks(src, block_num, num_blocks); } } @@ -143,43 +202,6 @@ static mp_obj_t supervisor_flash_obj_writeblocks(mp_obj_t self, mp_obj_t block_n } static MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_writeblocks_obj, supervisor_flash_obj_writeblocks); -static bool flash_ioctl(mp_obj_t self_in, size_t cmd, size_t arg, mp_int_t *out_value) { - if (out_value != NULL) { - *out_value = 0; - } - switch (cmd) { - case MP_BLOCKDEV_IOCTL_INIT: - supervisor_flash_init(); - break; - case MP_BLOCKDEV_IOCTL_DEINIT: - supervisor_flash_flush(); - break; // TODO properly - case MP_BLOCKDEV_IOCTL_SYNC: - supervisor_flash_flush(); - break; - case MP_BLOCKDEV_IOCTL_BLOCK_COUNT: - *out_value = flash_get_block_count(); - break; - case MP_BLOCKDEV_IOCTL_BLOCK_SIZE: - *out_value = supervisor_flash_get_block_size(); - break; - default: - return false; - } - return true; -} - -static mp_obj_t supervisor_flash_obj_ioctl(mp_obj_t self, mp_obj_t cmd_in, mp_obj_t arg_in) { - mp_int_t cmd = mp_obj_get_int(cmd_in); - mp_int_t arg = mp_obj_get_int(arg_in); - mp_int_t out_value; - if (flash_ioctl(self, cmd, arg, &out_value)) { - return MP_OBJ_NEW_SMALL_INT(out_value); - } - return mp_const_none; -} -static MP_DEFINE_CONST_FUN_OBJ_3(supervisor_flash_obj_ioctl_obj, supervisor_flash_obj_ioctl); - static const mp_rom_map_elem_t supervisor_flash_obj_locals_dict_table[] = { { MP_ROM_QSTR(MP_QSTR_readblocks), MP_ROM_PTR(&supervisor_flash_obj_readblocks_obj) }, { MP_ROM_QSTR(MP_QSTR_writeblocks), MP_ROM_PTR(&supervisor_flash_obj_writeblocks_obj) }, @@ -199,15 +221,16 @@ MP_DEFINE_CONST_OBJ_TYPE( void supervisor_flash_init_vfs(fs_user_mount_t *vfs) { vfs->base.type = &mp_fat_vfs_type; vfs->blockdev.flags |= MP_BLOCKDEV_FLAG_NATIVE | MP_BLOCKDEV_FLAG_HAVE_IOCTL; + vfs->blockdev.block_size = supervisor_flash_get_block_size(); vfs->fatfs.drv = vfs; vfs->fatfs.part = 1; // flash filesystem lives on first fake partition - vfs->blockdev.readblocks[0] = (mp_obj_t)&supervisor_flash_obj_readblocks_obj; - vfs->blockdev.readblocks[1] = (mp_obj_t)&supervisor_flash_obj; + vfs->blockdev.readblocks[0] = mp_const_none; + vfs->blockdev.readblocks[1] = (mp_obj_t)&vfs->blockdev; vfs->blockdev.readblocks[2] = (mp_obj_t)flash_read_blocks; // native version - vfs->blockdev.writeblocks[0] = (mp_obj_t)&supervisor_flash_obj_writeblocks_obj; - vfs->blockdev.writeblocks[1] = (mp_obj_t)&supervisor_flash_obj; + vfs->blockdev.writeblocks[0] = mp_const_none; + vfs->blockdev.writeblocks[1] = (mp_obj_t)&vfs->blockdev; vfs->blockdev.writeblocks[2] = (mp_obj_t)flash_write_blocks; // native version - vfs->blockdev.u.ioctl[0] = (mp_obj_t)&supervisor_flash_obj_ioctl_obj; - vfs->blockdev.u.ioctl[1] = (mp_obj_t)&supervisor_flash_obj; + vfs->blockdev.u.ioctl[0] = mp_const_none; + vfs->blockdev.u.ioctl[1] = (mp_obj_t)&vfs->blockdev; vfs->blockdev.u.ioctl[2] = (mp_obj_t)flash_ioctl; // native version } diff --git a/supervisor/shared/port.c b/supervisor/shared/port.c index 72bb45b8a27..15b0751c757 100644 --- a/supervisor/shared/port.c +++ b/supervisor/shared/port.c @@ -8,19 +8,33 @@ #include +#include "py/mphal.h" #include "py/runtime.h" +#include "py/gc.h" #include "lib/tlsf/tlsf.h" +#ifdef CIRCUITPY_BOOT_BUTTON +#include "shared-bindings/digitalio/DigitalInOut.h" +#include "shared-bindings/time/__init__.h" +#endif + static tlsf_t heap; +MP_WEAK void reset_port_early(void) { +} + MP_WEAK void port_wake_main_task(void) { } MP_WEAK void port_wake_main_task_from_isr(void) { } -MP_WEAK void port_yield(void) { +MP_WEAK void port_task_yield(void) { +} + +MP_WEAK void port_task_sleep_ms(uint32_t msecs) { + mp_hal_delay_ms(msecs); } MP_WEAK void port_boot_info(void) { @@ -38,11 +52,36 @@ MP_WEAK void *port_malloc(size_t size, bool dma_capable) { return block; } +// Ensure allocated memory is zero. +MP_WEAK void *port_malloc_zero(size_t size, bool dma_capable) { + void *ptr = port_malloc(size, dma_capable); + if (ptr) { + memset(ptr, 0, size); + } + return ptr; +} + MP_WEAK void port_free(void *ptr) { tlsf_free(heap, ptr); } -MP_WEAK void *port_realloc(void *ptr, size_t size) { +// Safely free an object that may have been allocated from either the GC heap or port heap. +// If the pointer is on the GC heap, it will be freed by the GC automatically, so we do nothing. +// If the pointer is not on the GC heap (i.e., allocated with port_malloc), we free it with port_free. +// This is safe to call during shutdown when GC may not be available. +void circuitpy_free_obj(mp_obj_t obj) { + if (obj == mp_const_none) { + return; + } + void *ptr = MP_OBJ_TO_PTR(obj); + if (gc_alloc_possible() && gc_ptr_on_heap(ptr)) { + gc_free(ptr); + } else { + port_free(ptr); + } +} + +MP_WEAK void *port_realloc(void *ptr, size_t size, bool dma_capable) { return tlsf_realloc(heap, ptr, size); } @@ -60,3 +99,45 @@ MP_WEAK size_t port_heap_get_largest_free_size(void) { // IDF does this. Not sure why. return tlsf_fit_size(heap, max_size); } + +MP_WEAK bool port_boot_button_pressed(void) { + #if defined(CIRCUITPY_BOOT_BUTTON) + // Init/deinit the boot button every time in case it is used for LEDs. + digitalio_digitalinout_obj_t boot_button; + common_hal_digitalio_digitalinout_construct(&boot_button, CIRCUITPY_BOOT_BUTTON); + common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP); + common_hal_time_delay_ms(1); + bool button_pressed = !common_hal_digitalio_digitalinout_get_value(&boot_button); + common_hal_digitalio_digitalinout_deinit(&boot_button); + return button_pressed; + #else + return false; + #endif +} + +// Ports may provide an implementation of this function if it is needed +MP_WEAK void port_gc_collect(void) { +} + +// Allocates an object in the port heap, not the VM heap, and also sets type, for mp_obj_malloc{,_var} macros. +MP_NOINLINE void *mp_obj_port_malloc_helper(size_t num_bytes, const mp_obj_type_t *type) { + mp_obj_base_t *base = (mp_obj_base_t *)port_malloc_zero(num_bytes, false); + base->type = type; + return base; +} + +// Creates a tuple on the port heap, not the VM heap. +// Implementation copied from py/objtuple.c. +mp_obj_t mp_obj_new_port_tuple(size_t n, const mp_obj_t *items) { + if (n == 0) { + return mp_const_empty_tuple; + } + mp_obj_tuple_t *o = mp_obj_port_malloc_var(mp_obj_tuple_t, items, mp_obj_t, n, &mp_type_tuple); + o->len = n; + if (items) { + for (size_t i = 0; i < n; i++) { + o->items[i] = items[i]; + } + } + return MP_OBJ_FROM_PTR(o); +} diff --git a/supervisor/shared/reload.c b/supervisor/shared/reload.c index fb7ff0403c2..862c4ccebc7 100644 --- a/supervisor/shared/reload.c +++ b/supervisor/shared/reload.c @@ -35,16 +35,16 @@ void reload_initiate(supervisor_run_reason_t run_reason) { port_wake_main_task(); } -void autoreload_reset() { +void autoreload_reset(void) { last_autoreload_trigger = 0; } -void autoreload_enable() { +void autoreload_enable(void) { autoreload_enabled = true; last_autoreload_trigger = 0; } -void autoreload_disable() { +void autoreload_disable(void) { autoreload_enabled = false; } @@ -56,11 +56,11 @@ void autoreload_resume(uint32_t suspend_reason_mask) { autoreload_suspended &= ~suspend_reason_mask; } -inline bool autoreload_is_enabled() { +inline bool autoreload_is_enabled(void) { return autoreload_enabled; } -void autoreload_trigger() { +void autoreload_trigger(void) { if (!autoreload_enabled || autoreload_suspended != 0) { return; } @@ -78,7 +78,7 @@ void autoreload_trigger() { } } -bool autoreload_ready() { +bool autoreload_ready(void) { if (last_autoreload_trigger == 0 || autoreload_suspended != 0) { return false; } diff --git a/supervisor/shared/safe_mode.c b/supervisor/shared/safe_mode.c index 30e5a23729b..fade06db596 100644 --- a/supervisor/shared/safe_mode.c +++ b/supervisor/shared/safe_mode.c @@ -8,10 +8,6 @@ #include "mphalport.h" -#if defined(CIRCUITPY_BOOT_BUTTON) -#include "shared-bindings/digitalio/DigitalInOut.h" -#include "shared-bindings/time/__init__.h" -#endif #include "shared-bindings/microcontroller/Processor.h" #include "shared-bindings/microcontroller/ResetReason.h" @@ -22,6 +18,14 @@ #include "supervisor/shared/translate/translate.h" #include "supervisor/shared/tick.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" +#endif + +#ifdef __ZEPHYR__ +#include +#endif + #define SAFE_MODE_DATA_GUARD 0xad0000af #define SAFE_MODE_DATA_GUARD_MASK 0xff0000ff @@ -50,10 +54,10 @@ safe_mode_t wait_for_safe_mode_reset(void) { } const mcu_reset_reason_t reset_reason = common_hal_mcu_processor_get_reset_reason(); - if (reset_reason != RESET_REASON_POWER_ON && - reset_reason != RESET_REASON_RESET_PIN && - reset_reason != RESET_REASON_UNKNOWN && - reset_reason != RESET_REASON_SOFTWARE) { + // Skip safe-mode wait if the reset reason was due to a problem. + if (reset_reason == MCU_RESET_REASON_BROWNOUT || + reset_reason == MCU_RESET_REASON_WATCHDOG || + reset_reason == MCU_RESET_REASON_RESCUE_DEBUG) { return SAFE_MODE_NONE; } #if CIRCUITPY_SKIP_SAFE_MODE_WAIT @@ -65,11 +69,23 @@ safe_mode_t wait_for_safe_mode_reset(void) { #if CIRCUITPY_STATUS_LED status_led_init(); #endif + + uint32_t safe_mode_delay_msecs = 1000; + + #if CIRCUITPY_SETTINGS_TOML + mp_float_t safe_mode_delay_secs = 1.0f; + // Will update delay_secs if setting is present. + settings_get_float("CIRCUITPY_SAFE_MODE_DELAY", &safe_mode_delay_secs); + if (safe_mode_delay_secs >= 0.0f && safe_mode_delay_secs <= (mp_float_t)UINT32_MAX) { + safe_mode_delay_msecs = safe_mode_delay_secs * 1000; + } + #endif + uint64_t start_ticks = supervisor_ticks_ms64(); uint64_t diff = 0; bool boot_in_safe_mode = false; - while (diff < 1000) { - #ifdef CIRCUITPY_STATUS_LED + while (diff < safe_mode_delay_msecs) { + #if CIRCUITPY_STATUS_LED // Blink on for 100, off for 100 bool led_on = (diff % 250) < 125; if (led_on) { @@ -78,19 +94,10 @@ safe_mode_t wait_for_safe_mode_reset(void) { new_status_color(BLACK); } #endif - // Init the boot button every time in case it is used for LEDs. - #ifdef CIRCUITPY_BOOT_BUTTON - digitalio_digitalinout_obj_t boot_button; - common_hal_digitalio_digitalinout_construct(&boot_button, CIRCUITPY_BOOT_BUTTON); - common_hal_digitalio_digitalinout_switch_to_input(&boot_button, PULL_UP); - common_hal_time_delay_ms(1); - bool button_pressed = !common_hal_digitalio_digitalinout_get_value(&boot_button); - common_hal_digitalio_digitalinout_deinit(&boot_button); - if (button_pressed) { + if (port_boot_button_pressed()) { boot_in_safe_mode = true; break; } - #endif diff = supervisor_ticks_ms64() - start_ticks; } #if CIRCUITPY_STATUS_LED @@ -112,10 +119,19 @@ void PLACE_IN_ITCM(safe_mode_on_next_reset)(safe_mode_t reason) { // Don't inline this so it's easy to break on it from GDB. void __attribute__((noinline, )) PLACE_IN_ITCM(reset_into_safe_mode)(safe_mode_t reason) { if (_safe_mode > SAFE_MODE_BROWNOUT && reason > SAFE_MODE_BROWNOUT) { + #ifdef __ZEPHYR__ + printk("Already in safe mode\n"); + printk("Reason: %d\n", reason); + printk("Current safe mode: %d\n", _safe_mode); + while (true) { + k_cpu_idle(); + } + #else while (true) { // This very bad because it means running in safe mode didn't save us. Only ignore brownout // because it may be due to a switch bouncing. } + #endif } safe_mode_on_next_reset(reason); @@ -142,7 +158,7 @@ void print_safe_mode_message(safe_mode_t reason) { case SAFE_MODE_USER: #if defined(BOARD_USER_SAFE_MODE_ACTION) message = BOARD_USER_SAFE_MODE_ACTION; - #elif defined(CIRCUITPY_BOOT_BUTTON) + #elif defined(CIRCUITPY_BOOT_BUTTON) || CIRCUITPY_BOOT_BUTTON_NO_GPIO message = MP_ERROR_TEXT("You pressed the BOOT button at start up"); #else message = MP_ERROR_TEXT("You pressed the reset button during boot."); diff --git a/supervisor/shared/safe_mode.h b/supervisor/shared/safe_mode.h index 8f4037cbe20..87f65d867ea 100644 --- a/supervisor/shared/safe_mode.h +++ b/supervisor/shared/safe_mode.h @@ -38,6 +38,6 @@ void set_safe_mode(safe_mode_t safe_mode); safe_mode_t wait_for_safe_mode_reset(void); void safe_mode_on_next_reset(safe_mode_t reason); -void reset_into_safe_mode(safe_mode_t reason) NORETURN; +void reset_into_safe_mode(safe_mode_t reason) MP_NORETURN; void print_safe_mode_message(safe_mode_t reason); diff --git a/supervisor/shared/serial.c b/supervisor/shared/serial.c index fce066f70de..1bfb8d73b3c 100644 --- a/supervisor/shared/serial.c +++ b/supervisor/shared/serial.c @@ -9,6 +9,7 @@ #include "py/mpconfig.h" #include "py/mphal.h" +#include "py/mpprint.h" #include "supervisor/shared/cpu.h" #include "supervisor/shared/display.h" @@ -16,7 +17,7 @@ #include "supervisor/shared/serial.h" #include "shared-bindings/microcontroller/Pin.h" -#if CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_BLE_SERIAL_SERVICE #include "supervisor/shared/bluetooth/serial.h" #endif @@ -34,7 +35,6 @@ #endif #if CIRCUITPY_CONSOLE_UART -#include "py/mpprint.h" #include "shared-bindings/busio/UART.h" busio_uart_obj_t console_uart; @@ -63,33 +63,94 @@ static bool _serial_console_write_disabled; // Set to true to temporarily discard writes to the display terminal only. static bool _serial_display_write_disabled; +// Indicates that serial console has been early initialized. +static bool _serial_console_early_inited = false; + #if CIRCUITPY_CONSOLE_UART -static void console_uart_print_strn(void *env, const char *str, size_t len) { + +// All output to the console uart comes through this inner write function. It ensures that all +// lines are terminated with a "cooked" '\r\n' sequence. Lines that are already cooked are sent +// on unchanged. +static void inner_console_uart_write_cb(void *env, const char *str, size_t len) { (void)env; int uart_errcode; - common_hal_busio_uart_write(&console_uart, (const uint8_t *)str, len, &uart_errcode); + bool last_cr = false; + while (len > 0) { + size_t i = 0; + if (str[0] == '\n' && !last_cr) { + common_hal_busio_uart_write(&console_uart, (const uint8_t *)"\r", 1, &uart_errcode); + i = 1; + } + // Lump all characters on the next line together. + while ((last_cr || str[i] != '\n') && i < len) { + last_cr = str[i] == '\r'; + i++; + } + common_hal_busio_uart_write(&console_uart, (const uint8_t *)str, i, &uart_errcode); + str = &str[i]; + len -= i; + } } -const mp_print_t console_uart_print = {NULL, console_uart_print_strn}; +#if CIRCUITPY_CONSOLE_UART_TIMESTAMP +static const mp_print_t inner_console_uart_write = {NULL, inner_console_uart_write_cb}; +static uint32_t console_uart_write_prev_time = 0; +static bool console_uart_write_prev_nl = true; + +static inline void console_uart_write_timestamp(void) { + uint32_t now = supervisor_ticks_ms32(); + uint32_t delta = now - console_uart_write_prev_time; + console_uart_write_prev_time = now; + mp_printf(&inner_console_uart_write, + "%01lu.%03lu(%01lu.%03lu): ", + now / 1000, now % 1000, delta / 1000, delta % 1000); +} #endif -int console_uart_printf(const char *fmt, ...) { - #if CIRCUITPY_CONSOLE_UART - // Skip prints that occur before console serial is started. It's better than - // crashing. - if (common_hal_busio_uart_deinited(&console_uart)) { - return 0; +static size_t console_uart_write(const char *str, size_t len) { + // Ignore writes if console uart is not yet initialized. + if (!_serial_console_early_inited) { + return len; } - va_list ap; - va_start(ap, fmt); - int ret = mp_vprintf(&console_uart_print, fmt, ap); - va_end(ap); - return ret; - #else - return 0; - #endif + + if (!_first_write_done) { + mp_hal_delay_ms(50); + _first_write_done = true; + } + + // There may be multiple newlines in the string, split at newlines. + int remaining_len = len; + while (remaining_len > 0) { + #if CIRCUITPY_CONSOLE_UART_TIMESTAMP + if (console_uart_write_prev_nl) { + console_uart_write_timestamp(); + console_uart_write_prev_nl = false; + } + #endif + int print_len = 0; + while (print_len < remaining_len) { + if (str[print_len++] == '\n') { + #if CIRCUITPY_CONSOLE_UART_TIMESTAMP + console_uart_write_prev_nl = true; + #endif + break; + } + } + inner_console_uart_write_cb(NULL, str, print_len); + str += print_len; + remaining_len -= print_len; + } + return len; +} + +static void console_uart_write_cb(void *env, const char *str, size_t len) { + (void)env; + console_uart_write(str, len); } +const mp_print_t console_uart_print = {NULL, console_uart_write_cb}; +#endif + MP_WEAK void board_serial_early_init(void) { } @@ -113,33 +174,15 @@ MP_WEAK void board_serial_write_substring(const char *text, uint32_t length) { (void)length; } -MP_WEAK void port_serial_early_init(void) { -} - -MP_WEAK void port_serial_init(void) { -} - -MP_WEAK bool port_serial_connected(void) { - return false; -} - -MP_WEAK char port_serial_read(void) { - return -1; -} - -MP_WEAK uint32_t port_serial_bytes_available(void) { - return 0; -} - -MP_WEAK void port_serial_write_substring(const char *text, uint32_t length) { - (void)text; - (void)length; -} - void serial_early_init(void) { - // Set up console UART, if enabled. + // Ignore duplicate calls to initialize allowing port-specific code to + // call this function early. + if (_serial_console_early_inited) { + return; + } #if CIRCUITPY_CONSOLE_UART + // Set up console UART, if enabled. console_uart.base.type = &busio_uart_type; const mcu_pin_obj_t *console_rx = MP_OBJ_TO_PTR(CIRCUITPY_CONSOLE_UART_RX); @@ -149,13 +192,18 @@ void serial_early_init(void) { false, CIRCUITPY_CONSOLE_UART_BAUDRATE, 8, BUSIO_UART_PARITY_NONE, 1, 1.0f, sizeof(console_uart_rx_buf), console_uart_rx_buf, true); common_hal_busio_uart_never_reset(&console_uart); - - // Do an initial print so that we can confirm the serial output is working. - console_uart_printf("Serial console setup\r\n"); #endif board_serial_early_init(); + + #if CIRCUITPY_PORT_SERIAL port_serial_early_init(); + #endif + + _serial_console_early_inited = true; + + // Do an initial print so that we can confirm the serial output is working. + CIRCUITPY_CONSOLE_UART_PRINTF("Serial console setup\n"); } void serial_init(void) { @@ -164,11 +212,14 @@ void serial_init(void) { #endif board_serial_init(); + + #if CIRCUITPY_PORT_SERIAL port_serial_init(); + #endif } bool serial_connected(void) { - #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected()) { return true; } @@ -178,17 +229,17 @@ bool serial_connected(void) { return true; #endif - #if CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE if (ble_serial_connected()) { return true; } #endif - #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (usb_cdc_console_enabled() && tud_cdc_connected()) { return true; } - #elif CIRCUITPY_USB_DEVICE + #elif CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE if (tud_cdc_connected()) { return true; } @@ -211,15 +262,18 @@ bool serial_connected(void) { return true; } + + #if CIRCUITPY_PORT_SERIAL if (port_serial_connected()) { return true; } + #endif return false; } char serial_read(void) { - #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected() && tud_vendor_available() > 0) { char tiny_buffer; tud_vendor_read(&tiny_buffer, 1); @@ -236,7 +290,7 @@ char serial_read(void) { } #endif - #if CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE if (ble_serial_available() > 0) { return ble_serial_read_char(); } @@ -244,7 +298,7 @@ char serial_read(void) { #if CIRCUITPY_WEB_WORKFLOW if (websocket_available()) { - char c = websocket_read_char(); + int c = websocket_read_char(); if (c != -1) { return c; } @@ -261,16 +315,19 @@ char serial_read(void) { return board_serial_read(); } + + #if CIRCUITPY_PORT_SERIAL if (port_serial_bytes_available() > 0) { return port_serial_read(); } + #endif #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (!usb_cdc_console_enabled()) { return -1; } #endif - #if CIRCUITPY_USB_DEVICE + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE return (char)tud_cdc_read_char(); #endif @@ -281,7 +338,7 @@ uint32_t serial_bytes_available(void) { // There may be multiple serial input channels, so sum the count from all. uint32_t count = 0; - #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected()) { count += tud_vendor_available(); } @@ -291,7 +348,7 @@ uint32_t serial_bytes_available(void) { count += common_hal_busio_uart_rx_characters_available(&console_uart); #endif - #if CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE count += ble_serial_available(); #endif @@ -303,7 +360,7 @@ uint32_t serial_bytes_available(void) { count += usb_keyboard_chars_available(); #endif - #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC if (usb_cdc_console_enabled()) { count += tud_cdc_available(); } @@ -312,8 +369,10 @@ uint32_t serial_bytes_available(void) { // Board-specific serial input. count += board_serial_bytes_available(); + #if CIRCUITPY_PORT_SERIAL // Port-specific serial input. count += port_serial_bytes_available(); + #endif return count; } @@ -340,22 +399,17 @@ uint32_t serial_write_substring(const char *text, uint32_t length) { return length_sent; } - #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VENDOR if (tud_vendor_connected()) { length_sent = tud_vendor_write(text, length); } #endif #if CIRCUITPY_CONSOLE_UART - if (!_first_write_done) { - mp_hal_delay_ms(50); - _first_write_done = true; - } - int uart_errcode; - length_sent = common_hal_busio_uart_write(&console_uart, (const uint8_t *)text, length, &uart_errcode); + length_sent = console_uart_write(text, length); #endif - #if CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE ble_serial_write(text, length); #endif @@ -369,7 +423,7 @@ uint32_t serial_write_substring(const char *text, uint32_t length) { } #endif - #if CIRCUITPY_USB_DEVICE + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE // Delay the very first write if (tud_cdc_connected() && !_first_write_done) { mp_hal_delay_ms(50); @@ -389,7 +443,10 @@ uint32_t serial_write_substring(const char *text, uint32_t length) { #endif board_serial_write_substring(text, length); + + #if CIRCUITPY_PORT_SERIAL port_serial_write_substring(text, length); + #endif return length_sent; } @@ -409,3 +466,73 @@ bool serial_display_write_disable(bool disabled) { _serial_display_write_disabled = disabled; return now; } + +// A general purpose hex/ascii dump function for arbitrary area of memory. +void print_hexdump(const mp_print_t *printer, const char *prefix, const uint8_t *buf, size_t len) { + size_t i; + for (i = 0; i < len; ++i) { + // print hex digit + if (i % 32 == 0) { + mp_printf(printer, "%s0x%04x:", prefix, i); + } + if (i % 32 == 16) { + mp_printf(printer, " : "); + } else if (i % 4 == 0) { + mp_printf(printer, " "); + } + mp_printf(printer, "%02x", buf[i]); + // print ascii chars for this line + if (i % 32 == 31) { + size_t k = i - 31; + mp_printf(printer, " : "); + for (size_t j = 0; j < 32; ++j) { + if (j == 16) { + mp_printf(printer, " "); + } + if (buf[k + j] >= 32 && buf[k + j] < 127) { + mp_printf(printer, "%c", buf[k + j]); + } else { + mp_printf(printer, "."); + } + } + mp_printf(printer, "\n"); + } + } + if (i % 32 != 0) { + // For a final line of less than 32 bytes, pad with spaces + i -= i % 32; + for (size_t j = len % 32; j < 32; ++j) { + if (j % 32 == 16) { + mp_printf(printer, " "); + } else if (j % 4 == 0) { + mp_printf(printer, " "); + } + mp_printf(printer, " "); + } + // Print ascii chars for the last line fragment + mp_printf(printer, " : "); + for (size_t j = 0; j < len % 32; ++j) { + if (j == 16) { + mp_printf(printer, " "); + } + if (buf[i + j] >= 32 && buf[i + j] < 127) { + mp_printf(printer, "%c", buf[i + j]); + } else { + mp_printf(printer, "."); + } + } + mp_printf(printer, "\n"); + } +} + +int console_uart_printf(const char *fmt, ...) { + #if CIRCUITPY_CONSOLE_UART + va_list args; + va_start(args, fmt); + int ret = mp_vprintf(&console_uart_print, fmt, args); + va_end(args); + return ret; + #else + return 0; + #endif +} diff --git a/supervisor/shared/serial.h b/supervisor/shared/serial.h index ea0f147cc49..d64a316ff32 100644 --- a/supervisor/shared/serial.h +++ b/supervisor/shared/serial.h @@ -11,6 +11,7 @@ #include #include "py/mpconfig.h" +#include "py/mpprint.h" #ifdef CIRCUITPY_BOOT_OUTPUT_FILE #include "py/misc.h" @@ -47,4 +48,8 @@ char board_serial_read(void); uint32_t board_serial_bytes_available(void); void board_serial_write_substring(const char *text, uint32_t length); -int console_uart_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2))); +extern const mp_print_t console_uart_print; + +int console_uart_printf(const char *fmt, ...); + +void print_hexdump(const mp_print_t *printer, const char *prefix, const uint8_t *buf, size_t len); diff --git a/supervisor/shared/settings.c b/supervisor/shared/settings.c new file mode 100644 index 00000000000..1414195411e --- /dev/null +++ b/supervisor/shared/settings.c @@ -0,0 +1,525 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries +// SPDX-FileCopyrightText: Copyright (c) 2026 Dan Halbert for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include +#include +#include +#include + +#include "py/gc.h" +#include "py/misc.h" +#include "py/mpstate.h" +#include "py/mpprint.h" +#include "py/objstr.h" +#include "py/parsenum.h" +#include "py/runtime.h" +#include "supervisor/filesystem.h" +#include "supervisor/shared/settings.h" + +#define SETTINGS_PATH "/settings.toml" + +#include "extmod/vfs.h" +#include "extmod/vfs_fat.h" + +#if CIRCUITPY_SETTINGS_TOML +typedef FIL file_arg; +static bool open_file(const char *name, file_arg *file_handle) { + #if defined(UNIX) + nlr_buf_t nlr; + if (nlr_push(&nlr) == 0) { + mp_obj_t file_obj = mp_call_function_2( + MP_OBJ_FROM_PTR(&mp_builtin_open_obj), mp_obj_new_str(name, strlen(name)), MP_ROM_QSTR(MP_QSTR_rb)); + mp_arg_validate_type(file_obj, &mp_type_vfs_fat_fileio, MP_QSTR_file); + pyb_file_obj_t *file = MP_OBJ_TO_PTR(file_obj); + *file_handle = file->fp; + nlr_pop(); + return true; + } else { + return false; + } + #else + fs_user_mount_t *fs_mount = filesystem_circuitpy(); + if (fs_mount == NULL) { + return false; + } + FATFS *fatfs = &fs_mount->fatfs; + FRESULT result = f_open(fatfs, file_handle, name, FA_READ); + return result == FR_OK; + #endif +} + +static void close_file(file_arg *file_handle) { + f_close(file_handle); +} + +static bool is_eof(file_arg *file_handle) { + return f_eof(file_handle) || f_error(file_handle); +} + +// Return 0 if there is no next character (EOF). +static uint8_t get_next_byte(FIL *file_handle) { + uint8_t character = 0; + UINT quantity_read; + // If there's an error or quantity_read is 0, character will remain 0. + f_read(file_handle, &character, 1, &quantity_read); + return character; +} + +static void seek_eof(file_arg *file_handle) { + f_lseek(file_handle, f_size(file_handle)); +} + +// For a fixed buffer, record the required size rather than throwing +static void vstr_add_byte_nonstd(vstr_t *vstr, byte b) { + if (!vstr->fixed_buf || vstr->alloc > vstr->len) { + vstr_add_byte(vstr, b); + } else { + vstr->len++; + } +} + +// For a fixed buffer, record the required size rather than throwing +static void vstr_add_char_nonstd(vstr_t *vstr, unichar c) { + size_t ulen = + (c < 0x80) ? 1 : + (c < 0x800) ? 2 : + (c < 0x10000) ? 3 : 4; + if (!vstr->fixed_buf || vstr->alloc > vstr->len + ulen) { + vstr_add_char(vstr, c); + } else { + vstr->len += ulen; + } +} + +static void next_line(file_arg *file_handle) { + uint8_t character; + do { + character = get_next_byte(file_handle); + } while (character != 0 && character != '\n'); +} + +// Discard whitespace, except for newlines, returning the next character after the whitespace. +// Return 0 if there is no next character (EOF). +static uint8_t consume_whitespace(file_arg *file_handle) { + uint8_t character; + do { + character = get_next_byte(file_handle); + } while (character != '\n' && character != 0 && unichar_isspace(character)); + return character; +} + +// Starting at the start of a new line, determines if the key matches the given key. +// +// If result is true, the key matches and file pointer is pointing just after the "=". +// If the result is false, the key does NOT match and the file pointer is +// pointing at the start of the next line, if any +static bool key_matches(file_arg *file_handle, const char *key) { + uint8_t character; + character = consume_whitespace(file_handle); + // [section] isn't implemented, so skip to end of file. + if (character == '[' || character == 0) { + seek_eof(file_handle); + return false; + } + while (*key) { + if (character != *key++) { + // A character didn't match the key, so it's not a match + // If the non-matching char was not the end of the line, + // then consume the rest of the line + if (character != '\n') { + next_line(file_handle); + } + return false; + } + character = get_next_byte(file_handle); + } + // the next character could be whitespace; consume if necessary + if (unichar_isspace(character)) { + character = consume_whitespace(file_handle); + } + // If we're not looking at the "=" then the key didn't match + if (character != '=') { + // A character didn't match the key, so it's not a match + // If the non-matching char was not the end of the line, + // then consume the rest of the line + if (character != '\n') { + next_line(file_handle); + } + return false; + } + return true; +} + +static settings_err_t read_unicode_escape(file_arg *file_handle, int sz, vstr_t *vstr) { + char hex_buf[sz + 1]; + for (int i = 0; i < sz; i++) { + hex_buf[i] = get_next_byte(file_handle); + } + hex_buf[sz] = 0; + char *end; + unsigned long c = strtoul(hex_buf, &end, 16); + if (end != &hex_buf[sz]) { + return SETTINGS_ERR_BAD_VALUE; + } + if (c >= 0x110000) { + return SETTINGS_ERR_UNICODE; + } + vstr_add_char_nonstd(vstr, c); + return SETTINGS_OK; +} + +// Read a quoted string +static settings_err_t read_string_value(file_arg *file_handle, vstr_t *vstr) { + while (true) { + int character = get_next_byte(file_handle); + switch (character) { + case 0: + case '\n': + return SETTINGS_ERR_BAD_VALUE; + + case '"': + character = consume_whitespace(file_handle); + switch (character) { + case '#': + next_line(file_handle); + MP_FALLTHROUGH; + case 0: + case '\n': + return SETTINGS_OK; + default: + return SETTINGS_ERR_BAD_VALUE; + } + + case '\\': + character = get_next_byte(file_handle); + switch (character) { + case 0: + case '\n': + return SETTINGS_ERR_BAD_VALUE; + case 'b': + character = '\b'; + break; + case 'r': + character = '\r'; + break; + case 'n': + character = '\n'; + break; + case 't': + character = '\t'; + break; + case 'v': + character = '\v'; + break; + case 'f': + character = '\f'; + break; + case 'U': + case 'u': { + int sz = (character == 'u') ? 4 : 8; + settings_err_t res; + res = read_unicode_escape(file_handle, sz, vstr); + if (res != SETTINGS_OK) { + return res; + } + continue; + } + // default falls through, other escaped characters + // represent themselves + } + MP_FALLTHROUGH; + default: + vstr_add_byte_nonstd(vstr, character); + } + } +} + +// Read a bare value (non-quoted value) as a string +// Trims leading and trailing spaces/tabs, stops at # comment or newline +static settings_err_t read_bare_value(file_arg *file_handle, vstr_t *vstr, int first_character) { + int character = first_character; + size_t trailing_space_count = 0; + + while (true) { + switch (character) { + case 0: + case '\n': + // Remove trailing spaces/tabs and \r + vstr->len -= trailing_space_count; + return SETTINGS_OK; + case '#': + // Remove trailing spaces/tabs and \r before comment + vstr->len -= trailing_space_count; + next_line(file_handle); + return SETTINGS_OK; + case ' ': + case '\t': + case '\r': + // Track potential trailing whitespace + vstr_add_byte_nonstd(vstr, character); + trailing_space_count++; + break; + default: + // Non-whitespace character resets trailing space count + vstr_add_byte_nonstd(vstr, character); + trailing_space_count = 0; + } + character = get_next_byte(file_handle); + } +} + +static mp_int_t read_value(file_arg *file_handle, vstr_t *vstr, bool *quoted) { + uint8_t character; + character = consume_whitespace(file_handle); + *quoted = (character == '"'); + + if (*quoted) { + return read_string_value(file_handle, vstr); + } else if (character == '\n' || character == 0) { + // Empty value is an error + return SETTINGS_ERR_BAD_VALUE; + } else { + return read_bare_value(file_handle, vstr, character); + } +} + +static settings_err_t settings_get_vstr(const char *key, vstr_t *vstr, bool *quoted) { + file_arg file_handle; + if (!open_file(SETTINGS_PATH, &file_handle)) { + return SETTINGS_ERR_OPEN; + } + + settings_err_t result = SETTINGS_ERR_NOT_FOUND; + while (!is_eof(&file_handle)) { + if (key_matches(&file_handle, key)) { + result = read_value(&file_handle, vstr, quoted); + break; + } + } + close_file(&file_handle); + return result; +} + +static settings_err_t settings_get_buf_terminated(const char *key, char *value, size_t value_len, bool *quoted) { + vstr_t vstr; + vstr_init_fixed_buf(&vstr, value_len, value); + settings_err_t result = settings_get_vstr(key, &vstr, quoted); + + if (result == SETTINGS_OK) { + vstr_add_byte_nonstd(&vstr, 0); + memcpy(value, vstr.buf, MIN(vstr.len, value_len)); + if (vstr.len > value_len) { // this length includes trailing NUL + result = SETTINGS_ERR_LENGTH; + } + } + return result; +} + +static void print_error(const char *key, settings_err_t result) { + switch (result) { + case SETTINGS_OK: + case SETTINGS_ERR_OPEN: + case SETTINGS_ERR_NOT_FOUND: + // These errors need not be printed. + // The code asking for the value is not necessarily expecting to find one. + return; + default: + mp_cprintf(&mp_plat_print, MP_ERROR_TEXT("An error occurred while retrieving '%s':\n"), key); + break; + } + + switch (result) { + case SETTINGS_ERR_UNICODE: + mp_cprintf(&mp_plat_print, MP_ERROR_TEXT("Invalid unicode escape")); + break; + case SETTINGS_ERR_BAD_VALUE: + mp_cprintf(&mp_plat_print, MP_ERROR_TEXT("Invalid format")); + break; + default: + mp_cprintf(&mp_plat_print, MP_ERROR_TEXT("Internal error")); + break; + } + mp_printf(&mp_plat_print, "\n"); +} + + +static settings_err_t get_str(const char *key, char *value, size_t value_len) { + bool quoted; + settings_err_t result = settings_get_buf_terminated(key, value, value_len, "ed); + if (result == SETTINGS_OK && !quoted) { + result = SETTINGS_ERR_BAD_VALUE; + } + return result; +} + +settings_err_t settings_get_str(const char *key, char *value, size_t value_len) { + settings_err_t result = get_str(key, value, value_len); + print_error(key, result); + return result; +} + +static settings_err_t get_int(const char *key, mp_int_t *value) { + char buf[16]; + bool quoted; + settings_err_t result = settings_get_buf_terminated(key, buf, sizeof(buf), "ed); + if (result != SETTINGS_OK) { + return result; + } + if (quoted) { + return SETTINGS_ERR_BAD_VALUE; + } + char *end; + long num = strtol(buf, &end, 0); + while (unichar_isspace(*end)) { + end++; + } + if (end == buf || *end) { // If the whole buffer was not consumed it's an error + return SETTINGS_ERR_BAD_VALUE; + } + *value = (mp_int_t)num; + return SETTINGS_OK; +} + +settings_err_t settings_get_int(const char *key, mp_int_t *value) { + settings_err_t result = get_int(key, value); + print_error(key, result); + return result; +} + +static settings_err_t get_bool(const char *key, bool *value) { + char buf[16]; + bool quoted; + settings_err_t result = settings_get_buf_terminated(key, buf, sizeof(buf), "ed); + if (result != SETTINGS_OK) { + return result; + } + if (quoted) { + return SETTINGS_ERR_BAD_VALUE; + } + + // Check for "true" or "false" (case-sensitive) + if (strcmp(buf, "true") == 0) { + *value = true; + return SETTINGS_OK; + } else if (strcmp(buf, "false") == 0) { + *value = false; + return SETTINGS_OK; + } + + // Not a valid boolean value + return SETTINGS_ERR_BAD_VALUE; +} + +settings_err_t settings_get_bool(const char *key, bool *value) { + settings_err_t result = get_bool(key, value); + print_error(key, result); + return result; +} + +#if MICROPY_PY_BUILTINS_FLOAT +static settings_err_t get_float(const char *key, mp_float_t *value) { + char buf[48]; + bool quoted; + settings_err_t result = settings_get_buf_terminated(key, buf, sizeof(buf), "ed); + if (result != SETTINGS_OK) { + return result; + } + if (quoted) { + return SETTINGS_ERR_BAD_VALUE; + } + + const char *str = buf; + const char *end = buf + strlen(buf); + bool neg = false; + + if (str < end && (*str == '+' || *str == '-')) { + neg = (*str == '-'); + str++; + } + + mp_float_t val; + if (end - str >= 3 && str[0] == 'i' && str[1] == 'n' && str[2] == 'f') { + str += 3; + val = (mp_float_t)INFINITY; + } else if (end - str >= 3 && str[0] == 'n' && str[1] == 'a' && str[2] == 'n') { + str += 3; + val = MICROPY_FLOAT_C_FUN(nan)(""); + } else { + const char *num_start = str; + str = mp_parse_float_internal(str, end - str, &val); + if (str == NULL || str == num_start) { + return SETTINGS_ERR_BAD_VALUE; + } + } + + if (str != end) { + return SETTINGS_ERR_BAD_VALUE; + } + + *value = neg ? -val : val; + return SETTINGS_OK; +} + +settings_err_t settings_get_float(const char *key, mp_float_t *value) { + settings_err_t result = get_float(key, value); + print_error(key, result); + return result; +} +#endif + +// Get the raw value as a vstr, whether quoted or bare. Value may be an invalid TOML value. +settings_err_t settings_get_raw_vstr(const char *key, vstr_t *vstr) { + bool quoted; + return settings_get_vstr(key, vstr, "ed); +} + +settings_err_t settings_get_obj(const char *key, mp_obj_t *value) { + vstr_t vstr; + vstr_init(&vstr, 32); + bool quoted; + + settings_err_t result = settings_get_vstr(key, &vstr, "ed); + if (result != SETTINGS_OK) { + return result; + } + + if (quoted) { + // Successfully parsed a quoted string + *value = mp_obj_new_str_from_vstr(&vstr); + return SETTINGS_OK; + } + + // Not a quoted string, try boolean + bool bool_val; + result = get_bool(key, &bool_val); + if (result == SETTINGS_OK) { + *value = mp_obj_new_bool(bool_val); + return SETTINGS_OK; + } + + // Not a boolean, try integer + mp_int_t int_val; + result = get_int(key, &int_val); + if (result == SETTINGS_OK) { + *value = mp_obj_new_int(int_val); + return SETTINGS_OK; + } + + // Not an integer, try float + #if MICROPY_PY_BUILTINS_FLOAT + mp_float_t float_val; + result = get_float(key, &float_val); + if (result == SETTINGS_OK) { + *value = mp_obj_new_float(float_val); + return SETTINGS_OK; + } + #endif + + return SETTINGS_ERR_BAD_VALUE; +} + +#endif diff --git a/supervisor/shared/settings.h b/supervisor/shared/settings.h new file mode 100644 index 00000000000..6d92d45d79a --- /dev/null +++ b/supervisor/shared/settings.h @@ -0,0 +1,64 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2022 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#pragma once + +#include "py/obj.h" + +typedef enum { + SETTINGS_OK = 0, + // The settings file could not be opened. + SETTINGS_ERR_OPEN, + SETTINGS_ERR_UNICODE, + SETTINGS_ERR_LENGTH, + SETTINGS_ERR_NOT_FOUND, + SETTINGS_ERR_BAD_VALUE, +} settings_err_t; + +// Read a string value from the settings file. +// If it fits, the return value is 0-terminated. The passed-in buffer +// may be modified even if an error is returned. Allocation free. +// An error that is not SETTINGS_ERR_OPEN or SETTINGS_ERR_NOT_FOUND is printed on the repl. +// Returns an error if the value is not a quoted string. +settings_err_t settings_get_str(const char *key, char *value, size_t value_len); + +// Read an integer value from the settings file. +// Returns SETTINGS_OK and sets value to the read value. Returns +// SETTINGS_ERR_... if the value was not numeric. allocation-free. +// If any error code is returned, value is guaranteed not modified +// An error that is not 'open' or 'not found' is printed on the repl. +settings_err_t settings_get_int(const char *key, mp_int_t *value); + +// Read a boolean value from the settings file. +// Returns SETTINGS_OK and sets value to the read value. Returns +// SETTINGS_ERR_... if the value was not a boolean (true or false). allocation-free. +// If any error code is returned, value is guaranteed not modified +// An error that is not 'open' or 'not found' is printed on the repl. +settings_err_t settings_get_bool(const char *key, bool *value); + +#if MICROPY_PY_BUILTINS_FLOAT +// Read a float value from the settings file. +// Returns SETTINGS_OK and sets value to the read value. Returns +// SETTINGS_ERR_... if the value was not a float. allocation-free. +// If any error code is returned, value is guaranteed not modified. +// An error that is not SETTINGS_ERR_OPEN or SETTINGS_ERR_NOT_FOUND is printed on the repl. +settings_err_t settings_get_float(const char *key, mp_float_t *value); +#endif + +// Read a value from the settings file and return as parsed Python object. +// Returns SETTINGS_OK and sets value to a parsed Python object from the RHS value: +// - Quoted strings return as str +// - Bare "true" or "false" return as bool +// - Valid integers return as int +// - Valid floats (containing '.' or 'e'/'E') return as float +// Returns SETTINGS_ERR_... if the value is not parseable as one of these types. +// An error that is not SETTINGS_ERR_OPEN or SETTINGS_ERR_NOT_FOUND is printed on the repl. +settings_err_t settings_get_obj(const char *key, mp_obj_t *value); + +// Read the raw value as a string, whether quoted or bare. +// This is used by os.getenv() to always return strings. +// Does not print errors. +settings_err_t settings_get_raw_vstr(const char *key, vstr_t *vstr); diff --git a/supervisor/shared/stack.c b/supervisor/shared/stack.c index ebf99f425cc..e7984f10d9f 100644 --- a/supervisor/shared/stack.c +++ b/supervisor/shared/stack.c @@ -13,17 +13,24 @@ #include "supervisor/shared/safe_mode.h" void stack_init(void) { + // Zephyr has a stack canary of its own. + #ifndef __ZEPHYR__ uint32_t *stack_limit = port_stack_get_limit(); *stack_limit = STACK_CANARY_VALUE; + #endif } inline bool stack_ok(void) { + #ifndef __ZEPHYR__ uint32_t *stack_limit = port_stack_get_limit(); return *stack_limit == STACK_CANARY_VALUE; + #endif } inline void assert_heap_ok(void) { + #ifndef __ZEPHYR__ if (!stack_ok()) { reset_into_safe_mode(SAFE_MODE_STACK_OVERFLOW); } + #endif } diff --git a/supervisor/shared/status_bar.c b/supervisor/shared/status_bar.c index 2a8f88d1a3f..3b6e00ef561 100644 --- a/supervisor/shared/status_bar.c +++ b/supervisor/shared/status_bar.c @@ -21,10 +21,14 @@ #include "supervisor/shared/web_workflow/web_workflow.h" #endif -#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE #include "supervisor/shared/bluetooth/bluetooth.h" #endif +#if CIRCUITPY_USB_KEYBOARD_WORKFLOW +#include "supervisor/usb.h" +#endif + static background_callback_t status_bar_background_cb; static bool _forced_dirty = false; @@ -75,12 +79,16 @@ void supervisor_status_bar_update(void) { serial_write("\x1b" "]0;"); serial_write("🐍"); + #if CIRCUITPY_USB_KEYBOARD_WORKFLOW + usb_keyboard_status(); + #endif + #if CIRCUITPY_WEB_WORKFLOW supervisor_web_workflow_status(); serial_write(" | "); #endif - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE supervisor_bluetooth_status(); serial_write(" | "); #endif @@ -111,7 +119,7 @@ static void status_bar_background(void *data) { dirty = dirty || supervisor_web_workflow_status_dirty(); #endif - #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_FILE_SERVICE || CIRCUITPY_BLE_SERIAL_SERVICE dirty = dirty || supervisor_bluetooth_status_dirty(); #endif diff --git a/supervisor/shared/status_leds.c b/supervisor/shared/status_leds.c index e7b3d4b6e46..ca29fd79212 100644 --- a/supervisor/shared/status_leds.c +++ b/supervisor/shared/status_leds.c @@ -112,7 +112,7 @@ static uint32_t current_status_color = 0; #endif static bool status_led_init_in_progress = false; -void status_led_init() { +void status_led_init(void) { if (status_led_init_in_progress) { // Avoid recursion. return; @@ -133,9 +133,9 @@ void status_led_init() { memset(status_apa102_color + 4, 0xff, APA102_BUFFER_LENGTH - 4); #if CIRCUITPY_BITBANG_APA102 shared_module_bitbangio_spi_construct(&status_apa102, - MICROPY_HW_APA102_SCK, - MICROPY_HW_APA102_MOSI, - NULL); + MP_OBJ_FROM_PTR(MICROPY_HW_APA102_SCK), + MP_OBJ_FROM_PTR(MICROPY_HW_APA102_MOSI), + mp_const_none); #else if (!common_hal_busio_spi_deinited(&status_apa102)) { common_hal_busio_spi_deinit(&status_apa102); @@ -170,7 +170,7 @@ void status_led_init() { common_hal_pwmio_pwmout_construct(&rgb_status_b, CIRCUITPY_RGB_STATUS_B, 0, 50000, false); } - #elif defined(MICROPY_HW_LED_STATUS) + #elif CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS) common_hal_digitalio_digitalinout_construct(&single_color_led, MICROPY_HW_LED_STATUS); common_hal_digitalio_digitalinout_switch_to_output( &single_color_led, MICROPY_HW_LED_STATUS_INVERTED == 0, DRIVE_MODE_PUSH_PULL); @@ -186,7 +186,7 @@ void status_led_init() { status_led_init_in_progress = false; } -void status_led_deinit() { +void status_led_deinit(void) { #ifdef MICROPY_HW_NEOPIXEL // Make sure the pin stays low for the reset period. The pin reset may pull // it up and stop the reset period. @@ -216,7 +216,7 @@ void status_led_deinit() { common_hal_pwmio_pwmout_deinit(&rgb_status_b); } - #elif defined(MICROPY_HW_LED_STATUS) + #elif CIRCUITPY_DIGITALIO && defined(MICROPY_HW_LED_STATUS) common_hal_digitalio_digitalinout_deinit(&single_color_led); #endif diff --git a/supervisor/shared/tick.c b/supervisor/shared/tick.c index 24a06e622a1..81815c0813b 100644 --- a/supervisor/shared/tick.c +++ b/supervisor/shared/tick.c @@ -27,6 +27,10 @@ #include "shared-module/keypad/__init__.h" #endif +#if CIRCUITPY_AUDIOFILEWRITER +#include "shared-module/audiofilewriter/AudioFileWriter.h" +#endif + #include "shared-bindings/microcontroller/__init__.h" #if CIRCUITPY_WATCHDOG @@ -59,6 +63,10 @@ static void supervisor_background_tick(void *unused) { filesystem_background(); + #if CIRCUITPY_AUDIOFILEWRITER + audiofilewriter_background(); + #endif + port_background_tick(); assert_heap_ok(); @@ -85,38 +93,49 @@ void supervisor_tick(void) { background_callback_add(&tick_callback, supervisor_background_tick, NULL); } -uint64_t supervisor_ticks_ms64() { +static uint64_t _get_raw_subticks(void) { + uint64_t ticks; + uint8_t subticks; + ticks = port_get_raw_ticks(&subticks); + return (ticks << 5) | subticks; +} + +uint64_t supervisor_ticks_ms64(void) { uint64_t result; result = port_get_raw_ticks(NULL); result = result * 1000 / 1024; return result; } -uint32_t supervisor_ticks_ms32() { +uint32_t supervisor_ticks_ms32(void) { return supervisor_ticks_ms64(); } void mp_hal_delay_ms(mp_uint_t delay_ms) { - uint64_t start_tick = port_get_raw_ticks(NULL); - // Adjust the delay to ticks vs ms. - uint64_t delay_ticks = (delay_ms * (uint64_t)1024) / 1000; - uint64_t end_tick = start_tick + delay_ticks; - int64_t remaining = delay_ticks; + uint64_t start_subtick = _get_raw_subticks(); + // Convert delay from ms to subticks + uint64_t delay_subticks = (delay_ms * (uint64_t)32768) / 1000; + uint64_t end_subtick = start_subtick + delay_subticks; + int64_t remaining = delay_subticks; // Loop until we've waited long enough or we've been CTRL-Ced by autoreload // or the user. while (remaining > 0 && !mp_hal_is_interrupted()) { RUN_BACKGROUND_TASKS; - remaining = end_tick - port_get_raw_ticks(NULL); - // We break a bit early so we don't risk setting the alarm before the time when we call - // sleep. - if (remaining < 1) { + // Exit if interrupted while running background tasks + if (mp_hal_is_interrupted()) { break; } - port_interrupt_after_ticks(remaining); - // Idle until an interrupt happens. - port_idle_until_interrupt(); - remaining = end_tick - port_get_raw_ticks(NULL); + // Recalculate remaining delay after running background tasks + remaining = end_subtick - _get_raw_subticks(); + // If remaining delay is less than 1 tick, idle loop until end of delay + int64_t remaining_ticks = remaining / 32; + if (remaining_ticks > 0) { + port_interrupt_after_ticks(remaining_ticks); + // Idle until an interrupt happens. + port_idle_until_interrupt(); + } + remaining = end_subtick - _get_raw_subticks(); } } diff --git a/supervisor/shared/translate/translate.c b/supervisor/shared/translate/translate.c index 958e0a2144f..b590b385a71 100644 --- a/supervisor/shared/translate/translate.c +++ b/supervisor/shared/translate/translate.c @@ -114,7 +114,7 @@ static void decompress_vstr(mp_rom_error_text_t compressed, vstr_t *decompressed } int v = values[searched_length + bits - max_code]; if (v == 1) { - qstr q = get_nbits(&b, translation_qstr_bits) + 1; // honestly no idea why "+1"... + qstr q = get_nbits(&b, translation_qstr_bits); vstr_add_str(decompressed, qstr_str(q)); } else { put_utf8(decompressed, v); diff --git a/supervisor/shared/usb.c b/supervisor/shared/usb.c new file mode 100644 index 00000000000..3aa24e62675 --- /dev/null +++ b/supervisor/shared/usb.c @@ -0,0 +1,73 @@ +// This file is part of the CircuitPython project: https://circuitpython.org +// +// SPDX-FileCopyrightText: Copyright (c) 2025 Scott Shawcroft for Adafruit Industries +// +// SPDX-License-Identifier: MIT + +#include "supervisor/usb.h" + +#if CIRCUITPY_STORAGE +#include "shared-module/storage/__init__.h" +#endif + +#if CIRCUITPY_USB_DEVICE +#include "shared-bindings/supervisor/__init__.h" + +#if CIRCUITPY_USB_CDC +#include "shared-module/usb_cdc/__init__.h" +#endif + +#if CIRCUITPY_USB_HID +#include "shared-module/usb_hid/__init__.h" +#endif + +#if CIRCUITPY_USB_MIDI +#include "shared-module/usb_midi/__init__.h" +#endif + +#if CIRCUITPY_USB_AUDIO +#include "shared-module/usb_audio/__init__.h" +#endif + +#if CIRCUITPY_USB_VIDEO +#include "shared-module/usb_video/__init__.h" +#endif +#endif + +// Set up USB defaults before any USB changes are made in boot.py +void usb_set_defaults(void) { + #if CIRCUITPY_USB_DEVICE + #if CIRCUITPY_STORAGE && CIRCUITPY_USB_MSC + storage_usb_set_defaults(); + #endif + + #if CIRCUITPY_USB_CDC + usb_cdc_set_defaults(); + #endif + + #if CIRCUITPY_USB_HID + usb_hid_set_defaults(); + #endif + + #if CIRCUITPY_USB_MIDI + usb_midi_set_defaults(); + #endif + #endif +}; + +// Call this when ready to run code.py or a REPL, and a VM has been started. +void usb_setup_with_vm(void) { + #if CIRCUITPY_USB_DEVICE + #if CIRCUITPY_USB_HID + usb_hid_setup_devices(); + #endif + + #if CIRCUITPY_USB_MIDI + usb_midi_setup_ports(); + #endif + + #if CIRCUITPY_USB_AUDIO + usb_audio_setup_singletons(); + #endif + #endif +} diff --git a/supervisor/shared/usb/host_keyboard.c b/supervisor/shared/usb/host_keyboard.c index 661ebb64223..de4f719d175 100644 --- a/supervisor/shared/usb/host_keyboard.c +++ b/supervisor/shared/usb/host_keyboard.c @@ -12,6 +12,8 @@ #include "shared/runtime/interrupt_char.h" #include "supervisor/usb.h" #include "supervisor/background_callback.h" +#include "supervisor/shared/serial.h" +#include "supervisor/shared/status_bar.h" #include "supervisor/shared/tick.h" #ifndef DEBUG @@ -26,6 +28,14 @@ static uint8_t _buf[16]; static uint8_t _dev_addr; static uint8_t _interface; +// A keyboard interface that is not boot-protocol, detected at mount time from +// its report descriptor. Composite HID devices (CircuitPython's usb_hid among +// them) present bInterfaceProtocol NONE and prefix each report with a report +// ID, so they fail the boot-protocol check in usb_keyboard_attach(). +static uint8_t _report_kbd_dev_addr; +static uint8_t _report_kbd_interface; +static uint8_t _report_kbd_report_id; + #define FLAG_SHIFT (1) #define FLAG_NUMLOCK (2) #define FLAG_CTRL (4) @@ -296,7 +306,12 @@ static void process_event(uint8_t dev_addr, uint8_t instance, const hid_keyboard uint8_t leds = (caps | (num << 1)); if (leds != old_report.reserved) { - tuh_hid_set_report(dev_addr, instance /*idx*/, 0 /*report_id*/, HID_REPORT_TYPE_OUTPUT /*report_type*/, &leds, sizeof(leds)); + // A report-protocol keyboard needs its report ID on the LED output report too. + uint8_t report_id = 0; + if (dev_addr == _report_kbd_dev_addr && instance == _report_kbd_interface) { + report_id = _report_kbd_report_id; + } + tuh_hid_set_report(dev_addr, instance /*idx*/, report_id, HID_REPORT_TYPE_OUTPUT /*report_type*/, &leds, sizeof(leds)); } old_report = *report; old_report.reserved = leds; @@ -316,6 +331,7 @@ void usb_keyboard_detach(uint8_t dev_addr, uint8_t interface) { tuh_hid_receive_abort(dev_addr, interface); _dev_addr = 0; _interface = 0; + supervisor_status_bar_request_update(false); } void usb_keyboard_attach(uint8_t dev_addr, uint8_t interface) { @@ -323,28 +339,65 @@ void usb_keyboard_attach(uint8_t dev_addr, uint8_t interface) { return; } uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, interface); - if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { + bool is_boot_keyboard = itf_protocol == HID_ITF_PROTOCOL_KEYBOARD; + // Detected at mount time by tuh_hid_mount_cb(). Device addresses start at + // 1, so a zeroed _report_kbd_dev_addr never matches. + bool is_report_keyboard = dev_addr == _report_kbd_dev_addr && interface == _report_kbd_interface; + if (is_boot_keyboard || is_report_keyboard) { _dev_addr = dev_addr; _interface = interface; tuh_hid_receive_report(dev_addr, interface); } + supervisor_status_bar_request_update(false); } void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t interface, uint8_t const *desc_report, uint16_t desc_len) { + // A non-boot interface can still be a keyboard, using report protocol. + // Find keyboard usage in its report descriptor so that we poll it too. + // Otherwise its interrupt IN endpoint is never drained, and a CircuitPython + // device plugged into us raises OSError("USB busy") on its second + // send_report() (#10721). + if (tuh_hid_interface_protocol(dev_addr, interface) == HID_ITF_PROTOCOL_NONE && + _report_kbd_dev_addr == 0) { + tuh_hid_report_info_t report_info[8]; + uint8_t report_count = + tuh_hid_parse_report_descriptor(report_info, TU_ARRAY_SIZE(report_info), desc_report, desc_len); + for (uint8_t i = 0; i < report_count; i++) { + if (report_info[i].usage_page == HID_USAGE_PAGE_DESKTOP && + report_info[i].usage == HID_USAGE_DESKTOP_KEYBOARD) { + _report_kbd_dev_addr = dev_addr; + _report_kbd_interface = interface; + _report_kbd_report_id = report_info[i].report_id; + break; + } + } + } usb_keyboard_attach(dev_addr, interface); } void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t interface) { + if (dev_addr == _report_kbd_dev_addr && interface == _report_kbd_interface) { + _report_kbd_dev_addr = 0; + _report_kbd_interface = 0; + _report_kbd_report_id = 0; + } usb_keyboard_detach(dev_addr, interface); } void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const *report, uint16_t len) { - if (len != sizeof(hid_keyboard_report_t)) { - return; - } else { + if (len == sizeof(hid_keyboard_report_t)) { process_event(dev_addr, instance, (hid_keyboard_report_t *)report); + } else if (dev_addr == _report_kbd_dev_addr && instance == _report_kbd_interface && + _report_kbd_report_id != 0 && + len == sizeof(hid_keyboard_report_t) + 1 && + report[0] == _report_kbd_report_id) { + // Report-protocol keyboards prefix the report with its report ID. + process_event(dev_addr, instance, (const hid_keyboard_report_t *)(report + 1)); } - // continue to request to receive report + // Always request the next report, even when this one wasn't a keyboard + // report we understand (a mouse or consumer control report ID from a + // composite device, for instance), so that the device's endpoint keeps + // draining and polling doesn't stop. tuh_hid_receive_report(dev_addr, instance); } @@ -362,3 +415,9 @@ char usb_keyboard_read_char(void) { } return -1; } + +void usb_keyboard_status(void) { + if (_dev_addr != 0 && _interface != 0) { + serial_write("🖮"); + } +} diff --git a/supervisor/shared/usb/tusb_config.h b/supervisor/shared/usb/tusb_config.h index a3ac3e3237d..ac63542b8e4 100644 --- a/supervisor/shared/usb/tusb_config.h +++ b/supervisor/shared/usb/tusb_config.h @@ -55,7 +55,11 @@ extern "C" { // When debugging TinyUSB, only output to the console UART link. #if CIRCUITPY_DEBUG_TINYUSB > 0 && defined(CIRCUITPY_CONSOLE_UART) #define CFG_TUSB_DEBUG CIRCUITPY_DEBUG_TINYUSB +#ifdef __ZEPHYR__ +#define CFG_TUSB_DEBUG_PRINTF zephyr_printk +#else #define CFG_TUSB_DEBUG_PRINTF console_uart_printf +#endif // Raise the device log level to 3 so we can debug host-only at level 2. #define CFG_TUD_LOG_LEVEL 3 @@ -75,18 +79,22 @@ extern "C" { #if CIRCUITPY_USB_DEVICE -#if CIRCUITPY_USB_DEVICE_INSTANCE == 0 -#if USB_HIGHSPEED -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) +#if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 +#define _DEVICE_SPEED OPT_MODE_HIGH_SPEED #else -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE) +#define _DEVICE_SPEED 0 #endif + +#if CIRCUITPY_USB_DEVICE_INSTANCE == 0 +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | _DEVICE_SPEED) #elif CIRCUITPY_USB_DEVICE_INSTANCE == 1 -#if USB_HIGHSPEED -#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED) -#else -#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE) +#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_DEVICE | _DEVICE_SPEED) #endif + +// Use DMA with the USB peripheral. +#if defined(CONFIG_IDF_TARGET_ESP32P4) || defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3) +#define CFG_TUD_DWC2_DMA_ENABLE (1) +#define CFG_TUH_DWC2_DMA_ENABLE (1) #endif // Vendor name included in Inquiry response, max 8 bytes @@ -107,8 +115,33 @@ extern "C" { #define CFG_TUD_HID CIRCUITPY_USB_HID #define CFG_TUD_MIDI CIRCUITPY_USB_MIDI #define CFG_TUD_VENDOR CIRCUITPY_USB_VENDOR +#define CFG_TUD_AUDIO CIRCUITPY_USB_AUDIO #define CFG_TUD_CUSTOM_CLASS 0 +// ------------- AUDIO CLASS (UAC2 microphone) -------------// +#if CIRCUITPY_USB_AUDIO +#include "shared-module/usb_audio/usb_audio_descriptors.h" + +// EP0 buffer for class-specific control requests (sample-freq range, volume range, ...). +#define CFG_TUD_AUDIO_CTRL_BUF_SZ 64 + +#define CFG_TUD_AUDIO_ENABLE_EP_IN 1 +// wMaxPacketSize, sized for the highest supported sample rate. +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, USB_AUDIO_MAX_SAMPLE_RATE, USB_AUDIO_N_BYTES_PER_SAMPLE, USB_AUDIO_N_CHANNELS) +// Deep software FIFO so the 1 ms refill keeps clear of the underrun floor. +#define CFG_TUD_AUDIO_FUNC_1_EP_IN_SW_BUF_SZ (16 * CFG_TUD_AUDIO_FUNC_1_EP_IN_SZ_MAX) + +// OUT endpoint (host -> board speaker). Compiled into the class driver +// unconditionally; whether it actually enumerates is decided by the emitted +// descriptor (still mic-only until the speaker descriptor lands). Mirrors the +// IN sizing above. +#define CFG_TUD_AUDIO_ENABLE_EP_OUT 1 +// wMaxPacketSize, sized for the highest supported sample rate. +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX TUD_AUDIO_EP_SIZE(TUD_OPT_HIGH_SPEED, USB_AUDIO_MAX_SAMPLE_RATE, USB_AUDIO_N_BYTES_PER_SAMPLE, USB_AUDIO_N_CHANNELS) +// Deep software FIFO so the 1 ms drain keeps clear of the overrun ceiling. +#define CFG_TUD_AUDIO_FUNC_1_EP_OUT_SW_BUF_SZ (16 * CFG_TUD_AUDIO_FUNC_1_EP_OUT_SZ_MAX) +#endif + /*------------------------------------------------------------------*/ /* CLASS DRIVER *------------------------------------------------------------------*/ @@ -147,27 +180,28 @@ extern "C" { #define CFG_TUH_RPI_PIO_USB 1 #endif -#if CIRCUITPY_USB_HOST_INSTANCE == 0 -#if USB_HIGHSPEED -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) +#if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 +#define _HOST_SPEED OPT_MODE_HIGH_SPEED #else -#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST) +#define _HOST_SPEED 0 #endif + +#if CIRCUITPY_USB_HOST_INSTANCE == 0 +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_HOST | _HOST_SPEED) #elif CIRCUITPY_USB_HOST_INSTANCE == 1 -#if USB_HIGHSPEED -#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED) -#else -#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST) -#endif +#define CFG_TUSB_RHPORT1_MODE (OPT_MODE_HOST | _HOST_SPEED) #endif // Size of buffer to hold descriptors and other data used for enumeration +// CircuitPython itself is 284 bytes of configuration descriptor when both CDC endpoints are +// enabled, plus 4 bytes for alignment. #ifndef CFG_TUH_ENUMERATION_BUFSIZE -#define CFG_TUH_ENUMERATION_BUFSIZE 256 +#define CFG_TUH_ENUMERATION_BUFSIZE (284 + 4) #endif #if CIRCUITPY_USB_KEYBOARD_WORKFLOW -#define CFG_TUH_HID 2 +// One keyboard, one mouse and two other HID like gamepad. +#define CFG_TUH_HID 4 #else #define CFG_TUH_HID 0 #endif @@ -190,6 +224,11 @@ extern "C" { #endif +// Hack to work with older nrfx than what TinyUSB is designed for. +#define nrf52_errata_187 errata_187 +#define nrf52_errata_171 errata_171 +#define nrf52_errata_166 errata_166 + #ifdef __cplusplus } #endif diff --git a/supervisor/shared/usb/usb.c b/supervisor/shared/usb/usb.c index b87cf78e903..51222be0e59 100644 --- a/supervisor/shared/usb/usb.c +++ b/supervisor/shared/usb/usb.c @@ -7,6 +7,8 @@ #include "py/objstr.h" #include "supervisor/background_callback.h" #include "supervisor/linker.h" +#include "supervisor/port.h" +#include "supervisor/shared/tick.h" #include "supervisor/usb.h" #include "shared/readline/readline.h" @@ -37,14 +39,67 @@ #include "shared-module/usb_video/__init__.h" #endif +#if CIRCUITPY_USB_AUDIO +#include "shared-module/usb_audio/__init__.h" +#endif + #endif #include "tusb.h" +#if CFG_TUSB_OS == OPT_OS_ZEPHYR +#include +int CFG_TUSB_DEBUG_PRINTF(const char *format, ...) { + va_list args; + va_start(args, format); + printk(format, args); + va_end(args); + return 0; +} + +#ifdef CFG_TUSB_DEBUG + #define USBD_STACK_SIZE (5 * CONFIG_IDLE_STACK_SIZE) +#else + #define USBD_STACK_SIZE (5 * CONFIG_IDLE_STACK_SIZE / 2) +#endif + +struct k_thread tinyusb_thread_data; +K_THREAD_STACK_DEFINE(tinyusb_thread_stack, USBD_STACK_SIZE); +k_tid_t _tinyusb_tid; + +// USB Device Driver task +// This top level thread process all usb events and invoke callbacks +static void tinyusb_thread(void *unused0, void *unused1, void *unused2) { + (void)unused0; + (void)unused1; + (void)unused2; + + // RTOS forever loop + while (1) { + // tinyusb device task + if (tusb_inited()) { + tud_task(); + tud_cdc_write_flush(); + } else { + k_sleep(K_MSEC(1000)); + } + } +} + +#endif + bool usb_enabled(void) { return tusb_inited(); } +bool usb_connected(void) { + #if CIRCUITPY_TINYUSB && CIRCUITPY_USB_DEVICE + return tud_ready(); + #else + return false; + #endif +} + MP_WEAK void post_usb_init(void) { } @@ -91,39 +146,14 @@ void usb_init(void) { tud_cdc_set_wanted_char(CHAR_CTRL_C); } #endif -} - -// Set up USB defaults before any USB changes are made in boot.py -void usb_set_defaults(void) { - #if CIRCUITPY_USB_DEVICE - #if CIRCUITPY_STORAGE && CIRCUITPY_USB_MSC - storage_usb_set_defaults(); - #endif - - #if CIRCUITPY_USB_CDC - usb_cdc_set_defaults(); - #endif - - #if CIRCUITPY_USB_HID - usb_hid_set_defaults(); - #endif - - #if CIRCUITPY_USB_MIDI - usb_midi_set_defaults(); - #endif - #endif -}; - -// Call this when ready to run code.py or a REPL, and a VM has been started. -void usb_setup_with_vm(void) { - #if CIRCUITPY_USB_DEVICE - #if CIRCUITPY_USB_HID - usb_hid_setup_devices(); - #endif - #if CIRCUITPY_USB_MIDI - usb_midi_setup_ports(); - #endif + #if CFG_TUSB_OS == OPT_OS_ZEPHYR + _tinyusb_tid = k_thread_create(&tinyusb_thread_data, tinyusb_thread_stack, + K_THREAD_STACK_SIZEOF(tinyusb_thread_stack), + tinyusb_thread, + NULL, NULL, NULL, + CONFIG_MAIN_THREAD_PRIORITY - 1, 0, K_NO_WAIT); + k_thread_name_set(_tinyusb_tid, "tinyusb"); #endif } @@ -135,9 +165,8 @@ void usb_background(void) { tuh_task(); #endif #elif CFG_TUSB_OS == OPT_OS_FREERTOS - // Yield to FreeRTOS in case TinyUSB runs in a separate task. Don't use - // port_yield() because it has a longer delay. - vTaskDelay(0); + // TinyUSB may run in a separate task, at the same priority as CircuitPython. + port_task_yield(); #endif // No need to flush if there's no REPL. #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_CDC @@ -149,9 +178,19 @@ void usb_background(void) { #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_VIDEO usb_video_task(); #endif + #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_AUDIO + usb_audio_task(); + #endif } } +// Ports may override this with a RAM-resident version when TinyUSB code that +// calls it must not execute from flash (e.g. raspberrypi polls +// tuh_task_event_ready(), which calls this, from core1). +MP_WEAK uint32_t tusb_time_millis_api(void) { + return supervisor_ticks_ms32(); +} + static background_callback_t usb_callback; static void usb_background_do(void *unused) { usb_background(); diff --git a/supervisor/shared/usb/usb_desc.c b/supervisor/shared/usb/usb_desc.c index c4e182ff1e5..7a0bc4686bb 100644 --- a/supervisor/shared/usb/usb_desc.c +++ b/supervisor/shared/usb/usb_desc.c @@ -32,6 +32,10 @@ #include "shared-module/usb_video/__init__.h" #endif +#if CIRCUITPY_USB_AUDIO +#include "shared-module/usb_audio/__init__.h" +#endif + #include "shared-bindings/microcontroller/Processor.h" @@ -137,9 +141,13 @@ static bool usb_build_configuration_descriptor(void) { #endif #if CIRCUITPY_USB_MSC + #if CIRCUITPY_STORAGE if (storage_usb_enabled()) { - total_descriptor_length += storage_usb_descriptor_length(); - } + #endif + total_descriptor_length += usb_msc_descriptor_length(); + #if CIRCUITPY_STORAGE +} + #endif #endif #if CIRCUITPY_USB_HID @@ -166,6 +174,12 @@ static bool usb_build_configuration_descriptor(void) { } #endif + #if CIRCUITPY_USB_AUDIO + if (usb_audio_enabled()) { + total_descriptor_length += usb_audio_descriptor_length(); + } + #endif + // Now we know how big the configuration descriptor will be, so we can allocate space for it. configuration_descriptor = (uint8_t *)port_malloc(total_descriptor_length, @@ -210,11 +224,15 @@ static bool usb_build_configuration_descriptor(void) { #endif #if CIRCUITPY_USB_MSC + #if CIRCUITPY_STORAGE if (storage_usb_enabled()) { - // Concatenate and fix up the MSC descriptor. - descriptor_buf_remaining += storage_usb_add_descriptor( - descriptor_buf_remaining, &descriptor_counts, ¤t_interface_string); - } + #endif + // Concatenate and fix up the MSC descriptor. + descriptor_buf_remaining += usb_msc_add_descriptor( + descriptor_buf_remaining, &descriptor_counts, ¤t_interface_string); + #if CIRCUITPY_STORAGE +} + #endif #endif #if CIRCUITPY_USB_HID @@ -251,6 +269,13 @@ static bool usb_build_configuration_descriptor(void) { descriptor_buf_remaining, &descriptor_counts, ¤t_interface_string); } #endif + + #if CIRCUITPY_USB_AUDIO + if (usb_audio_enabled()) { + descriptor_buf_remaining += usb_audio_add_descriptor( + descriptor_buf_remaining, &descriptor_counts, ¤t_interface_string); + } + #endif // Now we know how many interfaces have been used. configuration_descriptor[CONFIG_NUM_INTERFACES_INDEX] = descriptor_counts.current_interface; diff --git a/supervisor/shared/usb/usb_device.c b/supervisor/shared/usb/usb_device.c index ec08b8bf4d7..e3f1a0d4e26 100644 --- a/supervisor/shared/usb/usb_device.c +++ b/supervisor/shared/usb/usb_device.c @@ -156,7 +156,7 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ // size. Setting CFG_TUD_CDC_RX_BUFSIZE to the endpoint size and then sending // any character will prevent ctrl-c from working. Require at least a 64 // character buffer. -#if CFG_TUD_CDC_RX_BUFSIZE < CFG_TUD_CDC_EP_BUFSIZE + 64 +#if CFG_TUD_CDC_RX_BUFSIZE < CFG_TUD_CDC_RX_EPSIZE + 64 #error "CFG_TUD_CDC_RX_BUFSIZE must be 64 bytes bigger than endpoint size." #endif @@ -166,6 +166,9 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ * @param wanted_char The wanted char (set previously) */ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { + // CircuitPython's VM is run in a separate FreeRTOS task from TinyUSB on ESP. + // So, we must notify the other task when a CTRL-C is received. + port_wake_main_task(); // Workaround for using shared/runtime/interrupt_char.c // Compare mp_interrupt_char with wanted_char and ignore if not matched if (mp_interrupt_char == wanted_char) { @@ -177,7 +180,14 @@ void tud_cdc_rx_wanted_cb(uint8_t itf, char wanted_char) { void tud_cdc_send_break_cb(uint8_t itf, uint16_t duration_ms) { if (usb_cdc_console_enabled() && mp_interrupt_char != -1 && itf == 0 && duration_ms > 0) { mp_sched_keyboard_interrupt(); + port_wake_main_task(); } } +void tud_cdc_rx_cb(uint8_t itf) { + (void)itf; + // Workaround for "press any key to enter REPL" response being delayed on espressif. + // Wake main task when any key is pressed. + port_wake_main_task(); +} #endif diff --git a/supervisor/shared/usb/usb_msc_flash.c b/supervisor/shared/usb/usb_msc_flash.c index 201a818c0bf..163019b7328 100644 --- a/supervisor/shared/usb/usb_msc_flash.c +++ b/supervisor/shared/usb/usb_msc_flash.c @@ -5,43 +5,171 @@ // SPDX-License-Identifier: MIT #include "tusb.h" -// // #include "supervisor/flash.h" // For updating fatfs's cache #include "extmod/vfs.h" #include "extmod/vfs_fat.h" #include "lib/oofatfs/diskio.h" #include "lib/oofatfs/ff.h" +#include "py/gc.h" #include "py/mpstate.h" +#include "py/runtime.h" #include "shared-module/storage/__init__.h" #include "supervisor/filesystem.h" #include "supervisor/shared/reload.h" +#include "supervisor/shared/settings.h" #define MSC_FLASH_BLOCK_SIZE 512 -static bool ejected[1] = {true}; -static bool locked[1] = {false}; +#if CIRCUITPY_SAVES_PARTITION_SIZE > 0 +#define SAVES_COUNT 1 +#define SAVES_LUN (1) +#else +#define SAVES_COUNT 0 +#endif -// The root FS is always at the end of the list. +#if CIRCUITPY_SDCARD_USB +#include "shared-module/sdcardio/__init__.h" + +#define SDCARD_COUNT 1 +#define SDCARD_LUN (1 + SAVES_COUNT) +#else +#define SDCARD_COUNT 0 +#endif + +#define LUN_COUNT (1 + SAVES_COUNT + SDCARD_COUNT) + +// The ellipsis range in the designated initializer of `ejected` is not standard C, +// but it works in both gcc and clang. +static bool ejected[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = true}; +static bool eject_once[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; +static bool locked[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; + +// Set to true if a write was in a file data or metadata area, +// as opposed to in the filesystem metadata area (e.g., dirty bit). +// Used to determine if an auto-reload is warranted. +static bool content_write[LUN_COUNT] = { [0 ... (LUN_COUNT - 1)] = false}; + +#include "tusb.h" + +static const uint8_t usb_msc_descriptor_template[] = { + // MSC Interface Descriptor + 0x09, // 0 bLength + 0x04, // 1 bDescriptorType (Interface) + 0xFF, // 2 bInterfaceNumber [SET AT RUNTIME] +#define MSC_INTERFACE_INDEX (2) + 0x00, // 3 bAlternateSetting + 0x02, // 4 bNumEndpoints 2 + 0x08, // 5 bInterfaceClass: MSC + 0x06, // 6 bInterfaceSubClass: TRANSPARENT + 0x50, // 7 bInterfaceProtocol: BULK + 0xFF, // 8 iInterface (String Index) [SET AT RUNTIME] +#define MSC_INTERFACE_STRING_INDEX (8) + + // MSC Endpoint IN Descriptor + 0x07, // 9 bLength + 0x05, // 10 bDescriptorType (Endpoint) + 0xFF, // 11 bEndpointAddress (IN/D2H) [SET AT RUNTIME: 0x80 | number] +#define MSC_IN_ENDPOINT_INDEX (11) + 0x02, // 12 bmAttributes (Bulk) + #if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 + 0x00, 0x02, // 13,14 wMaxPacketSize 512 + #else + 0x40, 0x00, // 13,14 wMaxPacketSize 64 + #endif + 0x00, // 15 bInterval 0 (unit depends on device speed) + + // MSC Endpoint OUT Descriptor + 0x07, // 16 bLength + 0x05, // 17 bDescriptorType (Endpoint) + 0xFF, // 18 bEndpointAddress (OUT/H2D) [SET AT RUNTIME] +#define MSC_OUT_ENDPOINT_INDEX (18) + 0x02, // 19 bmAttributes (Bulk) + #if CIRCUITPY_USB_DEVICE_HIGH_SPEED == 1 + 0x00, 0x02, // 20,21 wMaxPacketSize 512 + #else + 0x40, 0x00, // 20,21 wMaxPacketSize 64 + #endif + 0x00, // 22 bInterval 0 (unit depends on device speed) +}; + +size_t usb_msc_descriptor_length(void) { + return sizeof(usb_msc_descriptor_template); +} + +static const char storage_interface_name[] = USB_INTERFACE_NAME " Mass Storage"; + +size_t usb_msc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string) { + memcpy(descriptor_buf, usb_msc_descriptor_template, sizeof(usb_msc_descriptor_template)); + descriptor_buf[MSC_INTERFACE_INDEX] = descriptor_counts->current_interface; + descriptor_counts->current_interface++; + + descriptor_buf[MSC_IN_ENDPOINT_INDEX] = + 0x80 | (USB_MSC_EP_NUM_IN ? USB_MSC_EP_NUM_IN : descriptor_counts->current_endpoint); + descriptor_counts->num_in_endpoints++; + // Some TinyUSB devices have issues with bi-directional endpoints + #ifdef TUD_ENDPOINT_ONE_DIRECTION_ONLY + descriptor_counts->current_endpoint++; + #endif + + descriptor_buf[MSC_OUT_ENDPOINT_INDEX] = + USB_MSC_EP_NUM_OUT ? USB_MSC_EP_NUM_OUT : descriptor_counts->current_endpoint; + descriptor_counts->num_out_endpoints++; + descriptor_counts->current_endpoint++; + + usb_add_interface_string(*current_interface_string, storage_interface_name); + descriptor_buf[MSC_INTERFACE_STRING_INDEX] = *current_interface_string; + (*current_interface_string)++; + + return sizeof(usb_msc_descriptor_template); +} + +// We hardcode LUN -> mount mapping so that it doesn't changes with saves and +// SD card appearing and disappearing. static fs_user_mount_t *get_vfs(int lun) { - // TODO(tannewt): Return the mount which matches the lun where 0 is the end - // and is counted in reverse. - if (lun > 0) { - return NULL; + fs_user_mount_t *root = filesystem_circuitpy(); + if (lun == 0) { + return root; } - mp_vfs_mount_t *current_mount = MP_STATE_VM(vfs_mount_table); - if (current_mount == NULL) { - return NULL; + // Other filesystems must be native because we don't guard against exceptions. + // They must also be off the VM heap so they don't disappear on autoreload. + #ifdef SAVES_LUN + if (lun == SAVES_LUN) { + const char *path_under_mount; + fs_user_mount_t *saves = filesystem_for_path("/saves", &path_under_mount); + if (saves != root && + (saves->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0 && !gc_ptr_on_heap(saves)) { + return saves; + } } - while (current_mount->next != NULL) { - current_mount = current_mount->next; + #endif + #ifdef SDCARD_LUN + if (lun == SDCARD_LUN) { + const char *path_under_mount; + fs_user_mount_t *sdcard = filesystem_for_path("/sd", &path_under_mount); + // If sdcard ("/sd") is on the root filesystem, nothing has been mounted there, so don't + // return it as a separate filesystem. + // If the SD card was automounted at startup, then it persists across VMs and its fs_user_mount_t is + // not on the heap. + // If the SD card filesystem was mounted by the user using heap objects, + // it should not be used when the VM has stopped running. + if ((sdcard != root) && + ((sdcard->blockdev.flags & MP_BLOCKDEV_FLAG_NATIVE) != 0) && + (vm_is_running() || !gc_ptr_on_heap(sdcard))) { + return sdcard; + } else { + // Clear any ejected state so that a re-insert causes it to reappear. + ejected[SDCARD_LUN] = false; + locked[SDCARD_LUN] = false; + } } - return current_mount->obj; + #endif + return NULL; } static void _usb_msc_uneject(void) { - for (uint8_t i = 0; i < sizeof(ejected); i++) { + for (uint8_t i = 0; i < LUN_COUNT; i++) { ejected[i] = false; locked[i] = false; } @@ -52,8 +180,8 @@ void usb_msc_mount(void) { } void usb_msc_umount(void) { - for (uint8_t i = 0; i < sizeof(ejected); i++) { - fs_user_mount_t *vfs = get_vfs(i + 1); + for (uint8_t i = 0; i < LUN_COUNT; i++) { + fs_user_mount_t *vfs = get_vfs(i); if (vfs == NULL) { continue; } @@ -62,27 +190,40 @@ void usb_msc_umount(void) { } } -bool usb_msc_ejected(void) { - bool all_ejected = true; - for (uint8_t i = 0; i < sizeof(ejected); i++) { - all_ejected &= ejected[i]; +void usb_msc_remount(fs_user_mount_t *fs_mount) { + for (uint8_t i = 0; i < LUN_COUNT; i++) { + fs_user_mount_t *vfs = get_vfs(i); + if (vfs == NULL || vfs != fs_mount) { + continue; + } + ejected[i] = false; + eject_once[i] = true; } - return all_ejected; +} + +uint8_t tud_msc_get_maxlun_cb(void) { + return LUN_COUNT; +} + +// PREVENT ALLOW MEDIUM REMOVAL: TinyUSB routes this to its own dedicated callback, +// NOT tud_msc_scsi_cb. Reply unsupported on all LUNs so the host keeps TUR polling +// on every LUN — eject/storage.remount() works uniformly across CIRCUITPY, SAVES, SD. +bool tud_msc_prevent_allow_medium_removal_cb(uint8_t lun, uint8_t prohibit_removal, uint8_t control) { + (void)prohibit_removal; + (void)control; + tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); + return false; } // Callback invoked when received an SCSI command not in built-in list below // - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, TEST_UNIT_READY, START_STOP_UNIT, MODE_SENSE6, REQUEST_SENSE -// - READ10 and WRITE10 have their own callbacks +// - PREVENT_ALLOW_MEDIUM_REMOVAL, READ10, WRITE10 have their own callbacks int32_t tud_msc_scsi_cb(uint8_t lun, const uint8_t scsi_cmd[16], void *buffer, uint16_t bufsize) { + // Note that no command uses a response right now. const void *response = NULL; int32_t resplen = 0; switch (scsi_cmd[0]) { - case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL: - // Host is about to read/write etc ... better not to disconnect disk - resplen = 0; - break; - default: // Set Sense = Invalid Command Operation tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00); @@ -107,12 +248,14 @@ int32_t tud_msc_scsi_cb(uint8_t lun, const uint8_t scsi_cmd[16], void *buffer, u void tud_msc_capacity_cb(uint8_t lun, uint32_t *block_count, uint16_t *block_size) { fs_user_mount_t *vfs = get_vfs(lun); - disk_ioctl(vfs, GET_SECTOR_COUNT, block_count); - disk_ioctl(vfs, GET_SECTOR_SIZE, block_size); + if (vfs != NULL) { + disk_ioctl(vfs, GET_SECTOR_COUNT, block_count); + disk_ioctl(vfs, GET_SECTOR_SIZE, block_size); + } } bool tud_msc_is_writable_cb(uint8_t lun) { - if (lun > 1) { + if (lun >= LUN_COUNT) { return false; } @@ -120,7 +263,7 @@ bool tud_msc_is_writable_cb(uint8_t lun) { if (vfs == NULL) { return false; } - if (vfs->blockdev.writeblocks[0] == MP_OBJ_NULL || !filesystem_is_writable_by_usb(vfs)) { + if (!filesystem_is_writable_by_usb(vfs)) { return false; } // Lock the blockdev once we say we're writable. @@ -139,6 +282,9 @@ int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void *buff const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; fs_user_mount_t *vfs = get_vfs(lun); + if (vfs == NULL) { + return -1; + } uint32_t disk_block_count; disk_ioctl(vfs, GET_SECTOR_COUNT, &disk_block_count); @@ -161,16 +307,22 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * const uint32_t block_count = bufsize / MSC_FLASH_BLOCK_SIZE; fs_user_mount_t *vfs = get_vfs(lun); + if (vfs == NULL) { + return -1; + } + disk_write(vfs, buffer, lba, block_count); // Since by getting here we assume the mount is read-only to - // MicroPython let's update the cached FatFs sector if it's the one + // CircuitPython let's update the cached FatFs sector if it's the one // we just wrote. + if #if FF_MAX_SS != FF_MIN_SS - if (vfs->fatfs.ssize == MSC_FLASH_BLOCK_SIZE) { + (vfs->fatfs.ssize == MSC_FLASH_BLOCK_SIZE) #else // The compiler can optimize this away. - if (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE) { - #endif + (FF_MAX_SS == FILESYSTEM_BLOCK_SIZE) + #endif + { if (lba == vfs->fatfs.winsect && lba > 0) { memcpy(vfs->fatfs.win, buffer + MSC_FLASH_BLOCK_SIZE * (vfs->fatfs.winsect - lba), @@ -178,17 +330,30 @@ int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t * } } + // A write to an lba below fatbase is in the filesystem metadata (BPB) area or the "Reserved Region", + // and is probably setting or clearing the dirty bit. This should not trigger auto-reload. + // All other writes will trigger auto-reload. + if (lba >= vfs->fatfs.fatbase) { + content_write[lun] = true; + } + return block_count * MSC_FLASH_BLOCK_SIZE; } // Callback invoked when WRITE10 command is completed (status received and accepted by host). // used to flush any pending cache. void tud_msc_write10_complete_cb(uint8_t lun) { - (void)lun; - - // This write is complete; initiate an autoreload. autoreload_resume(AUTORELOAD_SUSPEND_USB); - autoreload_trigger(); + + // This write is complete; initiate an autoreload if this was a file data or metadata write, + // not just a dirty-bit write. + if (content_write[lun] && + // Fast path: lun == 0 is CIRCUITPY, which can always trigger auto-reload if enabled. + // Don't autoreload if this lun was mounted by the user: that will cause a VM stop and an unmount. + (lun == 0 || !gc_ptr_on_heap(get_vfs(lun)))) { + autoreload_trigger(); + content_write[lun] = false; + } } // Invoked when received SCSI_CMD_INQUIRY @@ -201,10 +366,36 @@ void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16 memcpy(product_rev, CFG_TUD_MSC_PRODUCT_REV, strlen(CFG_TUD_MSC_PRODUCT_REV)); } +#ifdef SDCARD_LUN +#if CIRCUITPY_SETTINGS_TOML +typedef enum { + SDCARD_USB_SETTING_NOT_YET_READ = 0, + SDCARD_USB_SETTING_TRUE, + SDCARD_USB_SETTING_FALSE, +} sdcard_usb_setting_state_t; + +static sdcard_usb_setting_state_t _sdcard_usb_setting_state = SDCARD_USB_SETTING_NOT_YET_READ; + +// Read only once to save file access time. +static bool sdcard_usb_enabled(void) { + if (_sdcard_usb_setting_state == SDCARD_USB_SETTING_NOT_YET_READ) { + bool setting = true; + (void)settings_get_bool("CIRCUITPY_SDCARD_USB", &setting); + _sdcard_usb_setting_state = setting ? SDCARD_USB_SETTING_TRUE : SDCARD_USB_SETTING_FALSE; + } + return _sdcard_usb_setting_state == SDCARD_USB_SETTING_TRUE; +} +#else +static bool sdcard_usb_enabled(void) { + return CIRCUITPY_SDCARD_USB; +} +#endif +#endif + // Invoked when received Test Unit Ready command. // return true allowing host to read/write this LUN e.g SD card inserted bool tud_msc_test_unit_ready_cb(uint8_t lun) { - if (lun > 1) { + if (lun >= LUN_COUNT) { return false; } @@ -212,7 +403,13 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) { if (current_mount == NULL) { return false; } - if (ejected[lun]) { + + if (ejected[lun] || eject_once[lun] || (lun == 0 && !storage_usb_enabled()) + #ifdef SDCARD_LUN + || (lun == SDCARD_LUN && !sdcard_usb_enabled()) + #endif + ) { + eject_once[lun] = false; // Set 0x3a for media not present. tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3A, 0x00); return false; @@ -225,7 +422,7 @@ bool tud_msc_test_unit_ready_cb(uint8_t lun) { // - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage // - Start = 1 : active mode, if load_eject = 1 : load disk storage bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject) { - if (lun > 1) { + if (lun >= LUN_COUNT) { return false; } fs_user_mount_t *current_mount = get_vfs(lun); diff --git a/supervisor/shared/web_workflow/static/serial.js b/supervisor/shared/web_workflow/static/serial.js index 52cde953961..c8ee2537bae 100644 --- a/supervisor/shared/web_workflow/static/serial.js +++ b/supervisor/shared/web_workflow/static/serial.js @@ -43,6 +43,8 @@ ws.onmessage = function(e) { } else if (e.data == "\x1b[K") { // Clear line log.textContent = log.textContent.slice(0, -left_count); left_count = 0; + } else if (e.data == "\x1b[2K\x1b[0G") { + // ignore } else { log.textContent += e.data; } diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 45d3c21163a..f88e3322e23 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -8,6 +8,8 @@ #define _GNU_SOURCE #include +#include +#include #include #include "extmod/vfs.h" @@ -42,12 +44,16 @@ #include "shared-bindings/socketpool/Socket.h" #include "shared-bindings/socketpool/SocketPool.h" +#if CIRCUITPY_HOSTNETWORK +#include "bindings/hostnetwork/__init__.h" +#endif + #if CIRCUITPY_WIFI #include "shared-bindings/wifi/__init__.h" #endif -#if CIRCUITPY_OS_GETENV -#include "shared-module/os/__init__.h" +#if CIRCUITPY_SETTINGS_TOML +#include "supervisor/shared/settings.h" #endif enum request_state { @@ -84,12 +90,18 @@ typedef struct { char websocket_key[24 + 1]; } _request; +#if CIRCUITPY_WIFI static wifi_radio_error_t _wifi_status = WIFI_RADIO_ERROR_NONE; +#endif -#if CIRCUITPY_STATUS_BAR +#if CIRCUITPY_STATUS_BAR && (CIRCUITPY_WIFI || CIRCUITPY_HOSTNETWORK) // Store various last states to compute if status bar needs an update. static bool _last_enabled = false; static uint32_t _last_ip = 0; +static mp_int_t _last_web_api_port = 80; +#endif + +#if CIRCUITPY_STATUS_BAR && CIRCUITPY_WIFI static wifi_radio_error_t _last_wifi_status = WIFI_RADIO_ERROR_NONE; #endif @@ -171,11 +183,7 @@ static bool _base64_in_place(char *buf, size_t in_len, size_t out_len) { return true; } -static void _update_encoded_ip(void) { - uint32_t ipv4_address = 0; - if (common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj)) { - ipv4_address = wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj); - } +static void _update_encoded_ip(uint32_t ipv4_address) { if (_encoded_ip != ipv4_address) { uint8_t *octets = (uint8_t *)&ipv4_address; snprintf(_our_ip_encoded, sizeof(_our_ip_encoded), "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]); @@ -183,75 +191,127 @@ static void _update_encoded_ip(void) { } } +static bool _get_web_workflow_ip(uint32_t *ipv4_address) { + *ipv4_address = 0; + #if CIRCUITPY_WIFI + if (!common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj)) { + return false; + } + *ipv4_address = wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj); + return true; + #elif CIRCUITPY_HOSTNETWORK + // hostnetwork uses the host network namespace and is reachable via localhost. + *ipv4_address = 0x0100007f; // 127.0.0.1 + return true; + #else + return false; + #endif +} + +#if CIRCUITPY_STATUS_BAR +static void _print_web_workflow_endpoint(void) { + mp_printf(&mp_plat_print, "%s", _our_ip_encoded); + if (web_api_port != 80) { + mp_printf(&mp_plat_print, ":%d", web_api_port); + } +} +#endif + mdns_server_obj_t *supervisor_web_workflow_mdns(mp_obj_t network_interface) { - #if CIRCUITPY_MDNS + #if CIRCUITPY_MDNS && CIRCUITPY_WIFI if (network_interface == &common_hal_wifi_radio_obj && mdns.base.type == &mdns_server_type) { return &mdns; } #endif + (void)network_interface; return NULL; } #if CIRCUITPY_STATUS_BAR bool supervisor_web_workflow_status_dirty(void) { - return common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj) != _last_enabled || - _encoded_ip != _last_ip || - _last_wifi_status != _wifi_status; + #if CIRCUITPY_WIFI || CIRCUITPY_HOSTNETWORK + uint32_t ipv4_address = 0; + bool enabled = _get_web_workflow_ip(&ipv4_address); + if (enabled != _last_enabled || ipv4_address != _last_ip || web_api_port != _last_web_api_port) { + return true; + } + #if CIRCUITPY_WIFI + if (_last_wifi_status != _wifi_status) { + return true; + } + #endif + return false; + #else + return false; + #endif } #endif #if CIRCUITPY_STATUS_BAR void supervisor_web_workflow_status(void) { - _last_enabled = common_hal_wifi_radio_get_enabled(&common_hal_wifi_radio_obj); + #if CIRCUITPY_WIFI || CIRCUITPY_HOSTNETWORK + uint32_t ipv4_address = 0; + _last_enabled = _get_web_workflow_ip(&ipv4_address); + _last_web_api_port = web_api_port; + if (_last_enabled) { - uint32_t ipv4_address = wifi_radio_get_ipv4_address(&common_hal_wifi_radio_obj); + _update_encoded_ip(ipv4_address); + _last_ip = _encoded_ip; + if (ipv4_address != 0) { - _update_encoded_ip(); - _last_ip = _encoded_ip; - mp_printf(&mp_plat_print, "%s", _our_ip_encoded); - if (web_api_port != 80) { - mp_printf(&mp_plat_print, ":%d", web_api_port); - } + _print_web_workflow_endpoint(); // TODO: Use these unicode to show signal strength: ▂▄▆█ return; } - serial_write_compressed(MP_ERROR_TEXT("Wi-Fi: ")); - _last_wifi_status = _wifi_status; - if (_wifi_status == WIFI_RADIO_ERROR_AUTH_EXPIRE || - _wifi_status == WIFI_RADIO_ERROR_AUTH_FAIL) { - serial_write_compressed(MP_ERROR_TEXT("Authentication failure")); - } else if (_wifi_status != WIFI_RADIO_ERROR_NONE) { - mp_printf(&mp_plat_print, "%d", _wifi_status); - } else if (ipv4_address == 0) { - _last_ip = 0; - serial_write_compressed(MP_ERROR_TEXT("No IP")); - } else { - } - } else { - // Keep Wi-Fi print separate so its data can be matched with the one above. - serial_write_compressed(MP_ERROR_TEXT("Wi-Fi: ")); + } + + #if CIRCUITPY_WIFI + serial_write_compressed(MP_ERROR_TEXT("Wi-Fi: ")); + _last_wifi_status = _wifi_status; + if (!_last_enabled) { serial_write_compressed(MP_ERROR_TEXT("off")); + } else if (_wifi_status == WIFI_RADIO_ERROR_AUTH_EXPIRE || + _wifi_status == WIFI_RADIO_ERROR_AUTH_FAIL) { + serial_write_compressed(MP_ERROR_TEXT("Authentication failure")); + } else if (_wifi_status != WIFI_RADIO_ERROR_NONE) { + mp_printf(&mp_plat_print, "%d", _wifi_status); + } else { + _last_ip = 0; + serial_write_compressed(MP_ERROR_TEXT("No IP")); } + #endif + #else + return; + #endif } #endif bool supervisor_start_web_workflow(void) { - #if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_WIFI && CIRCUITPY_OS_GETENV + #if CIRCUITPY_WEB_WORKFLOW && CIRCUITPY_SETTINGS_TOML && (CIRCUITPY_WIFI || CIRCUITPY_HOSTNETWORK) + + #if CIRCUITPY_WIFI + mp_obj_t socketpool_radio = MP_OBJ_FROM_PTR(&common_hal_wifi_radio_obj); + #else + mp_obj_t socketpool_radio = MP_OBJ_FROM_PTR(&common_hal_hostnetwork_obj); + #endif + + settings_err_t result; + #if CIRCUITPY_WIFI char ssid[33]; char password[64]; - os_getenv_err_t result = common_hal_os_getenv_str("CIRCUITPY_WIFI_SSID", ssid, sizeof(ssid)); - if (result != GETENV_OK) { + result = settings_get_str("CIRCUITPY_WIFI_SSID", ssid, sizeof(ssid)); + if (result != SETTINGS_OK || strlen(ssid) < 1) { return false; } - result = common_hal_os_getenv_str("CIRCUITPY_WIFI_PASSWORD", password, sizeof(password)); - if (result == GETENV_ERR_NOT_FOUND) { + result = settings_get_str("CIRCUITPY_WIFI_PASSWORD", password, sizeof(password)); + if (result == SETTINGS_ERR_NOT_FOUND) { // if password is unspecified, assume an open network password[0] = '\0'; - } else if (result != GETENV_OK) { + } else if (result != SETTINGS_OK) { return false; } @@ -275,31 +335,30 @@ bool supervisor_start_web_workflow(void) { common_hal_wifi_radio_set_enabled(&common_hal_wifi_radio_obj, false); return false; } + #endif - // Skip starting the workflow if we're not starting from power on or reset. + // Skip starting the workflow if the reset reason reflects a problem. const mcu_reset_reason_t reset_reason = common_hal_mcu_processor_get_reset_reason(); - if (reset_reason != RESET_REASON_POWER_ON && - reset_reason != RESET_REASON_RESET_PIN && - reset_reason != RESET_REASON_DEEP_SLEEP_ALARM && - reset_reason != RESET_REASON_UNKNOWN && - reset_reason != RESET_REASON_SOFTWARE) { + if (reset_reason == MCU_RESET_REASON_BROWNOUT || + reset_reason == MCU_RESET_REASON_WATCHDOG || + reset_reason == MCU_RESET_REASON_RESCUE_DEBUG) { return false; } bool initialized = pool.base.type == &socketpool_socketpool_type; if (!initialized) { - result = common_hal_os_getenv_str("CIRCUITPY_WEB_INSTANCE_NAME", web_instance_name, sizeof(web_instance_name)); - if (result != GETENV_OK || web_instance_name[0] == '\0') { + result = settings_get_str("CIRCUITPY_WEB_INSTANCE_NAME", web_instance_name, sizeof(web_instance_name)); + if (result != SETTINGS_OK || web_instance_name[0] == '\0') { strcpy(web_instance_name, MICROPY_HW_BOARD_NAME); } // (leaves new_port unchanged on any failure) - (void)common_hal_os_getenv_int("CIRCUITPY_WEB_API_PORT", &web_api_port); + (void)settings_get_int("CIRCUITPY_WEB_API_PORT", &web_api_port); const size_t api_password_len = sizeof(_api_password) - 1; - result = common_hal_os_getenv_str("CIRCUITPY_WEB_API_PASSWORD", _api_password + 1, api_password_len); - if (result == GETENV_OK) { + result = settings_get_str("CIRCUITPY_WEB_API_PASSWORD", _api_password + 1, api_password_len); + if (result == SETTINGS_OK) { _api_password[0] = ':'; _base64_in_place(_api_password, strlen(_api_password), sizeof(_api_password) - 1); } else { // Skip starting web-workflow when no password is passed. @@ -307,7 +366,7 @@ bool supervisor_start_web_workflow(void) { } pool.base.type = &socketpool_socketpool_type; - common_hal_socketpool_socketpool_construct(&pool, &common_hal_wifi_radio_obj); + common_hal_socketpool_socketpool_construct(&pool, socketpool_radio); socketpool_socket_reset(&listening); socketpool_socket_reset(&active); @@ -373,7 +432,7 @@ void web_workflow_send_raw(socketpool_socket_obj_t *socket, bool flush, const ui total_sent += sent; if (total_sent < len) { // Yield so that network code can run. - port_yield(); + port_task_sleep_ms(4); } } } @@ -825,7 +884,6 @@ static void _reply_with_devices_json(socketpool_socket_obj_t *socket, _request * "\"instance_name\": \"%s\", " "\"port\": %d, " "\"ip\": \"%d.%d.%d.%d\"}", hostname, instance_name, port, octets[0], octets[1], octets[2], octets[3]); - common_hal_mdns_remoteservice_deinit(&found_devices[i]); } #endif _send_chunk(socket, "]}"); @@ -847,7 +905,9 @@ static void _reply_with_version_json(socketpool_socket_obj_t *socket, _request * instance_name = common_hal_mdns_server_get_instance_name(&mdns); } #endif - _update_encoded_ip(); + uint32_t ipv4_address = 0; + (void)_get_web_workflow_ip(&ipv4_address); + _update_encoded_ip(ipv4_address); // Note: this leverages the fact that C concats consecutive string literals together. mp_printf(&_socket_print, "{\"web_api_version\": 4, " @@ -977,7 +1037,7 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req if (result == FR_NO_FILE) { new_file = true; result = f_open(fs, &active_file, path, FA_WRITE | FA_OPEN_ALWAYS); - } else { + } else if (result == FR_OK) { old_length = f_size(&active_file); } @@ -988,6 +1048,18 @@ static void _write_file_and_reply(socketpool_socket_obj_t *socket, _request *req _reply_missing(socket, request); return; } + if (result == FR_WRITE_PROTECTED) { + // The filesystem is held by something else with write access (most + // commonly USB-MSC: the host has CIRCUITPY mounted, so CircuitPython + // can't write through FatFS). Match the mkdir/move/delete paths and + // reply 409 Conflict so clients can show an actionable message + // ("eject CIRCUITPY / disable USB MSC") instead of a generic 500. + override_fattime(0); + filesystem_unlock(fs_mount); + _discard_incoming(socket, request->content_length); + _reply_conflict(socket, request); + return; + } if (result != FR_OK) { override_fattime(0); filesystem_unlock(fs_mount); @@ -1085,6 +1157,10 @@ static void _reply_static(socketpool_socket_obj_t *socket, _request *request, co "Content-Encoding: gzip\r\n", "Content-Length: ", encoded_len, "\r\n", "Content-Type: ", content_type, "\r\n", + #if CIRCUITPY_DEBUG == 0 + "Cache-Control: max-age=31536000\r\n", // Cache for a year. + "Vary: Accept\r\n", + #endif "\r\n", NULL); web_workflow_send_raw(socket, true, response, response_len); } diff --git a/supervisor/shared/web_workflow/web_workflow.h b/supervisor/shared/web_workflow/web_workflow.h index 439964dd333..9ec15a14ddc 100644 --- a/supervisor/shared/web_workflow/web_workflow.h +++ b/supervisor/shared/web_workflow/web_workflow.h @@ -8,7 +8,12 @@ #include +#if CIRCUITPY_MDNS #include "shared-bindings/mdns/Server.h" +#else +typedef struct mdns_server_obj mdns_server_obj_t; +#endif + #include "shared-bindings/socketpool/Socket.h" // This background function should be called repeatedly. It cannot be done based diff --git a/supervisor/shared/workflow.c b/supervisor/shared/workflow.c index df2055580fc..21dd0512eb1 100644 --- a/supervisor/shared/workflow.c +++ b/supervisor/shared/workflow.c @@ -18,13 +18,15 @@ #if CIRCUITPY_BLEIO #include "shared-bindings/_bleio/__init__.h" #include "supervisor/shared/bluetooth/bluetooth.h" -#if CIRCUITPY_SERIAL_BLE +#if CIRCUITPY_BLE_SERIAL_SERVICE #include "supervisor/shared/bluetooth/serial.h" #endif #endif -#if CIRCUITPY_TINYUSB || CIRCUITPY_USB_KEYBOARD_WORKFLOW +#if CIRCUITPY_USB_DEVICE || CIRCUITPY_USB_KEYBOARD_WORKFLOW #include "supervisor/usb.h" +#endif +#if CIRCUITPY_TINYUSB #include "tusb.h" #endif @@ -43,10 +45,12 @@ void supervisor_workflow_reset(void) { #if CIRCUITPY_WEB_WORKFLOW bool result = supervisor_start_web_workflow(); - if (workflow_background_cb.fun) { - if (result) { - supervisor_workflow_request_background(); + if (result) { + if (!workflow_background_cb.fun) { + // Enable background callbacks if web_workflow startup successful. + workflow_background_cb.fun = supervisor_web_workflow_background; } + supervisor_workflow_request_background(); } #endif } @@ -68,8 +72,8 @@ void supervisor_workflow_request_background(void) { bool supervisor_workflow_active(void) { #if CIRCUITPY_USB_DEVICE // Eventually there might be other non-USB workflows, such as BLE. - // tud_ready() checks for usb mounted and not suspended. - if (tud_ready()) { + // usb_connected() checks for usb mounted and not suspended. + if (usb_connected()) { return true; } #endif @@ -78,7 +82,7 @@ bool supervisor_workflow_active(void) { return true; } #endif - #if CIRCUITPY_SERIAL_BLE + #if CIRCUITPY_BLE_SERIAL_SERVICE if (ble_serial_connected()) { return true; } @@ -89,7 +93,7 @@ bool supervisor_workflow_active(void) { void supervisor_workflow_start(void) { // Start USB after giving boot.py a chance to tweak behavior. - #if CIRCUITPY_TINYUSB + #if CIRCUITPY_USB_DEVICE // Setup USB connection after heap is available. // It needs the heap to build descriptors. usb_init(); @@ -105,9 +109,10 @@ void supervisor_workflow_start(void) { #if CIRCUITPY_WEB_WORKFLOW if (supervisor_start_web_workflow()) { - // Enable background callbacks if web_workflow startup successful - memset(&workflow_background_cb, 0, sizeof(workflow_background_cb)); + // Enable background callbacks if web_workflow startup successful. workflow_background_cb.fun = supervisor_web_workflow_background; + // Kick the first background run now that the callback is installed. + supervisor_workflow_request_background(); } #endif diff --git a/supervisor/stub/misc.c b/supervisor/stub/misc.c deleted file mode 100644 index c0a2a87f9fe..00000000000 --- a/supervisor/stub/misc.c +++ /dev/null @@ -1,13 +0,0 @@ -// This file is part of the CircuitPython project: https://circuitpython.org -// -// SPDX-FileCopyrightText: Copyright (c) 2022 Jeff Epler for Adafruit Industries -// -// SPDX-License-Identifier: MIT -#include "stdbool.h" - -#include "supervisor/port.h" -#include "py/mpconfig.h" - - -MP_WEAK void port_post_boot_py(bool heap_valid) { -} diff --git a/supervisor/supervisor.mk b/supervisor/supervisor.mk index 50ce3f4c181..2d881dfe070 100644 --- a/supervisor/supervisor.mk +++ b/supervisor/supervisor.mk @@ -1,6 +1,5 @@ SRC_SUPERVISOR = \ main.c \ - lib/tlsf/tlsf.c \ supervisor/port.c \ supervisor/shared/background_callback.c \ supervisor/shared/board.c \ @@ -19,7 +18,14 @@ SRC_SUPERVISOR = \ supervisor/shared/traceback.c \ supervisor/shared/translate/translate.c \ supervisor/shared/workflow.c \ - supervisor/stub/misc.c \ + +ifeq ($(CIRCUITPY_SETTINGS_TOML),1) +SRC_SUPERVISOR += supervisor/shared/settings.c +endif + +ifeq ($(CIRCUITPY_LIB_TLSF),1) +SRC_SUPERVISOR += lib/tlsf/tlsf.c +endif # For tlsf CFLAGS += -D_DEBUG=0 @@ -45,7 +51,7 @@ ifeq ($(CIRCUITPY_BLEIO),1) ifeq ($(CIRCUITPY_BLE_FILE_SERVICE),1) SRC_SUPERVISOR += supervisor/shared/bluetooth/file_transfer.c endif - ifeq ($(CIRCUITPY_SERIAL_BLE),1) + ifeq ($(CIRCUITPY_BLE_SERIAL_SERVICE),1) SRC_SUPERVISOR += supervisor/shared/bluetooth/serial.c endif endif @@ -114,13 +120,13 @@ ifeq ($(CIRCUITPY_TINYUSB),1) lib/tinyusb/src/common/tusb_fifo.c \ lib/tinyusb/src/tusb.c \ supervisor/usb.c \ + supervisor/shared/usb.c \ supervisor/shared/usb/usb.c \ ifeq ($(CIRCUITPY_USB_DEVICE),1) SRC_SUPERVISOR += \ lib/tinyusb/src/class/cdc/cdc_device.c \ lib/tinyusb/src/device/usbd.c \ - lib/tinyusb/src/device/usbd_control.c \ supervisor/shared/usb/usb_desc.c \ supervisor/shared/usb/usb_device.c \ @@ -142,6 +148,7 @@ ifeq ($(CIRCUITPY_TINYUSB),1) shared-bindings/usb_hid/Device.c \ shared-module/usb_hid/__init__.c \ shared-module/usb_hid/Device.c \ + shared-module/usb_hid/report_descriptors.c \ endif @@ -175,6 +182,20 @@ ifeq ($(CIRCUITPY_TINYUSB),1) CFLAGS += -DCFG_TUD_VIDEO=1 -DCFG_TUD_VIDEO_STREAMING=1 -DCFG_TUD_VIDEO_STREAMING_EP_BUFSIZE=256 -DCFG_TUD_VIDEO_STREAMING_BULK=1 endif + ifeq ($(CIRCUITPY_USB_AUDIO), 1) + SRC_SUPERVISOR += \ + shared-bindings/usb_audio/__init__.c \ + shared-module/usb_audio/__init__.c \ + shared-bindings/usb_audio/USBMicrophone.c \ + shared-module/usb_audio/USBMicrophone.c \ + shared-bindings/usb_audio/USBSpeaker.c \ + shared-module/usb_audio/USBSpeaker.c \ + lib/tinyusb/src/class/audio/audio_device.c \ + + # The CFG_TUD_AUDIO_* class driver settings are defined in + # supervisor/shared/usb/tusb_config.h, gated on CIRCUITPY_USB_AUDIO. + endif + ifeq ($(CIRCUITPY_USB_VENDOR), 1) SRC_SUPERVISOR += \ @@ -257,12 +278,10 @@ ifeq ($(CIRCUITPY_USB_CDC),1) CFLAGS += -DCFG_TUD_CDC=2 endif -USB_HIGHSPEED ?= 0 -CFLAGS += -DUSB_HIGHSPEED=$(USB_HIGHSPEED) - $(BUILD)/supervisor/shared/translate/translate.o: $(HEADER_BUILD)/qstrdefs.generated.h $(HEADER_BUILD)/compressed_translations.generated.h CIRCUITPY_DISPLAY_FONT ?= "../../tools/fonts/ter-u12n.bdf" +CIRCUITPY_FONT_EXTRA_CHARACTERS ?= "" $(BUILD)/autogen_display_resources-$(TRANSLATION).c: ../../tools/gen_display_resources.py $(TOP)/locale/$(TRANSLATION).po Makefile | $(HEADER_BUILD) $(STEPECHO) "GEN $@" @@ -270,4 +289,5 @@ $(BUILD)/autogen_display_resources-$(TRANSLATION).c: ../../tools/gen_display_res $(Q)$(PYTHON) ../../tools/gen_display_resources.py \ --font $(CIRCUITPY_DISPLAY_FONT) \ --sample_file $(TOP)/locale/$(TRANSLATION).po \ + --extra_characters $(CIRCUITPY_FONT_EXTRA_CHARACTERS) \ --output_c_file $@ diff --git a/supervisor/usb.h b/supervisor/usb.h index 0b0fabb5d60..d6e4236c9b4 100644 --- a/supervisor/usb.h +++ b/supervisor/usb.h @@ -48,6 +48,7 @@ typedef struct { bool usb_enabled(void); void usb_add_interface_string(uint8_t interface_string_index, const char str[]); bool usb_build_descriptors(const usb_identification_t *identification); +bool usb_connected(void); void usb_disconnect(void); void usb_init(void); void usb_set_defaults(void); @@ -61,9 +62,13 @@ void usb_setup_with_vm(void); // Propagate plug/unplug events to the MSC logic. #if CIRCUITPY_USB_DEVICE && CIRCUITPY_USB_MSC +size_t usb_msc_descriptor_length(void); +size_t usb_msc_add_descriptor(uint8_t *descriptor_buf, descriptor_counts_t *descriptor_counts, uint8_t *current_interface_string); void usb_msc_mount(void); void usb_msc_umount(void); -bool usb_msc_ejected(void); + +#include "extmod/vfs_fat.h" +void usb_msc_remount(fs_user_mount_t *fs_mount); #endif #if CIRCUITPY_USB_KEYBOARD_WORKFLOW @@ -71,6 +76,8 @@ void usb_keyboard_init(void); uint32_t usb_keyboard_chars_available(void); char usb_keyboard_read_char(void); +void usb_keyboard_status(void); + bool usb_keyboard_in_use(uint8_t dev_addr, uint8_t interface); void usb_keyboard_detach(uint8_t dev_addr, uint8_t interface); void usb_keyboard_attach(uint8_t dev_addr, uint8_t interface); diff --git a/tests/README.md b/tests/README.md index 54dd078053e..534e7e0a059 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,7 +1,46 @@ # MicroPython Test Suite -This directory contains tests for various functionality areas of MicroPython. -To run all stable tests, run "run-tests.py" script in this directory. +This directory contains tests for most parts of MicroPython. To run it you will need +CPython 3.8.2 or newer, which is used to validate MicroPython's behaviour. + +To run all stable tests, run the "run-tests.py" script in this directory. By default +that will run the test suite against the unix port of MicroPython. + +To run the test suite against a bare-metal target (a board running MicroPython firmware) +use the `-t` option to specify the serial port. This will automatically detect the +target platform and run the appropriate set of tests for that platform. For example: + + $ ./run-tests.py -t /dev/ttyACM0 + +That will run tests on the `/dev/ttyACM0` serial port. You can also use shortcut +device names like `a` for `/dev/ttyACM` and `c` for `COM`. Use +`./run-tests.py --help` to see all of the device possibilities, and other options. + +There are three kinds of tests: + +* Tests that use `unittest`: these tests require `unittest` to be installed on the + target (eg via `mpremote mip install unittest`), and are used to test things that are + MicroPython-specific, such as behaviour that is different to CPython, modules that + aren't available in CPython, and hardware tests. These tests are run only under + MicroPython and the test passes if the `unittest` runner prints "OK" at the end of the + run. Other output may be printed, eg for use as diagnostics, and this output does not + affect the result of the test. + +* Tests with a corresponding `.exp` file: similar to the `unittest` tests, these tests + are for features that generally cannot be run under CPython. In this case the test is + run under MicroPython only and the output from MicroPython is compared against the + provided `.exp` file. The test passes if the output matches exactly. + +* Tests without a corresponding `.exp` file (and don't use `unittest`): these tests are + used to test MicroPython behaviour that should precisely match CPython. These tests + are first run under CPython and the output captured, and then run under MicroPython + and the output compared to the CPython output. The test passes if the output matches + exactly. If the output differs then the test fails and the outputs are saved in a + `.exp` and a `.out` file respectively. + +In all three cases above, the test can usually be run directly on the target MicroPython +instance, either using the unix port with `micropython `, or on a board with +`mpremote run `. This is useful for creating and debugging tests. Tests of capabilities not supported on all platforms should be written to check for the capability being present. If it is not, the test @@ -15,15 +54,6 @@ condition a test. The run-tests.py script uses small scripts in the feature_check directory to check whether each such feature is present, and skips the relevant tests if not. -Tests are generally verified by running the test both in MicroPython and -in CPython and comparing the outputs. If the output differs the test fails -and the outputs are saved in a .out and a .exp file respectively. -For tests that cannot be run in CPython, for example because they use -the machine module, a .exp file can be provided next to the test's .py -file. A convenient way to generate that is to run the test, let it fail -(because CPython cannot run it) and then copy the .out file (but not -before checking it manually!) - When creating new tests, anything that relies on float support should go in the float/ subdirectory. Anything that relies on import x, where x is not a built-in module, should go in the import/ subdirectory. @@ -38,16 +68,14 @@ for a full list of command line options. ### Benchmarking a target -To run tests on a firmware target using `pyboard.py`, run the command line like +To run tests on a firmware target using a serial port, run the command line like this: ``` -./run-perfbench.py -p -d /dev/ttyACM0 168 100 +./run-perfbench.py -t /dev/ttyACM0 168 100 ``` -* `-p` indicates running on a remote target via pyboard.py, not the host. -* `-d PORTNAME` is the serial port, `/dev/ttyACM0` is the default if not - provided. +* `-t PORTNAME` is the serial port to use (and it supports shorthand like `a0`). * `168` is value `N`, the approximate CPU frequency in MHz (in this case Pyboard V1.1 is 168MHz). It's possible to choose other values as well: lower values like `10` will run much the tests much quicker, higher values like `1000` will @@ -107,11 +135,11 @@ Usually you want to know if something is faster or slower than a reference. To do this, copy the output of each `run-perfbench.py` run to a text file. This can be done multiple ways, but one way on Linux/macOS is with the `tee` -utility: `./run-perfbench.py -p 168 100 | tee pyb-run1.txt` +utility: `./run-perfbench.py -t a0 168 100 | tee pyb-run1.txt` Once you have two files with output from two different runs (maybe with different code or configuration), compare the runtimes with `./run-perfbench.py --t pybv-run1.txt pybv-run2.txt` or compare scores with `./run-perfbench.py -s +-m pybv-run1.txt pybv-run2.txt` or compare scores with `./run-perfbench.py -s pybv-run1.txt pybv-run2.txt`: ``` @@ -175,15 +203,37 @@ internal_bench/bytebuf: 1 tests performed (3 individual testcases) ``` +## Serial reliability and performance test + +Serial port reliability and performance can be tested using the `serial_test.py` script. +Pass the name of the port to test against, for example: + + $ ./serial_test.py -t /dev/ttyACM0 + +If no port is specified then `/dev/ttyACM0` is used as the default. + +The test will send data out to the target, and receive data from the target, in various +chunk sizes. The throughput of the serial connection will be reported for each sub-test. + ## Test key/certificates -SSL/TLS tests in `multi_net` and `net_inet` use a -self-signed key/cert pair that is randomly generated and to be used for -testing/demonstration only. You should always generate your own key/cert. +SSL/TLS tests in `multi_net` and `net_inet` use self-signed key/cert pairs +that are randomly generated to be used for testing/demonstration only. + +To run tests on-device the `.der` files should be copied and the current time +set to ensure certs validity. This can be done with: +``` +$ mpremote rtc --set cp multi_net/*.der net_inet/*.der : +``` + +### Generating new test key/certificates + +The keys used for the unit tests are included in the tests folders so don't generally +need to be re-created by end users. This section is included here for reference only. -To generate a new self-signed RSA key/cert pair with openssl do: +A new self-signed RSA key/cert pair can be created with openssl: ``` -$ openssl req -x509 -newkey rsa:2048 -keyout rsa_key.pem -out rsa_cert.pem -days 365 -nodes -subj '/CN=micropython.local/O=MicroPython/C=AU' +$ openssl req -x509 -newkey rsa:2048 -keyout rsa_key.pem -out rsa_cert.pem -days 3650 -nodes -subj '/CN=micropython.local/O=MicroPython/C=AU' ``` In this case CN is: micropython.local @@ -193,8 +243,9 @@ $ openssl pkey -in rsa_key.pem -out rsa_key.der -outform DER $ openssl x509 -in rsa_cert.pem -out rsa_cert.der -outform DER ``` -To test elliptic curve key/cert pairs, create a key then a certificate using: +For elliptic curve tests using key/cert pairs, create a key then a certificate using: ``` -$ openssl ecparam -name prime256v1 -genkey -noout -out ec_key.der -outform DER -$ openssl req -new -x509 -key ec_key.der -out ec_cert.der -outform DER -days 365 -nodes -subj '/CN=micropython.local/O=MicroPython/C=AU' +$ openssl ecparam -name prime256v1 -genkey -noout -out ec_key.pem +$ openssl pkey -in ec_key.pem -out ec_key.der -outform DER +$ openssl req -new -x509 -key ec_key.pem -out ec_cert.der -outform DER -days 3650 -nodes -subj '/CN=micropython.local/O=MicroPython/C=AU' ``` diff --git a/tests/basics/annotate_var.py.exp b/tests/basics/annotate_var.py.exp deleted file mode 100644 index 9b6536e966b..00000000000 --- a/tests/basics/annotate_var.py.exp +++ /dev/null @@ -1,5 +0,0 @@ -False -1 -(1, 2) -NameError -1 diff --git a/tests/basics/array_add.py b/tests/basics/array_add.py index 76ce59f761e..e78615541c3 100644 --- a/tests/basics/array_add.py +++ b/tests/basics/array_add.py @@ -14,3 +14,9 @@ a1.extend(array.array('I', [5])) print(a1) + +a1.extend([6, 7]) +print(a1) + +a1.extend(i for i in (8, 9)) +print(a1) diff --git a/tests/basics/assign_expr.py.exp b/tests/basics/assign_expr.py.exp deleted file mode 100644 index 47da56b80d4..00000000000 --- a/tests/basics/assign_expr.py.exp +++ /dev/null @@ -1,16 +0,0 @@ -4 -True -2 -4 5 -5 -1 5 5 -5 -2 1 -1 0 -any True -8 -123 -any True -8 -[(1, 0), (2, 2), (3, 6), (4, 12)] -4 diff --git a/tests/basics/assign_expr_scope.py.exp b/tests/basics/assign_expr_scope.py.exp deleted file mode 100644 index 5c780b38221..00000000000 --- a/tests/basics/assign_expr_scope.py.exp +++ /dev/null @@ -1,23 +0,0 @@ -scope0 -1 -None -scope1 -[1] -1 -None -scope2 -[0, 1] -1 -1 -scope3 -[0, 1] -None -None -scope4 -[0, 1] -1 -1 -scope5 -[0, 1] -1 -None diff --git a/tests/basics/async_await.py.exp b/tests/basics/async_await.py.exp deleted file mode 100644 index b51c388a933..00000000000 --- a/tests/basics/async_await.py.exp +++ /dev/null @@ -1,32 +0,0 @@ -4 -3 -2 -1 -0 -0 -1 -0 -0 -2 -1 -0 -0 -1 -0 -0 -3 -2 -1 -0 -0 -1 -0 -0 -2 -1 -0 -0 -1 -0 -0 -finished diff --git a/tests/basics/async_await2.py.exp b/tests/basics/async_await2.py.exp deleted file mode 100644 index fc9ff0aa535..00000000000 --- a/tests/basics/async_await2.py.exp +++ /dev/null @@ -1,5 +0,0 @@ -wait value: 1 -return from send: message from wait(1) -wait got back: message from main -x = 100 -got StopIteration diff --git a/tests/basics/async_def.py.exp b/tests/basics/async_def.py.exp deleted file mode 100644 index f555ace99ab..00000000000 --- a/tests/basics/async_def.py.exp +++ /dev/null @@ -1,3 +0,0 @@ -decorator -foo -StopIteration diff --git a/tests/basics/async_for.py.exp b/tests/basics/async_for.py.exp deleted file mode 100644 index 6f59979c065..00000000000 --- a/tests/basics/async_for.py.exp +++ /dev/null @@ -1,51 +0,0 @@ -== start == -init -aiter -init -anext -a -anext -b -anext -c -anext -== finish == -== start == -init -aiter -init -anext -d -anext -e -anext -f -anext -AsyncIteratorWrapper-def -== finish == -init -== start == -aiter -init -anext -g -anext -h -anext -i -anext -AsyncIteratorWrapper-ghi -== finish == -init -== start == -aiter -init -anext -j -anext -k -anext -l -anext -AsyncIteratorWrapper-jkl -== finish == diff --git a/tests/basics/async_for2.py b/tests/basics/async_for2.py index bbdb02c49b2..82232d52fc2 100644 --- a/tests/basics/async_for2.py +++ b/tests/basics/async_for2.py @@ -1,7 +1,7 @@ # test waiting within "async for" __anext__ function # CIRCUITPY-CHANGE -# uPy allows normal generators to be awaitables. +# MicroPython allows normal generators to be awaitables. # CircuitPython does not. # In CircuitPython you need to have an __await__ method on an awaitable like in CPython; # and like in CPython, generators do not have __await__. diff --git a/tests/basics/async_for2.py.exp b/tests/basics/async_for2.py.exp deleted file mode 100644 index 52bbe90c853..00000000000 --- a/tests/basics/async_for2.py.exp +++ /dev/null @@ -1,32 +0,0 @@ -init -aiter -anext -f start: 20 -coro yielded: 21 -coro yielded: 22 -f returned: 23 -x 0 -anext -f start: 20 -coro yielded: 21 -coro yielded: 22 -f returned: 23 -x 1 -anext -f start: 20 -coro yielded: 21 -coro yielded: 22 -f returned: 23 -x 2 -anext -f start: 20 -coro yielded: 21 -coro yielded: 22 -f returned: 23 -x 3 -anext -f start: 20 -coro yielded: 21 -coro yielded: 22 -f returned: 23 -finished diff --git a/tests/basics/async_syntaxerror.py.exp b/tests/basics/async_syntaxerror.py.exp deleted file mode 100644 index 5275689b413..00000000000 --- a/tests/basics/async_syntaxerror.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -SyntaxError -SyntaxError diff --git a/tests/basics/async_with.py.exp b/tests/basics/async_with.py.exp deleted file mode 100644 index 6bbf84cb4b5..00000000000 --- a/tests/basics/async_with.py.exp +++ /dev/null @@ -1,11 +0,0 @@ -enter -body -exit None None -finished -enter -1 -exit error -ValueError -enter -exit -BaseException diff --git a/tests/basics/async_with2.py b/tests/basics/async_with2.py index 5bac38236fe..b18fa6bdee1 100644 --- a/tests/basics/async_with2.py +++ b/tests/basics/async_with2.py @@ -1,7 +1,7 @@ # test waiting within async with enter/exit functions # CIRCUITPY-CHANGE -# uPy allows normal generators to be awaitables. +# MicroPython allows normal generators to be awaitables. # CircuitPython does not. # In CircuitPython you need to have an __await__ method on an awaitable like in CPython; # and like in CPython, generators do not have __await__. diff --git a/tests/basics/async_with2.py.exp b/tests/basics/async_with2.py.exp deleted file mode 100644 index 76b173b4c24..00000000000 --- a/tests/basics/async_with2.py.exp +++ /dev/null @@ -1,17 +0,0 @@ -enter -f start: 10 -coro yielded: 11 -coro yielded: 12 -f returned: 13 -body start -f start: 30 -coro yielded: 31 -coro yielded: 32 -body f returned: 33 -body end -exit None None -f start: 20 -coro yielded: 21 -coro yielded: 22 -f returned: 23 -finished diff --git a/tests/basics/async_with_break.py.exp b/tests/basics/async_with_break.py.exp deleted file mode 100644 index d077a88fad0..00000000000 --- a/tests/basics/async_with_break.py.exp +++ /dev/null @@ -1,15 +0,0 @@ -enter -body -exit None None -finished -enter -body -exit None None -finally -finished -enter -body -exit None None -finally inner -finally outer -finished diff --git a/tests/basics/async_with_return.py.exp b/tests/basics/async_with_return.py.exp deleted file mode 100644 index d077a88fad0..00000000000 --- a/tests/basics/async_with_return.py.exp +++ /dev/null @@ -1,15 +0,0 @@ -enter -body -exit None None -finished -enter -body -exit None None -finally -finished -enter -body -exit None None -finally inner -finally outer -finished diff --git a/tests/basics/attrtuple2.py b/tests/basics/attrtuple2.py new file mode 100644 index 00000000000..081d24b6ae9 --- /dev/null +++ b/tests/basics/attrtuple2.py @@ -0,0 +1,25 @@ +# test os.uname() attrtuple, if available +try: + import os +except ImportError: + print("SKIP") + raise SystemExit + +try: + u = os.uname() +except AttributeError: + print("SKIP") + raise SystemExit + +# test printing of attrtuple +print(str(u).find("machine=") > 0) + +# test read attr +print(isinstance(u.machine, str)) + +# test str modulo operator for attrtuple +impl_str = ("%s " * len(u)) % u +test_str = "" +for val in u: + test_str += val + " " +print(impl_str == test_str) diff --git a/tests/basics/boundmeth1.py b/tests/basics/boundmeth1.py index fe1b454688d..9f08d9bbb25 100644 --- a/tests/basics/boundmeth1.py +++ b/tests/basics/boundmeth1.py @@ -1,6 +1,6 @@ # tests basics of bound methods -# uPy and CPython differ when printing a bound method, so just print the type +# MicroPython and CPython differ when printing a bound method, so just print the type print(type(repr([].append))) diff --git a/tests/basics/builtin_help.py b/tests/basics/builtin_help.py index 6ec39653fe9..3d4e4f26bd2 100644 --- a/tests/basics/builtin_help.py +++ b/tests/basics/builtin_help.py @@ -14,4 +14,10 @@ help(micropython) # help for a module help('modules') # list available modules +class A: + x = 1 + y = 2 + del x +help(A) + print('done') # so last bit of output is predictable diff --git a/tests/basics/builtin_pow3_intbig.py b/tests/basics/builtin_pow3_intbig.py index bedc8b36b7e..41d2acbc0cc 100644 --- a/tests/basics/builtin_pow3_intbig.py +++ b/tests/basics/builtin_pow3_intbig.py @@ -20,3 +20,8 @@ print(hex(pow(y, x-1, x))) # Should be 1, since x is prime print(hex(pow(y, y-1, x))) # Should be a 'big value' print(hex(pow(y, y-1, y))) # Should be a 'big value' + +try: + print(pow(1, 2, 0)) +except ValueError: + print("ValueError") diff --git a/tests/basics/builtin_range.py b/tests/basics/builtin_range.py index 66226bad16a..9608a816310 100644 --- a/tests/basics/builtin_range.py +++ b/tests/basics/builtin_range.py @@ -32,13 +32,29 @@ print(range(1, 4)[0:]) print(range(1, 4)[1:]) print(range(1, 4)[:-1]) +print(range(4, 1)[:]) +print(range(4, 1)[0:]) +print(range(4, 1)[1:]) +print(range(4, 1)[:-1]) print(range(7, -2, -4)[:]) print(range(1, 100, 5)[5:15:3]) print(range(1, 100, 5)[15:5:-3]) print(range(100, 1, -5)[5:15:3]) print(range(100, 1, -5)[15:5:-3]) +print(range(1, 100, 5)[5:15:-3]) +print(range(1, 100, 5)[15:5:3]) +print(range(100, 1, -5)[5:15:-3]) +print(range(100, 1, -5)[15:5:3]) +print(range(1, 100, 5)[5:15:3]) +print(range(1, 100, 5)[15:5:-3]) +print(range(1, 100, -5)[5:15:3]) +print(range(1, 100, -5)[15:5:-3]) +print(range(1, 100, 5)[5:15:-3]) +print(range(1, 100, 5)[15:5:3]) +print(range(1, 100, -5)[5:15:-3]) +print(range(1, 100, -5)[15:5:3]) -# for this case uPy gives a different stop value but the listed elements are still correct +# for this case MicroPython gives a different stop value but the listed elements are still correct print(list(range(7, -2, -4)[2:-2:])) # zero step diff --git a/tests/basics/builtin_range_maxsize.py b/tests/basics/builtin_range_maxsize.py new file mode 100644 index 00000000000..b0f3a5e5129 --- /dev/null +++ b/tests/basics/builtin_range_maxsize.py @@ -0,0 +1,38 @@ +try: + from sys import maxsize +except ImportError: + print("SKIP") + raise SystemExit + +# Test the range builtin at extreme values. (https://github.com/micropython/micropython/issues/17684) +# +# This is written using asserts instead of prints because the value of `maxsize` differs. +# +# Numbers & counts right up against the max of mp_int_t also cause overflows, such as +# objrange.c:115:14: runtime error: signed integer overflow: 9223372036854775807 + 1 cannot be represented in type 'long int' +# so just avoid them for the purposes of this test. + +r = range(-maxsize + 1, -1) +assert r.start == -maxsize + 1 +assert r.stop == -1 +assert r[0] == -maxsize + 1 +assert r[1] == -maxsize + 2 +assert r[-1] == -2 +assert r[-2] == -3 + +ir = iter(r) +assert next(ir) == -maxsize + 1 +assert next(ir) == -maxsize + 2 + +r = range(0, maxsize - 1) +assert len(r) == maxsize - 1 +assert r.stop == maxsize - 1 + +r = range(maxsize, 0, -1) +assert len(r) == maxsize +assert r.start == maxsize +assert r[0] == maxsize +assert r[1] == maxsize - 1 +ir = iter(r) +assert next(ir) == maxsize +assert next(ir) == maxsize - 1 diff --git a/tests/basics/builtin_setattr.py b/tests/basics/builtin_setattr.py index e4acb14cac3..2c9a452c327 100644 --- a/tests/basics/builtin_setattr.py +++ b/tests/basics/builtin_setattr.py @@ -21,5 +21,5 @@ def __init__(self): try: setattr(int, 'to_bytes', 1) except (AttributeError, TypeError): - # uPy raises AttributeError, CPython raises TypeError + # MicroPython raises AttributeError, CPython raises TypeError print('AttributeError/TypeError') diff --git a/tests/basics/builtin_slice.py b/tests/basics/builtin_slice.py index 3ff3c3dd04d..cbce3d14ed6 100644 --- a/tests/basics/builtin_slice.py +++ b/tests/basics/builtin_slice.py @@ -1,11 +1,44 @@ # test builtin slice +# ensures that slices passed to user types are heap-allocated and can be +# safely stored as well as not overridden by subsequent slices. + # print slice class A: def __getitem__(self, idx): - print(idx) + print("get", idx) + print("abc"[1:]) + print("get", idx) + return idx + + def __setitem__(self, idx, value): + print("set", idx) + print("abc"[1:]) + print("set", idx) + self.saved_idx = idx + return idx + + def __delitem__(self, idx): + print("del", idx) + print("abc"[1:]) + print("del", idx) return idx -s = A()[1:2:3] + + +a = A() +s = a[1:2:3] +a[4:5:6] = s +del a[7:8:9] + +print(a.saved_idx) + +# nested slicing +print(A()[1 : A()[A()[2:3:4] : 5]]) + +# tuple slicing +a[1:2, 4:5, 7:8] +a[1, 4:5, 7:8, 2] +a[1:2, a[3:4], 5:6] # check type print(type(s) is slice) diff --git a/tests/basics/builtin_str_hex.py b/tests/basics/builtin_str_hex.py index 7390c8eaee1..9455883012c 100644 --- a/tests/basics/builtin_str_hex.py +++ b/tests/basics/builtin_str_hex.py @@ -20,5 +20,20 @@ "08090a0b0c0d0e0f", "7f80ff", "313233344142434461626364", + "ab\tcd\n ef ", + "ab cd ef", + "ab cd ef ", + " ab cd ef ", + # Invalid hex strings: + "abcde", # Odd number of hex digits + "ab cd e", + "a b cd ef", # Spaces between hex pairs + "ab cd e f ", + "abga", # Invalid hex digits + "ab_cd", + "ab:cd", ): - print(bytes.fromhex(x)) + try: + print(bytes.fromhex(x)) + except ValueError as e: + print("ValueError:", e) diff --git a/tests/basics/builtin_str_hex.py.exp b/tests/basics/builtin_str_hex.py.exp index 990dd857076..0309cad02d1 100644 --- a/tests/basics/builtin_str_hex.py.exp +++ b/tests/basics/builtin_str_hex.py.exp @@ -26,3 +26,14 @@ b'\x00\x01\x02\x03\x04\x05\x06\x07' b'\x08\t\n\x0b\x0c\r\x0e\x0f' b'\x7f\x80\xff' b'1234ABCDabcd' +b'\xab\xcd\xef' +b'\xab\xcd\xef' +b'\xab\xcd\xef' +b'\xab\xcd\xef' +ValueError: non-hex digit +ValueError: non-hex digit +ValueError: non-hex digit +ValueError: non-hex digit +ValueError: non-hex digit +ValueError: non-hex digit +ValueError: non-hex digit diff --git a/tests/basics/builtin_super.py b/tests/basics/builtin_super.py new file mode 100644 index 00000000000..5f7c3ae017e --- /dev/null +++ b/tests/basics/builtin_super.py @@ -0,0 +1,15 @@ +# Check that super rejects invalid arguments. +try: + super(str, 0) +except TypeError: + print("TypeError") + +try: + super(str, int) +except TypeError: + print("TypeError") + +try: + super(0, int) +except TypeError: + print("TypeError") diff --git a/tests/basics/bytes_format_modulo.py.exp b/tests/basics/bytes_format_modulo.py.exp deleted file mode 100644 index 782b7f91fcb..00000000000 --- a/tests/basics/bytes_format_modulo.py.exp +++ /dev/null @@ -1,5 +0,0 @@ -b'%' -b'=1=' -b'=1=2=' -b'=str=' -b"=b'str'=" diff --git a/tests/basics/class_bind_self.py b/tests/basics/class_bind_self.py index 813f876446e..8bece902ca2 100644 --- a/tests/basics/class_bind_self.py +++ b/tests/basics/class_bind_self.py @@ -52,7 +52,7 @@ def f4(self, arg): # generator print(C.f8(13)) print(C.f9(14)) -# not working in uPy +# not working in MicroPython #class C(list): # # this acts like a method and binds self # f1 = list.extend diff --git a/tests/basics/class_descriptor.py b/tests/basics/class_descriptor.py index 54f386230fe..feaed2fbb2a 100644 --- a/tests/basics/class_descriptor.py +++ b/tests/basics/class_descriptor.py @@ -1,34 +1,67 @@ class Descriptor: def __get__(self, obj, cls): - print('get') + print("get") print(type(obj) is Main) print(cls is Main) - return 'result' + return "result" def __set__(self, obj, val): - print('set') + print("set") print(type(obj) is Main) print(val) def __delete__(self, obj): - print('delete') + print("delete") print(type(obj) is Main) + def __set_name__(self, owner, name): + print("set_name", name) + print(owner.__name__ == "Main") + + class Main: Forward = Descriptor() + m = Main() try: m.__class__ except AttributeError: + # Target doesn't support __class__. print("SKIP") raise SystemExit r = m.Forward -if 'Descriptor' in repr(r.__class__): - print('SKIP') +if "Descriptor" in repr(r.__class__): + # Target doesn't support descriptors. + print("SKIP") raise SystemExit +# Test assignment and deletion. + print(r) -m.Forward = 'a' +m.Forward = "a" del m.Forward + +# Test that lookup of descriptors like __get__ are not passed into __getattr__. + + +class NonDescriptor: + def __getattr__(self, attr): + print("getattr", attr) + + +class TestClass: + non_descriptor = NonDescriptor() + + +print(isinstance(TestClass().non_descriptor, NonDescriptor)) + +t = TestClass() +t.non_descriptor = 123 +print(t.non_descriptor) + +try: + del TestClass().non_descriptor +except AttributeError: + print("AttributeError") diff --git a/tests/basics/class_inplace_op2.py.exp b/tests/basics/class_inplace_op2.py.exp deleted file mode 100644 index 8c323b5178e..00000000000 --- a/tests/basics/class_inplace_op2.py.exp +++ /dev/null @@ -1,12 +0,0 @@ -__imul__ -__imatmul__ -__ifloordiv__ -__itruediv__ -__imod__ -__ipow__ -__ior__ -__ixor__ -__iand__ -__ilshift__ -__irshift__ -TypeError diff --git a/tests/basics/class_ordereddict.py.exp b/tests/basics/class_ordereddict.py.exp deleted file mode 100644 index b723e327515..00000000000 --- a/tests/basics/class_ordereddict.py.exp +++ /dev/null @@ -1 +0,0 @@ -['a', 'b', 'c', 'd', 'e'] diff --git a/tests/basics/class_setname_hazard.py b/tests/basics/class_setname_hazard.py new file mode 100644 index 00000000000..77c04093462 --- /dev/null +++ b/tests/basics/class_setname_hazard.py @@ -0,0 +1,182 @@ +# Test that __set_name__ can access and mutate its owner argument. + + +def skip_if_no_descriptors(): + class Descriptor: + def __get__(self, obj, cls): + return + + class TestClass: + Forward = Descriptor() + + a = TestClass() + try: + a.__class__ + except AttributeError: + # Target doesn't support __class__. + print("SKIP") + raise SystemExit + + b = a.Forward + if "Descriptor" in repr(b.__class__): + # Target doesn't support descriptors. + print("SKIP") + raise SystemExit + + +skip_if_no_descriptors() + + +# Test basic accesses and mutations. + + +class GetSibling: + def __set_name__(self, owner, name): + print(getattr(owner, name + "_sib")) + + +class GetSiblingTest: + desc = GetSibling() + desc_sib = 111 + + +t110 = GetSiblingTest() + + +class SetSibling: + def __set_name__(self, owner, name): + setattr(owner, name + "_sib", 121) + + +class SetSiblingTest: + desc = SetSibling() + + +t120 = SetSiblingTest() + +print(t120.desc_sib) + + +class DelSibling: + def __set_name__(self, owner, name): + delattr(owner, name + "_sib") + + +class DelSiblingTest: + desc = DelSibling() + desc_sib = 131 + + +t130 = DelSiblingTest() + +try: + print(t130.desc_sib) +except AttributeError: + print("AttributeError") + + +class GetSelf: + x = 211 + + def __set_name__(self, owner, name): + print(getattr(owner, name).x) + + +class GetSelfTest: + desc = GetSelf() + + +t210 = GetSelfTest() + + +class SetSelf: + def __set_name__(self, owner, name): + setattr(owner, name, 221) + + +class SetSelfTest: + desc = SetSelf() + + +t220 = SetSelfTest() + +print(t220.desc) + + +class DelSelf: + def __set_name__(self, owner, name): + delattr(owner, name) + + +class DelSelfTest: + desc = DelSelf() + + +t230 = DelSelfTest() + +try: + print(t230.desc) +except AttributeError: + print("AttributeError") + + +# Test exception behavior. + + +class Raise: + def __set_name__(self, owner, name): + raise Exception() + + +try: + + class RaiseTest: + desc = Raise() +except Exception as e: # CPython raises RuntimeError, MicroPython propagates the original exception + print("Exception") + + +# Ensure removed/overwritten class members still get __set_name__ called. + + +class SetSpecific: + def __init__(self, sib_name, sib_replace): + self.sib_name = sib_name + self.sib_replace = sib_replace + + def __set_name__(self, owner, name): + setattr(owner, self.sib_name, self.sib_replace) + + +class SetReplaceTest: + a = SetSpecific("b", 312) # one of these is changed first + b = SetSpecific("a", 311) + + +t310 = SetReplaceTest() +print(t310.a) +print(t310.b) + + +class DelSpecific: + def __init__(self, sib_name): + self.sib_name = sib_name + + def __set_name__(self, owner, name): + delattr(owner, self.sib_name) + + +class DelReplaceTest: + a = DelSpecific("b") # one of these is removed first + b = DelSpecific("a") + + +t320 = DelReplaceTest() +try: + print(t320.a) +except AttributeError: + print("AttributeError") +try: + print(t320.b) +except AttributeError: + print("AttributeError") diff --git a/tests/basics/class_setname_hazard_rand.py b/tests/basics/class_setname_hazard_rand.py new file mode 100644 index 00000000000..4c9934c3bf0 --- /dev/null +++ b/tests/basics/class_setname_hazard_rand.py @@ -0,0 +1,111 @@ +# Test to make sure there's no sequence hazard even when a __set_name__ implementation +# mutates and reorders the namespace of its owner class. +# VERY hard bug to prove out except via a stochastic test. + + +try: + from random import choice + import re +except ImportError: + print("SKIP") + raise SystemExit + + +def skip_if_no_descriptors(): + class Descriptor: + def __get__(self, obj, cls): + return + + class TestClass: + Forward = Descriptor() + + a = TestClass() + try: + a.__class__ + except AttributeError: + # Target doesn't support __class__. + print("SKIP") + raise SystemExit + + b = a.Forward + if "Descriptor" in repr(b.__class__): + # Target doesn't support descriptors. + print("SKIP") + raise SystemExit + + +skip_if_no_descriptors() + +letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + +# Would be r"[A-Z]{5}", but not all ports support the {n} quantifier. +junk_re = re.compile(r"[A-Z][A-Z][A-Z][A-Z][A-Z]") + + +def junk_fill(obj, n=10): # Add randomly-generated attributes to an object. + for i in range(n): + name = "".join(choice(letters) for j in range(5)) + setattr(obj, name, object()) + + +def junk_clear(obj): # Remove attributes added by junk_fill. + to_del = [name for name in dir(obj) if junk_re.match(name)] + for name in to_del: + delattr(obj, name) + + +def junk_sequencer(): + global runs + try: + while True: + owner, name = yield + runs[name] = runs.get(name, 0) + 1 + junk_fill(owner) + finally: + junk_clear(owner) + + +class JunkMaker: + def __set_name__(self, owner, name): + global seq + seq.send((owner, name)) + + +runs = {} +seq = junk_sequencer() +next(seq) + + +class Main: + a = JunkMaker() + b = JunkMaker() + c = JunkMaker() + d = JunkMaker() + e = JunkMaker() + f = JunkMaker() + g = JunkMaker() + h = JunkMaker() + i = JunkMaker() + j = JunkMaker() + k = JunkMaker() + l = JunkMaker() + m = JunkMaker() + n = JunkMaker() + o = JunkMaker() + p = JunkMaker() + q = JunkMaker() + r = JunkMaker() + s = JunkMaker() + t = JunkMaker() + u = JunkMaker() + v = JunkMaker() + w = JunkMaker() + x = JunkMaker() + y = JunkMaker() + z = JunkMaker() + + +seq.close() + +for k in letters.lower(): + print(k, runs.get(k, 0)) diff --git a/tests/basics/del_attr.py b/tests/basics/del_attr.py index 8487b97e311..90a8a5a6f83 100644 --- a/tests/basics/del_attr.py +++ b/tests/basics/del_attr.py @@ -35,5 +35,5 @@ def f(): try: del int.to_bytes except (AttributeError, TypeError): - # uPy raises AttributeError, CPython raises TypeError + # MicroPython raises AttributeError, CPython raises TypeError print('AttributeError/TypeError') diff --git a/tests/basics/del_global.py b/tests/basics/del_global.py index d740357b033..e1aa074b97a 100644 --- a/tests/basics/del_global.py +++ b/tests/basics/del_global.py @@ -14,7 +14,7 @@ def do_del(): try: do_del() except: # NameError: - # FIXME uPy returns KeyError for this + # FIXME MicroPython returns KeyError for this print("NameError") # delete globals using a list diff --git a/tests/basics/del_name.py b/tests/basics/del_name.py index c92be54d3b6..8393b2df92a 100644 --- a/tests/basics/del_name.py +++ b/tests/basics/del_name.py @@ -10,7 +10,7 @@ try: del x except: # NameError: - # FIXME uPy returns KeyError for this + # FIXME MicroPython returns KeyError for this print("NameError") class C: diff --git a/tests/basics/deque2.py b/tests/basics/deque2.py index 3552d5be37a..ebc0872c7b4 100644 --- a/tests/basics/deque2.py +++ b/tests/basics/deque2.py @@ -31,6 +31,16 @@ d[3] = 5 print(d[3]) +# Access the last element via index, when the last element is at various locations +d = deque((), 2) +for i in range(4): + d.append(i) + print(i, d[-1]) + +# Write the last element then access all elements from the end +d[-1] = 4 +print(d[-2], d[-1]) + # Accessing indices out of bounds raises IndexError try: d[4] diff --git a/tests/basics/dict_views.py b/tests/basics/dict_views.py index a82f47b6be2..45f3238f1c6 100644 --- a/tests/basics/dict_views.py +++ b/tests/basics/dict_views.py @@ -6,6 +6,11 @@ # print a view with more than one item print({1:1, 2:1}.values()) +# `bool` and `len` unary ops +for d in ({}, {1: 2}, {1: 2, 3: 4}): + for op in (bool, len): + print(op(d.keys()), op(d.values()), op(d.items())) + # unsupported binary op on a dict values view try: {1:1}.values() + 1 diff --git a/tests/basics/exception_chain.py b/tests/basics/exception_chain.py index 579756c85fa..96c06c847ab 100644 --- a/tests/basics/exception_chain.py +++ b/tests/basics/exception_chain.py @@ -1,5 +1,12 @@ # CIRCUITPY-CHANGE: exception chaining is supported +import sys + +# The unix minimal build doesn't enable MICROPY_WARNINGS (required for this test). +if getattr(sys.implementation, "_build", None) == "minimal": + print("SKIP") + raise SystemExit + try: Exception().__cause__ except AttributeError: diff --git a/tests/basics/frozenset_set.py b/tests/basics/frozenset_set.py index 3bf456acfd7..2b3c6832609 100644 --- a/tests/basics/frozenset_set.py +++ b/tests/basics/frozenset_set.py @@ -8,5 +8,5 @@ # "Instances of set are compared to instances of frozenset based on their # members. For example:" print(set('abc') == frozenset('abc')) -# This doesn't work in uPy +# This doesn't work in MicroPython #print(set('abc') in set([frozenset('abc')])) diff --git a/tests/basics/fun_code.py b/tests/basics/fun_code.py new file mode 100644 index 00000000000..59e1f7ec048 --- /dev/null +++ b/tests/basics/fun_code.py @@ -0,0 +1,36 @@ +# Test function.__code__ attribute. + +try: + (lambda: 0).__code__ +except AttributeError: + print("SKIP") + raise SystemExit + + +def f(): + return a + + +ftype = type(f) + +# Test __code__ access and function constructor. +code = f.__code__ +print(type(ftype(code, {})) is ftype) + +# Test instantiating multiple code's with different globals dicts. +code = f.__code__ +f1 = ftype(code, {"a": 1}) +f2 = ftype(code, {"a": 2}) +print(f1(), f2()) + +# Test bad first argument type. +try: + ftype(None, {}) +except TypeError: + print("TypeError") + +# Test bad second argument type. +try: + ftype(f.__code__, None) +except TypeError: + print("TypeError") diff --git a/tests/basics/fun_code_colines.py b/tests/basics/fun_code_colines.py new file mode 100644 index 00000000000..a8867770edd --- /dev/null +++ b/tests/basics/fun_code_colines.py @@ -0,0 +1,81 @@ +# Check that we have sensical bytecode offsets in function.__code__.co_lines + +def f1(x, y, obj, obj2, obj3): + a = x + y # line 4: bc+4 line+4 + b = x - y # line 5: bc+4 line+1 + # line 6 + # line 7 + # line 8 + # line 9 + # line 10 + # line 11 + # line 12 + # line 13 + # line 14 + # line 15 + # line 16 + # line 17 + # line 18 + # line 19 + c = a * b # line 20: bc+4 line+15 + obj.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.fun() # line 21: bc+31 line+1; bc+27 line+0 + # line 22 + # line 23 + # line 24: bc+0 line+3 + # line 25 + # line 26 + # line 27: bc+0 line+3 + # line 28 + # line 29 + obj2.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.fun() # line 30: bc+31 line+3; bc+27 line+0 + # line 31 + # line 32 + # line 33: bc+0 line+3 + # line 34 + # line 35 + # line 36 + # line 37 + # line 38 + # line 39 + # line 40 + # line 41 + # line 42 + # line 43 + # line 44 + # line 45 + # line 46 + # line 47 + # line 48 + # line 49 + # line 50 + # line 51 + # line 52 + # line 53 + # line 54 + # line 55 + # line 56 + # line 57 + # line 58 + # line 59 + return obj3.a.b.c.d.e.f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.u.v.w.x.y.z.fun() # line 60: bc+31 line+27; bc+27 line+0 + +def f2(x, y): + a = x + y # line 63 + b = x - y # line 64 + return a * b # line 65 + +try: + f1.__code__.co_lines +except AttributeError: + print("SKIP") + raise SystemExit + +print("f1") +for start, end, line_no in f1.__code__.co_lines(): + print("line {} start: {}".format(line_no, start)) + print("line {} end: {}".format(line_no, end)) + +print("f2") +for start, end, line_no in f2.__code__.co_lines(): + print("line {} start: {}".format(line_no, start)) + print("line {} end: {}".format(line_no, end)) diff --git a/tests/basics/fun_code_colines.py.exp b/tests/basics/fun_code_colines.py.exp new file mode 100644 index 00000000000..19bd4ef6e2a --- /dev/null +++ b/tests/basics/fun_code_colines.py.exp @@ -0,0 +1,20 @@ +f1 +line 4 start: 0 +line 4 end: 4 +line 5 start: 4 +line 5 end: 8 +line 20 start: 8 +line 20 end: 12 +line 21 start: 12 +line 21 end: 70 +line 30 start: 70 +line 30 end: 128 +line 60 start: 128 +line 60 end: 186 +f2 +line 63 start: 0 +line 63 end: 4 +line 64 start: 4 +line 64 end: 8 +line 65 start: 8 +line 65 end: 12 diff --git a/tests/basics/fun_code_full.py b/tests/basics/fun_code_full.py new file mode 100644 index 00000000000..538863631a6 --- /dev/null +++ b/tests/basics/fun_code_full.py @@ -0,0 +1,38 @@ +# Test function.__code__ attributes not available with MICROPY_PY_BUILTINS_CODE <= MICROPY_PY_BUILTINS_CODE_BASIC + +try: + (lambda: 0).__code__.co_code +except AttributeError: + print("SKIP") + raise SystemExit + +def f(x, y): + a = x + y + b = x - y + return a * b + +code = f.__code__ + +print(type(code.co_code)) # both bytes (but mpy and cpy have different instruction sets) +print(code.co_consts) # (not necessarily the same set, but in this function they are) +print(code.co_filename.rsplit('/')[-1]) # same terminal filename but might be different paths on other ports +print(type(code.co_firstlineno)) # both ints (but mpy points to first line inside, cpy points to declaration) +print(code.co_name) +print(iter(code.co_names) is not None) # both iterable (but mpy returns dict with names as keys, cpy only the names; and not necessarily the same set) + +co_lines = code.co_lines() + +l = list(co_lines) +first_start = l[0][0] +last_end = l[-1][1] +print(first_start) # co_lines should start at the start of the bytecode +print(len(code.co_code) - last_end) # and end at the end of the bytecode + +prev_end = 0 +for start, end, line_no in l: + if end != prev_end: + print("non-contiguous") + break # the offset ranges should be contiguous + prev_end = end +else: + print("contiguous") diff --git a/tests/basics/fun_code_full.py.exp b/tests/basics/fun_code_full.py.exp new file mode 100644 index 00000000000..830effadfc6 --- /dev/null +++ b/tests/basics/fun_code_full.py.exp @@ -0,0 +1,9 @@ + +(None,) +fun_code_full.py + +f +True +0 +0 +non-contiguous diff --git a/tests/basics/fun_code_lnotab.py b/tests/basics/fun_code_lnotab.py new file mode 100644 index 00000000000..9223e5730f0 --- /dev/null +++ b/tests/basics/fun_code_lnotab.py @@ -0,0 +1,34 @@ +# Test deprecation of co_lnotab + +try: + (lambda: 0).__code__.co_code +except AttributeError: + print("SKIP") + raise SystemExit + + +import unittest +import sys + + +mpy_is_v2 = getattr(sys.implementation, '_v2', False) + + +def f(): + pass + + +class Test(unittest.TestCase): + + @unittest.skipIf(mpy_is_v2, "Removed in MicroPython v2 and later.") + def test_co_lnotab_exists(self): + self.assertIsInstance(f.__code__.co_lnotab, bytes) + + @unittest.skipUnless(mpy_is_v2, "Not removed before MicroPython v2.") + def test_co_lnotab_removed(self): + with self.assertRaises(AttributeError): + f.__code__.co_lnotab + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/basics/fun_code_micropython.py b/tests/basics/fun_code_micropython.py new file mode 100644 index 00000000000..2c319a2db8c --- /dev/null +++ b/tests/basics/fun_code_micropython.py @@ -0,0 +1,19 @@ +# Test MicroPython-specific restrictions of function.__code__ attribute. + +try: + (lambda: 0).__code__ +except AttributeError: + print("SKIP") + raise SystemExit + + +def f_with_children(): + def g(): + pass + + +# Can't access __code__ when function has children. +try: + f_with_children.__code__ +except AttributeError: + print("AttributeError") diff --git a/tests/basics/fun_code_micropython.py.exp b/tests/basics/fun_code_micropython.py.exp new file mode 100644 index 00000000000..d169edffb4c --- /dev/null +++ b/tests/basics/fun_code_micropython.py.exp @@ -0,0 +1 @@ +AttributeError diff --git a/tests/basics/fun_name.py b/tests/basics/fun_name.py index b2642280a2a..8aac35eeafa 100644 --- a/tests/basics/fun_name.py +++ b/tests/basics/fun_name.py @@ -16,7 +16,7 @@ def Fun(self): print('SKIP') raise SystemExit -# __name__ of a bound native method is not implemented in uPy +# __name__ of a bound native method is not implemented in MicroPython # the test here is to make sure it doesn't crash try: str((1).to_bytes.__name__) diff --git a/tests/basics/gc1.py b/tests/basics/gc1.py index 332bf9744c0..dff9538b14b 100644 --- a/tests/basics/gc1.py +++ b/tests/basics/gc1.py @@ -15,13 +15,13 @@ gc.collect() if hasattr(gc, 'mem_free'): - # uPy has these extra functions + # MicroPython has these extra functions # just test they execute and return an int assert type(gc.mem_free()) is int assert type(gc.mem_alloc()) is int if hasattr(gc, 'threshold'): - # uPy has this extra function + # MicroPython has this extra function # check execution and returns assert(gc.threshold(1) is None) assert(gc.threshold() == 0) diff --git a/tests/basics/gen_yield_from_throw_repeat.py b/tests/basics/gen_yield_from_throw_repeat.py index 67378ff47a1..96636a62443 100644 --- a/tests/basics/gen_yield_from_throw_repeat.py +++ b/tests/basics/gen_yield_from_throw_repeat.py @@ -1,4 +1,3 @@ -# CIRCUITPY-CHANGE: micropython does not have this test file # Test throwing repeatedly into the same generator, where that generator # is yielding from another generator. diff --git a/tests/basics/generator_throw_repeat.py b/tests/basics/generator_throw_repeat.py index 2b099494d36..6d6ef60a9b0 100644 --- a/tests/basics/generator_throw_repeat.py +++ b/tests/basics/generator_throw_repeat.py @@ -1,4 +1,3 @@ -# CIRCUITPY-CHANGE: micropython does not have this test file # Test throwing repeatedly into the same generator. diff --git a/tests/basics/import_instance_method.py b/tests/basics/import_instance_method.py new file mode 100644 index 00000000000..d25b70ac5f0 --- /dev/null +++ b/tests/basics/import_instance_method.py @@ -0,0 +1,38 @@ +# Test importing a method from a class instance. +# This is not a common thing to do, but ensures MicroPython has the same semantics as CPython. + +import sys + +if not hasattr(sys, "modules"): + print("SKIP") + raise SystemExit + + +class A: + def __init__(self, value): + self.value = value + + def meth(self): + return self.value + + def meth_with_arg(self, a): + return [self.value, a] + + +# Register a class instance as the module "mod". +sys.modules["mod"] = A(1) + +# Try importing it as a module. +import mod + +print(mod.meth()) +print(mod.meth_with_arg(2)) + +# Change the module. +sys.modules["mod"] = A(3) + +# Try importing it using "from ... import". +from mod import meth, meth_with_arg + +print(meth()) +print(meth_with_arg(4)) diff --git a/tests/basics/int1.py b/tests/basics/int1.py index 2d92105c73e..94723af4d00 100644 --- a/tests/basics/int1.py +++ b/tests/basics/int1.py @@ -13,6 +13,7 @@ print(int('+1')) print(int('-1')) print(int('01')) +print(int('00')) print(int('9')) print(int('10')) print(int('+10')) @@ -31,6 +32,7 @@ print(int('0', 10)) print(int('1', 10)) print(int(' \t 1 \t ', 10)) +print(int(' \t 00 \t ', 10)) print(int('11', 10)) print(int('11', 16)) print(int('11', 8)) @@ -52,6 +54,17 @@ print(int('0o12 \t ', 8)) print(int(b"12", 10)) print(int(b"12")) +print(int('000 ', 0)) +print(int('000 ', 2)) +print(int('000 ', 8)) +print(int('000 ', 10)) +print(int('000 ', 16)) +print(int('000 ', 36)) +print(int('010 ', 2)) +print(int('010 ', 8)) +print(int('010 ', 10)) +print(int('010 ', 16)) +print(int('010 ', 36)) def test(value, base): @@ -79,6 +92,8 @@ def test(value, base): test('0xg', 16) test('1 1', 16) test('123', 37) +test('01', 0) +test('01 ', 0) # check that we don't parse this as a floating point number print(0x1e+1) diff --git a/tests/basics/int_64_basics.py b/tests/basics/int_64_basics.py new file mode 100644 index 00000000000..ef76793317e --- /dev/null +++ b/tests/basics/int_64_basics.py @@ -0,0 +1,161 @@ +# test support for 64-bit long integers +# (some ports don't support arbitrary precision but do support these) + +# this test is adapted from int_big1.py with numbers kept within 64-bit signed range + +# to test arbitrary precision integers + +x = 1000000000000000000 +xn = -1000000000000000000 +y = 2000000000000000000 + +# printing +print(x) +print(y) +print('%#X' % (x - x)) # print prefix +print('{:#,}'.format(x)) # print with commas + +# construction +print(int(x)) + +# addition +print(x + 1) +print(x + y) +print(x + xn == 0) +print(bool(x + xn)) + +# subtraction +print(x - 1) +print(x - y) +print(y - x) +print(x - x == 0) +print(bool(x - x)) + +# multiplication +print(x * 2) +print(1090511627776 * 1048500) + +# integer division +print(x // 2) +print(y // x) + +# bit inversion +print(~x) +print(~(-x)) + +# left shift +print("left shift positive") +x = 0x40000000 +for i in range(32): + x = x << 1 + print(x) + +# right shift +print("right shift positive") +x = 0x2000000000000000 # TODO: why can't second-tip bit be set? +for i in range(64): + x = x >> 1 + print(x) + +# left shift of a negative number +print("left shift negative") +for i in range(8): + print(-10000000000000000 << i) + print(-10000000000000001 << i) + print(-10000000000000002 << i) + print(-10000000000000003 << i) + print(-10000000000000004 << i) + + +# right shift of a negative number +print("right shift negative") +for i in range(8): + print(-1000000000000000000 >> i) + print(-1000000000000000001 >> i) + print(-1000000000000000002 >> i) + print(-1000000000000000003 >> i) + print(-1000000000000000004 >> i) + +# conversion from string +print(int("1234567890123456789")) +print(int("-1234567890123456789")) +print(int("1234567890abcdef", 16)) +print(int("1234567890ABCDEF", 16)) +print(int("-1234567890ABCDEF", 16)) +print(int("ijklmnopqrsz", 36)) + +# numbers close to 64-bit limits +print(int("-9111222333444555666")) +print(int("9111222333444555666")) + +# numbers with preceding 0s +print(int("-00000000000000000000009111222333444555666")) +print(int("0000000000000000000000009111222333444555666")) + +# invalid characters in string +try: + print(int("1234567890abcdef")) +except ValueError: + print('ValueError'); +try: + print(int("123456789\x01")) +except ValueError: + print('ValueError'); + +# test parsing ints just on threshold of small to big +# for 32 bit archs +x = 1073741823 # small +x = -1073741823 # small +x = 1073741824 # big +x = -1073741824 # big +# for 64 bit archs +x = 4611686018427387903 # small +x = -4611686018427387903 # small +x = 4611686018427387904 # big +x = -4611686018427387904 # big + +# sys.maxsize is a constant bigint, so test it's compatible with dynamic ones +import sys +if hasattr(sys, "maxsize"): + print(sys.maxsize - 1 + 1 == sys.maxsize) +else: + print(True) # No maxsize property in this config + +# test extraction of big int value via mp_obj_get_int_maybe +x = 1 << 62 +print('a' * (x + 4 - x)) + +# test overflow check in mp_obj_get_int_maybe +x = 1 << 32 +r = None +try: + r = range(0, x) +except OverflowError: + # 32-bit target, correctly handled the overflow of x + print("ok") +if r is not None: + if len(r) == x: + # 64-bit target, everything is just a small-int + print("ok") + else: + # 32-bit target that did not handle the overflow of x + print("unhandled overflow") + +# negative shifts are invalid +try: + print((1 << 48) >> -4) +except ValueError as e: + print(e) + +try: + print((1 << 48) << -6) +except ValueError as e: + print(e) + +# Test that the most extreme 64 bit integer values all parse with int() +print(int("-9223372036854775807")) +print(int("-9223372036854775808")) +print(int("9223372036854775807")) + +# Test that the most negative 64 bit integer can be formed via arithmetic +print(-9223372036854775807-1) diff --git a/tests/basics/int_big_to_small.py b/tests/basics/int_big_to_small.py new file mode 100644 index 00000000000..c92d263fc28 --- /dev/null +++ b/tests/basics/int_big_to_small.py @@ -0,0 +1,33 @@ +try: + import micropython + micropython.heap_lock +except: + print("SKIP") + raise SystemExit + +# Skip this test on "REPR B" where (1<<29 + 1) is not a small int. +k = 1 << 29 +micropython.heap_lock() +try: + k = k + 1 +except MemoryError: + print("SKIP") + raise SystemExit +finally: + micropython.heap_unlock() + +# All less than small int max. +for d in (0, 27, 1<<29, -1861, -(1<<29)): + i = 1<<70 + print(i) + j = (1<<70) + d + print(j) + # k should now be a small int. + k = j - i + print(k) + + # Now verify that working with k doesn't allocate (i.e. it's a small int). + micropython.heap_lock() + print(k + 20) + print(k // 20) + micropython.heap_unlock() diff --git a/tests/basics/int_big_to_small.py.exp b/tests/basics/int_big_to_small.py.exp new file mode 100644 index 00000000000..1d4986e0443 --- /dev/null +++ b/tests/basics/int_big_to_small.py.exp @@ -0,0 +1,25 @@ +1180591620717411303424 +1180591620717411303424 +0 +20 +0 +1180591620717411303424 +1180591620717411303451 +27 +47 +1 +1180591620717411303424 +1180591620717948174336 +536870912 +536870932 +26843545 +1180591620717411303424 +1180591620717411301563 +-1861 +-1841 +-94 +1180591620717411303424 +1180591620716874432512 +-536870912 +-536870892 +-26843546 diff --git a/tests/basics/int_big_to_small_int29.py b/tests/basics/int_big_to_small_int29.py new file mode 100644 index 00000000000..438a74d2bc6 --- /dev/null +++ b/tests/basics/int_big_to_small_int29.py @@ -0,0 +1,22 @@ +try: + import micropython + micropython.heap_lock +except: + print("SKIP") + raise SystemExit + +# All less than small int max. +for d in (0, 27, 1<<28, -1861, -(1<<28)): + i = 1<<70 + print(i) + j = (1<<70) + d + print(j) + # k should now be a small int. + k = j - i + print(k) + + # Now verify that working with k doesn't allocate (i.e. it's a small int). + micropython.heap_lock() + print(k + 20) + print(k // 20) + micropython.heap_unlock() diff --git a/tests/basics/int_big_to_small_int29.py.exp b/tests/basics/int_big_to_small_int29.py.exp new file mode 100644 index 00000000000..0920101924a --- /dev/null +++ b/tests/basics/int_big_to_small_int29.py.exp @@ -0,0 +1,25 @@ +1180591620717411303424 +1180591620717411303424 +0 +20 +0 +1180591620717411303424 +1180591620717411303451 +27 +47 +1 +1180591620717411303424 +1180591620717679738880 +268435456 +268435476 +13421772 +1180591620717411303424 +1180591620717411301563 +-1861 +-1841 +-94 +1180591620717411303424 +1180591620717142867968 +-268435456 +-268435436 +-13421773 diff --git a/tests/basics/int_bytes.py b/tests/basics/int_bytes.py index 3840aa8e4f0..d1999bebb0e 100644 --- a/tests/basics/int_bytes.py +++ b/tests/basics/int_bytes.py @@ -26,6 +26,12 @@ except ValueError: print("ValueError") +# zero byte destination should also raise an error +try: + (1).to_bytes(0, "little") +except OverflowError: + print("OverflowError") + # CIRCUITPY-CHANGE: more tests # too small buffer should raise an error try: @@ -39,7 +45,24 @@ except OverflowError: print("OverflowError") +# except for converting 0 to a zero-length byte array +print((0).to_bytes(0, "big")) + +# byte length can fit the integer directly +print((0xFF).to_bytes(1, "little")) +print((0xFF).to_bytes(1, "big")) +print((0xEFF).to_bytes(2, "little")) +print((0xEFF).to_bytes(2, "big")) +print((0xCDEFF).to_bytes(3, "little")) +print((0xCDEFF).to_bytes(3, "big")) + +# OverFlowError if not big enough + try: (-256).to_bytes(2, "little", signed=False) except OverflowError: print("OverflowError") + +# byteorder arg can be omitted; default is "big" +print(int.from_bytes(b"\x01\0")) +print((100).to_bytes(10)) diff --git a/tests/basics/int_bytes_int64.py b/tests/basics/int_bytes_int64.py new file mode 100644 index 00000000000..032dbccc5b1 --- /dev/null +++ b/tests/basics/int_bytes_int64.py @@ -0,0 +1,52 @@ +import sys + +# Depending on the port, the numbers in this test may be implemented as "small" +# native 64 bit ints, arbitrary precision large ints, or large integers using 64-bit +# long longs. + +try: + x = int.from_bytes(b"\x6F\xAB\xCD\x12\x34\x56\x78\xFB", "big") +except OverflowError: + print("SKIP") # Port can't represent this size of integer at all + raise SystemExit + +print(hex(x)) +b = x.to_bytes(8, "little") +print(b) +print(x.to_bytes(8, "big")) + +# padding in output +print(x.to_bytes(20, "little")) +print(x.to_bytes(20, "big")) + +# check that extra zero bytes don't change the internal int value +print(int.from_bytes(b + bytes(10), "little") == x) + +# can't write to a zero-length bytes object +try: + x.to_bytes(0, "little") +except OverflowError: + print("OverflowError") + +# or one that it too short +try: + x.to_bytes(7, "big") +except OverflowError: + print("OverflowError") + +# negative representations + +# MicroPython int.to_bytes() behaves as if signed=True for negative numbers +if "micropython" in repr(sys.implementation): + + def to_bytes_compat(i, l, e): + return i.to_bytes(l, e) +else: + # Implement MicroPython compatible behaviour for CPython + def to_bytes_compat(i, l, e): + return i.to_bytes(l, e, signed=i < 0) + + +print(to_bytes_compat(-x, 8, "little")) +print(to_bytes_compat(-x, 20, "big")) +print(to_bytes_compat(-x, 20, "little")) diff --git a/tests/basics/int_bytes_intbig.py b/tests/basics/int_bytes_intbig.py index e78f55de01f..073c8bf7892 100644 --- a/tests/basics/int_bytes_intbig.py +++ b/tests/basics/int_bytes_intbig.py @@ -2,6 +2,8 @@ import skip_if skip_if.no_bigint() +import sys + # CIRCUITPY-CHANGE: signed support print((2**64).to_bytes(9, "little")) print((-2**64).to_bytes(9, "little", signed=True)) @@ -17,6 +19,10 @@ print(il.to_bytes(20, "little")) print(ib.to_bytes(20, "big")) +# check padding comes out correctly +print(il.to_bytes(40, "little")) +print(ib.to_bytes(40, "big")) + # check that extra zero bytes don't change the internal int value print(int.from_bytes(b + bytes(10), "little") == int.from_bytes(b, "little")) @@ -32,7 +38,38 @@ (-2**64).to_bytes(9, "little") except OverflowError: print("OverflowError") + +# negative representations + +# MicroPython int.to_bytes() behaves as if signed=True for negative numbers +if "micropython" in repr(sys.implementation): + + def to_bytes_compat(i, l, e): + return i.to_bytes(l, e) +else: + # Implement MicroPython compatible behaviour for CPython + def to_bytes_compat(i, l, e): + return i.to_bytes(l, e, signed=i < 0) + + +print(to_bytes_compat(-ib, 20, "big")) +print(to_bytes_compat(ib * -ib, 40, "big")) + +# case where an additional byte is needed for sign bit +ib = (2**64) - 1 +print(ib.to_bytes(8, "little")) + +ib *= -1 + try: (-2**64).to_bytes(9, "little", signed=False) except OverflowError: print("OverflowError") +try: + print(to_bytes_compat(ib, 8, "little")) +except OverflowError: + print("OverflowError") + + +print(to_bytes_compat(ib, 9, "little")) +print(to_bytes_compat(ib, 9, "big")) diff --git a/tests/basics/int_bytes_optional_args_cp311.py b/tests/basics/int_bytes_optional_args_cp311.py new file mode 100644 index 00000000000..07fdcdd2821 --- /dev/null +++ b/tests/basics/int_bytes_optional_args_cp311.py @@ -0,0 +1,9 @@ +# Check optional byteorder argument (CPython 3.11+) +print((10).to_bytes(1)) +print((100).to_bytes(10)) +print(int.from_bytes(b"\0\0\0\0\0\0\0\0\0\x01")) +print(int.from_bytes(b"\x01\0")) + +# Check optional length argument (CPython 3.11+) +print((10).to_bytes()) +print((100).to_bytes()) diff --git a/tests/basics/int_bytes_optional_args_cp311.py.exp b/tests/basics/int_bytes_optional_args_cp311.py.exp new file mode 100644 index 00000000000..6dffa2577fc --- /dev/null +++ b/tests/basics/int_bytes_optional_args_cp311.py.exp @@ -0,0 +1,6 @@ +b'\n' +b'\x00\x00\x00\x00\x00\x00\x00\x00\x00d' +1 +256 +b'\n' +b'd' diff --git a/tests/basics/io_buffered_writer.py b/tests/basics/io_buffered_writer.py index 11df0324e24..3cfee0103f7 100644 --- a/tests/basics/io_buffered_writer.py +++ b/tests/basics/io_buffered_writer.py @@ -1,10 +1,10 @@ -import io - try: + import io + io.BytesIO io.BufferedWriter -except AttributeError: - print("SKIP") +except (AttributeError, ImportError): + print('SKIP') raise SystemExit bts = io.BytesIO() @@ -28,3 +28,27 @@ # hashing a BufferedWriter print(type(hash(buf))) + +# Test failing flush() +class MyIO(io.IOBase): + def __init__(self): + self.count = 0 + + def write(self, buf): + self.count += 1 + if self.count < 3: + return None + print("writing", buf) + return len(buf) + + +buf = io.BufferedWriter(MyIO(), 8) + +buf.write(b"foobar") + +for _ in range(4): + try: + buf.flush() + print("flushed") + except OSError: + print("OSError") diff --git a/tests/basics/io_buffered_writer.py.exp b/tests/basics/io_buffered_writer.py.exp index 2209348f5af..d61eb148b45 100644 --- a/tests/basics/io_buffered_writer.py.exp +++ b/tests/basics/io_buffered_writer.py.exp @@ -4,3 +4,8 @@ b'foobarfoobar' b'foobarfoobar' b'foo' +OSError +OSError +writing bytearray(b'foobar') +flushed +flushed diff --git a/tests/basics/io_bytesio_cow.py b/tests/basics/io_bytesio_cow.py index 2edb7136a96..543c12ad42a 100644 --- a/tests/basics/io_bytesio_cow.py +++ b/tests/basics/io_bytesio_cow.py @@ -1,6 +1,12 @@ # Make sure that write operations on io.BytesIO don't # change original object it was constructed from. -import io + +try: + import io +except ImportError: + print("SKIP") + raise SystemExit + b = b"foobar" a = io.BytesIO(b) diff --git a/tests/basics/io_bytesio_ext.py b/tests/basics/io_bytesio_ext.py index 4d4c60c1363..92e71517811 100644 --- a/tests/basics/io_bytesio_ext.py +++ b/tests/basics/io_bytesio_ext.py @@ -1,5 +1,11 @@ # Extended stream operations on io.BytesIO -import io + +try: + import io +except ImportError: + print("SKIP") + raise SystemExit + a = io.BytesIO(b"foobar") a.seek(10) print(a.read(10)) diff --git a/tests/basics/io_bytesio_ext2.py b/tests/basics/io_bytesio_ext2.py index 414ac90a3b0..f60a6a9a604 100644 --- a/tests/basics/io_bytesio_ext2.py +++ b/tests/basics/io_bytesio_ext2.py @@ -1,4 +1,9 @@ -import io +try: + import io +except ImportError: + print("SKIP") + raise SystemExit + a = io.BytesIO(b"foobar") try: a.seek(-10) diff --git a/tests/basics/io_iobase.py b/tests/basics/io_iobase.py index b2ee5cd63a6..31f2616310e 100644 --- a/tests/basics/io_iobase.py +++ b/tests/basics/io_iobase.py @@ -1,15 +1,17 @@ import io try: + import io + io.IOBase -except AttributeError: +except (AttributeError, ImportError): print("SKIP") raise SystemExit class MyIO(io.IOBase): def write(self, buf): - # CPython and uPy pass in different types for buf (str vs bytearray) - print("write", len(buf)) + # CPython and MicroPython pass in different types for buf (str vs bytearray) + print('write', len(buf)) return len(buf) -print("test", file=MyIO()) +print('test', file=MyIO()) diff --git a/tests/basics/io_stringio1.py b/tests/basics/io_stringio1.py index 7d355930f5a..889e3ce6973 100644 --- a/tests/basics/io_stringio1.py +++ b/tests/basics/io_stringio1.py @@ -1,4 +1,9 @@ -import io +try: + import io +except ImportError: + print("SKIP") + raise SystemExit + a = io.StringIO() print('io.StringIO' in repr(a)) print(a.getvalue()) diff --git a/tests/basics/io_stringio_base.py b/tests/basics/io_stringio_base.py index 0f65fb3fabc..c8890dab73a 100644 --- a/tests/basics/io_stringio_base.py +++ b/tests/basics/io_stringio_base.py @@ -1,7 +1,11 @@ # Checks that an instance type inheriting from a native base that uses # MP_TYPE_FLAG_ITER_IS_STREAM will still have a getiter. -import io +try: + import io +except ImportError: + print("SKIP") + raise SystemExit a = io.StringIO() a.write("hello\nworld\nmicro\npython\n") diff --git a/tests/basics/io_stringio_with.py b/tests/basics/io_stringio_with.py index a3aa6ec84e0..0155ad5382d 100644 --- a/tests/basics/io_stringio_with.py +++ b/tests/basics/io_stringio_with.py @@ -1,4 +1,9 @@ -import io +try: + import io +except ImportError: + print("SKIP") + raise SystemExit + # test __enter__/__exit__ with io.StringIO() as b: b.write("foo") diff --git a/tests/basics/io_write_ext.py b/tests/basics/io_write_ext.py index 79f7450954e..5af1de7a6c3 100644 --- a/tests/basics/io_write_ext.py +++ b/tests/basics/io_write_ext.py @@ -1,11 +1,12 @@ # This tests extended (MicroPython-specific) form of write: # write(buf, len) and write(buf, offset, len) -import io try: + import io + io.BytesIO -except AttributeError: - print("SKIP") +except (AttributeError, ImportError): + print('SKIP') raise SystemExit buf = io.BytesIO() diff --git a/tests/basics/lexer.py b/tests/basics/lexer.py index 181d62db1aa..addb8a13df3 100644 --- a/tests/basics/lexer.py +++ b/tests/basics/lexer.py @@ -83,3 +83,11 @@ def a(x): exec(r"'\U0000000'") except SyntaxError: print("SyntaxError") + +# Properly formed integer literals +print(eval("00")) +# badly formed integer literals +try: + eval("01") +except SyntaxError: + print("SyntaxError") diff --git a/tests/basics/list_pop.py b/tests/basics/list_pop.py index 87ed456f851..58bcdd91e41 100644 --- a/tests/basics/list_pop.py +++ b/tests/basics/list_pop.py @@ -10,7 +10,7 @@ else: raise AssertionError("No IndexError raised") -# popping such that list storage shrinks (tests implementation detail of uPy) +# popping such that list storage shrinks (tests implementation detail of MicroPython) l = list(range(20)) for i in range(len(l)): l.pop() diff --git a/tests/basics/module2.py b/tests/basics/module2.py index a135601579c..d1dc18930f0 100644 --- a/tests/basics/module2.py +++ b/tests/basics/module2.py @@ -1,4 +1,4 @@ -# uPy behaviour only: builtin modules are read-only +# MicroPython behaviour only: builtin modules are read-only import sys try: sys.x = 1 diff --git a/tests/basics/namedtuple1.py b/tests/basics/namedtuple1.py index 362c60583ec..b9689b58423 100644 --- a/tests/basics/namedtuple1.py +++ b/tests/basics/namedtuple1.py @@ -21,6 +21,9 @@ print(isinstance(t, tuple)) + # a NamedTuple can be used as a tuple + print("(%d, %d)" % t) + # Check tuple can compare equal to namedtuple with same elements print(t == (t[0], t[1]), (t[0], t[1]) == t) diff --git a/tests/basics/nanbox_smallint.py b/tests/basics/nanbox_smallint.py index b3a502e447e..9451ab32846 100644 --- a/tests/basics/nanbox_smallint.py +++ b/tests/basics/nanbox_smallint.py @@ -23,17 +23,17 @@ raise SystemExit micropython.heap_lock() -print(int("0x80000000")) +print(int("0x80000000", 16)) micropython.heap_unlock() # This is the most positive small integer. micropython.heap_lock() -print(int("0x3fffffffffff")) +print(int("0x3fffffffffff", 16)) micropython.heap_unlock() # This is the most negative small integer. micropython.heap_lock() -print(int("-0x3fffffffffff") - 1) +print(int("-0x3fffffffffff", 16) - 1) micropython.heap_unlock() x = 1 diff --git a/tests/basics/parser.py b/tests/basics/parser.py index 626b67ad7a9..6ae5f05ba45 100644 --- a/tests/basics/parser.py +++ b/tests/basics/parser.py @@ -7,7 +7,7 @@ raise SystemExit # completely empty string -# uPy and CPy differ for this case +# MPy and CPy differ for this case #try: # compile("", "stdin", "single") #except SyntaxError: diff --git a/tests/basics/python34.py b/tests/basics/python34.py index 922234d22db..3071b55eff8 100644 --- a/tests/basics/python34.py +++ b/tests/basics/python34.py @@ -28,7 +28,7 @@ def test_syntax(code): test_syntax("del ()") # can't delete empty tuple (in 3.6 we can) # from basics/sys1.py -# uPy prints version 3.4 +# MicroPython prints version 3.4 import sys print(sys.version[:3]) print(sys.version_info[0], sys.version_info[1]) diff --git a/tests/basics/python36.py.exp b/tests/basics/python36.py.exp deleted file mode 100644 index 4b65daafa18..00000000000 --- a/tests/basics/python36.py.exp +++ /dev/null @@ -1,5 +0,0 @@ -100000 -165 -65535 -123 -83 diff --git a/tests/basics/self_type_check.py b/tests/basics/self_type_check.py index 3bd5b3eed60..5f6f6f2ca65 100644 --- a/tests/basics/self_type_check.py +++ b/tests/basics/self_type_check.py @@ -3,6 +3,14 @@ import skip_if skip_if.board_in("gemma_m0", "trinket_m0") +import sys + +# Minimal builds usually don't enable MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG, +# which is required for this test. +if getattr(sys.implementation, "_build", None) == "minimal": + print("SKIP") + raise SystemExit + list.append try: diff --git a/tests/basics/slice_optimise.py b/tests/basics/slice_optimise.py new file mode 100644 index 00000000000..f663e16b8c2 --- /dev/null +++ b/tests/basics/slice_optimise.py @@ -0,0 +1,23 @@ +# Test that the slice-on-stack optimisation does not break various uses of slice +# (see MP_TYPE_FLAG_SUBSCR_ALLOWS_STACK_SLICE type option). +# +# Note: this test has a corresponding .py.exp file because hashing slice objects +# was not allowed in CPython until 3.12. + +try: + from collections import OrderedDict +except ImportError: + print("SKIP") + raise SystemExit + +# Attempt to index with a slice, error should contain the slice (failed key). +try: + dict()[:] +except KeyError as e: + print("KeyError", e.args) + +# Put a slice and another object into an OrderedDict, and retrieve them. +x = OrderedDict() +x[:"a"] = 1 +x["b"] = 2 +print(list(x.keys()), list(x.values())) diff --git a/tests/basics/slice_optimise.py.exp b/tests/basics/slice_optimise.py.exp new file mode 100644 index 00000000000..3fa59aae15a --- /dev/null +++ b/tests/basics/slice_optimise.py.exp @@ -0,0 +1,2 @@ +KeyError (slice(None, None, None),) +[slice(None, 'a', None), 'b'] [1, 2] diff --git a/tests/basics/special_methods2.py.exp b/tests/basics/special_methods2.py.exp deleted file mode 100644 index a9ae75be55c..00000000000 --- a/tests/basics/special_methods2.py.exp +++ /dev/null @@ -1,19 +0,0 @@ -__pos__ called -__pos__ called -__neg__ called -__invert__ called -__mul__ called -__matmul__ called -__truediv__ called -__floordiv__ called -__iadd__ called -__isub__ called -__mod__ called -__pow__ called -__or__ called -__and__ called -__xor__ called -__lshift__ called -__rshift__ called -['a', 'b', 'c'] -False diff --git a/tests/basics/string_endswith.py b/tests/basics/string_endswith.py index 683562d10c3..2b0a063988b 100644 --- a/tests/basics/string_endswith.py +++ b/tests/basics/string_endswith.py @@ -5,11 +5,28 @@ print("foobar".endswith("")) print("foobar".endswith("foobarbaz")) -#print("1foobar".startswith("foo", 1)) -#print("1foo".startswith("foo", 1)) -#print("1foo".startswith("1foo", 1)) -#print("1fo".startswith("foo", 1)) -#print("1fo".startswith("foo", 10)) +print("foobar".endswith("bar", 3)) +print("foobar".endswith("bar", 4)) +print("foobar".endswith("foo", 0, 3)) +print("foobar".endswith("foo", 0, 4)) +print("foobar".endswith("foo", 1, 3)) +print("foobar".endswith("foo", 1, 3)) +print("foobar".endswith("oo", 1, 3)) +print("foobar".endswith("o", 2, 3)) +print("foobar".endswith("o", 3, 3)) +print("foobar".endswith("o", 4, 3)) + +print("foobar".endswith("bar", None, None)) +print("foobar".endswith("bar", None, 3)) +print("foobar".endswith("bar", 3, None)) +print("foobar".endswith("bar", 2, None)) +print("foobar".endswith("foo", None, 3)) + +print("foobar".endswith(("bar", "foo"))) +print("foobar".endswith(("foo", "bar"))) +print("foobar".endswith(("foo", "bar1"))) +print("foobar".endswith(("bar", ))) +print("foobar".endswith(("foo", ))) try: "foobar".endswith(1) diff --git a/tests/basics/string_endswith_upy.py b/tests/basics/string_endswith_upy.py deleted file mode 100644 index 06a4e71d2c9..00000000000 --- a/tests/basics/string_endswith_upy.py +++ /dev/null @@ -1,6 +0,0 @@ -# MicroPython doesn't support tuple argument - -try: - "foobar".endswith(("bar", "sth")) -except TypeError: - print("TypeError") diff --git a/tests/basics/string_endswith_upy.py.exp b/tests/basics/string_endswith_upy.py.exp deleted file mode 100644 index 6002b71c56e..00000000000 --- a/tests/basics/string_endswith_upy.py.exp +++ /dev/null @@ -1 +0,0 @@ -TypeError diff --git a/tests/basics/string_format.py b/tests/basics/string_format.py index e8600f58361..11e7836a73e 100644 --- a/tests/basics/string_format.py +++ b/tests/basics/string_format.py @@ -22,7 +22,17 @@ def test(fmt, *args): test("{:4x}", 123) test("{:4X}", 123) +test("{:4,d}", 1) +test("{:4_d}", 1) +test("{:4_o}", 1) +test("{:4_b}", 1) +test("{:4_x}", 1) + test("{:4,d}", 12345678) +test("{:4_d}", 12345678) +test("{:4_o}", 12345678) +test("{:4_b}", 12345678) +test("{:4_x}", 12345678) test("{:#4b}", 10) test("{:#4o}", 123) diff --git a/tests/basics/string_format_intbig.py b/tests/basics/string_format_intbig.py new file mode 100644 index 00000000000..a36c36752e7 --- /dev/null +++ b/tests/basics/string_format_intbig.py @@ -0,0 +1,15 @@ +# basic functionality test for {} format string using large integers + + +def test(fmt, *args): + print("{:8s}".format(fmt) + ">" + fmt.format(*args) + "<") + + +# Separator formatter + +test("{:,}", 123_456_789_012_345_678_901_234_567) +test("{:,}", 23_456_789_012_345_678_901_234_567) +test("{:,}", 3_456_789_012_345_678_901_234_567) +test("{:,}", -123_456_789_012_345_678_901_234_567) +test("{:,}", -23_456_789_012_345_678_901_234_567) +test("{:,}", -3_456_789_012_345_678_901_234_567) diff --git a/tests/basics/string_format_sep.py b/tests/basics/string_format_sep.py new file mode 100644 index 00000000000..de131fdaf33 --- /dev/null +++ b/tests/basics/string_format_sep.py @@ -0,0 +1,9 @@ +try: + "%d" % 1 +except TypeError: + print("SKIP") + raise SystemExit + +for v in (0, 0x10, 0x1000, -0x10, -0x1000): + for sz in range(1, 12): print(("{:0%d,d}" % sz).format(v)) + for sz in range(1, 12): print(("{:0%d_x}" % sz).format(v)) diff --git a/tests/basics/string_fstring.py b/tests/basics/string_fstring.py index 42d093b37b5..d94cc0cd3e6 100644 --- a/tests/basics/string_fstring.py +++ b/tests/basics/string_fstring.py @@ -65,3 +65,17 @@ def foo(a, b): # Still allow ! in expressions. print(f"{'1' if a != '456' else '0'!r:8s}") print(f"{'1' if a != '456' else '0'!s:8s}") + +# Concatenation of adjacent f-strings. +print(f"" f"") +print(f"a" f"b") +print(f"{x}" f"{y}") +print( + f"a{x}b---------------------------------" + f"cd---------------------------------" + f"e{y}f---------------------------------" +) + +# Raw f-strings. +print(rf"\r\a\w {'f'} \s\t\r\i\n\g") +print(fr"\r{x}") diff --git a/tests/basics/string_fstring_debug.py.exp b/tests/basics/string_fstring_debug.py.exp deleted file mode 100644 index f0309e1c98a..00000000000 --- a/tests/basics/string_fstring_debug.py.exp +++ /dev/null @@ -1,9 +0,0 @@ -x=1 -x=00000001 -a x=1 b 2 c -a x=00000001 b 2 c -a f() + g("foo") + h()=15 b -a f() + g("foo") + h()=0000000f b -a 1,=(1,) b -a x,y,=(1, 2) b -a x,1=(1, 1) b diff --git a/tests/basics/string_startswith.py b/tests/basics/string_startswith.py index e63ae3c1866..eefdea82198 100644 --- a/tests/basics/string_startswith.py +++ b/tests/basics/string_startswith.py @@ -10,6 +10,25 @@ print("1fo".startswith("foo", 1)) print("1fo".startswith("foo", 10)) +print("1foobar".startswith("foo", 1, 5)) +print("1foobar".startswith("foo", 1, 4)) +print("1foobar".startswith("foo", 1, 3)) +print("1foobar".startswith("oo", 2, 4)) +print("1foobar".startswith("o", 3, 4)) +print("1foobar".startswith("o", 4, 4)) +print("1foobar".startswith("o", 5, 4)) + +print("foobar".startswith("foo", None, None)) +print("foobar".startswith("foo", None, 3)) +print("foobar".startswith("foo", None, 2)) +print("foobar".startswith("bar", 3, None)) + + +print("foobar".startswith(("foo", "sth"))) +print("foobar".startswith(("sth", "foo"))) +print("foobar".startswith(("sth", "foo2"))) +print("foobar".startswith(("foo", ))) + try: "foobar".startswith(1) except TypeError: diff --git a/tests/basics/string_startswith_upy.py b/tests/basics/string_startswith_upy.py deleted file mode 100644 index 9ea1796c218..00000000000 --- a/tests/basics/string_startswith_upy.py +++ /dev/null @@ -1,6 +0,0 @@ -# MicroPython doesn't support tuple argument - -try: - "foobar".startswith(("foo", "sth")) -except TypeError: - print("TypeError") diff --git a/tests/basics/string_startswith_upy.py.exp b/tests/basics/string_startswith_upy.py.exp deleted file mode 100644 index 6002b71c56e..00000000000 --- a/tests/basics/string_startswith_upy.py.exp +++ /dev/null @@ -1 +0,0 @@ -TypeError diff --git a/tests/basics/subclass_classmethod.py b/tests/basics/subclass_classmethod.py index 00a2ebd7cd3..3089726aa9b 100644 --- a/tests/basics/subclass_classmethod.py +++ b/tests/basics/subclass_classmethod.py @@ -35,3 +35,34 @@ class B(A): B.bar() # class calling classmethod B().bar() # instance calling classmethod B().baz() # instance calling normal method + +# super inside a classmethod +# ensure the argument of the super method that is called is the child type + + +class C: + @classmethod + def f(cls): + print("C.f", cls.__name__) # cls should be D + + @classmethod + def g(cls): + print("C.g", cls.__name__) # cls should be D + + +class D(C): + @classmethod + def f(cls): + print("D.f", cls.__name__) + super().f() + + @classmethod + def g(cls): + print("D.g", cls.__name__) + super(D, cls).g() + + +D.f() +D.g() +D().f() +D().g() diff --git a/tests/basics/subclass_native1.py b/tests/basics/subclass_native1.py index 288a686d1a7..74b377eac91 100644 --- a/tests/basics/subclass_native1.py +++ b/tests/basics/subclass_native1.py @@ -21,11 +21,9 @@ class mylist(list): # TODO: Faults #print(a + a) -def foo(): - print("hello from foo") - +# subclassing a type that doesn't have make_new at the C level (not allowed) try: - class myfunc(type(foo)): + class myfunc(type([].append)): pass except TypeError: print("TypeError") diff --git a/tests/basics/subclass_native_call.py b/tests/basics/subclass_native_call.py new file mode 100644 index 00000000000..e77287060cc --- /dev/null +++ b/tests/basics/subclass_native_call.py @@ -0,0 +1,27 @@ +# test calling a subclass of a native class that supports calling + +# For this test we need a native class that can be subclassed (has make_new) +# and is callable (has call). The only one available is machine.Signal, which +# in turns needs PinBase. +try: + import machine + machine.PinBase + machine.Signal +except: + print("SKIP") + raise SystemExit + +class Pin(machine.PinBase): + #def __init__(self): + # self.v = 0 + + def value(self, v=None): + return 42 + +class MySignal(machine.Signal): + pass + +s = MySignal(Pin()) + +# apply call to the subclass, which should call the native base +print(s()) diff --git a/tests/basics/subclass_native_call.py.exp b/tests/basics/subclass_native_call.py.exp new file mode 100644 index 00000000000..d81cc0710eb --- /dev/null +++ b/tests/basics/subclass_native_call.py.exp @@ -0,0 +1 @@ +42 diff --git a/tests/basics/subclass_native_init.py b/tests/basics/subclass_native_init.py index 38d2f23ac38..102befd551f 100644 --- a/tests/basics/subclass_native_init.py +++ b/tests/basics/subclass_native_init.py @@ -1,11 +1,44 @@ # test subclassing a native type and overriding __init__ +if not hasattr(object, "__init__"): + print("SKIP") + raise SystemExit + # overriding list.__init__() class L(list): def __init__(self, a, b): super().__init__([a, b]) print(L(2, 3)) +# with keyword arguments, with star arguments and without because those use different C calls +class D(dict): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) +print(D()) +print(D([('a', 1)])) +print(D([('a', 1)], a=2, b=3)) +print(D(a=2, b=3)) + +class D(dict): + def __init__(self): + super().__init__() +print(D()) + +class D(dict): + def __init__(self): + super().__init__([]) +print(D()) + +class D(dict): + def __init__(self): + super().__init__(a=1) +print(D()) + +class D(dict): + def __init__(self): + super().__init__([], a=1) +print(D()) + # inherits implicitly from object class A: def __init__(self): diff --git a/tests/basics/subscr_tuple.py b/tests/basics/subscr_tuple.py index 0210e24df87..3b2703b829f 100644 --- a/tests/basics/subscr_tuple.py +++ b/tests/basics/subscr_tuple.py @@ -1,3 +1,4 @@ +# CIRCUITPY-CHANGE: micropython does not have this test file # subscripting a subclassed tuple class Foo(tuple): pass diff --git a/tests/basics/syntaxerror.py b/tests/basics/syntaxerror.py index c0702cb2452..7b6ef9b7550 100644 --- a/tests/basics/syntaxerror.py +++ b/tests/basics/syntaxerror.py @@ -86,7 +86,7 @@ def test_syntax(code): test_syntax("nonlocal a") test_syntax("await 1") -# error on uPy, warning on CPy +# error on MPy, warning on CPy #test_syntax("def f():\n a = 1\n global a") # default except must be last @@ -98,7 +98,7 @@ def test_syntax(code): # non-keyword after keyword test_syntax("f(a=1, 2)") -# doesn't error on uPy but should +# doesn't error on MPy but should #test_syntax("f(1, i for i in i)") # all elements of dict/set must be pairs or singles diff --git a/tests/basics/sys1.py b/tests/basics/sys1.py index 6266440e353..02946abc220 100644 --- a/tests/basics/sys1.py +++ b/tests/basics/sys1.py @@ -25,6 +25,18 @@ # Effectively skip subtests print(int) +if hasattr(sys.implementation, '_build'): + print(type(sys.implementation._build)) +else: + # Effectively skip subtests + print(str) + +if hasattr(sys.implementation, '_thread'): + print(sys.implementation._thread in ("GIL", "unsafe")) +else: + # Effectively skip subtests + print(True) + try: print(sys.intern('micropython') == 'micropython') has_intern = True diff --git a/tests/basics/sys_tracebacklimit.py b/tests/basics/sys_tracebacklimit.py index 3ae372b8d52..6f575fde654 100644 --- a/tests/basics/sys_tracebacklimit.py +++ b/tests/basics/sys_tracebacklimit.py @@ -30,7 +30,7 @@ def print_exc(e): if l.startswith(" File "): l = l.split('"') print(l[0], l[2]) - # uPy and CPy tracebacks differ in that CPy prints a source line for + # MPy and CPy tracebacks differ in that CPy prints a source line for # each traceback entry. In this case, we know that offending line # has 4-space indent, so filter it out. elif not l.startswith(" "): diff --git a/tests/basics/sys_tracebacklimit.py.native.exp b/tests/basics/sys_tracebacklimit.py.native.exp new file mode 100644 index 00000000000..f9d30c05856 --- /dev/null +++ b/tests/basics/sys_tracebacklimit.py.native.exp @@ -0,0 +1,22 @@ +ValueError: value + +limit 4 +ValueError: value + +limit 3 +ValueError: value + +limit 2 +ValueError: value + +limit 1 +ValueError: value + +limit 0 +ValueError: value + +limit -1 +ValueError: value + +True +False diff --git a/tests/basics/try_finally_continue.py.exp b/tests/basics/try_finally_continue.py.exp deleted file mode 100644 index 2901997b1aa..00000000000 --- a/tests/basics/try_finally_continue.py.exp +++ /dev/null @@ -1,9 +0,0 @@ -4 0 -continue -4 1 -continue -4 2 -continue -4 3 -continue -None diff --git a/tests/basics/tuple1.py b/tests/basics/tuple1.py index 72bb3f01bff..70ae071898e 100644 --- a/tests/basics/tuple1.py +++ b/tests/basics/tuple1.py @@ -17,7 +17,7 @@ x += (10, 11, 12) print(x) -# construction of tuple from large iterator (tests implementation detail of uPy) +# construction of tuple from large iterator (tests implementation detail of MicroPython) print(tuple(range(20))) # unsupported unary operation diff --git a/tests/circuitpython-manual/alarm/sleep_memory_persist.py b/tests/circuitpython-manual/alarm/sleep_memory_persist.py new file mode 100644 index 00000000000..39e6baafca7 --- /dev/null +++ b/tests/circuitpython-manual/alarm/sleep_memory_persist.py @@ -0,0 +1,100 @@ +"""Reproducer for https://github.com/adafruit/circuitpython/issues/10896 + +Copy to code.py. Sequences through test steps using sleep_memory to +track state. + +The test scoreboard is printed to the magtag e-ink display after every +run so the final display shows cumulative results. +""" + +import alarm +import binascii +import microcontroller +import struct +import supervisor +import time + +# Safe mode avoidance +# On boot CircuitPython writes a SAFE_MODE_USER guard to an RTC register, +# If a second boot occurs before 1000ms elapses then we enter safe mode. +# So, wait for 1000+1ms before calling microcontroller.reset(). +_SAFE_MODE_WINDOW_MS = 1000 + + +def _wait_for_safe_mode_window(): + elapsed_ms = time.monotonic() * 1000 + remaining = _SAFE_MODE_WINDOW_MS + 1 - elapsed_ms + if remaining > 0: + time.sleep(remaining / 1000) + + +# Test result enum +_UNTESTED = 0 +_PASS = 1 +_FAIL = 2 +_LABEL = {_UNTESTED: "-", _PASS: "PASS", _FAIL: "FAIL"} + +# CRC32-protected state in sleep_memory +# [magic:2][step:1][r_reset:1][r_reload:1][pad:1][crc32:4] +_MAGIC = 0xBE01 +_FMT = " board.D5 +# mic LRCL -> board.D6 +# mic DOUT -> board.D9 +# neopixel -> board.D10 +# +# The mic's 24-bit samples ride in 32-bit slots, so we use bit_depth=32 and +# an array.array("I", ...). For SPH0645 set left_justified=True. + +import array +import math +import time + +import board +import audioi2sin +import neopixel + +NUM_PIXELS = 30 +PIXEL_PIN = board.D10 + +SAMPLE_RATE = 16000 +SAMPLES_PER_FRAME = 512 # ~32 ms windows + +pixels = neopixel.NeoPixel(PIXEL_PIN, NUM_PIXELS, brightness=0.3, auto_write=False) + +mic = audioi2sin.I2SIn( + bit_clock=board.D5, + word_select=board.D6, + data=board.D9, + sample_rate=SAMPLE_RATE, + bit_depth=32, + mono=True, + left_justified=False, # set True for SPH0645LM4H +) + +buf = array.array("i", [0] * SAMPLES_PER_FRAME) + + +def wheel(pos): + pos = pos % 256 + if pos < 85: + return (pos * 3, 255 - pos * 3, 0) + if pos < 170: + pos -= 85 + return (255 - pos * 3, 0, pos * 3) + pos -= 170 + return (0, pos * 3, 255 - pos * 3) + + +# Smoothed noise floor + peak so the effect adapts to the room. +noise_floor = 2000.0 +peak = 20000.0 +hue = 0 +smoothed_level = 0.0 + +while True: + mic.record(buf, len(buf)) + + # Compute RMS of the window. + acc = 0 + for s in buf: + acc += s * s + rms = math.sqrt(acc / len(buf)) + + # Track a slow noise floor and a decaying peak for auto-gain. + noise_floor = 0.995 * noise_floor + 0.005 * rms + if rms > peak: + peak = rms + else: + peak *= 0.995 + if peak < noise_floor + 1000: + peak = noise_floor + 1000 + + level = (rms - noise_floor) / (peak - noise_floor) + if level < 0: + level = 0.0 + elif level > 1: + level = 1.0 + + # Smooth the bar so it doesn't jitter on every frame. + smoothed_level = 0.6 * smoothed_level + 0.4 * level + + lit = int(smoothed_level * NUM_PIXELS) + hue = (hue + 2) % 256 + + for i in range(NUM_PIXELS): + if i < lit: + r, g, b = wheel((hue + i * (256 // NUM_PIXELS)) % 256) + pixels[i] = (r, g, b) + else: + pixels[i] = (0, 0, 0) + pixels.show() + + time.sleep(0.005) diff --git a/tests/circuitpython-manual/audioi2sin/i2sin_record_sdcard.py b/tests/circuitpython-manual/audioi2sin/i2sin_record_sdcard.py new file mode 100644 index 00000000000..c381e272bf7 --- /dev/null +++ b/tests/circuitpython-manual/audioi2sin/i2sin_record_sdcard.py @@ -0,0 +1,105 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +# Record a longer I2S audio capture to a WAV file on an SD card. +# +# Produces /sd/recording.wav. Set left_justified=True for SPH0645LM4H mics. + +import array +import struct +import time + +import ulab.numpy as np +import board +import busio +import sdcardio +import storage +import audioi2sin + +# ---- Recording config ------------------------------------------------------ +SAMPLE_RATE = 16000 +RECORD_SECONDS = 10 +CHUNK_SAMPLES = 1024 # samples captured per record() call +OUTPUT_PATH = "/sd/talk.wav" + +# ---- Mount SD -------------------------------------------------------------- +spi = board.SPI() +sdcard = sdcardio.SDCard(spi, cs=board.D10, baudrate=24_000_000) +vfs = storage.VfsFat(sdcard) +storage.mount(vfs, "/sd") + +# ---- Mic ------------------------------------------------------------------- +# 24-bit MEMS mics ride in 32-bit slots. Downconvert each slot to a +# signed 16-bit PCM sample before writing. +mic = audioi2sin.I2SIn( + bit_clock=board.D5, + word_select=board.D6, + data=board.D9, + sample_rate=SAMPLE_RATE, + bit_depth=32, + mono=True, + left_justified=False, # True for SPH0645LM4H +) + +actual_rate = mic.sample_rate +print("Recording at", actual_rate, "Hz for", RECORD_SECONDS, "s ->", OUTPUT_PATH) + +raw = array.array("i", [0] * CHUNK_SAMPLES) +pcm16 = array.array("h", [0] * CHUNK_SAMPLES) + + +def write_wav_header(f, sample_rate, num_samples, bits_per_sample=16, channels=1): + byte_rate = sample_rate * channels * bits_per_sample // 8 + block_align = channels * bits_per_sample // 8 + data_size = num_samples * block_align + f.write(b"RIFF") + f.write(struct.pack("> 16 # take top 16 bits + pcm16[i] = s + # Write only the valid portion. + f.write(memoryview(pcm16)[:n]) + written += n + + elapsed = time.monotonic() - start + # Rewrite header now that we know the true sample count. + f.seek(0) + write_wav_header(f, actual_rate, written) + +storage.umount("/sd") + +print("Done. Wrote", written, "samples in", round(elapsed, 2), "s") diff --git a/tests/circuitpython-manual/audioi2sin/i2sin_record_sdcard_output_bit_depth.py b/tests/circuitpython-manual/audioi2sin/i2sin_record_sdcard_output_bit_depth.py new file mode 100644 index 00000000000..cc2d2e78c29 --- /dev/null +++ b/tests/circuitpython-manual/audioi2sin/i2sin_record_sdcard_output_bit_depth.py @@ -0,0 +1,100 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 Tim Cocks for Adafruit Industries +# +# SPDX-License-Identifier: MIT + +# Record a longer I2S audio capture to a WAV file on an SD card, using the +# `output_bit_depth` argument to have the driver downconvert each 32-bit slot +# to signed 16-bit PCM. Compared to `i2sin_record_sdcard.py`, this avoids the +# Python-side shift loop and writes directly from the recording buffer. +# +# Produces /sd/talk.wav. Set left_justified=True for SPH0645LM4H mics. + +import array +import struct +import time + +import board +import sdcardio +import storage +import audioi2sin + +# ---- Recording config ------------------------------------------------------ +SAMPLE_RATE = 16000 +RECORD_SECONDS = 10 +CHUNK_SAMPLES = 1024 # samples captured per record() call +OUTPUT_PATH = "/sd/talk.wav" + +# ---- Mount SD -------------------------------------------------------------- +spi = board.SPI() +sdcard = sdcardio.SDCard(spi, cs=board.D10, baudrate=24_000_000) +vfs = storage.VfsFat(sdcard) +storage.mount(vfs, "/sd") + +# ---- Mic ------------------------------------------------------------------- +# 24-bit MEMS mics ride in 32-bit slots. Ask the driver to downconvert each +# slot to a signed 16-bit PCM sample, so `record()` writes straight into a +# WAV-ready 'h' buffer. +mic = audioi2sin.I2SIn( + bit_clock=board.D5, + word_select=board.D6, + data=board.D9, + sample_rate=SAMPLE_RATE, + bit_depth=32, + output_bit_depth=16, + mono=True, + left_justified=False, # True for SPH0645LM4H +) + +actual_rate = mic.sample_rate +print("Recording at", actual_rate, "Hz for", RECORD_SECONDS, "s ->", OUTPUT_PATH) + +pcm16 = array.array("h", [0] * CHUNK_SAMPLES) + + +def write_wav_header(f, sample_rate, num_samples, bits_per_sample=16, channels=1): + byte_rate = sample_rate * channels * bits_per_sample // 8 + block_align = channels * bits_per_sample // 8 + data_size = num_samples * block_align + f.write(b"RIFF") + f.write(struct.pack(" **If using `run_serial_tests.py`** this step is done automatically — skip ahead. + +Copy the WAV test samples onto the board's `CIRCUITPY` drive root: + +``` +cp \ + tests/circuitpython-manual/audiocore/jeplayer-splash-8000-8bit-mono-unsigned.wav \ + tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-mono-signed.wav \ + tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-mono-signed.wav \ + tests/circuitpython-manual/audiocore/jeplayer-splash-8000-16bit-stereo-signed.wav \ + tests/circuitpython-manual/audiocore/jeplayer-splash-44100-16bit-stereo-signed.wav \ + /Volumes/CIRCUITPY/ +``` + +These five files cover every exercised code path: +- `8000-8bit-mono-unsigned` — 8-bit unsigned decode path, audibly lo-fi +- `8000-16bit-mono-signed` — 16-bit signed decode path at lowest sample rate +- `44100-16bit-mono-signed` — 16-bit at highest sample rate (DMA reconfiguration, audible quality difference) +- `8000-16bit-stereo-signed` — stereo decode path, left→A0, right→A1 +- `44100-16bit-stereo-signed` — stereo at 44.1 kHz + +The 16 kHz files in the audiocore test set are skipped because they exercise +no code paths beyond 8 kHz and 44.1 kHz. 24-bit WAVs are not supported by +`audiocore.WaveFile` and will raise `OSError` if loaded — they are omitted on +purpose. + +Copy the test scripts to the board as well (or paste them into the REPL): + +``` +cp tests/circuitpython-manual/audioio/wavefile_playback.py /Volumes/CIRCUITPY/ +cp tests/circuitpython-manual/audioio/wavefile_pause_resume.py /Volumes/CIRCUITPY/ +cp tests/circuitpython-manual/audioio/single_buffer_loop.py /Volumes/CIRCUITPY/ +cp tests/circuitpython-manual/audioio/stereo_playback.py /Volumes/CIRCUITPY/ +``` + +## Test 1 — WAV File Playback (`wavefile_playback.py`) *(automated)* + +Verifies that `AudioOut(board.A0)` can play WAV files at 8 kHz and 44.1 kHz +with 8-bit unsigned and 16-bit signed encodings. Stereo WAVs are played here +through the mono `AudioOut` (only the left channel is mixed to A0); the +stereo path is exercised separately in Test 5. + +**Note:** 24-bit WAV files are not supported by `audiocore.WaveFile` and will +print an `OSError` if any are present on the filesystem. That is expected. + +**Run from the REPL:** + +```python +import os +os.chdir("/") +exec(open("wavefile_playback.py").read()) +``` + +**Expected output (order may vary by filename sort):** + +``` +playing jeplayer-splash-44100-16bit-mono-signed.wav +playing jeplayer-splash-8000-16bit-mono-signed.wav +playing jeplayer-splash-8000-8bit-mono-unsigned.wav +done +``` + +**What to listen for:** + +- Each supported WAV plays the "jeplayer splash" jingle to completion before the next starts. +- No loud pops at the start or end of each file (the DAC ramp-in / ramp-out should suppress them). +- Audio pitch should match the sample rate: the 44100 Hz file sounds the most natural; the 8000 Hz file sounds lower fidelity. + +## Test 2 — Pause and Resume (`wavefile_pause_resume.py`) *(automated)* + +Verifies `AudioOut.pause()` / `AudioOut.resume()` by toggling every 100 ms during playback. The audio will sound choppy — that is intentional. + +**Run from the REPL:** + +```python +exec(open("wavefile_pause_resume.py").read()) +``` + +**Expected output (repeating for each WAV):** + +``` +playing with pause/resume: jeplayer-splash-44100-16bit-mono-signed.wav + paused + resumed + ... +playing with pause/resume: jeplayer-splash-8000-16bit-mono-signed.wav + paused + resumed + ... +playing with pause/resume: jeplayer-splash-8000-8bit-mono-unsigned.wav + paused + resumed + ... +done +``` + +**What to verify:** + +- The REPL prints alternating "paused" / "resumed" lines. +- Audio cuts in and out in sync with the prints. +- Playback eventually completes (the `while dac.playing` loop exits normally). +- No hard fault or hang. + +## Test 3 — Looping Sine Wave (`single_buffer_loop.py`) *(automated)* + +Verifies `RawSample` with `loop=True` and tests all four sample formats: +`unsigned 8-bit`, `signed 8-bit`, `unsigned 16-bit`, `signed 16-bit`. + +Each sample generates one cycle of a 440 Hz sine wave and loops for 1 second. + +**Run from the REPL:** + +```python +exec(open("single_buffer_loop.py").read()) +``` + +**Expected output:** + +``` +unsigned 8 bit + +signed 8 bit + +unsigned 16 bit + +signed 16 bit + +done +``` + +**What to listen for:** + +- A 440 Hz tone (concert A) for approximately 1 second for each format. +- All four formats use the same 8 kHz sample rate and should sound + essentially identical in pitch and volume — the test is comparing + format-conversion paths, not playback rates. +- No pops or glitches during the loop. +- Clean silence between tones (quiescent DAC value holds between `stop()` calls). + +## Test 4 — `deinit` and Re-init *(automated)* + +Verifies that `AudioOut` can be deconstructed and reconstructed without rebooting, and that pin A0 is properly released. + +```python +import audioio, analogio, board + +# Construct and immediately deinit AudioOut +dac = audioio.AudioOut(board.A0) +dac.deinit() + +# PA04 should now be free for AnalogOut +aout = analogio.AnalogOut(board.A0) +aout.value = 32768 # mid-scale +aout.deinit() + +# Re-create AudioOut on the same pin +dac2 = audioio.AudioOut(board.A0) +dac2.deinit() +print("pass") +``` + +**Expected output:** `pass` with no exceptions. + +## Test 5 — Stereo Playback (`stereo_playback.py`) *(automated)* + +Verifies that `AudioOut(board.A0, right_channel=board.A1)` drives both DAC +channels independently: left on **A0 (PA04, DAC_CH1)**, right on +**A1 (PA05, DAC_CH2)**, both clocked by TIM6. + +The script runs four phases in order: + +1. **Left-only 440 Hz tone** (~1 s) — only A0 should produce audio. +2. **Right-only 440 Hz tone** (~1 s) — only A1 should produce audio. +3. **Both-channel 440 Hz tone** (~1 s) — equal amplitude on both pins. +4. **Pan sweep L → R** (~3 s) — continuous equal-power (cos/sin) crossfade from A0 to A1 in a single non-looped buffer. +5. Then plays each stereo WAV (`44100` and `8000` Hz) in full. + +**Hardware required:** connect a stereo headphone/amp to A0 (left) and A1 +(right) with common ground, or scope-probe each pin separately. + +**Run from the REPL:** + +```python +import os +os.chdir("/") +exec(open("stereo_playback.py").read()) +``` + +**Expected output:** + +``` +channel test: left only +channel test: right only +channel test: both channels +pan sweep: left to right +playing stereo: jeplayer-splash-44100-16bit-stereo-signed.wav +playing stereo: jeplayer-splash-8000-16bit-stereo-signed.wav +done +``` + +**What to listen / look for:** + +- "left only" → tone in left ear, silence in right. +- "right only" → tone in right ear, silence in left. +- "both channels" → centered tone in both ears. +- "pan sweep" → tone smoothly travels left → right over ~3 s. +- Stereo WAVs play with proper L/R separation; no cross-contamination. +- On a scope: probing A0 and A1 simultaneously during phases 1 and 2 should + show one channel idle (mid-scale DC) while the other carries the sine. + +## Oscilloscope Checks (Optional) + +Each test script drives `board.D4` (pin D4) low at the start of each playback and high when it ends. This provides a clean trigger edge for a scope. + +- **Test 1:** Probe A0 — should show a sampled waveform at the correct sample rate. Probe D4 for a gate signal that spans the file duration. +- **Test 3:** Probe A0 — should show a 440 Hz staircase-sine at the DAC output (12-bit steps visible at 44.1 kHz; fewer at 8 kHz). A simple RC low-pass filter (1 kΩ + 100 nF) on the A0 output will smooth the staircase significantly. + +## Known Limitations + +- **Left channel must be A0 (PA04)**. Any other pin raises `ValueError: AudioOut requires pin A0 (PA04)`. +- **Right channel must be A1 (PA05)** when used. Any other pin raises `ValueError: AudioOut right channel requires pin A1 (PA05)`. +- **24-bit WAV files** are not supported by `audiocore.WaveFile` and will raise `OSError` when opened. +- Only one `AudioOut` instance can be active at a time. diff --git a/tests/circuitpython-manual/audioio/run_serial_tests.py b/tests/circuitpython-manual/audioio/run_serial_tests.py new file mode 100644 index 00000000000..9fbbe555592 --- /dev/null +++ b/tests/circuitpython-manual/audioio/run_serial_tests.py @@ -0,0 +1,582 @@ +#!/usr/bin/env python3 +""" +run_serial_tests.py — Automated REPL-based tests for STM32F405 audioio. + +Automates Tests 1–5 from README.md by: + 1. Copying WAV files and test scripts to the board via mpremote. + 2. Running each test on the device via the CircuitPython REPL. + 3. Comparing captured output to expected patterns and reporting PASS/FAIL. + +Usage: + python3 run_serial_tests.py + python3 run_serial_tests.py --port /dev/cu.usbmodemXXX + python3 run_serial_tests.py --circuitpy /Volumes/CIRCUITPY # macOS + python3 run_serial_tests.py --circuitpy /media/user/CIRCUITPY # Linux + python3 run_serial_tests.py --circuitpy D:\\ # Windows + python3 run_serial_tests.py --no-copy --tests 3,4 + +Requirements: + pip install mpremote +""" + +from __future__ import annotations + +import argparse +import os +import shutil +import subprocess +import sys +import time + +# --------------------------------------------------------------------------- +# Paths +# --------------------------------------------------------------------------- +SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) +REPO_ROOT = os.path.abspath(os.path.join(SCRIPT_DIR, "../../..")) +AUDIOCORE_DIR = os.path.join(REPO_ROOT, "tests", "circuitpython-manual", "audiocore") + +WAV_FILES = [ + "jeplayer-splash-8000-8bit-mono-unsigned.wav", + "jeplayer-splash-8000-16bit-mono-signed.wav", + "jeplayer-splash-44100-16bit-mono-signed.wav", + "jeplayer-splash-8000-16bit-stereo-signed.wav", + "jeplayer-splash-44100-16bit-stereo-signed.wav", +] + +TEST_SCRIPTS = [ + "wavefile_playback.py", + "wavefile_pause_resume.py", + "single_buffer_loop.py", + "stereo_playback.py", +] + +DEINIT_TEST_CODE = ( + "import audioio, analogio, board\n" + "dac = audioio.AudioOut(board.A0)\n" + "dac.deinit()\n" + "aout = analogio.AnalogOut(board.A0)\n" + "aout.value = 32768\n" + "aout.deinit()\n" + "dac2 = audioio.AudioOut(board.A0)\n" + "dac2.deinit()\n" + 'print("pass")\n' +) + +# --------------------------------------------------------------------------- +# mpremote helpers +# --------------------------------------------------------------------------- + + +def _mpremote(args: list, timeout: float = 30.0): + """Run an mpremote command, return (stdout, stderr). Raises on timeout.""" + try: + result = subprocess.run( + ["mpremote"] + args, + capture_output=True, + text=True, + timeout=timeout, + ) + return result.stdout, result.stderr + except subprocess.TimeoutExpired: + raise TimeoutError(f"mpremote timed out after {timeout}s") + except FileNotFoundError: + sys.exit("mpremote not found. Run: pip install mpremote") + + +# stderr substrings that indicate a transient host/USB issue worth retrying. +# Matched case-insensitively. CircuitPython USB-CDC briefly disappears during +# soft-reset and after some heavy DMA activity; mpremote's next invocation then +# either can't open the port or sees the kernel still holding the previous +# descriptor. +_RETRYABLE_STDERR = ( + "could not enter raw repl", + "failed to access", + "device not configured", + "errno 6", + "errno 16", + "resource busy", + "could not open", + "no such file or directory", + "serialexception", + "device disconnected", + "could not exclusively lock", +) + + +def _is_retryable(stderr: str) -> bool: + s = stderr.lower() + return any(needle in s for needle in _RETRYABLE_STDERR) + + +def _port_holders(port: str) -> list[str]: + """Return a human-readable list of processes holding *port* (Unix only). + + macOS / Linux only — uses `lsof`. Returns lines like "Code Helper (51298)". + Empty list when nothing holds the port or `lsof` is unavailable. + """ + if not port.startswith("/"): + return [] + holders: list[str] = [] + # Both /dev/cu.* (callout) and /dev/tty.* (dial-in) refer to the same UART + # on macOS — VS Code typically opens /dev/tty.* while we ask for /dev/cu.*, + # so check both. + candidates = {port} + if "/cu." in port: + candidates.add(port.replace("/cu.", "/tty.", 1)) + elif "/tty." in port: + candidates.add(port.replace("/tty.", "/cu.", 1)) + for path in candidates: + if not os.path.exists(path): + continue + try: + result = subprocess.run( + ["lsof", "-Fcp", path], + capture_output=True, + text=True, + timeout=5, + ) + except (FileNotFoundError, subprocess.TimeoutExpired): + return [] + pid = command = None + for line in result.stdout.splitlines(): + if line.startswith("p"): + pid = line[1:] + elif line.startswith("c"): + command = line[1:] + if pid: + holders.append(f"{command} (PID {pid}) on {path}") + pid = command = None + return holders + + +def _wait_for_port(port: str, timeout: float = 10.0) -> bool: + """Block until *port* exists in the filesystem, or *timeout* elapses. + + macOS / Linux expose serial ports as /dev nodes; Windows uses COMx which is + not a filesystem path, so on Windows we just sleep briefly and trust the + next mpremote call to surface the real error. + """ + if not port.startswith("/"): + time.sleep(0.5) + return True + deadline = time.time() + timeout + while time.time() < deadline: + if os.path.exists(port): + return True + time.sleep(0.1) + return False + + +def _interrupt_running_code(port: str, soft_reset: bool = False) -> None: + """Halt any code running on the device so mpremote can enter raw REPL. + + Strategy: + 1. Ctrl-C burst — usually breaks a busy print loop. + 2. Optional Ctrl-D soft reset, followed by a Ctrl-C flood through the + reboot window so code.py is interrupted *before* it gets busy again. + """ + try: + import serial # type: ignore[import-not-found] + except ImportError: + return + try: + with serial.Serial(port, 115200, timeout=0.1) as ser: + for _ in range(5): + ser.write(b"\x03") + ser.flush() + time.sleep(0.05) + if soft_reset: + ser.write(b"\x04") # Ctrl-D → soft reboot + ser.flush() + # Flood Ctrl-C while CircuitPython reboots so code.py can't + # get past its first iteration before we break in. + deadline = time.time() + 3.0 + while time.time() < deadline: + ser.write(b"\x03") + ser.flush() + time.sleep(0.05) + time.sleep(0.3) + ser.reset_input_buffer() + except (serial.SerialException, OSError): + pass + + +def find_port() -> str: + """Return the port of the first Adafruit device found by mpremote devs.""" + stdout, _ = _mpremote(["devs"]) + for line in stdout.splitlines(): + parts = line.split() + if not parts: + continue + # mpremote devs output: + # Filter for Adafruit VID (239a) + if any("239a" in p for p in parts): + return parts[0] + # Fall back to any USB serial port that isn't Bluetooth/wlan + for line in stdout.splitlines(): + parts = line.split() + if ( + parts + and parts[0].startswith("/dev/") + and "Bluetooth" not in line + and "wlan" not in line + ): + return parts[0] + raise RuntimeError( + "No board detected. Connect the board and/or pass --port.\n" + f"mpremote devs output:\n{stdout}" + ) + + +def find_circuitpy() -> str | None: + """Return the path to the mounted CIRCUITPY volume, or None if not found.""" + import platform + + system = platform.system() + + if system == "Darwin": + # Glob so a second CIRCUITPY volume (mounted as "CIRCUITPY 1") is found. + import glob + + candidates = sorted(glob.glob("/Volumes/CIRCUITPY*")) + elif system == "Windows": + # Scan all drive letters for a CIRCUITPY volume label. + import string + import ctypes + + candidates = [] + kernel32 = ctypes.windll.kernel32 # type: ignore[attr-defined] + buf = ctypes.create_unicode_buffer(256) + for letter in string.ascii_uppercase: + root = f"{letter}:\\" + if kernel32.GetVolumeInformationW(root, buf, 256, None, None, None, None, 0): + if buf.value == "CIRCUITPY": + candidates.append(root) + else: + # Linux: common udev/udisks mount points + candidates = ["/media/CIRCUITPY", "/run/media/CIRCUITPY"] + try: + import pwd + + user = pwd.getpwuid(os.getuid()).pw_name + candidates.insert(0, f"/run/media/{user}/CIRCUITPY") + candidates.insert(0, f"/media/{user}/CIRCUITPY") + except Exception: + pass + + for path in candidates: + if os.path.isdir(path): + return path + return None + + +def copy_files(port: str, circuitpy: str | None = None): + """Copy WAV samples and test scripts to the board.""" + mount = circuitpy or find_circuitpy() + if mount: + print(f"Copying files to board via {mount} ...") + else: + print("Copying files to board via mpremote ...") + files = [(os.path.join(AUDIOCORE_DIR, w), w) for w in WAV_FILES] + [ + (os.path.join(SCRIPT_DIR, s), s) for s in TEST_SCRIPTS + ] + # Check if device has enough space for test files + if mount: + needed = 0 + for src, dst in files: + if not os.path.exists(src): + continue + needed += os.path.getsize(src) + dest_path = os.path.join(mount, dst) + if os.path.exists(dest_path): + needed -= os.path.getsize(dest_path) + free = shutil.disk_usage(mount).free + if needed > free: + short = needed - free + print(f"ERROR: not enough space on {mount}.") + print(f" need: {needed / 1024:.1f} KiB") + print(f" free: {free / 1024:.1f} KiB") + print(f" short: {short / 1024:.1f} KiB") + print(f" Delete unrelated files (e.g. an old code.py or stale WAVs) and re-run.") + sys.exit(1) + missing = [] + for src, dst in files: + if not os.path.exists(src): + missing.append(src) + continue + if mount: + dest_path = os.path.join(mount, dst) + shutil.copy2(src, dest_path) + print(f" {dst} (copied)") + else: + stdout, stderr = _mpremote(["connect", port, "fs", "cp", src, f":/{dst}"], timeout=30) + if stderr and "Error" in stderr: + print(f" {dst} (FAILED: {stderr.strip()})") + else: + status = "up to date" if "Up to date" in stdout else "copied" + print(f" {dst} ({status})") + if missing: + print("WARNING: source files not found:") + for m in missing: + print(f" {m}") + print() + + +# --------------------------------------------------------------------------- +# Test runner +# --------------------------------------------------------------------------- + +PASS_TAG = "PASS" +FAIL_TAG = "FAIL" + + +def _check(condition: bool, message: str) -> bool: + print(f" [{PASS_TAG if condition else FAIL_TAG}] {message}") + return condition + + +def _run_exec(port: str, code: str, label: str, timeout: float, retries: int = 3): + """Execute *code* on the device via mpremote exec and print the output. + + Retries cover three failure modes: + * raw-REPL handshake blocked by a running code.py → Ctrl-C burst. + * Persistent handshake failure → soft-reset + Ctrl-C flood. + * Host-side serial drop ("device in use", "Errno 6", etc.) → wait for the + port node to re-appear, then retry. CircuitPython's USB-CDC can briefly + vanish after heavy DMA traffic or soft-reset. + """ + print(f"\n{'=' * 60}") + print(f" {label}") + print("=" * 60) + stdout = "" + stderr = "" + for attempt in range(retries + 1): + if not _wait_for_port(port, timeout=10.0): + print(f" [retry {attempt}/{retries}] port {port} not present — waited 10s") + continue + try: + stdout, stderr = _mpremote(["connect", port, "exec", code], timeout=timeout) + except TimeoutError as exc: + print(f" [FAIL] {exc}") + return False, "", "" + if not _is_retryable(stderr): + break + if attempt < retries: + handshake = "could not enter raw repl" in stderr.lower() + # Soft-reset only on persistent raw-REPL failures, not on host drops + # (a soft-reset there just makes the disconnect window longer). + escalate = handshake and attempt >= 1 + if handshake: + tactic = "soft-reset + Ctrl-C flood" if escalate else "Ctrl-C burst" + else: + tactic = f"port-drop recovery ({stderr.strip().splitlines()[-1] if stderr.strip() else '?'})" + print(f" [retry {attempt + 1}/{retries}] {tactic}") + _wait_for_port(port, timeout=10.0) + _interrupt_running_code(port, soft_reset=escalate) + time.sleep(0.5) + print("Output:") + for line in stdout.splitlines(): + print(f" {line}") + if stderr: + print("Stderr:") + for line in stderr.splitlines(): + print(f" {line}") + return True, stdout, stderr + + +def _settle_between_tests(port: str) -> None: + """Drain any lingering REPL output and wait for the port to be ready. + + CircuitPython occasionally re-enumerates its USB-CDC after a heavy test; + next mpremote call then races the kernel re-binding the tty. Polling for + the port node and then sending a Ctrl-C burst gives the host a clean + starting state before the next exec. + """ + _wait_for_port(port, timeout=10.0) + _interrupt_running_code(port, soft_reset=False) + time.sleep(0.3) + + +# --------------------------------------------------------------------------- +# Individual tests +# --------------------------------------------------------------------------- + + +def test1_wavefile_playback(port: str) -> bool: + code = 'exec(open("/wavefile_playback.py").read())' + ok, stdout, stderr = _run_exec( + port, code, "Test 1 — WAV File Playback (wavefile_playback.py)", timeout=180 + ) + if not ok: + return False + passed = True + for wav in sorted(WAV_FILES): + passed &= _check(f"playing {wav}" in stdout, f"played {wav}") + passed &= _check("OSError" not in stdout, "No OSError reported during playback") + passed &= _check("done" in stdout, "Script completed with 'done'") + passed &= _check(not stderr, f"No exceptions (stderr={stderr!r})") + return passed + + +def test2_pause_resume(port: str) -> bool: + code = 'exec(open("/wavefile_pause_resume.py").read())' + ok, stdout, stderr = _run_exec( + port, code, "Test 2 — Pause / Resume (wavefile_pause_resume.py)", timeout=180 + ) + if not ok: + return False + passed = True + for wav in sorted(WAV_FILES): + passed &= _check( + f"playing with pause/resume: {wav}" in stdout, f"pause/resume header for {wav}" + ) + passed &= _check("paused" in stdout, "At least one 'paused' line printed") + passed &= _check("resumed" in stdout, "At least one 'resumed' line printed") + passed &= _check("TIMEOUT" not in stdout, "No pause/resume hang timeout") + passed &= _check("OSError" not in stdout, "No OSError reported during playback") + passed &= _check("done" in stdout, "Script completed with 'done'") + passed &= _check(not stderr, f"No exceptions (stderr={stderr!r})") + return passed + + +def test3_single_buffer_loop(port: str) -> bool: + code = 'exec(open("/single_buffer_loop.py").read())' + ok, stdout, stderr = _run_exec( + port, code, "Test 3 — Looping Sine Wave (single_buffer_loop.py)", timeout=30 + ) + if not ok: + return False + passed = True + for label in ("unsigned 8 bit", "signed 8 bit", "unsigned 16 bit", "signed 16 bit"): + passed &= _check(label in stdout, f"'{label}' label printed") + passed &= _check("done" in stdout, "Script completed with 'done'") + passed &= _check(not stderr, f"No exceptions (stderr={stderr!r})") + return passed + + +def test5_stereo_playback(port: str) -> bool: + code = 'exec(open("/stereo_playback.py").read())' + ok, stdout, stderr = _run_exec( + port, code, "Test 5 — Stereo Playback (stereo_playback.py)", timeout=180 + ) + if not ok: + return False + passed = True + passed &= _check("channel test: left only" in stdout, "Left-only channel tone played") + passed &= _check("channel test: right only" in stdout, "Right-only channel tone played") + passed &= _check("channel test: both channels" in stdout, "Both-channel tone played") + passed &= _check("pan sweep: left to right" in stdout, "Pan sweep played") + passed &= _check( + "playing stereo: jeplayer-splash-44100-16bit-stereo-signed.wav" in stdout, + "44100 Hz 16-bit stereo WAV played", + ) + passed &= _check( + "playing stereo: jeplayer-splash-8000-16bit-stereo-signed.wav" in stdout, + "8000 Hz 16-bit stereo WAV played", + ) + passed &= _check("done" in stdout, "Script completed with 'done'") + passed &= _check(not stderr, f"No exceptions (stderr={stderr!r})") + return passed + + +def test4_deinit(port: str) -> bool: + ok, stdout, stderr = _run_exec( + port, DEINIT_TEST_CODE, "Test 4 — deinit and Re-init (inline)", timeout=10 + ) + if not ok: + return False + passed = True + passed &= _check("pass" in stdout, "Script printed 'pass'") + passed &= _check(not stderr, f"No exceptions (stderr={stderr!r})") + return passed + + +# --------------------------------------------------------------------------- +# Main +# --------------------------------------------------------------------------- + + +def main(): + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + parser.add_argument("--port", help="Serial port (auto-detected if omitted)") + parser.add_argument( + "--circuitpy", + metavar="PATH", + help="Path to mounted CIRCUITPY volume (auto-detected if omitted)", + ) + parser.add_argument( + "--no-copy", + action="store_true", + help="Skip copying files to the board (assume they are already present)", + ) + parser.add_argument( + "--tests", + default="1,2,3,4,5", + help="Comma-separated list of test numbers to run (default: 1,2,3,4,5)", + ) + args = parser.parse_args() + + selected = set(args.tests.split(",")) + + port = args.port or find_port() + print(f"Using port: {port}\n") + + # Surface the common "VS Code has the serial monitor open" pitfall up front + # — otherwise every test fails with the opaque "in use by another program". + holders = _port_holders(port) + if holders: + print("ERROR: port is held by another process:") + for h in holders: + print(f" {h}") + print( + "Close the offending app (e.g. VS Code Serial Monitor, screen, tio)\n" + "and re-run. mpremote needs exclusive access." + ) + sys.exit(2) + + if not args.no_copy: + copy_files(port, circuitpy=args.circuitpy) + + # Halt any running code.py so the first test gets a clean raw-REPL entry. + _interrupt_running_code(port) + + test_runners = [ + ("1", "Test 1 — WAV Playback", test1_wavefile_playback), + ("2", "Test 2 — Pause/Resume", test2_pause_resume), + ("3", "Test 3 — Looping Sine", test3_single_buffer_loop), + ("4", "Test 4 — deinit/Re-init", test4_deinit), + ("5", "Test 5 — Stereo Playback", test5_stereo_playback), + ] + results: dict[str, bool] = {} + first = True + for key, name, runner in test_runners: + if key not in selected: + continue + if not first: + _settle_between_tests(port) + first = False + results[name] = runner(port) + + print(f"\n{'=' * 60}") + print("SUMMARY") + print("=" * 60) + all_passed = True + for name, passed in results.items(): + print(f" [{'PASS' if passed else 'FAIL'}] {name}") + all_passed = all_passed and passed + + print() + if all_passed: + print("All automated tests passed.") + print("Remaining manual step: audio/oscilloscope verification.") + sys.exit(0) + else: + print("One or more tests FAILED — see details above.") + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/tests/circuitpython-manual/audioio/single_buffer_loop.py b/tests/circuitpython-manual/audioio/single_buffer_loop.py new file mode 100644 index 00000000000..4a4c4304275 --- /dev/null +++ b/tests/circuitpython-manual/audioio/single_buffer_loop.py @@ -0,0 +1,62 @@ +import audiocore +import audioio +import board +import digitalio +import array +import time +import math + +# Optional trigger pin for oscilloscope synchronisation. +try: + trigger = digitalio.DigitalInOut(board.D4) + trigger.switch_to_output(True) +except AttributeError: + trigger = None + +# Generate one period of a 440 Hz sine wave. All four samples use the same +# sample rate so each plays the same audible pitch — the test is comparing +# the four format-conversion paths, not playback rates. +sample_rate = 8000 +length = sample_rate // 440 # samples per cycle + +sample_names = ["unsigned 8 bit", "signed 8 bit", "unsigned 16 bit", "signed 16 bit"] + +# unsigned 8 bit +u8 = array.array("B", [0] * length) +for i in range(length): + u8[i] = int(math.sin(math.pi * 2 * i / length) * 127 + 128) +samples = [audiocore.RawSample(u8, sample_rate=sample_rate)] + +# signed 8 bit +s8 = array.array("b", [0] * length) +for i in range(length): + s8[i] = int(math.sin(math.pi * 2 * i / length) * 127) +samples.append(audiocore.RawSample(s8, sample_rate=sample_rate)) + +# unsigned 16 bit +u16 = array.array("H", [0] * length) +for i in range(length): + u16[i] = int(math.sin(math.pi * 2 * i / length) * 32767 + 32768) +samples.append(audiocore.RawSample(u16, sample_rate=sample_rate)) + +# signed 16 bit +s16 = array.array("h", [0] * length) +for i in range(length): + s16[i] = int(math.sin(math.pi * 2 * i / length) * 32767) +samples.append(audiocore.RawSample(s16, sample_rate=sample_rate)) + +dac = audioio.AudioOut(board.A0) +for sample, name in zip(samples, sample_names): + print(name) + if trigger: + trigger.value = False + dac.play(sample, loop=True) + time.sleep(1) + dac.stop() + time.sleep(0.1) + if trigger: + trigger.value = True + print() + +dac.deinit() +print("done") diff --git a/tests/circuitpython-manual/audioio/stereo_playback.py b/tests/circuitpython-manual/audioio/stereo_playback.py new file mode 100644 index 00000000000..cfdb4d39540 --- /dev/null +++ b/tests/circuitpython-manual/audioio/stereo_playback.py @@ -0,0 +1,128 @@ +import audiocore +import audioio +import board +import digitalio +import array +import gc +import math +import time +import os + +# Optional trigger pin for oscilloscope synchronisation. +try: + trigger = digitalio.DigitalInOut(board.D4) + trigger.switch_to_output(True) +except AttributeError: + trigger = None + +dac = audioio.AudioOut(board.A0, right_channel=board.A1) + +# --------------------------------------------------------------------------- +# Channel-isolation tones: prove each DAC channel can be driven independently. +# Listener should hear the 440 Hz tone shift between ears. +# --------------------------------------------------------------------------- +sample_rate = 8000 +freq = 440 +length = sample_rate // freq +sine = [int(math.sin(2 * math.pi * i / length) * 16000) for i in range(length)] +silence = [0] * length + + +def stereo_buffer(left, right): + buf = array.array("h", [0] * (len(left) * 2)) + for i in range(len(left)): + buf[2 * i] = left[i] + buf[2 * i + 1] = right[i] + return buf + + +channel_tests = ( + ("left only", sine, silence), + ("right only", silence, sine), + ("both channels", sine, sine), +) + +for label, left, right in channel_tests: + print("channel test:", label) + sample = audiocore.RawSample( + stereo_buffer(left, right), channel_count=2, sample_rate=sample_rate + ) + if trigger: + trigger.value = False + dac.play(sample, loop=True) + time.sleep(1.0) + dac.stop() + if trigger: + trigger.value = True + time.sleep(0.2) + del sample + print() + +del channel_tests, sine, silence + +# --------------------------------------------------------------------------- +# Pan sweep: continuous equal-power L→R over 2 s. Single non-looped buffer, +# played once for a smooth crossfade with no DMA restart clicks. +# +# Linear amplitude pan sounds like centred stereo at the midpoint because both +# channels are equally loud. Equal-power (cos/sin) pan keeps total energy +# constant so the source is perceived as moving rather than collapsing inwards. +# +# 2 s @ 4 kHz stereo 8-bit signed = 16000 bytes. Halving the sample rate keeps +# the buffer small while doubling perceived motion duration; 220 Hz at 4 kHz +# has the same samples-per-cycle as the earlier 440 Hz @ 8 kHz tones. +# --------------------------------------------------------------------------- +gc.collect() +pan_sr = sample_rate // 2 +pan_freq = freq // 2 +pan_seconds = 3 +pan_frames = pan_sr * pan_seconds +pan_buf = array.array("b", bytes(pan_frames * 2)) +two_pi_freq_over_sr = 2 * math.pi * pan_freq / pan_sr +half_pi = math.pi / 2 +for i in range(pan_frames): + s = math.sin(two_pi_freq_over_sr * i) + t = i / pan_frames # 0 → 1 + l_gain = math.cos(t * half_pi) + r_gain = math.sin(t * half_pi) + pan_buf[2 * i] = int(s * l_gain * 120) + pan_buf[2 * i + 1] = int(s * r_gain * 120) + +print("pan sweep: left to right") +pan_sample = audiocore.RawSample(pan_buf, channel_count=2, sample_rate=pan_sr) +if trigger: + trigger.value = False +dac.play(pan_sample) +while dac.playing: + time.sleep(0.05) +if trigger: + trigger.value = True +time.sleep(0.2) +print() + +# --------------------------------------------------------------------------- +# Stereo WAV files: full-content check. +# --------------------------------------------------------------------------- +sample_prefix = "jeplayer-splash" +wavs = sorted(fn for fn in os.listdir("/") if fn.startswith(sample_prefix) and "stereo" in fn) + +for filename in wavs: + print("playing stereo:", filename) + with open(filename, "rb") as sample_file: + try: + sample = audiocore.WaveFile(sample_file) + except OSError as e: + print(e) + continue + if trigger: + trigger.value = False + dac.play(sample) + while dac.playing: + time.sleep(0.1) + if trigger: + trigger.value = True + time.sleep(0.1) + print() + +dac.deinit() +print("done") diff --git a/tests/circuitpython-manual/audioio/wavefile_pause_resume.py b/tests/circuitpython-manual/audioio/wavefile_pause_resume.py new file mode 100644 index 00000000000..7661a828b26 --- /dev/null +++ b/tests/circuitpython-manual/audioio/wavefile_pause_resume.py @@ -0,0 +1,66 @@ +import audiocore +import audioio +import board +import digitalio +import time +import os + +# Optional trigger pin for oscilloscope synchronisation. +try: + trigger = digitalio.DigitalInOut(board.D4) + trigger.switch_to_output(True) +except AttributeError: + trigger = None + +sample_prefix = "jeplayer-splash" + +samples = [] +for fn in os.listdir("/"): + if fn.startswith(sample_prefix): + samples.append(fn) + +if not samples: + print( + "No sample files found. Copy *.wav files from tests/circuitpython-manual/audiocore/ to the board." + ) + +dac = audioio.AudioOut(board.A0) +for filename in sorted(samples): + print("playing with pause/resume:", filename) + with open(filename, "rb") as sample_file: + try: + sample = audiocore.WaveFile(sample_file) + except OSError as e: + print(e) + continue + if trigger: + trigger.value = False + dac.play(sample) + # Deliberately toggle pause/resume every 100 ms to stress-test the + # pause/resume cycle. Audio will sound choppy — that is expected. + # The wall-clock guard makes the test fail loudly instead of hanging + # if pause() ever leaves the driver in a state where playing never + # clears. 30 s is enough for the longest 44.1 kHz mono WAV in the + # set even with pause-doubling. + deadline = time.monotonic() + 30.0 + while dac.playing: + if time.monotonic() > deadline: + print(" TIMEOUT waiting for playback to finish") + dac.stop() + break + time.sleep(0.1) + if not dac.playing: # may have finished during sleep + break + if not dac.paused: + dac.pause() + print(" paused") + else: + dac.resume() + print(" resumed") + if trigger: + trigger.value = True + time.sleep(0.1) + print() + +dac.deinit() +print("done") diff --git a/tests/circuitpython-manual/audioio/wavefile_playback.py b/tests/circuitpython-manual/audioio/wavefile_playback.py new file mode 100644 index 00000000000..a7800c54ddc --- /dev/null +++ b/tests/circuitpython-manual/audioio/wavefile_playback.py @@ -0,0 +1,49 @@ +import audiocore +import audioio +import board +import digitalio +import time +import os + +# Optional trigger pin for oscilloscope synchronisation. +try: + trigger = digitalio.DigitalInOut(board.D4) + trigger.switch_to_output(True) +except AttributeError: + trigger = None + +# List WAV files from the audiocore test samples directory on the device. +# Copy tests/circuitpython-manual/audiocore/*.wav to the board's filesystem. +sample_prefix = "jeplayer-splash" + +samples = [] +for fn in os.listdir("/"): + if fn.startswith(sample_prefix): + samples.append(fn) + +if not samples: + print( + "No sample files found. Copy *.wav files from tests/circuitpython-manual/audiocore/ to the board." + ) + +dac = audioio.AudioOut(board.A0) +for filename in sorted(samples): + print("playing", filename) + with open(filename, "rb") as sample_file: + try: + sample = audiocore.WaveFile(sample_file) + except OSError as e: + print(e) + continue + if trigger: + trigger.value = False + dac.play(sample) + while dac.playing: + time.sleep(0.1) + if trigger: + trigger.value = True + time.sleep(0.1) + print() + +dac.deinit() +print("done") diff --git a/tests/circuitpython-manual/pwmio/code_extremes.py b/tests/circuitpython-manual/pwmio/code_extremes.py index 13dd5c90ad1..4ca8b2f70fa 100644 --- a/tests/circuitpython-manual/pwmio/code_extremes.py +++ b/tests/circuitpython-manual/pwmio/code_extremes.py @@ -80,7 +80,7 @@ if time.monotonic() > freq_time: break t0 = freq_time - print(f"({freq}, {i/freq_duration:.0f}), ", end="") + print(f"({freq}, {i / freq_duration:.0f}), ", end="") print(")") print("done.") pwm.deinit() diff --git a/tests/circuitpython-manual/pwmio/code_ramps.py b/tests/circuitpython-manual/pwmio/code_ramps.py index 6a06e4eff6b..e0d4901894f 100644 --- a/tests/circuitpython-manual/pwmio/code_ramps.py +++ b/tests/circuitpython-manual/pwmio/code_ramps.py @@ -96,7 +96,7 @@ if time.monotonic() > freq_time: break t0 = freq_time - print(f"({freq}, {i/freq_duration:.0f}), ", end="") + print(f"({freq}, {i / freq_duration:.0f}), ", end="") print(")") print("done.") pwm.deinit() diff --git a/tests/circuitpython-manual/pwmio/duty.py b/tests/circuitpython-manual/pwmio/duty.py index 0673f96c2b6..f5c3abd471d 100644 --- a/tests/circuitpython-manual/pwmio/duty.py +++ b/tests/circuitpython-manual/pwmio/duty.py @@ -107,7 +107,7 @@ def read( for duty in duty_labels: draw.text( (left - 10, y0 + (y1 - y0) * (1 - duty)), - f"{int(100*duty):d}%", + f"{int(100 * duty):d}%", duty_color, anchor="rm", ) diff --git a/tests/circuitpython-manual/rp2pio/README.md b/tests/circuitpython-manual/rp2pio/README.md new file mode 100644 index 00000000000..de67cf203d2 --- /dev/null +++ b/tests/circuitpython-manual/rp2pio/README.md @@ -0,0 +1,44 @@ +# rp2pio + audio DMA shared-IRQ manual tests + +These programs exercise the `DMA_IRQ_0` interrupt handlers on the RP2040 / +RP2350, which are shared between `audiocore`/`audiopwmio` (audio DMA) and +`rp2pio` (PIO background read/write DMA). + +They were written to validate the change in issue #9992 (moving `audio_dma.c` +off the fixed `isr_dma_0()` linker symbol and onto `irq_add_shared_handler()`, +with `rp2pio` registering its own shared handler). **They use only public APIs +that predate that change, so each program should behave identically before and +after it** — that is the point: they are regression tests, not feature tests. + +## What each program covers + +| Program | Audio DMA | PIO write DMA | PIO read DMA | +|---|---|---|---| +| `pio_background_write.py` | | ✓ | | +| `audio_dma_shared_irq_write.py` | ✓ | ✓ | | +| `audio_dma_shared_irq_loopback.py` | ✓ | ✓ | ✓ | + +Each goes through the background-DMA path (`background_write` / +`background_read`), which is interrupt-driven. The blocking `write`/`readinto`/ +`write_readinto` calls poll instead and do **not** use the DMA IRQ, so they are +deliberately not used here. The audio sample is created with +`single_buffer=False` so audio also uses the interrupt-driven (double-buffered) +DMA path rather than the no-interrupt single-buffer chaining path. + +## Wiring (Raspberry Pi Pico / Pico 2) + +- `GP13` — PWM audio output. Connect to an amplifier/speaker, or just leave it; + the test does not require you to hear anything, only that playback keeps + running. +- `GP2` — PIO output pin. +- `GP3` — PIO input pin (loopback test only). For a meaningful loopback, + connect `GP2` to `GP3` with a jumper. Without the jumper the read still + completes (it just reads whatever the floating/pulled pin sees), so the DMA + path is still exercised. + +## Running + +Copy one file at a time to `CIRCUITPY/code.py` and watch the serial console. +A successful run ends with a `PASS:` line. A hang (no further output) or a +`RuntimeError`/crash/safe-mode indicates a regression in the shared DMA IRQ +handling. diff --git a/tests/circuitpython-manual/rp2pio/audio_dma_shared_irq_loopback.py b/tests/circuitpython-manual/rp2pio/audio_dma_shared_irq_loopback.py new file mode 100644 index 00000000000..ba8ebbb589d --- /dev/null +++ b/tests/circuitpython-manual/rp2pio/audio_dma_shared_irq_loopback.py @@ -0,0 +1,85 @@ +"""Audio + rp2pio background write AND read sharing DMA_IRQ_0. + +Exercises all three DMA_IRQ_0 dispatch arms at once: + * audio playback (double-buffered, interrupt-driven), + * a continuous PIO background_write (write-completion interrupts), and + * repeated PIO background_read one-shots (read-completion interrupts). + +The continuous background_write keeps the state machine clocking so the read +side always has data to capture. Each background_read is a one-shot whose +completion is detected by polling `StateMachine.reading`; if that never clears, +the read-completion interrupt is not being serviced (a regression). Audio must +also keep playing throughout. + +Wiring: PWM audio on GP13 (speaker optional), PIO output on GP2, PIO input on +GP3. Jumper GP2 -> GP3 for a true loopback (then the captured data reflects what +was written); without the jumper the read still completes, so the DMA path is +still exercised. +""" + +import array +import math +import time + +import audiocore +import audiopwmio +import board +import rp2pio + +# --- Audio: signed-16 sine wave, double-buffered so it uses the DMA IRQ path. +SAMPLE_RATE = 16000 +SAMPLE_COUNT = 4000 # even count (required for single_buffer=False) +PERIODS = 32 +sine = array.array("h", [0] * SAMPLE_COUNT) +for i in range(SAMPLE_COUNT): + sine[i] = int(math.sin(2 * math.pi * PERIODS * i / SAMPLE_COUNT) * (2**14)) +sample = audiocore.RawSample(sine, sample_rate=SAMPLE_RATE, single_buffer=False) + +audio = audiopwmio.PWMAudioOut(board.GP13) +audio.play(sample, loop=True) +print("audio playing:", audio.playing) + +# --- PIO loopback program (hand assembled): +# .wrap_target +# out pins, 1 ; 0x6001 shift one bit OSR -> output pin (GP2) +# in pins, 1 ; 0x4001 shift one bit input pin (GP3) -> ISR +# .wrap +# auto_pull/auto_push at 32 bits keep both FIFOs (and their DMA) moving. +PROGRAM = array.array("H", [0x6001, 0x4001]) +sm = rp2pio.StateMachine( + PROGRAM, + frequency=2_000_000, + first_out_pin=board.GP2, + first_in_pin=board.GP3, + auto_pull=True, + pull_threshold=32, + out_shift_right=True, + auto_push=True, + push_threshold=32, + in_shift_right=True, +) + +out_buf = array.array("I", [0x0F0F0F0F] * 1024) +in_buf = array.array("I", [0] * 1024) + +# Continuous background write to keep the state machine clocking. +sm.background_write(loop=out_buf) + +ITERATIONS = 100 +for n in range(ITERATIONS): + sm.background_read(once=in_buf) + deadline = time.monotonic() + 2.0 + while sm.reading and time.monotonic() < deadline: + pass + if sm.reading: + raise RuntimeError(f"background_read stuck on iteration {n} (shared DMA IRQ wedged?)") + if not audio.playing: + raise RuntimeError(f"audio stopped unexpectedly on iteration {n}") + if n % 20 == 0: + print("iteration", n, "audio.playing", audio.playing, "first read word", hex(in_buf[0])) + +sm.stop_background_write() +audio.stop() +sm.deinit() +audio.deinit() +print("PASS: audio + rp2pio background write/read shared DMA_IRQ_0 for", ITERATIONS, "iterations") diff --git a/tests/circuitpython-manual/rp2pio/audio_dma_shared_irq_write.py b/tests/circuitpython-manual/rp2pio/audio_dma_shared_irq_write.py new file mode 100644 index 00000000000..fe00df06815 --- /dev/null +++ b/tests/circuitpython-manual/rp2pio/audio_dma_shared_irq_write.py @@ -0,0 +1,67 @@ +"""Audio playback + rp2pio background_write sharing DMA_IRQ_0. + +This is the scenario from issue #9868: audio output and a PIO peripheral (e.g. a +status NeoPixel) both want DMA completion interrupts at the same time. Audio +uses the interrupt-driven double-buffered path (`single_buffer=False`) and +rp2pio uses background_write, so both subsystems are serviced by DMA_IRQ_0 +concurrently. + +The test passes if the PIO writes keep completing AND audio keeps playing for +the whole run. A hang, crash, or audio stopping early indicates a regression. + +Wiring: PWM audio on GP13 (speaker optional), PIO output on GP2 (no connection +required). +""" + +import array +import math +import time + +import audiocore +import audiopwmio +import board +import rp2pio + +# --- Audio: signed-16 sine wave, double-buffered so it uses the DMA IRQ path. +SAMPLE_RATE = 16000 +SAMPLE_COUNT = 4000 # even count (required for single_buffer=False), several periods +PERIODS = 32 +sine = array.array("h", [0] * SAMPLE_COUNT) +for i in range(SAMPLE_COUNT): + sine[i] = int(math.sin(2 * math.pi * PERIODS * i / SAMPLE_COUNT) * (2**14)) +sample = audiocore.RawSample(sine, sample_rate=SAMPLE_RATE, single_buffer=False) + +audio = audiopwmio.PWMAudioOut(board.GP13) +audio.play(sample, loop=True) +print("audio playing:", audio.playing) + +# --- PIO: drain program that clocks the TX FIFO out on GP2 (see +# pio_background_write.py for the encoding). +PROGRAM = array.array("H", [0x6001]) +sm = rp2pio.StateMachine( + PROGRAM, + frequency=2_000_000, + first_out_pin=board.GP2, + auto_pull=True, + pull_threshold=32, + out_shift_right=True, +) +data = array.array("I", [0x5555AAAA] * 4096) + +ITERATIONS = 100 +for n in range(ITERATIONS): + sm.background_write(once=data) + deadline = time.monotonic() + 2.0 + while sm.writing and time.monotonic() < deadline: + pass + if sm.writing: + raise RuntimeError(f"background_write stuck on iteration {n} (shared DMA IRQ wedged?)") + if not audio.playing: + raise RuntimeError(f"audio stopped unexpectedly on iteration {n}") + if n % 20 == 0: + print("iteration", n, "audio.playing", audio.playing) + +audio.stop() +sm.deinit() +audio.deinit() +print("PASS: audio + rp2pio background_write shared DMA_IRQ_0 for", ITERATIONS, "iterations") diff --git a/tests/circuitpython-manual/rp2pio/pio_background_write.py b/tests/circuitpython-manual/rp2pio/pio_background_write.py new file mode 100644 index 00000000000..796175da7b1 --- /dev/null +++ b/tests/circuitpython-manual/rp2pio/pio_background_write.py @@ -0,0 +1,53 @@ +"""Baseline: rp2pio background_write DMA only (no audio). + +Exercises the PIO *write* arm of the shared DMA_IRQ_0 handler, plus the +add/remove of the shared handler as the only channel comes and goes. + +Repeatedly starts a one-shot background write and waits for it to finish by +polling `StateMachine.writing`. If `writing` never clears, the DMA completion +interrupt is not being serviced (a regression). Ends with a PASS line. + +Wiring: PIO output on GP2 (no connection required). +""" + +import array +import time + +import board +import rp2pio + +# PIO program (hand assembled, no adafruit_pioasm dependency): +# .wrap_target +# out pins, 1 ; shift one bit from OSR to the output pin +# .wrap +# With auto_pull and pull_threshold=32, the OSR is refilled from the TX FIFO +# every 32 bits, so the FIFO (and therefore the DMA) drains continuously. +# Encoding of `out pins, 1`: opcode OUT=0b011, dest PINS=0b000, count 1 -> 0x6001 +PROGRAM = array.array("H", [0x6001]) + +sm = rp2pio.StateMachine( + PROGRAM, + frequency=2_000_000, + first_out_pin=board.GP2, + auto_pull=True, + pull_threshold=32, + out_shift_right=True, +) + +# 16 KB of data per transfer, enough that the DMA genuinely runs and completes +# via interrupt rather than fitting in the FIFO. +data = array.array("I", [0x5555AAAA] * 4096) + +ITERATIONS = 50 +for n in range(ITERATIONS): + sm.background_write(once=data) + deadline = time.monotonic() + 2.0 + while sm.writing and time.monotonic() < deadline: + pass + if sm.writing: + raise RuntimeError(f"background_write stuck on iteration {n} (DMA IRQ not serviced?)") + if n % 10 == 0: + print("iteration", n, "ok") + +sm.deinit() +print("PASS: rp2pio background_write completed", ITERATIONS, "times") diff --git a/tests/circuitpython-manual/settings/code.py b/tests/circuitpython-manual/settings/code.py new file mode 100644 index 00000000000..bebed3d11ae --- /dev/null +++ b/tests/circuitpython-manual/settings/code.py @@ -0,0 +1,66 @@ +# Test supervisor.get_setting() parsing of settings.toml values. +# Copy settings.toml to the root of the board, then run this script. +# All lines should print PASS. + +import math +import supervisor + + +def check(key, expected): + got = supervisor.get_setting(key) + if type(got) is not type(expected): + print( + f"FAIL {key}: expected type {type(expected).__name__}, got {type(got).__name__} ({got!r})" + ) + return + if isinstance(expected, float) and math.isnan(expected): + ok = math.isnan(got) + else: + ok = got == expected + if ok: + print(f"PASS {key}") + else: + print(f"FAIL {key}: expected {expected!r}, got {got!r}") + + +check("str_val", "hello") +check("int_val", 42) +check("neg_int_val", -7) +check("hex_int_val", 31) +check("bool_true", True) +check("bool_false", False) +check("float_val", 3.14) +check("neg_float_val", -1.5) +check("sci_float_val", 6.626e-34) +# math.nan and math.inf are not always available +check("pos_inf", float("inf")) +check("neg_inf", -float("inf")) +check("pos_nan", float("nan")) + + +def check_bad(key): + try: + got = supervisor.get_setting(key) + print(f"FAIL {key}: expected ValueError, got {got!r}") + except ValueError: + print(f"PASS {key} raises ValueError") + + +check_bad("bad_word") # unquoted non-boolean word +check_bad("bad_float_junk") # float with trailing garbage +check_bad("bad_inf_junk") # inf with trailing characters +check_bad("bad_lone_sign") # bare + with nothing after it + +# Missing key returns default +got = supervisor.get_setting("no_such_key", "default") +if got == "default": + print("PASS missing key default") +else: + print(f"FAIL missing key default: got {got!r}") + +# Invalid value raises ValueError +try: + supervisor.get_setting("str_val") # quoted string is valid + print("PASS str via get_setting") +except ValueError: + print("FAIL str via get_setting raised ValueError unexpectedly") diff --git a/tests/circuitpython-manual/settings/settings.toml b/tests/circuitpython-manual/settings/settings.toml new file mode 100644 index 00000000000..5df2d104afe --- /dev/null +++ b/tests/circuitpython-manual/settings/settings.toml @@ -0,0 +1,16 @@ +str_val = "hello" +bad_word = hello +bad_float_junk = 1.2abc +bad_inf_junk = infoo +bad_lone_sign = + +int_val = 42 +neg_int_val = -7 +hex_int_val = 0x1F +bool_true = true +bool_false = false +float_val = 3.14 +neg_float_val = -1.5 +sci_float_val = 6.626e-34 +pos_inf = inf +neg_inf = -inf +pos_nan = nan diff --git a/tests/circuitpython-manual/synthio/note/biquad.py b/tests/circuitpython-manual/synthio/note/biquad.py index b4136a957fc..306c4fd637f 100644 --- a/tests/circuitpython-manual/synthio/note/biquad.py +++ b/tests/circuitpython-manual/synthio/note/biquad.py @@ -24,33 +24,39 @@ ) noise = np.array([random.randint(-VOLUME, VOLUME) for i in range(SAMPLE_SIZE)], dtype=np.int16) bend_out = np.linspace(0, 32767, num=SAMPLE_SIZE, endpoint=True, dtype=np.int16) +sweep = np.linspace(-32767, 32767, num=SAMPLE_SIZE, endpoint=True, dtype=np.int16) + +lfos_of_interest = [] def synthesize(synth): - for waveform in (sine, None, noise): - for biquad in ( - None, - synth.low_pass_filter(120), - ): - for midi_note in range(24, 90, 3): - n = synthio.Note( - frequency=synthio.midi_to_hz(midi_note), - envelope=envelope, - filter=biquad, - waveform=waveform, - bend=synthio.LFO(bend_out, once=True, rate=1 / 2, scale=5), - ) - - synth.press(n) - print(n.frequency) - yield 24 - synth.release_all() - yield 16 - yield 24 - yield 48 - - -with wave.open("biquad.wav", "w") as f: + freq_sweep = synthio.LFO( + sweep, offset=synthio.midi_to_hz(72), scale=synthio.midi_to_hz(72), rate=1, once=True + ) + + for biquad in ( + None, + synthio.Biquad(synthio.FilterMode.LOW_PASS, freq_sweep), + synthio.Biquad(synthio.FilterMode.HIGH_PASS, freq_sweep), + synthio.Biquad(synthio.FilterMode.BAND_PASS, freq_sweep, Q=8), + synthio.Biquad(synthio.FilterMode.NOTCH, freq_sweep, Q=8), + ): + n = synthio.Note( + frequency=synthio.midi_to_hz(72), + envelope=envelope, + filter=biquad, + waveform=sine, + ) + + freq_sweep.retrigger() + synth.press(n) + print("n", n.frequency) + yield 24 * 6 + synth.release_all() + yield 24 + + +with wave.open("blockfilter.wav", "w") as f: f.setnchannels(1) f.setsampwidth(2) f.setframerate(48000) diff --git a/tests/circuitpython-manual/usb/basic_mouse.py b/tests/circuitpython-manual/usb/basic_mouse.py index a3228610a43..156895fd25d 100644 --- a/tests/circuitpython-manual/usb/basic_mouse.py +++ b/tests/circuitpython-manual/usb/basic_mouse.py @@ -17,6 +17,8 @@ if device.is_kernel_driver_active(0): device.detach_kernel_driver(0) +device.set_configuration() + # Boot mice have 4 byte reports buf = array.array("b", [0] * 4) report_count = 0 diff --git a/tests/circuitpython-manual/usb/device_info.py b/tests/circuitpython-manual/usb/device_info.py index 7b8631a8f86..34817070555 100644 --- a/tests/circuitpython-manual/usb/device_info.py +++ b/tests/circuitpython-manual/usb/device_info.py @@ -9,7 +9,8 @@ d.switch_to_output(value=True) print("USB power on") -h = usb_host.Port(board.USB_HOST_DP, board.USB_HOST_DM) +if hasattr(board, "USB_HOST_DP") and hasattr(board, "USB_HOST_DM"): + h = usb_host.Port(board.USB_HOST_DP, board.USB_HOST_DM) while True: for device in usb.core.find(find_all=True): diff --git a/tests/circuitpython-manual/usb/displayio_mouse.py b/tests/circuitpython-manual/usb/displayio_mouse.py new file mode 100644 index 00000000000..8dd2b1e4826 --- /dev/null +++ b/tests/circuitpython-manual/usb/displayio_mouse.py @@ -0,0 +1,67 @@ +# SPDX-FileCopyrightText: 2025 Tim Cocks for Adafruit Industries +# SPDX-License-Identifier: MIT +import terminalio +import array +import usb.core +import supervisor +from displayio import Group, OnDiskBitmap, TileGrid +from adafruit_display_text.bitmap_label import Label + +display = supervisor.runtime.display + +main_group = Group() +display.root_group = main_group + +mouse_bmp = OnDiskBitmap("mouse_cursor.bmp") +mouse_bmp.pixel_shader.make_transparent(0) +mouse_tg = TileGrid(mouse_bmp, pixel_shader=mouse_bmp.pixel_shader) +mouse_tg.x = display.width // 2 +mouse_tg.y = display.height // 2 + +output_lbl = Label(terminalio.FONT, text=f"{mouse_tg.x},{mouse_tg.y}", color=0xFFFFFF, scale=1) +output_lbl.anchor_point = (0, 0) +output_lbl.anchored_position = (1, 1) +main_group.append(output_lbl) + +main_group.append(mouse_tg) + +# This is a basic Microsoft optical mouse with two buttons and a wheel that can +# also be pressed. +USB_VID = 0x046D +USB_PID = 0xC52F +# This is ordered by bit position. +BUTTONS = ["left", "right", "middle"] + +for device in usb.core.find(find_all=True): + print(f"{device.idVendor:04x}:{device.idProduct:04x}") + print(device.manufacturer, device.product) + print(device.serial_number) + if device.idVendor == USB_VID and device.idProduct == USB_PID: + mouse = device +# +print(mouse.manufacturer, mouse.product) + +if mouse.is_kernel_driver_active(0): + mouse.detach_kernel_driver(0) + +mouse.set_configuration() + +# Boot mice have 4 byte reports +buf = array.array("b", [0] * 4) +report_count = 0 + +# try: +while True: + try: + count = mouse.read(0x81, buf, timeout=10) + except usb.core.USBTimeoutError: + continue + + mouse_tg.x = max(0, min(display.width - 1, mouse_tg.x + buf[1])) + mouse_tg.y = max(0, min(display.height - 1, mouse_tg.y + buf[2])) + out_str = f"{mouse_tg.x},{mouse_tg.y}" + for i, button in enumerate(BUTTONS): + if buf[0] & (1 << i) != 0: + out_str += f" {button}" + + output_lbl.text = out_str diff --git a/tests/circuitpython-manual/usb/mouse_cursor.bmp b/tests/circuitpython-manual/usb/mouse_cursor.bmp new file mode 100644 index 00000000000..94ec328896c Binary files /dev/null and b/tests/circuitpython-manual/usb/mouse_cursor.bmp differ diff --git a/tests/circuitpython/aes.py b/tests/circuitpython/aes.py index b47c4279d32..7e614118e5d 100644 --- a/tests/circuitpython/aes.py +++ b/tests/circuitpython/aes.py @@ -100,7 +100,10 @@ print("truncated-CTR-1") ## Truncated CTR test case -plaintext = unhexlify("6bc1bee22e409f96e93d7e117393172a" "ae2d") +plaintext = unhexlify( + "6bc1bee22e409f96e93d7e117393172a" + "ae2d" +) # fmt: skip key = unhexlify("2b7e151628aed2a6abf7158809cf4f3c") counter = unhexlify("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") @@ -122,7 +125,10 @@ print("truncated-CTR-2") ## Truncated CTR test case #2 -plaintext = unhexlify("6bc1bee22e409f96e93d7e117393172a" "ae") +plaintext = unhexlify( + "6bc1bee22e409f96e93d7e117393172a" + "ae" +) # fmt: skip key = unhexlify("2b7e151628aed2a6abf7158809cf4f3c") counter = unhexlify("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") diff --git a/tests/circuitpython/audiofilter_filter.py b/tests/circuitpython/audiofilter_filter.py new file mode 100644 index 00000000000..8081c8a6fbd --- /dev/null +++ b/tests/circuitpython/audiofilter_filter.py @@ -0,0 +1,17 @@ +from audiofilters import Filter +from audiofilterhelper import synth_test, sine8k + + +@synth_test +def basic_filter(): + effect = Filter( + bits_per_sample=16, + samples_signed=True, + ) + yield effect, [] + + effect.play(sine8k, loop=True) + yield 4 + + effect.stop() + yield 2 diff --git a/tests/circuitpython/audiofilter_filter.py.exp b/tests/circuitpython/audiofilter_filter.py.exp new file mode 100644 index 00000000000..734ac16b3a7 --- /dev/null +++ b/tests/circuitpython/audiofilter_filter.py.exp @@ -0,0 +1,1536 @@ +0 0.0 +1 0.010467529296875 +2 0.02093505859375 +3 0.031402587890625 +4 0.0418701171875 +5 0.05230712890625 +6 0.062774658203125 +7 0.073211669921875 +8 0.083648681640625 +9 0.094085693359375 +10 0.104522705078125 +11 0.11492919921875 +12 0.12530517578125 +13 0.13568115234375 +14 0.14605712890625 +15 0.156402587890625 +16 0.166748046875 +17 0.17706298828125 +18 0.187347412109375 +19 0.1976318359375 +20 0.2078857421875 +21 0.218109130859375 +22 0.22833251953125 +23 0.238525390625 +24 0.2486572265625 +25 0.2587890625 +26 0.268890380859375 +27 0.278961181640625 +28 0.28900146484375 +29 0.29901123046875 +30 0.308990478515625 +31 0.318939208984375 +32 0.328826904296875 +33 0.338714599609375 +34 0.348541259765625 +35 0.35833740234375 +36 0.36810302734375 +37 0.3778076171875 +38 0.387481689453125 +39 0.397125244140625 +40 0.406707763671875 +41 0.416259765625 +42 0.425750732421875 +43 0.435211181640625 +44 0.444610595703125 +45 0.453948974609375 +46 0.4632568359375 +47 0.4725341796875 +48 0.481719970703125 +49 0.490875244140625 +50 0.499969482421875 +51 0.509002685546875 +52 0.51800537109375 +53 0.52691650390625 +54 0.535797119140625 +55 0.54461669921875 +56 0.5533447265625 +57 0.562042236328125 +58 0.5706787109375 +59 0.579254150390625 +60 0.587738037109375 +61 0.59619140625 +62 0.60455322265625 +63 0.612884521484375 +64 0.621124267578125 +65 0.6292724609375 +66 0.63739013671875 +67 0.645416259765625 +68 0.65338134765625 +69 0.661285400390625 +70 0.669097900390625 +71 0.676849365234375 +72 0.68450927734375 +73 0.692108154296875 +74 0.699615478515625 +75 0.707061767578125 +76 0.714447021484375 +77 0.721710205078125 +78 0.72894287109375 +79 0.736053466796875 +80 0.74310302734375 +81 0.75006103515625 +82 0.7569580078125 +83 0.763763427734375 +84 0.770477294921875 +85 0.777099609375 +86 0.783660888671875 +87 0.790130615234375 +88 0.796478271484375 +89 0.802764892578125 +90 0.808990478515625 +91 0.815093994140625 +92 0.82110595703125 +93 0.8270263671875 +94 0.8328857421875 +95 0.838623046875 +96 0.84429931640625 +97 0.849853515625 +98 0.855316162109375 +99 0.860687255859375 +100 0.865997314453125 +101 0.871185302734375 +102 0.876251220703125 +103 0.881256103515625 +104 0.88616943359375 +105 0.890960693359375 +106 0.895660400390625 +107 0.9002685546875 +108 0.90478515625 +109 0.9091796875 +110 0.91351318359375 +111 0.917724609375 +112 0.92181396484375 +113 0.92584228515625 +114 0.929718017578125 +115 0.93353271484375 +116 0.937225341796875 +117 0.940826416015625 +118 0.9443359375 +119 0.947723388671875 +120 0.951019287109375 +121 0.954193115234375 +122 0.957275390625 +123 0.960235595703125 +124 0.963104248046875 +125 0.96588134765625 +126 0.968536376953125 +127 0.971099853515625 +128 0.973541259765625 +129 0.975860595703125 +130 0.97808837890625 +131 0.980224609375 +132 0.98223876953125 +133 0.984161376953125 +134 0.9859619140625 +135 0.987640380859375 +136 0.989227294921875 +137 0.990692138671875 +138 0.9920654296875 +139 0.993316650390625 +140 0.994476318359375 +141 0.995513916015625 +142 0.9964599609375 +143 0.997283935546875 +144 0.99798583984375 +145 0.99859619140625 +146 0.99908447265625 +147 0.99945068359375 +148 0.999725341796875 +149 0.999908447265625 +150 0.999969482421875 +151 0.999908447265625 +152 0.999725341796875 +153 0.99945068359375 +154 0.99908447265625 +155 0.99859619140625 +156 0.99798583984375 +157 0.997283935546875 +158 0.9964599609375 +159 0.995513916015625 +160 0.994476318359375 +161 0.993316650390625 +162 0.9920654296875 +163 0.990692138671875 +164 0.989227294921875 +165 0.987640380859375 +166 0.9859619140625 +167 0.984161376953125 +168 0.98223876953125 +169 0.980224609375 +170 0.97808837890625 +171 0.975860595703125 +172 0.973541259765625 +173 0.971099853515625 +174 0.968536376953125 +175 0.96588134765625 +176 0.963104248046875 +177 0.960235595703125 +178 0.957275390625 +179 0.954193115234375 +180 0.951019287109375 +181 0.947723388671875 +182 0.9443359375 +183 0.940826416015625 +184 0.937225341796875 +185 0.93353271484375 +186 0.929718017578125 +187 0.92584228515625 +188 0.92181396484375 +189 0.917724609375 +190 0.91351318359375 +191 0.9091796875 +192 0.90478515625 +193 0.9002685546875 +194 0.895660400390625 +195 0.890960693359375 +196 0.88616943359375 +197 0.881256103515625 +198 0.876251220703125 +199 0.871185302734375 +200 0.865997314453125 +201 0.860687255859375 +202 0.855316162109375 +203 0.849853515625 +204 0.84429931640625 +205 0.838623046875 +206 0.8328857421875 +207 0.8270263671875 +208 0.82110595703125 +209 0.815093994140625 +210 0.808990478515625 +211 0.802764892578125 +212 0.796478271484375 +213 0.790130615234375 +214 0.783660888671875 +215 0.777099609375 +216 0.770477294921875 +217 0.763763427734375 +218 0.7569580078125 +219 0.75006103515625 +220 0.74310302734375 +221 0.736053466796875 +222 0.72894287109375 +223 0.721710205078125 +224 0.714447021484375 +225 0.707061767578125 +226 0.699615478515625 +227 0.692108154296875 +228 0.68450927734375 +229 0.676849365234375 +230 0.669097900390625 +231 0.661285400390625 +232 0.65338134765625 +233 0.645416259765625 +234 0.63739013671875 +235 0.6292724609375 +236 0.621124267578125 +237 0.612884521484375 +238 0.60455322265625 +239 0.59619140625 +240 0.587738037109375 +241 0.579254150390625 +242 0.5706787109375 +243 0.562042236328125 +244 0.5533447265625 +245 0.54461669921875 +246 0.535797119140625 +247 0.52691650390625 +248 0.51800537109375 +249 0.509002685546875 +250 0.499969482421875 +251 0.490875244140625 +252 0.481719970703125 +253 0.4725341796875 +254 0.4632568359375 +255 0.453948974609375 +256 0.444610595703125 +257 0.435211181640625 +258 0.425750732421875 +259 0.416259765625 +260 0.406707763671875 +261 0.397125244140625 +262 0.387481689453125 +263 0.3778076171875 +264 0.36810302734375 +265 0.35833740234375 +266 0.348541259765625 +267 0.338714599609375 +268 0.328826904296875 +269 0.318939208984375 +270 0.308990478515625 +271 0.29901123046875 +272 0.28900146484375 +273 0.278961181640625 +274 0.268890380859375 +275 0.2587890625 +276 0.2486572265625 +277 0.238525390625 +278 0.22833251953125 +279 0.218109130859375 +280 0.2078857421875 +281 0.1976318359375 +282 0.187347412109375 +283 0.17706298828125 +284 0.166748046875 +285 0.156402587890625 +286 0.14605712890625 +287 0.13568115234375 +288 0.12530517578125 +289 0.11492919921875 +290 0.104522705078125 +291 0.094085693359375 +292 0.083648681640625 +293 0.073211669921875 +294 0.062774658203125 +295 0.05230712890625 +296 0.0418701171875 +297 0.031402587890625 +298 0.02093505859375 +299 0.010467529296875 +300 0.0 +301 -0.010467529296875 +302 -0.02093505859375 +303 -0.031402587890625 +304 -0.0418701171875 +305 -0.05230712890625 +306 -0.062774658203125 +307 -0.073211669921875 +308 -0.083648681640625 +309 -0.094085693359375 +310 -0.104522705078125 +311 -0.11492919921875 +312 -0.12530517578125 +313 -0.13568115234375 +314 -0.14605712890625 +315 -0.156402587890625 +316 -0.166748046875 +317 -0.17706298828125 +318 -0.187347412109375 +319 -0.1976318359375 +320 -0.2078857421875 +321 -0.218109130859375 +322 -0.22833251953125 +323 -0.238525390625 +324 -0.2486572265625 +325 -0.2587890625 +326 -0.268890380859375 +327 -0.278961181640625 +328 -0.28900146484375 +329 -0.29901123046875 +330 -0.308990478515625 +331 -0.318939208984375 +332 -0.328826904296875 +333 -0.338714599609375 +334 -0.348541259765625 +335 -0.35833740234375 +336 -0.36810302734375 +337 -0.3778076171875 +338 -0.387481689453125 +339 -0.397125244140625 +340 -0.406707763671875 +341 -0.416259765625 +342 -0.425750732421875 +343 -0.435211181640625 +344 -0.444610595703125 +345 -0.453948974609375 +346 -0.4632568359375 +347 -0.4725341796875 +348 -0.481719970703125 +349 -0.490875244140625 +350 -0.499969482421875 +351 -0.509002685546875 +352 -0.51800537109375 +353 -0.52691650390625 +354 -0.535797119140625 +355 -0.54461669921875 +356 -0.5533447265625 +357 -0.562042236328125 +358 -0.5706787109375 +359 -0.579254150390625 +360 -0.587738037109375 +361 -0.59619140625 +362 -0.60455322265625 +363 -0.612884521484375 +364 -0.621124267578125 +365 -0.6292724609375 +366 -0.63739013671875 +367 -0.645416259765625 +368 -0.65338134765625 +369 -0.661285400390625 +370 -0.669097900390625 +371 -0.676849365234375 +372 -0.68450927734375 +373 -0.692108154296875 +374 -0.699615478515625 +375 -0.707061767578125 +376 -0.714447021484375 +377 -0.721710205078125 +378 -0.72894287109375 +379 -0.736053466796875 +380 -0.74310302734375 +381 -0.75006103515625 +382 -0.7569580078125 +383 -0.763763427734375 +384 -0.770477294921875 +385 -0.777099609375 +386 -0.783660888671875 +387 -0.790130615234375 +388 -0.796478271484375 +389 -0.802764892578125 +390 -0.808990478515625 +391 -0.815093994140625 +392 -0.82110595703125 +393 -0.8270263671875 +394 -0.8328857421875 +395 -0.838623046875 +396 -0.84429931640625 +397 -0.849853515625 +398 -0.855316162109375 +399 -0.860687255859375 +400 -0.865997314453125 +401 -0.871185302734375 +402 -0.876251220703125 +403 -0.881256103515625 +404 -0.88616943359375 +405 -0.890960693359375 +406 -0.895660400390625 +407 -0.9002685546875 +408 -0.90478515625 +409 -0.9091796875 +410 -0.91351318359375 +411 -0.917724609375 +412 -0.92181396484375 +413 -0.92584228515625 +414 -0.929718017578125 +415 -0.93353271484375 +416 -0.937225341796875 +417 -0.940826416015625 +418 -0.9443359375 +419 -0.947723388671875 +420 -0.951019287109375 +421 -0.954193115234375 +422 -0.957275390625 +423 -0.960235595703125 +424 -0.963104248046875 +425 -0.96588134765625 +426 -0.968536376953125 +427 -0.971099853515625 +428 -0.973541259765625 +429 -0.975860595703125 +430 -0.97808837890625 +431 -0.980224609375 +432 -0.98223876953125 +433 -0.984161376953125 +434 -0.9859619140625 +435 -0.987640380859375 +436 -0.989227294921875 +437 -0.990692138671875 +438 -0.9920654296875 +439 -0.993316650390625 +440 -0.994476318359375 +441 -0.995513916015625 +442 -0.9964599609375 +443 -0.997283935546875 +444 -0.99798583984375 +445 -0.99859619140625 +446 -0.99908447265625 +447 -0.99945068359375 +448 -0.999725341796875 +449 -0.999908447265625 +450 -0.999969482421875 +451 -0.999908447265625 +452 -0.999725341796875 +453 -0.99945068359375 +454 -0.99908447265625 +455 -0.99859619140625 +456 -0.99798583984375 +457 -0.997283935546875 +458 -0.9964599609375 +459 -0.995513916015625 +460 -0.994476318359375 +461 -0.993316650390625 +462 -0.9920654296875 +463 -0.990692138671875 +464 -0.989227294921875 +465 -0.987640380859375 +466 -0.9859619140625 +467 -0.984161376953125 +468 -0.98223876953125 +469 -0.980224609375 +470 -0.97808837890625 +471 -0.975860595703125 +472 -0.973541259765625 +473 -0.971099853515625 +474 -0.968536376953125 +475 -0.96588134765625 +476 -0.963104248046875 +477 -0.960235595703125 +478 -0.957275390625 +479 -0.954193115234375 +480 -0.951019287109375 +481 -0.947723388671875 +482 -0.9443359375 +483 -0.940826416015625 +484 -0.937225341796875 +485 -0.93353271484375 +486 -0.929718017578125 +487 -0.92584228515625 +488 -0.92181396484375 +489 -0.917724609375 +490 -0.91351318359375 +491 -0.9091796875 +492 -0.90478515625 +493 -0.9002685546875 +494 -0.895660400390625 +495 -0.890960693359375 +496 -0.88616943359375 +497 -0.881256103515625 +498 -0.876251220703125 +499 -0.871185302734375 +500 -0.865997314453125 +501 -0.860687255859375 +502 -0.855316162109375 +503 -0.849853515625 +504 -0.84429931640625 +505 -0.838623046875 +506 -0.8328857421875 +507 -0.8270263671875 +508 -0.82110595703125 +509 -0.815093994140625 +510 -0.808990478515625 +511 -0.802764892578125 +512 -0.796478271484375 +513 -0.790130615234375 +514 -0.783660888671875 +515 -0.777099609375 +516 -0.770477294921875 +517 -0.763763427734375 +518 -0.7569580078125 +519 -0.75006103515625 +520 -0.74310302734375 +521 -0.736053466796875 +522 -0.72894287109375 +523 -0.721710205078125 +524 -0.714447021484375 +525 -0.707061767578125 +526 -0.699615478515625 +527 -0.692108154296875 +528 -0.68450927734375 +529 -0.676849365234375 +530 -0.669097900390625 +531 -0.661285400390625 +532 -0.65338134765625 +533 -0.645416259765625 +534 -0.63739013671875 +535 -0.6292724609375 +536 -0.621124267578125 +537 -0.612884521484375 +538 -0.60455322265625 +539 -0.59619140625 +540 -0.587738037109375 +541 -0.579254150390625 +542 -0.5706787109375 +543 -0.562042236328125 +544 -0.5533447265625 +545 -0.54461669921875 +546 -0.535797119140625 +547 -0.52691650390625 +548 -0.51800537109375 +549 -0.509002685546875 +550 -0.499969482421875 +551 -0.490875244140625 +552 -0.481719970703125 +553 -0.4725341796875 +554 -0.4632568359375 +555 -0.453948974609375 +556 -0.444610595703125 +557 -0.435211181640625 +558 -0.425750732421875 +559 -0.416259765625 +560 -0.406707763671875 +561 -0.397125244140625 +562 -0.387481689453125 +563 -0.3778076171875 +564 -0.36810302734375 +565 -0.35833740234375 +566 -0.348541259765625 +567 -0.338714599609375 +568 -0.328826904296875 +569 -0.318939208984375 +570 -0.308990478515625 +571 -0.29901123046875 +572 -0.28900146484375 +573 -0.278961181640625 +574 -0.268890380859375 +575 -0.2587890625 +576 -0.2486572265625 +577 -0.238525390625 +578 -0.22833251953125 +579 -0.218109130859375 +580 -0.2078857421875 +581 -0.1976318359375 +582 -0.187347412109375 +583 -0.17706298828125 +584 -0.166748046875 +585 -0.156402587890625 +586 -0.14605712890625 +587 -0.13568115234375 +588 -0.12530517578125 +589 -0.11492919921875 +590 -0.104522705078125 +591 -0.094085693359375 +592 -0.083648681640625 +593 -0.073211669921875 +594 -0.062774658203125 +595 -0.05230712890625 +596 -0.0418701171875 +597 -0.031402587890625 +598 -0.02093505859375 +599 -0.010467529296875 +600 0.0 +601 0.010467529296875 +602 0.02093505859375 +603 0.031402587890625 +604 0.0418701171875 +605 0.05230712890625 +606 0.062774658203125 +607 0.073211669921875 +608 0.083648681640625 +609 0.094085693359375 +610 0.104522705078125 +611 0.11492919921875 +612 0.12530517578125 +613 0.13568115234375 +614 0.14605712890625 +615 0.156402587890625 +616 0.166748046875 +617 0.17706298828125 +618 0.187347412109375 +619 0.1976318359375 +620 0.2078857421875 +621 0.218109130859375 +622 0.22833251953125 +623 0.238525390625 +624 0.2486572265625 +625 0.2587890625 +626 0.268890380859375 +627 0.278961181640625 +628 0.28900146484375 +629 0.29901123046875 +630 0.308990478515625 +631 0.318939208984375 +632 0.328826904296875 +633 0.338714599609375 +634 0.348541259765625 +635 0.35833740234375 +636 0.36810302734375 +637 0.3778076171875 +638 0.387481689453125 +639 0.397125244140625 +640 0.406707763671875 +641 0.416259765625 +642 0.425750732421875 +643 0.435211181640625 +644 0.444610595703125 +645 0.453948974609375 +646 0.4632568359375 +647 0.4725341796875 +648 0.481719970703125 +649 0.490875244140625 +650 0.499969482421875 +651 0.509002685546875 +652 0.51800537109375 +653 0.52691650390625 +654 0.535797119140625 +655 0.54461669921875 +656 0.5533447265625 +657 0.562042236328125 +658 0.5706787109375 +659 0.579254150390625 +660 0.587738037109375 +661 0.59619140625 +662 0.60455322265625 +663 0.612884521484375 +664 0.621124267578125 +665 0.6292724609375 +666 0.63739013671875 +667 0.645416259765625 +668 0.65338134765625 +669 0.661285400390625 +670 0.669097900390625 +671 0.676849365234375 +672 0.68450927734375 +673 0.692108154296875 +674 0.699615478515625 +675 0.707061767578125 +676 0.714447021484375 +677 0.721710205078125 +678 0.72894287109375 +679 0.736053466796875 +680 0.74310302734375 +681 0.75006103515625 +682 0.7569580078125 +683 0.763763427734375 +684 0.770477294921875 +685 0.777099609375 +686 0.783660888671875 +687 0.790130615234375 +688 0.796478271484375 +689 0.802764892578125 +690 0.808990478515625 +691 0.815093994140625 +692 0.82110595703125 +693 0.8270263671875 +694 0.8328857421875 +695 0.838623046875 +696 0.84429931640625 +697 0.849853515625 +698 0.855316162109375 +699 0.860687255859375 +700 0.865997314453125 +701 0.871185302734375 +702 0.876251220703125 +703 0.881256103515625 +704 0.88616943359375 +705 0.890960693359375 +706 0.895660400390625 +707 0.9002685546875 +708 0.90478515625 +709 0.9091796875 +710 0.91351318359375 +711 0.917724609375 +712 0.92181396484375 +713 0.92584228515625 +714 0.929718017578125 +715 0.93353271484375 +716 0.937225341796875 +717 0.940826416015625 +718 0.9443359375 +719 0.947723388671875 +720 0.951019287109375 +721 0.954193115234375 +722 0.957275390625 +723 0.960235595703125 +724 0.963104248046875 +725 0.96588134765625 +726 0.968536376953125 +727 0.971099853515625 +728 0.973541259765625 +729 0.975860595703125 +730 0.97808837890625 +731 0.980224609375 +732 0.98223876953125 +733 0.984161376953125 +734 0.9859619140625 +735 0.987640380859375 +736 0.989227294921875 +737 0.990692138671875 +738 0.9920654296875 +739 0.993316650390625 +740 0.994476318359375 +741 0.995513916015625 +742 0.9964599609375 +743 0.997283935546875 +744 0.99798583984375 +745 0.99859619140625 +746 0.99908447265625 +747 0.99945068359375 +748 0.999725341796875 +749 0.999908447265625 +750 0.999969482421875 +751 0.999908447265625 +752 0.999725341796875 +753 0.99945068359375 +754 0.99908447265625 +755 0.99859619140625 +756 0.99798583984375 +757 0.997283935546875 +758 0.9964599609375 +759 0.995513916015625 +760 0.994476318359375 +761 0.993316650390625 +762 0.9920654296875 +763 0.990692138671875 +764 0.989227294921875 +765 0.987640380859375 +766 0.9859619140625 +767 0.984161376953125 +768 0.98223876953125 +769 0.980224609375 +770 0.97808837890625 +771 0.975860595703125 +772 0.973541259765625 +773 0.971099853515625 +774 0.968536376953125 +775 0.96588134765625 +776 0.963104248046875 +777 0.960235595703125 +778 0.957275390625 +779 0.954193115234375 +780 0.951019287109375 +781 0.947723388671875 +782 0.9443359375 +783 0.940826416015625 +784 0.937225341796875 +785 0.93353271484375 +786 0.929718017578125 +787 0.92584228515625 +788 0.92181396484375 +789 0.917724609375 +790 0.91351318359375 +791 0.9091796875 +792 0.90478515625 +793 0.9002685546875 +794 0.895660400390625 +795 0.890960693359375 +796 0.88616943359375 +797 0.881256103515625 +798 0.876251220703125 +799 0.871185302734375 +800 0.865997314453125 +801 0.860687255859375 +802 0.855316162109375 +803 0.849853515625 +804 0.84429931640625 +805 0.838623046875 +806 0.8328857421875 +807 0.8270263671875 +808 0.82110595703125 +809 0.815093994140625 +810 0.808990478515625 +811 0.802764892578125 +812 0.796478271484375 +813 0.790130615234375 +814 0.783660888671875 +815 0.777099609375 +816 0.770477294921875 +817 0.763763427734375 +818 0.7569580078125 +819 0.75006103515625 +820 0.74310302734375 +821 0.736053466796875 +822 0.72894287109375 +823 0.721710205078125 +824 0.714447021484375 +825 0.707061767578125 +826 0.699615478515625 +827 0.692108154296875 +828 0.68450927734375 +829 0.676849365234375 +830 0.669097900390625 +831 0.661285400390625 +832 0.65338134765625 +833 0.645416259765625 +834 0.63739013671875 +835 0.6292724609375 +836 0.621124267578125 +837 0.612884521484375 +838 0.60455322265625 +839 0.59619140625 +840 0.587738037109375 +841 0.579254150390625 +842 0.5706787109375 +843 0.562042236328125 +844 0.5533447265625 +845 0.54461669921875 +846 0.535797119140625 +847 0.52691650390625 +848 0.51800537109375 +849 0.509002685546875 +850 0.499969482421875 +851 0.490875244140625 +852 0.481719970703125 +853 0.4725341796875 +854 0.4632568359375 +855 0.453948974609375 +856 0.444610595703125 +857 0.435211181640625 +858 0.425750732421875 +859 0.416259765625 +860 0.406707763671875 +861 0.397125244140625 +862 0.387481689453125 +863 0.3778076171875 +864 0.36810302734375 +865 0.35833740234375 +866 0.348541259765625 +867 0.338714599609375 +868 0.328826904296875 +869 0.318939208984375 +870 0.308990478515625 +871 0.29901123046875 +872 0.28900146484375 +873 0.278961181640625 +874 0.268890380859375 +875 0.2587890625 +876 0.2486572265625 +877 0.238525390625 +878 0.22833251953125 +879 0.218109130859375 +880 0.2078857421875 +881 0.1976318359375 +882 0.187347412109375 +883 0.17706298828125 +884 0.166748046875 +885 0.156402587890625 +886 0.14605712890625 +887 0.13568115234375 +888 0.12530517578125 +889 0.11492919921875 +890 0.104522705078125 +891 0.094085693359375 +892 0.083648681640625 +893 0.073211669921875 +894 0.062774658203125 +895 0.05230712890625 +896 0.0418701171875 +897 0.031402587890625 +898 0.02093505859375 +899 0.010467529296875 +900 0.0 +901 -0.010467529296875 +902 -0.02093505859375 +903 -0.031402587890625 +904 -0.0418701171875 +905 -0.05230712890625 +906 -0.062774658203125 +907 -0.073211669921875 +908 -0.083648681640625 +909 -0.094085693359375 +910 -0.104522705078125 +911 -0.11492919921875 +912 -0.12530517578125 +913 -0.13568115234375 +914 -0.14605712890625 +915 -0.156402587890625 +916 -0.166748046875 +917 -0.17706298828125 +918 -0.187347412109375 +919 -0.1976318359375 +920 -0.2078857421875 +921 -0.218109130859375 +922 -0.22833251953125 +923 -0.238525390625 +924 -0.2486572265625 +925 -0.2587890625 +926 -0.268890380859375 +927 -0.278961181640625 +928 -0.28900146484375 +929 -0.29901123046875 +930 -0.308990478515625 +931 -0.318939208984375 +932 -0.328826904296875 +933 -0.338714599609375 +934 -0.348541259765625 +935 -0.35833740234375 +936 -0.36810302734375 +937 -0.3778076171875 +938 -0.387481689453125 +939 -0.397125244140625 +940 -0.406707763671875 +941 -0.416259765625 +942 -0.425750732421875 +943 -0.435211181640625 +944 -0.444610595703125 +945 -0.453948974609375 +946 -0.4632568359375 +947 -0.4725341796875 +948 -0.481719970703125 +949 -0.490875244140625 +950 -0.499969482421875 +951 -0.509002685546875 +952 -0.51800537109375 +953 -0.52691650390625 +954 -0.535797119140625 +955 -0.54461669921875 +956 -0.5533447265625 +957 -0.562042236328125 +958 -0.5706787109375 +959 -0.579254150390625 +960 -0.587738037109375 +961 -0.59619140625 +962 -0.60455322265625 +963 -0.612884521484375 +964 -0.621124267578125 +965 -0.6292724609375 +966 -0.63739013671875 +967 -0.645416259765625 +968 -0.65338134765625 +969 -0.661285400390625 +970 -0.669097900390625 +971 -0.676849365234375 +972 -0.68450927734375 +973 -0.692108154296875 +974 -0.699615478515625 +975 -0.707061767578125 +976 -0.714447021484375 +977 -0.721710205078125 +978 -0.72894287109375 +979 -0.736053466796875 +980 -0.74310302734375 +981 -0.75006103515625 +982 -0.7569580078125 +983 -0.763763427734375 +984 -0.770477294921875 +985 -0.777099609375 +986 -0.783660888671875 +987 -0.790130615234375 +988 -0.796478271484375 +989 -0.802764892578125 +990 -0.808990478515625 +991 -0.815093994140625 +992 -0.82110595703125 +993 -0.8270263671875 +994 -0.8328857421875 +995 -0.838623046875 +996 -0.84429931640625 +997 -0.849853515625 +998 -0.855316162109375 +999 -0.860687255859375 +1000 -0.865997314453125 +1001 -0.871185302734375 +1002 -0.876251220703125 +1003 -0.881256103515625 +1004 -0.88616943359375 +1005 -0.890960693359375 +1006 -0.895660400390625 +1007 -0.9002685546875 +1008 -0.90478515625 +1009 -0.9091796875 +1010 -0.91351318359375 +1011 -0.917724609375 +1012 -0.92181396484375 +1013 -0.92584228515625 +1014 -0.929718017578125 +1015 -0.93353271484375 +1016 -0.937225341796875 +1017 -0.940826416015625 +1018 -0.9443359375 +1019 -0.947723388671875 +1020 -0.951019287109375 +1021 -0.954193115234375 +1022 -0.957275390625 +1023 -0.960235595703125 +1024 0.0 +1025 0.0 +1026 0.0 +1027 0.0 +1028 0.0 +1029 0.0 +1030 0.0 +1031 0.0 +1032 0.0 +1033 0.0 +1034 0.0 +1035 0.0 +1036 0.0 +1037 0.0 +1038 0.0 +1039 0.0 +1040 0.0 +1041 0.0 +1042 0.0 +1043 0.0 +1044 0.0 +1045 0.0 +1046 0.0 +1047 0.0 +1048 0.0 +1049 0.0 +1050 0.0 +1051 0.0 +1052 0.0 +1053 0.0 +1054 0.0 +1055 0.0 +1056 0.0 +1057 0.0 +1058 0.0 +1059 0.0 +1060 0.0 +1061 0.0 +1062 0.0 +1063 0.0 +1064 0.0 +1065 0.0 +1066 0.0 +1067 0.0 +1068 0.0 +1069 0.0 +1070 0.0 +1071 0.0 +1072 0.0 +1073 0.0 +1074 0.0 +1075 0.0 +1076 0.0 +1077 0.0 +1078 0.0 +1079 0.0 +1080 0.0 +1081 0.0 +1082 0.0 +1083 0.0 +1084 0.0 +1085 0.0 +1086 0.0 +1087 0.0 +1088 0.0 +1089 0.0 +1090 0.0 +1091 0.0 +1092 0.0 +1093 0.0 +1094 0.0 +1095 0.0 +1096 0.0 +1097 0.0 +1098 0.0 +1099 0.0 +1100 0.0 +1101 0.0 +1102 0.0 +1103 0.0 +1104 0.0 +1105 0.0 +1106 0.0 +1107 0.0 +1108 0.0 +1109 0.0 +1110 0.0 +1111 0.0 +1112 0.0 +1113 0.0 +1114 0.0 +1115 0.0 +1116 0.0 +1117 0.0 +1118 0.0 +1119 0.0 +1120 0.0 +1121 0.0 +1122 0.0 +1123 0.0 +1124 0.0 +1125 0.0 +1126 0.0 +1127 0.0 +1128 0.0 +1129 0.0 +1130 0.0 +1131 0.0 +1132 0.0 +1133 0.0 +1134 0.0 +1135 0.0 +1136 0.0 +1137 0.0 +1138 0.0 +1139 0.0 +1140 0.0 +1141 0.0 +1142 0.0 +1143 0.0 +1144 0.0 +1145 0.0 +1146 0.0 +1147 0.0 +1148 0.0 +1149 0.0 +1150 0.0 +1151 0.0 +1152 0.0 +1153 0.0 +1154 0.0 +1155 0.0 +1156 0.0 +1157 0.0 +1158 0.0 +1159 0.0 +1160 0.0 +1161 0.0 +1162 0.0 +1163 0.0 +1164 0.0 +1165 0.0 +1166 0.0 +1167 0.0 +1168 0.0 +1169 0.0 +1170 0.0 +1171 0.0 +1172 0.0 +1173 0.0 +1174 0.0 +1175 0.0 +1176 0.0 +1177 0.0 +1178 0.0 +1179 0.0 +1180 0.0 +1181 0.0 +1182 0.0 +1183 0.0 +1184 0.0 +1185 0.0 +1186 0.0 +1187 0.0 +1188 0.0 +1189 0.0 +1190 0.0 +1191 0.0 +1192 0.0 +1193 0.0 +1194 0.0 +1195 0.0 +1196 0.0 +1197 0.0 +1198 0.0 +1199 0.0 +1200 0.0 +1201 0.0 +1202 0.0 +1203 0.0 +1204 0.0 +1205 0.0 +1206 0.0 +1207 0.0 +1208 0.0 +1209 0.0 +1210 0.0 +1211 0.0 +1212 0.0 +1213 0.0 +1214 0.0 +1215 0.0 +1216 0.0 +1217 0.0 +1218 0.0 +1219 0.0 +1220 0.0 +1221 0.0 +1222 0.0 +1223 0.0 +1224 0.0 +1225 0.0 +1226 0.0 +1227 0.0 +1228 0.0 +1229 0.0 +1230 0.0 +1231 0.0 +1232 0.0 +1233 0.0 +1234 0.0 +1235 0.0 +1236 0.0 +1237 0.0 +1238 0.0 +1239 0.0 +1240 0.0 +1241 0.0 +1242 0.0 +1243 0.0 +1244 0.0 +1245 0.0 +1246 0.0 +1247 0.0 +1248 0.0 +1249 0.0 +1250 0.0 +1251 0.0 +1252 0.0 +1253 0.0 +1254 0.0 +1255 0.0 +1256 0.0 +1257 0.0 +1258 0.0 +1259 0.0 +1260 0.0 +1261 0.0 +1262 0.0 +1263 0.0 +1264 0.0 +1265 0.0 +1266 0.0 +1267 0.0 +1268 0.0 +1269 0.0 +1270 0.0 +1271 0.0 +1272 0.0 +1273 0.0 +1274 0.0 +1275 0.0 +1276 0.0 +1277 0.0 +1278 0.0 +1279 0.0 +1280 0.0 +1281 0.0 +1282 0.0 +1283 0.0 +1284 0.0 +1285 0.0 +1286 0.0 +1287 0.0 +1288 0.0 +1289 0.0 +1290 0.0 +1291 0.0 +1292 0.0 +1293 0.0 +1294 0.0 +1295 0.0 +1296 0.0 +1297 0.0 +1298 0.0 +1299 0.0 +1300 0.0 +1301 0.0 +1302 0.0 +1303 0.0 +1304 0.0 +1305 0.0 +1306 0.0 +1307 0.0 +1308 0.0 +1309 0.0 +1310 0.0 +1311 0.0 +1312 0.0 +1313 0.0 +1314 0.0 +1315 0.0 +1316 0.0 +1317 0.0 +1318 0.0 +1319 0.0 +1320 0.0 +1321 0.0 +1322 0.0 +1323 0.0 +1324 0.0 +1325 0.0 +1326 0.0 +1327 0.0 +1328 0.0 +1329 0.0 +1330 0.0 +1331 0.0 +1332 0.0 +1333 0.0 +1334 0.0 +1335 0.0 +1336 0.0 +1337 0.0 +1338 0.0 +1339 0.0 +1340 0.0 +1341 0.0 +1342 0.0 +1343 0.0 +1344 0.0 +1345 0.0 +1346 0.0 +1347 0.0 +1348 0.0 +1349 0.0 +1350 0.0 +1351 0.0 +1352 0.0 +1353 0.0 +1354 0.0 +1355 0.0 +1356 0.0 +1357 0.0 +1358 0.0 +1359 0.0 +1360 0.0 +1361 0.0 +1362 0.0 +1363 0.0 +1364 0.0 +1365 0.0 +1366 0.0 +1367 0.0 +1368 0.0 +1369 0.0 +1370 0.0 +1371 0.0 +1372 0.0 +1373 0.0 +1374 0.0 +1375 0.0 +1376 0.0 +1377 0.0 +1378 0.0 +1379 0.0 +1380 0.0 +1381 0.0 +1382 0.0 +1383 0.0 +1384 0.0 +1385 0.0 +1386 0.0 +1387 0.0 +1388 0.0 +1389 0.0 +1390 0.0 +1391 0.0 +1392 0.0 +1393 0.0 +1394 0.0 +1395 0.0 +1396 0.0 +1397 0.0 +1398 0.0 +1399 0.0 +1400 0.0 +1401 0.0 +1402 0.0 +1403 0.0 +1404 0.0 +1405 0.0 +1406 0.0 +1407 0.0 +1408 0.0 +1409 0.0 +1410 0.0 +1411 0.0 +1412 0.0 +1413 0.0 +1414 0.0 +1415 0.0 +1416 0.0 +1417 0.0 +1418 0.0 +1419 0.0 +1420 0.0 +1421 0.0 +1422 0.0 +1423 0.0 +1424 0.0 +1425 0.0 +1426 0.0 +1427 0.0 +1428 0.0 +1429 0.0 +1430 0.0 +1431 0.0 +1432 0.0 +1433 0.0 +1434 0.0 +1435 0.0 +1436 0.0 +1437 0.0 +1438 0.0 +1439 0.0 +1440 0.0 +1441 0.0 +1442 0.0 +1443 0.0 +1444 0.0 +1445 0.0 +1446 0.0 +1447 0.0 +1448 0.0 +1449 0.0 +1450 0.0 +1451 0.0 +1452 0.0 +1453 0.0 +1454 0.0 +1455 0.0 +1456 0.0 +1457 0.0 +1458 0.0 +1459 0.0 +1460 0.0 +1461 0.0 +1462 0.0 +1463 0.0 +1464 0.0 +1465 0.0 +1466 0.0 +1467 0.0 +1468 0.0 +1469 0.0 +1470 0.0 +1471 0.0 +1472 0.0 +1473 0.0 +1474 0.0 +1475 0.0 +1476 0.0 +1477 0.0 +1478 0.0 +1479 0.0 +1480 0.0 +1481 0.0 +1482 0.0 +1483 0.0 +1484 0.0 +1485 0.0 +1486 0.0 +1487 0.0 +1488 0.0 +1489 0.0 +1490 0.0 +1491 0.0 +1492 0.0 +1493 0.0 +1494 0.0 +1495 0.0 +1496 0.0 +1497 0.0 +1498 0.0 +1499 0.0 +1500 0.0 +1501 0.0 +1502 0.0 +1503 0.0 +1504 0.0 +1505 0.0 +1506 0.0 +1507 0.0 +1508 0.0 +1509 0.0 +1510 0.0 +1511 0.0 +1512 0.0 +1513 0.0 +1514 0.0 +1515 0.0 +1516 0.0 +1517 0.0 +1518 0.0 +1519 0.0 +1520 0.0 +1521 0.0 +1522 0.0 +1523 0.0 +1524 0.0 +1525 0.0 +1526 0.0 +1527 0.0 +1528 0.0 +1529 0.0 +1530 0.0 +1531 0.0 +1532 0.0 +1533 0.0 +1534 0.0 +1535 0.0 diff --git a/tests/circuitpython/audiofilter_filter_biquads.py b/tests/circuitpython/audiofilter_filter_biquads.py new file mode 100644 index 00000000000..d5897d655da --- /dev/null +++ b/tests/circuitpython/audiofilter_filter_biquads.py @@ -0,0 +1,19 @@ +from audiofilters import Filter +from audiofilterhelper import synth_test, white8k +from synthio import Biquad, FilterMode + + +@synth_test +def basic_filter(): + effect = Filter( + filter=[ + Biquad(FilterMode.LOW_PASS, 400), + Biquad(FilterMode.HIGH_PASS, 300, Q=8), + ], + bits_per_sample=16, + samples_signed=True, + ) + yield effect, [] + + effect.play(white8k, loop=True) + yield 400 diff --git a/tests/circuitpython/audiofilter_filter_biquads.py.exp b/tests/circuitpython/audiofilter_filter_biquads.py.exp new file mode 100644 index 00000000000..769b73fa66b --- /dev/null +++ b/tests/circuitpython/audiofilter_filter_biquads.py.exp @@ -0,0 +1,102400 @@ +0 0.0030517578125 +1 0.021575927734375 +2 0.05120849609375 +3 0.053802490234375 +4 9.1552734375e-05 +5 -0.09271240234375 +6 -0.1846923828125 +7 -0.237152099609375 +8 -0.21197509765625 +9 -0.140045166015625 +10 -0.070159912109375 +11 0.004425048828125 +12 0.08868408203125 +13 0.1971435546875 +14 0.2984619140625 +15 0.34002685546875 +16 0.338958740234375 +17 0.311431884765625 +18 0.257110595703125 +19 0.169921875 +20 0.048919677734375 +21 -0.074859619140625 +22 -0.196044921875 +23 -0.3184814453125 +24 -0.41741943359375 +25 -0.462921142578125 +26 -0.4158935546875 +27 -0.27197265625 +28 -0.0966796875 +29 0.031219482421875 +30 0.110015869140625 +31 0.166961669921875 +32 0.20819091796875 +33 0.23388671875 +34 0.208282470703125 +35 0.152252197265625 +36 0.123321533203125 +37 0.093414306640625 +38 0.019500732421875 +39 -0.07281494140625 +40 -0.1202392578125 +41 -0.088623046875 +42 -0.024932861328125 +43 -0.00634765625 +44 -0.037872314453125 +45 -0.085601806640625 +46 -0.12237548828125 +47 -0.115478515625 +48 -0.05316162109375 +49 0.02166748046875 +50 0.051025390625 +51 0.041656494140625 +52 0.0546875 +53 0.127197265625 +54 0.21710205078125 +55 0.262786865234375 +56 0.282318115234375 +57 0.311279296875 +58 0.32342529296875 +59 0.273468017578125 +60 0.1549072265625 +61 0.017669677734375 +62 -0.088409423828125 +63 -0.15985107421875 +64 -0.197540283203125 +65 -0.2281494140625 +66 -0.296966552734375 +67 -0.39508056640625 +68 -0.505218505859375 +69 -0.59619140625 +70 -0.62982177734375 +71 -0.59893798828125 +72 -0.47979736328125 +73 -0.286041259765625 +74 -0.07379150390625 +75 0.12548828125 +76 0.278289794921875 +77 0.3721923828125 +78 0.44720458984375 +79 0.511260986328125 +80 0.519073486328125 +81 0.458740234375 +82 0.38153076171875 +83 0.337646484375 +84 0.332916259765625 +85 0.358184814453125 +86 0.379608154296875 +87 0.34600830078125 +88 0.239990234375 +89 0.085784912109375 +90 -0.082061767578125 +91 -0.239288330078125 +92 -0.370361328125 +93 -0.460906982421875 +94 -0.48858642578125 +95 -0.467864990234375 +96 -0.4451904296875 +97 -0.4154052734375 +98 -0.371429443359375 +99 -0.3514404296875 +100 -0.331756591796875 +101 -0.236968994140625 +102 -0.064300537109375 +103 0.137908935546875 +104 0.33056640625 +105 0.488922119140625 +106 0.58294677734375 +107 0.580413818359375 +108 0.497894287109375 +109 0.374176025390625 +110 0.252288818359375 +111 0.157257080078125 +112 0.0562744140625 +113 -0.065643310546875 +114 -0.1624755859375 +115 -0.230316162109375 +116 -0.288909912109375 +117 -0.30181884765625 +118 -0.25982666015625 +119 -0.20831298828125 +120 -0.18756103515625 +121 -0.18359375 +122 -0.147491455078125 +123 -0.077056884765625 +124 -0.011138916015625 +125 0.04608154296875 +126 0.087738037109375 +127 0.091278076171875 +128 0.09515380859375 +129 0.11663818359375 +130 0.1290283203125 +131 0.116546630859375 +132 0.07330322265625 +133 0.026763916015625 +134 -0.02392578125 +135 -0.110504150390625 +136 -0.195220947265625 +137 -0.23822021484375 +138 -0.248016357421875 +139 -0.201385498046875 +140 -0.108489990234375 +141 -0.00311279296875 +142 0.11688232421875 +143 0.21673583984375 +144 0.259368896484375 +145 0.257904052734375 +146 0.221710205078125 +147 0.1727294921875 +148 0.141082763671875 +149 0.106689453125 +150 0.0672607421875 +151 0.052734375 +152 0.08087158203125 +153 0.1357421875 +154 0.171783447265625 +155 0.1658935546875 +156 0.10931396484375 +157 0.007080078125 +158 -0.1170654296875 +159 -0.2578125 +160 -0.404937744140625 +161 -0.5286865234375 +162 -0.58502197265625 +163 -0.531005859375 +164 -0.390411376953125 +165 -0.225616455078125 +166 -0.062255859375 +167 0.100921630859375 +168 0.252532958984375 +169 0.365509033203125 +170 0.422332763671875 +171 0.41949462890625 +172 0.355621337890625 +173 0.254974365234375 +174 0.152984619140625 +175 0.062103271484375 +176 0.00994873046875 +177 -0.00531005859375 +178 -0.015167236328125 +179 -0.000640869140625 +180 0.050628662109375 +181 0.094940185546875 +182 0.079833984375 +183 0.021453857421875 +184 -0.04217529296875 +185 -0.10150146484375 +186 -0.1451416015625 +187 -0.18408203125 +188 -0.224334716796875 +189 -0.2666015625 +190 -0.318572998046875 +191 -0.37030029296875 +192 -0.39410400390625 +193 -0.35247802734375 +194 -0.241973876953125 +195 -0.08026123046875 +196 0.105438232421875 +197 0.25439453125 +198 0.339630126953125 +199 0.379913330078125 +200 0.368316650390625 +201 0.304412841796875 +202 0.239166259765625 +203 0.20916748046875 +204 0.188140869140625 +205 0.159393310546875 +206 0.150543212890625 +207 0.151947021484375 +208 0.122833251953125 +209 0.088531494140625 +210 0.072296142578125 +211 0.038360595703125 +212 -0.026214599609375 +213 -0.1209716796875 +214 -0.245208740234375 +215 -0.369354248046875 +216 -0.45306396484375 +217 -0.481781005859375 +218 -0.46917724609375 +219 -0.41973876953125 +220 -0.331298828125 +221 -0.221527099609375 +222 -0.1141357421875 +223 -0.015960693359375 +224 0.09100341796875 +225 0.22747802734375 +226 0.403167724609375 +227 0.596435546875 +228 0.74627685546875 +229 0.81036376953125 +230 0.7860107421875 +231 0.66998291015625 +232 0.46142578125 +233 0.197906494140625 +234 -0.05487060546875 +235 -0.23974609375 +236 -0.339080810546875 +237 -0.37896728515625 +238 -0.3905029296875 +239 -0.388916015625 +240 -0.391326904296875 +241 -0.4022216796875 +242 -0.39459228515625 +243 -0.3492431640625 +244 -0.287933349609375 +245 -0.254180908203125 +246 -0.26617431640625 +247 -0.270904541015625 +248 -0.21209716796875 +249 -0.121612548828125 +250 -0.059967041015625 +251 -0.03387451171875 +252 -0.01470947265625 +253 0.030426025390625 +254 0.133636474609375 +255 0.2659912109375 +256 0.385772705078125 +257 0.48480224609375 +258 0.531097412109375 +259 0.511962890625 +260 0.454986572265625 +261 0.404327392578125 +262 0.37890625 +263 0.350616455078125 +264 0.3045654296875 +265 0.243011474609375 +266 0.157379150390625 +267 0.027496337890625 +268 -0.149139404296875 +269 -0.3416748046875 +270 -0.53924560546875 +271 -0.725006103515625 +272 -0.838104248046875 +273 -0.832366943359375 +274 -0.727691650390625 +275 -0.579132080078125 +276 -0.435394287109375 +277 -0.318634033203125 +278 -0.195159912109375 +279 -0.038055419921875 +280 0.1104736328125 +281 0.208465576171875 +282 0.26983642578125 +283 0.34326171875 +284 0.446990966796875 +285 0.546905517578125 +286 0.61773681640625 +287 0.6514892578125 +288 0.661102294921875 +289 0.652679443359375 +290 0.602386474609375 +291 0.496124267578125 +292 0.347320556640625 +293 0.170989990234375 +294 -0.0401611328125 +295 -0.263031005859375 +296 -0.446502685546875 +297 -0.578399658203125 +298 -0.65399169921875 +299 -0.642364501953125 +300 -0.561676025390625 +301 -0.456390380859375 +302 -0.347869873046875 +303 -0.256988525390625 +304 -0.18792724609375 +305 -0.137359619140625 +306 -0.09747314453125 +307 -0.058319091796875 +308 -0.007720947265625 +309 0.06646728515625 +310 0.151611328125 +311 0.243743896484375 +312 0.35015869140625 +313 0.457366943359375 +314 0.542999267578125 +315 0.57110595703125 +316 0.504058837890625 +317 0.34808349609375 +318 0.142974853515625 +319 -0.0589599609375 +320 -0.219940185546875 +321 -0.33837890625 +322 -0.406005859375 +323 -0.4437255859375 +324 -0.497528076171875 +325 -0.561126708984375 +326 -0.600860595703125 +327 -0.58355712890625 +328 -0.4779052734375 +329 -0.27734375 +330 -0.00640869140625 +331 0.271636962890625 +332 0.48583984375 +333 0.60675048828125 +334 0.6533203125 +335 0.666595458984375 +336 0.64361572265625 +337 0.5740966796875 +338 0.499053955078125 +339 0.439697265625 +340 0.375091552734375 +341 0.2734375 +342 0.107147216796875 +343 -0.101470947265625 +344 -0.320648193359375 +345 -0.551544189453125 +346 -0.77642822265625 +347 -0.864105224609375 +348 -0.870391845703125 +349 -0.868682861328125 +350 -0.86053466796875 +351 -0.759246826171875 +352 -0.52203369140625 +353 -0.20556640625 +354 0.146942138671875 +355 0.48431396484375 +356 0.771270751953125 +357 0.868316650390625 +358 0.870361328125 +359 0.86395263671875 +360 0.8172607421875 +361 0.657073974609375 +362 0.470733642578125 +363 0.279388427734375 +364 0.086395263671875 +365 -0.140350341796875 +366 -0.40960693359375 +367 -0.6817626953125 +368 -0.859619140625 +369 -0.870391845703125 +370 -0.870391845703125 +371 -0.86444091796875 +372 -0.85723876953125 +373 -0.790008544921875 +374 -0.62847900390625 +375 -0.3956298828125 +376 -0.126708984375 +377 0.150115966796875 +378 0.424041748046875 +379 0.670623779296875 +380 0.854522705078125 +381 0.866485595703125 +382 0.86920166015625 +383 0.8653564453125 +384 0.857147216796875 +385 0.766845703125 +386 0.628509521484375 +387 0.462127685546875 +388 0.297210693359375 +389 0.14862060546875 +390 -0.00537109375 +391 -0.15753173828125 +392 -0.31304931640625 +393 -0.48876953125 +394 -0.6416015625 +395 -0.751373291015625 +396 -0.84619140625 +397 -0.861297607421875 +398 -0.863250732421875 +399 -0.856597900390625 +400 -0.7498779296875 +401 -0.624542236328125 +402 -0.47808837890625 +403 -0.253387451171875 +404 0.003692626953125 +405 0.2257080078125 +406 0.427154541015625 +407 0.643218994140625 +408 0.855926513671875 +409 0.870361328125 +410 0.870361328125 +411 0.862762451171875 +412 0.79669189453125 +413 0.595794677734375 +414 0.362152099609375 +415 0.1270751953125 +416 -0.086944580078125 +417 -0.2784423828125 +418 -0.484832763671875 +419 -0.729583740234375 +420 -0.86688232421875 +421 -0.870391845703125 +422 -0.86859130859375 +423 -0.86279296875 +424 -0.817962646484375 +425 -0.6116943359375 +426 -0.3128662109375 +427 0.039398193359375 +428 0.422821044921875 +429 0.805145263671875 +430 0.870361328125 +431 0.870361328125 +432 0.860015869140625 +433 0.727935791015625 +434 0.48114013671875 +435 0.2059326171875 +436 -0.06103515625 +437 -0.29913330078125 +438 -0.516204833984375 +439 -0.7252197265625 +440 -0.85980224609375 +441 -0.870391845703125 +442 -0.870391845703125 +443 -0.858062744140625 +444 -0.673004150390625 +445 -0.42694091796875 +446 -0.2100830078125 +447 -0.0362548828125 +448 0.10943603515625 +449 0.23516845703125 +450 0.373687744140625 +451 0.517791748046875 +452 0.602783203125 +453 0.635711669921875 +454 0.655181884765625 +455 0.65948486328125 +456 0.651275634765625 +457 0.61846923828125 +458 0.53753662109375 +459 0.404144287109375 +460 0.22186279296875 +461 0.003997802734375 +462 -0.22100830078125 +463 -0.42449951171875 +464 -0.579833984375 +465 -0.641876220703125 +466 -0.6177978515625 +467 -0.575531005859375 +468 -0.526336669921875 +469 -0.42645263671875 +470 -0.2581787109375 +471 -0.068695068359375 +472 0.09222412109375 +473 0.232147216796875 +474 0.3509521484375 +475 0.410064697265625 +476 0.372955322265625 +477 0.2554931640625 +478 0.10711669921875 +479 -0.052886962890625 +480 -0.186279296875 +481 -0.23291015625 +482 -0.209442138671875 +483 -0.174163818359375 +484 -0.126739501953125 +485 -0.048126220703125 +486 0.0426025390625 +487 0.10748291015625 +488 0.1409912109375 +489 0.19708251953125 +490 0.273651123046875 +491 0.31768798828125 +492 0.341094970703125 +493 0.368011474609375 +494 0.37249755859375 +495 0.30072021484375 +496 0.1517333984375 +497 -0.01470947265625 +498 -0.1883544921875 +499 -0.372711181640625 +500 -0.51397705078125 +501 -0.57177734375 +502 -0.53948974609375 +503 -0.43511962890625 +504 -0.2962646484375 +505 -0.161102294921875 +506 -0.0435791015625 +507 0.060394287109375 +508 0.13665771484375 +509 0.170135498046875 +510 0.16552734375 +511 0.15728759765625 +512 0.150787353515625 +513 0.12200927734375 +514 0.080108642578125 +515 0.05126953125 +516 0.062896728515625 +517 0.09271240234375 +518 0.092987060546875 +519 0.07855224609375 +520 0.06427001953125 +521 0.0347900390625 +522 -0.01171875 +523 -0.056060791015625 +524 -0.055511474609375 +525 -0.010467529296875 +526 0.02508544921875 +527 0.025665283203125 +528 0.017333984375 +529 0.00189208984375 +530 -0.03173828125 +531 -0.071502685546875 +532 -0.13543701171875 +533 -0.219970703125 +534 -0.300506591796875 +535 -0.376312255859375 +536 -0.416107177734375 +537 -0.371124267578125 +538 -0.242279052734375 +539 -0.069732666015625 +540 0.125640869140625 +541 0.31268310546875 +542 0.45501708984375 +543 0.554779052734375 +544 0.61065673828125 +545 0.610931396484375 +546 0.531463623046875 +547 0.3883056640625 +548 0.23468017578125 +549 0.095245361328125 +550 -0.00396728515625 +551 -0.04852294921875 +552 -0.055145263671875 +553 -0.0758056640625 +554 -0.138702392578125 +555 -0.209197998046875 +556 -0.289031982421875 +557 -0.37884521484375 +558 -0.456329345703125 +559 -0.51641845703125 +560 -0.519287109375 +561 -0.458251953125 +562 -0.384796142578125 +563 -0.323699951171875 +564 -0.269287109375 +565 -0.1951904296875 +566 -0.100006103515625 +567 -0.01055908203125 +568 0.1033935546875 +569 0.24908447265625 +570 0.373199462890625 +571 0.45806884765625 +572 0.511474609375 +573 0.565399169921875 +574 0.61138916015625 +575 0.5897216796875 +576 0.4906005859375 +577 0.33148193359375 +578 0.147796630859375 +579 -0.01873779296875 +580 -0.140289306640625 +581 -0.191986083984375 +582 -0.184295654296875 +583 -0.161834716796875 +584 -0.166595458984375 +585 -0.19390869140625 +586 -0.22442626953125 +587 -0.279754638671875 +588 -0.3389892578125 +589 -0.3543701171875 +590 -0.348175048828125 +591 -0.32598876953125 +592 -0.2581787109375 +593 -0.139801025390625 +594 0.014617919921875 +595 0.144378662109375 +596 0.221038818359375 +597 0.27069091796875 +598 0.294036865234375 +599 0.311767578125 +600 0.339141845703125 +601 0.360260009765625 +602 0.360504150390625 +603 0.308380126953125 +604 0.18170166015625 +605 0.0047607421875 +606 -0.17559814453125 +607 -0.3143310546875 +608 -0.36785888671875 +609 -0.36248779296875 +610 -0.343536376953125 +611 -0.3018798828125 +612 -0.231414794921875 +613 -0.117645263671875 +614 0.007049560546875 +615 0.087982177734375 +616 0.13946533203125 +617 0.17425537109375 +618 0.188201904296875 +619 0.171234130859375 +620 0.118438720703125 +621 0.05706787109375 +622 -0.010711669921875 +623 -0.0914306640625 +624 -0.162322998046875 +625 -0.194549560546875 +626 -0.1492919921875 +627 -0.02166748046875 +628 0.124053955078125 +629 0.211151123046875 +630 0.240447998046875 +631 0.242218017578125 +632 0.2257080078125 +633 0.194366455078125 +634 0.115509033203125 +635 0.0128173828125 +636 -0.053802490234375 +637 -0.110626220703125 +638 -0.199493408203125 +639 -0.29437255859375 +640 -0.33221435546875 +641 -0.27972412109375 +642 -0.185333251953125 +643 -0.128204345703125 +644 -0.115692138671875 +645 -0.116455078125 +646 -0.105926513671875 +647 -0.053955078125 +648 0.048797607421875 +649 0.157318115234375 +650 0.212005615234375 +651 0.218475341796875 +652 0.23724365234375 +653 0.30535888671875 +654 0.38128662109375 +655 0.404449462890625 +656 0.3944091796875 +657 0.3885498046875 +658 0.362640380859375 +659 0.27362060546875 +660 0.11712646484375 +661 -0.054901123046875 +662 -0.19085693359375 +663 -0.28570556640625 +664 -0.339263916015625 +665 -0.3775634765625 +666 -0.445709228515625 +667 -0.535064697265625 +668 -0.629058837890625 +669 -0.697601318359375 +670 -0.70391845703125 +671 -0.6424560546875 +672 -0.491241455078125 +673 -0.265716552734375 +674 -0.023712158203125 +675 0.201751708984375 +676 0.375823974609375 +677 0.485076904296875 +678 0.56884765625 +679 0.634765625 +680 0.63763427734375 +681 0.5660400390625 +682 0.4720458984375 +683 0.40692138671875 +684 0.3778076171875 +685 0.376953125 +686 0.371978759765625 +687 0.313140869140625 +688 0.184417724609375 +689 0.011199951171875 +690 -0.171051025390625 +691 -0.33740234375 +692 -0.47198486328125 +693 -0.560394287109375 +694 -0.58056640625 +695 -0.54754638671875 +696 -0.508575439453125 +697 -0.459503173828125 +698 -0.394378662109375 +699 -0.35260009765625 +700 -0.31170654296875 +701 -0.197418212890625 +702 -0.007965087890625 +703 0.207489013671875 +704 0.409210205078125 +705 0.57208251953125 +706 0.66595458984375 +707 0.65875244140625 +708 0.56744384765625 +709 0.431396484375 +710 0.29443359375 +711 0.182464599609375 +712 0.06365966796875 +713 -0.075958251953125 +714 -0.189422607421875 +715 -0.271942138671875 +716 -0.342529296875 +717 -0.364166259765625 +718 -0.327239990234375 +719 -0.2769775390625 +720 -0.253692626953125 +721 -0.24365234375 +722 -0.1983642578125 +723 -0.116241455078125 +724 -0.036834716796875 +725 0.034881591796875 +726 0.09124755859375 +727 0.10888671875 +728 0.125518798828125 +729 0.15771484375 +730 0.17828369140625 +731 0.17108154296875 +732 0.129974365234375 +733 0.082427978515625 +734 0.027679443359375 +735 -0.065643310546875 +736 -0.15936279296875 +737 -0.21307373046875 +738 -0.234649658203125 +739 -0.2001953125 +740 -0.119171142578125 +741 -0.024749755859375 +742 0.085784912109375 +743 0.178131103515625 +744 0.215576171875 +745 0.211456298828125 +746 0.17523193359375 +747 0.128753662109375 +748 0.1019287109375 +749 0.0743408203125 +750 0.04327392578125 +751 0.038177490234375 +752 0.076263427734375 +753 0.14105224609375 +754 0.186431884765625 +755 0.188812255859375 +756 0.1390380859375 +757 0.041778564453125 +758 -0.079437255859375 +759 -0.219390869140625 +760 -0.367828369140625 +761 -0.494873046875 +762 -0.556243896484375 +763 -0.508697509765625 +764 -0.3756103515625 +765 -0.218902587890625 +766 -0.063751220703125 +767 0.091552734375 +768 0.23602294921875 +769 0.342987060546875 +770 0.39520263671875 +771 0.389373779296875 +772 0.324249267578125 +773 0.224090576171875 +774 0.124267578125 +775 0.037078857421875 +776 -0.010101318359375 +777 -0.019439697265625 +778 -0.022796630859375 +779 -0.001556396484375 +780 0.056304931640625 +781 0.106719970703125 +782 0.096893310546875 +783 0.042694091796875 +784 -0.018035888671875 +785 -0.07586669921875 +786 -0.11944580078125 +787 -0.15972900390625 +788 -0.202606201171875 +789 -0.24859619140625 +790 -0.30517578125 +791 -0.36212158203125 +792 -0.39141845703125 +793 -0.35528564453125 +794 -0.249969482421875 +795 -0.092864990234375 +796 0.08905029296875 +797 0.2352294921875 +798 0.318817138671875 +799 0.358642578125 +800 0.347747802734375 +801 0.28564453125 +802 0.223175048828125 +803 0.196746826171875 +804 0.179840087890625 +805 0.155548095703125 +806 0.151214599609375 +807 0.156951904296875 +808 0.13177490234375 +809 0.100799560546875 +810 0.087127685546875 +811 0.05487060546875 +812 -0.009002685546875 +813 -0.10400390625 +814 -0.229400634765625 +815 -0.35552978515625 +816 -0.441925048828125 +817 -0.473846435546875 +818 -0.464813232421875 +819 -0.419097900390625 +820 -0.334320068359375 +821 -0.227935791015625 +822 -0.12347412109375 +823 -0.02764892578125 +824 0.077667236328125 +825 0.2132568359375 +826 0.38885498046875 +827 0.582794189453125 +828 0.734039306640625 +829 0.800140380859375 +830 0.7783203125 +831 0.6651611328125 +832 0.45965576171875 +833 0.199188232421875 +834 -0.050689697265625 +835 -0.23297119140625 +836 -0.33013916015625 +837 -0.368408203125 +838 -0.378936767578125 +839 -0.376983642578125 +840 -0.37969970703125 +841 -0.391510009765625 +842 -0.385345458984375 +843 -0.3419189453125 +844 -0.28289794921875 +845 -0.251617431640625 +846 -0.266143798828125 +847 -0.273345947265625 +848 -0.216796875 +849 -0.128265380859375 +850 -0.068145751953125 +851 -0.0430908203125 +852 -0.024444580078125 +853 0.020721435546875 +854 0.124481201171875 +855 0.25787353515625 +856 0.379119873046875 +857 0.47991943359375 +858 0.5281982421875 +859 0.511138916015625 +860 0.456207275390625 +861 0.407470703125 +862 0.383758544921875 +863 0.35687255859375 +864 0.31182861328125 +865 0.250885009765625 +866 0.1654052734375 +867 0.035247802734375 +868 -0.142059326171875 +869 -0.33563232421875 +870 -0.5345458984375 +871 -0.72186279296875 +872 -0.836669921875 +873 -0.8326416015625 +874 -0.7296142578125 +875 -0.582550048828125 +876 -0.440093994140625 +877 -0.324310302734375 +878 -0.20147705078125 +879 -0.044647216796875 +880 0.103973388671875 +881 0.202392578125 +882 0.264495849609375 +883 0.338897705078125 +884 0.443817138671875 +885 0.545074462890625 +886 0.6173095703125 +887 0.6524658203125 +888 0.66339111328125 +889 0.6561279296875 +890 0.606781005859375 +891 0.501190185546875 +892 0.352783203125 +893 0.176544189453125 +894 -0.034820556640625 +895 -0.258209228515625 +896 -0.44244384765625 +897 -0.5753173828125 +898 -0.65203857421875 +899 -0.641632080078125 +900 -0.562164306640625 +901 -0.458038330078125 +902 -0.350555419921875 +903 -0.260528564453125 +904 -0.192108154296875 +905 -0.141937255859375 +906 -0.1021728515625 +907 -0.062896728515625 +908 -0.011932373046875 +909 0.062835693359375 +910 0.148712158203125 +911 0.241729736328125 +912 0.34912109375 +913 0.457305908203125 +914 0.54388427734375 +915 0.5728759765625 +916 0.506591796875 +917 0.351226806640625 +918 0.146514892578125 +919 -0.05523681640625 +920 -0.21624755859375 +921 -0.334930419921875 +922 -0.402984619140625 +923 -0.4412841796875 +924 -0.49578857421875 +925 -0.5601806640625 +926 -0.600738525390625 +927 -0.584228515625 +928 -0.47930908203125 +929 -0.27935791015625 +930 -0.0089111328125 +931 0.268798828125 +932 0.482818603515625 +933 0.60369873046875 +934 0.650421142578125 +935 0.66400146484375 +936 0.6414794921875 +937 0.572540283203125 +938 0.498138427734375 +939 0.439453125 +940 0.375518798828125 +941 0.274505615234375 +942 0.1087646484375 +943 -0.099395751953125 +944 -0.3182373046875 +945 -0.5489501953125 +946 -0.7738037109375 +947 -0.86383056640625 +948 -0.870391845703125 +949 -0.86895751953125 +950 -0.861053466796875 +951 -0.765869140625 +952 -0.5301513671875 +953 -0.214691162109375 +954 0.137359619140625 +955 0.474822998046875 +956 0.76239013671875 +957 0.867462158203125 +958 0.870361328125 +959 0.86480712890625 +960 0.831817626953125 +961 0.677581787109375 +962 0.495880126953125 +963 0.30767822265625 +964 0.116180419921875 +965 -0.110748291015625 +966 -0.381805419921875 +967 -0.6572265625 +968 -0.857421875 +969 -0.870391845703125 +970 -0.870391845703125 +971 -0.86444091796875 +972 -0.85723876953125 +973 -0.790008544921875 +974 -0.62847900390625 +975 -0.3956298828125 +976 -0.126708984375 +977 0.150115966796875 +978 0.424041748046875 +979 0.670623779296875 +980 0.854522705078125 +981 0.866485595703125 +982 0.86920166015625 +983 0.8653564453125 +984 0.857147216796875 +985 0.766845703125 +986 0.628509521484375 +987 0.462127685546875 +988 0.297210693359375 +989 0.14862060546875 +990 -0.00537109375 +991 -0.15753173828125 +992 -0.31304931640625 +993 -0.48876953125 +994 -0.6416015625 +995 -0.751373291015625 +996 -0.84619140625 +997 -0.861297607421875 +998 -0.863250732421875 +999 -0.856597900390625 +1000 -0.7498779296875 +1001 -0.624542236328125 +1002 -0.47808837890625 +1003 -0.253387451171875 +1004 0.003692626953125 +1005 0.2257080078125 +1006 0.427154541015625 +1007 0.643218994140625 +1008 0.855926513671875 +1009 0.870361328125 +1010 0.870361328125 +1011 0.862762451171875 +1012 0.79669189453125 +1013 0.595794677734375 +1014 0.362152099609375 +1015 0.1270751953125 +1016 -0.086944580078125 +1017 -0.2784423828125 +1018 -0.484832763671875 +1019 -0.729583740234375 +1020 -0.86688232421875 +1021 -0.870391845703125 +1022 -0.86859130859375 +1023 -0.86279296875 +1024 -0.817962646484375 +1025 -0.6116943359375 +1026 -0.3128662109375 +1027 0.039398193359375 +1028 0.422821044921875 +1029 0.805145263671875 +1030 0.870361328125 +1031 0.870361328125 +1032 0.860015869140625 +1033 0.727935791015625 +1034 0.48114013671875 +1035 0.2059326171875 +1036 -0.06103515625 +1037 -0.29913330078125 +1038 -0.516204833984375 +1039 -0.7252197265625 +1040 -0.85980224609375 +1041 -0.870391845703125 +1042 -0.870391845703125 +1043 -0.858062744140625 +1044 -0.673004150390625 +1045 -0.42694091796875 +1046 -0.2100830078125 +1047 -0.0362548828125 +1048 0.10943603515625 +1049 0.23516845703125 +1050 0.373687744140625 +1051 0.517791748046875 +1052 0.602783203125 +1053 0.635711669921875 +1054 0.655181884765625 +1055 0.65948486328125 +1056 0.651275634765625 +1057 0.61846923828125 +1058 0.53753662109375 +1059 0.404144287109375 +1060 0.22186279296875 +1061 0.003997802734375 +1062 -0.22100830078125 +1063 -0.42449951171875 +1064 -0.579833984375 +1065 -0.641876220703125 +1066 -0.6177978515625 +1067 -0.575531005859375 +1068 -0.526336669921875 +1069 -0.42645263671875 +1070 -0.2581787109375 +1071 -0.068695068359375 +1072 0.09222412109375 +1073 0.232147216796875 +1074 0.3509521484375 +1075 0.410064697265625 +1076 0.372955322265625 +1077 0.2554931640625 +1078 0.10711669921875 +1079 -0.052886962890625 +1080 -0.186279296875 +1081 -0.23291015625 +1082 -0.209442138671875 +1083 -0.174163818359375 +1084 -0.126739501953125 +1085 -0.048126220703125 +1086 0.0426025390625 +1087 0.10748291015625 +1088 0.1409912109375 +1089 0.19708251953125 +1090 0.273651123046875 +1091 0.31768798828125 +1092 0.341094970703125 +1093 0.368011474609375 +1094 0.37249755859375 +1095 0.30072021484375 +1096 0.1517333984375 +1097 -0.01470947265625 +1098 -0.1883544921875 +1099 -0.372711181640625 +1100 -0.51397705078125 +1101 -0.57177734375 +1102 -0.53948974609375 +1103 -0.43511962890625 +1104 -0.2962646484375 +1105 -0.161102294921875 +1106 -0.0435791015625 +1107 0.060394287109375 +1108 0.13665771484375 +1109 0.170135498046875 +1110 0.16552734375 +1111 0.15728759765625 +1112 0.150787353515625 +1113 0.12200927734375 +1114 0.080108642578125 +1115 0.05126953125 +1116 0.062896728515625 +1117 0.09271240234375 +1118 0.092987060546875 +1119 0.07855224609375 +1120 0.06427001953125 +1121 0.0347900390625 +1122 -0.01171875 +1123 -0.056060791015625 +1124 -0.055511474609375 +1125 -0.010467529296875 +1126 0.02508544921875 +1127 0.025665283203125 +1128 0.017333984375 +1129 0.00189208984375 +1130 -0.03173828125 +1131 -0.071502685546875 +1132 -0.13543701171875 +1133 -0.219970703125 +1134 -0.300506591796875 +1135 -0.376312255859375 +1136 -0.416107177734375 +1137 -0.371124267578125 +1138 -0.242279052734375 +1139 -0.069732666015625 +1140 0.125640869140625 +1141 0.31268310546875 +1142 0.45501708984375 +1143 0.554779052734375 +1144 0.61065673828125 +1145 0.610931396484375 +1146 0.531463623046875 +1147 0.3883056640625 +1148 0.23468017578125 +1149 0.095245361328125 +1150 -0.00396728515625 +1151 -0.04852294921875 +1152 -0.055145263671875 +1153 -0.0758056640625 +1154 -0.138702392578125 +1155 -0.209197998046875 +1156 -0.289031982421875 +1157 -0.37884521484375 +1158 -0.456329345703125 +1159 -0.51641845703125 +1160 -0.519287109375 +1161 -0.458251953125 +1162 -0.384796142578125 +1163 -0.323699951171875 +1164 -0.269287109375 +1165 -0.1951904296875 +1166 -0.100006103515625 +1167 -0.01055908203125 +1168 0.1033935546875 +1169 0.24908447265625 +1170 0.373199462890625 +1171 0.45806884765625 +1172 0.511474609375 +1173 0.565399169921875 +1174 0.61138916015625 +1175 0.5897216796875 +1176 0.4906005859375 +1177 0.33148193359375 +1178 0.147796630859375 +1179 -0.01873779296875 +1180 -0.140289306640625 +1181 -0.191986083984375 +1182 -0.184295654296875 +1183 -0.161834716796875 +1184 -0.166595458984375 +1185 -0.19390869140625 +1186 -0.22442626953125 +1187 -0.279754638671875 +1188 -0.3389892578125 +1189 -0.3543701171875 +1190 -0.348175048828125 +1191 -0.32598876953125 +1192 -0.2581787109375 +1193 -0.139801025390625 +1194 0.014617919921875 +1195 0.144378662109375 +1196 0.221038818359375 +1197 0.27069091796875 +1198 0.294036865234375 +1199 0.311767578125 +1200 0.339141845703125 +1201 0.360260009765625 +1202 0.360504150390625 +1203 0.308380126953125 +1204 0.18170166015625 +1205 0.0047607421875 +1206 -0.17559814453125 +1207 -0.3143310546875 +1208 -0.36785888671875 +1209 -0.36248779296875 +1210 -0.343536376953125 +1211 -0.3018798828125 +1212 -0.231414794921875 +1213 -0.117645263671875 +1214 0.007049560546875 +1215 0.087982177734375 +1216 0.13946533203125 +1217 0.17425537109375 +1218 0.188201904296875 +1219 0.171234130859375 +1220 0.118438720703125 +1221 0.05706787109375 +1222 -0.010711669921875 +1223 -0.0914306640625 +1224 -0.162322998046875 +1225 -0.194549560546875 +1226 -0.1492919921875 +1227 -0.02166748046875 +1228 0.124053955078125 +1229 0.211151123046875 +1230 0.240447998046875 +1231 0.242218017578125 +1232 0.2257080078125 +1233 0.194366455078125 +1234 0.115509033203125 +1235 0.0128173828125 +1236 -0.053802490234375 +1237 -0.110626220703125 +1238 -0.199493408203125 +1239 -0.29437255859375 +1240 -0.33221435546875 +1241 -0.27972412109375 +1242 -0.185333251953125 +1243 -0.128204345703125 +1244 -0.115692138671875 +1245 -0.116455078125 +1246 -0.105926513671875 +1247 -0.053955078125 +1248 0.048797607421875 +1249 0.157318115234375 +1250 0.212005615234375 +1251 0.218475341796875 +1252 0.23724365234375 +1253 0.30535888671875 +1254 0.38128662109375 +1255 0.404449462890625 +1256 0.3944091796875 +1257 0.3885498046875 +1258 0.362640380859375 +1259 0.27362060546875 +1260 0.11712646484375 +1261 -0.054901123046875 +1262 -0.19085693359375 +1263 -0.28570556640625 +1264 -0.339263916015625 +1265 -0.3775634765625 +1266 -0.445709228515625 +1267 -0.535064697265625 +1268 -0.629058837890625 +1269 -0.697601318359375 +1270 -0.70391845703125 +1271 -0.6424560546875 +1272 -0.491241455078125 +1273 -0.265716552734375 +1274 -0.023712158203125 +1275 0.201751708984375 +1276 0.375823974609375 +1277 0.485076904296875 +1278 0.56884765625 +1279 0.634765625 +1280 0.63763427734375 +1281 0.5660400390625 +1282 0.4720458984375 +1283 0.40692138671875 +1284 0.3778076171875 +1285 0.376953125 +1286 0.371978759765625 +1287 0.313140869140625 +1288 0.184417724609375 +1289 0.011199951171875 +1290 -0.171051025390625 +1291 -0.33740234375 +1292 -0.47198486328125 +1293 -0.560394287109375 +1294 -0.58056640625 +1295 -0.54754638671875 +1296 -0.508575439453125 +1297 -0.459503173828125 +1298 -0.394378662109375 +1299 -0.35260009765625 +1300 -0.31170654296875 +1301 -0.197418212890625 +1302 -0.007965087890625 +1303 0.207489013671875 +1304 0.409210205078125 +1305 0.57208251953125 +1306 0.66595458984375 +1307 0.65875244140625 +1308 0.56744384765625 +1309 0.431396484375 +1310 0.29443359375 +1311 0.182464599609375 +1312 0.06365966796875 +1313 -0.075958251953125 +1314 -0.189422607421875 +1315 -0.271942138671875 +1316 -0.342529296875 +1317 -0.364166259765625 +1318 -0.327239990234375 +1319 -0.2769775390625 +1320 -0.253692626953125 +1321 -0.24365234375 +1322 -0.1983642578125 +1323 -0.116241455078125 +1324 -0.036834716796875 +1325 0.034881591796875 +1326 0.09124755859375 +1327 0.10888671875 +1328 0.125518798828125 +1329 0.15771484375 +1330 0.17828369140625 +1331 0.17108154296875 +1332 0.129974365234375 +1333 0.082427978515625 +1334 0.027679443359375 +1335 -0.065643310546875 +1336 -0.15936279296875 +1337 -0.21307373046875 +1338 -0.234649658203125 +1339 -0.2001953125 +1340 -0.119171142578125 +1341 -0.024749755859375 +1342 0.085784912109375 +1343 0.178131103515625 +1344 0.215576171875 +1345 0.211456298828125 +1346 0.17523193359375 +1347 0.128753662109375 +1348 0.1019287109375 +1349 0.0743408203125 +1350 0.04327392578125 +1351 0.038177490234375 +1352 0.076263427734375 +1353 0.14105224609375 +1354 0.186431884765625 +1355 0.188812255859375 +1356 0.1390380859375 +1357 0.041778564453125 +1358 -0.079437255859375 +1359 -0.219390869140625 +1360 -0.367828369140625 +1361 -0.494873046875 +1362 -0.556243896484375 +1363 -0.508697509765625 +1364 -0.3756103515625 +1365 -0.218902587890625 +1366 -0.063751220703125 +1367 0.091552734375 +1368 0.23602294921875 +1369 0.342987060546875 +1370 0.39520263671875 +1371 0.389373779296875 +1372 0.324249267578125 +1373 0.224090576171875 +1374 0.124267578125 +1375 0.037078857421875 +1376 -0.010101318359375 +1377 -0.019439697265625 +1378 -0.022796630859375 +1379 -0.001556396484375 +1380 0.056304931640625 +1381 0.106719970703125 +1382 0.096893310546875 +1383 0.042694091796875 +1384 -0.018035888671875 +1385 -0.07586669921875 +1386 -0.11944580078125 +1387 -0.15972900390625 +1388 -0.202606201171875 +1389 -0.24859619140625 +1390 -0.30517578125 +1391 -0.36212158203125 +1392 -0.39141845703125 +1393 -0.35528564453125 +1394 -0.249969482421875 +1395 -0.092864990234375 +1396 0.08905029296875 +1397 0.2352294921875 +1398 0.318817138671875 +1399 0.358642578125 +1400 0.347747802734375 +1401 0.28564453125 +1402 0.223175048828125 +1403 0.196746826171875 +1404 0.179840087890625 +1405 0.155548095703125 +1406 0.151214599609375 +1407 0.156951904296875 +1408 0.13177490234375 +1409 0.100799560546875 +1410 0.087127685546875 +1411 0.05487060546875 +1412 -0.009002685546875 +1413 -0.10400390625 +1414 -0.229400634765625 +1415 -0.35552978515625 +1416 -0.441925048828125 +1417 -0.473846435546875 +1418 -0.464813232421875 +1419 -0.419097900390625 +1420 -0.334320068359375 +1421 -0.227935791015625 +1422 -0.12347412109375 +1423 -0.02764892578125 +1424 0.077667236328125 +1425 0.2132568359375 +1426 0.38885498046875 +1427 0.582794189453125 +1428 0.734039306640625 +1429 0.800140380859375 +1430 0.7783203125 +1431 0.6651611328125 +1432 0.45965576171875 +1433 0.199188232421875 +1434 -0.050689697265625 +1435 -0.23297119140625 +1436 -0.33013916015625 +1437 -0.368408203125 +1438 -0.378936767578125 +1439 -0.376983642578125 +1440 -0.37969970703125 +1441 -0.391510009765625 +1442 -0.385345458984375 +1443 -0.3419189453125 +1444 -0.28289794921875 +1445 -0.251617431640625 +1446 -0.266143798828125 +1447 -0.273345947265625 +1448 -0.216796875 +1449 -0.128265380859375 +1450 -0.068145751953125 +1451 -0.0430908203125 +1452 -0.024444580078125 +1453 0.020721435546875 +1454 0.124481201171875 +1455 0.25787353515625 +1456 0.379119873046875 +1457 0.47991943359375 +1458 0.5281982421875 +1459 0.511138916015625 +1460 0.456207275390625 +1461 0.407470703125 +1462 0.383758544921875 +1463 0.35687255859375 +1464 0.31182861328125 +1465 0.250885009765625 +1466 0.1654052734375 +1467 0.035247802734375 +1468 -0.142059326171875 +1469 -0.33563232421875 +1470 -0.5345458984375 +1471 -0.72186279296875 +1472 -0.836669921875 +1473 -0.8326416015625 +1474 -0.7296142578125 +1475 -0.582550048828125 +1476 -0.440093994140625 +1477 -0.324310302734375 +1478 -0.20147705078125 +1479 -0.044647216796875 +1480 0.103973388671875 +1481 0.202392578125 +1482 0.264495849609375 +1483 0.338897705078125 +1484 0.443817138671875 +1485 0.545074462890625 +1486 0.6173095703125 +1487 0.6524658203125 +1488 0.66339111328125 +1489 0.6561279296875 +1490 0.606781005859375 +1491 0.501190185546875 +1492 0.352783203125 +1493 0.176544189453125 +1494 -0.034820556640625 +1495 -0.258209228515625 +1496 -0.44244384765625 +1497 -0.5753173828125 +1498 -0.65203857421875 +1499 -0.641632080078125 +1500 -0.562164306640625 +1501 -0.458038330078125 +1502 -0.350555419921875 +1503 -0.260528564453125 +1504 -0.192108154296875 +1505 -0.141937255859375 +1506 -0.1021728515625 +1507 -0.062896728515625 +1508 -0.011932373046875 +1509 0.062835693359375 +1510 0.148712158203125 +1511 0.241729736328125 +1512 0.34912109375 +1513 0.457305908203125 +1514 0.54388427734375 +1515 0.5728759765625 +1516 0.506591796875 +1517 0.351226806640625 +1518 0.146514892578125 +1519 -0.05523681640625 +1520 -0.21624755859375 +1521 -0.334930419921875 +1522 -0.402984619140625 +1523 -0.4412841796875 +1524 -0.49578857421875 +1525 -0.5601806640625 +1526 -0.600738525390625 +1527 -0.584228515625 +1528 -0.47930908203125 +1529 -0.27935791015625 +1530 -0.0089111328125 +1531 0.268798828125 +1532 0.482818603515625 +1533 0.60369873046875 +1534 0.650421142578125 +1535 0.66400146484375 +1536 0.6414794921875 +1537 0.572540283203125 +1538 0.498138427734375 +1539 0.439453125 +1540 0.375518798828125 +1541 0.274505615234375 +1542 0.1087646484375 +1543 -0.099395751953125 +1544 -0.3182373046875 +1545 -0.5489501953125 +1546 -0.7738037109375 +1547 -0.86383056640625 +1548 -0.870391845703125 +1549 -0.86895751953125 +1550 -0.861053466796875 +1551 -0.765869140625 +1552 -0.5301513671875 +1553 -0.214691162109375 +1554 0.137359619140625 +1555 0.474822998046875 +1556 0.76239013671875 +1557 0.867462158203125 +1558 0.870361328125 +1559 0.86480712890625 +1560 0.831817626953125 +1561 0.677581787109375 +1562 0.495880126953125 +1563 0.30767822265625 +1564 0.116180419921875 +1565 -0.110748291015625 +1566 -0.381805419921875 +1567 -0.6572265625 +1568 -0.857421875 +1569 -0.870391845703125 +1570 -0.870391845703125 +1571 -0.86444091796875 +1572 -0.85723876953125 +1573 -0.790008544921875 +1574 -0.62847900390625 +1575 -0.3956298828125 +1576 -0.126708984375 +1577 0.150115966796875 +1578 0.424041748046875 +1579 0.670623779296875 +1580 0.854522705078125 +1581 0.866485595703125 +1582 0.86920166015625 +1583 0.8653564453125 +1584 0.857147216796875 +1585 0.766845703125 +1586 0.628509521484375 +1587 0.462127685546875 +1588 0.297210693359375 +1589 0.14862060546875 +1590 -0.00537109375 +1591 -0.15753173828125 +1592 -0.31304931640625 +1593 -0.48876953125 +1594 -0.6416015625 +1595 -0.751373291015625 +1596 -0.84619140625 +1597 -0.861297607421875 +1598 -0.863250732421875 +1599 -0.856597900390625 +1600 -0.7498779296875 +1601 -0.624542236328125 +1602 -0.47808837890625 +1603 -0.253387451171875 +1604 0.003692626953125 +1605 0.2257080078125 +1606 0.427154541015625 +1607 0.643218994140625 +1608 0.855926513671875 +1609 0.870361328125 +1610 0.870361328125 +1611 0.862762451171875 +1612 0.79669189453125 +1613 0.595794677734375 +1614 0.362152099609375 +1615 0.1270751953125 +1616 -0.086944580078125 +1617 -0.2784423828125 +1618 -0.484832763671875 +1619 -0.729583740234375 +1620 -0.86688232421875 +1621 -0.870391845703125 +1622 -0.86859130859375 +1623 -0.86279296875 +1624 -0.817962646484375 +1625 -0.6116943359375 +1626 -0.3128662109375 +1627 0.039398193359375 +1628 0.422821044921875 +1629 0.805145263671875 +1630 0.870361328125 +1631 0.870361328125 +1632 0.860015869140625 +1633 0.727935791015625 +1634 0.48114013671875 +1635 0.2059326171875 +1636 -0.06103515625 +1637 -0.29913330078125 +1638 -0.516204833984375 +1639 -0.7252197265625 +1640 -0.85980224609375 +1641 -0.870391845703125 +1642 -0.870391845703125 +1643 -0.858062744140625 +1644 -0.673004150390625 +1645 -0.42694091796875 +1646 -0.2100830078125 +1647 -0.0362548828125 +1648 0.10943603515625 +1649 0.23516845703125 +1650 0.373687744140625 +1651 0.517791748046875 +1652 0.602783203125 +1653 0.635711669921875 +1654 0.655181884765625 +1655 0.65948486328125 +1656 0.651275634765625 +1657 0.61846923828125 +1658 0.53753662109375 +1659 0.404144287109375 +1660 0.22186279296875 +1661 0.003997802734375 +1662 -0.22100830078125 +1663 -0.42449951171875 +1664 -0.579833984375 +1665 -0.641876220703125 +1666 -0.6177978515625 +1667 -0.575531005859375 +1668 -0.526336669921875 +1669 -0.42645263671875 +1670 -0.2581787109375 +1671 -0.068695068359375 +1672 0.09222412109375 +1673 0.232147216796875 +1674 0.3509521484375 +1675 0.410064697265625 +1676 0.372955322265625 +1677 0.2554931640625 +1678 0.10711669921875 +1679 -0.052886962890625 +1680 -0.186279296875 +1681 -0.23291015625 +1682 -0.209442138671875 +1683 -0.174163818359375 +1684 -0.126739501953125 +1685 -0.048126220703125 +1686 0.0426025390625 +1687 0.10748291015625 +1688 0.1409912109375 +1689 0.19708251953125 +1690 0.273651123046875 +1691 0.31768798828125 +1692 0.341094970703125 +1693 0.368011474609375 +1694 0.37249755859375 +1695 0.30072021484375 +1696 0.1517333984375 +1697 -0.01470947265625 +1698 -0.1883544921875 +1699 -0.372711181640625 +1700 -0.51397705078125 +1701 -0.57177734375 +1702 -0.53948974609375 +1703 -0.43511962890625 +1704 -0.2962646484375 +1705 -0.161102294921875 +1706 -0.0435791015625 +1707 0.060394287109375 +1708 0.13665771484375 +1709 0.170135498046875 +1710 0.16552734375 +1711 0.15728759765625 +1712 0.150787353515625 +1713 0.12200927734375 +1714 0.080108642578125 +1715 0.05126953125 +1716 0.062896728515625 +1717 0.09271240234375 +1718 0.092987060546875 +1719 0.07855224609375 +1720 0.06427001953125 +1721 0.0347900390625 +1722 -0.01171875 +1723 -0.056060791015625 +1724 -0.055511474609375 +1725 -0.010467529296875 +1726 0.02508544921875 +1727 0.025665283203125 +1728 0.017333984375 +1729 0.00189208984375 +1730 -0.03173828125 +1731 -0.071502685546875 +1732 -0.13543701171875 +1733 -0.219970703125 +1734 -0.300506591796875 +1735 -0.376312255859375 +1736 -0.416107177734375 +1737 -0.371124267578125 +1738 -0.242279052734375 +1739 -0.069732666015625 +1740 0.125640869140625 +1741 0.31268310546875 +1742 0.45501708984375 +1743 0.554779052734375 +1744 0.61065673828125 +1745 0.610931396484375 +1746 0.531463623046875 +1747 0.3883056640625 +1748 0.23468017578125 +1749 0.095245361328125 +1750 -0.00396728515625 +1751 -0.04852294921875 +1752 -0.055145263671875 +1753 -0.0758056640625 +1754 -0.138702392578125 +1755 -0.209197998046875 +1756 -0.289031982421875 +1757 -0.37884521484375 +1758 -0.456329345703125 +1759 -0.51641845703125 +1760 -0.519287109375 +1761 -0.458251953125 +1762 -0.384796142578125 +1763 -0.323699951171875 +1764 -0.269287109375 +1765 -0.1951904296875 +1766 -0.100006103515625 +1767 -0.01055908203125 +1768 0.1033935546875 +1769 0.24908447265625 +1770 0.373199462890625 +1771 0.45806884765625 +1772 0.511474609375 +1773 0.565399169921875 +1774 0.61138916015625 +1775 0.5897216796875 +1776 0.4906005859375 +1777 0.33148193359375 +1778 0.147796630859375 +1779 -0.01873779296875 +1780 -0.140289306640625 +1781 -0.191986083984375 +1782 -0.184295654296875 +1783 -0.161834716796875 +1784 -0.166595458984375 +1785 -0.19390869140625 +1786 -0.22442626953125 +1787 -0.279754638671875 +1788 -0.3389892578125 +1789 -0.3543701171875 +1790 -0.348175048828125 +1791 -0.32598876953125 +1792 -0.2581787109375 +1793 -0.139801025390625 +1794 0.014617919921875 +1795 0.144378662109375 +1796 0.221038818359375 +1797 0.27069091796875 +1798 0.294036865234375 +1799 0.311767578125 +1800 0.339141845703125 +1801 0.360260009765625 +1802 0.360504150390625 +1803 0.308380126953125 +1804 0.18170166015625 +1805 0.0047607421875 +1806 -0.17559814453125 +1807 -0.3143310546875 +1808 -0.36785888671875 +1809 -0.36248779296875 +1810 -0.343536376953125 +1811 -0.3018798828125 +1812 -0.231414794921875 +1813 -0.117645263671875 +1814 0.007049560546875 +1815 0.087982177734375 +1816 0.13946533203125 +1817 0.17425537109375 +1818 0.188201904296875 +1819 0.171234130859375 +1820 0.118438720703125 +1821 0.05706787109375 +1822 -0.010711669921875 +1823 -0.0914306640625 +1824 -0.162322998046875 +1825 -0.194549560546875 +1826 -0.1492919921875 +1827 -0.02166748046875 +1828 0.124053955078125 +1829 0.211151123046875 +1830 0.240447998046875 +1831 0.242218017578125 +1832 0.2257080078125 +1833 0.194366455078125 +1834 0.115509033203125 +1835 0.0128173828125 +1836 -0.053802490234375 +1837 -0.110626220703125 +1838 -0.199493408203125 +1839 -0.29437255859375 +1840 -0.33221435546875 +1841 -0.27972412109375 +1842 -0.185333251953125 +1843 -0.128204345703125 +1844 -0.115692138671875 +1845 -0.116455078125 +1846 -0.105926513671875 +1847 -0.053955078125 +1848 0.048797607421875 +1849 0.157318115234375 +1850 0.212005615234375 +1851 0.218475341796875 +1852 0.23724365234375 +1853 0.30535888671875 +1854 0.38128662109375 +1855 0.404449462890625 +1856 0.3944091796875 +1857 0.3885498046875 +1858 0.362640380859375 +1859 0.27362060546875 +1860 0.11712646484375 +1861 -0.054901123046875 +1862 -0.19085693359375 +1863 -0.28570556640625 +1864 -0.339263916015625 +1865 -0.3775634765625 +1866 -0.445709228515625 +1867 -0.535064697265625 +1868 -0.629058837890625 +1869 -0.697601318359375 +1870 -0.70391845703125 +1871 -0.6424560546875 +1872 -0.491241455078125 +1873 -0.265716552734375 +1874 -0.023712158203125 +1875 0.201751708984375 +1876 0.375823974609375 +1877 0.485076904296875 +1878 0.56884765625 +1879 0.634765625 +1880 0.63763427734375 +1881 0.5660400390625 +1882 0.4720458984375 +1883 0.40692138671875 +1884 0.3778076171875 +1885 0.376953125 +1886 0.371978759765625 +1887 0.313140869140625 +1888 0.184417724609375 +1889 0.011199951171875 +1890 -0.171051025390625 +1891 -0.33740234375 +1892 -0.47198486328125 +1893 -0.560394287109375 +1894 -0.58056640625 +1895 -0.54754638671875 +1896 -0.508575439453125 +1897 -0.459503173828125 +1898 -0.394378662109375 +1899 -0.35260009765625 +1900 -0.31170654296875 +1901 -0.197418212890625 +1902 -0.007965087890625 +1903 0.207489013671875 +1904 0.409210205078125 +1905 0.57208251953125 +1906 0.66595458984375 +1907 0.65875244140625 +1908 0.56744384765625 +1909 0.431396484375 +1910 0.29443359375 +1911 0.182464599609375 +1912 0.06365966796875 +1913 -0.075958251953125 +1914 -0.189422607421875 +1915 -0.271942138671875 +1916 -0.342529296875 +1917 -0.364166259765625 +1918 -0.327239990234375 +1919 -0.2769775390625 +1920 -0.253692626953125 +1921 -0.24365234375 +1922 -0.1983642578125 +1923 -0.116241455078125 +1924 -0.036834716796875 +1925 0.034881591796875 +1926 0.09124755859375 +1927 0.10888671875 +1928 0.125518798828125 +1929 0.15771484375 +1930 0.17828369140625 +1931 0.17108154296875 +1932 0.129974365234375 +1933 0.082427978515625 +1934 0.027679443359375 +1935 -0.065643310546875 +1936 -0.15936279296875 +1937 -0.21307373046875 +1938 -0.234649658203125 +1939 -0.2001953125 +1940 -0.119171142578125 +1941 -0.024749755859375 +1942 0.085784912109375 +1943 0.178131103515625 +1944 0.215576171875 +1945 0.211456298828125 +1946 0.17523193359375 +1947 0.128753662109375 +1948 0.1019287109375 +1949 0.0743408203125 +1950 0.04327392578125 +1951 0.038177490234375 +1952 0.076263427734375 +1953 0.14105224609375 +1954 0.186431884765625 +1955 0.188812255859375 +1956 0.1390380859375 +1957 0.041778564453125 +1958 -0.079437255859375 +1959 -0.219390869140625 +1960 -0.367828369140625 +1961 -0.494873046875 +1962 -0.556243896484375 +1963 -0.508697509765625 +1964 -0.3756103515625 +1965 -0.218902587890625 +1966 -0.063751220703125 +1967 0.091552734375 +1968 0.23602294921875 +1969 0.342987060546875 +1970 0.39520263671875 +1971 0.389373779296875 +1972 0.324249267578125 +1973 0.224090576171875 +1974 0.124267578125 +1975 0.037078857421875 +1976 -0.010101318359375 +1977 -0.019439697265625 +1978 -0.022796630859375 +1979 -0.001556396484375 +1980 0.056304931640625 +1981 0.106719970703125 +1982 0.096893310546875 +1983 0.042694091796875 +1984 -0.018035888671875 +1985 -0.07586669921875 +1986 -0.11944580078125 +1987 -0.15972900390625 +1988 -0.202606201171875 +1989 -0.24859619140625 +1990 -0.30517578125 +1991 -0.36212158203125 +1992 -0.39141845703125 +1993 -0.35528564453125 +1994 -0.249969482421875 +1995 -0.092864990234375 +1996 0.08905029296875 +1997 0.2352294921875 +1998 0.318817138671875 +1999 0.358642578125 +2000 0.347747802734375 +2001 0.28564453125 +2002 0.223175048828125 +2003 0.196746826171875 +2004 0.179840087890625 +2005 0.155548095703125 +2006 0.151214599609375 +2007 0.156951904296875 +2008 0.13177490234375 +2009 0.100799560546875 +2010 0.087127685546875 +2011 0.05487060546875 +2012 -0.009002685546875 +2013 -0.10400390625 +2014 -0.229400634765625 +2015 -0.35552978515625 +2016 -0.441925048828125 +2017 -0.473846435546875 +2018 -0.464813232421875 +2019 -0.419097900390625 +2020 -0.334320068359375 +2021 -0.227935791015625 +2022 -0.12347412109375 +2023 -0.02764892578125 +2024 0.077667236328125 +2025 0.2132568359375 +2026 0.38885498046875 +2027 0.582794189453125 +2028 0.734039306640625 +2029 0.800140380859375 +2030 0.7783203125 +2031 0.6651611328125 +2032 0.45965576171875 +2033 0.199188232421875 +2034 -0.050689697265625 +2035 -0.23297119140625 +2036 -0.33013916015625 +2037 -0.368408203125 +2038 -0.378936767578125 +2039 -0.376983642578125 +2040 -0.37969970703125 +2041 -0.391510009765625 +2042 -0.385345458984375 +2043 -0.3419189453125 +2044 -0.28289794921875 +2045 -0.251617431640625 +2046 -0.266143798828125 +2047 -0.273345947265625 +2048 -0.216796875 +2049 -0.128265380859375 +2050 -0.068145751953125 +2051 -0.0430908203125 +2052 -0.024444580078125 +2053 0.020721435546875 +2054 0.124481201171875 +2055 0.25787353515625 +2056 0.379119873046875 +2057 0.47991943359375 +2058 0.5281982421875 +2059 0.511138916015625 +2060 0.456207275390625 +2061 0.407470703125 +2062 0.383758544921875 +2063 0.35687255859375 +2064 0.31182861328125 +2065 0.250885009765625 +2066 0.1654052734375 +2067 0.035247802734375 +2068 -0.142059326171875 +2069 -0.33563232421875 +2070 -0.5345458984375 +2071 -0.72186279296875 +2072 -0.836669921875 +2073 -0.8326416015625 +2074 -0.7296142578125 +2075 -0.582550048828125 +2076 -0.440093994140625 +2077 -0.324310302734375 +2078 -0.20147705078125 +2079 -0.044647216796875 +2080 0.103973388671875 +2081 0.202392578125 +2082 0.264495849609375 +2083 0.338897705078125 +2084 0.443817138671875 +2085 0.545074462890625 +2086 0.6173095703125 +2087 0.6524658203125 +2088 0.66339111328125 +2089 0.6561279296875 +2090 0.606781005859375 +2091 0.501190185546875 +2092 0.352783203125 +2093 0.176544189453125 +2094 -0.034820556640625 +2095 -0.258209228515625 +2096 -0.44244384765625 +2097 -0.5753173828125 +2098 -0.65203857421875 +2099 -0.641632080078125 +2100 -0.562164306640625 +2101 -0.458038330078125 +2102 -0.350555419921875 +2103 -0.260528564453125 +2104 -0.192108154296875 +2105 -0.141937255859375 +2106 -0.1021728515625 +2107 -0.062896728515625 +2108 -0.011932373046875 +2109 0.062835693359375 +2110 0.148712158203125 +2111 0.241729736328125 +2112 0.34912109375 +2113 0.457305908203125 +2114 0.54388427734375 +2115 0.5728759765625 +2116 0.506591796875 +2117 0.351226806640625 +2118 0.146514892578125 +2119 -0.05523681640625 +2120 -0.21624755859375 +2121 -0.334930419921875 +2122 -0.402984619140625 +2123 -0.4412841796875 +2124 -0.49578857421875 +2125 -0.5601806640625 +2126 -0.600738525390625 +2127 -0.584228515625 +2128 -0.47930908203125 +2129 -0.27935791015625 +2130 -0.0089111328125 +2131 0.268798828125 +2132 0.482818603515625 +2133 0.60369873046875 +2134 0.650421142578125 +2135 0.66400146484375 +2136 0.6414794921875 +2137 0.572540283203125 +2138 0.498138427734375 +2139 0.439453125 +2140 0.375518798828125 +2141 0.274505615234375 +2142 0.1087646484375 +2143 -0.099395751953125 +2144 -0.3182373046875 +2145 -0.5489501953125 +2146 -0.7738037109375 +2147 -0.86383056640625 +2148 -0.870391845703125 +2149 -0.86895751953125 +2150 -0.861053466796875 +2151 -0.765869140625 +2152 -0.5301513671875 +2153 -0.214691162109375 +2154 0.137359619140625 +2155 0.474822998046875 +2156 0.76239013671875 +2157 0.867462158203125 +2158 0.870361328125 +2159 0.86480712890625 +2160 0.831817626953125 +2161 0.677581787109375 +2162 0.495880126953125 +2163 0.30767822265625 +2164 0.116180419921875 +2165 -0.110748291015625 +2166 -0.381805419921875 +2167 -0.6572265625 +2168 -0.857421875 +2169 -0.870391845703125 +2170 -0.870391845703125 +2171 -0.86444091796875 +2172 -0.85723876953125 +2173 -0.790008544921875 +2174 -0.62847900390625 +2175 -0.3956298828125 +2176 -0.126708984375 +2177 0.150115966796875 +2178 0.424041748046875 +2179 0.670623779296875 +2180 0.854522705078125 +2181 0.866485595703125 +2182 0.86920166015625 +2183 0.8653564453125 +2184 0.857147216796875 +2185 0.766845703125 +2186 0.628509521484375 +2187 0.462127685546875 +2188 0.297210693359375 +2189 0.14862060546875 +2190 -0.00537109375 +2191 -0.15753173828125 +2192 -0.31304931640625 +2193 -0.48876953125 +2194 -0.6416015625 +2195 -0.751373291015625 +2196 -0.84619140625 +2197 -0.861297607421875 +2198 -0.863250732421875 +2199 -0.856597900390625 +2200 -0.7498779296875 +2201 -0.624542236328125 +2202 -0.47808837890625 +2203 -0.253387451171875 +2204 0.003692626953125 +2205 0.2257080078125 +2206 0.427154541015625 +2207 0.643218994140625 +2208 0.855926513671875 +2209 0.870361328125 +2210 0.870361328125 +2211 0.862762451171875 +2212 0.79669189453125 +2213 0.595794677734375 +2214 0.362152099609375 +2215 0.1270751953125 +2216 -0.086944580078125 +2217 -0.2784423828125 +2218 -0.484832763671875 +2219 -0.729583740234375 +2220 -0.86688232421875 +2221 -0.870391845703125 +2222 -0.86859130859375 +2223 -0.86279296875 +2224 -0.817962646484375 +2225 -0.6116943359375 +2226 -0.3128662109375 +2227 0.039398193359375 +2228 0.422821044921875 +2229 0.805145263671875 +2230 0.870361328125 +2231 0.870361328125 +2232 0.860015869140625 +2233 0.727935791015625 +2234 0.48114013671875 +2235 0.2059326171875 +2236 -0.06103515625 +2237 -0.29913330078125 +2238 -0.516204833984375 +2239 -0.7252197265625 +2240 -0.85980224609375 +2241 -0.870391845703125 +2242 -0.870391845703125 +2243 -0.858062744140625 +2244 -0.673004150390625 +2245 -0.42694091796875 +2246 -0.2100830078125 +2247 -0.0362548828125 +2248 0.10943603515625 +2249 0.23516845703125 +2250 0.373687744140625 +2251 0.517791748046875 +2252 0.602783203125 +2253 0.635711669921875 +2254 0.655181884765625 +2255 0.65948486328125 +2256 0.651275634765625 +2257 0.61846923828125 +2258 0.53753662109375 +2259 0.404144287109375 +2260 0.22186279296875 +2261 0.003997802734375 +2262 -0.22100830078125 +2263 -0.42449951171875 +2264 -0.579833984375 +2265 -0.641876220703125 +2266 -0.6177978515625 +2267 -0.575531005859375 +2268 -0.526336669921875 +2269 -0.42645263671875 +2270 -0.2581787109375 +2271 -0.068695068359375 +2272 0.09222412109375 +2273 0.232147216796875 +2274 0.3509521484375 +2275 0.410064697265625 +2276 0.372955322265625 +2277 0.2554931640625 +2278 0.10711669921875 +2279 -0.052886962890625 +2280 -0.186279296875 +2281 -0.23291015625 +2282 -0.209442138671875 +2283 -0.174163818359375 +2284 -0.126739501953125 +2285 -0.048126220703125 +2286 0.0426025390625 +2287 0.10748291015625 +2288 0.1409912109375 +2289 0.19708251953125 +2290 0.273651123046875 +2291 0.31768798828125 +2292 0.341094970703125 +2293 0.368011474609375 +2294 0.37249755859375 +2295 0.30072021484375 +2296 0.1517333984375 +2297 -0.01470947265625 +2298 -0.1883544921875 +2299 -0.372711181640625 +2300 -0.51397705078125 +2301 -0.57177734375 +2302 -0.53948974609375 +2303 -0.43511962890625 +2304 -0.2962646484375 +2305 -0.161102294921875 +2306 -0.0435791015625 +2307 0.060394287109375 +2308 0.13665771484375 +2309 0.170135498046875 +2310 0.16552734375 +2311 0.15728759765625 +2312 0.150787353515625 +2313 0.12200927734375 +2314 0.080108642578125 +2315 0.05126953125 +2316 0.062896728515625 +2317 0.09271240234375 +2318 0.092987060546875 +2319 0.07855224609375 +2320 0.06427001953125 +2321 0.0347900390625 +2322 -0.01171875 +2323 -0.056060791015625 +2324 -0.055511474609375 +2325 -0.010467529296875 +2326 0.02508544921875 +2327 0.025665283203125 +2328 0.017333984375 +2329 0.00189208984375 +2330 -0.03173828125 +2331 -0.071502685546875 +2332 -0.13543701171875 +2333 -0.219970703125 +2334 -0.300506591796875 +2335 -0.376312255859375 +2336 -0.416107177734375 +2337 -0.371124267578125 +2338 -0.242279052734375 +2339 -0.069732666015625 +2340 0.125640869140625 +2341 0.31268310546875 +2342 0.45501708984375 +2343 0.554779052734375 +2344 0.61065673828125 +2345 0.610931396484375 +2346 0.531463623046875 +2347 0.3883056640625 +2348 0.23468017578125 +2349 0.095245361328125 +2350 -0.00396728515625 +2351 -0.04852294921875 +2352 -0.055145263671875 +2353 -0.0758056640625 +2354 -0.138702392578125 +2355 -0.209197998046875 +2356 -0.289031982421875 +2357 -0.37884521484375 +2358 -0.456329345703125 +2359 -0.51641845703125 +2360 -0.519287109375 +2361 -0.458251953125 +2362 -0.384796142578125 +2363 -0.323699951171875 +2364 -0.269287109375 +2365 -0.1951904296875 +2366 -0.100006103515625 +2367 -0.01055908203125 +2368 0.1033935546875 +2369 0.24908447265625 +2370 0.373199462890625 +2371 0.45806884765625 +2372 0.511474609375 +2373 0.565399169921875 +2374 0.61138916015625 +2375 0.5897216796875 +2376 0.4906005859375 +2377 0.33148193359375 +2378 0.147796630859375 +2379 -0.01873779296875 +2380 -0.140289306640625 +2381 -0.191986083984375 +2382 -0.184295654296875 +2383 -0.161834716796875 +2384 -0.166595458984375 +2385 -0.19390869140625 +2386 -0.22442626953125 +2387 -0.279754638671875 +2388 -0.3389892578125 +2389 -0.3543701171875 +2390 -0.348175048828125 +2391 -0.32598876953125 +2392 -0.2581787109375 +2393 -0.139801025390625 +2394 0.014617919921875 +2395 0.144378662109375 +2396 0.221038818359375 +2397 0.27069091796875 +2398 0.294036865234375 +2399 0.311767578125 +2400 0.339141845703125 +2401 0.360260009765625 +2402 0.360504150390625 +2403 0.308380126953125 +2404 0.18170166015625 +2405 0.0047607421875 +2406 -0.17559814453125 +2407 -0.3143310546875 +2408 -0.36785888671875 +2409 -0.36248779296875 +2410 -0.343536376953125 +2411 -0.3018798828125 +2412 -0.231414794921875 +2413 -0.117645263671875 +2414 0.007049560546875 +2415 0.087982177734375 +2416 0.13946533203125 +2417 0.17425537109375 +2418 0.188201904296875 +2419 0.171234130859375 +2420 0.118438720703125 +2421 0.05706787109375 +2422 -0.010711669921875 +2423 -0.0914306640625 +2424 -0.162322998046875 +2425 -0.194549560546875 +2426 -0.1492919921875 +2427 -0.02166748046875 +2428 0.124053955078125 +2429 0.211151123046875 +2430 0.240447998046875 +2431 0.242218017578125 +2432 0.2257080078125 +2433 0.194366455078125 +2434 0.115509033203125 +2435 0.0128173828125 +2436 -0.053802490234375 +2437 -0.110626220703125 +2438 -0.199493408203125 +2439 -0.29437255859375 +2440 -0.33221435546875 +2441 -0.27972412109375 +2442 -0.185333251953125 +2443 -0.128204345703125 +2444 -0.115692138671875 +2445 -0.116455078125 +2446 -0.105926513671875 +2447 -0.053955078125 +2448 0.048797607421875 +2449 0.157318115234375 +2450 0.212005615234375 +2451 0.218475341796875 +2452 0.23724365234375 +2453 0.30535888671875 +2454 0.38128662109375 +2455 0.404449462890625 +2456 0.3944091796875 +2457 0.3885498046875 +2458 0.362640380859375 +2459 0.27362060546875 +2460 0.11712646484375 +2461 -0.054901123046875 +2462 -0.19085693359375 +2463 -0.28570556640625 +2464 -0.339263916015625 +2465 -0.3775634765625 +2466 -0.445709228515625 +2467 -0.535064697265625 +2468 -0.629058837890625 +2469 -0.697601318359375 +2470 -0.70391845703125 +2471 -0.6424560546875 +2472 -0.491241455078125 +2473 -0.265716552734375 +2474 -0.023712158203125 +2475 0.201751708984375 +2476 0.375823974609375 +2477 0.485076904296875 +2478 0.56884765625 +2479 0.634765625 +2480 0.63763427734375 +2481 0.5660400390625 +2482 0.4720458984375 +2483 0.40692138671875 +2484 0.3778076171875 +2485 0.376953125 +2486 0.371978759765625 +2487 0.313140869140625 +2488 0.184417724609375 +2489 0.011199951171875 +2490 -0.171051025390625 +2491 -0.33740234375 +2492 -0.47198486328125 +2493 -0.560394287109375 +2494 -0.58056640625 +2495 -0.54754638671875 +2496 -0.508575439453125 +2497 -0.459503173828125 +2498 -0.394378662109375 +2499 -0.35260009765625 +2500 -0.31170654296875 +2501 -0.197418212890625 +2502 -0.007965087890625 +2503 0.207489013671875 +2504 0.409210205078125 +2505 0.57208251953125 +2506 0.66595458984375 +2507 0.65875244140625 +2508 0.56744384765625 +2509 0.431396484375 +2510 0.29443359375 +2511 0.182464599609375 +2512 0.06365966796875 +2513 -0.075958251953125 +2514 -0.189422607421875 +2515 -0.271942138671875 +2516 -0.342529296875 +2517 -0.364166259765625 +2518 -0.327239990234375 +2519 -0.2769775390625 +2520 -0.253692626953125 +2521 -0.24365234375 +2522 -0.1983642578125 +2523 -0.116241455078125 +2524 -0.036834716796875 +2525 0.034881591796875 +2526 0.09124755859375 +2527 0.10888671875 +2528 0.125518798828125 +2529 0.15771484375 +2530 0.17828369140625 +2531 0.17108154296875 +2532 0.129974365234375 +2533 0.082427978515625 +2534 0.027679443359375 +2535 -0.065643310546875 +2536 -0.15936279296875 +2537 -0.21307373046875 +2538 -0.234649658203125 +2539 -0.2001953125 +2540 -0.119171142578125 +2541 -0.024749755859375 +2542 0.085784912109375 +2543 0.178131103515625 +2544 0.215576171875 +2545 0.211456298828125 +2546 0.17523193359375 +2547 0.128753662109375 +2548 0.1019287109375 +2549 0.0743408203125 +2550 0.04327392578125 +2551 0.038177490234375 +2552 0.076263427734375 +2553 0.14105224609375 +2554 0.186431884765625 +2555 0.188812255859375 +2556 0.1390380859375 +2557 0.041778564453125 +2558 -0.079437255859375 +2559 -0.219390869140625 +2560 -0.367828369140625 +2561 -0.494873046875 +2562 -0.556243896484375 +2563 -0.508697509765625 +2564 -0.3756103515625 +2565 -0.218902587890625 +2566 -0.063751220703125 +2567 0.091552734375 +2568 0.23602294921875 +2569 0.342987060546875 +2570 0.39520263671875 +2571 0.389373779296875 +2572 0.324249267578125 +2573 0.224090576171875 +2574 0.124267578125 +2575 0.037078857421875 +2576 -0.010101318359375 +2577 -0.019439697265625 +2578 -0.022796630859375 +2579 -0.001556396484375 +2580 0.056304931640625 +2581 0.106719970703125 +2582 0.096893310546875 +2583 0.042694091796875 +2584 -0.018035888671875 +2585 -0.07586669921875 +2586 -0.11944580078125 +2587 -0.15972900390625 +2588 -0.202606201171875 +2589 -0.24859619140625 +2590 -0.30517578125 +2591 -0.36212158203125 +2592 -0.39141845703125 +2593 -0.35528564453125 +2594 -0.249969482421875 +2595 -0.092864990234375 +2596 0.08905029296875 +2597 0.2352294921875 +2598 0.318817138671875 +2599 0.358642578125 +2600 0.347747802734375 +2601 0.28564453125 +2602 0.223175048828125 +2603 0.196746826171875 +2604 0.179840087890625 +2605 0.155548095703125 +2606 0.151214599609375 +2607 0.156951904296875 +2608 0.13177490234375 +2609 0.100799560546875 +2610 0.087127685546875 +2611 0.05487060546875 +2612 -0.009002685546875 +2613 -0.10400390625 +2614 -0.229400634765625 +2615 -0.35552978515625 +2616 -0.441925048828125 +2617 -0.473846435546875 +2618 -0.464813232421875 +2619 -0.419097900390625 +2620 -0.334320068359375 +2621 -0.227935791015625 +2622 -0.12347412109375 +2623 -0.02764892578125 +2624 0.077667236328125 +2625 0.2132568359375 +2626 0.38885498046875 +2627 0.582794189453125 +2628 0.734039306640625 +2629 0.800140380859375 +2630 0.7783203125 +2631 0.6651611328125 +2632 0.45965576171875 +2633 0.199188232421875 +2634 -0.050689697265625 +2635 -0.23297119140625 +2636 -0.33013916015625 +2637 -0.368408203125 +2638 -0.378936767578125 +2639 -0.376983642578125 +2640 -0.37969970703125 +2641 -0.391510009765625 +2642 -0.385345458984375 +2643 -0.3419189453125 +2644 -0.28289794921875 +2645 -0.251617431640625 +2646 -0.266143798828125 +2647 -0.273345947265625 +2648 -0.216796875 +2649 -0.128265380859375 +2650 -0.068145751953125 +2651 -0.0430908203125 +2652 -0.024444580078125 +2653 0.020721435546875 +2654 0.124481201171875 +2655 0.25787353515625 +2656 0.379119873046875 +2657 0.47991943359375 +2658 0.5281982421875 +2659 0.511138916015625 +2660 0.456207275390625 +2661 0.407470703125 +2662 0.383758544921875 +2663 0.35687255859375 +2664 0.31182861328125 +2665 0.250885009765625 +2666 0.1654052734375 +2667 0.035247802734375 +2668 -0.142059326171875 +2669 -0.33563232421875 +2670 -0.5345458984375 +2671 -0.72186279296875 +2672 -0.836669921875 +2673 -0.8326416015625 +2674 -0.7296142578125 +2675 -0.582550048828125 +2676 -0.440093994140625 +2677 -0.324310302734375 +2678 -0.20147705078125 +2679 -0.044647216796875 +2680 0.103973388671875 +2681 0.202392578125 +2682 0.264495849609375 +2683 0.338897705078125 +2684 0.443817138671875 +2685 0.545074462890625 +2686 0.6173095703125 +2687 0.6524658203125 +2688 0.66339111328125 +2689 0.6561279296875 +2690 0.606781005859375 +2691 0.501190185546875 +2692 0.352783203125 +2693 0.176544189453125 +2694 -0.034820556640625 +2695 -0.258209228515625 +2696 -0.44244384765625 +2697 -0.5753173828125 +2698 -0.65203857421875 +2699 -0.641632080078125 +2700 -0.562164306640625 +2701 -0.458038330078125 +2702 -0.350555419921875 +2703 -0.260528564453125 +2704 -0.192108154296875 +2705 -0.141937255859375 +2706 -0.1021728515625 +2707 -0.062896728515625 +2708 -0.011932373046875 +2709 0.062835693359375 +2710 0.148712158203125 +2711 0.241729736328125 +2712 0.34912109375 +2713 0.457305908203125 +2714 0.54388427734375 +2715 0.5728759765625 +2716 0.506591796875 +2717 0.351226806640625 +2718 0.146514892578125 +2719 -0.05523681640625 +2720 -0.21624755859375 +2721 -0.334930419921875 +2722 -0.402984619140625 +2723 -0.4412841796875 +2724 -0.49578857421875 +2725 -0.5601806640625 +2726 -0.600738525390625 +2727 -0.584228515625 +2728 -0.47930908203125 +2729 -0.27935791015625 +2730 -0.0089111328125 +2731 0.268798828125 +2732 0.482818603515625 +2733 0.60369873046875 +2734 0.650421142578125 +2735 0.66400146484375 +2736 0.6414794921875 +2737 0.572540283203125 +2738 0.498138427734375 +2739 0.439453125 +2740 0.375518798828125 +2741 0.274505615234375 +2742 0.1087646484375 +2743 -0.099395751953125 +2744 -0.3182373046875 +2745 -0.5489501953125 +2746 -0.7738037109375 +2747 -0.86383056640625 +2748 -0.870391845703125 +2749 -0.86895751953125 +2750 -0.861053466796875 +2751 -0.765869140625 +2752 -0.5301513671875 +2753 -0.214691162109375 +2754 0.137359619140625 +2755 0.474822998046875 +2756 0.76239013671875 +2757 0.867462158203125 +2758 0.870361328125 +2759 0.86480712890625 +2760 0.831817626953125 +2761 0.677581787109375 +2762 0.495880126953125 +2763 0.30767822265625 +2764 0.116180419921875 +2765 -0.110748291015625 +2766 -0.381805419921875 +2767 -0.6572265625 +2768 -0.857421875 +2769 -0.870391845703125 +2770 -0.870391845703125 +2771 -0.86444091796875 +2772 -0.85723876953125 +2773 -0.790008544921875 +2774 -0.62847900390625 +2775 -0.3956298828125 +2776 -0.126708984375 +2777 0.150115966796875 +2778 0.424041748046875 +2779 0.670623779296875 +2780 0.854522705078125 +2781 0.866485595703125 +2782 0.86920166015625 +2783 0.8653564453125 +2784 0.857147216796875 +2785 0.766845703125 +2786 0.628509521484375 +2787 0.462127685546875 +2788 0.297210693359375 +2789 0.14862060546875 +2790 -0.00537109375 +2791 -0.15753173828125 +2792 -0.31304931640625 +2793 -0.48876953125 +2794 -0.6416015625 +2795 -0.751373291015625 +2796 -0.84619140625 +2797 -0.861297607421875 +2798 -0.863250732421875 +2799 -0.856597900390625 +2800 -0.7498779296875 +2801 -0.624542236328125 +2802 -0.47808837890625 +2803 -0.253387451171875 +2804 0.003692626953125 +2805 0.2257080078125 +2806 0.427154541015625 +2807 0.643218994140625 +2808 0.855926513671875 +2809 0.870361328125 +2810 0.870361328125 +2811 0.862762451171875 +2812 0.79669189453125 +2813 0.595794677734375 +2814 0.362152099609375 +2815 0.1270751953125 +2816 -0.086944580078125 +2817 -0.2784423828125 +2818 -0.484832763671875 +2819 -0.729583740234375 +2820 -0.86688232421875 +2821 -0.870391845703125 +2822 -0.86859130859375 +2823 -0.86279296875 +2824 -0.817962646484375 +2825 -0.6116943359375 +2826 -0.3128662109375 +2827 0.039398193359375 +2828 0.422821044921875 +2829 0.805145263671875 +2830 0.870361328125 +2831 0.870361328125 +2832 0.860015869140625 +2833 0.727935791015625 +2834 0.48114013671875 +2835 0.2059326171875 +2836 -0.06103515625 +2837 -0.29913330078125 +2838 -0.516204833984375 +2839 -0.7252197265625 +2840 -0.85980224609375 +2841 -0.870391845703125 +2842 -0.870391845703125 +2843 -0.858062744140625 +2844 -0.673004150390625 +2845 -0.42694091796875 +2846 -0.2100830078125 +2847 -0.0362548828125 +2848 0.10943603515625 +2849 0.23516845703125 +2850 0.373687744140625 +2851 0.517791748046875 +2852 0.602783203125 +2853 0.635711669921875 +2854 0.655181884765625 +2855 0.65948486328125 +2856 0.651275634765625 +2857 0.61846923828125 +2858 0.53753662109375 +2859 0.404144287109375 +2860 0.22186279296875 +2861 0.003997802734375 +2862 -0.22100830078125 +2863 -0.42449951171875 +2864 -0.579833984375 +2865 -0.641876220703125 +2866 -0.6177978515625 +2867 -0.575531005859375 +2868 -0.526336669921875 +2869 -0.42645263671875 +2870 -0.2581787109375 +2871 -0.068695068359375 +2872 0.09222412109375 +2873 0.232147216796875 +2874 0.3509521484375 +2875 0.410064697265625 +2876 0.372955322265625 +2877 0.2554931640625 +2878 0.10711669921875 +2879 -0.052886962890625 +2880 -0.186279296875 +2881 -0.23291015625 +2882 -0.209442138671875 +2883 -0.174163818359375 +2884 -0.126739501953125 +2885 -0.048126220703125 +2886 0.0426025390625 +2887 0.10748291015625 +2888 0.1409912109375 +2889 0.19708251953125 +2890 0.273651123046875 +2891 0.31768798828125 +2892 0.341094970703125 +2893 0.368011474609375 +2894 0.37249755859375 +2895 0.30072021484375 +2896 0.1517333984375 +2897 -0.01470947265625 +2898 -0.1883544921875 +2899 -0.372711181640625 +2900 -0.51397705078125 +2901 -0.57177734375 +2902 -0.53948974609375 +2903 -0.43511962890625 +2904 -0.2962646484375 +2905 -0.161102294921875 +2906 -0.0435791015625 +2907 0.060394287109375 +2908 0.13665771484375 +2909 0.170135498046875 +2910 0.16552734375 +2911 0.15728759765625 +2912 0.150787353515625 +2913 0.12200927734375 +2914 0.080108642578125 +2915 0.05126953125 +2916 0.062896728515625 +2917 0.09271240234375 +2918 0.092987060546875 +2919 0.07855224609375 +2920 0.06427001953125 +2921 0.0347900390625 +2922 -0.01171875 +2923 -0.056060791015625 +2924 -0.055511474609375 +2925 -0.010467529296875 +2926 0.02508544921875 +2927 0.025665283203125 +2928 0.017333984375 +2929 0.00189208984375 +2930 -0.03173828125 +2931 -0.071502685546875 +2932 -0.13543701171875 +2933 -0.219970703125 +2934 -0.300506591796875 +2935 -0.376312255859375 +2936 -0.416107177734375 +2937 -0.371124267578125 +2938 -0.242279052734375 +2939 -0.069732666015625 +2940 0.125640869140625 +2941 0.31268310546875 +2942 0.45501708984375 +2943 0.554779052734375 +2944 0.61065673828125 +2945 0.610931396484375 +2946 0.531463623046875 +2947 0.3883056640625 +2948 0.23468017578125 +2949 0.095245361328125 +2950 -0.00396728515625 +2951 -0.04852294921875 +2952 -0.055145263671875 +2953 -0.0758056640625 +2954 -0.138702392578125 +2955 -0.209197998046875 +2956 -0.289031982421875 +2957 -0.37884521484375 +2958 -0.456329345703125 +2959 -0.51641845703125 +2960 -0.519287109375 +2961 -0.458251953125 +2962 -0.384796142578125 +2963 -0.323699951171875 +2964 -0.269287109375 +2965 -0.1951904296875 +2966 -0.100006103515625 +2967 -0.01055908203125 +2968 0.1033935546875 +2969 0.24908447265625 +2970 0.373199462890625 +2971 0.45806884765625 +2972 0.511474609375 +2973 0.565399169921875 +2974 0.61138916015625 +2975 0.5897216796875 +2976 0.4906005859375 +2977 0.33148193359375 +2978 0.147796630859375 +2979 -0.01873779296875 +2980 -0.140289306640625 +2981 -0.191986083984375 +2982 -0.184295654296875 +2983 -0.161834716796875 +2984 -0.166595458984375 +2985 -0.19390869140625 +2986 -0.22442626953125 +2987 -0.279754638671875 +2988 -0.3389892578125 +2989 -0.3543701171875 +2990 -0.348175048828125 +2991 -0.32598876953125 +2992 -0.2581787109375 +2993 -0.139801025390625 +2994 0.014617919921875 +2995 0.144378662109375 +2996 0.221038818359375 +2997 0.27069091796875 +2998 0.294036865234375 +2999 0.311767578125 +3000 0.339141845703125 +3001 0.360260009765625 +3002 0.360504150390625 +3003 0.308380126953125 +3004 0.18170166015625 +3005 0.0047607421875 +3006 -0.17559814453125 +3007 -0.3143310546875 +3008 -0.36785888671875 +3009 -0.36248779296875 +3010 -0.343536376953125 +3011 -0.3018798828125 +3012 -0.231414794921875 +3013 -0.117645263671875 +3014 0.007049560546875 +3015 0.087982177734375 +3016 0.13946533203125 +3017 0.17425537109375 +3018 0.188201904296875 +3019 0.171234130859375 +3020 0.118438720703125 +3021 0.05706787109375 +3022 -0.010711669921875 +3023 -0.0914306640625 +3024 -0.162322998046875 +3025 -0.194549560546875 +3026 -0.1492919921875 +3027 -0.02166748046875 +3028 0.124053955078125 +3029 0.211151123046875 +3030 0.240447998046875 +3031 0.242218017578125 +3032 0.2257080078125 +3033 0.194366455078125 +3034 0.115509033203125 +3035 0.0128173828125 +3036 -0.053802490234375 +3037 -0.110626220703125 +3038 -0.199493408203125 +3039 -0.29437255859375 +3040 -0.33221435546875 +3041 -0.27972412109375 +3042 -0.185333251953125 +3043 -0.128204345703125 +3044 -0.115692138671875 +3045 -0.116455078125 +3046 -0.105926513671875 +3047 -0.053955078125 +3048 0.048797607421875 +3049 0.157318115234375 +3050 0.212005615234375 +3051 0.218475341796875 +3052 0.23724365234375 +3053 0.30535888671875 +3054 0.38128662109375 +3055 0.404449462890625 +3056 0.3944091796875 +3057 0.3885498046875 +3058 0.362640380859375 +3059 0.27362060546875 +3060 0.11712646484375 +3061 -0.054901123046875 +3062 -0.19085693359375 +3063 -0.28570556640625 +3064 -0.339263916015625 +3065 -0.3775634765625 +3066 -0.445709228515625 +3067 -0.535064697265625 +3068 -0.629058837890625 +3069 -0.697601318359375 +3070 -0.70391845703125 +3071 -0.6424560546875 +3072 -0.491241455078125 +3073 -0.265716552734375 +3074 -0.023712158203125 +3075 0.201751708984375 +3076 0.375823974609375 +3077 0.485076904296875 +3078 0.56884765625 +3079 0.634765625 +3080 0.63763427734375 +3081 0.5660400390625 +3082 0.4720458984375 +3083 0.40692138671875 +3084 0.3778076171875 +3085 0.376953125 +3086 0.371978759765625 +3087 0.313140869140625 +3088 0.184417724609375 +3089 0.011199951171875 +3090 -0.171051025390625 +3091 -0.33740234375 +3092 -0.47198486328125 +3093 -0.560394287109375 +3094 -0.58056640625 +3095 -0.54754638671875 +3096 -0.508575439453125 +3097 -0.459503173828125 +3098 -0.394378662109375 +3099 -0.35260009765625 +3100 -0.31170654296875 +3101 -0.197418212890625 +3102 -0.007965087890625 +3103 0.207489013671875 +3104 0.409210205078125 +3105 0.57208251953125 +3106 0.66595458984375 +3107 0.65875244140625 +3108 0.56744384765625 +3109 0.431396484375 +3110 0.29443359375 +3111 0.182464599609375 +3112 0.06365966796875 +3113 -0.075958251953125 +3114 -0.189422607421875 +3115 -0.271942138671875 +3116 -0.342529296875 +3117 -0.364166259765625 +3118 -0.327239990234375 +3119 -0.2769775390625 +3120 -0.253692626953125 +3121 -0.24365234375 +3122 -0.1983642578125 +3123 -0.116241455078125 +3124 -0.036834716796875 +3125 0.034881591796875 +3126 0.09124755859375 +3127 0.10888671875 +3128 0.125518798828125 +3129 0.15771484375 +3130 0.17828369140625 +3131 0.17108154296875 +3132 0.129974365234375 +3133 0.082427978515625 +3134 0.027679443359375 +3135 -0.065643310546875 +3136 -0.15936279296875 +3137 -0.21307373046875 +3138 -0.234649658203125 +3139 -0.2001953125 +3140 -0.119171142578125 +3141 -0.024749755859375 +3142 0.085784912109375 +3143 0.178131103515625 +3144 0.215576171875 +3145 0.211456298828125 +3146 0.17523193359375 +3147 0.128753662109375 +3148 0.1019287109375 +3149 0.0743408203125 +3150 0.04327392578125 +3151 0.038177490234375 +3152 0.076263427734375 +3153 0.14105224609375 +3154 0.186431884765625 +3155 0.188812255859375 +3156 0.1390380859375 +3157 0.041778564453125 +3158 -0.079437255859375 +3159 -0.219390869140625 +3160 -0.367828369140625 +3161 -0.494873046875 +3162 -0.556243896484375 +3163 -0.508697509765625 +3164 -0.3756103515625 +3165 -0.218902587890625 +3166 -0.063751220703125 +3167 0.091552734375 +3168 0.23602294921875 +3169 0.342987060546875 +3170 0.39520263671875 +3171 0.389373779296875 +3172 0.324249267578125 +3173 0.224090576171875 +3174 0.124267578125 +3175 0.037078857421875 +3176 -0.010101318359375 +3177 -0.019439697265625 +3178 -0.022796630859375 +3179 -0.001556396484375 +3180 0.056304931640625 +3181 0.106719970703125 +3182 0.096893310546875 +3183 0.042694091796875 +3184 -0.018035888671875 +3185 -0.07586669921875 +3186 -0.11944580078125 +3187 -0.15972900390625 +3188 -0.202606201171875 +3189 -0.24859619140625 +3190 -0.30517578125 +3191 -0.36212158203125 +3192 -0.39141845703125 +3193 -0.35528564453125 +3194 -0.249969482421875 +3195 -0.092864990234375 +3196 0.08905029296875 +3197 0.2352294921875 +3198 0.318817138671875 +3199 0.358642578125 +3200 0.347747802734375 +3201 0.28564453125 +3202 0.223175048828125 +3203 0.196746826171875 +3204 0.179840087890625 +3205 0.155548095703125 +3206 0.151214599609375 +3207 0.156951904296875 +3208 0.13177490234375 +3209 0.100799560546875 +3210 0.087127685546875 +3211 0.05487060546875 +3212 -0.009002685546875 +3213 -0.10400390625 +3214 -0.229400634765625 +3215 -0.35552978515625 +3216 -0.441925048828125 +3217 -0.473846435546875 +3218 -0.464813232421875 +3219 -0.419097900390625 +3220 -0.334320068359375 +3221 -0.227935791015625 +3222 -0.12347412109375 +3223 -0.02764892578125 +3224 0.077667236328125 +3225 0.2132568359375 +3226 0.38885498046875 +3227 0.582794189453125 +3228 0.734039306640625 +3229 0.800140380859375 +3230 0.7783203125 +3231 0.6651611328125 +3232 0.45965576171875 +3233 0.199188232421875 +3234 -0.050689697265625 +3235 -0.23297119140625 +3236 -0.33013916015625 +3237 -0.368408203125 +3238 -0.378936767578125 +3239 -0.376983642578125 +3240 -0.37969970703125 +3241 -0.391510009765625 +3242 -0.385345458984375 +3243 -0.3419189453125 +3244 -0.28289794921875 +3245 -0.251617431640625 +3246 -0.266143798828125 +3247 -0.273345947265625 +3248 -0.216796875 +3249 -0.128265380859375 +3250 -0.068145751953125 +3251 -0.0430908203125 +3252 -0.024444580078125 +3253 0.020721435546875 +3254 0.124481201171875 +3255 0.25787353515625 +3256 0.379119873046875 +3257 0.47991943359375 +3258 0.5281982421875 +3259 0.511138916015625 +3260 0.456207275390625 +3261 0.407470703125 +3262 0.383758544921875 +3263 0.35687255859375 +3264 0.31182861328125 +3265 0.250885009765625 +3266 0.1654052734375 +3267 0.035247802734375 +3268 -0.142059326171875 +3269 -0.33563232421875 +3270 -0.5345458984375 +3271 -0.72186279296875 +3272 -0.836669921875 +3273 -0.8326416015625 +3274 -0.7296142578125 +3275 -0.582550048828125 +3276 -0.440093994140625 +3277 -0.324310302734375 +3278 -0.20147705078125 +3279 -0.044647216796875 +3280 0.103973388671875 +3281 0.202392578125 +3282 0.264495849609375 +3283 0.338897705078125 +3284 0.443817138671875 +3285 0.545074462890625 +3286 0.6173095703125 +3287 0.6524658203125 +3288 0.66339111328125 +3289 0.6561279296875 +3290 0.606781005859375 +3291 0.501190185546875 +3292 0.352783203125 +3293 0.176544189453125 +3294 -0.034820556640625 +3295 -0.258209228515625 +3296 -0.44244384765625 +3297 -0.5753173828125 +3298 -0.65203857421875 +3299 -0.641632080078125 +3300 -0.562164306640625 +3301 -0.458038330078125 +3302 -0.350555419921875 +3303 -0.260528564453125 +3304 -0.192108154296875 +3305 -0.141937255859375 +3306 -0.1021728515625 +3307 -0.062896728515625 +3308 -0.011932373046875 +3309 0.062835693359375 +3310 0.148712158203125 +3311 0.241729736328125 +3312 0.34912109375 +3313 0.457305908203125 +3314 0.54388427734375 +3315 0.5728759765625 +3316 0.506591796875 +3317 0.351226806640625 +3318 0.146514892578125 +3319 -0.05523681640625 +3320 -0.21624755859375 +3321 -0.334930419921875 +3322 -0.402984619140625 +3323 -0.4412841796875 +3324 -0.49578857421875 +3325 -0.5601806640625 +3326 -0.600738525390625 +3327 -0.584228515625 +3328 -0.47930908203125 +3329 -0.27935791015625 +3330 -0.0089111328125 +3331 0.268798828125 +3332 0.482818603515625 +3333 0.60369873046875 +3334 0.650421142578125 +3335 0.66400146484375 +3336 0.6414794921875 +3337 0.572540283203125 +3338 0.498138427734375 +3339 0.439453125 +3340 0.375518798828125 +3341 0.274505615234375 +3342 0.1087646484375 +3343 -0.099395751953125 +3344 -0.3182373046875 +3345 -0.5489501953125 +3346 -0.7738037109375 +3347 -0.86383056640625 +3348 -0.870391845703125 +3349 -0.86895751953125 +3350 -0.861053466796875 +3351 -0.765869140625 +3352 -0.5301513671875 +3353 -0.214691162109375 +3354 0.137359619140625 +3355 0.474822998046875 +3356 0.76239013671875 +3357 0.867462158203125 +3358 0.870361328125 +3359 0.86480712890625 +3360 0.831817626953125 +3361 0.677581787109375 +3362 0.495880126953125 +3363 0.30767822265625 +3364 0.116180419921875 +3365 -0.110748291015625 +3366 -0.381805419921875 +3367 -0.6572265625 +3368 -0.857421875 +3369 -0.870391845703125 +3370 -0.870391845703125 +3371 -0.86444091796875 +3372 -0.85723876953125 +3373 -0.790008544921875 +3374 -0.62847900390625 +3375 -0.3956298828125 +3376 -0.126708984375 +3377 0.150115966796875 +3378 0.424041748046875 +3379 0.670623779296875 +3380 0.854522705078125 +3381 0.866485595703125 +3382 0.86920166015625 +3383 0.8653564453125 +3384 0.857147216796875 +3385 0.766845703125 +3386 0.628509521484375 +3387 0.462127685546875 +3388 0.297210693359375 +3389 0.14862060546875 +3390 -0.00537109375 +3391 -0.15753173828125 +3392 -0.31304931640625 +3393 -0.48876953125 +3394 -0.6416015625 +3395 -0.751373291015625 +3396 -0.84619140625 +3397 -0.861297607421875 +3398 -0.863250732421875 +3399 -0.856597900390625 +3400 -0.7498779296875 +3401 -0.624542236328125 +3402 -0.47808837890625 +3403 -0.253387451171875 +3404 0.003692626953125 +3405 0.2257080078125 +3406 0.427154541015625 +3407 0.643218994140625 +3408 0.855926513671875 +3409 0.870361328125 +3410 0.870361328125 +3411 0.862762451171875 +3412 0.79669189453125 +3413 0.595794677734375 +3414 0.362152099609375 +3415 0.1270751953125 +3416 -0.086944580078125 +3417 -0.2784423828125 +3418 -0.484832763671875 +3419 -0.729583740234375 +3420 -0.86688232421875 +3421 -0.870391845703125 +3422 -0.86859130859375 +3423 -0.86279296875 +3424 -0.817962646484375 +3425 -0.6116943359375 +3426 -0.3128662109375 +3427 0.039398193359375 +3428 0.422821044921875 +3429 0.805145263671875 +3430 0.870361328125 +3431 0.870361328125 +3432 0.860015869140625 +3433 0.727935791015625 +3434 0.48114013671875 +3435 0.2059326171875 +3436 -0.06103515625 +3437 -0.29913330078125 +3438 -0.516204833984375 +3439 -0.7252197265625 +3440 -0.85980224609375 +3441 -0.870391845703125 +3442 -0.870391845703125 +3443 -0.858062744140625 +3444 -0.673004150390625 +3445 -0.42694091796875 +3446 -0.2100830078125 +3447 -0.0362548828125 +3448 0.10943603515625 +3449 0.23516845703125 +3450 0.373687744140625 +3451 0.517791748046875 +3452 0.602783203125 +3453 0.635711669921875 +3454 0.655181884765625 +3455 0.65948486328125 +3456 0.651275634765625 +3457 0.61846923828125 +3458 0.53753662109375 +3459 0.404144287109375 +3460 0.22186279296875 +3461 0.003997802734375 +3462 -0.22100830078125 +3463 -0.42449951171875 +3464 -0.579833984375 +3465 -0.641876220703125 +3466 -0.6177978515625 +3467 -0.575531005859375 +3468 -0.526336669921875 +3469 -0.42645263671875 +3470 -0.2581787109375 +3471 -0.068695068359375 +3472 0.09222412109375 +3473 0.232147216796875 +3474 0.3509521484375 +3475 0.410064697265625 +3476 0.372955322265625 +3477 0.2554931640625 +3478 0.10711669921875 +3479 -0.052886962890625 +3480 -0.186279296875 +3481 -0.23291015625 +3482 -0.209442138671875 +3483 -0.174163818359375 +3484 -0.126739501953125 +3485 -0.048126220703125 +3486 0.0426025390625 +3487 0.10748291015625 +3488 0.1409912109375 +3489 0.19708251953125 +3490 0.273651123046875 +3491 0.31768798828125 +3492 0.341094970703125 +3493 0.368011474609375 +3494 0.37249755859375 +3495 0.30072021484375 +3496 0.1517333984375 +3497 -0.01470947265625 +3498 -0.1883544921875 +3499 -0.372711181640625 +3500 -0.51397705078125 +3501 -0.57177734375 +3502 -0.53948974609375 +3503 -0.43511962890625 +3504 -0.2962646484375 +3505 -0.161102294921875 +3506 -0.0435791015625 +3507 0.060394287109375 +3508 0.13665771484375 +3509 0.170135498046875 +3510 0.16552734375 +3511 0.15728759765625 +3512 0.150787353515625 +3513 0.12200927734375 +3514 0.080108642578125 +3515 0.05126953125 +3516 0.062896728515625 +3517 0.09271240234375 +3518 0.092987060546875 +3519 0.07855224609375 +3520 0.06427001953125 +3521 0.0347900390625 +3522 -0.01171875 +3523 -0.056060791015625 +3524 -0.055511474609375 +3525 -0.010467529296875 +3526 0.02508544921875 +3527 0.025665283203125 +3528 0.017333984375 +3529 0.00189208984375 +3530 -0.03173828125 +3531 -0.071502685546875 +3532 -0.13543701171875 +3533 -0.219970703125 +3534 -0.300506591796875 +3535 -0.376312255859375 +3536 -0.416107177734375 +3537 -0.371124267578125 +3538 -0.242279052734375 +3539 -0.069732666015625 +3540 0.125640869140625 +3541 0.31268310546875 +3542 0.45501708984375 +3543 0.554779052734375 +3544 0.61065673828125 +3545 0.610931396484375 +3546 0.531463623046875 +3547 0.3883056640625 +3548 0.23468017578125 +3549 0.095245361328125 +3550 -0.00396728515625 +3551 -0.04852294921875 +3552 -0.055145263671875 +3553 -0.0758056640625 +3554 -0.138702392578125 +3555 -0.209197998046875 +3556 -0.289031982421875 +3557 -0.37884521484375 +3558 -0.456329345703125 +3559 -0.51641845703125 +3560 -0.519287109375 +3561 -0.458251953125 +3562 -0.384796142578125 +3563 -0.323699951171875 +3564 -0.269287109375 +3565 -0.1951904296875 +3566 -0.100006103515625 +3567 -0.01055908203125 +3568 0.1033935546875 +3569 0.24908447265625 +3570 0.373199462890625 +3571 0.45806884765625 +3572 0.511474609375 +3573 0.565399169921875 +3574 0.61138916015625 +3575 0.5897216796875 +3576 0.4906005859375 +3577 0.33148193359375 +3578 0.147796630859375 +3579 -0.01873779296875 +3580 -0.140289306640625 +3581 -0.191986083984375 +3582 -0.184295654296875 +3583 -0.161834716796875 +3584 -0.166595458984375 +3585 -0.19390869140625 +3586 -0.22442626953125 +3587 -0.279754638671875 +3588 -0.3389892578125 +3589 -0.3543701171875 +3590 -0.348175048828125 +3591 -0.32598876953125 +3592 -0.2581787109375 +3593 -0.139801025390625 +3594 0.014617919921875 +3595 0.144378662109375 +3596 0.221038818359375 +3597 0.27069091796875 +3598 0.294036865234375 +3599 0.311767578125 +3600 0.339141845703125 +3601 0.360260009765625 +3602 0.360504150390625 +3603 0.308380126953125 +3604 0.18170166015625 +3605 0.0047607421875 +3606 -0.17559814453125 +3607 -0.3143310546875 +3608 -0.36785888671875 +3609 -0.36248779296875 +3610 -0.343536376953125 +3611 -0.3018798828125 +3612 -0.231414794921875 +3613 -0.117645263671875 +3614 0.007049560546875 +3615 0.087982177734375 +3616 0.13946533203125 +3617 0.17425537109375 +3618 0.188201904296875 +3619 0.171234130859375 +3620 0.118438720703125 +3621 0.05706787109375 +3622 -0.010711669921875 +3623 -0.0914306640625 +3624 -0.162322998046875 +3625 -0.194549560546875 +3626 -0.1492919921875 +3627 -0.02166748046875 +3628 0.124053955078125 +3629 0.211151123046875 +3630 0.240447998046875 +3631 0.242218017578125 +3632 0.2257080078125 +3633 0.194366455078125 +3634 0.115509033203125 +3635 0.0128173828125 +3636 -0.053802490234375 +3637 -0.110626220703125 +3638 -0.199493408203125 +3639 -0.29437255859375 +3640 -0.33221435546875 +3641 -0.27972412109375 +3642 -0.185333251953125 +3643 -0.128204345703125 +3644 -0.115692138671875 +3645 -0.116455078125 +3646 -0.105926513671875 +3647 -0.053955078125 +3648 0.048797607421875 +3649 0.157318115234375 +3650 0.212005615234375 +3651 0.218475341796875 +3652 0.23724365234375 +3653 0.30535888671875 +3654 0.38128662109375 +3655 0.404449462890625 +3656 0.3944091796875 +3657 0.3885498046875 +3658 0.362640380859375 +3659 0.27362060546875 +3660 0.11712646484375 +3661 -0.054901123046875 +3662 -0.19085693359375 +3663 -0.28570556640625 +3664 -0.339263916015625 +3665 -0.3775634765625 +3666 -0.445709228515625 +3667 -0.535064697265625 +3668 -0.629058837890625 +3669 -0.697601318359375 +3670 -0.70391845703125 +3671 -0.6424560546875 +3672 -0.491241455078125 +3673 -0.265716552734375 +3674 -0.023712158203125 +3675 0.201751708984375 +3676 0.375823974609375 +3677 0.485076904296875 +3678 0.56884765625 +3679 0.634765625 +3680 0.63763427734375 +3681 0.5660400390625 +3682 0.4720458984375 +3683 0.40692138671875 +3684 0.3778076171875 +3685 0.376953125 +3686 0.371978759765625 +3687 0.313140869140625 +3688 0.184417724609375 +3689 0.011199951171875 +3690 -0.171051025390625 +3691 -0.33740234375 +3692 -0.47198486328125 +3693 -0.560394287109375 +3694 -0.58056640625 +3695 -0.54754638671875 +3696 -0.508575439453125 +3697 -0.459503173828125 +3698 -0.394378662109375 +3699 -0.35260009765625 +3700 -0.31170654296875 +3701 -0.197418212890625 +3702 -0.007965087890625 +3703 0.207489013671875 +3704 0.409210205078125 +3705 0.57208251953125 +3706 0.66595458984375 +3707 0.65875244140625 +3708 0.56744384765625 +3709 0.431396484375 +3710 0.29443359375 +3711 0.182464599609375 +3712 0.06365966796875 +3713 -0.075958251953125 +3714 -0.189422607421875 +3715 -0.271942138671875 +3716 -0.342529296875 +3717 -0.364166259765625 +3718 -0.327239990234375 +3719 -0.2769775390625 +3720 -0.253692626953125 +3721 -0.24365234375 +3722 -0.1983642578125 +3723 -0.116241455078125 +3724 -0.036834716796875 +3725 0.034881591796875 +3726 0.09124755859375 +3727 0.10888671875 +3728 0.125518798828125 +3729 0.15771484375 +3730 0.17828369140625 +3731 0.17108154296875 +3732 0.129974365234375 +3733 0.082427978515625 +3734 0.027679443359375 +3735 -0.065643310546875 +3736 -0.15936279296875 +3737 -0.21307373046875 +3738 -0.234649658203125 +3739 -0.2001953125 +3740 -0.119171142578125 +3741 -0.024749755859375 +3742 0.085784912109375 +3743 0.178131103515625 +3744 0.215576171875 +3745 0.211456298828125 +3746 0.17523193359375 +3747 0.128753662109375 +3748 0.1019287109375 +3749 0.0743408203125 +3750 0.04327392578125 +3751 0.038177490234375 +3752 0.076263427734375 +3753 0.14105224609375 +3754 0.186431884765625 +3755 0.188812255859375 +3756 0.1390380859375 +3757 0.041778564453125 +3758 -0.079437255859375 +3759 -0.219390869140625 +3760 -0.367828369140625 +3761 -0.494873046875 +3762 -0.556243896484375 +3763 -0.508697509765625 +3764 -0.3756103515625 +3765 -0.218902587890625 +3766 -0.063751220703125 +3767 0.091552734375 +3768 0.23602294921875 +3769 0.342987060546875 +3770 0.39520263671875 +3771 0.389373779296875 +3772 0.324249267578125 +3773 0.224090576171875 +3774 0.124267578125 +3775 0.037078857421875 +3776 -0.010101318359375 +3777 -0.019439697265625 +3778 -0.022796630859375 +3779 -0.001556396484375 +3780 0.056304931640625 +3781 0.106719970703125 +3782 0.096893310546875 +3783 0.042694091796875 +3784 -0.018035888671875 +3785 -0.07586669921875 +3786 -0.11944580078125 +3787 -0.15972900390625 +3788 -0.202606201171875 +3789 -0.24859619140625 +3790 -0.30517578125 +3791 -0.36212158203125 +3792 -0.39141845703125 +3793 -0.35528564453125 +3794 -0.249969482421875 +3795 -0.092864990234375 +3796 0.08905029296875 +3797 0.2352294921875 +3798 0.318817138671875 +3799 0.358642578125 +3800 0.347747802734375 +3801 0.28564453125 +3802 0.223175048828125 +3803 0.196746826171875 +3804 0.179840087890625 +3805 0.155548095703125 +3806 0.151214599609375 +3807 0.156951904296875 +3808 0.13177490234375 +3809 0.100799560546875 +3810 0.087127685546875 +3811 0.05487060546875 +3812 -0.009002685546875 +3813 -0.10400390625 +3814 -0.229400634765625 +3815 -0.35552978515625 +3816 -0.441925048828125 +3817 -0.473846435546875 +3818 -0.464813232421875 +3819 -0.419097900390625 +3820 -0.334320068359375 +3821 -0.227935791015625 +3822 -0.12347412109375 +3823 -0.02764892578125 +3824 0.077667236328125 +3825 0.2132568359375 +3826 0.38885498046875 +3827 0.582794189453125 +3828 0.734039306640625 +3829 0.800140380859375 +3830 0.7783203125 +3831 0.6651611328125 +3832 0.45965576171875 +3833 0.199188232421875 +3834 -0.050689697265625 +3835 -0.23297119140625 +3836 -0.33013916015625 +3837 -0.368408203125 +3838 -0.378936767578125 +3839 -0.376983642578125 +3840 -0.37969970703125 +3841 -0.391510009765625 +3842 -0.385345458984375 +3843 -0.3419189453125 +3844 -0.28289794921875 +3845 -0.251617431640625 +3846 -0.266143798828125 +3847 -0.273345947265625 +3848 -0.216796875 +3849 -0.128265380859375 +3850 -0.068145751953125 +3851 -0.0430908203125 +3852 -0.024444580078125 +3853 0.020721435546875 +3854 0.124481201171875 +3855 0.25787353515625 +3856 0.379119873046875 +3857 0.47991943359375 +3858 0.5281982421875 +3859 0.511138916015625 +3860 0.456207275390625 +3861 0.407470703125 +3862 0.383758544921875 +3863 0.35687255859375 +3864 0.31182861328125 +3865 0.250885009765625 +3866 0.1654052734375 +3867 0.035247802734375 +3868 -0.142059326171875 +3869 -0.33563232421875 +3870 -0.5345458984375 +3871 -0.72186279296875 +3872 -0.836669921875 +3873 -0.8326416015625 +3874 -0.7296142578125 +3875 -0.582550048828125 +3876 -0.440093994140625 +3877 -0.324310302734375 +3878 -0.20147705078125 +3879 -0.044647216796875 +3880 0.103973388671875 +3881 0.202392578125 +3882 0.264495849609375 +3883 0.338897705078125 +3884 0.443817138671875 +3885 0.545074462890625 +3886 0.6173095703125 +3887 0.6524658203125 +3888 0.66339111328125 +3889 0.6561279296875 +3890 0.606781005859375 +3891 0.501190185546875 +3892 0.352783203125 +3893 0.176544189453125 +3894 -0.034820556640625 +3895 -0.258209228515625 +3896 -0.44244384765625 +3897 -0.5753173828125 +3898 -0.65203857421875 +3899 -0.641632080078125 +3900 -0.562164306640625 +3901 -0.458038330078125 +3902 -0.350555419921875 +3903 -0.260528564453125 +3904 -0.192108154296875 +3905 -0.141937255859375 +3906 -0.1021728515625 +3907 -0.062896728515625 +3908 -0.011932373046875 +3909 0.062835693359375 +3910 0.148712158203125 +3911 0.241729736328125 +3912 0.34912109375 +3913 0.457305908203125 +3914 0.54388427734375 +3915 0.5728759765625 +3916 0.506591796875 +3917 0.351226806640625 +3918 0.146514892578125 +3919 -0.05523681640625 +3920 -0.21624755859375 +3921 -0.334930419921875 +3922 -0.402984619140625 +3923 -0.4412841796875 +3924 -0.49578857421875 +3925 -0.5601806640625 +3926 -0.600738525390625 +3927 -0.584228515625 +3928 -0.47930908203125 +3929 -0.27935791015625 +3930 -0.0089111328125 +3931 0.268798828125 +3932 0.482818603515625 +3933 0.60369873046875 +3934 0.650421142578125 +3935 0.66400146484375 +3936 0.6414794921875 +3937 0.572540283203125 +3938 0.498138427734375 +3939 0.439453125 +3940 0.375518798828125 +3941 0.274505615234375 +3942 0.1087646484375 +3943 -0.099395751953125 +3944 -0.3182373046875 +3945 -0.5489501953125 +3946 -0.7738037109375 +3947 -0.86383056640625 +3948 -0.870391845703125 +3949 -0.86895751953125 +3950 -0.861053466796875 +3951 -0.765869140625 +3952 -0.5301513671875 +3953 -0.214691162109375 +3954 0.137359619140625 +3955 0.474822998046875 +3956 0.76239013671875 +3957 0.867462158203125 +3958 0.870361328125 +3959 0.86480712890625 +3960 0.831817626953125 +3961 0.677581787109375 +3962 0.495880126953125 +3963 0.30767822265625 +3964 0.116180419921875 +3965 -0.110748291015625 +3966 -0.381805419921875 +3967 -0.6572265625 +3968 -0.857421875 +3969 -0.870391845703125 +3970 -0.870391845703125 +3971 -0.86444091796875 +3972 -0.85723876953125 +3973 -0.790008544921875 +3974 -0.62847900390625 +3975 -0.3956298828125 +3976 -0.126708984375 +3977 0.150115966796875 +3978 0.424041748046875 +3979 0.670623779296875 +3980 0.854522705078125 +3981 0.866485595703125 +3982 0.86920166015625 +3983 0.8653564453125 +3984 0.857147216796875 +3985 0.766845703125 +3986 0.628509521484375 +3987 0.462127685546875 +3988 0.297210693359375 +3989 0.14862060546875 +3990 -0.00537109375 +3991 -0.15753173828125 +3992 -0.31304931640625 +3993 -0.48876953125 +3994 -0.6416015625 +3995 -0.751373291015625 +3996 -0.84619140625 +3997 -0.861297607421875 +3998 -0.863250732421875 +3999 -0.856597900390625 +4000 -0.7498779296875 +4001 -0.624542236328125 +4002 -0.47808837890625 +4003 -0.253387451171875 +4004 0.003692626953125 +4005 0.2257080078125 +4006 0.427154541015625 +4007 0.643218994140625 +4008 0.855926513671875 +4009 0.870361328125 +4010 0.870361328125 +4011 0.862762451171875 +4012 0.79669189453125 +4013 0.595794677734375 +4014 0.362152099609375 +4015 0.1270751953125 +4016 -0.086944580078125 +4017 -0.2784423828125 +4018 -0.484832763671875 +4019 -0.729583740234375 +4020 -0.86688232421875 +4021 -0.870391845703125 +4022 -0.86859130859375 +4023 -0.86279296875 +4024 -0.817962646484375 +4025 -0.6116943359375 +4026 -0.3128662109375 +4027 0.039398193359375 +4028 0.422821044921875 +4029 0.805145263671875 +4030 0.870361328125 +4031 0.870361328125 +4032 0.860015869140625 +4033 0.727935791015625 +4034 0.48114013671875 +4035 0.2059326171875 +4036 -0.06103515625 +4037 -0.29913330078125 +4038 -0.516204833984375 +4039 -0.7252197265625 +4040 -0.85980224609375 +4041 -0.870391845703125 +4042 -0.870391845703125 +4043 -0.858062744140625 +4044 -0.673004150390625 +4045 -0.42694091796875 +4046 -0.2100830078125 +4047 -0.0362548828125 +4048 0.10943603515625 +4049 0.23516845703125 +4050 0.373687744140625 +4051 0.517791748046875 +4052 0.602783203125 +4053 0.635711669921875 +4054 0.655181884765625 +4055 0.65948486328125 +4056 0.651275634765625 +4057 0.61846923828125 +4058 0.53753662109375 +4059 0.404144287109375 +4060 0.22186279296875 +4061 0.003997802734375 +4062 -0.22100830078125 +4063 -0.42449951171875 +4064 -0.579833984375 +4065 -0.641876220703125 +4066 -0.6177978515625 +4067 -0.575531005859375 +4068 -0.526336669921875 +4069 -0.42645263671875 +4070 -0.2581787109375 +4071 -0.068695068359375 +4072 0.09222412109375 +4073 0.232147216796875 +4074 0.3509521484375 +4075 0.410064697265625 +4076 0.372955322265625 +4077 0.2554931640625 +4078 0.10711669921875 +4079 -0.052886962890625 +4080 -0.186279296875 +4081 -0.23291015625 +4082 -0.209442138671875 +4083 -0.174163818359375 +4084 -0.126739501953125 +4085 -0.048126220703125 +4086 0.0426025390625 +4087 0.10748291015625 +4088 0.1409912109375 +4089 0.19708251953125 +4090 0.273651123046875 +4091 0.31768798828125 +4092 0.341094970703125 +4093 0.368011474609375 +4094 0.37249755859375 +4095 0.30072021484375 +4096 0.1517333984375 +4097 -0.01470947265625 +4098 -0.1883544921875 +4099 -0.372711181640625 +4100 -0.51397705078125 +4101 -0.57177734375 +4102 -0.53948974609375 +4103 -0.43511962890625 +4104 -0.2962646484375 +4105 -0.161102294921875 +4106 -0.0435791015625 +4107 0.060394287109375 +4108 0.13665771484375 +4109 0.170135498046875 +4110 0.16552734375 +4111 0.15728759765625 +4112 0.150787353515625 +4113 0.12200927734375 +4114 0.080108642578125 +4115 0.05126953125 +4116 0.062896728515625 +4117 0.09271240234375 +4118 0.092987060546875 +4119 0.07855224609375 +4120 0.06427001953125 +4121 0.0347900390625 +4122 -0.01171875 +4123 -0.056060791015625 +4124 -0.055511474609375 +4125 -0.010467529296875 +4126 0.02508544921875 +4127 0.025665283203125 +4128 0.017333984375 +4129 0.00189208984375 +4130 -0.03173828125 +4131 -0.071502685546875 +4132 -0.13543701171875 +4133 -0.219970703125 +4134 -0.300506591796875 +4135 -0.376312255859375 +4136 -0.416107177734375 +4137 -0.371124267578125 +4138 -0.242279052734375 +4139 -0.069732666015625 +4140 0.125640869140625 +4141 0.31268310546875 +4142 0.45501708984375 +4143 0.554779052734375 +4144 0.61065673828125 +4145 0.610931396484375 +4146 0.531463623046875 +4147 0.3883056640625 +4148 0.23468017578125 +4149 0.095245361328125 +4150 -0.00396728515625 +4151 -0.04852294921875 +4152 -0.055145263671875 +4153 -0.0758056640625 +4154 -0.138702392578125 +4155 -0.209197998046875 +4156 -0.289031982421875 +4157 -0.37884521484375 +4158 -0.456329345703125 +4159 -0.51641845703125 +4160 -0.519287109375 +4161 -0.458251953125 +4162 -0.384796142578125 +4163 -0.323699951171875 +4164 -0.269287109375 +4165 -0.1951904296875 +4166 -0.100006103515625 +4167 -0.01055908203125 +4168 0.1033935546875 +4169 0.24908447265625 +4170 0.373199462890625 +4171 0.45806884765625 +4172 0.511474609375 +4173 0.565399169921875 +4174 0.61138916015625 +4175 0.5897216796875 +4176 0.4906005859375 +4177 0.33148193359375 +4178 0.147796630859375 +4179 -0.01873779296875 +4180 -0.140289306640625 +4181 -0.191986083984375 +4182 -0.184295654296875 +4183 -0.161834716796875 +4184 -0.166595458984375 +4185 -0.19390869140625 +4186 -0.22442626953125 +4187 -0.279754638671875 +4188 -0.3389892578125 +4189 -0.3543701171875 +4190 -0.348175048828125 +4191 -0.32598876953125 +4192 -0.2581787109375 +4193 -0.139801025390625 +4194 0.014617919921875 +4195 0.144378662109375 +4196 0.221038818359375 +4197 0.27069091796875 +4198 0.294036865234375 +4199 0.311767578125 +4200 0.339141845703125 +4201 0.360260009765625 +4202 0.360504150390625 +4203 0.308380126953125 +4204 0.18170166015625 +4205 0.0047607421875 +4206 -0.17559814453125 +4207 -0.3143310546875 +4208 -0.36785888671875 +4209 -0.36248779296875 +4210 -0.343536376953125 +4211 -0.3018798828125 +4212 -0.231414794921875 +4213 -0.117645263671875 +4214 0.007049560546875 +4215 0.087982177734375 +4216 0.13946533203125 +4217 0.17425537109375 +4218 0.188201904296875 +4219 0.171234130859375 +4220 0.118438720703125 +4221 0.05706787109375 +4222 -0.010711669921875 +4223 -0.0914306640625 +4224 -0.162322998046875 +4225 -0.194549560546875 +4226 -0.1492919921875 +4227 -0.02166748046875 +4228 0.124053955078125 +4229 0.211151123046875 +4230 0.240447998046875 +4231 0.242218017578125 +4232 0.2257080078125 +4233 0.194366455078125 +4234 0.115509033203125 +4235 0.0128173828125 +4236 -0.053802490234375 +4237 -0.110626220703125 +4238 -0.199493408203125 +4239 -0.29437255859375 +4240 -0.33221435546875 +4241 -0.27972412109375 +4242 -0.185333251953125 +4243 -0.128204345703125 +4244 -0.115692138671875 +4245 -0.116455078125 +4246 -0.105926513671875 +4247 -0.053955078125 +4248 0.048797607421875 +4249 0.157318115234375 +4250 0.212005615234375 +4251 0.218475341796875 +4252 0.23724365234375 +4253 0.30535888671875 +4254 0.38128662109375 +4255 0.404449462890625 +4256 0.3944091796875 +4257 0.3885498046875 +4258 0.362640380859375 +4259 0.27362060546875 +4260 0.11712646484375 +4261 -0.054901123046875 +4262 -0.19085693359375 +4263 -0.28570556640625 +4264 -0.339263916015625 +4265 -0.3775634765625 +4266 -0.445709228515625 +4267 -0.535064697265625 +4268 -0.629058837890625 +4269 -0.697601318359375 +4270 -0.70391845703125 +4271 -0.6424560546875 +4272 -0.491241455078125 +4273 -0.265716552734375 +4274 -0.023712158203125 +4275 0.201751708984375 +4276 0.375823974609375 +4277 0.485076904296875 +4278 0.56884765625 +4279 0.634765625 +4280 0.63763427734375 +4281 0.5660400390625 +4282 0.4720458984375 +4283 0.40692138671875 +4284 0.3778076171875 +4285 0.376953125 +4286 0.371978759765625 +4287 0.313140869140625 +4288 0.184417724609375 +4289 0.011199951171875 +4290 -0.171051025390625 +4291 -0.33740234375 +4292 -0.47198486328125 +4293 -0.560394287109375 +4294 -0.58056640625 +4295 -0.54754638671875 +4296 -0.508575439453125 +4297 -0.459503173828125 +4298 -0.394378662109375 +4299 -0.35260009765625 +4300 -0.31170654296875 +4301 -0.197418212890625 +4302 -0.007965087890625 +4303 0.207489013671875 +4304 0.409210205078125 +4305 0.57208251953125 +4306 0.66595458984375 +4307 0.65875244140625 +4308 0.56744384765625 +4309 0.431396484375 +4310 0.29443359375 +4311 0.182464599609375 +4312 0.06365966796875 +4313 -0.075958251953125 +4314 -0.189422607421875 +4315 -0.271942138671875 +4316 -0.342529296875 +4317 -0.364166259765625 +4318 -0.327239990234375 +4319 -0.2769775390625 +4320 -0.253692626953125 +4321 -0.24365234375 +4322 -0.1983642578125 +4323 -0.116241455078125 +4324 -0.036834716796875 +4325 0.034881591796875 +4326 0.09124755859375 +4327 0.10888671875 +4328 0.125518798828125 +4329 0.15771484375 +4330 0.17828369140625 +4331 0.17108154296875 +4332 0.129974365234375 +4333 0.082427978515625 +4334 0.027679443359375 +4335 -0.065643310546875 +4336 -0.15936279296875 +4337 -0.21307373046875 +4338 -0.234649658203125 +4339 -0.2001953125 +4340 -0.119171142578125 +4341 -0.024749755859375 +4342 0.085784912109375 +4343 0.178131103515625 +4344 0.215576171875 +4345 0.211456298828125 +4346 0.17523193359375 +4347 0.128753662109375 +4348 0.1019287109375 +4349 0.0743408203125 +4350 0.04327392578125 +4351 0.038177490234375 +4352 0.076263427734375 +4353 0.14105224609375 +4354 0.186431884765625 +4355 0.188812255859375 +4356 0.1390380859375 +4357 0.041778564453125 +4358 -0.079437255859375 +4359 -0.219390869140625 +4360 -0.367828369140625 +4361 -0.494873046875 +4362 -0.556243896484375 +4363 -0.508697509765625 +4364 -0.3756103515625 +4365 -0.218902587890625 +4366 -0.063751220703125 +4367 0.091552734375 +4368 0.23602294921875 +4369 0.342987060546875 +4370 0.39520263671875 +4371 0.389373779296875 +4372 0.324249267578125 +4373 0.224090576171875 +4374 0.124267578125 +4375 0.037078857421875 +4376 -0.010101318359375 +4377 -0.019439697265625 +4378 -0.022796630859375 +4379 -0.001556396484375 +4380 0.056304931640625 +4381 0.106719970703125 +4382 0.096893310546875 +4383 0.042694091796875 +4384 -0.018035888671875 +4385 -0.07586669921875 +4386 -0.11944580078125 +4387 -0.15972900390625 +4388 -0.202606201171875 +4389 -0.24859619140625 +4390 -0.30517578125 +4391 -0.36212158203125 +4392 -0.39141845703125 +4393 -0.35528564453125 +4394 -0.249969482421875 +4395 -0.092864990234375 +4396 0.08905029296875 +4397 0.2352294921875 +4398 0.318817138671875 +4399 0.358642578125 +4400 0.347747802734375 +4401 0.28564453125 +4402 0.223175048828125 +4403 0.196746826171875 +4404 0.179840087890625 +4405 0.155548095703125 +4406 0.151214599609375 +4407 0.156951904296875 +4408 0.13177490234375 +4409 0.100799560546875 +4410 0.087127685546875 +4411 0.05487060546875 +4412 -0.009002685546875 +4413 -0.10400390625 +4414 -0.229400634765625 +4415 -0.35552978515625 +4416 -0.441925048828125 +4417 -0.473846435546875 +4418 -0.464813232421875 +4419 -0.419097900390625 +4420 -0.334320068359375 +4421 -0.227935791015625 +4422 -0.12347412109375 +4423 -0.02764892578125 +4424 0.077667236328125 +4425 0.2132568359375 +4426 0.38885498046875 +4427 0.582794189453125 +4428 0.734039306640625 +4429 0.800140380859375 +4430 0.7783203125 +4431 0.6651611328125 +4432 0.45965576171875 +4433 0.199188232421875 +4434 -0.050689697265625 +4435 -0.23297119140625 +4436 -0.33013916015625 +4437 -0.368408203125 +4438 -0.378936767578125 +4439 -0.376983642578125 +4440 -0.37969970703125 +4441 -0.391510009765625 +4442 -0.385345458984375 +4443 -0.3419189453125 +4444 -0.28289794921875 +4445 -0.251617431640625 +4446 -0.266143798828125 +4447 -0.273345947265625 +4448 -0.216796875 +4449 -0.128265380859375 +4450 -0.068145751953125 +4451 -0.0430908203125 +4452 -0.024444580078125 +4453 0.020721435546875 +4454 0.124481201171875 +4455 0.25787353515625 +4456 0.379119873046875 +4457 0.47991943359375 +4458 0.5281982421875 +4459 0.511138916015625 +4460 0.456207275390625 +4461 0.407470703125 +4462 0.383758544921875 +4463 0.35687255859375 +4464 0.31182861328125 +4465 0.250885009765625 +4466 0.1654052734375 +4467 0.035247802734375 +4468 -0.142059326171875 +4469 -0.33563232421875 +4470 -0.5345458984375 +4471 -0.72186279296875 +4472 -0.836669921875 +4473 -0.8326416015625 +4474 -0.7296142578125 +4475 -0.582550048828125 +4476 -0.440093994140625 +4477 -0.324310302734375 +4478 -0.20147705078125 +4479 -0.044647216796875 +4480 0.103973388671875 +4481 0.202392578125 +4482 0.264495849609375 +4483 0.338897705078125 +4484 0.443817138671875 +4485 0.545074462890625 +4486 0.6173095703125 +4487 0.6524658203125 +4488 0.66339111328125 +4489 0.6561279296875 +4490 0.606781005859375 +4491 0.501190185546875 +4492 0.352783203125 +4493 0.176544189453125 +4494 -0.034820556640625 +4495 -0.258209228515625 +4496 -0.44244384765625 +4497 -0.5753173828125 +4498 -0.65203857421875 +4499 -0.641632080078125 +4500 -0.562164306640625 +4501 -0.458038330078125 +4502 -0.350555419921875 +4503 -0.260528564453125 +4504 -0.192108154296875 +4505 -0.141937255859375 +4506 -0.1021728515625 +4507 -0.062896728515625 +4508 -0.011932373046875 +4509 0.062835693359375 +4510 0.148712158203125 +4511 0.241729736328125 +4512 0.34912109375 +4513 0.457305908203125 +4514 0.54388427734375 +4515 0.5728759765625 +4516 0.506591796875 +4517 0.351226806640625 +4518 0.146514892578125 +4519 -0.05523681640625 +4520 -0.21624755859375 +4521 -0.334930419921875 +4522 -0.402984619140625 +4523 -0.4412841796875 +4524 -0.49578857421875 +4525 -0.5601806640625 +4526 -0.600738525390625 +4527 -0.584228515625 +4528 -0.47930908203125 +4529 -0.27935791015625 +4530 -0.0089111328125 +4531 0.268798828125 +4532 0.482818603515625 +4533 0.60369873046875 +4534 0.650421142578125 +4535 0.66400146484375 +4536 0.6414794921875 +4537 0.572540283203125 +4538 0.498138427734375 +4539 0.439453125 +4540 0.375518798828125 +4541 0.274505615234375 +4542 0.1087646484375 +4543 -0.099395751953125 +4544 -0.3182373046875 +4545 -0.5489501953125 +4546 -0.7738037109375 +4547 -0.86383056640625 +4548 -0.870391845703125 +4549 -0.86895751953125 +4550 -0.861053466796875 +4551 -0.765869140625 +4552 -0.5301513671875 +4553 -0.214691162109375 +4554 0.137359619140625 +4555 0.474822998046875 +4556 0.76239013671875 +4557 0.867462158203125 +4558 0.870361328125 +4559 0.86480712890625 +4560 0.831817626953125 +4561 0.677581787109375 +4562 0.495880126953125 +4563 0.30767822265625 +4564 0.116180419921875 +4565 -0.110748291015625 +4566 -0.381805419921875 +4567 -0.6572265625 +4568 -0.857421875 +4569 -0.870391845703125 +4570 -0.870391845703125 +4571 -0.86444091796875 +4572 -0.85723876953125 +4573 -0.790008544921875 +4574 -0.62847900390625 +4575 -0.3956298828125 +4576 -0.126708984375 +4577 0.150115966796875 +4578 0.424041748046875 +4579 0.670623779296875 +4580 0.854522705078125 +4581 0.866485595703125 +4582 0.86920166015625 +4583 0.8653564453125 +4584 0.857147216796875 +4585 0.766845703125 +4586 0.628509521484375 +4587 0.462127685546875 +4588 0.297210693359375 +4589 0.14862060546875 +4590 -0.00537109375 +4591 -0.15753173828125 +4592 -0.31304931640625 +4593 -0.48876953125 +4594 -0.6416015625 +4595 -0.751373291015625 +4596 -0.84619140625 +4597 -0.861297607421875 +4598 -0.863250732421875 +4599 -0.856597900390625 +4600 -0.7498779296875 +4601 -0.624542236328125 +4602 -0.47808837890625 +4603 -0.253387451171875 +4604 0.003692626953125 +4605 0.2257080078125 +4606 0.427154541015625 +4607 0.643218994140625 +4608 0.855926513671875 +4609 0.870361328125 +4610 0.870361328125 +4611 0.862762451171875 +4612 0.79669189453125 +4613 0.595794677734375 +4614 0.362152099609375 +4615 0.1270751953125 +4616 -0.086944580078125 +4617 -0.2784423828125 +4618 -0.484832763671875 +4619 -0.729583740234375 +4620 -0.86688232421875 +4621 -0.870391845703125 +4622 -0.86859130859375 +4623 -0.86279296875 +4624 -0.817962646484375 +4625 -0.6116943359375 +4626 -0.3128662109375 +4627 0.039398193359375 +4628 0.422821044921875 +4629 0.805145263671875 +4630 0.870361328125 +4631 0.870361328125 +4632 0.860015869140625 +4633 0.727935791015625 +4634 0.48114013671875 +4635 0.2059326171875 +4636 -0.06103515625 +4637 -0.29913330078125 +4638 -0.516204833984375 +4639 -0.7252197265625 +4640 -0.85980224609375 +4641 -0.870391845703125 +4642 -0.870391845703125 +4643 -0.858062744140625 +4644 -0.673004150390625 +4645 -0.42694091796875 +4646 -0.2100830078125 +4647 -0.0362548828125 +4648 0.10943603515625 +4649 0.23516845703125 +4650 0.373687744140625 +4651 0.517791748046875 +4652 0.602783203125 +4653 0.635711669921875 +4654 0.655181884765625 +4655 0.65948486328125 +4656 0.651275634765625 +4657 0.61846923828125 +4658 0.53753662109375 +4659 0.404144287109375 +4660 0.22186279296875 +4661 0.003997802734375 +4662 -0.22100830078125 +4663 -0.42449951171875 +4664 -0.579833984375 +4665 -0.641876220703125 +4666 -0.6177978515625 +4667 -0.575531005859375 +4668 -0.526336669921875 +4669 -0.42645263671875 +4670 -0.2581787109375 +4671 -0.068695068359375 +4672 0.09222412109375 +4673 0.232147216796875 +4674 0.3509521484375 +4675 0.410064697265625 +4676 0.372955322265625 +4677 0.2554931640625 +4678 0.10711669921875 +4679 -0.052886962890625 +4680 -0.186279296875 +4681 -0.23291015625 +4682 -0.209442138671875 +4683 -0.174163818359375 +4684 -0.126739501953125 +4685 -0.048126220703125 +4686 0.0426025390625 +4687 0.10748291015625 +4688 0.1409912109375 +4689 0.19708251953125 +4690 0.273651123046875 +4691 0.31768798828125 +4692 0.341094970703125 +4693 0.368011474609375 +4694 0.37249755859375 +4695 0.30072021484375 +4696 0.1517333984375 +4697 -0.01470947265625 +4698 -0.1883544921875 +4699 -0.372711181640625 +4700 -0.51397705078125 +4701 -0.57177734375 +4702 -0.53948974609375 +4703 -0.43511962890625 +4704 -0.2962646484375 +4705 -0.161102294921875 +4706 -0.0435791015625 +4707 0.060394287109375 +4708 0.13665771484375 +4709 0.170135498046875 +4710 0.16552734375 +4711 0.15728759765625 +4712 0.150787353515625 +4713 0.12200927734375 +4714 0.080108642578125 +4715 0.05126953125 +4716 0.062896728515625 +4717 0.09271240234375 +4718 0.092987060546875 +4719 0.07855224609375 +4720 0.06427001953125 +4721 0.0347900390625 +4722 -0.01171875 +4723 -0.056060791015625 +4724 -0.055511474609375 +4725 -0.010467529296875 +4726 0.02508544921875 +4727 0.025665283203125 +4728 0.017333984375 +4729 0.00189208984375 +4730 -0.03173828125 +4731 -0.071502685546875 +4732 -0.13543701171875 +4733 -0.219970703125 +4734 -0.300506591796875 +4735 -0.376312255859375 +4736 -0.416107177734375 +4737 -0.371124267578125 +4738 -0.242279052734375 +4739 -0.069732666015625 +4740 0.125640869140625 +4741 0.31268310546875 +4742 0.45501708984375 +4743 0.554779052734375 +4744 0.61065673828125 +4745 0.610931396484375 +4746 0.531463623046875 +4747 0.3883056640625 +4748 0.23468017578125 +4749 0.095245361328125 +4750 -0.00396728515625 +4751 -0.04852294921875 +4752 -0.055145263671875 +4753 -0.0758056640625 +4754 -0.138702392578125 +4755 -0.209197998046875 +4756 -0.289031982421875 +4757 -0.37884521484375 +4758 -0.456329345703125 +4759 -0.51641845703125 +4760 -0.519287109375 +4761 -0.458251953125 +4762 -0.384796142578125 +4763 -0.323699951171875 +4764 -0.269287109375 +4765 -0.1951904296875 +4766 -0.100006103515625 +4767 -0.01055908203125 +4768 0.1033935546875 +4769 0.24908447265625 +4770 0.373199462890625 +4771 0.45806884765625 +4772 0.511474609375 +4773 0.565399169921875 +4774 0.61138916015625 +4775 0.5897216796875 +4776 0.4906005859375 +4777 0.33148193359375 +4778 0.147796630859375 +4779 -0.01873779296875 +4780 -0.140289306640625 +4781 -0.191986083984375 +4782 -0.184295654296875 +4783 -0.161834716796875 +4784 -0.166595458984375 +4785 -0.19390869140625 +4786 -0.22442626953125 +4787 -0.279754638671875 +4788 -0.3389892578125 +4789 -0.3543701171875 +4790 -0.348175048828125 +4791 -0.32598876953125 +4792 -0.2581787109375 +4793 -0.139801025390625 +4794 0.014617919921875 +4795 0.144378662109375 +4796 0.221038818359375 +4797 0.27069091796875 +4798 0.294036865234375 +4799 0.311767578125 +4800 0.339141845703125 +4801 0.360260009765625 +4802 0.360504150390625 +4803 0.308380126953125 +4804 0.18170166015625 +4805 0.0047607421875 +4806 -0.17559814453125 +4807 -0.3143310546875 +4808 -0.36785888671875 +4809 -0.36248779296875 +4810 -0.343536376953125 +4811 -0.3018798828125 +4812 -0.231414794921875 +4813 -0.117645263671875 +4814 0.007049560546875 +4815 0.087982177734375 +4816 0.13946533203125 +4817 0.17425537109375 +4818 0.188201904296875 +4819 0.171234130859375 +4820 0.118438720703125 +4821 0.05706787109375 +4822 -0.010711669921875 +4823 -0.0914306640625 +4824 -0.162322998046875 +4825 -0.194549560546875 +4826 -0.1492919921875 +4827 -0.02166748046875 +4828 0.124053955078125 +4829 0.211151123046875 +4830 0.240447998046875 +4831 0.242218017578125 +4832 0.2257080078125 +4833 0.194366455078125 +4834 0.115509033203125 +4835 0.0128173828125 +4836 -0.053802490234375 +4837 -0.110626220703125 +4838 -0.199493408203125 +4839 -0.29437255859375 +4840 -0.33221435546875 +4841 -0.27972412109375 +4842 -0.185333251953125 +4843 -0.128204345703125 +4844 -0.115692138671875 +4845 -0.116455078125 +4846 -0.105926513671875 +4847 -0.053955078125 +4848 0.048797607421875 +4849 0.157318115234375 +4850 0.212005615234375 +4851 0.218475341796875 +4852 0.23724365234375 +4853 0.30535888671875 +4854 0.38128662109375 +4855 0.404449462890625 +4856 0.3944091796875 +4857 0.3885498046875 +4858 0.362640380859375 +4859 0.27362060546875 +4860 0.11712646484375 +4861 -0.054901123046875 +4862 -0.19085693359375 +4863 -0.28570556640625 +4864 -0.339263916015625 +4865 -0.3775634765625 +4866 -0.445709228515625 +4867 -0.535064697265625 +4868 -0.629058837890625 +4869 -0.697601318359375 +4870 -0.70391845703125 +4871 -0.6424560546875 +4872 -0.491241455078125 +4873 -0.265716552734375 +4874 -0.023712158203125 +4875 0.201751708984375 +4876 0.375823974609375 +4877 0.485076904296875 +4878 0.56884765625 +4879 0.634765625 +4880 0.63763427734375 +4881 0.5660400390625 +4882 0.4720458984375 +4883 0.40692138671875 +4884 0.3778076171875 +4885 0.376953125 +4886 0.371978759765625 +4887 0.313140869140625 +4888 0.184417724609375 +4889 0.011199951171875 +4890 -0.171051025390625 +4891 -0.33740234375 +4892 -0.47198486328125 +4893 -0.560394287109375 +4894 -0.58056640625 +4895 -0.54754638671875 +4896 -0.508575439453125 +4897 -0.459503173828125 +4898 -0.394378662109375 +4899 -0.35260009765625 +4900 -0.31170654296875 +4901 -0.197418212890625 +4902 -0.007965087890625 +4903 0.207489013671875 +4904 0.409210205078125 +4905 0.57208251953125 +4906 0.66595458984375 +4907 0.65875244140625 +4908 0.56744384765625 +4909 0.431396484375 +4910 0.29443359375 +4911 0.182464599609375 +4912 0.06365966796875 +4913 -0.075958251953125 +4914 -0.189422607421875 +4915 -0.271942138671875 +4916 -0.342529296875 +4917 -0.364166259765625 +4918 -0.327239990234375 +4919 -0.2769775390625 +4920 -0.253692626953125 +4921 -0.24365234375 +4922 -0.1983642578125 +4923 -0.116241455078125 +4924 -0.036834716796875 +4925 0.034881591796875 +4926 0.09124755859375 +4927 0.10888671875 +4928 0.125518798828125 +4929 0.15771484375 +4930 0.17828369140625 +4931 0.17108154296875 +4932 0.129974365234375 +4933 0.082427978515625 +4934 0.027679443359375 +4935 -0.065643310546875 +4936 -0.15936279296875 +4937 -0.21307373046875 +4938 -0.234649658203125 +4939 -0.2001953125 +4940 -0.119171142578125 +4941 -0.024749755859375 +4942 0.085784912109375 +4943 0.178131103515625 +4944 0.215576171875 +4945 0.211456298828125 +4946 0.17523193359375 +4947 0.128753662109375 +4948 0.1019287109375 +4949 0.0743408203125 +4950 0.04327392578125 +4951 0.038177490234375 +4952 0.076263427734375 +4953 0.14105224609375 +4954 0.186431884765625 +4955 0.188812255859375 +4956 0.1390380859375 +4957 0.041778564453125 +4958 -0.079437255859375 +4959 -0.219390869140625 +4960 -0.367828369140625 +4961 -0.494873046875 +4962 -0.556243896484375 +4963 -0.508697509765625 +4964 -0.3756103515625 +4965 -0.218902587890625 +4966 -0.063751220703125 +4967 0.091552734375 +4968 0.23602294921875 +4969 0.342987060546875 +4970 0.39520263671875 +4971 0.389373779296875 +4972 0.324249267578125 +4973 0.224090576171875 +4974 0.124267578125 +4975 0.037078857421875 +4976 -0.010101318359375 +4977 -0.019439697265625 +4978 -0.022796630859375 +4979 -0.001556396484375 +4980 0.056304931640625 +4981 0.106719970703125 +4982 0.096893310546875 +4983 0.042694091796875 +4984 -0.018035888671875 +4985 -0.07586669921875 +4986 -0.11944580078125 +4987 -0.15972900390625 +4988 -0.202606201171875 +4989 -0.24859619140625 +4990 -0.30517578125 +4991 -0.36212158203125 +4992 -0.39141845703125 +4993 -0.35528564453125 +4994 -0.249969482421875 +4995 -0.092864990234375 +4996 0.08905029296875 +4997 0.2352294921875 +4998 0.318817138671875 +4999 0.358642578125 +5000 0.347747802734375 +5001 0.28564453125 +5002 0.223175048828125 +5003 0.196746826171875 +5004 0.179840087890625 +5005 0.155548095703125 +5006 0.151214599609375 +5007 0.156951904296875 +5008 0.13177490234375 +5009 0.100799560546875 +5010 0.087127685546875 +5011 0.05487060546875 +5012 -0.009002685546875 +5013 -0.10400390625 +5014 -0.229400634765625 +5015 -0.35552978515625 +5016 -0.441925048828125 +5017 -0.473846435546875 +5018 -0.464813232421875 +5019 -0.419097900390625 +5020 -0.334320068359375 +5021 -0.227935791015625 +5022 -0.12347412109375 +5023 -0.02764892578125 +5024 0.077667236328125 +5025 0.2132568359375 +5026 0.38885498046875 +5027 0.582794189453125 +5028 0.734039306640625 +5029 0.800140380859375 +5030 0.7783203125 +5031 0.6651611328125 +5032 0.45965576171875 +5033 0.199188232421875 +5034 -0.050689697265625 +5035 -0.23297119140625 +5036 -0.33013916015625 +5037 -0.368408203125 +5038 -0.378936767578125 +5039 -0.376983642578125 +5040 -0.37969970703125 +5041 -0.391510009765625 +5042 -0.385345458984375 +5043 -0.3419189453125 +5044 -0.28289794921875 +5045 -0.251617431640625 +5046 -0.266143798828125 +5047 -0.273345947265625 +5048 -0.216796875 +5049 -0.128265380859375 +5050 -0.068145751953125 +5051 -0.0430908203125 +5052 -0.024444580078125 +5053 0.020721435546875 +5054 0.124481201171875 +5055 0.25787353515625 +5056 0.379119873046875 +5057 0.47991943359375 +5058 0.5281982421875 +5059 0.511138916015625 +5060 0.456207275390625 +5061 0.407470703125 +5062 0.383758544921875 +5063 0.35687255859375 +5064 0.31182861328125 +5065 0.250885009765625 +5066 0.1654052734375 +5067 0.035247802734375 +5068 -0.142059326171875 +5069 -0.33563232421875 +5070 -0.5345458984375 +5071 -0.72186279296875 +5072 -0.836669921875 +5073 -0.8326416015625 +5074 -0.7296142578125 +5075 -0.582550048828125 +5076 -0.440093994140625 +5077 -0.324310302734375 +5078 -0.20147705078125 +5079 -0.044647216796875 +5080 0.103973388671875 +5081 0.202392578125 +5082 0.264495849609375 +5083 0.338897705078125 +5084 0.443817138671875 +5085 0.545074462890625 +5086 0.6173095703125 +5087 0.6524658203125 +5088 0.66339111328125 +5089 0.6561279296875 +5090 0.606781005859375 +5091 0.501190185546875 +5092 0.352783203125 +5093 0.176544189453125 +5094 -0.034820556640625 +5095 -0.258209228515625 +5096 -0.44244384765625 +5097 -0.5753173828125 +5098 -0.65203857421875 +5099 -0.641632080078125 +5100 -0.562164306640625 +5101 -0.458038330078125 +5102 -0.350555419921875 +5103 -0.260528564453125 +5104 -0.192108154296875 +5105 -0.141937255859375 +5106 -0.1021728515625 +5107 -0.062896728515625 +5108 -0.011932373046875 +5109 0.062835693359375 +5110 0.148712158203125 +5111 0.241729736328125 +5112 0.34912109375 +5113 0.457305908203125 +5114 0.54388427734375 +5115 0.5728759765625 +5116 0.506591796875 +5117 0.351226806640625 +5118 0.146514892578125 +5119 -0.05523681640625 +5120 -0.21624755859375 +5121 -0.334930419921875 +5122 -0.402984619140625 +5123 -0.4412841796875 +5124 -0.49578857421875 +5125 -0.5601806640625 +5126 -0.600738525390625 +5127 -0.584228515625 +5128 -0.47930908203125 +5129 -0.27935791015625 +5130 -0.0089111328125 +5131 0.268798828125 +5132 0.482818603515625 +5133 0.60369873046875 +5134 0.650421142578125 +5135 0.66400146484375 +5136 0.6414794921875 +5137 0.572540283203125 +5138 0.498138427734375 +5139 0.439453125 +5140 0.375518798828125 +5141 0.274505615234375 +5142 0.1087646484375 +5143 -0.099395751953125 +5144 -0.3182373046875 +5145 -0.5489501953125 +5146 -0.7738037109375 +5147 -0.86383056640625 +5148 -0.870391845703125 +5149 -0.86895751953125 +5150 -0.861053466796875 +5151 -0.765869140625 +5152 -0.5301513671875 +5153 -0.214691162109375 +5154 0.137359619140625 +5155 0.474822998046875 +5156 0.76239013671875 +5157 0.867462158203125 +5158 0.870361328125 +5159 0.86480712890625 +5160 0.831817626953125 +5161 0.677581787109375 +5162 0.495880126953125 +5163 0.30767822265625 +5164 0.116180419921875 +5165 -0.110748291015625 +5166 -0.381805419921875 +5167 -0.6572265625 +5168 -0.857421875 +5169 -0.870391845703125 +5170 -0.870391845703125 +5171 -0.86444091796875 +5172 -0.85723876953125 +5173 -0.790008544921875 +5174 -0.62847900390625 +5175 -0.3956298828125 +5176 -0.126708984375 +5177 0.150115966796875 +5178 0.424041748046875 +5179 0.670623779296875 +5180 0.854522705078125 +5181 0.866485595703125 +5182 0.86920166015625 +5183 0.8653564453125 +5184 0.857147216796875 +5185 0.766845703125 +5186 0.628509521484375 +5187 0.462127685546875 +5188 0.297210693359375 +5189 0.14862060546875 +5190 -0.00537109375 +5191 -0.15753173828125 +5192 -0.31304931640625 +5193 -0.48876953125 +5194 -0.6416015625 +5195 -0.751373291015625 +5196 -0.84619140625 +5197 -0.861297607421875 +5198 -0.863250732421875 +5199 -0.856597900390625 +5200 -0.7498779296875 +5201 -0.624542236328125 +5202 -0.47808837890625 +5203 -0.253387451171875 +5204 0.003692626953125 +5205 0.2257080078125 +5206 0.427154541015625 +5207 0.643218994140625 +5208 0.855926513671875 +5209 0.870361328125 +5210 0.870361328125 +5211 0.862762451171875 +5212 0.79669189453125 +5213 0.595794677734375 +5214 0.362152099609375 +5215 0.1270751953125 +5216 -0.086944580078125 +5217 -0.2784423828125 +5218 -0.484832763671875 +5219 -0.729583740234375 +5220 -0.86688232421875 +5221 -0.870391845703125 +5222 -0.86859130859375 +5223 -0.86279296875 +5224 -0.817962646484375 +5225 -0.6116943359375 +5226 -0.3128662109375 +5227 0.039398193359375 +5228 0.422821044921875 +5229 0.805145263671875 +5230 0.870361328125 +5231 0.870361328125 +5232 0.860015869140625 +5233 0.727935791015625 +5234 0.48114013671875 +5235 0.2059326171875 +5236 -0.06103515625 +5237 -0.29913330078125 +5238 -0.516204833984375 +5239 -0.7252197265625 +5240 -0.85980224609375 +5241 -0.870391845703125 +5242 -0.870391845703125 +5243 -0.858062744140625 +5244 -0.673004150390625 +5245 -0.42694091796875 +5246 -0.2100830078125 +5247 -0.0362548828125 +5248 0.10943603515625 +5249 0.23516845703125 +5250 0.373687744140625 +5251 0.517791748046875 +5252 0.602783203125 +5253 0.635711669921875 +5254 0.655181884765625 +5255 0.65948486328125 +5256 0.651275634765625 +5257 0.61846923828125 +5258 0.53753662109375 +5259 0.404144287109375 +5260 0.22186279296875 +5261 0.003997802734375 +5262 -0.22100830078125 +5263 -0.42449951171875 +5264 -0.579833984375 +5265 -0.641876220703125 +5266 -0.6177978515625 +5267 -0.575531005859375 +5268 -0.526336669921875 +5269 -0.42645263671875 +5270 -0.2581787109375 +5271 -0.068695068359375 +5272 0.09222412109375 +5273 0.232147216796875 +5274 0.3509521484375 +5275 0.410064697265625 +5276 0.372955322265625 +5277 0.2554931640625 +5278 0.10711669921875 +5279 -0.052886962890625 +5280 -0.186279296875 +5281 -0.23291015625 +5282 -0.209442138671875 +5283 -0.174163818359375 +5284 -0.126739501953125 +5285 -0.048126220703125 +5286 0.0426025390625 +5287 0.10748291015625 +5288 0.1409912109375 +5289 0.19708251953125 +5290 0.273651123046875 +5291 0.31768798828125 +5292 0.341094970703125 +5293 0.368011474609375 +5294 0.37249755859375 +5295 0.30072021484375 +5296 0.1517333984375 +5297 -0.01470947265625 +5298 -0.1883544921875 +5299 -0.372711181640625 +5300 -0.51397705078125 +5301 -0.57177734375 +5302 -0.53948974609375 +5303 -0.43511962890625 +5304 -0.2962646484375 +5305 -0.161102294921875 +5306 -0.0435791015625 +5307 0.060394287109375 +5308 0.13665771484375 +5309 0.170135498046875 +5310 0.16552734375 +5311 0.15728759765625 +5312 0.150787353515625 +5313 0.12200927734375 +5314 0.080108642578125 +5315 0.05126953125 +5316 0.062896728515625 +5317 0.09271240234375 +5318 0.092987060546875 +5319 0.07855224609375 +5320 0.06427001953125 +5321 0.0347900390625 +5322 -0.01171875 +5323 -0.056060791015625 +5324 -0.055511474609375 +5325 -0.010467529296875 +5326 0.02508544921875 +5327 0.025665283203125 +5328 0.017333984375 +5329 0.00189208984375 +5330 -0.03173828125 +5331 -0.071502685546875 +5332 -0.13543701171875 +5333 -0.219970703125 +5334 -0.300506591796875 +5335 -0.376312255859375 +5336 -0.416107177734375 +5337 -0.371124267578125 +5338 -0.242279052734375 +5339 -0.069732666015625 +5340 0.125640869140625 +5341 0.31268310546875 +5342 0.45501708984375 +5343 0.554779052734375 +5344 0.61065673828125 +5345 0.610931396484375 +5346 0.531463623046875 +5347 0.3883056640625 +5348 0.23468017578125 +5349 0.095245361328125 +5350 -0.00396728515625 +5351 -0.04852294921875 +5352 -0.055145263671875 +5353 -0.0758056640625 +5354 -0.138702392578125 +5355 -0.209197998046875 +5356 -0.289031982421875 +5357 -0.37884521484375 +5358 -0.456329345703125 +5359 -0.51641845703125 +5360 -0.519287109375 +5361 -0.458251953125 +5362 -0.384796142578125 +5363 -0.323699951171875 +5364 -0.269287109375 +5365 -0.1951904296875 +5366 -0.100006103515625 +5367 -0.01055908203125 +5368 0.1033935546875 +5369 0.24908447265625 +5370 0.373199462890625 +5371 0.45806884765625 +5372 0.511474609375 +5373 0.565399169921875 +5374 0.61138916015625 +5375 0.5897216796875 +5376 0.4906005859375 +5377 0.33148193359375 +5378 0.147796630859375 +5379 -0.01873779296875 +5380 -0.140289306640625 +5381 -0.191986083984375 +5382 -0.184295654296875 +5383 -0.161834716796875 +5384 -0.166595458984375 +5385 -0.19390869140625 +5386 -0.22442626953125 +5387 -0.279754638671875 +5388 -0.3389892578125 +5389 -0.3543701171875 +5390 -0.348175048828125 +5391 -0.32598876953125 +5392 -0.2581787109375 +5393 -0.139801025390625 +5394 0.014617919921875 +5395 0.144378662109375 +5396 0.221038818359375 +5397 0.27069091796875 +5398 0.294036865234375 +5399 0.311767578125 +5400 0.339141845703125 +5401 0.360260009765625 +5402 0.360504150390625 +5403 0.308380126953125 +5404 0.18170166015625 +5405 0.0047607421875 +5406 -0.17559814453125 +5407 -0.3143310546875 +5408 -0.36785888671875 +5409 -0.36248779296875 +5410 -0.343536376953125 +5411 -0.3018798828125 +5412 -0.231414794921875 +5413 -0.117645263671875 +5414 0.007049560546875 +5415 0.087982177734375 +5416 0.13946533203125 +5417 0.17425537109375 +5418 0.188201904296875 +5419 0.171234130859375 +5420 0.118438720703125 +5421 0.05706787109375 +5422 -0.010711669921875 +5423 -0.0914306640625 +5424 -0.162322998046875 +5425 -0.194549560546875 +5426 -0.1492919921875 +5427 -0.02166748046875 +5428 0.124053955078125 +5429 0.211151123046875 +5430 0.240447998046875 +5431 0.242218017578125 +5432 0.2257080078125 +5433 0.194366455078125 +5434 0.115509033203125 +5435 0.0128173828125 +5436 -0.053802490234375 +5437 -0.110626220703125 +5438 -0.199493408203125 +5439 -0.29437255859375 +5440 -0.33221435546875 +5441 -0.27972412109375 +5442 -0.185333251953125 +5443 -0.128204345703125 +5444 -0.115692138671875 +5445 -0.116455078125 +5446 -0.105926513671875 +5447 -0.053955078125 +5448 0.048797607421875 +5449 0.157318115234375 +5450 0.212005615234375 +5451 0.218475341796875 +5452 0.23724365234375 +5453 0.30535888671875 +5454 0.38128662109375 +5455 0.404449462890625 +5456 0.3944091796875 +5457 0.3885498046875 +5458 0.362640380859375 +5459 0.27362060546875 +5460 0.11712646484375 +5461 -0.054901123046875 +5462 -0.19085693359375 +5463 -0.28570556640625 +5464 -0.339263916015625 +5465 -0.3775634765625 +5466 -0.445709228515625 +5467 -0.535064697265625 +5468 -0.629058837890625 +5469 -0.697601318359375 +5470 -0.70391845703125 +5471 -0.6424560546875 +5472 -0.491241455078125 +5473 -0.265716552734375 +5474 -0.023712158203125 +5475 0.201751708984375 +5476 0.375823974609375 +5477 0.485076904296875 +5478 0.56884765625 +5479 0.634765625 +5480 0.63763427734375 +5481 0.5660400390625 +5482 0.4720458984375 +5483 0.40692138671875 +5484 0.3778076171875 +5485 0.376953125 +5486 0.371978759765625 +5487 0.313140869140625 +5488 0.184417724609375 +5489 0.011199951171875 +5490 -0.171051025390625 +5491 -0.33740234375 +5492 -0.47198486328125 +5493 -0.560394287109375 +5494 -0.58056640625 +5495 -0.54754638671875 +5496 -0.508575439453125 +5497 -0.459503173828125 +5498 -0.394378662109375 +5499 -0.35260009765625 +5500 -0.31170654296875 +5501 -0.197418212890625 +5502 -0.007965087890625 +5503 0.207489013671875 +5504 0.409210205078125 +5505 0.57208251953125 +5506 0.66595458984375 +5507 0.65875244140625 +5508 0.56744384765625 +5509 0.431396484375 +5510 0.29443359375 +5511 0.182464599609375 +5512 0.06365966796875 +5513 -0.075958251953125 +5514 -0.189422607421875 +5515 -0.271942138671875 +5516 -0.342529296875 +5517 -0.364166259765625 +5518 -0.327239990234375 +5519 -0.2769775390625 +5520 -0.253692626953125 +5521 -0.24365234375 +5522 -0.1983642578125 +5523 -0.116241455078125 +5524 -0.036834716796875 +5525 0.034881591796875 +5526 0.09124755859375 +5527 0.10888671875 +5528 0.125518798828125 +5529 0.15771484375 +5530 0.17828369140625 +5531 0.17108154296875 +5532 0.129974365234375 +5533 0.082427978515625 +5534 0.027679443359375 +5535 -0.065643310546875 +5536 -0.15936279296875 +5537 -0.21307373046875 +5538 -0.234649658203125 +5539 -0.2001953125 +5540 -0.119171142578125 +5541 -0.024749755859375 +5542 0.085784912109375 +5543 0.178131103515625 +5544 0.215576171875 +5545 0.211456298828125 +5546 0.17523193359375 +5547 0.128753662109375 +5548 0.1019287109375 +5549 0.0743408203125 +5550 0.04327392578125 +5551 0.038177490234375 +5552 0.076263427734375 +5553 0.14105224609375 +5554 0.186431884765625 +5555 0.188812255859375 +5556 0.1390380859375 +5557 0.041778564453125 +5558 -0.079437255859375 +5559 -0.219390869140625 +5560 -0.367828369140625 +5561 -0.494873046875 +5562 -0.556243896484375 +5563 -0.508697509765625 +5564 -0.3756103515625 +5565 -0.218902587890625 +5566 -0.063751220703125 +5567 0.091552734375 +5568 0.23602294921875 +5569 0.342987060546875 +5570 0.39520263671875 +5571 0.389373779296875 +5572 0.324249267578125 +5573 0.224090576171875 +5574 0.124267578125 +5575 0.037078857421875 +5576 -0.010101318359375 +5577 -0.019439697265625 +5578 -0.022796630859375 +5579 -0.001556396484375 +5580 0.056304931640625 +5581 0.106719970703125 +5582 0.096893310546875 +5583 0.042694091796875 +5584 -0.018035888671875 +5585 -0.07586669921875 +5586 -0.11944580078125 +5587 -0.15972900390625 +5588 -0.202606201171875 +5589 -0.24859619140625 +5590 -0.30517578125 +5591 -0.36212158203125 +5592 -0.39141845703125 +5593 -0.35528564453125 +5594 -0.249969482421875 +5595 -0.092864990234375 +5596 0.08905029296875 +5597 0.2352294921875 +5598 0.318817138671875 +5599 0.358642578125 +5600 0.347747802734375 +5601 0.28564453125 +5602 0.223175048828125 +5603 0.196746826171875 +5604 0.179840087890625 +5605 0.155548095703125 +5606 0.151214599609375 +5607 0.156951904296875 +5608 0.13177490234375 +5609 0.100799560546875 +5610 0.087127685546875 +5611 0.05487060546875 +5612 -0.009002685546875 +5613 -0.10400390625 +5614 -0.229400634765625 +5615 -0.35552978515625 +5616 -0.441925048828125 +5617 -0.473846435546875 +5618 -0.464813232421875 +5619 -0.419097900390625 +5620 -0.334320068359375 +5621 -0.227935791015625 +5622 -0.12347412109375 +5623 -0.02764892578125 +5624 0.077667236328125 +5625 0.2132568359375 +5626 0.38885498046875 +5627 0.582794189453125 +5628 0.734039306640625 +5629 0.800140380859375 +5630 0.7783203125 +5631 0.6651611328125 +5632 0.45965576171875 +5633 0.199188232421875 +5634 -0.050689697265625 +5635 -0.23297119140625 +5636 -0.33013916015625 +5637 -0.368408203125 +5638 -0.378936767578125 +5639 -0.376983642578125 +5640 -0.37969970703125 +5641 -0.391510009765625 +5642 -0.385345458984375 +5643 -0.3419189453125 +5644 -0.28289794921875 +5645 -0.251617431640625 +5646 -0.266143798828125 +5647 -0.273345947265625 +5648 -0.216796875 +5649 -0.128265380859375 +5650 -0.068145751953125 +5651 -0.0430908203125 +5652 -0.024444580078125 +5653 0.020721435546875 +5654 0.124481201171875 +5655 0.25787353515625 +5656 0.379119873046875 +5657 0.47991943359375 +5658 0.5281982421875 +5659 0.511138916015625 +5660 0.456207275390625 +5661 0.407470703125 +5662 0.383758544921875 +5663 0.35687255859375 +5664 0.31182861328125 +5665 0.250885009765625 +5666 0.1654052734375 +5667 0.035247802734375 +5668 -0.142059326171875 +5669 -0.33563232421875 +5670 -0.5345458984375 +5671 -0.72186279296875 +5672 -0.836669921875 +5673 -0.8326416015625 +5674 -0.7296142578125 +5675 -0.582550048828125 +5676 -0.440093994140625 +5677 -0.324310302734375 +5678 -0.20147705078125 +5679 -0.044647216796875 +5680 0.103973388671875 +5681 0.202392578125 +5682 0.264495849609375 +5683 0.338897705078125 +5684 0.443817138671875 +5685 0.545074462890625 +5686 0.6173095703125 +5687 0.6524658203125 +5688 0.66339111328125 +5689 0.6561279296875 +5690 0.606781005859375 +5691 0.501190185546875 +5692 0.352783203125 +5693 0.176544189453125 +5694 -0.034820556640625 +5695 -0.258209228515625 +5696 -0.44244384765625 +5697 -0.5753173828125 +5698 -0.65203857421875 +5699 -0.641632080078125 +5700 -0.562164306640625 +5701 -0.458038330078125 +5702 -0.350555419921875 +5703 -0.260528564453125 +5704 -0.192108154296875 +5705 -0.141937255859375 +5706 -0.1021728515625 +5707 -0.062896728515625 +5708 -0.011932373046875 +5709 0.062835693359375 +5710 0.148712158203125 +5711 0.241729736328125 +5712 0.34912109375 +5713 0.457305908203125 +5714 0.54388427734375 +5715 0.5728759765625 +5716 0.506591796875 +5717 0.351226806640625 +5718 0.146514892578125 +5719 -0.05523681640625 +5720 -0.21624755859375 +5721 -0.334930419921875 +5722 -0.402984619140625 +5723 -0.4412841796875 +5724 -0.49578857421875 +5725 -0.5601806640625 +5726 -0.600738525390625 +5727 -0.584228515625 +5728 -0.47930908203125 +5729 -0.27935791015625 +5730 -0.0089111328125 +5731 0.268798828125 +5732 0.482818603515625 +5733 0.60369873046875 +5734 0.650421142578125 +5735 0.66400146484375 +5736 0.6414794921875 +5737 0.572540283203125 +5738 0.498138427734375 +5739 0.439453125 +5740 0.375518798828125 +5741 0.274505615234375 +5742 0.1087646484375 +5743 -0.099395751953125 +5744 -0.3182373046875 +5745 -0.5489501953125 +5746 -0.7738037109375 +5747 -0.86383056640625 +5748 -0.870391845703125 +5749 -0.86895751953125 +5750 -0.861053466796875 +5751 -0.765869140625 +5752 -0.5301513671875 +5753 -0.214691162109375 +5754 0.137359619140625 +5755 0.474822998046875 +5756 0.76239013671875 +5757 0.867462158203125 +5758 0.870361328125 +5759 0.86480712890625 +5760 0.831817626953125 +5761 0.677581787109375 +5762 0.495880126953125 +5763 0.30767822265625 +5764 0.116180419921875 +5765 -0.110748291015625 +5766 -0.381805419921875 +5767 -0.6572265625 +5768 -0.857421875 +5769 -0.870391845703125 +5770 -0.870391845703125 +5771 -0.86444091796875 +5772 -0.85723876953125 +5773 -0.790008544921875 +5774 -0.62847900390625 +5775 -0.3956298828125 +5776 -0.126708984375 +5777 0.150115966796875 +5778 0.424041748046875 +5779 0.670623779296875 +5780 0.854522705078125 +5781 0.866485595703125 +5782 0.86920166015625 +5783 0.8653564453125 +5784 0.857147216796875 +5785 0.766845703125 +5786 0.628509521484375 +5787 0.462127685546875 +5788 0.297210693359375 +5789 0.14862060546875 +5790 -0.00537109375 +5791 -0.15753173828125 +5792 -0.31304931640625 +5793 -0.48876953125 +5794 -0.6416015625 +5795 -0.751373291015625 +5796 -0.84619140625 +5797 -0.861297607421875 +5798 -0.863250732421875 +5799 -0.856597900390625 +5800 -0.7498779296875 +5801 -0.624542236328125 +5802 -0.47808837890625 +5803 -0.253387451171875 +5804 0.003692626953125 +5805 0.2257080078125 +5806 0.427154541015625 +5807 0.643218994140625 +5808 0.855926513671875 +5809 0.870361328125 +5810 0.870361328125 +5811 0.862762451171875 +5812 0.79669189453125 +5813 0.595794677734375 +5814 0.362152099609375 +5815 0.1270751953125 +5816 -0.086944580078125 +5817 -0.2784423828125 +5818 -0.484832763671875 +5819 -0.729583740234375 +5820 -0.86688232421875 +5821 -0.870391845703125 +5822 -0.86859130859375 +5823 -0.86279296875 +5824 -0.817962646484375 +5825 -0.6116943359375 +5826 -0.3128662109375 +5827 0.039398193359375 +5828 0.422821044921875 +5829 0.805145263671875 +5830 0.870361328125 +5831 0.870361328125 +5832 0.860015869140625 +5833 0.727935791015625 +5834 0.48114013671875 +5835 0.2059326171875 +5836 -0.06103515625 +5837 -0.29913330078125 +5838 -0.516204833984375 +5839 -0.7252197265625 +5840 -0.85980224609375 +5841 -0.870391845703125 +5842 -0.870391845703125 +5843 -0.858062744140625 +5844 -0.673004150390625 +5845 -0.42694091796875 +5846 -0.2100830078125 +5847 -0.0362548828125 +5848 0.10943603515625 +5849 0.23516845703125 +5850 0.373687744140625 +5851 0.517791748046875 +5852 0.602783203125 +5853 0.635711669921875 +5854 0.655181884765625 +5855 0.65948486328125 +5856 0.651275634765625 +5857 0.61846923828125 +5858 0.53753662109375 +5859 0.404144287109375 +5860 0.22186279296875 +5861 0.003997802734375 +5862 -0.22100830078125 +5863 -0.42449951171875 +5864 -0.579833984375 +5865 -0.641876220703125 +5866 -0.6177978515625 +5867 -0.575531005859375 +5868 -0.526336669921875 +5869 -0.42645263671875 +5870 -0.2581787109375 +5871 -0.068695068359375 +5872 0.09222412109375 +5873 0.232147216796875 +5874 0.3509521484375 +5875 0.410064697265625 +5876 0.372955322265625 +5877 0.2554931640625 +5878 0.10711669921875 +5879 -0.052886962890625 +5880 -0.186279296875 +5881 -0.23291015625 +5882 -0.209442138671875 +5883 -0.174163818359375 +5884 -0.126739501953125 +5885 -0.048126220703125 +5886 0.0426025390625 +5887 0.10748291015625 +5888 0.1409912109375 +5889 0.19708251953125 +5890 0.273651123046875 +5891 0.31768798828125 +5892 0.341094970703125 +5893 0.368011474609375 +5894 0.37249755859375 +5895 0.30072021484375 +5896 0.1517333984375 +5897 -0.01470947265625 +5898 -0.1883544921875 +5899 -0.372711181640625 +5900 -0.51397705078125 +5901 -0.57177734375 +5902 -0.53948974609375 +5903 -0.43511962890625 +5904 -0.2962646484375 +5905 -0.161102294921875 +5906 -0.0435791015625 +5907 0.060394287109375 +5908 0.13665771484375 +5909 0.170135498046875 +5910 0.16552734375 +5911 0.15728759765625 +5912 0.150787353515625 +5913 0.12200927734375 +5914 0.080108642578125 +5915 0.05126953125 +5916 0.062896728515625 +5917 0.09271240234375 +5918 0.092987060546875 +5919 0.07855224609375 +5920 0.06427001953125 +5921 0.0347900390625 +5922 -0.01171875 +5923 -0.056060791015625 +5924 -0.055511474609375 +5925 -0.010467529296875 +5926 0.02508544921875 +5927 0.025665283203125 +5928 0.017333984375 +5929 0.00189208984375 +5930 -0.03173828125 +5931 -0.071502685546875 +5932 -0.13543701171875 +5933 -0.219970703125 +5934 -0.300506591796875 +5935 -0.376312255859375 +5936 -0.416107177734375 +5937 -0.371124267578125 +5938 -0.242279052734375 +5939 -0.069732666015625 +5940 0.125640869140625 +5941 0.31268310546875 +5942 0.45501708984375 +5943 0.554779052734375 +5944 0.61065673828125 +5945 0.610931396484375 +5946 0.531463623046875 +5947 0.3883056640625 +5948 0.23468017578125 +5949 0.095245361328125 +5950 -0.00396728515625 +5951 -0.04852294921875 +5952 -0.055145263671875 +5953 -0.0758056640625 +5954 -0.138702392578125 +5955 -0.209197998046875 +5956 -0.289031982421875 +5957 -0.37884521484375 +5958 -0.456329345703125 +5959 -0.51641845703125 +5960 -0.519287109375 +5961 -0.458251953125 +5962 -0.384796142578125 +5963 -0.323699951171875 +5964 -0.269287109375 +5965 -0.1951904296875 +5966 -0.100006103515625 +5967 -0.01055908203125 +5968 0.1033935546875 +5969 0.24908447265625 +5970 0.373199462890625 +5971 0.45806884765625 +5972 0.511474609375 +5973 0.565399169921875 +5974 0.61138916015625 +5975 0.5897216796875 +5976 0.4906005859375 +5977 0.33148193359375 +5978 0.147796630859375 +5979 -0.01873779296875 +5980 -0.140289306640625 +5981 -0.191986083984375 +5982 -0.184295654296875 +5983 -0.161834716796875 +5984 -0.166595458984375 +5985 -0.19390869140625 +5986 -0.22442626953125 +5987 -0.279754638671875 +5988 -0.3389892578125 +5989 -0.3543701171875 +5990 -0.348175048828125 +5991 -0.32598876953125 +5992 -0.2581787109375 +5993 -0.139801025390625 +5994 0.014617919921875 +5995 0.144378662109375 +5996 0.221038818359375 +5997 0.27069091796875 +5998 0.294036865234375 +5999 0.311767578125 +6000 0.339141845703125 +6001 0.360260009765625 +6002 0.360504150390625 +6003 0.308380126953125 +6004 0.18170166015625 +6005 0.0047607421875 +6006 -0.17559814453125 +6007 -0.3143310546875 +6008 -0.36785888671875 +6009 -0.36248779296875 +6010 -0.343536376953125 +6011 -0.3018798828125 +6012 -0.231414794921875 +6013 -0.117645263671875 +6014 0.007049560546875 +6015 0.087982177734375 +6016 0.13946533203125 +6017 0.17425537109375 +6018 0.188201904296875 +6019 0.171234130859375 +6020 0.118438720703125 +6021 0.05706787109375 +6022 -0.010711669921875 +6023 -0.0914306640625 +6024 -0.162322998046875 +6025 -0.194549560546875 +6026 -0.1492919921875 +6027 -0.02166748046875 +6028 0.124053955078125 +6029 0.211151123046875 +6030 0.240447998046875 +6031 0.242218017578125 +6032 0.2257080078125 +6033 0.194366455078125 +6034 0.115509033203125 +6035 0.0128173828125 +6036 -0.053802490234375 +6037 -0.110626220703125 +6038 -0.199493408203125 +6039 -0.29437255859375 +6040 -0.33221435546875 +6041 -0.27972412109375 +6042 -0.185333251953125 +6043 -0.128204345703125 +6044 -0.115692138671875 +6045 -0.116455078125 +6046 -0.105926513671875 +6047 -0.053955078125 +6048 0.048797607421875 +6049 0.157318115234375 +6050 0.212005615234375 +6051 0.218475341796875 +6052 0.23724365234375 +6053 0.30535888671875 +6054 0.38128662109375 +6055 0.404449462890625 +6056 0.3944091796875 +6057 0.3885498046875 +6058 0.362640380859375 +6059 0.27362060546875 +6060 0.11712646484375 +6061 -0.054901123046875 +6062 -0.19085693359375 +6063 -0.28570556640625 +6064 -0.339263916015625 +6065 -0.3775634765625 +6066 -0.445709228515625 +6067 -0.535064697265625 +6068 -0.629058837890625 +6069 -0.697601318359375 +6070 -0.70391845703125 +6071 -0.6424560546875 +6072 -0.491241455078125 +6073 -0.265716552734375 +6074 -0.023712158203125 +6075 0.201751708984375 +6076 0.375823974609375 +6077 0.485076904296875 +6078 0.56884765625 +6079 0.634765625 +6080 0.63763427734375 +6081 0.5660400390625 +6082 0.4720458984375 +6083 0.40692138671875 +6084 0.3778076171875 +6085 0.376953125 +6086 0.371978759765625 +6087 0.313140869140625 +6088 0.184417724609375 +6089 0.011199951171875 +6090 -0.171051025390625 +6091 -0.33740234375 +6092 -0.47198486328125 +6093 -0.560394287109375 +6094 -0.58056640625 +6095 -0.54754638671875 +6096 -0.508575439453125 +6097 -0.459503173828125 +6098 -0.394378662109375 +6099 -0.35260009765625 +6100 -0.31170654296875 +6101 -0.197418212890625 +6102 -0.007965087890625 +6103 0.207489013671875 +6104 0.409210205078125 +6105 0.57208251953125 +6106 0.66595458984375 +6107 0.65875244140625 +6108 0.56744384765625 +6109 0.431396484375 +6110 0.29443359375 +6111 0.182464599609375 +6112 0.06365966796875 +6113 -0.075958251953125 +6114 -0.189422607421875 +6115 -0.271942138671875 +6116 -0.342529296875 +6117 -0.364166259765625 +6118 -0.327239990234375 +6119 -0.2769775390625 +6120 -0.253692626953125 +6121 -0.24365234375 +6122 -0.1983642578125 +6123 -0.116241455078125 +6124 -0.036834716796875 +6125 0.034881591796875 +6126 0.09124755859375 +6127 0.10888671875 +6128 0.125518798828125 +6129 0.15771484375 +6130 0.17828369140625 +6131 0.17108154296875 +6132 0.129974365234375 +6133 0.082427978515625 +6134 0.027679443359375 +6135 -0.065643310546875 +6136 -0.15936279296875 +6137 -0.21307373046875 +6138 -0.234649658203125 +6139 -0.2001953125 +6140 -0.119171142578125 +6141 -0.024749755859375 +6142 0.085784912109375 +6143 0.178131103515625 +6144 0.215576171875 +6145 0.211456298828125 +6146 0.17523193359375 +6147 0.128753662109375 +6148 0.1019287109375 +6149 0.0743408203125 +6150 0.04327392578125 +6151 0.038177490234375 +6152 0.076263427734375 +6153 0.14105224609375 +6154 0.186431884765625 +6155 0.188812255859375 +6156 0.1390380859375 +6157 0.041778564453125 +6158 -0.079437255859375 +6159 -0.219390869140625 +6160 -0.367828369140625 +6161 -0.494873046875 +6162 -0.556243896484375 +6163 -0.508697509765625 +6164 -0.3756103515625 +6165 -0.218902587890625 +6166 -0.063751220703125 +6167 0.091552734375 +6168 0.23602294921875 +6169 0.342987060546875 +6170 0.39520263671875 +6171 0.389373779296875 +6172 0.324249267578125 +6173 0.224090576171875 +6174 0.124267578125 +6175 0.037078857421875 +6176 -0.010101318359375 +6177 -0.019439697265625 +6178 -0.022796630859375 +6179 -0.001556396484375 +6180 0.056304931640625 +6181 0.106719970703125 +6182 0.096893310546875 +6183 0.042694091796875 +6184 -0.018035888671875 +6185 -0.07586669921875 +6186 -0.11944580078125 +6187 -0.15972900390625 +6188 -0.202606201171875 +6189 -0.24859619140625 +6190 -0.30517578125 +6191 -0.36212158203125 +6192 -0.39141845703125 +6193 -0.35528564453125 +6194 -0.249969482421875 +6195 -0.092864990234375 +6196 0.08905029296875 +6197 0.2352294921875 +6198 0.318817138671875 +6199 0.358642578125 +6200 0.347747802734375 +6201 0.28564453125 +6202 0.223175048828125 +6203 0.196746826171875 +6204 0.179840087890625 +6205 0.155548095703125 +6206 0.151214599609375 +6207 0.156951904296875 +6208 0.13177490234375 +6209 0.100799560546875 +6210 0.087127685546875 +6211 0.05487060546875 +6212 -0.009002685546875 +6213 -0.10400390625 +6214 -0.229400634765625 +6215 -0.35552978515625 +6216 -0.441925048828125 +6217 -0.473846435546875 +6218 -0.464813232421875 +6219 -0.419097900390625 +6220 -0.334320068359375 +6221 -0.227935791015625 +6222 -0.12347412109375 +6223 -0.02764892578125 +6224 0.077667236328125 +6225 0.2132568359375 +6226 0.38885498046875 +6227 0.582794189453125 +6228 0.734039306640625 +6229 0.800140380859375 +6230 0.7783203125 +6231 0.6651611328125 +6232 0.45965576171875 +6233 0.199188232421875 +6234 -0.050689697265625 +6235 -0.23297119140625 +6236 -0.33013916015625 +6237 -0.368408203125 +6238 -0.378936767578125 +6239 -0.376983642578125 +6240 -0.37969970703125 +6241 -0.391510009765625 +6242 -0.385345458984375 +6243 -0.3419189453125 +6244 -0.28289794921875 +6245 -0.251617431640625 +6246 -0.266143798828125 +6247 -0.273345947265625 +6248 -0.216796875 +6249 -0.128265380859375 +6250 -0.068145751953125 +6251 -0.0430908203125 +6252 -0.024444580078125 +6253 0.020721435546875 +6254 0.124481201171875 +6255 0.25787353515625 +6256 0.379119873046875 +6257 0.47991943359375 +6258 0.5281982421875 +6259 0.511138916015625 +6260 0.456207275390625 +6261 0.407470703125 +6262 0.383758544921875 +6263 0.35687255859375 +6264 0.31182861328125 +6265 0.250885009765625 +6266 0.1654052734375 +6267 0.035247802734375 +6268 -0.142059326171875 +6269 -0.33563232421875 +6270 -0.5345458984375 +6271 -0.72186279296875 +6272 -0.836669921875 +6273 -0.8326416015625 +6274 -0.7296142578125 +6275 -0.582550048828125 +6276 -0.440093994140625 +6277 -0.324310302734375 +6278 -0.20147705078125 +6279 -0.044647216796875 +6280 0.103973388671875 +6281 0.202392578125 +6282 0.264495849609375 +6283 0.338897705078125 +6284 0.443817138671875 +6285 0.545074462890625 +6286 0.6173095703125 +6287 0.6524658203125 +6288 0.66339111328125 +6289 0.6561279296875 +6290 0.606781005859375 +6291 0.501190185546875 +6292 0.352783203125 +6293 0.176544189453125 +6294 -0.034820556640625 +6295 -0.258209228515625 +6296 -0.44244384765625 +6297 -0.5753173828125 +6298 -0.65203857421875 +6299 -0.641632080078125 +6300 -0.562164306640625 +6301 -0.458038330078125 +6302 -0.350555419921875 +6303 -0.260528564453125 +6304 -0.192108154296875 +6305 -0.141937255859375 +6306 -0.1021728515625 +6307 -0.062896728515625 +6308 -0.011932373046875 +6309 0.062835693359375 +6310 0.148712158203125 +6311 0.241729736328125 +6312 0.34912109375 +6313 0.457305908203125 +6314 0.54388427734375 +6315 0.5728759765625 +6316 0.506591796875 +6317 0.351226806640625 +6318 0.146514892578125 +6319 -0.05523681640625 +6320 -0.21624755859375 +6321 -0.334930419921875 +6322 -0.402984619140625 +6323 -0.4412841796875 +6324 -0.49578857421875 +6325 -0.5601806640625 +6326 -0.600738525390625 +6327 -0.584228515625 +6328 -0.47930908203125 +6329 -0.27935791015625 +6330 -0.0089111328125 +6331 0.268798828125 +6332 0.482818603515625 +6333 0.60369873046875 +6334 0.650421142578125 +6335 0.66400146484375 +6336 0.6414794921875 +6337 0.572540283203125 +6338 0.498138427734375 +6339 0.439453125 +6340 0.375518798828125 +6341 0.274505615234375 +6342 0.1087646484375 +6343 -0.099395751953125 +6344 -0.3182373046875 +6345 -0.5489501953125 +6346 -0.7738037109375 +6347 -0.86383056640625 +6348 -0.870391845703125 +6349 -0.86895751953125 +6350 -0.861053466796875 +6351 -0.765869140625 +6352 -0.5301513671875 +6353 -0.214691162109375 +6354 0.137359619140625 +6355 0.474822998046875 +6356 0.76239013671875 +6357 0.867462158203125 +6358 0.870361328125 +6359 0.86480712890625 +6360 0.831817626953125 +6361 0.677581787109375 +6362 0.495880126953125 +6363 0.30767822265625 +6364 0.116180419921875 +6365 -0.110748291015625 +6366 -0.381805419921875 +6367 -0.6572265625 +6368 -0.857421875 +6369 -0.870391845703125 +6370 -0.870391845703125 +6371 -0.86444091796875 +6372 -0.85723876953125 +6373 -0.790008544921875 +6374 -0.62847900390625 +6375 -0.3956298828125 +6376 -0.126708984375 +6377 0.150115966796875 +6378 0.424041748046875 +6379 0.670623779296875 +6380 0.854522705078125 +6381 0.866485595703125 +6382 0.86920166015625 +6383 0.8653564453125 +6384 0.857147216796875 +6385 0.766845703125 +6386 0.628509521484375 +6387 0.462127685546875 +6388 0.297210693359375 +6389 0.14862060546875 +6390 -0.00537109375 +6391 -0.15753173828125 +6392 -0.31304931640625 +6393 -0.48876953125 +6394 -0.6416015625 +6395 -0.751373291015625 +6396 -0.84619140625 +6397 -0.861297607421875 +6398 -0.863250732421875 +6399 -0.856597900390625 +6400 -0.7498779296875 +6401 -0.624542236328125 +6402 -0.47808837890625 +6403 -0.253387451171875 +6404 0.003692626953125 +6405 0.2257080078125 +6406 0.427154541015625 +6407 0.643218994140625 +6408 0.855926513671875 +6409 0.870361328125 +6410 0.870361328125 +6411 0.862762451171875 +6412 0.79669189453125 +6413 0.595794677734375 +6414 0.362152099609375 +6415 0.1270751953125 +6416 -0.086944580078125 +6417 -0.2784423828125 +6418 -0.484832763671875 +6419 -0.729583740234375 +6420 -0.86688232421875 +6421 -0.870391845703125 +6422 -0.86859130859375 +6423 -0.86279296875 +6424 -0.817962646484375 +6425 -0.6116943359375 +6426 -0.3128662109375 +6427 0.039398193359375 +6428 0.422821044921875 +6429 0.805145263671875 +6430 0.870361328125 +6431 0.870361328125 +6432 0.860015869140625 +6433 0.727935791015625 +6434 0.48114013671875 +6435 0.2059326171875 +6436 -0.06103515625 +6437 -0.29913330078125 +6438 -0.516204833984375 +6439 -0.7252197265625 +6440 -0.85980224609375 +6441 -0.870391845703125 +6442 -0.870391845703125 +6443 -0.858062744140625 +6444 -0.673004150390625 +6445 -0.42694091796875 +6446 -0.2100830078125 +6447 -0.0362548828125 +6448 0.10943603515625 +6449 0.23516845703125 +6450 0.373687744140625 +6451 0.517791748046875 +6452 0.602783203125 +6453 0.635711669921875 +6454 0.655181884765625 +6455 0.65948486328125 +6456 0.651275634765625 +6457 0.61846923828125 +6458 0.53753662109375 +6459 0.404144287109375 +6460 0.22186279296875 +6461 0.003997802734375 +6462 -0.22100830078125 +6463 -0.42449951171875 +6464 -0.579833984375 +6465 -0.641876220703125 +6466 -0.6177978515625 +6467 -0.575531005859375 +6468 -0.526336669921875 +6469 -0.42645263671875 +6470 -0.2581787109375 +6471 -0.068695068359375 +6472 0.09222412109375 +6473 0.232147216796875 +6474 0.3509521484375 +6475 0.410064697265625 +6476 0.372955322265625 +6477 0.2554931640625 +6478 0.10711669921875 +6479 -0.052886962890625 +6480 -0.186279296875 +6481 -0.23291015625 +6482 -0.209442138671875 +6483 -0.174163818359375 +6484 -0.126739501953125 +6485 -0.048126220703125 +6486 0.0426025390625 +6487 0.10748291015625 +6488 0.1409912109375 +6489 0.19708251953125 +6490 0.273651123046875 +6491 0.31768798828125 +6492 0.341094970703125 +6493 0.368011474609375 +6494 0.37249755859375 +6495 0.30072021484375 +6496 0.1517333984375 +6497 -0.01470947265625 +6498 -0.1883544921875 +6499 -0.372711181640625 +6500 -0.51397705078125 +6501 -0.57177734375 +6502 -0.53948974609375 +6503 -0.43511962890625 +6504 -0.2962646484375 +6505 -0.161102294921875 +6506 -0.0435791015625 +6507 0.060394287109375 +6508 0.13665771484375 +6509 0.170135498046875 +6510 0.16552734375 +6511 0.15728759765625 +6512 0.150787353515625 +6513 0.12200927734375 +6514 0.080108642578125 +6515 0.05126953125 +6516 0.062896728515625 +6517 0.09271240234375 +6518 0.092987060546875 +6519 0.07855224609375 +6520 0.06427001953125 +6521 0.0347900390625 +6522 -0.01171875 +6523 -0.056060791015625 +6524 -0.055511474609375 +6525 -0.010467529296875 +6526 0.02508544921875 +6527 0.025665283203125 +6528 0.017333984375 +6529 0.00189208984375 +6530 -0.03173828125 +6531 -0.071502685546875 +6532 -0.13543701171875 +6533 -0.219970703125 +6534 -0.300506591796875 +6535 -0.376312255859375 +6536 -0.416107177734375 +6537 -0.371124267578125 +6538 -0.242279052734375 +6539 -0.069732666015625 +6540 0.125640869140625 +6541 0.31268310546875 +6542 0.45501708984375 +6543 0.554779052734375 +6544 0.61065673828125 +6545 0.610931396484375 +6546 0.531463623046875 +6547 0.3883056640625 +6548 0.23468017578125 +6549 0.095245361328125 +6550 -0.00396728515625 +6551 -0.04852294921875 +6552 -0.055145263671875 +6553 -0.0758056640625 +6554 -0.138702392578125 +6555 -0.209197998046875 +6556 -0.289031982421875 +6557 -0.37884521484375 +6558 -0.456329345703125 +6559 -0.51641845703125 +6560 -0.519287109375 +6561 -0.458251953125 +6562 -0.384796142578125 +6563 -0.323699951171875 +6564 -0.269287109375 +6565 -0.1951904296875 +6566 -0.100006103515625 +6567 -0.01055908203125 +6568 0.1033935546875 +6569 0.24908447265625 +6570 0.373199462890625 +6571 0.45806884765625 +6572 0.511474609375 +6573 0.565399169921875 +6574 0.61138916015625 +6575 0.5897216796875 +6576 0.4906005859375 +6577 0.33148193359375 +6578 0.147796630859375 +6579 -0.01873779296875 +6580 -0.140289306640625 +6581 -0.191986083984375 +6582 -0.184295654296875 +6583 -0.161834716796875 +6584 -0.166595458984375 +6585 -0.19390869140625 +6586 -0.22442626953125 +6587 -0.279754638671875 +6588 -0.3389892578125 +6589 -0.3543701171875 +6590 -0.348175048828125 +6591 -0.32598876953125 +6592 -0.2581787109375 +6593 -0.139801025390625 +6594 0.014617919921875 +6595 0.144378662109375 +6596 0.221038818359375 +6597 0.27069091796875 +6598 0.294036865234375 +6599 0.311767578125 +6600 0.339141845703125 +6601 0.360260009765625 +6602 0.360504150390625 +6603 0.308380126953125 +6604 0.18170166015625 +6605 0.0047607421875 +6606 -0.17559814453125 +6607 -0.3143310546875 +6608 -0.36785888671875 +6609 -0.36248779296875 +6610 -0.343536376953125 +6611 -0.3018798828125 +6612 -0.231414794921875 +6613 -0.117645263671875 +6614 0.007049560546875 +6615 0.087982177734375 +6616 0.13946533203125 +6617 0.17425537109375 +6618 0.188201904296875 +6619 0.171234130859375 +6620 0.118438720703125 +6621 0.05706787109375 +6622 -0.010711669921875 +6623 -0.0914306640625 +6624 -0.162322998046875 +6625 -0.194549560546875 +6626 -0.1492919921875 +6627 -0.02166748046875 +6628 0.124053955078125 +6629 0.211151123046875 +6630 0.240447998046875 +6631 0.242218017578125 +6632 0.2257080078125 +6633 0.194366455078125 +6634 0.115509033203125 +6635 0.0128173828125 +6636 -0.053802490234375 +6637 -0.110626220703125 +6638 -0.199493408203125 +6639 -0.29437255859375 +6640 -0.33221435546875 +6641 -0.27972412109375 +6642 -0.185333251953125 +6643 -0.128204345703125 +6644 -0.115692138671875 +6645 -0.116455078125 +6646 -0.105926513671875 +6647 -0.053955078125 +6648 0.048797607421875 +6649 0.157318115234375 +6650 0.212005615234375 +6651 0.218475341796875 +6652 0.23724365234375 +6653 0.30535888671875 +6654 0.38128662109375 +6655 0.404449462890625 +6656 0.3944091796875 +6657 0.3885498046875 +6658 0.362640380859375 +6659 0.27362060546875 +6660 0.11712646484375 +6661 -0.054901123046875 +6662 -0.19085693359375 +6663 -0.28570556640625 +6664 -0.339263916015625 +6665 -0.3775634765625 +6666 -0.445709228515625 +6667 -0.535064697265625 +6668 -0.629058837890625 +6669 -0.697601318359375 +6670 -0.70391845703125 +6671 -0.6424560546875 +6672 -0.491241455078125 +6673 -0.265716552734375 +6674 -0.023712158203125 +6675 0.201751708984375 +6676 0.375823974609375 +6677 0.485076904296875 +6678 0.56884765625 +6679 0.634765625 +6680 0.63763427734375 +6681 0.5660400390625 +6682 0.4720458984375 +6683 0.40692138671875 +6684 0.3778076171875 +6685 0.376953125 +6686 0.371978759765625 +6687 0.313140869140625 +6688 0.184417724609375 +6689 0.011199951171875 +6690 -0.171051025390625 +6691 -0.33740234375 +6692 -0.47198486328125 +6693 -0.560394287109375 +6694 -0.58056640625 +6695 -0.54754638671875 +6696 -0.508575439453125 +6697 -0.459503173828125 +6698 -0.394378662109375 +6699 -0.35260009765625 +6700 -0.31170654296875 +6701 -0.197418212890625 +6702 -0.007965087890625 +6703 0.207489013671875 +6704 0.409210205078125 +6705 0.57208251953125 +6706 0.66595458984375 +6707 0.65875244140625 +6708 0.56744384765625 +6709 0.431396484375 +6710 0.29443359375 +6711 0.182464599609375 +6712 0.06365966796875 +6713 -0.075958251953125 +6714 -0.189422607421875 +6715 -0.271942138671875 +6716 -0.342529296875 +6717 -0.364166259765625 +6718 -0.327239990234375 +6719 -0.2769775390625 +6720 -0.253692626953125 +6721 -0.24365234375 +6722 -0.1983642578125 +6723 -0.116241455078125 +6724 -0.036834716796875 +6725 0.034881591796875 +6726 0.09124755859375 +6727 0.10888671875 +6728 0.125518798828125 +6729 0.15771484375 +6730 0.17828369140625 +6731 0.17108154296875 +6732 0.129974365234375 +6733 0.082427978515625 +6734 0.027679443359375 +6735 -0.065643310546875 +6736 -0.15936279296875 +6737 -0.21307373046875 +6738 -0.234649658203125 +6739 -0.2001953125 +6740 -0.119171142578125 +6741 -0.024749755859375 +6742 0.085784912109375 +6743 0.178131103515625 +6744 0.215576171875 +6745 0.211456298828125 +6746 0.17523193359375 +6747 0.128753662109375 +6748 0.1019287109375 +6749 0.0743408203125 +6750 0.04327392578125 +6751 0.038177490234375 +6752 0.076263427734375 +6753 0.14105224609375 +6754 0.186431884765625 +6755 0.188812255859375 +6756 0.1390380859375 +6757 0.041778564453125 +6758 -0.079437255859375 +6759 -0.219390869140625 +6760 -0.367828369140625 +6761 -0.494873046875 +6762 -0.556243896484375 +6763 -0.508697509765625 +6764 -0.3756103515625 +6765 -0.218902587890625 +6766 -0.063751220703125 +6767 0.091552734375 +6768 0.23602294921875 +6769 0.342987060546875 +6770 0.39520263671875 +6771 0.389373779296875 +6772 0.324249267578125 +6773 0.224090576171875 +6774 0.124267578125 +6775 0.037078857421875 +6776 -0.010101318359375 +6777 -0.019439697265625 +6778 -0.022796630859375 +6779 -0.001556396484375 +6780 0.056304931640625 +6781 0.106719970703125 +6782 0.096893310546875 +6783 0.042694091796875 +6784 -0.018035888671875 +6785 -0.07586669921875 +6786 -0.11944580078125 +6787 -0.15972900390625 +6788 -0.202606201171875 +6789 -0.24859619140625 +6790 -0.30517578125 +6791 -0.36212158203125 +6792 -0.39141845703125 +6793 -0.35528564453125 +6794 -0.249969482421875 +6795 -0.092864990234375 +6796 0.08905029296875 +6797 0.2352294921875 +6798 0.318817138671875 +6799 0.358642578125 +6800 0.347747802734375 +6801 0.28564453125 +6802 0.223175048828125 +6803 0.196746826171875 +6804 0.179840087890625 +6805 0.155548095703125 +6806 0.151214599609375 +6807 0.156951904296875 +6808 0.13177490234375 +6809 0.100799560546875 +6810 0.087127685546875 +6811 0.05487060546875 +6812 -0.009002685546875 +6813 -0.10400390625 +6814 -0.229400634765625 +6815 -0.35552978515625 +6816 -0.441925048828125 +6817 -0.473846435546875 +6818 -0.464813232421875 +6819 -0.419097900390625 +6820 -0.334320068359375 +6821 -0.227935791015625 +6822 -0.12347412109375 +6823 -0.02764892578125 +6824 0.077667236328125 +6825 0.2132568359375 +6826 0.38885498046875 +6827 0.582794189453125 +6828 0.734039306640625 +6829 0.800140380859375 +6830 0.7783203125 +6831 0.6651611328125 +6832 0.45965576171875 +6833 0.199188232421875 +6834 -0.050689697265625 +6835 -0.23297119140625 +6836 -0.33013916015625 +6837 -0.368408203125 +6838 -0.378936767578125 +6839 -0.376983642578125 +6840 -0.37969970703125 +6841 -0.391510009765625 +6842 -0.385345458984375 +6843 -0.3419189453125 +6844 -0.28289794921875 +6845 -0.251617431640625 +6846 -0.266143798828125 +6847 -0.273345947265625 +6848 -0.216796875 +6849 -0.128265380859375 +6850 -0.068145751953125 +6851 -0.0430908203125 +6852 -0.024444580078125 +6853 0.020721435546875 +6854 0.124481201171875 +6855 0.25787353515625 +6856 0.379119873046875 +6857 0.47991943359375 +6858 0.5281982421875 +6859 0.511138916015625 +6860 0.456207275390625 +6861 0.407470703125 +6862 0.383758544921875 +6863 0.35687255859375 +6864 0.31182861328125 +6865 0.250885009765625 +6866 0.1654052734375 +6867 0.035247802734375 +6868 -0.142059326171875 +6869 -0.33563232421875 +6870 -0.5345458984375 +6871 -0.72186279296875 +6872 -0.836669921875 +6873 -0.8326416015625 +6874 -0.7296142578125 +6875 -0.582550048828125 +6876 -0.440093994140625 +6877 -0.324310302734375 +6878 -0.20147705078125 +6879 -0.044647216796875 +6880 0.103973388671875 +6881 0.202392578125 +6882 0.264495849609375 +6883 0.338897705078125 +6884 0.443817138671875 +6885 0.545074462890625 +6886 0.6173095703125 +6887 0.6524658203125 +6888 0.66339111328125 +6889 0.6561279296875 +6890 0.606781005859375 +6891 0.501190185546875 +6892 0.352783203125 +6893 0.176544189453125 +6894 -0.034820556640625 +6895 -0.258209228515625 +6896 -0.44244384765625 +6897 -0.5753173828125 +6898 -0.65203857421875 +6899 -0.641632080078125 +6900 -0.562164306640625 +6901 -0.458038330078125 +6902 -0.350555419921875 +6903 -0.260528564453125 +6904 -0.192108154296875 +6905 -0.141937255859375 +6906 -0.1021728515625 +6907 -0.062896728515625 +6908 -0.011932373046875 +6909 0.062835693359375 +6910 0.148712158203125 +6911 0.241729736328125 +6912 0.34912109375 +6913 0.457305908203125 +6914 0.54388427734375 +6915 0.5728759765625 +6916 0.506591796875 +6917 0.351226806640625 +6918 0.146514892578125 +6919 -0.05523681640625 +6920 -0.21624755859375 +6921 -0.334930419921875 +6922 -0.402984619140625 +6923 -0.4412841796875 +6924 -0.49578857421875 +6925 -0.5601806640625 +6926 -0.600738525390625 +6927 -0.584228515625 +6928 -0.47930908203125 +6929 -0.27935791015625 +6930 -0.0089111328125 +6931 0.268798828125 +6932 0.482818603515625 +6933 0.60369873046875 +6934 0.650421142578125 +6935 0.66400146484375 +6936 0.6414794921875 +6937 0.572540283203125 +6938 0.498138427734375 +6939 0.439453125 +6940 0.375518798828125 +6941 0.274505615234375 +6942 0.1087646484375 +6943 -0.099395751953125 +6944 -0.3182373046875 +6945 -0.5489501953125 +6946 -0.7738037109375 +6947 -0.86383056640625 +6948 -0.870391845703125 +6949 -0.86895751953125 +6950 -0.861053466796875 +6951 -0.765869140625 +6952 -0.5301513671875 +6953 -0.214691162109375 +6954 0.137359619140625 +6955 0.474822998046875 +6956 0.76239013671875 +6957 0.867462158203125 +6958 0.870361328125 +6959 0.86480712890625 +6960 0.831817626953125 +6961 0.677581787109375 +6962 0.495880126953125 +6963 0.30767822265625 +6964 0.116180419921875 +6965 -0.110748291015625 +6966 -0.381805419921875 +6967 -0.6572265625 +6968 -0.857421875 +6969 -0.870391845703125 +6970 -0.870391845703125 +6971 -0.86444091796875 +6972 -0.85723876953125 +6973 -0.790008544921875 +6974 -0.62847900390625 +6975 -0.3956298828125 +6976 -0.126708984375 +6977 0.150115966796875 +6978 0.424041748046875 +6979 0.670623779296875 +6980 0.854522705078125 +6981 0.866485595703125 +6982 0.86920166015625 +6983 0.8653564453125 +6984 0.857147216796875 +6985 0.766845703125 +6986 0.628509521484375 +6987 0.462127685546875 +6988 0.297210693359375 +6989 0.14862060546875 +6990 -0.00537109375 +6991 -0.15753173828125 +6992 -0.31304931640625 +6993 -0.48876953125 +6994 -0.6416015625 +6995 -0.751373291015625 +6996 -0.84619140625 +6997 -0.861297607421875 +6998 -0.863250732421875 +6999 -0.856597900390625 +7000 -0.7498779296875 +7001 -0.624542236328125 +7002 -0.47808837890625 +7003 -0.253387451171875 +7004 0.003692626953125 +7005 0.2257080078125 +7006 0.427154541015625 +7007 0.643218994140625 +7008 0.855926513671875 +7009 0.870361328125 +7010 0.870361328125 +7011 0.862762451171875 +7012 0.79669189453125 +7013 0.595794677734375 +7014 0.362152099609375 +7015 0.1270751953125 +7016 -0.086944580078125 +7017 -0.2784423828125 +7018 -0.484832763671875 +7019 -0.729583740234375 +7020 -0.86688232421875 +7021 -0.870391845703125 +7022 -0.86859130859375 +7023 -0.86279296875 +7024 -0.817962646484375 +7025 -0.6116943359375 +7026 -0.3128662109375 +7027 0.039398193359375 +7028 0.422821044921875 +7029 0.805145263671875 +7030 0.870361328125 +7031 0.870361328125 +7032 0.860015869140625 +7033 0.727935791015625 +7034 0.48114013671875 +7035 0.2059326171875 +7036 -0.06103515625 +7037 -0.29913330078125 +7038 -0.516204833984375 +7039 -0.7252197265625 +7040 -0.85980224609375 +7041 -0.870391845703125 +7042 -0.870391845703125 +7043 -0.858062744140625 +7044 -0.673004150390625 +7045 -0.42694091796875 +7046 -0.2100830078125 +7047 -0.0362548828125 +7048 0.10943603515625 +7049 0.23516845703125 +7050 0.373687744140625 +7051 0.517791748046875 +7052 0.602783203125 +7053 0.635711669921875 +7054 0.655181884765625 +7055 0.65948486328125 +7056 0.651275634765625 +7057 0.61846923828125 +7058 0.53753662109375 +7059 0.404144287109375 +7060 0.22186279296875 +7061 0.003997802734375 +7062 -0.22100830078125 +7063 -0.42449951171875 +7064 -0.579833984375 +7065 -0.641876220703125 +7066 -0.6177978515625 +7067 -0.575531005859375 +7068 -0.526336669921875 +7069 -0.42645263671875 +7070 -0.2581787109375 +7071 -0.068695068359375 +7072 0.09222412109375 +7073 0.232147216796875 +7074 0.3509521484375 +7075 0.410064697265625 +7076 0.372955322265625 +7077 0.2554931640625 +7078 0.10711669921875 +7079 -0.052886962890625 +7080 -0.186279296875 +7081 -0.23291015625 +7082 -0.209442138671875 +7083 -0.174163818359375 +7084 -0.126739501953125 +7085 -0.048126220703125 +7086 0.0426025390625 +7087 0.10748291015625 +7088 0.1409912109375 +7089 0.19708251953125 +7090 0.273651123046875 +7091 0.31768798828125 +7092 0.341094970703125 +7093 0.368011474609375 +7094 0.37249755859375 +7095 0.30072021484375 +7096 0.1517333984375 +7097 -0.01470947265625 +7098 -0.1883544921875 +7099 -0.372711181640625 +7100 -0.51397705078125 +7101 -0.57177734375 +7102 -0.53948974609375 +7103 -0.43511962890625 +7104 -0.2962646484375 +7105 -0.161102294921875 +7106 -0.0435791015625 +7107 0.060394287109375 +7108 0.13665771484375 +7109 0.170135498046875 +7110 0.16552734375 +7111 0.15728759765625 +7112 0.150787353515625 +7113 0.12200927734375 +7114 0.080108642578125 +7115 0.05126953125 +7116 0.062896728515625 +7117 0.09271240234375 +7118 0.092987060546875 +7119 0.07855224609375 +7120 0.06427001953125 +7121 0.0347900390625 +7122 -0.01171875 +7123 -0.056060791015625 +7124 -0.055511474609375 +7125 -0.010467529296875 +7126 0.02508544921875 +7127 0.025665283203125 +7128 0.017333984375 +7129 0.00189208984375 +7130 -0.03173828125 +7131 -0.071502685546875 +7132 -0.13543701171875 +7133 -0.219970703125 +7134 -0.300506591796875 +7135 -0.376312255859375 +7136 -0.416107177734375 +7137 -0.371124267578125 +7138 -0.242279052734375 +7139 -0.069732666015625 +7140 0.125640869140625 +7141 0.31268310546875 +7142 0.45501708984375 +7143 0.554779052734375 +7144 0.61065673828125 +7145 0.610931396484375 +7146 0.531463623046875 +7147 0.3883056640625 +7148 0.23468017578125 +7149 0.095245361328125 +7150 -0.00396728515625 +7151 -0.04852294921875 +7152 -0.055145263671875 +7153 -0.0758056640625 +7154 -0.138702392578125 +7155 -0.209197998046875 +7156 -0.289031982421875 +7157 -0.37884521484375 +7158 -0.456329345703125 +7159 -0.51641845703125 +7160 -0.519287109375 +7161 -0.458251953125 +7162 -0.384796142578125 +7163 -0.323699951171875 +7164 -0.269287109375 +7165 -0.1951904296875 +7166 -0.100006103515625 +7167 -0.01055908203125 +7168 0.1033935546875 +7169 0.24908447265625 +7170 0.373199462890625 +7171 0.45806884765625 +7172 0.511474609375 +7173 0.565399169921875 +7174 0.61138916015625 +7175 0.5897216796875 +7176 0.4906005859375 +7177 0.33148193359375 +7178 0.147796630859375 +7179 -0.01873779296875 +7180 -0.140289306640625 +7181 -0.191986083984375 +7182 -0.184295654296875 +7183 -0.161834716796875 +7184 -0.166595458984375 +7185 -0.19390869140625 +7186 -0.22442626953125 +7187 -0.279754638671875 +7188 -0.3389892578125 +7189 -0.3543701171875 +7190 -0.348175048828125 +7191 -0.32598876953125 +7192 -0.2581787109375 +7193 -0.139801025390625 +7194 0.014617919921875 +7195 0.144378662109375 +7196 0.221038818359375 +7197 0.27069091796875 +7198 0.294036865234375 +7199 0.311767578125 +7200 0.339141845703125 +7201 0.360260009765625 +7202 0.360504150390625 +7203 0.308380126953125 +7204 0.18170166015625 +7205 0.0047607421875 +7206 -0.17559814453125 +7207 -0.3143310546875 +7208 -0.36785888671875 +7209 -0.36248779296875 +7210 -0.343536376953125 +7211 -0.3018798828125 +7212 -0.231414794921875 +7213 -0.117645263671875 +7214 0.007049560546875 +7215 0.087982177734375 +7216 0.13946533203125 +7217 0.17425537109375 +7218 0.188201904296875 +7219 0.171234130859375 +7220 0.118438720703125 +7221 0.05706787109375 +7222 -0.010711669921875 +7223 -0.0914306640625 +7224 -0.162322998046875 +7225 -0.194549560546875 +7226 -0.1492919921875 +7227 -0.02166748046875 +7228 0.124053955078125 +7229 0.211151123046875 +7230 0.240447998046875 +7231 0.242218017578125 +7232 0.2257080078125 +7233 0.194366455078125 +7234 0.115509033203125 +7235 0.0128173828125 +7236 -0.053802490234375 +7237 -0.110626220703125 +7238 -0.199493408203125 +7239 -0.29437255859375 +7240 -0.33221435546875 +7241 -0.27972412109375 +7242 -0.185333251953125 +7243 -0.128204345703125 +7244 -0.115692138671875 +7245 -0.116455078125 +7246 -0.105926513671875 +7247 -0.053955078125 +7248 0.048797607421875 +7249 0.157318115234375 +7250 0.212005615234375 +7251 0.218475341796875 +7252 0.23724365234375 +7253 0.30535888671875 +7254 0.38128662109375 +7255 0.404449462890625 +7256 0.3944091796875 +7257 0.3885498046875 +7258 0.362640380859375 +7259 0.27362060546875 +7260 0.11712646484375 +7261 -0.054901123046875 +7262 -0.19085693359375 +7263 -0.28570556640625 +7264 -0.339263916015625 +7265 -0.3775634765625 +7266 -0.445709228515625 +7267 -0.535064697265625 +7268 -0.629058837890625 +7269 -0.697601318359375 +7270 -0.70391845703125 +7271 -0.6424560546875 +7272 -0.491241455078125 +7273 -0.265716552734375 +7274 -0.023712158203125 +7275 0.201751708984375 +7276 0.375823974609375 +7277 0.485076904296875 +7278 0.56884765625 +7279 0.634765625 +7280 0.63763427734375 +7281 0.5660400390625 +7282 0.4720458984375 +7283 0.40692138671875 +7284 0.3778076171875 +7285 0.376953125 +7286 0.371978759765625 +7287 0.313140869140625 +7288 0.184417724609375 +7289 0.011199951171875 +7290 -0.171051025390625 +7291 -0.33740234375 +7292 -0.47198486328125 +7293 -0.560394287109375 +7294 -0.58056640625 +7295 -0.54754638671875 +7296 -0.508575439453125 +7297 -0.459503173828125 +7298 -0.394378662109375 +7299 -0.35260009765625 +7300 -0.31170654296875 +7301 -0.197418212890625 +7302 -0.007965087890625 +7303 0.207489013671875 +7304 0.409210205078125 +7305 0.57208251953125 +7306 0.66595458984375 +7307 0.65875244140625 +7308 0.56744384765625 +7309 0.431396484375 +7310 0.29443359375 +7311 0.182464599609375 +7312 0.06365966796875 +7313 -0.075958251953125 +7314 -0.189422607421875 +7315 -0.271942138671875 +7316 -0.342529296875 +7317 -0.364166259765625 +7318 -0.327239990234375 +7319 -0.2769775390625 +7320 -0.253692626953125 +7321 -0.24365234375 +7322 -0.1983642578125 +7323 -0.116241455078125 +7324 -0.036834716796875 +7325 0.034881591796875 +7326 0.09124755859375 +7327 0.10888671875 +7328 0.125518798828125 +7329 0.15771484375 +7330 0.17828369140625 +7331 0.17108154296875 +7332 0.129974365234375 +7333 0.082427978515625 +7334 0.027679443359375 +7335 -0.065643310546875 +7336 -0.15936279296875 +7337 -0.21307373046875 +7338 -0.234649658203125 +7339 -0.2001953125 +7340 -0.119171142578125 +7341 -0.024749755859375 +7342 0.085784912109375 +7343 0.178131103515625 +7344 0.215576171875 +7345 0.211456298828125 +7346 0.17523193359375 +7347 0.128753662109375 +7348 0.1019287109375 +7349 0.0743408203125 +7350 0.04327392578125 +7351 0.038177490234375 +7352 0.076263427734375 +7353 0.14105224609375 +7354 0.186431884765625 +7355 0.188812255859375 +7356 0.1390380859375 +7357 0.041778564453125 +7358 -0.079437255859375 +7359 -0.219390869140625 +7360 -0.367828369140625 +7361 -0.494873046875 +7362 -0.556243896484375 +7363 -0.508697509765625 +7364 -0.3756103515625 +7365 -0.218902587890625 +7366 -0.063751220703125 +7367 0.091552734375 +7368 0.23602294921875 +7369 0.342987060546875 +7370 0.39520263671875 +7371 0.389373779296875 +7372 0.324249267578125 +7373 0.224090576171875 +7374 0.124267578125 +7375 0.037078857421875 +7376 -0.010101318359375 +7377 -0.019439697265625 +7378 -0.022796630859375 +7379 -0.001556396484375 +7380 0.056304931640625 +7381 0.106719970703125 +7382 0.096893310546875 +7383 0.042694091796875 +7384 -0.018035888671875 +7385 -0.07586669921875 +7386 -0.11944580078125 +7387 -0.15972900390625 +7388 -0.202606201171875 +7389 -0.24859619140625 +7390 -0.30517578125 +7391 -0.36212158203125 +7392 -0.39141845703125 +7393 -0.35528564453125 +7394 -0.249969482421875 +7395 -0.092864990234375 +7396 0.08905029296875 +7397 0.2352294921875 +7398 0.318817138671875 +7399 0.358642578125 +7400 0.347747802734375 +7401 0.28564453125 +7402 0.223175048828125 +7403 0.196746826171875 +7404 0.179840087890625 +7405 0.155548095703125 +7406 0.151214599609375 +7407 0.156951904296875 +7408 0.13177490234375 +7409 0.100799560546875 +7410 0.087127685546875 +7411 0.05487060546875 +7412 -0.009002685546875 +7413 -0.10400390625 +7414 -0.229400634765625 +7415 -0.35552978515625 +7416 -0.441925048828125 +7417 -0.473846435546875 +7418 -0.464813232421875 +7419 -0.419097900390625 +7420 -0.334320068359375 +7421 -0.227935791015625 +7422 -0.12347412109375 +7423 -0.02764892578125 +7424 0.077667236328125 +7425 0.2132568359375 +7426 0.38885498046875 +7427 0.582794189453125 +7428 0.734039306640625 +7429 0.800140380859375 +7430 0.7783203125 +7431 0.6651611328125 +7432 0.45965576171875 +7433 0.199188232421875 +7434 -0.050689697265625 +7435 -0.23297119140625 +7436 -0.33013916015625 +7437 -0.368408203125 +7438 -0.378936767578125 +7439 -0.376983642578125 +7440 -0.37969970703125 +7441 -0.391510009765625 +7442 -0.385345458984375 +7443 -0.3419189453125 +7444 -0.28289794921875 +7445 -0.251617431640625 +7446 -0.266143798828125 +7447 -0.273345947265625 +7448 -0.216796875 +7449 -0.128265380859375 +7450 -0.068145751953125 +7451 -0.0430908203125 +7452 -0.024444580078125 +7453 0.020721435546875 +7454 0.124481201171875 +7455 0.25787353515625 +7456 0.379119873046875 +7457 0.47991943359375 +7458 0.5281982421875 +7459 0.511138916015625 +7460 0.456207275390625 +7461 0.407470703125 +7462 0.383758544921875 +7463 0.35687255859375 +7464 0.31182861328125 +7465 0.250885009765625 +7466 0.1654052734375 +7467 0.035247802734375 +7468 -0.142059326171875 +7469 -0.33563232421875 +7470 -0.5345458984375 +7471 -0.72186279296875 +7472 -0.836669921875 +7473 -0.8326416015625 +7474 -0.7296142578125 +7475 -0.582550048828125 +7476 -0.440093994140625 +7477 -0.324310302734375 +7478 -0.20147705078125 +7479 -0.044647216796875 +7480 0.103973388671875 +7481 0.202392578125 +7482 0.264495849609375 +7483 0.338897705078125 +7484 0.443817138671875 +7485 0.545074462890625 +7486 0.6173095703125 +7487 0.6524658203125 +7488 0.66339111328125 +7489 0.6561279296875 +7490 0.606781005859375 +7491 0.501190185546875 +7492 0.352783203125 +7493 0.176544189453125 +7494 -0.034820556640625 +7495 -0.258209228515625 +7496 -0.44244384765625 +7497 -0.5753173828125 +7498 -0.65203857421875 +7499 -0.641632080078125 +7500 -0.562164306640625 +7501 -0.458038330078125 +7502 -0.350555419921875 +7503 -0.260528564453125 +7504 -0.192108154296875 +7505 -0.141937255859375 +7506 -0.1021728515625 +7507 -0.062896728515625 +7508 -0.011932373046875 +7509 0.062835693359375 +7510 0.148712158203125 +7511 0.241729736328125 +7512 0.34912109375 +7513 0.457305908203125 +7514 0.54388427734375 +7515 0.5728759765625 +7516 0.506591796875 +7517 0.351226806640625 +7518 0.146514892578125 +7519 -0.05523681640625 +7520 -0.21624755859375 +7521 -0.334930419921875 +7522 -0.402984619140625 +7523 -0.4412841796875 +7524 -0.49578857421875 +7525 -0.5601806640625 +7526 -0.600738525390625 +7527 -0.584228515625 +7528 -0.47930908203125 +7529 -0.27935791015625 +7530 -0.0089111328125 +7531 0.268798828125 +7532 0.482818603515625 +7533 0.60369873046875 +7534 0.650421142578125 +7535 0.66400146484375 +7536 0.6414794921875 +7537 0.572540283203125 +7538 0.498138427734375 +7539 0.439453125 +7540 0.375518798828125 +7541 0.274505615234375 +7542 0.1087646484375 +7543 -0.099395751953125 +7544 -0.3182373046875 +7545 -0.5489501953125 +7546 -0.7738037109375 +7547 -0.86383056640625 +7548 -0.870391845703125 +7549 -0.86895751953125 +7550 -0.861053466796875 +7551 -0.765869140625 +7552 -0.5301513671875 +7553 -0.214691162109375 +7554 0.137359619140625 +7555 0.474822998046875 +7556 0.76239013671875 +7557 0.867462158203125 +7558 0.870361328125 +7559 0.86480712890625 +7560 0.831817626953125 +7561 0.677581787109375 +7562 0.495880126953125 +7563 0.30767822265625 +7564 0.116180419921875 +7565 -0.110748291015625 +7566 -0.381805419921875 +7567 -0.6572265625 +7568 -0.857421875 +7569 -0.870391845703125 +7570 -0.870391845703125 +7571 -0.86444091796875 +7572 -0.85723876953125 +7573 -0.790008544921875 +7574 -0.62847900390625 +7575 -0.3956298828125 +7576 -0.126708984375 +7577 0.150115966796875 +7578 0.424041748046875 +7579 0.670623779296875 +7580 0.854522705078125 +7581 0.866485595703125 +7582 0.86920166015625 +7583 0.8653564453125 +7584 0.857147216796875 +7585 0.766845703125 +7586 0.628509521484375 +7587 0.462127685546875 +7588 0.297210693359375 +7589 0.14862060546875 +7590 -0.00537109375 +7591 -0.15753173828125 +7592 -0.31304931640625 +7593 -0.48876953125 +7594 -0.6416015625 +7595 -0.751373291015625 +7596 -0.84619140625 +7597 -0.861297607421875 +7598 -0.863250732421875 +7599 -0.856597900390625 +7600 -0.7498779296875 +7601 -0.624542236328125 +7602 -0.47808837890625 +7603 -0.253387451171875 +7604 0.003692626953125 +7605 0.2257080078125 +7606 0.427154541015625 +7607 0.643218994140625 +7608 0.855926513671875 +7609 0.870361328125 +7610 0.870361328125 +7611 0.862762451171875 +7612 0.79669189453125 +7613 0.595794677734375 +7614 0.362152099609375 +7615 0.1270751953125 +7616 -0.086944580078125 +7617 -0.2784423828125 +7618 -0.484832763671875 +7619 -0.729583740234375 +7620 -0.86688232421875 +7621 -0.870391845703125 +7622 -0.86859130859375 +7623 -0.86279296875 +7624 -0.817962646484375 +7625 -0.6116943359375 +7626 -0.3128662109375 +7627 0.039398193359375 +7628 0.422821044921875 +7629 0.805145263671875 +7630 0.870361328125 +7631 0.870361328125 +7632 0.860015869140625 +7633 0.727935791015625 +7634 0.48114013671875 +7635 0.2059326171875 +7636 -0.06103515625 +7637 -0.29913330078125 +7638 -0.516204833984375 +7639 -0.7252197265625 +7640 -0.85980224609375 +7641 -0.870391845703125 +7642 -0.870391845703125 +7643 -0.858062744140625 +7644 -0.673004150390625 +7645 -0.42694091796875 +7646 -0.2100830078125 +7647 -0.0362548828125 +7648 0.10943603515625 +7649 0.23516845703125 +7650 0.373687744140625 +7651 0.517791748046875 +7652 0.602783203125 +7653 0.635711669921875 +7654 0.655181884765625 +7655 0.65948486328125 +7656 0.651275634765625 +7657 0.61846923828125 +7658 0.53753662109375 +7659 0.404144287109375 +7660 0.22186279296875 +7661 0.003997802734375 +7662 -0.22100830078125 +7663 -0.42449951171875 +7664 -0.579833984375 +7665 -0.641876220703125 +7666 -0.6177978515625 +7667 -0.575531005859375 +7668 -0.526336669921875 +7669 -0.42645263671875 +7670 -0.2581787109375 +7671 -0.068695068359375 +7672 0.09222412109375 +7673 0.232147216796875 +7674 0.3509521484375 +7675 0.410064697265625 +7676 0.372955322265625 +7677 0.2554931640625 +7678 0.10711669921875 +7679 -0.052886962890625 +7680 -0.186279296875 +7681 -0.23291015625 +7682 -0.209442138671875 +7683 -0.174163818359375 +7684 -0.126739501953125 +7685 -0.048126220703125 +7686 0.0426025390625 +7687 0.10748291015625 +7688 0.1409912109375 +7689 0.19708251953125 +7690 0.273651123046875 +7691 0.31768798828125 +7692 0.341094970703125 +7693 0.368011474609375 +7694 0.37249755859375 +7695 0.30072021484375 +7696 0.1517333984375 +7697 -0.01470947265625 +7698 -0.1883544921875 +7699 -0.372711181640625 +7700 -0.51397705078125 +7701 -0.57177734375 +7702 -0.53948974609375 +7703 -0.43511962890625 +7704 -0.2962646484375 +7705 -0.161102294921875 +7706 -0.0435791015625 +7707 0.060394287109375 +7708 0.13665771484375 +7709 0.170135498046875 +7710 0.16552734375 +7711 0.15728759765625 +7712 0.150787353515625 +7713 0.12200927734375 +7714 0.080108642578125 +7715 0.05126953125 +7716 0.062896728515625 +7717 0.09271240234375 +7718 0.092987060546875 +7719 0.07855224609375 +7720 0.06427001953125 +7721 0.0347900390625 +7722 -0.01171875 +7723 -0.056060791015625 +7724 -0.055511474609375 +7725 -0.010467529296875 +7726 0.02508544921875 +7727 0.025665283203125 +7728 0.017333984375 +7729 0.00189208984375 +7730 -0.03173828125 +7731 -0.071502685546875 +7732 -0.13543701171875 +7733 -0.219970703125 +7734 -0.300506591796875 +7735 -0.376312255859375 +7736 -0.416107177734375 +7737 -0.371124267578125 +7738 -0.242279052734375 +7739 -0.069732666015625 +7740 0.125640869140625 +7741 0.31268310546875 +7742 0.45501708984375 +7743 0.554779052734375 +7744 0.61065673828125 +7745 0.610931396484375 +7746 0.531463623046875 +7747 0.3883056640625 +7748 0.23468017578125 +7749 0.095245361328125 +7750 -0.00396728515625 +7751 -0.04852294921875 +7752 -0.055145263671875 +7753 -0.0758056640625 +7754 -0.138702392578125 +7755 -0.209197998046875 +7756 -0.289031982421875 +7757 -0.37884521484375 +7758 -0.456329345703125 +7759 -0.51641845703125 +7760 -0.519287109375 +7761 -0.458251953125 +7762 -0.384796142578125 +7763 -0.323699951171875 +7764 -0.269287109375 +7765 -0.1951904296875 +7766 -0.100006103515625 +7767 -0.01055908203125 +7768 0.1033935546875 +7769 0.24908447265625 +7770 0.373199462890625 +7771 0.45806884765625 +7772 0.511474609375 +7773 0.565399169921875 +7774 0.61138916015625 +7775 0.5897216796875 +7776 0.4906005859375 +7777 0.33148193359375 +7778 0.147796630859375 +7779 -0.01873779296875 +7780 -0.140289306640625 +7781 -0.191986083984375 +7782 -0.184295654296875 +7783 -0.161834716796875 +7784 -0.166595458984375 +7785 -0.19390869140625 +7786 -0.22442626953125 +7787 -0.279754638671875 +7788 -0.3389892578125 +7789 -0.3543701171875 +7790 -0.348175048828125 +7791 -0.32598876953125 +7792 -0.2581787109375 +7793 -0.139801025390625 +7794 0.014617919921875 +7795 0.144378662109375 +7796 0.221038818359375 +7797 0.27069091796875 +7798 0.294036865234375 +7799 0.311767578125 +7800 0.339141845703125 +7801 0.360260009765625 +7802 0.360504150390625 +7803 0.308380126953125 +7804 0.18170166015625 +7805 0.0047607421875 +7806 -0.17559814453125 +7807 -0.3143310546875 +7808 -0.36785888671875 +7809 -0.36248779296875 +7810 -0.343536376953125 +7811 -0.3018798828125 +7812 -0.231414794921875 +7813 -0.117645263671875 +7814 0.007049560546875 +7815 0.087982177734375 +7816 0.13946533203125 +7817 0.17425537109375 +7818 0.188201904296875 +7819 0.171234130859375 +7820 0.118438720703125 +7821 0.05706787109375 +7822 -0.010711669921875 +7823 -0.0914306640625 +7824 -0.162322998046875 +7825 -0.194549560546875 +7826 -0.1492919921875 +7827 -0.02166748046875 +7828 0.124053955078125 +7829 0.211151123046875 +7830 0.240447998046875 +7831 0.242218017578125 +7832 0.2257080078125 +7833 0.194366455078125 +7834 0.115509033203125 +7835 0.0128173828125 +7836 -0.053802490234375 +7837 -0.110626220703125 +7838 -0.199493408203125 +7839 -0.29437255859375 +7840 -0.33221435546875 +7841 -0.27972412109375 +7842 -0.185333251953125 +7843 -0.128204345703125 +7844 -0.115692138671875 +7845 -0.116455078125 +7846 -0.105926513671875 +7847 -0.053955078125 +7848 0.048797607421875 +7849 0.157318115234375 +7850 0.212005615234375 +7851 0.218475341796875 +7852 0.23724365234375 +7853 0.30535888671875 +7854 0.38128662109375 +7855 0.404449462890625 +7856 0.3944091796875 +7857 0.3885498046875 +7858 0.362640380859375 +7859 0.27362060546875 +7860 0.11712646484375 +7861 -0.054901123046875 +7862 -0.19085693359375 +7863 -0.28570556640625 +7864 -0.339263916015625 +7865 -0.3775634765625 +7866 -0.445709228515625 +7867 -0.535064697265625 +7868 -0.629058837890625 +7869 -0.697601318359375 +7870 -0.70391845703125 +7871 -0.6424560546875 +7872 -0.491241455078125 +7873 -0.265716552734375 +7874 -0.023712158203125 +7875 0.201751708984375 +7876 0.375823974609375 +7877 0.485076904296875 +7878 0.56884765625 +7879 0.634765625 +7880 0.63763427734375 +7881 0.5660400390625 +7882 0.4720458984375 +7883 0.40692138671875 +7884 0.3778076171875 +7885 0.376953125 +7886 0.371978759765625 +7887 0.313140869140625 +7888 0.184417724609375 +7889 0.011199951171875 +7890 -0.171051025390625 +7891 -0.33740234375 +7892 -0.47198486328125 +7893 -0.560394287109375 +7894 -0.58056640625 +7895 -0.54754638671875 +7896 -0.508575439453125 +7897 -0.459503173828125 +7898 -0.394378662109375 +7899 -0.35260009765625 +7900 -0.31170654296875 +7901 -0.197418212890625 +7902 -0.007965087890625 +7903 0.207489013671875 +7904 0.409210205078125 +7905 0.57208251953125 +7906 0.66595458984375 +7907 0.65875244140625 +7908 0.56744384765625 +7909 0.431396484375 +7910 0.29443359375 +7911 0.182464599609375 +7912 0.06365966796875 +7913 -0.075958251953125 +7914 -0.189422607421875 +7915 -0.271942138671875 +7916 -0.342529296875 +7917 -0.364166259765625 +7918 -0.327239990234375 +7919 -0.2769775390625 +7920 -0.253692626953125 +7921 -0.24365234375 +7922 -0.1983642578125 +7923 -0.116241455078125 +7924 -0.036834716796875 +7925 0.034881591796875 +7926 0.09124755859375 +7927 0.10888671875 +7928 0.125518798828125 +7929 0.15771484375 +7930 0.17828369140625 +7931 0.17108154296875 +7932 0.129974365234375 +7933 0.082427978515625 +7934 0.027679443359375 +7935 -0.065643310546875 +7936 -0.15936279296875 +7937 -0.21307373046875 +7938 -0.234649658203125 +7939 -0.2001953125 +7940 -0.119171142578125 +7941 -0.024749755859375 +7942 0.085784912109375 +7943 0.178131103515625 +7944 0.215576171875 +7945 0.211456298828125 +7946 0.17523193359375 +7947 0.128753662109375 +7948 0.1019287109375 +7949 0.0743408203125 +7950 0.04327392578125 +7951 0.038177490234375 +7952 0.076263427734375 +7953 0.14105224609375 +7954 0.186431884765625 +7955 0.188812255859375 +7956 0.1390380859375 +7957 0.041778564453125 +7958 -0.079437255859375 +7959 -0.219390869140625 +7960 -0.367828369140625 +7961 -0.494873046875 +7962 -0.556243896484375 +7963 -0.508697509765625 +7964 -0.3756103515625 +7965 -0.218902587890625 +7966 -0.063751220703125 +7967 0.091552734375 +7968 0.23602294921875 +7969 0.342987060546875 +7970 0.39520263671875 +7971 0.389373779296875 +7972 0.324249267578125 +7973 0.224090576171875 +7974 0.124267578125 +7975 0.037078857421875 +7976 -0.010101318359375 +7977 -0.019439697265625 +7978 -0.022796630859375 +7979 -0.001556396484375 +7980 0.056304931640625 +7981 0.106719970703125 +7982 0.096893310546875 +7983 0.042694091796875 +7984 -0.018035888671875 +7985 -0.07586669921875 +7986 -0.11944580078125 +7987 -0.15972900390625 +7988 -0.202606201171875 +7989 -0.24859619140625 +7990 -0.30517578125 +7991 -0.36212158203125 +7992 -0.39141845703125 +7993 -0.35528564453125 +7994 -0.249969482421875 +7995 -0.092864990234375 +7996 0.08905029296875 +7997 0.2352294921875 +7998 0.318817138671875 +7999 0.358642578125 +8000 0.347747802734375 +8001 0.28564453125 +8002 0.223175048828125 +8003 0.196746826171875 +8004 0.179840087890625 +8005 0.155548095703125 +8006 0.151214599609375 +8007 0.156951904296875 +8008 0.13177490234375 +8009 0.100799560546875 +8010 0.087127685546875 +8011 0.05487060546875 +8012 -0.009002685546875 +8013 -0.10400390625 +8014 -0.229400634765625 +8015 -0.35552978515625 +8016 -0.441925048828125 +8017 -0.473846435546875 +8018 -0.464813232421875 +8019 -0.419097900390625 +8020 -0.334320068359375 +8021 -0.227935791015625 +8022 -0.12347412109375 +8023 -0.02764892578125 +8024 0.077667236328125 +8025 0.2132568359375 +8026 0.38885498046875 +8027 0.582794189453125 +8028 0.734039306640625 +8029 0.800140380859375 +8030 0.7783203125 +8031 0.6651611328125 +8032 0.45965576171875 +8033 0.199188232421875 +8034 -0.050689697265625 +8035 -0.23297119140625 +8036 -0.33013916015625 +8037 -0.368408203125 +8038 -0.378936767578125 +8039 -0.376983642578125 +8040 -0.37969970703125 +8041 -0.391510009765625 +8042 -0.385345458984375 +8043 -0.3419189453125 +8044 -0.28289794921875 +8045 -0.251617431640625 +8046 -0.266143798828125 +8047 -0.273345947265625 +8048 -0.216796875 +8049 -0.128265380859375 +8050 -0.068145751953125 +8051 -0.0430908203125 +8052 -0.024444580078125 +8053 0.020721435546875 +8054 0.124481201171875 +8055 0.25787353515625 +8056 0.379119873046875 +8057 0.47991943359375 +8058 0.5281982421875 +8059 0.511138916015625 +8060 0.456207275390625 +8061 0.407470703125 +8062 0.383758544921875 +8063 0.35687255859375 +8064 0.31182861328125 +8065 0.250885009765625 +8066 0.1654052734375 +8067 0.035247802734375 +8068 -0.142059326171875 +8069 -0.33563232421875 +8070 -0.5345458984375 +8071 -0.72186279296875 +8072 -0.836669921875 +8073 -0.8326416015625 +8074 -0.7296142578125 +8075 -0.582550048828125 +8076 -0.440093994140625 +8077 -0.324310302734375 +8078 -0.20147705078125 +8079 -0.044647216796875 +8080 0.103973388671875 +8081 0.202392578125 +8082 0.264495849609375 +8083 0.338897705078125 +8084 0.443817138671875 +8085 0.545074462890625 +8086 0.6173095703125 +8087 0.6524658203125 +8088 0.66339111328125 +8089 0.6561279296875 +8090 0.606781005859375 +8091 0.501190185546875 +8092 0.352783203125 +8093 0.176544189453125 +8094 -0.034820556640625 +8095 -0.258209228515625 +8096 -0.44244384765625 +8097 -0.5753173828125 +8098 -0.65203857421875 +8099 -0.641632080078125 +8100 -0.562164306640625 +8101 -0.458038330078125 +8102 -0.350555419921875 +8103 -0.260528564453125 +8104 -0.192108154296875 +8105 -0.141937255859375 +8106 -0.1021728515625 +8107 -0.062896728515625 +8108 -0.011932373046875 +8109 0.062835693359375 +8110 0.148712158203125 +8111 0.241729736328125 +8112 0.34912109375 +8113 0.457305908203125 +8114 0.54388427734375 +8115 0.5728759765625 +8116 0.506591796875 +8117 0.351226806640625 +8118 0.146514892578125 +8119 -0.05523681640625 +8120 -0.21624755859375 +8121 -0.334930419921875 +8122 -0.402984619140625 +8123 -0.4412841796875 +8124 -0.49578857421875 +8125 -0.5601806640625 +8126 -0.600738525390625 +8127 -0.584228515625 +8128 -0.47930908203125 +8129 -0.27935791015625 +8130 -0.0089111328125 +8131 0.268798828125 +8132 0.482818603515625 +8133 0.60369873046875 +8134 0.650421142578125 +8135 0.66400146484375 +8136 0.6414794921875 +8137 0.572540283203125 +8138 0.498138427734375 +8139 0.439453125 +8140 0.375518798828125 +8141 0.274505615234375 +8142 0.1087646484375 +8143 -0.099395751953125 +8144 -0.3182373046875 +8145 -0.5489501953125 +8146 -0.7738037109375 +8147 -0.86383056640625 +8148 -0.870391845703125 +8149 -0.86895751953125 +8150 -0.861053466796875 +8151 -0.765869140625 +8152 -0.5301513671875 +8153 -0.214691162109375 +8154 0.137359619140625 +8155 0.474822998046875 +8156 0.76239013671875 +8157 0.867462158203125 +8158 0.870361328125 +8159 0.86480712890625 +8160 0.831817626953125 +8161 0.677581787109375 +8162 0.495880126953125 +8163 0.30767822265625 +8164 0.116180419921875 +8165 -0.110748291015625 +8166 -0.381805419921875 +8167 -0.6572265625 +8168 -0.857421875 +8169 -0.870391845703125 +8170 -0.870391845703125 +8171 -0.86444091796875 +8172 -0.85723876953125 +8173 -0.790008544921875 +8174 -0.62847900390625 +8175 -0.3956298828125 +8176 -0.126708984375 +8177 0.150115966796875 +8178 0.424041748046875 +8179 0.670623779296875 +8180 0.854522705078125 +8181 0.866485595703125 +8182 0.86920166015625 +8183 0.8653564453125 +8184 0.857147216796875 +8185 0.766845703125 +8186 0.628509521484375 +8187 0.462127685546875 +8188 0.297210693359375 +8189 0.14862060546875 +8190 -0.00537109375 +8191 -0.15753173828125 +8192 -0.31304931640625 +8193 -0.48876953125 +8194 -0.6416015625 +8195 -0.751373291015625 +8196 -0.84619140625 +8197 -0.861297607421875 +8198 -0.863250732421875 +8199 -0.856597900390625 +8200 -0.7498779296875 +8201 -0.624542236328125 +8202 -0.47808837890625 +8203 -0.253387451171875 +8204 0.003692626953125 +8205 0.2257080078125 +8206 0.427154541015625 +8207 0.643218994140625 +8208 0.855926513671875 +8209 0.870361328125 +8210 0.870361328125 +8211 0.862762451171875 +8212 0.79669189453125 +8213 0.595794677734375 +8214 0.362152099609375 +8215 0.1270751953125 +8216 -0.086944580078125 +8217 -0.2784423828125 +8218 -0.484832763671875 +8219 -0.729583740234375 +8220 -0.86688232421875 +8221 -0.870391845703125 +8222 -0.86859130859375 +8223 -0.86279296875 +8224 -0.817962646484375 +8225 -0.6116943359375 +8226 -0.3128662109375 +8227 0.039398193359375 +8228 0.422821044921875 +8229 0.805145263671875 +8230 0.870361328125 +8231 0.870361328125 +8232 0.860015869140625 +8233 0.727935791015625 +8234 0.48114013671875 +8235 0.2059326171875 +8236 -0.06103515625 +8237 -0.29913330078125 +8238 -0.516204833984375 +8239 -0.7252197265625 +8240 -0.85980224609375 +8241 -0.870391845703125 +8242 -0.870391845703125 +8243 -0.858062744140625 +8244 -0.673004150390625 +8245 -0.42694091796875 +8246 -0.2100830078125 +8247 -0.0362548828125 +8248 0.10943603515625 +8249 0.23516845703125 +8250 0.373687744140625 +8251 0.517791748046875 +8252 0.602783203125 +8253 0.635711669921875 +8254 0.655181884765625 +8255 0.65948486328125 +8256 0.651275634765625 +8257 0.61846923828125 +8258 0.53753662109375 +8259 0.404144287109375 +8260 0.22186279296875 +8261 0.003997802734375 +8262 -0.22100830078125 +8263 -0.42449951171875 +8264 -0.579833984375 +8265 -0.641876220703125 +8266 -0.6177978515625 +8267 -0.575531005859375 +8268 -0.526336669921875 +8269 -0.42645263671875 +8270 -0.2581787109375 +8271 -0.068695068359375 +8272 0.09222412109375 +8273 0.232147216796875 +8274 0.3509521484375 +8275 0.410064697265625 +8276 0.372955322265625 +8277 0.2554931640625 +8278 0.10711669921875 +8279 -0.052886962890625 +8280 -0.186279296875 +8281 -0.23291015625 +8282 -0.209442138671875 +8283 -0.174163818359375 +8284 -0.126739501953125 +8285 -0.048126220703125 +8286 0.0426025390625 +8287 0.10748291015625 +8288 0.1409912109375 +8289 0.19708251953125 +8290 0.273651123046875 +8291 0.31768798828125 +8292 0.341094970703125 +8293 0.368011474609375 +8294 0.37249755859375 +8295 0.30072021484375 +8296 0.1517333984375 +8297 -0.01470947265625 +8298 -0.1883544921875 +8299 -0.372711181640625 +8300 -0.51397705078125 +8301 -0.57177734375 +8302 -0.53948974609375 +8303 -0.43511962890625 +8304 -0.2962646484375 +8305 -0.161102294921875 +8306 -0.0435791015625 +8307 0.060394287109375 +8308 0.13665771484375 +8309 0.170135498046875 +8310 0.16552734375 +8311 0.15728759765625 +8312 0.150787353515625 +8313 0.12200927734375 +8314 0.080108642578125 +8315 0.05126953125 +8316 0.062896728515625 +8317 0.09271240234375 +8318 0.092987060546875 +8319 0.07855224609375 +8320 0.06427001953125 +8321 0.0347900390625 +8322 -0.01171875 +8323 -0.056060791015625 +8324 -0.055511474609375 +8325 -0.010467529296875 +8326 0.02508544921875 +8327 0.025665283203125 +8328 0.017333984375 +8329 0.00189208984375 +8330 -0.03173828125 +8331 -0.071502685546875 +8332 -0.13543701171875 +8333 -0.219970703125 +8334 -0.300506591796875 +8335 -0.376312255859375 +8336 -0.416107177734375 +8337 -0.371124267578125 +8338 -0.242279052734375 +8339 -0.069732666015625 +8340 0.125640869140625 +8341 0.31268310546875 +8342 0.45501708984375 +8343 0.554779052734375 +8344 0.61065673828125 +8345 0.610931396484375 +8346 0.531463623046875 +8347 0.3883056640625 +8348 0.23468017578125 +8349 0.095245361328125 +8350 -0.00396728515625 +8351 -0.04852294921875 +8352 -0.055145263671875 +8353 -0.0758056640625 +8354 -0.138702392578125 +8355 -0.209197998046875 +8356 -0.289031982421875 +8357 -0.37884521484375 +8358 -0.456329345703125 +8359 -0.51641845703125 +8360 -0.519287109375 +8361 -0.458251953125 +8362 -0.384796142578125 +8363 -0.323699951171875 +8364 -0.269287109375 +8365 -0.1951904296875 +8366 -0.100006103515625 +8367 -0.01055908203125 +8368 0.1033935546875 +8369 0.24908447265625 +8370 0.373199462890625 +8371 0.45806884765625 +8372 0.511474609375 +8373 0.565399169921875 +8374 0.61138916015625 +8375 0.5897216796875 +8376 0.4906005859375 +8377 0.33148193359375 +8378 0.147796630859375 +8379 -0.01873779296875 +8380 -0.140289306640625 +8381 -0.191986083984375 +8382 -0.184295654296875 +8383 -0.161834716796875 +8384 -0.166595458984375 +8385 -0.19390869140625 +8386 -0.22442626953125 +8387 -0.279754638671875 +8388 -0.3389892578125 +8389 -0.3543701171875 +8390 -0.348175048828125 +8391 -0.32598876953125 +8392 -0.2581787109375 +8393 -0.139801025390625 +8394 0.014617919921875 +8395 0.144378662109375 +8396 0.221038818359375 +8397 0.27069091796875 +8398 0.294036865234375 +8399 0.311767578125 +8400 0.339141845703125 +8401 0.360260009765625 +8402 0.360504150390625 +8403 0.308380126953125 +8404 0.18170166015625 +8405 0.0047607421875 +8406 -0.17559814453125 +8407 -0.3143310546875 +8408 -0.36785888671875 +8409 -0.36248779296875 +8410 -0.343536376953125 +8411 -0.3018798828125 +8412 -0.231414794921875 +8413 -0.117645263671875 +8414 0.007049560546875 +8415 0.087982177734375 +8416 0.13946533203125 +8417 0.17425537109375 +8418 0.188201904296875 +8419 0.171234130859375 +8420 0.118438720703125 +8421 0.05706787109375 +8422 -0.010711669921875 +8423 -0.0914306640625 +8424 -0.162322998046875 +8425 -0.194549560546875 +8426 -0.1492919921875 +8427 -0.02166748046875 +8428 0.124053955078125 +8429 0.211151123046875 +8430 0.240447998046875 +8431 0.242218017578125 +8432 0.2257080078125 +8433 0.194366455078125 +8434 0.115509033203125 +8435 0.0128173828125 +8436 -0.053802490234375 +8437 -0.110626220703125 +8438 -0.199493408203125 +8439 -0.29437255859375 +8440 -0.33221435546875 +8441 -0.27972412109375 +8442 -0.185333251953125 +8443 -0.128204345703125 +8444 -0.115692138671875 +8445 -0.116455078125 +8446 -0.105926513671875 +8447 -0.053955078125 +8448 0.048797607421875 +8449 0.157318115234375 +8450 0.212005615234375 +8451 0.218475341796875 +8452 0.23724365234375 +8453 0.30535888671875 +8454 0.38128662109375 +8455 0.404449462890625 +8456 0.3944091796875 +8457 0.3885498046875 +8458 0.362640380859375 +8459 0.27362060546875 +8460 0.11712646484375 +8461 -0.054901123046875 +8462 -0.19085693359375 +8463 -0.28570556640625 +8464 -0.339263916015625 +8465 -0.3775634765625 +8466 -0.445709228515625 +8467 -0.535064697265625 +8468 -0.629058837890625 +8469 -0.697601318359375 +8470 -0.70391845703125 +8471 -0.6424560546875 +8472 -0.491241455078125 +8473 -0.265716552734375 +8474 -0.023712158203125 +8475 0.201751708984375 +8476 0.375823974609375 +8477 0.485076904296875 +8478 0.56884765625 +8479 0.634765625 +8480 0.63763427734375 +8481 0.5660400390625 +8482 0.4720458984375 +8483 0.40692138671875 +8484 0.3778076171875 +8485 0.376953125 +8486 0.371978759765625 +8487 0.313140869140625 +8488 0.184417724609375 +8489 0.011199951171875 +8490 -0.171051025390625 +8491 -0.33740234375 +8492 -0.47198486328125 +8493 -0.560394287109375 +8494 -0.58056640625 +8495 -0.54754638671875 +8496 -0.508575439453125 +8497 -0.459503173828125 +8498 -0.394378662109375 +8499 -0.35260009765625 +8500 -0.31170654296875 +8501 -0.197418212890625 +8502 -0.007965087890625 +8503 0.207489013671875 +8504 0.409210205078125 +8505 0.57208251953125 +8506 0.66595458984375 +8507 0.65875244140625 +8508 0.56744384765625 +8509 0.431396484375 +8510 0.29443359375 +8511 0.182464599609375 +8512 0.06365966796875 +8513 -0.075958251953125 +8514 -0.189422607421875 +8515 -0.271942138671875 +8516 -0.342529296875 +8517 -0.364166259765625 +8518 -0.327239990234375 +8519 -0.2769775390625 +8520 -0.253692626953125 +8521 -0.24365234375 +8522 -0.1983642578125 +8523 -0.116241455078125 +8524 -0.036834716796875 +8525 0.034881591796875 +8526 0.09124755859375 +8527 0.10888671875 +8528 0.125518798828125 +8529 0.15771484375 +8530 0.17828369140625 +8531 0.17108154296875 +8532 0.129974365234375 +8533 0.082427978515625 +8534 0.027679443359375 +8535 -0.065643310546875 +8536 -0.15936279296875 +8537 -0.21307373046875 +8538 -0.234649658203125 +8539 -0.2001953125 +8540 -0.119171142578125 +8541 -0.024749755859375 +8542 0.085784912109375 +8543 0.178131103515625 +8544 0.215576171875 +8545 0.211456298828125 +8546 0.17523193359375 +8547 0.128753662109375 +8548 0.1019287109375 +8549 0.0743408203125 +8550 0.04327392578125 +8551 0.038177490234375 +8552 0.076263427734375 +8553 0.14105224609375 +8554 0.186431884765625 +8555 0.188812255859375 +8556 0.1390380859375 +8557 0.041778564453125 +8558 -0.079437255859375 +8559 -0.219390869140625 +8560 -0.367828369140625 +8561 -0.494873046875 +8562 -0.556243896484375 +8563 -0.508697509765625 +8564 -0.3756103515625 +8565 -0.218902587890625 +8566 -0.063751220703125 +8567 0.091552734375 +8568 0.23602294921875 +8569 0.342987060546875 +8570 0.39520263671875 +8571 0.389373779296875 +8572 0.324249267578125 +8573 0.224090576171875 +8574 0.124267578125 +8575 0.037078857421875 +8576 -0.010101318359375 +8577 -0.019439697265625 +8578 -0.022796630859375 +8579 -0.001556396484375 +8580 0.056304931640625 +8581 0.106719970703125 +8582 0.096893310546875 +8583 0.042694091796875 +8584 -0.018035888671875 +8585 -0.07586669921875 +8586 -0.11944580078125 +8587 -0.15972900390625 +8588 -0.202606201171875 +8589 -0.24859619140625 +8590 -0.30517578125 +8591 -0.36212158203125 +8592 -0.39141845703125 +8593 -0.35528564453125 +8594 -0.249969482421875 +8595 -0.092864990234375 +8596 0.08905029296875 +8597 0.2352294921875 +8598 0.318817138671875 +8599 0.358642578125 +8600 0.347747802734375 +8601 0.28564453125 +8602 0.223175048828125 +8603 0.196746826171875 +8604 0.179840087890625 +8605 0.155548095703125 +8606 0.151214599609375 +8607 0.156951904296875 +8608 0.13177490234375 +8609 0.100799560546875 +8610 0.087127685546875 +8611 0.05487060546875 +8612 -0.009002685546875 +8613 -0.10400390625 +8614 -0.229400634765625 +8615 -0.35552978515625 +8616 -0.441925048828125 +8617 -0.473846435546875 +8618 -0.464813232421875 +8619 -0.419097900390625 +8620 -0.334320068359375 +8621 -0.227935791015625 +8622 -0.12347412109375 +8623 -0.02764892578125 +8624 0.077667236328125 +8625 0.2132568359375 +8626 0.38885498046875 +8627 0.582794189453125 +8628 0.734039306640625 +8629 0.800140380859375 +8630 0.7783203125 +8631 0.6651611328125 +8632 0.45965576171875 +8633 0.199188232421875 +8634 -0.050689697265625 +8635 -0.23297119140625 +8636 -0.33013916015625 +8637 -0.368408203125 +8638 -0.378936767578125 +8639 -0.376983642578125 +8640 -0.37969970703125 +8641 -0.391510009765625 +8642 -0.385345458984375 +8643 -0.3419189453125 +8644 -0.28289794921875 +8645 -0.251617431640625 +8646 -0.266143798828125 +8647 -0.273345947265625 +8648 -0.216796875 +8649 -0.128265380859375 +8650 -0.068145751953125 +8651 -0.0430908203125 +8652 -0.024444580078125 +8653 0.020721435546875 +8654 0.124481201171875 +8655 0.25787353515625 +8656 0.379119873046875 +8657 0.47991943359375 +8658 0.5281982421875 +8659 0.511138916015625 +8660 0.456207275390625 +8661 0.407470703125 +8662 0.383758544921875 +8663 0.35687255859375 +8664 0.31182861328125 +8665 0.250885009765625 +8666 0.1654052734375 +8667 0.035247802734375 +8668 -0.142059326171875 +8669 -0.33563232421875 +8670 -0.5345458984375 +8671 -0.72186279296875 +8672 -0.836669921875 +8673 -0.8326416015625 +8674 -0.7296142578125 +8675 -0.582550048828125 +8676 -0.440093994140625 +8677 -0.324310302734375 +8678 -0.20147705078125 +8679 -0.044647216796875 +8680 0.103973388671875 +8681 0.202392578125 +8682 0.264495849609375 +8683 0.338897705078125 +8684 0.443817138671875 +8685 0.545074462890625 +8686 0.6173095703125 +8687 0.6524658203125 +8688 0.66339111328125 +8689 0.6561279296875 +8690 0.606781005859375 +8691 0.501190185546875 +8692 0.352783203125 +8693 0.176544189453125 +8694 -0.034820556640625 +8695 -0.258209228515625 +8696 -0.44244384765625 +8697 -0.5753173828125 +8698 -0.65203857421875 +8699 -0.641632080078125 +8700 -0.562164306640625 +8701 -0.458038330078125 +8702 -0.350555419921875 +8703 -0.260528564453125 +8704 -0.192108154296875 +8705 -0.141937255859375 +8706 -0.1021728515625 +8707 -0.062896728515625 +8708 -0.011932373046875 +8709 0.062835693359375 +8710 0.148712158203125 +8711 0.241729736328125 +8712 0.34912109375 +8713 0.457305908203125 +8714 0.54388427734375 +8715 0.5728759765625 +8716 0.506591796875 +8717 0.351226806640625 +8718 0.146514892578125 +8719 -0.05523681640625 +8720 -0.21624755859375 +8721 -0.334930419921875 +8722 -0.402984619140625 +8723 -0.4412841796875 +8724 -0.49578857421875 +8725 -0.5601806640625 +8726 -0.600738525390625 +8727 -0.584228515625 +8728 -0.47930908203125 +8729 -0.27935791015625 +8730 -0.0089111328125 +8731 0.268798828125 +8732 0.482818603515625 +8733 0.60369873046875 +8734 0.650421142578125 +8735 0.66400146484375 +8736 0.6414794921875 +8737 0.572540283203125 +8738 0.498138427734375 +8739 0.439453125 +8740 0.375518798828125 +8741 0.274505615234375 +8742 0.1087646484375 +8743 -0.099395751953125 +8744 -0.3182373046875 +8745 -0.5489501953125 +8746 -0.7738037109375 +8747 -0.86383056640625 +8748 -0.870391845703125 +8749 -0.86895751953125 +8750 -0.861053466796875 +8751 -0.765869140625 +8752 -0.5301513671875 +8753 -0.214691162109375 +8754 0.137359619140625 +8755 0.474822998046875 +8756 0.76239013671875 +8757 0.867462158203125 +8758 0.870361328125 +8759 0.86480712890625 +8760 0.831817626953125 +8761 0.677581787109375 +8762 0.495880126953125 +8763 0.30767822265625 +8764 0.116180419921875 +8765 -0.110748291015625 +8766 -0.381805419921875 +8767 -0.6572265625 +8768 -0.857421875 +8769 -0.870391845703125 +8770 -0.870391845703125 +8771 -0.86444091796875 +8772 -0.85723876953125 +8773 -0.790008544921875 +8774 -0.62847900390625 +8775 -0.3956298828125 +8776 -0.126708984375 +8777 0.150115966796875 +8778 0.424041748046875 +8779 0.670623779296875 +8780 0.854522705078125 +8781 0.866485595703125 +8782 0.86920166015625 +8783 0.8653564453125 +8784 0.857147216796875 +8785 0.766845703125 +8786 0.628509521484375 +8787 0.462127685546875 +8788 0.297210693359375 +8789 0.14862060546875 +8790 -0.00537109375 +8791 -0.15753173828125 +8792 -0.31304931640625 +8793 -0.48876953125 +8794 -0.6416015625 +8795 -0.751373291015625 +8796 -0.84619140625 +8797 -0.861297607421875 +8798 -0.863250732421875 +8799 -0.856597900390625 +8800 -0.7498779296875 +8801 -0.624542236328125 +8802 -0.47808837890625 +8803 -0.253387451171875 +8804 0.003692626953125 +8805 0.2257080078125 +8806 0.427154541015625 +8807 0.643218994140625 +8808 0.855926513671875 +8809 0.870361328125 +8810 0.870361328125 +8811 0.862762451171875 +8812 0.79669189453125 +8813 0.595794677734375 +8814 0.362152099609375 +8815 0.1270751953125 +8816 -0.086944580078125 +8817 -0.2784423828125 +8818 -0.484832763671875 +8819 -0.729583740234375 +8820 -0.86688232421875 +8821 -0.870391845703125 +8822 -0.86859130859375 +8823 -0.86279296875 +8824 -0.817962646484375 +8825 -0.6116943359375 +8826 -0.3128662109375 +8827 0.039398193359375 +8828 0.422821044921875 +8829 0.805145263671875 +8830 0.870361328125 +8831 0.870361328125 +8832 0.860015869140625 +8833 0.727935791015625 +8834 0.48114013671875 +8835 0.2059326171875 +8836 -0.06103515625 +8837 -0.29913330078125 +8838 -0.516204833984375 +8839 -0.7252197265625 +8840 -0.85980224609375 +8841 -0.870391845703125 +8842 -0.870391845703125 +8843 -0.858062744140625 +8844 -0.673004150390625 +8845 -0.42694091796875 +8846 -0.2100830078125 +8847 -0.0362548828125 +8848 0.10943603515625 +8849 0.23516845703125 +8850 0.373687744140625 +8851 0.517791748046875 +8852 0.602783203125 +8853 0.635711669921875 +8854 0.655181884765625 +8855 0.65948486328125 +8856 0.651275634765625 +8857 0.61846923828125 +8858 0.53753662109375 +8859 0.404144287109375 +8860 0.22186279296875 +8861 0.003997802734375 +8862 -0.22100830078125 +8863 -0.42449951171875 +8864 -0.579833984375 +8865 -0.641876220703125 +8866 -0.6177978515625 +8867 -0.575531005859375 +8868 -0.526336669921875 +8869 -0.42645263671875 +8870 -0.2581787109375 +8871 -0.068695068359375 +8872 0.09222412109375 +8873 0.232147216796875 +8874 0.3509521484375 +8875 0.410064697265625 +8876 0.372955322265625 +8877 0.2554931640625 +8878 0.10711669921875 +8879 -0.052886962890625 +8880 -0.186279296875 +8881 -0.23291015625 +8882 -0.209442138671875 +8883 -0.174163818359375 +8884 -0.126739501953125 +8885 -0.048126220703125 +8886 0.0426025390625 +8887 0.10748291015625 +8888 0.1409912109375 +8889 0.19708251953125 +8890 0.273651123046875 +8891 0.31768798828125 +8892 0.341094970703125 +8893 0.368011474609375 +8894 0.37249755859375 +8895 0.30072021484375 +8896 0.1517333984375 +8897 -0.01470947265625 +8898 -0.1883544921875 +8899 -0.372711181640625 +8900 -0.51397705078125 +8901 -0.57177734375 +8902 -0.53948974609375 +8903 -0.43511962890625 +8904 -0.2962646484375 +8905 -0.161102294921875 +8906 -0.0435791015625 +8907 0.060394287109375 +8908 0.13665771484375 +8909 0.170135498046875 +8910 0.16552734375 +8911 0.15728759765625 +8912 0.150787353515625 +8913 0.12200927734375 +8914 0.080108642578125 +8915 0.05126953125 +8916 0.062896728515625 +8917 0.09271240234375 +8918 0.092987060546875 +8919 0.07855224609375 +8920 0.06427001953125 +8921 0.0347900390625 +8922 -0.01171875 +8923 -0.056060791015625 +8924 -0.055511474609375 +8925 -0.010467529296875 +8926 0.02508544921875 +8927 0.025665283203125 +8928 0.017333984375 +8929 0.00189208984375 +8930 -0.03173828125 +8931 -0.071502685546875 +8932 -0.13543701171875 +8933 -0.219970703125 +8934 -0.300506591796875 +8935 -0.376312255859375 +8936 -0.416107177734375 +8937 -0.371124267578125 +8938 -0.242279052734375 +8939 -0.069732666015625 +8940 0.125640869140625 +8941 0.31268310546875 +8942 0.45501708984375 +8943 0.554779052734375 +8944 0.61065673828125 +8945 0.610931396484375 +8946 0.531463623046875 +8947 0.3883056640625 +8948 0.23468017578125 +8949 0.095245361328125 +8950 -0.00396728515625 +8951 -0.04852294921875 +8952 -0.055145263671875 +8953 -0.0758056640625 +8954 -0.138702392578125 +8955 -0.209197998046875 +8956 -0.289031982421875 +8957 -0.37884521484375 +8958 -0.456329345703125 +8959 -0.51641845703125 +8960 -0.519287109375 +8961 -0.458251953125 +8962 -0.384796142578125 +8963 -0.323699951171875 +8964 -0.269287109375 +8965 -0.1951904296875 +8966 -0.100006103515625 +8967 -0.01055908203125 +8968 0.1033935546875 +8969 0.24908447265625 +8970 0.373199462890625 +8971 0.45806884765625 +8972 0.511474609375 +8973 0.565399169921875 +8974 0.61138916015625 +8975 0.5897216796875 +8976 0.4906005859375 +8977 0.33148193359375 +8978 0.147796630859375 +8979 -0.01873779296875 +8980 -0.140289306640625 +8981 -0.191986083984375 +8982 -0.184295654296875 +8983 -0.161834716796875 +8984 -0.166595458984375 +8985 -0.19390869140625 +8986 -0.22442626953125 +8987 -0.279754638671875 +8988 -0.3389892578125 +8989 -0.3543701171875 +8990 -0.348175048828125 +8991 -0.32598876953125 +8992 -0.2581787109375 +8993 -0.139801025390625 +8994 0.014617919921875 +8995 0.144378662109375 +8996 0.221038818359375 +8997 0.27069091796875 +8998 0.294036865234375 +8999 0.311767578125 +9000 0.339141845703125 +9001 0.360260009765625 +9002 0.360504150390625 +9003 0.308380126953125 +9004 0.18170166015625 +9005 0.0047607421875 +9006 -0.17559814453125 +9007 -0.3143310546875 +9008 -0.36785888671875 +9009 -0.36248779296875 +9010 -0.343536376953125 +9011 -0.3018798828125 +9012 -0.231414794921875 +9013 -0.117645263671875 +9014 0.007049560546875 +9015 0.087982177734375 +9016 0.13946533203125 +9017 0.17425537109375 +9018 0.188201904296875 +9019 0.171234130859375 +9020 0.118438720703125 +9021 0.05706787109375 +9022 -0.010711669921875 +9023 -0.0914306640625 +9024 -0.162322998046875 +9025 -0.194549560546875 +9026 -0.1492919921875 +9027 -0.02166748046875 +9028 0.124053955078125 +9029 0.211151123046875 +9030 0.240447998046875 +9031 0.242218017578125 +9032 0.2257080078125 +9033 0.194366455078125 +9034 0.115509033203125 +9035 0.0128173828125 +9036 -0.053802490234375 +9037 -0.110626220703125 +9038 -0.199493408203125 +9039 -0.29437255859375 +9040 -0.33221435546875 +9041 -0.27972412109375 +9042 -0.185333251953125 +9043 -0.128204345703125 +9044 -0.115692138671875 +9045 -0.116455078125 +9046 -0.105926513671875 +9047 -0.053955078125 +9048 0.048797607421875 +9049 0.157318115234375 +9050 0.212005615234375 +9051 0.218475341796875 +9052 0.23724365234375 +9053 0.30535888671875 +9054 0.38128662109375 +9055 0.404449462890625 +9056 0.3944091796875 +9057 0.3885498046875 +9058 0.362640380859375 +9059 0.27362060546875 +9060 0.11712646484375 +9061 -0.054901123046875 +9062 -0.19085693359375 +9063 -0.28570556640625 +9064 -0.339263916015625 +9065 -0.3775634765625 +9066 -0.445709228515625 +9067 -0.535064697265625 +9068 -0.629058837890625 +9069 -0.697601318359375 +9070 -0.70391845703125 +9071 -0.6424560546875 +9072 -0.491241455078125 +9073 -0.265716552734375 +9074 -0.023712158203125 +9075 0.201751708984375 +9076 0.375823974609375 +9077 0.485076904296875 +9078 0.56884765625 +9079 0.634765625 +9080 0.63763427734375 +9081 0.5660400390625 +9082 0.4720458984375 +9083 0.40692138671875 +9084 0.3778076171875 +9085 0.376953125 +9086 0.371978759765625 +9087 0.313140869140625 +9088 0.184417724609375 +9089 0.011199951171875 +9090 -0.171051025390625 +9091 -0.33740234375 +9092 -0.47198486328125 +9093 -0.560394287109375 +9094 -0.58056640625 +9095 -0.54754638671875 +9096 -0.508575439453125 +9097 -0.459503173828125 +9098 -0.394378662109375 +9099 -0.35260009765625 +9100 -0.31170654296875 +9101 -0.197418212890625 +9102 -0.007965087890625 +9103 0.207489013671875 +9104 0.409210205078125 +9105 0.57208251953125 +9106 0.66595458984375 +9107 0.65875244140625 +9108 0.56744384765625 +9109 0.431396484375 +9110 0.29443359375 +9111 0.182464599609375 +9112 0.06365966796875 +9113 -0.075958251953125 +9114 -0.189422607421875 +9115 -0.271942138671875 +9116 -0.342529296875 +9117 -0.364166259765625 +9118 -0.327239990234375 +9119 -0.2769775390625 +9120 -0.253692626953125 +9121 -0.24365234375 +9122 -0.1983642578125 +9123 -0.116241455078125 +9124 -0.036834716796875 +9125 0.034881591796875 +9126 0.09124755859375 +9127 0.10888671875 +9128 0.125518798828125 +9129 0.15771484375 +9130 0.17828369140625 +9131 0.17108154296875 +9132 0.129974365234375 +9133 0.082427978515625 +9134 0.027679443359375 +9135 -0.065643310546875 +9136 -0.15936279296875 +9137 -0.21307373046875 +9138 -0.234649658203125 +9139 -0.2001953125 +9140 -0.119171142578125 +9141 -0.024749755859375 +9142 0.085784912109375 +9143 0.178131103515625 +9144 0.215576171875 +9145 0.211456298828125 +9146 0.17523193359375 +9147 0.128753662109375 +9148 0.1019287109375 +9149 0.0743408203125 +9150 0.04327392578125 +9151 0.038177490234375 +9152 0.076263427734375 +9153 0.14105224609375 +9154 0.186431884765625 +9155 0.188812255859375 +9156 0.1390380859375 +9157 0.041778564453125 +9158 -0.079437255859375 +9159 -0.219390869140625 +9160 -0.367828369140625 +9161 -0.494873046875 +9162 -0.556243896484375 +9163 -0.508697509765625 +9164 -0.3756103515625 +9165 -0.218902587890625 +9166 -0.063751220703125 +9167 0.091552734375 +9168 0.23602294921875 +9169 0.342987060546875 +9170 0.39520263671875 +9171 0.389373779296875 +9172 0.324249267578125 +9173 0.224090576171875 +9174 0.124267578125 +9175 0.037078857421875 +9176 -0.010101318359375 +9177 -0.019439697265625 +9178 -0.022796630859375 +9179 -0.001556396484375 +9180 0.056304931640625 +9181 0.106719970703125 +9182 0.096893310546875 +9183 0.042694091796875 +9184 -0.018035888671875 +9185 -0.07586669921875 +9186 -0.11944580078125 +9187 -0.15972900390625 +9188 -0.202606201171875 +9189 -0.24859619140625 +9190 -0.30517578125 +9191 -0.36212158203125 +9192 -0.39141845703125 +9193 -0.35528564453125 +9194 -0.249969482421875 +9195 -0.092864990234375 +9196 0.08905029296875 +9197 0.2352294921875 +9198 0.318817138671875 +9199 0.358642578125 +9200 0.347747802734375 +9201 0.28564453125 +9202 0.223175048828125 +9203 0.196746826171875 +9204 0.179840087890625 +9205 0.155548095703125 +9206 0.151214599609375 +9207 0.156951904296875 +9208 0.13177490234375 +9209 0.100799560546875 +9210 0.087127685546875 +9211 0.05487060546875 +9212 -0.009002685546875 +9213 -0.10400390625 +9214 -0.229400634765625 +9215 -0.35552978515625 +9216 -0.441925048828125 +9217 -0.473846435546875 +9218 -0.464813232421875 +9219 -0.419097900390625 +9220 -0.334320068359375 +9221 -0.227935791015625 +9222 -0.12347412109375 +9223 -0.02764892578125 +9224 0.077667236328125 +9225 0.2132568359375 +9226 0.38885498046875 +9227 0.582794189453125 +9228 0.734039306640625 +9229 0.800140380859375 +9230 0.7783203125 +9231 0.6651611328125 +9232 0.45965576171875 +9233 0.199188232421875 +9234 -0.050689697265625 +9235 -0.23297119140625 +9236 -0.33013916015625 +9237 -0.368408203125 +9238 -0.378936767578125 +9239 -0.376983642578125 +9240 -0.37969970703125 +9241 -0.391510009765625 +9242 -0.385345458984375 +9243 -0.3419189453125 +9244 -0.28289794921875 +9245 -0.251617431640625 +9246 -0.266143798828125 +9247 -0.273345947265625 +9248 -0.216796875 +9249 -0.128265380859375 +9250 -0.068145751953125 +9251 -0.0430908203125 +9252 -0.024444580078125 +9253 0.020721435546875 +9254 0.124481201171875 +9255 0.25787353515625 +9256 0.379119873046875 +9257 0.47991943359375 +9258 0.5281982421875 +9259 0.511138916015625 +9260 0.456207275390625 +9261 0.407470703125 +9262 0.383758544921875 +9263 0.35687255859375 +9264 0.31182861328125 +9265 0.250885009765625 +9266 0.1654052734375 +9267 0.035247802734375 +9268 -0.142059326171875 +9269 -0.33563232421875 +9270 -0.5345458984375 +9271 -0.72186279296875 +9272 -0.836669921875 +9273 -0.8326416015625 +9274 -0.7296142578125 +9275 -0.582550048828125 +9276 -0.440093994140625 +9277 -0.324310302734375 +9278 -0.20147705078125 +9279 -0.044647216796875 +9280 0.103973388671875 +9281 0.202392578125 +9282 0.264495849609375 +9283 0.338897705078125 +9284 0.443817138671875 +9285 0.545074462890625 +9286 0.6173095703125 +9287 0.6524658203125 +9288 0.66339111328125 +9289 0.6561279296875 +9290 0.606781005859375 +9291 0.501190185546875 +9292 0.352783203125 +9293 0.176544189453125 +9294 -0.034820556640625 +9295 -0.258209228515625 +9296 -0.44244384765625 +9297 -0.5753173828125 +9298 -0.65203857421875 +9299 -0.641632080078125 +9300 -0.562164306640625 +9301 -0.458038330078125 +9302 -0.350555419921875 +9303 -0.260528564453125 +9304 -0.192108154296875 +9305 -0.141937255859375 +9306 -0.1021728515625 +9307 -0.062896728515625 +9308 -0.011932373046875 +9309 0.062835693359375 +9310 0.148712158203125 +9311 0.241729736328125 +9312 0.34912109375 +9313 0.457305908203125 +9314 0.54388427734375 +9315 0.5728759765625 +9316 0.506591796875 +9317 0.351226806640625 +9318 0.146514892578125 +9319 -0.05523681640625 +9320 -0.21624755859375 +9321 -0.334930419921875 +9322 -0.402984619140625 +9323 -0.4412841796875 +9324 -0.49578857421875 +9325 -0.5601806640625 +9326 -0.600738525390625 +9327 -0.584228515625 +9328 -0.47930908203125 +9329 -0.27935791015625 +9330 -0.0089111328125 +9331 0.268798828125 +9332 0.482818603515625 +9333 0.60369873046875 +9334 0.650421142578125 +9335 0.66400146484375 +9336 0.6414794921875 +9337 0.572540283203125 +9338 0.498138427734375 +9339 0.439453125 +9340 0.375518798828125 +9341 0.274505615234375 +9342 0.1087646484375 +9343 -0.099395751953125 +9344 -0.3182373046875 +9345 -0.5489501953125 +9346 -0.7738037109375 +9347 -0.86383056640625 +9348 -0.870391845703125 +9349 -0.86895751953125 +9350 -0.861053466796875 +9351 -0.765869140625 +9352 -0.5301513671875 +9353 -0.214691162109375 +9354 0.137359619140625 +9355 0.474822998046875 +9356 0.76239013671875 +9357 0.867462158203125 +9358 0.870361328125 +9359 0.86480712890625 +9360 0.831817626953125 +9361 0.677581787109375 +9362 0.495880126953125 +9363 0.30767822265625 +9364 0.116180419921875 +9365 -0.110748291015625 +9366 -0.381805419921875 +9367 -0.6572265625 +9368 -0.857421875 +9369 -0.870391845703125 +9370 -0.870391845703125 +9371 -0.86444091796875 +9372 -0.85723876953125 +9373 -0.790008544921875 +9374 -0.62847900390625 +9375 -0.3956298828125 +9376 -0.126708984375 +9377 0.150115966796875 +9378 0.424041748046875 +9379 0.670623779296875 +9380 0.854522705078125 +9381 0.866485595703125 +9382 0.86920166015625 +9383 0.8653564453125 +9384 0.857147216796875 +9385 0.766845703125 +9386 0.628509521484375 +9387 0.462127685546875 +9388 0.297210693359375 +9389 0.14862060546875 +9390 -0.00537109375 +9391 -0.15753173828125 +9392 -0.31304931640625 +9393 -0.48876953125 +9394 -0.6416015625 +9395 -0.751373291015625 +9396 -0.84619140625 +9397 -0.861297607421875 +9398 -0.863250732421875 +9399 -0.856597900390625 +9400 -0.7498779296875 +9401 -0.624542236328125 +9402 -0.47808837890625 +9403 -0.253387451171875 +9404 0.003692626953125 +9405 0.2257080078125 +9406 0.427154541015625 +9407 0.643218994140625 +9408 0.855926513671875 +9409 0.870361328125 +9410 0.870361328125 +9411 0.862762451171875 +9412 0.79669189453125 +9413 0.595794677734375 +9414 0.362152099609375 +9415 0.1270751953125 +9416 -0.086944580078125 +9417 -0.2784423828125 +9418 -0.484832763671875 +9419 -0.729583740234375 +9420 -0.86688232421875 +9421 -0.870391845703125 +9422 -0.86859130859375 +9423 -0.86279296875 +9424 -0.817962646484375 +9425 -0.6116943359375 +9426 -0.3128662109375 +9427 0.039398193359375 +9428 0.422821044921875 +9429 0.805145263671875 +9430 0.870361328125 +9431 0.870361328125 +9432 0.860015869140625 +9433 0.727935791015625 +9434 0.48114013671875 +9435 0.2059326171875 +9436 -0.06103515625 +9437 -0.29913330078125 +9438 -0.516204833984375 +9439 -0.7252197265625 +9440 -0.85980224609375 +9441 -0.870391845703125 +9442 -0.870391845703125 +9443 -0.858062744140625 +9444 -0.673004150390625 +9445 -0.42694091796875 +9446 -0.2100830078125 +9447 -0.0362548828125 +9448 0.10943603515625 +9449 0.23516845703125 +9450 0.373687744140625 +9451 0.517791748046875 +9452 0.602783203125 +9453 0.635711669921875 +9454 0.655181884765625 +9455 0.65948486328125 +9456 0.651275634765625 +9457 0.61846923828125 +9458 0.53753662109375 +9459 0.404144287109375 +9460 0.22186279296875 +9461 0.003997802734375 +9462 -0.22100830078125 +9463 -0.42449951171875 +9464 -0.579833984375 +9465 -0.641876220703125 +9466 -0.6177978515625 +9467 -0.575531005859375 +9468 -0.526336669921875 +9469 -0.42645263671875 +9470 -0.2581787109375 +9471 -0.068695068359375 +9472 0.09222412109375 +9473 0.232147216796875 +9474 0.3509521484375 +9475 0.410064697265625 +9476 0.372955322265625 +9477 0.2554931640625 +9478 0.10711669921875 +9479 -0.052886962890625 +9480 -0.186279296875 +9481 -0.23291015625 +9482 -0.209442138671875 +9483 -0.174163818359375 +9484 -0.126739501953125 +9485 -0.048126220703125 +9486 0.0426025390625 +9487 0.10748291015625 +9488 0.1409912109375 +9489 0.19708251953125 +9490 0.273651123046875 +9491 0.31768798828125 +9492 0.341094970703125 +9493 0.368011474609375 +9494 0.37249755859375 +9495 0.30072021484375 +9496 0.1517333984375 +9497 -0.01470947265625 +9498 -0.1883544921875 +9499 -0.372711181640625 +9500 -0.51397705078125 +9501 -0.57177734375 +9502 -0.53948974609375 +9503 -0.43511962890625 +9504 -0.2962646484375 +9505 -0.161102294921875 +9506 -0.0435791015625 +9507 0.060394287109375 +9508 0.13665771484375 +9509 0.170135498046875 +9510 0.16552734375 +9511 0.15728759765625 +9512 0.150787353515625 +9513 0.12200927734375 +9514 0.080108642578125 +9515 0.05126953125 +9516 0.062896728515625 +9517 0.09271240234375 +9518 0.092987060546875 +9519 0.07855224609375 +9520 0.06427001953125 +9521 0.0347900390625 +9522 -0.01171875 +9523 -0.056060791015625 +9524 -0.055511474609375 +9525 -0.010467529296875 +9526 0.02508544921875 +9527 0.025665283203125 +9528 0.017333984375 +9529 0.00189208984375 +9530 -0.03173828125 +9531 -0.071502685546875 +9532 -0.13543701171875 +9533 -0.219970703125 +9534 -0.300506591796875 +9535 -0.376312255859375 +9536 -0.416107177734375 +9537 -0.371124267578125 +9538 -0.242279052734375 +9539 -0.069732666015625 +9540 0.125640869140625 +9541 0.31268310546875 +9542 0.45501708984375 +9543 0.554779052734375 +9544 0.61065673828125 +9545 0.610931396484375 +9546 0.531463623046875 +9547 0.3883056640625 +9548 0.23468017578125 +9549 0.095245361328125 +9550 -0.00396728515625 +9551 -0.04852294921875 +9552 -0.055145263671875 +9553 -0.0758056640625 +9554 -0.138702392578125 +9555 -0.209197998046875 +9556 -0.289031982421875 +9557 -0.37884521484375 +9558 -0.456329345703125 +9559 -0.51641845703125 +9560 -0.519287109375 +9561 -0.458251953125 +9562 -0.384796142578125 +9563 -0.323699951171875 +9564 -0.269287109375 +9565 -0.1951904296875 +9566 -0.100006103515625 +9567 -0.01055908203125 +9568 0.1033935546875 +9569 0.24908447265625 +9570 0.373199462890625 +9571 0.45806884765625 +9572 0.511474609375 +9573 0.565399169921875 +9574 0.61138916015625 +9575 0.5897216796875 +9576 0.4906005859375 +9577 0.33148193359375 +9578 0.147796630859375 +9579 -0.01873779296875 +9580 -0.140289306640625 +9581 -0.191986083984375 +9582 -0.184295654296875 +9583 -0.161834716796875 +9584 -0.166595458984375 +9585 -0.19390869140625 +9586 -0.22442626953125 +9587 -0.279754638671875 +9588 -0.3389892578125 +9589 -0.3543701171875 +9590 -0.348175048828125 +9591 -0.32598876953125 +9592 -0.2581787109375 +9593 -0.139801025390625 +9594 0.014617919921875 +9595 0.144378662109375 +9596 0.221038818359375 +9597 0.27069091796875 +9598 0.294036865234375 +9599 0.311767578125 +9600 0.339141845703125 +9601 0.360260009765625 +9602 0.360504150390625 +9603 0.308380126953125 +9604 0.18170166015625 +9605 0.0047607421875 +9606 -0.17559814453125 +9607 -0.3143310546875 +9608 -0.36785888671875 +9609 -0.36248779296875 +9610 -0.343536376953125 +9611 -0.3018798828125 +9612 -0.231414794921875 +9613 -0.117645263671875 +9614 0.007049560546875 +9615 0.087982177734375 +9616 0.13946533203125 +9617 0.17425537109375 +9618 0.188201904296875 +9619 0.171234130859375 +9620 0.118438720703125 +9621 0.05706787109375 +9622 -0.010711669921875 +9623 -0.0914306640625 +9624 -0.162322998046875 +9625 -0.194549560546875 +9626 -0.1492919921875 +9627 -0.02166748046875 +9628 0.124053955078125 +9629 0.211151123046875 +9630 0.240447998046875 +9631 0.242218017578125 +9632 0.2257080078125 +9633 0.194366455078125 +9634 0.115509033203125 +9635 0.0128173828125 +9636 -0.053802490234375 +9637 -0.110626220703125 +9638 -0.199493408203125 +9639 -0.29437255859375 +9640 -0.33221435546875 +9641 -0.27972412109375 +9642 -0.185333251953125 +9643 -0.128204345703125 +9644 -0.115692138671875 +9645 -0.116455078125 +9646 -0.105926513671875 +9647 -0.053955078125 +9648 0.048797607421875 +9649 0.157318115234375 +9650 0.212005615234375 +9651 0.218475341796875 +9652 0.23724365234375 +9653 0.30535888671875 +9654 0.38128662109375 +9655 0.404449462890625 +9656 0.3944091796875 +9657 0.3885498046875 +9658 0.362640380859375 +9659 0.27362060546875 +9660 0.11712646484375 +9661 -0.054901123046875 +9662 -0.19085693359375 +9663 -0.28570556640625 +9664 -0.339263916015625 +9665 -0.3775634765625 +9666 -0.445709228515625 +9667 -0.535064697265625 +9668 -0.629058837890625 +9669 -0.697601318359375 +9670 -0.70391845703125 +9671 -0.6424560546875 +9672 -0.491241455078125 +9673 -0.265716552734375 +9674 -0.023712158203125 +9675 0.201751708984375 +9676 0.375823974609375 +9677 0.485076904296875 +9678 0.56884765625 +9679 0.634765625 +9680 0.63763427734375 +9681 0.5660400390625 +9682 0.4720458984375 +9683 0.40692138671875 +9684 0.3778076171875 +9685 0.376953125 +9686 0.371978759765625 +9687 0.313140869140625 +9688 0.184417724609375 +9689 0.011199951171875 +9690 -0.171051025390625 +9691 -0.33740234375 +9692 -0.47198486328125 +9693 -0.560394287109375 +9694 -0.58056640625 +9695 -0.54754638671875 +9696 -0.508575439453125 +9697 -0.459503173828125 +9698 -0.394378662109375 +9699 -0.35260009765625 +9700 -0.31170654296875 +9701 -0.197418212890625 +9702 -0.007965087890625 +9703 0.207489013671875 +9704 0.409210205078125 +9705 0.57208251953125 +9706 0.66595458984375 +9707 0.65875244140625 +9708 0.56744384765625 +9709 0.431396484375 +9710 0.29443359375 +9711 0.182464599609375 +9712 0.06365966796875 +9713 -0.075958251953125 +9714 -0.189422607421875 +9715 -0.271942138671875 +9716 -0.342529296875 +9717 -0.364166259765625 +9718 -0.327239990234375 +9719 -0.2769775390625 +9720 -0.253692626953125 +9721 -0.24365234375 +9722 -0.1983642578125 +9723 -0.116241455078125 +9724 -0.036834716796875 +9725 0.034881591796875 +9726 0.09124755859375 +9727 0.10888671875 +9728 0.125518798828125 +9729 0.15771484375 +9730 0.17828369140625 +9731 0.17108154296875 +9732 0.129974365234375 +9733 0.082427978515625 +9734 0.027679443359375 +9735 -0.065643310546875 +9736 -0.15936279296875 +9737 -0.21307373046875 +9738 -0.234649658203125 +9739 -0.2001953125 +9740 -0.119171142578125 +9741 -0.024749755859375 +9742 0.085784912109375 +9743 0.178131103515625 +9744 0.215576171875 +9745 0.211456298828125 +9746 0.17523193359375 +9747 0.128753662109375 +9748 0.1019287109375 +9749 0.0743408203125 +9750 0.04327392578125 +9751 0.038177490234375 +9752 0.076263427734375 +9753 0.14105224609375 +9754 0.186431884765625 +9755 0.188812255859375 +9756 0.1390380859375 +9757 0.041778564453125 +9758 -0.079437255859375 +9759 -0.219390869140625 +9760 -0.367828369140625 +9761 -0.494873046875 +9762 -0.556243896484375 +9763 -0.508697509765625 +9764 -0.3756103515625 +9765 -0.218902587890625 +9766 -0.063751220703125 +9767 0.091552734375 +9768 0.23602294921875 +9769 0.342987060546875 +9770 0.39520263671875 +9771 0.389373779296875 +9772 0.324249267578125 +9773 0.224090576171875 +9774 0.124267578125 +9775 0.037078857421875 +9776 -0.010101318359375 +9777 -0.019439697265625 +9778 -0.022796630859375 +9779 -0.001556396484375 +9780 0.056304931640625 +9781 0.106719970703125 +9782 0.096893310546875 +9783 0.042694091796875 +9784 -0.018035888671875 +9785 -0.07586669921875 +9786 -0.11944580078125 +9787 -0.15972900390625 +9788 -0.202606201171875 +9789 -0.24859619140625 +9790 -0.30517578125 +9791 -0.36212158203125 +9792 -0.39141845703125 +9793 -0.35528564453125 +9794 -0.249969482421875 +9795 -0.092864990234375 +9796 0.08905029296875 +9797 0.2352294921875 +9798 0.318817138671875 +9799 0.358642578125 +9800 0.347747802734375 +9801 0.28564453125 +9802 0.223175048828125 +9803 0.196746826171875 +9804 0.179840087890625 +9805 0.155548095703125 +9806 0.151214599609375 +9807 0.156951904296875 +9808 0.13177490234375 +9809 0.100799560546875 +9810 0.087127685546875 +9811 0.05487060546875 +9812 -0.009002685546875 +9813 -0.10400390625 +9814 -0.229400634765625 +9815 -0.35552978515625 +9816 -0.441925048828125 +9817 -0.473846435546875 +9818 -0.464813232421875 +9819 -0.419097900390625 +9820 -0.334320068359375 +9821 -0.227935791015625 +9822 -0.12347412109375 +9823 -0.02764892578125 +9824 0.077667236328125 +9825 0.2132568359375 +9826 0.38885498046875 +9827 0.582794189453125 +9828 0.734039306640625 +9829 0.800140380859375 +9830 0.7783203125 +9831 0.6651611328125 +9832 0.45965576171875 +9833 0.199188232421875 +9834 -0.050689697265625 +9835 -0.23297119140625 +9836 -0.33013916015625 +9837 -0.368408203125 +9838 -0.378936767578125 +9839 -0.376983642578125 +9840 -0.37969970703125 +9841 -0.391510009765625 +9842 -0.385345458984375 +9843 -0.3419189453125 +9844 -0.28289794921875 +9845 -0.251617431640625 +9846 -0.266143798828125 +9847 -0.273345947265625 +9848 -0.216796875 +9849 -0.128265380859375 +9850 -0.068145751953125 +9851 -0.0430908203125 +9852 -0.024444580078125 +9853 0.020721435546875 +9854 0.124481201171875 +9855 0.25787353515625 +9856 0.379119873046875 +9857 0.47991943359375 +9858 0.5281982421875 +9859 0.511138916015625 +9860 0.456207275390625 +9861 0.407470703125 +9862 0.383758544921875 +9863 0.35687255859375 +9864 0.31182861328125 +9865 0.250885009765625 +9866 0.1654052734375 +9867 0.035247802734375 +9868 -0.142059326171875 +9869 -0.33563232421875 +9870 -0.5345458984375 +9871 -0.72186279296875 +9872 -0.836669921875 +9873 -0.8326416015625 +9874 -0.7296142578125 +9875 -0.582550048828125 +9876 -0.440093994140625 +9877 -0.324310302734375 +9878 -0.20147705078125 +9879 -0.044647216796875 +9880 0.103973388671875 +9881 0.202392578125 +9882 0.264495849609375 +9883 0.338897705078125 +9884 0.443817138671875 +9885 0.545074462890625 +9886 0.6173095703125 +9887 0.6524658203125 +9888 0.66339111328125 +9889 0.6561279296875 +9890 0.606781005859375 +9891 0.501190185546875 +9892 0.352783203125 +9893 0.176544189453125 +9894 -0.034820556640625 +9895 -0.258209228515625 +9896 -0.44244384765625 +9897 -0.5753173828125 +9898 -0.65203857421875 +9899 -0.641632080078125 +9900 -0.562164306640625 +9901 -0.458038330078125 +9902 -0.350555419921875 +9903 -0.260528564453125 +9904 -0.192108154296875 +9905 -0.141937255859375 +9906 -0.1021728515625 +9907 -0.062896728515625 +9908 -0.011932373046875 +9909 0.062835693359375 +9910 0.148712158203125 +9911 0.241729736328125 +9912 0.34912109375 +9913 0.457305908203125 +9914 0.54388427734375 +9915 0.5728759765625 +9916 0.506591796875 +9917 0.351226806640625 +9918 0.146514892578125 +9919 -0.05523681640625 +9920 -0.21624755859375 +9921 -0.334930419921875 +9922 -0.402984619140625 +9923 -0.4412841796875 +9924 -0.49578857421875 +9925 -0.5601806640625 +9926 -0.600738525390625 +9927 -0.584228515625 +9928 -0.47930908203125 +9929 -0.27935791015625 +9930 -0.0089111328125 +9931 0.268798828125 +9932 0.482818603515625 +9933 0.60369873046875 +9934 0.650421142578125 +9935 0.66400146484375 +9936 0.6414794921875 +9937 0.572540283203125 +9938 0.498138427734375 +9939 0.439453125 +9940 0.375518798828125 +9941 0.274505615234375 +9942 0.1087646484375 +9943 -0.099395751953125 +9944 -0.3182373046875 +9945 -0.5489501953125 +9946 -0.7738037109375 +9947 -0.86383056640625 +9948 -0.870391845703125 +9949 -0.86895751953125 +9950 -0.861053466796875 +9951 -0.765869140625 +9952 -0.5301513671875 +9953 -0.214691162109375 +9954 0.137359619140625 +9955 0.474822998046875 +9956 0.76239013671875 +9957 0.867462158203125 +9958 0.870361328125 +9959 0.86480712890625 +9960 0.831817626953125 +9961 0.677581787109375 +9962 0.495880126953125 +9963 0.30767822265625 +9964 0.116180419921875 +9965 -0.110748291015625 +9966 -0.381805419921875 +9967 -0.6572265625 +9968 -0.857421875 +9969 -0.870391845703125 +9970 -0.870391845703125 +9971 -0.86444091796875 +9972 -0.85723876953125 +9973 -0.790008544921875 +9974 -0.62847900390625 +9975 -0.3956298828125 +9976 -0.126708984375 +9977 0.150115966796875 +9978 0.424041748046875 +9979 0.670623779296875 +9980 0.854522705078125 +9981 0.866485595703125 +9982 0.86920166015625 +9983 0.8653564453125 +9984 0.857147216796875 +9985 0.766845703125 +9986 0.628509521484375 +9987 0.462127685546875 +9988 0.297210693359375 +9989 0.14862060546875 +9990 -0.00537109375 +9991 -0.15753173828125 +9992 -0.31304931640625 +9993 -0.48876953125 +9994 -0.6416015625 +9995 -0.751373291015625 +9996 -0.84619140625 +9997 -0.861297607421875 +9998 -0.863250732421875 +9999 -0.856597900390625 +10000 -0.7498779296875 +10001 -0.624542236328125 +10002 -0.47808837890625 +10003 -0.253387451171875 +10004 0.003692626953125 +10005 0.2257080078125 +10006 0.427154541015625 +10007 0.643218994140625 +10008 0.855926513671875 +10009 0.870361328125 +10010 0.870361328125 +10011 0.862762451171875 +10012 0.79669189453125 +10013 0.595794677734375 +10014 0.362152099609375 +10015 0.1270751953125 +10016 -0.086944580078125 +10017 -0.2784423828125 +10018 -0.484832763671875 +10019 -0.729583740234375 +10020 -0.86688232421875 +10021 -0.870391845703125 +10022 -0.86859130859375 +10023 -0.86279296875 +10024 -0.817962646484375 +10025 -0.6116943359375 +10026 -0.3128662109375 +10027 0.039398193359375 +10028 0.422821044921875 +10029 0.805145263671875 +10030 0.870361328125 +10031 0.870361328125 +10032 0.860015869140625 +10033 0.727935791015625 +10034 0.48114013671875 +10035 0.2059326171875 +10036 -0.06103515625 +10037 -0.29913330078125 +10038 -0.516204833984375 +10039 -0.7252197265625 +10040 -0.85980224609375 +10041 -0.870391845703125 +10042 -0.870391845703125 +10043 -0.858062744140625 +10044 -0.673004150390625 +10045 -0.42694091796875 +10046 -0.2100830078125 +10047 -0.0362548828125 +10048 0.10943603515625 +10049 0.23516845703125 +10050 0.373687744140625 +10051 0.517791748046875 +10052 0.602783203125 +10053 0.635711669921875 +10054 0.655181884765625 +10055 0.65948486328125 +10056 0.651275634765625 +10057 0.61846923828125 +10058 0.53753662109375 +10059 0.404144287109375 +10060 0.22186279296875 +10061 0.003997802734375 +10062 -0.22100830078125 +10063 -0.42449951171875 +10064 -0.579833984375 +10065 -0.641876220703125 +10066 -0.6177978515625 +10067 -0.575531005859375 +10068 -0.526336669921875 +10069 -0.42645263671875 +10070 -0.2581787109375 +10071 -0.068695068359375 +10072 0.09222412109375 +10073 0.232147216796875 +10074 0.3509521484375 +10075 0.410064697265625 +10076 0.372955322265625 +10077 0.2554931640625 +10078 0.10711669921875 +10079 -0.052886962890625 +10080 -0.186279296875 +10081 -0.23291015625 +10082 -0.209442138671875 +10083 -0.174163818359375 +10084 -0.126739501953125 +10085 -0.048126220703125 +10086 0.0426025390625 +10087 0.10748291015625 +10088 0.1409912109375 +10089 0.19708251953125 +10090 0.273651123046875 +10091 0.31768798828125 +10092 0.341094970703125 +10093 0.368011474609375 +10094 0.37249755859375 +10095 0.30072021484375 +10096 0.1517333984375 +10097 -0.01470947265625 +10098 -0.1883544921875 +10099 -0.372711181640625 +10100 -0.51397705078125 +10101 -0.57177734375 +10102 -0.53948974609375 +10103 -0.43511962890625 +10104 -0.2962646484375 +10105 -0.161102294921875 +10106 -0.0435791015625 +10107 0.060394287109375 +10108 0.13665771484375 +10109 0.170135498046875 +10110 0.16552734375 +10111 0.15728759765625 +10112 0.150787353515625 +10113 0.12200927734375 +10114 0.080108642578125 +10115 0.05126953125 +10116 0.062896728515625 +10117 0.09271240234375 +10118 0.092987060546875 +10119 0.07855224609375 +10120 0.06427001953125 +10121 0.0347900390625 +10122 -0.01171875 +10123 -0.056060791015625 +10124 -0.055511474609375 +10125 -0.010467529296875 +10126 0.02508544921875 +10127 0.025665283203125 +10128 0.017333984375 +10129 0.00189208984375 +10130 -0.03173828125 +10131 -0.071502685546875 +10132 -0.13543701171875 +10133 -0.219970703125 +10134 -0.300506591796875 +10135 -0.376312255859375 +10136 -0.416107177734375 +10137 -0.371124267578125 +10138 -0.242279052734375 +10139 -0.069732666015625 +10140 0.125640869140625 +10141 0.31268310546875 +10142 0.45501708984375 +10143 0.554779052734375 +10144 0.61065673828125 +10145 0.610931396484375 +10146 0.531463623046875 +10147 0.3883056640625 +10148 0.23468017578125 +10149 0.095245361328125 +10150 -0.00396728515625 +10151 -0.04852294921875 +10152 -0.055145263671875 +10153 -0.0758056640625 +10154 -0.138702392578125 +10155 -0.209197998046875 +10156 -0.289031982421875 +10157 -0.37884521484375 +10158 -0.456329345703125 +10159 -0.51641845703125 +10160 -0.519287109375 +10161 -0.458251953125 +10162 -0.384796142578125 +10163 -0.323699951171875 +10164 -0.269287109375 +10165 -0.1951904296875 +10166 -0.100006103515625 +10167 -0.01055908203125 +10168 0.1033935546875 +10169 0.24908447265625 +10170 0.373199462890625 +10171 0.45806884765625 +10172 0.511474609375 +10173 0.565399169921875 +10174 0.61138916015625 +10175 0.5897216796875 +10176 0.4906005859375 +10177 0.33148193359375 +10178 0.147796630859375 +10179 -0.01873779296875 +10180 -0.140289306640625 +10181 -0.191986083984375 +10182 -0.184295654296875 +10183 -0.161834716796875 +10184 -0.166595458984375 +10185 -0.19390869140625 +10186 -0.22442626953125 +10187 -0.279754638671875 +10188 -0.3389892578125 +10189 -0.3543701171875 +10190 -0.348175048828125 +10191 -0.32598876953125 +10192 -0.2581787109375 +10193 -0.139801025390625 +10194 0.014617919921875 +10195 0.144378662109375 +10196 0.221038818359375 +10197 0.27069091796875 +10198 0.294036865234375 +10199 0.311767578125 +10200 0.339141845703125 +10201 0.360260009765625 +10202 0.360504150390625 +10203 0.308380126953125 +10204 0.18170166015625 +10205 0.0047607421875 +10206 -0.17559814453125 +10207 -0.3143310546875 +10208 -0.36785888671875 +10209 -0.36248779296875 +10210 -0.343536376953125 +10211 -0.3018798828125 +10212 -0.231414794921875 +10213 -0.117645263671875 +10214 0.007049560546875 +10215 0.087982177734375 +10216 0.13946533203125 +10217 0.17425537109375 +10218 0.188201904296875 +10219 0.171234130859375 +10220 0.118438720703125 +10221 0.05706787109375 +10222 -0.010711669921875 +10223 -0.0914306640625 +10224 -0.162322998046875 +10225 -0.194549560546875 +10226 -0.1492919921875 +10227 -0.02166748046875 +10228 0.124053955078125 +10229 0.211151123046875 +10230 0.240447998046875 +10231 0.242218017578125 +10232 0.2257080078125 +10233 0.194366455078125 +10234 0.115509033203125 +10235 0.0128173828125 +10236 -0.053802490234375 +10237 -0.110626220703125 +10238 -0.199493408203125 +10239 -0.29437255859375 +10240 -0.33221435546875 +10241 -0.27972412109375 +10242 -0.185333251953125 +10243 -0.128204345703125 +10244 -0.115692138671875 +10245 -0.116455078125 +10246 -0.105926513671875 +10247 -0.053955078125 +10248 0.048797607421875 +10249 0.157318115234375 +10250 0.212005615234375 +10251 0.218475341796875 +10252 0.23724365234375 +10253 0.30535888671875 +10254 0.38128662109375 +10255 0.404449462890625 +10256 0.3944091796875 +10257 0.3885498046875 +10258 0.362640380859375 +10259 0.27362060546875 +10260 0.11712646484375 +10261 -0.054901123046875 +10262 -0.19085693359375 +10263 -0.28570556640625 +10264 -0.339263916015625 +10265 -0.3775634765625 +10266 -0.445709228515625 +10267 -0.535064697265625 +10268 -0.629058837890625 +10269 -0.697601318359375 +10270 -0.70391845703125 +10271 -0.6424560546875 +10272 -0.491241455078125 +10273 -0.265716552734375 +10274 -0.023712158203125 +10275 0.201751708984375 +10276 0.375823974609375 +10277 0.485076904296875 +10278 0.56884765625 +10279 0.634765625 +10280 0.63763427734375 +10281 0.5660400390625 +10282 0.4720458984375 +10283 0.40692138671875 +10284 0.3778076171875 +10285 0.376953125 +10286 0.371978759765625 +10287 0.313140869140625 +10288 0.184417724609375 +10289 0.011199951171875 +10290 -0.171051025390625 +10291 -0.33740234375 +10292 -0.47198486328125 +10293 -0.560394287109375 +10294 -0.58056640625 +10295 -0.54754638671875 +10296 -0.508575439453125 +10297 -0.459503173828125 +10298 -0.394378662109375 +10299 -0.35260009765625 +10300 -0.31170654296875 +10301 -0.197418212890625 +10302 -0.007965087890625 +10303 0.207489013671875 +10304 0.409210205078125 +10305 0.57208251953125 +10306 0.66595458984375 +10307 0.65875244140625 +10308 0.56744384765625 +10309 0.431396484375 +10310 0.29443359375 +10311 0.182464599609375 +10312 0.06365966796875 +10313 -0.075958251953125 +10314 -0.189422607421875 +10315 -0.271942138671875 +10316 -0.342529296875 +10317 -0.364166259765625 +10318 -0.327239990234375 +10319 -0.2769775390625 +10320 -0.253692626953125 +10321 -0.24365234375 +10322 -0.1983642578125 +10323 -0.116241455078125 +10324 -0.036834716796875 +10325 0.034881591796875 +10326 0.09124755859375 +10327 0.10888671875 +10328 0.125518798828125 +10329 0.15771484375 +10330 0.17828369140625 +10331 0.17108154296875 +10332 0.129974365234375 +10333 0.082427978515625 +10334 0.027679443359375 +10335 -0.065643310546875 +10336 -0.15936279296875 +10337 -0.21307373046875 +10338 -0.234649658203125 +10339 -0.2001953125 +10340 -0.119171142578125 +10341 -0.024749755859375 +10342 0.085784912109375 +10343 0.178131103515625 +10344 0.215576171875 +10345 0.211456298828125 +10346 0.17523193359375 +10347 0.128753662109375 +10348 0.1019287109375 +10349 0.0743408203125 +10350 0.04327392578125 +10351 0.038177490234375 +10352 0.076263427734375 +10353 0.14105224609375 +10354 0.186431884765625 +10355 0.188812255859375 +10356 0.1390380859375 +10357 0.041778564453125 +10358 -0.079437255859375 +10359 -0.219390869140625 +10360 -0.367828369140625 +10361 -0.494873046875 +10362 -0.556243896484375 +10363 -0.508697509765625 +10364 -0.3756103515625 +10365 -0.218902587890625 +10366 -0.063751220703125 +10367 0.091552734375 +10368 0.23602294921875 +10369 0.342987060546875 +10370 0.39520263671875 +10371 0.389373779296875 +10372 0.324249267578125 +10373 0.224090576171875 +10374 0.124267578125 +10375 0.037078857421875 +10376 -0.010101318359375 +10377 -0.019439697265625 +10378 -0.022796630859375 +10379 -0.001556396484375 +10380 0.056304931640625 +10381 0.106719970703125 +10382 0.096893310546875 +10383 0.042694091796875 +10384 -0.018035888671875 +10385 -0.07586669921875 +10386 -0.11944580078125 +10387 -0.15972900390625 +10388 -0.202606201171875 +10389 -0.24859619140625 +10390 -0.30517578125 +10391 -0.36212158203125 +10392 -0.39141845703125 +10393 -0.35528564453125 +10394 -0.249969482421875 +10395 -0.092864990234375 +10396 0.08905029296875 +10397 0.2352294921875 +10398 0.318817138671875 +10399 0.358642578125 +10400 0.347747802734375 +10401 0.28564453125 +10402 0.223175048828125 +10403 0.196746826171875 +10404 0.179840087890625 +10405 0.155548095703125 +10406 0.151214599609375 +10407 0.156951904296875 +10408 0.13177490234375 +10409 0.100799560546875 +10410 0.087127685546875 +10411 0.05487060546875 +10412 -0.009002685546875 +10413 -0.10400390625 +10414 -0.229400634765625 +10415 -0.35552978515625 +10416 -0.441925048828125 +10417 -0.473846435546875 +10418 -0.464813232421875 +10419 -0.419097900390625 +10420 -0.334320068359375 +10421 -0.227935791015625 +10422 -0.12347412109375 +10423 -0.02764892578125 +10424 0.077667236328125 +10425 0.2132568359375 +10426 0.38885498046875 +10427 0.582794189453125 +10428 0.734039306640625 +10429 0.800140380859375 +10430 0.7783203125 +10431 0.6651611328125 +10432 0.45965576171875 +10433 0.199188232421875 +10434 -0.050689697265625 +10435 -0.23297119140625 +10436 -0.33013916015625 +10437 -0.368408203125 +10438 -0.378936767578125 +10439 -0.376983642578125 +10440 -0.37969970703125 +10441 -0.391510009765625 +10442 -0.385345458984375 +10443 -0.3419189453125 +10444 -0.28289794921875 +10445 -0.251617431640625 +10446 -0.266143798828125 +10447 -0.273345947265625 +10448 -0.216796875 +10449 -0.128265380859375 +10450 -0.068145751953125 +10451 -0.0430908203125 +10452 -0.024444580078125 +10453 0.020721435546875 +10454 0.124481201171875 +10455 0.25787353515625 +10456 0.379119873046875 +10457 0.47991943359375 +10458 0.5281982421875 +10459 0.511138916015625 +10460 0.456207275390625 +10461 0.407470703125 +10462 0.383758544921875 +10463 0.35687255859375 +10464 0.31182861328125 +10465 0.250885009765625 +10466 0.1654052734375 +10467 0.035247802734375 +10468 -0.142059326171875 +10469 -0.33563232421875 +10470 -0.5345458984375 +10471 -0.72186279296875 +10472 -0.836669921875 +10473 -0.8326416015625 +10474 -0.7296142578125 +10475 -0.582550048828125 +10476 -0.440093994140625 +10477 -0.324310302734375 +10478 -0.20147705078125 +10479 -0.044647216796875 +10480 0.103973388671875 +10481 0.202392578125 +10482 0.264495849609375 +10483 0.338897705078125 +10484 0.443817138671875 +10485 0.545074462890625 +10486 0.6173095703125 +10487 0.6524658203125 +10488 0.66339111328125 +10489 0.6561279296875 +10490 0.606781005859375 +10491 0.501190185546875 +10492 0.352783203125 +10493 0.176544189453125 +10494 -0.034820556640625 +10495 -0.258209228515625 +10496 -0.44244384765625 +10497 -0.5753173828125 +10498 -0.65203857421875 +10499 -0.641632080078125 +10500 -0.562164306640625 +10501 -0.458038330078125 +10502 -0.350555419921875 +10503 -0.260528564453125 +10504 -0.192108154296875 +10505 -0.141937255859375 +10506 -0.1021728515625 +10507 -0.062896728515625 +10508 -0.011932373046875 +10509 0.062835693359375 +10510 0.148712158203125 +10511 0.241729736328125 +10512 0.34912109375 +10513 0.457305908203125 +10514 0.54388427734375 +10515 0.5728759765625 +10516 0.506591796875 +10517 0.351226806640625 +10518 0.146514892578125 +10519 -0.05523681640625 +10520 -0.21624755859375 +10521 -0.334930419921875 +10522 -0.402984619140625 +10523 -0.4412841796875 +10524 -0.49578857421875 +10525 -0.5601806640625 +10526 -0.600738525390625 +10527 -0.584228515625 +10528 -0.47930908203125 +10529 -0.27935791015625 +10530 -0.0089111328125 +10531 0.268798828125 +10532 0.482818603515625 +10533 0.60369873046875 +10534 0.650421142578125 +10535 0.66400146484375 +10536 0.6414794921875 +10537 0.572540283203125 +10538 0.498138427734375 +10539 0.439453125 +10540 0.375518798828125 +10541 0.274505615234375 +10542 0.1087646484375 +10543 -0.099395751953125 +10544 -0.3182373046875 +10545 -0.5489501953125 +10546 -0.7738037109375 +10547 -0.86383056640625 +10548 -0.870391845703125 +10549 -0.86895751953125 +10550 -0.861053466796875 +10551 -0.765869140625 +10552 -0.5301513671875 +10553 -0.214691162109375 +10554 0.137359619140625 +10555 0.474822998046875 +10556 0.76239013671875 +10557 0.867462158203125 +10558 0.870361328125 +10559 0.86480712890625 +10560 0.831817626953125 +10561 0.677581787109375 +10562 0.495880126953125 +10563 0.30767822265625 +10564 0.116180419921875 +10565 -0.110748291015625 +10566 -0.381805419921875 +10567 -0.6572265625 +10568 -0.857421875 +10569 -0.870391845703125 +10570 -0.870391845703125 +10571 -0.86444091796875 +10572 -0.85723876953125 +10573 -0.790008544921875 +10574 -0.62847900390625 +10575 -0.3956298828125 +10576 -0.126708984375 +10577 0.150115966796875 +10578 0.424041748046875 +10579 0.670623779296875 +10580 0.854522705078125 +10581 0.866485595703125 +10582 0.86920166015625 +10583 0.8653564453125 +10584 0.857147216796875 +10585 0.766845703125 +10586 0.628509521484375 +10587 0.462127685546875 +10588 0.297210693359375 +10589 0.14862060546875 +10590 -0.00537109375 +10591 -0.15753173828125 +10592 -0.31304931640625 +10593 -0.48876953125 +10594 -0.6416015625 +10595 -0.751373291015625 +10596 -0.84619140625 +10597 -0.861297607421875 +10598 -0.863250732421875 +10599 -0.856597900390625 +10600 -0.7498779296875 +10601 -0.624542236328125 +10602 -0.47808837890625 +10603 -0.253387451171875 +10604 0.003692626953125 +10605 0.2257080078125 +10606 0.427154541015625 +10607 0.643218994140625 +10608 0.855926513671875 +10609 0.870361328125 +10610 0.870361328125 +10611 0.862762451171875 +10612 0.79669189453125 +10613 0.595794677734375 +10614 0.362152099609375 +10615 0.1270751953125 +10616 -0.086944580078125 +10617 -0.2784423828125 +10618 -0.484832763671875 +10619 -0.729583740234375 +10620 -0.86688232421875 +10621 -0.870391845703125 +10622 -0.86859130859375 +10623 -0.86279296875 +10624 -0.817962646484375 +10625 -0.6116943359375 +10626 -0.3128662109375 +10627 0.039398193359375 +10628 0.422821044921875 +10629 0.805145263671875 +10630 0.870361328125 +10631 0.870361328125 +10632 0.860015869140625 +10633 0.727935791015625 +10634 0.48114013671875 +10635 0.2059326171875 +10636 -0.06103515625 +10637 -0.29913330078125 +10638 -0.516204833984375 +10639 -0.7252197265625 +10640 -0.85980224609375 +10641 -0.870391845703125 +10642 -0.870391845703125 +10643 -0.858062744140625 +10644 -0.673004150390625 +10645 -0.42694091796875 +10646 -0.2100830078125 +10647 -0.0362548828125 +10648 0.10943603515625 +10649 0.23516845703125 +10650 0.373687744140625 +10651 0.517791748046875 +10652 0.602783203125 +10653 0.635711669921875 +10654 0.655181884765625 +10655 0.65948486328125 +10656 0.651275634765625 +10657 0.61846923828125 +10658 0.53753662109375 +10659 0.404144287109375 +10660 0.22186279296875 +10661 0.003997802734375 +10662 -0.22100830078125 +10663 -0.42449951171875 +10664 -0.579833984375 +10665 -0.641876220703125 +10666 -0.6177978515625 +10667 -0.575531005859375 +10668 -0.526336669921875 +10669 -0.42645263671875 +10670 -0.2581787109375 +10671 -0.068695068359375 +10672 0.09222412109375 +10673 0.232147216796875 +10674 0.3509521484375 +10675 0.410064697265625 +10676 0.372955322265625 +10677 0.2554931640625 +10678 0.10711669921875 +10679 -0.052886962890625 +10680 -0.186279296875 +10681 -0.23291015625 +10682 -0.209442138671875 +10683 -0.174163818359375 +10684 -0.126739501953125 +10685 -0.048126220703125 +10686 0.0426025390625 +10687 0.10748291015625 +10688 0.1409912109375 +10689 0.19708251953125 +10690 0.273651123046875 +10691 0.31768798828125 +10692 0.341094970703125 +10693 0.368011474609375 +10694 0.37249755859375 +10695 0.30072021484375 +10696 0.1517333984375 +10697 -0.01470947265625 +10698 -0.1883544921875 +10699 -0.372711181640625 +10700 -0.51397705078125 +10701 -0.57177734375 +10702 -0.53948974609375 +10703 -0.43511962890625 +10704 -0.2962646484375 +10705 -0.161102294921875 +10706 -0.0435791015625 +10707 0.060394287109375 +10708 0.13665771484375 +10709 0.170135498046875 +10710 0.16552734375 +10711 0.15728759765625 +10712 0.150787353515625 +10713 0.12200927734375 +10714 0.080108642578125 +10715 0.05126953125 +10716 0.062896728515625 +10717 0.09271240234375 +10718 0.092987060546875 +10719 0.07855224609375 +10720 0.06427001953125 +10721 0.0347900390625 +10722 -0.01171875 +10723 -0.056060791015625 +10724 -0.055511474609375 +10725 -0.010467529296875 +10726 0.02508544921875 +10727 0.025665283203125 +10728 0.017333984375 +10729 0.00189208984375 +10730 -0.03173828125 +10731 -0.071502685546875 +10732 -0.13543701171875 +10733 -0.219970703125 +10734 -0.300506591796875 +10735 -0.376312255859375 +10736 -0.416107177734375 +10737 -0.371124267578125 +10738 -0.242279052734375 +10739 -0.069732666015625 +10740 0.125640869140625 +10741 0.31268310546875 +10742 0.45501708984375 +10743 0.554779052734375 +10744 0.61065673828125 +10745 0.610931396484375 +10746 0.531463623046875 +10747 0.3883056640625 +10748 0.23468017578125 +10749 0.095245361328125 +10750 -0.00396728515625 +10751 -0.04852294921875 +10752 -0.055145263671875 +10753 -0.0758056640625 +10754 -0.138702392578125 +10755 -0.209197998046875 +10756 -0.289031982421875 +10757 -0.37884521484375 +10758 -0.456329345703125 +10759 -0.51641845703125 +10760 -0.519287109375 +10761 -0.458251953125 +10762 -0.384796142578125 +10763 -0.323699951171875 +10764 -0.269287109375 +10765 -0.1951904296875 +10766 -0.100006103515625 +10767 -0.01055908203125 +10768 0.1033935546875 +10769 0.24908447265625 +10770 0.373199462890625 +10771 0.45806884765625 +10772 0.511474609375 +10773 0.565399169921875 +10774 0.61138916015625 +10775 0.5897216796875 +10776 0.4906005859375 +10777 0.33148193359375 +10778 0.147796630859375 +10779 -0.01873779296875 +10780 -0.140289306640625 +10781 -0.191986083984375 +10782 -0.184295654296875 +10783 -0.161834716796875 +10784 -0.166595458984375 +10785 -0.19390869140625 +10786 -0.22442626953125 +10787 -0.279754638671875 +10788 -0.3389892578125 +10789 -0.3543701171875 +10790 -0.348175048828125 +10791 -0.32598876953125 +10792 -0.2581787109375 +10793 -0.139801025390625 +10794 0.014617919921875 +10795 0.144378662109375 +10796 0.221038818359375 +10797 0.27069091796875 +10798 0.294036865234375 +10799 0.311767578125 +10800 0.339141845703125 +10801 0.360260009765625 +10802 0.360504150390625 +10803 0.308380126953125 +10804 0.18170166015625 +10805 0.0047607421875 +10806 -0.17559814453125 +10807 -0.3143310546875 +10808 -0.36785888671875 +10809 -0.36248779296875 +10810 -0.343536376953125 +10811 -0.3018798828125 +10812 -0.231414794921875 +10813 -0.117645263671875 +10814 0.007049560546875 +10815 0.087982177734375 +10816 0.13946533203125 +10817 0.17425537109375 +10818 0.188201904296875 +10819 0.171234130859375 +10820 0.118438720703125 +10821 0.05706787109375 +10822 -0.010711669921875 +10823 -0.0914306640625 +10824 -0.162322998046875 +10825 -0.194549560546875 +10826 -0.1492919921875 +10827 -0.02166748046875 +10828 0.124053955078125 +10829 0.211151123046875 +10830 0.240447998046875 +10831 0.242218017578125 +10832 0.2257080078125 +10833 0.194366455078125 +10834 0.115509033203125 +10835 0.0128173828125 +10836 -0.053802490234375 +10837 -0.110626220703125 +10838 -0.199493408203125 +10839 -0.29437255859375 +10840 -0.33221435546875 +10841 -0.27972412109375 +10842 -0.185333251953125 +10843 -0.128204345703125 +10844 -0.115692138671875 +10845 -0.116455078125 +10846 -0.105926513671875 +10847 -0.053955078125 +10848 0.048797607421875 +10849 0.157318115234375 +10850 0.212005615234375 +10851 0.218475341796875 +10852 0.23724365234375 +10853 0.30535888671875 +10854 0.38128662109375 +10855 0.404449462890625 +10856 0.3944091796875 +10857 0.3885498046875 +10858 0.362640380859375 +10859 0.27362060546875 +10860 0.11712646484375 +10861 -0.054901123046875 +10862 -0.19085693359375 +10863 -0.28570556640625 +10864 -0.339263916015625 +10865 -0.3775634765625 +10866 -0.445709228515625 +10867 -0.535064697265625 +10868 -0.629058837890625 +10869 -0.697601318359375 +10870 -0.70391845703125 +10871 -0.6424560546875 +10872 -0.491241455078125 +10873 -0.265716552734375 +10874 -0.023712158203125 +10875 0.201751708984375 +10876 0.375823974609375 +10877 0.485076904296875 +10878 0.56884765625 +10879 0.634765625 +10880 0.63763427734375 +10881 0.5660400390625 +10882 0.4720458984375 +10883 0.40692138671875 +10884 0.3778076171875 +10885 0.376953125 +10886 0.371978759765625 +10887 0.313140869140625 +10888 0.184417724609375 +10889 0.011199951171875 +10890 -0.171051025390625 +10891 -0.33740234375 +10892 -0.47198486328125 +10893 -0.560394287109375 +10894 -0.58056640625 +10895 -0.54754638671875 +10896 -0.508575439453125 +10897 -0.459503173828125 +10898 -0.394378662109375 +10899 -0.35260009765625 +10900 -0.31170654296875 +10901 -0.197418212890625 +10902 -0.007965087890625 +10903 0.207489013671875 +10904 0.409210205078125 +10905 0.57208251953125 +10906 0.66595458984375 +10907 0.65875244140625 +10908 0.56744384765625 +10909 0.431396484375 +10910 0.29443359375 +10911 0.182464599609375 +10912 0.06365966796875 +10913 -0.075958251953125 +10914 -0.189422607421875 +10915 -0.271942138671875 +10916 -0.342529296875 +10917 -0.364166259765625 +10918 -0.327239990234375 +10919 -0.2769775390625 +10920 -0.253692626953125 +10921 -0.24365234375 +10922 -0.1983642578125 +10923 -0.116241455078125 +10924 -0.036834716796875 +10925 0.034881591796875 +10926 0.09124755859375 +10927 0.10888671875 +10928 0.125518798828125 +10929 0.15771484375 +10930 0.17828369140625 +10931 0.17108154296875 +10932 0.129974365234375 +10933 0.082427978515625 +10934 0.027679443359375 +10935 -0.065643310546875 +10936 -0.15936279296875 +10937 -0.21307373046875 +10938 -0.234649658203125 +10939 -0.2001953125 +10940 -0.119171142578125 +10941 -0.024749755859375 +10942 0.085784912109375 +10943 0.178131103515625 +10944 0.215576171875 +10945 0.211456298828125 +10946 0.17523193359375 +10947 0.128753662109375 +10948 0.1019287109375 +10949 0.0743408203125 +10950 0.04327392578125 +10951 0.038177490234375 +10952 0.076263427734375 +10953 0.14105224609375 +10954 0.186431884765625 +10955 0.188812255859375 +10956 0.1390380859375 +10957 0.041778564453125 +10958 -0.079437255859375 +10959 -0.219390869140625 +10960 -0.367828369140625 +10961 -0.494873046875 +10962 -0.556243896484375 +10963 -0.508697509765625 +10964 -0.3756103515625 +10965 -0.218902587890625 +10966 -0.063751220703125 +10967 0.091552734375 +10968 0.23602294921875 +10969 0.342987060546875 +10970 0.39520263671875 +10971 0.389373779296875 +10972 0.324249267578125 +10973 0.224090576171875 +10974 0.124267578125 +10975 0.037078857421875 +10976 -0.010101318359375 +10977 -0.019439697265625 +10978 -0.022796630859375 +10979 -0.001556396484375 +10980 0.056304931640625 +10981 0.106719970703125 +10982 0.096893310546875 +10983 0.042694091796875 +10984 -0.018035888671875 +10985 -0.07586669921875 +10986 -0.11944580078125 +10987 -0.15972900390625 +10988 -0.202606201171875 +10989 -0.24859619140625 +10990 -0.30517578125 +10991 -0.36212158203125 +10992 -0.39141845703125 +10993 -0.35528564453125 +10994 -0.249969482421875 +10995 -0.092864990234375 +10996 0.08905029296875 +10997 0.2352294921875 +10998 0.318817138671875 +10999 0.358642578125 +11000 0.347747802734375 +11001 0.28564453125 +11002 0.223175048828125 +11003 0.196746826171875 +11004 0.179840087890625 +11005 0.155548095703125 +11006 0.151214599609375 +11007 0.156951904296875 +11008 0.13177490234375 +11009 0.100799560546875 +11010 0.087127685546875 +11011 0.05487060546875 +11012 -0.009002685546875 +11013 -0.10400390625 +11014 -0.229400634765625 +11015 -0.35552978515625 +11016 -0.441925048828125 +11017 -0.473846435546875 +11018 -0.464813232421875 +11019 -0.419097900390625 +11020 -0.334320068359375 +11021 -0.227935791015625 +11022 -0.12347412109375 +11023 -0.02764892578125 +11024 0.077667236328125 +11025 0.2132568359375 +11026 0.38885498046875 +11027 0.582794189453125 +11028 0.734039306640625 +11029 0.800140380859375 +11030 0.7783203125 +11031 0.6651611328125 +11032 0.45965576171875 +11033 0.199188232421875 +11034 -0.050689697265625 +11035 -0.23297119140625 +11036 -0.33013916015625 +11037 -0.368408203125 +11038 -0.378936767578125 +11039 -0.376983642578125 +11040 -0.37969970703125 +11041 -0.391510009765625 +11042 -0.385345458984375 +11043 -0.3419189453125 +11044 -0.28289794921875 +11045 -0.251617431640625 +11046 -0.266143798828125 +11047 -0.273345947265625 +11048 -0.216796875 +11049 -0.128265380859375 +11050 -0.068145751953125 +11051 -0.0430908203125 +11052 -0.024444580078125 +11053 0.020721435546875 +11054 0.124481201171875 +11055 0.25787353515625 +11056 0.379119873046875 +11057 0.47991943359375 +11058 0.5281982421875 +11059 0.511138916015625 +11060 0.456207275390625 +11061 0.407470703125 +11062 0.383758544921875 +11063 0.35687255859375 +11064 0.31182861328125 +11065 0.250885009765625 +11066 0.1654052734375 +11067 0.035247802734375 +11068 -0.142059326171875 +11069 -0.33563232421875 +11070 -0.5345458984375 +11071 -0.72186279296875 +11072 -0.836669921875 +11073 -0.8326416015625 +11074 -0.7296142578125 +11075 -0.582550048828125 +11076 -0.440093994140625 +11077 -0.324310302734375 +11078 -0.20147705078125 +11079 -0.044647216796875 +11080 0.103973388671875 +11081 0.202392578125 +11082 0.264495849609375 +11083 0.338897705078125 +11084 0.443817138671875 +11085 0.545074462890625 +11086 0.6173095703125 +11087 0.6524658203125 +11088 0.66339111328125 +11089 0.6561279296875 +11090 0.606781005859375 +11091 0.501190185546875 +11092 0.352783203125 +11093 0.176544189453125 +11094 -0.034820556640625 +11095 -0.258209228515625 +11096 -0.44244384765625 +11097 -0.5753173828125 +11098 -0.65203857421875 +11099 -0.641632080078125 +11100 -0.562164306640625 +11101 -0.458038330078125 +11102 -0.350555419921875 +11103 -0.260528564453125 +11104 -0.192108154296875 +11105 -0.141937255859375 +11106 -0.1021728515625 +11107 -0.062896728515625 +11108 -0.011932373046875 +11109 0.062835693359375 +11110 0.148712158203125 +11111 0.241729736328125 +11112 0.34912109375 +11113 0.457305908203125 +11114 0.54388427734375 +11115 0.5728759765625 +11116 0.506591796875 +11117 0.351226806640625 +11118 0.146514892578125 +11119 -0.05523681640625 +11120 -0.21624755859375 +11121 -0.334930419921875 +11122 -0.402984619140625 +11123 -0.4412841796875 +11124 -0.49578857421875 +11125 -0.5601806640625 +11126 -0.600738525390625 +11127 -0.584228515625 +11128 -0.47930908203125 +11129 -0.27935791015625 +11130 -0.0089111328125 +11131 0.268798828125 +11132 0.482818603515625 +11133 0.60369873046875 +11134 0.650421142578125 +11135 0.66400146484375 +11136 0.6414794921875 +11137 0.572540283203125 +11138 0.498138427734375 +11139 0.439453125 +11140 0.375518798828125 +11141 0.274505615234375 +11142 0.1087646484375 +11143 -0.099395751953125 +11144 -0.3182373046875 +11145 -0.5489501953125 +11146 -0.7738037109375 +11147 -0.86383056640625 +11148 -0.870391845703125 +11149 -0.86895751953125 +11150 -0.861053466796875 +11151 -0.765869140625 +11152 -0.5301513671875 +11153 -0.214691162109375 +11154 0.137359619140625 +11155 0.474822998046875 +11156 0.76239013671875 +11157 0.867462158203125 +11158 0.870361328125 +11159 0.86480712890625 +11160 0.831817626953125 +11161 0.677581787109375 +11162 0.495880126953125 +11163 0.30767822265625 +11164 0.116180419921875 +11165 -0.110748291015625 +11166 -0.381805419921875 +11167 -0.6572265625 +11168 -0.857421875 +11169 -0.870391845703125 +11170 -0.870391845703125 +11171 -0.86444091796875 +11172 -0.85723876953125 +11173 -0.790008544921875 +11174 -0.62847900390625 +11175 -0.3956298828125 +11176 -0.126708984375 +11177 0.150115966796875 +11178 0.424041748046875 +11179 0.670623779296875 +11180 0.854522705078125 +11181 0.866485595703125 +11182 0.86920166015625 +11183 0.8653564453125 +11184 0.857147216796875 +11185 0.766845703125 +11186 0.628509521484375 +11187 0.462127685546875 +11188 0.297210693359375 +11189 0.14862060546875 +11190 -0.00537109375 +11191 -0.15753173828125 +11192 -0.31304931640625 +11193 -0.48876953125 +11194 -0.6416015625 +11195 -0.751373291015625 +11196 -0.84619140625 +11197 -0.861297607421875 +11198 -0.863250732421875 +11199 -0.856597900390625 +11200 -0.7498779296875 +11201 -0.624542236328125 +11202 -0.47808837890625 +11203 -0.253387451171875 +11204 0.003692626953125 +11205 0.2257080078125 +11206 0.427154541015625 +11207 0.643218994140625 +11208 0.855926513671875 +11209 0.870361328125 +11210 0.870361328125 +11211 0.862762451171875 +11212 0.79669189453125 +11213 0.595794677734375 +11214 0.362152099609375 +11215 0.1270751953125 +11216 -0.086944580078125 +11217 -0.2784423828125 +11218 -0.484832763671875 +11219 -0.729583740234375 +11220 -0.86688232421875 +11221 -0.870391845703125 +11222 -0.86859130859375 +11223 -0.86279296875 +11224 -0.817962646484375 +11225 -0.6116943359375 +11226 -0.3128662109375 +11227 0.039398193359375 +11228 0.422821044921875 +11229 0.805145263671875 +11230 0.870361328125 +11231 0.870361328125 +11232 0.860015869140625 +11233 0.727935791015625 +11234 0.48114013671875 +11235 0.2059326171875 +11236 -0.06103515625 +11237 -0.29913330078125 +11238 -0.516204833984375 +11239 -0.7252197265625 +11240 -0.85980224609375 +11241 -0.870391845703125 +11242 -0.870391845703125 +11243 -0.858062744140625 +11244 -0.673004150390625 +11245 -0.42694091796875 +11246 -0.2100830078125 +11247 -0.0362548828125 +11248 0.10943603515625 +11249 0.23516845703125 +11250 0.373687744140625 +11251 0.517791748046875 +11252 0.602783203125 +11253 0.635711669921875 +11254 0.655181884765625 +11255 0.65948486328125 +11256 0.651275634765625 +11257 0.61846923828125 +11258 0.53753662109375 +11259 0.404144287109375 +11260 0.22186279296875 +11261 0.003997802734375 +11262 -0.22100830078125 +11263 -0.42449951171875 +11264 -0.579833984375 +11265 -0.641876220703125 +11266 -0.6177978515625 +11267 -0.575531005859375 +11268 -0.526336669921875 +11269 -0.42645263671875 +11270 -0.2581787109375 +11271 -0.068695068359375 +11272 0.09222412109375 +11273 0.232147216796875 +11274 0.3509521484375 +11275 0.410064697265625 +11276 0.372955322265625 +11277 0.2554931640625 +11278 0.10711669921875 +11279 -0.052886962890625 +11280 -0.186279296875 +11281 -0.23291015625 +11282 -0.209442138671875 +11283 -0.174163818359375 +11284 -0.126739501953125 +11285 -0.048126220703125 +11286 0.0426025390625 +11287 0.10748291015625 +11288 0.1409912109375 +11289 0.19708251953125 +11290 0.273651123046875 +11291 0.31768798828125 +11292 0.341094970703125 +11293 0.368011474609375 +11294 0.37249755859375 +11295 0.30072021484375 +11296 0.1517333984375 +11297 -0.01470947265625 +11298 -0.1883544921875 +11299 -0.372711181640625 +11300 -0.51397705078125 +11301 -0.57177734375 +11302 -0.53948974609375 +11303 -0.43511962890625 +11304 -0.2962646484375 +11305 -0.161102294921875 +11306 -0.0435791015625 +11307 0.060394287109375 +11308 0.13665771484375 +11309 0.170135498046875 +11310 0.16552734375 +11311 0.15728759765625 +11312 0.150787353515625 +11313 0.12200927734375 +11314 0.080108642578125 +11315 0.05126953125 +11316 0.062896728515625 +11317 0.09271240234375 +11318 0.092987060546875 +11319 0.07855224609375 +11320 0.06427001953125 +11321 0.0347900390625 +11322 -0.01171875 +11323 -0.056060791015625 +11324 -0.055511474609375 +11325 -0.010467529296875 +11326 0.02508544921875 +11327 0.025665283203125 +11328 0.017333984375 +11329 0.00189208984375 +11330 -0.03173828125 +11331 -0.071502685546875 +11332 -0.13543701171875 +11333 -0.219970703125 +11334 -0.300506591796875 +11335 -0.376312255859375 +11336 -0.416107177734375 +11337 -0.371124267578125 +11338 -0.242279052734375 +11339 -0.069732666015625 +11340 0.125640869140625 +11341 0.31268310546875 +11342 0.45501708984375 +11343 0.554779052734375 +11344 0.61065673828125 +11345 0.610931396484375 +11346 0.531463623046875 +11347 0.3883056640625 +11348 0.23468017578125 +11349 0.095245361328125 +11350 -0.00396728515625 +11351 -0.04852294921875 +11352 -0.055145263671875 +11353 -0.0758056640625 +11354 -0.138702392578125 +11355 -0.209197998046875 +11356 -0.289031982421875 +11357 -0.37884521484375 +11358 -0.456329345703125 +11359 -0.51641845703125 +11360 -0.519287109375 +11361 -0.458251953125 +11362 -0.384796142578125 +11363 -0.323699951171875 +11364 -0.269287109375 +11365 -0.1951904296875 +11366 -0.100006103515625 +11367 -0.01055908203125 +11368 0.1033935546875 +11369 0.24908447265625 +11370 0.373199462890625 +11371 0.45806884765625 +11372 0.511474609375 +11373 0.565399169921875 +11374 0.61138916015625 +11375 0.5897216796875 +11376 0.4906005859375 +11377 0.33148193359375 +11378 0.147796630859375 +11379 -0.01873779296875 +11380 -0.140289306640625 +11381 -0.191986083984375 +11382 -0.184295654296875 +11383 -0.161834716796875 +11384 -0.166595458984375 +11385 -0.19390869140625 +11386 -0.22442626953125 +11387 -0.279754638671875 +11388 -0.3389892578125 +11389 -0.3543701171875 +11390 -0.348175048828125 +11391 -0.32598876953125 +11392 -0.2581787109375 +11393 -0.139801025390625 +11394 0.014617919921875 +11395 0.144378662109375 +11396 0.221038818359375 +11397 0.27069091796875 +11398 0.294036865234375 +11399 0.311767578125 +11400 0.339141845703125 +11401 0.360260009765625 +11402 0.360504150390625 +11403 0.308380126953125 +11404 0.18170166015625 +11405 0.0047607421875 +11406 -0.17559814453125 +11407 -0.3143310546875 +11408 -0.36785888671875 +11409 -0.36248779296875 +11410 -0.343536376953125 +11411 -0.3018798828125 +11412 -0.231414794921875 +11413 -0.117645263671875 +11414 0.007049560546875 +11415 0.087982177734375 +11416 0.13946533203125 +11417 0.17425537109375 +11418 0.188201904296875 +11419 0.171234130859375 +11420 0.118438720703125 +11421 0.05706787109375 +11422 -0.010711669921875 +11423 -0.0914306640625 +11424 -0.162322998046875 +11425 -0.194549560546875 +11426 -0.1492919921875 +11427 -0.02166748046875 +11428 0.124053955078125 +11429 0.211151123046875 +11430 0.240447998046875 +11431 0.242218017578125 +11432 0.2257080078125 +11433 0.194366455078125 +11434 0.115509033203125 +11435 0.0128173828125 +11436 -0.053802490234375 +11437 -0.110626220703125 +11438 -0.199493408203125 +11439 -0.29437255859375 +11440 -0.33221435546875 +11441 -0.27972412109375 +11442 -0.185333251953125 +11443 -0.128204345703125 +11444 -0.115692138671875 +11445 -0.116455078125 +11446 -0.105926513671875 +11447 -0.053955078125 +11448 0.048797607421875 +11449 0.157318115234375 +11450 0.212005615234375 +11451 0.218475341796875 +11452 0.23724365234375 +11453 0.30535888671875 +11454 0.38128662109375 +11455 0.404449462890625 +11456 0.3944091796875 +11457 0.3885498046875 +11458 0.362640380859375 +11459 0.27362060546875 +11460 0.11712646484375 +11461 -0.054901123046875 +11462 -0.19085693359375 +11463 -0.28570556640625 +11464 -0.339263916015625 +11465 -0.3775634765625 +11466 -0.445709228515625 +11467 -0.535064697265625 +11468 -0.629058837890625 +11469 -0.697601318359375 +11470 -0.70391845703125 +11471 -0.6424560546875 +11472 -0.491241455078125 +11473 -0.265716552734375 +11474 -0.023712158203125 +11475 0.201751708984375 +11476 0.375823974609375 +11477 0.485076904296875 +11478 0.56884765625 +11479 0.634765625 +11480 0.63763427734375 +11481 0.5660400390625 +11482 0.4720458984375 +11483 0.40692138671875 +11484 0.3778076171875 +11485 0.376953125 +11486 0.371978759765625 +11487 0.313140869140625 +11488 0.184417724609375 +11489 0.011199951171875 +11490 -0.171051025390625 +11491 -0.33740234375 +11492 -0.47198486328125 +11493 -0.560394287109375 +11494 -0.58056640625 +11495 -0.54754638671875 +11496 -0.508575439453125 +11497 -0.459503173828125 +11498 -0.394378662109375 +11499 -0.35260009765625 +11500 -0.31170654296875 +11501 -0.197418212890625 +11502 -0.007965087890625 +11503 0.207489013671875 +11504 0.409210205078125 +11505 0.57208251953125 +11506 0.66595458984375 +11507 0.65875244140625 +11508 0.56744384765625 +11509 0.431396484375 +11510 0.29443359375 +11511 0.182464599609375 +11512 0.06365966796875 +11513 -0.075958251953125 +11514 -0.189422607421875 +11515 -0.271942138671875 +11516 -0.342529296875 +11517 -0.364166259765625 +11518 -0.327239990234375 +11519 -0.2769775390625 +11520 -0.253692626953125 +11521 -0.24365234375 +11522 -0.1983642578125 +11523 -0.116241455078125 +11524 -0.036834716796875 +11525 0.034881591796875 +11526 0.09124755859375 +11527 0.10888671875 +11528 0.125518798828125 +11529 0.15771484375 +11530 0.17828369140625 +11531 0.17108154296875 +11532 0.129974365234375 +11533 0.082427978515625 +11534 0.027679443359375 +11535 -0.065643310546875 +11536 -0.15936279296875 +11537 -0.21307373046875 +11538 -0.234649658203125 +11539 -0.2001953125 +11540 -0.119171142578125 +11541 -0.024749755859375 +11542 0.085784912109375 +11543 0.178131103515625 +11544 0.215576171875 +11545 0.211456298828125 +11546 0.17523193359375 +11547 0.128753662109375 +11548 0.1019287109375 +11549 0.0743408203125 +11550 0.04327392578125 +11551 0.038177490234375 +11552 0.076263427734375 +11553 0.14105224609375 +11554 0.186431884765625 +11555 0.188812255859375 +11556 0.1390380859375 +11557 0.041778564453125 +11558 -0.079437255859375 +11559 -0.219390869140625 +11560 -0.367828369140625 +11561 -0.494873046875 +11562 -0.556243896484375 +11563 -0.508697509765625 +11564 -0.3756103515625 +11565 -0.218902587890625 +11566 -0.063751220703125 +11567 0.091552734375 +11568 0.23602294921875 +11569 0.342987060546875 +11570 0.39520263671875 +11571 0.389373779296875 +11572 0.324249267578125 +11573 0.224090576171875 +11574 0.124267578125 +11575 0.037078857421875 +11576 -0.010101318359375 +11577 -0.019439697265625 +11578 -0.022796630859375 +11579 -0.001556396484375 +11580 0.056304931640625 +11581 0.106719970703125 +11582 0.096893310546875 +11583 0.042694091796875 +11584 -0.018035888671875 +11585 -0.07586669921875 +11586 -0.11944580078125 +11587 -0.15972900390625 +11588 -0.202606201171875 +11589 -0.24859619140625 +11590 -0.30517578125 +11591 -0.36212158203125 +11592 -0.39141845703125 +11593 -0.35528564453125 +11594 -0.249969482421875 +11595 -0.092864990234375 +11596 0.08905029296875 +11597 0.2352294921875 +11598 0.318817138671875 +11599 0.358642578125 +11600 0.347747802734375 +11601 0.28564453125 +11602 0.223175048828125 +11603 0.196746826171875 +11604 0.179840087890625 +11605 0.155548095703125 +11606 0.151214599609375 +11607 0.156951904296875 +11608 0.13177490234375 +11609 0.100799560546875 +11610 0.087127685546875 +11611 0.05487060546875 +11612 -0.009002685546875 +11613 -0.10400390625 +11614 -0.229400634765625 +11615 -0.35552978515625 +11616 -0.441925048828125 +11617 -0.473846435546875 +11618 -0.464813232421875 +11619 -0.419097900390625 +11620 -0.334320068359375 +11621 -0.227935791015625 +11622 -0.12347412109375 +11623 -0.02764892578125 +11624 0.077667236328125 +11625 0.2132568359375 +11626 0.38885498046875 +11627 0.582794189453125 +11628 0.734039306640625 +11629 0.800140380859375 +11630 0.7783203125 +11631 0.6651611328125 +11632 0.45965576171875 +11633 0.199188232421875 +11634 -0.050689697265625 +11635 -0.23297119140625 +11636 -0.33013916015625 +11637 -0.368408203125 +11638 -0.378936767578125 +11639 -0.376983642578125 +11640 -0.37969970703125 +11641 -0.391510009765625 +11642 -0.385345458984375 +11643 -0.3419189453125 +11644 -0.28289794921875 +11645 -0.251617431640625 +11646 -0.266143798828125 +11647 -0.273345947265625 +11648 -0.216796875 +11649 -0.128265380859375 +11650 -0.068145751953125 +11651 -0.0430908203125 +11652 -0.024444580078125 +11653 0.020721435546875 +11654 0.124481201171875 +11655 0.25787353515625 +11656 0.379119873046875 +11657 0.47991943359375 +11658 0.5281982421875 +11659 0.511138916015625 +11660 0.456207275390625 +11661 0.407470703125 +11662 0.383758544921875 +11663 0.35687255859375 +11664 0.31182861328125 +11665 0.250885009765625 +11666 0.1654052734375 +11667 0.035247802734375 +11668 -0.142059326171875 +11669 -0.33563232421875 +11670 -0.5345458984375 +11671 -0.72186279296875 +11672 -0.836669921875 +11673 -0.8326416015625 +11674 -0.7296142578125 +11675 -0.582550048828125 +11676 -0.440093994140625 +11677 -0.324310302734375 +11678 -0.20147705078125 +11679 -0.044647216796875 +11680 0.103973388671875 +11681 0.202392578125 +11682 0.264495849609375 +11683 0.338897705078125 +11684 0.443817138671875 +11685 0.545074462890625 +11686 0.6173095703125 +11687 0.6524658203125 +11688 0.66339111328125 +11689 0.6561279296875 +11690 0.606781005859375 +11691 0.501190185546875 +11692 0.352783203125 +11693 0.176544189453125 +11694 -0.034820556640625 +11695 -0.258209228515625 +11696 -0.44244384765625 +11697 -0.5753173828125 +11698 -0.65203857421875 +11699 -0.641632080078125 +11700 -0.562164306640625 +11701 -0.458038330078125 +11702 -0.350555419921875 +11703 -0.260528564453125 +11704 -0.192108154296875 +11705 -0.141937255859375 +11706 -0.1021728515625 +11707 -0.062896728515625 +11708 -0.011932373046875 +11709 0.062835693359375 +11710 0.148712158203125 +11711 0.241729736328125 +11712 0.34912109375 +11713 0.457305908203125 +11714 0.54388427734375 +11715 0.5728759765625 +11716 0.506591796875 +11717 0.351226806640625 +11718 0.146514892578125 +11719 -0.05523681640625 +11720 -0.21624755859375 +11721 -0.334930419921875 +11722 -0.402984619140625 +11723 -0.4412841796875 +11724 -0.49578857421875 +11725 -0.5601806640625 +11726 -0.600738525390625 +11727 -0.584228515625 +11728 -0.47930908203125 +11729 -0.27935791015625 +11730 -0.0089111328125 +11731 0.268798828125 +11732 0.482818603515625 +11733 0.60369873046875 +11734 0.650421142578125 +11735 0.66400146484375 +11736 0.6414794921875 +11737 0.572540283203125 +11738 0.498138427734375 +11739 0.439453125 +11740 0.375518798828125 +11741 0.274505615234375 +11742 0.1087646484375 +11743 -0.099395751953125 +11744 -0.3182373046875 +11745 -0.5489501953125 +11746 -0.7738037109375 +11747 -0.86383056640625 +11748 -0.870391845703125 +11749 -0.86895751953125 +11750 -0.861053466796875 +11751 -0.765869140625 +11752 -0.5301513671875 +11753 -0.214691162109375 +11754 0.137359619140625 +11755 0.474822998046875 +11756 0.76239013671875 +11757 0.867462158203125 +11758 0.870361328125 +11759 0.86480712890625 +11760 0.831817626953125 +11761 0.677581787109375 +11762 0.495880126953125 +11763 0.30767822265625 +11764 0.116180419921875 +11765 -0.110748291015625 +11766 -0.381805419921875 +11767 -0.6572265625 +11768 -0.857421875 +11769 -0.870391845703125 +11770 -0.870391845703125 +11771 -0.86444091796875 +11772 -0.85723876953125 +11773 -0.790008544921875 +11774 -0.62847900390625 +11775 -0.3956298828125 +11776 -0.126708984375 +11777 0.150115966796875 +11778 0.424041748046875 +11779 0.670623779296875 +11780 0.854522705078125 +11781 0.866485595703125 +11782 0.86920166015625 +11783 0.8653564453125 +11784 0.857147216796875 +11785 0.766845703125 +11786 0.628509521484375 +11787 0.462127685546875 +11788 0.297210693359375 +11789 0.14862060546875 +11790 -0.00537109375 +11791 -0.15753173828125 +11792 -0.31304931640625 +11793 -0.48876953125 +11794 -0.6416015625 +11795 -0.751373291015625 +11796 -0.84619140625 +11797 -0.861297607421875 +11798 -0.863250732421875 +11799 -0.856597900390625 +11800 -0.7498779296875 +11801 -0.624542236328125 +11802 -0.47808837890625 +11803 -0.253387451171875 +11804 0.003692626953125 +11805 0.2257080078125 +11806 0.427154541015625 +11807 0.643218994140625 +11808 0.855926513671875 +11809 0.870361328125 +11810 0.870361328125 +11811 0.862762451171875 +11812 0.79669189453125 +11813 0.595794677734375 +11814 0.362152099609375 +11815 0.1270751953125 +11816 -0.086944580078125 +11817 -0.2784423828125 +11818 -0.484832763671875 +11819 -0.729583740234375 +11820 -0.86688232421875 +11821 -0.870391845703125 +11822 -0.86859130859375 +11823 -0.86279296875 +11824 -0.817962646484375 +11825 -0.6116943359375 +11826 -0.3128662109375 +11827 0.039398193359375 +11828 0.422821044921875 +11829 0.805145263671875 +11830 0.870361328125 +11831 0.870361328125 +11832 0.860015869140625 +11833 0.727935791015625 +11834 0.48114013671875 +11835 0.2059326171875 +11836 -0.06103515625 +11837 -0.29913330078125 +11838 -0.516204833984375 +11839 -0.7252197265625 +11840 -0.85980224609375 +11841 -0.870391845703125 +11842 -0.870391845703125 +11843 -0.858062744140625 +11844 -0.673004150390625 +11845 -0.42694091796875 +11846 -0.2100830078125 +11847 -0.0362548828125 +11848 0.10943603515625 +11849 0.23516845703125 +11850 0.373687744140625 +11851 0.517791748046875 +11852 0.602783203125 +11853 0.635711669921875 +11854 0.655181884765625 +11855 0.65948486328125 +11856 0.651275634765625 +11857 0.61846923828125 +11858 0.53753662109375 +11859 0.404144287109375 +11860 0.22186279296875 +11861 0.003997802734375 +11862 -0.22100830078125 +11863 -0.42449951171875 +11864 -0.579833984375 +11865 -0.641876220703125 +11866 -0.6177978515625 +11867 -0.575531005859375 +11868 -0.526336669921875 +11869 -0.42645263671875 +11870 -0.2581787109375 +11871 -0.068695068359375 +11872 0.09222412109375 +11873 0.232147216796875 +11874 0.3509521484375 +11875 0.410064697265625 +11876 0.372955322265625 +11877 0.2554931640625 +11878 0.10711669921875 +11879 -0.052886962890625 +11880 -0.186279296875 +11881 -0.23291015625 +11882 -0.209442138671875 +11883 -0.174163818359375 +11884 -0.126739501953125 +11885 -0.048126220703125 +11886 0.0426025390625 +11887 0.10748291015625 +11888 0.1409912109375 +11889 0.19708251953125 +11890 0.273651123046875 +11891 0.31768798828125 +11892 0.341094970703125 +11893 0.368011474609375 +11894 0.37249755859375 +11895 0.30072021484375 +11896 0.1517333984375 +11897 -0.01470947265625 +11898 -0.1883544921875 +11899 -0.372711181640625 +11900 -0.51397705078125 +11901 -0.57177734375 +11902 -0.53948974609375 +11903 -0.43511962890625 +11904 -0.2962646484375 +11905 -0.161102294921875 +11906 -0.0435791015625 +11907 0.060394287109375 +11908 0.13665771484375 +11909 0.170135498046875 +11910 0.16552734375 +11911 0.15728759765625 +11912 0.150787353515625 +11913 0.12200927734375 +11914 0.080108642578125 +11915 0.05126953125 +11916 0.062896728515625 +11917 0.09271240234375 +11918 0.092987060546875 +11919 0.07855224609375 +11920 0.06427001953125 +11921 0.0347900390625 +11922 -0.01171875 +11923 -0.056060791015625 +11924 -0.055511474609375 +11925 -0.010467529296875 +11926 0.02508544921875 +11927 0.025665283203125 +11928 0.017333984375 +11929 0.00189208984375 +11930 -0.03173828125 +11931 -0.071502685546875 +11932 -0.13543701171875 +11933 -0.219970703125 +11934 -0.300506591796875 +11935 -0.376312255859375 +11936 -0.416107177734375 +11937 -0.371124267578125 +11938 -0.242279052734375 +11939 -0.069732666015625 +11940 0.125640869140625 +11941 0.31268310546875 +11942 0.45501708984375 +11943 0.554779052734375 +11944 0.61065673828125 +11945 0.610931396484375 +11946 0.531463623046875 +11947 0.3883056640625 +11948 0.23468017578125 +11949 0.095245361328125 +11950 -0.00396728515625 +11951 -0.04852294921875 +11952 -0.055145263671875 +11953 -0.0758056640625 +11954 -0.138702392578125 +11955 -0.209197998046875 +11956 -0.289031982421875 +11957 -0.37884521484375 +11958 -0.456329345703125 +11959 -0.51641845703125 +11960 -0.519287109375 +11961 -0.458251953125 +11962 -0.384796142578125 +11963 -0.323699951171875 +11964 -0.269287109375 +11965 -0.1951904296875 +11966 -0.100006103515625 +11967 -0.01055908203125 +11968 0.1033935546875 +11969 0.24908447265625 +11970 0.373199462890625 +11971 0.45806884765625 +11972 0.511474609375 +11973 0.565399169921875 +11974 0.61138916015625 +11975 0.5897216796875 +11976 0.4906005859375 +11977 0.33148193359375 +11978 0.147796630859375 +11979 -0.01873779296875 +11980 -0.140289306640625 +11981 -0.191986083984375 +11982 -0.184295654296875 +11983 -0.161834716796875 +11984 -0.166595458984375 +11985 -0.19390869140625 +11986 -0.22442626953125 +11987 -0.279754638671875 +11988 -0.3389892578125 +11989 -0.3543701171875 +11990 -0.348175048828125 +11991 -0.32598876953125 +11992 -0.2581787109375 +11993 -0.139801025390625 +11994 0.014617919921875 +11995 0.144378662109375 +11996 0.221038818359375 +11997 0.27069091796875 +11998 0.294036865234375 +11999 0.311767578125 +12000 0.339141845703125 +12001 0.360260009765625 +12002 0.360504150390625 +12003 0.308380126953125 +12004 0.18170166015625 +12005 0.0047607421875 +12006 -0.17559814453125 +12007 -0.3143310546875 +12008 -0.36785888671875 +12009 -0.36248779296875 +12010 -0.343536376953125 +12011 -0.3018798828125 +12012 -0.231414794921875 +12013 -0.117645263671875 +12014 0.007049560546875 +12015 0.087982177734375 +12016 0.13946533203125 +12017 0.17425537109375 +12018 0.188201904296875 +12019 0.171234130859375 +12020 0.118438720703125 +12021 0.05706787109375 +12022 -0.010711669921875 +12023 -0.0914306640625 +12024 -0.162322998046875 +12025 -0.194549560546875 +12026 -0.1492919921875 +12027 -0.02166748046875 +12028 0.124053955078125 +12029 0.211151123046875 +12030 0.240447998046875 +12031 0.242218017578125 +12032 0.2257080078125 +12033 0.194366455078125 +12034 0.115509033203125 +12035 0.0128173828125 +12036 -0.053802490234375 +12037 -0.110626220703125 +12038 -0.199493408203125 +12039 -0.29437255859375 +12040 -0.33221435546875 +12041 -0.27972412109375 +12042 -0.185333251953125 +12043 -0.128204345703125 +12044 -0.115692138671875 +12045 -0.116455078125 +12046 -0.105926513671875 +12047 -0.053955078125 +12048 0.048797607421875 +12049 0.157318115234375 +12050 0.212005615234375 +12051 0.218475341796875 +12052 0.23724365234375 +12053 0.30535888671875 +12054 0.38128662109375 +12055 0.404449462890625 +12056 0.3944091796875 +12057 0.3885498046875 +12058 0.362640380859375 +12059 0.27362060546875 +12060 0.11712646484375 +12061 -0.054901123046875 +12062 -0.19085693359375 +12063 -0.28570556640625 +12064 -0.339263916015625 +12065 -0.3775634765625 +12066 -0.445709228515625 +12067 -0.535064697265625 +12068 -0.629058837890625 +12069 -0.697601318359375 +12070 -0.70391845703125 +12071 -0.6424560546875 +12072 -0.491241455078125 +12073 -0.265716552734375 +12074 -0.023712158203125 +12075 0.201751708984375 +12076 0.375823974609375 +12077 0.485076904296875 +12078 0.56884765625 +12079 0.634765625 +12080 0.63763427734375 +12081 0.5660400390625 +12082 0.4720458984375 +12083 0.40692138671875 +12084 0.3778076171875 +12085 0.376953125 +12086 0.371978759765625 +12087 0.313140869140625 +12088 0.184417724609375 +12089 0.011199951171875 +12090 -0.171051025390625 +12091 -0.33740234375 +12092 -0.47198486328125 +12093 -0.560394287109375 +12094 -0.58056640625 +12095 -0.54754638671875 +12096 -0.508575439453125 +12097 -0.459503173828125 +12098 -0.394378662109375 +12099 -0.35260009765625 +12100 -0.31170654296875 +12101 -0.197418212890625 +12102 -0.007965087890625 +12103 0.207489013671875 +12104 0.409210205078125 +12105 0.57208251953125 +12106 0.66595458984375 +12107 0.65875244140625 +12108 0.56744384765625 +12109 0.431396484375 +12110 0.29443359375 +12111 0.182464599609375 +12112 0.06365966796875 +12113 -0.075958251953125 +12114 -0.189422607421875 +12115 -0.271942138671875 +12116 -0.342529296875 +12117 -0.364166259765625 +12118 -0.327239990234375 +12119 -0.2769775390625 +12120 -0.253692626953125 +12121 -0.24365234375 +12122 -0.1983642578125 +12123 -0.116241455078125 +12124 -0.036834716796875 +12125 0.034881591796875 +12126 0.09124755859375 +12127 0.10888671875 +12128 0.125518798828125 +12129 0.15771484375 +12130 0.17828369140625 +12131 0.17108154296875 +12132 0.129974365234375 +12133 0.082427978515625 +12134 0.027679443359375 +12135 -0.065643310546875 +12136 -0.15936279296875 +12137 -0.21307373046875 +12138 -0.234649658203125 +12139 -0.2001953125 +12140 -0.119171142578125 +12141 -0.024749755859375 +12142 0.085784912109375 +12143 0.178131103515625 +12144 0.215576171875 +12145 0.211456298828125 +12146 0.17523193359375 +12147 0.128753662109375 +12148 0.1019287109375 +12149 0.0743408203125 +12150 0.04327392578125 +12151 0.038177490234375 +12152 0.076263427734375 +12153 0.14105224609375 +12154 0.186431884765625 +12155 0.188812255859375 +12156 0.1390380859375 +12157 0.041778564453125 +12158 -0.079437255859375 +12159 -0.219390869140625 +12160 -0.367828369140625 +12161 -0.494873046875 +12162 -0.556243896484375 +12163 -0.508697509765625 +12164 -0.3756103515625 +12165 -0.218902587890625 +12166 -0.063751220703125 +12167 0.091552734375 +12168 0.23602294921875 +12169 0.342987060546875 +12170 0.39520263671875 +12171 0.389373779296875 +12172 0.324249267578125 +12173 0.224090576171875 +12174 0.124267578125 +12175 0.037078857421875 +12176 -0.010101318359375 +12177 -0.019439697265625 +12178 -0.022796630859375 +12179 -0.001556396484375 +12180 0.056304931640625 +12181 0.106719970703125 +12182 0.096893310546875 +12183 0.042694091796875 +12184 -0.018035888671875 +12185 -0.07586669921875 +12186 -0.11944580078125 +12187 -0.15972900390625 +12188 -0.202606201171875 +12189 -0.24859619140625 +12190 -0.30517578125 +12191 -0.36212158203125 +12192 -0.39141845703125 +12193 -0.35528564453125 +12194 -0.249969482421875 +12195 -0.092864990234375 +12196 0.08905029296875 +12197 0.2352294921875 +12198 0.318817138671875 +12199 0.358642578125 +12200 0.347747802734375 +12201 0.28564453125 +12202 0.223175048828125 +12203 0.196746826171875 +12204 0.179840087890625 +12205 0.155548095703125 +12206 0.151214599609375 +12207 0.156951904296875 +12208 0.13177490234375 +12209 0.100799560546875 +12210 0.087127685546875 +12211 0.05487060546875 +12212 -0.009002685546875 +12213 -0.10400390625 +12214 -0.229400634765625 +12215 -0.35552978515625 +12216 -0.441925048828125 +12217 -0.473846435546875 +12218 -0.464813232421875 +12219 -0.419097900390625 +12220 -0.334320068359375 +12221 -0.227935791015625 +12222 -0.12347412109375 +12223 -0.02764892578125 +12224 0.077667236328125 +12225 0.2132568359375 +12226 0.38885498046875 +12227 0.582794189453125 +12228 0.734039306640625 +12229 0.800140380859375 +12230 0.7783203125 +12231 0.6651611328125 +12232 0.45965576171875 +12233 0.199188232421875 +12234 -0.050689697265625 +12235 -0.23297119140625 +12236 -0.33013916015625 +12237 -0.368408203125 +12238 -0.378936767578125 +12239 -0.376983642578125 +12240 -0.37969970703125 +12241 -0.391510009765625 +12242 -0.385345458984375 +12243 -0.3419189453125 +12244 -0.28289794921875 +12245 -0.251617431640625 +12246 -0.266143798828125 +12247 -0.273345947265625 +12248 -0.216796875 +12249 -0.128265380859375 +12250 -0.068145751953125 +12251 -0.0430908203125 +12252 -0.024444580078125 +12253 0.020721435546875 +12254 0.124481201171875 +12255 0.25787353515625 +12256 0.379119873046875 +12257 0.47991943359375 +12258 0.5281982421875 +12259 0.511138916015625 +12260 0.456207275390625 +12261 0.407470703125 +12262 0.383758544921875 +12263 0.35687255859375 +12264 0.31182861328125 +12265 0.250885009765625 +12266 0.1654052734375 +12267 0.035247802734375 +12268 -0.142059326171875 +12269 -0.33563232421875 +12270 -0.5345458984375 +12271 -0.72186279296875 +12272 -0.836669921875 +12273 -0.8326416015625 +12274 -0.7296142578125 +12275 -0.582550048828125 +12276 -0.440093994140625 +12277 -0.324310302734375 +12278 -0.20147705078125 +12279 -0.044647216796875 +12280 0.103973388671875 +12281 0.202392578125 +12282 0.264495849609375 +12283 0.338897705078125 +12284 0.443817138671875 +12285 0.545074462890625 +12286 0.6173095703125 +12287 0.6524658203125 +12288 0.66339111328125 +12289 0.6561279296875 +12290 0.606781005859375 +12291 0.501190185546875 +12292 0.352783203125 +12293 0.176544189453125 +12294 -0.034820556640625 +12295 -0.258209228515625 +12296 -0.44244384765625 +12297 -0.5753173828125 +12298 -0.65203857421875 +12299 -0.641632080078125 +12300 -0.562164306640625 +12301 -0.458038330078125 +12302 -0.350555419921875 +12303 -0.260528564453125 +12304 -0.192108154296875 +12305 -0.141937255859375 +12306 -0.1021728515625 +12307 -0.062896728515625 +12308 -0.011932373046875 +12309 0.062835693359375 +12310 0.148712158203125 +12311 0.241729736328125 +12312 0.34912109375 +12313 0.457305908203125 +12314 0.54388427734375 +12315 0.5728759765625 +12316 0.506591796875 +12317 0.351226806640625 +12318 0.146514892578125 +12319 -0.05523681640625 +12320 -0.21624755859375 +12321 -0.334930419921875 +12322 -0.402984619140625 +12323 -0.4412841796875 +12324 -0.49578857421875 +12325 -0.5601806640625 +12326 -0.600738525390625 +12327 -0.584228515625 +12328 -0.47930908203125 +12329 -0.27935791015625 +12330 -0.0089111328125 +12331 0.268798828125 +12332 0.482818603515625 +12333 0.60369873046875 +12334 0.650421142578125 +12335 0.66400146484375 +12336 0.6414794921875 +12337 0.572540283203125 +12338 0.498138427734375 +12339 0.439453125 +12340 0.375518798828125 +12341 0.274505615234375 +12342 0.1087646484375 +12343 -0.099395751953125 +12344 -0.3182373046875 +12345 -0.5489501953125 +12346 -0.7738037109375 +12347 -0.86383056640625 +12348 -0.870391845703125 +12349 -0.86895751953125 +12350 -0.861053466796875 +12351 -0.765869140625 +12352 -0.5301513671875 +12353 -0.214691162109375 +12354 0.137359619140625 +12355 0.474822998046875 +12356 0.76239013671875 +12357 0.867462158203125 +12358 0.870361328125 +12359 0.86480712890625 +12360 0.831817626953125 +12361 0.677581787109375 +12362 0.495880126953125 +12363 0.30767822265625 +12364 0.116180419921875 +12365 -0.110748291015625 +12366 -0.381805419921875 +12367 -0.6572265625 +12368 -0.857421875 +12369 -0.870391845703125 +12370 -0.870391845703125 +12371 -0.86444091796875 +12372 -0.85723876953125 +12373 -0.790008544921875 +12374 -0.62847900390625 +12375 -0.3956298828125 +12376 -0.126708984375 +12377 0.150115966796875 +12378 0.424041748046875 +12379 0.670623779296875 +12380 0.854522705078125 +12381 0.866485595703125 +12382 0.86920166015625 +12383 0.8653564453125 +12384 0.857147216796875 +12385 0.766845703125 +12386 0.628509521484375 +12387 0.462127685546875 +12388 0.297210693359375 +12389 0.14862060546875 +12390 -0.00537109375 +12391 -0.15753173828125 +12392 -0.31304931640625 +12393 -0.48876953125 +12394 -0.6416015625 +12395 -0.751373291015625 +12396 -0.84619140625 +12397 -0.861297607421875 +12398 -0.863250732421875 +12399 -0.856597900390625 +12400 -0.7498779296875 +12401 -0.624542236328125 +12402 -0.47808837890625 +12403 -0.253387451171875 +12404 0.003692626953125 +12405 0.2257080078125 +12406 0.427154541015625 +12407 0.643218994140625 +12408 0.855926513671875 +12409 0.870361328125 +12410 0.870361328125 +12411 0.862762451171875 +12412 0.79669189453125 +12413 0.595794677734375 +12414 0.362152099609375 +12415 0.1270751953125 +12416 -0.086944580078125 +12417 -0.2784423828125 +12418 -0.484832763671875 +12419 -0.729583740234375 +12420 -0.86688232421875 +12421 -0.870391845703125 +12422 -0.86859130859375 +12423 -0.86279296875 +12424 -0.817962646484375 +12425 -0.6116943359375 +12426 -0.3128662109375 +12427 0.039398193359375 +12428 0.422821044921875 +12429 0.805145263671875 +12430 0.870361328125 +12431 0.870361328125 +12432 0.860015869140625 +12433 0.727935791015625 +12434 0.48114013671875 +12435 0.2059326171875 +12436 -0.06103515625 +12437 -0.29913330078125 +12438 -0.516204833984375 +12439 -0.7252197265625 +12440 -0.85980224609375 +12441 -0.870391845703125 +12442 -0.870391845703125 +12443 -0.858062744140625 +12444 -0.673004150390625 +12445 -0.42694091796875 +12446 -0.2100830078125 +12447 -0.0362548828125 +12448 0.10943603515625 +12449 0.23516845703125 +12450 0.373687744140625 +12451 0.517791748046875 +12452 0.602783203125 +12453 0.635711669921875 +12454 0.655181884765625 +12455 0.65948486328125 +12456 0.651275634765625 +12457 0.61846923828125 +12458 0.53753662109375 +12459 0.404144287109375 +12460 0.22186279296875 +12461 0.003997802734375 +12462 -0.22100830078125 +12463 -0.42449951171875 +12464 -0.579833984375 +12465 -0.641876220703125 +12466 -0.6177978515625 +12467 -0.575531005859375 +12468 -0.526336669921875 +12469 -0.42645263671875 +12470 -0.2581787109375 +12471 -0.068695068359375 +12472 0.09222412109375 +12473 0.232147216796875 +12474 0.3509521484375 +12475 0.410064697265625 +12476 0.372955322265625 +12477 0.2554931640625 +12478 0.10711669921875 +12479 -0.052886962890625 +12480 -0.186279296875 +12481 -0.23291015625 +12482 -0.209442138671875 +12483 -0.174163818359375 +12484 -0.126739501953125 +12485 -0.048126220703125 +12486 0.0426025390625 +12487 0.10748291015625 +12488 0.1409912109375 +12489 0.19708251953125 +12490 0.273651123046875 +12491 0.31768798828125 +12492 0.341094970703125 +12493 0.368011474609375 +12494 0.37249755859375 +12495 0.30072021484375 +12496 0.1517333984375 +12497 -0.01470947265625 +12498 -0.1883544921875 +12499 -0.372711181640625 +12500 -0.51397705078125 +12501 -0.57177734375 +12502 -0.53948974609375 +12503 -0.43511962890625 +12504 -0.2962646484375 +12505 -0.161102294921875 +12506 -0.0435791015625 +12507 0.060394287109375 +12508 0.13665771484375 +12509 0.170135498046875 +12510 0.16552734375 +12511 0.15728759765625 +12512 0.150787353515625 +12513 0.12200927734375 +12514 0.080108642578125 +12515 0.05126953125 +12516 0.062896728515625 +12517 0.09271240234375 +12518 0.092987060546875 +12519 0.07855224609375 +12520 0.06427001953125 +12521 0.0347900390625 +12522 -0.01171875 +12523 -0.056060791015625 +12524 -0.055511474609375 +12525 -0.010467529296875 +12526 0.02508544921875 +12527 0.025665283203125 +12528 0.017333984375 +12529 0.00189208984375 +12530 -0.03173828125 +12531 -0.071502685546875 +12532 -0.13543701171875 +12533 -0.219970703125 +12534 -0.300506591796875 +12535 -0.376312255859375 +12536 -0.416107177734375 +12537 -0.371124267578125 +12538 -0.242279052734375 +12539 -0.069732666015625 +12540 0.125640869140625 +12541 0.31268310546875 +12542 0.45501708984375 +12543 0.554779052734375 +12544 0.61065673828125 +12545 0.610931396484375 +12546 0.531463623046875 +12547 0.3883056640625 +12548 0.23468017578125 +12549 0.095245361328125 +12550 -0.00396728515625 +12551 -0.04852294921875 +12552 -0.055145263671875 +12553 -0.0758056640625 +12554 -0.138702392578125 +12555 -0.209197998046875 +12556 -0.289031982421875 +12557 -0.37884521484375 +12558 -0.456329345703125 +12559 -0.51641845703125 +12560 -0.519287109375 +12561 -0.458251953125 +12562 -0.384796142578125 +12563 -0.323699951171875 +12564 -0.269287109375 +12565 -0.1951904296875 +12566 -0.100006103515625 +12567 -0.01055908203125 +12568 0.1033935546875 +12569 0.24908447265625 +12570 0.373199462890625 +12571 0.45806884765625 +12572 0.511474609375 +12573 0.565399169921875 +12574 0.61138916015625 +12575 0.5897216796875 +12576 0.4906005859375 +12577 0.33148193359375 +12578 0.147796630859375 +12579 -0.01873779296875 +12580 -0.140289306640625 +12581 -0.191986083984375 +12582 -0.184295654296875 +12583 -0.161834716796875 +12584 -0.166595458984375 +12585 -0.19390869140625 +12586 -0.22442626953125 +12587 -0.279754638671875 +12588 -0.3389892578125 +12589 -0.3543701171875 +12590 -0.348175048828125 +12591 -0.32598876953125 +12592 -0.2581787109375 +12593 -0.139801025390625 +12594 0.014617919921875 +12595 0.144378662109375 +12596 0.221038818359375 +12597 0.27069091796875 +12598 0.294036865234375 +12599 0.311767578125 +12600 0.339141845703125 +12601 0.360260009765625 +12602 0.360504150390625 +12603 0.308380126953125 +12604 0.18170166015625 +12605 0.0047607421875 +12606 -0.17559814453125 +12607 -0.3143310546875 +12608 -0.36785888671875 +12609 -0.36248779296875 +12610 -0.343536376953125 +12611 -0.3018798828125 +12612 -0.231414794921875 +12613 -0.117645263671875 +12614 0.007049560546875 +12615 0.087982177734375 +12616 0.13946533203125 +12617 0.17425537109375 +12618 0.188201904296875 +12619 0.171234130859375 +12620 0.118438720703125 +12621 0.05706787109375 +12622 -0.010711669921875 +12623 -0.0914306640625 +12624 -0.162322998046875 +12625 -0.194549560546875 +12626 -0.1492919921875 +12627 -0.02166748046875 +12628 0.124053955078125 +12629 0.211151123046875 +12630 0.240447998046875 +12631 0.242218017578125 +12632 0.2257080078125 +12633 0.194366455078125 +12634 0.115509033203125 +12635 0.0128173828125 +12636 -0.053802490234375 +12637 -0.110626220703125 +12638 -0.199493408203125 +12639 -0.29437255859375 +12640 -0.33221435546875 +12641 -0.27972412109375 +12642 -0.185333251953125 +12643 -0.128204345703125 +12644 -0.115692138671875 +12645 -0.116455078125 +12646 -0.105926513671875 +12647 -0.053955078125 +12648 0.048797607421875 +12649 0.157318115234375 +12650 0.212005615234375 +12651 0.218475341796875 +12652 0.23724365234375 +12653 0.30535888671875 +12654 0.38128662109375 +12655 0.404449462890625 +12656 0.3944091796875 +12657 0.3885498046875 +12658 0.362640380859375 +12659 0.27362060546875 +12660 0.11712646484375 +12661 -0.054901123046875 +12662 -0.19085693359375 +12663 -0.28570556640625 +12664 -0.339263916015625 +12665 -0.3775634765625 +12666 -0.445709228515625 +12667 -0.535064697265625 +12668 -0.629058837890625 +12669 -0.697601318359375 +12670 -0.70391845703125 +12671 -0.6424560546875 +12672 -0.491241455078125 +12673 -0.265716552734375 +12674 -0.023712158203125 +12675 0.201751708984375 +12676 0.375823974609375 +12677 0.485076904296875 +12678 0.56884765625 +12679 0.634765625 +12680 0.63763427734375 +12681 0.5660400390625 +12682 0.4720458984375 +12683 0.40692138671875 +12684 0.3778076171875 +12685 0.376953125 +12686 0.371978759765625 +12687 0.313140869140625 +12688 0.184417724609375 +12689 0.011199951171875 +12690 -0.171051025390625 +12691 -0.33740234375 +12692 -0.47198486328125 +12693 -0.560394287109375 +12694 -0.58056640625 +12695 -0.54754638671875 +12696 -0.508575439453125 +12697 -0.459503173828125 +12698 -0.394378662109375 +12699 -0.35260009765625 +12700 -0.31170654296875 +12701 -0.197418212890625 +12702 -0.007965087890625 +12703 0.207489013671875 +12704 0.409210205078125 +12705 0.57208251953125 +12706 0.66595458984375 +12707 0.65875244140625 +12708 0.56744384765625 +12709 0.431396484375 +12710 0.29443359375 +12711 0.182464599609375 +12712 0.06365966796875 +12713 -0.075958251953125 +12714 -0.189422607421875 +12715 -0.271942138671875 +12716 -0.342529296875 +12717 -0.364166259765625 +12718 -0.327239990234375 +12719 -0.2769775390625 +12720 -0.253692626953125 +12721 -0.24365234375 +12722 -0.1983642578125 +12723 -0.116241455078125 +12724 -0.036834716796875 +12725 0.034881591796875 +12726 0.09124755859375 +12727 0.10888671875 +12728 0.125518798828125 +12729 0.15771484375 +12730 0.17828369140625 +12731 0.17108154296875 +12732 0.129974365234375 +12733 0.082427978515625 +12734 0.027679443359375 +12735 -0.065643310546875 +12736 -0.15936279296875 +12737 -0.21307373046875 +12738 -0.234649658203125 +12739 -0.2001953125 +12740 -0.119171142578125 +12741 -0.024749755859375 +12742 0.085784912109375 +12743 0.178131103515625 +12744 0.215576171875 +12745 0.211456298828125 +12746 0.17523193359375 +12747 0.128753662109375 +12748 0.1019287109375 +12749 0.0743408203125 +12750 0.04327392578125 +12751 0.038177490234375 +12752 0.076263427734375 +12753 0.14105224609375 +12754 0.186431884765625 +12755 0.188812255859375 +12756 0.1390380859375 +12757 0.041778564453125 +12758 -0.079437255859375 +12759 -0.219390869140625 +12760 -0.367828369140625 +12761 -0.494873046875 +12762 -0.556243896484375 +12763 -0.508697509765625 +12764 -0.3756103515625 +12765 -0.218902587890625 +12766 -0.063751220703125 +12767 0.091552734375 +12768 0.23602294921875 +12769 0.342987060546875 +12770 0.39520263671875 +12771 0.389373779296875 +12772 0.324249267578125 +12773 0.224090576171875 +12774 0.124267578125 +12775 0.037078857421875 +12776 -0.010101318359375 +12777 -0.019439697265625 +12778 -0.022796630859375 +12779 -0.001556396484375 +12780 0.056304931640625 +12781 0.106719970703125 +12782 0.096893310546875 +12783 0.042694091796875 +12784 -0.018035888671875 +12785 -0.07586669921875 +12786 -0.11944580078125 +12787 -0.15972900390625 +12788 -0.202606201171875 +12789 -0.24859619140625 +12790 -0.30517578125 +12791 -0.36212158203125 +12792 -0.39141845703125 +12793 -0.35528564453125 +12794 -0.249969482421875 +12795 -0.092864990234375 +12796 0.08905029296875 +12797 0.2352294921875 +12798 0.318817138671875 +12799 0.358642578125 +12800 0.347747802734375 +12801 0.28564453125 +12802 0.223175048828125 +12803 0.196746826171875 +12804 0.179840087890625 +12805 0.155548095703125 +12806 0.151214599609375 +12807 0.156951904296875 +12808 0.13177490234375 +12809 0.100799560546875 +12810 0.087127685546875 +12811 0.05487060546875 +12812 -0.009002685546875 +12813 -0.10400390625 +12814 -0.229400634765625 +12815 -0.35552978515625 +12816 -0.441925048828125 +12817 -0.473846435546875 +12818 -0.464813232421875 +12819 -0.419097900390625 +12820 -0.334320068359375 +12821 -0.227935791015625 +12822 -0.12347412109375 +12823 -0.02764892578125 +12824 0.077667236328125 +12825 0.2132568359375 +12826 0.38885498046875 +12827 0.582794189453125 +12828 0.734039306640625 +12829 0.800140380859375 +12830 0.7783203125 +12831 0.6651611328125 +12832 0.45965576171875 +12833 0.199188232421875 +12834 -0.050689697265625 +12835 -0.23297119140625 +12836 -0.33013916015625 +12837 -0.368408203125 +12838 -0.378936767578125 +12839 -0.376983642578125 +12840 -0.37969970703125 +12841 -0.391510009765625 +12842 -0.385345458984375 +12843 -0.3419189453125 +12844 -0.28289794921875 +12845 -0.251617431640625 +12846 -0.266143798828125 +12847 -0.273345947265625 +12848 -0.216796875 +12849 -0.128265380859375 +12850 -0.068145751953125 +12851 -0.0430908203125 +12852 -0.024444580078125 +12853 0.020721435546875 +12854 0.124481201171875 +12855 0.25787353515625 +12856 0.379119873046875 +12857 0.47991943359375 +12858 0.5281982421875 +12859 0.511138916015625 +12860 0.456207275390625 +12861 0.407470703125 +12862 0.383758544921875 +12863 0.35687255859375 +12864 0.31182861328125 +12865 0.250885009765625 +12866 0.1654052734375 +12867 0.035247802734375 +12868 -0.142059326171875 +12869 -0.33563232421875 +12870 -0.5345458984375 +12871 -0.72186279296875 +12872 -0.836669921875 +12873 -0.8326416015625 +12874 -0.7296142578125 +12875 -0.582550048828125 +12876 -0.440093994140625 +12877 -0.324310302734375 +12878 -0.20147705078125 +12879 -0.044647216796875 +12880 0.103973388671875 +12881 0.202392578125 +12882 0.264495849609375 +12883 0.338897705078125 +12884 0.443817138671875 +12885 0.545074462890625 +12886 0.6173095703125 +12887 0.6524658203125 +12888 0.66339111328125 +12889 0.6561279296875 +12890 0.606781005859375 +12891 0.501190185546875 +12892 0.352783203125 +12893 0.176544189453125 +12894 -0.034820556640625 +12895 -0.258209228515625 +12896 -0.44244384765625 +12897 -0.5753173828125 +12898 -0.65203857421875 +12899 -0.641632080078125 +12900 -0.562164306640625 +12901 -0.458038330078125 +12902 -0.350555419921875 +12903 -0.260528564453125 +12904 -0.192108154296875 +12905 -0.141937255859375 +12906 -0.1021728515625 +12907 -0.062896728515625 +12908 -0.011932373046875 +12909 0.062835693359375 +12910 0.148712158203125 +12911 0.241729736328125 +12912 0.34912109375 +12913 0.457305908203125 +12914 0.54388427734375 +12915 0.5728759765625 +12916 0.506591796875 +12917 0.351226806640625 +12918 0.146514892578125 +12919 -0.05523681640625 +12920 -0.21624755859375 +12921 -0.334930419921875 +12922 -0.402984619140625 +12923 -0.4412841796875 +12924 -0.49578857421875 +12925 -0.5601806640625 +12926 -0.600738525390625 +12927 -0.584228515625 +12928 -0.47930908203125 +12929 -0.27935791015625 +12930 -0.0089111328125 +12931 0.268798828125 +12932 0.482818603515625 +12933 0.60369873046875 +12934 0.650421142578125 +12935 0.66400146484375 +12936 0.6414794921875 +12937 0.572540283203125 +12938 0.498138427734375 +12939 0.439453125 +12940 0.375518798828125 +12941 0.274505615234375 +12942 0.1087646484375 +12943 -0.099395751953125 +12944 -0.3182373046875 +12945 -0.5489501953125 +12946 -0.7738037109375 +12947 -0.86383056640625 +12948 -0.870391845703125 +12949 -0.86895751953125 +12950 -0.861053466796875 +12951 -0.765869140625 +12952 -0.5301513671875 +12953 -0.214691162109375 +12954 0.137359619140625 +12955 0.474822998046875 +12956 0.76239013671875 +12957 0.867462158203125 +12958 0.870361328125 +12959 0.86480712890625 +12960 0.831817626953125 +12961 0.677581787109375 +12962 0.495880126953125 +12963 0.30767822265625 +12964 0.116180419921875 +12965 -0.110748291015625 +12966 -0.381805419921875 +12967 -0.6572265625 +12968 -0.857421875 +12969 -0.870391845703125 +12970 -0.870391845703125 +12971 -0.86444091796875 +12972 -0.85723876953125 +12973 -0.790008544921875 +12974 -0.62847900390625 +12975 -0.3956298828125 +12976 -0.126708984375 +12977 0.150115966796875 +12978 0.424041748046875 +12979 0.670623779296875 +12980 0.854522705078125 +12981 0.866485595703125 +12982 0.86920166015625 +12983 0.8653564453125 +12984 0.857147216796875 +12985 0.766845703125 +12986 0.628509521484375 +12987 0.462127685546875 +12988 0.297210693359375 +12989 0.14862060546875 +12990 -0.00537109375 +12991 -0.15753173828125 +12992 -0.31304931640625 +12993 -0.48876953125 +12994 -0.6416015625 +12995 -0.751373291015625 +12996 -0.84619140625 +12997 -0.861297607421875 +12998 -0.863250732421875 +12999 -0.856597900390625 +13000 -0.7498779296875 +13001 -0.624542236328125 +13002 -0.47808837890625 +13003 -0.253387451171875 +13004 0.003692626953125 +13005 0.2257080078125 +13006 0.427154541015625 +13007 0.643218994140625 +13008 0.855926513671875 +13009 0.870361328125 +13010 0.870361328125 +13011 0.862762451171875 +13012 0.79669189453125 +13013 0.595794677734375 +13014 0.362152099609375 +13015 0.1270751953125 +13016 -0.086944580078125 +13017 -0.2784423828125 +13018 -0.484832763671875 +13019 -0.729583740234375 +13020 -0.86688232421875 +13021 -0.870391845703125 +13022 -0.86859130859375 +13023 -0.86279296875 +13024 -0.817962646484375 +13025 -0.6116943359375 +13026 -0.3128662109375 +13027 0.039398193359375 +13028 0.422821044921875 +13029 0.805145263671875 +13030 0.870361328125 +13031 0.870361328125 +13032 0.860015869140625 +13033 0.727935791015625 +13034 0.48114013671875 +13035 0.2059326171875 +13036 -0.06103515625 +13037 -0.29913330078125 +13038 -0.516204833984375 +13039 -0.7252197265625 +13040 -0.85980224609375 +13041 -0.870391845703125 +13042 -0.870391845703125 +13043 -0.858062744140625 +13044 -0.673004150390625 +13045 -0.42694091796875 +13046 -0.2100830078125 +13047 -0.0362548828125 +13048 0.10943603515625 +13049 0.23516845703125 +13050 0.373687744140625 +13051 0.517791748046875 +13052 0.602783203125 +13053 0.635711669921875 +13054 0.655181884765625 +13055 0.65948486328125 +13056 0.651275634765625 +13057 0.61846923828125 +13058 0.53753662109375 +13059 0.404144287109375 +13060 0.22186279296875 +13061 0.003997802734375 +13062 -0.22100830078125 +13063 -0.42449951171875 +13064 -0.579833984375 +13065 -0.641876220703125 +13066 -0.6177978515625 +13067 -0.575531005859375 +13068 -0.526336669921875 +13069 -0.42645263671875 +13070 -0.2581787109375 +13071 -0.068695068359375 +13072 0.09222412109375 +13073 0.232147216796875 +13074 0.3509521484375 +13075 0.410064697265625 +13076 0.372955322265625 +13077 0.2554931640625 +13078 0.10711669921875 +13079 -0.052886962890625 +13080 -0.186279296875 +13081 -0.23291015625 +13082 -0.209442138671875 +13083 -0.174163818359375 +13084 -0.126739501953125 +13085 -0.048126220703125 +13086 0.0426025390625 +13087 0.10748291015625 +13088 0.1409912109375 +13089 0.19708251953125 +13090 0.273651123046875 +13091 0.31768798828125 +13092 0.341094970703125 +13093 0.368011474609375 +13094 0.37249755859375 +13095 0.30072021484375 +13096 0.1517333984375 +13097 -0.01470947265625 +13098 -0.1883544921875 +13099 -0.372711181640625 +13100 -0.51397705078125 +13101 -0.57177734375 +13102 -0.53948974609375 +13103 -0.43511962890625 +13104 -0.2962646484375 +13105 -0.161102294921875 +13106 -0.0435791015625 +13107 0.060394287109375 +13108 0.13665771484375 +13109 0.170135498046875 +13110 0.16552734375 +13111 0.15728759765625 +13112 0.150787353515625 +13113 0.12200927734375 +13114 0.080108642578125 +13115 0.05126953125 +13116 0.062896728515625 +13117 0.09271240234375 +13118 0.092987060546875 +13119 0.07855224609375 +13120 0.06427001953125 +13121 0.0347900390625 +13122 -0.01171875 +13123 -0.056060791015625 +13124 -0.055511474609375 +13125 -0.010467529296875 +13126 0.02508544921875 +13127 0.025665283203125 +13128 0.017333984375 +13129 0.00189208984375 +13130 -0.03173828125 +13131 -0.071502685546875 +13132 -0.13543701171875 +13133 -0.219970703125 +13134 -0.300506591796875 +13135 -0.376312255859375 +13136 -0.416107177734375 +13137 -0.371124267578125 +13138 -0.242279052734375 +13139 -0.069732666015625 +13140 0.125640869140625 +13141 0.31268310546875 +13142 0.45501708984375 +13143 0.554779052734375 +13144 0.61065673828125 +13145 0.610931396484375 +13146 0.531463623046875 +13147 0.3883056640625 +13148 0.23468017578125 +13149 0.095245361328125 +13150 -0.00396728515625 +13151 -0.04852294921875 +13152 -0.055145263671875 +13153 -0.0758056640625 +13154 -0.138702392578125 +13155 -0.209197998046875 +13156 -0.289031982421875 +13157 -0.37884521484375 +13158 -0.456329345703125 +13159 -0.51641845703125 +13160 -0.519287109375 +13161 -0.458251953125 +13162 -0.384796142578125 +13163 -0.323699951171875 +13164 -0.269287109375 +13165 -0.1951904296875 +13166 -0.100006103515625 +13167 -0.01055908203125 +13168 0.1033935546875 +13169 0.24908447265625 +13170 0.373199462890625 +13171 0.45806884765625 +13172 0.511474609375 +13173 0.565399169921875 +13174 0.61138916015625 +13175 0.5897216796875 +13176 0.4906005859375 +13177 0.33148193359375 +13178 0.147796630859375 +13179 -0.01873779296875 +13180 -0.140289306640625 +13181 -0.191986083984375 +13182 -0.184295654296875 +13183 -0.161834716796875 +13184 -0.166595458984375 +13185 -0.19390869140625 +13186 -0.22442626953125 +13187 -0.279754638671875 +13188 -0.3389892578125 +13189 -0.3543701171875 +13190 -0.348175048828125 +13191 -0.32598876953125 +13192 -0.2581787109375 +13193 -0.139801025390625 +13194 0.014617919921875 +13195 0.144378662109375 +13196 0.221038818359375 +13197 0.27069091796875 +13198 0.294036865234375 +13199 0.311767578125 +13200 0.339141845703125 +13201 0.360260009765625 +13202 0.360504150390625 +13203 0.308380126953125 +13204 0.18170166015625 +13205 0.0047607421875 +13206 -0.17559814453125 +13207 -0.3143310546875 +13208 -0.36785888671875 +13209 -0.36248779296875 +13210 -0.343536376953125 +13211 -0.3018798828125 +13212 -0.231414794921875 +13213 -0.117645263671875 +13214 0.007049560546875 +13215 0.087982177734375 +13216 0.13946533203125 +13217 0.17425537109375 +13218 0.188201904296875 +13219 0.171234130859375 +13220 0.118438720703125 +13221 0.05706787109375 +13222 -0.010711669921875 +13223 -0.0914306640625 +13224 -0.162322998046875 +13225 -0.194549560546875 +13226 -0.1492919921875 +13227 -0.02166748046875 +13228 0.124053955078125 +13229 0.211151123046875 +13230 0.240447998046875 +13231 0.242218017578125 +13232 0.2257080078125 +13233 0.194366455078125 +13234 0.115509033203125 +13235 0.0128173828125 +13236 -0.053802490234375 +13237 -0.110626220703125 +13238 -0.199493408203125 +13239 -0.29437255859375 +13240 -0.33221435546875 +13241 -0.27972412109375 +13242 -0.185333251953125 +13243 -0.128204345703125 +13244 -0.115692138671875 +13245 -0.116455078125 +13246 -0.105926513671875 +13247 -0.053955078125 +13248 0.048797607421875 +13249 0.157318115234375 +13250 0.212005615234375 +13251 0.218475341796875 +13252 0.23724365234375 +13253 0.30535888671875 +13254 0.38128662109375 +13255 0.404449462890625 +13256 0.3944091796875 +13257 0.3885498046875 +13258 0.362640380859375 +13259 0.27362060546875 +13260 0.11712646484375 +13261 -0.054901123046875 +13262 -0.19085693359375 +13263 -0.28570556640625 +13264 -0.339263916015625 +13265 -0.3775634765625 +13266 -0.445709228515625 +13267 -0.535064697265625 +13268 -0.629058837890625 +13269 -0.697601318359375 +13270 -0.70391845703125 +13271 -0.6424560546875 +13272 -0.491241455078125 +13273 -0.265716552734375 +13274 -0.023712158203125 +13275 0.201751708984375 +13276 0.375823974609375 +13277 0.485076904296875 +13278 0.56884765625 +13279 0.634765625 +13280 0.63763427734375 +13281 0.5660400390625 +13282 0.4720458984375 +13283 0.40692138671875 +13284 0.3778076171875 +13285 0.376953125 +13286 0.371978759765625 +13287 0.313140869140625 +13288 0.184417724609375 +13289 0.011199951171875 +13290 -0.171051025390625 +13291 -0.33740234375 +13292 -0.47198486328125 +13293 -0.560394287109375 +13294 -0.58056640625 +13295 -0.54754638671875 +13296 -0.508575439453125 +13297 -0.459503173828125 +13298 -0.394378662109375 +13299 -0.35260009765625 +13300 -0.31170654296875 +13301 -0.197418212890625 +13302 -0.007965087890625 +13303 0.207489013671875 +13304 0.409210205078125 +13305 0.57208251953125 +13306 0.66595458984375 +13307 0.65875244140625 +13308 0.56744384765625 +13309 0.431396484375 +13310 0.29443359375 +13311 0.182464599609375 +13312 0.06365966796875 +13313 -0.075958251953125 +13314 -0.189422607421875 +13315 -0.271942138671875 +13316 -0.342529296875 +13317 -0.364166259765625 +13318 -0.327239990234375 +13319 -0.2769775390625 +13320 -0.253692626953125 +13321 -0.24365234375 +13322 -0.1983642578125 +13323 -0.116241455078125 +13324 -0.036834716796875 +13325 0.034881591796875 +13326 0.09124755859375 +13327 0.10888671875 +13328 0.125518798828125 +13329 0.15771484375 +13330 0.17828369140625 +13331 0.17108154296875 +13332 0.129974365234375 +13333 0.082427978515625 +13334 0.027679443359375 +13335 -0.065643310546875 +13336 -0.15936279296875 +13337 -0.21307373046875 +13338 -0.234649658203125 +13339 -0.2001953125 +13340 -0.119171142578125 +13341 -0.024749755859375 +13342 0.085784912109375 +13343 0.178131103515625 +13344 0.215576171875 +13345 0.211456298828125 +13346 0.17523193359375 +13347 0.128753662109375 +13348 0.1019287109375 +13349 0.0743408203125 +13350 0.04327392578125 +13351 0.038177490234375 +13352 0.076263427734375 +13353 0.14105224609375 +13354 0.186431884765625 +13355 0.188812255859375 +13356 0.1390380859375 +13357 0.041778564453125 +13358 -0.079437255859375 +13359 -0.219390869140625 +13360 -0.367828369140625 +13361 -0.494873046875 +13362 -0.556243896484375 +13363 -0.508697509765625 +13364 -0.3756103515625 +13365 -0.218902587890625 +13366 -0.063751220703125 +13367 0.091552734375 +13368 0.23602294921875 +13369 0.342987060546875 +13370 0.39520263671875 +13371 0.389373779296875 +13372 0.324249267578125 +13373 0.224090576171875 +13374 0.124267578125 +13375 0.037078857421875 +13376 -0.010101318359375 +13377 -0.019439697265625 +13378 -0.022796630859375 +13379 -0.001556396484375 +13380 0.056304931640625 +13381 0.106719970703125 +13382 0.096893310546875 +13383 0.042694091796875 +13384 -0.018035888671875 +13385 -0.07586669921875 +13386 -0.11944580078125 +13387 -0.15972900390625 +13388 -0.202606201171875 +13389 -0.24859619140625 +13390 -0.30517578125 +13391 -0.36212158203125 +13392 -0.39141845703125 +13393 -0.35528564453125 +13394 -0.249969482421875 +13395 -0.092864990234375 +13396 0.08905029296875 +13397 0.2352294921875 +13398 0.318817138671875 +13399 0.358642578125 +13400 0.347747802734375 +13401 0.28564453125 +13402 0.223175048828125 +13403 0.196746826171875 +13404 0.179840087890625 +13405 0.155548095703125 +13406 0.151214599609375 +13407 0.156951904296875 +13408 0.13177490234375 +13409 0.100799560546875 +13410 0.087127685546875 +13411 0.05487060546875 +13412 -0.009002685546875 +13413 -0.10400390625 +13414 -0.229400634765625 +13415 -0.35552978515625 +13416 -0.441925048828125 +13417 -0.473846435546875 +13418 -0.464813232421875 +13419 -0.419097900390625 +13420 -0.334320068359375 +13421 -0.227935791015625 +13422 -0.12347412109375 +13423 -0.02764892578125 +13424 0.077667236328125 +13425 0.2132568359375 +13426 0.38885498046875 +13427 0.582794189453125 +13428 0.734039306640625 +13429 0.800140380859375 +13430 0.7783203125 +13431 0.6651611328125 +13432 0.45965576171875 +13433 0.199188232421875 +13434 -0.050689697265625 +13435 -0.23297119140625 +13436 -0.33013916015625 +13437 -0.368408203125 +13438 -0.378936767578125 +13439 -0.376983642578125 +13440 -0.37969970703125 +13441 -0.391510009765625 +13442 -0.385345458984375 +13443 -0.3419189453125 +13444 -0.28289794921875 +13445 -0.251617431640625 +13446 -0.266143798828125 +13447 -0.273345947265625 +13448 -0.216796875 +13449 -0.128265380859375 +13450 -0.068145751953125 +13451 -0.0430908203125 +13452 -0.024444580078125 +13453 0.020721435546875 +13454 0.124481201171875 +13455 0.25787353515625 +13456 0.379119873046875 +13457 0.47991943359375 +13458 0.5281982421875 +13459 0.511138916015625 +13460 0.456207275390625 +13461 0.407470703125 +13462 0.383758544921875 +13463 0.35687255859375 +13464 0.31182861328125 +13465 0.250885009765625 +13466 0.1654052734375 +13467 0.035247802734375 +13468 -0.142059326171875 +13469 -0.33563232421875 +13470 -0.5345458984375 +13471 -0.72186279296875 +13472 -0.836669921875 +13473 -0.8326416015625 +13474 -0.7296142578125 +13475 -0.582550048828125 +13476 -0.440093994140625 +13477 -0.324310302734375 +13478 -0.20147705078125 +13479 -0.044647216796875 +13480 0.103973388671875 +13481 0.202392578125 +13482 0.264495849609375 +13483 0.338897705078125 +13484 0.443817138671875 +13485 0.545074462890625 +13486 0.6173095703125 +13487 0.6524658203125 +13488 0.66339111328125 +13489 0.6561279296875 +13490 0.606781005859375 +13491 0.501190185546875 +13492 0.352783203125 +13493 0.176544189453125 +13494 -0.034820556640625 +13495 -0.258209228515625 +13496 -0.44244384765625 +13497 -0.5753173828125 +13498 -0.65203857421875 +13499 -0.641632080078125 +13500 -0.562164306640625 +13501 -0.458038330078125 +13502 -0.350555419921875 +13503 -0.260528564453125 +13504 -0.192108154296875 +13505 -0.141937255859375 +13506 -0.1021728515625 +13507 -0.062896728515625 +13508 -0.011932373046875 +13509 0.062835693359375 +13510 0.148712158203125 +13511 0.241729736328125 +13512 0.34912109375 +13513 0.457305908203125 +13514 0.54388427734375 +13515 0.5728759765625 +13516 0.506591796875 +13517 0.351226806640625 +13518 0.146514892578125 +13519 -0.05523681640625 +13520 -0.21624755859375 +13521 -0.334930419921875 +13522 -0.402984619140625 +13523 -0.4412841796875 +13524 -0.49578857421875 +13525 -0.5601806640625 +13526 -0.600738525390625 +13527 -0.584228515625 +13528 -0.47930908203125 +13529 -0.27935791015625 +13530 -0.0089111328125 +13531 0.268798828125 +13532 0.482818603515625 +13533 0.60369873046875 +13534 0.650421142578125 +13535 0.66400146484375 +13536 0.6414794921875 +13537 0.572540283203125 +13538 0.498138427734375 +13539 0.439453125 +13540 0.375518798828125 +13541 0.274505615234375 +13542 0.1087646484375 +13543 -0.099395751953125 +13544 -0.3182373046875 +13545 -0.5489501953125 +13546 -0.7738037109375 +13547 -0.86383056640625 +13548 -0.870391845703125 +13549 -0.86895751953125 +13550 -0.861053466796875 +13551 -0.765869140625 +13552 -0.5301513671875 +13553 -0.214691162109375 +13554 0.137359619140625 +13555 0.474822998046875 +13556 0.76239013671875 +13557 0.867462158203125 +13558 0.870361328125 +13559 0.86480712890625 +13560 0.831817626953125 +13561 0.677581787109375 +13562 0.495880126953125 +13563 0.30767822265625 +13564 0.116180419921875 +13565 -0.110748291015625 +13566 -0.381805419921875 +13567 -0.6572265625 +13568 -0.857421875 +13569 -0.870391845703125 +13570 -0.870391845703125 +13571 -0.86444091796875 +13572 -0.85723876953125 +13573 -0.790008544921875 +13574 -0.62847900390625 +13575 -0.3956298828125 +13576 -0.126708984375 +13577 0.150115966796875 +13578 0.424041748046875 +13579 0.670623779296875 +13580 0.854522705078125 +13581 0.866485595703125 +13582 0.86920166015625 +13583 0.8653564453125 +13584 0.857147216796875 +13585 0.766845703125 +13586 0.628509521484375 +13587 0.462127685546875 +13588 0.297210693359375 +13589 0.14862060546875 +13590 -0.00537109375 +13591 -0.15753173828125 +13592 -0.31304931640625 +13593 -0.48876953125 +13594 -0.6416015625 +13595 -0.751373291015625 +13596 -0.84619140625 +13597 -0.861297607421875 +13598 -0.863250732421875 +13599 -0.856597900390625 +13600 -0.7498779296875 +13601 -0.624542236328125 +13602 -0.47808837890625 +13603 -0.253387451171875 +13604 0.003692626953125 +13605 0.2257080078125 +13606 0.427154541015625 +13607 0.643218994140625 +13608 0.855926513671875 +13609 0.870361328125 +13610 0.870361328125 +13611 0.862762451171875 +13612 0.79669189453125 +13613 0.595794677734375 +13614 0.362152099609375 +13615 0.1270751953125 +13616 -0.086944580078125 +13617 -0.2784423828125 +13618 -0.484832763671875 +13619 -0.729583740234375 +13620 -0.86688232421875 +13621 -0.870391845703125 +13622 -0.86859130859375 +13623 -0.86279296875 +13624 -0.817962646484375 +13625 -0.6116943359375 +13626 -0.3128662109375 +13627 0.039398193359375 +13628 0.422821044921875 +13629 0.805145263671875 +13630 0.870361328125 +13631 0.870361328125 +13632 0.860015869140625 +13633 0.727935791015625 +13634 0.48114013671875 +13635 0.2059326171875 +13636 -0.06103515625 +13637 -0.29913330078125 +13638 -0.516204833984375 +13639 -0.7252197265625 +13640 -0.85980224609375 +13641 -0.870391845703125 +13642 -0.870391845703125 +13643 -0.858062744140625 +13644 -0.673004150390625 +13645 -0.42694091796875 +13646 -0.2100830078125 +13647 -0.0362548828125 +13648 0.10943603515625 +13649 0.23516845703125 +13650 0.373687744140625 +13651 0.517791748046875 +13652 0.602783203125 +13653 0.635711669921875 +13654 0.655181884765625 +13655 0.65948486328125 +13656 0.651275634765625 +13657 0.61846923828125 +13658 0.53753662109375 +13659 0.404144287109375 +13660 0.22186279296875 +13661 0.003997802734375 +13662 -0.22100830078125 +13663 -0.42449951171875 +13664 -0.579833984375 +13665 -0.641876220703125 +13666 -0.6177978515625 +13667 -0.575531005859375 +13668 -0.526336669921875 +13669 -0.42645263671875 +13670 -0.2581787109375 +13671 -0.068695068359375 +13672 0.09222412109375 +13673 0.232147216796875 +13674 0.3509521484375 +13675 0.410064697265625 +13676 0.372955322265625 +13677 0.2554931640625 +13678 0.10711669921875 +13679 -0.052886962890625 +13680 -0.186279296875 +13681 -0.23291015625 +13682 -0.209442138671875 +13683 -0.174163818359375 +13684 -0.126739501953125 +13685 -0.048126220703125 +13686 0.0426025390625 +13687 0.10748291015625 +13688 0.1409912109375 +13689 0.19708251953125 +13690 0.273651123046875 +13691 0.31768798828125 +13692 0.341094970703125 +13693 0.368011474609375 +13694 0.37249755859375 +13695 0.30072021484375 +13696 0.1517333984375 +13697 -0.01470947265625 +13698 -0.1883544921875 +13699 -0.372711181640625 +13700 -0.51397705078125 +13701 -0.57177734375 +13702 -0.53948974609375 +13703 -0.43511962890625 +13704 -0.2962646484375 +13705 -0.161102294921875 +13706 -0.0435791015625 +13707 0.060394287109375 +13708 0.13665771484375 +13709 0.170135498046875 +13710 0.16552734375 +13711 0.15728759765625 +13712 0.150787353515625 +13713 0.12200927734375 +13714 0.080108642578125 +13715 0.05126953125 +13716 0.062896728515625 +13717 0.09271240234375 +13718 0.092987060546875 +13719 0.07855224609375 +13720 0.06427001953125 +13721 0.0347900390625 +13722 -0.01171875 +13723 -0.056060791015625 +13724 -0.055511474609375 +13725 -0.010467529296875 +13726 0.02508544921875 +13727 0.025665283203125 +13728 0.017333984375 +13729 0.00189208984375 +13730 -0.03173828125 +13731 -0.071502685546875 +13732 -0.13543701171875 +13733 -0.219970703125 +13734 -0.300506591796875 +13735 -0.376312255859375 +13736 -0.416107177734375 +13737 -0.371124267578125 +13738 -0.242279052734375 +13739 -0.069732666015625 +13740 0.125640869140625 +13741 0.31268310546875 +13742 0.45501708984375 +13743 0.554779052734375 +13744 0.61065673828125 +13745 0.610931396484375 +13746 0.531463623046875 +13747 0.3883056640625 +13748 0.23468017578125 +13749 0.095245361328125 +13750 -0.00396728515625 +13751 -0.04852294921875 +13752 -0.055145263671875 +13753 -0.0758056640625 +13754 -0.138702392578125 +13755 -0.209197998046875 +13756 -0.289031982421875 +13757 -0.37884521484375 +13758 -0.456329345703125 +13759 -0.51641845703125 +13760 -0.519287109375 +13761 -0.458251953125 +13762 -0.384796142578125 +13763 -0.323699951171875 +13764 -0.269287109375 +13765 -0.1951904296875 +13766 -0.100006103515625 +13767 -0.01055908203125 +13768 0.1033935546875 +13769 0.24908447265625 +13770 0.373199462890625 +13771 0.45806884765625 +13772 0.511474609375 +13773 0.565399169921875 +13774 0.61138916015625 +13775 0.5897216796875 +13776 0.4906005859375 +13777 0.33148193359375 +13778 0.147796630859375 +13779 -0.01873779296875 +13780 -0.140289306640625 +13781 -0.191986083984375 +13782 -0.184295654296875 +13783 -0.161834716796875 +13784 -0.166595458984375 +13785 -0.19390869140625 +13786 -0.22442626953125 +13787 -0.279754638671875 +13788 -0.3389892578125 +13789 -0.3543701171875 +13790 -0.348175048828125 +13791 -0.32598876953125 +13792 -0.2581787109375 +13793 -0.139801025390625 +13794 0.014617919921875 +13795 0.144378662109375 +13796 0.221038818359375 +13797 0.27069091796875 +13798 0.294036865234375 +13799 0.311767578125 +13800 0.339141845703125 +13801 0.360260009765625 +13802 0.360504150390625 +13803 0.308380126953125 +13804 0.18170166015625 +13805 0.0047607421875 +13806 -0.17559814453125 +13807 -0.3143310546875 +13808 -0.36785888671875 +13809 -0.36248779296875 +13810 -0.343536376953125 +13811 -0.3018798828125 +13812 -0.231414794921875 +13813 -0.117645263671875 +13814 0.007049560546875 +13815 0.087982177734375 +13816 0.13946533203125 +13817 0.17425537109375 +13818 0.188201904296875 +13819 0.171234130859375 +13820 0.118438720703125 +13821 0.05706787109375 +13822 -0.010711669921875 +13823 -0.0914306640625 +13824 -0.162322998046875 +13825 -0.194549560546875 +13826 -0.1492919921875 +13827 -0.02166748046875 +13828 0.124053955078125 +13829 0.211151123046875 +13830 0.240447998046875 +13831 0.242218017578125 +13832 0.2257080078125 +13833 0.194366455078125 +13834 0.115509033203125 +13835 0.0128173828125 +13836 -0.053802490234375 +13837 -0.110626220703125 +13838 -0.199493408203125 +13839 -0.29437255859375 +13840 -0.33221435546875 +13841 -0.27972412109375 +13842 -0.185333251953125 +13843 -0.128204345703125 +13844 -0.115692138671875 +13845 -0.116455078125 +13846 -0.105926513671875 +13847 -0.053955078125 +13848 0.048797607421875 +13849 0.157318115234375 +13850 0.212005615234375 +13851 0.218475341796875 +13852 0.23724365234375 +13853 0.30535888671875 +13854 0.38128662109375 +13855 0.404449462890625 +13856 0.3944091796875 +13857 0.3885498046875 +13858 0.362640380859375 +13859 0.27362060546875 +13860 0.11712646484375 +13861 -0.054901123046875 +13862 -0.19085693359375 +13863 -0.28570556640625 +13864 -0.339263916015625 +13865 -0.3775634765625 +13866 -0.445709228515625 +13867 -0.535064697265625 +13868 -0.629058837890625 +13869 -0.697601318359375 +13870 -0.70391845703125 +13871 -0.6424560546875 +13872 -0.491241455078125 +13873 -0.265716552734375 +13874 -0.023712158203125 +13875 0.201751708984375 +13876 0.375823974609375 +13877 0.485076904296875 +13878 0.56884765625 +13879 0.634765625 +13880 0.63763427734375 +13881 0.5660400390625 +13882 0.4720458984375 +13883 0.40692138671875 +13884 0.3778076171875 +13885 0.376953125 +13886 0.371978759765625 +13887 0.313140869140625 +13888 0.184417724609375 +13889 0.011199951171875 +13890 -0.171051025390625 +13891 -0.33740234375 +13892 -0.47198486328125 +13893 -0.560394287109375 +13894 -0.58056640625 +13895 -0.54754638671875 +13896 -0.508575439453125 +13897 -0.459503173828125 +13898 -0.394378662109375 +13899 -0.35260009765625 +13900 -0.31170654296875 +13901 -0.197418212890625 +13902 -0.007965087890625 +13903 0.207489013671875 +13904 0.409210205078125 +13905 0.57208251953125 +13906 0.66595458984375 +13907 0.65875244140625 +13908 0.56744384765625 +13909 0.431396484375 +13910 0.29443359375 +13911 0.182464599609375 +13912 0.06365966796875 +13913 -0.075958251953125 +13914 -0.189422607421875 +13915 -0.271942138671875 +13916 -0.342529296875 +13917 -0.364166259765625 +13918 -0.327239990234375 +13919 -0.2769775390625 +13920 -0.253692626953125 +13921 -0.24365234375 +13922 -0.1983642578125 +13923 -0.116241455078125 +13924 -0.036834716796875 +13925 0.034881591796875 +13926 0.09124755859375 +13927 0.10888671875 +13928 0.125518798828125 +13929 0.15771484375 +13930 0.17828369140625 +13931 0.17108154296875 +13932 0.129974365234375 +13933 0.082427978515625 +13934 0.027679443359375 +13935 -0.065643310546875 +13936 -0.15936279296875 +13937 -0.21307373046875 +13938 -0.234649658203125 +13939 -0.2001953125 +13940 -0.119171142578125 +13941 -0.024749755859375 +13942 0.085784912109375 +13943 0.178131103515625 +13944 0.215576171875 +13945 0.211456298828125 +13946 0.17523193359375 +13947 0.128753662109375 +13948 0.1019287109375 +13949 0.0743408203125 +13950 0.04327392578125 +13951 0.038177490234375 +13952 0.076263427734375 +13953 0.14105224609375 +13954 0.186431884765625 +13955 0.188812255859375 +13956 0.1390380859375 +13957 0.041778564453125 +13958 -0.079437255859375 +13959 -0.219390869140625 +13960 -0.367828369140625 +13961 -0.494873046875 +13962 -0.556243896484375 +13963 -0.508697509765625 +13964 -0.3756103515625 +13965 -0.218902587890625 +13966 -0.063751220703125 +13967 0.091552734375 +13968 0.23602294921875 +13969 0.342987060546875 +13970 0.39520263671875 +13971 0.389373779296875 +13972 0.324249267578125 +13973 0.224090576171875 +13974 0.124267578125 +13975 0.037078857421875 +13976 -0.010101318359375 +13977 -0.019439697265625 +13978 -0.022796630859375 +13979 -0.001556396484375 +13980 0.056304931640625 +13981 0.106719970703125 +13982 0.096893310546875 +13983 0.042694091796875 +13984 -0.018035888671875 +13985 -0.07586669921875 +13986 -0.11944580078125 +13987 -0.15972900390625 +13988 -0.202606201171875 +13989 -0.24859619140625 +13990 -0.30517578125 +13991 -0.36212158203125 +13992 -0.39141845703125 +13993 -0.35528564453125 +13994 -0.249969482421875 +13995 -0.092864990234375 +13996 0.08905029296875 +13997 0.2352294921875 +13998 0.318817138671875 +13999 0.358642578125 +14000 0.347747802734375 +14001 0.28564453125 +14002 0.223175048828125 +14003 0.196746826171875 +14004 0.179840087890625 +14005 0.155548095703125 +14006 0.151214599609375 +14007 0.156951904296875 +14008 0.13177490234375 +14009 0.100799560546875 +14010 0.087127685546875 +14011 0.05487060546875 +14012 -0.009002685546875 +14013 -0.10400390625 +14014 -0.229400634765625 +14015 -0.35552978515625 +14016 -0.441925048828125 +14017 -0.473846435546875 +14018 -0.464813232421875 +14019 -0.419097900390625 +14020 -0.334320068359375 +14021 -0.227935791015625 +14022 -0.12347412109375 +14023 -0.02764892578125 +14024 0.077667236328125 +14025 0.2132568359375 +14026 0.38885498046875 +14027 0.582794189453125 +14028 0.734039306640625 +14029 0.800140380859375 +14030 0.7783203125 +14031 0.6651611328125 +14032 0.45965576171875 +14033 0.199188232421875 +14034 -0.050689697265625 +14035 -0.23297119140625 +14036 -0.33013916015625 +14037 -0.368408203125 +14038 -0.378936767578125 +14039 -0.376983642578125 +14040 -0.37969970703125 +14041 -0.391510009765625 +14042 -0.385345458984375 +14043 -0.3419189453125 +14044 -0.28289794921875 +14045 -0.251617431640625 +14046 -0.266143798828125 +14047 -0.273345947265625 +14048 -0.216796875 +14049 -0.128265380859375 +14050 -0.068145751953125 +14051 -0.0430908203125 +14052 -0.024444580078125 +14053 0.020721435546875 +14054 0.124481201171875 +14055 0.25787353515625 +14056 0.379119873046875 +14057 0.47991943359375 +14058 0.5281982421875 +14059 0.511138916015625 +14060 0.456207275390625 +14061 0.407470703125 +14062 0.383758544921875 +14063 0.35687255859375 +14064 0.31182861328125 +14065 0.250885009765625 +14066 0.1654052734375 +14067 0.035247802734375 +14068 -0.142059326171875 +14069 -0.33563232421875 +14070 -0.5345458984375 +14071 -0.72186279296875 +14072 -0.836669921875 +14073 -0.8326416015625 +14074 -0.7296142578125 +14075 -0.582550048828125 +14076 -0.440093994140625 +14077 -0.324310302734375 +14078 -0.20147705078125 +14079 -0.044647216796875 +14080 0.103973388671875 +14081 0.202392578125 +14082 0.264495849609375 +14083 0.338897705078125 +14084 0.443817138671875 +14085 0.545074462890625 +14086 0.6173095703125 +14087 0.6524658203125 +14088 0.66339111328125 +14089 0.6561279296875 +14090 0.606781005859375 +14091 0.501190185546875 +14092 0.352783203125 +14093 0.176544189453125 +14094 -0.034820556640625 +14095 -0.258209228515625 +14096 -0.44244384765625 +14097 -0.5753173828125 +14098 -0.65203857421875 +14099 -0.641632080078125 +14100 -0.562164306640625 +14101 -0.458038330078125 +14102 -0.350555419921875 +14103 -0.260528564453125 +14104 -0.192108154296875 +14105 -0.141937255859375 +14106 -0.1021728515625 +14107 -0.062896728515625 +14108 -0.011932373046875 +14109 0.062835693359375 +14110 0.148712158203125 +14111 0.241729736328125 +14112 0.34912109375 +14113 0.457305908203125 +14114 0.54388427734375 +14115 0.5728759765625 +14116 0.506591796875 +14117 0.351226806640625 +14118 0.146514892578125 +14119 -0.05523681640625 +14120 -0.21624755859375 +14121 -0.334930419921875 +14122 -0.402984619140625 +14123 -0.4412841796875 +14124 -0.49578857421875 +14125 -0.5601806640625 +14126 -0.600738525390625 +14127 -0.584228515625 +14128 -0.47930908203125 +14129 -0.27935791015625 +14130 -0.0089111328125 +14131 0.268798828125 +14132 0.482818603515625 +14133 0.60369873046875 +14134 0.650421142578125 +14135 0.66400146484375 +14136 0.6414794921875 +14137 0.572540283203125 +14138 0.498138427734375 +14139 0.439453125 +14140 0.375518798828125 +14141 0.274505615234375 +14142 0.1087646484375 +14143 -0.099395751953125 +14144 -0.3182373046875 +14145 -0.5489501953125 +14146 -0.7738037109375 +14147 -0.86383056640625 +14148 -0.870391845703125 +14149 -0.86895751953125 +14150 -0.861053466796875 +14151 -0.765869140625 +14152 -0.5301513671875 +14153 -0.214691162109375 +14154 0.137359619140625 +14155 0.474822998046875 +14156 0.76239013671875 +14157 0.867462158203125 +14158 0.870361328125 +14159 0.86480712890625 +14160 0.831817626953125 +14161 0.677581787109375 +14162 0.495880126953125 +14163 0.30767822265625 +14164 0.116180419921875 +14165 -0.110748291015625 +14166 -0.381805419921875 +14167 -0.6572265625 +14168 -0.857421875 +14169 -0.870391845703125 +14170 -0.870391845703125 +14171 -0.86444091796875 +14172 -0.85723876953125 +14173 -0.790008544921875 +14174 -0.62847900390625 +14175 -0.3956298828125 +14176 -0.126708984375 +14177 0.150115966796875 +14178 0.424041748046875 +14179 0.670623779296875 +14180 0.854522705078125 +14181 0.866485595703125 +14182 0.86920166015625 +14183 0.8653564453125 +14184 0.857147216796875 +14185 0.766845703125 +14186 0.628509521484375 +14187 0.462127685546875 +14188 0.297210693359375 +14189 0.14862060546875 +14190 -0.00537109375 +14191 -0.15753173828125 +14192 -0.31304931640625 +14193 -0.48876953125 +14194 -0.6416015625 +14195 -0.751373291015625 +14196 -0.84619140625 +14197 -0.861297607421875 +14198 -0.863250732421875 +14199 -0.856597900390625 +14200 -0.7498779296875 +14201 -0.624542236328125 +14202 -0.47808837890625 +14203 -0.253387451171875 +14204 0.003692626953125 +14205 0.2257080078125 +14206 0.427154541015625 +14207 0.643218994140625 +14208 0.855926513671875 +14209 0.870361328125 +14210 0.870361328125 +14211 0.862762451171875 +14212 0.79669189453125 +14213 0.595794677734375 +14214 0.362152099609375 +14215 0.1270751953125 +14216 -0.086944580078125 +14217 -0.2784423828125 +14218 -0.484832763671875 +14219 -0.729583740234375 +14220 -0.86688232421875 +14221 -0.870391845703125 +14222 -0.86859130859375 +14223 -0.86279296875 +14224 -0.817962646484375 +14225 -0.6116943359375 +14226 -0.3128662109375 +14227 0.039398193359375 +14228 0.422821044921875 +14229 0.805145263671875 +14230 0.870361328125 +14231 0.870361328125 +14232 0.860015869140625 +14233 0.727935791015625 +14234 0.48114013671875 +14235 0.2059326171875 +14236 -0.06103515625 +14237 -0.29913330078125 +14238 -0.516204833984375 +14239 -0.7252197265625 +14240 -0.85980224609375 +14241 -0.870391845703125 +14242 -0.870391845703125 +14243 -0.858062744140625 +14244 -0.673004150390625 +14245 -0.42694091796875 +14246 -0.2100830078125 +14247 -0.0362548828125 +14248 0.10943603515625 +14249 0.23516845703125 +14250 0.373687744140625 +14251 0.517791748046875 +14252 0.602783203125 +14253 0.635711669921875 +14254 0.655181884765625 +14255 0.65948486328125 +14256 0.651275634765625 +14257 0.61846923828125 +14258 0.53753662109375 +14259 0.404144287109375 +14260 0.22186279296875 +14261 0.003997802734375 +14262 -0.22100830078125 +14263 -0.42449951171875 +14264 -0.579833984375 +14265 -0.641876220703125 +14266 -0.6177978515625 +14267 -0.575531005859375 +14268 -0.526336669921875 +14269 -0.42645263671875 +14270 -0.2581787109375 +14271 -0.068695068359375 +14272 0.09222412109375 +14273 0.232147216796875 +14274 0.3509521484375 +14275 0.410064697265625 +14276 0.372955322265625 +14277 0.2554931640625 +14278 0.10711669921875 +14279 -0.052886962890625 +14280 -0.186279296875 +14281 -0.23291015625 +14282 -0.209442138671875 +14283 -0.174163818359375 +14284 -0.126739501953125 +14285 -0.048126220703125 +14286 0.0426025390625 +14287 0.10748291015625 +14288 0.1409912109375 +14289 0.19708251953125 +14290 0.273651123046875 +14291 0.31768798828125 +14292 0.341094970703125 +14293 0.368011474609375 +14294 0.37249755859375 +14295 0.30072021484375 +14296 0.1517333984375 +14297 -0.01470947265625 +14298 -0.1883544921875 +14299 -0.372711181640625 +14300 -0.51397705078125 +14301 -0.57177734375 +14302 -0.53948974609375 +14303 -0.43511962890625 +14304 -0.2962646484375 +14305 -0.161102294921875 +14306 -0.0435791015625 +14307 0.060394287109375 +14308 0.13665771484375 +14309 0.170135498046875 +14310 0.16552734375 +14311 0.15728759765625 +14312 0.150787353515625 +14313 0.12200927734375 +14314 0.080108642578125 +14315 0.05126953125 +14316 0.062896728515625 +14317 0.09271240234375 +14318 0.092987060546875 +14319 0.07855224609375 +14320 0.06427001953125 +14321 0.0347900390625 +14322 -0.01171875 +14323 -0.056060791015625 +14324 -0.055511474609375 +14325 -0.010467529296875 +14326 0.02508544921875 +14327 0.025665283203125 +14328 0.017333984375 +14329 0.00189208984375 +14330 -0.03173828125 +14331 -0.071502685546875 +14332 -0.13543701171875 +14333 -0.219970703125 +14334 -0.300506591796875 +14335 -0.376312255859375 +14336 -0.416107177734375 +14337 -0.371124267578125 +14338 -0.242279052734375 +14339 -0.069732666015625 +14340 0.125640869140625 +14341 0.31268310546875 +14342 0.45501708984375 +14343 0.554779052734375 +14344 0.61065673828125 +14345 0.610931396484375 +14346 0.531463623046875 +14347 0.3883056640625 +14348 0.23468017578125 +14349 0.095245361328125 +14350 -0.00396728515625 +14351 -0.04852294921875 +14352 -0.055145263671875 +14353 -0.0758056640625 +14354 -0.138702392578125 +14355 -0.209197998046875 +14356 -0.289031982421875 +14357 -0.37884521484375 +14358 -0.456329345703125 +14359 -0.51641845703125 +14360 -0.519287109375 +14361 -0.458251953125 +14362 -0.384796142578125 +14363 -0.323699951171875 +14364 -0.269287109375 +14365 -0.1951904296875 +14366 -0.100006103515625 +14367 -0.01055908203125 +14368 0.1033935546875 +14369 0.24908447265625 +14370 0.373199462890625 +14371 0.45806884765625 +14372 0.511474609375 +14373 0.565399169921875 +14374 0.61138916015625 +14375 0.5897216796875 +14376 0.4906005859375 +14377 0.33148193359375 +14378 0.147796630859375 +14379 -0.01873779296875 +14380 -0.140289306640625 +14381 -0.191986083984375 +14382 -0.184295654296875 +14383 -0.161834716796875 +14384 -0.166595458984375 +14385 -0.19390869140625 +14386 -0.22442626953125 +14387 -0.279754638671875 +14388 -0.3389892578125 +14389 -0.3543701171875 +14390 -0.348175048828125 +14391 -0.32598876953125 +14392 -0.2581787109375 +14393 -0.139801025390625 +14394 0.014617919921875 +14395 0.144378662109375 +14396 0.221038818359375 +14397 0.27069091796875 +14398 0.294036865234375 +14399 0.311767578125 +14400 0.339141845703125 +14401 0.360260009765625 +14402 0.360504150390625 +14403 0.308380126953125 +14404 0.18170166015625 +14405 0.0047607421875 +14406 -0.17559814453125 +14407 -0.3143310546875 +14408 -0.36785888671875 +14409 -0.36248779296875 +14410 -0.343536376953125 +14411 -0.3018798828125 +14412 -0.231414794921875 +14413 -0.117645263671875 +14414 0.007049560546875 +14415 0.087982177734375 +14416 0.13946533203125 +14417 0.17425537109375 +14418 0.188201904296875 +14419 0.171234130859375 +14420 0.118438720703125 +14421 0.05706787109375 +14422 -0.010711669921875 +14423 -0.0914306640625 +14424 -0.162322998046875 +14425 -0.194549560546875 +14426 -0.1492919921875 +14427 -0.02166748046875 +14428 0.124053955078125 +14429 0.211151123046875 +14430 0.240447998046875 +14431 0.242218017578125 +14432 0.2257080078125 +14433 0.194366455078125 +14434 0.115509033203125 +14435 0.0128173828125 +14436 -0.053802490234375 +14437 -0.110626220703125 +14438 -0.199493408203125 +14439 -0.29437255859375 +14440 -0.33221435546875 +14441 -0.27972412109375 +14442 -0.185333251953125 +14443 -0.128204345703125 +14444 -0.115692138671875 +14445 -0.116455078125 +14446 -0.105926513671875 +14447 -0.053955078125 +14448 0.048797607421875 +14449 0.157318115234375 +14450 0.212005615234375 +14451 0.218475341796875 +14452 0.23724365234375 +14453 0.30535888671875 +14454 0.38128662109375 +14455 0.404449462890625 +14456 0.3944091796875 +14457 0.3885498046875 +14458 0.362640380859375 +14459 0.27362060546875 +14460 0.11712646484375 +14461 -0.054901123046875 +14462 -0.19085693359375 +14463 -0.28570556640625 +14464 -0.339263916015625 +14465 -0.3775634765625 +14466 -0.445709228515625 +14467 -0.535064697265625 +14468 -0.629058837890625 +14469 -0.697601318359375 +14470 -0.70391845703125 +14471 -0.6424560546875 +14472 -0.491241455078125 +14473 -0.265716552734375 +14474 -0.023712158203125 +14475 0.201751708984375 +14476 0.375823974609375 +14477 0.485076904296875 +14478 0.56884765625 +14479 0.634765625 +14480 0.63763427734375 +14481 0.5660400390625 +14482 0.4720458984375 +14483 0.40692138671875 +14484 0.3778076171875 +14485 0.376953125 +14486 0.371978759765625 +14487 0.313140869140625 +14488 0.184417724609375 +14489 0.011199951171875 +14490 -0.171051025390625 +14491 -0.33740234375 +14492 -0.47198486328125 +14493 -0.560394287109375 +14494 -0.58056640625 +14495 -0.54754638671875 +14496 -0.508575439453125 +14497 -0.459503173828125 +14498 -0.394378662109375 +14499 -0.35260009765625 +14500 -0.31170654296875 +14501 -0.197418212890625 +14502 -0.007965087890625 +14503 0.207489013671875 +14504 0.409210205078125 +14505 0.57208251953125 +14506 0.66595458984375 +14507 0.65875244140625 +14508 0.56744384765625 +14509 0.431396484375 +14510 0.29443359375 +14511 0.182464599609375 +14512 0.06365966796875 +14513 -0.075958251953125 +14514 -0.189422607421875 +14515 -0.271942138671875 +14516 -0.342529296875 +14517 -0.364166259765625 +14518 -0.327239990234375 +14519 -0.2769775390625 +14520 -0.253692626953125 +14521 -0.24365234375 +14522 -0.1983642578125 +14523 -0.116241455078125 +14524 -0.036834716796875 +14525 0.034881591796875 +14526 0.09124755859375 +14527 0.10888671875 +14528 0.125518798828125 +14529 0.15771484375 +14530 0.17828369140625 +14531 0.17108154296875 +14532 0.129974365234375 +14533 0.082427978515625 +14534 0.027679443359375 +14535 -0.065643310546875 +14536 -0.15936279296875 +14537 -0.21307373046875 +14538 -0.234649658203125 +14539 -0.2001953125 +14540 -0.119171142578125 +14541 -0.024749755859375 +14542 0.085784912109375 +14543 0.178131103515625 +14544 0.215576171875 +14545 0.211456298828125 +14546 0.17523193359375 +14547 0.128753662109375 +14548 0.1019287109375 +14549 0.0743408203125 +14550 0.04327392578125 +14551 0.038177490234375 +14552 0.076263427734375 +14553 0.14105224609375 +14554 0.186431884765625 +14555 0.188812255859375 +14556 0.1390380859375 +14557 0.041778564453125 +14558 -0.079437255859375 +14559 -0.219390869140625 +14560 -0.367828369140625 +14561 -0.494873046875 +14562 -0.556243896484375 +14563 -0.508697509765625 +14564 -0.3756103515625 +14565 -0.218902587890625 +14566 -0.063751220703125 +14567 0.091552734375 +14568 0.23602294921875 +14569 0.342987060546875 +14570 0.39520263671875 +14571 0.389373779296875 +14572 0.324249267578125 +14573 0.224090576171875 +14574 0.124267578125 +14575 0.037078857421875 +14576 -0.010101318359375 +14577 -0.019439697265625 +14578 -0.022796630859375 +14579 -0.001556396484375 +14580 0.056304931640625 +14581 0.106719970703125 +14582 0.096893310546875 +14583 0.042694091796875 +14584 -0.018035888671875 +14585 -0.07586669921875 +14586 -0.11944580078125 +14587 -0.15972900390625 +14588 -0.202606201171875 +14589 -0.24859619140625 +14590 -0.30517578125 +14591 -0.36212158203125 +14592 -0.39141845703125 +14593 -0.35528564453125 +14594 -0.249969482421875 +14595 -0.092864990234375 +14596 0.08905029296875 +14597 0.2352294921875 +14598 0.318817138671875 +14599 0.358642578125 +14600 0.347747802734375 +14601 0.28564453125 +14602 0.223175048828125 +14603 0.196746826171875 +14604 0.179840087890625 +14605 0.155548095703125 +14606 0.151214599609375 +14607 0.156951904296875 +14608 0.13177490234375 +14609 0.100799560546875 +14610 0.087127685546875 +14611 0.05487060546875 +14612 -0.009002685546875 +14613 -0.10400390625 +14614 -0.229400634765625 +14615 -0.35552978515625 +14616 -0.441925048828125 +14617 -0.473846435546875 +14618 -0.464813232421875 +14619 -0.419097900390625 +14620 -0.334320068359375 +14621 -0.227935791015625 +14622 -0.12347412109375 +14623 -0.02764892578125 +14624 0.077667236328125 +14625 0.2132568359375 +14626 0.38885498046875 +14627 0.582794189453125 +14628 0.734039306640625 +14629 0.800140380859375 +14630 0.7783203125 +14631 0.6651611328125 +14632 0.45965576171875 +14633 0.199188232421875 +14634 -0.050689697265625 +14635 -0.23297119140625 +14636 -0.33013916015625 +14637 -0.368408203125 +14638 -0.378936767578125 +14639 -0.376983642578125 +14640 -0.37969970703125 +14641 -0.391510009765625 +14642 -0.385345458984375 +14643 -0.3419189453125 +14644 -0.28289794921875 +14645 -0.251617431640625 +14646 -0.266143798828125 +14647 -0.273345947265625 +14648 -0.216796875 +14649 -0.128265380859375 +14650 -0.068145751953125 +14651 -0.0430908203125 +14652 -0.024444580078125 +14653 0.020721435546875 +14654 0.124481201171875 +14655 0.25787353515625 +14656 0.379119873046875 +14657 0.47991943359375 +14658 0.5281982421875 +14659 0.511138916015625 +14660 0.456207275390625 +14661 0.407470703125 +14662 0.383758544921875 +14663 0.35687255859375 +14664 0.31182861328125 +14665 0.250885009765625 +14666 0.1654052734375 +14667 0.035247802734375 +14668 -0.142059326171875 +14669 -0.33563232421875 +14670 -0.5345458984375 +14671 -0.72186279296875 +14672 -0.836669921875 +14673 -0.8326416015625 +14674 -0.7296142578125 +14675 -0.582550048828125 +14676 -0.440093994140625 +14677 -0.324310302734375 +14678 -0.20147705078125 +14679 -0.044647216796875 +14680 0.103973388671875 +14681 0.202392578125 +14682 0.264495849609375 +14683 0.338897705078125 +14684 0.443817138671875 +14685 0.545074462890625 +14686 0.6173095703125 +14687 0.6524658203125 +14688 0.66339111328125 +14689 0.6561279296875 +14690 0.606781005859375 +14691 0.501190185546875 +14692 0.352783203125 +14693 0.176544189453125 +14694 -0.034820556640625 +14695 -0.258209228515625 +14696 -0.44244384765625 +14697 -0.5753173828125 +14698 -0.65203857421875 +14699 -0.641632080078125 +14700 -0.562164306640625 +14701 -0.458038330078125 +14702 -0.350555419921875 +14703 -0.260528564453125 +14704 -0.192108154296875 +14705 -0.141937255859375 +14706 -0.1021728515625 +14707 -0.062896728515625 +14708 -0.011932373046875 +14709 0.062835693359375 +14710 0.148712158203125 +14711 0.241729736328125 +14712 0.34912109375 +14713 0.457305908203125 +14714 0.54388427734375 +14715 0.5728759765625 +14716 0.506591796875 +14717 0.351226806640625 +14718 0.146514892578125 +14719 -0.05523681640625 +14720 -0.21624755859375 +14721 -0.334930419921875 +14722 -0.402984619140625 +14723 -0.4412841796875 +14724 -0.49578857421875 +14725 -0.5601806640625 +14726 -0.600738525390625 +14727 -0.584228515625 +14728 -0.47930908203125 +14729 -0.27935791015625 +14730 -0.0089111328125 +14731 0.268798828125 +14732 0.482818603515625 +14733 0.60369873046875 +14734 0.650421142578125 +14735 0.66400146484375 +14736 0.6414794921875 +14737 0.572540283203125 +14738 0.498138427734375 +14739 0.439453125 +14740 0.375518798828125 +14741 0.274505615234375 +14742 0.1087646484375 +14743 -0.099395751953125 +14744 -0.3182373046875 +14745 -0.5489501953125 +14746 -0.7738037109375 +14747 -0.86383056640625 +14748 -0.870391845703125 +14749 -0.86895751953125 +14750 -0.861053466796875 +14751 -0.765869140625 +14752 -0.5301513671875 +14753 -0.214691162109375 +14754 0.137359619140625 +14755 0.474822998046875 +14756 0.76239013671875 +14757 0.867462158203125 +14758 0.870361328125 +14759 0.86480712890625 +14760 0.831817626953125 +14761 0.677581787109375 +14762 0.495880126953125 +14763 0.30767822265625 +14764 0.116180419921875 +14765 -0.110748291015625 +14766 -0.381805419921875 +14767 -0.6572265625 +14768 -0.857421875 +14769 -0.870391845703125 +14770 -0.870391845703125 +14771 -0.86444091796875 +14772 -0.85723876953125 +14773 -0.790008544921875 +14774 -0.62847900390625 +14775 -0.3956298828125 +14776 -0.126708984375 +14777 0.150115966796875 +14778 0.424041748046875 +14779 0.670623779296875 +14780 0.854522705078125 +14781 0.866485595703125 +14782 0.86920166015625 +14783 0.8653564453125 +14784 0.857147216796875 +14785 0.766845703125 +14786 0.628509521484375 +14787 0.462127685546875 +14788 0.297210693359375 +14789 0.14862060546875 +14790 -0.00537109375 +14791 -0.15753173828125 +14792 -0.31304931640625 +14793 -0.48876953125 +14794 -0.6416015625 +14795 -0.751373291015625 +14796 -0.84619140625 +14797 -0.861297607421875 +14798 -0.863250732421875 +14799 -0.856597900390625 +14800 -0.7498779296875 +14801 -0.624542236328125 +14802 -0.47808837890625 +14803 -0.253387451171875 +14804 0.003692626953125 +14805 0.2257080078125 +14806 0.427154541015625 +14807 0.643218994140625 +14808 0.855926513671875 +14809 0.870361328125 +14810 0.870361328125 +14811 0.862762451171875 +14812 0.79669189453125 +14813 0.595794677734375 +14814 0.362152099609375 +14815 0.1270751953125 +14816 -0.086944580078125 +14817 -0.2784423828125 +14818 -0.484832763671875 +14819 -0.729583740234375 +14820 -0.86688232421875 +14821 -0.870391845703125 +14822 -0.86859130859375 +14823 -0.86279296875 +14824 -0.817962646484375 +14825 -0.6116943359375 +14826 -0.3128662109375 +14827 0.039398193359375 +14828 0.422821044921875 +14829 0.805145263671875 +14830 0.870361328125 +14831 0.870361328125 +14832 0.860015869140625 +14833 0.727935791015625 +14834 0.48114013671875 +14835 0.2059326171875 +14836 -0.06103515625 +14837 -0.29913330078125 +14838 -0.516204833984375 +14839 -0.7252197265625 +14840 -0.85980224609375 +14841 -0.870391845703125 +14842 -0.870391845703125 +14843 -0.858062744140625 +14844 -0.673004150390625 +14845 -0.42694091796875 +14846 -0.2100830078125 +14847 -0.0362548828125 +14848 0.10943603515625 +14849 0.23516845703125 +14850 0.373687744140625 +14851 0.517791748046875 +14852 0.602783203125 +14853 0.635711669921875 +14854 0.655181884765625 +14855 0.65948486328125 +14856 0.651275634765625 +14857 0.61846923828125 +14858 0.53753662109375 +14859 0.404144287109375 +14860 0.22186279296875 +14861 0.003997802734375 +14862 -0.22100830078125 +14863 -0.42449951171875 +14864 -0.579833984375 +14865 -0.641876220703125 +14866 -0.6177978515625 +14867 -0.575531005859375 +14868 -0.526336669921875 +14869 -0.42645263671875 +14870 -0.2581787109375 +14871 -0.068695068359375 +14872 0.09222412109375 +14873 0.232147216796875 +14874 0.3509521484375 +14875 0.410064697265625 +14876 0.372955322265625 +14877 0.2554931640625 +14878 0.10711669921875 +14879 -0.052886962890625 +14880 -0.186279296875 +14881 -0.23291015625 +14882 -0.209442138671875 +14883 -0.174163818359375 +14884 -0.126739501953125 +14885 -0.048126220703125 +14886 0.0426025390625 +14887 0.10748291015625 +14888 0.1409912109375 +14889 0.19708251953125 +14890 0.273651123046875 +14891 0.31768798828125 +14892 0.341094970703125 +14893 0.368011474609375 +14894 0.37249755859375 +14895 0.30072021484375 +14896 0.1517333984375 +14897 -0.01470947265625 +14898 -0.1883544921875 +14899 -0.372711181640625 +14900 -0.51397705078125 +14901 -0.57177734375 +14902 -0.53948974609375 +14903 -0.43511962890625 +14904 -0.2962646484375 +14905 -0.161102294921875 +14906 -0.0435791015625 +14907 0.060394287109375 +14908 0.13665771484375 +14909 0.170135498046875 +14910 0.16552734375 +14911 0.15728759765625 +14912 0.150787353515625 +14913 0.12200927734375 +14914 0.080108642578125 +14915 0.05126953125 +14916 0.062896728515625 +14917 0.09271240234375 +14918 0.092987060546875 +14919 0.07855224609375 +14920 0.06427001953125 +14921 0.0347900390625 +14922 -0.01171875 +14923 -0.056060791015625 +14924 -0.055511474609375 +14925 -0.010467529296875 +14926 0.02508544921875 +14927 0.025665283203125 +14928 0.017333984375 +14929 0.00189208984375 +14930 -0.03173828125 +14931 -0.071502685546875 +14932 -0.13543701171875 +14933 -0.219970703125 +14934 -0.300506591796875 +14935 -0.376312255859375 +14936 -0.416107177734375 +14937 -0.371124267578125 +14938 -0.242279052734375 +14939 -0.069732666015625 +14940 0.125640869140625 +14941 0.31268310546875 +14942 0.45501708984375 +14943 0.554779052734375 +14944 0.61065673828125 +14945 0.610931396484375 +14946 0.531463623046875 +14947 0.3883056640625 +14948 0.23468017578125 +14949 0.095245361328125 +14950 -0.00396728515625 +14951 -0.04852294921875 +14952 -0.055145263671875 +14953 -0.0758056640625 +14954 -0.138702392578125 +14955 -0.209197998046875 +14956 -0.289031982421875 +14957 -0.37884521484375 +14958 -0.456329345703125 +14959 -0.51641845703125 +14960 -0.519287109375 +14961 -0.458251953125 +14962 -0.384796142578125 +14963 -0.323699951171875 +14964 -0.269287109375 +14965 -0.1951904296875 +14966 -0.100006103515625 +14967 -0.01055908203125 +14968 0.1033935546875 +14969 0.24908447265625 +14970 0.373199462890625 +14971 0.45806884765625 +14972 0.511474609375 +14973 0.565399169921875 +14974 0.61138916015625 +14975 0.5897216796875 +14976 0.4906005859375 +14977 0.33148193359375 +14978 0.147796630859375 +14979 -0.01873779296875 +14980 -0.140289306640625 +14981 -0.191986083984375 +14982 -0.184295654296875 +14983 -0.161834716796875 +14984 -0.166595458984375 +14985 -0.19390869140625 +14986 -0.22442626953125 +14987 -0.279754638671875 +14988 -0.3389892578125 +14989 -0.3543701171875 +14990 -0.348175048828125 +14991 -0.32598876953125 +14992 -0.2581787109375 +14993 -0.139801025390625 +14994 0.014617919921875 +14995 0.144378662109375 +14996 0.221038818359375 +14997 0.27069091796875 +14998 0.294036865234375 +14999 0.311767578125 +15000 0.339141845703125 +15001 0.360260009765625 +15002 0.360504150390625 +15003 0.308380126953125 +15004 0.18170166015625 +15005 0.0047607421875 +15006 -0.17559814453125 +15007 -0.3143310546875 +15008 -0.36785888671875 +15009 -0.36248779296875 +15010 -0.343536376953125 +15011 -0.3018798828125 +15012 -0.231414794921875 +15013 -0.117645263671875 +15014 0.007049560546875 +15015 0.087982177734375 +15016 0.13946533203125 +15017 0.17425537109375 +15018 0.188201904296875 +15019 0.171234130859375 +15020 0.118438720703125 +15021 0.05706787109375 +15022 -0.010711669921875 +15023 -0.0914306640625 +15024 -0.162322998046875 +15025 -0.194549560546875 +15026 -0.1492919921875 +15027 -0.02166748046875 +15028 0.124053955078125 +15029 0.211151123046875 +15030 0.240447998046875 +15031 0.242218017578125 +15032 0.2257080078125 +15033 0.194366455078125 +15034 0.115509033203125 +15035 0.0128173828125 +15036 -0.053802490234375 +15037 -0.110626220703125 +15038 -0.199493408203125 +15039 -0.29437255859375 +15040 -0.33221435546875 +15041 -0.27972412109375 +15042 -0.185333251953125 +15043 -0.128204345703125 +15044 -0.115692138671875 +15045 -0.116455078125 +15046 -0.105926513671875 +15047 -0.053955078125 +15048 0.048797607421875 +15049 0.157318115234375 +15050 0.212005615234375 +15051 0.218475341796875 +15052 0.23724365234375 +15053 0.30535888671875 +15054 0.38128662109375 +15055 0.404449462890625 +15056 0.3944091796875 +15057 0.3885498046875 +15058 0.362640380859375 +15059 0.27362060546875 +15060 0.11712646484375 +15061 -0.054901123046875 +15062 -0.19085693359375 +15063 -0.28570556640625 +15064 -0.339263916015625 +15065 -0.3775634765625 +15066 -0.445709228515625 +15067 -0.535064697265625 +15068 -0.629058837890625 +15069 -0.697601318359375 +15070 -0.70391845703125 +15071 -0.6424560546875 +15072 -0.491241455078125 +15073 -0.265716552734375 +15074 -0.023712158203125 +15075 0.201751708984375 +15076 0.375823974609375 +15077 0.485076904296875 +15078 0.56884765625 +15079 0.634765625 +15080 0.63763427734375 +15081 0.5660400390625 +15082 0.4720458984375 +15083 0.40692138671875 +15084 0.3778076171875 +15085 0.376953125 +15086 0.371978759765625 +15087 0.313140869140625 +15088 0.184417724609375 +15089 0.011199951171875 +15090 -0.171051025390625 +15091 -0.33740234375 +15092 -0.47198486328125 +15093 -0.560394287109375 +15094 -0.58056640625 +15095 -0.54754638671875 +15096 -0.508575439453125 +15097 -0.459503173828125 +15098 -0.394378662109375 +15099 -0.35260009765625 +15100 -0.31170654296875 +15101 -0.197418212890625 +15102 -0.007965087890625 +15103 0.207489013671875 +15104 0.409210205078125 +15105 0.57208251953125 +15106 0.66595458984375 +15107 0.65875244140625 +15108 0.56744384765625 +15109 0.431396484375 +15110 0.29443359375 +15111 0.182464599609375 +15112 0.06365966796875 +15113 -0.075958251953125 +15114 -0.189422607421875 +15115 -0.271942138671875 +15116 -0.342529296875 +15117 -0.364166259765625 +15118 -0.327239990234375 +15119 -0.2769775390625 +15120 -0.253692626953125 +15121 -0.24365234375 +15122 -0.1983642578125 +15123 -0.116241455078125 +15124 -0.036834716796875 +15125 0.034881591796875 +15126 0.09124755859375 +15127 0.10888671875 +15128 0.125518798828125 +15129 0.15771484375 +15130 0.17828369140625 +15131 0.17108154296875 +15132 0.129974365234375 +15133 0.082427978515625 +15134 0.027679443359375 +15135 -0.065643310546875 +15136 -0.15936279296875 +15137 -0.21307373046875 +15138 -0.234649658203125 +15139 -0.2001953125 +15140 -0.119171142578125 +15141 -0.024749755859375 +15142 0.085784912109375 +15143 0.178131103515625 +15144 0.215576171875 +15145 0.211456298828125 +15146 0.17523193359375 +15147 0.128753662109375 +15148 0.1019287109375 +15149 0.0743408203125 +15150 0.04327392578125 +15151 0.038177490234375 +15152 0.076263427734375 +15153 0.14105224609375 +15154 0.186431884765625 +15155 0.188812255859375 +15156 0.1390380859375 +15157 0.041778564453125 +15158 -0.079437255859375 +15159 -0.219390869140625 +15160 -0.367828369140625 +15161 -0.494873046875 +15162 -0.556243896484375 +15163 -0.508697509765625 +15164 -0.3756103515625 +15165 -0.218902587890625 +15166 -0.063751220703125 +15167 0.091552734375 +15168 0.23602294921875 +15169 0.342987060546875 +15170 0.39520263671875 +15171 0.389373779296875 +15172 0.324249267578125 +15173 0.224090576171875 +15174 0.124267578125 +15175 0.037078857421875 +15176 -0.010101318359375 +15177 -0.019439697265625 +15178 -0.022796630859375 +15179 -0.001556396484375 +15180 0.056304931640625 +15181 0.106719970703125 +15182 0.096893310546875 +15183 0.042694091796875 +15184 -0.018035888671875 +15185 -0.07586669921875 +15186 -0.11944580078125 +15187 -0.15972900390625 +15188 -0.202606201171875 +15189 -0.24859619140625 +15190 -0.30517578125 +15191 -0.36212158203125 +15192 -0.39141845703125 +15193 -0.35528564453125 +15194 -0.249969482421875 +15195 -0.092864990234375 +15196 0.08905029296875 +15197 0.2352294921875 +15198 0.318817138671875 +15199 0.358642578125 +15200 0.347747802734375 +15201 0.28564453125 +15202 0.223175048828125 +15203 0.196746826171875 +15204 0.179840087890625 +15205 0.155548095703125 +15206 0.151214599609375 +15207 0.156951904296875 +15208 0.13177490234375 +15209 0.100799560546875 +15210 0.087127685546875 +15211 0.05487060546875 +15212 -0.009002685546875 +15213 -0.10400390625 +15214 -0.229400634765625 +15215 -0.35552978515625 +15216 -0.441925048828125 +15217 -0.473846435546875 +15218 -0.464813232421875 +15219 -0.419097900390625 +15220 -0.334320068359375 +15221 -0.227935791015625 +15222 -0.12347412109375 +15223 -0.02764892578125 +15224 0.077667236328125 +15225 0.2132568359375 +15226 0.38885498046875 +15227 0.582794189453125 +15228 0.734039306640625 +15229 0.800140380859375 +15230 0.7783203125 +15231 0.6651611328125 +15232 0.45965576171875 +15233 0.199188232421875 +15234 -0.050689697265625 +15235 -0.23297119140625 +15236 -0.33013916015625 +15237 -0.368408203125 +15238 -0.378936767578125 +15239 -0.376983642578125 +15240 -0.37969970703125 +15241 -0.391510009765625 +15242 -0.385345458984375 +15243 -0.3419189453125 +15244 -0.28289794921875 +15245 -0.251617431640625 +15246 -0.266143798828125 +15247 -0.273345947265625 +15248 -0.216796875 +15249 -0.128265380859375 +15250 -0.068145751953125 +15251 -0.0430908203125 +15252 -0.024444580078125 +15253 0.020721435546875 +15254 0.124481201171875 +15255 0.25787353515625 +15256 0.379119873046875 +15257 0.47991943359375 +15258 0.5281982421875 +15259 0.511138916015625 +15260 0.456207275390625 +15261 0.407470703125 +15262 0.383758544921875 +15263 0.35687255859375 +15264 0.31182861328125 +15265 0.250885009765625 +15266 0.1654052734375 +15267 0.035247802734375 +15268 -0.142059326171875 +15269 -0.33563232421875 +15270 -0.5345458984375 +15271 -0.72186279296875 +15272 -0.836669921875 +15273 -0.8326416015625 +15274 -0.7296142578125 +15275 -0.582550048828125 +15276 -0.440093994140625 +15277 -0.324310302734375 +15278 -0.20147705078125 +15279 -0.044647216796875 +15280 0.103973388671875 +15281 0.202392578125 +15282 0.264495849609375 +15283 0.338897705078125 +15284 0.443817138671875 +15285 0.545074462890625 +15286 0.6173095703125 +15287 0.6524658203125 +15288 0.66339111328125 +15289 0.6561279296875 +15290 0.606781005859375 +15291 0.501190185546875 +15292 0.352783203125 +15293 0.176544189453125 +15294 -0.034820556640625 +15295 -0.258209228515625 +15296 -0.44244384765625 +15297 -0.5753173828125 +15298 -0.65203857421875 +15299 -0.641632080078125 +15300 -0.562164306640625 +15301 -0.458038330078125 +15302 -0.350555419921875 +15303 -0.260528564453125 +15304 -0.192108154296875 +15305 -0.141937255859375 +15306 -0.1021728515625 +15307 -0.062896728515625 +15308 -0.011932373046875 +15309 0.062835693359375 +15310 0.148712158203125 +15311 0.241729736328125 +15312 0.34912109375 +15313 0.457305908203125 +15314 0.54388427734375 +15315 0.5728759765625 +15316 0.506591796875 +15317 0.351226806640625 +15318 0.146514892578125 +15319 -0.05523681640625 +15320 -0.21624755859375 +15321 -0.334930419921875 +15322 -0.402984619140625 +15323 -0.4412841796875 +15324 -0.49578857421875 +15325 -0.5601806640625 +15326 -0.600738525390625 +15327 -0.584228515625 +15328 -0.47930908203125 +15329 -0.27935791015625 +15330 -0.0089111328125 +15331 0.268798828125 +15332 0.482818603515625 +15333 0.60369873046875 +15334 0.650421142578125 +15335 0.66400146484375 +15336 0.6414794921875 +15337 0.572540283203125 +15338 0.498138427734375 +15339 0.439453125 +15340 0.375518798828125 +15341 0.274505615234375 +15342 0.1087646484375 +15343 -0.099395751953125 +15344 -0.3182373046875 +15345 -0.5489501953125 +15346 -0.7738037109375 +15347 -0.86383056640625 +15348 -0.870391845703125 +15349 -0.86895751953125 +15350 -0.861053466796875 +15351 -0.765869140625 +15352 -0.5301513671875 +15353 -0.214691162109375 +15354 0.137359619140625 +15355 0.474822998046875 +15356 0.76239013671875 +15357 0.867462158203125 +15358 0.870361328125 +15359 0.86480712890625 +15360 0.831817626953125 +15361 0.677581787109375 +15362 0.495880126953125 +15363 0.30767822265625 +15364 0.116180419921875 +15365 -0.110748291015625 +15366 -0.381805419921875 +15367 -0.6572265625 +15368 -0.857421875 +15369 -0.870391845703125 +15370 -0.870391845703125 +15371 -0.86444091796875 +15372 -0.85723876953125 +15373 -0.790008544921875 +15374 -0.62847900390625 +15375 -0.3956298828125 +15376 -0.126708984375 +15377 0.150115966796875 +15378 0.424041748046875 +15379 0.670623779296875 +15380 0.854522705078125 +15381 0.866485595703125 +15382 0.86920166015625 +15383 0.8653564453125 +15384 0.857147216796875 +15385 0.766845703125 +15386 0.628509521484375 +15387 0.462127685546875 +15388 0.297210693359375 +15389 0.14862060546875 +15390 -0.00537109375 +15391 -0.15753173828125 +15392 -0.31304931640625 +15393 -0.48876953125 +15394 -0.6416015625 +15395 -0.751373291015625 +15396 -0.84619140625 +15397 -0.861297607421875 +15398 -0.863250732421875 +15399 -0.856597900390625 +15400 -0.7498779296875 +15401 -0.624542236328125 +15402 -0.47808837890625 +15403 -0.253387451171875 +15404 0.003692626953125 +15405 0.2257080078125 +15406 0.427154541015625 +15407 0.643218994140625 +15408 0.855926513671875 +15409 0.870361328125 +15410 0.870361328125 +15411 0.862762451171875 +15412 0.79669189453125 +15413 0.595794677734375 +15414 0.362152099609375 +15415 0.1270751953125 +15416 -0.086944580078125 +15417 -0.2784423828125 +15418 -0.484832763671875 +15419 -0.729583740234375 +15420 -0.86688232421875 +15421 -0.870391845703125 +15422 -0.86859130859375 +15423 -0.86279296875 +15424 -0.817962646484375 +15425 -0.6116943359375 +15426 -0.3128662109375 +15427 0.039398193359375 +15428 0.422821044921875 +15429 0.805145263671875 +15430 0.870361328125 +15431 0.870361328125 +15432 0.860015869140625 +15433 0.727935791015625 +15434 0.48114013671875 +15435 0.2059326171875 +15436 -0.06103515625 +15437 -0.29913330078125 +15438 -0.516204833984375 +15439 -0.7252197265625 +15440 -0.85980224609375 +15441 -0.870391845703125 +15442 -0.870391845703125 +15443 -0.858062744140625 +15444 -0.673004150390625 +15445 -0.42694091796875 +15446 -0.2100830078125 +15447 -0.0362548828125 +15448 0.10943603515625 +15449 0.23516845703125 +15450 0.373687744140625 +15451 0.517791748046875 +15452 0.602783203125 +15453 0.635711669921875 +15454 0.655181884765625 +15455 0.65948486328125 +15456 0.651275634765625 +15457 0.61846923828125 +15458 0.53753662109375 +15459 0.404144287109375 +15460 0.22186279296875 +15461 0.003997802734375 +15462 -0.22100830078125 +15463 -0.42449951171875 +15464 -0.579833984375 +15465 -0.641876220703125 +15466 -0.6177978515625 +15467 -0.575531005859375 +15468 -0.526336669921875 +15469 -0.42645263671875 +15470 -0.2581787109375 +15471 -0.068695068359375 +15472 0.09222412109375 +15473 0.232147216796875 +15474 0.3509521484375 +15475 0.410064697265625 +15476 0.372955322265625 +15477 0.2554931640625 +15478 0.10711669921875 +15479 -0.052886962890625 +15480 -0.186279296875 +15481 -0.23291015625 +15482 -0.209442138671875 +15483 -0.174163818359375 +15484 -0.126739501953125 +15485 -0.048126220703125 +15486 0.0426025390625 +15487 0.10748291015625 +15488 0.1409912109375 +15489 0.19708251953125 +15490 0.273651123046875 +15491 0.31768798828125 +15492 0.341094970703125 +15493 0.368011474609375 +15494 0.37249755859375 +15495 0.30072021484375 +15496 0.1517333984375 +15497 -0.01470947265625 +15498 -0.1883544921875 +15499 -0.372711181640625 +15500 -0.51397705078125 +15501 -0.57177734375 +15502 -0.53948974609375 +15503 -0.43511962890625 +15504 -0.2962646484375 +15505 -0.161102294921875 +15506 -0.0435791015625 +15507 0.060394287109375 +15508 0.13665771484375 +15509 0.170135498046875 +15510 0.16552734375 +15511 0.15728759765625 +15512 0.150787353515625 +15513 0.12200927734375 +15514 0.080108642578125 +15515 0.05126953125 +15516 0.062896728515625 +15517 0.09271240234375 +15518 0.092987060546875 +15519 0.07855224609375 +15520 0.06427001953125 +15521 0.0347900390625 +15522 -0.01171875 +15523 -0.056060791015625 +15524 -0.055511474609375 +15525 -0.010467529296875 +15526 0.02508544921875 +15527 0.025665283203125 +15528 0.017333984375 +15529 0.00189208984375 +15530 -0.03173828125 +15531 -0.071502685546875 +15532 -0.13543701171875 +15533 -0.219970703125 +15534 -0.300506591796875 +15535 -0.376312255859375 +15536 -0.416107177734375 +15537 -0.371124267578125 +15538 -0.242279052734375 +15539 -0.069732666015625 +15540 0.125640869140625 +15541 0.31268310546875 +15542 0.45501708984375 +15543 0.554779052734375 +15544 0.61065673828125 +15545 0.610931396484375 +15546 0.531463623046875 +15547 0.3883056640625 +15548 0.23468017578125 +15549 0.095245361328125 +15550 -0.00396728515625 +15551 -0.04852294921875 +15552 -0.055145263671875 +15553 -0.0758056640625 +15554 -0.138702392578125 +15555 -0.209197998046875 +15556 -0.289031982421875 +15557 -0.37884521484375 +15558 -0.456329345703125 +15559 -0.51641845703125 +15560 -0.519287109375 +15561 -0.458251953125 +15562 -0.384796142578125 +15563 -0.323699951171875 +15564 -0.269287109375 +15565 -0.1951904296875 +15566 -0.100006103515625 +15567 -0.01055908203125 +15568 0.1033935546875 +15569 0.24908447265625 +15570 0.373199462890625 +15571 0.45806884765625 +15572 0.511474609375 +15573 0.565399169921875 +15574 0.61138916015625 +15575 0.5897216796875 +15576 0.4906005859375 +15577 0.33148193359375 +15578 0.147796630859375 +15579 -0.01873779296875 +15580 -0.140289306640625 +15581 -0.191986083984375 +15582 -0.184295654296875 +15583 -0.161834716796875 +15584 -0.166595458984375 +15585 -0.19390869140625 +15586 -0.22442626953125 +15587 -0.279754638671875 +15588 -0.3389892578125 +15589 -0.3543701171875 +15590 -0.348175048828125 +15591 -0.32598876953125 +15592 -0.2581787109375 +15593 -0.139801025390625 +15594 0.014617919921875 +15595 0.144378662109375 +15596 0.221038818359375 +15597 0.27069091796875 +15598 0.294036865234375 +15599 0.311767578125 +15600 0.339141845703125 +15601 0.360260009765625 +15602 0.360504150390625 +15603 0.308380126953125 +15604 0.18170166015625 +15605 0.0047607421875 +15606 -0.17559814453125 +15607 -0.3143310546875 +15608 -0.36785888671875 +15609 -0.36248779296875 +15610 -0.343536376953125 +15611 -0.3018798828125 +15612 -0.231414794921875 +15613 -0.117645263671875 +15614 0.007049560546875 +15615 0.087982177734375 +15616 0.13946533203125 +15617 0.17425537109375 +15618 0.188201904296875 +15619 0.171234130859375 +15620 0.118438720703125 +15621 0.05706787109375 +15622 -0.010711669921875 +15623 -0.0914306640625 +15624 -0.162322998046875 +15625 -0.194549560546875 +15626 -0.1492919921875 +15627 -0.02166748046875 +15628 0.124053955078125 +15629 0.211151123046875 +15630 0.240447998046875 +15631 0.242218017578125 +15632 0.2257080078125 +15633 0.194366455078125 +15634 0.115509033203125 +15635 0.0128173828125 +15636 -0.053802490234375 +15637 -0.110626220703125 +15638 -0.199493408203125 +15639 -0.29437255859375 +15640 -0.33221435546875 +15641 -0.27972412109375 +15642 -0.185333251953125 +15643 -0.128204345703125 +15644 -0.115692138671875 +15645 -0.116455078125 +15646 -0.105926513671875 +15647 -0.053955078125 +15648 0.048797607421875 +15649 0.157318115234375 +15650 0.212005615234375 +15651 0.218475341796875 +15652 0.23724365234375 +15653 0.30535888671875 +15654 0.38128662109375 +15655 0.404449462890625 +15656 0.3944091796875 +15657 0.3885498046875 +15658 0.362640380859375 +15659 0.27362060546875 +15660 0.11712646484375 +15661 -0.054901123046875 +15662 -0.19085693359375 +15663 -0.28570556640625 +15664 -0.339263916015625 +15665 -0.3775634765625 +15666 -0.445709228515625 +15667 -0.535064697265625 +15668 -0.629058837890625 +15669 -0.697601318359375 +15670 -0.70391845703125 +15671 -0.6424560546875 +15672 -0.491241455078125 +15673 -0.265716552734375 +15674 -0.023712158203125 +15675 0.201751708984375 +15676 0.375823974609375 +15677 0.485076904296875 +15678 0.56884765625 +15679 0.634765625 +15680 0.63763427734375 +15681 0.5660400390625 +15682 0.4720458984375 +15683 0.40692138671875 +15684 0.3778076171875 +15685 0.376953125 +15686 0.371978759765625 +15687 0.313140869140625 +15688 0.184417724609375 +15689 0.011199951171875 +15690 -0.171051025390625 +15691 -0.33740234375 +15692 -0.47198486328125 +15693 -0.560394287109375 +15694 -0.58056640625 +15695 -0.54754638671875 +15696 -0.508575439453125 +15697 -0.459503173828125 +15698 -0.394378662109375 +15699 -0.35260009765625 +15700 -0.31170654296875 +15701 -0.197418212890625 +15702 -0.007965087890625 +15703 0.207489013671875 +15704 0.409210205078125 +15705 0.57208251953125 +15706 0.66595458984375 +15707 0.65875244140625 +15708 0.56744384765625 +15709 0.431396484375 +15710 0.29443359375 +15711 0.182464599609375 +15712 0.06365966796875 +15713 -0.075958251953125 +15714 -0.189422607421875 +15715 -0.271942138671875 +15716 -0.342529296875 +15717 -0.364166259765625 +15718 -0.327239990234375 +15719 -0.2769775390625 +15720 -0.253692626953125 +15721 -0.24365234375 +15722 -0.1983642578125 +15723 -0.116241455078125 +15724 -0.036834716796875 +15725 0.034881591796875 +15726 0.09124755859375 +15727 0.10888671875 +15728 0.125518798828125 +15729 0.15771484375 +15730 0.17828369140625 +15731 0.17108154296875 +15732 0.129974365234375 +15733 0.082427978515625 +15734 0.027679443359375 +15735 -0.065643310546875 +15736 -0.15936279296875 +15737 -0.21307373046875 +15738 -0.234649658203125 +15739 -0.2001953125 +15740 -0.119171142578125 +15741 -0.024749755859375 +15742 0.085784912109375 +15743 0.178131103515625 +15744 0.215576171875 +15745 0.211456298828125 +15746 0.17523193359375 +15747 0.128753662109375 +15748 0.1019287109375 +15749 0.0743408203125 +15750 0.04327392578125 +15751 0.038177490234375 +15752 0.076263427734375 +15753 0.14105224609375 +15754 0.186431884765625 +15755 0.188812255859375 +15756 0.1390380859375 +15757 0.041778564453125 +15758 -0.079437255859375 +15759 -0.219390869140625 +15760 -0.367828369140625 +15761 -0.494873046875 +15762 -0.556243896484375 +15763 -0.508697509765625 +15764 -0.3756103515625 +15765 -0.218902587890625 +15766 -0.063751220703125 +15767 0.091552734375 +15768 0.23602294921875 +15769 0.342987060546875 +15770 0.39520263671875 +15771 0.389373779296875 +15772 0.324249267578125 +15773 0.224090576171875 +15774 0.124267578125 +15775 0.037078857421875 +15776 -0.010101318359375 +15777 -0.019439697265625 +15778 -0.022796630859375 +15779 -0.001556396484375 +15780 0.056304931640625 +15781 0.106719970703125 +15782 0.096893310546875 +15783 0.042694091796875 +15784 -0.018035888671875 +15785 -0.07586669921875 +15786 -0.11944580078125 +15787 -0.15972900390625 +15788 -0.202606201171875 +15789 -0.24859619140625 +15790 -0.30517578125 +15791 -0.36212158203125 +15792 -0.39141845703125 +15793 -0.35528564453125 +15794 -0.249969482421875 +15795 -0.092864990234375 +15796 0.08905029296875 +15797 0.2352294921875 +15798 0.318817138671875 +15799 0.358642578125 +15800 0.347747802734375 +15801 0.28564453125 +15802 0.223175048828125 +15803 0.196746826171875 +15804 0.179840087890625 +15805 0.155548095703125 +15806 0.151214599609375 +15807 0.156951904296875 +15808 0.13177490234375 +15809 0.100799560546875 +15810 0.087127685546875 +15811 0.05487060546875 +15812 -0.009002685546875 +15813 -0.10400390625 +15814 -0.229400634765625 +15815 -0.35552978515625 +15816 -0.441925048828125 +15817 -0.473846435546875 +15818 -0.464813232421875 +15819 -0.419097900390625 +15820 -0.334320068359375 +15821 -0.227935791015625 +15822 -0.12347412109375 +15823 -0.02764892578125 +15824 0.077667236328125 +15825 0.2132568359375 +15826 0.38885498046875 +15827 0.582794189453125 +15828 0.734039306640625 +15829 0.800140380859375 +15830 0.7783203125 +15831 0.6651611328125 +15832 0.45965576171875 +15833 0.199188232421875 +15834 -0.050689697265625 +15835 -0.23297119140625 +15836 -0.33013916015625 +15837 -0.368408203125 +15838 -0.378936767578125 +15839 -0.376983642578125 +15840 -0.37969970703125 +15841 -0.391510009765625 +15842 -0.385345458984375 +15843 -0.3419189453125 +15844 -0.28289794921875 +15845 -0.251617431640625 +15846 -0.266143798828125 +15847 -0.273345947265625 +15848 -0.216796875 +15849 -0.128265380859375 +15850 -0.068145751953125 +15851 -0.0430908203125 +15852 -0.024444580078125 +15853 0.020721435546875 +15854 0.124481201171875 +15855 0.25787353515625 +15856 0.379119873046875 +15857 0.47991943359375 +15858 0.5281982421875 +15859 0.511138916015625 +15860 0.456207275390625 +15861 0.407470703125 +15862 0.383758544921875 +15863 0.35687255859375 +15864 0.31182861328125 +15865 0.250885009765625 +15866 0.1654052734375 +15867 0.035247802734375 +15868 -0.142059326171875 +15869 -0.33563232421875 +15870 -0.5345458984375 +15871 -0.72186279296875 +15872 -0.836669921875 +15873 -0.8326416015625 +15874 -0.7296142578125 +15875 -0.582550048828125 +15876 -0.440093994140625 +15877 -0.324310302734375 +15878 -0.20147705078125 +15879 -0.044647216796875 +15880 0.103973388671875 +15881 0.202392578125 +15882 0.264495849609375 +15883 0.338897705078125 +15884 0.443817138671875 +15885 0.545074462890625 +15886 0.6173095703125 +15887 0.6524658203125 +15888 0.66339111328125 +15889 0.6561279296875 +15890 0.606781005859375 +15891 0.501190185546875 +15892 0.352783203125 +15893 0.176544189453125 +15894 -0.034820556640625 +15895 -0.258209228515625 +15896 -0.44244384765625 +15897 -0.5753173828125 +15898 -0.65203857421875 +15899 -0.641632080078125 +15900 -0.562164306640625 +15901 -0.458038330078125 +15902 -0.350555419921875 +15903 -0.260528564453125 +15904 -0.192108154296875 +15905 -0.141937255859375 +15906 -0.1021728515625 +15907 -0.062896728515625 +15908 -0.011932373046875 +15909 0.062835693359375 +15910 0.148712158203125 +15911 0.241729736328125 +15912 0.34912109375 +15913 0.457305908203125 +15914 0.54388427734375 +15915 0.5728759765625 +15916 0.506591796875 +15917 0.351226806640625 +15918 0.146514892578125 +15919 -0.05523681640625 +15920 -0.21624755859375 +15921 -0.334930419921875 +15922 -0.402984619140625 +15923 -0.4412841796875 +15924 -0.49578857421875 +15925 -0.5601806640625 +15926 -0.600738525390625 +15927 -0.584228515625 +15928 -0.47930908203125 +15929 -0.27935791015625 +15930 -0.0089111328125 +15931 0.268798828125 +15932 0.482818603515625 +15933 0.60369873046875 +15934 0.650421142578125 +15935 0.66400146484375 +15936 0.6414794921875 +15937 0.572540283203125 +15938 0.498138427734375 +15939 0.439453125 +15940 0.375518798828125 +15941 0.274505615234375 +15942 0.1087646484375 +15943 -0.099395751953125 +15944 -0.3182373046875 +15945 -0.5489501953125 +15946 -0.7738037109375 +15947 -0.86383056640625 +15948 -0.870391845703125 +15949 -0.86895751953125 +15950 -0.861053466796875 +15951 -0.765869140625 +15952 -0.5301513671875 +15953 -0.214691162109375 +15954 0.137359619140625 +15955 0.474822998046875 +15956 0.76239013671875 +15957 0.867462158203125 +15958 0.870361328125 +15959 0.86480712890625 +15960 0.831817626953125 +15961 0.677581787109375 +15962 0.495880126953125 +15963 0.30767822265625 +15964 0.116180419921875 +15965 -0.110748291015625 +15966 -0.381805419921875 +15967 -0.6572265625 +15968 -0.857421875 +15969 -0.870391845703125 +15970 -0.870391845703125 +15971 -0.86444091796875 +15972 -0.85723876953125 +15973 -0.790008544921875 +15974 -0.62847900390625 +15975 -0.3956298828125 +15976 -0.126708984375 +15977 0.150115966796875 +15978 0.424041748046875 +15979 0.670623779296875 +15980 0.854522705078125 +15981 0.866485595703125 +15982 0.86920166015625 +15983 0.8653564453125 +15984 0.857147216796875 +15985 0.766845703125 +15986 0.628509521484375 +15987 0.462127685546875 +15988 0.297210693359375 +15989 0.14862060546875 +15990 -0.00537109375 +15991 -0.15753173828125 +15992 -0.31304931640625 +15993 -0.48876953125 +15994 -0.6416015625 +15995 -0.751373291015625 +15996 -0.84619140625 +15997 -0.861297607421875 +15998 -0.863250732421875 +15999 -0.856597900390625 +16000 -0.7498779296875 +16001 -0.624542236328125 +16002 -0.47808837890625 +16003 -0.253387451171875 +16004 0.003692626953125 +16005 0.2257080078125 +16006 0.427154541015625 +16007 0.643218994140625 +16008 0.855926513671875 +16009 0.870361328125 +16010 0.870361328125 +16011 0.862762451171875 +16012 0.79669189453125 +16013 0.595794677734375 +16014 0.362152099609375 +16015 0.1270751953125 +16016 -0.086944580078125 +16017 -0.2784423828125 +16018 -0.484832763671875 +16019 -0.729583740234375 +16020 -0.86688232421875 +16021 -0.870391845703125 +16022 -0.86859130859375 +16023 -0.86279296875 +16024 -0.817962646484375 +16025 -0.6116943359375 +16026 -0.3128662109375 +16027 0.039398193359375 +16028 0.422821044921875 +16029 0.805145263671875 +16030 0.870361328125 +16031 0.870361328125 +16032 0.860015869140625 +16033 0.727935791015625 +16034 0.48114013671875 +16035 0.2059326171875 +16036 -0.06103515625 +16037 -0.29913330078125 +16038 -0.516204833984375 +16039 -0.7252197265625 +16040 -0.85980224609375 +16041 -0.870391845703125 +16042 -0.870391845703125 +16043 -0.858062744140625 +16044 -0.673004150390625 +16045 -0.42694091796875 +16046 -0.2100830078125 +16047 -0.0362548828125 +16048 0.10943603515625 +16049 0.23516845703125 +16050 0.373687744140625 +16051 0.517791748046875 +16052 0.602783203125 +16053 0.635711669921875 +16054 0.655181884765625 +16055 0.65948486328125 +16056 0.651275634765625 +16057 0.61846923828125 +16058 0.53753662109375 +16059 0.404144287109375 +16060 0.22186279296875 +16061 0.003997802734375 +16062 -0.22100830078125 +16063 -0.42449951171875 +16064 -0.579833984375 +16065 -0.641876220703125 +16066 -0.6177978515625 +16067 -0.575531005859375 +16068 -0.526336669921875 +16069 -0.42645263671875 +16070 -0.2581787109375 +16071 -0.068695068359375 +16072 0.09222412109375 +16073 0.232147216796875 +16074 0.3509521484375 +16075 0.410064697265625 +16076 0.372955322265625 +16077 0.2554931640625 +16078 0.10711669921875 +16079 -0.052886962890625 +16080 -0.186279296875 +16081 -0.23291015625 +16082 -0.209442138671875 +16083 -0.174163818359375 +16084 -0.126739501953125 +16085 -0.048126220703125 +16086 0.0426025390625 +16087 0.10748291015625 +16088 0.1409912109375 +16089 0.19708251953125 +16090 0.273651123046875 +16091 0.31768798828125 +16092 0.341094970703125 +16093 0.368011474609375 +16094 0.37249755859375 +16095 0.30072021484375 +16096 0.1517333984375 +16097 -0.01470947265625 +16098 -0.1883544921875 +16099 -0.372711181640625 +16100 -0.51397705078125 +16101 -0.57177734375 +16102 -0.53948974609375 +16103 -0.43511962890625 +16104 -0.2962646484375 +16105 -0.161102294921875 +16106 -0.0435791015625 +16107 0.060394287109375 +16108 0.13665771484375 +16109 0.170135498046875 +16110 0.16552734375 +16111 0.15728759765625 +16112 0.150787353515625 +16113 0.12200927734375 +16114 0.080108642578125 +16115 0.05126953125 +16116 0.062896728515625 +16117 0.09271240234375 +16118 0.092987060546875 +16119 0.07855224609375 +16120 0.06427001953125 +16121 0.0347900390625 +16122 -0.01171875 +16123 -0.056060791015625 +16124 -0.055511474609375 +16125 -0.010467529296875 +16126 0.02508544921875 +16127 0.025665283203125 +16128 0.017333984375 +16129 0.00189208984375 +16130 -0.03173828125 +16131 -0.071502685546875 +16132 -0.13543701171875 +16133 -0.219970703125 +16134 -0.300506591796875 +16135 -0.376312255859375 +16136 -0.416107177734375 +16137 -0.371124267578125 +16138 -0.242279052734375 +16139 -0.069732666015625 +16140 0.125640869140625 +16141 0.31268310546875 +16142 0.45501708984375 +16143 0.554779052734375 +16144 0.61065673828125 +16145 0.610931396484375 +16146 0.531463623046875 +16147 0.3883056640625 +16148 0.23468017578125 +16149 0.095245361328125 +16150 -0.00396728515625 +16151 -0.04852294921875 +16152 -0.055145263671875 +16153 -0.0758056640625 +16154 -0.138702392578125 +16155 -0.209197998046875 +16156 -0.289031982421875 +16157 -0.37884521484375 +16158 -0.456329345703125 +16159 -0.51641845703125 +16160 -0.519287109375 +16161 -0.458251953125 +16162 -0.384796142578125 +16163 -0.323699951171875 +16164 -0.269287109375 +16165 -0.1951904296875 +16166 -0.100006103515625 +16167 -0.01055908203125 +16168 0.1033935546875 +16169 0.24908447265625 +16170 0.373199462890625 +16171 0.45806884765625 +16172 0.511474609375 +16173 0.565399169921875 +16174 0.61138916015625 +16175 0.5897216796875 +16176 0.4906005859375 +16177 0.33148193359375 +16178 0.147796630859375 +16179 -0.01873779296875 +16180 -0.140289306640625 +16181 -0.191986083984375 +16182 -0.184295654296875 +16183 -0.161834716796875 +16184 -0.166595458984375 +16185 -0.19390869140625 +16186 -0.22442626953125 +16187 -0.279754638671875 +16188 -0.3389892578125 +16189 -0.3543701171875 +16190 -0.348175048828125 +16191 -0.32598876953125 +16192 -0.2581787109375 +16193 -0.139801025390625 +16194 0.014617919921875 +16195 0.144378662109375 +16196 0.221038818359375 +16197 0.27069091796875 +16198 0.294036865234375 +16199 0.311767578125 +16200 0.339141845703125 +16201 0.360260009765625 +16202 0.360504150390625 +16203 0.308380126953125 +16204 0.18170166015625 +16205 0.0047607421875 +16206 -0.17559814453125 +16207 -0.3143310546875 +16208 -0.36785888671875 +16209 -0.36248779296875 +16210 -0.343536376953125 +16211 -0.3018798828125 +16212 -0.231414794921875 +16213 -0.117645263671875 +16214 0.007049560546875 +16215 0.087982177734375 +16216 0.13946533203125 +16217 0.17425537109375 +16218 0.188201904296875 +16219 0.171234130859375 +16220 0.118438720703125 +16221 0.05706787109375 +16222 -0.010711669921875 +16223 -0.0914306640625 +16224 -0.162322998046875 +16225 -0.194549560546875 +16226 -0.1492919921875 +16227 -0.02166748046875 +16228 0.124053955078125 +16229 0.211151123046875 +16230 0.240447998046875 +16231 0.242218017578125 +16232 0.2257080078125 +16233 0.194366455078125 +16234 0.115509033203125 +16235 0.0128173828125 +16236 -0.053802490234375 +16237 -0.110626220703125 +16238 -0.199493408203125 +16239 -0.29437255859375 +16240 -0.33221435546875 +16241 -0.27972412109375 +16242 -0.185333251953125 +16243 -0.128204345703125 +16244 -0.115692138671875 +16245 -0.116455078125 +16246 -0.105926513671875 +16247 -0.053955078125 +16248 0.048797607421875 +16249 0.157318115234375 +16250 0.212005615234375 +16251 0.218475341796875 +16252 0.23724365234375 +16253 0.30535888671875 +16254 0.38128662109375 +16255 0.404449462890625 +16256 0.3944091796875 +16257 0.3885498046875 +16258 0.362640380859375 +16259 0.27362060546875 +16260 0.11712646484375 +16261 -0.054901123046875 +16262 -0.19085693359375 +16263 -0.28570556640625 +16264 -0.339263916015625 +16265 -0.3775634765625 +16266 -0.445709228515625 +16267 -0.535064697265625 +16268 -0.629058837890625 +16269 -0.697601318359375 +16270 -0.70391845703125 +16271 -0.6424560546875 +16272 -0.491241455078125 +16273 -0.265716552734375 +16274 -0.023712158203125 +16275 0.201751708984375 +16276 0.375823974609375 +16277 0.485076904296875 +16278 0.56884765625 +16279 0.634765625 +16280 0.63763427734375 +16281 0.5660400390625 +16282 0.4720458984375 +16283 0.40692138671875 +16284 0.3778076171875 +16285 0.376953125 +16286 0.371978759765625 +16287 0.313140869140625 +16288 0.184417724609375 +16289 0.011199951171875 +16290 -0.171051025390625 +16291 -0.33740234375 +16292 -0.47198486328125 +16293 -0.560394287109375 +16294 -0.58056640625 +16295 -0.54754638671875 +16296 -0.508575439453125 +16297 -0.459503173828125 +16298 -0.394378662109375 +16299 -0.35260009765625 +16300 -0.31170654296875 +16301 -0.197418212890625 +16302 -0.007965087890625 +16303 0.207489013671875 +16304 0.409210205078125 +16305 0.57208251953125 +16306 0.66595458984375 +16307 0.65875244140625 +16308 0.56744384765625 +16309 0.431396484375 +16310 0.29443359375 +16311 0.182464599609375 +16312 0.06365966796875 +16313 -0.075958251953125 +16314 -0.189422607421875 +16315 -0.271942138671875 +16316 -0.342529296875 +16317 -0.364166259765625 +16318 -0.327239990234375 +16319 -0.2769775390625 +16320 -0.253692626953125 +16321 -0.24365234375 +16322 -0.1983642578125 +16323 -0.116241455078125 +16324 -0.036834716796875 +16325 0.034881591796875 +16326 0.09124755859375 +16327 0.10888671875 +16328 0.125518798828125 +16329 0.15771484375 +16330 0.17828369140625 +16331 0.17108154296875 +16332 0.129974365234375 +16333 0.082427978515625 +16334 0.027679443359375 +16335 -0.065643310546875 +16336 -0.15936279296875 +16337 -0.21307373046875 +16338 -0.234649658203125 +16339 -0.2001953125 +16340 -0.119171142578125 +16341 -0.024749755859375 +16342 0.085784912109375 +16343 0.178131103515625 +16344 0.215576171875 +16345 0.211456298828125 +16346 0.17523193359375 +16347 0.128753662109375 +16348 0.1019287109375 +16349 0.0743408203125 +16350 0.04327392578125 +16351 0.038177490234375 +16352 0.076263427734375 +16353 0.14105224609375 +16354 0.186431884765625 +16355 0.188812255859375 +16356 0.1390380859375 +16357 0.041778564453125 +16358 -0.079437255859375 +16359 -0.219390869140625 +16360 -0.367828369140625 +16361 -0.494873046875 +16362 -0.556243896484375 +16363 -0.508697509765625 +16364 -0.3756103515625 +16365 -0.218902587890625 +16366 -0.063751220703125 +16367 0.091552734375 +16368 0.23602294921875 +16369 0.342987060546875 +16370 0.39520263671875 +16371 0.389373779296875 +16372 0.324249267578125 +16373 0.224090576171875 +16374 0.124267578125 +16375 0.037078857421875 +16376 -0.010101318359375 +16377 -0.019439697265625 +16378 -0.022796630859375 +16379 -0.001556396484375 +16380 0.056304931640625 +16381 0.106719970703125 +16382 0.096893310546875 +16383 0.042694091796875 +16384 -0.018035888671875 +16385 -0.07586669921875 +16386 -0.11944580078125 +16387 -0.15972900390625 +16388 -0.202606201171875 +16389 -0.24859619140625 +16390 -0.30517578125 +16391 -0.36212158203125 +16392 -0.39141845703125 +16393 -0.35528564453125 +16394 -0.249969482421875 +16395 -0.092864990234375 +16396 0.08905029296875 +16397 0.2352294921875 +16398 0.318817138671875 +16399 0.358642578125 +16400 0.347747802734375 +16401 0.28564453125 +16402 0.223175048828125 +16403 0.196746826171875 +16404 0.179840087890625 +16405 0.155548095703125 +16406 0.151214599609375 +16407 0.156951904296875 +16408 0.13177490234375 +16409 0.100799560546875 +16410 0.087127685546875 +16411 0.05487060546875 +16412 -0.009002685546875 +16413 -0.10400390625 +16414 -0.229400634765625 +16415 -0.35552978515625 +16416 -0.441925048828125 +16417 -0.473846435546875 +16418 -0.464813232421875 +16419 -0.419097900390625 +16420 -0.334320068359375 +16421 -0.227935791015625 +16422 -0.12347412109375 +16423 -0.02764892578125 +16424 0.077667236328125 +16425 0.2132568359375 +16426 0.38885498046875 +16427 0.582794189453125 +16428 0.734039306640625 +16429 0.800140380859375 +16430 0.7783203125 +16431 0.6651611328125 +16432 0.45965576171875 +16433 0.199188232421875 +16434 -0.050689697265625 +16435 -0.23297119140625 +16436 -0.33013916015625 +16437 -0.368408203125 +16438 -0.378936767578125 +16439 -0.376983642578125 +16440 -0.37969970703125 +16441 -0.391510009765625 +16442 -0.385345458984375 +16443 -0.3419189453125 +16444 -0.28289794921875 +16445 -0.251617431640625 +16446 -0.266143798828125 +16447 -0.273345947265625 +16448 -0.216796875 +16449 -0.128265380859375 +16450 -0.068145751953125 +16451 -0.0430908203125 +16452 -0.024444580078125 +16453 0.020721435546875 +16454 0.124481201171875 +16455 0.25787353515625 +16456 0.379119873046875 +16457 0.47991943359375 +16458 0.5281982421875 +16459 0.511138916015625 +16460 0.456207275390625 +16461 0.407470703125 +16462 0.383758544921875 +16463 0.35687255859375 +16464 0.31182861328125 +16465 0.250885009765625 +16466 0.1654052734375 +16467 0.035247802734375 +16468 -0.142059326171875 +16469 -0.33563232421875 +16470 -0.5345458984375 +16471 -0.72186279296875 +16472 -0.836669921875 +16473 -0.8326416015625 +16474 -0.7296142578125 +16475 -0.582550048828125 +16476 -0.440093994140625 +16477 -0.324310302734375 +16478 -0.20147705078125 +16479 -0.044647216796875 +16480 0.103973388671875 +16481 0.202392578125 +16482 0.264495849609375 +16483 0.338897705078125 +16484 0.443817138671875 +16485 0.545074462890625 +16486 0.6173095703125 +16487 0.6524658203125 +16488 0.66339111328125 +16489 0.6561279296875 +16490 0.606781005859375 +16491 0.501190185546875 +16492 0.352783203125 +16493 0.176544189453125 +16494 -0.034820556640625 +16495 -0.258209228515625 +16496 -0.44244384765625 +16497 -0.5753173828125 +16498 -0.65203857421875 +16499 -0.641632080078125 +16500 -0.562164306640625 +16501 -0.458038330078125 +16502 -0.350555419921875 +16503 -0.260528564453125 +16504 -0.192108154296875 +16505 -0.141937255859375 +16506 -0.1021728515625 +16507 -0.062896728515625 +16508 -0.011932373046875 +16509 0.062835693359375 +16510 0.148712158203125 +16511 0.241729736328125 +16512 0.34912109375 +16513 0.457305908203125 +16514 0.54388427734375 +16515 0.5728759765625 +16516 0.506591796875 +16517 0.351226806640625 +16518 0.146514892578125 +16519 -0.05523681640625 +16520 -0.21624755859375 +16521 -0.334930419921875 +16522 -0.402984619140625 +16523 -0.4412841796875 +16524 -0.49578857421875 +16525 -0.5601806640625 +16526 -0.600738525390625 +16527 -0.584228515625 +16528 -0.47930908203125 +16529 -0.27935791015625 +16530 -0.0089111328125 +16531 0.268798828125 +16532 0.482818603515625 +16533 0.60369873046875 +16534 0.650421142578125 +16535 0.66400146484375 +16536 0.6414794921875 +16537 0.572540283203125 +16538 0.498138427734375 +16539 0.439453125 +16540 0.375518798828125 +16541 0.274505615234375 +16542 0.1087646484375 +16543 -0.099395751953125 +16544 -0.3182373046875 +16545 -0.5489501953125 +16546 -0.7738037109375 +16547 -0.86383056640625 +16548 -0.870391845703125 +16549 -0.86895751953125 +16550 -0.861053466796875 +16551 -0.765869140625 +16552 -0.5301513671875 +16553 -0.214691162109375 +16554 0.137359619140625 +16555 0.474822998046875 +16556 0.76239013671875 +16557 0.867462158203125 +16558 0.870361328125 +16559 0.86480712890625 +16560 0.831817626953125 +16561 0.677581787109375 +16562 0.495880126953125 +16563 0.30767822265625 +16564 0.116180419921875 +16565 -0.110748291015625 +16566 -0.381805419921875 +16567 -0.6572265625 +16568 -0.857421875 +16569 -0.870391845703125 +16570 -0.870391845703125 +16571 -0.86444091796875 +16572 -0.85723876953125 +16573 -0.790008544921875 +16574 -0.62847900390625 +16575 -0.3956298828125 +16576 -0.126708984375 +16577 0.150115966796875 +16578 0.424041748046875 +16579 0.670623779296875 +16580 0.854522705078125 +16581 0.866485595703125 +16582 0.86920166015625 +16583 0.8653564453125 +16584 0.857147216796875 +16585 0.766845703125 +16586 0.628509521484375 +16587 0.462127685546875 +16588 0.297210693359375 +16589 0.14862060546875 +16590 -0.00537109375 +16591 -0.15753173828125 +16592 -0.31304931640625 +16593 -0.48876953125 +16594 -0.6416015625 +16595 -0.751373291015625 +16596 -0.84619140625 +16597 -0.861297607421875 +16598 -0.863250732421875 +16599 -0.856597900390625 +16600 -0.7498779296875 +16601 -0.624542236328125 +16602 -0.47808837890625 +16603 -0.253387451171875 +16604 0.003692626953125 +16605 0.2257080078125 +16606 0.427154541015625 +16607 0.643218994140625 +16608 0.855926513671875 +16609 0.870361328125 +16610 0.870361328125 +16611 0.862762451171875 +16612 0.79669189453125 +16613 0.595794677734375 +16614 0.362152099609375 +16615 0.1270751953125 +16616 -0.086944580078125 +16617 -0.2784423828125 +16618 -0.484832763671875 +16619 -0.729583740234375 +16620 -0.86688232421875 +16621 -0.870391845703125 +16622 -0.86859130859375 +16623 -0.86279296875 +16624 -0.817962646484375 +16625 -0.6116943359375 +16626 -0.3128662109375 +16627 0.039398193359375 +16628 0.422821044921875 +16629 0.805145263671875 +16630 0.870361328125 +16631 0.870361328125 +16632 0.860015869140625 +16633 0.727935791015625 +16634 0.48114013671875 +16635 0.2059326171875 +16636 -0.06103515625 +16637 -0.29913330078125 +16638 -0.516204833984375 +16639 -0.7252197265625 +16640 -0.85980224609375 +16641 -0.870391845703125 +16642 -0.870391845703125 +16643 -0.858062744140625 +16644 -0.673004150390625 +16645 -0.42694091796875 +16646 -0.2100830078125 +16647 -0.0362548828125 +16648 0.10943603515625 +16649 0.23516845703125 +16650 0.373687744140625 +16651 0.517791748046875 +16652 0.602783203125 +16653 0.635711669921875 +16654 0.655181884765625 +16655 0.65948486328125 +16656 0.651275634765625 +16657 0.61846923828125 +16658 0.53753662109375 +16659 0.404144287109375 +16660 0.22186279296875 +16661 0.003997802734375 +16662 -0.22100830078125 +16663 -0.42449951171875 +16664 -0.579833984375 +16665 -0.641876220703125 +16666 -0.6177978515625 +16667 -0.575531005859375 +16668 -0.526336669921875 +16669 -0.42645263671875 +16670 -0.2581787109375 +16671 -0.068695068359375 +16672 0.09222412109375 +16673 0.232147216796875 +16674 0.3509521484375 +16675 0.410064697265625 +16676 0.372955322265625 +16677 0.2554931640625 +16678 0.10711669921875 +16679 -0.052886962890625 +16680 -0.186279296875 +16681 -0.23291015625 +16682 -0.209442138671875 +16683 -0.174163818359375 +16684 -0.126739501953125 +16685 -0.048126220703125 +16686 0.0426025390625 +16687 0.10748291015625 +16688 0.1409912109375 +16689 0.19708251953125 +16690 0.273651123046875 +16691 0.31768798828125 +16692 0.341094970703125 +16693 0.368011474609375 +16694 0.37249755859375 +16695 0.30072021484375 +16696 0.1517333984375 +16697 -0.01470947265625 +16698 -0.1883544921875 +16699 -0.372711181640625 +16700 -0.51397705078125 +16701 -0.57177734375 +16702 -0.53948974609375 +16703 -0.43511962890625 +16704 -0.2962646484375 +16705 -0.161102294921875 +16706 -0.0435791015625 +16707 0.060394287109375 +16708 0.13665771484375 +16709 0.170135498046875 +16710 0.16552734375 +16711 0.15728759765625 +16712 0.150787353515625 +16713 0.12200927734375 +16714 0.080108642578125 +16715 0.05126953125 +16716 0.062896728515625 +16717 0.09271240234375 +16718 0.092987060546875 +16719 0.07855224609375 +16720 0.06427001953125 +16721 0.0347900390625 +16722 -0.01171875 +16723 -0.056060791015625 +16724 -0.055511474609375 +16725 -0.010467529296875 +16726 0.02508544921875 +16727 0.025665283203125 +16728 0.017333984375 +16729 0.00189208984375 +16730 -0.03173828125 +16731 -0.071502685546875 +16732 -0.13543701171875 +16733 -0.219970703125 +16734 -0.300506591796875 +16735 -0.376312255859375 +16736 -0.416107177734375 +16737 -0.371124267578125 +16738 -0.242279052734375 +16739 -0.069732666015625 +16740 0.125640869140625 +16741 0.31268310546875 +16742 0.45501708984375 +16743 0.554779052734375 +16744 0.61065673828125 +16745 0.610931396484375 +16746 0.531463623046875 +16747 0.3883056640625 +16748 0.23468017578125 +16749 0.095245361328125 +16750 -0.00396728515625 +16751 -0.04852294921875 +16752 -0.055145263671875 +16753 -0.0758056640625 +16754 -0.138702392578125 +16755 -0.209197998046875 +16756 -0.289031982421875 +16757 -0.37884521484375 +16758 -0.456329345703125 +16759 -0.51641845703125 +16760 -0.519287109375 +16761 -0.458251953125 +16762 -0.384796142578125 +16763 -0.323699951171875 +16764 -0.269287109375 +16765 -0.1951904296875 +16766 -0.100006103515625 +16767 -0.01055908203125 +16768 0.1033935546875 +16769 0.24908447265625 +16770 0.373199462890625 +16771 0.45806884765625 +16772 0.511474609375 +16773 0.565399169921875 +16774 0.61138916015625 +16775 0.5897216796875 +16776 0.4906005859375 +16777 0.33148193359375 +16778 0.147796630859375 +16779 -0.01873779296875 +16780 -0.140289306640625 +16781 -0.191986083984375 +16782 -0.184295654296875 +16783 -0.161834716796875 +16784 -0.166595458984375 +16785 -0.19390869140625 +16786 -0.22442626953125 +16787 -0.279754638671875 +16788 -0.3389892578125 +16789 -0.3543701171875 +16790 -0.348175048828125 +16791 -0.32598876953125 +16792 -0.2581787109375 +16793 -0.139801025390625 +16794 0.014617919921875 +16795 0.144378662109375 +16796 0.221038818359375 +16797 0.27069091796875 +16798 0.294036865234375 +16799 0.311767578125 +16800 0.339141845703125 +16801 0.360260009765625 +16802 0.360504150390625 +16803 0.308380126953125 +16804 0.18170166015625 +16805 0.0047607421875 +16806 -0.17559814453125 +16807 -0.3143310546875 +16808 -0.36785888671875 +16809 -0.36248779296875 +16810 -0.343536376953125 +16811 -0.3018798828125 +16812 -0.231414794921875 +16813 -0.117645263671875 +16814 0.007049560546875 +16815 0.087982177734375 +16816 0.13946533203125 +16817 0.17425537109375 +16818 0.188201904296875 +16819 0.171234130859375 +16820 0.118438720703125 +16821 0.05706787109375 +16822 -0.010711669921875 +16823 -0.0914306640625 +16824 -0.162322998046875 +16825 -0.194549560546875 +16826 -0.1492919921875 +16827 -0.02166748046875 +16828 0.124053955078125 +16829 0.211151123046875 +16830 0.240447998046875 +16831 0.242218017578125 +16832 0.2257080078125 +16833 0.194366455078125 +16834 0.115509033203125 +16835 0.0128173828125 +16836 -0.053802490234375 +16837 -0.110626220703125 +16838 -0.199493408203125 +16839 -0.29437255859375 +16840 -0.33221435546875 +16841 -0.27972412109375 +16842 -0.185333251953125 +16843 -0.128204345703125 +16844 -0.115692138671875 +16845 -0.116455078125 +16846 -0.105926513671875 +16847 -0.053955078125 +16848 0.048797607421875 +16849 0.157318115234375 +16850 0.212005615234375 +16851 0.218475341796875 +16852 0.23724365234375 +16853 0.30535888671875 +16854 0.38128662109375 +16855 0.404449462890625 +16856 0.3944091796875 +16857 0.3885498046875 +16858 0.362640380859375 +16859 0.27362060546875 +16860 0.11712646484375 +16861 -0.054901123046875 +16862 -0.19085693359375 +16863 -0.28570556640625 +16864 -0.339263916015625 +16865 -0.3775634765625 +16866 -0.445709228515625 +16867 -0.535064697265625 +16868 -0.629058837890625 +16869 -0.697601318359375 +16870 -0.70391845703125 +16871 -0.6424560546875 +16872 -0.491241455078125 +16873 -0.265716552734375 +16874 -0.023712158203125 +16875 0.201751708984375 +16876 0.375823974609375 +16877 0.485076904296875 +16878 0.56884765625 +16879 0.634765625 +16880 0.63763427734375 +16881 0.5660400390625 +16882 0.4720458984375 +16883 0.40692138671875 +16884 0.3778076171875 +16885 0.376953125 +16886 0.371978759765625 +16887 0.313140869140625 +16888 0.184417724609375 +16889 0.011199951171875 +16890 -0.171051025390625 +16891 -0.33740234375 +16892 -0.47198486328125 +16893 -0.560394287109375 +16894 -0.58056640625 +16895 -0.54754638671875 +16896 -0.508575439453125 +16897 -0.459503173828125 +16898 -0.394378662109375 +16899 -0.35260009765625 +16900 -0.31170654296875 +16901 -0.197418212890625 +16902 -0.007965087890625 +16903 0.207489013671875 +16904 0.409210205078125 +16905 0.57208251953125 +16906 0.66595458984375 +16907 0.65875244140625 +16908 0.56744384765625 +16909 0.431396484375 +16910 0.29443359375 +16911 0.182464599609375 +16912 0.06365966796875 +16913 -0.075958251953125 +16914 -0.189422607421875 +16915 -0.271942138671875 +16916 -0.342529296875 +16917 -0.364166259765625 +16918 -0.327239990234375 +16919 -0.2769775390625 +16920 -0.253692626953125 +16921 -0.24365234375 +16922 -0.1983642578125 +16923 -0.116241455078125 +16924 -0.036834716796875 +16925 0.034881591796875 +16926 0.09124755859375 +16927 0.10888671875 +16928 0.125518798828125 +16929 0.15771484375 +16930 0.17828369140625 +16931 0.17108154296875 +16932 0.129974365234375 +16933 0.082427978515625 +16934 0.027679443359375 +16935 -0.065643310546875 +16936 -0.15936279296875 +16937 -0.21307373046875 +16938 -0.234649658203125 +16939 -0.2001953125 +16940 -0.119171142578125 +16941 -0.024749755859375 +16942 0.085784912109375 +16943 0.178131103515625 +16944 0.215576171875 +16945 0.211456298828125 +16946 0.17523193359375 +16947 0.128753662109375 +16948 0.1019287109375 +16949 0.0743408203125 +16950 0.04327392578125 +16951 0.038177490234375 +16952 0.076263427734375 +16953 0.14105224609375 +16954 0.186431884765625 +16955 0.188812255859375 +16956 0.1390380859375 +16957 0.041778564453125 +16958 -0.079437255859375 +16959 -0.219390869140625 +16960 -0.367828369140625 +16961 -0.494873046875 +16962 -0.556243896484375 +16963 -0.508697509765625 +16964 -0.3756103515625 +16965 -0.218902587890625 +16966 -0.063751220703125 +16967 0.091552734375 +16968 0.23602294921875 +16969 0.342987060546875 +16970 0.39520263671875 +16971 0.389373779296875 +16972 0.324249267578125 +16973 0.224090576171875 +16974 0.124267578125 +16975 0.037078857421875 +16976 -0.010101318359375 +16977 -0.019439697265625 +16978 -0.022796630859375 +16979 -0.001556396484375 +16980 0.056304931640625 +16981 0.106719970703125 +16982 0.096893310546875 +16983 0.042694091796875 +16984 -0.018035888671875 +16985 -0.07586669921875 +16986 -0.11944580078125 +16987 -0.15972900390625 +16988 -0.202606201171875 +16989 -0.24859619140625 +16990 -0.30517578125 +16991 -0.36212158203125 +16992 -0.39141845703125 +16993 -0.35528564453125 +16994 -0.249969482421875 +16995 -0.092864990234375 +16996 0.08905029296875 +16997 0.2352294921875 +16998 0.318817138671875 +16999 0.358642578125 +17000 0.347747802734375 +17001 0.28564453125 +17002 0.223175048828125 +17003 0.196746826171875 +17004 0.179840087890625 +17005 0.155548095703125 +17006 0.151214599609375 +17007 0.156951904296875 +17008 0.13177490234375 +17009 0.100799560546875 +17010 0.087127685546875 +17011 0.05487060546875 +17012 -0.009002685546875 +17013 -0.10400390625 +17014 -0.229400634765625 +17015 -0.35552978515625 +17016 -0.441925048828125 +17017 -0.473846435546875 +17018 -0.464813232421875 +17019 -0.419097900390625 +17020 -0.334320068359375 +17021 -0.227935791015625 +17022 -0.12347412109375 +17023 -0.02764892578125 +17024 0.077667236328125 +17025 0.2132568359375 +17026 0.38885498046875 +17027 0.582794189453125 +17028 0.734039306640625 +17029 0.800140380859375 +17030 0.7783203125 +17031 0.6651611328125 +17032 0.45965576171875 +17033 0.199188232421875 +17034 -0.050689697265625 +17035 -0.23297119140625 +17036 -0.33013916015625 +17037 -0.368408203125 +17038 -0.378936767578125 +17039 -0.376983642578125 +17040 -0.37969970703125 +17041 -0.391510009765625 +17042 -0.385345458984375 +17043 -0.3419189453125 +17044 -0.28289794921875 +17045 -0.251617431640625 +17046 -0.266143798828125 +17047 -0.273345947265625 +17048 -0.216796875 +17049 -0.128265380859375 +17050 -0.068145751953125 +17051 -0.0430908203125 +17052 -0.024444580078125 +17053 0.020721435546875 +17054 0.124481201171875 +17055 0.25787353515625 +17056 0.379119873046875 +17057 0.47991943359375 +17058 0.5281982421875 +17059 0.511138916015625 +17060 0.456207275390625 +17061 0.407470703125 +17062 0.383758544921875 +17063 0.35687255859375 +17064 0.31182861328125 +17065 0.250885009765625 +17066 0.1654052734375 +17067 0.035247802734375 +17068 -0.142059326171875 +17069 -0.33563232421875 +17070 -0.5345458984375 +17071 -0.72186279296875 +17072 -0.836669921875 +17073 -0.8326416015625 +17074 -0.7296142578125 +17075 -0.582550048828125 +17076 -0.440093994140625 +17077 -0.324310302734375 +17078 -0.20147705078125 +17079 -0.044647216796875 +17080 0.103973388671875 +17081 0.202392578125 +17082 0.264495849609375 +17083 0.338897705078125 +17084 0.443817138671875 +17085 0.545074462890625 +17086 0.6173095703125 +17087 0.6524658203125 +17088 0.66339111328125 +17089 0.6561279296875 +17090 0.606781005859375 +17091 0.501190185546875 +17092 0.352783203125 +17093 0.176544189453125 +17094 -0.034820556640625 +17095 -0.258209228515625 +17096 -0.44244384765625 +17097 -0.5753173828125 +17098 -0.65203857421875 +17099 -0.641632080078125 +17100 -0.562164306640625 +17101 -0.458038330078125 +17102 -0.350555419921875 +17103 -0.260528564453125 +17104 -0.192108154296875 +17105 -0.141937255859375 +17106 -0.1021728515625 +17107 -0.062896728515625 +17108 -0.011932373046875 +17109 0.062835693359375 +17110 0.148712158203125 +17111 0.241729736328125 +17112 0.34912109375 +17113 0.457305908203125 +17114 0.54388427734375 +17115 0.5728759765625 +17116 0.506591796875 +17117 0.351226806640625 +17118 0.146514892578125 +17119 -0.05523681640625 +17120 -0.21624755859375 +17121 -0.334930419921875 +17122 -0.402984619140625 +17123 -0.4412841796875 +17124 -0.49578857421875 +17125 -0.5601806640625 +17126 -0.600738525390625 +17127 -0.584228515625 +17128 -0.47930908203125 +17129 -0.27935791015625 +17130 -0.0089111328125 +17131 0.268798828125 +17132 0.482818603515625 +17133 0.60369873046875 +17134 0.650421142578125 +17135 0.66400146484375 +17136 0.6414794921875 +17137 0.572540283203125 +17138 0.498138427734375 +17139 0.439453125 +17140 0.375518798828125 +17141 0.274505615234375 +17142 0.1087646484375 +17143 -0.099395751953125 +17144 -0.3182373046875 +17145 -0.5489501953125 +17146 -0.7738037109375 +17147 -0.86383056640625 +17148 -0.870391845703125 +17149 -0.86895751953125 +17150 -0.861053466796875 +17151 -0.765869140625 +17152 -0.5301513671875 +17153 -0.214691162109375 +17154 0.137359619140625 +17155 0.474822998046875 +17156 0.76239013671875 +17157 0.867462158203125 +17158 0.870361328125 +17159 0.86480712890625 +17160 0.831817626953125 +17161 0.677581787109375 +17162 0.495880126953125 +17163 0.30767822265625 +17164 0.116180419921875 +17165 -0.110748291015625 +17166 -0.381805419921875 +17167 -0.6572265625 +17168 -0.857421875 +17169 -0.870391845703125 +17170 -0.870391845703125 +17171 -0.86444091796875 +17172 -0.85723876953125 +17173 -0.790008544921875 +17174 -0.62847900390625 +17175 -0.3956298828125 +17176 -0.126708984375 +17177 0.150115966796875 +17178 0.424041748046875 +17179 0.670623779296875 +17180 0.854522705078125 +17181 0.866485595703125 +17182 0.86920166015625 +17183 0.8653564453125 +17184 0.857147216796875 +17185 0.766845703125 +17186 0.628509521484375 +17187 0.462127685546875 +17188 0.297210693359375 +17189 0.14862060546875 +17190 -0.00537109375 +17191 -0.15753173828125 +17192 -0.31304931640625 +17193 -0.48876953125 +17194 -0.6416015625 +17195 -0.751373291015625 +17196 -0.84619140625 +17197 -0.861297607421875 +17198 -0.863250732421875 +17199 -0.856597900390625 +17200 -0.7498779296875 +17201 -0.624542236328125 +17202 -0.47808837890625 +17203 -0.253387451171875 +17204 0.003692626953125 +17205 0.2257080078125 +17206 0.427154541015625 +17207 0.643218994140625 +17208 0.855926513671875 +17209 0.870361328125 +17210 0.870361328125 +17211 0.862762451171875 +17212 0.79669189453125 +17213 0.595794677734375 +17214 0.362152099609375 +17215 0.1270751953125 +17216 -0.086944580078125 +17217 -0.2784423828125 +17218 -0.484832763671875 +17219 -0.729583740234375 +17220 -0.86688232421875 +17221 -0.870391845703125 +17222 -0.86859130859375 +17223 -0.86279296875 +17224 -0.817962646484375 +17225 -0.6116943359375 +17226 -0.3128662109375 +17227 0.039398193359375 +17228 0.422821044921875 +17229 0.805145263671875 +17230 0.870361328125 +17231 0.870361328125 +17232 0.860015869140625 +17233 0.727935791015625 +17234 0.48114013671875 +17235 0.2059326171875 +17236 -0.06103515625 +17237 -0.29913330078125 +17238 -0.516204833984375 +17239 -0.7252197265625 +17240 -0.85980224609375 +17241 -0.870391845703125 +17242 -0.870391845703125 +17243 -0.858062744140625 +17244 -0.673004150390625 +17245 -0.42694091796875 +17246 -0.2100830078125 +17247 -0.0362548828125 +17248 0.10943603515625 +17249 0.23516845703125 +17250 0.373687744140625 +17251 0.517791748046875 +17252 0.602783203125 +17253 0.635711669921875 +17254 0.655181884765625 +17255 0.65948486328125 +17256 0.651275634765625 +17257 0.61846923828125 +17258 0.53753662109375 +17259 0.404144287109375 +17260 0.22186279296875 +17261 0.003997802734375 +17262 -0.22100830078125 +17263 -0.42449951171875 +17264 -0.579833984375 +17265 -0.641876220703125 +17266 -0.6177978515625 +17267 -0.575531005859375 +17268 -0.526336669921875 +17269 -0.42645263671875 +17270 -0.2581787109375 +17271 -0.068695068359375 +17272 0.09222412109375 +17273 0.232147216796875 +17274 0.3509521484375 +17275 0.410064697265625 +17276 0.372955322265625 +17277 0.2554931640625 +17278 0.10711669921875 +17279 -0.052886962890625 +17280 -0.186279296875 +17281 -0.23291015625 +17282 -0.209442138671875 +17283 -0.174163818359375 +17284 -0.126739501953125 +17285 -0.048126220703125 +17286 0.0426025390625 +17287 0.10748291015625 +17288 0.1409912109375 +17289 0.19708251953125 +17290 0.273651123046875 +17291 0.31768798828125 +17292 0.341094970703125 +17293 0.368011474609375 +17294 0.37249755859375 +17295 0.30072021484375 +17296 0.1517333984375 +17297 -0.01470947265625 +17298 -0.1883544921875 +17299 -0.372711181640625 +17300 -0.51397705078125 +17301 -0.57177734375 +17302 -0.53948974609375 +17303 -0.43511962890625 +17304 -0.2962646484375 +17305 -0.161102294921875 +17306 -0.0435791015625 +17307 0.060394287109375 +17308 0.13665771484375 +17309 0.170135498046875 +17310 0.16552734375 +17311 0.15728759765625 +17312 0.150787353515625 +17313 0.12200927734375 +17314 0.080108642578125 +17315 0.05126953125 +17316 0.062896728515625 +17317 0.09271240234375 +17318 0.092987060546875 +17319 0.07855224609375 +17320 0.06427001953125 +17321 0.0347900390625 +17322 -0.01171875 +17323 -0.056060791015625 +17324 -0.055511474609375 +17325 -0.010467529296875 +17326 0.02508544921875 +17327 0.025665283203125 +17328 0.017333984375 +17329 0.00189208984375 +17330 -0.03173828125 +17331 -0.071502685546875 +17332 -0.13543701171875 +17333 -0.219970703125 +17334 -0.300506591796875 +17335 -0.376312255859375 +17336 -0.416107177734375 +17337 -0.371124267578125 +17338 -0.242279052734375 +17339 -0.069732666015625 +17340 0.125640869140625 +17341 0.31268310546875 +17342 0.45501708984375 +17343 0.554779052734375 +17344 0.61065673828125 +17345 0.610931396484375 +17346 0.531463623046875 +17347 0.3883056640625 +17348 0.23468017578125 +17349 0.095245361328125 +17350 -0.00396728515625 +17351 -0.04852294921875 +17352 -0.055145263671875 +17353 -0.0758056640625 +17354 -0.138702392578125 +17355 -0.209197998046875 +17356 -0.289031982421875 +17357 -0.37884521484375 +17358 -0.456329345703125 +17359 -0.51641845703125 +17360 -0.519287109375 +17361 -0.458251953125 +17362 -0.384796142578125 +17363 -0.323699951171875 +17364 -0.269287109375 +17365 -0.1951904296875 +17366 -0.100006103515625 +17367 -0.01055908203125 +17368 0.1033935546875 +17369 0.24908447265625 +17370 0.373199462890625 +17371 0.45806884765625 +17372 0.511474609375 +17373 0.565399169921875 +17374 0.61138916015625 +17375 0.5897216796875 +17376 0.4906005859375 +17377 0.33148193359375 +17378 0.147796630859375 +17379 -0.01873779296875 +17380 -0.140289306640625 +17381 -0.191986083984375 +17382 -0.184295654296875 +17383 -0.161834716796875 +17384 -0.166595458984375 +17385 -0.19390869140625 +17386 -0.22442626953125 +17387 -0.279754638671875 +17388 -0.3389892578125 +17389 -0.3543701171875 +17390 -0.348175048828125 +17391 -0.32598876953125 +17392 -0.2581787109375 +17393 -0.139801025390625 +17394 0.014617919921875 +17395 0.144378662109375 +17396 0.221038818359375 +17397 0.27069091796875 +17398 0.294036865234375 +17399 0.311767578125 +17400 0.339141845703125 +17401 0.360260009765625 +17402 0.360504150390625 +17403 0.308380126953125 +17404 0.18170166015625 +17405 0.0047607421875 +17406 -0.17559814453125 +17407 -0.3143310546875 +17408 -0.36785888671875 +17409 -0.36248779296875 +17410 -0.343536376953125 +17411 -0.3018798828125 +17412 -0.231414794921875 +17413 -0.117645263671875 +17414 0.007049560546875 +17415 0.087982177734375 +17416 0.13946533203125 +17417 0.17425537109375 +17418 0.188201904296875 +17419 0.171234130859375 +17420 0.118438720703125 +17421 0.05706787109375 +17422 -0.010711669921875 +17423 -0.0914306640625 +17424 -0.162322998046875 +17425 -0.194549560546875 +17426 -0.1492919921875 +17427 -0.02166748046875 +17428 0.124053955078125 +17429 0.211151123046875 +17430 0.240447998046875 +17431 0.242218017578125 +17432 0.2257080078125 +17433 0.194366455078125 +17434 0.115509033203125 +17435 0.0128173828125 +17436 -0.053802490234375 +17437 -0.110626220703125 +17438 -0.199493408203125 +17439 -0.29437255859375 +17440 -0.33221435546875 +17441 -0.27972412109375 +17442 -0.185333251953125 +17443 -0.128204345703125 +17444 -0.115692138671875 +17445 -0.116455078125 +17446 -0.105926513671875 +17447 -0.053955078125 +17448 0.048797607421875 +17449 0.157318115234375 +17450 0.212005615234375 +17451 0.218475341796875 +17452 0.23724365234375 +17453 0.30535888671875 +17454 0.38128662109375 +17455 0.404449462890625 +17456 0.3944091796875 +17457 0.3885498046875 +17458 0.362640380859375 +17459 0.27362060546875 +17460 0.11712646484375 +17461 -0.054901123046875 +17462 -0.19085693359375 +17463 -0.28570556640625 +17464 -0.339263916015625 +17465 -0.3775634765625 +17466 -0.445709228515625 +17467 -0.535064697265625 +17468 -0.629058837890625 +17469 -0.697601318359375 +17470 -0.70391845703125 +17471 -0.6424560546875 +17472 -0.491241455078125 +17473 -0.265716552734375 +17474 -0.023712158203125 +17475 0.201751708984375 +17476 0.375823974609375 +17477 0.485076904296875 +17478 0.56884765625 +17479 0.634765625 +17480 0.63763427734375 +17481 0.5660400390625 +17482 0.4720458984375 +17483 0.40692138671875 +17484 0.3778076171875 +17485 0.376953125 +17486 0.371978759765625 +17487 0.313140869140625 +17488 0.184417724609375 +17489 0.011199951171875 +17490 -0.171051025390625 +17491 -0.33740234375 +17492 -0.47198486328125 +17493 -0.560394287109375 +17494 -0.58056640625 +17495 -0.54754638671875 +17496 -0.508575439453125 +17497 -0.459503173828125 +17498 -0.394378662109375 +17499 -0.35260009765625 +17500 -0.31170654296875 +17501 -0.197418212890625 +17502 -0.007965087890625 +17503 0.207489013671875 +17504 0.409210205078125 +17505 0.57208251953125 +17506 0.66595458984375 +17507 0.65875244140625 +17508 0.56744384765625 +17509 0.431396484375 +17510 0.29443359375 +17511 0.182464599609375 +17512 0.06365966796875 +17513 -0.075958251953125 +17514 -0.189422607421875 +17515 -0.271942138671875 +17516 -0.342529296875 +17517 -0.364166259765625 +17518 -0.327239990234375 +17519 -0.2769775390625 +17520 -0.253692626953125 +17521 -0.24365234375 +17522 -0.1983642578125 +17523 -0.116241455078125 +17524 -0.036834716796875 +17525 0.034881591796875 +17526 0.09124755859375 +17527 0.10888671875 +17528 0.125518798828125 +17529 0.15771484375 +17530 0.17828369140625 +17531 0.17108154296875 +17532 0.129974365234375 +17533 0.082427978515625 +17534 0.027679443359375 +17535 -0.065643310546875 +17536 -0.15936279296875 +17537 -0.21307373046875 +17538 -0.234649658203125 +17539 -0.2001953125 +17540 -0.119171142578125 +17541 -0.024749755859375 +17542 0.085784912109375 +17543 0.178131103515625 +17544 0.215576171875 +17545 0.211456298828125 +17546 0.17523193359375 +17547 0.128753662109375 +17548 0.1019287109375 +17549 0.0743408203125 +17550 0.04327392578125 +17551 0.038177490234375 +17552 0.076263427734375 +17553 0.14105224609375 +17554 0.186431884765625 +17555 0.188812255859375 +17556 0.1390380859375 +17557 0.041778564453125 +17558 -0.079437255859375 +17559 -0.219390869140625 +17560 -0.367828369140625 +17561 -0.494873046875 +17562 -0.556243896484375 +17563 -0.508697509765625 +17564 -0.3756103515625 +17565 -0.218902587890625 +17566 -0.063751220703125 +17567 0.091552734375 +17568 0.23602294921875 +17569 0.342987060546875 +17570 0.39520263671875 +17571 0.389373779296875 +17572 0.324249267578125 +17573 0.224090576171875 +17574 0.124267578125 +17575 0.037078857421875 +17576 -0.010101318359375 +17577 -0.019439697265625 +17578 -0.022796630859375 +17579 -0.001556396484375 +17580 0.056304931640625 +17581 0.106719970703125 +17582 0.096893310546875 +17583 0.042694091796875 +17584 -0.018035888671875 +17585 -0.07586669921875 +17586 -0.11944580078125 +17587 -0.15972900390625 +17588 -0.202606201171875 +17589 -0.24859619140625 +17590 -0.30517578125 +17591 -0.36212158203125 +17592 -0.39141845703125 +17593 -0.35528564453125 +17594 -0.249969482421875 +17595 -0.092864990234375 +17596 0.08905029296875 +17597 0.2352294921875 +17598 0.318817138671875 +17599 0.358642578125 +17600 0.347747802734375 +17601 0.28564453125 +17602 0.223175048828125 +17603 0.196746826171875 +17604 0.179840087890625 +17605 0.155548095703125 +17606 0.151214599609375 +17607 0.156951904296875 +17608 0.13177490234375 +17609 0.100799560546875 +17610 0.087127685546875 +17611 0.05487060546875 +17612 -0.009002685546875 +17613 -0.10400390625 +17614 -0.229400634765625 +17615 -0.35552978515625 +17616 -0.441925048828125 +17617 -0.473846435546875 +17618 -0.464813232421875 +17619 -0.419097900390625 +17620 -0.334320068359375 +17621 -0.227935791015625 +17622 -0.12347412109375 +17623 -0.02764892578125 +17624 0.077667236328125 +17625 0.2132568359375 +17626 0.38885498046875 +17627 0.582794189453125 +17628 0.734039306640625 +17629 0.800140380859375 +17630 0.7783203125 +17631 0.6651611328125 +17632 0.45965576171875 +17633 0.199188232421875 +17634 -0.050689697265625 +17635 -0.23297119140625 +17636 -0.33013916015625 +17637 -0.368408203125 +17638 -0.378936767578125 +17639 -0.376983642578125 +17640 -0.37969970703125 +17641 -0.391510009765625 +17642 -0.385345458984375 +17643 -0.3419189453125 +17644 -0.28289794921875 +17645 -0.251617431640625 +17646 -0.266143798828125 +17647 -0.273345947265625 +17648 -0.216796875 +17649 -0.128265380859375 +17650 -0.068145751953125 +17651 -0.0430908203125 +17652 -0.024444580078125 +17653 0.020721435546875 +17654 0.124481201171875 +17655 0.25787353515625 +17656 0.379119873046875 +17657 0.47991943359375 +17658 0.5281982421875 +17659 0.511138916015625 +17660 0.456207275390625 +17661 0.407470703125 +17662 0.383758544921875 +17663 0.35687255859375 +17664 0.31182861328125 +17665 0.250885009765625 +17666 0.1654052734375 +17667 0.035247802734375 +17668 -0.142059326171875 +17669 -0.33563232421875 +17670 -0.5345458984375 +17671 -0.72186279296875 +17672 -0.836669921875 +17673 -0.8326416015625 +17674 -0.7296142578125 +17675 -0.582550048828125 +17676 -0.440093994140625 +17677 -0.324310302734375 +17678 -0.20147705078125 +17679 -0.044647216796875 +17680 0.103973388671875 +17681 0.202392578125 +17682 0.264495849609375 +17683 0.338897705078125 +17684 0.443817138671875 +17685 0.545074462890625 +17686 0.6173095703125 +17687 0.6524658203125 +17688 0.66339111328125 +17689 0.6561279296875 +17690 0.606781005859375 +17691 0.501190185546875 +17692 0.352783203125 +17693 0.176544189453125 +17694 -0.034820556640625 +17695 -0.258209228515625 +17696 -0.44244384765625 +17697 -0.5753173828125 +17698 -0.65203857421875 +17699 -0.641632080078125 +17700 -0.562164306640625 +17701 -0.458038330078125 +17702 -0.350555419921875 +17703 -0.260528564453125 +17704 -0.192108154296875 +17705 -0.141937255859375 +17706 -0.1021728515625 +17707 -0.062896728515625 +17708 -0.011932373046875 +17709 0.062835693359375 +17710 0.148712158203125 +17711 0.241729736328125 +17712 0.34912109375 +17713 0.457305908203125 +17714 0.54388427734375 +17715 0.5728759765625 +17716 0.506591796875 +17717 0.351226806640625 +17718 0.146514892578125 +17719 -0.05523681640625 +17720 -0.21624755859375 +17721 -0.334930419921875 +17722 -0.402984619140625 +17723 -0.4412841796875 +17724 -0.49578857421875 +17725 -0.5601806640625 +17726 -0.600738525390625 +17727 -0.584228515625 +17728 -0.47930908203125 +17729 -0.27935791015625 +17730 -0.0089111328125 +17731 0.268798828125 +17732 0.482818603515625 +17733 0.60369873046875 +17734 0.650421142578125 +17735 0.66400146484375 +17736 0.6414794921875 +17737 0.572540283203125 +17738 0.498138427734375 +17739 0.439453125 +17740 0.375518798828125 +17741 0.274505615234375 +17742 0.1087646484375 +17743 -0.099395751953125 +17744 -0.3182373046875 +17745 -0.5489501953125 +17746 -0.7738037109375 +17747 -0.86383056640625 +17748 -0.870391845703125 +17749 -0.86895751953125 +17750 -0.861053466796875 +17751 -0.765869140625 +17752 -0.5301513671875 +17753 -0.214691162109375 +17754 0.137359619140625 +17755 0.474822998046875 +17756 0.76239013671875 +17757 0.867462158203125 +17758 0.870361328125 +17759 0.86480712890625 +17760 0.831817626953125 +17761 0.677581787109375 +17762 0.495880126953125 +17763 0.30767822265625 +17764 0.116180419921875 +17765 -0.110748291015625 +17766 -0.381805419921875 +17767 -0.6572265625 +17768 -0.857421875 +17769 -0.870391845703125 +17770 -0.870391845703125 +17771 -0.86444091796875 +17772 -0.85723876953125 +17773 -0.790008544921875 +17774 -0.62847900390625 +17775 -0.3956298828125 +17776 -0.126708984375 +17777 0.150115966796875 +17778 0.424041748046875 +17779 0.670623779296875 +17780 0.854522705078125 +17781 0.866485595703125 +17782 0.86920166015625 +17783 0.8653564453125 +17784 0.857147216796875 +17785 0.766845703125 +17786 0.628509521484375 +17787 0.462127685546875 +17788 0.297210693359375 +17789 0.14862060546875 +17790 -0.00537109375 +17791 -0.15753173828125 +17792 -0.31304931640625 +17793 -0.48876953125 +17794 -0.6416015625 +17795 -0.751373291015625 +17796 -0.84619140625 +17797 -0.861297607421875 +17798 -0.863250732421875 +17799 -0.856597900390625 +17800 -0.7498779296875 +17801 -0.624542236328125 +17802 -0.47808837890625 +17803 -0.253387451171875 +17804 0.003692626953125 +17805 0.2257080078125 +17806 0.427154541015625 +17807 0.643218994140625 +17808 0.855926513671875 +17809 0.870361328125 +17810 0.870361328125 +17811 0.862762451171875 +17812 0.79669189453125 +17813 0.595794677734375 +17814 0.362152099609375 +17815 0.1270751953125 +17816 -0.086944580078125 +17817 -0.2784423828125 +17818 -0.484832763671875 +17819 -0.729583740234375 +17820 -0.86688232421875 +17821 -0.870391845703125 +17822 -0.86859130859375 +17823 -0.86279296875 +17824 -0.817962646484375 +17825 -0.6116943359375 +17826 -0.3128662109375 +17827 0.039398193359375 +17828 0.422821044921875 +17829 0.805145263671875 +17830 0.870361328125 +17831 0.870361328125 +17832 0.860015869140625 +17833 0.727935791015625 +17834 0.48114013671875 +17835 0.2059326171875 +17836 -0.06103515625 +17837 -0.29913330078125 +17838 -0.516204833984375 +17839 -0.7252197265625 +17840 -0.85980224609375 +17841 -0.870391845703125 +17842 -0.870391845703125 +17843 -0.858062744140625 +17844 -0.673004150390625 +17845 -0.42694091796875 +17846 -0.2100830078125 +17847 -0.0362548828125 +17848 0.10943603515625 +17849 0.23516845703125 +17850 0.373687744140625 +17851 0.517791748046875 +17852 0.602783203125 +17853 0.635711669921875 +17854 0.655181884765625 +17855 0.65948486328125 +17856 0.651275634765625 +17857 0.61846923828125 +17858 0.53753662109375 +17859 0.404144287109375 +17860 0.22186279296875 +17861 0.003997802734375 +17862 -0.22100830078125 +17863 -0.42449951171875 +17864 -0.579833984375 +17865 -0.641876220703125 +17866 -0.6177978515625 +17867 -0.575531005859375 +17868 -0.526336669921875 +17869 -0.42645263671875 +17870 -0.2581787109375 +17871 -0.068695068359375 +17872 0.09222412109375 +17873 0.232147216796875 +17874 0.3509521484375 +17875 0.410064697265625 +17876 0.372955322265625 +17877 0.2554931640625 +17878 0.10711669921875 +17879 -0.052886962890625 +17880 -0.186279296875 +17881 -0.23291015625 +17882 -0.209442138671875 +17883 -0.174163818359375 +17884 -0.126739501953125 +17885 -0.048126220703125 +17886 0.0426025390625 +17887 0.10748291015625 +17888 0.1409912109375 +17889 0.19708251953125 +17890 0.273651123046875 +17891 0.31768798828125 +17892 0.341094970703125 +17893 0.368011474609375 +17894 0.37249755859375 +17895 0.30072021484375 +17896 0.1517333984375 +17897 -0.01470947265625 +17898 -0.1883544921875 +17899 -0.372711181640625 +17900 -0.51397705078125 +17901 -0.57177734375 +17902 -0.53948974609375 +17903 -0.43511962890625 +17904 -0.2962646484375 +17905 -0.161102294921875 +17906 -0.0435791015625 +17907 0.060394287109375 +17908 0.13665771484375 +17909 0.170135498046875 +17910 0.16552734375 +17911 0.15728759765625 +17912 0.150787353515625 +17913 0.12200927734375 +17914 0.080108642578125 +17915 0.05126953125 +17916 0.062896728515625 +17917 0.09271240234375 +17918 0.092987060546875 +17919 0.07855224609375 +17920 0.06427001953125 +17921 0.0347900390625 +17922 -0.01171875 +17923 -0.056060791015625 +17924 -0.055511474609375 +17925 -0.010467529296875 +17926 0.02508544921875 +17927 0.025665283203125 +17928 0.017333984375 +17929 0.00189208984375 +17930 -0.03173828125 +17931 -0.071502685546875 +17932 -0.13543701171875 +17933 -0.219970703125 +17934 -0.300506591796875 +17935 -0.376312255859375 +17936 -0.416107177734375 +17937 -0.371124267578125 +17938 -0.242279052734375 +17939 -0.069732666015625 +17940 0.125640869140625 +17941 0.31268310546875 +17942 0.45501708984375 +17943 0.554779052734375 +17944 0.61065673828125 +17945 0.610931396484375 +17946 0.531463623046875 +17947 0.3883056640625 +17948 0.23468017578125 +17949 0.095245361328125 +17950 -0.00396728515625 +17951 -0.04852294921875 +17952 -0.055145263671875 +17953 -0.0758056640625 +17954 -0.138702392578125 +17955 -0.209197998046875 +17956 -0.289031982421875 +17957 -0.37884521484375 +17958 -0.456329345703125 +17959 -0.51641845703125 +17960 -0.519287109375 +17961 -0.458251953125 +17962 -0.384796142578125 +17963 -0.323699951171875 +17964 -0.269287109375 +17965 -0.1951904296875 +17966 -0.100006103515625 +17967 -0.01055908203125 +17968 0.1033935546875 +17969 0.24908447265625 +17970 0.373199462890625 +17971 0.45806884765625 +17972 0.511474609375 +17973 0.565399169921875 +17974 0.61138916015625 +17975 0.5897216796875 +17976 0.4906005859375 +17977 0.33148193359375 +17978 0.147796630859375 +17979 -0.01873779296875 +17980 -0.140289306640625 +17981 -0.191986083984375 +17982 -0.184295654296875 +17983 -0.161834716796875 +17984 -0.166595458984375 +17985 -0.19390869140625 +17986 -0.22442626953125 +17987 -0.279754638671875 +17988 -0.3389892578125 +17989 -0.3543701171875 +17990 -0.348175048828125 +17991 -0.32598876953125 +17992 -0.2581787109375 +17993 -0.139801025390625 +17994 0.014617919921875 +17995 0.144378662109375 +17996 0.221038818359375 +17997 0.27069091796875 +17998 0.294036865234375 +17999 0.311767578125 +18000 0.339141845703125 +18001 0.360260009765625 +18002 0.360504150390625 +18003 0.308380126953125 +18004 0.18170166015625 +18005 0.0047607421875 +18006 -0.17559814453125 +18007 -0.3143310546875 +18008 -0.36785888671875 +18009 -0.36248779296875 +18010 -0.343536376953125 +18011 -0.3018798828125 +18012 -0.231414794921875 +18013 -0.117645263671875 +18014 0.007049560546875 +18015 0.087982177734375 +18016 0.13946533203125 +18017 0.17425537109375 +18018 0.188201904296875 +18019 0.171234130859375 +18020 0.118438720703125 +18021 0.05706787109375 +18022 -0.010711669921875 +18023 -0.0914306640625 +18024 -0.162322998046875 +18025 -0.194549560546875 +18026 -0.1492919921875 +18027 -0.02166748046875 +18028 0.124053955078125 +18029 0.211151123046875 +18030 0.240447998046875 +18031 0.242218017578125 +18032 0.2257080078125 +18033 0.194366455078125 +18034 0.115509033203125 +18035 0.0128173828125 +18036 -0.053802490234375 +18037 -0.110626220703125 +18038 -0.199493408203125 +18039 -0.29437255859375 +18040 -0.33221435546875 +18041 -0.27972412109375 +18042 -0.185333251953125 +18043 -0.128204345703125 +18044 -0.115692138671875 +18045 -0.116455078125 +18046 -0.105926513671875 +18047 -0.053955078125 +18048 0.048797607421875 +18049 0.157318115234375 +18050 0.212005615234375 +18051 0.218475341796875 +18052 0.23724365234375 +18053 0.30535888671875 +18054 0.38128662109375 +18055 0.404449462890625 +18056 0.3944091796875 +18057 0.3885498046875 +18058 0.362640380859375 +18059 0.27362060546875 +18060 0.11712646484375 +18061 -0.054901123046875 +18062 -0.19085693359375 +18063 -0.28570556640625 +18064 -0.339263916015625 +18065 -0.3775634765625 +18066 -0.445709228515625 +18067 -0.535064697265625 +18068 -0.629058837890625 +18069 -0.697601318359375 +18070 -0.70391845703125 +18071 -0.6424560546875 +18072 -0.491241455078125 +18073 -0.265716552734375 +18074 -0.023712158203125 +18075 0.201751708984375 +18076 0.375823974609375 +18077 0.485076904296875 +18078 0.56884765625 +18079 0.634765625 +18080 0.63763427734375 +18081 0.5660400390625 +18082 0.4720458984375 +18083 0.40692138671875 +18084 0.3778076171875 +18085 0.376953125 +18086 0.371978759765625 +18087 0.313140869140625 +18088 0.184417724609375 +18089 0.011199951171875 +18090 -0.171051025390625 +18091 -0.33740234375 +18092 -0.47198486328125 +18093 -0.560394287109375 +18094 -0.58056640625 +18095 -0.54754638671875 +18096 -0.508575439453125 +18097 -0.459503173828125 +18098 -0.394378662109375 +18099 -0.35260009765625 +18100 -0.31170654296875 +18101 -0.197418212890625 +18102 -0.007965087890625 +18103 0.207489013671875 +18104 0.409210205078125 +18105 0.57208251953125 +18106 0.66595458984375 +18107 0.65875244140625 +18108 0.56744384765625 +18109 0.431396484375 +18110 0.29443359375 +18111 0.182464599609375 +18112 0.06365966796875 +18113 -0.075958251953125 +18114 -0.189422607421875 +18115 -0.271942138671875 +18116 -0.342529296875 +18117 -0.364166259765625 +18118 -0.327239990234375 +18119 -0.2769775390625 +18120 -0.253692626953125 +18121 -0.24365234375 +18122 -0.1983642578125 +18123 -0.116241455078125 +18124 -0.036834716796875 +18125 0.034881591796875 +18126 0.09124755859375 +18127 0.10888671875 +18128 0.125518798828125 +18129 0.15771484375 +18130 0.17828369140625 +18131 0.17108154296875 +18132 0.129974365234375 +18133 0.082427978515625 +18134 0.027679443359375 +18135 -0.065643310546875 +18136 -0.15936279296875 +18137 -0.21307373046875 +18138 -0.234649658203125 +18139 -0.2001953125 +18140 -0.119171142578125 +18141 -0.024749755859375 +18142 0.085784912109375 +18143 0.178131103515625 +18144 0.215576171875 +18145 0.211456298828125 +18146 0.17523193359375 +18147 0.128753662109375 +18148 0.1019287109375 +18149 0.0743408203125 +18150 0.04327392578125 +18151 0.038177490234375 +18152 0.076263427734375 +18153 0.14105224609375 +18154 0.186431884765625 +18155 0.188812255859375 +18156 0.1390380859375 +18157 0.041778564453125 +18158 -0.079437255859375 +18159 -0.219390869140625 +18160 -0.367828369140625 +18161 -0.494873046875 +18162 -0.556243896484375 +18163 -0.508697509765625 +18164 -0.3756103515625 +18165 -0.218902587890625 +18166 -0.063751220703125 +18167 0.091552734375 +18168 0.23602294921875 +18169 0.342987060546875 +18170 0.39520263671875 +18171 0.389373779296875 +18172 0.324249267578125 +18173 0.224090576171875 +18174 0.124267578125 +18175 0.037078857421875 +18176 -0.010101318359375 +18177 -0.019439697265625 +18178 -0.022796630859375 +18179 -0.001556396484375 +18180 0.056304931640625 +18181 0.106719970703125 +18182 0.096893310546875 +18183 0.042694091796875 +18184 -0.018035888671875 +18185 -0.07586669921875 +18186 -0.11944580078125 +18187 -0.15972900390625 +18188 -0.202606201171875 +18189 -0.24859619140625 +18190 -0.30517578125 +18191 -0.36212158203125 +18192 -0.39141845703125 +18193 -0.35528564453125 +18194 -0.249969482421875 +18195 -0.092864990234375 +18196 0.08905029296875 +18197 0.2352294921875 +18198 0.318817138671875 +18199 0.358642578125 +18200 0.347747802734375 +18201 0.28564453125 +18202 0.223175048828125 +18203 0.196746826171875 +18204 0.179840087890625 +18205 0.155548095703125 +18206 0.151214599609375 +18207 0.156951904296875 +18208 0.13177490234375 +18209 0.100799560546875 +18210 0.087127685546875 +18211 0.05487060546875 +18212 -0.009002685546875 +18213 -0.10400390625 +18214 -0.229400634765625 +18215 -0.35552978515625 +18216 -0.441925048828125 +18217 -0.473846435546875 +18218 -0.464813232421875 +18219 -0.419097900390625 +18220 -0.334320068359375 +18221 -0.227935791015625 +18222 -0.12347412109375 +18223 -0.02764892578125 +18224 0.077667236328125 +18225 0.2132568359375 +18226 0.38885498046875 +18227 0.582794189453125 +18228 0.734039306640625 +18229 0.800140380859375 +18230 0.7783203125 +18231 0.6651611328125 +18232 0.45965576171875 +18233 0.199188232421875 +18234 -0.050689697265625 +18235 -0.23297119140625 +18236 -0.33013916015625 +18237 -0.368408203125 +18238 -0.378936767578125 +18239 -0.376983642578125 +18240 -0.37969970703125 +18241 -0.391510009765625 +18242 -0.385345458984375 +18243 -0.3419189453125 +18244 -0.28289794921875 +18245 -0.251617431640625 +18246 -0.266143798828125 +18247 -0.273345947265625 +18248 -0.216796875 +18249 -0.128265380859375 +18250 -0.068145751953125 +18251 -0.0430908203125 +18252 -0.024444580078125 +18253 0.020721435546875 +18254 0.124481201171875 +18255 0.25787353515625 +18256 0.379119873046875 +18257 0.47991943359375 +18258 0.5281982421875 +18259 0.511138916015625 +18260 0.456207275390625 +18261 0.407470703125 +18262 0.383758544921875 +18263 0.35687255859375 +18264 0.31182861328125 +18265 0.250885009765625 +18266 0.1654052734375 +18267 0.035247802734375 +18268 -0.142059326171875 +18269 -0.33563232421875 +18270 -0.5345458984375 +18271 -0.72186279296875 +18272 -0.836669921875 +18273 -0.8326416015625 +18274 -0.7296142578125 +18275 -0.582550048828125 +18276 -0.440093994140625 +18277 -0.324310302734375 +18278 -0.20147705078125 +18279 -0.044647216796875 +18280 0.103973388671875 +18281 0.202392578125 +18282 0.264495849609375 +18283 0.338897705078125 +18284 0.443817138671875 +18285 0.545074462890625 +18286 0.6173095703125 +18287 0.6524658203125 +18288 0.66339111328125 +18289 0.6561279296875 +18290 0.606781005859375 +18291 0.501190185546875 +18292 0.352783203125 +18293 0.176544189453125 +18294 -0.034820556640625 +18295 -0.258209228515625 +18296 -0.44244384765625 +18297 -0.5753173828125 +18298 -0.65203857421875 +18299 -0.641632080078125 +18300 -0.562164306640625 +18301 -0.458038330078125 +18302 -0.350555419921875 +18303 -0.260528564453125 +18304 -0.192108154296875 +18305 -0.141937255859375 +18306 -0.1021728515625 +18307 -0.062896728515625 +18308 -0.011932373046875 +18309 0.062835693359375 +18310 0.148712158203125 +18311 0.241729736328125 +18312 0.34912109375 +18313 0.457305908203125 +18314 0.54388427734375 +18315 0.5728759765625 +18316 0.506591796875 +18317 0.351226806640625 +18318 0.146514892578125 +18319 -0.05523681640625 +18320 -0.21624755859375 +18321 -0.334930419921875 +18322 -0.402984619140625 +18323 -0.4412841796875 +18324 -0.49578857421875 +18325 -0.5601806640625 +18326 -0.600738525390625 +18327 -0.584228515625 +18328 -0.47930908203125 +18329 -0.27935791015625 +18330 -0.0089111328125 +18331 0.268798828125 +18332 0.482818603515625 +18333 0.60369873046875 +18334 0.650421142578125 +18335 0.66400146484375 +18336 0.6414794921875 +18337 0.572540283203125 +18338 0.498138427734375 +18339 0.439453125 +18340 0.375518798828125 +18341 0.274505615234375 +18342 0.1087646484375 +18343 -0.099395751953125 +18344 -0.3182373046875 +18345 -0.5489501953125 +18346 -0.7738037109375 +18347 -0.86383056640625 +18348 -0.870391845703125 +18349 -0.86895751953125 +18350 -0.861053466796875 +18351 -0.765869140625 +18352 -0.5301513671875 +18353 -0.214691162109375 +18354 0.137359619140625 +18355 0.474822998046875 +18356 0.76239013671875 +18357 0.867462158203125 +18358 0.870361328125 +18359 0.86480712890625 +18360 0.831817626953125 +18361 0.677581787109375 +18362 0.495880126953125 +18363 0.30767822265625 +18364 0.116180419921875 +18365 -0.110748291015625 +18366 -0.381805419921875 +18367 -0.6572265625 +18368 -0.857421875 +18369 -0.870391845703125 +18370 -0.870391845703125 +18371 -0.86444091796875 +18372 -0.85723876953125 +18373 -0.790008544921875 +18374 -0.62847900390625 +18375 -0.3956298828125 +18376 -0.126708984375 +18377 0.150115966796875 +18378 0.424041748046875 +18379 0.670623779296875 +18380 0.854522705078125 +18381 0.866485595703125 +18382 0.86920166015625 +18383 0.8653564453125 +18384 0.857147216796875 +18385 0.766845703125 +18386 0.628509521484375 +18387 0.462127685546875 +18388 0.297210693359375 +18389 0.14862060546875 +18390 -0.00537109375 +18391 -0.15753173828125 +18392 -0.31304931640625 +18393 -0.48876953125 +18394 -0.6416015625 +18395 -0.751373291015625 +18396 -0.84619140625 +18397 -0.861297607421875 +18398 -0.863250732421875 +18399 -0.856597900390625 +18400 -0.7498779296875 +18401 -0.624542236328125 +18402 -0.47808837890625 +18403 -0.253387451171875 +18404 0.003692626953125 +18405 0.2257080078125 +18406 0.427154541015625 +18407 0.643218994140625 +18408 0.855926513671875 +18409 0.870361328125 +18410 0.870361328125 +18411 0.862762451171875 +18412 0.79669189453125 +18413 0.595794677734375 +18414 0.362152099609375 +18415 0.1270751953125 +18416 -0.086944580078125 +18417 -0.2784423828125 +18418 -0.484832763671875 +18419 -0.729583740234375 +18420 -0.86688232421875 +18421 -0.870391845703125 +18422 -0.86859130859375 +18423 -0.86279296875 +18424 -0.817962646484375 +18425 -0.6116943359375 +18426 -0.3128662109375 +18427 0.039398193359375 +18428 0.422821044921875 +18429 0.805145263671875 +18430 0.870361328125 +18431 0.870361328125 +18432 0.860015869140625 +18433 0.727935791015625 +18434 0.48114013671875 +18435 0.2059326171875 +18436 -0.06103515625 +18437 -0.29913330078125 +18438 -0.516204833984375 +18439 -0.7252197265625 +18440 -0.85980224609375 +18441 -0.870391845703125 +18442 -0.870391845703125 +18443 -0.858062744140625 +18444 -0.673004150390625 +18445 -0.42694091796875 +18446 -0.2100830078125 +18447 -0.0362548828125 +18448 0.10943603515625 +18449 0.23516845703125 +18450 0.373687744140625 +18451 0.517791748046875 +18452 0.602783203125 +18453 0.635711669921875 +18454 0.655181884765625 +18455 0.65948486328125 +18456 0.651275634765625 +18457 0.61846923828125 +18458 0.53753662109375 +18459 0.404144287109375 +18460 0.22186279296875 +18461 0.003997802734375 +18462 -0.22100830078125 +18463 -0.42449951171875 +18464 -0.579833984375 +18465 -0.641876220703125 +18466 -0.6177978515625 +18467 -0.575531005859375 +18468 -0.526336669921875 +18469 -0.42645263671875 +18470 -0.2581787109375 +18471 -0.068695068359375 +18472 0.09222412109375 +18473 0.232147216796875 +18474 0.3509521484375 +18475 0.410064697265625 +18476 0.372955322265625 +18477 0.2554931640625 +18478 0.10711669921875 +18479 -0.052886962890625 +18480 -0.186279296875 +18481 -0.23291015625 +18482 -0.209442138671875 +18483 -0.174163818359375 +18484 -0.126739501953125 +18485 -0.048126220703125 +18486 0.0426025390625 +18487 0.10748291015625 +18488 0.1409912109375 +18489 0.19708251953125 +18490 0.273651123046875 +18491 0.31768798828125 +18492 0.341094970703125 +18493 0.368011474609375 +18494 0.37249755859375 +18495 0.30072021484375 +18496 0.1517333984375 +18497 -0.01470947265625 +18498 -0.1883544921875 +18499 -0.372711181640625 +18500 -0.51397705078125 +18501 -0.57177734375 +18502 -0.53948974609375 +18503 -0.43511962890625 +18504 -0.2962646484375 +18505 -0.161102294921875 +18506 -0.0435791015625 +18507 0.060394287109375 +18508 0.13665771484375 +18509 0.170135498046875 +18510 0.16552734375 +18511 0.15728759765625 +18512 0.150787353515625 +18513 0.12200927734375 +18514 0.080108642578125 +18515 0.05126953125 +18516 0.062896728515625 +18517 0.09271240234375 +18518 0.092987060546875 +18519 0.07855224609375 +18520 0.06427001953125 +18521 0.0347900390625 +18522 -0.01171875 +18523 -0.056060791015625 +18524 -0.055511474609375 +18525 -0.010467529296875 +18526 0.02508544921875 +18527 0.025665283203125 +18528 0.017333984375 +18529 0.00189208984375 +18530 -0.03173828125 +18531 -0.071502685546875 +18532 -0.13543701171875 +18533 -0.219970703125 +18534 -0.300506591796875 +18535 -0.376312255859375 +18536 -0.416107177734375 +18537 -0.371124267578125 +18538 -0.242279052734375 +18539 -0.069732666015625 +18540 0.125640869140625 +18541 0.31268310546875 +18542 0.45501708984375 +18543 0.554779052734375 +18544 0.61065673828125 +18545 0.610931396484375 +18546 0.531463623046875 +18547 0.3883056640625 +18548 0.23468017578125 +18549 0.095245361328125 +18550 -0.00396728515625 +18551 -0.04852294921875 +18552 -0.055145263671875 +18553 -0.0758056640625 +18554 -0.138702392578125 +18555 -0.209197998046875 +18556 -0.289031982421875 +18557 -0.37884521484375 +18558 -0.456329345703125 +18559 -0.51641845703125 +18560 -0.519287109375 +18561 -0.458251953125 +18562 -0.384796142578125 +18563 -0.323699951171875 +18564 -0.269287109375 +18565 -0.1951904296875 +18566 -0.100006103515625 +18567 -0.01055908203125 +18568 0.1033935546875 +18569 0.24908447265625 +18570 0.373199462890625 +18571 0.45806884765625 +18572 0.511474609375 +18573 0.565399169921875 +18574 0.61138916015625 +18575 0.5897216796875 +18576 0.4906005859375 +18577 0.33148193359375 +18578 0.147796630859375 +18579 -0.01873779296875 +18580 -0.140289306640625 +18581 -0.191986083984375 +18582 -0.184295654296875 +18583 -0.161834716796875 +18584 -0.166595458984375 +18585 -0.19390869140625 +18586 -0.22442626953125 +18587 -0.279754638671875 +18588 -0.3389892578125 +18589 -0.3543701171875 +18590 -0.348175048828125 +18591 -0.32598876953125 +18592 -0.2581787109375 +18593 -0.139801025390625 +18594 0.014617919921875 +18595 0.144378662109375 +18596 0.221038818359375 +18597 0.27069091796875 +18598 0.294036865234375 +18599 0.311767578125 +18600 0.339141845703125 +18601 0.360260009765625 +18602 0.360504150390625 +18603 0.308380126953125 +18604 0.18170166015625 +18605 0.0047607421875 +18606 -0.17559814453125 +18607 -0.3143310546875 +18608 -0.36785888671875 +18609 -0.36248779296875 +18610 -0.343536376953125 +18611 -0.3018798828125 +18612 -0.231414794921875 +18613 -0.117645263671875 +18614 0.007049560546875 +18615 0.087982177734375 +18616 0.13946533203125 +18617 0.17425537109375 +18618 0.188201904296875 +18619 0.171234130859375 +18620 0.118438720703125 +18621 0.05706787109375 +18622 -0.010711669921875 +18623 -0.0914306640625 +18624 -0.162322998046875 +18625 -0.194549560546875 +18626 -0.1492919921875 +18627 -0.02166748046875 +18628 0.124053955078125 +18629 0.211151123046875 +18630 0.240447998046875 +18631 0.242218017578125 +18632 0.2257080078125 +18633 0.194366455078125 +18634 0.115509033203125 +18635 0.0128173828125 +18636 -0.053802490234375 +18637 -0.110626220703125 +18638 -0.199493408203125 +18639 -0.29437255859375 +18640 -0.33221435546875 +18641 -0.27972412109375 +18642 -0.185333251953125 +18643 -0.128204345703125 +18644 -0.115692138671875 +18645 -0.116455078125 +18646 -0.105926513671875 +18647 -0.053955078125 +18648 0.048797607421875 +18649 0.157318115234375 +18650 0.212005615234375 +18651 0.218475341796875 +18652 0.23724365234375 +18653 0.30535888671875 +18654 0.38128662109375 +18655 0.404449462890625 +18656 0.3944091796875 +18657 0.3885498046875 +18658 0.362640380859375 +18659 0.27362060546875 +18660 0.11712646484375 +18661 -0.054901123046875 +18662 -0.19085693359375 +18663 -0.28570556640625 +18664 -0.339263916015625 +18665 -0.3775634765625 +18666 -0.445709228515625 +18667 -0.535064697265625 +18668 -0.629058837890625 +18669 -0.697601318359375 +18670 -0.70391845703125 +18671 -0.6424560546875 +18672 -0.491241455078125 +18673 -0.265716552734375 +18674 -0.023712158203125 +18675 0.201751708984375 +18676 0.375823974609375 +18677 0.485076904296875 +18678 0.56884765625 +18679 0.634765625 +18680 0.63763427734375 +18681 0.5660400390625 +18682 0.4720458984375 +18683 0.40692138671875 +18684 0.3778076171875 +18685 0.376953125 +18686 0.371978759765625 +18687 0.313140869140625 +18688 0.184417724609375 +18689 0.011199951171875 +18690 -0.171051025390625 +18691 -0.33740234375 +18692 -0.47198486328125 +18693 -0.560394287109375 +18694 -0.58056640625 +18695 -0.54754638671875 +18696 -0.508575439453125 +18697 -0.459503173828125 +18698 -0.394378662109375 +18699 -0.35260009765625 +18700 -0.31170654296875 +18701 -0.197418212890625 +18702 -0.007965087890625 +18703 0.207489013671875 +18704 0.409210205078125 +18705 0.57208251953125 +18706 0.66595458984375 +18707 0.65875244140625 +18708 0.56744384765625 +18709 0.431396484375 +18710 0.29443359375 +18711 0.182464599609375 +18712 0.06365966796875 +18713 -0.075958251953125 +18714 -0.189422607421875 +18715 -0.271942138671875 +18716 -0.342529296875 +18717 -0.364166259765625 +18718 -0.327239990234375 +18719 -0.2769775390625 +18720 -0.253692626953125 +18721 -0.24365234375 +18722 -0.1983642578125 +18723 -0.116241455078125 +18724 -0.036834716796875 +18725 0.034881591796875 +18726 0.09124755859375 +18727 0.10888671875 +18728 0.125518798828125 +18729 0.15771484375 +18730 0.17828369140625 +18731 0.17108154296875 +18732 0.129974365234375 +18733 0.082427978515625 +18734 0.027679443359375 +18735 -0.065643310546875 +18736 -0.15936279296875 +18737 -0.21307373046875 +18738 -0.234649658203125 +18739 -0.2001953125 +18740 -0.119171142578125 +18741 -0.024749755859375 +18742 0.085784912109375 +18743 0.178131103515625 +18744 0.215576171875 +18745 0.211456298828125 +18746 0.17523193359375 +18747 0.128753662109375 +18748 0.1019287109375 +18749 0.0743408203125 +18750 0.04327392578125 +18751 0.038177490234375 +18752 0.076263427734375 +18753 0.14105224609375 +18754 0.186431884765625 +18755 0.188812255859375 +18756 0.1390380859375 +18757 0.041778564453125 +18758 -0.079437255859375 +18759 -0.219390869140625 +18760 -0.367828369140625 +18761 -0.494873046875 +18762 -0.556243896484375 +18763 -0.508697509765625 +18764 -0.3756103515625 +18765 -0.218902587890625 +18766 -0.063751220703125 +18767 0.091552734375 +18768 0.23602294921875 +18769 0.342987060546875 +18770 0.39520263671875 +18771 0.389373779296875 +18772 0.324249267578125 +18773 0.224090576171875 +18774 0.124267578125 +18775 0.037078857421875 +18776 -0.010101318359375 +18777 -0.019439697265625 +18778 -0.022796630859375 +18779 -0.001556396484375 +18780 0.056304931640625 +18781 0.106719970703125 +18782 0.096893310546875 +18783 0.042694091796875 +18784 -0.018035888671875 +18785 -0.07586669921875 +18786 -0.11944580078125 +18787 -0.15972900390625 +18788 -0.202606201171875 +18789 -0.24859619140625 +18790 -0.30517578125 +18791 -0.36212158203125 +18792 -0.39141845703125 +18793 -0.35528564453125 +18794 -0.249969482421875 +18795 -0.092864990234375 +18796 0.08905029296875 +18797 0.2352294921875 +18798 0.318817138671875 +18799 0.358642578125 +18800 0.347747802734375 +18801 0.28564453125 +18802 0.223175048828125 +18803 0.196746826171875 +18804 0.179840087890625 +18805 0.155548095703125 +18806 0.151214599609375 +18807 0.156951904296875 +18808 0.13177490234375 +18809 0.100799560546875 +18810 0.087127685546875 +18811 0.05487060546875 +18812 -0.009002685546875 +18813 -0.10400390625 +18814 -0.229400634765625 +18815 -0.35552978515625 +18816 -0.441925048828125 +18817 -0.473846435546875 +18818 -0.464813232421875 +18819 -0.419097900390625 +18820 -0.334320068359375 +18821 -0.227935791015625 +18822 -0.12347412109375 +18823 -0.02764892578125 +18824 0.077667236328125 +18825 0.2132568359375 +18826 0.38885498046875 +18827 0.582794189453125 +18828 0.734039306640625 +18829 0.800140380859375 +18830 0.7783203125 +18831 0.6651611328125 +18832 0.45965576171875 +18833 0.199188232421875 +18834 -0.050689697265625 +18835 -0.23297119140625 +18836 -0.33013916015625 +18837 -0.368408203125 +18838 -0.378936767578125 +18839 -0.376983642578125 +18840 -0.37969970703125 +18841 -0.391510009765625 +18842 -0.385345458984375 +18843 -0.3419189453125 +18844 -0.28289794921875 +18845 -0.251617431640625 +18846 -0.266143798828125 +18847 -0.273345947265625 +18848 -0.216796875 +18849 -0.128265380859375 +18850 -0.068145751953125 +18851 -0.0430908203125 +18852 -0.024444580078125 +18853 0.020721435546875 +18854 0.124481201171875 +18855 0.25787353515625 +18856 0.379119873046875 +18857 0.47991943359375 +18858 0.5281982421875 +18859 0.511138916015625 +18860 0.456207275390625 +18861 0.407470703125 +18862 0.383758544921875 +18863 0.35687255859375 +18864 0.31182861328125 +18865 0.250885009765625 +18866 0.1654052734375 +18867 0.035247802734375 +18868 -0.142059326171875 +18869 -0.33563232421875 +18870 -0.5345458984375 +18871 -0.72186279296875 +18872 -0.836669921875 +18873 -0.8326416015625 +18874 -0.7296142578125 +18875 -0.582550048828125 +18876 -0.440093994140625 +18877 -0.324310302734375 +18878 -0.20147705078125 +18879 -0.044647216796875 +18880 0.103973388671875 +18881 0.202392578125 +18882 0.264495849609375 +18883 0.338897705078125 +18884 0.443817138671875 +18885 0.545074462890625 +18886 0.6173095703125 +18887 0.6524658203125 +18888 0.66339111328125 +18889 0.6561279296875 +18890 0.606781005859375 +18891 0.501190185546875 +18892 0.352783203125 +18893 0.176544189453125 +18894 -0.034820556640625 +18895 -0.258209228515625 +18896 -0.44244384765625 +18897 -0.5753173828125 +18898 -0.65203857421875 +18899 -0.641632080078125 +18900 -0.562164306640625 +18901 -0.458038330078125 +18902 -0.350555419921875 +18903 -0.260528564453125 +18904 -0.192108154296875 +18905 -0.141937255859375 +18906 -0.1021728515625 +18907 -0.062896728515625 +18908 -0.011932373046875 +18909 0.062835693359375 +18910 0.148712158203125 +18911 0.241729736328125 +18912 0.34912109375 +18913 0.457305908203125 +18914 0.54388427734375 +18915 0.5728759765625 +18916 0.506591796875 +18917 0.351226806640625 +18918 0.146514892578125 +18919 -0.05523681640625 +18920 -0.21624755859375 +18921 -0.334930419921875 +18922 -0.402984619140625 +18923 -0.4412841796875 +18924 -0.49578857421875 +18925 -0.5601806640625 +18926 -0.600738525390625 +18927 -0.584228515625 +18928 -0.47930908203125 +18929 -0.27935791015625 +18930 -0.0089111328125 +18931 0.268798828125 +18932 0.482818603515625 +18933 0.60369873046875 +18934 0.650421142578125 +18935 0.66400146484375 +18936 0.6414794921875 +18937 0.572540283203125 +18938 0.498138427734375 +18939 0.439453125 +18940 0.375518798828125 +18941 0.274505615234375 +18942 0.1087646484375 +18943 -0.099395751953125 +18944 -0.3182373046875 +18945 -0.5489501953125 +18946 -0.7738037109375 +18947 -0.86383056640625 +18948 -0.870391845703125 +18949 -0.86895751953125 +18950 -0.861053466796875 +18951 -0.765869140625 +18952 -0.5301513671875 +18953 -0.214691162109375 +18954 0.137359619140625 +18955 0.474822998046875 +18956 0.76239013671875 +18957 0.867462158203125 +18958 0.870361328125 +18959 0.86480712890625 +18960 0.831817626953125 +18961 0.677581787109375 +18962 0.495880126953125 +18963 0.30767822265625 +18964 0.116180419921875 +18965 -0.110748291015625 +18966 -0.381805419921875 +18967 -0.6572265625 +18968 -0.857421875 +18969 -0.870391845703125 +18970 -0.870391845703125 +18971 -0.86444091796875 +18972 -0.85723876953125 +18973 -0.790008544921875 +18974 -0.62847900390625 +18975 -0.3956298828125 +18976 -0.126708984375 +18977 0.150115966796875 +18978 0.424041748046875 +18979 0.670623779296875 +18980 0.854522705078125 +18981 0.866485595703125 +18982 0.86920166015625 +18983 0.8653564453125 +18984 0.857147216796875 +18985 0.766845703125 +18986 0.628509521484375 +18987 0.462127685546875 +18988 0.297210693359375 +18989 0.14862060546875 +18990 -0.00537109375 +18991 -0.15753173828125 +18992 -0.31304931640625 +18993 -0.48876953125 +18994 -0.6416015625 +18995 -0.751373291015625 +18996 -0.84619140625 +18997 -0.861297607421875 +18998 -0.863250732421875 +18999 -0.856597900390625 +19000 -0.7498779296875 +19001 -0.624542236328125 +19002 -0.47808837890625 +19003 -0.253387451171875 +19004 0.003692626953125 +19005 0.2257080078125 +19006 0.427154541015625 +19007 0.643218994140625 +19008 0.855926513671875 +19009 0.870361328125 +19010 0.870361328125 +19011 0.862762451171875 +19012 0.79669189453125 +19013 0.595794677734375 +19014 0.362152099609375 +19015 0.1270751953125 +19016 -0.086944580078125 +19017 -0.2784423828125 +19018 -0.484832763671875 +19019 -0.729583740234375 +19020 -0.86688232421875 +19021 -0.870391845703125 +19022 -0.86859130859375 +19023 -0.86279296875 +19024 -0.817962646484375 +19025 -0.6116943359375 +19026 -0.3128662109375 +19027 0.039398193359375 +19028 0.422821044921875 +19029 0.805145263671875 +19030 0.870361328125 +19031 0.870361328125 +19032 0.860015869140625 +19033 0.727935791015625 +19034 0.48114013671875 +19035 0.2059326171875 +19036 -0.06103515625 +19037 -0.29913330078125 +19038 -0.516204833984375 +19039 -0.7252197265625 +19040 -0.85980224609375 +19041 -0.870391845703125 +19042 -0.870391845703125 +19043 -0.858062744140625 +19044 -0.673004150390625 +19045 -0.42694091796875 +19046 -0.2100830078125 +19047 -0.0362548828125 +19048 0.10943603515625 +19049 0.23516845703125 +19050 0.373687744140625 +19051 0.517791748046875 +19052 0.602783203125 +19053 0.635711669921875 +19054 0.655181884765625 +19055 0.65948486328125 +19056 0.651275634765625 +19057 0.61846923828125 +19058 0.53753662109375 +19059 0.404144287109375 +19060 0.22186279296875 +19061 0.003997802734375 +19062 -0.22100830078125 +19063 -0.42449951171875 +19064 -0.579833984375 +19065 -0.641876220703125 +19066 -0.6177978515625 +19067 -0.575531005859375 +19068 -0.526336669921875 +19069 -0.42645263671875 +19070 -0.2581787109375 +19071 -0.068695068359375 +19072 0.09222412109375 +19073 0.232147216796875 +19074 0.3509521484375 +19075 0.410064697265625 +19076 0.372955322265625 +19077 0.2554931640625 +19078 0.10711669921875 +19079 -0.052886962890625 +19080 -0.186279296875 +19081 -0.23291015625 +19082 -0.209442138671875 +19083 -0.174163818359375 +19084 -0.126739501953125 +19085 -0.048126220703125 +19086 0.0426025390625 +19087 0.10748291015625 +19088 0.1409912109375 +19089 0.19708251953125 +19090 0.273651123046875 +19091 0.31768798828125 +19092 0.341094970703125 +19093 0.368011474609375 +19094 0.37249755859375 +19095 0.30072021484375 +19096 0.1517333984375 +19097 -0.01470947265625 +19098 -0.1883544921875 +19099 -0.372711181640625 +19100 -0.51397705078125 +19101 -0.57177734375 +19102 -0.53948974609375 +19103 -0.43511962890625 +19104 -0.2962646484375 +19105 -0.161102294921875 +19106 -0.0435791015625 +19107 0.060394287109375 +19108 0.13665771484375 +19109 0.170135498046875 +19110 0.16552734375 +19111 0.15728759765625 +19112 0.150787353515625 +19113 0.12200927734375 +19114 0.080108642578125 +19115 0.05126953125 +19116 0.062896728515625 +19117 0.09271240234375 +19118 0.092987060546875 +19119 0.07855224609375 +19120 0.06427001953125 +19121 0.0347900390625 +19122 -0.01171875 +19123 -0.056060791015625 +19124 -0.055511474609375 +19125 -0.010467529296875 +19126 0.02508544921875 +19127 0.025665283203125 +19128 0.017333984375 +19129 0.00189208984375 +19130 -0.03173828125 +19131 -0.071502685546875 +19132 -0.13543701171875 +19133 -0.219970703125 +19134 -0.300506591796875 +19135 -0.376312255859375 +19136 -0.416107177734375 +19137 -0.371124267578125 +19138 -0.242279052734375 +19139 -0.069732666015625 +19140 0.125640869140625 +19141 0.31268310546875 +19142 0.45501708984375 +19143 0.554779052734375 +19144 0.61065673828125 +19145 0.610931396484375 +19146 0.531463623046875 +19147 0.3883056640625 +19148 0.23468017578125 +19149 0.095245361328125 +19150 -0.00396728515625 +19151 -0.04852294921875 +19152 -0.055145263671875 +19153 -0.0758056640625 +19154 -0.138702392578125 +19155 -0.209197998046875 +19156 -0.289031982421875 +19157 -0.37884521484375 +19158 -0.456329345703125 +19159 -0.51641845703125 +19160 -0.519287109375 +19161 -0.458251953125 +19162 -0.384796142578125 +19163 -0.323699951171875 +19164 -0.269287109375 +19165 -0.1951904296875 +19166 -0.100006103515625 +19167 -0.01055908203125 +19168 0.1033935546875 +19169 0.24908447265625 +19170 0.373199462890625 +19171 0.45806884765625 +19172 0.511474609375 +19173 0.565399169921875 +19174 0.61138916015625 +19175 0.5897216796875 +19176 0.4906005859375 +19177 0.33148193359375 +19178 0.147796630859375 +19179 -0.01873779296875 +19180 -0.140289306640625 +19181 -0.191986083984375 +19182 -0.184295654296875 +19183 -0.161834716796875 +19184 -0.166595458984375 +19185 -0.19390869140625 +19186 -0.22442626953125 +19187 -0.279754638671875 +19188 -0.3389892578125 +19189 -0.3543701171875 +19190 -0.348175048828125 +19191 -0.32598876953125 +19192 -0.2581787109375 +19193 -0.139801025390625 +19194 0.014617919921875 +19195 0.144378662109375 +19196 0.221038818359375 +19197 0.27069091796875 +19198 0.294036865234375 +19199 0.311767578125 +19200 0.339141845703125 +19201 0.360260009765625 +19202 0.360504150390625 +19203 0.308380126953125 +19204 0.18170166015625 +19205 0.0047607421875 +19206 -0.17559814453125 +19207 -0.3143310546875 +19208 -0.36785888671875 +19209 -0.36248779296875 +19210 -0.343536376953125 +19211 -0.3018798828125 +19212 -0.231414794921875 +19213 -0.117645263671875 +19214 0.007049560546875 +19215 0.087982177734375 +19216 0.13946533203125 +19217 0.17425537109375 +19218 0.188201904296875 +19219 0.171234130859375 +19220 0.118438720703125 +19221 0.05706787109375 +19222 -0.010711669921875 +19223 -0.0914306640625 +19224 -0.162322998046875 +19225 -0.194549560546875 +19226 -0.1492919921875 +19227 -0.02166748046875 +19228 0.124053955078125 +19229 0.211151123046875 +19230 0.240447998046875 +19231 0.242218017578125 +19232 0.2257080078125 +19233 0.194366455078125 +19234 0.115509033203125 +19235 0.0128173828125 +19236 -0.053802490234375 +19237 -0.110626220703125 +19238 -0.199493408203125 +19239 -0.29437255859375 +19240 -0.33221435546875 +19241 -0.27972412109375 +19242 -0.185333251953125 +19243 -0.128204345703125 +19244 -0.115692138671875 +19245 -0.116455078125 +19246 -0.105926513671875 +19247 -0.053955078125 +19248 0.048797607421875 +19249 0.157318115234375 +19250 0.212005615234375 +19251 0.218475341796875 +19252 0.23724365234375 +19253 0.30535888671875 +19254 0.38128662109375 +19255 0.404449462890625 +19256 0.3944091796875 +19257 0.3885498046875 +19258 0.362640380859375 +19259 0.27362060546875 +19260 0.11712646484375 +19261 -0.054901123046875 +19262 -0.19085693359375 +19263 -0.28570556640625 +19264 -0.339263916015625 +19265 -0.3775634765625 +19266 -0.445709228515625 +19267 -0.535064697265625 +19268 -0.629058837890625 +19269 -0.697601318359375 +19270 -0.70391845703125 +19271 -0.6424560546875 +19272 -0.491241455078125 +19273 -0.265716552734375 +19274 -0.023712158203125 +19275 0.201751708984375 +19276 0.375823974609375 +19277 0.485076904296875 +19278 0.56884765625 +19279 0.634765625 +19280 0.63763427734375 +19281 0.5660400390625 +19282 0.4720458984375 +19283 0.40692138671875 +19284 0.3778076171875 +19285 0.376953125 +19286 0.371978759765625 +19287 0.313140869140625 +19288 0.184417724609375 +19289 0.011199951171875 +19290 -0.171051025390625 +19291 -0.33740234375 +19292 -0.47198486328125 +19293 -0.560394287109375 +19294 -0.58056640625 +19295 -0.54754638671875 +19296 -0.508575439453125 +19297 -0.459503173828125 +19298 -0.394378662109375 +19299 -0.35260009765625 +19300 -0.31170654296875 +19301 -0.197418212890625 +19302 -0.007965087890625 +19303 0.207489013671875 +19304 0.409210205078125 +19305 0.57208251953125 +19306 0.66595458984375 +19307 0.65875244140625 +19308 0.56744384765625 +19309 0.431396484375 +19310 0.29443359375 +19311 0.182464599609375 +19312 0.06365966796875 +19313 -0.075958251953125 +19314 -0.189422607421875 +19315 -0.271942138671875 +19316 -0.342529296875 +19317 -0.364166259765625 +19318 -0.327239990234375 +19319 -0.2769775390625 +19320 -0.253692626953125 +19321 -0.24365234375 +19322 -0.1983642578125 +19323 -0.116241455078125 +19324 -0.036834716796875 +19325 0.034881591796875 +19326 0.09124755859375 +19327 0.10888671875 +19328 0.125518798828125 +19329 0.15771484375 +19330 0.17828369140625 +19331 0.17108154296875 +19332 0.129974365234375 +19333 0.082427978515625 +19334 0.027679443359375 +19335 -0.065643310546875 +19336 -0.15936279296875 +19337 -0.21307373046875 +19338 -0.234649658203125 +19339 -0.2001953125 +19340 -0.119171142578125 +19341 -0.024749755859375 +19342 0.085784912109375 +19343 0.178131103515625 +19344 0.215576171875 +19345 0.211456298828125 +19346 0.17523193359375 +19347 0.128753662109375 +19348 0.1019287109375 +19349 0.0743408203125 +19350 0.04327392578125 +19351 0.038177490234375 +19352 0.076263427734375 +19353 0.14105224609375 +19354 0.186431884765625 +19355 0.188812255859375 +19356 0.1390380859375 +19357 0.041778564453125 +19358 -0.079437255859375 +19359 -0.219390869140625 +19360 -0.367828369140625 +19361 -0.494873046875 +19362 -0.556243896484375 +19363 -0.508697509765625 +19364 -0.3756103515625 +19365 -0.218902587890625 +19366 -0.063751220703125 +19367 0.091552734375 +19368 0.23602294921875 +19369 0.342987060546875 +19370 0.39520263671875 +19371 0.389373779296875 +19372 0.324249267578125 +19373 0.224090576171875 +19374 0.124267578125 +19375 0.037078857421875 +19376 -0.010101318359375 +19377 -0.019439697265625 +19378 -0.022796630859375 +19379 -0.001556396484375 +19380 0.056304931640625 +19381 0.106719970703125 +19382 0.096893310546875 +19383 0.042694091796875 +19384 -0.018035888671875 +19385 -0.07586669921875 +19386 -0.11944580078125 +19387 -0.15972900390625 +19388 -0.202606201171875 +19389 -0.24859619140625 +19390 -0.30517578125 +19391 -0.36212158203125 +19392 -0.39141845703125 +19393 -0.35528564453125 +19394 -0.249969482421875 +19395 -0.092864990234375 +19396 0.08905029296875 +19397 0.2352294921875 +19398 0.318817138671875 +19399 0.358642578125 +19400 0.347747802734375 +19401 0.28564453125 +19402 0.223175048828125 +19403 0.196746826171875 +19404 0.179840087890625 +19405 0.155548095703125 +19406 0.151214599609375 +19407 0.156951904296875 +19408 0.13177490234375 +19409 0.100799560546875 +19410 0.087127685546875 +19411 0.05487060546875 +19412 -0.009002685546875 +19413 -0.10400390625 +19414 -0.229400634765625 +19415 -0.35552978515625 +19416 -0.441925048828125 +19417 -0.473846435546875 +19418 -0.464813232421875 +19419 -0.419097900390625 +19420 -0.334320068359375 +19421 -0.227935791015625 +19422 -0.12347412109375 +19423 -0.02764892578125 +19424 0.077667236328125 +19425 0.2132568359375 +19426 0.38885498046875 +19427 0.582794189453125 +19428 0.734039306640625 +19429 0.800140380859375 +19430 0.7783203125 +19431 0.6651611328125 +19432 0.45965576171875 +19433 0.199188232421875 +19434 -0.050689697265625 +19435 -0.23297119140625 +19436 -0.33013916015625 +19437 -0.368408203125 +19438 -0.378936767578125 +19439 -0.376983642578125 +19440 -0.37969970703125 +19441 -0.391510009765625 +19442 -0.385345458984375 +19443 -0.3419189453125 +19444 -0.28289794921875 +19445 -0.251617431640625 +19446 -0.266143798828125 +19447 -0.273345947265625 +19448 -0.216796875 +19449 -0.128265380859375 +19450 -0.068145751953125 +19451 -0.0430908203125 +19452 -0.024444580078125 +19453 0.020721435546875 +19454 0.124481201171875 +19455 0.25787353515625 +19456 0.379119873046875 +19457 0.47991943359375 +19458 0.5281982421875 +19459 0.511138916015625 +19460 0.456207275390625 +19461 0.407470703125 +19462 0.383758544921875 +19463 0.35687255859375 +19464 0.31182861328125 +19465 0.250885009765625 +19466 0.1654052734375 +19467 0.035247802734375 +19468 -0.142059326171875 +19469 -0.33563232421875 +19470 -0.5345458984375 +19471 -0.72186279296875 +19472 -0.836669921875 +19473 -0.8326416015625 +19474 -0.7296142578125 +19475 -0.582550048828125 +19476 -0.440093994140625 +19477 -0.324310302734375 +19478 -0.20147705078125 +19479 -0.044647216796875 +19480 0.103973388671875 +19481 0.202392578125 +19482 0.264495849609375 +19483 0.338897705078125 +19484 0.443817138671875 +19485 0.545074462890625 +19486 0.6173095703125 +19487 0.6524658203125 +19488 0.66339111328125 +19489 0.6561279296875 +19490 0.606781005859375 +19491 0.501190185546875 +19492 0.352783203125 +19493 0.176544189453125 +19494 -0.034820556640625 +19495 -0.258209228515625 +19496 -0.44244384765625 +19497 -0.5753173828125 +19498 -0.65203857421875 +19499 -0.641632080078125 +19500 -0.562164306640625 +19501 -0.458038330078125 +19502 -0.350555419921875 +19503 -0.260528564453125 +19504 -0.192108154296875 +19505 -0.141937255859375 +19506 -0.1021728515625 +19507 -0.062896728515625 +19508 -0.011932373046875 +19509 0.062835693359375 +19510 0.148712158203125 +19511 0.241729736328125 +19512 0.34912109375 +19513 0.457305908203125 +19514 0.54388427734375 +19515 0.5728759765625 +19516 0.506591796875 +19517 0.351226806640625 +19518 0.146514892578125 +19519 -0.05523681640625 +19520 -0.21624755859375 +19521 -0.334930419921875 +19522 -0.402984619140625 +19523 -0.4412841796875 +19524 -0.49578857421875 +19525 -0.5601806640625 +19526 -0.600738525390625 +19527 -0.584228515625 +19528 -0.47930908203125 +19529 -0.27935791015625 +19530 -0.0089111328125 +19531 0.268798828125 +19532 0.482818603515625 +19533 0.60369873046875 +19534 0.650421142578125 +19535 0.66400146484375 +19536 0.6414794921875 +19537 0.572540283203125 +19538 0.498138427734375 +19539 0.439453125 +19540 0.375518798828125 +19541 0.274505615234375 +19542 0.1087646484375 +19543 -0.099395751953125 +19544 -0.3182373046875 +19545 -0.5489501953125 +19546 -0.7738037109375 +19547 -0.86383056640625 +19548 -0.870391845703125 +19549 -0.86895751953125 +19550 -0.861053466796875 +19551 -0.765869140625 +19552 -0.5301513671875 +19553 -0.214691162109375 +19554 0.137359619140625 +19555 0.474822998046875 +19556 0.76239013671875 +19557 0.867462158203125 +19558 0.870361328125 +19559 0.86480712890625 +19560 0.831817626953125 +19561 0.677581787109375 +19562 0.495880126953125 +19563 0.30767822265625 +19564 0.116180419921875 +19565 -0.110748291015625 +19566 -0.381805419921875 +19567 -0.6572265625 +19568 -0.857421875 +19569 -0.870391845703125 +19570 -0.870391845703125 +19571 -0.86444091796875 +19572 -0.85723876953125 +19573 -0.790008544921875 +19574 -0.62847900390625 +19575 -0.3956298828125 +19576 -0.126708984375 +19577 0.150115966796875 +19578 0.424041748046875 +19579 0.670623779296875 +19580 0.854522705078125 +19581 0.866485595703125 +19582 0.86920166015625 +19583 0.8653564453125 +19584 0.857147216796875 +19585 0.766845703125 +19586 0.628509521484375 +19587 0.462127685546875 +19588 0.297210693359375 +19589 0.14862060546875 +19590 -0.00537109375 +19591 -0.15753173828125 +19592 -0.31304931640625 +19593 -0.48876953125 +19594 -0.6416015625 +19595 -0.751373291015625 +19596 -0.84619140625 +19597 -0.861297607421875 +19598 -0.863250732421875 +19599 -0.856597900390625 +19600 -0.7498779296875 +19601 -0.624542236328125 +19602 -0.47808837890625 +19603 -0.253387451171875 +19604 0.003692626953125 +19605 0.2257080078125 +19606 0.427154541015625 +19607 0.643218994140625 +19608 0.855926513671875 +19609 0.870361328125 +19610 0.870361328125 +19611 0.862762451171875 +19612 0.79669189453125 +19613 0.595794677734375 +19614 0.362152099609375 +19615 0.1270751953125 +19616 -0.086944580078125 +19617 -0.2784423828125 +19618 -0.484832763671875 +19619 -0.729583740234375 +19620 -0.86688232421875 +19621 -0.870391845703125 +19622 -0.86859130859375 +19623 -0.86279296875 +19624 -0.817962646484375 +19625 -0.6116943359375 +19626 -0.3128662109375 +19627 0.039398193359375 +19628 0.422821044921875 +19629 0.805145263671875 +19630 0.870361328125 +19631 0.870361328125 +19632 0.860015869140625 +19633 0.727935791015625 +19634 0.48114013671875 +19635 0.2059326171875 +19636 -0.06103515625 +19637 -0.29913330078125 +19638 -0.516204833984375 +19639 -0.7252197265625 +19640 -0.85980224609375 +19641 -0.870391845703125 +19642 -0.870391845703125 +19643 -0.858062744140625 +19644 -0.673004150390625 +19645 -0.42694091796875 +19646 -0.2100830078125 +19647 -0.0362548828125 +19648 0.10943603515625 +19649 0.23516845703125 +19650 0.373687744140625 +19651 0.517791748046875 +19652 0.602783203125 +19653 0.635711669921875 +19654 0.655181884765625 +19655 0.65948486328125 +19656 0.651275634765625 +19657 0.61846923828125 +19658 0.53753662109375 +19659 0.404144287109375 +19660 0.22186279296875 +19661 0.003997802734375 +19662 -0.22100830078125 +19663 -0.42449951171875 +19664 -0.579833984375 +19665 -0.641876220703125 +19666 -0.6177978515625 +19667 -0.575531005859375 +19668 -0.526336669921875 +19669 -0.42645263671875 +19670 -0.2581787109375 +19671 -0.068695068359375 +19672 0.09222412109375 +19673 0.232147216796875 +19674 0.3509521484375 +19675 0.410064697265625 +19676 0.372955322265625 +19677 0.2554931640625 +19678 0.10711669921875 +19679 -0.052886962890625 +19680 -0.186279296875 +19681 -0.23291015625 +19682 -0.209442138671875 +19683 -0.174163818359375 +19684 -0.126739501953125 +19685 -0.048126220703125 +19686 0.0426025390625 +19687 0.10748291015625 +19688 0.1409912109375 +19689 0.19708251953125 +19690 0.273651123046875 +19691 0.31768798828125 +19692 0.341094970703125 +19693 0.368011474609375 +19694 0.37249755859375 +19695 0.30072021484375 +19696 0.1517333984375 +19697 -0.01470947265625 +19698 -0.1883544921875 +19699 -0.372711181640625 +19700 -0.51397705078125 +19701 -0.57177734375 +19702 -0.53948974609375 +19703 -0.43511962890625 +19704 -0.2962646484375 +19705 -0.161102294921875 +19706 -0.0435791015625 +19707 0.060394287109375 +19708 0.13665771484375 +19709 0.170135498046875 +19710 0.16552734375 +19711 0.15728759765625 +19712 0.150787353515625 +19713 0.12200927734375 +19714 0.080108642578125 +19715 0.05126953125 +19716 0.062896728515625 +19717 0.09271240234375 +19718 0.092987060546875 +19719 0.07855224609375 +19720 0.06427001953125 +19721 0.0347900390625 +19722 -0.01171875 +19723 -0.056060791015625 +19724 -0.055511474609375 +19725 -0.010467529296875 +19726 0.02508544921875 +19727 0.025665283203125 +19728 0.017333984375 +19729 0.00189208984375 +19730 -0.03173828125 +19731 -0.071502685546875 +19732 -0.13543701171875 +19733 -0.219970703125 +19734 -0.300506591796875 +19735 -0.376312255859375 +19736 -0.416107177734375 +19737 -0.371124267578125 +19738 -0.242279052734375 +19739 -0.069732666015625 +19740 0.125640869140625 +19741 0.31268310546875 +19742 0.45501708984375 +19743 0.554779052734375 +19744 0.61065673828125 +19745 0.610931396484375 +19746 0.531463623046875 +19747 0.3883056640625 +19748 0.23468017578125 +19749 0.095245361328125 +19750 -0.00396728515625 +19751 -0.04852294921875 +19752 -0.055145263671875 +19753 -0.0758056640625 +19754 -0.138702392578125 +19755 -0.209197998046875 +19756 -0.289031982421875 +19757 -0.37884521484375 +19758 -0.456329345703125 +19759 -0.51641845703125 +19760 -0.519287109375 +19761 -0.458251953125 +19762 -0.384796142578125 +19763 -0.323699951171875 +19764 -0.269287109375 +19765 -0.1951904296875 +19766 -0.100006103515625 +19767 -0.01055908203125 +19768 0.1033935546875 +19769 0.24908447265625 +19770 0.373199462890625 +19771 0.45806884765625 +19772 0.511474609375 +19773 0.565399169921875 +19774 0.61138916015625 +19775 0.5897216796875 +19776 0.4906005859375 +19777 0.33148193359375 +19778 0.147796630859375 +19779 -0.01873779296875 +19780 -0.140289306640625 +19781 -0.191986083984375 +19782 -0.184295654296875 +19783 -0.161834716796875 +19784 -0.166595458984375 +19785 -0.19390869140625 +19786 -0.22442626953125 +19787 -0.279754638671875 +19788 -0.3389892578125 +19789 -0.3543701171875 +19790 -0.348175048828125 +19791 -0.32598876953125 +19792 -0.2581787109375 +19793 -0.139801025390625 +19794 0.014617919921875 +19795 0.144378662109375 +19796 0.221038818359375 +19797 0.27069091796875 +19798 0.294036865234375 +19799 0.311767578125 +19800 0.339141845703125 +19801 0.360260009765625 +19802 0.360504150390625 +19803 0.308380126953125 +19804 0.18170166015625 +19805 0.0047607421875 +19806 -0.17559814453125 +19807 -0.3143310546875 +19808 -0.36785888671875 +19809 -0.36248779296875 +19810 -0.343536376953125 +19811 -0.3018798828125 +19812 -0.231414794921875 +19813 -0.117645263671875 +19814 0.007049560546875 +19815 0.087982177734375 +19816 0.13946533203125 +19817 0.17425537109375 +19818 0.188201904296875 +19819 0.171234130859375 +19820 0.118438720703125 +19821 0.05706787109375 +19822 -0.010711669921875 +19823 -0.0914306640625 +19824 -0.162322998046875 +19825 -0.194549560546875 +19826 -0.1492919921875 +19827 -0.02166748046875 +19828 0.124053955078125 +19829 0.211151123046875 +19830 0.240447998046875 +19831 0.242218017578125 +19832 0.2257080078125 +19833 0.194366455078125 +19834 0.115509033203125 +19835 0.0128173828125 +19836 -0.053802490234375 +19837 -0.110626220703125 +19838 -0.199493408203125 +19839 -0.29437255859375 +19840 -0.33221435546875 +19841 -0.27972412109375 +19842 -0.185333251953125 +19843 -0.128204345703125 +19844 -0.115692138671875 +19845 -0.116455078125 +19846 -0.105926513671875 +19847 -0.053955078125 +19848 0.048797607421875 +19849 0.157318115234375 +19850 0.212005615234375 +19851 0.218475341796875 +19852 0.23724365234375 +19853 0.30535888671875 +19854 0.38128662109375 +19855 0.404449462890625 +19856 0.3944091796875 +19857 0.3885498046875 +19858 0.362640380859375 +19859 0.27362060546875 +19860 0.11712646484375 +19861 -0.054901123046875 +19862 -0.19085693359375 +19863 -0.28570556640625 +19864 -0.339263916015625 +19865 -0.3775634765625 +19866 -0.445709228515625 +19867 -0.535064697265625 +19868 -0.629058837890625 +19869 -0.697601318359375 +19870 -0.70391845703125 +19871 -0.6424560546875 +19872 -0.491241455078125 +19873 -0.265716552734375 +19874 -0.023712158203125 +19875 0.201751708984375 +19876 0.375823974609375 +19877 0.485076904296875 +19878 0.56884765625 +19879 0.634765625 +19880 0.63763427734375 +19881 0.5660400390625 +19882 0.4720458984375 +19883 0.40692138671875 +19884 0.3778076171875 +19885 0.376953125 +19886 0.371978759765625 +19887 0.313140869140625 +19888 0.184417724609375 +19889 0.011199951171875 +19890 -0.171051025390625 +19891 -0.33740234375 +19892 -0.47198486328125 +19893 -0.560394287109375 +19894 -0.58056640625 +19895 -0.54754638671875 +19896 -0.508575439453125 +19897 -0.459503173828125 +19898 -0.394378662109375 +19899 -0.35260009765625 +19900 -0.31170654296875 +19901 -0.197418212890625 +19902 -0.007965087890625 +19903 0.207489013671875 +19904 0.409210205078125 +19905 0.57208251953125 +19906 0.66595458984375 +19907 0.65875244140625 +19908 0.56744384765625 +19909 0.431396484375 +19910 0.29443359375 +19911 0.182464599609375 +19912 0.06365966796875 +19913 -0.075958251953125 +19914 -0.189422607421875 +19915 -0.271942138671875 +19916 -0.342529296875 +19917 -0.364166259765625 +19918 -0.327239990234375 +19919 -0.2769775390625 +19920 -0.253692626953125 +19921 -0.24365234375 +19922 -0.1983642578125 +19923 -0.116241455078125 +19924 -0.036834716796875 +19925 0.034881591796875 +19926 0.09124755859375 +19927 0.10888671875 +19928 0.125518798828125 +19929 0.15771484375 +19930 0.17828369140625 +19931 0.17108154296875 +19932 0.129974365234375 +19933 0.082427978515625 +19934 0.027679443359375 +19935 -0.065643310546875 +19936 -0.15936279296875 +19937 -0.21307373046875 +19938 -0.234649658203125 +19939 -0.2001953125 +19940 -0.119171142578125 +19941 -0.024749755859375 +19942 0.085784912109375 +19943 0.178131103515625 +19944 0.215576171875 +19945 0.211456298828125 +19946 0.17523193359375 +19947 0.128753662109375 +19948 0.1019287109375 +19949 0.0743408203125 +19950 0.04327392578125 +19951 0.038177490234375 +19952 0.076263427734375 +19953 0.14105224609375 +19954 0.186431884765625 +19955 0.188812255859375 +19956 0.1390380859375 +19957 0.041778564453125 +19958 -0.079437255859375 +19959 -0.219390869140625 +19960 -0.367828369140625 +19961 -0.494873046875 +19962 -0.556243896484375 +19963 -0.508697509765625 +19964 -0.3756103515625 +19965 -0.218902587890625 +19966 -0.063751220703125 +19967 0.091552734375 +19968 0.23602294921875 +19969 0.342987060546875 +19970 0.39520263671875 +19971 0.389373779296875 +19972 0.324249267578125 +19973 0.224090576171875 +19974 0.124267578125 +19975 0.037078857421875 +19976 -0.010101318359375 +19977 -0.019439697265625 +19978 -0.022796630859375 +19979 -0.001556396484375 +19980 0.056304931640625 +19981 0.106719970703125 +19982 0.096893310546875 +19983 0.042694091796875 +19984 -0.018035888671875 +19985 -0.07586669921875 +19986 -0.11944580078125 +19987 -0.15972900390625 +19988 -0.202606201171875 +19989 -0.24859619140625 +19990 -0.30517578125 +19991 -0.36212158203125 +19992 -0.39141845703125 +19993 -0.35528564453125 +19994 -0.249969482421875 +19995 -0.092864990234375 +19996 0.08905029296875 +19997 0.2352294921875 +19998 0.318817138671875 +19999 0.358642578125 +20000 0.347747802734375 +20001 0.28564453125 +20002 0.223175048828125 +20003 0.196746826171875 +20004 0.179840087890625 +20005 0.155548095703125 +20006 0.151214599609375 +20007 0.156951904296875 +20008 0.13177490234375 +20009 0.100799560546875 +20010 0.087127685546875 +20011 0.05487060546875 +20012 -0.009002685546875 +20013 -0.10400390625 +20014 -0.229400634765625 +20015 -0.35552978515625 +20016 -0.441925048828125 +20017 -0.473846435546875 +20018 -0.464813232421875 +20019 -0.419097900390625 +20020 -0.334320068359375 +20021 -0.227935791015625 +20022 -0.12347412109375 +20023 -0.02764892578125 +20024 0.077667236328125 +20025 0.2132568359375 +20026 0.38885498046875 +20027 0.582794189453125 +20028 0.734039306640625 +20029 0.800140380859375 +20030 0.7783203125 +20031 0.6651611328125 +20032 0.45965576171875 +20033 0.199188232421875 +20034 -0.050689697265625 +20035 -0.23297119140625 +20036 -0.33013916015625 +20037 -0.368408203125 +20038 -0.378936767578125 +20039 -0.376983642578125 +20040 -0.37969970703125 +20041 -0.391510009765625 +20042 -0.385345458984375 +20043 -0.3419189453125 +20044 -0.28289794921875 +20045 -0.251617431640625 +20046 -0.266143798828125 +20047 -0.273345947265625 +20048 -0.216796875 +20049 -0.128265380859375 +20050 -0.068145751953125 +20051 -0.0430908203125 +20052 -0.024444580078125 +20053 0.020721435546875 +20054 0.124481201171875 +20055 0.25787353515625 +20056 0.379119873046875 +20057 0.47991943359375 +20058 0.5281982421875 +20059 0.511138916015625 +20060 0.456207275390625 +20061 0.407470703125 +20062 0.383758544921875 +20063 0.35687255859375 +20064 0.31182861328125 +20065 0.250885009765625 +20066 0.1654052734375 +20067 0.035247802734375 +20068 -0.142059326171875 +20069 -0.33563232421875 +20070 -0.5345458984375 +20071 -0.72186279296875 +20072 -0.836669921875 +20073 -0.8326416015625 +20074 -0.7296142578125 +20075 -0.582550048828125 +20076 -0.440093994140625 +20077 -0.324310302734375 +20078 -0.20147705078125 +20079 -0.044647216796875 +20080 0.103973388671875 +20081 0.202392578125 +20082 0.264495849609375 +20083 0.338897705078125 +20084 0.443817138671875 +20085 0.545074462890625 +20086 0.6173095703125 +20087 0.6524658203125 +20088 0.66339111328125 +20089 0.6561279296875 +20090 0.606781005859375 +20091 0.501190185546875 +20092 0.352783203125 +20093 0.176544189453125 +20094 -0.034820556640625 +20095 -0.258209228515625 +20096 -0.44244384765625 +20097 -0.5753173828125 +20098 -0.65203857421875 +20099 -0.641632080078125 +20100 -0.562164306640625 +20101 -0.458038330078125 +20102 -0.350555419921875 +20103 -0.260528564453125 +20104 -0.192108154296875 +20105 -0.141937255859375 +20106 -0.1021728515625 +20107 -0.062896728515625 +20108 -0.011932373046875 +20109 0.062835693359375 +20110 0.148712158203125 +20111 0.241729736328125 +20112 0.34912109375 +20113 0.457305908203125 +20114 0.54388427734375 +20115 0.5728759765625 +20116 0.506591796875 +20117 0.351226806640625 +20118 0.146514892578125 +20119 -0.05523681640625 +20120 -0.21624755859375 +20121 -0.334930419921875 +20122 -0.402984619140625 +20123 -0.4412841796875 +20124 -0.49578857421875 +20125 -0.5601806640625 +20126 -0.600738525390625 +20127 -0.584228515625 +20128 -0.47930908203125 +20129 -0.27935791015625 +20130 -0.0089111328125 +20131 0.268798828125 +20132 0.482818603515625 +20133 0.60369873046875 +20134 0.650421142578125 +20135 0.66400146484375 +20136 0.6414794921875 +20137 0.572540283203125 +20138 0.498138427734375 +20139 0.439453125 +20140 0.375518798828125 +20141 0.274505615234375 +20142 0.1087646484375 +20143 -0.099395751953125 +20144 -0.3182373046875 +20145 -0.5489501953125 +20146 -0.7738037109375 +20147 -0.86383056640625 +20148 -0.870391845703125 +20149 -0.86895751953125 +20150 -0.861053466796875 +20151 -0.765869140625 +20152 -0.5301513671875 +20153 -0.214691162109375 +20154 0.137359619140625 +20155 0.474822998046875 +20156 0.76239013671875 +20157 0.867462158203125 +20158 0.870361328125 +20159 0.86480712890625 +20160 0.831817626953125 +20161 0.677581787109375 +20162 0.495880126953125 +20163 0.30767822265625 +20164 0.116180419921875 +20165 -0.110748291015625 +20166 -0.381805419921875 +20167 -0.6572265625 +20168 -0.857421875 +20169 -0.870391845703125 +20170 -0.870391845703125 +20171 -0.86444091796875 +20172 -0.85723876953125 +20173 -0.790008544921875 +20174 -0.62847900390625 +20175 -0.3956298828125 +20176 -0.126708984375 +20177 0.150115966796875 +20178 0.424041748046875 +20179 0.670623779296875 +20180 0.854522705078125 +20181 0.866485595703125 +20182 0.86920166015625 +20183 0.8653564453125 +20184 0.857147216796875 +20185 0.766845703125 +20186 0.628509521484375 +20187 0.462127685546875 +20188 0.297210693359375 +20189 0.14862060546875 +20190 -0.00537109375 +20191 -0.15753173828125 +20192 -0.31304931640625 +20193 -0.48876953125 +20194 -0.6416015625 +20195 -0.751373291015625 +20196 -0.84619140625 +20197 -0.861297607421875 +20198 -0.863250732421875 +20199 -0.856597900390625 +20200 -0.7498779296875 +20201 -0.624542236328125 +20202 -0.47808837890625 +20203 -0.253387451171875 +20204 0.003692626953125 +20205 0.2257080078125 +20206 0.427154541015625 +20207 0.643218994140625 +20208 0.855926513671875 +20209 0.870361328125 +20210 0.870361328125 +20211 0.862762451171875 +20212 0.79669189453125 +20213 0.595794677734375 +20214 0.362152099609375 +20215 0.1270751953125 +20216 -0.086944580078125 +20217 -0.2784423828125 +20218 -0.484832763671875 +20219 -0.729583740234375 +20220 -0.86688232421875 +20221 -0.870391845703125 +20222 -0.86859130859375 +20223 -0.86279296875 +20224 -0.817962646484375 +20225 -0.6116943359375 +20226 -0.3128662109375 +20227 0.039398193359375 +20228 0.422821044921875 +20229 0.805145263671875 +20230 0.870361328125 +20231 0.870361328125 +20232 0.860015869140625 +20233 0.727935791015625 +20234 0.48114013671875 +20235 0.2059326171875 +20236 -0.06103515625 +20237 -0.29913330078125 +20238 -0.516204833984375 +20239 -0.7252197265625 +20240 -0.85980224609375 +20241 -0.870391845703125 +20242 -0.870391845703125 +20243 -0.858062744140625 +20244 -0.673004150390625 +20245 -0.42694091796875 +20246 -0.2100830078125 +20247 -0.0362548828125 +20248 0.10943603515625 +20249 0.23516845703125 +20250 0.373687744140625 +20251 0.517791748046875 +20252 0.602783203125 +20253 0.635711669921875 +20254 0.655181884765625 +20255 0.65948486328125 +20256 0.651275634765625 +20257 0.61846923828125 +20258 0.53753662109375 +20259 0.404144287109375 +20260 0.22186279296875 +20261 0.003997802734375 +20262 -0.22100830078125 +20263 -0.42449951171875 +20264 -0.579833984375 +20265 -0.641876220703125 +20266 -0.6177978515625 +20267 -0.575531005859375 +20268 -0.526336669921875 +20269 -0.42645263671875 +20270 -0.2581787109375 +20271 -0.068695068359375 +20272 0.09222412109375 +20273 0.232147216796875 +20274 0.3509521484375 +20275 0.410064697265625 +20276 0.372955322265625 +20277 0.2554931640625 +20278 0.10711669921875 +20279 -0.052886962890625 +20280 -0.186279296875 +20281 -0.23291015625 +20282 -0.209442138671875 +20283 -0.174163818359375 +20284 -0.126739501953125 +20285 -0.048126220703125 +20286 0.0426025390625 +20287 0.10748291015625 +20288 0.1409912109375 +20289 0.19708251953125 +20290 0.273651123046875 +20291 0.31768798828125 +20292 0.341094970703125 +20293 0.368011474609375 +20294 0.37249755859375 +20295 0.30072021484375 +20296 0.1517333984375 +20297 -0.01470947265625 +20298 -0.1883544921875 +20299 -0.372711181640625 +20300 -0.51397705078125 +20301 -0.57177734375 +20302 -0.53948974609375 +20303 -0.43511962890625 +20304 -0.2962646484375 +20305 -0.161102294921875 +20306 -0.0435791015625 +20307 0.060394287109375 +20308 0.13665771484375 +20309 0.170135498046875 +20310 0.16552734375 +20311 0.15728759765625 +20312 0.150787353515625 +20313 0.12200927734375 +20314 0.080108642578125 +20315 0.05126953125 +20316 0.062896728515625 +20317 0.09271240234375 +20318 0.092987060546875 +20319 0.07855224609375 +20320 0.06427001953125 +20321 0.0347900390625 +20322 -0.01171875 +20323 -0.056060791015625 +20324 -0.055511474609375 +20325 -0.010467529296875 +20326 0.02508544921875 +20327 0.025665283203125 +20328 0.017333984375 +20329 0.00189208984375 +20330 -0.03173828125 +20331 -0.071502685546875 +20332 -0.13543701171875 +20333 -0.219970703125 +20334 -0.300506591796875 +20335 -0.376312255859375 +20336 -0.416107177734375 +20337 -0.371124267578125 +20338 -0.242279052734375 +20339 -0.069732666015625 +20340 0.125640869140625 +20341 0.31268310546875 +20342 0.45501708984375 +20343 0.554779052734375 +20344 0.61065673828125 +20345 0.610931396484375 +20346 0.531463623046875 +20347 0.3883056640625 +20348 0.23468017578125 +20349 0.095245361328125 +20350 -0.00396728515625 +20351 -0.04852294921875 +20352 -0.055145263671875 +20353 -0.0758056640625 +20354 -0.138702392578125 +20355 -0.209197998046875 +20356 -0.289031982421875 +20357 -0.37884521484375 +20358 -0.456329345703125 +20359 -0.51641845703125 +20360 -0.519287109375 +20361 -0.458251953125 +20362 -0.384796142578125 +20363 -0.323699951171875 +20364 -0.269287109375 +20365 -0.1951904296875 +20366 -0.100006103515625 +20367 -0.01055908203125 +20368 0.1033935546875 +20369 0.24908447265625 +20370 0.373199462890625 +20371 0.45806884765625 +20372 0.511474609375 +20373 0.565399169921875 +20374 0.61138916015625 +20375 0.5897216796875 +20376 0.4906005859375 +20377 0.33148193359375 +20378 0.147796630859375 +20379 -0.01873779296875 +20380 -0.140289306640625 +20381 -0.191986083984375 +20382 -0.184295654296875 +20383 -0.161834716796875 +20384 -0.166595458984375 +20385 -0.19390869140625 +20386 -0.22442626953125 +20387 -0.279754638671875 +20388 -0.3389892578125 +20389 -0.3543701171875 +20390 -0.348175048828125 +20391 -0.32598876953125 +20392 -0.2581787109375 +20393 -0.139801025390625 +20394 0.014617919921875 +20395 0.144378662109375 +20396 0.221038818359375 +20397 0.27069091796875 +20398 0.294036865234375 +20399 0.311767578125 +20400 0.339141845703125 +20401 0.360260009765625 +20402 0.360504150390625 +20403 0.308380126953125 +20404 0.18170166015625 +20405 0.0047607421875 +20406 -0.17559814453125 +20407 -0.3143310546875 +20408 -0.36785888671875 +20409 -0.36248779296875 +20410 -0.343536376953125 +20411 -0.3018798828125 +20412 -0.231414794921875 +20413 -0.117645263671875 +20414 0.007049560546875 +20415 0.087982177734375 +20416 0.13946533203125 +20417 0.17425537109375 +20418 0.188201904296875 +20419 0.171234130859375 +20420 0.118438720703125 +20421 0.05706787109375 +20422 -0.010711669921875 +20423 -0.0914306640625 +20424 -0.162322998046875 +20425 -0.194549560546875 +20426 -0.1492919921875 +20427 -0.02166748046875 +20428 0.124053955078125 +20429 0.211151123046875 +20430 0.240447998046875 +20431 0.242218017578125 +20432 0.2257080078125 +20433 0.194366455078125 +20434 0.115509033203125 +20435 0.0128173828125 +20436 -0.053802490234375 +20437 -0.110626220703125 +20438 -0.199493408203125 +20439 -0.29437255859375 +20440 -0.33221435546875 +20441 -0.27972412109375 +20442 -0.185333251953125 +20443 -0.128204345703125 +20444 -0.115692138671875 +20445 -0.116455078125 +20446 -0.105926513671875 +20447 -0.053955078125 +20448 0.048797607421875 +20449 0.157318115234375 +20450 0.212005615234375 +20451 0.218475341796875 +20452 0.23724365234375 +20453 0.30535888671875 +20454 0.38128662109375 +20455 0.404449462890625 +20456 0.3944091796875 +20457 0.3885498046875 +20458 0.362640380859375 +20459 0.27362060546875 +20460 0.11712646484375 +20461 -0.054901123046875 +20462 -0.19085693359375 +20463 -0.28570556640625 +20464 -0.339263916015625 +20465 -0.3775634765625 +20466 -0.445709228515625 +20467 -0.535064697265625 +20468 -0.629058837890625 +20469 -0.697601318359375 +20470 -0.70391845703125 +20471 -0.6424560546875 +20472 -0.491241455078125 +20473 -0.265716552734375 +20474 -0.023712158203125 +20475 0.201751708984375 +20476 0.375823974609375 +20477 0.485076904296875 +20478 0.56884765625 +20479 0.634765625 +20480 0.63763427734375 +20481 0.5660400390625 +20482 0.4720458984375 +20483 0.40692138671875 +20484 0.3778076171875 +20485 0.376953125 +20486 0.371978759765625 +20487 0.313140869140625 +20488 0.184417724609375 +20489 0.011199951171875 +20490 -0.171051025390625 +20491 -0.33740234375 +20492 -0.47198486328125 +20493 -0.560394287109375 +20494 -0.58056640625 +20495 -0.54754638671875 +20496 -0.508575439453125 +20497 -0.459503173828125 +20498 -0.394378662109375 +20499 -0.35260009765625 +20500 -0.31170654296875 +20501 -0.197418212890625 +20502 -0.007965087890625 +20503 0.207489013671875 +20504 0.409210205078125 +20505 0.57208251953125 +20506 0.66595458984375 +20507 0.65875244140625 +20508 0.56744384765625 +20509 0.431396484375 +20510 0.29443359375 +20511 0.182464599609375 +20512 0.06365966796875 +20513 -0.075958251953125 +20514 -0.189422607421875 +20515 -0.271942138671875 +20516 -0.342529296875 +20517 -0.364166259765625 +20518 -0.327239990234375 +20519 -0.2769775390625 +20520 -0.253692626953125 +20521 -0.24365234375 +20522 -0.1983642578125 +20523 -0.116241455078125 +20524 -0.036834716796875 +20525 0.034881591796875 +20526 0.09124755859375 +20527 0.10888671875 +20528 0.125518798828125 +20529 0.15771484375 +20530 0.17828369140625 +20531 0.17108154296875 +20532 0.129974365234375 +20533 0.082427978515625 +20534 0.027679443359375 +20535 -0.065643310546875 +20536 -0.15936279296875 +20537 -0.21307373046875 +20538 -0.234649658203125 +20539 -0.2001953125 +20540 -0.119171142578125 +20541 -0.024749755859375 +20542 0.085784912109375 +20543 0.178131103515625 +20544 0.215576171875 +20545 0.211456298828125 +20546 0.17523193359375 +20547 0.128753662109375 +20548 0.1019287109375 +20549 0.0743408203125 +20550 0.04327392578125 +20551 0.038177490234375 +20552 0.076263427734375 +20553 0.14105224609375 +20554 0.186431884765625 +20555 0.188812255859375 +20556 0.1390380859375 +20557 0.041778564453125 +20558 -0.079437255859375 +20559 -0.219390869140625 +20560 -0.367828369140625 +20561 -0.494873046875 +20562 -0.556243896484375 +20563 -0.508697509765625 +20564 -0.3756103515625 +20565 -0.218902587890625 +20566 -0.063751220703125 +20567 0.091552734375 +20568 0.23602294921875 +20569 0.342987060546875 +20570 0.39520263671875 +20571 0.389373779296875 +20572 0.324249267578125 +20573 0.224090576171875 +20574 0.124267578125 +20575 0.037078857421875 +20576 -0.010101318359375 +20577 -0.019439697265625 +20578 -0.022796630859375 +20579 -0.001556396484375 +20580 0.056304931640625 +20581 0.106719970703125 +20582 0.096893310546875 +20583 0.042694091796875 +20584 -0.018035888671875 +20585 -0.07586669921875 +20586 -0.11944580078125 +20587 -0.15972900390625 +20588 -0.202606201171875 +20589 -0.24859619140625 +20590 -0.30517578125 +20591 -0.36212158203125 +20592 -0.39141845703125 +20593 -0.35528564453125 +20594 -0.249969482421875 +20595 -0.092864990234375 +20596 0.08905029296875 +20597 0.2352294921875 +20598 0.318817138671875 +20599 0.358642578125 +20600 0.347747802734375 +20601 0.28564453125 +20602 0.223175048828125 +20603 0.196746826171875 +20604 0.179840087890625 +20605 0.155548095703125 +20606 0.151214599609375 +20607 0.156951904296875 +20608 0.13177490234375 +20609 0.100799560546875 +20610 0.087127685546875 +20611 0.05487060546875 +20612 -0.009002685546875 +20613 -0.10400390625 +20614 -0.229400634765625 +20615 -0.35552978515625 +20616 -0.441925048828125 +20617 -0.473846435546875 +20618 -0.464813232421875 +20619 -0.419097900390625 +20620 -0.334320068359375 +20621 -0.227935791015625 +20622 -0.12347412109375 +20623 -0.02764892578125 +20624 0.077667236328125 +20625 0.2132568359375 +20626 0.38885498046875 +20627 0.582794189453125 +20628 0.734039306640625 +20629 0.800140380859375 +20630 0.7783203125 +20631 0.6651611328125 +20632 0.45965576171875 +20633 0.199188232421875 +20634 -0.050689697265625 +20635 -0.23297119140625 +20636 -0.33013916015625 +20637 -0.368408203125 +20638 -0.378936767578125 +20639 -0.376983642578125 +20640 -0.37969970703125 +20641 -0.391510009765625 +20642 -0.385345458984375 +20643 -0.3419189453125 +20644 -0.28289794921875 +20645 -0.251617431640625 +20646 -0.266143798828125 +20647 -0.273345947265625 +20648 -0.216796875 +20649 -0.128265380859375 +20650 -0.068145751953125 +20651 -0.0430908203125 +20652 -0.024444580078125 +20653 0.020721435546875 +20654 0.124481201171875 +20655 0.25787353515625 +20656 0.379119873046875 +20657 0.47991943359375 +20658 0.5281982421875 +20659 0.511138916015625 +20660 0.456207275390625 +20661 0.407470703125 +20662 0.383758544921875 +20663 0.35687255859375 +20664 0.31182861328125 +20665 0.250885009765625 +20666 0.1654052734375 +20667 0.035247802734375 +20668 -0.142059326171875 +20669 -0.33563232421875 +20670 -0.5345458984375 +20671 -0.72186279296875 +20672 -0.836669921875 +20673 -0.8326416015625 +20674 -0.7296142578125 +20675 -0.582550048828125 +20676 -0.440093994140625 +20677 -0.324310302734375 +20678 -0.20147705078125 +20679 -0.044647216796875 +20680 0.103973388671875 +20681 0.202392578125 +20682 0.264495849609375 +20683 0.338897705078125 +20684 0.443817138671875 +20685 0.545074462890625 +20686 0.6173095703125 +20687 0.6524658203125 +20688 0.66339111328125 +20689 0.6561279296875 +20690 0.606781005859375 +20691 0.501190185546875 +20692 0.352783203125 +20693 0.176544189453125 +20694 -0.034820556640625 +20695 -0.258209228515625 +20696 -0.44244384765625 +20697 -0.5753173828125 +20698 -0.65203857421875 +20699 -0.641632080078125 +20700 -0.562164306640625 +20701 -0.458038330078125 +20702 -0.350555419921875 +20703 -0.260528564453125 +20704 -0.192108154296875 +20705 -0.141937255859375 +20706 -0.1021728515625 +20707 -0.062896728515625 +20708 -0.011932373046875 +20709 0.062835693359375 +20710 0.148712158203125 +20711 0.241729736328125 +20712 0.34912109375 +20713 0.457305908203125 +20714 0.54388427734375 +20715 0.5728759765625 +20716 0.506591796875 +20717 0.351226806640625 +20718 0.146514892578125 +20719 -0.05523681640625 +20720 -0.21624755859375 +20721 -0.334930419921875 +20722 -0.402984619140625 +20723 -0.4412841796875 +20724 -0.49578857421875 +20725 -0.5601806640625 +20726 -0.600738525390625 +20727 -0.584228515625 +20728 -0.47930908203125 +20729 -0.27935791015625 +20730 -0.0089111328125 +20731 0.268798828125 +20732 0.482818603515625 +20733 0.60369873046875 +20734 0.650421142578125 +20735 0.66400146484375 +20736 0.6414794921875 +20737 0.572540283203125 +20738 0.498138427734375 +20739 0.439453125 +20740 0.375518798828125 +20741 0.274505615234375 +20742 0.1087646484375 +20743 -0.099395751953125 +20744 -0.3182373046875 +20745 -0.5489501953125 +20746 -0.7738037109375 +20747 -0.86383056640625 +20748 -0.870391845703125 +20749 -0.86895751953125 +20750 -0.861053466796875 +20751 -0.765869140625 +20752 -0.5301513671875 +20753 -0.214691162109375 +20754 0.137359619140625 +20755 0.474822998046875 +20756 0.76239013671875 +20757 0.867462158203125 +20758 0.870361328125 +20759 0.86480712890625 +20760 0.831817626953125 +20761 0.677581787109375 +20762 0.495880126953125 +20763 0.30767822265625 +20764 0.116180419921875 +20765 -0.110748291015625 +20766 -0.381805419921875 +20767 -0.6572265625 +20768 -0.857421875 +20769 -0.870391845703125 +20770 -0.870391845703125 +20771 -0.86444091796875 +20772 -0.85723876953125 +20773 -0.790008544921875 +20774 -0.62847900390625 +20775 -0.3956298828125 +20776 -0.126708984375 +20777 0.150115966796875 +20778 0.424041748046875 +20779 0.670623779296875 +20780 0.854522705078125 +20781 0.866485595703125 +20782 0.86920166015625 +20783 0.8653564453125 +20784 0.857147216796875 +20785 0.766845703125 +20786 0.628509521484375 +20787 0.462127685546875 +20788 0.297210693359375 +20789 0.14862060546875 +20790 -0.00537109375 +20791 -0.15753173828125 +20792 -0.31304931640625 +20793 -0.48876953125 +20794 -0.6416015625 +20795 -0.751373291015625 +20796 -0.84619140625 +20797 -0.861297607421875 +20798 -0.863250732421875 +20799 -0.856597900390625 +20800 -0.7498779296875 +20801 -0.624542236328125 +20802 -0.47808837890625 +20803 -0.253387451171875 +20804 0.003692626953125 +20805 0.2257080078125 +20806 0.427154541015625 +20807 0.643218994140625 +20808 0.855926513671875 +20809 0.870361328125 +20810 0.870361328125 +20811 0.862762451171875 +20812 0.79669189453125 +20813 0.595794677734375 +20814 0.362152099609375 +20815 0.1270751953125 +20816 -0.086944580078125 +20817 -0.2784423828125 +20818 -0.484832763671875 +20819 -0.729583740234375 +20820 -0.86688232421875 +20821 -0.870391845703125 +20822 -0.86859130859375 +20823 -0.86279296875 +20824 -0.817962646484375 +20825 -0.6116943359375 +20826 -0.3128662109375 +20827 0.039398193359375 +20828 0.422821044921875 +20829 0.805145263671875 +20830 0.870361328125 +20831 0.870361328125 +20832 0.860015869140625 +20833 0.727935791015625 +20834 0.48114013671875 +20835 0.2059326171875 +20836 -0.06103515625 +20837 -0.29913330078125 +20838 -0.516204833984375 +20839 -0.7252197265625 +20840 -0.85980224609375 +20841 -0.870391845703125 +20842 -0.870391845703125 +20843 -0.858062744140625 +20844 -0.673004150390625 +20845 -0.42694091796875 +20846 -0.2100830078125 +20847 -0.0362548828125 +20848 0.10943603515625 +20849 0.23516845703125 +20850 0.373687744140625 +20851 0.517791748046875 +20852 0.602783203125 +20853 0.635711669921875 +20854 0.655181884765625 +20855 0.65948486328125 +20856 0.651275634765625 +20857 0.61846923828125 +20858 0.53753662109375 +20859 0.404144287109375 +20860 0.22186279296875 +20861 0.003997802734375 +20862 -0.22100830078125 +20863 -0.42449951171875 +20864 -0.579833984375 +20865 -0.641876220703125 +20866 -0.6177978515625 +20867 -0.575531005859375 +20868 -0.526336669921875 +20869 -0.42645263671875 +20870 -0.2581787109375 +20871 -0.068695068359375 +20872 0.09222412109375 +20873 0.232147216796875 +20874 0.3509521484375 +20875 0.410064697265625 +20876 0.372955322265625 +20877 0.2554931640625 +20878 0.10711669921875 +20879 -0.052886962890625 +20880 -0.186279296875 +20881 -0.23291015625 +20882 -0.209442138671875 +20883 -0.174163818359375 +20884 -0.126739501953125 +20885 -0.048126220703125 +20886 0.0426025390625 +20887 0.10748291015625 +20888 0.1409912109375 +20889 0.19708251953125 +20890 0.273651123046875 +20891 0.31768798828125 +20892 0.341094970703125 +20893 0.368011474609375 +20894 0.37249755859375 +20895 0.30072021484375 +20896 0.1517333984375 +20897 -0.01470947265625 +20898 -0.1883544921875 +20899 -0.372711181640625 +20900 -0.51397705078125 +20901 -0.57177734375 +20902 -0.53948974609375 +20903 -0.43511962890625 +20904 -0.2962646484375 +20905 -0.161102294921875 +20906 -0.0435791015625 +20907 0.060394287109375 +20908 0.13665771484375 +20909 0.170135498046875 +20910 0.16552734375 +20911 0.15728759765625 +20912 0.150787353515625 +20913 0.12200927734375 +20914 0.080108642578125 +20915 0.05126953125 +20916 0.062896728515625 +20917 0.09271240234375 +20918 0.092987060546875 +20919 0.07855224609375 +20920 0.06427001953125 +20921 0.0347900390625 +20922 -0.01171875 +20923 -0.056060791015625 +20924 -0.055511474609375 +20925 -0.010467529296875 +20926 0.02508544921875 +20927 0.025665283203125 +20928 0.017333984375 +20929 0.00189208984375 +20930 -0.03173828125 +20931 -0.071502685546875 +20932 -0.13543701171875 +20933 -0.219970703125 +20934 -0.300506591796875 +20935 -0.376312255859375 +20936 -0.416107177734375 +20937 -0.371124267578125 +20938 -0.242279052734375 +20939 -0.069732666015625 +20940 0.125640869140625 +20941 0.31268310546875 +20942 0.45501708984375 +20943 0.554779052734375 +20944 0.61065673828125 +20945 0.610931396484375 +20946 0.531463623046875 +20947 0.3883056640625 +20948 0.23468017578125 +20949 0.095245361328125 +20950 -0.00396728515625 +20951 -0.04852294921875 +20952 -0.055145263671875 +20953 -0.0758056640625 +20954 -0.138702392578125 +20955 -0.209197998046875 +20956 -0.289031982421875 +20957 -0.37884521484375 +20958 -0.456329345703125 +20959 -0.51641845703125 +20960 -0.519287109375 +20961 -0.458251953125 +20962 -0.384796142578125 +20963 -0.323699951171875 +20964 -0.269287109375 +20965 -0.1951904296875 +20966 -0.100006103515625 +20967 -0.01055908203125 +20968 0.1033935546875 +20969 0.24908447265625 +20970 0.373199462890625 +20971 0.45806884765625 +20972 0.511474609375 +20973 0.565399169921875 +20974 0.61138916015625 +20975 0.5897216796875 +20976 0.4906005859375 +20977 0.33148193359375 +20978 0.147796630859375 +20979 -0.01873779296875 +20980 -0.140289306640625 +20981 -0.191986083984375 +20982 -0.184295654296875 +20983 -0.161834716796875 +20984 -0.166595458984375 +20985 -0.19390869140625 +20986 -0.22442626953125 +20987 -0.279754638671875 +20988 -0.3389892578125 +20989 -0.3543701171875 +20990 -0.348175048828125 +20991 -0.32598876953125 +20992 -0.2581787109375 +20993 -0.139801025390625 +20994 0.014617919921875 +20995 0.144378662109375 +20996 0.221038818359375 +20997 0.27069091796875 +20998 0.294036865234375 +20999 0.311767578125 +21000 0.339141845703125 +21001 0.360260009765625 +21002 0.360504150390625 +21003 0.308380126953125 +21004 0.18170166015625 +21005 0.0047607421875 +21006 -0.17559814453125 +21007 -0.3143310546875 +21008 -0.36785888671875 +21009 -0.36248779296875 +21010 -0.343536376953125 +21011 -0.3018798828125 +21012 -0.231414794921875 +21013 -0.117645263671875 +21014 0.007049560546875 +21015 0.087982177734375 +21016 0.13946533203125 +21017 0.17425537109375 +21018 0.188201904296875 +21019 0.171234130859375 +21020 0.118438720703125 +21021 0.05706787109375 +21022 -0.010711669921875 +21023 -0.0914306640625 +21024 -0.162322998046875 +21025 -0.194549560546875 +21026 -0.1492919921875 +21027 -0.02166748046875 +21028 0.124053955078125 +21029 0.211151123046875 +21030 0.240447998046875 +21031 0.242218017578125 +21032 0.2257080078125 +21033 0.194366455078125 +21034 0.115509033203125 +21035 0.0128173828125 +21036 -0.053802490234375 +21037 -0.110626220703125 +21038 -0.199493408203125 +21039 -0.29437255859375 +21040 -0.33221435546875 +21041 -0.27972412109375 +21042 -0.185333251953125 +21043 -0.128204345703125 +21044 -0.115692138671875 +21045 -0.116455078125 +21046 -0.105926513671875 +21047 -0.053955078125 +21048 0.048797607421875 +21049 0.157318115234375 +21050 0.212005615234375 +21051 0.218475341796875 +21052 0.23724365234375 +21053 0.30535888671875 +21054 0.38128662109375 +21055 0.404449462890625 +21056 0.3944091796875 +21057 0.3885498046875 +21058 0.362640380859375 +21059 0.27362060546875 +21060 0.11712646484375 +21061 -0.054901123046875 +21062 -0.19085693359375 +21063 -0.28570556640625 +21064 -0.339263916015625 +21065 -0.3775634765625 +21066 -0.445709228515625 +21067 -0.535064697265625 +21068 -0.629058837890625 +21069 -0.697601318359375 +21070 -0.70391845703125 +21071 -0.6424560546875 +21072 -0.491241455078125 +21073 -0.265716552734375 +21074 -0.023712158203125 +21075 0.201751708984375 +21076 0.375823974609375 +21077 0.485076904296875 +21078 0.56884765625 +21079 0.634765625 +21080 0.63763427734375 +21081 0.5660400390625 +21082 0.4720458984375 +21083 0.40692138671875 +21084 0.3778076171875 +21085 0.376953125 +21086 0.371978759765625 +21087 0.313140869140625 +21088 0.184417724609375 +21089 0.011199951171875 +21090 -0.171051025390625 +21091 -0.33740234375 +21092 -0.47198486328125 +21093 -0.560394287109375 +21094 -0.58056640625 +21095 -0.54754638671875 +21096 -0.508575439453125 +21097 -0.459503173828125 +21098 -0.394378662109375 +21099 -0.35260009765625 +21100 -0.31170654296875 +21101 -0.197418212890625 +21102 -0.007965087890625 +21103 0.207489013671875 +21104 0.409210205078125 +21105 0.57208251953125 +21106 0.66595458984375 +21107 0.65875244140625 +21108 0.56744384765625 +21109 0.431396484375 +21110 0.29443359375 +21111 0.182464599609375 +21112 0.06365966796875 +21113 -0.075958251953125 +21114 -0.189422607421875 +21115 -0.271942138671875 +21116 -0.342529296875 +21117 -0.364166259765625 +21118 -0.327239990234375 +21119 -0.2769775390625 +21120 -0.253692626953125 +21121 -0.24365234375 +21122 -0.1983642578125 +21123 -0.116241455078125 +21124 -0.036834716796875 +21125 0.034881591796875 +21126 0.09124755859375 +21127 0.10888671875 +21128 0.125518798828125 +21129 0.15771484375 +21130 0.17828369140625 +21131 0.17108154296875 +21132 0.129974365234375 +21133 0.082427978515625 +21134 0.027679443359375 +21135 -0.065643310546875 +21136 -0.15936279296875 +21137 -0.21307373046875 +21138 -0.234649658203125 +21139 -0.2001953125 +21140 -0.119171142578125 +21141 -0.024749755859375 +21142 0.085784912109375 +21143 0.178131103515625 +21144 0.215576171875 +21145 0.211456298828125 +21146 0.17523193359375 +21147 0.128753662109375 +21148 0.1019287109375 +21149 0.0743408203125 +21150 0.04327392578125 +21151 0.038177490234375 +21152 0.076263427734375 +21153 0.14105224609375 +21154 0.186431884765625 +21155 0.188812255859375 +21156 0.1390380859375 +21157 0.041778564453125 +21158 -0.079437255859375 +21159 -0.219390869140625 +21160 -0.367828369140625 +21161 -0.494873046875 +21162 -0.556243896484375 +21163 -0.508697509765625 +21164 -0.3756103515625 +21165 -0.218902587890625 +21166 -0.063751220703125 +21167 0.091552734375 +21168 0.23602294921875 +21169 0.342987060546875 +21170 0.39520263671875 +21171 0.389373779296875 +21172 0.324249267578125 +21173 0.224090576171875 +21174 0.124267578125 +21175 0.037078857421875 +21176 -0.010101318359375 +21177 -0.019439697265625 +21178 -0.022796630859375 +21179 -0.001556396484375 +21180 0.056304931640625 +21181 0.106719970703125 +21182 0.096893310546875 +21183 0.042694091796875 +21184 -0.018035888671875 +21185 -0.07586669921875 +21186 -0.11944580078125 +21187 -0.15972900390625 +21188 -0.202606201171875 +21189 -0.24859619140625 +21190 -0.30517578125 +21191 -0.36212158203125 +21192 -0.39141845703125 +21193 -0.35528564453125 +21194 -0.249969482421875 +21195 -0.092864990234375 +21196 0.08905029296875 +21197 0.2352294921875 +21198 0.318817138671875 +21199 0.358642578125 +21200 0.347747802734375 +21201 0.28564453125 +21202 0.223175048828125 +21203 0.196746826171875 +21204 0.179840087890625 +21205 0.155548095703125 +21206 0.151214599609375 +21207 0.156951904296875 +21208 0.13177490234375 +21209 0.100799560546875 +21210 0.087127685546875 +21211 0.05487060546875 +21212 -0.009002685546875 +21213 -0.10400390625 +21214 -0.229400634765625 +21215 -0.35552978515625 +21216 -0.441925048828125 +21217 -0.473846435546875 +21218 -0.464813232421875 +21219 -0.419097900390625 +21220 -0.334320068359375 +21221 -0.227935791015625 +21222 -0.12347412109375 +21223 -0.02764892578125 +21224 0.077667236328125 +21225 0.2132568359375 +21226 0.38885498046875 +21227 0.582794189453125 +21228 0.734039306640625 +21229 0.800140380859375 +21230 0.7783203125 +21231 0.6651611328125 +21232 0.45965576171875 +21233 0.199188232421875 +21234 -0.050689697265625 +21235 -0.23297119140625 +21236 -0.33013916015625 +21237 -0.368408203125 +21238 -0.378936767578125 +21239 -0.376983642578125 +21240 -0.37969970703125 +21241 -0.391510009765625 +21242 -0.385345458984375 +21243 -0.3419189453125 +21244 -0.28289794921875 +21245 -0.251617431640625 +21246 -0.266143798828125 +21247 -0.273345947265625 +21248 -0.216796875 +21249 -0.128265380859375 +21250 -0.068145751953125 +21251 -0.0430908203125 +21252 -0.024444580078125 +21253 0.020721435546875 +21254 0.124481201171875 +21255 0.25787353515625 +21256 0.379119873046875 +21257 0.47991943359375 +21258 0.5281982421875 +21259 0.511138916015625 +21260 0.456207275390625 +21261 0.407470703125 +21262 0.383758544921875 +21263 0.35687255859375 +21264 0.31182861328125 +21265 0.250885009765625 +21266 0.1654052734375 +21267 0.035247802734375 +21268 -0.142059326171875 +21269 -0.33563232421875 +21270 -0.5345458984375 +21271 -0.72186279296875 +21272 -0.836669921875 +21273 -0.8326416015625 +21274 -0.7296142578125 +21275 -0.582550048828125 +21276 -0.440093994140625 +21277 -0.324310302734375 +21278 -0.20147705078125 +21279 -0.044647216796875 +21280 0.103973388671875 +21281 0.202392578125 +21282 0.264495849609375 +21283 0.338897705078125 +21284 0.443817138671875 +21285 0.545074462890625 +21286 0.6173095703125 +21287 0.6524658203125 +21288 0.66339111328125 +21289 0.6561279296875 +21290 0.606781005859375 +21291 0.501190185546875 +21292 0.352783203125 +21293 0.176544189453125 +21294 -0.034820556640625 +21295 -0.258209228515625 +21296 -0.44244384765625 +21297 -0.5753173828125 +21298 -0.65203857421875 +21299 -0.641632080078125 +21300 -0.562164306640625 +21301 -0.458038330078125 +21302 -0.350555419921875 +21303 -0.260528564453125 +21304 -0.192108154296875 +21305 -0.141937255859375 +21306 -0.1021728515625 +21307 -0.062896728515625 +21308 -0.011932373046875 +21309 0.062835693359375 +21310 0.148712158203125 +21311 0.241729736328125 +21312 0.34912109375 +21313 0.457305908203125 +21314 0.54388427734375 +21315 0.5728759765625 +21316 0.506591796875 +21317 0.351226806640625 +21318 0.146514892578125 +21319 -0.05523681640625 +21320 -0.21624755859375 +21321 -0.334930419921875 +21322 -0.402984619140625 +21323 -0.4412841796875 +21324 -0.49578857421875 +21325 -0.5601806640625 +21326 -0.600738525390625 +21327 -0.584228515625 +21328 -0.47930908203125 +21329 -0.27935791015625 +21330 -0.0089111328125 +21331 0.268798828125 +21332 0.482818603515625 +21333 0.60369873046875 +21334 0.650421142578125 +21335 0.66400146484375 +21336 0.6414794921875 +21337 0.572540283203125 +21338 0.498138427734375 +21339 0.439453125 +21340 0.375518798828125 +21341 0.274505615234375 +21342 0.1087646484375 +21343 -0.099395751953125 +21344 -0.3182373046875 +21345 -0.5489501953125 +21346 -0.7738037109375 +21347 -0.86383056640625 +21348 -0.870391845703125 +21349 -0.86895751953125 +21350 -0.861053466796875 +21351 -0.765869140625 +21352 -0.5301513671875 +21353 -0.214691162109375 +21354 0.137359619140625 +21355 0.474822998046875 +21356 0.76239013671875 +21357 0.867462158203125 +21358 0.870361328125 +21359 0.86480712890625 +21360 0.831817626953125 +21361 0.677581787109375 +21362 0.495880126953125 +21363 0.30767822265625 +21364 0.116180419921875 +21365 -0.110748291015625 +21366 -0.381805419921875 +21367 -0.6572265625 +21368 -0.857421875 +21369 -0.870391845703125 +21370 -0.870391845703125 +21371 -0.86444091796875 +21372 -0.85723876953125 +21373 -0.790008544921875 +21374 -0.62847900390625 +21375 -0.3956298828125 +21376 -0.126708984375 +21377 0.150115966796875 +21378 0.424041748046875 +21379 0.670623779296875 +21380 0.854522705078125 +21381 0.866485595703125 +21382 0.86920166015625 +21383 0.8653564453125 +21384 0.857147216796875 +21385 0.766845703125 +21386 0.628509521484375 +21387 0.462127685546875 +21388 0.297210693359375 +21389 0.14862060546875 +21390 -0.00537109375 +21391 -0.15753173828125 +21392 -0.31304931640625 +21393 -0.48876953125 +21394 -0.6416015625 +21395 -0.751373291015625 +21396 -0.84619140625 +21397 -0.861297607421875 +21398 -0.863250732421875 +21399 -0.856597900390625 +21400 -0.7498779296875 +21401 -0.624542236328125 +21402 -0.47808837890625 +21403 -0.253387451171875 +21404 0.003692626953125 +21405 0.2257080078125 +21406 0.427154541015625 +21407 0.643218994140625 +21408 0.855926513671875 +21409 0.870361328125 +21410 0.870361328125 +21411 0.862762451171875 +21412 0.79669189453125 +21413 0.595794677734375 +21414 0.362152099609375 +21415 0.1270751953125 +21416 -0.086944580078125 +21417 -0.2784423828125 +21418 -0.484832763671875 +21419 -0.729583740234375 +21420 -0.86688232421875 +21421 -0.870391845703125 +21422 -0.86859130859375 +21423 -0.86279296875 +21424 -0.817962646484375 +21425 -0.6116943359375 +21426 -0.3128662109375 +21427 0.039398193359375 +21428 0.422821044921875 +21429 0.805145263671875 +21430 0.870361328125 +21431 0.870361328125 +21432 0.860015869140625 +21433 0.727935791015625 +21434 0.48114013671875 +21435 0.2059326171875 +21436 -0.06103515625 +21437 -0.29913330078125 +21438 -0.516204833984375 +21439 -0.7252197265625 +21440 -0.85980224609375 +21441 -0.870391845703125 +21442 -0.870391845703125 +21443 -0.858062744140625 +21444 -0.673004150390625 +21445 -0.42694091796875 +21446 -0.2100830078125 +21447 -0.0362548828125 +21448 0.10943603515625 +21449 0.23516845703125 +21450 0.373687744140625 +21451 0.517791748046875 +21452 0.602783203125 +21453 0.635711669921875 +21454 0.655181884765625 +21455 0.65948486328125 +21456 0.651275634765625 +21457 0.61846923828125 +21458 0.53753662109375 +21459 0.404144287109375 +21460 0.22186279296875 +21461 0.003997802734375 +21462 -0.22100830078125 +21463 -0.42449951171875 +21464 -0.579833984375 +21465 -0.641876220703125 +21466 -0.6177978515625 +21467 -0.575531005859375 +21468 -0.526336669921875 +21469 -0.42645263671875 +21470 -0.2581787109375 +21471 -0.068695068359375 +21472 0.09222412109375 +21473 0.232147216796875 +21474 0.3509521484375 +21475 0.410064697265625 +21476 0.372955322265625 +21477 0.2554931640625 +21478 0.10711669921875 +21479 -0.052886962890625 +21480 -0.186279296875 +21481 -0.23291015625 +21482 -0.209442138671875 +21483 -0.174163818359375 +21484 -0.126739501953125 +21485 -0.048126220703125 +21486 0.0426025390625 +21487 0.10748291015625 +21488 0.1409912109375 +21489 0.19708251953125 +21490 0.273651123046875 +21491 0.31768798828125 +21492 0.341094970703125 +21493 0.368011474609375 +21494 0.37249755859375 +21495 0.30072021484375 +21496 0.1517333984375 +21497 -0.01470947265625 +21498 -0.1883544921875 +21499 -0.372711181640625 +21500 -0.51397705078125 +21501 -0.57177734375 +21502 -0.53948974609375 +21503 -0.43511962890625 +21504 -0.2962646484375 +21505 -0.161102294921875 +21506 -0.0435791015625 +21507 0.060394287109375 +21508 0.13665771484375 +21509 0.170135498046875 +21510 0.16552734375 +21511 0.15728759765625 +21512 0.150787353515625 +21513 0.12200927734375 +21514 0.080108642578125 +21515 0.05126953125 +21516 0.062896728515625 +21517 0.09271240234375 +21518 0.092987060546875 +21519 0.07855224609375 +21520 0.06427001953125 +21521 0.0347900390625 +21522 -0.01171875 +21523 -0.056060791015625 +21524 -0.055511474609375 +21525 -0.010467529296875 +21526 0.02508544921875 +21527 0.025665283203125 +21528 0.017333984375 +21529 0.00189208984375 +21530 -0.03173828125 +21531 -0.071502685546875 +21532 -0.13543701171875 +21533 -0.219970703125 +21534 -0.300506591796875 +21535 -0.376312255859375 +21536 -0.416107177734375 +21537 -0.371124267578125 +21538 -0.242279052734375 +21539 -0.069732666015625 +21540 0.125640869140625 +21541 0.31268310546875 +21542 0.45501708984375 +21543 0.554779052734375 +21544 0.61065673828125 +21545 0.610931396484375 +21546 0.531463623046875 +21547 0.3883056640625 +21548 0.23468017578125 +21549 0.095245361328125 +21550 -0.00396728515625 +21551 -0.04852294921875 +21552 -0.055145263671875 +21553 -0.0758056640625 +21554 -0.138702392578125 +21555 -0.209197998046875 +21556 -0.289031982421875 +21557 -0.37884521484375 +21558 -0.456329345703125 +21559 -0.51641845703125 +21560 -0.519287109375 +21561 -0.458251953125 +21562 -0.384796142578125 +21563 -0.323699951171875 +21564 -0.269287109375 +21565 -0.1951904296875 +21566 -0.100006103515625 +21567 -0.01055908203125 +21568 0.1033935546875 +21569 0.24908447265625 +21570 0.373199462890625 +21571 0.45806884765625 +21572 0.511474609375 +21573 0.565399169921875 +21574 0.61138916015625 +21575 0.5897216796875 +21576 0.4906005859375 +21577 0.33148193359375 +21578 0.147796630859375 +21579 -0.01873779296875 +21580 -0.140289306640625 +21581 -0.191986083984375 +21582 -0.184295654296875 +21583 -0.161834716796875 +21584 -0.166595458984375 +21585 -0.19390869140625 +21586 -0.22442626953125 +21587 -0.279754638671875 +21588 -0.3389892578125 +21589 -0.3543701171875 +21590 -0.348175048828125 +21591 -0.32598876953125 +21592 -0.2581787109375 +21593 -0.139801025390625 +21594 0.014617919921875 +21595 0.144378662109375 +21596 0.221038818359375 +21597 0.27069091796875 +21598 0.294036865234375 +21599 0.311767578125 +21600 0.339141845703125 +21601 0.360260009765625 +21602 0.360504150390625 +21603 0.308380126953125 +21604 0.18170166015625 +21605 0.0047607421875 +21606 -0.17559814453125 +21607 -0.3143310546875 +21608 -0.36785888671875 +21609 -0.36248779296875 +21610 -0.343536376953125 +21611 -0.3018798828125 +21612 -0.231414794921875 +21613 -0.117645263671875 +21614 0.007049560546875 +21615 0.087982177734375 +21616 0.13946533203125 +21617 0.17425537109375 +21618 0.188201904296875 +21619 0.171234130859375 +21620 0.118438720703125 +21621 0.05706787109375 +21622 -0.010711669921875 +21623 -0.0914306640625 +21624 -0.162322998046875 +21625 -0.194549560546875 +21626 -0.1492919921875 +21627 -0.02166748046875 +21628 0.124053955078125 +21629 0.211151123046875 +21630 0.240447998046875 +21631 0.242218017578125 +21632 0.2257080078125 +21633 0.194366455078125 +21634 0.115509033203125 +21635 0.0128173828125 +21636 -0.053802490234375 +21637 -0.110626220703125 +21638 -0.199493408203125 +21639 -0.29437255859375 +21640 -0.33221435546875 +21641 -0.27972412109375 +21642 -0.185333251953125 +21643 -0.128204345703125 +21644 -0.115692138671875 +21645 -0.116455078125 +21646 -0.105926513671875 +21647 -0.053955078125 +21648 0.048797607421875 +21649 0.157318115234375 +21650 0.212005615234375 +21651 0.218475341796875 +21652 0.23724365234375 +21653 0.30535888671875 +21654 0.38128662109375 +21655 0.404449462890625 +21656 0.3944091796875 +21657 0.3885498046875 +21658 0.362640380859375 +21659 0.27362060546875 +21660 0.11712646484375 +21661 -0.054901123046875 +21662 -0.19085693359375 +21663 -0.28570556640625 +21664 -0.339263916015625 +21665 -0.3775634765625 +21666 -0.445709228515625 +21667 -0.535064697265625 +21668 -0.629058837890625 +21669 -0.697601318359375 +21670 -0.70391845703125 +21671 -0.6424560546875 +21672 -0.491241455078125 +21673 -0.265716552734375 +21674 -0.023712158203125 +21675 0.201751708984375 +21676 0.375823974609375 +21677 0.485076904296875 +21678 0.56884765625 +21679 0.634765625 +21680 0.63763427734375 +21681 0.5660400390625 +21682 0.4720458984375 +21683 0.40692138671875 +21684 0.3778076171875 +21685 0.376953125 +21686 0.371978759765625 +21687 0.313140869140625 +21688 0.184417724609375 +21689 0.011199951171875 +21690 -0.171051025390625 +21691 -0.33740234375 +21692 -0.47198486328125 +21693 -0.560394287109375 +21694 -0.58056640625 +21695 -0.54754638671875 +21696 -0.508575439453125 +21697 -0.459503173828125 +21698 -0.394378662109375 +21699 -0.35260009765625 +21700 -0.31170654296875 +21701 -0.197418212890625 +21702 -0.007965087890625 +21703 0.207489013671875 +21704 0.409210205078125 +21705 0.57208251953125 +21706 0.66595458984375 +21707 0.65875244140625 +21708 0.56744384765625 +21709 0.431396484375 +21710 0.29443359375 +21711 0.182464599609375 +21712 0.06365966796875 +21713 -0.075958251953125 +21714 -0.189422607421875 +21715 -0.271942138671875 +21716 -0.342529296875 +21717 -0.364166259765625 +21718 -0.327239990234375 +21719 -0.2769775390625 +21720 -0.253692626953125 +21721 -0.24365234375 +21722 -0.1983642578125 +21723 -0.116241455078125 +21724 -0.036834716796875 +21725 0.034881591796875 +21726 0.09124755859375 +21727 0.10888671875 +21728 0.125518798828125 +21729 0.15771484375 +21730 0.17828369140625 +21731 0.17108154296875 +21732 0.129974365234375 +21733 0.082427978515625 +21734 0.027679443359375 +21735 -0.065643310546875 +21736 -0.15936279296875 +21737 -0.21307373046875 +21738 -0.234649658203125 +21739 -0.2001953125 +21740 -0.119171142578125 +21741 -0.024749755859375 +21742 0.085784912109375 +21743 0.178131103515625 +21744 0.215576171875 +21745 0.211456298828125 +21746 0.17523193359375 +21747 0.128753662109375 +21748 0.1019287109375 +21749 0.0743408203125 +21750 0.04327392578125 +21751 0.038177490234375 +21752 0.076263427734375 +21753 0.14105224609375 +21754 0.186431884765625 +21755 0.188812255859375 +21756 0.1390380859375 +21757 0.041778564453125 +21758 -0.079437255859375 +21759 -0.219390869140625 +21760 -0.367828369140625 +21761 -0.494873046875 +21762 -0.556243896484375 +21763 -0.508697509765625 +21764 -0.3756103515625 +21765 -0.218902587890625 +21766 -0.063751220703125 +21767 0.091552734375 +21768 0.23602294921875 +21769 0.342987060546875 +21770 0.39520263671875 +21771 0.389373779296875 +21772 0.324249267578125 +21773 0.224090576171875 +21774 0.124267578125 +21775 0.037078857421875 +21776 -0.010101318359375 +21777 -0.019439697265625 +21778 -0.022796630859375 +21779 -0.001556396484375 +21780 0.056304931640625 +21781 0.106719970703125 +21782 0.096893310546875 +21783 0.042694091796875 +21784 -0.018035888671875 +21785 -0.07586669921875 +21786 -0.11944580078125 +21787 -0.15972900390625 +21788 -0.202606201171875 +21789 -0.24859619140625 +21790 -0.30517578125 +21791 -0.36212158203125 +21792 -0.39141845703125 +21793 -0.35528564453125 +21794 -0.249969482421875 +21795 -0.092864990234375 +21796 0.08905029296875 +21797 0.2352294921875 +21798 0.318817138671875 +21799 0.358642578125 +21800 0.347747802734375 +21801 0.28564453125 +21802 0.223175048828125 +21803 0.196746826171875 +21804 0.179840087890625 +21805 0.155548095703125 +21806 0.151214599609375 +21807 0.156951904296875 +21808 0.13177490234375 +21809 0.100799560546875 +21810 0.087127685546875 +21811 0.05487060546875 +21812 -0.009002685546875 +21813 -0.10400390625 +21814 -0.229400634765625 +21815 -0.35552978515625 +21816 -0.441925048828125 +21817 -0.473846435546875 +21818 -0.464813232421875 +21819 -0.419097900390625 +21820 -0.334320068359375 +21821 -0.227935791015625 +21822 -0.12347412109375 +21823 -0.02764892578125 +21824 0.077667236328125 +21825 0.2132568359375 +21826 0.38885498046875 +21827 0.582794189453125 +21828 0.734039306640625 +21829 0.800140380859375 +21830 0.7783203125 +21831 0.6651611328125 +21832 0.45965576171875 +21833 0.199188232421875 +21834 -0.050689697265625 +21835 -0.23297119140625 +21836 -0.33013916015625 +21837 -0.368408203125 +21838 -0.378936767578125 +21839 -0.376983642578125 +21840 -0.37969970703125 +21841 -0.391510009765625 +21842 -0.385345458984375 +21843 -0.3419189453125 +21844 -0.28289794921875 +21845 -0.251617431640625 +21846 -0.266143798828125 +21847 -0.273345947265625 +21848 -0.216796875 +21849 -0.128265380859375 +21850 -0.068145751953125 +21851 -0.0430908203125 +21852 -0.024444580078125 +21853 0.020721435546875 +21854 0.124481201171875 +21855 0.25787353515625 +21856 0.379119873046875 +21857 0.47991943359375 +21858 0.5281982421875 +21859 0.511138916015625 +21860 0.456207275390625 +21861 0.407470703125 +21862 0.383758544921875 +21863 0.35687255859375 +21864 0.31182861328125 +21865 0.250885009765625 +21866 0.1654052734375 +21867 0.035247802734375 +21868 -0.142059326171875 +21869 -0.33563232421875 +21870 -0.5345458984375 +21871 -0.72186279296875 +21872 -0.836669921875 +21873 -0.8326416015625 +21874 -0.7296142578125 +21875 -0.582550048828125 +21876 -0.440093994140625 +21877 -0.324310302734375 +21878 -0.20147705078125 +21879 -0.044647216796875 +21880 0.103973388671875 +21881 0.202392578125 +21882 0.264495849609375 +21883 0.338897705078125 +21884 0.443817138671875 +21885 0.545074462890625 +21886 0.6173095703125 +21887 0.6524658203125 +21888 0.66339111328125 +21889 0.6561279296875 +21890 0.606781005859375 +21891 0.501190185546875 +21892 0.352783203125 +21893 0.176544189453125 +21894 -0.034820556640625 +21895 -0.258209228515625 +21896 -0.44244384765625 +21897 -0.5753173828125 +21898 -0.65203857421875 +21899 -0.641632080078125 +21900 -0.562164306640625 +21901 -0.458038330078125 +21902 -0.350555419921875 +21903 -0.260528564453125 +21904 -0.192108154296875 +21905 -0.141937255859375 +21906 -0.1021728515625 +21907 -0.062896728515625 +21908 -0.011932373046875 +21909 0.062835693359375 +21910 0.148712158203125 +21911 0.241729736328125 +21912 0.34912109375 +21913 0.457305908203125 +21914 0.54388427734375 +21915 0.5728759765625 +21916 0.506591796875 +21917 0.351226806640625 +21918 0.146514892578125 +21919 -0.05523681640625 +21920 -0.21624755859375 +21921 -0.334930419921875 +21922 -0.402984619140625 +21923 -0.4412841796875 +21924 -0.49578857421875 +21925 -0.5601806640625 +21926 -0.600738525390625 +21927 -0.584228515625 +21928 -0.47930908203125 +21929 -0.27935791015625 +21930 -0.0089111328125 +21931 0.268798828125 +21932 0.482818603515625 +21933 0.60369873046875 +21934 0.650421142578125 +21935 0.66400146484375 +21936 0.6414794921875 +21937 0.572540283203125 +21938 0.498138427734375 +21939 0.439453125 +21940 0.375518798828125 +21941 0.274505615234375 +21942 0.1087646484375 +21943 -0.099395751953125 +21944 -0.3182373046875 +21945 -0.5489501953125 +21946 -0.7738037109375 +21947 -0.86383056640625 +21948 -0.870391845703125 +21949 -0.86895751953125 +21950 -0.861053466796875 +21951 -0.765869140625 +21952 -0.5301513671875 +21953 -0.214691162109375 +21954 0.137359619140625 +21955 0.474822998046875 +21956 0.76239013671875 +21957 0.867462158203125 +21958 0.870361328125 +21959 0.86480712890625 +21960 0.831817626953125 +21961 0.677581787109375 +21962 0.495880126953125 +21963 0.30767822265625 +21964 0.116180419921875 +21965 -0.110748291015625 +21966 -0.381805419921875 +21967 -0.6572265625 +21968 -0.857421875 +21969 -0.870391845703125 +21970 -0.870391845703125 +21971 -0.86444091796875 +21972 -0.85723876953125 +21973 -0.790008544921875 +21974 -0.62847900390625 +21975 -0.3956298828125 +21976 -0.126708984375 +21977 0.150115966796875 +21978 0.424041748046875 +21979 0.670623779296875 +21980 0.854522705078125 +21981 0.866485595703125 +21982 0.86920166015625 +21983 0.8653564453125 +21984 0.857147216796875 +21985 0.766845703125 +21986 0.628509521484375 +21987 0.462127685546875 +21988 0.297210693359375 +21989 0.14862060546875 +21990 -0.00537109375 +21991 -0.15753173828125 +21992 -0.31304931640625 +21993 -0.48876953125 +21994 -0.6416015625 +21995 -0.751373291015625 +21996 -0.84619140625 +21997 -0.861297607421875 +21998 -0.863250732421875 +21999 -0.856597900390625 +22000 -0.7498779296875 +22001 -0.624542236328125 +22002 -0.47808837890625 +22003 -0.253387451171875 +22004 0.003692626953125 +22005 0.2257080078125 +22006 0.427154541015625 +22007 0.643218994140625 +22008 0.855926513671875 +22009 0.870361328125 +22010 0.870361328125 +22011 0.862762451171875 +22012 0.79669189453125 +22013 0.595794677734375 +22014 0.362152099609375 +22015 0.1270751953125 +22016 -0.086944580078125 +22017 -0.2784423828125 +22018 -0.484832763671875 +22019 -0.729583740234375 +22020 -0.86688232421875 +22021 -0.870391845703125 +22022 -0.86859130859375 +22023 -0.86279296875 +22024 -0.817962646484375 +22025 -0.6116943359375 +22026 -0.3128662109375 +22027 0.039398193359375 +22028 0.422821044921875 +22029 0.805145263671875 +22030 0.870361328125 +22031 0.870361328125 +22032 0.860015869140625 +22033 0.727935791015625 +22034 0.48114013671875 +22035 0.2059326171875 +22036 -0.06103515625 +22037 -0.29913330078125 +22038 -0.516204833984375 +22039 -0.7252197265625 +22040 -0.85980224609375 +22041 -0.870391845703125 +22042 -0.870391845703125 +22043 -0.858062744140625 +22044 -0.673004150390625 +22045 -0.42694091796875 +22046 -0.2100830078125 +22047 -0.0362548828125 +22048 0.10943603515625 +22049 0.23516845703125 +22050 0.373687744140625 +22051 0.517791748046875 +22052 0.602783203125 +22053 0.635711669921875 +22054 0.655181884765625 +22055 0.65948486328125 +22056 0.651275634765625 +22057 0.61846923828125 +22058 0.53753662109375 +22059 0.404144287109375 +22060 0.22186279296875 +22061 0.003997802734375 +22062 -0.22100830078125 +22063 -0.42449951171875 +22064 -0.579833984375 +22065 -0.641876220703125 +22066 -0.6177978515625 +22067 -0.575531005859375 +22068 -0.526336669921875 +22069 -0.42645263671875 +22070 -0.2581787109375 +22071 -0.068695068359375 +22072 0.09222412109375 +22073 0.232147216796875 +22074 0.3509521484375 +22075 0.410064697265625 +22076 0.372955322265625 +22077 0.2554931640625 +22078 0.10711669921875 +22079 -0.052886962890625 +22080 -0.186279296875 +22081 -0.23291015625 +22082 -0.209442138671875 +22083 -0.174163818359375 +22084 -0.126739501953125 +22085 -0.048126220703125 +22086 0.0426025390625 +22087 0.10748291015625 +22088 0.1409912109375 +22089 0.19708251953125 +22090 0.273651123046875 +22091 0.31768798828125 +22092 0.341094970703125 +22093 0.368011474609375 +22094 0.37249755859375 +22095 0.30072021484375 +22096 0.1517333984375 +22097 -0.01470947265625 +22098 -0.1883544921875 +22099 -0.372711181640625 +22100 -0.51397705078125 +22101 -0.57177734375 +22102 -0.53948974609375 +22103 -0.43511962890625 +22104 -0.2962646484375 +22105 -0.161102294921875 +22106 -0.0435791015625 +22107 0.060394287109375 +22108 0.13665771484375 +22109 0.170135498046875 +22110 0.16552734375 +22111 0.15728759765625 +22112 0.150787353515625 +22113 0.12200927734375 +22114 0.080108642578125 +22115 0.05126953125 +22116 0.062896728515625 +22117 0.09271240234375 +22118 0.092987060546875 +22119 0.07855224609375 +22120 0.06427001953125 +22121 0.0347900390625 +22122 -0.01171875 +22123 -0.056060791015625 +22124 -0.055511474609375 +22125 -0.010467529296875 +22126 0.02508544921875 +22127 0.025665283203125 +22128 0.017333984375 +22129 0.00189208984375 +22130 -0.03173828125 +22131 -0.071502685546875 +22132 -0.13543701171875 +22133 -0.219970703125 +22134 -0.300506591796875 +22135 -0.376312255859375 +22136 -0.416107177734375 +22137 -0.371124267578125 +22138 -0.242279052734375 +22139 -0.069732666015625 +22140 0.125640869140625 +22141 0.31268310546875 +22142 0.45501708984375 +22143 0.554779052734375 +22144 0.61065673828125 +22145 0.610931396484375 +22146 0.531463623046875 +22147 0.3883056640625 +22148 0.23468017578125 +22149 0.095245361328125 +22150 -0.00396728515625 +22151 -0.04852294921875 +22152 -0.055145263671875 +22153 -0.0758056640625 +22154 -0.138702392578125 +22155 -0.209197998046875 +22156 -0.289031982421875 +22157 -0.37884521484375 +22158 -0.456329345703125 +22159 -0.51641845703125 +22160 -0.519287109375 +22161 -0.458251953125 +22162 -0.384796142578125 +22163 -0.323699951171875 +22164 -0.269287109375 +22165 -0.1951904296875 +22166 -0.100006103515625 +22167 -0.01055908203125 +22168 0.1033935546875 +22169 0.24908447265625 +22170 0.373199462890625 +22171 0.45806884765625 +22172 0.511474609375 +22173 0.565399169921875 +22174 0.61138916015625 +22175 0.5897216796875 +22176 0.4906005859375 +22177 0.33148193359375 +22178 0.147796630859375 +22179 -0.01873779296875 +22180 -0.140289306640625 +22181 -0.191986083984375 +22182 -0.184295654296875 +22183 -0.161834716796875 +22184 -0.166595458984375 +22185 -0.19390869140625 +22186 -0.22442626953125 +22187 -0.279754638671875 +22188 -0.3389892578125 +22189 -0.3543701171875 +22190 -0.348175048828125 +22191 -0.32598876953125 +22192 -0.2581787109375 +22193 -0.139801025390625 +22194 0.014617919921875 +22195 0.144378662109375 +22196 0.221038818359375 +22197 0.27069091796875 +22198 0.294036865234375 +22199 0.311767578125 +22200 0.339141845703125 +22201 0.360260009765625 +22202 0.360504150390625 +22203 0.308380126953125 +22204 0.18170166015625 +22205 0.0047607421875 +22206 -0.17559814453125 +22207 -0.3143310546875 +22208 -0.36785888671875 +22209 -0.36248779296875 +22210 -0.343536376953125 +22211 -0.3018798828125 +22212 -0.231414794921875 +22213 -0.117645263671875 +22214 0.007049560546875 +22215 0.087982177734375 +22216 0.13946533203125 +22217 0.17425537109375 +22218 0.188201904296875 +22219 0.171234130859375 +22220 0.118438720703125 +22221 0.05706787109375 +22222 -0.010711669921875 +22223 -0.0914306640625 +22224 -0.162322998046875 +22225 -0.194549560546875 +22226 -0.1492919921875 +22227 -0.02166748046875 +22228 0.124053955078125 +22229 0.211151123046875 +22230 0.240447998046875 +22231 0.242218017578125 +22232 0.2257080078125 +22233 0.194366455078125 +22234 0.115509033203125 +22235 0.0128173828125 +22236 -0.053802490234375 +22237 -0.110626220703125 +22238 -0.199493408203125 +22239 -0.29437255859375 +22240 -0.33221435546875 +22241 -0.27972412109375 +22242 -0.185333251953125 +22243 -0.128204345703125 +22244 -0.115692138671875 +22245 -0.116455078125 +22246 -0.105926513671875 +22247 -0.053955078125 +22248 0.048797607421875 +22249 0.157318115234375 +22250 0.212005615234375 +22251 0.218475341796875 +22252 0.23724365234375 +22253 0.30535888671875 +22254 0.38128662109375 +22255 0.404449462890625 +22256 0.3944091796875 +22257 0.3885498046875 +22258 0.362640380859375 +22259 0.27362060546875 +22260 0.11712646484375 +22261 -0.054901123046875 +22262 -0.19085693359375 +22263 -0.28570556640625 +22264 -0.339263916015625 +22265 -0.3775634765625 +22266 -0.445709228515625 +22267 -0.535064697265625 +22268 -0.629058837890625 +22269 -0.697601318359375 +22270 -0.70391845703125 +22271 -0.6424560546875 +22272 -0.491241455078125 +22273 -0.265716552734375 +22274 -0.023712158203125 +22275 0.201751708984375 +22276 0.375823974609375 +22277 0.485076904296875 +22278 0.56884765625 +22279 0.634765625 +22280 0.63763427734375 +22281 0.5660400390625 +22282 0.4720458984375 +22283 0.40692138671875 +22284 0.3778076171875 +22285 0.376953125 +22286 0.371978759765625 +22287 0.313140869140625 +22288 0.184417724609375 +22289 0.011199951171875 +22290 -0.171051025390625 +22291 -0.33740234375 +22292 -0.47198486328125 +22293 -0.560394287109375 +22294 -0.58056640625 +22295 -0.54754638671875 +22296 -0.508575439453125 +22297 -0.459503173828125 +22298 -0.394378662109375 +22299 -0.35260009765625 +22300 -0.31170654296875 +22301 -0.197418212890625 +22302 -0.007965087890625 +22303 0.207489013671875 +22304 0.409210205078125 +22305 0.57208251953125 +22306 0.66595458984375 +22307 0.65875244140625 +22308 0.56744384765625 +22309 0.431396484375 +22310 0.29443359375 +22311 0.182464599609375 +22312 0.06365966796875 +22313 -0.075958251953125 +22314 -0.189422607421875 +22315 -0.271942138671875 +22316 -0.342529296875 +22317 -0.364166259765625 +22318 -0.327239990234375 +22319 -0.2769775390625 +22320 -0.253692626953125 +22321 -0.24365234375 +22322 -0.1983642578125 +22323 -0.116241455078125 +22324 -0.036834716796875 +22325 0.034881591796875 +22326 0.09124755859375 +22327 0.10888671875 +22328 0.125518798828125 +22329 0.15771484375 +22330 0.17828369140625 +22331 0.17108154296875 +22332 0.129974365234375 +22333 0.082427978515625 +22334 0.027679443359375 +22335 -0.065643310546875 +22336 -0.15936279296875 +22337 -0.21307373046875 +22338 -0.234649658203125 +22339 -0.2001953125 +22340 -0.119171142578125 +22341 -0.024749755859375 +22342 0.085784912109375 +22343 0.178131103515625 +22344 0.215576171875 +22345 0.211456298828125 +22346 0.17523193359375 +22347 0.128753662109375 +22348 0.1019287109375 +22349 0.0743408203125 +22350 0.04327392578125 +22351 0.038177490234375 +22352 0.076263427734375 +22353 0.14105224609375 +22354 0.186431884765625 +22355 0.188812255859375 +22356 0.1390380859375 +22357 0.041778564453125 +22358 -0.079437255859375 +22359 -0.219390869140625 +22360 -0.367828369140625 +22361 -0.494873046875 +22362 -0.556243896484375 +22363 -0.508697509765625 +22364 -0.3756103515625 +22365 -0.218902587890625 +22366 -0.063751220703125 +22367 0.091552734375 +22368 0.23602294921875 +22369 0.342987060546875 +22370 0.39520263671875 +22371 0.389373779296875 +22372 0.324249267578125 +22373 0.224090576171875 +22374 0.124267578125 +22375 0.037078857421875 +22376 -0.010101318359375 +22377 -0.019439697265625 +22378 -0.022796630859375 +22379 -0.001556396484375 +22380 0.056304931640625 +22381 0.106719970703125 +22382 0.096893310546875 +22383 0.042694091796875 +22384 -0.018035888671875 +22385 -0.07586669921875 +22386 -0.11944580078125 +22387 -0.15972900390625 +22388 -0.202606201171875 +22389 -0.24859619140625 +22390 -0.30517578125 +22391 -0.36212158203125 +22392 -0.39141845703125 +22393 -0.35528564453125 +22394 -0.249969482421875 +22395 -0.092864990234375 +22396 0.08905029296875 +22397 0.2352294921875 +22398 0.318817138671875 +22399 0.358642578125 +22400 0.347747802734375 +22401 0.28564453125 +22402 0.223175048828125 +22403 0.196746826171875 +22404 0.179840087890625 +22405 0.155548095703125 +22406 0.151214599609375 +22407 0.156951904296875 +22408 0.13177490234375 +22409 0.100799560546875 +22410 0.087127685546875 +22411 0.05487060546875 +22412 -0.009002685546875 +22413 -0.10400390625 +22414 -0.229400634765625 +22415 -0.35552978515625 +22416 -0.441925048828125 +22417 -0.473846435546875 +22418 -0.464813232421875 +22419 -0.419097900390625 +22420 -0.334320068359375 +22421 -0.227935791015625 +22422 -0.12347412109375 +22423 -0.02764892578125 +22424 0.077667236328125 +22425 0.2132568359375 +22426 0.38885498046875 +22427 0.582794189453125 +22428 0.734039306640625 +22429 0.800140380859375 +22430 0.7783203125 +22431 0.6651611328125 +22432 0.45965576171875 +22433 0.199188232421875 +22434 -0.050689697265625 +22435 -0.23297119140625 +22436 -0.33013916015625 +22437 -0.368408203125 +22438 -0.378936767578125 +22439 -0.376983642578125 +22440 -0.37969970703125 +22441 -0.391510009765625 +22442 -0.385345458984375 +22443 -0.3419189453125 +22444 -0.28289794921875 +22445 -0.251617431640625 +22446 -0.266143798828125 +22447 -0.273345947265625 +22448 -0.216796875 +22449 -0.128265380859375 +22450 -0.068145751953125 +22451 -0.0430908203125 +22452 -0.024444580078125 +22453 0.020721435546875 +22454 0.124481201171875 +22455 0.25787353515625 +22456 0.379119873046875 +22457 0.47991943359375 +22458 0.5281982421875 +22459 0.511138916015625 +22460 0.456207275390625 +22461 0.407470703125 +22462 0.383758544921875 +22463 0.35687255859375 +22464 0.31182861328125 +22465 0.250885009765625 +22466 0.1654052734375 +22467 0.035247802734375 +22468 -0.142059326171875 +22469 -0.33563232421875 +22470 -0.5345458984375 +22471 -0.72186279296875 +22472 -0.836669921875 +22473 -0.8326416015625 +22474 -0.7296142578125 +22475 -0.582550048828125 +22476 -0.440093994140625 +22477 -0.324310302734375 +22478 -0.20147705078125 +22479 -0.044647216796875 +22480 0.103973388671875 +22481 0.202392578125 +22482 0.264495849609375 +22483 0.338897705078125 +22484 0.443817138671875 +22485 0.545074462890625 +22486 0.6173095703125 +22487 0.6524658203125 +22488 0.66339111328125 +22489 0.6561279296875 +22490 0.606781005859375 +22491 0.501190185546875 +22492 0.352783203125 +22493 0.176544189453125 +22494 -0.034820556640625 +22495 -0.258209228515625 +22496 -0.44244384765625 +22497 -0.5753173828125 +22498 -0.65203857421875 +22499 -0.641632080078125 +22500 -0.562164306640625 +22501 -0.458038330078125 +22502 -0.350555419921875 +22503 -0.260528564453125 +22504 -0.192108154296875 +22505 -0.141937255859375 +22506 -0.1021728515625 +22507 -0.062896728515625 +22508 -0.011932373046875 +22509 0.062835693359375 +22510 0.148712158203125 +22511 0.241729736328125 +22512 0.34912109375 +22513 0.457305908203125 +22514 0.54388427734375 +22515 0.5728759765625 +22516 0.506591796875 +22517 0.351226806640625 +22518 0.146514892578125 +22519 -0.05523681640625 +22520 -0.21624755859375 +22521 -0.334930419921875 +22522 -0.402984619140625 +22523 -0.4412841796875 +22524 -0.49578857421875 +22525 -0.5601806640625 +22526 -0.600738525390625 +22527 -0.584228515625 +22528 -0.47930908203125 +22529 -0.27935791015625 +22530 -0.0089111328125 +22531 0.268798828125 +22532 0.482818603515625 +22533 0.60369873046875 +22534 0.650421142578125 +22535 0.66400146484375 +22536 0.6414794921875 +22537 0.572540283203125 +22538 0.498138427734375 +22539 0.439453125 +22540 0.375518798828125 +22541 0.274505615234375 +22542 0.1087646484375 +22543 -0.099395751953125 +22544 -0.3182373046875 +22545 -0.5489501953125 +22546 -0.7738037109375 +22547 -0.86383056640625 +22548 -0.870391845703125 +22549 -0.86895751953125 +22550 -0.861053466796875 +22551 -0.765869140625 +22552 -0.5301513671875 +22553 -0.214691162109375 +22554 0.137359619140625 +22555 0.474822998046875 +22556 0.76239013671875 +22557 0.867462158203125 +22558 0.870361328125 +22559 0.86480712890625 +22560 0.831817626953125 +22561 0.677581787109375 +22562 0.495880126953125 +22563 0.30767822265625 +22564 0.116180419921875 +22565 -0.110748291015625 +22566 -0.381805419921875 +22567 -0.6572265625 +22568 -0.857421875 +22569 -0.870391845703125 +22570 -0.870391845703125 +22571 -0.86444091796875 +22572 -0.85723876953125 +22573 -0.790008544921875 +22574 -0.62847900390625 +22575 -0.3956298828125 +22576 -0.126708984375 +22577 0.150115966796875 +22578 0.424041748046875 +22579 0.670623779296875 +22580 0.854522705078125 +22581 0.866485595703125 +22582 0.86920166015625 +22583 0.8653564453125 +22584 0.857147216796875 +22585 0.766845703125 +22586 0.628509521484375 +22587 0.462127685546875 +22588 0.297210693359375 +22589 0.14862060546875 +22590 -0.00537109375 +22591 -0.15753173828125 +22592 -0.31304931640625 +22593 -0.48876953125 +22594 -0.6416015625 +22595 -0.751373291015625 +22596 -0.84619140625 +22597 -0.861297607421875 +22598 -0.863250732421875 +22599 -0.856597900390625 +22600 -0.7498779296875 +22601 -0.624542236328125 +22602 -0.47808837890625 +22603 -0.253387451171875 +22604 0.003692626953125 +22605 0.2257080078125 +22606 0.427154541015625 +22607 0.643218994140625 +22608 0.855926513671875 +22609 0.870361328125 +22610 0.870361328125 +22611 0.862762451171875 +22612 0.79669189453125 +22613 0.595794677734375 +22614 0.362152099609375 +22615 0.1270751953125 +22616 -0.086944580078125 +22617 -0.2784423828125 +22618 -0.484832763671875 +22619 -0.729583740234375 +22620 -0.86688232421875 +22621 -0.870391845703125 +22622 -0.86859130859375 +22623 -0.86279296875 +22624 -0.817962646484375 +22625 -0.6116943359375 +22626 -0.3128662109375 +22627 0.039398193359375 +22628 0.422821044921875 +22629 0.805145263671875 +22630 0.870361328125 +22631 0.870361328125 +22632 0.860015869140625 +22633 0.727935791015625 +22634 0.48114013671875 +22635 0.2059326171875 +22636 -0.06103515625 +22637 -0.29913330078125 +22638 -0.516204833984375 +22639 -0.7252197265625 +22640 -0.85980224609375 +22641 -0.870391845703125 +22642 -0.870391845703125 +22643 -0.858062744140625 +22644 -0.673004150390625 +22645 -0.42694091796875 +22646 -0.2100830078125 +22647 -0.0362548828125 +22648 0.10943603515625 +22649 0.23516845703125 +22650 0.373687744140625 +22651 0.517791748046875 +22652 0.602783203125 +22653 0.635711669921875 +22654 0.655181884765625 +22655 0.65948486328125 +22656 0.651275634765625 +22657 0.61846923828125 +22658 0.53753662109375 +22659 0.404144287109375 +22660 0.22186279296875 +22661 0.003997802734375 +22662 -0.22100830078125 +22663 -0.42449951171875 +22664 -0.579833984375 +22665 -0.641876220703125 +22666 -0.6177978515625 +22667 -0.575531005859375 +22668 -0.526336669921875 +22669 -0.42645263671875 +22670 -0.2581787109375 +22671 -0.068695068359375 +22672 0.09222412109375 +22673 0.232147216796875 +22674 0.3509521484375 +22675 0.410064697265625 +22676 0.372955322265625 +22677 0.2554931640625 +22678 0.10711669921875 +22679 -0.052886962890625 +22680 -0.186279296875 +22681 -0.23291015625 +22682 -0.209442138671875 +22683 -0.174163818359375 +22684 -0.126739501953125 +22685 -0.048126220703125 +22686 0.0426025390625 +22687 0.10748291015625 +22688 0.1409912109375 +22689 0.19708251953125 +22690 0.273651123046875 +22691 0.31768798828125 +22692 0.341094970703125 +22693 0.368011474609375 +22694 0.37249755859375 +22695 0.30072021484375 +22696 0.1517333984375 +22697 -0.01470947265625 +22698 -0.1883544921875 +22699 -0.372711181640625 +22700 -0.51397705078125 +22701 -0.57177734375 +22702 -0.53948974609375 +22703 -0.43511962890625 +22704 -0.2962646484375 +22705 -0.161102294921875 +22706 -0.0435791015625 +22707 0.060394287109375 +22708 0.13665771484375 +22709 0.170135498046875 +22710 0.16552734375 +22711 0.15728759765625 +22712 0.150787353515625 +22713 0.12200927734375 +22714 0.080108642578125 +22715 0.05126953125 +22716 0.062896728515625 +22717 0.09271240234375 +22718 0.092987060546875 +22719 0.07855224609375 +22720 0.06427001953125 +22721 0.0347900390625 +22722 -0.01171875 +22723 -0.056060791015625 +22724 -0.055511474609375 +22725 -0.010467529296875 +22726 0.02508544921875 +22727 0.025665283203125 +22728 0.017333984375 +22729 0.00189208984375 +22730 -0.03173828125 +22731 -0.071502685546875 +22732 -0.13543701171875 +22733 -0.219970703125 +22734 -0.300506591796875 +22735 -0.376312255859375 +22736 -0.416107177734375 +22737 -0.371124267578125 +22738 -0.242279052734375 +22739 -0.069732666015625 +22740 0.125640869140625 +22741 0.31268310546875 +22742 0.45501708984375 +22743 0.554779052734375 +22744 0.61065673828125 +22745 0.610931396484375 +22746 0.531463623046875 +22747 0.3883056640625 +22748 0.23468017578125 +22749 0.095245361328125 +22750 -0.00396728515625 +22751 -0.04852294921875 +22752 -0.055145263671875 +22753 -0.0758056640625 +22754 -0.138702392578125 +22755 -0.209197998046875 +22756 -0.289031982421875 +22757 -0.37884521484375 +22758 -0.456329345703125 +22759 -0.51641845703125 +22760 -0.519287109375 +22761 -0.458251953125 +22762 -0.384796142578125 +22763 -0.323699951171875 +22764 -0.269287109375 +22765 -0.1951904296875 +22766 -0.100006103515625 +22767 -0.01055908203125 +22768 0.1033935546875 +22769 0.24908447265625 +22770 0.373199462890625 +22771 0.45806884765625 +22772 0.511474609375 +22773 0.565399169921875 +22774 0.61138916015625 +22775 0.5897216796875 +22776 0.4906005859375 +22777 0.33148193359375 +22778 0.147796630859375 +22779 -0.01873779296875 +22780 -0.140289306640625 +22781 -0.191986083984375 +22782 -0.184295654296875 +22783 -0.161834716796875 +22784 -0.166595458984375 +22785 -0.19390869140625 +22786 -0.22442626953125 +22787 -0.279754638671875 +22788 -0.3389892578125 +22789 -0.3543701171875 +22790 -0.348175048828125 +22791 -0.32598876953125 +22792 -0.2581787109375 +22793 -0.139801025390625 +22794 0.014617919921875 +22795 0.144378662109375 +22796 0.221038818359375 +22797 0.27069091796875 +22798 0.294036865234375 +22799 0.311767578125 +22800 0.339141845703125 +22801 0.360260009765625 +22802 0.360504150390625 +22803 0.308380126953125 +22804 0.18170166015625 +22805 0.0047607421875 +22806 -0.17559814453125 +22807 -0.3143310546875 +22808 -0.36785888671875 +22809 -0.36248779296875 +22810 -0.343536376953125 +22811 -0.3018798828125 +22812 -0.231414794921875 +22813 -0.117645263671875 +22814 0.007049560546875 +22815 0.087982177734375 +22816 0.13946533203125 +22817 0.17425537109375 +22818 0.188201904296875 +22819 0.171234130859375 +22820 0.118438720703125 +22821 0.05706787109375 +22822 -0.010711669921875 +22823 -0.0914306640625 +22824 -0.162322998046875 +22825 -0.194549560546875 +22826 -0.1492919921875 +22827 -0.02166748046875 +22828 0.124053955078125 +22829 0.211151123046875 +22830 0.240447998046875 +22831 0.242218017578125 +22832 0.2257080078125 +22833 0.194366455078125 +22834 0.115509033203125 +22835 0.0128173828125 +22836 -0.053802490234375 +22837 -0.110626220703125 +22838 -0.199493408203125 +22839 -0.29437255859375 +22840 -0.33221435546875 +22841 -0.27972412109375 +22842 -0.185333251953125 +22843 -0.128204345703125 +22844 -0.115692138671875 +22845 -0.116455078125 +22846 -0.105926513671875 +22847 -0.053955078125 +22848 0.048797607421875 +22849 0.157318115234375 +22850 0.212005615234375 +22851 0.218475341796875 +22852 0.23724365234375 +22853 0.30535888671875 +22854 0.38128662109375 +22855 0.404449462890625 +22856 0.3944091796875 +22857 0.3885498046875 +22858 0.362640380859375 +22859 0.27362060546875 +22860 0.11712646484375 +22861 -0.054901123046875 +22862 -0.19085693359375 +22863 -0.28570556640625 +22864 -0.339263916015625 +22865 -0.3775634765625 +22866 -0.445709228515625 +22867 -0.535064697265625 +22868 -0.629058837890625 +22869 -0.697601318359375 +22870 -0.70391845703125 +22871 -0.6424560546875 +22872 -0.491241455078125 +22873 -0.265716552734375 +22874 -0.023712158203125 +22875 0.201751708984375 +22876 0.375823974609375 +22877 0.485076904296875 +22878 0.56884765625 +22879 0.634765625 +22880 0.63763427734375 +22881 0.5660400390625 +22882 0.4720458984375 +22883 0.40692138671875 +22884 0.3778076171875 +22885 0.376953125 +22886 0.371978759765625 +22887 0.313140869140625 +22888 0.184417724609375 +22889 0.011199951171875 +22890 -0.171051025390625 +22891 -0.33740234375 +22892 -0.47198486328125 +22893 -0.560394287109375 +22894 -0.58056640625 +22895 -0.54754638671875 +22896 -0.508575439453125 +22897 -0.459503173828125 +22898 -0.394378662109375 +22899 -0.35260009765625 +22900 -0.31170654296875 +22901 -0.197418212890625 +22902 -0.007965087890625 +22903 0.207489013671875 +22904 0.409210205078125 +22905 0.57208251953125 +22906 0.66595458984375 +22907 0.65875244140625 +22908 0.56744384765625 +22909 0.431396484375 +22910 0.29443359375 +22911 0.182464599609375 +22912 0.06365966796875 +22913 -0.075958251953125 +22914 -0.189422607421875 +22915 -0.271942138671875 +22916 -0.342529296875 +22917 -0.364166259765625 +22918 -0.327239990234375 +22919 -0.2769775390625 +22920 -0.253692626953125 +22921 -0.24365234375 +22922 -0.1983642578125 +22923 -0.116241455078125 +22924 -0.036834716796875 +22925 0.034881591796875 +22926 0.09124755859375 +22927 0.10888671875 +22928 0.125518798828125 +22929 0.15771484375 +22930 0.17828369140625 +22931 0.17108154296875 +22932 0.129974365234375 +22933 0.082427978515625 +22934 0.027679443359375 +22935 -0.065643310546875 +22936 -0.15936279296875 +22937 -0.21307373046875 +22938 -0.234649658203125 +22939 -0.2001953125 +22940 -0.119171142578125 +22941 -0.024749755859375 +22942 0.085784912109375 +22943 0.178131103515625 +22944 0.215576171875 +22945 0.211456298828125 +22946 0.17523193359375 +22947 0.128753662109375 +22948 0.1019287109375 +22949 0.0743408203125 +22950 0.04327392578125 +22951 0.038177490234375 +22952 0.076263427734375 +22953 0.14105224609375 +22954 0.186431884765625 +22955 0.188812255859375 +22956 0.1390380859375 +22957 0.041778564453125 +22958 -0.079437255859375 +22959 -0.219390869140625 +22960 -0.367828369140625 +22961 -0.494873046875 +22962 -0.556243896484375 +22963 -0.508697509765625 +22964 -0.3756103515625 +22965 -0.218902587890625 +22966 -0.063751220703125 +22967 0.091552734375 +22968 0.23602294921875 +22969 0.342987060546875 +22970 0.39520263671875 +22971 0.389373779296875 +22972 0.324249267578125 +22973 0.224090576171875 +22974 0.124267578125 +22975 0.037078857421875 +22976 -0.010101318359375 +22977 -0.019439697265625 +22978 -0.022796630859375 +22979 -0.001556396484375 +22980 0.056304931640625 +22981 0.106719970703125 +22982 0.096893310546875 +22983 0.042694091796875 +22984 -0.018035888671875 +22985 -0.07586669921875 +22986 -0.11944580078125 +22987 -0.15972900390625 +22988 -0.202606201171875 +22989 -0.24859619140625 +22990 -0.30517578125 +22991 -0.36212158203125 +22992 -0.39141845703125 +22993 -0.35528564453125 +22994 -0.249969482421875 +22995 -0.092864990234375 +22996 0.08905029296875 +22997 0.2352294921875 +22998 0.318817138671875 +22999 0.358642578125 +23000 0.347747802734375 +23001 0.28564453125 +23002 0.223175048828125 +23003 0.196746826171875 +23004 0.179840087890625 +23005 0.155548095703125 +23006 0.151214599609375 +23007 0.156951904296875 +23008 0.13177490234375 +23009 0.100799560546875 +23010 0.087127685546875 +23011 0.05487060546875 +23012 -0.009002685546875 +23013 -0.10400390625 +23014 -0.229400634765625 +23015 -0.35552978515625 +23016 -0.441925048828125 +23017 -0.473846435546875 +23018 -0.464813232421875 +23019 -0.419097900390625 +23020 -0.334320068359375 +23021 -0.227935791015625 +23022 -0.12347412109375 +23023 -0.02764892578125 +23024 0.077667236328125 +23025 0.2132568359375 +23026 0.38885498046875 +23027 0.582794189453125 +23028 0.734039306640625 +23029 0.800140380859375 +23030 0.7783203125 +23031 0.6651611328125 +23032 0.45965576171875 +23033 0.199188232421875 +23034 -0.050689697265625 +23035 -0.23297119140625 +23036 -0.33013916015625 +23037 -0.368408203125 +23038 -0.378936767578125 +23039 -0.376983642578125 +23040 -0.37969970703125 +23041 -0.391510009765625 +23042 -0.385345458984375 +23043 -0.3419189453125 +23044 -0.28289794921875 +23045 -0.251617431640625 +23046 -0.266143798828125 +23047 -0.273345947265625 +23048 -0.216796875 +23049 -0.128265380859375 +23050 -0.068145751953125 +23051 -0.0430908203125 +23052 -0.024444580078125 +23053 0.020721435546875 +23054 0.124481201171875 +23055 0.25787353515625 +23056 0.379119873046875 +23057 0.47991943359375 +23058 0.5281982421875 +23059 0.511138916015625 +23060 0.456207275390625 +23061 0.407470703125 +23062 0.383758544921875 +23063 0.35687255859375 +23064 0.31182861328125 +23065 0.250885009765625 +23066 0.1654052734375 +23067 0.035247802734375 +23068 -0.142059326171875 +23069 -0.33563232421875 +23070 -0.5345458984375 +23071 -0.72186279296875 +23072 -0.836669921875 +23073 -0.8326416015625 +23074 -0.7296142578125 +23075 -0.582550048828125 +23076 -0.440093994140625 +23077 -0.324310302734375 +23078 -0.20147705078125 +23079 -0.044647216796875 +23080 0.103973388671875 +23081 0.202392578125 +23082 0.264495849609375 +23083 0.338897705078125 +23084 0.443817138671875 +23085 0.545074462890625 +23086 0.6173095703125 +23087 0.6524658203125 +23088 0.66339111328125 +23089 0.6561279296875 +23090 0.606781005859375 +23091 0.501190185546875 +23092 0.352783203125 +23093 0.176544189453125 +23094 -0.034820556640625 +23095 -0.258209228515625 +23096 -0.44244384765625 +23097 -0.5753173828125 +23098 -0.65203857421875 +23099 -0.641632080078125 +23100 -0.562164306640625 +23101 -0.458038330078125 +23102 -0.350555419921875 +23103 -0.260528564453125 +23104 -0.192108154296875 +23105 -0.141937255859375 +23106 -0.1021728515625 +23107 -0.062896728515625 +23108 -0.011932373046875 +23109 0.062835693359375 +23110 0.148712158203125 +23111 0.241729736328125 +23112 0.34912109375 +23113 0.457305908203125 +23114 0.54388427734375 +23115 0.5728759765625 +23116 0.506591796875 +23117 0.351226806640625 +23118 0.146514892578125 +23119 -0.05523681640625 +23120 -0.21624755859375 +23121 -0.334930419921875 +23122 -0.402984619140625 +23123 -0.4412841796875 +23124 -0.49578857421875 +23125 -0.5601806640625 +23126 -0.600738525390625 +23127 -0.584228515625 +23128 -0.47930908203125 +23129 -0.27935791015625 +23130 -0.0089111328125 +23131 0.268798828125 +23132 0.482818603515625 +23133 0.60369873046875 +23134 0.650421142578125 +23135 0.66400146484375 +23136 0.6414794921875 +23137 0.572540283203125 +23138 0.498138427734375 +23139 0.439453125 +23140 0.375518798828125 +23141 0.274505615234375 +23142 0.1087646484375 +23143 -0.099395751953125 +23144 -0.3182373046875 +23145 -0.5489501953125 +23146 -0.7738037109375 +23147 -0.86383056640625 +23148 -0.870391845703125 +23149 -0.86895751953125 +23150 -0.861053466796875 +23151 -0.765869140625 +23152 -0.5301513671875 +23153 -0.214691162109375 +23154 0.137359619140625 +23155 0.474822998046875 +23156 0.76239013671875 +23157 0.867462158203125 +23158 0.870361328125 +23159 0.86480712890625 +23160 0.831817626953125 +23161 0.677581787109375 +23162 0.495880126953125 +23163 0.30767822265625 +23164 0.116180419921875 +23165 -0.110748291015625 +23166 -0.381805419921875 +23167 -0.6572265625 +23168 -0.857421875 +23169 -0.870391845703125 +23170 -0.870391845703125 +23171 -0.86444091796875 +23172 -0.85723876953125 +23173 -0.790008544921875 +23174 -0.62847900390625 +23175 -0.3956298828125 +23176 -0.126708984375 +23177 0.150115966796875 +23178 0.424041748046875 +23179 0.670623779296875 +23180 0.854522705078125 +23181 0.866485595703125 +23182 0.86920166015625 +23183 0.8653564453125 +23184 0.857147216796875 +23185 0.766845703125 +23186 0.628509521484375 +23187 0.462127685546875 +23188 0.297210693359375 +23189 0.14862060546875 +23190 -0.00537109375 +23191 -0.15753173828125 +23192 -0.31304931640625 +23193 -0.48876953125 +23194 -0.6416015625 +23195 -0.751373291015625 +23196 -0.84619140625 +23197 -0.861297607421875 +23198 -0.863250732421875 +23199 -0.856597900390625 +23200 -0.7498779296875 +23201 -0.624542236328125 +23202 -0.47808837890625 +23203 -0.253387451171875 +23204 0.003692626953125 +23205 0.2257080078125 +23206 0.427154541015625 +23207 0.643218994140625 +23208 0.855926513671875 +23209 0.870361328125 +23210 0.870361328125 +23211 0.862762451171875 +23212 0.79669189453125 +23213 0.595794677734375 +23214 0.362152099609375 +23215 0.1270751953125 +23216 -0.086944580078125 +23217 -0.2784423828125 +23218 -0.484832763671875 +23219 -0.729583740234375 +23220 -0.86688232421875 +23221 -0.870391845703125 +23222 -0.86859130859375 +23223 -0.86279296875 +23224 -0.817962646484375 +23225 -0.6116943359375 +23226 -0.3128662109375 +23227 0.039398193359375 +23228 0.422821044921875 +23229 0.805145263671875 +23230 0.870361328125 +23231 0.870361328125 +23232 0.860015869140625 +23233 0.727935791015625 +23234 0.48114013671875 +23235 0.2059326171875 +23236 -0.06103515625 +23237 -0.29913330078125 +23238 -0.516204833984375 +23239 -0.7252197265625 +23240 -0.85980224609375 +23241 -0.870391845703125 +23242 -0.870391845703125 +23243 -0.858062744140625 +23244 -0.673004150390625 +23245 -0.42694091796875 +23246 -0.2100830078125 +23247 -0.0362548828125 +23248 0.10943603515625 +23249 0.23516845703125 +23250 0.373687744140625 +23251 0.517791748046875 +23252 0.602783203125 +23253 0.635711669921875 +23254 0.655181884765625 +23255 0.65948486328125 +23256 0.651275634765625 +23257 0.61846923828125 +23258 0.53753662109375 +23259 0.404144287109375 +23260 0.22186279296875 +23261 0.003997802734375 +23262 -0.22100830078125 +23263 -0.42449951171875 +23264 -0.579833984375 +23265 -0.641876220703125 +23266 -0.6177978515625 +23267 -0.575531005859375 +23268 -0.526336669921875 +23269 -0.42645263671875 +23270 -0.2581787109375 +23271 -0.068695068359375 +23272 0.09222412109375 +23273 0.232147216796875 +23274 0.3509521484375 +23275 0.410064697265625 +23276 0.372955322265625 +23277 0.2554931640625 +23278 0.10711669921875 +23279 -0.052886962890625 +23280 -0.186279296875 +23281 -0.23291015625 +23282 -0.209442138671875 +23283 -0.174163818359375 +23284 -0.126739501953125 +23285 -0.048126220703125 +23286 0.0426025390625 +23287 0.10748291015625 +23288 0.1409912109375 +23289 0.19708251953125 +23290 0.273651123046875 +23291 0.31768798828125 +23292 0.341094970703125 +23293 0.368011474609375 +23294 0.37249755859375 +23295 0.30072021484375 +23296 0.1517333984375 +23297 -0.01470947265625 +23298 -0.1883544921875 +23299 -0.372711181640625 +23300 -0.51397705078125 +23301 -0.57177734375 +23302 -0.53948974609375 +23303 -0.43511962890625 +23304 -0.2962646484375 +23305 -0.161102294921875 +23306 -0.0435791015625 +23307 0.060394287109375 +23308 0.13665771484375 +23309 0.170135498046875 +23310 0.16552734375 +23311 0.15728759765625 +23312 0.150787353515625 +23313 0.12200927734375 +23314 0.080108642578125 +23315 0.05126953125 +23316 0.062896728515625 +23317 0.09271240234375 +23318 0.092987060546875 +23319 0.07855224609375 +23320 0.06427001953125 +23321 0.0347900390625 +23322 -0.01171875 +23323 -0.056060791015625 +23324 -0.055511474609375 +23325 -0.010467529296875 +23326 0.02508544921875 +23327 0.025665283203125 +23328 0.017333984375 +23329 0.00189208984375 +23330 -0.03173828125 +23331 -0.071502685546875 +23332 -0.13543701171875 +23333 -0.219970703125 +23334 -0.300506591796875 +23335 -0.376312255859375 +23336 -0.416107177734375 +23337 -0.371124267578125 +23338 -0.242279052734375 +23339 -0.069732666015625 +23340 0.125640869140625 +23341 0.31268310546875 +23342 0.45501708984375 +23343 0.554779052734375 +23344 0.61065673828125 +23345 0.610931396484375 +23346 0.531463623046875 +23347 0.3883056640625 +23348 0.23468017578125 +23349 0.095245361328125 +23350 -0.00396728515625 +23351 -0.04852294921875 +23352 -0.055145263671875 +23353 -0.0758056640625 +23354 -0.138702392578125 +23355 -0.209197998046875 +23356 -0.289031982421875 +23357 -0.37884521484375 +23358 -0.456329345703125 +23359 -0.51641845703125 +23360 -0.519287109375 +23361 -0.458251953125 +23362 -0.384796142578125 +23363 -0.323699951171875 +23364 -0.269287109375 +23365 -0.1951904296875 +23366 -0.100006103515625 +23367 -0.01055908203125 +23368 0.1033935546875 +23369 0.24908447265625 +23370 0.373199462890625 +23371 0.45806884765625 +23372 0.511474609375 +23373 0.565399169921875 +23374 0.61138916015625 +23375 0.5897216796875 +23376 0.4906005859375 +23377 0.33148193359375 +23378 0.147796630859375 +23379 -0.01873779296875 +23380 -0.140289306640625 +23381 -0.191986083984375 +23382 -0.184295654296875 +23383 -0.161834716796875 +23384 -0.166595458984375 +23385 -0.19390869140625 +23386 -0.22442626953125 +23387 -0.279754638671875 +23388 -0.3389892578125 +23389 -0.3543701171875 +23390 -0.348175048828125 +23391 -0.32598876953125 +23392 -0.2581787109375 +23393 -0.139801025390625 +23394 0.014617919921875 +23395 0.144378662109375 +23396 0.221038818359375 +23397 0.27069091796875 +23398 0.294036865234375 +23399 0.311767578125 +23400 0.339141845703125 +23401 0.360260009765625 +23402 0.360504150390625 +23403 0.308380126953125 +23404 0.18170166015625 +23405 0.0047607421875 +23406 -0.17559814453125 +23407 -0.3143310546875 +23408 -0.36785888671875 +23409 -0.36248779296875 +23410 -0.343536376953125 +23411 -0.3018798828125 +23412 -0.231414794921875 +23413 -0.117645263671875 +23414 0.007049560546875 +23415 0.087982177734375 +23416 0.13946533203125 +23417 0.17425537109375 +23418 0.188201904296875 +23419 0.171234130859375 +23420 0.118438720703125 +23421 0.05706787109375 +23422 -0.010711669921875 +23423 -0.0914306640625 +23424 -0.162322998046875 +23425 -0.194549560546875 +23426 -0.1492919921875 +23427 -0.02166748046875 +23428 0.124053955078125 +23429 0.211151123046875 +23430 0.240447998046875 +23431 0.242218017578125 +23432 0.2257080078125 +23433 0.194366455078125 +23434 0.115509033203125 +23435 0.0128173828125 +23436 -0.053802490234375 +23437 -0.110626220703125 +23438 -0.199493408203125 +23439 -0.29437255859375 +23440 -0.33221435546875 +23441 -0.27972412109375 +23442 -0.185333251953125 +23443 -0.128204345703125 +23444 -0.115692138671875 +23445 -0.116455078125 +23446 -0.105926513671875 +23447 -0.053955078125 +23448 0.048797607421875 +23449 0.157318115234375 +23450 0.212005615234375 +23451 0.218475341796875 +23452 0.23724365234375 +23453 0.30535888671875 +23454 0.38128662109375 +23455 0.404449462890625 +23456 0.3944091796875 +23457 0.3885498046875 +23458 0.362640380859375 +23459 0.27362060546875 +23460 0.11712646484375 +23461 -0.054901123046875 +23462 -0.19085693359375 +23463 -0.28570556640625 +23464 -0.339263916015625 +23465 -0.3775634765625 +23466 -0.445709228515625 +23467 -0.535064697265625 +23468 -0.629058837890625 +23469 -0.697601318359375 +23470 -0.70391845703125 +23471 -0.6424560546875 +23472 -0.491241455078125 +23473 -0.265716552734375 +23474 -0.023712158203125 +23475 0.201751708984375 +23476 0.375823974609375 +23477 0.485076904296875 +23478 0.56884765625 +23479 0.634765625 +23480 0.63763427734375 +23481 0.5660400390625 +23482 0.4720458984375 +23483 0.40692138671875 +23484 0.3778076171875 +23485 0.376953125 +23486 0.371978759765625 +23487 0.313140869140625 +23488 0.184417724609375 +23489 0.011199951171875 +23490 -0.171051025390625 +23491 -0.33740234375 +23492 -0.47198486328125 +23493 -0.560394287109375 +23494 -0.58056640625 +23495 -0.54754638671875 +23496 -0.508575439453125 +23497 -0.459503173828125 +23498 -0.394378662109375 +23499 -0.35260009765625 +23500 -0.31170654296875 +23501 -0.197418212890625 +23502 -0.007965087890625 +23503 0.207489013671875 +23504 0.409210205078125 +23505 0.57208251953125 +23506 0.66595458984375 +23507 0.65875244140625 +23508 0.56744384765625 +23509 0.431396484375 +23510 0.29443359375 +23511 0.182464599609375 +23512 0.06365966796875 +23513 -0.075958251953125 +23514 -0.189422607421875 +23515 -0.271942138671875 +23516 -0.342529296875 +23517 -0.364166259765625 +23518 -0.327239990234375 +23519 -0.2769775390625 +23520 -0.253692626953125 +23521 -0.24365234375 +23522 -0.1983642578125 +23523 -0.116241455078125 +23524 -0.036834716796875 +23525 0.034881591796875 +23526 0.09124755859375 +23527 0.10888671875 +23528 0.125518798828125 +23529 0.15771484375 +23530 0.17828369140625 +23531 0.17108154296875 +23532 0.129974365234375 +23533 0.082427978515625 +23534 0.027679443359375 +23535 -0.065643310546875 +23536 -0.15936279296875 +23537 -0.21307373046875 +23538 -0.234649658203125 +23539 -0.2001953125 +23540 -0.119171142578125 +23541 -0.024749755859375 +23542 0.085784912109375 +23543 0.178131103515625 +23544 0.215576171875 +23545 0.211456298828125 +23546 0.17523193359375 +23547 0.128753662109375 +23548 0.1019287109375 +23549 0.0743408203125 +23550 0.04327392578125 +23551 0.038177490234375 +23552 0.076263427734375 +23553 0.14105224609375 +23554 0.186431884765625 +23555 0.188812255859375 +23556 0.1390380859375 +23557 0.041778564453125 +23558 -0.079437255859375 +23559 -0.219390869140625 +23560 -0.367828369140625 +23561 -0.494873046875 +23562 -0.556243896484375 +23563 -0.508697509765625 +23564 -0.3756103515625 +23565 -0.218902587890625 +23566 -0.063751220703125 +23567 0.091552734375 +23568 0.23602294921875 +23569 0.342987060546875 +23570 0.39520263671875 +23571 0.389373779296875 +23572 0.324249267578125 +23573 0.224090576171875 +23574 0.124267578125 +23575 0.037078857421875 +23576 -0.010101318359375 +23577 -0.019439697265625 +23578 -0.022796630859375 +23579 -0.001556396484375 +23580 0.056304931640625 +23581 0.106719970703125 +23582 0.096893310546875 +23583 0.042694091796875 +23584 -0.018035888671875 +23585 -0.07586669921875 +23586 -0.11944580078125 +23587 -0.15972900390625 +23588 -0.202606201171875 +23589 -0.24859619140625 +23590 -0.30517578125 +23591 -0.36212158203125 +23592 -0.39141845703125 +23593 -0.35528564453125 +23594 -0.249969482421875 +23595 -0.092864990234375 +23596 0.08905029296875 +23597 0.2352294921875 +23598 0.318817138671875 +23599 0.358642578125 +23600 0.347747802734375 +23601 0.28564453125 +23602 0.223175048828125 +23603 0.196746826171875 +23604 0.179840087890625 +23605 0.155548095703125 +23606 0.151214599609375 +23607 0.156951904296875 +23608 0.13177490234375 +23609 0.100799560546875 +23610 0.087127685546875 +23611 0.05487060546875 +23612 -0.009002685546875 +23613 -0.10400390625 +23614 -0.229400634765625 +23615 -0.35552978515625 +23616 -0.441925048828125 +23617 -0.473846435546875 +23618 -0.464813232421875 +23619 -0.419097900390625 +23620 -0.334320068359375 +23621 -0.227935791015625 +23622 -0.12347412109375 +23623 -0.02764892578125 +23624 0.077667236328125 +23625 0.2132568359375 +23626 0.38885498046875 +23627 0.582794189453125 +23628 0.734039306640625 +23629 0.800140380859375 +23630 0.7783203125 +23631 0.6651611328125 +23632 0.45965576171875 +23633 0.199188232421875 +23634 -0.050689697265625 +23635 -0.23297119140625 +23636 -0.33013916015625 +23637 -0.368408203125 +23638 -0.378936767578125 +23639 -0.376983642578125 +23640 -0.37969970703125 +23641 -0.391510009765625 +23642 -0.385345458984375 +23643 -0.3419189453125 +23644 -0.28289794921875 +23645 -0.251617431640625 +23646 -0.266143798828125 +23647 -0.273345947265625 +23648 -0.216796875 +23649 -0.128265380859375 +23650 -0.068145751953125 +23651 -0.0430908203125 +23652 -0.024444580078125 +23653 0.020721435546875 +23654 0.124481201171875 +23655 0.25787353515625 +23656 0.379119873046875 +23657 0.47991943359375 +23658 0.5281982421875 +23659 0.511138916015625 +23660 0.456207275390625 +23661 0.407470703125 +23662 0.383758544921875 +23663 0.35687255859375 +23664 0.31182861328125 +23665 0.250885009765625 +23666 0.1654052734375 +23667 0.035247802734375 +23668 -0.142059326171875 +23669 -0.33563232421875 +23670 -0.5345458984375 +23671 -0.72186279296875 +23672 -0.836669921875 +23673 -0.8326416015625 +23674 -0.7296142578125 +23675 -0.582550048828125 +23676 -0.440093994140625 +23677 -0.324310302734375 +23678 -0.20147705078125 +23679 -0.044647216796875 +23680 0.103973388671875 +23681 0.202392578125 +23682 0.264495849609375 +23683 0.338897705078125 +23684 0.443817138671875 +23685 0.545074462890625 +23686 0.6173095703125 +23687 0.6524658203125 +23688 0.66339111328125 +23689 0.6561279296875 +23690 0.606781005859375 +23691 0.501190185546875 +23692 0.352783203125 +23693 0.176544189453125 +23694 -0.034820556640625 +23695 -0.258209228515625 +23696 -0.44244384765625 +23697 -0.5753173828125 +23698 -0.65203857421875 +23699 -0.641632080078125 +23700 -0.562164306640625 +23701 -0.458038330078125 +23702 -0.350555419921875 +23703 -0.260528564453125 +23704 -0.192108154296875 +23705 -0.141937255859375 +23706 -0.1021728515625 +23707 -0.062896728515625 +23708 -0.011932373046875 +23709 0.062835693359375 +23710 0.148712158203125 +23711 0.241729736328125 +23712 0.34912109375 +23713 0.457305908203125 +23714 0.54388427734375 +23715 0.5728759765625 +23716 0.506591796875 +23717 0.351226806640625 +23718 0.146514892578125 +23719 -0.05523681640625 +23720 -0.21624755859375 +23721 -0.334930419921875 +23722 -0.402984619140625 +23723 -0.4412841796875 +23724 -0.49578857421875 +23725 -0.5601806640625 +23726 -0.600738525390625 +23727 -0.584228515625 +23728 -0.47930908203125 +23729 -0.27935791015625 +23730 -0.0089111328125 +23731 0.268798828125 +23732 0.482818603515625 +23733 0.60369873046875 +23734 0.650421142578125 +23735 0.66400146484375 +23736 0.6414794921875 +23737 0.572540283203125 +23738 0.498138427734375 +23739 0.439453125 +23740 0.375518798828125 +23741 0.274505615234375 +23742 0.1087646484375 +23743 -0.099395751953125 +23744 -0.3182373046875 +23745 -0.5489501953125 +23746 -0.7738037109375 +23747 -0.86383056640625 +23748 -0.870391845703125 +23749 -0.86895751953125 +23750 -0.861053466796875 +23751 -0.765869140625 +23752 -0.5301513671875 +23753 -0.214691162109375 +23754 0.137359619140625 +23755 0.474822998046875 +23756 0.76239013671875 +23757 0.867462158203125 +23758 0.870361328125 +23759 0.86480712890625 +23760 0.831817626953125 +23761 0.677581787109375 +23762 0.495880126953125 +23763 0.30767822265625 +23764 0.116180419921875 +23765 -0.110748291015625 +23766 -0.381805419921875 +23767 -0.6572265625 +23768 -0.857421875 +23769 -0.870391845703125 +23770 -0.870391845703125 +23771 -0.86444091796875 +23772 -0.85723876953125 +23773 -0.790008544921875 +23774 -0.62847900390625 +23775 -0.3956298828125 +23776 -0.126708984375 +23777 0.150115966796875 +23778 0.424041748046875 +23779 0.670623779296875 +23780 0.854522705078125 +23781 0.866485595703125 +23782 0.86920166015625 +23783 0.8653564453125 +23784 0.857147216796875 +23785 0.766845703125 +23786 0.628509521484375 +23787 0.462127685546875 +23788 0.297210693359375 +23789 0.14862060546875 +23790 -0.00537109375 +23791 -0.15753173828125 +23792 -0.31304931640625 +23793 -0.48876953125 +23794 -0.6416015625 +23795 -0.751373291015625 +23796 -0.84619140625 +23797 -0.861297607421875 +23798 -0.863250732421875 +23799 -0.856597900390625 +23800 -0.7498779296875 +23801 -0.624542236328125 +23802 -0.47808837890625 +23803 -0.253387451171875 +23804 0.003692626953125 +23805 0.2257080078125 +23806 0.427154541015625 +23807 0.643218994140625 +23808 0.855926513671875 +23809 0.870361328125 +23810 0.870361328125 +23811 0.862762451171875 +23812 0.79669189453125 +23813 0.595794677734375 +23814 0.362152099609375 +23815 0.1270751953125 +23816 -0.086944580078125 +23817 -0.2784423828125 +23818 -0.484832763671875 +23819 -0.729583740234375 +23820 -0.86688232421875 +23821 -0.870391845703125 +23822 -0.86859130859375 +23823 -0.86279296875 +23824 -0.817962646484375 +23825 -0.6116943359375 +23826 -0.3128662109375 +23827 0.039398193359375 +23828 0.422821044921875 +23829 0.805145263671875 +23830 0.870361328125 +23831 0.870361328125 +23832 0.860015869140625 +23833 0.727935791015625 +23834 0.48114013671875 +23835 0.2059326171875 +23836 -0.06103515625 +23837 -0.29913330078125 +23838 -0.516204833984375 +23839 -0.7252197265625 +23840 -0.85980224609375 +23841 -0.870391845703125 +23842 -0.870391845703125 +23843 -0.858062744140625 +23844 -0.673004150390625 +23845 -0.42694091796875 +23846 -0.2100830078125 +23847 -0.0362548828125 +23848 0.10943603515625 +23849 0.23516845703125 +23850 0.373687744140625 +23851 0.517791748046875 +23852 0.602783203125 +23853 0.635711669921875 +23854 0.655181884765625 +23855 0.65948486328125 +23856 0.651275634765625 +23857 0.61846923828125 +23858 0.53753662109375 +23859 0.404144287109375 +23860 0.22186279296875 +23861 0.003997802734375 +23862 -0.22100830078125 +23863 -0.42449951171875 +23864 -0.579833984375 +23865 -0.641876220703125 +23866 -0.6177978515625 +23867 -0.575531005859375 +23868 -0.526336669921875 +23869 -0.42645263671875 +23870 -0.2581787109375 +23871 -0.068695068359375 +23872 0.09222412109375 +23873 0.232147216796875 +23874 0.3509521484375 +23875 0.410064697265625 +23876 0.372955322265625 +23877 0.2554931640625 +23878 0.10711669921875 +23879 -0.052886962890625 +23880 -0.186279296875 +23881 -0.23291015625 +23882 -0.209442138671875 +23883 -0.174163818359375 +23884 -0.126739501953125 +23885 -0.048126220703125 +23886 0.0426025390625 +23887 0.10748291015625 +23888 0.1409912109375 +23889 0.19708251953125 +23890 0.273651123046875 +23891 0.31768798828125 +23892 0.341094970703125 +23893 0.368011474609375 +23894 0.37249755859375 +23895 0.30072021484375 +23896 0.1517333984375 +23897 -0.01470947265625 +23898 -0.1883544921875 +23899 -0.372711181640625 +23900 -0.51397705078125 +23901 -0.57177734375 +23902 -0.53948974609375 +23903 -0.43511962890625 +23904 -0.2962646484375 +23905 -0.161102294921875 +23906 -0.0435791015625 +23907 0.060394287109375 +23908 0.13665771484375 +23909 0.170135498046875 +23910 0.16552734375 +23911 0.15728759765625 +23912 0.150787353515625 +23913 0.12200927734375 +23914 0.080108642578125 +23915 0.05126953125 +23916 0.062896728515625 +23917 0.09271240234375 +23918 0.092987060546875 +23919 0.07855224609375 +23920 0.06427001953125 +23921 0.0347900390625 +23922 -0.01171875 +23923 -0.056060791015625 +23924 -0.055511474609375 +23925 -0.010467529296875 +23926 0.02508544921875 +23927 0.025665283203125 +23928 0.017333984375 +23929 0.00189208984375 +23930 -0.03173828125 +23931 -0.071502685546875 +23932 -0.13543701171875 +23933 -0.219970703125 +23934 -0.300506591796875 +23935 -0.376312255859375 +23936 -0.416107177734375 +23937 -0.371124267578125 +23938 -0.242279052734375 +23939 -0.069732666015625 +23940 0.125640869140625 +23941 0.31268310546875 +23942 0.45501708984375 +23943 0.554779052734375 +23944 0.61065673828125 +23945 0.610931396484375 +23946 0.531463623046875 +23947 0.3883056640625 +23948 0.23468017578125 +23949 0.095245361328125 +23950 -0.00396728515625 +23951 -0.04852294921875 +23952 -0.055145263671875 +23953 -0.0758056640625 +23954 -0.138702392578125 +23955 -0.209197998046875 +23956 -0.289031982421875 +23957 -0.37884521484375 +23958 -0.456329345703125 +23959 -0.51641845703125 +23960 -0.519287109375 +23961 -0.458251953125 +23962 -0.384796142578125 +23963 -0.323699951171875 +23964 -0.269287109375 +23965 -0.1951904296875 +23966 -0.100006103515625 +23967 -0.01055908203125 +23968 0.1033935546875 +23969 0.24908447265625 +23970 0.373199462890625 +23971 0.45806884765625 +23972 0.511474609375 +23973 0.565399169921875 +23974 0.61138916015625 +23975 0.5897216796875 +23976 0.4906005859375 +23977 0.33148193359375 +23978 0.147796630859375 +23979 -0.01873779296875 +23980 -0.140289306640625 +23981 -0.191986083984375 +23982 -0.184295654296875 +23983 -0.161834716796875 +23984 -0.166595458984375 +23985 -0.19390869140625 +23986 -0.22442626953125 +23987 -0.279754638671875 +23988 -0.3389892578125 +23989 -0.3543701171875 +23990 -0.348175048828125 +23991 -0.32598876953125 +23992 -0.2581787109375 +23993 -0.139801025390625 +23994 0.014617919921875 +23995 0.144378662109375 +23996 0.221038818359375 +23997 0.27069091796875 +23998 0.294036865234375 +23999 0.311767578125 +24000 0.339141845703125 +24001 0.360260009765625 +24002 0.360504150390625 +24003 0.308380126953125 +24004 0.18170166015625 +24005 0.0047607421875 +24006 -0.17559814453125 +24007 -0.3143310546875 +24008 -0.36785888671875 +24009 -0.36248779296875 +24010 -0.343536376953125 +24011 -0.3018798828125 +24012 -0.231414794921875 +24013 -0.117645263671875 +24014 0.007049560546875 +24015 0.087982177734375 +24016 0.13946533203125 +24017 0.17425537109375 +24018 0.188201904296875 +24019 0.171234130859375 +24020 0.118438720703125 +24021 0.05706787109375 +24022 -0.010711669921875 +24023 -0.0914306640625 +24024 -0.162322998046875 +24025 -0.194549560546875 +24026 -0.1492919921875 +24027 -0.02166748046875 +24028 0.124053955078125 +24029 0.211151123046875 +24030 0.240447998046875 +24031 0.242218017578125 +24032 0.2257080078125 +24033 0.194366455078125 +24034 0.115509033203125 +24035 0.0128173828125 +24036 -0.053802490234375 +24037 -0.110626220703125 +24038 -0.199493408203125 +24039 -0.29437255859375 +24040 -0.33221435546875 +24041 -0.27972412109375 +24042 -0.185333251953125 +24043 -0.128204345703125 +24044 -0.115692138671875 +24045 -0.116455078125 +24046 -0.105926513671875 +24047 -0.053955078125 +24048 0.048797607421875 +24049 0.157318115234375 +24050 0.212005615234375 +24051 0.218475341796875 +24052 0.23724365234375 +24053 0.30535888671875 +24054 0.38128662109375 +24055 0.404449462890625 +24056 0.3944091796875 +24057 0.3885498046875 +24058 0.362640380859375 +24059 0.27362060546875 +24060 0.11712646484375 +24061 -0.054901123046875 +24062 -0.19085693359375 +24063 -0.28570556640625 +24064 -0.339263916015625 +24065 -0.3775634765625 +24066 -0.445709228515625 +24067 -0.535064697265625 +24068 -0.629058837890625 +24069 -0.697601318359375 +24070 -0.70391845703125 +24071 -0.6424560546875 +24072 -0.491241455078125 +24073 -0.265716552734375 +24074 -0.023712158203125 +24075 0.201751708984375 +24076 0.375823974609375 +24077 0.485076904296875 +24078 0.56884765625 +24079 0.634765625 +24080 0.63763427734375 +24081 0.5660400390625 +24082 0.4720458984375 +24083 0.40692138671875 +24084 0.3778076171875 +24085 0.376953125 +24086 0.371978759765625 +24087 0.313140869140625 +24088 0.184417724609375 +24089 0.011199951171875 +24090 -0.171051025390625 +24091 -0.33740234375 +24092 -0.47198486328125 +24093 -0.560394287109375 +24094 -0.58056640625 +24095 -0.54754638671875 +24096 -0.508575439453125 +24097 -0.459503173828125 +24098 -0.394378662109375 +24099 -0.35260009765625 +24100 -0.31170654296875 +24101 -0.197418212890625 +24102 -0.007965087890625 +24103 0.207489013671875 +24104 0.409210205078125 +24105 0.57208251953125 +24106 0.66595458984375 +24107 0.65875244140625 +24108 0.56744384765625 +24109 0.431396484375 +24110 0.29443359375 +24111 0.182464599609375 +24112 0.06365966796875 +24113 -0.075958251953125 +24114 -0.189422607421875 +24115 -0.271942138671875 +24116 -0.342529296875 +24117 -0.364166259765625 +24118 -0.327239990234375 +24119 -0.2769775390625 +24120 -0.253692626953125 +24121 -0.24365234375 +24122 -0.1983642578125 +24123 -0.116241455078125 +24124 -0.036834716796875 +24125 0.034881591796875 +24126 0.09124755859375 +24127 0.10888671875 +24128 0.125518798828125 +24129 0.15771484375 +24130 0.17828369140625 +24131 0.17108154296875 +24132 0.129974365234375 +24133 0.082427978515625 +24134 0.027679443359375 +24135 -0.065643310546875 +24136 -0.15936279296875 +24137 -0.21307373046875 +24138 -0.234649658203125 +24139 -0.2001953125 +24140 -0.119171142578125 +24141 -0.024749755859375 +24142 0.085784912109375 +24143 0.178131103515625 +24144 0.215576171875 +24145 0.211456298828125 +24146 0.17523193359375 +24147 0.128753662109375 +24148 0.1019287109375 +24149 0.0743408203125 +24150 0.04327392578125 +24151 0.038177490234375 +24152 0.076263427734375 +24153 0.14105224609375 +24154 0.186431884765625 +24155 0.188812255859375 +24156 0.1390380859375 +24157 0.041778564453125 +24158 -0.079437255859375 +24159 -0.219390869140625 +24160 -0.367828369140625 +24161 -0.494873046875 +24162 -0.556243896484375 +24163 -0.508697509765625 +24164 -0.3756103515625 +24165 -0.218902587890625 +24166 -0.063751220703125 +24167 0.091552734375 +24168 0.23602294921875 +24169 0.342987060546875 +24170 0.39520263671875 +24171 0.389373779296875 +24172 0.324249267578125 +24173 0.224090576171875 +24174 0.124267578125 +24175 0.037078857421875 +24176 -0.010101318359375 +24177 -0.019439697265625 +24178 -0.022796630859375 +24179 -0.001556396484375 +24180 0.056304931640625 +24181 0.106719970703125 +24182 0.096893310546875 +24183 0.042694091796875 +24184 -0.018035888671875 +24185 -0.07586669921875 +24186 -0.11944580078125 +24187 -0.15972900390625 +24188 -0.202606201171875 +24189 -0.24859619140625 +24190 -0.30517578125 +24191 -0.36212158203125 +24192 -0.39141845703125 +24193 -0.35528564453125 +24194 -0.249969482421875 +24195 -0.092864990234375 +24196 0.08905029296875 +24197 0.2352294921875 +24198 0.318817138671875 +24199 0.358642578125 +24200 0.347747802734375 +24201 0.28564453125 +24202 0.223175048828125 +24203 0.196746826171875 +24204 0.179840087890625 +24205 0.155548095703125 +24206 0.151214599609375 +24207 0.156951904296875 +24208 0.13177490234375 +24209 0.100799560546875 +24210 0.087127685546875 +24211 0.05487060546875 +24212 -0.009002685546875 +24213 -0.10400390625 +24214 -0.229400634765625 +24215 -0.35552978515625 +24216 -0.441925048828125 +24217 -0.473846435546875 +24218 -0.464813232421875 +24219 -0.419097900390625 +24220 -0.334320068359375 +24221 -0.227935791015625 +24222 -0.12347412109375 +24223 -0.02764892578125 +24224 0.077667236328125 +24225 0.2132568359375 +24226 0.38885498046875 +24227 0.582794189453125 +24228 0.734039306640625 +24229 0.800140380859375 +24230 0.7783203125 +24231 0.6651611328125 +24232 0.45965576171875 +24233 0.199188232421875 +24234 -0.050689697265625 +24235 -0.23297119140625 +24236 -0.33013916015625 +24237 -0.368408203125 +24238 -0.378936767578125 +24239 -0.376983642578125 +24240 -0.37969970703125 +24241 -0.391510009765625 +24242 -0.385345458984375 +24243 -0.3419189453125 +24244 -0.28289794921875 +24245 -0.251617431640625 +24246 -0.266143798828125 +24247 -0.273345947265625 +24248 -0.216796875 +24249 -0.128265380859375 +24250 -0.068145751953125 +24251 -0.0430908203125 +24252 -0.024444580078125 +24253 0.020721435546875 +24254 0.124481201171875 +24255 0.25787353515625 +24256 0.379119873046875 +24257 0.47991943359375 +24258 0.5281982421875 +24259 0.511138916015625 +24260 0.456207275390625 +24261 0.407470703125 +24262 0.383758544921875 +24263 0.35687255859375 +24264 0.31182861328125 +24265 0.250885009765625 +24266 0.1654052734375 +24267 0.035247802734375 +24268 -0.142059326171875 +24269 -0.33563232421875 +24270 -0.5345458984375 +24271 -0.72186279296875 +24272 -0.836669921875 +24273 -0.8326416015625 +24274 -0.7296142578125 +24275 -0.582550048828125 +24276 -0.440093994140625 +24277 -0.324310302734375 +24278 -0.20147705078125 +24279 -0.044647216796875 +24280 0.103973388671875 +24281 0.202392578125 +24282 0.264495849609375 +24283 0.338897705078125 +24284 0.443817138671875 +24285 0.545074462890625 +24286 0.6173095703125 +24287 0.6524658203125 +24288 0.66339111328125 +24289 0.6561279296875 +24290 0.606781005859375 +24291 0.501190185546875 +24292 0.352783203125 +24293 0.176544189453125 +24294 -0.034820556640625 +24295 -0.258209228515625 +24296 -0.44244384765625 +24297 -0.5753173828125 +24298 -0.65203857421875 +24299 -0.641632080078125 +24300 -0.562164306640625 +24301 -0.458038330078125 +24302 -0.350555419921875 +24303 -0.260528564453125 +24304 -0.192108154296875 +24305 -0.141937255859375 +24306 -0.1021728515625 +24307 -0.062896728515625 +24308 -0.011932373046875 +24309 0.062835693359375 +24310 0.148712158203125 +24311 0.241729736328125 +24312 0.34912109375 +24313 0.457305908203125 +24314 0.54388427734375 +24315 0.5728759765625 +24316 0.506591796875 +24317 0.351226806640625 +24318 0.146514892578125 +24319 -0.05523681640625 +24320 -0.21624755859375 +24321 -0.334930419921875 +24322 -0.402984619140625 +24323 -0.4412841796875 +24324 -0.49578857421875 +24325 -0.5601806640625 +24326 -0.600738525390625 +24327 -0.584228515625 +24328 -0.47930908203125 +24329 -0.27935791015625 +24330 -0.0089111328125 +24331 0.268798828125 +24332 0.482818603515625 +24333 0.60369873046875 +24334 0.650421142578125 +24335 0.66400146484375 +24336 0.6414794921875 +24337 0.572540283203125 +24338 0.498138427734375 +24339 0.439453125 +24340 0.375518798828125 +24341 0.274505615234375 +24342 0.1087646484375 +24343 -0.099395751953125 +24344 -0.3182373046875 +24345 -0.5489501953125 +24346 -0.7738037109375 +24347 -0.86383056640625 +24348 -0.870391845703125 +24349 -0.86895751953125 +24350 -0.861053466796875 +24351 -0.765869140625 +24352 -0.5301513671875 +24353 -0.214691162109375 +24354 0.137359619140625 +24355 0.474822998046875 +24356 0.76239013671875 +24357 0.867462158203125 +24358 0.870361328125 +24359 0.86480712890625 +24360 0.831817626953125 +24361 0.677581787109375 +24362 0.495880126953125 +24363 0.30767822265625 +24364 0.116180419921875 +24365 -0.110748291015625 +24366 -0.381805419921875 +24367 -0.6572265625 +24368 -0.857421875 +24369 -0.870391845703125 +24370 -0.870391845703125 +24371 -0.86444091796875 +24372 -0.85723876953125 +24373 -0.790008544921875 +24374 -0.62847900390625 +24375 -0.3956298828125 +24376 -0.126708984375 +24377 0.150115966796875 +24378 0.424041748046875 +24379 0.670623779296875 +24380 0.854522705078125 +24381 0.866485595703125 +24382 0.86920166015625 +24383 0.8653564453125 +24384 0.857147216796875 +24385 0.766845703125 +24386 0.628509521484375 +24387 0.462127685546875 +24388 0.297210693359375 +24389 0.14862060546875 +24390 -0.00537109375 +24391 -0.15753173828125 +24392 -0.31304931640625 +24393 -0.48876953125 +24394 -0.6416015625 +24395 -0.751373291015625 +24396 -0.84619140625 +24397 -0.861297607421875 +24398 -0.863250732421875 +24399 -0.856597900390625 +24400 -0.7498779296875 +24401 -0.624542236328125 +24402 -0.47808837890625 +24403 -0.253387451171875 +24404 0.003692626953125 +24405 0.2257080078125 +24406 0.427154541015625 +24407 0.643218994140625 +24408 0.855926513671875 +24409 0.870361328125 +24410 0.870361328125 +24411 0.862762451171875 +24412 0.79669189453125 +24413 0.595794677734375 +24414 0.362152099609375 +24415 0.1270751953125 +24416 -0.086944580078125 +24417 -0.2784423828125 +24418 -0.484832763671875 +24419 -0.729583740234375 +24420 -0.86688232421875 +24421 -0.870391845703125 +24422 -0.86859130859375 +24423 -0.86279296875 +24424 -0.817962646484375 +24425 -0.6116943359375 +24426 -0.3128662109375 +24427 0.039398193359375 +24428 0.422821044921875 +24429 0.805145263671875 +24430 0.870361328125 +24431 0.870361328125 +24432 0.860015869140625 +24433 0.727935791015625 +24434 0.48114013671875 +24435 0.2059326171875 +24436 -0.06103515625 +24437 -0.29913330078125 +24438 -0.516204833984375 +24439 -0.7252197265625 +24440 -0.85980224609375 +24441 -0.870391845703125 +24442 -0.870391845703125 +24443 -0.858062744140625 +24444 -0.673004150390625 +24445 -0.42694091796875 +24446 -0.2100830078125 +24447 -0.0362548828125 +24448 0.10943603515625 +24449 0.23516845703125 +24450 0.373687744140625 +24451 0.517791748046875 +24452 0.602783203125 +24453 0.635711669921875 +24454 0.655181884765625 +24455 0.65948486328125 +24456 0.651275634765625 +24457 0.61846923828125 +24458 0.53753662109375 +24459 0.404144287109375 +24460 0.22186279296875 +24461 0.003997802734375 +24462 -0.22100830078125 +24463 -0.42449951171875 +24464 -0.579833984375 +24465 -0.641876220703125 +24466 -0.6177978515625 +24467 -0.575531005859375 +24468 -0.526336669921875 +24469 -0.42645263671875 +24470 -0.2581787109375 +24471 -0.068695068359375 +24472 0.09222412109375 +24473 0.232147216796875 +24474 0.3509521484375 +24475 0.410064697265625 +24476 0.372955322265625 +24477 0.2554931640625 +24478 0.10711669921875 +24479 -0.052886962890625 +24480 -0.186279296875 +24481 -0.23291015625 +24482 -0.209442138671875 +24483 -0.174163818359375 +24484 -0.126739501953125 +24485 -0.048126220703125 +24486 0.0426025390625 +24487 0.10748291015625 +24488 0.1409912109375 +24489 0.19708251953125 +24490 0.273651123046875 +24491 0.31768798828125 +24492 0.341094970703125 +24493 0.368011474609375 +24494 0.37249755859375 +24495 0.30072021484375 +24496 0.1517333984375 +24497 -0.01470947265625 +24498 -0.1883544921875 +24499 -0.372711181640625 +24500 -0.51397705078125 +24501 -0.57177734375 +24502 -0.53948974609375 +24503 -0.43511962890625 +24504 -0.2962646484375 +24505 -0.161102294921875 +24506 -0.0435791015625 +24507 0.060394287109375 +24508 0.13665771484375 +24509 0.170135498046875 +24510 0.16552734375 +24511 0.15728759765625 +24512 0.150787353515625 +24513 0.12200927734375 +24514 0.080108642578125 +24515 0.05126953125 +24516 0.062896728515625 +24517 0.09271240234375 +24518 0.092987060546875 +24519 0.07855224609375 +24520 0.06427001953125 +24521 0.0347900390625 +24522 -0.01171875 +24523 -0.056060791015625 +24524 -0.055511474609375 +24525 -0.010467529296875 +24526 0.02508544921875 +24527 0.025665283203125 +24528 0.017333984375 +24529 0.00189208984375 +24530 -0.03173828125 +24531 -0.071502685546875 +24532 -0.13543701171875 +24533 -0.219970703125 +24534 -0.300506591796875 +24535 -0.376312255859375 +24536 -0.416107177734375 +24537 -0.371124267578125 +24538 -0.242279052734375 +24539 -0.069732666015625 +24540 0.125640869140625 +24541 0.31268310546875 +24542 0.45501708984375 +24543 0.554779052734375 +24544 0.61065673828125 +24545 0.610931396484375 +24546 0.531463623046875 +24547 0.3883056640625 +24548 0.23468017578125 +24549 0.095245361328125 +24550 -0.00396728515625 +24551 -0.04852294921875 +24552 -0.055145263671875 +24553 -0.0758056640625 +24554 -0.138702392578125 +24555 -0.209197998046875 +24556 -0.289031982421875 +24557 -0.37884521484375 +24558 -0.456329345703125 +24559 -0.51641845703125 +24560 -0.519287109375 +24561 -0.458251953125 +24562 -0.384796142578125 +24563 -0.323699951171875 +24564 -0.269287109375 +24565 -0.1951904296875 +24566 -0.100006103515625 +24567 -0.01055908203125 +24568 0.1033935546875 +24569 0.24908447265625 +24570 0.373199462890625 +24571 0.45806884765625 +24572 0.511474609375 +24573 0.565399169921875 +24574 0.61138916015625 +24575 0.5897216796875 +24576 0.4906005859375 +24577 0.33148193359375 +24578 0.147796630859375 +24579 -0.01873779296875 +24580 -0.140289306640625 +24581 -0.191986083984375 +24582 -0.184295654296875 +24583 -0.161834716796875 +24584 -0.166595458984375 +24585 -0.19390869140625 +24586 -0.22442626953125 +24587 -0.279754638671875 +24588 -0.3389892578125 +24589 -0.3543701171875 +24590 -0.348175048828125 +24591 -0.32598876953125 +24592 -0.2581787109375 +24593 -0.139801025390625 +24594 0.014617919921875 +24595 0.144378662109375 +24596 0.221038818359375 +24597 0.27069091796875 +24598 0.294036865234375 +24599 0.311767578125 +24600 0.339141845703125 +24601 0.360260009765625 +24602 0.360504150390625 +24603 0.308380126953125 +24604 0.18170166015625 +24605 0.0047607421875 +24606 -0.17559814453125 +24607 -0.3143310546875 +24608 -0.36785888671875 +24609 -0.36248779296875 +24610 -0.343536376953125 +24611 -0.3018798828125 +24612 -0.231414794921875 +24613 -0.117645263671875 +24614 0.007049560546875 +24615 0.087982177734375 +24616 0.13946533203125 +24617 0.17425537109375 +24618 0.188201904296875 +24619 0.171234130859375 +24620 0.118438720703125 +24621 0.05706787109375 +24622 -0.010711669921875 +24623 -0.0914306640625 +24624 -0.162322998046875 +24625 -0.194549560546875 +24626 -0.1492919921875 +24627 -0.02166748046875 +24628 0.124053955078125 +24629 0.211151123046875 +24630 0.240447998046875 +24631 0.242218017578125 +24632 0.2257080078125 +24633 0.194366455078125 +24634 0.115509033203125 +24635 0.0128173828125 +24636 -0.053802490234375 +24637 -0.110626220703125 +24638 -0.199493408203125 +24639 -0.29437255859375 +24640 -0.33221435546875 +24641 -0.27972412109375 +24642 -0.185333251953125 +24643 -0.128204345703125 +24644 -0.115692138671875 +24645 -0.116455078125 +24646 -0.105926513671875 +24647 -0.053955078125 +24648 0.048797607421875 +24649 0.157318115234375 +24650 0.212005615234375 +24651 0.218475341796875 +24652 0.23724365234375 +24653 0.30535888671875 +24654 0.38128662109375 +24655 0.404449462890625 +24656 0.3944091796875 +24657 0.3885498046875 +24658 0.362640380859375 +24659 0.27362060546875 +24660 0.11712646484375 +24661 -0.054901123046875 +24662 -0.19085693359375 +24663 -0.28570556640625 +24664 -0.339263916015625 +24665 -0.3775634765625 +24666 -0.445709228515625 +24667 -0.535064697265625 +24668 -0.629058837890625 +24669 -0.697601318359375 +24670 -0.70391845703125 +24671 -0.6424560546875 +24672 -0.491241455078125 +24673 -0.265716552734375 +24674 -0.023712158203125 +24675 0.201751708984375 +24676 0.375823974609375 +24677 0.485076904296875 +24678 0.56884765625 +24679 0.634765625 +24680 0.63763427734375 +24681 0.5660400390625 +24682 0.4720458984375 +24683 0.40692138671875 +24684 0.3778076171875 +24685 0.376953125 +24686 0.371978759765625 +24687 0.313140869140625 +24688 0.184417724609375 +24689 0.011199951171875 +24690 -0.171051025390625 +24691 -0.33740234375 +24692 -0.47198486328125 +24693 -0.560394287109375 +24694 -0.58056640625 +24695 -0.54754638671875 +24696 -0.508575439453125 +24697 -0.459503173828125 +24698 -0.394378662109375 +24699 -0.35260009765625 +24700 -0.31170654296875 +24701 -0.197418212890625 +24702 -0.007965087890625 +24703 0.207489013671875 +24704 0.409210205078125 +24705 0.57208251953125 +24706 0.66595458984375 +24707 0.65875244140625 +24708 0.56744384765625 +24709 0.431396484375 +24710 0.29443359375 +24711 0.182464599609375 +24712 0.06365966796875 +24713 -0.075958251953125 +24714 -0.189422607421875 +24715 -0.271942138671875 +24716 -0.342529296875 +24717 -0.364166259765625 +24718 -0.327239990234375 +24719 -0.2769775390625 +24720 -0.253692626953125 +24721 -0.24365234375 +24722 -0.1983642578125 +24723 -0.116241455078125 +24724 -0.036834716796875 +24725 0.034881591796875 +24726 0.09124755859375 +24727 0.10888671875 +24728 0.125518798828125 +24729 0.15771484375 +24730 0.17828369140625 +24731 0.17108154296875 +24732 0.129974365234375 +24733 0.082427978515625 +24734 0.027679443359375 +24735 -0.065643310546875 +24736 -0.15936279296875 +24737 -0.21307373046875 +24738 -0.234649658203125 +24739 -0.2001953125 +24740 -0.119171142578125 +24741 -0.024749755859375 +24742 0.085784912109375 +24743 0.178131103515625 +24744 0.215576171875 +24745 0.211456298828125 +24746 0.17523193359375 +24747 0.128753662109375 +24748 0.1019287109375 +24749 0.0743408203125 +24750 0.04327392578125 +24751 0.038177490234375 +24752 0.076263427734375 +24753 0.14105224609375 +24754 0.186431884765625 +24755 0.188812255859375 +24756 0.1390380859375 +24757 0.041778564453125 +24758 -0.079437255859375 +24759 -0.219390869140625 +24760 -0.367828369140625 +24761 -0.494873046875 +24762 -0.556243896484375 +24763 -0.508697509765625 +24764 -0.3756103515625 +24765 -0.218902587890625 +24766 -0.063751220703125 +24767 0.091552734375 +24768 0.23602294921875 +24769 0.342987060546875 +24770 0.39520263671875 +24771 0.389373779296875 +24772 0.324249267578125 +24773 0.224090576171875 +24774 0.124267578125 +24775 0.037078857421875 +24776 -0.010101318359375 +24777 -0.019439697265625 +24778 -0.022796630859375 +24779 -0.001556396484375 +24780 0.056304931640625 +24781 0.106719970703125 +24782 0.096893310546875 +24783 0.042694091796875 +24784 -0.018035888671875 +24785 -0.07586669921875 +24786 -0.11944580078125 +24787 -0.15972900390625 +24788 -0.202606201171875 +24789 -0.24859619140625 +24790 -0.30517578125 +24791 -0.36212158203125 +24792 -0.39141845703125 +24793 -0.35528564453125 +24794 -0.249969482421875 +24795 -0.092864990234375 +24796 0.08905029296875 +24797 0.2352294921875 +24798 0.318817138671875 +24799 0.358642578125 +24800 0.347747802734375 +24801 0.28564453125 +24802 0.223175048828125 +24803 0.196746826171875 +24804 0.179840087890625 +24805 0.155548095703125 +24806 0.151214599609375 +24807 0.156951904296875 +24808 0.13177490234375 +24809 0.100799560546875 +24810 0.087127685546875 +24811 0.05487060546875 +24812 -0.009002685546875 +24813 -0.10400390625 +24814 -0.229400634765625 +24815 -0.35552978515625 +24816 -0.441925048828125 +24817 -0.473846435546875 +24818 -0.464813232421875 +24819 -0.419097900390625 +24820 -0.334320068359375 +24821 -0.227935791015625 +24822 -0.12347412109375 +24823 -0.02764892578125 +24824 0.077667236328125 +24825 0.2132568359375 +24826 0.38885498046875 +24827 0.582794189453125 +24828 0.734039306640625 +24829 0.800140380859375 +24830 0.7783203125 +24831 0.6651611328125 +24832 0.45965576171875 +24833 0.199188232421875 +24834 -0.050689697265625 +24835 -0.23297119140625 +24836 -0.33013916015625 +24837 -0.368408203125 +24838 -0.378936767578125 +24839 -0.376983642578125 +24840 -0.37969970703125 +24841 -0.391510009765625 +24842 -0.385345458984375 +24843 -0.3419189453125 +24844 -0.28289794921875 +24845 -0.251617431640625 +24846 -0.266143798828125 +24847 -0.273345947265625 +24848 -0.216796875 +24849 -0.128265380859375 +24850 -0.068145751953125 +24851 -0.0430908203125 +24852 -0.024444580078125 +24853 0.020721435546875 +24854 0.124481201171875 +24855 0.25787353515625 +24856 0.379119873046875 +24857 0.47991943359375 +24858 0.5281982421875 +24859 0.511138916015625 +24860 0.456207275390625 +24861 0.407470703125 +24862 0.383758544921875 +24863 0.35687255859375 +24864 0.31182861328125 +24865 0.250885009765625 +24866 0.1654052734375 +24867 0.035247802734375 +24868 -0.142059326171875 +24869 -0.33563232421875 +24870 -0.5345458984375 +24871 -0.72186279296875 +24872 -0.836669921875 +24873 -0.8326416015625 +24874 -0.7296142578125 +24875 -0.582550048828125 +24876 -0.440093994140625 +24877 -0.324310302734375 +24878 -0.20147705078125 +24879 -0.044647216796875 +24880 0.103973388671875 +24881 0.202392578125 +24882 0.264495849609375 +24883 0.338897705078125 +24884 0.443817138671875 +24885 0.545074462890625 +24886 0.6173095703125 +24887 0.6524658203125 +24888 0.66339111328125 +24889 0.6561279296875 +24890 0.606781005859375 +24891 0.501190185546875 +24892 0.352783203125 +24893 0.176544189453125 +24894 -0.034820556640625 +24895 -0.258209228515625 +24896 -0.44244384765625 +24897 -0.5753173828125 +24898 -0.65203857421875 +24899 -0.641632080078125 +24900 -0.562164306640625 +24901 -0.458038330078125 +24902 -0.350555419921875 +24903 -0.260528564453125 +24904 -0.192108154296875 +24905 -0.141937255859375 +24906 -0.1021728515625 +24907 -0.062896728515625 +24908 -0.011932373046875 +24909 0.062835693359375 +24910 0.148712158203125 +24911 0.241729736328125 +24912 0.34912109375 +24913 0.457305908203125 +24914 0.54388427734375 +24915 0.5728759765625 +24916 0.506591796875 +24917 0.351226806640625 +24918 0.146514892578125 +24919 -0.05523681640625 +24920 -0.21624755859375 +24921 -0.334930419921875 +24922 -0.402984619140625 +24923 -0.4412841796875 +24924 -0.49578857421875 +24925 -0.5601806640625 +24926 -0.600738525390625 +24927 -0.584228515625 +24928 -0.47930908203125 +24929 -0.27935791015625 +24930 -0.0089111328125 +24931 0.268798828125 +24932 0.482818603515625 +24933 0.60369873046875 +24934 0.650421142578125 +24935 0.66400146484375 +24936 0.6414794921875 +24937 0.572540283203125 +24938 0.498138427734375 +24939 0.439453125 +24940 0.375518798828125 +24941 0.274505615234375 +24942 0.1087646484375 +24943 -0.099395751953125 +24944 -0.3182373046875 +24945 -0.5489501953125 +24946 -0.7738037109375 +24947 -0.86383056640625 +24948 -0.870391845703125 +24949 -0.86895751953125 +24950 -0.861053466796875 +24951 -0.765869140625 +24952 -0.5301513671875 +24953 -0.214691162109375 +24954 0.137359619140625 +24955 0.474822998046875 +24956 0.76239013671875 +24957 0.867462158203125 +24958 0.870361328125 +24959 0.86480712890625 +24960 0.831817626953125 +24961 0.677581787109375 +24962 0.495880126953125 +24963 0.30767822265625 +24964 0.116180419921875 +24965 -0.110748291015625 +24966 -0.381805419921875 +24967 -0.6572265625 +24968 -0.857421875 +24969 -0.870391845703125 +24970 -0.870391845703125 +24971 -0.86444091796875 +24972 -0.85723876953125 +24973 -0.790008544921875 +24974 -0.62847900390625 +24975 -0.3956298828125 +24976 -0.126708984375 +24977 0.150115966796875 +24978 0.424041748046875 +24979 0.670623779296875 +24980 0.854522705078125 +24981 0.866485595703125 +24982 0.86920166015625 +24983 0.8653564453125 +24984 0.857147216796875 +24985 0.766845703125 +24986 0.628509521484375 +24987 0.462127685546875 +24988 0.297210693359375 +24989 0.14862060546875 +24990 -0.00537109375 +24991 -0.15753173828125 +24992 -0.31304931640625 +24993 -0.48876953125 +24994 -0.6416015625 +24995 -0.751373291015625 +24996 -0.84619140625 +24997 -0.861297607421875 +24998 -0.863250732421875 +24999 -0.856597900390625 +25000 -0.7498779296875 +25001 -0.624542236328125 +25002 -0.47808837890625 +25003 -0.253387451171875 +25004 0.003692626953125 +25005 0.2257080078125 +25006 0.427154541015625 +25007 0.643218994140625 +25008 0.855926513671875 +25009 0.870361328125 +25010 0.870361328125 +25011 0.862762451171875 +25012 0.79669189453125 +25013 0.595794677734375 +25014 0.362152099609375 +25015 0.1270751953125 +25016 -0.086944580078125 +25017 -0.2784423828125 +25018 -0.484832763671875 +25019 -0.729583740234375 +25020 -0.86688232421875 +25021 -0.870391845703125 +25022 -0.86859130859375 +25023 -0.86279296875 +25024 -0.817962646484375 +25025 -0.6116943359375 +25026 -0.3128662109375 +25027 0.039398193359375 +25028 0.422821044921875 +25029 0.805145263671875 +25030 0.870361328125 +25031 0.870361328125 +25032 0.860015869140625 +25033 0.727935791015625 +25034 0.48114013671875 +25035 0.2059326171875 +25036 -0.06103515625 +25037 -0.29913330078125 +25038 -0.516204833984375 +25039 -0.7252197265625 +25040 -0.85980224609375 +25041 -0.870391845703125 +25042 -0.870391845703125 +25043 -0.858062744140625 +25044 -0.673004150390625 +25045 -0.42694091796875 +25046 -0.2100830078125 +25047 -0.0362548828125 +25048 0.10943603515625 +25049 0.23516845703125 +25050 0.373687744140625 +25051 0.517791748046875 +25052 0.602783203125 +25053 0.635711669921875 +25054 0.655181884765625 +25055 0.65948486328125 +25056 0.651275634765625 +25057 0.61846923828125 +25058 0.53753662109375 +25059 0.404144287109375 +25060 0.22186279296875 +25061 0.003997802734375 +25062 -0.22100830078125 +25063 -0.42449951171875 +25064 -0.579833984375 +25065 -0.641876220703125 +25066 -0.6177978515625 +25067 -0.575531005859375 +25068 -0.526336669921875 +25069 -0.42645263671875 +25070 -0.2581787109375 +25071 -0.068695068359375 +25072 0.09222412109375 +25073 0.232147216796875 +25074 0.3509521484375 +25075 0.410064697265625 +25076 0.372955322265625 +25077 0.2554931640625 +25078 0.10711669921875 +25079 -0.052886962890625 +25080 -0.186279296875 +25081 -0.23291015625 +25082 -0.209442138671875 +25083 -0.174163818359375 +25084 -0.126739501953125 +25085 -0.048126220703125 +25086 0.0426025390625 +25087 0.10748291015625 +25088 0.1409912109375 +25089 0.19708251953125 +25090 0.273651123046875 +25091 0.31768798828125 +25092 0.341094970703125 +25093 0.368011474609375 +25094 0.37249755859375 +25095 0.30072021484375 +25096 0.1517333984375 +25097 -0.01470947265625 +25098 -0.1883544921875 +25099 -0.372711181640625 +25100 -0.51397705078125 +25101 -0.57177734375 +25102 -0.53948974609375 +25103 -0.43511962890625 +25104 -0.2962646484375 +25105 -0.161102294921875 +25106 -0.0435791015625 +25107 0.060394287109375 +25108 0.13665771484375 +25109 0.170135498046875 +25110 0.16552734375 +25111 0.15728759765625 +25112 0.150787353515625 +25113 0.12200927734375 +25114 0.080108642578125 +25115 0.05126953125 +25116 0.062896728515625 +25117 0.09271240234375 +25118 0.092987060546875 +25119 0.07855224609375 +25120 0.06427001953125 +25121 0.0347900390625 +25122 -0.01171875 +25123 -0.056060791015625 +25124 -0.055511474609375 +25125 -0.010467529296875 +25126 0.02508544921875 +25127 0.025665283203125 +25128 0.017333984375 +25129 0.00189208984375 +25130 -0.03173828125 +25131 -0.071502685546875 +25132 -0.13543701171875 +25133 -0.219970703125 +25134 -0.300506591796875 +25135 -0.376312255859375 +25136 -0.416107177734375 +25137 -0.371124267578125 +25138 -0.242279052734375 +25139 -0.069732666015625 +25140 0.125640869140625 +25141 0.31268310546875 +25142 0.45501708984375 +25143 0.554779052734375 +25144 0.61065673828125 +25145 0.610931396484375 +25146 0.531463623046875 +25147 0.3883056640625 +25148 0.23468017578125 +25149 0.095245361328125 +25150 -0.00396728515625 +25151 -0.04852294921875 +25152 -0.055145263671875 +25153 -0.0758056640625 +25154 -0.138702392578125 +25155 -0.209197998046875 +25156 -0.289031982421875 +25157 -0.37884521484375 +25158 -0.456329345703125 +25159 -0.51641845703125 +25160 -0.519287109375 +25161 -0.458251953125 +25162 -0.384796142578125 +25163 -0.323699951171875 +25164 -0.269287109375 +25165 -0.1951904296875 +25166 -0.100006103515625 +25167 -0.01055908203125 +25168 0.1033935546875 +25169 0.24908447265625 +25170 0.373199462890625 +25171 0.45806884765625 +25172 0.511474609375 +25173 0.565399169921875 +25174 0.61138916015625 +25175 0.5897216796875 +25176 0.4906005859375 +25177 0.33148193359375 +25178 0.147796630859375 +25179 -0.01873779296875 +25180 -0.140289306640625 +25181 -0.191986083984375 +25182 -0.184295654296875 +25183 -0.161834716796875 +25184 -0.166595458984375 +25185 -0.19390869140625 +25186 -0.22442626953125 +25187 -0.279754638671875 +25188 -0.3389892578125 +25189 -0.3543701171875 +25190 -0.348175048828125 +25191 -0.32598876953125 +25192 -0.2581787109375 +25193 -0.139801025390625 +25194 0.014617919921875 +25195 0.144378662109375 +25196 0.221038818359375 +25197 0.27069091796875 +25198 0.294036865234375 +25199 0.311767578125 +25200 0.339141845703125 +25201 0.360260009765625 +25202 0.360504150390625 +25203 0.308380126953125 +25204 0.18170166015625 +25205 0.0047607421875 +25206 -0.17559814453125 +25207 -0.3143310546875 +25208 -0.36785888671875 +25209 -0.36248779296875 +25210 -0.343536376953125 +25211 -0.3018798828125 +25212 -0.231414794921875 +25213 -0.117645263671875 +25214 0.007049560546875 +25215 0.087982177734375 +25216 0.13946533203125 +25217 0.17425537109375 +25218 0.188201904296875 +25219 0.171234130859375 +25220 0.118438720703125 +25221 0.05706787109375 +25222 -0.010711669921875 +25223 -0.0914306640625 +25224 -0.162322998046875 +25225 -0.194549560546875 +25226 -0.1492919921875 +25227 -0.02166748046875 +25228 0.124053955078125 +25229 0.211151123046875 +25230 0.240447998046875 +25231 0.242218017578125 +25232 0.2257080078125 +25233 0.194366455078125 +25234 0.115509033203125 +25235 0.0128173828125 +25236 -0.053802490234375 +25237 -0.110626220703125 +25238 -0.199493408203125 +25239 -0.29437255859375 +25240 -0.33221435546875 +25241 -0.27972412109375 +25242 -0.185333251953125 +25243 -0.128204345703125 +25244 -0.115692138671875 +25245 -0.116455078125 +25246 -0.105926513671875 +25247 -0.053955078125 +25248 0.048797607421875 +25249 0.157318115234375 +25250 0.212005615234375 +25251 0.218475341796875 +25252 0.23724365234375 +25253 0.30535888671875 +25254 0.38128662109375 +25255 0.404449462890625 +25256 0.3944091796875 +25257 0.3885498046875 +25258 0.362640380859375 +25259 0.27362060546875 +25260 0.11712646484375 +25261 -0.054901123046875 +25262 -0.19085693359375 +25263 -0.28570556640625 +25264 -0.339263916015625 +25265 -0.3775634765625 +25266 -0.445709228515625 +25267 -0.535064697265625 +25268 -0.629058837890625 +25269 -0.697601318359375 +25270 -0.70391845703125 +25271 -0.6424560546875 +25272 -0.491241455078125 +25273 -0.265716552734375 +25274 -0.023712158203125 +25275 0.201751708984375 +25276 0.375823974609375 +25277 0.485076904296875 +25278 0.56884765625 +25279 0.634765625 +25280 0.63763427734375 +25281 0.5660400390625 +25282 0.4720458984375 +25283 0.40692138671875 +25284 0.3778076171875 +25285 0.376953125 +25286 0.371978759765625 +25287 0.313140869140625 +25288 0.184417724609375 +25289 0.011199951171875 +25290 -0.171051025390625 +25291 -0.33740234375 +25292 -0.47198486328125 +25293 -0.560394287109375 +25294 -0.58056640625 +25295 -0.54754638671875 +25296 -0.508575439453125 +25297 -0.459503173828125 +25298 -0.394378662109375 +25299 -0.35260009765625 +25300 -0.31170654296875 +25301 -0.197418212890625 +25302 -0.007965087890625 +25303 0.207489013671875 +25304 0.409210205078125 +25305 0.57208251953125 +25306 0.66595458984375 +25307 0.65875244140625 +25308 0.56744384765625 +25309 0.431396484375 +25310 0.29443359375 +25311 0.182464599609375 +25312 0.06365966796875 +25313 -0.075958251953125 +25314 -0.189422607421875 +25315 -0.271942138671875 +25316 -0.342529296875 +25317 -0.364166259765625 +25318 -0.327239990234375 +25319 -0.2769775390625 +25320 -0.253692626953125 +25321 -0.24365234375 +25322 -0.1983642578125 +25323 -0.116241455078125 +25324 -0.036834716796875 +25325 0.034881591796875 +25326 0.09124755859375 +25327 0.10888671875 +25328 0.125518798828125 +25329 0.15771484375 +25330 0.17828369140625 +25331 0.17108154296875 +25332 0.129974365234375 +25333 0.082427978515625 +25334 0.027679443359375 +25335 -0.065643310546875 +25336 -0.15936279296875 +25337 -0.21307373046875 +25338 -0.234649658203125 +25339 -0.2001953125 +25340 -0.119171142578125 +25341 -0.024749755859375 +25342 0.085784912109375 +25343 0.178131103515625 +25344 0.215576171875 +25345 0.211456298828125 +25346 0.17523193359375 +25347 0.128753662109375 +25348 0.1019287109375 +25349 0.0743408203125 +25350 0.04327392578125 +25351 0.038177490234375 +25352 0.076263427734375 +25353 0.14105224609375 +25354 0.186431884765625 +25355 0.188812255859375 +25356 0.1390380859375 +25357 0.041778564453125 +25358 -0.079437255859375 +25359 -0.219390869140625 +25360 -0.367828369140625 +25361 -0.494873046875 +25362 -0.556243896484375 +25363 -0.508697509765625 +25364 -0.3756103515625 +25365 -0.218902587890625 +25366 -0.063751220703125 +25367 0.091552734375 +25368 0.23602294921875 +25369 0.342987060546875 +25370 0.39520263671875 +25371 0.389373779296875 +25372 0.324249267578125 +25373 0.224090576171875 +25374 0.124267578125 +25375 0.037078857421875 +25376 -0.010101318359375 +25377 -0.019439697265625 +25378 -0.022796630859375 +25379 -0.001556396484375 +25380 0.056304931640625 +25381 0.106719970703125 +25382 0.096893310546875 +25383 0.042694091796875 +25384 -0.018035888671875 +25385 -0.07586669921875 +25386 -0.11944580078125 +25387 -0.15972900390625 +25388 -0.202606201171875 +25389 -0.24859619140625 +25390 -0.30517578125 +25391 -0.36212158203125 +25392 -0.39141845703125 +25393 -0.35528564453125 +25394 -0.249969482421875 +25395 -0.092864990234375 +25396 0.08905029296875 +25397 0.2352294921875 +25398 0.318817138671875 +25399 0.358642578125 +25400 0.347747802734375 +25401 0.28564453125 +25402 0.223175048828125 +25403 0.196746826171875 +25404 0.179840087890625 +25405 0.155548095703125 +25406 0.151214599609375 +25407 0.156951904296875 +25408 0.13177490234375 +25409 0.100799560546875 +25410 0.087127685546875 +25411 0.05487060546875 +25412 -0.009002685546875 +25413 -0.10400390625 +25414 -0.229400634765625 +25415 -0.35552978515625 +25416 -0.441925048828125 +25417 -0.473846435546875 +25418 -0.464813232421875 +25419 -0.419097900390625 +25420 -0.334320068359375 +25421 -0.227935791015625 +25422 -0.12347412109375 +25423 -0.02764892578125 +25424 0.077667236328125 +25425 0.2132568359375 +25426 0.38885498046875 +25427 0.582794189453125 +25428 0.734039306640625 +25429 0.800140380859375 +25430 0.7783203125 +25431 0.6651611328125 +25432 0.45965576171875 +25433 0.199188232421875 +25434 -0.050689697265625 +25435 -0.23297119140625 +25436 -0.33013916015625 +25437 -0.368408203125 +25438 -0.378936767578125 +25439 -0.376983642578125 +25440 -0.37969970703125 +25441 -0.391510009765625 +25442 -0.385345458984375 +25443 -0.3419189453125 +25444 -0.28289794921875 +25445 -0.251617431640625 +25446 -0.266143798828125 +25447 -0.273345947265625 +25448 -0.216796875 +25449 -0.128265380859375 +25450 -0.068145751953125 +25451 -0.0430908203125 +25452 -0.024444580078125 +25453 0.020721435546875 +25454 0.124481201171875 +25455 0.25787353515625 +25456 0.379119873046875 +25457 0.47991943359375 +25458 0.5281982421875 +25459 0.511138916015625 +25460 0.456207275390625 +25461 0.407470703125 +25462 0.383758544921875 +25463 0.35687255859375 +25464 0.31182861328125 +25465 0.250885009765625 +25466 0.1654052734375 +25467 0.035247802734375 +25468 -0.142059326171875 +25469 -0.33563232421875 +25470 -0.5345458984375 +25471 -0.72186279296875 +25472 -0.836669921875 +25473 -0.8326416015625 +25474 -0.7296142578125 +25475 -0.582550048828125 +25476 -0.440093994140625 +25477 -0.324310302734375 +25478 -0.20147705078125 +25479 -0.044647216796875 +25480 0.103973388671875 +25481 0.202392578125 +25482 0.264495849609375 +25483 0.338897705078125 +25484 0.443817138671875 +25485 0.545074462890625 +25486 0.6173095703125 +25487 0.6524658203125 +25488 0.66339111328125 +25489 0.6561279296875 +25490 0.606781005859375 +25491 0.501190185546875 +25492 0.352783203125 +25493 0.176544189453125 +25494 -0.034820556640625 +25495 -0.258209228515625 +25496 -0.44244384765625 +25497 -0.5753173828125 +25498 -0.65203857421875 +25499 -0.641632080078125 +25500 -0.562164306640625 +25501 -0.458038330078125 +25502 -0.350555419921875 +25503 -0.260528564453125 +25504 -0.192108154296875 +25505 -0.141937255859375 +25506 -0.1021728515625 +25507 -0.062896728515625 +25508 -0.011932373046875 +25509 0.062835693359375 +25510 0.148712158203125 +25511 0.241729736328125 +25512 0.34912109375 +25513 0.457305908203125 +25514 0.54388427734375 +25515 0.5728759765625 +25516 0.506591796875 +25517 0.351226806640625 +25518 0.146514892578125 +25519 -0.05523681640625 +25520 -0.21624755859375 +25521 -0.334930419921875 +25522 -0.402984619140625 +25523 -0.4412841796875 +25524 -0.49578857421875 +25525 -0.5601806640625 +25526 -0.600738525390625 +25527 -0.584228515625 +25528 -0.47930908203125 +25529 -0.27935791015625 +25530 -0.0089111328125 +25531 0.268798828125 +25532 0.482818603515625 +25533 0.60369873046875 +25534 0.650421142578125 +25535 0.66400146484375 +25536 0.6414794921875 +25537 0.572540283203125 +25538 0.498138427734375 +25539 0.439453125 +25540 0.375518798828125 +25541 0.274505615234375 +25542 0.1087646484375 +25543 -0.099395751953125 +25544 -0.3182373046875 +25545 -0.5489501953125 +25546 -0.7738037109375 +25547 -0.86383056640625 +25548 -0.870391845703125 +25549 -0.86895751953125 +25550 -0.861053466796875 +25551 -0.765869140625 +25552 -0.5301513671875 +25553 -0.214691162109375 +25554 0.137359619140625 +25555 0.474822998046875 +25556 0.76239013671875 +25557 0.867462158203125 +25558 0.870361328125 +25559 0.86480712890625 +25560 0.831817626953125 +25561 0.677581787109375 +25562 0.495880126953125 +25563 0.30767822265625 +25564 0.116180419921875 +25565 -0.110748291015625 +25566 -0.381805419921875 +25567 -0.6572265625 +25568 -0.857421875 +25569 -0.870391845703125 +25570 -0.870391845703125 +25571 -0.86444091796875 +25572 -0.85723876953125 +25573 -0.790008544921875 +25574 -0.62847900390625 +25575 -0.3956298828125 +25576 -0.126708984375 +25577 0.150115966796875 +25578 0.424041748046875 +25579 0.670623779296875 +25580 0.854522705078125 +25581 0.866485595703125 +25582 0.86920166015625 +25583 0.8653564453125 +25584 0.857147216796875 +25585 0.766845703125 +25586 0.628509521484375 +25587 0.462127685546875 +25588 0.297210693359375 +25589 0.14862060546875 +25590 -0.00537109375 +25591 -0.15753173828125 +25592 -0.31304931640625 +25593 -0.48876953125 +25594 -0.6416015625 +25595 -0.751373291015625 +25596 -0.84619140625 +25597 -0.861297607421875 +25598 -0.863250732421875 +25599 -0.856597900390625 +25600 -0.7498779296875 +25601 -0.624542236328125 +25602 -0.47808837890625 +25603 -0.253387451171875 +25604 0.003692626953125 +25605 0.2257080078125 +25606 0.427154541015625 +25607 0.643218994140625 +25608 0.855926513671875 +25609 0.870361328125 +25610 0.870361328125 +25611 0.862762451171875 +25612 0.79669189453125 +25613 0.595794677734375 +25614 0.362152099609375 +25615 0.1270751953125 +25616 -0.086944580078125 +25617 -0.2784423828125 +25618 -0.484832763671875 +25619 -0.729583740234375 +25620 -0.86688232421875 +25621 -0.870391845703125 +25622 -0.86859130859375 +25623 -0.86279296875 +25624 -0.817962646484375 +25625 -0.6116943359375 +25626 -0.3128662109375 +25627 0.039398193359375 +25628 0.422821044921875 +25629 0.805145263671875 +25630 0.870361328125 +25631 0.870361328125 +25632 0.860015869140625 +25633 0.727935791015625 +25634 0.48114013671875 +25635 0.2059326171875 +25636 -0.06103515625 +25637 -0.29913330078125 +25638 -0.516204833984375 +25639 -0.7252197265625 +25640 -0.85980224609375 +25641 -0.870391845703125 +25642 -0.870391845703125 +25643 -0.858062744140625 +25644 -0.673004150390625 +25645 -0.42694091796875 +25646 -0.2100830078125 +25647 -0.0362548828125 +25648 0.10943603515625 +25649 0.23516845703125 +25650 0.373687744140625 +25651 0.517791748046875 +25652 0.602783203125 +25653 0.635711669921875 +25654 0.655181884765625 +25655 0.65948486328125 +25656 0.651275634765625 +25657 0.61846923828125 +25658 0.53753662109375 +25659 0.404144287109375 +25660 0.22186279296875 +25661 0.003997802734375 +25662 -0.22100830078125 +25663 -0.42449951171875 +25664 -0.579833984375 +25665 -0.641876220703125 +25666 -0.6177978515625 +25667 -0.575531005859375 +25668 -0.526336669921875 +25669 -0.42645263671875 +25670 -0.2581787109375 +25671 -0.068695068359375 +25672 0.09222412109375 +25673 0.232147216796875 +25674 0.3509521484375 +25675 0.410064697265625 +25676 0.372955322265625 +25677 0.2554931640625 +25678 0.10711669921875 +25679 -0.052886962890625 +25680 -0.186279296875 +25681 -0.23291015625 +25682 -0.209442138671875 +25683 -0.174163818359375 +25684 -0.126739501953125 +25685 -0.048126220703125 +25686 0.0426025390625 +25687 0.10748291015625 +25688 0.1409912109375 +25689 0.19708251953125 +25690 0.273651123046875 +25691 0.31768798828125 +25692 0.341094970703125 +25693 0.368011474609375 +25694 0.37249755859375 +25695 0.30072021484375 +25696 0.1517333984375 +25697 -0.01470947265625 +25698 -0.1883544921875 +25699 -0.372711181640625 +25700 -0.51397705078125 +25701 -0.57177734375 +25702 -0.53948974609375 +25703 -0.43511962890625 +25704 -0.2962646484375 +25705 -0.161102294921875 +25706 -0.0435791015625 +25707 0.060394287109375 +25708 0.13665771484375 +25709 0.170135498046875 +25710 0.16552734375 +25711 0.15728759765625 +25712 0.150787353515625 +25713 0.12200927734375 +25714 0.080108642578125 +25715 0.05126953125 +25716 0.062896728515625 +25717 0.09271240234375 +25718 0.092987060546875 +25719 0.07855224609375 +25720 0.06427001953125 +25721 0.0347900390625 +25722 -0.01171875 +25723 -0.056060791015625 +25724 -0.055511474609375 +25725 -0.010467529296875 +25726 0.02508544921875 +25727 0.025665283203125 +25728 0.017333984375 +25729 0.00189208984375 +25730 -0.03173828125 +25731 -0.071502685546875 +25732 -0.13543701171875 +25733 -0.219970703125 +25734 -0.300506591796875 +25735 -0.376312255859375 +25736 -0.416107177734375 +25737 -0.371124267578125 +25738 -0.242279052734375 +25739 -0.069732666015625 +25740 0.125640869140625 +25741 0.31268310546875 +25742 0.45501708984375 +25743 0.554779052734375 +25744 0.61065673828125 +25745 0.610931396484375 +25746 0.531463623046875 +25747 0.3883056640625 +25748 0.23468017578125 +25749 0.095245361328125 +25750 -0.00396728515625 +25751 -0.04852294921875 +25752 -0.055145263671875 +25753 -0.0758056640625 +25754 -0.138702392578125 +25755 -0.209197998046875 +25756 -0.289031982421875 +25757 -0.37884521484375 +25758 -0.456329345703125 +25759 -0.51641845703125 +25760 -0.519287109375 +25761 -0.458251953125 +25762 -0.384796142578125 +25763 -0.323699951171875 +25764 -0.269287109375 +25765 -0.1951904296875 +25766 -0.100006103515625 +25767 -0.01055908203125 +25768 0.1033935546875 +25769 0.24908447265625 +25770 0.373199462890625 +25771 0.45806884765625 +25772 0.511474609375 +25773 0.565399169921875 +25774 0.61138916015625 +25775 0.5897216796875 +25776 0.4906005859375 +25777 0.33148193359375 +25778 0.147796630859375 +25779 -0.01873779296875 +25780 -0.140289306640625 +25781 -0.191986083984375 +25782 -0.184295654296875 +25783 -0.161834716796875 +25784 -0.166595458984375 +25785 -0.19390869140625 +25786 -0.22442626953125 +25787 -0.279754638671875 +25788 -0.3389892578125 +25789 -0.3543701171875 +25790 -0.348175048828125 +25791 -0.32598876953125 +25792 -0.2581787109375 +25793 -0.139801025390625 +25794 0.014617919921875 +25795 0.144378662109375 +25796 0.221038818359375 +25797 0.27069091796875 +25798 0.294036865234375 +25799 0.311767578125 +25800 0.339141845703125 +25801 0.360260009765625 +25802 0.360504150390625 +25803 0.308380126953125 +25804 0.18170166015625 +25805 0.0047607421875 +25806 -0.17559814453125 +25807 -0.3143310546875 +25808 -0.36785888671875 +25809 -0.36248779296875 +25810 -0.343536376953125 +25811 -0.3018798828125 +25812 -0.231414794921875 +25813 -0.117645263671875 +25814 0.007049560546875 +25815 0.087982177734375 +25816 0.13946533203125 +25817 0.17425537109375 +25818 0.188201904296875 +25819 0.171234130859375 +25820 0.118438720703125 +25821 0.05706787109375 +25822 -0.010711669921875 +25823 -0.0914306640625 +25824 -0.162322998046875 +25825 -0.194549560546875 +25826 -0.1492919921875 +25827 -0.02166748046875 +25828 0.124053955078125 +25829 0.211151123046875 +25830 0.240447998046875 +25831 0.242218017578125 +25832 0.2257080078125 +25833 0.194366455078125 +25834 0.115509033203125 +25835 0.0128173828125 +25836 -0.053802490234375 +25837 -0.110626220703125 +25838 -0.199493408203125 +25839 -0.29437255859375 +25840 -0.33221435546875 +25841 -0.27972412109375 +25842 -0.185333251953125 +25843 -0.128204345703125 +25844 -0.115692138671875 +25845 -0.116455078125 +25846 -0.105926513671875 +25847 -0.053955078125 +25848 0.048797607421875 +25849 0.157318115234375 +25850 0.212005615234375 +25851 0.218475341796875 +25852 0.23724365234375 +25853 0.30535888671875 +25854 0.38128662109375 +25855 0.404449462890625 +25856 0.3944091796875 +25857 0.3885498046875 +25858 0.362640380859375 +25859 0.27362060546875 +25860 0.11712646484375 +25861 -0.054901123046875 +25862 -0.19085693359375 +25863 -0.28570556640625 +25864 -0.339263916015625 +25865 -0.3775634765625 +25866 -0.445709228515625 +25867 -0.535064697265625 +25868 -0.629058837890625 +25869 -0.697601318359375 +25870 -0.70391845703125 +25871 -0.6424560546875 +25872 -0.491241455078125 +25873 -0.265716552734375 +25874 -0.023712158203125 +25875 0.201751708984375 +25876 0.375823974609375 +25877 0.485076904296875 +25878 0.56884765625 +25879 0.634765625 +25880 0.63763427734375 +25881 0.5660400390625 +25882 0.4720458984375 +25883 0.40692138671875 +25884 0.3778076171875 +25885 0.376953125 +25886 0.371978759765625 +25887 0.313140869140625 +25888 0.184417724609375 +25889 0.011199951171875 +25890 -0.171051025390625 +25891 -0.33740234375 +25892 -0.47198486328125 +25893 -0.560394287109375 +25894 -0.58056640625 +25895 -0.54754638671875 +25896 -0.508575439453125 +25897 -0.459503173828125 +25898 -0.394378662109375 +25899 -0.35260009765625 +25900 -0.31170654296875 +25901 -0.197418212890625 +25902 -0.007965087890625 +25903 0.207489013671875 +25904 0.409210205078125 +25905 0.57208251953125 +25906 0.66595458984375 +25907 0.65875244140625 +25908 0.56744384765625 +25909 0.431396484375 +25910 0.29443359375 +25911 0.182464599609375 +25912 0.06365966796875 +25913 -0.075958251953125 +25914 -0.189422607421875 +25915 -0.271942138671875 +25916 -0.342529296875 +25917 -0.364166259765625 +25918 -0.327239990234375 +25919 -0.2769775390625 +25920 -0.253692626953125 +25921 -0.24365234375 +25922 -0.1983642578125 +25923 -0.116241455078125 +25924 -0.036834716796875 +25925 0.034881591796875 +25926 0.09124755859375 +25927 0.10888671875 +25928 0.125518798828125 +25929 0.15771484375 +25930 0.17828369140625 +25931 0.17108154296875 +25932 0.129974365234375 +25933 0.082427978515625 +25934 0.027679443359375 +25935 -0.065643310546875 +25936 -0.15936279296875 +25937 -0.21307373046875 +25938 -0.234649658203125 +25939 -0.2001953125 +25940 -0.119171142578125 +25941 -0.024749755859375 +25942 0.085784912109375 +25943 0.178131103515625 +25944 0.215576171875 +25945 0.211456298828125 +25946 0.17523193359375 +25947 0.128753662109375 +25948 0.1019287109375 +25949 0.0743408203125 +25950 0.04327392578125 +25951 0.038177490234375 +25952 0.076263427734375 +25953 0.14105224609375 +25954 0.186431884765625 +25955 0.188812255859375 +25956 0.1390380859375 +25957 0.041778564453125 +25958 -0.079437255859375 +25959 -0.219390869140625 +25960 -0.367828369140625 +25961 -0.494873046875 +25962 -0.556243896484375 +25963 -0.508697509765625 +25964 -0.3756103515625 +25965 -0.218902587890625 +25966 -0.063751220703125 +25967 0.091552734375 +25968 0.23602294921875 +25969 0.342987060546875 +25970 0.39520263671875 +25971 0.389373779296875 +25972 0.324249267578125 +25973 0.224090576171875 +25974 0.124267578125 +25975 0.037078857421875 +25976 -0.010101318359375 +25977 -0.019439697265625 +25978 -0.022796630859375 +25979 -0.001556396484375 +25980 0.056304931640625 +25981 0.106719970703125 +25982 0.096893310546875 +25983 0.042694091796875 +25984 -0.018035888671875 +25985 -0.07586669921875 +25986 -0.11944580078125 +25987 -0.15972900390625 +25988 -0.202606201171875 +25989 -0.24859619140625 +25990 -0.30517578125 +25991 -0.36212158203125 +25992 -0.39141845703125 +25993 -0.35528564453125 +25994 -0.249969482421875 +25995 -0.092864990234375 +25996 0.08905029296875 +25997 0.2352294921875 +25998 0.318817138671875 +25999 0.358642578125 +26000 0.347747802734375 +26001 0.28564453125 +26002 0.223175048828125 +26003 0.196746826171875 +26004 0.179840087890625 +26005 0.155548095703125 +26006 0.151214599609375 +26007 0.156951904296875 +26008 0.13177490234375 +26009 0.100799560546875 +26010 0.087127685546875 +26011 0.05487060546875 +26012 -0.009002685546875 +26013 -0.10400390625 +26014 -0.229400634765625 +26015 -0.35552978515625 +26016 -0.441925048828125 +26017 -0.473846435546875 +26018 -0.464813232421875 +26019 -0.419097900390625 +26020 -0.334320068359375 +26021 -0.227935791015625 +26022 -0.12347412109375 +26023 -0.02764892578125 +26024 0.077667236328125 +26025 0.2132568359375 +26026 0.38885498046875 +26027 0.582794189453125 +26028 0.734039306640625 +26029 0.800140380859375 +26030 0.7783203125 +26031 0.6651611328125 +26032 0.45965576171875 +26033 0.199188232421875 +26034 -0.050689697265625 +26035 -0.23297119140625 +26036 -0.33013916015625 +26037 -0.368408203125 +26038 -0.378936767578125 +26039 -0.376983642578125 +26040 -0.37969970703125 +26041 -0.391510009765625 +26042 -0.385345458984375 +26043 -0.3419189453125 +26044 -0.28289794921875 +26045 -0.251617431640625 +26046 -0.266143798828125 +26047 -0.273345947265625 +26048 -0.216796875 +26049 -0.128265380859375 +26050 -0.068145751953125 +26051 -0.0430908203125 +26052 -0.024444580078125 +26053 0.020721435546875 +26054 0.124481201171875 +26055 0.25787353515625 +26056 0.379119873046875 +26057 0.47991943359375 +26058 0.5281982421875 +26059 0.511138916015625 +26060 0.456207275390625 +26061 0.407470703125 +26062 0.383758544921875 +26063 0.35687255859375 +26064 0.31182861328125 +26065 0.250885009765625 +26066 0.1654052734375 +26067 0.035247802734375 +26068 -0.142059326171875 +26069 -0.33563232421875 +26070 -0.5345458984375 +26071 -0.72186279296875 +26072 -0.836669921875 +26073 -0.8326416015625 +26074 -0.7296142578125 +26075 -0.582550048828125 +26076 -0.440093994140625 +26077 -0.324310302734375 +26078 -0.20147705078125 +26079 -0.044647216796875 +26080 0.103973388671875 +26081 0.202392578125 +26082 0.264495849609375 +26083 0.338897705078125 +26084 0.443817138671875 +26085 0.545074462890625 +26086 0.6173095703125 +26087 0.6524658203125 +26088 0.66339111328125 +26089 0.6561279296875 +26090 0.606781005859375 +26091 0.501190185546875 +26092 0.352783203125 +26093 0.176544189453125 +26094 -0.034820556640625 +26095 -0.258209228515625 +26096 -0.44244384765625 +26097 -0.5753173828125 +26098 -0.65203857421875 +26099 -0.641632080078125 +26100 -0.562164306640625 +26101 -0.458038330078125 +26102 -0.350555419921875 +26103 -0.260528564453125 +26104 -0.192108154296875 +26105 -0.141937255859375 +26106 -0.1021728515625 +26107 -0.062896728515625 +26108 -0.011932373046875 +26109 0.062835693359375 +26110 0.148712158203125 +26111 0.241729736328125 +26112 0.34912109375 +26113 0.457305908203125 +26114 0.54388427734375 +26115 0.5728759765625 +26116 0.506591796875 +26117 0.351226806640625 +26118 0.146514892578125 +26119 -0.05523681640625 +26120 -0.21624755859375 +26121 -0.334930419921875 +26122 -0.402984619140625 +26123 -0.4412841796875 +26124 -0.49578857421875 +26125 -0.5601806640625 +26126 -0.600738525390625 +26127 -0.584228515625 +26128 -0.47930908203125 +26129 -0.27935791015625 +26130 -0.0089111328125 +26131 0.268798828125 +26132 0.482818603515625 +26133 0.60369873046875 +26134 0.650421142578125 +26135 0.66400146484375 +26136 0.6414794921875 +26137 0.572540283203125 +26138 0.498138427734375 +26139 0.439453125 +26140 0.375518798828125 +26141 0.274505615234375 +26142 0.1087646484375 +26143 -0.099395751953125 +26144 -0.3182373046875 +26145 -0.5489501953125 +26146 -0.7738037109375 +26147 -0.86383056640625 +26148 -0.870391845703125 +26149 -0.86895751953125 +26150 -0.861053466796875 +26151 -0.765869140625 +26152 -0.5301513671875 +26153 -0.214691162109375 +26154 0.137359619140625 +26155 0.474822998046875 +26156 0.76239013671875 +26157 0.867462158203125 +26158 0.870361328125 +26159 0.86480712890625 +26160 0.831817626953125 +26161 0.677581787109375 +26162 0.495880126953125 +26163 0.30767822265625 +26164 0.116180419921875 +26165 -0.110748291015625 +26166 -0.381805419921875 +26167 -0.6572265625 +26168 -0.857421875 +26169 -0.870391845703125 +26170 -0.870391845703125 +26171 -0.86444091796875 +26172 -0.85723876953125 +26173 -0.790008544921875 +26174 -0.62847900390625 +26175 -0.3956298828125 +26176 -0.126708984375 +26177 0.150115966796875 +26178 0.424041748046875 +26179 0.670623779296875 +26180 0.854522705078125 +26181 0.866485595703125 +26182 0.86920166015625 +26183 0.8653564453125 +26184 0.857147216796875 +26185 0.766845703125 +26186 0.628509521484375 +26187 0.462127685546875 +26188 0.297210693359375 +26189 0.14862060546875 +26190 -0.00537109375 +26191 -0.15753173828125 +26192 -0.31304931640625 +26193 -0.48876953125 +26194 -0.6416015625 +26195 -0.751373291015625 +26196 -0.84619140625 +26197 -0.861297607421875 +26198 -0.863250732421875 +26199 -0.856597900390625 +26200 -0.7498779296875 +26201 -0.624542236328125 +26202 -0.47808837890625 +26203 -0.253387451171875 +26204 0.003692626953125 +26205 0.2257080078125 +26206 0.427154541015625 +26207 0.643218994140625 +26208 0.855926513671875 +26209 0.870361328125 +26210 0.870361328125 +26211 0.862762451171875 +26212 0.79669189453125 +26213 0.595794677734375 +26214 0.362152099609375 +26215 0.1270751953125 +26216 -0.086944580078125 +26217 -0.2784423828125 +26218 -0.484832763671875 +26219 -0.729583740234375 +26220 -0.86688232421875 +26221 -0.870391845703125 +26222 -0.86859130859375 +26223 -0.86279296875 +26224 -0.817962646484375 +26225 -0.6116943359375 +26226 -0.3128662109375 +26227 0.039398193359375 +26228 0.422821044921875 +26229 0.805145263671875 +26230 0.870361328125 +26231 0.870361328125 +26232 0.860015869140625 +26233 0.727935791015625 +26234 0.48114013671875 +26235 0.2059326171875 +26236 -0.06103515625 +26237 -0.29913330078125 +26238 -0.516204833984375 +26239 -0.7252197265625 +26240 -0.85980224609375 +26241 -0.870391845703125 +26242 -0.870391845703125 +26243 -0.858062744140625 +26244 -0.673004150390625 +26245 -0.42694091796875 +26246 -0.2100830078125 +26247 -0.0362548828125 +26248 0.10943603515625 +26249 0.23516845703125 +26250 0.373687744140625 +26251 0.517791748046875 +26252 0.602783203125 +26253 0.635711669921875 +26254 0.655181884765625 +26255 0.65948486328125 +26256 0.651275634765625 +26257 0.61846923828125 +26258 0.53753662109375 +26259 0.404144287109375 +26260 0.22186279296875 +26261 0.003997802734375 +26262 -0.22100830078125 +26263 -0.42449951171875 +26264 -0.579833984375 +26265 -0.641876220703125 +26266 -0.6177978515625 +26267 -0.575531005859375 +26268 -0.526336669921875 +26269 -0.42645263671875 +26270 -0.2581787109375 +26271 -0.068695068359375 +26272 0.09222412109375 +26273 0.232147216796875 +26274 0.3509521484375 +26275 0.410064697265625 +26276 0.372955322265625 +26277 0.2554931640625 +26278 0.10711669921875 +26279 -0.052886962890625 +26280 -0.186279296875 +26281 -0.23291015625 +26282 -0.209442138671875 +26283 -0.174163818359375 +26284 -0.126739501953125 +26285 -0.048126220703125 +26286 0.0426025390625 +26287 0.10748291015625 +26288 0.1409912109375 +26289 0.19708251953125 +26290 0.273651123046875 +26291 0.31768798828125 +26292 0.341094970703125 +26293 0.368011474609375 +26294 0.37249755859375 +26295 0.30072021484375 +26296 0.1517333984375 +26297 -0.01470947265625 +26298 -0.1883544921875 +26299 -0.372711181640625 +26300 -0.51397705078125 +26301 -0.57177734375 +26302 -0.53948974609375 +26303 -0.43511962890625 +26304 -0.2962646484375 +26305 -0.161102294921875 +26306 -0.0435791015625 +26307 0.060394287109375 +26308 0.13665771484375 +26309 0.170135498046875 +26310 0.16552734375 +26311 0.15728759765625 +26312 0.150787353515625 +26313 0.12200927734375 +26314 0.080108642578125 +26315 0.05126953125 +26316 0.062896728515625 +26317 0.09271240234375 +26318 0.092987060546875 +26319 0.07855224609375 +26320 0.06427001953125 +26321 0.0347900390625 +26322 -0.01171875 +26323 -0.056060791015625 +26324 -0.055511474609375 +26325 -0.010467529296875 +26326 0.02508544921875 +26327 0.025665283203125 +26328 0.017333984375 +26329 0.00189208984375 +26330 -0.03173828125 +26331 -0.071502685546875 +26332 -0.13543701171875 +26333 -0.219970703125 +26334 -0.300506591796875 +26335 -0.376312255859375 +26336 -0.416107177734375 +26337 -0.371124267578125 +26338 -0.242279052734375 +26339 -0.069732666015625 +26340 0.125640869140625 +26341 0.31268310546875 +26342 0.45501708984375 +26343 0.554779052734375 +26344 0.61065673828125 +26345 0.610931396484375 +26346 0.531463623046875 +26347 0.3883056640625 +26348 0.23468017578125 +26349 0.095245361328125 +26350 -0.00396728515625 +26351 -0.04852294921875 +26352 -0.055145263671875 +26353 -0.0758056640625 +26354 -0.138702392578125 +26355 -0.209197998046875 +26356 -0.289031982421875 +26357 -0.37884521484375 +26358 -0.456329345703125 +26359 -0.51641845703125 +26360 -0.519287109375 +26361 -0.458251953125 +26362 -0.384796142578125 +26363 -0.323699951171875 +26364 -0.269287109375 +26365 -0.1951904296875 +26366 -0.100006103515625 +26367 -0.01055908203125 +26368 0.1033935546875 +26369 0.24908447265625 +26370 0.373199462890625 +26371 0.45806884765625 +26372 0.511474609375 +26373 0.565399169921875 +26374 0.61138916015625 +26375 0.5897216796875 +26376 0.4906005859375 +26377 0.33148193359375 +26378 0.147796630859375 +26379 -0.01873779296875 +26380 -0.140289306640625 +26381 -0.191986083984375 +26382 -0.184295654296875 +26383 -0.161834716796875 +26384 -0.166595458984375 +26385 -0.19390869140625 +26386 -0.22442626953125 +26387 -0.279754638671875 +26388 -0.3389892578125 +26389 -0.3543701171875 +26390 -0.348175048828125 +26391 -0.32598876953125 +26392 -0.2581787109375 +26393 -0.139801025390625 +26394 0.014617919921875 +26395 0.144378662109375 +26396 0.221038818359375 +26397 0.27069091796875 +26398 0.294036865234375 +26399 0.311767578125 +26400 0.339141845703125 +26401 0.360260009765625 +26402 0.360504150390625 +26403 0.308380126953125 +26404 0.18170166015625 +26405 0.0047607421875 +26406 -0.17559814453125 +26407 -0.3143310546875 +26408 -0.36785888671875 +26409 -0.36248779296875 +26410 -0.343536376953125 +26411 -0.3018798828125 +26412 -0.231414794921875 +26413 -0.117645263671875 +26414 0.007049560546875 +26415 0.087982177734375 +26416 0.13946533203125 +26417 0.17425537109375 +26418 0.188201904296875 +26419 0.171234130859375 +26420 0.118438720703125 +26421 0.05706787109375 +26422 -0.010711669921875 +26423 -0.0914306640625 +26424 -0.162322998046875 +26425 -0.194549560546875 +26426 -0.1492919921875 +26427 -0.02166748046875 +26428 0.124053955078125 +26429 0.211151123046875 +26430 0.240447998046875 +26431 0.242218017578125 +26432 0.2257080078125 +26433 0.194366455078125 +26434 0.115509033203125 +26435 0.0128173828125 +26436 -0.053802490234375 +26437 -0.110626220703125 +26438 -0.199493408203125 +26439 -0.29437255859375 +26440 -0.33221435546875 +26441 -0.27972412109375 +26442 -0.185333251953125 +26443 -0.128204345703125 +26444 -0.115692138671875 +26445 -0.116455078125 +26446 -0.105926513671875 +26447 -0.053955078125 +26448 0.048797607421875 +26449 0.157318115234375 +26450 0.212005615234375 +26451 0.218475341796875 +26452 0.23724365234375 +26453 0.30535888671875 +26454 0.38128662109375 +26455 0.404449462890625 +26456 0.3944091796875 +26457 0.3885498046875 +26458 0.362640380859375 +26459 0.27362060546875 +26460 0.11712646484375 +26461 -0.054901123046875 +26462 -0.19085693359375 +26463 -0.28570556640625 +26464 -0.339263916015625 +26465 -0.3775634765625 +26466 -0.445709228515625 +26467 -0.535064697265625 +26468 -0.629058837890625 +26469 -0.697601318359375 +26470 -0.70391845703125 +26471 -0.6424560546875 +26472 -0.491241455078125 +26473 -0.265716552734375 +26474 -0.023712158203125 +26475 0.201751708984375 +26476 0.375823974609375 +26477 0.485076904296875 +26478 0.56884765625 +26479 0.634765625 +26480 0.63763427734375 +26481 0.5660400390625 +26482 0.4720458984375 +26483 0.40692138671875 +26484 0.3778076171875 +26485 0.376953125 +26486 0.371978759765625 +26487 0.313140869140625 +26488 0.184417724609375 +26489 0.011199951171875 +26490 -0.171051025390625 +26491 -0.33740234375 +26492 -0.47198486328125 +26493 -0.560394287109375 +26494 -0.58056640625 +26495 -0.54754638671875 +26496 -0.508575439453125 +26497 -0.459503173828125 +26498 -0.394378662109375 +26499 -0.35260009765625 +26500 -0.31170654296875 +26501 -0.197418212890625 +26502 -0.007965087890625 +26503 0.207489013671875 +26504 0.409210205078125 +26505 0.57208251953125 +26506 0.66595458984375 +26507 0.65875244140625 +26508 0.56744384765625 +26509 0.431396484375 +26510 0.29443359375 +26511 0.182464599609375 +26512 0.06365966796875 +26513 -0.075958251953125 +26514 -0.189422607421875 +26515 -0.271942138671875 +26516 -0.342529296875 +26517 -0.364166259765625 +26518 -0.327239990234375 +26519 -0.2769775390625 +26520 -0.253692626953125 +26521 -0.24365234375 +26522 -0.1983642578125 +26523 -0.116241455078125 +26524 -0.036834716796875 +26525 0.034881591796875 +26526 0.09124755859375 +26527 0.10888671875 +26528 0.125518798828125 +26529 0.15771484375 +26530 0.17828369140625 +26531 0.17108154296875 +26532 0.129974365234375 +26533 0.082427978515625 +26534 0.027679443359375 +26535 -0.065643310546875 +26536 -0.15936279296875 +26537 -0.21307373046875 +26538 -0.234649658203125 +26539 -0.2001953125 +26540 -0.119171142578125 +26541 -0.024749755859375 +26542 0.085784912109375 +26543 0.178131103515625 +26544 0.215576171875 +26545 0.211456298828125 +26546 0.17523193359375 +26547 0.128753662109375 +26548 0.1019287109375 +26549 0.0743408203125 +26550 0.04327392578125 +26551 0.038177490234375 +26552 0.076263427734375 +26553 0.14105224609375 +26554 0.186431884765625 +26555 0.188812255859375 +26556 0.1390380859375 +26557 0.041778564453125 +26558 -0.079437255859375 +26559 -0.219390869140625 +26560 -0.367828369140625 +26561 -0.494873046875 +26562 -0.556243896484375 +26563 -0.508697509765625 +26564 -0.3756103515625 +26565 -0.218902587890625 +26566 -0.063751220703125 +26567 0.091552734375 +26568 0.23602294921875 +26569 0.342987060546875 +26570 0.39520263671875 +26571 0.389373779296875 +26572 0.324249267578125 +26573 0.224090576171875 +26574 0.124267578125 +26575 0.037078857421875 +26576 -0.010101318359375 +26577 -0.019439697265625 +26578 -0.022796630859375 +26579 -0.001556396484375 +26580 0.056304931640625 +26581 0.106719970703125 +26582 0.096893310546875 +26583 0.042694091796875 +26584 -0.018035888671875 +26585 -0.07586669921875 +26586 -0.11944580078125 +26587 -0.15972900390625 +26588 -0.202606201171875 +26589 -0.24859619140625 +26590 -0.30517578125 +26591 -0.36212158203125 +26592 -0.39141845703125 +26593 -0.35528564453125 +26594 -0.249969482421875 +26595 -0.092864990234375 +26596 0.08905029296875 +26597 0.2352294921875 +26598 0.318817138671875 +26599 0.358642578125 +26600 0.347747802734375 +26601 0.28564453125 +26602 0.223175048828125 +26603 0.196746826171875 +26604 0.179840087890625 +26605 0.155548095703125 +26606 0.151214599609375 +26607 0.156951904296875 +26608 0.13177490234375 +26609 0.100799560546875 +26610 0.087127685546875 +26611 0.05487060546875 +26612 -0.009002685546875 +26613 -0.10400390625 +26614 -0.229400634765625 +26615 -0.35552978515625 +26616 -0.441925048828125 +26617 -0.473846435546875 +26618 -0.464813232421875 +26619 -0.419097900390625 +26620 -0.334320068359375 +26621 -0.227935791015625 +26622 -0.12347412109375 +26623 -0.02764892578125 +26624 0.077667236328125 +26625 0.2132568359375 +26626 0.38885498046875 +26627 0.582794189453125 +26628 0.734039306640625 +26629 0.800140380859375 +26630 0.7783203125 +26631 0.6651611328125 +26632 0.45965576171875 +26633 0.199188232421875 +26634 -0.050689697265625 +26635 -0.23297119140625 +26636 -0.33013916015625 +26637 -0.368408203125 +26638 -0.378936767578125 +26639 -0.376983642578125 +26640 -0.37969970703125 +26641 -0.391510009765625 +26642 -0.385345458984375 +26643 -0.3419189453125 +26644 -0.28289794921875 +26645 -0.251617431640625 +26646 -0.266143798828125 +26647 -0.273345947265625 +26648 -0.216796875 +26649 -0.128265380859375 +26650 -0.068145751953125 +26651 -0.0430908203125 +26652 -0.024444580078125 +26653 0.020721435546875 +26654 0.124481201171875 +26655 0.25787353515625 +26656 0.379119873046875 +26657 0.47991943359375 +26658 0.5281982421875 +26659 0.511138916015625 +26660 0.456207275390625 +26661 0.407470703125 +26662 0.383758544921875 +26663 0.35687255859375 +26664 0.31182861328125 +26665 0.250885009765625 +26666 0.1654052734375 +26667 0.035247802734375 +26668 -0.142059326171875 +26669 -0.33563232421875 +26670 -0.5345458984375 +26671 -0.72186279296875 +26672 -0.836669921875 +26673 -0.8326416015625 +26674 -0.7296142578125 +26675 -0.582550048828125 +26676 -0.440093994140625 +26677 -0.324310302734375 +26678 -0.20147705078125 +26679 -0.044647216796875 +26680 0.103973388671875 +26681 0.202392578125 +26682 0.264495849609375 +26683 0.338897705078125 +26684 0.443817138671875 +26685 0.545074462890625 +26686 0.6173095703125 +26687 0.6524658203125 +26688 0.66339111328125 +26689 0.6561279296875 +26690 0.606781005859375 +26691 0.501190185546875 +26692 0.352783203125 +26693 0.176544189453125 +26694 -0.034820556640625 +26695 -0.258209228515625 +26696 -0.44244384765625 +26697 -0.5753173828125 +26698 -0.65203857421875 +26699 -0.641632080078125 +26700 -0.562164306640625 +26701 -0.458038330078125 +26702 -0.350555419921875 +26703 -0.260528564453125 +26704 -0.192108154296875 +26705 -0.141937255859375 +26706 -0.1021728515625 +26707 -0.062896728515625 +26708 -0.011932373046875 +26709 0.062835693359375 +26710 0.148712158203125 +26711 0.241729736328125 +26712 0.34912109375 +26713 0.457305908203125 +26714 0.54388427734375 +26715 0.5728759765625 +26716 0.506591796875 +26717 0.351226806640625 +26718 0.146514892578125 +26719 -0.05523681640625 +26720 -0.21624755859375 +26721 -0.334930419921875 +26722 -0.402984619140625 +26723 -0.4412841796875 +26724 -0.49578857421875 +26725 -0.5601806640625 +26726 -0.600738525390625 +26727 -0.584228515625 +26728 -0.47930908203125 +26729 -0.27935791015625 +26730 -0.0089111328125 +26731 0.268798828125 +26732 0.482818603515625 +26733 0.60369873046875 +26734 0.650421142578125 +26735 0.66400146484375 +26736 0.6414794921875 +26737 0.572540283203125 +26738 0.498138427734375 +26739 0.439453125 +26740 0.375518798828125 +26741 0.274505615234375 +26742 0.1087646484375 +26743 -0.099395751953125 +26744 -0.3182373046875 +26745 -0.5489501953125 +26746 -0.7738037109375 +26747 -0.86383056640625 +26748 -0.870391845703125 +26749 -0.86895751953125 +26750 -0.861053466796875 +26751 -0.765869140625 +26752 -0.5301513671875 +26753 -0.214691162109375 +26754 0.137359619140625 +26755 0.474822998046875 +26756 0.76239013671875 +26757 0.867462158203125 +26758 0.870361328125 +26759 0.86480712890625 +26760 0.831817626953125 +26761 0.677581787109375 +26762 0.495880126953125 +26763 0.30767822265625 +26764 0.116180419921875 +26765 -0.110748291015625 +26766 -0.381805419921875 +26767 -0.6572265625 +26768 -0.857421875 +26769 -0.870391845703125 +26770 -0.870391845703125 +26771 -0.86444091796875 +26772 -0.85723876953125 +26773 -0.790008544921875 +26774 -0.62847900390625 +26775 -0.3956298828125 +26776 -0.126708984375 +26777 0.150115966796875 +26778 0.424041748046875 +26779 0.670623779296875 +26780 0.854522705078125 +26781 0.866485595703125 +26782 0.86920166015625 +26783 0.8653564453125 +26784 0.857147216796875 +26785 0.766845703125 +26786 0.628509521484375 +26787 0.462127685546875 +26788 0.297210693359375 +26789 0.14862060546875 +26790 -0.00537109375 +26791 -0.15753173828125 +26792 -0.31304931640625 +26793 -0.48876953125 +26794 -0.6416015625 +26795 -0.751373291015625 +26796 -0.84619140625 +26797 -0.861297607421875 +26798 -0.863250732421875 +26799 -0.856597900390625 +26800 -0.7498779296875 +26801 -0.624542236328125 +26802 -0.47808837890625 +26803 -0.253387451171875 +26804 0.003692626953125 +26805 0.2257080078125 +26806 0.427154541015625 +26807 0.643218994140625 +26808 0.855926513671875 +26809 0.870361328125 +26810 0.870361328125 +26811 0.862762451171875 +26812 0.79669189453125 +26813 0.595794677734375 +26814 0.362152099609375 +26815 0.1270751953125 +26816 -0.086944580078125 +26817 -0.2784423828125 +26818 -0.484832763671875 +26819 -0.729583740234375 +26820 -0.86688232421875 +26821 -0.870391845703125 +26822 -0.86859130859375 +26823 -0.86279296875 +26824 -0.817962646484375 +26825 -0.6116943359375 +26826 -0.3128662109375 +26827 0.039398193359375 +26828 0.422821044921875 +26829 0.805145263671875 +26830 0.870361328125 +26831 0.870361328125 +26832 0.860015869140625 +26833 0.727935791015625 +26834 0.48114013671875 +26835 0.2059326171875 +26836 -0.06103515625 +26837 -0.29913330078125 +26838 -0.516204833984375 +26839 -0.7252197265625 +26840 -0.85980224609375 +26841 -0.870391845703125 +26842 -0.870391845703125 +26843 -0.858062744140625 +26844 -0.673004150390625 +26845 -0.42694091796875 +26846 -0.2100830078125 +26847 -0.0362548828125 +26848 0.10943603515625 +26849 0.23516845703125 +26850 0.373687744140625 +26851 0.517791748046875 +26852 0.602783203125 +26853 0.635711669921875 +26854 0.655181884765625 +26855 0.65948486328125 +26856 0.651275634765625 +26857 0.61846923828125 +26858 0.53753662109375 +26859 0.404144287109375 +26860 0.22186279296875 +26861 0.003997802734375 +26862 -0.22100830078125 +26863 -0.42449951171875 +26864 -0.579833984375 +26865 -0.641876220703125 +26866 -0.6177978515625 +26867 -0.575531005859375 +26868 -0.526336669921875 +26869 -0.42645263671875 +26870 -0.2581787109375 +26871 -0.068695068359375 +26872 0.09222412109375 +26873 0.232147216796875 +26874 0.3509521484375 +26875 0.410064697265625 +26876 0.372955322265625 +26877 0.2554931640625 +26878 0.10711669921875 +26879 -0.052886962890625 +26880 -0.186279296875 +26881 -0.23291015625 +26882 -0.209442138671875 +26883 -0.174163818359375 +26884 -0.126739501953125 +26885 -0.048126220703125 +26886 0.0426025390625 +26887 0.10748291015625 +26888 0.1409912109375 +26889 0.19708251953125 +26890 0.273651123046875 +26891 0.31768798828125 +26892 0.341094970703125 +26893 0.368011474609375 +26894 0.37249755859375 +26895 0.30072021484375 +26896 0.1517333984375 +26897 -0.01470947265625 +26898 -0.1883544921875 +26899 -0.372711181640625 +26900 -0.51397705078125 +26901 -0.57177734375 +26902 -0.53948974609375 +26903 -0.43511962890625 +26904 -0.2962646484375 +26905 -0.161102294921875 +26906 -0.0435791015625 +26907 0.060394287109375 +26908 0.13665771484375 +26909 0.170135498046875 +26910 0.16552734375 +26911 0.15728759765625 +26912 0.150787353515625 +26913 0.12200927734375 +26914 0.080108642578125 +26915 0.05126953125 +26916 0.062896728515625 +26917 0.09271240234375 +26918 0.092987060546875 +26919 0.07855224609375 +26920 0.06427001953125 +26921 0.0347900390625 +26922 -0.01171875 +26923 -0.056060791015625 +26924 -0.055511474609375 +26925 -0.010467529296875 +26926 0.02508544921875 +26927 0.025665283203125 +26928 0.017333984375 +26929 0.00189208984375 +26930 -0.03173828125 +26931 -0.071502685546875 +26932 -0.13543701171875 +26933 -0.219970703125 +26934 -0.300506591796875 +26935 -0.376312255859375 +26936 -0.416107177734375 +26937 -0.371124267578125 +26938 -0.242279052734375 +26939 -0.069732666015625 +26940 0.125640869140625 +26941 0.31268310546875 +26942 0.45501708984375 +26943 0.554779052734375 +26944 0.61065673828125 +26945 0.610931396484375 +26946 0.531463623046875 +26947 0.3883056640625 +26948 0.23468017578125 +26949 0.095245361328125 +26950 -0.00396728515625 +26951 -0.04852294921875 +26952 -0.055145263671875 +26953 -0.0758056640625 +26954 -0.138702392578125 +26955 -0.209197998046875 +26956 -0.289031982421875 +26957 -0.37884521484375 +26958 -0.456329345703125 +26959 -0.51641845703125 +26960 -0.519287109375 +26961 -0.458251953125 +26962 -0.384796142578125 +26963 -0.323699951171875 +26964 -0.269287109375 +26965 -0.1951904296875 +26966 -0.100006103515625 +26967 -0.01055908203125 +26968 0.1033935546875 +26969 0.24908447265625 +26970 0.373199462890625 +26971 0.45806884765625 +26972 0.511474609375 +26973 0.565399169921875 +26974 0.61138916015625 +26975 0.5897216796875 +26976 0.4906005859375 +26977 0.33148193359375 +26978 0.147796630859375 +26979 -0.01873779296875 +26980 -0.140289306640625 +26981 -0.191986083984375 +26982 -0.184295654296875 +26983 -0.161834716796875 +26984 -0.166595458984375 +26985 -0.19390869140625 +26986 -0.22442626953125 +26987 -0.279754638671875 +26988 -0.3389892578125 +26989 -0.3543701171875 +26990 -0.348175048828125 +26991 -0.32598876953125 +26992 -0.2581787109375 +26993 -0.139801025390625 +26994 0.014617919921875 +26995 0.144378662109375 +26996 0.221038818359375 +26997 0.27069091796875 +26998 0.294036865234375 +26999 0.311767578125 +27000 0.339141845703125 +27001 0.360260009765625 +27002 0.360504150390625 +27003 0.308380126953125 +27004 0.18170166015625 +27005 0.0047607421875 +27006 -0.17559814453125 +27007 -0.3143310546875 +27008 -0.36785888671875 +27009 -0.36248779296875 +27010 -0.343536376953125 +27011 -0.3018798828125 +27012 -0.231414794921875 +27013 -0.117645263671875 +27014 0.007049560546875 +27015 0.087982177734375 +27016 0.13946533203125 +27017 0.17425537109375 +27018 0.188201904296875 +27019 0.171234130859375 +27020 0.118438720703125 +27021 0.05706787109375 +27022 -0.010711669921875 +27023 -0.0914306640625 +27024 -0.162322998046875 +27025 -0.194549560546875 +27026 -0.1492919921875 +27027 -0.02166748046875 +27028 0.124053955078125 +27029 0.211151123046875 +27030 0.240447998046875 +27031 0.242218017578125 +27032 0.2257080078125 +27033 0.194366455078125 +27034 0.115509033203125 +27035 0.0128173828125 +27036 -0.053802490234375 +27037 -0.110626220703125 +27038 -0.199493408203125 +27039 -0.29437255859375 +27040 -0.33221435546875 +27041 -0.27972412109375 +27042 -0.185333251953125 +27043 -0.128204345703125 +27044 -0.115692138671875 +27045 -0.116455078125 +27046 -0.105926513671875 +27047 -0.053955078125 +27048 0.048797607421875 +27049 0.157318115234375 +27050 0.212005615234375 +27051 0.218475341796875 +27052 0.23724365234375 +27053 0.30535888671875 +27054 0.38128662109375 +27055 0.404449462890625 +27056 0.3944091796875 +27057 0.3885498046875 +27058 0.362640380859375 +27059 0.27362060546875 +27060 0.11712646484375 +27061 -0.054901123046875 +27062 -0.19085693359375 +27063 -0.28570556640625 +27064 -0.339263916015625 +27065 -0.3775634765625 +27066 -0.445709228515625 +27067 -0.535064697265625 +27068 -0.629058837890625 +27069 -0.697601318359375 +27070 -0.70391845703125 +27071 -0.6424560546875 +27072 -0.491241455078125 +27073 -0.265716552734375 +27074 -0.023712158203125 +27075 0.201751708984375 +27076 0.375823974609375 +27077 0.485076904296875 +27078 0.56884765625 +27079 0.634765625 +27080 0.63763427734375 +27081 0.5660400390625 +27082 0.4720458984375 +27083 0.40692138671875 +27084 0.3778076171875 +27085 0.376953125 +27086 0.371978759765625 +27087 0.313140869140625 +27088 0.184417724609375 +27089 0.011199951171875 +27090 -0.171051025390625 +27091 -0.33740234375 +27092 -0.47198486328125 +27093 -0.560394287109375 +27094 -0.58056640625 +27095 -0.54754638671875 +27096 -0.508575439453125 +27097 -0.459503173828125 +27098 -0.394378662109375 +27099 -0.35260009765625 +27100 -0.31170654296875 +27101 -0.197418212890625 +27102 -0.007965087890625 +27103 0.207489013671875 +27104 0.409210205078125 +27105 0.57208251953125 +27106 0.66595458984375 +27107 0.65875244140625 +27108 0.56744384765625 +27109 0.431396484375 +27110 0.29443359375 +27111 0.182464599609375 +27112 0.06365966796875 +27113 -0.075958251953125 +27114 -0.189422607421875 +27115 -0.271942138671875 +27116 -0.342529296875 +27117 -0.364166259765625 +27118 -0.327239990234375 +27119 -0.2769775390625 +27120 -0.253692626953125 +27121 -0.24365234375 +27122 -0.1983642578125 +27123 -0.116241455078125 +27124 -0.036834716796875 +27125 0.034881591796875 +27126 0.09124755859375 +27127 0.10888671875 +27128 0.125518798828125 +27129 0.15771484375 +27130 0.17828369140625 +27131 0.17108154296875 +27132 0.129974365234375 +27133 0.082427978515625 +27134 0.027679443359375 +27135 -0.065643310546875 +27136 -0.15936279296875 +27137 -0.21307373046875 +27138 -0.234649658203125 +27139 -0.2001953125 +27140 -0.119171142578125 +27141 -0.024749755859375 +27142 0.085784912109375 +27143 0.178131103515625 +27144 0.215576171875 +27145 0.211456298828125 +27146 0.17523193359375 +27147 0.128753662109375 +27148 0.1019287109375 +27149 0.0743408203125 +27150 0.04327392578125 +27151 0.038177490234375 +27152 0.076263427734375 +27153 0.14105224609375 +27154 0.186431884765625 +27155 0.188812255859375 +27156 0.1390380859375 +27157 0.041778564453125 +27158 -0.079437255859375 +27159 -0.219390869140625 +27160 -0.367828369140625 +27161 -0.494873046875 +27162 -0.556243896484375 +27163 -0.508697509765625 +27164 -0.3756103515625 +27165 -0.218902587890625 +27166 -0.063751220703125 +27167 0.091552734375 +27168 0.23602294921875 +27169 0.342987060546875 +27170 0.39520263671875 +27171 0.389373779296875 +27172 0.324249267578125 +27173 0.224090576171875 +27174 0.124267578125 +27175 0.037078857421875 +27176 -0.010101318359375 +27177 -0.019439697265625 +27178 -0.022796630859375 +27179 -0.001556396484375 +27180 0.056304931640625 +27181 0.106719970703125 +27182 0.096893310546875 +27183 0.042694091796875 +27184 -0.018035888671875 +27185 -0.07586669921875 +27186 -0.11944580078125 +27187 -0.15972900390625 +27188 -0.202606201171875 +27189 -0.24859619140625 +27190 -0.30517578125 +27191 -0.36212158203125 +27192 -0.39141845703125 +27193 -0.35528564453125 +27194 -0.249969482421875 +27195 -0.092864990234375 +27196 0.08905029296875 +27197 0.2352294921875 +27198 0.318817138671875 +27199 0.358642578125 +27200 0.347747802734375 +27201 0.28564453125 +27202 0.223175048828125 +27203 0.196746826171875 +27204 0.179840087890625 +27205 0.155548095703125 +27206 0.151214599609375 +27207 0.156951904296875 +27208 0.13177490234375 +27209 0.100799560546875 +27210 0.087127685546875 +27211 0.05487060546875 +27212 -0.009002685546875 +27213 -0.10400390625 +27214 -0.229400634765625 +27215 -0.35552978515625 +27216 -0.441925048828125 +27217 -0.473846435546875 +27218 -0.464813232421875 +27219 -0.419097900390625 +27220 -0.334320068359375 +27221 -0.227935791015625 +27222 -0.12347412109375 +27223 -0.02764892578125 +27224 0.077667236328125 +27225 0.2132568359375 +27226 0.38885498046875 +27227 0.582794189453125 +27228 0.734039306640625 +27229 0.800140380859375 +27230 0.7783203125 +27231 0.6651611328125 +27232 0.45965576171875 +27233 0.199188232421875 +27234 -0.050689697265625 +27235 -0.23297119140625 +27236 -0.33013916015625 +27237 -0.368408203125 +27238 -0.378936767578125 +27239 -0.376983642578125 +27240 -0.37969970703125 +27241 -0.391510009765625 +27242 -0.385345458984375 +27243 -0.3419189453125 +27244 -0.28289794921875 +27245 -0.251617431640625 +27246 -0.266143798828125 +27247 -0.273345947265625 +27248 -0.216796875 +27249 -0.128265380859375 +27250 -0.068145751953125 +27251 -0.0430908203125 +27252 -0.024444580078125 +27253 0.020721435546875 +27254 0.124481201171875 +27255 0.25787353515625 +27256 0.379119873046875 +27257 0.47991943359375 +27258 0.5281982421875 +27259 0.511138916015625 +27260 0.456207275390625 +27261 0.407470703125 +27262 0.383758544921875 +27263 0.35687255859375 +27264 0.31182861328125 +27265 0.250885009765625 +27266 0.1654052734375 +27267 0.035247802734375 +27268 -0.142059326171875 +27269 -0.33563232421875 +27270 -0.5345458984375 +27271 -0.72186279296875 +27272 -0.836669921875 +27273 -0.8326416015625 +27274 -0.7296142578125 +27275 -0.582550048828125 +27276 -0.440093994140625 +27277 -0.324310302734375 +27278 -0.20147705078125 +27279 -0.044647216796875 +27280 0.103973388671875 +27281 0.202392578125 +27282 0.264495849609375 +27283 0.338897705078125 +27284 0.443817138671875 +27285 0.545074462890625 +27286 0.6173095703125 +27287 0.6524658203125 +27288 0.66339111328125 +27289 0.6561279296875 +27290 0.606781005859375 +27291 0.501190185546875 +27292 0.352783203125 +27293 0.176544189453125 +27294 -0.034820556640625 +27295 -0.258209228515625 +27296 -0.44244384765625 +27297 -0.5753173828125 +27298 -0.65203857421875 +27299 -0.641632080078125 +27300 -0.562164306640625 +27301 -0.458038330078125 +27302 -0.350555419921875 +27303 -0.260528564453125 +27304 -0.192108154296875 +27305 -0.141937255859375 +27306 -0.1021728515625 +27307 -0.062896728515625 +27308 -0.011932373046875 +27309 0.062835693359375 +27310 0.148712158203125 +27311 0.241729736328125 +27312 0.34912109375 +27313 0.457305908203125 +27314 0.54388427734375 +27315 0.5728759765625 +27316 0.506591796875 +27317 0.351226806640625 +27318 0.146514892578125 +27319 -0.05523681640625 +27320 -0.21624755859375 +27321 -0.334930419921875 +27322 -0.402984619140625 +27323 -0.4412841796875 +27324 -0.49578857421875 +27325 -0.5601806640625 +27326 -0.600738525390625 +27327 -0.584228515625 +27328 -0.47930908203125 +27329 -0.27935791015625 +27330 -0.0089111328125 +27331 0.268798828125 +27332 0.482818603515625 +27333 0.60369873046875 +27334 0.650421142578125 +27335 0.66400146484375 +27336 0.6414794921875 +27337 0.572540283203125 +27338 0.498138427734375 +27339 0.439453125 +27340 0.375518798828125 +27341 0.274505615234375 +27342 0.1087646484375 +27343 -0.099395751953125 +27344 -0.3182373046875 +27345 -0.5489501953125 +27346 -0.7738037109375 +27347 -0.86383056640625 +27348 -0.870391845703125 +27349 -0.86895751953125 +27350 -0.861053466796875 +27351 -0.765869140625 +27352 -0.5301513671875 +27353 -0.214691162109375 +27354 0.137359619140625 +27355 0.474822998046875 +27356 0.76239013671875 +27357 0.867462158203125 +27358 0.870361328125 +27359 0.86480712890625 +27360 0.831817626953125 +27361 0.677581787109375 +27362 0.495880126953125 +27363 0.30767822265625 +27364 0.116180419921875 +27365 -0.110748291015625 +27366 -0.381805419921875 +27367 -0.6572265625 +27368 -0.857421875 +27369 -0.870391845703125 +27370 -0.870391845703125 +27371 -0.86444091796875 +27372 -0.85723876953125 +27373 -0.790008544921875 +27374 -0.62847900390625 +27375 -0.3956298828125 +27376 -0.126708984375 +27377 0.150115966796875 +27378 0.424041748046875 +27379 0.670623779296875 +27380 0.854522705078125 +27381 0.866485595703125 +27382 0.86920166015625 +27383 0.8653564453125 +27384 0.857147216796875 +27385 0.766845703125 +27386 0.628509521484375 +27387 0.462127685546875 +27388 0.297210693359375 +27389 0.14862060546875 +27390 -0.00537109375 +27391 -0.15753173828125 +27392 -0.31304931640625 +27393 -0.48876953125 +27394 -0.6416015625 +27395 -0.751373291015625 +27396 -0.84619140625 +27397 -0.861297607421875 +27398 -0.863250732421875 +27399 -0.856597900390625 +27400 -0.7498779296875 +27401 -0.624542236328125 +27402 -0.47808837890625 +27403 -0.253387451171875 +27404 0.003692626953125 +27405 0.2257080078125 +27406 0.427154541015625 +27407 0.643218994140625 +27408 0.855926513671875 +27409 0.870361328125 +27410 0.870361328125 +27411 0.862762451171875 +27412 0.79669189453125 +27413 0.595794677734375 +27414 0.362152099609375 +27415 0.1270751953125 +27416 -0.086944580078125 +27417 -0.2784423828125 +27418 -0.484832763671875 +27419 -0.729583740234375 +27420 -0.86688232421875 +27421 -0.870391845703125 +27422 -0.86859130859375 +27423 -0.86279296875 +27424 -0.817962646484375 +27425 -0.6116943359375 +27426 -0.3128662109375 +27427 0.039398193359375 +27428 0.422821044921875 +27429 0.805145263671875 +27430 0.870361328125 +27431 0.870361328125 +27432 0.860015869140625 +27433 0.727935791015625 +27434 0.48114013671875 +27435 0.2059326171875 +27436 -0.06103515625 +27437 -0.29913330078125 +27438 -0.516204833984375 +27439 -0.7252197265625 +27440 -0.85980224609375 +27441 -0.870391845703125 +27442 -0.870391845703125 +27443 -0.858062744140625 +27444 -0.673004150390625 +27445 -0.42694091796875 +27446 -0.2100830078125 +27447 -0.0362548828125 +27448 0.10943603515625 +27449 0.23516845703125 +27450 0.373687744140625 +27451 0.517791748046875 +27452 0.602783203125 +27453 0.635711669921875 +27454 0.655181884765625 +27455 0.65948486328125 +27456 0.651275634765625 +27457 0.61846923828125 +27458 0.53753662109375 +27459 0.404144287109375 +27460 0.22186279296875 +27461 0.003997802734375 +27462 -0.22100830078125 +27463 -0.42449951171875 +27464 -0.579833984375 +27465 -0.641876220703125 +27466 -0.6177978515625 +27467 -0.575531005859375 +27468 -0.526336669921875 +27469 -0.42645263671875 +27470 -0.2581787109375 +27471 -0.068695068359375 +27472 0.09222412109375 +27473 0.232147216796875 +27474 0.3509521484375 +27475 0.410064697265625 +27476 0.372955322265625 +27477 0.2554931640625 +27478 0.10711669921875 +27479 -0.052886962890625 +27480 -0.186279296875 +27481 -0.23291015625 +27482 -0.209442138671875 +27483 -0.174163818359375 +27484 -0.126739501953125 +27485 -0.048126220703125 +27486 0.0426025390625 +27487 0.10748291015625 +27488 0.1409912109375 +27489 0.19708251953125 +27490 0.273651123046875 +27491 0.31768798828125 +27492 0.341094970703125 +27493 0.368011474609375 +27494 0.37249755859375 +27495 0.30072021484375 +27496 0.1517333984375 +27497 -0.01470947265625 +27498 -0.1883544921875 +27499 -0.372711181640625 +27500 -0.51397705078125 +27501 -0.57177734375 +27502 -0.53948974609375 +27503 -0.43511962890625 +27504 -0.2962646484375 +27505 -0.161102294921875 +27506 -0.0435791015625 +27507 0.060394287109375 +27508 0.13665771484375 +27509 0.170135498046875 +27510 0.16552734375 +27511 0.15728759765625 +27512 0.150787353515625 +27513 0.12200927734375 +27514 0.080108642578125 +27515 0.05126953125 +27516 0.062896728515625 +27517 0.09271240234375 +27518 0.092987060546875 +27519 0.07855224609375 +27520 0.06427001953125 +27521 0.0347900390625 +27522 -0.01171875 +27523 -0.056060791015625 +27524 -0.055511474609375 +27525 -0.010467529296875 +27526 0.02508544921875 +27527 0.025665283203125 +27528 0.017333984375 +27529 0.00189208984375 +27530 -0.03173828125 +27531 -0.071502685546875 +27532 -0.13543701171875 +27533 -0.219970703125 +27534 -0.300506591796875 +27535 -0.376312255859375 +27536 -0.416107177734375 +27537 -0.371124267578125 +27538 -0.242279052734375 +27539 -0.069732666015625 +27540 0.125640869140625 +27541 0.31268310546875 +27542 0.45501708984375 +27543 0.554779052734375 +27544 0.61065673828125 +27545 0.610931396484375 +27546 0.531463623046875 +27547 0.3883056640625 +27548 0.23468017578125 +27549 0.095245361328125 +27550 -0.00396728515625 +27551 -0.04852294921875 +27552 -0.055145263671875 +27553 -0.0758056640625 +27554 -0.138702392578125 +27555 -0.209197998046875 +27556 -0.289031982421875 +27557 -0.37884521484375 +27558 -0.456329345703125 +27559 -0.51641845703125 +27560 -0.519287109375 +27561 -0.458251953125 +27562 -0.384796142578125 +27563 -0.323699951171875 +27564 -0.269287109375 +27565 -0.1951904296875 +27566 -0.100006103515625 +27567 -0.01055908203125 +27568 0.1033935546875 +27569 0.24908447265625 +27570 0.373199462890625 +27571 0.45806884765625 +27572 0.511474609375 +27573 0.565399169921875 +27574 0.61138916015625 +27575 0.5897216796875 +27576 0.4906005859375 +27577 0.33148193359375 +27578 0.147796630859375 +27579 -0.01873779296875 +27580 -0.140289306640625 +27581 -0.191986083984375 +27582 -0.184295654296875 +27583 -0.161834716796875 +27584 -0.166595458984375 +27585 -0.19390869140625 +27586 -0.22442626953125 +27587 -0.279754638671875 +27588 -0.3389892578125 +27589 -0.3543701171875 +27590 -0.348175048828125 +27591 -0.32598876953125 +27592 -0.2581787109375 +27593 -0.139801025390625 +27594 0.014617919921875 +27595 0.144378662109375 +27596 0.221038818359375 +27597 0.27069091796875 +27598 0.294036865234375 +27599 0.311767578125 +27600 0.339141845703125 +27601 0.360260009765625 +27602 0.360504150390625 +27603 0.308380126953125 +27604 0.18170166015625 +27605 0.0047607421875 +27606 -0.17559814453125 +27607 -0.3143310546875 +27608 -0.36785888671875 +27609 -0.36248779296875 +27610 -0.343536376953125 +27611 -0.3018798828125 +27612 -0.231414794921875 +27613 -0.117645263671875 +27614 0.007049560546875 +27615 0.087982177734375 +27616 0.13946533203125 +27617 0.17425537109375 +27618 0.188201904296875 +27619 0.171234130859375 +27620 0.118438720703125 +27621 0.05706787109375 +27622 -0.010711669921875 +27623 -0.0914306640625 +27624 -0.162322998046875 +27625 -0.194549560546875 +27626 -0.1492919921875 +27627 -0.02166748046875 +27628 0.124053955078125 +27629 0.211151123046875 +27630 0.240447998046875 +27631 0.242218017578125 +27632 0.2257080078125 +27633 0.194366455078125 +27634 0.115509033203125 +27635 0.0128173828125 +27636 -0.053802490234375 +27637 -0.110626220703125 +27638 -0.199493408203125 +27639 -0.29437255859375 +27640 -0.33221435546875 +27641 -0.27972412109375 +27642 -0.185333251953125 +27643 -0.128204345703125 +27644 -0.115692138671875 +27645 -0.116455078125 +27646 -0.105926513671875 +27647 -0.053955078125 +27648 0.048797607421875 +27649 0.157318115234375 +27650 0.212005615234375 +27651 0.218475341796875 +27652 0.23724365234375 +27653 0.30535888671875 +27654 0.38128662109375 +27655 0.404449462890625 +27656 0.3944091796875 +27657 0.3885498046875 +27658 0.362640380859375 +27659 0.27362060546875 +27660 0.11712646484375 +27661 -0.054901123046875 +27662 -0.19085693359375 +27663 -0.28570556640625 +27664 -0.339263916015625 +27665 -0.3775634765625 +27666 -0.445709228515625 +27667 -0.535064697265625 +27668 -0.629058837890625 +27669 -0.697601318359375 +27670 -0.70391845703125 +27671 -0.6424560546875 +27672 -0.491241455078125 +27673 -0.265716552734375 +27674 -0.023712158203125 +27675 0.201751708984375 +27676 0.375823974609375 +27677 0.485076904296875 +27678 0.56884765625 +27679 0.634765625 +27680 0.63763427734375 +27681 0.5660400390625 +27682 0.4720458984375 +27683 0.40692138671875 +27684 0.3778076171875 +27685 0.376953125 +27686 0.371978759765625 +27687 0.313140869140625 +27688 0.184417724609375 +27689 0.011199951171875 +27690 -0.171051025390625 +27691 -0.33740234375 +27692 -0.47198486328125 +27693 -0.560394287109375 +27694 -0.58056640625 +27695 -0.54754638671875 +27696 -0.508575439453125 +27697 -0.459503173828125 +27698 -0.394378662109375 +27699 -0.35260009765625 +27700 -0.31170654296875 +27701 -0.197418212890625 +27702 -0.007965087890625 +27703 0.207489013671875 +27704 0.409210205078125 +27705 0.57208251953125 +27706 0.66595458984375 +27707 0.65875244140625 +27708 0.56744384765625 +27709 0.431396484375 +27710 0.29443359375 +27711 0.182464599609375 +27712 0.06365966796875 +27713 -0.075958251953125 +27714 -0.189422607421875 +27715 -0.271942138671875 +27716 -0.342529296875 +27717 -0.364166259765625 +27718 -0.327239990234375 +27719 -0.2769775390625 +27720 -0.253692626953125 +27721 -0.24365234375 +27722 -0.1983642578125 +27723 -0.116241455078125 +27724 -0.036834716796875 +27725 0.034881591796875 +27726 0.09124755859375 +27727 0.10888671875 +27728 0.125518798828125 +27729 0.15771484375 +27730 0.17828369140625 +27731 0.17108154296875 +27732 0.129974365234375 +27733 0.082427978515625 +27734 0.027679443359375 +27735 -0.065643310546875 +27736 -0.15936279296875 +27737 -0.21307373046875 +27738 -0.234649658203125 +27739 -0.2001953125 +27740 -0.119171142578125 +27741 -0.024749755859375 +27742 0.085784912109375 +27743 0.178131103515625 +27744 0.215576171875 +27745 0.211456298828125 +27746 0.17523193359375 +27747 0.128753662109375 +27748 0.1019287109375 +27749 0.0743408203125 +27750 0.04327392578125 +27751 0.038177490234375 +27752 0.076263427734375 +27753 0.14105224609375 +27754 0.186431884765625 +27755 0.188812255859375 +27756 0.1390380859375 +27757 0.041778564453125 +27758 -0.079437255859375 +27759 -0.219390869140625 +27760 -0.367828369140625 +27761 -0.494873046875 +27762 -0.556243896484375 +27763 -0.508697509765625 +27764 -0.3756103515625 +27765 -0.218902587890625 +27766 -0.063751220703125 +27767 0.091552734375 +27768 0.23602294921875 +27769 0.342987060546875 +27770 0.39520263671875 +27771 0.389373779296875 +27772 0.324249267578125 +27773 0.224090576171875 +27774 0.124267578125 +27775 0.037078857421875 +27776 -0.010101318359375 +27777 -0.019439697265625 +27778 -0.022796630859375 +27779 -0.001556396484375 +27780 0.056304931640625 +27781 0.106719970703125 +27782 0.096893310546875 +27783 0.042694091796875 +27784 -0.018035888671875 +27785 -0.07586669921875 +27786 -0.11944580078125 +27787 -0.15972900390625 +27788 -0.202606201171875 +27789 -0.24859619140625 +27790 -0.30517578125 +27791 -0.36212158203125 +27792 -0.39141845703125 +27793 -0.35528564453125 +27794 -0.249969482421875 +27795 -0.092864990234375 +27796 0.08905029296875 +27797 0.2352294921875 +27798 0.318817138671875 +27799 0.358642578125 +27800 0.347747802734375 +27801 0.28564453125 +27802 0.223175048828125 +27803 0.196746826171875 +27804 0.179840087890625 +27805 0.155548095703125 +27806 0.151214599609375 +27807 0.156951904296875 +27808 0.13177490234375 +27809 0.100799560546875 +27810 0.087127685546875 +27811 0.05487060546875 +27812 -0.009002685546875 +27813 -0.10400390625 +27814 -0.229400634765625 +27815 -0.35552978515625 +27816 -0.441925048828125 +27817 -0.473846435546875 +27818 -0.464813232421875 +27819 -0.419097900390625 +27820 -0.334320068359375 +27821 -0.227935791015625 +27822 -0.12347412109375 +27823 -0.02764892578125 +27824 0.077667236328125 +27825 0.2132568359375 +27826 0.38885498046875 +27827 0.582794189453125 +27828 0.734039306640625 +27829 0.800140380859375 +27830 0.7783203125 +27831 0.6651611328125 +27832 0.45965576171875 +27833 0.199188232421875 +27834 -0.050689697265625 +27835 -0.23297119140625 +27836 -0.33013916015625 +27837 -0.368408203125 +27838 -0.378936767578125 +27839 -0.376983642578125 +27840 -0.37969970703125 +27841 -0.391510009765625 +27842 -0.385345458984375 +27843 -0.3419189453125 +27844 -0.28289794921875 +27845 -0.251617431640625 +27846 -0.266143798828125 +27847 -0.273345947265625 +27848 -0.216796875 +27849 -0.128265380859375 +27850 -0.068145751953125 +27851 -0.0430908203125 +27852 -0.024444580078125 +27853 0.020721435546875 +27854 0.124481201171875 +27855 0.25787353515625 +27856 0.379119873046875 +27857 0.47991943359375 +27858 0.5281982421875 +27859 0.511138916015625 +27860 0.456207275390625 +27861 0.407470703125 +27862 0.383758544921875 +27863 0.35687255859375 +27864 0.31182861328125 +27865 0.250885009765625 +27866 0.1654052734375 +27867 0.035247802734375 +27868 -0.142059326171875 +27869 -0.33563232421875 +27870 -0.5345458984375 +27871 -0.72186279296875 +27872 -0.836669921875 +27873 -0.8326416015625 +27874 -0.7296142578125 +27875 -0.582550048828125 +27876 -0.440093994140625 +27877 -0.324310302734375 +27878 -0.20147705078125 +27879 -0.044647216796875 +27880 0.103973388671875 +27881 0.202392578125 +27882 0.264495849609375 +27883 0.338897705078125 +27884 0.443817138671875 +27885 0.545074462890625 +27886 0.6173095703125 +27887 0.6524658203125 +27888 0.66339111328125 +27889 0.6561279296875 +27890 0.606781005859375 +27891 0.501190185546875 +27892 0.352783203125 +27893 0.176544189453125 +27894 -0.034820556640625 +27895 -0.258209228515625 +27896 -0.44244384765625 +27897 -0.5753173828125 +27898 -0.65203857421875 +27899 -0.641632080078125 +27900 -0.562164306640625 +27901 -0.458038330078125 +27902 -0.350555419921875 +27903 -0.260528564453125 +27904 -0.192108154296875 +27905 -0.141937255859375 +27906 -0.1021728515625 +27907 -0.062896728515625 +27908 -0.011932373046875 +27909 0.062835693359375 +27910 0.148712158203125 +27911 0.241729736328125 +27912 0.34912109375 +27913 0.457305908203125 +27914 0.54388427734375 +27915 0.5728759765625 +27916 0.506591796875 +27917 0.351226806640625 +27918 0.146514892578125 +27919 -0.05523681640625 +27920 -0.21624755859375 +27921 -0.334930419921875 +27922 -0.402984619140625 +27923 -0.4412841796875 +27924 -0.49578857421875 +27925 -0.5601806640625 +27926 -0.600738525390625 +27927 -0.584228515625 +27928 -0.47930908203125 +27929 -0.27935791015625 +27930 -0.0089111328125 +27931 0.268798828125 +27932 0.482818603515625 +27933 0.60369873046875 +27934 0.650421142578125 +27935 0.66400146484375 +27936 0.6414794921875 +27937 0.572540283203125 +27938 0.498138427734375 +27939 0.439453125 +27940 0.375518798828125 +27941 0.274505615234375 +27942 0.1087646484375 +27943 -0.099395751953125 +27944 -0.3182373046875 +27945 -0.5489501953125 +27946 -0.7738037109375 +27947 -0.86383056640625 +27948 -0.870391845703125 +27949 -0.86895751953125 +27950 -0.861053466796875 +27951 -0.765869140625 +27952 -0.5301513671875 +27953 -0.214691162109375 +27954 0.137359619140625 +27955 0.474822998046875 +27956 0.76239013671875 +27957 0.867462158203125 +27958 0.870361328125 +27959 0.86480712890625 +27960 0.831817626953125 +27961 0.677581787109375 +27962 0.495880126953125 +27963 0.30767822265625 +27964 0.116180419921875 +27965 -0.110748291015625 +27966 -0.381805419921875 +27967 -0.6572265625 +27968 -0.857421875 +27969 -0.870391845703125 +27970 -0.870391845703125 +27971 -0.86444091796875 +27972 -0.85723876953125 +27973 -0.790008544921875 +27974 -0.62847900390625 +27975 -0.3956298828125 +27976 -0.126708984375 +27977 0.150115966796875 +27978 0.424041748046875 +27979 0.670623779296875 +27980 0.854522705078125 +27981 0.866485595703125 +27982 0.86920166015625 +27983 0.8653564453125 +27984 0.857147216796875 +27985 0.766845703125 +27986 0.628509521484375 +27987 0.462127685546875 +27988 0.297210693359375 +27989 0.14862060546875 +27990 -0.00537109375 +27991 -0.15753173828125 +27992 -0.31304931640625 +27993 -0.48876953125 +27994 -0.6416015625 +27995 -0.751373291015625 +27996 -0.84619140625 +27997 -0.861297607421875 +27998 -0.863250732421875 +27999 -0.856597900390625 +28000 -0.7498779296875 +28001 -0.624542236328125 +28002 -0.47808837890625 +28003 -0.253387451171875 +28004 0.003692626953125 +28005 0.2257080078125 +28006 0.427154541015625 +28007 0.643218994140625 +28008 0.855926513671875 +28009 0.870361328125 +28010 0.870361328125 +28011 0.862762451171875 +28012 0.79669189453125 +28013 0.595794677734375 +28014 0.362152099609375 +28015 0.1270751953125 +28016 -0.086944580078125 +28017 -0.2784423828125 +28018 -0.484832763671875 +28019 -0.729583740234375 +28020 -0.86688232421875 +28021 -0.870391845703125 +28022 -0.86859130859375 +28023 -0.86279296875 +28024 -0.817962646484375 +28025 -0.6116943359375 +28026 -0.3128662109375 +28027 0.039398193359375 +28028 0.422821044921875 +28029 0.805145263671875 +28030 0.870361328125 +28031 0.870361328125 +28032 0.860015869140625 +28033 0.727935791015625 +28034 0.48114013671875 +28035 0.2059326171875 +28036 -0.06103515625 +28037 -0.29913330078125 +28038 -0.516204833984375 +28039 -0.7252197265625 +28040 -0.85980224609375 +28041 -0.870391845703125 +28042 -0.870391845703125 +28043 -0.858062744140625 +28044 -0.673004150390625 +28045 -0.42694091796875 +28046 -0.2100830078125 +28047 -0.0362548828125 +28048 0.10943603515625 +28049 0.23516845703125 +28050 0.373687744140625 +28051 0.517791748046875 +28052 0.602783203125 +28053 0.635711669921875 +28054 0.655181884765625 +28055 0.65948486328125 +28056 0.651275634765625 +28057 0.61846923828125 +28058 0.53753662109375 +28059 0.404144287109375 +28060 0.22186279296875 +28061 0.003997802734375 +28062 -0.22100830078125 +28063 -0.42449951171875 +28064 -0.579833984375 +28065 -0.641876220703125 +28066 -0.6177978515625 +28067 -0.575531005859375 +28068 -0.526336669921875 +28069 -0.42645263671875 +28070 -0.2581787109375 +28071 -0.068695068359375 +28072 0.09222412109375 +28073 0.232147216796875 +28074 0.3509521484375 +28075 0.410064697265625 +28076 0.372955322265625 +28077 0.2554931640625 +28078 0.10711669921875 +28079 -0.052886962890625 +28080 -0.186279296875 +28081 -0.23291015625 +28082 -0.209442138671875 +28083 -0.174163818359375 +28084 -0.126739501953125 +28085 -0.048126220703125 +28086 0.0426025390625 +28087 0.10748291015625 +28088 0.1409912109375 +28089 0.19708251953125 +28090 0.273651123046875 +28091 0.31768798828125 +28092 0.341094970703125 +28093 0.368011474609375 +28094 0.37249755859375 +28095 0.30072021484375 +28096 0.1517333984375 +28097 -0.01470947265625 +28098 -0.1883544921875 +28099 -0.372711181640625 +28100 -0.51397705078125 +28101 -0.57177734375 +28102 -0.53948974609375 +28103 -0.43511962890625 +28104 -0.2962646484375 +28105 -0.161102294921875 +28106 -0.0435791015625 +28107 0.060394287109375 +28108 0.13665771484375 +28109 0.170135498046875 +28110 0.16552734375 +28111 0.15728759765625 +28112 0.150787353515625 +28113 0.12200927734375 +28114 0.080108642578125 +28115 0.05126953125 +28116 0.062896728515625 +28117 0.09271240234375 +28118 0.092987060546875 +28119 0.07855224609375 +28120 0.06427001953125 +28121 0.0347900390625 +28122 -0.01171875 +28123 -0.056060791015625 +28124 -0.055511474609375 +28125 -0.010467529296875 +28126 0.02508544921875 +28127 0.025665283203125 +28128 0.017333984375 +28129 0.00189208984375 +28130 -0.03173828125 +28131 -0.071502685546875 +28132 -0.13543701171875 +28133 -0.219970703125 +28134 -0.300506591796875 +28135 -0.376312255859375 +28136 -0.416107177734375 +28137 -0.371124267578125 +28138 -0.242279052734375 +28139 -0.069732666015625 +28140 0.125640869140625 +28141 0.31268310546875 +28142 0.45501708984375 +28143 0.554779052734375 +28144 0.61065673828125 +28145 0.610931396484375 +28146 0.531463623046875 +28147 0.3883056640625 +28148 0.23468017578125 +28149 0.095245361328125 +28150 -0.00396728515625 +28151 -0.04852294921875 +28152 -0.055145263671875 +28153 -0.0758056640625 +28154 -0.138702392578125 +28155 -0.209197998046875 +28156 -0.289031982421875 +28157 -0.37884521484375 +28158 -0.456329345703125 +28159 -0.51641845703125 +28160 -0.519287109375 +28161 -0.458251953125 +28162 -0.384796142578125 +28163 -0.323699951171875 +28164 -0.269287109375 +28165 -0.1951904296875 +28166 -0.100006103515625 +28167 -0.01055908203125 +28168 0.1033935546875 +28169 0.24908447265625 +28170 0.373199462890625 +28171 0.45806884765625 +28172 0.511474609375 +28173 0.565399169921875 +28174 0.61138916015625 +28175 0.5897216796875 +28176 0.4906005859375 +28177 0.33148193359375 +28178 0.147796630859375 +28179 -0.01873779296875 +28180 -0.140289306640625 +28181 -0.191986083984375 +28182 -0.184295654296875 +28183 -0.161834716796875 +28184 -0.166595458984375 +28185 -0.19390869140625 +28186 -0.22442626953125 +28187 -0.279754638671875 +28188 -0.3389892578125 +28189 -0.3543701171875 +28190 -0.348175048828125 +28191 -0.32598876953125 +28192 -0.2581787109375 +28193 -0.139801025390625 +28194 0.014617919921875 +28195 0.144378662109375 +28196 0.221038818359375 +28197 0.27069091796875 +28198 0.294036865234375 +28199 0.311767578125 +28200 0.339141845703125 +28201 0.360260009765625 +28202 0.360504150390625 +28203 0.308380126953125 +28204 0.18170166015625 +28205 0.0047607421875 +28206 -0.17559814453125 +28207 -0.3143310546875 +28208 -0.36785888671875 +28209 -0.36248779296875 +28210 -0.343536376953125 +28211 -0.3018798828125 +28212 -0.231414794921875 +28213 -0.117645263671875 +28214 0.007049560546875 +28215 0.087982177734375 +28216 0.13946533203125 +28217 0.17425537109375 +28218 0.188201904296875 +28219 0.171234130859375 +28220 0.118438720703125 +28221 0.05706787109375 +28222 -0.010711669921875 +28223 -0.0914306640625 +28224 -0.162322998046875 +28225 -0.194549560546875 +28226 -0.1492919921875 +28227 -0.02166748046875 +28228 0.124053955078125 +28229 0.211151123046875 +28230 0.240447998046875 +28231 0.242218017578125 +28232 0.2257080078125 +28233 0.194366455078125 +28234 0.115509033203125 +28235 0.0128173828125 +28236 -0.053802490234375 +28237 -0.110626220703125 +28238 -0.199493408203125 +28239 -0.29437255859375 +28240 -0.33221435546875 +28241 -0.27972412109375 +28242 -0.185333251953125 +28243 -0.128204345703125 +28244 -0.115692138671875 +28245 -0.116455078125 +28246 -0.105926513671875 +28247 -0.053955078125 +28248 0.048797607421875 +28249 0.157318115234375 +28250 0.212005615234375 +28251 0.218475341796875 +28252 0.23724365234375 +28253 0.30535888671875 +28254 0.38128662109375 +28255 0.404449462890625 +28256 0.3944091796875 +28257 0.3885498046875 +28258 0.362640380859375 +28259 0.27362060546875 +28260 0.11712646484375 +28261 -0.054901123046875 +28262 -0.19085693359375 +28263 -0.28570556640625 +28264 -0.339263916015625 +28265 -0.3775634765625 +28266 -0.445709228515625 +28267 -0.535064697265625 +28268 -0.629058837890625 +28269 -0.697601318359375 +28270 -0.70391845703125 +28271 -0.6424560546875 +28272 -0.491241455078125 +28273 -0.265716552734375 +28274 -0.023712158203125 +28275 0.201751708984375 +28276 0.375823974609375 +28277 0.485076904296875 +28278 0.56884765625 +28279 0.634765625 +28280 0.63763427734375 +28281 0.5660400390625 +28282 0.4720458984375 +28283 0.40692138671875 +28284 0.3778076171875 +28285 0.376953125 +28286 0.371978759765625 +28287 0.313140869140625 +28288 0.184417724609375 +28289 0.011199951171875 +28290 -0.171051025390625 +28291 -0.33740234375 +28292 -0.47198486328125 +28293 -0.560394287109375 +28294 -0.58056640625 +28295 -0.54754638671875 +28296 -0.508575439453125 +28297 -0.459503173828125 +28298 -0.394378662109375 +28299 -0.35260009765625 +28300 -0.31170654296875 +28301 -0.197418212890625 +28302 -0.007965087890625 +28303 0.207489013671875 +28304 0.409210205078125 +28305 0.57208251953125 +28306 0.66595458984375 +28307 0.65875244140625 +28308 0.56744384765625 +28309 0.431396484375 +28310 0.29443359375 +28311 0.182464599609375 +28312 0.06365966796875 +28313 -0.075958251953125 +28314 -0.189422607421875 +28315 -0.271942138671875 +28316 -0.342529296875 +28317 -0.364166259765625 +28318 -0.327239990234375 +28319 -0.2769775390625 +28320 -0.253692626953125 +28321 -0.24365234375 +28322 -0.1983642578125 +28323 -0.116241455078125 +28324 -0.036834716796875 +28325 0.034881591796875 +28326 0.09124755859375 +28327 0.10888671875 +28328 0.125518798828125 +28329 0.15771484375 +28330 0.17828369140625 +28331 0.17108154296875 +28332 0.129974365234375 +28333 0.082427978515625 +28334 0.027679443359375 +28335 -0.065643310546875 +28336 -0.15936279296875 +28337 -0.21307373046875 +28338 -0.234649658203125 +28339 -0.2001953125 +28340 -0.119171142578125 +28341 -0.024749755859375 +28342 0.085784912109375 +28343 0.178131103515625 +28344 0.215576171875 +28345 0.211456298828125 +28346 0.17523193359375 +28347 0.128753662109375 +28348 0.1019287109375 +28349 0.0743408203125 +28350 0.04327392578125 +28351 0.038177490234375 +28352 0.076263427734375 +28353 0.14105224609375 +28354 0.186431884765625 +28355 0.188812255859375 +28356 0.1390380859375 +28357 0.041778564453125 +28358 -0.079437255859375 +28359 -0.219390869140625 +28360 -0.367828369140625 +28361 -0.494873046875 +28362 -0.556243896484375 +28363 -0.508697509765625 +28364 -0.3756103515625 +28365 -0.218902587890625 +28366 -0.063751220703125 +28367 0.091552734375 +28368 0.23602294921875 +28369 0.342987060546875 +28370 0.39520263671875 +28371 0.389373779296875 +28372 0.324249267578125 +28373 0.224090576171875 +28374 0.124267578125 +28375 0.037078857421875 +28376 -0.010101318359375 +28377 -0.019439697265625 +28378 -0.022796630859375 +28379 -0.001556396484375 +28380 0.056304931640625 +28381 0.106719970703125 +28382 0.096893310546875 +28383 0.042694091796875 +28384 -0.018035888671875 +28385 -0.07586669921875 +28386 -0.11944580078125 +28387 -0.15972900390625 +28388 -0.202606201171875 +28389 -0.24859619140625 +28390 -0.30517578125 +28391 -0.36212158203125 +28392 -0.39141845703125 +28393 -0.35528564453125 +28394 -0.249969482421875 +28395 -0.092864990234375 +28396 0.08905029296875 +28397 0.2352294921875 +28398 0.318817138671875 +28399 0.358642578125 +28400 0.347747802734375 +28401 0.28564453125 +28402 0.223175048828125 +28403 0.196746826171875 +28404 0.179840087890625 +28405 0.155548095703125 +28406 0.151214599609375 +28407 0.156951904296875 +28408 0.13177490234375 +28409 0.100799560546875 +28410 0.087127685546875 +28411 0.05487060546875 +28412 -0.009002685546875 +28413 -0.10400390625 +28414 -0.229400634765625 +28415 -0.35552978515625 +28416 -0.441925048828125 +28417 -0.473846435546875 +28418 -0.464813232421875 +28419 -0.419097900390625 +28420 -0.334320068359375 +28421 -0.227935791015625 +28422 -0.12347412109375 +28423 -0.02764892578125 +28424 0.077667236328125 +28425 0.2132568359375 +28426 0.38885498046875 +28427 0.582794189453125 +28428 0.734039306640625 +28429 0.800140380859375 +28430 0.7783203125 +28431 0.6651611328125 +28432 0.45965576171875 +28433 0.199188232421875 +28434 -0.050689697265625 +28435 -0.23297119140625 +28436 -0.33013916015625 +28437 -0.368408203125 +28438 -0.378936767578125 +28439 -0.376983642578125 +28440 -0.37969970703125 +28441 -0.391510009765625 +28442 -0.385345458984375 +28443 -0.3419189453125 +28444 -0.28289794921875 +28445 -0.251617431640625 +28446 -0.266143798828125 +28447 -0.273345947265625 +28448 -0.216796875 +28449 -0.128265380859375 +28450 -0.068145751953125 +28451 -0.0430908203125 +28452 -0.024444580078125 +28453 0.020721435546875 +28454 0.124481201171875 +28455 0.25787353515625 +28456 0.379119873046875 +28457 0.47991943359375 +28458 0.5281982421875 +28459 0.511138916015625 +28460 0.456207275390625 +28461 0.407470703125 +28462 0.383758544921875 +28463 0.35687255859375 +28464 0.31182861328125 +28465 0.250885009765625 +28466 0.1654052734375 +28467 0.035247802734375 +28468 -0.142059326171875 +28469 -0.33563232421875 +28470 -0.5345458984375 +28471 -0.72186279296875 +28472 -0.836669921875 +28473 -0.8326416015625 +28474 -0.7296142578125 +28475 -0.582550048828125 +28476 -0.440093994140625 +28477 -0.324310302734375 +28478 -0.20147705078125 +28479 -0.044647216796875 +28480 0.103973388671875 +28481 0.202392578125 +28482 0.264495849609375 +28483 0.338897705078125 +28484 0.443817138671875 +28485 0.545074462890625 +28486 0.6173095703125 +28487 0.6524658203125 +28488 0.66339111328125 +28489 0.6561279296875 +28490 0.606781005859375 +28491 0.501190185546875 +28492 0.352783203125 +28493 0.176544189453125 +28494 -0.034820556640625 +28495 -0.258209228515625 +28496 -0.44244384765625 +28497 -0.5753173828125 +28498 -0.65203857421875 +28499 -0.641632080078125 +28500 -0.562164306640625 +28501 -0.458038330078125 +28502 -0.350555419921875 +28503 -0.260528564453125 +28504 -0.192108154296875 +28505 -0.141937255859375 +28506 -0.1021728515625 +28507 -0.062896728515625 +28508 -0.011932373046875 +28509 0.062835693359375 +28510 0.148712158203125 +28511 0.241729736328125 +28512 0.34912109375 +28513 0.457305908203125 +28514 0.54388427734375 +28515 0.5728759765625 +28516 0.506591796875 +28517 0.351226806640625 +28518 0.146514892578125 +28519 -0.05523681640625 +28520 -0.21624755859375 +28521 -0.334930419921875 +28522 -0.402984619140625 +28523 -0.4412841796875 +28524 -0.49578857421875 +28525 -0.5601806640625 +28526 -0.600738525390625 +28527 -0.584228515625 +28528 -0.47930908203125 +28529 -0.27935791015625 +28530 -0.0089111328125 +28531 0.268798828125 +28532 0.482818603515625 +28533 0.60369873046875 +28534 0.650421142578125 +28535 0.66400146484375 +28536 0.6414794921875 +28537 0.572540283203125 +28538 0.498138427734375 +28539 0.439453125 +28540 0.375518798828125 +28541 0.274505615234375 +28542 0.1087646484375 +28543 -0.099395751953125 +28544 -0.3182373046875 +28545 -0.5489501953125 +28546 -0.7738037109375 +28547 -0.86383056640625 +28548 -0.870391845703125 +28549 -0.86895751953125 +28550 -0.861053466796875 +28551 -0.765869140625 +28552 -0.5301513671875 +28553 -0.214691162109375 +28554 0.137359619140625 +28555 0.474822998046875 +28556 0.76239013671875 +28557 0.867462158203125 +28558 0.870361328125 +28559 0.86480712890625 +28560 0.831817626953125 +28561 0.677581787109375 +28562 0.495880126953125 +28563 0.30767822265625 +28564 0.116180419921875 +28565 -0.110748291015625 +28566 -0.381805419921875 +28567 -0.6572265625 +28568 -0.857421875 +28569 -0.870391845703125 +28570 -0.870391845703125 +28571 -0.86444091796875 +28572 -0.85723876953125 +28573 -0.790008544921875 +28574 -0.62847900390625 +28575 -0.3956298828125 +28576 -0.126708984375 +28577 0.150115966796875 +28578 0.424041748046875 +28579 0.670623779296875 +28580 0.854522705078125 +28581 0.866485595703125 +28582 0.86920166015625 +28583 0.8653564453125 +28584 0.857147216796875 +28585 0.766845703125 +28586 0.628509521484375 +28587 0.462127685546875 +28588 0.297210693359375 +28589 0.14862060546875 +28590 -0.00537109375 +28591 -0.15753173828125 +28592 -0.31304931640625 +28593 -0.48876953125 +28594 -0.6416015625 +28595 -0.751373291015625 +28596 -0.84619140625 +28597 -0.861297607421875 +28598 -0.863250732421875 +28599 -0.856597900390625 +28600 -0.7498779296875 +28601 -0.624542236328125 +28602 -0.47808837890625 +28603 -0.253387451171875 +28604 0.003692626953125 +28605 0.2257080078125 +28606 0.427154541015625 +28607 0.643218994140625 +28608 0.855926513671875 +28609 0.870361328125 +28610 0.870361328125 +28611 0.862762451171875 +28612 0.79669189453125 +28613 0.595794677734375 +28614 0.362152099609375 +28615 0.1270751953125 +28616 -0.086944580078125 +28617 -0.2784423828125 +28618 -0.484832763671875 +28619 -0.729583740234375 +28620 -0.86688232421875 +28621 -0.870391845703125 +28622 -0.86859130859375 +28623 -0.86279296875 +28624 -0.817962646484375 +28625 -0.6116943359375 +28626 -0.3128662109375 +28627 0.039398193359375 +28628 0.422821044921875 +28629 0.805145263671875 +28630 0.870361328125 +28631 0.870361328125 +28632 0.860015869140625 +28633 0.727935791015625 +28634 0.48114013671875 +28635 0.2059326171875 +28636 -0.06103515625 +28637 -0.29913330078125 +28638 -0.516204833984375 +28639 -0.7252197265625 +28640 -0.85980224609375 +28641 -0.870391845703125 +28642 -0.870391845703125 +28643 -0.858062744140625 +28644 -0.673004150390625 +28645 -0.42694091796875 +28646 -0.2100830078125 +28647 -0.0362548828125 +28648 0.10943603515625 +28649 0.23516845703125 +28650 0.373687744140625 +28651 0.517791748046875 +28652 0.602783203125 +28653 0.635711669921875 +28654 0.655181884765625 +28655 0.65948486328125 +28656 0.651275634765625 +28657 0.61846923828125 +28658 0.53753662109375 +28659 0.404144287109375 +28660 0.22186279296875 +28661 0.003997802734375 +28662 -0.22100830078125 +28663 -0.42449951171875 +28664 -0.579833984375 +28665 -0.641876220703125 +28666 -0.6177978515625 +28667 -0.575531005859375 +28668 -0.526336669921875 +28669 -0.42645263671875 +28670 -0.2581787109375 +28671 -0.068695068359375 +28672 0.09222412109375 +28673 0.232147216796875 +28674 0.3509521484375 +28675 0.410064697265625 +28676 0.372955322265625 +28677 0.2554931640625 +28678 0.10711669921875 +28679 -0.052886962890625 +28680 -0.186279296875 +28681 -0.23291015625 +28682 -0.209442138671875 +28683 -0.174163818359375 +28684 -0.126739501953125 +28685 -0.048126220703125 +28686 0.0426025390625 +28687 0.10748291015625 +28688 0.1409912109375 +28689 0.19708251953125 +28690 0.273651123046875 +28691 0.31768798828125 +28692 0.341094970703125 +28693 0.368011474609375 +28694 0.37249755859375 +28695 0.30072021484375 +28696 0.1517333984375 +28697 -0.01470947265625 +28698 -0.1883544921875 +28699 -0.372711181640625 +28700 -0.51397705078125 +28701 -0.57177734375 +28702 -0.53948974609375 +28703 -0.43511962890625 +28704 -0.2962646484375 +28705 -0.161102294921875 +28706 -0.0435791015625 +28707 0.060394287109375 +28708 0.13665771484375 +28709 0.170135498046875 +28710 0.16552734375 +28711 0.15728759765625 +28712 0.150787353515625 +28713 0.12200927734375 +28714 0.080108642578125 +28715 0.05126953125 +28716 0.062896728515625 +28717 0.09271240234375 +28718 0.092987060546875 +28719 0.07855224609375 +28720 0.06427001953125 +28721 0.0347900390625 +28722 -0.01171875 +28723 -0.056060791015625 +28724 -0.055511474609375 +28725 -0.010467529296875 +28726 0.02508544921875 +28727 0.025665283203125 +28728 0.017333984375 +28729 0.00189208984375 +28730 -0.03173828125 +28731 -0.071502685546875 +28732 -0.13543701171875 +28733 -0.219970703125 +28734 -0.300506591796875 +28735 -0.376312255859375 +28736 -0.416107177734375 +28737 -0.371124267578125 +28738 -0.242279052734375 +28739 -0.069732666015625 +28740 0.125640869140625 +28741 0.31268310546875 +28742 0.45501708984375 +28743 0.554779052734375 +28744 0.61065673828125 +28745 0.610931396484375 +28746 0.531463623046875 +28747 0.3883056640625 +28748 0.23468017578125 +28749 0.095245361328125 +28750 -0.00396728515625 +28751 -0.04852294921875 +28752 -0.055145263671875 +28753 -0.0758056640625 +28754 -0.138702392578125 +28755 -0.209197998046875 +28756 -0.289031982421875 +28757 -0.37884521484375 +28758 -0.456329345703125 +28759 -0.51641845703125 +28760 -0.519287109375 +28761 -0.458251953125 +28762 -0.384796142578125 +28763 -0.323699951171875 +28764 -0.269287109375 +28765 -0.1951904296875 +28766 -0.100006103515625 +28767 -0.01055908203125 +28768 0.1033935546875 +28769 0.24908447265625 +28770 0.373199462890625 +28771 0.45806884765625 +28772 0.511474609375 +28773 0.565399169921875 +28774 0.61138916015625 +28775 0.5897216796875 +28776 0.4906005859375 +28777 0.33148193359375 +28778 0.147796630859375 +28779 -0.01873779296875 +28780 -0.140289306640625 +28781 -0.191986083984375 +28782 -0.184295654296875 +28783 -0.161834716796875 +28784 -0.166595458984375 +28785 -0.19390869140625 +28786 -0.22442626953125 +28787 -0.279754638671875 +28788 -0.3389892578125 +28789 -0.3543701171875 +28790 -0.348175048828125 +28791 -0.32598876953125 +28792 -0.2581787109375 +28793 -0.139801025390625 +28794 0.014617919921875 +28795 0.144378662109375 +28796 0.221038818359375 +28797 0.27069091796875 +28798 0.294036865234375 +28799 0.311767578125 +28800 0.339141845703125 +28801 0.360260009765625 +28802 0.360504150390625 +28803 0.308380126953125 +28804 0.18170166015625 +28805 0.0047607421875 +28806 -0.17559814453125 +28807 -0.3143310546875 +28808 -0.36785888671875 +28809 -0.36248779296875 +28810 -0.343536376953125 +28811 -0.3018798828125 +28812 -0.231414794921875 +28813 -0.117645263671875 +28814 0.007049560546875 +28815 0.087982177734375 +28816 0.13946533203125 +28817 0.17425537109375 +28818 0.188201904296875 +28819 0.171234130859375 +28820 0.118438720703125 +28821 0.05706787109375 +28822 -0.010711669921875 +28823 -0.0914306640625 +28824 -0.162322998046875 +28825 -0.194549560546875 +28826 -0.1492919921875 +28827 -0.02166748046875 +28828 0.124053955078125 +28829 0.211151123046875 +28830 0.240447998046875 +28831 0.242218017578125 +28832 0.2257080078125 +28833 0.194366455078125 +28834 0.115509033203125 +28835 0.0128173828125 +28836 -0.053802490234375 +28837 -0.110626220703125 +28838 -0.199493408203125 +28839 -0.29437255859375 +28840 -0.33221435546875 +28841 -0.27972412109375 +28842 -0.185333251953125 +28843 -0.128204345703125 +28844 -0.115692138671875 +28845 -0.116455078125 +28846 -0.105926513671875 +28847 -0.053955078125 +28848 0.048797607421875 +28849 0.157318115234375 +28850 0.212005615234375 +28851 0.218475341796875 +28852 0.23724365234375 +28853 0.30535888671875 +28854 0.38128662109375 +28855 0.404449462890625 +28856 0.3944091796875 +28857 0.3885498046875 +28858 0.362640380859375 +28859 0.27362060546875 +28860 0.11712646484375 +28861 -0.054901123046875 +28862 -0.19085693359375 +28863 -0.28570556640625 +28864 -0.339263916015625 +28865 -0.3775634765625 +28866 -0.445709228515625 +28867 -0.535064697265625 +28868 -0.629058837890625 +28869 -0.697601318359375 +28870 -0.70391845703125 +28871 -0.6424560546875 +28872 -0.491241455078125 +28873 -0.265716552734375 +28874 -0.023712158203125 +28875 0.201751708984375 +28876 0.375823974609375 +28877 0.485076904296875 +28878 0.56884765625 +28879 0.634765625 +28880 0.63763427734375 +28881 0.5660400390625 +28882 0.4720458984375 +28883 0.40692138671875 +28884 0.3778076171875 +28885 0.376953125 +28886 0.371978759765625 +28887 0.313140869140625 +28888 0.184417724609375 +28889 0.011199951171875 +28890 -0.171051025390625 +28891 -0.33740234375 +28892 -0.47198486328125 +28893 -0.560394287109375 +28894 -0.58056640625 +28895 -0.54754638671875 +28896 -0.508575439453125 +28897 -0.459503173828125 +28898 -0.394378662109375 +28899 -0.35260009765625 +28900 -0.31170654296875 +28901 -0.197418212890625 +28902 -0.007965087890625 +28903 0.207489013671875 +28904 0.409210205078125 +28905 0.57208251953125 +28906 0.66595458984375 +28907 0.65875244140625 +28908 0.56744384765625 +28909 0.431396484375 +28910 0.29443359375 +28911 0.182464599609375 +28912 0.06365966796875 +28913 -0.075958251953125 +28914 -0.189422607421875 +28915 -0.271942138671875 +28916 -0.342529296875 +28917 -0.364166259765625 +28918 -0.327239990234375 +28919 -0.2769775390625 +28920 -0.253692626953125 +28921 -0.24365234375 +28922 -0.1983642578125 +28923 -0.116241455078125 +28924 -0.036834716796875 +28925 0.034881591796875 +28926 0.09124755859375 +28927 0.10888671875 +28928 0.125518798828125 +28929 0.15771484375 +28930 0.17828369140625 +28931 0.17108154296875 +28932 0.129974365234375 +28933 0.082427978515625 +28934 0.027679443359375 +28935 -0.065643310546875 +28936 -0.15936279296875 +28937 -0.21307373046875 +28938 -0.234649658203125 +28939 -0.2001953125 +28940 -0.119171142578125 +28941 -0.024749755859375 +28942 0.085784912109375 +28943 0.178131103515625 +28944 0.215576171875 +28945 0.211456298828125 +28946 0.17523193359375 +28947 0.128753662109375 +28948 0.1019287109375 +28949 0.0743408203125 +28950 0.04327392578125 +28951 0.038177490234375 +28952 0.076263427734375 +28953 0.14105224609375 +28954 0.186431884765625 +28955 0.188812255859375 +28956 0.1390380859375 +28957 0.041778564453125 +28958 -0.079437255859375 +28959 -0.219390869140625 +28960 -0.367828369140625 +28961 -0.494873046875 +28962 -0.556243896484375 +28963 -0.508697509765625 +28964 -0.3756103515625 +28965 -0.218902587890625 +28966 -0.063751220703125 +28967 0.091552734375 +28968 0.23602294921875 +28969 0.342987060546875 +28970 0.39520263671875 +28971 0.389373779296875 +28972 0.324249267578125 +28973 0.224090576171875 +28974 0.124267578125 +28975 0.037078857421875 +28976 -0.010101318359375 +28977 -0.019439697265625 +28978 -0.022796630859375 +28979 -0.001556396484375 +28980 0.056304931640625 +28981 0.106719970703125 +28982 0.096893310546875 +28983 0.042694091796875 +28984 -0.018035888671875 +28985 -0.07586669921875 +28986 -0.11944580078125 +28987 -0.15972900390625 +28988 -0.202606201171875 +28989 -0.24859619140625 +28990 -0.30517578125 +28991 -0.36212158203125 +28992 -0.39141845703125 +28993 -0.35528564453125 +28994 -0.249969482421875 +28995 -0.092864990234375 +28996 0.08905029296875 +28997 0.2352294921875 +28998 0.318817138671875 +28999 0.358642578125 +29000 0.347747802734375 +29001 0.28564453125 +29002 0.223175048828125 +29003 0.196746826171875 +29004 0.179840087890625 +29005 0.155548095703125 +29006 0.151214599609375 +29007 0.156951904296875 +29008 0.13177490234375 +29009 0.100799560546875 +29010 0.087127685546875 +29011 0.05487060546875 +29012 -0.009002685546875 +29013 -0.10400390625 +29014 -0.229400634765625 +29015 -0.35552978515625 +29016 -0.441925048828125 +29017 -0.473846435546875 +29018 -0.464813232421875 +29019 -0.419097900390625 +29020 -0.334320068359375 +29021 -0.227935791015625 +29022 -0.12347412109375 +29023 -0.02764892578125 +29024 0.077667236328125 +29025 0.2132568359375 +29026 0.38885498046875 +29027 0.582794189453125 +29028 0.734039306640625 +29029 0.800140380859375 +29030 0.7783203125 +29031 0.6651611328125 +29032 0.45965576171875 +29033 0.199188232421875 +29034 -0.050689697265625 +29035 -0.23297119140625 +29036 -0.33013916015625 +29037 -0.368408203125 +29038 -0.378936767578125 +29039 -0.376983642578125 +29040 -0.37969970703125 +29041 -0.391510009765625 +29042 -0.385345458984375 +29043 -0.3419189453125 +29044 -0.28289794921875 +29045 -0.251617431640625 +29046 -0.266143798828125 +29047 -0.273345947265625 +29048 -0.216796875 +29049 -0.128265380859375 +29050 -0.068145751953125 +29051 -0.0430908203125 +29052 -0.024444580078125 +29053 0.020721435546875 +29054 0.124481201171875 +29055 0.25787353515625 +29056 0.379119873046875 +29057 0.47991943359375 +29058 0.5281982421875 +29059 0.511138916015625 +29060 0.456207275390625 +29061 0.407470703125 +29062 0.383758544921875 +29063 0.35687255859375 +29064 0.31182861328125 +29065 0.250885009765625 +29066 0.1654052734375 +29067 0.035247802734375 +29068 -0.142059326171875 +29069 -0.33563232421875 +29070 -0.5345458984375 +29071 -0.72186279296875 +29072 -0.836669921875 +29073 -0.8326416015625 +29074 -0.7296142578125 +29075 -0.582550048828125 +29076 -0.440093994140625 +29077 -0.324310302734375 +29078 -0.20147705078125 +29079 -0.044647216796875 +29080 0.103973388671875 +29081 0.202392578125 +29082 0.264495849609375 +29083 0.338897705078125 +29084 0.443817138671875 +29085 0.545074462890625 +29086 0.6173095703125 +29087 0.6524658203125 +29088 0.66339111328125 +29089 0.6561279296875 +29090 0.606781005859375 +29091 0.501190185546875 +29092 0.352783203125 +29093 0.176544189453125 +29094 -0.034820556640625 +29095 -0.258209228515625 +29096 -0.44244384765625 +29097 -0.5753173828125 +29098 -0.65203857421875 +29099 -0.641632080078125 +29100 -0.562164306640625 +29101 -0.458038330078125 +29102 -0.350555419921875 +29103 -0.260528564453125 +29104 -0.192108154296875 +29105 -0.141937255859375 +29106 -0.1021728515625 +29107 -0.062896728515625 +29108 -0.011932373046875 +29109 0.062835693359375 +29110 0.148712158203125 +29111 0.241729736328125 +29112 0.34912109375 +29113 0.457305908203125 +29114 0.54388427734375 +29115 0.5728759765625 +29116 0.506591796875 +29117 0.351226806640625 +29118 0.146514892578125 +29119 -0.05523681640625 +29120 -0.21624755859375 +29121 -0.334930419921875 +29122 -0.402984619140625 +29123 -0.4412841796875 +29124 -0.49578857421875 +29125 -0.5601806640625 +29126 -0.600738525390625 +29127 -0.584228515625 +29128 -0.47930908203125 +29129 -0.27935791015625 +29130 -0.0089111328125 +29131 0.268798828125 +29132 0.482818603515625 +29133 0.60369873046875 +29134 0.650421142578125 +29135 0.66400146484375 +29136 0.6414794921875 +29137 0.572540283203125 +29138 0.498138427734375 +29139 0.439453125 +29140 0.375518798828125 +29141 0.274505615234375 +29142 0.1087646484375 +29143 -0.099395751953125 +29144 -0.3182373046875 +29145 -0.5489501953125 +29146 -0.7738037109375 +29147 -0.86383056640625 +29148 -0.870391845703125 +29149 -0.86895751953125 +29150 -0.861053466796875 +29151 -0.765869140625 +29152 -0.5301513671875 +29153 -0.214691162109375 +29154 0.137359619140625 +29155 0.474822998046875 +29156 0.76239013671875 +29157 0.867462158203125 +29158 0.870361328125 +29159 0.86480712890625 +29160 0.831817626953125 +29161 0.677581787109375 +29162 0.495880126953125 +29163 0.30767822265625 +29164 0.116180419921875 +29165 -0.110748291015625 +29166 -0.381805419921875 +29167 -0.6572265625 +29168 -0.857421875 +29169 -0.870391845703125 +29170 -0.870391845703125 +29171 -0.86444091796875 +29172 -0.85723876953125 +29173 -0.790008544921875 +29174 -0.62847900390625 +29175 -0.3956298828125 +29176 -0.126708984375 +29177 0.150115966796875 +29178 0.424041748046875 +29179 0.670623779296875 +29180 0.854522705078125 +29181 0.866485595703125 +29182 0.86920166015625 +29183 0.8653564453125 +29184 0.857147216796875 +29185 0.766845703125 +29186 0.628509521484375 +29187 0.462127685546875 +29188 0.297210693359375 +29189 0.14862060546875 +29190 -0.00537109375 +29191 -0.15753173828125 +29192 -0.31304931640625 +29193 -0.48876953125 +29194 -0.6416015625 +29195 -0.751373291015625 +29196 -0.84619140625 +29197 -0.861297607421875 +29198 -0.863250732421875 +29199 -0.856597900390625 +29200 -0.7498779296875 +29201 -0.624542236328125 +29202 -0.47808837890625 +29203 -0.253387451171875 +29204 0.003692626953125 +29205 0.2257080078125 +29206 0.427154541015625 +29207 0.643218994140625 +29208 0.855926513671875 +29209 0.870361328125 +29210 0.870361328125 +29211 0.862762451171875 +29212 0.79669189453125 +29213 0.595794677734375 +29214 0.362152099609375 +29215 0.1270751953125 +29216 -0.086944580078125 +29217 -0.2784423828125 +29218 -0.484832763671875 +29219 -0.729583740234375 +29220 -0.86688232421875 +29221 -0.870391845703125 +29222 -0.86859130859375 +29223 -0.86279296875 +29224 -0.817962646484375 +29225 -0.6116943359375 +29226 -0.3128662109375 +29227 0.039398193359375 +29228 0.422821044921875 +29229 0.805145263671875 +29230 0.870361328125 +29231 0.870361328125 +29232 0.860015869140625 +29233 0.727935791015625 +29234 0.48114013671875 +29235 0.2059326171875 +29236 -0.06103515625 +29237 -0.29913330078125 +29238 -0.516204833984375 +29239 -0.7252197265625 +29240 -0.85980224609375 +29241 -0.870391845703125 +29242 -0.870391845703125 +29243 -0.858062744140625 +29244 -0.673004150390625 +29245 -0.42694091796875 +29246 -0.2100830078125 +29247 -0.0362548828125 +29248 0.10943603515625 +29249 0.23516845703125 +29250 0.373687744140625 +29251 0.517791748046875 +29252 0.602783203125 +29253 0.635711669921875 +29254 0.655181884765625 +29255 0.65948486328125 +29256 0.651275634765625 +29257 0.61846923828125 +29258 0.53753662109375 +29259 0.404144287109375 +29260 0.22186279296875 +29261 0.003997802734375 +29262 -0.22100830078125 +29263 -0.42449951171875 +29264 -0.579833984375 +29265 -0.641876220703125 +29266 -0.6177978515625 +29267 -0.575531005859375 +29268 -0.526336669921875 +29269 -0.42645263671875 +29270 -0.2581787109375 +29271 -0.068695068359375 +29272 0.09222412109375 +29273 0.232147216796875 +29274 0.3509521484375 +29275 0.410064697265625 +29276 0.372955322265625 +29277 0.2554931640625 +29278 0.10711669921875 +29279 -0.052886962890625 +29280 -0.186279296875 +29281 -0.23291015625 +29282 -0.209442138671875 +29283 -0.174163818359375 +29284 -0.126739501953125 +29285 -0.048126220703125 +29286 0.0426025390625 +29287 0.10748291015625 +29288 0.1409912109375 +29289 0.19708251953125 +29290 0.273651123046875 +29291 0.31768798828125 +29292 0.341094970703125 +29293 0.368011474609375 +29294 0.37249755859375 +29295 0.30072021484375 +29296 0.1517333984375 +29297 -0.01470947265625 +29298 -0.1883544921875 +29299 -0.372711181640625 +29300 -0.51397705078125 +29301 -0.57177734375 +29302 -0.53948974609375 +29303 -0.43511962890625 +29304 -0.2962646484375 +29305 -0.161102294921875 +29306 -0.0435791015625 +29307 0.060394287109375 +29308 0.13665771484375 +29309 0.170135498046875 +29310 0.16552734375 +29311 0.15728759765625 +29312 0.150787353515625 +29313 0.12200927734375 +29314 0.080108642578125 +29315 0.05126953125 +29316 0.062896728515625 +29317 0.09271240234375 +29318 0.092987060546875 +29319 0.07855224609375 +29320 0.06427001953125 +29321 0.0347900390625 +29322 -0.01171875 +29323 -0.056060791015625 +29324 -0.055511474609375 +29325 -0.010467529296875 +29326 0.02508544921875 +29327 0.025665283203125 +29328 0.017333984375 +29329 0.00189208984375 +29330 -0.03173828125 +29331 -0.071502685546875 +29332 -0.13543701171875 +29333 -0.219970703125 +29334 -0.300506591796875 +29335 -0.376312255859375 +29336 -0.416107177734375 +29337 -0.371124267578125 +29338 -0.242279052734375 +29339 -0.069732666015625 +29340 0.125640869140625 +29341 0.31268310546875 +29342 0.45501708984375 +29343 0.554779052734375 +29344 0.61065673828125 +29345 0.610931396484375 +29346 0.531463623046875 +29347 0.3883056640625 +29348 0.23468017578125 +29349 0.095245361328125 +29350 -0.00396728515625 +29351 -0.04852294921875 +29352 -0.055145263671875 +29353 -0.0758056640625 +29354 -0.138702392578125 +29355 -0.209197998046875 +29356 -0.289031982421875 +29357 -0.37884521484375 +29358 -0.456329345703125 +29359 -0.51641845703125 +29360 -0.519287109375 +29361 -0.458251953125 +29362 -0.384796142578125 +29363 -0.323699951171875 +29364 -0.269287109375 +29365 -0.1951904296875 +29366 -0.100006103515625 +29367 -0.01055908203125 +29368 0.1033935546875 +29369 0.24908447265625 +29370 0.373199462890625 +29371 0.45806884765625 +29372 0.511474609375 +29373 0.565399169921875 +29374 0.61138916015625 +29375 0.5897216796875 +29376 0.4906005859375 +29377 0.33148193359375 +29378 0.147796630859375 +29379 -0.01873779296875 +29380 -0.140289306640625 +29381 -0.191986083984375 +29382 -0.184295654296875 +29383 -0.161834716796875 +29384 -0.166595458984375 +29385 -0.19390869140625 +29386 -0.22442626953125 +29387 -0.279754638671875 +29388 -0.3389892578125 +29389 -0.3543701171875 +29390 -0.348175048828125 +29391 -0.32598876953125 +29392 -0.2581787109375 +29393 -0.139801025390625 +29394 0.014617919921875 +29395 0.144378662109375 +29396 0.221038818359375 +29397 0.27069091796875 +29398 0.294036865234375 +29399 0.311767578125 +29400 0.339141845703125 +29401 0.360260009765625 +29402 0.360504150390625 +29403 0.308380126953125 +29404 0.18170166015625 +29405 0.0047607421875 +29406 -0.17559814453125 +29407 -0.3143310546875 +29408 -0.36785888671875 +29409 -0.36248779296875 +29410 -0.343536376953125 +29411 -0.3018798828125 +29412 -0.231414794921875 +29413 -0.117645263671875 +29414 0.007049560546875 +29415 0.087982177734375 +29416 0.13946533203125 +29417 0.17425537109375 +29418 0.188201904296875 +29419 0.171234130859375 +29420 0.118438720703125 +29421 0.05706787109375 +29422 -0.010711669921875 +29423 -0.0914306640625 +29424 -0.162322998046875 +29425 -0.194549560546875 +29426 -0.1492919921875 +29427 -0.02166748046875 +29428 0.124053955078125 +29429 0.211151123046875 +29430 0.240447998046875 +29431 0.242218017578125 +29432 0.2257080078125 +29433 0.194366455078125 +29434 0.115509033203125 +29435 0.0128173828125 +29436 -0.053802490234375 +29437 -0.110626220703125 +29438 -0.199493408203125 +29439 -0.29437255859375 +29440 -0.33221435546875 +29441 -0.27972412109375 +29442 -0.185333251953125 +29443 -0.128204345703125 +29444 -0.115692138671875 +29445 -0.116455078125 +29446 -0.105926513671875 +29447 -0.053955078125 +29448 0.048797607421875 +29449 0.157318115234375 +29450 0.212005615234375 +29451 0.218475341796875 +29452 0.23724365234375 +29453 0.30535888671875 +29454 0.38128662109375 +29455 0.404449462890625 +29456 0.3944091796875 +29457 0.3885498046875 +29458 0.362640380859375 +29459 0.27362060546875 +29460 0.11712646484375 +29461 -0.054901123046875 +29462 -0.19085693359375 +29463 -0.28570556640625 +29464 -0.339263916015625 +29465 -0.3775634765625 +29466 -0.445709228515625 +29467 -0.535064697265625 +29468 -0.629058837890625 +29469 -0.697601318359375 +29470 -0.70391845703125 +29471 -0.6424560546875 +29472 -0.491241455078125 +29473 -0.265716552734375 +29474 -0.023712158203125 +29475 0.201751708984375 +29476 0.375823974609375 +29477 0.485076904296875 +29478 0.56884765625 +29479 0.634765625 +29480 0.63763427734375 +29481 0.5660400390625 +29482 0.4720458984375 +29483 0.40692138671875 +29484 0.3778076171875 +29485 0.376953125 +29486 0.371978759765625 +29487 0.313140869140625 +29488 0.184417724609375 +29489 0.011199951171875 +29490 -0.171051025390625 +29491 -0.33740234375 +29492 -0.47198486328125 +29493 -0.560394287109375 +29494 -0.58056640625 +29495 -0.54754638671875 +29496 -0.508575439453125 +29497 -0.459503173828125 +29498 -0.394378662109375 +29499 -0.35260009765625 +29500 -0.31170654296875 +29501 -0.197418212890625 +29502 -0.007965087890625 +29503 0.207489013671875 +29504 0.409210205078125 +29505 0.57208251953125 +29506 0.66595458984375 +29507 0.65875244140625 +29508 0.56744384765625 +29509 0.431396484375 +29510 0.29443359375 +29511 0.182464599609375 +29512 0.06365966796875 +29513 -0.075958251953125 +29514 -0.189422607421875 +29515 -0.271942138671875 +29516 -0.342529296875 +29517 -0.364166259765625 +29518 -0.327239990234375 +29519 -0.2769775390625 +29520 -0.253692626953125 +29521 -0.24365234375 +29522 -0.1983642578125 +29523 -0.116241455078125 +29524 -0.036834716796875 +29525 0.034881591796875 +29526 0.09124755859375 +29527 0.10888671875 +29528 0.125518798828125 +29529 0.15771484375 +29530 0.17828369140625 +29531 0.17108154296875 +29532 0.129974365234375 +29533 0.082427978515625 +29534 0.027679443359375 +29535 -0.065643310546875 +29536 -0.15936279296875 +29537 -0.21307373046875 +29538 -0.234649658203125 +29539 -0.2001953125 +29540 -0.119171142578125 +29541 -0.024749755859375 +29542 0.085784912109375 +29543 0.178131103515625 +29544 0.215576171875 +29545 0.211456298828125 +29546 0.17523193359375 +29547 0.128753662109375 +29548 0.1019287109375 +29549 0.0743408203125 +29550 0.04327392578125 +29551 0.038177490234375 +29552 0.076263427734375 +29553 0.14105224609375 +29554 0.186431884765625 +29555 0.188812255859375 +29556 0.1390380859375 +29557 0.041778564453125 +29558 -0.079437255859375 +29559 -0.219390869140625 +29560 -0.367828369140625 +29561 -0.494873046875 +29562 -0.556243896484375 +29563 -0.508697509765625 +29564 -0.3756103515625 +29565 -0.218902587890625 +29566 -0.063751220703125 +29567 0.091552734375 +29568 0.23602294921875 +29569 0.342987060546875 +29570 0.39520263671875 +29571 0.389373779296875 +29572 0.324249267578125 +29573 0.224090576171875 +29574 0.124267578125 +29575 0.037078857421875 +29576 -0.010101318359375 +29577 -0.019439697265625 +29578 -0.022796630859375 +29579 -0.001556396484375 +29580 0.056304931640625 +29581 0.106719970703125 +29582 0.096893310546875 +29583 0.042694091796875 +29584 -0.018035888671875 +29585 -0.07586669921875 +29586 -0.11944580078125 +29587 -0.15972900390625 +29588 -0.202606201171875 +29589 -0.24859619140625 +29590 -0.30517578125 +29591 -0.36212158203125 +29592 -0.39141845703125 +29593 -0.35528564453125 +29594 -0.249969482421875 +29595 -0.092864990234375 +29596 0.08905029296875 +29597 0.2352294921875 +29598 0.318817138671875 +29599 0.358642578125 +29600 0.347747802734375 +29601 0.28564453125 +29602 0.223175048828125 +29603 0.196746826171875 +29604 0.179840087890625 +29605 0.155548095703125 +29606 0.151214599609375 +29607 0.156951904296875 +29608 0.13177490234375 +29609 0.100799560546875 +29610 0.087127685546875 +29611 0.05487060546875 +29612 -0.009002685546875 +29613 -0.10400390625 +29614 -0.229400634765625 +29615 -0.35552978515625 +29616 -0.441925048828125 +29617 -0.473846435546875 +29618 -0.464813232421875 +29619 -0.419097900390625 +29620 -0.334320068359375 +29621 -0.227935791015625 +29622 -0.12347412109375 +29623 -0.02764892578125 +29624 0.077667236328125 +29625 0.2132568359375 +29626 0.38885498046875 +29627 0.582794189453125 +29628 0.734039306640625 +29629 0.800140380859375 +29630 0.7783203125 +29631 0.6651611328125 +29632 0.45965576171875 +29633 0.199188232421875 +29634 -0.050689697265625 +29635 -0.23297119140625 +29636 -0.33013916015625 +29637 -0.368408203125 +29638 -0.378936767578125 +29639 -0.376983642578125 +29640 -0.37969970703125 +29641 -0.391510009765625 +29642 -0.385345458984375 +29643 -0.3419189453125 +29644 -0.28289794921875 +29645 -0.251617431640625 +29646 -0.266143798828125 +29647 -0.273345947265625 +29648 -0.216796875 +29649 -0.128265380859375 +29650 -0.068145751953125 +29651 -0.0430908203125 +29652 -0.024444580078125 +29653 0.020721435546875 +29654 0.124481201171875 +29655 0.25787353515625 +29656 0.379119873046875 +29657 0.47991943359375 +29658 0.5281982421875 +29659 0.511138916015625 +29660 0.456207275390625 +29661 0.407470703125 +29662 0.383758544921875 +29663 0.35687255859375 +29664 0.31182861328125 +29665 0.250885009765625 +29666 0.1654052734375 +29667 0.035247802734375 +29668 -0.142059326171875 +29669 -0.33563232421875 +29670 -0.5345458984375 +29671 -0.72186279296875 +29672 -0.836669921875 +29673 -0.8326416015625 +29674 -0.7296142578125 +29675 -0.582550048828125 +29676 -0.440093994140625 +29677 -0.324310302734375 +29678 -0.20147705078125 +29679 -0.044647216796875 +29680 0.103973388671875 +29681 0.202392578125 +29682 0.264495849609375 +29683 0.338897705078125 +29684 0.443817138671875 +29685 0.545074462890625 +29686 0.6173095703125 +29687 0.6524658203125 +29688 0.66339111328125 +29689 0.6561279296875 +29690 0.606781005859375 +29691 0.501190185546875 +29692 0.352783203125 +29693 0.176544189453125 +29694 -0.034820556640625 +29695 -0.258209228515625 +29696 -0.44244384765625 +29697 -0.5753173828125 +29698 -0.65203857421875 +29699 -0.641632080078125 +29700 -0.562164306640625 +29701 -0.458038330078125 +29702 -0.350555419921875 +29703 -0.260528564453125 +29704 -0.192108154296875 +29705 -0.141937255859375 +29706 -0.1021728515625 +29707 -0.062896728515625 +29708 -0.011932373046875 +29709 0.062835693359375 +29710 0.148712158203125 +29711 0.241729736328125 +29712 0.34912109375 +29713 0.457305908203125 +29714 0.54388427734375 +29715 0.5728759765625 +29716 0.506591796875 +29717 0.351226806640625 +29718 0.146514892578125 +29719 -0.05523681640625 +29720 -0.21624755859375 +29721 -0.334930419921875 +29722 -0.402984619140625 +29723 -0.4412841796875 +29724 -0.49578857421875 +29725 -0.5601806640625 +29726 -0.600738525390625 +29727 -0.584228515625 +29728 -0.47930908203125 +29729 -0.27935791015625 +29730 -0.0089111328125 +29731 0.268798828125 +29732 0.482818603515625 +29733 0.60369873046875 +29734 0.650421142578125 +29735 0.66400146484375 +29736 0.6414794921875 +29737 0.572540283203125 +29738 0.498138427734375 +29739 0.439453125 +29740 0.375518798828125 +29741 0.274505615234375 +29742 0.1087646484375 +29743 -0.099395751953125 +29744 -0.3182373046875 +29745 -0.5489501953125 +29746 -0.7738037109375 +29747 -0.86383056640625 +29748 -0.870391845703125 +29749 -0.86895751953125 +29750 -0.861053466796875 +29751 -0.765869140625 +29752 -0.5301513671875 +29753 -0.214691162109375 +29754 0.137359619140625 +29755 0.474822998046875 +29756 0.76239013671875 +29757 0.867462158203125 +29758 0.870361328125 +29759 0.86480712890625 +29760 0.831817626953125 +29761 0.677581787109375 +29762 0.495880126953125 +29763 0.30767822265625 +29764 0.116180419921875 +29765 -0.110748291015625 +29766 -0.381805419921875 +29767 -0.6572265625 +29768 -0.857421875 +29769 -0.870391845703125 +29770 -0.870391845703125 +29771 -0.86444091796875 +29772 -0.85723876953125 +29773 -0.790008544921875 +29774 -0.62847900390625 +29775 -0.3956298828125 +29776 -0.126708984375 +29777 0.150115966796875 +29778 0.424041748046875 +29779 0.670623779296875 +29780 0.854522705078125 +29781 0.866485595703125 +29782 0.86920166015625 +29783 0.8653564453125 +29784 0.857147216796875 +29785 0.766845703125 +29786 0.628509521484375 +29787 0.462127685546875 +29788 0.297210693359375 +29789 0.14862060546875 +29790 -0.00537109375 +29791 -0.15753173828125 +29792 -0.31304931640625 +29793 -0.48876953125 +29794 -0.6416015625 +29795 -0.751373291015625 +29796 -0.84619140625 +29797 -0.861297607421875 +29798 -0.863250732421875 +29799 -0.856597900390625 +29800 -0.7498779296875 +29801 -0.624542236328125 +29802 -0.47808837890625 +29803 -0.253387451171875 +29804 0.003692626953125 +29805 0.2257080078125 +29806 0.427154541015625 +29807 0.643218994140625 +29808 0.855926513671875 +29809 0.870361328125 +29810 0.870361328125 +29811 0.862762451171875 +29812 0.79669189453125 +29813 0.595794677734375 +29814 0.362152099609375 +29815 0.1270751953125 +29816 -0.086944580078125 +29817 -0.2784423828125 +29818 -0.484832763671875 +29819 -0.729583740234375 +29820 -0.86688232421875 +29821 -0.870391845703125 +29822 -0.86859130859375 +29823 -0.86279296875 +29824 -0.817962646484375 +29825 -0.6116943359375 +29826 -0.3128662109375 +29827 0.039398193359375 +29828 0.422821044921875 +29829 0.805145263671875 +29830 0.870361328125 +29831 0.870361328125 +29832 0.860015869140625 +29833 0.727935791015625 +29834 0.48114013671875 +29835 0.2059326171875 +29836 -0.06103515625 +29837 -0.29913330078125 +29838 -0.516204833984375 +29839 -0.7252197265625 +29840 -0.85980224609375 +29841 -0.870391845703125 +29842 -0.870391845703125 +29843 -0.858062744140625 +29844 -0.673004150390625 +29845 -0.42694091796875 +29846 -0.2100830078125 +29847 -0.0362548828125 +29848 0.10943603515625 +29849 0.23516845703125 +29850 0.373687744140625 +29851 0.517791748046875 +29852 0.602783203125 +29853 0.635711669921875 +29854 0.655181884765625 +29855 0.65948486328125 +29856 0.651275634765625 +29857 0.61846923828125 +29858 0.53753662109375 +29859 0.404144287109375 +29860 0.22186279296875 +29861 0.003997802734375 +29862 -0.22100830078125 +29863 -0.42449951171875 +29864 -0.579833984375 +29865 -0.641876220703125 +29866 -0.6177978515625 +29867 -0.575531005859375 +29868 -0.526336669921875 +29869 -0.42645263671875 +29870 -0.2581787109375 +29871 -0.068695068359375 +29872 0.09222412109375 +29873 0.232147216796875 +29874 0.3509521484375 +29875 0.410064697265625 +29876 0.372955322265625 +29877 0.2554931640625 +29878 0.10711669921875 +29879 -0.052886962890625 +29880 -0.186279296875 +29881 -0.23291015625 +29882 -0.209442138671875 +29883 -0.174163818359375 +29884 -0.126739501953125 +29885 -0.048126220703125 +29886 0.0426025390625 +29887 0.10748291015625 +29888 0.1409912109375 +29889 0.19708251953125 +29890 0.273651123046875 +29891 0.31768798828125 +29892 0.341094970703125 +29893 0.368011474609375 +29894 0.37249755859375 +29895 0.30072021484375 +29896 0.1517333984375 +29897 -0.01470947265625 +29898 -0.1883544921875 +29899 -0.372711181640625 +29900 -0.51397705078125 +29901 -0.57177734375 +29902 -0.53948974609375 +29903 -0.43511962890625 +29904 -0.2962646484375 +29905 -0.161102294921875 +29906 -0.0435791015625 +29907 0.060394287109375 +29908 0.13665771484375 +29909 0.170135498046875 +29910 0.16552734375 +29911 0.15728759765625 +29912 0.150787353515625 +29913 0.12200927734375 +29914 0.080108642578125 +29915 0.05126953125 +29916 0.062896728515625 +29917 0.09271240234375 +29918 0.092987060546875 +29919 0.07855224609375 +29920 0.06427001953125 +29921 0.0347900390625 +29922 -0.01171875 +29923 -0.056060791015625 +29924 -0.055511474609375 +29925 -0.010467529296875 +29926 0.02508544921875 +29927 0.025665283203125 +29928 0.017333984375 +29929 0.00189208984375 +29930 -0.03173828125 +29931 -0.071502685546875 +29932 -0.13543701171875 +29933 -0.219970703125 +29934 -0.300506591796875 +29935 -0.376312255859375 +29936 -0.416107177734375 +29937 -0.371124267578125 +29938 -0.242279052734375 +29939 -0.069732666015625 +29940 0.125640869140625 +29941 0.31268310546875 +29942 0.45501708984375 +29943 0.554779052734375 +29944 0.61065673828125 +29945 0.610931396484375 +29946 0.531463623046875 +29947 0.3883056640625 +29948 0.23468017578125 +29949 0.095245361328125 +29950 -0.00396728515625 +29951 -0.04852294921875 +29952 -0.055145263671875 +29953 -0.0758056640625 +29954 -0.138702392578125 +29955 -0.209197998046875 +29956 -0.289031982421875 +29957 -0.37884521484375 +29958 -0.456329345703125 +29959 -0.51641845703125 +29960 -0.519287109375 +29961 -0.458251953125 +29962 -0.384796142578125 +29963 -0.323699951171875 +29964 -0.269287109375 +29965 -0.1951904296875 +29966 -0.100006103515625 +29967 -0.01055908203125 +29968 0.1033935546875 +29969 0.24908447265625 +29970 0.373199462890625 +29971 0.45806884765625 +29972 0.511474609375 +29973 0.565399169921875 +29974 0.61138916015625 +29975 0.5897216796875 +29976 0.4906005859375 +29977 0.33148193359375 +29978 0.147796630859375 +29979 -0.01873779296875 +29980 -0.140289306640625 +29981 -0.191986083984375 +29982 -0.184295654296875 +29983 -0.161834716796875 +29984 -0.166595458984375 +29985 -0.19390869140625 +29986 -0.22442626953125 +29987 -0.279754638671875 +29988 -0.3389892578125 +29989 -0.3543701171875 +29990 -0.348175048828125 +29991 -0.32598876953125 +29992 -0.2581787109375 +29993 -0.139801025390625 +29994 0.014617919921875 +29995 0.144378662109375 +29996 0.221038818359375 +29997 0.27069091796875 +29998 0.294036865234375 +29999 0.311767578125 +30000 0.339141845703125 +30001 0.360260009765625 +30002 0.360504150390625 +30003 0.308380126953125 +30004 0.18170166015625 +30005 0.0047607421875 +30006 -0.17559814453125 +30007 -0.3143310546875 +30008 -0.36785888671875 +30009 -0.36248779296875 +30010 -0.343536376953125 +30011 -0.3018798828125 +30012 -0.231414794921875 +30013 -0.117645263671875 +30014 0.007049560546875 +30015 0.087982177734375 +30016 0.13946533203125 +30017 0.17425537109375 +30018 0.188201904296875 +30019 0.171234130859375 +30020 0.118438720703125 +30021 0.05706787109375 +30022 -0.010711669921875 +30023 -0.0914306640625 +30024 -0.162322998046875 +30025 -0.194549560546875 +30026 -0.1492919921875 +30027 -0.02166748046875 +30028 0.124053955078125 +30029 0.211151123046875 +30030 0.240447998046875 +30031 0.242218017578125 +30032 0.2257080078125 +30033 0.194366455078125 +30034 0.115509033203125 +30035 0.0128173828125 +30036 -0.053802490234375 +30037 -0.110626220703125 +30038 -0.199493408203125 +30039 -0.29437255859375 +30040 -0.33221435546875 +30041 -0.27972412109375 +30042 -0.185333251953125 +30043 -0.128204345703125 +30044 -0.115692138671875 +30045 -0.116455078125 +30046 -0.105926513671875 +30047 -0.053955078125 +30048 0.048797607421875 +30049 0.157318115234375 +30050 0.212005615234375 +30051 0.218475341796875 +30052 0.23724365234375 +30053 0.30535888671875 +30054 0.38128662109375 +30055 0.404449462890625 +30056 0.3944091796875 +30057 0.3885498046875 +30058 0.362640380859375 +30059 0.27362060546875 +30060 0.11712646484375 +30061 -0.054901123046875 +30062 -0.19085693359375 +30063 -0.28570556640625 +30064 -0.339263916015625 +30065 -0.3775634765625 +30066 -0.445709228515625 +30067 -0.535064697265625 +30068 -0.629058837890625 +30069 -0.697601318359375 +30070 -0.70391845703125 +30071 -0.6424560546875 +30072 -0.491241455078125 +30073 -0.265716552734375 +30074 -0.023712158203125 +30075 0.201751708984375 +30076 0.375823974609375 +30077 0.485076904296875 +30078 0.56884765625 +30079 0.634765625 +30080 0.63763427734375 +30081 0.5660400390625 +30082 0.4720458984375 +30083 0.40692138671875 +30084 0.3778076171875 +30085 0.376953125 +30086 0.371978759765625 +30087 0.313140869140625 +30088 0.184417724609375 +30089 0.011199951171875 +30090 -0.171051025390625 +30091 -0.33740234375 +30092 -0.47198486328125 +30093 -0.560394287109375 +30094 -0.58056640625 +30095 -0.54754638671875 +30096 -0.508575439453125 +30097 -0.459503173828125 +30098 -0.394378662109375 +30099 -0.35260009765625 +30100 -0.31170654296875 +30101 -0.197418212890625 +30102 -0.007965087890625 +30103 0.207489013671875 +30104 0.409210205078125 +30105 0.57208251953125 +30106 0.66595458984375 +30107 0.65875244140625 +30108 0.56744384765625 +30109 0.431396484375 +30110 0.29443359375 +30111 0.182464599609375 +30112 0.06365966796875 +30113 -0.075958251953125 +30114 -0.189422607421875 +30115 -0.271942138671875 +30116 -0.342529296875 +30117 -0.364166259765625 +30118 -0.327239990234375 +30119 -0.2769775390625 +30120 -0.253692626953125 +30121 -0.24365234375 +30122 -0.1983642578125 +30123 -0.116241455078125 +30124 -0.036834716796875 +30125 0.034881591796875 +30126 0.09124755859375 +30127 0.10888671875 +30128 0.125518798828125 +30129 0.15771484375 +30130 0.17828369140625 +30131 0.17108154296875 +30132 0.129974365234375 +30133 0.082427978515625 +30134 0.027679443359375 +30135 -0.065643310546875 +30136 -0.15936279296875 +30137 -0.21307373046875 +30138 -0.234649658203125 +30139 -0.2001953125 +30140 -0.119171142578125 +30141 -0.024749755859375 +30142 0.085784912109375 +30143 0.178131103515625 +30144 0.215576171875 +30145 0.211456298828125 +30146 0.17523193359375 +30147 0.128753662109375 +30148 0.1019287109375 +30149 0.0743408203125 +30150 0.04327392578125 +30151 0.038177490234375 +30152 0.076263427734375 +30153 0.14105224609375 +30154 0.186431884765625 +30155 0.188812255859375 +30156 0.1390380859375 +30157 0.041778564453125 +30158 -0.079437255859375 +30159 -0.219390869140625 +30160 -0.367828369140625 +30161 -0.494873046875 +30162 -0.556243896484375 +30163 -0.508697509765625 +30164 -0.3756103515625 +30165 -0.218902587890625 +30166 -0.063751220703125 +30167 0.091552734375 +30168 0.23602294921875 +30169 0.342987060546875 +30170 0.39520263671875 +30171 0.389373779296875 +30172 0.324249267578125 +30173 0.224090576171875 +30174 0.124267578125 +30175 0.037078857421875 +30176 -0.010101318359375 +30177 -0.019439697265625 +30178 -0.022796630859375 +30179 -0.001556396484375 +30180 0.056304931640625 +30181 0.106719970703125 +30182 0.096893310546875 +30183 0.042694091796875 +30184 -0.018035888671875 +30185 -0.07586669921875 +30186 -0.11944580078125 +30187 -0.15972900390625 +30188 -0.202606201171875 +30189 -0.24859619140625 +30190 -0.30517578125 +30191 -0.36212158203125 +30192 -0.39141845703125 +30193 -0.35528564453125 +30194 -0.249969482421875 +30195 -0.092864990234375 +30196 0.08905029296875 +30197 0.2352294921875 +30198 0.318817138671875 +30199 0.358642578125 +30200 0.347747802734375 +30201 0.28564453125 +30202 0.223175048828125 +30203 0.196746826171875 +30204 0.179840087890625 +30205 0.155548095703125 +30206 0.151214599609375 +30207 0.156951904296875 +30208 0.13177490234375 +30209 0.100799560546875 +30210 0.087127685546875 +30211 0.05487060546875 +30212 -0.009002685546875 +30213 -0.10400390625 +30214 -0.229400634765625 +30215 -0.35552978515625 +30216 -0.441925048828125 +30217 -0.473846435546875 +30218 -0.464813232421875 +30219 -0.419097900390625 +30220 -0.334320068359375 +30221 -0.227935791015625 +30222 -0.12347412109375 +30223 -0.02764892578125 +30224 0.077667236328125 +30225 0.2132568359375 +30226 0.38885498046875 +30227 0.582794189453125 +30228 0.734039306640625 +30229 0.800140380859375 +30230 0.7783203125 +30231 0.6651611328125 +30232 0.45965576171875 +30233 0.199188232421875 +30234 -0.050689697265625 +30235 -0.23297119140625 +30236 -0.33013916015625 +30237 -0.368408203125 +30238 -0.378936767578125 +30239 -0.376983642578125 +30240 -0.37969970703125 +30241 -0.391510009765625 +30242 -0.385345458984375 +30243 -0.3419189453125 +30244 -0.28289794921875 +30245 -0.251617431640625 +30246 -0.266143798828125 +30247 -0.273345947265625 +30248 -0.216796875 +30249 -0.128265380859375 +30250 -0.068145751953125 +30251 -0.0430908203125 +30252 -0.024444580078125 +30253 0.020721435546875 +30254 0.124481201171875 +30255 0.25787353515625 +30256 0.379119873046875 +30257 0.47991943359375 +30258 0.5281982421875 +30259 0.511138916015625 +30260 0.456207275390625 +30261 0.407470703125 +30262 0.383758544921875 +30263 0.35687255859375 +30264 0.31182861328125 +30265 0.250885009765625 +30266 0.1654052734375 +30267 0.035247802734375 +30268 -0.142059326171875 +30269 -0.33563232421875 +30270 -0.5345458984375 +30271 -0.72186279296875 +30272 -0.836669921875 +30273 -0.8326416015625 +30274 -0.7296142578125 +30275 -0.582550048828125 +30276 -0.440093994140625 +30277 -0.324310302734375 +30278 -0.20147705078125 +30279 -0.044647216796875 +30280 0.103973388671875 +30281 0.202392578125 +30282 0.264495849609375 +30283 0.338897705078125 +30284 0.443817138671875 +30285 0.545074462890625 +30286 0.6173095703125 +30287 0.6524658203125 +30288 0.66339111328125 +30289 0.6561279296875 +30290 0.606781005859375 +30291 0.501190185546875 +30292 0.352783203125 +30293 0.176544189453125 +30294 -0.034820556640625 +30295 -0.258209228515625 +30296 -0.44244384765625 +30297 -0.5753173828125 +30298 -0.65203857421875 +30299 -0.641632080078125 +30300 -0.562164306640625 +30301 -0.458038330078125 +30302 -0.350555419921875 +30303 -0.260528564453125 +30304 -0.192108154296875 +30305 -0.141937255859375 +30306 -0.1021728515625 +30307 -0.062896728515625 +30308 -0.011932373046875 +30309 0.062835693359375 +30310 0.148712158203125 +30311 0.241729736328125 +30312 0.34912109375 +30313 0.457305908203125 +30314 0.54388427734375 +30315 0.5728759765625 +30316 0.506591796875 +30317 0.351226806640625 +30318 0.146514892578125 +30319 -0.05523681640625 +30320 -0.21624755859375 +30321 -0.334930419921875 +30322 -0.402984619140625 +30323 -0.4412841796875 +30324 -0.49578857421875 +30325 -0.5601806640625 +30326 -0.600738525390625 +30327 -0.584228515625 +30328 -0.47930908203125 +30329 -0.27935791015625 +30330 -0.0089111328125 +30331 0.268798828125 +30332 0.482818603515625 +30333 0.60369873046875 +30334 0.650421142578125 +30335 0.66400146484375 +30336 0.6414794921875 +30337 0.572540283203125 +30338 0.498138427734375 +30339 0.439453125 +30340 0.375518798828125 +30341 0.274505615234375 +30342 0.1087646484375 +30343 -0.099395751953125 +30344 -0.3182373046875 +30345 -0.5489501953125 +30346 -0.7738037109375 +30347 -0.86383056640625 +30348 -0.870391845703125 +30349 -0.86895751953125 +30350 -0.861053466796875 +30351 -0.765869140625 +30352 -0.5301513671875 +30353 -0.214691162109375 +30354 0.137359619140625 +30355 0.474822998046875 +30356 0.76239013671875 +30357 0.867462158203125 +30358 0.870361328125 +30359 0.86480712890625 +30360 0.831817626953125 +30361 0.677581787109375 +30362 0.495880126953125 +30363 0.30767822265625 +30364 0.116180419921875 +30365 -0.110748291015625 +30366 -0.381805419921875 +30367 -0.6572265625 +30368 -0.857421875 +30369 -0.870391845703125 +30370 -0.870391845703125 +30371 -0.86444091796875 +30372 -0.85723876953125 +30373 -0.790008544921875 +30374 -0.62847900390625 +30375 -0.3956298828125 +30376 -0.126708984375 +30377 0.150115966796875 +30378 0.424041748046875 +30379 0.670623779296875 +30380 0.854522705078125 +30381 0.866485595703125 +30382 0.86920166015625 +30383 0.8653564453125 +30384 0.857147216796875 +30385 0.766845703125 +30386 0.628509521484375 +30387 0.462127685546875 +30388 0.297210693359375 +30389 0.14862060546875 +30390 -0.00537109375 +30391 -0.15753173828125 +30392 -0.31304931640625 +30393 -0.48876953125 +30394 -0.6416015625 +30395 -0.751373291015625 +30396 -0.84619140625 +30397 -0.861297607421875 +30398 -0.863250732421875 +30399 -0.856597900390625 +30400 -0.7498779296875 +30401 -0.624542236328125 +30402 -0.47808837890625 +30403 -0.253387451171875 +30404 0.003692626953125 +30405 0.2257080078125 +30406 0.427154541015625 +30407 0.643218994140625 +30408 0.855926513671875 +30409 0.870361328125 +30410 0.870361328125 +30411 0.862762451171875 +30412 0.79669189453125 +30413 0.595794677734375 +30414 0.362152099609375 +30415 0.1270751953125 +30416 -0.086944580078125 +30417 -0.2784423828125 +30418 -0.484832763671875 +30419 -0.729583740234375 +30420 -0.86688232421875 +30421 -0.870391845703125 +30422 -0.86859130859375 +30423 -0.86279296875 +30424 -0.817962646484375 +30425 -0.6116943359375 +30426 -0.3128662109375 +30427 0.039398193359375 +30428 0.422821044921875 +30429 0.805145263671875 +30430 0.870361328125 +30431 0.870361328125 +30432 0.860015869140625 +30433 0.727935791015625 +30434 0.48114013671875 +30435 0.2059326171875 +30436 -0.06103515625 +30437 -0.29913330078125 +30438 -0.516204833984375 +30439 -0.7252197265625 +30440 -0.85980224609375 +30441 -0.870391845703125 +30442 -0.870391845703125 +30443 -0.858062744140625 +30444 -0.673004150390625 +30445 -0.42694091796875 +30446 -0.2100830078125 +30447 -0.0362548828125 +30448 0.10943603515625 +30449 0.23516845703125 +30450 0.373687744140625 +30451 0.517791748046875 +30452 0.602783203125 +30453 0.635711669921875 +30454 0.655181884765625 +30455 0.65948486328125 +30456 0.651275634765625 +30457 0.61846923828125 +30458 0.53753662109375 +30459 0.404144287109375 +30460 0.22186279296875 +30461 0.003997802734375 +30462 -0.22100830078125 +30463 -0.42449951171875 +30464 -0.579833984375 +30465 -0.641876220703125 +30466 -0.6177978515625 +30467 -0.575531005859375 +30468 -0.526336669921875 +30469 -0.42645263671875 +30470 -0.2581787109375 +30471 -0.068695068359375 +30472 0.09222412109375 +30473 0.232147216796875 +30474 0.3509521484375 +30475 0.410064697265625 +30476 0.372955322265625 +30477 0.2554931640625 +30478 0.10711669921875 +30479 -0.052886962890625 +30480 -0.186279296875 +30481 -0.23291015625 +30482 -0.209442138671875 +30483 -0.174163818359375 +30484 -0.126739501953125 +30485 -0.048126220703125 +30486 0.0426025390625 +30487 0.10748291015625 +30488 0.1409912109375 +30489 0.19708251953125 +30490 0.273651123046875 +30491 0.31768798828125 +30492 0.341094970703125 +30493 0.368011474609375 +30494 0.37249755859375 +30495 0.30072021484375 +30496 0.1517333984375 +30497 -0.01470947265625 +30498 -0.1883544921875 +30499 -0.372711181640625 +30500 -0.51397705078125 +30501 -0.57177734375 +30502 -0.53948974609375 +30503 -0.43511962890625 +30504 -0.2962646484375 +30505 -0.161102294921875 +30506 -0.0435791015625 +30507 0.060394287109375 +30508 0.13665771484375 +30509 0.170135498046875 +30510 0.16552734375 +30511 0.15728759765625 +30512 0.150787353515625 +30513 0.12200927734375 +30514 0.080108642578125 +30515 0.05126953125 +30516 0.062896728515625 +30517 0.09271240234375 +30518 0.092987060546875 +30519 0.07855224609375 +30520 0.06427001953125 +30521 0.0347900390625 +30522 -0.01171875 +30523 -0.056060791015625 +30524 -0.055511474609375 +30525 -0.010467529296875 +30526 0.02508544921875 +30527 0.025665283203125 +30528 0.017333984375 +30529 0.00189208984375 +30530 -0.03173828125 +30531 -0.071502685546875 +30532 -0.13543701171875 +30533 -0.219970703125 +30534 -0.300506591796875 +30535 -0.376312255859375 +30536 -0.416107177734375 +30537 -0.371124267578125 +30538 -0.242279052734375 +30539 -0.069732666015625 +30540 0.125640869140625 +30541 0.31268310546875 +30542 0.45501708984375 +30543 0.554779052734375 +30544 0.61065673828125 +30545 0.610931396484375 +30546 0.531463623046875 +30547 0.3883056640625 +30548 0.23468017578125 +30549 0.095245361328125 +30550 -0.00396728515625 +30551 -0.04852294921875 +30552 -0.055145263671875 +30553 -0.0758056640625 +30554 -0.138702392578125 +30555 -0.209197998046875 +30556 -0.289031982421875 +30557 -0.37884521484375 +30558 -0.456329345703125 +30559 -0.51641845703125 +30560 -0.519287109375 +30561 -0.458251953125 +30562 -0.384796142578125 +30563 -0.323699951171875 +30564 -0.269287109375 +30565 -0.1951904296875 +30566 -0.100006103515625 +30567 -0.01055908203125 +30568 0.1033935546875 +30569 0.24908447265625 +30570 0.373199462890625 +30571 0.45806884765625 +30572 0.511474609375 +30573 0.565399169921875 +30574 0.61138916015625 +30575 0.5897216796875 +30576 0.4906005859375 +30577 0.33148193359375 +30578 0.147796630859375 +30579 -0.01873779296875 +30580 -0.140289306640625 +30581 -0.191986083984375 +30582 -0.184295654296875 +30583 -0.161834716796875 +30584 -0.166595458984375 +30585 -0.19390869140625 +30586 -0.22442626953125 +30587 -0.279754638671875 +30588 -0.3389892578125 +30589 -0.3543701171875 +30590 -0.348175048828125 +30591 -0.32598876953125 +30592 -0.2581787109375 +30593 -0.139801025390625 +30594 0.014617919921875 +30595 0.144378662109375 +30596 0.221038818359375 +30597 0.27069091796875 +30598 0.294036865234375 +30599 0.311767578125 +30600 0.339141845703125 +30601 0.360260009765625 +30602 0.360504150390625 +30603 0.308380126953125 +30604 0.18170166015625 +30605 0.0047607421875 +30606 -0.17559814453125 +30607 -0.3143310546875 +30608 -0.36785888671875 +30609 -0.36248779296875 +30610 -0.343536376953125 +30611 -0.3018798828125 +30612 -0.231414794921875 +30613 -0.117645263671875 +30614 0.007049560546875 +30615 0.087982177734375 +30616 0.13946533203125 +30617 0.17425537109375 +30618 0.188201904296875 +30619 0.171234130859375 +30620 0.118438720703125 +30621 0.05706787109375 +30622 -0.010711669921875 +30623 -0.0914306640625 +30624 -0.162322998046875 +30625 -0.194549560546875 +30626 -0.1492919921875 +30627 -0.02166748046875 +30628 0.124053955078125 +30629 0.211151123046875 +30630 0.240447998046875 +30631 0.242218017578125 +30632 0.2257080078125 +30633 0.194366455078125 +30634 0.115509033203125 +30635 0.0128173828125 +30636 -0.053802490234375 +30637 -0.110626220703125 +30638 -0.199493408203125 +30639 -0.29437255859375 +30640 -0.33221435546875 +30641 -0.27972412109375 +30642 -0.185333251953125 +30643 -0.128204345703125 +30644 -0.115692138671875 +30645 -0.116455078125 +30646 -0.105926513671875 +30647 -0.053955078125 +30648 0.048797607421875 +30649 0.157318115234375 +30650 0.212005615234375 +30651 0.218475341796875 +30652 0.23724365234375 +30653 0.30535888671875 +30654 0.38128662109375 +30655 0.404449462890625 +30656 0.3944091796875 +30657 0.3885498046875 +30658 0.362640380859375 +30659 0.27362060546875 +30660 0.11712646484375 +30661 -0.054901123046875 +30662 -0.19085693359375 +30663 -0.28570556640625 +30664 -0.339263916015625 +30665 -0.3775634765625 +30666 -0.445709228515625 +30667 -0.535064697265625 +30668 -0.629058837890625 +30669 -0.697601318359375 +30670 -0.70391845703125 +30671 -0.6424560546875 +30672 -0.491241455078125 +30673 -0.265716552734375 +30674 -0.023712158203125 +30675 0.201751708984375 +30676 0.375823974609375 +30677 0.485076904296875 +30678 0.56884765625 +30679 0.634765625 +30680 0.63763427734375 +30681 0.5660400390625 +30682 0.4720458984375 +30683 0.40692138671875 +30684 0.3778076171875 +30685 0.376953125 +30686 0.371978759765625 +30687 0.313140869140625 +30688 0.184417724609375 +30689 0.011199951171875 +30690 -0.171051025390625 +30691 -0.33740234375 +30692 -0.47198486328125 +30693 -0.560394287109375 +30694 -0.58056640625 +30695 -0.54754638671875 +30696 -0.508575439453125 +30697 -0.459503173828125 +30698 -0.394378662109375 +30699 -0.35260009765625 +30700 -0.31170654296875 +30701 -0.197418212890625 +30702 -0.007965087890625 +30703 0.207489013671875 +30704 0.409210205078125 +30705 0.57208251953125 +30706 0.66595458984375 +30707 0.65875244140625 +30708 0.56744384765625 +30709 0.431396484375 +30710 0.29443359375 +30711 0.182464599609375 +30712 0.06365966796875 +30713 -0.075958251953125 +30714 -0.189422607421875 +30715 -0.271942138671875 +30716 -0.342529296875 +30717 -0.364166259765625 +30718 -0.327239990234375 +30719 -0.2769775390625 +30720 -0.253692626953125 +30721 -0.24365234375 +30722 -0.1983642578125 +30723 -0.116241455078125 +30724 -0.036834716796875 +30725 0.034881591796875 +30726 0.09124755859375 +30727 0.10888671875 +30728 0.125518798828125 +30729 0.15771484375 +30730 0.17828369140625 +30731 0.17108154296875 +30732 0.129974365234375 +30733 0.082427978515625 +30734 0.027679443359375 +30735 -0.065643310546875 +30736 -0.15936279296875 +30737 -0.21307373046875 +30738 -0.234649658203125 +30739 -0.2001953125 +30740 -0.119171142578125 +30741 -0.024749755859375 +30742 0.085784912109375 +30743 0.178131103515625 +30744 0.215576171875 +30745 0.211456298828125 +30746 0.17523193359375 +30747 0.128753662109375 +30748 0.1019287109375 +30749 0.0743408203125 +30750 0.04327392578125 +30751 0.038177490234375 +30752 0.076263427734375 +30753 0.14105224609375 +30754 0.186431884765625 +30755 0.188812255859375 +30756 0.1390380859375 +30757 0.041778564453125 +30758 -0.079437255859375 +30759 -0.219390869140625 +30760 -0.367828369140625 +30761 -0.494873046875 +30762 -0.556243896484375 +30763 -0.508697509765625 +30764 -0.3756103515625 +30765 -0.218902587890625 +30766 -0.063751220703125 +30767 0.091552734375 +30768 0.23602294921875 +30769 0.342987060546875 +30770 0.39520263671875 +30771 0.389373779296875 +30772 0.324249267578125 +30773 0.224090576171875 +30774 0.124267578125 +30775 0.037078857421875 +30776 -0.010101318359375 +30777 -0.019439697265625 +30778 -0.022796630859375 +30779 -0.001556396484375 +30780 0.056304931640625 +30781 0.106719970703125 +30782 0.096893310546875 +30783 0.042694091796875 +30784 -0.018035888671875 +30785 -0.07586669921875 +30786 -0.11944580078125 +30787 -0.15972900390625 +30788 -0.202606201171875 +30789 -0.24859619140625 +30790 -0.30517578125 +30791 -0.36212158203125 +30792 -0.39141845703125 +30793 -0.35528564453125 +30794 -0.249969482421875 +30795 -0.092864990234375 +30796 0.08905029296875 +30797 0.2352294921875 +30798 0.318817138671875 +30799 0.358642578125 +30800 0.347747802734375 +30801 0.28564453125 +30802 0.223175048828125 +30803 0.196746826171875 +30804 0.179840087890625 +30805 0.155548095703125 +30806 0.151214599609375 +30807 0.156951904296875 +30808 0.13177490234375 +30809 0.100799560546875 +30810 0.087127685546875 +30811 0.05487060546875 +30812 -0.009002685546875 +30813 -0.10400390625 +30814 -0.229400634765625 +30815 -0.35552978515625 +30816 -0.441925048828125 +30817 -0.473846435546875 +30818 -0.464813232421875 +30819 -0.419097900390625 +30820 -0.334320068359375 +30821 -0.227935791015625 +30822 -0.12347412109375 +30823 -0.02764892578125 +30824 0.077667236328125 +30825 0.2132568359375 +30826 0.38885498046875 +30827 0.582794189453125 +30828 0.734039306640625 +30829 0.800140380859375 +30830 0.7783203125 +30831 0.6651611328125 +30832 0.45965576171875 +30833 0.199188232421875 +30834 -0.050689697265625 +30835 -0.23297119140625 +30836 -0.33013916015625 +30837 -0.368408203125 +30838 -0.378936767578125 +30839 -0.376983642578125 +30840 -0.37969970703125 +30841 -0.391510009765625 +30842 -0.385345458984375 +30843 -0.3419189453125 +30844 -0.28289794921875 +30845 -0.251617431640625 +30846 -0.266143798828125 +30847 -0.273345947265625 +30848 -0.216796875 +30849 -0.128265380859375 +30850 -0.068145751953125 +30851 -0.0430908203125 +30852 -0.024444580078125 +30853 0.020721435546875 +30854 0.124481201171875 +30855 0.25787353515625 +30856 0.379119873046875 +30857 0.47991943359375 +30858 0.5281982421875 +30859 0.511138916015625 +30860 0.456207275390625 +30861 0.407470703125 +30862 0.383758544921875 +30863 0.35687255859375 +30864 0.31182861328125 +30865 0.250885009765625 +30866 0.1654052734375 +30867 0.035247802734375 +30868 -0.142059326171875 +30869 -0.33563232421875 +30870 -0.5345458984375 +30871 -0.72186279296875 +30872 -0.836669921875 +30873 -0.8326416015625 +30874 -0.7296142578125 +30875 -0.582550048828125 +30876 -0.440093994140625 +30877 -0.324310302734375 +30878 -0.20147705078125 +30879 -0.044647216796875 +30880 0.103973388671875 +30881 0.202392578125 +30882 0.264495849609375 +30883 0.338897705078125 +30884 0.443817138671875 +30885 0.545074462890625 +30886 0.6173095703125 +30887 0.6524658203125 +30888 0.66339111328125 +30889 0.6561279296875 +30890 0.606781005859375 +30891 0.501190185546875 +30892 0.352783203125 +30893 0.176544189453125 +30894 -0.034820556640625 +30895 -0.258209228515625 +30896 -0.44244384765625 +30897 -0.5753173828125 +30898 -0.65203857421875 +30899 -0.641632080078125 +30900 -0.562164306640625 +30901 -0.458038330078125 +30902 -0.350555419921875 +30903 -0.260528564453125 +30904 -0.192108154296875 +30905 -0.141937255859375 +30906 -0.1021728515625 +30907 -0.062896728515625 +30908 -0.011932373046875 +30909 0.062835693359375 +30910 0.148712158203125 +30911 0.241729736328125 +30912 0.34912109375 +30913 0.457305908203125 +30914 0.54388427734375 +30915 0.5728759765625 +30916 0.506591796875 +30917 0.351226806640625 +30918 0.146514892578125 +30919 -0.05523681640625 +30920 -0.21624755859375 +30921 -0.334930419921875 +30922 -0.402984619140625 +30923 -0.4412841796875 +30924 -0.49578857421875 +30925 -0.5601806640625 +30926 -0.600738525390625 +30927 -0.584228515625 +30928 -0.47930908203125 +30929 -0.27935791015625 +30930 -0.0089111328125 +30931 0.268798828125 +30932 0.482818603515625 +30933 0.60369873046875 +30934 0.650421142578125 +30935 0.66400146484375 +30936 0.6414794921875 +30937 0.572540283203125 +30938 0.498138427734375 +30939 0.439453125 +30940 0.375518798828125 +30941 0.274505615234375 +30942 0.1087646484375 +30943 -0.099395751953125 +30944 -0.3182373046875 +30945 -0.5489501953125 +30946 -0.7738037109375 +30947 -0.86383056640625 +30948 -0.870391845703125 +30949 -0.86895751953125 +30950 -0.861053466796875 +30951 -0.765869140625 +30952 -0.5301513671875 +30953 -0.214691162109375 +30954 0.137359619140625 +30955 0.474822998046875 +30956 0.76239013671875 +30957 0.867462158203125 +30958 0.870361328125 +30959 0.86480712890625 +30960 0.831817626953125 +30961 0.677581787109375 +30962 0.495880126953125 +30963 0.30767822265625 +30964 0.116180419921875 +30965 -0.110748291015625 +30966 -0.381805419921875 +30967 -0.6572265625 +30968 -0.857421875 +30969 -0.870391845703125 +30970 -0.870391845703125 +30971 -0.86444091796875 +30972 -0.85723876953125 +30973 -0.790008544921875 +30974 -0.62847900390625 +30975 -0.3956298828125 +30976 -0.126708984375 +30977 0.150115966796875 +30978 0.424041748046875 +30979 0.670623779296875 +30980 0.854522705078125 +30981 0.866485595703125 +30982 0.86920166015625 +30983 0.8653564453125 +30984 0.857147216796875 +30985 0.766845703125 +30986 0.628509521484375 +30987 0.462127685546875 +30988 0.297210693359375 +30989 0.14862060546875 +30990 -0.00537109375 +30991 -0.15753173828125 +30992 -0.31304931640625 +30993 -0.48876953125 +30994 -0.6416015625 +30995 -0.751373291015625 +30996 -0.84619140625 +30997 -0.861297607421875 +30998 -0.863250732421875 +30999 -0.856597900390625 +31000 -0.7498779296875 +31001 -0.624542236328125 +31002 -0.47808837890625 +31003 -0.253387451171875 +31004 0.003692626953125 +31005 0.2257080078125 +31006 0.427154541015625 +31007 0.643218994140625 +31008 0.855926513671875 +31009 0.870361328125 +31010 0.870361328125 +31011 0.862762451171875 +31012 0.79669189453125 +31013 0.595794677734375 +31014 0.362152099609375 +31015 0.1270751953125 +31016 -0.086944580078125 +31017 -0.2784423828125 +31018 -0.484832763671875 +31019 -0.729583740234375 +31020 -0.86688232421875 +31021 -0.870391845703125 +31022 -0.86859130859375 +31023 -0.86279296875 +31024 -0.817962646484375 +31025 -0.6116943359375 +31026 -0.3128662109375 +31027 0.039398193359375 +31028 0.422821044921875 +31029 0.805145263671875 +31030 0.870361328125 +31031 0.870361328125 +31032 0.860015869140625 +31033 0.727935791015625 +31034 0.48114013671875 +31035 0.2059326171875 +31036 -0.06103515625 +31037 -0.29913330078125 +31038 -0.516204833984375 +31039 -0.7252197265625 +31040 -0.85980224609375 +31041 -0.870391845703125 +31042 -0.870391845703125 +31043 -0.858062744140625 +31044 -0.673004150390625 +31045 -0.42694091796875 +31046 -0.2100830078125 +31047 -0.0362548828125 +31048 0.10943603515625 +31049 0.23516845703125 +31050 0.373687744140625 +31051 0.517791748046875 +31052 0.602783203125 +31053 0.635711669921875 +31054 0.655181884765625 +31055 0.65948486328125 +31056 0.651275634765625 +31057 0.61846923828125 +31058 0.53753662109375 +31059 0.404144287109375 +31060 0.22186279296875 +31061 0.003997802734375 +31062 -0.22100830078125 +31063 -0.42449951171875 +31064 -0.579833984375 +31065 -0.641876220703125 +31066 -0.6177978515625 +31067 -0.575531005859375 +31068 -0.526336669921875 +31069 -0.42645263671875 +31070 -0.2581787109375 +31071 -0.068695068359375 +31072 0.09222412109375 +31073 0.232147216796875 +31074 0.3509521484375 +31075 0.410064697265625 +31076 0.372955322265625 +31077 0.2554931640625 +31078 0.10711669921875 +31079 -0.052886962890625 +31080 -0.186279296875 +31081 -0.23291015625 +31082 -0.209442138671875 +31083 -0.174163818359375 +31084 -0.126739501953125 +31085 -0.048126220703125 +31086 0.0426025390625 +31087 0.10748291015625 +31088 0.1409912109375 +31089 0.19708251953125 +31090 0.273651123046875 +31091 0.31768798828125 +31092 0.341094970703125 +31093 0.368011474609375 +31094 0.37249755859375 +31095 0.30072021484375 +31096 0.1517333984375 +31097 -0.01470947265625 +31098 -0.1883544921875 +31099 -0.372711181640625 +31100 -0.51397705078125 +31101 -0.57177734375 +31102 -0.53948974609375 +31103 -0.43511962890625 +31104 -0.2962646484375 +31105 -0.161102294921875 +31106 -0.0435791015625 +31107 0.060394287109375 +31108 0.13665771484375 +31109 0.170135498046875 +31110 0.16552734375 +31111 0.15728759765625 +31112 0.150787353515625 +31113 0.12200927734375 +31114 0.080108642578125 +31115 0.05126953125 +31116 0.062896728515625 +31117 0.09271240234375 +31118 0.092987060546875 +31119 0.07855224609375 +31120 0.06427001953125 +31121 0.0347900390625 +31122 -0.01171875 +31123 -0.056060791015625 +31124 -0.055511474609375 +31125 -0.010467529296875 +31126 0.02508544921875 +31127 0.025665283203125 +31128 0.017333984375 +31129 0.00189208984375 +31130 -0.03173828125 +31131 -0.071502685546875 +31132 -0.13543701171875 +31133 -0.219970703125 +31134 -0.300506591796875 +31135 -0.376312255859375 +31136 -0.416107177734375 +31137 -0.371124267578125 +31138 -0.242279052734375 +31139 -0.069732666015625 +31140 0.125640869140625 +31141 0.31268310546875 +31142 0.45501708984375 +31143 0.554779052734375 +31144 0.61065673828125 +31145 0.610931396484375 +31146 0.531463623046875 +31147 0.3883056640625 +31148 0.23468017578125 +31149 0.095245361328125 +31150 -0.00396728515625 +31151 -0.04852294921875 +31152 -0.055145263671875 +31153 -0.0758056640625 +31154 -0.138702392578125 +31155 -0.209197998046875 +31156 -0.289031982421875 +31157 -0.37884521484375 +31158 -0.456329345703125 +31159 -0.51641845703125 +31160 -0.519287109375 +31161 -0.458251953125 +31162 -0.384796142578125 +31163 -0.323699951171875 +31164 -0.269287109375 +31165 -0.1951904296875 +31166 -0.100006103515625 +31167 -0.01055908203125 +31168 0.1033935546875 +31169 0.24908447265625 +31170 0.373199462890625 +31171 0.45806884765625 +31172 0.511474609375 +31173 0.565399169921875 +31174 0.61138916015625 +31175 0.5897216796875 +31176 0.4906005859375 +31177 0.33148193359375 +31178 0.147796630859375 +31179 -0.01873779296875 +31180 -0.140289306640625 +31181 -0.191986083984375 +31182 -0.184295654296875 +31183 -0.161834716796875 +31184 -0.166595458984375 +31185 -0.19390869140625 +31186 -0.22442626953125 +31187 -0.279754638671875 +31188 -0.3389892578125 +31189 -0.3543701171875 +31190 -0.348175048828125 +31191 -0.32598876953125 +31192 -0.2581787109375 +31193 -0.139801025390625 +31194 0.014617919921875 +31195 0.144378662109375 +31196 0.221038818359375 +31197 0.27069091796875 +31198 0.294036865234375 +31199 0.311767578125 +31200 0.339141845703125 +31201 0.360260009765625 +31202 0.360504150390625 +31203 0.308380126953125 +31204 0.18170166015625 +31205 0.0047607421875 +31206 -0.17559814453125 +31207 -0.3143310546875 +31208 -0.36785888671875 +31209 -0.36248779296875 +31210 -0.343536376953125 +31211 -0.3018798828125 +31212 -0.231414794921875 +31213 -0.117645263671875 +31214 0.007049560546875 +31215 0.087982177734375 +31216 0.13946533203125 +31217 0.17425537109375 +31218 0.188201904296875 +31219 0.171234130859375 +31220 0.118438720703125 +31221 0.05706787109375 +31222 -0.010711669921875 +31223 -0.0914306640625 +31224 -0.162322998046875 +31225 -0.194549560546875 +31226 -0.1492919921875 +31227 -0.02166748046875 +31228 0.124053955078125 +31229 0.211151123046875 +31230 0.240447998046875 +31231 0.242218017578125 +31232 0.2257080078125 +31233 0.194366455078125 +31234 0.115509033203125 +31235 0.0128173828125 +31236 -0.053802490234375 +31237 -0.110626220703125 +31238 -0.199493408203125 +31239 -0.29437255859375 +31240 -0.33221435546875 +31241 -0.27972412109375 +31242 -0.185333251953125 +31243 -0.128204345703125 +31244 -0.115692138671875 +31245 -0.116455078125 +31246 -0.105926513671875 +31247 -0.053955078125 +31248 0.048797607421875 +31249 0.157318115234375 +31250 0.212005615234375 +31251 0.218475341796875 +31252 0.23724365234375 +31253 0.30535888671875 +31254 0.38128662109375 +31255 0.404449462890625 +31256 0.3944091796875 +31257 0.3885498046875 +31258 0.362640380859375 +31259 0.27362060546875 +31260 0.11712646484375 +31261 -0.054901123046875 +31262 -0.19085693359375 +31263 -0.28570556640625 +31264 -0.339263916015625 +31265 -0.3775634765625 +31266 -0.445709228515625 +31267 -0.535064697265625 +31268 -0.629058837890625 +31269 -0.697601318359375 +31270 -0.70391845703125 +31271 -0.6424560546875 +31272 -0.491241455078125 +31273 -0.265716552734375 +31274 -0.023712158203125 +31275 0.201751708984375 +31276 0.375823974609375 +31277 0.485076904296875 +31278 0.56884765625 +31279 0.634765625 +31280 0.63763427734375 +31281 0.5660400390625 +31282 0.4720458984375 +31283 0.40692138671875 +31284 0.3778076171875 +31285 0.376953125 +31286 0.371978759765625 +31287 0.313140869140625 +31288 0.184417724609375 +31289 0.011199951171875 +31290 -0.171051025390625 +31291 -0.33740234375 +31292 -0.47198486328125 +31293 -0.560394287109375 +31294 -0.58056640625 +31295 -0.54754638671875 +31296 -0.508575439453125 +31297 -0.459503173828125 +31298 -0.394378662109375 +31299 -0.35260009765625 +31300 -0.31170654296875 +31301 -0.197418212890625 +31302 -0.007965087890625 +31303 0.207489013671875 +31304 0.409210205078125 +31305 0.57208251953125 +31306 0.66595458984375 +31307 0.65875244140625 +31308 0.56744384765625 +31309 0.431396484375 +31310 0.29443359375 +31311 0.182464599609375 +31312 0.06365966796875 +31313 -0.075958251953125 +31314 -0.189422607421875 +31315 -0.271942138671875 +31316 -0.342529296875 +31317 -0.364166259765625 +31318 -0.327239990234375 +31319 -0.2769775390625 +31320 -0.253692626953125 +31321 -0.24365234375 +31322 -0.1983642578125 +31323 -0.116241455078125 +31324 -0.036834716796875 +31325 0.034881591796875 +31326 0.09124755859375 +31327 0.10888671875 +31328 0.125518798828125 +31329 0.15771484375 +31330 0.17828369140625 +31331 0.17108154296875 +31332 0.129974365234375 +31333 0.082427978515625 +31334 0.027679443359375 +31335 -0.065643310546875 +31336 -0.15936279296875 +31337 -0.21307373046875 +31338 -0.234649658203125 +31339 -0.2001953125 +31340 -0.119171142578125 +31341 -0.024749755859375 +31342 0.085784912109375 +31343 0.178131103515625 +31344 0.215576171875 +31345 0.211456298828125 +31346 0.17523193359375 +31347 0.128753662109375 +31348 0.1019287109375 +31349 0.0743408203125 +31350 0.04327392578125 +31351 0.038177490234375 +31352 0.076263427734375 +31353 0.14105224609375 +31354 0.186431884765625 +31355 0.188812255859375 +31356 0.1390380859375 +31357 0.041778564453125 +31358 -0.079437255859375 +31359 -0.219390869140625 +31360 -0.367828369140625 +31361 -0.494873046875 +31362 -0.556243896484375 +31363 -0.508697509765625 +31364 -0.3756103515625 +31365 -0.218902587890625 +31366 -0.063751220703125 +31367 0.091552734375 +31368 0.23602294921875 +31369 0.342987060546875 +31370 0.39520263671875 +31371 0.389373779296875 +31372 0.324249267578125 +31373 0.224090576171875 +31374 0.124267578125 +31375 0.037078857421875 +31376 -0.010101318359375 +31377 -0.019439697265625 +31378 -0.022796630859375 +31379 -0.001556396484375 +31380 0.056304931640625 +31381 0.106719970703125 +31382 0.096893310546875 +31383 0.042694091796875 +31384 -0.018035888671875 +31385 -0.07586669921875 +31386 -0.11944580078125 +31387 -0.15972900390625 +31388 -0.202606201171875 +31389 -0.24859619140625 +31390 -0.30517578125 +31391 -0.36212158203125 +31392 -0.39141845703125 +31393 -0.35528564453125 +31394 -0.249969482421875 +31395 -0.092864990234375 +31396 0.08905029296875 +31397 0.2352294921875 +31398 0.318817138671875 +31399 0.358642578125 +31400 0.347747802734375 +31401 0.28564453125 +31402 0.223175048828125 +31403 0.196746826171875 +31404 0.179840087890625 +31405 0.155548095703125 +31406 0.151214599609375 +31407 0.156951904296875 +31408 0.13177490234375 +31409 0.100799560546875 +31410 0.087127685546875 +31411 0.05487060546875 +31412 -0.009002685546875 +31413 -0.10400390625 +31414 -0.229400634765625 +31415 -0.35552978515625 +31416 -0.441925048828125 +31417 -0.473846435546875 +31418 -0.464813232421875 +31419 -0.419097900390625 +31420 -0.334320068359375 +31421 -0.227935791015625 +31422 -0.12347412109375 +31423 -0.02764892578125 +31424 0.077667236328125 +31425 0.2132568359375 +31426 0.38885498046875 +31427 0.582794189453125 +31428 0.734039306640625 +31429 0.800140380859375 +31430 0.7783203125 +31431 0.6651611328125 +31432 0.45965576171875 +31433 0.199188232421875 +31434 -0.050689697265625 +31435 -0.23297119140625 +31436 -0.33013916015625 +31437 -0.368408203125 +31438 -0.378936767578125 +31439 -0.376983642578125 +31440 -0.37969970703125 +31441 -0.391510009765625 +31442 -0.385345458984375 +31443 -0.3419189453125 +31444 -0.28289794921875 +31445 -0.251617431640625 +31446 -0.266143798828125 +31447 -0.273345947265625 +31448 -0.216796875 +31449 -0.128265380859375 +31450 -0.068145751953125 +31451 -0.0430908203125 +31452 -0.024444580078125 +31453 0.020721435546875 +31454 0.124481201171875 +31455 0.25787353515625 +31456 0.379119873046875 +31457 0.47991943359375 +31458 0.5281982421875 +31459 0.511138916015625 +31460 0.456207275390625 +31461 0.407470703125 +31462 0.383758544921875 +31463 0.35687255859375 +31464 0.31182861328125 +31465 0.250885009765625 +31466 0.1654052734375 +31467 0.035247802734375 +31468 -0.142059326171875 +31469 -0.33563232421875 +31470 -0.5345458984375 +31471 -0.72186279296875 +31472 -0.836669921875 +31473 -0.8326416015625 +31474 -0.7296142578125 +31475 -0.582550048828125 +31476 -0.440093994140625 +31477 -0.324310302734375 +31478 -0.20147705078125 +31479 -0.044647216796875 +31480 0.103973388671875 +31481 0.202392578125 +31482 0.264495849609375 +31483 0.338897705078125 +31484 0.443817138671875 +31485 0.545074462890625 +31486 0.6173095703125 +31487 0.6524658203125 +31488 0.66339111328125 +31489 0.6561279296875 +31490 0.606781005859375 +31491 0.501190185546875 +31492 0.352783203125 +31493 0.176544189453125 +31494 -0.034820556640625 +31495 -0.258209228515625 +31496 -0.44244384765625 +31497 -0.5753173828125 +31498 -0.65203857421875 +31499 -0.641632080078125 +31500 -0.562164306640625 +31501 -0.458038330078125 +31502 -0.350555419921875 +31503 -0.260528564453125 +31504 -0.192108154296875 +31505 -0.141937255859375 +31506 -0.1021728515625 +31507 -0.062896728515625 +31508 -0.011932373046875 +31509 0.062835693359375 +31510 0.148712158203125 +31511 0.241729736328125 +31512 0.34912109375 +31513 0.457305908203125 +31514 0.54388427734375 +31515 0.5728759765625 +31516 0.506591796875 +31517 0.351226806640625 +31518 0.146514892578125 +31519 -0.05523681640625 +31520 -0.21624755859375 +31521 -0.334930419921875 +31522 -0.402984619140625 +31523 -0.4412841796875 +31524 -0.49578857421875 +31525 -0.5601806640625 +31526 -0.600738525390625 +31527 -0.584228515625 +31528 -0.47930908203125 +31529 -0.27935791015625 +31530 -0.0089111328125 +31531 0.268798828125 +31532 0.482818603515625 +31533 0.60369873046875 +31534 0.650421142578125 +31535 0.66400146484375 +31536 0.6414794921875 +31537 0.572540283203125 +31538 0.498138427734375 +31539 0.439453125 +31540 0.375518798828125 +31541 0.274505615234375 +31542 0.1087646484375 +31543 -0.099395751953125 +31544 -0.3182373046875 +31545 -0.5489501953125 +31546 -0.7738037109375 +31547 -0.86383056640625 +31548 -0.870391845703125 +31549 -0.86895751953125 +31550 -0.861053466796875 +31551 -0.765869140625 +31552 -0.5301513671875 +31553 -0.214691162109375 +31554 0.137359619140625 +31555 0.474822998046875 +31556 0.76239013671875 +31557 0.867462158203125 +31558 0.870361328125 +31559 0.86480712890625 +31560 0.831817626953125 +31561 0.677581787109375 +31562 0.495880126953125 +31563 0.30767822265625 +31564 0.116180419921875 +31565 -0.110748291015625 +31566 -0.381805419921875 +31567 -0.6572265625 +31568 -0.857421875 +31569 -0.870391845703125 +31570 -0.870391845703125 +31571 -0.86444091796875 +31572 -0.85723876953125 +31573 -0.790008544921875 +31574 -0.62847900390625 +31575 -0.3956298828125 +31576 -0.126708984375 +31577 0.150115966796875 +31578 0.424041748046875 +31579 0.670623779296875 +31580 0.854522705078125 +31581 0.866485595703125 +31582 0.86920166015625 +31583 0.8653564453125 +31584 0.857147216796875 +31585 0.766845703125 +31586 0.628509521484375 +31587 0.462127685546875 +31588 0.297210693359375 +31589 0.14862060546875 +31590 -0.00537109375 +31591 -0.15753173828125 +31592 -0.31304931640625 +31593 -0.48876953125 +31594 -0.6416015625 +31595 -0.751373291015625 +31596 -0.84619140625 +31597 -0.861297607421875 +31598 -0.863250732421875 +31599 -0.856597900390625 +31600 -0.7498779296875 +31601 -0.624542236328125 +31602 -0.47808837890625 +31603 -0.253387451171875 +31604 0.003692626953125 +31605 0.2257080078125 +31606 0.427154541015625 +31607 0.643218994140625 +31608 0.855926513671875 +31609 0.870361328125 +31610 0.870361328125 +31611 0.862762451171875 +31612 0.79669189453125 +31613 0.595794677734375 +31614 0.362152099609375 +31615 0.1270751953125 +31616 -0.086944580078125 +31617 -0.2784423828125 +31618 -0.484832763671875 +31619 -0.729583740234375 +31620 -0.86688232421875 +31621 -0.870391845703125 +31622 -0.86859130859375 +31623 -0.86279296875 +31624 -0.817962646484375 +31625 -0.6116943359375 +31626 -0.3128662109375 +31627 0.039398193359375 +31628 0.422821044921875 +31629 0.805145263671875 +31630 0.870361328125 +31631 0.870361328125 +31632 0.860015869140625 +31633 0.727935791015625 +31634 0.48114013671875 +31635 0.2059326171875 +31636 -0.06103515625 +31637 -0.29913330078125 +31638 -0.516204833984375 +31639 -0.7252197265625 +31640 -0.85980224609375 +31641 -0.870391845703125 +31642 -0.870391845703125 +31643 -0.858062744140625 +31644 -0.673004150390625 +31645 -0.42694091796875 +31646 -0.2100830078125 +31647 -0.0362548828125 +31648 0.10943603515625 +31649 0.23516845703125 +31650 0.373687744140625 +31651 0.517791748046875 +31652 0.602783203125 +31653 0.635711669921875 +31654 0.655181884765625 +31655 0.65948486328125 +31656 0.651275634765625 +31657 0.61846923828125 +31658 0.53753662109375 +31659 0.404144287109375 +31660 0.22186279296875 +31661 0.003997802734375 +31662 -0.22100830078125 +31663 -0.42449951171875 +31664 -0.579833984375 +31665 -0.641876220703125 +31666 -0.6177978515625 +31667 -0.575531005859375 +31668 -0.526336669921875 +31669 -0.42645263671875 +31670 -0.2581787109375 +31671 -0.068695068359375 +31672 0.09222412109375 +31673 0.232147216796875 +31674 0.3509521484375 +31675 0.410064697265625 +31676 0.372955322265625 +31677 0.2554931640625 +31678 0.10711669921875 +31679 -0.052886962890625 +31680 -0.186279296875 +31681 -0.23291015625 +31682 -0.209442138671875 +31683 -0.174163818359375 +31684 -0.126739501953125 +31685 -0.048126220703125 +31686 0.0426025390625 +31687 0.10748291015625 +31688 0.1409912109375 +31689 0.19708251953125 +31690 0.273651123046875 +31691 0.31768798828125 +31692 0.341094970703125 +31693 0.368011474609375 +31694 0.37249755859375 +31695 0.30072021484375 +31696 0.1517333984375 +31697 -0.01470947265625 +31698 -0.1883544921875 +31699 -0.372711181640625 +31700 -0.51397705078125 +31701 -0.57177734375 +31702 -0.53948974609375 +31703 -0.43511962890625 +31704 -0.2962646484375 +31705 -0.161102294921875 +31706 -0.0435791015625 +31707 0.060394287109375 +31708 0.13665771484375 +31709 0.170135498046875 +31710 0.16552734375 +31711 0.15728759765625 +31712 0.150787353515625 +31713 0.12200927734375 +31714 0.080108642578125 +31715 0.05126953125 +31716 0.062896728515625 +31717 0.09271240234375 +31718 0.092987060546875 +31719 0.07855224609375 +31720 0.06427001953125 +31721 0.0347900390625 +31722 -0.01171875 +31723 -0.056060791015625 +31724 -0.055511474609375 +31725 -0.010467529296875 +31726 0.02508544921875 +31727 0.025665283203125 +31728 0.017333984375 +31729 0.00189208984375 +31730 -0.03173828125 +31731 -0.071502685546875 +31732 -0.13543701171875 +31733 -0.219970703125 +31734 -0.300506591796875 +31735 -0.376312255859375 +31736 -0.416107177734375 +31737 -0.371124267578125 +31738 -0.242279052734375 +31739 -0.069732666015625 +31740 0.125640869140625 +31741 0.31268310546875 +31742 0.45501708984375 +31743 0.554779052734375 +31744 0.61065673828125 +31745 0.610931396484375 +31746 0.531463623046875 +31747 0.3883056640625 +31748 0.23468017578125 +31749 0.095245361328125 +31750 -0.00396728515625 +31751 -0.04852294921875 +31752 -0.055145263671875 +31753 -0.0758056640625 +31754 -0.138702392578125 +31755 -0.209197998046875 +31756 -0.289031982421875 +31757 -0.37884521484375 +31758 -0.456329345703125 +31759 -0.51641845703125 +31760 -0.519287109375 +31761 -0.458251953125 +31762 -0.384796142578125 +31763 -0.323699951171875 +31764 -0.269287109375 +31765 -0.1951904296875 +31766 -0.100006103515625 +31767 -0.01055908203125 +31768 0.1033935546875 +31769 0.24908447265625 +31770 0.373199462890625 +31771 0.45806884765625 +31772 0.511474609375 +31773 0.565399169921875 +31774 0.61138916015625 +31775 0.5897216796875 +31776 0.4906005859375 +31777 0.33148193359375 +31778 0.147796630859375 +31779 -0.01873779296875 +31780 -0.140289306640625 +31781 -0.191986083984375 +31782 -0.184295654296875 +31783 -0.161834716796875 +31784 -0.166595458984375 +31785 -0.19390869140625 +31786 -0.22442626953125 +31787 -0.279754638671875 +31788 -0.3389892578125 +31789 -0.3543701171875 +31790 -0.348175048828125 +31791 -0.32598876953125 +31792 -0.2581787109375 +31793 -0.139801025390625 +31794 0.014617919921875 +31795 0.144378662109375 +31796 0.221038818359375 +31797 0.27069091796875 +31798 0.294036865234375 +31799 0.311767578125 +31800 0.339141845703125 +31801 0.360260009765625 +31802 0.360504150390625 +31803 0.308380126953125 +31804 0.18170166015625 +31805 0.0047607421875 +31806 -0.17559814453125 +31807 -0.3143310546875 +31808 -0.36785888671875 +31809 -0.36248779296875 +31810 -0.343536376953125 +31811 -0.3018798828125 +31812 -0.231414794921875 +31813 -0.117645263671875 +31814 0.007049560546875 +31815 0.087982177734375 +31816 0.13946533203125 +31817 0.17425537109375 +31818 0.188201904296875 +31819 0.171234130859375 +31820 0.118438720703125 +31821 0.05706787109375 +31822 -0.010711669921875 +31823 -0.0914306640625 +31824 -0.162322998046875 +31825 -0.194549560546875 +31826 -0.1492919921875 +31827 -0.02166748046875 +31828 0.124053955078125 +31829 0.211151123046875 +31830 0.240447998046875 +31831 0.242218017578125 +31832 0.2257080078125 +31833 0.194366455078125 +31834 0.115509033203125 +31835 0.0128173828125 +31836 -0.053802490234375 +31837 -0.110626220703125 +31838 -0.199493408203125 +31839 -0.29437255859375 +31840 -0.33221435546875 +31841 -0.27972412109375 +31842 -0.185333251953125 +31843 -0.128204345703125 +31844 -0.115692138671875 +31845 -0.116455078125 +31846 -0.105926513671875 +31847 -0.053955078125 +31848 0.048797607421875 +31849 0.157318115234375 +31850 0.212005615234375 +31851 0.218475341796875 +31852 0.23724365234375 +31853 0.30535888671875 +31854 0.38128662109375 +31855 0.404449462890625 +31856 0.3944091796875 +31857 0.3885498046875 +31858 0.362640380859375 +31859 0.27362060546875 +31860 0.11712646484375 +31861 -0.054901123046875 +31862 -0.19085693359375 +31863 -0.28570556640625 +31864 -0.339263916015625 +31865 -0.3775634765625 +31866 -0.445709228515625 +31867 -0.535064697265625 +31868 -0.629058837890625 +31869 -0.697601318359375 +31870 -0.70391845703125 +31871 -0.6424560546875 +31872 -0.491241455078125 +31873 -0.265716552734375 +31874 -0.023712158203125 +31875 0.201751708984375 +31876 0.375823974609375 +31877 0.485076904296875 +31878 0.56884765625 +31879 0.634765625 +31880 0.63763427734375 +31881 0.5660400390625 +31882 0.4720458984375 +31883 0.40692138671875 +31884 0.3778076171875 +31885 0.376953125 +31886 0.371978759765625 +31887 0.313140869140625 +31888 0.184417724609375 +31889 0.011199951171875 +31890 -0.171051025390625 +31891 -0.33740234375 +31892 -0.47198486328125 +31893 -0.560394287109375 +31894 -0.58056640625 +31895 -0.54754638671875 +31896 -0.508575439453125 +31897 -0.459503173828125 +31898 -0.394378662109375 +31899 -0.35260009765625 +31900 -0.31170654296875 +31901 -0.197418212890625 +31902 -0.007965087890625 +31903 0.207489013671875 +31904 0.409210205078125 +31905 0.57208251953125 +31906 0.66595458984375 +31907 0.65875244140625 +31908 0.56744384765625 +31909 0.431396484375 +31910 0.29443359375 +31911 0.182464599609375 +31912 0.06365966796875 +31913 -0.075958251953125 +31914 -0.189422607421875 +31915 -0.271942138671875 +31916 -0.342529296875 +31917 -0.364166259765625 +31918 -0.327239990234375 +31919 -0.2769775390625 +31920 -0.253692626953125 +31921 -0.24365234375 +31922 -0.1983642578125 +31923 -0.116241455078125 +31924 -0.036834716796875 +31925 0.034881591796875 +31926 0.09124755859375 +31927 0.10888671875 +31928 0.125518798828125 +31929 0.15771484375 +31930 0.17828369140625 +31931 0.17108154296875 +31932 0.129974365234375 +31933 0.082427978515625 +31934 0.027679443359375 +31935 -0.065643310546875 +31936 -0.15936279296875 +31937 -0.21307373046875 +31938 -0.234649658203125 +31939 -0.2001953125 +31940 -0.119171142578125 +31941 -0.024749755859375 +31942 0.085784912109375 +31943 0.178131103515625 +31944 0.215576171875 +31945 0.211456298828125 +31946 0.17523193359375 +31947 0.128753662109375 +31948 0.1019287109375 +31949 0.0743408203125 +31950 0.04327392578125 +31951 0.038177490234375 +31952 0.076263427734375 +31953 0.14105224609375 +31954 0.186431884765625 +31955 0.188812255859375 +31956 0.1390380859375 +31957 0.041778564453125 +31958 -0.079437255859375 +31959 -0.219390869140625 +31960 -0.367828369140625 +31961 -0.494873046875 +31962 -0.556243896484375 +31963 -0.508697509765625 +31964 -0.3756103515625 +31965 -0.218902587890625 +31966 -0.063751220703125 +31967 0.091552734375 +31968 0.23602294921875 +31969 0.342987060546875 +31970 0.39520263671875 +31971 0.389373779296875 +31972 0.324249267578125 +31973 0.224090576171875 +31974 0.124267578125 +31975 0.037078857421875 +31976 -0.010101318359375 +31977 -0.019439697265625 +31978 -0.022796630859375 +31979 -0.001556396484375 +31980 0.056304931640625 +31981 0.106719970703125 +31982 0.096893310546875 +31983 0.042694091796875 +31984 -0.018035888671875 +31985 -0.07586669921875 +31986 -0.11944580078125 +31987 -0.15972900390625 +31988 -0.202606201171875 +31989 -0.24859619140625 +31990 -0.30517578125 +31991 -0.36212158203125 +31992 -0.39141845703125 +31993 -0.35528564453125 +31994 -0.249969482421875 +31995 -0.092864990234375 +31996 0.08905029296875 +31997 0.2352294921875 +31998 0.318817138671875 +31999 0.358642578125 +32000 0.347747802734375 +32001 0.28564453125 +32002 0.223175048828125 +32003 0.196746826171875 +32004 0.179840087890625 +32005 0.155548095703125 +32006 0.151214599609375 +32007 0.156951904296875 +32008 0.13177490234375 +32009 0.100799560546875 +32010 0.087127685546875 +32011 0.05487060546875 +32012 -0.009002685546875 +32013 -0.10400390625 +32014 -0.229400634765625 +32015 -0.35552978515625 +32016 -0.441925048828125 +32017 -0.473846435546875 +32018 -0.464813232421875 +32019 -0.419097900390625 +32020 -0.334320068359375 +32021 -0.227935791015625 +32022 -0.12347412109375 +32023 -0.02764892578125 +32024 0.077667236328125 +32025 0.2132568359375 +32026 0.38885498046875 +32027 0.582794189453125 +32028 0.734039306640625 +32029 0.800140380859375 +32030 0.7783203125 +32031 0.6651611328125 +32032 0.45965576171875 +32033 0.199188232421875 +32034 -0.050689697265625 +32035 -0.23297119140625 +32036 -0.33013916015625 +32037 -0.368408203125 +32038 -0.378936767578125 +32039 -0.376983642578125 +32040 -0.37969970703125 +32041 -0.391510009765625 +32042 -0.385345458984375 +32043 -0.3419189453125 +32044 -0.28289794921875 +32045 -0.251617431640625 +32046 -0.266143798828125 +32047 -0.273345947265625 +32048 -0.216796875 +32049 -0.128265380859375 +32050 -0.068145751953125 +32051 -0.0430908203125 +32052 -0.024444580078125 +32053 0.020721435546875 +32054 0.124481201171875 +32055 0.25787353515625 +32056 0.379119873046875 +32057 0.47991943359375 +32058 0.5281982421875 +32059 0.511138916015625 +32060 0.456207275390625 +32061 0.407470703125 +32062 0.383758544921875 +32063 0.35687255859375 +32064 0.31182861328125 +32065 0.250885009765625 +32066 0.1654052734375 +32067 0.035247802734375 +32068 -0.142059326171875 +32069 -0.33563232421875 +32070 -0.5345458984375 +32071 -0.72186279296875 +32072 -0.836669921875 +32073 -0.8326416015625 +32074 -0.7296142578125 +32075 -0.582550048828125 +32076 -0.440093994140625 +32077 -0.324310302734375 +32078 -0.20147705078125 +32079 -0.044647216796875 +32080 0.103973388671875 +32081 0.202392578125 +32082 0.264495849609375 +32083 0.338897705078125 +32084 0.443817138671875 +32085 0.545074462890625 +32086 0.6173095703125 +32087 0.6524658203125 +32088 0.66339111328125 +32089 0.6561279296875 +32090 0.606781005859375 +32091 0.501190185546875 +32092 0.352783203125 +32093 0.176544189453125 +32094 -0.034820556640625 +32095 -0.258209228515625 +32096 -0.44244384765625 +32097 -0.5753173828125 +32098 -0.65203857421875 +32099 -0.641632080078125 +32100 -0.562164306640625 +32101 -0.458038330078125 +32102 -0.350555419921875 +32103 -0.260528564453125 +32104 -0.192108154296875 +32105 -0.141937255859375 +32106 -0.1021728515625 +32107 -0.062896728515625 +32108 -0.011932373046875 +32109 0.062835693359375 +32110 0.148712158203125 +32111 0.241729736328125 +32112 0.34912109375 +32113 0.457305908203125 +32114 0.54388427734375 +32115 0.5728759765625 +32116 0.506591796875 +32117 0.351226806640625 +32118 0.146514892578125 +32119 -0.05523681640625 +32120 -0.21624755859375 +32121 -0.334930419921875 +32122 -0.402984619140625 +32123 -0.4412841796875 +32124 -0.49578857421875 +32125 -0.5601806640625 +32126 -0.600738525390625 +32127 -0.584228515625 +32128 -0.47930908203125 +32129 -0.27935791015625 +32130 -0.0089111328125 +32131 0.268798828125 +32132 0.482818603515625 +32133 0.60369873046875 +32134 0.650421142578125 +32135 0.66400146484375 +32136 0.6414794921875 +32137 0.572540283203125 +32138 0.498138427734375 +32139 0.439453125 +32140 0.375518798828125 +32141 0.274505615234375 +32142 0.1087646484375 +32143 -0.099395751953125 +32144 -0.3182373046875 +32145 -0.5489501953125 +32146 -0.7738037109375 +32147 -0.86383056640625 +32148 -0.870391845703125 +32149 -0.86895751953125 +32150 -0.861053466796875 +32151 -0.765869140625 +32152 -0.5301513671875 +32153 -0.214691162109375 +32154 0.137359619140625 +32155 0.474822998046875 +32156 0.76239013671875 +32157 0.867462158203125 +32158 0.870361328125 +32159 0.86480712890625 +32160 0.831817626953125 +32161 0.677581787109375 +32162 0.495880126953125 +32163 0.30767822265625 +32164 0.116180419921875 +32165 -0.110748291015625 +32166 -0.381805419921875 +32167 -0.6572265625 +32168 -0.857421875 +32169 -0.870391845703125 +32170 -0.870391845703125 +32171 -0.86444091796875 +32172 -0.85723876953125 +32173 -0.790008544921875 +32174 -0.62847900390625 +32175 -0.3956298828125 +32176 -0.126708984375 +32177 0.150115966796875 +32178 0.424041748046875 +32179 0.670623779296875 +32180 0.854522705078125 +32181 0.866485595703125 +32182 0.86920166015625 +32183 0.8653564453125 +32184 0.857147216796875 +32185 0.766845703125 +32186 0.628509521484375 +32187 0.462127685546875 +32188 0.297210693359375 +32189 0.14862060546875 +32190 -0.00537109375 +32191 -0.15753173828125 +32192 -0.31304931640625 +32193 -0.48876953125 +32194 -0.6416015625 +32195 -0.751373291015625 +32196 -0.84619140625 +32197 -0.861297607421875 +32198 -0.863250732421875 +32199 -0.856597900390625 +32200 -0.7498779296875 +32201 -0.624542236328125 +32202 -0.47808837890625 +32203 -0.253387451171875 +32204 0.003692626953125 +32205 0.2257080078125 +32206 0.427154541015625 +32207 0.643218994140625 +32208 0.855926513671875 +32209 0.870361328125 +32210 0.870361328125 +32211 0.862762451171875 +32212 0.79669189453125 +32213 0.595794677734375 +32214 0.362152099609375 +32215 0.1270751953125 +32216 -0.086944580078125 +32217 -0.2784423828125 +32218 -0.484832763671875 +32219 -0.729583740234375 +32220 -0.86688232421875 +32221 -0.870391845703125 +32222 -0.86859130859375 +32223 -0.86279296875 +32224 -0.817962646484375 +32225 -0.6116943359375 +32226 -0.3128662109375 +32227 0.039398193359375 +32228 0.422821044921875 +32229 0.805145263671875 +32230 0.870361328125 +32231 0.870361328125 +32232 0.860015869140625 +32233 0.727935791015625 +32234 0.48114013671875 +32235 0.2059326171875 +32236 -0.06103515625 +32237 -0.29913330078125 +32238 -0.516204833984375 +32239 -0.7252197265625 +32240 -0.85980224609375 +32241 -0.870391845703125 +32242 -0.870391845703125 +32243 -0.858062744140625 +32244 -0.673004150390625 +32245 -0.42694091796875 +32246 -0.2100830078125 +32247 -0.0362548828125 +32248 0.10943603515625 +32249 0.23516845703125 +32250 0.373687744140625 +32251 0.517791748046875 +32252 0.602783203125 +32253 0.635711669921875 +32254 0.655181884765625 +32255 0.65948486328125 +32256 0.651275634765625 +32257 0.61846923828125 +32258 0.53753662109375 +32259 0.404144287109375 +32260 0.22186279296875 +32261 0.003997802734375 +32262 -0.22100830078125 +32263 -0.42449951171875 +32264 -0.579833984375 +32265 -0.641876220703125 +32266 -0.6177978515625 +32267 -0.575531005859375 +32268 -0.526336669921875 +32269 -0.42645263671875 +32270 -0.2581787109375 +32271 -0.068695068359375 +32272 0.09222412109375 +32273 0.232147216796875 +32274 0.3509521484375 +32275 0.410064697265625 +32276 0.372955322265625 +32277 0.2554931640625 +32278 0.10711669921875 +32279 -0.052886962890625 +32280 -0.186279296875 +32281 -0.23291015625 +32282 -0.209442138671875 +32283 -0.174163818359375 +32284 -0.126739501953125 +32285 -0.048126220703125 +32286 0.0426025390625 +32287 0.10748291015625 +32288 0.1409912109375 +32289 0.19708251953125 +32290 0.273651123046875 +32291 0.31768798828125 +32292 0.341094970703125 +32293 0.368011474609375 +32294 0.37249755859375 +32295 0.30072021484375 +32296 0.1517333984375 +32297 -0.01470947265625 +32298 -0.1883544921875 +32299 -0.372711181640625 +32300 -0.51397705078125 +32301 -0.57177734375 +32302 -0.53948974609375 +32303 -0.43511962890625 +32304 -0.2962646484375 +32305 -0.161102294921875 +32306 -0.0435791015625 +32307 0.060394287109375 +32308 0.13665771484375 +32309 0.170135498046875 +32310 0.16552734375 +32311 0.15728759765625 +32312 0.150787353515625 +32313 0.12200927734375 +32314 0.080108642578125 +32315 0.05126953125 +32316 0.062896728515625 +32317 0.09271240234375 +32318 0.092987060546875 +32319 0.07855224609375 +32320 0.06427001953125 +32321 0.0347900390625 +32322 -0.01171875 +32323 -0.056060791015625 +32324 -0.055511474609375 +32325 -0.010467529296875 +32326 0.02508544921875 +32327 0.025665283203125 +32328 0.017333984375 +32329 0.00189208984375 +32330 -0.03173828125 +32331 -0.071502685546875 +32332 -0.13543701171875 +32333 -0.219970703125 +32334 -0.300506591796875 +32335 -0.376312255859375 +32336 -0.416107177734375 +32337 -0.371124267578125 +32338 -0.242279052734375 +32339 -0.069732666015625 +32340 0.125640869140625 +32341 0.31268310546875 +32342 0.45501708984375 +32343 0.554779052734375 +32344 0.61065673828125 +32345 0.610931396484375 +32346 0.531463623046875 +32347 0.3883056640625 +32348 0.23468017578125 +32349 0.095245361328125 +32350 -0.00396728515625 +32351 -0.04852294921875 +32352 -0.055145263671875 +32353 -0.0758056640625 +32354 -0.138702392578125 +32355 -0.209197998046875 +32356 -0.289031982421875 +32357 -0.37884521484375 +32358 -0.456329345703125 +32359 -0.51641845703125 +32360 -0.519287109375 +32361 -0.458251953125 +32362 -0.384796142578125 +32363 -0.323699951171875 +32364 -0.269287109375 +32365 -0.1951904296875 +32366 -0.100006103515625 +32367 -0.01055908203125 +32368 0.1033935546875 +32369 0.24908447265625 +32370 0.373199462890625 +32371 0.45806884765625 +32372 0.511474609375 +32373 0.565399169921875 +32374 0.61138916015625 +32375 0.5897216796875 +32376 0.4906005859375 +32377 0.33148193359375 +32378 0.147796630859375 +32379 -0.01873779296875 +32380 -0.140289306640625 +32381 -0.191986083984375 +32382 -0.184295654296875 +32383 -0.161834716796875 +32384 -0.166595458984375 +32385 -0.19390869140625 +32386 -0.22442626953125 +32387 -0.279754638671875 +32388 -0.3389892578125 +32389 -0.3543701171875 +32390 -0.348175048828125 +32391 -0.32598876953125 +32392 -0.2581787109375 +32393 -0.139801025390625 +32394 0.014617919921875 +32395 0.144378662109375 +32396 0.221038818359375 +32397 0.27069091796875 +32398 0.294036865234375 +32399 0.311767578125 +32400 0.339141845703125 +32401 0.360260009765625 +32402 0.360504150390625 +32403 0.308380126953125 +32404 0.18170166015625 +32405 0.0047607421875 +32406 -0.17559814453125 +32407 -0.3143310546875 +32408 -0.36785888671875 +32409 -0.36248779296875 +32410 -0.343536376953125 +32411 -0.3018798828125 +32412 -0.231414794921875 +32413 -0.117645263671875 +32414 0.007049560546875 +32415 0.087982177734375 +32416 0.13946533203125 +32417 0.17425537109375 +32418 0.188201904296875 +32419 0.171234130859375 +32420 0.118438720703125 +32421 0.05706787109375 +32422 -0.010711669921875 +32423 -0.0914306640625 +32424 -0.162322998046875 +32425 -0.194549560546875 +32426 -0.1492919921875 +32427 -0.02166748046875 +32428 0.124053955078125 +32429 0.211151123046875 +32430 0.240447998046875 +32431 0.242218017578125 +32432 0.2257080078125 +32433 0.194366455078125 +32434 0.115509033203125 +32435 0.0128173828125 +32436 -0.053802490234375 +32437 -0.110626220703125 +32438 -0.199493408203125 +32439 -0.29437255859375 +32440 -0.33221435546875 +32441 -0.27972412109375 +32442 -0.185333251953125 +32443 -0.128204345703125 +32444 -0.115692138671875 +32445 -0.116455078125 +32446 -0.105926513671875 +32447 -0.053955078125 +32448 0.048797607421875 +32449 0.157318115234375 +32450 0.212005615234375 +32451 0.218475341796875 +32452 0.23724365234375 +32453 0.30535888671875 +32454 0.38128662109375 +32455 0.404449462890625 +32456 0.3944091796875 +32457 0.3885498046875 +32458 0.362640380859375 +32459 0.27362060546875 +32460 0.11712646484375 +32461 -0.054901123046875 +32462 -0.19085693359375 +32463 -0.28570556640625 +32464 -0.339263916015625 +32465 -0.3775634765625 +32466 -0.445709228515625 +32467 -0.535064697265625 +32468 -0.629058837890625 +32469 -0.697601318359375 +32470 -0.70391845703125 +32471 -0.6424560546875 +32472 -0.491241455078125 +32473 -0.265716552734375 +32474 -0.023712158203125 +32475 0.201751708984375 +32476 0.375823974609375 +32477 0.485076904296875 +32478 0.56884765625 +32479 0.634765625 +32480 0.63763427734375 +32481 0.5660400390625 +32482 0.4720458984375 +32483 0.40692138671875 +32484 0.3778076171875 +32485 0.376953125 +32486 0.371978759765625 +32487 0.313140869140625 +32488 0.184417724609375 +32489 0.011199951171875 +32490 -0.171051025390625 +32491 -0.33740234375 +32492 -0.47198486328125 +32493 -0.560394287109375 +32494 -0.58056640625 +32495 -0.54754638671875 +32496 -0.508575439453125 +32497 -0.459503173828125 +32498 -0.394378662109375 +32499 -0.35260009765625 +32500 -0.31170654296875 +32501 -0.197418212890625 +32502 -0.007965087890625 +32503 0.207489013671875 +32504 0.409210205078125 +32505 0.57208251953125 +32506 0.66595458984375 +32507 0.65875244140625 +32508 0.56744384765625 +32509 0.431396484375 +32510 0.29443359375 +32511 0.182464599609375 +32512 0.06365966796875 +32513 -0.075958251953125 +32514 -0.189422607421875 +32515 -0.271942138671875 +32516 -0.342529296875 +32517 -0.364166259765625 +32518 -0.327239990234375 +32519 -0.2769775390625 +32520 -0.253692626953125 +32521 -0.24365234375 +32522 -0.1983642578125 +32523 -0.116241455078125 +32524 -0.036834716796875 +32525 0.034881591796875 +32526 0.09124755859375 +32527 0.10888671875 +32528 0.125518798828125 +32529 0.15771484375 +32530 0.17828369140625 +32531 0.17108154296875 +32532 0.129974365234375 +32533 0.082427978515625 +32534 0.027679443359375 +32535 -0.065643310546875 +32536 -0.15936279296875 +32537 -0.21307373046875 +32538 -0.234649658203125 +32539 -0.2001953125 +32540 -0.119171142578125 +32541 -0.024749755859375 +32542 0.085784912109375 +32543 0.178131103515625 +32544 0.215576171875 +32545 0.211456298828125 +32546 0.17523193359375 +32547 0.128753662109375 +32548 0.1019287109375 +32549 0.0743408203125 +32550 0.04327392578125 +32551 0.038177490234375 +32552 0.076263427734375 +32553 0.14105224609375 +32554 0.186431884765625 +32555 0.188812255859375 +32556 0.1390380859375 +32557 0.041778564453125 +32558 -0.079437255859375 +32559 -0.219390869140625 +32560 -0.367828369140625 +32561 -0.494873046875 +32562 -0.556243896484375 +32563 -0.508697509765625 +32564 -0.3756103515625 +32565 -0.218902587890625 +32566 -0.063751220703125 +32567 0.091552734375 +32568 0.23602294921875 +32569 0.342987060546875 +32570 0.39520263671875 +32571 0.389373779296875 +32572 0.324249267578125 +32573 0.224090576171875 +32574 0.124267578125 +32575 0.037078857421875 +32576 -0.010101318359375 +32577 -0.019439697265625 +32578 -0.022796630859375 +32579 -0.001556396484375 +32580 0.056304931640625 +32581 0.106719970703125 +32582 0.096893310546875 +32583 0.042694091796875 +32584 -0.018035888671875 +32585 -0.07586669921875 +32586 -0.11944580078125 +32587 -0.15972900390625 +32588 -0.202606201171875 +32589 -0.24859619140625 +32590 -0.30517578125 +32591 -0.36212158203125 +32592 -0.39141845703125 +32593 -0.35528564453125 +32594 -0.249969482421875 +32595 -0.092864990234375 +32596 0.08905029296875 +32597 0.2352294921875 +32598 0.318817138671875 +32599 0.358642578125 +32600 0.347747802734375 +32601 0.28564453125 +32602 0.223175048828125 +32603 0.196746826171875 +32604 0.179840087890625 +32605 0.155548095703125 +32606 0.151214599609375 +32607 0.156951904296875 +32608 0.13177490234375 +32609 0.100799560546875 +32610 0.087127685546875 +32611 0.05487060546875 +32612 -0.009002685546875 +32613 -0.10400390625 +32614 -0.229400634765625 +32615 -0.35552978515625 +32616 -0.441925048828125 +32617 -0.473846435546875 +32618 -0.464813232421875 +32619 -0.419097900390625 +32620 -0.334320068359375 +32621 -0.227935791015625 +32622 -0.12347412109375 +32623 -0.02764892578125 +32624 0.077667236328125 +32625 0.2132568359375 +32626 0.38885498046875 +32627 0.582794189453125 +32628 0.734039306640625 +32629 0.800140380859375 +32630 0.7783203125 +32631 0.6651611328125 +32632 0.45965576171875 +32633 0.199188232421875 +32634 -0.050689697265625 +32635 -0.23297119140625 +32636 -0.33013916015625 +32637 -0.368408203125 +32638 -0.378936767578125 +32639 -0.376983642578125 +32640 -0.37969970703125 +32641 -0.391510009765625 +32642 -0.385345458984375 +32643 -0.3419189453125 +32644 -0.28289794921875 +32645 -0.251617431640625 +32646 -0.266143798828125 +32647 -0.273345947265625 +32648 -0.216796875 +32649 -0.128265380859375 +32650 -0.068145751953125 +32651 -0.0430908203125 +32652 -0.024444580078125 +32653 0.020721435546875 +32654 0.124481201171875 +32655 0.25787353515625 +32656 0.379119873046875 +32657 0.47991943359375 +32658 0.5281982421875 +32659 0.511138916015625 +32660 0.456207275390625 +32661 0.407470703125 +32662 0.383758544921875 +32663 0.35687255859375 +32664 0.31182861328125 +32665 0.250885009765625 +32666 0.1654052734375 +32667 0.035247802734375 +32668 -0.142059326171875 +32669 -0.33563232421875 +32670 -0.5345458984375 +32671 -0.72186279296875 +32672 -0.836669921875 +32673 -0.8326416015625 +32674 -0.7296142578125 +32675 -0.582550048828125 +32676 -0.440093994140625 +32677 -0.324310302734375 +32678 -0.20147705078125 +32679 -0.044647216796875 +32680 0.103973388671875 +32681 0.202392578125 +32682 0.264495849609375 +32683 0.338897705078125 +32684 0.443817138671875 +32685 0.545074462890625 +32686 0.6173095703125 +32687 0.6524658203125 +32688 0.66339111328125 +32689 0.6561279296875 +32690 0.606781005859375 +32691 0.501190185546875 +32692 0.352783203125 +32693 0.176544189453125 +32694 -0.034820556640625 +32695 -0.258209228515625 +32696 -0.44244384765625 +32697 -0.5753173828125 +32698 -0.65203857421875 +32699 -0.641632080078125 +32700 -0.562164306640625 +32701 -0.458038330078125 +32702 -0.350555419921875 +32703 -0.260528564453125 +32704 -0.192108154296875 +32705 -0.141937255859375 +32706 -0.1021728515625 +32707 -0.062896728515625 +32708 -0.011932373046875 +32709 0.062835693359375 +32710 0.148712158203125 +32711 0.241729736328125 +32712 0.34912109375 +32713 0.457305908203125 +32714 0.54388427734375 +32715 0.5728759765625 +32716 0.506591796875 +32717 0.351226806640625 +32718 0.146514892578125 +32719 -0.05523681640625 +32720 -0.21624755859375 +32721 -0.334930419921875 +32722 -0.402984619140625 +32723 -0.4412841796875 +32724 -0.49578857421875 +32725 -0.5601806640625 +32726 -0.600738525390625 +32727 -0.584228515625 +32728 -0.47930908203125 +32729 -0.27935791015625 +32730 -0.0089111328125 +32731 0.268798828125 +32732 0.482818603515625 +32733 0.60369873046875 +32734 0.650421142578125 +32735 0.66400146484375 +32736 0.6414794921875 +32737 0.572540283203125 +32738 0.498138427734375 +32739 0.439453125 +32740 0.375518798828125 +32741 0.274505615234375 +32742 0.1087646484375 +32743 -0.099395751953125 +32744 -0.3182373046875 +32745 -0.5489501953125 +32746 -0.7738037109375 +32747 -0.86383056640625 +32748 -0.870391845703125 +32749 -0.86895751953125 +32750 -0.861053466796875 +32751 -0.765869140625 +32752 -0.5301513671875 +32753 -0.214691162109375 +32754 0.137359619140625 +32755 0.474822998046875 +32756 0.76239013671875 +32757 0.867462158203125 +32758 0.870361328125 +32759 0.86480712890625 +32760 0.831817626953125 +32761 0.677581787109375 +32762 0.495880126953125 +32763 0.30767822265625 +32764 0.116180419921875 +32765 -0.110748291015625 +32766 -0.381805419921875 +32767 -0.6572265625 +32768 -0.857421875 +32769 -0.870391845703125 +32770 -0.870391845703125 +32771 -0.86444091796875 +32772 -0.85723876953125 +32773 -0.790008544921875 +32774 -0.62847900390625 +32775 -0.3956298828125 +32776 -0.126708984375 +32777 0.150115966796875 +32778 0.424041748046875 +32779 0.670623779296875 +32780 0.854522705078125 +32781 0.866485595703125 +32782 0.86920166015625 +32783 0.8653564453125 +32784 0.857147216796875 +32785 0.766845703125 +32786 0.628509521484375 +32787 0.462127685546875 +32788 0.297210693359375 +32789 0.14862060546875 +32790 -0.00537109375 +32791 -0.15753173828125 +32792 -0.31304931640625 +32793 -0.48876953125 +32794 -0.6416015625 +32795 -0.751373291015625 +32796 -0.84619140625 +32797 -0.861297607421875 +32798 -0.863250732421875 +32799 -0.856597900390625 +32800 -0.7498779296875 +32801 -0.624542236328125 +32802 -0.47808837890625 +32803 -0.253387451171875 +32804 0.003692626953125 +32805 0.2257080078125 +32806 0.427154541015625 +32807 0.643218994140625 +32808 0.855926513671875 +32809 0.870361328125 +32810 0.870361328125 +32811 0.862762451171875 +32812 0.79669189453125 +32813 0.595794677734375 +32814 0.362152099609375 +32815 0.1270751953125 +32816 -0.086944580078125 +32817 -0.2784423828125 +32818 -0.484832763671875 +32819 -0.729583740234375 +32820 -0.86688232421875 +32821 -0.870391845703125 +32822 -0.86859130859375 +32823 -0.86279296875 +32824 -0.817962646484375 +32825 -0.6116943359375 +32826 -0.3128662109375 +32827 0.039398193359375 +32828 0.422821044921875 +32829 0.805145263671875 +32830 0.870361328125 +32831 0.870361328125 +32832 0.860015869140625 +32833 0.727935791015625 +32834 0.48114013671875 +32835 0.2059326171875 +32836 -0.06103515625 +32837 -0.29913330078125 +32838 -0.516204833984375 +32839 -0.7252197265625 +32840 -0.85980224609375 +32841 -0.870391845703125 +32842 -0.870391845703125 +32843 -0.858062744140625 +32844 -0.673004150390625 +32845 -0.42694091796875 +32846 -0.2100830078125 +32847 -0.0362548828125 +32848 0.10943603515625 +32849 0.23516845703125 +32850 0.373687744140625 +32851 0.517791748046875 +32852 0.602783203125 +32853 0.635711669921875 +32854 0.655181884765625 +32855 0.65948486328125 +32856 0.651275634765625 +32857 0.61846923828125 +32858 0.53753662109375 +32859 0.404144287109375 +32860 0.22186279296875 +32861 0.003997802734375 +32862 -0.22100830078125 +32863 -0.42449951171875 +32864 -0.579833984375 +32865 -0.641876220703125 +32866 -0.6177978515625 +32867 -0.575531005859375 +32868 -0.526336669921875 +32869 -0.42645263671875 +32870 -0.2581787109375 +32871 -0.068695068359375 +32872 0.09222412109375 +32873 0.232147216796875 +32874 0.3509521484375 +32875 0.410064697265625 +32876 0.372955322265625 +32877 0.2554931640625 +32878 0.10711669921875 +32879 -0.052886962890625 +32880 -0.186279296875 +32881 -0.23291015625 +32882 -0.209442138671875 +32883 -0.174163818359375 +32884 -0.126739501953125 +32885 -0.048126220703125 +32886 0.0426025390625 +32887 0.10748291015625 +32888 0.1409912109375 +32889 0.19708251953125 +32890 0.273651123046875 +32891 0.31768798828125 +32892 0.341094970703125 +32893 0.368011474609375 +32894 0.37249755859375 +32895 0.30072021484375 +32896 0.1517333984375 +32897 -0.01470947265625 +32898 -0.1883544921875 +32899 -0.372711181640625 +32900 -0.51397705078125 +32901 -0.57177734375 +32902 -0.53948974609375 +32903 -0.43511962890625 +32904 -0.2962646484375 +32905 -0.161102294921875 +32906 -0.0435791015625 +32907 0.060394287109375 +32908 0.13665771484375 +32909 0.170135498046875 +32910 0.16552734375 +32911 0.15728759765625 +32912 0.150787353515625 +32913 0.12200927734375 +32914 0.080108642578125 +32915 0.05126953125 +32916 0.062896728515625 +32917 0.09271240234375 +32918 0.092987060546875 +32919 0.07855224609375 +32920 0.06427001953125 +32921 0.0347900390625 +32922 -0.01171875 +32923 -0.056060791015625 +32924 -0.055511474609375 +32925 -0.010467529296875 +32926 0.02508544921875 +32927 0.025665283203125 +32928 0.017333984375 +32929 0.00189208984375 +32930 -0.03173828125 +32931 -0.071502685546875 +32932 -0.13543701171875 +32933 -0.219970703125 +32934 -0.300506591796875 +32935 -0.376312255859375 +32936 -0.416107177734375 +32937 -0.371124267578125 +32938 -0.242279052734375 +32939 -0.069732666015625 +32940 0.125640869140625 +32941 0.31268310546875 +32942 0.45501708984375 +32943 0.554779052734375 +32944 0.61065673828125 +32945 0.610931396484375 +32946 0.531463623046875 +32947 0.3883056640625 +32948 0.23468017578125 +32949 0.095245361328125 +32950 -0.00396728515625 +32951 -0.04852294921875 +32952 -0.055145263671875 +32953 -0.0758056640625 +32954 -0.138702392578125 +32955 -0.209197998046875 +32956 -0.289031982421875 +32957 -0.37884521484375 +32958 -0.456329345703125 +32959 -0.51641845703125 +32960 -0.519287109375 +32961 -0.458251953125 +32962 -0.384796142578125 +32963 -0.323699951171875 +32964 -0.269287109375 +32965 -0.1951904296875 +32966 -0.100006103515625 +32967 -0.01055908203125 +32968 0.1033935546875 +32969 0.24908447265625 +32970 0.373199462890625 +32971 0.45806884765625 +32972 0.511474609375 +32973 0.565399169921875 +32974 0.61138916015625 +32975 0.5897216796875 +32976 0.4906005859375 +32977 0.33148193359375 +32978 0.147796630859375 +32979 -0.01873779296875 +32980 -0.140289306640625 +32981 -0.191986083984375 +32982 -0.184295654296875 +32983 -0.161834716796875 +32984 -0.166595458984375 +32985 -0.19390869140625 +32986 -0.22442626953125 +32987 -0.279754638671875 +32988 -0.3389892578125 +32989 -0.3543701171875 +32990 -0.348175048828125 +32991 -0.32598876953125 +32992 -0.2581787109375 +32993 -0.139801025390625 +32994 0.014617919921875 +32995 0.144378662109375 +32996 0.221038818359375 +32997 0.27069091796875 +32998 0.294036865234375 +32999 0.311767578125 +33000 0.339141845703125 +33001 0.360260009765625 +33002 0.360504150390625 +33003 0.308380126953125 +33004 0.18170166015625 +33005 0.0047607421875 +33006 -0.17559814453125 +33007 -0.3143310546875 +33008 -0.36785888671875 +33009 -0.36248779296875 +33010 -0.343536376953125 +33011 -0.3018798828125 +33012 -0.231414794921875 +33013 -0.117645263671875 +33014 0.007049560546875 +33015 0.087982177734375 +33016 0.13946533203125 +33017 0.17425537109375 +33018 0.188201904296875 +33019 0.171234130859375 +33020 0.118438720703125 +33021 0.05706787109375 +33022 -0.010711669921875 +33023 -0.0914306640625 +33024 -0.162322998046875 +33025 -0.194549560546875 +33026 -0.1492919921875 +33027 -0.02166748046875 +33028 0.124053955078125 +33029 0.211151123046875 +33030 0.240447998046875 +33031 0.242218017578125 +33032 0.2257080078125 +33033 0.194366455078125 +33034 0.115509033203125 +33035 0.0128173828125 +33036 -0.053802490234375 +33037 -0.110626220703125 +33038 -0.199493408203125 +33039 -0.29437255859375 +33040 -0.33221435546875 +33041 -0.27972412109375 +33042 -0.185333251953125 +33043 -0.128204345703125 +33044 -0.115692138671875 +33045 -0.116455078125 +33046 -0.105926513671875 +33047 -0.053955078125 +33048 0.048797607421875 +33049 0.157318115234375 +33050 0.212005615234375 +33051 0.218475341796875 +33052 0.23724365234375 +33053 0.30535888671875 +33054 0.38128662109375 +33055 0.404449462890625 +33056 0.3944091796875 +33057 0.3885498046875 +33058 0.362640380859375 +33059 0.27362060546875 +33060 0.11712646484375 +33061 -0.054901123046875 +33062 -0.19085693359375 +33063 -0.28570556640625 +33064 -0.339263916015625 +33065 -0.3775634765625 +33066 -0.445709228515625 +33067 -0.535064697265625 +33068 -0.629058837890625 +33069 -0.697601318359375 +33070 -0.70391845703125 +33071 -0.6424560546875 +33072 -0.491241455078125 +33073 -0.265716552734375 +33074 -0.023712158203125 +33075 0.201751708984375 +33076 0.375823974609375 +33077 0.485076904296875 +33078 0.56884765625 +33079 0.634765625 +33080 0.63763427734375 +33081 0.5660400390625 +33082 0.4720458984375 +33083 0.40692138671875 +33084 0.3778076171875 +33085 0.376953125 +33086 0.371978759765625 +33087 0.313140869140625 +33088 0.184417724609375 +33089 0.011199951171875 +33090 -0.171051025390625 +33091 -0.33740234375 +33092 -0.47198486328125 +33093 -0.560394287109375 +33094 -0.58056640625 +33095 -0.54754638671875 +33096 -0.508575439453125 +33097 -0.459503173828125 +33098 -0.394378662109375 +33099 -0.35260009765625 +33100 -0.31170654296875 +33101 -0.197418212890625 +33102 -0.007965087890625 +33103 0.207489013671875 +33104 0.409210205078125 +33105 0.57208251953125 +33106 0.66595458984375 +33107 0.65875244140625 +33108 0.56744384765625 +33109 0.431396484375 +33110 0.29443359375 +33111 0.182464599609375 +33112 0.06365966796875 +33113 -0.075958251953125 +33114 -0.189422607421875 +33115 -0.271942138671875 +33116 -0.342529296875 +33117 -0.364166259765625 +33118 -0.327239990234375 +33119 -0.2769775390625 +33120 -0.253692626953125 +33121 -0.24365234375 +33122 -0.1983642578125 +33123 -0.116241455078125 +33124 -0.036834716796875 +33125 0.034881591796875 +33126 0.09124755859375 +33127 0.10888671875 +33128 0.125518798828125 +33129 0.15771484375 +33130 0.17828369140625 +33131 0.17108154296875 +33132 0.129974365234375 +33133 0.082427978515625 +33134 0.027679443359375 +33135 -0.065643310546875 +33136 -0.15936279296875 +33137 -0.21307373046875 +33138 -0.234649658203125 +33139 -0.2001953125 +33140 -0.119171142578125 +33141 -0.024749755859375 +33142 0.085784912109375 +33143 0.178131103515625 +33144 0.215576171875 +33145 0.211456298828125 +33146 0.17523193359375 +33147 0.128753662109375 +33148 0.1019287109375 +33149 0.0743408203125 +33150 0.04327392578125 +33151 0.038177490234375 +33152 0.076263427734375 +33153 0.14105224609375 +33154 0.186431884765625 +33155 0.188812255859375 +33156 0.1390380859375 +33157 0.041778564453125 +33158 -0.079437255859375 +33159 -0.219390869140625 +33160 -0.367828369140625 +33161 -0.494873046875 +33162 -0.556243896484375 +33163 -0.508697509765625 +33164 -0.3756103515625 +33165 -0.218902587890625 +33166 -0.063751220703125 +33167 0.091552734375 +33168 0.23602294921875 +33169 0.342987060546875 +33170 0.39520263671875 +33171 0.389373779296875 +33172 0.324249267578125 +33173 0.224090576171875 +33174 0.124267578125 +33175 0.037078857421875 +33176 -0.010101318359375 +33177 -0.019439697265625 +33178 -0.022796630859375 +33179 -0.001556396484375 +33180 0.056304931640625 +33181 0.106719970703125 +33182 0.096893310546875 +33183 0.042694091796875 +33184 -0.018035888671875 +33185 -0.07586669921875 +33186 -0.11944580078125 +33187 -0.15972900390625 +33188 -0.202606201171875 +33189 -0.24859619140625 +33190 -0.30517578125 +33191 -0.36212158203125 +33192 -0.39141845703125 +33193 -0.35528564453125 +33194 -0.249969482421875 +33195 -0.092864990234375 +33196 0.08905029296875 +33197 0.2352294921875 +33198 0.318817138671875 +33199 0.358642578125 +33200 0.347747802734375 +33201 0.28564453125 +33202 0.223175048828125 +33203 0.196746826171875 +33204 0.179840087890625 +33205 0.155548095703125 +33206 0.151214599609375 +33207 0.156951904296875 +33208 0.13177490234375 +33209 0.100799560546875 +33210 0.087127685546875 +33211 0.05487060546875 +33212 -0.009002685546875 +33213 -0.10400390625 +33214 -0.229400634765625 +33215 -0.35552978515625 +33216 -0.441925048828125 +33217 -0.473846435546875 +33218 -0.464813232421875 +33219 -0.419097900390625 +33220 -0.334320068359375 +33221 -0.227935791015625 +33222 -0.12347412109375 +33223 -0.02764892578125 +33224 0.077667236328125 +33225 0.2132568359375 +33226 0.38885498046875 +33227 0.582794189453125 +33228 0.734039306640625 +33229 0.800140380859375 +33230 0.7783203125 +33231 0.6651611328125 +33232 0.45965576171875 +33233 0.199188232421875 +33234 -0.050689697265625 +33235 -0.23297119140625 +33236 -0.33013916015625 +33237 -0.368408203125 +33238 -0.378936767578125 +33239 -0.376983642578125 +33240 -0.37969970703125 +33241 -0.391510009765625 +33242 -0.385345458984375 +33243 -0.3419189453125 +33244 -0.28289794921875 +33245 -0.251617431640625 +33246 -0.266143798828125 +33247 -0.273345947265625 +33248 -0.216796875 +33249 -0.128265380859375 +33250 -0.068145751953125 +33251 -0.0430908203125 +33252 -0.024444580078125 +33253 0.020721435546875 +33254 0.124481201171875 +33255 0.25787353515625 +33256 0.379119873046875 +33257 0.47991943359375 +33258 0.5281982421875 +33259 0.511138916015625 +33260 0.456207275390625 +33261 0.407470703125 +33262 0.383758544921875 +33263 0.35687255859375 +33264 0.31182861328125 +33265 0.250885009765625 +33266 0.1654052734375 +33267 0.035247802734375 +33268 -0.142059326171875 +33269 -0.33563232421875 +33270 -0.5345458984375 +33271 -0.72186279296875 +33272 -0.836669921875 +33273 -0.8326416015625 +33274 -0.7296142578125 +33275 -0.582550048828125 +33276 -0.440093994140625 +33277 -0.324310302734375 +33278 -0.20147705078125 +33279 -0.044647216796875 +33280 0.103973388671875 +33281 0.202392578125 +33282 0.264495849609375 +33283 0.338897705078125 +33284 0.443817138671875 +33285 0.545074462890625 +33286 0.6173095703125 +33287 0.6524658203125 +33288 0.66339111328125 +33289 0.6561279296875 +33290 0.606781005859375 +33291 0.501190185546875 +33292 0.352783203125 +33293 0.176544189453125 +33294 -0.034820556640625 +33295 -0.258209228515625 +33296 -0.44244384765625 +33297 -0.5753173828125 +33298 -0.65203857421875 +33299 -0.641632080078125 +33300 -0.562164306640625 +33301 -0.458038330078125 +33302 -0.350555419921875 +33303 -0.260528564453125 +33304 -0.192108154296875 +33305 -0.141937255859375 +33306 -0.1021728515625 +33307 -0.062896728515625 +33308 -0.011932373046875 +33309 0.062835693359375 +33310 0.148712158203125 +33311 0.241729736328125 +33312 0.34912109375 +33313 0.457305908203125 +33314 0.54388427734375 +33315 0.5728759765625 +33316 0.506591796875 +33317 0.351226806640625 +33318 0.146514892578125 +33319 -0.05523681640625 +33320 -0.21624755859375 +33321 -0.334930419921875 +33322 -0.402984619140625 +33323 -0.4412841796875 +33324 -0.49578857421875 +33325 -0.5601806640625 +33326 -0.600738525390625 +33327 -0.584228515625 +33328 -0.47930908203125 +33329 -0.27935791015625 +33330 -0.0089111328125 +33331 0.268798828125 +33332 0.482818603515625 +33333 0.60369873046875 +33334 0.650421142578125 +33335 0.66400146484375 +33336 0.6414794921875 +33337 0.572540283203125 +33338 0.498138427734375 +33339 0.439453125 +33340 0.375518798828125 +33341 0.274505615234375 +33342 0.1087646484375 +33343 -0.099395751953125 +33344 -0.3182373046875 +33345 -0.5489501953125 +33346 -0.7738037109375 +33347 -0.86383056640625 +33348 -0.870391845703125 +33349 -0.86895751953125 +33350 -0.861053466796875 +33351 -0.765869140625 +33352 -0.5301513671875 +33353 -0.214691162109375 +33354 0.137359619140625 +33355 0.474822998046875 +33356 0.76239013671875 +33357 0.867462158203125 +33358 0.870361328125 +33359 0.86480712890625 +33360 0.831817626953125 +33361 0.677581787109375 +33362 0.495880126953125 +33363 0.30767822265625 +33364 0.116180419921875 +33365 -0.110748291015625 +33366 -0.381805419921875 +33367 -0.6572265625 +33368 -0.857421875 +33369 -0.870391845703125 +33370 -0.870391845703125 +33371 -0.86444091796875 +33372 -0.85723876953125 +33373 -0.790008544921875 +33374 -0.62847900390625 +33375 -0.3956298828125 +33376 -0.126708984375 +33377 0.150115966796875 +33378 0.424041748046875 +33379 0.670623779296875 +33380 0.854522705078125 +33381 0.866485595703125 +33382 0.86920166015625 +33383 0.8653564453125 +33384 0.857147216796875 +33385 0.766845703125 +33386 0.628509521484375 +33387 0.462127685546875 +33388 0.297210693359375 +33389 0.14862060546875 +33390 -0.00537109375 +33391 -0.15753173828125 +33392 -0.31304931640625 +33393 -0.48876953125 +33394 -0.6416015625 +33395 -0.751373291015625 +33396 -0.84619140625 +33397 -0.861297607421875 +33398 -0.863250732421875 +33399 -0.856597900390625 +33400 -0.7498779296875 +33401 -0.624542236328125 +33402 -0.47808837890625 +33403 -0.253387451171875 +33404 0.003692626953125 +33405 0.2257080078125 +33406 0.427154541015625 +33407 0.643218994140625 +33408 0.855926513671875 +33409 0.870361328125 +33410 0.870361328125 +33411 0.862762451171875 +33412 0.79669189453125 +33413 0.595794677734375 +33414 0.362152099609375 +33415 0.1270751953125 +33416 -0.086944580078125 +33417 -0.2784423828125 +33418 -0.484832763671875 +33419 -0.729583740234375 +33420 -0.86688232421875 +33421 -0.870391845703125 +33422 -0.86859130859375 +33423 -0.86279296875 +33424 -0.817962646484375 +33425 -0.6116943359375 +33426 -0.3128662109375 +33427 0.039398193359375 +33428 0.422821044921875 +33429 0.805145263671875 +33430 0.870361328125 +33431 0.870361328125 +33432 0.860015869140625 +33433 0.727935791015625 +33434 0.48114013671875 +33435 0.2059326171875 +33436 -0.06103515625 +33437 -0.29913330078125 +33438 -0.516204833984375 +33439 -0.7252197265625 +33440 -0.85980224609375 +33441 -0.870391845703125 +33442 -0.870391845703125 +33443 -0.858062744140625 +33444 -0.673004150390625 +33445 -0.42694091796875 +33446 -0.2100830078125 +33447 -0.0362548828125 +33448 0.10943603515625 +33449 0.23516845703125 +33450 0.373687744140625 +33451 0.517791748046875 +33452 0.602783203125 +33453 0.635711669921875 +33454 0.655181884765625 +33455 0.65948486328125 +33456 0.651275634765625 +33457 0.61846923828125 +33458 0.53753662109375 +33459 0.404144287109375 +33460 0.22186279296875 +33461 0.003997802734375 +33462 -0.22100830078125 +33463 -0.42449951171875 +33464 -0.579833984375 +33465 -0.641876220703125 +33466 -0.6177978515625 +33467 -0.575531005859375 +33468 -0.526336669921875 +33469 -0.42645263671875 +33470 -0.2581787109375 +33471 -0.068695068359375 +33472 0.09222412109375 +33473 0.232147216796875 +33474 0.3509521484375 +33475 0.410064697265625 +33476 0.372955322265625 +33477 0.2554931640625 +33478 0.10711669921875 +33479 -0.052886962890625 +33480 -0.186279296875 +33481 -0.23291015625 +33482 -0.209442138671875 +33483 -0.174163818359375 +33484 -0.126739501953125 +33485 -0.048126220703125 +33486 0.0426025390625 +33487 0.10748291015625 +33488 0.1409912109375 +33489 0.19708251953125 +33490 0.273651123046875 +33491 0.31768798828125 +33492 0.341094970703125 +33493 0.368011474609375 +33494 0.37249755859375 +33495 0.30072021484375 +33496 0.1517333984375 +33497 -0.01470947265625 +33498 -0.1883544921875 +33499 -0.372711181640625 +33500 -0.51397705078125 +33501 -0.57177734375 +33502 -0.53948974609375 +33503 -0.43511962890625 +33504 -0.2962646484375 +33505 -0.161102294921875 +33506 -0.0435791015625 +33507 0.060394287109375 +33508 0.13665771484375 +33509 0.170135498046875 +33510 0.16552734375 +33511 0.15728759765625 +33512 0.150787353515625 +33513 0.12200927734375 +33514 0.080108642578125 +33515 0.05126953125 +33516 0.062896728515625 +33517 0.09271240234375 +33518 0.092987060546875 +33519 0.07855224609375 +33520 0.06427001953125 +33521 0.0347900390625 +33522 -0.01171875 +33523 -0.056060791015625 +33524 -0.055511474609375 +33525 -0.010467529296875 +33526 0.02508544921875 +33527 0.025665283203125 +33528 0.017333984375 +33529 0.00189208984375 +33530 -0.03173828125 +33531 -0.071502685546875 +33532 -0.13543701171875 +33533 -0.219970703125 +33534 -0.300506591796875 +33535 -0.376312255859375 +33536 -0.416107177734375 +33537 -0.371124267578125 +33538 -0.242279052734375 +33539 -0.069732666015625 +33540 0.125640869140625 +33541 0.31268310546875 +33542 0.45501708984375 +33543 0.554779052734375 +33544 0.61065673828125 +33545 0.610931396484375 +33546 0.531463623046875 +33547 0.3883056640625 +33548 0.23468017578125 +33549 0.095245361328125 +33550 -0.00396728515625 +33551 -0.04852294921875 +33552 -0.055145263671875 +33553 -0.0758056640625 +33554 -0.138702392578125 +33555 -0.209197998046875 +33556 -0.289031982421875 +33557 -0.37884521484375 +33558 -0.456329345703125 +33559 -0.51641845703125 +33560 -0.519287109375 +33561 -0.458251953125 +33562 -0.384796142578125 +33563 -0.323699951171875 +33564 -0.269287109375 +33565 -0.1951904296875 +33566 -0.100006103515625 +33567 -0.01055908203125 +33568 0.1033935546875 +33569 0.24908447265625 +33570 0.373199462890625 +33571 0.45806884765625 +33572 0.511474609375 +33573 0.565399169921875 +33574 0.61138916015625 +33575 0.5897216796875 +33576 0.4906005859375 +33577 0.33148193359375 +33578 0.147796630859375 +33579 -0.01873779296875 +33580 -0.140289306640625 +33581 -0.191986083984375 +33582 -0.184295654296875 +33583 -0.161834716796875 +33584 -0.166595458984375 +33585 -0.19390869140625 +33586 -0.22442626953125 +33587 -0.279754638671875 +33588 -0.3389892578125 +33589 -0.3543701171875 +33590 -0.348175048828125 +33591 -0.32598876953125 +33592 -0.2581787109375 +33593 -0.139801025390625 +33594 0.014617919921875 +33595 0.144378662109375 +33596 0.221038818359375 +33597 0.27069091796875 +33598 0.294036865234375 +33599 0.311767578125 +33600 0.339141845703125 +33601 0.360260009765625 +33602 0.360504150390625 +33603 0.308380126953125 +33604 0.18170166015625 +33605 0.0047607421875 +33606 -0.17559814453125 +33607 -0.3143310546875 +33608 -0.36785888671875 +33609 -0.36248779296875 +33610 -0.343536376953125 +33611 -0.3018798828125 +33612 -0.231414794921875 +33613 -0.117645263671875 +33614 0.007049560546875 +33615 0.087982177734375 +33616 0.13946533203125 +33617 0.17425537109375 +33618 0.188201904296875 +33619 0.171234130859375 +33620 0.118438720703125 +33621 0.05706787109375 +33622 -0.010711669921875 +33623 -0.0914306640625 +33624 -0.162322998046875 +33625 -0.194549560546875 +33626 -0.1492919921875 +33627 -0.02166748046875 +33628 0.124053955078125 +33629 0.211151123046875 +33630 0.240447998046875 +33631 0.242218017578125 +33632 0.2257080078125 +33633 0.194366455078125 +33634 0.115509033203125 +33635 0.0128173828125 +33636 -0.053802490234375 +33637 -0.110626220703125 +33638 -0.199493408203125 +33639 -0.29437255859375 +33640 -0.33221435546875 +33641 -0.27972412109375 +33642 -0.185333251953125 +33643 -0.128204345703125 +33644 -0.115692138671875 +33645 -0.116455078125 +33646 -0.105926513671875 +33647 -0.053955078125 +33648 0.048797607421875 +33649 0.157318115234375 +33650 0.212005615234375 +33651 0.218475341796875 +33652 0.23724365234375 +33653 0.30535888671875 +33654 0.38128662109375 +33655 0.404449462890625 +33656 0.3944091796875 +33657 0.3885498046875 +33658 0.362640380859375 +33659 0.27362060546875 +33660 0.11712646484375 +33661 -0.054901123046875 +33662 -0.19085693359375 +33663 -0.28570556640625 +33664 -0.339263916015625 +33665 -0.3775634765625 +33666 -0.445709228515625 +33667 -0.535064697265625 +33668 -0.629058837890625 +33669 -0.697601318359375 +33670 -0.70391845703125 +33671 -0.6424560546875 +33672 -0.491241455078125 +33673 -0.265716552734375 +33674 -0.023712158203125 +33675 0.201751708984375 +33676 0.375823974609375 +33677 0.485076904296875 +33678 0.56884765625 +33679 0.634765625 +33680 0.63763427734375 +33681 0.5660400390625 +33682 0.4720458984375 +33683 0.40692138671875 +33684 0.3778076171875 +33685 0.376953125 +33686 0.371978759765625 +33687 0.313140869140625 +33688 0.184417724609375 +33689 0.011199951171875 +33690 -0.171051025390625 +33691 -0.33740234375 +33692 -0.47198486328125 +33693 -0.560394287109375 +33694 -0.58056640625 +33695 -0.54754638671875 +33696 -0.508575439453125 +33697 -0.459503173828125 +33698 -0.394378662109375 +33699 -0.35260009765625 +33700 -0.31170654296875 +33701 -0.197418212890625 +33702 -0.007965087890625 +33703 0.207489013671875 +33704 0.409210205078125 +33705 0.57208251953125 +33706 0.66595458984375 +33707 0.65875244140625 +33708 0.56744384765625 +33709 0.431396484375 +33710 0.29443359375 +33711 0.182464599609375 +33712 0.06365966796875 +33713 -0.075958251953125 +33714 -0.189422607421875 +33715 -0.271942138671875 +33716 -0.342529296875 +33717 -0.364166259765625 +33718 -0.327239990234375 +33719 -0.2769775390625 +33720 -0.253692626953125 +33721 -0.24365234375 +33722 -0.1983642578125 +33723 -0.116241455078125 +33724 -0.036834716796875 +33725 0.034881591796875 +33726 0.09124755859375 +33727 0.10888671875 +33728 0.125518798828125 +33729 0.15771484375 +33730 0.17828369140625 +33731 0.17108154296875 +33732 0.129974365234375 +33733 0.082427978515625 +33734 0.027679443359375 +33735 -0.065643310546875 +33736 -0.15936279296875 +33737 -0.21307373046875 +33738 -0.234649658203125 +33739 -0.2001953125 +33740 -0.119171142578125 +33741 -0.024749755859375 +33742 0.085784912109375 +33743 0.178131103515625 +33744 0.215576171875 +33745 0.211456298828125 +33746 0.17523193359375 +33747 0.128753662109375 +33748 0.1019287109375 +33749 0.0743408203125 +33750 0.04327392578125 +33751 0.038177490234375 +33752 0.076263427734375 +33753 0.14105224609375 +33754 0.186431884765625 +33755 0.188812255859375 +33756 0.1390380859375 +33757 0.041778564453125 +33758 -0.079437255859375 +33759 -0.219390869140625 +33760 -0.367828369140625 +33761 -0.494873046875 +33762 -0.556243896484375 +33763 -0.508697509765625 +33764 -0.3756103515625 +33765 -0.218902587890625 +33766 -0.063751220703125 +33767 0.091552734375 +33768 0.23602294921875 +33769 0.342987060546875 +33770 0.39520263671875 +33771 0.389373779296875 +33772 0.324249267578125 +33773 0.224090576171875 +33774 0.124267578125 +33775 0.037078857421875 +33776 -0.010101318359375 +33777 -0.019439697265625 +33778 -0.022796630859375 +33779 -0.001556396484375 +33780 0.056304931640625 +33781 0.106719970703125 +33782 0.096893310546875 +33783 0.042694091796875 +33784 -0.018035888671875 +33785 -0.07586669921875 +33786 -0.11944580078125 +33787 -0.15972900390625 +33788 -0.202606201171875 +33789 -0.24859619140625 +33790 -0.30517578125 +33791 -0.36212158203125 +33792 -0.39141845703125 +33793 -0.35528564453125 +33794 -0.249969482421875 +33795 -0.092864990234375 +33796 0.08905029296875 +33797 0.2352294921875 +33798 0.318817138671875 +33799 0.358642578125 +33800 0.347747802734375 +33801 0.28564453125 +33802 0.223175048828125 +33803 0.196746826171875 +33804 0.179840087890625 +33805 0.155548095703125 +33806 0.151214599609375 +33807 0.156951904296875 +33808 0.13177490234375 +33809 0.100799560546875 +33810 0.087127685546875 +33811 0.05487060546875 +33812 -0.009002685546875 +33813 -0.10400390625 +33814 -0.229400634765625 +33815 -0.35552978515625 +33816 -0.441925048828125 +33817 -0.473846435546875 +33818 -0.464813232421875 +33819 -0.419097900390625 +33820 -0.334320068359375 +33821 -0.227935791015625 +33822 -0.12347412109375 +33823 -0.02764892578125 +33824 0.077667236328125 +33825 0.2132568359375 +33826 0.38885498046875 +33827 0.582794189453125 +33828 0.734039306640625 +33829 0.800140380859375 +33830 0.7783203125 +33831 0.6651611328125 +33832 0.45965576171875 +33833 0.199188232421875 +33834 -0.050689697265625 +33835 -0.23297119140625 +33836 -0.33013916015625 +33837 -0.368408203125 +33838 -0.378936767578125 +33839 -0.376983642578125 +33840 -0.37969970703125 +33841 -0.391510009765625 +33842 -0.385345458984375 +33843 -0.3419189453125 +33844 -0.28289794921875 +33845 -0.251617431640625 +33846 -0.266143798828125 +33847 -0.273345947265625 +33848 -0.216796875 +33849 -0.128265380859375 +33850 -0.068145751953125 +33851 -0.0430908203125 +33852 -0.024444580078125 +33853 0.020721435546875 +33854 0.124481201171875 +33855 0.25787353515625 +33856 0.379119873046875 +33857 0.47991943359375 +33858 0.5281982421875 +33859 0.511138916015625 +33860 0.456207275390625 +33861 0.407470703125 +33862 0.383758544921875 +33863 0.35687255859375 +33864 0.31182861328125 +33865 0.250885009765625 +33866 0.1654052734375 +33867 0.035247802734375 +33868 -0.142059326171875 +33869 -0.33563232421875 +33870 -0.5345458984375 +33871 -0.72186279296875 +33872 -0.836669921875 +33873 -0.8326416015625 +33874 -0.7296142578125 +33875 -0.582550048828125 +33876 -0.440093994140625 +33877 -0.324310302734375 +33878 -0.20147705078125 +33879 -0.044647216796875 +33880 0.103973388671875 +33881 0.202392578125 +33882 0.264495849609375 +33883 0.338897705078125 +33884 0.443817138671875 +33885 0.545074462890625 +33886 0.6173095703125 +33887 0.6524658203125 +33888 0.66339111328125 +33889 0.6561279296875 +33890 0.606781005859375 +33891 0.501190185546875 +33892 0.352783203125 +33893 0.176544189453125 +33894 -0.034820556640625 +33895 -0.258209228515625 +33896 -0.44244384765625 +33897 -0.5753173828125 +33898 -0.65203857421875 +33899 -0.641632080078125 +33900 -0.562164306640625 +33901 -0.458038330078125 +33902 -0.350555419921875 +33903 -0.260528564453125 +33904 -0.192108154296875 +33905 -0.141937255859375 +33906 -0.1021728515625 +33907 -0.062896728515625 +33908 -0.011932373046875 +33909 0.062835693359375 +33910 0.148712158203125 +33911 0.241729736328125 +33912 0.34912109375 +33913 0.457305908203125 +33914 0.54388427734375 +33915 0.5728759765625 +33916 0.506591796875 +33917 0.351226806640625 +33918 0.146514892578125 +33919 -0.05523681640625 +33920 -0.21624755859375 +33921 -0.334930419921875 +33922 -0.402984619140625 +33923 -0.4412841796875 +33924 -0.49578857421875 +33925 -0.5601806640625 +33926 -0.600738525390625 +33927 -0.584228515625 +33928 -0.47930908203125 +33929 -0.27935791015625 +33930 -0.0089111328125 +33931 0.268798828125 +33932 0.482818603515625 +33933 0.60369873046875 +33934 0.650421142578125 +33935 0.66400146484375 +33936 0.6414794921875 +33937 0.572540283203125 +33938 0.498138427734375 +33939 0.439453125 +33940 0.375518798828125 +33941 0.274505615234375 +33942 0.1087646484375 +33943 -0.099395751953125 +33944 -0.3182373046875 +33945 -0.5489501953125 +33946 -0.7738037109375 +33947 -0.86383056640625 +33948 -0.870391845703125 +33949 -0.86895751953125 +33950 -0.861053466796875 +33951 -0.765869140625 +33952 -0.5301513671875 +33953 -0.214691162109375 +33954 0.137359619140625 +33955 0.474822998046875 +33956 0.76239013671875 +33957 0.867462158203125 +33958 0.870361328125 +33959 0.86480712890625 +33960 0.831817626953125 +33961 0.677581787109375 +33962 0.495880126953125 +33963 0.30767822265625 +33964 0.116180419921875 +33965 -0.110748291015625 +33966 -0.381805419921875 +33967 -0.6572265625 +33968 -0.857421875 +33969 -0.870391845703125 +33970 -0.870391845703125 +33971 -0.86444091796875 +33972 -0.85723876953125 +33973 -0.790008544921875 +33974 -0.62847900390625 +33975 -0.3956298828125 +33976 -0.126708984375 +33977 0.150115966796875 +33978 0.424041748046875 +33979 0.670623779296875 +33980 0.854522705078125 +33981 0.866485595703125 +33982 0.86920166015625 +33983 0.8653564453125 +33984 0.857147216796875 +33985 0.766845703125 +33986 0.628509521484375 +33987 0.462127685546875 +33988 0.297210693359375 +33989 0.14862060546875 +33990 -0.00537109375 +33991 -0.15753173828125 +33992 -0.31304931640625 +33993 -0.48876953125 +33994 -0.6416015625 +33995 -0.751373291015625 +33996 -0.84619140625 +33997 -0.861297607421875 +33998 -0.863250732421875 +33999 -0.856597900390625 +34000 -0.7498779296875 +34001 -0.624542236328125 +34002 -0.47808837890625 +34003 -0.253387451171875 +34004 0.003692626953125 +34005 0.2257080078125 +34006 0.427154541015625 +34007 0.643218994140625 +34008 0.855926513671875 +34009 0.870361328125 +34010 0.870361328125 +34011 0.862762451171875 +34012 0.79669189453125 +34013 0.595794677734375 +34014 0.362152099609375 +34015 0.1270751953125 +34016 -0.086944580078125 +34017 -0.2784423828125 +34018 -0.484832763671875 +34019 -0.729583740234375 +34020 -0.86688232421875 +34021 -0.870391845703125 +34022 -0.86859130859375 +34023 -0.86279296875 +34024 -0.817962646484375 +34025 -0.6116943359375 +34026 -0.3128662109375 +34027 0.039398193359375 +34028 0.422821044921875 +34029 0.805145263671875 +34030 0.870361328125 +34031 0.870361328125 +34032 0.860015869140625 +34033 0.727935791015625 +34034 0.48114013671875 +34035 0.2059326171875 +34036 -0.06103515625 +34037 -0.29913330078125 +34038 -0.516204833984375 +34039 -0.7252197265625 +34040 -0.85980224609375 +34041 -0.870391845703125 +34042 -0.870391845703125 +34043 -0.858062744140625 +34044 -0.673004150390625 +34045 -0.42694091796875 +34046 -0.2100830078125 +34047 -0.0362548828125 +34048 0.10943603515625 +34049 0.23516845703125 +34050 0.373687744140625 +34051 0.517791748046875 +34052 0.602783203125 +34053 0.635711669921875 +34054 0.655181884765625 +34055 0.65948486328125 +34056 0.651275634765625 +34057 0.61846923828125 +34058 0.53753662109375 +34059 0.404144287109375 +34060 0.22186279296875 +34061 0.003997802734375 +34062 -0.22100830078125 +34063 -0.42449951171875 +34064 -0.579833984375 +34065 -0.641876220703125 +34066 -0.6177978515625 +34067 -0.575531005859375 +34068 -0.526336669921875 +34069 -0.42645263671875 +34070 -0.2581787109375 +34071 -0.068695068359375 +34072 0.09222412109375 +34073 0.232147216796875 +34074 0.3509521484375 +34075 0.410064697265625 +34076 0.372955322265625 +34077 0.2554931640625 +34078 0.10711669921875 +34079 -0.052886962890625 +34080 -0.186279296875 +34081 -0.23291015625 +34082 -0.209442138671875 +34083 -0.174163818359375 +34084 -0.126739501953125 +34085 -0.048126220703125 +34086 0.0426025390625 +34087 0.10748291015625 +34088 0.1409912109375 +34089 0.19708251953125 +34090 0.273651123046875 +34091 0.31768798828125 +34092 0.341094970703125 +34093 0.368011474609375 +34094 0.37249755859375 +34095 0.30072021484375 +34096 0.1517333984375 +34097 -0.01470947265625 +34098 -0.1883544921875 +34099 -0.372711181640625 +34100 -0.51397705078125 +34101 -0.57177734375 +34102 -0.53948974609375 +34103 -0.43511962890625 +34104 -0.2962646484375 +34105 -0.161102294921875 +34106 -0.0435791015625 +34107 0.060394287109375 +34108 0.13665771484375 +34109 0.170135498046875 +34110 0.16552734375 +34111 0.15728759765625 +34112 0.150787353515625 +34113 0.12200927734375 +34114 0.080108642578125 +34115 0.05126953125 +34116 0.062896728515625 +34117 0.09271240234375 +34118 0.092987060546875 +34119 0.07855224609375 +34120 0.06427001953125 +34121 0.0347900390625 +34122 -0.01171875 +34123 -0.056060791015625 +34124 -0.055511474609375 +34125 -0.010467529296875 +34126 0.02508544921875 +34127 0.025665283203125 +34128 0.017333984375 +34129 0.00189208984375 +34130 -0.03173828125 +34131 -0.071502685546875 +34132 -0.13543701171875 +34133 -0.219970703125 +34134 -0.300506591796875 +34135 -0.376312255859375 +34136 -0.416107177734375 +34137 -0.371124267578125 +34138 -0.242279052734375 +34139 -0.069732666015625 +34140 0.125640869140625 +34141 0.31268310546875 +34142 0.45501708984375 +34143 0.554779052734375 +34144 0.61065673828125 +34145 0.610931396484375 +34146 0.531463623046875 +34147 0.3883056640625 +34148 0.23468017578125 +34149 0.095245361328125 +34150 -0.00396728515625 +34151 -0.04852294921875 +34152 -0.055145263671875 +34153 -0.0758056640625 +34154 -0.138702392578125 +34155 -0.209197998046875 +34156 -0.289031982421875 +34157 -0.37884521484375 +34158 -0.456329345703125 +34159 -0.51641845703125 +34160 -0.519287109375 +34161 -0.458251953125 +34162 -0.384796142578125 +34163 -0.323699951171875 +34164 -0.269287109375 +34165 -0.1951904296875 +34166 -0.100006103515625 +34167 -0.01055908203125 +34168 0.1033935546875 +34169 0.24908447265625 +34170 0.373199462890625 +34171 0.45806884765625 +34172 0.511474609375 +34173 0.565399169921875 +34174 0.61138916015625 +34175 0.5897216796875 +34176 0.4906005859375 +34177 0.33148193359375 +34178 0.147796630859375 +34179 -0.01873779296875 +34180 -0.140289306640625 +34181 -0.191986083984375 +34182 -0.184295654296875 +34183 -0.161834716796875 +34184 -0.166595458984375 +34185 -0.19390869140625 +34186 -0.22442626953125 +34187 -0.279754638671875 +34188 -0.3389892578125 +34189 -0.3543701171875 +34190 -0.348175048828125 +34191 -0.32598876953125 +34192 -0.2581787109375 +34193 -0.139801025390625 +34194 0.014617919921875 +34195 0.144378662109375 +34196 0.221038818359375 +34197 0.27069091796875 +34198 0.294036865234375 +34199 0.311767578125 +34200 0.339141845703125 +34201 0.360260009765625 +34202 0.360504150390625 +34203 0.308380126953125 +34204 0.18170166015625 +34205 0.0047607421875 +34206 -0.17559814453125 +34207 -0.3143310546875 +34208 -0.36785888671875 +34209 -0.36248779296875 +34210 -0.343536376953125 +34211 -0.3018798828125 +34212 -0.231414794921875 +34213 -0.117645263671875 +34214 0.007049560546875 +34215 0.087982177734375 +34216 0.13946533203125 +34217 0.17425537109375 +34218 0.188201904296875 +34219 0.171234130859375 +34220 0.118438720703125 +34221 0.05706787109375 +34222 -0.010711669921875 +34223 -0.0914306640625 +34224 -0.162322998046875 +34225 -0.194549560546875 +34226 -0.1492919921875 +34227 -0.02166748046875 +34228 0.124053955078125 +34229 0.211151123046875 +34230 0.240447998046875 +34231 0.242218017578125 +34232 0.2257080078125 +34233 0.194366455078125 +34234 0.115509033203125 +34235 0.0128173828125 +34236 -0.053802490234375 +34237 -0.110626220703125 +34238 -0.199493408203125 +34239 -0.29437255859375 +34240 -0.33221435546875 +34241 -0.27972412109375 +34242 -0.185333251953125 +34243 -0.128204345703125 +34244 -0.115692138671875 +34245 -0.116455078125 +34246 -0.105926513671875 +34247 -0.053955078125 +34248 0.048797607421875 +34249 0.157318115234375 +34250 0.212005615234375 +34251 0.218475341796875 +34252 0.23724365234375 +34253 0.30535888671875 +34254 0.38128662109375 +34255 0.404449462890625 +34256 0.3944091796875 +34257 0.3885498046875 +34258 0.362640380859375 +34259 0.27362060546875 +34260 0.11712646484375 +34261 -0.054901123046875 +34262 -0.19085693359375 +34263 -0.28570556640625 +34264 -0.339263916015625 +34265 -0.3775634765625 +34266 -0.445709228515625 +34267 -0.535064697265625 +34268 -0.629058837890625 +34269 -0.697601318359375 +34270 -0.70391845703125 +34271 -0.6424560546875 +34272 -0.491241455078125 +34273 -0.265716552734375 +34274 -0.023712158203125 +34275 0.201751708984375 +34276 0.375823974609375 +34277 0.485076904296875 +34278 0.56884765625 +34279 0.634765625 +34280 0.63763427734375 +34281 0.5660400390625 +34282 0.4720458984375 +34283 0.40692138671875 +34284 0.3778076171875 +34285 0.376953125 +34286 0.371978759765625 +34287 0.313140869140625 +34288 0.184417724609375 +34289 0.011199951171875 +34290 -0.171051025390625 +34291 -0.33740234375 +34292 -0.47198486328125 +34293 -0.560394287109375 +34294 -0.58056640625 +34295 -0.54754638671875 +34296 -0.508575439453125 +34297 -0.459503173828125 +34298 -0.394378662109375 +34299 -0.35260009765625 +34300 -0.31170654296875 +34301 -0.197418212890625 +34302 -0.007965087890625 +34303 0.207489013671875 +34304 0.409210205078125 +34305 0.57208251953125 +34306 0.66595458984375 +34307 0.65875244140625 +34308 0.56744384765625 +34309 0.431396484375 +34310 0.29443359375 +34311 0.182464599609375 +34312 0.06365966796875 +34313 -0.075958251953125 +34314 -0.189422607421875 +34315 -0.271942138671875 +34316 -0.342529296875 +34317 -0.364166259765625 +34318 -0.327239990234375 +34319 -0.2769775390625 +34320 -0.253692626953125 +34321 -0.24365234375 +34322 -0.1983642578125 +34323 -0.116241455078125 +34324 -0.036834716796875 +34325 0.034881591796875 +34326 0.09124755859375 +34327 0.10888671875 +34328 0.125518798828125 +34329 0.15771484375 +34330 0.17828369140625 +34331 0.17108154296875 +34332 0.129974365234375 +34333 0.082427978515625 +34334 0.027679443359375 +34335 -0.065643310546875 +34336 -0.15936279296875 +34337 -0.21307373046875 +34338 -0.234649658203125 +34339 -0.2001953125 +34340 -0.119171142578125 +34341 -0.024749755859375 +34342 0.085784912109375 +34343 0.178131103515625 +34344 0.215576171875 +34345 0.211456298828125 +34346 0.17523193359375 +34347 0.128753662109375 +34348 0.1019287109375 +34349 0.0743408203125 +34350 0.04327392578125 +34351 0.038177490234375 +34352 0.076263427734375 +34353 0.14105224609375 +34354 0.186431884765625 +34355 0.188812255859375 +34356 0.1390380859375 +34357 0.041778564453125 +34358 -0.079437255859375 +34359 -0.219390869140625 +34360 -0.367828369140625 +34361 -0.494873046875 +34362 -0.556243896484375 +34363 -0.508697509765625 +34364 -0.3756103515625 +34365 -0.218902587890625 +34366 -0.063751220703125 +34367 0.091552734375 +34368 0.23602294921875 +34369 0.342987060546875 +34370 0.39520263671875 +34371 0.389373779296875 +34372 0.324249267578125 +34373 0.224090576171875 +34374 0.124267578125 +34375 0.037078857421875 +34376 -0.010101318359375 +34377 -0.019439697265625 +34378 -0.022796630859375 +34379 -0.001556396484375 +34380 0.056304931640625 +34381 0.106719970703125 +34382 0.096893310546875 +34383 0.042694091796875 +34384 -0.018035888671875 +34385 -0.07586669921875 +34386 -0.11944580078125 +34387 -0.15972900390625 +34388 -0.202606201171875 +34389 -0.24859619140625 +34390 -0.30517578125 +34391 -0.36212158203125 +34392 -0.39141845703125 +34393 -0.35528564453125 +34394 -0.249969482421875 +34395 -0.092864990234375 +34396 0.08905029296875 +34397 0.2352294921875 +34398 0.318817138671875 +34399 0.358642578125 +34400 0.347747802734375 +34401 0.28564453125 +34402 0.223175048828125 +34403 0.196746826171875 +34404 0.179840087890625 +34405 0.155548095703125 +34406 0.151214599609375 +34407 0.156951904296875 +34408 0.13177490234375 +34409 0.100799560546875 +34410 0.087127685546875 +34411 0.05487060546875 +34412 -0.009002685546875 +34413 -0.10400390625 +34414 -0.229400634765625 +34415 -0.35552978515625 +34416 -0.441925048828125 +34417 -0.473846435546875 +34418 -0.464813232421875 +34419 -0.419097900390625 +34420 -0.334320068359375 +34421 -0.227935791015625 +34422 -0.12347412109375 +34423 -0.02764892578125 +34424 0.077667236328125 +34425 0.2132568359375 +34426 0.38885498046875 +34427 0.582794189453125 +34428 0.734039306640625 +34429 0.800140380859375 +34430 0.7783203125 +34431 0.6651611328125 +34432 0.45965576171875 +34433 0.199188232421875 +34434 -0.050689697265625 +34435 -0.23297119140625 +34436 -0.33013916015625 +34437 -0.368408203125 +34438 -0.378936767578125 +34439 -0.376983642578125 +34440 -0.37969970703125 +34441 -0.391510009765625 +34442 -0.385345458984375 +34443 -0.3419189453125 +34444 -0.28289794921875 +34445 -0.251617431640625 +34446 -0.266143798828125 +34447 -0.273345947265625 +34448 -0.216796875 +34449 -0.128265380859375 +34450 -0.068145751953125 +34451 -0.0430908203125 +34452 -0.024444580078125 +34453 0.020721435546875 +34454 0.124481201171875 +34455 0.25787353515625 +34456 0.379119873046875 +34457 0.47991943359375 +34458 0.5281982421875 +34459 0.511138916015625 +34460 0.456207275390625 +34461 0.407470703125 +34462 0.383758544921875 +34463 0.35687255859375 +34464 0.31182861328125 +34465 0.250885009765625 +34466 0.1654052734375 +34467 0.035247802734375 +34468 -0.142059326171875 +34469 -0.33563232421875 +34470 -0.5345458984375 +34471 -0.72186279296875 +34472 -0.836669921875 +34473 -0.8326416015625 +34474 -0.7296142578125 +34475 -0.582550048828125 +34476 -0.440093994140625 +34477 -0.324310302734375 +34478 -0.20147705078125 +34479 -0.044647216796875 +34480 0.103973388671875 +34481 0.202392578125 +34482 0.264495849609375 +34483 0.338897705078125 +34484 0.443817138671875 +34485 0.545074462890625 +34486 0.6173095703125 +34487 0.6524658203125 +34488 0.66339111328125 +34489 0.6561279296875 +34490 0.606781005859375 +34491 0.501190185546875 +34492 0.352783203125 +34493 0.176544189453125 +34494 -0.034820556640625 +34495 -0.258209228515625 +34496 -0.44244384765625 +34497 -0.5753173828125 +34498 -0.65203857421875 +34499 -0.641632080078125 +34500 -0.562164306640625 +34501 -0.458038330078125 +34502 -0.350555419921875 +34503 -0.260528564453125 +34504 -0.192108154296875 +34505 -0.141937255859375 +34506 -0.1021728515625 +34507 -0.062896728515625 +34508 -0.011932373046875 +34509 0.062835693359375 +34510 0.148712158203125 +34511 0.241729736328125 +34512 0.34912109375 +34513 0.457305908203125 +34514 0.54388427734375 +34515 0.5728759765625 +34516 0.506591796875 +34517 0.351226806640625 +34518 0.146514892578125 +34519 -0.05523681640625 +34520 -0.21624755859375 +34521 -0.334930419921875 +34522 -0.402984619140625 +34523 -0.4412841796875 +34524 -0.49578857421875 +34525 -0.5601806640625 +34526 -0.600738525390625 +34527 -0.584228515625 +34528 -0.47930908203125 +34529 -0.27935791015625 +34530 -0.0089111328125 +34531 0.268798828125 +34532 0.482818603515625 +34533 0.60369873046875 +34534 0.650421142578125 +34535 0.66400146484375 +34536 0.6414794921875 +34537 0.572540283203125 +34538 0.498138427734375 +34539 0.439453125 +34540 0.375518798828125 +34541 0.274505615234375 +34542 0.1087646484375 +34543 -0.099395751953125 +34544 -0.3182373046875 +34545 -0.5489501953125 +34546 -0.7738037109375 +34547 -0.86383056640625 +34548 -0.870391845703125 +34549 -0.86895751953125 +34550 -0.861053466796875 +34551 -0.765869140625 +34552 -0.5301513671875 +34553 -0.214691162109375 +34554 0.137359619140625 +34555 0.474822998046875 +34556 0.76239013671875 +34557 0.867462158203125 +34558 0.870361328125 +34559 0.86480712890625 +34560 0.831817626953125 +34561 0.677581787109375 +34562 0.495880126953125 +34563 0.30767822265625 +34564 0.116180419921875 +34565 -0.110748291015625 +34566 -0.381805419921875 +34567 -0.6572265625 +34568 -0.857421875 +34569 -0.870391845703125 +34570 -0.870391845703125 +34571 -0.86444091796875 +34572 -0.85723876953125 +34573 -0.790008544921875 +34574 -0.62847900390625 +34575 -0.3956298828125 +34576 -0.126708984375 +34577 0.150115966796875 +34578 0.424041748046875 +34579 0.670623779296875 +34580 0.854522705078125 +34581 0.866485595703125 +34582 0.86920166015625 +34583 0.8653564453125 +34584 0.857147216796875 +34585 0.766845703125 +34586 0.628509521484375 +34587 0.462127685546875 +34588 0.297210693359375 +34589 0.14862060546875 +34590 -0.00537109375 +34591 -0.15753173828125 +34592 -0.31304931640625 +34593 -0.48876953125 +34594 -0.6416015625 +34595 -0.751373291015625 +34596 -0.84619140625 +34597 -0.861297607421875 +34598 -0.863250732421875 +34599 -0.856597900390625 +34600 -0.7498779296875 +34601 -0.624542236328125 +34602 -0.47808837890625 +34603 -0.253387451171875 +34604 0.003692626953125 +34605 0.2257080078125 +34606 0.427154541015625 +34607 0.643218994140625 +34608 0.855926513671875 +34609 0.870361328125 +34610 0.870361328125 +34611 0.862762451171875 +34612 0.79669189453125 +34613 0.595794677734375 +34614 0.362152099609375 +34615 0.1270751953125 +34616 -0.086944580078125 +34617 -0.2784423828125 +34618 -0.484832763671875 +34619 -0.729583740234375 +34620 -0.86688232421875 +34621 -0.870391845703125 +34622 -0.86859130859375 +34623 -0.86279296875 +34624 -0.817962646484375 +34625 -0.6116943359375 +34626 -0.3128662109375 +34627 0.039398193359375 +34628 0.422821044921875 +34629 0.805145263671875 +34630 0.870361328125 +34631 0.870361328125 +34632 0.860015869140625 +34633 0.727935791015625 +34634 0.48114013671875 +34635 0.2059326171875 +34636 -0.06103515625 +34637 -0.29913330078125 +34638 -0.516204833984375 +34639 -0.7252197265625 +34640 -0.85980224609375 +34641 -0.870391845703125 +34642 -0.870391845703125 +34643 -0.858062744140625 +34644 -0.673004150390625 +34645 -0.42694091796875 +34646 -0.2100830078125 +34647 -0.0362548828125 +34648 0.10943603515625 +34649 0.23516845703125 +34650 0.373687744140625 +34651 0.517791748046875 +34652 0.602783203125 +34653 0.635711669921875 +34654 0.655181884765625 +34655 0.65948486328125 +34656 0.651275634765625 +34657 0.61846923828125 +34658 0.53753662109375 +34659 0.404144287109375 +34660 0.22186279296875 +34661 0.003997802734375 +34662 -0.22100830078125 +34663 -0.42449951171875 +34664 -0.579833984375 +34665 -0.641876220703125 +34666 -0.6177978515625 +34667 -0.575531005859375 +34668 -0.526336669921875 +34669 -0.42645263671875 +34670 -0.2581787109375 +34671 -0.068695068359375 +34672 0.09222412109375 +34673 0.232147216796875 +34674 0.3509521484375 +34675 0.410064697265625 +34676 0.372955322265625 +34677 0.2554931640625 +34678 0.10711669921875 +34679 -0.052886962890625 +34680 -0.186279296875 +34681 -0.23291015625 +34682 -0.209442138671875 +34683 -0.174163818359375 +34684 -0.126739501953125 +34685 -0.048126220703125 +34686 0.0426025390625 +34687 0.10748291015625 +34688 0.1409912109375 +34689 0.19708251953125 +34690 0.273651123046875 +34691 0.31768798828125 +34692 0.341094970703125 +34693 0.368011474609375 +34694 0.37249755859375 +34695 0.30072021484375 +34696 0.1517333984375 +34697 -0.01470947265625 +34698 -0.1883544921875 +34699 -0.372711181640625 +34700 -0.51397705078125 +34701 -0.57177734375 +34702 -0.53948974609375 +34703 -0.43511962890625 +34704 -0.2962646484375 +34705 -0.161102294921875 +34706 -0.0435791015625 +34707 0.060394287109375 +34708 0.13665771484375 +34709 0.170135498046875 +34710 0.16552734375 +34711 0.15728759765625 +34712 0.150787353515625 +34713 0.12200927734375 +34714 0.080108642578125 +34715 0.05126953125 +34716 0.062896728515625 +34717 0.09271240234375 +34718 0.092987060546875 +34719 0.07855224609375 +34720 0.06427001953125 +34721 0.0347900390625 +34722 -0.01171875 +34723 -0.056060791015625 +34724 -0.055511474609375 +34725 -0.010467529296875 +34726 0.02508544921875 +34727 0.025665283203125 +34728 0.017333984375 +34729 0.00189208984375 +34730 -0.03173828125 +34731 -0.071502685546875 +34732 -0.13543701171875 +34733 -0.219970703125 +34734 -0.300506591796875 +34735 -0.376312255859375 +34736 -0.416107177734375 +34737 -0.371124267578125 +34738 -0.242279052734375 +34739 -0.069732666015625 +34740 0.125640869140625 +34741 0.31268310546875 +34742 0.45501708984375 +34743 0.554779052734375 +34744 0.61065673828125 +34745 0.610931396484375 +34746 0.531463623046875 +34747 0.3883056640625 +34748 0.23468017578125 +34749 0.095245361328125 +34750 -0.00396728515625 +34751 -0.04852294921875 +34752 -0.055145263671875 +34753 -0.0758056640625 +34754 -0.138702392578125 +34755 -0.209197998046875 +34756 -0.289031982421875 +34757 -0.37884521484375 +34758 -0.456329345703125 +34759 -0.51641845703125 +34760 -0.519287109375 +34761 -0.458251953125 +34762 -0.384796142578125 +34763 -0.323699951171875 +34764 -0.269287109375 +34765 -0.1951904296875 +34766 -0.100006103515625 +34767 -0.01055908203125 +34768 0.1033935546875 +34769 0.24908447265625 +34770 0.373199462890625 +34771 0.45806884765625 +34772 0.511474609375 +34773 0.565399169921875 +34774 0.61138916015625 +34775 0.5897216796875 +34776 0.4906005859375 +34777 0.33148193359375 +34778 0.147796630859375 +34779 -0.01873779296875 +34780 -0.140289306640625 +34781 -0.191986083984375 +34782 -0.184295654296875 +34783 -0.161834716796875 +34784 -0.166595458984375 +34785 -0.19390869140625 +34786 -0.22442626953125 +34787 -0.279754638671875 +34788 -0.3389892578125 +34789 -0.3543701171875 +34790 -0.348175048828125 +34791 -0.32598876953125 +34792 -0.2581787109375 +34793 -0.139801025390625 +34794 0.014617919921875 +34795 0.144378662109375 +34796 0.221038818359375 +34797 0.27069091796875 +34798 0.294036865234375 +34799 0.311767578125 +34800 0.339141845703125 +34801 0.360260009765625 +34802 0.360504150390625 +34803 0.308380126953125 +34804 0.18170166015625 +34805 0.0047607421875 +34806 -0.17559814453125 +34807 -0.3143310546875 +34808 -0.36785888671875 +34809 -0.36248779296875 +34810 -0.343536376953125 +34811 -0.3018798828125 +34812 -0.231414794921875 +34813 -0.117645263671875 +34814 0.007049560546875 +34815 0.087982177734375 +34816 0.13946533203125 +34817 0.17425537109375 +34818 0.188201904296875 +34819 0.171234130859375 +34820 0.118438720703125 +34821 0.05706787109375 +34822 -0.010711669921875 +34823 -0.0914306640625 +34824 -0.162322998046875 +34825 -0.194549560546875 +34826 -0.1492919921875 +34827 -0.02166748046875 +34828 0.124053955078125 +34829 0.211151123046875 +34830 0.240447998046875 +34831 0.242218017578125 +34832 0.2257080078125 +34833 0.194366455078125 +34834 0.115509033203125 +34835 0.0128173828125 +34836 -0.053802490234375 +34837 -0.110626220703125 +34838 -0.199493408203125 +34839 -0.29437255859375 +34840 -0.33221435546875 +34841 -0.27972412109375 +34842 -0.185333251953125 +34843 -0.128204345703125 +34844 -0.115692138671875 +34845 -0.116455078125 +34846 -0.105926513671875 +34847 -0.053955078125 +34848 0.048797607421875 +34849 0.157318115234375 +34850 0.212005615234375 +34851 0.218475341796875 +34852 0.23724365234375 +34853 0.30535888671875 +34854 0.38128662109375 +34855 0.404449462890625 +34856 0.3944091796875 +34857 0.3885498046875 +34858 0.362640380859375 +34859 0.27362060546875 +34860 0.11712646484375 +34861 -0.054901123046875 +34862 -0.19085693359375 +34863 -0.28570556640625 +34864 -0.339263916015625 +34865 -0.3775634765625 +34866 -0.445709228515625 +34867 -0.535064697265625 +34868 -0.629058837890625 +34869 -0.697601318359375 +34870 -0.70391845703125 +34871 -0.6424560546875 +34872 -0.491241455078125 +34873 -0.265716552734375 +34874 -0.023712158203125 +34875 0.201751708984375 +34876 0.375823974609375 +34877 0.485076904296875 +34878 0.56884765625 +34879 0.634765625 +34880 0.63763427734375 +34881 0.5660400390625 +34882 0.4720458984375 +34883 0.40692138671875 +34884 0.3778076171875 +34885 0.376953125 +34886 0.371978759765625 +34887 0.313140869140625 +34888 0.184417724609375 +34889 0.011199951171875 +34890 -0.171051025390625 +34891 -0.33740234375 +34892 -0.47198486328125 +34893 -0.560394287109375 +34894 -0.58056640625 +34895 -0.54754638671875 +34896 -0.508575439453125 +34897 -0.459503173828125 +34898 -0.394378662109375 +34899 -0.35260009765625 +34900 -0.31170654296875 +34901 -0.197418212890625 +34902 -0.007965087890625 +34903 0.207489013671875 +34904 0.409210205078125 +34905 0.57208251953125 +34906 0.66595458984375 +34907 0.65875244140625 +34908 0.56744384765625 +34909 0.431396484375 +34910 0.29443359375 +34911 0.182464599609375 +34912 0.06365966796875 +34913 -0.075958251953125 +34914 -0.189422607421875 +34915 -0.271942138671875 +34916 -0.342529296875 +34917 -0.364166259765625 +34918 -0.327239990234375 +34919 -0.2769775390625 +34920 -0.253692626953125 +34921 -0.24365234375 +34922 -0.1983642578125 +34923 -0.116241455078125 +34924 -0.036834716796875 +34925 0.034881591796875 +34926 0.09124755859375 +34927 0.10888671875 +34928 0.125518798828125 +34929 0.15771484375 +34930 0.17828369140625 +34931 0.17108154296875 +34932 0.129974365234375 +34933 0.082427978515625 +34934 0.027679443359375 +34935 -0.065643310546875 +34936 -0.15936279296875 +34937 -0.21307373046875 +34938 -0.234649658203125 +34939 -0.2001953125 +34940 -0.119171142578125 +34941 -0.024749755859375 +34942 0.085784912109375 +34943 0.178131103515625 +34944 0.215576171875 +34945 0.211456298828125 +34946 0.17523193359375 +34947 0.128753662109375 +34948 0.1019287109375 +34949 0.0743408203125 +34950 0.04327392578125 +34951 0.038177490234375 +34952 0.076263427734375 +34953 0.14105224609375 +34954 0.186431884765625 +34955 0.188812255859375 +34956 0.1390380859375 +34957 0.041778564453125 +34958 -0.079437255859375 +34959 -0.219390869140625 +34960 -0.367828369140625 +34961 -0.494873046875 +34962 -0.556243896484375 +34963 -0.508697509765625 +34964 -0.3756103515625 +34965 -0.218902587890625 +34966 -0.063751220703125 +34967 0.091552734375 +34968 0.23602294921875 +34969 0.342987060546875 +34970 0.39520263671875 +34971 0.389373779296875 +34972 0.324249267578125 +34973 0.224090576171875 +34974 0.124267578125 +34975 0.037078857421875 +34976 -0.010101318359375 +34977 -0.019439697265625 +34978 -0.022796630859375 +34979 -0.001556396484375 +34980 0.056304931640625 +34981 0.106719970703125 +34982 0.096893310546875 +34983 0.042694091796875 +34984 -0.018035888671875 +34985 -0.07586669921875 +34986 -0.11944580078125 +34987 -0.15972900390625 +34988 -0.202606201171875 +34989 -0.24859619140625 +34990 -0.30517578125 +34991 -0.36212158203125 +34992 -0.39141845703125 +34993 -0.35528564453125 +34994 -0.249969482421875 +34995 -0.092864990234375 +34996 0.08905029296875 +34997 0.2352294921875 +34998 0.318817138671875 +34999 0.358642578125 +35000 0.347747802734375 +35001 0.28564453125 +35002 0.223175048828125 +35003 0.196746826171875 +35004 0.179840087890625 +35005 0.155548095703125 +35006 0.151214599609375 +35007 0.156951904296875 +35008 0.13177490234375 +35009 0.100799560546875 +35010 0.087127685546875 +35011 0.05487060546875 +35012 -0.009002685546875 +35013 -0.10400390625 +35014 -0.229400634765625 +35015 -0.35552978515625 +35016 -0.441925048828125 +35017 -0.473846435546875 +35018 -0.464813232421875 +35019 -0.419097900390625 +35020 -0.334320068359375 +35021 -0.227935791015625 +35022 -0.12347412109375 +35023 -0.02764892578125 +35024 0.077667236328125 +35025 0.2132568359375 +35026 0.38885498046875 +35027 0.582794189453125 +35028 0.734039306640625 +35029 0.800140380859375 +35030 0.7783203125 +35031 0.6651611328125 +35032 0.45965576171875 +35033 0.199188232421875 +35034 -0.050689697265625 +35035 -0.23297119140625 +35036 -0.33013916015625 +35037 -0.368408203125 +35038 -0.378936767578125 +35039 -0.376983642578125 +35040 -0.37969970703125 +35041 -0.391510009765625 +35042 -0.385345458984375 +35043 -0.3419189453125 +35044 -0.28289794921875 +35045 -0.251617431640625 +35046 -0.266143798828125 +35047 -0.273345947265625 +35048 -0.216796875 +35049 -0.128265380859375 +35050 -0.068145751953125 +35051 -0.0430908203125 +35052 -0.024444580078125 +35053 0.020721435546875 +35054 0.124481201171875 +35055 0.25787353515625 +35056 0.379119873046875 +35057 0.47991943359375 +35058 0.5281982421875 +35059 0.511138916015625 +35060 0.456207275390625 +35061 0.407470703125 +35062 0.383758544921875 +35063 0.35687255859375 +35064 0.31182861328125 +35065 0.250885009765625 +35066 0.1654052734375 +35067 0.035247802734375 +35068 -0.142059326171875 +35069 -0.33563232421875 +35070 -0.5345458984375 +35071 -0.72186279296875 +35072 -0.836669921875 +35073 -0.8326416015625 +35074 -0.7296142578125 +35075 -0.582550048828125 +35076 -0.440093994140625 +35077 -0.324310302734375 +35078 -0.20147705078125 +35079 -0.044647216796875 +35080 0.103973388671875 +35081 0.202392578125 +35082 0.264495849609375 +35083 0.338897705078125 +35084 0.443817138671875 +35085 0.545074462890625 +35086 0.6173095703125 +35087 0.6524658203125 +35088 0.66339111328125 +35089 0.6561279296875 +35090 0.606781005859375 +35091 0.501190185546875 +35092 0.352783203125 +35093 0.176544189453125 +35094 -0.034820556640625 +35095 -0.258209228515625 +35096 -0.44244384765625 +35097 -0.5753173828125 +35098 -0.65203857421875 +35099 -0.641632080078125 +35100 -0.562164306640625 +35101 -0.458038330078125 +35102 -0.350555419921875 +35103 -0.260528564453125 +35104 -0.192108154296875 +35105 -0.141937255859375 +35106 -0.1021728515625 +35107 -0.062896728515625 +35108 -0.011932373046875 +35109 0.062835693359375 +35110 0.148712158203125 +35111 0.241729736328125 +35112 0.34912109375 +35113 0.457305908203125 +35114 0.54388427734375 +35115 0.5728759765625 +35116 0.506591796875 +35117 0.351226806640625 +35118 0.146514892578125 +35119 -0.05523681640625 +35120 -0.21624755859375 +35121 -0.334930419921875 +35122 -0.402984619140625 +35123 -0.4412841796875 +35124 -0.49578857421875 +35125 -0.5601806640625 +35126 -0.600738525390625 +35127 -0.584228515625 +35128 -0.47930908203125 +35129 -0.27935791015625 +35130 -0.0089111328125 +35131 0.268798828125 +35132 0.482818603515625 +35133 0.60369873046875 +35134 0.650421142578125 +35135 0.66400146484375 +35136 0.6414794921875 +35137 0.572540283203125 +35138 0.498138427734375 +35139 0.439453125 +35140 0.375518798828125 +35141 0.274505615234375 +35142 0.1087646484375 +35143 -0.099395751953125 +35144 -0.3182373046875 +35145 -0.5489501953125 +35146 -0.7738037109375 +35147 -0.86383056640625 +35148 -0.870391845703125 +35149 -0.86895751953125 +35150 -0.861053466796875 +35151 -0.765869140625 +35152 -0.5301513671875 +35153 -0.214691162109375 +35154 0.137359619140625 +35155 0.474822998046875 +35156 0.76239013671875 +35157 0.867462158203125 +35158 0.870361328125 +35159 0.86480712890625 +35160 0.831817626953125 +35161 0.677581787109375 +35162 0.495880126953125 +35163 0.30767822265625 +35164 0.116180419921875 +35165 -0.110748291015625 +35166 -0.381805419921875 +35167 -0.6572265625 +35168 -0.857421875 +35169 -0.870391845703125 +35170 -0.870391845703125 +35171 -0.86444091796875 +35172 -0.85723876953125 +35173 -0.790008544921875 +35174 -0.62847900390625 +35175 -0.3956298828125 +35176 -0.126708984375 +35177 0.150115966796875 +35178 0.424041748046875 +35179 0.670623779296875 +35180 0.854522705078125 +35181 0.866485595703125 +35182 0.86920166015625 +35183 0.8653564453125 +35184 0.857147216796875 +35185 0.766845703125 +35186 0.628509521484375 +35187 0.462127685546875 +35188 0.297210693359375 +35189 0.14862060546875 +35190 -0.00537109375 +35191 -0.15753173828125 +35192 -0.31304931640625 +35193 -0.48876953125 +35194 -0.6416015625 +35195 -0.751373291015625 +35196 -0.84619140625 +35197 -0.861297607421875 +35198 -0.863250732421875 +35199 -0.856597900390625 +35200 -0.7498779296875 +35201 -0.624542236328125 +35202 -0.47808837890625 +35203 -0.253387451171875 +35204 0.003692626953125 +35205 0.2257080078125 +35206 0.427154541015625 +35207 0.643218994140625 +35208 0.855926513671875 +35209 0.870361328125 +35210 0.870361328125 +35211 0.862762451171875 +35212 0.79669189453125 +35213 0.595794677734375 +35214 0.362152099609375 +35215 0.1270751953125 +35216 -0.086944580078125 +35217 -0.2784423828125 +35218 -0.484832763671875 +35219 -0.729583740234375 +35220 -0.86688232421875 +35221 -0.870391845703125 +35222 -0.86859130859375 +35223 -0.86279296875 +35224 -0.817962646484375 +35225 -0.6116943359375 +35226 -0.3128662109375 +35227 0.039398193359375 +35228 0.422821044921875 +35229 0.805145263671875 +35230 0.870361328125 +35231 0.870361328125 +35232 0.860015869140625 +35233 0.727935791015625 +35234 0.48114013671875 +35235 0.2059326171875 +35236 -0.06103515625 +35237 -0.29913330078125 +35238 -0.516204833984375 +35239 -0.7252197265625 +35240 -0.85980224609375 +35241 -0.870391845703125 +35242 -0.870391845703125 +35243 -0.858062744140625 +35244 -0.673004150390625 +35245 -0.42694091796875 +35246 -0.2100830078125 +35247 -0.0362548828125 +35248 0.10943603515625 +35249 0.23516845703125 +35250 0.373687744140625 +35251 0.517791748046875 +35252 0.602783203125 +35253 0.635711669921875 +35254 0.655181884765625 +35255 0.65948486328125 +35256 0.651275634765625 +35257 0.61846923828125 +35258 0.53753662109375 +35259 0.404144287109375 +35260 0.22186279296875 +35261 0.003997802734375 +35262 -0.22100830078125 +35263 -0.42449951171875 +35264 -0.579833984375 +35265 -0.641876220703125 +35266 -0.6177978515625 +35267 -0.575531005859375 +35268 -0.526336669921875 +35269 -0.42645263671875 +35270 -0.2581787109375 +35271 -0.068695068359375 +35272 0.09222412109375 +35273 0.232147216796875 +35274 0.3509521484375 +35275 0.410064697265625 +35276 0.372955322265625 +35277 0.2554931640625 +35278 0.10711669921875 +35279 -0.052886962890625 +35280 -0.186279296875 +35281 -0.23291015625 +35282 -0.209442138671875 +35283 -0.174163818359375 +35284 -0.126739501953125 +35285 -0.048126220703125 +35286 0.0426025390625 +35287 0.10748291015625 +35288 0.1409912109375 +35289 0.19708251953125 +35290 0.273651123046875 +35291 0.31768798828125 +35292 0.341094970703125 +35293 0.368011474609375 +35294 0.37249755859375 +35295 0.30072021484375 +35296 0.1517333984375 +35297 -0.01470947265625 +35298 -0.1883544921875 +35299 -0.372711181640625 +35300 -0.51397705078125 +35301 -0.57177734375 +35302 -0.53948974609375 +35303 -0.43511962890625 +35304 -0.2962646484375 +35305 -0.161102294921875 +35306 -0.0435791015625 +35307 0.060394287109375 +35308 0.13665771484375 +35309 0.170135498046875 +35310 0.16552734375 +35311 0.15728759765625 +35312 0.150787353515625 +35313 0.12200927734375 +35314 0.080108642578125 +35315 0.05126953125 +35316 0.062896728515625 +35317 0.09271240234375 +35318 0.092987060546875 +35319 0.07855224609375 +35320 0.06427001953125 +35321 0.0347900390625 +35322 -0.01171875 +35323 -0.056060791015625 +35324 -0.055511474609375 +35325 -0.010467529296875 +35326 0.02508544921875 +35327 0.025665283203125 +35328 0.017333984375 +35329 0.00189208984375 +35330 -0.03173828125 +35331 -0.071502685546875 +35332 -0.13543701171875 +35333 -0.219970703125 +35334 -0.300506591796875 +35335 -0.376312255859375 +35336 -0.416107177734375 +35337 -0.371124267578125 +35338 -0.242279052734375 +35339 -0.069732666015625 +35340 0.125640869140625 +35341 0.31268310546875 +35342 0.45501708984375 +35343 0.554779052734375 +35344 0.61065673828125 +35345 0.610931396484375 +35346 0.531463623046875 +35347 0.3883056640625 +35348 0.23468017578125 +35349 0.095245361328125 +35350 -0.00396728515625 +35351 -0.04852294921875 +35352 -0.055145263671875 +35353 -0.0758056640625 +35354 -0.138702392578125 +35355 -0.209197998046875 +35356 -0.289031982421875 +35357 -0.37884521484375 +35358 -0.456329345703125 +35359 -0.51641845703125 +35360 -0.519287109375 +35361 -0.458251953125 +35362 -0.384796142578125 +35363 -0.323699951171875 +35364 -0.269287109375 +35365 -0.1951904296875 +35366 -0.100006103515625 +35367 -0.01055908203125 +35368 0.1033935546875 +35369 0.24908447265625 +35370 0.373199462890625 +35371 0.45806884765625 +35372 0.511474609375 +35373 0.565399169921875 +35374 0.61138916015625 +35375 0.5897216796875 +35376 0.4906005859375 +35377 0.33148193359375 +35378 0.147796630859375 +35379 -0.01873779296875 +35380 -0.140289306640625 +35381 -0.191986083984375 +35382 -0.184295654296875 +35383 -0.161834716796875 +35384 -0.166595458984375 +35385 -0.19390869140625 +35386 -0.22442626953125 +35387 -0.279754638671875 +35388 -0.3389892578125 +35389 -0.3543701171875 +35390 -0.348175048828125 +35391 -0.32598876953125 +35392 -0.2581787109375 +35393 -0.139801025390625 +35394 0.014617919921875 +35395 0.144378662109375 +35396 0.221038818359375 +35397 0.27069091796875 +35398 0.294036865234375 +35399 0.311767578125 +35400 0.339141845703125 +35401 0.360260009765625 +35402 0.360504150390625 +35403 0.308380126953125 +35404 0.18170166015625 +35405 0.0047607421875 +35406 -0.17559814453125 +35407 -0.3143310546875 +35408 -0.36785888671875 +35409 -0.36248779296875 +35410 -0.343536376953125 +35411 -0.3018798828125 +35412 -0.231414794921875 +35413 -0.117645263671875 +35414 0.007049560546875 +35415 0.087982177734375 +35416 0.13946533203125 +35417 0.17425537109375 +35418 0.188201904296875 +35419 0.171234130859375 +35420 0.118438720703125 +35421 0.05706787109375 +35422 -0.010711669921875 +35423 -0.0914306640625 +35424 -0.162322998046875 +35425 -0.194549560546875 +35426 -0.1492919921875 +35427 -0.02166748046875 +35428 0.124053955078125 +35429 0.211151123046875 +35430 0.240447998046875 +35431 0.242218017578125 +35432 0.2257080078125 +35433 0.194366455078125 +35434 0.115509033203125 +35435 0.0128173828125 +35436 -0.053802490234375 +35437 -0.110626220703125 +35438 -0.199493408203125 +35439 -0.29437255859375 +35440 -0.33221435546875 +35441 -0.27972412109375 +35442 -0.185333251953125 +35443 -0.128204345703125 +35444 -0.115692138671875 +35445 -0.116455078125 +35446 -0.105926513671875 +35447 -0.053955078125 +35448 0.048797607421875 +35449 0.157318115234375 +35450 0.212005615234375 +35451 0.218475341796875 +35452 0.23724365234375 +35453 0.30535888671875 +35454 0.38128662109375 +35455 0.404449462890625 +35456 0.3944091796875 +35457 0.3885498046875 +35458 0.362640380859375 +35459 0.27362060546875 +35460 0.11712646484375 +35461 -0.054901123046875 +35462 -0.19085693359375 +35463 -0.28570556640625 +35464 -0.339263916015625 +35465 -0.3775634765625 +35466 -0.445709228515625 +35467 -0.535064697265625 +35468 -0.629058837890625 +35469 -0.697601318359375 +35470 -0.70391845703125 +35471 -0.6424560546875 +35472 -0.491241455078125 +35473 -0.265716552734375 +35474 -0.023712158203125 +35475 0.201751708984375 +35476 0.375823974609375 +35477 0.485076904296875 +35478 0.56884765625 +35479 0.634765625 +35480 0.63763427734375 +35481 0.5660400390625 +35482 0.4720458984375 +35483 0.40692138671875 +35484 0.3778076171875 +35485 0.376953125 +35486 0.371978759765625 +35487 0.313140869140625 +35488 0.184417724609375 +35489 0.011199951171875 +35490 -0.171051025390625 +35491 -0.33740234375 +35492 -0.47198486328125 +35493 -0.560394287109375 +35494 -0.58056640625 +35495 -0.54754638671875 +35496 -0.508575439453125 +35497 -0.459503173828125 +35498 -0.394378662109375 +35499 -0.35260009765625 +35500 -0.31170654296875 +35501 -0.197418212890625 +35502 -0.007965087890625 +35503 0.207489013671875 +35504 0.409210205078125 +35505 0.57208251953125 +35506 0.66595458984375 +35507 0.65875244140625 +35508 0.56744384765625 +35509 0.431396484375 +35510 0.29443359375 +35511 0.182464599609375 +35512 0.06365966796875 +35513 -0.075958251953125 +35514 -0.189422607421875 +35515 -0.271942138671875 +35516 -0.342529296875 +35517 -0.364166259765625 +35518 -0.327239990234375 +35519 -0.2769775390625 +35520 -0.253692626953125 +35521 -0.24365234375 +35522 -0.1983642578125 +35523 -0.116241455078125 +35524 -0.036834716796875 +35525 0.034881591796875 +35526 0.09124755859375 +35527 0.10888671875 +35528 0.125518798828125 +35529 0.15771484375 +35530 0.17828369140625 +35531 0.17108154296875 +35532 0.129974365234375 +35533 0.082427978515625 +35534 0.027679443359375 +35535 -0.065643310546875 +35536 -0.15936279296875 +35537 -0.21307373046875 +35538 -0.234649658203125 +35539 -0.2001953125 +35540 -0.119171142578125 +35541 -0.024749755859375 +35542 0.085784912109375 +35543 0.178131103515625 +35544 0.215576171875 +35545 0.211456298828125 +35546 0.17523193359375 +35547 0.128753662109375 +35548 0.1019287109375 +35549 0.0743408203125 +35550 0.04327392578125 +35551 0.038177490234375 +35552 0.076263427734375 +35553 0.14105224609375 +35554 0.186431884765625 +35555 0.188812255859375 +35556 0.1390380859375 +35557 0.041778564453125 +35558 -0.079437255859375 +35559 -0.219390869140625 +35560 -0.367828369140625 +35561 -0.494873046875 +35562 -0.556243896484375 +35563 -0.508697509765625 +35564 -0.3756103515625 +35565 -0.218902587890625 +35566 -0.063751220703125 +35567 0.091552734375 +35568 0.23602294921875 +35569 0.342987060546875 +35570 0.39520263671875 +35571 0.389373779296875 +35572 0.324249267578125 +35573 0.224090576171875 +35574 0.124267578125 +35575 0.037078857421875 +35576 -0.010101318359375 +35577 -0.019439697265625 +35578 -0.022796630859375 +35579 -0.001556396484375 +35580 0.056304931640625 +35581 0.106719970703125 +35582 0.096893310546875 +35583 0.042694091796875 +35584 -0.018035888671875 +35585 -0.07586669921875 +35586 -0.11944580078125 +35587 -0.15972900390625 +35588 -0.202606201171875 +35589 -0.24859619140625 +35590 -0.30517578125 +35591 -0.36212158203125 +35592 -0.39141845703125 +35593 -0.35528564453125 +35594 -0.249969482421875 +35595 -0.092864990234375 +35596 0.08905029296875 +35597 0.2352294921875 +35598 0.318817138671875 +35599 0.358642578125 +35600 0.347747802734375 +35601 0.28564453125 +35602 0.223175048828125 +35603 0.196746826171875 +35604 0.179840087890625 +35605 0.155548095703125 +35606 0.151214599609375 +35607 0.156951904296875 +35608 0.13177490234375 +35609 0.100799560546875 +35610 0.087127685546875 +35611 0.05487060546875 +35612 -0.009002685546875 +35613 -0.10400390625 +35614 -0.229400634765625 +35615 -0.35552978515625 +35616 -0.441925048828125 +35617 -0.473846435546875 +35618 -0.464813232421875 +35619 -0.419097900390625 +35620 -0.334320068359375 +35621 -0.227935791015625 +35622 -0.12347412109375 +35623 -0.02764892578125 +35624 0.077667236328125 +35625 0.2132568359375 +35626 0.38885498046875 +35627 0.582794189453125 +35628 0.734039306640625 +35629 0.800140380859375 +35630 0.7783203125 +35631 0.6651611328125 +35632 0.45965576171875 +35633 0.199188232421875 +35634 -0.050689697265625 +35635 -0.23297119140625 +35636 -0.33013916015625 +35637 -0.368408203125 +35638 -0.378936767578125 +35639 -0.376983642578125 +35640 -0.37969970703125 +35641 -0.391510009765625 +35642 -0.385345458984375 +35643 -0.3419189453125 +35644 -0.28289794921875 +35645 -0.251617431640625 +35646 -0.266143798828125 +35647 -0.273345947265625 +35648 -0.216796875 +35649 -0.128265380859375 +35650 -0.068145751953125 +35651 -0.0430908203125 +35652 -0.024444580078125 +35653 0.020721435546875 +35654 0.124481201171875 +35655 0.25787353515625 +35656 0.379119873046875 +35657 0.47991943359375 +35658 0.5281982421875 +35659 0.511138916015625 +35660 0.456207275390625 +35661 0.407470703125 +35662 0.383758544921875 +35663 0.35687255859375 +35664 0.31182861328125 +35665 0.250885009765625 +35666 0.1654052734375 +35667 0.035247802734375 +35668 -0.142059326171875 +35669 -0.33563232421875 +35670 -0.5345458984375 +35671 -0.72186279296875 +35672 -0.836669921875 +35673 -0.8326416015625 +35674 -0.7296142578125 +35675 -0.582550048828125 +35676 -0.440093994140625 +35677 -0.324310302734375 +35678 -0.20147705078125 +35679 -0.044647216796875 +35680 0.103973388671875 +35681 0.202392578125 +35682 0.264495849609375 +35683 0.338897705078125 +35684 0.443817138671875 +35685 0.545074462890625 +35686 0.6173095703125 +35687 0.6524658203125 +35688 0.66339111328125 +35689 0.6561279296875 +35690 0.606781005859375 +35691 0.501190185546875 +35692 0.352783203125 +35693 0.176544189453125 +35694 -0.034820556640625 +35695 -0.258209228515625 +35696 -0.44244384765625 +35697 -0.5753173828125 +35698 -0.65203857421875 +35699 -0.641632080078125 +35700 -0.562164306640625 +35701 -0.458038330078125 +35702 -0.350555419921875 +35703 -0.260528564453125 +35704 -0.192108154296875 +35705 -0.141937255859375 +35706 -0.1021728515625 +35707 -0.062896728515625 +35708 -0.011932373046875 +35709 0.062835693359375 +35710 0.148712158203125 +35711 0.241729736328125 +35712 0.34912109375 +35713 0.457305908203125 +35714 0.54388427734375 +35715 0.5728759765625 +35716 0.506591796875 +35717 0.351226806640625 +35718 0.146514892578125 +35719 -0.05523681640625 +35720 -0.21624755859375 +35721 -0.334930419921875 +35722 -0.402984619140625 +35723 -0.4412841796875 +35724 -0.49578857421875 +35725 -0.5601806640625 +35726 -0.600738525390625 +35727 -0.584228515625 +35728 -0.47930908203125 +35729 -0.27935791015625 +35730 -0.0089111328125 +35731 0.268798828125 +35732 0.482818603515625 +35733 0.60369873046875 +35734 0.650421142578125 +35735 0.66400146484375 +35736 0.6414794921875 +35737 0.572540283203125 +35738 0.498138427734375 +35739 0.439453125 +35740 0.375518798828125 +35741 0.274505615234375 +35742 0.1087646484375 +35743 -0.099395751953125 +35744 -0.3182373046875 +35745 -0.5489501953125 +35746 -0.7738037109375 +35747 -0.86383056640625 +35748 -0.870391845703125 +35749 -0.86895751953125 +35750 -0.861053466796875 +35751 -0.765869140625 +35752 -0.5301513671875 +35753 -0.214691162109375 +35754 0.137359619140625 +35755 0.474822998046875 +35756 0.76239013671875 +35757 0.867462158203125 +35758 0.870361328125 +35759 0.86480712890625 +35760 0.831817626953125 +35761 0.677581787109375 +35762 0.495880126953125 +35763 0.30767822265625 +35764 0.116180419921875 +35765 -0.110748291015625 +35766 -0.381805419921875 +35767 -0.6572265625 +35768 -0.857421875 +35769 -0.870391845703125 +35770 -0.870391845703125 +35771 -0.86444091796875 +35772 -0.85723876953125 +35773 -0.790008544921875 +35774 -0.62847900390625 +35775 -0.3956298828125 +35776 -0.126708984375 +35777 0.150115966796875 +35778 0.424041748046875 +35779 0.670623779296875 +35780 0.854522705078125 +35781 0.866485595703125 +35782 0.86920166015625 +35783 0.8653564453125 +35784 0.857147216796875 +35785 0.766845703125 +35786 0.628509521484375 +35787 0.462127685546875 +35788 0.297210693359375 +35789 0.14862060546875 +35790 -0.00537109375 +35791 -0.15753173828125 +35792 -0.31304931640625 +35793 -0.48876953125 +35794 -0.6416015625 +35795 -0.751373291015625 +35796 -0.84619140625 +35797 -0.861297607421875 +35798 -0.863250732421875 +35799 -0.856597900390625 +35800 -0.7498779296875 +35801 -0.624542236328125 +35802 -0.47808837890625 +35803 -0.253387451171875 +35804 0.003692626953125 +35805 0.2257080078125 +35806 0.427154541015625 +35807 0.643218994140625 +35808 0.855926513671875 +35809 0.870361328125 +35810 0.870361328125 +35811 0.862762451171875 +35812 0.79669189453125 +35813 0.595794677734375 +35814 0.362152099609375 +35815 0.1270751953125 +35816 -0.086944580078125 +35817 -0.2784423828125 +35818 -0.484832763671875 +35819 -0.729583740234375 +35820 -0.86688232421875 +35821 -0.870391845703125 +35822 -0.86859130859375 +35823 -0.86279296875 +35824 -0.817962646484375 +35825 -0.6116943359375 +35826 -0.3128662109375 +35827 0.039398193359375 +35828 0.422821044921875 +35829 0.805145263671875 +35830 0.870361328125 +35831 0.870361328125 +35832 0.860015869140625 +35833 0.727935791015625 +35834 0.48114013671875 +35835 0.2059326171875 +35836 -0.06103515625 +35837 -0.29913330078125 +35838 -0.516204833984375 +35839 -0.7252197265625 +35840 -0.85980224609375 +35841 -0.870391845703125 +35842 -0.870391845703125 +35843 -0.858062744140625 +35844 -0.673004150390625 +35845 -0.42694091796875 +35846 -0.2100830078125 +35847 -0.0362548828125 +35848 0.10943603515625 +35849 0.23516845703125 +35850 0.373687744140625 +35851 0.517791748046875 +35852 0.602783203125 +35853 0.635711669921875 +35854 0.655181884765625 +35855 0.65948486328125 +35856 0.651275634765625 +35857 0.61846923828125 +35858 0.53753662109375 +35859 0.404144287109375 +35860 0.22186279296875 +35861 0.003997802734375 +35862 -0.22100830078125 +35863 -0.42449951171875 +35864 -0.579833984375 +35865 -0.641876220703125 +35866 -0.6177978515625 +35867 -0.575531005859375 +35868 -0.526336669921875 +35869 -0.42645263671875 +35870 -0.2581787109375 +35871 -0.068695068359375 +35872 0.09222412109375 +35873 0.232147216796875 +35874 0.3509521484375 +35875 0.410064697265625 +35876 0.372955322265625 +35877 0.2554931640625 +35878 0.10711669921875 +35879 -0.052886962890625 +35880 -0.186279296875 +35881 -0.23291015625 +35882 -0.209442138671875 +35883 -0.174163818359375 +35884 -0.126739501953125 +35885 -0.048126220703125 +35886 0.0426025390625 +35887 0.10748291015625 +35888 0.1409912109375 +35889 0.19708251953125 +35890 0.273651123046875 +35891 0.31768798828125 +35892 0.341094970703125 +35893 0.368011474609375 +35894 0.37249755859375 +35895 0.30072021484375 +35896 0.1517333984375 +35897 -0.01470947265625 +35898 -0.1883544921875 +35899 -0.372711181640625 +35900 -0.51397705078125 +35901 -0.57177734375 +35902 -0.53948974609375 +35903 -0.43511962890625 +35904 -0.2962646484375 +35905 -0.161102294921875 +35906 -0.0435791015625 +35907 0.060394287109375 +35908 0.13665771484375 +35909 0.170135498046875 +35910 0.16552734375 +35911 0.15728759765625 +35912 0.150787353515625 +35913 0.12200927734375 +35914 0.080108642578125 +35915 0.05126953125 +35916 0.062896728515625 +35917 0.09271240234375 +35918 0.092987060546875 +35919 0.07855224609375 +35920 0.06427001953125 +35921 0.0347900390625 +35922 -0.01171875 +35923 -0.056060791015625 +35924 -0.055511474609375 +35925 -0.010467529296875 +35926 0.02508544921875 +35927 0.025665283203125 +35928 0.017333984375 +35929 0.00189208984375 +35930 -0.03173828125 +35931 -0.071502685546875 +35932 -0.13543701171875 +35933 -0.219970703125 +35934 -0.300506591796875 +35935 -0.376312255859375 +35936 -0.416107177734375 +35937 -0.371124267578125 +35938 -0.242279052734375 +35939 -0.069732666015625 +35940 0.125640869140625 +35941 0.31268310546875 +35942 0.45501708984375 +35943 0.554779052734375 +35944 0.61065673828125 +35945 0.610931396484375 +35946 0.531463623046875 +35947 0.3883056640625 +35948 0.23468017578125 +35949 0.095245361328125 +35950 -0.00396728515625 +35951 -0.04852294921875 +35952 -0.055145263671875 +35953 -0.0758056640625 +35954 -0.138702392578125 +35955 -0.209197998046875 +35956 -0.289031982421875 +35957 -0.37884521484375 +35958 -0.456329345703125 +35959 -0.51641845703125 +35960 -0.519287109375 +35961 -0.458251953125 +35962 -0.384796142578125 +35963 -0.323699951171875 +35964 -0.269287109375 +35965 -0.1951904296875 +35966 -0.100006103515625 +35967 -0.01055908203125 +35968 0.1033935546875 +35969 0.24908447265625 +35970 0.373199462890625 +35971 0.45806884765625 +35972 0.511474609375 +35973 0.565399169921875 +35974 0.61138916015625 +35975 0.5897216796875 +35976 0.4906005859375 +35977 0.33148193359375 +35978 0.147796630859375 +35979 -0.01873779296875 +35980 -0.140289306640625 +35981 -0.191986083984375 +35982 -0.184295654296875 +35983 -0.161834716796875 +35984 -0.166595458984375 +35985 -0.19390869140625 +35986 -0.22442626953125 +35987 -0.279754638671875 +35988 -0.3389892578125 +35989 -0.3543701171875 +35990 -0.348175048828125 +35991 -0.32598876953125 +35992 -0.2581787109375 +35993 -0.139801025390625 +35994 0.014617919921875 +35995 0.144378662109375 +35996 0.221038818359375 +35997 0.27069091796875 +35998 0.294036865234375 +35999 0.311767578125 +36000 0.339141845703125 +36001 0.360260009765625 +36002 0.360504150390625 +36003 0.308380126953125 +36004 0.18170166015625 +36005 0.0047607421875 +36006 -0.17559814453125 +36007 -0.3143310546875 +36008 -0.36785888671875 +36009 -0.36248779296875 +36010 -0.343536376953125 +36011 -0.3018798828125 +36012 -0.231414794921875 +36013 -0.117645263671875 +36014 0.007049560546875 +36015 0.087982177734375 +36016 0.13946533203125 +36017 0.17425537109375 +36018 0.188201904296875 +36019 0.171234130859375 +36020 0.118438720703125 +36021 0.05706787109375 +36022 -0.010711669921875 +36023 -0.0914306640625 +36024 -0.162322998046875 +36025 -0.194549560546875 +36026 -0.1492919921875 +36027 -0.02166748046875 +36028 0.124053955078125 +36029 0.211151123046875 +36030 0.240447998046875 +36031 0.242218017578125 +36032 0.2257080078125 +36033 0.194366455078125 +36034 0.115509033203125 +36035 0.0128173828125 +36036 -0.053802490234375 +36037 -0.110626220703125 +36038 -0.199493408203125 +36039 -0.29437255859375 +36040 -0.33221435546875 +36041 -0.27972412109375 +36042 -0.185333251953125 +36043 -0.128204345703125 +36044 -0.115692138671875 +36045 -0.116455078125 +36046 -0.105926513671875 +36047 -0.053955078125 +36048 0.048797607421875 +36049 0.157318115234375 +36050 0.212005615234375 +36051 0.218475341796875 +36052 0.23724365234375 +36053 0.30535888671875 +36054 0.38128662109375 +36055 0.404449462890625 +36056 0.3944091796875 +36057 0.3885498046875 +36058 0.362640380859375 +36059 0.27362060546875 +36060 0.11712646484375 +36061 -0.054901123046875 +36062 -0.19085693359375 +36063 -0.28570556640625 +36064 -0.339263916015625 +36065 -0.3775634765625 +36066 -0.445709228515625 +36067 -0.535064697265625 +36068 -0.629058837890625 +36069 -0.697601318359375 +36070 -0.70391845703125 +36071 -0.6424560546875 +36072 -0.491241455078125 +36073 -0.265716552734375 +36074 -0.023712158203125 +36075 0.201751708984375 +36076 0.375823974609375 +36077 0.485076904296875 +36078 0.56884765625 +36079 0.634765625 +36080 0.63763427734375 +36081 0.5660400390625 +36082 0.4720458984375 +36083 0.40692138671875 +36084 0.3778076171875 +36085 0.376953125 +36086 0.371978759765625 +36087 0.313140869140625 +36088 0.184417724609375 +36089 0.011199951171875 +36090 -0.171051025390625 +36091 -0.33740234375 +36092 -0.47198486328125 +36093 -0.560394287109375 +36094 -0.58056640625 +36095 -0.54754638671875 +36096 -0.508575439453125 +36097 -0.459503173828125 +36098 -0.394378662109375 +36099 -0.35260009765625 +36100 -0.31170654296875 +36101 -0.197418212890625 +36102 -0.007965087890625 +36103 0.207489013671875 +36104 0.409210205078125 +36105 0.57208251953125 +36106 0.66595458984375 +36107 0.65875244140625 +36108 0.56744384765625 +36109 0.431396484375 +36110 0.29443359375 +36111 0.182464599609375 +36112 0.06365966796875 +36113 -0.075958251953125 +36114 -0.189422607421875 +36115 -0.271942138671875 +36116 -0.342529296875 +36117 -0.364166259765625 +36118 -0.327239990234375 +36119 -0.2769775390625 +36120 -0.253692626953125 +36121 -0.24365234375 +36122 -0.1983642578125 +36123 -0.116241455078125 +36124 -0.036834716796875 +36125 0.034881591796875 +36126 0.09124755859375 +36127 0.10888671875 +36128 0.125518798828125 +36129 0.15771484375 +36130 0.17828369140625 +36131 0.17108154296875 +36132 0.129974365234375 +36133 0.082427978515625 +36134 0.027679443359375 +36135 -0.065643310546875 +36136 -0.15936279296875 +36137 -0.21307373046875 +36138 -0.234649658203125 +36139 -0.2001953125 +36140 -0.119171142578125 +36141 -0.024749755859375 +36142 0.085784912109375 +36143 0.178131103515625 +36144 0.215576171875 +36145 0.211456298828125 +36146 0.17523193359375 +36147 0.128753662109375 +36148 0.1019287109375 +36149 0.0743408203125 +36150 0.04327392578125 +36151 0.038177490234375 +36152 0.076263427734375 +36153 0.14105224609375 +36154 0.186431884765625 +36155 0.188812255859375 +36156 0.1390380859375 +36157 0.041778564453125 +36158 -0.079437255859375 +36159 -0.219390869140625 +36160 -0.367828369140625 +36161 -0.494873046875 +36162 -0.556243896484375 +36163 -0.508697509765625 +36164 -0.3756103515625 +36165 -0.218902587890625 +36166 -0.063751220703125 +36167 0.091552734375 +36168 0.23602294921875 +36169 0.342987060546875 +36170 0.39520263671875 +36171 0.389373779296875 +36172 0.324249267578125 +36173 0.224090576171875 +36174 0.124267578125 +36175 0.037078857421875 +36176 -0.010101318359375 +36177 -0.019439697265625 +36178 -0.022796630859375 +36179 -0.001556396484375 +36180 0.056304931640625 +36181 0.106719970703125 +36182 0.096893310546875 +36183 0.042694091796875 +36184 -0.018035888671875 +36185 -0.07586669921875 +36186 -0.11944580078125 +36187 -0.15972900390625 +36188 -0.202606201171875 +36189 -0.24859619140625 +36190 -0.30517578125 +36191 -0.36212158203125 +36192 -0.39141845703125 +36193 -0.35528564453125 +36194 -0.249969482421875 +36195 -0.092864990234375 +36196 0.08905029296875 +36197 0.2352294921875 +36198 0.318817138671875 +36199 0.358642578125 +36200 0.347747802734375 +36201 0.28564453125 +36202 0.223175048828125 +36203 0.196746826171875 +36204 0.179840087890625 +36205 0.155548095703125 +36206 0.151214599609375 +36207 0.156951904296875 +36208 0.13177490234375 +36209 0.100799560546875 +36210 0.087127685546875 +36211 0.05487060546875 +36212 -0.009002685546875 +36213 -0.10400390625 +36214 -0.229400634765625 +36215 -0.35552978515625 +36216 -0.441925048828125 +36217 -0.473846435546875 +36218 -0.464813232421875 +36219 -0.419097900390625 +36220 -0.334320068359375 +36221 -0.227935791015625 +36222 -0.12347412109375 +36223 -0.02764892578125 +36224 0.077667236328125 +36225 0.2132568359375 +36226 0.38885498046875 +36227 0.582794189453125 +36228 0.734039306640625 +36229 0.800140380859375 +36230 0.7783203125 +36231 0.6651611328125 +36232 0.45965576171875 +36233 0.199188232421875 +36234 -0.050689697265625 +36235 -0.23297119140625 +36236 -0.33013916015625 +36237 -0.368408203125 +36238 -0.378936767578125 +36239 -0.376983642578125 +36240 -0.37969970703125 +36241 -0.391510009765625 +36242 -0.385345458984375 +36243 -0.3419189453125 +36244 -0.28289794921875 +36245 -0.251617431640625 +36246 -0.266143798828125 +36247 -0.273345947265625 +36248 -0.216796875 +36249 -0.128265380859375 +36250 -0.068145751953125 +36251 -0.0430908203125 +36252 -0.024444580078125 +36253 0.020721435546875 +36254 0.124481201171875 +36255 0.25787353515625 +36256 0.379119873046875 +36257 0.47991943359375 +36258 0.5281982421875 +36259 0.511138916015625 +36260 0.456207275390625 +36261 0.407470703125 +36262 0.383758544921875 +36263 0.35687255859375 +36264 0.31182861328125 +36265 0.250885009765625 +36266 0.1654052734375 +36267 0.035247802734375 +36268 -0.142059326171875 +36269 -0.33563232421875 +36270 -0.5345458984375 +36271 -0.72186279296875 +36272 -0.836669921875 +36273 -0.8326416015625 +36274 -0.7296142578125 +36275 -0.582550048828125 +36276 -0.440093994140625 +36277 -0.324310302734375 +36278 -0.20147705078125 +36279 -0.044647216796875 +36280 0.103973388671875 +36281 0.202392578125 +36282 0.264495849609375 +36283 0.338897705078125 +36284 0.443817138671875 +36285 0.545074462890625 +36286 0.6173095703125 +36287 0.6524658203125 +36288 0.66339111328125 +36289 0.6561279296875 +36290 0.606781005859375 +36291 0.501190185546875 +36292 0.352783203125 +36293 0.176544189453125 +36294 -0.034820556640625 +36295 -0.258209228515625 +36296 -0.44244384765625 +36297 -0.5753173828125 +36298 -0.65203857421875 +36299 -0.641632080078125 +36300 -0.562164306640625 +36301 -0.458038330078125 +36302 -0.350555419921875 +36303 -0.260528564453125 +36304 -0.192108154296875 +36305 -0.141937255859375 +36306 -0.1021728515625 +36307 -0.062896728515625 +36308 -0.011932373046875 +36309 0.062835693359375 +36310 0.148712158203125 +36311 0.241729736328125 +36312 0.34912109375 +36313 0.457305908203125 +36314 0.54388427734375 +36315 0.5728759765625 +36316 0.506591796875 +36317 0.351226806640625 +36318 0.146514892578125 +36319 -0.05523681640625 +36320 -0.21624755859375 +36321 -0.334930419921875 +36322 -0.402984619140625 +36323 -0.4412841796875 +36324 -0.49578857421875 +36325 -0.5601806640625 +36326 -0.600738525390625 +36327 -0.584228515625 +36328 -0.47930908203125 +36329 -0.27935791015625 +36330 -0.0089111328125 +36331 0.268798828125 +36332 0.482818603515625 +36333 0.60369873046875 +36334 0.650421142578125 +36335 0.66400146484375 +36336 0.6414794921875 +36337 0.572540283203125 +36338 0.498138427734375 +36339 0.439453125 +36340 0.375518798828125 +36341 0.274505615234375 +36342 0.1087646484375 +36343 -0.099395751953125 +36344 -0.3182373046875 +36345 -0.5489501953125 +36346 -0.7738037109375 +36347 -0.86383056640625 +36348 -0.870391845703125 +36349 -0.86895751953125 +36350 -0.861053466796875 +36351 -0.765869140625 +36352 -0.5301513671875 +36353 -0.214691162109375 +36354 0.137359619140625 +36355 0.474822998046875 +36356 0.76239013671875 +36357 0.867462158203125 +36358 0.870361328125 +36359 0.86480712890625 +36360 0.831817626953125 +36361 0.677581787109375 +36362 0.495880126953125 +36363 0.30767822265625 +36364 0.116180419921875 +36365 -0.110748291015625 +36366 -0.381805419921875 +36367 -0.6572265625 +36368 -0.857421875 +36369 -0.870391845703125 +36370 -0.870391845703125 +36371 -0.86444091796875 +36372 -0.85723876953125 +36373 -0.790008544921875 +36374 -0.62847900390625 +36375 -0.3956298828125 +36376 -0.126708984375 +36377 0.150115966796875 +36378 0.424041748046875 +36379 0.670623779296875 +36380 0.854522705078125 +36381 0.866485595703125 +36382 0.86920166015625 +36383 0.8653564453125 +36384 0.857147216796875 +36385 0.766845703125 +36386 0.628509521484375 +36387 0.462127685546875 +36388 0.297210693359375 +36389 0.14862060546875 +36390 -0.00537109375 +36391 -0.15753173828125 +36392 -0.31304931640625 +36393 -0.48876953125 +36394 -0.6416015625 +36395 -0.751373291015625 +36396 -0.84619140625 +36397 -0.861297607421875 +36398 -0.863250732421875 +36399 -0.856597900390625 +36400 -0.7498779296875 +36401 -0.624542236328125 +36402 -0.47808837890625 +36403 -0.253387451171875 +36404 0.003692626953125 +36405 0.2257080078125 +36406 0.427154541015625 +36407 0.643218994140625 +36408 0.855926513671875 +36409 0.870361328125 +36410 0.870361328125 +36411 0.862762451171875 +36412 0.79669189453125 +36413 0.595794677734375 +36414 0.362152099609375 +36415 0.1270751953125 +36416 -0.086944580078125 +36417 -0.2784423828125 +36418 -0.484832763671875 +36419 -0.729583740234375 +36420 -0.86688232421875 +36421 -0.870391845703125 +36422 -0.86859130859375 +36423 -0.86279296875 +36424 -0.817962646484375 +36425 -0.6116943359375 +36426 -0.3128662109375 +36427 0.039398193359375 +36428 0.422821044921875 +36429 0.805145263671875 +36430 0.870361328125 +36431 0.870361328125 +36432 0.860015869140625 +36433 0.727935791015625 +36434 0.48114013671875 +36435 0.2059326171875 +36436 -0.06103515625 +36437 -0.29913330078125 +36438 -0.516204833984375 +36439 -0.7252197265625 +36440 -0.85980224609375 +36441 -0.870391845703125 +36442 -0.870391845703125 +36443 -0.858062744140625 +36444 -0.673004150390625 +36445 -0.42694091796875 +36446 -0.2100830078125 +36447 -0.0362548828125 +36448 0.10943603515625 +36449 0.23516845703125 +36450 0.373687744140625 +36451 0.517791748046875 +36452 0.602783203125 +36453 0.635711669921875 +36454 0.655181884765625 +36455 0.65948486328125 +36456 0.651275634765625 +36457 0.61846923828125 +36458 0.53753662109375 +36459 0.404144287109375 +36460 0.22186279296875 +36461 0.003997802734375 +36462 -0.22100830078125 +36463 -0.42449951171875 +36464 -0.579833984375 +36465 -0.641876220703125 +36466 -0.6177978515625 +36467 -0.575531005859375 +36468 -0.526336669921875 +36469 -0.42645263671875 +36470 -0.2581787109375 +36471 -0.068695068359375 +36472 0.09222412109375 +36473 0.232147216796875 +36474 0.3509521484375 +36475 0.410064697265625 +36476 0.372955322265625 +36477 0.2554931640625 +36478 0.10711669921875 +36479 -0.052886962890625 +36480 -0.186279296875 +36481 -0.23291015625 +36482 -0.209442138671875 +36483 -0.174163818359375 +36484 -0.126739501953125 +36485 -0.048126220703125 +36486 0.0426025390625 +36487 0.10748291015625 +36488 0.1409912109375 +36489 0.19708251953125 +36490 0.273651123046875 +36491 0.31768798828125 +36492 0.341094970703125 +36493 0.368011474609375 +36494 0.37249755859375 +36495 0.30072021484375 +36496 0.1517333984375 +36497 -0.01470947265625 +36498 -0.1883544921875 +36499 -0.372711181640625 +36500 -0.51397705078125 +36501 -0.57177734375 +36502 -0.53948974609375 +36503 -0.43511962890625 +36504 -0.2962646484375 +36505 -0.161102294921875 +36506 -0.0435791015625 +36507 0.060394287109375 +36508 0.13665771484375 +36509 0.170135498046875 +36510 0.16552734375 +36511 0.15728759765625 +36512 0.150787353515625 +36513 0.12200927734375 +36514 0.080108642578125 +36515 0.05126953125 +36516 0.062896728515625 +36517 0.09271240234375 +36518 0.092987060546875 +36519 0.07855224609375 +36520 0.06427001953125 +36521 0.0347900390625 +36522 -0.01171875 +36523 -0.056060791015625 +36524 -0.055511474609375 +36525 -0.010467529296875 +36526 0.02508544921875 +36527 0.025665283203125 +36528 0.017333984375 +36529 0.00189208984375 +36530 -0.03173828125 +36531 -0.071502685546875 +36532 -0.13543701171875 +36533 -0.219970703125 +36534 -0.300506591796875 +36535 -0.376312255859375 +36536 -0.416107177734375 +36537 -0.371124267578125 +36538 -0.242279052734375 +36539 -0.069732666015625 +36540 0.125640869140625 +36541 0.31268310546875 +36542 0.45501708984375 +36543 0.554779052734375 +36544 0.61065673828125 +36545 0.610931396484375 +36546 0.531463623046875 +36547 0.3883056640625 +36548 0.23468017578125 +36549 0.095245361328125 +36550 -0.00396728515625 +36551 -0.04852294921875 +36552 -0.055145263671875 +36553 -0.0758056640625 +36554 -0.138702392578125 +36555 -0.209197998046875 +36556 -0.289031982421875 +36557 -0.37884521484375 +36558 -0.456329345703125 +36559 -0.51641845703125 +36560 -0.519287109375 +36561 -0.458251953125 +36562 -0.384796142578125 +36563 -0.323699951171875 +36564 -0.269287109375 +36565 -0.1951904296875 +36566 -0.100006103515625 +36567 -0.01055908203125 +36568 0.1033935546875 +36569 0.24908447265625 +36570 0.373199462890625 +36571 0.45806884765625 +36572 0.511474609375 +36573 0.565399169921875 +36574 0.61138916015625 +36575 0.5897216796875 +36576 0.4906005859375 +36577 0.33148193359375 +36578 0.147796630859375 +36579 -0.01873779296875 +36580 -0.140289306640625 +36581 -0.191986083984375 +36582 -0.184295654296875 +36583 -0.161834716796875 +36584 -0.166595458984375 +36585 -0.19390869140625 +36586 -0.22442626953125 +36587 -0.279754638671875 +36588 -0.3389892578125 +36589 -0.3543701171875 +36590 -0.348175048828125 +36591 -0.32598876953125 +36592 -0.2581787109375 +36593 -0.139801025390625 +36594 0.014617919921875 +36595 0.144378662109375 +36596 0.221038818359375 +36597 0.27069091796875 +36598 0.294036865234375 +36599 0.311767578125 +36600 0.339141845703125 +36601 0.360260009765625 +36602 0.360504150390625 +36603 0.308380126953125 +36604 0.18170166015625 +36605 0.0047607421875 +36606 -0.17559814453125 +36607 -0.3143310546875 +36608 -0.36785888671875 +36609 -0.36248779296875 +36610 -0.343536376953125 +36611 -0.3018798828125 +36612 -0.231414794921875 +36613 -0.117645263671875 +36614 0.007049560546875 +36615 0.087982177734375 +36616 0.13946533203125 +36617 0.17425537109375 +36618 0.188201904296875 +36619 0.171234130859375 +36620 0.118438720703125 +36621 0.05706787109375 +36622 -0.010711669921875 +36623 -0.0914306640625 +36624 -0.162322998046875 +36625 -0.194549560546875 +36626 -0.1492919921875 +36627 -0.02166748046875 +36628 0.124053955078125 +36629 0.211151123046875 +36630 0.240447998046875 +36631 0.242218017578125 +36632 0.2257080078125 +36633 0.194366455078125 +36634 0.115509033203125 +36635 0.0128173828125 +36636 -0.053802490234375 +36637 -0.110626220703125 +36638 -0.199493408203125 +36639 -0.29437255859375 +36640 -0.33221435546875 +36641 -0.27972412109375 +36642 -0.185333251953125 +36643 -0.128204345703125 +36644 -0.115692138671875 +36645 -0.116455078125 +36646 -0.105926513671875 +36647 -0.053955078125 +36648 0.048797607421875 +36649 0.157318115234375 +36650 0.212005615234375 +36651 0.218475341796875 +36652 0.23724365234375 +36653 0.30535888671875 +36654 0.38128662109375 +36655 0.404449462890625 +36656 0.3944091796875 +36657 0.3885498046875 +36658 0.362640380859375 +36659 0.27362060546875 +36660 0.11712646484375 +36661 -0.054901123046875 +36662 -0.19085693359375 +36663 -0.28570556640625 +36664 -0.339263916015625 +36665 -0.3775634765625 +36666 -0.445709228515625 +36667 -0.535064697265625 +36668 -0.629058837890625 +36669 -0.697601318359375 +36670 -0.70391845703125 +36671 -0.6424560546875 +36672 -0.491241455078125 +36673 -0.265716552734375 +36674 -0.023712158203125 +36675 0.201751708984375 +36676 0.375823974609375 +36677 0.485076904296875 +36678 0.56884765625 +36679 0.634765625 +36680 0.63763427734375 +36681 0.5660400390625 +36682 0.4720458984375 +36683 0.40692138671875 +36684 0.3778076171875 +36685 0.376953125 +36686 0.371978759765625 +36687 0.313140869140625 +36688 0.184417724609375 +36689 0.011199951171875 +36690 -0.171051025390625 +36691 -0.33740234375 +36692 -0.47198486328125 +36693 -0.560394287109375 +36694 -0.58056640625 +36695 -0.54754638671875 +36696 -0.508575439453125 +36697 -0.459503173828125 +36698 -0.394378662109375 +36699 -0.35260009765625 +36700 -0.31170654296875 +36701 -0.197418212890625 +36702 -0.007965087890625 +36703 0.207489013671875 +36704 0.409210205078125 +36705 0.57208251953125 +36706 0.66595458984375 +36707 0.65875244140625 +36708 0.56744384765625 +36709 0.431396484375 +36710 0.29443359375 +36711 0.182464599609375 +36712 0.06365966796875 +36713 -0.075958251953125 +36714 -0.189422607421875 +36715 -0.271942138671875 +36716 -0.342529296875 +36717 -0.364166259765625 +36718 -0.327239990234375 +36719 -0.2769775390625 +36720 -0.253692626953125 +36721 -0.24365234375 +36722 -0.1983642578125 +36723 -0.116241455078125 +36724 -0.036834716796875 +36725 0.034881591796875 +36726 0.09124755859375 +36727 0.10888671875 +36728 0.125518798828125 +36729 0.15771484375 +36730 0.17828369140625 +36731 0.17108154296875 +36732 0.129974365234375 +36733 0.082427978515625 +36734 0.027679443359375 +36735 -0.065643310546875 +36736 -0.15936279296875 +36737 -0.21307373046875 +36738 -0.234649658203125 +36739 -0.2001953125 +36740 -0.119171142578125 +36741 -0.024749755859375 +36742 0.085784912109375 +36743 0.178131103515625 +36744 0.215576171875 +36745 0.211456298828125 +36746 0.17523193359375 +36747 0.128753662109375 +36748 0.1019287109375 +36749 0.0743408203125 +36750 0.04327392578125 +36751 0.038177490234375 +36752 0.076263427734375 +36753 0.14105224609375 +36754 0.186431884765625 +36755 0.188812255859375 +36756 0.1390380859375 +36757 0.041778564453125 +36758 -0.079437255859375 +36759 -0.219390869140625 +36760 -0.367828369140625 +36761 -0.494873046875 +36762 -0.556243896484375 +36763 -0.508697509765625 +36764 -0.3756103515625 +36765 -0.218902587890625 +36766 -0.063751220703125 +36767 0.091552734375 +36768 0.23602294921875 +36769 0.342987060546875 +36770 0.39520263671875 +36771 0.389373779296875 +36772 0.324249267578125 +36773 0.224090576171875 +36774 0.124267578125 +36775 0.037078857421875 +36776 -0.010101318359375 +36777 -0.019439697265625 +36778 -0.022796630859375 +36779 -0.001556396484375 +36780 0.056304931640625 +36781 0.106719970703125 +36782 0.096893310546875 +36783 0.042694091796875 +36784 -0.018035888671875 +36785 -0.07586669921875 +36786 -0.11944580078125 +36787 -0.15972900390625 +36788 -0.202606201171875 +36789 -0.24859619140625 +36790 -0.30517578125 +36791 -0.36212158203125 +36792 -0.39141845703125 +36793 -0.35528564453125 +36794 -0.249969482421875 +36795 -0.092864990234375 +36796 0.08905029296875 +36797 0.2352294921875 +36798 0.318817138671875 +36799 0.358642578125 +36800 0.347747802734375 +36801 0.28564453125 +36802 0.223175048828125 +36803 0.196746826171875 +36804 0.179840087890625 +36805 0.155548095703125 +36806 0.151214599609375 +36807 0.156951904296875 +36808 0.13177490234375 +36809 0.100799560546875 +36810 0.087127685546875 +36811 0.05487060546875 +36812 -0.009002685546875 +36813 -0.10400390625 +36814 -0.229400634765625 +36815 -0.35552978515625 +36816 -0.441925048828125 +36817 -0.473846435546875 +36818 -0.464813232421875 +36819 -0.419097900390625 +36820 -0.334320068359375 +36821 -0.227935791015625 +36822 -0.12347412109375 +36823 -0.02764892578125 +36824 0.077667236328125 +36825 0.2132568359375 +36826 0.38885498046875 +36827 0.582794189453125 +36828 0.734039306640625 +36829 0.800140380859375 +36830 0.7783203125 +36831 0.6651611328125 +36832 0.45965576171875 +36833 0.199188232421875 +36834 -0.050689697265625 +36835 -0.23297119140625 +36836 -0.33013916015625 +36837 -0.368408203125 +36838 -0.378936767578125 +36839 -0.376983642578125 +36840 -0.37969970703125 +36841 -0.391510009765625 +36842 -0.385345458984375 +36843 -0.3419189453125 +36844 -0.28289794921875 +36845 -0.251617431640625 +36846 -0.266143798828125 +36847 -0.273345947265625 +36848 -0.216796875 +36849 -0.128265380859375 +36850 -0.068145751953125 +36851 -0.0430908203125 +36852 -0.024444580078125 +36853 0.020721435546875 +36854 0.124481201171875 +36855 0.25787353515625 +36856 0.379119873046875 +36857 0.47991943359375 +36858 0.5281982421875 +36859 0.511138916015625 +36860 0.456207275390625 +36861 0.407470703125 +36862 0.383758544921875 +36863 0.35687255859375 +36864 0.31182861328125 +36865 0.250885009765625 +36866 0.1654052734375 +36867 0.035247802734375 +36868 -0.142059326171875 +36869 -0.33563232421875 +36870 -0.5345458984375 +36871 -0.72186279296875 +36872 -0.836669921875 +36873 -0.8326416015625 +36874 -0.7296142578125 +36875 -0.582550048828125 +36876 -0.440093994140625 +36877 -0.324310302734375 +36878 -0.20147705078125 +36879 -0.044647216796875 +36880 0.103973388671875 +36881 0.202392578125 +36882 0.264495849609375 +36883 0.338897705078125 +36884 0.443817138671875 +36885 0.545074462890625 +36886 0.6173095703125 +36887 0.6524658203125 +36888 0.66339111328125 +36889 0.6561279296875 +36890 0.606781005859375 +36891 0.501190185546875 +36892 0.352783203125 +36893 0.176544189453125 +36894 -0.034820556640625 +36895 -0.258209228515625 +36896 -0.44244384765625 +36897 -0.5753173828125 +36898 -0.65203857421875 +36899 -0.641632080078125 +36900 -0.562164306640625 +36901 -0.458038330078125 +36902 -0.350555419921875 +36903 -0.260528564453125 +36904 -0.192108154296875 +36905 -0.141937255859375 +36906 -0.1021728515625 +36907 -0.062896728515625 +36908 -0.011932373046875 +36909 0.062835693359375 +36910 0.148712158203125 +36911 0.241729736328125 +36912 0.34912109375 +36913 0.457305908203125 +36914 0.54388427734375 +36915 0.5728759765625 +36916 0.506591796875 +36917 0.351226806640625 +36918 0.146514892578125 +36919 -0.05523681640625 +36920 -0.21624755859375 +36921 -0.334930419921875 +36922 -0.402984619140625 +36923 -0.4412841796875 +36924 -0.49578857421875 +36925 -0.5601806640625 +36926 -0.600738525390625 +36927 -0.584228515625 +36928 -0.47930908203125 +36929 -0.27935791015625 +36930 -0.0089111328125 +36931 0.268798828125 +36932 0.482818603515625 +36933 0.60369873046875 +36934 0.650421142578125 +36935 0.66400146484375 +36936 0.6414794921875 +36937 0.572540283203125 +36938 0.498138427734375 +36939 0.439453125 +36940 0.375518798828125 +36941 0.274505615234375 +36942 0.1087646484375 +36943 -0.099395751953125 +36944 -0.3182373046875 +36945 -0.5489501953125 +36946 -0.7738037109375 +36947 -0.86383056640625 +36948 -0.870391845703125 +36949 -0.86895751953125 +36950 -0.861053466796875 +36951 -0.765869140625 +36952 -0.5301513671875 +36953 -0.214691162109375 +36954 0.137359619140625 +36955 0.474822998046875 +36956 0.76239013671875 +36957 0.867462158203125 +36958 0.870361328125 +36959 0.86480712890625 +36960 0.831817626953125 +36961 0.677581787109375 +36962 0.495880126953125 +36963 0.30767822265625 +36964 0.116180419921875 +36965 -0.110748291015625 +36966 -0.381805419921875 +36967 -0.6572265625 +36968 -0.857421875 +36969 -0.870391845703125 +36970 -0.870391845703125 +36971 -0.86444091796875 +36972 -0.85723876953125 +36973 -0.790008544921875 +36974 -0.62847900390625 +36975 -0.3956298828125 +36976 -0.126708984375 +36977 0.150115966796875 +36978 0.424041748046875 +36979 0.670623779296875 +36980 0.854522705078125 +36981 0.866485595703125 +36982 0.86920166015625 +36983 0.8653564453125 +36984 0.857147216796875 +36985 0.766845703125 +36986 0.628509521484375 +36987 0.462127685546875 +36988 0.297210693359375 +36989 0.14862060546875 +36990 -0.00537109375 +36991 -0.15753173828125 +36992 -0.31304931640625 +36993 -0.48876953125 +36994 -0.6416015625 +36995 -0.751373291015625 +36996 -0.84619140625 +36997 -0.861297607421875 +36998 -0.863250732421875 +36999 -0.856597900390625 +37000 -0.7498779296875 +37001 -0.624542236328125 +37002 -0.47808837890625 +37003 -0.253387451171875 +37004 0.003692626953125 +37005 0.2257080078125 +37006 0.427154541015625 +37007 0.643218994140625 +37008 0.855926513671875 +37009 0.870361328125 +37010 0.870361328125 +37011 0.862762451171875 +37012 0.79669189453125 +37013 0.595794677734375 +37014 0.362152099609375 +37015 0.1270751953125 +37016 -0.086944580078125 +37017 -0.2784423828125 +37018 -0.484832763671875 +37019 -0.729583740234375 +37020 -0.86688232421875 +37021 -0.870391845703125 +37022 -0.86859130859375 +37023 -0.86279296875 +37024 -0.817962646484375 +37025 -0.6116943359375 +37026 -0.3128662109375 +37027 0.039398193359375 +37028 0.422821044921875 +37029 0.805145263671875 +37030 0.870361328125 +37031 0.870361328125 +37032 0.860015869140625 +37033 0.727935791015625 +37034 0.48114013671875 +37035 0.2059326171875 +37036 -0.06103515625 +37037 -0.29913330078125 +37038 -0.516204833984375 +37039 -0.7252197265625 +37040 -0.85980224609375 +37041 -0.870391845703125 +37042 -0.870391845703125 +37043 -0.858062744140625 +37044 -0.673004150390625 +37045 -0.42694091796875 +37046 -0.2100830078125 +37047 -0.0362548828125 +37048 0.10943603515625 +37049 0.23516845703125 +37050 0.373687744140625 +37051 0.517791748046875 +37052 0.602783203125 +37053 0.635711669921875 +37054 0.655181884765625 +37055 0.65948486328125 +37056 0.651275634765625 +37057 0.61846923828125 +37058 0.53753662109375 +37059 0.404144287109375 +37060 0.22186279296875 +37061 0.003997802734375 +37062 -0.22100830078125 +37063 -0.42449951171875 +37064 -0.579833984375 +37065 -0.641876220703125 +37066 -0.6177978515625 +37067 -0.575531005859375 +37068 -0.526336669921875 +37069 -0.42645263671875 +37070 -0.2581787109375 +37071 -0.068695068359375 +37072 0.09222412109375 +37073 0.232147216796875 +37074 0.3509521484375 +37075 0.410064697265625 +37076 0.372955322265625 +37077 0.2554931640625 +37078 0.10711669921875 +37079 -0.052886962890625 +37080 -0.186279296875 +37081 -0.23291015625 +37082 -0.209442138671875 +37083 -0.174163818359375 +37084 -0.126739501953125 +37085 -0.048126220703125 +37086 0.0426025390625 +37087 0.10748291015625 +37088 0.1409912109375 +37089 0.19708251953125 +37090 0.273651123046875 +37091 0.31768798828125 +37092 0.341094970703125 +37093 0.368011474609375 +37094 0.37249755859375 +37095 0.30072021484375 +37096 0.1517333984375 +37097 -0.01470947265625 +37098 -0.1883544921875 +37099 -0.372711181640625 +37100 -0.51397705078125 +37101 -0.57177734375 +37102 -0.53948974609375 +37103 -0.43511962890625 +37104 -0.2962646484375 +37105 -0.161102294921875 +37106 -0.0435791015625 +37107 0.060394287109375 +37108 0.13665771484375 +37109 0.170135498046875 +37110 0.16552734375 +37111 0.15728759765625 +37112 0.150787353515625 +37113 0.12200927734375 +37114 0.080108642578125 +37115 0.05126953125 +37116 0.062896728515625 +37117 0.09271240234375 +37118 0.092987060546875 +37119 0.07855224609375 +37120 0.06427001953125 +37121 0.0347900390625 +37122 -0.01171875 +37123 -0.056060791015625 +37124 -0.055511474609375 +37125 -0.010467529296875 +37126 0.02508544921875 +37127 0.025665283203125 +37128 0.017333984375 +37129 0.00189208984375 +37130 -0.03173828125 +37131 -0.071502685546875 +37132 -0.13543701171875 +37133 -0.219970703125 +37134 -0.300506591796875 +37135 -0.376312255859375 +37136 -0.416107177734375 +37137 -0.371124267578125 +37138 -0.242279052734375 +37139 -0.069732666015625 +37140 0.125640869140625 +37141 0.31268310546875 +37142 0.45501708984375 +37143 0.554779052734375 +37144 0.61065673828125 +37145 0.610931396484375 +37146 0.531463623046875 +37147 0.3883056640625 +37148 0.23468017578125 +37149 0.095245361328125 +37150 -0.00396728515625 +37151 -0.04852294921875 +37152 -0.055145263671875 +37153 -0.0758056640625 +37154 -0.138702392578125 +37155 -0.209197998046875 +37156 -0.289031982421875 +37157 -0.37884521484375 +37158 -0.456329345703125 +37159 -0.51641845703125 +37160 -0.519287109375 +37161 -0.458251953125 +37162 -0.384796142578125 +37163 -0.323699951171875 +37164 -0.269287109375 +37165 -0.1951904296875 +37166 -0.100006103515625 +37167 -0.01055908203125 +37168 0.1033935546875 +37169 0.24908447265625 +37170 0.373199462890625 +37171 0.45806884765625 +37172 0.511474609375 +37173 0.565399169921875 +37174 0.61138916015625 +37175 0.5897216796875 +37176 0.4906005859375 +37177 0.33148193359375 +37178 0.147796630859375 +37179 -0.01873779296875 +37180 -0.140289306640625 +37181 -0.191986083984375 +37182 -0.184295654296875 +37183 -0.161834716796875 +37184 -0.166595458984375 +37185 -0.19390869140625 +37186 -0.22442626953125 +37187 -0.279754638671875 +37188 -0.3389892578125 +37189 -0.3543701171875 +37190 -0.348175048828125 +37191 -0.32598876953125 +37192 -0.2581787109375 +37193 -0.139801025390625 +37194 0.014617919921875 +37195 0.144378662109375 +37196 0.221038818359375 +37197 0.27069091796875 +37198 0.294036865234375 +37199 0.311767578125 +37200 0.339141845703125 +37201 0.360260009765625 +37202 0.360504150390625 +37203 0.308380126953125 +37204 0.18170166015625 +37205 0.0047607421875 +37206 -0.17559814453125 +37207 -0.3143310546875 +37208 -0.36785888671875 +37209 -0.36248779296875 +37210 -0.343536376953125 +37211 -0.3018798828125 +37212 -0.231414794921875 +37213 -0.117645263671875 +37214 0.007049560546875 +37215 0.087982177734375 +37216 0.13946533203125 +37217 0.17425537109375 +37218 0.188201904296875 +37219 0.171234130859375 +37220 0.118438720703125 +37221 0.05706787109375 +37222 -0.010711669921875 +37223 -0.0914306640625 +37224 -0.162322998046875 +37225 -0.194549560546875 +37226 -0.1492919921875 +37227 -0.02166748046875 +37228 0.124053955078125 +37229 0.211151123046875 +37230 0.240447998046875 +37231 0.242218017578125 +37232 0.2257080078125 +37233 0.194366455078125 +37234 0.115509033203125 +37235 0.0128173828125 +37236 -0.053802490234375 +37237 -0.110626220703125 +37238 -0.199493408203125 +37239 -0.29437255859375 +37240 -0.33221435546875 +37241 -0.27972412109375 +37242 -0.185333251953125 +37243 -0.128204345703125 +37244 -0.115692138671875 +37245 -0.116455078125 +37246 -0.105926513671875 +37247 -0.053955078125 +37248 0.048797607421875 +37249 0.157318115234375 +37250 0.212005615234375 +37251 0.218475341796875 +37252 0.23724365234375 +37253 0.30535888671875 +37254 0.38128662109375 +37255 0.404449462890625 +37256 0.3944091796875 +37257 0.3885498046875 +37258 0.362640380859375 +37259 0.27362060546875 +37260 0.11712646484375 +37261 -0.054901123046875 +37262 -0.19085693359375 +37263 -0.28570556640625 +37264 -0.339263916015625 +37265 -0.3775634765625 +37266 -0.445709228515625 +37267 -0.535064697265625 +37268 -0.629058837890625 +37269 -0.697601318359375 +37270 -0.70391845703125 +37271 -0.6424560546875 +37272 -0.491241455078125 +37273 -0.265716552734375 +37274 -0.023712158203125 +37275 0.201751708984375 +37276 0.375823974609375 +37277 0.485076904296875 +37278 0.56884765625 +37279 0.634765625 +37280 0.63763427734375 +37281 0.5660400390625 +37282 0.4720458984375 +37283 0.40692138671875 +37284 0.3778076171875 +37285 0.376953125 +37286 0.371978759765625 +37287 0.313140869140625 +37288 0.184417724609375 +37289 0.011199951171875 +37290 -0.171051025390625 +37291 -0.33740234375 +37292 -0.47198486328125 +37293 -0.560394287109375 +37294 -0.58056640625 +37295 -0.54754638671875 +37296 -0.508575439453125 +37297 -0.459503173828125 +37298 -0.394378662109375 +37299 -0.35260009765625 +37300 -0.31170654296875 +37301 -0.197418212890625 +37302 -0.007965087890625 +37303 0.207489013671875 +37304 0.409210205078125 +37305 0.57208251953125 +37306 0.66595458984375 +37307 0.65875244140625 +37308 0.56744384765625 +37309 0.431396484375 +37310 0.29443359375 +37311 0.182464599609375 +37312 0.06365966796875 +37313 -0.075958251953125 +37314 -0.189422607421875 +37315 -0.271942138671875 +37316 -0.342529296875 +37317 -0.364166259765625 +37318 -0.327239990234375 +37319 -0.2769775390625 +37320 -0.253692626953125 +37321 -0.24365234375 +37322 -0.1983642578125 +37323 -0.116241455078125 +37324 -0.036834716796875 +37325 0.034881591796875 +37326 0.09124755859375 +37327 0.10888671875 +37328 0.125518798828125 +37329 0.15771484375 +37330 0.17828369140625 +37331 0.17108154296875 +37332 0.129974365234375 +37333 0.082427978515625 +37334 0.027679443359375 +37335 -0.065643310546875 +37336 -0.15936279296875 +37337 -0.21307373046875 +37338 -0.234649658203125 +37339 -0.2001953125 +37340 -0.119171142578125 +37341 -0.024749755859375 +37342 0.085784912109375 +37343 0.178131103515625 +37344 0.215576171875 +37345 0.211456298828125 +37346 0.17523193359375 +37347 0.128753662109375 +37348 0.1019287109375 +37349 0.0743408203125 +37350 0.04327392578125 +37351 0.038177490234375 +37352 0.076263427734375 +37353 0.14105224609375 +37354 0.186431884765625 +37355 0.188812255859375 +37356 0.1390380859375 +37357 0.041778564453125 +37358 -0.079437255859375 +37359 -0.219390869140625 +37360 -0.367828369140625 +37361 -0.494873046875 +37362 -0.556243896484375 +37363 -0.508697509765625 +37364 -0.3756103515625 +37365 -0.218902587890625 +37366 -0.063751220703125 +37367 0.091552734375 +37368 0.23602294921875 +37369 0.342987060546875 +37370 0.39520263671875 +37371 0.389373779296875 +37372 0.324249267578125 +37373 0.224090576171875 +37374 0.124267578125 +37375 0.037078857421875 +37376 -0.010101318359375 +37377 -0.019439697265625 +37378 -0.022796630859375 +37379 -0.001556396484375 +37380 0.056304931640625 +37381 0.106719970703125 +37382 0.096893310546875 +37383 0.042694091796875 +37384 -0.018035888671875 +37385 -0.07586669921875 +37386 -0.11944580078125 +37387 -0.15972900390625 +37388 -0.202606201171875 +37389 -0.24859619140625 +37390 -0.30517578125 +37391 -0.36212158203125 +37392 -0.39141845703125 +37393 -0.35528564453125 +37394 -0.249969482421875 +37395 -0.092864990234375 +37396 0.08905029296875 +37397 0.2352294921875 +37398 0.318817138671875 +37399 0.358642578125 +37400 0.347747802734375 +37401 0.28564453125 +37402 0.223175048828125 +37403 0.196746826171875 +37404 0.179840087890625 +37405 0.155548095703125 +37406 0.151214599609375 +37407 0.156951904296875 +37408 0.13177490234375 +37409 0.100799560546875 +37410 0.087127685546875 +37411 0.05487060546875 +37412 -0.009002685546875 +37413 -0.10400390625 +37414 -0.229400634765625 +37415 -0.35552978515625 +37416 -0.441925048828125 +37417 -0.473846435546875 +37418 -0.464813232421875 +37419 -0.419097900390625 +37420 -0.334320068359375 +37421 -0.227935791015625 +37422 -0.12347412109375 +37423 -0.02764892578125 +37424 0.077667236328125 +37425 0.2132568359375 +37426 0.38885498046875 +37427 0.582794189453125 +37428 0.734039306640625 +37429 0.800140380859375 +37430 0.7783203125 +37431 0.6651611328125 +37432 0.45965576171875 +37433 0.199188232421875 +37434 -0.050689697265625 +37435 -0.23297119140625 +37436 -0.33013916015625 +37437 -0.368408203125 +37438 -0.378936767578125 +37439 -0.376983642578125 +37440 -0.37969970703125 +37441 -0.391510009765625 +37442 -0.385345458984375 +37443 -0.3419189453125 +37444 -0.28289794921875 +37445 -0.251617431640625 +37446 -0.266143798828125 +37447 -0.273345947265625 +37448 -0.216796875 +37449 -0.128265380859375 +37450 -0.068145751953125 +37451 -0.0430908203125 +37452 -0.024444580078125 +37453 0.020721435546875 +37454 0.124481201171875 +37455 0.25787353515625 +37456 0.379119873046875 +37457 0.47991943359375 +37458 0.5281982421875 +37459 0.511138916015625 +37460 0.456207275390625 +37461 0.407470703125 +37462 0.383758544921875 +37463 0.35687255859375 +37464 0.31182861328125 +37465 0.250885009765625 +37466 0.1654052734375 +37467 0.035247802734375 +37468 -0.142059326171875 +37469 -0.33563232421875 +37470 -0.5345458984375 +37471 -0.72186279296875 +37472 -0.836669921875 +37473 -0.8326416015625 +37474 -0.7296142578125 +37475 -0.582550048828125 +37476 -0.440093994140625 +37477 -0.324310302734375 +37478 -0.20147705078125 +37479 -0.044647216796875 +37480 0.103973388671875 +37481 0.202392578125 +37482 0.264495849609375 +37483 0.338897705078125 +37484 0.443817138671875 +37485 0.545074462890625 +37486 0.6173095703125 +37487 0.6524658203125 +37488 0.66339111328125 +37489 0.6561279296875 +37490 0.606781005859375 +37491 0.501190185546875 +37492 0.352783203125 +37493 0.176544189453125 +37494 -0.034820556640625 +37495 -0.258209228515625 +37496 -0.44244384765625 +37497 -0.5753173828125 +37498 -0.65203857421875 +37499 -0.641632080078125 +37500 -0.562164306640625 +37501 -0.458038330078125 +37502 -0.350555419921875 +37503 -0.260528564453125 +37504 -0.192108154296875 +37505 -0.141937255859375 +37506 -0.1021728515625 +37507 -0.062896728515625 +37508 -0.011932373046875 +37509 0.062835693359375 +37510 0.148712158203125 +37511 0.241729736328125 +37512 0.34912109375 +37513 0.457305908203125 +37514 0.54388427734375 +37515 0.5728759765625 +37516 0.506591796875 +37517 0.351226806640625 +37518 0.146514892578125 +37519 -0.05523681640625 +37520 -0.21624755859375 +37521 -0.334930419921875 +37522 -0.402984619140625 +37523 -0.4412841796875 +37524 -0.49578857421875 +37525 -0.5601806640625 +37526 -0.600738525390625 +37527 -0.584228515625 +37528 -0.47930908203125 +37529 -0.27935791015625 +37530 -0.0089111328125 +37531 0.268798828125 +37532 0.482818603515625 +37533 0.60369873046875 +37534 0.650421142578125 +37535 0.66400146484375 +37536 0.6414794921875 +37537 0.572540283203125 +37538 0.498138427734375 +37539 0.439453125 +37540 0.375518798828125 +37541 0.274505615234375 +37542 0.1087646484375 +37543 -0.099395751953125 +37544 -0.3182373046875 +37545 -0.5489501953125 +37546 -0.7738037109375 +37547 -0.86383056640625 +37548 -0.870391845703125 +37549 -0.86895751953125 +37550 -0.861053466796875 +37551 -0.765869140625 +37552 -0.5301513671875 +37553 -0.214691162109375 +37554 0.137359619140625 +37555 0.474822998046875 +37556 0.76239013671875 +37557 0.867462158203125 +37558 0.870361328125 +37559 0.86480712890625 +37560 0.831817626953125 +37561 0.677581787109375 +37562 0.495880126953125 +37563 0.30767822265625 +37564 0.116180419921875 +37565 -0.110748291015625 +37566 -0.381805419921875 +37567 -0.6572265625 +37568 -0.857421875 +37569 -0.870391845703125 +37570 -0.870391845703125 +37571 -0.86444091796875 +37572 -0.85723876953125 +37573 -0.790008544921875 +37574 -0.62847900390625 +37575 -0.3956298828125 +37576 -0.126708984375 +37577 0.150115966796875 +37578 0.424041748046875 +37579 0.670623779296875 +37580 0.854522705078125 +37581 0.866485595703125 +37582 0.86920166015625 +37583 0.8653564453125 +37584 0.857147216796875 +37585 0.766845703125 +37586 0.628509521484375 +37587 0.462127685546875 +37588 0.297210693359375 +37589 0.14862060546875 +37590 -0.00537109375 +37591 -0.15753173828125 +37592 -0.31304931640625 +37593 -0.48876953125 +37594 -0.6416015625 +37595 -0.751373291015625 +37596 -0.84619140625 +37597 -0.861297607421875 +37598 -0.863250732421875 +37599 -0.856597900390625 +37600 -0.7498779296875 +37601 -0.624542236328125 +37602 -0.47808837890625 +37603 -0.253387451171875 +37604 0.003692626953125 +37605 0.2257080078125 +37606 0.427154541015625 +37607 0.643218994140625 +37608 0.855926513671875 +37609 0.870361328125 +37610 0.870361328125 +37611 0.862762451171875 +37612 0.79669189453125 +37613 0.595794677734375 +37614 0.362152099609375 +37615 0.1270751953125 +37616 -0.086944580078125 +37617 -0.2784423828125 +37618 -0.484832763671875 +37619 -0.729583740234375 +37620 -0.86688232421875 +37621 -0.870391845703125 +37622 -0.86859130859375 +37623 -0.86279296875 +37624 -0.817962646484375 +37625 -0.6116943359375 +37626 -0.3128662109375 +37627 0.039398193359375 +37628 0.422821044921875 +37629 0.805145263671875 +37630 0.870361328125 +37631 0.870361328125 +37632 0.860015869140625 +37633 0.727935791015625 +37634 0.48114013671875 +37635 0.2059326171875 +37636 -0.06103515625 +37637 -0.29913330078125 +37638 -0.516204833984375 +37639 -0.7252197265625 +37640 -0.85980224609375 +37641 -0.870391845703125 +37642 -0.870391845703125 +37643 -0.858062744140625 +37644 -0.673004150390625 +37645 -0.42694091796875 +37646 -0.2100830078125 +37647 -0.0362548828125 +37648 0.10943603515625 +37649 0.23516845703125 +37650 0.373687744140625 +37651 0.517791748046875 +37652 0.602783203125 +37653 0.635711669921875 +37654 0.655181884765625 +37655 0.65948486328125 +37656 0.651275634765625 +37657 0.61846923828125 +37658 0.53753662109375 +37659 0.404144287109375 +37660 0.22186279296875 +37661 0.003997802734375 +37662 -0.22100830078125 +37663 -0.42449951171875 +37664 -0.579833984375 +37665 -0.641876220703125 +37666 -0.6177978515625 +37667 -0.575531005859375 +37668 -0.526336669921875 +37669 -0.42645263671875 +37670 -0.2581787109375 +37671 -0.068695068359375 +37672 0.09222412109375 +37673 0.232147216796875 +37674 0.3509521484375 +37675 0.410064697265625 +37676 0.372955322265625 +37677 0.2554931640625 +37678 0.10711669921875 +37679 -0.052886962890625 +37680 -0.186279296875 +37681 -0.23291015625 +37682 -0.209442138671875 +37683 -0.174163818359375 +37684 -0.126739501953125 +37685 -0.048126220703125 +37686 0.0426025390625 +37687 0.10748291015625 +37688 0.1409912109375 +37689 0.19708251953125 +37690 0.273651123046875 +37691 0.31768798828125 +37692 0.341094970703125 +37693 0.368011474609375 +37694 0.37249755859375 +37695 0.30072021484375 +37696 0.1517333984375 +37697 -0.01470947265625 +37698 -0.1883544921875 +37699 -0.372711181640625 +37700 -0.51397705078125 +37701 -0.57177734375 +37702 -0.53948974609375 +37703 -0.43511962890625 +37704 -0.2962646484375 +37705 -0.161102294921875 +37706 -0.0435791015625 +37707 0.060394287109375 +37708 0.13665771484375 +37709 0.170135498046875 +37710 0.16552734375 +37711 0.15728759765625 +37712 0.150787353515625 +37713 0.12200927734375 +37714 0.080108642578125 +37715 0.05126953125 +37716 0.062896728515625 +37717 0.09271240234375 +37718 0.092987060546875 +37719 0.07855224609375 +37720 0.06427001953125 +37721 0.0347900390625 +37722 -0.01171875 +37723 -0.056060791015625 +37724 -0.055511474609375 +37725 -0.010467529296875 +37726 0.02508544921875 +37727 0.025665283203125 +37728 0.017333984375 +37729 0.00189208984375 +37730 -0.03173828125 +37731 -0.071502685546875 +37732 -0.13543701171875 +37733 -0.219970703125 +37734 -0.300506591796875 +37735 -0.376312255859375 +37736 -0.416107177734375 +37737 -0.371124267578125 +37738 -0.242279052734375 +37739 -0.069732666015625 +37740 0.125640869140625 +37741 0.31268310546875 +37742 0.45501708984375 +37743 0.554779052734375 +37744 0.61065673828125 +37745 0.610931396484375 +37746 0.531463623046875 +37747 0.3883056640625 +37748 0.23468017578125 +37749 0.095245361328125 +37750 -0.00396728515625 +37751 -0.04852294921875 +37752 -0.055145263671875 +37753 -0.0758056640625 +37754 -0.138702392578125 +37755 -0.209197998046875 +37756 -0.289031982421875 +37757 -0.37884521484375 +37758 -0.456329345703125 +37759 -0.51641845703125 +37760 -0.519287109375 +37761 -0.458251953125 +37762 -0.384796142578125 +37763 -0.323699951171875 +37764 -0.269287109375 +37765 -0.1951904296875 +37766 -0.100006103515625 +37767 -0.01055908203125 +37768 0.1033935546875 +37769 0.24908447265625 +37770 0.373199462890625 +37771 0.45806884765625 +37772 0.511474609375 +37773 0.565399169921875 +37774 0.61138916015625 +37775 0.5897216796875 +37776 0.4906005859375 +37777 0.33148193359375 +37778 0.147796630859375 +37779 -0.01873779296875 +37780 -0.140289306640625 +37781 -0.191986083984375 +37782 -0.184295654296875 +37783 -0.161834716796875 +37784 -0.166595458984375 +37785 -0.19390869140625 +37786 -0.22442626953125 +37787 -0.279754638671875 +37788 -0.3389892578125 +37789 -0.3543701171875 +37790 -0.348175048828125 +37791 -0.32598876953125 +37792 -0.2581787109375 +37793 -0.139801025390625 +37794 0.014617919921875 +37795 0.144378662109375 +37796 0.221038818359375 +37797 0.27069091796875 +37798 0.294036865234375 +37799 0.311767578125 +37800 0.339141845703125 +37801 0.360260009765625 +37802 0.360504150390625 +37803 0.308380126953125 +37804 0.18170166015625 +37805 0.0047607421875 +37806 -0.17559814453125 +37807 -0.3143310546875 +37808 -0.36785888671875 +37809 -0.36248779296875 +37810 -0.343536376953125 +37811 -0.3018798828125 +37812 -0.231414794921875 +37813 -0.117645263671875 +37814 0.007049560546875 +37815 0.087982177734375 +37816 0.13946533203125 +37817 0.17425537109375 +37818 0.188201904296875 +37819 0.171234130859375 +37820 0.118438720703125 +37821 0.05706787109375 +37822 -0.010711669921875 +37823 -0.0914306640625 +37824 -0.162322998046875 +37825 -0.194549560546875 +37826 -0.1492919921875 +37827 -0.02166748046875 +37828 0.124053955078125 +37829 0.211151123046875 +37830 0.240447998046875 +37831 0.242218017578125 +37832 0.2257080078125 +37833 0.194366455078125 +37834 0.115509033203125 +37835 0.0128173828125 +37836 -0.053802490234375 +37837 -0.110626220703125 +37838 -0.199493408203125 +37839 -0.29437255859375 +37840 -0.33221435546875 +37841 -0.27972412109375 +37842 -0.185333251953125 +37843 -0.128204345703125 +37844 -0.115692138671875 +37845 -0.116455078125 +37846 -0.105926513671875 +37847 -0.053955078125 +37848 0.048797607421875 +37849 0.157318115234375 +37850 0.212005615234375 +37851 0.218475341796875 +37852 0.23724365234375 +37853 0.30535888671875 +37854 0.38128662109375 +37855 0.404449462890625 +37856 0.3944091796875 +37857 0.3885498046875 +37858 0.362640380859375 +37859 0.27362060546875 +37860 0.11712646484375 +37861 -0.054901123046875 +37862 -0.19085693359375 +37863 -0.28570556640625 +37864 -0.339263916015625 +37865 -0.3775634765625 +37866 -0.445709228515625 +37867 -0.535064697265625 +37868 -0.629058837890625 +37869 -0.697601318359375 +37870 -0.70391845703125 +37871 -0.6424560546875 +37872 -0.491241455078125 +37873 -0.265716552734375 +37874 -0.023712158203125 +37875 0.201751708984375 +37876 0.375823974609375 +37877 0.485076904296875 +37878 0.56884765625 +37879 0.634765625 +37880 0.63763427734375 +37881 0.5660400390625 +37882 0.4720458984375 +37883 0.40692138671875 +37884 0.3778076171875 +37885 0.376953125 +37886 0.371978759765625 +37887 0.313140869140625 +37888 0.184417724609375 +37889 0.011199951171875 +37890 -0.171051025390625 +37891 -0.33740234375 +37892 -0.47198486328125 +37893 -0.560394287109375 +37894 -0.58056640625 +37895 -0.54754638671875 +37896 -0.508575439453125 +37897 -0.459503173828125 +37898 -0.394378662109375 +37899 -0.35260009765625 +37900 -0.31170654296875 +37901 -0.197418212890625 +37902 -0.007965087890625 +37903 0.207489013671875 +37904 0.409210205078125 +37905 0.57208251953125 +37906 0.66595458984375 +37907 0.65875244140625 +37908 0.56744384765625 +37909 0.431396484375 +37910 0.29443359375 +37911 0.182464599609375 +37912 0.06365966796875 +37913 -0.075958251953125 +37914 -0.189422607421875 +37915 -0.271942138671875 +37916 -0.342529296875 +37917 -0.364166259765625 +37918 -0.327239990234375 +37919 -0.2769775390625 +37920 -0.253692626953125 +37921 -0.24365234375 +37922 -0.1983642578125 +37923 -0.116241455078125 +37924 -0.036834716796875 +37925 0.034881591796875 +37926 0.09124755859375 +37927 0.10888671875 +37928 0.125518798828125 +37929 0.15771484375 +37930 0.17828369140625 +37931 0.17108154296875 +37932 0.129974365234375 +37933 0.082427978515625 +37934 0.027679443359375 +37935 -0.065643310546875 +37936 -0.15936279296875 +37937 -0.21307373046875 +37938 -0.234649658203125 +37939 -0.2001953125 +37940 -0.119171142578125 +37941 -0.024749755859375 +37942 0.085784912109375 +37943 0.178131103515625 +37944 0.215576171875 +37945 0.211456298828125 +37946 0.17523193359375 +37947 0.128753662109375 +37948 0.1019287109375 +37949 0.0743408203125 +37950 0.04327392578125 +37951 0.038177490234375 +37952 0.076263427734375 +37953 0.14105224609375 +37954 0.186431884765625 +37955 0.188812255859375 +37956 0.1390380859375 +37957 0.041778564453125 +37958 -0.079437255859375 +37959 -0.219390869140625 +37960 -0.367828369140625 +37961 -0.494873046875 +37962 -0.556243896484375 +37963 -0.508697509765625 +37964 -0.3756103515625 +37965 -0.218902587890625 +37966 -0.063751220703125 +37967 0.091552734375 +37968 0.23602294921875 +37969 0.342987060546875 +37970 0.39520263671875 +37971 0.389373779296875 +37972 0.324249267578125 +37973 0.224090576171875 +37974 0.124267578125 +37975 0.037078857421875 +37976 -0.010101318359375 +37977 -0.019439697265625 +37978 -0.022796630859375 +37979 -0.001556396484375 +37980 0.056304931640625 +37981 0.106719970703125 +37982 0.096893310546875 +37983 0.042694091796875 +37984 -0.018035888671875 +37985 -0.07586669921875 +37986 -0.11944580078125 +37987 -0.15972900390625 +37988 -0.202606201171875 +37989 -0.24859619140625 +37990 -0.30517578125 +37991 -0.36212158203125 +37992 -0.39141845703125 +37993 -0.35528564453125 +37994 -0.249969482421875 +37995 -0.092864990234375 +37996 0.08905029296875 +37997 0.2352294921875 +37998 0.318817138671875 +37999 0.358642578125 +38000 0.347747802734375 +38001 0.28564453125 +38002 0.223175048828125 +38003 0.196746826171875 +38004 0.179840087890625 +38005 0.155548095703125 +38006 0.151214599609375 +38007 0.156951904296875 +38008 0.13177490234375 +38009 0.100799560546875 +38010 0.087127685546875 +38011 0.05487060546875 +38012 -0.009002685546875 +38013 -0.10400390625 +38014 -0.229400634765625 +38015 -0.35552978515625 +38016 -0.441925048828125 +38017 -0.473846435546875 +38018 -0.464813232421875 +38019 -0.419097900390625 +38020 -0.334320068359375 +38021 -0.227935791015625 +38022 -0.12347412109375 +38023 -0.02764892578125 +38024 0.077667236328125 +38025 0.2132568359375 +38026 0.38885498046875 +38027 0.582794189453125 +38028 0.734039306640625 +38029 0.800140380859375 +38030 0.7783203125 +38031 0.6651611328125 +38032 0.45965576171875 +38033 0.199188232421875 +38034 -0.050689697265625 +38035 -0.23297119140625 +38036 -0.33013916015625 +38037 -0.368408203125 +38038 -0.378936767578125 +38039 -0.376983642578125 +38040 -0.37969970703125 +38041 -0.391510009765625 +38042 -0.385345458984375 +38043 -0.3419189453125 +38044 -0.28289794921875 +38045 -0.251617431640625 +38046 -0.266143798828125 +38047 -0.273345947265625 +38048 -0.216796875 +38049 -0.128265380859375 +38050 -0.068145751953125 +38051 -0.0430908203125 +38052 -0.024444580078125 +38053 0.020721435546875 +38054 0.124481201171875 +38055 0.25787353515625 +38056 0.379119873046875 +38057 0.47991943359375 +38058 0.5281982421875 +38059 0.511138916015625 +38060 0.456207275390625 +38061 0.407470703125 +38062 0.383758544921875 +38063 0.35687255859375 +38064 0.31182861328125 +38065 0.250885009765625 +38066 0.1654052734375 +38067 0.035247802734375 +38068 -0.142059326171875 +38069 -0.33563232421875 +38070 -0.5345458984375 +38071 -0.72186279296875 +38072 -0.836669921875 +38073 -0.8326416015625 +38074 -0.7296142578125 +38075 -0.582550048828125 +38076 -0.440093994140625 +38077 -0.324310302734375 +38078 -0.20147705078125 +38079 -0.044647216796875 +38080 0.103973388671875 +38081 0.202392578125 +38082 0.264495849609375 +38083 0.338897705078125 +38084 0.443817138671875 +38085 0.545074462890625 +38086 0.6173095703125 +38087 0.6524658203125 +38088 0.66339111328125 +38089 0.6561279296875 +38090 0.606781005859375 +38091 0.501190185546875 +38092 0.352783203125 +38093 0.176544189453125 +38094 -0.034820556640625 +38095 -0.258209228515625 +38096 -0.44244384765625 +38097 -0.5753173828125 +38098 -0.65203857421875 +38099 -0.641632080078125 +38100 -0.562164306640625 +38101 -0.458038330078125 +38102 -0.350555419921875 +38103 -0.260528564453125 +38104 -0.192108154296875 +38105 -0.141937255859375 +38106 -0.1021728515625 +38107 -0.062896728515625 +38108 -0.011932373046875 +38109 0.062835693359375 +38110 0.148712158203125 +38111 0.241729736328125 +38112 0.34912109375 +38113 0.457305908203125 +38114 0.54388427734375 +38115 0.5728759765625 +38116 0.506591796875 +38117 0.351226806640625 +38118 0.146514892578125 +38119 -0.05523681640625 +38120 -0.21624755859375 +38121 -0.334930419921875 +38122 -0.402984619140625 +38123 -0.4412841796875 +38124 -0.49578857421875 +38125 -0.5601806640625 +38126 -0.600738525390625 +38127 -0.584228515625 +38128 -0.47930908203125 +38129 -0.27935791015625 +38130 -0.0089111328125 +38131 0.268798828125 +38132 0.482818603515625 +38133 0.60369873046875 +38134 0.650421142578125 +38135 0.66400146484375 +38136 0.6414794921875 +38137 0.572540283203125 +38138 0.498138427734375 +38139 0.439453125 +38140 0.375518798828125 +38141 0.274505615234375 +38142 0.1087646484375 +38143 -0.099395751953125 +38144 -0.3182373046875 +38145 -0.5489501953125 +38146 -0.7738037109375 +38147 -0.86383056640625 +38148 -0.870391845703125 +38149 -0.86895751953125 +38150 -0.861053466796875 +38151 -0.765869140625 +38152 -0.5301513671875 +38153 -0.214691162109375 +38154 0.137359619140625 +38155 0.474822998046875 +38156 0.76239013671875 +38157 0.867462158203125 +38158 0.870361328125 +38159 0.86480712890625 +38160 0.831817626953125 +38161 0.677581787109375 +38162 0.495880126953125 +38163 0.30767822265625 +38164 0.116180419921875 +38165 -0.110748291015625 +38166 -0.381805419921875 +38167 -0.6572265625 +38168 -0.857421875 +38169 -0.870391845703125 +38170 -0.870391845703125 +38171 -0.86444091796875 +38172 -0.85723876953125 +38173 -0.790008544921875 +38174 -0.62847900390625 +38175 -0.3956298828125 +38176 -0.126708984375 +38177 0.150115966796875 +38178 0.424041748046875 +38179 0.670623779296875 +38180 0.854522705078125 +38181 0.866485595703125 +38182 0.86920166015625 +38183 0.8653564453125 +38184 0.857147216796875 +38185 0.766845703125 +38186 0.628509521484375 +38187 0.462127685546875 +38188 0.297210693359375 +38189 0.14862060546875 +38190 -0.00537109375 +38191 -0.15753173828125 +38192 -0.31304931640625 +38193 -0.48876953125 +38194 -0.6416015625 +38195 -0.751373291015625 +38196 -0.84619140625 +38197 -0.861297607421875 +38198 -0.863250732421875 +38199 -0.856597900390625 +38200 -0.7498779296875 +38201 -0.624542236328125 +38202 -0.47808837890625 +38203 -0.253387451171875 +38204 0.003692626953125 +38205 0.2257080078125 +38206 0.427154541015625 +38207 0.643218994140625 +38208 0.855926513671875 +38209 0.870361328125 +38210 0.870361328125 +38211 0.862762451171875 +38212 0.79669189453125 +38213 0.595794677734375 +38214 0.362152099609375 +38215 0.1270751953125 +38216 -0.086944580078125 +38217 -0.2784423828125 +38218 -0.484832763671875 +38219 -0.729583740234375 +38220 -0.86688232421875 +38221 -0.870391845703125 +38222 -0.86859130859375 +38223 -0.86279296875 +38224 -0.817962646484375 +38225 -0.6116943359375 +38226 -0.3128662109375 +38227 0.039398193359375 +38228 0.422821044921875 +38229 0.805145263671875 +38230 0.870361328125 +38231 0.870361328125 +38232 0.860015869140625 +38233 0.727935791015625 +38234 0.48114013671875 +38235 0.2059326171875 +38236 -0.06103515625 +38237 -0.29913330078125 +38238 -0.516204833984375 +38239 -0.7252197265625 +38240 -0.85980224609375 +38241 -0.870391845703125 +38242 -0.870391845703125 +38243 -0.858062744140625 +38244 -0.673004150390625 +38245 -0.42694091796875 +38246 -0.2100830078125 +38247 -0.0362548828125 +38248 0.10943603515625 +38249 0.23516845703125 +38250 0.373687744140625 +38251 0.517791748046875 +38252 0.602783203125 +38253 0.635711669921875 +38254 0.655181884765625 +38255 0.65948486328125 +38256 0.651275634765625 +38257 0.61846923828125 +38258 0.53753662109375 +38259 0.404144287109375 +38260 0.22186279296875 +38261 0.003997802734375 +38262 -0.22100830078125 +38263 -0.42449951171875 +38264 -0.579833984375 +38265 -0.641876220703125 +38266 -0.6177978515625 +38267 -0.575531005859375 +38268 -0.526336669921875 +38269 -0.42645263671875 +38270 -0.2581787109375 +38271 -0.068695068359375 +38272 0.09222412109375 +38273 0.232147216796875 +38274 0.3509521484375 +38275 0.410064697265625 +38276 0.372955322265625 +38277 0.2554931640625 +38278 0.10711669921875 +38279 -0.052886962890625 +38280 -0.186279296875 +38281 -0.23291015625 +38282 -0.209442138671875 +38283 -0.174163818359375 +38284 -0.126739501953125 +38285 -0.048126220703125 +38286 0.0426025390625 +38287 0.10748291015625 +38288 0.1409912109375 +38289 0.19708251953125 +38290 0.273651123046875 +38291 0.31768798828125 +38292 0.341094970703125 +38293 0.368011474609375 +38294 0.37249755859375 +38295 0.30072021484375 +38296 0.1517333984375 +38297 -0.01470947265625 +38298 -0.1883544921875 +38299 -0.372711181640625 +38300 -0.51397705078125 +38301 -0.57177734375 +38302 -0.53948974609375 +38303 -0.43511962890625 +38304 -0.2962646484375 +38305 -0.161102294921875 +38306 -0.0435791015625 +38307 0.060394287109375 +38308 0.13665771484375 +38309 0.170135498046875 +38310 0.16552734375 +38311 0.15728759765625 +38312 0.150787353515625 +38313 0.12200927734375 +38314 0.080108642578125 +38315 0.05126953125 +38316 0.062896728515625 +38317 0.09271240234375 +38318 0.092987060546875 +38319 0.07855224609375 +38320 0.06427001953125 +38321 0.0347900390625 +38322 -0.01171875 +38323 -0.056060791015625 +38324 -0.055511474609375 +38325 -0.010467529296875 +38326 0.02508544921875 +38327 0.025665283203125 +38328 0.017333984375 +38329 0.00189208984375 +38330 -0.03173828125 +38331 -0.071502685546875 +38332 -0.13543701171875 +38333 -0.219970703125 +38334 -0.300506591796875 +38335 -0.376312255859375 +38336 -0.416107177734375 +38337 -0.371124267578125 +38338 -0.242279052734375 +38339 -0.069732666015625 +38340 0.125640869140625 +38341 0.31268310546875 +38342 0.45501708984375 +38343 0.554779052734375 +38344 0.61065673828125 +38345 0.610931396484375 +38346 0.531463623046875 +38347 0.3883056640625 +38348 0.23468017578125 +38349 0.095245361328125 +38350 -0.00396728515625 +38351 -0.04852294921875 +38352 -0.055145263671875 +38353 -0.0758056640625 +38354 -0.138702392578125 +38355 -0.209197998046875 +38356 -0.289031982421875 +38357 -0.37884521484375 +38358 -0.456329345703125 +38359 -0.51641845703125 +38360 -0.519287109375 +38361 -0.458251953125 +38362 -0.384796142578125 +38363 -0.323699951171875 +38364 -0.269287109375 +38365 -0.1951904296875 +38366 -0.100006103515625 +38367 -0.01055908203125 +38368 0.1033935546875 +38369 0.24908447265625 +38370 0.373199462890625 +38371 0.45806884765625 +38372 0.511474609375 +38373 0.565399169921875 +38374 0.61138916015625 +38375 0.5897216796875 +38376 0.4906005859375 +38377 0.33148193359375 +38378 0.147796630859375 +38379 -0.01873779296875 +38380 -0.140289306640625 +38381 -0.191986083984375 +38382 -0.184295654296875 +38383 -0.161834716796875 +38384 -0.166595458984375 +38385 -0.19390869140625 +38386 -0.22442626953125 +38387 -0.279754638671875 +38388 -0.3389892578125 +38389 -0.3543701171875 +38390 -0.348175048828125 +38391 -0.32598876953125 +38392 -0.2581787109375 +38393 -0.139801025390625 +38394 0.014617919921875 +38395 0.144378662109375 +38396 0.221038818359375 +38397 0.27069091796875 +38398 0.294036865234375 +38399 0.311767578125 +38400 0.339141845703125 +38401 0.360260009765625 +38402 0.360504150390625 +38403 0.308380126953125 +38404 0.18170166015625 +38405 0.0047607421875 +38406 -0.17559814453125 +38407 -0.3143310546875 +38408 -0.36785888671875 +38409 -0.36248779296875 +38410 -0.343536376953125 +38411 -0.3018798828125 +38412 -0.231414794921875 +38413 -0.117645263671875 +38414 0.007049560546875 +38415 0.087982177734375 +38416 0.13946533203125 +38417 0.17425537109375 +38418 0.188201904296875 +38419 0.171234130859375 +38420 0.118438720703125 +38421 0.05706787109375 +38422 -0.010711669921875 +38423 -0.0914306640625 +38424 -0.162322998046875 +38425 -0.194549560546875 +38426 -0.1492919921875 +38427 -0.02166748046875 +38428 0.124053955078125 +38429 0.211151123046875 +38430 0.240447998046875 +38431 0.242218017578125 +38432 0.2257080078125 +38433 0.194366455078125 +38434 0.115509033203125 +38435 0.0128173828125 +38436 -0.053802490234375 +38437 -0.110626220703125 +38438 -0.199493408203125 +38439 -0.29437255859375 +38440 -0.33221435546875 +38441 -0.27972412109375 +38442 -0.185333251953125 +38443 -0.128204345703125 +38444 -0.115692138671875 +38445 -0.116455078125 +38446 -0.105926513671875 +38447 -0.053955078125 +38448 0.048797607421875 +38449 0.157318115234375 +38450 0.212005615234375 +38451 0.218475341796875 +38452 0.23724365234375 +38453 0.30535888671875 +38454 0.38128662109375 +38455 0.404449462890625 +38456 0.3944091796875 +38457 0.3885498046875 +38458 0.362640380859375 +38459 0.27362060546875 +38460 0.11712646484375 +38461 -0.054901123046875 +38462 -0.19085693359375 +38463 -0.28570556640625 +38464 -0.339263916015625 +38465 -0.3775634765625 +38466 -0.445709228515625 +38467 -0.535064697265625 +38468 -0.629058837890625 +38469 -0.697601318359375 +38470 -0.70391845703125 +38471 -0.6424560546875 +38472 -0.491241455078125 +38473 -0.265716552734375 +38474 -0.023712158203125 +38475 0.201751708984375 +38476 0.375823974609375 +38477 0.485076904296875 +38478 0.56884765625 +38479 0.634765625 +38480 0.63763427734375 +38481 0.5660400390625 +38482 0.4720458984375 +38483 0.40692138671875 +38484 0.3778076171875 +38485 0.376953125 +38486 0.371978759765625 +38487 0.313140869140625 +38488 0.184417724609375 +38489 0.011199951171875 +38490 -0.171051025390625 +38491 -0.33740234375 +38492 -0.47198486328125 +38493 -0.560394287109375 +38494 -0.58056640625 +38495 -0.54754638671875 +38496 -0.508575439453125 +38497 -0.459503173828125 +38498 -0.394378662109375 +38499 -0.35260009765625 +38500 -0.31170654296875 +38501 -0.197418212890625 +38502 -0.007965087890625 +38503 0.207489013671875 +38504 0.409210205078125 +38505 0.57208251953125 +38506 0.66595458984375 +38507 0.65875244140625 +38508 0.56744384765625 +38509 0.431396484375 +38510 0.29443359375 +38511 0.182464599609375 +38512 0.06365966796875 +38513 -0.075958251953125 +38514 -0.189422607421875 +38515 -0.271942138671875 +38516 -0.342529296875 +38517 -0.364166259765625 +38518 -0.327239990234375 +38519 -0.2769775390625 +38520 -0.253692626953125 +38521 -0.24365234375 +38522 -0.1983642578125 +38523 -0.116241455078125 +38524 -0.036834716796875 +38525 0.034881591796875 +38526 0.09124755859375 +38527 0.10888671875 +38528 0.125518798828125 +38529 0.15771484375 +38530 0.17828369140625 +38531 0.17108154296875 +38532 0.129974365234375 +38533 0.082427978515625 +38534 0.027679443359375 +38535 -0.065643310546875 +38536 -0.15936279296875 +38537 -0.21307373046875 +38538 -0.234649658203125 +38539 -0.2001953125 +38540 -0.119171142578125 +38541 -0.024749755859375 +38542 0.085784912109375 +38543 0.178131103515625 +38544 0.215576171875 +38545 0.211456298828125 +38546 0.17523193359375 +38547 0.128753662109375 +38548 0.1019287109375 +38549 0.0743408203125 +38550 0.04327392578125 +38551 0.038177490234375 +38552 0.076263427734375 +38553 0.14105224609375 +38554 0.186431884765625 +38555 0.188812255859375 +38556 0.1390380859375 +38557 0.041778564453125 +38558 -0.079437255859375 +38559 -0.219390869140625 +38560 -0.367828369140625 +38561 -0.494873046875 +38562 -0.556243896484375 +38563 -0.508697509765625 +38564 -0.3756103515625 +38565 -0.218902587890625 +38566 -0.063751220703125 +38567 0.091552734375 +38568 0.23602294921875 +38569 0.342987060546875 +38570 0.39520263671875 +38571 0.389373779296875 +38572 0.324249267578125 +38573 0.224090576171875 +38574 0.124267578125 +38575 0.037078857421875 +38576 -0.010101318359375 +38577 -0.019439697265625 +38578 -0.022796630859375 +38579 -0.001556396484375 +38580 0.056304931640625 +38581 0.106719970703125 +38582 0.096893310546875 +38583 0.042694091796875 +38584 -0.018035888671875 +38585 -0.07586669921875 +38586 -0.11944580078125 +38587 -0.15972900390625 +38588 -0.202606201171875 +38589 -0.24859619140625 +38590 -0.30517578125 +38591 -0.36212158203125 +38592 -0.39141845703125 +38593 -0.35528564453125 +38594 -0.249969482421875 +38595 -0.092864990234375 +38596 0.08905029296875 +38597 0.2352294921875 +38598 0.318817138671875 +38599 0.358642578125 +38600 0.347747802734375 +38601 0.28564453125 +38602 0.223175048828125 +38603 0.196746826171875 +38604 0.179840087890625 +38605 0.155548095703125 +38606 0.151214599609375 +38607 0.156951904296875 +38608 0.13177490234375 +38609 0.100799560546875 +38610 0.087127685546875 +38611 0.05487060546875 +38612 -0.009002685546875 +38613 -0.10400390625 +38614 -0.229400634765625 +38615 -0.35552978515625 +38616 -0.441925048828125 +38617 -0.473846435546875 +38618 -0.464813232421875 +38619 -0.419097900390625 +38620 -0.334320068359375 +38621 -0.227935791015625 +38622 -0.12347412109375 +38623 -0.02764892578125 +38624 0.077667236328125 +38625 0.2132568359375 +38626 0.38885498046875 +38627 0.582794189453125 +38628 0.734039306640625 +38629 0.800140380859375 +38630 0.7783203125 +38631 0.6651611328125 +38632 0.45965576171875 +38633 0.199188232421875 +38634 -0.050689697265625 +38635 -0.23297119140625 +38636 -0.33013916015625 +38637 -0.368408203125 +38638 -0.378936767578125 +38639 -0.376983642578125 +38640 -0.37969970703125 +38641 -0.391510009765625 +38642 -0.385345458984375 +38643 -0.3419189453125 +38644 -0.28289794921875 +38645 -0.251617431640625 +38646 -0.266143798828125 +38647 -0.273345947265625 +38648 -0.216796875 +38649 -0.128265380859375 +38650 -0.068145751953125 +38651 -0.0430908203125 +38652 -0.024444580078125 +38653 0.020721435546875 +38654 0.124481201171875 +38655 0.25787353515625 +38656 0.379119873046875 +38657 0.47991943359375 +38658 0.5281982421875 +38659 0.511138916015625 +38660 0.456207275390625 +38661 0.407470703125 +38662 0.383758544921875 +38663 0.35687255859375 +38664 0.31182861328125 +38665 0.250885009765625 +38666 0.1654052734375 +38667 0.035247802734375 +38668 -0.142059326171875 +38669 -0.33563232421875 +38670 -0.5345458984375 +38671 -0.72186279296875 +38672 -0.836669921875 +38673 -0.8326416015625 +38674 -0.7296142578125 +38675 -0.582550048828125 +38676 -0.440093994140625 +38677 -0.324310302734375 +38678 -0.20147705078125 +38679 -0.044647216796875 +38680 0.103973388671875 +38681 0.202392578125 +38682 0.264495849609375 +38683 0.338897705078125 +38684 0.443817138671875 +38685 0.545074462890625 +38686 0.6173095703125 +38687 0.6524658203125 +38688 0.66339111328125 +38689 0.6561279296875 +38690 0.606781005859375 +38691 0.501190185546875 +38692 0.352783203125 +38693 0.176544189453125 +38694 -0.034820556640625 +38695 -0.258209228515625 +38696 -0.44244384765625 +38697 -0.5753173828125 +38698 -0.65203857421875 +38699 -0.641632080078125 +38700 -0.562164306640625 +38701 -0.458038330078125 +38702 -0.350555419921875 +38703 -0.260528564453125 +38704 -0.192108154296875 +38705 -0.141937255859375 +38706 -0.1021728515625 +38707 -0.062896728515625 +38708 -0.011932373046875 +38709 0.062835693359375 +38710 0.148712158203125 +38711 0.241729736328125 +38712 0.34912109375 +38713 0.457305908203125 +38714 0.54388427734375 +38715 0.5728759765625 +38716 0.506591796875 +38717 0.351226806640625 +38718 0.146514892578125 +38719 -0.05523681640625 +38720 -0.21624755859375 +38721 -0.334930419921875 +38722 -0.402984619140625 +38723 -0.4412841796875 +38724 -0.49578857421875 +38725 -0.5601806640625 +38726 -0.600738525390625 +38727 -0.584228515625 +38728 -0.47930908203125 +38729 -0.27935791015625 +38730 -0.0089111328125 +38731 0.268798828125 +38732 0.482818603515625 +38733 0.60369873046875 +38734 0.650421142578125 +38735 0.66400146484375 +38736 0.6414794921875 +38737 0.572540283203125 +38738 0.498138427734375 +38739 0.439453125 +38740 0.375518798828125 +38741 0.274505615234375 +38742 0.1087646484375 +38743 -0.099395751953125 +38744 -0.3182373046875 +38745 -0.5489501953125 +38746 -0.7738037109375 +38747 -0.86383056640625 +38748 -0.870391845703125 +38749 -0.86895751953125 +38750 -0.861053466796875 +38751 -0.765869140625 +38752 -0.5301513671875 +38753 -0.214691162109375 +38754 0.137359619140625 +38755 0.474822998046875 +38756 0.76239013671875 +38757 0.867462158203125 +38758 0.870361328125 +38759 0.86480712890625 +38760 0.831817626953125 +38761 0.677581787109375 +38762 0.495880126953125 +38763 0.30767822265625 +38764 0.116180419921875 +38765 -0.110748291015625 +38766 -0.381805419921875 +38767 -0.6572265625 +38768 -0.857421875 +38769 -0.870391845703125 +38770 -0.870391845703125 +38771 -0.86444091796875 +38772 -0.85723876953125 +38773 -0.790008544921875 +38774 -0.62847900390625 +38775 -0.3956298828125 +38776 -0.126708984375 +38777 0.150115966796875 +38778 0.424041748046875 +38779 0.670623779296875 +38780 0.854522705078125 +38781 0.866485595703125 +38782 0.86920166015625 +38783 0.8653564453125 +38784 0.857147216796875 +38785 0.766845703125 +38786 0.628509521484375 +38787 0.462127685546875 +38788 0.297210693359375 +38789 0.14862060546875 +38790 -0.00537109375 +38791 -0.15753173828125 +38792 -0.31304931640625 +38793 -0.48876953125 +38794 -0.6416015625 +38795 -0.751373291015625 +38796 -0.84619140625 +38797 -0.861297607421875 +38798 -0.863250732421875 +38799 -0.856597900390625 +38800 -0.7498779296875 +38801 -0.624542236328125 +38802 -0.47808837890625 +38803 -0.253387451171875 +38804 0.003692626953125 +38805 0.2257080078125 +38806 0.427154541015625 +38807 0.643218994140625 +38808 0.855926513671875 +38809 0.870361328125 +38810 0.870361328125 +38811 0.862762451171875 +38812 0.79669189453125 +38813 0.595794677734375 +38814 0.362152099609375 +38815 0.1270751953125 +38816 -0.086944580078125 +38817 -0.2784423828125 +38818 -0.484832763671875 +38819 -0.729583740234375 +38820 -0.86688232421875 +38821 -0.870391845703125 +38822 -0.86859130859375 +38823 -0.86279296875 +38824 -0.817962646484375 +38825 -0.6116943359375 +38826 -0.3128662109375 +38827 0.039398193359375 +38828 0.422821044921875 +38829 0.805145263671875 +38830 0.870361328125 +38831 0.870361328125 +38832 0.860015869140625 +38833 0.727935791015625 +38834 0.48114013671875 +38835 0.2059326171875 +38836 -0.06103515625 +38837 -0.29913330078125 +38838 -0.516204833984375 +38839 -0.7252197265625 +38840 -0.85980224609375 +38841 -0.870391845703125 +38842 -0.870391845703125 +38843 -0.858062744140625 +38844 -0.673004150390625 +38845 -0.42694091796875 +38846 -0.2100830078125 +38847 -0.0362548828125 +38848 0.10943603515625 +38849 0.23516845703125 +38850 0.373687744140625 +38851 0.517791748046875 +38852 0.602783203125 +38853 0.635711669921875 +38854 0.655181884765625 +38855 0.65948486328125 +38856 0.651275634765625 +38857 0.61846923828125 +38858 0.53753662109375 +38859 0.404144287109375 +38860 0.22186279296875 +38861 0.003997802734375 +38862 -0.22100830078125 +38863 -0.42449951171875 +38864 -0.579833984375 +38865 -0.641876220703125 +38866 -0.6177978515625 +38867 -0.575531005859375 +38868 -0.526336669921875 +38869 -0.42645263671875 +38870 -0.2581787109375 +38871 -0.068695068359375 +38872 0.09222412109375 +38873 0.232147216796875 +38874 0.3509521484375 +38875 0.410064697265625 +38876 0.372955322265625 +38877 0.2554931640625 +38878 0.10711669921875 +38879 -0.052886962890625 +38880 -0.186279296875 +38881 -0.23291015625 +38882 -0.209442138671875 +38883 -0.174163818359375 +38884 -0.126739501953125 +38885 -0.048126220703125 +38886 0.0426025390625 +38887 0.10748291015625 +38888 0.1409912109375 +38889 0.19708251953125 +38890 0.273651123046875 +38891 0.31768798828125 +38892 0.341094970703125 +38893 0.368011474609375 +38894 0.37249755859375 +38895 0.30072021484375 +38896 0.1517333984375 +38897 -0.01470947265625 +38898 -0.1883544921875 +38899 -0.372711181640625 +38900 -0.51397705078125 +38901 -0.57177734375 +38902 -0.53948974609375 +38903 -0.43511962890625 +38904 -0.2962646484375 +38905 -0.161102294921875 +38906 -0.0435791015625 +38907 0.060394287109375 +38908 0.13665771484375 +38909 0.170135498046875 +38910 0.16552734375 +38911 0.15728759765625 +38912 0.150787353515625 +38913 0.12200927734375 +38914 0.080108642578125 +38915 0.05126953125 +38916 0.062896728515625 +38917 0.09271240234375 +38918 0.092987060546875 +38919 0.07855224609375 +38920 0.06427001953125 +38921 0.0347900390625 +38922 -0.01171875 +38923 -0.056060791015625 +38924 -0.055511474609375 +38925 -0.010467529296875 +38926 0.02508544921875 +38927 0.025665283203125 +38928 0.017333984375 +38929 0.00189208984375 +38930 -0.03173828125 +38931 -0.071502685546875 +38932 -0.13543701171875 +38933 -0.219970703125 +38934 -0.300506591796875 +38935 -0.376312255859375 +38936 -0.416107177734375 +38937 -0.371124267578125 +38938 -0.242279052734375 +38939 -0.069732666015625 +38940 0.125640869140625 +38941 0.31268310546875 +38942 0.45501708984375 +38943 0.554779052734375 +38944 0.61065673828125 +38945 0.610931396484375 +38946 0.531463623046875 +38947 0.3883056640625 +38948 0.23468017578125 +38949 0.095245361328125 +38950 -0.00396728515625 +38951 -0.04852294921875 +38952 -0.055145263671875 +38953 -0.0758056640625 +38954 -0.138702392578125 +38955 -0.209197998046875 +38956 -0.289031982421875 +38957 -0.37884521484375 +38958 -0.456329345703125 +38959 -0.51641845703125 +38960 -0.519287109375 +38961 -0.458251953125 +38962 -0.384796142578125 +38963 -0.323699951171875 +38964 -0.269287109375 +38965 -0.1951904296875 +38966 -0.100006103515625 +38967 -0.01055908203125 +38968 0.1033935546875 +38969 0.24908447265625 +38970 0.373199462890625 +38971 0.45806884765625 +38972 0.511474609375 +38973 0.565399169921875 +38974 0.61138916015625 +38975 0.5897216796875 +38976 0.4906005859375 +38977 0.33148193359375 +38978 0.147796630859375 +38979 -0.01873779296875 +38980 -0.140289306640625 +38981 -0.191986083984375 +38982 -0.184295654296875 +38983 -0.161834716796875 +38984 -0.166595458984375 +38985 -0.19390869140625 +38986 -0.22442626953125 +38987 -0.279754638671875 +38988 -0.3389892578125 +38989 -0.3543701171875 +38990 -0.348175048828125 +38991 -0.32598876953125 +38992 -0.2581787109375 +38993 -0.139801025390625 +38994 0.014617919921875 +38995 0.144378662109375 +38996 0.221038818359375 +38997 0.27069091796875 +38998 0.294036865234375 +38999 0.311767578125 +39000 0.339141845703125 +39001 0.360260009765625 +39002 0.360504150390625 +39003 0.308380126953125 +39004 0.18170166015625 +39005 0.0047607421875 +39006 -0.17559814453125 +39007 -0.3143310546875 +39008 -0.36785888671875 +39009 -0.36248779296875 +39010 -0.343536376953125 +39011 -0.3018798828125 +39012 -0.231414794921875 +39013 -0.117645263671875 +39014 0.007049560546875 +39015 0.087982177734375 +39016 0.13946533203125 +39017 0.17425537109375 +39018 0.188201904296875 +39019 0.171234130859375 +39020 0.118438720703125 +39021 0.05706787109375 +39022 -0.010711669921875 +39023 -0.0914306640625 +39024 -0.162322998046875 +39025 -0.194549560546875 +39026 -0.1492919921875 +39027 -0.02166748046875 +39028 0.124053955078125 +39029 0.211151123046875 +39030 0.240447998046875 +39031 0.242218017578125 +39032 0.2257080078125 +39033 0.194366455078125 +39034 0.115509033203125 +39035 0.0128173828125 +39036 -0.053802490234375 +39037 -0.110626220703125 +39038 -0.199493408203125 +39039 -0.29437255859375 +39040 -0.33221435546875 +39041 -0.27972412109375 +39042 -0.185333251953125 +39043 -0.128204345703125 +39044 -0.115692138671875 +39045 -0.116455078125 +39046 -0.105926513671875 +39047 -0.053955078125 +39048 0.048797607421875 +39049 0.157318115234375 +39050 0.212005615234375 +39051 0.218475341796875 +39052 0.23724365234375 +39053 0.30535888671875 +39054 0.38128662109375 +39055 0.404449462890625 +39056 0.3944091796875 +39057 0.3885498046875 +39058 0.362640380859375 +39059 0.27362060546875 +39060 0.11712646484375 +39061 -0.054901123046875 +39062 -0.19085693359375 +39063 -0.28570556640625 +39064 -0.339263916015625 +39065 -0.3775634765625 +39066 -0.445709228515625 +39067 -0.535064697265625 +39068 -0.629058837890625 +39069 -0.697601318359375 +39070 -0.70391845703125 +39071 -0.6424560546875 +39072 -0.491241455078125 +39073 -0.265716552734375 +39074 -0.023712158203125 +39075 0.201751708984375 +39076 0.375823974609375 +39077 0.485076904296875 +39078 0.56884765625 +39079 0.634765625 +39080 0.63763427734375 +39081 0.5660400390625 +39082 0.4720458984375 +39083 0.40692138671875 +39084 0.3778076171875 +39085 0.376953125 +39086 0.371978759765625 +39087 0.313140869140625 +39088 0.184417724609375 +39089 0.011199951171875 +39090 -0.171051025390625 +39091 -0.33740234375 +39092 -0.47198486328125 +39093 -0.560394287109375 +39094 -0.58056640625 +39095 -0.54754638671875 +39096 -0.508575439453125 +39097 -0.459503173828125 +39098 -0.394378662109375 +39099 -0.35260009765625 +39100 -0.31170654296875 +39101 -0.197418212890625 +39102 -0.007965087890625 +39103 0.207489013671875 +39104 0.409210205078125 +39105 0.57208251953125 +39106 0.66595458984375 +39107 0.65875244140625 +39108 0.56744384765625 +39109 0.431396484375 +39110 0.29443359375 +39111 0.182464599609375 +39112 0.06365966796875 +39113 -0.075958251953125 +39114 -0.189422607421875 +39115 -0.271942138671875 +39116 -0.342529296875 +39117 -0.364166259765625 +39118 -0.327239990234375 +39119 -0.2769775390625 +39120 -0.253692626953125 +39121 -0.24365234375 +39122 -0.1983642578125 +39123 -0.116241455078125 +39124 -0.036834716796875 +39125 0.034881591796875 +39126 0.09124755859375 +39127 0.10888671875 +39128 0.125518798828125 +39129 0.15771484375 +39130 0.17828369140625 +39131 0.17108154296875 +39132 0.129974365234375 +39133 0.082427978515625 +39134 0.027679443359375 +39135 -0.065643310546875 +39136 -0.15936279296875 +39137 -0.21307373046875 +39138 -0.234649658203125 +39139 -0.2001953125 +39140 -0.119171142578125 +39141 -0.024749755859375 +39142 0.085784912109375 +39143 0.178131103515625 +39144 0.215576171875 +39145 0.211456298828125 +39146 0.17523193359375 +39147 0.128753662109375 +39148 0.1019287109375 +39149 0.0743408203125 +39150 0.04327392578125 +39151 0.038177490234375 +39152 0.076263427734375 +39153 0.14105224609375 +39154 0.186431884765625 +39155 0.188812255859375 +39156 0.1390380859375 +39157 0.041778564453125 +39158 -0.079437255859375 +39159 -0.219390869140625 +39160 -0.367828369140625 +39161 -0.494873046875 +39162 -0.556243896484375 +39163 -0.508697509765625 +39164 -0.3756103515625 +39165 -0.218902587890625 +39166 -0.063751220703125 +39167 0.091552734375 +39168 0.23602294921875 +39169 0.342987060546875 +39170 0.39520263671875 +39171 0.389373779296875 +39172 0.324249267578125 +39173 0.224090576171875 +39174 0.124267578125 +39175 0.037078857421875 +39176 -0.010101318359375 +39177 -0.019439697265625 +39178 -0.022796630859375 +39179 -0.001556396484375 +39180 0.056304931640625 +39181 0.106719970703125 +39182 0.096893310546875 +39183 0.042694091796875 +39184 -0.018035888671875 +39185 -0.07586669921875 +39186 -0.11944580078125 +39187 -0.15972900390625 +39188 -0.202606201171875 +39189 -0.24859619140625 +39190 -0.30517578125 +39191 -0.36212158203125 +39192 -0.39141845703125 +39193 -0.35528564453125 +39194 -0.249969482421875 +39195 -0.092864990234375 +39196 0.08905029296875 +39197 0.2352294921875 +39198 0.318817138671875 +39199 0.358642578125 +39200 0.347747802734375 +39201 0.28564453125 +39202 0.223175048828125 +39203 0.196746826171875 +39204 0.179840087890625 +39205 0.155548095703125 +39206 0.151214599609375 +39207 0.156951904296875 +39208 0.13177490234375 +39209 0.100799560546875 +39210 0.087127685546875 +39211 0.05487060546875 +39212 -0.009002685546875 +39213 -0.10400390625 +39214 -0.229400634765625 +39215 -0.35552978515625 +39216 -0.441925048828125 +39217 -0.473846435546875 +39218 -0.464813232421875 +39219 -0.419097900390625 +39220 -0.334320068359375 +39221 -0.227935791015625 +39222 -0.12347412109375 +39223 -0.02764892578125 +39224 0.077667236328125 +39225 0.2132568359375 +39226 0.38885498046875 +39227 0.582794189453125 +39228 0.734039306640625 +39229 0.800140380859375 +39230 0.7783203125 +39231 0.6651611328125 +39232 0.45965576171875 +39233 0.199188232421875 +39234 -0.050689697265625 +39235 -0.23297119140625 +39236 -0.33013916015625 +39237 -0.368408203125 +39238 -0.378936767578125 +39239 -0.376983642578125 +39240 -0.37969970703125 +39241 -0.391510009765625 +39242 -0.385345458984375 +39243 -0.3419189453125 +39244 -0.28289794921875 +39245 -0.251617431640625 +39246 -0.266143798828125 +39247 -0.273345947265625 +39248 -0.216796875 +39249 -0.128265380859375 +39250 -0.068145751953125 +39251 -0.0430908203125 +39252 -0.024444580078125 +39253 0.020721435546875 +39254 0.124481201171875 +39255 0.25787353515625 +39256 0.379119873046875 +39257 0.47991943359375 +39258 0.5281982421875 +39259 0.511138916015625 +39260 0.456207275390625 +39261 0.407470703125 +39262 0.383758544921875 +39263 0.35687255859375 +39264 0.31182861328125 +39265 0.250885009765625 +39266 0.1654052734375 +39267 0.035247802734375 +39268 -0.142059326171875 +39269 -0.33563232421875 +39270 -0.5345458984375 +39271 -0.72186279296875 +39272 -0.836669921875 +39273 -0.8326416015625 +39274 -0.7296142578125 +39275 -0.582550048828125 +39276 -0.440093994140625 +39277 -0.324310302734375 +39278 -0.20147705078125 +39279 -0.044647216796875 +39280 0.103973388671875 +39281 0.202392578125 +39282 0.264495849609375 +39283 0.338897705078125 +39284 0.443817138671875 +39285 0.545074462890625 +39286 0.6173095703125 +39287 0.6524658203125 +39288 0.66339111328125 +39289 0.6561279296875 +39290 0.606781005859375 +39291 0.501190185546875 +39292 0.352783203125 +39293 0.176544189453125 +39294 -0.034820556640625 +39295 -0.258209228515625 +39296 -0.44244384765625 +39297 -0.5753173828125 +39298 -0.65203857421875 +39299 -0.641632080078125 +39300 -0.562164306640625 +39301 -0.458038330078125 +39302 -0.350555419921875 +39303 -0.260528564453125 +39304 -0.192108154296875 +39305 -0.141937255859375 +39306 -0.1021728515625 +39307 -0.062896728515625 +39308 -0.011932373046875 +39309 0.062835693359375 +39310 0.148712158203125 +39311 0.241729736328125 +39312 0.34912109375 +39313 0.457305908203125 +39314 0.54388427734375 +39315 0.5728759765625 +39316 0.506591796875 +39317 0.351226806640625 +39318 0.146514892578125 +39319 -0.05523681640625 +39320 -0.21624755859375 +39321 -0.334930419921875 +39322 -0.402984619140625 +39323 -0.4412841796875 +39324 -0.49578857421875 +39325 -0.5601806640625 +39326 -0.600738525390625 +39327 -0.584228515625 +39328 -0.47930908203125 +39329 -0.27935791015625 +39330 -0.0089111328125 +39331 0.268798828125 +39332 0.482818603515625 +39333 0.60369873046875 +39334 0.650421142578125 +39335 0.66400146484375 +39336 0.6414794921875 +39337 0.572540283203125 +39338 0.498138427734375 +39339 0.439453125 +39340 0.375518798828125 +39341 0.274505615234375 +39342 0.1087646484375 +39343 -0.099395751953125 +39344 -0.3182373046875 +39345 -0.5489501953125 +39346 -0.7738037109375 +39347 -0.86383056640625 +39348 -0.870391845703125 +39349 -0.86895751953125 +39350 -0.861053466796875 +39351 -0.765869140625 +39352 -0.5301513671875 +39353 -0.214691162109375 +39354 0.137359619140625 +39355 0.474822998046875 +39356 0.76239013671875 +39357 0.867462158203125 +39358 0.870361328125 +39359 0.86480712890625 +39360 0.831817626953125 +39361 0.677581787109375 +39362 0.495880126953125 +39363 0.30767822265625 +39364 0.116180419921875 +39365 -0.110748291015625 +39366 -0.381805419921875 +39367 -0.6572265625 +39368 -0.857421875 +39369 -0.870391845703125 +39370 -0.870391845703125 +39371 -0.86444091796875 +39372 -0.85723876953125 +39373 -0.790008544921875 +39374 -0.62847900390625 +39375 -0.3956298828125 +39376 -0.126708984375 +39377 0.150115966796875 +39378 0.424041748046875 +39379 0.670623779296875 +39380 0.854522705078125 +39381 0.866485595703125 +39382 0.86920166015625 +39383 0.8653564453125 +39384 0.857147216796875 +39385 0.766845703125 +39386 0.628509521484375 +39387 0.462127685546875 +39388 0.297210693359375 +39389 0.14862060546875 +39390 -0.00537109375 +39391 -0.15753173828125 +39392 -0.31304931640625 +39393 -0.48876953125 +39394 -0.6416015625 +39395 -0.751373291015625 +39396 -0.84619140625 +39397 -0.861297607421875 +39398 -0.863250732421875 +39399 -0.856597900390625 +39400 -0.7498779296875 +39401 -0.624542236328125 +39402 -0.47808837890625 +39403 -0.253387451171875 +39404 0.003692626953125 +39405 0.2257080078125 +39406 0.427154541015625 +39407 0.643218994140625 +39408 0.855926513671875 +39409 0.870361328125 +39410 0.870361328125 +39411 0.862762451171875 +39412 0.79669189453125 +39413 0.595794677734375 +39414 0.362152099609375 +39415 0.1270751953125 +39416 -0.086944580078125 +39417 -0.2784423828125 +39418 -0.484832763671875 +39419 -0.729583740234375 +39420 -0.86688232421875 +39421 -0.870391845703125 +39422 -0.86859130859375 +39423 -0.86279296875 +39424 -0.817962646484375 +39425 -0.6116943359375 +39426 -0.3128662109375 +39427 0.039398193359375 +39428 0.422821044921875 +39429 0.805145263671875 +39430 0.870361328125 +39431 0.870361328125 +39432 0.860015869140625 +39433 0.727935791015625 +39434 0.48114013671875 +39435 0.2059326171875 +39436 -0.06103515625 +39437 -0.29913330078125 +39438 -0.516204833984375 +39439 -0.7252197265625 +39440 -0.85980224609375 +39441 -0.870391845703125 +39442 -0.870391845703125 +39443 -0.858062744140625 +39444 -0.673004150390625 +39445 -0.42694091796875 +39446 -0.2100830078125 +39447 -0.0362548828125 +39448 0.10943603515625 +39449 0.23516845703125 +39450 0.373687744140625 +39451 0.517791748046875 +39452 0.602783203125 +39453 0.635711669921875 +39454 0.655181884765625 +39455 0.65948486328125 +39456 0.651275634765625 +39457 0.61846923828125 +39458 0.53753662109375 +39459 0.404144287109375 +39460 0.22186279296875 +39461 0.003997802734375 +39462 -0.22100830078125 +39463 -0.42449951171875 +39464 -0.579833984375 +39465 -0.641876220703125 +39466 -0.6177978515625 +39467 -0.575531005859375 +39468 -0.526336669921875 +39469 -0.42645263671875 +39470 -0.2581787109375 +39471 -0.068695068359375 +39472 0.09222412109375 +39473 0.232147216796875 +39474 0.3509521484375 +39475 0.410064697265625 +39476 0.372955322265625 +39477 0.2554931640625 +39478 0.10711669921875 +39479 -0.052886962890625 +39480 -0.186279296875 +39481 -0.23291015625 +39482 -0.209442138671875 +39483 -0.174163818359375 +39484 -0.126739501953125 +39485 -0.048126220703125 +39486 0.0426025390625 +39487 0.10748291015625 +39488 0.1409912109375 +39489 0.19708251953125 +39490 0.273651123046875 +39491 0.31768798828125 +39492 0.341094970703125 +39493 0.368011474609375 +39494 0.37249755859375 +39495 0.30072021484375 +39496 0.1517333984375 +39497 -0.01470947265625 +39498 -0.1883544921875 +39499 -0.372711181640625 +39500 -0.51397705078125 +39501 -0.57177734375 +39502 -0.53948974609375 +39503 -0.43511962890625 +39504 -0.2962646484375 +39505 -0.161102294921875 +39506 -0.0435791015625 +39507 0.060394287109375 +39508 0.13665771484375 +39509 0.170135498046875 +39510 0.16552734375 +39511 0.15728759765625 +39512 0.150787353515625 +39513 0.12200927734375 +39514 0.080108642578125 +39515 0.05126953125 +39516 0.062896728515625 +39517 0.09271240234375 +39518 0.092987060546875 +39519 0.07855224609375 +39520 0.06427001953125 +39521 0.0347900390625 +39522 -0.01171875 +39523 -0.056060791015625 +39524 -0.055511474609375 +39525 -0.010467529296875 +39526 0.02508544921875 +39527 0.025665283203125 +39528 0.017333984375 +39529 0.00189208984375 +39530 -0.03173828125 +39531 -0.071502685546875 +39532 -0.13543701171875 +39533 -0.219970703125 +39534 -0.300506591796875 +39535 -0.376312255859375 +39536 -0.416107177734375 +39537 -0.371124267578125 +39538 -0.242279052734375 +39539 -0.069732666015625 +39540 0.125640869140625 +39541 0.31268310546875 +39542 0.45501708984375 +39543 0.554779052734375 +39544 0.61065673828125 +39545 0.610931396484375 +39546 0.531463623046875 +39547 0.3883056640625 +39548 0.23468017578125 +39549 0.095245361328125 +39550 -0.00396728515625 +39551 -0.04852294921875 +39552 -0.055145263671875 +39553 -0.0758056640625 +39554 -0.138702392578125 +39555 -0.209197998046875 +39556 -0.289031982421875 +39557 -0.37884521484375 +39558 -0.456329345703125 +39559 -0.51641845703125 +39560 -0.519287109375 +39561 -0.458251953125 +39562 -0.384796142578125 +39563 -0.323699951171875 +39564 -0.269287109375 +39565 -0.1951904296875 +39566 -0.100006103515625 +39567 -0.01055908203125 +39568 0.1033935546875 +39569 0.24908447265625 +39570 0.373199462890625 +39571 0.45806884765625 +39572 0.511474609375 +39573 0.565399169921875 +39574 0.61138916015625 +39575 0.5897216796875 +39576 0.4906005859375 +39577 0.33148193359375 +39578 0.147796630859375 +39579 -0.01873779296875 +39580 -0.140289306640625 +39581 -0.191986083984375 +39582 -0.184295654296875 +39583 -0.161834716796875 +39584 -0.166595458984375 +39585 -0.19390869140625 +39586 -0.22442626953125 +39587 -0.279754638671875 +39588 -0.3389892578125 +39589 -0.3543701171875 +39590 -0.348175048828125 +39591 -0.32598876953125 +39592 -0.2581787109375 +39593 -0.139801025390625 +39594 0.014617919921875 +39595 0.144378662109375 +39596 0.221038818359375 +39597 0.27069091796875 +39598 0.294036865234375 +39599 0.311767578125 +39600 0.339141845703125 +39601 0.360260009765625 +39602 0.360504150390625 +39603 0.308380126953125 +39604 0.18170166015625 +39605 0.0047607421875 +39606 -0.17559814453125 +39607 -0.3143310546875 +39608 -0.36785888671875 +39609 -0.36248779296875 +39610 -0.343536376953125 +39611 -0.3018798828125 +39612 -0.231414794921875 +39613 -0.117645263671875 +39614 0.007049560546875 +39615 0.087982177734375 +39616 0.13946533203125 +39617 0.17425537109375 +39618 0.188201904296875 +39619 0.171234130859375 +39620 0.118438720703125 +39621 0.05706787109375 +39622 -0.010711669921875 +39623 -0.0914306640625 +39624 -0.162322998046875 +39625 -0.194549560546875 +39626 -0.1492919921875 +39627 -0.02166748046875 +39628 0.124053955078125 +39629 0.211151123046875 +39630 0.240447998046875 +39631 0.242218017578125 +39632 0.2257080078125 +39633 0.194366455078125 +39634 0.115509033203125 +39635 0.0128173828125 +39636 -0.053802490234375 +39637 -0.110626220703125 +39638 -0.199493408203125 +39639 -0.29437255859375 +39640 -0.33221435546875 +39641 -0.27972412109375 +39642 -0.185333251953125 +39643 -0.128204345703125 +39644 -0.115692138671875 +39645 -0.116455078125 +39646 -0.105926513671875 +39647 -0.053955078125 +39648 0.048797607421875 +39649 0.157318115234375 +39650 0.212005615234375 +39651 0.218475341796875 +39652 0.23724365234375 +39653 0.30535888671875 +39654 0.38128662109375 +39655 0.404449462890625 +39656 0.3944091796875 +39657 0.3885498046875 +39658 0.362640380859375 +39659 0.27362060546875 +39660 0.11712646484375 +39661 -0.054901123046875 +39662 -0.19085693359375 +39663 -0.28570556640625 +39664 -0.339263916015625 +39665 -0.3775634765625 +39666 -0.445709228515625 +39667 -0.535064697265625 +39668 -0.629058837890625 +39669 -0.697601318359375 +39670 -0.70391845703125 +39671 -0.6424560546875 +39672 -0.491241455078125 +39673 -0.265716552734375 +39674 -0.023712158203125 +39675 0.201751708984375 +39676 0.375823974609375 +39677 0.485076904296875 +39678 0.56884765625 +39679 0.634765625 +39680 0.63763427734375 +39681 0.5660400390625 +39682 0.4720458984375 +39683 0.40692138671875 +39684 0.3778076171875 +39685 0.376953125 +39686 0.371978759765625 +39687 0.313140869140625 +39688 0.184417724609375 +39689 0.011199951171875 +39690 -0.171051025390625 +39691 -0.33740234375 +39692 -0.47198486328125 +39693 -0.560394287109375 +39694 -0.58056640625 +39695 -0.54754638671875 +39696 -0.508575439453125 +39697 -0.459503173828125 +39698 -0.394378662109375 +39699 -0.35260009765625 +39700 -0.31170654296875 +39701 -0.197418212890625 +39702 -0.007965087890625 +39703 0.207489013671875 +39704 0.409210205078125 +39705 0.57208251953125 +39706 0.66595458984375 +39707 0.65875244140625 +39708 0.56744384765625 +39709 0.431396484375 +39710 0.29443359375 +39711 0.182464599609375 +39712 0.06365966796875 +39713 -0.075958251953125 +39714 -0.189422607421875 +39715 -0.271942138671875 +39716 -0.342529296875 +39717 -0.364166259765625 +39718 -0.327239990234375 +39719 -0.2769775390625 +39720 -0.253692626953125 +39721 -0.24365234375 +39722 -0.1983642578125 +39723 -0.116241455078125 +39724 -0.036834716796875 +39725 0.034881591796875 +39726 0.09124755859375 +39727 0.10888671875 +39728 0.125518798828125 +39729 0.15771484375 +39730 0.17828369140625 +39731 0.17108154296875 +39732 0.129974365234375 +39733 0.082427978515625 +39734 0.027679443359375 +39735 -0.065643310546875 +39736 -0.15936279296875 +39737 -0.21307373046875 +39738 -0.234649658203125 +39739 -0.2001953125 +39740 -0.119171142578125 +39741 -0.024749755859375 +39742 0.085784912109375 +39743 0.178131103515625 +39744 0.215576171875 +39745 0.211456298828125 +39746 0.17523193359375 +39747 0.128753662109375 +39748 0.1019287109375 +39749 0.0743408203125 +39750 0.04327392578125 +39751 0.038177490234375 +39752 0.076263427734375 +39753 0.14105224609375 +39754 0.186431884765625 +39755 0.188812255859375 +39756 0.1390380859375 +39757 0.041778564453125 +39758 -0.079437255859375 +39759 -0.219390869140625 +39760 -0.367828369140625 +39761 -0.494873046875 +39762 -0.556243896484375 +39763 -0.508697509765625 +39764 -0.3756103515625 +39765 -0.218902587890625 +39766 -0.063751220703125 +39767 0.091552734375 +39768 0.23602294921875 +39769 0.342987060546875 +39770 0.39520263671875 +39771 0.389373779296875 +39772 0.324249267578125 +39773 0.224090576171875 +39774 0.124267578125 +39775 0.037078857421875 +39776 -0.010101318359375 +39777 -0.019439697265625 +39778 -0.022796630859375 +39779 -0.001556396484375 +39780 0.056304931640625 +39781 0.106719970703125 +39782 0.096893310546875 +39783 0.042694091796875 +39784 -0.018035888671875 +39785 -0.07586669921875 +39786 -0.11944580078125 +39787 -0.15972900390625 +39788 -0.202606201171875 +39789 -0.24859619140625 +39790 -0.30517578125 +39791 -0.36212158203125 +39792 -0.39141845703125 +39793 -0.35528564453125 +39794 -0.249969482421875 +39795 -0.092864990234375 +39796 0.08905029296875 +39797 0.2352294921875 +39798 0.318817138671875 +39799 0.358642578125 +39800 0.347747802734375 +39801 0.28564453125 +39802 0.223175048828125 +39803 0.196746826171875 +39804 0.179840087890625 +39805 0.155548095703125 +39806 0.151214599609375 +39807 0.156951904296875 +39808 0.13177490234375 +39809 0.100799560546875 +39810 0.087127685546875 +39811 0.05487060546875 +39812 -0.009002685546875 +39813 -0.10400390625 +39814 -0.229400634765625 +39815 -0.35552978515625 +39816 -0.441925048828125 +39817 -0.473846435546875 +39818 -0.464813232421875 +39819 -0.419097900390625 +39820 -0.334320068359375 +39821 -0.227935791015625 +39822 -0.12347412109375 +39823 -0.02764892578125 +39824 0.077667236328125 +39825 0.2132568359375 +39826 0.38885498046875 +39827 0.582794189453125 +39828 0.734039306640625 +39829 0.800140380859375 +39830 0.7783203125 +39831 0.6651611328125 +39832 0.45965576171875 +39833 0.199188232421875 +39834 -0.050689697265625 +39835 -0.23297119140625 +39836 -0.33013916015625 +39837 -0.368408203125 +39838 -0.378936767578125 +39839 -0.376983642578125 +39840 -0.37969970703125 +39841 -0.391510009765625 +39842 -0.385345458984375 +39843 -0.3419189453125 +39844 -0.28289794921875 +39845 -0.251617431640625 +39846 -0.266143798828125 +39847 -0.273345947265625 +39848 -0.216796875 +39849 -0.128265380859375 +39850 -0.068145751953125 +39851 -0.0430908203125 +39852 -0.024444580078125 +39853 0.020721435546875 +39854 0.124481201171875 +39855 0.25787353515625 +39856 0.379119873046875 +39857 0.47991943359375 +39858 0.5281982421875 +39859 0.511138916015625 +39860 0.456207275390625 +39861 0.407470703125 +39862 0.383758544921875 +39863 0.35687255859375 +39864 0.31182861328125 +39865 0.250885009765625 +39866 0.1654052734375 +39867 0.035247802734375 +39868 -0.142059326171875 +39869 -0.33563232421875 +39870 -0.5345458984375 +39871 -0.72186279296875 +39872 -0.836669921875 +39873 -0.8326416015625 +39874 -0.7296142578125 +39875 -0.582550048828125 +39876 -0.440093994140625 +39877 -0.324310302734375 +39878 -0.20147705078125 +39879 -0.044647216796875 +39880 0.103973388671875 +39881 0.202392578125 +39882 0.264495849609375 +39883 0.338897705078125 +39884 0.443817138671875 +39885 0.545074462890625 +39886 0.6173095703125 +39887 0.6524658203125 +39888 0.66339111328125 +39889 0.6561279296875 +39890 0.606781005859375 +39891 0.501190185546875 +39892 0.352783203125 +39893 0.176544189453125 +39894 -0.034820556640625 +39895 -0.258209228515625 +39896 -0.44244384765625 +39897 -0.5753173828125 +39898 -0.65203857421875 +39899 -0.641632080078125 +39900 -0.562164306640625 +39901 -0.458038330078125 +39902 -0.350555419921875 +39903 -0.260528564453125 +39904 -0.192108154296875 +39905 -0.141937255859375 +39906 -0.1021728515625 +39907 -0.062896728515625 +39908 -0.011932373046875 +39909 0.062835693359375 +39910 0.148712158203125 +39911 0.241729736328125 +39912 0.34912109375 +39913 0.457305908203125 +39914 0.54388427734375 +39915 0.5728759765625 +39916 0.506591796875 +39917 0.351226806640625 +39918 0.146514892578125 +39919 -0.05523681640625 +39920 -0.21624755859375 +39921 -0.334930419921875 +39922 -0.402984619140625 +39923 -0.4412841796875 +39924 -0.49578857421875 +39925 -0.5601806640625 +39926 -0.600738525390625 +39927 -0.584228515625 +39928 -0.47930908203125 +39929 -0.27935791015625 +39930 -0.0089111328125 +39931 0.268798828125 +39932 0.482818603515625 +39933 0.60369873046875 +39934 0.650421142578125 +39935 0.66400146484375 +39936 0.6414794921875 +39937 0.572540283203125 +39938 0.498138427734375 +39939 0.439453125 +39940 0.375518798828125 +39941 0.274505615234375 +39942 0.1087646484375 +39943 -0.099395751953125 +39944 -0.3182373046875 +39945 -0.5489501953125 +39946 -0.7738037109375 +39947 -0.86383056640625 +39948 -0.870391845703125 +39949 -0.86895751953125 +39950 -0.861053466796875 +39951 -0.765869140625 +39952 -0.5301513671875 +39953 -0.214691162109375 +39954 0.137359619140625 +39955 0.474822998046875 +39956 0.76239013671875 +39957 0.867462158203125 +39958 0.870361328125 +39959 0.86480712890625 +39960 0.831817626953125 +39961 0.677581787109375 +39962 0.495880126953125 +39963 0.30767822265625 +39964 0.116180419921875 +39965 -0.110748291015625 +39966 -0.381805419921875 +39967 -0.6572265625 +39968 -0.857421875 +39969 -0.870391845703125 +39970 -0.870391845703125 +39971 -0.86444091796875 +39972 -0.85723876953125 +39973 -0.790008544921875 +39974 -0.62847900390625 +39975 -0.3956298828125 +39976 -0.126708984375 +39977 0.150115966796875 +39978 0.424041748046875 +39979 0.670623779296875 +39980 0.854522705078125 +39981 0.866485595703125 +39982 0.86920166015625 +39983 0.8653564453125 +39984 0.857147216796875 +39985 0.766845703125 +39986 0.628509521484375 +39987 0.462127685546875 +39988 0.297210693359375 +39989 0.14862060546875 +39990 -0.00537109375 +39991 -0.15753173828125 +39992 -0.31304931640625 +39993 -0.48876953125 +39994 -0.6416015625 +39995 -0.751373291015625 +39996 -0.84619140625 +39997 -0.861297607421875 +39998 -0.863250732421875 +39999 -0.856597900390625 +40000 -0.7498779296875 +40001 -0.624542236328125 +40002 -0.47808837890625 +40003 -0.253387451171875 +40004 0.003692626953125 +40005 0.2257080078125 +40006 0.427154541015625 +40007 0.643218994140625 +40008 0.855926513671875 +40009 0.870361328125 +40010 0.870361328125 +40011 0.862762451171875 +40012 0.79669189453125 +40013 0.595794677734375 +40014 0.362152099609375 +40015 0.1270751953125 +40016 -0.086944580078125 +40017 -0.2784423828125 +40018 -0.484832763671875 +40019 -0.729583740234375 +40020 -0.86688232421875 +40021 -0.870391845703125 +40022 -0.86859130859375 +40023 -0.86279296875 +40024 -0.817962646484375 +40025 -0.6116943359375 +40026 -0.3128662109375 +40027 0.039398193359375 +40028 0.422821044921875 +40029 0.805145263671875 +40030 0.870361328125 +40031 0.870361328125 +40032 0.860015869140625 +40033 0.727935791015625 +40034 0.48114013671875 +40035 0.2059326171875 +40036 -0.06103515625 +40037 -0.29913330078125 +40038 -0.516204833984375 +40039 -0.7252197265625 +40040 -0.85980224609375 +40041 -0.870391845703125 +40042 -0.870391845703125 +40043 -0.858062744140625 +40044 -0.673004150390625 +40045 -0.42694091796875 +40046 -0.2100830078125 +40047 -0.0362548828125 +40048 0.10943603515625 +40049 0.23516845703125 +40050 0.373687744140625 +40051 0.517791748046875 +40052 0.602783203125 +40053 0.635711669921875 +40054 0.655181884765625 +40055 0.65948486328125 +40056 0.651275634765625 +40057 0.61846923828125 +40058 0.53753662109375 +40059 0.404144287109375 +40060 0.22186279296875 +40061 0.003997802734375 +40062 -0.22100830078125 +40063 -0.42449951171875 +40064 -0.579833984375 +40065 -0.641876220703125 +40066 -0.6177978515625 +40067 -0.575531005859375 +40068 -0.526336669921875 +40069 -0.42645263671875 +40070 -0.2581787109375 +40071 -0.068695068359375 +40072 0.09222412109375 +40073 0.232147216796875 +40074 0.3509521484375 +40075 0.410064697265625 +40076 0.372955322265625 +40077 0.2554931640625 +40078 0.10711669921875 +40079 -0.052886962890625 +40080 -0.186279296875 +40081 -0.23291015625 +40082 -0.209442138671875 +40083 -0.174163818359375 +40084 -0.126739501953125 +40085 -0.048126220703125 +40086 0.0426025390625 +40087 0.10748291015625 +40088 0.1409912109375 +40089 0.19708251953125 +40090 0.273651123046875 +40091 0.31768798828125 +40092 0.341094970703125 +40093 0.368011474609375 +40094 0.37249755859375 +40095 0.30072021484375 +40096 0.1517333984375 +40097 -0.01470947265625 +40098 -0.1883544921875 +40099 -0.372711181640625 +40100 -0.51397705078125 +40101 -0.57177734375 +40102 -0.53948974609375 +40103 -0.43511962890625 +40104 -0.2962646484375 +40105 -0.161102294921875 +40106 -0.0435791015625 +40107 0.060394287109375 +40108 0.13665771484375 +40109 0.170135498046875 +40110 0.16552734375 +40111 0.15728759765625 +40112 0.150787353515625 +40113 0.12200927734375 +40114 0.080108642578125 +40115 0.05126953125 +40116 0.062896728515625 +40117 0.09271240234375 +40118 0.092987060546875 +40119 0.07855224609375 +40120 0.06427001953125 +40121 0.0347900390625 +40122 -0.01171875 +40123 -0.056060791015625 +40124 -0.055511474609375 +40125 -0.010467529296875 +40126 0.02508544921875 +40127 0.025665283203125 +40128 0.017333984375 +40129 0.00189208984375 +40130 -0.03173828125 +40131 -0.071502685546875 +40132 -0.13543701171875 +40133 -0.219970703125 +40134 -0.300506591796875 +40135 -0.376312255859375 +40136 -0.416107177734375 +40137 -0.371124267578125 +40138 -0.242279052734375 +40139 -0.069732666015625 +40140 0.125640869140625 +40141 0.31268310546875 +40142 0.45501708984375 +40143 0.554779052734375 +40144 0.61065673828125 +40145 0.610931396484375 +40146 0.531463623046875 +40147 0.3883056640625 +40148 0.23468017578125 +40149 0.095245361328125 +40150 -0.00396728515625 +40151 -0.04852294921875 +40152 -0.055145263671875 +40153 -0.0758056640625 +40154 -0.138702392578125 +40155 -0.209197998046875 +40156 -0.289031982421875 +40157 -0.37884521484375 +40158 -0.456329345703125 +40159 -0.51641845703125 +40160 -0.519287109375 +40161 -0.458251953125 +40162 -0.384796142578125 +40163 -0.323699951171875 +40164 -0.269287109375 +40165 -0.1951904296875 +40166 -0.100006103515625 +40167 -0.01055908203125 +40168 0.1033935546875 +40169 0.24908447265625 +40170 0.373199462890625 +40171 0.45806884765625 +40172 0.511474609375 +40173 0.565399169921875 +40174 0.61138916015625 +40175 0.5897216796875 +40176 0.4906005859375 +40177 0.33148193359375 +40178 0.147796630859375 +40179 -0.01873779296875 +40180 -0.140289306640625 +40181 -0.191986083984375 +40182 -0.184295654296875 +40183 -0.161834716796875 +40184 -0.166595458984375 +40185 -0.19390869140625 +40186 -0.22442626953125 +40187 -0.279754638671875 +40188 -0.3389892578125 +40189 -0.3543701171875 +40190 -0.348175048828125 +40191 -0.32598876953125 +40192 -0.2581787109375 +40193 -0.139801025390625 +40194 0.014617919921875 +40195 0.144378662109375 +40196 0.221038818359375 +40197 0.27069091796875 +40198 0.294036865234375 +40199 0.311767578125 +40200 0.339141845703125 +40201 0.360260009765625 +40202 0.360504150390625 +40203 0.308380126953125 +40204 0.18170166015625 +40205 0.0047607421875 +40206 -0.17559814453125 +40207 -0.3143310546875 +40208 -0.36785888671875 +40209 -0.36248779296875 +40210 -0.343536376953125 +40211 -0.3018798828125 +40212 -0.231414794921875 +40213 -0.117645263671875 +40214 0.007049560546875 +40215 0.087982177734375 +40216 0.13946533203125 +40217 0.17425537109375 +40218 0.188201904296875 +40219 0.171234130859375 +40220 0.118438720703125 +40221 0.05706787109375 +40222 -0.010711669921875 +40223 -0.0914306640625 +40224 -0.162322998046875 +40225 -0.194549560546875 +40226 -0.1492919921875 +40227 -0.02166748046875 +40228 0.124053955078125 +40229 0.211151123046875 +40230 0.240447998046875 +40231 0.242218017578125 +40232 0.2257080078125 +40233 0.194366455078125 +40234 0.115509033203125 +40235 0.0128173828125 +40236 -0.053802490234375 +40237 -0.110626220703125 +40238 -0.199493408203125 +40239 -0.29437255859375 +40240 -0.33221435546875 +40241 -0.27972412109375 +40242 -0.185333251953125 +40243 -0.128204345703125 +40244 -0.115692138671875 +40245 -0.116455078125 +40246 -0.105926513671875 +40247 -0.053955078125 +40248 0.048797607421875 +40249 0.157318115234375 +40250 0.212005615234375 +40251 0.218475341796875 +40252 0.23724365234375 +40253 0.30535888671875 +40254 0.38128662109375 +40255 0.404449462890625 +40256 0.3944091796875 +40257 0.3885498046875 +40258 0.362640380859375 +40259 0.27362060546875 +40260 0.11712646484375 +40261 -0.054901123046875 +40262 -0.19085693359375 +40263 -0.28570556640625 +40264 -0.339263916015625 +40265 -0.3775634765625 +40266 -0.445709228515625 +40267 -0.535064697265625 +40268 -0.629058837890625 +40269 -0.697601318359375 +40270 -0.70391845703125 +40271 -0.6424560546875 +40272 -0.491241455078125 +40273 -0.265716552734375 +40274 -0.023712158203125 +40275 0.201751708984375 +40276 0.375823974609375 +40277 0.485076904296875 +40278 0.56884765625 +40279 0.634765625 +40280 0.63763427734375 +40281 0.5660400390625 +40282 0.4720458984375 +40283 0.40692138671875 +40284 0.3778076171875 +40285 0.376953125 +40286 0.371978759765625 +40287 0.313140869140625 +40288 0.184417724609375 +40289 0.011199951171875 +40290 -0.171051025390625 +40291 -0.33740234375 +40292 -0.47198486328125 +40293 -0.560394287109375 +40294 -0.58056640625 +40295 -0.54754638671875 +40296 -0.508575439453125 +40297 -0.459503173828125 +40298 -0.394378662109375 +40299 -0.35260009765625 +40300 -0.31170654296875 +40301 -0.197418212890625 +40302 -0.007965087890625 +40303 0.207489013671875 +40304 0.409210205078125 +40305 0.57208251953125 +40306 0.66595458984375 +40307 0.65875244140625 +40308 0.56744384765625 +40309 0.431396484375 +40310 0.29443359375 +40311 0.182464599609375 +40312 0.06365966796875 +40313 -0.075958251953125 +40314 -0.189422607421875 +40315 -0.271942138671875 +40316 -0.342529296875 +40317 -0.364166259765625 +40318 -0.327239990234375 +40319 -0.2769775390625 +40320 -0.253692626953125 +40321 -0.24365234375 +40322 -0.1983642578125 +40323 -0.116241455078125 +40324 -0.036834716796875 +40325 0.034881591796875 +40326 0.09124755859375 +40327 0.10888671875 +40328 0.125518798828125 +40329 0.15771484375 +40330 0.17828369140625 +40331 0.17108154296875 +40332 0.129974365234375 +40333 0.082427978515625 +40334 0.027679443359375 +40335 -0.065643310546875 +40336 -0.15936279296875 +40337 -0.21307373046875 +40338 -0.234649658203125 +40339 -0.2001953125 +40340 -0.119171142578125 +40341 -0.024749755859375 +40342 0.085784912109375 +40343 0.178131103515625 +40344 0.215576171875 +40345 0.211456298828125 +40346 0.17523193359375 +40347 0.128753662109375 +40348 0.1019287109375 +40349 0.0743408203125 +40350 0.04327392578125 +40351 0.038177490234375 +40352 0.076263427734375 +40353 0.14105224609375 +40354 0.186431884765625 +40355 0.188812255859375 +40356 0.1390380859375 +40357 0.041778564453125 +40358 -0.079437255859375 +40359 -0.219390869140625 +40360 -0.367828369140625 +40361 -0.494873046875 +40362 -0.556243896484375 +40363 -0.508697509765625 +40364 -0.3756103515625 +40365 -0.218902587890625 +40366 -0.063751220703125 +40367 0.091552734375 +40368 0.23602294921875 +40369 0.342987060546875 +40370 0.39520263671875 +40371 0.389373779296875 +40372 0.324249267578125 +40373 0.224090576171875 +40374 0.124267578125 +40375 0.037078857421875 +40376 -0.010101318359375 +40377 -0.019439697265625 +40378 -0.022796630859375 +40379 -0.001556396484375 +40380 0.056304931640625 +40381 0.106719970703125 +40382 0.096893310546875 +40383 0.042694091796875 +40384 -0.018035888671875 +40385 -0.07586669921875 +40386 -0.11944580078125 +40387 -0.15972900390625 +40388 -0.202606201171875 +40389 -0.24859619140625 +40390 -0.30517578125 +40391 -0.36212158203125 +40392 -0.39141845703125 +40393 -0.35528564453125 +40394 -0.249969482421875 +40395 -0.092864990234375 +40396 0.08905029296875 +40397 0.2352294921875 +40398 0.318817138671875 +40399 0.358642578125 +40400 0.347747802734375 +40401 0.28564453125 +40402 0.223175048828125 +40403 0.196746826171875 +40404 0.179840087890625 +40405 0.155548095703125 +40406 0.151214599609375 +40407 0.156951904296875 +40408 0.13177490234375 +40409 0.100799560546875 +40410 0.087127685546875 +40411 0.05487060546875 +40412 -0.009002685546875 +40413 -0.10400390625 +40414 -0.229400634765625 +40415 -0.35552978515625 +40416 -0.441925048828125 +40417 -0.473846435546875 +40418 -0.464813232421875 +40419 -0.419097900390625 +40420 -0.334320068359375 +40421 -0.227935791015625 +40422 -0.12347412109375 +40423 -0.02764892578125 +40424 0.077667236328125 +40425 0.2132568359375 +40426 0.38885498046875 +40427 0.582794189453125 +40428 0.734039306640625 +40429 0.800140380859375 +40430 0.7783203125 +40431 0.6651611328125 +40432 0.45965576171875 +40433 0.199188232421875 +40434 -0.050689697265625 +40435 -0.23297119140625 +40436 -0.33013916015625 +40437 -0.368408203125 +40438 -0.378936767578125 +40439 -0.376983642578125 +40440 -0.37969970703125 +40441 -0.391510009765625 +40442 -0.385345458984375 +40443 -0.3419189453125 +40444 -0.28289794921875 +40445 -0.251617431640625 +40446 -0.266143798828125 +40447 -0.273345947265625 +40448 -0.216796875 +40449 -0.128265380859375 +40450 -0.068145751953125 +40451 -0.0430908203125 +40452 -0.024444580078125 +40453 0.020721435546875 +40454 0.124481201171875 +40455 0.25787353515625 +40456 0.379119873046875 +40457 0.47991943359375 +40458 0.5281982421875 +40459 0.511138916015625 +40460 0.456207275390625 +40461 0.407470703125 +40462 0.383758544921875 +40463 0.35687255859375 +40464 0.31182861328125 +40465 0.250885009765625 +40466 0.1654052734375 +40467 0.035247802734375 +40468 -0.142059326171875 +40469 -0.33563232421875 +40470 -0.5345458984375 +40471 -0.72186279296875 +40472 -0.836669921875 +40473 -0.8326416015625 +40474 -0.7296142578125 +40475 -0.582550048828125 +40476 -0.440093994140625 +40477 -0.324310302734375 +40478 -0.20147705078125 +40479 -0.044647216796875 +40480 0.103973388671875 +40481 0.202392578125 +40482 0.264495849609375 +40483 0.338897705078125 +40484 0.443817138671875 +40485 0.545074462890625 +40486 0.6173095703125 +40487 0.6524658203125 +40488 0.66339111328125 +40489 0.6561279296875 +40490 0.606781005859375 +40491 0.501190185546875 +40492 0.352783203125 +40493 0.176544189453125 +40494 -0.034820556640625 +40495 -0.258209228515625 +40496 -0.44244384765625 +40497 -0.5753173828125 +40498 -0.65203857421875 +40499 -0.641632080078125 +40500 -0.562164306640625 +40501 -0.458038330078125 +40502 -0.350555419921875 +40503 -0.260528564453125 +40504 -0.192108154296875 +40505 -0.141937255859375 +40506 -0.1021728515625 +40507 -0.062896728515625 +40508 -0.011932373046875 +40509 0.062835693359375 +40510 0.148712158203125 +40511 0.241729736328125 +40512 0.34912109375 +40513 0.457305908203125 +40514 0.54388427734375 +40515 0.5728759765625 +40516 0.506591796875 +40517 0.351226806640625 +40518 0.146514892578125 +40519 -0.05523681640625 +40520 -0.21624755859375 +40521 -0.334930419921875 +40522 -0.402984619140625 +40523 -0.4412841796875 +40524 -0.49578857421875 +40525 -0.5601806640625 +40526 -0.600738525390625 +40527 -0.584228515625 +40528 -0.47930908203125 +40529 -0.27935791015625 +40530 -0.0089111328125 +40531 0.268798828125 +40532 0.482818603515625 +40533 0.60369873046875 +40534 0.650421142578125 +40535 0.66400146484375 +40536 0.6414794921875 +40537 0.572540283203125 +40538 0.498138427734375 +40539 0.439453125 +40540 0.375518798828125 +40541 0.274505615234375 +40542 0.1087646484375 +40543 -0.099395751953125 +40544 -0.3182373046875 +40545 -0.5489501953125 +40546 -0.7738037109375 +40547 -0.86383056640625 +40548 -0.870391845703125 +40549 -0.86895751953125 +40550 -0.861053466796875 +40551 -0.765869140625 +40552 -0.5301513671875 +40553 -0.214691162109375 +40554 0.137359619140625 +40555 0.474822998046875 +40556 0.76239013671875 +40557 0.867462158203125 +40558 0.870361328125 +40559 0.86480712890625 +40560 0.831817626953125 +40561 0.677581787109375 +40562 0.495880126953125 +40563 0.30767822265625 +40564 0.116180419921875 +40565 -0.110748291015625 +40566 -0.381805419921875 +40567 -0.6572265625 +40568 -0.857421875 +40569 -0.870391845703125 +40570 -0.870391845703125 +40571 -0.86444091796875 +40572 -0.85723876953125 +40573 -0.790008544921875 +40574 -0.62847900390625 +40575 -0.3956298828125 +40576 -0.126708984375 +40577 0.150115966796875 +40578 0.424041748046875 +40579 0.670623779296875 +40580 0.854522705078125 +40581 0.866485595703125 +40582 0.86920166015625 +40583 0.8653564453125 +40584 0.857147216796875 +40585 0.766845703125 +40586 0.628509521484375 +40587 0.462127685546875 +40588 0.297210693359375 +40589 0.14862060546875 +40590 -0.00537109375 +40591 -0.15753173828125 +40592 -0.31304931640625 +40593 -0.48876953125 +40594 -0.6416015625 +40595 -0.751373291015625 +40596 -0.84619140625 +40597 -0.861297607421875 +40598 -0.863250732421875 +40599 -0.856597900390625 +40600 -0.7498779296875 +40601 -0.624542236328125 +40602 -0.47808837890625 +40603 -0.253387451171875 +40604 0.003692626953125 +40605 0.2257080078125 +40606 0.427154541015625 +40607 0.643218994140625 +40608 0.855926513671875 +40609 0.870361328125 +40610 0.870361328125 +40611 0.862762451171875 +40612 0.79669189453125 +40613 0.595794677734375 +40614 0.362152099609375 +40615 0.1270751953125 +40616 -0.086944580078125 +40617 -0.2784423828125 +40618 -0.484832763671875 +40619 -0.729583740234375 +40620 -0.86688232421875 +40621 -0.870391845703125 +40622 -0.86859130859375 +40623 -0.86279296875 +40624 -0.817962646484375 +40625 -0.6116943359375 +40626 -0.3128662109375 +40627 0.039398193359375 +40628 0.422821044921875 +40629 0.805145263671875 +40630 0.870361328125 +40631 0.870361328125 +40632 0.860015869140625 +40633 0.727935791015625 +40634 0.48114013671875 +40635 0.2059326171875 +40636 -0.06103515625 +40637 -0.29913330078125 +40638 -0.516204833984375 +40639 -0.7252197265625 +40640 -0.85980224609375 +40641 -0.870391845703125 +40642 -0.870391845703125 +40643 -0.858062744140625 +40644 -0.673004150390625 +40645 -0.42694091796875 +40646 -0.2100830078125 +40647 -0.0362548828125 +40648 0.10943603515625 +40649 0.23516845703125 +40650 0.373687744140625 +40651 0.517791748046875 +40652 0.602783203125 +40653 0.635711669921875 +40654 0.655181884765625 +40655 0.65948486328125 +40656 0.651275634765625 +40657 0.61846923828125 +40658 0.53753662109375 +40659 0.404144287109375 +40660 0.22186279296875 +40661 0.003997802734375 +40662 -0.22100830078125 +40663 -0.42449951171875 +40664 -0.579833984375 +40665 -0.641876220703125 +40666 -0.6177978515625 +40667 -0.575531005859375 +40668 -0.526336669921875 +40669 -0.42645263671875 +40670 -0.2581787109375 +40671 -0.068695068359375 +40672 0.09222412109375 +40673 0.232147216796875 +40674 0.3509521484375 +40675 0.410064697265625 +40676 0.372955322265625 +40677 0.2554931640625 +40678 0.10711669921875 +40679 -0.052886962890625 +40680 -0.186279296875 +40681 -0.23291015625 +40682 -0.209442138671875 +40683 -0.174163818359375 +40684 -0.126739501953125 +40685 -0.048126220703125 +40686 0.0426025390625 +40687 0.10748291015625 +40688 0.1409912109375 +40689 0.19708251953125 +40690 0.273651123046875 +40691 0.31768798828125 +40692 0.341094970703125 +40693 0.368011474609375 +40694 0.37249755859375 +40695 0.30072021484375 +40696 0.1517333984375 +40697 -0.01470947265625 +40698 -0.1883544921875 +40699 -0.372711181640625 +40700 -0.51397705078125 +40701 -0.57177734375 +40702 -0.53948974609375 +40703 -0.43511962890625 +40704 -0.2962646484375 +40705 -0.161102294921875 +40706 -0.0435791015625 +40707 0.060394287109375 +40708 0.13665771484375 +40709 0.170135498046875 +40710 0.16552734375 +40711 0.15728759765625 +40712 0.150787353515625 +40713 0.12200927734375 +40714 0.080108642578125 +40715 0.05126953125 +40716 0.062896728515625 +40717 0.09271240234375 +40718 0.092987060546875 +40719 0.07855224609375 +40720 0.06427001953125 +40721 0.0347900390625 +40722 -0.01171875 +40723 -0.056060791015625 +40724 -0.055511474609375 +40725 -0.010467529296875 +40726 0.02508544921875 +40727 0.025665283203125 +40728 0.017333984375 +40729 0.00189208984375 +40730 -0.03173828125 +40731 -0.071502685546875 +40732 -0.13543701171875 +40733 -0.219970703125 +40734 -0.300506591796875 +40735 -0.376312255859375 +40736 -0.416107177734375 +40737 -0.371124267578125 +40738 -0.242279052734375 +40739 -0.069732666015625 +40740 0.125640869140625 +40741 0.31268310546875 +40742 0.45501708984375 +40743 0.554779052734375 +40744 0.61065673828125 +40745 0.610931396484375 +40746 0.531463623046875 +40747 0.3883056640625 +40748 0.23468017578125 +40749 0.095245361328125 +40750 -0.00396728515625 +40751 -0.04852294921875 +40752 -0.055145263671875 +40753 -0.0758056640625 +40754 -0.138702392578125 +40755 -0.209197998046875 +40756 -0.289031982421875 +40757 -0.37884521484375 +40758 -0.456329345703125 +40759 -0.51641845703125 +40760 -0.519287109375 +40761 -0.458251953125 +40762 -0.384796142578125 +40763 -0.323699951171875 +40764 -0.269287109375 +40765 -0.1951904296875 +40766 -0.100006103515625 +40767 -0.01055908203125 +40768 0.1033935546875 +40769 0.24908447265625 +40770 0.373199462890625 +40771 0.45806884765625 +40772 0.511474609375 +40773 0.565399169921875 +40774 0.61138916015625 +40775 0.5897216796875 +40776 0.4906005859375 +40777 0.33148193359375 +40778 0.147796630859375 +40779 -0.01873779296875 +40780 -0.140289306640625 +40781 -0.191986083984375 +40782 -0.184295654296875 +40783 -0.161834716796875 +40784 -0.166595458984375 +40785 -0.19390869140625 +40786 -0.22442626953125 +40787 -0.279754638671875 +40788 -0.3389892578125 +40789 -0.3543701171875 +40790 -0.348175048828125 +40791 -0.32598876953125 +40792 -0.2581787109375 +40793 -0.139801025390625 +40794 0.014617919921875 +40795 0.144378662109375 +40796 0.221038818359375 +40797 0.27069091796875 +40798 0.294036865234375 +40799 0.311767578125 +40800 0.339141845703125 +40801 0.360260009765625 +40802 0.360504150390625 +40803 0.308380126953125 +40804 0.18170166015625 +40805 0.0047607421875 +40806 -0.17559814453125 +40807 -0.3143310546875 +40808 -0.36785888671875 +40809 -0.36248779296875 +40810 -0.343536376953125 +40811 -0.3018798828125 +40812 -0.231414794921875 +40813 -0.117645263671875 +40814 0.007049560546875 +40815 0.087982177734375 +40816 0.13946533203125 +40817 0.17425537109375 +40818 0.188201904296875 +40819 0.171234130859375 +40820 0.118438720703125 +40821 0.05706787109375 +40822 -0.010711669921875 +40823 -0.0914306640625 +40824 -0.162322998046875 +40825 -0.194549560546875 +40826 -0.1492919921875 +40827 -0.02166748046875 +40828 0.124053955078125 +40829 0.211151123046875 +40830 0.240447998046875 +40831 0.242218017578125 +40832 0.2257080078125 +40833 0.194366455078125 +40834 0.115509033203125 +40835 0.0128173828125 +40836 -0.053802490234375 +40837 -0.110626220703125 +40838 -0.199493408203125 +40839 -0.29437255859375 +40840 -0.33221435546875 +40841 -0.27972412109375 +40842 -0.185333251953125 +40843 -0.128204345703125 +40844 -0.115692138671875 +40845 -0.116455078125 +40846 -0.105926513671875 +40847 -0.053955078125 +40848 0.048797607421875 +40849 0.157318115234375 +40850 0.212005615234375 +40851 0.218475341796875 +40852 0.23724365234375 +40853 0.30535888671875 +40854 0.38128662109375 +40855 0.404449462890625 +40856 0.3944091796875 +40857 0.3885498046875 +40858 0.362640380859375 +40859 0.27362060546875 +40860 0.11712646484375 +40861 -0.054901123046875 +40862 -0.19085693359375 +40863 -0.28570556640625 +40864 -0.339263916015625 +40865 -0.3775634765625 +40866 -0.445709228515625 +40867 -0.535064697265625 +40868 -0.629058837890625 +40869 -0.697601318359375 +40870 -0.70391845703125 +40871 -0.6424560546875 +40872 -0.491241455078125 +40873 -0.265716552734375 +40874 -0.023712158203125 +40875 0.201751708984375 +40876 0.375823974609375 +40877 0.485076904296875 +40878 0.56884765625 +40879 0.634765625 +40880 0.63763427734375 +40881 0.5660400390625 +40882 0.4720458984375 +40883 0.40692138671875 +40884 0.3778076171875 +40885 0.376953125 +40886 0.371978759765625 +40887 0.313140869140625 +40888 0.184417724609375 +40889 0.011199951171875 +40890 -0.171051025390625 +40891 -0.33740234375 +40892 -0.47198486328125 +40893 -0.560394287109375 +40894 -0.58056640625 +40895 -0.54754638671875 +40896 -0.508575439453125 +40897 -0.459503173828125 +40898 -0.394378662109375 +40899 -0.35260009765625 +40900 -0.31170654296875 +40901 -0.197418212890625 +40902 -0.007965087890625 +40903 0.207489013671875 +40904 0.409210205078125 +40905 0.57208251953125 +40906 0.66595458984375 +40907 0.65875244140625 +40908 0.56744384765625 +40909 0.431396484375 +40910 0.29443359375 +40911 0.182464599609375 +40912 0.06365966796875 +40913 -0.075958251953125 +40914 -0.189422607421875 +40915 -0.271942138671875 +40916 -0.342529296875 +40917 -0.364166259765625 +40918 -0.327239990234375 +40919 -0.2769775390625 +40920 -0.253692626953125 +40921 -0.24365234375 +40922 -0.1983642578125 +40923 -0.116241455078125 +40924 -0.036834716796875 +40925 0.034881591796875 +40926 0.09124755859375 +40927 0.10888671875 +40928 0.125518798828125 +40929 0.15771484375 +40930 0.17828369140625 +40931 0.17108154296875 +40932 0.129974365234375 +40933 0.082427978515625 +40934 0.027679443359375 +40935 -0.065643310546875 +40936 -0.15936279296875 +40937 -0.21307373046875 +40938 -0.234649658203125 +40939 -0.2001953125 +40940 -0.119171142578125 +40941 -0.024749755859375 +40942 0.085784912109375 +40943 0.178131103515625 +40944 0.215576171875 +40945 0.211456298828125 +40946 0.17523193359375 +40947 0.128753662109375 +40948 0.1019287109375 +40949 0.0743408203125 +40950 0.04327392578125 +40951 0.038177490234375 +40952 0.076263427734375 +40953 0.14105224609375 +40954 0.186431884765625 +40955 0.188812255859375 +40956 0.1390380859375 +40957 0.041778564453125 +40958 -0.079437255859375 +40959 -0.219390869140625 +40960 -0.367828369140625 +40961 -0.494873046875 +40962 -0.556243896484375 +40963 -0.508697509765625 +40964 -0.3756103515625 +40965 -0.218902587890625 +40966 -0.063751220703125 +40967 0.091552734375 +40968 0.23602294921875 +40969 0.342987060546875 +40970 0.39520263671875 +40971 0.389373779296875 +40972 0.324249267578125 +40973 0.224090576171875 +40974 0.124267578125 +40975 0.037078857421875 +40976 -0.010101318359375 +40977 -0.019439697265625 +40978 -0.022796630859375 +40979 -0.001556396484375 +40980 0.056304931640625 +40981 0.106719970703125 +40982 0.096893310546875 +40983 0.042694091796875 +40984 -0.018035888671875 +40985 -0.07586669921875 +40986 -0.11944580078125 +40987 -0.15972900390625 +40988 -0.202606201171875 +40989 -0.24859619140625 +40990 -0.30517578125 +40991 -0.36212158203125 +40992 -0.39141845703125 +40993 -0.35528564453125 +40994 -0.249969482421875 +40995 -0.092864990234375 +40996 0.08905029296875 +40997 0.2352294921875 +40998 0.318817138671875 +40999 0.358642578125 +41000 0.347747802734375 +41001 0.28564453125 +41002 0.223175048828125 +41003 0.196746826171875 +41004 0.179840087890625 +41005 0.155548095703125 +41006 0.151214599609375 +41007 0.156951904296875 +41008 0.13177490234375 +41009 0.100799560546875 +41010 0.087127685546875 +41011 0.05487060546875 +41012 -0.009002685546875 +41013 -0.10400390625 +41014 -0.229400634765625 +41015 -0.35552978515625 +41016 -0.441925048828125 +41017 -0.473846435546875 +41018 -0.464813232421875 +41019 -0.419097900390625 +41020 -0.334320068359375 +41021 -0.227935791015625 +41022 -0.12347412109375 +41023 -0.02764892578125 +41024 0.077667236328125 +41025 0.2132568359375 +41026 0.38885498046875 +41027 0.582794189453125 +41028 0.734039306640625 +41029 0.800140380859375 +41030 0.7783203125 +41031 0.6651611328125 +41032 0.45965576171875 +41033 0.199188232421875 +41034 -0.050689697265625 +41035 -0.23297119140625 +41036 -0.33013916015625 +41037 -0.368408203125 +41038 -0.378936767578125 +41039 -0.376983642578125 +41040 -0.37969970703125 +41041 -0.391510009765625 +41042 -0.385345458984375 +41043 -0.3419189453125 +41044 -0.28289794921875 +41045 -0.251617431640625 +41046 -0.266143798828125 +41047 -0.273345947265625 +41048 -0.216796875 +41049 -0.128265380859375 +41050 -0.068145751953125 +41051 -0.0430908203125 +41052 -0.024444580078125 +41053 0.020721435546875 +41054 0.124481201171875 +41055 0.25787353515625 +41056 0.379119873046875 +41057 0.47991943359375 +41058 0.5281982421875 +41059 0.511138916015625 +41060 0.456207275390625 +41061 0.407470703125 +41062 0.383758544921875 +41063 0.35687255859375 +41064 0.31182861328125 +41065 0.250885009765625 +41066 0.1654052734375 +41067 0.035247802734375 +41068 -0.142059326171875 +41069 -0.33563232421875 +41070 -0.5345458984375 +41071 -0.72186279296875 +41072 -0.836669921875 +41073 -0.8326416015625 +41074 -0.7296142578125 +41075 -0.582550048828125 +41076 -0.440093994140625 +41077 -0.324310302734375 +41078 -0.20147705078125 +41079 -0.044647216796875 +41080 0.103973388671875 +41081 0.202392578125 +41082 0.264495849609375 +41083 0.338897705078125 +41084 0.443817138671875 +41085 0.545074462890625 +41086 0.6173095703125 +41087 0.6524658203125 +41088 0.66339111328125 +41089 0.6561279296875 +41090 0.606781005859375 +41091 0.501190185546875 +41092 0.352783203125 +41093 0.176544189453125 +41094 -0.034820556640625 +41095 -0.258209228515625 +41096 -0.44244384765625 +41097 -0.5753173828125 +41098 -0.65203857421875 +41099 -0.641632080078125 +41100 -0.562164306640625 +41101 -0.458038330078125 +41102 -0.350555419921875 +41103 -0.260528564453125 +41104 -0.192108154296875 +41105 -0.141937255859375 +41106 -0.1021728515625 +41107 -0.062896728515625 +41108 -0.011932373046875 +41109 0.062835693359375 +41110 0.148712158203125 +41111 0.241729736328125 +41112 0.34912109375 +41113 0.457305908203125 +41114 0.54388427734375 +41115 0.5728759765625 +41116 0.506591796875 +41117 0.351226806640625 +41118 0.146514892578125 +41119 -0.05523681640625 +41120 -0.21624755859375 +41121 -0.334930419921875 +41122 -0.402984619140625 +41123 -0.4412841796875 +41124 -0.49578857421875 +41125 -0.5601806640625 +41126 -0.600738525390625 +41127 -0.584228515625 +41128 -0.47930908203125 +41129 -0.27935791015625 +41130 -0.0089111328125 +41131 0.268798828125 +41132 0.482818603515625 +41133 0.60369873046875 +41134 0.650421142578125 +41135 0.66400146484375 +41136 0.6414794921875 +41137 0.572540283203125 +41138 0.498138427734375 +41139 0.439453125 +41140 0.375518798828125 +41141 0.274505615234375 +41142 0.1087646484375 +41143 -0.099395751953125 +41144 -0.3182373046875 +41145 -0.5489501953125 +41146 -0.7738037109375 +41147 -0.86383056640625 +41148 -0.870391845703125 +41149 -0.86895751953125 +41150 -0.861053466796875 +41151 -0.765869140625 +41152 -0.5301513671875 +41153 -0.214691162109375 +41154 0.137359619140625 +41155 0.474822998046875 +41156 0.76239013671875 +41157 0.867462158203125 +41158 0.870361328125 +41159 0.86480712890625 +41160 0.831817626953125 +41161 0.677581787109375 +41162 0.495880126953125 +41163 0.30767822265625 +41164 0.116180419921875 +41165 -0.110748291015625 +41166 -0.381805419921875 +41167 -0.6572265625 +41168 -0.857421875 +41169 -0.870391845703125 +41170 -0.870391845703125 +41171 -0.86444091796875 +41172 -0.85723876953125 +41173 -0.790008544921875 +41174 -0.62847900390625 +41175 -0.3956298828125 +41176 -0.126708984375 +41177 0.150115966796875 +41178 0.424041748046875 +41179 0.670623779296875 +41180 0.854522705078125 +41181 0.866485595703125 +41182 0.86920166015625 +41183 0.8653564453125 +41184 0.857147216796875 +41185 0.766845703125 +41186 0.628509521484375 +41187 0.462127685546875 +41188 0.297210693359375 +41189 0.14862060546875 +41190 -0.00537109375 +41191 -0.15753173828125 +41192 -0.31304931640625 +41193 -0.48876953125 +41194 -0.6416015625 +41195 -0.751373291015625 +41196 -0.84619140625 +41197 -0.861297607421875 +41198 -0.863250732421875 +41199 -0.856597900390625 +41200 -0.7498779296875 +41201 -0.624542236328125 +41202 -0.47808837890625 +41203 -0.253387451171875 +41204 0.003692626953125 +41205 0.2257080078125 +41206 0.427154541015625 +41207 0.643218994140625 +41208 0.855926513671875 +41209 0.870361328125 +41210 0.870361328125 +41211 0.862762451171875 +41212 0.79669189453125 +41213 0.595794677734375 +41214 0.362152099609375 +41215 0.1270751953125 +41216 -0.086944580078125 +41217 -0.2784423828125 +41218 -0.484832763671875 +41219 -0.729583740234375 +41220 -0.86688232421875 +41221 -0.870391845703125 +41222 -0.86859130859375 +41223 -0.86279296875 +41224 -0.817962646484375 +41225 -0.6116943359375 +41226 -0.3128662109375 +41227 0.039398193359375 +41228 0.422821044921875 +41229 0.805145263671875 +41230 0.870361328125 +41231 0.870361328125 +41232 0.860015869140625 +41233 0.727935791015625 +41234 0.48114013671875 +41235 0.2059326171875 +41236 -0.06103515625 +41237 -0.29913330078125 +41238 -0.516204833984375 +41239 -0.7252197265625 +41240 -0.85980224609375 +41241 -0.870391845703125 +41242 -0.870391845703125 +41243 -0.858062744140625 +41244 -0.673004150390625 +41245 -0.42694091796875 +41246 -0.2100830078125 +41247 -0.0362548828125 +41248 0.10943603515625 +41249 0.23516845703125 +41250 0.373687744140625 +41251 0.517791748046875 +41252 0.602783203125 +41253 0.635711669921875 +41254 0.655181884765625 +41255 0.65948486328125 +41256 0.651275634765625 +41257 0.61846923828125 +41258 0.53753662109375 +41259 0.404144287109375 +41260 0.22186279296875 +41261 0.003997802734375 +41262 -0.22100830078125 +41263 -0.42449951171875 +41264 -0.579833984375 +41265 -0.641876220703125 +41266 -0.6177978515625 +41267 -0.575531005859375 +41268 -0.526336669921875 +41269 -0.42645263671875 +41270 -0.2581787109375 +41271 -0.068695068359375 +41272 0.09222412109375 +41273 0.232147216796875 +41274 0.3509521484375 +41275 0.410064697265625 +41276 0.372955322265625 +41277 0.2554931640625 +41278 0.10711669921875 +41279 -0.052886962890625 +41280 -0.186279296875 +41281 -0.23291015625 +41282 -0.209442138671875 +41283 -0.174163818359375 +41284 -0.126739501953125 +41285 -0.048126220703125 +41286 0.0426025390625 +41287 0.10748291015625 +41288 0.1409912109375 +41289 0.19708251953125 +41290 0.273651123046875 +41291 0.31768798828125 +41292 0.341094970703125 +41293 0.368011474609375 +41294 0.37249755859375 +41295 0.30072021484375 +41296 0.1517333984375 +41297 -0.01470947265625 +41298 -0.1883544921875 +41299 -0.372711181640625 +41300 -0.51397705078125 +41301 -0.57177734375 +41302 -0.53948974609375 +41303 -0.43511962890625 +41304 -0.2962646484375 +41305 -0.161102294921875 +41306 -0.0435791015625 +41307 0.060394287109375 +41308 0.13665771484375 +41309 0.170135498046875 +41310 0.16552734375 +41311 0.15728759765625 +41312 0.150787353515625 +41313 0.12200927734375 +41314 0.080108642578125 +41315 0.05126953125 +41316 0.062896728515625 +41317 0.09271240234375 +41318 0.092987060546875 +41319 0.07855224609375 +41320 0.06427001953125 +41321 0.0347900390625 +41322 -0.01171875 +41323 -0.056060791015625 +41324 -0.055511474609375 +41325 -0.010467529296875 +41326 0.02508544921875 +41327 0.025665283203125 +41328 0.017333984375 +41329 0.00189208984375 +41330 -0.03173828125 +41331 -0.071502685546875 +41332 -0.13543701171875 +41333 -0.219970703125 +41334 -0.300506591796875 +41335 -0.376312255859375 +41336 -0.416107177734375 +41337 -0.371124267578125 +41338 -0.242279052734375 +41339 -0.069732666015625 +41340 0.125640869140625 +41341 0.31268310546875 +41342 0.45501708984375 +41343 0.554779052734375 +41344 0.61065673828125 +41345 0.610931396484375 +41346 0.531463623046875 +41347 0.3883056640625 +41348 0.23468017578125 +41349 0.095245361328125 +41350 -0.00396728515625 +41351 -0.04852294921875 +41352 -0.055145263671875 +41353 -0.0758056640625 +41354 -0.138702392578125 +41355 -0.209197998046875 +41356 -0.289031982421875 +41357 -0.37884521484375 +41358 -0.456329345703125 +41359 -0.51641845703125 +41360 -0.519287109375 +41361 -0.458251953125 +41362 -0.384796142578125 +41363 -0.323699951171875 +41364 -0.269287109375 +41365 -0.1951904296875 +41366 -0.100006103515625 +41367 -0.01055908203125 +41368 0.1033935546875 +41369 0.24908447265625 +41370 0.373199462890625 +41371 0.45806884765625 +41372 0.511474609375 +41373 0.565399169921875 +41374 0.61138916015625 +41375 0.5897216796875 +41376 0.4906005859375 +41377 0.33148193359375 +41378 0.147796630859375 +41379 -0.01873779296875 +41380 -0.140289306640625 +41381 -0.191986083984375 +41382 -0.184295654296875 +41383 -0.161834716796875 +41384 -0.166595458984375 +41385 -0.19390869140625 +41386 -0.22442626953125 +41387 -0.279754638671875 +41388 -0.3389892578125 +41389 -0.3543701171875 +41390 -0.348175048828125 +41391 -0.32598876953125 +41392 -0.2581787109375 +41393 -0.139801025390625 +41394 0.014617919921875 +41395 0.144378662109375 +41396 0.221038818359375 +41397 0.27069091796875 +41398 0.294036865234375 +41399 0.311767578125 +41400 0.339141845703125 +41401 0.360260009765625 +41402 0.360504150390625 +41403 0.308380126953125 +41404 0.18170166015625 +41405 0.0047607421875 +41406 -0.17559814453125 +41407 -0.3143310546875 +41408 -0.36785888671875 +41409 -0.36248779296875 +41410 -0.343536376953125 +41411 -0.3018798828125 +41412 -0.231414794921875 +41413 -0.117645263671875 +41414 0.007049560546875 +41415 0.087982177734375 +41416 0.13946533203125 +41417 0.17425537109375 +41418 0.188201904296875 +41419 0.171234130859375 +41420 0.118438720703125 +41421 0.05706787109375 +41422 -0.010711669921875 +41423 -0.0914306640625 +41424 -0.162322998046875 +41425 -0.194549560546875 +41426 -0.1492919921875 +41427 -0.02166748046875 +41428 0.124053955078125 +41429 0.211151123046875 +41430 0.240447998046875 +41431 0.242218017578125 +41432 0.2257080078125 +41433 0.194366455078125 +41434 0.115509033203125 +41435 0.0128173828125 +41436 -0.053802490234375 +41437 -0.110626220703125 +41438 -0.199493408203125 +41439 -0.29437255859375 +41440 -0.33221435546875 +41441 -0.27972412109375 +41442 -0.185333251953125 +41443 -0.128204345703125 +41444 -0.115692138671875 +41445 -0.116455078125 +41446 -0.105926513671875 +41447 -0.053955078125 +41448 0.048797607421875 +41449 0.157318115234375 +41450 0.212005615234375 +41451 0.218475341796875 +41452 0.23724365234375 +41453 0.30535888671875 +41454 0.38128662109375 +41455 0.404449462890625 +41456 0.3944091796875 +41457 0.3885498046875 +41458 0.362640380859375 +41459 0.27362060546875 +41460 0.11712646484375 +41461 -0.054901123046875 +41462 -0.19085693359375 +41463 -0.28570556640625 +41464 -0.339263916015625 +41465 -0.3775634765625 +41466 -0.445709228515625 +41467 -0.535064697265625 +41468 -0.629058837890625 +41469 -0.697601318359375 +41470 -0.70391845703125 +41471 -0.6424560546875 +41472 -0.491241455078125 +41473 -0.265716552734375 +41474 -0.023712158203125 +41475 0.201751708984375 +41476 0.375823974609375 +41477 0.485076904296875 +41478 0.56884765625 +41479 0.634765625 +41480 0.63763427734375 +41481 0.5660400390625 +41482 0.4720458984375 +41483 0.40692138671875 +41484 0.3778076171875 +41485 0.376953125 +41486 0.371978759765625 +41487 0.313140869140625 +41488 0.184417724609375 +41489 0.011199951171875 +41490 -0.171051025390625 +41491 -0.33740234375 +41492 -0.47198486328125 +41493 -0.560394287109375 +41494 -0.58056640625 +41495 -0.54754638671875 +41496 -0.508575439453125 +41497 -0.459503173828125 +41498 -0.394378662109375 +41499 -0.35260009765625 +41500 -0.31170654296875 +41501 -0.197418212890625 +41502 -0.007965087890625 +41503 0.207489013671875 +41504 0.409210205078125 +41505 0.57208251953125 +41506 0.66595458984375 +41507 0.65875244140625 +41508 0.56744384765625 +41509 0.431396484375 +41510 0.29443359375 +41511 0.182464599609375 +41512 0.06365966796875 +41513 -0.075958251953125 +41514 -0.189422607421875 +41515 -0.271942138671875 +41516 -0.342529296875 +41517 -0.364166259765625 +41518 -0.327239990234375 +41519 -0.2769775390625 +41520 -0.253692626953125 +41521 -0.24365234375 +41522 -0.1983642578125 +41523 -0.116241455078125 +41524 -0.036834716796875 +41525 0.034881591796875 +41526 0.09124755859375 +41527 0.10888671875 +41528 0.125518798828125 +41529 0.15771484375 +41530 0.17828369140625 +41531 0.17108154296875 +41532 0.129974365234375 +41533 0.082427978515625 +41534 0.027679443359375 +41535 -0.065643310546875 +41536 -0.15936279296875 +41537 -0.21307373046875 +41538 -0.234649658203125 +41539 -0.2001953125 +41540 -0.119171142578125 +41541 -0.024749755859375 +41542 0.085784912109375 +41543 0.178131103515625 +41544 0.215576171875 +41545 0.211456298828125 +41546 0.17523193359375 +41547 0.128753662109375 +41548 0.1019287109375 +41549 0.0743408203125 +41550 0.04327392578125 +41551 0.038177490234375 +41552 0.076263427734375 +41553 0.14105224609375 +41554 0.186431884765625 +41555 0.188812255859375 +41556 0.1390380859375 +41557 0.041778564453125 +41558 -0.079437255859375 +41559 -0.219390869140625 +41560 -0.367828369140625 +41561 -0.494873046875 +41562 -0.556243896484375 +41563 -0.508697509765625 +41564 -0.3756103515625 +41565 -0.218902587890625 +41566 -0.063751220703125 +41567 0.091552734375 +41568 0.23602294921875 +41569 0.342987060546875 +41570 0.39520263671875 +41571 0.389373779296875 +41572 0.324249267578125 +41573 0.224090576171875 +41574 0.124267578125 +41575 0.037078857421875 +41576 -0.010101318359375 +41577 -0.019439697265625 +41578 -0.022796630859375 +41579 -0.001556396484375 +41580 0.056304931640625 +41581 0.106719970703125 +41582 0.096893310546875 +41583 0.042694091796875 +41584 -0.018035888671875 +41585 -0.07586669921875 +41586 -0.11944580078125 +41587 -0.15972900390625 +41588 -0.202606201171875 +41589 -0.24859619140625 +41590 -0.30517578125 +41591 -0.36212158203125 +41592 -0.39141845703125 +41593 -0.35528564453125 +41594 -0.249969482421875 +41595 -0.092864990234375 +41596 0.08905029296875 +41597 0.2352294921875 +41598 0.318817138671875 +41599 0.358642578125 +41600 0.347747802734375 +41601 0.28564453125 +41602 0.223175048828125 +41603 0.196746826171875 +41604 0.179840087890625 +41605 0.155548095703125 +41606 0.151214599609375 +41607 0.156951904296875 +41608 0.13177490234375 +41609 0.100799560546875 +41610 0.087127685546875 +41611 0.05487060546875 +41612 -0.009002685546875 +41613 -0.10400390625 +41614 -0.229400634765625 +41615 -0.35552978515625 +41616 -0.441925048828125 +41617 -0.473846435546875 +41618 -0.464813232421875 +41619 -0.419097900390625 +41620 -0.334320068359375 +41621 -0.227935791015625 +41622 -0.12347412109375 +41623 -0.02764892578125 +41624 0.077667236328125 +41625 0.2132568359375 +41626 0.38885498046875 +41627 0.582794189453125 +41628 0.734039306640625 +41629 0.800140380859375 +41630 0.7783203125 +41631 0.6651611328125 +41632 0.45965576171875 +41633 0.199188232421875 +41634 -0.050689697265625 +41635 -0.23297119140625 +41636 -0.33013916015625 +41637 -0.368408203125 +41638 -0.378936767578125 +41639 -0.376983642578125 +41640 -0.37969970703125 +41641 -0.391510009765625 +41642 -0.385345458984375 +41643 -0.3419189453125 +41644 -0.28289794921875 +41645 -0.251617431640625 +41646 -0.266143798828125 +41647 -0.273345947265625 +41648 -0.216796875 +41649 -0.128265380859375 +41650 -0.068145751953125 +41651 -0.0430908203125 +41652 -0.024444580078125 +41653 0.020721435546875 +41654 0.124481201171875 +41655 0.25787353515625 +41656 0.379119873046875 +41657 0.47991943359375 +41658 0.5281982421875 +41659 0.511138916015625 +41660 0.456207275390625 +41661 0.407470703125 +41662 0.383758544921875 +41663 0.35687255859375 +41664 0.31182861328125 +41665 0.250885009765625 +41666 0.1654052734375 +41667 0.035247802734375 +41668 -0.142059326171875 +41669 -0.33563232421875 +41670 -0.5345458984375 +41671 -0.72186279296875 +41672 -0.836669921875 +41673 -0.8326416015625 +41674 -0.7296142578125 +41675 -0.582550048828125 +41676 -0.440093994140625 +41677 -0.324310302734375 +41678 -0.20147705078125 +41679 -0.044647216796875 +41680 0.103973388671875 +41681 0.202392578125 +41682 0.264495849609375 +41683 0.338897705078125 +41684 0.443817138671875 +41685 0.545074462890625 +41686 0.6173095703125 +41687 0.6524658203125 +41688 0.66339111328125 +41689 0.6561279296875 +41690 0.606781005859375 +41691 0.501190185546875 +41692 0.352783203125 +41693 0.176544189453125 +41694 -0.034820556640625 +41695 -0.258209228515625 +41696 -0.44244384765625 +41697 -0.5753173828125 +41698 -0.65203857421875 +41699 -0.641632080078125 +41700 -0.562164306640625 +41701 -0.458038330078125 +41702 -0.350555419921875 +41703 -0.260528564453125 +41704 -0.192108154296875 +41705 -0.141937255859375 +41706 -0.1021728515625 +41707 -0.062896728515625 +41708 -0.011932373046875 +41709 0.062835693359375 +41710 0.148712158203125 +41711 0.241729736328125 +41712 0.34912109375 +41713 0.457305908203125 +41714 0.54388427734375 +41715 0.5728759765625 +41716 0.506591796875 +41717 0.351226806640625 +41718 0.146514892578125 +41719 -0.05523681640625 +41720 -0.21624755859375 +41721 -0.334930419921875 +41722 -0.402984619140625 +41723 -0.4412841796875 +41724 -0.49578857421875 +41725 -0.5601806640625 +41726 -0.600738525390625 +41727 -0.584228515625 +41728 -0.47930908203125 +41729 -0.27935791015625 +41730 -0.0089111328125 +41731 0.268798828125 +41732 0.482818603515625 +41733 0.60369873046875 +41734 0.650421142578125 +41735 0.66400146484375 +41736 0.6414794921875 +41737 0.572540283203125 +41738 0.498138427734375 +41739 0.439453125 +41740 0.375518798828125 +41741 0.274505615234375 +41742 0.1087646484375 +41743 -0.099395751953125 +41744 -0.3182373046875 +41745 -0.5489501953125 +41746 -0.7738037109375 +41747 -0.86383056640625 +41748 -0.870391845703125 +41749 -0.86895751953125 +41750 -0.861053466796875 +41751 -0.765869140625 +41752 -0.5301513671875 +41753 -0.214691162109375 +41754 0.137359619140625 +41755 0.474822998046875 +41756 0.76239013671875 +41757 0.867462158203125 +41758 0.870361328125 +41759 0.86480712890625 +41760 0.831817626953125 +41761 0.677581787109375 +41762 0.495880126953125 +41763 0.30767822265625 +41764 0.116180419921875 +41765 -0.110748291015625 +41766 -0.381805419921875 +41767 -0.6572265625 +41768 -0.857421875 +41769 -0.870391845703125 +41770 -0.870391845703125 +41771 -0.86444091796875 +41772 -0.85723876953125 +41773 -0.790008544921875 +41774 -0.62847900390625 +41775 -0.3956298828125 +41776 -0.126708984375 +41777 0.150115966796875 +41778 0.424041748046875 +41779 0.670623779296875 +41780 0.854522705078125 +41781 0.866485595703125 +41782 0.86920166015625 +41783 0.8653564453125 +41784 0.857147216796875 +41785 0.766845703125 +41786 0.628509521484375 +41787 0.462127685546875 +41788 0.297210693359375 +41789 0.14862060546875 +41790 -0.00537109375 +41791 -0.15753173828125 +41792 -0.31304931640625 +41793 -0.48876953125 +41794 -0.6416015625 +41795 -0.751373291015625 +41796 -0.84619140625 +41797 -0.861297607421875 +41798 -0.863250732421875 +41799 -0.856597900390625 +41800 -0.7498779296875 +41801 -0.624542236328125 +41802 -0.47808837890625 +41803 -0.253387451171875 +41804 0.003692626953125 +41805 0.2257080078125 +41806 0.427154541015625 +41807 0.643218994140625 +41808 0.855926513671875 +41809 0.870361328125 +41810 0.870361328125 +41811 0.862762451171875 +41812 0.79669189453125 +41813 0.595794677734375 +41814 0.362152099609375 +41815 0.1270751953125 +41816 -0.086944580078125 +41817 -0.2784423828125 +41818 -0.484832763671875 +41819 -0.729583740234375 +41820 -0.86688232421875 +41821 -0.870391845703125 +41822 -0.86859130859375 +41823 -0.86279296875 +41824 -0.817962646484375 +41825 -0.6116943359375 +41826 -0.3128662109375 +41827 0.039398193359375 +41828 0.422821044921875 +41829 0.805145263671875 +41830 0.870361328125 +41831 0.870361328125 +41832 0.860015869140625 +41833 0.727935791015625 +41834 0.48114013671875 +41835 0.2059326171875 +41836 -0.06103515625 +41837 -0.29913330078125 +41838 -0.516204833984375 +41839 -0.7252197265625 +41840 -0.85980224609375 +41841 -0.870391845703125 +41842 -0.870391845703125 +41843 -0.858062744140625 +41844 -0.673004150390625 +41845 -0.42694091796875 +41846 -0.2100830078125 +41847 -0.0362548828125 +41848 0.10943603515625 +41849 0.23516845703125 +41850 0.373687744140625 +41851 0.517791748046875 +41852 0.602783203125 +41853 0.635711669921875 +41854 0.655181884765625 +41855 0.65948486328125 +41856 0.651275634765625 +41857 0.61846923828125 +41858 0.53753662109375 +41859 0.404144287109375 +41860 0.22186279296875 +41861 0.003997802734375 +41862 -0.22100830078125 +41863 -0.42449951171875 +41864 -0.579833984375 +41865 -0.641876220703125 +41866 -0.6177978515625 +41867 -0.575531005859375 +41868 -0.526336669921875 +41869 -0.42645263671875 +41870 -0.2581787109375 +41871 -0.068695068359375 +41872 0.09222412109375 +41873 0.232147216796875 +41874 0.3509521484375 +41875 0.410064697265625 +41876 0.372955322265625 +41877 0.2554931640625 +41878 0.10711669921875 +41879 -0.052886962890625 +41880 -0.186279296875 +41881 -0.23291015625 +41882 -0.209442138671875 +41883 -0.174163818359375 +41884 -0.126739501953125 +41885 -0.048126220703125 +41886 0.0426025390625 +41887 0.10748291015625 +41888 0.1409912109375 +41889 0.19708251953125 +41890 0.273651123046875 +41891 0.31768798828125 +41892 0.341094970703125 +41893 0.368011474609375 +41894 0.37249755859375 +41895 0.30072021484375 +41896 0.1517333984375 +41897 -0.01470947265625 +41898 -0.1883544921875 +41899 -0.372711181640625 +41900 -0.51397705078125 +41901 -0.57177734375 +41902 -0.53948974609375 +41903 -0.43511962890625 +41904 -0.2962646484375 +41905 -0.161102294921875 +41906 -0.0435791015625 +41907 0.060394287109375 +41908 0.13665771484375 +41909 0.170135498046875 +41910 0.16552734375 +41911 0.15728759765625 +41912 0.150787353515625 +41913 0.12200927734375 +41914 0.080108642578125 +41915 0.05126953125 +41916 0.062896728515625 +41917 0.09271240234375 +41918 0.092987060546875 +41919 0.07855224609375 +41920 0.06427001953125 +41921 0.0347900390625 +41922 -0.01171875 +41923 -0.056060791015625 +41924 -0.055511474609375 +41925 -0.010467529296875 +41926 0.02508544921875 +41927 0.025665283203125 +41928 0.017333984375 +41929 0.00189208984375 +41930 -0.03173828125 +41931 -0.071502685546875 +41932 -0.13543701171875 +41933 -0.219970703125 +41934 -0.300506591796875 +41935 -0.376312255859375 +41936 -0.416107177734375 +41937 -0.371124267578125 +41938 -0.242279052734375 +41939 -0.069732666015625 +41940 0.125640869140625 +41941 0.31268310546875 +41942 0.45501708984375 +41943 0.554779052734375 +41944 0.61065673828125 +41945 0.610931396484375 +41946 0.531463623046875 +41947 0.3883056640625 +41948 0.23468017578125 +41949 0.095245361328125 +41950 -0.00396728515625 +41951 -0.04852294921875 +41952 -0.055145263671875 +41953 -0.0758056640625 +41954 -0.138702392578125 +41955 -0.209197998046875 +41956 -0.289031982421875 +41957 -0.37884521484375 +41958 -0.456329345703125 +41959 -0.51641845703125 +41960 -0.519287109375 +41961 -0.458251953125 +41962 -0.384796142578125 +41963 -0.323699951171875 +41964 -0.269287109375 +41965 -0.1951904296875 +41966 -0.100006103515625 +41967 -0.01055908203125 +41968 0.1033935546875 +41969 0.24908447265625 +41970 0.373199462890625 +41971 0.45806884765625 +41972 0.511474609375 +41973 0.565399169921875 +41974 0.61138916015625 +41975 0.5897216796875 +41976 0.4906005859375 +41977 0.33148193359375 +41978 0.147796630859375 +41979 -0.01873779296875 +41980 -0.140289306640625 +41981 -0.191986083984375 +41982 -0.184295654296875 +41983 -0.161834716796875 +41984 -0.166595458984375 +41985 -0.19390869140625 +41986 -0.22442626953125 +41987 -0.279754638671875 +41988 -0.3389892578125 +41989 -0.3543701171875 +41990 -0.348175048828125 +41991 -0.32598876953125 +41992 -0.2581787109375 +41993 -0.139801025390625 +41994 0.014617919921875 +41995 0.144378662109375 +41996 0.221038818359375 +41997 0.27069091796875 +41998 0.294036865234375 +41999 0.311767578125 +42000 0.339141845703125 +42001 0.360260009765625 +42002 0.360504150390625 +42003 0.308380126953125 +42004 0.18170166015625 +42005 0.0047607421875 +42006 -0.17559814453125 +42007 -0.3143310546875 +42008 -0.36785888671875 +42009 -0.36248779296875 +42010 -0.343536376953125 +42011 -0.3018798828125 +42012 -0.231414794921875 +42013 -0.117645263671875 +42014 0.007049560546875 +42015 0.087982177734375 +42016 0.13946533203125 +42017 0.17425537109375 +42018 0.188201904296875 +42019 0.171234130859375 +42020 0.118438720703125 +42021 0.05706787109375 +42022 -0.010711669921875 +42023 -0.0914306640625 +42024 -0.162322998046875 +42025 -0.194549560546875 +42026 -0.1492919921875 +42027 -0.02166748046875 +42028 0.124053955078125 +42029 0.211151123046875 +42030 0.240447998046875 +42031 0.242218017578125 +42032 0.2257080078125 +42033 0.194366455078125 +42034 0.115509033203125 +42035 0.0128173828125 +42036 -0.053802490234375 +42037 -0.110626220703125 +42038 -0.199493408203125 +42039 -0.29437255859375 +42040 -0.33221435546875 +42041 -0.27972412109375 +42042 -0.185333251953125 +42043 -0.128204345703125 +42044 -0.115692138671875 +42045 -0.116455078125 +42046 -0.105926513671875 +42047 -0.053955078125 +42048 0.048797607421875 +42049 0.157318115234375 +42050 0.212005615234375 +42051 0.218475341796875 +42052 0.23724365234375 +42053 0.30535888671875 +42054 0.38128662109375 +42055 0.404449462890625 +42056 0.3944091796875 +42057 0.3885498046875 +42058 0.362640380859375 +42059 0.27362060546875 +42060 0.11712646484375 +42061 -0.054901123046875 +42062 -0.19085693359375 +42063 -0.28570556640625 +42064 -0.339263916015625 +42065 -0.3775634765625 +42066 -0.445709228515625 +42067 -0.535064697265625 +42068 -0.629058837890625 +42069 -0.697601318359375 +42070 -0.70391845703125 +42071 -0.6424560546875 +42072 -0.491241455078125 +42073 -0.265716552734375 +42074 -0.023712158203125 +42075 0.201751708984375 +42076 0.375823974609375 +42077 0.485076904296875 +42078 0.56884765625 +42079 0.634765625 +42080 0.63763427734375 +42081 0.5660400390625 +42082 0.4720458984375 +42083 0.40692138671875 +42084 0.3778076171875 +42085 0.376953125 +42086 0.371978759765625 +42087 0.313140869140625 +42088 0.184417724609375 +42089 0.011199951171875 +42090 -0.171051025390625 +42091 -0.33740234375 +42092 -0.47198486328125 +42093 -0.560394287109375 +42094 -0.58056640625 +42095 -0.54754638671875 +42096 -0.508575439453125 +42097 -0.459503173828125 +42098 -0.394378662109375 +42099 -0.35260009765625 +42100 -0.31170654296875 +42101 -0.197418212890625 +42102 -0.007965087890625 +42103 0.207489013671875 +42104 0.409210205078125 +42105 0.57208251953125 +42106 0.66595458984375 +42107 0.65875244140625 +42108 0.56744384765625 +42109 0.431396484375 +42110 0.29443359375 +42111 0.182464599609375 +42112 0.06365966796875 +42113 -0.075958251953125 +42114 -0.189422607421875 +42115 -0.271942138671875 +42116 -0.342529296875 +42117 -0.364166259765625 +42118 -0.327239990234375 +42119 -0.2769775390625 +42120 -0.253692626953125 +42121 -0.24365234375 +42122 -0.1983642578125 +42123 -0.116241455078125 +42124 -0.036834716796875 +42125 0.034881591796875 +42126 0.09124755859375 +42127 0.10888671875 +42128 0.125518798828125 +42129 0.15771484375 +42130 0.17828369140625 +42131 0.17108154296875 +42132 0.129974365234375 +42133 0.082427978515625 +42134 0.027679443359375 +42135 -0.065643310546875 +42136 -0.15936279296875 +42137 -0.21307373046875 +42138 -0.234649658203125 +42139 -0.2001953125 +42140 -0.119171142578125 +42141 -0.024749755859375 +42142 0.085784912109375 +42143 0.178131103515625 +42144 0.215576171875 +42145 0.211456298828125 +42146 0.17523193359375 +42147 0.128753662109375 +42148 0.1019287109375 +42149 0.0743408203125 +42150 0.04327392578125 +42151 0.038177490234375 +42152 0.076263427734375 +42153 0.14105224609375 +42154 0.186431884765625 +42155 0.188812255859375 +42156 0.1390380859375 +42157 0.041778564453125 +42158 -0.079437255859375 +42159 -0.219390869140625 +42160 -0.367828369140625 +42161 -0.494873046875 +42162 -0.556243896484375 +42163 -0.508697509765625 +42164 -0.3756103515625 +42165 -0.218902587890625 +42166 -0.063751220703125 +42167 0.091552734375 +42168 0.23602294921875 +42169 0.342987060546875 +42170 0.39520263671875 +42171 0.389373779296875 +42172 0.324249267578125 +42173 0.224090576171875 +42174 0.124267578125 +42175 0.037078857421875 +42176 -0.010101318359375 +42177 -0.019439697265625 +42178 -0.022796630859375 +42179 -0.001556396484375 +42180 0.056304931640625 +42181 0.106719970703125 +42182 0.096893310546875 +42183 0.042694091796875 +42184 -0.018035888671875 +42185 -0.07586669921875 +42186 -0.11944580078125 +42187 -0.15972900390625 +42188 -0.202606201171875 +42189 -0.24859619140625 +42190 -0.30517578125 +42191 -0.36212158203125 +42192 -0.39141845703125 +42193 -0.35528564453125 +42194 -0.249969482421875 +42195 -0.092864990234375 +42196 0.08905029296875 +42197 0.2352294921875 +42198 0.318817138671875 +42199 0.358642578125 +42200 0.347747802734375 +42201 0.28564453125 +42202 0.223175048828125 +42203 0.196746826171875 +42204 0.179840087890625 +42205 0.155548095703125 +42206 0.151214599609375 +42207 0.156951904296875 +42208 0.13177490234375 +42209 0.100799560546875 +42210 0.087127685546875 +42211 0.05487060546875 +42212 -0.009002685546875 +42213 -0.10400390625 +42214 -0.229400634765625 +42215 -0.35552978515625 +42216 -0.441925048828125 +42217 -0.473846435546875 +42218 -0.464813232421875 +42219 -0.419097900390625 +42220 -0.334320068359375 +42221 -0.227935791015625 +42222 -0.12347412109375 +42223 -0.02764892578125 +42224 0.077667236328125 +42225 0.2132568359375 +42226 0.38885498046875 +42227 0.582794189453125 +42228 0.734039306640625 +42229 0.800140380859375 +42230 0.7783203125 +42231 0.6651611328125 +42232 0.45965576171875 +42233 0.199188232421875 +42234 -0.050689697265625 +42235 -0.23297119140625 +42236 -0.33013916015625 +42237 -0.368408203125 +42238 -0.378936767578125 +42239 -0.376983642578125 +42240 -0.37969970703125 +42241 -0.391510009765625 +42242 -0.385345458984375 +42243 -0.3419189453125 +42244 -0.28289794921875 +42245 -0.251617431640625 +42246 -0.266143798828125 +42247 -0.273345947265625 +42248 -0.216796875 +42249 -0.128265380859375 +42250 -0.068145751953125 +42251 -0.0430908203125 +42252 -0.024444580078125 +42253 0.020721435546875 +42254 0.124481201171875 +42255 0.25787353515625 +42256 0.379119873046875 +42257 0.47991943359375 +42258 0.5281982421875 +42259 0.511138916015625 +42260 0.456207275390625 +42261 0.407470703125 +42262 0.383758544921875 +42263 0.35687255859375 +42264 0.31182861328125 +42265 0.250885009765625 +42266 0.1654052734375 +42267 0.035247802734375 +42268 -0.142059326171875 +42269 -0.33563232421875 +42270 -0.5345458984375 +42271 -0.72186279296875 +42272 -0.836669921875 +42273 -0.8326416015625 +42274 -0.7296142578125 +42275 -0.582550048828125 +42276 -0.440093994140625 +42277 -0.324310302734375 +42278 -0.20147705078125 +42279 -0.044647216796875 +42280 0.103973388671875 +42281 0.202392578125 +42282 0.264495849609375 +42283 0.338897705078125 +42284 0.443817138671875 +42285 0.545074462890625 +42286 0.6173095703125 +42287 0.6524658203125 +42288 0.66339111328125 +42289 0.6561279296875 +42290 0.606781005859375 +42291 0.501190185546875 +42292 0.352783203125 +42293 0.176544189453125 +42294 -0.034820556640625 +42295 -0.258209228515625 +42296 -0.44244384765625 +42297 -0.5753173828125 +42298 -0.65203857421875 +42299 -0.641632080078125 +42300 -0.562164306640625 +42301 -0.458038330078125 +42302 -0.350555419921875 +42303 -0.260528564453125 +42304 -0.192108154296875 +42305 -0.141937255859375 +42306 -0.1021728515625 +42307 -0.062896728515625 +42308 -0.011932373046875 +42309 0.062835693359375 +42310 0.148712158203125 +42311 0.241729736328125 +42312 0.34912109375 +42313 0.457305908203125 +42314 0.54388427734375 +42315 0.5728759765625 +42316 0.506591796875 +42317 0.351226806640625 +42318 0.146514892578125 +42319 -0.05523681640625 +42320 -0.21624755859375 +42321 -0.334930419921875 +42322 -0.402984619140625 +42323 -0.4412841796875 +42324 -0.49578857421875 +42325 -0.5601806640625 +42326 -0.600738525390625 +42327 -0.584228515625 +42328 -0.47930908203125 +42329 -0.27935791015625 +42330 -0.0089111328125 +42331 0.268798828125 +42332 0.482818603515625 +42333 0.60369873046875 +42334 0.650421142578125 +42335 0.66400146484375 +42336 0.6414794921875 +42337 0.572540283203125 +42338 0.498138427734375 +42339 0.439453125 +42340 0.375518798828125 +42341 0.274505615234375 +42342 0.1087646484375 +42343 -0.099395751953125 +42344 -0.3182373046875 +42345 -0.5489501953125 +42346 -0.7738037109375 +42347 -0.86383056640625 +42348 -0.870391845703125 +42349 -0.86895751953125 +42350 -0.861053466796875 +42351 -0.765869140625 +42352 -0.5301513671875 +42353 -0.214691162109375 +42354 0.137359619140625 +42355 0.474822998046875 +42356 0.76239013671875 +42357 0.867462158203125 +42358 0.870361328125 +42359 0.86480712890625 +42360 0.831817626953125 +42361 0.677581787109375 +42362 0.495880126953125 +42363 0.30767822265625 +42364 0.116180419921875 +42365 -0.110748291015625 +42366 -0.381805419921875 +42367 -0.6572265625 +42368 -0.857421875 +42369 -0.870391845703125 +42370 -0.870391845703125 +42371 -0.86444091796875 +42372 -0.85723876953125 +42373 -0.790008544921875 +42374 -0.62847900390625 +42375 -0.3956298828125 +42376 -0.126708984375 +42377 0.150115966796875 +42378 0.424041748046875 +42379 0.670623779296875 +42380 0.854522705078125 +42381 0.866485595703125 +42382 0.86920166015625 +42383 0.8653564453125 +42384 0.857147216796875 +42385 0.766845703125 +42386 0.628509521484375 +42387 0.462127685546875 +42388 0.297210693359375 +42389 0.14862060546875 +42390 -0.00537109375 +42391 -0.15753173828125 +42392 -0.31304931640625 +42393 -0.48876953125 +42394 -0.6416015625 +42395 -0.751373291015625 +42396 -0.84619140625 +42397 -0.861297607421875 +42398 -0.863250732421875 +42399 -0.856597900390625 +42400 -0.7498779296875 +42401 -0.624542236328125 +42402 -0.47808837890625 +42403 -0.253387451171875 +42404 0.003692626953125 +42405 0.2257080078125 +42406 0.427154541015625 +42407 0.643218994140625 +42408 0.855926513671875 +42409 0.870361328125 +42410 0.870361328125 +42411 0.862762451171875 +42412 0.79669189453125 +42413 0.595794677734375 +42414 0.362152099609375 +42415 0.1270751953125 +42416 -0.086944580078125 +42417 -0.2784423828125 +42418 -0.484832763671875 +42419 -0.729583740234375 +42420 -0.86688232421875 +42421 -0.870391845703125 +42422 -0.86859130859375 +42423 -0.86279296875 +42424 -0.817962646484375 +42425 -0.6116943359375 +42426 -0.3128662109375 +42427 0.039398193359375 +42428 0.422821044921875 +42429 0.805145263671875 +42430 0.870361328125 +42431 0.870361328125 +42432 0.860015869140625 +42433 0.727935791015625 +42434 0.48114013671875 +42435 0.2059326171875 +42436 -0.06103515625 +42437 -0.29913330078125 +42438 -0.516204833984375 +42439 -0.7252197265625 +42440 -0.85980224609375 +42441 -0.870391845703125 +42442 -0.870391845703125 +42443 -0.858062744140625 +42444 -0.673004150390625 +42445 -0.42694091796875 +42446 -0.2100830078125 +42447 -0.0362548828125 +42448 0.10943603515625 +42449 0.23516845703125 +42450 0.373687744140625 +42451 0.517791748046875 +42452 0.602783203125 +42453 0.635711669921875 +42454 0.655181884765625 +42455 0.65948486328125 +42456 0.651275634765625 +42457 0.61846923828125 +42458 0.53753662109375 +42459 0.404144287109375 +42460 0.22186279296875 +42461 0.003997802734375 +42462 -0.22100830078125 +42463 -0.42449951171875 +42464 -0.579833984375 +42465 -0.641876220703125 +42466 -0.6177978515625 +42467 -0.575531005859375 +42468 -0.526336669921875 +42469 -0.42645263671875 +42470 -0.2581787109375 +42471 -0.068695068359375 +42472 0.09222412109375 +42473 0.232147216796875 +42474 0.3509521484375 +42475 0.410064697265625 +42476 0.372955322265625 +42477 0.2554931640625 +42478 0.10711669921875 +42479 -0.052886962890625 +42480 -0.186279296875 +42481 -0.23291015625 +42482 -0.209442138671875 +42483 -0.174163818359375 +42484 -0.126739501953125 +42485 -0.048126220703125 +42486 0.0426025390625 +42487 0.10748291015625 +42488 0.1409912109375 +42489 0.19708251953125 +42490 0.273651123046875 +42491 0.31768798828125 +42492 0.341094970703125 +42493 0.368011474609375 +42494 0.37249755859375 +42495 0.30072021484375 +42496 0.1517333984375 +42497 -0.01470947265625 +42498 -0.1883544921875 +42499 -0.372711181640625 +42500 -0.51397705078125 +42501 -0.57177734375 +42502 -0.53948974609375 +42503 -0.43511962890625 +42504 -0.2962646484375 +42505 -0.161102294921875 +42506 -0.0435791015625 +42507 0.060394287109375 +42508 0.13665771484375 +42509 0.170135498046875 +42510 0.16552734375 +42511 0.15728759765625 +42512 0.150787353515625 +42513 0.12200927734375 +42514 0.080108642578125 +42515 0.05126953125 +42516 0.062896728515625 +42517 0.09271240234375 +42518 0.092987060546875 +42519 0.07855224609375 +42520 0.06427001953125 +42521 0.0347900390625 +42522 -0.01171875 +42523 -0.056060791015625 +42524 -0.055511474609375 +42525 -0.010467529296875 +42526 0.02508544921875 +42527 0.025665283203125 +42528 0.017333984375 +42529 0.00189208984375 +42530 -0.03173828125 +42531 -0.071502685546875 +42532 -0.13543701171875 +42533 -0.219970703125 +42534 -0.300506591796875 +42535 -0.376312255859375 +42536 -0.416107177734375 +42537 -0.371124267578125 +42538 -0.242279052734375 +42539 -0.069732666015625 +42540 0.125640869140625 +42541 0.31268310546875 +42542 0.45501708984375 +42543 0.554779052734375 +42544 0.61065673828125 +42545 0.610931396484375 +42546 0.531463623046875 +42547 0.3883056640625 +42548 0.23468017578125 +42549 0.095245361328125 +42550 -0.00396728515625 +42551 -0.04852294921875 +42552 -0.055145263671875 +42553 -0.0758056640625 +42554 -0.138702392578125 +42555 -0.209197998046875 +42556 -0.289031982421875 +42557 -0.37884521484375 +42558 -0.456329345703125 +42559 -0.51641845703125 +42560 -0.519287109375 +42561 -0.458251953125 +42562 -0.384796142578125 +42563 -0.323699951171875 +42564 -0.269287109375 +42565 -0.1951904296875 +42566 -0.100006103515625 +42567 -0.01055908203125 +42568 0.1033935546875 +42569 0.24908447265625 +42570 0.373199462890625 +42571 0.45806884765625 +42572 0.511474609375 +42573 0.565399169921875 +42574 0.61138916015625 +42575 0.5897216796875 +42576 0.4906005859375 +42577 0.33148193359375 +42578 0.147796630859375 +42579 -0.01873779296875 +42580 -0.140289306640625 +42581 -0.191986083984375 +42582 -0.184295654296875 +42583 -0.161834716796875 +42584 -0.166595458984375 +42585 -0.19390869140625 +42586 -0.22442626953125 +42587 -0.279754638671875 +42588 -0.3389892578125 +42589 -0.3543701171875 +42590 -0.348175048828125 +42591 -0.32598876953125 +42592 -0.2581787109375 +42593 -0.139801025390625 +42594 0.014617919921875 +42595 0.144378662109375 +42596 0.221038818359375 +42597 0.27069091796875 +42598 0.294036865234375 +42599 0.311767578125 +42600 0.339141845703125 +42601 0.360260009765625 +42602 0.360504150390625 +42603 0.308380126953125 +42604 0.18170166015625 +42605 0.0047607421875 +42606 -0.17559814453125 +42607 -0.3143310546875 +42608 -0.36785888671875 +42609 -0.36248779296875 +42610 -0.343536376953125 +42611 -0.3018798828125 +42612 -0.231414794921875 +42613 -0.117645263671875 +42614 0.007049560546875 +42615 0.087982177734375 +42616 0.13946533203125 +42617 0.17425537109375 +42618 0.188201904296875 +42619 0.171234130859375 +42620 0.118438720703125 +42621 0.05706787109375 +42622 -0.010711669921875 +42623 -0.0914306640625 +42624 -0.162322998046875 +42625 -0.194549560546875 +42626 -0.1492919921875 +42627 -0.02166748046875 +42628 0.124053955078125 +42629 0.211151123046875 +42630 0.240447998046875 +42631 0.242218017578125 +42632 0.2257080078125 +42633 0.194366455078125 +42634 0.115509033203125 +42635 0.0128173828125 +42636 -0.053802490234375 +42637 -0.110626220703125 +42638 -0.199493408203125 +42639 -0.29437255859375 +42640 -0.33221435546875 +42641 -0.27972412109375 +42642 -0.185333251953125 +42643 -0.128204345703125 +42644 -0.115692138671875 +42645 -0.116455078125 +42646 -0.105926513671875 +42647 -0.053955078125 +42648 0.048797607421875 +42649 0.157318115234375 +42650 0.212005615234375 +42651 0.218475341796875 +42652 0.23724365234375 +42653 0.30535888671875 +42654 0.38128662109375 +42655 0.404449462890625 +42656 0.3944091796875 +42657 0.3885498046875 +42658 0.362640380859375 +42659 0.27362060546875 +42660 0.11712646484375 +42661 -0.054901123046875 +42662 -0.19085693359375 +42663 -0.28570556640625 +42664 -0.339263916015625 +42665 -0.3775634765625 +42666 -0.445709228515625 +42667 -0.535064697265625 +42668 -0.629058837890625 +42669 -0.697601318359375 +42670 -0.70391845703125 +42671 -0.6424560546875 +42672 -0.491241455078125 +42673 -0.265716552734375 +42674 -0.023712158203125 +42675 0.201751708984375 +42676 0.375823974609375 +42677 0.485076904296875 +42678 0.56884765625 +42679 0.634765625 +42680 0.63763427734375 +42681 0.5660400390625 +42682 0.4720458984375 +42683 0.40692138671875 +42684 0.3778076171875 +42685 0.376953125 +42686 0.371978759765625 +42687 0.313140869140625 +42688 0.184417724609375 +42689 0.011199951171875 +42690 -0.171051025390625 +42691 -0.33740234375 +42692 -0.47198486328125 +42693 -0.560394287109375 +42694 -0.58056640625 +42695 -0.54754638671875 +42696 -0.508575439453125 +42697 -0.459503173828125 +42698 -0.394378662109375 +42699 -0.35260009765625 +42700 -0.31170654296875 +42701 -0.197418212890625 +42702 -0.007965087890625 +42703 0.207489013671875 +42704 0.409210205078125 +42705 0.57208251953125 +42706 0.66595458984375 +42707 0.65875244140625 +42708 0.56744384765625 +42709 0.431396484375 +42710 0.29443359375 +42711 0.182464599609375 +42712 0.06365966796875 +42713 -0.075958251953125 +42714 -0.189422607421875 +42715 -0.271942138671875 +42716 -0.342529296875 +42717 -0.364166259765625 +42718 -0.327239990234375 +42719 -0.2769775390625 +42720 -0.253692626953125 +42721 -0.24365234375 +42722 -0.1983642578125 +42723 -0.116241455078125 +42724 -0.036834716796875 +42725 0.034881591796875 +42726 0.09124755859375 +42727 0.10888671875 +42728 0.125518798828125 +42729 0.15771484375 +42730 0.17828369140625 +42731 0.17108154296875 +42732 0.129974365234375 +42733 0.082427978515625 +42734 0.027679443359375 +42735 -0.065643310546875 +42736 -0.15936279296875 +42737 -0.21307373046875 +42738 -0.234649658203125 +42739 -0.2001953125 +42740 -0.119171142578125 +42741 -0.024749755859375 +42742 0.085784912109375 +42743 0.178131103515625 +42744 0.215576171875 +42745 0.211456298828125 +42746 0.17523193359375 +42747 0.128753662109375 +42748 0.1019287109375 +42749 0.0743408203125 +42750 0.04327392578125 +42751 0.038177490234375 +42752 0.076263427734375 +42753 0.14105224609375 +42754 0.186431884765625 +42755 0.188812255859375 +42756 0.1390380859375 +42757 0.041778564453125 +42758 -0.079437255859375 +42759 -0.219390869140625 +42760 -0.367828369140625 +42761 -0.494873046875 +42762 -0.556243896484375 +42763 -0.508697509765625 +42764 -0.3756103515625 +42765 -0.218902587890625 +42766 -0.063751220703125 +42767 0.091552734375 +42768 0.23602294921875 +42769 0.342987060546875 +42770 0.39520263671875 +42771 0.389373779296875 +42772 0.324249267578125 +42773 0.224090576171875 +42774 0.124267578125 +42775 0.037078857421875 +42776 -0.010101318359375 +42777 -0.019439697265625 +42778 -0.022796630859375 +42779 -0.001556396484375 +42780 0.056304931640625 +42781 0.106719970703125 +42782 0.096893310546875 +42783 0.042694091796875 +42784 -0.018035888671875 +42785 -0.07586669921875 +42786 -0.11944580078125 +42787 -0.15972900390625 +42788 -0.202606201171875 +42789 -0.24859619140625 +42790 -0.30517578125 +42791 -0.36212158203125 +42792 -0.39141845703125 +42793 -0.35528564453125 +42794 -0.249969482421875 +42795 -0.092864990234375 +42796 0.08905029296875 +42797 0.2352294921875 +42798 0.318817138671875 +42799 0.358642578125 +42800 0.347747802734375 +42801 0.28564453125 +42802 0.223175048828125 +42803 0.196746826171875 +42804 0.179840087890625 +42805 0.155548095703125 +42806 0.151214599609375 +42807 0.156951904296875 +42808 0.13177490234375 +42809 0.100799560546875 +42810 0.087127685546875 +42811 0.05487060546875 +42812 -0.009002685546875 +42813 -0.10400390625 +42814 -0.229400634765625 +42815 -0.35552978515625 +42816 -0.441925048828125 +42817 -0.473846435546875 +42818 -0.464813232421875 +42819 -0.419097900390625 +42820 -0.334320068359375 +42821 -0.227935791015625 +42822 -0.12347412109375 +42823 -0.02764892578125 +42824 0.077667236328125 +42825 0.2132568359375 +42826 0.38885498046875 +42827 0.582794189453125 +42828 0.734039306640625 +42829 0.800140380859375 +42830 0.7783203125 +42831 0.6651611328125 +42832 0.45965576171875 +42833 0.199188232421875 +42834 -0.050689697265625 +42835 -0.23297119140625 +42836 -0.33013916015625 +42837 -0.368408203125 +42838 -0.378936767578125 +42839 -0.376983642578125 +42840 -0.37969970703125 +42841 -0.391510009765625 +42842 -0.385345458984375 +42843 -0.3419189453125 +42844 -0.28289794921875 +42845 -0.251617431640625 +42846 -0.266143798828125 +42847 -0.273345947265625 +42848 -0.216796875 +42849 -0.128265380859375 +42850 -0.068145751953125 +42851 -0.0430908203125 +42852 -0.024444580078125 +42853 0.020721435546875 +42854 0.124481201171875 +42855 0.25787353515625 +42856 0.379119873046875 +42857 0.47991943359375 +42858 0.5281982421875 +42859 0.511138916015625 +42860 0.456207275390625 +42861 0.407470703125 +42862 0.383758544921875 +42863 0.35687255859375 +42864 0.31182861328125 +42865 0.250885009765625 +42866 0.1654052734375 +42867 0.035247802734375 +42868 -0.142059326171875 +42869 -0.33563232421875 +42870 -0.5345458984375 +42871 -0.72186279296875 +42872 -0.836669921875 +42873 -0.8326416015625 +42874 -0.7296142578125 +42875 -0.582550048828125 +42876 -0.440093994140625 +42877 -0.324310302734375 +42878 -0.20147705078125 +42879 -0.044647216796875 +42880 0.103973388671875 +42881 0.202392578125 +42882 0.264495849609375 +42883 0.338897705078125 +42884 0.443817138671875 +42885 0.545074462890625 +42886 0.6173095703125 +42887 0.6524658203125 +42888 0.66339111328125 +42889 0.6561279296875 +42890 0.606781005859375 +42891 0.501190185546875 +42892 0.352783203125 +42893 0.176544189453125 +42894 -0.034820556640625 +42895 -0.258209228515625 +42896 -0.44244384765625 +42897 -0.5753173828125 +42898 -0.65203857421875 +42899 -0.641632080078125 +42900 -0.562164306640625 +42901 -0.458038330078125 +42902 -0.350555419921875 +42903 -0.260528564453125 +42904 -0.192108154296875 +42905 -0.141937255859375 +42906 -0.1021728515625 +42907 -0.062896728515625 +42908 -0.011932373046875 +42909 0.062835693359375 +42910 0.148712158203125 +42911 0.241729736328125 +42912 0.34912109375 +42913 0.457305908203125 +42914 0.54388427734375 +42915 0.5728759765625 +42916 0.506591796875 +42917 0.351226806640625 +42918 0.146514892578125 +42919 -0.05523681640625 +42920 -0.21624755859375 +42921 -0.334930419921875 +42922 -0.402984619140625 +42923 -0.4412841796875 +42924 -0.49578857421875 +42925 -0.5601806640625 +42926 -0.600738525390625 +42927 -0.584228515625 +42928 -0.47930908203125 +42929 -0.27935791015625 +42930 -0.0089111328125 +42931 0.268798828125 +42932 0.482818603515625 +42933 0.60369873046875 +42934 0.650421142578125 +42935 0.66400146484375 +42936 0.6414794921875 +42937 0.572540283203125 +42938 0.498138427734375 +42939 0.439453125 +42940 0.375518798828125 +42941 0.274505615234375 +42942 0.1087646484375 +42943 -0.099395751953125 +42944 -0.3182373046875 +42945 -0.5489501953125 +42946 -0.7738037109375 +42947 -0.86383056640625 +42948 -0.870391845703125 +42949 -0.86895751953125 +42950 -0.861053466796875 +42951 -0.765869140625 +42952 -0.5301513671875 +42953 -0.214691162109375 +42954 0.137359619140625 +42955 0.474822998046875 +42956 0.76239013671875 +42957 0.867462158203125 +42958 0.870361328125 +42959 0.86480712890625 +42960 0.831817626953125 +42961 0.677581787109375 +42962 0.495880126953125 +42963 0.30767822265625 +42964 0.116180419921875 +42965 -0.110748291015625 +42966 -0.381805419921875 +42967 -0.6572265625 +42968 -0.857421875 +42969 -0.870391845703125 +42970 -0.870391845703125 +42971 -0.86444091796875 +42972 -0.85723876953125 +42973 -0.790008544921875 +42974 -0.62847900390625 +42975 -0.3956298828125 +42976 -0.126708984375 +42977 0.150115966796875 +42978 0.424041748046875 +42979 0.670623779296875 +42980 0.854522705078125 +42981 0.866485595703125 +42982 0.86920166015625 +42983 0.8653564453125 +42984 0.857147216796875 +42985 0.766845703125 +42986 0.628509521484375 +42987 0.462127685546875 +42988 0.297210693359375 +42989 0.14862060546875 +42990 -0.00537109375 +42991 -0.15753173828125 +42992 -0.31304931640625 +42993 -0.48876953125 +42994 -0.6416015625 +42995 -0.751373291015625 +42996 -0.84619140625 +42997 -0.861297607421875 +42998 -0.863250732421875 +42999 -0.856597900390625 +43000 -0.7498779296875 +43001 -0.624542236328125 +43002 -0.47808837890625 +43003 -0.253387451171875 +43004 0.003692626953125 +43005 0.2257080078125 +43006 0.427154541015625 +43007 0.643218994140625 +43008 0.855926513671875 +43009 0.870361328125 +43010 0.870361328125 +43011 0.862762451171875 +43012 0.79669189453125 +43013 0.595794677734375 +43014 0.362152099609375 +43015 0.1270751953125 +43016 -0.086944580078125 +43017 -0.2784423828125 +43018 -0.484832763671875 +43019 -0.729583740234375 +43020 -0.86688232421875 +43021 -0.870391845703125 +43022 -0.86859130859375 +43023 -0.86279296875 +43024 -0.817962646484375 +43025 -0.6116943359375 +43026 -0.3128662109375 +43027 0.039398193359375 +43028 0.422821044921875 +43029 0.805145263671875 +43030 0.870361328125 +43031 0.870361328125 +43032 0.860015869140625 +43033 0.727935791015625 +43034 0.48114013671875 +43035 0.2059326171875 +43036 -0.06103515625 +43037 -0.29913330078125 +43038 -0.516204833984375 +43039 -0.7252197265625 +43040 -0.85980224609375 +43041 -0.870391845703125 +43042 -0.870391845703125 +43043 -0.858062744140625 +43044 -0.673004150390625 +43045 -0.42694091796875 +43046 -0.2100830078125 +43047 -0.0362548828125 +43048 0.10943603515625 +43049 0.23516845703125 +43050 0.373687744140625 +43051 0.517791748046875 +43052 0.602783203125 +43053 0.635711669921875 +43054 0.655181884765625 +43055 0.65948486328125 +43056 0.651275634765625 +43057 0.61846923828125 +43058 0.53753662109375 +43059 0.404144287109375 +43060 0.22186279296875 +43061 0.003997802734375 +43062 -0.22100830078125 +43063 -0.42449951171875 +43064 -0.579833984375 +43065 -0.641876220703125 +43066 -0.6177978515625 +43067 -0.575531005859375 +43068 -0.526336669921875 +43069 -0.42645263671875 +43070 -0.2581787109375 +43071 -0.068695068359375 +43072 0.09222412109375 +43073 0.232147216796875 +43074 0.3509521484375 +43075 0.410064697265625 +43076 0.372955322265625 +43077 0.2554931640625 +43078 0.10711669921875 +43079 -0.052886962890625 +43080 -0.186279296875 +43081 -0.23291015625 +43082 -0.209442138671875 +43083 -0.174163818359375 +43084 -0.126739501953125 +43085 -0.048126220703125 +43086 0.0426025390625 +43087 0.10748291015625 +43088 0.1409912109375 +43089 0.19708251953125 +43090 0.273651123046875 +43091 0.31768798828125 +43092 0.341094970703125 +43093 0.368011474609375 +43094 0.37249755859375 +43095 0.30072021484375 +43096 0.1517333984375 +43097 -0.01470947265625 +43098 -0.1883544921875 +43099 -0.372711181640625 +43100 -0.51397705078125 +43101 -0.57177734375 +43102 -0.53948974609375 +43103 -0.43511962890625 +43104 -0.2962646484375 +43105 -0.161102294921875 +43106 -0.0435791015625 +43107 0.060394287109375 +43108 0.13665771484375 +43109 0.170135498046875 +43110 0.16552734375 +43111 0.15728759765625 +43112 0.150787353515625 +43113 0.12200927734375 +43114 0.080108642578125 +43115 0.05126953125 +43116 0.062896728515625 +43117 0.09271240234375 +43118 0.092987060546875 +43119 0.07855224609375 +43120 0.06427001953125 +43121 0.0347900390625 +43122 -0.01171875 +43123 -0.056060791015625 +43124 -0.055511474609375 +43125 -0.010467529296875 +43126 0.02508544921875 +43127 0.025665283203125 +43128 0.017333984375 +43129 0.00189208984375 +43130 -0.03173828125 +43131 -0.071502685546875 +43132 -0.13543701171875 +43133 -0.219970703125 +43134 -0.300506591796875 +43135 -0.376312255859375 +43136 -0.416107177734375 +43137 -0.371124267578125 +43138 -0.242279052734375 +43139 -0.069732666015625 +43140 0.125640869140625 +43141 0.31268310546875 +43142 0.45501708984375 +43143 0.554779052734375 +43144 0.61065673828125 +43145 0.610931396484375 +43146 0.531463623046875 +43147 0.3883056640625 +43148 0.23468017578125 +43149 0.095245361328125 +43150 -0.00396728515625 +43151 -0.04852294921875 +43152 -0.055145263671875 +43153 -0.0758056640625 +43154 -0.138702392578125 +43155 -0.209197998046875 +43156 -0.289031982421875 +43157 -0.37884521484375 +43158 -0.456329345703125 +43159 -0.51641845703125 +43160 -0.519287109375 +43161 -0.458251953125 +43162 -0.384796142578125 +43163 -0.323699951171875 +43164 -0.269287109375 +43165 -0.1951904296875 +43166 -0.100006103515625 +43167 -0.01055908203125 +43168 0.1033935546875 +43169 0.24908447265625 +43170 0.373199462890625 +43171 0.45806884765625 +43172 0.511474609375 +43173 0.565399169921875 +43174 0.61138916015625 +43175 0.5897216796875 +43176 0.4906005859375 +43177 0.33148193359375 +43178 0.147796630859375 +43179 -0.01873779296875 +43180 -0.140289306640625 +43181 -0.191986083984375 +43182 -0.184295654296875 +43183 -0.161834716796875 +43184 -0.166595458984375 +43185 -0.19390869140625 +43186 -0.22442626953125 +43187 -0.279754638671875 +43188 -0.3389892578125 +43189 -0.3543701171875 +43190 -0.348175048828125 +43191 -0.32598876953125 +43192 -0.2581787109375 +43193 -0.139801025390625 +43194 0.014617919921875 +43195 0.144378662109375 +43196 0.221038818359375 +43197 0.27069091796875 +43198 0.294036865234375 +43199 0.311767578125 +43200 0.339141845703125 +43201 0.360260009765625 +43202 0.360504150390625 +43203 0.308380126953125 +43204 0.18170166015625 +43205 0.0047607421875 +43206 -0.17559814453125 +43207 -0.3143310546875 +43208 -0.36785888671875 +43209 -0.36248779296875 +43210 -0.343536376953125 +43211 -0.3018798828125 +43212 -0.231414794921875 +43213 -0.117645263671875 +43214 0.007049560546875 +43215 0.087982177734375 +43216 0.13946533203125 +43217 0.17425537109375 +43218 0.188201904296875 +43219 0.171234130859375 +43220 0.118438720703125 +43221 0.05706787109375 +43222 -0.010711669921875 +43223 -0.0914306640625 +43224 -0.162322998046875 +43225 -0.194549560546875 +43226 -0.1492919921875 +43227 -0.02166748046875 +43228 0.124053955078125 +43229 0.211151123046875 +43230 0.240447998046875 +43231 0.242218017578125 +43232 0.2257080078125 +43233 0.194366455078125 +43234 0.115509033203125 +43235 0.0128173828125 +43236 -0.053802490234375 +43237 -0.110626220703125 +43238 -0.199493408203125 +43239 -0.29437255859375 +43240 -0.33221435546875 +43241 -0.27972412109375 +43242 -0.185333251953125 +43243 -0.128204345703125 +43244 -0.115692138671875 +43245 -0.116455078125 +43246 -0.105926513671875 +43247 -0.053955078125 +43248 0.048797607421875 +43249 0.157318115234375 +43250 0.212005615234375 +43251 0.218475341796875 +43252 0.23724365234375 +43253 0.30535888671875 +43254 0.38128662109375 +43255 0.404449462890625 +43256 0.3944091796875 +43257 0.3885498046875 +43258 0.362640380859375 +43259 0.27362060546875 +43260 0.11712646484375 +43261 -0.054901123046875 +43262 -0.19085693359375 +43263 -0.28570556640625 +43264 -0.339263916015625 +43265 -0.3775634765625 +43266 -0.445709228515625 +43267 -0.535064697265625 +43268 -0.629058837890625 +43269 -0.697601318359375 +43270 -0.70391845703125 +43271 -0.6424560546875 +43272 -0.491241455078125 +43273 -0.265716552734375 +43274 -0.023712158203125 +43275 0.201751708984375 +43276 0.375823974609375 +43277 0.485076904296875 +43278 0.56884765625 +43279 0.634765625 +43280 0.63763427734375 +43281 0.5660400390625 +43282 0.4720458984375 +43283 0.40692138671875 +43284 0.3778076171875 +43285 0.376953125 +43286 0.371978759765625 +43287 0.313140869140625 +43288 0.184417724609375 +43289 0.011199951171875 +43290 -0.171051025390625 +43291 -0.33740234375 +43292 -0.47198486328125 +43293 -0.560394287109375 +43294 -0.58056640625 +43295 -0.54754638671875 +43296 -0.508575439453125 +43297 -0.459503173828125 +43298 -0.394378662109375 +43299 -0.35260009765625 +43300 -0.31170654296875 +43301 -0.197418212890625 +43302 -0.007965087890625 +43303 0.207489013671875 +43304 0.409210205078125 +43305 0.57208251953125 +43306 0.66595458984375 +43307 0.65875244140625 +43308 0.56744384765625 +43309 0.431396484375 +43310 0.29443359375 +43311 0.182464599609375 +43312 0.06365966796875 +43313 -0.075958251953125 +43314 -0.189422607421875 +43315 -0.271942138671875 +43316 -0.342529296875 +43317 -0.364166259765625 +43318 -0.327239990234375 +43319 -0.2769775390625 +43320 -0.253692626953125 +43321 -0.24365234375 +43322 -0.1983642578125 +43323 -0.116241455078125 +43324 -0.036834716796875 +43325 0.034881591796875 +43326 0.09124755859375 +43327 0.10888671875 +43328 0.125518798828125 +43329 0.15771484375 +43330 0.17828369140625 +43331 0.17108154296875 +43332 0.129974365234375 +43333 0.082427978515625 +43334 0.027679443359375 +43335 -0.065643310546875 +43336 -0.15936279296875 +43337 -0.21307373046875 +43338 -0.234649658203125 +43339 -0.2001953125 +43340 -0.119171142578125 +43341 -0.024749755859375 +43342 0.085784912109375 +43343 0.178131103515625 +43344 0.215576171875 +43345 0.211456298828125 +43346 0.17523193359375 +43347 0.128753662109375 +43348 0.1019287109375 +43349 0.0743408203125 +43350 0.04327392578125 +43351 0.038177490234375 +43352 0.076263427734375 +43353 0.14105224609375 +43354 0.186431884765625 +43355 0.188812255859375 +43356 0.1390380859375 +43357 0.041778564453125 +43358 -0.079437255859375 +43359 -0.219390869140625 +43360 -0.367828369140625 +43361 -0.494873046875 +43362 -0.556243896484375 +43363 -0.508697509765625 +43364 -0.3756103515625 +43365 -0.218902587890625 +43366 -0.063751220703125 +43367 0.091552734375 +43368 0.23602294921875 +43369 0.342987060546875 +43370 0.39520263671875 +43371 0.389373779296875 +43372 0.324249267578125 +43373 0.224090576171875 +43374 0.124267578125 +43375 0.037078857421875 +43376 -0.010101318359375 +43377 -0.019439697265625 +43378 -0.022796630859375 +43379 -0.001556396484375 +43380 0.056304931640625 +43381 0.106719970703125 +43382 0.096893310546875 +43383 0.042694091796875 +43384 -0.018035888671875 +43385 -0.07586669921875 +43386 -0.11944580078125 +43387 -0.15972900390625 +43388 -0.202606201171875 +43389 -0.24859619140625 +43390 -0.30517578125 +43391 -0.36212158203125 +43392 -0.39141845703125 +43393 -0.35528564453125 +43394 -0.249969482421875 +43395 -0.092864990234375 +43396 0.08905029296875 +43397 0.2352294921875 +43398 0.318817138671875 +43399 0.358642578125 +43400 0.347747802734375 +43401 0.28564453125 +43402 0.223175048828125 +43403 0.196746826171875 +43404 0.179840087890625 +43405 0.155548095703125 +43406 0.151214599609375 +43407 0.156951904296875 +43408 0.13177490234375 +43409 0.100799560546875 +43410 0.087127685546875 +43411 0.05487060546875 +43412 -0.009002685546875 +43413 -0.10400390625 +43414 -0.229400634765625 +43415 -0.35552978515625 +43416 -0.441925048828125 +43417 -0.473846435546875 +43418 -0.464813232421875 +43419 -0.419097900390625 +43420 -0.334320068359375 +43421 -0.227935791015625 +43422 -0.12347412109375 +43423 -0.02764892578125 +43424 0.077667236328125 +43425 0.2132568359375 +43426 0.38885498046875 +43427 0.582794189453125 +43428 0.734039306640625 +43429 0.800140380859375 +43430 0.7783203125 +43431 0.6651611328125 +43432 0.45965576171875 +43433 0.199188232421875 +43434 -0.050689697265625 +43435 -0.23297119140625 +43436 -0.33013916015625 +43437 -0.368408203125 +43438 -0.378936767578125 +43439 -0.376983642578125 +43440 -0.37969970703125 +43441 -0.391510009765625 +43442 -0.385345458984375 +43443 -0.3419189453125 +43444 -0.28289794921875 +43445 -0.251617431640625 +43446 -0.266143798828125 +43447 -0.273345947265625 +43448 -0.216796875 +43449 -0.128265380859375 +43450 -0.068145751953125 +43451 -0.0430908203125 +43452 -0.024444580078125 +43453 0.020721435546875 +43454 0.124481201171875 +43455 0.25787353515625 +43456 0.379119873046875 +43457 0.47991943359375 +43458 0.5281982421875 +43459 0.511138916015625 +43460 0.456207275390625 +43461 0.407470703125 +43462 0.383758544921875 +43463 0.35687255859375 +43464 0.31182861328125 +43465 0.250885009765625 +43466 0.1654052734375 +43467 0.035247802734375 +43468 -0.142059326171875 +43469 -0.33563232421875 +43470 -0.5345458984375 +43471 -0.72186279296875 +43472 -0.836669921875 +43473 -0.8326416015625 +43474 -0.7296142578125 +43475 -0.582550048828125 +43476 -0.440093994140625 +43477 -0.324310302734375 +43478 -0.20147705078125 +43479 -0.044647216796875 +43480 0.103973388671875 +43481 0.202392578125 +43482 0.264495849609375 +43483 0.338897705078125 +43484 0.443817138671875 +43485 0.545074462890625 +43486 0.6173095703125 +43487 0.6524658203125 +43488 0.66339111328125 +43489 0.6561279296875 +43490 0.606781005859375 +43491 0.501190185546875 +43492 0.352783203125 +43493 0.176544189453125 +43494 -0.034820556640625 +43495 -0.258209228515625 +43496 -0.44244384765625 +43497 -0.5753173828125 +43498 -0.65203857421875 +43499 -0.641632080078125 +43500 -0.562164306640625 +43501 -0.458038330078125 +43502 -0.350555419921875 +43503 -0.260528564453125 +43504 -0.192108154296875 +43505 -0.141937255859375 +43506 -0.1021728515625 +43507 -0.062896728515625 +43508 -0.011932373046875 +43509 0.062835693359375 +43510 0.148712158203125 +43511 0.241729736328125 +43512 0.34912109375 +43513 0.457305908203125 +43514 0.54388427734375 +43515 0.5728759765625 +43516 0.506591796875 +43517 0.351226806640625 +43518 0.146514892578125 +43519 -0.05523681640625 +43520 -0.21624755859375 +43521 -0.334930419921875 +43522 -0.402984619140625 +43523 -0.4412841796875 +43524 -0.49578857421875 +43525 -0.5601806640625 +43526 -0.600738525390625 +43527 -0.584228515625 +43528 -0.47930908203125 +43529 -0.27935791015625 +43530 -0.0089111328125 +43531 0.268798828125 +43532 0.482818603515625 +43533 0.60369873046875 +43534 0.650421142578125 +43535 0.66400146484375 +43536 0.6414794921875 +43537 0.572540283203125 +43538 0.498138427734375 +43539 0.439453125 +43540 0.375518798828125 +43541 0.274505615234375 +43542 0.1087646484375 +43543 -0.099395751953125 +43544 -0.3182373046875 +43545 -0.5489501953125 +43546 -0.7738037109375 +43547 -0.86383056640625 +43548 -0.870391845703125 +43549 -0.86895751953125 +43550 -0.861053466796875 +43551 -0.765869140625 +43552 -0.5301513671875 +43553 -0.214691162109375 +43554 0.137359619140625 +43555 0.474822998046875 +43556 0.76239013671875 +43557 0.867462158203125 +43558 0.870361328125 +43559 0.86480712890625 +43560 0.831817626953125 +43561 0.677581787109375 +43562 0.495880126953125 +43563 0.30767822265625 +43564 0.116180419921875 +43565 -0.110748291015625 +43566 -0.381805419921875 +43567 -0.6572265625 +43568 -0.857421875 +43569 -0.870391845703125 +43570 -0.870391845703125 +43571 -0.86444091796875 +43572 -0.85723876953125 +43573 -0.790008544921875 +43574 -0.62847900390625 +43575 -0.3956298828125 +43576 -0.126708984375 +43577 0.150115966796875 +43578 0.424041748046875 +43579 0.670623779296875 +43580 0.854522705078125 +43581 0.866485595703125 +43582 0.86920166015625 +43583 0.8653564453125 +43584 0.857147216796875 +43585 0.766845703125 +43586 0.628509521484375 +43587 0.462127685546875 +43588 0.297210693359375 +43589 0.14862060546875 +43590 -0.00537109375 +43591 -0.15753173828125 +43592 -0.31304931640625 +43593 -0.48876953125 +43594 -0.6416015625 +43595 -0.751373291015625 +43596 -0.84619140625 +43597 -0.861297607421875 +43598 -0.863250732421875 +43599 -0.856597900390625 +43600 -0.7498779296875 +43601 -0.624542236328125 +43602 -0.47808837890625 +43603 -0.253387451171875 +43604 0.003692626953125 +43605 0.2257080078125 +43606 0.427154541015625 +43607 0.643218994140625 +43608 0.855926513671875 +43609 0.870361328125 +43610 0.870361328125 +43611 0.862762451171875 +43612 0.79669189453125 +43613 0.595794677734375 +43614 0.362152099609375 +43615 0.1270751953125 +43616 -0.086944580078125 +43617 -0.2784423828125 +43618 -0.484832763671875 +43619 -0.729583740234375 +43620 -0.86688232421875 +43621 -0.870391845703125 +43622 -0.86859130859375 +43623 -0.86279296875 +43624 -0.817962646484375 +43625 -0.6116943359375 +43626 -0.3128662109375 +43627 0.039398193359375 +43628 0.422821044921875 +43629 0.805145263671875 +43630 0.870361328125 +43631 0.870361328125 +43632 0.860015869140625 +43633 0.727935791015625 +43634 0.48114013671875 +43635 0.2059326171875 +43636 -0.06103515625 +43637 -0.29913330078125 +43638 -0.516204833984375 +43639 -0.7252197265625 +43640 -0.85980224609375 +43641 -0.870391845703125 +43642 -0.870391845703125 +43643 -0.858062744140625 +43644 -0.673004150390625 +43645 -0.42694091796875 +43646 -0.2100830078125 +43647 -0.0362548828125 +43648 0.10943603515625 +43649 0.23516845703125 +43650 0.373687744140625 +43651 0.517791748046875 +43652 0.602783203125 +43653 0.635711669921875 +43654 0.655181884765625 +43655 0.65948486328125 +43656 0.651275634765625 +43657 0.61846923828125 +43658 0.53753662109375 +43659 0.404144287109375 +43660 0.22186279296875 +43661 0.003997802734375 +43662 -0.22100830078125 +43663 -0.42449951171875 +43664 -0.579833984375 +43665 -0.641876220703125 +43666 -0.6177978515625 +43667 -0.575531005859375 +43668 -0.526336669921875 +43669 -0.42645263671875 +43670 -0.2581787109375 +43671 -0.068695068359375 +43672 0.09222412109375 +43673 0.232147216796875 +43674 0.3509521484375 +43675 0.410064697265625 +43676 0.372955322265625 +43677 0.2554931640625 +43678 0.10711669921875 +43679 -0.052886962890625 +43680 -0.186279296875 +43681 -0.23291015625 +43682 -0.209442138671875 +43683 -0.174163818359375 +43684 -0.126739501953125 +43685 -0.048126220703125 +43686 0.0426025390625 +43687 0.10748291015625 +43688 0.1409912109375 +43689 0.19708251953125 +43690 0.273651123046875 +43691 0.31768798828125 +43692 0.341094970703125 +43693 0.368011474609375 +43694 0.37249755859375 +43695 0.30072021484375 +43696 0.1517333984375 +43697 -0.01470947265625 +43698 -0.1883544921875 +43699 -0.372711181640625 +43700 -0.51397705078125 +43701 -0.57177734375 +43702 -0.53948974609375 +43703 -0.43511962890625 +43704 -0.2962646484375 +43705 -0.161102294921875 +43706 -0.0435791015625 +43707 0.060394287109375 +43708 0.13665771484375 +43709 0.170135498046875 +43710 0.16552734375 +43711 0.15728759765625 +43712 0.150787353515625 +43713 0.12200927734375 +43714 0.080108642578125 +43715 0.05126953125 +43716 0.062896728515625 +43717 0.09271240234375 +43718 0.092987060546875 +43719 0.07855224609375 +43720 0.06427001953125 +43721 0.0347900390625 +43722 -0.01171875 +43723 -0.056060791015625 +43724 -0.055511474609375 +43725 -0.010467529296875 +43726 0.02508544921875 +43727 0.025665283203125 +43728 0.017333984375 +43729 0.00189208984375 +43730 -0.03173828125 +43731 -0.071502685546875 +43732 -0.13543701171875 +43733 -0.219970703125 +43734 -0.300506591796875 +43735 -0.376312255859375 +43736 -0.416107177734375 +43737 -0.371124267578125 +43738 -0.242279052734375 +43739 -0.069732666015625 +43740 0.125640869140625 +43741 0.31268310546875 +43742 0.45501708984375 +43743 0.554779052734375 +43744 0.61065673828125 +43745 0.610931396484375 +43746 0.531463623046875 +43747 0.3883056640625 +43748 0.23468017578125 +43749 0.095245361328125 +43750 -0.00396728515625 +43751 -0.04852294921875 +43752 -0.055145263671875 +43753 -0.0758056640625 +43754 -0.138702392578125 +43755 -0.209197998046875 +43756 -0.289031982421875 +43757 -0.37884521484375 +43758 -0.456329345703125 +43759 -0.51641845703125 +43760 -0.519287109375 +43761 -0.458251953125 +43762 -0.384796142578125 +43763 -0.323699951171875 +43764 -0.269287109375 +43765 -0.1951904296875 +43766 -0.100006103515625 +43767 -0.01055908203125 +43768 0.1033935546875 +43769 0.24908447265625 +43770 0.373199462890625 +43771 0.45806884765625 +43772 0.511474609375 +43773 0.565399169921875 +43774 0.61138916015625 +43775 0.5897216796875 +43776 0.4906005859375 +43777 0.33148193359375 +43778 0.147796630859375 +43779 -0.01873779296875 +43780 -0.140289306640625 +43781 -0.191986083984375 +43782 -0.184295654296875 +43783 -0.161834716796875 +43784 -0.166595458984375 +43785 -0.19390869140625 +43786 -0.22442626953125 +43787 -0.279754638671875 +43788 -0.3389892578125 +43789 -0.3543701171875 +43790 -0.348175048828125 +43791 -0.32598876953125 +43792 -0.2581787109375 +43793 -0.139801025390625 +43794 0.014617919921875 +43795 0.144378662109375 +43796 0.221038818359375 +43797 0.27069091796875 +43798 0.294036865234375 +43799 0.311767578125 +43800 0.339141845703125 +43801 0.360260009765625 +43802 0.360504150390625 +43803 0.308380126953125 +43804 0.18170166015625 +43805 0.0047607421875 +43806 -0.17559814453125 +43807 -0.3143310546875 +43808 -0.36785888671875 +43809 -0.36248779296875 +43810 -0.343536376953125 +43811 -0.3018798828125 +43812 -0.231414794921875 +43813 -0.117645263671875 +43814 0.007049560546875 +43815 0.087982177734375 +43816 0.13946533203125 +43817 0.17425537109375 +43818 0.188201904296875 +43819 0.171234130859375 +43820 0.118438720703125 +43821 0.05706787109375 +43822 -0.010711669921875 +43823 -0.0914306640625 +43824 -0.162322998046875 +43825 -0.194549560546875 +43826 -0.1492919921875 +43827 -0.02166748046875 +43828 0.124053955078125 +43829 0.211151123046875 +43830 0.240447998046875 +43831 0.242218017578125 +43832 0.2257080078125 +43833 0.194366455078125 +43834 0.115509033203125 +43835 0.0128173828125 +43836 -0.053802490234375 +43837 -0.110626220703125 +43838 -0.199493408203125 +43839 -0.29437255859375 +43840 -0.33221435546875 +43841 -0.27972412109375 +43842 -0.185333251953125 +43843 -0.128204345703125 +43844 -0.115692138671875 +43845 -0.116455078125 +43846 -0.105926513671875 +43847 -0.053955078125 +43848 0.048797607421875 +43849 0.157318115234375 +43850 0.212005615234375 +43851 0.218475341796875 +43852 0.23724365234375 +43853 0.30535888671875 +43854 0.38128662109375 +43855 0.404449462890625 +43856 0.3944091796875 +43857 0.3885498046875 +43858 0.362640380859375 +43859 0.27362060546875 +43860 0.11712646484375 +43861 -0.054901123046875 +43862 -0.19085693359375 +43863 -0.28570556640625 +43864 -0.339263916015625 +43865 -0.3775634765625 +43866 -0.445709228515625 +43867 -0.535064697265625 +43868 -0.629058837890625 +43869 -0.697601318359375 +43870 -0.70391845703125 +43871 -0.6424560546875 +43872 -0.491241455078125 +43873 -0.265716552734375 +43874 -0.023712158203125 +43875 0.201751708984375 +43876 0.375823974609375 +43877 0.485076904296875 +43878 0.56884765625 +43879 0.634765625 +43880 0.63763427734375 +43881 0.5660400390625 +43882 0.4720458984375 +43883 0.40692138671875 +43884 0.3778076171875 +43885 0.376953125 +43886 0.371978759765625 +43887 0.313140869140625 +43888 0.184417724609375 +43889 0.011199951171875 +43890 -0.171051025390625 +43891 -0.33740234375 +43892 -0.47198486328125 +43893 -0.560394287109375 +43894 -0.58056640625 +43895 -0.54754638671875 +43896 -0.508575439453125 +43897 -0.459503173828125 +43898 -0.394378662109375 +43899 -0.35260009765625 +43900 -0.31170654296875 +43901 -0.197418212890625 +43902 -0.007965087890625 +43903 0.207489013671875 +43904 0.409210205078125 +43905 0.57208251953125 +43906 0.66595458984375 +43907 0.65875244140625 +43908 0.56744384765625 +43909 0.431396484375 +43910 0.29443359375 +43911 0.182464599609375 +43912 0.06365966796875 +43913 -0.075958251953125 +43914 -0.189422607421875 +43915 -0.271942138671875 +43916 -0.342529296875 +43917 -0.364166259765625 +43918 -0.327239990234375 +43919 -0.2769775390625 +43920 -0.253692626953125 +43921 -0.24365234375 +43922 -0.1983642578125 +43923 -0.116241455078125 +43924 -0.036834716796875 +43925 0.034881591796875 +43926 0.09124755859375 +43927 0.10888671875 +43928 0.125518798828125 +43929 0.15771484375 +43930 0.17828369140625 +43931 0.17108154296875 +43932 0.129974365234375 +43933 0.082427978515625 +43934 0.027679443359375 +43935 -0.065643310546875 +43936 -0.15936279296875 +43937 -0.21307373046875 +43938 -0.234649658203125 +43939 -0.2001953125 +43940 -0.119171142578125 +43941 -0.024749755859375 +43942 0.085784912109375 +43943 0.178131103515625 +43944 0.215576171875 +43945 0.211456298828125 +43946 0.17523193359375 +43947 0.128753662109375 +43948 0.1019287109375 +43949 0.0743408203125 +43950 0.04327392578125 +43951 0.038177490234375 +43952 0.076263427734375 +43953 0.14105224609375 +43954 0.186431884765625 +43955 0.188812255859375 +43956 0.1390380859375 +43957 0.041778564453125 +43958 -0.079437255859375 +43959 -0.219390869140625 +43960 -0.367828369140625 +43961 -0.494873046875 +43962 -0.556243896484375 +43963 -0.508697509765625 +43964 -0.3756103515625 +43965 -0.218902587890625 +43966 -0.063751220703125 +43967 0.091552734375 +43968 0.23602294921875 +43969 0.342987060546875 +43970 0.39520263671875 +43971 0.389373779296875 +43972 0.324249267578125 +43973 0.224090576171875 +43974 0.124267578125 +43975 0.037078857421875 +43976 -0.010101318359375 +43977 -0.019439697265625 +43978 -0.022796630859375 +43979 -0.001556396484375 +43980 0.056304931640625 +43981 0.106719970703125 +43982 0.096893310546875 +43983 0.042694091796875 +43984 -0.018035888671875 +43985 -0.07586669921875 +43986 -0.11944580078125 +43987 -0.15972900390625 +43988 -0.202606201171875 +43989 -0.24859619140625 +43990 -0.30517578125 +43991 -0.36212158203125 +43992 -0.39141845703125 +43993 -0.35528564453125 +43994 -0.249969482421875 +43995 -0.092864990234375 +43996 0.08905029296875 +43997 0.2352294921875 +43998 0.318817138671875 +43999 0.358642578125 +44000 0.347747802734375 +44001 0.28564453125 +44002 0.223175048828125 +44003 0.196746826171875 +44004 0.179840087890625 +44005 0.155548095703125 +44006 0.151214599609375 +44007 0.156951904296875 +44008 0.13177490234375 +44009 0.100799560546875 +44010 0.087127685546875 +44011 0.05487060546875 +44012 -0.009002685546875 +44013 -0.10400390625 +44014 -0.229400634765625 +44015 -0.35552978515625 +44016 -0.441925048828125 +44017 -0.473846435546875 +44018 -0.464813232421875 +44019 -0.419097900390625 +44020 -0.334320068359375 +44021 -0.227935791015625 +44022 -0.12347412109375 +44023 -0.02764892578125 +44024 0.077667236328125 +44025 0.2132568359375 +44026 0.38885498046875 +44027 0.582794189453125 +44028 0.734039306640625 +44029 0.800140380859375 +44030 0.7783203125 +44031 0.6651611328125 +44032 0.45965576171875 +44033 0.199188232421875 +44034 -0.050689697265625 +44035 -0.23297119140625 +44036 -0.33013916015625 +44037 -0.368408203125 +44038 -0.378936767578125 +44039 -0.376983642578125 +44040 -0.37969970703125 +44041 -0.391510009765625 +44042 -0.385345458984375 +44043 -0.3419189453125 +44044 -0.28289794921875 +44045 -0.251617431640625 +44046 -0.266143798828125 +44047 -0.273345947265625 +44048 -0.216796875 +44049 -0.128265380859375 +44050 -0.068145751953125 +44051 -0.0430908203125 +44052 -0.024444580078125 +44053 0.020721435546875 +44054 0.124481201171875 +44055 0.25787353515625 +44056 0.379119873046875 +44057 0.47991943359375 +44058 0.5281982421875 +44059 0.511138916015625 +44060 0.456207275390625 +44061 0.407470703125 +44062 0.383758544921875 +44063 0.35687255859375 +44064 0.31182861328125 +44065 0.250885009765625 +44066 0.1654052734375 +44067 0.035247802734375 +44068 -0.142059326171875 +44069 -0.33563232421875 +44070 -0.5345458984375 +44071 -0.72186279296875 +44072 -0.836669921875 +44073 -0.8326416015625 +44074 -0.7296142578125 +44075 -0.582550048828125 +44076 -0.440093994140625 +44077 -0.324310302734375 +44078 -0.20147705078125 +44079 -0.044647216796875 +44080 0.103973388671875 +44081 0.202392578125 +44082 0.264495849609375 +44083 0.338897705078125 +44084 0.443817138671875 +44085 0.545074462890625 +44086 0.6173095703125 +44087 0.6524658203125 +44088 0.66339111328125 +44089 0.6561279296875 +44090 0.606781005859375 +44091 0.501190185546875 +44092 0.352783203125 +44093 0.176544189453125 +44094 -0.034820556640625 +44095 -0.258209228515625 +44096 -0.44244384765625 +44097 -0.5753173828125 +44098 -0.65203857421875 +44099 -0.641632080078125 +44100 -0.562164306640625 +44101 -0.458038330078125 +44102 -0.350555419921875 +44103 -0.260528564453125 +44104 -0.192108154296875 +44105 -0.141937255859375 +44106 -0.1021728515625 +44107 -0.062896728515625 +44108 -0.011932373046875 +44109 0.062835693359375 +44110 0.148712158203125 +44111 0.241729736328125 +44112 0.34912109375 +44113 0.457305908203125 +44114 0.54388427734375 +44115 0.5728759765625 +44116 0.506591796875 +44117 0.351226806640625 +44118 0.146514892578125 +44119 -0.05523681640625 +44120 -0.21624755859375 +44121 -0.334930419921875 +44122 -0.402984619140625 +44123 -0.4412841796875 +44124 -0.49578857421875 +44125 -0.5601806640625 +44126 -0.600738525390625 +44127 -0.584228515625 +44128 -0.47930908203125 +44129 -0.27935791015625 +44130 -0.0089111328125 +44131 0.268798828125 +44132 0.482818603515625 +44133 0.60369873046875 +44134 0.650421142578125 +44135 0.66400146484375 +44136 0.6414794921875 +44137 0.572540283203125 +44138 0.498138427734375 +44139 0.439453125 +44140 0.375518798828125 +44141 0.274505615234375 +44142 0.1087646484375 +44143 -0.099395751953125 +44144 -0.3182373046875 +44145 -0.5489501953125 +44146 -0.7738037109375 +44147 -0.86383056640625 +44148 -0.870391845703125 +44149 -0.86895751953125 +44150 -0.861053466796875 +44151 -0.765869140625 +44152 -0.5301513671875 +44153 -0.214691162109375 +44154 0.137359619140625 +44155 0.474822998046875 +44156 0.76239013671875 +44157 0.867462158203125 +44158 0.870361328125 +44159 0.86480712890625 +44160 0.831817626953125 +44161 0.677581787109375 +44162 0.495880126953125 +44163 0.30767822265625 +44164 0.116180419921875 +44165 -0.110748291015625 +44166 -0.381805419921875 +44167 -0.6572265625 +44168 -0.857421875 +44169 -0.870391845703125 +44170 -0.870391845703125 +44171 -0.86444091796875 +44172 -0.85723876953125 +44173 -0.790008544921875 +44174 -0.62847900390625 +44175 -0.3956298828125 +44176 -0.126708984375 +44177 0.150115966796875 +44178 0.424041748046875 +44179 0.670623779296875 +44180 0.854522705078125 +44181 0.866485595703125 +44182 0.86920166015625 +44183 0.8653564453125 +44184 0.857147216796875 +44185 0.766845703125 +44186 0.628509521484375 +44187 0.462127685546875 +44188 0.297210693359375 +44189 0.14862060546875 +44190 -0.00537109375 +44191 -0.15753173828125 +44192 -0.31304931640625 +44193 -0.48876953125 +44194 -0.6416015625 +44195 -0.751373291015625 +44196 -0.84619140625 +44197 -0.861297607421875 +44198 -0.863250732421875 +44199 -0.856597900390625 +44200 -0.7498779296875 +44201 -0.624542236328125 +44202 -0.47808837890625 +44203 -0.253387451171875 +44204 0.003692626953125 +44205 0.2257080078125 +44206 0.427154541015625 +44207 0.643218994140625 +44208 0.855926513671875 +44209 0.870361328125 +44210 0.870361328125 +44211 0.862762451171875 +44212 0.79669189453125 +44213 0.595794677734375 +44214 0.362152099609375 +44215 0.1270751953125 +44216 -0.086944580078125 +44217 -0.2784423828125 +44218 -0.484832763671875 +44219 -0.729583740234375 +44220 -0.86688232421875 +44221 -0.870391845703125 +44222 -0.86859130859375 +44223 -0.86279296875 +44224 -0.817962646484375 +44225 -0.6116943359375 +44226 -0.3128662109375 +44227 0.039398193359375 +44228 0.422821044921875 +44229 0.805145263671875 +44230 0.870361328125 +44231 0.870361328125 +44232 0.860015869140625 +44233 0.727935791015625 +44234 0.48114013671875 +44235 0.2059326171875 +44236 -0.06103515625 +44237 -0.29913330078125 +44238 -0.516204833984375 +44239 -0.7252197265625 +44240 -0.85980224609375 +44241 -0.870391845703125 +44242 -0.870391845703125 +44243 -0.858062744140625 +44244 -0.673004150390625 +44245 -0.42694091796875 +44246 -0.2100830078125 +44247 -0.0362548828125 +44248 0.10943603515625 +44249 0.23516845703125 +44250 0.373687744140625 +44251 0.517791748046875 +44252 0.602783203125 +44253 0.635711669921875 +44254 0.655181884765625 +44255 0.65948486328125 +44256 0.651275634765625 +44257 0.61846923828125 +44258 0.53753662109375 +44259 0.404144287109375 +44260 0.22186279296875 +44261 0.003997802734375 +44262 -0.22100830078125 +44263 -0.42449951171875 +44264 -0.579833984375 +44265 -0.641876220703125 +44266 -0.6177978515625 +44267 -0.575531005859375 +44268 -0.526336669921875 +44269 -0.42645263671875 +44270 -0.2581787109375 +44271 -0.068695068359375 +44272 0.09222412109375 +44273 0.232147216796875 +44274 0.3509521484375 +44275 0.410064697265625 +44276 0.372955322265625 +44277 0.2554931640625 +44278 0.10711669921875 +44279 -0.052886962890625 +44280 -0.186279296875 +44281 -0.23291015625 +44282 -0.209442138671875 +44283 -0.174163818359375 +44284 -0.126739501953125 +44285 -0.048126220703125 +44286 0.0426025390625 +44287 0.10748291015625 +44288 0.1409912109375 +44289 0.19708251953125 +44290 0.273651123046875 +44291 0.31768798828125 +44292 0.341094970703125 +44293 0.368011474609375 +44294 0.37249755859375 +44295 0.30072021484375 +44296 0.1517333984375 +44297 -0.01470947265625 +44298 -0.1883544921875 +44299 -0.372711181640625 +44300 -0.51397705078125 +44301 -0.57177734375 +44302 -0.53948974609375 +44303 -0.43511962890625 +44304 -0.2962646484375 +44305 -0.161102294921875 +44306 -0.0435791015625 +44307 0.060394287109375 +44308 0.13665771484375 +44309 0.170135498046875 +44310 0.16552734375 +44311 0.15728759765625 +44312 0.150787353515625 +44313 0.12200927734375 +44314 0.080108642578125 +44315 0.05126953125 +44316 0.062896728515625 +44317 0.09271240234375 +44318 0.092987060546875 +44319 0.07855224609375 +44320 0.06427001953125 +44321 0.0347900390625 +44322 -0.01171875 +44323 -0.056060791015625 +44324 -0.055511474609375 +44325 -0.010467529296875 +44326 0.02508544921875 +44327 0.025665283203125 +44328 0.017333984375 +44329 0.00189208984375 +44330 -0.03173828125 +44331 -0.071502685546875 +44332 -0.13543701171875 +44333 -0.219970703125 +44334 -0.300506591796875 +44335 -0.376312255859375 +44336 -0.416107177734375 +44337 -0.371124267578125 +44338 -0.242279052734375 +44339 -0.069732666015625 +44340 0.125640869140625 +44341 0.31268310546875 +44342 0.45501708984375 +44343 0.554779052734375 +44344 0.61065673828125 +44345 0.610931396484375 +44346 0.531463623046875 +44347 0.3883056640625 +44348 0.23468017578125 +44349 0.095245361328125 +44350 -0.00396728515625 +44351 -0.04852294921875 +44352 -0.055145263671875 +44353 -0.0758056640625 +44354 -0.138702392578125 +44355 -0.209197998046875 +44356 -0.289031982421875 +44357 -0.37884521484375 +44358 -0.456329345703125 +44359 -0.51641845703125 +44360 -0.519287109375 +44361 -0.458251953125 +44362 -0.384796142578125 +44363 -0.323699951171875 +44364 -0.269287109375 +44365 -0.1951904296875 +44366 -0.100006103515625 +44367 -0.01055908203125 +44368 0.1033935546875 +44369 0.24908447265625 +44370 0.373199462890625 +44371 0.45806884765625 +44372 0.511474609375 +44373 0.565399169921875 +44374 0.61138916015625 +44375 0.5897216796875 +44376 0.4906005859375 +44377 0.33148193359375 +44378 0.147796630859375 +44379 -0.01873779296875 +44380 -0.140289306640625 +44381 -0.191986083984375 +44382 -0.184295654296875 +44383 -0.161834716796875 +44384 -0.166595458984375 +44385 -0.19390869140625 +44386 -0.22442626953125 +44387 -0.279754638671875 +44388 -0.3389892578125 +44389 -0.3543701171875 +44390 -0.348175048828125 +44391 -0.32598876953125 +44392 -0.2581787109375 +44393 -0.139801025390625 +44394 0.014617919921875 +44395 0.144378662109375 +44396 0.221038818359375 +44397 0.27069091796875 +44398 0.294036865234375 +44399 0.311767578125 +44400 0.339141845703125 +44401 0.360260009765625 +44402 0.360504150390625 +44403 0.308380126953125 +44404 0.18170166015625 +44405 0.0047607421875 +44406 -0.17559814453125 +44407 -0.3143310546875 +44408 -0.36785888671875 +44409 -0.36248779296875 +44410 -0.343536376953125 +44411 -0.3018798828125 +44412 -0.231414794921875 +44413 -0.117645263671875 +44414 0.007049560546875 +44415 0.087982177734375 +44416 0.13946533203125 +44417 0.17425537109375 +44418 0.188201904296875 +44419 0.171234130859375 +44420 0.118438720703125 +44421 0.05706787109375 +44422 -0.010711669921875 +44423 -0.0914306640625 +44424 -0.162322998046875 +44425 -0.194549560546875 +44426 -0.1492919921875 +44427 -0.02166748046875 +44428 0.124053955078125 +44429 0.211151123046875 +44430 0.240447998046875 +44431 0.242218017578125 +44432 0.2257080078125 +44433 0.194366455078125 +44434 0.115509033203125 +44435 0.0128173828125 +44436 -0.053802490234375 +44437 -0.110626220703125 +44438 -0.199493408203125 +44439 -0.29437255859375 +44440 -0.33221435546875 +44441 -0.27972412109375 +44442 -0.185333251953125 +44443 -0.128204345703125 +44444 -0.115692138671875 +44445 -0.116455078125 +44446 -0.105926513671875 +44447 -0.053955078125 +44448 0.048797607421875 +44449 0.157318115234375 +44450 0.212005615234375 +44451 0.218475341796875 +44452 0.23724365234375 +44453 0.30535888671875 +44454 0.38128662109375 +44455 0.404449462890625 +44456 0.3944091796875 +44457 0.3885498046875 +44458 0.362640380859375 +44459 0.27362060546875 +44460 0.11712646484375 +44461 -0.054901123046875 +44462 -0.19085693359375 +44463 -0.28570556640625 +44464 -0.339263916015625 +44465 -0.3775634765625 +44466 -0.445709228515625 +44467 -0.535064697265625 +44468 -0.629058837890625 +44469 -0.697601318359375 +44470 -0.70391845703125 +44471 -0.6424560546875 +44472 -0.491241455078125 +44473 -0.265716552734375 +44474 -0.023712158203125 +44475 0.201751708984375 +44476 0.375823974609375 +44477 0.485076904296875 +44478 0.56884765625 +44479 0.634765625 +44480 0.63763427734375 +44481 0.5660400390625 +44482 0.4720458984375 +44483 0.40692138671875 +44484 0.3778076171875 +44485 0.376953125 +44486 0.371978759765625 +44487 0.313140869140625 +44488 0.184417724609375 +44489 0.011199951171875 +44490 -0.171051025390625 +44491 -0.33740234375 +44492 -0.47198486328125 +44493 -0.560394287109375 +44494 -0.58056640625 +44495 -0.54754638671875 +44496 -0.508575439453125 +44497 -0.459503173828125 +44498 -0.394378662109375 +44499 -0.35260009765625 +44500 -0.31170654296875 +44501 -0.197418212890625 +44502 -0.007965087890625 +44503 0.207489013671875 +44504 0.409210205078125 +44505 0.57208251953125 +44506 0.66595458984375 +44507 0.65875244140625 +44508 0.56744384765625 +44509 0.431396484375 +44510 0.29443359375 +44511 0.182464599609375 +44512 0.06365966796875 +44513 -0.075958251953125 +44514 -0.189422607421875 +44515 -0.271942138671875 +44516 -0.342529296875 +44517 -0.364166259765625 +44518 -0.327239990234375 +44519 -0.2769775390625 +44520 -0.253692626953125 +44521 -0.24365234375 +44522 -0.1983642578125 +44523 -0.116241455078125 +44524 -0.036834716796875 +44525 0.034881591796875 +44526 0.09124755859375 +44527 0.10888671875 +44528 0.125518798828125 +44529 0.15771484375 +44530 0.17828369140625 +44531 0.17108154296875 +44532 0.129974365234375 +44533 0.082427978515625 +44534 0.027679443359375 +44535 -0.065643310546875 +44536 -0.15936279296875 +44537 -0.21307373046875 +44538 -0.234649658203125 +44539 -0.2001953125 +44540 -0.119171142578125 +44541 -0.024749755859375 +44542 0.085784912109375 +44543 0.178131103515625 +44544 0.215576171875 +44545 0.211456298828125 +44546 0.17523193359375 +44547 0.128753662109375 +44548 0.1019287109375 +44549 0.0743408203125 +44550 0.04327392578125 +44551 0.038177490234375 +44552 0.076263427734375 +44553 0.14105224609375 +44554 0.186431884765625 +44555 0.188812255859375 +44556 0.1390380859375 +44557 0.041778564453125 +44558 -0.079437255859375 +44559 -0.219390869140625 +44560 -0.367828369140625 +44561 -0.494873046875 +44562 -0.556243896484375 +44563 -0.508697509765625 +44564 -0.3756103515625 +44565 -0.218902587890625 +44566 -0.063751220703125 +44567 0.091552734375 +44568 0.23602294921875 +44569 0.342987060546875 +44570 0.39520263671875 +44571 0.389373779296875 +44572 0.324249267578125 +44573 0.224090576171875 +44574 0.124267578125 +44575 0.037078857421875 +44576 -0.010101318359375 +44577 -0.019439697265625 +44578 -0.022796630859375 +44579 -0.001556396484375 +44580 0.056304931640625 +44581 0.106719970703125 +44582 0.096893310546875 +44583 0.042694091796875 +44584 -0.018035888671875 +44585 -0.07586669921875 +44586 -0.11944580078125 +44587 -0.15972900390625 +44588 -0.202606201171875 +44589 -0.24859619140625 +44590 -0.30517578125 +44591 -0.36212158203125 +44592 -0.39141845703125 +44593 -0.35528564453125 +44594 -0.249969482421875 +44595 -0.092864990234375 +44596 0.08905029296875 +44597 0.2352294921875 +44598 0.318817138671875 +44599 0.358642578125 +44600 0.347747802734375 +44601 0.28564453125 +44602 0.223175048828125 +44603 0.196746826171875 +44604 0.179840087890625 +44605 0.155548095703125 +44606 0.151214599609375 +44607 0.156951904296875 +44608 0.13177490234375 +44609 0.100799560546875 +44610 0.087127685546875 +44611 0.05487060546875 +44612 -0.009002685546875 +44613 -0.10400390625 +44614 -0.229400634765625 +44615 -0.35552978515625 +44616 -0.441925048828125 +44617 -0.473846435546875 +44618 -0.464813232421875 +44619 -0.419097900390625 +44620 -0.334320068359375 +44621 -0.227935791015625 +44622 -0.12347412109375 +44623 -0.02764892578125 +44624 0.077667236328125 +44625 0.2132568359375 +44626 0.38885498046875 +44627 0.582794189453125 +44628 0.734039306640625 +44629 0.800140380859375 +44630 0.7783203125 +44631 0.6651611328125 +44632 0.45965576171875 +44633 0.199188232421875 +44634 -0.050689697265625 +44635 -0.23297119140625 +44636 -0.33013916015625 +44637 -0.368408203125 +44638 -0.378936767578125 +44639 -0.376983642578125 +44640 -0.37969970703125 +44641 -0.391510009765625 +44642 -0.385345458984375 +44643 -0.3419189453125 +44644 -0.28289794921875 +44645 -0.251617431640625 +44646 -0.266143798828125 +44647 -0.273345947265625 +44648 -0.216796875 +44649 -0.128265380859375 +44650 -0.068145751953125 +44651 -0.0430908203125 +44652 -0.024444580078125 +44653 0.020721435546875 +44654 0.124481201171875 +44655 0.25787353515625 +44656 0.379119873046875 +44657 0.47991943359375 +44658 0.5281982421875 +44659 0.511138916015625 +44660 0.456207275390625 +44661 0.407470703125 +44662 0.383758544921875 +44663 0.35687255859375 +44664 0.31182861328125 +44665 0.250885009765625 +44666 0.1654052734375 +44667 0.035247802734375 +44668 -0.142059326171875 +44669 -0.33563232421875 +44670 -0.5345458984375 +44671 -0.72186279296875 +44672 -0.836669921875 +44673 -0.8326416015625 +44674 -0.7296142578125 +44675 -0.582550048828125 +44676 -0.440093994140625 +44677 -0.324310302734375 +44678 -0.20147705078125 +44679 -0.044647216796875 +44680 0.103973388671875 +44681 0.202392578125 +44682 0.264495849609375 +44683 0.338897705078125 +44684 0.443817138671875 +44685 0.545074462890625 +44686 0.6173095703125 +44687 0.6524658203125 +44688 0.66339111328125 +44689 0.6561279296875 +44690 0.606781005859375 +44691 0.501190185546875 +44692 0.352783203125 +44693 0.176544189453125 +44694 -0.034820556640625 +44695 -0.258209228515625 +44696 -0.44244384765625 +44697 -0.5753173828125 +44698 -0.65203857421875 +44699 -0.641632080078125 +44700 -0.562164306640625 +44701 -0.458038330078125 +44702 -0.350555419921875 +44703 -0.260528564453125 +44704 -0.192108154296875 +44705 -0.141937255859375 +44706 -0.1021728515625 +44707 -0.062896728515625 +44708 -0.011932373046875 +44709 0.062835693359375 +44710 0.148712158203125 +44711 0.241729736328125 +44712 0.34912109375 +44713 0.457305908203125 +44714 0.54388427734375 +44715 0.5728759765625 +44716 0.506591796875 +44717 0.351226806640625 +44718 0.146514892578125 +44719 -0.05523681640625 +44720 -0.21624755859375 +44721 -0.334930419921875 +44722 -0.402984619140625 +44723 -0.4412841796875 +44724 -0.49578857421875 +44725 -0.5601806640625 +44726 -0.600738525390625 +44727 -0.584228515625 +44728 -0.47930908203125 +44729 -0.27935791015625 +44730 -0.0089111328125 +44731 0.268798828125 +44732 0.482818603515625 +44733 0.60369873046875 +44734 0.650421142578125 +44735 0.66400146484375 +44736 0.6414794921875 +44737 0.572540283203125 +44738 0.498138427734375 +44739 0.439453125 +44740 0.375518798828125 +44741 0.274505615234375 +44742 0.1087646484375 +44743 -0.099395751953125 +44744 -0.3182373046875 +44745 -0.5489501953125 +44746 -0.7738037109375 +44747 -0.86383056640625 +44748 -0.870391845703125 +44749 -0.86895751953125 +44750 -0.861053466796875 +44751 -0.765869140625 +44752 -0.5301513671875 +44753 -0.214691162109375 +44754 0.137359619140625 +44755 0.474822998046875 +44756 0.76239013671875 +44757 0.867462158203125 +44758 0.870361328125 +44759 0.86480712890625 +44760 0.831817626953125 +44761 0.677581787109375 +44762 0.495880126953125 +44763 0.30767822265625 +44764 0.116180419921875 +44765 -0.110748291015625 +44766 -0.381805419921875 +44767 -0.6572265625 +44768 -0.857421875 +44769 -0.870391845703125 +44770 -0.870391845703125 +44771 -0.86444091796875 +44772 -0.85723876953125 +44773 -0.790008544921875 +44774 -0.62847900390625 +44775 -0.3956298828125 +44776 -0.126708984375 +44777 0.150115966796875 +44778 0.424041748046875 +44779 0.670623779296875 +44780 0.854522705078125 +44781 0.866485595703125 +44782 0.86920166015625 +44783 0.8653564453125 +44784 0.857147216796875 +44785 0.766845703125 +44786 0.628509521484375 +44787 0.462127685546875 +44788 0.297210693359375 +44789 0.14862060546875 +44790 -0.00537109375 +44791 -0.15753173828125 +44792 -0.31304931640625 +44793 -0.48876953125 +44794 -0.6416015625 +44795 -0.751373291015625 +44796 -0.84619140625 +44797 -0.861297607421875 +44798 -0.863250732421875 +44799 -0.856597900390625 +44800 -0.7498779296875 +44801 -0.624542236328125 +44802 -0.47808837890625 +44803 -0.253387451171875 +44804 0.003692626953125 +44805 0.2257080078125 +44806 0.427154541015625 +44807 0.643218994140625 +44808 0.855926513671875 +44809 0.870361328125 +44810 0.870361328125 +44811 0.862762451171875 +44812 0.79669189453125 +44813 0.595794677734375 +44814 0.362152099609375 +44815 0.1270751953125 +44816 -0.086944580078125 +44817 -0.2784423828125 +44818 -0.484832763671875 +44819 -0.729583740234375 +44820 -0.86688232421875 +44821 -0.870391845703125 +44822 -0.86859130859375 +44823 -0.86279296875 +44824 -0.817962646484375 +44825 -0.6116943359375 +44826 -0.3128662109375 +44827 0.039398193359375 +44828 0.422821044921875 +44829 0.805145263671875 +44830 0.870361328125 +44831 0.870361328125 +44832 0.860015869140625 +44833 0.727935791015625 +44834 0.48114013671875 +44835 0.2059326171875 +44836 -0.06103515625 +44837 -0.29913330078125 +44838 -0.516204833984375 +44839 -0.7252197265625 +44840 -0.85980224609375 +44841 -0.870391845703125 +44842 -0.870391845703125 +44843 -0.858062744140625 +44844 -0.673004150390625 +44845 -0.42694091796875 +44846 -0.2100830078125 +44847 -0.0362548828125 +44848 0.10943603515625 +44849 0.23516845703125 +44850 0.373687744140625 +44851 0.517791748046875 +44852 0.602783203125 +44853 0.635711669921875 +44854 0.655181884765625 +44855 0.65948486328125 +44856 0.651275634765625 +44857 0.61846923828125 +44858 0.53753662109375 +44859 0.404144287109375 +44860 0.22186279296875 +44861 0.003997802734375 +44862 -0.22100830078125 +44863 -0.42449951171875 +44864 -0.579833984375 +44865 -0.641876220703125 +44866 -0.6177978515625 +44867 -0.575531005859375 +44868 -0.526336669921875 +44869 -0.42645263671875 +44870 -0.2581787109375 +44871 -0.068695068359375 +44872 0.09222412109375 +44873 0.232147216796875 +44874 0.3509521484375 +44875 0.410064697265625 +44876 0.372955322265625 +44877 0.2554931640625 +44878 0.10711669921875 +44879 -0.052886962890625 +44880 -0.186279296875 +44881 -0.23291015625 +44882 -0.209442138671875 +44883 -0.174163818359375 +44884 -0.126739501953125 +44885 -0.048126220703125 +44886 0.0426025390625 +44887 0.10748291015625 +44888 0.1409912109375 +44889 0.19708251953125 +44890 0.273651123046875 +44891 0.31768798828125 +44892 0.341094970703125 +44893 0.368011474609375 +44894 0.37249755859375 +44895 0.30072021484375 +44896 0.1517333984375 +44897 -0.01470947265625 +44898 -0.1883544921875 +44899 -0.372711181640625 +44900 -0.51397705078125 +44901 -0.57177734375 +44902 -0.53948974609375 +44903 -0.43511962890625 +44904 -0.2962646484375 +44905 -0.161102294921875 +44906 -0.0435791015625 +44907 0.060394287109375 +44908 0.13665771484375 +44909 0.170135498046875 +44910 0.16552734375 +44911 0.15728759765625 +44912 0.150787353515625 +44913 0.12200927734375 +44914 0.080108642578125 +44915 0.05126953125 +44916 0.062896728515625 +44917 0.09271240234375 +44918 0.092987060546875 +44919 0.07855224609375 +44920 0.06427001953125 +44921 0.0347900390625 +44922 -0.01171875 +44923 -0.056060791015625 +44924 -0.055511474609375 +44925 -0.010467529296875 +44926 0.02508544921875 +44927 0.025665283203125 +44928 0.017333984375 +44929 0.00189208984375 +44930 -0.03173828125 +44931 -0.071502685546875 +44932 -0.13543701171875 +44933 -0.219970703125 +44934 -0.300506591796875 +44935 -0.376312255859375 +44936 -0.416107177734375 +44937 -0.371124267578125 +44938 -0.242279052734375 +44939 -0.069732666015625 +44940 0.125640869140625 +44941 0.31268310546875 +44942 0.45501708984375 +44943 0.554779052734375 +44944 0.61065673828125 +44945 0.610931396484375 +44946 0.531463623046875 +44947 0.3883056640625 +44948 0.23468017578125 +44949 0.095245361328125 +44950 -0.00396728515625 +44951 -0.04852294921875 +44952 -0.055145263671875 +44953 -0.0758056640625 +44954 -0.138702392578125 +44955 -0.209197998046875 +44956 -0.289031982421875 +44957 -0.37884521484375 +44958 -0.456329345703125 +44959 -0.51641845703125 +44960 -0.519287109375 +44961 -0.458251953125 +44962 -0.384796142578125 +44963 -0.323699951171875 +44964 -0.269287109375 +44965 -0.1951904296875 +44966 -0.100006103515625 +44967 -0.01055908203125 +44968 0.1033935546875 +44969 0.24908447265625 +44970 0.373199462890625 +44971 0.45806884765625 +44972 0.511474609375 +44973 0.565399169921875 +44974 0.61138916015625 +44975 0.5897216796875 +44976 0.4906005859375 +44977 0.33148193359375 +44978 0.147796630859375 +44979 -0.01873779296875 +44980 -0.140289306640625 +44981 -0.191986083984375 +44982 -0.184295654296875 +44983 -0.161834716796875 +44984 -0.166595458984375 +44985 -0.19390869140625 +44986 -0.22442626953125 +44987 -0.279754638671875 +44988 -0.3389892578125 +44989 -0.3543701171875 +44990 -0.348175048828125 +44991 -0.32598876953125 +44992 -0.2581787109375 +44993 -0.139801025390625 +44994 0.014617919921875 +44995 0.144378662109375 +44996 0.221038818359375 +44997 0.27069091796875 +44998 0.294036865234375 +44999 0.311767578125 +45000 0.339141845703125 +45001 0.360260009765625 +45002 0.360504150390625 +45003 0.308380126953125 +45004 0.18170166015625 +45005 0.0047607421875 +45006 -0.17559814453125 +45007 -0.3143310546875 +45008 -0.36785888671875 +45009 -0.36248779296875 +45010 -0.343536376953125 +45011 -0.3018798828125 +45012 -0.231414794921875 +45013 -0.117645263671875 +45014 0.007049560546875 +45015 0.087982177734375 +45016 0.13946533203125 +45017 0.17425537109375 +45018 0.188201904296875 +45019 0.171234130859375 +45020 0.118438720703125 +45021 0.05706787109375 +45022 -0.010711669921875 +45023 -0.0914306640625 +45024 -0.162322998046875 +45025 -0.194549560546875 +45026 -0.1492919921875 +45027 -0.02166748046875 +45028 0.124053955078125 +45029 0.211151123046875 +45030 0.240447998046875 +45031 0.242218017578125 +45032 0.2257080078125 +45033 0.194366455078125 +45034 0.115509033203125 +45035 0.0128173828125 +45036 -0.053802490234375 +45037 -0.110626220703125 +45038 -0.199493408203125 +45039 -0.29437255859375 +45040 -0.33221435546875 +45041 -0.27972412109375 +45042 -0.185333251953125 +45043 -0.128204345703125 +45044 -0.115692138671875 +45045 -0.116455078125 +45046 -0.105926513671875 +45047 -0.053955078125 +45048 0.048797607421875 +45049 0.157318115234375 +45050 0.212005615234375 +45051 0.218475341796875 +45052 0.23724365234375 +45053 0.30535888671875 +45054 0.38128662109375 +45055 0.404449462890625 +45056 0.3944091796875 +45057 0.3885498046875 +45058 0.362640380859375 +45059 0.27362060546875 +45060 0.11712646484375 +45061 -0.054901123046875 +45062 -0.19085693359375 +45063 -0.28570556640625 +45064 -0.339263916015625 +45065 -0.3775634765625 +45066 -0.445709228515625 +45067 -0.535064697265625 +45068 -0.629058837890625 +45069 -0.697601318359375 +45070 -0.70391845703125 +45071 -0.6424560546875 +45072 -0.491241455078125 +45073 -0.265716552734375 +45074 -0.023712158203125 +45075 0.201751708984375 +45076 0.375823974609375 +45077 0.485076904296875 +45078 0.56884765625 +45079 0.634765625 +45080 0.63763427734375 +45081 0.5660400390625 +45082 0.4720458984375 +45083 0.40692138671875 +45084 0.3778076171875 +45085 0.376953125 +45086 0.371978759765625 +45087 0.313140869140625 +45088 0.184417724609375 +45089 0.011199951171875 +45090 -0.171051025390625 +45091 -0.33740234375 +45092 -0.47198486328125 +45093 -0.560394287109375 +45094 -0.58056640625 +45095 -0.54754638671875 +45096 -0.508575439453125 +45097 -0.459503173828125 +45098 -0.394378662109375 +45099 -0.35260009765625 +45100 -0.31170654296875 +45101 -0.197418212890625 +45102 -0.007965087890625 +45103 0.207489013671875 +45104 0.409210205078125 +45105 0.57208251953125 +45106 0.66595458984375 +45107 0.65875244140625 +45108 0.56744384765625 +45109 0.431396484375 +45110 0.29443359375 +45111 0.182464599609375 +45112 0.06365966796875 +45113 -0.075958251953125 +45114 -0.189422607421875 +45115 -0.271942138671875 +45116 -0.342529296875 +45117 -0.364166259765625 +45118 -0.327239990234375 +45119 -0.2769775390625 +45120 -0.253692626953125 +45121 -0.24365234375 +45122 -0.1983642578125 +45123 -0.116241455078125 +45124 -0.036834716796875 +45125 0.034881591796875 +45126 0.09124755859375 +45127 0.10888671875 +45128 0.125518798828125 +45129 0.15771484375 +45130 0.17828369140625 +45131 0.17108154296875 +45132 0.129974365234375 +45133 0.082427978515625 +45134 0.027679443359375 +45135 -0.065643310546875 +45136 -0.15936279296875 +45137 -0.21307373046875 +45138 -0.234649658203125 +45139 -0.2001953125 +45140 -0.119171142578125 +45141 -0.024749755859375 +45142 0.085784912109375 +45143 0.178131103515625 +45144 0.215576171875 +45145 0.211456298828125 +45146 0.17523193359375 +45147 0.128753662109375 +45148 0.1019287109375 +45149 0.0743408203125 +45150 0.04327392578125 +45151 0.038177490234375 +45152 0.076263427734375 +45153 0.14105224609375 +45154 0.186431884765625 +45155 0.188812255859375 +45156 0.1390380859375 +45157 0.041778564453125 +45158 -0.079437255859375 +45159 -0.219390869140625 +45160 -0.367828369140625 +45161 -0.494873046875 +45162 -0.556243896484375 +45163 -0.508697509765625 +45164 -0.3756103515625 +45165 -0.218902587890625 +45166 -0.063751220703125 +45167 0.091552734375 +45168 0.23602294921875 +45169 0.342987060546875 +45170 0.39520263671875 +45171 0.389373779296875 +45172 0.324249267578125 +45173 0.224090576171875 +45174 0.124267578125 +45175 0.037078857421875 +45176 -0.010101318359375 +45177 -0.019439697265625 +45178 -0.022796630859375 +45179 -0.001556396484375 +45180 0.056304931640625 +45181 0.106719970703125 +45182 0.096893310546875 +45183 0.042694091796875 +45184 -0.018035888671875 +45185 -0.07586669921875 +45186 -0.11944580078125 +45187 -0.15972900390625 +45188 -0.202606201171875 +45189 -0.24859619140625 +45190 -0.30517578125 +45191 -0.36212158203125 +45192 -0.39141845703125 +45193 -0.35528564453125 +45194 -0.249969482421875 +45195 -0.092864990234375 +45196 0.08905029296875 +45197 0.2352294921875 +45198 0.318817138671875 +45199 0.358642578125 +45200 0.347747802734375 +45201 0.28564453125 +45202 0.223175048828125 +45203 0.196746826171875 +45204 0.179840087890625 +45205 0.155548095703125 +45206 0.151214599609375 +45207 0.156951904296875 +45208 0.13177490234375 +45209 0.100799560546875 +45210 0.087127685546875 +45211 0.05487060546875 +45212 -0.009002685546875 +45213 -0.10400390625 +45214 -0.229400634765625 +45215 -0.35552978515625 +45216 -0.441925048828125 +45217 -0.473846435546875 +45218 -0.464813232421875 +45219 -0.419097900390625 +45220 -0.334320068359375 +45221 -0.227935791015625 +45222 -0.12347412109375 +45223 -0.02764892578125 +45224 0.077667236328125 +45225 0.2132568359375 +45226 0.38885498046875 +45227 0.582794189453125 +45228 0.734039306640625 +45229 0.800140380859375 +45230 0.7783203125 +45231 0.6651611328125 +45232 0.45965576171875 +45233 0.199188232421875 +45234 -0.050689697265625 +45235 -0.23297119140625 +45236 -0.33013916015625 +45237 -0.368408203125 +45238 -0.378936767578125 +45239 -0.376983642578125 +45240 -0.37969970703125 +45241 -0.391510009765625 +45242 -0.385345458984375 +45243 -0.3419189453125 +45244 -0.28289794921875 +45245 -0.251617431640625 +45246 -0.266143798828125 +45247 -0.273345947265625 +45248 -0.216796875 +45249 -0.128265380859375 +45250 -0.068145751953125 +45251 -0.0430908203125 +45252 -0.024444580078125 +45253 0.020721435546875 +45254 0.124481201171875 +45255 0.25787353515625 +45256 0.379119873046875 +45257 0.47991943359375 +45258 0.5281982421875 +45259 0.511138916015625 +45260 0.456207275390625 +45261 0.407470703125 +45262 0.383758544921875 +45263 0.35687255859375 +45264 0.31182861328125 +45265 0.250885009765625 +45266 0.1654052734375 +45267 0.035247802734375 +45268 -0.142059326171875 +45269 -0.33563232421875 +45270 -0.5345458984375 +45271 -0.72186279296875 +45272 -0.836669921875 +45273 -0.8326416015625 +45274 -0.7296142578125 +45275 -0.582550048828125 +45276 -0.440093994140625 +45277 -0.324310302734375 +45278 -0.20147705078125 +45279 -0.044647216796875 +45280 0.103973388671875 +45281 0.202392578125 +45282 0.264495849609375 +45283 0.338897705078125 +45284 0.443817138671875 +45285 0.545074462890625 +45286 0.6173095703125 +45287 0.6524658203125 +45288 0.66339111328125 +45289 0.6561279296875 +45290 0.606781005859375 +45291 0.501190185546875 +45292 0.352783203125 +45293 0.176544189453125 +45294 -0.034820556640625 +45295 -0.258209228515625 +45296 -0.44244384765625 +45297 -0.5753173828125 +45298 -0.65203857421875 +45299 -0.641632080078125 +45300 -0.562164306640625 +45301 -0.458038330078125 +45302 -0.350555419921875 +45303 -0.260528564453125 +45304 -0.192108154296875 +45305 -0.141937255859375 +45306 -0.1021728515625 +45307 -0.062896728515625 +45308 -0.011932373046875 +45309 0.062835693359375 +45310 0.148712158203125 +45311 0.241729736328125 +45312 0.34912109375 +45313 0.457305908203125 +45314 0.54388427734375 +45315 0.5728759765625 +45316 0.506591796875 +45317 0.351226806640625 +45318 0.146514892578125 +45319 -0.05523681640625 +45320 -0.21624755859375 +45321 -0.334930419921875 +45322 -0.402984619140625 +45323 -0.4412841796875 +45324 -0.49578857421875 +45325 -0.5601806640625 +45326 -0.600738525390625 +45327 -0.584228515625 +45328 -0.47930908203125 +45329 -0.27935791015625 +45330 -0.0089111328125 +45331 0.268798828125 +45332 0.482818603515625 +45333 0.60369873046875 +45334 0.650421142578125 +45335 0.66400146484375 +45336 0.6414794921875 +45337 0.572540283203125 +45338 0.498138427734375 +45339 0.439453125 +45340 0.375518798828125 +45341 0.274505615234375 +45342 0.1087646484375 +45343 -0.099395751953125 +45344 -0.3182373046875 +45345 -0.5489501953125 +45346 -0.7738037109375 +45347 -0.86383056640625 +45348 -0.870391845703125 +45349 -0.86895751953125 +45350 -0.861053466796875 +45351 -0.765869140625 +45352 -0.5301513671875 +45353 -0.214691162109375 +45354 0.137359619140625 +45355 0.474822998046875 +45356 0.76239013671875 +45357 0.867462158203125 +45358 0.870361328125 +45359 0.86480712890625 +45360 0.831817626953125 +45361 0.677581787109375 +45362 0.495880126953125 +45363 0.30767822265625 +45364 0.116180419921875 +45365 -0.110748291015625 +45366 -0.381805419921875 +45367 -0.6572265625 +45368 -0.857421875 +45369 -0.870391845703125 +45370 -0.870391845703125 +45371 -0.86444091796875 +45372 -0.85723876953125 +45373 -0.790008544921875 +45374 -0.62847900390625 +45375 -0.3956298828125 +45376 -0.126708984375 +45377 0.150115966796875 +45378 0.424041748046875 +45379 0.670623779296875 +45380 0.854522705078125 +45381 0.866485595703125 +45382 0.86920166015625 +45383 0.8653564453125 +45384 0.857147216796875 +45385 0.766845703125 +45386 0.628509521484375 +45387 0.462127685546875 +45388 0.297210693359375 +45389 0.14862060546875 +45390 -0.00537109375 +45391 -0.15753173828125 +45392 -0.31304931640625 +45393 -0.48876953125 +45394 -0.6416015625 +45395 -0.751373291015625 +45396 -0.84619140625 +45397 -0.861297607421875 +45398 -0.863250732421875 +45399 -0.856597900390625 +45400 -0.7498779296875 +45401 -0.624542236328125 +45402 -0.47808837890625 +45403 -0.253387451171875 +45404 0.003692626953125 +45405 0.2257080078125 +45406 0.427154541015625 +45407 0.643218994140625 +45408 0.855926513671875 +45409 0.870361328125 +45410 0.870361328125 +45411 0.862762451171875 +45412 0.79669189453125 +45413 0.595794677734375 +45414 0.362152099609375 +45415 0.1270751953125 +45416 -0.086944580078125 +45417 -0.2784423828125 +45418 -0.484832763671875 +45419 -0.729583740234375 +45420 -0.86688232421875 +45421 -0.870391845703125 +45422 -0.86859130859375 +45423 -0.86279296875 +45424 -0.817962646484375 +45425 -0.6116943359375 +45426 -0.3128662109375 +45427 0.039398193359375 +45428 0.422821044921875 +45429 0.805145263671875 +45430 0.870361328125 +45431 0.870361328125 +45432 0.860015869140625 +45433 0.727935791015625 +45434 0.48114013671875 +45435 0.2059326171875 +45436 -0.06103515625 +45437 -0.29913330078125 +45438 -0.516204833984375 +45439 -0.7252197265625 +45440 -0.85980224609375 +45441 -0.870391845703125 +45442 -0.870391845703125 +45443 -0.858062744140625 +45444 -0.673004150390625 +45445 -0.42694091796875 +45446 -0.2100830078125 +45447 -0.0362548828125 +45448 0.10943603515625 +45449 0.23516845703125 +45450 0.373687744140625 +45451 0.517791748046875 +45452 0.602783203125 +45453 0.635711669921875 +45454 0.655181884765625 +45455 0.65948486328125 +45456 0.651275634765625 +45457 0.61846923828125 +45458 0.53753662109375 +45459 0.404144287109375 +45460 0.22186279296875 +45461 0.003997802734375 +45462 -0.22100830078125 +45463 -0.42449951171875 +45464 -0.579833984375 +45465 -0.641876220703125 +45466 -0.6177978515625 +45467 -0.575531005859375 +45468 -0.526336669921875 +45469 -0.42645263671875 +45470 -0.2581787109375 +45471 -0.068695068359375 +45472 0.09222412109375 +45473 0.232147216796875 +45474 0.3509521484375 +45475 0.410064697265625 +45476 0.372955322265625 +45477 0.2554931640625 +45478 0.10711669921875 +45479 -0.052886962890625 +45480 -0.186279296875 +45481 -0.23291015625 +45482 -0.209442138671875 +45483 -0.174163818359375 +45484 -0.126739501953125 +45485 -0.048126220703125 +45486 0.0426025390625 +45487 0.10748291015625 +45488 0.1409912109375 +45489 0.19708251953125 +45490 0.273651123046875 +45491 0.31768798828125 +45492 0.341094970703125 +45493 0.368011474609375 +45494 0.37249755859375 +45495 0.30072021484375 +45496 0.1517333984375 +45497 -0.01470947265625 +45498 -0.1883544921875 +45499 -0.372711181640625 +45500 -0.51397705078125 +45501 -0.57177734375 +45502 -0.53948974609375 +45503 -0.43511962890625 +45504 -0.2962646484375 +45505 -0.161102294921875 +45506 -0.0435791015625 +45507 0.060394287109375 +45508 0.13665771484375 +45509 0.170135498046875 +45510 0.16552734375 +45511 0.15728759765625 +45512 0.150787353515625 +45513 0.12200927734375 +45514 0.080108642578125 +45515 0.05126953125 +45516 0.062896728515625 +45517 0.09271240234375 +45518 0.092987060546875 +45519 0.07855224609375 +45520 0.06427001953125 +45521 0.0347900390625 +45522 -0.01171875 +45523 -0.056060791015625 +45524 -0.055511474609375 +45525 -0.010467529296875 +45526 0.02508544921875 +45527 0.025665283203125 +45528 0.017333984375 +45529 0.00189208984375 +45530 -0.03173828125 +45531 -0.071502685546875 +45532 -0.13543701171875 +45533 -0.219970703125 +45534 -0.300506591796875 +45535 -0.376312255859375 +45536 -0.416107177734375 +45537 -0.371124267578125 +45538 -0.242279052734375 +45539 -0.069732666015625 +45540 0.125640869140625 +45541 0.31268310546875 +45542 0.45501708984375 +45543 0.554779052734375 +45544 0.61065673828125 +45545 0.610931396484375 +45546 0.531463623046875 +45547 0.3883056640625 +45548 0.23468017578125 +45549 0.095245361328125 +45550 -0.00396728515625 +45551 -0.04852294921875 +45552 -0.055145263671875 +45553 -0.0758056640625 +45554 -0.138702392578125 +45555 -0.209197998046875 +45556 -0.289031982421875 +45557 -0.37884521484375 +45558 -0.456329345703125 +45559 -0.51641845703125 +45560 -0.519287109375 +45561 -0.458251953125 +45562 -0.384796142578125 +45563 -0.323699951171875 +45564 -0.269287109375 +45565 -0.1951904296875 +45566 -0.100006103515625 +45567 -0.01055908203125 +45568 0.1033935546875 +45569 0.24908447265625 +45570 0.373199462890625 +45571 0.45806884765625 +45572 0.511474609375 +45573 0.565399169921875 +45574 0.61138916015625 +45575 0.5897216796875 +45576 0.4906005859375 +45577 0.33148193359375 +45578 0.147796630859375 +45579 -0.01873779296875 +45580 -0.140289306640625 +45581 -0.191986083984375 +45582 -0.184295654296875 +45583 -0.161834716796875 +45584 -0.166595458984375 +45585 -0.19390869140625 +45586 -0.22442626953125 +45587 -0.279754638671875 +45588 -0.3389892578125 +45589 -0.3543701171875 +45590 -0.348175048828125 +45591 -0.32598876953125 +45592 -0.2581787109375 +45593 -0.139801025390625 +45594 0.014617919921875 +45595 0.144378662109375 +45596 0.221038818359375 +45597 0.27069091796875 +45598 0.294036865234375 +45599 0.311767578125 +45600 0.339141845703125 +45601 0.360260009765625 +45602 0.360504150390625 +45603 0.308380126953125 +45604 0.18170166015625 +45605 0.0047607421875 +45606 -0.17559814453125 +45607 -0.3143310546875 +45608 -0.36785888671875 +45609 -0.36248779296875 +45610 -0.343536376953125 +45611 -0.3018798828125 +45612 -0.231414794921875 +45613 -0.117645263671875 +45614 0.007049560546875 +45615 0.087982177734375 +45616 0.13946533203125 +45617 0.17425537109375 +45618 0.188201904296875 +45619 0.171234130859375 +45620 0.118438720703125 +45621 0.05706787109375 +45622 -0.010711669921875 +45623 -0.0914306640625 +45624 -0.162322998046875 +45625 -0.194549560546875 +45626 -0.1492919921875 +45627 -0.02166748046875 +45628 0.124053955078125 +45629 0.211151123046875 +45630 0.240447998046875 +45631 0.242218017578125 +45632 0.2257080078125 +45633 0.194366455078125 +45634 0.115509033203125 +45635 0.0128173828125 +45636 -0.053802490234375 +45637 -0.110626220703125 +45638 -0.199493408203125 +45639 -0.29437255859375 +45640 -0.33221435546875 +45641 -0.27972412109375 +45642 -0.185333251953125 +45643 -0.128204345703125 +45644 -0.115692138671875 +45645 -0.116455078125 +45646 -0.105926513671875 +45647 -0.053955078125 +45648 0.048797607421875 +45649 0.157318115234375 +45650 0.212005615234375 +45651 0.218475341796875 +45652 0.23724365234375 +45653 0.30535888671875 +45654 0.38128662109375 +45655 0.404449462890625 +45656 0.3944091796875 +45657 0.3885498046875 +45658 0.362640380859375 +45659 0.27362060546875 +45660 0.11712646484375 +45661 -0.054901123046875 +45662 -0.19085693359375 +45663 -0.28570556640625 +45664 -0.339263916015625 +45665 -0.3775634765625 +45666 -0.445709228515625 +45667 -0.535064697265625 +45668 -0.629058837890625 +45669 -0.697601318359375 +45670 -0.70391845703125 +45671 -0.6424560546875 +45672 -0.491241455078125 +45673 -0.265716552734375 +45674 -0.023712158203125 +45675 0.201751708984375 +45676 0.375823974609375 +45677 0.485076904296875 +45678 0.56884765625 +45679 0.634765625 +45680 0.63763427734375 +45681 0.5660400390625 +45682 0.4720458984375 +45683 0.40692138671875 +45684 0.3778076171875 +45685 0.376953125 +45686 0.371978759765625 +45687 0.313140869140625 +45688 0.184417724609375 +45689 0.011199951171875 +45690 -0.171051025390625 +45691 -0.33740234375 +45692 -0.47198486328125 +45693 -0.560394287109375 +45694 -0.58056640625 +45695 -0.54754638671875 +45696 -0.508575439453125 +45697 -0.459503173828125 +45698 -0.394378662109375 +45699 -0.35260009765625 +45700 -0.31170654296875 +45701 -0.197418212890625 +45702 -0.007965087890625 +45703 0.207489013671875 +45704 0.409210205078125 +45705 0.57208251953125 +45706 0.66595458984375 +45707 0.65875244140625 +45708 0.56744384765625 +45709 0.431396484375 +45710 0.29443359375 +45711 0.182464599609375 +45712 0.06365966796875 +45713 -0.075958251953125 +45714 -0.189422607421875 +45715 -0.271942138671875 +45716 -0.342529296875 +45717 -0.364166259765625 +45718 -0.327239990234375 +45719 -0.2769775390625 +45720 -0.253692626953125 +45721 -0.24365234375 +45722 -0.1983642578125 +45723 -0.116241455078125 +45724 -0.036834716796875 +45725 0.034881591796875 +45726 0.09124755859375 +45727 0.10888671875 +45728 0.125518798828125 +45729 0.15771484375 +45730 0.17828369140625 +45731 0.17108154296875 +45732 0.129974365234375 +45733 0.082427978515625 +45734 0.027679443359375 +45735 -0.065643310546875 +45736 -0.15936279296875 +45737 -0.21307373046875 +45738 -0.234649658203125 +45739 -0.2001953125 +45740 -0.119171142578125 +45741 -0.024749755859375 +45742 0.085784912109375 +45743 0.178131103515625 +45744 0.215576171875 +45745 0.211456298828125 +45746 0.17523193359375 +45747 0.128753662109375 +45748 0.1019287109375 +45749 0.0743408203125 +45750 0.04327392578125 +45751 0.038177490234375 +45752 0.076263427734375 +45753 0.14105224609375 +45754 0.186431884765625 +45755 0.188812255859375 +45756 0.1390380859375 +45757 0.041778564453125 +45758 -0.079437255859375 +45759 -0.219390869140625 +45760 -0.367828369140625 +45761 -0.494873046875 +45762 -0.556243896484375 +45763 -0.508697509765625 +45764 -0.3756103515625 +45765 -0.218902587890625 +45766 -0.063751220703125 +45767 0.091552734375 +45768 0.23602294921875 +45769 0.342987060546875 +45770 0.39520263671875 +45771 0.389373779296875 +45772 0.324249267578125 +45773 0.224090576171875 +45774 0.124267578125 +45775 0.037078857421875 +45776 -0.010101318359375 +45777 -0.019439697265625 +45778 -0.022796630859375 +45779 -0.001556396484375 +45780 0.056304931640625 +45781 0.106719970703125 +45782 0.096893310546875 +45783 0.042694091796875 +45784 -0.018035888671875 +45785 -0.07586669921875 +45786 -0.11944580078125 +45787 -0.15972900390625 +45788 -0.202606201171875 +45789 -0.24859619140625 +45790 -0.30517578125 +45791 -0.36212158203125 +45792 -0.39141845703125 +45793 -0.35528564453125 +45794 -0.249969482421875 +45795 -0.092864990234375 +45796 0.08905029296875 +45797 0.2352294921875 +45798 0.318817138671875 +45799 0.358642578125 +45800 0.347747802734375 +45801 0.28564453125 +45802 0.223175048828125 +45803 0.196746826171875 +45804 0.179840087890625 +45805 0.155548095703125 +45806 0.151214599609375 +45807 0.156951904296875 +45808 0.13177490234375 +45809 0.100799560546875 +45810 0.087127685546875 +45811 0.05487060546875 +45812 -0.009002685546875 +45813 -0.10400390625 +45814 -0.229400634765625 +45815 -0.35552978515625 +45816 -0.441925048828125 +45817 -0.473846435546875 +45818 -0.464813232421875 +45819 -0.419097900390625 +45820 -0.334320068359375 +45821 -0.227935791015625 +45822 -0.12347412109375 +45823 -0.02764892578125 +45824 0.077667236328125 +45825 0.2132568359375 +45826 0.38885498046875 +45827 0.582794189453125 +45828 0.734039306640625 +45829 0.800140380859375 +45830 0.7783203125 +45831 0.6651611328125 +45832 0.45965576171875 +45833 0.199188232421875 +45834 -0.050689697265625 +45835 -0.23297119140625 +45836 -0.33013916015625 +45837 -0.368408203125 +45838 -0.378936767578125 +45839 -0.376983642578125 +45840 -0.37969970703125 +45841 -0.391510009765625 +45842 -0.385345458984375 +45843 -0.3419189453125 +45844 -0.28289794921875 +45845 -0.251617431640625 +45846 -0.266143798828125 +45847 -0.273345947265625 +45848 -0.216796875 +45849 -0.128265380859375 +45850 -0.068145751953125 +45851 -0.0430908203125 +45852 -0.024444580078125 +45853 0.020721435546875 +45854 0.124481201171875 +45855 0.25787353515625 +45856 0.379119873046875 +45857 0.47991943359375 +45858 0.5281982421875 +45859 0.511138916015625 +45860 0.456207275390625 +45861 0.407470703125 +45862 0.383758544921875 +45863 0.35687255859375 +45864 0.31182861328125 +45865 0.250885009765625 +45866 0.1654052734375 +45867 0.035247802734375 +45868 -0.142059326171875 +45869 -0.33563232421875 +45870 -0.5345458984375 +45871 -0.72186279296875 +45872 -0.836669921875 +45873 -0.8326416015625 +45874 -0.7296142578125 +45875 -0.582550048828125 +45876 -0.440093994140625 +45877 -0.324310302734375 +45878 -0.20147705078125 +45879 -0.044647216796875 +45880 0.103973388671875 +45881 0.202392578125 +45882 0.264495849609375 +45883 0.338897705078125 +45884 0.443817138671875 +45885 0.545074462890625 +45886 0.6173095703125 +45887 0.6524658203125 +45888 0.66339111328125 +45889 0.6561279296875 +45890 0.606781005859375 +45891 0.501190185546875 +45892 0.352783203125 +45893 0.176544189453125 +45894 -0.034820556640625 +45895 -0.258209228515625 +45896 -0.44244384765625 +45897 -0.5753173828125 +45898 -0.65203857421875 +45899 -0.641632080078125 +45900 -0.562164306640625 +45901 -0.458038330078125 +45902 -0.350555419921875 +45903 -0.260528564453125 +45904 -0.192108154296875 +45905 -0.141937255859375 +45906 -0.1021728515625 +45907 -0.062896728515625 +45908 -0.011932373046875 +45909 0.062835693359375 +45910 0.148712158203125 +45911 0.241729736328125 +45912 0.34912109375 +45913 0.457305908203125 +45914 0.54388427734375 +45915 0.5728759765625 +45916 0.506591796875 +45917 0.351226806640625 +45918 0.146514892578125 +45919 -0.05523681640625 +45920 -0.21624755859375 +45921 -0.334930419921875 +45922 -0.402984619140625 +45923 -0.4412841796875 +45924 -0.49578857421875 +45925 -0.5601806640625 +45926 -0.600738525390625 +45927 -0.584228515625 +45928 -0.47930908203125 +45929 -0.27935791015625 +45930 -0.0089111328125 +45931 0.268798828125 +45932 0.482818603515625 +45933 0.60369873046875 +45934 0.650421142578125 +45935 0.66400146484375 +45936 0.6414794921875 +45937 0.572540283203125 +45938 0.498138427734375 +45939 0.439453125 +45940 0.375518798828125 +45941 0.274505615234375 +45942 0.1087646484375 +45943 -0.099395751953125 +45944 -0.3182373046875 +45945 -0.5489501953125 +45946 -0.7738037109375 +45947 -0.86383056640625 +45948 -0.870391845703125 +45949 -0.86895751953125 +45950 -0.861053466796875 +45951 -0.765869140625 +45952 -0.5301513671875 +45953 -0.214691162109375 +45954 0.137359619140625 +45955 0.474822998046875 +45956 0.76239013671875 +45957 0.867462158203125 +45958 0.870361328125 +45959 0.86480712890625 +45960 0.831817626953125 +45961 0.677581787109375 +45962 0.495880126953125 +45963 0.30767822265625 +45964 0.116180419921875 +45965 -0.110748291015625 +45966 -0.381805419921875 +45967 -0.6572265625 +45968 -0.857421875 +45969 -0.870391845703125 +45970 -0.870391845703125 +45971 -0.86444091796875 +45972 -0.85723876953125 +45973 -0.790008544921875 +45974 -0.62847900390625 +45975 -0.3956298828125 +45976 -0.126708984375 +45977 0.150115966796875 +45978 0.424041748046875 +45979 0.670623779296875 +45980 0.854522705078125 +45981 0.866485595703125 +45982 0.86920166015625 +45983 0.8653564453125 +45984 0.857147216796875 +45985 0.766845703125 +45986 0.628509521484375 +45987 0.462127685546875 +45988 0.297210693359375 +45989 0.14862060546875 +45990 -0.00537109375 +45991 -0.15753173828125 +45992 -0.31304931640625 +45993 -0.48876953125 +45994 -0.6416015625 +45995 -0.751373291015625 +45996 -0.84619140625 +45997 -0.861297607421875 +45998 -0.863250732421875 +45999 -0.856597900390625 +46000 -0.7498779296875 +46001 -0.624542236328125 +46002 -0.47808837890625 +46003 -0.253387451171875 +46004 0.003692626953125 +46005 0.2257080078125 +46006 0.427154541015625 +46007 0.643218994140625 +46008 0.855926513671875 +46009 0.870361328125 +46010 0.870361328125 +46011 0.862762451171875 +46012 0.79669189453125 +46013 0.595794677734375 +46014 0.362152099609375 +46015 0.1270751953125 +46016 -0.086944580078125 +46017 -0.2784423828125 +46018 -0.484832763671875 +46019 -0.729583740234375 +46020 -0.86688232421875 +46021 -0.870391845703125 +46022 -0.86859130859375 +46023 -0.86279296875 +46024 -0.817962646484375 +46025 -0.6116943359375 +46026 -0.3128662109375 +46027 0.039398193359375 +46028 0.422821044921875 +46029 0.805145263671875 +46030 0.870361328125 +46031 0.870361328125 +46032 0.860015869140625 +46033 0.727935791015625 +46034 0.48114013671875 +46035 0.2059326171875 +46036 -0.06103515625 +46037 -0.29913330078125 +46038 -0.516204833984375 +46039 -0.7252197265625 +46040 -0.85980224609375 +46041 -0.870391845703125 +46042 -0.870391845703125 +46043 -0.858062744140625 +46044 -0.673004150390625 +46045 -0.42694091796875 +46046 -0.2100830078125 +46047 -0.0362548828125 +46048 0.10943603515625 +46049 0.23516845703125 +46050 0.373687744140625 +46051 0.517791748046875 +46052 0.602783203125 +46053 0.635711669921875 +46054 0.655181884765625 +46055 0.65948486328125 +46056 0.651275634765625 +46057 0.61846923828125 +46058 0.53753662109375 +46059 0.404144287109375 +46060 0.22186279296875 +46061 0.003997802734375 +46062 -0.22100830078125 +46063 -0.42449951171875 +46064 -0.579833984375 +46065 -0.641876220703125 +46066 -0.6177978515625 +46067 -0.575531005859375 +46068 -0.526336669921875 +46069 -0.42645263671875 +46070 -0.2581787109375 +46071 -0.068695068359375 +46072 0.09222412109375 +46073 0.232147216796875 +46074 0.3509521484375 +46075 0.410064697265625 +46076 0.372955322265625 +46077 0.2554931640625 +46078 0.10711669921875 +46079 -0.052886962890625 +46080 -0.186279296875 +46081 -0.23291015625 +46082 -0.209442138671875 +46083 -0.174163818359375 +46084 -0.126739501953125 +46085 -0.048126220703125 +46086 0.0426025390625 +46087 0.10748291015625 +46088 0.1409912109375 +46089 0.19708251953125 +46090 0.273651123046875 +46091 0.31768798828125 +46092 0.341094970703125 +46093 0.368011474609375 +46094 0.37249755859375 +46095 0.30072021484375 +46096 0.1517333984375 +46097 -0.01470947265625 +46098 -0.1883544921875 +46099 -0.372711181640625 +46100 -0.51397705078125 +46101 -0.57177734375 +46102 -0.53948974609375 +46103 -0.43511962890625 +46104 -0.2962646484375 +46105 -0.161102294921875 +46106 -0.0435791015625 +46107 0.060394287109375 +46108 0.13665771484375 +46109 0.170135498046875 +46110 0.16552734375 +46111 0.15728759765625 +46112 0.150787353515625 +46113 0.12200927734375 +46114 0.080108642578125 +46115 0.05126953125 +46116 0.062896728515625 +46117 0.09271240234375 +46118 0.092987060546875 +46119 0.07855224609375 +46120 0.06427001953125 +46121 0.0347900390625 +46122 -0.01171875 +46123 -0.056060791015625 +46124 -0.055511474609375 +46125 -0.010467529296875 +46126 0.02508544921875 +46127 0.025665283203125 +46128 0.017333984375 +46129 0.00189208984375 +46130 -0.03173828125 +46131 -0.071502685546875 +46132 -0.13543701171875 +46133 -0.219970703125 +46134 -0.300506591796875 +46135 -0.376312255859375 +46136 -0.416107177734375 +46137 -0.371124267578125 +46138 -0.242279052734375 +46139 -0.069732666015625 +46140 0.125640869140625 +46141 0.31268310546875 +46142 0.45501708984375 +46143 0.554779052734375 +46144 0.61065673828125 +46145 0.610931396484375 +46146 0.531463623046875 +46147 0.3883056640625 +46148 0.23468017578125 +46149 0.095245361328125 +46150 -0.00396728515625 +46151 -0.04852294921875 +46152 -0.055145263671875 +46153 -0.0758056640625 +46154 -0.138702392578125 +46155 -0.209197998046875 +46156 -0.289031982421875 +46157 -0.37884521484375 +46158 -0.456329345703125 +46159 -0.51641845703125 +46160 -0.519287109375 +46161 -0.458251953125 +46162 -0.384796142578125 +46163 -0.323699951171875 +46164 -0.269287109375 +46165 -0.1951904296875 +46166 -0.100006103515625 +46167 -0.01055908203125 +46168 0.1033935546875 +46169 0.24908447265625 +46170 0.373199462890625 +46171 0.45806884765625 +46172 0.511474609375 +46173 0.565399169921875 +46174 0.61138916015625 +46175 0.5897216796875 +46176 0.4906005859375 +46177 0.33148193359375 +46178 0.147796630859375 +46179 -0.01873779296875 +46180 -0.140289306640625 +46181 -0.191986083984375 +46182 -0.184295654296875 +46183 -0.161834716796875 +46184 -0.166595458984375 +46185 -0.19390869140625 +46186 -0.22442626953125 +46187 -0.279754638671875 +46188 -0.3389892578125 +46189 -0.3543701171875 +46190 -0.348175048828125 +46191 -0.32598876953125 +46192 -0.2581787109375 +46193 -0.139801025390625 +46194 0.014617919921875 +46195 0.144378662109375 +46196 0.221038818359375 +46197 0.27069091796875 +46198 0.294036865234375 +46199 0.311767578125 +46200 0.339141845703125 +46201 0.360260009765625 +46202 0.360504150390625 +46203 0.308380126953125 +46204 0.18170166015625 +46205 0.0047607421875 +46206 -0.17559814453125 +46207 -0.3143310546875 +46208 -0.36785888671875 +46209 -0.36248779296875 +46210 -0.343536376953125 +46211 -0.3018798828125 +46212 -0.231414794921875 +46213 -0.117645263671875 +46214 0.007049560546875 +46215 0.087982177734375 +46216 0.13946533203125 +46217 0.17425537109375 +46218 0.188201904296875 +46219 0.171234130859375 +46220 0.118438720703125 +46221 0.05706787109375 +46222 -0.010711669921875 +46223 -0.0914306640625 +46224 -0.162322998046875 +46225 -0.194549560546875 +46226 -0.1492919921875 +46227 -0.02166748046875 +46228 0.124053955078125 +46229 0.211151123046875 +46230 0.240447998046875 +46231 0.242218017578125 +46232 0.2257080078125 +46233 0.194366455078125 +46234 0.115509033203125 +46235 0.0128173828125 +46236 -0.053802490234375 +46237 -0.110626220703125 +46238 -0.199493408203125 +46239 -0.29437255859375 +46240 -0.33221435546875 +46241 -0.27972412109375 +46242 -0.185333251953125 +46243 -0.128204345703125 +46244 -0.115692138671875 +46245 -0.116455078125 +46246 -0.105926513671875 +46247 -0.053955078125 +46248 0.048797607421875 +46249 0.157318115234375 +46250 0.212005615234375 +46251 0.218475341796875 +46252 0.23724365234375 +46253 0.30535888671875 +46254 0.38128662109375 +46255 0.404449462890625 +46256 0.3944091796875 +46257 0.3885498046875 +46258 0.362640380859375 +46259 0.27362060546875 +46260 0.11712646484375 +46261 -0.054901123046875 +46262 -0.19085693359375 +46263 -0.28570556640625 +46264 -0.339263916015625 +46265 -0.3775634765625 +46266 -0.445709228515625 +46267 -0.535064697265625 +46268 -0.629058837890625 +46269 -0.697601318359375 +46270 -0.70391845703125 +46271 -0.6424560546875 +46272 -0.491241455078125 +46273 -0.265716552734375 +46274 -0.023712158203125 +46275 0.201751708984375 +46276 0.375823974609375 +46277 0.485076904296875 +46278 0.56884765625 +46279 0.634765625 +46280 0.63763427734375 +46281 0.5660400390625 +46282 0.4720458984375 +46283 0.40692138671875 +46284 0.3778076171875 +46285 0.376953125 +46286 0.371978759765625 +46287 0.313140869140625 +46288 0.184417724609375 +46289 0.011199951171875 +46290 -0.171051025390625 +46291 -0.33740234375 +46292 -0.47198486328125 +46293 -0.560394287109375 +46294 -0.58056640625 +46295 -0.54754638671875 +46296 -0.508575439453125 +46297 -0.459503173828125 +46298 -0.394378662109375 +46299 -0.35260009765625 +46300 -0.31170654296875 +46301 -0.197418212890625 +46302 -0.007965087890625 +46303 0.207489013671875 +46304 0.409210205078125 +46305 0.57208251953125 +46306 0.66595458984375 +46307 0.65875244140625 +46308 0.56744384765625 +46309 0.431396484375 +46310 0.29443359375 +46311 0.182464599609375 +46312 0.06365966796875 +46313 -0.075958251953125 +46314 -0.189422607421875 +46315 -0.271942138671875 +46316 -0.342529296875 +46317 -0.364166259765625 +46318 -0.327239990234375 +46319 -0.2769775390625 +46320 -0.253692626953125 +46321 -0.24365234375 +46322 -0.1983642578125 +46323 -0.116241455078125 +46324 -0.036834716796875 +46325 0.034881591796875 +46326 0.09124755859375 +46327 0.10888671875 +46328 0.125518798828125 +46329 0.15771484375 +46330 0.17828369140625 +46331 0.17108154296875 +46332 0.129974365234375 +46333 0.082427978515625 +46334 0.027679443359375 +46335 -0.065643310546875 +46336 -0.15936279296875 +46337 -0.21307373046875 +46338 -0.234649658203125 +46339 -0.2001953125 +46340 -0.119171142578125 +46341 -0.024749755859375 +46342 0.085784912109375 +46343 0.178131103515625 +46344 0.215576171875 +46345 0.211456298828125 +46346 0.17523193359375 +46347 0.128753662109375 +46348 0.1019287109375 +46349 0.0743408203125 +46350 0.04327392578125 +46351 0.038177490234375 +46352 0.076263427734375 +46353 0.14105224609375 +46354 0.186431884765625 +46355 0.188812255859375 +46356 0.1390380859375 +46357 0.041778564453125 +46358 -0.079437255859375 +46359 -0.219390869140625 +46360 -0.367828369140625 +46361 -0.494873046875 +46362 -0.556243896484375 +46363 -0.508697509765625 +46364 -0.3756103515625 +46365 -0.218902587890625 +46366 -0.063751220703125 +46367 0.091552734375 +46368 0.23602294921875 +46369 0.342987060546875 +46370 0.39520263671875 +46371 0.389373779296875 +46372 0.324249267578125 +46373 0.224090576171875 +46374 0.124267578125 +46375 0.037078857421875 +46376 -0.010101318359375 +46377 -0.019439697265625 +46378 -0.022796630859375 +46379 -0.001556396484375 +46380 0.056304931640625 +46381 0.106719970703125 +46382 0.096893310546875 +46383 0.042694091796875 +46384 -0.018035888671875 +46385 -0.07586669921875 +46386 -0.11944580078125 +46387 -0.15972900390625 +46388 -0.202606201171875 +46389 -0.24859619140625 +46390 -0.30517578125 +46391 -0.36212158203125 +46392 -0.39141845703125 +46393 -0.35528564453125 +46394 -0.249969482421875 +46395 -0.092864990234375 +46396 0.08905029296875 +46397 0.2352294921875 +46398 0.318817138671875 +46399 0.358642578125 +46400 0.347747802734375 +46401 0.28564453125 +46402 0.223175048828125 +46403 0.196746826171875 +46404 0.179840087890625 +46405 0.155548095703125 +46406 0.151214599609375 +46407 0.156951904296875 +46408 0.13177490234375 +46409 0.100799560546875 +46410 0.087127685546875 +46411 0.05487060546875 +46412 -0.009002685546875 +46413 -0.10400390625 +46414 -0.229400634765625 +46415 -0.35552978515625 +46416 -0.441925048828125 +46417 -0.473846435546875 +46418 -0.464813232421875 +46419 -0.419097900390625 +46420 -0.334320068359375 +46421 -0.227935791015625 +46422 -0.12347412109375 +46423 -0.02764892578125 +46424 0.077667236328125 +46425 0.2132568359375 +46426 0.38885498046875 +46427 0.582794189453125 +46428 0.734039306640625 +46429 0.800140380859375 +46430 0.7783203125 +46431 0.6651611328125 +46432 0.45965576171875 +46433 0.199188232421875 +46434 -0.050689697265625 +46435 -0.23297119140625 +46436 -0.33013916015625 +46437 -0.368408203125 +46438 -0.378936767578125 +46439 -0.376983642578125 +46440 -0.37969970703125 +46441 -0.391510009765625 +46442 -0.385345458984375 +46443 -0.3419189453125 +46444 -0.28289794921875 +46445 -0.251617431640625 +46446 -0.266143798828125 +46447 -0.273345947265625 +46448 -0.216796875 +46449 -0.128265380859375 +46450 -0.068145751953125 +46451 -0.0430908203125 +46452 -0.024444580078125 +46453 0.020721435546875 +46454 0.124481201171875 +46455 0.25787353515625 +46456 0.379119873046875 +46457 0.47991943359375 +46458 0.5281982421875 +46459 0.511138916015625 +46460 0.456207275390625 +46461 0.407470703125 +46462 0.383758544921875 +46463 0.35687255859375 +46464 0.31182861328125 +46465 0.250885009765625 +46466 0.1654052734375 +46467 0.035247802734375 +46468 -0.142059326171875 +46469 -0.33563232421875 +46470 -0.5345458984375 +46471 -0.72186279296875 +46472 -0.836669921875 +46473 -0.8326416015625 +46474 -0.7296142578125 +46475 -0.582550048828125 +46476 -0.440093994140625 +46477 -0.324310302734375 +46478 -0.20147705078125 +46479 -0.044647216796875 +46480 0.103973388671875 +46481 0.202392578125 +46482 0.264495849609375 +46483 0.338897705078125 +46484 0.443817138671875 +46485 0.545074462890625 +46486 0.6173095703125 +46487 0.6524658203125 +46488 0.66339111328125 +46489 0.6561279296875 +46490 0.606781005859375 +46491 0.501190185546875 +46492 0.352783203125 +46493 0.176544189453125 +46494 -0.034820556640625 +46495 -0.258209228515625 +46496 -0.44244384765625 +46497 -0.5753173828125 +46498 -0.65203857421875 +46499 -0.641632080078125 +46500 -0.562164306640625 +46501 -0.458038330078125 +46502 -0.350555419921875 +46503 -0.260528564453125 +46504 -0.192108154296875 +46505 -0.141937255859375 +46506 -0.1021728515625 +46507 -0.062896728515625 +46508 -0.011932373046875 +46509 0.062835693359375 +46510 0.148712158203125 +46511 0.241729736328125 +46512 0.34912109375 +46513 0.457305908203125 +46514 0.54388427734375 +46515 0.5728759765625 +46516 0.506591796875 +46517 0.351226806640625 +46518 0.146514892578125 +46519 -0.05523681640625 +46520 -0.21624755859375 +46521 -0.334930419921875 +46522 -0.402984619140625 +46523 -0.4412841796875 +46524 -0.49578857421875 +46525 -0.5601806640625 +46526 -0.600738525390625 +46527 -0.584228515625 +46528 -0.47930908203125 +46529 -0.27935791015625 +46530 -0.0089111328125 +46531 0.268798828125 +46532 0.482818603515625 +46533 0.60369873046875 +46534 0.650421142578125 +46535 0.66400146484375 +46536 0.6414794921875 +46537 0.572540283203125 +46538 0.498138427734375 +46539 0.439453125 +46540 0.375518798828125 +46541 0.274505615234375 +46542 0.1087646484375 +46543 -0.099395751953125 +46544 -0.3182373046875 +46545 -0.5489501953125 +46546 -0.7738037109375 +46547 -0.86383056640625 +46548 -0.870391845703125 +46549 -0.86895751953125 +46550 -0.861053466796875 +46551 -0.765869140625 +46552 -0.5301513671875 +46553 -0.214691162109375 +46554 0.137359619140625 +46555 0.474822998046875 +46556 0.76239013671875 +46557 0.867462158203125 +46558 0.870361328125 +46559 0.86480712890625 +46560 0.831817626953125 +46561 0.677581787109375 +46562 0.495880126953125 +46563 0.30767822265625 +46564 0.116180419921875 +46565 -0.110748291015625 +46566 -0.381805419921875 +46567 -0.6572265625 +46568 -0.857421875 +46569 -0.870391845703125 +46570 -0.870391845703125 +46571 -0.86444091796875 +46572 -0.85723876953125 +46573 -0.790008544921875 +46574 -0.62847900390625 +46575 -0.3956298828125 +46576 -0.126708984375 +46577 0.150115966796875 +46578 0.424041748046875 +46579 0.670623779296875 +46580 0.854522705078125 +46581 0.866485595703125 +46582 0.86920166015625 +46583 0.8653564453125 +46584 0.857147216796875 +46585 0.766845703125 +46586 0.628509521484375 +46587 0.462127685546875 +46588 0.297210693359375 +46589 0.14862060546875 +46590 -0.00537109375 +46591 -0.15753173828125 +46592 -0.31304931640625 +46593 -0.48876953125 +46594 -0.6416015625 +46595 -0.751373291015625 +46596 -0.84619140625 +46597 -0.861297607421875 +46598 -0.863250732421875 +46599 -0.856597900390625 +46600 -0.7498779296875 +46601 -0.624542236328125 +46602 -0.47808837890625 +46603 -0.253387451171875 +46604 0.003692626953125 +46605 0.2257080078125 +46606 0.427154541015625 +46607 0.643218994140625 +46608 0.855926513671875 +46609 0.870361328125 +46610 0.870361328125 +46611 0.862762451171875 +46612 0.79669189453125 +46613 0.595794677734375 +46614 0.362152099609375 +46615 0.1270751953125 +46616 -0.086944580078125 +46617 -0.2784423828125 +46618 -0.484832763671875 +46619 -0.729583740234375 +46620 -0.86688232421875 +46621 -0.870391845703125 +46622 -0.86859130859375 +46623 -0.86279296875 +46624 -0.817962646484375 +46625 -0.6116943359375 +46626 -0.3128662109375 +46627 0.039398193359375 +46628 0.422821044921875 +46629 0.805145263671875 +46630 0.870361328125 +46631 0.870361328125 +46632 0.860015869140625 +46633 0.727935791015625 +46634 0.48114013671875 +46635 0.2059326171875 +46636 -0.06103515625 +46637 -0.29913330078125 +46638 -0.516204833984375 +46639 -0.7252197265625 +46640 -0.85980224609375 +46641 -0.870391845703125 +46642 -0.870391845703125 +46643 -0.858062744140625 +46644 -0.673004150390625 +46645 -0.42694091796875 +46646 -0.2100830078125 +46647 -0.0362548828125 +46648 0.10943603515625 +46649 0.23516845703125 +46650 0.373687744140625 +46651 0.517791748046875 +46652 0.602783203125 +46653 0.635711669921875 +46654 0.655181884765625 +46655 0.65948486328125 +46656 0.651275634765625 +46657 0.61846923828125 +46658 0.53753662109375 +46659 0.404144287109375 +46660 0.22186279296875 +46661 0.003997802734375 +46662 -0.22100830078125 +46663 -0.42449951171875 +46664 -0.579833984375 +46665 -0.641876220703125 +46666 -0.6177978515625 +46667 -0.575531005859375 +46668 -0.526336669921875 +46669 -0.42645263671875 +46670 -0.2581787109375 +46671 -0.068695068359375 +46672 0.09222412109375 +46673 0.232147216796875 +46674 0.3509521484375 +46675 0.410064697265625 +46676 0.372955322265625 +46677 0.2554931640625 +46678 0.10711669921875 +46679 -0.052886962890625 +46680 -0.186279296875 +46681 -0.23291015625 +46682 -0.209442138671875 +46683 -0.174163818359375 +46684 -0.126739501953125 +46685 -0.048126220703125 +46686 0.0426025390625 +46687 0.10748291015625 +46688 0.1409912109375 +46689 0.19708251953125 +46690 0.273651123046875 +46691 0.31768798828125 +46692 0.341094970703125 +46693 0.368011474609375 +46694 0.37249755859375 +46695 0.30072021484375 +46696 0.1517333984375 +46697 -0.01470947265625 +46698 -0.1883544921875 +46699 -0.372711181640625 +46700 -0.51397705078125 +46701 -0.57177734375 +46702 -0.53948974609375 +46703 -0.43511962890625 +46704 -0.2962646484375 +46705 -0.161102294921875 +46706 -0.0435791015625 +46707 0.060394287109375 +46708 0.13665771484375 +46709 0.170135498046875 +46710 0.16552734375 +46711 0.15728759765625 +46712 0.150787353515625 +46713 0.12200927734375 +46714 0.080108642578125 +46715 0.05126953125 +46716 0.062896728515625 +46717 0.09271240234375 +46718 0.092987060546875 +46719 0.07855224609375 +46720 0.06427001953125 +46721 0.0347900390625 +46722 -0.01171875 +46723 -0.056060791015625 +46724 -0.055511474609375 +46725 -0.010467529296875 +46726 0.02508544921875 +46727 0.025665283203125 +46728 0.017333984375 +46729 0.00189208984375 +46730 -0.03173828125 +46731 -0.071502685546875 +46732 -0.13543701171875 +46733 -0.219970703125 +46734 -0.300506591796875 +46735 -0.376312255859375 +46736 -0.416107177734375 +46737 -0.371124267578125 +46738 -0.242279052734375 +46739 -0.069732666015625 +46740 0.125640869140625 +46741 0.31268310546875 +46742 0.45501708984375 +46743 0.554779052734375 +46744 0.61065673828125 +46745 0.610931396484375 +46746 0.531463623046875 +46747 0.3883056640625 +46748 0.23468017578125 +46749 0.095245361328125 +46750 -0.00396728515625 +46751 -0.04852294921875 +46752 -0.055145263671875 +46753 -0.0758056640625 +46754 -0.138702392578125 +46755 -0.209197998046875 +46756 -0.289031982421875 +46757 -0.37884521484375 +46758 -0.456329345703125 +46759 -0.51641845703125 +46760 -0.519287109375 +46761 -0.458251953125 +46762 -0.384796142578125 +46763 -0.323699951171875 +46764 -0.269287109375 +46765 -0.1951904296875 +46766 -0.100006103515625 +46767 -0.01055908203125 +46768 0.1033935546875 +46769 0.24908447265625 +46770 0.373199462890625 +46771 0.45806884765625 +46772 0.511474609375 +46773 0.565399169921875 +46774 0.61138916015625 +46775 0.5897216796875 +46776 0.4906005859375 +46777 0.33148193359375 +46778 0.147796630859375 +46779 -0.01873779296875 +46780 -0.140289306640625 +46781 -0.191986083984375 +46782 -0.184295654296875 +46783 -0.161834716796875 +46784 -0.166595458984375 +46785 -0.19390869140625 +46786 -0.22442626953125 +46787 -0.279754638671875 +46788 -0.3389892578125 +46789 -0.3543701171875 +46790 -0.348175048828125 +46791 -0.32598876953125 +46792 -0.2581787109375 +46793 -0.139801025390625 +46794 0.014617919921875 +46795 0.144378662109375 +46796 0.221038818359375 +46797 0.27069091796875 +46798 0.294036865234375 +46799 0.311767578125 +46800 0.339141845703125 +46801 0.360260009765625 +46802 0.360504150390625 +46803 0.308380126953125 +46804 0.18170166015625 +46805 0.0047607421875 +46806 -0.17559814453125 +46807 -0.3143310546875 +46808 -0.36785888671875 +46809 -0.36248779296875 +46810 -0.343536376953125 +46811 -0.3018798828125 +46812 -0.231414794921875 +46813 -0.117645263671875 +46814 0.007049560546875 +46815 0.087982177734375 +46816 0.13946533203125 +46817 0.17425537109375 +46818 0.188201904296875 +46819 0.171234130859375 +46820 0.118438720703125 +46821 0.05706787109375 +46822 -0.010711669921875 +46823 -0.0914306640625 +46824 -0.162322998046875 +46825 -0.194549560546875 +46826 -0.1492919921875 +46827 -0.02166748046875 +46828 0.124053955078125 +46829 0.211151123046875 +46830 0.240447998046875 +46831 0.242218017578125 +46832 0.2257080078125 +46833 0.194366455078125 +46834 0.115509033203125 +46835 0.0128173828125 +46836 -0.053802490234375 +46837 -0.110626220703125 +46838 -0.199493408203125 +46839 -0.29437255859375 +46840 -0.33221435546875 +46841 -0.27972412109375 +46842 -0.185333251953125 +46843 -0.128204345703125 +46844 -0.115692138671875 +46845 -0.116455078125 +46846 -0.105926513671875 +46847 -0.053955078125 +46848 0.048797607421875 +46849 0.157318115234375 +46850 0.212005615234375 +46851 0.218475341796875 +46852 0.23724365234375 +46853 0.30535888671875 +46854 0.38128662109375 +46855 0.404449462890625 +46856 0.3944091796875 +46857 0.3885498046875 +46858 0.362640380859375 +46859 0.27362060546875 +46860 0.11712646484375 +46861 -0.054901123046875 +46862 -0.19085693359375 +46863 -0.28570556640625 +46864 -0.339263916015625 +46865 -0.3775634765625 +46866 -0.445709228515625 +46867 -0.535064697265625 +46868 -0.629058837890625 +46869 -0.697601318359375 +46870 -0.70391845703125 +46871 -0.6424560546875 +46872 -0.491241455078125 +46873 -0.265716552734375 +46874 -0.023712158203125 +46875 0.201751708984375 +46876 0.375823974609375 +46877 0.485076904296875 +46878 0.56884765625 +46879 0.634765625 +46880 0.63763427734375 +46881 0.5660400390625 +46882 0.4720458984375 +46883 0.40692138671875 +46884 0.3778076171875 +46885 0.376953125 +46886 0.371978759765625 +46887 0.313140869140625 +46888 0.184417724609375 +46889 0.011199951171875 +46890 -0.171051025390625 +46891 -0.33740234375 +46892 -0.47198486328125 +46893 -0.560394287109375 +46894 -0.58056640625 +46895 -0.54754638671875 +46896 -0.508575439453125 +46897 -0.459503173828125 +46898 -0.394378662109375 +46899 -0.35260009765625 +46900 -0.31170654296875 +46901 -0.197418212890625 +46902 -0.007965087890625 +46903 0.207489013671875 +46904 0.409210205078125 +46905 0.57208251953125 +46906 0.66595458984375 +46907 0.65875244140625 +46908 0.56744384765625 +46909 0.431396484375 +46910 0.29443359375 +46911 0.182464599609375 +46912 0.06365966796875 +46913 -0.075958251953125 +46914 -0.189422607421875 +46915 -0.271942138671875 +46916 -0.342529296875 +46917 -0.364166259765625 +46918 -0.327239990234375 +46919 -0.2769775390625 +46920 -0.253692626953125 +46921 -0.24365234375 +46922 -0.1983642578125 +46923 -0.116241455078125 +46924 -0.036834716796875 +46925 0.034881591796875 +46926 0.09124755859375 +46927 0.10888671875 +46928 0.125518798828125 +46929 0.15771484375 +46930 0.17828369140625 +46931 0.17108154296875 +46932 0.129974365234375 +46933 0.082427978515625 +46934 0.027679443359375 +46935 -0.065643310546875 +46936 -0.15936279296875 +46937 -0.21307373046875 +46938 -0.234649658203125 +46939 -0.2001953125 +46940 -0.119171142578125 +46941 -0.024749755859375 +46942 0.085784912109375 +46943 0.178131103515625 +46944 0.215576171875 +46945 0.211456298828125 +46946 0.17523193359375 +46947 0.128753662109375 +46948 0.1019287109375 +46949 0.0743408203125 +46950 0.04327392578125 +46951 0.038177490234375 +46952 0.076263427734375 +46953 0.14105224609375 +46954 0.186431884765625 +46955 0.188812255859375 +46956 0.1390380859375 +46957 0.041778564453125 +46958 -0.079437255859375 +46959 -0.219390869140625 +46960 -0.367828369140625 +46961 -0.494873046875 +46962 -0.556243896484375 +46963 -0.508697509765625 +46964 -0.3756103515625 +46965 -0.218902587890625 +46966 -0.063751220703125 +46967 0.091552734375 +46968 0.23602294921875 +46969 0.342987060546875 +46970 0.39520263671875 +46971 0.389373779296875 +46972 0.324249267578125 +46973 0.224090576171875 +46974 0.124267578125 +46975 0.037078857421875 +46976 -0.010101318359375 +46977 -0.019439697265625 +46978 -0.022796630859375 +46979 -0.001556396484375 +46980 0.056304931640625 +46981 0.106719970703125 +46982 0.096893310546875 +46983 0.042694091796875 +46984 -0.018035888671875 +46985 -0.07586669921875 +46986 -0.11944580078125 +46987 -0.15972900390625 +46988 -0.202606201171875 +46989 -0.24859619140625 +46990 -0.30517578125 +46991 -0.36212158203125 +46992 -0.39141845703125 +46993 -0.35528564453125 +46994 -0.249969482421875 +46995 -0.092864990234375 +46996 0.08905029296875 +46997 0.2352294921875 +46998 0.318817138671875 +46999 0.358642578125 +47000 0.347747802734375 +47001 0.28564453125 +47002 0.223175048828125 +47003 0.196746826171875 +47004 0.179840087890625 +47005 0.155548095703125 +47006 0.151214599609375 +47007 0.156951904296875 +47008 0.13177490234375 +47009 0.100799560546875 +47010 0.087127685546875 +47011 0.05487060546875 +47012 -0.009002685546875 +47013 -0.10400390625 +47014 -0.229400634765625 +47015 -0.35552978515625 +47016 -0.441925048828125 +47017 -0.473846435546875 +47018 -0.464813232421875 +47019 -0.419097900390625 +47020 -0.334320068359375 +47021 -0.227935791015625 +47022 -0.12347412109375 +47023 -0.02764892578125 +47024 0.077667236328125 +47025 0.2132568359375 +47026 0.38885498046875 +47027 0.582794189453125 +47028 0.734039306640625 +47029 0.800140380859375 +47030 0.7783203125 +47031 0.6651611328125 +47032 0.45965576171875 +47033 0.199188232421875 +47034 -0.050689697265625 +47035 -0.23297119140625 +47036 -0.33013916015625 +47037 -0.368408203125 +47038 -0.378936767578125 +47039 -0.376983642578125 +47040 -0.37969970703125 +47041 -0.391510009765625 +47042 -0.385345458984375 +47043 -0.3419189453125 +47044 -0.28289794921875 +47045 -0.251617431640625 +47046 -0.266143798828125 +47047 -0.273345947265625 +47048 -0.216796875 +47049 -0.128265380859375 +47050 -0.068145751953125 +47051 -0.0430908203125 +47052 -0.024444580078125 +47053 0.020721435546875 +47054 0.124481201171875 +47055 0.25787353515625 +47056 0.379119873046875 +47057 0.47991943359375 +47058 0.5281982421875 +47059 0.511138916015625 +47060 0.456207275390625 +47061 0.407470703125 +47062 0.383758544921875 +47063 0.35687255859375 +47064 0.31182861328125 +47065 0.250885009765625 +47066 0.1654052734375 +47067 0.035247802734375 +47068 -0.142059326171875 +47069 -0.33563232421875 +47070 -0.5345458984375 +47071 -0.72186279296875 +47072 -0.836669921875 +47073 -0.8326416015625 +47074 -0.7296142578125 +47075 -0.582550048828125 +47076 -0.440093994140625 +47077 -0.324310302734375 +47078 -0.20147705078125 +47079 -0.044647216796875 +47080 0.103973388671875 +47081 0.202392578125 +47082 0.264495849609375 +47083 0.338897705078125 +47084 0.443817138671875 +47085 0.545074462890625 +47086 0.6173095703125 +47087 0.6524658203125 +47088 0.66339111328125 +47089 0.6561279296875 +47090 0.606781005859375 +47091 0.501190185546875 +47092 0.352783203125 +47093 0.176544189453125 +47094 -0.034820556640625 +47095 -0.258209228515625 +47096 -0.44244384765625 +47097 -0.5753173828125 +47098 -0.65203857421875 +47099 -0.641632080078125 +47100 -0.562164306640625 +47101 -0.458038330078125 +47102 -0.350555419921875 +47103 -0.260528564453125 +47104 -0.192108154296875 +47105 -0.141937255859375 +47106 -0.1021728515625 +47107 -0.062896728515625 +47108 -0.011932373046875 +47109 0.062835693359375 +47110 0.148712158203125 +47111 0.241729736328125 +47112 0.34912109375 +47113 0.457305908203125 +47114 0.54388427734375 +47115 0.5728759765625 +47116 0.506591796875 +47117 0.351226806640625 +47118 0.146514892578125 +47119 -0.05523681640625 +47120 -0.21624755859375 +47121 -0.334930419921875 +47122 -0.402984619140625 +47123 -0.4412841796875 +47124 -0.49578857421875 +47125 -0.5601806640625 +47126 -0.600738525390625 +47127 -0.584228515625 +47128 -0.47930908203125 +47129 -0.27935791015625 +47130 -0.0089111328125 +47131 0.268798828125 +47132 0.482818603515625 +47133 0.60369873046875 +47134 0.650421142578125 +47135 0.66400146484375 +47136 0.6414794921875 +47137 0.572540283203125 +47138 0.498138427734375 +47139 0.439453125 +47140 0.375518798828125 +47141 0.274505615234375 +47142 0.1087646484375 +47143 -0.099395751953125 +47144 -0.3182373046875 +47145 -0.5489501953125 +47146 -0.7738037109375 +47147 -0.86383056640625 +47148 -0.870391845703125 +47149 -0.86895751953125 +47150 -0.861053466796875 +47151 -0.765869140625 +47152 -0.5301513671875 +47153 -0.214691162109375 +47154 0.137359619140625 +47155 0.474822998046875 +47156 0.76239013671875 +47157 0.867462158203125 +47158 0.870361328125 +47159 0.86480712890625 +47160 0.831817626953125 +47161 0.677581787109375 +47162 0.495880126953125 +47163 0.30767822265625 +47164 0.116180419921875 +47165 -0.110748291015625 +47166 -0.381805419921875 +47167 -0.6572265625 +47168 -0.857421875 +47169 -0.870391845703125 +47170 -0.870391845703125 +47171 -0.86444091796875 +47172 -0.85723876953125 +47173 -0.790008544921875 +47174 -0.62847900390625 +47175 -0.3956298828125 +47176 -0.126708984375 +47177 0.150115966796875 +47178 0.424041748046875 +47179 0.670623779296875 +47180 0.854522705078125 +47181 0.866485595703125 +47182 0.86920166015625 +47183 0.8653564453125 +47184 0.857147216796875 +47185 0.766845703125 +47186 0.628509521484375 +47187 0.462127685546875 +47188 0.297210693359375 +47189 0.14862060546875 +47190 -0.00537109375 +47191 -0.15753173828125 +47192 -0.31304931640625 +47193 -0.48876953125 +47194 -0.6416015625 +47195 -0.751373291015625 +47196 -0.84619140625 +47197 -0.861297607421875 +47198 -0.863250732421875 +47199 -0.856597900390625 +47200 -0.7498779296875 +47201 -0.624542236328125 +47202 -0.47808837890625 +47203 -0.253387451171875 +47204 0.003692626953125 +47205 0.2257080078125 +47206 0.427154541015625 +47207 0.643218994140625 +47208 0.855926513671875 +47209 0.870361328125 +47210 0.870361328125 +47211 0.862762451171875 +47212 0.79669189453125 +47213 0.595794677734375 +47214 0.362152099609375 +47215 0.1270751953125 +47216 -0.086944580078125 +47217 -0.2784423828125 +47218 -0.484832763671875 +47219 -0.729583740234375 +47220 -0.86688232421875 +47221 -0.870391845703125 +47222 -0.86859130859375 +47223 -0.86279296875 +47224 -0.817962646484375 +47225 -0.6116943359375 +47226 -0.3128662109375 +47227 0.039398193359375 +47228 0.422821044921875 +47229 0.805145263671875 +47230 0.870361328125 +47231 0.870361328125 +47232 0.860015869140625 +47233 0.727935791015625 +47234 0.48114013671875 +47235 0.2059326171875 +47236 -0.06103515625 +47237 -0.29913330078125 +47238 -0.516204833984375 +47239 -0.7252197265625 +47240 -0.85980224609375 +47241 -0.870391845703125 +47242 -0.870391845703125 +47243 -0.858062744140625 +47244 -0.673004150390625 +47245 -0.42694091796875 +47246 -0.2100830078125 +47247 -0.0362548828125 +47248 0.10943603515625 +47249 0.23516845703125 +47250 0.373687744140625 +47251 0.517791748046875 +47252 0.602783203125 +47253 0.635711669921875 +47254 0.655181884765625 +47255 0.65948486328125 +47256 0.651275634765625 +47257 0.61846923828125 +47258 0.53753662109375 +47259 0.404144287109375 +47260 0.22186279296875 +47261 0.003997802734375 +47262 -0.22100830078125 +47263 -0.42449951171875 +47264 -0.579833984375 +47265 -0.641876220703125 +47266 -0.6177978515625 +47267 -0.575531005859375 +47268 -0.526336669921875 +47269 -0.42645263671875 +47270 -0.2581787109375 +47271 -0.068695068359375 +47272 0.09222412109375 +47273 0.232147216796875 +47274 0.3509521484375 +47275 0.410064697265625 +47276 0.372955322265625 +47277 0.2554931640625 +47278 0.10711669921875 +47279 -0.052886962890625 +47280 -0.186279296875 +47281 -0.23291015625 +47282 -0.209442138671875 +47283 -0.174163818359375 +47284 -0.126739501953125 +47285 -0.048126220703125 +47286 0.0426025390625 +47287 0.10748291015625 +47288 0.1409912109375 +47289 0.19708251953125 +47290 0.273651123046875 +47291 0.31768798828125 +47292 0.341094970703125 +47293 0.368011474609375 +47294 0.37249755859375 +47295 0.30072021484375 +47296 0.1517333984375 +47297 -0.01470947265625 +47298 -0.1883544921875 +47299 -0.372711181640625 +47300 -0.51397705078125 +47301 -0.57177734375 +47302 -0.53948974609375 +47303 -0.43511962890625 +47304 -0.2962646484375 +47305 -0.161102294921875 +47306 -0.0435791015625 +47307 0.060394287109375 +47308 0.13665771484375 +47309 0.170135498046875 +47310 0.16552734375 +47311 0.15728759765625 +47312 0.150787353515625 +47313 0.12200927734375 +47314 0.080108642578125 +47315 0.05126953125 +47316 0.062896728515625 +47317 0.09271240234375 +47318 0.092987060546875 +47319 0.07855224609375 +47320 0.06427001953125 +47321 0.0347900390625 +47322 -0.01171875 +47323 -0.056060791015625 +47324 -0.055511474609375 +47325 -0.010467529296875 +47326 0.02508544921875 +47327 0.025665283203125 +47328 0.017333984375 +47329 0.00189208984375 +47330 -0.03173828125 +47331 -0.071502685546875 +47332 -0.13543701171875 +47333 -0.219970703125 +47334 -0.300506591796875 +47335 -0.376312255859375 +47336 -0.416107177734375 +47337 -0.371124267578125 +47338 -0.242279052734375 +47339 -0.069732666015625 +47340 0.125640869140625 +47341 0.31268310546875 +47342 0.45501708984375 +47343 0.554779052734375 +47344 0.61065673828125 +47345 0.610931396484375 +47346 0.531463623046875 +47347 0.3883056640625 +47348 0.23468017578125 +47349 0.095245361328125 +47350 -0.00396728515625 +47351 -0.04852294921875 +47352 -0.055145263671875 +47353 -0.0758056640625 +47354 -0.138702392578125 +47355 -0.209197998046875 +47356 -0.289031982421875 +47357 -0.37884521484375 +47358 -0.456329345703125 +47359 -0.51641845703125 +47360 -0.519287109375 +47361 -0.458251953125 +47362 -0.384796142578125 +47363 -0.323699951171875 +47364 -0.269287109375 +47365 -0.1951904296875 +47366 -0.100006103515625 +47367 -0.01055908203125 +47368 0.1033935546875 +47369 0.24908447265625 +47370 0.373199462890625 +47371 0.45806884765625 +47372 0.511474609375 +47373 0.565399169921875 +47374 0.61138916015625 +47375 0.5897216796875 +47376 0.4906005859375 +47377 0.33148193359375 +47378 0.147796630859375 +47379 -0.01873779296875 +47380 -0.140289306640625 +47381 -0.191986083984375 +47382 -0.184295654296875 +47383 -0.161834716796875 +47384 -0.166595458984375 +47385 -0.19390869140625 +47386 -0.22442626953125 +47387 -0.279754638671875 +47388 -0.3389892578125 +47389 -0.3543701171875 +47390 -0.348175048828125 +47391 -0.32598876953125 +47392 -0.2581787109375 +47393 -0.139801025390625 +47394 0.014617919921875 +47395 0.144378662109375 +47396 0.221038818359375 +47397 0.27069091796875 +47398 0.294036865234375 +47399 0.311767578125 +47400 0.339141845703125 +47401 0.360260009765625 +47402 0.360504150390625 +47403 0.308380126953125 +47404 0.18170166015625 +47405 0.0047607421875 +47406 -0.17559814453125 +47407 -0.3143310546875 +47408 -0.36785888671875 +47409 -0.36248779296875 +47410 -0.343536376953125 +47411 -0.3018798828125 +47412 -0.231414794921875 +47413 -0.117645263671875 +47414 0.007049560546875 +47415 0.087982177734375 +47416 0.13946533203125 +47417 0.17425537109375 +47418 0.188201904296875 +47419 0.171234130859375 +47420 0.118438720703125 +47421 0.05706787109375 +47422 -0.010711669921875 +47423 -0.0914306640625 +47424 -0.162322998046875 +47425 -0.194549560546875 +47426 -0.1492919921875 +47427 -0.02166748046875 +47428 0.124053955078125 +47429 0.211151123046875 +47430 0.240447998046875 +47431 0.242218017578125 +47432 0.2257080078125 +47433 0.194366455078125 +47434 0.115509033203125 +47435 0.0128173828125 +47436 -0.053802490234375 +47437 -0.110626220703125 +47438 -0.199493408203125 +47439 -0.29437255859375 +47440 -0.33221435546875 +47441 -0.27972412109375 +47442 -0.185333251953125 +47443 -0.128204345703125 +47444 -0.115692138671875 +47445 -0.116455078125 +47446 -0.105926513671875 +47447 -0.053955078125 +47448 0.048797607421875 +47449 0.157318115234375 +47450 0.212005615234375 +47451 0.218475341796875 +47452 0.23724365234375 +47453 0.30535888671875 +47454 0.38128662109375 +47455 0.404449462890625 +47456 0.3944091796875 +47457 0.3885498046875 +47458 0.362640380859375 +47459 0.27362060546875 +47460 0.11712646484375 +47461 -0.054901123046875 +47462 -0.19085693359375 +47463 -0.28570556640625 +47464 -0.339263916015625 +47465 -0.3775634765625 +47466 -0.445709228515625 +47467 -0.535064697265625 +47468 -0.629058837890625 +47469 -0.697601318359375 +47470 -0.70391845703125 +47471 -0.6424560546875 +47472 -0.491241455078125 +47473 -0.265716552734375 +47474 -0.023712158203125 +47475 0.201751708984375 +47476 0.375823974609375 +47477 0.485076904296875 +47478 0.56884765625 +47479 0.634765625 +47480 0.63763427734375 +47481 0.5660400390625 +47482 0.4720458984375 +47483 0.40692138671875 +47484 0.3778076171875 +47485 0.376953125 +47486 0.371978759765625 +47487 0.313140869140625 +47488 0.184417724609375 +47489 0.011199951171875 +47490 -0.171051025390625 +47491 -0.33740234375 +47492 -0.47198486328125 +47493 -0.560394287109375 +47494 -0.58056640625 +47495 -0.54754638671875 +47496 -0.508575439453125 +47497 -0.459503173828125 +47498 -0.394378662109375 +47499 -0.35260009765625 +47500 -0.31170654296875 +47501 -0.197418212890625 +47502 -0.007965087890625 +47503 0.207489013671875 +47504 0.409210205078125 +47505 0.57208251953125 +47506 0.66595458984375 +47507 0.65875244140625 +47508 0.56744384765625 +47509 0.431396484375 +47510 0.29443359375 +47511 0.182464599609375 +47512 0.06365966796875 +47513 -0.075958251953125 +47514 -0.189422607421875 +47515 -0.271942138671875 +47516 -0.342529296875 +47517 -0.364166259765625 +47518 -0.327239990234375 +47519 -0.2769775390625 +47520 -0.253692626953125 +47521 -0.24365234375 +47522 -0.1983642578125 +47523 -0.116241455078125 +47524 -0.036834716796875 +47525 0.034881591796875 +47526 0.09124755859375 +47527 0.10888671875 +47528 0.125518798828125 +47529 0.15771484375 +47530 0.17828369140625 +47531 0.17108154296875 +47532 0.129974365234375 +47533 0.082427978515625 +47534 0.027679443359375 +47535 -0.065643310546875 +47536 -0.15936279296875 +47537 -0.21307373046875 +47538 -0.234649658203125 +47539 -0.2001953125 +47540 -0.119171142578125 +47541 -0.024749755859375 +47542 0.085784912109375 +47543 0.178131103515625 +47544 0.215576171875 +47545 0.211456298828125 +47546 0.17523193359375 +47547 0.128753662109375 +47548 0.1019287109375 +47549 0.0743408203125 +47550 0.04327392578125 +47551 0.038177490234375 +47552 0.076263427734375 +47553 0.14105224609375 +47554 0.186431884765625 +47555 0.188812255859375 +47556 0.1390380859375 +47557 0.041778564453125 +47558 -0.079437255859375 +47559 -0.219390869140625 +47560 -0.367828369140625 +47561 -0.494873046875 +47562 -0.556243896484375 +47563 -0.508697509765625 +47564 -0.3756103515625 +47565 -0.218902587890625 +47566 -0.063751220703125 +47567 0.091552734375 +47568 0.23602294921875 +47569 0.342987060546875 +47570 0.39520263671875 +47571 0.389373779296875 +47572 0.324249267578125 +47573 0.224090576171875 +47574 0.124267578125 +47575 0.037078857421875 +47576 -0.010101318359375 +47577 -0.019439697265625 +47578 -0.022796630859375 +47579 -0.001556396484375 +47580 0.056304931640625 +47581 0.106719970703125 +47582 0.096893310546875 +47583 0.042694091796875 +47584 -0.018035888671875 +47585 -0.07586669921875 +47586 -0.11944580078125 +47587 -0.15972900390625 +47588 -0.202606201171875 +47589 -0.24859619140625 +47590 -0.30517578125 +47591 -0.36212158203125 +47592 -0.39141845703125 +47593 -0.35528564453125 +47594 -0.249969482421875 +47595 -0.092864990234375 +47596 0.08905029296875 +47597 0.2352294921875 +47598 0.318817138671875 +47599 0.358642578125 +47600 0.347747802734375 +47601 0.28564453125 +47602 0.223175048828125 +47603 0.196746826171875 +47604 0.179840087890625 +47605 0.155548095703125 +47606 0.151214599609375 +47607 0.156951904296875 +47608 0.13177490234375 +47609 0.100799560546875 +47610 0.087127685546875 +47611 0.05487060546875 +47612 -0.009002685546875 +47613 -0.10400390625 +47614 -0.229400634765625 +47615 -0.35552978515625 +47616 -0.441925048828125 +47617 -0.473846435546875 +47618 -0.464813232421875 +47619 -0.419097900390625 +47620 -0.334320068359375 +47621 -0.227935791015625 +47622 -0.12347412109375 +47623 -0.02764892578125 +47624 0.077667236328125 +47625 0.2132568359375 +47626 0.38885498046875 +47627 0.582794189453125 +47628 0.734039306640625 +47629 0.800140380859375 +47630 0.7783203125 +47631 0.6651611328125 +47632 0.45965576171875 +47633 0.199188232421875 +47634 -0.050689697265625 +47635 -0.23297119140625 +47636 -0.33013916015625 +47637 -0.368408203125 +47638 -0.378936767578125 +47639 -0.376983642578125 +47640 -0.37969970703125 +47641 -0.391510009765625 +47642 -0.385345458984375 +47643 -0.3419189453125 +47644 -0.28289794921875 +47645 -0.251617431640625 +47646 -0.266143798828125 +47647 -0.273345947265625 +47648 -0.216796875 +47649 -0.128265380859375 +47650 -0.068145751953125 +47651 -0.0430908203125 +47652 -0.024444580078125 +47653 0.020721435546875 +47654 0.124481201171875 +47655 0.25787353515625 +47656 0.379119873046875 +47657 0.47991943359375 +47658 0.5281982421875 +47659 0.511138916015625 +47660 0.456207275390625 +47661 0.407470703125 +47662 0.383758544921875 +47663 0.35687255859375 +47664 0.31182861328125 +47665 0.250885009765625 +47666 0.1654052734375 +47667 0.035247802734375 +47668 -0.142059326171875 +47669 -0.33563232421875 +47670 -0.5345458984375 +47671 -0.72186279296875 +47672 -0.836669921875 +47673 -0.8326416015625 +47674 -0.7296142578125 +47675 -0.582550048828125 +47676 -0.440093994140625 +47677 -0.324310302734375 +47678 -0.20147705078125 +47679 -0.044647216796875 +47680 0.103973388671875 +47681 0.202392578125 +47682 0.264495849609375 +47683 0.338897705078125 +47684 0.443817138671875 +47685 0.545074462890625 +47686 0.6173095703125 +47687 0.6524658203125 +47688 0.66339111328125 +47689 0.6561279296875 +47690 0.606781005859375 +47691 0.501190185546875 +47692 0.352783203125 +47693 0.176544189453125 +47694 -0.034820556640625 +47695 -0.258209228515625 +47696 -0.44244384765625 +47697 -0.5753173828125 +47698 -0.65203857421875 +47699 -0.641632080078125 +47700 -0.562164306640625 +47701 -0.458038330078125 +47702 -0.350555419921875 +47703 -0.260528564453125 +47704 -0.192108154296875 +47705 -0.141937255859375 +47706 -0.1021728515625 +47707 -0.062896728515625 +47708 -0.011932373046875 +47709 0.062835693359375 +47710 0.148712158203125 +47711 0.241729736328125 +47712 0.34912109375 +47713 0.457305908203125 +47714 0.54388427734375 +47715 0.5728759765625 +47716 0.506591796875 +47717 0.351226806640625 +47718 0.146514892578125 +47719 -0.05523681640625 +47720 -0.21624755859375 +47721 -0.334930419921875 +47722 -0.402984619140625 +47723 -0.4412841796875 +47724 -0.49578857421875 +47725 -0.5601806640625 +47726 -0.600738525390625 +47727 -0.584228515625 +47728 -0.47930908203125 +47729 -0.27935791015625 +47730 -0.0089111328125 +47731 0.268798828125 +47732 0.482818603515625 +47733 0.60369873046875 +47734 0.650421142578125 +47735 0.66400146484375 +47736 0.6414794921875 +47737 0.572540283203125 +47738 0.498138427734375 +47739 0.439453125 +47740 0.375518798828125 +47741 0.274505615234375 +47742 0.1087646484375 +47743 -0.099395751953125 +47744 -0.3182373046875 +47745 -0.5489501953125 +47746 -0.7738037109375 +47747 -0.86383056640625 +47748 -0.870391845703125 +47749 -0.86895751953125 +47750 -0.861053466796875 +47751 -0.765869140625 +47752 -0.5301513671875 +47753 -0.214691162109375 +47754 0.137359619140625 +47755 0.474822998046875 +47756 0.76239013671875 +47757 0.867462158203125 +47758 0.870361328125 +47759 0.86480712890625 +47760 0.831817626953125 +47761 0.677581787109375 +47762 0.495880126953125 +47763 0.30767822265625 +47764 0.116180419921875 +47765 -0.110748291015625 +47766 -0.381805419921875 +47767 -0.6572265625 +47768 -0.857421875 +47769 -0.870391845703125 +47770 -0.870391845703125 +47771 -0.86444091796875 +47772 -0.85723876953125 +47773 -0.790008544921875 +47774 -0.62847900390625 +47775 -0.3956298828125 +47776 -0.126708984375 +47777 0.150115966796875 +47778 0.424041748046875 +47779 0.670623779296875 +47780 0.854522705078125 +47781 0.866485595703125 +47782 0.86920166015625 +47783 0.8653564453125 +47784 0.857147216796875 +47785 0.766845703125 +47786 0.628509521484375 +47787 0.462127685546875 +47788 0.297210693359375 +47789 0.14862060546875 +47790 -0.00537109375 +47791 -0.15753173828125 +47792 -0.31304931640625 +47793 -0.48876953125 +47794 -0.6416015625 +47795 -0.751373291015625 +47796 -0.84619140625 +47797 -0.861297607421875 +47798 -0.863250732421875 +47799 -0.856597900390625 +47800 -0.7498779296875 +47801 -0.624542236328125 +47802 -0.47808837890625 +47803 -0.253387451171875 +47804 0.003692626953125 +47805 0.2257080078125 +47806 0.427154541015625 +47807 0.643218994140625 +47808 0.855926513671875 +47809 0.870361328125 +47810 0.870361328125 +47811 0.862762451171875 +47812 0.79669189453125 +47813 0.595794677734375 +47814 0.362152099609375 +47815 0.1270751953125 +47816 -0.086944580078125 +47817 -0.2784423828125 +47818 -0.484832763671875 +47819 -0.729583740234375 +47820 -0.86688232421875 +47821 -0.870391845703125 +47822 -0.86859130859375 +47823 -0.86279296875 +47824 -0.817962646484375 +47825 -0.6116943359375 +47826 -0.3128662109375 +47827 0.039398193359375 +47828 0.422821044921875 +47829 0.805145263671875 +47830 0.870361328125 +47831 0.870361328125 +47832 0.860015869140625 +47833 0.727935791015625 +47834 0.48114013671875 +47835 0.2059326171875 +47836 -0.06103515625 +47837 -0.29913330078125 +47838 -0.516204833984375 +47839 -0.7252197265625 +47840 -0.85980224609375 +47841 -0.870391845703125 +47842 -0.870391845703125 +47843 -0.858062744140625 +47844 -0.673004150390625 +47845 -0.42694091796875 +47846 -0.2100830078125 +47847 -0.0362548828125 +47848 0.10943603515625 +47849 0.23516845703125 +47850 0.373687744140625 +47851 0.517791748046875 +47852 0.602783203125 +47853 0.635711669921875 +47854 0.655181884765625 +47855 0.65948486328125 +47856 0.651275634765625 +47857 0.61846923828125 +47858 0.53753662109375 +47859 0.404144287109375 +47860 0.22186279296875 +47861 0.003997802734375 +47862 -0.22100830078125 +47863 -0.42449951171875 +47864 -0.579833984375 +47865 -0.641876220703125 +47866 -0.6177978515625 +47867 -0.575531005859375 +47868 -0.526336669921875 +47869 -0.42645263671875 +47870 -0.2581787109375 +47871 -0.068695068359375 +47872 0.09222412109375 +47873 0.232147216796875 +47874 0.3509521484375 +47875 0.410064697265625 +47876 0.372955322265625 +47877 0.2554931640625 +47878 0.10711669921875 +47879 -0.052886962890625 +47880 -0.186279296875 +47881 -0.23291015625 +47882 -0.209442138671875 +47883 -0.174163818359375 +47884 -0.126739501953125 +47885 -0.048126220703125 +47886 0.0426025390625 +47887 0.10748291015625 +47888 0.1409912109375 +47889 0.19708251953125 +47890 0.273651123046875 +47891 0.31768798828125 +47892 0.341094970703125 +47893 0.368011474609375 +47894 0.37249755859375 +47895 0.30072021484375 +47896 0.1517333984375 +47897 -0.01470947265625 +47898 -0.1883544921875 +47899 -0.372711181640625 +47900 -0.51397705078125 +47901 -0.57177734375 +47902 -0.53948974609375 +47903 -0.43511962890625 +47904 -0.2962646484375 +47905 -0.161102294921875 +47906 -0.0435791015625 +47907 0.060394287109375 +47908 0.13665771484375 +47909 0.170135498046875 +47910 0.16552734375 +47911 0.15728759765625 +47912 0.150787353515625 +47913 0.12200927734375 +47914 0.080108642578125 +47915 0.05126953125 +47916 0.062896728515625 +47917 0.09271240234375 +47918 0.092987060546875 +47919 0.07855224609375 +47920 0.06427001953125 +47921 0.0347900390625 +47922 -0.01171875 +47923 -0.056060791015625 +47924 -0.055511474609375 +47925 -0.010467529296875 +47926 0.02508544921875 +47927 0.025665283203125 +47928 0.017333984375 +47929 0.00189208984375 +47930 -0.03173828125 +47931 -0.071502685546875 +47932 -0.13543701171875 +47933 -0.219970703125 +47934 -0.300506591796875 +47935 -0.376312255859375 +47936 -0.416107177734375 +47937 -0.371124267578125 +47938 -0.242279052734375 +47939 -0.069732666015625 +47940 0.125640869140625 +47941 0.31268310546875 +47942 0.45501708984375 +47943 0.554779052734375 +47944 0.61065673828125 +47945 0.610931396484375 +47946 0.531463623046875 +47947 0.3883056640625 +47948 0.23468017578125 +47949 0.095245361328125 +47950 -0.00396728515625 +47951 -0.04852294921875 +47952 -0.055145263671875 +47953 -0.0758056640625 +47954 -0.138702392578125 +47955 -0.209197998046875 +47956 -0.289031982421875 +47957 -0.37884521484375 +47958 -0.456329345703125 +47959 -0.51641845703125 +47960 -0.519287109375 +47961 -0.458251953125 +47962 -0.384796142578125 +47963 -0.323699951171875 +47964 -0.269287109375 +47965 -0.1951904296875 +47966 -0.100006103515625 +47967 -0.01055908203125 +47968 0.1033935546875 +47969 0.24908447265625 +47970 0.373199462890625 +47971 0.45806884765625 +47972 0.511474609375 +47973 0.565399169921875 +47974 0.61138916015625 +47975 0.5897216796875 +47976 0.4906005859375 +47977 0.33148193359375 +47978 0.147796630859375 +47979 -0.01873779296875 +47980 -0.140289306640625 +47981 -0.191986083984375 +47982 -0.184295654296875 +47983 -0.161834716796875 +47984 -0.166595458984375 +47985 -0.19390869140625 +47986 -0.22442626953125 +47987 -0.279754638671875 +47988 -0.3389892578125 +47989 -0.3543701171875 +47990 -0.348175048828125 +47991 -0.32598876953125 +47992 -0.2581787109375 +47993 -0.139801025390625 +47994 0.014617919921875 +47995 0.144378662109375 +47996 0.221038818359375 +47997 0.27069091796875 +47998 0.294036865234375 +47999 0.311767578125 +48000 0.339141845703125 +48001 0.360260009765625 +48002 0.360504150390625 +48003 0.308380126953125 +48004 0.18170166015625 +48005 0.0047607421875 +48006 -0.17559814453125 +48007 -0.3143310546875 +48008 -0.36785888671875 +48009 -0.36248779296875 +48010 -0.343536376953125 +48011 -0.3018798828125 +48012 -0.231414794921875 +48013 -0.117645263671875 +48014 0.007049560546875 +48015 0.087982177734375 +48016 0.13946533203125 +48017 0.17425537109375 +48018 0.188201904296875 +48019 0.171234130859375 +48020 0.118438720703125 +48021 0.05706787109375 +48022 -0.010711669921875 +48023 -0.0914306640625 +48024 -0.162322998046875 +48025 -0.194549560546875 +48026 -0.1492919921875 +48027 -0.02166748046875 +48028 0.124053955078125 +48029 0.211151123046875 +48030 0.240447998046875 +48031 0.242218017578125 +48032 0.2257080078125 +48033 0.194366455078125 +48034 0.115509033203125 +48035 0.0128173828125 +48036 -0.053802490234375 +48037 -0.110626220703125 +48038 -0.199493408203125 +48039 -0.29437255859375 +48040 -0.33221435546875 +48041 -0.27972412109375 +48042 -0.185333251953125 +48043 -0.128204345703125 +48044 -0.115692138671875 +48045 -0.116455078125 +48046 -0.105926513671875 +48047 -0.053955078125 +48048 0.048797607421875 +48049 0.157318115234375 +48050 0.212005615234375 +48051 0.218475341796875 +48052 0.23724365234375 +48053 0.30535888671875 +48054 0.38128662109375 +48055 0.404449462890625 +48056 0.3944091796875 +48057 0.3885498046875 +48058 0.362640380859375 +48059 0.27362060546875 +48060 0.11712646484375 +48061 -0.054901123046875 +48062 -0.19085693359375 +48063 -0.28570556640625 +48064 -0.339263916015625 +48065 -0.3775634765625 +48066 -0.445709228515625 +48067 -0.535064697265625 +48068 -0.629058837890625 +48069 -0.697601318359375 +48070 -0.70391845703125 +48071 -0.6424560546875 +48072 -0.491241455078125 +48073 -0.265716552734375 +48074 -0.023712158203125 +48075 0.201751708984375 +48076 0.375823974609375 +48077 0.485076904296875 +48078 0.56884765625 +48079 0.634765625 +48080 0.63763427734375 +48081 0.5660400390625 +48082 0.4720458984375 +48083 0.40692138671875 +48084 0.3778076171875 +48085 0.376953125 +48086 0.371978759765625 +48087 0.313140869140625 +48088 0.184417724609375 +48089 0.011199951171875 +48090 -0.171051025390625 +48091 -0.33740234375 +48092 -0.47198486328125 +48093 -0.560394287109375 +48094 -0.58056640625 +48095 -0.54754638671875 +48096 -0.508575439453125 +48097 -0.459503173828125 +48098 -0.394378662109375 +48099 -0.35260009765625 +48100 -0.31170654296875 +48101 -0.197418212890625 +48102 -0.007965087890625 +48103 0.207489013671875 +48104 0.409210205078125 +48105 0.57208251953125 +48106 0.66595458984375 +48107 0.65875244140625 +48108 0.56744384765625 +48109 0.431396484375 +48110 0.29443359375 +48111 0.182464599609375 +48112 0.06365966796875 +48113 -0.075958251953125 +48114 -0.189422607421875 +48115 -0.271942138671875 +48116 -0.342529296875 +48117 -0.364166259765625 +48118 -0.327239990234375 +48119 -0.2769775390625 +48120 -0.253692626953125 +48121 -0.24365234375 +48122 -0.1983642578125 +48123 -0.116241455078125 +48124 -0.036834716796875 +48125 0.034881591796875 +48126 0.09124755859375 +48127 0.10888671875 +48128 0.125518798828125 +48129 0.15771484375 +48130 0.17828369140625 +48131 0.17108154296875 +48132 0.129974365234375 +48133 0.082427978515625 +48134 0.027679443359375 +48135 -0.065643310546875 +48136 -0.15936279296875 +48137 -0.21307373046875 +48138 -0.234649658203125 +48139 -0.2001953125 +48140 -0.119171142578125 +48141 -0.024749755859375 +48142 0.085784912109375 +48143 0.178131103515625 +48144 0.215576171875 +48145 0.211456298828125 +48146 0.17523193359375 +48147 0.128753662109375 +48148 0.1019287109375 +48149 0.0743408203125 +48150 0.04327392578125 +48151 0.038177490234375 +48152 0.076263427734375 +48153 0.14105224609375 +48154 0.186431884765625 +48155 0.188812255859375 +48156 0.1390380859375 +48157 0.041778564453125 +48158 -0.079437255859375 +48159 -0.219390869140625 +48160 -0.367828369140625 +48161 -0.494873046875 +48162 -0.556243896484375 +48163 -0.508697509765625 +48164 -0.3756103515625 +48165 -0.218902587890625 +48166 -0.063751220703125 +48167 0.091552734375 +48168 0.23602294921875 +48169 0.342987060546875 +48170 0.39520263671875 +48171 0.389373779296875 +48172 0.324249267578125 +48173 0.224090576171875 +48174 0.124267578125 +48175 0.037078857421875 +48176 -0.010101318359375 +48177 -0.019439697265625 +48178 -0.022796630859375 +48179 -0.001556396484375 +48180 0.056304931640625 +48181 0.106719970703125 +48182 0.096893310546875 +48183 0.042694091796875 +48184 -0.018035888671875 +48185 -0.07586669921875 +48186 -0.11944580078125 +48187 -0.15972900390625 +48188 -0.202606201171875 +48189 -0.24859619140625 +48190 -0.30517578125 +48191 -0.36212158203125 +48192 -0.39141845703125 +48193 -0.35528564453125 +48194 -0.249969482421875 +48195 -0.092864990234375 +48196 0.08905029296875 +48197 0.2352294921875 +48198 0.318817138671875 +48199 0.358642578125 +48200 0.347747802734375 +48201 0.28564453125 +48202 0.223175048828125 +48203 0.196746826171875 +48204 0.179840087890625 +48205 0.155548095703125 +48206 0.151214599609375 +48207 0.156951904296875 +48208 0.13177490234375 +48209 0.100799560546875 +48210 0.087127685546875 +48211 0.05487060546875 +48212 -0.009002685546875 +48213 -0.10400390625 +48214 -0.229400634765625 +48215 -0.35552978515625 +48216 -0.441925048828125 +48217 -0.473846435546875 +48218 -0.464813232421875 +48219 -0.419097900390625 +48220 -0.334320068359375 +48221 -0.227935791015625 +48222 -0.12347412109375 +48223 -0.02764892578125 +48224 0.077667236328125 +48225 0.2132568359375 +48226 0.38885498046875 +48227 0.582794189453125 +48228 0.734039306640625 +48229 0.800140380859375 +48230 0.7783203125 +48231 0.6651611328125 +48232 0.45965576171875 +48233 0.199188232421875 +48234 -0.050689697265625 +48235 -0.23297119140625 +48236 -0.33013916015625 +48237 -0.368408203125 +48238 -0.378936767578125 +48239 -0.376983642578125 +48240 -0.37969970703125 +48241 -0.391510009765625 +48242 -0.385345458984375 +48243 -0.3419189453125 +48244 -0.28289794921875 +48245 -0.251617431640625 +48246 -0.266143798828125 +48247 -0.273345947265625 +48248 -0.216796875 +48249 -0.128265380859375 +48250 -0.068145751953125 +48251 -0.0430908203125 +48252 -0.024444580078125 +48253 0.020721435546875 +48254 0.124481201171875 +48255 0.25787353515625 +48256 0.379119873046875 +48257 0.47991943359375 +48258 0.5281982421875 +48259 0.511138916015625 +48260 0.456207275390625 +48261 0.407470703125 +48262 0.383758544921875 +48263 0.35687255859375 +48264 0.31182861328125 +48265 0.250885009765625 +48266 0.1654052734375 +48267 0.035247802734375 +48268 -0.142059326171875 +48269 -0.33563232421875 +48270 -0.5345458984375 +48271 -0.72186279296875 +48272 -0.836669921875 +48273 -0.8326416015625 +48274 -0.7296142578125 +48275 -0.582550048828125 +48276 -0.440093994140625 +48277 -0.324310302734375 +48278 -0.20147705078125 +48279 -0.044647216796875 +48280 0.103973388671875 +48281 0.202392578125 +48282 0.264495849609375 +48283 0.338897705078125 +48284 0.443817138671875 +48285 0.545074462890625 +48286 0.6173095703125 +48287 0.6524658203125 +48288 0.66339111328125 +48289 0.6561279296875 +48290 0.606781005859375 +48291 0.501190185546875 +48292 0.352783203125 +48293 0.176544189453125 +48294 -0.034820556640625 +48295 -0.258209228515625 +48296 -0.44244384765625 +48297 -0.5753173828125 +48298 -0.65203857421875 +48299 -0.641632080078125 +48300 -0.562164306640625 +48301 -0.458038330078125 +48302 -0.350555419921875 +48303 -0.260528564453125 +48304 -0.192108154296875 +48305 -0.141937255859375 +48306 -0.1021728515625 +48307 -0.062896728515625 +48308 -0.011932373046875 +48309 0.062835693359375 +48310 0.148712158203125 +48311 0.241729736328125 +48312 0.34912109375 +48313 0.457305908203125 +48314 0.54388427734375 +48315 0.5728759765625 +48316 0.506591796875 +48317 0.351226806640625 +48318 0.146514892578125 +48319 -0.05523681640625 +48320 -0.21624755859375 +48321 -0.334930419921875 +48322 -0.402984619140625 +48323 -0.4412841796875 +48324 -0.49578857421875 +48325 -0.5601806640625 +48326 -0.600738525390625 +48327 -0.584228515625 +48328 -0.47930908203125 +48329 -0.27935791015625 +48330 -0.0089111328125 +48331 0.268798828125 +48332 0.482818603515625 +48333 0.60369873046875 +48334 0.650421142578125 +48335 0.66400146484375 +48336 0.6414794921875 +48337 0.572540283203125 +48338 0.498138427734375 +48339 0.439453125 +48340 0.375518798828125 +48341 0.274505615234375 +48342 0.1087646484375 +48343 -0.099395751953125 +48344 -0.3182373046875 +48345 -0.5489501953125 +48346 -0.7738037109375 +48347 -0.86383056640625 +48348 -0.870391845703125 +48349 -0.86895751953125 +48350 -0.861053466796875 +48351 -0.765869140625 +48352 -0.5301513671875 +48353 -0.214691162109375 +48354 0.137359619140625 +48355 0.474822998046875 +48356 0.76239013671875 +48357 0.867462158203125 +48358 0.870361328125 +48359 0.86480712890625 +48360 0.831817626953125 +48361 0.677581787109375 +48362 0.495880126953125 +48363 0.30767822265625 +48364 0.116180419921875 +48365 -0.110748291015625 +48366 -0.381805419921875 +48367 -0.6572265625 +48368 -0.857421875 +48369 -0.870391845703125 +48370 -0.870391845703125 +48371 -0.86444091796875 +48372 -0.85723876953125 +48373 -0.790008544921875 +48374 -0.62847900390625 +48375 -0.3956298828125 +48376 -0.126708984375 +48377 0.150115966796875 +48378 0.424041748046875 +48379 0.670623779296875 +48380 0.854522705078125 +48381 0.866485595703125 +48382 0.86920166015625 +48383 0.8653564453125 +48384 0.857147216796875 +48385 0.766845703125 +48386 0.628509521484375 +48387 0.462127685546875 +48388 0.297210693359375 +48389 0.14862060546875 +48390 -0.00537109375 +48391 -0.15753173828125 +48392 -0.31304931640625 +48393 -0.48876953125 +48394 -0.6416015625 +48395 -0.751373291015625 +48396 -0.84619140625 +48397 -0.861297607421875 +48398 -0.863250732421875 +48399 -0.856597900390625 +48400 -0.7498779296875 +48401 -0.624542236328125 +48402 -0.47808837890625 +48403 -0.253387451171875 +48404 0.003692626953125 +48405 0.2257080078125 +48406 0.427154541015625 +48407 0.643218994140625 +48408 0.855926513671875 +48409 0.870361328125 +48410 0.870361328125 +48411 0.862762451171875 +48412 0.79669189453125 +48413 0.595794677734375 +48414 0.362152099609375 +48415 0.1270751953125 +48416 -0.086944580078125 +48417 -0.2784423828125 +48418 -0.484832763671875 +48419 -0.729583740234375 +48420 -0.86688232421875 +48421 -0.870391845703125 +48422 -0.86859130859375 +48423 -0.86279296875 +48424 -0.817962646484375 +48425 -0.6116943359375 +48426 -0.3128662109375 +48427 0.039398193359375 +48428 0.422821044921875 +48429 0.805145263671875 +48430 0.870361328125 +48431 0.870361328125 +48432 0.860015869140625 +48433 0.727935791015625 +48434 0.48114013671875 +48435 0.2059326171875 +48436 -0.06103515625 +48437 -0.29913330078125 +48438 -0.516204833984375 +48439 -0.7252197265625 +48440 -0.85980224609375 +48441 -0.870391845703125 +48442 -0.870391845703125 +48443 -0.858062744140625 +48444 -0.673004150390625 +48445 -0.42694091796875 +48446 -0.2100830078125 +48447 -0.0362548828125 +48448 0.10943603515625 +48449 0.23516845703125 +48450 0.373687744140625 +48451 0.517791748046875 +48452 0.602783203125 +48453 0.635711669921875 +48454 0.655181884765625 +48455 0.65948486328125 +48456 0.651275634765625 +48457 0.61846923828125 +48458 0.53753662109375 +48459 0.404144287109375 +48460 0.22186279296875 +48461 0.003997802734375 +48462 -0.22100830078125 +48463 -0.42449951171875 +48464 -0.579833984375 +48465 -0.641876220703125 +48466 -0.6177978515625 +48467 -0.575531005859375 +48468 -0.526336669921875 +48469 -0.42645263671875 +48470 -0.2581787109375 +48471 -0.068695068359375 +48472 0.09222412109375 +48473 0.232147216796875 +48474 0.3509521484375 +48475 0.410064697265625 +48476 0.372955322265625 +48477 0.2554931640625 +48478 0.10711669921875 +48479 -0.052886962890625 +48480 -0.186279296875 +48481 -0.23291015625 +48482 -0.209442138671875 +48483 -0.174163818359375 +48484 -0.126739501953125 +48485 -0.048126220703125 +48486 0.0426025390625 +48487 0.10748291015625 +48488 0.1409912109375 +48489 0.19708251953125 +48490 0.273651123046875 +48491 0.31768798828125 +48492 0.341094970703125 +48493 0.368011474609375 +48494 0.37249755859375 +48495 0.30072021484375 +48496 0.1517333984375 +48497 -0.01470947265625 +48498 -0.1883544921875 +48499 -0.372711181640625 +48500 -0.51397705078125 +48501 -0.57177734375 +48502 -0.53948974609375 +48503 -0.43511962890625 +48504 -0.2962646484375 +48505 -0.161102294921875 +48506 -0.0435791015625 +48507 0.060394287109375 +48508 0.13665771484375 +48509 0.170135498046875 +48510 0.16552734375 +48511 0.15728759765625 +48512 0.150787353515625 +48513 0.12200927734375 +48514 0.080108642578125 +48515 0.05126953125 +48516 0.062896728515625 +48517 0.09271240234375 +48518 0.092987060546875 +48519 0.07855224609375 +48520 0.06427001953125 +48521 0.0347900390625 +48522 -0.01171875 +48523 -0.056060791015625 +48524 -0.055511474609375 +48525 -0.010467529296875 +48526 0.02508544921875 +48527 0.025665283203125 +48528 0.017333984375 +48529 0.00189208984375 +48530 -0.03173828125 +48531 -0.071502685546875 +48532 -0.13543701171875 +48533 -0.219970703125 +48534 -0.300506591796875 +48535 -0.376312255859375 +48536 -0.416107177734375 +48537 -0.371124267578125 +48538 -0.242279052734375 +48539 -0.069732666015625 +48540 0.125640869140625 +48541 0.31268310546875 +48542 0.45501708984375 +48543 0.554779052734375 +48544 0.61065673828125 +48545 0.610931396484375 +48546 0.531463623046875 +48547 0.3883056640625 +48548 0.23468017578125 +48549 0.095245361328125 +48550 -0.00396728515625 +48551 -0.04852294921875 +48552 -0.055145263671875 +48553 -0.0758056640625 +48554 -0.138702392578125 +48555 -0.209197998046875 +48556 -0.289031982421875 +48557 -0.37884521484375 +48558 -0.456329345703125 +48559 -0.51641845703125 +48560 -0.519287109375 +48561 -0.458251953125 +48562 -0.384796142578125 +48563 -0.323699951171875 +48564 -0.269287109375 +48565 -0.1951904296875 +48566 -0.100006103515625 +48567 -0.01055908203125 +48568 0.1033935546875 +48569 0.24908447265625 +48570 0.373199462890625 +48571 0.45806884765625 +48572 0.511474609375 +48573 0.565399169921875 +48574 0.61138916015625 +48575 0.5897216796875 +48576 0.4906005859375 +48577 0.33148193359375 +48578 0.147796630859375 +48579 -0.01873779296875 +48580 -0.140289306640625 +48581 -0.191986083984375 +48582 -0.184295654296875 +48583 -0.161834716796875 +48584 -0.166595458984375 +48585 -0.19390869140625 +48586 -0.22442626953125 +48587 -0.279754638671875 +48588 -0.3389892578125 +48589 -0.3543701171875 +48590 -0.348175048828125 +48591 -0.32598876953125 +48592 -0.2581787109375 +48593 -0.139801025390625 +48594 0.014617919921875 +48595 0.144378662109375 +48596 0.221038818359375 +48597 0.27069091796875 +48598 0.294036865234375 +48599 0.311767578125 +48600 0.339141845703125 +48601 0.360260009765625 +48602 0.360504150390625 +48603 0.308380126953125 +48604 0.18170166015625 +48605 0.0047607421875 +48606 -0.17559814453125 +48607 -0.3143310546875 +48608 -0.36785888671875 +48609 -0.36248779296875 +48610 -0.343536376953125 +48611 -0.3018798828125 +48612 -0.231414794921875 +48613 -0.117645263671875 +48614 0.007049560546875 +48615 0.087982177734375 +48616 0.13946533203125 +48617 0.17425537109375 +48618 0.188201904296875 +48619 0.171234130859375 +48620 0.118438720703125 +48621 0.05706787109375 +48622 -0.010711669921875 +48623 -0.0914306640625 +48624 -0.162322998046875 +48625 -0.194549560546875 +48626 -0.1492919921875 +48627 -0.02166748046875 +48628 0.124053955078125 +48629 0.211151123046875 +48630 0.240447998046875 +48631 0.242218017578125 +48632 0.2257080078125 +48633 0.194366455078125 +48634 0.115509033203125 +48635 0.0128173828125 +48636 -0.053802490234375 +48637 -0.110626220703125 +48638 -0.199493408203125 +48639 -0.29437255859375 +48640 -0.33221435546875 +48641 -0.27972412109375 +48642 -0.185333251953125 +48643 -0.128204345703125 +48644 -0.115692138671875 +48645 -0.116455078125 +48646 -0.105926513671875 +48647 -0.053955078125 +48648 0.048797607421875 +48649 0.157318115234375 +48650 0.212005615234375 +48651 0.218475341796875 +48652 0.23724365234375 +48653 0.30535888671875 +48654 0.38128662109375 +48655 0.404449462890625 +48656 0.3944091796875 +48657 0.3885498046875 +48658 0.362640380859375 +48659 0.27362060546875 +48660 0.11712646484375 +48661 -0.054901123046875 +48662 -0.19085693359375 +48663 -0.28570556640625 +48664 -0.339263916015625 +48665 -0.3775634765625 +48666 -0.445709228515625 +48667 -0.535064697265625 +48668 -0.629058837890625 +48669 -0.697601318359375 +48670 -0.70391845703125 +48671 -0.6424560546875 +48672 -0.491241455078125 +48673 -0.265716552734375 +48674 -0.023712158203125 +48675 0.201751708984375 +48676 0.375823974609375 +48677 0.485076904296875 +48678 0.56884765625 +48679 0.634765625 +48680 0.63763427734375 +48681 0.5660400390625 +48682 0.4720458984375 +48683 0.40692138671875 +48684 0.3778076171875 +48685 0.376953125 +48686 0.371978759765625 +48687 0.313140869140625 +48688 0.184417724609375 +48689 0.011199951171875 +48690 -0.171051025390625 +48691 -0.33740234375 +48692 -0.47198486328125 +48693 -0.560394287109375 +48694 -0.58056640625 +48695 -0.54754638671875 +48696 -0.508575439453125 +48697 -0.459503173828125 +48698 -0.394378662109375 +48699 -0.35260009765625 +48700 -0.31170654296875 +48701 -0.197418212890625 +48702 -0.007965087890625 +48703 0.207489013671875 +48704 0.409210205078125 +48705 0.57208251953125 +48706 0.66595458984375 +48707 0.65875244140625 +48708 0.56744384765625 +48709 0.431396484375 +48710 0.29443359375 +48711 0.182464599609375 +48712 0.06365966796875 +48713 -0.075958251953125 +48714 -0.189422607421875 +48715 -0.271942138671875 +48716 -0.342529296875 +48717 -0.364166259765625 +48718 -0.327239990234375 +48719 -0.2769775390625 +48720 -0.253692626953125 +48721 -0.24365234375 +48722 -0.1983642578125 +48723 -0.116241455078125 +48724 -0.036834716796875 +48725 0.034881591796875 +48726 0.09124755859375 +48727 0.10888671875 +48728 0.125518798828125 +48729 0.15771484375 +48730 0.17828369140625 +48731 0.17108154296875 +48732 0.129974365234375 +48733 0.082427978515625 +48734 0.027679443359375 +48735 -0.065643310546875 +48736 -0.15936279296875 +48737 -0.21307373046875 +48738 -0.234649658203125 +48739 -0.2001953125 +48740 -0.119171142578125 +48741 -0.024749755859375 +48742 0.085784912109375 +48743 0.178131103515625 +48744 0.215576171875 +48745 0.211456298828125 +48746 0.17523193359375 +48747 0.128753662109375 +48748 0.1019287109375 +48749 0.0743408203125 +48750 0.04327392578125 +48751 0.038177490234375 +48752 0.076263427734375 +48753 0.14105224609375 +48754 0.186431884765625 +48755 0.188812255859375 +48756 0.1390380859375 +48757 0.041778564453125 +48758 -0.079437255859375 +48759 -0.219390869140625 +48760 -0.367828369140625 +48761 -0.494873046875 +48762 -0.556243896484375 +48763 -0.508697509765625 +48764 -0.3756103515625 +48765 -0.218902587890625 +48766 -0.063751220703125 +48767 0.091552734375 +48768 0.23602294921875 +48769 0.342987060546875 +48770 0.39520263671875 +48771 0.389373779296875 +48772 0.324249267578125 +48773 0.224090576171875 +48774 0.124267578125 +48775 0.037078857421875 +48776 -0.010101318359375 +48777 -0.019439697265625 +48778 -0.022796630859375 +48779 -0.001556396484375 +48780 0.056304931640625 +48781 0.106719970703125 +48782 0.096893310546875 +48783 0.042694091796875 +48784 -0.018035888671875 +48785 -0.07586669921875 +48786 -0.11944580078125 +48787 -0.15972900390625 +48788 -0.202606201171875 +48789 -0.24859619140625 +48790 -0.30517578125 +48791 -0.36212158203125 +48792 -0.39141845703125 +48793 -0.35528564453125 +48794 -0.249969482421875 +48795 -0.092864990234375 +48796 0.08905029296875 +48797 0.2352294921875 +48798 0.318817138671875 +48799 0.358642578125 +48800 0.347747802734375 +48801 0.28564453125 +48802 0.223175048828125 +48803 0.196746826171875 +48804 0.179840087890625 +48805 0.155548095703125 +48806 0.151214599609375 +48807 0.156951904296875 +48808 0.13177490234375 +48809 0.100799560546875 +48810 0.087127685546875 +48811 0.05487060546875 +48812 -0.009002685546875 +48813 -0.10400390625 +48814 -0.229400634765625 +48815 -0.35552978515625 +48816 -0.441925048828125 +48817 -0.473846435546875 +48818 -0.464813232421875 +48819 -0.419097900390625 +48820 -0.334320068359375 +48821 -0.227935791015625 +48822 -0.12347412109375 +48823 -0.02764892578125 +48824 0.077667236328125 +48825 0.2132568359375 +48826 0.38885498046875 +48827 0.582794189453125 +48828 0.734039306640625 +48829 0.800140380859375 +48830 0.7783203125 +48831 0.6651611328125 +48832 0.45965576171875 +48833 0.199188232421875 +48834 -0.050689697265625 +48835 -0.23297119140625 +48836 -0.33013916015625 +48837 -0.368408203125 +48838 -0.378936767578125 +48839 -0.376983642578125 +48840 -0.37969970703125 +48841 -0.391510009765625 +48842 -0.385345458984375 +48843 -0.3419189453125 +48844 -0.28289794921875 +48845 -0.251617431640625 +48846 -0.266143798828125 +48847 -0.273345947265625 +48848 -0.216796875 +48849 -0.128265380859375 +48850 -0.068145751953125 +48851 -0.0430908203125 +48852 -0.024444580078125 +48853 0.020721435546875 +48854 0.124481201171875 +48855 0.25787353515625 +48856 0.379119873046875 +48857 0.47991943359375 +48858 0.5281982421875 +48859 0.511138916015625 +48860 0.456207275390625 +48861 0.407470703125 +48862 0.383758544921875 +48863 0.35687255859375 +48864 0.31182861328125 +48865 0.250885009765625 +48866 0.1654052734375 +48867 0.035247802734375 +48868 -0.142059326171875 +48869 -0.33563232421875 +48870 -0.5345458984375 +48871 -0.72186279296875 +48872 -0.836669921875 +48873 -0.8326416015625 +48874 -0.7296142578125 +48875 -0.582550048828125 +48876 -0.440093994140625 +48877 -0.324310302734375 +48878 -0.20147705078125 +48879 -0.044647216796875 +48880 0.103973388671875 +48881 0.202392578125 +48882 0.264495849609375 +48883 0.338897705078125 +48884 0.443817138671875 +48885 0.545074462890625 +48886 0.6173095703125 +48887 0.6524658203125 +48888 0.66339111328125 +48889 0.6561279296875 +48890 0.606781005859375 +48891 0.501190185546875 +48892 0.352783203125 +48893 0.176544189453125 +48894 -0.034820556640625 +48895 -0.258209228515625 +48896 -0.44244384765625 +48897 -0.5753173828125 +48898 -0.65203857421875 +48899 -0.641632080078125 +48900 -0.562164306640625 +48901 -0.458038330078125 +48902 -0.350555419921875 +48903 -0.260528564453125 +48904 -0.192108154296875 +48905 -0.141937255859375 +48906 -0.1021728515625 +48907 -0.062896728515625 +48908 -0.011932373046875 +48909 0.062835693359375 +48910 0.148712158203125 +48911 0.241729736328125 +48912 0.34912109375 +48913 0.457305908203125 +48914 0.54388427734375 +48915 0.5728759765625 +48916 0.506591796875 +48917 0.351226806640625 +48918 0.146514892578125 +48919 -0.05523681640625 +48920 -0.21624755859375 +48921 -0.334930419921875 +48922 -0.402984619140625 +48923 -0.4412841796875 +48924 -0.49578857421875 +48925 -0.5601806640625 +48926 -0.600738525390625 +48927 -0.584228515625 +48928 -0.47930908203125 +48929 -0.27935791015625 +48930 -0.0089111328125 +48931 0.268798828125 +48932 0.482818603515625 +48933 0.60369873046875 +48934 0.650421142578125 +48935 0.66400146484375 +48936 0.6414794921875 +48937 0.572540283203125 +48938 0.498138427734375 +48939 0.439453125 +48940 0.375518798828125 +48941 0.274505615234375 +48942 0.1087646484375 +48943 -0.099395751953125 +48944 -0.3182373046875 +48945 -0.5489501953125 +48946 -0.7738037109375 +48947 -0.86383056640625 +48948 -0.870391845703125 +48949 -0.86895751953125 +48950 -0.861053466796875 +48951 -0.765869140625 +48952 -0.5301513671875 +48953 -0.214691162109375 +48954 0.137359619140625 +48955 0.474822998046875 +48956 0.76239013671875 +48957 0.867462158203125 +48958 0.870361328125 +48959 0.86480712890625 +48960 0.831817626953125 +48961 0.677581787109375 +48962 0.495880126953125 +48963 0.30767822265625 +48964 0.116180419921875 +48965 -0.110748291015625 +48966 -0.381805419921875 +48967 -0.6572265625 +48968 -0.857421875 +48969 -0.870391845703125 +48970 -0.870391845703125 +48971 -0.86444091796875 +48972 -0.85723876953125 +48973 -0.790008544921875 +48974 -0.62847900390625 +48975 -0.3956298828125 +48976 -0.126708984375 +48977 0.150115966796875 +48978 0.424041748046875 +48979 0.670623779296875 +48980 0.854522705078125 +48981 0.866485595703125 +48982 0.86920166015625 +48983 0.8653564453125 +48984 0.857147216796875 +48985 0.766845703125 +48986 0.628509521484375 +48987 0.462127685546875 +48988 0.297210693359375 +48989 0.14862060546875 +48990 -0.00537109375 +48991 -0.15753173828125 +48992 -0.31304931640625 +48993 -0.48876953125 +48994 -0.6416015625 +48995 -0.751373291015625 +48996 -0.84619140625 +48997 -0.861297607421875 +48998 -0.863250732421875 +48999 -0.856597900390625 +49000 -0.7498779296875 +49001 -0.624542236328125 +49002 -0.47808837890625 +49003 -0.253387451171875 +49004 0.003692626953125 +49005 0.2257080078125 +49006 0.427154541015625 +49007 0.643218994140625 +49008 0.855926513671875 +49009 0.870361328125 +49010 0.870361328125 +49011 0.862762451171875 +49012 0.79669189453125 +49013 0.595794677734375 +49014 0.362152099609375 +49015 0.1270751953125 +49016 -0.086944580078125 +49017 -0.2784423828125 +49018 -0.484832763671875 +49019 -0.729583740234375 +49020 -0.86688232421875 +49021 -0.870391845703125 +49022 -0.86859130859375 +49023 -0.86279296875 +49024 -0.817962646484375 +49025 -0.6116943359375 +49026 -0.3128662109375 +49027 0.039398193359375 +49028 0.422821044921875 +49029 0.805145263671875 +49030 0.870361328125 +49031 0.870361328125 +49032 0.860015869140625 +49033 0.727935791015625 +49034 0.48114013671875 +49035 0.2059326171875 +49036 -0.06103515625 +49037 -0.29913330078125 +49038 -0.516204833984375 +49039 -0.7252197265625 +49040 -0.85980224609375 +49041 -0.870391845703125 +49042 -0.870391845703125 +49043 -0.858062744140625 +49044 -0.673004150390625 +49045 -0.42694091796875 +49046 -0.2100830078125 +49047 -0.0362548828125 +49048 0.10943603515625 +49049 0.23516845703125 +49050 0.373687744140625 +49051 0.517791748046875 +49052 0.602783203125 +49053 0.635711669921875 +49054 0.655181884765625 +49055 0.65948486328125 +49056 0.651275634765625 +49057 0.61846923828125 +49058 0.53753662109375 +49059 0.404144287109375 +49060 0.22186279296875 +49061 0.003997802734375 +49062 -0.22100830078125 +49063 -0.42449951171875 +49064 -0.579833984375 +49065 -0.641876220703125 +49066 -0.6177978515625 +49067 -0.575531005859375 +49068 -0.526336669921875 +49069 -0.42645263671875 +49070 -0.2581787109375 +49071 -0.068695068359375 +49072 0.09222412109375 +49073 0.232147216796875 +49074 0.3509521484375 +49075 0.410064697265625 +49076 0.372955322265625 +49077 0.2554931640625 +49078 0.10711669921875 +49079 -0.052886962890625 +49080 -0.186279296875 +49081 -0.23291015625 +49082 -0.209442138671875 +49083 -0.174163818359375 +49084 -0.126739501953125 +49085 -0.048126220703125 +49086 0.0426025390625 +49087 0.10748291015625 +49088 0.1409912109375 +49089 0.19708251953125 +49090 0.273651123046875 +49091 0.31768798828125 +49092 0.341094970703125 +49093 0.368011474609375 +49094 0.37249755859375 +49095 0.30072021484375 +49096 0.1517333984375 +49097 -0.01470947265625 +49098 -0.1883544921875 +49099 -0.372711181640625 +49100 -0.51397705078125 +49101 -0.57177734375 +49102 -0.53948974609375 +49103 -0.43511962890625 +49104 -0.2962646484375 +49105 -0.161102294921875 +49106 -0.0435791015625 +49107 0.060394287109375 +49108 0.13665771484375 +49109 0.170135498046875 +49110 0.16552734375 +49111 0.15728759765625 +49112 0.150787353515625 +49113 0.12200927734375 +49114 0.080108642578125 +49115 0.05126953125 +49116 0.062896728515625 +49117 0.09271240234375 +49118 0.092987060546875 +49119 0.07855224609375 +49120 0.06427001953125 +49121 0.0347900390625 +49122 -0.01171875 +49123 -0.056060791015625 +49124 -0.055511474609375 +49125 -0.010467529296875 +49126 0.02508544921875 +49127 0.025665283203125 +49128 0.017333984375 +49129 0.00189208984375 +49130 -0.03173828125 +49131 -0.071502685546875 +49132 -0.13543701171875 +49133 -0.219970703125 +49134 -0.300506591796875 +49135 -0.376312255859375 +49136 -0.416107177734375 +49137 -0.371124267578125 +49138 -0.242279052734375 +49139 -0.069732666015625 +49140 0.125640869140625 +49141 0.31268310546875 +49142 0.45501708984375 +49143 0.554779052734375 +49144 0.61065673828125 +49145 0.610931396484375 +49146 0.531463623046875 +49147 0.3883056640625 +49148 0.23468017578125 +49149 0.095245361328125 +49150 -0.00396728515625 +49151 -0.04852294921875 +49152 -0.055145263671875 +49153 -0.0758056640625 +49154 -0.138702392578125 +49155 -0.209197998046875 +49156 -0.289031982421875 +49157 -0.37884521484375 +49158 -0.456329345703125 +49159 -0.51641845703125 +49160 -0.519287109375 +49161 -0.458251953125 +49162 -0.384796142578125 +49163 -0.323699951171875 +49164 -0.269287109375 +49165 -0.1951904296875 +49166 -0.100006103515625 +49167 -0.01055908203125 +49168 0.1033935546875 +49169 0.24908447265625 +49170 0.373199462890625 +49171 0.45806884765625 +49172 0.511474609375 +49173 0.565399169921875 +49174 0.61138916015625 +49175 0.5897216796875 +49176 0.4906005859375 +49177 0.33148193359375 +49178 0.147796630859375 +49179 -0.01873779296875 +49180 -0.140289306640625 +49181 -0.191986083984375 +49182 -0.184295654296875 +49183 -0.161834716796875 +49184 -0.166595458984375 +49185 -0.19390869140625 +49186 -0.22442626953125 +49187 -0.279754638671875 +49188 -0.3389892578125 +49189 -0.3543701171875 +49190 -0.348175048828125 +49191 -0.32598876953125 +49192 -0.2581787109375 +49193 -0.139801025390625 +49194 0.014617919921875 +49195 0.144378662109375 +49196 0.221038818359375 +49197 0.27069091796875 +49198 0.294036865234375 +49199 0.311767578125 +49200 0.339141845703125 +49201 0.360260009765625 +49202 0.360504150390625 +49203 0.308380126953125 +49204 0.18170166015625 +49205 0.0047607421875 +49206 -0.17559814453125 +49207 -0.3143310546875 +49208 -0.36785888671875 +49209 -0.36248779296875 +49210 -0.343536376953125 +49211 -0.3018798828125 +49212 -0.231414794921875 +49213 -0.117645263671875 +49214 0.007049560546875 +49215 0.087982177734375 +49216 0.13946533203125 +49217 0.17425537109375 +49218 0.188201904296875 +49219 0.171234130859375 +49220 0.118438720703125 +49221 0.05706787109375 +49222 -0.010711669921875 +49223 -0.0914306640625 +49224 -0.162322998046875 +49225 -0.194549560546875 +49226 -0.1492919921875 +49227 -0.02166748046875 +49228 0.124053955078125 +49229 0.211151123046875 +49230 0.240447998046875 +49231 0.242218017578125 +49232 0.2257080078125 +49233 0.194366455078125 +49234 0.115509033203125 +49235 0.0128173828125 +49236 -0.053802490234375 +49237 -0.110626220703125 +49238 -0.199493408203125 +49239 -0.29437255859375 +49240 -0.33221435546875 +49241 -0.27972412109375 +49242 -0.185333251953125 +49243 -0.128204345703125 +49244 -0.115692138671875 +49245 -0.116455078125 +49246 -0.105926513671875 +49247 -0.053955078125 +49248 0.048797607421875 +49249 0.157318115234375 +49250 0.212005615234375 +49251 0.218475341796875 +49252 0.23724365234375 +49253 0.30535888671875 +49254 0.38128662109375 +49255 0.404449462890625 +49256 0.3944091796875 +49257 0.3885498046875 +49258 0.362640380859375 +49259 0.27362060546875 +49260 0.11712646484375 +49261 -0.054901123046875 +49262 -0.19085693359375 +49263 -0.28570556640625 +49264 -0.339263916015625 +49265 -0.3775634765625 +49266 -0.445709228515625 +49267 -0.535064697265625 +49268 -0.629058837890625 +49269 -0.697601318359375 +49270 -0.70391845703125 +49271 -0.6424560546875 +49272 -0.491241455078125 +49273 -0.265716552734375 +49274 -0.023712158203125 +49275 0.201751708984375 +49276 0.375823974609375 +49277 0.485076904296875 +49278 0.56884765625 +49279 0.634765625 +49280 0.63763427734375 +49281 0.5660400390625 +49282 0.4720458984375 +49283 0.40692138671875 +49284 0.3778076171875 +49285 0.376953125 +49286 0.371978759765625 +49287 0.313140869140625 +49288 0.184417724609375 +49289 0.011199951171875 +49290 -0.171051025390625 +49291 -0.33740234375 +49292 -0.47198486328125 +49293 -0.560394287109375 +49294 -0.58056640625 +49295 -0.54754638671875 +49296 -0.508575439453125 +49297 -0.459503173828125 +49298 -0.394378662109375 +49299 -0.35260009765625 +49300 -0.31170654296875 +49301 -0.197418212890625 +49302 -0.007965087890625 +49303 0.207489013671875 +49304 0.409210205078125 +49305 0.57208251953125 +49306 0.66595458984375 +49307 0.65875244140625 +49308 0.56744384765625 +49309 0.431396484375 +49310 0.29443359375 +49311 0.182464599609375 +49312 0.06365966796875 +49313 -0.075958251953125 +49314 -0.189422607421875 +49315 -0.271942138671875 +49316 -0.342529296875 +49317 -0.364166259765625 +49318 -0.327239990234375 +49319 -0.2769775390625 +49320 -0.253692626953125 +49321 -0.24365234375 +49322 -0.1983642578125 +49323 -0.116241455078125 +49324 -0.036834716796875 +49325 0.034881591796875 +49326 0.09124755859375 +49327 0.10888671875 +49328 0.125518798828125 +49329 0.15771484375 +49330 0.17828369140625 +49331 0.17108154296875 +49332 0.129974365234375 +49333 0.082427978515625 +49334 0.027679443359375 +49335 -0.065643310546875 +49336 -0.15936279296875 +49337 -0.21307373046875 +49338 -0.234649658203125 +49339 -0.2001953125 +49340 -0.119171142578125 +49341 -0.024749755859375 +49342 0.085784912109375 +49343 0.178131103515625 +49344 0.215576171875 +49345 0.211456298828125 +49346 0.17523193359375 +49347 0.128753662109375 +49348 0.1019287109375 +49349 0.0743408203125 +49350 0.04327392578125 +49351 0.038177490234375 +49352 0.076263427734375 +49353 0.14105224609375 +49354 0.186431884765625 +49355 0.188812255859375 +49356 0.1390380859375 +49357 0.041778564453125 +49358 -0.079437255859375 +49359 -0.219390869140625 +49360 -0.367828369140625 +49361 -0.494873046875 +49362 -0.556243896484375 +49363 -0.508697509765625 +49364 -0.3756103515625 +49365 -0.218902587890625 +49366 -0.063751220703125 +49367 0.091552734375 +49368 0.23602294921875 +49369 0.342987060546875 +49370 0.39520263671875 +49371 0.389373779296875 +49372 0.324249267578125 +49373 0.224090576171875 +49374 0.124267578125 +49375 0.037078857421875 +49376 -0.010101318359375 +49377 -0.019439697265625 +49378 -0.022796630859375 +49379 -0.001556396484375 +49380 0.056304931640625 +49381 0.106719970703125 +49382 0.096893310546875 +49383 0.042694091796875 +49384 -0.018035888671875 +49385 -0.07586669921875 +49386 -0.11944580078125 +49387 -0.15972900390625 +49388 -0.202606201171875 +49389 -0.24859619140625 +49390 -0.30517578125 +49391 -0.36212158203125 +49392 -0.39141845703125 +49393 -0.35528564453125 +49394 -0.249969482421875 +49395 -0.092864990234375 +49396 0.08905029296875 +49397 0.2352294921875 +49398 0.318817138671875 +49399 0.358642578125 +49400 0.347747802734375 +49401 0.28564453125 +49402 0.223175048828125 +49403 0.196746826171875 +49404 0.179840087890625 +49405 0.155548095703125 +49406 0.151214599609375 +49407 0.156951904296875 +49408 0.13177490234375 +49409 0.100799560546875 +49410 0.087127685546875 +49411 0.05487060546875 +49412 -0.009002685546875 +49413 -0.10400390625 +49414 -0.229400634765625 +49415 -0.35552978515625 +49416 -0.441925048828125 +49417 -0.473846435546875 +49418 -0.464813232421875 +49419 -0.419097900390625 +49420 -0.334320068359375 +49421 -0.227935791015625 +49422 -0.12347412109375 +49423 -0.02764892578125 +49424 0.077667236328125 +49425 0.2132568359375 +49426 0.38885498046875 +49427 0.582794189453125 +49428 0.734039306640625 +49429 0.800140380859375 +49430 0.7783203125 +49431 0.6651611328125 +49432 0.45965576171875 +49433 0.199188232421875 +49434 -0.050689697265625 +49435 -0.23297119140625 +49436 -0.33013916015625 +49437 -0.368408203125 +49438 -0.378936767578125 +49439 -0.376983642578125 +49440 -0.37969970703125 +49441 -0.391510009765625 +49442 -0.385345458984375 +49443 -0.3419189453125 +49444 -0.28289794921875 +49445 -0.251617431640625 +49446 -0.266143798828125 +49447 -0.273345947265625 +49448 -0.216796875 +49449 -0.128265380859375 +49450 -0.068145751953125 +49451 -0.0430908203125 +49452 -0.024444580078125 +49453 0.020721435546875 +49454 0.124481201171875 +49455 0.25787353515625 +49456 0.379119873046875 +49457 0.47991943359375 +49458 0.5281982421875 +49459 0.511138916015625 +49460 0.456207275390625 +49461 0.407470703125 +49462 0.383758544921875 +49463 0.35687255859375 +49464 0.31182861328125 +49465 0.250885009765625 +49466 0.1654052734375 +49467 0.035247802734375 +49468 -0.142059326171875 +49469 -0.33563232421875 +49470 -0.5345458984375 +49471 -0.72186279296875 +49472 -0.836669921875 +49473 -0.8326416015625 +49474 -0.7296142578125 +49475 -0.582550048828125 +49476 -0.440093994140625 +49477 -0.324310302734375 +49478 -0.20147705078125 +49479 -0.044647216796875 +49480 0.103973388671875 +49481 0.202392578125 +49482 0.264495849609375 +49483 0.338897705078125 +49484 0.443817138671875 +49485 0.545074462890625 +49486 0.6173095703125 +49487 0.6524658203125 +49488 0.66339111328125 +49489 0.6561279296875 +49490 0.606781005859375 +49491 0.501190185546875 +49492 0.352783203125 +49493 0.176544189453125 +49494 -0.034820556640625 +49495 -0.258209228515625 +49496 -0.44244384765625 +49497 -0.5753173828125 +49498 -0.65203857421875 +49499 -0.641632080078125 +49500 -0.562164306640625 +49501 -0.458038330078125 +49502 -0.350555419921875 +49503 -0.260528564453125 +49504 -0.192108154296875 +49505 -0.141937255859375 +49506 -0.1021728515625 +49507 -0.062896728515625 +49508 -0.011932373046875 +49509 0.062835693359375 +49510 0.148712158203125 +49511 0.241729736328125 +49512 0.34912109375 +49513 0.457305908203125 +49514 0.54388427734375 +49515 0.5728759765625 +49516 0.506591796875 +49517 0.351226806640625 +49518 0.146514892578125 +49519 -0.05523681640625 +49520 -0.21624755859375 +49521 -0.334930419921875 +49522 -0.402984619140625 +49523 -0.4412841796875 +49524 -0.49578857421875 +49525 -0.5601806640625 +49526 -0.600738525390625 +49527 -0.584228515625 +49528 -0.47930908203125 +49529 -0.27935791015625 +49530 -0.0089111328125 +49531 0.268798828125 +49532 0.482818603515625 +49533 0.60369873046875 +49534 0.650421142578125 +49535 0.66400146484375 +49536 0.6414794921875 +49537 0.572540283203125 +49538 0.498138427734375 +49539 0.439453125 +49540 0.375518798828125 +49541 0.274505615234375 +49542 0.1087646484375 +49543 -0.099395751953125 +49544 -0.3182373046875 +49545 -0.5489501953125 +49546 -0.7738037109375 +49547 -0.86383056640625 +49548 -0.870391845703125 +49549 -0.86895751953125 +49550 -0.861053466796875 +49551 -0.765869140625 +49552 -0.5301513671875 +49553 -0.214691162109375 +49554 0.137359619140625 +49555 0.474822998046875 +49556 0.76239013671875 +49557 0.867462158203125 +49558 0.870361328125 +49559 0.86480712890625 +49560 0.831817626953125 +49561 0.677581787109375 +49562 0.495880126953125 +49563 0.30767822265625 +49564 0.116180419921875 +49565 -0.110748291015625 +49566 -0.381805419921875 +49567 -0.6572265625 +49568 -0.857421875 +49569 -0.870391845703125 +49570 -0.870391845703125 +49571 -0.86444091796875 +49572 -0.85723876953125 +49573 -0.790008544921875 +49574 -0.62847900390625 +49575 -0.3956298828125 +49576 -0.126708984375 +49577 0.150115966796875 +49578 0.424041748046875 +49579 0.670623779296875 +49580 0.854522705078125 +49581 0.866485595703125 +49582 0.86920166015625 +49583 0.8653564453125 +49584 0.857147216796875 +49585 0.766845703125 +49586 0.628509521484375 +49587 0.462127685546875 +49588 0.297210693359375 +49589 0.14862060546875 +49590 -0.00537109375 +49591 -0.15753173828125 +49592 -0.31304931640625 +49593 -0.48876953125 +49594 -0.6416015625 +49595 -0.751373291015625 +49596 -0.84619140625 +49597 -0.861297607421875 +49598 -0.863250732421875 +49599 -0.856597900390625 +49600 -0.7498779296875 +49601 -0.624542236328125 +49602 -0.47808837890625 +49603 -0.253387451171875 +49604 0.003692626953125 +49605 0.2257080078125 +49606 0.427154541015625 +49607 0.643218994140625 +49608 0.855926513671875 +49609 0.870361328125 +49610 0.870361328125 +49611 0.862762451171875 +49612 0.79669189453125 +49613 0.595794677734375 +49614 0.362152099609375 +49615 0.1270751953125 +49616 -0.086944580078125 +49617 -0.2784423828125 +49618 -0.484832763671875 +49619 -0.729583740234375 +49620 -0.86688232421875 +49621 -0.870391845703125 +49622 -0.86859130859375 +49623 -0.86279296875 +49624 -0.817962646484375 +49625 -0.6116943359375 +49626 -0.3128662109375 +49627 0.039398193359375 +49628 0.422821044921875 +49629 0.805145263671875 +49630 0.870361328125 +49631 0.870361328125 +49632 0.860015869140625 +49633 0.727935791015625 +49634 0.48114013671875 +49635 0.2059326171875 +49636 -0.06103515625 +49637 -0.29913330078125 +49638 -0.516204833984375 +49639 -0.7252197265625 +49640 -0.85980224609375 +49641 -0.870391845703125 +49642 -0.870391845703125 +49643 -0.858062744140625 +49644 -0.673004150390625 +49645 -0.42694091796875 +49646 -0.2100830078125 +49647 -0.0362548828125 +49648 0.10943603515625 +49649 0.23516845703125 +49650 0.373687744140625 +49651 0.517791748046875 +49652 0.602783203125 +49653 0.635711669921875 +49654 0.655181884765625 +49655 0.65948486328125 +49656 0.651275634765625 +49657 0.61846923828125 +49658 0.53753662109375 +49659 0.404144287109375 +49660 0.22186279296875 +49661 0.003997802734375 +49662 -0.22100830078125 +49663 -0.42449951171875 +49664 -0.579833984375 +49665 -0.641876220703125 +49666 -0.6177978515625 +49667 -0.575531005859375 +49668 -0.526336669921875 +49669 -0.42645263671875 +49670 -0.2581787109375 +49671 -0.068695068359375 +49672 0.09222412109375 +49673 0.232147216796875 +49674 0.3509521484375 +49675 0.410064697265625 +49676 0.372955322265625 +49677 0.2554931640625 +49678 0.10711669921875 +49679 -0.052886962890625 +49680 -0.186279296875 +49681 -0.23291015625 +49682 -0.209442138671875 +49683 -0.174163818359375 +49684 -0.126739501953125 +49685 -0.048126220703125 +49686 0.0426025390625 +49687 0.10748291015625 +49688 0.1409912109375 +49689 0.19708251953125 +49690 0.273651123046875 +49691 0.31768798828125 +49692 0.341094970703125 +49693 0.368011474609375 +49694 0.37249755859375 +49695 0.30072021484375 +49696 0.1517333984375 +49697 -0.01470947265625 +49698 -0.1883544921875 +49699 -0.372711181640625 +49700 -0.51397705078125 +49701 -0.57177734375 +49702 -0.53948974609375 +49703 -0.43511962890625 +49704 -0.2962646484375 +49705 -0.161102294921875 +49706 -0.0435791015625 +49707 0.060394287109375 +49708 0.13665771484375 +49709 0.170135498046875 +49710 0.16552734375 +49711 0.15728759765625 +49712 0.150787353515625 +49713 0.12200927734375 +49714 0.080108642578125 +49715 0.05126953125 +49716 0.062896728515625 +49717 0.09271240234375 +49718 0.092987060546875 +49719 0.07855224609375 +49720 0.06427001953125 +49721 0.0347900390625 +49722 -0.01171875 +49723 -0.056060791015625 +49724 -0.055511474609375 +49725 -0.010467529296875 +49726 0.02508544921875 +49727 0.025665283203125 +49728 0.017333984375 +49729 0.00189208984375 +49730 -0.03173828125 +49731 -0.071502685546875 +49732 -0.13543701171875 +49733 -0.219970703125 +49734 -0.300506591796875 +49735 -0.376312255859375 +49736 -0.416107177734375 +49737 -0.371124267578125 +49738 -0.242279052734375 +49739 -0.069732666015625 +49740 0.125640869140625 +49741 0.31268310546875 +49742 0.45501708984375 +49743 0.554779052734375 +49744 0.61065673828125 +49745 0.610931396484375 +49746 0.531463623046875 +49747 0.3883056640625 +49748 0.23468017578125 +49749 0.095245361328125 +49750 -0.00396728515625 +49751 -0.04852294921875 +49752 -0.055145263671875 +49753 -0.0758056640625 +49754 -0.138702392578125 +49755 -0.209197998046875 +49756 -0.289031982421875 +49757 -0.37884521484375 +49758 -0.456329345703125 +49759 -0.51641845703125 +49760 -0.519287109375 +49761 -0.458251953125 +49762 -0.384796142578125 +49763 -0.323699951171875 +49764 -0.269287109375 +49765 -0.1951904296875 +49766 -0.100006103515625 +49767 -0.01055908203125 +49768 0.1033935546875 +49769 0.24908447265625 +49770 0.373199462890625 +49771 0.45806884765625 +49772 0.511474609375 +49773 0.565399169921875 +49774 0.61138916015625 +49775 0.5897216796875 +49776 0.4906005859375 +49777 0.33148193359375 +49778 0.147796630859375 +49779 -0.01873779296875 +49780 -0.140289306640625 +49781 -0.191986083984375 +49782 -0.184295654296875 +49783 -0.161834716796875 +49784 -0.166595458984375 +49785 -0.19390869140625 +49786 -0.22442626953125 +49787 -0.279754638671875 +49788 -0.3389892578125 +49789 -0.3543701171875 +49790 -0.348175048828125 +49791 -0.32598876953125 +49792 -0.2581787109375 +49793 -0.139801025390625 +49794 0.014617919921875 +49795 0.144378662109375 +49796 0.221038818359375 +49797 0.27069091796875 +49798 0.294036865234375 +49799 0.311767578125 +49800 0.339141845703125 +49801 0.360260009765625 +49802 0.360504150390625 +49803 0.308380126953125 +49804 0.18170166015625 +49805 0.0047607421875 +49806 -0.17559814453125 +49807 -0.3143310546875 +49808 -0.36785888671875 +49809 -0.36248779296875 +49810 -0.343536376953125 +49811 -0.3018798828125 +49812 -0.231414794921875 +49813 -0.117645263671875 +49814 0.007049560546875 +49815 0.087982177734375 +49816 0.13946533203125 +49817 0.17425537109375 +49818 0.188201904296875 +49819 0.171234130859375 +49820 0.118438720703125 +49821 0.05706787109375 +49822 -0.010711669921875 +49823 -0.0914306640625 +49824 -0.162322998046875 +49825 -0.194549560546875 +49826 -0.1492919921875 +49827 -0.02166748046875 +49828 0.124053955078125 +49829 0.211151123046875 +49830 0.240447998046875 +49831 0.242218017578125 +49832 0.2257080078125 +49833 0.194366455078125 +49834 0.115509033203125 +49835 0.0128173828125 +49836 -0.053802490234375 +49837 -0.110626220703125 +49838 -0.199493408203125 +49839 -0.29437255859375 +49840 -0.33221435546875 +49841 -0.27972412109375 +49842 -0.185333251953125 +49843 -0.128204345703125 +49844 -0.115692138671875 +49845 -0.116455078125 +49846 -0.105926513671875 +49847 -0.053955078125 +49848 0.048797607421875 +49849 0.157318115234375 +49850 0.212005615234375 +49851 0.218475341796875 +49852 0.23724365234375 +49853 0.30535888671875 +49854 0.38128662109375 +49855 0.404449462890625 +49856 0.3944091796875 +49857 0.3885498046875 +49858 0.362640380859375 +49859 0.27362060546875 +49860 0.11712646484375 +49861 -0.054901123046875 +49862 -0.19085693359375 +49863 -0.28570556640625 +49864 -0.339263916015625 +49865 -0.3775634765625 +49866 -0.445709228515625 +49867 -0.535064697265625 +49868 -0.629058837890625 +49869 -0.697601318359375 +49870 -0.70391845703125 +49871 -0.6424560546875 +49872 -0.491241455078125 +49873 -0.265716552734375 +49874 -0.023712158203125 +49875 0.201751708984375 +49876 0.375823974609375 +49877 0.485076904296875 +49878 0.56884765625 +49879 0.634765625 +49880 0.63763427734375 +49881 0.5660400390625 +49882 0.4720458984375 +49883 0.40692138671875 +49884 0.3778076171875 +49885 0.376953125 +49886 0.371978759765625 +49887 0.313140869140625 +49888 0.184417724609375 +49889 0.011199951171875 +49890 -0.171051025390625 +49891 -0.33740234375 +49892 -0.47198486328125 +49893 -0.560394287109375 +49894 -0.58056640625 +49895 -0.54754638671875 +49896 -0.508575439453125 +49897 -0.459503173828125 +49898 -0.394378662109375 +49899 -0.35260009765625 +49900 -0.31170654296875 +49901 -0.197418212890625 +49902 -0.007965087890625 +49903 0.207489013671875 +49904 0.409210205078125 +49905 0.57208251953125 +49906 0.66595458984375 +49907 0.65875244140625 +49908 0.56744384765625 +49909 0.431396484375 +49910 0.29443359375 +49911 0.182464599609375 +49912 0.06365966796875 +49913 -0.075958251953125 +49914 -0.189422607421875 +49915 -0.271942138671875 +49916 -0.342529296875 +49917 -0.364166259765625 +49918 -0.327239990234375 +49919 -0.2769775390625 +49920 -0.253692626953125 +49921 -0.24365234375 +49922 -0.1983642578125 +49923 -0.116241455078125 +49924 -0.036834716796875 +49925 0.034881591796875 +49926 0.09124755859375 +49927 0.10888671875 +49928 0.125518798828125 +49929 0.15771484375 +49930 0.17828369140625 +49931 0.17108154296875 +49932 0.129974365234375 +49933 0.082427978515625 +49934 0.027679443359375 +49935 -0.065643310546875 +49936 -0.15936279296875 +49937 -0.21307373046875 +49938 -0.234649658203125 +49939 -0.2001953125 +49940 -0.119171142578125 +49941 -0.024749755859375 +49942 0.085784912109375 +49943 0.178131103515625 +49944 0.215576171875 +49945 0.211456298828125 +49946 0.17523193359375 +49947 0.128753662109375 +49948 0.1019287109375 +49949 0.0743408203125 +49950 0.04327392578125 +49951 0.038177490234375 +49952 0.076263427734375 +49953 0.14105224609375 +49954 0.186431884765625 +49955 0.188812255859375 +49956 0.1390380859375 +49957 0.041778564453125 +49958 -0.079437255859375 +49959 -0.219390869140625 +49960 -0.367828369140625 +49961 -0.494873046875 +49962 -0.556243896484375 +49963 -0.508697509765625 +49964 -0.3756103515625 +49965 -0.218902587890625 +49966 -0.063751220703125 +49967 0.091552734375 +49968 0.23602294921875 +49969 0.342987060546875 +49970 0.39520263671875 +49971 0.389373779296875 +49972 0.324249267578125 +49973 0.224090576171875 +49974 0.124267578125 +49975 0.037078857421875 +49976 -0.010101318359375 +49977 -0.019439697265625 +49978 -0.022796630859375 +49979 -0.001556396484375 +49980 0.056304931640625 +49981 0.106719970703125 +49982 0.096893310546875 +49983 0.042694091796875 +49984 -0.018035888671875 +49985 -0.07586669921875 +49986 -0.11944580078125 +49987 -0.15972900390625 +49988 -0.202606201171875 +49989 -0.24859619140625 +49990 -0.30517578125 +49991 -0.36212158203125 +49992 -0.39141845703125 +49993 -0.35528564453125 +49994 -0.249969482421875 +49995 -0.092864990234375 +49996 0.08905029296875 +49997 0.2352294921875 +49998 0.318817138671875 +49999 0.358642578125 +50000 0.347747802734375 +50001 0.28564453125 +50002 0.223175048828125 +50003 0.196746826171875 +50004 0.179840087890625 +50005 0.155548095703125 +50006 0.151214599609375 +50007 0.156951904296875 +50008 0.13177490234375 +50009 0.100799560546875 +50010 0.087127685546875 +50011 0.05487060546875 +50012 -0.009002685546875 +50013 -0.10400390625 +50014 -0.229400634765625 +50015 -0.35552978515625 +50016 -0.441925048828125 +50017 -0.473846435546875 +50018 -0.464813232421875 +50019 -0.419097900390625 +50020 -0.334320068359375 +50021 -0.227935791015625 +50022 -0.12347412109375 +50023 -0.02764892578125 +50024 0.077667236328125 +50025 0.2132568359375 +50026 0.38885498046875 +50027 0.582794189453125 +50028 0.734039306640625 +50029 0.800140380859375 +50030 0.7783203125 +50031 0.6651611328125 +50032 0.45965576171875 +50033 0.199188232421875 +50034 -0.050689697265625 +50035 -0.23297119140625 +50036 -0.33013916015625 +50037 -0.368408203125 +50038 -0.378936767578125 +50039 -0.376983642578125 +50040 -0.37969970703125 +50041 -0.391510009765625 +50042 -0.385345458984375 +50043 -0.3419189453125 +50044 -0.28289794921875 +50045 -0.251617431640625 +50046 -0.266143798828125 +50047 -0.273345947265625 +50048 -0.216796875 +50049 -0.128265380859375 +50050 -0.068145751953125 +50051 -0.0430908203125 +50052 -0.024444580078125 +50053 0.020721435546875 +50054 0.124481201171875 +50055 0.25787353515625 +50056 0.379119873046875 +50057 0.47991943359375 +50058 0.5281982421875 +50059 0.511138916015625 +50060 0.456207275390625 +50061 0.407470703125 +50062 0.383758544921875 +50063 0.35687255859375 +50064 0.31182861328125 +50065 0.250885009765625 +50066 0.1654052734375 +50067 0.035247802734375 +50068 -0.142059326171875 +50069 -0.33563232421875 +50070 -0.5345458984375 +50071 -0.72186279296875 +50072 -0.836669921875 +50073 -0.8326416015625 +50074 -0.7296142578125 +50075 -0.582550048828125 +50076 -0.440093994140625 +50077 -0.324310302734375 +50078 -0.20147705078125 +50079 -0.044647216796875 +50080 0.103973388671875 +50081 0.202392578125 +50082 0.264495849609375 +50083 0.338897705078125 +50084 0.443817138671875 +50085 0.545074462890625 +50086 0.6173095703125 +50087 0.6524658203125 +50088 0.66339111328125 +50089 0.6561279296875 +50090 0.606781005859375 +50091 0.501190185546875 +50092 0.352783203125 +50093 0.176544189453125 +50094 -0.034820556640625 +50095 -0.258209228515625 +50096 -0.44244384765625 +50097 -0.5753173828125 +50098 -0.65203857421875 +50099 -0.641632080078125 +50100 -0.562164306640625 +50101 -0.458038330078125 +50102 -0.350555419921875 +50103 -0.260528564453125 +50104 -0.192108154296875 +50105 -0.141937255859375 +50106 -0.1021728515625 +50107 -0.062896728515625 +50108 -0.011932373046875 +50109 0.062835693359375 +50110 0.148712158203125 +50111 0.241729736328125 +50112 0.34912109375 +50113 0.457305908203125 +50114 0.54388427734375 +50115 0.5728759765625 +50116 0.506591796875 +50117 0.351226806640625 +50118 0.146514892578125 +50119 -0.05523681640625 +50120 -0.21624755859375 +50121 -0.334930419921875 +50122 -0.402984619140625 +50123 -0.4412841796875 +50124 -0.49578857421875 +50125 -0.5601806640625 +50126 -0.600738525390625 +50127 -0.584228515625 +50128 -0.47930908203125 +50129 -0.27935791015625 +50130 -0.0089111328125 +50131 0.268798828125 +50132 0.482818603515625 +50133 0.60369873046875 +50134 0.650421142578125 +50135 0.66400146484375 +50136 0.6414794921875 +50137 0.572540283203125 +50138 0.498138427734375 +50139 0.439453125 +50140 0.375518798828125 +50141 0.274505615234375 +50142 0.1087646484375 +50143 -0.099395751953125 +50144 -0.3182373046875 +50145 -0.5489501953125 +50146 -0.7738037109375 +50147 -0.86383056640625 +50148 -0.870391845703125 +50149 -0.86895751953125 +50150 -0.861053466796875 +50151 -0.765869140625 +50152 -0.5301513671875 +50153 -0.214691162109375 +50154 0.137359619140625 +50155 0.474822998046875 +50156 0.76239013671875 +50157 0.867462158203125 +50158 0.870361328125 +50159 0.86480712890625 +50160 0.831817626953125 +50161 0.677581787109375 +50162 0.495880126953125 +50163 0.30767822265625 +50164 0.116180419921875 +50165 -0.110748291015625 +50166 -0.381805419921875 +50167 -0.6572265625 +50168 -0.857421875 +50169 -0.870391845703125 +50170 -0.870391845703125 +50171 -0.86444091796875 +50172 -0.85723876953125 +50173 -0.790008544921875 +50174 -0.62847900390625 +50175 -0.3956298828125 +50176 -0.126708984375 +50177 0.150115966796875 +50178 0.424041748046875 +50179 0.670623779296875 +50180 0.854522705078125 +50181 0.866485595703125 +50182 0.86920166015625 +50183 0.8653564453125 +50184 0.857147216796875 +50185 0.766845703125 +50186 0.628509521484375 +50187 0.462127685546875 +50188 0.297210693359375 +50189 0.14862060546875 +50190 -0.00537109375 +50191 -0.15753173828125 +50192 -0.31304931640625 +50193 -0.48876953125 +50194 -0.6416015625 +50195 -0.751373291015625 +50196 -0.84619140625 +50197 -0.861297607421875 +50198 -0.863250732421875 +50199 -0.856597900390625 +50200 -0.7498779296875 +50201 -0.624542236328125 +50202 -0.47808837890625 +50203 -0.253387451171875 +50204 0.003692626953125 +50205 0.2257080078125 +50206 0.427154541015625 +50207 0.643218994140625 +50208 0.855926513671875 +50209 0.870361328125 +50210 0.870361328125 +50211 0.862762451171875 +50212 0.79669189453125 +50213 0.595794677734375 +50214 0.362152099609375 +50215 0.1270751953125 +50216 -0.086944580078125 +50217 -0.2784423828125 +50218 -0.484832763671875 +50219 -0.729583740234375 +50220 -0.86688232421875 +50221 -0.870391845703125 +50222 -0.86859130859375 +50223 -0.86279296875 +50224 -0.817962646484375 +50225 -0.6116943359375 +50226 -0.3128662109375 +50227 0.039398193359375 +50228 0.422821044921875 +50229 0.805145263671875 +50230 0.870361328125 +50231 0.870361328125 +50232 0.860015869140625 +50233 0.727935791015625 +50234 0.48114013671875 +50235 0.2059326171875 +50236 -0.06103515625 +50237 -0.29913330078125 +50238 -0.516204833984375 +50239 -0.7252197265625 +50240 -0.85980224609375 +50241 -0.870391845703125 +50242 -0.870391845703125 +50243 -0.858062744140625 +50244 -0.673004150390625 +50245 -0.42694091796875 +50246 -0.2100830078125 +50247 -0.0362548828125 +50248 0.10943603515625 +50249 0.23516845703125 +50250 0.373687744140625 +50251 0.517791748046875 +50252 0.602783203125 +50253 0.635711669921875 +50254 0.655181884765625 +50255 0.65948486328125 +50256 0.651275634765625 +50257 0.61846923828125 +50258 0.53753662109375 +50259 0.404144287109375 +50260 0.22186279296875 +50261 0.003997802734375 +50262 -0.22100830078125 +50263 -0.42449951171875 +50264 -0.579833984375 +50265 -0.641876220703125 +50266 -0.6177978515625 +50267 -0.575531005859375 +50268 -0.526336669921875 +50269 -0.42645263671875 +50270 -0.2581787109375 +50271 -0.068695068359375 +50272 0.09222412109375 +50273 0.232147216796875 +50274 0.3509521484375 +50275 0.410064697265625 +50276 0.372955322265625 +50277 0.2554931640625 +50278 0.10711669921875 +50279 -0.052886962890625 +50280 -0.186279296875 +50281 -0.23291015625 +50282 -0.209442138671875 +50283 -0.174163818359375 +50284 -0.126739501953125 +50285 -0.048126220703125 +50286 0.0426025390625 +50287 0.10748291015625 +50288 0.1409912109375 +50289 0.19708251953125 +50290 0.273651123046875 +50291 0.31768798828125 +50292 0.341094970703125 +50293 0.368011474609375 +50294 0.37249755859375 +50295 0.30072021484375 +50296 0.1517333984375 +50297 -0.01470947265625 +50298 -0.1883544921875 +50299 -0.372711181640625 +50300 -0.51397705078125 +50301 -0.57177734375 +50302 -0.53948974609375 +50303 -0.43511962890625 +50304 -0.2962646484375 +50305 -0.161102294921875 +50306 -0.0435791015625 +50307 0.060394287109375 +50308 0.13665771484375 +50309 0.170135498046875 +50310 0.16552734375 +50311 0.15728759765625 +50312 0.150787353515625 +50313 0.12200927734375 +50314 0.080108642578125 +50315 0.05126953125 +50316 0.062896728515625 +50317 0.09271240234375 +50318 0.092987060546875 +50319 0.07855224609375 +50320 0.06427001953125 +50321 0.0347900390625 +50322 -0.01171875 +50323 -0.056060791015625 +50324 -0.055511474609375 +50325 -0.010467529296875 +50326 0.02508544921875 +50327 0.025665283203125 +50328 0.017333984375 +50329 0.00189208984375 +50330 -0.03173828125 +50331 -0.071502685546875 +50332 -0.13543701171875 +50333 -0.219970703125 +50334 -0.300506591796875 +50335 -0.376312255859375 +50336 -0.416107177734375 +50337 -0.371124267578125 +50338 -0.242279052734375 +50339 -0.069732666015625 +50340 0.125640869140625 +50341 0.31268310546875 +50342 0.45501708984375 +50343 0.554779052734375 +50344 0.61065673828125 +50345 0.610931396484375 +50346 0.531463623046875 +50347 0.3883056640625 +50348 0.23468017578125 +50349 0.095245361328125 +50350 -0.00396728515625 +50351 -0.04852294921875 +50352 -0.055145263671875 +50353 -0.0758056640625 +50354 -0.138702392578125 +50355 -0.209197998046875 +50356 -0.289031982421875 +50357 -0.37884521484375 +50358 -0.456329345703125 +50359 -0.51641845703125 +50360 -0.519287109375 +50361 -0.458251953125 +50362 -0.384796142578125 +50363 -0.323699951171875 +50364 -0.269287109375 +50365 -0.1951904296875 +50366 -0.100006103515625 +50367 -0.01055908203125 +50368 0.1033935546875 +50369 0.24908447265625 +50370 0.373199462890625 +50371 0.45806884765625 +50372 0.511474609375 +50373 0.565399169921875 +50374 0.61138916015625 +50375 0.5897216796875 +50376 0.4906005859375 +50377 0.33148193359375 +50378 0.147796630859375 +50379 -0.01873779296875 +50380 -0.140289306640625 +50381 -0.191986083984375 +50382 -0.184295654296875 +50383 -0.161834716796875 +50384 -0.166595458984375 +50385 -0.19390869140625 +50386 -0.22442626953125 +50387 -0.279754638671875 +50388 -0.3389892578125 +50389 -0.3543701171875 +50390 -0.348175048828125 +50391 -0.32598876953125 +50392 -0.2581787109375 +50393 -0.139801025390625 +50394 0.014617919921875 +50395 0.144378662109375 +50396 0.221038818359375 +50397 0.27069091796875 +50398 0.294036865234375 +50399 0.311767578125 +50400 0.339141845703125 +50401 0.360260009765625 +50402 0.360504150390625 +50403 0.308380126953125 +50404 0.18170166015625 +50405 0.0047607421875 +50406 -0.17559814453125 +50407 -0.3143310546875 +50408 -0.36785888671875 +50409 -0.36248779296875 +50410 -0.343536376953125 +50411 -0.3018798828125 +50412 -0.231414794921875 +50413 -0.117645263671875 +50414 0.007049560546875 +50415 0.087982177734375 +50416 0.13946533203125 +50417 0.17425537109375 +50418 0.188201904296875 +50419 0.171234130859375 +50420 0.118438720703125 +50421 0.05706787109375 +50422 -0.010711669921875 +50423 -0.0914306640625 +50424 -0.162322998046875 +50425 -0.194549560546875 +50426 -0.1492919921875 +50427 -0.02166748046875 +50428 0.124053955078125 +50429 0.211151123046875 +50430 0.240447998046875 +50431 0.242218017578125 +50432 0.2257080078125 +50433 0.194366455078125 +50434 0.115509033203125 +50435 0.0128173828125 +50436 -0.053802490234375 +50437 -0.110626220703125 +50438 -0.199493408203125 +50439 -0.29437255859375 +50440 -0.33221435546875 +50441 -0.27972412109375 +50442 -0.185333251953125 +50443 -0.128204345703125 +50444 -0.115692138671875 +50445 -0.116455078125 +50446 -0.105926513671875 +50447 -0.053955078125 +50448 0.048797607421875 +50449 0.157318115234375 +50450 0.212005615234375 +50451 0.218475341796875 +50452 0.23724365234375 +50453 0.30535888671875 +50454 0.38128662109375 +50455 0.404449462890625 +50456 0.3944091796875 +50457 0.3885498046875 +50458 0.362640380859375 +50459 0.27362060546875 +50460 0.11712646484375 +50461 -0.054901123046875 +50462 -0.19085693359375 +50463 -0.28570556640625 +50464 -0.339263916015625 +50465 -0.3775634765625 +50466 -0.445709228515625 +50467 -0.535064697265625 +50468 -0.629058837890625 +50469 -0.697601318359375 +50470 -0.70391845703125 +50471 -0.6424560546875 +50472 -0.491241455078125 +50473 -0.265716552734375 +50474 -0.023712158203125 +50475 0.201751708984375 +50476 0.375823974609375 +50477 0.485076904296875 +50478 0.56884765625 +50479 0.634765625 +50480 0.63763427734375 +50481 0.5660400390625 +50482 0.4720458984375 +50483 0.40692138671875 +50484 0.3778076171875 +50485 0.376953125 +50486 0.371978759765625 +50487 0.313140869140625 +50488 0.184417724609375 +50489 0.011199951171875 +50490 -0.171051025390625 +50491 -0.33740234375 +50492 -0.47198486328125 +50493 -0.560394287109375 +50494 -0.58056640625 +50495 -0.54754638671875 +50496 -0.508575439453125 +50497 -0.459503173828125 +50498 -0.394378662109375 +50499 -0.35260009765625 +50500 -0.31170654296875 +50501 -0.197418212890625 +50502 -0.007965087890625 +50503 0.207489013671875 +50504 0.409210205078125 +50505 0.57208251953125 +50506 0.66595458984375 +50507 0.65875244140625 +50508 0.56744384765625 +50509 0.431396484375 +50510 0.29443359375 +50511 0.182464599609375 +50512 0.06365966796875 +50513 -0.075958251953125 +50514 -0.189422607421875 +50515 -0.271942138671875 +50516 -0.342529296875 +50517 -0.364166259765625 +50518 -0.327239990234375 +50519 -0.2769775390625 +50520 -0.253692626953125 +50521 -0.24365234375 +50522 -0.1983642578125 +50523 -0.116241455078125 +50524 -0.036834716796875 +50525 0.034881591796875 +50526 0.09124755859375 +50527 0.10888671875 +50528 0.125518798828125 +50529 0.15771484375 +50530 0.17828369140625 +50531 0.17108154296875 +50532 0.129974365234375 +50533 0.082427978515625 +50534 0.027679443359375 +50535 -0.065643310546875 +50536 -0.15936279296875 +50537 -0.21307373046875 +50538 -0.234649658203125 +50539 -0.2001953125 +50540 -0.119171142578125 +50541 -0.024749755859375 +50542 0.085784912109375 +50543 0.178131103515625 +50544 0.215576171875 +50545 0.211456298828125 +50546 0.17523193359375 +50547 0.128753662109375 +50548 0.1019287109375 +50549 0.0743408203125 +50550 0.04327392578125 +50551 0.038177490234375 +50552 0.076263427734375 +50553 0.14105224609375 +50554 0.186431884765625 +50555 0.188812255859375 +50556 0.1390380859375 +50557 0.041778564453125 +50558 -0.079437255859375 +50559 -0.219390869140625 +50560 -0.367828369140625 +50561 -0.494873046875 +50562 -0.556243896484375 +50563 -0.508697509765625 +50564 -0.3756103515625 +50565 -0.218902587890625 +50566 -0.063751220703125 +50567 0.091552734375 +50568 0.23602294921875 +50569 0.342987060546875 +50570 0.39520263671875 +50571 0.389373779296875 +50572 0.324249267578125 +50573 0.224090576171875 +50574 0.124267578125 +50575 0.037078857421875 +50576 -0.010101318359375 +50577 -0.019439697265625 +50578 -0.022796630859375 +50579 -0.001556396484375 +50580 0.056304931640625 +50581 0.106719970703125 +50582 0.096893310546875 +50583 0.042694091796875 +50584 -0.018035888671875 +50585 -0.07586669921875 +50586 -0.11944580078125 +50587 -0.15972900390625 +50588 -0.202606201171875 +50589 -0.24859619140625 +50590 -0.30517578125 +50591 -0.36212158203125 +50592 -0.39141845703125 +50593 -0.35528564453125 +50594 -0.249969482421875 +50595 -0.092864990234375 +50596 0.08905029296875 +50597 0.2352294921875 +50598 0.318817138671875 +50599 0.358642578125 +50600 0.347747802734375 +50601 0.28564453125 +50602 0.223175048828125 +50603 0.196746826171875 +50604 0.179840087890625 +50605 0.155548095703125 +50606 0.151214599609375 +50607 0.156951904296875 +50608 0.13177490234375 +50609 0.100799560546875 +50610 0.087127685546875 +50611 0.05487060546875 +50612 -0.009002685546875 +50613 -0.10400390625 +50614 -0.229400634765625 +50615 -0.35552978515625 +50616 -0.441925048828125 +50617 -0.473846435546875 +50618 -0.464813232421875 +50619 -0.419097900390625 +50620 -0.334320068359375 +50621 -0.227935791015625 +50622 -0.12347412109375 +50623 -0.02764892578125 +50624 0.077667236328125 +50625 0.2132568359375 +50626 0.38885498046875 +50627 0.582794189453125 +50628 0.734039306640625 +50629 0.800140380859375 +50630 0.7783203125 +50631 0.6651611328125 +50632 0.45965576171875 +50633 0.199188232421875 +50634 -0.050689697265625 +50635 -0.23297119140625 +50636 -0.33013916015625 +50637 -0.368408203125 +50638 -0.378936767578125 +50639 -0.376983642578125 +50640 -0.37969970703125 +50641 -0.391510009765625 +50642 -0.385345458984375 +50643 -0.3419189453125 +50644 -0.28289794921875 +50645 -0.251617431640625 +50646 -0.266143798828125 +50647 -0.273345947265625 +50648 -0.216796875 +50649 -0.128265380859375 +50650 -0.068145751953125 +50651 -0.0430908203125 +50652 -0.024444580078125 +50653 0.020721435546875 +50654 0.124481201171875 +50655 0.25787353515625 +50656 0.379119873046875 +50657 0.47991943359375 +50658 0.5281982421875 +50659 0.511138916015625 +50660 0.456207275390625 +50661 0.407470703125 +50662 0.383758544921875 +50663 0.35687255859375 +50664 0.31182861328125 +50665 0.250885009765625 +50666 0.1654052734375 +50667 0.035247802734375 +50668 -0.142059326171875 +50669 -0.33563232421875 +50670 -0.5345458984375 +50671 -0.72186279296875 +50672 -0.836669921875 +50673 -0.8326416015625 +50674 -0.7296142578125 +50675 -0.582550048828125 +50676 -0.440093994140625 +50677 -0.324310302734375 +50678 -0.20147705078125 +50679 -0.044647216796875 +50680 0.103973388671875 +50681 0.202392578125 +50682 0.264495849609375 +50683 0.338897705078125 +50684 0.443817138671875 +50685 0.545074462890625 +50686 0.6173095703125 +50687 0.6524658203125 +50688 0.66339111328125 +50689 0.6561279296875 +50690 0.606781005859375 +50691 0.501190185546875 +50692 0.352783203125 +50693 0.176544189453125 +50694 -0.034820556640625 +50695 -0.258209228515625 +50696 -0.44244384765625 +50697 -0.5753173828125 +50698 -0.65203857421875 +50699 -0.641632080078125 +50700 -0.562164306640625 +50701 -0.458038330078125 +50702 -0.350555419921875 +50703 -0.260528564453125 +50704 -0.192108154296875 +50705 -0.141937255859375 +50706 -0.1021728515625 +50707 -0.062896728515625 +50708 -0.011932373046875 +50709 0.062835693359375 +50710 0.148712158203125 +50711 0.241729736328125 +50712 0.34912109375 +50713 0.457305908203125 +50714 0.54388427734375 +50715 0.5728759765625 +50716 0.506591796875 +50717 0.351226806640625 +50718 0.146514892578125 +50719 -0.05523681640625 +50720 -0.21624755859375 +50721 -0.334930419921875 +50722 -0.402984619140625 +50723 -0.4412841796875 +50724 -0.49578857421875 +50725 -0.5601806640625 +50726 -0.600738525390625 +50727 -0.584228515625 +50728 -0.47930908203125 +50729 -0.27935791015625 +50730 -0.0089111328125 +50731 0.268798828125 +50732 0.482818603515625 +50733 0.60369873046875 +50734 0.650421142578125 +50735 0.66400146484375 +50736 0.6414794921875 +50737 0.572540283203125 +50738 0.498138427734375 +50739 0.439453125 +50740 0.375518798828125 +50741 0.274505615234375 +50742 0.1087646484375 +50743 -0.099395751953125 +50744 -0.3182373046875 +50745 -0.5489501953125 +50746 -0.7738037109375 +50747 -0.86383056640625 +50748 -0.870391845703125 +50749 -0.86895751953125 +50750 -0.861053466796875 +50751 -0.765869140625 +50752 -0.5301513671875 +50753 -0.214691162109375 +50754 0.137359619140625 +50755 0.474822998046875 +50756 0.76239013671875 +50757 0.867462158203125 +50758 0.870361328125 +50759 0.86480712890625 +50760 0.831817626953125 +50761 0.677581787109375 +50762 0.495880126953125 +50763 0.30767822265625 +50764 0.116180419921875 +50765 -0.110748291015625 +50766 -0.381805419921875 +50767 -0.6572265625 +50768 -0.857421875 +50769 -0.870391845703125 +50770 -0.870391845703125 +50771 -0.86444091796875 +50772 -0.85723876953125 +50773 -0.790008544921875 +50774 -0.62847900390625 +50775 -0.3956298828125 +50776 -0.126708984375 +50777 0.150115966796875 +50778 0.424041748046875 +50779 0.670623779296875 +50780 0.854522705078125 +50781 0.866485595703125 +50782 0.86920166015625 +50783 0.8653564453125 +50784 0.857147216796875 +50785 0.766845703125 +50786 0.628509521484375 +50787 0.462127685546875 +50788 0.297210693359375 +50789 0.14862060546875 +50790 -0.00537109375 +50791 -0.15753173828125 +50792 -0.31304931640625 +50793 -0.48876953125 +50794 -0.6416015625 +50795 -0.751373291015625 +50796 -0.84619140625 +50797 -0.861297607421875 +50798 -0.863250732421875 +50799 -0.856597900390625 +50800 -0.7498779296875 +50801 -0.624542236328125 +50802 -0.47808837890625 +50803 -0.253387451171875 +50804 0.003692626953125 +50805 0.2257080078125 +50806 0.427154541015625 +50807 0.643218994140625 +50808 0.855926513671875 +50809 0.870361328125 +50810 0.870361328125 +50811 0.862762451171875 +50812 0.79669189453125 +50813 0.595794677734375 +50814 0.362152099609375 +50815 0.1270751953125 +50816 -0.086944580078125 +50817 -0.2784423828125 +50818 -0.484832763671875 +50819 -0.729583740234375 +50820 -0.86688232421875 +50821 -0.870391845703125 +50822 -0.86859130859375 +50823 -0.86279296875 +50824 -0.817962646484375 +50825 -0.6116943359375 +50826 -0.3128662109375 +50827 0.039398193359375 +50828 0.422821044921875 +50829 0.805145263671875 +50830 0.870361328125 +50831 0.870361328125 +50832 0.860015869140625 +50833 0.727935791015625 +50834 0.48114013671875 +50835 0.2059326171875 +50836 -0.06103515625 +50837 -0.29913330078125 +50838 -0.516204833984375 +50839 -0.7252197265625 +50840 -0.85980224609375 +50841 -0.870391845703125 +50842 -0.870391845703125 +50843 -0.858062744140625 +50844 -0.673004150390625 +50845 -0.42694091796875 +50846 -0.2100830078125 +50847 -0.0362548828125 +50848 0.10943603515625 +50849 0.23516845703125 +50850 0.373687744140625 +50851 0.517791748046875 +50852 0.602783203125 +50853 0.635711669921875 +50854 0.655181884765625 +50855 0.65948486328125 +50856 0.651275634765625 +50857 0.61846923828125 +50858 0.53753662109375 +50859 0.404144287109375 +50860 0.22186279296875 +50861 0.003997802734375 +50862 -0.22100830078125 +50863 -0.42449951171875 +50864 -0.579833984375 +50865 -0.641876220703125 +50866 -0.6177978515625 +50867 -0.575531005859375 +50868 -0.526336669921875 +50869 -0.42645263671875 +50870 -0.2581787109375 +50871 -0.068695068359375 +50872 0.09222412109375 +50873 0.232147216796875 +50874 0.3509521484375 +50875 0.410064697265625 +50876 0.372955322265625 +50877 0.2554931640625 +50878 0.10711669921875 +50879 -0.052886962890625 +50880 -0.186279296875 +50881 -0.23291015625 +50882 -0.209442138671875 +50883 -0.174163818359375 +50884 -0.126739501953125 +50885 -0.048126220703125 +50886 0.0426025390625 +50887 0.10748291015625 +50888 0.1409912109375 +50889 0.19708251953125 +50890 0.273651123046875 +50891 0.31768798828125 +50892 0.341094970703125 +50893 0.368011474609375 +50894 0.37249755859375 +50895 0.30072021484375 +50896 0.1517333984375 +50897 -0.01470947265625 +50898 -0.1883544921875 +50899 -0.372711181640625 +50900 -0.51397705078125 +50901 -0.57177734375 +50902 -0.53948974609375 +50903 -0.43511962890625 +50904 -0.2962646484375 +50905 -0.161102294921875 +50906 -0.0435791015625 +50907 0.060394287109375 +50908 0.13665771484375 +50909 0.170135498046875 +50910 0.16552734375 +50911 0.15728759765625 +50912 0.150787353515625 +50913 0.12200927734375 +50914 0.080108642578125 +50915 0.05126953125 +50916 0.062896728515625 +50917 0.09271240234375 +50918 0.092987060546875 +50919 0.07855224609375 +50920 0.06427001953125 +50921 0.0347900390625 +50922 -0.01171875 +50923 -0.056060791015625 +50924 -0.055511474609375 +50925 -0.010467529296875 +50926 0.02508544921875 +50927 0.025665283203125 +50928 0.017333984375 +50929 0.00189208984375 +50930 -0.03173828125 +50931 -0.071502685546875 +50932 -0.13543701171875 +50933 -0.219970703125 +50934 -0.300506591796875 +50935 -0.376312255859375 +50936 -0.416107177734375 +50937 -0.371124267578125 +50938 -0.242279052734375 +50939 -0.069732666015625 +50940 0.125640869140625 +50941 0.31268310546875 +50942 0.45501708984375 +50943 0.554779052734375 +50944 0.61065673828125 +50945 0.610931396484375 +50946 0.531463623046875 +50947 0.3883056640625 +50948 0.23468017578125 +50949 0.095245361328125 +50950 -0.00396728515625 +50951 -0.04852294921875 +50952 -0.055145263671875 +50953 -0.0758056640625 +50954 -0.138702392578125 +50955 -0.209197998046875 +50956 -0.289031982421875 +50957 -0.37884521484375 +50958 -0.456329345703125 +50959 -0.51641845703125 +50960 -0.519287109375 +50961 -0.458251953125 +50962 -0.384796142578125 +50963 -0.323699951171875 +50964 -0.269287109375 +50965 -0.1951904296875 +50966 -0.100006103515625 +50967 -0.01055908203125 +50968 0.1033935546875 +50969 0.24908447265625 +50970 0.373199462890625 +50971 0.45806884765625 +50972 0.511474609375 +50973 0.565399169921875 +50974 0.61138916015625 +50975 0.5897216796875 +50976 0.4906005859375 +50977 0.33148193359375 +50978 0.147796630859375 +50979 -0.01873779296875 +50980 -0.140289306640625 +50981 -0.191986083984375 +50982 -0.184295654296875 +50983 -0.161834716796875 +50984 -0.166595458984375 +50985 -0.19390869140625 +50986 -0.22442626953125 +50987 -0.279754638671875 +50988 -0.3389892578125 +50989 -0.3543701171875 +50990 -0.348175048828125 +50991 -0.32598876953125 +50992 -0.2581787109375 +50993 -0.139801025390625 +50994 0.014617919921875 +50995 0.144378662109375 +50996 0.221038818359375 +50997 0.27069091796875 +50998 0.294036865234375 +50999 0.311767578125 +51000 0.339141845703125 +51001 0.360260009765625 +51002 0.360504150390625 +51003 0.308380126953125 +51004 0.18170166015625 +51005 0.0047607421875 +51006 -0.17559814453125 +51007 -0.3143310546875 +51008 -0.36785888671875 +51009 -0.36248779296875 +51010 -0.343536376953125 +51011 -0.3018798828125 +51012 -0.231414794921875 +51013 -0.117645263671875 +51014 0.007049560546875 +51015 0.087982177734375 +51016 0.13946533203125 +51017 0.17425537109375 +51018 0.188201904296875 +51019 0.171234130859375 +51020 0.118438720703125 +51021 0.05706787109375 +51022 -0.010711669921875 +51023 -0.0914306640625 +51024 -0.162322998046875 +51025 -0.194549560546875 +51026 -0.1492919921875 +51027 -0.02166748046875 +51028 0.124053955078125 +51029 0.211151123046875 +51030 0.240447998046875 +51031 0.242218017578125 +51032 0.2257080078125 +51033 0.194366455078125 +51034 0.115509033203125 +51035 0.0128173828125 +51036 -0.053802490234375 +51037 -0.110626220703125 +51038 -0.199493408203125 +51039 -0.29437255859375 +51040 -0.33221435546875 +51041 -0.27972412109375 +51042 -0.185333251953125 +51043 -0.128204345703125 +51044 -0.115692138671875 +51045 -0.116455078125 +51046 -0.105926513671875 +51047 -0.053955078125 +51048 0.048797607421875 +51049 0.157318115234375 +51050 0.212005615234375 +51051 0.218475341796875 +51052 0.23724365234375 +51053 0.30535888671875 +51054 0.38128662109375 +51055 0.404449462890625 +51056 0.3944091796875 +51057 0.3885498046875 +51058 0.362640380859375 +51059 0.27362060546875 +51060 0.11712646484375 +51061 -0.054901123046875 +51062 -0.19085693359375 +51063 -0.28570556640625 +51064 -0.339263916015625 +51065 -0.3775634765625 +51066 -0.445709228515625 +51067 -0.535064697265625 +51068 -0.629058837890625 +51069 -0.697601318359375 +51070 -0.70391845703125 +51071 -0.6424560546875 +51072 -0.491241455078125 +51073 -0.265716552734375 +51074 -0.023712158203125 +51075 0.201751708984375 +51076 0.375823974609375 +51077 0.485076904296875 +51078 0.56884765625 +51079 0.634765625 +51080 0.63763427734375 +51081 0.5660400390625 +51082 0.4720458984375 +51083 0.40692138671875 +51084 0.3778076171875 +51085 0.376953125 +51086 0.371978759765625 +51087 0.313140869140625 +51088 0.184417724609375 +51089 0.011199951171875 +51090 -0.171051025390625 +51091 -0.33740234375 +51092 -0.47198486328125 +51093 -0.560394287109375 +51094 -0.58056640625 +51095 -0.54754638671875 +51096 -0.508575439453125 +51097 -0.459503173828125 +51098 -0.394378662109375 +51099 -0.35260009765625 +51100 -0.31170654296875 +51101 -0.197418212890625 +51102 -0.007965087890625 +51103 0.207489013671875 +51104 0.409210205078125 +51105 0.57208251953125 +51106 0.66595458984375 +51107 0.65875244140625 +51108 0.56744384765625 +51109 0.431396484375 +51110 0.29443359375 +51111 0.182464599609375 +51112 0.06365966796875 +51113 -0.075958251953125 +51114 -0.189422607421875 +51115 -0.271942138671875 +51116 -0.342529296875 +51117 -0.364166259765625 +51118 -0.327239990234375 +51119 -0.2769775390625 +51120 -0.253692626953125 +51121 -0.24365234375 +51122 -0.1983642578125 +51123 -0.116241455078125 +51124 -0.036834716796875 +51125 0.034881591796875 +51126 0.09124755859375 +51127 0.10888671875 +51128 0.125518798828125 +51129 0.15771484375 +51130 0.17828369140625 +51131 0.17108154296875 +51132 0.129974365234375 +51133 0.082427978515625 +51134 0.027679443359375 +51135 -0.065643310546875 +51136 -0.15936279296875 +51137 -0.21307373046875 +51138 -0.234649658203125 +51139 -0.2001953125 +51140 -0.119171142578125 +51141 -0.024749755859375 +51142 0.085784912109375 +51143 0.178131103515625 +51144 0.215576171875 +51145 0.211456298828125 +51146 0.17523193359375 +51147 0.128753662109375 +51148 0.1019287109375 +51149 0.0743408203125 +51150 0.04327392578125 +51151 0.038177490234375 +51152 0.076263427734375 +51153 0.14105224609375 +51154 0.186431884765625 +51155 0.188812255859375 +51156 0.1390380859375 +51157 0.041778564453125 +51158 -0.079437255859375 +51159 -0.219390869140625 +51160 -0.367828369140625 +51161 -0.494873046875 +51162 -0.556243896484375 +51163 -0.508697509765625 +51164 -0.3756103515625 +51165 -0.218902587890625 +51166 -0.063751220703125 +51167 0.091552734375 +51168 0.23602294921875 +51169 0.342987060546875 +51170 0.39520263671875 +51171 0.389373779296875 +51172 0.324249267578125 +51173 0.224090576171875 +51174 0.124267578125 +51175 0.037078857421875 +51176 -0.010101318359375 +51177 -0.019439697265625 +51178 -0.022796630859375 +51179 -0.001556396484375 +51180 0.056304931640625 +51181 0.106719970703125 +51182 0.096893310546875 +51183 0.042694091796875 +51184 -0.018035888671875 +51185 -0.07586669921875 +51186 -0.11944580078125 +51187 -0.15972900390625 +51188 -0.202606201171875 +51189 -0.24859619140625 +51190 -0.30517578125 +51191 -0.36212158203125 +51192 -0.39141845703125 +51193 -0.35528564453125 +51194 -0.249969482421875 +51195 -0.092864990234375 +51196 0.08905029296875 +51197 0.2352294921875 +51198 0.318817138671875 +51199 0.358642578125 +51200 0.347747802734375 +51201 0.28564453125 +51202 0.223175048828125 +51203 0.196746826171875 +51204 0.179840087890625 +51205 0.155548095703125 +51206 0.151214599609375 +51207 0.156951904296875 +51208 0.13177490234375 +51209 0.100799560546875 +51210 0.087127685546875 +51211 0.05487060546875 +51212 -0.009002685546875 +51213 -0.10400390625 +51214 -0.229400634765625 +51215 -0.35552978515625 +51216 -0.441925048828125 +51217 -0.473846435546875 +51218 -0.464813232421875 +51219 -0.419097900390625 +51220 -0.334320068359375 +51221 -0.227935791015625 +51222 -0.12347412109375 +51223 -0.02764892578125 +51224 0.077667236328125 +51225 0.2132568359375 +51226 0.38885498046875 +51227 0.582794189453125 +51228 0.734039306640625 +51229 0.800140380859375 +51230 0.7783203125 +51231 0.6651611328125 +51232 0.45965576171875 +51233 0.199188232421875 +51234 -0.050689697265625 +51235 -0.23297119140625 +51236 -0.33013916015625 +51237 -0.368408203125 +51238 -0.378936767578125 +51239 -0.376983642578125 +51240 -0.37969970703125 +51241 -0.391510009765625 +51242 -0.385345458984375 +51243 -0.3419189453125 +51244 -0.28289794921875 +51245 -0.251617431640625 +51246 -0.266143798828125 +51247 -0.273345947265625 +51248 -0.216796875 +51249 -0.128265380859375 +51250 -0.068145751953125 +51251 -0.0430908203125 +51252 -0.024444580078125 +51253 0.020721435546875 +51254 0.124481201171875 +51255 0.25787353515625 +51256 0.379119873046875 +51257 0.47991943359375 +51258 0.5281982421875 +51259 0.511138916015625 +51260 0.456207275390625 +51261 0.407470703125 +51262 0.383758544921875 +51263 0.35687255859375 +51264 0.31182861328125 +51265 0.250885009765625 +51266 0.1654052734375 +51267 0.035247802734375 +51268 -0.142059326171875 +51269 -0.33563232421875 +51270 -0.5345458984375 +51271 -0.72186279296875 +51272 -0.836669921875 +51273 -0.8326416015625 +51274 -0.7296142578125 +51275 -0.582550048828125 +51276 -0.440093994140625 +51277 -0.324310302734375 +51278 -0.20147705078125 +51279 -0.044647216796875 +51280 0.103973388671875 +51281 0.202392578125 +51282 0.264495849609375 +51283 0.338897705078125 +51284 0.443817138671875 +51285 0.545074462890625 +51286 0.6173095703125 +51287 0.6524658203125 +51288 0.66339111328125 +51289 0.6561279296875 +51290 0.606781005859375 +51291 0.501190185546875 +51292 0.352783203125 +51293 0.176544189453125 +51294 -0.034820556640625 +51295 -0.258209228515625 +51296 -0.44244384765625 +51297 -0.5753173828125 +51298 -0.65203857421875 +51299 -0.641632080078125 +51300 -0.562164306640625 +51301 -0.458038330078125 +51302 -0.350555419921875 +51303 -0.260528564453125 +51304 -0.192108154296875 +51305 -0.141937255859375 +51306 -0.1021728515625 +51307 -0.062896728515625 +51308 -0.011932373046875 +51309 0.062835693359375 +51310 0.148712158203125 +51311 0.241729736328125 +51312 0.34912109375 +51313 0.457305908203125 +51314 0.54388427734375 +51315 0.5728759765625 +51316 0.506591796875 +51317 0.351226806640625 +51318 0.146514892578125 +51319 -0.05523681640625 +51320 -0.21624755859375 +51321 -0.334930419921875 +51322 -0.402984619140625 +51323 -0.4412841796875 +51324 -0.49578857421875 +51325 -0.5601806640625 +51326 -0.600738525390625 +51327 -0.584228515625 +51328 -0.47930908203125 +51329 -0.27935791015625 +51330 -0.0089111328125 +51331 0.268798828125 +51332 0.482818603515625 +51333 0.60369873046875 +51334 0.650421142578125 +51335 0.66400146484375 +51336 0.6414794921875 +51337 0.572540283203125 +51338 0.498138427734375 +51339 0.439453125 +51340 0.375518798828125 +51341 0.274505615234375 +51342 0.1087646484375 +51343 -0.099395751953125 +51344 -0.3182373046875 +51345 -0.5489501953125 +51346 -0.7738037109375 +51347 -0.86383056640625 +51348 -0.870391845703125 +51349 -0.86895751953125 +51350 -0.861053466796875 +51351 -0.765869140625 +51352 -0.5301513671875 +51353 -0.214691162109375 +51354 0.137359619140625 +51355 0.474822998046875 +51356 0.76239013671875 +51357 0.867462158203125 +51358 0.870361328125 +51359 0.86480712890625 +51360 0.831817626953125 +51361 0.677581787109375 +51362 0.495880126953125 +51363 0.30767822265625 +51364 0.116180419921875 +51365 -0.110748291015625 +51366 -0.381805419921875 +51367 -0.6572265625 +51368 -0.857421875 +51369 -0.870391845703125 +51370 -0.870391845703125 +51371 -0.86444091796875 +51372 -0.85723876953125 +51373 -0.790008544921875 +51374 -0.62847900390625 +51375 -0.3956298828125 +51376 -0.126708984375 +51377 0.150115966796875 +51378 0.424041748046875 +51379 0.670623779296875 +51380 0.854522705078125 +51381 0.866485595703125 +51382 0.86920166015625 +51383 0.8653564453125 +51384 0.857147216796875 +51385 0.766845703125 +51386 0.628509521484375 +51387 0.462127685546875 +51388 0.297210693359375 +51389 0.14862060546875 +51390 -0.00537109375 +51391 -0.15753173828125 +51392 -0.31304931640625 +51393 -0.48876953125 +51394 -0.6416015625 +51395 -0.751373291015625 +51396 -0.84619140625 +51397 -0.861297607421875 +51398 -0.863250732421875 +51399 -0.856597900390625 +51400 -0.7498779296875 +51401 -0.624542236328125 +51402 -0.47808837890625 +51403 -0.253387451171875 +51404 0.003692626953125 +51405 0.2257080078125 +51406 0.427154541015625 +51407 0.643218994140625 +51408 0.855926513671875 +51409 0.870361328125 +51410 0.870361328125 +51411 0.862762451171875 +51412 0.79669189453125 +51413 0.595794677734375 +51414 0.362152099609375 +51415 0.1270751953125 +51416 -0.086944580078125 +51417 -0.2784423828125 +51418 -0.484832763671875 +51419 -0.729583740234375 +51420 -0.86688232421875 +51421 -0.870391845703125 +51422 -0.86859130859375 +51423 -0.86279296875 +51424 -0.817962646484375 +51425 -0.6116943359375 +51426 -0.3128662109375 +51427 0.039398193359375 +51428 0.422821044921875 +51429 0.805145263671875 +51430 0.870361328125 +51431 0.870361328125 +51432 0.860015869140625 +51433 0.727935791015625 +51434 0.48114013671875 +51435 0.2059326171875 +51436 -0.06103515625 +51437 -0.29913330078125 +51438 -0.516204833984375 +51439 -0.7252197265625 +51440 -0.85980224609375 +51441 -0.870391845703125 +51442 -0.870391845703125 +51443 -0.858062744140625 +51444 -0.673004150390625 +51445 -0.42694091796875 +51446 -0.2100830078125 +51447 -0.0362548828125 +51448 0.10943603515625 +51449 0.23516845703125 +51450 0.373687744140625 +51451 0.517791748046875 +51452 0.602783203125 +51453 0.635711669921875 +51454 0.655181884765625 +51455 0.65948486328125 +51456 0.651275634765625 +51457 0.61846923828125 +51458 0.53753662109375 +51459 0.404144287109375 +51460 0.22186279296875 +51461 0.003997802734375 +51462 -0.22100830078125 +51463 -0.42449951171875 +51464 -0.579833984375 +51465 -0.641876220703125 +51466 -0.6177978515625 +51467 -0.575531005859375 +51468 -0.526336669921875 +51469 -0.42645263671875 +51470 -0.2581787109375 +51471 -0.068695068359375 +51472 0.09222412109375 +51473 0.232147216796875 +51474 0.3509521484375 +51475 0.410064697265625 +51476 0.372955322265625 +51477 0.2554931640625 +51478 0.10711669921875 +51479 -0.052886962890625 +51480 -0.186279296875 +51481 -0.23291015625 +51482 -0.209442138671875 +51483 -0.174163818359375 +51484 -0.126739501953125 +51485 -0.048126220703125 +51486 0.0426025390625 +51487 0.10748291015625 +51488 0.1409912109375 +51489 0.19708251953125 +51490 0.273651123046875 +51491 0.31768798828125 +51492 0.341094970703125 +51493 0.368011474609375 +51494 0.37249755859375 +51495 0.30072021484375 +51496 0.1517333984375 +51497 -0.01470947265625 +51498 -0.1883544921875 +51499 -0.372711181640625 +51500 -0.51397705078125 +51501 -0.57177734375 +51502 -0.53948974609375 +51503 -0.43511962890625 +51504 -0.2962646484375 +51505 -0.161102294921875 +51506 -0.0435791015625 +51507 0.060394287109375 +51508 0.13665771484375 +51509 0.170135498046875 +51510 0.16552734375 +51511 0.15728759765625 +51512 0.150787353515625 +51513 0.12200927734375 +51514 0.080108642578125 +51515 0.05126953125 +51516 0.062896728515625 +51517 0.09271240234375 +51518 0.092987060546875 +51519 0.07855224609375 +51520 0.06427001953125 +51521 0.0347900390625 +51522 -0.01171875 +51523 -0.056060791015625 +51524 -0.055511474609375 +51525 -0.010467529296875 +51526 0.02508544921875 +51527 0.025665283203125 +51528 0.017333984375 +51529 0.00189208984375 +51530 -0.03173828125 +51531 -0.071502685546875 +51532 -0.13543701171875 +51533 -0.219970703125 +51534 -0.300506591796875 +51535 -0.376312255859375 +51536 -0.416107177734375 +51537 -0.371124267578125 +51538 -0.242279052734375 +51539 -0.069732666015625 +51540 0.125640869140625 +51541 0.31268310546875 +51542 0.45501708984375 +51543 0.554779052734375 +51544 0.61065673828125 +51545 0.610931396484375 +51546 0.531463623046875 +51547 0.3883056640625 +51548 0.23468017578125 +51549 0.095245361328125 +51550 -0.00396728515625 +51551 -0.04852294921875 +51552 -0.055145263671875 +51553 -0.0758056640625 +51554 -0.138702392578125 +51555 -0.209197998046875 +51556 -0.289031982421875 +51557 -0.37884521484375 +51558 -0.456329345703125 +51559 -0.51641845703125 +51560 -0.519287109375 +51561 -0.458251953125 +51562 -0.384796142578125 +51563 -0.323699951171875 +51564 -0.269287109375 +51565 -0.1951904296875 +51566 -0.100006103515625 +51567 -0.01055908203125 +51568 0.1033935546875 +51569 0.24908447265625 +51570 0.373199462890625 +51571 0.45806884765625 +51572 0.511474609375 +51573 0.565399169921875 +51574 0.61138916015625 +51575 0.5897216796875 +51576 0.4906005859375 +51577 0.33148193359375 +51578 0.147796630859375 +51579 -0.01873779296875 +51580 -0.140289306640625 +51581 -0.191986083984375 +51582 -0.184295654296875 +51583 -0.161834716796875 +51584 -0.166595458984375 +51585 -0.19390869140625 +51586 -0.22442626953125 +51587 -0.279754638671875 +51588 -0.3389892578125 +51589 -0.3543701171875 +51590 -0.348175048828125 +51591 -0.32598876953125 +51592 -0.2581787109375 +51593 -0.139801025390625 +51594 0.014617919921875 +51595 0.144378662109375 +51596 0.221038818359375 +51597 0.27069091796875 +51598 0.294036865234375 +51599 0.311767578125 +51600 0.339141845703125 +51601 0.360260009765625 +51602 0.360504150390625 +51603 0.308380126953125 +51604 0.18170166015625 +51605 0.0047607421875 +51606 -0.17559814453125 +51607 -0.3143310546875 +51608 -0.36785888671875 +51609 -0.36248779296875 +51610 -0.343536376953125 +51611 -0.3018798828125 +51612 -0.231414794921875 +51613 -0.117645263671875 +51614 0.007049560546875 +51615 0.087982177734375 +51616 0.13946533203125 +51617 0.17425537109375 +51618 0.188201904296875 +51619 0.171234130859375 +51620 0.118438720703125 +51621 0.05706787109375 +51622 -0.010711669921875 +51623 -0.0914306640625 +51624 -0.162322998046875 +51625 -0.194549560546875 +51626 -0.1492919921875 +51627 -0.02166748046875 +51628 0.124053955078125 +51629 0.211151123046875 +51630 0.240447998046875 +51631 0.242218017578125 +51632 0.2257080078125 +51633 0.194366455078125 +51634 0.115509033203125 +51635 0.0128173828125 +51636 -0.053802490234375 +51637 -0.110626220703125 +51638 -0.199493408203125 +51639 -0.29437255859375 +51640 -0.33221435546875 +51641 -0.27972412109375 +51642 -0.185333251953125 +51643 -0.128204345703125 +51644 -0.115692138671875 +51645 -0.116455078125 +51646 -0.105926513671875 +51647 -0.053955078125 +51648 0.048797607421875 +51649 0.157318115234375 +51650 0.212005615234375 +51651 0.218475341796875 +51652 0.23724365234375 +51653 0.30535888671875 +51654 0.38128662109375 +51655 0.404449462890625 +51656 0.3944091796875 +51657 0.3885498046875 +51658 0.362640380859375 +51659 0.27362060546875 +51660 0.11712646484375 +51661 -0.054901123046875 +51662 -0.19085693359375 +51663 -0.28570556640625 +51664 -0.339263916015625 +51665 -0.3775634765625 +51666 -0.445709228515625 +51667 -0.535064697265625 +51668 -0.629058837890625 +51669 -0.697601318359375 +51670 -0.70391845703125 +51671 -0.6424560546875 +51672 -0.491241455078125 +51673 -0.265716552734375 +51674 -0.023712158203125 +51675 0.201751708984375 +51676 0.375823974609375 +51677 0.485076904296875 +51678 0.56884765625 +51679 0.634765625 +51680 0.63763427734375 +51681 0.5660400390625 +51682 0.4720458984375 +51683 0.40692138671875 +51684 0.3778076171875 +51685 0.376953125 +51686 0.371978759765625 +51687 0.313140869140625 +51688 0.184417724609375 +51689 0.011199951171875 +51690 -0.171051025390625 +51691 -0.33740234375 +51692 -0.47198486328125 +51693 -0.560394287109375 +51694 -0.58056640625 +51695 -0.54754638671875 +51696 -0.508575439453125 +51697 -0.459503173828125 +51698 -0.394378662109375 +51699 -0.35260009765625 +51700 -0.31170654296875 +51701 -0.197418212890625 +51702 -0.007965087890625 +51703 0.207489013671875 +51704 0.409210205078125 +51705 0.57208251953125 +51706 0.66595458984375 +51707 0.65875244140625 +51708 0.56744384765625 +51709 0.431396484375 +51710 0.29443359375 +51711 0.182464599609375 +51712 0.06365966796875 +51713 -0.075958251953125 +51714 -0.189422607421875 +51715 -0.271942138671875 +51716 -0.342529296875 +51717 -0.364166259765625 +51718 -0.327239990234375 +51719 -0.2769775390625 +51720 -0.253692626953125 +51721 -0.24365234375 +51722 -0.1983642578125 +51723 -0.116241455078125 +51724 -0.036834716796875 +51725 0.034881591796875 +51726 0.09124755859375 +51727 0.10888671875 +51728 0.125518798828125 +51729 0.15771484375 +51730 0.17828369140625 +51731 0.17108154296875 +51732 0.129974365234375 +51733 0.082427978515625 +51734 0.027679443359375 +51735 -0.065643310546875 +51736 -0.15936279296875 +51737 -0.21307373046875 +51738 -0.234649658203125 +51739 -0.2001953125 +51740 -0.119171142578125 +51741 -0.024749755859375 +51742 0.085784912109375 +51743 0.178131103515625 +51744 0.215576171875 +51745 0.211456298828125 +51746 0.17523193359375 +51747 0.128753662109375 +51748 0.1019287109375 +51749 0.0743408203125 +51750 0.04327392578125 +51751 0.038177490234375 +51752 0.076263427734375 +51753 0.14105224609375 +51754 0.186431884765625 +51755 0.188812255859375 +51756 0.1390380859375 +51757 0.041778564453125 +51758 -0.079437255859375 +51759 -0.219390869140625 +51760 -0.367828369140625 +51761 -0.494873046875 +51762 -0.556243896484375 +51763 -0.508697509765625 +51764 -0.3756103515625 +51765 -0.218902587890625 +51766 -0.063751220703125 +51767 0.091552734375 +51768 0.23602294921875 +51769 0.342987060546875 +51770 0.39520263671875 +51771 0.389373779296875 +51772 0.324249267578125 +51773 0.224090576171875 +51774 0.124267578125 +51775 0.037078857421875 +51776 -0.010101318359375 +51777 -0.019439697265625 +51778 -0.022796630859375 +51779 -0.001556396484375 +51780 0.056304931640625 +51781 0.106719970703125 +51782 0.096893310546875 +51783 0.042694091796875 +51784 -0.018035888671875 +51785 -0.07586669921875 +51786 -0.11944580078125 +51787 -0.15972900390625 +51788 -0.202606201171875 +51789 -0.24859619140625 +51790 -0.30517578125 +51791 -0.36212158203125 +51792 -0.39141845703125 +51793 -0.35528564453125 +51794 -0.249969482421875 +51795 -0.092864990234375 +51796 0.08905029296875 +51797 0.2352294921875 +51798 0.318817138671875 +51799 0.358642578125 +51800 0.347747802734375 +51801 0.28564453125 +51802 0.223175048828125 +51803 0.196746826171875 +51804 0.179840087890625 +51805 0.155548095703125 +51806 0.151214599609375 +51807 0.156951904296875 +51808 0.13177490234375 +51809 0.100799560546875 +51810 0.087127685546875 +51811 0.05487060546875 +51812 -0.009002685546875 +51813 -0.10400390625 +51814 -0.229400634765625 +51815 -0.35552978515625 +51816 -0.441925048828125 +51817 -0.473846435546875 +51818 -0.464813232421875 +51819 -0.419097900390625 +51820 -0.334320068359375 +51821 -0.227935791015625 +51822 -0.12347412109375 +51823 -0.02764892578125 +51824 0.077667236328125 +51825 0.2132568359375 +51826 0.38885498046875 +51827 0.582794189453125 +51828 0.734039306640625 +51829 0.800140380859375 +51830 0.7783203125 +51831 0.6651611328125 +51832 0.45965576171875 +51833 0.199188232421875 +51834 -0.050689697265625 +51835 -0.23297119140625 +51836 -0.33013916015625 +51837 -0.368408203125 +51838 -0.378936767578125 +51839 -0.376983642578125 +51840 -0.37969970703125 +51841 -0.391510009765625 +51842 -0.385345458984375 +51843 -0.3419189453125 +51844 -0.28289794921875 +51845 -0.251617431640625 +51846 -0.266143798828125 +51847 -0.273345947265625 +51848 -0.216796875 +51849 -0.128265380859375 +51850 -0.068145751953125 +51851 -0.0430908203125 +51852 -0.024444580078125 +51853 0.020721435546875 +51854 0.124481201171875 +51855 0.25787353515625 +51856 0.379119873046875 +51857 0.47991943359375 +51858 0.5281982421875 +51859 0.511138916015625 +51860 0.456207275390625 +51861 0.407470703125 +51862 0.383758544921875 +51863 0.35687255859375 +51864 0.31182861328125 +51865 0.250885009765625 +51866 0.1654052734375 +51867 0.035247802734375 +51868 -0.142059326171875 +51869 -0.33563232421875 +51870 -0.5345458984375 +51871 -0.72186279296875 +51872 -0.836669921875 +51873 -0.8326416015625 +51874 -0.7296142578125 +51875 -0.582550048828125 +51876 -0.440093994140625 +51877 -0.324310302734375 +51878 -0.20147705078125 +51879 -0.044647216796875 +51880 0.103973388671875 +51881 0.202392578125 +51882 0.264495849609375 +51883 0.338897705078125 +51884 0.443817138671875 +51885 0.545074462890625 +51886 0.6173095703125 +51887 0.6524658203125 +51888 0.66339111328125 +51889 0.6561279296875 +51890 0.606781005859375 +51891 0.501190185546875 +51892 0.352783203125 +51893 0.176544189453125 +51894 -0.034820556640625 +51895 -0.258209228515625 +51896 -0.44244384765625 +51897 -0.5753173828125 +51898 -0.65203857421875 +51899 -0.641632080078125 +51900 -0.562164306640625 +51901 -0.458038330078125 +51902 -0.350555419921875 +51903 -0.260528564453125 +51904 -0.192108154296875 +51905 -0.141937255859375 +51906 -0.1021728515625 +51907 -0.062896728515625 +51908 -0.011932373046875 +51909 0.062835693359375 +51910 0.148712158203125 +51911 0.241729736328125 +51912 0.34912109375 +51913 0.457305908203125 +51914 0.54388427734375 +51915 0.5728759765625 +51916 0.506591796875 +51917 0.351226806640625 +51918 0.146514892578125 +51919 -0.05523681640625 +51920 -0.21624755859375 +51921 -0.334930419921875 +51922 -0.402984619140625 +51923 -0.4412841796875 +51924 -0.49578857421875 +51925 -0.5601806640625 +51926 -0.600738525390625 +51927 -0.584228515625 +51928 -0.47930908203125 +51929 -0.27935791015625 +51930 -0.0089111328125 +51931 0.268798828125 +51932 0.482818603515625 +51933 0.60369873046875 +51934 0.650421142578125 +51935 0.66400146484375 +51936 0.6414794921875 +51937 0.572540283203125 +51938 0.498138427734375 +51939 0.439453125 +51940 0.375518798828125 +51941 0.274505615234375 +51942 0.1087646484375 +51943 -0.099395751953125 +51944 -0.3182373046875 +51945 -0.5489501953125 +51946 -0.7738037109375 +51947 -0.86383056640625 +51948 -0.870391845703125 +51949 -0.86895751953125 +51950 -0.861053466796875 +51951 -0.765869140625 +51952 -0.5301513671875 +51953 -0.214691162109375 +51954 0.137359619140625 +51955 0.474822998046875 +51956 0.76239013671875 +51957 0.867462158203125 +51958 0.870361328125 +51959 0.86480712890625 +51960 0.831817626953125 +51961 0.677581787109375 +51962 0.495880126953125 +51963 0.30767822265625 +51964 0.116180419921875 +51965 -0.110748291015625 +51966 -0.381805419921875 +51967 -0.6572265625 +51968 -0.857421875 +51969 -0.870391845703125 +51970 -0.870391845703125 +51971 -0.86444091796875 +51972 -0.85723876953125 +51973 -0.790008544921875 +51974 -0.62847900390625 +51975 -0.3956298828125 +51976 -0.126708984375 +51977 0.150115966796875 +51978 0.424041748046875 +51979 0.670623779296875 +51980 0.854522705078125 +51981 0.866485595703125 +51982 0.86920166015625 +51983 0.8653564453125 +51984 0.857147216796875 +51985 0.766845703125 +51986 0.628509521484375 +51987 0.462127685546875 +51988 0.297210693359375 +51989 0.14862060546875 +51990 -0.00537109375 +51991 -0.15753173828125 +51992 -0.31304931640625 +51993 -0.48876953125 +51994 -0.6416015625 +51995 -0.751373291015625 +51996 -0.84619140625 +51997 -0.861297607421875 +51998 -0.863250732421875 +51999 -0.856597900390625 +52000 -0.7498779296875 +52001 -0.624542236328125 +52002 -0.47808837890625 +52003 -0.253387451171875 +52004 0.003692626953125 +52005 0.2257080078125 +52006 0.427154541015625 +52007 0.643218994140625 +52008 0.855926513671875 +52009 0.870361328125 +52010 0.870361328125 +52011 0.862762451171875 +52012 0.79669189453125 +52013 0.595794677734375 +52014 0.362152099609375 +52015 0.1270751953125 +52016 -0.086944580078125 +52017 -0.2784423828125 +52018 -0.484832763671875 +52019 -0.729583740234375 +52020 -0.86688232421875 +52021 -0.870391845703125 +52022 -0.86859130859375 +52023 -0.86279296875 +52024 -0.817962646484375 +52025 -0.6116943359375 +52026 -0.3128662109375 +52027 0.039398193359375 +52028 0.422821044921875 +52029 0.805145263671875 +52030 0.870361328125 +52031 0.870361328125 +52032 0.860015869140625 +52033 0.727935791015625 +52034 0.48114013671875 +52035 0.2059326171875 +52036 -0.06103515625 +52037 -0.29913330078125 +52038 -0.516204833984375 +52039 -0.7252197265625 +52040 -0.85980224609375 +52041 -0.870391845703125 +52042 -0.870391845703125 +52043 -0.858062744140625 +52044 -0.673004150390625 +52045 -0.42694091796875 +52046 -0.2100830078125 +52047 -0.0362548828125 +52048 0.10943603515625 +52049 0.23516845703125 +52050 0.373687744140625 +52051 0.517791748046875 +52052 0.602783203125 +52053 0.635711669921875 +52054 0.655181884765625 +52055 0.65948486328125 +52056 0.651275634765625 +52057 0.61846923828125 +52058 0.53753662109375 +52059 0.404144287109375 +52060 0.22186279296875 +52061 0.003997802734375 +52062 -0.22100830078125 +52063 -0.42449951171875 +52064 -0.579833984375 +52065 -0.641876220703125 +52066 -0.6177978515625 +52067 -0.575531005859375 +52068 -0.526336669921875 +52069 -0.42645263671875 +52070 -0.2581787109375 +52071 -0.068695068359375 +52072 0.09222412109375 +52073 0.232147216796875 +52074 0.3509521484375 +52075 0.410064697265625 +52076 0.372955322265625 +52077 0.2554931640625 +52078 0.10711669921875 +52079 -0.052886962890625 +52080 -0.186279296875 +52081 -0.23291015625 +52082 -0.209442138671875 +52083 -0.174163818359375 +52084 -0.126739501953125 +52085 -0.048126220703125 +52086 0.0426025390625 +52087 0.10748291015625 +52088 0.1409912109375 +52089 0.19708251953125 +52090 0.273651123046875 +52091 0.31768798828125 +52092 0.341094970703125 +52093 0.368011474609375 +52094 0.37249755859375 +52095 0.30072021484375 +52096 0.1517333984375 +52097 -0.01470947265625 +52098 -0.1883544921875 +52099 -0.372711181640625 +52100 -0.51397705078125 +52101 -0.57177734375 +52102 -0.53948974609375 +52103 -0.43511962890625 +52104 -0.2962646484375 +52105 -0.161102294921875 +52106 -0.0435791015625 +52107 0.060394287109375 +52108 0.13665771484375 +52109 0.170135498046875 +52110 0.16552734375 +52111 0.15728759765625 +52112 0.150787353515625 +52113 0.12200927734375 +52114 0.080108642578125 +52115 0.05126953125 +52116 0.062896728515625 +52117 0.09271240234375 +52118 0.092987060546875 +52119 0.07855224609375 +52120 0.06427001953125 +52121 0.0347900390625 +52122 -0.01171875 +52123 -0.056060791015625 +52124 -0.055511474609375 +52125 -0.010467529296875 +52126 0.02508544921875 +52127 0.025665283203125 +52128 0.017333984375 +52129 0.00189208984375 +52130 -0.03173828125 +52131 -0.071502685546875 +52132 -0.13543701171875 +52133 -0.219970703125 +52134 -0.300506591796875 +52135 -0.376312255859375 +52136 -0.416107177734375 +52137 -0.371124267578125 +52138 -0.242279052734375 +52139 -0.069732666015625 +52140 0.125640869140625 +52141 0.31268310546875 +52142 0.45501708984375 +52143 0.554779052734375 +52144 0.61065673828125 +52145 0.610931396484375 +52146 0.531463623046875 +52147 0.3883056640625 +52148 0.23468017578125 +52149 0.095245361328125 +52150 -0.00396728515625 +52151 -0.04852294921875 +52152 -0.055145263671875 +52153 -0.0758056640625 +52154 -0.138702392578125 +52155 -0.209197998046875 +52156 -0.289031982421875 +52157 -0.37884521484375 +52158 -0.456329345703125 +52159 -0.51641845703125 +52160 -0.519287109375 +52161 -0.458251953125 +52162 -0.384796142578125 +52163 -0.323699951171875 +52164 -0.269287109375 +52165 -0.1951904296875 +52166 -0.100006103515625 +52167 -0.01055908203125 +52168 0.1033935546875 +52169 0.24908447265625 +52170 0.373199462890625 +52171 0.45806884765625 +52172 0.511474609375 +52173 0.565399169921875 +52174 0.61138916015625 +52175 0.5897216796875 +52176 0.4906005859375 +52177 0.33148193359375 +52178 0.147796630859375 +52179 -0.01873779296875 +52180 -0.140289306640625 +52181 -0.191986083984375 +52182 -0.184295654296875 +52183 -0.161834716796875 +52184 -0.166595458984375 +52185 -0.19390869140625 +52186 -0.22442626953125 +52187 -0.279754638671875 +52188 -0.3389892578125 +52189 -0.3543701171875 +52190 -0.348175048828125 +52191 -0.32598876953125 +52192 -0.2581787109375 +52193 -0.139801025390625 +52194 0.014617919921875 +52195 0.144378662109375 +52196 0.221038818359375 +52197 0.27069091796875 +52198 0.294036865234375 +52199 0.311767578125 +52200 0.339141845703125 +52201 0.360260009765625 +52202 0.360504150390625 +52203 0.308380126953125 +52204 0.18170166015625 +52205 0.0047607421875 +52206 -0.17559814453125 +52207 -0.3143310546875 +52208 -0.36785888671875 +52209 -0.36248779296875 +52210 -0.343536376953125 +52211 -0.3018798828125 +52212 -0.231414794921875 +52213 -0.117645263671875 +52214 0.007049560546875 +52215 0.087982177734375 +52216 0.13946533203125 +52217 0.17425537109375 +52218 0.188201904296875 +52219 0.171234130859375 +52220 0.118438720703125 +52221 0.05706787109375 +52222 -0.010711669921875 +52223 -0.0914306640625 +52224 -0.162322998046875 +52225 -0.194549560546875 +52226 -0.1492919921875 +52227 -0.02166748046875 +52228 0.124053955078125 +52229 0.211151123046875 +52230 0.240447998046875 +52231 0.242218017578125 +52232 0.2257080078125 +52233 0.194366455078125 +52234 0.115509033203125 +52235 0.0128173828125 +52236 -0.053802490234375 +52237 -0.110626220703125 +52238 -0.199493408203125 +52239 -0.29437255859375 +52240 -0.33221435546875 +52241 -0.27972412109375 +52242 -0.185333251953125 +52243 -0.128204345703125 +52244 -0.115692138671875 +52245 -0.116455078125 +52246 -0.105926513671875 +52247 -0.053955078125 +52248 0.048797607421875 +52249 0.157318115234375 +52250 0.212005615234375 +52251 0.218475341796875 +52252 0.23724365234375 +52253 0.30535888671875 +52254 0.38128662109375 +52255 0.404449462890625 +52256 0.3944091796875 +52257 0.3885498046875 +52258 0.362640380859375 +52259 0.27362060546875 +52260 0.11712646484375 +52261 -0.054901123046875 +52262 -0.19085693359375 +52263 -0.28570556640625 +52264 -0.339263916015625 +52265 -0.3775634765625 +52266 -0.445709228515625 +52267 -0.535064697265625 +52268 -0.629058837890625 +52269 -0.697601318359375 +52270 -0.70391845703125 +52271 -0.6424560546875 +52272 -0.491241455078125 +52273 -0.265716552734375 +52274 -0.023712158203125 +52275 0.201751708984375 +52276 0.375823974609375 +52277 0.485076904296875 +52278 0.56884765625 +52279 0.634765625 +52280 0.63763427734375 +52281 0.5660400390625 +52282 0.4720458984375 +52283 0.40692138671875 +52284 0.3778076171875 +52285 0.376953125 +52286 0.371978759765625 +52287 0.313140869140625 +52288 0.184417724609375 +52289 0.011199951171875 +52290 -0.171051025390625 +52291 -0.33740234375 +52292 -0.47198486328125 +52293 -0.560394287109375 +52294 -0.58056640625 +52295 -0.54754638671875 +52296 -0.508575439453125 +52297 -0.459503173828125 +52298 -0.394378662109375 +52299 -0.35260009765625 +52300 -0.31170654296875 +52301 -0.197418212890625 +52302 -0.007965087890625 +52303 0.207489013671875 +52304 0.409210205078125 +52305 0.57208251953125 +52306 0.66595458984375 +52307 0.65875244140625 +52308 0.56744384765625 +52309 0.431396484375 +52310 0.29443359375 +52311 0.182464599609375 +52312 0.06365966796875 +52313 -0.075958251953125 +52314 -0.189422607421875 +52315 -0.271942138671875 +52316 -0.342529296875 +52317 -0.364166259765625 +52318 -0.327239990234375 +52319 -0.2769775390625 +52320 -0.253692626953125 +52321 -0.24365234375 +52322 -0.1983642578125 +52323 -0.116241455078125 +52324 -0.036834716796875 +52325 0.034881591796875 +52326 0.09124755859375 +52327 0.10888671875 +52328 0.125518798828125 +52329 0.15771484375 +52330 0.17828369140625 +52331 0.17108154296875 +52332 0.129974365234375 +52333 0.082427978515625 +52334 0.027679443359375 +52335 -0.065643310546875 +52336 -0.15936279296875 +52337 -0.21307373046875 +52338 -0.234649658203125 +52339 -0.2001953125 +52340 -0.119171142578125 +52341 -0.024749755859375 +52342 0.085784912109375 +52343 0.178131103515625 +52344 0.215576171875 +52345 0.211456298828125 +52346 0.17523193359375 +52347 0.128753662109375 +52348 0.1019287109375 +52349 0.0743408203125 +52350 0.04327392578125 +52351 0.038177490234375 +52352 0.076263427734375 +52353 0.14105224609375 +52354 0.186431884765625 +52355 0.188812255859375 +52356 0.1390380859375 +52357 0.041778564453125 +52358 -0.079437255859375 +52359 -0.219390869140625 +52360 -0.367828369140625 +52361 -0.494873046875 +52362 -0.556243896484375 +52363 -0.508697509765625 +52364 -0.3756103515625 +52365 -0.218902587890625 +52366 -0.063751220703125 +52367 0.091552734375 +52368 0.23602294921875 +52369 0.342987060546875 +52370 0.39520263671875 +52371 0.389373779296875 +52372 0.324249267578125 +52373 0.224090576171875 +52374 0.124267578125 +52375 0.037078857421875 +52376 -0.010101318359375 +52377 -0.019439697265625 +52378 -0.022796630859375 +52379 -0.001556396484375 +52380 0.056304931640625 +52381 0.106719970703125 +52382 0.096893310546875 +52383 0.042694091796875 +52384 -0.018035888671875 +52385 -0.07586669921875 +52386 -0.11944580078125 +52387 -0.15972900390625 +52388 -0.202606201171875 +52389 -0.24859619140625 +52390 -0.30517578125 +52391 -0.36212158203125 +52392 -0.39141845703125 +52393 -0.35528564453125 +52394 -0.249969482421875 +52395 -0.092864990234375 +52396 0.08905029296875 +52397 0.2352294921875 +52398 0.318817138671875 +52399 0.358642578125 +52400 0.347747802734375 +52401 0.28564453125 +52402 0.223175048828125 +52403 0.196746826171875 +52404 0.179840087890625 +52405 0.155548095703125 +52406 0.151214599609375 +52407 0.156951904296875 +52408 0.13177490234375 +52409 0.100799560546875 +52410 0.087127685546875 +52411 0.05487060546875 +52412 -0.009002685546875 +52413 -0.10400390625 +52414 -0.229400634765625 +52415 -0.35552978515625 +52416 -0.441925048828125 +52417 -0.473846435546875 +52418 -0.464813232421875 +52419 -0.419097900390625 +52420 -0.334320068359375 +52421 -0.227935791015625 +52422 -0.12347412109375 +52423 -0.02764892578125 +52424 0.077667236328125 +52425 0.2132568359375 +52426 0.38885498046875 +52427 0.582794189453125 +52428 0.734039306640625 +52429 0.800140380859375 +52430 0.7783203125 +52431 0.6651611328125 +52432 0.45965576171875 +52433 0.199188232421875 +52434 -0.050689697265625 +52435 -0.23297119140625 +52436 -0.33013916015625 +52437 -0.368408203125 +52438 -0.378936767578125 +52439 -0.376983642578125 +52440 -0.37969970703125 +52441 -0.391510009765625 +52442 -0.385345458984375 +52443 -0.3419189453125 +52444 -0.28289794921875 +52445 -0.251617431640625 +52446 -0.266143798828125 +52447 -0.273345947265625 +52448 -0.216796875 +52449 -0.128265380859375 +52450 -0.068145751953125 +52451 -0.0430908203125 +52452 -0.024444580078125 +52453 0.020721435546875 +52454 0.124481201171875 +52455 0.25787353515625 +52456 0.379119873046875 +52457 0.47991943359375 +52458 0.5281982421875 +52459 0.511138916015625 +52460 0.456207275390625 +52461 0.407470703125 +52462 0.383758544921875 +52463 0.35687255859375 +52464 0.31182861328125 +52465 0.250885009765625 +52466 0.1654052734375 +52467 0.035247802734375 +52468 -0.142059326171875 +52469 -0.33563232421875 +52470 -0.5345458984375 +52471 -0.72186279296875 +52472 -0.836669921875 +52473 -0.8326416015625 +52474 -0.7296142578125 +52475 -0.582550048828125 +52476 -0.440093994140625 +52477 -0.324310302734375 +52478 -0.20147705078125 +52479 -0.044647216796875 +52480 0.103973388671875 +52481 0.202392578125 +52482 0.264495849609375 +52483 0.338897705078125 +52484 0.443817138671875 +52485 0.545074462890625 +52486 0.6173095703125 +52487 0.6524658203125 +52488 0.66339111328125 +52489 0.6561279296875 +52490 0.606781005859375 +52491 0.501190185546875 +52492 0.352783203125 +52493 0.176544189453125 +52494 -0.034820556640625 +52495 -0.258209228515625 +52496 -0.44244384765625 +52497 -0.5753173828125 +52498 -0.65203857421875 +52499 -0.641632080078125 +52500 -0.562164306640625 +52501 -0.458038330078125 +52502 -0.350555419921875 +52503 -0.260528564453125 +52504 -0.192108154296875 +52505 -0.141937255859375 +52506 -0.1021728515625 +52507 -0.062896728515625 +52508 -0.011932373046875 +52509 0.062835693359375 +52510 0.148712158203125 +52511 0.241729736328125 +52512 0.34912109375 +52513 0.457305908203125 +52514 0.54388427734375 +52515 0.5728759765625 +52516 0.506591796875 +52517 0.351226806640625 +52518 0.146514892578125 +52519 -0.05523681640625 +52520 -0.21624755859375 +52521 -0.334930419921875 +52522 -0.402984619140625 +52523 -0.4412841796875 +52524 -0.49578857421875 +52525 -0.5601806640625 +52526 -0.600738525390625 +52527 -0.584228515625 +52528 -0.47930908203125 +52529 -0.27935791015625 +52530 -0.0089111328125 +52531 0.268798828125 +52532 0.482818603515625 +52533 0.60369873046875 +52534 0.650421142578125 +52535 0.66400146484375 +52536 0.6414794921875 +52537 0.572540283203125 +52538 0.498138427734375 +52539 0.439453125 +52540 0.375518798828125 +52541 0.274505615234375 +52542 0.1087646484375 +52543 -0.099395751953125 +52544 -0.3182373046875 +52545 -0.5489501953125 +52546 -0.7738037109375 +52547 -0.86383056640625 +52548 -0.870391845703125 +52549 -0.86895751953125 +52550 -0.861053466796875 +52551 -0.765869140625 +52552 -0.5301513671875 +52553 -0.214691162109375 +52554 0.137359619140625 +52555 0.474822998046875 +52556 0.76239013671875 +52557 0.867462158203125 +52558 0.870361328125 +52559 0.86480712890625 +52560 0.831817626953125 +52561 0.677581787109375 +52562 0.495880126953125 +52563 0.30767822265625 +52564 0.116180419921875 +52565 -0.110748291015625 +52566 -0.381805419921875 +52567 -0.6572265625 +52568 -0.857421875 +52569 -0.870391845703125 +52570 -0.870391845703125 +52571 -0.86444091796875 +52572 -0.85723876953125 +52573 -0.790008544921875 +52574 -0.62847900390625 +52575 -0.3956298828125 +52576 -0.126708984375 +52577 0.150115966796875 +52578 0.424041748046875 +52579 0.670623779296875 +52580 0.854522705078125 +52581 0.866485595703125 +52582 0.86920166015625 +52583 0.8653564453125 +52584 0.857147216796875 +52585 0.766845703125 +52586 0.628509521484375 +52587 0.462127685546875 +52588 0.297210693359375 +52589 0.14862060546875 +52590 -0.00537109375 +52591 -0.15753173828125 +52592 -0.31304931640625 +52593 -0.48876953125 +52594 -0.6416015625 +52595 -0.751373291015625 +52596 -0.84619140625 +52597 -0.861297607421875 +52598 -0.863250732421875 +52599 -0.856597900390625 +52600 -0.7498779296875 +52601 -0.624542236328125 +52602 -0.47808837890625 +52603 -0.253387451171875 +52604 0.003692626953125 +52605 0.2257080078125 +52606 0.427154541015625 +52607 0.643218994140625 +52608 0.855926513671875 +52609 0.870361328125 +52610 0.870361328125 +52611 0.862762451171875 +52612 0.79669189453125 +52613 0.595794677734375 +52614 0.362152099609375 +52615 0.1270751953125 +52616 -0.086944580078125 +52617 -0.2784423828125 +52618 -0.484832763671875 +52619 -0.729583740234375 +52620 -0.86688232421875 +52621 -0.870391845703125 +52622 -0.86859130859375 +52623 -0.86279296875 +52624 -0.817962646484375 +52625 -0.6116943359375 +52626 -0.3128662109375 +52627 0.039398193359375 +52628 0.422821044921875 +52629 0.805145263671875 +52630 0.870361328125 +52631 0.870361328125 +52632 0.860015869140625 +52633 0.727935791015625 +52634 0.48114013671875 +52635 0.2059326171875 +52636 -0.06103515625 +52637 -0.29913330078125 +52638 -0.516204833984375 +52639 -0.7252197265625 +52640 -0.85980224609375 +52641 -0.870391845703125 +52642 -0.870391845703125 +52643 -0.858062744140625 +52644 -0.673004150390625 +52645 -0.42694091796875 +52646 -0.2100830078125 +52647 -0.0362548828125 +52648 0.10943603515625 +52649 0.23516845703125 +52650 0.373687744140625 +52651 0.517791748046875 +52652 0.602783203125 +52653 0.635711669921875 +52654 0.655181884765625 +52655 0.65948486328125 +52656 0.651275634765625 +52657 0.61846923828125 +52658 0.53753662109375 +52659 0.404144287109375 +52660 0.22186279296875 +52661 0.003997802734375 +52662 -0.22100830078125 +52663 -0.42449951171875 +52664 -0.579833984375 +52665 -0.641876220703125 +52666 -0.6177978515625 +52667 -0.575531005859375 +52668 -0.526336669921875 +52669 -0.42645263671875 +52670 -0.2581787109375 +52671 -0.068695068359375 +52672 0.09222412109375 +52673 0.232147216796875 +52674 0.3509521484375 +52675 0.410064697265625 +52676 0.372955322265625 +52677 0.2554931640625 +52678 0.10711669921875 +52679 -0.052886962890625 +52680 -0.186279296875 +52681 -0.23291015625 +52682 -0.209442138671875 +52683 -0.174163818359375 +52684 -0.126739501953125 +52685 -0.048126220703125 +52686 0.0426025390625 +52687 0.10748291015625 +52688 0.1409912109375 +52689 0.19708251953125 +52690 0.273651123046875 +52691 0.31768798828125 +52692 0.341094970703125 +52693 0.368011474609375 +52694 0.37249755859375 +52695 0.30072021484375 +52696 0.1517333984375 +52697 -0.01470947265625 +52698 -0.1883544921875 +52699 -0.372711181640625 +52700 -0.51397705078125 +52701 -0.57177734375 +52702 -0.53948974609375 +52703 -0.43511962890625 +52704 -0.2962646484375 +52705 -0.161102294921875 +52706 -0.0435791015625 +52707 0.060394287109375 +52708 0.13665771484375 +52709 0.170135498046875 +52710 0.16552734375 +52711 0.15728759765625 +52712 0.150787353515625 +52713 0.12200927734375 +52714 0.080108642578125 +52715 0.05126953125 +52716 0.062896728515625 +52717 0.09271240234375 +52718 0.092987060546875 +52719 0.07855224609375 +52720 0.06427001953125 +52721 0.0347900390625 +52722 -0.01171875 +52723 -0.056060791015625 +52724 -0.055511474609375 +52725 -0.010467529296875 +52726 0.02508544921875 +52727 0.025665283203125 +52728 0.017333984375 +52729 0.00189208984375 +52730 -0.03173828125 +52731 -0.071502685546875 +52732 -0.13543701171875 +52733 -0.219970703125 +52734 -0.300506591796875 +52735 -0.376312255859375 +52736 -0.416107177734375 +52737 -0.371124267578125 +52738 -0.242279052734375 +52739 -0.069732666015625 +52740 0.125640869140625 +52741 0.31268310546875 +52742 0.45501708984375 +52743 0.554779052734375 +52744 0.61065673828125 +52745 0.610931396484375 +52746 0.531463623046875 +52747 0.3883056640625 +52748 0.23468017578125 +52749 0.095245361328125 +52750 -0.00396728515625 +52751 -0.04852294921875 +52752 -0.055145263671875 +52753 -0.0758056640625 +52754 -0.138702392578125 +52755 -0.209197998046875 +52756 -0.289031982421875 +52757 -0.37884521484375 +52758 -0.456329345703125 +52759 -0.51641845703125 +52760 -0.519287109375 +52761 -0.458251953125 +52762 -0.384796142578125 +52763 -0.323699951171875 +52764 -0.269287109375 +52765 -0.1951904296875 +52766 -0.100006103515625 +52767 -0.01055908203125 +52768 0.1033935546875 +52769 0.24908447265625 +52770 0.373199462890625 +52771 0.45806884765625 +52772 0.511474609375 +52773 0.565399169921875 +52774 0.61138916015625 +52775 0.5897216796875 +52776 0.4906005859375 +52777 0.33148193359375 +52778 0.147796630859375 +52779 -0.01873779296875 +52780 -0.140289306640625 +52781 -0.191986083984375 +52782 -0.184295654296875 +52783 -0.161834716796875 +52784 -0.166595458984375 +52785 -0.19390869140625 +52786 -0.22442626953125 +52787 -0.279754638671875 +52788 -0.3389892578125 +52789 -0.3543701171875 +52790 -0.348175048828125 +52791 -0.32598876953125 +52792 -0.2581787109375 +52793 -0.139801025390625 +52794 0.014617919921875 +52795 0.144378662109375 +52796 0.221038818359375 +52797 0.27069091796875 +52798 0.294036865234375 +52799 0.311767578125 +52800 0.339141845703125 +52801 0.360260009765625 +52802 0.360504150390625 +52803 0.308380126953125 +52804 0.18170166015625 +52805 0.0047607421875 +52806 -0.17559814453125 +52807 -0.3143310546875 +52808 -0.36785888671875 +52809 -0.36248779296875 +52810 -0.343536376953125 +52811 -0.3018798828125 +52812 -0.231414794921875 +52813 -0.117645263671875 +52814 0.007049560546875 +52815 0.087982177734375 +52816 0.13946533203125 +52817 0.17425537109375 +52818 0.188201904296875 +52819 0.171234130859375 +52820 0.118438720703125 +52821 0.05706787109375 +52822 -0.010711669921875 +52823 -0.0914306640625 +52824 -0.162322998046875 +52825 -0.194549560546875 +52826 -0.1492919921875 +52827 -0.02166748046875 +52828 0.124053955078125 +52829 0.211151123046875 +52830 0.240447998046875 +52831 0.242218017578125 +52832 0.2257080078125 +52833 0.194366455078125 +52834 0.115509033203125 +52835 0.0128173828125 +52836 -0.053802490234375 +52837 -0.110626220703125 +52838 -0.199493408203125 +52839 -0.29437255859375 +52840 -0.33221435546875 +52841 -0.27972412109375 +52842 -0.185333251953125 +52843 -0.128204345703125 +52844 -0.115692138671875 +52845 -0.116455078125 +52846 -0.105926513671875 +52847 -0.053955078125 +52848 0.048797607421875 +52849 0.157318115234375 +52850 0.212005615234375 +52851 0.218475341796875 +52852 0.23724365234375 +52853 0.30535888671875 +52854 0.38128662109375 +52855 0.404449462890625 +52856 0.3944091796875 +52857 0.3885498046875 +52858 0.362640380859375 +52859 0.27362060546875 +52860 0.11712646484375 +52861 -0.054901123046875 +52862 -0.19085693359375 +52863 -0.28570556640625 +52864 -0.339263916015625 +52865 -0.3775634765625 +52866 -0.445709228515625 +52867 -0.535064697265625 +52868 -0.629058837890625 +52869 -0.697601318359375 +52870 -0.70391845703125 +52871 -0.6424560546875 +52872 -0.491241455078125 +52873 -0.265716552734375 +52874 -0.023712158203125 +52875 0.201751708984375 +52876 0.375823974609375 +52877 0.485076904296875 +52878 0.56884765625 +52879 0.634765625 +52880 0.63763427734375 +52881 0.5660400390625 +52882 0.4720458984375 +52883 0.40692138671875 +52884 0.3778076171875 +52885 0.376953125 +52886 0.371978759765625 +52887 0.313140869140625 +52888 0.184417724609375 +52889 0.011199951171875 +52890 -0.171051025390625 +52891 -0.33740234375 +52892 -0.47198486328125 +52893 -0.560394287109375 +52894 -0.58056640625 +52895 -0.54754638671875 +52896 -0.508575439453125 +52897 -0.459503173828125 +52898 -0.394378662109375 +52899 -0.35260009765625 +52900 -0.31170654296875 +52901 -0.197418212890625 +52902 -0.007965087890625 +52903 0.207489013671875 +52904 0.409210205078125 +52905 0.57208251953125 +52906 0.66595458984375 +52907 0.65875244140625 +52908 0.56744384765625 +52909 0.431396484375 +52910 0.29443359375 +52911 0.182464599609375 +52912 0.06365966796875 +52913 -0.075958251953125 +52914 -0.189422607421875 +52915 -0.271942138671875 +52916 -0.342529296875 +52917 -0.364166259765625 +52918 -0.327239990234375 +52919 -0.2769775390625 +52920 -0.253692626953125 +52921 -0.24365234375 +52922 -0.1983642578125 +52923 -0.116241455078125 +52924 -0.036834716796875 +52925 0.034881591796875 +52926 0.09124755859375 +52927 0.10888671875 +52928 0.125518798828125 +52929 0.15771484375 +52930 0.17828369140625 +52931 0.17108154296875 +52932 0.129974365234375 +52933 0.082427978515625 +52934 0.027679443359375 +52935 -0.065643310546875 +52936 -0.15936279296875 +52937 -0.21307373046875 +52938 -0.234649658203125 +52939 -0.2001953125 +52940 -0.119171142578125 +52941 -0.024749755859375 +52942 0.085784912109375 +52943 0.178131103515625 +52944 0.215576171875 +52945 0.211456298828125 +52946 0.17523193359375 +52947 0.128753662109375 +52948 0.1019287109375 +52949 0.0743408203125 +52950 0.04327392578125 +52951 0.038177490234375 +52952 0.076263427734375 +52953 0.14105224609375 +52954 0.186431884765625 +52955 0.188812255859375 +52956 0.1390380859375 +52957 0.041778564453125 +52958 -0.079437255859375 +52959 -0.219390869140625 +52960 -0.367828369140625 +52961 -0.494873046875 +52962 -0.556243896484375 +52963 -0.508697509765625 +52964 -0.3756103515625 +52965 -0.218902587890625 +52966 -0.063751220703125 +52967 0.091552734375 +52968 0.23602294921875 +52969 0.342987060546875 +52970 0.39520263671875 +52971 0.389373779296875 +52972 0.324249267578125 +52973 0.224090576171875 +52974 0.124267578125 +52975 0.037078857421875 +52976 -0.010101318359375 +52977 -0.019439697265625 +52978 -0.022796630859375 +52979 -0.001556396484375 +52980 0.056304931640625 +52981 0.106719970703125 +52982 0.096893310546875 +52983 0.042694091796875 +52984 -0.018035888671875 +52985 -0.07586669921875 +52986 -0.11944580078125 +52987 -0.15972900390625 +52988 -0.202606201171875 +52989 -0.24859619140625 +52990 -0.30517578125 +52991 -0.36212158203125 +52992 -0.39141845703125 +52993 -0.35528564453125 +52994 -0.249969482421875 +52995 -0.092864990234375 +52996 0.08905029296875 +52997 0.2352294921875 +52998 0.318817138671875 +52999 0.358642578125 +53000 0.347747802734375 +53001 0.28564453125 +53002 0.223175048828125 +53003 0.196746826171875 +53004 0.179840087890625 +53005 0.155548095703125 +53006 0.151214599609375 +53007 0.156951904296875 +53008 0.13177490234375 +53009 0.100799560546875 +53010 0.087127685546875 +53011 0.05487060546875 +53012 -0.009002685546875 +53013 -0.10400390625 +53014 -0.229400634765625 +53015 -0.35552978515625 +53016 -0.441925048828125 +53017 -0.473846435546875 +53018 -0.464813232421875 +53019 -0.419097900390625 +53020 -0.334320068359375 +53021 -0.227935791015625 +53022 -0.12347412109375 +53023 -0.02764892578125 +53024 0.077667236328125 +53025 0.2132568359375 +53026 0.38885498046875 +53027 0.582794189453125 +53028 0.734039306640625 +53029 0.800140380859375 +53030 0.7783203125 +53031 0.6651611328125 +53032 0.45965576171875 +53033 0.199188232421875 +53034 -0.050689697265625 +53035 -0.23297119140625 +53036 -0.33013916015625 +53037 -0.368408203125 +53038 -0.378936767578125 +53039 -0.376983642578125 +53040 -0.37969970703125 +53041 -0.391510009765625 +53042 -0.385345458984375 +53043 -0.3419189453125 +53044 -0.28289794921875 +53045 -0.251617431640625 +53046 -0.266143798828125 +53047 -0.273345947265625 +53048 -0.216796875 +53049 -0.128265380859375 +53050 -0.068145751953125 +53051 -0.0430908203125 +53052 -0.024444580078125 +53053 0.020721435546875 +53054 0.124481201171875 +53055 0.25787353515625 +53056 0.379119873046875 +53057 0.47991943359375 +53058 0.5281982421875 +53059 0.511138916015625 +53060 0.456207275390625 +53061 0.407470703125 +53062 0.383758544921875 +53063 0.35687255859375 +53064 0.31182861328125 +53065 0.250885009765625 +53066 0.1654052734375 +53067 0.035247802734375 +53068 -0.142059326171875 +53069 -0.33563232421875 +53070 -0.5345458984375 +53071 -0.72186279296875 +53072 -0.836669921875 +53073 -0.8326416015625 +53074 -0.7296142578125 +53075 -0.582550048828125 +53076 -0.440093994140625 +53077 -0.324310302734375 +53078 -0.20147705078125 +53079 -0.044647216796875 +53080 0.103973388671875 +53081 0.202392578125 +53082 0.264495849609375 +53083 0.338897705078125 +53084 0.443817138671875 +53085 0.545074462890625 +53086 0.6173095703125 +53087 0.6524658203125 +53088 0.66339111328125 +53089 0.6561279296875 +53090 0.606781005859375 +53091 0.501190185546875 +53092 0.352783203125 +53093 0.176544189453125 +53094 -0.034820556640625 +53095 -0.258209228515625 +53096 -0.44244384765625 +53097 -0.5753173828125 +53098 -0.65203857421875 +53099 -0.641632080078125 +53100 -0.562164306640625 +53101 -0.458038330078125 +53102 -0.350555419921875 +53103 -0.260528564453125 +53104 -0.192108154296875 +53105 -0.141937255859375 +53106 -0.1021728515625 +53107 -0.062896728515625 +53108 -0.011932373046875 +53109 0.062835693359375 +53110 0.148712158203125 +53111 0.241729736328125 +53112 0.34912109375 +53113 0.457305908203125 +53114 0.54388427734375 +53115 0.5728759765625 +53116 0.506591796875 +53117 0.351226806640625 +53118 0.146514892578125 +53119 -0.05523681640625 +53120 -0.21624755859375 +53121 -0.334930419921875 +53122 -0.402984619140625 +53123 -0.4412841796875 +53124 -0.49578857421875 +53125 -0.5601806640625 +53126 -0.600738525390625 +53127 -0.584228515625 +53128 -0.47930908203125 +53129 -0.27935791015625 +53130 -0.0089111328125 +53131 0.268798828125 +53132 0.482818603515625 +53133 0.60369873046875 +53134 0.650421142578125 +53135 0.66400146484375 +53136 0.6414794921875 +53137 0.572540283203125 +53138 0.498138427734375 +53139 0.439453125 +53140 0.375518798828125 +53141 0.274505615234375 +53142 0.1087646484375 +53143 -0.099395751953125 +53144 -0.3182373046875 +53145 -0.5489501953125 +53146 -0.7738037109375 +53147 -0.86383056640625 +53148 -0.870391845703125 +53149 -0.86895751953125 +53150 -0.861053466796875 +53151 -0.765869140625 +53152 -0.5301513671875 +53153 -0.214691162109375 +53154 0.137359619140625 +53155 0.474822998046875 +53156 0.76239013671875 +53157 0.867462158203125 +53158 0.870361328125 +53159 0.86480712890625 +53160 0.831817626953125 +53161 0.677581787109375 +53162 0.495880126953125 +53163 0.30767822265625 +53164 0.116180419921875 +53165 -0.110748291015625 +53166 -0.381805419921875 +53167 -0.6572265625 +53168 -0.857421875 +53169 -0.870391845703125 +53170 -0.870391845703125 +53171 -0.86444091796875 +53172 -0.85723876953125 +53173 -0.790008544921875 +53174 -0.62847900390625 +53175 -0.3956298828125 +53176 -0.126708984375 +53177 0.150115966796875 +53178 0.424041748046875 +53179 0.670623779296875 +53180 0.854522705078125 +53181 0.866485595703125 +53182 0.86920166015625 +53183 0.8653564453125 +53184 0.857147216796875 +53185 0.766845703125 +53186 0.628509521484375 +53187 0.462127685546875 +53188 0.297210693359375 +53189 0.14862060546875 +53190 -0.00537109375 +53191 -0.15753173828125 +53192 -0.31304931640625 +53193 -0.48876953125 +53194 -0.6416015625 +53195 -0.751373291015625 +53196 -0.84619140625 +53197 -0.861297607421875 +53198 -0.863250732421875 +53199 -0.856597900390625 +53200 -0.7498779296875 +53201 -0.624542236328125 +53202 -0.47808837890625 +53203 -0.253387451171875 +53204 0.003692626953125 +53205 0.2257080078125 +53206 0.427154541015625 +53207 0.643218994140625 +53208 0.855926513671875 +53209 0.870361328125 +53210 0.870361328125 +53211 0.862762451171875 +53212 0.79669189453125 +53213 0.595794677734375 +53214 0.362152099609375 +53215 0.1270751953125 +53216 -0.086944580078125 +53217 -0.2784423828125 +53218 -0.484832763671875 +53219 -0.729583740234375 +53220 -0.86688232421875 +53221 -0.870391845703125 +53222 -0.86859130859375 +53223 -0.86279296875 +53224 -0.817962646484375 +53225 -0.6116943359375 +53226 -0.3128662109375 +53227 0.039398193359375 +53228 0.422821044921875 +53229 0.805145263671875 +53230 0.870361328125 +53231 0.870361328125 +53232 0.860015869140625 +53233 0.727935791015625 +53234 0.48114013671875 +53235 0.2059326171875 +53236 -0.06103515625 +53237 -0.29913330078125 +53238 -0.516204833984375 +53239 -0.7252197265625 +53240 -0.85980224609375 +53241 -0.870391845703125 +53242 -0.870391845703125 +53243 -0.858062744140625 +53244 -0.673004150390625 +53245 -0.42694091796875 +53246 -0.2100830078125 +53247 -0.0362548828125 +53248 0.10943603515625 +53249 0.23516845703125 +53250 0.373687744140625 +53251 0.517791748046875 +53252 0.602783203125 +53253 0.635711669921875 +53254 0.655181884765625 +53255 0.65948486328125 +53256 0.651275634765625 +53257 0.61846923828125 +53258 0.53753662109375 +53259 0.404144287109375 +53260 0.22186279296875 +53261 0.003997802734375 +53262 -0.22100830078125 +53263 -0.42449951171875 +53264 -0.579833984375 +53265 -0.641876220703125 +53266 -0.6177978515625 +53267 -0.575531005859375 +53268 -0.526336669921875 +53269 -0.42645263671875 +53270 -0.2581787109375 +53271 -0.068695068359375 +53272 0.09222412109375 +53273 0.232147216796875 +53274 0.3509521484375 +53275 0.410064697265625 +53276 0.372955322265625 +53277 0.2554931640625 +53278 0.10711669921875 +53279 -0.052886962890625 +53280 -0.186279296875 +53281 -0.23291015625 +53282 -0.209442138671875 +53283 -0.174163818359375 +53284 -0.126739501953125 +53285 -0.048126220703125 +53286 0.0426025390625 +53287 0.10748291015625 +53288 0.1409912109375 +53289 0.19708251953125 +53290 0.273651123046875 +53291 0.31768798828125 +53292 0.341094970703125 +53293 0.368011474609375 +53294 0.37249755859375 +53295 0.30072021484375 +53296 0.1517333984375 +53297 -0.01470947265625 +53298 -0.1883544921875 +53299 -0.372711181640625 +53300 -0.51397705078125 +53301 -0.57177734375 +53302 -0.53948974609375 +53303 -0.43511962890625 +53304 -0.2962646484375 +53305 -0.161102294921875 +53306 -0.0435791015625 +53307 0.060394287109375 +53308 0.13665771484375 +53309 0.170135498046875 +53310 0.16552734375 +53311 0.15728759765625 +53312 0.150787353515625 +53313 0.12200927734375 +53314 0.080108642578125 +53315 0.05126953125 +53316 0.062896728515625 +53317 0.09271240234375 +53318 0.092987060546875 +53319 0.07855224609375 +53320 0.06427001953125 +53321 0.0347900390625 +53322 -0.01171875 +53323 -0.056060791015625 +53324 -0.055511474609375 +53325 -0.010467529296875 +53326 0.02508544921875 +53327 0.025665283203125 +53328 0.017333984375 +53329 0.00189208984375 +53330 -0.03173828125 +53331 -0.071502685546875 +53332 -0.13543701171875 +53333 -0.219970703125 +53334 -0.300506591796875 +53335 -0.376312255859375 +53336 -0.416107177734375 +53337 -0.371124267578125 +53338 -0.242279052734375 +53339 -0.069732666015625 +53340 0.125640869140625 +53341 0.31268310546875 +53342 0.45501708984375 +53343 0.554779052734375 +53344 0.61065673828125 +53345 0.610931396484375 +53346 0.531463623046875 +53347 0.3883056640625 +53348 0.23468017578125 +53349 0.095245361328125 +53350 -0.00396728515625 +53351 -0.04852294921875 +53352 -0.055145263671875 +53353 -0.0758056640625 +53354 -0.138702392578125 +53355 -0.209197998046875 +53356 -0.289031982421875 +53357 -0.37884521484375 +53358 -0.456329345703125 +53359 -0.51641845703125 +53360 -0.519287109375 +53361 -0.458251953125 +53362 -0.384796142578125 +53363 -0.323699951171875 +53364 -0.269287109375 +53365 -0.1951904296875 +53366 -0.100006103515625 +53367 -0.01055908203125 +53368 0.1033935546875 +53369 0.24908447265625 +53370 0.373199462890625 +53371 0.45806884765625 +53372 0.511474609375 +53373 0.565399169921875 +53374 0.61138916015625 +53375 0.5897216796875 +53376 0.4906005859375 +53377 0.33148193359375 +53378 0.147796630859375 +53379 -0.01873779296875 +53380 -0.140289306640625 +53381 -0.191986083984375 +53382 -0.184295654296875 +53383 -0.161834716796875 +53384 -0.166595458984375 +53385 -0.19390869140625 +53386 -0.22442626953125 +53387 -0.279754638671875 +53388 -0.3389892578125 +53389 -0.3543701171875 +53390 -0.348175048828125 +53391 -0.32598876953125 +53392 -0.2581787109375 +53393 -0.139801025390625 +53394 0.014617919921875 +53395 0.144378662109375 +53396 0.221038818359375 +53397 0.27069091796875 +53398 0.294036865234375 +53399 0.311767578125 +53400 0.339141845703125 +53401 0.360260009765625 +53402 0.360504150390625 +53403 0.308380126953125 +53404 0.18170166015625 +53405 0.0047607421875 +53406 -0.17559814453125 +53407 -0.3143310546875 +53408 -0.36785888671875 +53409 -0.36248779296875 +53410 -0.343536376953125 +53411 -0.3018798828125 +53412 -0.231414794921875 +53413 -0.117645263671875 +53414 0.007049560546875 +53415 0.087982177734375 +53416 0.13946533203125 +53417 0.17425537109375 +53418 0.188201904296875 +53419 0.171234130859375 +53420 0.118438720703125 +53421 0.05706787109375 +53422 -0.010711669921875 +53423 -0.0914306640625 +53424 -0.162322998046875 +53425 -0.194549560546875 +53426 -0.1492919921875 +53427 -0.02166748046875 +53428 0.124053955078125 +53429 0.211151123046875 +53430 0.240447998046875 +53431 0.242218017578125 +53432 0.2257080078125 +53433 0.194366455078125 +53434 0.115509033203125 +53435 0.0128173828125 +53436 -0.053802490234375 +53437 -0.110626220703125 +53438 -0.199493408203125 +53439 -0.29437255859375 +53440 -0.33221435546875 +53441 -0.27972412109375 +53442 -0.185333251953125 +53443 -0.128204345703125 +53444 -0.115692138671875 +53445 -0.116455078125 +53446 -0.105926513671875 +53447 -0.053955078125 +53448 0.048797607421875 +53449 0.157318115234375 +53450 0.212005615234375 +53451 0.218475341796875 +53452 0.23724365234375 +53453 0.30535888671875 +53454 0.38128662109375 +53455 0.404449462890625 +53456 0.3944091796875 +53457 0.3885498046875 +53458 0.362640380859375 +53459 0.27362060546875 +53460 0.11712646484375 +53461 -0.054901123046875 +53462 -0.19085693359375 +53463 -0.28570556640625 +53464 -0.339263916015625 +53465 -0.3775634765625 +53466 -0.445709228515625 +53467 -0.535064697265625 +53468 -0.629058837890625 +53469 -0.697601318359375 +53470 -0.70391845703125 +53471 -0.6424560546875 +53472 -0.491241455078125 +53473 -0.265716552734375 +53474 -0.023712158203125 +53475 0.201751708984375 +53476 0.375823974609375 +53477 0.485076904296875 +53478 0.56884765625 +53479 0.634765625 +53480 0.63763427734375 +53481 0.5660400390625 +53482 0.4720458984375 +53483 0.40692138671875 +53484 0.3778076171875 +53485 0.376953125 +53486 0.371978759765625 +53487 0.313140869140625 +53488 0.184417724609375 +53489 0.011199951171875 +53490 -0.171051025390625 +53491 -0.33740234375 +53492 -0.47198486328125 +53493 -0.560394287109375 +53494 -0.58056640625 +53495 -0.54754638671875 +53496 -0.508575439453125 +53497 -0.459503173828125 +53498 -0.394378662109375 +53499 -0.35260009765625 +53500 -0.31170654296875 +53501 -0.197418212890625 +53502 -0.007965087890625 +53503 0.207489013671875 +53504 0.409210205078125 +53505 0.57208251953125 +53506 0.66595458984375 +53507 0.65875244140625 +53508 0.56744384765625 +53509 0.431396484375 +53510 0.29443359375 +53511 0.182464599609375 +53512 0.06365966796875 +53513 -0.075958251953125 +53514 -0.189422607421875 +53515 -0.271942138671875 +53516 -0.342529296875 +53517 -0.364166259765625 +53518 -0.327239990234375 +53519 -0.2769775390625 +53520 -0.253692626953125 +53521 -0.24365234375 +53522 -0.1983642578125 +53523 -0.116241455078125 +53524 -0.036834716796875 +53525 0.034881591796875 +53526 0.09124755859375 +53527 0.10888671875 +53528 0.125518798828125 +53529 0.15771484375 +53530 0.17828369140625 +53531 0.17108154296875 +53532 0.129974365234375 +53533 0.082427978515625 +53534 0.027679443359375 +53535 -0.065643310546875 +53536 -0.15936279296875 +53537 -0.21307373046875 +53538 -0.234649658203125 +53539 -0.2001953125 +53540 -0.119171142578125 +53541 -0.024749755859375 +53542 0.085784912109375 +53543 0.178131103515625 +53544 0.215576171875 +53545 0.211456298828125 +53546 0.17523193359375 +53547 0.128753662109375 +53548 0.1019287109375 +53549 0.0743408203125 +53550 0.04327392578125 +53551 0.038177490234375 +53552 0.076263427734375 +53553 0.14105224609375 +53554 0.186431884765625 +53555 0.188812255859375 +53556 0.1390380859375 +53557 0.041778564453125 +53558 -0.079437255859375 +53559 -0.219390869140625 +53560 -0.367828369140625 +53561 -0.494873046875 +53562 -0.556243896484375 +53563 -0.508697509765625 +53564 -0.3756103515625 +53565 -0.218902587890625 +53566 -0.063751220703125 +53567 0.091552734375 +53568 0.23602294921875 +53569 0.342987060546875 +53570 0.39520263671875 +53571 0.389373779296875 +53572 0.324249267578125 +53573 0.224090576171875 +53574 0.124267578125 +53575 0.037078857421875 +53576 -0.010101318359375 +53577 -0.019439697265625 +53578 -0.022796630859375 +53579 -0.001556396484375 +53580 0.056304931640625 +53581 0.106719970703125 +53582 0.096893310546875 +53583 0.042694091796875 +53584 -0.018035888671875 +53585 -0.07586669921875 +53586 -0.11944580078125 +53587 -0.15972900390625 +53588 -0.202606201171875 +53589 -0.24859619140625 +53590 -0.30517578125 +53591 -0.36212158203125 +53592 -0.39141845703125 +53593 -0.35528564453125 +53594 -0.249969482421875 +53595 -0.092864990234375 +53596 0.08905029296875 +53597 0.2352294921875 +53598 0.318817138671875 +53599 0.358642578125 +53600 0.347747802734375 +53601 0.28564453125 +53602 0.223175048828125 +53603 0.196746826171875 +53604 0.179840087890625 +53605 0.155548095703125 +53606 0.151214599609375 +53607 0.156951904296875 +53608 0.13177490234375 +53609 0.100799560546875 +53610 0.087127685546875 +53611 0.05487060546875 +53612 -0.009002685546875 +53613 -0.10400390625 +53614 -0.229400634765625 +53615 -0.35552978515625 +53616 -0.441925048828125 +53617 -0.473846435546875 +53618 -0.464813232421875 +53619 -0.419097900390625 +53620 -0.334320068359375 +53621 -0.227935791015625 +53622 -0.12347412109375 +53623 -0.02764892578125 +53624 0.077667236328125 +53625 0.2132568359375 +53626 0.38885498046875 +53627 0.582794189453125 +53628 0.734039306640625 +53629 0.800140380859375 +53630 0.7783203125 +53631 0.6651611328125 +53632 0.45965576171875 +53633 0.199188232421875 +53634 -0.050689697265625 +53635 -0.23297119140625 +53636 -0.33013916015625 +53637 -0.368408203125 +53638 -0.378936767578125 +53639 -0.376983642578125 +53640 -0.37969970703125 +53641 -0.391510009765625 +53642 -0.385345458984375 +53643 -0.3419189453125 +53644 -0.28289794921875 +53645 -0.251617431640625 +53646 -0.266143798828125 +53647 -0.273345947265625 +53648 -0.216796875 +53649 -0.128265380859375 +53650 -0.068145751953125 +53651 -0.0430908203125 +53652 -0.024444580078125 +53653 0.020721435546875 +53654 0.124481201171875 +53655 0.25787353515625 +53656 0.379119873046875 +53657 0.47991943359375 +53658 0.5281982421875 +53659 0.511138916015625 +53660 0.456207275390625 +53661 0.407470703125 +53662 0.383758544921875 +53663 0.35687255859375 +53664 0.31182861328125 +53665 0.250885009765625 +53666 0.1654052734375 +53667 0.035247802734375 +53668 -0.142059326171875 +53669 -0.33563232421875 +53670 -0.5345458984375 +53671 -0.72186279296875 +53672 -0.836669921875 +53673 -0.8326416015625 +53674 -0.7296142578125 +53675 -0.582550048828125 +53676 -0.440093994140625 +53677 -0.324310302734375 +53678 -0.20147705078125 +53679 -0.044647216796875 +53680 0.103973388671875 +53681 0.202392578125 +53682 0.264495849609375 +53683 0.338897705078125 +53684 0.443817138671875 +53685 0.545074462890625 +53686 0.6173095703125 +53687 0.6524658203125 +53688 0.66339111328125 +53689 0.6561279296875 +53690 0.606781005859375 +53691 0.501190185546875 +53692 0.352783203125 +53693 0.176544189453125 +53694 -0.034820556640625 +53695 -0.258209228515625 +53696 -0.44244384765625 +53697 -0.5753173828125 +53698 -0.65203857421875 +53699 -0.641632080078125 +53700 -0.562164306640625 +53701 -0.458038330078125 +53702 -0.350555419921875 +53703 -0.260528564453125 +53704 -0.192108154296875 +53705 -0.141937255859375 +53706 -0.1021728515625 +53707 -0.062896728515625 +53708 -0.011932373046875 +53709 0.062835693359375 +53710 0.148712158203125 +53711 0.241729736328125 +53712 0.34912109375 +53713 0.457305908203125 +53714 0.54388427734375 +53715 0.5728759765625 +53716 0.506591796875 +53717 0.351226806640625 +53718 0.146514892578125 +53719 -0.05523681640625 +53720 -0.21624755859375 +53721 -0.334930419921875 +53722 -0.402984619140625 +53723 -0.4412841796875 +53724 -0.49578857421875 +53725 -0.5601806640625 +53726 -0.600738525390625 +53727 -0.584228515625 +53728 -0.47930908203125 +53729 -0.27935791015625 +53730 -0.0089111328125 +53731 0.268798828125 +53732 0.482818603515625 +53733 0.60369873046875 +53734 0.650421142578125 +53735 0.66400146484375 +53736 0.6414794921875 +53737 0.572540283203125 +53738 0.498138427734375 +53739 0.439453125 +53740 0.375518798828125 +53741 0.274505615234375 +53742 0.1087646484375 +53743 -0.099395751953125 +53744 -0.3182373046875 +53745 -0.5489501953125 +53746 -0.7738037109375 +53747 -0.86383056640625 +53748 -0.870391845703125 +53749 -0.86895751953125 +53750 -0.861053466796875 +53751 -0.765869140625 +53752 -0.5301513671875 +53753 -0.214691162109375 +53754 0.137359619140625 +53755 0.474822998046875 +53756 0.76239013671875 +53757 0.867462158203125 +53758 0.870361328125 +53759 0.86480712890625 +53760 0.831817626953125 +53761 0.677581787109375 +53762 0.495880126953125 +53763 0.30767822265625 +53764 0.116180419921875 +53765 -0.110748291015625 +53766 -0.381805419921875 +53767 -0.6572265625 +53768 -0.857421875 +53769 -0.870391845703125 +53770 -0.870391845703125 +53771 -0.86444091796875 +53772 -0.85723876953125 +53773 -0.790008544921875 +53774 -0.62847900390625 +53775 -0.3956298828125 +53776 -0.126708984375 +53777 0.150115966796875 +53778 0.424041748046875 +53779 0.670623779296875 +53780 0.854522705078125 +53781 0.866485595703125 +53782 0.86920166015625 +53783 0.8653564453125 +53784 0.857147216796875 +53785 0.766845703125 +53786 0.628509521484375 +53787 0.462127685546875 +53788 0.297210693359375 +53789 0.14862060546875 +53790 -0.00537109375 +53791 -0.15753173828125 +53792 -0.31304931640625 +53793 -0.48876953125 +53794 -0.6416015625 +53795 -0.751373291015625 +53796 -0.84619140625 +53797 -0.861297607421875 +53798 -0.863250732421875 +53799 -0.856597900390625 +53800 -0.7498779296875 +53801 -0.624542236328125 +53802 -0.47808837890625 +53803 -0.253387451171875 +53804 0.003692626953125 +53805 0.2257080078125 +53806 0.427154541015625 +53807 0.643218994140625 +53808 0.855926513671875 +53809 0.870361328125 +53810 0.870361328125 +53811 0.862762451171875 +53812 0.79669189453125 +53813 0.595794677734375 +53814 0.362152099609375 +53815 0.1270751953125 +53816 -0.086944580078125 +53817 -0.2784423828125 +53818 -0.484832763671875 +53819 -0.729583740234375 +53820 -0.86688232421875 +53821 -0.870391845703125 +53822 -0.86859130859375 +53823 -0.86279296875 +53824 -0.817962646484375 +53825 -0.6116943359375 +53826 -0.3128662109375 +53827 0.039398193359375 +53828 0.422821044921875 +53829 0.805145263671875 +53830 0.870361328125 +53831 0.870361328125 +53832 0.860015869140625 +53833 0.727935791015625 +53834 0.48114013671875 +53835 0.2059326171875 +53836 -0.06103515625 +53837 -0.29913330078125 +53838 -0.516204833984375 +53839 -0.7252197265625 +53840 -0.85980224609375 +53841 -0.870391845703125 +53842 -0.870391845703125 +53843 -0.858062744140625 +53844 -0.673004150390625 +53845 -0.42694091796875 +53846 -0.2100830078125 +53847 -0.0362548828125 +53848 0.10943603515625 +53849 0.23516845703125 +53850 0.373687744140625 +53851 0.517791748046875 +53852 0.602783203125 +53853 0.635711669921875 +53854 0.655181884765625 +53855 0.65948486328125 +53856 0.651275634765625 +53857 0.61846923828125 +53858 0.53753662109375 +53859 0.404144287109375 +53860 0.22186279296875 +53861 0.003997802734375 +53862 -0.22100830078125 +53863 -0.42449951171875 +53864 -0.579833984375 +53865 -0.641876220703125 +53866 -0.6177978515625 +53867 -0.575531005859375 +53868 -0.526336669921875 +53869 -0.42645263671875 +53870 -0.2581787109375 +53871 -0.068695068359375 +53872 0.09222412109375 +53873 0.232147216796875 +53874 0.3509521484375 +53875 0.410064697265625 +53876 0.372955322265625 +53877 0.2554931640625 +53878 0.10711669921875 +53879 -0.052886962890625 +53880 -0.186279296875 +53881 -0.23291015625 +53882 -0.209442138671875 +53883 -0.174163818359375 +53884 -0.126739501953125 +53885 -0.048126220703125 +53886 0.0426025390625 +53887 0.10748291015625 +53888 0.1409912109375 +53889 0.19708251953125 +53890 0.273651123046875 +53891 0.31768798828125 +53892 0.341094970703125 +53893 0.368011474609375 +53894 0.37249755859375 +53895 0.30072021484375 +53896 0.1517333984375 +53897 -0.01470947265625 +53898 -0.1883544921875 +53899 -0.372711181640625 +53900 -0.51397705078125 +53901 -0.57177734375 +53902 -0.53948974609375 +53903 -0.43511962890625 +53904 -0.2962646484375 +53905 -0.161102294921875 +53906 -0.0435791015625 +53907 0.060394287109375 +53908 0.13665771484375 +53909 0.170135498046875 +53910 0.16552734375 +53911 0.15728759765625 +53912 0.150787353515625 +53913 0.12200927734375 +53914 0.080108642578125 +53915 0.05126953125 +53916 0.062896728515625 +53917 0.09271240234375 +53918 0.092987060546875 +53919 0.07855224609375 +53920 0.06427001953125 +53921 0.0347900390625 +53922 -0.01171875 +53923 -0.056060791015625 +53924 -0.055511474609375 +53925 -0.010467529296875 +53926 0.02508544921875 +53927 0.025665283203125 +53928 0.017333984375 +53929 0.00189208984375 +53930 -0.03173828125 +53931 -0.071502685546875 +53932 -0.13543701171875 +53933 -0.219970703125 +53934 -0.300506591796875 +53935 -0.376312255859375 +53936 -0.416107177734375 +53937 -0.371124267578125 +53938 -0.242279052734375 +53939 -0.069732666015625 +53940 0.125640869140625 +53941 0.31268310546875 +53942 0.45501708984375 +53943 0.554779052734375 +53944 0.61065673828125 +53945 0.610931396484375 +53946 0.531463623046875 +53947 0.3883056640625 +53948 0.23468017578125 +53949 0.095245361328125 +53950 -0.00396728515625 +53951 -0.04852294921875 +53952 -0.055145263671875 +53953 -0.0758056640625 +53954 -0.138702392578125 +53955 -0.209197998046875 +53956 -0.289031982421875 +53957 -0.37884521484375 +53958 -0.456329345703125 +53959 -0.51641845703125 +53960 -0.519287109375 +53961 -0.458251953125 +53962 -0.384796142578125 +53963 -0.323699951171875 +53964 -0.269287109375 +53965 -0.1951904296875 +53966 -0.100006103515625 +53967 -0.01055908203125 +53968 0.1033935546875 +53969 0.24908447265625 +53970 0.373199462890625 +53971 0.45806884765625 +53972 0.511474609375 +53973 0.565399169921875 +53974 0.61138916015625 +53975 0.5897216796875 +53976 0.4906005859375 +53977 0.33148193359375 +53978 0.147796630859375 +53979 -0.01873779296875 +53980 -0.140289306640625 +53981 -0.191986083984375 +53982 -0.184295654296875 +53983 -0.161834716796875 +53984 -0.166595458984375 +53985 -0.19390869140625 +53986 -0.22442626953125 +53987 -0.279754638671875 +53988 -0.3389892578125 +53989 -0.3543701171875 +53990 -0.348175048828125 +53991 -0.32598876953125 +53992 -0.2581787109375 +53993 -0.139801025390625 +53994 0.014617919921875 +53995 0.144378662109375 +53996 0.221038818359375 +53997 0.27069091796875 +53998 0.294036865234375 +53999 0.311767578125 +54000 0.339141845703125 +54001 0.360260009765625 +54002 0.360504150390625 +54003 0.308380126953125 +54004 0.18170166015625 +54005 0.0047607421875 +54006 -0.17559814453125 +54007 -0.3143310546875 +54008 -0.36785888671875 +54009 -0.36248779296875 +54010 -0.343536376953125 +54011 -0.3018798828125 +54012 -0.231414794921875 +54013 -0.117645263671875 +54014 0.007049560546875 +54015 0.087982177734375 +54016 0.13946533203125 +54017 0.17425537109375 +54018 0.188201904296875 +54019 0.171234130859375 +54020 0.118438720703125 +54021 0.05706787109375 +54022 -0.010711669921875 +54023 -0.0914306640625 +54024 -0.162322998046875 +54025 -0.194549560546875 +54026 -0.1492919921875 +54027 -0.02166748046875 +54028 0.124053955078125 +54029 0.211151123046875 +54030 0.240447998046875 +54031 0.242218017578125 +54032 0.2257080078125 +54033 0.194366455078125 +54034 0.115509033203125 +54035 0.0128173828125 +54036 -0.053802490234375 +54037 -0.110626220703125 +54038 -0.199493408203125 +54039 -0.29437255859375 +54040 -0.33221435546875 +54041 -0.27972412109375 +54042 -0.185333251953125 +54043 -0.128204345703125 +54044 -0.115692138671875 +54045 -0.116455078125 +54046 -0.105926513671875 +54047 -0.053955078125 +54048 0.048797607421875 +54049 0.157318115234375 +54050 0.212005615234375 +54051 0.218475341796875 +54052 0.23724365234375 +54053 0.30535888671875 +54054 0.38128662109375 +54055 0.404449462890625 +54056 0.3944091796875 +54057 0.3885498046875 +54058 0.362640380859375 +54059 0.27362060546875 +54060 0.11712646484375 +54061 -0.054901123046875 +54062 -0.19085693359375 +54063 -0.28570556640625 +54064 -0.339263916015625 +54065 -0.3775634765625 +54066 -0.445709228515625 +54067 -0.535064697265625 +54068 -0.629058837890625 +54069 -0.697601318359375 +54070 -0.70391845703125 +54071 -0.6424560546875 +54072 -0.491241455078125 +54073 -0.265716552734375 +54074 -0.023712158203125 +54075 0.201751708984375 +54076 0.375823974609375 +54077 0.485076904296875 +54078 0.56884765625 +54079 0.634765625 +54080 0.63763427734375 +54081 0.5660400390625 +54082 0.4720458984375 +54083 0.40692138671875 +54084 0.3778076171875 +54085 0.376953125 +54086 0.371978759765625 +54087 0.313140869140625 +54088 0.184417724609375 +54089 0.011199951171875 +54090 -0.171051025390625 +54091 -0.33740234375 +54092 -0.47198486328125 +54093 -0.560394287109375 +54094 -0.58056640625 +54095 -0.54754638671875 +54096 -0.508575439453125 +54097 -0.459503173828125 +54098 -0.394378662109375 +54099 -0.35260009765625 +54100 -0.31170654296875 +54101 -0.197418212890625 +54102 -0.007965087890625 +54103 0.207489013671875 +54104 0.409210205078125 +54105 0.57208251953125 +54106 0.66595458984375 +54107 0.65875244140625 +54108 0.56744384765625 +54109 0.431396484375 +54110 0.29443359375 +54111 0.182464599609375 +54112 0.06365966796875 +54113 -0.075958251953125 +54114 -0.189422607421875 +54115 -0.271942138671875 +54116 -0.342529296875 +54117 -0.364166259765625 +54118 -0.327239990234375 +54119 -0.2769775390625 +54120 -0.253692626953125 +54121 -0.24365234375 +54122 -0.1983642578125 +54123 -0.116241455078125 +54124 -0.036834716796875 +54125 0.034881591796875 +54126 0.09124755859375 +54127 0.10888671875 +54128 0.125518798828125 +54129 0.15771484375 +54130 0.17828369140625 +54131 0.17108154296875 +54132 0.129974365234375 +54133 0.082427978515625 +54134 0.027679443359375 +54135 -0.065643310546875 +54136 -0.15936279296875 +54137 -0.21307373046875 +54138 -0.234649658203125 +54139 -0.2001953125 +54140 -0.119171142578125 +54141 -0.024749755859375 +54142 0.085784912109375 +54143 0.178131103515625 +54144 0.215576171875 +54145 0.211456298828125 +54146 0.17523193359375 +54147 0.128753662109375 +54148 0.1019287109375 +54149 0.0743408203125 +54150 0.04327392578125 +54151 0.038177490234375 +54152 0.076263427734375 +54153 0.14105224609375 +54154 0.186431884765625 +54155 0.188812255859375 +54156 0.1390380859375 +54157 0.041778564453125 +54158 -0.079437255859375 +54159 -0.219390869140625 +54160 -0.367828369140625 +54161 -0.494873046875 +54162 -0.556243896484375 +54163 -0.508697509765625 +54164 -0.3756103515625 +54165 -0.218902587890625 +54166 -0.063751220703125 +54167 0.091552734375 +54168 0.23602294921875 +54169 0.342987060546875 +54170 0.39520263671875 +54171 0.389373779296875 +54172 0.324249267578125 +54173 0.224090576171875 +54174 0.124267578125 +54175 0.037078857421875 +54176 -0.010101318359375 +54177 -0.019439697265625 +54178 -0.022796630859375 +54179 -0.001556396484375 +54180 0.056304931640625 +54181 0.106719970703125 +54182 0.096893310546875 +54183 0.042694091796875 +54184 -0.018035888671875 +54185 -0.07586669921875 +54186 -0.11944580078125 +54187 -0.15972900390625 +54188 -0.202606201171875 +54189 -0.24859619140625 +54190 -0.30517578125 +54191 -0.36212158203125 +54192 -0.39141845703125 +54193 -0.35528564453125 +54194 -0.249969482421875 +54195 -0.092864990234375 +54196 0.08905029296875 +54197 0.2352294921875 +54198 0.318817138671875 +54199 0.358642578125 +54200 0.347747802734375 +54201 0.28564453125 +54202 0.223175048828125 +54203 0.196746826171875 +54204 0.179840087890625 +54205 0.155548095703125 +54206 0.151214599609375 +54207 0.156951904296875 +54208 0.13177490234375 +54209 0.100799560546875 +54210 0.087127685546875 +54211 0.05487060546875 +54212 -0.009002685546875 +54213 -0.10400390625 +54214 -0.229400634765625 +54215 -0.35552978515625 +54216 -0.441925048828125 +54217 -0.473846435546875 +54218 -0.464813232421875 +54219 -0.419097900390625 +54220 -0.334320068359375 +54221 -0.227935791015625 +54222 -0.12347412109375 +54223 -0.02764892578125 +54224 0.077667236328125 +54225 0.2132568359375 +54226 0.38885498046875 +54227 0.582794189453125 +54228 0.734039306640625 +54229 0.800140380859375 +54230 0.7783203125 +54231 0.6651611328125 +54232 0.45965576171875 +54233 0.199188232421875 +54234 -0.050689697265625 +54235 -0.23297119140625 +54236 -0.33013916015625 +54237 -0.368408203125 +54238 -0.378936767578125 +54239 -0.376983642578125 +54240 -0.37969970703125 +54241 -0.391510009765625 +54242 -0.385345458984375 +54243 -0.3419189453125 +54244 -0.28289794921875 +54245 -0.251617431640625 +54246 -0.266143798828125 +54247 -0.273345947265625 +54248 -0.216796875 +54249 -0.128265380859375 +54250 -0.068145751953125 +54251 -0.0430908203125 +54252 -0.024444580078125 +54253 0.020721435546875 +54254 0.124481201171875 +54255 0.25787353515625 +54256 0.379119873046875 +54257 0.47991943359375 +54258 0.5281982421875 +54259 0.511138916015625 +54260 0.456207275390625 +54261 0.407470703125 +54262 0.383758544921875 +54263 0.35687255859375 +54264 0.31182861328125 +54265 0.250885009765625 +54266 0.1654052734375 +54267 0.035247802734375 +54268 -0.142059326171875 +54269 -0.33563232421875 +54270 -0.5345458984375 +54271 -0.72186279296875 +54272 -0.836669921875 +54273 -0.8326416015625 +54274 -0.7296142578125 +54275 -0.582550048828125 +54276 -0.440093994140625 +54277 -0.324310302734375 +54278 -0.20147705078125 +54279 -0.044647216796875 +54280 0.103973388671875 +54281 0.202392578125 +54282 0.264495849609375 +54283 0.338897705078125 +54284 0.443817138671875 +54285 0.545074462890625 +54286 0.6173095703125 +54287 0.6524658203125 +54288 0.66339111328125 +54289 0.6561279296875 +54290 0.606781005859375 +54291 0.501190185546875 +54292 0.352783203125 +54293 0.176544189453125 +54294 -0.034820556640625 +54295 -0.258209228515625 +54296 -0.44244384765625 +54297 -0.5753173828125 +54298 -0.65203857421875 +54299 -0.641632080078125 +54300 -0.562164306640625 +54301 -0.458038330078125 +54302 -0.350555419921875 +54303 -0.260528564453125 +54304 -0.192108154296875 +54305 -0.141937255859375 +54306 -0.1021728515625 +54307 -0.062896728515625 +54308 -0.011932373046875 +54309 0.062835693359375 +54310 0.148712158203125 +54311 0.241729736328125 +54312 0.34912109375 +54313 0.457305908203125 +54314 0.54388427734375 +54315 0.5728759765625 +54316 0.506591796875 +54317 0.351226806640625 +54318 0.146514892578125 +54319 -0.05523681640625 +54320 -0.21624755859375 +54321 -0.334930419921875 +54322 -0.402984619140625 +54323 -0.4412841796875 +54324 -0.49578857421875 +54325 -0.5601806640625 +54326 -0.600738525390625 +54327 -0.584228515625 +54328 -0.47930908203125 +54329 -0.27935791015625 +54330 -0.0089111328125 +54331 0.268798828125 +54332 0.482818603515625 +54333 0.60369873046875 +54334 0.650421142578125 +54335 0.66400146484375 +54336 0.6414794921875 +54337 0.572540283203125 +54338 0.498138427734375 +54339 0.439453125 +54340 0.375518798828125 +54341 0.274505615234375 +54342 0.1087646484375 +54343 -0.099395751953125 +54344 -0.3182373046875 +54345 -0.5489501953125 +54346 -0.7738037109375 +54347 -0.86383056640625 +54348 -0.870391845703125 +54349 -0.86895751953125 +54350 -0.861053466796875 +54351 -0.765869140625 +54352 -0.5301513671875 +54353 -0.214691162109375 +54354 0.137359619140625 +54355 0.474822998046875 +54356 0.76239013671875 +54357 0.867462158203125 +54358 0.870361328125 +54359 0.86480712890625 +54360 0.831817626953125 +54361 0.677581787109375 +54362 0.495880126953125 +54363 0.30767822265625 +54364 0.116180419921875 +54365 -0.110748291015625 +54366 -0.381805419921875 +54367 -0.6572265625 +54368 -0.857421875 +54369 -0.870391845703125 +54370 -0.870391845703125 +54371 -0.86444091796875 +54372 -0.85723876953125 +54373 -0.790008544921875 +54374 -0.62847900390625 +54375 -0.3956298828125 +54376 -0.126708984375 +54377 0.150115966796875 +54378 0.424041748046875 +54379 0.670623779296875 +54380 0.854522705078125 +54381 0.866485595703125 +54382 0.86920166015625 +54383 0.8653564453125 +54384 0.857147216796875 +54385 0.766845703125 +54386 0.628509521484375 +54387 0.462127685546875 +54388 0.297210693359375 +54389 0.14862060546875 +54390 -0.00537109375 +54391 -0.15753173828125 +54392 -0.31304931640625 +54393 -0.48876953125 +54394 -0.6416015625 +54395 -0.751373291015625 +54396 -0.84619140625 +54397 -0.861297607421875 +54398 -0.863250732421875 +54399 -0.856597900390625 +54400 -0.7498779296875 +54401 -0.624542236328125 +54402 -0.47808837890625 +54403 -0.253387451171875 +54404 0.003692626953125 +54405 0.2257080078125 +54406 0.427154541015625 +54407 0.643218994140625 +54408 0.855926513671875 +54409 0.870361328125 +54410 0.870361328125 +54411 0.862762451171875 +54412 0.79669189453125 +54413 0.595794677734375 +54414 0.362152099609375 +54415 0.1270751953125 +54416 -0.086944580078125 +54417 -0.2784423828125 +54418 -0.484832763671875 +54419 -0.729583740234375 +54420 -0.86688232421875 +54421 -0.870391845703125 +54422 -0.86859130859375 +54423 -0.86279296875 +54424 -0.817962646484375 +54425 -0.6116943359375 +54426 -0.3128662109375 +54427 0.039398193359375 +54428 0.422821044921875 +54429 0.805145263671875 +54430 0.870361328125 +54431 0.870361328125 +54432 0.860015869140625 +54433 0.727935791015625 +54434 0.48114013671875 +54435 0.2059326171875 +54436 -0.06103515625 +54437 -0.29913330078125 +54438 -0.516204833984375 +54439 -0.7252197265625 +54440 -0.85980224609375 +54441 -0.870391845703125 +54442 -0.870391845703125 +54443 -0.858062744140625 +54444 -0.673004150390625 +54445 -0.42694091796875 +54446 -0.2100830078125 +54447 -0.0362548828125 +54448 0.10943603515625 +54449 0.23516845703125 +54450 0.373687744140625 +54451 0.517791748046875 +54452 0.602783203125 +54453 0.635711669921875 +54454 0.655181884765625 +54455 0.65948486328125 +54456 0.651275634765625 +54457 0.61846923828125 +54458 0.53753662109375 +54459 0.404144287109375 +54460 0.22186279296875 +54461 0.003997802734375 +54462 -0.22100830078125 +54463 -0.42449951171875 +54464 -0.579833984375 +54465 -0.641876220703125 +54466 -0.6177978515625 +54467 -0.575531005859375 +54468 -0.526336669921875 +54469 -0.42645263671875 +54470 -0.2581787109375 +54471 -0.068695068359375 +54472 0.09222412109375 +54473 0.232147216796875 +54474 0.3509521484375 +54475 0.410064697265625 +54476 0.372955322265625 +54477 0.2554931640625 +54478 0.10711669921875 +54479 -0.052886962890625 +54480 -0.186279296875 +54481 -0.23291015625 +54482 -0.209442138671875 +54483 -0.174163818359375 +54484 -0.126739501953125 +54485 -0.048126220703125 +54486 0.0426025390625 +54487 0.10748291015625 +54488 0.1409912109375 +54489 0.19708251953125 +54490 0.273651123046875 +54491 0.31768798828125 +54492 0.341094970703125 +54493 0.368011474609375 +54494 0.37249755859375 +54495 0.30072021484375 +54496 0.1517333984375 +54497 -0.01470947265625 +54498 -0.1883544921875 +54499 -0.372711181640625 +54500 -0.51397705078125 +54501 -0.57177734375 +54502 -0.53948974609375 +54503 -0.43511962890625 +54504 -0.2962646484375 +54505 -0.161102294921875 +54506 -0.0435791015625 +54507 0.060394287109375 +54508 0.13665771484375 +54509 0.170135498046875 +54510 0.16552734375 +54511 0.15728759765625 +54512 0.150787353515625 +54513 0.12200927734375 +54514 0.080108642578125 +54515 0.05126953125 +54516 0.062896728515625 +54517 0.09271240234375 +54518 0.092987060546875 +54519 0.07855224609375 +54520 0.06427001953125 +54521 0.0347900390625 +54522 -0.01171875 +54523 -0.056060791015625 +54524 -0.055511474609375 +54525 -0.010467529296875 +54526 0.02508544921875 +54527 0.025665283203125 +54528 0.017333984375 +54529 0.00189208984375 +54530 -0.03173828125 +54531 -0.071502685546875 +54532 -0.13543701171875 +54533 -0.219970703125 +54534 -0.300506591796875 +54535 -0.376312255859375 +54536 -0.416107177734375 +54537 -0.371124267578125 +54538 -0.242279052734375 +54539 -0.069732666015625 +54540 0.125640869140625 +54541 0.31268310546875 +54542 0.45501708984375 +54543 0.554779052734375 +54544 0.61065673828125 +54545 0.610931396484375 +54546 0.531463623046875 +54547 0.3883056640625 +54548 0.23468017578125 +54549 0.095245361328125 +54550 -0.00396728515625 +54551 -0.04852294921875 +54552 -0.055145263671875 +54553 -0.0758056640625 +54554 -0.138702392578125 +54555 -0.209197998046875 +54556 -0.289031982421875 +54557 -0.37884521484375 +54558 -0.456329345703125 +54559 -0.51641845703125 +54560 -0.519287109375 +54561 -0.458251953125 +54562 -0.384796142578125 +54563 -0.323699951171875 +54564 -0.269287109375 +54565 -0.1951904296875 +54566 -0.100006103515625 +54567 -0.01055908203125 +54568 0.1033935546875 +54569 0.24908447265625 +54570 0.373199462890625 +54571 0.45806884765625 +54572 0.511474609375 +54573 0.565399169921875 +54574 0.61138916015625 +54575 0.5897216796875 +54576 0.4906005859375 +54577 0.33148193359375 +54578 0.147796630859375 +54579 -0.01873779296875 +54580 -0.140289306640625 +54581 -0.191986083984375 +54582 -0.184295654296875 +54583 -0.161834716796875 +54584 -0.166595458984375 +54585 -0.19390869140625 +54586 -0.22442626953125 +54587 -0.279754638671875 +54588 -0.3389892578125 +54589 -0.3543701171875 +54590 -0.348175048828125 +54591 -0.32598876953125 +54592 -0.2581787109375 +54593 -0.139801025390625 +54594 0.014617919921875 +54595 0.144378662109375 +54596 0.221038818359375 +54597 0.27069091796875 +54598 0.294036865234375 +54599 0.311767578125 +54600 0.339141845703125 +54601 0.360260009765625 +54602 0.360504150390625 +54603 0.308380126953125 +54604 0.18170166015625 +54605 0.0047607421875 +54606 -0.17559814453125 +54607 -0.3143310546875 +54608 -0.36785888671875 +54609 -0.36248779296875 +54610 -0.343536376953125 +54611 -0.3018798828125 +54612 -0.231414794921875 +54613 -0.117645263671875 +54614 0.007049560546875 +54615 0.087982177734375 +54616 0.13946533203125 +54617 0.17425537109375 +54618 0.188201904296875 +54619 0.171234130859375 +54620 0.118438720703125 +54621 0.05706787109375 +54622 -0.010711669921875 +54623 -0.0914306640625 +54624 -0.162322998046875 +54625 -0.194549560546875 +54626 -0.1492919921875 +54627 -0.02166748046875 +54628 0.124053955078125 +54629 0.211151123046875 +54630 0.240447998046875 +54631 0.242218017578125 +54632 0.2257080078125 +54633 0.194366455078125 +54634 0.115509033203125 +54635 0.0128173828125 +54636 -0.053802490234375 +54637 -0.110626220703125 +54638 -0.199493408203125 +54639 -0.29437255859375 +54640 -0.33221435546875 +54641 -0.27972412109375 +54642 -0.185333251953125 +54643 -0.128204345703125 +54644 -0.115692138671875 +54645 -0.116455078125 +54646 -0.105926513671875 +54647 -0.053955078125 +54648 0.048797607421875 +54649 0.157318115234375 +54650 0.212005615234375 +54651 0.218475341796875 +54652 0.23724365234375 +54653 0.30535888671875 +54654 0.38128662109375 +54655 0.404449462890625 +54656 0.3944091796875 +54657 0.3885498046875 +54658 0.362640380859375 +54659 0.27362060546875 +54660 0.11712646484375 +54661 -0.054901123046875 +54662 -0.19085693359375 +54663 -0.28570556640625 +54664 -0.339263916015625 +54665 -0.3775634765625 +54666 -0.445709228515625 +54667 -0.535064697265625 +54668 -0.629058837890625 +54669 -0.697601318359375 +54670 -0.70391845703125 +54671 -0.6424560546875 +54672 -0.491241455078125 +54673 -0.265716552734375 +54674 -0.023712158203125 +54675 0.201751708984375 +54676 0.375823974609375 +54677 0.485076904296875 +54678 0.56884765625 +54679 0.634765625 +54680 0.63763427734375 +54681 0.5660400390625 +54682 0.4720458984375 +54683 0.40692138671875 +54684 0.3778076171875 +54685 0.376953125 +54686 0.371978759765625 +54687 0.313140869140625 +54688 0.184417724609375 +54689 0.011199951171875 +54690 -0.171051025390625 +54691 -0.33740234375 +54692 -0.47198486328125 +54693 -0.560394287109375 +54694 -0.58056640625 +54695 -0.54754638671875 +54696 -0.508575439453125 +54697 -0.459503173828125 +54698 -0.394378662109375 +54699 -0.35260009765625 +54700 -0.31170654296875 +54701 -0.197418212890625 +54702 -0.007965087890625 +54703 0.207489013671875 +54704 0.409210205078125 +54705 0.57208251953125 +54706 0.66595458984375 +54707 0.65875244140625 +54708 0.56744384765625 +54709 0.431396484375 +54710 0.29443359375 +54711 0.182464599609375 +54712 0.06365966796875 +54713 -0.075958251953125 +54714 -0.189422607421875 +54715 -0.271942138671875 +54716 -0.342529296875 +54717 -0.364166259765625 +54718 -0.327239990234375 +54719 -0.2769775390625 +54720 -0.253692626953125 +54721 -0.24365234375 +54722 -0.1983642578125 +54723 -0.116241455078125 +54724 -0.036834716796875 +54725 0.034881591796875 +54726 0.09124755859375 +54727 0.10888671875 +54728 0.125518798828125 +54729 0.15771484375 +54730 0.17828369140625 +54731 0.17108154296875 +54732 0.129974365234375 +54733 0.082427978515625 +54734 0.027679443359375 +54735 -0.065643310546875 +54736 -0.15936279296875 +54737 -0.21307373046875 +54738 -0.234649658203125 +54739 -0.2001953125 +54740 -0.119171142578125 +54741 -0.024749755859375 +54742 0.085784912109375 +54743 0.178131103515625 +54744 0.215576171875 +54745 0.211456298828125 +54746 0.17523193359375 +54747 0.128753662109375 +54748 0.1019287109375 +54749 0.0743408203125 +54750 0.04327392578125 +54751 0.038177490234375 +54752 0.076263427734375 +54753 0.14105224609375 +54754 0.186431884765625 +54755 0.188812255859375 +54756 0.1390380859375 +54757 0.041778564453125 +54758 -0.079437255859375 +54759 -0.219390869140625 +54760 -0.367828369140625 +54761 -0.494873046875 +54762 -0.556243896484375 +54763 -0.508697509765625 +54764 -0.3756103515625 +54765 -0.218902587890625 +54766 -0.063751220703125 +54767 0.091552734375 +54768 0.23602294921875 +54769 0.342987060546875 +54770 0.39520263671875 +54771 0.389373779296875 +54772 0.324249267578125 +54773 0.224090576171875 +54774 0.124267578125 +54775 0.037078857421875 +54776 -0.010101318359375 +54777 -0.019439697265625 +54778 -0.022796630859375 +54779 -0.001556396484375 +54780 0.056304931640625 +54781 0.106719970703125 +54782 0.096893310546875 +54783 0.042694091796875 +54784 -0.018035888671875 +54785 -0.07586669921875 +54786 -0.11944580078125 +54787 -0.15972900390625 +54788 -0.202606201171875 +54789 -0.24859619140625 +54790 -0.30517578125 +54791 -0.36212158203125 +54792 -0.39141845703125 +54793 -0.35528564453125 +54794 -0.249969482421875 +54795 -0.092864990234375 +54796 0.08905029296875 +54797 0.2352294921875 +54798 0.318817138671875 +54799 0.358642578125 +54800 0.347747802734375 +54801 0.28564453125 +54802 0.223175048828125 +54803 0.196746826171875 +54804 0.179840087890625 +54805 0.155548095703125 +54806 0.151214599609375 +54807 0.156951904296875 +54808 0.13177490234375 +54809 0.100799560546875 +54810 0.087127685546875 +54811 0.05487060546875 +54812 -0.009002685546875 +54813 -0.10400390625 +54814 -0.229400634765625 +54815 -0.35552978515625 +54816 -0.441925048828125 +54817 -0.473846435546875 +54818 -0.464813232421875 +54819 -0.419097900390625 +54820 -0.334320068359375 +54821 -0.227935791015625 +54822 -0.12347412109375 +54823 -0.02764892578125 +54824 0.077667236328125 +54825 0.2132568359375 +54826 0.38885498046875 +54827 0.582794189453125 +54828 0.734039306640625 +54829 0.800140380859375 +54830 0.7783203125 +54831 0.6651611328125 +54832 0.45965576171875 +54833 0.199188232421875 +54834 -0.050689697265625 +54835 -0.23297119140625 +54836 -0.33013916015625 +54837 -0.368408203125 +54838 -0.378936767578125 +54839 -0.376983642578125 +54840 -0.37969970703125 +54841 -0.391510009765625 +54842 -0.385345458984375 +54843 -0.3419189453125 +54844 -0.28289794921875 +54845 -0.251617431640625 +54846 -0.266143798828125 +54847 -0.273345947265625 +54848 -0.216796875 +54849 -0.128265380859375 +54850 -0.068145751953125 +54851 -0.0430908203125 +54852 -0.024444580078125 +54853 0.020721435546875 +54854 0.124481201171875 +54855 0.25787353515625 +54856 0.379119873046875 +54857 0.47991943359375 +54858 0.5281982421875 +54859 0.511138916015625 +54860 0.456207275390625 +54861 0.407470703125 +54862 0.383758544921875 +54863 0.35687255859375 +54864 0.31182861328125 +54865 0.250885009765625 +54866 0.1654052734375 +54867 0.035247802734375 +54868 -0.142059326171875 +54869 -0.33563232421875 +54870 -0.5345458984375 +54871 -0.72186279296875 +54872 -0.836669921875 +54873 -0.8326416015625 +54874 -0.7296142578125 +54875 -0.582550048828125 +54876 -0.440093994140625 +54877 -0.324310302734375 +54878 -0.20147705078125 +54879 -0.044647216796875 +54880 0.103973388671875 +54881 0.202392578125 +54882 0.264495849609375 +54883 0.338897705078125 +54884 0.443817138671875 +54885 0.545074462890625 +54886 0.6173095703125 +54887 0.6524658203125 +54888 0.66339111328125 +54889 0.6561279296875 +54890 0.606781005859375 +54891 0.501190185546875 +54892 0.352783203125 +54893 0.176544189453125 +54894 -0.034820556640625 +54895 -0.258209228515625 +54896 -0.44244384765625 +54897 -0.5753173828125 +54898 -0.65203857421875 +54899 -0.641632080078125 +54900 -0.562164306640625 +54901 -0.458038330078125 +54902 -0.350555419921875 +54903 -0.260528564453125 +54904 -0.192108154296875 +54905 -0.141937255859375 +54906 -0.1021728515625 +54907 -0.062896728515625 +54908 -0.011932373046875 +54909 0.062835693359375 +54910 0.148712158203125 +54911 0.241729736328125 +54912 0.34912109375 +54913 0.457305908203125 +54914 0.54388427734375 +54915 0.5728759765625 +54916 0.506591796875 +54917 0.351226806640625 +54918 0.146514892578125 +54919 -0.05523681640625 +54920 -0.21624755859375 +54921 -0.334930419921875 +54922 -0.402984619140625 +54923 -0.4412841796875 +54924 -0.49578857421875 +54925 -0.5601806640625 +54926 -0.600738525390625 +54927 -0.584228515625 +54928 -0.47930908203125 +54929 -0.27935791015625 +54930 -0.0089111328125 +54931 0.268798828125 +54932 0.482818603515625 +54933 0.60369873046875 +54934 0.650421142578125 +54935 0.66400146484375 +54936 0.6414794921875 +54937 0.572540283203125 +54938 0.498138427734375 +54939 0.439453125 +54940 0.375518798828125 +54941 0.274505615234375 +54942 0.1087646484375 +54943 -0.099395751953125 +54944 -0.3182373046875 +54945 -0.5489501953125 +54946 -0.7738037109375 +54947 -0.86383056640625 +54948 -0.870391845703125 +54949 -0.86895751953125 +54950 -0.861053466796875 +54951 -0.765869140625 +54952 -0.5301513671875 +54953 -0.214691162109375 +54954 0.137359619140625 +54955 0.474822998046875 +54956 0.76239013671875 +54957 0.867462158203125 +54958 0.870361328125 +54959 0.86480712890625 +54960 0.831817626953125 +54961 0.677581787109375 +54962 0.495880126953125 +54963 0.30767822265625 +54964 0.116180419921875 +54965 -0.110748291015625 +54966 -0.381805419921875 +54967 -0.6572265625 +54968 -0.857421875 +54969 -0.870391845703125 +54970 -0.870391845703125 +54971 -0.86444091796875 +54972 -0.85723876953125 +54973 -0.790008544921875 +54974 -0.62847900390625 +54975 -0.3956298828125 +54976 -0.126708984375 +54977 0.150115966796875 +54978 0.424041748046875 +54979 0.670623779296875 +54980 0.854522705078125 +54981 0.866485595703125 +54982 0.86920166015625 +54983 0.8653564453125 +54984 0.857147216796875 +54985 0.766845703125 +54986 0.628509521484375 +54987 0.462127685546875 +54988 0.297210693359375 +54989 0.14862060546875 +54990 -0.00537109375 +54991 -0.15753173828125 +54992 -0.31304931640625 +54993 -0.48876953125 +54994 -0.6416015625 +54995 -0.751373291015625 +54996 -0.84619140625 +54997 -0.861297607421875 +54998 -0.863250732421875 +54999 -0.856597900390625 +55000 -0.7498779296875 +55001 -0.624542236328125 +55002 -0.47808837890625 +55003 -0.253387451171875 +55004 0.003692626953125 +55005 0.2257080078125 +55006 0.427154541015625 +55007 0.643218994140625 +55008 0.855926513671875 +55009 0.870361328125 +55010 0.870361328125 +55011 0.862762451171875 +55012 0.79669189453125 +55013 0.595794677734375 +55014 0.362152099609375 +55015 0.1270751953125 +55016 -0.086944580078125 +55017 -0.2784423828125 +55018 -0.484832763671875 +55019 -0.729583740234375 +55020 -0.86688232421875 +55021 -0.870391845703125 +55022 -0.86859130859375 +55023 -0.86279296875 +55024 -0.817962646484375 +55025 -0.6116943359375 +55026 -0.3128662109375 +55027 0.039398193359375 +55028 0.422821044921875 +55029 0.805145263671875 +55030 0.870361328125 +55031 0.870361328125 +55032 0.860015869140625 +55033 0.727935791015625 +55034 0.48114013671875 +55035 0.2059326171875 +55036 -0.06103515625 +55037 -0.29913330078125 +55038 -0.516204833984375 +55039 -0.7252197265625 +55040 -0.85980224609375 +55041 -0.870391845703125 +55042 -0.870391845703125 +55043 -0.858062744140625 +55044 -0.673004150390625 +55045 -0.42694091796875 +55046 -0.2100830078125 +55047 -0.0362548828125 +55048 0.10943603515625 +55049 0.23516845703125 +55050 0.373687744140625 +55051 0.517791748046875 +55052 0.602783203125 +55053 0.635711669921875 +55054 0.655181884765625 +55055 0.65948486328125 +55056 0.651275634765625 +55057 0.61846923828125 +55058 0.53753662109375 +55059 0.404144287109375 +55060 0.22186279296875 +55061 0.003997802734375 +55062 -0.22100830078125 +55063 -0.42449951171875 +55064 -0.579833984375 +55065 -0.641876220703125 +55066 -0.6177978515625 +55067 -0.575531005859375 +55068 -0.526336669921875 +55069 -0.42645263671875 +55070 -0.2581787109375 +55071 -0.068695068359375 +55072 0.09222412109375 +55073 0.232147216796875 +55074 0.3509521484375 +55075 0.410064697265625 +55076 0.372955322265625 +55077 0.2554931640625 +55078 0.10711669921875 +55079 -0.052886962890625 +55080 -0.186279296875 +55081 -0.23291015625 +55082 -0.209442138671875 +55083 -0.174163818359375 +55084 -0.126739501953125 +55085 -0.048126220703125 +55086 0.0426025390625 +55087 0.10748291015625 +55088 0.1409912109375 +55089 0.19708251953125 +55090 0.273651123046875 +55091 0.31768798828125 +55092 0.341094970703125 +55093 0.368011474609375 +55094 0.37249755859375 +55095 0.30072021484375 +55096 0.1517333984375 +55097 -0.01470947265625 +55098 -0.1883544921875 +55099 -0.372711181640625 +55100 -0.51397705078125 +55101 -0.57177734375 +55102 -0.53948974609375 +55103 -0.43511962890625 +55104 -0.2962646484375 +55105 -0.161102294921875 +55106 -0.0435791015625 +55107 0.060394287109375 +55108 0.13665771484375 +55109 0.170135498046875 +55110 0.16552734375 +55111 0.15728759765625 +55112 0.150787353515625 +55113 0.12200927734375 +55114 0.080108642578125 +55115 0.05126953125 +55116 0.062896728515625 +55117 0.09271240234375 +55118 0.092987060546875 +55119 0.07855224609375 +55120 0.06427001953125 +55121 0.0347900390625 +55122 -0.01171875 +55123 -0.056060791015625 +55124 -0.055511474609375 +55125 -0.010467529296875 +55126 0.02508544921875 +55127 0.025665283203125 +55128 0.017333984375 +55129 0.00189208984375 +55130 -0.03173828125 +55131 -0.071502685546875 +55132 -0.13543701171875 +55133 -0.219970703125 +55134 -0.300506591796875 +55135 -0.376312255859375 +55136 -0.416107177734375 +55137 -0.371124267578125 +55138 -0.242279052734375 +55139 -0.069732666015625 +55140 0.125640869140625 +55141 0.31268310546875 +55142 0.45501708984375 +55143 0.554779052734375 +55144 0.61065673828125 +55145 0.610931396484375 +55146 0.531463623046875 +55147 0.3883056640625 +55148 0.23468017578125 +55149 0.095245361328125 +55150 -0.00396728515625 +55151 -0.04852294921875 +55152 -0.055145263671875 +55153 -0.0758056640625 +55154 -0.138702392578125 +55155 -0.209197998046875 +55156 -0.289031982421875 +55157 -0.37884521484375 +55158 -0.456329345703125 +55159 -0.51641845703125 +55160 -0.519287109375 +55161 -0.458251953125 +55162 -0.384796142578125 +55163 -0.323699951171875 +55164 -0.269287109375 +55165 -0.1951904296875 +55166 -0.100006103515625 +55167 -0.01055908203125 +55168 0.1033935546875 +55169 0.24908447265625 +55170 0.373199462890625 +55171 0.45806884765625 +55172 0.511474609375 +55173 0.565399169921875 +55174 0.61138916015625 +55175 0.5897216796875 +55176 0.4906005859375 +55177 0.33148193359375 +55178 0.147796630859375 +55179 -0.01873779296875 +55180 -0.140289306640625 +55181 -0.191986083984375 +55182 -0.184295654296875 +55183 -0.161834716796875 +55184 -0.166595458984375 +55185 -0.19390869140625 +55186 -0.22442626953125 +55187 -0.279754638671875 +55188 -0.3389892578125 +55189 -0.3543701171875 +55190 -0.348175048828125 +55191 -0.32598876953125 +55192 -0.2581787109375 +55193 -0.139801025390625 +55194 0.014617919921875 +55195 0.144378662109375 +55196 0.221038818359375 +55197 0.27069091796875 +55198 0.294036865234375 +55199 0.311767578125 +55200 0.339141845703125 +55201 0.360260009765625 +55202 0.360504150390625 +55203 0.308380126953125 +55204 0.18170166015625 +55205 0.0047607421875 +55206 -0.17559814453125 +55207 -0.3143310546875 +55208 -0.36785888671875 +55209 -0.36248779296875 +55210 -0.343536376953125 +55211 -0.3018798828125 +55212 -0.231414794921875 +55213 -0.117645263671875 +55214 0.007049560546875 +55215 0.087982177734375 +55216 0.13946533203125 +55217 0.17425537109375 +55218 0.188201904296875 +55219 0.171234130859375 +55220 0.118438720703125 +55221 0.05706787109375 +55222 -0.010711669921875 +55223 -0.0914306640625 +55224 -0.162322998046875 +55225 -0.194549560546875 +55226 -0.1492919921875 +55227 -0.02166748046875 +55228 0.124053955078125 +55229 0.211151123046875 +55230 0.240447998046875 +55231 0.242218017578125 +55232 0.2257080078125 +55233 0.194366455078125 +55234 0.115509033203125 +55235 0.0128173828125 +55236 -0.053802490234375 +55237 -0.110626220703125 +55238 -0.199493408203125 +55239 -0.29437255859375 +55240 -0.33221435546875 +55241 -0.27972412109375 +55242 -0.185333251953125 +55243 -0.128204345703125 +55244 -0.115692138671875 +55245 -0.116455078125 +55246 -0.105926513671875 +55247 -0.053955078125 +55248 0.048797607421875 +55249 0.157318115234375 +55250 0.212005615234375 +55251 0.218475341796875 +55252 0.23724365234375 +55253 0.30535888671875 +55254 0.38128662109375 +55255 0.404449462890625 +55256 0.3944091796875 +55257 0.3885498046875 +55258 0.362640380859375 +55259 0.27362060546875 +55260 0.11712646484375 +55261 -0.054901123046875 +55262 -0.19085693359375 +55263 -0.28570556640625 +55264 -0.339263916015625 +55265 -0.3775634765625 +55266 -0.445709228515625 +55267 -0.535064697265625 +55268 -0.629058837890625 +55269 -0.697601318359375 +55270 -0.70391845703125 +55271 -0.6424560546875 +55272 -0.491241455078125 +55273 -0.265716552734375 +55274 -0.023712158203125 +55275 0.201751708984375 +55276 0.375823974609375 +55277 0.485076904296875 +55278 0.56884765625 +55279 0.634765625 +55280 0.63763427734375 +55281 0.5660400390625 +55282 0.4720458984375 +55283 0.40692138671875 +55284 0.3778076171875 +55285 0.376953125 +55286 0.371978759765625 +55287 0.313140869140625 +55288 0.184417724609375 +55289 0.011199951171875 +55290 -0.171051025390625 +55291 -0.33740234375 +55292 -0.47198486328125 +55293 -0.560394287109375 +55294 -0.58056640625 +55295 -0.54754638671875 +55296 -0.508575439453125 +55297 -0.459503173828125 +55298 -0.394378662109375 +55299 -0.35260009765625 +55300 -0.31170654296875 +55301 -0.197418212890625 +55302 -0.007965087890625 +55303 0.207489013671875 +55304 0.409210205078125 +55305 0.57208251953125 +55306 0.66595458984375 +55307 0.65875244140625 +55308 0.56744384765625 +55309 0.431396484375 +55310 0.29443359375 +55311 0.182464599609375 +55312 0.06365966796875 +55313 -0.075958251953125 +55314 -0.189422607421875 +55315 -0.271942138671875 +55316 -0.342529296875 +55317 -0.364166259765625 +55318 -0.327239990234375 +55319 -0.2769775390625 +55320 -0.253692626953125 +55321 -0.24365234375 +55322 -0.1983642578125 +55323 -0.116241455078125 +55324 -0.036834716796875 +55325 0.034881591796875 +55326 0.09124755859375 +55327 0.10888671875 +55328 0.125518798828125 +55329 0.15771484375 +55330 0.17828369140625 +55331 0.17108154296875 +55332 0.129974365234375 +55333 0.082427978515625 +55334 0.027679443359375 +55335 -0.065643310546875 +55336 -0.15936279296875 +55337 -0.21307373046875 +55338 -0.234649658203125 +55339 -0.2001953125 +55340 -0.119171142578125 +55341 -0.024749755859375 +55342 0.085784912109375 +55343 0.178131103515625 +55344 0.215576171875 +55345 0.211456298828125 +55346 0.17523193359375 +55347 0.128753662109375 +55348 0.1019287109375 +55349 0.0743408203125 +55350 0.04327392578125 +55351 0.038177490234375 +55352 0.076263427734375 +55353 0.14105224609375 +55354 0.186431884765625 +55355 0.188812255859375 +55356 0.1390380859375 +55357 0.041778564453125 +55358 -0.079437255859375 +55359 -0.219390869140625 +55360 -0.367828369140625 +55361 -0.494873046875 +55362 -0.556243896484375 +55363 -0.508697509765625 +55364 -0.3756103515625 +55365 -0.218902587890625 +55366 -0.063751220703125 +55367 0.091552734375 +55368 0.23602294921875 +55369 0.342987060546875 +55370 0.39520263671875 +55371 0.389373779296875 +55372 0.324249267578125 +55373 0.224090576171875 +55374 0.124267578125 +55375 0.037078857421875 +55376 -0.010101318359375 +55377 -0.019439697265625 +55378 -0.022796630859375 +55379 -0.001556396484375 +55380 0.056304931640625 +55381 0.106719970703125 +55382 0.096893310546875 +55383 0.042694091796875 +55384 -0.018035888671875 +55385 -0.07586669921875 +55386 -0.11944580078125 +55387 -0.15972900390625 +55388 -0.202606201171875 +55389 -0.24859619140625 +55390 -0.30517578125 +55391 -0.36212158203125 +55392 -0.39141845703125 +55393 -0.35528564453125 +55394 -0.249969482421875 +55395 -0.092864990234375 +55396 0.08905029296875 +55397 0.2352294921875 +55398 0.318817138671875 +55399 0.358642578125 +55400 0.347747802734375 +55401 0.28564453125 +55402 0.223175048828125 +55403 0.196746826171875 +55404 0.179840087890625 +55405 0.155548095703125 +55406 0.151214599609375 +55407 0.156951904296875 +55408 0.13177490234375 +55409 0.100799560546875 +55410 0.087127685546875 +55411 0.05487060546875 +55412 -0.009002685546875 +55413 -0.10400390625 +55414 -0.229400634765625 +55415 -0.35552978515625 +55416 -0.441925048828125 +55417 -0.473846435546875 +55418 -0.464813232421875 +55419 -0.419097900390625 +55420 -0.334320068359375 +55421 -0.227935791015625 +55422 -0.12347412109375 +55423 -0.02764892578125 +55424 0.077667236328125 +55425 0.2132568359375 +55426 0.38885498046875 +55427 0.582794189453125 +55428 0.734039306640625 +55429 0.800140380859375 +55430 0.7783203125 +55431 0.6651611328125 +55432 0.45965576171875 +55433 0.199188232421875 +55434 -0.050689697265625 +55435 -0.23297119140625 +55436 -0.33013916015625 +55437 -0.368408203125 +55438 -0.378936767578125 +55439 -0.376983642578125 +55440 -0.37969970703125 +55441 -0.391510009765625 +55442 -0.385345458984375 +55443 -0.3419189453125 +55444 -0.28289794921875 +55445 -0.251617431640625 +55446 -0.266143798828125 +55447 -0.273345947265625 +55448 -0.216796875 +55449 -0.128265380859375 +55450 -0.068145751953125 +55451 -0.0430908203125 +55452 -0.024444580078125 +55453 0.020721435546875 +55454 0.124481201171875 +55455 0.25787353515625 +55456 0.379119873046875 +55457 0.47991943359375 +55458 0.5281982421875 +55459 0.511138916015625 +55460 0.456207275390625 +55461 0.407470703125 +55462 0.383758544921875 +55463 0.35687255859375 +55464 0.31182861328125 +55465 0.250885009765625 +55466 0.1654052734375 +55467 0.035247802734375 +55468 -0.142059326171875 +55469 -0.33563232421875 +55470 -0.5345458984375 +55471 -0.72186279296875 +55472 -0.836669921875 +55473 -0.8326416015625 +55474 -0.7296142578125 +55475 -0.582550048828125 +55476 -0.440093994140625 +55477 -0.324310302734375 +55478 -0.20147705078125 +55479 -0.044647216796875 +55480 0.103973388671875 +55481 0.202392578125 +55482 0.264495849609375 +55483 0.338897705078125 +55484 0.443817138671875 +55485 0.545074462890625 +55486 0.6173095703125 +55487 0.6524658203125 +55488 0.66339111328125 +55489 0.6561279296875 +55490 0.606781005859375 +55491 0.501190185546875 +55492 0.352783203125 +55493 0.176544189453125 +55494 -0.034820556640625 +55495 -0.258209228515625 +55496 -0.44244384765625 +55497 -0.5753173828125 +55498 -0.65203857421875 +55499 -0.641632080078125 +55500 -0.562164306640625 +55501 -0.458038330078125 +55502 -0.350555419921875 +55503 -0.260528564453125 +55504 -0.192108154296875 +55505 -0.141937255859375 +55506 -0.1021728515625 +55507 -0.062896728515625 +55508 -0.011932373046875 +55509 0.062835693359375 +55510 0.148712158203125 +55511 0.241729736328125 +55512 0.34912109375 +55513 0.457305908203125 +55514 0.54388427734375 +55515 0.5728759765625 +55516 0.506591796875 +55517 0.351226806640625 +55518 0.146514892578125 +55519 -0.05523681640625 +55520 -0.21624755859375 +55521 -0.334930419921875 +55522 -0.402984619140625 +55523 -0.4412841796875 +55524 -0.49578857421875 +55525 -0.5601806640625 +55526 -0.600738525390625 +55527 -0.584228515625 +55528 -0.47930908203125 +55529 -0.27935791015625 +55530 -0.0089111328125 +55531 0.268798828125 +55532 0.482818603515625 +55533 0.60369873046875 +55534 0.650421142578125 +55535 0.66400146484375 +55536 0.6414794921875 +55537 0.572540283203125 +55538 0.498138427734375 +55539 0.439453125 +55540 0.375518798828125 +55541 0.274505615234375 +55542 0.1087646484375 +55543 -0.099395751953125 +55544 -0.3182373046875 +55545 -0.5489501953125 +55546 -0.7738037109375 +55547 -0.86383056640625 +55548 -0.870391845703125 +55549 -0.86895751953125 +55550 -0.861053466796875 +55551 -0.765869140625 +55552 -0.5301513671875 +55553 -0.214691162109375 +55554 0.137359619140625 +55555 0.474822998046875 +55556 0.76239013671875 +55557 0.867462158203125 +55558 0.870361328125 +55559 0.86480712890625 +55560 0.831817626953125 +55561 0.677581787109375 +55562 0.495880126953125 +55563 0.30767822265625 +55564 0.116180419921875 +55565 -0.110748291015625 +55566 -0.381805419921875 +55567 -0.6572265625 +55568 -0.857421875 +55569 -0.870391845703125 +55570 -0.870391845703125 +55571 -0.86444091796875 +55572 -0.85723876953125 +55573 -0.790008544921875 +55574 -0.62847900390625 +55575 -0.3956298828125 +55576 -0.126708984375 +55577 0.150115966796875 +55578 0.424041748046875 +55579 0.670623779296875 +55580 0.854522705078125 +55581 0.866485595703125 +55582 0.86920166015625 +55583 0.8653564453125 +55584 0.857147216796875 +55585 0.766845703125 +55586 0.628509521484375 +55587 0.462127685546875 +55588 0.297210693359375 +55589 0.14862060546875 +55590 -0.00537109375 +55591 -0.15753173828125 +55592 -0.31304931640625 +55593 -0.48876953125 +55594 -0.6416015625 +55595 -0.751373291015625 +55596 -0.84619140625 +55597 -0.861297607421875 +55598 -0.863250732421875 +55599 -0.856597900390625 +55600 -0.7498779296875 +55601 -0.624542236328125 +55602 -0.47808837890625 +55603 -0.253387451171875 +55604 0.003692626953125 +55605 0.2257080078125 +55606 0.427154541015625 +55607 0.643218994140625 +55608 0.855926513671875 +55609 0.870361328125 +55610 0.870361328125 +55611 0.862762451171875 +55612 0.79669189453125 +55613 0.595794677734375 +55614 0.362152099609375 +55615 0.1270751953125 +55616 -0.086944580078125 +55617 -0.2784423828125 +55618 -0.484832763671875 +55619 -0.729583740234375 +55620 -0.86688232421875 +55621 -0.870391845703125 +55622 -0.86859130859375 +55623 -0.86279296875 +55624 -0.817962646484375 +55625 -0.6116943359375 +55626 -0.3128662109375 +55627 0.039398193359375 +55628 0.422821044921875 +55629 0.805145263671875 +55630 0.870361328125 +55631 0.870361328125 +55632 0.860015869140625 +55633 0.727935791015625 +55634 0.48114013671875 +55635 0.2059326171875 +55636 -0.06103515625 +55637 -0.29913330078125 +55638 -0.516204833984375 +55639 -0.7252197265625 +55640 -0.85980224609375 +55641 -0.870391845703125 +55642 -0.870391845703125 +55643 -0.858062744140625 +55644 -0.673004150390625 +55645 -0.42694091796875 +55646 -0.2100830078125 +55647 -0.0362548828125 +55648 0.10943603515625 +55649 0.23516845703125 +55650 0.373687744140625 +55651 0.517791748046875 +55652 0.602783203125 +55653 0.635711669921875 +55654 0.655181884765625 +55655 0.65948486328125 +55656 0.651275634765625 +55657 0.61846923828125 +55658 0.53753662109375 +55659 0.404144287109375 +55660 0.22186279296875 +55661 0.003997802734375 +55662 -0.22100830078125 +55663 -0.42449951171875 +55664 -0.579833984375 +55665 -0.641876220703125 +55666 -0.6177978515625 +55667 -0.575531005859375 +55668 -0.526336669921875 +55669 -0.42645263671875 +55670 -0.2581787109375 +55671 -0.068695068359375 +55672 0.09222412109375 +55673 0.232147216796875 +55674 0.3509521484375 +55675 0.410064697265625 +55676 0.372955322265625 +55677 0.2554931640625 +55678 0.10711669921875 +55679 -0.052886962890625 +55680 -0.186279296875 +55681 -0.23291015625 +55682 -0.209442138671875 +55683 -0.174163818359375 +55684 -0.126739501953125 +55685 -0.048126220703125 +55686 0.0426025390625 +55687 0.10748291015625 +55688 0.1409912109375 +55689 0.19708251953125 +55690 0.273651123046875 +55691 0.31768798828125 +55692 0.341094970703125 +55693 0.368011474609375 +55694 0.37249755859375 +55695 0.30072021484375 +55696 0.1517333984375 +55697 -0.01470947265625 +55698 -0.1883544921875 +55699 -0.372711181640625 +55700 -0.51397705078125 +55701 -0.57177734375 +55702 -0.53948974609375 +55703 -0.43511962890625 +55704 -0.2962646484375 +55705 -0.161102294921875 +55706 -0.0435791015625 +55707 0.060394287109375 +55708 0.13665771484375 +55709 0.170135498046875 +55710 0.16552734375 +55711 0.15728759765625 +55712 0.150787353515625 +55713 0.12200927734375 +55714 0.080108642578125 +55715 0.05126953125 +55716 0.062896728515625 +55717 0.09271240234375 +55718 0.092987060546875 +55719 0.07855224609375 +55720 0.06427001953125 +55721 0.0347900390625 +55722 -0.01171875 +55723 -0.056060791015625 +55724 -0.055511474609375 +55725 -0.010467529296875 +55726 0.02508544921875 +55727 0.025665283203125 +55728 0.017333984375 +55729 0.00189208984375 +55730 -0.03173828125 +55731 -0.071502685546875 +55732 -0.13543701171875 +55733 -0.219970703125 +55734 -0.300506591796875 +55735 -0.376312255859375 +55736 -0.416107177734375 +55737 -0.371124267578125 +55738 -0.242279052734375 +55739 -0.069732666015625 +55740 0.125640869140625 +55741 0.31268310546875 +55742 0.45501708984375 +55743 0.554779052734375 +55744 0.61065673828125 +55745 0.610931396484375 +55746 0.531463623046875 +55747 0.3883056640625 +55748 0.23468017578125 +55749 0.095245361328125 +55750 -0.00396728515625 +55751 -0.04852294921875 +55752 -0.055145263671875 +55753 -0.0758056640625 +55754 -0.138702392578125 +55755 -0.209197998046875 +55756 -0.289031982421875 +55757 -0.37884521484375 +55758 -0.456329345703125 +55759 -0.51641845703125 +55760 -0.519287109375 +55761 -0.458251953125 +55762 -0.384796142578125 +55763 -0.323699951171875 +55764 -0.269287109375 +55765 -0.1951904296875 +55766 -0.100006103515625 +55767 -0.01055908203125 +55768 0.1033935546875 +55769 0.24908447265625 +55770 0.373199462890625 +55771 0.45806884765625 +55772 0.511474609375 +55773 0.565399169921875 +55774 0.61138916015625 +55775 0.5897216796875 +55776 0.4906005859375 +55777 0.33148193359375 +55778 0.147796630859375 +55779 -0.01873779296875 +55780 -0.140289306640625 +55781 -0.191986083984375 +55782 -0.184295654296875 +55783 -0.161834716796875 +55784 -0.166595458984375 +55785 -0.19390869140625 +55786 -0.22442626953125 +55787 -0.279754638671875 +55788 -0.3389892578125 +55789 -0.3543701171875 +55790 -0.348175048828125 +55791 -0.32598876953125 +55792 -0.2581787109375 +55793 -0.139801025390625 +55794 0.014617919921875 +55795 0.144378662109375 +55796 0.221038818359375 +55797 0.27069091796875 +55798 0.294036865234375 +55799 0.311767578125 +55800 0.339141845703125 +55801 0.360260009765625 +55802 0.360504150390625 +55803 0.308380126953125 +55804 0.18170166015625 +55805 0.0047607421875 +55806 -0.17559814453125 +55807 -0.3143310546875 +55808 -0.36785888671875 +55809 -0.36248779296875 +55810 -0.343536376953125 +55811 -0.3018798828125 +55812 -0.231414794921875 +55813 -0.117645263671875 +55814 0.007049560546875 +55815 0.087982177734375 +55816 0.13946533203125 +55817 0.17425537109375 +55818 0.188201904296875 +55819 0.171234130859375 +55820 0.118438720703125 +55821 0.05706787109375 +55822 -0.010711669921875 +55823 -0.0914306640625 +55824 -0.162322998046875 +55825 -0.194549560546875 +55826 -0.1492919921875 +55827 -0.02166748046875 +55828 0.124053955078125 +55829 0.211151123046875 +55830 0.240447998046875 +55831 0.242218017578125 +55832 0.2257080078125 +55833 0.194366455078125 +55834 0.115509033203125 +55835 0.0128173828125 +55836 -0.053802490234375 +55837 -0.110626220703125 +55838 -0.199493408203125 +55839 -0.29437255859375 +55840 -0.33221435546875 +55841 -0.27972412109375 +55842 -0.185333251953125 +55843 -0.128204345703125 +55844 -0.115692138671875 +55845 -0.116455078125 +55846 -0.105926513671875 +55847 -0.053955078125 +55848 0.048797607421875 +55849 0.157318115234375 +55850 0.212005615234375 +55851 0.218475341796875 +55852 0.23724365234375 +55853 0.30535888671875 +55854 0.38128662109375 +55855 0.404449462890625 +55856 0.3944091796875 +55857 0.3885498046875 +55858 0.362640380859375 +55859 0.27362060546875 +55860 0.11712646484375 +55861 -0.054901123046875 +55862 -0.19085693359375 +55863 -0.28570556640625 +55864 -0.339263916015625 +55865 -0.3775634765625 +55866 -0.445709228515625 +55867 -0.535064697265625 +55868 -0.629058837890625 +55869 -0.697601318359375 +55870 -0.70391845703125 +55871 -0.6424560546875 +55872 -0.491241455078125 +55873 -0.265716552734375 +55874 -0.023712158203125 +55875 0.201751708984375 +55876 0.375823974609375 +55877 0.485076904296875 +55878 0.56884765625 +55879 0.634765625 +55880 0.63763427734375 +55881 0.5660400390625 +55882 0.4720458984375 +55883 0.40692138671875 +55884 0.3778076171875 +55885 0.376953125 +55886 0.371978759765625 +55887 0.313140869140625 +55888 0.184417724609375 +55889 0.011199951171875 +55890 -0.171051025390625 +55891 -0.33740234375 +55892 -0.47198486328125 +55893 -0.560394287109375 +55894 -0.58056640625 +55895 -0.54754638671875 +55896 -0.508575439453125 +55897 -0.459503173828125 +55898 -0.394378662109375 +55899 -0.35260009765625 +55900 -0.31170654296875 +55901 -0.197418212890625 +55902 -0.007965087890625 +55903 0.207489013671875 +55904 0.409210205078125 +55905 0.57208251953125 +55906 0.66595458984375 +55907 0.65875244140625 +55908 0.56744384765625 +55909 0.431396484375 +55910 0.29443359375 +55911 0.182464599609375 +55912 0.06365966796875 +55913 -0.075958251953125 +55914 -0.189422607421875 +55915 -0.271942138671875 +55916 -0.342529296875 +55917 -0.364166259765625 +55918 -0.327239990234375 +55919 -0.2769775390625 +55920 -0.253692626953125 +55921 -0.24365234375 +55922 -0.1983642578125 +55923 -0.116241455078125 +55924 -0.036834716796875 +55925 0.034881591796875 +55926 0.09124755859375 +55927 0.10888671875 +55928 0.125518798828125 +55929 0.15771484375 +55930 0.17828369140625 +55931 0.17108154296875 +55932 0.129974365234375 +55933 0.082427978515625 +55934 0.027679443359375 +55935 -0.065643310546875 +55936 -0.15936279296875 +55937 -0.21307373046875 +55938 -0.234649658203125 +55939 -0.2001953125 +55940 -0.119171142578125 +55941 -0.024749755859375 +55942 0.085784912109375 +55943 0.178131103515625 +55944 0.215576171875 +55945 0.211456298828125 +55946 0.17523193359375 +55947 0.128753662109375 +55948 0.1019287109375 +55949 0.0743408203125 +55950 0.04327392578125 +55951 0.038177490234375 +55952 0.076263427734375 +55953 0.14105224609375 +55954 0.186431884765625 +55955 0.188812255859375 +55956 0.1390380859375 +55957 0.041778564453125 +55958 -0.079437255859375 +55959 -0.219390869140625 +55960 -0.367828369140625 +55961 -0.494873046875 +55962 -0.556243896484375 +55963 -0.508697509765625 +55964 -0.3756103515625 +55965 -0.218902587890625 +55966 -0.063751220703125 +55967 0.091552734375 +55968 0.23602294921875 +55969 0.342987060546875 +55970 0.39520263671875 +55971 0.389373779296875 +55972 0.324249267578125 +55973 0.224090576171875 +55974 0.124267578125 +55975 0.037078857421875 +55976 -0.010101318359375 +55977 -0.019439697265625 +55978 -0.022796630859375 +55979 -0.001556396484375 +55980 0.056304931640625 +55981 0.106719970703125 +55982 0.096893310546875 +55983 0.042694091796875 +55984 -0.018035888671875 +55985 -0.07586669921875 +55986 -0.11944580078125 +55987 -0.15972900390625 +55988 -0.202606201171875 +55989 -0.24859619140625 +55990 -0.30517578125 +55991 -0.36212158203125 +55992 -0.39141845703125 +55993 -0.35528564453125 +55994 -0.249969482421875 +55995 -0.092864990234375 +55996 0.08905029296875 +55997 0.2352294921875 +55998 0.318817138671875 +55999 0.358642578125 +56000 0.347747802734375 +56001 0.28564453125 +56002 0.223175048828125 +56003 0.196746826171875 +56004 0.179840087890625 +56005 0.155548095703125 +56006 0.151214599609375 +56007 0.156951904296875 +56008 0.13177490234375 +56009 0.100799560546875 +56010 0.087127685546875 +56011 0.05487060546875 +56012 -0.009002685546875 +56013 -0.10400390625 +56014 -0.229400634765625 +56015 -0.35552978515625 +56016 -0.441925048828125 +56017 -0.473846435546875 +56018 -0.464813232421875 +56019 -0.419097900390625 +56020 -0.334320068359375 +56021 -0.227935791015625 +56022 -0.12347412109375 +56023 -0.02764892578125 +56024 0.077667236328125 +56025 0.2132568359375 +56026 0.38885498046875 +56027 0.582794189453125 +56028 0.734039306640625 +56029 0.800140380859375 +56030 0.7783203125 +56031 0.6651611328125 +56032 0.45965576171875 +56033 0.199188232421875 +56034 -0.050689697265625 +56035 -0.23297119140625 +56036 -0.33013916015625 +56037 -0.368408203125 +56038 -0.378936767578125 +56039 -0.376983642578125 +56040 -0.37969970703125 +56041 -0.391510009765625 +56042 -0.385345458984375 +56043 -0.3419189453125 +56044 -0.28289794921875 +56045 -0.251617431640625 +56046 -0.266143798828125 +56047 -0.273345947265625 +56048 -0.216796875 +56049 -0.128265380859375 +56050 -0.068145751953125 +56051 -0.0430908203125 +56052 -0.024444580078125 +56053 0.020721435546875 +56054 0.124481201171875 +56055 0.25787353515625 +56056 0.379119873046875 +56057 0.47991943359375 +56058 0.5281982421875 +56059 0.511138916015625 +56060 0.456207275390625 +56061 0.407470703125 +56062 0.383758544921875 +56063 0.35687255859375 +56064 0.31182861328125 +56065 0.250885009765625 +56066 0.1654052734375 +56067 0.035247802734375 +56068 -0.142059326171875 +56069 -0.33563232421875 +56070 -0.5345458984375 +56071 -0.72186279296875 +56072 -0.836669921875 +56073 -0.8326416015625 +56074 -0.7296142578125 +56075 -0.582550048828125 +56076 -0.440093994140625 +56077 -0.324310302734375 +56078 -0.20147705078125 +56079 -0.044647216796875 +56080 0.103973388671875 +56081 0.202392578125 +56082 0.264495849609375 +56083 0.338897705078125 +56084 0.443817138671875 +56085 0.545074462890625 +56086 0.6173095703125 +56087 0.6524658203125 +56088 0.66339111328125 +56089 0.6561279296875 +56090 0.606781005859375 +56091 0.501190185546875 +56092 0.352783203125 +56093 0.176544189453125 +56094 -0.034820556640625 +56095 -0.258209228515625 +56096 -0.44244384765625 +56097 -0.5753173828125 +56098 -0.65203857421875 +56099 -0.641632080078125 +56100 -0.562164306640625 +56101 -0.458038330078125 +56102 -0.350555419921875 +56103 -0.260528564453125 +56104 -0.192108154296875 +56105 -0.141937255859375 +56106 -0.1021728515625 +56107 -0.062896728515625 +56108 -0.011932373046875 +56109 0.062835693359375 +56110 0.148712158203125 +56111 0.241729736328125 +56112 0.34912109375 +56113 0.457305908203125 +56114 0.54388427734375 +56115 0.5728759765625 +56116 0.506591796875 +56117 0.351226806640625 +56118 0.146514892578125 +56119 -0.05523681640625 +56120 -0.21624755859375 +56121 -0.334930419921875 +56122 -0.402984619140625 +56123 -0.4412841796875 +56124 -0.49578857421875 +56125 -0.5601806640625 +56126 -0.600738525390625 +56127 -0.584228515625 +56128 -0.47930908203125 +56129 -0.27935791015625 +56130 -0.0089111328125 +56131 0.268798828125 +56132 0.482818603515625 +56133 0.60369873046875 +56134 0.650421142578125 +56135 0.66400146484375 +56136 0.6414794921875 +56137 0.572540283203125 +56138 0.498138427734375 +56139 0.439453125 +56140 0.375518798828125 +56141 0.274505615234375 +56142 0.1087646484375 +56143 -0.099395751953125 +56144 -0.3182373046875 +56145 -0.5489501953125 +56146 -0.7738037109375 +56147 -0.86383056640625 +56148 -0.870391845703125 +56149 -0.86895751953125 +56150 -0.861053466796875 +56151 -0.765869140625 +56152 -0.5301513671875 +56153 -0.214691162109375 +56154 0.137359619140625 +56155 0.474822998046875 +56156 0.76239013671875 +56157 0.867462158203125 +56158 0.870361328125 +56159 0.86480712890625 +56160 0.831817626953125 +56161 0.677581787109375 +56162 0.495880126953125 +56163 0.30767822265625 +56164 0.116180419921875 +56165 -0.110748291015625 +56166 -0.381805419921875 +56167 -0.6572265625 +56168 -0.857421875 +56169 -0.870391845703125 +56170 -0.870391845703125 +56171 -0.86444091796875 +56172 -0.85723876953125 +56173 -0.790008544921875 +56174 -0.62847900390625 +56175 -0.3956298828125 +56176 -0.126708984375 +56177 0.150115966796875 +56178 0.424041748046875 +56179 0.670623779296875 +56180 0.854522705078125 +56181 0.866485595703125 +56182 0.86920166015625 +56183 0.8653564453125 +56184 0.857147216796875 +56185 0.766845703125 +56186 0.628509521484375 +56187 0.462127685546875 +56188 0.297210693359375 +56189 0.14862060546875 +56190 -0.00537109375 +56191 -0.15753173828125 +56192 -0.31304931640625 +56193 -0.48876953125 +56194 -0.6416015625 +56195 -0.751373291015625 +56196 -0.84619140625 +56197 -0.861297607421875 +56198 -0.863250732421875 +56199 -0.856597900390625 +56200 -0.7498779296875 +56201 -0.624542236328125 +56202 -0.47808837890625 +56203 -0.253387451171875 +56204 0.003692626953125 +56205 0.2257080078125 +56206 0.427154541015625 +56207 0.643218994140625 +56208 0.855926513671875 +56209 0.870361328125 +56210 0.870361328125 +56211 0.862762451171875 +56212 0.79669189453125 +56213 0.595794677734375 +56214 0.362152099609375 +56215 0.1270751953125 +56216 -0.086944580078125 +56217 -0.2784423828125 +56218 -0.484832763671875 +56219 -0.729583740234375 +56220 -0.86688232421875 +56221 -0.870391845703125 +56222 -0.86859130859375 +56223 -0.86279296875 +56224 -0.817962646484375 +56225 -0.6116943359375 +56226 -0.3128662109375 +56227 0.039398193359375 +56228 0.422821044921875 +56229 0.805145263671875 +56230 0.870361328125 +56231 0.870361328125 +56232 0.860015869140625 +56233 0.727935791015625 +56234 0.48114013671875 +56235 0.2059326171875 +56236 -0.06103515625 +56237 -0.29913330078125 +56238 -0.516204833984375 +56239 -0.7252197265625 +56240 -0.85980224609375 +56241 -0.870391845703125 +56242 -0.870391845703125 +56243 -0.858062744140625 +56244 -0.673004150390625 +56245 -0.42694091796875 +56246 -0.2100830078125 +56247 -0.0362548828125 +56248 0.10943603515625 +56249 0.23516845703125 +56250 0.373687744140625 +56251 0.517791748046875 +56252 0.602783203125 +56253 0.635711669921875 +56254 0.655181884765625 +56255 0.65948486328125 +56256 0.651275634765625 +56257 0.61846923828125 +56258 0.53753662109375 +56259 0.404144287109375 +56260 0.22186279296875 +56261 0.003997802734375 +56262 -0.22100830078125 +56263 -0.42449951171875 +56264 -0.579833984375 +56265 -0.641876220703125 +56266 -0.6177978515625 +56267 -0.575531005859375 +56268 -0.526336669921875 +56269 -0.42645263671875 +56270 -0.2581787109375 +56271 -0.068695068359375 +56272 0.09222412109375 +56273 0.232147216796875 +56274 0.3509521484375 +56275 0.410064697265625 +56276 0.372955322265625 +56277 0.2554931640625 +56278 0.10711669921875 +56279 -0.052886962890625 +56280 -0.186279296875 +56281 -0.23291015625 +56282 -0.209442138671875 +56283 -0.174163818359375 +56284 -0.126739501953125 +56285 -0.048126220703125 +56286 0.0426025390625 +56287 0.10748291015625 +56288 0.1409912109375 +56289 0.19708251953125 +56290 0.273651123046875 +56291 0.31768798828125 +56292 0.341094970703125 +56293 0.368011474609375 +56294 0.37249755859375 +56295 0.30072021484375 +56296 0.1517333984375 +56297 -0.01470947265625 +56298 -0.1883544921875 +56299 -0.372711181640625 +56300 -0.51397705078125 +56301 -0.57177734375 +56302 -0.53948974609375 +56303 -0.43511962890625 +56304 -0.2962646484375 +56305 -0.161102294921875 +56306 -0.0435791015625 +56307 0.060394287109375 +56308 0.13665771484375 +56309 0.170135498046875 +56310 0.16552734375 +56311 0.15728759765625 +56312 0.150787353515625 +56313 0.12200927734375 +56314 0.080108642578125 +56315 0.05126953125 +56316 0.062896728515625 +56317 0.09271240234375 +56318 0.092987060546875 +56319 0.07855224609375 +56320 0.06427001953125 +56321 0.0347900390625 +56322 -0.01171875 +56323 -0.056060791015625 +56324 -0.055511474609375 +56325 -0.010467529296875 +56326 0.02508544921875 +56327 0.025665283203125 +56328 0.017333984375 +56329 0.00189208984375 +56330 -0.03173828125 +56331 -0.071502685546875 +56332 -0.13543701171875 +56333 -0.219970703125 +56334 -0.300506591796875 +56335 -0.376312255859375 +56336 -0.416107177734375 +56337 -0.371124267578125 +56338 -0.242279052734375 +56339 -0.069732666015625 +56340 0.125640869140625 +56341 0.31268310546875 +56342 0.45501708984375 +56343 0.554779052734375 +56344 0.61065673828125 +56345 0.610931396484375 +56346 0.531463623046875 +56347 0.3883056640625 +56348 0.23468017578125 +56349 0.095245361328125 +56350 -0.00396728515625 +56351 -0.04852294921875 +56352 -0.055145263671875 +56353 -0.0758056640625 +56354 -0.138702392578125 +56355 -0.209197998046875 +56356 -0.289031982421875 +56357 -0.37884521484375 +56358 -0.456329345703125 +56359 -0.51641845703125 +56360 -0.519287109375 +56361 -0.458251953125 +56362 -0.384796142578125 +56363 -0.323699951171875 +56364 -0.269287109375 +56365 -0.1951904296875 +56366 -0.100006103515625 +56367 -0.01055908203125 +56368 0.1033935546875 +56369 0.24908447265625 +56370 0.373199462890625 +56371 0.45806884765625 +56372 0.511474609375 +56373 0.565399169921875 +56374 0.61138916015625 +56375 0.5897216796875 +56376 0.4906005859375 +56377 0.33148193359375 +56378 0.147796630859375 +56379 -0.01873779296875 +56380 -0.140289306640625 +56381 -0.191986083984375 +56382 -0.184295654296875 +56383 -0.161834716796875 +56384 -0.166595458984375 +56385 -0.19390869140625 +56386 -0.22442626953125 +56387 -0.279754638671875 +56388 -0.3389892578125 +56389 -0.3543701171875 +56390 -0.348175048828125 +56391 -0.32598876953125 +56392 -0.2581787109375 +56393 -0.139801025390625 +56394 0.014617919921875 +56395 0.144378662109375 +56396 0.221038818359375 +56397 0.27069091796875 +56398 0.294036865234375 +56399 0.311767578125 +56400 0.339141845703125 +56401 0.360260009765625 +56402 0.360504150390625 +56403 0.308380126953125 +56404 0.18170166015625 +56405 0.0047607421875 +56406 -0.17559814453125 +56407 -0.3143310546875 +56408 -0.36785888671875 +56409 -0.36248779296875 +56410 -0.343536376953125 +56411 -0.3018798828125 +56412 -0.231414794921875 +56413 -0.117645263671875 +56414 0.007049560546875 +56415 0.087982177734375 +56416 0.13946533203125 +56417 0.17425537109375 +56418 0.188201904296875 +56419 0.171234130859375 +56420 0.118438720703125 +56421 0.05706787109375 +56422 -0.010711669921875 +56423 -0.0914306640625 +56424 -0.162322998046875 +56425 -0.194549560546875 +56426 -0.1492919921875 +56427 -0.02166748046875 +56428 0.124053955078125 +56429 0.211151123046875 +56430 0.240447998046875 +56431 0.242218017578125 +56432 0.2257080078125 +56433 0.194366455078125 +56434 0.115509033203125 +56435 0.0128173828125 +56436 -0.053802490234375 +56437 -0.110626220703125 +56438 -0.199493408203125 +56439 -0.29437255859375 +56440 -0.33221435546875 +56441 -0.27972412109375 +56442 -0.185333251953125 +56443 -0.128204345703125 +56444 -0.115692138671875 +56445 -0.116455078125 +56446 -0.105926513671875 +56447 -0.053955078125 +56448 0.048797607421875 +56449 0.157318115234375 +56450 0.212005615234375 +56451 0.218475341796875 +56452 0.23724365234375 +56453 0.30535888671875 +56454 0.38128662109375 +56455 0.404449462890625 +56456 0.3944091796875 +56457 0.3885498046875 +56458 0.362640380859375 +56459 0.27362060546875 +56460 0.11712646484375 +56461 -0.054901123046875 +56462 -0.19085693359375 +56463 -0.28570556640625 +56464 -0.339263916015625 +56465 -0.3775634765625 +56466 -0.445709228515625 +56467 -0.535064697265625 +56468 -0.629058837890625 +56469 -0.697601318359375 +56470 -0.70391845703125 +56471 -0.6424560546875 +56472 -0.491241455078125 +56473 -0.265716552734375 +56474 -0.023712158203125 +56475 0.201751708984375 +56476 0.375823974609375 +56477 0.485076904296875 +56478 0.56884765625 +56479 0.634765625 +56480 0.63763427734375 +56481 0.5660400390625 +56482 0.4720458984375 +56483 0.40692138671875 +56484 0.3778076171875 +56485 0.376953125 +56486 0.371978759765625 +56487 0.313140869140625 +56488 0.184417724609375 +56489 0.011199951171875 +56490 -0.171051025390625 +56491 -0.33740234375 +56492 -0.47198486328125 +56493 -0.560394287109375 +56494 -0.58056640625 +56495 -0.54754638671875 +56496 -0.508575439453125 +56497 -0.459503173828125 +56498 -0.394378662109375 +56499 -0.35260009765625 +56500 -0.31170654296875 +56501 -0.197418212890625 +56502 -0.007965087890625 +56503 0.207489013671875 +56504 0.409210205078125 +56505 0.57208251953125 +56506 0.66595458984375 +56507 0.65875244140625 +56508 0.56744384765625 +56509 0.431396484375 +56510 0.29443359375 +56511 0.182464599609375 +56512 0.06365966796875 +56513 -0.075958251953125 +56514 -0.189422607421875 +56515 -0.271942138671875 +56516 -0.342529296875 +56517 -0.364166259765625 +56518 -0.327239990234375 +56519 -0.2769775390625 +56520 -0.253692626953125 +56521 -0.24365234375 +56522 -0.1983642578125 +56523 -0.116241455078125 +56524 -0.036834716796875 +56525 0.034881591796875 +56526 0.09124755859375 +56527 0.10888671875 +56528 0.125518798828125 +56529 0.15771484375 +56530 0.17828369140625 +56531 0.17108154296875 +56532 0.129974365234375 +56533 0.082427978515625 +56534 0.027679443359375 +56535 -0.065643310546875 +56536 -0.15936279296875 +56537 -0.21307373046875 +56538 -0.234649658203125 +56539 -0.2001953125 +56540 -0.119171142578125 +56541 -0.024749755859375 +56542 0.085784912109375 +56543 0.178131103515625 +56544 0.215576171875 +56545 0.211456298828125 +56546 0.17523193359375 +56547 0.128753662109375 +56548 0.1019287109375 +56549 0.0743408203125 +56550 0.04327392578125 +56551 0.038177490234375 +56552 0.076263427734375 +56553 0.14105224609375 +56554 0.186431884765625 +56555 0.188812255859375 +56556 0.1390380859375 +56557 0.041778564453125 +56558 -0.079437255859375 +56559 -0.219390869140625 +56560 -0.367828369140625 +56561 -0.494873046875 +56562 -0.556243896484375 +56563 -0.508697509765625 +56564 -0.3756103515625 +56565 -0.218902587890625 +56566 -0.063751220703125 +56567 0.091552734375 +56568 0.23602294921875 +56569 0.342987060546875 +56570 0.39520263671875 +56571 0.389373779296875 +56572 0.324249267578125 +56573 0.224090576171875 +56574 0.124267578125 +56575 0.037078857421875 +56576 -0.010101318359375 +56577 -0.019439697265625 +56578 -0.022796630859375 +56579 -0.001556396484375 +56580 0.056304931640625 +56581 0.106719970703125 +56582 0.096893310546875 +56583 0.042694091796875 +56584 -0.018035888671875 +56585 -0.07586669921875 +56586 -0.11944580078125 +56587 -0.15972900390625 +56588 -0.202606201171875 +56589 -0.24859619140625 +56590 -0.30517578125 +56591 -0.36212158203125 +56592 -0.39141845703125 +56593 -0.35528564453125 +56594 -0.249969482421875 +56595 -0.092864990234375 +56596 0.08905029296875 +56597 0.2352294921875 +56598 0.318817138671875 +56599 0.358642578125 +56600 0.347747802734375 +56601 0.28564453125 +56602 0.223175048828125 +56603 0.196746826171875 +56604 0.179840087890625 +56605 0.155548095703125 +56606 0.151214599609375 +56607 0.156951904296875 +56608 0.13177490234375 +56609 0.100799560546875 +56610 0.087127685546875 +56611 0.05487060546875 +56612 -0.009002685546875 +56613 -0.10400390625 +56614 -0.229400634765625 +56615 -0.35552978515625 +56616 -0.441925048828125 +56617 -0.473846435546875 +56618 -0.464813232421875 +56619 -0.419097900390625 +56620 -0.334320068359375 +56621 -0.227935791015625 +56622 -0.12347412109375 +56623 -0.02764892578125 +56624 0.077667236328125 +56625 0.2132568359375 +56626 0.38885498046875 +56627 0.582794189453125 +56628 0.734039306640625 +56629 0.800140380859375 +56630 0.7783203125 +56631 0.6651611328125 +56632 0.45965576171875 +56633 0.199188232421875 +56634 -0.050689697265625 +56635 -0.23297119140625 +56636 -0.33013916015625 +56637 -0.368408203125 +56638 -0.378936767578125 +56639 -0.376983642578125 +56640 -0.37969970703125 +56641 -0.391510009765625 +56642 -0.385345458984375 +56643 -0.3419189453125 +56644 -0.28289794921875 +56645 -0.251617431640625 +56646 -0.266143798828125 +56647 -0.273345947265625 +56648 -0.216796875 +56649 -0.128265380859375 +56650 -0.068145751953125 +56651 -0.0430908203125 +56652 -0.024444580078125 +56653 0.020721435546875 +56654 0.124481201171875 +56655 0.25787353515625 +56656 0.379119873046875 +56657 0.47991943359375 +56658 0.5281982421875 +56659 0.511138916015625 +56660 0.456207275390625 +56661 0.407470703125 +56662 0.383758544921875 +56663 0.35687255859375 +56664 0.31182861328125 +56665 0.250885009765625 +56666 0.1654052734375 +56667 0.035247802734375 +56668 -0.142059326171875 +56669 -0.33563232421875 +56670 -0.5345458984375 +56671 -0.72186279296875 +56672 -0.836669921875 +56673 -0.8326416015625 +56674 -0.7296142578125 +56675 -0.582550048828125 +56676 -0.440093994140625 +56677 -0.324310302734375 +56678 -0.20147705078125 +56679 -0.044647216796875 +56680 0.103973388671875 +56681 0.202392578125 +56682 0.264495849609375 +56683 0.338897705078125 +56684 0.443817138671875 +56685 0.545074462890625 +56686 0.6173095703125 +56687 0.6524658203125 +56688 0.66339111328125 +56689 0.6561279296875 +56690 0.606781005859375 +56691 0.501190185546875 +56692 0.352783203125 +56693 0.176544189453125 +56694 -0.034820556640625 +56695 -0.258209228515625 +56696 -0.44244384765625 +56697 -0.5753173828125 +56698 -0.65203857421875 +56699 -0.641632080078125 +56700 -0.562164306640625 +56701 -0.458038330078125 +56702 -0.350555419921875 +56703 -0.260528564453125 +56704 -0.192108154296875 +56705 -0.141937255859375 +56706 -0.1021728515625 +56707 -0.062896728515625 +56708 -0.011932373046875 +56709 0.062835693359375 +56710 0.148712158203125 +56711 0.241729736328125 +56712 0.34912109375 +56713 0.457305908203125 +56714 0.54388427734375 +56715 0.5728759765625 +56716 0.506591796875 +56717 0.351226806640625 +56718 0.146514892578125 +56719 -0.05523681640625 +56720 -0.21624755859375 +56721 -0.334930419921875 +56722 -0.402984619140625 +56723 -0.4412841796875 +56724 -0.49578857421875 +56725 -0.5601806640625 +56726 -0.600738525390625 +56727 -0.584228515625 +56728 -0.47930908203125 +56729 -0.27935791015625 +56730 -0.0089111328125 +56731 0.268798828125 +56732 0.482818603515625 +56733 0.60369873046875 +56734 0.650421142578125 +56735 0.66400146484375 +56736 0.6414794921875 +56737 0.572540283203125 +56738 0.498138427734375 +56739 0.439453125 +56740 0.375518798828125 +56741 0.274505615234375 +56742 0.1087646484375 +56743 -0.099395751953125 +56744 -0.3182373046875 +56745 -0.5489501953125 +56746 -0.7738037109375 +56747 -0.86383056640625 +56748 -0.870391845703125 +56749 -0.86895751953125 +56750 -0.861053466796875 +56751 -0.765869140625 +56752 -0.5301513671875 +56753 -0.214691162109375 +56754 0.137359619140625 +56755 0.474822998046875 +56756 0.76239013671875 +56757 0.867462158203125 +56758 0.870361328125 +56759 0.86480712890625 +56760 0.831817626953125 +56761 0.677581787109375 +56762 0.495880126953125 +56763 0.30767822265625 +56764 0.116180419921875 +56765 -0.110748291015625 +56766 -0.381805419921875 +56767 -0.6572265625 +56768 -0.857421875 +56769 -0.870391845703125 +56770 -0.870391845703125 +56771 -0.86444091796875 +56772 -0.85723876953125 +56773 -0.790008544921875 +56774 -0.62847900390625 +56775 -0.3956298828125 +56776 -0.126708984375 +56777 0.150115966796875 +56778 0.424041748046875 +56779 0.670623779296875 +56780 0.854522705078125 +56781 0.866485595703125 +56782 0.86920166015625 +56783 0.8653564453125 +56784 0.857147216796875 +56785 0.766845703125 +56786 0.628509521484375 +56787 0.462127685546875 +56788 0.297210693359375 +56789 0.14862060546875 +56790 -0.00537109375 +56791 -0.15753173828125 +56792 -0.31304931640625 +56793 -0.48876953125 +56794 -0.6416015625 +56795 -0.751373291015625 +56796 -0.84619140625 +56797 -0.861297607421875 +56798 -0.863250732421875 +56799 -0.856597900390625 +56800 -0.7498779296875 +56801 -0.624542236328125 +56802 -0.47808837890625 +56803 -0.253387451171875 +56804 0.003692626953125 +56805 0.2257080078125 +56806 0.427154541015625 +56807 0.643218994140625 +56808 0.855926513671875 +56809 0.870361328125 +56810 0.870361328125 +56811 0.862762451171875 +56812 0.79669189453125 +56813 0.595794677734375 +56814 0.362152099609375 +56815 0.1270751953125 +56816 -0.086944580078125 +56817 -0.2784423828125 +56818 -0.484832763671875 +56819 -0.729583740234375 +56820 -0.86688232421875 +56821 -0.870391845703125 +56822 -0.86859130859375 +56823 -0.86279296875 +56824 -0.817962646484375 +56825 -0.6116943359375 +56826 -0.3128662109375 +56827 0.039398193359375 +56828 0.422821044921875 +56829 0.805145263671875 +56830 0.870361328125 +56831 0.870361328125 +56832 0.860015869140625 +56833 0.727935791015625 +56834 0.48114013671875 +56835 0.2059326171875 +56836 -0.06103515625 +56837 -0.29913330078125 +56838 -0.516204833984375 +56839 -0.7252197265625 +56840 -0.85980224609375 +56841 -0.870391845703125 +56842 -0.870391845703125 +56843 -0.858062744140625 +56844 -0.673004150390625 +56845 -0.42694091796875 +56846 -0.2100830078125 +56847 -0.0362548828125 +56848 0.10943603515625 +56849 0.23516845703125 +56850 0.373687744140625 +56851 0.517791748046875 +56852 0.602783203125 +56853 0.635711669921875 +56854 0.655181884765625 +56855 0.65948486328125 +56856 0.651275634765625 +56857 0.61846923828125 +56858 0.53753662109375 +56859 0.404144287109375 +56860 0.22186279296875 +56861 0.003997802734375 +56862 -0.22100830078125 +56863 -0.42449951171875 +56864 -0.579833984375 +56865 -0.641876220703125 +56866 -0.6177978515625 +56867 -0.575531005859375 +56868 -0.526336669921875 +56869 -0.42645263671875 +56870 -0.2581787109375 +56871 -0.068695068359375 +56872 0.09222412109375 +56873 0.232147216796875 +56874 0.3509521484375 +56875 0.410064697265625 +56876 0.372955322265625 +56877 0.2554931640625 +56878 0.10711669921875 +56879 -0.052886962890625 +56880 -0.186279296875 +56881 -0.23291015625 +56882 -0.209442138671875 +56883 -0.174163818359375 +56884 -0.126739501953125 +56885 -0.048126220703125 +56886 0.0426025390625 +56887 0.10748291015625 +56888 0.1409912109375 +56889 0.19708251953125 +56890 0.273651123046875 +56891 0.31768798828125 +56892 0.341094970703125 +56893 0.368011474609375 +56894 0.37249755859375 +56895 0.30072021484375 +56896 0.1517333984375 +56897 -0.01470947265625 +56898 -0.1883544921875 +56899 -0.372711181640625 +56900 -0.51397705078125 +56901 -0.57177734375 +56902 -0.53948974609375 +56903 -0.43511962890625 +56904 -0.2962646484375 +56905 -0.161102294921875 +56906 -0.0435791015625 +56907 0.060394287109375 +56908 0.13665771484375 +56909 0.170135498046875 +56910 0.16552734375 +56911 0.15728759765625 +56912 0.150787353515625 +56913 0.12200927734375 +56914 0.080108642578125 +56915 0.05126953125 +56916 0.062896728515625 +56917 0.09271240234375 +56918 0.092987060546875 +56919 0.07855224609375 +56920 0.06427001953125 +56921 0.0347900390625 +56922 -0.01171875 +56923 -0.056060791015625 +56924 -0.055511474609375 +56925 -0.010467529296875 +56926 0.02508544921875 +56927 0.025665283203125 +56928 0.017333984375 +56929 0.00189208984375 +56930 -0.03173828125 +56931 -0.071502685546875 +56932 -0.13543701171875 +56933 -0.219970703125 +56934 -0.300506591796875 +56935 -0.376312255859375 +56936 -0.416107177734375 +56937 -0.371124267578125 +56938 -0.242279052734375 +56939 -0.069732666015625 +56940 0.125640869140625 +56941 0.31268310546875 +56942 0.45501708984375 +56943 0.554779052734375 +56944 0.61065673828125 +56945 0.610931396484375 +56946 0.531463623046875 +56947 0.3883056640625 +56948 0.23468017578125 +56949 0.095245361328125 +56950 -0.00396728515625 +56951 -0.04852294921875 +56952 -0.055145263671875 +56953 -0.0758056640625 +56954 -0.138702392578125 +56955 -0.209197998046875 +56956 -0.289031982421875 +56957 -0.37884521484375 +56958 -0.456329345703125 +56959 -0.51641845703125 +56960 -0.519287109375 +56961 -0.458251953125 +56962 -0.384796142578125 +56963 -0.323699951171875 +56964 -0.269287109375 +56965 -0.1951904296875 +56966 -0.100006103515625 +56967 -0.01055908203125 +56968 0.1033935546875 +56969 0.24908447265625 +56970 0.373199462890625 +56971 0.45806884765625 +56972 0.511474609375 +56973 0.565399169921875 +56974 0.61138916015625 +56975 0.5897216796875 +56976 0.4906005859375 +56977 0.33148193359375 +56978 0.147796630859375 +56979 -0.01873779296875 +56980 -0.140289306640625 +56981 -0.191986083984375 +56982 -0.184295654296875 +56983 -0.161834716796875 +56984 -0.166595458984375 +56985 -0.19390869140625 +56986 -0.22442626953125 +56987 -0.279754638671875 +56988 -0.3389892578125 +56989 -0.3543701171875 +56990 -0.348175048828125 +56991 -0.32598876953125 +56992 -0.2581787109375 +56993 -0.139801025390625 +56994 0.014617919921875 +56995 0.144378662109375 +56996 0.221038818359375 +56997 0.27069091796875 +56998 0.294036865234375 +56999 0.311767578125 +57000 0.339141845703125 +57001 0.360260009765625 +57002 0.360504150390625 +57003 0.308380126953125 +57004 0.18170166015625 +57005 0.0047607421875 +57006 -0.17559814453125 +57007 -0.3143310546875 +57008 -0.36785888671875 +57009 -0.36248779296875 +57010 -0.343536376953125 +57011 -0.3018798828125 +57012 -0.231414794921875 +57013 -0.117645263671875 +57014 0.007049560546875 +57015 0.087982177734375 +57016 0.13946533203125 +57017 0.17425537109375 +57018 0.188201904296875 +57019 0.171234130859375 +57020 0.118438720703125 +57021 0.05706787109375 +57022 -0.010711669921875 +57023 -0.0914306640625 +57024 -0.162322998046875 +57025 -0.194549560546875 +57026 -0.1492919921875 +57027 -0.02166748046875 +57028 0.124053955078125 +57029 0.211151123046875 +57030 0.240447998046875 +57031 0.242218017578125 +57032 0.2257080078125 +57033 0.194366455078125 +57034 0.115509033203125 +57035 0.0128173828125 +57036 -0.053802490234375 +57037 -0.110626220703125 +57038 -0.199493408203125 +57039 -0.29437255859375 +57040 -0.33221435546875 +57041 -0.27972412109375 +57042 -0.185333251953125 +57043 -0.128204345703125 +57044 -0.115692138671875 +57045 -0.116455078125 +57046 -0.105926513671875 +57047 -0.053955078125 +57048 0.048797607421875 +57049 0.157318115234375 +57050 0.212005615234375 +57051 0.218475341796875 +57052 0.23724365234375 +57053 0.30535888671875 +57054 0.38128662109375 +57055 0.404449462890625 +57056 0.3944091796875 +57057 0.3885498046875 +57058 0.362640380859375 +57059 0.27362060546875 +57060 0.11712646484375 +57061 -0.054901123046875 +57062 -0.19085693359375 +57063 -0.28570556640625 +57064 -0.339263916015625 +57065 -0.3775634765625 +57066 -0.445709228515625 +57067 -0.535064697265625 +57068 -0.629058837890625 +57069 -0.697601318359375 +57070 -0.70391845703125 +57071 -0.6424560546875 +57072 -0.491241455078125 +57073 -0.265716552734375 +57074 -0.023712158203125 +57075 0.201751708984375 +57076 0.375823974609375 +57077 0.485076904296875 +57078 0.56884765625 +57079 0.634765625 +57080 0.63763427734375 +57081 0.5660400390625 +57082 0.4720458984375 +57083 0.40692138671875 +57084 0.3778076171875 +57085 0.376953125 +57086 0.371978759765625 +57087 0.313140869140625 +57088 0.184417724609375 +57089 0.011199951171875 +57090 -0.171051025390625 +57091 -0.33740234375 +57092 -0.47198486328125 +57093 -0.560394287109375 +57094 -0.58056640625 +57095 -0.54754638671875 +57096 -0.508575439453125 +57097 -0.459503173828125 +57098 -0.394378662109375 +57099 -0.35260009765625 +57100 -0.31170654296875 +57101 -0.197418212890625 +57102 -0.007965087890625 +57103 0.207489013671875 +57104 0.409210205078125 +57105 0.57208251953125 +57106 0.66595458984375 +57107 0.65875244140625 +57108 0.56744384765625 +57109 0.431396484375 +57110 0.29443359375 +57111 0.182464599609375 +57112 0.06365966796875 +57113 -0.075958251953125 +57114 -0.189422607421875 +57115 -0.271942138671875 +57116 -0.342529296875 +57117 -0.364166259765625 +57118 -0.327239990234375 +57119 -0.2769775390625 +57120 -0.253692626953125 +57121 -0.24365234375 +57122 -0.1983642578125 +57123 -0.116241455078125 +57124 -0.036834716796875 +57125 0.034881591796875 +57126 0.09124755859375 +57127 0.10888671875 +57128 0.125518798828125 +57129 0.15771484375 +57130 0.17828369140625 +57131 0.17108154296875 +57132 0.129974365234375 +57133 0.082427978515625 +57134 0.027679443359375 +57135 -0.065643310546875 +57136 -0.15936279296875 +57137 -0.21307373046875 +57138 -0.234649658203125 +57139 -0.2001953125 +57140 -0.119171142578125 +57141 -0.024749755859375 +57142 0.085784912109375 +57143 0.178131103515625 +57144 0.215576171875 +57145 0.211456298828125 +57146 0.17523193359375 +57147 0.128753662109375 +57148 0.1019287109375 +57149 0.0743408203125 +57150 0.04327392578125 +57151 0.038177490234375 +57152 0.076263427734375 +57153 0.14105224609375 +57154 0.186431884765625 +57155 0.188812255859375 +57156 0.1390380859375 +57157 0.041778564453125 +57158 -0.079437255859375 +57159 -0.219390869140625 +57160 -0.367828369140625 +57161 -0.494873046875 +57162 -0.556243896484375 +57163 -0.508697509765625 +57164 -0.3756103515625 +57165 -0.218902587890625 +57166 -0.063751220703125 +57167 0.091552734375 +57168 0.23602294921875 +57169 0.342987060546875 +57170 0.39520263671875 +57171 0.389373779296875 +57172 0.324249267578125 +57173 0.224090576171875 +57174 0.124267578125 +57175 0.037078857421875 +57176 -0.010101318359375 +57177 -0.019439697265625 +57178 -0.022796630859375 +57179 -0.001556396484375 +57180 0.056304931640625 +57181 0.106719970703125 +57182 0.096893310546875 +57183 0.042694091796875 +57184 -0.018035888671875 +57185 -0.07586669921875 +57186 -0.11944580078125 +57187 -0.15972900390625 +57188 -0.202606201171875 +57189 -0.24859619140625 +57190 -0.30517578125 +57191 -0.36212158203125 +57192 -0.39141845703125 +57193 -0.35528564453125 +57194 -0.249969482421875 +57195 -0.092864990234375 +57196 0.08905029296875 +57197 0.2352294921875 +57198 0.318817138671875 +57199 0.358642578125 +57200 0.347747802734375 +57201 0.28564453125 +57202 0.223175048828125 +57203 0.196746826171875 +57204 0.179840087890625 +57205 0.155548095703125 +57206 0.151214599609375 +57207 0.156951904296875 +57208 0.13177490234375 +57209 0.100799560546875 +57210 0.087127685546875 +57211 0.05487060546875 +57212 -0.009002685546875 +57213 -0.10400390625 +57214 -0.229400634765625 +57215 -0.35552978515625 +57216 -0.441925048828125 +57217 -0.473846435546875 +57218 -0.464813232421875 +57219 -0.419097900390625 +57220 -0.334320068359375 +57221 -0.227935791015625 +57222 -0.12347412109375 +57223 -0.02764892578125 +57224 0.077667236328125 +57225 0.2132568359375 +57226 0.38885498046875 +57227 0.582794189453125 +57228 0.734039306640625 +57229 0.800140380859375 +57230 0.7783203125 +57231 0.6651611328125 +57232 0.45965576171875 +57233 0.199188232421875 +57234 -0.050689697265625 +57235 -0.23297119140625 +57236 -0.33013916015625 +57237 -0.368408203125 +57238 -0.378936767578125 +57239 -0.376983642578125 +57240 -0.37969970703125 +57241 -0.391510009765625 +57242 -0.385345458984375 +57243 -0.3419189453125 +57244 -0.28289794921875 +57245 -0.251617431640625 +57246 -0.266143798828125 +57247 -0.273345947265625 +57248 -0.216796875 +57249 -0.128265380859375 +57250 -0.068145751953125 +57251 -0.0430908203125 +57252 -0.024444580078125 +57253 0.020721435546875 +57254 0.124481201171875 +57255 0.25787353515625 +57256 0.379119873046875 +57257 0.47991943359375 +57258 0.5281982421875 +57259 0.511138916015625 +57260 0.456207275390625 +57261 0.407470703125 +57262 0.383758544921875 +57263 0.35687255859375 +57264 0.31182861328125 +57265 0.250885009765625 +57266 0.1654052734375 +57267 0.035247802734375 +57268 -0.142059326171875 +57269 -0.33563232421875 +57270 -0.5345458984375 +57271 -0.72186279296875 +57272 -0.836669921875 +57273 -0.8326416015625 +57274 -0.7296142578125 +57275 -0.582550048828125 +57276 -0.440093994140625 +57277 -0.324310302734375 +57278 -0.20147705078125 +57279 -0.044647216796875 +57280 0.103973388671875 +57281 0.202392578125 +57282 0.264495849609375 +57283 0.338897705078125 +57284 0.443817138671875 +57285 0.545074462890625 +57286 0.6173095703125 +57287 0.6524658203125 +57288 0.66339111328125 +57289 0.6561279296875 +57290 0.606781005859375 +57291 0.501190185546875 +57292 0.352783203125 +57293 0.176544189453125 +57294 -0.034820556640625 +57295 -0.258209228515625 +57296 -0.44244384765625 +57297 -0.5753173828125 +57298 -0.65203857421875 +57299 -0.641632080078125 +57300 -0.562164306640625 +57301 -0.458038330078125 +57302 -0.350555419921875 +57303 -0.260528564453125 +57304 -0.192108154296875 +57305 -0.141937255859375 +57306 -0.1021728515625 +57307 -0.062896728515625 +57308 -0.011932373046875 +57309 0.062835693359375 +57310 0.148712158203125 +57311 0.241729736328125 +57312 0.34912109375 +57313 0.457305908203125 +57314 0.54388427734375 +57315 0.5728759765625 +57316 0.506591796875 +57317 0.351226806640625 +57318 0.146514892578125 +57319 -0.05523681640625 +57320 -0.21624755859375 +57321 -0.334930419921875 +57322 -0.402984619140625 +57323 -0.4412841796875 +57324 -0.49578857421875 +57325 -0.5601806640625 +57326 -0.600738525390625 +57327 -0.584228515625 +57328 -0.47930908203125 +57329 -0.27935791015625 +57330 -0.0089111328125 +57331 0.268798828125 +57332 0.482818603515625 +57333 0.60369873046875 +57334 0.650421142578125 +57335 0.66400146484375 +57336 0.6414794921875 +57337 0.572540283203125 +57338 0.498138427734375 +57339 0.439453125 +57340 0.375518798828125 +57341 0.274505615234375 +57342 0.1087646484375 +57343 -0.099395751953125 +57344 -0.3182373046875 +57345 -0.5489501953125 +57346 -0.7738037109375 +57347 -0.86383056640625 +57348 -0.870391845703125 +57349 -0.86895751953125 +57350 -0.861053466796875 +57351 -0.765869140625 +57352 -0.5301513671875 +57353 -0.214691162109375 +57354 0.137359619140625 +57355 0.474822998046875 +57356 0.76239013671875 +57357 0.867462158203125 +57358 0.870361328125 +57359 0.86480712890625 +57360 0.831817626953125 +57361 0.677581787109375 +57362 0.495880126953125 +57363 0.30767822265625 +57364 0.116180419921875 +57365 -0.110748291015625 +57366 -0.381805419921875 +57367 -0.6572265625 +57368 -0.857421875 +57369 -0.870391845703125 +57370 -0.870391845703125 +57371 -0.86444091796875 +57372 -0.85723876953125 +57373 -0.790008544921875 +57374 -0.62847900390625 +57375 -0.3956298828125 +57376 -0.126708984375 +57377 0.150115966796875 +57378 0.424041748046875 +57379 0.670623779296875 +57380 0.854522705078125 +57381 0.866485595703125 +57382 0.86920166015625 +57383 0.8653564453125 +57384 0.857147216796875 +57385 0.766845703125 +57386 0.628509521484375 +57387 0.462127685546875 +57388 0.297210693359375 +57389 0.14862060546875 +57390 -0.00537109375 +57391 -0.15753173828125 +57392 -0.31304931640625 +57393 -0.48876953125 +57394 -0.6416015625 +57395 -0.751373291015625 +57396 -0.84619140625 +57397 -0.861297607421875 +57398 -0.863250732421875 +57399 -0.856597900390625 +57400 -0.7498779296875 +57401 -0.624542236328125 +57402 -0.47808837890625 +57403 -0.253387451171875 +57404 0.003692626953125 +57405 0.2257080078125 +57406 0.427154541015625 +57407 0.643218994140625 +57408 0.855926513671875 +57409 0.870361328125 +57410 0.870361328125 +57411 0.862762451171875 +57412 0.79669189453125 +57413 0.595794677734375 +57414 0.362152099609375 +57415 0.1270751953125 +57416 -0.086944580078125 +57417 -0.2784423828125 +57418 -0.484832763671875 +57419 -0.729583740234375 +57420 -0.86688232421875 +57421 -0.870391845703125 +57422 -0.86859130859375 +57423 -0.86279296875 +57424 -0.817962646484375 +57425 -0.6116943359375 +57426 -0.3128662109375 +57427 0.039398193359375 +57428 0.422821044921875 +57429 0.805145263671875 +57430 0.870361328125 +57431 0.870361328125 +57432 0.860015869140625 +57433 0.727935791015625 +57434 0.48114013671875 +57435 0.2059326171875 +57436 -0.06103515625 +57437 -0.29913330078125 +57438 -0.516204833984375 +57439 -0.7252197265625 +57440 -0.85980224609375 +57441 -0.870391845703125 +57442 -0.870391845703125 +57443 -0.858062744140625 +57444 -0.673004150390625 +57445 -0.42694091796875 +57446 -0.2100830078125 +57447 -0.0362548828125 +57448 0.10943603515625 +57449 0.23516845703125 +57450 0.373687744140625 +57451 0.517791748046875 +57452 0.602783203125 +57453 0.635711669921875 +57454 0.655181884765625 +57455 0.65948486328125 +57456 0.651275634765625 +57457 0.61846923828125 +57458 0.53753662109375 +57459 0.404144287109375 +57460 0.22186279296875 +57461 0.003997802734375 +57462 -0.22100830078125 +57463 -0.42449951171875 +57464 -0.579833984375 +57465 -0.641876220703125 +57466 -0.6177978515625 +57467 -0.575531005859375 +57468 -0.526336669921875 +57469 -0.42645263671875 +57470 -0.2581787109375 +57471 -0.068695068359375 +57472 0.09222412109375 +57473 0.232147216796875 +57474 0.3509521484375 +57475 0.410064697265625 +57476 0.372955322265625 +57477 0.2554931640625 +57478 0.10711669921875 +57479 -0.052886962890625 +57480 -0.186279296875 +57481 -0.23291015625 +57482 -0.209442138671875 +57483 -0.174163818359375 +57484 -0.126739501953125 +57485 -0.048126220703125 +57486 0.0426025390625 +57487 0.10748291015625 +57488 0.1409912109375 +57489 0.19708251953125 +57490 0.273651123046875 +57491 0.31768798828125 +57492 0.341094970703125 +57493 0.368011474609375 +57494 0.37249755859375 +57495 0.30072021484375 +57496 0.1517333984375 +57497 -0.01470947265625 +57498 -0.1883544921875 +57499 -0.372711181640625 +57500 -0.51397705078125 +57501 -0.57177734375 +57502 -0.53948974609375 +57503 -0.43511962890625 +57504 -0.2962646484375 +57505 -0.161102294921875 +57506 -0.0435791015625 +57507 0.060394287109375 +57508 0.13665771484375 +57509 0.170135498046875 +57510 0.16552734375 +57511 0.15728759765625 +57512 0.150787353515625 +57513 0.12200927734375 +57514 0.080108642578125 +57515 0.05126953125 +57516 0.062896728515625 +57517 0.09271240234375 +57518 0.092987060546875 +57519 0.07855224609375 +57520 0.06427001953125 +57521 0.0347900390625 +57522 -0.01171875 +57523 -0.056060791015625 +57524 -0.055511474609375 +57525 -0.010467529296875 +57526 0.02508544921875 +57527 0.025665283203125 +57528 0.017333984375 +57529 0.00189208984375 +57530 -0.03173828125 +57531 -0.071502685546875 +57532 -0.13543701171875 +57533 -0.219970703125 +57534 -0.300506591796875 +57535 -0.376312255859375 +57536 -0.416107177734375 +57537 -0.371124267578125 +57538 -0.242279052734375 +57539 -0.069732666015625 +57540 0.125640869140625 +57541 0.31268310546875 +57542 0.45501708984375 +57543 0.554779052734375 +57544 0.61065673828125 +57545 0.610931396484375 +57546 0.531463623046875 +57547 0.3883056640625 +57548 0.23468017578125 +57549 0.095245361328125 +57550 -0.00396728515625 +57551 -0.04852294921875 +57552 -0.055145263671875 +57553 -0.0758056640625 +57554 -0.138702392578125 +57555 -0.209197998046875 +57556 -0.289031982421875 +57557 -0.37884521484375 +57558 -0.456329345703125 +57559 -0.51641845703125 +57560 -0.519287109375 +57561 -0.458251953125 +57562 -0.384796142578125 +57563 -0.323699951171875 +57564 -0.269287109375 +57565 -0.1951904296875 +57566 -0.100006103515625 +57567 -0.01055908203125 +57568 0.1033935546875 +57569 0.24908447265625 +57570 0.373199462890625 +57571 0.45806884765625 +57572 0.511474609375 +57573 0.565399169921875 +57574 0.61138916015625 +57575 0.5897216796875 +57576 0.4906005859375 +57577 0.33148193359375 +57578 0.147796630859375 +57579 -0.01873779296875 +57580 -0.140289306640625 +57581 -0.191986083984375 +57582 -0.184295654296875 +57583 -0.161834716796875 +57584 -0.166595458984375 +57585 -0.19390869140625 +57586 -0.22442626953125 +57587 -0.279754638671875 +57588 -0.3389892578125 +57589 -0.3543701171875 +57590 -0.348175048828125 +57591 -0.32598876953125 +57592 -0.2581787109375 +57593 -0.139801025390625 +57594 0.014617919921875 +57595 0.144378662109375 +57596 0.221038818359375 +57597 0.27069091796875 +57598 0.294036865234375 +57599 0.311767578125 +57600 0.339141845703125 +57601 0.360260009765625 +57602 0.360504150390625 +57603 0.308380126953125 +57604 0.18170166015625 +57605 0.0047607421875 +57606 -0.17559814453125 +57607 -0.3143310546875 +57608 -0.36785888671875 +57609 -0.36248779296875 +57610 -0.343536376953125 +57611 -0.3018798828125 +57612 -0.231414794921875 +57613 -0.117645263671875 +57614 0.007049560546875 +57615 0.087982177734375 +57616 0.13946533203125 +57617 0.17425537109375 +57618 0.188201904296875 +57619 0.171234130859375 +57620 0.118438720703125 +57621 0.05706787109375 +57622 -0.010711669921875 +57623 -0.0914306640625 +57624 -0.162322998046875 +57625 -0.194549560546875 +57626 -0.1492919921875 +57627 -0.02166748046875 +57628 0.124053955078125 +57629 0.211151123046875 +57630 0.240447998046875 +57631 0.242218017578125 +57632 0.2257080078125 +57633 0.194366455078125 +57634 0.115509033203125 +57635 0.0128173828125 +57636 -0.053802490234375 +57637 -0.110626220703125 +57638 -0.199493408203125 +57639 -0.29437255859375 +57640 -0.33221435546875 +57641 -0.27972412109375 +57642 -0.185333251953125 +57643 -0.128204345703125 +57644 -0.115692138671875 +57645 -0.116455078125 +57646 -0.105926513671875 +57647 -0.053955078125 +57648 0.048797607421875 +57649 0.157318115234375 +57650 0.212005615234375 +57651 0.218475341796875 +57652 0.23724365234375 +57653 0.30535888671875 +57654 0.38128662109375 +57655 0.404449462890625 +57656 0.3944091796875 +57657 0.3885498046875 +57658 0.362640380859375 +57659 0.27362060546875 +57660 0.11712646484375 +57661 -0.054901123046875 +57662 -0.19085693359375 +57663 -0.28570556640625 +57664 -0.339263916015625 +57665 -0.3775634765625 +57666 -0.445709228515625 +57667 -0.535064697265625 +57668 -0.629058837890625 +57669 -0.697601318359375 +57670 -0.70391845703125 +57671 -0.6424560546875 +57672 -0.491241455078125 +57673 -0.265716552734375 +57674 -0.023712158203125 +57675 0.201751708984375 +57676 0.375823974609375 +57677 0.485076904296875 +57678 0.56884765625 +57679 0.634765625 +57680 0.63763427734375 +57681 0.5660400390625 +57682 0.4720458984375 +57683 0.40692138671875 +57684 0.3778076171875 +57685 0.376953125 +57686 0.371978759765625 +57687 0.313140869140625 +57688 0.184417724609375 +57689 0.011199951171875 +57690 -0.171051025390625 +57691 -0.33740234375 +57692 -0.47198486328125 +57693 -0.560394287109375 +57694 -0.58056640625 +57695 -0.54754638671875 +57696 -0.508575439453125 +57697 -0.459503173828125 +57698 -0.394378662109375 +57699 -0.35260009765625 +57700 -0.31170654296875 +57701 -0.197418212890625 +57702 -0.007965087890625 +57703 0.207489013671875 +57704 0.409210205078125 +57705 0.57208251953125 +57706 0.66595458984375 +57707 0.65875244140625 +57708 0.56744384765625 +57709 0.431396484375 +57710 0.29443359375 +57711 0.182464599609375 +57712 0.06365966796875 +57713 -0.075958251953125 +57714 -0.189422607421875 +57715 -0.271942138671875 +57716 -0.342529296875 +57717 -0.364166259765625 +57718 -0.327239990234375 +57719 -0.2769775390625 +57720 -0.253692626953125 +57721 -0.24365234375 +57722 -0.1983642578125 +57723 -0.116241455078125 +57724 -0.036834716796875 +57725 0.034881591796875 +57726 0.09124755859375 +57727 0.10888671875 +57728 0.125518798828125 +57729 0.15771484375 +57730 0.17828369140625 +57731 0.17108154296875 +57732 0.129974365234375 +57733 0.082427978515625 +57734 0.027679443359375 +57735 -0.065643310546875 +57736 -0.15936279296875 +57737 -0.21307373046875 +57738 -0.234649658203125 +57739 -0.2001953125 +57740 -0.119171142578125 +57741 -0.024749755859375 +57742 0.085784912109375 +57743 0.178131103515625 +57744 0.215576171875 +57745 0.211456298828125 +57746 0.17523193359375 +57747 0.128753662109375 +57748 0.1019287109375 +57749 0.0743408203125 +57750 0.04327392578125 +57751 0.038177490234375 +57752 0.076263427734375 +57753 0.14105224609375 +57754 0.186431884765625 +57755 0.188812255859375 +57756 0.1390380859375 +57757 0.041778564453125 +57758 -0.079437255859375 +57759 -0.219390869140625 +57760 -0.367828369140625 +57761 -0.494873046875 +57762 -0.556243896484375 +57763 -0.508697509765625 +57764 -0.3756103515625 +57765 -0.218902587890625 +57766 -0.063751220703125 +57767 0.091552734375 +57768 0.23602294921875 +57769 0.342987060546875 +57770 0.39520263671875 +57771 0.389373779296875 +57772 0.324249267578125 +57773 0.224090576171875 +57774 0.124267578125 +57775 0.037078857421875 +57776 -0.010101318359375 +57777 -0.019439697265625 +57778 -0.022796630859375 +57779 -0.001556396484375 +57780 0.056304931640625 +57781 0.106719970703125 +57782 0.096893310546875 +57783 0.042694091796875 +57784 -0.018035888671875 +57785 -0.07586669921875 +57786 -0.11944580078125 +57787 -0.15972900390625 +57788 -0.202606201171875 +57789 -0.24859619140625 +57790 -0.30517578125 +57791 -0.36212158203125 +57792 -0.39141845703125 +57793 -0.35528564453125 +57794 -0.249969482421875 +57795 -0.092864990234375 +57796 0.08905029296875 +57797 0.2352294921875 +57798 0.318817138671875 +57799 0.358642578125 +57800 0.347747802734375 +57801 0.28564453125 +57802 0.223175048828125 +57803 0.196746826171875 +57804 0.179840087890625 +57805 0.155548095703125 +57806 0.151214599609375 +57807 0.156951904296875 +57808 0.13177490234375 +57809 0.100799560546875 +57810 0.087127685546875 +57811 0.05487060546875 +57812 -0.009002685546875 +57813 -0.10400390625 +57814 -0.229400634765625 +57815 -0.35552978515625 +57816 -0.441925048828125 +57817 -0.473846435546875 +57818 -0.464813232421875 +57819 -0.419097900390625 +57820 -0.334320068359375 +57821 -0.227935791015625 +57822 -0.12347412109375 +57823 -0.02764892578125 +57824 0.077667236328125 +57825 0.2132568359375 +57826 0.38885498046875 +57827 0.582794189453125 +57828 0.734039306640625 +57829 0.800140380859375 +57830 0.7783203125 +57831 0.6651611328125 +57832 0.45965576171875 +57833 0.199188232421875 +57834 -0.050689697265625 +57835 -0.23297119140625 +57836 -0.33013916015625 +57837 -0.368408203125 +57838 -0.378936767578125 +57839 -0.376983642578125 +57840 -0.37969970703125 +57841 -0.391510009765625 +57842 -0.385345458984375 +57843 -0.3419189453125 +57844 -0.28289794921875 +57845 -0.251617431640625 +57846 -0.266143798828125 +57847 -0.273345947265625 +57848 -0.216796875 +57849 -0.128265380859375 +57850 -0.068145751953125 +57851 -0.0430908203125 +57852 -0.024444580078125 +57853 0.020721435546875 +57854 0.124481201171875 +57855 0.25787353515625 +57856 0.379119873046875 +57857 0.47991943359375 +57858 0.5281982421875 +57859 0.511138916015625 +57860 0.456207275390625 +57861 0.407470703125 +57862 0.383758544921875 +57863 0.35687255859375 +57864 0.31182861328125 +57865 0.250885009765625 +57866 0.1654052734375 +57867 0.035247802734375 +57868 -0.142059326171875 +57869 -0.33563232421875 +57870 -0.5345458984375 +57871 -0.72186279296875 +57872 -0.836669921875 +57873 -0.8326416015625 +57874 -0.7296142578125 +57875 -0.582550048828125 +57876 -0.440093994140625 +57877 -0.324310302734375 +57878 -0.20147705078125 +57879 -0.044647216796875 +57880 0.103973388671875 +57881 0.202392578125 +57882 0.264495849609375 +57883 0.338897705078125 +57884 0.443817138671875 +57885 0.545074462890625 +57886 0.6173095703125 +57887 0.6524658203125 +57888 0.66339111328125 +57889 0.6561279296875 +57890 0.606781005859375 +57891 0.501190185546875 +57892 0.352783203125 +57893 0.176544189453125 +57894 -0.034820556640625 +57895 -0.258209228515625 +57896 -0.44244384765625 +57897 -0.5753173828125 +57898 -0.65203857421875 +57899 -0.641632080078125 +57900 -0.562164306640625 +57901 -0.458038330078125 +57902 -0.350555419921875 +57903 -0.260528564453125 +57904 -0.192108154296875 +57905 -0.141937255859375 +57906 -0.1021728515625 +57907 -0.062896728515625 +57908 -0.011932373046875 +57909 0.062835693359375 +57910 0.148712158203125 +57911 0.241729736328125 +57912 0.34912109375 +57913 0.457305908203125 +57914 0.54388427734375 +57915 0.5728759765625 +57916 0.506591796875 +57917 0.351226806640625 +57918 0.146514892578125 +57919 -0.05523681640625 +57920 -0.21624755859375 +57921 -0.334930419921875 +57922 -0.402984619140625 +57923 -0.4412841796875 +57924 -0.49578857421875 +57925 -0.5601806640625 +57926 -0.600738525390625 +57927 -0.584228515625 +57928 -0.47930908203125 +57929 -0.27935791015625 +57930 -0.0089111328125 +57931 0.268798828125 +57932 0.482818603515625 +57933 0.60369873046875 +57934 0.650421142578125 +57935 0.66400146484375 +57936 0.6414794921875 +57937 0.572540283203125 +57938 0.498138427734375 +57939 0.439453125 +57940 0.375518798828125 +57941 0.274505615234375 +57942 0.1087646484375 +57943 -0.099395751953125 +57944 -0.3182373046875 +57945 -0.5489501953125 +57946 -0.7738037109375 +57947 -0.86383056640625 +57948 -0.870391845703125 +57949 -0.86895751953125 +57950 -0.861053466796875 +57951 -0.765869140625 +57952 -0.5301513671875 +57953 -0.214691162109375 +57954 0.137359619140625 +57955 0.474822998046875 +57956 0.76239013671875 +57957 0.867462158203125 +57958 0.870361328125 +57959 0.86480712890625 +57960 0.831817626953125 +57961 0.677581787109375 +57962 0.495880126953125 +57963 0.30767822265625 +57964 0.116180419921875 +57965 -0.110748291015625 +57966 -0.381805419921875 +57967 -0.6572265625 +57968 -0.857421875 +57969 -0.870391845703125 +57970 -0.870391845703125 +57971 -0.86444091796875 +57972 -0.85723876953125 +57973 -0.790008544921875 +57974 -0.62847900390625 +57975 -0.3956298828125 +57976 -0.126708984375 +57977 0.150115966796875 +57978 0.424041748046875 +57979 0.670623779296875 +57980 0.854522705078125 +57981 0.866485595703125 +57982 0.86920166015625 +57983 0.8653564453125 +57984 0.857147216796875 +57985 0.766845703125 +57986 0.628509521484375 +57987 0.462127685546875 +57988 0.297210693359375 +57989 0.14862060546875 +57990 -0.00537109375 +57991 -0.15753173828125 +57992 -0.31304931640625 +57993 -0.48876953125 +57994 -0.6416015625 +57995 -0.751373291015625 +57996 -0.84619140625 +57997 -0.861297607421875 +57998 -0.863250732421875 +57999 -0.856597900390625 +58000 -0.7498779296875 +58001 -0.624542236328125 +58002 -0.47808837890625 +58003 -0.253387451171875 +58004 0.003692626953125 +58005 0.2257080078125 +58006 0.427154541015625 +58007 0.643218994140625 +58008 0.855926513671875 +58009 0.870361328125 +58010 0.870361328125 +58011 0.862762451171875 +58012 0.79669189453125 +58013 0.595794677734375 +58014 0.362152099609375 +58015 0.1270751953125 +58016 -0.086944580078125 +58017 -0.2784423828125 +58018 -0.484832763671875 +58019 -0.729583740234375 +58020 -0.86688232421875 +58021 -0.870391845703125 +58022 -0.86859130859375 +58023 -0.86279296875 +58024 -0.817962646484375 +58025 -0.6116943359375 +58026 -0.3128662109375 +58027 0.039398193359375 +58028 0.422821044921875 +58029 0.805145263671875 +58030 0.870361328125 +58031 0.870361328125 +58032 0.860015869140625 +58033 0.727935791015625 +58034 0.48114013671875 +58035 0.2059326171875 +58036 -0.06103515625 +58037 -0.29913330078125 +58038 -0.516204833984375 +58039 -0.7252197265625 +58040 -0.85980224609375 +58041 -0.870391845703125 +58042 -0.870391845703125 +58043 -0.858062744140625 +58044 -0.673004150390625 +58045 -0.42694091796875 +58046 -0.2100830078125 +58047 -0.0362548828125 +58048 0.10943603515625 +58049 0.23516845703125 +58050 0.373687744140625 +58051 0.517791748046875 +58052 0.602783203125 +58053 0.635711669921875 +58054 0.655181884765625 +58055 0.65948486328125 +58056 0.651275634765625 +58057 0.61846923828125 +58058 0.53753662109375 +58059 0.404144287109375 +58060 0.22186279296875 +58061 0.003997802734375 +58062 -0.22100830078125 +58063 -0.42449951171875 +58064 -0.579833984375 +58065 -0.641876220703125 +58066 -0.6177978515625 +58067 -0.575531005859375 +58068 -0.526336669921875 +58069 -0.42645263671875 +58070 -0.2581787109375 +58071 -0.068695068359375 +58072 0.09222412109375 +58073 0.232147216796875 +58074 0.3509521484375 +58075 0.410064697265625 +58076 0.372955322265625 +58077 0.2554931640625 +58078 0.10711669921875 +58079 -0.052886962890625 +58080 -0.186279296875 +58081 -0.23291015625 +58082 -0.209442138671875 +58083 -0.174163818359375 +58084 -0.126739501953125 +58085 -0.048126220703125 +58086 0.0426025390625 +58087 0.10748291015625 +58088 0.1409912109375 +58089 0.19708251953125 +58090 0.273651123046875 +58091 0.31768798828125 +58092 0.341094970703125 +58093 0.368011474609375 +58094 0.37249755859375 +58095 0.30072021484375 +58096 0.1517333984375 +58097 -0.01470947265625 +58098 -0.1883544921875 +58099 -0.372711181640625 +58100 -0.51397705078125 +58101 -0.57177734375 +58102 -0.53948974609375 +58103 -0.43511962890625 +58104 -0.2962646484375 +58105 -0.161102294921875 +58106 -0.0435791015625 +58107 0.060394287109375 +58108 0.13665771484375 +58109 0.170135498046875 +58110 0.16552734375 +58111 0.15728759765625 +58112 0.150787353515625 +58113 0.12200927734375 +58114 0.080108642578125 +58115 0.05126953125 +58116 0.062896728515625 +58117 0.09271240234375 +58118 0.092987060546875 +58119 0.07855224609375 +58120 0.06427001953125 +58121 0.0347900390625 +58122 -0.01171875 +58123 -0.056060791015625 +58124 -0.055511474609375 +58125 -0.010467529296875 +58126 0.02508544921875 +58127 0.025665283203125 +58128 0.017333984375 +58129 0.00189208984375 +58130 -0.03173828125 +58131 -0.071502685546875 +58132 -0.13543701171875 +58133 -0.219970703125 +58134 -0.300506591796875 +58135 -0.376312255859375 +58136 -0.416107177734375 +58137 -0.371124267578125 +58138 -0.242279052734375 +58139 -0.069732666015625 +58140 0.125640869140625 +58141 0.31268310546875 +58142 0.45501708984375 +58143 0.554779052734375 +58144 0.61065673828125 +58145 0.610931396484375 +58146 0.531463623046875 +58147 0.3883056640625 +58148 0.23468017578125 +58149 0.095245361328125 +58150 -0.00396728515625 +58151 -0.04852294921875 +58152 -0.055145263671875 +58153 -0.0758056640625 +58154 -0.138702392578125 +58155 -0.209197998046875 +58156 -0.289031982421875 +58157 -0.37884521484375 +58158 -0.456329345703125 +58159 -0.51641845703125 +58160 -0.519287109375 +58161 -0.458251953125 +58162 -0.384796142578125 +58163 -0.323699951171875 +58164 -0.269287109375 +58165 -0.1951904296875 +58166 -0.100006103515625 +58167 -0.01055908203125 +58168 0.1033935546875 +58169 0.24908447265625 +58170 0.373199462890625 +58171 0.45806884765625 +58172 0.511474609375 +58173 0.565399169921875 +58174 0.61138916015625 +58175 0.5897216796875 +58176 0.4906005859375 +58177 0.33148193359375 +58178 0.147796630859375 +58179 -0.01873779296875 +58180 -0.140289306640625 +58181 -0.191986083984375 +58182 -0.184295654296875 +58183 -0.161834716796875 +58184 -0.166595458984375 +58185 -0.19390869140625 +58186 -0.22442626953125 +58187 -0.279754638671875 +58188 -0.3389892578125 +58189 -0.3543701171875 +58190 -0.348175048828125 +58191 -0.32598876953125 +58192 -0.2581787109375 +58193 -0.139801025390625 +58194 0.014617919921875 +58195 0.144378662109375 +58196 0.221038818359375 +58197 0.27069091796875 +58198 0.294036865234375 +58199 0.311767578125 +58200 0.339141845703125 +58201 0.360260009765625 +58202 0.360504150390625 +58203 0.308380126953125 +58204 0.18170166015625 +58205 0.0047607421875 +58206 -0.17559814453125 +58207 -0.3143310546875 +58208 -0.36785888671875 +58209 -0.36248779296875 +58210 -0.343536376953125 +58211 -0.3018798828125 +58212 -0.231414794921875 +58213 -0.117645263671875 +58214 0.007049560546875 +58215 0.087982177734375 +58216 0.13946533203125 +58217 0.17425537109375 +58218 0.188201904296875 +58219 0.171234130859375 +58220 0.118438720703125 +58221 0.05706787109375 +58222 -0.010711669921875 +58223 -0.0914306640625 +58224 -0.162322998046875 +58225 -0.194549560546875 +58226 -0.1492919921875 +58227 -0.02166748046875 +58228 0.124053955078125 +58229 0.211151123046875 +58230 0.240447998046875 +58231 0.242218017578125 +58232 0.2257080078125 +58233 0.194366455078125 +58234 0.115509033203125 +58235 0.0128173828125 +58236 -0.053802490234375 +58237 -0.110626220703125 +58238 -0.199493408203125 +58239 -0.29437255859375 +58240 -0.33221435546875 +58241 -0.27972412109375 +58242 -0.185333251953125 +58243 -0.128204345703125 +58244 -0.115692138671875 +58245 -0.116455078125 +58246 -0.105926513671875 +58247 -0.053955078125 +58248 0.048797607421875 +58249 0.157318115234375 +58250 0.212005615234375 +58251 0.218475341796875 +58252 0.23724365234375 +58253 0.30535888671875 +58254 0.38128662109375 +58255 0.404449462890625 +58256 0.3944091796875 +58257 0.3885498046875 +58258 0.362640380859375 +58259 0.27362060546875 +58260 0.11712646484375 +58261 -0.054901123046875 +58262 -0.19085693359375 +58263 -0.28570556640625 +58264 -0.339263916015625 +58265 -0.3775634765625 +58266 -0.445709228515625 +58267 -0.535064697265625 +58268 -0.629058837890625 +58269 -0.697601318359375 +58270 -0.70391845703125 +58271 -0.6424560546875 +58272 -0.491241455078125 +58273 -0.265716552734375 +58274 -0.023712158203125 +58275 0.201751708984375 +58276 0.375823974609375 +58277 0.485076904296875 +58278 0.56884765625 +58279 0.634765625 +58280 0.63763427734375 +58281 0.5660400390625 +58282 0.4720458984375 +58283 0.40692138671875 +58284 0.3778076171875 +58285 0.376953125 +58286 0.371978759765625 +58287 0.313140869140625 +58288 0.184417724609375 +58289 0.011199951171875 +58290 -0.171051025390625 +58291 -0.33740234375 +58292 -0.47198486328125 +58293 -0.560394287109375 +58294 -0.58056640625 +58295 -0.54754638671875 +58296 -0.508575439453125 +58297 -0.459503173828125 +58298 -0.394378662109375 +58299 -0.35260009765625 +58300 -0.31170654296875 +58301 -0.197418212890625 +58302 -0.007965087890625 +58303 0.207489013671875 +58304 0.409210205078125 +58305 0.57208251953125 +58306 0.66595458984375 +58307 0.65875244140625 +58308 0.56744384765625 +58309 0.431396484375 +58310 0.29443359375 +58311 0.182464599609375 +58312 0.06365966796875 +58313 -0.075958251953125 +58314 -0.189422607421875 +58315 -0.271942138671875 +58316 -0.342529296875 +58317 -0.364166259765625 +58318 -0.327239990234375 +58319 -0.2769775390625 +58320 -0.253692626953125 +58321 -0.24365234375 +58322 -0.1983642578125 +58323 -0.116241455078125 +58324 -0.036834716796875 +58325 0.034881591796875 +58326 0.09124755859375 +58327 0.10888671875 +58328 0.125518798828125 +58329 0.15771484375 +58330 0.17828369140625 +58331 0.17108154296875 +58332 0.129974365234375 +58333 0.082427978515625 +58334 0.027679443359375 +58335 -0.065643310546875 +58336 -0.15936279296875 +58337 -0.21307373046875 +58338 -0.234649658203125 +58339 -0.2001953125 +58340 -0.119171142578125 +58341 -0.024749755859375 +58342 0.085784912109375 +58343 0.178131103515625 +58344 0.215576171875 +58345 0.211456298828125 +58346 0.17523193359375 +58347 0.128753662109375 +58348 0.1019287109375 +58349 0.0743408203125 +58350 0.04327392578125 +58351 0.038177490234375 +58352 0.076263427734375 +58353 0.14105224609375 +58354 0.186431884765625 +58355 0.188812255859375 +58356 0.1390380859375 +58357 0.041778564453125 +58358 -0.079437255859375 +58359 -0.219390869140625 +58360 -0.367828369140625 +58361 -0.494873046875 +58362 -0.556243896484375 +58363 -0.508697509765625 +58364 -0.3756103515625 +58365 -0.218902587890625 +58366 -0.063751220703125 +58367 0.091552734375 +58368 0.23602294921875 +58369 0.342987060546875 +58370 0.39520263671875 +58371 0.389373779296875 +58372 0.324249267578125 +58373 0.224090576171875 +58374 0.124267578125 +58375 0.037078857421875 +58376 -0.010101318359375 +58377 -0.019439697265625 +58378 -0.022796630859375 +58379 -0.001556396484375 +58380 0.056304931640625 +58381 0.106719970703125 +58382 0.096893310546875 +58383 0.042694091796875 +58384 -0.018035888671875 +58385 -0.07586669921875 +58386 -0.11944580078125 +58387 -0.15972900390625 +58388 -0.202606201171875 +58389 -0.24859619140625 +58390 -0.30517578125 +58391 -0.36212158203125 +58392 -0.39141845703125 +58393 -0.35528564453125 +58394 -0.249969482421875 +58395 -0.092864990234375 +58396 0.08905029296875 +58397 0.2352294921875 +58398 0.318817138671875 +58399 0.358642578125 +58400 0.347747802734375 +58401 0.28564453125 +58402 0.223175048828125 +58403 0.196746826171875 +58404 0.179840087890625 +58405 0.155548095703125 +58406 0.151214599609375 +58407 0.156951904296875 +58408 0.13177490234375 +58409 0.100799560546875 +58410 0.087127685546875 +58411 0.05487060546875 +58412 -0.009002685546875 +58413 -0.10400390625 +58414 -0.229400634765625 +58415 -0.35552978515625 +58416 -0.441925048828125 +58417 -0.473846435546875 +58418 -0.464813232421875 +58419 -0.419097900390625 +58420 -0.334320068359375 +58421 -0.227935791015625 +58422 -0.12347412109375 +58423 -0.02764892578125 +58424 0.077667236328125 +58425 0.2132568359375 +58426 0.38885498046875 +58427 0.582794189453125 +58428 0.734039306640625 +58429 0.800140380859375 +58430 0.7783203125 +58431 0.6651611328125 +58432 0.45965576171875 +58433 0.199188232421875 +58434 -0.050689697265625 +58435 -0.23297119140625 +58436 -0.33013916015625 +58437 -0.368408203125 +58438 -0.378936767578125 +58439 -0.376983642578125 +58440 -0.37969970703125 +58441 -0.391510009765625 +58442 -0.385345458984375 +58443 -0.3419189453125 +58444 -0.28289794921875 +58445 -0.251617431640625 +58446 -0.266143798828125 +58447 -0.273345947265625 +58448 -0.216796875 +58449 -0.128265380859375 +58450 -0.068145751953125 +58451 -0.0430908203125 +58452 -0.024444580078125 +58453 0.020721435546875 +58454 0.124481201171875 +58455 0.25787353515625 +58456 0.379119873046875 +58457 0.47991943359375 +58458 0.5281982421875 +58459 0.511138916015625 +58460 0.456207275390625 +58461 0.407470703125 +58462 0.383758544921875 +58463 0.35687255859375 +58464 0.31182861328125 +58465 0.250885009765625 +58466 0.1654052734375 +58467 0.035247802734375 +58468 -0.142059326171875 +58469 -0.33563232421875 +58470 -0.5345458984375 +58471 -0.72186279296875 +58472 -0.836669921875 +58473 -0.8326416015625 +58474 -0.7296142578125 +58475 -0.582550048828125 +58476 -0.440093994140625 +58477 -0.324310302734375 +58478 -0.20147705078125 +58479 -0.044647216796875 +58480 0.103973388671875 +58481 0.202392578125 +58482 0.264495849609375 +58483 0.338897705078125 +58484 0.443817138671875 +58485 0.545074462890625 +58486 0.6173095703125 +58487 0.6524658203125 +58488 0.66339111328125 +58489 0.6561279296875 +58490 0.606781005859375 +58491 0.501190185546875 +58492 0.352783203125 +58493 0.176544189453125 +58494 -0.034820556640625 +58495 -0.258209228515625 +58496 -0.44244384765625 +58497 -0.5753173828125 +58498 -0.65203857421875 +58499 -0.641632080078125 +58500 -0.562164306640625 +58501 -0.458038330078125 +58502 -0.350555419921875 +58503 -0.260528564453125 +58504 -0.192108154296875 +58505 -0.141937255859375 +58506 -0.1021728515625 +58507 -0.062896728515625 +58508 -0.011932373046875 +58509 0.062835693359375 +58510 0.148712158203125 +58511 0.241729736328125 +58512 0.34912109375 +58513 0.457305908203125 +58514 0.54388427734375 +58515 0.5728759765625 +58516 0.506591796875 +58517 0.351226806640625 +58518 0.146514892578125 +58519 -0.05523681640625 +58520 -0.21624755859375 +58521 -0.334930419921875 +58522 -0.402984619140625 +58523 -0.4412841796875 +58524 -0.49578857421875 +58525 -0.5601806640625 +58526 -0.600738525390625 +58527 -0.584228515625 +58528 -0.47930908203125 +58529 -0.27935791015625 +58530 -0.0089111328125 +58531 0.268798828125 +58532 0.482818603515625 +58533 0.60369873046875 +58534 0.650421142578125 +58535 0.66400146484375 +58536 0.6414794921875 +58537 0.572540283203125 +58538 0.498138427734375 +58539 0.439453125 +58540 0.375518798828125 +58541 0.274505615234375 +58542 0.1087646484375 +58543 -0.099395751953125 +58544 -0.3182373046875 +58545 -0.5489501953125 +58546 -0.7738037109375 +58547 -0.86383056640625 +58548 -0.870391845703125 +58549 -0.86895751953125 +58550 -0.861053466796875 +58551 -0.765869140625 +58552 -0.5301513671875 +58553 -0.214691162109375 +58554 0.137359619140625 +58555 0.474822998046875 +58556 0.76239013671875 +58557 0.867462158203125 +58558 0.870361328125 +58559 0.86480712890625 +58560 0.831817626953125 +58561 0.677581787109375 +58562 0.495880126953125 +58563 0.30767822265625 +58564 0.116180419921875 +58565 -0.110748291015625 +58566 -0.381805419921875 +58567 -0.6572265625 +58568 -0.857421875 +58569 -0.870391845703125 +58570 -0.870391845703125 +58571 -0.86444091796875 +58572 -0.85723876953125 +58573 -0.790008544921875 +58574 -0.62847900390625 +58575 -0.3956298828125 +58576 -0.126708984375 +58577 0.150115966796875 +58578 0.424041748046875 +58579 0.670623779296875 +58580 0.854522705078125 +58581 0.866485595703125 +58582 0.86920166015625 +58583 0.8653564453125 +58584 0.857147216796875 +58585 0.766845703125 +58586 0.628509521484375 +58587 0.462127685546875 +58588 0.297210693359375 +58589 0.14862060546875 +58590 -0.00537109375 +58591 -0.15753173828125 +58592 -0.31304931640625 +58593 -0.48876953125 +58594 -0.6416015625 +58595 -0.751373291015625 +58596 -0.84619140625 +58597 -0.861297607421875 +58598 -0.863250732421875 +58599 -0.856597900390625 +58600 -0.7498779296875 +58601 -0.624542236328125 +58602 -0.47808837890625 +58603 -0.253387451171875 +58604 0.003692626953125 +58605 0.2257080078125 +58606 0.427154541015625 +58607 0.643218994140625 +58608 0.855926513671875 +58609 0.870361328125 +58610 0.870361328125 +58611 0.862762451171875 +58612 0.79669189453125 +58613 0.595794677734375 +58614 0.362152099609375 +58615 0.1270751953125 +58616 -0.086944580078125 +58617 -0.2784423828125 +58618 -0.484832763671875 +58619 -0.729583740234375 +58620 -0.86688232421875 +58621 -0.870391845703125 +58622 -0.86859130859375 +58623 -0.86279296875 +58624 -0.817962646484375 +58625 -0.6116943359375 +58626 -0.3128662109375 +58627 0.039398193359375 +58628 0.422821044921875 +58629 0.805145263671875 +58630 0.870361328125 +58631 0.870361328125 +58632 0.860015869140625 +58633 0.727935791015625 +58634 0.48114013671875 +58635 0.2059326171875 +58636 -0.06103515625 +58637 -0.29913330078125 +58638 -0.516204833984375 +58639 -0.7252197265625 +58640 -0.85980224609375 +58641 -0.870391845703125 +58642 -0.870391845703125 +58643 -0.858062744140625 +58644 -0.673004150390625 +58645 -0.42694091796875 +58646 -0.2100830078125 +58647 -0.0362548828125 +58648 0.10943603515625 +58649 0.23516845703125 +58650 0.373687744140625 +58651 0.517791748046875 +58652 0.602783203125 +58653 0.635711669921875 +58654 0.655181884765625 +58655 0.65948486328125 +58656 0.651275634765625 +58657 0.61846923828125 +58658 0.53753662109375 +58659 0.404144287109375 +58660 0.22186279296875 +58661 0.003997802734375 +58662 -0.22100830078125 +58663 -0.42449951171875 +58664 -0.579833984375 +58665 -0.641876220703125 +58666 -0.6177978515625 +58667 -0.575531005859375 +58668 -0.526336669921875 +58669 -0.42645263671875 +58670 -0.2581787109375 +58671 -0.068695068359375 +58672 0.09222412109375 +58673 0.232147216796875 +58674 0.3509521484375 +58675 0.410064697265625 +58676 0.372955322265625 +58677 0.2554931640625 +58678 0.10711669921875 +58679 -0.052886962890625 +58680 -0.186279296875 +58681 -0.23291015625 +58682 -0.209442138671875 +58683 -0.174163818359375 +58684 -0.126739501953125 +58685 -0.048126220703125 +58686 0.0426025390625 +58687 0.10748291015625 +58688 0.1409912109375 +58689 0.19708251953125 +58690 0.273651123046875 +58691 0.31768798828125 +58692 0.341094970703125 +58693 0.368011474609375 +58694 0.37249755859375 +58695 0.30072021484375 +58696 0.1517333984375 +58697 -0.01470947265625 +58698 -0.1883544921875 +58699 -0.372711181640625 +58700 -0.51397705078125 +58701 -0.57177734375 +58702 -0.53948974609375 +58703 -0.43511962890625 +58704 -0.2962646484375 +58705 -0.161102294921875 +58706 -0.0435791015625 +58707 0.060394287109375 +58708 0.13665771484375 +58709 0.170135498046875 +58710 0.16552734375 +58711 0.15728759765625 +58712 0.150787353515625 +58713 0.12200927734375 +58714 0.080108642578125 +58715 0.05126953125 +58716 0.062896728515625 +58717 0.09271240234375 +58718 0.092987060546875 +58719 0.07855224609375 +58720 0.06427001953125 +58721 0.0347900390625 +58722 -0.01171875 +58723 -0.056060791015625 +58724 -0.055511474609375 +58725 -0.010467529296875 +58726 0.02508544921875 +58727 0.025665283203125 +58728 0.017333984375 +58729 0.00189208984375 +58730 -0.03173828125 +58731 -0.071502685546875 +58732 -0.13543701171875 +58733 -0.219970703125 +58734 -0.300506591796875 +58735 -0.376312255859375 +58736 -0.416107177734375 +58737 -0.371124267578125 +58738 -0.242279052734375 +58739 -0.069732666015625 +58740 0.125640869140625 +58741 0.31268310546875 +58742 0.45501708984375 +58743 0.554779052734375 +58744 0.61065673828125 +58745 0.610931396484375 +58746 0.531463623046875 +58747 0.3883056640625 +58748 0.23468017578125 +58749 0.095245361328125 +58750 -0.00396728515625 +58751 -0.04852294921875 +58752 -0.055145263671875 +58753 -0.0758056640625 +58754 -0.138702392578125 +58755 -0.209197998046875 +58756 -0.289031982421875 +58757 -0.37884521484375 +58758 -0.456329345703125 +58759 -0.51641845703125 +58760 -0.519287109375 +58761 -0.458251953125 +58762 -0.384796142578125 +58763 -0.323699951171875 +58764 -0.269287109375 +58765 -0.1951904296875 +58766 -0.100006103515625 +58767 -0.01055908203125 +58768 0.1033935546875 +58769 0.24908447265625 +58770 0.373199462890625 +58771 0.45806884765625 +58772 0.511474609375 +58773 0.565399169921875 +58774 0.61138916015625 +58775 0.5897216796875 +58776 0.4906005859375 +58777 0.33148193359375 +58778 0.147796630859375 +58779 -0.01873779296875 +58780 -0.140289306640625 +58781 -0.191986083984375 +58782 -0.184295654296875 +58783 -0.161834716796875 +58784 -0.166595458984375 +58785 -0.19390869140625 +58786 -0.22442626953125 +58787 -0.279754638671875 +58788 -0.3389892578125 +58789 -0.3543701171875 +58790 -0.348175048828125 +58791 -0.32598876953125 +58792 -0.2581787109375 +58793 -0.139801025390625 +58794 0.014617919921875 +58795 0.144378662109375 +58796 0.221038818359375 +58797 0.27069091796875 +58798 0.294036865234375 +58799 0.311767578125 +58800 0.339141845703125 +58801 0.360260009765625 +58802 0.360504150390625 +58803 0.308380126953125 +58804 0.18170166015625 +58805 0.0047607421875 +58806 -0.17559814453125 +58807 -0.3143310546875 +58808 -0.36785888671875 +58809 -0.36248779296875 +58810 -0.343536376953125 +58811 -0.3018798828125 +58812 -0.231414794921875 +58813 -0.117645263671875 +58814 0.007049560546875 +58815 0.087982177734375 +58816 0.13946533203125 +58817 0.17425537109375 +58818 0.188201904296875 +58819 0.171234130859375 +58820 0.118438720703125 +58821 0.05706787109375 +58822 -0.010711669921875 +58823 -0.0914306640625 +58824 -0.162322998046875 +58825 -0.194549560546875 +58826 -0.1492919921875 +58827 -0.02166748046875 +58828 0.124053955078125 +58829 0.211151123046875 +58830 0.240447998046875 +58831 0.242218017578125 +58832 0.2257080078125 +58833 0.194366455078125 +58834 0.115509033203125 +58835 0.0128173828125 +58836 -0.053802490234375 +58837 -0.110626220703125 +58838 -0.199493408203125 +58839 -0.29437255859375 +58840 -0.33221435546875 +58841 -0.27972412109375 +58842 -0.185333251953125 +58843 -0.128204345703125 +58844 -0.115692138671875 +58845 -0.116455078125 +58846 -0.105926513671875 +58847 -0.053955078125 +58848 0.048797607421875 +58849 0.157318115234375 +58850 0.212005615234375 +58851 0.218475341796875 +58852 0.23724365234375 +58853 0.30535888671875 +58854 0.38128662109375 +58855 0.404449462890625 +58856 0.3944091796875 +58857 0.3885498046875 +58858 0.362640380859375 +58859 0.27362060546875 +58860 0.11712646484375 +58861 -0.054901123046875 +58862 -0.19085693359375 +58863 -0.28570556640625 +58864 -0.339263916015625 +58865 -0.3775634765625 +58866 -0.445709228515625 +58867 -0.535064697265625 +58868 -0.629058837890625 +58869 -0.697601318359375 +58870 -0.70391845703125 +58871 -0.6424560546875 +58872 -0.491241455078125 +58873 -0.265716552734375 +58874 -0.023712158203125 +58875 0.201751708984375 +58876 0.375823974609375 +58877 0.485076904296875 +58878 0.56884765625 +58879 0.634765625 +58880 0.63763427734375 +58881 0.5660400390625 +58882 0.4720458984375 +58883 0.40692138671875 +58884 0.3778076171875 +58885 0.376953125 +58886 0.371978759765625 +58887 0.313140869140625 +58888 0.184417724609375 +58889 0.011199951171875 +58890 -0.171051025390625 +58891 -0.33740234375 +58892 -0.47198486328125 +58893 -0.560394287109375 +58894 -0.58056640625 +58895 -0.54754638671875 +58896 -0.508575439453125 +58897 -0.459503173828125 +58898 -0.394378662109375 +58899 -0.35260009765625 +58900 -0.31170654296875 +58901 -0.197418212890625 +58902 -0.007965087890625 +58903 0.207489013671875 +58904 0.409210205078125 +58905 0.57208251953125 +58906 0.66595458984375 +58907 0.65875244140625 +58908 0.56744384765625 +58909 0.431396484375 +58910 0.29443359375 +58911 0.182464599609375 +58912 0.06365966796875 +58913 -0.075958251953125 +58914 -0.189422607421875 +58915 -0.271942138671875 +58916 -0.342529296875 +58917 -0.364166259765625 +58918 -0.327239990234375 +58919 -0.2769775390625 +58920 -0.253692626953125 +58921 -0.24365234375 +58922 -0.1983642578125 +58923 -0.116241455078125 +58924 -0.036834716796875 +58925 0.034881591796875 +58926 0.09124755859375 +58927 0.10888671875 +58928 0.125518798828125 +58929 0.15771484375 +58930 0.17828369140625 +58931 0.17108154296875 +58932 0.129974365234375 +58933 0.082427978515625 +58934 0.027679443359375 +58935 -0.065643310546875 +58936 -0.15936279296875 +58937 -0.21307373046875 +58938 -0.234649658203125 +58939 -0.2001953125 +58940 -0.119171142578125 +58941 -0.024749755859375 +58942 0.085784912109375 +58943 0.178131103515625 +58944 0.215576171875 +58945 0.211456298828125 +58946 0.17523193359375 +58947 0.128753662109375 +58948 0.1019287109375 +58949 0.0743408203125 +58950 0.04327392578125 +58951 0.038177490234375 +58952 0.076263427734375 +58953 0.14105224609375 +58954 0.186431884765625 +58955 0.188812255859375 +58956 0.1390380859375 +58957 0.041778564453125 +58958 -0.079437255859375 +58959 -0.219390869140625 +58960 -0.367828369140625 +58961 -0.494873046875 +58962 -0.556243896484375 +58963 -0.508697509765625 +58964 -0.3756103515625 +58965 -0.218902587890625 +58966 -0.063751220703125 +58967 0.091552734375 +58968 0.23602294921875 +58969 0.342987060546875 +58970 0.39520263671875 +58971 0.389373779296875 +58972 0.324249267578125 +58973 0.224090576171875 +58974 0.124267578125 +58975 0.037078857421875 +58976 -0.010101318359375 +58977 -0.019439697265625 +58978 -0.022796630859375 +58979 -0.001556396484375 +58980 0.056304931640625 +58981 0.106719970703125 +58982 0.096893310546875 +58983 0.042694091796875 +58984 -0.018035888671875 +58985 -0.07586669921875 +58986 -0.11944580078125 +58987 -0.15972900390625 +58988 -0.202606201171875 +58989 -0.24859619140625 +58990 -0.30517578125 +58991 -0.36212158203125 +58992 -0.39141845703125 +58993 -0.35528564453125 +58994 -0.249969482421875 +58995 -0.092864990234375 +58996 0.08905029296875 +58997 0.2352294921875 +58998 0.318817138671875 +58999 0.358642578125 +59000 0.347747802734375 +59001 0.28564453125 +59002 0.223175048828125 +59003 0.196746826171875 +59004 0.179840087890625 +59005 0.155548095703125 +59006 0.151214599609375 +59007 0.156951904296875 +59008 0.13177490234375 +59009 0.100799560546875 +59010 0.087127685546875 +59011 0.05487060546875 +59012 -0.009002685546875 +59013 -0.10400390625 +59014 -0.229400634765625 +59015 -0.35552978515625 +59016 -0.441925048828125 +59017 -0.473846435546875 +59018 -0.464813232421875 +59019 -0.419097900390625 +59020 -0.334320068359375 +59021 -0.227935791015625 +59022 -0.12347412109375 +59023 -0.02764892578125 +59024 0.077667236328125 +59025 0.2132568359375 +59026 0.38885498046875 +59027 0.582794189453125 +59028 0.734039306640625 +59029 0.800140380859375 +59030 0.7783203125 +59031 0.6651611328125 +59032 0.45965576171875 +59033 0.199188232421875 +59034 -0.050689697265625 +59035 -0.23297119140625 +59036 -0.33013916015625 +59037 -0.368408203125 +59038 -0.378936767578125 +59039 -0.376983642578125 +59040 -0.37969970703125 +59041 -0.391510009765625 +59042 -0.385345458984375 +59043 -0.3419189453125 +59044 -0.28289794921875 +59045 -0.251617431640625 +59046 -0.266143798828125 +59047 -0.273345947265625 +59048 -0.216796875 +59049 -0.128265380859375 +59050 -0.068145751953125 +59051 -0.0430908203125 +59052 -0.024444580078125 +59053 0.020721435546875 +59054 0.124481201171875 +59055 0.25787353515625 +59056 0.379119873046875 +59057 0.47991943359375 +59058 0.5281982421875 +59059 0.511138916015625 +59060 0.456207275390625 +59061 0.407470703125 +59062 0.383758544921875 +59063 0.35687255859375 +59064 0.31182861328125 +59065 0.250885009765625 +59066 0.1654052734375 +59067 0.035247802734375 +59068 -0.142059326171875 +59069 -0.33563232421875 +59070 -0.5345458984375 +59071 -0.72186279296875 +59072 -0.836669921875 +59073 -0.8326416015625 +59074 -0.7296142578125 +59075 -0.582550048828125 +59076 -0.440093994140625 +59077 -0.324310302734375 +59078 -0.20147705078125 +59079 -0.044647216796875 +59080 0.103973388671875 +59081 0.202392578125 +59082 0.264495849609375 +59083 0.338897705078125 +59084 0.443817138671875 +59085 0.545074462890625 +59086 0.6173095703125 +59087 0.6524658203125 +59088 0.66339111328125 +59089 0.6561279296875 +59090 0.606781005859375 +59091 0.501190185546875 +59092 0.352783203125 +59093 0.176544189453125 +59094 -0.034820556640625 +59095 -0.258209228515625 +59096 -0.44244384765625 +59097 -0.5753173828125 +59098 -0.65203857421875 +59099 -0.641632080078125 +59100 -0.562164306640625 +59101 -0.458038330078125 +59102 -0.350555419921875 +59103 -0.260528564453125 +59104 -0.192108154296875 +59105 -0.141937255859375 +59106 -0.1021728515625 +59107 -0.062896728515625 +59108 -0.011932373046875 +59109 0.062835693359375 +59110 0.148712158203125 +59111 0.241729736328125 +59112 0.34912109375 +59113 0.457305908203125 +59114 0.54388427734375 +59115 0.5728759765625 +59116 0.506591796875 +59117 0.351226806640625 +59118 0.146514892578125 +59119 -0.05523681640625 +59120 -0.21624755859375 +59121 -0.334930419921875 +59122 -0.402984619140625 +59123 -0.4412841796875 +59124 -0.49578857421875 +59125 -0.5601806640625 +59126 -0.600738525390625 +59127 -0.584228515625 +59128 -0.47930908203125 +59129 -0.27935791015625 +59130 -0.0089111328125 +59131 0.268798828125 +59132 0.482818603515625 +59133 0.60369873046875 +59134 0.650421142578125 +59135 0.66400146484375 +59136 0.6414794921875 +59137 0.572540283203125 +59138 0.498138427734375 +59139 0.439453125 +59140 0.375518798828125 +59141 0.274505615234375 +59142 0.1087646484375 +59143 -0.099395751953125 +59144 -0.3182373046875 +59145 -0.5489501953125 +59146 -0.7738037109375 +59147 -0.86383056640625 +59148 -0.870391845703125 +59149 -0.86895751953125 +59150 -0.861053466796875 +59151 -0.765869140625 +59152 -0.5301513671875 +59153 -0.214691162109375 +59154 0.137359619140625 +59155 0.474822998046875 +59156 0.76239013671875 +59157 0.867462158203125 +59158 0.870361328125 +59159 0.86480712890625 +59160 0.831817626953125 +59161 0.677581787109375 +59162 0.495880126953125 +59163 0.30767822265625 +59164 0.116180419921875 +59165 -0.110748291015625 +59166 -0.381805419921875 +59167 -0.6572265625 +59168 -0.857421875 +59169 -0.870391845703125 +59170 -0.870391845703125 +59171 -0.86444091796875 +59172 -0.85723876953125 +59173 -0.790008544921875 +59174 -0.62847900390625 +59175 -0.3956298828125 +59176 -0.126708984375 +59177 0.150115966796875 +59178 0.424041748046875 +59179 0.670623779296875 +59180 0.854522705078125 +59181 0.866485595703125 +59182 0.86920166015625 +59183 0.8653564453125 +59184 0.857147216796875 +59185 0.766845703125 +59186 0.628509521484375 +59187 0.462127685546875 +59188 0.297210693359375 +59189 0.14862060546875 +59190 -0.00537109375 +59191 -0.15753173828125 +59192 -0.31304931640625 +59193 -0.48876953125 +59194 -0.6416015625 +59195 -0.751373291015625 +59196 -0.84619140625 +59197 -0.861297607421875 +59198 -0.863250732421875 +59199 -0.856597900390625 +59200 -0.7498779296875 +59201 -0.624542236328125 +59202 -0.47808837890625 +59203 -0.253387451171875 +59204 0.003692626953125 +59205 0.2257080078125 +59206 0.427154541015625 +59207 0.643218994140625 +59208 0.855926513671875 +59209 0.870361328125 +59210 0.870361328125 +59211 0.862762451171875 +59212 0.79669189453125 +59213 0.595794677734375 +59214 0.362152099609375 +59215 0.1270751953125 +59216 -0.086944580078125 +59217 -0.2784423828125 +59218 -0.484832763671875 +59219 -0.729583740234375 +59220 -0.86688232421875 +59221 -0.870391845703125 +59222 -0.86859130859375 +59223 -0.86279296875 +59224 -0.817962646484375 +59225 -0.6116943359375 +59226 -0.3128662109375 +59227 0.039398193359375 +59228 0.422821044921875 +59229 0.805145263671875 +59230 0.870361328125 +59231 0.870361328125 +59232 0.860015869140625 +59233 0.727935791015625 +59234 0.48114013671875 +59235 0.2059326171875 +59236 -0.06103515625 +59237 -0.29913330078125 +59238 -0.516204833984375 +59239 -0.7252197265625 +59240 -0.85980224609375 +59241 -0.870391845703125 +59242 -0.870391845703125 +59243 -0.858062744140625 +59244 -0.673004150390625 +59245 -0.42694091796875 +59246 -0.2100830078125 +59247 -0.0362548828125 +59248 0.10943603515625 +59249 0.23516845703125 +59250 0.373687744140625 +59251 0.517791748046875 +59252 0.602783203125 +59253 0.635711669921875 +59254 0.655181884765625 +59255 0.65948486328125 +59256 0.651275634765625 +59257 0.61846923828125 +59258 0.53753662109375 +59259 0.404144287109375 +59260 0.22186279296875 +59261 0.003997802734375 +59262 -0.22100830078125 +59263 -0.42449951171875 +59264 -0.579833984375 +59265 -0.641876220703125 +59266 -0.6177978515625 +59267 -0.575531005859375 +59268 -0.526336669921875 +59269 -0.42645263671875 +59270 -0.2581787109375 +59271 -0.068695068359375 +59272 0.09222412109375 +59273 0.232147216796875 +59274 0.3509521484375 +59275 0.410064697265625 +59276 0.372955322265625 +59277 0.2554931640625 +59278 0.10711669921875 +59279 -0.052886962890625 +59280 -0.186279296875 +59281 -0.23291015625 +59282 -0.209442138671875 +59283 -0.174163818359375 +59284 -0.126739501953125 +59285 -0.048126220703125 +59286 0.0426025390625 +59287 0.10748291015625 +59288 0.1409912109375 +59289 0.19708251953125 +59290 0.273651123046875 +59291 0.31768798828125 +59292 0.341094970703125 +59293 0.368011474609375 +59294 0.37249755859375 +59295 0.30072021484375 +59296 0.1517333984375 +59297 -0.01470947265625 +59298 -0.1883544921875 +59299 -0.372711181640625 +59300 -0.51397705078125 +59301 -0.57177734375 +59302 -0.53948974609375 +59303 -0.43511962890625 +59304 -0.2962646484375 +59305 -0.161102294921875 +59306 -0.0435791015625 +59307 0.060394287109375 +59308 0.13665771484375 +59309 0.170135498046875 +59310 0.16552734375 +59311 0.15728759765625 +59312 0.150787353515625 +59313 0.12200927734375 +59314 0.080108642578125 +59315 0.05126953125 +59316 0.062896728515625 +59317 0.09271240234375 +59318 0.092987060546875 +59319 0.07855224609375 +59320 0.06427001953125 +59321 0.0347900390625 +59322 -0.01171875 +59323 -0.056060791015625 +59324 -0.055511474609375 +59325 -0.010467529296875 +59326 0.02508544921875 +59327 0.025665283203125 +59328 0.017333984375 +59329 0.00189208984375 +59330 -0.03173828125 +59331 -0.071502685546875 +59332 -0.13543701171875 +59333 -0.219970703125 +59334 -0.300506591796875 +59335 -0.376312255859375 +59336 -0.416107177734375 +59337 -0.371124267578125 +59338 -0.242279052734375 +59339 -0.069732666015625 +59340 0.125640869140625 +59341 0.31268310546875 +59342 0.45501708984375 +59343 0.554779052734375 +59344 0.61065673828125 +59345 0.610931396484375 +59346 0.531463623046875 +59347 0.3883056640625 +59348 0.23468017578125 +59349 0.095245361328125 +59350 -0.00396728515625 +59351 -0.04852294921875 +59352 -0.055145263671875 +59353 -0.0758056640625 +59354 -0.138702392578125 +59355 -0.209197998046875 +59356 -0.289031982421875 +59357 -0.37884521484375 +59358 -0.456329345703125 +59359 -0.51641845703125 +59360 -0.519287109375 +59361 -0.458251953125 +59362 -0.384796142578125 +59363 -0.323699951171875 +59364 -0.269287109375 +59365 -0.1951904296875 +59366 -0.100006103515625 +59367 -0.01055908203125 +59368 0.1033935546875 +59369 0.24908447265625 +59370 0.373199462890625 +59371 0.45806884765625 +59372 0.511474609375 +59373 0.565399169921875 +59374 0.61138916015625 +59375 0.5897216796875 +59376 0.4906005859375 +59377 0.33148193359375 +59378 0.147796630859375 +59379 -0.01873779296875 +59380 -0.140289306640625 +59381 -0.191986083984375 +59382 -0.184295654296875 +59383 -0.161834716796875 +59384 -0.166595458984375 +59385 -0.19390869140625 +59386 -0.22442626953125 +59387 -0.279754638671875 +59388 -0.3389892578125 +59389 -0.3543701171875 +59390 -0.348175048828125 +59391 -0.32598876953125 +59392 -0.2581787109375 +59393 -0.139801025390625 +59394 0.014617919921875 +59395 0.144378662109375 +59396 0.221038818359375 +59397 0.27069091796875 +59398 0.294036865234375 +59399 0.311767578125 +59400 0.339141845703125 +59401 0.360260009765625 +59402 0.360504150390625 +59403 0.308380126953125 +59404 0.18170166015625 +59405 0.0047607421875 +59406 -0.17559814453125 +59407 -0.3143310546875 +59408 -0.36785888671875 +59409 -0.36248779296875 +59410 -0.343536376953125 +59411 -0.3018798828125 +59412 -0.231414794921875 +59413 -0.117645263671875 +59414 0.007049560546875 +59415 0.087982177734375 +59416 0.13946533203125 +59417 0.17425537109375 +59418 0.188201904296875 +59419 0.171234130859375 +59420 0.118438720703125 +59421 0.05706787109375 +59422 -0.010711669921875 +59423 -0.0914306640625 +59424 -0.162322998046875 +59425 -0.194549560546875 +59426 -0.1492919921875 +59427 -0.02166748046875 +59428 0.124053955078125 +59429 0.211151123046875 +59430 0.240447998046875 +59431 0.242218017578125 +59432 0.2257080078125 +59433 0.194366455078125 +59434 0.115509033203125 +59435 0.0128173828125 +59436 -0.053802490234375 +59437 -0.110626220703125 +59438 -0.199493408203125 +59439 -0.29437255859375 +59440 -0.33221435546875 +59441 -0.27972412109375 +59442 -0.185333251953125 +59443 -0.128204345703125 +59444 -0.115692138671875 +59445 -0.116455078125 +59446 -0.105926513671875 +59447 -0.053955078125 +59448 0.048797607421875 +59449 0.157318115234375 +59450 0.212005615234375 +59451 0.218475341796875 +59452 0.23724365234375 +59453 0.30535888671875 +59454 0.38128662109375 +59455 0.404449462890625 +59456 0.3944091796875 +59457 0.3885498046875 +59458 0.362640380859375 +59459 0.27362060546875 +59460 0.11712646484375 +59461 -0.054901123046875 +59462 -0.19085693359375 +59463 -0.28570556640625 +59464 -0.339263916015625 +59465 -0.3775634765625 +59466 -0.445709228515625 +59467 -0.535064697265625 +59468 -0.629058837890625 +59469 -0.697601318359375 +59470 -0.70391845703125 +59471 -0.6424560546875 +59472 -0.491241455078125 +59473 -0.265716552734375 +59474 -0.023712158203125 +59475 0.201751708984375 +59476 0.375823974609375 +59477 0.485076904296875 +59478 0.56884765625 +59479 0.634765625 +59480 0.63763427734375 +59481 0.5660400390625 +59482 0.4720458984375 +59483 0.40692138671875 +59484 0.3778076171875 +59485 0.376953125 +59486 0.371978759765625 +59487 0.313140869140625 +59488 0.184417724609375 +59489 0.011199951171875 +59490 -0.171051025390625 +59491 -0.33740234375 +59492 -0.47198486328125 +59493 -0.560394287109375 +59494 -0.58056640625 +59495 -0.54754638671875 +59496 -0.508575439453125 +59497 -0.459503173828125 +59498 -0.394378662109375 +59499 -0.35260009765625 +59500 -0.31170654296875 +59501 -0.197418212890625 +59502 -0.007965087890625 +59503 0.207489013671875 +59504 0.409210205078125 +59505 0.57208251953125 +59506 0.66595458984375 +59507 0.65875244140625 +59508 0.56744384765625 +59509 0.431396484375 +59510 0.29443359375 +59511 0.182464599609375 +59512 0.06365966796875 +59513 -0.075958251953125 +59514 -0.189422607421875 +59515 -0.271942138671875 +59516 -0.342529296875 +59517 -0.364166259765625 +59518 -0.327239990234375 +59519 -0.2769775390625 +59520 -0.253692626953125 +59521 -0.24365234375 +59522 -0.1983642578125 +59523 -0.116241455078125 +59524 -0.036834716796875 +59525 0.034881591796875 +59526 0.09124755859375 +59527 0.10888671875 +59528 0.125518798828125 +59529 0.15771484375 +59530 0.17828369140625 +59531 0.17108154296875 +59532 0.129974365234375 +59533 0.082427978515625 +59534 0.027679443359375 +59535 -0.065643310546875 +59536 -0.15936279296875 +59537 -0.21307373046875 +59538 -0.234649658203125 +59539 -0.2001953125 +59540 -0.119171142578125 +59541 -0.024749755859375 +59542 0.085784912109375 +59543 0.178131103515625 +59544 0.215576171875 +59545 0.211456298828125 +59546 0.17523193359375 +59547 0.128753662109375 +59548 0.1019287109375 +59549 0.0743408203125 +59550 0.04327392578125 +59551 0.038177490234375 +59552 0.076263427734375 +59553 0.14105224609375 +59554 0.186431884765625 +59555 0.188812255859375 +59556 0.1390380859375 +59557 0.041778564453125 +59558 -0.079437255859375 +59559 -0.219390869140625 +59560 -0.367828369140625 +59561 -0.494873046875 +59562 -0.556243896484375 +59563 -0.508697509765625 +59564 -0.3756103515625 +59565 -0.218902587890625 +59566 -0.063751220703125 +59567 0.091552734375 +59568 0.23602294921875 +59569 0.342987060546875 +59570 0.39520263671875 +59571 0.389373779296875 +59572 0.324249267578125 +59573 0.224090576171875 +59574 0.124267578125 +59575 0.037078857421875 +59576 -0.010101318359375 +59577 -0.019439697265625 +59578 -0.022796630859375 +59579 -0.001556396484375 +59580 0.056304931640625 +59581 0.106719970703125 +59582 0.096893310546875 +59583 0.042694091796875 +59584 -0.018035888671875 +59585 -0.07586669921875 +59586 -0.11944580078125 +59587 -0.15972900390625 +59588 -0.202606201171875 +59589 -0.24859619140625 +59590 -0.30517578125 +59591 -0.36212158203125 +59592 -0.39141845703125 +59593 -0.35528564453125 +59594 -0.249969482421875 +59595 -0.092864990234375 +59596 0.08905029296875 +59597 0.2352294921875 +59598 0.318817138671875 +59599 0.358642578125 +59600 0.347747802734375 +59601 0.28564453125 +59602 0.223175048828125 +59603 0.196746826171875 +59604 0.179840087890625 +59605 0.155548095703125 +59606 0.151214599609375 +59607 0.156951904296875 +59608 0.13177490234375 +59609 0.100799560546875 +59610 0.087127685546875 +59611 0.05487060546875 +59612 -0.009002685546875 +59613 -0.10400390625 +59614 -0.229400634765625 +59615 -0.35552978515625 +59616 -0.441925048828125 +59617 -0.473846435546875 +59618 -0.464813232421875 +59619 -0.419097900390625 +59620 -0.334320068359375 +59621 -0.227935791015625 +59622 -0.12347412109375 +59623 -0.02764892578125 +59624 0.077667236328125 +59625 0.2132568359375 +59626 0.38885498046875 +59627 0.582794189453125 +59628 0.734039306640625 +59629 0.800140380859375 +59630 0.7783203125 +59631 0.6651611328125 +59632 0.45965576171875 +59633 0.199188232421875 +59634 -0.050689697265625 +59635 -0.23297119140625 +59636 -0.33013916015625 +59637 -0.368408203125 +59638 -0.378936767578125 +59639 -0.376983642578125 +59640 -0.37969970703125 +59641 -0.391510009765625 +59642 -0.385345458984375 +59643 -0.3419189453125 +59644 -0.28289794921875 +59645 -0.251617431640625 +59646 -0.266143798828125 +59647 -0.273345947265625 +59648 -0.216796875 +59649 -0.128265380859375 +59650 -0.068145751953125 +59651 -0.0430908203125 +59652 -0.024444580078125 +59653 0.020721435546875 +59654 0.124481201171875 +59655 0.25787353515625 +59656 0.379119873046875 +59657 0.47991943359375 +59658 0.5281982421875 +59659 0.511138916015625 +59660 0.456207275390625 +59661 0.407470703125 +59662 0.383758544921875 +59663 0.35687255859375 +59664 0.31182861328125 +59665 0.250885009765625 +59666 0.1654052734375 +59667 0.035247802734375 +59668 -0.142059326171875 +59669 -0.33563232421875 +59670 -0.5345458984375 +59671 -0.72186279296875 +59672 -0.836669921875 +59673 -0.8326416015625 +59674 -0.7296142578125 +59675 -0.582550048828125 +59676 -0.440093994140625 +59677 -0.324310302734375 +59678 -0.20147705078125 +59679 -0.044647216796875 +59680 0.103973388671875 +59681 0.202392578125 +59682 0.264495849609375 +59683 0.338897705078125 +59684 0.443817138671875 +59685 0.545074462890625 +59686 0.6173095703125 +59687 0.6524658203125 +59688 0.66339111328125 +59689 0.6561279296875 +59690 0.606781005859375 +59691 0.501190185546875 +59692 0.352783203125 +59693 0.176544189453125 +59694 -0.034820556640625 +59695 -0.258209228515625 +59696 -0.44244384765625 +59697 -0.5753173828125 +59698 -0.65203857421875 +59699 -0.641632080078125 +59700 -0.562164306640625 +59701 -0.458038330078125 +59702 -0.350555419921875 +59703 -0.260528564453125 +59704 -0.192108154296875 +59705 -0.141937255859375 +59706 -0.1021728515625 +59707 -0.062896728515625 +59708 -0.011932373046875 +59709 0.062835693359375 +59710 0.148712158203125 +59711 0.241729736328125 +59712 0.34912109375 +59713 0.457305908203125 +59714 0.54388427734375 +59715 0.5728759765625 +59716 0.506591796875 +59717 0.351226806640625 +59718 0.146514892578125 +59719 -0.05523681640625 +59720 -0.21624755859375 +59721 -0.334930419921875 +59722 -0.402984619140625 +59723 -0.4412841796875 +59724 -0.49578857421875 +59725 -0.5601806640625 +59726 -0.600738525390625 +59727 -0.584228515625 +59728 -0.47930908203125 +59729 -0.27935791015625 +59730 -0.0089111328125 +59731 0.268798828125 +59732 0.482818603515625 +59733 0.60369873046875 +59734 0.650421142578125 +59735 0.66400146484375 +59736 0.6414794921875 +59737 0.572540283203125 +59738 0.498138427734375 +59739 0.439453125 +59740 0.375518798828125 +59741 0.274505615234375 +59742 0.1087646484375 +59743 -0.099395751953125 +59744 -0.3182373046875 +59745 -0.5489501953125 +59746 -0.7738037109375 +59747 -0.86383056640625 +59748 -0.870391845703125 +59749 -0.86895751953125 +59750 -0.861053466796875 +59751 -0.765869140625 +59752 -0.5301513671875 +59753 -0.214691162109375 +59754 0.137359619140625 +59755 0.474822998046875 +59756 0.76239013671875 +59757 0.867462158203125 +59758 0.870361328125 +59759 0.86480712890625 +59760 0.831817626953125 +59761 0.677581787109375 +59762 0.495880126953125 +59763 0.30767822265625 +59764 0.116180419921875 +59765 -0.110748291015625 +59766 -0.381805419921875 +59767 -0.6572265625 +59768 -0.857421875 +59769 -0.870391845703125 +59770 -0.870391845703125 +59771 -0.86444091796875 +59772 -0.85723876953125 +59773 -0.790008544921875 +59774 -0.62847900390625 +59775 -0.3956298828125 +59776 -0.126708984375 +59777 0.150115966796875 +59778 0.424041748046875 +59779 0.670623779296875 +59780 0.854522705078125 +59781 0.866485595703125 +59782 0.86920166015625 +59783 0.8653564453125 +59784 0.857147216796875 +59785 0.766845703125 +59786 0.628509521484375 +59787 0.462127685546875 +59788 0.297210693359375 +59789 0.14862060546875 +59790 -0.00537109375 +59791 -0.15753173828125 +59792 -0.31304931640625 +59793 -0.48876953125 +59794 -0.6416015625 +59795 -0.751373291015625 +59796 -0.84619140625 +59797 -0.861297607421875 +59798 -0.863250732421875 +59799 -0.856597900390625 +59800 -0.7498779296875 +59801 -0.624542236328125 +59802 -0.47808837890625 +59803 -0.253387451171875 +59804 0.003692626953125 +59805 0.2257080078125 +59806 0.427154541015625 +59807 0.643218994140625 +59808 0.855926513671875 +59809 0.870361328125 +59810 0.870361328125 +59811 0.862762451171875 +59812 0.79669189453125 +59813 0.595794677734375 +59814 0.362152099609375 +59815 0.1270751953125 +59816 -0.086944580078125 +59817 -0.2784423828125 +59818 -0.484832763671875 +59819 -0.729583740234375 +59820 -0.86688232421875 +59821 -0.870391845703125 +59822 -0.86859130859375 +59823 -0.86279296875 +59824 -0.817962646484375 +59825 -0.6116943359375 +59826 -0.3128662109375 +59827 0.039398193359375 +59828 0.422821044921875 +59829 0.805145263671875 +59830 0.870361328125 +59831 0.870361328125 +59832 0.860015869140625 +59833 0.727935791015625 +59834 0.48114013671875 +59835 0.2059326171875 +59836 -0.06103515625 +59837 -0.29913330078125 +59838 -0.516204833984375 +59839 -0.7252197265625 +59840 -0.85980224609375 +59841 -0.870391845703125 +59842 -0.870391845703125 +59843 -0.858062744140625 +59844 -0.673004150390625 +59845 -0.42694091796875 +59846 -0.2100830078125 +59847 -0.0362548828125 +59848 0.10943603515625 +59849 0.23516845703125 +59850 0.373687744140625 +59851 0.517791748046875 +59852 0.602783203125 +59853 0.635711669921875 +59854 0.655181884765625 +59855 0.65948486328125 +59856 0.651275634765625 +59857 0.61846923828125 +59858 0.53753662109375 +59859 0.404144287109375 +59860 0.22186279296875 +59861 0.003997802734375 +59862 -0.22100830078125 +59863 -0.42449951171875 +59864 -0.579833984375 +59865 -0.641876220703125 +59866 -0.6177978515625 +59867 -0.575531005859375 +59868 -0.526336669921875 +59869 -0.42645263671875 +59870 -0.2581787109375 +59871 -0.068695068359375 +59872 0.09222412109375 +59873 0.232147216796875 +59874 0.3509521484375 +59875 0.410064697265625 +59876 0.372955322265625 +59877 0.2554931640625 +59878 0.10711669921875 +59879 -0.052886962890625 +59880 -0.186279296875 +59881 -0.23291015625 +59882 -0.209442138671875 +59883 -0.174163818359375 +59884 -0.126739501953125 +59885 -0.048126220703125 +59886 0.0426025390625 +59887 0.10748291015625 +59888 0.1409912109375 +59889 0.19708251953125 +59890 0.273651123046875 +59891 0.31768798828125 +59892 0.341094970703125 +59893 0.368011474609375 +59894 0.37249755859375 +59895 0.30072021484375 +59896 0.1517333984375 +59897 -0.01470947265625 +59898 -0.1883544921875 +59899 -0.372711181640625 +59900 -0.51397705078125 +59901 -0.57177734375 +59902 -0.53948974609375 +59903 -0.43511962890625 +59904 -0.2962646484375 +59905 -0.161102294921875 +59906 -0.0435791015625 +59907 0.060394287109375 +59908 0.13665771484375 +59909 0.170135498046875 +59910 0.16552734375 +59911 0.15728759765625 +59912 0.150787353515625 +59913 0.12200927734375 +59914 0.080108642578125 +59915 0.05126953125 +59916 0.062896728515625 +59917 0.09271240234375 +59918 0.092987060546875 +59919 0.07855224609375 +59920 0.06427001953125 +59921 0.0347900390625 +59922 -0.01171875 +59923 -0.056060791015625 +59924 -0.055511474609375 +59925 -0.010467529296875 +59926 0.02508544921875 +59927 0.025665283203125 +59928 0.017333984375 +59929 0.00189208984375 +59930 -0.03173828125 +59931 -0.071502685546875 +59932 -0.13543701171875 +59933 -0.219970703125 +59934 -0.300506591796875 +59935 -0.376312255859375 +59936 -0.416107177734375 +59937 -0.371124267578125 +59938 -0.242279052734375 +59939 -0.069732666015625 +59940 0.125640869140625 +59941 0.31268310546875 +59942 0.45501708984375 +59943 0.554779052734375 +59944 0.61065673828125 +59945 0.610931396484375 +59946 0.531463623046875 +59947 0.3883056640625 +59948 0.23468017578125 +59949 0.095245361328125 +59950 -0.00396728515625 +59951 -0.04852294921875 +59952 -0.055145263671875 +59953 -0.0758056640625 +59954 -0.138702392578125 +59955 -0.209197998046875 +59956 -0.289031982421875 +59957 -0.37884521484375 +59958 -0.456329345703125 +59959 -0.51641845703125 +59960 -0.519287109375 +59961 -0.458251953125 +59962 -0.384796142578125 +59963 -0.323699951171875 +59964 -0.269287109375 +59965 -0.1951904296875 +59966 -0.100006103515625 +59967 -0.01055908203125 +59968 0.1033935546875 +59969 0.24908447265625 +59970 0.373199462890625 +59971 0.45806884765625 +59972 0.511474609375 +59973 0.565399169921875 +59974 0.61138916015625 +59975 0.5897216796875 +59976 0.4906005859375 +59977 0.33148193359375 +59978 0.147796630859375 +59979 -0.01873779296875 +59980 -0.140289306640625 +59981 -0.191986083984375 +59982 -0.184295654296875 +59983 -0.161834716796875 +59984 -0.166595458984375 +59985 -0.19390869140625 +59986 -0.22442626953125 +59987 -0.279754638671875 +59988 -0.3389892578125 +59989 -0.3543701171875 +59990 -0.348175048828125 +59991 -0.32598876953125 +59992 -0.2581787109375 +59993 -0.139801025390625 +59994 0.014617919921875 +59995 0.144378662109375 +59996 0.221038818359375 +59997 0.27069091796875 +59998 0.294036865234375 +59999 0.311767578125 +60000 0.339141845703125 +60001 0.360260009765625 +60002 0.360504150390625 +60003 0.308380126953125 +60004 0.18170166015625 +60005 0.0047607421875 +60006 -0.17559814453125 +60007 -0.3143310546875 +60008 -0.36785888671875 +60009 -0.36248779296875 +60010 -0.343536376953125 +60011 -0.3018798828125 +60012 -0.231414794921875 +60013 -0.117645263671875 +60014 0.007049560546875 +60015 0.087982177734375 +60016 0.13946533203125 +60017 0.17425537109375 +60018 0.188201904296875 +60019 0.171234130859375 +60020 0.118438720703125 +60021 0.05706787109375 +60022 -0.010711669921875 +60023 -0.0914306640625 +60024 -0.162322998046875 +60025 -0.194549560546875 +60026 -0.1492919921875 +60027 -0.02166748046875 +60028 0.124053955078125 +60029 0.211151123046875 +60030 0.240447998046875 +60031 0.242218017578125 +60032 0.2257080078125 +60033 0.194366455078125 +60034 0.115509033203125 +60035 0.0128173828125 +60036 -0.053802490234375 +60037 -0.110626220703125 +60038 -0.199493408203125 +60039 -0.29437255859375 +60040 -0.33221435546875 +60041 -0.27972412109375 +60042 -0.185333251953125 +60043 -0.128204345703125 +60044 -0.115692138671875 +60045 -0.116455078125 +60046 -0.105926513671875 +60047 -0.053955078125 +60048 0.048797607421875 +60049 0.157318115234375 +60050 0.212005615234375 +60051 0.218475341796875 +60052 0.23724365234375 +60053 0.30535888671875 +60054 0.38128662109375 +60055 0.404449462890625 +60056 0.3944091796875 +60057 0.3885498046875 +60058 0.362640380859375 +60059 0.27362060546875 +60060 0.11712646484375 +60061 -0.054901123046875 +60062 -0.19085693359375 +60063 -0.28570556640625 +60064 -0.339263916015625 +60065 -0.3775634765625 +60066 -0.445709228515625 +60067 -0.535064697265625 +60068 -0.629058837890625 +60069 -0.697601318359375 +60070 -0.70391845703125 +60071 -0.6424560546875 +60072 -0.491241455078125 +60073 -0.265716552734375 +60074 -0.023712158203125 +60075 0.201751708984375 +60076 0.375823974609375 +60077 0.485076904296875 +60078 0.56884765625 +60079 0.634765625 +60080 0.63763427734375 +60081 0.5660400390625 +60082 0.4720458984375 +60083 0.40692138671875 +60084 0.3778076171875 +60085 0.376953125 +60086 0.371978759765625 +60087 0.313140869140625 +60088 0.184417724609375 +60089 0.011199951171875 +60090 -0.171051025390625 +60091 -0.33740234375 +60092 -0.47198486328125 +60093 -0.560394287109375 +60094 -0.58056640625 +60095 -0.54754638671875 +60096 -0.508575439453125 +60097 -0.459503173828125 +60098 -0.394378662109375 +60099 -0.35260009765625 +60100 -0.31170654296875 +60101 -0.197418212890625 +60102 -0.007965087890625 +60103 0.207489013671875 +60104 0.409210205078125 +60105 0.57208251953125 +60106 0.66595458984375 +60107 0.65875244140625 +60108 0.56744384765625 +60109 0.431396484375 +60110 0.29443359375 +60111 0.182464599609375 +60112 0.06365966796875 +60113 -0.075958251953125 +60114 -0.189422607421875 +60115 -0.271942138671875 +60116 -0.342529296875 +60117 -0.364166259765625 +60118 -0.327239990234375 +60119 -0.2769775390625 +60120 -0.253692626953125 +60121 -0.24365234375 +60122 -0.1983642578125 +60123 -0.116241455078125 +60124 -0.036834716796875 +60125 0.034881591796875 +60126 0.09124755859375 +60127 0.10888671875 +60128 0.125518798828125 +60129 0.15771484375 +60130 0.17828369140625 +60131 0.17108154296875 +60132 0.129974365234375 +60133 0.082427978515625 +60134 0.027679443359375 +60135 -0.065643310546875 +60136 -0.15936279296875 +60137 -0.21307373046875 +60138 -0.234649658203125 +60139 -0.2001953125 +60140 -0.119171142578125 +60141 -0.024749755859375 +60142 0.085784912109375 +60143 0.178131103515625 +60144 0.215576171875 +60145 0.211456298828125 +60146 0.17523193359375 +60147 0.128753662109375 +60148 0.1019287109375 +60149 0.0743408203125 +60150 0.04327392578125 +60151 0.038177490234375 +60152 0.076263427734375 +60153 0.14105224609375 +60154 0.186431884765625 +60155 0.188812255859375 +60156 0.1390380859375 +60157 0.041778564453125 +60158 -0.079437255859375 +60159 -0.219390869140625 +60160 -0.367828369140625 +60161 -0.494873046875 +60162 -0.556243896484375 +60163 -0.508697509765625 +60164 -0.3756103515625 +60165 -0.218902587890625 +60166 -0.063751220703125 +60167 0.091552734375 +60168 0.23602294921875 +60169 0.342987060546875 +60170 0.39520263671875 +60171 0.389373779296875 +60172 0.324249267578125 +60173 0.224090576171875 +60174 0.124267578125 +60175 0.037078857421875 +60176 -0.010101318359375 +60177 -0.019439697265625 +60178 -0.022796630859375 +60179 -0.001556396484375 +60180 0.056304931640625 +60181 0.106719970703125 +60182 0.096893310546875 +60183 0.042694091796875 +60184 -0.018035888671875 +60185 -0.07586669921875 +60186 -0.11944580078125 +60187 -0.15972900390625 +60188 -0.202606201171875 +60189 -0.24859619140625 +60190 -0.30517578125 +60191 -0.36212158203125 +60192 -0.39141845703125 +60193 -0.35528564453125 +60194 -0.249969482421875 +60195 -0.092864990234375 +60196 0.08905029296875 +60197 0.2352294921875 +60198 0.318817138671875 +60199 0.358642578125 +60200 0.347747802734375 +60201 0.28564453125 +60202 0.223175048828125 +60203 0.196746826171875 +60204 0.179840087890625 +60205 0.155548095703125 +60206 0.151214599609375 +60207 0.156951904296875 +60208 0.13177490234375 +60209 0.100799560546875 +60210 0.087127685546875 +60211 0.05487060546875 +60212 -0.009002685546875 +60213 -0.10400390625 +60214 -0.229400634765625 +60215 -0.35552978515625 +60216 -0.441925048828125 +60217 -0.473846435546875 +60218 -0.464813232421875 +60219 -0.419097900390625 +60220 -0.334320068359375 +60221 -0.227935791015625 +60222 -0.12347412109375 +60223 -0.02764892578125 +60224 0.077667236328125 +60225 0.2132568359375 +60226 0.38885498046875 +60227 0.582794189453125 +60228 0.734039306640625 +60229 0.800140380859375 +60230 0.7783203125 +60231 0.6651611328125 +60232 0.45965576171875 +60233 0.199188232421875 +60234 -0.050689697265625 +60235 -0.23297119140625 +60236 -0.33013916015625 +60237 -0.368408203125 +60238 -0.378936767578125 +60239 -0.376983642578125 +60240 -0.37969970703125 +60241 -0.391510009765625 +60242 -0.385345458984375 +60243 -0.3419189453125 +60244 -0.28289794921875 +60245 -0.251617431640625 +60246 -0.266143798828125 +60247 -0.273345947265625 +60248 -0.216796875 +60249 -0.128265380859375 +60250 -0.068145751953125 +60251 -0.0430908203125 +60252 -0.024444580078125 +60253 0.020721435546875 +60254 0.124481201171875 +60255 0.25787353515625 +60256 0.379119873046875 +60257 0.47991943359375 +60258 0.5281982421875 +60259 0.511138916015625 +60260 0.456207275390625 +60261 0.407470703125 +60262 0.383758544921875 +60263 0.35687255859375 +60264 0.31182861328125 +60265 0.250885009765625 +60266 0.1654052734375 +60267 0.035247802734375 +60268 -0.142059326171875 +60269 -0.33563232421875 +60270 -0.5345458984375 +60271 -0.72186279296875 +60272 -0.836669921875 +60273 -0.8326416015625 +60274 -0.7296142578125 +60275 -0.582550048828125 +60276 -0.440093994140625 +60277 -0.324310302734375 +60278 -0.20147705078125 +60279 -0.044647216796875 +60280 0.103973388671875 +60281 0.202392578125 +60282 0.264495849609375 +60283 0.338897705078125 +60284 0.443817138671875 +60285 0.545074462890625 +60286 0.6173095703125 +60287 0.6524658203125 +60288 0.66339111328125 +60289 0.6561279296875 +60290 0.606781005859375 +60291 0.501190185546875 +60292 0.352783203125 +60293 0.176544189453125 +60294 -0.034820556640625 +60295 -0.258209228515625 +60296 -0.44244384765625 +60297 -0.5753173828125 +60298 -0.65203857421875 +60299 -0.641632080078125 +60300 -0.562164306640625 +60301 -0.458038330078125 +60302 -0.350555419921875 +60303 -0.260528564453125 +60304 -0.192108154296875 +60305 -0.141937255859375 +60306 -0.1021728515625 +60307 -0.062896728515625 +60308 -0.011932373046875 +60309 0.062835693359375 +60310 0.148712158203125 +60311 0.241729736328125 +60312 0.34912109375 +60313 0.457305908203125 +60314 0.54388427734375 +60315 0.5728759765625 +60316 0.506591796875 +60317 0.351226806640625 +60318 0.146514892578125 +60319 -0.05523681640625 +60320 -0.21624755859375 +60321 -0.334930419921875 +60322 -0.402984619140625 +60323 -0.4412841796875 +60324 -0.49578857421875 +60325 -0.5601806640625 +60326 -0.600738525390625 +60327 -0.584228515625 +60328 -0.47930908203125 +60329 -0.27935791015625 +60330 -0.0089111328125 +60331 0.268798828125 +60332 0.482818603515625 +60333 0.60369873046875 +60334 0.650421142578125 +60335 0.66400146484375 +60336 0.6414794921875 +60337 0.572540283203125 +60338 0.498138427734375 +60339 0.439453125 +60340 0.375518798828125 +60341 0.274505615234375 +60342 0.1087646484375 +60343 -0.099395751953125 +60344 -0.3182373046875 +60345 -0.5489501953125 +60346 -0.7738037109375 +60347 -0.86383056640625 +60348 -0.870391845703125 +60349 -0.86895751953125 +60350 -0.861053466796875 +60351 -0.765869140625 +60352 -0.5301513671875 +60353 -0.214691162109375 +60354 0.137359619140625 +60355 0.474822998046875 +60356 0.76239013671875 +60357 0.867462158203125 +60358 0.870361328125 +60359 0.86480712890625 +60360 0.831817626953125 +60361 0.677581787109375 +60362 0.495880126953125 +60363 0.30767822265625 +60364 0.116180419921875 +60365 -0.110748291015625 +60366 -0.381805419921875 +60367 -0.6572265625 +60368 -0.857421875 +60369 -0.870391845703125 +60370 -0.870391845703125 +60371 -0.86444091796875 +60372 -0.85723876953125 +60373 -0.790008544921875 +60374 -0.62847900390625 +60375 -0.3956298828125 +60376 -0.126708984375 +60377 0.150115966796875 +60378 0.424041748046875 +60379 0.670623779296875 +60380 0.854522705078125 +60381 0.866485595703125 +60382 0.86920166015625 +60383 0.8653564453125 +60384 0.857147216796875 +60385 0.766845703125 +60386 0.628509521484375 +60387 0.462127685546875 +60388 0.297210693359375 +60389 0.14862060546875 +60390 -0.00537109375 +60391 -0.15753173828125 +60392 -0.31304931640625 +60393 -0.48876953125 +60394 -0.6416015625 +60395 -0.751373291015625 +60396 -0.84619140625 +60397 -0.861297607421875 +60398 -0.863250732421875 +60399 -0.856597900390625 +60400 -0.7498779296875 +60401 -0.624542236328125 +60402 -0.47808837890625 +60403 -0.253387451171875 +60404 0.003692626953125 +60405 0.2257080078125 +60406 0.427154541015625 +60407 0.643218994140625 +60408 0.855926513671875 +60409 0.870361328125 +60410 0.870361328125 +60411 0.862762451171875 +60412 0.79669189453125 +60413 0.595794677734375 +60414 0.362152099609375 +60415 0.1270751953125 +60416 -0.086944580078125 +60417 -0.2784423828125 +60418 -0.484832763671875 +60419 -0.729583740234375 +60420 -0.86688232421875 +60421 -0.870391845703125 +60422 -0.86859130859375 +60423 -0.86279296875 +60424 -0.817962646484375 +60425 -0.6116943359375 +60426 -0.3128662109375 +60427 0.039398193359375 +60428 0.422821044921875 +60429 0.805145263671875 +60430 0.870361328125 +60431 0.870361328125 +60432 0.860015869140625 +60433 0.727935791015625 +60434 0.48114013671875 +60435 0.2059326171875 +60436 -0.06103515625 +60437 -0.29913330078125 +60438 -0.516204833984375 +60439 -0.7252197265625 +60440 -0.85980224609375 +60441 -0.870391845703125 +60442 -0.870391845703125 +60443 -0.858062744140625 +60444 -0.673004150390625 +60445 -0.42694091796875 +60446 -0.2100830078125 +60447 -0.0362548828125 +60448 0.10943603515625 +60449 0.23516845703125 +60450 0.373687744140625 +60451 0.517791748046875 +60452 0.602783203125 +60453 0.635711669921875 +60454 0.655181884765625 +60455 0.65948486328125 +60456 0.651275634765625 +60457 0.61846923828125 +60458 0.53753662109375 +60459 0.404144287109375 +60460 0.22186279296875 +60461 0.003997802734375 +60462 -0.22100830078125 +60463 -0.42449951171875 +60464 -0.579833984375 +60465 -0.641876220703125 +60466 -0.6177978515625 +60467 -0.575531005859375 +60468 -0.526336669921875 +60469 -0.42645263671875 +60470 -0.2581787109375 +60471 -0.068695068359375 +60472 0.09222412109375 +60473 0.232147216796875 +60474 0.3509521484375 +60475 0.410064697265625 +60476 0.372955322265625 +60477 0.2554931640625 +60478 0.10711669921875 +60479 -0.052886962890625 +60480 -0.186279296875 +60481 -0.23291015625 +60482 -0.209442138671875 +60483 -0.174163818359375 +60484 -0.126739501953125 +60485 -0.048126220703125 +60486 0.0426025390625 +60487 0.10748291015625 +60488 0.1409912109375 +60489 0.19708251953125 +60490 0.273651123046875 +60491 0.31768798828125 +60492 0.341094970703125 +60493 0.368011474609375 +60494 0.37249755859375 +60495 0.30072021484375 +60496 0.1517333984375 +60497 -0.01470947265625 +60498 -0.1883544921875 +60499 -0.372711181640625 +60500 -0.51397705078125 +60501 -0.57177734375 +60502 -0.53948974609375 +60503 -0.43511962890625 +60504 -0.2962646484375 +60505 -0.161102294921875 +60506 -0.0435791015625 +60507 0.060394287109375 +60508 0.13665771484375 +60509 0.170135498046875 +60510 0.16552734375 +60511 0.15728759765625 +60512 0.150787353515625 +60513 0.12200927734375 +60514 0.080108642578125 +60515 0.05126953125 +60516 0.062896728515625 +60517 0.09271240234375 +60518 0.092987060546875 +60519 0.07855224609375 +60520 0.06427001953125 +60521 0.0347900390625 +60522 -0.01171875 +60523 -0.056060791015625 +60524 -0.055511474609375 +60525 -0.010467529296875 +60526 0.02508544921875 +60527 0.025665283203125 +60528 0.017333984375 +60529 0.00189208984375 +60530 -0.03173828125 +60531 -0.071502685546875 +60532 -0.13543701171875 +60533 -0.219970703125 +60534 -0.300506591796875 +60535 -0.376312255859375 +60536 -0.416107177734375 +60537 -0.371124267578125 +60538 -0.242279052734375 +60539 -0.069732666015625 +60540 0.125640869140625 +60541 0.31268310546875 +60542 0.45501708984375 +60543 0.554779052734375 +60544 0.61065673828125 +60545 0.610931396484375 +60546 0.531463623046875 +60547 0.3883056640625 +60548 0.23468017578125 +60549 0.095245361328125 +60550 -0.00396728515625 +60551 -0.04852294921875 +60552 -0.055145263671875 +60553 -0.0758056640625 +60554 -0.138702392578125 +60555 -0.209197998046875 +60556 -0.289031982421875 +60557 -0.37884521484375 +60558 -0.456329345703125 +60559 -0.51641845703125 +60560 -0.519287109375 +60561 -0.458251953125 +60562 -0.384796142578125 +60563 -0.323699951171875 +60564 -0.269287109375 +60565 -0.1951904296875 +60566 -0.100006103515625 +60567 -0.01055908203125 +60568 0.1033935546875 +60569 0.24908447265625 +60570 0.373199462890625 +60571 0.45806884765625 +60572 0.511474609375 +60573 0.565399169921875 +60574 0.61138916015625 +60575 0.5897216796875 +60576 0.4906005859375 +60577 0.33148193359375 +60578 0.147796630859375 +60579 -0.01873779296875 +60580 -0.140289306640625 +60581 -0.191986083984375 +60582 -0.184295654296875 +60583 -0.161834716796875 +60584 -0.166595458984375 +60585 -0.19390869140625 +60586 -0.22442626953125 +60587 -0.279754638671875 +60588 -0.3389892578125 +60589 -0.3543701171875 +60590 -0.348175048828125 +60591 -0.32598876953125 +60592 -0.2581787109375 +60593 -0.139801025390625 +60594 0.014617919921875 +60595 0.144378662109375 +60596 0.221038818359375 +60597 0.27069091796875 +60598 0.294036865234375 +60599 0.311767578125 +60600 0.339141845703125 +60601 0.360260009765625 +60602 0.360504150390625 +60603 0.308380126953125 +60604 0.18170166015625 +60605 0.0047607421875 +60606 -0.17559814453125 +60607 -0.3143310546875 +60608 -0.36785888671875 +60609 -0.36248779296875 +60610 -0.343536376953125 +60611 -0.3018798828125 +60612 -0.231414794921875 +60613 -0.117645263671875 +60614 0.007049560546875 +60615 0.087982177734375 +60616 0.13946533203125 +60617 0.17425537109375 +60618 0.188201904296875 +60619 0.171234130859375 +60620 0.118438720703125 +60621 0.05706787109375 +60622 -0.010711669921875 +60623 -0.0914306640625 +60624 -0.162322998046875 +60625 -0.194549560546875 +60626 -0.1492919921875 +60627 -0.02166748046875 +60628 0.124053955078125 +60629 0.211151123046875 +60630 0.240447998046875 +60631 0.242218017578125 +60632 0.2257080078125 +60633 0.194366455078125 +60634 0.115509033203125 +60635 0.0128173828125 +60636 -0.053802490234375 +60637 -0.110626220703125 +60638 -0.199493408203125 +60639 -0.29437255859375 +60640 -0.33221435546875 +60641 -0.27972412109375 +60642 -0.185333251953125 +60643 -0.128204345703125 +60644 -0.115692138671875 +60645 -0.116455078125 +60646 -0.105926513671875 +60647 -0.053955078125 +60648 0.048797607421875 +60649 0.157318115234375 +60650 0.212005615234375 +60651 0.218475341796875 +60652 0.23724365234375 +60653 0.30535888671875 +60654 0.38128662109375 +60655 0.404449462890625 +60656 0.3944091796875 +60657 0.3885498046875 +60658 0.362640380859375 +60659 0.27362060546875 +60660 0.11712646484375 +60661 -0.054901123046875 +60662 -0.19085693359375 +60663 -0.28570556640625 +60664 -0.339263916015625 +60665 -0.3775634765625 +60666 -0.445709228515625 +60667 -0.535064697265625 +60668 -0.629058837890625 +60669 -0.697601318359375 +60670 -0.70391845703125 +60671 -0.6424560546875 +60672 -0.491241455078125 +60673 -0.265716552734375 +60674 -0.023712158203125 +60675 0.201751708984375 +60676 0.375823974609375 +60677 0.485076904296875 +60678 0.56884765625 +60679 0.634765625 +60680 0.63763427734375 +60681 0.5660400390625 +60682 0.4720458984375 +60683 0.40692138671875 +60684 0.3778076171875 +60685 0.376953125 +60686 0.371978759765625 +60687 0.313140869140625 +60688 0.184417724609375 +60689 0.011199951171875 +60690 -0.171051025390625 +60691 -0.33740234375 +60692 -0.47198486328125 +60693 -0.560394287109375 +60694 -0.58056640625 +60695 -0.54754638671875 +60696 -0.508575439453125 +60697 -0.459503173828125 +60698 -0.394378662109375 +60699 -0.35260009765625 +60700 -0.31170654296875 +60701 -0.197418212890625 +60702 -0.007965087890625 +60703 0.207489013671875 +60704 0.409210205078125 +60705 0.57208251953125 +60706 0.66595458984375 +60707 0.65875244140625 +60708 0.56744384765625 +60709 0.431396484375 +60710 0.29443359375 +60711 0.182464599609375 +60712 0.06365966796875 +60713 -0.075958251953125 +60714 -0.189422607421875 +60715 -0.271942138671875 +60716 -0.342529296875 +60717 -0.364166259765625 +60718 -0.327239990234375 +60719 -0.2769775390625 +60720 -0.253692626953125 +60721 -0.24365234375 +60722 -0.1983642578125 +60723 -0.116241455078125 +60724 -0.036834716796875 +60725 0.034881591796875 +60726 0.09124755859375 +60727 0.10888671875 +60728 0.125518798828125 +60729 0.15771484375 +60730 0.17828369140625 +60731 0.17108154296875 +60732 0.129974365234375 +60733 0.082427978515625 +60734 0.027679443359375 +60735 -0.065643310546875 +60736 -0.15936279296875 +60737 -0.21307373046875 +60738 -0.234649658203125 +60739 -0.2001953125 +60740 -0.119171142578125 +60741 -0.024749755859375 +60742 0.085784912109375 +60743 0.178131103515625 +60744 0.215576171875 +60745 0.211456298828125 +60746 0.17523193359375 +60747 0.128753662109375 +60748 0.1019287109375 +60749 0.0743408203125 +60750 0.04327392578125 +60751 0.038177490234375 +60752 0.076263427734375 +60753 0.14105224609375 +60754 0.186431884765625 +60755 0.188812255859375 +60756 0.1390380859375 +60757 0.041778564453125 +60758 -0.079437255859375 +60759 -0.219390869140625 +60760 -0.367828369140625 +60761 -0.494873046875 +60762 -0.556243896484375 +60763 -0.508697509765625 +60764 -0.3756103515625 +60765 -0.218902587890625 +60766 -0.063751220703125 +60767 0.091552734375 +60768 0.23602294921875 +60769 0.342987060546875 +60770 0.39520263671875 +60771 0.389373779296875 +60772 0.324249267578125 +60773 0.224090576171875 +60774 0.124267578125 +60775 0.037078857421875 +60776 -0.010101318359375 +60777 -0.019439697265625 +60778 -0.022796630859375 +60779 -0.001556396484375 +60780 0.056304931640625 +60781 0.106719970703125 +60782 0.096893310546875 +60783 0.042694091796875 +60784 -0.018035888671875 +60785 -0.07586669921875 +60786 -0.11944580078125 +60787 -0.15972900390625 +60788 -0.202606201171875 +60789 -0.24859619140625 +60790 -0.30517578125 +60791 -0.36212158203125 +60792 -0.39141845703125 +60793 -0.35528564453125 +60794 -0.249969482421875 +60795 -0.092864990234375 +60796 0.08905029296875 +60797 0.2352294921875 +60798 0.318817138671875 +60799 0.358642578125 +60800 0.347747802734375 +60801 0.28564453125 +60802 0.223175048828125 +60803 0.196746826171875 +60804 0.179840087890625 +60805 0.155548095703125 +60806 0.151214599609375 +60807 0.156951904296875 +60808 0.13177490234375 +60809 0.100799560546875 +60810 0.087127685546875 +60811 0.05487060546875 +60812 -0.009002685546875 +60813 -0.10400390625 +60814 -0.229400634765625 +60815 -0.35552978515625 +60816 -0.441925048828125 +60817 -0.473846435546875 +60818 -0.464813232421875 +60819 -0.419097900390625 +60820 -0.334320068359375 +60821 -0.227935791015625 +60822 -0.12347412109375 +60823 -0.02764892578125 +60824 0.077667236328125 +60825 0.2132568359375 +60826 0.38885498046875 +60827 0.582794189453125 +60828 0.734039306640625 +60829 0.800140380859375 +60830 0.7783203125 +60831 0.6651611328125 +60832 0.45965576171875 +60833 0.199188232421875 +60834 -0.050689697265625 +60835 -0.23297119140625 +60836 -0.33013916015625 +60837 -0.368408203125 +60838 -0.378936767578125 +60839 -0.376983642578125 +60840 -0.37969970703125 +60841 -0.391510009765625 +60842 -0.385345458984375 +60843 -0.3419189453125 +60844 -0.28289794921875 +60845 -0.251617431640625 +60846 -0.266143798828125 +60847 -0.273345947265625 +60848 -0.216796875 +60849 -0.128265380859375 +60850 -0.068145751953125 +60851 -0.0430908203125 +60852 -0.024444580078125 +60853 0.020721435546875 +60854 0.124481201171875 +60855 0.25787353515625 +60856 0.379119873046875 +60857 0.47991943359375 +60858 0.5281982421875 +60859 0.511138916015625 +60860 0.456207275390625 +60861 0.407470703125 +60862 0.383758544921875 +60863 0.35687255859375 +60864 0.31182861328125 +60865 0.250885009765625 +60866 0.1654052734375 +60867 0.035247802734375 +60868 -0.142059326171875 +60869 -0.33563232421875 +60870 -0.5345458984375 +60871 -0.72186279296875 +60872 -0.836669921875 +60873 -0.8326416015625 +60874 -0.7296142578125 +60875 -0.582550048828125 +60876 -0.440093994140625 +60877 -0.324310302734375 +60878 -0.20147705078125 +60879 -0.044647216796875 +60880 0.103973388671875 +60881 0.202392578125 +60882 0.264495849609375 +60883 0.338897705078125 +60884 0.443817138671875 +60885 0.545074462890625 +60886 0.6173095703125 +60887 0.6524658203125 +60888 0.66339111328125 +60889 0.6561279296875 +60890 0.606781005859375 +60891 0.501190185546875 +60892 0.352783203125 +60893 0.176544189453125 +60894 -0.034820556640625 +60895 -0.258209228515625 +60896 -0.44244384765625 +60897 -0.5753173828125 +60898 -0.65203857421875 +60899 -0.641632080078125 +60900 -0.562164306640625 +60901 -0.458038330078125 +60902 -0.350555419921875 +60903 -0.260528564453125 +60904 -0.192108154296875 +60905 -0.141937255859375 +60906 -0.1021728515625 +60907 -0.062896728515625 +60908 -0.011932373046875 +60909 0.062835693359375 +60910 0.148712158203125 +60911 0.241729736328125 +60912 0.34912109375 +60913 0.457305908203125 +60914 0.54388427734375 +60915 0.5728759765625 +60916 0.506591796875 +60917 0.351226806640625 +60918 0.146514892578125 +60919 -0.05523681640625 +60920 -0.21624755859375 +60921 -0.334930419921875 +60922 -0.402984619140625 +60923 -0.4412841796875 +60924 -0.49578857421875 +60925 -0.5601806640625 +60926 -0.600738525390625 +60927 -0.584228515625 +60928 -0.47930908203125 +60929 -0.27935791015625 +60930 -0.0089111328125 +60931 0.268798828125 +60932 0.482818603515625 +60933 0.60369873046875 +60934 0.650421142578125 +60935 0.66400146484375 +60936 0.6414794921875 +60937 0.572540283203125 +60938 0.498138427734375 +60939 0.439453125 +60940 0.375518798828125 +60941 0.274505615234375 +60942 0.1087646484375 +60943 -0.099395751953125 +60944 -0.3182373046875 +60945 -0.5489501953125 +60946 -0.7738037109375 +60947 -0.86383056640625 +60948 -0.870391845703125 +60949 -0.86895751953125 +60950 -0.861053466796875 +60951 -0.765869140625 +60952 -0.5301513671875 +60953 -0.214691162109375 +60954 0.137359619140625 +60955 0.474822998046875 +60956 0.76239013671875 +60957 0.867462158203125 +60958 0.870361328125 +60959 0.86480712890625 +60960 0.831817626953125 +60961 0.677581787109375 +60962 0.495880126953125 +60963 0.30767822265625 +60964 0.116180419921875 +60965 -0.110748291015625 +60966 -0.381805419921875 +60967 -0.6572265625 +60968 -0.857421875 +60969 -0.870391845703125 +60970 -0.870391845703125 +60971 -0.86444091796875 +60972 -0.85723876953125 +60973 -0.790008544921875 +60974 -0.62847900390625 +60975 -0.3956298828125 +60976 -0.126708984375 +60977 0.150115966796875 +60978 0.424041748046875 +60979 0.670623779296875 +60980 0.854522705078125 +60981 0.866485595703125 +60982 0.86920166015625 +60983 0.8653564453125 +60984 0.857147216796875 +60985 0.766845703125 +60986 0.628509521484375 +60987 0.462127685546875 +60988 0.297210693359375 +60989 0.14862060546875 +60990 -0.00537109375 +60991 -0.15753173828125 +60992 -0.31304931640625 +60993 -0.48876953125 +60994 -0.6416015625 +60995 -0.751373291015625 +60996 -0.84619140625 +60997 -0.861297607421875 +60998 -0.863250732421875 +60999 -0.856597900390625 +61000 -0.7498779296875 +61001 -0.624542236328125 +61002 -0.47808837890625 +61003 -0.253387451171875 +61004 0.003692626953125 +61005 0.2257080078125 +61006 0.427154541015625 +61007 0.643218994140625 +61008 0.855926513671875 +61009 0.870361328125 +61010 0.870361328125 +61011 0.862762451171875 +61012 0.79669189453125 +61013 0.595794677734375 +61014 0.362152099609375 +61015 0.1270751953125 +61016 -0.086944580078125 +61017 -0.2784423828125 +61018 -0.484832763671875 +61019 -0.729583740234375 +61020 -0.86688232421875 +61021 -0.870391845703125 +61022 -0.86859130859375 +61023 -0.86279296875 +61024 -0.817962646484375 +61025 -0.6116943359375 +61026 -0.3128662109375 +61027 0.039398193359375 +61028 0.422821044921875 +61029 0.805145263671875 +61030 0.870361328125 +61031 0.870361328125 +61032 0.860015869140625 +61033 0.727935791015625 +61034 0.48114013671875 +61035 0.2059326171875 +61036 -0.06103515625 +61037 -0.29913330078125 +61038 -0.516204833984375 +61039 -0.7252197265625 +61040 -0.85980224609375 +61041 -0.870391845703125 +61042 -0.870391845703125 +61043 -0.858062744140625 +61044 -0.673004150390625 +61045 -0.42694091796875 +61046 -0.2100830078125 +61047 -0.0362548828125 +61048 0.10943603515625 +61049 0.23516845703125 +61050 0.373687744140625 +61051 0.517791748046875 +61052 0.602783203125 +61053 0.635711669921875 +61054 0.655181884765625 +61055 0.65948486328125 +61056 0.651275634765625 +61057 0.61846923828125 +61058 0.53753662109375 +61059 0.404144287109375 +61060 0.22186279296875 +61061 0.003997802734375 +61062 -0.22100830078125 +61063 -0.42449951171875 +61064 -0.579833984375 +61065 -0.641876220703125 +61066 -0.6177978515625 +61067 -0.575531005859375 +61068 -0.526336669921875 +61069 -0.42645263671875 +61070 -0.2581787109375 +61071 -0.068695068359375 +61072 0.09222412109375 +61073 0.232147216796875 +61074 0.3509521484375 +61075 0.410064697265625 +61076 0.372955322265625 +61077 0.2554931640625 +61078 0.10711669921875 +61079 -0.052886962890625 +61080 -0.186279296875 +61081 -0.23291015625 +61082 -0.209442138671875 +61083 -0.174163818359375 +61084 -0.126739501953125 +61085 -0.048126220703125 +61086 0.0426025390625 +61087 0.10748291015625 +61088 0.1409912109375 +61089 0.19708251953125 +61090 0.273651123046875 +61091 0.31768798828125 +61092 0.341094970703125 +61093 0.368011474609375 +61094 0.37249755859375 +61095 0.30072021484375 +61096 0.1517333984375 +61097 -0.01470947265625 +61098 -0.1883544921875 +61099 -0.372711181640625 +61100 -0.51397705078125 +61101 -0.57177734375 +61102 -0.53948974609375 +61103 -0.43511962890625 +61104 -0.2962646484375 +61105 -0.161102294921875 +61106 -0.0435791015625 +61107 0.060394287109375 +61108 0.13665771484375 +61109 0.170135498046875 +61110 0.16552734375 +61111 0.15728759765625 +61112 0.150787353515625 +61113 0.12200927734375 +61114 0.080108642578125 +61115 0.05126953125 +61116 0.062896728515625 +61117 0.09271240234375 +61118 0.092987060546875 +61119 0.07855224609375 +61120 0.06427001953125 +61121 0.0347900390625 +61122 -0.01171875 +61123 -0.056060791015625 +61124 -0.055511474609375 +61125 -0.010467529296875 +61126 0.02508544921875 +61127 0.025665283203125 +61128 0.017333984375 +61129 0.00189208984375 +61130 -0.03173828125 +61131 -0.071502685546875 +61132 -0.13543701171875 +61133 -0.219970703125 +61134 -0.300506591796875 +61135 -0.376312255859375 +61136 -0.416107177734375 +61137 -0.371124267578125 +61138 -0.242279052734375 +61139 -0.069732666015625 +61140 0.125640869140625 +61141 0.31268310546875 +61142 0.45501708984375 +61143 0.554779052734375 +61144 0.61065673828125 +61145 0.610931396484375 +61146 0.531463623046875 +61147 0.3883056640625 +61148 0.23468017578125 +61149 0.095245361328125 +61150 -0.00396728515625 +61151 -0.04852294921875 +61152 -0.055145263671875 +61153 -0.0758056640625 +61154 -0.138702392578125 +61155 -0.209197998046875 +61156 -0.289031982421875 +61157 -0.37884521484375 +61158 -0.456329345703125 +61159 -0.51641845703125 +61160 -0.519287109375 +61161 -0.458251953125 +61162 -0.384796142578125 +61163 -0.323699951171875 +61164 -0.269287109375 +61165 -0.1951904296875 +61166 -0.100006103515625 +61167 -0.01055908203125 +61168 0.1033935546875 +61169 0.24908447265625 +61170 0.373199462890625 +61171 0.45806884765625 +61172 0.511474609375 +61173 0.565399169921875 +61174 0.61138916015625 +61175 0.5897216796875 +61176 0.4906005859375 +61177 0.33148193359375 +61178 0.147796630859375 +61179 -0.01873779296875 +61180 -0.140289306640625 +61181 -0.191986083984375 +61182 -0.184295654296875 +61183 -0.161834716796875 +61184 -0.166595458984375 +61185 -0.19390869140625 +61186 -0.22442626953125 +61187 -0.279754638671875 +61188 -0.3389892578125 +61189 -0.3543701171875 +61190 -0.348175048828125 +61191 -0.32598876953125 +61192 -0.2581787109375 +61193 -0.139801025390625 +61194 0.014617919921875 +61195 0.144378662109375 +61196 0.221038818359375 +61197 0.27069091796875 +61198 0.294036865234375 +61199 0.311767578125 +61200 0.339141845703125 +61201 0.360260009765625 +61202 0.360504150390625 +61203 0.308380126953125 +61204 0.18170166015625 +61205 0.0047607421875 +61206 -0.17559814453125 +61207 -0.3143310546875 +61208 -0.36785888671875 +61209 -0.36248779296875 +61210 -0.343536376953125 +61211 -0.3018798828125 +61212 -0.231414794921875 +61213 -0.117645263671875 +61214 0.007049560546875 +61215 0.087982177734375 +61216 0.13946533203125 +61217 0.17425537109375 +61218 0.188201904296875 +61219 0.171234130859375 +61220 0.118438720703125 +61221 0.05706787109375 +61222 -0.010711669921875 +61223 -0.0914306640625 +61224 -0.162322998046875 +61225 -0.194549560546875 +61226 -0.1492919921875 +61227 -0.02166748046875 +61228 0.124053955078125 +61229 0.211151123046875 +61230 0.240447998046875 +61231 0.242218017578125 +61232 0.2257080078125 +61233 0.194366455078125 +61234 0.115509033203125 +61235 0.0128173828125 +61236 -0.053802490234375 +61237 -0.110626220703125 +61238 -0.199493408203125 +61239 -0.29437255859375 +61240 -0.33221435546875 +61241 -0.27972412109375 +61242 -0.185333251953125 +61243 -0.128204345703125 +61244 -0.115692138671875 +61245 -0.116455078125 +61246 -0.105926513671875 +61247 -0.053955078125 +61248 0.048797607421875 +61249 0.157318115234375 +61250 0.212005615234375 +61251 0.218475341796875 +61252 0.23724365234375 +61253 0.30535888671875 +61254 0.38128662109375 +61255 0.404449462890625 +61256 0.3944091796875 +61257 0.3885498046875 +61258 0.362640380859375 +61259 0.27362060546875 +61260 0.11712646484375 +61261 -0.054901123046875 +61262 -0.19085693359375 +61263 -0.28570556640625 +61264 -0.339263916015625 +61265 -0.3775634765625 +61266 -0.445709228515625 +61267 -0.535064697265625 +61268 -0.629058837890625 +61269 -0.697601318359375 +61270 -0.70391845703125 +61271 -0.6424560546875 +61272 -0.491241455078125 +61273 -0.265716552734375 +61274 -0.023712158203125 +61275 0.201751708984375 +61276 0.375823974609375 +61277 0.485076904296875 +61278 0.56884765625 +61279 0.634765625 +61280 0.63763427734375 +61281 0.5660400390625 +61282 0.4720458984375 +61283 0.40692138671875 +61284 0.3778076171875 +61285 0.376953125 +61286 0.371978759765625 +61287 0.313140869140625 +61288 0.184417724609375 +61289 0.011199951171875 +61290 -0.171051025390625 +61291 -0.33740234375 +61292 -0.47198486328125 +61293 -0.560394287109375 +61294 -0.58056640625 +61295 -0.54754638671875 +61296 -0.508575439453125 +61297 -0.459503173828125 +61298 -0.394378662109375 +61299 -0.35260009765625 +61300 -0.31170654296875 +61301 -0.197418212890625 +61302 -0.007965087890625 +61303 0.207489013671875 +61304 0.409210205078125 +61305 0.57208251953125 +61306 0.66595458984375 +61307 0.65875244140625 +61308 0.56744384765625 +61309 0.431396484375 +61310 0.29443359375 +61311 0.182464599609375 +61312 0.06365966796875 +61313 -0.075958251953125 +61314 -0.189422607421875 +61315 -0.271942138671875 +61316 -0.342529296875 +61317 -0.364166259765625 +61318 -0.327239990234375 +61319 -0.2769775390625 +61320 -0.253692626953125 +61321 -0.24365234375 +61322 -0.1983642578125 +61323 -0.116241455078125 +61324 -0.036834716796875 +61325 0.034881591796875 +61326 0.09124755859375 +61327 0.10888671875 +61328 0.125518798828125 +61329 0.15771484375 +61330 0.17828369140625 +61331 0.17108154296875 +61332 0.129974365234375 +61333 0.082427978515625 +61334 0.027679443359375 +61335 -0.065643310546875 +61336 -0.15936279296875 +61337 -0.21307373046875 +61338 -0.234649658203125 +61339 -0.2001953125 +61340 -0.119171142578125 +61341 -0.024749755859375 +61342 0.085784912109375 +61343 0.178131103515625 +61344 0.215576171875 +61345 0.211456298828125 +61346 0.17523193359375 +61347 0.128753662109375 +61348 0.1019287109375 +61349 0.0743408203125 +61350 0.04327392578125 +61351 0.038177490234375 +61352 0.076263427734375 +61353 0.14105224609375 +61354 0.186431884765625 +61355 0.188812255859375 +61356 0.1390380859375 +61357 0.041778564453125 +61358 -0.079437255859375 +61359 -0.219390869140625 +61360 -0.367828369140625 +61361 -0.494873046875 +61362 -0.556243896484375 +61363 -0.508697509765625 +61364 -0.3756103515625 +61365 -0.218902587890625 +61366 -0.063751220703125 +61367 0.091552734375 +61368 0.23602294921875 +61369 0.342987060546875 +61370 0.39520263671875 +61371 0.389373779296875 +61372 0.324249267578125 +61373 0.224090576171875 +61374 0.124267578125 +61375 0.037078857421875 +61376 -0.010101318359375 +61377 -0.019439697265625 +61378 -0.022796630859375 +61379 -0.001556396484375 +61380 0.056304931640625 +61381 0.106719970703125 +61382 0.096893310546875 +61383 0.042694091796875 +61384 -0.018035888671875 +61385 -0.07586669921875 +61386 -0.11944580078125 +61387 -0.15972900390625 +61388 -0.202606201171875 +61389 -0.24859619140625 +61390 -0.30517578125 +61391 -0.36212158203125 +61392 -0.39141845703125 +61393 -0.35528564453125 +61394 -0.249969482421875 +61395 -0.092864990234375 +61396 0.08905029296875 +61397 0.2352294921875 +61398 0.318817138671875 +61399 0.358642578125 +61400 0.347747802734375 +61401 0.28564453125 +61402 0.223175048828125 +61403 0.196746826171875 +61404 0.179840087890625 +61405 0.155548095703125 +61406 0.151214599609375 +61407 0.156951904296875 +61408 0.13177490234375 +61409 0.100799560546875 +61410 0.087127685546875 +61411 0.05487060546875 +61412 -0.009002685546875 +61413 -0.10400390625 +61414 -0.229400634765625 +61415 -0.35552978515625 +61416 -0.441925048828125 +61417 -0.473846435546875 +61418 -0.464813232421875 +61419 -0.419097900390625 +61420 -0.334320068359375 +61421 -0.227935791015625 +61422 -0.12347412109375 +61423 -0.02764892578125 +61424 0.077667236328125 +61425 0.2132568359375 +61426 0.38885498046875 +61427 0.582794189453125 +61428 0.734039306640625 +61429 0.800140380859375 +61430 0.7783203125 +61431 0.6651611328125 +61432 0.45965576171875 +61433 0.199188232421875 +61434 -0.050689697265625 +61435 -0.23297119140625 +61436 -0.33013916015625 +61437 -0.368408203125 +61438 -0.378936767578125 +61439 -0.376983642578125 +61440 -0.37969970703125 +61441 -0.391510009765625 +61442 -0.385345458984375 +61443 -0.3419189453125 +61444 -0.28289794921875 +61445 -0.251617431640625 +61446 -0.266143798828125 +61447 -0.273345947265625 +61448 -0.216796875 +61449 -0.128265380859375 +61450 -0.068145751953125 +61451 -0.0430908203125 +61452 -0.024444580078125 +61453 0.020721435546875 +61454 0.124481201171875 +61455 0.25787353515625 +61456 0.379119873046875 +61457 0.47991943359375 +61458 0.5281982421875 +61459 0.511138916015625 +61460 0.456207275390625 +61461 0.407470703125 +61462 0.383758544921875 +61463 0.35687255859375 +61464 0.31182861328125 +61465 0.250885009765625 +61466 0.1654052734375 +61467 0.035247802734375 +61468 -0.142059326171875 +61469 -0.33563232421875 +61470 -0.5345458984375 +61471 -0.72186279296875 +61472 -0.836669921875 +61473 -0.8326416015625 +61474 -0.7296142578125 +61475 -0.582550048828125 +61476 -0.440093994140625 +61477 -0.324310302734375 +61478 -0.20147705078125 +61479 -0.044647216796875 +61480 0.103973388671875 +61481 0.202392578125 +61482 0.264495849609375 +61483 0.338897705078125 +61484 0.443817138671875 +61485 0.545074462890625 +61486 0.6173095703125 +61487 0.6524658203125 +61488 0.66339111328125 +61489 0.6561279296875 +61490 0.606781005859375 +61491 0.501190185546875 +61492 0.352783203125 +61493 0.176544189453125 +61494 -0.034820556640625 +61495 -0.258209228515625 +61496 -0.44244384765625 +61497 -0.5753173828125 +61498 -0.65203857421875 +61499 -0.641632080078125 +61500 -0.562164306640625 +61501 -0.458038330078125 +61502 -0.350555419921875 +61503 -0.260528564453125 +61504 -0.192108154296875 +61505 -0.141937255859375 +61506 -0.1021728515625 +61507 -0.062896728515625 +61508 -0.011932373046875 +61509 0.062835693359375 +61510 0.148712158203125 +61511 0.241729736328125 +61512 0.34912109375 +61513 0.457305908203125 +61514 0.54388427734375 +61515 0.5728759765625 +61516 0.506591796875 +61517 0.351226806640625 +61518 0.146514892578125 +61519 -0.05523681640625 +61520 -0.21624755859375 +61521 -0.334930419921875 +61522 -0.402984619140625 +61523 -0.4412841796875 +61524 -0.49578857421875 +61525 -0.5601806640625 +61526 -0.600738525390625 +61527 -0.584228515625 +61528 -0.47930908203125 +61529 -0.27935791015625 +61530 -0.0089111328125 +61531 0.268798828125 +61532 0.482818603515625 +61533 0.60369873046875 +61534 0.650421142578125 +61535 0.66400146484375 +61536 0.6414794921875 +61537 0.572540283203125 +61538 0.498138427734375 +61539 0.439453125 +61540 0.375518798828125 +61541 0.274505615234375 +61542 0.1087646484375 +61543 -0.099395751953125 +61544 -0.3182373046875 +61545 -0.5489501953125 +61546 -0.7738037109375 +61547 -0.86383056640625 +61548 -0.870391845703125 +61549 -0.86895751953125 +61550 -0.861053466796875 +61551 -0.765869140625 +61552 -0.5301513671875 +61553 -0.214691162109375 +61554 0.137359619140625 +61555 0.474822998046875 +61556 0.76239013671875 +61557 0.867462158203125 +61558 0.870361328125 +61559 0.86480712890625 +61560 0.831817626953125 +61561 0.677581787109375 +61562 0.495880126953125 +61563 0.30767822265625 +61564 0.116180419921875 +61565 -0.110748291015625 +61566 -0.381805419921875 +61567 -0.6572265625 +61568 -0.857421875 +61569 -0.870391845703125 +61570 -0.870391845703125 +61571 -0.86444091796875 +61572 -0.85723876953125 +61573 -0.790008544921875 +61574 -0.62847900390625 +61575 -0.3956298828125 +61576 -0.126708984375 +61577 0.150115966796875 +61578 0.424041748046875 +61579 0.670623779296875 +61580 0.854522705078125 +61581 0.866485595703125 +61582 0.86920166015625 +61583 0.8653564453125 +61584 0.857147216796875 +61585 0.766845703125 +61586 0.628509521484375 +61587 0.462127685546875 +61588 0.297210693359375 +61589 0.14862060546875 +61590 -0.00537109375 +61591 -0.15753173828125 +61592 -0.31304931640625 +61593 -0.48876953125 +61594 -0.6416015625 +61595 -0.751373291015625 +61596 -0.84619140625 +61597 -0.861297607421875 +61598 -0.863250732421875 +61599 -0.856597900390625 +61600 -0.7498779296875 +61601 -0.624542236328125 +61602 -0.47808837890625 +61603 -0.253387451171875 +61604 0.003692626953125 +61605 0.2257080078125 +61606 0.427154541015625 +61607 0.643218994140625 +61608 0.855926513671875 +61609 0.870361328125 +61610 0.870361328125 +61611 0.862762451171875 +61612 0.79669189453125 +61613 0.595794677734375 +61614 0.362152099609375 +61615 0.1270751953125 +61616 -0.086944580078125 +61617 -0.2784423828125 +61618 -0.484832763671875 +61619 -0.729583740234375 +61620 -0.86688232421875 +61621 -0.870391845703125 +61622 -0.86859130859375 +61623 -0.86279296875 +61624 -0.817962646484375 +61625 -0.6116943359375 +61626 -0.3128662109375 +61627 0.039398193359375 +61628 0.422821044921875 +61629 0.805145263671875 +61630 0.870361328125 +61631 0.870361328125 +61632 0.860015869140625 +61633 0.727935791015625 +61634 0.48114013671875 +61635 0.2059326171875 +61636 -0.06103515625 +61637 -0.29913330078125 +61638 -0.516204833984375 +61639 -0.7252197265625 +61640 -0.85980224609375 +61641 -0.870391845703125 +61642 -0.870391845703125 +61643 -0.858062744140625 +61644 -0.673004150390625 +61645 -0.42694091796875 +61646 -0.2100830078125 +61647 -0.0362548828125 +61648 0.10943603515625 +61649 0.23516845703125 +61650 0.373687744140625 +61651 0.517791748046875 +61652 0.602783203125 +61653 0.635711669921875 +61654 0.655181884765625 +61655 0.65948486328125 +61656 0.651275634765625 +61657 0.61846923828125 +61658 0.53753662109375 +61659 0.404144287109375 +61660 0.22186279296875 +61661 0.003997802734375 +61662 -0.22100830078125 +61663 -0.42449951171875 +61664 -0.579833984375 +61665 -0.641876220703125 +61666 -0.6177978515625 +61667 -0.575531005859375 +61668 -0.526336669921875 +61669 -0.42645263671875 +61670 -0.2581787109375 +61671 -0.068695068359375 +61672 0.09222412109375 +61673 0.232147216796875 +61674 0.3509521484375 +61675 0.410064697265625 +61676 0.372955322265625 +61677 0.2554931640625 +61678 0.10711669921875 +61679 -0.052886962890625 +61680 -0.186279296875 +61681 -0.23291015625 +61682 -0.209442138671875 +61683 -0.174163818359375 +61684 -0.126739501953125 +61685 -0.048126220703125 +61686 0.0426025390625 +61687 0.10748291015625 +61688 0.1409912109375 +61689 0.19708251953125 +61690 0.273651123046875 +61691 0.31768798828125 +61692 0.341094970703125 +61693 0.368011474609375 +61694 0.37249755859375 +61695 0.30072021484375 +61696 0.1517333984375 +61697 -0.01470947265625 +61698 -0.1883544921875 +61699 -0.372711181640625 +61700 -0.51397705078125 +61701 -0.57177734375 +61702 -0.53948974609375 +61703 -0.43511962890625 +61704 -0.2962646484375 +61705 -0.161102294921875 +61706 -0.0435791015625 +61707 0.060394287109375 +61708 0.13665771484375 +61709 0.170135498046875 +61710 0.16552734375 +61711 0.15728759765625 +61712 0.150787353515625 +61713 0.12200927734375 +61714 0.080108642578125 +61715 0.05126953125 +61716 0.062896728515625 +61717 0.09271240234375 +61718 0.092987060546875 +61719 0.07855224609375 +61720 0.06427001953125 +61721 0.0347900390625 +61722 -0.01171875 +61723 -0.056060791015625 +61724 -0.055511474609375 +61725 -0.010467529296875 +61726 0.02508544921875 +61727 0.025665283203125 +61728 0.017333984375 +61729 0.00189208984375 +61730 -0.03173828125 +61731 -0.071502685546875 +61732 -0.13543701171875 +61733 -0.219970703125 +61734 -0.300506591796875 +61735 -0.376312255859375 +61736 -0.416107177734375 +61737 -0.371124267578125 +61738 -0.242279052734375 +61739 -0.069732666015625 +61740 0.125640869140625 +61741 0.31268310546875 +61742 0.45501708984375 +61743 0.554779052734375 +61744 0.61065673828125 +61745 0.610931396484375 +61746 0.531463623046875 +61747 0.3883056640625 +61748 0.23468017578125 +61749 0.095245361328125 +61750 -0.00396728515625 +61751 -0.04852294921875 +61752 -0.055145263671875 +61753 -0.0758056640625 +61754 -0.138702392578125 +61755 -0.209197998046875 +61756 -0.289031982421875 +61757 -0.37884521484375 +61758 -0.456329345703125 +61759 -0.51641845703125 +61760 -0.519287109375 +61761 -0.458251953125 +61762 -0.384796142578125 +61763 -0.323699951171875 +61764 -0.269287109375 +61765 -0.1951904296875 +61766 -0.100006103515625 +61767 -0.01055908203125 +61768 0.1033935546875 +61769 0.24908447265625 +61770 0.373199462890625 +61771 0.45806884765625 +61772 0.511474609375 +61773 0.565399169921875 +61774 0.61138916015625 +61775 0.5897216796875 +61776 0.4906005859375 +61777 0.33148193359375 +61778 0.147796630859375 +61779 -0.01873779296875 +61780 -0.140289306640625 +61781 -0.191986083984375 +61782 -0.184295654296875 +61783 -0.161834716796875 +61784 -0.166595458984375 +61785 -0.19390869140625 +61786 -0.22442626953125 +61787 -0.279754638671875 +61788 -0.3389892578125 +61789 -0.3543701171875 +61790 -0.348175048828125 +61791 -0.32598876953125 +61792 -0.2581787109375 +61793 -0.139801025390625 +61794 0.014617919921875 +61795 0.144378662109375 +61796 0.221038818359375 +61797 0.27069091796875 +61798 0.294036865234375 +61799 0.311767578125 +61800 0.339141845703125 +61801 0.360260009765625 +61802 0.360504150390625 +61803 0.308380126953125 +61804 0.18170166015625 +61805 0.0047607421875 +61806 -0.17559814453125 +61807 -0.3143310546875 +61808 -0.36785888671875 +61809 -0.36248779296875 +61810 -0.343536376953125 +61811 -0.3018798828125 +61812 -0.231414794921875 +61813 -0.117645263671875 +61814 0.007049560546875 +61815 0.087982177734375 +61816 0.13946533203125 +61817 0.17425537109375 +61818 0.188201904296875 +61819 0.171234130859375 +61820 0.118438720703125 +61821 0.05706787109375 +61822 -0.010711669921875 +61823 -0.0914306640625 +61824 -0.162322998046875 +61825 -0.194549560546875 +61826 -0.1492919921875 +61827 -0.02166748046875 +61828 0.124053955078125 +61829 0.211151123046875 +61830 0.240447998046875 +61831 0.242218017578125 +61832 0.2257080078125 +61833 0.194366455078125 +61834 0.115509033203125 +61835 0.0128173828125 +61836 -0.053802490234375 +61837 -0.110626220703125 +61838 -0.199493408203125 +61839 -0.29437255859375 +61840 -0.33221435546875 +61841 -0.27972412109375 +61842 -0.185333251953125 +61843 -0.128204345703125 +61844 -0.115692138671875 +61845 -0.116455078125 +61846 -0.105926513671875 +61847 -0.053955078125 +61848 0.048797607421875 +61849 0.157318115234375 +61850 0.212005615234375 +61851 0.218475341796875 +61852 0.23724365234375 +61853 0.30535888671875 +61854 0.38128662109375 +61855 0.404449462890625 +61856 0.3944091796875 +61857 0.3885498046875 +61858 0.362640380859375 +61859 0.27362060546875 +61860 0.11712646484375 +61861 -0.054901123046875 +61862 -0.19085693359375 +61863 -0.28570556640625 +61864 -0.339263916015625 +61865 -0.3775634765625 +61866 -0.445709228515625 +61867 -0.535064697265625 +61868 -0.629058837890625 +61869 -0.697601318359375 +61870 -0.70391845703125 +61871 -0.6424560546875 +61872 -0.491241455078125 +61873 -0.265716552734375 +61874 -0.023712158203125 +61875 0.201751708984375 +61876 0.375823974609375 +61877 0.485076904296875 +61878 0.56884765625 +61879 0.634765625 +61880 0.63763427734375 +61881 0.5660400390625 +61882 0.4720458984375 +61883 0.40692138671875 +61884 0.3778076171875 +61885 0.376953125 +61886 0.371978759765625 +61887 0.313140869140625 +61888 0.184417724609375 +61889 0.011199951171875 +61890 -0.171051025390625 +61891 -0.33740234375 +61892 -0.47198486328125 +61893 -0.560394287109375 +61894 -0.58056640625 +61895 -0.54754638671875 +61896 -0.508575439453125 +61897 -0.459503173828125 +61898 -0.394378662109375 +61899 -0.35260009765625 +61900 -0.31170654296875 +61901 -0.197418212890625 +61902 -0.007965087890625 +61903 0.207489013671875 +61904 0.409210205078125 +61905 0.57208251953125 +61906 0.66595458984375 +61907 0.65875244140625 +61908 0.56744384765625 +61909 0.431396484375 +61910 0.29443359375 +61911 0.182464599609375 +61912 0.06365966796875 +61913 -0.075958251953125 +61914 -0.189422607421875 +61915 -0.271942138671875 +61916 -0.342529296875 +61917 -0.364166259765625 +61918 -0.327239990234375 +61919 -0.2769775390625 +61920 -0.253692626953125 +61921 -0.24365234375 +61922 -0.1983642578125 +61923 -0.116241455078125 +61924 -0.036834716796875 +61925 0.034881591796875 +61926 0.09124755859375 +61927 0.10888671875 +61928 0.125518798828125 +61929 0.15771484375 +61930 0.17828369140625 +61931 0.17108154296875 +61932 0.129974365234375 +61933 0.082427978515625 +61934 0.027679443359375 +61935 -0.065643310546875 +61936 -0.15936279296875 +61937 -0.21307373046875 +61938 -0.234649658203125 +61939 -0.2001953125 +61940 -0.119171142578125 +61941 -0.024749755859375 +61942 0.085784912109375 +61943 0.178131103515625 +61944 0.215576171875 +61945 0.211456298828125 +61946 0.17523193359375 +61947 0.128753662109375 +61948 0.1019287109375 +61949 0.0743408203125 +61950 0.04327392578125 +61951 0.038177490234375 +61952 0.076263427734375 +61953 0.14105224609375 +61954 0.186431884765625 +61955 0.188812255859375 +61956 0.1390380859375 +61957 0.041778564453125 +61958 -0.079437255859375 +61959 -0.219390869140625 +61960 -0.367828369140625 +61961 -0.494873046875 +61962 -0.556243896484375 +61963 -0.508697509765625 +61964 -0.3756103515625 +61965 -0.218902587890625 +61966 -0.063751220703125 +61967 0.091552734375 +61968 0.23602294921875 +61969 0.342987060546875 +61970 0.39520263671875 +61971 0.389373779296875 +61972 0.324249267578125 +61973 0.224090576171875 +61974 0.124267578125 +61975 0.037078857421875 +61976 -0.010101318359375 +61977 -0.019439697265625 +61978 -0.022796630859375 +61979 -0.001556396484375 +61980 0.056304931640625 +61981 0.106719970703125 +61982 0.096893310546875 +61983 0.042694091796875 +61984 -0.018035888671875 +61985 -0.07586669921875 +61986 -0.11944580078125 +61987 -0.15972900390625 +61988 -0.202606201171875 +61989 -0.24859619140625 +61990 -0.30517578125 +61991 -0.36212158203125 +61992 -0.39141845703125 +61993 -0.35528564453125 +61994 -0.249969482421875 +61995 -0.092864990234375 +61996 0.08905029296875 +61997 0.2352294921875 +61998 0.318817138671875 +61999 0.358642578125 +62000 0.347747802734375 +62001 0.28564453125 +62002 0.223175048828125 +62003 0.196746826171875 +62004 0.179840087890625 +62005 0.155548095703125 +62006 0.151214599609375 +62007 0.156951904296875 +62008 0.13177490234375 +62009 0.100799560546875 +62010 0.087127685546875 +62011 0.05487060546875 +62012 -0.009002685546875 +62013 -0.10400390625 +62014 -0.229400634765625 +62015 -0.35552978515625 +62016 -0.441925048828125 +62017 -0.473846435546875 +62018 -0.464813232421875 +62019 -0.419097900390625 +62020 -0.334320068359375 +62021 -0.227935791015625 +62022 -0.12347412109375 +62023 -0.02764892578125 +62024 0.077667236328125 +62025 0.2132568359375 +62026 0.38885498046875 +62027 0.582794189453125 +62028 0.734039306640625 +62029 0.800140380859375 +62030 0.7783203125 +62031 0.6651611328125 +62032 0.45965576171875 +62033 0.199188232421875 +62034 -0.050689697265625 +62035 -0.23297119140625 +62036 -0.33013916015625 +62037 -0.368408203125 +62038 -0.378936767578125 +62039 -0.376983642578125 +62040 -0.37969970703125 +62041 -0.391510009765625 +62042 -0.385345458984375 +62043 -0.3419189453125 +62044 -0.28289794921875 +62045 -0.251617431640625 +62046 -0.266143798828125 +62047 -0.273345947265625 +62048 -0.216796875 +62049 -0.128265380859375 +62050 -0.068145751953125 +62051 -0.0430908203125 +62052 -0.024444580078125 +62053 0.020721435546875 +62054 0.124481201171875 +62055 0.25787353515625 +62056 0.379119873046875 +62057 0.47991943359375 +62058 0.5281982421875 +62059 0.511138916015625 +62060 0.456207275390625 +62061 0.407470703125 +62062 0.383758544921875 +62063 0.35687255859375 +62064 0.31182861328125 +62065 0.250885009765625 +62066 0.1654052734375 +62067 0.035247802734375 +62068 -0.142059326171875 +62069 -0.33563232421875 +62070 -0.5345458984375 +62071 -0.72186279296875 +62072 -0.836669921875 +62073 -0.8326416015625 +62074 -0.7296142578125 +62075 -0.582550048828125 +62076 -0.440093994140625 +62077 -0.324310302734375 +62078 -0.20147705078125 +62079 -0.044647216796875 +62080 0.103973388671875 +62081 0.202392578125 +62082 0.264495849609375 +62083 0.338897705078125 +62084 0.443817138671875 +62085 0.545074462890625 +62086 0.6173095703125 +62087 0.6524658203125 +62088 0.66339111328125 +62089 0.6561279296875 +62090 0.606781005859375 +62091 0.501190185546875 +62092 0.352783203125 +62093 0.176544189453125 +62094 -0.034820556640625 +62095 -0.258209228515625 +62096 -0.44244384765625 +62097 -0.5753173828125 +62098 -0.65203857421875 +62099 -0.641632080078125 +62100 -0.562164306640625 +62101 -0.458038330078125 +62102 -0.350555419921875 +62103 -0.260528564453125 +62104 -0.192108154296875 +62105 -0.141937255859375 +62106 -0.1021728515625 +62107 -0.062896728515625 +62108 -0.011932373046875 +62109 0.062835693359375 +62110 0.148712158203125 +62111 0.241729736328125 +62112 0.34912109375 +62113 0.457305908203125 +62114 0.54388427734375 +62115 0.5728759765625 +62116 0.506591796875 +62117 0.351226806640625 +62118 0.146514892578125 +62119 -0.05523681640625 +62120 -0.21624755859375 +62121 -0.334930419921875 +62122 -0.402984619140625 +62123 -0.4412841796875 +62124 -0.49578857421875 +62125 -0.5601806640625 +62126 -0.600738525390625 +62127 -0.584228515625 +62128 -0.47930908203125 +62129 -0.27935791015625 +62130 -0.0089111328125 +62131 0.268798828125 +62132 0.482818603515625 +62133 0.60369873046875 +62134 0.650421142578125 +62135 0.66400146484375 +62136 0.6414794921875 +62137 0.572540283203125 +62138 0.498138427734375 +62139 0.439453125 +62140 0.375518798828125 +62141 0.274505615234375 +62142 0.1087646484375 +62143 -0.099395751953125 +62144 -0.3182373046875 +62145 -0.5489501953125 +62146 -0.7738037109375 +62147 -0.86383056640625 +62148 -0.870391845703125 +62149 -0.86895751953125 +62150 -0.861053466796875 +62151 -0.765869140625 +62152 -0.5301513671875 +62153 -0.214691162109375 +62154 0.137359619140625 +62155 0.474822998046875 +62156 0.76239013671875 +62157 0.867462158203125 +62158 0.870361328125 +62159 0.86480712890625 +62160 0.831817626953125 +62161 0.677581787109375 +62162 0.495880126953125 +62163 0.30767822265625 +62164 0.116180419921875 +62165 -0.110748291015625 +62166 -0.381805419921875 +62167 -0.6572265625 +62168 -0.857421875 +62169 -0.870391845703125 +62170 -0.870391845703125 +62171 -0.86444091796875 +62172 -0.85723876953125 +62173 -0.790008544921875 +62174 -0.62847900390625 +62175 -0.3956298828125 +62176 -0.126708984375 +62177 0.150115966796875 +62178 0.424041748046875 +62179 0.670623779296875 +62180 0.854522705078125 +62181 0.866485595703125 +62182 0.86920166015625 +62183 0.8653564453125 +62184 0.857147216796875 +62185 0.766845703125 +62186 0.628509521484375 +62187 0.462127685546875 +62188 0.297210693359375 +62189 0.14862060546875 +62190 -0.00537109375 +62191 -0.15753173828125 +62192 -0.31304931640625 +62193 -0.48876953125 +62194 -0.6416015625 +62195 -0.751373291015625 +62196 -0.84619140625 +62197 -0.861297607421875 +62198 -0.863250732421875 +62199 -0.856597900390625 +62200 -0.7498779296875 +62201 -0.624542236328125 +62202 -0.47808837890625 +62203 -0.253387451171875 +62204 0.003692626953125 +62205 0.2257080078125 +62206 0.427154541015625 +62207 0.643218994140625 +62208 0.855926513671875 +62209 0.870361328125 +62210 0.870361328125 +62211 0.862762451171875 +62212 0.79669189453125 +62213 0.595794677734375 +62214 0.362152099609375 +62215 0.1270751953125 +62216 -0.086944580078125 +62217 -0.2784423828125 +62218 -0.484832763671875 +62219 -0.729583740234375 +62220 -0.86688232421875 +62221 -0.870391845703125 +62222 -0.86859130859375 +62223 -0.86279296875 +62224 -0.817962646484375 +62225 -0.6116943359375 +62226 -0.3128662109375 +62227 0.039398193359375 +62228 0.422821044921875 +62229 0.805145263671875 +62230 0.870361328125 +62231 0.870361328125 +62232 0.860015869140625 +62233 0.727935791015625 +62234 0.48114013671875 +62235 0.2059326171875 +62236 -0.06103515625 +62237 -0.29913330078125 +62238 -0.516204833984375 +62239 -0.7252197265625 +62240 -0.85980224609375 +62241 -0.870391845703125 +62242 -0.870391845703125 +62243 -0.858062744140625 +62244 -0.673004150390625 +62245 -0.42694091796875 +62246 -0.2100830078125 +62247 -0.0362548828125 +62248 0.10943603515625 +62249 0.23516845703125 +62250 0.373687744140625 +62251 0.517791748046875 +62252 0.602783203125 +62253 0.635711669921875 +62254 0.655181884765625 +62255 0.65948486328125 +62256 0.651275634765625 +62257 0.61846923828125 +62258 0.53753662109375 +62259 0.404144287109375 +62260 0.22186279296875 +62261 0.003997802734375 +62262 -0.22100830078125 +62263 -0.42449951171875 +62264 -0.579833984375 +62265 -0.641876220703125 +62266 -0.6177978515625 +62267 -0.575531005859375 +62268 -0.526336669921875 +62269 -0.42645263671875 +62270 -0.2581787109375 +62271 -0.068695068359375 +62272 0.09222412109375 +62273 0.232147216796875 +62274 0.3509521484375 +62275 0.410064697265625 +62276 0.372955322265625 +62277 0.2554931640625 +62278 0.10711669921875 +62279 -0.052886962890625 +62280 -0.186279296875 +62281 -0.23291015625 +62282 -0.209442138671875 +62283 -0.174163818359375 +62284 -0.126739501953125 +62285 -0.048126220703125 +62286 0.0426025390625 +62287 0.10748291015625 +62288 0.1409912109375 +62289 0.19708251953125 +62290 0.273651123046875 +62291 0.31768798828125 +62292 0.341094970703125 +62293 0.368011474609375 +62294 0.37249755859375 +62295 0.30072021484375 +62296 0.1517333984375 +62297 -0.01470947265625 +62298 -0.1883544921875 +62299 -0.372711181640625 +62300 -0.51397705078125 +62301 -0.57177734375 +62302 -0.53948974609375 +62303 -0.43511962890625 +62304 -0.2962646484375 +62305 -0.161102294921875 +62306 -0.0435791015625 +62307 0.060394287109375 +62308 0.13665771484375 +62309 0.170135498046875 +62310 0.16552734375 +62311 0.15728759765625 +62312 0.150787353515625 +62313 0.12200927734375 +62314 0.080108642578125 +62315 0.05126953125 +62316 0.062896728515625 +62317 0.09271240234375 +62318 0.092987060546875 +62319 0.07855224609375 +62320 0.06427001953125 +62321 0.0347900390625 +62322 -0.01171875 +62323 -0.056060791015625 +62324 -0.055511474609375 +62325 -0.010467529296875 +62326 0.02508544921875 +62327 0.025665283203125 +62328 0.017333984375 +62329 0.00189208984375 +62330 -0.03173828125 +62331 -0.071502685546875 +62332 -0.13543701171875 +62333 -0.219970703125 +62334 -0.300506591796875 +62335 -0.376312255859375 +62336 -0.416107177734375 +62337 -0.371124267578125 +62338 -0.242279052734375 +62339 -0.069732666015625 +62340 0.125640869140625 +62341 0.31268310546875 +62342 0.45501708984375 +62343 0.554779052734375 +62344 0.61065673828125 +62345 0.610931396484375 +62346 0.531463623046875 +62347 0.3883056640625 +62348 0.23468017578125 +62349 0.095245361328125 +62350 -0.00396728515625 +62351 -0.04852294921875 +62352 -0.055145263671875 +62353 -0.0758056640625 +62354 -0.138702392578125 +62355 -0.209197998046875 +62356 -0.289031982421875 +62357 -0.37884521484375 +62358 -0.456329345703125 +62359 -0.51641845703125 +62360 -0.519287109375 +62361 -0.458251953125 +62362 -0.384796142578125 +62363 -0.323699951171875 +62364 -0.269287109375 +62365 -0.1951904296875 +62366 -0.100006103515625 +62367 -0.01055908203125 +62368 0.1033935546875 +62369 0.24908447265625 +62370 0.373199462890625 +62371 0.45806884765625 +62372 0.511474609375 +62373 0.565399169921875 +62374 0.61138916015625 +62375 0.5897216796875 +62376 0.4906005859375 +62377 0.33148193359375 +62378 0.147796630859375 +62379 -0.01873779296875 +62380 -0.140289306640625 +62381 -0.191986083984375 +62382 -0.184295654296875 +62383 -0.161834716796875 +62384 -0.166595458984375 +62385 -0.19390869140625 +62386 -0.22442626953125 +62387 -0.279754638671875 +62388 -0.3389892578125 +62389 -0.3543701171875 +62390 -0.348175048828125 +62391 -0.32598876953125 +62392 -0.2581787109375 +62393 -0.139801025390625 +62394 0.014617919921875 +62395 0.144378662109375 +62396 0.221038818359375 +62397 0.27069091796875 +62398 0.294036865234375 +62399 0.311767578125 +62400 0.339141845703125 +62401 0.360260009765625 +62402 0.360504150390625 +62403 0.308380126953125 +62404 0.18170166015625 +62405 0.0047607421875 +62406 -0.17559814453125 +62407 -0.3143310546875 +62408 -0.36785888671875 +62409 -0.36248779296875 +62410 -0.343536376953125 +62411 -0.3018798828125 +62412 -0.231414794921875 +62413 -0.117645263671875 +62414 0.007049560546875 +62415 0.087982177734375 +62416 0.13946533203125 +62417 0.17425537109375 +62418 0.188201904296875 +62419 0.171234130859375 +62420 0.118438720703125 +62421 0.05706787109375 +62422 -0.010711669921875 +62423 -0.0914306640625 +62424 -0.162322998046875 +62425 -0.194549560546875 +62426 -0.1492919921875 +62427 -0.02166748046875 +62428 0.124053955078125 +62429 0.211151123046875 +62430 0.240447998046875 +62431 0.242218017578125 +62432 0.2257080078125 +62433 0.194366455078125 +62434 0.115509033203125 +62435 0.0128173828125 +62436 -0.053802490234375 +62437 -0.110626220703125 +62438 -0.199493408203125 +62439 -0.29437255859375 +62440 -0.33221435546875 +62441 -0.27972412109375 +62442 -0.185333251953125 +62443 -0.128204345703125 +62444 -0.115692138671875 +62445 -0.116455078125 +62446 -0.105926513671875 +62447 -0.053955078125 +62448 0.048797607421875 +62449 0.157318115234375 +62450 0.212005615234375 +62451 0.218475341796875 +62452 0.23724365234375 +62453 0.30535888671875 +62454 0.38128662109375 +62455 0.404449462890625 +62456 0.3944091796875 +62457 0.3885498046875 +62458 0.362640380859375 +62459 0.27362060546875 +62460 0.11712646484375 +62461 -0.054901123046875 +62462 -0.19085693359375 +62463 -0.28570556640625 +62464 -0.339263916015625 +62465 -0.3775634765625 +62466 -0.445709228515625 +62467 -0.535064697265625 +62468 -0.629058837890625 +62469 -0.697601318359375 +62470 -0.70391845703125 +62471 -0.6424560546875 +62472 -0.491241455078125 +62473 -0.265716552734375 +62474 -0.023712158203125 +62475 0.201751708984375 +62476 0.375823974609375 +62477 0.485076904296875 +62478 0.56884765625 +62479 0.634765625 +62480 0.63763427734375 +62481 0.5660400390625 +62482 0.4720458984375 +62483 0.40692138671875 +62484 0.3778076171875 +62485 0.376953125 +62486 0.371978759765625 +62487 0.313140869140625 +62488 0.184417724609375 +62489 0.011199951171875 +62490 -0.171051025390625 +62491 -0.33740234375 +62492 -0.47198486328125 +62493 -0.560394287109375 +62494 -0.58056640625 +62495 -0.54754638671875 +62496 -0.508575439453125 +62497 -0.459503173828125 +62498 -0.394378662109375 +62499 -0.35260009765625 +62500 -0.31170654296875 +62501 -0.197418212890625 +62502 -0.007965087890625 +62503 0.207489013671875 +62504 0.409210205078125 +62505 0.57208251953125 +62506 0.66595458984375 +62507 0.65875244140625 +62508 0.56744384765625 +62509 0.431396484375 +62510 0.29443359375 +62511 0.182464599609375 +62512 0.06365966796875 +62513 -0.075958251953125 +62514 -0.189422607421875 +62515 -0.271942138671875 +62516 -0.342529296875 +62517 -0.364166259765625 +62518 -0.327239990234375 +62519 -0.2769775390625 +62520 -0.253692626953125 +62521 -0.24365234375 +62522 -0.1983642578125 +62523 -0.116241455078125 +62524 -0.036834716796875 +62525 0.034881591796875 +62526 0.09124755859375 +62527 0.10888671875 +62528 0.125518798828125 +62529 0.15771484375 +62530 0.17828369140625 +62531 0.17108154296875 +62532 0.129974365234375 +62533 0.082427978515625 +62534 0.027679443359375 +62535 -0.065643310546875 +62536 -0.15936279296875 +62537 -0.21307373046875 +62538 -0.234649658203125 +62539 -0.2001953125 +62540 -0.119171142578125 +62541 -0.024749755859375 +62542 0.085784912109375 +62543 0.178131103515625 +62544 0.215576171875 +62545 0.211456298828125 +62546 0.17523193359375 +62547 0.128753662109375 +62548 0.1019287109375 +62549 0.0743408203125 +62550 0.04327392578125 +62551 0.038177490234375 +62552 0.076263427734375 +62553 0.14105224609375 +62554 0.186431884765625 +62555 0.188812255859375 +62556 0.1390380859375 +62557 0.041778564453125 +62558 -0.079437255859375 +62559 -0.219390869140625 +62560 -0.367828369140625 +62561 -0.494873046875 +62562 -0.556243896484375 +62563 -0.508697509765625 +62564 -0.3756103515625 +62565 -0.218902587890625 +62566 -0.063751220703125 +62567 0.091552734375 +62568 0.23602294921875 +62569 0.342987060546875 +62570 0.39520263671875 +62571 0.389373779296875 +62572 0.324249267578125 +62573 0.224090576171875 +62574 0.124267578125 +62575 0.037078857421875 +62576 -0.010101318359375 +62577 -0.019439697265625 +62578 -0.022796630859375 +62579 -0.001556396484375 +62580 0.056304931640625 +62581 0.106719970703125 +62582 0.096893310546875 +62583 0.042694091796875 +62584 -0.018035888671875 +62585 -0.07586669921875 +62586 -0.11944580078125 +62587 -0.15972900390625 +62588 -0.202606201171875 +62589 -0.24859619140625 +62590 -0.30517578125 +62591 -0.36212158203125 +62592 -0.39141845703125 +62593 -0.35528564453125 +62594 -0.249969482421875 +62595 -0.092864990234375 +62596 0.08905029296875 +62597 0.2352294921875 +62598 0.318817138671875 +62599 0.358642578125 +62600 0.347747802734375 +62601 0.28564453125 +62602 0.223175048828125 +62603 0.196746826171875 +62604 0.179840087890625 +62605 0.155548095703125 +62606 0.151214599609375 +62607 0.156951904296875 +62608 0.13177490234375 +62609 0.100799560546875 +62610 0.087127685546875 +62611 0.05487060546875 +62612 -0.009002685546875 +62613 -0.10400390625 +62614 -0.229400634765625 +62615 -0.35552978515625 +62616 -0.441925048828125 +62617 -0.473846435546875 +62618 -0.464813232421875 +62619 -0.419097900390625 +62620 -0.334320068359375 +62621 -0.227935791015625 +62622 -0.12347412109375 +62623 -0.02764892578125 +62624 0.077667236328125 +62625 0.2132568359375 +62626 0.38885498046875 +62627 0.582794189453125 +62628 0.734039306640625 +62629 0.800140380859375 +62630 0.7783203125 +62631 0.6651611328125 +62632 0.45965576171875 +62633 0.199188232421875 +62634 -0.050689697265625 +62635 -0.23297119140625 +62636 -0.33013916015625 +62637 -0.368408203125 +62638 -0.378936767578125 +62639 -0.376983642578125 +62640 -0.37969970703125 +62641 -0.391510009765625 +62642 -0.385345458984375 +62643 -0.3419189453125 +62644 -0.28289794921875 +62645 -0.251617431640625 +62646 -0.266143798828125 +62647 -0.273345947265625 +62648 -0.216796875 +62649 -0.128265380859375 +62650 -0.068145751953125 +62651 -0.0430908203125 +62652 -0.024444580078125 +62653 0.020721435546875 +62654 0.124481201171875 +62655 0.25787353515625 +62656 0.379119873046875 +62657 0.47991943359375 +62658 0.5281982421875 +62659 0.511138916015625 +62660 0.456207275390625 +62661 0.407470703125 +62662 0.383758544921875 +62663 0.35687255859375 +62664 0.31182861328125 +62665 0.250885009765625 +62666 0.1654052734375 +62667 0.035247802734375 +62668 -0.142059326171875 +62669 -0.33563232421875 +62670 -0.5345458984375 +62671 -0.72186279296875 +62672 -0.836669921875 +62673 -0.8326416015625 +62674 -0.7296142578125 +62675 -0.582550048828125 +62676 -0.440093994140625 +62677 -0.324310302734375 +62678 -0.20147705078125 +62679 -0.044647216796875 +62680 0.103973388671875 +62681 0.202392578125 +62682 0.264495849609375 +62683 0.338897705078125 +62684 0.443817138671875 +62685 0.545074462890625 +62686 0.6173095703125 +62687 0.6524658203125 +62688 0.66339111328125 +62689 0.6561279296875 +62690 0.606781005859375 +62691 0.501190185546875 +62692 0.352783203125 +62693 0.176544189453125 +62694 -0.034820556640625 +62695 -0.258209228515625 +62696 -0.44244384765625 +62697 -0.5753173828125 +62698 -0.65203857421875 +62699 -0.641632080078125 +62700 -0.562164306640625 +62701 -0.458038330078125 +62702 -0.350555419921875 +62703 -0.260528564453125 +62704 -0.192108154296875 +62705 -0.141937255859375 +62706 -0.1021728515625 +62707 -0.062896728515625 +62708 -0.011932373046875 +62709 0.062835693359375 +62710 0.148712158203125 +62711 0.241729736328125 +62712 0.34912109375 +62713 0.457305908203125 +62714 0.54388427734375 +62715 0.5728759765625 +62716 0.506591796875 +62717 0.351226806640625 +62718 0.146514892578125 +62719 -0.05523681640625 +62720 -0.21624755859375 +62721 -0.334930419921875 +62722 -0.402984619140625 +62723 -0.4412841796875 +62724 -0.49578857421875 +62725 -0.5601806640625 +62726 -0.600738525390625 +62727 -0.584228515625 +62728 -0.47930908203125 +62729 -0.27935791015625 +62730 -0.0089111328125 +62731 0.268798828125 +62732 0.482818603515625 +62733 0.60369873046875 +62734 0.650421142578125 +62735 0.66400146484375 +62736 0.6414794921875 +62737 0.572540283203125 +62738 0.498138427734375 +62739 0.439453125 +62740 0.375518798828125 +62741 0.274505615234375 +62742 0.1087646484375 +62743 -0.099395751953125 +62744 -0.3182373046875 +62745 -0.5489501953125 +62746 -0.7738037109375 +62747 -0.86383056640625 +62748 -0.870391845703125 +62749 -0.86895751953125 +62750 -0.861053466796875 +62751 -0.765869140625 +62752 -0.5301513671875 +62753 -0.214691162109375 +62754 0.137359619140625 +62755 0.474822998046875 +62756 0.76239013671875 +62757 0.867462158203125 +62758 0.870361328125 +62759 0.86480712890625 +62760 0.831817626953125 +62761 0.677581787109375 +62762 0.495880126953125 +62763 0.30767822265625 +62764 0.116180419921875 +62765 -0.110748291015625 +62766 -0.381805419921875 +62767 -0.6572265625 +62768 -0.857421875 +62769 -0.870391845703125 +62770 -0.870391845703125 +62771 -0.86444091796875 +62772 -0.85723876953125 +62773 -0.790008544921875 +62774 -0.62847900390625 +62775 -0.3956298828125 +62776 -0.126708984375 +62777 0.150115966796875 +62778 0.424041748046875 +62779 0.670623779296875 +62780 0.854522705078125 +62781 0.866485595703125 +62782 0.86920166015625 +62783 0.8653564453125 +62784 0.857147216796875 +62785 0.766845703125 +62786 0.628509521484375 +62787 0.462127685546875 +62788 0.297210693359375 +62789 0.14862060546875 +62790 -0.00537109375 +62791 -0.15753173828125 +62792 -0.31304931640625 +62793 -0.48876953125 +62794 -0.6416015625 +62795 -0.751373291015625 +62796 -0.84619140625 +62797 -0.861297607421875 +62798 -0.863250732421875 +62799 -0.856597900390625 +62800 -0.7498779296875 +62801 -0.624542236328125 +62802 -0.47808837890625 +62803 -0.253387451171875 +62804 0.003692626953125 +62805 0.2257080078125 +62806 0.427154541015625 +62807 0.643218994140625 +62808 0.855926513671875 +62809 0.870361328125 +62810 0.870361328125 +62811 0.862762451171875 +62812 0.79669189453125 +62813 0.595794677734375 +62814 0.362152099609375 +62815 0.1270751953125 +62816 -0.086944580078125 +62817 -0.2784423828125 +62818 -0.484832763671875 +62819 -0.729583740234375 +62820 -0.86688232421875 +62821 -0.870391845703125 +62822 -0.86859130859375 +62823 -0.86279296875 +62824 -0.817962646484375 +62825 -0.6116943359375 +62826 -0.3128662109375 +62827 0.039398193359375 +62828 0.422821044921875 +62829 0.805145263671875 +62830 0.870361328125 +62831 0.870361328125 +62832 0.860015869140625 +62833 0.727935791015625 +62834 0.48114013671875 +62835 0.2059326171875 +62836 -0.06103515625 +62837 -0.29913330078125 +62838 -0.516204833984375 +62839 -0.7252197265625 +62840 -0.85980224609375 +62841 -0.870391845703125 +62842 -0.870391845703125 +62843 -0.858062744140625 +62844 -0.673004150390625 +62845 -0.42694091796875 +62846 -0.2100830078125 +62847 -0.0362548828125 +62848 0.10943603515625 +62849 0.23516845703125 +62850 0.373687744140625 +62851 0.517791748046875 +62852 0.602783203125 +62853 0.635711669921875 +62854 0.655181884765625 +62855 0.65948486328125 +62856 0.651275634765625 +62857 0.61846923828125 +62858 0.53753662109375 +62859 0.404144287109375 +62860 0.22186279296875 +62861 0.003997802734375 +62862 -0.22100830078125 +62863 -0.42449951171875 +62864 -0.579833984375 +62865 -0.641876220703125 +62866 -0.6177978515625 +62867 -0.575531005859375 +62868 -0.526336669921875 +62869 -0.42645263671875 +62870 -0.2581787109375 +62871 -0.068695068359375 +62872 0.09222412109375 +62873 0.232147216796875 +62874 0.3509521484375 +62875 0.410064697265625 +62876 0.372955322265625 +62877 0.2554931640625 +62878 0.10711669921875 +62879 -0.052886962890625 +62880 -0.186279296875 +62881 -0.23291015625 +62882 -0.209442138671875 +62883 -0.174163818359375 +62884 -0.126739501953125 +62885 -0.048126220703125 +62886 0.0426025390625 +62887 0.10748291015625 +62888 0.1409912109375 +62889 0.19708251953125 +62890 0.273651123046875 +62891 0.31768798828125 +62892 0.341094970703125 +62893 0.368011474609375 +62894 0.37249755859375 +62895 0.30072021484375 +62896 0.1517333984375 +62897 -0.01470947265625 +62898 -0.1883544921875 +62899 -0.372711181640625 +62900 -0.51397705078125 +62901 -0.57177734375 +62902 -0.53948974609375 +62903 -0.43511962890625 +62904 -0.2962646484375 +62905 -0.161102294921875 +62906 -0.0435791015625 +62907 0.060394287109375 +62908 0.13665771484375 +62909 0.170135498046875 +62910 0.16552734375 +62911 0.15728759765625 +62912 0.150787353515625 +62913 0.12200927734375 +62914 0.080108642578125 +62915 0.05126953125 +62916 0.062896728515625 +62917 0.09271240234375 +62918 0.092987060546875 +62919 0.07855224609375 +62920 0.06427001953125 +62921 0.0347900390625 +62922 -0.01171875 +62923 -0.056060791015625 +62924 -0.055511474609375 +62925 -0.010467529296875 +62926 0.02508544921875 +62927 0.025665283203125 +62928 0.017333984375 +62929 0.00189208984375 +62930 -0.03173828125 +62931 -0.071502685546875 +62932 -0.13543701171875 +62933 -0.219970703125 +62934 -0.300506591796875 +62935 -0.376312255859375 +62936 -0.416107177734375 +62937 -0.371124267578125 +62938 -0.242279052734375 +62939 -0.069732666015625 +62940 0.125640869140625 +62941 0.31268310546875 +62942 0.45501708984375 +62943 0.554779052734375 +62944 0.61065673828125 +62945 0.610931396484375 +62946 0.531463623046875 +62947 0.3883056640625 +62948 0.23468017578125 +62949 0.095245361328125 +62950 -0.00396728515625 +62951 -0.04852294921875 +62952 -0.055145263671875 +62953 -0.0758056640625 +62954 -0.138702392578125 +62955 -0.209197998046875 +62956 -0.289031982421875 +62957 -0.37884521484375 +62958 -0.456329345703125 +62959 -0.51641845703125 +62960 -0.519287109375 +62961 -0.458251953125 +62962 -0.384796142578125 +62963 -0.323699951171875 +62964 -0.269287109375 +62965 -0.1951904296875 +62966 -0.100006103515625 +62967 -0.01055908203125 +62968 0.1033935546875 +62969 0.24908447265625 +62970 0.373199462890625 +62971 0.45806884765625 +62972 0.511474609375 +62973 0.565399169921875 +62974 0.61138916015625 +62975 0.5897216796875 +62976 0.4906005859375 +62977 0.33148193359375 +62978 0.147796630859375 +62979 -0.01873779296875 +62980 -0.140289306640625 +62981 -0.191986083984375 +62982 -0.184295654296875 +62983 -0.161834716796875 +62984 -0.166595458984375 +62985 -0.19390869140625 +62986 -0.22442626953125 +62987 -0.279754638671875 +62988 -0.3389892578125 +62989 -0.3543701171875 +62990 -0.348175048828125 +62991 -0.32598876953125 +62992 -0.2581787109375 +62993 -0.139801025390625 +62994 0.014617919921875 +62995 0.144378662109375 +62996 0.221038818359375 +62997 0.27069091796875 +62998 0.294036865234375 +62999 0.311767578125 +63000 0.339141845703125 +63001 0.360260009765625 +63002 0.360504150390625 +63003 0.308380126953125 +63004 0.18170166015625 +63005 0.0047607421875 +63006 -0.17559814453125 +63007 -0.3143310546875 +63008 -0.36785888671875 +63009 -0.36248779296875 +63010 -0.343536376953125 +63011 -0.3018798828125 +63012 -0.231414794921875 +63013 -0.117645263671875 +63014 0.007049560546875 +63015 0.087982177734375 +63016 0.13946533203125 +63017 0.17425537109375 +63018 0.188201904296875 +63019 0.171234130859375 +63020 0.118438720703125 +63021 0.05706787109375 +63022 -0.010711669921875 +63023 -0.0914306640625 +63024 -0.162322998046875 +63025 -0.194549560546875 +63026 -0.1492919921875 +63027 -0.02166748046875 +63028 0.124053955078125 +63029 0.211151123046875 +63030 0.240447998046875 +63031 0.242218017578125 +63032 0.2257080078125 +63033 0.194366455078125 +63034 0.115509033203125 +63035 0.0128173828125 +63036 -0.053802490234375 +63037 -0.110626220703125 +63038 -0.199493408203125 +63039 -0.29437255859375 +63040 -0.33221435546875 +63041 -0.27972412109375 +63042 -0.185333251953125 +63043 -0.128204345703125 +63044 -0.115692138671875 +63045 -0.116455078125 +63046 -0.105926513671875 +63047 -0.053955078125 +63048 0.048797607421875 +63049 0.157318115234375 +63050 0.212005615234375 +63051 0.218475341796875 +63052 0.23724365234375 +63053 0.30535888671875 +63054 0.38128662109375 +63055 0.404449462890625 +63056 0.3944091796875 +63057 0.3885498046875 +63058 0.362640380859375 +63059 0.27362060546875 +63060 0.11712646484375 +63061 -0.054901123046875 +63062 -0.19085693359375 +63063 -0.28570556640625 +63064 -0.339263916015625 +63065 -0.3775634765625 +63066 -0.445709228515625 +63067 -0.535064697265625 +63068 -0.629058837890625 +63069 -0.697601318359375 +63070 -0.70391845703125 +63071 -0.6424560546875 +63072 -0.491241455078125 +63073 -0.265716552734375 +63074 -0.023712158203125 +63075 0.201751708984375 +63076 0.375823974609375 +63077 0.485076904296875 +63078 0.56884765625 +63079 0.634765625 +63080 0.63763427734375 +63081 0.5660400390625 +63082 0.4720458984375 +63083 0.40692138671875 +63084 0.3778076171875 +63085 0.376953125 +63086 0.371978759765625 +63087 0.313140869140625 +63088 0.184417724609375 +63089 0.011199951171875 +63090 -0.171051025390625 +63091 -0.33740234375 +63092 -0.47198486328125 +63093 -0.560394287109375 +63094 -0.58056640625 +63095 -0.54754638671875 +63096 -0.508575439453125 +63097 -0.459503173828125 +63098 -0.394378662109375 +63099 -0.35260009765625 +63100 -0.31170654296875 +63101 -0.197418212890625 +63102 -0.007965087890625 +63103 0.207489013671875 +63104 0.409210205078125 +63105 0.57208251953125 +63106 0.66595458984375 +63107 0.65875244140625 +63108 0.56744384765625 +63109 0.431396484375 +63110 0.29443359375 +63111 0.182464599609375 +63112 0.06365966796875 +63113 -0.075958251953125 +63114 -0.189422607421875 +63115 -0.271942138671875 +63116 -0.342529296875 +63117 -0.364166259765625 +63118 -0.327239990234375 +63119 -0.2769775390625 +63120 -0.253692626953125 +63121 -0.24365234375 +63122 -0.1983642578125 +63123 -0.116241455078125 +63124 -0.036834716796875 +63125 0.034881591796875 +63126 0.09124755859375 +63127 0.10888671875 +63128 0.125518798828125 +63129 0.15771484375 +63130 0.17828369140625 +63131 0.17108154296875 +63132 0.129974365234375 +63133 0.082427978515625 +63134 0.027679443359375 +63135 -0.065643310546875 +63136 -0.15936279296875 +63137 -0.21307373046875 +63138 -0.234649658203125 +63139 -0.2001953125 +63140 -0.119171142578125 +63141 -0.024749755859375 +63142 0.085784912109375 +63143 0.178131103515625 +63144 0.215576171875 +63145 0.211456298828125 +63146 0.17523193359375 +63147 0.128753662109375 +63148 0.1019287109375 +63149 0.0743408203125 +63150 0.04327392578125 +63151 0.038177490234375 +63152 0.076263427734375 +63153 0.14105224609375 +63154 0.186431884765625 +63155 0.188812255859375 +63156 0.1390380859375 +63157 0.041778564453125 +63158 -0.079437255859375 +63159 -0.219390869140625 +63160 -0.367828369140625 +63161 -0.494873046875 +63162 -0.556243896484375 +63163 -0.508697509765625 +63164 -0.3756103515625 +63165 -0.218902587890625 +63166 -0.063751220703125 +63167 0.091552734375 +63168 0.23602294921875 +63169 0.342987060546875 +63170 0.39520263671875 +63171 0.389373779296875 +63172 0.324249267578125 +63173 0.224090576171875 +63174 0.124267578125 +63175 0.037078857421875 +63176 -0.010101318359375 +63177 -0.019439697265625 +63178 -0.022796630859375 +63179 -0.001556396484375 +63180 0.056304931640625 +63181 0.106719970703125 +63182 0.096893310546875 +63183 0.042694091796875 +63184 -0.018035888671875 +63185 -0.07586669921875 +63186 -0.11944580078125 +63187 -0.15972900390625 +63188 -0.202606201171875 +63189 -0.24859619140625 +63190 -0.30517578125 +63191 -0.36212158203125 +63192 -0.39141845703125 +63193 -0.35528564453125 +63194 -0.249969482421875 +63195 -0.092864990234375 +63196 0.08905029296875 +63197 0.2352294921875 +63198 0.318817138671875 +63199 0.358642578125 +63200 0.347747802734375 +63201 0.28564453125 +63202 0.223175048828125 +63203 0.196746826171875 +63204 0.179840087890625 +63205 0.155548095703125 +63206 0.151214599609375 +63207 0.156951904296875 +63208 0.13177490234375 +63209 0.100799560546875 +63210 0.087127685546875 +63211 0.05487060546875 +63212 -0.009002685546875 +63213 -0.10400390625 +63214 -0.229400634765625 +63215 -0.35552978515625 +63216 -0.441925048828125 +63217 -0.473846435546875 +63218 -0.464813232421875 +63219 -0.419097900390625 +63220 -0.334320068359375 +63221 -0.227935791015625 +63222 -0.12347412109375 +63223 -0.02764892578125 +63224 0.077667236328125 +63225 0.2132568359375 +63226 0.38885498046875 +63227 0.582794189453125 +63228 0.734039306640625 +63229 0.800140380859375 +63230 0.7783203125 +63231 0.6651611328125 +63232 0.45965576171875 +63233 0.199188232421875 +63234 -0.050689697265625 +63235 -0.23297119140625 +63236 -0.33013916015625 +63237 -0.368408203125 +63238 -0.378936767578125 +63239 -0.376983642578125 +63240 -0.37969970703125 +63241 -0.391510009765625 +63242 -0.385345458984375 +63243 -0.3419189453125 +63244 -0.28289794921875 +63245 -0.251617431640625 +63246 -0.266143798828125 +63247 -0.273345947265625 +63248 -0.216796875 +63249 -0.128265380859375 +63250 -0.068145751953125 +63251 -0.0430908203125 +63252 -0.024444580078125 +63253 0.020721435546875 +63254 0.124481201171875 +63255 0.25787353515625 +63256 0.379119873046875 +63257 0.47991943359375 +63258 0.5281982421875 +63259 0.511138916015625 +63260 0.456207275390625 +63261 0.407470703125 +63262 0.383758544921875 +63263 0.35687255859375 +63264 0.31182861328125 +63265 0.250885009765625 +63266 0.1654052734375 +63267 0.035247802734375 +63268 -0.142059326171875 +63269 -0.33563232421875 +63270 -0.5345458984375 +63271 -0.72186279296875 +63272 -0.836669921875 +63273 -0.8326416015625 +63274 -0.7296142578125 +63275 -0.582550048828125 +63276 -0.440093994140625 +63277 -0.324310302734375 +63278 -0.20147705078125 +63279 -0.044647216796875 +63280 0.103973388671875 +63281 0.202392578125 +63282 0.264495849609375 +63283 0.338897705078125 +63284 0.443817138671875 +63285 0.545074462890625 +63286 0.6173095703125 +63287 0.6524658203125 +63288 0.66339111328125 +63289 0.6561279296875 +63290 0.606781005859375 +63291 0.501190185546875 +63292 0.352783203125 +63293 0.176544189453125 +63294 -0.034820556640625 +63295 -0.258209228515625 +63296 -0.44244384765625 +63297 -0.5753173828125 +63298 -0.65203857421875 +63299 -0.641632080078125 +63300 -0.562164306640625 +63301 -0.458038330078125 +63302 -0.350555419921875 +63303 -0.260528564453125 +63304 -0.192108154296875 +63305 -0.141937255859375 +63306 -0.1021728515625 +63307 -0.062896728515625 +63308 -0.011932373046875 +63309 0.062835693359375 +63310 0.148712158203125 +63311 0.241729736328125 +63312 0.34912109375 +63313 0.457305908203125 +63314 0.54388427734375 +63315 0.5728759765625 +63316 0.506591796875 +63317 0.351226806640625 +63318 0.146514892578125 +63319 -0.05523681640625 +63320 -0.21624755859375 +63321 -0.334930419921875 +63322 -0.402984619140625 +63323 -0.4412841796875 +63324 -0.49578857421875 +63325 -0.5601806640625 +63326 -0.600738525390625 +63327 -0.584228515625 +63328 -0.47930908203125 +63329 -0.27935791015625 +63330 -0.0089111328125 +63331 0.268798828125 +63332 0.482818603515625 +63333 0.60369873046875 +63334 0.650421142578125 +63335 0.66400146484375 +63336 0.6414794921875 +63337 0.572540283203125 +63338 0.498138427734375 +63339 0.439453125 +63340 0.375518798828125 +63341 0.274505615234375 +63342 0.1087646484375 +63343 -0.099395751953125 +63344 -0.3182373046875 +63345 -0.5489501953125 +63346 -0.7738037109375 +63347 -0.86383056640625 +63348 -0.870391845703125 +63349 -0.86895751953125 +63350 -0.861053466796875 +63351 -0.765869140625 +63352 -0.5301513671875 +63353 -0.214691162109375 +63354 0.137359619140625 +63355 0.474822998046875 +63356 0.76239013671875 +63357 0.867462158203125 +63358 0.870361328125 +63359 0.86480712890625 +63360 0.831817626953125 +63361 0.677581787109375 +63362 0.495880126953125 +63363 0.30767822265625 +63364 0.116180419921875 +63365 -0.110748291015625 +63366 -0.381805419921875 +63367 -0.6572265625 +63368 -0.857421875 +63369 -0.870391845703125 +63370 -0.870391845703125 +63371 -0.86444091796875 +63372 -0.85723876953125 +63373 -0.790008544921875 +63374 -0.62847900390625 +63375 -0.3956298828125 +63376 -0.126708984375 +63377 0.150115966796875 +63378 0.424041748046875 +63379 0.670623779296875 +63380 0.854522705078125 +63381 0.866485595703125 +63382 0.86920166015625 +63383 0.8653564453125 +63384 0.857147216796875 +63385 0.766845703125 +63386 0.628509521484375 +63387 0.462127685546875 +63388 0.297210693359375 +63389 0.14862060546875 +63390 -0.00537109375 +63391 -0.15753173828125 +63392 -0.31304931640625 +63393 -0.48876953125 +63394 -0.6416015625 +63395 -0.751373291015625 +63396 -0.84619140625 +63397 -0.861297607421875 +63398 -0.863250732421875 +63399 -0.856597900390625 +63400 -0.7498779296875 +63401 -0.624542236328125 +63402 -0.47808837890625 +63403 -0.253387451171875 +63404 0.003692626953125 +63405 0.2257080078125 +63406 0.427154541015625 +63407 0.643218994140625 +63408 0.855926513671875 +63409 0.870361328125 +63410 0.870361328125 +63411 0.862762451171875 +63412 0.79669189453125 +63413 0.595794677734375 +63414 0.362152099609375 +63415 0.1270751953125 +63416 -0.086944580078125 +63417 -0.2784423828125 +63418 -0.484832763671875 +63419 -0.729583740234375 +63420 -0.86688232421875 +63421 -0.870391845703125 +63422 -0.86859130859375 +63423 -0.86279296875 +63424 -0.817962646484375 +63425 -0.6116943359375 +63426 -0.3128662109375 +63427 0.039398193359375 +63428 0.422821044921875 +63429 0.805145263671875 +63430 0.870361328125 +63431 0.870361328125 +63432 0.860015869140625 +63433 0.727935791015625 +63434 0.48114013671875 +63435 0.2059326171875 +63436 -0.06103515625 +63437 -0.29913330078125 +63438 -0.516204833984375 +63439 -0.7252197265625 +63440 -0.85980224609375 +63441 -0.870391845703125 +63442 -0.870391845703125 +63443 -0.858062744140625 +63444 -0.673004150390625 +63445 -0.42694091796875 +63446 -0.2100830078125 +63447 -0.0362548828125 +63448 0.10943603515625 +63449 0.23516845703125 +63450 0.373687744140625 +63451 0.517791748046875 +63452 0.602783203125 +63453 0.635711669921875 +63454 0.655181884765625 +63455 0.65948486328125 +63456 0.651275634765625 +63457 0.61846923828125 +63458 0.53753662109375 +63459 0.404144287109375 +63460 0.22186279296875 +63461 0.003997802734375 +63462 -0.22100830078125 +63463 -0.42449951171875 +63464 -0.579833984375 +63465 -0.641876220703125 +63466 -0.6177978515625 +63467 -0.575531005859375 +63468 -0.526336669921875 +63469 -0.42645263671875 +63470 -0.2581787109375 +63471 -0.068695068359375 +63472 0.09222412109375 +63473 0.232147216796875 +63474 0.3509521484375 +63475 0.410064697265625 +63476 0.372955322265625 +63477 0.2554931640625 +63478 0.10711669921875 +63479 -0.052886962890625 +63480 -0.186279296875 +63481 -0.23291015625 +63482 -0.209442138671875 +63483 -0.174163818359375 +63484 -0.126739501953125 +63485 -0.048126220703125 +63486 0.0426025390625 +63487 0.10748291015625 +63488 0.1409912109375 +63489 0.19708251953125 +63490 0.273651123046875 +63491 0.31768798828125 +63492 0.341094970703125 +63493 0.368011474609375 +63494 0.37249755859375 +63495 0.30072021484375 +63496 0.1517333984375 +63497 -0.01470947265625 +63498 -0.1883544921875 +63499 -0.372711181640625 +63500 -0.51397705078125 +63501 -0.57177734375 +63502 -0.53948974609375 +63503 -0.43511962890625 +63504 -0.2962646484375 +63505 -0.161102294921875 +63506 -0.0435791015625 +63507 0.060394287109375 +63508 0.13665771484375 +63509 0.170135498046875 +63510 0.16552734375 +63511 0.15728759765625 +63512 0.150787353515625 +63513 0.12200927734375 +63514 0.080108642578125 +63515 0.05126953125 +63516 0.062896728515625 +63517 0.09271240234375 +63518 0.092987060546875 +63519 0.07855224609375 +63520 0.06427001953125 +63521 0.0347900390625 +63522 -0.01171875 +63523 -0.056060791015625 +63524 -0.055511474609375 +63525 -0.010467529296875 +63526 0.02508544921875 +63527 0.025665283203125 +63528 0.017333984375 +63529 0.00189208984375 +63530 -0.03173828125 +63531 -0.071502685546875 +63532 -0.13543701171875 +63533 -0.219970703125 +63534 -0.300506591796875 +63535 -0.376312255859375 +63536 -0.416107177734375 +63537 -0.371124267578125 +63538 -0.242279052734375 +63539 -0.069732666015625 +63540 0.125640869140625 +63541 0.31268310546875 +63542 0.45501708984375 +63543 0.554779052734375 +63544 0.61065673828125 +63545 0.610931396484375 +63546 0.531463623046875 +63547 0.3883056640625 +63548 0.23468017578125 +63549 0.095245361328125 +63550 -0.00396728515625 +63551 -0.04852294921875 +63552 -0.055145263671875 +63553 -0.0758056640625 +63554 -0.138702392578125 +63555 -0.209197998046875 +63556 -0.289031982421875 +63557 -0.37884521484375 +63558 -0.456329345703125 +63559 -0.51641845703125 +63560 -0.519287109375 +63561 -0.458251953125 +63562 -0.384796142578125 +63563 -0.323699951171875 +63564 -0.269287109375 +63565 -0.1951904296875 +63566 -0.100006103515625 +63567 -0.01055908203125 +63568 0.1033935546875 +63569 0.24908447265625 +63570 0.373199462890625 +63571 0.45806884765625 +63572 0.511474609375 +63573 0.565399169921875 +63574 0.61138916015625 +63575 0.5897216796875 +63576 0.4906005859375 +63577 0.33148193359375 +63578 0.147796630859375 +63579 -0.01873779296875 +63580 -0.140289306640625 +63581 -0.191986083984375 +63582 -0.184295654296875 +63583 -0.161834716796875 +63584 -0.166595458984375 +63585 -0.19390869140625 +63586 -0.22442626953125 +63587 -0.279754638671875 +63588 -0.3389892578125 +63589 -0.3543701171875 +63590 -0.348175048828125 +63591 -0.32598876953125 +63592 -0.2581787109375 +63593 -0.139801025390625 +63594 0.014617919921875 +63595 0.144378662109375 +63596 0.221038818359375 +63597 0.27069091796875 +63598 0.294036865234375 +63599 0.311767578125 +63600 0.339141845703125 +63601 0.360260009765625 +63602 0.360504150390625 +63603 0.308380126953125 +63604 0.18170166015625 +63605 0.0047607421875 +63606 -0.17559814453125 +63607 -0.3143310546875 +63608 -0.36785888671875 +63609 -0.36248779296875 +63610 -0.343536376953125 +63611 -0.3018798828125 +63612 -0.231414794921875 +63613 -0.117645263671875 +63614 0.007049560546875 +63615 0.087982177734375 +63616 0.13946533203125 +63617 0.17425537109375 +63618 0.188201904296875 +63619 0.171234130859375 +63620 0.118438720703125 +63621 0.05706787109375 +63622 -0.010711669921875 +63623 -0.0914306640625 +63624 -0.162322998046875 +63625 -0.194549560546875 +63626 -0.1492919921875 +63627 -0.02166748046875 +63628 0.124053955078125 +63629 0.211151123046875 +63630 0.240447998046875 +63631 0.242218017578125 +63632 0.2257080078125 +63633 0.194366455078125 +63634 0.115509033203125 +63635 0.0128173828125 +63636 -0.053802490234375 +63637 -0.110626220703125 +63638 -0.199493408203125 +63639 -0.29437255859375 +63640 -0.33221435546875 +63641 -0.27972412109375 +63642 -0.185333251953125 +63643 -0.128204345703125 +63644 -0.115692138671875 +63645 -0.116455078125 +63646 -0.105926513671875 +63647 -0.053955078125 +63648 0.048797607421875 +63649 0.157318115234375 +63650 0.212005615234375 +63651 0.218475341796875 +63652 0.23724365234375 +63653 0.30535888671875 +63654 0.38128662109375 +63655 0.404449462890625 +63656 0.3944091796875 +63657 0.3885498046875 +63658 0.362640380859375 +63659 0.27362060546875 +63660 0.11712646484375 +63661 -0.054901123046875 +63662 -0.19085693359375 +63663 -0.28570556640625 +63664 -0.339263916015625 +63665 -0.3775634765625 +63666 -0.445709228515625 +63667 -0.535064697265625 +63668 -0.629058837890625 +63669 -0.697601318359375 +63670 -0.70391845703125 +63671 -0.6424560546875 +63672 -0.491241455078125 +63673 -0.265716552734375 +63674 -0.023712158203125 +63675 0.201751708984375 +63676 0.375823974609375 +63677 0.485076904296875 +63678 0.56884765625 +63679 0.634765625 +63680 0.63763427734375 +63681 0.5660400390625 +63682 0.4720458984375 +63683 0.40692138671875 +63684 0.3778076171875 +63685 0.376953125 +63686 0.371978759765625 +63687 0.313140869140625 +63688 0.184417724609375 +63689 0.011199951171875 +63690 -0.171051025390625 +63691 -0.33740234375 +63692 -0.47198486328125 +63693 -0.560394287109375 +63694 -0.58056640625 +63695 -0.54754638671875 +63696 -0.508575439453125 +63697 -0.459503173828125 +63698 -0.394378662109375 +63699 -0.35260009765625 +63700 -0.31170654296875 +63701 -0.197418212890625 +63702 -0.007965087890625 +63703 0.207489013671875 +63704 0.409210205078125 +63705 0.57208251953125 +63706 0.66595458984375 +63707 0.65875244140625 +63708 0.56744384765625 +63709 0.431396484375 +63710 0.29443359375 +63711 0.182464599609375 +63712 0.06365966796875 +63713 -0.075958251953125 +63714 -0.189422607421875 +63715 -0.271942138671875 +63716 -0.342529296875 +63717 -0.364166259765625 +63718 -0.327239990234375 +63719 -0.2769775390625 +63720 -0.253692626953125 +63721 -0.24365234375 +63722 -0.1983642578125 +63723 -0.116241455078125 +63724 -0.036834716796875 +63725 0.034881591796875 +63726 0.09124755859375 +63727 0.10888671875 +63728 0.125518798828125 +63729 0.15771484375 +63730 0.17828369140625 +63731 0.17108154296875 +63732 0.129974365234375 +63733 0.082427978515625 +63734 0.027679443359375 +63735 -0.065643310546875 +63736 -0.15936279296875 +63737 -0.21307373046875 +63738 -0.234649658203125 +63739 -0.2001953125 +63740 -0.119171142578125 +63741 -0.024749755859375 +63742 0.085784912109375 +63743 0.178131103515625 +63744 0.215576171875 +63745 0.211456298828125 +63746 0.17523193359375 +63747 0.128753662109375 +63748 0.1019287109375 +63749 0.0743408203125 +63750 0.04327392578125 +63751 0.038177490234375 +63752 0.076263427734375 +63753 0.14105224609375 +63754 0.186431884765625 +63755 0.188812255859375 +63756 0.1390380859375 +63757 0.041778564453125 +63758 -0.079437255859375 +63759 -0.219390869140625 +63760 -0.367828369140625 +63761 -0.494873046875 +63762 -0.556243896484375 +63763 -0.508697509765625 +63764 -0.3756103515625 +63765 -0.218902587890625 +63766 -0.063751220703125 +63767 0.091552734375 +63768 0.23602294921875 +63769 0.342987060546875 +63770 0.39520263671875 +63771 0.389373779296875 +63772 0.324249267578125 +63773 0.224090576171875 +63774 0.124267578125 +63775 0.037078857421875 +63776 -0.010101318359375 +63777 -0.019439697265625 +63778 -0.022796630859375 +63779 -0.001556396484375 +63780 0.056304931640625 +63781 0.106719970703125 +63782 0.096893310546875 +63783 0.042694091796875 +63784 -0.018035888671875 +63785 -0.07586669921875 +63786 -0.11944580078125 +63787 -0.15972900390625 +63788 -0.202606201171875 +63789 -0.24859619140625 +63790 -0.30517578125 +63791 -0.36212158203125 +63792 -0.39141845703125 +63793 -0.35528564453125 +63794 -0.249969482421875 +63795 -0.092864990234375 +63796 0.08905029296875 +63797 0.2352294921875 +63798 0.318817138671875 +63799 0.358642578125 +63800 0.347747802734375 +63801 0.28564453125 +63802 0.223175048828125 +63803 0.196746826171875 +63804 0.179840087890625 +63805 0.155548095703125 +63806 0.151214599609375 +63807 0.156951904296875 +63808 0.13177490234375 +63809 0.100799560546875 +63810 0.087127685546875 +63811 0.05487060546875 +63812 -0.009002685546875 +63813 -0.10400390625 +63814 -0.229400634765625 +63815 -0.35552978515625 +63816 -0.441925048828125 +63817 -0.473846435546875 +63818 -0.464813232421875 +63819 -0.419097900390625 +63820 -0.334320068359375 +63821 -0.227935791015625 +63822 -0.12347412109375 +63823 -0.02764892578125 +63824 0.077667236328125 +63825 0.2132568359375 +63826 0.38885498046875 +63827 0.582794189453125 +63828 0.734039306640625 +63829 0.800140380859375 +63830 0.7783203125 +63831 0.6651611328125 +63832 0.45965576171875 +63833 0.199188232421875 +63834 -0.050689697265625 +63835 -0.23297119140625 +63836 -0.33013916015625 +63837 -0.368408203125 +63838 -0.378936767578125 +63839 -0.376983642578125 +63840 -0.37969970703125 +63841 -0.391510009765625 +63842 -0.385345458984375 +63843 -0.3419189453125 +63844 -0.28289794921875 +63845 -0.251617431640625 +63846 -0.266143798828125 +63847 -0.273345947265625 +63848 -0.216796875 +63849 -0.128265380859375 +63850 -0.068145751953125 +63851 -0.0430908203125 +63852 -0.024444580078125 +63853 0.020721435546875 +63854 0.124481201171875 +63855 0.25787353515625 +63856 0.379119873046875 +63857 0.47991943359375 +63858 0.5281982421875 +63859 0.511138916015625 +63860 0.456207275390625 +63861 0.407470703125 +63862 0.383758544921875 +63863 0.35687255859375 +63864 0.31182861328125 +63865 0.250885009765625 +63866 0.1654052734375 +63867 0.035247802734375 +63868 -0.142059326171875 +63869 -0.33563232421875 +63870 -0.5345458984375 +63871 -0.72186279296875 +63872 -0.836669921875 +63873 -0.8326416015625 +63874 -0.7296142578125 +63875 -0.582550048828125 +63876 -0.440093994140625 +63877 -0.324310302734375 +63878 -0.20147705078125 +63879 -0.044647216796875 +63880 0.103973388671875 +63881 0.202392578125 +63882 0.264495849609375 +63883 0.338897705078125 +63884 0.443817138671875 +63885 0.545074462890625 +63886 0.6173095703125 +63887 0.6524658203125 +63888 0.66339111328125 +63889 0.6561279296875 +63890 0.606781005859375 +63891 0.501190185546875 +63892 0.352783203125 +63893 0.176544189453125 +63894 -0.034820556640625 +63895 -0.258209228515625 +63896 -0.44244384765625 +63897 -0.5753173828125 +63898 -0.65203857421875 +63899 -0.641632080078125 +63900 -0.562164306640625 +63901 -0.458038330078125 +63902 -0.350555419921875 +63903 -0.260528564453125 +63904 -0.192108154296875 +63905 -0.141937255859375 +63906 -0.1021728515625 +63907 -0.062896728515625 +63908 -0.011932373046875 +63909 0.062835693359375 +63910 0.148712158203125 +63911 0.241729736328125 +63912 0.34912109375 +63913 0.457305908203125 +63914 0.54388427734375 +63915 0.5728759765625 +63916 0.506591796875 +63917 0.351226806640625 +63918 0.146514892578125 +63919 -0.05523681640625 +63920 -0.21624755859375 +63921 -0.334930419921875 +63922 -0.402984619140625 +63923 -0.4412841796875 +63924 -0.49578857421875 +63925 -0.5601806640625 +63926 -0.600738525390625 +63927 -0.584228515625 +63928 -0.47930908203125 +63929 -0.27935791015625 +63930 -0.0089111328125 +63931 0.268798828125 +63932 0.482818603515625 +63933 0.60369873046875 +63934 0.650421142578125 +63935 0.66400146484375 +63936 0.6414794921875 +63937 0.572540283203125 +63938 0.498138427734375 +63939 0.439453125 +63940 0.375518798828125 +63941 0.274505615234375 +63942 0.1087646484375 +63943 -0.099395751953125 +63944 -0.3182373046875 +63945 -0.5489501953125 +63946 -0.7738037109375 +63947 -0.86383056640625 +63948 -0.870391845703125 +63949 -0.86895751953125 +63950 -0.861053466796875 +63951 -0.765869140625 +63952 -0.5301513671875 +63953 -0.214691162109375 +63954 0.137359619140625 +63955 0.474822998046875 +63956 0.76239013671875 +63957 0.867462158203125 +63958 0.870361328125 +63959 0.86480712890625 +63960 0.831817626953125 +63961 0.677581787109375 +63962 0.495880126953125 +63963 0.30767822265625 +63964 0.116180419921875 +63965 -0.110748291015625 +63966 -0.381805419921875 +63967 -0.6572265625 +63968 -0.857421875 +63969 -0.870391845703125 +63970 -0.870391845703125 +63971 -0.86444091796875 +63972 -0.85723876953125 +63973 -0.790008544921875 +63974 -0.62847900390625 +63975 -0.3956298828125 +63976 -0.126708984375 +63977 0.150115966796875 +63978 0.424041748046875 +63979 0.670623779296875 +63980 0.854522705078125 +63981 0.866485595703125 +63982 0.86920166015625 +63983 0.8653564453125 +63984 0.857147216796875 +63985 0.766845703125 +63986 0.628509521484375 +63987 0.462127685546875 +63988 0.297210693359375 +63989 0.14862060546875 +63990 -0.00537109375 +63991 -0.15753173828125 +63992 -0.31304931640625 +63993 -0.48876953125 +63994 -0.6416015625 +63995 -0.751373291015625 +63996 -0.84619140625 +63997 -0.861297607421875 +63998 -0.863250732421875 +63999 -0.856597900390625 +64000 -0.7498779296875 +64001 -0.624542236328125 +64002 -0.47808837890625 +64003 -0.253387451171875 +64004 0.003692626953125 +64005 0.2257080078125 +64006 0.427154541015625 +64007 0.643218994140625 +64008 0.855926513671875 +64009 0.870361328125 +64010 0.870361328125 +64011 0.862762451171875 +64012 0.79669189453125 +64013 0.595794677734375 +64014 0.362152099609375 +64015 0.1270751953125 +64016 -0.086944580078125 +64017 -0.2784423828125 +64018 -0.484832763671875 +64019 -0.729583740234375 +64020 -0.86688232421875 +64021 -0.870391845703125 +64022 -0.86859130859375 +64023 -0.86279296875 +64024 -0.817962646484375 +64025 -0.6116943359375 +64026 -0.3128662109375 +64027 0.039398193359375 +64028 0.422821044921875 +64029 0.805145263671875 +64030 0.870361328125 +64031 0.870361328125 +64032 0.860015869140625 +64033 0.727935791015625 +64034 0.48114013671875 +64035 0.2059326171875 +64036 -0.06103515625 +64037 -0.29913330078125 +64038 -0.516204833984375 +64039 -0.7252197265625 +64040 -0.85980224609375 +64041 -0.870391845703125 +64042 -0.870391845703125 +64043 -0.858062744140625 +64044 -0.673004150390625 +64045 -0.42694091796875 +64046 -0.2100830078125 +64047 -0.0362548828125 +64048 0.10943603515625 +64049 0.23516845703125 +64050 0.373687744140625 +64051 0.517791748046875 +64052 0.602783203125 +64053 0.635711669921875 +64054 0.655181884765625 +64055 0.65948486328125 +64056 0.651275634765625 +64057 0.61846923828125 +64058 0.53753662109375 +64059 0.404144287109375 +64060 0.22186279296875 +64061 0.003997802734375 +64062 -0.22100830078125 +64063 -0.42449951171875 +64064 -0.579833984375 +64065 -0.641876220703125 +64066 -0.6177978515625 +64067 -0.575531005859375 +64068 -0.526336669921875 +64069 -0.42645263671875 +64070 -0.2581787109375 +64071 -0.068695068359375 +64072 0.09222412109375 +64073 0.232147216796875 +64074 0.3509521484375 +64075 0.410064697265625 +64076 0.372955322265625 +64077 0.2554931640625 +64078 0.10711669921875 +64079 -0.052886962890625 +64080 -0.186279296875 +64081 -0.23291015625 +64082 -0.209442138671875 +64083 -0.174163818359375 +64084 -0.126739501953125 +64085 -0.048126220703125 +64086 0.0426025390625 +64087 0.10748291015625 +64088 0.1409912109375 +64089 0.19708251953125 +64090 0.273651123046875 +64091 0.31768798828125 +64092 0.341094970703125 +64093 0.368011474609375 +64094 0.37249755859375 +64095 0.30072021484375 +64096 0.1517333984375 +64097 -0.01470947265625 +64098 -0.1883544921875 +64099 -0.372711181640625 +64100 -0.51397705078125 +64101 -0.57177734375 +64102 -0.53948974609375 +64103 -0.43511962890625 +64104 -0.2962646484375 +64105 -0.161102294921875 +64106 -0.0435791015625 +64107 0.060394287109375 +64108 0.13665771484375 +64109 0.170135498046875 +64110 0.16552734375 +64111 0.15728759765625 +64112 0.150787353515625 +64113 0.12200927734375 +64114 0.080108642578125 +64115 0.05126953125 +64116 0.062896728515625 +64117 0.09271240234375 +64118 0.092987060546875 +64119 0.07855224609375 +64120 0.06427001953125 +64121 0.0347900390625 +64122 -0.01171875 +64123 -0.056060791015625 +64124 -0.055511474609375 +64125 -0.010467529296875 +64126 0.02508544921875 +64127 0.025665283203125 +64128 0.017333984375 +64129 0.00189208984375 +64130 -0.03173828125 +64131 -0.071502685546875 +64132 -0.13543701171875 +64133 -0.219970703125 +64134 -0.300506591796875 +64135 -0.376312255859375 +64136 -0.416107177734375 +64137 -0.371124267578125 +64138 -0.242279052734375 +64139 -0.069732666015625 +64140 0.125640869140625 +64141 0.31268310546875 +64142 0.45501708984375 +64143 0.554779052734375 +64144 0.61065673828125 +64145 0.610931396484375 +64146 0.531463623046875 +64147 0.3883056640625 +64148 0.23468017578125 +64149 0.095245361328125 +64150 -0.00396728515625 +64151 -0.04852294921875 +64152 -0.055145263671875 +64153 -0.0758056640625 +64154 -0.138702392578125 +64155 -0.209197998046875 +64156 -0.289031982421875 +64157 -0.37884521484375 +64158 -0.456329345703125 +64159 -0.51641845703125 +64160 -0.519287109375 +64161 -0.458251953125 +64162 -0.384796142578125 +64163 -0.323699951171875 +64164 -0.269287109375 +64165 -0.1951904296875 +64166 -0.100006103515625 +64167 -0.01055908203125 +64168 0.1033935546875 +64169 0.24908447265625 +64170 0.373199462890625 +64171 0.45806884765625 +64172 0.511474609375 +64173 0.565399169921875 +64174 0.61138916015625 +64175 0.5897216796875 +64176 0.4906005859375 +64177 0.33148193359375 +64178 0.147796630859375 +64179 -0.01873779296875 +64180 -0.140289306640625 +64181 -0.191986083984375 +64182 -0.184295654296875 +64183 -0.161834716796875 +64184 -0.166595458984375 +64185 -0.19390869140625 +64186 -0.22442626953125 +64187 -0.279754638671875 +64188 -0.3389892578125 +64189 -0.3543701171875 +64190 -0.348175048828125 +64191 -0.32598876953125 +64192 -0.2581787109375 +64193 -0.139801025390625 +64194 0.014617919921875 +64195 0.144378662109375 +64196 0.221038818359375 +64197 0.27069091796875 +64198 0.294036865234375 +64199 0.311767578125 +64200 0.339141845703125 +64201 0.360260009765625 +64202 0.360504150390625 +64203 0.308380126953125 +64204 0.18170166015625 +64205 0.0047607421875 +64206 -0.17559814453125 +64207 -0.3143310546875 +64208 -0.36785888671875 +64209 -0.36248779296875 +64210 -0.343536376953125 +64211 -0.3018798828125 +64212 -0.231414794921875 +64213 -0.117645263671875 +64214 0.007049560546875 +64215 0.087982177734375 +64216 0.13946533203125 +64217 0.17425537109375 +64218 0.188201904296875 +64219 0.171234130859375 +64220 0.118438720703125 +64221 0.05706787109375 +64222 -0.010711669921875 +64223 -0.0914306640625 +64224 -0.162322998046875 +64225 -0.194549560546875 +64226 -0.1492919921875 +64227 -0.02166748046875 +64228 0.124053955078125 +64229 0.211151123046875 +64230 0.240447998046875 +64231 0.242218017578125 +64232 0.2257080078125 +64233 0.194366455078125 +64234 0.115509033203125 +64235 0.0128173828125 +64236 -0.053802490234375 +64237 -0.110626220703125 +64238 -0.199493408203125 +64239 -0.29437255859375 +64240 -0.33221435546875 +64241 -0.27972412109375 +64242 -0.185333251953125 +64243 -0.128204345703125 +64244 -0.115692138671875 +64245 -0.116455078125 +64246 -0.105926513671875 +64247 -0.053955078125 +64248 0.048797607421875 +64249 0.157318115234375 +64250 0.212005615234375 +64251 0.218475341796875 +64252 0.23724365234375 +64253 0.30535888671875 +64254 0.38128662109375 +64255 0.404449462890625 +64256 0.3944091796875 +64257 0.3885498046875 +64258 0.362640380859375 +64259 0.27362060546875 +64260 0.11712646484375 +64261 -0.054901123046875 +64262 -0.19085693359375 +64263 -0.28570556640625 +64264 -0.339263916015625 +64265 -0.3775634765625 +64266 -0.445709228515625 +64267 -0.535064697265625 +64268 -0.629058837890625 +64269 -0.697601318359375 +64270 -0.70391845703125 +64271 -0.6424560546875 +64272 -0.491241455078125 +64273 -0.265716552734375 +64274 -0.023712158203125 +64275 0.201751708984375 +64276 0.375823974609375 +64277 0.485076904296875 +64278 0.56884765625 +64279 0.634765625 +64280 0.63763427734375 +64281 0.5660400390625 +64282 0.4720458984375 +64283 0.40692138671875 +64284 0.3778076171875 +64285 0.376953125 +64286 0.371978759765625 +64287 0.313140869140625 +64288 0.184417724609375 +64289 0.011199951171875 +64290 -0.171051025390625 +64291 -0.33740234375 +64292 -0.47198486328125 +64293 -0.560394287109375 +64294 -0.58056640625 +64295 -0.54754638671875 +64296 -0.508575439453125 +64297 -0.459503173828125 +64298 -0.394378662109375 +64299 -0.35260009765625 +64300 -0.31170654296875 +64301 -0.197418212890625 +64302 -0.007965087890625 +64303 0.207489013671875 +64304 0.409210205078125 +64305 0.57208251953125 +64306 0.66595458984375 +64307 0.65875244140625 +64308 0.56744384765625 +64309 0.431396484375 +64310 0.29443359375 +64311 0.182464599609375 +64312 0.06365966796875 +64313 -0.075958251953125 +64314 -0.189422607421875 +64315 -0.271942138671875 +64316 -0.342529296875 +64317 -0.364166259765625 +64318 -0.327239990234375 +64319 -0.2769775390625 +64320 -0.253692626953125 +64321 -0.24365234375 +64322 -0.1983642578125 +64323 -0.116241455078125 +64324 -0.036834716796875 +64325 0.034881591796875 +64326 0.09124755859375 +64327 0.10888671875 +64328 0.125518798828125 +64329 0.15771484375 +64330 0.17828369140625 +64331 0.17108154296875 +64332 0.129974365234375 +64333 0.082427978515625 +64334 0.027679443359375 +64335 -0.065643310546875 +64336 -0.15936279296875 +64337 -0.21307373046875 +64338 -0.234649658203125 +64339 -0.2001953125 +64340 -0.119171142578125 +64341 -0.024749755859375 +64342 0.085784912109375 +64343 0.178131103515625 +64344 0.215576171875 +64345 0.211456298828125 +64346 0.17523193359375 +64347 0.128753662109375 +64348 0.1019287109375 +64349 0.0743408203125 +64350 0.04327392578125 +64351 0.038177490234375 +64352 0.076263427734375 +64353 0.14105224609375 +64354 0.186431884765625 +64355 0.188812255859375 +64356 0.1390380859375 +64357 0.041778564453125 +64358 -0.079437255859375 +64359 -0.219390869140625 +64360 -0.367828369140625 +64361 -0.494873046875 +64362 -0.556243896484375 +64363 -0.508697509765625 +64364 -0.3756103515625 +64365 -0.218902587890625 +64366 -0.063751220703125 +64367 0.091552734375 +64368 0.23602294921875 +64369 0.342987060546875 +64370 0.39520263671875 +64371 0.389373779296875 +64372 0.324249267578125 +64373 0.224090576171875 +64374 0.124267578125 +64375 0.037078857421875 +64376 -0.010101318359375 +64377 -0.019439697265625 +64378 -0.022796630859375 +64379 -0.001556396484375 +64380 0.056304931640625 +64381 0.106719970703125 +64382 0.096893310546875 +64383 0.042694091796875 +64384 -0.018035888671875 +64385 -0.07586669921875 +64386 -0.11944580078125 +64387 -0.15972900390625 +64388 -0.202606201171875 +64389 -0.24859619140625 +64390 -0.30517578125 +64391 -0.36212158203125 +64392 -0.39141845703125 +64393 -0.35528564453125 +64394 -0.249969482421875 +64395 -0.092864990234375 +64396 0.08905029296875 +64397 0.2352294921875 +64398 0.318817138671875 +64399 0.358642578125 +64400 0.347747802734375 +64401 0.28564453125 +64402 0.223175048828125 +64403 0.196746826171875 +64404 0.179840087890625 +64405 0.155548095703125 +64406 0.151214599609375 +64407 0.156951904296875 +64408 0.13177490234375 +64409 0.100799560546875 +64410 0.087127685546875 +64411 0.05487060546875 +64412 -0.009002685546875 +64413 -0.10400390625 +64414 -0.229400634765625 +64415 -0.35552978515625 +64416 -0.441925048828125 +64417 -0.473846435546875 +64418 -0.464813232421875 +64419 -0.419097900390625 +64420 -0.334320068359375 +64421 -0.227935791015625 +64422 -0.12347412109375 +64423 -0.02764892578125 +64424 0.077667236328125 +64425 0.2132568359375 +64426 0.38885498046875 +64427 0.582794189453125 +64428 0.734039306640625 +64429 0.800140380859375 +64430 0.7783203125 +64431 0.6651611328125 +64432 0.45965576171875 +64433 0.199188232421875 +64434 -0.050689697265625 +64435 -0.23297119140625 +64436 -0.33013916015625 +64437 -0.368408203125 +64438 -0.378936767578125 +64439 -0.376983642578125 +64440 -0.37969970703125 +64441 -0.391510009765625 +64442 -0.385345458984375 +64443 -0.3419189453125 +64444 -0.28289794921875 +64445 -0.251617431640625 +64446 -0.266143798828125 +64447 -0.273345947265625 +64448 -0.216796875 +64449 -0.128265380859375 +64450 -0.068145751953125 +64451 -0.0430908203125 +64452 -0.024444580078125 +64453 0.020721435546875 +64454 0.124481201171875 +64455 0.25787353515625 +64456 0.379119873046875 +64457 0.47991943359375 +64458 0.5281982421875 +64459 0.511138916015625 +64460 0.456207275390625 +64461 0.407470703125 +64462 0.383758544921875 +64463 0.35687255859375 +64464 0.31182861328125 +64465 0.250885009765625 +64466 0.1654052734375 +64467 0.035247802734375 +64468 -0.142059326171875 +64469 -0.33563232421875 +64470 -0.5345458984375 +64471 -0.72186279296875 +64472 -0.836669921875 +64473 -0.8326416015625 +64474 -0.7296142578125 +64475 -0.582550048828125 +64476 -0.440093994140625 +64477 -0.324310302734375 +64478 -0.20147705078125 +64479 -0.044647216796875 +64480 0.103973388671875 +64481 0.202392578125 +64482 0.264495849609375 +64483 0.338897705078125 +64484 0.443817138671875 +64485 0.545074462890625 +64486 0.6173095703125 +64487 0.6524658203125 +64488 0.66339111328125 +64489 0.6561279296875 +64490 0.606781005859375 +64491 0.501190185546875 +64492 0.352783203125 +64493 0.176544189453125 +64494 -0.034820556640625 +64495 -0.258209228515625 +64496 -0.44244384765625 +64497 -0.5753173828125 +64498 -0.65203857421875 +64499 -0.641632080078125 +64500 -0.562164306640625 +64501 -0.458038330078125 +64502 -0.350555419921875 +64503 -0.260528564453125 +64504 -0.192108154296875 +64505 -0.141937255859375 +64506 -0.1021728515625 +64507 -0.062896728515625 +64508 -0.011932373046875 +64509 0.062835693359375 +64510 0.148712158203125 +64511 0.241729736328125 +64512 0.34912109375 +64513 0.457305908203125 +64514 0.54388427734375 +64515 0.5728759765625 +64516 0.506591796875 +64517 0.351226806640625 +64518 0.146514892578125 +64519 -0.05523681640625 +64520 -0.21624755859375 +64521 -0.334930419921875 +64522 -0.402984619140625 +64523 -0.4412841796875 +64524 -0.49578857421875 +64525 -0.5601806640625 +64526 -0.600738525390625 +64527 -0.584228515625 +64528 -0.47930908203125 +64529 -0.27935791015625 +64530 -0.0089111328125 +64531 0.268798828125 +64532 0.482818603515625 +64533 0.60369873046875 +64534 0.650421142578125 +64535 0.66400146484375 +64536 0.6414794921875 +64537 0.572540283203125 +64538 0.498138427734375 +64539 0.439453125 +64540 0.375518798828125 +64541 0.274505615234375 +64542 0.1087646484375 +64543 -0.099395751953125 +64544 -0.3182373046875 +64545 -0.5489501953125 +64546 -0.7738037109375 +64547 -0.86383056640625 +64548 -0.870391845703125 +64549 -0.86895751953125 +64550 -0.861053466796875 +64551 -0.765869140625 +64552 -0.5301513671875 +64553 -0.214691162109375 +64554 0.137359619140625 +64555 0.474822998046875 +64556 0.76239013671875 +64557 0.867462158203125 +64558 0.870361328125 +64559 0.86480712890625 +64560 0.831817626953125 +64561 0.677581787109375 +64562 0.495880126953125 +64563 0.30767822265625 +64564 0.116180419921875 +64565 -0.110748291015625 +64566 -0.381805419921875 +64567 -0.6572265625 +64568 -0.857421875 +64569 -0.870391845703125 +64570 -0.870391845703125 +64571 -0.86444091796875 +64572 -0.85723876953125 +64573 -0.790008544921875 +64574 -0.62847900390625 +64575 -0.3956298828125 +64576 -0.126708984375 +64577 0.150115966796875 +64578 0.424041748046875 +64579 0.670623779296875 +64580 0.854522705078125 +64581 0.866485595703125 +64582 0.86920166015625 +64583 0.8653564453125 +64584 0.857147216796875 +64585 0.766845703125 +64586 0.628509521484375 +64587 0.462127685546875 +64588 0.297210693359375 +64589 0.14862060546875 +64590 -0.00537109375 +64591 -0.15753173828125 +64592 -0.31304931640625 +64593 -0.48876953125 +64594 -0.6416015625 +64595 -0.751373291015625 +64596 -0.84619140625 +64597 -0.861297607421875 +64598 -0.863250732421875 +64599 -0.856597900390625 +64600 -0.7498779296875 +64601 -0.624542236328125 +64602 -0.47808837890625 +64603 -0.253387451171875 +64604 0.003692626953125 +64605 0.2257080078125 +64606 0.427154541015625 +64607 0.643218994140625 +64608 0.855926513671875 +64609 0.870361328125 +64610 0.870361328125 +64611 0.862762451171875 +64612 0.79669189453125 +64613 0.595794677734375 +64614 0.362152099609375 +64615 0.1270751953125 +64616 -0.086944580078125 +64617 -0.2784423828125 +64618 -0.484832763671875 +64619 -0.729583740234375 +64620 -0.86688232421875 +64621 -0.870391845703125 +64622 -0.86859130859375 +64623 -0.86279296875 +64624 -0.817962646484375 +64625 -0.6116943359375 +64626 -0.3128662109375 +64627 0.039398193359375 +64628 0.422821044921875 +64629 0.805145263671875 +64630 0.870361328125 +64631 0.870361328125 +64632 0.860015869140625 +64633 0.727935791015625 +64634 0.48114013671875 +64635 0.2059326171875 +64636 -0.06103515625 +64637 -0.29913330078125 +64638 -0.516204833984375 +64639 -0.7252197265625 +64640 -0.85980224609375 +64641 -0.870391845703125 +64642 -0.870391845703125 +64643 -0.858062744140625 +64644 -0.673004150390625 +64645 -0.42694091796875 +64646 -0.2100830078125 +64647 -0.0362548828125 +64648 0.10943603515625 +64649 0.23516845703125 +64650 0.373687744140625 +64651 0.517791748046875 +64652 0.602783203125 +64653 0.635711669921875 +64654 0.655181884765625 +64655 0.65948486328125 +64656 0.651275634765625 +64657 0.61846923828125 +64658 0.53753662109375 +64659 0.404144287109375 +64660 0.22186279296875 +64661 0.003997802734375 +64662 -0.22100830078125 +64663 -0.42449951171875 +64664 -0.579833984375 +64665 -0.641876220703125 +64666 -0.6177978515625 +64667 -0.575531005859375 +64668 -0.526336669921875 +64669 -0.42645263671875 +64670 -0.2581787109375 +64671 -0.068695068359375 +64672 0.09222412109375 +64673 0.232147216796875 +64674 0.3509521484375 +64675 0.410064697265625 +64676 0.372955322265625 +64677 0.2554931640625 +64678 0.10711669921875 +64679 -0.052886962890625 +64680 -0.186279296875 +64681 -0.23291015625 +64682 -0.209442138671875 +64683 -0.174163818359375 +64684 -0.126739501953125 +64685 -0.048126220703125 +64686 0.0426025390625 +64687 0.10748291015625 +64688 0.1409912109375 +64689 0.19708251953125 +64690 0.273651123046875 +64691 0.31768798828125 +64692 0.341094970703125 +64693 0.368011474609375 +64694 0.37249755859375 +64695 0.30072021484375 +64696 0.1517333984375 +64697 -0.01470947265625 +64698 -0.1883544921875 +64699 -0.372711181640625 +64700 -0.51397705078125 +64701 -0.57177734375 +64702 -0.53948974609375 +64703 -0.43511962890625 +64704 -0.2962646484375 +64705 -0.161102294921875 +64706 -0.0435791015625 +64707 0.060394287109375 +64708 0.13665771484375 +64709 0.170135498046875 +64710 0.16552734375 +64711 0.15728759765625 +64712 0.150787353515625 +64713 0.12200927734375 +64714 0.080108642578125 +64715 0.05126953125 +64716 0.062896728515625 +64717 0.09271240234375 +64718 0.092987060546875 +64719 0.07855224609375 +64720 0.06427001953125 +64721 0.0347900390625 +64722 -0.01171875 +64723 -0.056060791015625 +64724 -0.055511474609375 +64725 -0.010467529296875 +64726 0.02508544921875 +64727 0.025665283203125 +64728 0.017333984375 +64729 0.00189208984375 +64730 -0.03173828125 +64731 -0.071502685546875 +64732 -0.13543701171875 +64733 -0.219970703125 +64734 -0.300506591796875 +64735 -0.376312255859375 +64736 -0.416107177734375 +64737 -0.371124267578125 +64738 -0.242279052734375 +64739 -0.069732666015625 +64740 0.125640869140625 +64741 0.31268310546875 +64742 0.45501708984375 +64743 0.554779052734375 +64744 0.61065673828125 +64745 0.610931396484375 +64746 0.531463623046875 +64747 0.3883056640625 +64748 0.23468017578125 +64749 0.095245361328125 +64750 -0.00396728515625 +64751 -0.04852294921875 +64752 -0.055145263671875 +64753 -0.0758056640625 +64754 -0.138702392578125 +64755 -0.209197998046875 +64756 -0.289031982421875 +64757 -0.37884521484375 +64758 -0.456329345703125 +64759 -0.51641845703125 +64760 -0.519287109375 +64761 -0.458251953125 +64762 -0.384796142578125 +64763 -0.323699951171875 +64764 -0.269287109375 +64765 -0.1951904296875 +64766 -0.100006103515625 +64767 -0.01055908203125 +64768 0.1033935546875 +64769 0.24908447265625 +64770 0.373199462890625 +64771 0.45806884765625 +64772 0.511474609375 +64773 0.565399169921875 +64774 0.61138916015625 +64775 0.5897216796875 +64776 0.4906005859375 +64777 0.33148193359375 +64778 0.147796630859375 +64779 -0.01873779296875 +64780 -0.140289306640625 +64781 -0.191986083984375 +64782 -0.184295654296875 +64783 -0.161834716796875 +64784 -0.166595458984375 +64785 -0.19390869140625 +64786 -0.22442626953125 +64787 -0.279754638671875 +64788 -0.3389892578125 +64789 -0.3543701171875 +64790 -0.348175048828125 +64791 -0.32598876953125 +64792 -0.2581787109375 +64793 -0.139801025390625 +64794 0.014617919921875 +64795 0.144378662109375 +64796 0.221038818359375 +64797 0.27069091796875 +64798 0.294036865234375 +64799 0.311767578125 +64800 0.339141845703125 +64801 0.360260009765625 +64802 0.360504150390625 +64803 0.308380126953125 +64804 0.18170166015625 +64805 0.0047607421875 +64806 -0.17559814453125 +64807 -0.3143310546875 +64808 -0.36785888671875 +64809 -0.36248779296875 +64810 -0.343536376953125 +64811 -0.3018798828125 +64812 -0.231414794921875 +64813 -0.117645263671875 +64814 0.007049560546875 +64815 0.087982177734375 +64816 0.13946533203125 +64817 0.17425537109375 +64818 0.188201904296875 +64819 0.171234130859375 +64820 0.118438720703125 +64821 0.05706787109375 +64822 -0.010711669921875 +64823 -0.0914306640625 +64824 -0.162322998046875 +64825 -0.194549560546875 +64826 -0.1492919921875 +64827 -0.02166748046875 +64828 0.124053955078125 +64829 0.211151123046875 +64830 0.240447998046875 +64831 0.242218017578125 +64832 0.2257080078125 +64833 0.194366455078125 +64834 0.115509033203125 +64835 0.0128173828125 +64836 -0.053802490234375 +64837 -0.110626220703125 +64838 -0.199493408203125 +64839 -0.29437255859375 +64840 -0.33221435546875 +64841 -0.27972412109375 +64842 -0.185333251953125 +64843 -0.128204345703125 +64844 -0.115692138671875 +64845 -0.116455078125 +64846 -0.105926513671875 +64847 -0.053955078125 +64848 0.048797607421875 +64849 0.157318115234375 +64850 0.212005615234375 +64851 0.218475341796875 +64852 0.23724365234375 +64853 0.30535888671875 +64854 0.38128662109375 +64855 0.404449462890625 +64856 0.3944091796875 +64857 0.3885498046875 +64858 0.362640380859375 +64859 0.27362060546875 +64860 0.11712646484375 +64861 -0.054901123046875 +64862 -0.19085693359375 +64863 -0.28570556640625 +64864 -0.339263916015625 +64865 -0.3775634765625 +64866 -0.445709228515625 +64867 -0.535064697265625 +64868 -0.629058837890625 +64869 -0.697601318359375 +64870 -0.70391845703125 +64871 -0.6424560546875 +64872 -0.491241455078125 +64873 -0.265716552734375 +64874 -0.023712158203125 +64875 0.201751708984375 +64876 0.375823974609375 +64877 0.485076904296875 +64878 0.56884765625 +64879 0.634765625 +64880 0.63763427734375 +64881 0.5660400390625 +64882 0.4720458984375 +64883 0.40692138671875 +64884 0.3778076171875 +64885 0.376953125 +64886 0.371978759765625 +64887 0.313140869140625 +64888 0.184417724609375 +64889 0.011199951171875 +64890 -0.171051025390625 +64891 -0.33740234375 +64892 -0.47198486328125 +64893 -0.560394287109375 +64894 -0.58056640625 +64895 -0.54754638671875 +64896 -0.508575439453125 +64897 -0.459503173828125 +64898 -0.394378662109375 +64899 -0.35260009765625 +64900 -0.31170654296875 +64901 -0.197418212890625 +64902 -0.007965087890625 +64903 0.207489013671875 +64904 0.409210205078125 +64905 0.57208251953125 +64906 0.66595458984375 +64907 0.65875244140625 +64908 0.56744384765625 +64909 0.431396484375 +64910 0.29443359375 +64911 0.182464599609375 +64912 0.06365966796875 +64913 -0.075958251953125 +64914 -0.189422607421875 +64915 -0.271942138671875 +64916 -0.342529296875 +64917 -0.364166259765625 +64918 -0.327239990234375 +64919 -0.2769775390625 +64920 -0.253692626953125 +64921 -0.24365234375 +64922 -0.1983642578125 +64923 -0.116241455078125 +64924 -0.036834716796875 +64925 0.034881591796875 +64926 0.09124755859375 +64927 0.10888671875 +64928 0.125518798828125 +64929 0.15771484375 +64930 0.17828369140625 +64931 0.17108154296875 +64932 0.129974365234375 +64933 0.082427978515625 +64934 0.027679443359375 +64935 -0.065643310546875 +64936 -0.15936279296875 +64937 -0.21307373046875 +64938 -0.234649658203125 +64939 -0.2001953125 +64940 -0.119171142578125 +64941 -0.024749755859375 +64942 0.085784912109375 +64943 0.178131103515625 +64944 0.215576171875 +64945 0.211456298828125 +64946 0.17523193359375 +64947 0.128753662109375 +64948 0.1019287109375 +64949 0.0743408203125 +64950 0.04327392578125 +64951 0.038177490234375 +64952 0.076263427734375 +64953 0.14105224609375 +64954 0.186431884765625 +64955 0.188812255859375 +64956 0.1390380859375 +64957 0.041778564453125 +64958 -0.079437255859375 +64959 -0.219390869140625 +64960 -0.367828369140625 +64961 -0.494873046875 +64962 -0.556243896484375 +64963 -0.508697509765625 +64964 -0.3756103515625 +64965 -0.218902587890625 +64966 -0.063751220703125 +64967 0.091552734375 +64968 0.23602294921875 +64969 0.342987060546875 +64970 0.39520263671875 +64971 0.389373779296875 +64972 0.324249267578125 +64973 0.224090576171875 +64974 0.124267578125 +64975 0.037078857421875 +64976 -0.010101318359375 +64977 -0.019439697265625 +64978 -0.022796630859375 +64979 -0.001556396484375 +64980 0.056304931640625 +64981 0.106719970703125 +64982 0.096893310546875 +64983 0.042694091796875 +64984 -0.018035888671875 +64985 -0.07586669921875 +64986 -0.11944580078125 +64987 -0.15972900390625 +64988 -0.202606201171875 +64989 -0.24859619140625 +64990 -0.30517578125 +64991 -0.36212158203125 +64992 -0.39141845703125 +64993 -0.35528564453125 +64994 -0.249969482421875 +64995 -0.092864990234375 +64996 0.08905029296875 +64997 0.2352294921875 +64998 0.318817138671875 +64999 0.358642578125 +65000 0.347747802734375 +65001 0.28564453125 +65002 0.223175048828125 +65003 0.196746826171875 +65004 0.179840087890625 +65005 0.155548095703125 +65006 0.151214599609375 +65007 0.156951904296875 +65008 0.13177490234375 +65009 0.100799560546875 +65010 0.087127685546875 +65011 0.05487060546875 +65012 -0.009002685546875 +65013 -0.10400390625 +65014 -0.229400634765625 +65015 -0.35552978515625 +65016 -0.441925048828125 +65017 -0.473846435546875 +65018 -0.464813232421875 +65019 -0.419097900390625 +65020 -0.334320068359375 +65021 -0.227935791015625 +65022 -0.12347412109375 +65023 -0.02764892578125 +65024 0.077667236328125 +65025 0.2132568359375 +65026 0.38885498046875 +65027 0.582794189453125 +65028 0.734039306640625 +65029 0.800140380859375 +65030 0.7783203125 +65031 0.6651611328125 +65032 0.45965576171875 +65033 0.199188232421875 +65034 -0.050689697265625 +65035 -0.23297119140625 +65036 -0.33013916015625 +65037 -0.368408203125 +65038 -0.378936767578125 +65039 -0.376983642578125 +65040 -0.37969970703125 +65041 -0.391510009765625 +65042 -0.385345458984375 +65043 -0.3419189453125 +65044 -0.28289794921875 +65045 -0.251617431640625 +65046 -0.266143798828125 +65047 -0.273345947265625 +65048 -0.216796875 +65049 -0.128265380859375 +65050 -0.068145751953125 +65051 -0.0430908203125 +65052 -0.024444580078125 +65053 0.020721435546875 +65054 0.124481201171875 +65055 0.25787353515625 +65056 0.379119873046875 +65057 0.47991943359375 +65058 0.5281982421875 +65059 0.511138916015625 +65060 0.456207275390625 +65061 0.407470703125 +65062 0.383758544921875 +65063 0.35687255859375 +65064 0.31182861328125 +65065 0.250885009765625 +65066 0.1654052734375 +65067 0.035247802734375 +65068 -0.142059326171875 +65069 -0.33563232421875 +65070 -0.5345458984375 +65071 -0.72186279296875 +65072 -0.836669921875 +65073 -0.8326416015625 +65074 -0.7296142578125 +65075 -0.582550048828125 +65076 -0.440093994140625 +65077 -0.324310302734375 +65078 -0.20147705078125 +65079 -0.044647216796875 +65080 0.103973388671875 +65081 0.202392578125 +65082 0.264495849609375 +65083 0.338897705078125 +65084 0.443817138671875 +65085 0.545074462890625 +65086 0.6173095703125 +65087 0.6524658203125 +65088 0.66339111328125 +65089 0.6561279296875 +65090 0.606781005859375 +65091 0.501190185546875 +65092 0.352783203125 +65093 0.176544189453125 +65094 -0.034820556640625 +65095 -0.258209228515625 +65096 -0.44244384765625 +65097 -0.5753173828125 +65098 -0.65203857421875 +65099 -0.641632080078125 +65100 -0.562164306640625 +65101 -0.458038330078125 +65102 -0.350555419921875 +65103 -0.260528564453125 +65104 -0.192108154296875 +65105 -0.141937255859375 +65106 -0.1021728515625 +65107 -0.062896728515625 +65108 -0.011932373046875 +65109 0.062835693359375 +65110 0.148712158203125 +65111 0.241729736328125 +65112 0.34912109375 +65113 0.457305908203125 +65114 0.54388427734375 +65115 0.5728759765625 +65116 0.506591796875 +65117 0.351226806640625 +65118 0.146514892578125 +65119 -0.05523681640625 +65120 -0.21624755859375 +65121 -0.334930419921875 +65122 -0.402984619140625 +65123 -0.4412841796875 +65124 -0.49578857421875 +65125 -0.5601806640625 +65126 -0.600738525390625 +65127 -0.584228515625 +65128 -0.47930908203125 +65129 -0.27935791015625 +65130 -0.0089111328125 +65131 0.268798828125 +65132 0.482818603515625 +65133 0.60369873046875 +65134 0.650421142578125 +65135 0.66400146484375 +65136 0.6414794921875 +65137 0.572540283203125 +65138 0.498138427734375 +65139 0.439453125 +65140 0.375518798828125 +65141 0.274505615234375 +65142 0.1087646484375 +65143 -0.099395751953125 +65144 -0.3182373046875 +65145 -0.5489501953125 +65146 -0.7738037109375 +65147 -0.86383056640625 +65148 -0.870391845703125 +65149 -0.86895751953125 +65150 -0.861053466796875 +65151 -0.765869140625 +65152 -0.5301513671875 +65153 -0.214691162109375 +65154 0.137359619140625 +65155 0.474822998046875 +65156 0.76239013671875 +65157 0.867462158203125 +65158 0.870361328125 +65159 0.86480712890625 +65160 0.831817626953125 +65161 0.677581787109375 +65162 0.495880126953125 +65163 0.30767822265625 +65164 0.116180419921875 +65165 -0.110748291015625 +65166 -0.381805419921875 +65167 -0.6572265625 +65168 -0.857421875 +65169 -0.870391845703125 +65170 -0.870391845703125 +65171 -0.86444091796875 +65172 -0.85723876953125 +65173 -0.790008544921875 +65174 -0.62847900390625 +65175 -0.3956298828125 +65176 -0.126708984375 +65177 0.150115966796875 +65178 0.424041748046875 +65179 0.670623779296875 +65180 0.854522705078125 +65181 0.866485595703125 +65182 0.86920166015625 +65183 0.8653564453125 +65184 0.857147216796875 +65185 0.766845703125 +65186 0.628509521484375 +65187 0.462127685546875 +65188 0.297210693359375 +65189 0.14862060546875 +65190 -0.00537109375 +65191 -0.15753173828125 +65192 -0.31304931640625 +65193 -0.48876953125 +65194 -0.6416015625 +65195 -0.751373291015625 +65196 -0.84619140625 +65197 -0.861297607421875 +65198 -0.863250732421875 +65199 -0.856597900390625 +65200 -0.7498779296875 +65201 -0.624542236328125 +65202 -0.47808837890625 +65203 -0.253387451171875 +65204 0.003692626953125 +65205 0.2257080078125 +65206 0.427154541015625 +65207 0.643218994140625 +65208 0.855926513671875 +65209 0.870361328125 +65210 0.870361328125 +65211 0.862762451171875 +65212 0.79669189453125 +65213 0.595794677734375 +65214 0.362152099609375 +65215 0.1270751953125 +65216 -0.086944580078125 +65217 -0.2784423828125 +65218 -0.484832763671875 +65219 -0.729583740234375 +65220 -0.86688232421875 +65221 -0.870391845703125 +65222 -0.86859130859375 +65223 -0.86279296875 +65224 -0.817962646484375 +65225 -0.6116943359375 +65226 -0.3128662109375 +65227 0.039398193359375 +65228 0.422821044921875 +65229 0.805145263671875 +65230 0.870361328125 +65231 0.870361328125 +65232 0.860015869140625 +65233 0.727935791015625 +65234 0.48114013671875 +65235 0.2059326171875 +65236 -0.06103515625 +65237 -0.29913330078125 +65238 -0.516204833984375 +65239 -0.7252197265625 +65240 -0.85980224609375 +65241 -0.870391845703125 +65242 -0.870391845703125 +65243 -0.858062744140625 +65244 -0.673004150390625 +65245 -0.42694091796875 +65246 -0.2100830078125 +65247 -0.0362548828125 +65248 0.10943603515625 +65249 0.23516845703125 +65250 0.373687744140625 +65251 0.517791748046875 +65252 0.602783203125 +65253 0.635711669921875 +65254 0.655181884765625 +65255 0.65948486328125 +65256 0.651275634765625 +65257 0.61846923828125 +65258 0.53753662109375 +65259 0.404144287109375 +65260 0.22186279296875 +65261 0.003997802734375 +65262 -0.22100830078125 +65263 -0.42449951171875 +65264 -0.579833984375 +65265 -0.641876220703125 +65266 -0.6177978515625 +65267 -0.575531005859375 +65268 -0.526336669921875 +65269 -0.42645263671875 +65270 -0.2581787109375 +65271 -0.068695068359375 +65272 0.09222412109375 +65273 0.232147216796875 +65274 0.3509521484375 +65275 0.410064697265625 +65276 0.372955322265625 +65277 0.2554931640625 +65278 0.10711669921875 +65279 -0.052886962890625 +65280 -0.186279296875 +65281 -0.23291015625 +65282 -0.209442138671875 +65283 -0.174163818359375 +65284 -0.126739501953125 +65285 -0.048126220703125 +65286 0.0426025390625 +65287 0.10748291015625 +65288 0.1409912109375 +65289 0.19708251953125 +65290 0.273651123046875 +65291 0.31768798828125 +65292 0.341094970703125 +65293 0.368011474609375 +65294 0.37249755859375 +65295 0.30072021484375 +65296 0.1517333984375 +65297 -0.01470947265625 +65298 -0.1883544921875 +65299 -0.372711181640625 +65300 -0.51397705078125 +65301 -0.57177734375 +65302 -0.53948974609375 +65303 -0.43511962890625 +65304 -0.2962646484375 +65305 -0.161102294921875 +65306 -0.0435791015625 +65307 0.060394287109375 +65308 0.13665771484375 +65309 0.170135498046875 +65310 0.16552734375 +65311 0.15728759765625 +65312 0.150787353515625 +65313 0.12200927734375 +65314 0.080108642578125 +65315 0.05126953125 +65316 0.062896728515625 +65317 0.09271240234375 +65318 0.092987060546875 +65319 0.07855224609375 +65320 0.06427001953125 +65321 0.0347900390625 +65322 -0.01171875 +65323 -0.056060791015625 +65324 -0.055511474609375 +65325 -0.010467529296875 +65326 0.02508544921875 +65327 0.025665283203125 +65328 0.017333984375 +65329 0.00189208984375 +65330 -0.03173828125 +65331 -0.071502685546875 +65332 -0.13543701171875 +65333 -0.219970703125 +65334 -0.300506591796875 +65335 -0.376312255859375 +65336 -0.416107177734375 +65337 -0.371124267578125 +65338 -0.242279052734375 +65339 -0.069732666015625 +65340 0.125640869140625 +65341 0.31268310546875 +65342 0.45501708984375 +65343 0.554779052734375 +65344 0.61065673828125 +65345 0.610931396484375 +65346 0.531463623046875 +65347 0.3883056640625 +65348 0.23468017578125 +65349 0.095245361328125 +65350 -0.00396728515625 +65351 -0.04852294921875 +65352 -0.055145263671875 +65353 -0.0758056640625 +65354 -0.138702392578125 +65355 -0.209197998046875 +65356 -0.289031982421875 +65357 -0.37884521484375 +65358 -0.456329345703125 +65359 -0.51641845703125 +65360 -0.519287109375 +65361 -0.458251953125 +65362 -0.384796142578125 +65363 -0.323699951171875 +65364 -0.269287109375 +65365 -0.1951904296875 +65366 -0.100006103515625 +65367 -0.01055908203125 +65368 0.1033935546875 +65369 0.24908447265625 +65370 0.373199462890625 +65371 0.45806884765625 +65372 0.511474609375 +65373 0.565399169921875 +65374 0.61138916015625 +65375 0.5897216796875 +65376 0.4906005859375 +65377 0.33148193359375 +65378 0.147796630859375 +65379 -0.01873779296875 +65380 -0.140289306640625 +65381 -0.191986083984375 +65382 -0.184295654296875 +65383 -0.161834716796875 +65384 -0.166595458984375 +65385 -0.19390869140625 +65386 -0.22442626953125 +65387 -0.279754638671875 +65388 -0.3389892578125 +65389 -0.3543701171875 +65390 -0.348175048828125 +65391 -0.32598876953125 +65392 -0.2581787109375 +65393 -0.139801025390625 +65394 0.014617919921875 +65395 0.144378662109375 +65396 0.221038818359375 +65397 0.27069091796875 +65398 0.294036865234375 +65399 0.311767578125 +65400 0.339141845703125 +65401 0.360260009765625 +65402 0.360504150390625 +65403 0.308380126953125 +65404 0.18170166015625 +65405 0.0047607421875 +65406 -0.17559814453125 +65407 -0.3143310546875 +65408 -0.36785888671875 +65409 -0.36248779296875 +65410 -0.343536376953125 +65411 -0.3018798828125 +65412 -0.231414794921875 +65413 -0.117645263671875 +65414 0.007049560546875 +65415 0.087982177734375 +65416 0.13946533203125 +65417 0.17425537109375 +65418 0.188201904296875 +65419 0.171234130859375 +65420 0.118438720703125 +65421 0.05706787109375 +65422 -0.010711669921875 +65423 -0.0914306640625 +65424 -0.162322998046875 +65425 -0.194549560546875 +65426 -0.1492919921875 +65427 -0.02166748046875 +65428 0.124053955078125 +65429 0.211151123046875 +65430 0.240447998046875 +65431 0.242218017578125 +65432 0.2257080078125 +65433 0.194366455078125 +65434 0.115509033203125 +65435 0.0128173828125 +65436 -0.053802490234375 +65437 -0.110626220703125 +65438 -0.199493408203125 +65439 -0.29437255859375 +65440 -0.33221435546875 +65441 -0.27972412109375 +65442 -0.185333251953125 +65443 -0.128204345703125 +65444 -0.115692138671875 +65445 -0.116455078125 +65446 -0.105926513671875 +65447 -0.053955078125 +65448 0.048797607421875 +65449 0.157318115234375 +65450 0.212005615234375 +65451 0.218475341796875 +65452 0.23724365234375 +65453 0.30535888671875 +65454 0.38128662109375 +65455 0.404449462890625 +65456 0.3944091796875 +65457 0.3885498046875 +65458 0.362640380859375 +65459 0.27362060546875 +65460 0.11712646484375 +65461 -0.054901123046875 +65462 -0.19085693359375 +65463 -0.28570556640625 +65464 -0.339263916015625 +65465 -0.3775634765625 +65466 -0.445709228515625 +65467 -0.535064697265625 +65468 -0.629058837890625 +65469 -0.697601318359375 +65470 -0.70391845703125 +65471 -0.6424560546875 +65472 -0.491241455078125 +65473 -0.265716552734375 +65474 -0.023712158203125 +65475 0.201751708984375 +65476 0.375823974609375 +65477 0.485076904296875 +65478 0.56884765625 +65479 0.634765625 +65480 0.63763427734375 +65481 0.5660400390625 +65482 0.4720458984375 +65483 0.40692138671875 +65484 0.3778076171875 +65485 0.376953125 +65486 0.371978759765625 +65487 0.313140869140625 +65488 0.184417724609375 +65489 0.011199951171875 +65490 -0.171051025390625 +65491 -0.33740234375 +65492 -0.47198486328125 +65493 -0.560394287109375 +65494 -0.58056640625 +65495 -0.54754638671875 +65496 -0.508575439453125 +65497 -0.459503173828125 +65498 -0.394378662109375 +65499 -0.35260009765625 +65500 -0.31170654296875 +65501 -0.197418212890625 +65502 -0.007965087890625 +65503 0.207489013671875 +65504 0.409210205078125 +65505 0.57208251953125 +65506 0.66595458984375 +65507 0.65875244140625 +65508 0.56744384765625 +65509 0.431396484375 +65510 0.29443359375 +65511 0.182464599609375 +65512 0.06365966796875 +65513 -0.075958251953125 +65514 -0.189422607421875 +65515 -0.271942138671875 +65516 -0.342529296875 +65517 -0.364166259765625 +65518 -0.327239990234375 +65519 -0.2769775390625 +65520 -0.253692626953125 +65521 -0.24365234375 +65522 -0.1983642578125 +65523 -0.116241455078125 +65524 -0.036834716796875 +65525 0.034881591796875 +65526 0.09124755859375 +65527 0.10888671875 +65528 0.125518798828125 +65529 0.15771484375 +65530 0.17828369140625 +65531 0.17108154296875 +65532 0.129974365234375 +65533 0.082427978515625 +65534 0.027679443359375 +65535 -0.065643310546875 +65536 -0.15936279296875 +65537 -0.21307373046875 +65538 -0.234649658203125 +65539 -0.2001953125 +65540 -0.119171142578125 +65541 -0.024749755859375 +65542 0.085784912109375 +65543 0.178131103515625 +65544 0.215576171875 +65545 0.211456298828125 +65546 0.17523193359375 +65547 0.128753662109375 +65548 0.1019287109375 +65549 0.0743408203125 +65550 0.04327392578125 +65551 0.038177490234375 +65552 0.076263427734375 +65553 0.14105224609375 +65554 0.186431884765625 +65555 0.188812255859375 +65556 0.1390380859375 +65557 0.041778564453125 +65558 -0.079437255859375 +65559 -0.219390869140625 +65560 -0.367828369140625 +65561 -0.494873046875 +65562 -0.556243896484375 +65563 -0.508697509765625 +65564 -0.3756103515625 +65565 -0.218902587890625 +65566 -0.063751220703125 +65567 0.091552734375 +65568 0.23602294921875 +65569 0.342987060546875 +65570 0.39520263671875 +65571 0.389373779296875 +65572 0.324249267578125 +65573 0.224090576171875 +65574 0.124267578125 +65575 0.037078857421875 +65576 -0.010101318359375 +65577 -0.019439697265625 +65578 -0.022796630859375 +65579 -0.001556396484375 +65580 0.056304931640625 +65581 0.106719970703125 +65582 0.096893310546875 +65583 0.042694091796875 +65584 -0.018035888671875 +65585 -0.07586669921875 +65586 -0.11944580078125 +65587 -0.15972900390625 +65588 -0.202606201171875 +65589 -0.24859619140625 +65590 -0.30517578125 +65591 -0.36212158203125 +65592 -0.39141845703125 +65593 -0.35528564453125 +65594 -0.249969482421875 +65595 -0.092864990234375 +65596 0.08905029296875 +65597 0.2352294921875 +65598 0.318817138671875 +65599 0.358642578125 +65600 0.347747802734375 +65601 0.28564453125 +65602 0.223175048828125 +65603 0.196746826171875 +65604 0.179840087890625 +65605 0.155548095703125 +65606 0.151214599609375 +65607 0.156951904296875 +65608 0.13177490234375 +65609 0.100799560546875 +65610 0.087127685546875 +65611 0.05487060546875 +65612 -0.009002685546875 +65613 -0.10400390625 +65614 -0.229400634765625 +65615 -0.35552978515625 +65616 -0.441925048828125 +65617 -0.473846435546875 +65618 -0.464813232421875 +65619 -0.419097900390625 +65620 -0.334320068359375 +65621 -0.227935791015625 +65622 -0.12347412109375 +65623 -0.02764892578125 +65624 0.077667236328125 +65625 0.2132568359375 +65626 0.38885498046875 +65627 0.582794189453125 +65628 0.734039306640625 +65629 0.800140380859375 +65630 0.7783203125 +65631 0.6651611328125 +65632 0.45965576171875 +65633 0.199188232421875 +65634 -0.050689697265625 +65635 -0.23297119140625 +65636 -0.33013916015625 +65637 -0.368408203125 +65638 -0.378936767578125 +65639 -0.376983642578125 +65640 -0.37969970703125 +65641 -0.391510009765625 +65642 -0.385345458984375 +65643 -0.3419189453125 +65644 -0.28289794921875 +65645 -0.251617431640625 +65646 -0.266143798828125 +65647 -0.273345947265625 +65648 -0.216796875 +65649 -0.128265380859375 +65650 -0.068145751953125 +65651 -0.0430908203125 +65652 -0.024444580078125 +65653 0.020721435546875 +65654 0.124481201171875 +65655 0.25787353515625 +65656 0.379119873046875 +65657 0.47991943359375 +65658 0.5281982421875 +65659 0.511138916015625 +65660 0.456207275390625 +65661 0.407470703125 +65662 0.383758544921875 +65663 0.35687255859375 +65664 0.31182861328125 +65665 0.250885009765625 +65666 0.1654052734375 +65667 0.035247802734375 +65668 -0.142059326171875 +65669 -0.33563232421875 +65670 -0.5345458984375 +65671 -0.72186279296875 +65672 -0.836669921875 +65673 -0.8326416015625 +65674 -0.7296142578125 +65675 -0.582550048828125 +65676 -0.440093994140625 +65677 -0.324310302734375 +65678 -0.20147705078125 +65679 -0.044647216796875 +65680 0.103973388671875 +65681 0.202392578125 +65682 0.264495849609375 +65683 0.338897705078125 +65684 0.443817138671875 +65685 0.545074462890625 +65686 0.6173095703125 +65687 0.6524658203125 +65688 0.66339111328125 +65689 0.6561279296875 +65690 0.606781005859375 +65691 0.501190185546875 +65692 0.352783203125 +65693 0.176544189453125 +65694 -0.034820556640625 +65695 -0.258209228515625 +65696 -0.44244384765625 +65697 -0.5753173828125 +65698 -0.65203857421875 +65699 -0.641632080078125 +65700 -0.562164306640625 +65701 -0.458038330078125 +65702 -0.350555419921875 +65703 -0.260528564453125 +65704 -0.192108154296875 +65705 -0.141937255859375 +65706 -0.1021728515625 +65707 -0.062896728515625 +65708 -0.011932373046875 +65709 0.062835693359375 +65710 0.148712158203125 +65711 0.241729736328125 +65712 0.34912109375 +65713 0.457305908203125 +65714 0.54388427734375 +65715 0.5728759765625 +65716 0.506591796875 +65717 0.351226806640625 +65718 0.146514892578125 +65719 -0.05523681640625 +65720 -0.21624755859375 +65721 -0.334930419921875 +65722 -0.402984619140625 +65723 -0.4412841796875 +65724 -0.49578857421875 +65725 -0.5601806640625 +65726 -0.600738525390625 +65727 -0.584228515625 +65728 -0.47930908203125 +65729 -0.27935791015625 +65730 -0.0089111328125 +65731 0.268798828125 +65732 0.482818603515625 +65733 0.60369873046875 +65734 0.650421142578125 +65735 0.66400146484375 +65736 0.6414794921875 +65737 0.572540283203125 +65738 0.498138427734375 +65739 0.439453125 +65740 0.375518798828125 +65741 0.274505615234375 +65742 0.1087646484375 +65743 -0.099395751953125 +65744 -0.3182373046875 +65745 -0.5489501953125 +65746 -0.7738037109375 +65747 -0.86383056640625 +65748 -0.870391845703125 +65749 -0.86895751953125 +65750 -0.861053466796875 +65751 -0.765869140625 +65752 -0.5301513671875 +65753 -0.214691162109375 +65754 0.137359619140625 +65755 0.474822998046875 +65756 0.76239013671875 +65757 0.867462158203125 +65758 0.870361328125 +65759 0.86480712890625 +65760 0.831817626953125 +65761 0.677581787109375 +65762 0.495880126953125 +65763 0.30767822265625 +65764 0.116180419921875 +65765 -0.110748291015625 +65766 -0.381805419921875 +65767 -0.6572265625 +65768 -0.857421875 +65769 -0.870391845703125 +65770 -0.870391845703125 +65771 -0.86444091796875 +65772 -0.85723876953125 +65773 -0.790008544921875 +65774 -0.62847900390625 +65775 -0.3956298828125 +65776 -0.126708984375 +65777 0.150115966796875 +65778 0.424041748046875 +65779 0.670623779296875 +65780 0.854522705078125 +65781 0.866485595703125 +65782 0.86920166015625 +65783 0.8653564453125 +65784 0.857147216796875 +65785 0.766845703125 +65786 0.628509521484375 +65787 0.462127685546875 +65788 0.297210693359375 +65789 0.14862060546875 +65790 -0.00537109375 +65791 -0.15753173828125 +65792 -0.31304931640625 +65793 -0.48876953125 +65794 -0.6416015625 +65795 -0.751373291015625 +65796 -0.84619140625 +65797 -0.861297607421875 +65798 -0.863250732421875 +65799 -0.856597900390625 +65800 -0.7498779296875 +65801 -0.624542236328125 +65802 -0.47808837890625 +65803 -0.253387451171875 +65804 0.003692626953125 +65805 0.2257080078125 +65806 0.427154541015625 +65807 0.643218994140625 +65808 0.855926513671875 +65809 0.870361328125 +65810 0.870361328125 +65811 0.862762451171875 +65812 0.79669189453125 +65813 0.595794677734375 +65814 0.362152099609375 +65815 0.1270751953125 +65816 -0.086944580078125 +65817 -0.2784423828125 +65818 -0.484832763671875 +65819 -0.729583740234375 +65820 -0.86688232421875 +65821 -0.870391845703125 +65822 -0.86859130859375 +65823 -0.86279296875 +65824 -0.817962646484375 +65825 -0.6116943359375 +65826 -0.3128662109375 +65827 0.039398193359375 +65828 0.422821044921875 +65829 0.805145263671875 +65830 0.870361328125 +65831 0.870361328125 +65832 0.860015869140625 +65833 0.727935791015625 +65834 0.48114013671875 +65835 0.2059326171875 +65836 -0.06103515625 +65837 -0.29913330078125 +65838 -0.516204833984375 +65839 -0.7252197265625 +65840 -0.85980224609375 +65841 -0.870391845703125 +65842 -0.870391845703125 +65843 -0.858062744140625 +65844 -0.673004150390625 +65845 -0.42694091796875 +65846 -0.2100830078125 +65847 -0.0362548828125 +65848 0.10943603515625 +65849 0.23516845703125 +65850 0.373687744140625 +65851 0.517791748046875 +65852 0.602783203125 +65853 0.635711669921875 +65854 0.655181884765625 +65855 0.65948486328125 +65856 0.651275634765625 +65857 0.61846923828125 +65858 0.53753662109375 +65859 0.404144287109375 +65860 0.22186279296875 +65861 0.003997802734375 +65862 -0.22100830078125 +65863 -0.42449951171875 +65864 -0.579833984375 +65865 -0.641876220703125 +65866 -0.6177978515625 +65867 -0.575531005859375 +65868 -0.526336669921875 +65869 -0.42645263671875 +65870 -0.2581787109375 +65871 -0.068695068359375 +65872 0.09222412109375 +65873 0.232147216796875 +65874 0.3509521484375 +65875 0.410064697265625 +65876 0.372955322265625 +65877 0.2554931640625 +65878 0.10711669921875 +65879 -0.052886962890625 +65880 -0.186279296875 +65881 -0.23291015625 +65882 -0.209442138671875 +65883 -0.174163818359375 +65884 -0.126739501953125 +65885 -0.048126220703125 +65886 0.0426025390625 +65887 0.10748291015625 +65888 0.1409912109375 +65889 0.19708251953125 +65890 0.273651123046875 +65891 0.31768798828125 +65892 0.341094970703125 +65893 0.368011474609375 +65894 0.37249755859375 +65895 0.30072021484375 +65896 0.1517333984375 +65897 -0.01470947265625 +65898 -0.1883544921875 +65899 -0.372711181640625 +65900 -0.51397705078125 +65901 -0.57177734375 +65902 -0.53948974609375 +65903 -0.43511962890625 +65904 -0.2962646484375 +65905 -0.161102294921875 +65906 -0.0435791015625 +65907 0.060394287109375 +65908 0.13665771484375 +65909 0.170135498046875 +65910 0.16552734375 +65911 0.15728759765625 +65912 0.150787353515625 +65913 0.12200927734375 +65914 0.080108642578125 +65915 0.05126953125 +65916 0.062896728515625 +65917 0.09271240234375 +65918 0.092987060546875 +65919 0.07855224609375 +65920 0.06427001953125 +65921 0.0347900390625 +65922 -0.01171875 +65923 -0.056060791015625 +65924 -0.055511474609375 +65925 -0.010467529296875 +65926 0.02508544921875 +65927 0.025665283203125 +65928 0.017333984375 +65929 0.00189208984375 +65930 -0.03173828125 +65931 -0.071502685546875 +65932 -0.13543701171875 +65933 -0.219970703125 +65934 -0.300506591796875 +65935 -0.376312255859375 +65936 -0.416107177734375 +65937 -0.371124267578125 +65938 -0.242279052734375 +65939 -0.069732666015625 +65940 0.125640869140625 +65941 0.31268310546875 +65942 0.45501708984375 +65943 0.554779052734375 +65944 0.61065673828125 +65945 0.610931396484375 +65946 0.531463623046875 +65947 0.3883056640625 +65948 0.23468017578125 +65949 0.095245361328125 +65950 -0.00396728515625 +65951 -0.04852294921875 +65952 -0.055145263671875 +65953 -0.0758056640625 +65954 -0.138702392578125 +65955 -0.209197998046875 +65956 -0.289031982421875 +65957 -0.37884521484375 +65958 -0.456329345703125 +65959 -0.51641845703125 +65960 -0.519287109375 +65961 -0.458251953125 +65962 -0.384796142578125 +65963 -0.323699951171875 +65964 -0.269287109375 +65965 -0.1951904296875 +65966 -0.100006103515625 +65967 -0.01055908203125 +65968 0.1033935546875 +65969 0.24908447265625 +65970 0.373199462890625 +65971 0.45806884765625 +65972 0.511474609375 +65973 0.565399169921875 +65974 0.61138916015625 +65975 0.5897216796875 +65976 0.4906005859375 +65977 0.33148193359375 +65978 0.147796630859375 +65979 -0.01873779296875 +65980 -0.140289306640625 +65981 -0.191986083984375 +65982 -0.184295654296875 +65983 -0.161834716796875 +65984 -0.166595458984375 +65985 -0.19390869140625 +65986 -0.22442626953125 +65987 -0.279754638671875 +65988 -0.3389892578125 +65989 -0.3543701171875 +65990 -0.348175048828125 +65991 -0.32598876953125 +65992 -0.2581787109375 +65993 -0.139801025390625 +65994 0.014617919921875 +65995 0.144378662109375 +65996 0.221038818359375 +65997 0.27069091796875 +65998 0.294036865234375 +65999 0.311767578125 +66000 0.339141845703125 +66001 0.360260009765625 +66002 0.360504150390625 +66003 0.308380126953125 +66004 0.18170166015625 +66005 0.0047607421875 +66006 -0.17559814453125 +66007 -0.3143310546875 +66008 -0.36785888671875 +66009 -0.36248779296875 +66010 -0.343536376953125 +66011 -0.3018798828125 +66012 -0.231414794921875 +66013 -0.117645263671875 +66014 0.007049560546875 +66015 0.087982177734375 +66016 0.13946533203125 +66017 0.17425537109375 +66018 0.188201904296875 +66019 0.171234130859375 +66020 0.118438720703125 +66021 0.05706787109375 +66022 -0.010711669921875 +66023 -0.0914306640625 +66024 -0.162322998046875 +66025 -0.194549560546875 +66026 -0.1492919921875 +66027 -0.02166748046875 +66028 0.124053955078125 +66029 0.211151123046875 +66030 0.240447998046875 +66031 0.242218017578125 +66032 0.2257080078125 +66033 0.194366455078125 +66034 0.115509033203125 +66035 0.0128173828125 +66036 -0.053802490234375 +66037 -0.110626220703125 +66038 -0.199493408203125 +66039 -0.29437255859375 +66040 -0.33221435546875 +66041 -0.27972412109375 +66042 -0.185333251953125 +66043 -0.128204345703125 +66044 -0.115692138671875 +66045 -0.116455078125 +66046 -0.105926513671875 +66047 -0.053955078125 +66048 0.048797607421875 +66049 0.157318115234375 +66050 0.212005615234375 +66051 0.218475341796875 +66052 0.23724365234375 +66053 0.30535888671875 +66054 0.38128662109375 +66055 0.404449462890625 +66056 0.3944091796875 +66057 0.3885498046875 +66058 0.362640380859375 +66059 0.27362060546875 +66060 0.11712646484375 +66061 -0.054901123046875 +66062 -0.19085693359375 +66063 -0.28570556640625 +66064 -0.339263916015625 +66065 -0.3775634765625 +66066 -0.445709228515625 +66067 -0.535064697265625 +66068 -0.629058837890625 +66069 -0.697601318359375 +66070 -0.70391845703125 +66071 -0.6424560546875 +66072 -0.491241455078125 +66073 -0.265716552734375 +66074 -0.023712158203125 +66075 0.201751708984375 +66076 0.375823974609375 +66077 0.485076904296875 +66078 0.56884765625 +66079 0.634765625 +66080 0.63763427734375 +66081 0.5660400390625 +66082 0.4720458984375 +66083 0.40692138671875 +66084 0.3778076171875 +66085 0.376953125 +66086 0.371978759765625 +66087 0.313140869140625 +66088 0.184417724609375 +66089 0.011199951171875 +66090 -0.171051025390625 +66091 -0.33740234375 +66092 -0.47198486328125 +66093 -0.560394287109375 +66094 -0.58056640625 +66095 -0.54754638671875 +66096 -0.508575439453125 +66097 -0.459503173828125 +66098 -0.394378662109375 +66099 -0.35260009765625 +66100 -0.31170654296875 +66101 -0.197418212890625 +66102 -0.007965087890625 +66103 0.207489013671875 +66104 0.409210205078125 +66105 0.57208251953125 +66106 0.66595458984375 +66107 0.65875244140625 +66108 0.56744384765625 +66109 0.431396484375 +66110 0.29443359375 +66111 0.182464599609375 +66112 0.06365966796875 +66113 -0.075958251953125 +66114 -0.189422607421875 +66115 -0.271942138671875 +66116 -0.342529296875 +66117 -0.364166259765625 +66118 -0.327239990234375 +66119 -0.2769775390625 +66120 -0.253692626953125 +66121 -0.24365234375 +66122 -0.1983642578125 +66123 -0.116241455078125 +66124 -0.036834716796875 +66125 0.034881591796875 +66126 0.09124755859375 +66127 0.10888671875 +66128 0.125518798828125 +66129 0.15771484375 +66130 0.17828369140625 +66131 0.17108154296875 +66132 0.129974365234375 +66133 0.082427978515625 +66134 0.027679443359375 +66135 -0.065643310546875 +66136 -0.15936279296875 +66137 -0.21307373046875 +66138 -0.234649658203125 +66139 -0.2001953125 +66140 -0.119171142578125 +66141 -0.024749755859375 +66142 0.085784912109375 +66143 0.178131103515625 +66144 0.215576171875 +66145 0.211456298828125 +66146 0.17523193359375 +66147 0.128753662109375 +66148 0.1019287109375 +66149 0.0743408203125 +66150 0.04327392578125 +66151 0.038177490234375 +66152 0.076263427734375 +66153 0.14105224609375 +66154 0.186431884765625 +66155 0.188812255859375 +66156 0.1390380859375 +66157 0.041778564453125 +66158 -0.079437255859375 +66159 -0.219390869140625 +66160 -0.367828369140625 +66161 -0.494873046875 +66162 -0.556243896484375 +66163 -0.508697509765625 +66164 -0.3756103515625 +66165 -0.218902587890625 +66166 -0.063751220703125 +66167 0.091552734375 +66168 0.23602294921875 +66169 0.342987060546875 +66170 0.39520263671875 +66171 0.389373779296875 +66172 0.324249267578125 +66173 0.224090576171875 +66174 0.124267578125 +66175 0.037078857421875 +66176 -0.010101318359375 +66177 -0.019439697265625 +66178 -0.022796630859375 +66179 -0.001556396484375 +66180 0.056304931640625 +66181 0.106719970703125 +66182 0.096893310546875 +66183 0.042694091796875 +66184 -0.018035888671875 +66185 -0.07586669921875 +66186 -0.11944580078125 +66187 -0.15972900390625 +66188 -0.202606201171875 +66189 -0.24859619140625 +66190 -0.30517578125 +66191 -0.36212158203125 +66192 -0.39141845703125 +66193 -0.35528564453125 +66194 -0.249969482421875 +66195 -0.092864990234375 +66196 0.08905029296875 +66197 0.2352294921875 +66198 0.318817138671875 +66199 0.358642578125 +66200 0.347747802734375 +66201 0.28564453125 +66202 0.223175048828125 +66203 0.196746826171875 +66204 0.179840087890625 +66205 0.155548095703125 +66206 0.151214599609375 +66207 0.156951904296875 +66208 0.13177490234375 +66209 0.100799560546875 +66210 0.087127685546875 +66211 0.05487060546875 +66212 -0.009002685546875 +66213 -0.10400390625 +66214 -0.229400634765625 +66215 -0.35552978515625 +66216 -0.441925048828125 +66217 -0.473846435546875 +66218 -0.464813232421875 +66219 -0.419097900390625 +66220 -0.334320068359375 +66221 -0.227935791015625 +66222 -0.12347412109375 +66223 -0.02764892578125 +66224 0.077667236328125 +66225 0.2132568359375 +66226 0.38885498046875 +66227 0.582794189453125 +66228 0.734039306640625 +66229 0.800140380859375 +66230 0.7783203125 +66231 0.6651611328125 +66232 0.45965576171875 +66233 0.199188232421875 +66234 -0.050689697265625 +66235 -0.23297119140625 +66236 -0.33013916015625 +66237 -0.368408203125 +66238 -0.378936767578125 +66239 -0.376983642578125 +66240 -0.37969970703125 +66241 -0.391510009765625 +66242 -0.385345458984375 +66243 -0.3419189453125 +66244 -0.28289794921875 +66245 -0.251617431640625 +66246 -0.266143798828125 +66247 -0.273345947265625 +66248 -0.216796875 +66249 -0.128265380859375 +66250 -0.068145751953125 +66251 -0.0430908203125 +66252 -0.024444580078125 +66253 0.020721435546875 +66254 0.124481201171875 +66255 0.25787353515625 +66256 0.379119873046875 +66257 0.47991943359375 +66258 0.5281982421875 +66259 0.511138916015625 +66260 0.456207275390625 +66261 0.407470703125 +66262 0.383758544921875 +66263 0.35687255859375 +66264 0.31182861328125 +66265 0.250885009765625 +66266 0.1654052734375 +66267 0.035247802734375 +66268 -0.142059326171875 +66269 -0.33563232421875 +66270 -0.5345458984375 +66271 -0.72186279296875 +66272 -0.836669921875 +66273 -0.8326416015625 +66274 -0.7296142578125 +66275 -0.582550048828125 +66276 -0.440093994140625 +66277 -0.324310302734375 +66278 -0.20147705078125 +66279 -0.044647216796875 +66280 0.103973388671875 +66281 0.202392578125 +66282 0.264495849609375 +66283 0.338897705078125 +66284 0.443817138671875 +66285 0.545074462890625 +66286 0.6173095703125 +66287 0.6524658203125 +66288 0.66339111328125 +66289 0.6561279296875 +66290 0.606781005859375 +66291 0.501190185546875 +66292 0.352783203125 +66293 0.176544189453125 +66294 -0.034820556640625 +66295 -0.258209228515625 +66296 -0.44244384765625 +66297 -0.5753173828125 +66298 -0.65203857421875 +66299 -0.641632080078125 +66300 -0.562164306640625 +66301 -0.458038330078125 +66302 -0.350555419921875 +66303 -0.260528564453125 +66304 -0.192108154296875 +66305 -0.141937255859375 +66306 -0.1021728515625 +66307 -0.062896728515625 +66308 -0.011932373046875 +66309 0.062835693359375 +66310 0.148712158203125 +66311 0.241729736328125 +66312 0.34912109375 +66313 0.457305908203125 +66314 0.54388427734375 +66315 0.5728759765625 +66316 0.506591796875 +66317 0.351226806640625 +66318 0.146514892578125 +66319 -0.05523681640625 +66320 -0.21624755859375 +66321 -0.334930419921875 +66322 -0.402984619140625 +66323 -0.4412841796875 +66324 -0.49578857421875 +66325 -0.5601806640625 +66326 -0.600738525390625 +66327 -0.584228515625 +66328 -0.47930908203125 +66329 -0.27935791015625 +66330 -0.0089111328125 +66331 0.268798828125 +66332 0.482818603515625 +66333 0.60369873046875 +66334 0.650421142578125 +66335 0.66400146484375 +66336 0.6414794921875 +66337 0.572540283203125 +66338 0.498138427734375 +66339 0.439453125 +66340 0.375518798828125 +66341 0.274505615234375 +66342 0.1087646484375 +66343 -0.099395751953125 +66344 -0.3182373046875 +66345 -0.5489501953125 +66346 -0.7738037109375 +66347 -0.86383056640625 +66348 -0.870391845703125 +66349 -0.86895751953125 +66350 -0.861053466796875 +66351 -0.765869140625 +66352 -0.5301513671875 +66353 -0.214691162109375 +66354 0.137359619140625 +66355 0.474822998046875 +66356 0.76239013671875 +66357 0.867462158203125 +66358 0.870361328125 +66359 0.86480712890625 +66360 0.831817626953125 +66361 0.677581787109375 +66362 0.495880126953125 +66363 0.30767822265625 +66364 0.116180419921875 +66365 -0.110748291015625 +66366 -0.381805419921875 +66367 -0.6572265625 +66368 -0.857421875 +66369 -0.870391845703125 +66370 -0.870391845703125 +66371 -0.86444091796875 +66372 -0.85723876953125 +66373 -0.790008544921875 +66374 -0.62847900390625 +66375 -0.3956298828125 +66376 -0.126708984375 +66377 0.150115966796875 +66378 0.424041748046875 +66379 0.670623779296875 +66380 0.854522705078125 +66381 0.866485595703125 +66382 0.86920166015625 +66383 0.8653564453125 +66384 0.857147216796875 +66385 0.766845703125 +66386 0.628509521484375 +66387 0.462127685546875 +66388 0.297210693359375 +66389 0.14862060546875 +66390 -0.00537109375 +66391 -0.15753173828125 +66392 -0.31304931640625 +66393 -0.48876953125 +66394 -0.6416015625 +66395 -0.751373291015625 +66396 -0.84619140625 +66397 -0.861297607421875 +66398 -0.863250732421875 +66399 -0.856597900390625 +66400 -0.7498779296875 +66401 -0.624542236328125 +66402 -0.47808837890625 +66403 -0.253387451171875 +66404 0.003692626953125 +66405 0.2257080078125 +66406 0.427154541015625 +66407 0.643218994140625 +66408 0.855926513671875 +66409 0.870361328125 +66410 0.870361328125 +66411 0.862762451171875 +66412 0.79669189453125 +66413 0.595794677734375 +66414 0.362152099609375 +66415 0.1270751953125 +66416 -0.086944580078125 +66417 -0.2784423828125 +66418 -0.484832763671875 +66419 -0.729583740234375 +66420 -0.86688232421875 +66421 -0.870391845703125 +66422 -0.86859130859375 +66423 -0.86279296875 +66424 -0.817962646484375 +66425 -0.6116943359375 +66426 -0.3128662109375 +66427 0.039398193359375 +66428 0.422821044921875 +66429 0.805145263671875 +66430 0.870361328125 +66431 0.870361328125 +66432 0.860015869140625 +66433 0.727935791015625 +66434 0.48114013671875 +66435 0.2059326171875 +66436 -0.06103515625 +66437 -0.29913330078125 +66438 -0.516204833984375 +66439 -0.7252197265625 +66440 -0.85980224609375 +66441 -0.870391845703125 +66442 -0.870391845703125 +66443 -0.858062744140625 +66444 -0.673004150390625 +66445 -0.42694091796875 +66446 -0.2100830078125 +66447 -0.0362548828125 +66448 0.10943603515625 +66449 0.23516845703125 +66450 0.373687744140625 +66451 0.517791748046875 +66452 0.602783203125 +66453 0.635711669921875 +66454 0.655181884765625 +66455 0.65948486328125 +66456 0.651275634765625 +66457 0.61846923828125 +66458 0.53753662109375 +66459 0.404144287109375 +66460 0.22186279296875 +66461 0.003997802734375 +66462 -0.22100830078125 +66463 -0.42449951171875 +66464 -0.579833984375 +66465 -0.641876220703125 +66466 -0.6177978515625 +66467 -0.575531005859375 +66468 -0.526336669921875 +66469 -0.42645263671875 +66470 -0.2581787109375 +66471 -0.068695068359375 +66472 0.09222412109375 +66473 0.232147216796875 +66474 0.3509521484375 +66475 0.410064697265625 +66476 0.372955322265625 +66477 0.2554931640625 +66478 0.10711669921875 +66479 -0.052886962890625 +66480 -0.186279296875 +66481 -0.23291015625 +66482 -0.209442138671875 +66483 -0.174163818359375 +66484 -0.126739501953125 +66485 -0.048126220703125 +66486 0.0426025390625 +66487 0.10748291015625 +66488 0.1409912109375 +66489 0.19708251953125 +66490 0.273651123046875 +66491 0.31768798828125 +66492 0.341094970703125 +66493 0.368011474609375 +66494 0.37249755859375 +66495 0.30072021484375 +66496 0.1517333984375 +66497 -0.01470947265625 +66498 -0.1883544921875 +66499 -0.372711181640625 +66500 -0.51397705078125 +66501 -0.57177734375 +66502 -0.53948974609375 +66503 -0.43511962890625 +66504 -0.2962646484375 +66505 -0.161102294921875 +66506 -0.0435791015625 +66507 0.060394287109375 +66508 0.13665771484375 +66509 0.170135498046875 +66510 0.16552734375 +66511 0.15728759765625 +66512 0.150787353515625 +66513 0.12200927734375 +66514 0.080108642578125 +66515 0.05126953125 +66516 0.062896728515625 +66517 0.09271240234375 +66518 0.092987060546875 +66519 0.07855224609375 +66520 0.06427001953125 +66521 0.0347900390625 +66522 -0.01171875 +66523 -0.056060791015625 +66524 -0.055511474609375 +66525 -0.010467529296875 +66526 0.02508544921875 +66527 0.025665283203125 +66528 0.017333984375 +66529 0.00189208984375 +66530 -0.03173828125 +66531 -0.071502685546875 +66532 -0.13543701171875 +66533 -0.219970703125 +66534 -0.300506591796875 +66535 -0.376312255859375 +66536 -0.416107177734375 +66537 -0.371124267578125 +66538 -0.242279052734375 +66539 -0.069732666015625 +66540 0.125640869140625 +66541 0.31268310546875 +66542 0.45501708984375 +66543 0.554779052734375 +66544 0.61065673828125 +66545 0.610931396484375 +66546 0.531463623046875 +66547 0.3883056640625 +66548 0.23468017578125 +66549 0.095245361328125 +66550 -0.00396728515625 +66551 -0.04852294921875 +66552 -0.055145263671875 +66553 -0.0758056640625 +66554 -0.138702392578125 +66555 -0.209197998046875 +66556 -0.289031982421875 +66557 -0.37884521484375 +66558 -0.456329345703125 +66559 -0.51641845703125 +66560 -0.519287109375 +66561 -0.458251953125 +66562 -0.384796142578125 +66563 -0.323699951171875 +66564 -0.269287109375 +66565 -0.1951904296875 +66566 -0.100006103515625 +66567 -0.01055908203125 +66568 0.1033935546875 +66569 0.24908447265625 +66570 0.373199462890625 +66571 0.45806884765625 +66572 0.511474609375 +66573 0.565399169921875 +66574 0.61138916015625 +66575 0.5897216796875 +66576 0.4906005859375 +66577 0.33148193359375 +66578 0.147796630859375 +66579 -0.01873779296875 +66580 -0.140289306640625 +66581 -0.191986083984375 +66582 -0.184295654296875 +66583 -0.161834716796875 +66584 -0.166595458984375 +66585 -0.19390869140625 +66586 -0.22442626953125 +66587 -0.279754638671875 +66588 -0.3389892578125 +66589 -0.3543701171875 +66590 -0.348175048828125 +66591 -0.32598876953125 +66592 -0.2581787109375 +66593 -0.139801025390625 +66594 0.014617919921875 +66595 0.144378662109375 +66596 0.221038818359375 +66597 0.27069091796875 +66598 0.294036865234375 +66599 0.311767578125 +66600 0.339141845703125 +66601 0.360260009765625 +66602 0.360504150390625 +66603 0.308380126953125 +66604 0.18170166015625 +66605 0.0047607421875 +66606 -0.17559814453125 +66607 -0.3143310546875 +66608 -0.36785888671875 +66609 -0.36248779296875 +66610 -0.343536376953125 +66611 -0.3018798828125 +66612 -0.231414794921875 +66613 -0.117645263671875 +66614 0.007049560546875 +66615 0.087982177734375 +66616 0.13946533203125 +66617 0.17425537109375 +66618 0.188201904296875 +66619 0.171234130859375 +66620 0.118438720703125 +66621 0.05706787109375 +66622 -0.010711669921875 +66623 -0.0914306640625 +66624 -0.162322998046875 +66625 -0.194549560546875 +66626 -0.1492919921875 +66627 -0.02166748046875 +66628 0.124053955078125 +66629 0.211151123046875 +66630 0.240447998046875 +66631 0.242218017578125 +66632 0.2257080078125 +66633 0.194366455078125 +66634 0.115509033203125 +66635 0.0128173828125 +66636 -0.053802490234375 +66637 -0.110626220703125 +66638 -0.199493408203125 +66639 -0.29437255859375 +66640 -0.33221435546875 +66641 -0.27972412109375 +66642 -0.185333251953125 +66643 -0.128204345703125 +66644 -0.115692138671875 +66645 -0.116455078125 +66646 -0.105926513671875 +66647 -0.053955078125 +66648 0.048797607421875 +66649 0.157318115234375 +66650 0.212005615234375 +66651 0.218475341796875 +66652 0.23724365234375 +66653 0.30535888671875 +66654 0.38128662109375 +66655 0.404449462890625 +66656 0.3944091796875 +66657 0.3885498046875 +66658 0.362640380859375 +66659 0.27362060546875 +66660 0.11712646484375 +66661 -0.054901123046875 +66662 -0.19085693359375 +66663 -0.28570556640625 +66664 -0.339263916015625 +66665 -0.3775634765625 +66666 -0.445709228515625 +66667 -0.535064697265625 +66668 -0.629058837890625 +66669 -0.697601318359375 +66670 -0.70391845703125 +66671 -0.6424560546875 +66672 -0.491241455078125 +66673 -0.265716552734375 +66674 -0.023712158203125 +66675 0.201751708984375 +66676 0.375823974609375 +66677 0.485076904296875 +66678 0.56884765625 +66679 0.634765625 +66680 0.63763427734375 +66681 0.5660400390625 +66682 0.4720458984375 +66683 0.40692138671875 +66684 0.3778076171875 +66685 0.376953125 +66686 0.371978759765625 +66687 0.313140869140625 +66688 0.184417724609375 +66689 0.011199951171875 +66690 -0.171051025390625 +66691 -0.33740234375 +66692 -0.47198486328125 +66693 -0.560394287109375 +66694 -0.58056640625 +66695 -0.54754638671875 +66696 -0.508575439453125 +66697 -0.459503173828125 +66698 -0.394378662109375 +66699 -0.35260009765625 +66700 -0.31170654296875 +66701 -0.197418212890625 +66702 -0.007965087890625 +66703 0.207489013671875 +66704 0.409210205078125 +66705 0.57208251953125 +66706 0.66595458984375 +66707 0.65875244140625 +66708 0.56744384765625 +66709 0.431396484375 +66710 0.29443359375 +66711 0.182464599609375 +66712 0.06365966796875 +66713 -0.075958251953125 +66714 -0.189422607421875 +66715 -0.271942138671875 +66716 -0.342529296875 +66717 -0.364166259765625 +66718 -0.327239990234375 +66719 -0.2769775390625 +66720 -0.253692626953125 +66721 -0.24365234375 +66722 -0.1983642578125 +66723 -0.116241455078125 +66724 -0.036834716796875 +66725 0.034881591796875 +66726 0.09124755859375 +66727 0.10888671875 +66728 0.125518798828125 +66729 0.15771484375 +66730 0.17828369140625 +66731 0.17108154296875 +66732 0.129974365234375 +66733 0.082427978515625 +66734 0.027679443359375 +66735 -0.065643310546875 +66736 -0.15936279296875 +66737 -0.21307373046875 +66738 -0.234649658203125 +66739 -0.2001953125 +66740 -0.119171142578125 +66741 -0.024749755859375 +66742 0.085784912109375 +66743 0.178131103515625 +66744 0.215576171875 +66745 0.211456298828125 +66746 0.17523193359375 +66747 0.128753662109375 +66748 0.1019287109375 +66749 0.0743408203125 +66750 0.04327392578125 +66751 0.038177490234375 +66752 0.076263427734375 +66753 0.14105224609375 +66754 0.186431884765625 +66755 0.188812255859375 +66756 0.1390380859375 +66757 0.041778564453125 +66758 -0.079437255859375 +66759 -0.219390869140625 +66760 -0.367828369140625 +66761 -0.494873046875 +66762 -0.556243896484375 +66763 -0.508697509765625 +66764 -0.3756103515625 +66765 -0.218902587890625 +66766 -0.063751220703125 +66767 0.091552734375 +66768 0.23602294921875 +66769 0.342987060546875 +66770 0.39520263671875 +66771 0.389373779296875 +66772 0.324249267578125 +66773 0.224090576171875 +66774 0.124267578125 +66775 0.037078857421875 +66776 -0.010101318359375 +66777 -0.019439697265625 +66778 -0.022796630859375 +66779 -0.001556396484375 +66780 0.056304931640625 +66781 0.106719970703125 +66782 0.096893310546875 +66783 0.042694091796875 +66784 -0.018035888671875 +66785 -0.07586669921875 +66786 -0.11944580078125 +66787 -0.15972900390625 +66788 -0.202606201171875 +66789 -0.24859619140625 +66790 -0.30517578125 +66791 -0.36212158203125 +66792 -0.39141845703125 +66793 -0.35528564453125 +66794 -0.249969482421875 +66795 -0.092864990234375 +66796 0.08905029296875 +66797 0.2352294921875 +66798 0.318817138671875 +66799 0.358642578125 +66800 0.347747802734375 +66801 0.28564453125 +66802 0.223175048828125 +66803 0.196746826171875 +66804 0.179840087890625 +66805 0.155548095703125 +66806 0.151214599609375 +66807 0.156951904296875 +66808 0.13177490234375 +66809 0.100799560546875 +66810 0.087127685546875 +66811 0.05487060546875 +66812 -0.009002685546875 +66813 -0.10400390625 +66814 -0.229400634765625 +66815 -0.35552978515625 +66816 -0.441925048828125 +66817 -0.473846435546875 +66818 -0.464813232421875 +66819 -0.419097900390625 +66820 -0.334320068359375 +66821 -0.227935791015625 +66822 -0.12347412109375 +66823 -0.02764892578125 +66824 0.077667236328125 +66825 0.2132568359375 +66826 0.38885498046875 +66827 0.582794189453125 +66828 0.734039306640625 +66829 0.800140380859375 +66830 0.7783203125 +66831 0.6651611328125 +66832 0.45965576171875 +66833 0.199188232421875 +66834 -0.050689697265625 +66835 -0.23297119140625 +66836 -0.33013916015625 +66837 -0.368408203125 +66838 -0.378936767578125 +66839 -0.376983642578125 +66840 -0.37969970703125 +66841 -0.391510009765625 +66842 -0.385345458984375 +66843 -0.3419189453125 +66844 -0.28289794921875 +66845 -0.251617431640625 +66846 -0.266143798828125 +66847 -0.273345947265625 +66848 -0.216796875 +66849 -0.128265380859375 +66850 -0.068145751953125 +66851 -0.0430908203125 +66852 -0.024444580078125 +66853 0.020721435546875 +66854 0.124481201171875 +66855 0.25787353515625 +66856 0.379119873046875 +66857 0.47991943359375 +66858 0.5281982421875 +66859 0.511138916015625 +66860 0.456207275390625 +66861 0.407470703125 +66862 0.383758544921875 +66863 0.35687255859375 +66864 0.31182861328125 +66865 0.250885009765625 +66866 0.1654052734375 +66867 0.035247802734375 +66868 -0.142059326171875 +66869 -0.33563232421875 +66870 -0.5345458984375 +66871 -0.72186279296875 +66872 -0.836669921875 +66873 -0.8326416015625 +66874 -0.7296142578125 +66875 -0.582550048828125 +66876 -0.440093994140625 +66877 -0.324310302734375 +66878 -0.20147705078125 +66879 -0.044647216796875 +66880 0.103973388671875 +66881 0.202392578125 +66882 0.264495849609375 +66883 0.338897705078125 +66884 0.443817138671875 +66885 0.545074462890625 +66886 0.6173095703125 +66887 0.6524658203125 +66888 0.66339111328125 +66889 0.6561279296875 +66890 0.606781005859375 +66891 0.501190185546875 +66892 0.352783203125 +66893 0.176544189453125 +66894 -0.034820556640625 +66895 -0.258209228515625 +66896 -0.44244384765625 +66897 -0.5753173828125 +66898 -0.65203857421875 +66899 -0.641632080078125 +66900 -0.562164306640625 +66901 -0.458038330078125 +66902 -0.350555419921875 +66903 -0.260528564453125 +66904 -0.192108154296875 +66905 -0.141937255859375 +66906 -0.1021728515625 +66907 -0.062896728515625 +66908 -0.011932373046875 +66909 0.062835693359375 +66910 0.148712158203125 +66911 0.241729736328125 +66912 0.34912109375 +66913 0.457305908203125 +66914 0.54388427734375 +66915 0.5728759765625 +66916 0.506591796875 +66917 0.351226806640625 +66918 0.146514892578125 +66919 -0.05523681640625 +66920 -0.21624755859375 +66921 -0.334930419921875 +66922 -0.402984619140625 +66923 -0.4412841796875 +66924 -0.49578857421875 +66925 -0.5601806640625 +66926 -0.600738525390625 +66927 -0.584228515625 +66928 -0.47930908203125 +66929 -0.27935791015625 +66930 -0.0089111328125 +66931 0.268798828125 +66932 0.482818603515625 +66933 0.60369873046875 +66934 0.650421142578125 +66935 0.66400146484375 +66936 0.6414794921875 +66937 0.572540283203125 +66938 0.498138427734375 +66939 0.439453125 +66940 0.375518798828125 +66941 0.274505615234375 +66942 0.1087646484375 +66943 -0.099395751953125 +66944 -0.3182373046875 +66945 -0.5489501953125 +66946 -0.7738037109375 +66947 -0.86383056640625 +66948 -0.870391845703125 +66949 -0.86895751953125 +66950 -0.861053466796875 +66951 -0.765869140625 +66952 -0.5301513671875 +66953 -0.214691162109375 +66954 0.137359619140625 +66955 0.474822998046875 +66956 0.76239013671875 +66957 0.867462158203125 +66958 0.870361328125 +66959 0.86480712890625 +66960 0.831817626953125 +66961 0.677581787109375 +66962 0.495880126953125 +66963 0.30767822265625 +66964 0.116180419921875 +66965 -0.110748291015625 +66966 -0.381805419921875 +66967 -0.6572265625 +66968 -0.857421875 +66969 -0.870391845703125 +66970 -0.870391845703125 +66971 -0.86444091796875 +66972 -0.85723876953125 +66973 -0.790008544921875 +66974 -0.62847900390625 +66975 -0.3956298828125 +66976 -0.126708984375 +66977 0.150115966796875 +66978 0.424041748046875 +66979 0.670623779296875 +66980 0.854522705078125 +66981 0.866485595703125 +66982 0.86920166015625 +66983 0.8653564453125 +66984 0.857147216796875 +66985 0.766845703125 +66986 0.628509521484375 +66987 0.462127685546875 +66988 0.297210693359375 +66989 0.14862060546875 +66990 -0.00537109375 +66991 -0.15753173828125 +66992 -0.31304931640625 +66993 -0.48876953125 +66994 -0.6416015625 +66995 -0.751373291015625 +66996 -0.84619140625 +66997 -0.861297607421875 +66998 -0.863250732421875 +66999 -0.856597900390625 +67000 -0.7498779296875 +67001 -0.624542236328125 +67002 -0.47808837890625 +67003 -0.253387451171875 +67004 0.003692626953125 +67005 0.2257080078125 +67006 0.427154541015625 +67007 0.643218994140625 +67008 0.855926513671875 +67009 0.870361328125 +67010 0.870361328125 +67011 0.862762451171875 +67012 0.79669189453125 +67013 0.595794677734375 +67014 0.362152099609375 +67015 0.1270751953125 +67016 -0.086944580078125 +67017 -0.2784423828125 +67018 -0.484832763671875 +67019 -0.729583740234375 +67020 -0.86688232421875 +67021 -0.870391845703125 +67022 -0.86859130859375 +67023 -0.86279296875 +67024 -0.817962646484375 +67025 -0.6116943359375 +67026 -0.3128662109375 +67027 0.039398193359375 +67028 0.422821044921875 +67029 0.805145263671875 +67030 0.870361328125 +67031 0.870361328125 +67032 0.860015869140625 +67033 0.727935791015625 +67034 0.48114013671875 +67035 0.2059326171875 +67036 -0.06103515625 +67037 -0.29913330078125 +67038 -0.516204833984375 +67039 -0.7252197265625 +67040 -0.85980224609375 +67041 -0.870391845703125 +67042 -0.870391845703125 +67043 -0.858062744140625 +67044 -0.673004150390625 +67045 -0.42694091796875 +67046 -0.2100830078125 +67047 -0.0362548828125 +67048 0.10943603515625 +67049 0.23516845703125 +67050 0.373687744140625 +67051 0.517791748046875 +67052 0.602783203125 +67053 0.635711669921875 +67054 0.655181884765625 +67055 0.65948486328125 +67056 0.651275634765625 +67057 0.61846923828125 +67058 0.53753662109375 +67059 0.404144287109375 +67060 0.22186279296875 +67061 0.003997802734375 +67062 -0.22100830078125 +67063 -0.42449951171875 +67064 -0.579833984375 +67065 -0.641876220703125 +67066 -0.6177978515625 +67067 -0.575531005859375 +67068 -0.526336669921875 +67069 -0.42645263671875 +67070 -0.2581787109375 +67071 -0.068695068359375 +67072 0.09222412109375 +67073 0.232147216796875 +67074 0.3509521484375 +67075 0.410064697265625 +67076 0.372955322265625 +67077 0.2554931640625 +67078 0.10711669921875 +67079 -0.052886962890625 +67080 -0.186279296875 +67081 -0.23291015625 +67082 -0.209442138671875 +67083 -0.174163818359375 +67084 -0.126739501953125 +67085 -0.048126220703125 +67086 0.0426025390625 +67087 0.10748291015625 +67088 0.1409912109375 +67089 0.19708251953125 +67090 0.273651123046875 +67091 0.31768798828125 +67092 0.341094970703125 +67093 0.368011474609375 +67094 0.37249755859375 +67095 0.30072021484375 +67096 0.1517333984375 +67097 -0.01470947265625 +67098 -0.1883544921875 +67099 -0.372711181640625 +67100 -0.51397705078125 +67101 -0.57177734375 +67102 -0.53948974609375 +67103 -0.43511962890625 +67104 -0.2962646484375 +67105 -0.161102294921875 +67106 -0.0435791015625 +67107 0.060394287109375 +67108 0.13665771484375 +67109 0.170135498046875 +67110 0.16552734375 +67111 0.15728759765625 +67112 0.150787353515625 +67113 0.12200927734375 +67114 0.080108642578125 +67115 0.05126953125 +67116 0.062896728515625 +67117 0.09271240234375 +67118 0.092987060546875 +67119 0.07855224609375 +67120 0.06427001953125 +67121 0.0347900390625 +67122 -0.01171875 +67123 -0.056060791015625 +67124 -0.055511474609375 +67125 -0.010467529296875 +67126 0.02508544921875 +67127 0.025665283203125 +67128 0.017333984375 +67129 0.00189208984375 +67130 -0.03173828125 +67131 -0.071502685546875 +67132 -0.13543701171875 +67133 -0.219970703125 +67134 -0.300506591796875 +67135 -0.376312255859375 +67136 -0.416107177734375 +67137 -0.371124267578125 +67138 -0.242279052734375 +67139 -0.069732666015625 +67140 0.125640869140625 +67141 0.31268310546875 +67142 0.45501708984375 +67143 0.554779052734375 +67144 0.61065673828125 +67145 0.610931396484375 +67146 0.531463623046875 +67147 0.3883056640625 +67148 0.23468017578125 +67149 0.095245361328125 +67150 -0.00396728515625 +67151 -0.04852294921875 +67152 -0.055145263671875 +67153 -0.0758056640625 +67154 -0.138702392578125 +67155 -0.209197998046875 +67156 -0.289031982421875 +67157 -0.37884521484375 +67158 -0.456329345703125 +67159 -0.51641845703125 +67160 -0.519287109375 +67161 -0.458251953125 +67162 -0.384796142578125 +67163 -0.323699951171875 +67164 -0.269287109375 +67165 -0.1951904296875 +67166 -0.100006103515625 +67167 -0.01055908203125 +67168 0.1033935546875 +67169 0.24908447265625 +67170 0.373199462890625 +67171 0.45806884765625 +67172 0.511474609375 +67173 0.565399169921875 +67174 0.61138916015625 +67175 0.5897216796875 +67176 0.4906005859375 +67177 0.33148193359375 +67178 0.147796630859375 +67179 -0.01873779296875 +67180 -0.140289306640625 +67181 -0.191986083984375 +67182 -0.184295654296875 +67183 -0.161834716796875 +67184 -0.166595458984375 +67185 -0.19390869140625 +67186 -0.22442626953125 +67187 -0.279754638671875 +67188 -0.3389892578125 +67189 -0.3543701171875 +67190 -0.348175048828125 +67191 -0.32598876953125 +67192 -0.2581787109375 +67193 -0.139801025390625 +67194 0.014617919921875 +67195 0.144378662109375 +67196 0.221038818359375 +67197 0.27069091796875 +67198 0.294036865234375 +67199 0.311767578125 +67200 0.339141845703125 +67201 0.360260009765625 +67202 0.360504150390625 +67203 0.308380126953125 +67204 0.18170166015625 +67205 0.0047607421875 +67206 -0.17559814453125 +67207 -0.3143310546875 +67208 -0.36785888671875 +67209 -0.36248779296875 +67210 -0.343536376953125 +67211 -0.3018798828125 +67212 -0.231414794921875 +67213 -0.117645263671875 +67214 0.007049560546875 +67215 0.087982177734375 +67216 0.13946533203125 +67217 0.17425537109375 +67218 0.188201904296875 +67219 0.171234130859375 +67220 0.118438720703125 +67221 0.05706787109375 +67222 -0.010711669921875 +67223 -0.0914306640625 +67224 -0.162322998046875 +67225 -0.194549560546875 +67226 -0.1492919921875 +67227 -0.02166748046875 +67228 0.124053955078125 +67229 0.211151123046875 +67230 0.240447998046875 +67231 0.242218017578125 +67232 0.2257080078125 +67233 0.194366455078125 +67234 0.115509033203125 +67235 0.0128173828125 +67236 -0.053802490234375 +67237 -0.110626220703125 +67238 -0.199493408203125 +67239 -0.29437255859375 +67240 -0.33221435546875 +67241 -0.27972412109375 +67242 -0.185333251953125 +67243 -0.128204345703125 +67244 -0.115692138671875 +67245 -0.116455078125 +67246 -0.105926513671875 +67247 -0.053955078125 +67248 0.048797607421875 +67249 0.157318115234375 +67250 0.212005615234375 +67251 0.218475341796875 +67252 0.23724365234375 +67253 0.30535888671875 +67254 0.38128662109375 +67255 0.404449462890625 +67256 0.3944091796875 +67257 0.3885498046875 +67258 0.362640380859375 +67259 0.27362060546875 +67260 0.11712646484375 +67261 -0.054901123046875 +67262 -0.19085693359375 +67263 -0.28570556640625 +67264 -0.339263916015625 +67265 -0.3775634765625 +67266 -0.445709228515625 +67267 -0.535064697265625 +67268 -0.629058837890625 +67269 -0.697601318359375 +67270 -0.70391845703125 +67271 -0.6424560546875 +67272 -0.491241455078125 +67273 -0.265716552734375 +67274 -0.023712158203125 +67275 0.201751708984375 +67276 0.375823974609375 +67277 0.485076904296875 +67278 0.56884765625 +67279 0.634765625 +67280 0.63763427734375 +67281 0.5660400390625 +67282 0.4720458984375 +67283 0.40692138671875 +67284 0.3778076171875 +67285 0.376953125 +67286 0.371978759765625 +67287 0.313140869140625 +67288 0.184417724609375 +67289 0.011199951171875 +67290 -0.171051025390625 +67291 -0.33740234375 +67292 -0.47198486328125 +67293 -0.560394287109375 +67294 -0.58056640625 +67295 -0.54754638671875 +67296 -0.508575439453125 +67297 -0.459503173828125 +67298 -0.394378662109375 +67299 -0.35260009765625 +67300 -0.31170654296875 +67301 -0.197418212890625 +67302 -0.007965087890625 +67303 0.207489013671875 +67304 0.409210205078125 +67305 0.57208251953125 +67306 0.66595458984375 +67307 0.65875244140625 +67308 0.56744384765625 +67309 0.431396484375 +67310 0.29443359375 +67311 0.182464599609375 +67312 0.06365966796875 +67313 -0.075958251953125 +67314 -0.189422607421875 +67315 -0.271942138671875 +67316 -0.342529296875 +67317 -0.364166259765625 +67318 -0.327239990234375 +67319 -0.2769775390625 +67320 -0.253692626953125 +67321 -0.24365234375 +67322 -0.1983642578125 +67323 -0.116241455078125 +67324 -0.036834716796875 +67325 0.034881591796875 +67326 0.09124755859375 +67327 0.10888671875 +67328 0.125518798828125 +67329 0.15771484375 +67330 0.17828369140625 +67331 0.17108154296875 +67332 0.129974365234375 +67333 0.082427978515625 +67334 0.027679443359375 +67335 -0.065643310546875 +67336 -0.15936279296875 +67337 -0.21307373046875 +67338 -0.234649658203125 +67339 -0.2001953125 +67340 -0.119171142578125 +67341 -0.024749755859375 +67342 0.085784912109375 +67343 0.178131103515625 +67344 0.215576171875 +67345 0.211456298828125 +67346 0.17523193359375 +67347 0.128753662109375 +67348 0.1019287109375 +67349 0.0743408203125 +67350 0.04327392578125 +67351 0.038177490234375 +67352 0.076263427734375 +67353 0.14105224609375 +67354 0.186431884765625 +67355 0.188812255859375 +67356 0.1390380859375 +67357 0.041778564453125 +67358 -0.079437255859375 +67359 -0.219390869140625 +67360 -0.367828369140625 +67361 -0.494873046875 +67362 -0.556243896484375 +67363 -0.508697509765625 +67364 -0.3756103515625 +67365 -0.218902587890625 +67366 -0.063751220703125 +67367 0.091552734375 +67368 0.23602294921875 +67369 0.342987060546875 +67370 0.39520263671875 +67371 0.389373779296875 +67372 0.324249267578125 +67373 0.224090576171875 +67374 0.124267578125 +67375 0.037078857421875 +67376 -0.010101318359375 +67377 -0.019439697265625 +67378 -0.022796630859375 +67379 -0.001556396484375 +67380 0.056304931640625 +67381 0.106719970703125 +67382 0.096893310546875 +67383 0.042694091796875 +67384 -0.018035888671875 +67385 -0.07586669921875 +67386 -0.11944580078125 +67387 -0.15972900390625 +67388 -0.202606201171875 +67389 -0.24859619140625 +67390 -0.30517578125 +67391 -0.36212158203125 +67392 -0.39141845703125 +67393 -0.35528564453125 +67394 -0.249969482421875 +67395 -0.092864990234375 +67396 0.08905029296875 +67397 0.2352294921875 +67398 0.318817138671875 +67399 0.358642578125 +67400 0.347747802734375 +67401 0.28564453125 +67402 0.223175048828125 +67403 0.196746826171875 +67404 0.179840087890625 +67405 0.155548095703125 +67406 0.151214599609375 +67407 0.156951904296875 +67408 0.13177490234375 +67409 0.100799560546875 +67410 0.087127685546875 +67411 0.05487060546875 +67412 -0.009002685546875 +67413 -0.10400390625 +67414 -0.229400634765625 +67415 -0.35552978515625 +67416 -0.441925048828125 +67417 -0.473846435546875 +67418 -0.464813232421875 +67419 -0.419097900390625 +67420 -0.334320068359375 +67421 -0.227935791015625 +67422 -0.12347412109375 +67423 -0.02764892578125 +67424 0.077667236328125 +67425 0.2132568359375 +67426 0.38885498046875 +67427 0.582794189453125 +67428 0.734039306640625 +67429 0.800140380859375 +67430 0.7783203125 +67431 0.6651611328125 +67432 0.45965576171875 +67433 0.199188232421875 +67434 -0.050689697265625 +67435 -0.23297119140625 +67436 -0.33013916015625 +67437 -0.368408203125 +67438 -0.378936767578125 +67439 -0.376983642578125 +67440 -0.37969970703125 +67441 -0.391510009765625 +67442 -0.385345458984375 +67443 -0.3419189453125 +67444 -0.28289794921875 +67445 -0.251617431640625 +67446 -0.266143798828125 +67447 -0.273345947265625 +67448 -0.216796875 +67449 -0.128265380859375 +67450 -0.068145751953125 +67451 -0.0430908203125 +67452 -0.024444580078125 +67453 0.020721435546875 +67454 0.124481201171875 +67455 0.25787353515625 +67456 0.379119873046875 +67457 0.47991943359375 +67458 0.5281982421875 +67459 0.511138916015625 +67460 0.456207275390625 +67461 0.407470703125 +67462 0.383758544921875 +67463 0.35687255859375 +67464 0.31182861328125 +67465 0.250885009765625 +67466 0.1654052734375 +67467 0.035247802734375 +67468 -0.142059326171875 +67469 -0.33563232421875 +67470 -0.5345458984375 +67471 -0.72186279296875 +67472 -0.836669921875 +67473 -0.8326416015625 +67474 -0.7296142578125 +67475 -0.582550048828125 +67476 -0.440093994140625 +67477 -0.324310302734375 +67478 -0.20147705078125 +67479 -0.044647216796875 +67480 0.103973388671875 +67481 0.202392578125 +67482 0.264495849609375 +67483 0.338897705078125 +67484 0.443817138671875 +67485 0.545074462890625 +67486 0.6173095703125 +67487 0.6524658203125 +67488 0.66339111328125 +67489 0.6561279296875 +67490 0.606781005859375 +67491 0.501190185546875 +67492 0.352783203125 +67493 0.176544189453125 +67494 -0.034820556640625 +67495 -0.258209228515625 +67496 -0.44244384765625 +67497 -0.5753173828125 +67498 -0.65203857421875 +67499 -0.641632080078125 +67500 -0.562164306640625 +67501 -0.458038330078125 +67502 -0.350555419921875 +67503 -0.260528564453125 +67504 -0.192108154296875 +67505 -0.141937255859375 +67506 -0.1021728515625 +67507 -0.062896728515625 +67508 -0.011932373046875 +67509 0.062835693359375 +67510 0.148712158203125 +67511 0.241729736328125 +67512 0.34912109375 +67513 0.457305908203125 +67514 0.54388427734375 +67515 0.5728759765625 +67516 0.506591796875 +67517 0.351226806640625 +67518 0.146514892578125 +67519 -0.05523681640625 +67520 -0.21624755859375 +67521 -0.334930419921875 +67522 -0.402984619140625 +67523 -0.4412841796875 +67524 -0.49578857421875 +67525 -0.5601806640625 +67526 -0.600738525390625 +67527 -0.584228515625 +67528 -0.47930908203125 +67529 -0.27935791015625 +67530 -0.0089111328125 +67531 0.268798828125 +67532 0.482818603515625 +67533 0.60369873046875 +67534 0.650421142578125 +67535 0.66400146484375 +67536 0.6414794921875 +67537 0.572540283203125 +67538 0.498138427734375 +67539 0.439453125 +67540 0.375518798828125 +67541 0.274505615234375 +67542 0.1087646484375 +67543 -0.099395751953125 +67544 -0.3182373046875 +67545 -0.5489501953125 +67546 -0.7738037109375 +67547 -0.86383056640625 +67548 -0.870391845703125 +67549 -0.86895751953125 +67550 -0.861053466796875 +67551 -0.765869140625 +67552 -0.5301513671875 +67553 -0.214691162109375 +67554 0.137359619140625 +67555 0.474822998046875 +67556 0.76239013671875 +67557 0.867462158203125 +67558 0.870361328125 +67559 0.86480712890625 +67560 0.831817626953125 +67561 0.677581787109375 +67562 0.495880126953125 +67563 0.30767822265625 +67564 0.116180419921875 +67565 -0.110748291015625 +67566 -0.381805419921875 +67567 -0.6572265625 +67568 -0.857421875 +67569 -0.870391845703125 +67570 -0.870391845703125 +67571 -0.86444091796875 +67572 -0.85723876953125 +67573 -0.790008544921875 +67574 -0.62847900390625 +67575 -0.3956298828125 +67576 -0.126708984375 +67577 0.150115966796875 +67578 0.424041748046875 +67579 0.670623779296875 +67580 0.854522705078125 +67581 0.866485595703125 +67582 0.86920166015625 +67583 0.8653564453125 +67584 0.857147216796875 +67585 0.766845703125 +67586 0.628509521484375 +67587 0.462127685546875 +67588 0.297210693359375 +67589 0.14862060546875 +67590 -0.00537109375 +67591 -0.15753173828125 +67592 -0.31304931640625 +67593 -0.48876953125 +67594 -0.6416015625 +67595 -0.751373291015625 +67596 -0.84619140625 +67597 -0.861297607421875 +67598 -0.863250732421875 +67599 -0.856597900390625 +67600 -0.7498779296875 +67601 -0.624542236328125 +67602 -0.47808837890625 +67603 -0.253387451171875 +67604 0.003692626953125 +67605 0.2257080078125 +67606 0.427154541015625 +67607 0.643218994140625 +67608 0.855926513671875 +67609 0.870361328125 +67610 0.870361328125 +67611 0.862762451171875 +67612 0.79669189453125 +67613 0.595794677734375 +67614 0.362152099609375 +67615 0.1270751953125 +67616 -0.086944580078125 +67617 -0.2784423828125 +67618 -0.484832763671875 +67619 -0.729583740234375 +67620 -0.86688232421875 +67621 -0.870391845703125 +67622 -0.86859130859375 +67623 -0.86279296875 +67624 -0.817962646484375 +67625 -0.6116943359375 +67626 -0.3128662109375 +67627 0.039398193359375 +67628 0.422821044921875 +67629 0.805145263671875 +67630 0.870361328125 +67631 0.870361328125 +67632 0.860015869140625 +67633 0.727935791015625 +67634 0.48114013671875 +67635 0.2059326171875 +67636 -0.06103515625 +67637 -0.29913330078125 +67638 -0.516204833984375 +67639 -0.7252197265625 +67640 -0.85980224609375 +67641 -0.870391845703125 +67642 -0.870391845703125 +67643 -0.858062744140625 +67644 -0.673004150390625 +67645 -0.42694091796875 +67646 -0.2100830078125 +67647 -0.0362548828125 +67648 0.10943603515625 +67649 0.23516845703125 +67650 0.373687744140625 +67651 0.517791748046875 +67652 0.602783203125 +67653 0.635711669921875 +67654 0.655181884765625 +67655 0.65948486328125 +67656 0.651275634765625 +67657 0.61846923828125 +67658 0.53753662109375 +67659 0.404144287109375 +67660 0.22186279296875 +67661 0.003997802734375 +67662 -0.22100830078125 +67663 -0.42449951171875 +67664 -0.579833984375 +67665 -0.641876220703125 +67666 -0.6177978515625 +67667 -0.575531005859375 +67668 -0.526336669921875 +67669 -0.42645263671875 +67670 -0.2581787109375 +67671 -0.068695068359375 +67672 0.09222412109375 +67673 0.232147216796875 +67674 0.3509521484375 +67675 0.410064697265625 +67676 0.372955322265625 +67677 0.2554931640625 +67678 0.10711669921875 +67679 -0.052886962890625 +67680 -0.186279296875 +67681 -0.23291015625 +67682 -0.209442138671875 +67683 -0.174163818359375 +67684 -0.126739501953125 +67685 -0.048126220703125 +67686 0.0426025390625 +67687 0.10748291015625 +67688 0.1409912109375 +67689 0.19708251953125 +67690 0.273651123046875 +67691 0.31768798828125 +67692 0.341094970703125 +67693 0.368011474609375 +67694 0.37249755859375 +67695 0.30072021484375 +67696 0.1517333984375 +67697 -0.01470947265625 +67698 -0.1883544921875 +67699 -0.372711181640625 +67700 -0.51397705078125 +67701 -0.57177734375 +67702 -0.53948974609375 +67703 -0.43511962890625 +67704 -0.2962646484375 +67705 -0.161102294921875 +67706 -0.0435791015625 +67707 0.060394287109375 +67708 0.13665771484375 +67709 0.170135498046875 +67710 0.16552734375 +67711 0.15728759765625 +67712 0.150787353515625 +67713 0.12200927734375 +67714 0.080108642578125 +67715 0.05126953125 +67716 0.062896728515625 +67717 0.09271240234375 +67718 0.092987060546875 +67719 0.07855224609375 +67720 0.06427001953125 +67721 0.0347900390625 +67722 -0.01171875 +67723 -0.056060791015625 +67724 -0.055511474609375 +67725 -0.010467529296875 +67726 0.02508544921875 +67727 0.025665283203125 +67728 0.017333984375 +67729 0.00189208984375 +67730 -0.03173828125 +67731 -0.071502685546875 +67732 -0.13543701171875 +67733 -0.219970703125 +67734 -0.300506591796875 +67735 -0.376312255859375 +67736 -0.416107177734375 +67737 -0.371124267578125 +67738 -0.242279052734375 +67739 -0.069732666015625 +67740 0.125640869140625 +67741 0.31268310546875 +67742 0.45501708984375 +67743 0.554779052734375 +67744 0.61065673828125 +67745 0.610931396484375 +67746 0.531463623046875 +67747 0.3883056640625 +67748 0.23468017578125 +67749 0.095245361328125 +67750 -0.00396728515625 +67751 -0.04852294921875 +67752 -0.055145263671875 +67753 -0.0758056640625 +67754 -0.138702392578125 +67755 -0.209197998046875 +67756 -0.289031982421875 +67757 -0.37884521484375 +67758 -0.456329345703125 +67759 -0.51641845703125 +67760 -0.519287109375 +67761 -0.458251953125 +67762 -0.384796142578125 +67763 -0.323699951171875 +67764 -0.269287109375 +67765 -0.1951904296875 +67766 -0.100006103515625 +67767 -0.01055908203125 +67768 0.1033935546875 +67769 0.24908447265625 +67770 0.373199462890625 +67771 0.45806884765625 +67772 0.511474609375 +67773 0.565399169921875 +67774 0.61138916015625 +67775 0.5897216796875 +67776 0.4906005859375 +67777 0.33148193359375 +67778 0.147796630859375 +67779 -0.01873779296875 +67780 -0.140289306640625 +67781 -0.191986083984375 +67782 -0.184295654296875 +67783 -0.161834716796875 +67784 -0.166595458984375 +67785 -0.19390869140625 +67786 -0.22442626953125 +67787 -0.279754638671875 +67788 -0.3389892578125 +67789 -0.3543701171875 +67790 -0.348175048828125 +67791 -0.32598876953125 +67792 -0.2581787109375 +67793 -0.139801025390625 +67794 0.014617919921875 +67795 0.144378662109375 +67796 0.221038818359375 +67797 0.27069091796875 +67798 0.294036865234375 +67799 0.311767578125 +67800 0.339141845703125 +67801 0.360260009765625 +67802 0.360504150390625 +67803 0.308380126953125 +67804 0.18170166015625 +67805 0.0047607421875 +67806 -0.17559814453125 +67807 -0.3143310546875 +67808 -0.36785888671875 +67809 -0.36248779296875 +67810 -0.343536376953125 +67811 -0.3018798828125 +67812 -0.231414794921875 +67813 -0.117645263671875 +67814 0.007049560546875 +67815 0.087982177734375 +67816 0.13946533203125 +67817 0.17425537109375 +67818 0.188201904296875 +67819 0.171234130859375 +67820 0.118438720703125 +67821 0.05706787109375 +67822 -0.010711669921875 +67823 -0.0914306640625 +67824 -0.162322998046875 +67825 -0.194549560546875 +67826 -0.1492919921875 +67827 -0.02166748046875 +67828 0.124053955078125 +67829 0.211151123046875 +67830 0.240447998046875 +67831 0.242218017578125 +67832 0.2257080078125 +67833 0.194366455078125 +67834 0.115509033203125 +67835 0.0128173828125 +67836 -0.053802490234375 +67837 -0.110626220703125 +67838 -0.199493408203125 +67839 -0.29437255859375 +67840 -0.33221435546875 +67841 -0.27972412109375 +67842 -0.185333251953125 +67843 -0.128204345703125 +67844 -0.115692138671875 +67845 -0.116455078125 +67846 -0.105926513671875 +67847 -0.053955078125 +67848 0.048797607421875 +67849 0.157318115234375 +67850 0.212005615234375 +67851 0.218475341796875 +67852 0.23724365234375 +67853 0.30535888671875 +67854 0.38128662109375 +67855 0.404449462890625 +67856 0.3944091796875 +67857 0.3885498046875 +67858 0.362640380859375 +67859 0.27362060546875 +67860 0.11712646484375 +67861 -0.054901123046875 +67862 -0.19085693359375 +67863 -0.28570556640625 +67864 -0.339263916015625 +67865 -0.3775634765625 +67866 -0.445709228515625 +67867 -0.535064697265625 +67868 -0.629058837890625 +67869 -0.697601318359375 +67870 -0.70391845703125 +67871 -0.6424560546875 +67872 -0.491241455078125 +67873 -0.265716552734375 +67874 -0.023712158203125 +67875 0.201751708984375 +67876 0.375823974609375 +67877 0.485076904296875 +67878 0.56884765625 +67879 0.634765625 +67880 0.63763427734375 +67881 0.5660400390625 +67882 0.4720458984375 +67883 0.40692138671875 +67884 0.3778076171875 +67885 0.376953125 +67886 0.371978759765625 +67887 0.313140869140625 +67888 0.184417724609375 +67889 0.011199951171875 +67890 -0.171051025390625 +67891 -0.33740234375 +67892 -0.47198486328125 +67893 -0.560394287109375 +67894 -0.58056640625 +67895 -0.54754638671875 +67896 -0.508575439453125 +67897 -0.459503173828125 +67898 -0.394378662109375 +67899 -0.35260009765625 +67900 -0.31170654296875 +67901 -0.197418212890625 +67902 -0.007965087890625 +67903 0.207489013671875 +67904 0.409210205078125 +67905 0.57208251953125 +67906 0.66595458984375 +67907 0.65875244140625 +67908 0.56744384765625 +67909 0.431396484375 +67910 0.29443359375 +67911 0.182464599609375 +67912 0.06365966796875 +67913 -0.075958251953125 +67914 -0.189422607421875 +67915 -0.271942138671875 +67916 -0.342529296875 +67917 -0.364166259765625 +67918 -0.327239990234375 +67919 -0.2769775390625 +67920 -0.253692626953125 +67921 -0.24365234375 +67922 -0.1983642578125 +67923 -0.116241455078125 +67924 -0.036834716796875 +67925 0.034881591796875 +67926 0.09124755859375 +67927 0.10888671875 +67928 0.125518798828125 +67929 0.15771484375 +67930 0.17828369140625 +67931 0.17108154296875 +67932 0.129974365234375 +67933 0.082427978515625 +67934 0.027679443359375 +67935 -0.065643310546875 +67936 -0.15936279296875 +67937 -0.21307373046875 +67938 -0.234649658203125 +67939 -0.2001953125 +67940 -0.119171142578125 +67941 -0.024749755859375 +67942 0.085784912109375 +67943 0.178131103515625 +67944 0.215576171875 +67945 0.211456298828125 +67946 0.17523193359375 +67947 0.128753662109375 +67948 0.1019287109375 +67949 0.0743408203125 +67950 0.04327392578125 +67951 0.038177490234375 +67952 0.076263427734375 +67953 0.14105224609375 +67954 0.186431884765625 +67955 0.188812255859375 +67956 0.1390380859375 +67957 0.041778564453125 +67958 -0.079437255859375 +67959 -0.219390869140625 +67960 -0.367828369140625 +67961 -0.494873046875 +67962 -0.556243896484375 +67963 -0.508697509765625 +67964 -0.3756103515625 +67965 -0.218902587890625 +67966 -0.063751220703125 +67967 0.091552734375 +67968 0.23602294921875 +67969 0.342987060546875 +67970 0.39520263671875 +67971 0.389373779296875 +67972 0.324249267578125 +67973 0.224090576171875 +67974 0.124267578125 +67975 0.037078857421875 +67976 -0.010101318359375 +67977 -0.019439697265625 +67978 -0.022796630859375 +67979 -0.001556396484375 +67980 0.056304931640625 +67981 0.106719970703125 +67982 0.096893310546875 +67983 0.042694091796875 +67984 -0.018035888671875 +67985 -0.07586669921875 +67986 -0.11944580078125 +67987 -0.15972900390625 +67988 -0.202606201171875 +67989 -0.24859619140625 +67990 -0.30517578125 +67991 -0.36212158203125 +67992 -0.39141845703125 +67993 -0.35528564453125 +67994 -0.249969482421875 +67995 -0.092864990234375 +67996 0.08905029296875 +67997 0.2352294921875 +67998 0.318817138671875 +67999 0.358642578125 +68000 0.347747802734375 +68001 0.28564453125 +68002 0.223175048828125 +68003 0.196746826171875 +68004 0.179840087890625 +68005 0.155548095703125 +68006 0.151214599609375 +68007 0.156951904296875 +68008 0.13177490234375 +68009 0.100799560546875 +68010 0.087127685546875 +68011 0.05487060546875 +68012 -0.009002685546875 +68013 -0.10400390625 +68014 -0.229400634765625 +68015 -0.35552978515625 +68016 -0.441925048828125 +68017 -0.473846435546875 +68018 -0.464813232421875 +68019 -0.419097900390625 +68020 -0.334320068359375 +68021 -0.227935791015625 +68022 -0.12347412109375 +68023 -0.02764892578125 +68024 0.077667236328125 +68025 0.2132568359375 +68026 0.38885498046875 +68027 0.582794189453125 +68028 0.734039306640625 +68029 0.800140380859375 +68030 0.7783203125 +68031 0.6651611328125 +68032 0.45965576171875 +68033 0.199188232421875 +68034 -0.050689697265625 +68035 -0.23297119140625 +68036 -0.33013916015625 +68037 -0.368408203125 +68038 -0.378936767578125 +68039 -0.376983642578125 +68040 -0.37969970703125 +68041 -0.391510009765625 +68042 -0.385345458984375 +68043 -0.3419189453125 +68044 -0.28289794921875 +68045 -0.251617431640625 +68046 -0.266143798828125 +68047 -0.273345947265625 +68048 -0.216796875 +68049 -0.128265380859375 +68050 -0.068145751953125 +68051 -0.0430908203125 +68052 -0.024444580078125 +68053 0.020721435546875 +68054 0.124481201171875 +68055 0.25787353515625 +68056 0.379119873046875 +68057 0.47991943359375 +68058 0.5281982421875 +68059 0.511138916015625 +68060 0.456207275390625 +68061 0.407470703125 +68062 0.383758544921875 +68063 0.35687255859375 +68064 0.31182861328125 +68065 0.250885009765625 +68066 0.1654052734375 +68067 0.035247802734375 +68068 -0.142059326171875 +68069 -0.33563232421875 +68070 -0.5345458984375 +68071 -0.72186279296875 +68072 -0.836669921875 +68073 -0.8326416015625 +68074 -0.7296142578125 +68075 -0.582550048828125 +68076 -0.440093994140625 +68077 -0.324310302734375 +68078 -0.20147705078125 +68079 -0.044647216796875 +68080 0.103973388671875 +68081 0.202392578125 +68082 0.264495849609375 +68083 0.338897705078125 +68084 0.443817138671875 +68085 0.545074462890625 +68086 0.6173095703125 +68087 0.6524658203125 +68088 0.66339111328125 +68089 0.6561279296875 +68090 0.606781005859375 +68091 0.501190185546875 +68092 0.352783203125 +68093 0.176544189453125 +68094 -0.034820556640625 +68095 -0.258209228515625 +68096 -0.44244384765625 +68097 -0.5753173828125 +68098 -0.65203857421875 +68099 -0.641632080078125 +68100 -0.562164306640625 +68101 -0.458038330078125 +68102 -0.350555419921875 +68103 -0.260528564453125 +68104 -0.192108154296875 +68105 -0.141937255859375 +68106 -0.1021728515625 +68107 -0.062896728515625 +68108 -0.011932373046875 +68109 0.062835693359375 +68110 0.148712158203125 +68111 0.241729736328125 +68112 0.34912109375 +68113 0.457305908203125 +68114 0.54388427734375 +68115 0.5728759765625 +68116 0.506591796875 +68117 0.351226806640625 +68118 0.146514892578125 +68119 -0.05523681640625 +68120 -0.21624755859375 +68121 -0.334930419921875 +68122 -0.402984619140625 +68123 -0.4412841796875 +68124 -0.49578857421875 +68125 -0.5601806640625 +68126 -0.600738525390625 +68127 -0.584228515625 +68128 -0.47930908203125 +68129 -0.27935791015625 +68130 -0.0089111328125 +68131 0.268798828125 +68132 0.482818603515625 +68133 0.60369873046875 +68134 0.650421142578125 +68135 0.66400146484375 +68136 0.6414794921875 +68137 0.572540283203125 +68138 0.498138427734375 +68139 0.439453125 +68140 0.375518798828125 +68141 0.274505615234375 +68142 0.1087646484375 +68143 -0.099395751953125 +68144 -0.3182373046875 +68145 -0.5489501953125 +68146 -0.7738037109375 +68147 -0.86383056640625 +68148 -0.870391845703125 +68149 -0.86895751953125 +68150 -0.861053466796875 +68151 -0.765869140625 +68152 -0.5301513671875 +68153 -0.214691162109375 +68154 0.137359619140625 +68155 0.474822998046875 +68156 0.76239013671875 +68157 0.867462158203125 +68158 0.870361328125 +68159 0.86480712890625 +68160 0.831817626953125 +68161 0.677581787109375 +68162 0.495880126953125 +68163 0.30767822265625 +68164 0.116180419921875 +68165 -0.110748291015625 +68166 -0.381805419921875 +68167 -0.6572265625 +68168 -0.857421875 +68169 -0.870391845703125 +68170 -0.870391845703125 +68171 -0.86444091796875 +68172 -0.85723876953125 +68173 -0.790008544921875 +68174 -0.62847900390625 +68175 -0.3956298828125 +68176 -0.126708984375 +68177 0.150115966796875 +68178 0.424041748046875 +68179 0.670623779296875 +68180 0.854522705078125 +68181 0.866485595703125 +68182 0.86920166015625 +68183 0.8653564453125 +68184 0.857147216796875 +68185 0.766845703125 +68186 0.628509521484375 +68187 0.462127685546875 +68188 0.297210693359375 +68189 0.14862060546875 +68190 -0.00537109375 +68191 -0.15753173828125 +68192 -0.31304931640625 +68193 -0.48876953125 +68194 -0.6416015625 +68195 -0.751373291015625 +68196 -0.84619140625 +68197 -0.861297607421875 +68198 -0.863250732421875 +68199 -0.856597900390625 +68200 -0.7498779296875 +68201 -0.624542236328125 +68202 -0.47808837890625 +68203 -0.253387451171875 +68204 0.003692626953125 +68205 0.2257080078125 +68206 0.427154541015625 +68207 0.643218994140625 +68208 0.855926513671875 +68209 0.870361328125 +68210 0.870361328125 +68211 0.862762451171875 +68212 0.79669189453125 +68213 0.595794677734375 +68214 0.362152099609375 +68215 0.1270751953125 +68216 -0.086944580078125 +68217 -0.2784423828125 +68218 -0.484832763671875 +68219 -0.729583740234375 +68220 -0.86688232421875 +68221 -0.870391845703125 +68222 -0.86859130859375 +68223 -0.86279296875 +68224 -0.817962646484375 +68225 -0.6116943359375 +68226 -0.3128662109375 +68227 0.039398193359375 +68228 0.422821044921875 +68229 0.805145263671875 +68230 0.870361328125 +68231 0.870361328125 +68232 0.860015869140625 +68233 0.727935791015625 +68234 0.48114013671875 +68235 0.2059326171875 +68236 -0.06103515625 +68237 -0.29913330078125 +68238 -0.516204833984375 +68239 -0.7252197265625 +68240 -0.85980224609375 +68241 -0.870391845703125 +68242 -0.870391845703125 +68243 -0.858062744140625 +68244 -0.673004150390625 +68245 -0.42694091796875 +68246 -0.2100830078125 +68247 -0.0362548828125 +68248 0.10943603515625 +68249 0.23516845703125 +68250 0.373687744140625 +68251 0.517791748046875 +68252 0.602783203125 +68253 0.635711669921875 +68254 0.655181884765625 +68255 0.65948486328125 +68256 0.651275634765625 +68257 0.61846923828125 +68258 0.53753662109375 +68259 0.404144287109375 +68260 0.22186279296875 +68261 0.003997802734375 +68262 -0.22100830078125 +68263 -0.42449951171875 +68264 -0.579833984375 +68265 -0.641876220703125 +68266 -0.6177978515625 +68267 -0.575531005859375 +68268 -0.526336669921875 +68269 -0.42645263671875 +68270 -0.2581787109375 +68271 -0.068695068359375 +68272 0.09222412109375 +68273 0.232147216796875 +68274 0.3509521484375 +68275 0.410064697265625 +68276 0.372955322265625 +68277 0.2554931640625 +68278 0.10711669921875 +68279 -0.052886962890625 +68280 -0.186279296875 +68281 -0.23291015625 +68282 -0.209442138671875 +68283 -0.174163818359375 +68284 -0.126739501953125 +68285 -0.048126220703125 +68286 0.0426025390625 +68287 0.10748291015625 +68288 0.1409912109375 +68289 0.19708251953125 +68290 0.273651123046875 +68291 0.31768798828125 +68292 0.341094970703125 +68293 0.368011474609375 +68294 0.37249755859375 +68295 0.30072021484375 +68296 0.1517333984375 +68297 -0.01470947265625 +68298 -0.1883544921875 +68299 -0.372711181640625 +68300 -0.51397705078125 +68301 -0.57177734375 +68302 -0.53948974609375 +68303 -0.43511962890625 +68304 -0.2962646484375 +68305 -0.161102294921875 +68306 -0.0435791015625 +68307 0.060394287109375 +68308 0.13665771484375 +68309 0.170135498046875 +68310 0.16552734375 +68311 0.15728759765625 +68312 0.150787353515625 +68313 0.12200927734375 +68314 0.080108642578125 +68315 0.05126953125 +68316 0.062896728515625 +68317 0.09271240234375 +68318 0.092987060546875 +68319 0.07855224609375 +68320 0.06427001953125 +68321 0.0347900390625 +68322 -0.01171875 +68323 -0.056060791015625 +68324 -0.055511474609375 +68325 -0.010467529296875 +68326 0.02508544921875 +68327 0.025665283203125 +68328 0.017333984375 +68329 0.00189208984375 +68330 -0.03173828125 +68331 -0.071502685546875 +68332 -0.13543701171875 +68333 -0.219970703125 +68334 -0.300506591796875 +68335 -0.376312255859375 +68336 -0.416107177734375 +68337 -0.371124267578125 +68338 -0.242279052734375 +68339 -0.069732666015625 +68340 0.125640869140625 +68341 0.31268310546875 +68342 0.45501708984375 +68343 0.554779052734375 +68344 0.61065673828125 +68345 0.610931396484375 +68346 0.531463623046875 +68347 0.3883056640625 +68348 0.23468017578125 +68349 0.095245361328125 +68350 -0.00396728515625 +68351 -0.04852294921875 +68352 -0.055145263671875 +68353 -0.0758056640625 +68354 -0.138702392578125 +68355 -0.209197998046875 +68356 -0.289031982421875 +68357 -0.37884521484375 +68358 -0.456329345703125 +68359 -0.51641845703125 +68360 -0.519287109375 +68361 -0.458251953125 +68362 -0.384796142578125 +68363 -0.323699951171875 +68364 -0.269287109375 +68365 -0.1951904296875 +68366 -0.100006103515625 +68367 -0.01055908203125 +68368 0.1033935546875 +68369 0.24908447265625 +68370 0.373199462890625 +68371 0.45806884765625 +68372 0.511474609375 +68373 0.565399169921875 +68374 0.61138916015625 +68375 0.5897216796875 +68376 0.4906005859375 +68377 0.33148193359375 +68378 0.147796630859375 +68379 -0.01873779296875 +68380 -0.140289306640625 +68381 -0.191986083984375 +68382 -0.184295654296875 +68383 -0.161834716796875 +68384 -0.166595458984375 +68385 -0.19390869140625 +68386 -0.22442626953125 +68387 -0.279754638671875 +68388 -0.3389892578125 +68389 -0.3543701171875 +68390 -0.348175048828125 +68391 -0.32598876953125 +68392 -0.2581787109375 +68393 -0.139801025390625 +68394 0.014617919921875 +68395 0.144378662109375 +68396 0.221038818359375 +68397 0.27069091796875 +68398 0.294036865234375 +68399 0.311767578125 +68400 0.339141845703125 +68401 0.360260009765625 +68402 0.360504150390625 +68403 0.308380126953125 +68404 0.18170166015625 +68405 0.0047607421875 +68406 -0.17559814453125 +68407 -0.3143310546875 +68408 -0.36785888671875 +68409 -0.36248779296875 +68410 -0.343536376953125 +68411 -0.3018798828125 +68412 -0.231414794921875 +68413 -0.117645263671875 +68414 0.007049560546875 +68415 0.087982177734375 +68416 0.13946533203125 +68417 0.17425537109375 +68418 0.188201904296875 +68419 0.171234130859375 +68420 0.118438720703125 +68421 0.05706787109375 +68422 -0.010711669921875 +68423 -0.0914306640625 +68424 -0.162322998046875 +68425 -0.194549560546875 +68426 -0.1492919921875 +68427 -0.02166748046875 +68428 0.124053955078125 +68429 0.211151123046875 +68430 0.240447998046875 +68431 0.242218017578125 +68432 0.2257080078125 +68433 0.194366455078125 +68434 0.115509033203125 +68435 0.0128173828125 +68436 -0.053802490234375 +68437 -0.110626220703125 +68438 -0.199493408203125 +68439 -0.29437255859375 +68440 -0.33221435546875 +68441 -0.27972412109375 +68442 -0.185333251953125 +68443 -0.128204345703125 +68444 -0.115692138671875 +68445 -0.116455078125 +68446 -0.105926513671875 +68447 -0.053955078125 +68448 0.048797607421875 +68449 0.157318115234375 +68450 0.212005615234375 +68451 0.218475341796875 +68452 0.23724365234375 +68453 0.30535888671875 +68454 0.38128662109375 +68455 0.404449462890625 +68456 0.3944091796875 +68457 0.3885498046875 +68458 0.362640380859375 +68459 0.27362060546875 +68460 0.11712646484375 +68461 -0.054901123046875 +68462 -0.19085693359375 +68463 -0.28570556640625 +68464 -0.339263916015625 +68465 -0.3775634765625 +68466 -0.445709228515625 +68467 -0.535064697265625 +68468 -0.629058837890625 +68469 -0.697601318359375 +68470 -0.70391845703125 +68471 -0.6424560546875 +68472 -0.491241455078125 +68473 -0.265716552734375 +68474 -0.023712158203125 +68475 0.201751708984375 +68476 0.375823974609375 +68477 0.485076904296875 +68478 0.56884765625 +68479 0.634765625 +68480 0.63763427734375 +68481 0.5660400390625 +68482 0.4720458984375 +68483 0.40692138671875 +68484 0.3778076171875 +68485 0.376953125 +68486 0.371978759765625 +68487 0.313140869140625 +68488 0.184417724609375 +68489 0.011199951171875 +68490 -0.171051025390625 +68491 -0.33740234375 +68492 -0.47198486328125 +68493 -0.560394287109375 +68494 -0.58056640625 +68495 -0.54754638671875 +68496 -0.508575439453125 +68497 -0.459503173828125 +68498 -0.394378662109375 +68499 -0.35260009765625 +68500 -0.31170654296875 +68501 -0.197418212890625 +68502 -0.007965087890625 +68503 0.207489013671875 +68504 0.409210205078125 +68505 0.57208251953125 +68506 0.66595458984375 +68507 0.65875244140625 +68508 0.56744384765625 +68509 0.431396484375 +68510 0.29443359375 +68511 0.182464599609375 +68512 0.06365966796875 +68513 -0.075958251953125 +68514 -0.189422607421875 +68515 -0.271942138671875 +68516 -0.342529296875 +68517 -0.364166259765625 +68518 -0.327239990234375 +68519 -0.2769775390625 +68520 -0.253692626953125 +68521 -0.24365234375 +68522 -0.1983642578125 +68523 -0.116241455078125 +68524 -0.036834716796875 +68525 0.034881591796875 +68526 0.09124755859375 +68527 0.10888671875 +68528 0.125518798828125 +68529 0.15771484375 +68530 0.17828369140625 +68531 0.17108154296875 +68532 0.129974365234375 +68533 0.082427978515625 +68534 0.027679443359375 +68535 -0.065643310546875 +68536 -0.15936279296875 +68537 -0.21307373046875 +68538 -0.234649658203125 +68539 -0.2001953125 +68540 -0.119171142578125 +68541 -0.024749755859375 +68542 0.085784912109375 +68543 0.178131103515625 +68544 0.215576171875 +68545 0.211456298828125 +68546 0.17523193359375 +68547 0.128753662109375 +68548 0.1019287109375 +68549 0.0743408203125 +68550 0.04327392578125 +68551 0.038177490234375 +68552 0.076263427734375 +68553 0.14105224609375 +68554 0.186431884765625 +68555 0.188812255859375 +68556 0.1390380859375 +68557 0.041778564453125 +68558 -0.079437255859375 +68559 -0.219390869140625 +68560 -0.367828369140625 +68561 -0.494873046875 +68562 -0.556243896484375 +68563 -0.508697509765625 +68564 -0.3756103515625 +68565 -0.218902587890625 +68566 -0.063751220703125 +68567 0.091552734375 +68568 0.23602294921875 +68569 0.342987060546875 +68570 0.39520263671875 +68571 0.389373779296875 +68572 0.324249267578125 +68573 0.224090576171875 +68574 0.124267578125 +68575 0.037078857421875 +68576 -0.010101318359375 +68577 -0.019439697265625 +68578 -0.022796630859375 +68579 -0.001556396484375 +68580 0.056304931640625 +68581 0.106719970703125 +68582 0.096893310546875 +68583 0.042694091796875 +68584 -0.018035888671875 +68585 -0.07586669921875 +68586 -0.11944580078125 +68587 -0.15972900390625 +68588 -0.202606201171875 +68589 -0.24859619140625 +68590 -0.30517578125 +68591 -0.36212158203125 +68592 -0.39141845703125 +68593 -0.35528564453125 +68594 -0.249969482421875 +68595 -0.092864990234375 +68596 0.08905029296875 +68597 0.2352294921875 +68598 0.318817138671875 +68599 0.358642578125 +68600 0.347747802734375 +68601 0.28564453125 +68602 0.223175048828125 +68603 0.196746826171875 +68604 0.179840087890625 +68605 0.155548095703125 +68606 0.151214599609375 +68607 0.156951904296875 +68608 0.13177490234375 +68609 0.100799560546875 +68610 0.087127685546875 +68611 0.05487060546875 +68612 -0.009002685546875 +68613 -0.10400390625 +68614 -0.229400634765625 +68615 -0.35552978515625 +68616 -0.441925048828125 +68617 -0.473846435546875 +68618 -0.464813232421875 +68619 -0.419097900390625 +68620 -0.334320068359375 +68621 -0.227935791015625 +68622 -0.12347412109375 +68623 -0.02764892578125 +68624 0.077667236328125 +68625 0.2132568359375 +68626 0.38885498046875 +68627 0.582794189453125 +68628 0.734039306640625 +68629 0.800140380859375 +68630 0.7783203125 +68631 0.6651611328125 +68632 0.45965576171875 +68633 0.199188232421875 +68634 -0.050689697265625 +68635 -0.23297119140625 +68636 -0.33013916015625 +68637 -0.368408203125 +68638 -0.378936767578125 +68639 -0.376983642578125 +68640 -0.37969970703125 +68641 -0.391510009765625 +68642 -0.385345458984375 +68643 -0.3419189453125 +68644 -0.28289794921875 +68645 -0.251617431640625 +68646 -0.266143798828125 +68647 -0.273345947265625 +68648 -0.216796875 +68649 -0.128265380859375 +68650 -0.068145751953125 +68651 -0.0430908203125 +68652 -0.024444580078125 +68653 0.020721435546875 +68654 0.124481201171875 +68655 0.25787353515625 +68656 0.379119873046875 +68657 0.47991943359375 +68658 0.5281982421875 +68659 0.511138916015625 +68660 0.456207275390625 +68661 0.407470703125 +68662 0.383758544921875 +68663 0.35687255859375 +68664 0.31182861328125 +68665 0.250885009765625 +68666 0.1654052734375 +68667 0.035247802734375 +68668 -0.142059326171875 +68669 -0.33563232421875 +68670 -0.5345458984375 +68671 -0.72186279296875 +68672 -0.836669921875 +68673 -0.8326416015625 +68674 -0.7296142578125 +68675 -0.582550048828125 +68676 -0.440093994140625 +68677 -0.324310302734375 +68678 -0.20147705078125 +68679 -0.044647216796875 +68680 0.103973388671875 +68681 0.202392578125 +68682 0.264495849609375 +68683 0.338897705078125 +68684 0.443817138671875 +68685 0.545074462890625 +68686 0.6173095703125 +68687 0.6524658203125 +68688 0.66339111328125 +68689 0.6561279296875 +68690 0.606781005859375 +68691 0.501190185546875 +68692 0.352783203125 +68693 0.176544189453125 +68694 -0.034820556640625 +68695 -0.258209228515625 +68696 -0.44244384765625 +68697 -0.5753173828125 +68698 -0.65203857421875 +68699 -0.641632080078125 +68700 -0.562164306640625 +68701 -0.458038330078125 +68702 -0.350555419921875 +68703 -0.260528564453125 +68704 -0.192108154296875 +68705 -0.141937255859375 +68706 -0.1021728515625 +68707 -0.062896728515625 +68708 -0.011932373046875 +68709 0.062835693359375 +68710 0.148712158203125 +68711 0.241729736328125 +68712 0.34912109375 +68713 0.457305908203125 +68714 0.54388427734375 +68715 0.5728759765625 +68716 0.506591796875 +68717 0.351226806640625 +68718 0.146514892578125 +68719 -0.05523681640625 +68720 -0.21624755859375 +68721 -0.334930419921875 +68722 -0.402984619140625 +68723 -0.4412841796875 +68724 -0.49578857421875 +68725 -0.5601806640625 +68726 -0.600738525390625 +68727 -0.584228515625 +68728 -0.47930908203125 +68729 -0.27935791015625 +68730 -0.0089111328125 +68731 0.268798828125 +68732 0.482818603515625 +68733 0.60369873046875 +68734 0.650421142578125 +68735 0.66400146484375 +68736 0.6414794921875 +68737 0.572540283203125 +68738 0.498138427734375 +68739 0.439453125 +68740 0.375518798828125 +68741 0.274505615234375 +68742 0.1087646484375 +68743 -0.099395751953125 +68744 -0.3182373046875 +68745 -0.5489501953125 +68746 -0.7738037109375 +68747 -0.86383056640625 +68748 -0.870391845703125 +68749 -0.86895751953125 +68750 -0.861053466796875 +68751 -0.765869140625 +68752 -0.5301513671875 +68753 -0.214691162109375 +68754 0.137359619140625 +68755 0.474822998046875 +68756 0.76239013671875 +68757 0.867462158203125 +68758 0.870361328125 +68759 0.86480712890625 +68760 0.831817626953125 +68761 0.677581787109375 +68762 0.495880126953125 +68763 0.30767822265625 +68764 0.116180419921875 +68765 -0.110748291015625 +68766 -0.381805419921875 +68767 -0.6572265625 +68768 -0.857421875 +68769 -0.870391845703125 +68770 -0.870391845703125 +68771 -0.86444091796875 +68772 -0.85723876953125 +68773 -0.790008544921875 +68774 -0.62847900390625 +68775 -0.3956298828125 +68776 -0.126708984375 +68777 0.150115966796875 +68778 0.424041748046875 +68779 0.670623779296875 +68780 0.854522705078125 +68781 0.866485595703125 +68782 0.86920166015625 +68783 0.8653564453125 +68784 0.857147216796875 +68785 0.766845703125 +68786 0.628509521484375 +68787 0.462127685546875 +68788 0.297210693359375 +68789 0.14862060546875 +68790 -0.00537109375 +68791 -0.15753173828125 +68792 -0.31304931640625 +68793 -0.48876953125 +68794 -0.6416015625 +68795 -0.751373291015625 +68796 -0.84619140625 +68797 -0.861297607421875 +68798 -0.863250732421875 +68799 -0.856597900390625 +68800 -0.7498779296875 +68801 -0.624542236328125 +68802 -0.47808837890625 +68803 -0.253387451171875 +68804 0.003692626953125 +68805 0.2257080078125 +68806 0.427154541015625 +68807 0.643218994140625 +68808 0.855926513671875 +68809 0.870361328125 +68810 0.870361328125 +68811 0.862762451171875 +68812 0.79669189453125 +68813 0.595794677734375 +68814 0.362152099609375 +68815 0.1270751953125 +68816 -0.086944580078125 +68817 -0.2784423828125 +68818 -0.484832763671875 +68819 -0.729583740234375 +68820 -0.86688232421875 +68821 -0.870391845703125 +68822 -0.86859130859375 +68823 -0.86279296875 +68824 -0.817962646484375 +68825 -0.6116943359375 +68826 -0.3128662109375 +68827 0.039398193359375 +68828 0.422821044921875 +68829 0.805145263671875 +68830 0.870361328125 +68831 0.870361328125 +68832 0.860015869140625 +68833 0.727935791015625 +68834 0.48114013671875 +68835 0.2059326171875 +68836 -0.06103515625 +68837 -0.29913330078125 +68838 -0.516204833984375 +68839 -0.7252197265625 +68840 -0.85980224609375 +68841 -0.870391845703125 +68842 -0.870391845703125 +68843 -0.858062744140625 +68844 -0.673004150390625 +68845 -0.42694091796875 +68846 -0.2100830078125 +68847 -0.0362548828125 +68848 0.10943603515625 +68849 0.23516845703125 +68850 0.373687744140625 +68851 0.517791748046875 +68852 0.602783203125 +68853 0.635711669921875 +68854 0.655181884765625 +68855 0.65948486328125 +68856 0.651275634765625 +68857 0.61846923828125 +68858 0.53753662109375 +68859 0.404144287109375 +68860 0.22186279296875 +68861 0.003997802734375 +68862 -0.22100830078125 +68863 -0.42449951171875 +68864 -0.579833984375 +68865 -0.641876220703125 +68866 -0.6177978515625 +68867 -0.575531005859375 +68868 -0.526336669921875 +68869 -0.42645263671875 +68870 -0.2581787109375 +68871 -0.068695068359375 +68872 0.09222412109375 +68873 0.232147216796875 +68874 0.3509521484375 +68875 0.410064697265625 +68876 0.372955322265625 +68877 0.2554931640625 +68878 0.10711669921875 +68879 -0.052886962890625 +68880 -0.186279296875 +68881 -0.23291015625 +68882 -0.209442138671875 +68883 -0.174163818359375 +68884 -0.126739501953125 +68885 -0.048126220703125 +68886 0.0426025390625 +68887 0.10748291015625 +68888 0.1409912109375 +68889 0.19708251953125 +68890 0.273651123046875 +68891 0.31768798828125 +68892 0.341094970703125 +68893 0.368011474609375 +68894 0.37249755859375 +68895 0.30072021484375 +68896 0.1517333984375 +68897 -0.01470947265625 +68898 -0.1883544921875 +68899 -0.372711181640625 +68900 -0.51397705078125 +68901 -0.57177734375 +68902 -0.53948974609375 +68903 -0.43511962890625 +68904 -0.2962646484375 +68905 -0.161102294921875 +68906 -0.0435791015625 +68907 0.060394287109375 +68908 0.13665771484375 +68909 0.170135498046875 +68910 0.16552734375 +68911 0.15728759765625 +68912 0.150787353515625 +68913 0.12200927734375 +68914 0.080108642578125 +68915 0.05126953125 +68916 0.062896728515625 +68917 0.09271240234375 +68918 0.092987060546875 +68919 0.07855224609375 +68920 0.06427001953125 +68921 0.0347900390625 +68922 -0.01171875 +68923 -0.056060791015625 +68924 -0.055511474609375 +68925 -0.010467529296875 +68926 0.02508544921875 +68927 0.025665283203125 +68928 0.017333984375 +68929 0.00189208984375 +68930 -0.03173828125 +68931 -0.071502685546875 +68932 -0.13543701171875 +68933 -0.219970703125 +68934 -0.300506591796875 +68935 -0.376312255859375 +68936 -0.416107177734375 +68937 -0.371124267578125 +68938 -0.242279052734375 +68939 -0.069732666015625 +68940 0.125640869140625 +68941 0.31268310546875 +68942 0.45501708984375 +68943 0.554779052734375 +68944 0.61065673828125 +68945 0.610931396484375 +68946 0.531463623046875 +68947 0.3883056640625 +68948 0.23468017578125 +68949 0.095245361328125 +68950 -0.00396728515625 +68951 -0.04852294921875 +68952 -0.055145263671875 +68953 -0.0758056640625 +68954 -0.138702392578125 +68955 -0.209197998046875 +68956 -0.289031982421875 +68957 -0.37884521484375 +68958 -0.456329345703125 +68959 -0.51641845703125 +68960 -0.519287109375 +68961 -0.458251953125 +68962 -0.384796142578125 +68963 -0.323699951171875 +68964 -0.269287109375 +68965 -0.1951904296875 +68966 -0.100006103515625 +68967 -0.01055908203125 +68968 0.1033935546875 +68969 0.24908447265625 +68970 0.373199462890625 +68971 0.45806884765625 +68972 0.511474609375 +68973 0.565399169921875 +68974 0.61138916015625 +68975 0.5897216796875 +68976 0.4906005859375 +68977 0.33148193359375 +68978 0.147796630859375 +68979 -0.01873779296875 +68980 -0.140289306640625 +68981 -0.191986083984375 +68982 -0.184295654296875 +68983 -0.161834716796875 +68984 -0.166595458984375 +68985 -0.19390869140625 +68986 -0.22442626953125 +68987 -0.279754638671875 +68988 -0.3389892578125 +68989 -0.3543701171875 +68990 -0.348175048828125 +68991 -0.32598876953125 +68992 -0.2581787109375 +68993 -0.139801025390625 +68994 0.014617919921875 +68995 0.144378662109375 +68996 0.221038818359375 +68997 0.27069091796875 +68998 0.294036865234375 +68999 0.311767578125 +69000 0.339141845703125 +69001 0.360260009765625 +69002 0.360504150390625 +69003 0.308380126953125 +69004 0.18170166015625 +69005 0.0047607421875 +69006 -0.17559814453125 +69007 -0.3143310546875 +69008 -0.36785888671875 +69009 -0.36248779296875 +69010 -0.343536376953125 +69011 -0.3018798828125 +69012 -0.231414794921875 +69013 -0.117645263671875 +69014 0.007049560546875 +69015 0.087982177734375 +69016 0.13946533203125 +69017 0.17425537109375 +69018 0.188201904296875 +69019 0.171234130859375 +69020 0.118438720703125 +69021 0.05706787109375 +69022 -0.010711669921875 +69023 -0.0914306640625 +69024 -0.162322998046875 +69025 -0.194549560546875 +69026 -0.1492919921875 +69027 -0.02166748046875 +69028 0.124053955078125 +69029 0.211151123046875 +69030 0.240447998046875 +69031 0.242218017578125 +69032 0.2257080078125 +69033 0.194366455078125 +69034 0.115509033203125 +69035 0.0128173828125 +69036 -0.053802490234375 +69037 -0.110626220703125 +69038 -0.199493408203125 +69039 -0.29437255859375 +69040 -0.33221435546875 +69041 -0.27972412109375 +69042 -0.185333251953125 +69043 -0.128204345703125 +69044 -0.115692138671875 +69045 -0.116455078125 +69046 -0.105926513671875 +69047 -0.053955078125 +69048 0.048797607421875 +69049 0.157318115234375 +69050 0.212005615234375 +69051 0.218475341796875 +69052 0.23724365234375 +69053 0.30535888671875 +69054 0.38128662109375 +69055 0.404449462890625 +69056 0.3944091796875 +69057 0.3885498046875 +69058 0.362640380859375 +69059 0.27362060546875 +69060 0.11712646484375 +69061 -0.054901123046875 +69062 -0.19085693359375 +69063 -0.28570556640625 +69064 -0.339263916015625 +69065 -0.3775634765625 +69066 -0.445709228515625 +69067 -0.535064697265625 +69068 -0.629058837890625 +69069 -0.697601318359375 +69070 -0.70391845703125 +69071 -0.6424560546875 +69072 -0.491241455078125 +69073 -0.265716552734375 +69074 -0.023712158203125 +69075 0.201751708984375 +69076 0.375823974609375 +69077 0.485076904296875 +69078 0.56884765625 +69079 0.634765625 +69080 0.63763427734375 +69081 0.5660400390625 +69082 0.4720458984375 +69083 0.40692138671875 +69084 0.3778076171875 +69085 0.376953125 +69086 0.371978759765625 +69087 0.313140869140625 +69088 0.184417724609375 +69089 0.011199951171875 +69090 -0.171051025390625 +69091 -0.33740234375 +69092 -0.47198486328125 +69093 -0.560394287109375 +69094 -0.58056640625 +69095 -0.54754638671875 +69096 -0.508575439453125 +69097 -0.459503173828125 +69098 -0.394378662109375 +69099 -0.35260009765625 +69100 -0.31170654296875 +69101 -0.197418212890625 +69102 -0.007965087890625 +69103 0.207489013671875 +69104 0.409210205078125 +69105 0.57208251953125 +69106 0.66595458984375 +69107 0.65875244140625 +69108 0.56744384765625 +69109 0.431396484375 +69110 0.29443359375 +69111 0.182464599609375 +69112 0.06365966796875 +69113 -0.075958251953125 +69114 -0.189422607421875 +69115 -0.271942138671875 +69116 -0.342529296875 +69117 -0.364166259765625 +69118 -0.327239990234375 +69119 -0.2769775390625 +69120 -0.253692626953125 +69121 -0.24365234375 +69122 -0.1983642578125 +69123 -0.116241455078125 +69124 -0.036834716796875 +69125 0.034881591796875 +69126 0.09124755859375 +69127 0.10888671875 +69128 0.125518798828125 +69129 0.15771484375 +69130 0.17828369140625 +69131 0.17108154296875 +69132 0.129974365234375 +69133 0.082427978515625 +69134 0.027679443359375 +69135 -0.065643310546875 +69136 -0.15936279296875 +69137 -0.21307373046875 +69138 -0.234649658203125 +69139 -0.2001953125 +69140 -0.119171142578125 +69141 -0.024749755859375 +69142 0.085784912109375 +69143 0.178131103515625 +69144 0.215576171875 +69145 0.211456298828125 +69146 0.17523193359375 +69147 0.128753662109375 +69148 0.1019287109375 +69149 0.0743408203125 +69150 0.04327392578125 +69151 0.038177490234375 +69152 0.076263427734375 +69153 0.14105224609375 +69154 0.186431884765625 +69155 0.188812255859375 +69156 0.1390380859375 +69157 0.041778564453125 +69158 -0.079437255859375 +69159 -0.219390869140625 +69160 -0.367828369140625 +69161 -0.494873046875 +69162 -0.556243896484375 +69163 -0.508697509765625 +69164 -0.3756103515625 +69165 -0.218902587890625 +69166 -0.063751220703125 +69167 0.091552734375 +69168 0.23602294921875 +69169 0.342987060546875 +69170 0.39520263671875 +69171 0.389373779296875 +69172 0.324249267578125 +69173 0.224090576171875 +69174 0.124267578125 +69175 0.037078857421875 +69176 -0.010101318359375 +69177 -0.019439697265625 +69178 -0.022796630859375 +69179 -0.001556396484375 +69180 0.056304931640625 +69181 0.106719970703125 +69182 0.096893310546875 +69183 0.042694091796875 +69184 -0.018035888671875 +69185 -0.07586669921875 +69186 -0.11944580078125 +69187 -0.15972900390625 +69188 -0.202606201171875 +69189 -0.24859619140625 +69190 -0.30517578125 +69191 -0.36212158203125 +69192 -0.39141845703125 +69193 -0.35528564453125 +69194 -0.249969482421875 +69195 -0.092864990234375 +69196 0.08905029296875 +69197 0.2352294921875 +69198 0.318817138671875 +69199 0.358642578125 +69200 0.347747802734375 +69201 0.28564453125 +69202 0.223175048828125 +69203 0.196746826171875 +69204 0.179840087890625 +69205 0.155548095703125 +69206 0.151214599609375 +69207 0.156951904296875 +69208 0.13177490234375 +69209 0.100799560546875 +69210 0.087127685546875 +69211 0.05487060546875 +69212 -0.009002685546875 +69213 -0.10400390625 +69214 -0.229400634765625 +69215 -0.35552978515625 +69216 -0.441925048828125 +69217 -0.473846435546875 +69218 -0.464813232421875 +69219 -0.419097900390625 +69220 -0.334320068359375 +69221 -0.227935791015625 +69222 -0.12347412109375 +69223 -0.02764892578125 +69224 0.077667236328125 +69225 0.2132568359375 +69226 0.38885498046875 +69227 0.582794189453125 +69228 0.734039306640625 +69229 0.800140380859375 +69230 0.7783203125 +69231 0.6651611328125 +69232 0.45965576171875 +69233 0.199188232421875 +69234 -0.050689697265625 +69235 -0.23297119140625 +69236 -0.33013916015625 +69237 -0.368408203125 +69238 -0.378936767578125 +69239 -0.376983642578125 +69240 -0.37969970703125 +69241 -0.391510009765625 +69242 -0.385345458984375 +69243 -0.3419189453125 +69244 -0.28289794921875 +69245 -0.251617431640625 +69246 -0.266143798828125 +69247 -0.273345947265625 +69248 -0.216796875 +69249 -0.128265380859375 +69250 -0.068145751953125 +69251 -0.0430908203125 +69252 -0.024444580078125 +69253 0.020721435546875 +69254 0.124481201171875 +69255 0.25787353515625 +69256 0.379119873046875 +69257 0.47991943359375 +69258 0.5281982421875 +69259 0.511138916015625 +69260 0.456207275390625 +69261 0.407470703125 +69262 0.383758544921875 +69263 0.35687255859375 +69264 0.31182861328125 +69265 0.250885009765625 +69266 0.1654052734375 +69267 0.035247802734375 +69268 -0.142059326171875 +69269 -0.33563232421875 +69270 -0.5345458984375 +69271 -0.72186279296875 +69272 -0.836669921875 +69273 -0.8326416015625 +69274 -0.7296142578125 +69275 -0.582550048828125 +69276 -0.440093994140625 +69277 -0.324310302734375 +69278 -0.20147705078125 +69279 -0.044647216796875 +69280 0.103973388671875 +69281 0.202392578125 +69282 0.264495849609375 +69283 0.338897705078125 +69284 0.443817138671875 +69285 0.545074462890625 +69286 0.6173095703125 +69287 0.6524658203125 +69288 0.66339111328125 +69289 0.6561279296875 +69290 0.606781005859375 +69291 0.501190185546875 +69292 0.352783203125 +69293 0.176544189453125 +69294 -0.034820556640625 +69295 -0.258209228515625 +69296 -0.44244384765625 +69297 -0.5753173828125 +69298 -0.65203857421875 +69299 -0.641632080078125 +69300 -0.562164306640625 +69301 -0.458038330078125 +69302 -0.350555419921875 +69303 -0.260528564453125 +69304 -0.192108154296875 +69305 -0.141937255859375 +69306 -0.1021728515625 +69307 -0.062896728515625 +69308 -0.011932373046875 +69309 0.062835693359375 +69310 0.148712158203125 +69311 0.241729736328125 +69312 0.34912109375 +69313 0.457305908203125 +69314 0.54388427734375 +69315 0.5728759765625 +69316 0.506591796875 +69317 0.351226806640625 +69318 0.146514892578125 +69319 -0.05523681640625 +69320 -0.21624755859375 +69321 -0.334930419921875 +69322 -0.402984619140625 +69323 -0.4412841796875 +69324 -0.49578857421875 +69325 -0.5601806640625 +69326 -0.600738525390625 +69327 -0.584228515625 +69328 -0.47930908203125 +69329 -0.27935791015625 +69330 -0.0089111328125 +69331 0.268798828125 +69332 0.482818603515625 +69333 0.60369873046875 +69334 0.650421142578125 +69335 0.66400146484375 +69336 0.6414794921875 +69337 0.572540283203125 +69338 0.498138427734375 +69339 0.439453125 +69340 0.375518798828125 +69341 0.274505615234375 +69342 0.1087646484375 +69343 -0.099395751953125 +69344 -0.3182373046875 +69345 -0.5489501953125 +69346 -0.7738037109375 +69347 -0.86383056640625 +69348 -0.870391845703125 +69349 -0.86895751953125 +69350 -0.861053466796875 +69351 -0.765869140625 +69352 -0.5301513671875 +69353 -0.214691162109375 +69354 0.137359619140625 +69355 0.474822998046875 +69356 0.76239013671875 +69357 0.867462158203125 +69358 0.870361328125 +69359 0.86480712890625 +69360 0.831817626953125 +69361 0.677581787109375 +69362 0.495880126953125 +69363 0.30767822265625 +69364 0.116180419921875 +69365 -0.110748291015625 +69366 -0.381805419921875 +69367 -0.6572265625 +69368 -0.857421875 +69369 -0.870391845703125 +69370 -0.870391845703125 +69371 -0.86444091796875 +69372 -0.85723876953125 +69373 -0.790008544921875 +69374 -0.62847900390625 +69375 -0.3956298828125 +69376 -0.126708984375 +69377 0.150115966796875 +69378 0.424041748046875 +69379 0.670623779296875 +69380 0.854522705078125 +69381 0.866485595703125 +69382 0.86920166015625 +69383 0.8653564453125 +69384 0.857147216796875 +69385 0.766845703125 +69386 0.628509521484375 +69387 0.462127685546875 +69388 0.297210693359375 +69389 0.14862060546875 +69390 -0.00537109375 +69391 -0.15753173828125 +69392 -0.31304931640625 +69393 -0.48876953125 +69394 -0.6416015625 +69395 -0.751373291015625 +69396 -0.84619140625 +69397 -0.861297607421875 +69398 -0.863250732421875 +69399 -0.856597900390625 +69400 -0.7498779296875 +69401 -0.624542236328125 +69402 -0.47808837890625 +69403 -0.253387451171875 +69404 0.003692626953125 +69405 0.2257080078125 +69406 0.427154541015625 +69407 0.643218994140625 +69408 0.855926513671875 +69409 0.870361328125 +69410 0.870361328125 +69411 0.862762451171875 +69412 0.79669189453125 +69413 0.595794677734375 +69414 0.362152099609375 +69415 0.1270751953125 +69416 -0.086944580078125 +69417 -0.2784423828125 +69418 -0.484832763671875 +69419 -0.729583740234375 +69420 -0.86688232421875 +69421 -0.870391845703125 +69422 -0.86859130859375 +69423 -0.86279296875 +69424 -0.817962646484375 +69425 -0.6116943359375 +69426 -0.3128662109375 +69427 0.039398193359375 +69428 0.422821044921875 +69429 0.805145263671875 +69430 0.870361328125 +69431 0.870361328125 +69432 0.860015869140625 +69433 0.727935791015625 +69434 0.48114013671875 +69435 0.2059326171875 +69436 -0.06103515625 +69437 -0.29913330078125 +69438 -0.516204833984375 +69439 -0.7252197265625 +69440 -0.85980224609375 +69441 -0.870391845703125 +69442 -0.870391845703125 +69443 -0.858062744140625 +69444 -0.673004150390625 +69445 -0.42694091796875 +69446 -0.2100830078125 +69447 -0.0362548828125 +69448 0.10943603515625 +69449 0.23516845703125 +69450 0.373687744140625 +69451 0.517791748046875 +69452 0.602783203125 +69453 0.635711669921875 +69454 0.655181884765625 +69455 0.65948486328125 +69456 0.651275634765625 +69457 0.61846923828125 +69458 0.53753662109375 +69459 0.404144287109375 +69460 0.22186279296875 +69461 0.003997802734375 +69462 -0.22100830078125 +69463 -0.42449951171875 +69464 -0.579833984375 +69465 -0.641876220703125 +69466 -0.6177978515625 +69467 -0.575531005859375 +69468 -0.526336669921875 +69469 -0.42645263671875 +69470 -0.2581787109375 +69471 -0.068695068359375 +69472 0.09222412109375 +69473 0.232147216796875 +69474 0.3509521484375 +69475 0.410064697265625 +69476 0.372955322265625 +69477 0.2554931640625 +69478 0.10711669921875 +69479 -0.052886962890625 +69480 -0.186279296875 +69481 -0.23291015625 +69482 -0.209442138671875 +69483 -0.174163818359375 +69484 -0.126739501953125 +69485 -0.048126220703125 +69486 0.0426025390625 +69487 0.10748291015625 +69488 0.1409912109375 +69489 0.19708251953125 +69490 0.273651123046875 +69491 0.31768798828125 +69492 0.341094970703125 +69493 0.368011474609375 +69494 0.37249755859375 +69495 0.30072021484375 +69496 0.1517333984375 +69497 -0.01470947265625 +69498 -0.1883544921875 +69499 -0.372711181640625 +69500 -0.51397705078125 +69501 -0.57177734375 +69502 -0.53948974609375 +69503 -0.43511962890625 +69504 -0.2962646484375 +69505 -0.161102294921875 +69506 -0.0435791015625 +69507 0.060394287109375 +69508 0.13665771484375 +69509 0.170135498046875 +69510 0.16552734375 +69511 0.15728759765625 +69512 0.150787353515625 +69513 0.12200927734375 +69514 0.080108642578125 +69515 0.05126953125 +69516 0.062896728515625 +69517 0.09271240234375 +69518 0.092987060546875 +69519 0.07855224609375 +69520 0.06427001953125 +69521 0.0347900390625 +69522 -0.01171875 +69523 -0.056060791015625 +69524 -0.055511474609375 +69525 -0.010467529296875 +69526 0.02508544921875 +69527 0.025665283203125 +69528 0.017333984375 +69529 0.00189208984375 +69530 -0.03173828125 +69531 -0.071502685546875 +69532 -0.13543701171875 +69533 -0.219970703125 +69534 -0.300506591796875 +69535 -0.376312255859375 +69536 -0.416107177734375 +69537 -0.371124267578125 +69538 -0.242279052734375 +69539 -0.069732666015625 +69540 0.125640869140625 +69541 0.31268310546875 +69542 0.45501708984375 +69543 0.554779052734375 +69544 0.61065673828125 +69545 0.610931396484375 +69546 0.531463623046875 +69547 0.3883056640625 +69548 0.23468017578125 +69549 0.095245361328125 +69550 -0.00396728515625 +69551 -0.04852294921875 +69552 -0.055145263671875 +69553 -0.0758056640625 +69554 -0.138702392578125 +69555 -0.209197998046875 +69556 -0.289031982421875 +69557 -0.37884521484375 +69558 -0.456329345703125 +69559 -0.51641845703125 +69560 -0.519287109375 +69561 -0.458251953125 +69562 -0.384796142578125 +69563 -0.323699951171875 +69564 -0.269287109375 +69565 -0.1951904296875 +69566 -0.100006103515625 +69567 -0.01055908203125 +69568 0.1033935546875 +69569 0.24908447265625 +69570 0.373199462890625 +69571 0.45806884765625 +69572 0.511474609375 +69573 0.565399169921875 +69574 0.61138916015625 +69575 0.5897216796875 +69576 0.4906005859375 +69577 0.33148193359375 +69578 0.147796630859375 +69579 -0.01873779296875 +69580 -0.140289306640625 +69581 -0.191986083984375 +69582 -0.184295654296875 +69583 -0.161834716796875 +69584 -0.166595458984375 +69585 -0.19390869140625 +69586 -0.22442626953125 +69587 -0.279754638671875 +69588 -0.3389892578125 +69589 -0.3543701171875 +69590 -0.348175048828125 +69591 -0.32598876953125 +69592 -0.2581787109375 +69593 -0.139801025390625 +69594 0.014617919921875 +69595 0.144378662109375 +69596 0.221038818359375 +69597 0.27069091796875 +69598 0.294036865234375 +69599 0.311767578125 +69600 0.339141845703125 +69601 0.360260009765625 +69602 0.360504150390625 +69603 0.308380126953125 +69604 0.18170166015625 +69605 0.0047607421875 +69606 -0.17559814453125 +69607 -0.3143310546875 +69608 -0.36785888671875 +69609 -0.36248779296875 +69610 -0.343536376953125 +69611 -0.3018798828125 +69612 -0.231414794921875 +69613 -0.117645263671875 +69614 0.007049560546875 +69615 0.087982177734375 +69616 0.13946533203125 +69617 0.17425537109375 +69618 0.188201904296875 +69619 0.171234130859375 +69620 0.118438720703125 +69621 0.05706787109375 +69622 -0.010711669921875 +69623 -0.0914306640625 +69624 -0.162322998046875 +69625 -0.194549560546875 +69626 -0.1492919921875 +69627 -0.02166748046875 +69628 0.124053955078125 +69629 0.211151123046875 +69630 0.240447998046875 +69631 0.242218017578125 +69632 0.2257080078125 +69633 0.194366455078125 +69634 0.115509033203125 +69635 0.0128173828125 +69636 -0.053802490234375 +69637 -0.110626220703125 +69638 -0.199493408203125 +69639 -0.29437255859375 +69640 -0.33221435546875 +69641 -0.27972412109375 +69642 -0.185333251953125 +69643 -0.128204345703125 +69644 -0.115692138671875 +69645 -0.116455078125 +69646 -0.105926513671875 +69647 -0.053955078125 +69648 0.048797607421875 +69649 0.157318115234375 +69650 0.212005615234375 +69651 0.218475341796875 +69652 0.23724365234375 +69653 0.30535888671875 +69654 0.38128662109375 +69655 0.404449462890625 +69656 0.3944091796875 +69657 0.3885498046875 +69658 0.362640380859375 +69659 0.27362060546875 +69660 0.11712646484375 +69661 -0.054901123046875 +69662 -0.19085693359375 +69663 -0.28570556640625 +69664 -0.339263916015625 +69665 -0.3775634765625 +69666 -0.445709228515625 +69667 -0.535064697265625 +69668 -0.629058837890625 +69669 -0.697601318359375 +69670 -0.70391845703125 +69671 -0.6424560546875 +69672 -0.491241455078125 +69673 -0.265716552734375 +69674 -0.023712158203125 +69675 0.201751708984375 +69676 0.375823974609375 +69677 0.485076904296875 +69678 0.56884765625 +69679 0.634765625 +69680 0.63763427734375 +69681 0.5660400390625 +69682 0.4720458984375 +69683 0.40692138671875 +69684 0.3778076171875 +69685 0.376953125 +69686 0.371978759765625 +69687 0.313140869140625 +69688 0.184417724609375 +69689 0.011199951171875 +69690 -0.171051025390625 +69691 -0.33740234375 +69692 -0.47198486328125 +69693 -0.560394287109375 +69694 -0.58056640625 +69695 -0.54754638671875 +69696 -0.508575439453125 +69697 -0.459503173828125 +69698 -0.394378662109375 +69699 -0.35260009765625 +69700 -0.31170654296875 +69701 -0.197418212890625 +69702 -0.007965087890625 +69703 0.207489013671875 +69704 0.409210205078125 +69705 0.57208251953125 +69706 0.66595458984375 +69707 0.65875244140625 +69708 0.56744384765625 +69709 0.431396484375 +69710 0.29443359375 +69711 0.182464599609375 +69712 0.06365966796875 +69713 -0.075958251953125 +69714 -0.189422607421875 +69715 -0.271942138671875 +69716 -0.342529296875 +69717 -0.364166259765625 +69718 -0.327239990234375 +69719 -0.2769775390625 +69720 -0.253692626953125 +69721 -0.24365234375 +69722 -0.1983642578125 +69723 -0.116241455078125 +69724 -0.036834716796875 +69725 0.034881591796875 +69726 0.09124755859375 +69727 0.10888671875 +69728 0.125518798828125 +69729 0.15771484375 +69730 0.17828369140625 +69731 0.17108154296875 +69732 0.129974365234375 +69733 0.082427978515625 +69734 0.027679443359375 +69735 -0.065643310546875 +69736 -0.15936279296875 +69737 -0.21307373046875 +69738 -0.234649658203125 +69739 -0.2001953125 +69740 -0.119171142578125 +69741 -0.024749755859375 +69742 0.085784912109375 +69743 0.178131103515625 +69744 0.215576171875 +69745 0.211456298828125 +69746 0.17523193359375 +69747 0.128753662109375 +69748 0.1019287109375 +69749 0.0743408203125 +69750 0.04327392578125 +69751 0.038177490234375 +69752 0.076263427734375 +69753 0.14105224609375 +69754 0.186431884765625 +69755 0.188812255859375 +69756 0.1390380859375 +69757 0.041778564453125 +69758 -0.079437255859375 +69759 -0.219390869140625 +69760 -0.367828369140625 +69761 -0.494873046875 +69762 -0.556243896484375 +69763 -0.508697509765625 +69764 -0.3756103515625 +69765 -0.218902587890625 +69766 -0.063751220703125 +69767 0.091552734375 +69768 0.23602294921875 +69769 0.342987060546875 +69770 0.39520263671875 +69771 0.389373779296875 +69772 0.324249267578125 +69773 0.224090576171875 +69774 0.124267578125 +69775 0.037078857421875 +69776 -0.010101318359375 +69777 -0.019439697265625 +69778 -0.022796630859375 +69779 -0.001556396484375 +69780 0.056304931640625 +69781 0.106719970703125 +69782 0.096893310546875 +69783 0.042694091796875 +69784 -0.018035888671875 +69785 -0.07586669921875 +69786 -0.11944580078125 +69787 -0.15972900390625 +69788 -0.202606201171875 +69789 -0.24859619140625 +69790 -0.30517578125 +69791 -0.36212158203125 +69792 -0.39141845703125 +69793 -0.35528564453125 +69794 -0.249969482421875 +69795 -0.092864990234375 +69796 0.08905029296875 +69797 0.2352294921875 +69798 0.318817138671875 +69799 0.358642578125 +69800 0.347747802734375 +69801 0.28564453125 +69802 0.223175048828125 +69803 0.196746826171875 +69804 0.179840087890625 +69805 0.155548095703125 +69806 0.151214599609375 +69807 0.156951904296875 +69808 0.13177490234375 +69809 0.100799560546875 +69810 0.087127685546875 +69811 0.05487060546875 +69812 -0.009002685546875 +69813 -0.10400390625 +69814 -0.229400634765625 +69815 -0.35552978515625 +69816 -0.441925048828125 +69817 -0.473846435546875 +69818 -0.464813232421875 +69819 -0.419097900390625 +69820 -0.334320068359375 +69821 -0.227935791015625 +69822 -0.12347412109375 +69823 -0.02764892578125 +69824 0.077667236328125 +69825 0.2132568359375 +69826 0.38885498046875 +69827 0.582794189453125 +69828 0.734039306640625 +69829 0.800140380859375 +69830 0.7783203125 +69831 0.6651611328125 +69832 0.45965576171875 +69833 0.199188232421875 +69834 -0.050689697265625 +69835 -0.23297119140625 +69836 -0.33013916015625 +69837 -0.368408203125 +69838 -0.378936767578125 +69839 -0.376983642578125 +69840 -0.37969970703125 +69841 -0.391510009765625 +69842 -0.385345458984375 +69843 -0.3419189453125 +69844 -0.28289794921875 +69845 -0.251617431640625 +69846 -0.266143798828125 +69847 -0.273345947265625 +69848 -0.216796875 +69849 -0.128265380859375 +69850 -0.068145751953125 +69851 -0.0430908203125 +69852 -0.024444580078125 +69853 0.020721435546875 +69854 0.124481201171875 +69855 0.25787353515625 +69856 0.379119873046875 +69857 0.47991943359375 +69858 0.5281982421875 +69859 0.511138916015625 +69860 0.456207275390625 +69861 0.407470703125 +69862 0.383758544921875 +69863 0.35687255859375 +69864 0.31182861328125 +69865 0.250885009765625 +69866 0.1654052734375 +69867 0.035247802734375 +69868 -0.142059326171875 +69869 -0.33563232421875 +69870 -0.5345458984375 +69871 -0.72186279296875 +69872 -0.836669921875 +69873 -0.8326416015625 +69874 -0.7296142578125 +69875 -0.582550048828125 +69876 -0.440093994140625 +69877 -0.324310302734375 +69878 -0.20147705078125 +69879 -0.044647216796875 +69880 0.103973388671875 +69881 0.202392578125 +69882 0.264495849609375 +69883 0.338897705078125 +69884 0.443817138671875 +69885 0.545074462890625 +69886 0.6173095703125 +69887 0.6524658203125 +69888 0.66339111328125 +69889 0.6561279296875 +69890 0.606781005859375 +69891 0.501190185546875 +69892 0.352783203125 +69893 0.176544189453125 +69894 -0.034820556640625 +69895 -0.258209228515625 +69896 -0.44244384765625 +69897 -0.5753173828125 +69898 -0.65203857421875 +69899 -0.641632080078125 +69900 -0.562164306640625 +69901 -0.458038330078125 +69902 -0.350555419921875 +69903 -0.260528564453125 +69904 -0.192108154296875 +69905 -0.141937255859375 +69906 -0.1021728515625 +69907 -0.062896728515625 +69908 -0.011932373046875 +69909 0.062835693359375 +69910 0.148712158203125 +69911 0.241729736328125 +69912 0.34912109375 +69913 0.457305908203125 +69914 0.54388427734375 +69915 0.5728759765625 +69916 0.506591796875 +69917 0.351226806640625 +69918 0.146514892578125 +69919 -0.05523681640625 +69920 -0.21624755859375 +69921 -0.334930419921875 +69922 -0.402984619140625 +69923 -0.4412841796875 +69924 -0.49578857421875 +69925 -0.5601806640625 +69926 -0.600738525390625 +69927 -0.584228515625 +69928 -0.47930908203125 +69929 -0.27935791015625 +69930 -0.0089111328125 +69931 0.268798828125 +69932 0.482818603515625 +69933 0.60369873046875 +69934 0.650421142578125 +69935 0.66400146484375 +69936 0.6414794921875 +69937 0.572540283203125 +69938 0.498138427734375 +69939 0.439453125 +69940 0.375518798828125 +69941 0.274505615234375 +69942 0.1087646484375 +69943 -0.099395751953125 +69944 -0.3182373046875 +69945 -0.5489501953125 +69946 -0.7738037109375 +69947 -0.86383056640625 +69948 -0.870391845703125 +69949 -0.86895751953125 +69950 -0.861053466796875 +69951 -0.765869140625 +69952 -0.5301513671875 +69953 -0.214691162109375 +69954 0.137359619140625 +69955 0.474822998046875 +69956 0.76239013671875 +69957 0.867462158203125 +69958 0.870361328125 +69959 0.86480712890625 +69960 0.831817626953125 +69961 0.677581787109375 +69962 0.495880126953125 +69963 0.30767822265625 +69964 0.116180419921875 +69965 -0.110748291015625 +69966 -0.381805419921875 +69967 -0.6572265625 +69968 -0.857421875 +69969 -0.870391845703125 +69970 -0.870391845703125 +69971 -0.86444091796875 +69972 -0.85723876953125 +69973 -0.790008544921875 +69974 -0.62847900390625 +69975 -0.3956298828125 +69976 -0.126708984375 +69977 0.150115966796875 +69978 0.424041748046875 +69979 0.670623779296875 +69980 0.854522705078125 +69981 0.866485595703125 +69982 0.86920166015625 +69983 0.8653564453125 +69984 0.857147216796875 +69985 0.766845703125 +69986 0.628509521484375 +69987 0.462127685546875 +69988 0.297210693359375 +69989 0.14862060546875 +69990 -0.00537109375 +69991 -0.15753173828125 +69992 -0.31304931640625 +69993 -0.48876953125 +69994 -0.6416015625 +69995 -0.751373291015625 +69996 -0.84619140625 +69997 -0.861297607421875 +69998 -0.863250732421875 +69999 -0.856597900390625 +70000 -0.7498779296875 +70001 -0.624542236328125 +70002 -0.47808837890625 +70003 -0.253387451171875 +70004 0.003692626953125 +70005 0.2257080078125 +70006 0.427154541015625 +70007 0.643218994140625 +70008 0.855926513671875 +70009 0.870361328125 +70010 0.870361328125 +70011 0.862762451171875 +70012 0.79669189453125 +70013 0.595794677734375 +70014 0.362152099609375 +70015 0.1270751953125 +70016 -0.086944580078125 +70017 -0.2784423828125 +70018 -0.484832763671875 +70019 -0.729583740234375 +70020 -0.86688232421875 +70021 -0.870391845703125 +70022 -0.86859130859375 +70023 -0.86279296875 +70024 -0.817962646484375 +70025 -0.6116943359375 +70026 -0.3128662109375 +70027 0.039398193359375 +70028 0.422821044921875 +70029 0.805145263671875 +70030 0.870361328125 +70031 0.870361328125 +70032 0.860015869140625 +70033 0.727935791015625 +70034 0.48114013671875 +70035 0.2059326171875 +70036 -0.06103515625 +70037 -0.29913330078125 +70038 -0.516204833984375 +70039 -0.7252197265625 +70040 -0.85980224609375 +70041 -0.870391845703125 +70042 -0.870391845703125 +70043 -0.858062744140625 +70044 -0.673004150390625 +70045 -0.42694091796875 +70046 -0.2100830078125 +70047 -0.0362548828125 +70048 0.10943603515625 +70049 0.23516845703125 +70050 0.373687744140625 +70051 0.517791748046875 +70052 0.602783203125 +70053 0.635711669921875 +70054 0.655181884765625 +70055 0.65948486328125 +70056 0.651275634765625 +70057 0.61846923828125 +70058 0.53753662109375 +70059 0.404144287109375 +70060 0.22186279296875 +70061 0.003997802734375 +70062 -0.22100830078125 +70063 -0.42449951171875 +70064 -0.579833984375 +70065 -0.641876220703125 +70066 -0.6177978515625 +70067 -0.575531005859375 +70068 -0.526336669921875 +70069 -0.42645263671875 +70070 -0.2581787109375 +70071 -0.068695068359375 +70072 0.09222412109375 +70073 0.232147216796875 +70074 0.3509521484375 +70075 0.410064697265625 +70076 0.372955322265625 +70077 0.2554931640625 +70078 0.10711669921875 +70079 -0.052886962890625 +70080 -0.186279296875 +70081 -0.23291015625 +70082 -0.209442138671875 +70083 -0.174163818359375 +70084 -0.126739501953125 +70085 -0.048126220703125 +70086 0.0426025390625 +70087 0.10748291015625 +70088 0.1409912109375 +70089 0.19708251953125 +70090 0.273651123046875 +70091 0.31768798828125 +70092 0.341094970703125 +70093 0.368011474609375 +70094 0.37249755859375 +70095 0.30072021484375 +70096 0.1517333984375 +70097 -0.01470947265625 +70098 -0.1883544921875 +70099 -0.372711181640625 +70100 -0.51397705078125 +70101 -0.57177734375 +70102 -0.53948974609375 +70103 -0.43511962890625 +70104 -0.2962646484375 +70105 -0.161102294921875 +70106 -0.0435791015625 +70107 0.060394287109375 +70108 0.13665771484375 +70109 0.170135498046875 +70110 0.16552734375 +70111 0.15728759765625 +70112 0.150787353515625 +70113 0.12200927734375 +70114 0.080108642578125 +70115 0.05126953125 +70116 0.062896728515625 +70117 0.09271240234375 +70118 0.092987060546875 +70119 0.07855224609375 +70120 0.06427001953125 +70121 0.0347900390625 +70122 -0.01171875 +70123 -0.056060791015625 +70124 -0.055511474609375 +70125 -0.010467529296875 +70126 0.02508544921875 +70127 0.025665283203125 +70128 0.017333984375 +70129 0.00189208984375 +70130 -0.03173828125 +70131 -0.071502685546875 +70132 -0.13543701171875 +70133 -0.219970703125 +70134 -0.300506591796875 +70135 -0.376312255859375 +70136 -0.416107177734375 +70137 -0.371124267578125 +70138 -0.242279052734375 +70139 -0.069732666015625 +70140 0.125640869140625 +70141 0.31268310546875 +70142 0.45501708984375 +70143 0.554779052734375 +70144 0.61065673828125 +70145 0.610931396484375 +70146 0.531463623046875 +70147 0.3883056640625 +70148 0.23468017578125 +70149 0.095245361328125 +70150 -0.00396728515625 +70151 -0.04852294921875 +70152 -0.055145263671875 +70153 -0.0758056640625 +70154 -0.138702392578125 +70155 -0.209197998046875 +70156 -0.289031982421875 +70157 -0.37884521484375 +70158 -0.456329345703125 +70159 -0.51641845703125 +70160 -0.519287109375 +70161 -0.458251953125 +70162 -0.384796142578125 +70163 -0.323699951171875 +70164 -0.269287109375 +70165 -0.1951904296875 +70166 -0.100006103515625 +70167 -0.01055908203125 +70168 0.1033935546875 +70169 0.24908447265625 +70170 0.373199462890625 +70171 0.45806884765625 +70172 0.511474609375 +70173 0.565399169921875 +70174 0.61138916015625 +70175 0.5897216796875 +70176 0.4906005859375 +70177 0.33148193359375 +70178 0.147796630859375 +70179 -0.01873779296875 +70180 -0.140289306640625 +70181 -0.191986083984375 +70182 -0.184295654296875 +70183 -0.161834716796875 +70184 -0.166595458984375 +70185 -0.19390869140625 +70186 -0.22442626953125 +70187 -0.279754638671875 +70188 -0.3389892578125 +70189 -0.3543701171875 +70190 -0.348175048828125 +70191 -0.32598876953125 +70192 -0.2581787109375 +70193 -0.139801025390625 +70194 0.014617919921875 +70195 0.144378662109375 +70196 0.221038818359375 +70197 0.27069091796875 +70198 0.294036865234375 +70199 0.311767578125 +70200 0.339141845703125 +70201 0.360260009765625 +70202 0.360504150390625 +70203 0.308380126953125 +70204 0.18170166015625 +70205 0.0047607421875 +70206 -0.17559814453125 +70207 -0.3143310546875 +70208 -0.36785888671875 +70209 -0.36248779296875 +70210 -0.343536376953125 +70211 -0.3018798828125 +70212 -0.231414794921875 +70213 -0.117645263671875 +70214 0.007049560546875 +70215 0.087982177734375 +70216 0.13946533203125 +70217 0.17425537109375 +70218 0.188201904296875 +70219 0.171234130859375 +70220 0.118438720703125 +70221 0.05706787109375 +70222 -0.010711669921875 +70223 -0.0914306640625 +70224 -0.162322998046875 +70225 -0.194549560546875 +70226 -0.1492919921875 +70227 -0.02166748046875 +70228 0.124053955078125 +70229 0.211151123046875 +70230 0.240447998046875 +70231 0.242218017578125 +70232 0.2257080078125 +70233 0.194366455078125 +70234 0.115509033203125 +70235 0.0128173828125 +70236 -0.053802490234375 +70237 -0.110626220703125 +70238 -0.199493408203125 +70239 -0.29437255859375 +70240 -0.33221435546875 +70241 -0.27972412109375 +70242 -0.185333251953125 +70243 -0.128204345703125 +70244 -0.115692138671875 +70245 -0.116455078125 +70246 -0.105926513671875 +70247 -0.053955078125 +70248 0.048797607421875 +70249 0.157318115234375 +70250 0.212005615234375 +70251 0.218475341796875 +70252 0.23724365234375 +70253 0.30535888671875 +70254 0.38128662109375 +70255 0.404449462890625 +70256 0.3944091796875 +70257 0.3885498046875 +70258 0.362640380859375 +70259 0.27362060546875 +70260 0.11712646484375 +70261 -0.054901123046875 +70262 -0.19085693359375 +70263 -0.28570556640625 +70264 -0.339263916015625 +70265 -0.3775634765625 +70266 -0.445709228515625 +70267 -0.535064697265625 +70268 -0.629058837890625 +70269 -0.697601318359375 +70270 -0.70391845703125 +70271 -0.6424560546875 +70272 -0.491241455078125 +70273 -0.265716552734375 +70274 -0.023712158203125 +70275 0.201751708984375 +70276 0.375823974609375 +70277 0.485076904296875 +70278 0.56884765625 +70279 0.634765625 +70280 0.63763427734375 +70281 0.5660400390625 +70282 0.4720458984375 +70283 0.40692138671875 +70284 0.3778076171875 +70285 0.376953125 +70286 0.371978759765625 +70287 0.313140869140625 +70288 0.184417724609375 +70289 0.011199951171875 +70290 -0.171051025390625 +70291 -0.33740234375 +70292 -0.47198486328125 +70293 -0.560394287109375 +70294 -0.58056640625 +70295 -0.54754638671875 +70296 -0.508575439453125 +70297 -0.459503173828125 +70298 -0.394378662109375 +70299 -0.35260009765625 +70300 -0.31170654296875 +70301 -0.197418212890625 +70302 -0.007965087890625 +70303 0.207489013671875 +70304 0.409210205078125 +70305 0.57208251953125 +70306 0.66595458984375 +70307 0.65875244140625 +70308 0.56744384765625 +70309 0.431396484375 +70310 0.29443359375 +70311 0.182464599609375 +70312 0.06365966796875 +70313 -0.075958251953125 +70314 -0.189422607421875 +70315 -0.271942138671875 +70316 -0.342529296875 +70317 -0.364166259765625 +70318 -0.327239990234375 +70319 -0.2769775390625 +70320 -0.253692626953125 +70321 -0.24365234375 +70322 -0.1983642578125 +70323 -0.116241455078125 +70324 -0.036834716796875 +70325 0.034881591796875 +70326 0.09124755859375 +70327 0.10888671875 +70328 0.125518798828125 +70329 0.15771484375 +70330 0.17828369140625 +70331 0.17108154296875 +70332 0.129974365234375 +70333 0.082427978515625 +70334 0.027679443359375 +70335 -0.065643310546875 +70336 -0.15936279296875 +70337 -0.21307373046875 +70338 -0.234649658203125 +70339 -0.2001953125 +70340 -0.119171142578125 +70341 -0.024749755859375 +70342 0.085784912109375 +70343 0.178131103515625 +70344 0.215576171875 +70345 0.211456298828125 +70346 0.17523193359375 +70347 0.128753662109375 +70348 0.1019287109375 +70349 0.0743408203125 +70350 0.04327392578125 +70351 0.038177490234375 +70352 0.076263427734375 +70353 0.14105224609375 +70354 0.186431884765625 +70355 0.188812255859375 +70356 0.1390380859375 +70357 0.041778564453125 +70358 -0.079437255859375 +70359 -0.219390869140625 +70360 -0.367828369140625 +70361 -0.494873046875 +70362 -0.556243896484375 +70363 -0.508697509765625 +70364 -0.3756103515625 +70365 -0.218902587890625 +70366 -0.063751220703125 +70367 0.091552734375 +70368 0.23602294921875 +70369 0.342987060546875 +70370 0.39520263671875 +70371 0.389373779296875 +70372 0.324249267578125 +70373 0.224090576171875 +70374 0.124267578125 +70375 0.037078857421875 +70376 -0.010101318359375 +70377 -0.019439697265625 +70378 -0.022796630859375 +70379 -0.001556396484375 +70380 0.056304931640625 +70381 0.106719970703125 +70382 0.096893310546875 +70383 0.042694091796875 +70384 -0.018035888671875 +70385 -0.07586669921875 +70386 -0.11944580078125 +70387 -0.15972900390625 +70388 -0.202606201171875 +70389 -0.24859619140625 +70390 -0.30517578125 +70391 -0.36212158203125 +70392 -0.39141845703125 +70393 -0.35528564453125 +70394 -0.249969482421875 +70395 -0.092864990234375 +70396 0.08905029296875 +70397 0.2352294921875 +70398 0.318817138671875 +70399 0.358642578125 +70400 0.347747802734375 +70401 0.28564453125 +70402 0.223175048828125 +70403 0.196746826171875 +70404 0.179840087890625 +70405 0.155548095703125 +70406 0.151214599609375 +70407 0.156951904296875 +70408 0.13177490234375 +70409 0.100799560546875 +70410 0.087127685546875 +70411 0.05487060546875 +70412 -0.009002685546875 +70413 -0.10400390625 +70414 -0.229400634765625 +70415 -0.35552978515625 +70416 -0.441925048828125 +70417 -0.473846435546875 +70418 -0.464813232421875 +70419 -0.419097900390625 +70420 -0.334320068359375 +70421 -0.227935791015625 +70422 -0.12347412109375 +70423 -0.02764892578125 +70424 0.077667236328125 +70425 0.2132568359375 +70426 0.38885498046875 +70427 0.582794189453125 +70428 0.734039306640625 +70429 0.800140380859375 +70430 0.7783203125 +70431 0.6651611328125 +70432 0.45965576171875 +70433 0.199188232421875 +70434 -0.050689697265625 +70435 -0.23297119140625 +70436 -0.33013916015625 +70437 -0.368408203125 +70438 -0.378936767578125 +70439 -0.376983642578125 +70440 -0.37969970703125 +70441 -0.391510009765625 +70442 -0.385345458984375 +70443 -0.3419189453125 +70444 -0.28289794921875 +70445 -0.251617431640625 +70446 -0.266143798828125 +70447 -0.273345947265625 +70448 -0.216796875 +70449 -0.128265380859375 +70450 -0.068145751953125 +70451 -0.0430908203125 +70452 -0.024444580078125 +70453 0.020721435546875 +70454 0.124481201171875 +70455 0.25787353515625 +70456 0.379119873046875 +70457 0.47991943359375 +70458 0.5281982421875 +70459 0.511138916015625 +70460 0.456207275390625 +70461 0.407470703125 +70462 0.383758544921875 +70463 0.35687255859375 +70464 0.31182861328125 +70465 0.250885009765625 +70466 0.1654052734375 +70467 0.035247802734375 +70468 -0.142059326171875 +70469 -0.33563232421875 +70470 -0.5345458984375 +70471 -0.72186279296875 +70472 -0.836669921875 +70473 -0.8326416015625 +70474 -0.7296142578125 +70475 -0.582550048828125 +70476 -0.440093994140625 +70477 -0.324310302734375 +70478 -0.20147705078125 +70479 -0.044647216796875 +70480 0.103973388671875 +70481 0.202392578125 +70482 0.264495849609375 +70483 0.338897705078125 +70484 0.443817138671875 +70485 0.545074462890625 +70486 0.6173095703125 +70487 0.6524658203125 +70488 0.66339111328125 +70489 0.6561279296875 +70490 0.606781005859375 +70491 0.501190185546875 +70492 0.352783203125 +70493 0.176544189453125 +70494 -0.034820556640625 +70495 -0.258209228515625 +70496 -0.44244384765625 +70497 -0.5753173828125 +70498 -0.65203857421875 +70499 -0.641632080078125 +70500 -0.562164306640625 +70501 -0.458038330078125 +70502 -0.350555419921875 +70503 -0.260528564453125 +70504 -0.192108154296875 +70505 -0.141937255859375 +70506 -0.1021728515625 +70507 -0.062896728515625 +70508 -0.011932373046875 +70509 0.062835693359375 +70510 0.148712158203125 +70511 0.241729736328125 +70512 0.34912109375 +70513 0.457305908203125 +70514 0.54388427734375 +70515 0.5728759765625 +70516 0.506591796875 +70517 0.351226806640625 +70518 0.146514892578125 +70519 -0.05523681640625 +70520 -0.21624755859375 +70521 -0.334930419921875 +70522 -0.402984619140625 +70523 -0.4412841796875 +70524 -0.49578857421875 +70525 -0.5601806640625 +70526 -0.600738525390625 +70527 -0.584228515625 +70528 -0.47930908203125 +70529 -0.27935791015625 +70530 -0.0089111328125 +70531 0.268798828125 +70532 0.482818603515625 +70533 0.60369873046875 +70534 0.650421142578125 +70535 0.66400146484375 +70536 0.6414794921875 +70537 0.572540283203125 +70538 0.498138427734375 +70539 0.439453125 +70540 0.375518798828125 +70541 0.274505615234375 +70542 0.1087646484375 +70543 -0.099395751953125 +70544 -0.3182373046875 +70545 -0.5489501953125 +70546 -0.7738037109375 +70547 -0.86383056640625 +70548 -0.870391845703125 +70549 -0.86895751953125 +70550 -0.861053466796875 +70551 -0.765869140625 +70552 -0.5301513671875 +70553 -0.214691162109375 +70554 0.137359619140625 +70555 0.474822998046875 +70556 0.76239013671875 +70557 0.867462158203125 +70558 0.870361328125 +70559 0.86480712890625 +70560 0.831817626953125 +70561 0.677581787109375 +70562 0.495880126953125 +70563 0.30767822265625 +70564 0.116180419921875 +70565 -0.110748291015625 +70566 -0.381805419921875 +70567 -0.6572265625 +70568 -0.857421875 +70569 -0.870391845703125 +70570 -0.870391845703125 +70571 -0.86444091796875 +70572 -0.85723876953125 +70573 -0.790008544921875 +70574 -0.62847900390625 +70575 -0.3956298828125 +70576 -0.126708984375 +70577 0.150115966796875 +70578 0.424041748046875 +70579 0.670623779296875 +70580 0.854522705078125 +70581 0.866485595703125 +70582 0.86920166015625 +70583 0.8653564453125 +70584 0.857147216796875 +70585 0.766845703125 +70586 0.628509521484375 +70587 0.462127685546875 +70588 0.297210693359375 +70589 0.14862060546875 +70590 -0.00537109375 +70591 -0.15753173828125 +70592 -0.31304931640625 +70593 -0.48876953125 +70594 -0.6416015625 +70595 -0.751373291015625 +70596 -0.84619140625 +70597 -0.861297607421875 +70598 -0.863250732421875 +70599 -0.856597900390625 +70600 -0.7498779296875 +70601 -0.624542236328125 +70602 -0.47808837890625 +70603 -0.253387451171875 +70604 0.003692626953125 +70605 0.2257080078125 +70606 0.427154541015625 +70607 0.643218994140625 +70608 0.855926513671875 +70609 0.870361328125 +70610 0.870361328125 +70611 0.862762451171875 +70612 0.79669189453125 +70613 0.595794677734375 +70614 0.362152099609375 +70615 0.1270751953125 +70616 -0.086944580078125 +70617 -0.2784423828125 +70618 -0.484832763671875 +70619 -0.729583740234375 +70620 -0.86688232421875 +70621 -0.870391845703125 +70622 -0.86859130859375 +70623 -0.86279296875 +70624 -0.817962646484375 +70625 -0.6116943359375 +70626 -0.3128662109375 +70627 0.039398193359375 +70628 0.422821044921875 +70629 0.805145263671875 +70630 0.870361328125 +70631 0.870361328125 +70632 0.860015869140625 +70633 0.727935791015625 +70634 0.48114013671875 +70635 0.2059326171875 +70636 -0.06103515625 +70637 -0.29913330078125 +70638 -0.516204833984375 +70639 -0.7252197265625 +70640 -0.85980224609375 +70641 -0.870391845703125 +70642 -0.870391845703125 +70643 -0.858062744140625 +70644 -0.673004150390625 +70645 -0.42694091796875 +70646 -0.2100830078125 +70647 -0.0362548828125 +70648 0.10943603515625 +70649 0.23516845703125 +70650 0.373687744140625 +70651 0.517791748046875 +70652 0.602783203125 +70653 0.635711669921875 +70654 0.655181884765625 +70655 0.65948486328125 +70656 0.651275634765625 +70657 0.61846923828125 +70658 0.53753662109375 +70659 0.404144287109375 +70660 0.22186279296875 +70661 0.003997802734375 +70662 -0.22100830078125 +70663 -0.42449951171875 +70664 -0.579833984375 +70665 -0.641876220703125 +70666 -0.6177978515625 +70667 -0.575531005859375 +70668 -0.526336669921875 +70669 -0.42645263671875 +70670 -0.2581787109375 +70671 -0.068695068359375 +70672 0.09222412109375 +70673 0.232147216796875 +70674 0.3509521484375 +70675 0.410064697265625 +70676 0.372955322265625 +70677 0.2554931640625 +70678 0.10711669921875 +70679 -0.052886962890625 +70680 -0.186279296875 +70681 -0.23291015625 +70682 -0.209442138671875 +70683 -0.174163818359375 +70684 -0.126739501953125 +70685 -0.048126220703125 +70686 0.0426025390625 +70687 0.10748291015625 +70688 0.1409912109375 +70689 0.19708251953125 +70690 0.273651123046875 +70691 0.31768798828125 +70692 0.341094970703125 +70693 0.368011474609375 +70694 0.37249755859375 +70695 0.30072021484375 +70696 0.1517333984375 +70697 -0.01470947265625 +70698 -0.1883544921875 +70699 -0.372711181640625 +70700 -0.51397705078125 +70701 -0.57177734375 +70702 -0.53948974609375 +70703 -0.43511962890625 +70704 -0.2962646484375 +70705 -0.161102294921875 +70706 -0.0435791015625 +70707 0.060394287109375 +70708 0.13665771484375 +70709 0.170135498046875 +70710 0.16552734375 +70711 0.15728759765625 +70712 0.150787353515625 +70713 0.12200927734375 +70714 0.080108642578125 +70715 0.05126953125 +70716 0.062896728515625 +70717 0.09271240234375 +70718 0.092987060546875 +70719 0.07855224609375 +70720 0.06427001953125 +70721 0.0347900390625 +70722 -0.01171875 +70723 -0.056060791015625 +70724 -0.055511474609375 +70725 -0.010467529296875 +70726 0.02508544921875 +70727 0.025665283203125 +70728 0.017333984375 +70729 0.00189208984375 +70730 -0.03173828125 +70731 -0.071502685546875 +70732 -0.13543701171875 +70733 -0.219970703125 +70734 -0.300506591796875 +70735 -0.376312255859375 +70736 -0.416107177734375 +70737 -0.371124267578125 +70738 -0.242279052734375 +70739 -0.069732666015625 +70740 0.125640869140625 +70741 0.31268310546875 +70742 0.45501708984375 +70743 0.554779052734375 +70744 0.61065673828125 +70745 0.610931396484375 +70746 0.531463623046875 +70747 0.3883056640625 +70748 0.23468017578125 +70749 0.095245361328125 +70750 -0.00396728515625 +70751 -0.04852294921875 +70752 -0.055145263671875 +70753 -0.0758056640625 +70754 -0.138702392578125 +70755 -0.209197998046875 +70756 -0.289031982421875 +70757 -0.37884521484375 +70758 -0.456329345703125 +70759 -0.51641845703125 +70760 -0.519287109375 +70761 -0.458251953125 +70762 -0.384796142578125 +70763 -0.323699951171875 +70764 -0.269287109375 +70765 -0.1951904296875 +70766 -0.100006103515625 +70767 -0.01055908203125 +70768 0.1033935546875 +70769 0.24908447265625 +70770 0.373199462890625 +70771 0.45806884765625 +70772 0.511474609375 +70773 0.565399169921875 +70774 0.61138916015625 +70775 0.5897216796875 +70776 0.4906005859375 +70777 0.33148193359375 +70778 0.147796630859375 +70779 -0.01873779296875 +70780 -0.140289306640625 +70781 -0.191986083984375 +70782 -0.184295654296875 +70783 -0.161834716796875 +70784 -0.166595458984375 +70785 -0.19390869140625 +70786 -0.22442626953125 +70787 -0.279754638671875 +70788 -0.3389892578125 +70789 -0.3543701171875 +70790 -0.348175048828125 +70791 -0.32598876953125 +70792 -0.2581787109375 +70793 -0.139801025390625 +70794 0.014617919921875 +70795 0.144378662109375 +70796 0.221038818359375 +70797 0.27069091796875 +70798 0.294036865234375 +70799 0.311767578125 +70800 0.339141845703125 +70801 0.360260009765625 +70802 0.360504150390625 +70803 0.308380126953125 +70804 0.18170166015625 +70805 0.0047607421875 +70806 -0.17559814453125 +70807 -0.3143310546875 +70808 -0.36785888671875 +70809 -0.36248779296875 +70810 -0.343536376953125 +70811 -0.3018798828125 +70812 -0.231414794921875 +70813 -0.117645263671875 +70814 0.007049560546875 +70815 0.087982177734375 +70816 0.13946533203125 +70817 0.17425537109375 +70818 0.188201904296875 +70819 0.171234130859375 +70820 0.118438720703125 +70821 0.05706787109375 +70822 -0.010711669921875 +70823 -0.0914306640625 +70824 -0.162322998046875 +70825 -0.194549560546875 +70826 -0.1492919921875 +70827 -0.02166748046875 +70828 0.124053955078125 +70829 0.211151123046875 +70830 0.240447998046875 +70831 0.242218017578125 +70832 0.2257080078125 +70833 0.194366455078125 +70834 0.115509033203125 +70835 0.0128173828125 +70836 -0.053802490234375 +70837 -0.110626220703125 +70838 -0.199493408203125 +70839 -0.29437255859375 +70840 -0.33221435546875 +70841 -0.27972412109375 +70842 -0.185333251953125 +70843 -0.128204345703125 +70844 -0.115692138671875 +70845 -0.116455078125 +70846 -0.105926513671875 +70847 -0.053955078125 +70848 0.048797607421875 +70849 0.157318115234375 +70850 0.212005615234375 +70851 0.218475341796875 +70852 0.23724365234375 +70853 0.30535888671875 +70854 0.38128662109375 +70855 0.404449462890625 +70856 0.3944091796875 +70857 0.3885498046875 +70858 0.362640380859375 +70859 0.27362060546875 +70860 0.11712646484375 +70861 -0.054901123046875 +70862 -0.19085693359375 +70863 -0.28570556640625 +70864 -0.339263916015625 +70865 -0.3775634765625 +70866 -0.445709228515625 +70867 -0.535064697265625 +70868 -0.629058837890625 +70869 -0.697601318359375 +70870 -0.70391845703125 +70871 -0.6424560546875 +70872 -0.491241455078125 +70873 -0.265716552734375 +70874 -0.023712158203125 +70875 0.201751708984375 +70876 0.375823974609375 +70877 0.485076904296875 +70878 0.56884765625 +70879 0.634765625 +70880 0.63763427734375 +70881 0.5660400390625 +70882 0.4720458984375 +70883 0.40692138671875 +70884 0.3778076171875 +70885 0.376953125 +70886 0.371978759765625 +70887 0.313140869140625 +70888 0.184417724609375 +70889 0.011199951171875 +70890 -0.171051025390625 +70891 -0.33740234375 +70892 -0.47198486328125 +70893 -0.560394287109375 +70894 -0.58056640625 +70895 -0.54754638671875 +70896 -0.508575439453125 +70897 -0.459503173828125 +70898 -0.394378662109375 +70899 -0.35260009765625 +70900 -0.31170654296875 +70901 -0.197418212890625 +70902 -0.007965087890625 +70903 0.207489013671875 +70904 0.409210205078125 +70905 0.57208251953125 +70906 0.66595458984375 +70907 0.65875244140625 +70908 0.56744384765625 +70909 0.431396484375 +70910 0.29443359375 +70911 0.182464599609375 +70912 0.06365966796875 +70913 -0.075958251953125 +70914 -0.189422607421875 +70915 -0.271942138671875 +70916 -0.342529296875 +70917 -0.364166259765625 +70918 -0.327239990234375 +70919 -0.2769775390625 +70920 -0.253692626953125 +70921 -0.24365234375 +70922 -0.1983642578125 +70923 -0.116241455078125 +70924 -0.036834716796875 +70925 0.034881591796875 +70926 0.09124755859375 +70927 0.10888671875 +70928 0.125518798828125 +70929 0.15771484375 +70930 0.17828369140625 +70931 0.17108154296875 +70932 0.129974365234375 +70933 0.082427978515625 +70934 0.027679443359375 +70935 -0.065643310546875 +70936 -0.15936279296875 +70937 -0.21307373046875 +70938 -0.234649658203125 +70939 -0.2001953125 +70940 -0.119171142578125 +70941 -0.024749755859375 +70942 0.085784912109375 +70943 0.178131103515625 +70944 0.215576171875 +70945 0.211456298828125 +70946 0.17523193359375 +70947 0.128753662109375 +70948 0.1019287109375 +70949 0.0743408203125 +70950 0.04327392578125 +70951 0.038177490234375 +70952 0.076263427734375 +70953 0.14105224609375 +70954 0.186431884765625 +70955 0.188812255859375 +70956 0.1390380859375 +70957 0.041778564453125 +70958 -0.079437255859375 +70959 -0.219390869140625 +70960 -0.367828369140625 +70961 -0.494873046875 +70962 -0.556243896484375 +70963 -0.508697509765625 +70964 -0.3756103515625 +70965 -0.218902587890625 +70966 -0.063751220703125 +70967 0.091552734375 +70968 0.23602294921875 +70969 0.342987060546875 +70970 0.39520263671875 +70971 0.389373779296875 +70972 0.324249267578125 +70973 0.224090576171875 +70974 0.124267578125 +70975 0.037078857421875 +70976 -0.010101318359375 +70977 -0.019439697265625 +70978 -0.022796630859375 +70979 -0.001556396484375 +70980 0.056304931640625 +70981 0.106719970703125 +70982 0.096893310546875 +70983 0.042694091796875 +70984 -0.018035888671875 +70985 -0.07586669921875 +70986 -0.11944580078125 +70987 -0.15972900390625 +70988 -0.202606201171875 +70989 -0.24859619140625 +70990 -0.30517578125 +70991 -0.36212158203125 +70992 -0.39141845703125 +70993 -0.35528564453125 +70994 -0.249969482421875 +70995 -0.092864990234375 +70996 0.08905029296875 +70997 0.2352294921875 +70998 0.318817138671875 +70999 0.358642578125 +71000 0.347747802734375 +71001 0.28564453125 +71002 0.223175048828125 +71003 0.196746826171875 +71004 0.179840087890625 +71005 0.155548095703125 +71006 0.151214599609375 +71007 0.156951904296875 +71008 0.13177490234375 +71009 0.100799560546875 +71010 0.087127685546875 +71011 0.05487060546875 +71012 -0.009002685546875 +71013 -0.10400390625 +71014 -0.229400634765625 +71015 -0.35552978515625 +71016 -0.441925048828125 +71017 -0.473846435546875 +71018 -0.464813232421875 +71019 -0.419097900390625 +71020 -0.334320068359375 +71021 -0.227935791015625 +71022 -0.12347412109375 +71023 -0.02764892578125 +71024 0.077667236328125 +71025 0.2132568359375 +71026 0.38885498046875 +71027 0.582794189453125 +71028 0.734039306640625 +71029 0.800140380859375 +71030 0.7783203125 +71031 0.6651611328125 +71032 0.45965576171875 +71033 0.199188232421875 +71034 -0.050689697265625 +71035 -0.23297119140625 +71036 -0.33013916015625 +71037 -0.368408203125 +71038 -0.378936767578125 +71039 -0.376983642578125 +71040 -0.37969970703125 +71041 -0.391510009765625 +71042 -0.385345458984375 +71043 -0.3419189453125 +71044 -0.28289794921875 +71045 -0.251617431640625 +71046 -0.266143798828125 +71047 -0.273345947265625 +71048 -0.216796875 +71049 -0.128265380859375 +71050 -0.068145751953125 +71051 -0.0430908203125 +71052 -0.024444580078125 +71053 0.020721435546875 +71054 0.124481201171875 +71055 0.25787353515625 +71056 0.379119873046875 +71057 0.47991943359375 +71058 0.5281982421875 +71059 0.511138916015625 +71060 0.456207275390625 +71061 0.407470703125 +71062 0.383758544921875 +71063 0.35687255859375 +71064 0.31182861328125 +71065 0.250885009765625 +71066 0.1654052734375 +71067 0.035247802734375 +71068 -0.142059326171875 +71069 -0.33563232421875 +71070 -0.5345458984375 +71071 -0.72186279296875 +71072 -0.836669921875 +71073 -0.8326416015625 +71074 -0.7296142578125 +71075 -0.582550048828125 +71076 -0.440093994140625 +71077 -0.324310302734375 +71078 -0.20147705078125 +71079 -0.044647216796875 +71080 0.103973388671875 +71081 0.202392578125 +71082 0.264495849609375 +71083 0.338897705078125 +71084 0.443817138671875 +71085 0.545074462890625 +71086 0.6173095703125 +71087 0.6524658203125 +71088 0.66339111328125 +71089 0.6561279296875 +71090 0.606781005859375 +71091 0.501190185546875 +71092 0.352783203125 +71093 0.176544189453125 +71094 -0.034820556640625 +71095 -0.258209228515625 +71096 -0.44244384765625 +71097 -0.5753173828125 +71098 -0.65203857421875 +71099 -0.641632080078125 +71100 -0.562164306640625 +71101 -0.458038330078125 +71102 -0.350555419921875 +71103 -0.260528564453125 +71104 -0.192108154296875 +71105 -0.141937255859375 +71106 -0.1021728515625 +71107 -0.062896728515625 +71108 -0.011932373046875 +71109 0.062835693359375 +71110 0.148712158203125 +71111 0.241729736328125 +71112 0.34912109375 +71113 0.457305908203125 +71114 0.54388427734375 +71115 0.5728759765625 +71116 0.506591796875 +71117 0.351226806640625 +71118 0.146514892578125 +71119 -0.05523681640625 +71120 -0.21624755859375 +71121 -0.334930419921875 +71122 -0.402984619140625 +71123 -0.4412841796875 +71124 -0.49578857421875 +71125 -0.5601806640625 +71126 -0.600738525390625 +71127 -0.584228515625 +71128 -0.47930908203125 +71129 -0.27935791015625 +71130 -0.0089111328125 +71131 0.268798828125 +71132 0.482818603515625 +71133 0.60369873046875 +71134 0.650421142578125 +71135 0.66400146484375 +71136 0.6414794921875 +71137 0.572540283203125 +71138 0.498138427734375 +71139 0.439453125 +71140 0.375518798828125 +71141 0.274505615234375 +71142 0.1087646484375 +71143 -0.099395751953125 +71144 -0.3182373046875 +71145 -0.5489501953125 +71146 -0.7738037109375 +71147 -0.86383056640625 +71148 -0.870391845703125 +71149 -0.86895751953125 +71150 -0.861053466796875 +71151 -0.765869140625 +71152 -0.5301513671875 +71153 -0.214691162109375 +71154 0.137359619140625 +71155 0.474822998046875 +71156 0.76239013671875 +71157 0.867462158203125 +71158 0.870361328125 +71159 0.86480712890625 +71160 0.831817626953125 +71161 0.677581787109375 +71162 0.495880126953125 +71163 0.30767822265625 +71164 0.116180419921875 +71165 -0.110748291015625 +71166 -0.381805419921875 +71167 -0.6572265625 +71168 -0.857421875 +71169 -0.870391845703125 +71170 -0.870391845703125 +71171 -0.86444091796875 +71172 -0.85723876953125 +71173 -0.790008544921875 +71174 -0.62847900390625 +71175 -0.3956298828125 +71176 -0.126708984375 +71177 0.150115966796875 +71178 0.424041748046875 +71179 0.670623779296875 +71180 0.854522705078125 +71181 0.866485595703125 +71182 0.86920166015625 +71183 0.8653564453125 +71184 0.857147216796875 +71185 0.766845703125 +71186 0.628509521484375 +71187 0.462127685546875 +71188 0.297210693359375 +71189 0.14862060546875 +71190 -0.00537109375 +71191 -0.15753173828125 +71192 -0.31304931640625 +71193 -0.48876953125 +71194 -0.6416015625 +71195 -0.751373291015625 +71196 -0.84619140625 +71197 -0.861297607421875 +71198 -0.863250732421875 +71199 -0.856597900390625 +71200 -0.7498779296875 +71201 -0.624542236328125 +71202 -0.47808837890625 +71203 -0.253387451171875 +71204 0.003692626953125 +71205 0.2257080078125 +71206 0.427154541015625 +71207 0.643218994140625 +71208 0.855926513671875 +71209 0.870361328125 +71210 0.870361328125 +71211 0.862762451171875 +71212 0.79669189453125 +71213 0.595794677734375 +71214 0.362152099609375 +71215 0.1270751953125 +71216 -0.086944580078125 +71217 -0.2784423828125 +71218 -0.484832763671875 +71219 -0.729583740234375 +71220 -0.86688232421875 +71221 -0.870391845703125 +71222 -0.86859130859375 +71223 -0.86279296875 +71224 -0.817962646484375 +71225 -0.6116943359375 +71226 -0.3128662109375 +71227 0.039398193359375 +71228 0.422821044921875 +71229 0.805145263671875 +71230 0.870361328125 +71231 0.870361328125 +71232 0.860015869140625 +71233 0.727935791015625 +71234 0.48114013671875 +71235 0.2059326171875 +71236 -0.06103515625 +71237 -0.29913330078125 +71238 -0.516204833984375 +71239 -0.7252197265625 +71240 -0.85980224609375 +71241 -0.870391845703125 +71242 -0.870391845703125 +71243 -0.858062744140625 +71244 -0.673004150390625 +71245 -0.42694091796875 +71246 -0.2100830078125 +71247 -0.0362548828125 +71248 0.10943603515625 +71249 0.23516845703125 +71250 0.373687744140625 +71251 0.517791748046875 +71252 0.602783203125 +71253 0.635711669921875 +71254 0.655181884765625 +71255 0.65948486328125 +71256 0.651275634765625 +71257 0.61846923828125 +71258 0.53753662109375 +71259 0.404144287109375 +71260 0.22186279296875 +71261 0.003997802734375 +71262 -0.22100830078125 +71263 -0.42449951171875 +71264 -0.579833984375 +71265 -0.641876220703125 +71266 -0.6177978515625 +71267 -0.575531005859375 +71268 -0.526336669921875 +71269 -0.42645263671875 +71270 -0.2581787109375 +71271 -0.068695068359375 +71272 0.09222412109375 +71273 0.232147216796875 +71274 0.3509521484375 +71275 0.410064697265625 +71276 0.372955322265625 +71277 0.2554931640625 +71278 0.10711669921875 +71279 -0.052886962890625 +71280 -0.186279296875 +71281 -0.23291015625 +71282 -0.209442138671875 +71283 -0.174163818359375 +71284 -0.126739501953125 +71285 -0.048126220703125 +71286 0.0426025390625 +71287 0.10748291015625 +71288 0.1409912109375 +71289 0.19708251953125 +71290 0.273651123046875 +71291 0.31768798828125 +71292 0.341094970703125 +71293 0.368011474609375 +71294 0.37249755859375 +71295 0.30072021484375 +71296 0.1517333984375 +71297 -0.01470947265625 +71298 -0.1883544921875 +71299 -0.372711181640625 +71300 -0.51397705078125 +71301 -0.57177734375 +71302 -0.53948974609375 +71303 -0.43511962890625 +71304 -0.2962646484375 +71305 -0.161102294921875 +71306 -0.0435791015625 +71307 0.060394287109375 +71308 0.13665771484375 +71309 0.170135498046875 +71310 0.16552734375 +71311 0.15728759765625 +71312 0.150787353515625 +71313 0.12200927734375 +71314 0.080108642578125 +71315 0.05126953125 +71316 0.062896728515625 +71317 0.09271240234375 +71318 0.092987060546875 +71319 0.07855224609375 +71320 0.06427001953125 +71321 0.0347900390625 +71322 -0.01171875 +71323 -0.056060791015625 +71324 -0.055511474609375 +71325 -0.010467529296875 +71326 0.02508544921875 +71327 0.025665283203125 +71328 0.017333984375 +71329 0.00189208984375 +71330 -0.03173828125 +71331 -0.071502685546875 +71332 -0.13543701171875 +71333 -0.219970703125 +71334 -0.300506591796875 +71335 -0.376312255859375 +71336 -0.416107177734375 +71337 -0.371124267578125 +71338 -0.242279052734375 +71339 -0.069732666015625 +71340 0.125640869140625 +71341 0.31268310546875 +71342 0.45501708984375 +71343 0.554779052734375 +71344 0.61065673828125 +71345 0.610931396484375 +71346 0.531463623046875 +71347 0.3883056640625 +71348 0.23468017578125 +71349 0.095245361328125 +71350 -0.00396728515625 +71351 -0.04852294921875 +71352 -0.055145263671875 +71353 -0.0758056640625 +71354 -0.138702392578125 +71355 -0.209197998046875 +71356 -0.289031982421875 +71357 -0.37884521484375 +71358 -0.456329345703125 +71359 -0.51641845703125 +71360 -0.519287109375 +71361 -0.458251953125 +71362 -0.384796142578125 +71363 -0.323699951171875 +71364 -0.269287109375 +71365 -0.1951904296875 +71366 -0.100006103515625 +71367 -0.01055908203125 +71368 0.1033935546875 +71369 0.24908447265625 +71370 0.373199462890625 +71371 0.45806884765625 +71372 0.511474609375 +71373 0.565399169921875 +71374 0.61138916015625 +71375 0.5897216796875 +71376 0.4906005859375 +71377 0.33148193359375 +71378 0.147796630859375 +71379 -0.01873779296875 +71380 -0.140289306640625 +71381 -0.191986083984375 +71382 -0.184295654296875 +71383 -0.161834716796875 +71384 -0.166595458984375 +71385 -0.19390869140625 +71386 -0.22442626953125 +71387 -0.279754638671875 +71388 -0.3389892578125 +71389 -0.3543701171875 +71390 -0.348175048828125 +71391 -0.32598876953125 +71392 -0.2581787109375 +71393 -0.139801025390625 +71394 0.014617919921875 +71395 0.144378662109375 +71396 0.221038818359375 +71397 0.27069091796875 +71398 0.294036865234375 +71399 0.311767578125 +71400 0.339141845703125 +71401 0.360260009765625 +71402 0.360504150390625 +71403 0.308380126953125 +71404 0.18170166015625 +71405 0.0047607421875 +71406 -0.17559814453125 +71407 -0.3143310546875 +71408 -0.36785888671875 +71409 -0.36248779296875 +71410 -0.343536376953125 +71411 -0.3018798828125 +71412 -0.231414794921875 +71413 -0.117645263671875 +71414 0.007049560546875 +71415 0.087982177734375 +71416 0.13946533203125 +71417 0.17425537109375 +71418 0.188201904296875 +71419 0.171234130859375 +71420 0.118438720703125 +71421 0.05706787109375 +71422 -0.010711669921875 +71423 -0.0914306640625 +71424 -0.162322998046875 +71425 -0.194549560546875 +71426 -0.1492919921875 +71427 -0.02166748046875 +71428 0.124053955078125 +71429 0.211151123046875 +71430 0.240447998046875 +71431 0.242218017578125 +71432 0.2257080078125 +71433 0.194366455078125 +71434 0.115509033203125 +71435 0.0128173828125 +71436 -0.053802490234375 +71437 -0.110626220703125 +71438 -0.199493408203125 +71439 -0.29437255859375 +71440 -0.33221435546875 +71441 -0.27972412109375 +71442 -0.185333251953125 +71443 -0.128204345703125 +71444 -0.115692138671875 +71445 -0.116455078125 +71446 -0.105926513671875 +71447 -0.053955078125 +71448 0.048797607421875 +71449 0.157318115234375 +71450 0.212005615234375 +71451 0.218475341796875 +71452 0.23724365234375 +71453 0.30535888671875 +71454 0.38128662109375 +71455 0.404449462890625 +71456 0.3944091796875 +71457 0.3885498046875 +71458 0.362640380859375 +71459 0.27362060546875 +71460 0.11712646484375 +71461 -0.054901123046875 +71462 -0.19085693359375 +71463 -0.28570556640625 +71464 -0.339263916015625 +71465 -0.3775634765625 +71466 -0.445709228515625 +71467 -0.535064697265625 +71468 -0.629058837890625 +71469 -0.697601318359375 +71470 -0.70391845703125 +71471 -0.6424560546875 +71472 -0.491241455078125 +71473 -0.265716552734375 +71474 -0.023712158203125 +71475 0.201751708984375 +71476 0.375823974609375 +71477 0.485076904296875 +71478 0.56884765625 +71479 0.634765625 +71480 0.63763427734375 +71481 0.5660400390625 +71482 0.4720458984375 +71483 0.40692138671875 +71484 0.3778076171875 +71485 0.376953125 +71486 0.371978759765625 +71487 0.313140869140625 +71488 0.184417724609375 +71489 0.011199951171875 +71490 -0.171051025390625 +71491 -0.33740234375 +71492 -0.47198486328125 +71493 -0.560394287109375 +71494 -0.58056640625 +71495 -0.54754638671875 +71496 -0.508575439453125 +71497 -0.459503173828125 +71498 -0.394378662109375 +71499 -0.35260009765625 +71500 -0.31170654296875 +71501 -0.197418212890625 +71502 -0.007965087890625 +71503 0.207489013671875 +71504 0.409210205078125 +71505 0.57208251953125 +71506 0.66595458984375 +71507 0.65875244140625 +71508 0.56744384765625 +71509 0.431396484375 +71510 0.29443359375 +71511 0.182464599609375 +71512 0.06365966796875 +71513 -0.075958251953125 +71514 -0.189422607421875 +71515 -0.271942138671875 +71516 -0.342529296875 +71517 -0.364166259765625 +71518 -0.327239990234375 +71519 -0.2769775390625 +71520 -0.253692626953125 +71521 -0.24365234375 +71522 -0.1983642578125 +71523 -0.116241455078125 +71524 -0.036834716796875 +71525 0.034881591796875 +71526 0.09124755859375 +71527 0.10888671875 +71528 0.125518798828125 +71529 0.15771484375 +71530 0.17828369140625 +71531 0.17108154296875 +71532 0.129974365234375 +71533 0.082427978515625 +71534 0.027679443359375 +71535 -0.065643310546875 +71536 -0.15936279296875 +71537 -0.21307373046875 +71538 -0.234649658203125 +71539 -0.2001953125 +71540 -0.119171142578125 +71541 -0.024749755859375 +71542 0.085784912109375 +71543 0.178131103515625 +71544 0.215576171875 +71545 0.211456298828125 +71546 0.17523193359375 +71547 0.128753662109375 +71548 0.1019287109375 +71549 0.0743408203125 +71550 0.04327392578125 +71551 0.038177490234375 +71552 0.076263427734375 +71553 0.14105224609375 +71554 0.186431884765625 +71555 0.188812255859375 +71556 0.1390380859375 +71557 0.041778564453125 +71558 -0.079437255859375 +71559 -0.219390869140625 +71560 -0.367828369140625 +71561 -0.494873046875 +71562 -0.556243896484375 +71563 -0.508697509765625 +71564 -0.3756103515625 +71565 -0.218902587890625 +71566 -0.063751220703125 +71567 0.091552734375 +71568 0.23602294921875 +71569 0.342987060546875 +71570 0.39520263671875 +71571 0.389373779296875 +71572 0.324249267578125 +71573 0.224090576171875 +71574 0.124267578125 +71575 0.037078857421875 +71576 -0.010101318359375 +71577 -0.019439697265625 +71578 -0.022796630859375 +71579 -0.001556396484375 +71580 0.056304931640625 +71581 0.106719970703125 +71582 0.096893310546875 +71583 0.042694091796875 +71584 -0.018035888671875 +71585 -0.07586669921875 +71586 -0.11944580078125 +71587 -0.15972900390625 +71588 -0.202606201171875 +71589 -0.24859619140625 +71590 -0.30517578125 +71591 -0.36212158203125 +71592 -0.39141845703125 +71593 -0.35528564453125 +71594 -0.249969482421875 +71595 -0.092864990234375 +71596 0.08905029296875 +71597 0.2352294921875 +71598 0.318817138671875 +71599 0.358642578125 +71600 0.347747802734375 +71601 0.28564453125 +71602 0.223175048828125 +71603 0.196746826171875 +71604 0.179840087890625 +71605 0.155548095703125 +71606 0.151214599609375 +71607 0.156951904296875 +71608 0.13177490234375 +71609 0.100799560546875 +71610 0.087127685546875 +71611 0.05487060546875 +71612 -0.009002685546875 +71613 -0.10400390625 +71614 -0.229400634765625 +71615 -0.35552978515625 +71616 -0.441925048828125 +71617 -0.473846435546875 +71618 -0.464813232421875 +71619 -0.419097900390625 +71620 -0.334320068359375 +71621 -0.227935791015625 +71622 -0.12347412109375 +71623 -0.02764892578125 +71624 0.077667236328125 +71625 0.2132568359375 +71626 0.38885498046875 +71627 0.582794189453125 +71628 0.734039306640625 +71629 0.800140380859375 +71630 0.7783203125 +71631 0.6651611328125 +71632 0.45965576171875 +71633 0.199188232421875 +71634 -0.050689697265625 +71635 -0.23297119140625 +71636 -0.33013916015625 +71637 -0.368408203125 +71638 -0.378936767578125 +71639 -0.376983642578125 +71640 -0.37969970703125 +71641 -0.391510009765625 +71642 -0.385345458984375 +71643 -0.3419189453125 +71644 -0.28289794921875 +71645 -0.251617431640625 +71646 -0.266143798828125 +71647 -0.273345947265625 +71648 -0.216796875 +71649 -0.128265380859375 +71650 -0.068145751953125 +71651 -0.0430908203125 +71652 -0.024444580078125 +71653 0.020721435546875 +71654 0.124481201171875 +71655 0.25787353515625 +71656 0.379119873046875 +71657 0.47991943359375 +71658 0.5281982421875 +71659 0.511138916015625 +71660 0.456207275390625 +71661 0.407470703125 +71662 0.383758544921875 +71663 0.35687255859375 +71664 0.31182861328125 +71665 0.250885009765625 +71666 0.1654052734375 +71667 0.035247802734375 +71668 -0.142059326171875 +71669 -0.33563232421875 +71670 -0.5345458984375 +71671 -0.72186279296875 +71672 -0.836669921875 +71673 -0.8326416015625 +71674 -0.7296142578125 +71675 -0.582550048828125 +71676 -0.440093994140625 +71677 -0.324310302734375 +71678 -0.20147705078125 +71679 -0.044647216796875 +71680 0.103973388671875 +71681 0.202392578125 +71682 0.264495849609375 +71683 0.338897705078125 +71684 0.443817138671875 +71685 0.545074462890625 +71686 0.6173095703125 +71687 0.6524658203125 +71688 0.66339111328125 +71689 0.6561279296875 +71690 0.606781005859375 +71691 0.501190185546875 +71692 0.352783203125 +71693 0.176544189453125 +71694 -0.034820556640625 +71695 -0.258209228515625 +71696 -0.44244384765625 +71697 -0.5753173828125 +71698 -0.65203857421875 +71699 -0.641632080078125 +71700 -0.562164306640625 +71701 -0.458038330078125 +71702 -0.350555419921875 +71703 -0.260528564453125 +71704 -0.192108154296875 +71705 -0.141937255859375 +71706 -0.1021728515625 +71707 -0.062896728515625 +71708 -0.011932373046875 +71709 0.062835693359375 +71710 0.148712158203125 +71711 0.241729736328125 +71712 0.34912109375 +71713 0.457305908203125 +71714 0.54388427734375 +71715 0.5728759765625 +71716 0.506591796875 +71717 0.351226806640625 +71718 0.146514892578125 +71719 -0.05523681640625 +71720 -0.21624755859375 +71721 -0.334930419921875 +71722 -0.402984619140625 +71723 -0.4412841796875 +71724 -0.49578857421875 +71725 -0.5601806640625 +71726 -0.600738525390625 +71727 -0.584228515625 +71728 -0.47930908203125 +71729 -0.27935791015625 +71730 -0.0089111328125 +71731 0.268798828125 +71732 0.482818603515625 +71733 0.60369873046875 +71734 0.650421142578125 +71735 0.66400146484375 +71736 0.6414794921875 +71737 0.572540283203125 +71738 0.498138427734375 +71739 0.439453125 +71740 0.375518798828125 +71741 0.274505615234375 +71742 0.1087646484375 +71743 -0.099395751953125 +71744 -0.3182373046875 +71745 -0.5489501953125 +71746 -0.7738037109375 +71747 -0.86383056640625 +71748 -0.870391845703125 +71749 -0.86895751953125 +71750 -0.861053466796875 +71751 -0.765869140625 +71752 -0.5301513671875 +71753 -0.214691162109375 +71754 0.137359619140625 +71755 0.474822998046875 +71756 0.76239013671875 +71757 0.867462158203125 +71758 0.870361328125 +71759 0.86480712890625 +71760 0.831817626953125 +71761 0.677581787109375 +71762 0.495880126953125 +71763 0.30767822265625 +71764 0.116180419921875 +71765 -0.110748291015625 +71766 -0.381805419921875 +71767 -0.6572265625 +71768 -0.857421875 +71769 -0.870391845703125 +71770 -0.870391845703125 +71771 -0.86444091796875 +71772 -0.85723876953125 +71773 -0.790008544921875 +71774 -0.62847900390625 +71775 -0.3956298828125 +71776 -0.126708984375 +71777 0.150115966796875 +71778 0.424041748046875 +71779 0.670623779296875 +71780 0.854522705078125 +71781 0.866485595703125 +71782 0.86920166015625 +71783 0.8653564453125 +71784 0.857147216796875 +71785 0.766845703125 +71786 0.628509521484375 +71787 0.462127685546875 +71788 0.297210693359375 +71789 0.14862060546875 +71790 -0.00537109375 +71791 -0.15753173828125 +71792 -0.31304931640625 +71793 -0.48876953125 +71794 -0.6416015625 +71795 -0.751373291015625 +71796 -0.84619140625 +71797 -0.861297607421875 +71798 -0.863250732421875 +71799 -0.856597900390625 +71800 -0.7498779296875 +71801 -0.624542236328125 +71802 -0.47808837890625 +71803 -0.253387451171875 +71804 0.003692626953125 +71805 0.2257080078125 +71806 0.427154541015625 +71807 0.643218994140625 +71808 0.855926513671875 +71809 0.870361328125 +71810 0.870361328125 +71811 0.862762451171875 +71812 0.79669189453125 +71813 0.595794677734375 +71814 0.362152099609375 +71815 0.1270751953125 +71816 -0.086944580078125 +71817 -0.2784423828125 +71818 -0.484832763671875 +71819 -0.729583740234375 +71820 -0.86688232421875 +71821 -0.870391845703125 +71822 -0.86859130859375 +71823 -0.86279296875 +71824 -0.817962646484375 +71825 -0.6116943359375 +71826 -0.3128662109375 +71827 0.039398193359375 +71828 0.422821044921875 +71829 0.805145263671875 +71830 0.870361328125 +71831 0.870361328125 +71832 0.860015869140625 +71833 0.727935791015625 +71834 0.48114013671875 +71835 0.2059326171875 +71836 -0.06103515625 +71837 -0.29913330078125 +71838 -0.516204833984375 +71839 -0.7252197265625 +71840 -0.85980224609375 +71841 -0.870391845703125 +71842 -0.870391845703125 +71843 -0.858062744140625 +71844 -0.673004150390625 +71845 -0.42694091796875 +71846 -0.2100830078125 +71847 -0.0362548828125 +71848 0.10943603515625 +71849 0.23516845703125 +71850 0.373687744140625 +71851 0.517791748046875 +71852 0.602783203125 +71853 0.635711669921875 +71854 0.655181884765625 +71855 0.65948486328125 +71856 0.651275634765625 +71857 0.61846923828125 +71858 0.53753662109375 +71859 0.404144287109375 +71860 0.22186279296875 +71861 0.003997802734375 +71862 -0.22100830078125 +71863 -0.42449951171875 +71864 -0.579833984375 +71865 -0.641876220703125 +71866 -0.6177978515625 +71867 -0.575531005859375 +71868 -0.526336669921875 +71869 -0.42645263671875 +71870 -0.2581787109375 +71871 -0.068695068359375 +71872 0.09222412109375 +71873 0.232147216796875 +71874 0.3509521484375 +71875 0.410064697265625 +71876 0.372955322265625 +71877 0.2554931640625 +71878 0.10711669921875 +71879 -0.052886962890625 +71880 -0.186279296875 +71881 -0.23291015625 +71882 -0.209442138671875 +71883 -0.174163818359375 +71884 -0.126739501953125 +71885 -0.048126220703125 +71886 0.0426025390625 +71887 0.10748291015625 +71888 0.1409912109375 +71889 0.19708251953125 +71890 0.273651123046875 +71891 0.31768798828125 +71892 0.341094970703125 +71893 0.368011474609375 +71894 0.37249755859375 +71895 0.30072021484375 +71896 0.1517333984375 +71897 -0.01470947265625 +71898 -0.1883544921875 +71899 -0.372711181640625 +71900 -0.51397705078125 +71901 -0.57177734375 +71902 -0.53948974609375 +71903 -0.43511962890625 +71904 -0.2962646484375 +71905 -0.161102294921875 +71906 -0.0435791015625 +71907 0.060394287109375 +71908 0.13665771484375 +71909 0.170135498046875 +71910 0.16552734375 +71911 0.15728759765625 +71912 0.150787353515625 +71913 0.12200927734375 +71914 0.080108642578125 +71915 0.05126953125 +71916 0.062896728515625 +71917 0.09271240234375 +71918 0.092987060546875 +71919 0.07855224609375 +71920 0.06427001953125 +71921 0.0347900390625 +71922 -0.01171875 +71923 -0.056060791015625 +71924 -0.055511474609375 +71925 -0.010467529296875 +71926 0.02508544921875 +71927 0.025665283203125 +71928 0.017333984375 +71929 0.00189208984375 +71930 -0.03173828125 +71931 -0.071502685546875 +71932 -0.13543701171875 +71933 -0.219970703125 +71934 -0.300506591796875 +71935 -0.376312255859375 +71936 -0.416107177734375 +71937 -0.371124267578125 +71938 -0.242279052734375 +71939 -0.069732666015625 +71940 0.125640869140625 +71941 0.31268310546875 +71942 0.45501708984375 +71943 0.554779052734375 +71944 0.61065673828125 +71945 0.610931396484375 +71946 0.531463623046875 +71947 0.3883056640625 +71948 0.23468017578125 +71949 0.095245361328125 +71950 -0.00396728515625 +71951 -0.04852294921875 +71952 -0.055145263671875 +71953 -0.0758056640625 +71954 -0.138702392578125 +71955 -0.209197998046875 +71956 -0.289031982421875 +71957 -0.37884521484375 +71958 -0.456329345703125 +71959 -0.51641845703125 +71960 -0.519287109375 +71961 -0.458251953125 +71962 -0.384796142578125 +71963 -0.323699951171875 +71964 -0.269287109375 +71965 -0.1951904296875 +71966 -0.100006103515625 +71967 -0.01055908203125 +71968 0.1033935546875 +71969 0.24908447265625 +71970 0.373199462890625 +71971 0.45806884765625 +71972 0.511474609375 +71973 0.565399169921875 +71974 0.61138916015625 +71975 0.5897216796875 +71976 0.4906005859375 +71977 0.33148193359375 +71978 0.147796630859375 +71979 -0.01873779296875 +71980 -0.140289306640625 +71981 -0.191986083984375 +71982 -0.184295654296875 +71983 -0.161834716796875 +71984 -0.166595458984375 +71985 -0.19390869140625 +71986 -0.22442626953125 +71987 -0.279754638671875 +71988 -0.3389892578125 +71989 -0.3543701171875 +71990 -0.348175048828125 +71991 -0.32598876953125 +71992 -0.2581787109375 +71993 -0.139801025390625 +71994 0.014617919921875 +71995 0.144378662109375 +71996 0.221038818359375 +71997 0.27069091796875 +71998 0.294036865234375 +71999 0.311767578125 +72000 0.339141845703125 +72001 0.360260009765625 +72002 0.360504150390625 +72003 0.308380126953125 +72004 0.18170166015625 +72005 0.0047607421875 +72006 -0.17559814453125 +72007 -0.3143310546875 +72008 -0.36785888671875 +72009 -0.36248779296875 +72010 -0.343536376953125 +72011 -0.3018798828125 +72012 -0.231414794921875 +72013 -0.117645263671875 +72014 0.007049560546875 +72015 0.087982177734375 +72016 0.13946533203125 +72017 0.17425537109375 +72018 0.188201904296875 +72019 0.171234130859375 +72020 0.118438720703125 +72021 0.05706787109375 +72022 -0.010711669921875 +72023 -0.0914306640625 +72024 -0.162322998046875 +72025 -0.194549560546875 +72026 -0.1492919921875 +72027 -0.02166748046875 +72028 0.124053955078125 +72029 0.211151123046875 +72030 0.240447998046875 +72031 0.242218017578125 +72032 0.2257080078125 +72033 0.194366455078125 +72034 0.115509033203125 +72035 0.0128173828125 +72036 -0.053802490234375 +72037 -0.110626220703125 +72038 -0.199493408203125 +72039 -0.29437255859375 +72040 -0.33221435546875 +72041 -0.27972412109375 +72042 -0.185333251953125 +72043 -0.128204345703125 +72044 -0.115692138671875 +72045 -0.116455078125 +72046 -0.105926513671875 +72047 -0.053955078125 +72048 0.048797607421875 +72049 0.157318115234375 +72050 0.212005615234375 +72051 0.218475341796875 +72052 0.23724365234375 +72053 0.30535888671875 +72054 0.38128662109375 +72055 0.404449462890625 +72056 0.3944091796875 +72057 0.3885498046875 +72058 0.362640380859375 +72059 0.27362060546875 +72060 0.11712646484375 +72061 -0.054901123046875 +72062 -0.19085693359375 +72063 -0.28570556640625 +72064 -0.339263916015625 +72065 -0.3775634765625 +72066 -0.445709228515625 +72067 -0.535064697265625 +72068 -0.629058837890625 +72069 -0.697601318359375 +72070 -0.70391845703125 +72071 -0.6424560546875 +72072 -0.491241455078125 +72073 -0.265716552734375 +72074 -0.023712158203125 +72075 0.201751708984375 +72076 0.375823974609375 +72077 0.485076904296875 +72078 0.56884765625 +72079 0.634765625 +72080 0.63763427734375 +72081 0.5660400390625 +72082 0.4720458984375 +72083 0.40692138671875 +72084 0.3778076171875 +72085 0.376953125 +72086 0.371978759765625 +72087 0.313140869140625 +72088 0.184417724609375 +72089 0.011199951171875 +72090 -0.171051025390625 +72091 -0.33740234375 +72092 -0.47198486328125 +72093 -0.560394287109375 +72094 -0.58056640625 +72095 -0.54754638671875 +72096 -0.508575439453125 +72097 -0.459503173828125 +72098 -0.394378662109375 +72099 -0.35260009765625 +72100 -0.31170654296875 +72101 -0.197418212890625 +72102 -0.007965087890625 +72103 0.207489013671875 +72104 0.409210205078125 +72105 0.57208251953125 +72106 0.66595458984375 +72107 0.65875244140625 +72108 0.56744384765625 +72109 0.431396484375 +72110 0.29443359375 +72111 0.182464599609375 +72112 0.06365966796875 +72113 -0.075958251953125 +72114 -0.189422607421875 +72115 -0.271942138671875 +72116 -0.342529296875 +72117 -0.364166259765625 +72118 -0.327239990234375 +72119 -0.2769775390625 +72120 -0.253692626953125 +72121 -0.24365234375 +72122 -0.1983642578125 +72123 -0.116241455078125 +72124 -0.036834716796875 +72125 0.034881591796875 +72126 0.09124755859375 +72127 0.10888671875 +72128 0.125518798828125 +72129 0.15771484375 +72130 0.17828369140625 +72131 0.17108154296875 +72132 0.129974365234375 +72133 0.082427978515625 +72134 0.027679443359375 +72135 -0.065643310546875 +72136 -0.15936279296875 +72137 -0.21307373046875 +72138 -0.234649658203125 +72139 -0.2001953125 +72140 -0.119171142578125 +72141 -0.024749755859375 +72142 0.085784912109375 +72143 0.178131103515625 +72144 0.215576171875 +72145 0.211456298828125 +72146 0.17523193359375 +72147 0.128753662109375 +72148 0.1019287109375 +72149 0.0743408203125 +72150 0.04327392578125 +72151 0.038177490234375 +72152 0.076263427734375 +72153 0.14105224609375 +72154 0.186431884765625 +72155 0.188812255859375 +72156 0.1390380859375 +72157 0.041778564453125 +72158 -0.079437255859375 +72159 -0.219390869140625 +72160 -0.367828369140625 +72161 -0.494873046875 +72162 -0.556243896484375 +72163 -0.508697509765625 +72164 -0.3756103515625 +72165 -0.218902587890625 +72166 -0.063751220703125 +72167 0.091552734375 +72168 0.23602294921875 +72169 0.342987060546875 +72170 0.39520263671875 +72171 0.389373779296875 +72172 0.324249267578125 +72173 0.224090576171875 +72174 0.124267578125 +72175 0.037078857421875 +72176 -0.010101318359375 +72177 -0.019439697265625 +72178 -0.022796630859375 +72179 -0.001556396484375 +72180 0.056304931640625 +72181 0.106719970703125 +72182 0.096893310546875 +72183 0.042694091796875 +72184 -0.018035888671875 +72185 -0.07586669921875 +72186 -0.11944580078125 +72187 -0.15972900390625 +72188 -0.202606201171875 +72189 -0.24859619140625 +72190 -0.30517578125 +72191 -0.36212158203125 +72192 -0.39141845703125 +72193 -0.35528564453125 +72194 -0.249969482421875 +72195 -0.092864990234375 +72196 0.08905029296875 +72197 0.2352294921875 +72198 0.318817138671875 +72199 0.358642578125 +72200 0.347747802734375 +72201 0.28564453125 +72202 0.223175048828125 +72203 0.196746826171875 +72204 0.179840087890625 +72205 0.155548095703125 +72206 0.151214599609375 +72207 0.156951904296875 +72208 0.13177490234375 +72209 0.100799560546875 +72210 0.087127685546875 +72211 0.05487060546875 +72212 -0.009002685546875 +72213 -0.10400390625 +72214 -0.229400634765625 +72215 -0.35552978515625 +72216 -0.441925048828125 +72217 -0.473846435546875 +72218 -0.464813232421875 +72219 -0.419097900390625 +72220 -0.334320068359375 +72221 -0.227935791015625 +72222 -0.12347412109375 +72223 -0.02764892578125 +72224 0.077667236328125 +72225 0.2132568359375 +72226 0.38885498046875 +72227 0.582794189453125 +72228 0.734039306640625 +72229 0.800140380859375 +72230 0.7783203125 +72231 0.6651611328125 +72232 0.45965576171875 +72233 0.199188232421875 +72234 -0.050689697265625 +72235 -0.23297119140625 +72236 -0.33013916015625 +72237 -0.368408203125 +72238 -0.378936767578125 +72239 -0.376983642578125 +72240 -0.37969970703125 +72241 -0.391510009765625 +72242 -0.385345458984375 +72243 -0.3419189453125 +72244 -0.28289794921875 +72245 -0.251617431640625 +72246 -0.266143798828125 +72247 -0.273345947265625 +72248 -0.216796875 +72249 -0.128265380859375 +72250 -0.068145751953125 +72251 -0.0430908203125 +72252 -0.024444580078125 +72253 0.020721435546875 +72254 0.124481201171875 +72255 0.25787353515625 +72256 0.379119873046875 +72257 0.47991943359375 +72258 0.5281982421875 +72259 0.511138916015625 +72260 0.456207275390625 +72261 0.407470703125 +72262 0.383758544921875 +72263 0.35687255859375 +72264 0.31182861328125 +72265 0.250885009765625 +72266 0.1654052734375 +72267 0.035247802734375 +72268 -0.142059326171875 +72269 -0.33563232421875 +72270 -0.5345458984375 +72271 -0.72186279296875 +72272 -0.836669921875 +72273 -0.8326416015625 +72274 -0.7296142578125 +72275 -0.582550048828125 +72276 -0.440093994140625 +72277 -0.324310302734375 +72278 -0.20147705078125 +72279 -0.044647216796875 +72280 0.103973388671875 +72281 0.202392578125 +72282 0.264495849609375 +72283 0.338897705078125 +72284 0.443817138671875 +72285 0.545074462890625 +72286 0.6173095703125 +72287 0.6524658203125 +72288 0.66339111328125 +72289 0.6561279296875 +72290 0.606781005859375 +72291 0.501190185546875 +72292 0.352783203125 +72293 0.176544189453125 +72294 -0.034820556640625 +72295 -0.258209228515625 +72296 -0.44244384765625 +72297 -0.5753173828125 +72298 -0.65203857421875 +72299 -0.641632080078125 +72300 -0.562164306640625 +72301 -0.458038330078125 +72302 -0.350555419921875 +72303 -0.260528564453125 +72304 -0.192108154296875 +72305 -0.141937255859375 +72306 -0.1021728515625 +72307 -0.062896728515625 +72308 -0.011932373046875 +72309 0.062835693359375 +72310 0.148712158203125 +72311 0.241729736328125 +72312 0.34912109375 +72313 0.457305908203125 +72314 0.54388427734375 +72315 0.5728759765625 +72316 0.506591796875 +72317 0.351226806640625 +72318 0.146514892578125 +72319 -0.05523681640625 +72320 -0.21624755859375 +72321 -0.334930419921875 +72322 -0.402984619140625 +72323 -0.4412841796875 +72324 -0.49578857421875 +72325 -0.5601806640625 +72326 -0.600738525390625 +72327 -0.584228515625 +72328 -0.47930908203125 +72329 -0.27935791015625 +72330 -0.0089111328125 +72331 0.268798828125 +72332 0.482818603515625 +72333 0.60369873046875 +72334 0.650421142578125 +72335 0.66400146484375 +72336 0.6414794921875 +72337 0.572540283203125 +72338 0.498138427734375 +72339 0.439453125 +72340 0.375518798828125 +72341 0.274505615234375 +72342 0.1087646484375 +72343 -0.099395751953125 +72344 -0.3182373046875 +72345 -0.5489501953125 +72346 -0.7738037109375 +72347 -0.86383056640625 +72348 -0.870391845703125 +72349 -0.86895751953125 +72350 -0.861053466796875 +72351 -0.765869140625 +72352 -0.5301513671875 +72353 -0.214691162109375 +72354 0.137359619140625 +72355 0.474822998046875 +72356 0.76239013671875 +72357 0.867462158203125 +72358 0.870361328125 +72359 0.86480712890625 +72360 0.831817626953125 +72361 0.677581787109375 +72362 0.495880126953125 +72363 0.30767822265625 +72364 0.116180419921875 +72365 -0.110748291015625 +72366 -0.381805419921875 +72367 -0.6572265625 +72368 -0.857421875 +72369 -0.870391845703125 +72370 -0.870391845703125 +72371 -0.86444091796875 +72372 -0.85723876953125 +72373 -0.790008544921875 +72374 -0.62847900390625 +72375 -0.3956298828125 +72376 -0.126708984375 +72377 0.150115966796875 +72378 0.424041748046875 +72379 0.670623779296875 +72380 0.854522705078125 +72381 0.866485595703125 +72382 0.86920166015625 +72383 0.8653564453125 +72384 0.857147216796875 +72385 0.766845703125 +72386 0.628509521484375 +72387 0.462127685546875 +72388 0.297210693359375 +72389 0.14862060546875 +72390 -0.00537109375 +72391 -0.15753173828125 +72392 -0.31304931640625 +72393 -0.48876953125 +72394 -0.6416015625 +72395 -0.751373291015625 +72396 -0.84619140625 +72397 -0.861297607421875 +72398 -0.863250732421875 +72399 -0.856597900390625 +72400 -0.7498779296875 +72401 -0.624542236328125 +72402 -0.47808837890625 +72403 -0.253387451171875 +72404 0.003692626953125 +72405 0.2257080078125 +72406 0.427154541015625 +72407 0.643218994140625 +72408 0.855926513671875 +72409 0.870361328125 +72410 0.870361328125 +72411 0.862762451171875 +72412 0.79669189453125 +72413 0.595794677734375 +72414 0.362152099609375 +72415 0.1270751953125 +72416 -0.086944580078125 +72417 -0.2784423828125 +72418 -0.484832763671875 +72419 -0.729583740234375 +72420 -0.86688232421875 +72421 -0.870391845703125 +72422 -0.86859130859375 +72423 -0.86279296875 +72424 -0.817962646484375 +72425 -0.6116943359375 +72426 -0.3128662109375 +72427 0.039398193359375 +72428 0.422821044921875 +72429 0.805145263671875 +72430 0.870361328125 +72431 0.870361328125 +72432 0.860015869140625 +72433 0.727935791015625 +72434 0.48114013671875 +72435 0.2059326171875 +72436 -0.06103515625 +72437 -0.29913330078125 +72438 -0.516204833984375 +72439 -0.7252197265625 +72440 -0.85980224609375 +72441 -0.870391845703125 +72442 -0.870391845703125 +72443 -0.858062744140625 +72444 -0.673004150390625 +72445 -0.42694091796875 +72446 -0.2100830078125 +72447 -0.0362548828125 +72448 0.10943603515625 +72449 0.23516845703125 +72450 0.373687744140625 +72451 0.517791748046875 +72452 0.602783203125 +72453 0.635711669921875 +72454 0.655181884765625 +72455 0.65948486328125 +72456 0.651275634765625 +72457 0.61846923828125 +72458 0.53753662109375 +72459 0.404144287109375 +72460 0.22186279296875 +72461 0.003997802734375 +72462 -0.22100830078125 +72463 -0.42449951171875 +72464 -0.579833984375 +72465 -0.641876220703125 +72466 -0.6177978515625 +72467 -0.575531005859375 +72468 -0.526336669921875 +72469 -0.42645263671875 +72470 -0.2581787109375 +72471 -0.068695068359375 +72472 0.09222412109375 +72473 0.232147216796875 +72474 0.3509521484375 +72475 0.410064697265625 +72476 0.372955322265625 +72477 0.2554931640625 +72478 0.10711669921875 +72479 -0.052886962890625 +72480 -0.186279296875 +72481 -0.23291015625 +72482 -0.209442138671875 +72483 -0.174163818359375 +72484 -0.126739501953125 +72485 -0.048126220703125 +72486 0.0426025390625 +72487 0.10748291015625 +72488 0.1409912109375 +72489 0.19708251953125 +72490 0.273651123046875 +72491 0.31768798828125 +72492 0.341094970703125 +72493 0.368011474609375 +72494 0.37249755859375 +72495 0.30072021484375 +72496 0.1517333984375 +72497 -0.01470947265625 +72498 -0.1883544921875 +72499 -0.372711181640625 +72500 -0.51397705078125 +72501 -0.57177734375 +72502 -0.53948974609375 +72503 -0.43511962890625 +72504 -0.2962646484375 +72505 -0.161102294921875 +72506 -0.0435791015625 +72507 0.060394287109375 +72508 0.13665771484375 +72509 0.170135498046875 +72510 0.16552734375 +72511 0.15728759765625 +72512 0.150787353515625 +72513 0.12200927734375 +72514 0.080108642578125 +72515 0.05126953125 +72516 0.062896728515625 +72517 0.09271240234375 +72518 0.092987060546875 +72519 0.07855224609375 +72520 0.06427001953125 +72521 0.0347900390625 +72522 -0.01171875 +72523 -0.056060791015625 +72524 -0.055511474609375 +72525 -0.010467529296875 +72526 0.02508544921875 +72527 0.025665283203125 +72528 0.017333984375 +72529 0.00189208984375 +72530 -0.03173828125 +72531 -0.071502685546875 +72532 -0.13543701171875 +72533 -0.219970703125 +72534 -0.300506591796875 +72535 -0.376312255859375 +72536 -0.416107177734375 +72537 -0.371124267578125 +72538 -0.242279052734375 +72539 -0.069732666015625 +72540 0.125640869140625 +72541 0.31268310546875 +72542 0.45501708984375 +72543 0.554779052734375 +72544 0.61065673828125 +72545 0.610931396484375 +72546 0.531463623046875 +72547 0.3883056640625 +72548 0.23468017578125 +72549 0.095245361328125 +72550 -0.00396728515625 +72551 -0.04852294921875 +72552 -0.055145263671875 +72553 -0.0758056640625 +72554 -0.138702392578125 +72555 -0.209197998046875 +72556 -0.289031982421875 +72557 -0.37884521484375 +72558 -0.456329345703125 +72559 -0.51641845703125 +72560 -0.519287109375 +72561 -0.458251953125 +72562 -0.384796142578125 +72563 -0.323699951171875 +72564 -0.269287109375 +72565 -0.1951904296875 +72566 -0.100006103515625 +72567 -0.01055908203125 +72568 0.1033935546875 +72569 0.24908447265625 +72570 0.373199462890625 +72571 0.45806884765625 +72572 0.511474609375 +72573 0.565399169921875 +72574 0.61138916015625 +72575 0.5897216796875 +72576 0.4906005859375 +72577 0.33148193359375 +72578 0.147796630859375 +72579 -0.01873779296875 +72580 -0.140289306640625 +72581 -0.191986083984375 +72582 -0.184295654296875 +72583 -0.161834716796875 +72584 -0.166595458984375 +72585 -0.19390869140625 +72586 -0.22442626953125 +72587 -0.279754638671875 +72588 -0.3389892578125 +72589 -0.3543701171875 +72590 -0.348175048828125 +72591 -0.32598876953125 +72592 -0.2581787109375 +72593 -0.139801025390625 +72594 0.014617919921875 +72595 0.144378662109375 +72596 0.221038818359375 +72597 0.27069091796875 +72598 0.294036865234375 +72599 0.311767578125 +72600 0.339141845703125 +72601 0.360260009765625 +72602 0.360504150390625 +72603 0.308380126953125 +72604 0.18170166015625 +72605 0.0047607421875 +72606 -0.17559814453125 +72607 -0.3143310546875 +72608 -0.36785888671875 +72609 -0.36248779296875 +72610 -0.343536376953125 +72611 -0.3018798828125 +72612 -0.231414794921875 +72613 -0.117645263671875 +72614 0.007049560546875 +72615 0.087982177734375 +72616 0.13946533203125 +72617 0.17425537109375 +72618 0.188201904296875 +72619 0.171234130859375 +72620 0.118438720703125 +72621 0.05706787109375 +72622 -0.010711669921875 +72623 -0.0914306640625 +72624 -0.162322998046875 +72625 -0.194549560546875 +72626 -0.1492919921875 +72627 -0.02166748046875 +72628 0.124053955078125 +72629 0.211151123046875 +72630 0.240447998046875 +72631 0.242218017578125 +72632 0.2257080078125 +72633 0.194366455078125 +72634 0.115509033203125 +72635 0.0128173828125 +72636 -0.053802490234375 +72637 -0.110626220703125 +72638 -0.199493408203125 +72639 -0.29437255859375 +72640 -0.33221435546875 +72641 -0.27972412109375 +72642 -0.185333251953125 +72643 -0.128204345703125 +72644 -0.115692138671875 +72645 -0.116455078125 +72646 -0.105926513671875 +72647 -0.053955078125 +72648 0.048797607421875 +72649 0.157318115234375 +72650 0.212005615234375 +72651 0.218475341796875 +72652 0.23724365234375 +72653 0.30535888671875 +72654 0.38128662109375 +72655 0.404449462890625 +72656 0.3944091796875 +72657 0.3885498046875 +72658 0.362640380859375 +72659 0.27362060546875 +72660 0.11712646484375 +72661 -0.054901123046875 +72662 -0.19085693359375 +72663 -0.28570556640625 +72664 -0.339263916015625 +72665 -0.3775634765625 +72666 -0.445709228515625 +72667 -0.535064697265625 +72668 -0.629058837890625 +72669 -0.697601318359375 +72670 -0.70391845703125 +72671 -0.6424560546875 +72672 -0.491241455078125 +72673 -0.265716552734375 +72674 -0.023712158203125 +72675 0.201751708984375 +72676 0.375823974609375 +72677 0.485076904296875 +72678 0.56884765625 +72679 0.634765625 +72680 0.63763427734375 +72681 0.5660400390625 +72682 0.4720458984375 +72683 0.40692138671875 +72684 0.3778076171875 +72685 0.376953125 +72686 0.371978759765625 +72687 0.313140869140625 +72688 0.184417724609375 +72689 0.011199951171875 +72690 -0.171051025390625 +72691 -0.33740234375 +72692 -0.47198486328125 +72693 -0.560394287109375 +72694 -0.58056640625 +72695 -0.54754638671875 +72696 -0.508575439453125 +72697 -0.459503173828125 +72698 -0.394378662109375 +72699 -0.35260009765625 +72700 -0.31170654296875 +72701 -0.197418212890625 +72702 -0.007965087890625 +72703 0.207489013671875 +72704 0.409210205078125 +72705 0.57208251953125 +72706 0.66595458984375 +72707 0.65875244140625 +72708 0.56744384765625 +72709 0.431396484375 +72710 0.29443359375 +72711 0.182464599609375 +72712 0.06365966796875 +72713 -0.075958251953125 +72714 -0.189422607421875 +72715 -0.271942138671875 +72716 -0.342529296875 +72717 -0.364166259765625 +72718 -0.327239990234375 +72719 -0.2769775390625 +72720 -0.253692626953125 +72721 -0.24365234375 +72722 -0.1983642578125 +72723 -0.116241455078125 +72724 -0.036834716796875 +72725 0.034881591796875 +72726 0.09124755859375 +72727 0.10888671875 +72728 0.125518798828125 +72729 0.15771484375 +72730 0.17828369140625 +72731 0.17108154296875 +72732 0.129974365234375 +72733 0.082427978515625 +72734 0.027679443359375 +72735 -0.065643310546875 +72736 -0.15936279296875 +72737 -0.21307373046875 +72738 -0.234649658203125 +72739 -0.2001953125 +72740 -0.119171142578125 +72741 -0.024749755859375 +72742 0.085784912109375 +72743 0.178131103515625 +72744 0.215576171875 +72745 0.211456298828125 +72746 0.17523193359375 +72747 0.128753662109375 +72748 0.1019287109375 +72749 0.0743408203125 +72750 0.04327392578125 +72751 0.038177490234375 +72752 0.076263427734375 +72753 0.14105224609375 +72754 0.186431884765625 +72755 0.188812255859375 +72756 0.1390380859375 +72757 0.041778564453125 +72758 -0.079437255859375 +72759 -0.219390869140625 +72760 -0.367828369140625 +72761 -0.494873046875 +72762 -0.556243896484375 +72763 -0.508697509765625 +72764 -0.3756103515625 +72765 -0.218902587890625 +72766 -0.063751220703125 +72767 0.091552734375 +72768 0.23602294921875 +72769 0.342987060546875 +72770 0.39520263671875 +72771 0.389373779296875 +72772 0.324249267578125 +72773 0.224090576171875 +72774 0.124267578125 +72775 0.037078857421875 +72776 -0.010101318359375 +72777 -0.019439697265625 +72778 -0.022796630859375 +72779 -0.001556396484375 +72780 0.056304931640625 +72781 0.106719970703125 +72782 0.096893310546875 +72783 0.042694091796875 +72784 -0.018035888671875 +72785 -0.07586669921875 +72786 -0.11944580078125 +72787 -0.15972900390625 +72788 -0.202606201171875 +72789 -0.24859619140625 +72790 -0.30517578125 +72791 -0.36212158203125 +72792 -0.39141845703125 +72793 -0.35528564453125 +72794 -0.249969482421875 +72795 -0.092864990234375 +72796 0.08905029296875 +72797 0.2352294921875 +72798 0.318817138671875 +72799 0.358642578125 +72800 0.347747802734375 +72801 0.28564453125 +72802 0.223175048828125 +72803 0.196746826171875 +72804 0.179840087890625 +72805 0.155548095703125 +72806 0.151214599609375 +72807 0.156951904296875 +72808 0.13177490234375 +72809 0.100799560546875 +72810 0.087127685546875 +72811 0.05487060546875 +72812 -0.009002685546875 +72813 -0.10400390625 +72814 -0.229400634765625 +72815 -0.35552978515625 +72816 -0.441925048828125 +72817 -0.473846435546875 +72818 -0.464813232421875 +72819 -0.419097900390625 +72820 -0.334320068359375 +72821 -0.227935791015625 +72822 -0.12347412109375 +72823 -0.02764892578125 +72824 0.077667236328125 +72825 0.2132568359375 +72826 0.38885498046875 +72827 0.582794189453125 +72828 0.734039306640625 +72829 0.800140380859375 +72830 0.7783203125 +72831 0.6651611328125 +72832 0.45965576171875 +72833 0.199188232421875 +72834 -0.050689697265625 +72835 -0.23297119140625 +72836 -0.33013916015625 +72837 -0.368408203125 +72838 -0.378936767578125 +72839 -0.376983642578125 +72840 -0.37969970703125 +72841 -0.391510009765625 +72842 -0.385345458984375 +72843 -0.3419189453125 +72844 -0.28289794921875 +72845 -0.251617431640625 +72846 -0.266143798828125 +72847 -0.273345947265625 +72848 -0.216796875 +72849 -0.128265380859375 +72850 -0.068145751953125 +72851 -0.0430908203125 +72852 -0.024444580078125 +72853 0.020721435546875 +72854 0.124481201171875 +72855 0.25787353515625 +72856 0.379119873046875 +72857 0.47991943359375 +72858 0.5281982421875 +72859 0.511138916015625 +72860 0.456207275390625 +72861 0.407470703125 +72862 0.383758544921875 +72863 0.35687255859375 +72864 0.31182861328125 +72865 0.250885009765625 +72866 0.1654052734375 +72867 0.035247802734375 +72868 -0.142059326171875 +72869 -0.33563232421875 +72870 -0.5345458984375 +72871 -0.72186279296875 +72872 -0.836669921875 +72873 -0.8326416015625 +72874 -0.7296142578125 +72875 -0.582550048828125 +72876 -0.440093994140625 +72877 -0.324310302734375 +72878 -0.20147705078125 +72879 -0.044647216796875 +72880 0.103973388671875 +72881 0.202392578125 +72882 0.264495849609375 +72883 0.338897705078125 +72884 0.443817138671875 +72885 0.545074462890625 +72886 0.6173095703125 +72887 0.6524658203125 +72888 0.66339111328125 +72889 0.6561279296875 +72890 0.606781005859375 +72891 0.501190185546875 +72892 0.352783203125 +72893 0.176544189453125 +72894 -0.034820556640625 +72895 -0.258209228515625 +72896 -0.44244384765625 +72897 -0.5753173828125 +72898 -0.65203857421875 +72899 -0.641632080078125 +72900 -0.562164306640625 +72901 -0.458038330078125 +72902 -0.350555419921875 +72903 -0.260528564453125 +72904 -0.192108154296875 +72905 -0.141937255859375 +72906 -0.1021728515625 +72907 -0.062896728515625 +72908 -0.011932373046875 +72909 0.062835693359375 +72910 0.148712158203125 +72911 0.241729736328125 +72912 0.34912109375 +72913 0.457305908203125 +72914 0.54388427734375 +72915 0.5728759765625 +72916 0.506591796875 +72917 0.351226806640625 +72918 0.146514892578125 +72919 -0.05523681640625 +72920 -0.21624755859375 +72921 -0.334930419921875 +72922 -0.402984619140625 +72923 -0.4412841796875 +72924 -0.49578857421875 +72925 -0.5601806640625 +72926 -0.600738525390625 +72927 -0.584228515625 +72928 -0.47930908203125 +72929 -0.27935791015625 +72930 -0.0089111328125 +72931 0.268798828125 +72932 0.482818603515625 +72933 0.60369873046875 +72934 0.650421142578125 +72935 0.66400146484375 +72936 0.6414794921875 +72937 0.572540283203125 +72938 0.498138427734375 +72939 0.439453125 +72940 0.375518798828125 +72941 0.274505615234375 +72942 0.1087646484375 +72943 -0.099395751953125 +72944 -0.3182373046875 +72945 -0.5489501953125 +72946 -0.7738037109375 +72947 -0.86383056640625 +72948 -0.870391845703125 +72949 -0.86895751953125 +72950 -0.861053466796875 +72951 -0.765869140625 +72952 -0.5301513671875 +72953 -0.214691162109375 +72954 0.137359619140625 +72955 0.474822998046875 +72956 0.76239013671875 +72957 0.867462158203125 +72958 0.870361328125 +72959 0.86480712890625 +72960 0.831817626953125 +72961 0.677581787109375 +72962 0.495880126953125 +72963 0.30767822265625 +72964 0.116180419921875 +72965 -0.110748291015625 +72966 -0.381805419921875 +72967 -0.6572265625 +72968 -0.857421875 +72969 -0.870391845703125 +72970 -0.870391845703125 +72971 -0.86444091796875 +72972 -0.85723876953125 +72973 -0.790008544921875 +72974 -0.62847900390625 +72975 -0.3956298828125 +72976 -0.126708984375 +72977 0.150115966796875 +72978 0.424041748046875 +72979 0.670623779296875 +72980 0.854522705078125 +72981 0.866485595703125 +72982 0.86920166015625 +72983 0.8653564453125 +72984 0.857147216796875 +72985 0.766845703125 +72986 0.628509521484375 +72987 0.462127685546875 +72988 0.297210693359375 +72989 0.14862060546875 +72990 -0.00537109375 +72991 -0.15753173828125 +72992 -0.31304931640625 +72993 -0.48876953125 +72994 -0.6416015625 +72995 -0.751373291015625 +72996 -0.84619140625 +72997 -0.861297607421875 +72998 -0.863250732421875 +72999 -0.856597900390625 +73000 -0.7498779296875 +73001 -0.624542236328125 +73002 -0.47808837890625 +73003 -0.253387451171875 +73004 0.003692626953125 +73005 0.2257080078125 +73006 0.427154541015625 +73007 0.643218994140625 +73008 0.855926513671875 +73009 0.870361328125 +73010 0.870361328125 +73011 0.862762451171875 +73012 0.79669189453125 +73013 0.595794677734375 +73014 0.362152099609375 +73015 0.1270751953125 +73016 -0.086944580078125 +73017 -0.2784423828125 +73018 -0.484832763671875 +73019 -0.729583740234375 +73020 -0.86688232421875 +73021 -0.870391845703125 +73022 -0.86859130859375 +73023 -0.86279296875 +73024 -0.817962646484375 +73025 -0.6116943359375 +73026 -0.3128662109375 +73027 0.039398193359375 +73028 0.422821044921875 +73029 0.805145263671875 +73030 0.870361328125 +73031 0.870361328125 +73032 0.860015869140625 +73033 0.727935791015625 +73034 0.48114013671875 +73035 0.2059326171875 +73036 -0.06103515625 +73037 -0.29913330078125 +73038 -0.516204833984375 +73039 -0.7252197265625 +73040 -0.85980224609375 +73041 -0.870391845703125 +73042 -0.870391845703125 +73043 -0.858062744140625 +73044 -0.673004150390625 +73045 -0.42694091796875 +73046 -0.2100830078125 +73047 -0.0362548828125 +73048 0.10943603515625 +73049 0.23516845703125 +73050 0.373687744140625 +73051 0.517791748046875 +73052 0.602783203125 +73053 0.635711669921875 +73054 0.655181884765625 +73055 0.65948486328125 +73056 0.651275634765625 +73057 0.61846923828125 +73058 0.53753662109375 +73059 0.404144287109375 +73060 0.22186279296875 +73061 0.003997802734375 +73062 -0.22100830078125 +73063 -0.42449951171875 +73064 -0.579833984375 +73065 -0.641876220703125 +73066 -0.6177978515625 +73067 -0.575531005859375 +73068 -0.526336669921875 +73069 -0.42645263671875 +73070 -0.2581787109375 +73071 -0.068695068359375 +73072 0.09222412109375 +73073 0.232147216796875 +73074 0.3509521484375 +73075 0.410064697265625 +73076 0.372955322265625 +73077 0.2554931640625 +73078 0.10711669921875 +73079 -0.052886962890625 +73080 -0.186279296875 +73081 -0.23291015625 +73082 -0.209442138671875 +73083 -0.174163818359375 +73084 -0.126739501953125 +73085 -0.048126220703125 +73086 0.0426025390625 +73087 0.10748291015625 +73088 0.1409912109375 +73089 0.19708251953125 +73090 0.273651123046875 +73091 0.31768798828125 +73092 0.341094970703125 +73093 0.368011474609375 +73094 0.37249755859375 +73095 0.30072021484375 +73096 0.1517333984375 +73097 -0.01470947265625 +73098 -0.1883544921875 +73099 -0.372711181640625 +73100 -0.51397705078125 +73101 -0.57177734375 +73102 -0.53948974609375 +73103 -0.43511962890625 +73104 -0.2962646484375 +73105 -0.161102294921875 +73106 -0.0435791015625 +73107 0.060394287109375 +73108 0.13665771484375 +73109 0.170135498046875 +73110 0.16552734375 +73111 0.15728759765625 +73112 0.150787353515625 +73113 0.12200927734375 +73114 0.080108642578125 +73115 0.05126953125 +73116 0.062896728515625 +73117 0.09271240234375 +73118 0.092987060546875 +73119 0.07855224609375 +73120 0.06427001953125 +73121 0.0347900390625 +73122 -0.01171875 +73123 -0.056060791015625 +73124 -0.055511474609375 +73125 -0.010467529296875 +73126 0.02508544921875 +73127 0.025665283203125 +73128 0.017333984375 +73129 0.00189208984375 +73130 -0.03173828125 +73131 -0.071502685546875 +73132 -0.13543701171875 +73133 -0.219970703125 +73134 -0.300506591796875 +73135 -0.376312255859375 +73136 -0.416107177734375 +73137 -0.371124267578125 +73138 -0.242279052734375 +73139 -0.069732666015625 +73140 0.125640869140625 +73141 0.31268310546875 +73142 0.45501708984375 +73143 0.554779052734375 +73144 0.61065673828125 +73145 0.610931396484375 +73146 0.531463623046875 +73147 0.3883056640625 +73148 0.23468017578125 +73149 0.095245361328125 +73150 -0.00396728515625 +73151 -0.04852294921875 +73152 -0.055145263671875 +73153 -0.0758056640625 +73154 -0.138702392578125 +73155 -0.209197998046875 +73156 -0.289031982421875 +73157 -0.37884521484375 +73158 -0.456329345703125 +73159 -0.51641845703125 +73160 -0.519287109375 +73161 -0.458251953125 +73162 -0.384796142578125 +73163 -0.323699951171875 +73164 -0.269287109375 +73165 -0.1951904296875 +73166 -0.100006103515625 +73167 -0.01055908203125 +73168 0.1033935546875 +73169 0.24908447265625 +73170 0.373199462890625 +73171 0.45806884765625 +73172 0.511474609375 +73173 0.565399169921875 +73174 0.61138916015625 +73175 0.5897216796875 +73176 0.4906005859375 +73177 0.33148193359375 +73178 0.147796630859375 +73179 -0.01873779296875 +73180 -0.140289306640625 +73181 -0.191986083984375 +73182 -0.184295654296875 +73183 -0.161834716796875 +73184 -0.166595458984375 +73185 -0.19390869140625 +73186 -0.22442626953125 +73187 -0.279754638671875 +73188 -0.3389892578125 +73189 -0.3543701171875 +73190 -0.348175048828125 +73191 -0.32598876953125 +73192 -0.2581787109375 +73193 -0.139801025390625 +73194 0.014617919921875 +73195 0.144378662109375 +73196 0.221038818359375 +73197 0.27069091796875 +73198 0.294036865234375 +73199 0.311767578125 +73200 0.339141845703125 +73201 0.360260009765625 +73202 0.360504150390625 +73203 0.308380126953125 +73204 0.18170166015625 +73205 0.0047607421875 +73206 -0.17559814453125 +73207 -0.3143310546875 +73208 -0.36785888671875 +73209 -0.36248779296875 +73210 -0.343536376953125 +73211 -0.3018798828125 +73212 -0.231414794921875 +73213 -0.117645263671875 +73214 0.007049560546875 +73215 0.087982177734375 +73216 0.13946533203125 +73217 0.17425537109375 +73218 0.188201904296875 +73219 0.171234130859375 +73220 0.118438720703125 +73221 0.05706787109375 +73222 -0.010711669921875 +73223 -0.0914306640625 +73224 -0.162322998046875 +73225 -0.194549560546875 +73226 -0.1492919921875 +73227 -0.02166748046875 +73228 0.124053955078125 +73229 0.211151123046875 +73230 0.240447998046875 +73231 0.242218017578125 +73232 0.2257080078125 +73233 0.194366455078125 +73234 0.115509033203125 +73235 0.0128173828125 +73236 -0.053802490234375 +73237 -0.110626220703125 +73238 -0.199493408203125 +73239 -0.29437255859375 +73240 -0.33221435546875 +73241 -0.27972412109375 +73242 -0.185333251953125 +73243 -0.128204345703125 +73244 -0.115692138671875 +73245 -0.116455078125 +73246 -0.105926513671875 +73247 -0.053955078125 +73248 0.048797607421875 +73249 0.157318115234375 +73250 0.212005615234375 +73251 0.218475341796875 +73252 0.23724365234375 +73253 0.30535888671875 +73254 0.38128662109375 +73255 0.404449462890625 +73256 0.3944091796875 +73257 0.3885498046875 +73258 0.362640380859375 +73259 0.27362060546875 +73260 0.11712646484375 +73261 -0.054901123046875 +73262 -0.19085693359375 +73263 -0.28570556640625 +73264 -0.339263916015625 +73265 -0.3775634765625 +73266 -0.445709228515625 +73267 -0.535064697265625 +73268 -0.629058837890625 +73269 -0.697601318359375 +73270 -0.70391845703125 +73271 -0.6424560546875 +73272 -0.491241455078125 +73273 -0.265716552734375 +73274 -0.023712158203125 +73275 0.201751708984375 +73276 0.375823974609375 +73277 0.485076904296875 +73278 0.56884765625 +73279 0.634765625 +73280 0.63763427734375 +73281 0.5660400390625 +73282 0.4720458984375 +73283 0.40692138671875 +73284 0.3778076171875 +73285 0.376953125 +73286 0.371978759765625 +73287 0.313140869140625 +73288 0.184417724609375 +73289 0.011199951171875 +73290 -0.171051025390625 +73291 -0.33740234375 +73292 -0.47198486328125 +73293 -0.560394287109375 +73294 -0.58056640625 +73295 -0.54754638671875 +73296 -0.508575439453125 +73297 -0.459503173828125 +73298 -0.394378662109375 +73299 -0.35260009765625 +73300 -0.31170654296875 +73301 -0.197418212890625 +73302 -0.007965087890625 +73303 0.207489013671875 +73304 0.409210205078125 +73305 0.57208251953125 +73306 0.66595458984375 +73307 0.65875244140625 +73308 0.56744384765625 +73309 0.431396484375 +73310 0.29443359375 +73311 0.182464599609375 +73312 0.06365966796875 +73313 -0.075958251953125 +73314 -0.189422607421875 +73315 -0.271942138671875 +73316 -0.342529296875 +73317 -0.364166259765625 +73318 -0.327239990234375 +73319 -0.2769775390625 +73320 -0.253692626953125 +73321 -0.24365234375 +73322 -0.1983642578125 +73323 -0.116241455078125 +73324 -0.036834716796875 +73325 0.034881591796875 +73326 0.09124755859375 +73327 0.10888671875 +73328 0.125518798828125 +73329 0.15771484375 +73330 0.17828369140625 +73331 0.17108154296875 +73332 0.129974365234375 +73333 0.082427978515625 +73334 0.027679443359375 +73335 -0.065643310546875 +73336 -0.15936279296875 +73337 -0.21307373046875 +73338 -0.234649658203125 +73339 -0.2001953125 +73340 -0.119171142578125 +73341 -0.024749755859375 +73342 0.085784912109375 +73343 0.178131103515625 +73344 0.215576171875 +73345 0.211456298828125 +73346 0.17523193359375 +73347 0.128753662109375 +73348 0.1019287109375 +73349 0.0743408203125 +73350 0.04327392578125 +73351 0.038177490234375 +73352 0.076263427734375 +73353 0.14105224609375 +73354 0.186431884765625 +73355 0.188812255859375 +73356 0.1390380859375 +73357 0.041778564453125 +73358 -0.079437255859375 +73359 -0.219390869140625 +73360 -0.367828369140625 +73361 -0.494873046875 +73362 -0.556243896484375 +73363 -0.508697509765625 +73364 -0.3756103515625 +73365 -0.218902587890625 +73366 -0.063751220703125 +73367 0.091552734375 +73368 0.23602294921875 +73369 0.342987060546875 +73370 0.39520263671875 +73371 0.389373779296875 +73372 0.324249267578125 +73373 0.224090576171875 +73374 0.124267578125 +73375 0.037078857421875 +73376 -0.010101318359375 +73377 -0.019439697265625 +73378 -0.022796630859375 +73379 -0.001556396484375 +73380 0.056304931640625 +73381 0.106719970703125 +73382 0.096893310546875 +73383 0.042694091796875 +73384 -0.018035888671875 +73385 -0.07586669921875 +73386 -0.11944580078125 +73387 -0.15972900390625 +73388 -0.202606201171875 +73389 -0.24859619140625 +73390 -0.30517578125 +73391 -0.36212158203125 +73392 -0.39141845703125 +73393 -0.35528564453125 +73394 -0.249969482421875 +73395 -0.092864990234375 +73396 0.08905029296875 +73397 0.2352294921875 +73398 0.318817138671875 +73399 0.358642578125 +73400 0.347747802734375 +73401 0.28564453125 +73402 0.223175048828125 +73403 0.196746826171875 +73404 0.179840087890625 +73405 0.155548095703125 +73406 0.151214599609375 +73407 0.156951904296875 +73408 0.13177490234375 +73409 0.100799560546875 +73410 0.087127685546875 +73411 0.05487060546875 +73412 -0.009002685546875 +73413 -0.10400390625 +73414 -0.229400634765625 +73415 -0.35552978515625 +73416 -0.441925048828125 +73417 -0.473846435546875 +73418 -0.464813232421875 +73419 -0.419097900390625 +73420 -0.334320068359375 +73421 -0.227935791015625 +73422 -0.12347412109375 +73423 -0.02764892578125 +73424 0.077667236328125 +73425 0.2132568359375 +73426 0.38885498046875 +73427 0.582794189453125 +73428 0.734039306640625 +73429 0.800140380859375 +73430 0.7783203125 +73431 0.6651611328125 +73432 0.45965576171875 +73433 0.199188232421875 +73434 -0.050689697265625 +73435 -0.23297119140625 +73436 -0.33013916015625 +73437 -0.368408203125 +73438 -0.378936767578125 +73439 -0.376983642578125 +73440 -0.37969970703125 +73441 -0.391510009765625 +73442 -0.385345458984375 +73443 -0.3419189453125 +73444 -0.28289794921875 +73445 -0.251617431640625 +73446 -0.266143798828125 +73447 -0.273345947265625 +73448 -0.216796875 +73449 -0.128265380859375 +73450 -0.068145751953125 +73451 -0.0430908203125 +73452 -0.024444580078125 +73453 0.020721435546875 +73454 0.124481201171875 +73455 0.25787353515625 +73456 0.379119873046875 +73457 0.47991943359375 +73458 0.5281982421875 +73459 0.511138916015625 +73460 0.456207275390625 +73461 0.407470703125 +73462 0.383758544921875 +73463 0.35687255859375 +73464 0.31182861328125 +73465 0.250885009765625 +73466 0.1654052734375 +73467 0.035247802734375 +73468 -0.142059326171875 +73469 -0.33563232421875 +73470 -0.5345458984375 +73471 -0.72186279296875 +73472 -0.836669921875 +73473 -0.8326416015625 +73474 -0.7296142578125 +73475 -0.582550048828125 +73476 -0.440093994140625 +73477 -0.324310302734375 +73478 -0.20147705078125 +73479 -0.044647216796875 +73480 0.103973388671875 +73481 0.202392578125 +73482 0.264495849609375 +73483 0.338897705078125 +73484 0.443817138671875 +73485 0.545074462890625 +73486 0.6173095703125 +73487 0.6524658203125 +73488 0.66339111328125 +73489 0.6561279296875 +73490 0.606781005859375 +73491 0.501190185546875 +73492 0.352783203125 +73493 0.176544189453125 +73494 -0.034820556640625 +73495 -0.258209228515625 +73496 -0.44244384765625 +73497 -0.5753173828125 +73498 -0.65203857421875 +73499 -0.641632080078125 +73500 -0.562164306640625 +73501 -0.458038330078125 +73502 -0.350555419921875 +73503 -0.260528564453125 +73504 -0.192108154296875 +73505 -0.141937255859375 +73506 -0.1021728515625 +73507 -0.062896728515625 +73508 -0.011932373046875 +73509 0.062835693359375 +73510 0.148712158203125 +73511 0.241729736328125 +73512 0.34912109375 +73513 0.457305908203125 +73514 0.54388427734375 +73515 0.5728759765625 +73516 0.506591796875 +73517 0.351226806640625 +73518 0.146514892578125 +73519 -0.05523681640625 +73520 -0.21624755859375 +73521 -0.334930419921875 +73522 -0.402984619140625 +73523 -0.4412841796875 +73524 -0.49578857421875 +73525 -0.5601806640625 +73526 -0.600738525390625 +73527 -0.584228515625 +73528 -0.47930908203125 +73529 -0.27935791015625 +73530 -0.0089111328125 +73531 0.268798828125 +73532 0.482818603515625 +73533 0.60369873046875 +73534 0.650421142578125 +73535 0.66400146484375 +73536 0.6414794921875 +73537 0.572540283203125 +73538 0.498138427734375 +73539 0.439453125 +73540 0.375518798828125 +73541 0.274505615234375 +73542 0.1087646484375 +73543 -0.099395751953125 +73544 -0.3182373046875 +73545 -0.5489501953125 +73546 -0.7738037109375 +73547 -0.86383056640625 +73548 -0.870391845703125 +73549 -0.86895751953125 +73550 -0.861053466796875 +73551 -0.765869140625 +73552 -0.5301513671875 +73553 -0.214691162109375 +73554 0.137359619140625 +73555 0.474822998046875 +73556 0.76239013671875 +73557 0.867462158203125 +73558 0.870361328125 +73559 0.86480712890625 +73560 0.831817626953125 +73561 0.677581787109375 +73562 0.495880126953125 +73563 0.30767822265625 +73564 0.116180419921875 +73565 -0.110748291015625 +73566 -0.381805419921875 +73567 -0.6572265625 +73568 -0.857421875 +73569 -0.870391845703125 +73570 -0.870391845703125 +73571 -0.86444091796875 +73572 -0.85723876953125 +73573 -0.790008544921875 +73574 -0.62847900390625 +73575 -0.3956298828125 +73576 -0.126708984375 +73577 0.150115966796875 +73578 0.424041748046875 +73579 0.670623779296875 +73580 0.854522705078125 +73581 0.866485595703125 +73582 0.86920166015625 +73583 0.8653564453125 +73584 0.857147216796875 +73585 0.766845703125 +73586 0.628509521484375 +73587 0.462127685546875 +73588 0.297210693359375 +73589 0.14862060546875 +73590 -0.00537109375 +73591 -0.15753173828125 +73592 -0.31304931640625 +73593 -0.48876953125 +73594 -0.6416015625 +73595 -0.751373291015625 +73596 -0.84619140625 +73597 -0.861297607421875 +73598 -0.863250732421875 +73599 -0.856597900390625 +73600 -0.7498779296875 +73601 -0.624542236328125 +73602 -0.47808837890625 +73603 -0.253387451171875 +73604 0.003692626953125 +73605 0.2257080078125 +73606 0.427154541015625 +73607 0.643218994140625 +73608 0.855926513671875 +73609 0.870361328125 +73610 0.870361328125 +73611 0.862762451171875 +73612 0.79669189453125 +73613 0.595794677734375 +73614 0.362152099609375 +73615 0.1270751953125 +73616 -0.086944580078125 +73617 -0.2784423828125 +73618 -0.484832763671875 +73619 -0.729583740234375 +73620 -0.86688232421875 +73621 -0.870391845703125 +73622 -0.86859130859375 +73623 -0.86279296875 +73624 -0.817962646484375 +73625 -0.6116943359375 +73626 -0.3128662109375 +73627 0.039398193359375 +73628 0.422821044921875 +73629 0.805145263671875 +73630 0.870361328125 +73631 0.870361328125 +73632 0.860015869140625 +73633 0.727935791015625 +73634 0.48114013671875 +73635 0.2059326171875 +73636 -0.06103515625 +73637 -0.29913330078125 +73638 -0.516204833984375 +73639 -0.7252197265625 +73640 -0.85980224609375 +73641 -0.870391845703125 +73642 -0.870391845703125 +73643 -0.858062744140625 +73644 -0.673004150390625 +73645 -0.42694091796875 +73646 -0.2100830078125 +73647 -0.0362548828125 +73648 0.10943603515625 +73649 0.23516845703125 +73650 0.373687744140625 +73651 0.517791748046875 +73652 0.602783203125 +73653 0.635711669921875 +73654 0.655181884765625 +73655 0.65948486328125 +73656 0.651275634765625 +73657 0.61846923828125 +73658 0.53753662109375 +73659 0.404144287109375 +73660 0.22186279296875 +73661 0.003997802734375 +73662 -0.22100830078125 +73663 -0.42449951171875 +73664 -0.579833984375 +73665 -0.641876220703125 +73666 -0.6177978515625 +73667 -0.575531005859375 +73668 -0.526336669921875 +73669 -0.42645263671875 +73670 -0.2581787109375 +73671 -0.068695068359375 +73672 0.09222412109375 +73673 0.232147216796875 +73674 0.3509521484375 +73675 0.410064697265625 +73676 0.372955322265625 +73677 0.2554931640625 +73678 0.10711669921875 +73679 -0.052886962890625 +73680 -0.186279296875 +73681 -0.23291015625 +73682 -0.209442138671875 +73683 -0.174163818359375 +73684 -0.126739501953125 +73685 -0.048126220703125 +73686 0.0426025390625 +73687 0.10748291015625 +73688 0.1409912109375 +73689 0.19708251953125 +73690 0.273651123046875 +73691 0.31768798828125 +73692 0.341094970703125 +73693 0.368011474609375 +73694 0.37249755859375 +73695 0.30072021484375 +73696 0.1517333984375 +73697 -0.01470947265625 +73698 -0.1883544921875 +73699 -0.372711181640625 +73700 -0.51397705078125 +73701 -0.57177734375 +73702 -0.53948974609375 +73703 -0.43511962890625 +73704 -0.2962646484375 +73705 -0.161102294921875 +73706 -0.0435791015625 +73707 0.060394287109375 +73708 0.13665771484375 +73709 0.170135498046875 +73710 0.16552734375 +73711 0.15728759765625 +73712 0.150787353515625 +73713 0.12200927734375 +73714 0.080108642578125 +73715 0.05126953125 +73716 0.062896728515625 +73717 0.09271240234375 +73718 0.092987060546875 +73719 0.07855224609375 +73720 0.06427001953125 +73721 0.0347900390625 +73722 -0.01171875 +73723 -0.056060791015625 +73724 -0.055511474609375 +73725 -0.010467529296875 +73726 0.02508544921875 +73727 0.025665283203125 +73728 0.017333984375 +73729 0.00189208984375 +73730 -0.03173828125 +73731 -0.071502685546875 +73732 -0.13543701171875 +73733 -0.219970703125 +73734 -0.300506591796875 +73735 -0.376312255859375 +73736 -0.416107177734375 +73737 -0.371124267578125 +73738 -0.242279052734375 +73739 -0.069732666015625 +73740 0.125640869140625 +73741 0.31268310546875 +73742 0.45501708984375 +73743 0.554779052734375 +73744 0.61065673828125 +73745 0.610931396484375 +73746 0.531463623046875 +73747 0.3883056640625 +73748 0.23468017578125 +73749 0.095245361328125 +73750 -0.00396728515625 +73751 -0.04852294921875 +73752 -0.055145263671875 +73753 -0.0758056640625 +73754 -0.138702392578125 +73755 -0.209197998046875 +73756 -0.289031982421875 +73757 -0.37884521484375 +73758 -0.456329345703125 +73759 -0.51641845703125 +73760 -0.519287109375 +73761 -0.458251953125 +73762 -0.384796142578125 +73763 -0.323699951171875 +73764 -0.269287109375 +73765 -0.1951904296875 +73766 -0.100006103515625 +73767 -0.01055908203125 +73768 0.1033935546875 +73769 0.24908447265625 +73770 0.373199462890625 +73771 0.45806884765625 +73772 0.511474609375 +73773 0.565399169921875 +73774 0.61138916015625 +73775 0.5897216796875 +73776 0.4906005859375 +73777 0.33148193359375 +73778 0.147796630859375 +73779 -0.01873779296875 +73780 -0.140289306640625 +73781 -0.191986083984375 +73782 -0.184295654296875 +73783 -0.161834716796875 +73784 -0.166595458984375 +73785 -0.19390869140625 +73786 -0.22442626953125 +73787 -0.279754638671875 +73788 -0.3389892578125 +73789 -0.3543701171875 +73790 -0.348175048828125 +73791 -0.32598876953125 +73792 -0.2581787109375 +73793 -0.139801025390625 +73794 0.014617919921875 +73795 0.144378662109375 +73796 0.221038818359375 +73797 0.27069091796875 +73798 0.294036865234375 +73799 0.311767578125 +73800 0.339141845703125 +73801 0.360260009765625 +73802 0.360504150390625 +73803 0.308380126953125 +73804 0.18170166015625 +73805 0.0047607421875 +73806 -0.17559814453125 +73807 -0.3143310546875 +73808 -0.36785888671875 +73809 -0.36248779296875 +73810 -0.343536376953125 +73811 -0.3018798828125 +73812 -0.231414794921875 +73813 -0.117645263671875 +73814 0.007049560546875 +73815 0.087982177734375 +73816 0.13946533203125 +73817 0.17425537109375 +73818 0.188201904296875 +73819 0.171234130859375 +73820 0.118438720703125 +73821 0.05706787109375 +73822 -0.010711669921875 +73823 -0.0914306640625 +73824 -0.162322998046875 +73825 -0.194549560546875 +73826 -0.1492919921875 +73827 -0.02166748046875 +73828 0.124053955078125 +73829 0.211151123046875 +73830 0.240447998046875 +73831 0.242218017578125 +73832 0.2257080078125 +73833 0.194366455078125 +73834 0.115509033203125 +73835 0.0128173828125 +73836 -0.053802490234375 +73837 -0.110626220703125 +73838 -0.199493408203125 +73839 -0.29437255859375 +73840 -0.33221435546875 +73841 -0.27972412109375 +73842 -0.185333251953125 +73843 -0.128204345703125 +73844 -0.115692138671875 +73845 -0.116455078125 +73846 -0.105926513671875 +73847 -0.053955078125 +73848 0.048797607421875 +73849 0.157318115234375 +73850 0.212005615234375 +73851 0.218475341796875 +73852 0.23724365234375 +73853 0.30535888671875 +73854 0.38128662109375 +73855 0.404449462890625 +73856 0.3944091796875 +73857 0.3885498046875 +73858 0.362640380859375 +73859 0.27362060546875 +73860 0.11712646484375 +73861 -0.054901123046875 +73862 -0.19085693359375 +73863 -0.28570556640625 +73864 -0.339263916015625 +73865 -0.3775634765625 +73866 -0.445709228515625 +73867 -0.535064697265625 +73868 -0.629058837890625 +73869 -0.697601318359375 +73870 -0.70391845703125 +73871 -0.6424560546875 +73872 -0.491241455078125 +73873 -0.265716552734375 +73874 -0.023712158203125 +73875 0.201751708984375 +73876 0.375823974609375 +73877 0.485076904296875 +73878 0.56884765625 +73879 0.634765625 +73880 0.63763427734375 +73881 0.5660400390625 +73882 0.4720458984375 +73883 0.40692138671875 +73884 0.3778076171875 +73885 0.376953125 +73886 0.371978759765625 +73887 0.313140869140625 +73888 0.184417724609375 +73889 0.011199951171875 +73890 -0.171051025390625 +73891 -0.33740234375 +73892 -0.47198486328125 +73893 -0.560394287109375 +73894 -0.58056640625 +73895 -0.54754638671875 +73896 -0.508575439453125 +73897 -0.459503173828125 +73898 -0.394378662109375 +73899 -0.35260009765625 +73900 -0.31170654296875 +73901 -0.197418212890625 +73902 -0.007965087890625 +73903 0.207489013671875 +73904 0.409210205078125 +73905 0.57208251953125 +73906 0.66595458984375 +73907 0.65875244140625 +73908 0.56744384765625 +73909 0.431396484375 +73910 0.29443359375 +73911 0.182464599609375 +73912 0.06365966796875 +73913 -0.075958251953125 +73914 -0.189422607421875 +73915 -0.271942138671875 +73916 -0.342529296875 +73917 -0.364166259765625 +73918 -0.327239990234375 +73919 -0.2769775390625 +73920 -0.253692626953125 +73921 -0.24365234375 +73922 -0.1983642578125 +73923 -0.116241455078125 +73924 -0.036834716796875 +73925 0.034881591796875 +73926 0.09124755859375 +73927 0.10888671875 +73928 0.125518798828125 +73929 0.15771484375 +73930 0.17828369140625 +73931 0.17108154296875 +73932 0.129974365234375 +73933 0.082427978515625 +73934 0.027679443359375 +73935 -0.065643310546875 +73936 -0.15936279296875 +73937 -0.21307373046875 +73938 -0.234649658203125 +73939 -0.2001953125 +73940 -0.119171142578125 +73941 -0.024749755859375 +73942 0.085784912109375 +73943 0.178131103515625 +73944 0.215576171875 +73945 0.211456298828125 +73946 0.17523193359375 +73947 0.128753662109375 +73948 0.1019287109375 +73949 0.0743408203125 +73950 0.04327392578125 +73951 0.038177490234375 +73952 0.076263427734375 +73953 0.14105224609375 +73954 0.186431884765625 +73955 0.188812255859375 +73956 0.1390380859375 +73957 0.041778564453125 +73958 -0.079437255859375 +73959 -0.219390869140625 +73960 -0.367828369140625 +73961 -0.494873046875 +73962 -0.556243896484375 +73963 -0.508697509765625 +73964 -0.3756103515625 +73965 -0.218902587890625 +73966 -0.063751220703125 +73967 0.091552734375 +73968 0.23602294921875 +73969 0.342987060546875 +73970 0.39520263671875 +73971 0.389373779296875 +73972 0.324249267578125 +73973 0.224090576171875 +73974 0.124267578125 +73975 0.037078857421875 +73976 -0.010101318359375 +73977 -0.019439697265625 +73978 -0.022796630859375 +73979 -0.001556396484375 +73980 0.056304931640625 +73981 0.106719970703125 +73982 0.096893310546875 +73983 0.042694091796875 +73984 -0.018035888671875 +73985 -0.07586669921875 +73986 -0.11944580078125 +73987 -0.15972900390625 +73988 -0.202606201171875 +73989 -0.24859619140625 +73990 -0.30517578125 +73991 -0.36212158203125 +73992 -0.39141845703125 +73993 -0.35528564453125 +73994 -0.249969482421875 +73995 -0.092864990234375 +73996 0.08905029296875 +73997 0.2352294921875 +73998 0.318817138671875 +73999 0.358642578125 +74000 0.347747802734375 +74001 0.28564453125 +74002 0.223175048828125 +74003 0.196746826171875 +74004 0.179840087890625 +74005 0.155548095703125 +74006 0.151214599609375 +74007 0.156951904296875 +74008 0.13177490234375 +74009 0.100799560546875 +74010 0.087127685546875 +74011 0.05487060546875 +74012 -0.009002685546875 +74013 -0.10400390625 +74014 -0.229400634765625 +74015 -0.35552978515625 +74016 -0.441925048828125 +74017 -0.473846435546875 +74018 -0.464813232421875 +74019 -0.419097900390625 +74020 -0.334320068359375 +74021 -0.227935791015625 +74022 -0.12347412109375 +74023 -0.02764892578125 +74024 0.077667236328125 +74025 0.2132568359375 +74026 0.38885498046875 +74027 0.582794189453125 +74028 0.734039306640625 +74029 0.800140380859375 +74030 0.7783203125 +74031 0.6651611328125 +74032 0.45965576171875 +74033 0.199188232421875 +74034 -0.050689697265625 +74035 -0.23297119140625 +74036 -0.33013916015625 +74037 -0.368408203125 +74038 -0.378936767578125 +74039 -0.376983642578125 +74040 -0.37969970703125 +74041 -0.391510009765625 +74042 -0.385345458984375 +74043 -0.3419189453125 +74044 -0.28289794921875 +74045 -0.251617431640625 +74046 -0.266143798828125 +74047 -0.273345947265625 +74048 -0.216796875 +74049 -0.128265380859375 +74050 -0.068145751953125 +74051 -0.0430908203125 +74052 -0.024444580078125 +74053 0.020721435546875 +74054 0.124481201171875 +74055 0.25787353515625 +74056 0.379119873046875 +74057 0.47991943359375 +74058 0.5281982421875 +74059 0.511138916015625 +74060 0.456207275390625 +74061 0.407470703125 +74062 0.383758544921875 +74063 0.35687255859375 +74064 0.31182861328125 +74065 0.250885009765625 +74066 0.1654052734375 +74067 0.035247802734375 +74068 -0.142059326171875 +74069 -0.33563232421875 +74070 -0.5345458984375 +74071 -0.72186279296875 +74072 -0.836669921875 +74073 -0.8326416015625 +74074 -0.7296142578125 +74075 -0.582550048828125 +74076 -0.440093994140625 +74077 -0.324310302734375 +74078 -0.20147705078125 +74079 -0.044647216796875 +74080 0.103973388671875 +74081 0.202392578125 +74082 0.264495849609375 +74083 0.338897705078125 +74084 0.443817138671875 +74085 0.545074462890625 +74086 0.6173095703125 +74087 0.6524658203125 +74088 0.66339111328125 +74089 0.6561279296875 +74090 0.606781005859375 +74091 0.501190185546875 +74092 0.352783203125 +74093 0.176544189453125 +74094 -0.034820556640625 +74095 -0.258209228515625 +74096 -0.44244384765625 +74097 -0.5753173828125 +74098 -0.65203857421875 +74099 -0.641632080078125 +74100 -0.562164306640625 +74101 -0.458038330078125 +74102 -0.350555419921875 +74103 -0.260528564453125 +74104 -0.192108154296875 +74105 -0.141937255859375 +74106 -0.1021728515625 +74107 -0.062896728515625 +74108 -0.011932373046875 +74109 0.062835693359375 +74110 0.148712158203125 +74111 0.241729736328125 +74112 0.34912109375 +74113 0.457305908203125 +74114 0.54388427734375 +74115 0.5728759765625 +74116 0.506591796875 +74117 0.351226806640625 +74118 0.146514892578125 +74119 -0.05523681640625 +74120 -0.21624755859375 +74121 -0.334930419921875 +74122 -0.402984619140625 +74123 -0.4412841796875 +74124 -0.49578857421875 +74125 -0.5601806640625 +74126 -0.600738525390625 +74127 -0.584228515625 +74128 -0.47930908203125 +74129 -0.27935791015625 +74130 -0.0089111328125 +74131 0.268798828125 +74132 0.482818603515625 +74133 0.60369873046875 +74134 0.650421142578125 +74135 0.66400146484375 +74136 0.6414794921875 +74137 0.572540283203125 +74138 0.498138427734375 +74139 0.439453125 +74140 0.375518798828125 +74141 0.274505615234375 +74142 0.1087646484375 +74143 -0.099395751953125 +74144 -0.3182373046875 +74145 -0.5489501953125 +74146 -0.7738037109375 +74147 -0.86383056640625 +74148 -0.870391845703125 +74149 -0.86895751953125 +74150 -0.861053466796875 +74151 -0.765869140625 +74152 -0.5301513671875 +74153 -0.214691162109375 +74154 0.137359619140625 +74155 0.474822998046875 +74156 0.76239013671875 +74157 0.867462158203125 +74158 0.870361328125 +74159 0.86480712890625 +74160 0.831817626953125 +74161 0.677581787109375 +74162 0.495880126953125 +74163 0.30767822265625 +74164 0.116180419921875 +74165 -0.110748291015625 +74166 -0.381805419921875 +74167 -0.6572265625 +74168 -0.857421875 +74169 -0.870391845703125 +74170 -0.870391845703125 +74171 -0.86444091796875 +74172 -0.85723876953125 +74173 -0.790008544921875 +74174 -0.62847900390625 +74175 -0.3956298828125 +74176 -0.126708984375 +74177 0.150115966796875 +74178 0.424041748046875 +74179 0.670623779296875 +74180 0.854522705078125 +74181 0.866485595703125 +74182 0.86920166015625 +74183 0.8653564453125 +74184 0.857147216796875 +74185 0.766845703125 +74186 0.628509521484375 +74187 0.462127685546875 +74188 0.297210693359375 +74189 0.14862060546875 +74190 -0.00537109375 +74191 -0.15753173828125 +74192 -0.31304931640625 +74193 -0.48876953125 +74194 -0.6416015625 +74195 -0.751373291015625 +74196 -0.84619140625 +74197 -0.861297607421875 +74198 -0.863250732421875 +74199 -0.856597900390625 +74200 -0.7498779296875 +74201 -0.624542236328125 +74202 -0.47808837890625 +74203 -0.253387451171875 +74204 0.003692626953125 +74205 0.2257080078125 +74206 0.427154541015625 +74207 0.643218994140625 +74208 0.855926513671875 +74209 0.870361328125 +74210 0.870361328125 +74211 0.862762451171875 +74212 0.79669189453125 +74213 0.595794677734375 +74214 0.362152099609375 +74215 0.1270751953125 +74216 -0.086944580078125 +74217 -0.2784423828125 +74218 -0.484832763671875 +74219 -0.729583740234375 +74220 -0.86688232421875 +74221 -0.870391845703125 +74222 -0.86859130859375 +74223 -0.86279296875 +74224 -0.817962646484375 +74225 -0.6116943359375 +74226 -0.3128662109375 +74227 0.039398193359375 +74228 0.422821044921875 +74229 0.805145263671875 +74230 0.870361328125 +74231 0.870361328125 +74232 0.860015869140625 +74233 0.727935791015625 +74234 0.48114013671875 +74235 0.2059326171875 +74236 -0.06103515625 +74237 -0.29913330078125 +74238 -0.516204833984375 +74239 -0.7252197265625 +74240 -0.85980224609375 +74241 -0.870391845703125 +74242 -0.870391845703125 +74243 -0.858062744140625 +74244 -0.673004150390625 +74245 -0.42694091796875 +74246 -0.2100830078125 +74247 -0.0362548828125 +74248 0.10943603515625 +74249 0.23516845703125 +74250 0.373687744140625 +74251 0.517791748046875 +74252 0.602783203125 +74253 0.635711669921875 +74254 0.655181884765625 +74255 0.65948486328125 +74256 0.651275634765625 +74257 0.61846923828125 +74258 0.53753662109375 +74259 0.404144287109375 +74260 0.22186279296875 +74261 0.003997802734375 +74262 -0.22100830078125 +74263 -0.42449951171875 +74264 -0.579833984375 +74265 -0.641876220703125 +74266 -0.6177978515625 +74267 -0.575531005859375 +74268 -0.526336669921875 +74269 -0.42645263671875 +74270 -0.2581787109375 +74271 -0.068695068359375 +74272 0.09222412109375 +74273 0.232147216796875 +74274 0.3509521484375 +74275 0.410064697265625 +74276 0.372955322265625 +74277 0.2554931640625 +74278 0.10711669921875 +74279 -0.052886962890625 +74280 -0.186279296875 +74281 -0.23291015625 +74282 -0.209442138671875 +74283 -0.174163818359375 +74284 -0.126739501953125 +74285 -0.048126220703125 +74286 0.0426025390625 +74287 0.10748291015625 +74288 0.1409912109375 +74289 0.19708251953125 +74290 0.273651123046875 +74291 0.31768798828125 +74292 0.341094970703125 +74293 0.368011474609375 +74294 0.37249755859375 +74295 0.30072021484375 +74296 0.1517333984375 +74297 -0.01470947265625 +74298 -0.1883544921875 +74299 -0.372711181640625 +74300 -0.51397705078125 +74301 -0.57177734375 +74302 -0.53948974609375 +74303 -0.43511962890625 +74304 -0.2962646484375 +74305 -0.161102294921875 +74306 -0.0435791015625 +74307 0.060394287109375 +74308 0.13665771484375 +74309 0.170135498046875 +74310 0.16552734375 +74311 0.15728759765625 +74312 0.150787353515625 +74313 0.12200927734375 +74314 0.080108642578125 +74315 0.05126953125 +74316 0.062896728515625 +74317 0.09271240234375 +74318 0.092987060546875 +74319 0.07855224609375 +74320 0.06427001953125 +74321 0.0347900390625 +74322 -0.01171875 +74323 -0.056060791015625 +74324 -0.055511474609375 +74325 -0.010467529296875 +74326 0.02508544921875 +74327 0.025665283203125 +74328 0.017333984375 +74329 0.00189208984375 +74330 -0.03173828125 +74331 -0.071502685546875 +74332 -0.13543701171875 +74333 -0.219970703125 +74334 -0.300506591796875 +74335 -0.376312255859375 +74336 -0.416107177734375 +74337 -0.371124267578125 +74338 -0.242279052734375 +74339 -0.069732666015625 +74340 0.125640869140625 +74341 0.31268310546875 +74342 0.45501708984375 +74343 0.554779052734375 +74344 0.61065673828125 +74345 0.610931396484375 +74346 0.531463623046875 +74347 0.3883056640625 +74348 0.23468017578125 +74349 0.095245361328125 +74350 -0.00396728515625 +74351 -0.04852294921875 +74352 -0.055145263671875 +74353 -0.0758056640625 +74354 -0.138702392578125 +74355 -0.209197998046875 +74356 -0.289031982421875 +74357 -0.37884521484375 +74358 -0.456329345703125 +74359 -0.51641845703125 +74360 -0.519287109375 +74361 -0.458251953125 +74362 -0.384796142578125 +74363 -0.323699951171875 +74364 -0.269287109375 +74365 -0.1951904296875 +74366 -0.100006103515625 +74367 -0.01055908203125 +74368 0.1033935546875 +74369 0.24908447265625 +74370 0.373199462890625 +74371 0.45806884765625 +74372 0.511474609375 +74373 0.565399169921875 +74374 0.61138916015625 +74375 0.5897216796875 +74376 0.4906005859375 +74377 0.33148193359375 +74378 0.147796630859375 +74379 -0.01873779296875 +74380 -0.140289306640625 +74381 -0.191986083984375 +74382 -0.184295654296875 +74383 -0.161834716796875 +74384 -0.166595458984375 +74385 -0.19390869140625 +74386 -0.22442626953125 +74387 -0.279754638671875 +74388 -0.3389892578125 +74389 -0.3543701171875 +74390 -0.348175048828125 +74391 -0.32598876953125 +74392 -0.2581787109375 +74393 -0.139801025390625 +74394 0.014617919921875 +74395 0.144378662109375 +74396 0.221038818359375 +74397 0.27069091796875 +74398 0.294036865234375 +74399 0.311767578125 +74400 0.339141845703125 +74401 0.360260009765625 +74402 0.360504150390625 +74403 0.308380126953125 +74404 0.18170166015625 +74405 0.0047607421875 +74406 -0.17559814453125 +74407 -0.3143310546875 +74408 -0.36785888671875 +74409 -0.36248779296875 +74410 -0.343536376953125 +74411 -0.3018798828125 +74412 -0.231414794921875 +74413 -0.117645263671875 +74414 0.007049560546875 +74415 0.087982177734375 +74416 0.13946533203125 +74417 0.17425537109375 +74418 0.188201904296875 +74419 0.171234130859375 +74420 0.118438720703125 +74421 0.05706787109375 +74422 -0.010711669921875 +74423 -0.0914306640625 +74424 -0.162322998046875 +74425 -0.194549560546875 +74426 -0.1492919921875 +74427 -0.02166748046875 +74428 0.124053955078125 +74429 0.211151123046875 +74430 0.240447998046875 +74431 0.242218017578125 +74432 0.2257080078125 +74433 0.194366455078125 +74434 0.115509033203125 +74435 0.0128173828125 +74436 -0.053802490234375 +74437 -0.110626220703125 +74438 -0.199493408203125 +74439 -0.29437255859375 +74440 -0.33221435546875 +74441 -0.27972412109375 +74442 -0.185333251953125 +74443 -0.128204345703125 +74444 -0.115692138671875 +74445 -0.116455078125 +74446 -0.105926513671875 +74447 -0.053955078125 +74448 0.048797607421875 +74449 0.157318115234375 +74450 0.212005615234375 +74451 0.218475341796875 +74452 0.23724365234375 +74453 0.30535888671875 +74454 0.38128662109375 +74455 0.404449462890625 +74456 0.3944091796875 +74457 0.3885498046875 +74458 0.362640380859375 +74459 0.27362060546875 +74460 0.11712646484375 +74461 -0.054901123046875 +74462 -0.19085693359375 +74463 -0.28570556640625 +74464 -0.339263916015625 +74465 -0.3775634765625 +74466 -0.445709228515625 +74467 -0.535064697265625 +74468 -0.629058837890625 +74469 -0.697601318359375 +74470 -0.70391845703125 +74471 -0.6424560546875 +74472 -0.491241455078125 +74473 -0.265716552734375 +74474 -0.023712158203125 +74475 0.201751708984375 +74476 0.375823974609375 +74477 0.485076904296875 +74478 0.56884765625 +74479 0.634765625 +74480 0.63763427734375 +74481 0.5660400390625 +74482 0.4720458984375 +74483 0.40692138671875 +74484 0.3778076171875 +74485 0.376953125 +74486 0.371978759765625 +74487 0.313140869140625 +74488 0.184417724609375 +74489 0.011199951171875 +74490 -0.171051025390625 +74491 -0.33740234375 +74492 -0.47198486328125 +74493 -0.560394287109375 +74494 -0.58056640625 +74495 -0.54754638671875 +74496 -0.508575439453125 +74497 -0.459503173828125 +74498 -0.394378662109375 +74499 -0.35260009765625 +74500 -0.31170654296875 +74501 -0.197418212890625 +74502 -0.007965087890625 +74503 0.207489013671875 +74504 0.409210205078125 +74505 0.57208251953125 +74506 0.66595458984375 +74507 0.65875244140625 +74508 0.56744384765625 +74509 0.431396484375 +74510 0.29443359375 +74511 0.182464599609375 +74512 0.06365966796875 +74513 -0.075958251953125 +74514 -0.189422607421875 +74515 -0.271942138671875 +74516 -0.342529296875 +74517 -0.364166259765625 +74518 -0.327239990234375 +74519 -0.2769775390625 +74520 -0.253692626953125 +74521 -0.24365234375 +74522 -0.1983642578125 +74523 -0.116241455078125 +74524 -0.036834716796875 +74525 0.034881591796875 +74526 0.09124755859375 +74527 0.10888671875 +74528 0.125518798828125 +74529 0.15771484375 +74530 0.17828369140625 +74531 0.17108154296875 +74532 0.129974365234375 +74533 0.082427978515625 +74534 0.027679443359375 +74535 -0.065643310546875 +74536 -0.15936279296875 +74537 -0.21307373046875 +74538 -0.234649658203125 +74539 -0.2001953125 +74540 -0.119171142578125 +74541 -0.024749755859375 +74542 0.085784912109375 +74543 0.178131103515625 +74544 0.215576171875 +74545 0.211456298828125 +74546 0.17523193359375 +74547 0.128753662109375 +74548 0.1019287109375 +74549 0.0743408203125 +74550 0.04327392578125 +74551 0.038177490234375 +74552 0.076263427734375 +74553 0.14105224609375 +74554 0.186431884765625 +74555 0.188812255859375 +74556 0.1390380859375 +74557 0.041778564453125 +74558 -0.079437255859375 +74559 -0.219390869140625 +74560 -0.367828369140625 +74561 -0.494873046875 +74562 -0.556243896484375 +74563 -0.508697509765625 +74564 -0.3756103515625 +74565 -0.218902587890625 +74566 -0.063751220703125 +74567 0.091552734375 +74568 0.23602294921875 +74569 0.342987060546875 +74570 0.39520263671875 +74571 0.389373779296875 +74572 0.324249267578125 +74573 0.224090576171875 +74574 0.124267578125 +74575 0.037078857421875 +74576 -0.010101318359375 +74577 -0.019439697265625 +74578 -0.022796630859375 +74579 -0.001556396484375 +74580 0.056304931640625 +74581 0.106719970703125 +74582 0.096893310546875 +74583 0.042694091796875 +74584 -0.018035888671875 +74585 -0.07586669921875 +74586 -0.11944580078125 +74587 -0.15972900390625 +74588 -0.202606201171875 +74589 -0.24859619140625 +74590 -0.30517578125 +74591 -0.36212158203125 +74592 -0.39141845703125 +74593 -0.35528564453125 +74594 -0.249969482421875 +74595 -0.092864990234375 +74596 0.08905029296875 +74597 0.2352294921875 +74598 0.318817138671875 +74599 0.358642578125 +74600 0.347747802734375 +74601 0.28564453125 +74602 0.223175048828125 +74603 0.196746826171875 +74604 0.179840087890625 +74605 0.155548095703125 +74606 0.151214599609375 +74607 0.156951904296875 +74608 0.13177490234375 +74609 0.100799560546875 +74610 0.087127685546875 +74611 0.05487060546875 +74612 -0.009002685546875 +74613 -0.10400390625 +74614 -0.229400634765625 +74615 -0.35552978515625 +74616 -0.441925048828125 +74617 -0.473846435546875 +74618 -0.464813232421875 +74619 -0.419097900390625 +74620 -0.334320068359375 +74621 -0.227935791015625 +74622 -0.12347412109375 +74623 -0.02764892578125 +74624 0.077667236328125 +74625 0.2132568359375 +74626 0.38885498046875 +74627 0.582794189453125 +74628 0.734039306640625 +74629 0.800140380859375 +74630 0.7783203125 +74631 0.6651611328125 +74632 0.45965576171875 +74633 0.199188232421875 +74634 -0.050689697265625 +74635 -0.23297119140625 +74636 -0.33013916015625 +74637 -0.368408203125 +74638 -0.378936767578125 +74639 -0.376983642578125 +74640 -0.37969970703125 +74641 -0.391510009765625 +74642 -0.385345458984375 +74643 -0.3419189453125 +74644 -0.28289794921875 +74645 -0.251617431640625 +74646 -0.266143798828125 +74647 -0.273345947265625 +74648 -0.216796875 +74649 -0.128265380859375 +74650 -0.068145751953125 +74651 -0.0430908203125 +74652 -0.024444580078125 +74653 0.020721435546875 +74654 0.124481201171875 +74655 0.25787353515625 +74656 0.379119873046875 +74657 0.47991943359375 +74658 0.5281982421875 +74659 0.511138916015625 +74660 0.456207275390625 +74661 0.407470703125 +74662 0.383758544921875 +74663 0.35687255859375 +74664 0.31182861328125 +74665 0.250885009765625 +74666 0.1654052734375 +74667 0.035247802734375 +74668 -0.142059326171875 +74669 -0.33563232421875 +74670 -0.5345458984375 +74671 -0.72186279296875 +74672 -0.836669921875 +74673 -0.8326416015625 +74674 -0.7296142578125 +74675 -0.582550048828125 +74676 -0.440093994140625 +74677 -0.324310302734375 +74678 -0.20147705078125 +74679 -0.044647216796875 +74680 0.103973388671875 +74681 0.202392578125 +74682 0.264495849609375 +74683 0.338897705078125 +74684 0.443817138671875 +74685 0.545074462890625 +74686 0.6173095703125 +74687 0.6524658203125 +74688 0.66339111328125 +74689 0.6561279296875 +74690 0.606781005859375 +74691 0.501190185546875 +74692 0.352783203125 +74693 0.176544189453125 +74694 -0.034820556640625 +74695 -0.258209228515625 +74696 -0.44244384765625 +74697 -0.5753173828125 +74698 -0.65203857421875 +74699 -0.641632080078125 +74700 -0.562164306640625 +74701 -0.458038330078125 +74702 -0.350555419921875 +74703 -0.260528564453125 +74704 -0.192108154296875 +74705 -0.141937255859375 +74706 -0.1021728515625 +74707 -0.062896728515625 +74708 -0.011932373046875 +74709 0.062835693359375 +74710 0.148712158203125 +74711 0.241729736328125 +74712 0.34912109375 +74713 0.457305908203125 +74714 0.54388427734375 +74715 0.5728759765625 +74716 0.506591796875 +74717 0.351226806640625 +74718 0.146514892578125 +74719 -0.05523681640625 +74720 -0.21624755859375 +74721 -0.334930419921875 +74722 -0.402984619140625 +74723 -0.4412841796875 +74724 -0.49578857421875 +74725 -0.5601806640625 +74726 -0.600738525390625 +74727 -0.584228515625 +74728 -0.47930908203125 +74729 -0.27935791015625 +74730 -0.0089111328125 +74731 0.268798828125 +74732 0.482818603515625 +74733 0.60369873046875 +74734 0.650421142578125 +74735 0.66400146484375 +74736 0.6414794921875 +74737 0.572540283203125 +74738 0.498138427734375 +74739 0.439453125 +74740 0.375518798828125 +74741 0.274505615234375 +74742 0.1087646484375 +74743 -0.099395751953125 +74744 -0.3182373046875 +74745 -0.5489501953125 +74746 -0.7738037109375 +74747 -0.86383056640625 +74748 -0.870391845703125 +74749 -0.86895751953125 +74750 -0.861053466796875 +74751 -0.765869140625 +74752 -0.5301513671875 +74753 -0.214691162109375 +74754 0.137359619140625 +74755 0.474822998046875 +74756 0.76239013671875 +74757 0.867462158203125 +74758 0.870361328125 +74759 0.86480712890625 +74760 0.831817626953125 +74761 0.677581787109375 +74762 0.495880126953125 +74763 0.30767822265625 +74764 0.116180419921875 +74765 -0.110748291015625 +74766 -0.381805419921875 +74767 -0.6572265625 +74768 -0.857421875 +74769 -0.870391845703125 +74770 -0.870391845703125 +74771 -0.86444091796875 +74772 -0.85723876953125 +74773 -0.790008544921875 +74774 -0.62847900390625 +74775 -0.3956298828125 +74776 -0.126708984375 +74777 0.150115966796875 +74778 0.424041748046875 +74779 0.670623779296875 +74780 0.854522705078125 +74781 0.866485595703125 +74782 0.86920166015625 +74783 0.8653564453125 +74784 0.857147216796875 +74785 0.766845703125 +74786 0.628509521484375 +74787 0.462127685546875 +74788 0.297210693359375 +74789 0.14862060546875 +74790 -0.00537109375 +74791 -0.15753173828125 +74792 -0.31304931640625 +74793 -0.48876953125 +74794 -0.6416015625 +74795 -0.751373291015625 +74796 -0.84619140625 +74797 -0.861297607421875 +74798 -0.863250732421875 +74799 -0.856597900390625 +74800 -0.7498779296875 +74801 -0.624542236328125 +74802 -0.47808837890625 +74803 -0.253387451171875 +74804 0.003692626953125 +74805 0.2257080078125 +74806 0.427154541015625 +74807 0.643218994140625 +74808 0.855926513671875 +74809 0.870361328125 +74810 0.870361328125 +74811 0.862762451171875 +74812 0.79669189453125 +74813 0.595794677734375 +74814 0.362152099609375 +74815 0.1270751953125 +74816 -0.086944580078125 +74817 -0.2784423828125 +74818 -0.484832763671875 +74819 -0.729583740234375 +74820 -0.86688232421875 +74821 -0.870391845703125 +74822 -0.86859130859375 +74823 -0.86279296875 +74824 -0.817962646484375 +74825 -0.6116943359375 +74826 -0.3128662109375 +74827 0.039398193359375 +74828 0.422821044921875 +74829 0.805145263671875 +74830 0.870361328125 +74831 0.870361328125 +74832 0.860015869140625 +74833 0.727935791015625 +74834 0.48114013671875 +74835 0.2059326171875 +74836 -0.06103515625 +74837 -0.29913330078125 +74838 -0.516204833984375 +74839 -0.7252197265625 +74840 -0.85980224609375 +74841 -0.870391845703125 +74842 -0.870391845703125 +74843 -0.858062744140625 +74844 -0.673004150390625 +74845 -0.42694091796875 +74846 -0.2100830078125 +74847 -0.0362548828125 +74848 0.10943603515625 +74849 0.23516845703125 +74850 0.373687744140625 +74851 0.517791748046875 +74852 0.602783203125 +74853 0.635711669921875 +74854 0.655181884765625 +74855 0.65948486328125 +74856 0.651275634765625 +74857 0.61846923828125 +74858 0.53753662109375 +74859 0.404144287109375 +74860 0.22186279296875 +74861 0.003997802734375 +74862 -0.22100830078125 +74863 -0.42449951171875 +74864 -0.579833984375 +74865 -0.641876220703125 +74866 -0.6177978515625 +74867 -0.575531005859375 +74868 -0.526336669921875 +74869 -0.42645263671875 +74870 -0.2581787109375 +74871 -0.068695068359375 +74872 0.09222412109375 +74873 0.232147216796875 +74874 0.3509521484375 +74875 0.410064697265625 +74876 0.372955322265625 +74877 0.2554931640625 +74878 0.10711669921875 +74879 -0.052886962890625 +74880 -0.186279296875 +74881 -0.23291015625 +74882 -0.209442138671875 +74883 -0.174163818359375 +74884 -0.126739501953125 +74885 -0.048126220703125 +74886 0.0426025390625 +74887 0.10748291015625 +74888 0.1409912109375 +74889 0.19708251953125 +74890 0.273651123046875 +74891 0.31768798828125 +74892 0.341094970703125 +74893 0.368011474609375 +74894 0.37249755859375 +74895 0.30072021484375 +74896 0.1517333984375 +74897 -0.01470947265625 +74898 -0.1883544921875 +74899 -0.372711181640625 +74900 -0.51397705078125 +74901 -0.57177734375 +74902 -0.53948974609375 +74903 -0.43511962890625 +74904 -0.2962646484375 +74905 -0.161102294921875 +74906 -0.0435791015625 +74907 0.060394287109375 +74908 0.13665771484375 +74909 0.170135498046875 +74910 0.16552734375 +74911 0.15728759765625 +74912 0.150787353515625 +74913 0.12200927734375 +74914 0.080108642578125 +74915 0.05126953125 +74916 0.062896728515625 +74917 0.09271240234375 +74918 0.092987060546875 +74919 0.07855224609375 +74920 0.06427001953125 +74921 0.0347900390625 +74922 -0.01171875 +74923 -0.056060791015625 +74924 -0.055511474609375 +74925 -0.010467529296875 +74926 0.02508544921875 +74927 0.025665283203125 +74928 0.017333984375 +74929 0.00189208984375 +74930 -0.03173828125 +74931 -0.071502685546875 +74932 -0.13543701171875 +74933 -0.219970703125 +74934 -0.300506591796875 +74935 -0.376312255859375 +74936 -0.416107177734375 +74937 -0.371124267578125 +74938 -0.242279052734375 +74939 -0.069732666015625 +74940 0.125640869140625 +74941 0.31268310546875 +74942 0.45501708984375 +74943 0.554779052734375 +74944 0.61065673828125 +74945 0.610931396484375 +74946 0.531463623046875 +74947 0.3883056640625 +74948 0.23468017578125 +74949 0.095245361328125 +74950 -0.00396728515625 +74951 -0.04852294921875 +74952 -0.055145263671875 +74953 -0.0758056640625 +74954 -0.138702392578125 +74955 -0.209197998046875 +74956 -0.289031982421875 +74957 -0.37884521484375 +74958 -0.456329345703125 +74959 -0.51641845703125 +74960 -0.519287109375 +74961 -0.458251953125 +74962 -0.384796142578125 +74963 -0.323699951171875 +74964 -0.269287109375 +74965 -0.1951904296875 +74966 -0.100006103515625 +74967 -0.01055908203125 +74968 0.1033935546875 +74969 0.24908447265625 +74970 0.373199462890625 +74971 0.45806884765625 +74972 0.511474609375 +74973 0.565399169921875 +74974 0.61138916015625 +74975 0.5897216796875 +74976 0.4906005859375 +74977 0.33148193359375 +74978 0.147796630859375 +74979 -0.01873779296875 +74980 -0.140289306640625 +74981 -0.191986083984375 +74982 -0.184295654296875 +74983 -0.161834716796875 +74984 -0.166595458984375 +74985 -0.19390869140625 +74986 -0.22442626953125 +74987 -0.279754638671875 +74988 -0.3389892578125 +74989 -0.3543701171875 +74990 -0.348175048828125 +74991 -0.32598876953125 +74992 -0.2581787109375 +74993 -0.139801025390625 +74994 0.014617919921875 +74995 0.144378662109375 +74996 0.221038818359375 +74997 0.27069091796875 +74998 0.294036865234375 +74999 0.311767578125 +75000 0.339141845703125 +75001 0.360260009765625 +75002 0.360504150390625 +75003 0.308380126953125 +75004 0.18170166015625 +75005 0.0047607421875 +75006 -0.17559814453125 +75007 -0.3143310546875 +75008 -0.36785888671875 +75009 -0.36248779296875 +75010 -0.343536376953125 +75011 -0.3018798828125 +75012 -0.231414794921875 +75013 -0.117645263671875 +75014 0.007049560546875 +75015 0.087982177734375 +75016 0.13946533203125 +75017 0.17425537109375 +75018 0.188201904296875 +75019 0.171234130859375 +75020 0.118438720703125 +75021 0.05706787109375 +75022 -0.010711669921875 +75023 -0.0914306640625 +75024 -0.162322998046875 +75025 -0.194549560546875 +75026 -0.1492919921875 +75027 -0.02166748046875 +75028 0.124053955078125 +75029 0.211151123046875 +75030 0.240447998046875 +75031 0.242218017578125 +75032 0.2257080078125 +75033 0.194366455078125 +75034 0.115509033203125 +75035 0.0128173828125 +75036 -0.053802490234375 +75037 -0.110626220703125 +75038 -0.199493408203125 +75039 -0.29437255859375 +75040 -0.33221435546875 +75041 -0.27972412109375 +75042 -0.185333251953125 +75043 -0.128204345703125 +75044 -0.115692138671875 +75045 -0.116455078125 +75046 -0.105926513671875 +75047 -0.053955078125 +75048 0.048797607421875 +75049 0.157318115234375 +75050 0.212005615234375 +75051 0.218475341796875 +75052 0.23724365234375 +75053 0.30535888671875 +75054 0.38128662109375 +75055 0.404449462890625 +75056 0.3944091796875 +75057 0.3885498046875 +75058 0.362640380859375 +75059 0.27362060546875 +75060 0.11712646484375 +75061 -0.054901123046875 +75062 -0.19085693359375 +75063 -0.28570556640625 +75064 -0.339263916015625 +75065 -0.3775634765625 +75066 -0.445709228515625 +75067 -0.535064697265625 +75068 -0.629058837890625 +75069 -0.697601318359375 +75070 -0.70391845703125 +75071 -0.6424560546875 +75072 -0.491241455078125 +75073 -0.265716552734375 +75074 -0.023712158203125 +75075 0.201751708984375 +75076 0.375823974609375 +75077 0.485076904296875 +75078 0.56884765625 +75079 0.634765625 +75080 0.63763427734375 +75081 0.5660400390625 +75082 0.4720458984375 +75083 0.40692138671875 +75084 0.3778076171875 +75085 0.376953125 +75086 0.371978759765625 +75087 0.313140869140625 +75088 0.184417724609375 +75089 0.011199951171875 +75090 -0.171051025390625 +75091 -0.33740234375 +75092 -0.47198486328125 +75093 -0.560394287109375 +75094 -0.58056640625 +75095 -0.54754638671875 +75096 -0.508575439453125 +75097 -0.459503173828125 +75098 -0.394378662109375 +75099 -0.35260009765625 +75100 -0.31170654296875 +75101 -0.197418212890625 +75102 -0.007965087890625 +75103 0.207489013671875 +75104 0.409210205078125 +75105 0.57208251953125 +75106 0.66595458984375 +75107 0.65875244140625 +75108 0.56744384765625 +75109 0.431396484375 +75110 0.29443359375 +75111 0.182464599609375 +75112 0.06365966796875 +75113 -0.075958251953125 +75114 -0.189422607421875 +75115 -0.271942138671875 +75116 -0.342529296875 +75117 -0.364166259765625 +75118 -0.327239990234375 +75119 -0.2769775390625 +75120 -0.253692626953125 +75121 -0.24365234375 +75122 -0.1983642578125 +75123 -0.116241455078125 +75124 -0.036834716796875 +75125 0.034881591796875 +75126 0.09124755859375 +75127 0.10888671875 +75128 0.125518798828125 +75129 0.15771484375 +75130 0.17828369140625 +75131 0.17108154296875 +75132 0.129974365234375 +75133 0.082427978515625 +75134 0.027679443359375 +75135 -0.065643310546875 +75136 -0.15936279296875 +75137 -0.21307373046875 +75138 -0.234649658203125 +75139 -0.2001953125 +75140 -0.119171142578125 +75141 -0.024749755859375 +75142 0.085784912109375 +75143 0.178131103515625 +75144 0.215576171875 +75145 0.211456298828125 +75146 0.17523193359375 +75147 0.128753662109375 +75148 0.1019287109375 +75149 0.0743408203125 +75150 0.04327392578125 +75151 0.038177490234375 +75152 0.076263427734375 +75153 0.14105224609375 +75154 0.186431884765625 +75155 0.188812255859375 +75156 0.1390380859375 +75157 0.041778564453125 +75158 -0.079437255859375 +75159 -0.219390869140625 +75160 -0.367828369140625 +75161 -0.494873046875 +75162 -0.556243896484375 +75163 -0.508697509765625 +75164 -0.3756103515625 +75165 -0.218902587890625 +75166 -0.063751220703125 +75167 0.091552734375 +75168 0.23602294921875 +75169 0.342987060546875 +75170 0.39520263671875 +75171 0.389373779296875 +75172 0.324249267578125 +75173 0.224090576171875 +75174 0.124267578125 +75175 0.037078857421875 +75176 -0.010101318359375 +75177 -0.019439697265625 +75178 -0.022796630859375 +75179 -0.001556396484375 +75180 0.056304931640625 +75181 0.106719970703125 +75182 0.096893310546875 +75183 0.042694091796875 +75184 -0.018035888671875 +75185 -0.07586669921875 +75186 -0.11944580078125 +75187 -0.15972900390625 +75188 -0.202606201171875 +75189 -0.24859619140625 +75190 -0.30517578125 +75191 -0.36212158203125 +75192 -0.39141845703125 +75193 -0.35528564453125 +75194 -0.249969482421875 +75195 -0.092864990234375 +75196 0.08905029296875 +75197 0.2352294921875 +75198 0.318817138671875 +75199 0.358642578125 +75200 0.347747802734375 +75201 0.28564453125 +75202 0.223175048828125 +75203 0.196746826171875 +75204 0.179840087890625 +75205 0.155548095703125 +75206 0.151214599609375 +75207 0.156951904296875 +75208 0.13177490234375 +75209 0.100799560546875 +75210 0.087127685546875 +75211 0.05487060546875 +75212 -0.009002685546875 +75213 -0.10400390625 +75214 -0.229400634765625 +75215 -0.35552978515625 +75216 -0.441925048828125 +75217 -0.473846435546875 +75218 -0.464813232421875 +75219 -0.419097900390625 +75220 -0.334320068359375 +75221 -0.227935791015625 +75222 -0.12347412109375 +75223 -0.02764892578125 +75224 0.077667236328125 +75225 0.2132568359375 +75226 0.38885498046875 +75227 0.582794189453125 +75228 0.734039306640625 +75229 0.800140380859375 +75230 0.7783203125 +75231 0.6651611328125 +75232 0.45965576171875 +75233 0.199188232421875 +75234 -0.050689697265625 +75235 -0.23297119140625 +75236 -0.33013916015625 +75237 -0.368408203125 +75238 -0.378936767578125 +75239 -0.376983642578125 +75240 -0.37969970703125 +75241 -0.391510009765625 +75242 -0.385345458984375 +75243 -0.3419189453125 +75244 -0.28289794921875 +75245 -0.251617431640625 +75246 -0.266143798828125 +75247 -0.273345947265625 +75248 -0.216796875 +75249 -0.128265380859375 +75250 -0.068145751953125 +75251 -0.0430908203125 +75252 -0.024444580078125 +75253 0.020721435546875 +75254 0.124481201171875 +75255 0.25787353515625 +75256 0.379119873046875 +75257 0.47991943359375 +75258 0.5281982421875 +75259 0.511138916015625 +75260 0.456207275390625 +75261 0.407470703125 +75262 0.383758544921875 +75263 0.35687255859375 +75264 0.31182861328125 +75265 0.250885009765625 +75266 0.1654052734375 +75267 0.035247802734375 +75268 -0.142059326171875 +75269 -0.33563232421875 +75270 -0.5345458984375 +75271 -0.72186279296875 +75272 -0.836669921875 +75273 -0.8326416015625 +75274 -0.7296142578125 +75275 -0.582550048828125 +75276 -0.440093994140625 +75277 -0.324310302734375 +75278 -0.20147705078125 +75279 -0.044647216796875 +75280 0.103973388671875 +75281 0.202392578125 +75282 0.264495849609375 +75283 0.338897705078125 +75284 0.443817138671875 +75285 0.545074462890625 +75286 0.6173095703125 +75287 0.6524658203125 +75288 0.66339111328125 +75289 0.6561279296875 +75290 0.606781005859375 +75291 0.501190185546875 +75292 0.352783203125 +75293 0.176544189453125 +75294 -0.034820556640625 +75295 -0.258209228515625 +75296 -0.44244384765625 +75297 -0.5753173828125 +75298 -0.65203857421875 +75299 -0.641632080078125 +75300 -0.562164306640625 +75301 -0.458038330078125 +75302 -0.350555419921875 +75303 -0.260528564453125 +75304 -0.192108154296875 +75305 -0.141937255859375 +75306 -0.1021728515625 +75307 -0.062896728515625 +75308 -0.011932373046875 +75309 0.062835693359375 +75310 0.148712158203125 +75311 0.241729736328125 +75312 0.34912109375 +75313 0.457305908203125 +75314 0.54388427734375 +75315 0.5728759765625 +75316 0.506591796875 +75317 0.351226806640625 +75318 0.146514892578125 +75319 -0.05523681640625 +75320 -0.21624755859375 +75321 -0.334930419921875 +75322 -0.402984619140625 +75323 -0.4412841796875 +75324 -0.49578857421875 +75325 -0.5601806640625 +75326 -0.600738525390625 +75327 -0.584228515625 +75328 -0.47930908203125 +75329 -0.27935791015625 +75330 -0.0089111328125 +75331 0.268798828125 +75332 0.482818603515625 +75333 0.60369873046875 +75334 0.650421142578125 +75335 0.66400146484375 +75336 0.6414794921875 +75337 0.572540283203125 +75338 0.498138427734375 +75339 0.439453125 +75340 0.375518798828125 +75341 0.274505615234375 +75342 0.1087646484375 +75343 -0.099395751953125 +75344 -0.3182373046875 +75345 -0.5489501953125 +75346 -0.7738037109375 +75347 -0.86383056640625 +75348 -0.870391845703125 +75349 -0.86895751953125 +75350 -0.861053466796875 +75351 -0.765869140625 +75352 -0.5301513671875 +75353 -0.214691162109375 +75354 0.137359619140625 +75355 0.474822998046875 +75356 0.76239013671875 +75357 0.867462158203125 +75358 0.870361328125 +75359 0.86480712890625 +75360 0.831817626953125 +75361 0.677581787109375 +75362 0.495880126953125 +75363 0.30767822265625 +75364 0.116180419921875 +75365 -0.110748291015625 +75366 -0.381805419921875 +75367 -0.6572265625 +75368 -0.857421875 +75369 -0.870391845703125 +75370 -0.870391845703125 +75371 -0.86444091796875 +75372 -0.85723876953125 +75373 -0.790008544921875 +75374 -0.62847900390625 +75375 -0.3956298828125 +75376 -0.126708984375 +75377 0.150115966796875 +75378 0.424041748046875 +75379 0.670623779296875 +75380 0.854522705078125 +75381 0.866485595703125 +75382 0.86920166015625 +75383 0.8653564453125 +75384 0.857147216796875 +75385 0.766845703125 +75386 0.628509521484375 +75387 0.462127685546875 +75388 0.297210693359375 +75389 0.14862060546875 +75390 -0.00537109375 +75391 -0.15753173828125 +75392 -0.31304931640625 +75393 -0.48876953125 +75394 -0.6416015625 +75395 -0.751373291015625 +75396 -0.84619140625 +75397 -0.861297607421875 +75398 -0.863250732421875 +75399 -0.856597900390625 +75400 -0.7498779296875 +75401 -0.624542236328125 +75402 -0.47808837890625 +75403 -0.253387451171875 +75404 0.003692626953125 +75405 0.2257080078125 +75406 0.427154541015625 +75407 0.643218994140625 +75408 0.855926513671875 +75409 0.870361328125 +75410 0.870361328125 +75411 0.862762451171875 +75412 0.79669189453125 +75413 0.595794677734375 +75414 0.362152099609375 +75415 0.1270751953125 +75416 -0.086944580078125 +75417 -0.2784423828125 +75418 -0.484832763671875 +75419 -0.729583740234375 +75420 -0.86688232421875 +75421 -0.870391845703125 +75422 -0.86859130859375 +75423 -0.86279296875 +75424 -0.817962646484375 +75425 -0.6116943359375 +75426 -0.3128662109375 +75427 0.039398193359375 +75428 0.422821044921875 +75429 0.805145263671875 +75430 0.870361328125 +75431 0.870361328125 +75432 0.860015869140625 +75433 0.727935791015625 +75434 0.48114013671875 +75435 0.2059326171875 +75436 -0.06103515625 +75437 -0.29913330078125 +75438 -0.516204833984375 +75439 -0.7252197265625 +75440 -0.85980224609375 +75441 -0.870391845703125 +75442 -0.870391845703125 +75443 -0.858062744140625 +75444 -0.673004150390625 +75445 -0.42694091796875 +75446 -0.2100830078125 +75447 -0.0362548828125 +75448 0.10943603515625 +75449 0.23516845703125 +75450 0.373687744140625 +75451 0.517791748046875 +75452 0.602783203125 +75453 0.635711669921875 +75454 0.655181884765625 +75455 0.65948486328125 +75456 0.651275634765625 +75457 0.61846923828125 +75458 0.53753662109375 +75459 0.404144287109375 +75460 0.22186279296875 +75461 0.003997802734375 +75462 -0.22100830078125 +75463 -0.42449951171875 +75464 -0.579833984375 +75465 -0.641876220703125 +75466 -0.6177978515625 +75467 -0.575531005859375 +75468 -0.526336669921875 +75469 -0.42645263671875 +75470 -0.2581787109375 +75471 -0.068695068359375 +75472 0.09222412109375 +75473 0.232147216796875 +75474 0.3509521484375 +75475 0.410064697265625 +75476 0.372955322265625 +75477 0.2554931640625 +75478 0.10711669921875 +75479 -0.052886962890625 +75480 -0.186279296875 +75481 -0.23291015625 +75482 -0.209442138671875 +75483 -0.174163818359375 +75484 -0.126739501953125 +75485 -0.048126220703125 +75486 0.0426025390625 +75487 0.10748291015625 +75488 0.1409912109375 +75489 0.19708251953125 +75490 0.273651123046875 +75491 0.31768798828125 +75492 0.341094970703125 +75493 0.368011474609375 +75494 0.37249755859375 +75495 0.30072021484375 +75496 0.1517333984375 +75497 -0.01470947265625 +75498 -0.1883544921875 +75499 -0.372711181640625 +75500 -0.51397705078125 +75501 -0.57177734375 +75502 -0.53948974609375 +75503 -0.43511962890625 +75504 -0.2962646484375 +75505 -0.161102294921875 +75506 -0.0435791015625 +75507 0.060394287109375 +75508 0.13665771484375 +75509 0.170135498046875 +75510 0.16552734375 +75511 0.15728759765625 +75512 0.150787353515625 +75513 0.12200927734375 +75514 0.080108642578125 +75515 0.05126953125 +75516 0.062896728515625 +75517 0.09271240234375 +75518 0.092987060546875 +75519 0.07855224609375 +75520 0.06427001953125 +75521 0.0347900390625 +75522 -0.01171875 +75523 -0.056060791015625 +75524 -0.055511474609375 +75525 -0.010467529296875 +75526 0.02508544921875 +75527 0.025665283203125 +75528 0.017333984375 +75529 0.00189208984375 +75530 -0.03173828125 +75531 -0.071502685546875 +75532 -0.13543701171875 +75533 -0.219970703125 +75534 -0.300506591796875 +75535 -0.376312255859375 +75536 -0.416107177734375 +75537 -0.371124267578125 +75538 -0.242279052734375 +75539 -0.069732666015625 +75540 0.125640869140625 +75541 0.31268310546875 +75542 0.45501708984375 +75543 0.554779052734375 +75544 0.61065673828125 +75545 0.610931396484375 +75546 0.531463623046875 +75547 0.3883056640625 +75548 0.23468017578125 +75549 0.095245361328125 +75550 -0.00396728515625 +75551 -0.04852294921875 +75552 -0.055145263671875 +75553 -0.0758056640625 +75554 -0.138702392578125 +75555 -0.209197998046875 +75556 -0.289031982421875 +75557 -0.37884521484375 +75558 -0.456329345703125 +75559 -0.51641845703125 +75560 -0.519287109375 +75561 -0.458251953125 +75562 -0.384796142578125 +75563 -0.323699951171875 +75564 -0.269287109375 +75565 -0.1951904296875 +75566 -0.100006103515625 +75567 -0.01055908203125 +75568 0.1033935546875 +75569 0.24908447265625 +75570 0.373199462890625 +75571 0.45806884765625 +75572 0.511474609375 +75573 0.565399169921875 +75574 0.61138916015625 +75575 0.5897216796875 +75576 0.4906005859375 +75577 0.33148193359375 +75578 0.147796630859375 +75579 -0.01873779296875 +75580 -0.140289306640625 +75581 -0.191986083984375 +75582 -0.184295654296875 +75583 -0.161834716796875 +75584 -0.166595458984375 +75585 -0.19390869140625 +75586 -0.22442626953125 +75587 -0.279754638671875 +75588 -0.3389892578125 +75589 -0.3543701171875 +75590 -0.348175048828125 +75591 -0.32598876953125 +75592 -0.2581787109375 +75593 -0.139801025390625 +75594 0.014617919921875 +75595 0.144378662109375 +75596 0.221038818359375 +75597 0.27069091796875 +75598 0.294036865234375 +75599 0.311767578125 +75600 0.339141845703125 +75601 0.360260009765625 +75602 0.360504150390625 +75603 0.308380126953125 +75604 0.18170166015625 +75605 0.0047607421875 +75606 -0.17559814453125 +75607 -0.3143310546875 +75608 -0.36785888671875 +75609 -0.36248779296875 +75610 -0.343536376953125 +75611 -0.3018798828125 +75612 -0.231414794921875 +75613 -0.117645263671875 +75614 0.007049560546875 +75615 0.087982177734375 +75616 0.13946533203125 +75617 0.17425537109375 +75618 0.188201904296875 +75619 0.171234130859375 +75620 0.118438720703125 +75621 0.05706787109375 +75622 -0.010711669921875 +75623 -0.0914306640625 +75624 -0.162322998046875 +75625 -0.194549560546875 +75626 -0.1492919921875 +75627 -0.02166748046875 +75628 0.124053955078125 +75629 0.211151123046875 +75630 0.240447998046875 +75631 0.242218017578125 +75632 0.2257080078125 +75633 0.194366455078125 +75634 0.115509033203125 +75635 0.0128173828125 +75636 -0.053802490234375 +75637 -0.110626220703125 +75638 -0.199493408203125 +75639 -0.29437255859375 +75640 -0.33221435546875 +75641 -0.27972412109375 +75642 -0.185333251953125 +75643 -0.128204345703125 +75644 -0.115692138671875 +75645 -0.116455078125 +75646 -0.105926513671875 +75647 -0.053955078125 +75648 0.048797607421875 +75649 0.157318115234375 +75650 0.212005615234375 +75651 0.218475341796875 +75652 0.23724365234375 +75653 0.30535888671875 +75654 0.38128662109375 +75655 0.404449462890625 +75656 0.3944091796875 +75657 0.3885498046875 +75658 0.362640380859375 +75659 0.27362060546875 +75660 0.11712646484375 +75661 -0.054901123046875 +75662 -0.19085693359375 +75663 -0.28570556640625 +75664 -0.339263916015625 +75665 -0.3775634765625 +75666 -0.445709228515625 +75667 -0.535064697265625 +75668 -0.629058837890625 +75669 -0.697601318359375 +75670 -0.70391845703125 +75671 -0.6424560546875 +75672 -0.491241455078125 +75673 -0.265716552734375 +75674 -0.023712158203125 +75675 0.201751708984375 +75676 0.375823974609375 +75677 0.485076904296875 +75678 0.56884765625 +75679 0.634765625 +75680 0.63763427734375 +75681 0.5660400390625 +75682 0.4720458984375 +75683 0.40692138671875 +75684 0.3778076171875 +75685 0.376953125 +75686 0.371978759765625 +75687 0.313140869140625 +75688 0.184417724609375 +75689 0.011199951171875 +75690 -0.171051025390625 +75691 -0.33740234375 +75692 -0.47198486328125 +75693 -0.560394287109375 +75694 -0.58056640625 +75695 -0.54754638671875 +75696 -0.508575439453125 +75697 -0.459503173828125 +75698 -0.394378662109375 +75699 -0.35260009765625 +75700 -0.31170654296875 +75701 -0.197418212890625 +75702 -0.007965087890625 +75703 0.207489013671875 +75704 0.409210205078125 +75705 0.57208251953125 +75706 0.66595458984375 +75707 0.65875244140625 +75708 0.56744384765625 +75709 0.431396484375 +75710 0.29443359375 +75711 0.182464599609375 +75712 0.06365966796875 +75713 -0.075958251953125 +75714 -0.189422607421875 +75715 -0.271942138671875 +75716 -0.342529296875 +75717 -0.364166259765625 +75718 -0.327239990234375 +75719 -0.2769775390625 +75720 -0.253692626953125 +75721 -0.24365234375 +75722 -0.1983642578125 +75723 -0.116241455078125 +75724 -0.036834716796875 +75725 0.034881591796875 +75726 0.09124755859375 +75727 0.10888671875 +75728 0.125518798828125 +75729 0.15771484375 +75730 0.17828369140625 +75731 0.17108154296875 +75732 0.129974365234375 +75733 0.082427978515625 +75734 0.027679443359375 +75735 -0.065643310546875 +75736 -0.15936279296875 +75737 -0.21307373046875 +75738 -0.234649658203125 +75739 -0.2001953125 +75740 -0.119171142578125 +75741 -0.024749755859375 +75742 0.085784912109375 +75743 0.178131103515625 +75744 0.215576171875 +75745 0.211456298828125 +75746 0.17523193359375 +75747 0.128753662109375 +75748 0.1019287109375 +75749 0.0743408203125 +75750 0.04327392578125 +75751 0.038177490234375 +75752 0.076263427734375 +75753 0.14105224609375 +75754 0.186431884765625 +75755 0.188812255859375 +75756 0.1390380859375 +75757 0.041778564453125 +75758 -0.079437255859375 +75759 -0.219390869140625 +75760 -0.367828369140625 +75761 -0.494873046875 +75762 -0.556243896484375 +75763 -0.508697509765625 +75764 -0.3756103515625 +75765 -0.218902587890625 +75766 -0.063751220703125 +75767 0.091552734375 +75768 0.23602294921875 +75769 0.342987060546875 +75770 0.39520263671875 +75771 0.389373779296875 +75772 0.324249267578125 +75773 0.224090576171875 +75774 0.124267578125 +75775 0.037078857421875 +75776 -0.010101318359375 +75777 -0.019439697265625 +75778 -0.022796630859375 +75779 -0.001556396484375 +75780 0.056304931640625 +75781 0.106719970703125 +75782 0.096893310546875 +75783 0.042694091796875 +75784 -0.018035888671875 +75785 -0.07586669921875 +75786 -0.11944580078125 +75787 -0.15972900390625 +75788 -0.202606201171875 +75789 -0.24859619140625 +75790 -0.30517578125 +75791 -0.36212158203125 +75792 -0.39141845703125 +75793 -0.35528564453125 +75794 -0.249969482421875 +75795 -0.092864990234375 +75796 0.08905029296875 +75797 0.2352294921875 +75798 0.318817138671875 +75799 0.358642578125 +75800 0.347747802734375 +75801 0.28564453125 +75802 0.223175048828125 +75803 0.196746826171875 +75804 0.179840087890625 +75805 0.155548095703125 +75806 0.151214599609375 +75807 0.156951904296875 +75808 0.13177490234375 +75809 0.100799560546875 +75810 0.087127685546875 +75811 0.05487060546875 +75812 -0.009002685546875 +75813 -0.10400390625 +75814 -0.229400634765625 +75815 -0.35552978515625 +75816 -0.441925048828125 +75817 -0.473846435546875 +75818 -0.464813232421875 +75819 -0.419097900390625 +75820 -0.334320068359375 +75821 -0.227935791015625 +75822 -0.12347412109375 +75823 -0.02764892578125 +75824 0.077667236328125 +75825 0.2132568359375 +75826 0.38885498046875 +75827 0.582794189453125 +75828 0.734039306640625 +75829 0.800140380859375 +75830 0.7783203125 +75831 0.6651611328125 +75832 0.45965576171875 +75833 0.199188232421875 +75834 -0.050689697265625 +75835 -0.23297119140625 +75836 -0.33013916015625 +75837 -0.368408203125 +75838 -0.378936767578125 +75839 -0.376983642578125 +75840 -0.37969970703125 +75841 -0.391510009765625 +75842 -0.385345458984375 +75843 -0.3419189453125 +75844 -0.28289794921875 +75845 -0.251617431640625 +75846 -0.266143798828125 +75847 -0.273345947265625 +75848 -0.216796875 +75849 -0.128265380859375 +75850 -0.068145751953125 +75851 -0.0430908203125 +75852 -0.024444580078125 +75853 0.020721435546875 +75854 0.124481201171875 +75855 0.25787353515625 +75856 0.379119873046875 +75857 0.47991943359375 +75858 0.5281982421875 +75859 0.511138916015625 +75860 0.456207275390625 +75861 0.407470703125 +75862 0.383758544921875 +75863 0.35687255859375 +75864 0.31182861328125 +75865 0.250885009765625 +75866 0.1654052734375 +75867 0.035247802734375 +75868 -0.142059326171875 +75869 -0.33563232421875 +75870 -0.5345458984375 +75871 -0.72186279296875 +75872 -0.836669921875 +75873 -0.8326416015625 +75874 -0.7296142578125 +75875 -0.582550048828125 +75876 -0.440093994140625 +75877 -0.324310302734375 +75878 -0.20147705078125 +75879 -0.044647216796875 +75880 0.103973388671875 +75881 0.202392578125 +75882 0.264495849609375 +75883 0.338897705078125 +75884 0.443817138671875 +75885 0.545074462890625 +75886 0.6173095703125 +75887 0.6524658203125 +75888 0.66339111328125 +75889 0.6561279296875 +75890 0.606781005859375 +75891 0.501190185546875 +75892 0.352783203125 +75893 0.176544189453125 +75894 -0.034820556640625 +75895 -0.258209228515625 +75896 -0.44244384765625 +75897 -0.5753173828125 +75898 -0.65203857421875 +75899 -0.641632080078125 +75900 -0.562164306640625 +75901 -0.458038330078125 +75902 -0.350555419921875 +75903 -0.260528564453125 +75904 -0.192108154296875 +75905 -0.141937255859375 +75906 -0.1021728515625 +75907 -0.062896728515625 +75908 -0.011932373046875 +75909 0.062835693359375 +75910 0.148712158203125 +75911 0.241729736328125 +75912 0.34912109375 +75913 0.457305908203125 +75914 0.54388427734375 +75915 0.5728759765625 +75916 0.506591796875 +75917 0.351226806640625 +75918 0.146514892578125 +75919 -0.05523681640625 +75920 -0.21624755859375 +75921 -0.334930419921875 +75922 -0.402984619140625 +75923 -0.4412841796875 +75924 -0.49578857421875 +75925 -0.5601806640625 +75926 -0.600738525390625 +75927 -0.584228515625 +75928 -0.47930908203125 +75929 -0.27935791015625 +75930 -0.0089111328125 +75931 0.268798828125 +75932 0.482818603515625 +75933 0.60369873046875 +75934 0.650421142578125 +75935 0.66400146484375 +75936 0.6414794921875 +75937 0.572540283203125 +75938 0.498138427734375 +75939 0.439453125 +75940 0.375518798828125 +75941 0.274505615234375 +75942 0.1087646484375 +75943 -0.099395751953125 +75944 -0.3182373046875 +75945 -0.5489501953125 +75946 -0.7738037109375 +75947 -0.86383056640625 +75948 -0.870391845703125 +75949 -0.86895751953125 +75950 -0.861053466796875 +75951 -0.765869140625 +75952 -0.5301513671875 +75953 -0.214691162109375 +75954 0.137359619140625 +75955 0.474822998046875 +75956 0.76239013671875 +75957 0.867462158203125 +75958 0.870361328125 +75959 0.86480712890625 +75960 0.831817626953125 +75961 0.677581787109375 +75962 0.495880126953125 +75963 0.30767822265625 +75964 0.116180419921875 +75965 -0.110748291015625 +75966 -0.381805419921875 +75967 -0.6572265625 +75968 -0.857421875 +75969 -0.870391845703125 +75970 -0.870391845703125 +75971 -0.86444091796875 +75972 -0.85723876953125 +75973 -0.790008544921875 +75974 -0.62847900390625 +75975 -0.3956298828125 +75976 -0.126708984375 +75977 0.150115966796875 +75978 0.424041748046875 +75979 0.670623779296875 +75980 0.854522705078125 +75981 0.866485595703125 +75982 0.86920166015625 +75983 0.8653564453125 +75984 0.857147216796875 +75985 0.766845703125 +75986 0.628509521484375 +75987 0.462127685546875 +75988 0.297210693359375 +75989 0.14862060546875 +75990 -0.00537109375 +75991 -0.15753173828125 +75992 -0.31304931640625 +75993 -0.48876953125 +75994 -0.6416015625 +75995 -0.751373291015625 +75996 -0.84619140625 +75997 -0.861297607421875 +75998 -0.863250732421875 +75999 -0.856597900390625 +76000 -0.7498779296875 +76001 -0.624542236328125 +76002 -0.47808837890625 +76003 -0.253387451171875 +76004 0.003692626953125 +76005 0.2257080078125 +76006 0.427154541015625 +76007 0.643218994140625 +76008 0.855926513671875 +76009 0.870361328125 +76010 0.870361328125 +76011 0.862762451171875 +76012 0.79669189453125 +76013 0.595794677734375 +76014 0.362152099609375 +76015 0.1270751953125 +76016 -0.086944580078125 +76017 -0.2784423828125 +76018 -0.484832763671875 +76019 -0.729583740234375 +76020 -0.86688232421875 +76021 -0.870391845703125 +76022 -0.86859130859375 +76023 -0.86279296875 +76024 -0.817962646484375 +76025 -0.6116943359375 +76026 -0.3128662109375 +76027 0.039398193359375 +76028 0.422821044921875 +76029 0.805145263671875 +76030 0.870361328125 +76031 0.870361328125 +76032 0.860015869140625 +76033 0.727935791015625 +76034 0.48114013671875 +76035 0.2059326171875 +76036 -0.06103515625 +76037 -0.29913330078125 +76038 -0.516204833984375 +76039 -0.7252197265625 +76040 -0.85980224609375 +76041 -0.870391845703125 +76042 -0.870391845703125 +76043 -0.858062744140625 +76044 -0.673004150390625 +76045 -0.42694091796875 +76046 -0.2100830078125 +76047 -0.0362548828125 +76048 0.10943603515625 +76049 0.23516845703125 +76050 0.373687744140625 +76051 0.517791748046875 +76052 0.602783203125 +76053 0.635711669921875 +76054 0.655181884765625 +76055 0.65948486328125 +76056 0.651275634765625 +76057 0.61846923828125 +76058 0.53753662109375 +76059 0.404144287109375 +76060 0.22186279296875 +76061 0.003997802734375 +76062 -0.22100830078125 +76063 -0.42449951171875 +76064 -0.579833984375 +76065 -0.641876220703125 +76066 -0.6177978515625 +76067 -0.575531005859375 +76068 -0.526336669921875 +76069 -0.42645263671875 +76070 -0.2581787109375 +76071 -0.068695068359375 +76072 0.09222412109375 +76073 0.232147216796875 +76074 0.3509521484375 +76075 0.410064697265625 +76076 0.372955322265625 +76077 0.2554931640625 +76078 0.10711669921875 +76079 -0.052886962890625 +76080 -0.186279296875 +76081 -0.23291015625 +76082 -0.209442138671875 +76083 -0.174163818359375 +76084 -0.126739501953125 +76085 -0.048126220703125 +76086 0.0426025390625 +76087 0.10748291015625 +76088 0.1409912109375 +76089 0.19708251953125 +76090 0.273651123046875 +76091 0.31768798828125 +76092 0.341094970703125 +76093 0.368011474609375 +76094 0.37249755859375 +76095 0.30072021484375 +76096 0.1517333984375 +76097 -0.01470947265625 +76098 -0.1883544921875 +76099 -0.372711181640625 +76100 -0.51397705078125 +76101 -0.57177734375 +76102 -0.53948974609375 +76103 -0.43511962890625 +76104 -0.2962646484375 +76105 -0.161102294921875 +76106 -0.0435791015625 +76107 0.060394287109375 +76108 0.13665771484375 +76109 0.170135498046875 +76110 0.16552734375 +76111 0.15728759765625 +76112 0.150787353515625 +76113 0.12200927734375 +76114 0.080108642578125 +76115 0.05126953125 +76116 0.062896728515625 +76117 0.09271240234375 +76118 0.092987060546875 +76119 0.07855224609375 +76120 0.06427001953125 +76121 0.0347900390625 +76122 -0.01171875 +76123 -0.056060791015625 +76124 -0.055511474609375 +76125 -0.010467529296875 +76126 0.02508544921875 +76127 0.025665283203125 +76128 0.017333984375 +76129 0.00189208984375 +76130 -0.03173828125 +76131 -0.071502685546875 +76132 -0.13543701171875 +76133 -0.219970703125 +76134 -0.300506591796875 +76135 -0.376312255859375 +76136 -0.416107177734375 +76137 -0.371124267578125 +76138 -0.242279052734375 +76139 -0.069732666015625 +76140 0.125640869140625 +76141 0.31268310546875 +76142 0.45501708984375 +76143 0.554779052734375 +76144 0.61065673828125 +76145 0.610931396484375 +76146 0.531463623046875 +76147 0.3883056640625 +76148 0.23468017578125 +76149 0.095245361328125 +76150 -0.00396728515625 +76151 -0.04852294921875 +76152 -0.055145263671875 +76153 -0.0758056640625 +76154 -0.138702392578125 +76155 -0.209197998046875 +76156 -0.289031982421875 +76157 -0.37884521484375 +76158 -0.456329345703125 +76159 -0.51641845703125 +76160 -0.519287109375 +76161 -0.458251953125 +76162 -0.384796142578125 +76163 -0.323699951171875 +76164 -0.269287109375 +76165 -0.1951904296875 +76166 -0.100006103515625 +76167 -0.01055908203125 +76168 0.1033935546875 +76169 0.24908447265625 +76170 0.373199462890625 +76171 0.45806884765625 +76172 0.511474609375 +76173 0.565399169921875 +76174 0.61138916015625 +76175 0.5897216796875 +76176 0.4906005859375 +76177 0.33148193359375 +76178 0.147796630859375 +76179 -0.01873779296875 +76180 -0.140289306640625 +76181 -0.191986083984375 +76182 -0.184295654296875 +76183 -0.161834716796875 +76184 -0.166595458984375 +76185 -0.19390869140625 +76186 -0.22442626953125 +76187 -0.279754638671875 +76188 -0.3389892578125 +76189 -0.3543701171875 +76190 -0.348175048828125 +76191 -0.32598876953125 +76192 -0.2581787109375 +76193 -0.139801025390625 +76194 0.014617919921875 +76195 0.144378662109375 +76196 0.221038818359375 +76197 0.27069091796875 +76198 0.294036865234375 +76199 0.311767578125 +76200 0.339141845703125 +76201 0.360260009765625 +76202 0.360504150390625 +76203 0.308380126953125 +76204 0.18170166015625 +76205 0.0047607421875 +76206 -0.17559814453125 +76207 -0.3143310546875 +76208 -0.36785888671875 +76209 -0.36248779296875 +76210 -0.343536376953125 +76211 -0.3018798828125 +76212 -0.231414794921875 +76213 -0.117645263671875 +76214 0.007049560546875 +76215 0.087982177734375 +76216 0.13946533203125 +76217 0.17425537109375 +76218 0.188201904296875 +76219 0.171234130859375 +76220 0.118438720703125 +76221 0.05706787109375 +76222 -0.010711669921875 +76223 -0.0914306640625 +76224 -0.162322998046875 +76225 -0.194549560546875 +76226 -0.1492919921875 +76227 -0.02166748046875 +76228 0.124053955078125 +76229 0.211151123046875 +76230 0.240447998046875 +76231 0.242218017578125 +76232 0.2257080078125 +76233 0.194366455078125 +76234 0.115509033203125 +76235 0.0128173828125 +76236 -0.053802490234375 +76237 -0.110626220703125 +76238 -0.199493408203125 +76239 -0.29437255859375 +76240 -0.33221435546875 +76241 -0.27972412109375 +76242 -0.185333251953125 +76243 -0.128204345703125 +76244 -0.115692138671875 +76245 -0.116455078125 +76246 -0.105926513671875 +76247 -0.053955078125 +76248 0.048797607421875 +76249 0.157318115234375 +76250 0.212005615234375 +76251 0.218475341796875 +76252 0.23724365234375 +76253 0.30535888671875 +76254 0.38128662109375 +76255 0.404449462890625 +76256 0.3944091796875 +76257 0.3885498046875 +76258 0.362640380859375 +76259 0.27362060546875 +76260 0.11712646484375 +76261 -0.054901123046875 +76262 -0.19085693359375 +76263 -0.28570556640625 +76264 -0.339263916015625 +76265 -0.3775634765625 +76266 -0.445709228515625 +76267 -0.535064697265625 +76268 -0.629058837890625 +76269 -0.697601318359375 +76270 -0.70391845703125 +76271 -0.6424560546875 +76272 -0.491241455078125 +76273 -0.265716552734375 +76274 -0.023712158203125 +76275 0.201751708984375 +76276 0.375823974609375 +76277 0.485076904296875 +76278 0.56884765625 +76279 0.634765625 +76280 0.63763427734375 +76281 0.5660400390625 +76282 0.4720458984375 +76283 0.40692138671875 +76284 0.3778076171875 +76285 0.376953125 +76286 0.371978759765625 +76287 0.313140869140625 +76288 0.184417724609375 +76289 0.011199951171875 +76290 -0.171051025390625 +76291 -0.33740234375 +76292 -0.47198486328125 +76293 -0.560394287109375 +76294 -0.58056640625 +76295 -0.54754638671875 +76296 -0.508575439453125 +76297 -0.459503173828125 +76298 -0.394378662109375 +76299 -0.35260009765625 +76300 -0.31170654296875 +76301 -0.197418212890625 +76302 -0.007965087890625 +76303 0.207489013671875 +76304 0.409210205078125 +76305 0.57208251953125 +76306 0.66595458984375 +76307 0.65875244140625 +76308 0.56744384765625 +76309 0.431396484375 +76310 0.29443359375 +76311 0.182464599609375 +76312 0.06365966796875 +76313 -0.075958251953125 +76314 -0.189422607421875 +76315 -0.271942138671875 +76316 -0.342529296875 +76317 -0.364166259765625 +76318 -0.327239990234375 +76319 -0.2769775390625 +76320 -0.253692626953125 +76321 -0.24365234375 +76322 -0.1983642578125 +76323 -0.116241455078125 +76324 -0.036834716796875 +76325 0.034881591796875 +76326 0.09124755859375 +76327 0.10888671875 +76328 0.125518798828125 +76329 0.15771484375 +76330 0.17828369140625 +76331 0.17108154296875 +76332 0.129974365234375 +76333 0.082427978515625 +76334 0.027679443359375 +76335 -0.065643310546875 +76336 -0.15936279296875 +76337 -0.21307373046875 +76338 -0.234649658203125 +76339 -0.2001953125 +76340 -0.119171142578125 +76341 -0.024749755859375 +76342 0.085784912109375 +76343 0.178131103515625 +76344 0.215576171875 +76345 0.211456298828125 +76346 0.17523193359375 +76347 0.128753662109375 +76348 0.1019287109375 +76349 0.0743408203125 +76350 0.04327392578125 +76351 0.038177490234375 +76352 0.076263427734375 +76353 0.14105224609375 +76354 0.186431884765625 +76355 0.188812255859375 +76356 0.1390380859375 +76357 0.041778564453125 +76358 -0.079437255859375 +76359 -0.219390869140625 +76360 -0.367828369140625 +76361 -0.494873046875 +76362 -0.556243896484375 +76363 -0.508697509765625 +76364 -0.3756103515625 +76365 -0.218902587890625 +76366 -0.063751220703125 +76367 0.091552734375 +76368 0.23602294921875 +76369 0.342987060546875 +76370 0.39520263671875 +76371 0.389373779296875 +76372 0.324249267578125 +76373 0.224090576171875 +76374 0.124267578125 +76375 0.037078857421875 +76376 -0.010101318359375 +76377 -0.019439697265625 +76378 -0.022796630859375 +76379 -0.001556396484375 +76380 0.056304931640625 +76381 0.106719970703125 +76382 0.096893310546875 +76383 0.042694091796875 +76384 -0.018035888671875 +76385 -0.07586669921875 +76386 -0.11944580078125 +76387 -0.15972900390625 +76388 -0.202606201171875 +76389 -0.24859619140625 +76390 -0.30517578125 +76391 -0.36212158203125 +76392 -0.39141845703125 +76393 -0.35528564453125 +76394 -0.249969482421875 +76395 -0.092864990234375 +76396 0.08905029296875 +76397 0.2352294921875 +76398 0.318817138671875 +76399 0.358642578125 +76400 0.347747802734375 +76401 0.28564453125 +76402 0.223175048828125 +76403 0.196746826171875 +76404 0.179840087890625 +76405 0.155548095703125 +76406 0.151214599609375 +76407 0.156951904296875 +76408 0.13177490234375 +76409 0.100799560546875 +76410 0.087127685546875 +76411 0.05487060546875 +76412 -0.009002685546875 +76413 -0.10400390625 +76414 -0.229400634765625 +76415 -0.35552978515625 +76416 -0.441925048828125 +76417 -0.473846435546875 +76418 -0.464813232421875 +76419 -0.419097900390625 +76420 -0.334320068359375 +76421 -0.227935791015625 +76422 -0.12347412109375 +76423 -0.02764892578125 +76424 0.077667236328125 +76425 0.2132568359375 +76426 0.38885498046875 +76427 0.582794189453125 +76428 0.734039306640625 +76429 0.800140380859375 +76430 0.7783203125 +76431 0.6651611328125 +76432 0.45965576171875 +76433 0.199188232421875 +76434 -0.050689697265625 +76435 -0.23297119140625 +76436 -0.33013916015625 +76437 -0.368408203125 +76438 -0.378936767578125 +76439 -0.376983642578125 +76440 -0.37969970703125 +76441 -0.391510009765625 +76442 -0.385345458984375 +76443 -0.3419189453125 +76444 -0.28289794921875 +76445 -0.251617431640625 +76446 -0.266143798828125 +76447 -0.273345947265625 +76448 -0.216796875 +76449 -0.128265380859375 +76450 -0.068145751953125 +76451 -0.0430908203125 +76452 -0.024444580078125 +76453 0.020721435546875 +76454 0.124481201171875 +76455 0.25787353515625 +76456 0.379119873046875 +76457 0.47991943359375 +76458 0.5281982421875 +76459 0.511138916015625 +76460 0.456207275390625 +76461 0.407470703125 +76462 0.383758544921875 +76463 0.35687255859375 +76464 0.31182861328125 +76465 0.250885009765625 +76466 0.1654052734375 +76467 0.035247802734375 +76468 -0.142059326171875 +76469 -0.33563232421875 +76470 -0.5345458984375 +76471 -0.72186279296875 +76472 -0.836669921875 +76473 -0.8326416015625 +76474 -0.7296142578125 +76475 -0.582550048828125 +76476 -0.440093994140625 +76477 -0.324310302734375 +76478 -0.20147705078125 +76479 -0.044647216796875 +76480 0.103973388671875 +76481 0.202392578125 +76482 0.264495849609375 +76483 0.338897705078125 +76484 0.443817138671875 +76485 0.545074462890625 +76486 0.6173095703125 +76487 0.6524658203125 +76488 0.66339111328125 +76489 0.6561279296875 +76490 0.606781005859375 +76491 0.501190185546875 +76492 0.352783203125 +76493 0.176544189453125 +76494 -0.034820556640625 +76495 -0.258209228515625 +76496 -0.44244384765625 +76497 -0.5753173828125 +76498 -0.65203857421875 +76499 -0.641632080078125 +76500 -0.562164306640625 +76501 -0.458038330078125 +76502 -0.350555419921875 +76503 -0.260528564453125 +76504 -0.192108154296875 +76505 -0.141937255859375 +76506 -0.1021728515625 +76507 -0.062896728515625 +76508 -0.011932373046875 +76509 0.062835693359375 +76510 0.148712158203125 +76511 0.241729736328125 +76512 0.34912109375 +76513 0.457305908203125 +76514 0.54388427734375 +76515 0.5728759765625 +76516 0.506591796875 +76517 0.351226806640625 +76518 0.146514892578125 +76519 -0.05523681640625 +76520 -0.21624755859375 +76521 -0.334930419921875 +76522 -0.402984619140625 +76523 -0.4412841796875 +76524 -0.49578857421875 +76525 -0.5601806640625 +76526 -0.600738525390625 +76527 -0.584228515625 +76528 -0.47930908203125 +76529 -0.27935791015625 +76530 -0.0089111328125 +76531 0.268798828125 +76532 0.482818603515625 +76533 0.60369873046875 +76534 0.650421142578125 +76535 0.66400146484375 +76536 0.6414794921875 +76537 0.572540283203125 +76538 0.498138427734375 +76539 0.439453125 +76540 0.375518798828125 +76541 0.274505615234375 +76542 0.1087646484375 +76543 -0.099395751953125 +76544 -0.3182373046875 +76545 -0.5489501953125 +76546 -0.7738037109375 +76547 -0.86383056640625 +76548 -0.870391845703125 +76549 -0.86895751953125 +76550 -0.861053466796875 +76551 -0.765869140625 +76552 -0.5301513671875 +76553 -0.214691162109375 +76554 0.137359619140625 +76555 0.474822998046875 +76556 0.76239013671875 +76557 0.867462158203125 +76558 0.870361328125 +76559 0.86480712890625 +76560 0.831817626953125 +76561 0.677581787109375 +76562 0.495880126953125 +76563 0.30767822265625 +76564 0.116180419921875 +76565 -0.110748291015625 +76566 -0.381805419921875 +76567 -0.6572265625 +76568 -0.857421875 +76569 -0.870391845703125 +76570 -0.870391845703125 +76571 -0.86444091796875 +76572 -0.85723876953125 +76573 -0.790008544921875 +76574 -0.62847900390625 +76575 -0.3956298828125 +76576 -0.126708984375 +76577 0.150115966796875 +76578 0.424041748046875 +76579 0.670623779296875 +76580 0.854522705078125 +76581 0.866485595703125 +76582 0.86920166015625 +76583 0.8653564453125 +76584 0.857147216796875 +76585 0.766845703125 +76586 0.628509521484375 +76587 0.462127685546875 +76588 0.297210693359375 +76589 0.14862060546875 +76590 -0.00537109375 +76591 -0.15753173828125 +76592 -0.31304931640625 +76593 -0.48876953125 +76594 -0.6416015625 +76595 -0.751373291015625 +76596 -0.84619140625 +76597 -0.861297607421875 +76598 -0.863250732421875 +76599 -0.856597900390625 +76600 -0.7498779296875 +76601 -0.624542236328125 +76602 -0.47808837890625 +76603 -0.253387451171875 +76604 0.003692626953125 +76605 0.2257080078125 +76606 0.427154541015625 +76607 0.643218994140625 +76608 0.855926513671875 +76609 0.870361328125 +76610 0.870361328125 +76611 0.862762451171875 +76612 0.79669189453125 +76613 0.595794677734375 +76614 0.362152099609375 +76615 0.1270751953125 +76616 -0.086944580078125 +76617 -0.2784423828125 +76618 -0.484832763671875 +76619 -0.729583740234375 +76620 -0.86688232421875 +76621 -0.870391845703125 +76622 -0.86859130859375 +76623 -0.86279296875 +76624 -0.817962646484375 +76625 -0.6116943359375 +76626 -0.3128662109375 +76627 0.039398193359375 +76628 0.422821044921875 +76629 0.805145263671875 +76630 0.870361328125 +76631 0.870361328125 +76632 0.860015869140625 +76633 0.727935791015625 +76634 0.48114013671875 +76635 0.2059326171875 +76636 -0.06103515625 +76637 -0.29913330078125 +76638 -0.516204833984375 +76639 -0.7252197265625 +76640 -0.85980224609375 +76641 -0.870391845703125 +76642 -0.870391845703125 +76643 -0.858062744140625 +76644 -0.673004150390625 +76645 -0.42694091796875 +76646 -0.2100830078125 +76647 -0.0362548828125 +76648 0.10943603515625 +76649 0.23516845703125 +76650 0.373687744140625 +76651 0.517791748046875 +76652 0.602783203125 +76653 0.635711669921875 +76654 0.655181884765625 +76655 0.65948486328125 +76656 0.651275634765625 +76657 0.61846923828125 +76658 0.53753662109375 +76659 0.404144287109375 +76660 0.22186279296875 +76661 0.003997802734375 +76662 -0.22100830078125 +76663 -0.42449951171875 +76664 -0.579833984375 +76665 -0.641876220703125 +76666 -0.6177978515625 +76667 -0.575531005859375 +76668 -0.526336669921875 +76669 -0.42645263671875 +76670 -0.2581787109375 +76671 -0.068695068359375 +76672 0.09222412109375 +76673 0.232147216796875 +76674 0.3509521484375 +76675 0.410064697265625 +76676 0.372955322265625 +76677 0.2554931640625 +76678 0.10711669921875 +76679 -0.052886962890625 +76680 -0.186279296875 +76681 -0.23291015625 +76682 -0.209442138671875 +76683 -0.174163818359375 +76684 -0.126739501953125 +76685 -0.048126220703125 +76686 0.0426025390625 +76687 0.10748291015625 +76688 0.1409912109375 +76689 0.19708251953125 +76690 0.273651123046875 +76691 0.31768798828125 +76692 0.341094970703125 +76693 0.368011474609375 +76694 0.37249755859375 +76695 0.30072021484375 +76696 0.1517333984375 +76697 -0.01470947265625 +76698 -0.1883544921875 +76699 -0.372711181640625 +76700 -0.51397705078125 +76701 -0.57177734375 +76702 -0.53948974609375 +76703 -0.43511962890625 +76704 -0.2962646484375 +76705 -0.161102294921875 +76706 -0.0435791015625 +76707 0.060394287109375 +76708 0.13665771484375 +76709 0.170135498046875 +76710 0.16552734375 +76711 0.15728759765625 +76712 0.150787353515625 +76713 0.12200927734375 +76714 0.080108642578125 +76715 0.05126953125 +76716 0.062896728515625 +76717 0.09271240234375 +76718 0.092987060546875 +76719 0.07855224609375 +76720 0.06427001953125 +76721 0.0347900390625 +76722 -0.01171875 +76723 -0.056060791015625 +76724 -0.055511474609375 +76725 -0.010467529296875 +76726 0.02508544921875 +76727 0.025665283203125 +76728 0.017333984375 +76729 0.00189208984375 +76730 -0.03173828125 +76731 -0.071502685546875 +76732 -0.13543701171875 +76733 -0.219970703125 +76734 -0.300506591796875 +76735 -0.376312255859375 +76736 -0.416107177734375 +76737 -0.371124267578125 +76738 -0.242279052734375 +76739 -0.069732666015625 +76740 0.125640869140625 +76741 0.31268310546875 +76742 0.45501708984375 +76743 0.554779052734375 +76744 0.61065673828125 +76745 0.610931396484375 +76746 0.531463623046875 +76747 0.3883056640625 +76748 0.23468017578125 +76749 0.095245361328125 +76750 -0.00396728515625 +76751 -0.04852294921875 +76752 -0.055145263671875 +76753 -0.0758056640625 +76754 -0.138702392578125 +76755 -0.209197998046875 +76756 -0.289031982421875 +76757 -0.37884521484375 +76758 -0.456329345703125 +76759 -0.51641845703125 +76760 -0.519287109375 +76761 -0.458251953125 +76762 -0.384796142578125 +76763 -0.323699951171875 +76764 -0.269287109375 +76765 -0.1951904296875 +76766 -0.100006103515625 +76767 -0.01055908203125 +76768 0.1033935546875 +76769 0.24908447265625 +76770 0.373199462890625 +76771 0.45806884765625 +76772 0.511474609375 +76773 0.565399169921875 +76774 0.61138916015625 +76775 0.5897216796875 +76776 0.4906005859375 +76777 0.33148193359375 +76778 0.147796630859375 +76779 -0.01873779296875 +76780 -0.140289306640625 +76781 -0.191986083984375 +76782 -0.184295654296875 +76783 -0.161834716796875 +76784 -0.166595458984375 +76785 -0.19390869140625 +76786 -0.22442626953125 +76787 -0.279754638671875 +76788 -0.3389892578125 +76789 -0.3543701171875 +76790 -0.348175048828125 +76791 -0.32598876953125 +76792 -0.2581787109375 +76793 -0.139801025390625 +76794 0.014617919921875 +76795 0.144378662109375 +76796 0.221038818359375 +76797 0.27069091796875 +76798 0.294036865234375 +76799 0.311767578125 +76800 0.339141845703125 +76801 0.360260009765625 +76802 0.360504150390625 +76803 0.308380126953125 +76804 0.18170166015625 +76805 0.0047607421875 +76806 -0.17559814453125 +76807 -0.3143310546875 +76808 -0.36785888671875 +76809 -0.36248779296875 +76810 -0.343536376953125 +76811 -0.3018798828125 +76812 -0.231414794921875 +76813 -0.117645263671875 +76814 0.007049560546875 +76815 0.087982177734375 +76816 0.13946533203125 +76817 0.17425537109375 +76818 0.188201904296875 +76819 0.171234130859375 +76820 0.118438720703125 +76821 0.05706787109375 +76822 -0.010711669921875 +76823 -0.0914306640625 +76824 -0.162322998046875 +76825 -0.194549560546875 +76826 -0.1492919921875 +76827 -0.02166748046875 +76828 0.124053955078125 +76829 0.211151123046875 +76830 0.240447998046875 +76831 0.242218017578125 +76832 0.2257080078125 +76833 0.194366455078125 +76834 0.115509033203125 +76835 0.0128173828125 +76836 -0.053802490234375 +76837 -0.110626220703125 +76838 -0.199493408203125 +76839 -0.29437255859375 +76840 -0.33221435546875 +76841 -0.27972412109375 +76842 -0.185333251953125 +76843 -0.128204345703125 +76844 -0.115692138671875 +76845 -0.116455078125 +76846 -0.105926513671875 +76847 -0.053955078125 +76848 0.048797607421875 +76849 0.157318115234375 +76850 0.212005615234375 +76851 0.218475341796875 +76852 0.23724365234375 +76853 0.30535888671875 +76854 0.38128662109375 +76855 0.404449462890625 +76856 0.3944091796875 +76857 0.3885498046875 +76858 0.362640380859375 +76859 0.27362060546875 +76860 0.11712646484375 +76861 -0.054901123046875 +76862 -0.19085693359375 +76863 -0.28570556640625 +76864 -0.339263916015625 +76865 -0.3775634765625 +76866 -0.445709228515625 +76867 -0.535064697265625 +76868 -0.629058837890625 +76869 -0.697601318359375 +76870 -0.70391845703125 +76871 -0.6424560546875 +76872 -0.491241455078125 +76873 -0.265716552734375 +76874 -0.023712158203125 +76875 0.201751708984375 +76876 0.375823974609375 +76877 0.485076904296875 +76878 0.56884765625 +76879 0.634765625 +76880 0.63763427734375 +76881 0.5660400390625 +76882 0.4720458984375 +76883 0.40692138671875 +76884 0.3778076171875 +76885 0.376953125 +76886 0.371978759765625 +76887 0.313140869140625 +76888 0.184417724609375 +76889 0.011199951171875 +76890 -0.171051025390625 +76891 -0.33740234375 +76892 -0.47198486328125 +76893 -0.560394287109375 +76894 -0.58056640625 +76895 -0.54754638671875 +76896 -0.508575439453125 +76897 -0.459503173828125 +76898 -0.394378662109375 +76899 -0.35260009765625 +76900 -0.31170654296875 +76901 -0.197418212890625 +76902 -0.007965087890625 +76903 0.207489013671875 +76904 0.409210205078125 +76905 0.57208251953125 +76906 0.66595458984375 +76907 0.65875244140625 +76908 0.56744384765625 +76909 0.431396484375 +76910 0.29443359375 +76911 0.182464599609375 +76912 0.06365966796875 +76913 -0.075958251953125 +76914 -0.189422607421875 +76915 -0.271942138671875 +76916 -0.342529296875 +76917 -0.364166259765625 +76918 -0.327239990234375 +76919 -0.2769775390625 +76920 -0.253692626953125 +76921 -0.24365234375 +76922 -0.1983642578125 +76923 -0.116241455078125 +76924 -0.036834716796875 +76925 0.034881591796875 +76926 0.09124755859375 +76927 0.10888671875 +76928 0.125518798828125 +76929 0.15771484375 +76930 0.17828369140625 +76931 0.17108154296875 +76932 0.129974365234375 +76933 0.082427978515625 +76934 0.027679443359375 +76935 -0.065643310546875 +76936 -0.15936279296875 +76937 -0.21307373046875 +76938 -0.234649658203125 +76939 -0.2001953125 +76940 -0.119171142578125 +76941 -0.024749755859375 +76942 0.085784912109375 +76943 0.178131103515625 +76944 0.215576171875 +76945 0.211456298828125 +76946 0.17523193359375 +76947 0.128753662109375 +76948 0.1019287109375 +76949 0.0743408203125 +76950 0.04327392578125 +76951 0.038177490234375 +76952 0.076263427734375 +76953 0.14105224609375 +76954 0.186431884765625 +76955 0.188812255859375 +76956 0.1390380859375 +76957 0.041778564453125 +76958 -0.079437255859375 +76959 -0.219390869140625 +76960 -0.367828369140625 +76961 -0.494873046875 +76962 -0.556243896484375 +76963 -0.508697509765625 +76964 -0.3756103515625 +76965 -0.218902587890625 +76966 -0.063751220703125 +76967 0.091552734375 +76968 0.23602294921875 +76969 0.342987060546875 +76970 0.39520263671875 +76971 0.389373779296875 +76972 0.324249267578125 +76973 0.224090576171875 +76974 0.124267578125 +76975 0.037078857421875 +76976 -0.010101318359375 +76977 -0.019439697265625 +76978 -0.022796630859375 +76979 -0.001556396484375 +76980 0.056304931640625 +76981 0.106719970703125 +76982 0.096893310546875 +76983 0.042694091796875 +76984 -0.018035888671875 +76985 -0.07586669921875 +76986 -0.11944580078125 +76987 -0.15972900390625 +76988 -0.202606201171875 +76989 -0.24859619140625 +76990 -0.30517578125 +76991 -0.36212158203125 +76992 -0.39141845703125 +76993 -0.35528564453125 +76994 -0.249969482421875 +76995 -0.092864990234375 +76996 0.08905029296875 +76997 0.2352294921875 +76998 0.318817138671875 +76999 0.358642578125 +77000 0.347747802734375 +77001 0.28564453125 +77002 0.223175048828125 +77003 0.196746826171875 +77004 0.179840087890625 +77005 0.155548095703125 +77006 0.151214599609375 +77007 0.156951904296875 +77008 0.13177490234375 +77009 0.100799560546875 +77010 0.087127685546875 +77011 0.05487060546875 +77012 -0.009002685546875 +77013 -0.10400390625 +77014 -0.229400634765625 +77015 -0.35552978515625 +77016 -0.441925048828125 +77017 -0.473846435546875 +77018 -0.464813232421875 +77019 -0.419097900390625 +77020 -0.334320068359375 +77021 -0.227935791015625 +77022 -0.12347412109375 +77023 -0.02764892578125 +77024 0.077667236328125 +77025 0.2132568359375 +77026 0.38885498046875 +77027 0.582794189453125 +77028 0.734039306640625 +77029 0.800140380859375 +77030 0.7783203125 +77031 0.6651611328125 +77032 0.45965576171875 +77033 0.199188232421875 +77034 -0.050689697265625 +77035 -0.23297119140625 +77036 -0.33013916015625 +77037 -0.368408203125 +77038 -0.378936767578125 +77039 -0.376983642578125 +77040 -0.37969970703125 +77041 -0.391510009765625 +77042 -0.385345458984375 +77043 -0.3419189453125 +77044 -0.28289794921875 +77045 -0.251617431640625 +77046 -0.266143798828125 +77047 -0.273345947265625 +77048 -0.216796875 +77049 -0.128265380859375 +77050 -0.068145751953125 +77051 -0.0430908203125 +77052 -0.024444580078125 +77053 0.020721435546875 +77054 0.124481201171875 +77055 0.25787353515625 +77056 0.379119873046875 +77057 0.47991943359375 +77058 0.5281982421875 +77059 0.511138916015625 +77060 0.456207275390625 +77061 0.407470703125 +77062 0.383758544921875 +77063 0.35687255859375 +77064 0.31182861328125 +77065 0.250885009765625 +77066 0.1654052734375 +77067 0.035247802734375 +77068 -0.142059326171875 +77069 -0.33563232421875 +77070 -0.5345458984375 +77071 -0.72186279296875 +77072 -0.836669921875 +77073 -0.8326416015625 +77074 -0.7296142578125 +77075 -0.582550048828125 +77076 -0.440093994140625 +77077 -0.324310302734375 +77078 -0.20147705078125 +77079 -0.044647216796875 +77080 0.103973388671875 +77081 0.202392578125 +77082 0.264495849609375 +77083 0.338897705078125 +77084 0.443817138671875 +77085 0.545074462890625 +77086 0.6173095703125 +77087 0.6524658203125 +77088 0.66339111328125 +77089 0.6561279296875 +77090 0.606781005859375 +77091 0.501190185546875 +77092 0.352783203125 +77093 0.176544189453125 +77094 -0.034820556640625 +77095 -0.258209228515625 +77096 -0.44244384765625 +77097 -0.5753173828125 +77098 -0.65203857421875 +77099 -0.641632080078125 +77100 -0.562164306640625 +77101 -0.458038330078125 +77102 -0.350555419921875 +77103 -0.260528564453125 +77104 -0.192108154296875 +77105 -0.141937255859375 +77106 -0.1021728515625 +77107 -0.062896728515625 +77108 -0.011932373046875 +77109 0.062835693359375 +77110 0.148712158203125 +77111 0.241729736328125 +77112 0.34912109375 +77113 0.457305908203125 +77114 0.54388427734375 +77115 0.5728759765625 +77116 0.506591796875 +77117 0.351226806640625 +77118 0.146514892578125 +77119 -0.05523681640625 +77120 -0.21624755859375 +77121 -0.334930419921875 +77122 -0.402984619140625 +77123 -0.4412841796875 +77124 -0.49578857421875 +77125 -0.5601806640625 +77126 -0.600738525390625 +77127 -0.584228515625 +77128 -0.47930908203125 +77129 -0.27935791015625 +77130 -0.0089111328125 +77131 0.268798828125 +77132 0.482818603515625 +77133 0.60369873046875 +77134 0.650421142578125 +77135 0.66400146484375 +77136 0.6414794921875 +77137 0.572540283203125 +77138 0.498138427734375 +77139 0.439453125 +77140 0.375518798828125 +77141 0.274505615234375 +77142 0.1087646484375 +77143 -0.099395751953125 +77144 -0.3182373046875 +77145 -0.5489501953125 +77146 -0.7738037109375 +77147 -0.86383056640625 +77148 -0.870391845703125 +77149 -0.86895751953125 +77150 -0.861053466796875 +77151 -0.765869140625 +77152 -0.5301513671875 +77153 -0.214691162109375 +77154 0.137359619140625 +77155 0.474822998046875 +77156 0.76239013671875 +77157 0.867462158203125 +77158 0.870361328125 +77159 0.86480712890625 +77160 0.831817626953125 +77161 0.677581787109375 +77162 0.495880126953125 +77163 0.30767822265625 +77164 0.116180419921875 +77165 -0.110748291015625 +77166 -0.381805419921875 +77167 -0.6572265625 +77168 -0.857421875 +77169 -0.870391845703125 +77170 -0.870391845703125 +77171 -0.86444091796875 +77172 -0.85723876953125 +77173 -0.790008544921875 +77174 -0.62847900390625 +77175 -0.3956298828125 +77176 -0.126708984375 +77177 0.150115966796875 +77178 0.424041748046875 +77179 0.670623779296875 +77180 0.854522705078125 +77181 0.866485595703125 +77182 0.86920166015625 +77183 0.8653564453125 +77184 0.857147216796875 +77185 0.766845703125 +77186 0.628509521484375 +77187 0.462127685546875 +77188 0.297210693359375 +77189 0.14862060546875 +77190 -0.00537109375 +77191 -0.15753173828125 +77192 -0.31304931640625 +77193 -0.48876953125 +77194 -0.6416015625 +77195 -0.751373291015625 +77196 -0.84619140625 +77197 -0.861297607421875 +77198 -0.863250732421875 +77199 -0.856597900390625 +77200 -0.7498779296875 +77201 -0.624542236328125 +77202 -0.47808837890625 +77203 -0.253387451171875 +77204 0.003692626953125 +77205 0.2257080078125 +77206 0.427154541015625 +77207 0.643218994140625 +77208 0.855926513671875 +77209 0.870361328125 +77210 0.870361328125 +77211 0.862762451171875 +77212 0.79669189453125 +77213 0.595794677734375 +77214 0.362152099609375 +77215 0.1270751953125 +77216 -0.086944580078125 +77217 -0.2784423828125 +77218 -0.484832763671875 +77219 -0.729583740234375 +77220 -0.86688232421875 +77221 -0.870391845703125 +77222 -0.86859130859375 +77223 -0.86279296875 +77224 -0.817962646484375 +77225 -0.6116943359375 +77226 -0.3128662109375 +77227 0.039398193359375 +77228 0.422821044921875 +77229 0.805145263671875 +77230 0.870361328125 +77231 0.870361328125 +77232 0.860015869140625 +77233 0.727935791015625 +77234 0.48114013671875 +77235 0.2059326171875 +77236 -0.06103515625 +77237 -0.29913330078125 +77238 -0.516204833984375 +77239 -0.7252197265625 +77240 -0.85980224609375 +77241 -0.870391845703125 +77242 -0.870391845703125 +77243 -0.858062744140625 +77244 -0.673004150390625 +77245 -0.42694091796875 +77246 -0.2100830078125 +77247 -0.0362548828125 +77248 0.10943603515625 +77249 0.23516845703125 +77250 0.373687744140625 +77251 0.517791748046875 +77252 0.602783203125 +77253 0.635711669921875 +77254 0.655181884765625 +77255 0.65948486328125 +77256 0.651275634765625 +77257 0.61846923828125 +77258 0.53753662109375 +77259 0.404144287109375 +77260 0.22186279296875 +77261 0.003997802734375 +77262 -0.22100830078125 +77263 -0.42449951171875 +77264 -0.579833984375 +77265 -0.641876220703125 +77266 -0.6177978515625 +77267 -0.575531005859375 +77268 -0.526336669921875 +77269 -0.42645263671875 +77270 -0.2581787109375 +77271 -0.068695068359375 +77272 0.09222412109375 +77273 0.232147216796875 +77274 0.3509521484375 +77275 0.410064697265625 +77276 0.372955322265625 +77277 0.2554931640625 +77278 0.10711669921875 +77279 -0.052886962890625 +77280 -0.186279296875 +77281 -0.23291015625 +77282 -0.209442138671875 +77283 -0.174163818359375 +77284 -0.126739501953125 +77285 -0.048126220703125 +77286 0.0426025390625 +77287 0.10748291015625 +77288 0.1409912109375 +77289 0.19708251953125 +77290 0.273651123046875 +77291 0.31768798828125 +77292 0.341094970703125 +77293 0.368011474609375 +77294 0.37249755859375 +77295 0.30072021484375 +77296 0.1517333984375 +77297 -0.01470947265625 +77298 -0.1883544921875 +77299 -0.372711181640625 +77300 -0.51397705078125 +77301 -0.57177734375 +77302 -0.53948974609375 +77303 -0.43511962890625 +77304 -0.2962646484375 +77305 -0.161102294921875 +77306 -0.0435791015625 +77307 0.060394287109375 +77308 0.13665771484375 +77309 0.170135498046875 +77310 0.16552734375 +77311 0.15728759765625 +77312 0.150787353515625 +77313 0.12200927734375 +77314 0.080108642578125 +77315 0.05126953125 +77316 0.062896728515625 +77317 0.09271240234375 +77318 0.092987060546875 +77319 0.07855224609375 +77320 0.06427001953125 +77321 0.0347900390625 +77322 -0.01171875 +77323 -0.056060791015625 +77324 -0.055511474609375 +77325 -0.010467529296875 +77326 0.02508544921875 +77327 0.025665283203125 +77328 0.017333984375 +77329 0.00189208984375 +77330 -0.03173828125 +77331 -0.071502685546875 +77332 -0.13543701171875 +77333 -0.219970703125 +77334 -0.300506591796875 +77335 -0.376312255859375 +77336 -0.416107177734375 +77337 -0.371124267578125 +77338 -0.242279052734375 +77339 -0.069732666015625 +77340 0.125640869140625 +77341 0.31268310546875 +77342 0.45501708984375 +77343 0.554779052734375 +77344 0.61065673828125 +77345 0.610931396484375 +77346 0.531463623046875 +77347 0.3883056640625 +77348 0.23468017578125 +77349 0.095245361328125 +77350 -0.00396728515625 +77351 -0.04852294921875 +77352 -0.055145263671875 +77353 -0.0758056640625 +77354 -0.138702392578125 +77355 -0.209197998046875 +77356 -0.289031982421875 +77357 -0.37884521484375 +77358 -0.456329345703125 +77359 -0.51641845703125 +77360 -0.519287109375 +77361 -0.458251953125 +77362 -0.384796142578125 +77363 -0.323699951171875 +77364 -0.269287109375 +77365 -0.1951904296875 +77366 -0.100006103515625 +77367 -0.01055908203125 +77368 0.1033935546875 +77369 0.24908447265625 +77370 0.373199462890625 +77371 0.45806884765625 +77372 0.511474609375 +77373 0.565399169921875 +77374 0.61138916015625 +77375 0.5897216796875 +77376 0.4906005859375 +77377 0.33148193359375 +77378 0.147796630859375 +77379 -0.01873779296875 +77380 -0.140289306640625 +77381 -0.191986083984375 +77382 -0.184295654296875 +77383 -0.161834716796875 +77384 -0.166595458984375 +77385 -0.19390869140625 +77386 -0.22442626953125 +77387 -0.279754638671875 +77388 -0.3389892578125 +77389 -0.3543701171875 +77390 -0.348175048828125 +77391 -0.32598876953125 +77392 -0.2581787109375 +77393 -0.139801025390625 +77394 0.014617919921875 +77395 0.144378662109375 +77396 0.221038818359375 +77397 0.27069091796875 +77398 0.294036865234375 +77399 0.311767578125 +77400 0.339141845703125 +77401 0.360260009765625 +77402 0.360504150390625 +77403 0.308380126953125 +77404 0.18170166015625 +77405 0.0047607421875 +77406 -0.17559814453125 +77407 -0.3143310546875 +77408 -0.36785888671875 +77409 -0.36248779296875 +77410 -0.343536376953125 +77411 -0.3018798828125 +77412 -0.231414794921875 +77413 -0.117645263671875 +77414 0.007049560546875 +77415 0.087982177734375 +77416 0.13946533203125 +77417 0.17425537109375 +77418 0.188201904296875 +77419 0.171234130859375 +77420 0.118438720703125 +77421 0.05706787109375 +77422 -0.010711669921875 +77423 -0.0914306640625 +77424 -0.162322998046875 +77425 -0.194549560546875 +77426 -0.1492919921875 +77427 -0.02166748046875 +77428 0.124053955078125 +77429 0.211151123046875 +77430 0.240447998046875 +77431 0.242218017578125 +77432 0.2257080078125 +77433 0.194366455078125 +77434 0.115509033203125 +77435 0.0128173828125 +77436 -0.053802490234375 +77437 -0.110626220703125 +77438 -0.199493408203125 +77439 -0.29437255859375 +77440 -0.33221435546875 +77441 -0.27972412109375 +77442 -0.185333251953125 +77443 -0.128204345703125 +77444 -0.115692138671875 +77445 -0.116455078125 +77446 -0.105926513671875 +77447 -0.053955078125 +77448 0.048797607421875 +77449 0.157318115234375 +77450 0.212005615234375 +77451 0.218475341796875 +77452 0.23724365234375 +77453 0.30535888671875 +77454 0.38128662109375 +77455 0.404449462890625 +77456 0.3944091796875 +77457 0.3885498046875 +77458 0.362640380859375 +77459 0.27362060546875 +77460 0.11712646484375 +77461 -0.054901123046875 +77462 -0.19085693359375 +77463 -0.28570556640625 +77464 -0.339263916015625 +77465 -0.3775634765625 +77466 -0.445709228515625 +77467 -0.535064697265625 +77468 -0.629058837890625 +77469 -0.697601318359375 +77470 -0.70391845703125 +77471 -0.6424560546875 +77472 -0.491241455078125 +77473 -0.265716552734375 +77474 -0.023712158203125 +77475 0.201751708984375 +77476 0.375823974609375 +77477 0.485076904296875 +77478 0.56884765625 +77479 0.634765625 +77480 0.63763427734375 +77481 0.5660400390625 +77482 0.4720458984375 +77483 0.40692138671875 +77484 0.3778076171875 +77485 0.376953125 +77486 0.371978759765625 +77487 0.313140869140625 +77488 0.184417724609375 +77489 0.011199951171875 +77490 -0.171051025390625 +77491 -0.33740234375 +77492 -0.47198486328125 +77493 -0.560394287109375 +77494 -0.58056640625 +77495 -0.54754638671875 +77496 -0.508575439453125 +77497 -0.459503173828125 +77498 -0.394378662109375 +77499 -0.35260009765625 +77500 -0.31170654296875 +77501 -0.197418212890625 +77502 -0.007965087890625 +77503 0.207489013671875 +77504 0.409210205078125 +77505 0.57208251953125 +77506 0.66595458984375 +77507 0.65875244140625 +77508 0.56744384765625 +77509 0.431396484375 +77510 0.29443359375 +77511 0.182464599609375 +77512 0.06365966796875 +77513 -0.075958251953125 +77514 -0.189422607421875 +77515 -0.271942138671875 +77516 -0.342529296875 +77517 -0.364166259765625 +77518 -0.327239990234375 +77519 -0.2769775390625 +77520 -0.253692626953125 +77521 -0.24365234375 +77522 -0.1983642578125 +77523 -0.116241455078125 +77524 -0.036834716796875 +77525 0.034881591796875 +77526 0.09124755859375 +77527 0.10888671875 +77528 0.125518798828125 +77529 0.15771484375 +77530 0.17828369140625 +77531 0.17108154296875 +77532 0.129974365234375 +77533 0.082427978515625 +77534 0.027679443359375 +77535 -0.065643310546875 +77536 -0.15936279296875 +77537 -0.21307373046875 +77538 -0.234649658203125 +77539 -0.2001953125 +77540 -0.119171142578125 +77541 -0.024749755859375 +77542 0.085784912109375 +77543 0.178131103515625 +77544 0.215576171875 +77545 0.211456298828125 +77546 0.17523193359375 +77547 0.128753662109375 +77548 0.1019287109375 +77549 0.0743408203125 +77550 0.04327392578125 +77551 0.038177490234375 +77552 0.076263427734375 +77553 0.14105224609375 +77554 0.186431884765625 +77555 0.188812255859375 +77556 0.1390380859375 +77557 0.041778564453125 +77558 -0.079437255859375 +77559 -0.219390869140625 +77560 -0.367828369140625 +77561 -0.494873046875 +77562 -0.556243896484375 +77563 -0.508697509765625 +77564 -0.3756103515625 +77565 -0.218902587890625 +77566 -0.063751220703125 +77567 0.091552734375 +77568 0.23602294921875 +77569 0.342987060546875 +77570 0.39520263671875 +77571 0.389373779296875 +77572 0.324249267578125 +77573 0.224090576171875 +77574 0.124267578125 +77575 0.037078857421875 +77576 -0.010101318359375 +77577 -0.019439697265625 +77578 -0.022796630859375 +77579 -0.001556396484375 +77580 0.056304931640625 +77581 0.106719970703125 +77582 0.096893310546875 +77583 0.042694091796875 +77584 -0.018035888671875 +77585 -0.07586669921875 +77586 -0.11944580078125 +77587 -0.15972900390625 +77588 -0.202606201171875 +77589 -0.24859619140625 +77590 -0.30517578125 +77591 -0.36212158203125 +77592 -0.39141845703125 +77593 -0.35528564453125 +77594 -0.249969482421875 +77595 -0.092864990234375 +77596 0.08905029296875 +77597 0.2352294921875 +77598 0.318817138671875 +77599 0.358642578125 +77600 0.347747802734375 +77601 0.28564453125 +77602 0.223175048828125 +77603 0.196746826171875 +77604 0.179840087890625 +77605 0.155548095703125 +77606 0.151214599609375 +77607 0.156951904296875 +77608 0.13177490234375 +77609 0.100799560546875 +77610 0.087127685546875 +77611 0.05487060546875 +77612 -0.009002685546875 +77613 -0.10400390625 +77614 -0.229400634765625 +77615 -0.35552978515625 +77616 -0.441925048828125 +77617 -0.473846435546875 +77618 -0.464813232421875 +77619 -0.419097900390625 +77620 -0.334320068359375 +77621 -0.227935791015625 +77622 -0.12347412109375 +77623 -0.02764892578125 +77624 0.077667236328125 +77625 0.2132568359375 +77626 0.38885498046875 +77627 0.582794189453125 +77628 0.734039306640625 +77629 0.800140380859375 +77630 0.7783203125 +77631 0.6651611328125 +77632 0.45965576171875 +77633 0.199188232421875 +77634 -0.050689697265625 +77635 -0.23297119140625 +77636 -0.33013916015625 +77637 -0.368408203125 +77638 -0.378936767578125 +77639 -0.376983642578125 +77640 -0.37969970703125 +77641 -0.391510009765625 +77642 -0.385345458984375 +77643 -0.3419189453125 +77644 -0.28289794921875 +77645 -0.251617431640625 +77646 -0.266143798828125 +77647 -0.273345947265625 +77648 -0.216796875 +77649 -0.128265380859375 +77650 -0.068145751953125 +77651 -0.0430908203125 +77652 -0.024444580078125 +77653 0.020721435546875 +77654 0.124481201171875 +77655 0.25787353515625 +77656 0.379119873046875 +77657 0.47991943359375 +77658 0.5281982421875 +77659 0.511138916015625 +77660 0.456207275390625 +77661 0.407470703125 +77662 0.383758544921875 +77663 0.35687255859375 +77664 0.31182861328125 +77665 0.250885009765625 +77666 0.1654052734375 +77667 0.035247802734375 +77668 -0.142059326171875 +77669 -0.33563232421875 +77670 -0.5345458984375 +77671 -0.72186279296875 +77672 -0.836669921875 +77673 -0.8326416015625 +77674 -0.7296142578125 +77675 -0.582550048828125 +77676 -0.440093994140625 +77677 -0.324310302734375 +77678 -0.20147705078125 +77679 -0.044647216796875 +77680 0.103973388671875 +77681 0.202392578125 +77682 0.264495849609375 +77683 0.338897705078125 +77684 0.443817138671875 +77685 0.545074462890625 +77686 0.6173095703125 +77687 0.6524658203125 +77688 0.66339111328125 +77689 0.6561279296875 +77690 0.606781005859375 +77691 0.501190185546875 +77692 0.352783203125 +77693 0.176544189453125 +77694 -0.034820556640625 +77695 -0.258209228515625 +77696 -0.44244384765625 +77697 -0.5753173828125 +77698 -0.65203857421875 +77699 -0.641632080078125 +77700 -0.562164306640625 +77701 -0.458038330078125 +77702 -0.350555419921875 +77703 -0.260528564453125 +77704 -0.192108154296875 +77705 -0.141937255859375 +77706 -0.1021728515625 +77707 -0.062896728515625 +77708 -0.011932373046875 +77709 0.062835693359375 +77710 0.148712158203125 +77711 0.241729736328125 +77712 0.34912109375 +77713 0.457305908203125 +77714 0.54388427734375 +77715 0.5728759765625 +77716 0.506591796875 +77717 0.351226806640625 +77718 0.146514892578125 +77719 -0.05523681640625 +77720 -0.21624755859375 +77721 -0.334930419921875 +77722 -0.402984619140625 +77723 -0.4412841796875 +77724 -0.49578857421875 +77725 -0.5601806640625 +77726 -0.600738525390625 +77727 -0.584228515625 +77728 -0.47930908203125 +77729 -0.27935791015625 +77730 -0.0089111328125 +77731 0.268798828125 +77732 0.482818603515625 +77733 0.60369873046875 +77734 0.650421142578125 +77735 0.66400146484375 +77736 0.6414794921875 +77737 0.572540283203125 +77738 0.498138427734375 +77739 0.439453125 +77740 0.375518798828125 +77741 0.274505615234375 +77742 0.1087646484375 +77743 -0.099395751953125 +77744 -0.3182373046875 +77745 -0.5489501953125 +77746 -0.7738037109375 +77747 -0.86383056640625 +77748 -0.870391845703125 +77749 -0.86895751953125 +77750 -0.861053466796875 +77751 -0.765869140625 +77752 -0.5301513671875 +77753 -0.214691162109375 +77754 0.137359619140625 +77755 0.474822998046875 +77756 0.76239013671875 +77757 0.867462158203125 +77758 0.870361328125 +77759 0.86480712890625 +77760 0.831817626953125 +77761 0.677581787109375 +77762 0.495880126953125 +77763 0.30767822265625 +77764 0.116180419921875 +77765 -0.110748291015625 +77766 -0.381805419921875 +77767 -0.6572265625 +77768 -0.857421875 +77769 -0.870391845703125 +77770 -0.870391845703125 +77771 -0.86444091796875 +77772 -0.85723876953125 +77773 -0.790008544921875 +77774 -0.62847900390625 +77775 -0.3956298828125 +77776 -0.126708984375 +77777 0.150115966796875 +77778 0.424041748046875 +77779 0.670623779296875 +77780 0.854522705078125 +77781 0.866485595703125 +77782 0.86920166015625 +77783 0.8653564453125 +77784 0.857147216796875 +77785 0.766845703125 +77786 0.628509521484375 +77787 0.462127685546875 +77788 0.297210693359375 +77789 0.14862060546875 +77790 -0.00537109375 +77791 -0.15753173828125 +77792 -0.31304931640625 +77793 -0.48876953125 +77794 -0.6416015625 +77795 -0.751373291015625 +77796 -0.84619140625 +77797 -0.861297607421875 +77798 -0.863250732421875 +77799 -0.856597900390625 +77800 -0.7498779296875 +77801 -0.624542236328125 +77802 -0.47808837890625 +77803 -0.253387451171875 +77804 0.003692626953125 +77805 0.2257080078125 +77806 0.427154541015625 +77807 0.643218994140625 +77808 0.855926513671875 +77809 0.870361328125 +77810 0.870361328125 +77811 0.862762451171875 +77812 0.79669189453125 +77813 0.595794677734375 +77814 0.362152099609375 +77815 0.1270751953125 +77816 -0.086944580078125 +77817 -0.2784423828125 +77818 -0.484832763671875 +77819 -0.729583740234375 +77820 -0.86688232421875 +77821 -0.870391845703125 +77822 -0.86859130859375 +77823 -0.86279296875 +77824 -0.817962646484375 +77825 -0.6116943359375 +77826 -0.3128662109375 +77827 0.039398193359375 +77828 0.422821044921875 +77829 0.805145263671875 +77830 0.870361328125 +77831 0.870361328125 +77832 0.860015869140625 +77833 0.727935791015625 +77834 0.48114013671875 +77835 0.2059326171875 +77836 -0.06103515625 +77837 -0.29913330078125 +77838 -0.516204833984375 +77839 -0.7252197265625 +77840 -0.85980224609375 +77841 -0.870391845703125 +77842 -0.870391845703125 +77843 -0.858062744140625 +77844 -0.673004150390625 +77845 -0.42694091796875 +77846 -0.2100830078125 +77847 -0.0362548828125 +77848 0.10943603515625 +77849 0.23516845703125 +77850 0.373687744140625 +77851 0.517791748046875 +77852 0.602783203125 +77853 0.635711669921875 +77854 0.655181884765625 +77855 0.65948486328125 +77856 0.651275634765625 +77857 0.61846923828125 +77858 0.53753662109375 +77859 0.404144287109375 +77860 0.22186279296875 +77861 0.003997802734375 +77862 -0.22100830078125 +77863 -0.42449951171875 +77864 -0.579833984375 +77865 -0.641876220703125 +77866 -0.6177978515625 +77867 -0.575531005859375 +77868 -0.526336669921875 +77869 -0.42645263671875 +77870 -0.2581787109375 +77871 -0.068695068359375 +77872 0.09222412109375 +77873 0.232147216796875 +77874 0.3509521484375 +77875 0.410064697265625 +77876 0.372955322265625 +77877 0.2554931640625 +77878 0.10711669921875 +77879 -0.052886962890625 +77880 -0.186279296875 +77881 -0.23291015625 +77882 -0.209442138671875 +77883 -0.174163818359375 +77884 -0.126739501953125 +77885 -0.048126220703125 +77886 0.0426025390625 +77887 0.10748291015625 +77888 0.1409912109375 +77889 0.19708251953125 +77890 0.273651123046875 +77891 0.31768798828125 +77892 0.341094970703125 +77893 0.368011474609375 +77894 0.37249755859375 +77895 0.30072021484375 +77896 0.1517333984375 +77897 -0.01470947265625 +77898 -0.1883544921875 +77899 -0.372711181640625 +77900 -0.51397705078125 +77901 -0.57177734375 +77902 -0.53948974609375 +77903 -0.43511962890625 +77904 -0.2962646484375 +77905 -0.161102294921875 +77906 -0.0435791015625 +77907 0.060394287109375 +77908 0.13665771484375 +77909 0.170135498046875 +77910 0.16552734375 +77911 0.15728759765625 +77912 0.150787353515625 +77913 0.12200927734375 +77914 0.080108642578125 +77915 0.05126953125 +77916 0.062896728515625 +77917 0.09271240234375 +77918 0.092987060546875 +77919 0.07855224609375 +77920 0.06427001953125 +77921 0.0347900390625 +77922 -0.01171875 +77923 -0.056060791015625 +77924 -0.055511474609375 +77925 -0.010467529296875 +77926 0.02508544921875 +77927 0.025665283203125 +77928 0.017333984375 +77929 0.00189208984375 +77930 -0.03173828125 +77931 -0.071502685546875 +77932 -0.13543701171875 +77933 -0.219970703125 +77934 -0.300506591796875 +77935 -0.376312255859375 +77936 -0.416107177734375 +77937 -0.371124267578125 +77938 -0.242279052734375 +77939 -0.069732666015625 +77940 0.125640869140625 +77941 0.31268310546875 +77942 0.45501708984375 +77943 0.554779052734375 +77944 0.61065673828125 +77945 0.610931396484375 +77946 0.531463623046875 +77947 0.3883056640625 +77948 0.23468017578125 +77949 0.095245361328125 +77950 -0.00396728515625 +77951 -0.04852294921875 +77952 -0.055145263671875 +77953 -0.0758056640625 +77954 -0.138702392578125 +77955 -0.209197998046875 +77956 -0.289031982421875 +77957 -0.37884521484375 +77958 -0.456329345703125 +77959 -0.51641845703125 +77960 -0.519287109375 +77961 -0.458251953125 +77962 -0.384796142578125 +77963 -0.323699951171875 +77964 -0.269287109375 +77965 -0.1951904296875 +77966 -0.100006103515625 +77967 -0.01055908203125 +77968 0.1033935546875 +77969 0.24908447265625 +77970 0.373199462890625 +77971 0.45806884765625 +77972 0.511474609375 +77973 0.565399169921875 +77974 0.61138916015625 +77975 0.5897216796875 +77976 0.4906005859375 +77977 0.33148193359375 +77978 0.147796630859375 +77979 -0.01873779296875 +77980 -0.140289306640625 +77981 -0.191986083984375 +77982 -0.184295654296875 +77983 -0.161834716796875 +77984 -0.166595458984375 +77985 -0.19390869140625 +77986 -0.22442626953125 +77987 -0.279754638671875 +77988 -0.3389892578125 +77989 -0.3543701171875 +77990 -0.348175048828125 +77991 -0.32598876953125 +77992 -0.2581787109375 +77993 -0.139801025390625 +77994 0.014617919921875 +77995 0.144378662109375 +77996 0.221038818359375 +77997 0.27069091796875 +77998 0.294036865234375 +77999 0.311767578125 +78000 0.339141845703125 +78001 0.360260009765625 +78002 0.360504150390625 +78003 0.308380126953125 +78004 0.18170166015625 +78005 0.0047607421875 +78006 -0.17559814453125 +78007 -0.3143310546875 +78008 -0.36785888671875 +78009 -0.36248779296875 +78010 -0.343536376953125 +78011 -0.3018798828125 +78012 -0.231414794921875 +78013 -0.117645263671875 +78014 0.007049560546875 +78015 0.087982177734375 +78016 0.13946533203125 +78017 0.17425537109375 +78018 0.188201904296875 +78019 0.171234130859375 +78020 0.118438720703125 +78021 0.05706787109375 +78022 -0.010711669921875 +78023 -0.0914306640625 +78024 -0.162322998046875 +78025 -0.194549560546875 +78026 -0.1492919921875 +78027 -0.02166748046875 +78028 0.124053955078125 +78029 0.211151123046875 +78030 0.240447998046875 +78031 0.242218017578125 +78032 0.2257080078125 +78033 0.194366455078125 +78034 0.115509033203125 +78035 0.0128173828125 +78036 -0.053802490234375 +78037 -0.110626220703125 +78038 -0.199493408203125 +78039 -0.29437255859375 +78040 -0.33221435546875 +78041 -0.27972412109375 +78042 -0.185333251953125 +78043 -0.128204345703125 +78044 -0.115692138671875 +78045 -0.116455078125 +78046 -0.105926513671875 +78047 -0.053955078125 +78048 0.048797607421875 +78049 0.157318115234375 +78050 0.212005615234375 +78051 0.218475341796875 +78052 0.23724365234375 +78053 0.30535888671875 +78054 0.38128662109375 +78055 0.404449462890625 +78056 0.3944091796875 +78057 0.3885498046875 +78058 0.362640380859375 +78059 0.27362060546875 +78060 0.11712646484375 +78061 -0.054901123046875 +78062 -0.19085693359375 +78063 -0.28570556640625 +78064 -0.339263916015625 +78065 -0.3775634765625 +78066 -0.445709228515625 +78067 -0.535064697265625 +78068 -0.629058837890625 +78069 -0.697601318359375 +78070 -0.70391845703125 +78071 -0.6424560546875 +78072 -0.491241455078125 +78073 -0.265716552734375 +78074 -0.023712158203125 +78075 0.201751708984375 +78076 0.375823974609375 +78077 0.485076904296875 +78078 0.56884765625 +78079 0.634765625 +78080 0.63763427734375 +78081 0.5660400390625 +78082 0.4720458984375 +78083 0.40692138671875 +78084 0.3778076171875 +78085 0.376953125 +78086 0.371978759765625 +78087 0.313140869140625 +78088 0.184417724609375 +78089 0.011199951171875 +78090 -0.171051025390625 +78091 -0.33740234375 +78092 -0.47198486328125 +78093 -0.560394287109375 +78094 -0.58056640625 +78095 -0.54754638671875 +78096 -0.508575439453125 +78097 -0.459503173828125 +78098 -0.394378662109375 +78099 -0.35260009765625 +78100 -0.31170654296875 +78101 -0.197418212890625 +78102 -0.007965087890625 +78103 0.207489013671875 +78104 0.409210205078125 +78105 0.57208251953125 +78106 0.66595458984375 +78107 0.65875244140625 +78108 0.56744384765625 +78109 0.431396484375 +78110 0.29443359375 +78111 0.182464599609375 +78112 0.06365966796875 +78113 -0.075958251953125 +78114 -0.189422607421875 +78115 -0.271942138671875 +78116 -0.342529296875 +78117 -0.364166259765625 +78118 -0.327239990234375 +78119 -0.2769775390625 +78120 -0.253692626953125 +78121 -0.24365234375 +78122 -0.1983642578125 +78123 -0.116241455078125 +78124 -0.036834716796875 +78125 0.034881591796875 +78126 0.09124755859375 +78127 0.10888671875 +78128 0.125518798828125 +78129 0.15771484375 +78130 0.17828369140625 +78131 0.17108154296875 +78132 0.129974365234375 +78133 0.082427978515625 +78134 0.027679443359375 +78135 -0.065643310546875 +78136 -0.15936279296875 +78137 -0.21307373046875 +78138 -0.234649658203125 +78139 -0.2001953125 +78140 -0.119171142578125 +78141 -0.024749755859375 +78142 0.085784912109375 +78143 0.178131103515625 +78144 0.215576171875 +78145 0.211456298828125 +78146 0.17523193359375 +78147 0.128753662109375 +78148 0.1019287109375 +78149 0.0743408203125 +78150 0.04327392578125 +78151 0.038177490234375 +78152 0.076263427734375 +78153 0.14105224609375 +78154 0.186431884765625 +78155 0.188812255859375 +78156 0.1390380859375 +78157 0.041778564453125 +78158 -0.079437255859375 +78159 -0.219390869140625 +78160 -0.367828369140625 +78161 -0.494873046875 +78162 -0.556243896484375 +78163 -0.508697509765625 +78164 -0.3756103515625 +78165 -0.218902587890625 +78166 -0.063751220703125 +78167 0.091552734375 +78168 0.23602294921875 +78169 0.342987060546875 +78170 0.39520263671875 +78171 0.389373779296875 +78172 0.324249267578125 +78173 0.224090576171875 +78174 0.124267578125 +78175 0.037078857421875 +78176 -0.010101318359375 +78177 -0.019439697265625 +78178 -0.022796630859375 +78179 -0.001556396484375 +78180 0.056304931640625 +78181 0.106719970703125 +78182 0.096893310546875 +78183 0.042694091796875 +78184 -0.018035888671875 +78185 -0.07586669921875 +78186 -0.11944580078125 +78187 -0.15972900390625 +78188 -0.202606201171875 +78189 -0.24859619140625 +78190 -0.30517578125 +78191 -0.36212158203125 +78192 -0.39141845703125 +78193 -0.35528564453125 +78194 -0.249969482421875 +78195 -0.092864990234375 +78196 0.08905029296875 +78197 0.2352294921875 +78198 0.318817138671875 +78199 0.358642578125 +78200 0.347747802734375 +78201 0.28564453125 +78202 0.223175048828125 +78203 0.196746826171875 +78204 0.179840087890625 +78205 0.155548095703125 +78206 0.151214599609375 +78207 0.156951904296875 +78208 0.13177490234375 +78209 0.100799560546875 +78210 0.087127685546875 +78211 0.05487060546875 +78212 -0.009002685546875 +78213 -0.10400390625 +78214 -0.229400634765625 +78215 -0.35552978515625 +78216 -0.441925048828125 +78217 -0.473846435546875 +78218 -0.464813232421875 +78219 -0.419097900390625 +78220 -0.334320068359375 +78221 -0.227935791015625 +78222 -0.12347412109375 +78223 -0.02764892578125 +78224 0.077667236328125 +78225 0.2132568359375 +78226 0.38885498046875 +78227 0.582794189453125 +78228 0.734039306640625 +78229 0.800140380859375 +78230 0.7783203125 +78231 0.6651611328125 +78232 0.45965576171875 +78233 0.199188232421875 +78234 -0.050689697265625 +78235 -0.23297119140625 +78236 -0.33013916015625 +78237 -0.368408203125 +78238 -0.378936767578125 +78239 -0.376983642578125 +78240 -0.37969970703125 +78241 -0.391510009765625 +78242 -0.385345458984375 +78243 -0.3419189453125 +78244 -0.28289794921875 +78245 -0.251617431640625 +78246 -0.266143798828125 +78247 -0.273345947265625 +78248 -0.216796875 +78249 -0.128265380859375 +78250 -0.068145751953125 +78251 -0.0430908203125 +78252 -0.024444580078125 +78253 0.020721435546875 +78254 0.124481201171875 +78255 0.25787353515625 +78256 0.379119873046875 +78257 0.47991943359375 +78258 0.5281982421875 +78259 0.511138916015625 +78260 0.456207275390625 +78261 0.407470703125 +78262 0.383758544921875 +78263 0.35687255859375 +78264 0.31182861328125 +78265 0.250885009765625 +78266 0.1654052734375 +78267 0.035247802734375 +78268 -0.142059326171875 +78269 -0.33563232421875 +78270 -0.5345458984375 +78271 -0.72186279296875 +78272 -0.836669921875 +78273 -0.8326416015625 +78274 -0.7296142578125 +78275 -0.582550048828125 +78276 -0.440093994140625 +78277 -0.324310302734375 +78278 -0.20147705078125 +78279 -0.044647216796875 +78280 0.103973388671875 +78281 0.202392578125 +78282 0.264495849609375 +78283 0.338897705078125 +78284 0.443817138671875 +78285 0.545074462890625 +78286 0.6173095703125 +78287 0.6524658203125 +78288 0.66339111328125 +78289 0.6561279296875 +78290 0.606781005859375 +78291 0.501190185546875 +78292 0.352783203125 +78293 0.176544189453125 +78294 -0.034820556640625 +78295 -0.258209228515625 +78296 -0.44244384765625 +78297 -0.5753173828125 +78298 -0.65203857421875 +78299 -0.641632080078125 +78300 -0.562164306640625 +78301 -0.458038330078125 +78302 -0.350555419921875 +78303 -0.260528564453125 +78304 -0.192108154296875 +78305 -0.141937255859375 +78306 -0.1021728515625 +78307 -0.062896728515625 +78308 -0.011932373046875 +78309 0.062835693359375 +78310 0.148712158203125 +78311 0.241729736328125 +78312 0.34912109375 +78313 0.457305908203125 +78314 0.54388427734375 +78315 0.5728759765625 +78316 0.506591796875 +78317 0.351226806640625 +78318 0.146514892578125 +78319 -0.05523681640625 +78320 -0.21624755859375 +78321 -0.334930419921875 +78322 -0.402984619140625 +78323 -0.4412841796875 +78324 -0.49578857421875 +78325 -0.5601806640625 +78326 -0.600738525390625 +78327 -0.584228515625 +78328 -0.47930908203125 +78329 -0.27935791015625 +78330 -0.0089111328125 +78331 0.268798828125 +78332 0.482818603515625 +78333 0.60369873046875 +78334 0.650421142578125 +78335 0.66400146484375 +78336 0.6414794921875 +78337 0.572540283203125 +78338 0.498138427734375 +78339 0.439453125 +78340 0.375518798828125 +78341 0.274505615234375 +78342 0.1087646484375 +78343 -0.099395751953125 +78344 -0.3182373046875 +78345 -0.5489501953125 +78346 -0.7738037109375 +78347 -0.86383056640625 +78348 -0.870391845703125 +78349 -0.86895751953125 +78350 -0.861053466796875 +78351 -0.765869140625 +78352 -0.5301513671875 +78353 -0.214691162109375 +78354 0.137359619140625 +78355 0.474822998046875 +78356 0.76239013671875 +78357 0.867462158203125 +78358 0.870361328125 +78359 0.86480712890625 +78360 0.831817626953125 +78361 0.677581787109375 +78362 0.495880126953125 +78363 0.30767822265625 +78364 0.116180419921875 +78365 -0.110748291015625 +78366 -0.381805419921875 +78367 -0.6572265625 +78368 -0.857421875 +78369 -0.870391845703125 +78370 -0.870391845703125 +78371 -0.86444091796875 +78372 -0.85723876953125 +78373 -0.790008544921875 +78374 -0.62847900390625 +78375 -0.3956298828125 +78376 -0.126708984375 +78377 0.150115966796875 +78378 0.424041748046875 +78379 0.670623779296875 +78380 0.854522705078125 +78381 0.866485595703125 +78382 0.86920166015625 +78383 0.8653564453125 +78384 0.857147216796875 +78385 0.766845703125 +78386 0.628509521484375 +78387 0.462127685546875 +78388 0.297210693359375 +78389 0.14862060546875 +78390 -0.00537109375 +78391 -0.15753173828125 +78392 -0.31304931640625 +78393 -0.48876953125 +78394 -0.6416015625 +78395 -0.751373291015625 +78396 -0.84619140625 +78397 -0.861297607421875 +78398 -0.863250732421875 +78399 -0.856597900390625 +78400 -0.7498779296875 +78401 -0.624542236328125 +78402 -0.47808837890625 +78403 -0.253387451171875 +78404 0.003692626953125 +78405 0.2257080078125 +78406 0.427154541015625 +78407 0.643218994140625 +78408 0.855926513671875 +78409 0.870361328125 +78410 0.870361328125 +78411 0.862762451171875 +78412 0.79669189453125 +78413 0.595794677734375 +78414 0.362152099609375 +78415 0.1270751953125 +78416 -0.086944580078125 +78417 -0.2784423828125 +78418 -0.484832763671875 +78419 -0.729583740234375 +78420 -0.86688232421875 +78421 -0.870391845703125 +78422 -0.86859130859375 +78423 -0.86279296875 +78424 -0.817962646484375 +78425 -0.6116943359375 +78426 -0.3128662109375 +78427 0.039398193359375 +78428 0.422821044921875 +78429 0.805145263671875 +78430 0.870361328125 +78431 0.870361328125 +78432 0.860015869140625 +78433 0.727935791015625 +78434 0.48114013671875 +78435 0.2059326171875 +78436 -0.06103515625 +78437 -0.29913330078125 +78438 -0.516204833984375 +78439 -0.7252197265625 +78440 -0.85980224609375 +78441 -0.870391845703125 +78442 -0.870391845703125 +78443 -0.858062744140625 +78444 -0.673004150390625 +78445 -0.42694091796875 +78446 -0.2100830078125 +78447 -0.0362548828125 +78448 0.10943603515625 +78449 0.23516845703125 +78450 0.373687744140625 +78451 0.517791748046875 +78452 0.602783203125 +78453 0.635711669921875 +78454 0.655181884765625 +78455 0.65948486328125 +78456 0.651275634765625 +78457 0.61846923828125 +78458 0.53753662109375 +78459 0.404144287109375 +78460 0.22186279296875 +78461 0.003997802734375 +78462 -0.22100830078125 +78463 -0.42449951171875 +78464 -0.579833984375 +78465 -0.641876220703125 +78466 -0.6177978515625 +78467 -0.575531005859375 +78468 -0.526336669921875 +78469 -0.42645263671875 +78470 -0.2581787109375 +78471 -0.068695068359375 +78472 0.09222412109375 +78473 0.232147216796875 +78474 0.3509521484375 +78475 0.410064697265625 +78476 0.372955322265625 +78477 0.2554931640625 +78478 0.10711669921875 +78479 -0.052886962890625 +78480 -0.186279296875 +78481 -0.23291015625 +78482 -0.209442138671875 +78483 -0.174163818359375 +78484 -0.126739501953125 +78485 -0.048126220703125 +78486 0.0426025390625 +78487 0.10748291015625 +78488 0.1409912109375 +78489 0.19708251953125 +78490 0.273651123046875 +78491 0.31768798828125 +78492 0.341094970703125 +78493 0.368011474609375 +78494 0.37249755859375 +78495 0.30072021484375 +78496 0.1517333984375 +78497 -0.01470947265625 +78498 -0.1883544921875 +78499 -0.372711181640625 +78500 -0.51397705078125 +78501 -0.57177734375 +78502 -0.53948974609375 +78503 -0.43511962890625 +78504 -0.2962646484375 +78505 -0.161102294921875 +78506 -0.0435791015625 +78507 0.060394287109375 +78508 0.13665771484375 +78509 0.170135498046875 +78510 0.16552734375 +78511 0.15728759765625 +78512 0.150787353515625 +78513 0.12200927734375 +78514 0.080108642578125 +78515 0.05126953125 +78516 0.062896728515625 +78517 0.09271240234375 +78518 0.092987060546875 +78519 0.07855224609375 +78520 0.06427001953125 +78521 0.0347900390625 +78522 -0.01171875 +78523 -0.056060791015625 +78524 -0.055511474609375 +78525 -0.010467529296875 +78526 0.02508544921875 +78527 0.025665283203125 +78528 0.017333984375 +78529 0.00189208984375 +78530 -0.03173828125 +78531 -0.071502685546875 +78532 -0.13543701171875 +78533 -0.219970703125 +78534 -0.300506591796875 +78535 -0.376312255859375 +78536 -0.416107177734375 +78537 -0.371124267578125 +78538 -0.242279052734375 +78539 -0.069732666015625 +78540 0.125640869140625 +78541 0.31268310546875 +78542 0.45501708984375 +78543 0.554779052734375 +78544 0.61065673828125 +78545 0.610931396484375 +78546 0.531463623046875 +78547 0.3883056640625 +78548 0.23468017578125 +78549 0.095245361328125 +78550 -0.00396728515625 +78551 -0.04852294921875 +78552 -0.055145263671875 +78553 -0.0758056640625 +78554 -0.138702392578125 +78555 -0.209197998046875 +78556 -0.289031982421875 +78557 -0.37884521484375 +78558 -0.456329345703125 +78559 -0.51641845703125 +78560 -0.519287109375 +78561 -0.458251953125 +78562 -0.384796142578125 +78563 -0.323699951171875 +78564 -0.269287109375 +78565 -0.1951904296875 +78566 -0.100006103515625 +78567 -0.01055908203125 +78568 0.1033935546875 +78569 0.24908447265625 +78570 0.373199462890625 +78571 0.45806884765625 +78572 0.511474609375 +78573 0.565399169921875 +78574 0.61138916015625 +78575 0.5897216796875 +78576 0.4906005859375 +78577 0.33148193359375 +78578 0.147796630859375 +78579 -0.01873779296875 +78580 -0.140289306640625 +78581 -0.191986083984375 +78582 -0.184295654296875 +78583 -0.161834716796875 +78584 -0.166595458984375 +78585 -0.19390869140625 +78586 -0.22442626953125 +78587 -0.279754638671875 +78588 -0.3389892578125 +78589 -0.3543701171875 +78590 -0.348175048828125 +78591 -0.32598876953125 +78592 -0.2581787109375 +78593 -0.139801025390625 +78594 0.014617919921875 +78595 0.144378662109375 +78596 0.221038818359375 +78597 0.27069091796875 +78598 0.294036865234375 +78599 0.311767578125 +78600 0.339141845703125 +78601 0.360260009765625 +78602 0.360504150390625 +78603 0.308380126953125 +78604 0.18170166015625 +78605 0.0047607421875 +78606 -0.17559814453125 +78607 -0.3143310546875 +78608 -0.36785888671875 +78609 -0.36248779296875 +78610 -0.343536376953125 +78611 -0.3018798828125 +78612 -0.231414794921875 +78613 -0.117645263671875 +78614 0.007049560546875 +78615 0.087982177734375 +78616 0.13946533203125 +78617 0.17425537109375 +78618 0.188201904296875 +78619 0.171234130859375 +78620 0.118438720703125 +78621 0.05706787109375 +78622 -0.010711669921875 +78623 -0.0914306640625 +78624 -0.162322998046875 +78625 -0.194549560546875 +78626 -0.1492919921875 +78627 -0.02166748046875 +78628 0.124053955078125 +78629 0.211151123046875 +78630 0.240447998046875 +78631 0.242218017578125 +78632 0.2257080078125 +78633 0.194366455078125 +78634 0.115509033203125 +78635 0.0128173828125 +78636 -0.053802490234375 +78637 -0.110626220703125 +78638 -0.199493408203125 +78639 -0.29437255859375 +78640 -0.33221435546875 +78641 -0.27972412109375 +78642 -0.185333251953125 +78643 -0.128204345703125 +78644 -0.115692138671875 +78645 -0.116455078125 +78646 -0.105926513671875 +78647 -0.053955078125 +78648 0.048797607421875 +78649 0.157318115234375 +78650 0.212005615234375 +78651 0.218475341796875 +78652 0.23724365234375 +78653 0.30535888671875 +78654 0.38128662109375 +78655 0.404449462890625 +78656 0.3944091796875 +78657 0.3885498046875 +78658 0.362640380859375 +78659 0.27362060546875 +78660 0.11712646484375 +78661 -0.054901123046875 +78662 -0.19085693359375 +78663 -0.28570556640625 +78664 -0.339263916015625 +78665 -0.3775634765625 +78666 -0.445709228515625 +78667 -0.535064697265625 +78668 -0.629058837890625 +78669 -0.697601318359375 +78670 -0.70391845703125 +78671 -0.6424560546875 +78672 -0.491241455078125 +78673 -0.265716552734375 +78674 -0.023712158203125 +78675 0.201751708984375 +78676 0.375823974609375 +78677 0.485076904296875 +78678 0.56884765625 +78679 0.634765625 +78680 0.63763427734375 +78681 0.5660400390625 +78682 0.4720458984375 +78683 0.40692138671875 +78684 0.3778076171875 +78685 0.376953125 +78686 0.371978759765625 +78687 0.313140869140625 +78688 0.184417724609375 +78689 0.011199951171875 +78690 -0.171051025390625 +78691 -0.33740234375 +78692 -0.47198486328125 +78693 -0.560394287109375 +78694 -0.58056640625 +78695 -0.54754638671875 +78696 -0.508575439453125 +78697 -0.459503173828125 +78698 -0.394378662109375 +78699 -0.35260009765625 +78700 -0.31170654296875 +78701 -0.197418212890625 +78702 -0.007965087890625 +78703 0.207489013671875 +78704 0.409210205078125 +78705 0.57208251953125 +78706 0.66595458984375 +78707 0.65875244140625 +78708 0.56744384765625 +78709 0.431396484375 +78710 0.29443359375 +78711 0.182464599609375 +78712 0.06365966796875 +78713 -0.075958251953125 +78714 -0.189422607421875 +78715 -0.271942138671875 +78716 -0.342529296875 +78717 -0.364166259765625 +78718 -0.327239990234375 +78719 -0.2769775390625 +78720 -0.253692626953125 +78721 -0.24365234375 +78722 -0.1983642578125 +78723 -0.116241455078125 +78724 -0.036834716796875 +78725 0.034881591796875 +78726 0.09124755859375 +78727 0.10888671875 +78728 0.125518798828125 +78729 0.15771484375 +78730 0.17828369140625 +78731 0.17108154296875 +78732 0.129974365234375 +78733 0.082427978515625 +78734 0.027679443359375 +78735 -0.065643310546875 +78736 -0.15936279296875 +78737 -0.21307373046875 +78738 -0.234649658203125 +78739 -0.2001953125 +78740 -0.119171142578125 +78741 -0.024749755859375 +78742 0.085784912109375 +78743 0.178131103515625 +78744 0.215576171875 +78745 0.211456298828125 +78746 0.17523193359375 +78747 0.128753662109375 +78748 0.1019287109375 +78749 0.0743408203125 +78750 0.04327392578125 +78751 0.038177490234375 +78752 0.076263427734375 +78753 0.14105224609375 +78754 0.186431884765625 +78755 0.188812255859375 +78756 0.1390380859375 +78757 0.041778564453125 +78758 -0.079437255859375 +78759 -0.219390869140625 +78760 -0.367828369140625 +78761 -0.494873046875 +78762 -0.556243896484375 +78763 -0.508697509765625 +78764 -0.3756103515625 +78765 -0.218902587890625 +78766 -0.063751220703125 +78767 0.091552734375 +78768 0.23602294921875 +78769 0.342987060546875 +78770 0.39520263671875 +78771 0.389373779296875 +78772 0.324249267578125 +78773 0.224090576171875 +78774 0.124267578125 +78775 0.037078857421875 +78776 -0.010101318359375 +78777 -0.019439697265625 +78778 -0.022796630859375 +78779 -0.001556396484375 +78780 0.056304931640625 +78781 0.106719970703125 +78782 0.096893310546875 +78783 0.042694091796875 +78784 -0.018035888671875 +78785 -0.07586669921875 +78786 -0.11944580078125 +78787 -0.15972900390625 +78788 -0.202606201171875 +78789 -0.24859619140625 +78790 -0.30517578125 +78791 -0.36212158203125 +78792 -0.39141845703125 +78793 -0.35528564453125 +78794 -0.249969482421875 +78795 -0.092864990234375 +78796 0.08905029296875 +78797 0.2352294921875 +78798 0.318817138671875 +78799 0.358642578125 +78800 0.347747802734375 +78801 0.28564453125 +78802 0.223175048828125 +78803 0.196746826171875 +78804 0.179840087890625 +78805 0.155548095703125 +78806 0.151214599609375 +78807 0.156951904296875 +78808 0.13177490234375 +78809 0.100799560546875 +78810 0.087127685546875 +78811 0.05487060546875 +78812 -0.009002685546875 +78813 -0.10400390625 +78814 -0.229400634765625 +78815 -0.35552978515625 +78816 -0.441925048828125 +78817 -0.473846435546875 +78818 -0.464813232421875 +78819 -0.419097900390625 +78820 -0.334320068359375 +78821 -0.227935791015625 +78822 -0.12347412109375 +78823 -0.02764892578125 +78824 0.077667236328125 +78825 0.2132568359375 +78826 0.38885498046875 +78827 0.582794189453125 +78828 0.734039306640625 +78829 0.800140380859375 +78830 0.7783203125 +78831 0.6651611328125 +78832 0.45965576171875 +78833 0.199188232421875 +78834 -0.050689697265625 +78835 -0.23297119140625 +78836 -0.33013916015625 +78837 -0.368408203125 +78838 -0.378936767578125 +78839 -0.376983642578125 +78840 -0.37969970703125 +78841 -0.391510009765625 +78842 -0.385345458984375 +78843 -0.3419189453125 +78844 -0.28289794921875 +78845 -0.251617431640625 +78846 -0.266143798828125 +78847 -0.273345947265625 +78848 -0.216796875 +78849 -0.128265380859375 +78850 -0.068145751953125 +78851 -0.0430908203125 +78852 -0.024444580078125 +78853 0.020721435546875 +78854 0.124481201171875 +78855 0.25787353515625 +78856 0.379119873046875 +78857 0.47991943359375 +78858 0.5281982421875 +78859 0.511138916015625 +78860 0.456207275390625 +78861 0.407470703125 +78862 0.383758544921875 +78863 0.35687255859375 +78864 0.31182861328125 +78865 0.250885009765625 +78866 0.1654052734375 +78867 0.035247802734375 +78868 -0.142059326171875 +78869 -0.33563232421875 +78870 -0.5345458984375 +78871 -0.72186279296875 +78872 -0.836669921875 +78873 -0.8326416015625 +78874 -0.7296142578125 +78875 -0.582550048828125 +78876 -0.440093994140625 +78877 -0.324310302734375 +78878 -0.20147705078125 +78879 -0.044647216796875 +78880 0.103973388671875 +78881 0.202392578125 +78882 0.264495849609375 +78883 0.338897705078125 +78884 0.443817138671875 +78885 0.545074462890625 +78886 0.6173095703125 +78887 0.6524658203125 +78888 0.66339111328125 +78889 0.6561279296875 +78890 0.606781005859375 +78891 0.501190185546875 +78892 0.352783203125 +78893 0.176544189453125 +78894 -0.034820556640625 +78895 -0.258209228515625 +78896 -0.44244384765625 +78897 -0.5753173828125 +78898 -0.65203857421875 +78899 -0.641632080078125 +78900 -0.562164306640625 +78901 -0.458038330078125 +78902 -0.350555419921875 +78903 -0.260528564453125 +78904 -0.192108154296875 +78905 -0.141937255859375 +78906 -0.1021728515625 +78907 -0.062896728515625 +78908 -0.011932373046875 +78909 0.062835693359375 +78910 0.148712158203125 +78911 0.241729736328125 +78912 0.34912109375 +78913 0.457305908203125 +78914 0.54388427734375 +78915 0.5728759765625 +78916 0.506591796875 +78917 0.351226806640625 +78918 0.146514892578125 +78919 -0.05523681640625 +78920 -0.21624755859375 +78921 -0.334930419921875 +78922 -0.402984619140625 +78923 -0.4412841796875 +78924 -0.49578857421875 +78925 -0.5601806640625 +78926 -0.600738525390625 +78927 -0.584228515625 +78928 -0.47930908203125 +78929 -0.27935791015625 +78930 -0.0089111328125 +78931 0.268798828125 +78932 0.482818603515625 +78933 0.60369873046875 +78934 0.650421142578125 +78935 0.66400146484375 +78936 0.6414794921875 +78937 0.572540283203125 +78938 0.498138427734375 +78939 0.439453125 +78940 0.375518798828125 +78941 0.274505615234375 +78942 0.1087646484375 +78943 -0.099395751953125 +78944 -0.3182373046875 +78945 -0.5489501953125 +78946 -0.7738037109375 +78947 -0.86383056640625 +78948 -0.870391845703125 +78949 -0.86895751953125 +78950 -0.861053466796875 +78951 -0.765869140625 +78952 -0.5301513671875 +78953 -0.214691162109375 +78954 0.137359619140625 +78955 0.474822998046875 +78956 0.76239013671875 +78957 0.867462158203125 +78958 0.870361328125 +78959 0.86480712890625 +78960 0.831817626953125 +78961 0.677581787109375 +78962 0.495880126953125 +78963 0.30767822265625 +78964 0.116180419921875 +78965 -0.110748291015625 +78966 -0.381805419921875 +78967 -0.6572265625 +78968 -0.857421875 +78969 -0.870391845703125 +78970 -0.870391845703125 +78971 -0.86444091796875 +78972 -0.85723876953125 +78973 -0.790008544921875 +78974 -0.62847900390625 +78975 -0.3956298828125 +78976 -0.126708984375 +78977 0.150115966796875 +78978 0.424041748046875 +78979 0.670623779296875 +78980 0.854522705078125 +78981 0.866485595703125 +78982 0.86920166015625 +78983 0.8653564453125 +78984 0.857147216796875 +78985 0.766845703125 +78986 0.628509521484375 +78987 0.462127685546875 +78988 0.297210693359375 +78989 0.14862060546875 +78990 -0.00537109375 +78991 -0.15753173828125 +78992 -0.31304931640625 +78993 -0.48876953125 +78994 -0.6416015625 +78995 -0.751373291015625 +78996 -0.84619140625 +78997 -0.861297607421875 +78998 -0.863250732421875 +78999 -0.856597900390625 +79000 -0.7498779296875 +79001 -0.624542236328125 +79002 -0.47808837890625 +79003 -0.253387451171875 +79004 0.003692626953125 +79005 0.2257080078125 +79006 0.427154541015625 +79007 0.643218994140625 +79008 0.855926513671875 +79009 0.870361328125 +79010 0.870361328125 +79011 0.862762451171875 +79012 0.79669189453125 +79013 0.595794677734375 +79014 0.362152099609375 +79015 0.1270751953125 +79016 -0.086944580078125 +79017 -0.2784423828125 +79018 -0.484832763671875 +79019 -0.729583740234375 +79020 -0.86688232421875 +79021 -0.870391845703125 +79022 -0.86859130859375 +79023 -0.86279296875 +79024 -0.817962646484375 +79025 -0.6116943359375 +79026 -0.3128662109375 +79027 0.039398193359375 +79028 0.422821044921875 +79029 0.805145263671875 +79030 0.870361328125 +79031 0.870361328125 +79032 0.860015869140625 +79033 0.727935791015625 +79034 0.48114013671875 +79035 0.2059326171875 +79036 -0.06103515625 +79037 -0.29913330078125 +79038 -0.516204833984375 +79039 -0.7252197265625 +79040 -0.85980224609375 +79041 -0.870391845703125 +79042 -0.870391845703125 +79043 -0.858062744140625 +79044 -0.673004150390625 +79045 -0.42694091796875 +79046 -0.2100830078125 +79047 -0.0362548828125 +79048 0.10943603515625 +79049 0.23516845703125 +79050 0.373687744140625 +79051 0.517791748046875 +79052 0.602783203125 +79053 0.635711669921875 +79054 0.655181884765625 +79055 0.65948486328125 +79056 0.651275634765625 +79057 0.61846923828125 +79058 0.53753662109375 +79059 0.404144287109375 +79060 0.22186279296875 +79061 0.003997802734375 +79062 -0.22100830078125 +79063 -0.42449951171875 +79064 -0.579833984375 +79065 -0.641876220703125 +79066 -0.6177978515625 +79067 -0.575531005859375 +79068 -0.526336669921875 +79069 -0.42645263671875 +79070 -0.2581787109375 +79071 -0.068695068359375 +79072 0.09222412109375 +79073 0.232147216796875 +79074 0.3509521484375 +79075 0.410064697265625 +79076 0.372955322265625 +79077 0.2554931640625 +79078 0.10711669921875 +79079 -0.052886962890625 +79080 -0.186279296875 +79081 -0.23291015625 +79082 -0.209442138671875 +79083 -0.174163818359375 +79084 -0.126739501953125 +79085 -0.048126220703125 +79086 0.0426025390625 +79087 0.10748291015625 +79088 0.1409912109375 +79089 0.19708251953125 +79090 0.273651123046875 +79091 0.31768798828125 +79092 0.341094970703125 +79093 0.368011474609375 +79094 0.37249755859375 +79095 0.30072021484375 +79096 0.1517333984375 +79097 -0.01470947265625 +79098 -0.1883544921875 +79099 -0.372711181640625 +79100 -0.51397705078125 +79101 -0.57177734375 +79102 -0.53948974609375 +79103 -0.43511962890625 +79104 -0.2962646484375 +79105 -0.161102294921875 +79106 -0.0435791015625 +79107 0.060394287109375 +79108 0.13665771484375 +79109 0.170135498046875 +79110 0.16552734375 +79111 0.15728759765625 +79112 0.150787353515625 +79113 0.12200927734375 +79114 0.080108642578125 +79115 0.05126953125 +79116 0.062896728515625 +79117 0.09271240234375 +79118 0.092987060546875 +79119 0.07855224609375 +79120 0.06427001953125 +79121 0.0347900390625 +79122 -0.01171875 +79123 -0.056060791015625 +79124 -0.055511474609375 +79125 -0.010467529296875 +79126 0.02508544921875 +79127 0.025665283203125 +79128 0.017333984375 +79129 0.00189208984375 +79130 -0.03173828125 +79131 -0.071502685546875 +79132 -0.13543701171875 +79133 -0.219970703125 +79134 -0.300506591796875 +79135 -0.376312255859375 +79136 -0.416107177734375 +79137 -0.371124267578125 +79138 -0.242279052734375 +79139 -0.069732666015625 +79140 0.125640869140625 +79141 0.31268310546875 +79142 0.45501708984375 +79143 0.554779052734375 +79144 0.61065673828125 +79145 0.610931396484375 +79146 0.531463623046875 +79147 0.3883056640625 +79148 0.23468017578125 +79149 0.095245361328125 +79150 -0.00396728515625 +79151 -0.04852294921875 +79152 -0.055145263671875 +79153 -0.0758056640625 +79154 -0.138702392578125 +79155 -0.209197998046875 +79156 -0.289031982421875 +79157 -0.37884521484375 +79158 -0.456329345703125 +79159 -0.51641845703125 +79160 -0.519287109375 +79161 -0.458251953125 +79162 -0.384796142578125 +79163 -0.323699951171875 +79164 -0.269287109375 +79165 -0.1951904296875 +79166 -0.100006103515625 +79167 -0.01055908203125 +79168 0.1033935546875 +79169 0.24908447265625 +79170 0.373199462890625 +79171 0.45806884765625 +79172 0.511474609375 +79173 0.565399169921875 +79174 0.61138916015625 +79175 0.5897216796875 +79176 0.4906005859375 +79177 0.33148193359375 +79178 0.147796630859375 +79179 -0.01873779296875 +79180 -0.140289306640625 +79181 -0.191986083984375 +79182 -0.184295654296875 +79183 -0.161834716796875 +79184 -0.166595458984375 +79185 -0.19390869140625 +79186 -0.22442626953125 +79187 -0.279754638671875 +79188 -0.3389892578125 +79189 -0.3543701171875 +79190 -0.348175048828125 +79191 -0.32598876953125 +79192 -0.2581787109375 +79193 -0.139801025390625 +79194 0.014617919921875 +79195 0.144378662109375 +79196 0.221038818359375 +79197 0.27069091796875 +79198 0.294036865234375 +79199 0.311767578125 +79200 0.339141845703125 +79201 0.360260009765625 +79202 0.360504150390625 +79203 0.308380126953125 +79204 0.18170166015625 +79205 0.0047607421875 +79206 -0.17559814453125 +79207 -0.3143310546875 +79208 -0.36785888671875 +79209 -0.36248779296875 +79210 -0.343536376953125 +79211 -0.3018798828125 +79212 -0.231414794921875 +79213 -0.117645263671875 +79214 0.007049560546875 +79215 0.087982177734375 +79216 0.13946533203125 +79217 0.17425537109375 +79218 0.188201904296875 +79219 0.171234130859375 +79220 0.118438720703125 +79221 0.05706787109375 +79222 -0.010711669921875 +79223 -0.0914306640625 +79224 -0.162322998046875 +79225 -0.194549560546875 +79226 -0.1492919921875 +79227 -0.02166748046875 +79228 0.124053955078125 +79229 0.211151123046875 +79230 0.240447998046875 +79231 0.242218017578125 +79232 0.2257080078125 +79233 0.194366455078125 +79234 0.115509033203125 +79235 0.0128173828125 +79236 -0.053802490234375 +79237 -0.110626220703125 +79238 -0.199493408203125 +79239 -0.29437255859375 +79240 -0.33221435546875 +79241 -0.27972412109375 +79242 -0.185333251953125 +79243 -0.128204345703125 +79244 -0.115692138671875 +79245 -0.116455078125 +79246 -0.105926513671875 +79247 -0.053955078125 +79248 0.048797607421875 +79249 0.157318115234375 +79250 0.212005615234375 +79251 0.218475341796875 +79252 0.23724365234375 +79253 0.30535888671875 +79254 0.38128662109375 +79255 0.404449462890625 +79256 0.3944091796875 +79257 0.3885498046875 +79258 0.362640380859375 +79259 0.27362060546875 +79260 0.11712646484375 +79261 -0.054901123046875 +79262 -0.19085693359375 +79263 -0.28570556640625 +79264 -0.339263916015625 +79265 -0.3775634765625 +79266 -0.445709228515625 +79267 -0.535064697265625 +79268 -0.629058837890625 +79269 -0.697601318359375 +79270 -0.70391845703125 +79271 -0.6424560546875 +79272 -0.491241455078125 +79273 -0.265716552734375 +79274 -0.023712158203125 +79275 0.201751708984375 +79276 0.375823974609375 +79277 0.485076904296875 +79278 0.56884765625 +79279 0.634765625 +79280 0.63763427734375 +79281 0.5660400390625 +79282 0.4720458984375 +79283 0.40692138671875 +79284 0.3778076171875 +79285 0.376953125 +79286 0.371978759765625 +79287 0.313140869140625 +79288 0.184417724609375 +79289 0.011199951171875 +79290 -0.171051025390625 +79291 -0.33740234375 +79292 -0.47198486328125 +79293 -0.560394287109375 +79294 -0.58056640625 +79295 -0.54754638671875 +79296 -0.508575439453125 +79297 -0.459503173828125 +79298 -0.394378662109375 +79299 -0.35260009765625 +79300 -0.31170654296875 +79301 -0.197418212890625 +79302 -0.007965087890625 +79303 0.207489013671875 +79304 0.409210205078125 +79305 0.57208251953125 +79306 0.66595458984375 +79307 0.65875244140625 +79308 0.56744384765625 +79309 0.431396484375 +79310 0.29443359375 +79311 0.182464599609375 +79312 0.06365966796875 +79313 -0.075958251953125 +79314 -0.189422607421875 +79315 -0.271942138671875 +79316 -0.342529296875 +79317 -0.364166259765625 +79318 -0.327239990234375 +79319 -0.2769775390625 +79320 -0.253692626953125 +79321 -0.24365234375 +79322 -0.1983642578125 +79323 -0.116241455078125 +79324 -0.036834716796875 +79325 0.034881591796875 +79326 0.09124755859375 +79327 0.10888671875 +79328 0.125518798828125 +79329 0.15771484375 +79330 0.17828369140625 +79331 0.17108154296875 +79332 0.129974365234375 +79333 0.082427978515625 +79334 0.027679443359375 +79335 -0.065643310546875 +79336 -0.15936279296875 +79337 -0.21307373046875 +79338 -0.234649658203125 +79339 -0.2001953125 +79340 -0.119171142578125 +79341 -0.024749755859375 +79342 0.085784912109375 +79343 0.178131103515625 +79344 0.215576171875 +79345 0.211456298828125 +79346 0.17523193359375 +79347 0.128753662109375 +79348 0.1019287109375 +79349 0.0743408203125 +79350 0.04327392578125 +79351 0.038177490234375 +79352 0.076263427734375 +79353 0.14105224609375 +79354 0.186431884765625 +79355 0.188812255859375 +79356 0.1390380859375 +79357 0.041778564453125 +79358 -0.079437255859375 +79359 -0.219390869140625 +79360 -0.367828369140625 +79361 -0.494873046875 +79362 -0.556243896484375 +79363 -0.508697509765625 +79364 -0.3756103515625 +79365 -0.218902587890625 +79366 -0.063751220703125 +79367 0.091552734375 +79368 0.23602294921875 +79369 0.342987060546875 +79370 0.39520263671875 +79371 0.389373779296875 +79372 0.324249267578125 +79373 0.224090576171875 +79374 0.124267578125 +79375 0.037078857421875 +79376 -0.010101318359375 +79377 -0.019439697265625 +79378 -0.022796630859375 +79379 -0.001556396484375 +79380 0.056304931640625 +79381 0.106719970703125 +79382 0.096893310546875 +79383 0.042694091796875 +79384 -0.018035888671875 +79385 -0.07586669921875 +79386 -0.11944580078125 +79387 -0.15972900390625 +79388 -0.202606201171875 +79389 -0.24859619140625 +79390 -0.30517578125 +79391 -0.36212158203125 +79392 -0.39141845703125 +79393 -0.35528564453125 +79394 -0.249969482421875 +79395 -0.092864990234375 +79396 0.08905029296875 +79397 0.2352294921875 +79398 0.318817138671875 +79399 0.358642578125 +79400 0.347747802734375 +79401 0.28564453125 +79402 0.223175048828125 +79403 0.196746826171875 +79404 0.179840087890625 +79405 0.155548095703125 +79406 0.151214599609375 +79407 0.156951904296875 +79408 0.13177490234375 +79409 0.100799560546875 +79410 0.087127685546875 +79411 0.05487060546875 +79412 -0.009002685546875 +79413 -0.10400390625 +79414 -0.229400634765625 +79415 -0.35552978515625 +79416 -0.441925048828125 +79417 -0.473846435546875 +79418 -0.464813232421875 +79419 -0.419097900390625 +79420 -0.334320068359375 +79421 -0.227935791015625 +79422 -0.12347412109375 +79423 -0.02764892578125 +79424 0.077667236328125 +79425 0.2132568359375 +79426 0.38885498046875 +79427 0.582794189453125 +79428 0.734039306640625 +79429 0.800140380859375 +79430 0.7783203125 +79431 0.6651611328125 +79432 0.45965576171875 +79433 0.199188232421875 +79434 -0.050689697265625 +79435 -0.23297119140625 +79436 -0.33013916015625 +79437 -0.368408203125 +79438 -0.378936767578125 +79439 -0.376983642578125 +79440 -0.37969970703125 +79441 -0.391510009765625 +79442 -0.385345458984375 +79443 -0.3419189453125 +79444 -0.28289794921875 +79445 -0.251617431640625 +79446 -0.266143798828125 +79447 -0.273345947265625 +79448 -0.216796875 +79449 -0.128265380859375 +79450 -0.068145751953125 +79451 -0.0430908203125 +79452 -0.024444580078125 +79453 0.020721435546875 +79454 0.124481201171875 +79455 0.25787353515625 +79456 0.379119873046875 +79457 0.47991943359375 +79458 0.5281982421875 +79459 0.511138916015625 +79460 0.456207275390625 +79461 0.407470703125 +79462 0.383758544921875 +79463 0.35687255859375 +79464 0.31182861328125 +79465 0.250885009765625 +79466 0.1654052734375 +79467 0.035247802734375 +79468 -0.142059326171875 +79469 -0.33563232421875 +79470 -0.5345458984375 +79471 -0.72186279296875 +79472 -0.836669921875 +79473 -0.8326416015625 +79474 -0.7296142578125 +79475 -0.582550048828125 +79476 -0.440093994140625 +79477 -0.324310302734375 +79478 -0.20147705078125 +79479 -0.044647216796875 +79480 0.103973388671875 +79481 0.202392578125 +79482 0.264495849609375 +79483 0.338897705078125 +79484 0.443817138671875 +79485 0.545074462890625 +79486 0.6173095703125 +79487 0.6524658203125 +79488 0.66339111328125 +79489 0.6561279296875 +79490 0.606781005859375 +79491 0.501190185546875 +79492 0.352783203125 +79493 0.176544189453125 +79494 -0.034820556640625 +79495 -0.258209228515625 +79496 -0.44244384765625 +79497 -0.5753173828125 +79498 -0.65203857421875 +79499 -0.641632080078125 +79500 -0.562164306640625 +79501 -0.458038330078125 +79502 -0.350555419921875 +79503 -0.260528564453125 +79504 -0.192108154296875 +79505 -0.141937255859375 +79506 -0.1021728515625 +79507 -0.062896728515625 +79508 -0.011932373046875 +79509 0.062835693359375 +79510 0.148712158203125 +79511 0.241729736328125 +79512 0.34912109375 +79513 0.457305908203125 +79514 0.54388427734375 +79515 0.5728759765625 +79516 0.506591796875 +79517 0.351226806640625 +79518 0.146514892578125 +79519 -0.05523681640625 +79520 -0.21624755859375 +79521 -0.334930419921875 +79522 -0.402984619140625 +79523 -0.4412841796875 +79524 -0.49578857421875 +79525 -0.5601806640625 +79526 -0.600738525390625 +79527 -0.584228515625 +79528 -0.47930908203125 +79529 -0.27935791015625 +79530 -0.0089111328125 +79531 0.268798828125 +79532 0.482818603515625 +79533 0.60369873046875 +79534 0.650421142578125 +79535 0.66400146484375 +79536 0.6414794921875 +79537 0.572540283203125 +79538 0.498138427734375 +79539 0.439453125 +79540 0.375518798828125 +79541 0.274505615234375 +79542 0.1087646484375 +79543 -0.099395751953125 +79544 -0.3182373046875 +79545 -0.5489501953125 +79546 -0.7738037109375 +79547 -0.86383056640625 +79548 -0.870391845703125 +79549 -0.86895751953125 +79550 -0.861053466796875 +79551 -0.765869140625 +79552 -0.5301513671875 +79553 -0.214691162109375 +79554 0.137359619140625 +79555 0.474822998046875 +79556 0.76239013671875 +79557 0.867462158203125 +79558 0.870361328125 +79559 0.86480712890625 +79560 0.831817626953125 +79561 0.677581787109375 +79562 0.495880126953125 +79563 0.30767822265625 +79564 0.116180419921875 +79565 -0.110748291015625 +79566 -0.381805419921875 +79567 -0.6572265625 +79568 -0.857421875 +79569 -0.870391845703125 +79570 -0.870391845703125 +79571 -0.86444091796875 +79572 -0.85723876953125 +79573 -0.790008544921875 +79574 -0.62847900390625 +79575 -0.3956298828125 +79576 -0.126708984375 +79577 0.150115966796875 +79578 0.424041748046875 +79579 0.670623779296875 +79580 0.854522705078125 +79581 0.866485595703125 +79582 0.86920166015625 +79583 0.8653564453125 +79584 0.857147216796875 +79585 0.766845703125 +79586 0.628509521484375 +79587 0.462127685546875 +79588 0.297210693359375 +79589 0.14862060546875 +79590 -0.00537109375 +79591 -0.15753173828125 +79592 -0.31304931640625 +79593 -0.48876953125 +79594 -0.6416015625 +79595 -0.751373291015625 +79596 -0.84619140625 +79597 -0.861297607421875 +79598 -0.863250732421875 +79599 -0.856597900390625 +79600 -0.7498779296875 +79601 -0.624542236328125 +79602 -0.47808837890625 +79603 -0.253387451171875 +79604 0.003692626953125 +79605 0.2257080078125 +79606 0.427154541015625 +79607 0.643218994140625 +79608 0.855926513671875 +79609 0.870361328125 +79610 0.870361328125 +79611 0.862762451171875 +79612 0.79669189453125 +79613 0.595794677734375 +79614 0.362152099609375 +79615 0.1270751953125 +79616 -0.086944580078125 +79617 -0.2784423828125 +79618 -0.484832763671875 +79619 -0.729583740234375 +79620 -0.86688232421875 +79621 -0.870391845703125 +79622 -0.86859130859375 +79623 -0.86279296875 +79624 -0.817962646484375 +79625 -0.6116943359375 +79626 -0.3128662109375 +79627 0.039398193359375 +79628 0.422821044921875 +79629 0.805145263671875 +79630 0.870361328125 +79631 0.870361328125 +79632 0.860015869140625 +79633 0.727935791015625 +79634 0.48114013671875 +79635 0.2059326171875 +79636 -0.06103515625 +79637 -0.29913330078125 +79638 -0.516204833984375 +79639 -0.7252197265625 +79640 -0.85980224609375 +79641 -0.870391845703125 +79642 -0.870391845703125 +79643 -0.858062744140625 +79644 -0.673004150390625 +79645 -0.42694091796875 +79646 -0.2100830078125 +79647 -0.0362548828125 +79648 0.10943603515625 +79649 0.23516845703125 +79650 0.373687744140625 +79651 0.517791748046875 +79652 0.602783203125 +79653 0.635711669921875 +79654 0.655181884765625 +79655 0.65948486328125 +79656 0.651275634765625 +79657 0.61846923828125 +79658 0.53753662109375 +79659 0.404144287109375 +79660 0.22186279296875 +79661 0.003997802734375 +79662 -0.22100830078125 +79663 -0.42449951171875 +79664 -0.579833984375 +79665 -0.641876220703125 +79666 -0.6177978515625 +79667 -0.575531005859375 +79668 -0.526336669921875 +79669 -0.42645263671875 +79670 -0.2581787109375 +79671 -0.068695068359375 +79672 0.09222412109375 +79673 0.232147216796875 +79674 0.3509521484375 +79675 0.410064697265625 +79676 0.372955322265625 +79677 0.2554931640625 +79678 0.10711669921875 +79679 -0.052886962890625 +79680 -0.186279296875 +79681 -0.23291015625 +79682 -0.209442138671875 +79683 -0.174163818359375 +79684 -0.126739501953125 +79685 -0.048126220703125 +79686 0.0426025390625 +79687 0.10748291015625 +79688 0.1409912109375 +79689 0.19708251953125 +79690 0.273651123046875 +79691 0.31768798828125 +79692 0.341094970703125 +79693 0.368011474609375 +79694 0.37249755859375 +79695 0.30072021484375 +79696 0.1517333984375 +79697 -0.01470947265625 +79698 -0.1883544921875 +79699 -0.372711181640625 +79700 -0.51397705078125 +79701 -0.57177734375 +79702 -0.53948974609375 +79703 -0.43511962890625 +79704 -0.2962646484375 +79705 -0.161102294921875 +79706 -0.0435791015625 +79707 0.060394287109375 +79708 0.13665771484375 +79709 0.170135498046875 +79710 0.16552734375 +79711 0.15728759765625 +79712 0.150787353515625 +79713 0.12200927734375 +79714 0.080108642578125 +79715 0.05126953125 +79716 0.062896728515625 +79717 0.09271240234375 +79718 0.092987060546875 +79719 0.07855224609375 +79720 0.06427001953125 +79721 0.0347900390625 +79722 -0.01171875 +79723 -0.056060791015625 +79724 -0.055511474609375 +79725 -0.010467529296875 +79726 0.02508544921875 +79727 0.025665283203125 +79728 0.017333984375 +79729 0.00189208984375 +79730 -0.03173828125 +79731 -0.071502685546875 +79732 -0.13543701171875 +79733 -0.219970703125 +79734 -0.300506591796875 +79735 -0.376312255859375 +79736 -0.416107177734375 +79737 -0.371124267578125 +79738 -0.242279052734375 +79739 -0.069732666015625 +79740 0.125640869140625 +79741 0.31268310546875 +79742 0.45501708984375 +79743 0.554779052734375 +79744 0.61065673828125 +79745 0.610931396484375 +79746 0.531463623046875 +79747 0.3883056640625 +79748 0.23468017578125 +79749 0.095245361328125 +79750 -0.00396728515625 +79751 -0.04852294921875 +79752 -0.055145263671875 +79753 -0.0758056640625 +79754 -0.138702392578125 +79755 -0.209197998046875 +79756 -0.289031982421875 +79757 -0.37884521484375 +79758 -0.456329345703125 +79759 -0.51641845703125 +79760 -0.519287109375 +79761 -0.458251953125 +79762 -0.384796142578125 +79763 -0.323699951171875 +79764 -0.269287109375 +79765 -0.1951904296875 +79766 -0.100006103515625 +79767 -0.01055908203125 +79768 0.1033935546875 +79769 0.24908447265625 +79770 0.373199462890625 +79771 0.45806884765625 +79772 0.511474609375 +79773 0.565399169921875 +79774 0.61138916015625 +79775 0.5897216796875 +79776 0.4906005859375 +79777 0.33148193359375 +79778 0.147796630859375 +79779 -0.01873779296875 +79780 -0.140289306640625 +79781 -0.191986083984375 +79782 -0.184295654296875 +79783 -0.161834716796875 +79784 -0.166595458984375 +79785 -0.19390869140625 +79786 -0.22442626953125 +79787 -0.279754638671875 +79788 -0.3389892578125 +79789 -0.3543701171875 +79790 -0.348175048828125 +79791 -0.32598876953125 +79792 -0.2581787109375 +79793 -0.139801025390625 +79794 0.014617919921875 +79795 0.144378662109375 +79796 0.221038818359375 +79797 0.27069091796875 +79798 0.294036865234375 +79799 0.311767578125 +79800 0.339141845703125 +79801 0.360260009765625 +79802 0.360504150390625 +79803 0.308380126953125 +79804 0.18170166015625 +79805 0.0047607421875 +79806 -0.17559814453125 +79807 -0.3143310546875 +79808 -0.36785888671875 +79809 -0.36248779296875 +79810 -0.343536376953125 +79811 -0.3018798828125 +79812 -0.231414794921875 +79813 -0.117645263671875 +79814 0.007049560546875 +79815 0.087982177734375 +79816 0.13946533203125 +79817 0.17425537109375 +79818 0.188201904296875 +79819 0.171234130859375 +79820 0.118438720703125 +79821 0.05706787109375 +79822 -0.010711669921875 +79823 -0.0914306640625 +79824 -0.162322998046875 +79825 -0.194549560546875 +79826 -0.1492919921875 +79827 -0.02166748046875 +79828 0.124053955078125 +79829 0.211151123046875 +79830 0.240447998046875 +79831 0.242218017578125 +79832 0.2257080078125 +79833 0.194366455078125 +79834 0.115509033203125 +79835 0.0128173828125 +79836 -0.053802490234375 +79837 -0.110626220703125 +79838 -0.199493408203125 +79839 -0.29437255859375 +79840 -0.33221435546875 +79841 -0.27972412109375 +79842 -0.185333251953125 +79843 -0.128204345703125 +79844 -0.115692138671875 +79845 -0.116455078125 +79846 -0.105926513671875 +79847 -0.053955078125 +79848 0.048797607421875 +79849 0.157318115234375 +79850 0.212005615234375 +79851 0.218475341796875 +79852 0.23724365234375 +79853 0.30535888671875 +79854 0.38128662109375 +79855 0.404449462890625 +79856 0.3944091796875 +79857 0.3885498046875 +79858 0.362640380859375 +79859 0.27362060546875 +79860 0.11712646484375 +79861 -0.054901123046875 +79862 -0.19085693359375 +79863 -0.28570556640625 +79864 -0.339263916015625 +79865 -0.3775634765625 +79866 -0.445709228515625 +79867 -0.535064697265625 +79868 -0.629058837890625 +79869 -0.697601318359375 +79870 -0.70391845703125 +79871 -0.6424560546875 +79872 -0.491241455078125 +79873 -0.265716552734375 +79874 -0.023712158203125 +79875 0.201751708984375 +79876 0.375823974609375 +79877 0.485076904296875 +79878 0.56884765625 +79879 0.634765625 +79880 0.63763427734375 +79881 0.5660400390625 +79882 0.4720458984375 +79883 0.40692138671875 +79884 0.3778076171875 +79885 0.376953125 +79886 0.371978759765625 +79887 0.313140869140625 +79888 0.184417724609375 +79889 0.011199951171875 +79890 -0.171051025390625 +79891 -0.33740234375 +79892 -0.47198486328125 +79893 -0.560394287109375 +79894 -0.58056640625 +79895 -0.54754638671875 +79896 -0.508575439453125 +79897 -0.459503173828125 +79898 -0.394378662109375 +79899 -0.35260009765625 +79900 -0.31170654296875 +79901 -0.197418212890625 +79902 -0.007965087890625 +79903 0.207489013671875 +79904 0.409210205078125 +79905 0.57208251953125 +79906 0.66595458984375 +79907 0.65875244140625 +79908 0.56744384765625 +79909 0.431396484375 +79910 0.29443359375 +79911 0.182464599609375 +79912 0.06365966796875 +79913 -0.075958251953125 +79914 -0.189422607421875 +79915 -0.271942138671875 +79916 -0.342529296875 +79917 -0.364166259765625 +79918 -0.327239990234375 +79919 -0.2769775390625 +79920 -0.253692626953125 +79921 -0.24365234375 +79922 -0.1983642578125 +79923 -0.116241455078125 +79924 -0.036834716796875 +79925 0.034881591796875 +79926 0.09124755859375 +79927 0.10888671875 +79928 0.125518798828125 +79929 0.15771484375 +79930 0.17828369140625 +79931 0.17108154296875 +79932 0.129974365234375 +79933 0.082427978515625 +79934 0.027679443359375 +79935 -0.065643310546875 +79936 -0.15936279296875 +79937 -0.21307373046875 +79938 -0.234649658203125 +79939 -0.2001953125 +79940 -0.119171142578125 +79941 -0.024749755859375 +79942 0.085784912109375 +79943 0.178131103515625 +79944 0.215576171875 +79945 0.211456298828125 +79946 0.17523193359375 +79947 0.128753662109375 +79948 0.1019287109375 +79949 0.0743408203125 +79950 0.04327392578125 +79951 0.038177490234375 +79952 0.076263427734375 +79953 0.14105224609375 +79954 0.186431884765625 +79955 0.188812255859375 +79956 0.1390380859375 +79957 0.041778564453125 +79958 -0.079437255859375 +79959 -0.219390869140625 +79960 -0.367828369140625 +79961 -0.494873046875 +79962 -0.556243896484375 +79963 -0.508697509765625 +79964 -0.3756103515625 +79965 -0.218902587890625 +79966 -0.063751220703125 +79967 0.091552734375 +79968 0.23602294921875 +79969 0.342987060546875 +79970 0.39520263671875 +79971 0.389373779296875 +79972 0.324249267578125 +79973 0.224090576171875 +79974 0.124267578125 +79975 0.037078857421875 +79976 -0.010101318359375 +79977 -0.019439697265625 +79978 -0.022796630859375 +79979 -0.001556396484375 +79980 0.056304931640625 +79981 0.106719970703125 +79982 0.096893310546875 +79983 0.042694091796875 +79984 -0.018035888671875 +79985 -0.07586669921875 +79986 -0.11944580078125 +79987 -0.15972900390625 +79988 -0.202606201171875 +79989 -0.24859619140625 +79990 -0.30517578125 +79991 -0.36212158203125 +79992 -0.39141845703125 +79993 -0.35528564453125 +79994 -0.249969482421875 +79995 -0.092864990234375 +79996 0.08905029296875 +79997 0.2352294921875 +79998 0.318817138671875 +79999 0.358642578125 +80000 0.347747802734375 +80001 0.28564453125 +80002 0.223175048828125 +80003 0.196746826171875 +80004 0.179840087890625 +80005 0.155548095703125 +80006 0.151214599609375 +80007 0.156951904296875 +80008 0.13177490234375 +80009 0.100799560546875 +80010 0.087127685546875 +80011 0.05487060546875 +80012 -0.009002685546875 +80013 -0.10400390625 +80014 -0.229400634765625 +80015 -0.35552978515625 +80016 -0.441925048828125 +80017 -0.473846435546875 +80018 -0.464813232421875 +80019 -0.419097900390625 +80020 -0.334320068359375 +80021 -0.227935791015625 +80022 -0.12347412109375 +80023 -0.02764892578125 +80024 0.077667236328125 +80025 0.2132568359375 +80026 0.38885498046875 +80027 0.582794189453125 +80028 0.734039306640625 +80029 0.800140380859375 +80030 0.7783203125 +80031 0.6651611328125 +80032 0.45965576171875 +80033 0.199188232421875 +80034 -0.050689697265625 +80035 -0.23297119140625 +80036 -0.33013916015625 +80037 -0.368408203125 +80038 -0.378936767578125 +80039 -0.376983642578125 +80040 -0.37969970703125 +80041 -0.391510009765625 +80042 -0.385345458984375 +80043 -0.3419189453125 +80044 -0.28289794921875 +80045 -0.251617431640625 +80046 -0.266143798828125 +80047 -0.273345947265625 +80048 -0.216796875 +80049 -0.128265380859375 +80050 -0.068145751953125 +80051 -0.0430908203125 +80052 -0.024444580078125 +80053 0.020721435546875 +80054 0.124481201171875 +80055 0.25787353515625 +80056 0.379119873046875 +80057 0.47991943359375 +80058 0.5281982421875 +80059 0.511138916015625 +80060 0.456207275390625 +80061 0.407470703125 +80062 0.383758544921875 +80063 0.35687255859375 +80064 0.31182861328125 +80065 0.250885009765625 +80066 0.1654052734375 +80067 0.035247802734375 +80068 -0.142059326171875 +80069 -0.33563232421875 +80070 -0.5345458984375 +80071 -0.72186279296875 +80072 -0.836669921875 +80073 -0.8326416015625 +80074 -0.7296142578125 +80075 -0.582550048828125 +80076 -0.440093994140625 +80077 -0.324310302734375 +80078 -0.20147705078125 +80079 -0.044647216796875 +80080 0.103973388671875 +80081 0.202392578125 +80082 0.264495849609375 +80083 0.338897705078125 +80084 0.443817138671875 +80085 0.545074462890625 +80086 0.6173095703125 +80087 0.6524658203125 +80088 0.66339111328125 +80089 0.6561279296875 +80090 0.606781005859375 +80091 0.501190185546875 +80092 0.352783203125 +80093 0.176544189453125 +80094 -0.034820556640625 +80095 -0.258209228515625 +80096 -0.44244384765625 +80097 -0.5753173828125 +80098 -0.65203857421875 +80099 -0.641632080078125 +80100 -0.562164306640625 +80101 -0.458038330078125 +80102 -0.350555419921875 +80103 -0.260528564453125 +80104 -0.192108154296875 +80105 -0.141937255859375 +80106 -0.1021728515625 +80107 -0.062896728515625 +80108 -0.011932373046875 +80109 0.062835693359375 +80110 0.148712158203125 +80111 0.241729736328125 +80112 0.34912109375 +80113 0.457305908203125 +80114 0.54388427734375 +80115 0.5728759765625 +80116 0.506591796875 +80117 0.351226806640625 +80118 0.146514892578125 +80119 -0.05523681640625 +80120 -0.21624755859375 +80121 -0.334930419921875 +80122 -0.402984619140625 +80123 -0.4412841796875 +80124 -0.49578857421875 +80125 -0.5601806640625 +80126 -0.600738525390625 +80127 -0.584228515625 +80128 -0.47930908203125 +80129 -0.27935791015625 +80130 -0.0089111328125 +80131 0.268798828125 +80132 0.482818603515625 +80133 0.60369873046875 +80134 0.650421142578125 +80135 0.66400146484375 +80136 0.6414794921875 +80137 0.572540283203125 +80138 0.498138427734375 +80139 0.439453125 +80140 0.375518798828125 +80141 0.274505615234375 +80142 0.1087646484375 +80143 -0.099395751953125 +80144 -0.3182373046875 +80145 -0.5489501953125 +80146 -0.7738037109375 +80147 -0.86383056640625 +80148 -0.870391845703125 +80149 -0.86895751953125 +80150 -0.861053466796875 +80151 -0.765869140625 +80152 -0.5301513671875 +80153 -0.214691162109375 +80154 0.137359619140625 +80155 0.474822998046875 +80156 0.76239013671875 +80157 0.867462158203125 +80158 0.870361328125 +80159 0.86480712890625 +80160 0.831817626953125 +80161 0.677581787109375 +80162 0.495880126953125 +80163 0.30767822265625 +80164 0.116180419921875 +80165 -0.110748291015625 +80166 -0.381805419921875 +80167 -0.6572265625 +80168 -0.857421875 +80169 -0.870391845703125 +80170 -0.870391845703125 +80171 -0.86444091796875 +80172 -0.85723876953125 +80173 -0.790008544921875 +80174 -0.62847900390625 +80175 -0.3956298828125 +80176 -0.126708984375 +80177 0.150115966796875 +80178 0.424041748046875 +80179 0.670623779296875 +80180 0.854522705078125 +80181 0.866485595703125 +80182 0.86920166015625 +80183 0.8653564453125 +80184 0.857147216796875 +80185 0.766845703125 +80186 0.628509521484375 +80187 0.462127685546875 +80188 0.297210693359375 +80189 0.14862060546875 +80190 -0.00537109375 +80191 -0.15753173828125 +80192 -0.31304931640625 +80193 -0.48876953125 +80194 -0.6416015625 +80195 -0.751373291015625 +80196 -0.84619140625 +80197 -0.861297607421875 +80198 -0.863250732421875 +80199 -0.856597900390625 +80200 -0.7498779296875 +80201 -0.624542236328125 +80202 -0.47808837890625 +80203 -0.253387451171875 +80204 0.003692626953125 +80205 0.2257080078125 +80206 0.427154541015625 +80207 0.643218994140625 +80208 0.855926513671875 +80209 0.870361328125 +80210 0.870361328125 +80211 0.862762451171875 +80212 0.79669189453125 +80213 0.595794677734375 +80214 0.362152099609375 +80215 0.1270751953125 +80216 -0.086944580078125 +80217 -0.2784423828125 +80218 -0.484832763671875 +80219 -0.729583740234375 +80220 -0.86688232421875 +80221 -0.870391845703125 +80222 -0.86859130859375 +80223 -0.86279296875 +80224 -0.817962646484375 +80225 -0.6116943359375 +80226 -0.3128662109375 +80227 0.039398193359375 +80228 0.422821044921875 +80229 0.805145263671875 +80230 0.870361328125 +80231 0.870361328125 +80232 0.860015869140625 +80233 0.727935791015625 +80234 0.48114013671875 +80235 0.2059326171875 +80236 -0.06103515625 +80237 -0.29913330078125 +80238 -0.516204833984375 +80239 -0.7252197265625 +80240 -0.85980224609375 +80241 -0.870391845703125 +80242 -0.870391845703125 +80243 -0.858062744140625 +80244 -0.673004150390625 +80245 -0.42694091796875 +80246 -0.2100830078125 +80247 -0.0362548828125 +80248 0.10943603515625 +80249 0.23516845703125 +80250 0.373687744140625 +80251 0.517791748046875 +80252 0.602783203125 +80253 0.635711669921875 +80254 0.655181884765625 +80255 0.65948486328125 +80256 0.651275634765625 +80257 0.61846923828125 +80258 0.53753662109375 +80259 0.404144287109375 +80260 0.22186279296875 +80261 0.003997802734375 +80262 -0.22100830078125 +80263 -0.42449951171875 +80264 -0.579833984375 +80265 -0.641876220703125 +80266 -0.6177978515625 +80267 -0.575531005859375 +80268 -0.526336669921875 +80269 -0.42645263671875 +80270 -0.2581787109375 +80271 -0.068695068359375 +80272 0.09222412109375 +80273 0.232147216796875 +80274 0.3509521484375 +80275 0.410064697265625 +80276 0.372955322265625 +80277 0.2554931640625 +80278 0.10711669921875 +80279 -0.052886962890625 +80280 -0.186279296875 +80281 -0.23291015625 +80282 -0.209442138671875 +80283 -0.174163818359375 +80284 -0.126739501953125 +80285 -0.048126220703125 +80286 0.0426025390625 +80287 0.10748291015625 +80288 0.1409912109375 +80289 0.19708251953125 +80290 0.273651123046875 +80291 0.31768798828125 +80292 0.341094970703125 +80293 0.368011474609375 +80294 0.37249755859375 +80295 0.30072021484375 +80296 0.1517333984375 +80297 -0.01470947265625 +80298 -0.1883544921875 +80299 -0.372711181640625 +80300 -0.51397705078125 +80301 -0.57177734375 +80302 -0.53948974609375 +80303 -0.43511962890625 +80304 -0.2962646484375 +80305 -0.161102294921875 +80306 -0.0435791015625 +80307 0.060394287109375 +80308 0.13665771484375 +80309 0.170135498046875 +80310 0.16552734375 +80311 0.15728759765625 +80312 0.150787353515625 +80313 0.12200927734375 +80314 0.080108642578125 +80315 0.05126953125 +80316 0.062896728515625 +80317 0.09271240234375 +80318 0.092987060546875 +80319 0.07855224609375 +80320 0.06427001953125 +80321 0.0347900390625 +80322 -0.01171875 +80323 -0.056060791015625 +80324 -0.055511474609375 +80325 -0.010467529296875 +80326 0.02508544921875 +80327 0.025665283203125 +80328 0.017333984375 +80329 0.00189208984375 +80330 -0.03173828125 +80331 -0.071502685546875 +80332 -0.13543701171875 +80333 -0.219970703125 +80334 -0.300506591796875 +80335 -0.376312255859375 +80336 -0.416107177734375 +80337 -0.371124267578125 +80338 -0.242279052734375 +80339 -0.069732666015625 +80340 0.125640869140625 +80341 0.31268310546875 +80342 0.45501708984375 +80343 0.554779052734375 +80344 0.61065673828125 +80345 0.610931396484375 +80346 0.531463623046875 +80347 0.3883056640625 +80348 0.23468017578125 +80349 0.095245361328125 +80350 -0.00396728515625 +80351 -0.04852294921875 +80352 -0.055145263671875 +80353 -0.0758056640625 +80354 -0.138702392578125 +80355 -0.209197998046875 +80356 -0.289031982421875 +80357 -0.37884521484375 +80358 -0.456329345703125 +80359 -0.51641845703125 +80360 -0.519287109375 +80361 -0.458251953125 +80362 -0.384796142578125 +80363 -0.323699951171875 +80364 -0.269287109375 +80365 -0.1951904296875 +80366 -0.100006103515625 +80367 -0.01055908203125 +80368 0.1033935546875 +80369 0.24908447265625 +80370 0.373199462890625 +80371 0.45806884765625 +80372 0.511474609375 +80373 0.565399169921875 +80374 0.61138916015625 +80375 0.5897216796875 +80376 0.4906005859375 +80377 0.33148193359375 +80378 0.147796630859375 +80379 -0.01873779296875 +80380 -0.140289306640625 +80381 -0.191986083984375 +80382 -0.184295654296875 +80383 -0.161834716796875 +80384 -0.166595458984375 +80385 -0.19390869140625 +80386 -0.22442626953125 +80387 -0.279754638671875 +80388 -0.3389892578125 +80389 -0.3543701171875 +80390 -0.348175048828125 +80391 -0.32598876953125 +80392 -0.2581787109375 +80393 -0.139801025390625 +80394 0.014617919921875 +80395 0.144378662109375 +80396 0.221038818359375 +80397 0.27069091796875 +80398 0.294036865234375 +80399 0.311767578125 +80400 0.339141845703125 +80401 0.360260009765625 +80402 0.360504150390625 +80403 0.308380126953125 +80404 0.18170166015625 +80405 0.0047607421875 +80406 -0.17559814453125 +80407 -0.3143310546875 +80408 -0.36785888671875 +80409 -0.36248779296875 +80410 -0.343536376953125 +80411 -0.3018798828125 +80412 -0.231414794921875 +80413 -0.117645263671875 +80414 0.007049560546875 +80415 0.087982177734375 +80416 0.13946533203125 +80417 0.17425537109375 +80418 0.188201904296875 +80419 0.171234130859375 +80420 0.118438720703125 +80421 0.05706787109375 +80422 -0.010711669921875 +80423 -0.0914306640625 +80424 -0.162322998046875 +80425 -0.194549560546875 +80426 -0.1492919921875 +80427 -0.02166748046875 +80428 0.124053955078125 +80429 0.211151123046875 +80430 0.240447998046875 +80431 0.242218017578125 +80432 0.2257080078125 +80433 0.194366455078125 +80434 0.115509033203125 +80435 0.0128173828125 +80436 -0.053802490234375 +80437 -0.110626220703125 +80438 -0.199493408203125 +80439 -0.29437255859375 +80440 -0.33221435546875 +80441 -0.27972412109375 +80442 -0.185333251953125 +80443 -0.128204345703125 +80444 -0.115692138671875 +80445 -0.116455078125 +80446 -0.105926513671875 +80447 -0.053955078125 +80448 0.048797607421875 +80449 0.157318115234375 +80450 0.212005615234375 +80451 0.218475341796875 +80452 0.23724365234375 +80453 0.30535888671875 +80454 0.38128662109375 +80455 0.404449462890625 +80456 0.3944091796875 +80457 0.3885498046875 +80458 0.362640380859375 +80459 0.27362060546875 +80460 0.11712646484375 +80461 -0.054901123046875 +80462 -0.19085693359375 +80463 -0.28570556640625 +80464 -0.339263916015625 +80465 -0.3775634765625 +80466 -0.445709228515625 +80467 -0.535064697265625 +80468 -0.629058837890625 +80469 -0.697601318359375 +80470 -0.70391845703125 +80471 -0.6424560546875 +80472 -0.491241455078125 +80473 -0.265716552734375 +80474 -0.023712158203125 +80475 0.201751708984375 +80476 0.375823974609375 +80477 0.485076904296875 +80478 0.56884765625 +80479 0.634765625 +80480 0.63763427734375 +80481 0.5660400390625 +80482 0.4720458984375 +80483 0.40692138671875 +80484 0.3778076171875 +80485 0.376953125 +80486 0.371978759765625 +80487 0.313140869140625 +80488 0.184417724609375 +80489 0.011199951171875 +80490 -0.171051025390625 +80491 -0.33740234375 +80492 -0.47198486328125 +80493 -0.560394287109375 +80494 -0.58056640625 +80495 -0.54754638671875 +80496 -0.508575439453125 +80497 -0.459503173828125 +80498 -0.394378662109375 +80499 -0.35260009765625 +80500 -0.31170654296875 +80501 -0.197418212890625 +80502 -0.007965087890625 +80503 0.207489013671875 +80504 0.409210205078125 +80505 0.57208251953125 +80506 0.66595458984375 +80507 0.65875244140625 +80508 0.56744384765625 +80509 0.431396484375 +80510 0.29443359375 +80511 0.182464599609375 +80512 0.06365966796875 +80513 -0.075958251953125 +80514 -0.189422607421875 +80515 -0.271942138671875 +80516 -0.342529296875 +80517 -0.364166259765625 +80518 -0.327239990234375 +80519 -0.2769775390625 +80520 -0.253692626953125 +80521 -0.24365234375 +80522 -0.1983642578125 +80523 -0.116241455078125 +80524 -0.036834716796875 +80525 0.034881591796875 +80526 0.09124755859375 +80527 0.10888671875 +80528 0.125518798828125 +80529 0.15771484375 +80530 0.17828369140625 +80531 0.17108154296875 +80532 0.129974365234375 +80533 0.082427978515625 +80534 0.027679443359375 +80535 -0.065643310546875 +80536 -0.15936279296875 +80537 -0.21307373046875 +80538 -0.234649658203125 +80539 -0.2001953125 +80540 -0.119171142578125 +80541 -0.024749755859375 +80542 0.085784912109375 +80543 0.178131103515625 +80544 0.215576171875 +80545 0.211456298828125 +80546 0.17523193359375 +80547 0.128753662109375 +80548 0.1019287109375 +80549 0.0743408203125 +80550 0.04327392578125 +80551 0.038177490234375 +80552 0.076263427734375 +80553 0.14105224609375 +80554 0.186431884765625 +80555 0.188812255859375 +80556 0.1390380859375 +80557 0.041778564453125 +80558 -0.079437255859375 +80559 -0.219390869140625 +80560 -0.367828369140625 +80561 -0.494873046875 +80562 -0.556243896484375 +80563 -0.508697509765625 +80564 -0.3756103515625 +80565 -0.218902587890625 +80566 -0.063751220703125 +80567 0.091552734375 +80568 0.23602294921875 +80569 0.342987060546875 +80570 0.39520263671875 +80571 0.389373779296875 +80572 0.324249267578125 +80573 0.224090576171875 +80574 0.124267578125 +80575 0.037078857421875 +80576 -0.010101318359375 +80577 -0.019439697265625 +80578 -0.022796630859375 +80579 -0.001556396484375 +80580 0.056304931640625 +80581 0.106719970703125 +80582 0.096893310546875 +80583 0.042694091796875 +80584 -0.018035888671875 +80585 -0.07586669921875 +80586 -0.11944580078125 +80587 -0.15972900390625 +80588 -0.202606201171875 +80589 -0.24859619140625 +80590 -0.30517578125 +80591 -0.36212158203125 +80592 -0.39141845703125 +80593 -0.35528564453125 +80594 -0.249969482421875 +80595 -0.092864990234375 +80596 0.08905029296875 +80597 0.2352294921875 +80598 0.318817138671875 +80599 0.358642578125 +80600 0.347747802734375 +80601 0.28564453125 +80602 0.223175048828125 +80603 0.196746826171875 +80604 0.179840087890625 +80605 0.155548095703125 +80606 0.151214599609375 +80607 0.156951904296875 +80608 0.13177490234375 +80609 0.100799560546875 +80610 0.087127685546875 +80611 0.05487060546875 +80612 -0.009002685546875 +80613 -0.10400390625 +80614 -0.229400634765625 +80615 -0.35552978515625 +80616 -0.441925048828125 +80617 -0.473846435546875 +80618 -0.464813232421875 +80619 -0.419097900390625 +80620 -0.334320068359375 +80621 -0.227935791015625 +80622 -0.12347412109375 +80623 -0.02764892578125 +80624 0.077667236328125 +80625 0.2132568359375 +80626 0.38885498046875 +80627 0.582794189453125 +80628 0.734039306640625 +80629 0.800140380859375 +80630 0.7783203125 +80631 0.6651611328125 +80632 0.45965576171875 +80633 0.199188232421875 +80634 -0.050689697265625 +80635 -0.23297119140625 +80636 -0.33013916015625 +80637 -0.368408203125 +80638 -0.378936767578125 +80639 -0.376983642578125 +80640 -0.37969970703125 +80641 -0.391510009765625 +80642 -0.385345458984375 +80643 -0.3419189453125 +80644 -0.28289794921875 +80645 -0.251617431640625 +80646 -0.266143798828125 +80647 -0.273345947265625 +80648 -0.216796875 +80649 -0.128265380859375 +80650 -0.068145751953125 +80651 -0.0430908203125 +80652 -0.024444580078125 +80653 0.020721435546875 +80654 0.124481201171875 +80655 0.25787353515625 +80656 0.379119873046875 +80657 0.47991943359375 +80658 0.5281982421875 +80659 0.511138916015625 +80660 0.456207275390625 +80661 0.407470703125 +80662 0.383758544921875 +80663 0.35687255859375 +80664 0.31182861328125 +80665 0.250885009765625 +80666 0.1654052734375 +80667 0.035247802734375 +80668 -0.142059326171875 +80669 -0.33563232421875 +80670 -0.5345458984375 +80671 -0.72186279296875 +80672 -0.836669921875 +80673 -0.8326416015625 +80674 -0.7296142578125 +80675 -0.582550048828125 +80676 -0.440093994140625 +80677 -0.324310302734375 +80678 -0.20147705078125 +80679 -0.044647216796875 +80680 0.103973388671875 +80681 0.202392578125 +80682 0.264495849609375 +80683 0.338897705078125 +80684 0.443817138671875 +80685 0.545074462890625 +80686 0.6173095703125 +80687 0.6524658203125 +80688 0.66339111328125 +80689 0.6561279296875 +80690 0.606781005859375 +80691 0.501190185546875 +80692 0.352783203125 +80693 0.176544189453125 +80694 -0.034820556640625 +80695 -0.258209228515625 +80696 -0.44244384765625 +80697 -0.5753173828125 +80698 -0.65203857421875 +80699 -0.641632080078125 +80700 -0.562164306640625 +80701 -0.458038330078125 +80702 -0.350555419921875 +80703 -0.260528564453125 +80704 -0.192108154296875 +80705 -0.141937255859375 +80706 -0.1021728515625 +80707 -0.062896728515625 +80708 -0.011932373046875 +80709 0.062835693359375 +80710 0.148712158203125 +80711 0.241729736328125 +80712 0.34912109375 +80713 0.457305908203125 +80714 0.54388427734375 +80715 0.5728759765625 +80716 0.506591796875 +80717 0.351226806640625 +80718 0.146514892578125 +80719 -0.05523681640625 +80720 -0.21624755859375 +80721 -0.334930419921875 +80722 -0.402984619140625 +80723 -0.4412841796875 +80724 -0.49578857421875 +80725 -0.5601806640625 +80726 -0.600738525390625 +80727 -0.584228515625 +80728 -0.47930908203125 +80729 -0.27935791015625 +80730 -0.0089111328125 +80731 0.268798828125 +80732 0.482818603515625 +80733 0.60369873046875 +80734 0.650421142578125 +80735 0.66400146484375 +80736 0.6414794921875 +80737 0.572540283203125 +80738 0.498138427734375 +80739 0.439453125 +80740 0.375518798828125 +80741 0.274505615234375 +80742 0.1087646484375 +80743 -0.099395751953125 +80744 -0.3182373046875 +80745 -0.5489501953125 +80746 -0.7738037109375 +80747 -0.86383056640625 +80748 -0.870391845703125 +80749 -0.86895751953125 +80750 -0.861053466796875 +80751 -0.765869140625 +80752 -0.5301513671875 +80753 -0.214691162109375 +80754 0.137359619140625 +80755 0.474822998046875 +80756 0.76239013671875 +80757 0.867462158203125 +80758 0.870361328125 +80759 0.86480712890625 +80760 0.831817626953125 +80761 0.677581787109375 +80762 0.495880126953125 +80763 0.30767822265625 +80764 0.116180419921875 +80765 -0.110748291015625 +80766 -0.381805419921875 +80767 -0.6572265625 +80768 -0.857421875 +80769 -0.870391845703125 +80770 -0.870391845703125 +80771 -0.86444091796875 +80772 -0.85723876953125 +80773 -0.790008544921875 +80774 -0.62847900390625 +80775 -0.3956298828125 +80776 -0.126708984375 +80777 0.150115966796875 +80778 0.424041748046875 +80779 0.670623779296875 +80780 0.854522705078125 +80781 0.866485595703125 +80782 0.86920166015625 +80783 0.8653564453125 +80784 0.857147216796875 +80785 0.766845703125 +80786 0.628509521484375 +80787 0.462127685546875 +80788 0.297210693359375 +80789 0.14862060546875 +80790 -0.00537109375 +80791 -0.15753173828125 +80792 -0.31304931640625 +80793 -0.48876953125 +80794 -0.6416015625 +80795 -0.751373291015625 +80796 -0.84619140625 +80797 -0.861297607421875 +80798 -0.863250732421875 +80799 -0.856597900390625 +80800 -0.7498779296875 +80801 -0.624542236328125 +80802 -0.47808837890625 +80803 -0.253387451171875 +80804 0.003692626953125 +80805 0.2257080078125 +80806 0.427154541015625 +80807 0.643218994140625 +80808 0.855926513671875 +80809 0.870361328125 +80810 0.870361328125 +80811 0.862762451171875 +80812 0.79669189453125 +80813 0.595794677734375 +80814 0.362152099609375 +80815 0.1270751953125 +80816 -0.086944580078125 +80817 -0.2784423828125 +80818 -0.484832763671875 +80819 -0.729583740234375 +80820 -0.86688232421875 +80821 -0.870391845703125 +80822 -0.86859130859375 +80823 -0.86279296875 +80824 -0.817962646484375 +80825 -0.6116943359375 +80826 -0.3128662109375 +80827 0.039398193359375 +80828 0.422821044921875 +80829 0.805145263671875 +80830 0.870361328125 +80831 0.870361328125 +80832 0.860015869140625 +80833 0.727935791015625 +80834 0.48114013671875 +80835 0.2059326171875 +80836 -0.06103515625 +80837 -0.29913330078125 +80838 -0.516204833984375 +80839 -0.7252197265625 +80840 -0.85980224609375 +80841 -0.870391845703125 +80842 -0.870391845703125 +80843 -0.858062744140625 +80844 -0.673004150390625 +80845 -0.42694091796875 +80846 -0.2100830078125 +80847 -0.0362548828125 +80848 0.10943603515625 +80849 0.23516845703125 +80850 0.373687744140625 +80851 0.517791748046875 +80852 0.602783203125 +80853 0.635711669921875 +80854 0.655181884765625 +80855 0.65948486328125 +80856 0.651275634765625 +80857 0.61846923828125 +80858 0.53753662109375 +80859 0.404144287109375 +80860 0.22186279296875 +80861 0.003997802734375 +80862 -0.22100830078125 +80863 -0.42449951171875 +80864 -0.579833984375 +80865 -0.641876220703125 +80866 -0.6177978515625 +80867 -0.575531005859375 +80868 -0.526336669921875 +80869 -0.42645263671875 +80870 -0.2581787109375 +80871 -0.068695068359375 +80872 0.09222412109375 +80873 0.232147216796875 +80874 0.3509521484375 +80875 0.410064697265625 +80876 0.372955322265625 +80877 0.2554931640625 +80878 0.10711669921875 +80879 -0.052886962890625 +80880 -0.186279296875 +80881 -0.23291015625 +80882 -0.209442138671875 +80883 -0.174163818359375 +80884 -0.126739501953125 +80885 -0.048126220703125 +80886 0.0426025390625 +80887 0.10748291015625 +80888 0.1409912109375 +80889 0.19708251953125 +80890 0.273651123046875 +80891 0.31768798828125 +80892 0.341094970703125 +80893 0.368011474609375 +80894 0.37249755859375 +80895 0.30072021484375 +80896 0.1517333984375 +80897 -0.01470947265625 +80898 -0.1883544921875 +80899 -0.372711181640625 +80900 -0.51397705078125 +80901 -0.57177734375 +80902 -0.53948974609375 +80903 -0.43511962890625 +80904 -0.2962646484375 +80905 -0.161102294921875 +80906 -0.0435791015625 +80907 0.060394287109375 +80908 0.13665771484375 +80909 0.170135498046875 +80910 0.16552734375 +80911 0.15728759765625 +80912 0.150787353515625 +80913 0.12200927734375 +80914 0.080108642578125 +80915 0.05126953125 +80916 0.062896728515625 +80917 0.09271240234375 +80918 0.092987060546875 +80919 0.07855224609375 +80920 0.06427001953125 +80921 0.0347900390625 +80922 -0.01171875 +80923 -0.056060791015625 +80924 -0.055511474609375 +80925 -0.010467529296875 +80926 0.02508544921875 +80927 0.025665283203125 +80928 0.017333984375 +80929 0.00189208984375 +80930 -0.03173828125 +80931 -0.071502685546875 +80932 -0.13543701171875 +80933 -0.219970703125 +80934 -0.300506591796875 +80935 -0.376312255859375 +80936 -0.416107177734375 +80937 -0.371124267578125 +80938 -0.242279052734375 +80939 -0.069732666015625 +80940 0.125640869140625 +80941 0.31268310546875 +80942 0.45501708984375 +80943 0.554779052734375 +80944 0.61065673828125 +80945 0.610931396484375 +80946 0.531463623046875 +80947 0.3883056640625 +80948 0.23468017578125 +80949 0.095245361328125 +80950 -0.00396728515625 +80951 -0.04852294921875 +80952 -0.055145263671875 +80953 -0.0758056640625 +80954 -0.138702392578125 +80955 -0.209197998046875 +80956 -0.289031982421875 +80957 -0.37884521484375 +80958 -0.456329345703125 +80959 -0.51641845703125 +80960 -0.519287109375 +80961 -0.458251953125 +80962 -0.384796142578125 +80963 -0.323699951171875 +80964 -0.269287109375 +80965 -0.1951904296875 +80966 -0.100006103515625 +80967 -0.01055908203125 +80968 0.1033935546875 +80969 0.24908447265625 +80970 0.373199462890625 +80971 0.45806884765625 +80972 0.511474609375 +80973 0.565399169921875 +80974 0.61138916015625 +80975 0.5897216796875 +80976 0.4906005859375 +80977 0.33148193359375 +80978 0.147796630859375 +80979 -0.01873779296875 +80980 -0.140289306640625 +80981 -0.191986083984375 +80982 -0.184295654296875 +80983 -0.161834716796875 +80984 -0.166595458984375 +80985 -0.19390869140625 +80986 -0.22442626953125 +80987 -0.279754638671875 +80988 -0.3389892578125 +80989 -0.3543701171875 +80990 -0.348175048828125 +80991 -0.32598876953125 +80992 -0.2581787109375 +80993 -0.139801025390625 +80994 0.014617919921875 +80995 0.144378662109375 +80996 0.221038818359375 +80997 0.27069091796875 +80998 0.294036865234375 +80999 0.311767578125 +81000 0.339141845703125 +81001 0.360260009765625 +81002 0.360504150390625 +81003 0.308380126953125 +81004 0.18170166015625 +81005 0.0047607421875 +81006 -0.17559814453125 +81007 -0.3143310546875 +81008 -0.36785888671875 +81009 -0.36248779296875 +81010 -0.343536376953125 +81011 -0.3018798828125 +81012 -0.231414794921875 +81013 -0.117645263671875 +81014 0.007049560546875 +81015 0.087982177734375 +81016 0.13946533203125 +81017 0.17425537109375 +81018 0.188201904296875 +81019 0.171234130859375 +81020 0.118438720703125 +81021 0.05706787109375 +81022 -0.010711669921875 +81023 -0.0914306640625 +81024 -0.162322998046875 +81025 -0.194549560546875 +81026 -0.1492919921875 +81027 -0.02166748046875 +81028 0.124053955078125 +81029 0.211151123046875 +81030 0.240447998046875 +81031 0.242218017578125 +81032 0.2257080078125 +81033 0.194366455078125 +81034 0.115509033203125 +81035 0.0128173828125 +81036 -0.053802490234375 +81037 -0.110626220703125 +81038 -0.199493408203125 +81039 -0.29437255859375 +81040 -0.33221435546875 +81041 -0.27972412109375 +81042 -0.185333251953125 +81043 -0.128204345703125 +81044 -0.115692138671875 +81045 -0.116455078125 +81046 -0.105926513671875 +81047 -0.053955078125 +81048 0.048797607421875 +81049 0.157318115234375 +81050 0.212005615234375 +81051 0.218475341796875 +81052 0.23724365234375 +81053 0.30535888671875 +81054 0.38128662109375 +81055 0.404449462890625 +81056 0.3944091796875 +81057 0.3885498046875 +81058 0.362640380859375 +81059 0.27362060546875 +81060 0.11712646484375 +81061 -0.054901123046875 +81062 -0.19085693359375 +81063 -0.28570556640625 +81064 -0.339263916015625 +81065 -0.3775634765625 +81066 -0.445709228515625 +81067 -0.535064697265625 +81068 -0.629058837890625 +81069 -0.697601318359375 +81070 -0.70391845703125 +81071 -0.6424560546875 +81072 -0.491241455078125 +81073 -0.265716552734375 +81074 -0.023712158203125 +81075 0.201751708984375 +81076 0.375823974609375 +81077 0.485076904296875 +81078 0.56884765625 +81079 0.634765625 +81080 0.63763427734375 +81081 0.5660400390625 +81082 0.4720458984375 +81083 0.40692138671875 +81084 0.3778076171875 +81085 0.376953125 +81086 0.371978759765625 +81087 0.313140869140625 +81088 0.184417724609375 +81089 0.011199951171875 +81090 -0.171051025390625 +81091 -0.33740234375 +81092 -0.47198486328125 +81093 -0.560394287109375 +81094 -0.58056640625 +81095 -0.54754638671875 +81096 -0.508575439453125 +81097 -0.459503173828125 +81098 -0.394378662109375 +81099 -0.35260009765625 +81100 -0.31170654296875 +81101 -0.197418212890625 +81102 -0.007965087890625 +81103 0.207489013671875 +81104 0.409210205078125 +81105 0.57208251953125 +81106 0.66595458984375 +81107 0.65875244140625 +81108 0.56744384765625 +81109 0.431396484375 +81110 0.29443359375 +81111 0.182464599609375 +81112 0.06365966796875 +81113 -0.075958251953125 +81114 -0.189422607421875 +81115 -0.271942138671875 +81116 -0.342529296875 +81117 -0.364166259765625 +81118 -0.327239990234375 +81119 -0.2769775390625 +81120 -0.253692626953125 +81121 -0.24365234375 +81122 -0.1983642578125 +81123 -0.116241455078125 +81124 -0.036834716796875 +81125 0.034881591796875 +81126 0.09124755859375 +81127 0.10888671875 +81128 0.125518798828125 +81129 0.15771484375 +81130 0.17828369140625 +81131 0.17108154296875 +81132 0.129974365234375 +81133 0.082427978515625 +81134 0.027679443359375 +81135 -0.065643310546875 +81136 -0.15936279296875 +81137 -0.21307373046875 +81138 -0.234649658203125 +81139 -0.2001953125 +81140 -0.119171142578125 +81141 -0.024749755859375 +81142 0.085784912109375 +81143 0.178131103515625 +81144 0.215576171875 +81145 0.211456298828125 +81146 0.17523193359375 +81147 0.128753662109375 +81148 0.1019287109375 +81149 0.0743408203125 +81150 0.04327392578125 +81151 0.038177490234375 +81152 0.076263427734375 +81153 0.14105224609375 +81154 0.186431884765625 +81155 0.188812255859375 +81156 0.1390380859375 +81157 0.041778564453125 +81158 -0.079437255859375 +81159 -0.219390869140625 +81160 -0.367828369140625 +81161 -0.494873046875 +81162 -0.556243896484375 +81163 -0.508697509765625 +81164 -0.3756103515625 +81165 -0.218902587890625 +81166 -0.063751220703125 +81167 0.091552734375 +81168 0.23602294921875 +81169 0.342987060546875 +81170 0.39520263671875 +81171 0.389373779296875 +81172 0.324249267578125 +81173 0.224090576171875 +81174 0.124267578125 +81175 0.037078857421875 +81176 -0.010101318359375 +81177 -0.019439697265625 +81178 -0.022796630859375 +81179 -0.001556396484375 +81180 0.056304931640625 +81181 0.106719970703125 +81182 0.096893310546875 +81183 0.042694091796875 +81184 -0.018035888671875 +81185 -0.07586669921875 +81186 -0.11944580078125 +81187 -0.15972900390625 +81188 -0.202606201171875 +81189 -0.24859619140625 +81190 -0.30517578125 +81191 -0.36212158203125 +81192 -0.39141845703125 +81193 -0.35528564453125 +81194 -0.249969482421875 +81195 -0.092864990234375 +81196 0.08905029296875 +81197 0.2352294921875 +81198 0.318817138671875 +81199 0.358642578125 +81200 0.347747802734375 +81201 0.28564453125 +81202 0.223175048828125 +81203 0.196746826171875 +81204 0.179840087890625 +81205 0.155548095703125 +81206 0.151214599609375 +81207 0.156951904296875 +81208 0.13177490234375 +81209 0.100799560546875 +81210 0.087127685546875 +81211 0.05487060546875 +81212 -0.009002685546875 +81213 -0.10400390625 +81214 -0.229400634765625 +81215 -0.35552978515625 +81216 -0.441925048828125 +81217 -0.473846435546875 +81218 -0.464813232421875 +81219 -0.419097900390625 +81220 -0.334320068359375 +81221 -0.227935791015625 +81222 -0.12347412109375 +81223 -0.02764892578125 +81224 0.077667236328125 +81225 0.2132568359375 +81226 0.38885498046875 +81227 0.582794189453125 +81228 0.734039306640625 +81229 0.800140380859375 +81230 0.7783203125 +81231 0.6651611328125 +81232 0.45965576171875 +81233 0.199188232421875 +81234 -0.050689697265625 +81235 -0.23297119140625 +81236 -0.33013916015625 +81237 -0.368408203125 +81238 -0.378936767578125 +81239 -0.376983642578125 +81240 -0.37969970703125 +81241 -0.391510009765625 +81242 -0.385345458984375 +81243 -0.3419189453125 +81244 -0.28289794921875 +81245 -0.251617431640625 +81246 -0.266143798828125 +81247 -0.273345947265625 +81248 -0.216796875 +81249 -0.128265380859375 +81250 -0.068145751953125 +81251 -0.0430908203125 +81252 -0.024444580078125 +81253 0.020721435546875 +81254 0.124481201171875 +81255 0.25787353515625 +81256 0.379119873046875 +81257 0.47991943359375 +81258 0.5281982421875 +81259 0.511138916015625 +81260 0.456207275390625 +81261 0.407470703125 +81262 0.383758544921875 +81263 0.35687255859375 +81264 0.31182861328125 +81265 0.250885009765625 +81266 0.1654052734375 +81267 0.035247802734375 +81268 -0.142059326171875 +81269 -0.33563232421875 +81270 -0.5345458984375 +81271 -0.72186279296875 +81272 -0.836669921875 +81273 -0.8326416015625 +81274 -0.7296142578125 +81275 -0.582550048828125 +81276 -0.440093994140625 +81277 -0.324310302734375 +81278 -0.20147705078125 +81279 -0.044647216796875 +81280 0.103973388671875 +81281 0.202392578125 +81282 0.264495849609375 +81283 0.338897705078125 +81284 0.443817138671875 +81285 0.545074462890625 +81286 0.6173095703125 +81287 0.6524658203125 +81288 0.66339111328125 +81289 0.6561279296875 +81290 0.606781005859375 +81291 0.501190185546875 +81292 0.352783203125 +81293 0.176544189453125 +81294 -0.034820556640625 +81295 -0.258209228515625 +81296 -0.44244384765625 +81297 -0.5753173828125 +81298 -0.65203857421875 +81299 -0.641632080078125 +81300 -0.562164306640625 +81301 -0.458038330078125 +81302 -0.350555419921875 +81303 -0.260528564453125 +81304 -0.192108154296875 +81305 -0.141937255859375 +81306 -0.1021728515625 +81307 -0.062896728515625 +81308 -0.011932373046875 +81309 0.062835693359375 +81310 0.148712158203125 +81311 0.241729736328125 +81312 0.34912109375 +81313 0.457305908203125 +81314 0.54388427734375 +81315 0.5728759765625 +81316 0.506591796875 +81317 0.351226806640625 +81318 0.146514892578125 +81319 -0.05523681640625 +81320 -0.21624755859375 +81321 -0.334930419921875 +81322 -0.402984619140625 +81323 -0.4412841796875 +81324 -0.49578857421875 +81325 -0.5601806640625 +81326 -0.600738525390625 +81327 -0.584228515625 +81328 -0.47930908203125 +81329 -0.27935791015625 +81330 -0.0089111328125 +81331 0.268798828125 +81332 0.482818603515625 +81333 0.60369873046875 +81334 0.650421142578125 +81335 0.66400146484375 +81336 0.6414794921875 +81337 0.572540283203125 +81338 0.498138427734375 +81339 0.439453125 +81340 0.375518798828125 +81341 0.274505615234375 +81342 0.1087646484375 +81343 -0.099395751953125 +81344 -0.3182373046875 +81345 -0.5489501953125 +81346 -0.7738037109375 +81347 -0.86383056640625 +81348 -0.870391845703125 +81349 -0.86895751953125 +81350 -0.861053466796875 +81351 -0.765869140625 +81352 -0.5301513671875 +81353 -0.214691162109375 +81354 0.137359619140625 +81355 0.474822998046875 +81356 0.76239013671875 +81357 0.867462158203125 +81358 0.870361328125 +81359 0.86480712890625 +81360 0.831817626953125 +81361 0.677581787109375 +81362 0.495880126953125 +81363 0.30767822265625 +81364 0.116180419921875 +81365 -0.110748291015625 +81366 -0.381805419921875 +81367 -0.6572265625 +81368 -0.857421875 +81369 -0.870391845703125 +81370 -0.870391845703125 +81371 -0.86444091796875 +81372 -0.85723876953125 +81373 -0.790008544921875 +81374 -0.62847900390625 +81375 -0.3956298828125 +81376 -0.126708984375 +81377 0.150115966796875 +81378 0.424041748046875 +81379 0.670623779296875 +81380 0.854522705078125 +81381 0.866485595703125 +81382 0.86920166015625 +81383 0.8653564453125 +81384 0.857147216796875 +81385 0.766845703125 +81386 0.628509521484375 +81387 0.462127685546875 +81388 0.297210693359375 +81389 0.14862060546875 +81390 -0.00537109375 +81391 -0.15753173828125 +81392 -0.31304931640625 +81393 -0.48876953125 +81394 -0.6416015625 +81395 -0.751373291015625 +81396 -0.84619140625 +81397 -0.861297607421875 +81398 -0.863250732421875 +81399 -0.856597900390625 +81400 -0.7498779296875 +81401 -0.624542236328125 +81402 -0.47808837890625 +81403 -0.253387451171875 +81404 0.003692626953125 +81405 0.2257080078125 +81406 0.427154541015625 +81407 0.643218994140625 +81408 0.855926513671875 +81409 0.870361328125 +81410 0.870361328125 +81411 0.862762451171875 +81412 0.79669189453125 +81413 0.595794677734375 +81414 0.362152099609375 +81415 0.1270751953125 +81416 -0.086944580078125 +81417 -0.2784423828125 +81418 -0.484832763671875 +81419 -0.729583740234375 +81420 -0.86688232421875 +81421 -0.870391845703125 +81422 -0.86859130859375 +81423 -0.86279296875 +81424 -0.817962646484375 +81425 -0.6116943359375 +81426 -0.3128662109375 +81427 0.039398193359375 +81428 0.422821044921875 +81429 0.805145263671875 +81430 0.870361328125 +81431 0.870361328125 +81432 0.860015869140625 +81433 0.727935791015625 +81434 0.48114013671875 +81435 0.2059326171875 +81436 -0.06103515625 +81437 -0.29913330078125 +81438 -0.516204833984375 +81439 -0.7252197265625 +81440 -0.85980224609375 +81441 -0.870391845703125 +81442 -0.870391845703125 +81443 -0.858062744140625 +81444 -0.673004150390625 +81445 -0.42694091796875 +81446 -0.2100830078125 +81447 -0.0362548828125 +81448 0.10943603515625 +81449 0.23516845703125 +81450 0.373687744140625 +81451 0.517791748046875 +81452 0.602783203125 +81453 0.635711669921875 +81454 0.655181884765625 +81455 0.65948486328125 +81456 0.651275634765625 +81457 0.61846923828125 +81458 0.53753662109375 +81459 0.404144287109375 +81460 0.22186279296875 +81461 0.003997802734375 +81462 -0.22100830078125 +81463 -0.42449951171875 +81464 -0.579833984375 +81465 -0.641876220703125 +81466 -0.6177978515625 +81467 -0.575531005859375 +81468 -0.526336669921875 +81469 -0.42645263671875 +81470 -0.2581787109375 +81471 -0.068695068359375 +81472 0.09222412109375 +81473 0.232147216796875 +81474 0.3509521484375 +81475 0.410064697265625 +81476 0.372955322265625 +81477 0.2554931640625 +81478 0.10711669921875 +81479 -0.052886962890625 +81480 -0.186279296875 +81481 -0.23291015625 +81482 -0.209442138671875 +81483 -0.174163818359375 +81484 -0.126739501953125 +81485 -0.048126220703125 +81486 0.0426025390625 +81487 0.10748291015625 +81488 0.1409912109375 +81489 0.19708251953125 +81490 0.273651123046875 +81491 0.31768798828125 +81492 0.341094970703125 +81493 0.368011474609375 +81494 0.37249755859375 +81495 0.30072021484375 +81496 0.1517333984375 +81497 -0.01470947265625 +81498 -0.1883544921875 +81499 -0.372711181640625 +81500 -0.51397705078125 +81501 -0.57177734375 +81502 -0.53948974609375 +81503 -0.43511962890625 +81504 -0.2962646484375 +81505 -0.161102294921875 +81506 -0.0435791015625 +81507 0.060394287109375 +81508 0.13665771484375 +81509 0.170135498046875 +81510 0.16552734375 +81511 0.15728759765625 +81512 0.150787353515625 +81513 0.12200927734375 +81514 0.080108642578125 +81515 0.05126953125 +81516 0.062896728515625 +81517 0.09271240234375 +81518 0.092987060546875 +81519 0.07855224609375 +81520 0.06427001953125 +81521 0.0347900390625 +81522 -0.01171875 +81523 -0.056060791015625 +81524 -0.055511474609375 +81525 -0.010467529296875 +81526 0.02508544921875 +81527 0.025665283203125 +81528 0.017333984375 +81529 0.00189208984375 +81530 -0.03173828125 +81531 -0.071502685546875 +81532 -0.13543701171875 +81533 -0.219970703125 +81534 -0.300506591796875 +81535 -0.376312255859375 +81536 -0.416107177734375 +81537 -0.371124267578125 +81538 -0.242279052734375 +81539 -0.069732666015625 +81540 0.125640869140625 +81541 0.31268310546875 +81542 0.45501708984375 +81543 0.554779052734375 +81544 0.61065673828125 +81545 0.610931396484375 +81546 0.531463623046875 +81547 0.3883056640625 +81548 0.23468017578125 +81549 0.095245361328125 +81550 -0.00396728515625 +81551 -0.04852294921875 +81552 -0.055145263671875 +81553 -0.0758056640625 +81554 -0.138702392578125 +81555 -0.209197998046875 +81556 -0.289031982421875 +81557 -0.37884521484375 +81558 -0.456329345703125 +81559 -0.51641845703125 +81560 -0.519287109375 +81561 -0.458251953125 +81562 -0.384796142578125 +81563 -0.323699951171875 +81564 -0.269287109375 +81565 -0.1951904296875 +81566 -0.100006103515625 +81567 -0.01055908203125 +81568 0.1033935546875 +81569 0.24908447265625 +81570 0.373199462890625 +81571 0.45806884765625 +81572 0.511474609375 +81573 0.565399169921875 +81574 0.61138916015625 +81575 0.5897216796875 +81576 0.4906005859375 +81577 0.33148193359375 +81578 0.147796630859375 +81579 -0.01873779296875 +81580 -0.140289306640625 +81581 -0.191986083984375 +81582 -0.184295654296875 +81583 -0.161834716796875 +81584 -0.166595458984375 +81585 -0.19390869140625 +81586 -0.22442626953125 +81587 -0.279754638671875 +81588 -0.3389892578125 +81589 -0.3543701171875 +81590 -0.348175048828125 +81591 -0.32598876953125 +81592 -0.2581787109375 +81593 -0.139801025390625 +81594 0.014617919921875 +81595 0.144378662109375 +81596 0.221038818359375 +81597 0.27069091796875 +81598 0.294036865234375 +81599 0.311767578125 +81600 0.339141845703125 +81601 0.360260009765625 +81602 0.360504150390625 +81603 0.308380126953125 +81604 0.18170166015625 +81605 0.0047607421875 +81606 -0.17559814453125 +81607 -0.3143310546875 +81608 -0.36785888671875 +81609 -0.36248779296875 +81610 -0.343536376953125 +81611 -0.3018798828125 +81612 -0.231414794921875 +81613 -0.117645263671875 +81614 0.007049560546875 +81615 0.087982177734375 +81616 0.13946533203125 +81617 0.17425537109375 +81618 0.188201904296875 +81619 0.171234130859375 +81620 0.118438720703125 +81621 0.05706787109375 +81622 -0.010711669921875 +81623 -0.0914306640625 +81624 -0.162322998046875 +81625 -0.194549560546875 +81626 -0.1492919921875 +81627 -0.02166748046875 +81628 0.124053955078125 +81629 0.211151123046875 +81630 0.240447998046875 +81631 0.242218017578125 +81632 0.2257080078125 +81633 0.194366455078125 +81634 0.115509033203125 +81635 0.0128173828125 +81636 -0.053802490234375 +81637 -0.110626220703125 +81638 -0.199493408203125 +81639 -0.29437255859375 +81640 -0.33221435546875 +81641 -0.27972412109375 +81642 -0.185333251953125 +81643 -0.128204345703125 +81644 -0.115692138671875 +81645 -0.116455078125 +81646 -0.105926513671875 +81647 -0.053955078125 +81648 0.048797607421875 +81649 0.157318115234375 +81650 0.212005615234375 +81651 0.218475341796875 +81652 0.23724365234375 +81653 0.30535888671875 +81654 0.38128662109375 +81655 0.404449462890625 +81656 0.3944091796875 +81657 0.3885498046875 +81658 0.362640380859375 +81659 0.27362060546875 +81660 0.11712646484375 +81661 -0.054901123046875 +81662 -0.19085693359375 +81663 -0.28570556640625 +81664 -0.339263916015625 +81665 -0.3775634765625 +81666 -0.445709228515625 +81667 -0.535064697265625 +81668 -0.629058837890625 +81669 -0.697601318359375 +81670 -0.70391845703125 +81671 -0.6424560546875 +81672 -0.491241455078125 +81673 -0.265716552734375 +81674 -0.023712158203125 +81675 0.201751708984375 +81676 0.375823974609375 +81677 0.485076904296875 +81678 0.56884765625 +81679 0.634765625 +81680 0.63763427734375 +81681 0.5660400390625 +81682 0.4720458984375 +81683 0.40692138671875 +81684 0.3778076171875 +81685 0.376953125 +81686 0.371978759765625 +81687 0.313140869140625 +81688 0.184417724609375 +81689 0.011199951171875 +81690 -0.171051025390625 +81691 -0.33740234375 +81692 -0.47198486328125 +81693 -0.560394287109375 +81694 -0.58056640625 +81695 -0.54754638671875 +81696 -0.508575439453125 +81697 -0.459503173828125 +81698 -0.394378662109375 +81699 -0.35260009765625 +81700 -0.31170654296875 +81701 -0.197418212890625 +81702 -0.007965087890625 +81703 0.207489013671875 +81704 0.409210205078125 +81705 0.57208251953125 +81706 0.66595458984375 +81707 0.65875244140625 +81708 0.56744384765625 +81709 0.431396484375 +81710 0.29443359375 +81711 0.182464599609375 +81712 0.06365966796875 +81713 -0.075958251953125 +81714 -0.189422607421875 +81715 -0.271942138671875 +81716 -0.342529296875 +81717 -0.364166259765625 +81718 -0.327239990234375 +81719 -0.2769775390625 +81720 -0.253692626953125 +81721 -0.24365234375 +81722 -0.1983642578125 +81723 -0.116241455078125 +81724 -0.036834716796875 +81725 0.034881591796875 +81726 0.09124755859375 +81727 0.10888671875 +81728 0.125518798828125 +81729 0.15771484375 +81730 0.17828369140625 +81731 0.17108154296875 +81732 0.129974365234375 +81733 0.082427978515625 +81734 0.027679443359375 +81735 -0.065643310546875 +81736 -0.15936279296875 +81737 -0.21307373046875 +81738 -0.234649658203125 +81739 -0.2001953125 +81740 -0.119171142578125 +81741 -0.024749755859375 +81742 0.085784912109375 +81743 0.178131103515625 +81744 0.215576171875 +81745 0.211456298828125 +81746 0.17523193359375 +81747 0.128753662109375 +81748 0.1019287109375 +81749 0.0743408203125 +81750 0.04327392578125 +81751 0.038177490234375 +81752 0.076263427734375 +81753 0.14105224609375 +81754 0.186431884765625 +81755 0.188812255859375 +81756 0.1390380859375 +81757 0.041778564453125 +81758 -0.079437255859375 +81759 -0.219390869140625 +81760 -0.367828369140625 +81761 -0.494873046875 +81762 -0.556243896484375 +81763 -0.508697509765625 +81764 -0.3756103515625 +81765 -0.218902587890625 +81766 -0.063751220703125 +81767 0.091552734375 +81768 0.23602294921875 +81769 0.342987060546875 +81770 0.39520263671875 +81771 0.389373779296875 +81772 0.324249267578125 +81773 0.224090576171875 +81774 0.124267578125 +81775 0.037078857421875 +81776 -0.010101318359375 +81777 -0.019439697265625 +81778 -0.022796630859375 +81779 -0.001556396484375 +81780 0.056304931640625 +81781 0.106719970703125 +81782 0.096893310546875 +81783 0.042694091796875 +81784 -0.018035888671875 +81785 -0.07586669921875 +81786 -0.11944580078125 +81787 -0.15972900390625 +81788 -0.202606201171875 +81789 -0.24859619140625 +81790 -0.30517578125 +81791 -0.36212158203125 +81792 -0.39141845703125 +81793 -0.35528564453125 +81794 -0.249969482421875 +81795 -0.092864990234375 +81796 0.08905029296875 +81797 0.2352294921875 +81798 0.318817138671875 +81799 0.358642578125 +81800 0.347747802734375 +81801 0.28564453125 +81802 0.223175048828125 +81803 0.196746826171875 +81804 0.179840087890625 +81805 0.155548095703125 +81806 0.151214599609375 +81807 0.156951904296875 +81808 0.13177490234375 +81809 0.100799560546875 +81810 0.087127685546875 +81811 0.05487060546875 +81812 -0.009002685546875 +81813 -0.10400390625 +81814 -0.229400634765625 +81815 -0.35552978515625 +81816 -0.441925048828125 +81817 -0.473846435546875 +81818 -0.464813232421875 +81819 -0.419097900390625 +81820 -0.334320068359375 +81821 -0.227935791015625 +81822 -0.12347412109375 +81823 -0.02764892578125 +81824 0.077667236328125 +81825 0.2132568359375 +81826 0.38885498046875 +81827 0.582794189453125 +81828 0.734039306640625 +81829 0.800140380859375 +81830 0.7783203125 +81831 0.6651611328125 +81832 0.45965576171875 +81833 0.199188232421875 +81834 -0.050689697265625 +81835 -0.23297119140625 +81836 -0.33013916015625 +81837 -0.368408203125 +81838 -0.378936767578125 +81839 -0.376983642578125 +81840 -0.37969970703125 +81841 -0.391510009765625 +81842 -0.385345458984375 +81843 -0.3419189453125 +81844 -0.28289794921875 +81845 -0.251617431640625 +81846 -0.266143798828125 +81847 -0.273345947265625 +81848 -0.216796875 +81849 -0.128265380859375 +81850 -0.068145751953125 +81851 -0.0430908203125 +81852 -0.024444580078125 +81853 0.020721435546875 +81854 0.124481201171875 +81855 0.25787353515625 +81856 0.379119873046875 +81857 0.47991943359375 +81858 0.5281982421875 +81859 0.511138916015625 +81860 0.456207275390625 +81861 0.407470703125 +81862 0.383758544921875 +81863 0.35687255859375 +81864 0.31182861328125 +81865 0.250885009765625 +81866 0.1654052734375 +81867 0.035247802734375 +81868 -0.142059326171875 +81869 -0.33563232421875 +81870 -0.5345458984375 +81871 -0.72186279296875 +81872 -0.836669921875 +81873 -0.8326416015625 +81874 -0.7296142578125 +81875 -0.582550048828125 +81876 -0.440093994140625 +81877 -0.324310302734375 +81878 -0.20147705078125 +81879 -0.044647216796875 +81880 0.103973388671875 +81881 0.202392578125 +81882 0.264495849609375 +81883 0.338897705078125 +81884 0.443817138671875 +81885 0.545074462890625 +81886 0.6173095703125 +81887 0.6524658203125 +81888 0.66339111328125 +81889 0.6561279296875 +81890 0.606781005859375 +81891 0.501190185546875 +81892 0.352783203125 +81893 0.176544189453125 +81894 -0.034820556640625 +81895 -0.258209228515625 +81896 -0.44244384765625 +81897 -0.5753173828125 +81898 -0.65203857421875 +81899 -0.641632080078125 +81900 -0.562164306640625 +81901 -0.458038330078125 +81902 -0.350555419921875 +81903 -0.260528564453125 +81904 -0.192108154296875 +81905 -0.141937255859375 +81906 -0.1021728515625 +81907 -0.062896728515625 +81908 -0.011932373046875 +81909 0.062835693359375 +81910 0.148712158203125 +81911 0.241729736328125 +81912 0.34912109375 +81913 0.457305908203125 +81914 0.54388427734375 +81915 0.5728759765625 +81916 0.506591796875 +81917 0.351226806640625 +81918 0.146514892578125 +81919 -0.05523681640625 +81920 -0.21624755859375 +81921 -0.334930419921875 +81922 -0.402984619140625 +81923 -0.4412841796875 +81924 -0.49578857421875 +81925 -0.5601806640625 +81926 -0.600738525390625 +81927 -0.584228515625 +81928 -0.47930908203125 +81929 -0.27935791015625 +81930 -0.0089111328125 +81931 0.268798828125 +81932 0.482818603515625 +81933 0.60369873046875 +81934 0.650421142578125 +81935 0.66400146484375 +81936 0.6414794921875 +81937 0.572540283203125 +81938 0.498138427734375 +81939 0.439453125 +81940 0.375518798828125 +81941 0.274505615234375 +81942 0.1087646484375 +81943 -0.099395751953125 +81944 -0.3182373046875 +81945 -0.5489501953125 +81946 -0.7738037109375 +81947 -0.86383056640625 +81948 -0.870391845703125 +81949 -0.86895751953125 +81950 -0.861053466796875 +81951 -0.765869140625 +81952 -0.5301513671875 +81953 -0.214691162109375 +81954 0.137359619140625 +81955 0.474822998046875 +81956 0.76239013671875 +81957 0.867462158203125 +81958 0.870361328125 +81959 0.86480712890625 +81960 0.831817626953125 +81961 0.677581787109375 +81962 0.495880126953125 +81963 0.30767822265625 +81964 0.116180419921875 +81965 -0.110748291015625 +81966 -0.381805419921875 +81967 -0.6572265625 +81968 -0.857421875 +81969 -0.870391845703125 +81970 -0.870391845703125 +81971 -0.86444091796875 +81972 -0.85723876953125 +81973 -0.790008544921875 +81974 -0.62847900390625 +81975 -0.3956298828125 +81976 -0.126708984375 +81977 0.150115966796875 +81978 0.424041748046875 +81979 0.670623779296875 +81980 0.854522705078125 +81981 0.866485595703125 +81982 0.86920166015625 +81983 0.8653564453125 +81984 0.857147216796875 +81985 0.766845703125 +81986 0.628509521484375 +81987 0.462127685546875 +81988 0.297210693359375 +81989 0.14862060546875 +81990 -0.00537109375 +81991 -0.15753173828125 +81992 -0.31304931640625 +81993 -0.48876953125 +81994 -0.6416015625 +81995 -0.751373291015625 +81996 -0.84619140625 +81997 -0.861297607421875 +81998 -0.863250732421875 +81999 -0.856597900390625 +82000 -0.7498779296875 +82001 -0.624542236328125 +82002 -0.47808837890625 +82003 -0.253387451171875 +82004 0.003692626953125 +82005 0.2257080078125 +82006 0.427154541015625 +82007 0.643218994140625 +82008 0.855926513671875 +82009 0.870361328125 +82010 0.870361328125 +82011 0.862762451171875 +82012 0.79669189453125 +82013 0.595794677734375 +82014 0.362152099609375 +82015 0.1270751953125 +82016 -0.086944580078125 +82017 -0.2784423828125 +82018 -0.484832763671875 +82019 -0.729583740234375 +82020 -0.86688232421875 +82021 -0.870391845703125 +82022 -0.86859130859375 +82023 -0.86279296875 +82024 -0.817962646484375 +82025 -0.6116943359375 +82026 -0.3128662109375 +82027 0.039398193359375 +82028 0.422821044921875 +82029 0.805145263671875 +82030 0.870361328125 +82031 0.870361328125 +82032 0.860015869140625 +82033 0.727935791015625 +82034 0.48114013671875 +82035 0.2059326171875 +82036 -0.06103515625 +82037 -0.29913330078125 +82038 -0.516204833984375 +82039 -0.7252197265625 +82040 -0.85980224609375 +82041 -0.870391845703125 +82042 -0.870391845703125 +82043 -0.858062744140625 +82044 -0.673004150390625 +82045 -0.42694091796875 +82046 -0.2100830078125 +82047 -0.0362548828125 +82048 0.10943603515625 +82049 0.23516845703125 +82050 0.373687744140625 +82051 0.517791748046875 +82052 0.602783203125 +82053 0.635711669921875 +82054 0.655181884765625 +82055 0.65948486328125 +82056 0.651275634765625 +82057 0.61846923828125 +82058 0.53753662109375 +82059 0.404144287109375 +82060 0.22186279296875 +82061 0.003997802734375 +82062 -0.22100830078125 +82063 -0.42449951171875 +82064 -0.579833984375 +82065 -0.641876220703125 +82066 -0.6177978515625 +82067 -0.575531005859375 +82068 -0.526336669921875 +82069 -0.42645263671875 +82070 -0.2581787109375 +82071 -0.068695068359375 +82072 0.09222412109375 +82073 0.232147216796875 +82074 0.3509521484375 +82075 0.410064697265625 +82076 0.372955322265625 +82077 0.2554931640625 +82078 0.10711669921875 +82079 -0.052886962890625 +82080 -0.186279296875 +82081 -0.23291015625 +82082 -0.209442138671875 +82083 -0.174163818359375 +82084 -0.126739501953125 +82085 -0.048126220703125 +82086 0.0426025390625 +82087 0.10748291015625 +82088 0.1409912109375 +82089 0.19708251953125 +82090 0.273651123046875 +82091 0.31768798828125 +82092 0.341094970703125 +82093 0.368011474609375 +82094 0.37249755859375 +82095 0.30072021484375 +82096 0.1517333984375 +82097 -0.01470947265625 +82098 -0.1883544921875 +82099 -0.372711181640625 +82100 -0.51397705078125 +82101 -0.57177734375 +82102 -0.53948974609375 +82103 -0.43511962890625 +82104 -0.2962646484375 +82105 -0.161102294921875 +82106 -0.0435791015625 +82107 0.060394287109375 +82108 0.13665771484375 +82109 0.170135498046875 +82110 0.16552734375 +82111 0.15728759765625 +82112 0.150787353515625 +82113 0.12200927734375 +82114 0.080108642578125 +82115 0.05126953125 +82116 0.062896728515625 +82117 0.09271240234375 +82118 0.092987060546875 +82119 0.07855224609375 +82120 0.06427001953125 +82121 0.0347900390625 +82122 -0.01171875 +82123 -0.056060791015625 +82124 -0.055511474609375 +82125 -0.010467529296875 +82126 0.02508544921875 +82127 0.025665283203125 +82128 0.017333984375 +82129 0.00189208984375 +82130 -0.03173828125 +82131 -0.071502685546875 +82132 -0.13543701171875 +82133 -0.219970703125 +82134 -0.300506591796875 +82135 -0.376312255859375 +82136 -0.416107177734375 +82137 -0.371124267578125 +82138 -0.242279052734375 +82139 -0.069732666015625 +82140 0.125640869140625 +82141 0.31268310546875 +82142 0.45501708984375 +82143 0.554779052734375 +82144 0.61065673828125 +82145 0.610931396484375 +82146 0.531463623046875 +82147 0.3883056640625 +82148 0.23468017578125 +82149 0.095245361328125 +82150 -0.00396728515625 +82151 -0.04852294921875 +82152 -0.055145263671875 +82153 -0.0758056640625 +82154 -0.138702392578125 +82155 -0.209197998046875 +82156 -0.289031982421875 +82157 -0.37884521484375 +82158 -0.456329345703125 +82159 -0.51641845703125 +82160 -0.519287109375 +82161 -0.458251953125 +82162 -0.384796142578125 +82163 -0.323699951171875 +82164 -0.269287109375 +82165 -0.1951904296875 +82166 -0.100006103515625 +82167 -0.01055908203125 +82168 0.1033935546875 +82169 0.24908447265625 +82170 0.373199462890625 +82171 0.45806884765625 +82172 0.511474609375 +82173 0.565399169921875 +82174 0.61138916015625 +82175 0.5897216796875 +82176 0.4906005859375 +82177 0.33148193359375 +82178 0.147796630859375 +82179 -0.01873779296875 +82180 -0.140289306640625 +82181 -0.191986083984375 +82182 -0.184295654296875 +82183 -0.161834716796875 +82184 -0.166595458984375 +82185 -0.19390869140625 +82186 -0.22442626953125 +82187 -0.279754638671875 +82188 -0.3389892578125 +82189 -0.3543701171875 +82190 -0.348175048828125 +82191 -0.32598876953125 +82192 -0.2581787109375 +82193 -0.139801025390625 +82194 0.014617919921875 +82195 0.144378662109375 +82196 0.221038818359375 +82197 0.27069091796875 +82198 0.294036865234375 +82199 0.311767578125 +82200 0.339141845703125 +82201 0.360260009765625 +82202 0.360504150390625 +82203 0.308380126953125 +82204 0.18170166015625 +82205 0.0047607421875 +82206 -0.17559814453125 +82207 -0.3143310546875 +82208 -0.36785888671875 +82209 -0.36248779296875 +82210 -0.343536376953125 +82211 -0.3018798828125 +82212 -0.231414794921875 +82213 -0.117645263671875 +82214 0.007049560546875 +82215 0.087982177734375 +82216 0.13946533203125 +82217 0.17425537109375 +82218 0.188201904296875 +82219 0.171234130859375 +82220 0.118438720703125 +82221 0.05706787109375 +82222 -0.010711669921875 +82223 -0.0914306640625 +82224 -0.162322998046875 +82225 -0.194549560546875 +82226 -0.1492919921875 +82227 -0.02166748046875 +82228 0.124053955078125 +82229 0.211151123046875 +82230 0.240447998046875 +82231 0.242218017578125 +82232 0.2257080078125 +82233 0.194366455078125 +82234 0.115509033203125 +82235 0.0128173828125 +82236 -0.053802490234375 +82237 -0.110626220703125 +82238 -0.199493408203125 +82239 -0.29437255859375 +82240 -0.33221435546875 +82241 -0.27972412109375 +82242 -0.185333251953125 +82243 -0.128204345703125 +82244 -0.115692138671875 +82245 -0.116455078125 +82246 -0.105926513671875 +82247 -0.053955078125 +82248 0.048797607421875 +82249 0.157318115234375 +82250 0.212005615234375 +82251 0.218475341796875 +82252 0.23724365234375 +82253 0.30535888671875 +82254 0.38128662109375 +82255 0.404449462890625 +82256 0.3944091796875 +82257 0.3885498046875 +82258 0.362640380859375 +82259 0.27362060546875 +82260 0.11712646484375 +82261 -0.054901123046875 +82262 -0.19085693359375 +82263 -0.28570556640625 +82264 -0.339263916015625 +82265 -0.3775634765625 +82266 -0.445709228515625 +82267 -0.535064697265625 +82268 -0.629058837890625 +82269 -0.697601318359375 +82270 -0.70391845703125 +82271 -0.6424560546875 +82272 -0.491241455078125 +82273 -0.265716552734375 +82274 -0.023712158203125 +82275 0.201751708984375 +82276 0.375823974609375 +82277 0.485076904296875 +82278 0.56884765625 +82279 0.634765625 +82280 0.63763427734375 +82281 0.5660400390625 +82282 0.4720458984375 +82283 0.40692138671875 +82284 0.3778076171875 +82285 0.376953125 +82286 0.371978759765625 +82287 0.313140869140625 +82288 0.184417724609375 +82289 0.011199951171875 +82290 -0.171051025390625 +82291 -0.33740234375 +82292 -0.47198486328125 +82293 -0.560394287109375 +82294 -0.58056640625 +82295 -0.54754638671875 +82296 -0.508575439453125 +82297 -0.459503173828125 +82298 -0.394378662109375 +82299 -0.35260009765625 +82300 -0.31170654296875 +82301 -0.197418212890625 +82302 -0.007965087890625 +82303 0.207489013671875 +82304 0.409210205078125 +82305 0.57208251953125 +82306 0.66595458984375 +82307 0.65875244140625 +82308 0.56744384765625 +82309 0.431396484375 +82310 0.29443359375 +82311 0.182464599609375 +82312 0.06365966796875 +82313 -0.075958251953125 +82314 -0.189422607421875 +82315 -0.271942138671875 +82316 -0.342529296875 +82317 -0.364166259765625 +82318 -0.327239990234375 +82319 -0.2769775390625 +82320 -0.253692626953125 +82321 -0.24365234375 +82322 -0.1983642578125 +82323 -0.116241455078125 +82324 -0.036834716796875 +82325 0.034881591796875 +82326 0.09124755859375 +82327 0.10888671875 +82328 0.125518798828125 +82329 0.15771484375 +82330 0.17828369140625 +82331 0.17108154296875 +82332 0.129974365234375 +82333 0.082427978515625 +82334 0.027679443359375 +82335 -0.065643310546875 +82336 -0.15936279296875 +82337 -0.21307373046875 +82338 -0.234649658203125 +82339 -0.2001953125 +82340 -0.119171142578125 +82341 -0.024749755859375 +82342 0.085784912109375 +82343 0.178131103515625 +82344 0.215576171875 +82345 0.211456298828125 +82346 0.17523193359375 +82347 0.128753662109375 +82348 0.1019287109375 +82349 0.0743408203125 +82350 0.04327392578125 +82351 0.038177490234375 +82352 0.076263427734375 +82353 0.14105224609375 +82354 0.186431884765625 +82355 0.188812255859375 +82356 0.1390380859375 +82357 0.041778564453125 +82358 -0.079437255859375 +82359 -0.219390869140625 +82360 -0.367828369140625 +82361 -0.494873046875 +82362 -0.556243896484375 +82363 -0.508697509765625 +82364 -0.3756103515625 +82365 -0.218902587890625 +82366 -0.063751220703125 +82367 0.091552734375 +82368 0.23602294921875 +82369 0.342987060546875 +82370 0.39520263671875 +82371 0.389373779296875 +82372 0.324249267578125 +82373 0.224090576171875 +82374 0.124267578125 +82375 0.037078857421875 +82376 -0.010101318359375 +82377 -0.019439697265625 +82378 -0.022796630859375 +82379 -0.001556396484375 +82380 0.056304931640625 +82381 0.106719970703125 +82382 0.096893310546875 +82383 0.042694091796875 +82384 -0.018035888671875 +82385 -0.07586669921875 +82386 -0.11944580078125 +82387 -0.15972900390625 +82388 -0.202606201171875 +82389 -0.24859619140625 +82390 -0.30517578125 +82391 -0.36212158203125 +82392 -0.39141845703125 +82393 -0.35528564453125 +82394 -0.249969482421875 +82395 -0.092864990234375 +82396 0.08905029296875 +82397 0.2352294921875 +82398 0.318817138671875 +82399 0.358642578125 +82400 0.347747802734375 +82401 0.28564453125 +82402 0.223175048828125 +82403 0.196746826171875 +82404 0.179840087890625 +82405 0.155548095703125 +82406 0.151214599609375 +82407 0.156951904296875 +82408 0.13177490234375 +82409 0.100799560546875 +82410 0.087127685546875 +82411 0.05487060546875 +82412 -0.009002685546875 +82413 -0.10400390625 +82414 -0.229400634765625 +82415 -0.35552978515625 +82416 -0.441925048828125 +82417 -0.473846435546875 +82418 -0.464813232421875 +82419 -0.419097900390625 +82420 -0.334320068359375 +82421 -0.227935791015625 +82422 -0.12347412109375 +82423 -0.02764892578125 +82424 0.077667236328125 +82425 0.2132568359375 +82426 0.38885498046875 +82427 0.582794189453125 +82428 0.734039306640625 +82429 0.800140380859375 +82430 0.7783203125 +82431 0.6651611328125 +82432 0.45965576171875 +82433 0.199188232421875 +82434 -0.050689697265625 +82435 -0.23297119140625 +82436 -0.33013916015625 +82437 -0.368408203125 +82438 -0.378936767578125 +82439 -0.376983642578125 +82440 -0.37969970703125 +82441 -0.391510009765625 +82442 -0.385345458984375 +82443 -0.3419189453125 +82444 -0.28289794921875 +82445 -0.251617431640625 +82446 -0.266143798828125 +82447 -0.273345947265625 +82448 -0.216796875 +82449 -0.128265380859375 +82450 -0.068145751953125 +82451 -0.0430908203125 +82452 -0.024444580078125 +82453 0.020721435546875 +82454 0.124481201171875 +82455 0.25787353515625 +82456 0.379119873046875 +82457 0.47991943359375 +82458 0.5281982421875 +82459 0.511138916015625 +82460 0.456207275390625 +82461 0.407470703125 +82462 0.383758544921875 +82463 0.35687255859375 +82464 0.31182861328125 +82465 0.250885009765625 +82466 0.1654052734375 +82467 0.035247802734375 +82468 -0.142059326171875 +82469 -0.33563232421875 +82470 -0.5345458984375 +82471 -0.72186279296875 +82472 -0.836669921875 +82473 -0.8326416015625 +82474 -0.7296142578125 +82475 -0.582550048828125 +82476 -0.440093994140625 +82477 -0.324310302734375 +82478 -0.20147705078125 +82479 -0.044647216796875 +82480 0.103973388671875 +82481 0.202392578125 +82482 0.264495849609375 +82483 0.338897705078125 +82484 0.443817138671875 +82485 0.545074462890625 +82486 0.6173095703125 +82487 0.6524658203125 +82488 0.66339111328125 +82489 0.6561279296875 +82490 0.606781005859375 +82491 0.501190185546875 +82492 0.352783203125 +82493 0.176544189453125 +82494 -0.034820556640625 +82495 -0.258209228515625 +82496 -0.44244384765625 +82497 -0.5753173828125 +82498 -0.65203857421875 +82499 -0.641632080078125 +82500 -0.562164306640625 +82501 -0.458038330078125 +82502 -0.350555419921875 +82503 -0.260528564453125 +82504 -0.192108154296875 +82505 -0.141937255859375 +82506 -0.1021728515625 +82507 -0.062896728515625 +82508 -0.011932373046875 +82509 0.062835693359375 +82510 0.148712158203125 +82511 0.241729736328125 +82512 0.34912109375 +82513 0.457305908203125 +82514 0.54388427734375 +82515 0.5728759765625 +82516 0.506591796875 +82517 0.351226806640625 +82518 0.146514892578125 +82519 -0.05523681640625 +82520 -0.21624755859375 +82521 -0.334930419921875 +82522 -0.402984619140625 +82523 -0.4412841796875 +82524 -0.49578857421875 +82525 -0.5601806640625 +82526 -0.600738525390625 +82527 -0.584228515625 +82528 -0.47930908203125 +82529 -0.27935791015625 +82530 -0.0089111328125 +82531 0.268798828125 +82532 0.482818603515625 +82533 0.60369873046875 +82534 0.650421142578125 +82535 0.66400146484375 +82536 0.6414794921875 +82537 0.572540283203125 +82538 0.498138427734375 +82539 0.439453125 +82540 0.375518798828125 +82541 0.274505615234375 +82542 0.1087646484375 +82543 -0.099395751953125 +82544 -0.3182373046875 +82545 -0.5489501953125 +82546 -0.7738037109375 +82547 -0.86383056640625 +82548 -0.870391845703125 +82549 -0.86895751953125 +82550 -0.861053466796875 +82551 -0.765869140625 +82552 -0.5301513671875 +82553 -0.214691162109375 +82554 0.137359619140625 +82555 0.474822998046875 +82556 0.76239013671875 +82557 0.867462158203125 +82558 0.870361328125 +82559 0.86480712890625 +82560 0.831817626953125 +82561 0.677581787109375 +82562 0.495880126953125 +82563 0.30767822265625 +82564 0.116180419921875 +82565 -0.110748291015625 +82566 -0.381805419921875 +82567 -0.6572265625 +82568 -0.857421875 +82569 -0.870391845703125 +82570 -0.870391845703125 +82571 -0.86444091796875 +82572 -0.85723876953125 +82573 -0.790008544921875 +82574 -0.62847900390625 +82575 -0.3956298828125 +82576 -0.126708984375 +82577 0.150115966796875 +82578 0.424041748046875 +82579 0.670623779296875 +82580 0.854522705078125 +82581 0.866485595703125 +82582 0.86920166015625 +82583 0.8653564453125 +82584 0.857147216796875 +82585 0.766845703125 +82586 0.628509521484375 +82587 0.462127685546875 +82588 0.297210693359375 +82589 0.14862060546875 +82590 -0.00537109375 +82591 -0.15753173828125 +82592 -0.31304931640625 +82593 -0.48876953125 +82594 -0.6416015625 +82595 -0.751373291015625 +82596 -0.84619140625 +82597 -0.861297607421875 +82598 -0.863250732421875 +82599 -0.856597900390625 +82600 -0.7498779296875 +82601 -0.624542236328125 +82602 -0.47808837890625 +82603 -0.253387451171875 +82604 0.003692626953125 +82605 0.2257080078125 +82606 0.427154541015625 +82607 0.643218994140625 +82608 0.855926513671875 +82609 0.870361328125 +82610 0.870361328125 +82611 0.862762451171875 +82612 0.79669189453125 +82613 0.595794677734375 +82614 0.362152099609375 +82615 0.1270751953125 +82616 -0.086944580078125 +82617 -0.2784423828125 +82618 -0.484832763671875 +82619 -0.729583740234375 +82620 -0.86688232421875 +82621 -0.870391845703125 +82622 -0.86859130859375 +82623 -0.86279296875 +82624 -0.817962646484375 +82625 -0.6116943359375 +82626 -0.3128662109375 +82627 0.039398193359375 +82628 0.422821044921875 +82629 0.805145263671875 +82630 0.870361328125 +82631 0.870361328125 +82632 0.860015869140625 +82633 0.727935791015625 +82634 0.48114013671875 +82635 0.2059326171875 +82636 -0.06103515625 +82637 -0.29913330078125 +82638 -0.516204833984375 +82639 -0.7252197265625 +82640 -0.85980224609375 +82641 -0.870391845703125 +82642 -0.870391845703125 +82643 -0.858062744140625 +82644 -0.673004150390625 +82645 -0.42694091796875 +82646 -0.2100830078125 +82647 -0.0362548828125 +82648 0.10943603515625 +82649 0.23516845703125 +82650 0.373687744140625 +82651 0.517791748046875 +82652 0.602783203125 +82653 0.635711669921875 +82654 0.655181884765625 +82655 0.65948486328125 +82656 0.651275634765625 +82657 0.61846923828125 +82658 0.53753662109375 +82659 0.404144287109375 +82660 0.22186279296875 +82661 0.003997802734375 +82662 -0.22100830078125 +82663 -0.42449951171875 +82664 -0.579833984375 +82665 -0.641876220703125 +82666 -0.6177978515625 +82667 -0.575531005859375 +82668 -0.526336669921875 +82669 -0.42645263671875 +82670 -0.2581787109375 +82671 -0.068695068359375 +82672 0.09222412109375 +82673 0.232147216796875 +82674 0.3509521484375 +82675 0.410064697265625 +82676 0.372955322265625 +82677 0.2554931640625 +82678 0.10711669921875 +82679 -0.052886962890625 +82680 -0.186279296875 +82681 -0.23291015625 +82682 -0.209442138671875 +82683 -0.174163818359375 +82684 -0.126739501953125 +82685 -0.048126220703125 +82686 0.0426025390625 +82687 0.10748291015625 +82688 0.1409912109375 +82689 0.19708251953125 +82690 0.273651123046875 +82691 0.31768798828125 +82692 0.341094970703125 +82693 0.368011474609375 +82694 0.37249755859375 +82695 0.30072021484375 +82696 0.1517333984375 +82697 -0.01470947265625 +82698 -0.1883544921875 +82699 -0.372711181640625 +82700 -0.51397705078125 +82701 -0.57177734375 +82702 -0.53948974609375 +82703 -0.43511962890625 +82704 -0.2962646484375 +82705 -0.161102294921875 +82706 -0.0435791015625 +82707 0.060394287109375 +82708 0.13665771484375 +82709 0.170135498046875 +82710 0.16552734375 +82711 0.15728759765625 +82712 0.150787353515625 +82713 0.12200927734375 +82714 0.080108642578125 +82715 0.05126953125 +82716 0.062896728515625 +82717 0.09271240234375 +82718 0.092987060546875 +82719 0.07855224609375 +82720 0.06427001953125 +82721 0.0347900390625 +82722 -0.01171875 +82723 -0.056060791015625 +82724 -0.055511474609375 +82725 -0.010467529296875 +82726 0.02508544921875 +82727 0.025665283203125 +82728 0.017333984375 +82729 0.00189208984375 +82730 -0.03173828125 +82731 -0.071502685546875 +82732 -0.13543701171875 +82733 -0.219970703125 +82734 -0.300506591796875 +82735 -0.376312255859375 +82736 -0.416107177734375 +82737 -0.371124267578125 +82738 -0.242279052734375 +82739 -0.069732666015625 +82740 0.125640869140625 +82741 0.31268310546875 +82742 0.45501708984375 +82743 0.554779052734375 +82744 0.61065673828125 +82745 0.610931396484375 +82746 0.531463623046875 +82747 0.3883056640625 +82748 0.23468017578125 +82749 0.095245361328125 +82750 -0.00396728515625 +82751 -0.04852294921875 +82752 -0.055145263671875 +82753 -0.0758056640625 +82754 -0.138702392578125 +82755 -0.209197998046875 +82756 -0.289031982421875 +82757 -0.37884521484375 +82758 -0.456329345703125 +82759 -0.51641845703125 +82760 -0.519287109375 +82761 -0.458251953125 +82762 -0.384796142578125 +82763 -0.323699951171875 +82764 -0.269287109375 +82765 -0.1951904296875 +82766 -0.100006103515625 +82767 -0.01055908203125 +82768 0.1033935546875 +82769 0.24908447265625 +82770 0.373199462890625 +82771 0.45806884765625 +82772 0.511474609375 +82773 0.565399169921875 +82774 0.61138916015625 +82775 0.5897216796875 +82776 0.4906005859375 +82777 0.33148193359375 +82778 0.147796630859375 +82779 -0.01873779296875 +82780 -0.140289306640625 +82781 -0.191986083984375 +82782 -0.184295654296875 +82783 -0.161834716796875 +82784 -0.166595458984375 +82785 -0.19390869140625 +82786 -0.22442626953125 +82787 -0.279754638671875 +82788 -0.3389892578125 +82789 -0.3543701171875 +82790 -0.348175048828125 +82791 -0.32598876953125 +82792 -0.2581787109375 +82793 -0.139801025390625 +82794 0.014617919921875 +82795 0.144378662109375 +82796 0.221038818359375 +82797 0.27069091796875 +82798 0.294036865234375 +82799 0.311767578125 +82800 0.339141845703125 +82801 0.360260009765625 +82802 0.360504150390625 +82803 0.308380126953125 +82804 0.18170166015625 +82805 0.0047607421875 +82806 -0.17559814453125 +82807 -0.3143310546875 +82808 -0.36785888671875 +82809 -0.36248779296875 +82810 -0.343536376953125 +82811 -0.3018798828125 +82812 -0.231414794921875 +82813 -0.117645263671875 +82814 0.007049560546875 +82815 0.087982177734375 +82816 0.13946533203125 +82817 0.17425537109375 +82818 0.188201904296875 +82819 0.171234130859375 +82820 0.118438720703125 +82821 0.05706787109375 +82822 -0.010711669921875 +82823 -0.0914306640625 +82824 -0.162322998046875 +82825 -0.194549560546875 +82826 -0.1492919921875 +82827 -0.02166748046875 +82828 0.124053955078125 +82829 0.211151123046875 +82830 0.240447998046875 +82831 0.242218017578125 +82832 0.2257080078125 +82833 0.194366455078125 +82834 0.115509033203125 +82835 0.0128173828125 +82836 -0.053802490234375 +82837 -0.110626220703125 +82838 -0.199493408203125 +82839 -0.29437255859375 +82840 -0.33221435546875 +82841 -0.27972412109375 +82842 -0.185333251953125 +82843 -0.128204345703125 +82844 -0.115692138671875 +82845 -0.116455078125 +82846 -0.105926513671875 +82847 -0.053955078125 +82848 0.048797607421875 +82849 0.157318115234375 +82850 0.212005615234375 +82851 0.218475341796875 +82852 0.23724365234375 +82853 0.30535888671875 +82854 0.38128662109375 +82855 0.404449462890625 +82856 0.3944091796875 +82857 0.3885498046875 +82858 0.362640380859375 +82859 0.27362060546875 +82860 0.11712646484375 +82861 -0.054901123046875 +82862 -0.19085693359375 +82863 -0.28570556640625 +82864 -0.339263916015625 +82865 -0.3775634765625 +82866 -0.445709228515625 +82867 -0.535064697265625 +82868 -0.629058837890625 +82869 -0.697601318359375 +82870 -0.70391845703125 +82871 -0.6424560546875 +82872 -0.491241455078125 +82873 -0.265716552734375 +82874 -0.023712158203125 +82875 0.201751708984375 +82876 0.375823974609375 +82877 0.485076904296875 +82878 0.56884765625 +82879 0.634765625 +82880 0.63763427734375 +82881 0.5660400390625 +82882 0.4720458984375 +82883 0.40692138671875 +82884 0.3778076171875 +82885 0.376953125 +82886 0.371978759765625 +82887 0.313140869140625 +82888 0.184417724609375 +82889 0.011199951171875 +82890 -0.171051025390625 +82891 -0.33740234375 +82892 -0.47198486328125 +82893 -0.560394287109375 +82894 -0.58056640625 +82895 -0.54754638671875 +82896 -0.508575439453125 +82897 -0.459503173828125 +82898 -0.394378662109375 +82899 -0.35260009765625 +82900 -0.31170654296875 +82901 -0.197418212890625 +82902 -0.007965087890625 +82903 0.207489013671875 +82904 0.409210205078125 +82905 0.57208251953125 +82906 0.66595458984375 +82907 0.65875244140625 +82908 0.56744384765625 +82909 0.431396484375 +82910 0.29443359375 +82911 0.182464599609375 +82912 0.06365966796875 +82913 -0.075958251953125 +82914 -0.189422607421875 +82915 -0.271942138671875 +82916 -0.342529296875 +82917 -0.364166259765625 +82918 -0.327239990234375 +82919 -0.2769775390625 +82920 -0.253692626953125 +82921 -0.24365234375 +82922 -0.1983642578125 +82923 -0.116241455078125 +82924 -0.036834716796875 +82925 0.034881591796875 +82926 0.09124755859375 +82927 0.10888671875 +82928 0.125518798828125 +82929 0.15771484375 +82930 0.17828369140625 +82931 0.17108154296875 +82932 0.129974365234375 +82933 0.082427978515625 +82934 0.027679443359375 +82935 -0.065643310546875 +82936 -0.15936279296875 +82937 -0.21307373046875 +82938 -0.234649658203125 +82939 -0.2001953125 +82940 -0.119171142578125 +82941 -0.024749755859375 +82942 0.085784912109375 +82943 0.178131103515625 +82944 0.215576171875 +82945 0.211456298828125 +82946 0.17523193359375 +82947 0.128753662109375 +82948 0.1019287109375 +82949 0.0743408203125 +82950 0.04327392578125 +82951 0.038177490234375 +82952 0.076263427734375 +82953 0.14105224609375 +82954 0.186431884765625 +82955 0.188812255859375 +82956 0.1390380859375 +82957 0.041778564453125 +82958 -0.079437255859375 +82959 -0.219390869140625 +82960 -0.367828369140625 +82961 -0.494873046875 +82962 -0.556243896484375 +82963 -0.508697509765625 +82964 -0.3756103515625 +82965 -0.218902587890625 +82966 -0.063751220703125 +82967 0.091552734375 +82968 0.23602294921875 +82969 0.342987060546875 +82970 0.39520263671875 +82971 0.389373779296875 +82972 0.324249267578125 +82973 0.224090576171875 +82974 0.124267578125 +82975 0.037078857421875 +82976 -0.010101318359375 +82977 -0.019439697265625 +82978 -0.022796630859375 +82979 -0.001556396484375 +82980 0.056304931640625 +82981 0.106719970703125 +82982 0.096893310546875 +82983 0.042694091796875 +82984 -0.018035888671875 +82985 -0.07586669921875 +82986 -0.11944580078125 +82987 -0.15972900390625 +82988 -0.202606201171875 +82989 -0.24859619140625 +82990 -0.30517578125 +82991 -0.36212158203125 +82992 -0.39141845703125 +82993 -0.35528564453125 +82994 -0.249969482421875 +82995 -0.092864990234375 +82996 0.08905029296875 +82997 0.2352294921875 +82998 0.318817138671875 +82999 0.358642578125 +83000 0.347747802734375 +83001 0.28564453125 +83002 0.223175048828125 +83003 0.196746826171875 +83004 0.179840087890625 +83005 0.155548095703125 +83006 0.151214599609375 +83007 0.156951904296875 +83008 0.13177490234375 +83009 0.100799560546875 +83010 0.087127685546875 +83011 0.05487060546875 +83012 -0.009002685546875 +83013 -0.10400390625 +83014 -0.229400634765625 +83015 -0.35552978515625 +83016 -0.441925048828125 +83017 -0.473846435546875 +83018 -0.464813232421875 +83019 -0.419097900390625 +83020 -0.334320068359375 +83021 -0.227935791015625 +83022 -0.12347412109375 +83023 -0.02764892578125 +83024 0.077667236328125 +83025 0.2132568359375 +83026 0.38885498046875 +83027 0.582794189453125 +83028 0.734039306640625 +83029 0.800140380859375 +83030 0.7783203125 +83031 0.6651611328125 +83032 0.45965576171875 +83033 0.199188232421875 +83034 -0.050689697265625 +83035 -0.23297119140625 +83036 -0.33013916015625 +83037 -0.368408203125 +83038 -0.378936767578125 +83039 -0.376983642578125 +83040 -0.37969970703125 +83041 -0.391510009765625 +83042 -0.385345458984375 +83043 -0.3419189453125 +83044 -0.28289794921875 +83045 -0.251617431640625 +83046 -0.266143798828125 +83047 -0.273345947265625 +83048 -0.216796875 +83049 -0.128265380859375 +83050 -0.068145751953125 +83051 -0.0430908203125 +83052 -0.024444580078125 +83053 0.020721435546875 +83054 0.124481201171875 +83055 0.25787353515625 +83056 0.379119873046875 +83057 0.47991943359375 +83058 0.5281982421875 +83059 0.511138916015625 +83060 0.456207275390625 +83061 0.407470703125 +83062 0.383758544921875 +83063 0.35687255859375 +83064 0.31182861328125 +83065 0.250885009765625 +83066 0.1654052734375 +83067 0.035247802734375 +83068 -0.142059326171875 +83069 -0.33563232421875 +83070 -0.5345458984375 +83071 -0.72186279296875 +83072 -0.836669921875 +83073 -0.8326416015625 +83074 -0.7296142578125 +83075 -0.582550048828125 +83076 -0.440093994140625 +83077 -0.324310302734375 +83078 -0.20147705078125 +83079 -0.044647216796875 +83080 0.103973388671875 +83081 0.202392578125 +83082 0.264495849609375 +83083 0.338897705078125 +83084 0.443817138671875 +83085 0.545074462890625 +83086 0.6173095703125 +83087 0.6524658203125 +83088 0.66339111328125 +83089 0.6561279296875 +83090 0.606781005859375 +83091 0.501190185546875 +83092 0.352783203125 +83093 0.176544189453125 +83094 -0.034820556640625 +83095 -0.258209228515625 +83096 -0.44244384765625 +83097 -0.5753173828125 +83098 -0.65203857421875 +83099 -0.641632080078125 +83100 -0.562164306640625 +83101 -0.458038330078125 +83102 -0.350555419921875 +83103 -0.260528564453125 +83104 -0.192108154296875 +83105 -0.141937255859375 +83106 -0.1021728515625 +83107 -0.062896728515625 +83108 -0.011932373046875 +83109 0.062835693359375 +83110 0.148712158203125 +83111 0.241729736328125 +83112 0.34912109375 +83113 0.457305908203125 +83114 0.54388427734375 +83115 0.5728759765625 +83116 0.506591796875 +83117 0.351226806640625 +83118 0.146514892578125 +83119 -0.05523681640625 +83120 -0.21624755859375 +83121 -0.334930419921875 +83122 -0.402984619140625 +83123 -0.4412841796875 +83124 -0.49578857421875 +83125 -0.5601806640625 +83126 -0.600738525390625 +83127 -0.584228515625 +83128 -0.47930908203125 +83129 -0.27935791015625 +83130 -0.0089111328125 +83131 0.268798828125 +83132 0.482818603515625 +83133 0.60369873046875 +83134 0.650421142578125 +83135 0.66400146484375 +83136 0.6414794921875 +83137 0.572540283203125 +83138 0.498138427734375 +83139 0.439453125 +83140 0.375518798828125 +83141 0.274505615234375 +83142 0.1087646484375 +83143 -0.099395751953125 +83144 -0.3182373046875 +83145 -0.5489501953125 +83146 -0.7738037109375 +83147 -0.86383056640625 +83148 -0.870391845703125 +83149 -0.86895751953125 +83150 -0.861053466796875 +83151 -0.765869140625 +83152 -0.5301513671875 +83153 -0.214691162109375 +83154 0.137359619140625 +83155 0.474822998046875 +83156 0.76239013671875 +83157 0.867462158203125 +83158 0.870361328125 +83159 0.86480712890625 +83160 0.831817626953125 +83161 0.677581787109375 +83162 0.495880126953125 +83163 0.30767822265625 +83164 0.116180419921875 +83165 -0.110748291015625 +83166 -0.381805419921875 +83167 -0.6572265625 +83168 -0.857421875 +83169 -0.870391845703125 +83170 -0.870391845703125 +83171 -0.86444091796875 +83172 -0.85723876953125 +83173 -0.790008544921875 +83174 -0.62847900390625 +83175 -0.3956298828125 +83176 -0.126708984375 +83177 0.150115966796875 +83178 0.424041748046875 +83179 0.670623779296875 +83180 0.854522705078125 +83181 0.866485595703125 +83182 0.86920166015625 +83183 0.8653564453125 +83184 0.857147216796875 +83185 0.766845703125 +83186 0.628509521484375 +83187 0.462127685546875 +83188 0.297210693359375 +83189 0.14862060546875 +83190 -0.00537109375 +83191 -0.15753173828125 +83192 -0.31304931640625 +83193 -0.48876953125 +83194 -0.6416015625 +83195 -0.751373291015625 +83196 -0.84619140625 +83197 -0.861297607421875 +83198 -0.863250732421875 +83199 -0.856597900390625 +83200 -0.7498779296875 +83201 -0.624542236328125 +83202 -0.47808837890625 +83203 -0.253387451171875 +83204 0.003692626953125 +83205 0.2257080078125 +83206 0.427154541015625 +83207 0.643218994140625 +83208 0.855926513671875 +83209 0.870361328125 +83210 0.870361328125 +83211 0.862762451171875 +83212 0.79669189453125 +83213 0.595794677734375 +83214 0.362152099609375 +83215 0.1270751953125 +83216 -0.086944580078125 +83217 -0.2784423828125 +83218 -0.484832763671875 +83219 -0.729583740234375 +83220 -0.86688232421875 +83221 -0.870391845703125 +83222 -0.86859130859375 +83223 -0.86279296875 +83224 -0.817962646484375 +83225 -0.6116943359375 +83226 -0.3128662109375 +83227 0.039398193359375 +83228 0.422821044921875 +83229 0.805145263671875 +83230 0.870361328125 +83231 0.870361328125 +83232 0.860015869140625 +83233 0.727935791015625 +83234 0.48114013671875 +83235 0.2059326171875 +83236 -0.06103515625 +83237 -0.29913330078125 +83238 -0.516204833984375 +83239 -0.7252197265625 +83240 -0.85980224609375 +83241 -0.870391845703125 +83242 -0.870391845703125 +83243 -0.858062744140625 +83244 -0.673004150390625 +83245 -0.42694091796875 +83246 -0.2100830078125 +83247 -0.0362548828125 +83248 0.10943603515625 +83249 0.23516845703125 +83250 0.373687744140625 +83251 0.517791748046875 +83252 0.602783203125 +83253 0.635711669921875 +83254 0.655181884765625 +83255 0.65948486328125 +83256 0.651275634765625 +83257 0.61846923828125 +83258 0.53753662109375 +83259 0.404144287109375 +83260 0.22186279296875 +83261 0.003997802734375 +83262 -0.22100830078125 +83263 -0.42449951171875 +83264 -0.579833984375 +83265 -0.641876220703125 +83266 -0.6177978515625 +83267 -0.575531005859375 +83268 -0.526336669921875 +83269 -0.42645263671875 +83270 -0.2581787109375 +83271 -0.068695068359375 +83272 0.09222412109375 +83273 0.232147216796875 +83274 0.3509521484375 +83275 0.410064697265625 +83276 0.372955322265625 +83277 0.2554931640625 +83278 0.10711669921875 +83279 -0.052886962890625 +83280 -0.186279296875 +83281 -0.23291015625 +83282 -0.209442138671875 +83283 -0.174163818359375 +83284 -0.126739501953125 +83285 -0.048126220703125 +83286 0.0426025390625 +83287 0.10748291015625 +83288 0.1409912109375 +83289 0.19708251953125 +83290 0.273651123046875 +83291 0.31768798828125 +83292 0.341094970703125 +83293 0.368011474609375 +83294 0.37249755859375 +83295 0.30072021484375 +83296 0.1517333984375 +83297 -0.01470947265625 +83298 -0.1883544921875 +83299 -0.372711181640625 +83300 -0.51397705078125 +83301 -0.57177734375 +83302 -0.53948974609375 +83303 -0.43511962890625 +83304 -0.2962646484375 +83305 -0.161102294921875 +83306 -0.0435791015625 +83307 0.060394287109375 +83308 0.13665771484375 +83309 0.170135498046875 +83310 0.16552734375 +83311 0.15728759765625 +83312 0.150787353515625 +83313 0.12200927734375 +83314 0.080108642578125 +83315 0.05126953125 +83316 0.062896728515625 +83317 0.09271240234375 +83318 0.092987060546875 +83319 0.07855224609375 +83320 0.06427001953125 +83321 0.0347900390625 +83322 -0.01171875 +83323 -0.056060791015625 +83324 -0.055511474609375 +83325 -0.010467529296875 +83326 0.02508544921875 +83327 0.025665283203125 +83328 0.017333984375 +83329 0.00189208984375 +83330 -0.03173828125 +83331 -0.071502685546875 +83332 -0.13543701171875 +83333 -0.219970703125 +83334 -0.300506591796875 +83335 -0.376312255859375 +83336 -0.416107177734375 +83337 -0.371124267578125 +83338 -0.242279052734375 +83339 -0.069732666015625 +83340 0.125640869140625 +83341 0.31268310546875 +83342 0.45501708984375 +83343 0.554779052734375 +83344 0.61065673828125 +83345 0.610931396484375 +83346 0.531463623046875 +83347 0.3883056640625 +83348 0.23468017578125 +83349 0.095245361328125 +83350 -0.00396728515625 +83351 -0.04852294921875 +83352 -0.055145263671875 +83353 -0.0758056640625 +83354 -0.138702392578125 +83355 -0.209197998046875 +83356 -0.289031982421875 +83357 -0.37884521484375 +83358 -0.456329345703125 +83359 -0.51641845703125 +83360 -0.519287109375 +83361 -0.458251953125 +83362 -0.384796142578125 +83363 -0.323699951171875 +83364 -0.269287109375 +83365 -0.1951904296875 +83366 -0.100006103515625 +83367 -0.01055908203125 +83368 0.1033935546875 +83369 0.24908447265625 +83370 0.373199462890625 +83371 0.45806884765625 +83372 0.511474609375 +83373 0.565399169921875 +83374 0.61138916015625 +83375 0.5897216796875 +83376 0.4906005859375 +83377 0.33148193359375 +83378 0.147796630859375 +83379 -0.01873779296875 +83380 -0.140289306640625 +83381 -0.191986083984375 +83382 -0.184295654296875 +83383 -0.161834716796875 +83384 -0.166595458984375 +83385 -0.19390869140625 +83386 -0.22442626953125 +83387 -0.279754638671875 +83388 -0.3389892578125 +83389 -0.3543701171875 +83390 -0.348175048828125 +83391 -0.32598876953125 +83392 -0.2581787109375 +83393 -0.139801025390625 +83394 0.014617919921875 +83395 0.144378662109375 +83396 0.221038818359375 +83397 0.27069091796875 +83398 0.294036865234375 +83399 0.311767578125 +83400 0.339141845703125 +83401 0.360260009765625 +83402 0.360504150390625 +83403 0.308380126953125 +83404 0.18170166015625 +83405 0.0047607421875 +83406 -0.17559814453125 +83407 -0.3143310546875 +83408 -0.36785888671875 +83409 -0.36248779296875 +83410 -0.343536376953125 +83411 -0.3018798828125 +83412 -0.231414794921875 +83413 -0.117645263671875 +83414 0.007049560546875 +83415 0.087982177734375 +83416 0.13946533203125 +83417 0.17425537109375 +83418 0.188201904296875 +83419 0.171234130859375 +83420 0.118438720703125 +83421 0.05706787109375 +83422 -0.010711669921875 +83423 -0.0914306640625 +83424 -0.162322998046875 +83425 -0.194549560546875 +83426 -0.1492919921875 +83427 -0.02166748046875 +83428 0.124053955078125 +83429 0.211151123046875 +83430 0.240447998046875 +83431 0.242218017578125 +83432 0.2257080078125 +83433 0.194366455078125 +83434 0.115509033203125 +83435 0.0128173828125 +83436 -0.053802490234375 +83437 -0.110626220703125 +83438 -0.199493408203125 +83439 -0.29437255859375 +83440 -0.33221435546875 +83441 -0.27972412109375 +83442 -0.185333251953125 +83443 -0.128204345703125 +83444 -0.115692138671875 +83445 -0.116455078125 +83446 -0.105926513671875 +83447 -0.053955078125 +83448 0.048797607421875 +83449 0.157318115234375 +83450 0.212005615234375 +83451 0.218475341796875 +83452 0.23724365234375 +83453 0.30535888671875 +83454 0.38128662109375 +83455 0.404449462890625 +83456 0.3944091796875 +83457 0.3885498046875 +83458 0.362640380859375 +83459 0.27362060546875 +83460 0.11712646484375 +83461 -0.054901123046875 +83462 -0.19085693359375 +83463 -0.28570556640625 +83464 -0.339263916015625 +83465 -0.3775634765625 +83466 -0.445709228515625 +83467 -0.535064697265625 +83468 -0.629058837890625 +83469 -0.697601318359375 +83470 -0.70391845703125 +83471 -0.6424560546875 +83472 -0.491241455078125 +83473 -0.265716552734375 +83474 -0.023712158203125 +83475 0.201751708984375 +83476 0.375823974609375 +83477 0.485076904296875 +83478 0.56884765625 +83479 0.634765625 +83480 0.63763427734375 +83481 0.5660400390625 +83482 0.4720458984375 +83483 0.40692138671875 +83484 0.3778076171875 +83485 0.376953125 +83486 0.371978759765625 +83487 0.313140869140625 +83488 0.184417724609375 +83489 0.011199951171875 +83490 -0.171051025390625 +83491 -0.33740234375 +83492 -0.47198486328125 +83493 -0.560394287109375 +83494 -0.58056640625 +83495 -0.54754638671875 +83496 -0.508575439453125 +83497 -0.459503173828125 +83498 -0.394378662109375 +83499 -0.35260009765625 +83500 -0.31170654296875 +83501 -0.197418212890625 +83502 -0.007965087890625 +83503 0.207489013671875 +83504 0.409210205078125 +83505 0.57208251953125 +83506 0.66595458984375 +83507 0.65875244140625 +83508 0.56744384765625 +83509 0.431396484375 +83510 0.29443359375 +83511 0.182464599609375 +83512 0.06365966796875 +83513 -0.075958251953125 +83514 -0.189422607421875 +83515 -0.271942138671875 +83516 -0.342529296875 +83517 -0.364166259765625 +83518 -0.327239990234375 +83519 -0.2769775390625 +83520 -0.253692626953125 +83521 -0.24365234375 +83522 -0.1983642578125 +83523 -0.116241455078125 +83524 -0.036834716796875 +83525 0.034881591796875 +83526 0.09124755859375 +83527 0.10888671875 +83528 0.125518798828125 +83529 0.15771484375 +83530 0.17828369140625 +83531 0.17108154296875 +83532 0.129974365234375 +83533 0.082427978515625 +83534 0.027679443359375 +83535 -0.065643310546875 +83536 -0.15936279296875 +83537 -0.21307373046875 +83538 -0.234649658203125 +83539 -0.2001953125 +83540 -0.119171142578125 +83541 -0.024749755859375 +83542 0.085784912109375 +83543 0.178131103515625 +83544 0.215576171875 +83545 0.211456298828125 +83546 0.17523193359375 +83547 0.128753662109375 +83548 0.1019287109375 +83549 0.0743408203125 +83550 0.04327392578125 +83551 0.038177490234375 +83552 0.076263427734375 +83553 0.14105224609375 +83554 0.186431884765625 +83555 0.188812255859375 +83556 0.1390380859375 +83557 0.041778564453125 +83558 -0.079437255859375 +83559 -0.219390869140625 +83560 -0.367828369140625 +83561 -0.494873046875 +83562 -0.556243896484375 +83563 -0.508697509765625 +83564 -0.3756103515625 +83565 -0.218902587890625 +83566 -0.063751220703125 +83567 0.091552734375 +83568 0.23602294921875 +83569 0.342987060546875 +83570 0.39520263671875 +83571 0.389373779296875 +83572 0.324249267578125 +83573 0.224090576171875 +83574 0.124267578125 +83575 0.037078857421875 +83576 -0.010101318359375 +83577 -0.019439697265625 +83578 -0.022796630859375 +83579 -0.001556396484375 +83580 0.056304931640625 +83581 0.106719970703125 +83582 0.096893310546875 +83583 0.042694091796875 +83584 -0.018035888671875 +83585 -0.07586669921875 +83586 -0.11944580078125 +83587 -0.15972900390625 +83588 -0.202606201171875 +83589 -0.24859619140625 +83590 -0.30517578125 +83591 -0.36212158203125 +83592 -0.39141845703125 +83593 -0.35528564453125 +83594 -0.249969482421875 +83595 -0.092864990234375 +83596 0.08905029296875 +83597 0.2352294921875 +83598 0.318817138671875 +83599 0.358642578125 +83600 0.347747802734375 +83601 0.28564453125 +83602 0.223175048828125 +83603 0.196746826171875 +83604 0.179840087890625 +83605 0.155548095703125 +83606 0.151214599609375 +83607 0.156951904296875 +83608 0.13177490234375 +83609 0.100799560546875 +83610 0.087127685546875 +83611 0.05487060546875 +83612 -0.009002685546875 +83613 -0.10400390625 +83614 -0.229400634765625 +83615 -0.35552978515625 +83616 -0.441925048828125 +83617 -0.473846435546875 +83618 -0.464813232421875 +83619 -0.419097900390625 +83620 -0.334320068359375 +83621 -0.227935791015625 +83622 -0.12347412109375 +83623 -0.02764892578125 +83624 0.077667236328125 +83625 0.2132568359375 +83626 0.38885498046875 +83627 0.582794189453125 +83628 0.734039306640625 +83629 0.800140380859375 +83630 0.7783203125 +83631 0.6651611328125 +83632 0.45965576171875 +83633 0.199188232421875 +83634 -0.050689697265625 +83635 -0.23297119140625 +83636 -0.33013916015625 +83637 -0.368408203125 +83638 -0.378936767578125 +83639 -0.376983642578125 +83640 -0.37969970703125 +83641 -0.391510009765625 +83642 -0.385345458984375 +83643 -0.3419189453125 +83644 -0.28289794921875 +83645 -0.251617431640625 +83646 -0.266143798828125 +83647 -0.273345947265625 +83648 -0.216796875 +83649 -0.128265380859375 +83650 -0.068145751953125 +83651 -0.0430908203125 +83652 -0.024444580078125 +83653 0.020721435546875 +83654 0.124481201171875 +83655 0.25787353515625 +83656 0.379119873046875 +83657 0.47991943359375 +83658 0.5281982421875 +83659 0.511138916015625 +83660 0.456207275390625 +83661 0.407470703125 +83662 0.383758544921875 +83663 0.35687255859375 +83664 0.31182861328125 +83665 0.250885009765625 +83666 0.1654052734375 +83667 0.035247802734375 +83668 -0.142059326171875 +83669 -0.33563232421875 +83670 -0.5345458984375 +83671 -0.72186279296875 +83672 -0.836669921875 +83673 -0.8326416015625 +83674 -0.7296142578125 +83675 -0.582550048828125 +83676 -0.440093994140625 +83677 -0.324310302734375 +83678 -0.20147705078125 +83679 -0.044647216796875 +83680 0.103973388671875 +83681 0.202392578125 +83682 0.264495849609375 +83683 0.338897705078125 +83684 0.443817138671875 +83685 0.545074462890625 +83686 0.6173095703125 +83687 0.6524658203125 +83688 0.66339111328125 +83689 0.6561279296875 +83690 0.606781005859375 +83691 0.501190185546875 +83692 0.352783203125 +83693 0.176544189453125 +83694 -0.034820556640625 +83695 -0.258209228515625 +83696 -0.44244384765625 +83697 -0.5753173828125 +83698 -0.65203857421875 +83699 -0.641632080078125 +83700 -0.562164306640625 +83701 -0.458038330078125 +83702 -0.350555419921875 +83703 -0.260528564453125 +83704 -0.192108154296875 +83705 -0.141937255859375 +83706 -0.1021728515625 +83707 -0.062896728515625 +83708 -0.011932373046875 +83709 0.062835693359375 +83710 0.148712158203125 +83711 0.241729736328125 +83712 0.34912109375 +83713 0.457305908203125 +83714 0.54388427734375 +83715 0.5728759765625 +83716 0.506591796875 +83717 0.351226806640625 +83718 0.146514892578125 +83719 -0.05523681640625 +83720 -0.21624755859375 +83721 -0.334930419921875 +83722 -0.402984619140625 +83723 -0.4412841796875 +83724 -0.49578857421875 +83725 -0.5601806640625 +83726 -0.600738525390625 +83727 -0.584228515625 +83728 -0.47930908203125 +83729 -0.27935791015625 +83730 -0.0089111328125 +83731 0.268798828125 +83732 0.482818603515625 +83733 0.60369873046875 +83734 0.650421142578125 +83735 0.66400146484375 +83736 0.6414794921875 +83737 0.572540283203125 +83738 0.498138427734375 +83739 0.439453125 +83740 0.375518798828125 +83741 0.274505615234375 +83742 0.1087646484375 +83743 -0.099395751953125 +83744 -0.3182373046875 +83745 -0.5489501953125 +83746 -0.7738037109375 +83747 -0.86383056640625 +83748 -0.870391845703125 +83749 -0.86895751953125 +83750 -0.861053466796875 +83751 -0.765869140625 +83752 -0.5301513671875 +83753 -0.214691162109375 +83754 0.137359619140625 +83755 0.474822998046875 +83756 0.76239013671875 +83757 0.867462158203125 +83758 0.870361328125 +83759 0.86480712890625 +83760 0.831817626953125 +83761 0.677581787109375 +83762 0.495880126953125 +83763 0.30767822265625 +83764 0.116180419921875 +83765 -0.110748291015625 +83766 -0.381805419921875 +83767 -0.6572265625 +83768 -0.857421875 +83769 -0.870391845703125 +83770 -0.870391845703125 +83771 -0.86444091796875 +83772 -0.85723876953125 +83773 -0.790008544921875 +83774 -0.62847900390625 +83775 -0.3956298828125 +83776 -0.126708984375 +83777 0.150115966796875 +83778 0.424041748046875 +83779 0.670623779296875 +83780 0.854522705078125 +83781 0.866485595703125 +83782 0.86920166015625 +83783 0.8653564453125 +83784 0.857147216796875 +83785 0.766845703125 +83786 0.628509521484375 +83787 0.462127685546875 +83788 0.297210693359375 +83789 0.14862060546875 +83790 -0.00537109375 +83791 -0.15753173828125 +83792 -0.31304931640625 +83793 -0.48876953125 +83794 -0.6416015625 +83795 -0.751373291015625 +83796 -0.84619140625 +83797 -0.861297607421875 +83798 -0.863250732421875 +83799 -0.856597900390625 +83800 -0.7498779296875 +83801 -0.624542236328125 +83802 -0.47808837890625 +83803 -0.253387451171875 +83804 0.003692626953125 +83805 0.2257080078125 +83806 0.427154541015625 +83807 0.643218994140625 +83808 0.855926513671875 +83809 0.870361328125 +83810 0.870361328125 +83811 0.862762451171875 +83812 0.79669189453125 +83813 0.595794677734375 +83814 0.362152099609375 +83815 0.1270751953125 +83816 -0.086944580078125 +83817 -0.2784423828125 +83818 -0.484832763671875 +83819 -0.729583740234375 +83820 -0.86688232421875 +83821 -0.870391845703125 +83822 -0.86859130859375 +83823 -0.86279296875 +83824 -0.817962646484375 +83825 -0.6116943359375 +83826 -0.3128662109375 +83827 0.039398193359375 +83828 0.422821044921875 +83829 0.805145263671875 +83830 0.870361328125 +83831 0.870361328125 +83832 0.860015869140625 +83833 0.727935791015625 +83834 0.48114013671875 +83835 0.2059326171875 +83836 -0.06103515625 +83837 -0.29913330078125 +83838 -0.516204833984375 +83839 -0.7252197265625 +83840 -0.85980224609375 +83841 -0.870391845703125 +83842 -0.870391845703125 +83843 -0.858062744140625 +83844 -0.673004150390625 +83845 -0.42694091796875 +83846 -0.2100830078125 +83847 -0.0362548828125 +83848 0.10943603515625 +83849 0.23516845703125 +83850 0.373687744140625 +83851 0.517791748046875 +83852 0.602783203125 +83853 0.635711669921875 +83854 0.655181884765625 +83855 0.65948486328125 +83856 0.651275634765625 +83857 0.61846923828125 +83858 0.53753662109375 +83859 0.404144287109375 +83860 0.22186279296875 +83861 0.003997802734375 +83862 -0.22100830078125 +83863 -0.42449951171875 +83864 -0.579833984375 +83865 -0.641876220703125 +83866 -0.6177978515625 +83867 -0.575531005859375 +83868 -0.526336669921875 +83869 -0.42645263671875 +83870 -0.2581787109375 +83871 -0.068695068359375 +83872 0.09222412109375 +83873 0.232147216796875 +83874 0.3509521484375 +83875 0.410064697265625 +83876 0.372955322265625 +83877 0.2554931640625 +83878 0.10711669921875 +83879 -0.052886962890625 +83880 -0.186279296875 +83881 -0.23291015625 +83882 -0.209442138671875 +83883 -0.174163818359375 +83884 -0.126739501953125 +83885 -0.048126220703125 +83886 0.0426025390625 +83887 0.10748291015625 +83888 0.1409912109375 +83889 0.19708251953125 +83890 0.273651123046875 +83891 0.31768798828125 +83892 0.341094970703125 +83893 0.368011474609375 +83894 0.37249755859375 +83895 0.30072021484375 +83896 0.1517333984375 +83897 -0.01470947265625 +83898 -0.1883544921875 +83899 -0.372711181640625 +83900 -0.51397705078125 +83901 -0.57177734375 +83902 -0.53948974609375 +83903 -0.43511962890625 +83904 -0.2962646484375 +83905 -0.161102294921875 +83906 -0.0435791015625 +83907 0.060394287109375 +83908 0.13665771484375 +83909 0.170135498046875 +83910 0.16552734375 +83911 0.15728759765625 +83912 0.150787353515625 +83913 0.12200927734375 +83914 0.080108642578125 +83915 0.05126953125 +83916 0.062896728515625 +83917 0.09271240234375 +83918 0.092987060546875 +83919 0.07855224609375 +83920 0.06427001953125 +83921 0.0347900390625 +83922 -0.01171875 +83923 -0.056060791015625 +83924 -0.055511474609375 +83925 -0.010467529296875 +83926 0.02508544921875 +83927 0.025665283203125 +83928 0.017333984375 +83929 0.00189208984375 +83930 -0.03173828125 +83931 -0.071502685546875 +83932 -0.13543701171875 +83933 -0.219970703125 +83934 -0.300506591796875 +83935 -0.376312255859375 +83936 -0.416107177734375 +83937 -0.371124267578125 +83938 -0.242279052734375 +83939 -0.069732666015625 +83940 0.125640869140625 +83941 0.31268310546875 +83942 0.45501708984375 +83943 0.554779052734375 +83944 0.61065673828125 +83945 0.610931396484375 +83946 0.531463623046875 +83947 0.3883056640625 +83948 0.23468017578125 +83949 0.095245361328125 +83950 -0.00396728515625 +83951 -0.04852294921875 +83952 -0.055145263671875 +83953 -0.0758056640625 +83954 -0.138702392578125 +83955 -0.209197998046875 +83956 -0.289031982421875 +83957 -0.37884521484375 +83958 -0.456329345703125 +83959 -0.51641845703125 +83960 -0.519287109375 +83961 -0.458251953125 +83962 -0.384796142578125 +83963 -0.323699951171875 +83964 -0.269287109375 +83965 -0.1951904296875 +83966 -0.100006103515625 +83967 -0.01055908203125 +83968 0.1033935546875 +83969 0.24908447265625 +83970 0.373199462890625 +83971 0.45806884765625 +83972 0.511474609375 +83973 0.565399169921875 +83974 0.61138916015625 +83975 0.5897216796875 +83976 0.4906005859375 +83977 0.33148193359375 +83978 0.147796630859375 +83979 -0.01873779296875 +83980 -0.140289306640625 +83981 -0.191986083984375 +83982 -0.184295654296875 +83983 -0.161834716796875 +83984 -0.166595458984375 +83985 -0.19390869140625 +83986 -0.22442626953125 +83987 -0.279754638671875 +83988 -0.3389892578125 +83989 -0.3543701171875 +83990 -0.348175048828125 +83991 -0.32598876953125 +83992 -0.2581787109375 +83993 -0.139801025390625 +83994 0.014617919921875 +83995 0.144378662109375 +83996 0.221038818359375 +83997 0.27069091796875 +83998 0.294036865234375 +83999 0.311767578125 +84000 0.339141845703125 +84001 0.360260009765625 +84002 0.360504150390625 +84003 0.308380126953125 +84004 0.18170166015625 +84005 0.0047607421875 +84006 -0.17559814453125 +84007 -0.3143310546875 +84008 -0.36785888671875 +84009 -0.36248779296875 +84010 -0.343536376953125 +84011 -0.3018798828125 +84012 -0.231414794921875 +84013 -0.117645263671875 +84014 0.007049560546875 +84015 0.087982177734375 +84016 0.13946533203125 +84017 0.17425537109375 +84018 0.188201904296875 +84019 0.171234130859375 +84020 0.118438720703125 +84021 0.05706787109375 +84022 -0.010711669921875 +84023 -0.0914306640625 +84024 -0.162322998046875 +84025 -0.194549560546875 +84026 -0.1492919921875 +84027 -0.02166748046875 +84028 0.124053955078125 +84029 0.211151123046875 +84030 0.240447998046875 +84031 0.242218017578125 +84032 0.2257080078125 +84033 0.194366455078125 +84034 0.115509033203125 +84035 0.0128173828125 +84036 -0.053802490234375 +84037 -0.110626220703125 +84038 -0.199493408203125 +84039 -0.29437255859375 +84040 -0.33221435546875 +84041 -0.27972412109375 +84042 -0.185333251953125 +84043 -0.128204345703125 +84044 -0.115692138671875 +84045 -0.116455078125 +84046 -0.105926513671875 +84047 -0.053955078125 +84048 0.048797607421875 +84049 0.157318115234375 +84050 0.212005615234375 +84051 0.218475341796875 +84052 0.23724365234375 +84053 0.30535888671875 +84054 0.38128662109375 +84055 0.404449462890625 +84056 0.3944091796875 +84057 0.3885498046875 +84058 0.362640380859375 +84059 0.27362060546875 +84060 0.11712646484375 +84061 -0.054901123046875 +84062 -0.19085693359375 +84063 -0.28570556640625 +84064 -0.339263916015625 +84065 -0.3775634765625 +84066 -0.445709228515625 +84067 -0.535064697265625 +84068 -0.629058837890625 +84069 -0.697601318359375 +84070 -0.70391845703125 +84071 -0.6424560546875 +84072 -0.491241455078125 +84073 -0.265716552734375 +84074 -0.023712158203125 +84075 0.201751708984375 +84076 0.375823974609375 +84077 0.485076904296875 +84078 0.56884765625 +84079 0.634765625 +84080 0.63763427734375 +84081 0.5660400390625 +84082 0.4720458984375 +84083 0.40692138671875 +84084 0.3778076171875 +84085 0.376953125 +84086 0.371978759765625 +84087 0.313140869140625 +84088 0.184417724609375 +84089 0.011199951171875 +84090 -0.171051025390625 +84091 -0.33740234375 +84092 -0.47198486328125 +84093 -0.560394287109375 +84094 -0.58056640625 +84095 -0.54754638671875 +84096 -0.508575439453125 +84097 -0.459503173828125 +84098 -0.394378662109375 +84099 -0.35260009765625 +84100 -0.31170654296875 +84101 -0.197418212890625 +84102 -0.007965087890625 +84103 0.207489013671875 +84104 0.409210205078125 +84105 0.57208251953125 +84106 0.66595458984375 +84107 0.65875244140625 +84108 0.56744384765625 +84109 0.431396484375 +84110 0.29443359375 +84111 0.182464599609375 +84112 0.06365966796875 +84113 -0.075958251953125 +84114 -0.189422607421875 +84115 -0.271942138671875 +84116 -0.342529296875 +84117 -0.364166259765625 +84118 -0.327239990234375 +84119 -0.2769775390625 +84120 -0.253692626953125 +84121 -0.24365234375 +84122 -0.1983642578125 +84123 -0.116241455078125 +84124 -0.036834716796875 +84125 0.034881591796875 +84126 0.09124755859375 +84127 0.10888671875 +84128 0.125518798828125 +84129 0.15771484375 +84130 0.17828369140625 +84131 0.17108154296875 +84132 0.129974365234375 +84133 0.082427978515625 +84134 0.027679443359375 +84135 -0.065643310546875 +84136 -0.15936279296875 +84137 -0.21307373046875 +84138 -0.234649658203125 +84139 -0.2001953125 +84140 -0.119171142578125 +84141 -0.024749755859375 +84142 0.085784912109375 +84143 0.178131103515625 +84144 0.215576171875 +84145 0.211456298828125 +84146 0.17523193359375 +84147 0.128753662109375 +84148 0.1019287109375 +84149 0.0743408203125 +84150 0.04327392578125 +84151 0.038177490234375 +84152 0.076263427734375 +84153 0.14105224609375 +84154 0.186431884765625 +84155 0.188812255859375 +84156 0.1390380859375 +84157 0.041778564453125 +84158 -0.079437255859375 +84159 -0.219390869140625 +84160 -0.367828369140625 +84161 -0.494873046875 +84162 -0.556243896484375 +84163 -0.508697509765625 +84164 -0.3756103515625 +84165 -0.218902587890625 +84166 -0.063751220703125 +84167 0.091552734375 +84168 0.23602294921875 +84169 0.342987060546875 +84170 0.39520263671875 +84171 0.389373779296875 +84172 0.324249267578125 +84173 0.224090576171875 +84174 0.124267578125 +84175 0.037078857421875 +84176 -0.010101318359375 +84177 -0.019439697265625 +84178 -0.022796630859375 +84179 -0.001556396484375 +84180 0.056304931640625 +84181 0.106719970703125 +84182 0.096893310546875 +84183 0.042694091796875 +84184 -0.018035888671875 +84185 -0.07586669921875 +84186 -0.11944580078125 +84187 -0.15972900390625 +84188 -0.202606201171875 +84189 -0.24859619140625 +84190 -0.30517578125 +84191 -0.36212158203125 +84192 -0.39141845703125 +84193 -0.35528564453125 +84194 -0.249969482421875 +84195 -0.092864990234375 +84196 0.08905029296875 +84197 0.2352294921875 +84198 0.318817138671875 +84199 0.358642578125 +84200 0.347747802734375 +84201 0.28564453125 +84202 0.223175048828125 +84203 0.196746826171875 +84204 0.179840087890625 +84205 0.155548095703125 +84206 0.151214599609375 +84207 0.156951904296875 +84208 0.13177490234375 +84209 0.100799560546875 +84210 0.087127685546875 +84211 0.05487060546875 +84212 -0.009002685546875 +84213 -0.10400390625 +84214 -0.229400634765625 +84215 -0.35552978515625 +84216 -0.441925048828125 +84217 -0.473846435546875 +84218 -0.464813232421875 +84219 -0.419097900390625 +84220 -0.334320068359375 +84221 -0.227935791015625 +84222 -0.12347412109375 +84223 -0.02764892578125 +84224 0.077667236328125 +84225 0.2132568359375 +84226 0.38885498046875 +84227 0.582794189453125 +84228 0.734039306640625 +84229 0.800140380859375 +84230 0.7783203125 +84231 0.6651611328125 +84232 0.45965576171875 +84233 0.199188232421875 +84234 -0.050689697265625 +84235 -0.23297119140625 +84236 -0.33013916015625 +84237 -0.368408203125 +84238 -0.378936767578125 +84239 -0.376983642578125 +84240 -0.37969970703125 +84241 -0.391510009765625 +84242 -0.385345458984375 +84243 -0.3419189453125 +84244 -0.28289794921875 +84245 -0.251617431640625 +84246 -0.266143798828125 +84247 -0.273345947265625 +84248 -0.216796875 +84249 -0.128265380859375 +84250 -0.068145751953125 +84251 -0.0430908203125 +84252 -0.024444580078125 +84253 0.020721435546875 +84254 0.124481201171875 +84255 0.25787353515625 +84256 0.379119873046875 +84257 0.47991943359375 +84258 0.5281982421875 +84259 0.511138916015625 +84260 0.456207275390625 +84261 0.407470703125 +84262 0.383758544921875 +84263 0.35687255859375 +84264 0.31182861328125 +84265 0.250885009765625 +84266 0.1654052734375 +84267 0.035247802734375 +84268 -0.142059326171875 +84269 -0.33563232421875 +84270 -0.5345458984375 +84271 -0.72186279296875 +84272 -0.836669921875 +84273 -0.8326416015625 +84274 -0.7296142578125 +84275 -0.582550048828125 +84276 -0.440093994140625 +84277 -0.324310302734375 +84278 -0.20147705078125 +84279 -0.044647216796875 +84280 0.103973388671875 +84281 0.202392578125 +84282 0.264495849609375 +84283 0.338897705078125 +84284 0.443817138671875 +84285 0.545074462890625 +84286 0.6173095703125 +84287 0.6524658203125 +84288 0.66339111328125 +84289 0.6561279296875 +84290 0.606781005859375 +84291 0.501190185546875 +84292 0.352783203125 +84293 0.176544189453125 +84294 -0.034820556640625 +84295 -0.258209228515625 +84296 -0.44244384765625 +84297 -0.5753173828125 +84298 -0.65203857421875 +84299 -0.641632080078125 +84300 -0.562164306640625 +84301 -0.458038330078125 +84302 -0.350555419921875 +84303 -0.260528564453125 +84304 -0.192108154296875 +84305 -0.141937255859375 +84306 -0.1021728515625 +84307 -0.062896728515625 +84308 -0.011932373046875 +84309 0.062835693359375 +84310 0.148712158203125 +84311 0.241729736328125 +84312 0.34912109375 +84313 0.457305908203125 +84314 0.54388427734375 +84315 0.5728759765625 +84316 0.506591796875 +84317 0.351226806640625 +84318 0.146514892578125 +84319 -0.05523681640625 +84320 -0.21624755859375 +84321 -0.334930419921875 +84322 -0.402984619140625 +84323 -0.4412841796875 +84324 -0.49578857421875 +84325 -0.5601806640625 +84326 -0.600738525390625 +84327 -0.584228515625 +84328 -0.47930908203125 +84329 -0.27935791015625 +84330 -0.0089111328125 +84331 0.268798828125 +84332 0.482818603515625 +84333 0.60369873046875 +84334 0.650421142578125 +84335 0.66400146484375 +84336 0.6414794921875 +84337 0.572540283203125 +84338 0.498138427734375 +84339 0.439453125 +84340 0.375518798828125 +84341 0.274505615234375 +84342 0.1087646484375 +84343 -0.099395751953125 +84344 -0.3182373046875 +84345 -0.5489501953125 +84346 -0.7738037109375 +84347 -0.86383056640625 +84348 -0.870391845703125 +84349 -0.86895751953125 +84350 -0.861053466796875 +84351 -0.765869140625 +84352 -0.5301513671875 +84353 -0.214691162109375 +84354 0.137359619140625 +84355 0.474822998046875 +84356 0.76239013671875 +84357 0.867462158203125 +84358 0.870361328125 +84359 0.86480712890625 +84360 0.831817626953125 +84361 0.677581787109375 +84362 0.495880126953125 +84363 0.30767822265625 +84364 0.116180419921875 +84365 -0.110748291015625 +84366 -0.381805419921875 +84367 -0.6572265625 +84368 -0.857421875 +84369 -0.870391845703125 +84370 -0.870391845703125 +84371 -0.86444091796875 +84372 -0.85723876953125 +84373 -0.790008544921875 +84374 -0.62847900390625 +84375 -0.3956298828125 +84376 -0.126708984375 +84377 0.150115966796875 +84378 0.424041748046875 +84379 0.670623779296875 +84380 0.854522705078125 +84381 0.866485595703125 +84382 0.86920166015625 +84383 0.8653564453125 +84384 0.857147216796875 +84385 0.766845703125 +84386 0.628509521484375 +84387 0.462127685546875 +84388 0.297210693359375 +84389 0.14862060546875 +84390 -0.00537109375 +84391 -0.15753173828125 +84392 -0.31304931640625 +84393 -0.48876953125 +84394 -0.6416015625 +84395 -0.751373291015625 +84396 -0.84619140625 +84397 -0.861297607421875 +84398 -0.863250732421875 +84399 -0.856597900390625 +84400 -0.7498779296875 +84401 -0.624542236328125 +84402 -0.47808837890625 +84403 -0.253387451171875 +84404 0.003692626953125 +84405 0.2257080078125 +84406 0.427154541015625 +84407 0.643218994140625 +84408 0.855926513671875 +84409 0.870361328125 +84410 0.870361328125 +84411 0.862762451171875 +84412 0.79669189453125 +84413 0.595794677734375 +84414 0.362152099609375 +84415 0.1270751953125 +84416 -0.086944580078125 +84417 -0.2784423828125 +84418 -0.484832763671875 +84419 -0.729583740234375 +84420 -0.86688232421875 +84421 -0.870391845703125 +84422 -0.86859130859375 +84423 -0.86279296875 +84424 -0.817962646484375 +84425 -0.6116943359375 +84426 -0.3128662109375 +84427 0.039398193359375 +84428 0.422821044921875 +84429 0.805145263671875 +84430 0.870361328125 +84431 0.870361328125 +84432 0.860015869140625 +84433 0.727935791015625 +84434 0.48114013671875 +84435 0.2059326171875 +84436 -0.06103515625 +84437 -0.29913330078125 +84438 -0.516204833984375 +84439 -0.7252197265625 +84440 -0.85980224609375 +84441 -0.870391845703125 +84442 -0.870391845703125 +84443 -0.858062744140625 +84444 -0.673004150390625 +84445 -0.42694091796875 +84446 -0.2100830078125 +84447 -0.0362548828125 +84448 0.10943603515625 +84449 0.23516845703125 +84450 0.373687744140625 +84451 0.517791748046875 +84452 0.602783203125 +84453 0.635711669921875 +84454 0.655181884765625 +84455 0.65948486328125 +84456 0.651275634765625 +84457 0.61846923828125 +84458 0.53753662109375 +84459 0.404144287109375 +84460 0.22186279296875 +84461 0.003997802734375 +84462 -0.22100830078125 +84463 -0.42449951171875 +84464 -0.579833984375 +84465 -0.641876220703125 +84466 -0.6177978515625 +84467 -0.575531005859375 +84468 -0.526336669921875 +84469 -0.42645263671875 +84470 -0.2581787109375 +84471 -0.068695068359375 +84472 0.09222412109375 +84473 0.232147216796875 +84474 0.3509521484375 +84475 0.410064697265625 +84476 0.372955322265625 +84477 0.2554931640625 +84478 0.10711669921875 +84479 -0.052886962890625 +84480 -0.186279296875 +84481 -0.23291015625 +84482 -0.209442138671875 +84483 -0.174163818359375 +84484 -0.126739501953125 +84485 -0.048126220703125 +84486 0.0426025390625 +84487 0.10748291015625 +84488 0.1409912109375 +84489 0.19708251953125 +84490 0.273651123046875 +84491 0.31768798828125 +84492 0.341094970703125 +84493 0.368011474609375 +84494 0.37249755859375 +84495 0.30072021484375 +84496 0.1517333984375 +84497 -0.01470947265625 +84498 -0.1883544921875 +84499 -0.372711181640625 +84500 -0.51397705078125 +84501 -0.57177734375 +84502 -0.53948974609375 +84503 -0.43511962890625 +84504 -0.2962646484375 +84505 -0.161102294921875 +84506 -0.0435791015625 +84507 0.060394287109375 +84508 0.13665771484375 +84509 0.170135498046875 +84510 0.16552734375 +84511 0.15728759765625 +84512 0.150787353515625 +84513 0.12200927734375 +84514 0.080108642578125 +84515 0.05126953125 +84516 0.062896728515625 +84517 0.09271240234375 +84518 0.092987060546875 +84519 0.07855224609375 +84520 0.06427001953125 +84521 0.0347900390625 +84522 -0.01171875 +84523 -0.056060791015625 +84524 -0.055511474609375 +84525 -0.010467529296875 +84526 0.02508544921875 +84527 0.025665283203125 +84528 0.017333984375 +84529 0.00189208984375 +84530 -0.03173828125 +84531 -0.071502685546875 +84532 -0.13543701171875 +84533 -0.219970703125 +84534 -0.300506591796875 +84535 -0.376312255859375 +84536 -0.416107177734375 +84537 -0.371124267578125 +84538 -0.242279052734375 +84539 -0.069732666015625 +84540 0.125640869140625 +84541 0.31268310546875 +84542 0.45501708984375 +84543 0.554779052734375 +84544 0.61065673828125 +84545 0.610931396484375 +84546 0.531463623046875 +84547 0.3883056640625 +84548 0.23468017578125 +84549 0.095245361328125 +84550 -0.00396728515625 +84551 -0.04852294921875 +84552 -0.055145263671875 +84553 -0.0758056640625 +84554 -0.138702392578125 +84555 -0.209197998046875 +84556 -0.289031982421875 +84557 -0.37884521484375 +84558 -0.456329345703125 +84559 -0.51641845703125 +84560 -0.519287109375 +84561 -0.458251953125 +84562 -0.384796142578125 +84563 -0.323699951171875 +84564 -0.269287109375 +84565 -0.1951904296875 +84566 -0.100006103515625 +84567 -0.01055908203125 +84568 0.1033935546875 +84569 0.24908447265625 +84570 0.373199462890625 +84571 0.45806884765625 +84572 0.511474609375 +84573 0.565399169921875 +84574 0.61138916015625 +84575 0.5897216796875 +84576 0.4906005859375 +84577 0.33148193359375 +84578 0.147796630859375 +84579 -0.01873779296875 +84580 -0.140289306640625 +84581 -0.191986083984375 +84582 -0.184295654296875 +84583 -0.161834716796875 +84584 -0.166595458984375 +84585 -0.19390869140625 +84586 -0.22442626953125 +84587 -0.279754638671875 +84588 -0.3389892578125 +84589 -0.3543701171875 +84590 -0.348175048828125 +84591 -0.32598876953125 +84592 -0.2581787109375 +84593 -0.139801025390625 +84594 0.014617919921875 +84595 0.144378662109375 +84596 0.221038818359375 +84597 0.27069091796875 +84598 0.294036865234375 +84599 0.311767578125 +84600 0.339141845703125 +84601 0.360260009765625 +84602 0.360504150390625 +84603 0.308380126953125 +84604 0.18170166015625 +84605 0.0047607421875 +84606 -0.17559814453125 +84607 -0.3143310546875 +84608 -0.36785888671875 +84609 -0.36248779296875 +84610 -0.343536376953125 +84611 -0.3018798828125 +84612 -0.231414794921875 +84613 -0.117645263671875 +84614 0.007049560546875 +84615 0.087982177734375 +84616 0.13946533203125 +84617 0.17425537109375 +84618 0.188201904296875 +84619 0.171234130859375 +84620 0.118438720703125 +84621 0.05706787109375 +84622 -0.010711669921875 +84623 -0.0914306640625 +84624 -0.162322998046875 +84625 -0.194549560546875 +84626 -0.1492919921875 +84627 -0.02166748046875 +84628 0.124053955078125 +84629 0.211151123046875 +84630 0.240447998046875 +84631 0.242218017578125 +84632 0.2257080078125 +84633 0.194366455078125 +84634 0.115509033203125 +84635 0.0128173828125 +84636 -0.053802490234375 +84637 -0.110626220703125 +84638 -0.199493408203125 +84639 -0.29437255859375 +84640 -0.33221435546875 +84641 -0.27972412109375 +84642 -0.185333251953125 +84643 -0.128204345703125 +84644 -0.115692138671875 +84645 -0.116455078125 +84646 -0.105926513671875 +84647 -0.053955078125 +84648 0.048797607421875 +84649 0.157318115234375 +84650 0.212005615234375 +84651 0.218475341796875 +84652 0.23724365234375 +84653 0.30535888671875 +84654 0.38128662109375 +84655 0.404449462890625 +84656 0.3944091796875 +84657 0.3885498046875 +84658 0.362640380859375 +84659 0.27362060546875 +84660 0.11712646484375 +84661 -0.054901123046875 +84662 -0.19085693359375 +84663 -0.28570556640625 +84664 -0.339263916015625 +84665 -0.3775634765625 +84666 -0.445709228515625 +84667 -0.535064697265625 +84668 -0.629058837890625 +84669 -0.697601318359375 +84670 -0.70391845703125 +84671 -0.6424560546875 +84672 -0.491241455078125 +84673 -0.265716552734375 +84674 -0.023712158203125 +84675 0.201751708984375 +84676 0.375823974609375 +84677 0.485076904296875 +84678 0.56884765625 +84679 0.634765625 +84680 0.63763427734375 +84681 0.5660400390625 +84682 0.4720458984375 +84683 0.40692138671875 +84684 0.3778076171875 +84685 0.376953125 +84686 0.371978759765625 +84687 0.313140869140625 +84688 0.184417724609375 +84689 0.011199951171875 +84690 -0.171051025390625 +84691 -0.33740234375 +84692 -0.47198486328125 +84693 -0.560394287109375 +84694 -0.58056640625 +84695 -0.54754638671875 +84696 -0.508575439453125 +84697 -0.459503173828125 +84698 -0.394378662109375 +84699 -0.35260009765625 +84700 -0.31170654296875 +84701 -0.197418212890625 +84702 -0.007965087890625 +84703 0.207489013671875 +84704 0.409210205078125 +84705 0.57208251953125 +84706 0.66595458984375 +84707 0.65875244140625 +84708 0.56744384765625 +84709 0.431396484375 +84710 0.29443359375 +84711 0.182464599609375 +84712 0.06365966796875 +84713 -0.075958251953125 +84714 -0.189422607421875 +84715 -0.271942138671875 +84716 -0.342529296875 +84717 -0.364166259765625 +84718 -0.327239990234375 +84719 -0.2769775390625 +84720 -0.253692626953125 +84721 -0.24365234375 +84722 -0.1983642578125 +84723 -0.116241455078125 +84724 -0.036834716796875 +84725 0.034881591796875 +84726 0.09124755859375 +84727 0.10888671875 +84728 0.125518798828125 +84729 0.15771484375 +84730 0.17828369140625 +84731 0.17108154296875 +84732 0.129974365234375 +84733 0.082427978515625 +84734 0.027679443359375 +84735 -0.065643310546875 +84736 -0.15936279296875 +84737 -0.21307373046875 +84738 -0.234649658203125 +84739 -0.2001953125 +84740 -0.119171142578125 +84741 -0.024749755859375 +84742 0.085784912109375 +84743 0.178131103515625 +84744 0.215576171875 +84745 0.211456298828125 +84746 0.17523193359375 +84747 0.128753662109375 +84748 0.1019287109375 +84749 0.0743408203125 +84750 0.04327392578125 +84751 0.038177490234375 +84752 0.076263427734375 +84753 0.14105224609375 +84754 0.186431884765625 +84755 0.188812255859375 +84756 0.1390380859375 +84757 0.041778564453125 +84758 -0.079437255859375 +84759 -0.219390869140625 +84760 -0.367828369140625 +84761 -0.494873046875 +84762 -0.556243896484375 +84763 -0.508697509765625 +84764 -0.3756103515625 +84765 -0.218902587890625 +84766 -0.063751220703125 +84767 0.091552734375 +84768 0.23602294921875 +84769 0.342987060546875 +84770 0.39520263671875 +84771 0.389373779296875 +84772 0.324249267578125 +84773 0.224090576171875 +84774 0.124267578125 +84775 0.037078857421875 +84776 -0.010101318359375 +84777 -0.019439697265625 +84778 -0.022796630859375 +84779 -0.001556396484375 +84780 0.056304931640625 +84781 0.106719970703125 +84782 0.096893310546875 +84783 0.042694091796875 +84784 -0.018035888671875 +84785 -0.07586669921875 +84786 -0.11944580078125 +84787 -0.15972900390625 +84788 -0.202606201171875 +84789 -0.24859619140625 +84790 -0.30517578125 +84791 -0.36212158203125 +84792 -0.39141845703125 +84793 -0.35528564453125 +84794 -0.249969482421875 +84795 -0.092864990234375 +84796 0.08905029296875 +84797 0.2352294921875 +84798 0.318817138671875 +84799 0.358642578125 +84800 0.347747802734375 +84801 0.28564453125 +84802 0.223175048828125 +84803 0.196746826171875 +84804 0.179840087890625 +84805 0.155548095703125 +84806 0.151214599609375 +84807 0.156951904296875 +84808 0.13177490234375 +84809 0.100799560546875 +84810 0.087127685546875 +84811 0.05487060546875 +84812 -0.009002685546875 +84813 -0.10400390625 +84814 -0.229400634765625 +84815 -0.35552978515625 +84816 -0.441925048828125 +84817 -0.473846435546875 +84818 -0.464813232421875 +84819 -0.419097900390625 +84820 -0.334320068359375 +84821 -0.227935791015625 +84822 -0.12347412109375 +84823 -0.02764892578125 +84824 0.077667236328125 +84825 0.2132568359375 +84826 0.38885498046875 +84827 0.582794189453125 +84828 0.734039306640625 +84829 0.800140380859375 +84830 0.7783203125 +84831 0.6651611328125 +84832 0.45965576171875 +84833 0.199188232421875 +84834 -0.050689697265625 +84835 -0.23297119140625 +84836 -0.33013916015625 +84837 -0.368408203125 +84838 -0.378936767578125 +84839 -0.376983642578125 +84840 -0.37969970703125 +84841 -0.391510009765625 +84842 -0.385345458984375 +84843 -0.3419189453125 +84844 -0.28289794921875 +84845 -0.251617431640625 +84846 -0.266143798828125 +84847 -0.273345947265625 +84848 -0.216796875 +84849 -0.128265380859375 +84850 -0.068145751953125 +84851 -0.0430908203125 +84852 -0.024444580078125 +84853 0.020721435546875 +84854 0.124481201171875 +84855 0.25787353515625 +84856 0.379119873046875 +84857 0.47991943359375 +84858 0.5281982421875 +84859 0.511138916015625 +84860 0.456207275390625 +84861 0.407470703125 +84862 0.383758544921875 +84863 0.35687255859375 +84864 0.31182861328125 +84865 0.250885009765625 +84866 0.1654052734375 +84867 0.035247802734375 +84868 -0.142059326171875 +84869 -0.33563232421875 +84870 -0.5345458984375 +84871 -0.72186279296875 +84872 -0.836669921875 +84873 -0.8326416015625 +84874 -0.7296142578125 +84875 -0.582550048828125 +84876 -0.440093994140625 +84877 -0.324310302734375 +84878 -0.20147705078125 +84879 -0.044647216796875 +84880 0.103973388671875 +84881 0.202392578125 +84882 0.264495849609375 +84883 0.338897705078125 +84884 0.443817138671875 +84885 0.545074462890625 +84886 0.6173095703125 +84887 0.6524658203125 +84888 0.66339111328125 +84889 0.6561279296875 +84890 0.606781005859375 +84891 0.501190185546875 +84892 0.352783203125 +84893 0.176544189453125 +84894 -0.034820556640625 +84895 -0.258209228515625 +84896 -0.44244384765625 +84897 -0.5753173828125 +84898 -0.65203857421875 +84899 -0.641632080078125 +84900 -0.562164306640625 +84901 -0.458038330078125 +84902 -0.350555419921875 +84903 -0.260528564453125 +84904 -0.192108154296875 +84905 -0.141937255859375 +84906 -0.1021728515625 +84907 -0.062896728515625 +84908 -0.011932373046875 +84909 0.062835693359375 +84910 0.148712158203125 +84911 0.241729736328125 +84912 0.34912109375 +84913 0.457305908203125 +84914 0.54388427734375 +84915 0.5728759765625 +84916 0.506591796875 +84917 0.351226806640625 +84918 0.146514892578125 +84919 -0.05523681640625 +84920 -0.21624755859375 +84921 -0.334930419921875 +84922 -0.402984619140625 +84923 -0.4412841796875 +84924 -0.49578857421875 +84925 -0.5601806640625 +84926 -0.600738525390625 +84927 -0.584228515625 +84928 -0.47930908203125 +84929 -0.27935791015625 +84930 -0.0089111328125 +84931 0.268798828125 +84932 0.482818603515625 +84933 0.60369873046875 +84934 0.650421142578125 +84935 0.66400146484375 +84936 0.6414794921875 +84937 0.572540283203125 +84938 0.498138427734375 +84939 0.439453125 +84940 0.375518798828125 +84941 0.274505615234375 +84942 0.1087646484375 +84943 -0.099395751953125 +84944 -0.3182373046875 +84945 -0.5489501953125 +84946 -0.7738037109375 +84947 -0.86383056640625 +84948 -0.870391845703125 +84949 -0.86895751953125 +84950 -0.861053466796875 +84951 -0.765869140625 +84952 -0.5301513671875 +84953 -0.214691162109375 +84954 0.137359619140625 +84955 0.474822998046875 +84956 0.76239013671875 +84957 0.867462158203125 +84958 0.870361328125 +84959 0.86480712890625 +84960 0.831817626953125 +84961 0.677581787109375 +84962 0.495880126953125 +84963 0.30767822265625 +84964 0.116180419921875 +84965 -0.110748291015625 +84966 -0.381805419921875 +84967 -0.6572265625 +84968 -0.857421875 +84969 -0.870391845703125 +84970 -0.870391845703125 +84971 -0.86444091796875 +84972 -0.85723876953125 +84973 -0.790008544921875 +84974 -0.62847900390625 +84975 -0.3956298828125 +84976 -0.126708984375 +84977 0.150115966796875 +84978 0.424041748046875 +84979 0.670623779296875 +84980 0.854522705078125 +84981 0.866485595703125 +84982 0.86920166015625 +84983 0.8653564453125 +84984 0.857147216796875 +84985 0.766845703125 +84986 0.628509521484375 +84987 0.462127685546875 +84988 0.297210693359375 +84989 0.14862060546875 +84990 -0.00537109375 +84991 -0.15753173828125 +84992 -0.31304931640625 +84993 -0.48876953125 +84994 -0.6416015625 +84995 -0.751373291015625 +84996 -0.84619140625 +84997 -0.861297607421875 +84998 -0.863250732421875 +84999 -0.856597900390625 +85000 -0.7498779296875 +85001 -0.624542236328125 +85002 -0.47808837890625 +85003 -0.253387451171875 +85004 0.003692626953125 +85005 0.2257080078125 +85006 0.427154541015625 +85007 0.643218994140625 +85008 0.855926513671875 +85009 0.870361328125 +85010 0.870361328125 +85011 0.862762451171875 +85012 0.79669189453125 +85013 0.595794677734375 +85014 0.362152099609375 +85015 0.1270751953125 +85016 -0.086944580078125 +85017 -0.2784423828125 +85018 -0.484832763671875 +85019 -0.729583740234375 +85020 -0.86688232421875 +85021 -0.870391845703125 +85022 -0.86859130859375 +85023 -0.86279296875 +85024 -0.817962646484375 +85025 -0.6116943359375 +85026 -0.3128662109375 +85027 0.039398193359375 +85028 0.422821044921875 +85029 0.805145263671875 +85030 0.870361328125 +85031 0.870361328125 +85032 0.860015869140625 +85033 0.727935791015625 +85034 0.48114013671875 +85035 0.2059326171875 +85036 -0.06103515625 +85037 -0.29913330078125 +85038 -0.516204833984375 +85039 -0.7252197265625 +85040 -0.85980224609375 +85041 -0.870391845703125 +85042 -0.870391845703125 +85043 -0.858062744140625 +85044 -0.673004150390625 +85045 -0.42694091796875 +85046 -0.2100830078125 +85047 -0.0362548828125 +85048 0.10943603515625 +85049 0.23516845703125 +85050 0.373687744140625 +85051 0.517791748046875 +85052 0.602783203125 +85053 0.635711669921875 +85054 0.655181884765625 +85055 0.65948486328125 +85056 0.651275634765625 +85057 0.61846923828125 +85058 0.53753662109375 +85059 0.404144287109375 +85060 0.22186279296875 +85061 0.003997802734375 +85062 -0.22100830078125 +85063 -0.42449951171875 +85064 -0.579833984375 +85065 -0.641876220703125 +85066 -0.6177978515625 +85067 -0.575531005859375 +85068 -0.526336669921875 +85069 -0.42645263671875 +85070 -0.2581787109375 +85071 -0.068695068359375 +85072 0.09222412109375 +85073 0.232147216796875 +85074 0.3509521484375 +85075 0.410064697265625 +85076 0.372955322265625 +85077 0.2554931640625 +85078 0.10711669921875 +85079 -0.052886962890625 +85080 -0.186279296875 +85081 -0.23291015625 +85082 -0.209442138671875 +85083 -0.174163818359375 +85084 -0.126739501953125 +85085 -0.048126220703125 +85086 0.0426025390625 +85087 0.10748291015625 +85088 0.1409912109375 +85089 0.19708251953125 +85090 0.273651123046875 +85091 0.31768798828125 +85092 0.341094970703125 +85093 0.368011474609375 +85094 0.37249755859375 +85095 0.30072021484375 +85096 0.1517333984375 +85097 -0.01470947265625 +85098 -0.1883544921875 +85099 -0.372711181640625 +85100 -0.51397705078125 +85101 -0.57177734375 +85102 -0.53948974609375 +85103 -0.43511962890625 +85104 -0.2962646484375 +85105 -0.161102294921875 +85106 -0.0435791015625 +85107 0.060394287109375 +85108 0.13665771484375 +85109 0.170135498046875 +85110 0.16552734375 +85111 0.15728759765625 +85112 0.150787353515625 +85113 0.12200927734375 +85114 0.080108642578125 +85115 0.05126953125 +85116 0.062896728515625 +85117 0.09271240234375 +85118 0.092987060546875 +85119 0.07855224609375 +85120 0.06427001953125 +85121 0.0347900390625 +85122 -0.01171875 +85123 -0.056060791015625 +85124 -0.055511474609375 +85125 -0.010467529296875 +85126 0.02508544921875 +85127 0.025665283203125 +85128 0.017333984375 +85129 0.00189208984375 +85130 -0.03173828125 +85131 -0.071502685546875 +85132 -0.13543701171875 +85133 -0.219970703125 +85134 -0.300506591796875 +85135 -0.376312255859375 +85136 -0.416107177734375 +85137 -0.371124267578125 +85138 -0.242279052734375 +85139 -0.069732666015625 +85140 0.125640869140625 +85141 0.31268310546875 +85142 0.45501708984375 +85143 0.554779052734375 +85144 0.61065673828125 +85145 0.610931396484375 +85146 0.531463623046875 +85147 0.3883056640625 +85148 0.23468017578125 +85149 0.095245361328125 +85150 -0.00396728515625 +85151 -0.04852294921875 +85152 -0.055145263671875 +85153 -0.0758056640625 +85154 -0.138702392578125 +85155 -0.209197998046875 +85156 -0.289031982421875 +85157 -0.37884521484375 +85158 -0.456329345703125 +85159 -0.51641845703125 +85160 -0.519287109375 +85161 -0.458251953125 +85162 -0.384796142578125 +85163 -0.323699951171875 +85164 -0.269287109375 +85165 -0.1951904296875 +85166 -0.100006103515625 +85167 -0.01055908203125 +85168 0.1033935546875 +85169 0.24908447265625 +85170 0.373199462890625 +85171 0.45806884765625 +85172 0.511474609375 +85173 0.565399169921875 +85174 0.61138916015625 +85175 0.5897216796875 +85176 0.4906005859375 +85177 0.33148193359375 +85178 0.147796630859375 +85179 -0.01873779296875 +85180 -0.140289306640625 +85181 -0.191986083984375 +85182 -0.184295654296875 +85183 -0.161834716796875 +85184 -0.166595458984375 +85185 -0.19390869140625 +85186 -0.22442626953125 +85187 -0.279754638671875 +85188 -0.3389892578125 +85189 -0.3543701171875 +85190 -0.348175048828125 +85191 -0.32598876953125 +85192 -0.2581787109375 +85193 -0.139801025390625 +85194 0.014617919921875 +85195 0.144378662109375 +85196 0.221038818359375 +85197 0.27069091796875 +85198 0.294036865234375 +85199 0.311767578125 +85200 0.339141845703125 +85201 0.360260009765625 +85202 0.360504150390625 +85203 0.308380126953125 +85204 0.18170166015625 +85205 0.0047607421875 +85206 -0.17559814453125 +85207 -0.3143310546875 +85208 -0.36785888671875 +85209 -0.36248779296875 +85210 -0.343536376953125 +85211 -0.3018798828125 +85212 -0.231414794921875 +85213 -0.117645263671875 +85214 0.007049560546875 +85215 0.087982177734375 +85216 0.13946533203125 +85217 0.17425537109375 +85218 0.188201904296875 +85219 0.171234130859375 +85220 0.118438720703125 +85221 0.05706787109375 +85222 -0.010711669921875 +85223 -0.0914306640625 +85224 -0.162322998046875 +85225 -0.194549560546875 +85226 -0.1492919921875 +85227 -0.02166748046875 +85228 0.124053955078125 +85229 0.211151123046875 +85230 0.240447998046875 +85231 0.242218017578125 +85232 0.2257080078125 +85233 0.194366455078125 +85234 0.115509033203125 +85235 0.0128173828125 +85236 -0.053802490234375 +85237 -0.110626220703125 +85238 -0.199493408203125 +85239 -0.29437255859375 +85240 -0.33221435546875 +85241 -0.27972412109375 +85242 -0.185333251953125 +85243 -0.128204345703125 +85244 -0.115692138671875 +85245 -0.116455078125 +85246 -0.105926513671875 +85247 -0.053955078125 +85248 0.048797607421875 +85249 0.157318115234375 +85250 0.212005615234375 +85251 0.218475341796875 +85252 0.23724365234375 +85253 0.30535888671875 +85254 0.38128662109375 +85255 0.404449462890625 +85256 0.3944091796875 +85257 0.3885498046875 +85258 0.362640380859375 +85259 0.27362060546875 +85260 0.11712646484375 +85261 -0.054901123046875 +85262 -0.19085693359375 +85263 -0.28570556640625 +85264 -0.339263916015625 +85265 -0.3775634765625 +85266 -0.445709228515625 +85267 -0.535064697265625 +85268 -0.629058837890625 +85269 -0.697601318359375 +85270 -0.70391845703125 +85271 -0.6424560546875 +85272 -0.491241455078125 +85273 -0.265716552734375 +85274 -0.023712158203125 +85275 0.201751708984375 +85276 0.375823974609375 +85277 0.485076904296875 +85278 0.56884765625 +85279 0.634765625 +85280 0.63763427734375 +85281 0.5660400390625 +85282 0.4720458984375 +85283 0.40692138671875 +85284 0.3778076171875 +85285 0.376953125 +85286 0.371978759765625 +85287 0.313140869140625 +85288 0.184417724609375 +85289 0.011199951171875 +85290 -0.171051025390625 +85291 -0.33740234375 +85292 -0.47198486328125 +85293 -0.560394287109375 +85294 -0.58056640625 +85295 -0.54754638671875 +85296 -0.508575439453125 +85297 -0.459503173828125 +85298 -0.394378662109375 +85299 -0.35260009765625 +85300 -0.31170654296875 +85301 -0.197418212890625 +85302 -0.007965087890625 +85303 0.207489013671875 +85304 0.409210205078125 +85305 0.57208251953125 +85306 0.66595458984375 +85307 0.65875244140625 +85308 0.56744384765625 +85309 0.431396484375 +85310 0.29443359375 +85311 0.182464599609375 +85312 0.06365966796875 +85313 -0.075958251953125 +85314 -0.189422607421875 +85315 -0.271942138671875 +85316 -0.342529296875 +85317 -0.364166259765625 +85318 -0.327239990234375 +85319 -0.2769775390625 +85320 -0.253692626953125 +85321 -0.24365234375 +85322 -0.1983642578125 +85323 -0.116241455078125 +85324 -0.036834716796875 +85325 0.034881591796875 +85326 0.09124755859375 +85327 0.10888671875 +85328 0.125518798828125 +85329 0.15771484375 +85330 0.17828369140625 +85331 0.17108154296875 +85332 0.129974365234375 +85333 0.082427978515625 +85334 0.027679443359375 +85335 -0.065643310546875 +85336 -0.15936279296875 +85337 -0.21307373046875 +85338 -0.234649658203125 +85339 -0.2001953125 +85340 -0.119171142578125 +85341 -0.024749755859375 +85342 0.085784912109375 +85343 0.178131103515625 +85344 0.215576171875 +85345 0.211456298828125 +85346 0.17523193359375 +85347 0.128753662109375 +85348 0.1019287109375 +85349 0.0743408203125 +85350 0.04327392578125 +85351 0.038177490234375 +85352 0.076263427734375 +85353 0.14105224609375 +85354 0.186431884765625 +85355 0.188812255859375 +85356 0.1390380859375 +85357 0.041778564453125 +85358 -0.079437255859375 +85359 -0.219390869140625 +85360 -0.367828369140625 +85361 -0.494873046875 +85362 -0.556243896484375 +85363 -0.508697509765625 +85364 -0.3756103515625 +85365 -0.218902587890625 +85366 -0.063751220703125 +85367 0.091552734375 +85368 0.23602294921875 +85369 0.342987060546875 +85370 0.39520263671875 +85371 0.389373779296875 +85372 0.324249267578125 +85373 0.224090576171875 +85374 0.124267578125 +85375 0.037078857421875 +85376 -0.010101318359375 +85377 -0.019439697265625 +85378 -0.022796630859375 +85379 -0.001556396484375 +85380 0.056304931640625 +85381 0.106719970703125 +85382 0.096893310546875 +85383 0.042694091796875 +85384 -0.018035888671875 +85385 -0.07586669921875 +85386 -0.11944580078125 +85387 -0.15972900390625 +85388 -0.202606201171875 +85389 -0.24859619140625 +85390 -0.30517578125 +85391 -0.36212158203125 +85392 -0.39141845703125 +85393 -0.35528564453125 +85394 -0.249969482421875 +85395 -0.092864990234375 +85396 0.08905029296875 +85397 0.2352294921875 +85398 0.318817138671875 +85399 0.358642578125 +85400 0.347747802734375 +85401 0.28564453125 +85402 0.223175048828125 +85403 0.196746826171875 +85404 0.179840087890625 +85405 0.155548095703125 +85406 0.151214599609375 +85407 0.156951904296875 +85408 0.13177490234375 +85409 0.100799560546875 +85410 0.087127685546875 +85411 0.05487060546875 +85412 -0.009002685546875 +85413 -0.10400390625 +85414 -0.229400634765625 +85415 -0.35552978515625 +85416 -0.441925048828125 +85417 -0.473846435546875 +85418 -0.464813232421875 +85419 -0.419097900390625 +85420 -0.334320068359375 +85421 -0.227935791015625 +85422 -0.12347412109375 +85423 -0.02764892578125 +85424 0.077667236328125 +85425 0.2132568359375 +85426 0.38885498046875 +85427 0.582794189453125 +85428 0.734039306640625 +85429 0.800140380859375 +85430 0.7783203125 +85431 0.6651611328125 +85432 0.45965576171875 +85433 0.199188232421875 +85434 -0.050689697265625 +85435 -0.23297119140625 +85436 -0.33013916015625 +85437 -0.368408203125 +85438 -0.378936767578125 +85439 -0.376983642578125 +85440 -0.37969970703125 +85441 -0.391510009765625 +85442 -0.385345458984375 +85443 -0.3419189453125 +85444 -0.28289794921875 +85445 -0.251617431640625 +85446 -0.266143798828125 +85447 -0.273345947265625 +85448 -0.216796875 +85449 -0.128265380859375 +85450 -0.068145751953125 +85451 -0.0430908203125 +85452 -0.024444580078125 +85453 0.020721435546875 +85454 0.124481201171875 +85455 0.25787353515625 +85456 0.379119873046875 +85457 0.47991943359375 +85458 0.5281982421875 +85459 0.511138916015625 +85460 0.456207275390625 +85461 0.407470703125 +85462 0.383758544921875 +85463 0.35687255859375 +85464 0.31182861328125 +85465 0.250885009765625 +85466 0.1654052734375 +85467 0.035247802734375 +85468 -0.142059326171875 +85469 -0.33563232421875 +85470 -0.5345458984375 +85471 -0.72186279296875 +85472 -0.836669921875 +85473 -0.8326416015625 +85474 -0.7296142578125 +85475 -0.582550048828125 +85476 -0.440093994140625 +85477 -0.324310302734375 +85478 -0.20147705078125 +85479 -0.044647216796875 +85480 0.103973388671875 +85481 0.202392578125 +85482 0.264495849609375 +85483 0.338897705078125 +85484 0.443817138671875 +85485 0.545074462890625 +85486 0.6173095703125 +85487 0.6524658203125 +85488 0.66339111328125 +85489 0.6561279296875 +85490 0.606781005859375 +85491 0.501190185546875 +85492 0.352783203125 +85493 0.176544189453125 +85494 -0.034820556640625 +85495 -0.258209228515625 +85496 -0.44244384765625 +85497 -0.5753173828125 +85498 -0.65203857421875 +85499 -0.641632080078125 +85500 -0.562164306640625 +85501 -0.458038330078125 +85502 -0.350555419921875 +85503 -0.260528564453125 +85504 -0.192108154296875 +85505 -0.141937255859375 +85506 -0.1021728515625 +85507 -0.062896728515625 +85508 -0.011932373046875 +85509 0.062835693359375 +85510 0.148712158203125 +85511 0.241729736328125 +85512 0.34912109375 +85513 0.457305908203125 +85514 0.54388427734375 +85515 0.5728759765625 +85516 0.506591796875 +85517 0.351226806640625 +85518 0.146514892578125 +85519 -0.05523681640625 +85520 -0.21624755859375 +85521 -0.334930419921875 +85522 -0.402984619140625 +85523 -0.4412841796875 +85524 -0.49578857421875 +85525 -0.5601806640625 +85526 -0.600738525390625 +85527 -0.584228515625 +85528 -0.47930908203125 +85529 -0.27935791015625 +85530 -0.0089111328125 +85531 0.268798828125 +85532 0.482818603515625 +85533 0.60369873046875 +85534 0.650421142578125 +85535 0.66400146484375 +85536 0.6414794921875 +85537 0.572540283203125 +85538 0.498138427734375 +85539 0.439453125 +85540 0.375518798828125 +85541 0.274505615234375 +85542 0.1087646484375 +85543 -0.099395751953125 +85544 -0.3182373046875 +85545 -0.5489501953125 +85546 -0.7738037109375 +85547 -0.86383056640625 +85548 -0.870391845703125 +85549 -0.86895751953125 +85550 -0.861053466796875 +85551 -0.765869140625 +85552 -0.5301513671875 +85553 -0.214691162109375 +85554 0.137359619140625 +85555 0.474822998046875 +85556 0.76239013671875 +85557 0.867462158203125 +85558 0.870361328125 +85559 0.86480712890625 +85560 0.831817626953125 +85561 0.677581787109375 +85562 0.495880126953125 +85563 0.30767822265625 +85564 0.116180419921875 +85565 -0.110748291015625 +85566 -0.381805419921875 +85567 -0.6572265625 +85568 -0.857421875 +85569 -0.870391845703125 +85570 -0.870391845703125 +85571 -0.86444091796875 +85572 -0.85723876953125 +85573 -0.790008544921875 +85574 -0.62847900390625 +85575 -0.3956298828125 +85576 -0.126708984375 +85577 0.150115966796875 +85578 0.424041748046875 +85579 0.670623779296875 +85580 0.854522705078125 +85581 0.866485595703125 +85582 0.86920166015625 +85583 0.8653564453125 +85584 0.857147216796875 +85585 0.766845703125 +85586 0.628509521484375 +85587 0.462127685546875 +85588 0.297210693359375 +85589 0.14862060546875 +85590 -0.00537109375 +85591 -0.15753173828125 +85592 -0.31304931640625 +85593 -0.48876953125 +85594 -0.6416015625 +85595 -0.751373291015625 +85596 -0.84619140625 +85597 -0.861297607421875 +85598 -0.863250732421875 +85599 -0.856597900390625 +85600 -0.7498779296875 +85601 -0.624542236328125 +85602 -0.47808837890625 +85603 -0.253387451171875 +85604 0.003692626953125 +85605 0.2257080078125 +85606 0.427154541015625 +85607 0.643218994140625 +85608 0.855926513671875 +85609 0.870361328125 +85610 0.870361328125 +85611 0.862762451171875 +85612 0.79669189453125 +85613 0.595794677734375 +85614 0.362152099609375 +85615 0.1270751953125 +85616 -0.086944580078125 +85617 -0.2784423828125 +85618 -0.484832763671875 +85619 -0.729583740234375 +85620 -0.86688232421875 +85621 -0.870391845703125 +85622 -0.86859130859375 +85623 -0.86279296875 +85624 -0.817962646484375 +85625 -0.6116943359375 +85626 -0.3128662109375 +85627 0.039398193359375 +85628 0.422821044921875 +85629 0.805145263671875 +85630 0.870361328125 +85631 0.870361328125 +85632 0.860015869140625 +85633 0.727935791015625 +85634 0.48114013671875 +85635 0.2059326171875 +85636 -0.06103515625 +85637 -0.29913330078125 +85638 -0.516204833984375 +85639 -0.7252197265625 +85640 -0.85980224609375 +85641 -0.870391845703125 +85642 -0.870391845703125 +85643 -0.858062744140625 +85644 -0.673004150390625 +85645 -0.42694091796875 +85646 -0.2100830078125 +85647 -0.0362548828125 +85648 0.10943603515625 +85649 0.23516845703125 +85650 0.373687744140625 +85651 0.517791748046875 +85652 0.602783203125 +85653 0.635711669921875 +85654 0.655181884765625 +85655 0.65948486328125 +85656 0.651275634765625 +85657 0.61846923828125 +85658 0.53753662109375 +85659 0.404144287109375 +85660 0.22186279296875 +85661 0.003997802734375 +85662 -0.22100830078125 +85663 -0.42449951171875 +85664 -0.579833984375 +85665 -0.641876220703125 +85666 -0.6177978515625 +85667 -0.575531005859375 +85668 -0.526336669921875 +85669 -0.42645263671875 +85670 -0.2581787109375 +85671 -0.068695068359375 +85672 0.09222412109375 +85673 0.232147216796875 +85674 0.3509521484375 +85675 0.410064697265625 +85676 0.372955322265625 +85677 0.2554931640625 +85678 0.10711669921875 +85679 -0.052886962890625 +85680 -0.186279296875 +85681 -0.23291015625 +85682 -0.209442138671875 +85683 -0.174163818359375 +85684 -0.126739501953125 +85685 -0.048126220703125 +85686 0.0426025390625 +85687 0.10748291015625 +85688 0.1409912109375 +85689 0.19708251953125 +85690 0.273651123046875 +85691 0.31768798828125 +85692 0.341094970703125 +85693 0.368011474609375 +85694 0.37249755859375 +85695 0.30072021484375 +85696 0.1517333984375 +85697 -0.01470947265625 +85698 -0.1883544921875 +85699 -0.372711181640625 +85700 -0.51397705078125 +85701 -0.57177734375 +85702 -0.53948974609375 +85703 -0.43511962890625 +85704 -0.2962646484375 +85705 -0.161102294921875 +85706 -0.0435791015625 +85707 0.060394287109375 +85708 0.13665771484375 +85709 0.170135498046875 +85710 0.16552734375 +85711 0.15728759765625 +85712 0.150787353515625 +85713 0.12200927734375 +85714 0.080108642578125 +85715 0.05126953125 +85716 0.062896728515625 +85717 0.09271240234375 +85718 0.092987060546875 +85719 0.07855224609375 +85720 0.06427001953125 +85721 0.0347900390625 +85722 -0.01171875 +85723 -0.056060791015625 +85724 -0.055511474609375 +85725 -0.010467529296875 +85726 0.02508544921875 +85727 0.025665283203125 +85728 0.017333984375 +85729 0.00189208984375 +85730 -0.03173828125 +85731 -0.071502685546875 +85732 -0.13543701171875 +85733 -0.219970703125 +85734 -0.300506591796875 +85735 -0.376312255859375 +85736 -0.416107177734375 +85737 -0.371124267578125 +85738 -0.242279052734375 +85739 -0.069732666015625 +85740 0.125640869140625 +85741 0.31268310546875 +85742 0.45501708984375 +85743 0.554779052734375 +85744 0.61065673828125 +85745 0.610931396484375 +85746 0.531463623046875 +85747 0.3883056640625 +85748 0.23468017578125 +85749 0.095245361328125 +85750 -0.00396728515625 +85751 -0.04852294921875 +85752 -0.055145263671875 +85753 -0.0758056640625 +85754 -0.138702392578125 +85755 -0.209197998046875 +85756 -0.289031982421875 +85757 -0.37884521484375 +85758 -0.456329345703125 +85759 -0.51641845703125 +85760 -0.519287109375 +85761 -0.458251953125 +85762 -0.384796142578125 +85763 -0.323699951171875 +85764 -0.269287109375 +85765 -0.1951904296875 +85766 -0.100006103515625 +85767 -0.01055908203125 +85768 0.1033935546875 +85769 0.24908447265625 +85770 0.373199462890625 +85771 0.45806884765625 +85772 0.511474609375 +85773 0.565399169921875 +85774 0.61138916015625 +85775 0.5897216796875 +85776 0.4906005859375 +85777 0.33148193359375 +85778 0.147796630859375 +85779 -0.01873779296875 +85780 -0.140289306640625 +85781 -0.191986083984375 +85782 -0.184295654296875 +85783 -0.161834716796875 +85784 -0.166595458984375 +85785 -0.19390869140625 +85786 -0.22442626953125 +85787 -0.279754638671875 +85788 -0.3389892578125 +85789 -0.3543701171875 +85790 -0.348175048828125 +85791 -0.32598876953125 +85792 -0.2581787109375 +85793 -0.139801025390625 +85794 0.014617919921875 +85795 0.144378662109375 +85796 0.221038818359375 +85797 0.27069091796875 +85798 0.294036865234375 +85799 0.311767578125 +85800 0.339141845703125 +85801 0.360260009765625 +85802 0.360504150390625 +85803 0.308380126953125 +85804 0.18170166015625 +85805 0.0047607421875 +85806 -0.17559814453125 +85807 -0.3143310546875 +85808 -0.36785888671875 +85809 -0.36248779296875 +85810 -0.343536376953125 +85811 -0.3018798828125 +85812 -0.231414794921875 +85813 -0.117645263671875 +85814 0.007049560546875 +85815 0.087982177734375 +85816 0.13946533203125 +85817 0.17425537109375 +85818 0.188201904296875 +85819 0.171234130859375 +85820 0.118438720703125 +85821 0.05706787109375 +85822 -0.010711669921875 +85823 -0.0914306640625 +85824 -0.162322998046875 +85825 -0.194549560546875 +85826 -0.1492919921875 +85827 -0.02166748046875 +85828 0.124053955078125 +85829 0.211151123046875 +85830 0.240447998046875 +85831 0.242218017578125 +85832 0.2257080078125 +85833 0.194366455078125 +85834 0.115509033203125 +85835 0.0128173828125 +85836 -0.053802490234375 +85837 -0.110626220703125 +85838 -0.199493408203125 +85839 -0.29437255859375 +85840 -0.33221435546875 +85841 -0.27972412109375 +85842 -0.185333251953125 +85843 -0.128204345703125 +85844 -0.115692138671875 +85845 -0.116455078125 +85846 -0.105926513671875 +85847 -0.053955078125 +85848 0.048797607421875 +85849 0.157318115234375 +85850 0.212005615234375 +85851 0.218475341796875 +85852 0.23724365234375 +85853 0.30535888671875 +85854 0.38128662109375 +85855 0.404449462890625 +85856 0.3944091796875 +85857 0.3885498046875 +85858 0.362640380859375 +85859 0.27362060546875 +85860 0.11712646484375 +85861 -0.054901123046875 +85862 -0.19085693359375 +85863 -0.28570556640625 +85864 -0.339263916015625 +85865 -0.3775634765625 +85866 -0.445709228515625 +85867 -0.535064697265625 +85868 -0.629058837890625 +85869 -0.697601318359375 +85870 -0.70391845703125 +85871 -0.6424560546875 +85872 -0.491241455078125 +85873 -0.265716552734375 +85874 -0.023712158203125 +85875 0.201751708984375 +85876 0.375823974609375 +85877 0.485076904296875 +85878 0.56884765625 +85879 0.634765625 +85880 0.63763427734375 +85881 0.5660400390625 +85882 0.4720458984375 +85883 0.40692138671875 +85884 0.3778076171875 +85885 0.376953125 +85886 0.371978759765625 +85887 0.313140869140625 +85888 0.184417724609375 +85889 0.011199951171875 +85890 -0.171051025390625 +85891 -0.33740234375 +85892 -0.47198486328125 +85893 -0.560394287109375 +85894 -0.58056640625 +85895 -0.54754638671875 +85896 -0.508575439453125 +85897 -0.459503173828125 +85898 -0.394378662109375 +85899 -0.35260009765625 +85900 -0.31170654296875 +85901 -0.197418212890625 +85902 -0.007965087890625 +85903 0.207489013671875 +85904 0.409210205078125 +85905 0.57208251953125 +85906 0.66595458984375 +85907 0.65875244140625 +85908 0.56744384765625 +85909 0.431396484375 +85910 0.29443359375 +85911 0.182464599609375 +85912 0.06365966796875 +85913 -0.075958251953125 +85914 -0.189422607421875 +85915 -0.271942138671875 +85916 -0.342529296875 +85917 -0.364166259765625 +85918 -0.327239990234375 +85919 -0.2769775390625 +85920 -0.253692626953125 +85921 -0.24365234375 +85922 -0.1983642578125 +85923 -0.116241455078125 +85924 -0.036834716796875 +85925 0.034881591796875 +85926 0.09124755859375 +85927 0.10888671875 +85928 0.125518798828125 +85929 0.15771484375 +85930 0.17828369140625 +85931 0.17108154296875 +85932 0.129974365234375 +85933 0.082427978515625 +85934 0.027679443359375 +85935 -0.065643310546875 +85936 -0.15936279296875 +85937 -0.21307373046875 +85938 -0.234649658203125 +85939 -0.2001953125 +85940 -0.119171142578125 +85941 -0.024749755859375 +85942 0.085784912109375 +85943 0.178131103515625 +85944 0.215576171875 +85945 0.211456298828125 +85946 0.17523193359375 +85947 0.128753662109375 +85948 0.1019287109375 +85949 0.0743408203125 +85950 0.04327392578125 +85951 0.038177490234375 +85952 0.076263427734375 +85953 0.14105224609375 +85954 0.186431884765625 +85955 0.188812255859375 +85956 0.1390380859375 +85957 0.041778564453125 +85958 -0.079437255859375 +85959 -0.219390869140625 +85960 -0.367828369140625 +85961 -0.494873046875 +85962 -0.556243896484375 +85963 -0.508697509765625 +85964 -0.3756103515625 +85965 -0.218902587890625 +85966 -0.063751220703125 +85967 0.091552734375 +85968 0.23602294921875 +85969 0.342987060546875 +85970 0.39520263671875 +85971 0.389373779296875 +85972 0.324249267578125 +85973 0.224090576171875 +85974 0.124267578125 +85975 0.037078857421875 +85976 -0.010101318359375 +85977 -0.019439697265625 +85978 -0.022796630859375 +85979 -0.001556396484375 +85980 0.056304931640625 +85981 0.106719970703125 +85982 0.096893310546875 +85983 0.042694091796875 +85984 -0.018035888671875 +85985 -0.07586669921875 +85986 -0.11944580078125 +85987 -0.15972900390625 +85988 -0.202606201171875 +85989 -0.24859619140625 +85990 -0.30517578125 +85991 -0.36212158203125 +85992 -0.39141845703125 +85993 -0.35528564453125 +85994 -0.249969482421875 +85995 -0.092864990234375 +85996 0.08905029296875 +85997 0.2352294921875 +85998 0.318817138671875 +85999 0.358642578125 +86000 0.347747802734375 +86001 0.28564453125 +86002 0.223175048828125 +86003 0.196746826171875 +86004 0.179840087890625 +86005 0.155548095703125 +86006 0.151214599609375 +86007 0.156951904296875 +86008 0.13177490234375 +86009 0.100799560546875 +86010 0.087127685546875 +86011 0.05487060546875 +86012 -0.009002685546875 +86013 -0.10400390625 +86014 -0.229400634765625 +86015 -0.35552978515625 +86016 -0.441925048828125 +86017 -0.473846435546875 +86018 -0.464813232421875 +86019 -0.419097900390625 +86020 -0.334320068359375 +86021 -0.227935791015625 +86022 -0.12347412109375 +86023 -0.02764892578125 +86024 0.077667236328125 +86025 0.2132568359375 +86026 0.38885498046875 +86027 0.582794189453125 +86028 0.734039306640625 +86029 0.800140380859375 +86030 0.7783203125 +86031 0.6651611328125 +86032 0.45965576171875 +86033 0.199188232421875 +86034 -0.050689697265625 +86035 -0.23297119140625 +86036 -0.33013916015625 +86037 -0.368408203125 +86038 -0.378936767578125 +86039 -0.376983642578125 +86040 -0.37969970703125 +86041 -0.391510009765625 +86042 -0.385345458984375 +86043 -0.3419189453125 +86044 -0.28289794921875 +86045 -0.251617431640625 +86046 -0.266143798828125 +86047 -0.273345947265625 +86048 -0.216796875 +86049 -0.128265380859375 +86050 -0.068145751953125 +86051 -0.0430908203125 +86052 -0.024444580078125 +86053 0.020721435546875 +86054 0.124481201171875 +86055 0.25787353515625 +86056 0.379119873046875 +86057 0.47991943359375 +86058 0.5281982421875 +86059 0.511138916015625 +86060 0.456207275390625 +86061 0.407470703125 +86062 0.383758544921875 +86063 0.35687255859375 +86064 0.31182861328125 +86065 0.250885009765625 +86066 0.1654052734375 +86067 0.035247802734375 +86068 -0.142059326171875 +86069 -0.33563232421875 +86070 -0.5345458984375 +86071 -0.72186279296875 +86072 -0.836669921875 +86073 -0.8326416015625 +86074 -0.7296142578125 +86075 -0.582550048828125 +86076 -0.440093994140625 +86077 -0.324310302734375 +86078 -0.20147705078125 +86079 -0.044647216796875 +86080 0.103973388671875 +86081 0.202392578125 +86082 0.264495849609375 +86083 0.338897705078125 +86084 0.443817138671875 +86085 0.545074462890625 +86086 0.6173095703125 +86087 0.6524658203125 +86088 0.66339111328125 +86089 0.6561279296875 +86090 0.606781005859375 +86091 0.501190185546875 +86092 0.352783203125 +86093 0.176544189453125 +86094 -0.034820556640625 +86095 -0.258209228515625 +86096 -0.44244384765625 +86097 -0.5753173828125 +86098 -0.65203857421875 +86099 -0.641632080078125 +86100 -0.562164306640625 +86101 -0.458038330078125 +86102 -0.350555419921875 +86103 -0.260528564453125 +86104 -0.192108154296875 +86105 -0.141937255859375 +86106 -0.1021728515625 +86107 -0.062896728515625 +86108 -0.011932373046875 +86109 0.062835693359375 +86110 0.148712158203125 +86111 0.241729736328125 +86112 0.34912109375 +86113 0.457305908203125 +86114 0.54388427734375 +86115 0.5728759765625 +86116 0.506591796875 +86117 0.351226806640625 +86118 0.146514892578125 +86119 -0.05523681640625 +86120 -0.21624755859375 +86121 -0.334930419921875 +86122 -0.402984619140625 +86123 -0.4412841796875 +86124 -0.49578857421875 +86125 -0.5601806640625 +86126 -0.600738525390625 +86127 -0.584228515625 +86128 -0.47930908203125 +86129 -0.27935791015625 +86130 -0.0089111328125 +86131 0.268798828125 +86132 0.482818603515625 +86133 0.60369873046875 +86134 0.650421142578125 +86135 0.66400146484375 +86136 0.6414794921875 +86137 0.572540283203125 +86138 0.498138427734375 +86139 0.439453125 +86140 0.375518798828125 +86141 0.274505615234375 +86142 0.1087646484375 +86143 -0.099395751953125 +86144 -0.3182373046875 +86145 -0.5489501953125 +86146 -0.7738037109375 +86147 -0.86383056640625 +86148 -0.870391845703125 +86149 -0.86895751953125 +86150 -0.861053466796875 +86151 -0.765869140625 +86152 -0.5301513671875 +86153 -0.214691162109375 +86154 0.137359619140625 +86155 0.474822998046875 +86156 0.76239013671875 +86157 0.867462158203125 +86158 0.870361328125 +86159 0.86480712890625 +86160 0.831817626953125 +86161 0.677581787109375 +86162 0.495880126953125 +86163 0.30767822265625 +86164 0.116180419921875 +86165 -0.110748291015625 +86166 -0.381805419921875 +86167 -0.6572265625 +86168 -0.857421875 +86169 -0.870391845703125 +86170 -0.870391845703125 +86171 -0.86444091796875 +86172 -0.85723876953125 +86173 -0.790008544921875 +86174 -0.62847900390625 +86175 -0.3956298828125 +86176 -0.126708984375 +86177 0.150115966796875 +86178 0.424041748046875 +86179 0.670623779296875 +86180 0.854522705078125 +86181 0.866485595703125 +86182 0.86920166015625 +86183 0.8653564453125 +86184 0.857147216796875 +86185 0.766845703125 +86186 0.628509521484375 +86187 0.462127685546875 +86188 0.297210693359375 +86189 0.14862060546875 +86190 -0.00537109375 +86191 -0.15753173828125 +86192 -0.31304931640625 +86193 -0.48876953125 +86194 -0.6416015625 +86195 -0.751373291015625 +86196 -0.84619140625 +86197 -0.861297607421875 +86198 -0.863250732421875 +86199 -0.856597900390625 +86200 -0.7498779296875 +86201 -0.624542236328125 +86202 -0.47808837890625 +86203 -0.253387451171875 +86204 0.003692626953125 +86205 0.2257080078125 +86206 0.427154541015625 +86207 0.643218994140625 +86208 0.855926513671875 +86209 0.870361328125 +86210 0.870361328125 +86211 0.862762451171875 +86212 0.79669189453125 +86213 0.595794677734375 +86214 0.362152099609375 +86215 0.1270751953125 +86216 -0.086944580078125 +86217 -0.2784423828125 +86218 -0.484832763671875 +86219 -0.729583740234375 +86220 -0.86688232421875 +86221 -0.870391845703125 +86222 -0.86859130859375 +86223 -0.86279296875 +86224 -0.817962646484375 +86225 -0.6116943359375 +86226 -0.3128662109375 +86227 0.039398193359375 +86228 0.422821044921875 +86229 0.805145263671875 +86230 0.870361328125 +86231 0.870361328125 +86232 0.860015869140625 +86233 0.727935791015625 +86234 0.48114013671875 +86235 0.2059326171875 +86236 -0.06103515625 +86237 -0.29913330078125 +86238 -0.516204833984375 +86239 -0.7252197265625 +86240 -0.85980224609375 +86241 -0.870391845703125 +86242 -0.870391845703125 +86243 -0.858062744140625 +86244 -0.673004150390625 +86245 -0.42694091796875 +86246 -0.2100830078125 +86247 -0.0362548828125 +86248 0.10943603515625 +86249 0.23516845703125 +86250 0.373687744140625 +86251 0.517791748046875 +86252 0.602783203125 +86253 0.635711669921875 +86254 0.655181884765625 +86255 0.65948486328125 +86256 0.651275634765625 +86257 0.61846923828125 +86258 0.53753662109375 +86259 0.404144287109375 +86260 0.22186279296875 +86261 0.003997802734375 +86262 -0.22100830078125 +86263 -0.42449951171875 +86264 -0.579833984375 +86265 -0.641876220703125 +86266 -0.6177978515625 +86267 -0.575531005859375 +86268 -0.526336669921875 +86269 -0.42645263671875 +86270 -0.2581787109375 +86271 -0.068695068359375 +86272 0.09222412109375 +86273 0.232147216796875 +86274 0.3509521484375 +86275 0.410064697265625 +86276 0.372955322265625 +86277 0.2554931640625 +86278 0.10711669921875 +86279 -0.052886962890625 +86280 -0.186279296875 +86281 -0.23291015625 +86282 -0.209442138671875 +86283 -0.174163818359375 +86284 -0.126739501953125 +86285 -0.048126220703125 +86286 0.0426025390625 +86287 0.10748291015625 +86288 0.1409912109375 +86289 0.19708251953125 +86290 0.273651123046875 +86291 0.31768798828125 +86292 0.341094970703125 +86293 0.368011474609375 +86294 0.37249755859375 +86295 0.30072021484375 +86296 0.1517333984375 +86297 -0.01470947265625 +86298 -0.1883544921875 +86299 -0.372711181640625 +86300 -0.51397705078125 +86301 -0.57177734375 +86302 -0.53948974609375 +86303 -0.43511962890625 +86304 -0.2962646484375 +86305 -0.161102294921875 +86306 -0.0435791015625 +86307 0.060394287109375 +86308 0.13665771484375 +86309 0.170135498046875 +86310 0.16552734375 +86311 0.15728759765625 +86312 0.150787353515625 +86313 0.12200927734375 +86314 0.080108642578125 +86315 0.05126953125 +86316 0.062896728515625 +86317 0.09271240234375 +86318 0.092987060546875 +86319 0.07855224609375 +86320 0.06427001953125 +86321 0.0347900390625 +86322 -0.01171875 +86323 -0.056060791015625 +86324 -0.055511474609375 +86325 -0.010467529296875 +86326 0.02508544921875 +86327 0.025665283203125 +86328 0.017333984375 +86329 0.00189208984375 +86330 -0.03173828125 +86331 -0.071502685546875 +86332 -0.13543701171875 +86333 -0.219970703125 +86334 -0.300506591796875 +86335 -0.376312255859375 +86336 -0.416107177734375 +86337 -0.371124267578125 +86338 -0.242279052734375 +86339 -0.069732666015625 +86340 0.125640869140625 +86341 0.31268310546875 +86342 0.45501708984375 +86343 0.554779052734375 +86344 0.61065673828125 +86345 0.610931396484375 +86346 0.531463623046875 +86347 0.3883056640625 +86348 0.23468017578125 +86349 0.095245361328125 +86350 -0.00396728515625 +86351 -0.04852294921875 +86352 -0.055145263671875 +86353 -0.0758056640625 +86354 -0.138702392578125 +86355 -0.209197998046875 +86356 -0.289031982421875 +86357 -0.37884521484375 +86358 -0.456329345703125 +86359 -0.51641845703125 +86360 -0.519287109375 +86361 -0.458251953125 +86362 -0.384796142578125 +86363 -0.323699951171875 +86364 -0.269287109375 +86365 -0.1951904296875 +86366 -0.100006103515625 +86367 -0.01055908203125 +86368 0.1033935546875 +86369 0.24908447265625 +86370 0.373199462890625 +86371 0.45806884765625 +86372 0.511474609375 +86373 0.565399169921875 +86374 0.61138916015625 +86375 0.5897216796875 +86376 0.4906005859375 +86377 0.33148193359375 +86378 0.147796630859375 +86379 -0.01873779296875 +86380 -0.140289306640625 +86381 -0.191986083984375 +86382 -0.184295654296875 +86383 -0.161834716796875 +86384 -0.166595458984375 +86385 -0.19390869140625 +86386 -0.22442626953125 +86387 -0.279754638671875 +86388 -0.3389892578125 +86389 -0.3543701171875 +86390 -0.348175048828125 +86391 -0.32598876953125 +86392 -0.2581787109375 +86393 -0.139801025390625 +86394 0.014617919921875 +86395 0.144378662109375 +86396 0.221038818359375 +86397 0.27069091796875 +86398 0.294036865234375 +86399 0.311767578125 +86400 0.339141845703125 +86401 0.360260009765625 +86402 0.360504150390625 +86403 0.308380126953125 +86404 0.18170166015625 +86405 0.0047607421875 +86406 -0.17559814453125 +86407 -0.3143310546875 +86408 -0.36785888671875 +86409 -0.36248779296875 +86410 -0.343536376953125 +86411 -0.3018798828125 +86412 -0.231414794921875 +86413 -0.117645263671875 +86414 0.007049560546875 +86415 0.087982177734375 +86416 0.13946533203125 +86417 0.17425537109375 +86418 0.188201904296875 +86419 0.171234130859375 +86420 0.118438720703125 +86421 0.05706787109375 +86422 -0.010711669921875 +86423 -0.0914306640625 +86424 -0.162322998046875 +86425 -0.194549560546875 +86426 -0.1492919921875 +86427 -0.02166748046875 +86428 0.124053955078125 +86429 0.211151123046875 +86430 0.240447998046875 +86431 0.242218017578125 +86432 0.2257080078125 +86433 0.194366455078125 +86434 0.115509033203125 +86435 0.0128173828125 +86436 -0.053802490234375 +86437 -0.110626220703125 +86438 -0.199493408203125 +86439 -0.29437255859375 +86440 -0.33221435546875 +86441 -0.27972412109375 +86442 -0.185333251953125 +86443 -0.128204345703125 +86444 -0.115692138671875 +86445 -0.116455078125 +86446 -0.105926513671875 +86447 -0.053955078125 +86448 0.048797607421875 +86449 0.157318115234375 +86450 0.212005615234375 +86451 0.218475341796875 +86452 0.23724365234375 +86453 0.30535888671875 +86454 0.38128662109375 +86455 0.404449462890625 +86456 0.3944091796875 +86457 0.3885498046875 +86458 0.362640380859375 +86459 0.27362060546875 +86460 0.11712646484375 +86461 -0.054901123046875 +86462 -0.19085693359375 +86463 -0.28570556640625 +86464 -0.339263916015625 +86465 -0.3775634765625 +86466 -0.445709228515625 +86467 -0.535064697265625 +86468 -0.629058837890625 +86469 -0.697601318359375 +86470 -0.70391845703125 +86471 -0.6424560546875 +86472 -0.491241455078125 +86473 -0.265716552734375 +86474 -0.023712158203125 +86475 0.201751708984375 +86476 0.375823974609375 +86477 0.485076904296875 +86478 0.56884765625 +86479 0.634765625 +86480 0.63763427734375 +86481 0.5660400390625 +86482 0.4720458984375 +86483 0.40692138671875 +86484 0.3778076171875 +86485 0.376953125 +86486 0.371978759765625 +86487 0.313140869140625 +86488 0.184417724609375 +86489 0.011199951171875 +86490 -0.171051025390625 +86491 -0.33740234375 +86492 -0.47198486328125 +86493 -0.560394287109375 +86494 -0.58056640625 +86495 -0.54754638671875 +86496 -0.508575439453125 +86497 -0.459503173828125 +86498 -0.394378662109375 +86499 -0.35260009765625 +86500 -0.31170654296875 +86501 -0.197418212890625 +86502 -0.007965087890625 +86503 0.207489013671875 +86504 0.409210205078125 +86505 0.57208251953125 +86506 0.66595458984375 +86507 0.65875244140625 +86508 0.56744384765625 +86509 0.431396484375 +86510 0.29443359375 +86511 0.182464599609375 +86512 0.06365966796875 +86513 -0.075958251953125 +86514 -0.189422607421875 +86515 -0.271942138671875 +86516 -0.342529296875 +86517 -0.364166259765625 +86518 -0.327239990234375 +86519 -0.2769775390625 +86520 -0.253692626953125 +86521 -0.24365234375 +86522 -0.1983642578125 +86523 -0.116241455078125 +86524 -0.036834716796875 +86525 0.034881591796875 +86526 0.09124755859375 +86527 0.10888671875 +86528 0.125518798828125 +86529 0.15771484375 +86530 0.17828369140625 +86531 0.17108154296875 +86532 0.129974365234375 +86533 0.082427978515625 +86534 0.027679443359375 +86535 -0.065643310546875 +86536 -0.15936279296875 +86537 -0.21307373046875 +86538 -0.234649658203125 +86539 -0.2001953125 +86540 -0.119171142578125 +86541 -0.024749755859375 +86542 0.085784912109375 +86543 0.178131103515625 +86544 0.215576171875 +86545 0.211456298828125 +86546 0.17523193359375 +86547 0.128753662109375 +86548 0.1019287109375 +86549 0.0743408203125 +86550 0.04327392578125 +86551 0.038177490234375 +86552 0.076263427734375 +86553 0.14105224609375 +86554 0.186431884765625 +86555 0.188812255859375 +86556 0.1390380859375 +86557 0.041778564453125 +86558 -0.079437255859375 +86559 -0.219390869140625 +86560 -0.367828369140625 +86561 -0.494873046875 +86562 -0.556243896484375 +86563 -0.508697509765625 +86564 -0.3756103515625 +86565 -0.218902587890625 +86566 -0.063751220703125 +86567 0.091552734375 +86568 0.23602294921875 +86569 0.342987060546875 +86570 0.39520263671875 +86571 0.389373779296875 +86572 0.324249267578125 +86573 0.224090576171875 +86574 0.124267578125 +86575 0.037078857421875 +86576 -0.010101318359375 +86577 -0.019439697265625 +86578 -0.022796630859375 +86579 -0.001556396484375 +86580 0.056304931640625 +86581 0.106719970703125 +86582 0.096893310546875 +86583 0.042694091796875 +86584 -0.018035888671875 +86585 -0.07586669921875 +86586 -0.11944580078125 +86587 -0.15972900390625 +86588 -0.202606201171875 +86589 -0.24859619140625 +86590 -0.30517578125 +86591 -0.36212158203125 +86592 -0.39141845703125 +86593 -0.35528564453125 +86594 -0.249969482421875 +86595 -0.092864990234375 +86596 0.08905029296875 +86597 0.2352294921875 +86598 0.318817138671875 +86599 0.358642578125 +86600 0.347747802734375 +86601 0.28564453125 +86602 0.223175048828125 +86603 0.196746826171875 +86604 0.179840087890625 +86605 0.155548095703125 +86606 0.151214599609375 +86607 0.156951904296875 +86608 0.13177490234375 +86609 0.100799560546875 +86610 0.087127685546875 +86611 0.05487060546875 +86612 -0.009002685546875 +86613 -0.10400390625 +86614 -0.229400634765625 +86615 -0.35552978515625 +86616 -0.441925048828125 +86617 -0.473846435546875 +86618 -0.464813232421875 +86619 -0.419097900390625 +86620 -0.334320068359375 +86621 -0.227935791015625 +86622 -0.12347412109375 +86623 -0.02764892578125 +86624 0.077667236328125 +86625 0.2132568359375 +86626 0.38885498046875 +86627 0.582794189453125 +86628 0.734039306640625 +86629 0.800140380859375 +86630 0.7783203125 +86631 0.6651611328125 +86632 0.45965576171875 +86633 0.199188232421875 +86634 -0.050689697265625 +86635 -0.23297119140625 +86636 -0.33013916015625 +86637 -0.368408203125 +86638 -0.378936767578125 +86639 -0.376983642578125 +86640 -0.37969970703125 +86641 -0.391510009765625 +86642 -0.385345458984375 +86643 -0.3419189453125 +86644 -0.28289794921875 +86645 -0.251617431640625 +86646 -0.266143798828125 +86647 -0.273345947265625 +86648 -0.216796875 +86649 -0.128265380859375 +86650 -0.068145751953125 +86651 -0.0430908203125 +86652 -0.024444580078125 +86653 0.020721435546875 +86654 0.124481201171875 +86655 0.25787353515625 +86656 0.379119873046875 +86657 0.47991943359375 +86658 0.5281982421875 +86659 0.511138916015625 +86660 0.456207275390625 +86661 0.407470703125 +86662 0.383758544921875 +86663 0.35687255859375 +86664 0.31182861328125 +86665 0.250885009765625 +86666 0.1654052734375 +86667 0.035247802734375 +86668 -0.142059326171875 +86669 -0.33563232421875 +86670 -0.5345458984375 +86671 -0.72186279296875 +86672 -0.836669921875 +86673 -0.8326416015625 +86674 -0.7296142578125 +86675 -0.582550048828125 +86676 -0.440093994140625 +86677 -0.324310302734375 +86678 -0.20147705078125 +86679 -0.044647216796875 +86680 0.103973388671875 +86681 0.202392578125 +86682 0.264495849609375 +86683 0.338897705078125 +86684 0.443817138671875 +86685 0.545074462890625 +86686 0.6173095703125 +86687 0.6524658203125 +86688 0.66339111328125 +86689 0.6561279296875 +86690 0.606781005859375 +86691 0.501190185546875 +86692 0.352783203125 +86693 0.176544189453125 +86694 -0.034820556640625 +86695 -0.258209228515625 +86696 -0.44244384765625 +86697 -0.5753173828125 +86698 -0.65203857421875 +86699 -0.641632080078125 +86700 -0.562164306640625 +86701 -0.458038330078125 +86702 -0.350555419921875 +86703 -0.260528564453125 +86704 -0.192108154296875 +86705 -0.141937255859375 +86706 -0.1021728515625 +86707 -0.062896728515625 +86708 -0.011932373046875 +86709 0.062835693359375 +86710 0.148712158203125 +86711 0.241729736328125 +86712 0.34912109375 +86713 0.457305908203125 +86714 0.54388427734375 +86715 0.5728759765625 +86716 0.506591796875 +86717 0.351226806640625 +86718 0.146514892578125 +86719 -0.05523681640625 +86720 -0.21624755859375 +86721 -0.334930419921875 +86722 -0.402984619140625 +86723 -0.4412841796875 +86724 -0.49578857421875 +86725 -0.5601806640625 +86726 -0.600738525390625 +86727 -0.584228515625 +86728 -0.47930908203125 +86729 -0.27935791015625 +86730 -0.0089111328125 +86731 0.268798828125 +86732 0.482818603515625 +86733 0.60369873046875 +86734 0.650421142578125 +86735 0.66400146484375 +86736 0.6414794921875 +86737 0.572540283203125 +86738 0.498138427734375 +86739 0.439453125 +86740 0.375518798828125 +86741 0.274505615234375 +86742 0.1087646484375 +86743 -0.099395751953125 +86744 -0.3182373046875 +86745 -0.5489501953125 +86746 -0.7738037109375 +86747 -0.86383056640625 +86748 -0.870391845703125 +86749 -0.86895751953125 +86750 -0.861053466796875 +86751 -0.765869140625 +86752 -0.5301513671875 +86753 -0.214691162109375 +86754 0.137359619140625 +86755 0.474822998046875 +86756 0.76239013671875 +86757 0.867462158203125 +86758 0.870361328125 +86759 0.86480712890625 +86760 0.831817626953125 +86761 0.677581787109375 +86762 0.495880126953125 +86763 0.30767822265625 +86764 0.116180419921875 +86765 -0.110748291015625 +86766 -0.381805419921875 +86767 -0.6572265625 +86768 -0.857421875 +86769 -0.870391845703125 +86770 -0.870391845703125 +86771 -0.86444091796875 +86772 -0.85723876953125 +86773 -0.790008544921875 +86774 -0.62847900390625 +86775 -0.3956298828125 +86776 -0.126708984375 +86777 0.150115966796875 +86778 0.424041748046875 +86779 0.670623779296875 +86780 0.854522705078125 +86781 0.866485595703125 +86782 0.86920166015625 +86783 0.8653564453125 +86784 0.857147216796875 +86785 0.766845703125 +86786 0.628509521484375 +86787 0.462127685546875 +86788 0.297210693359375 +86789 0.14862060546875 +86790 -0.00537109375 +86791 -0.15753173828125 +86792 -0.31304931640625 +86793 -0.48876953125 +86794 -0.6416015625 +86795 -0.751373291015625 +86796 -0.84619140625 +86797 -0.861297607421875 +86798 -0.863250732421875 +86799 -0.856597900390625 +86800 -0.7498779296875 +86801 -0.624542236328125 +86802 -0.47808837890625 +86803 -0.253387451171875 +86804 0.003692626953125 +86805 0.2257080078125 +86806 0.427154541015625 +86807 0.643218994140625 +86808 0.855926513671875 +86809 0.870361328125 +86810 0.870361328125 +86811 0.862762451171875 +86812 0.79669189453125 +86813 0.595794677734375 +86814 0.362152099609375 +86815 0.1270751953125 +86816 -0.086944580078125 +86817 -0.2784423828125 +86818 -0.484832763671875 +86819 -0.729583740234375 +86820 -0.86688232421875 +86821 -0.870391845703125 +86822 -0.86859130859375 +86823 -0.86279296875 +86824 -0.817962646484375 +86825 -0.6116943359375 +86826 -0.3128662109375 +86827 0.039398193359375 +86828 0.422821044921875 +86829 0.805145263671875 +86830 0.870361328125 +86831 0.870361328125 +86832 0.860015869140625 +86833 0.727935791015625 +86834 0.48114013671875 +86835 0.2059326171875 +86836 -0.06103515625 +86837 -0.29913330078125 +86838 -0.516204833984375 +86839 -0.7252197265625 +86840 -0.85980224609375 +86841 -0.870391845703125 +86842 -0.870391845703125 +86843 -0.858062744140625 +86844 -0.673004150390625 +86845 -0.42694091796875 +86846 -0.2100830078125 +86847 -0.0362548828125 +86848 0.10943603515625 +86849 0.23516845703125 +86850 0.373687744140625 +86851 0.517791748046875 +86852 0.602783203125 +86853 0.635711669921875 +86854 0.655181884765625 +86855 0.65948486328125 +86856 0.651275634765625 +86857 0.61846923828125 +86858 0.53753662109375 +86859 0.404144287109375 +86860 0.22186279296875 +86861 0.003997802734375 +86862 -0.22100830078125 +86863 -0.42449951171875 +86864 -0.579833984375 +86865 -0.641876220703125 +86866 -0.6177978515625 +86867 -0.575531005859375 +86868 -0.526336669921875 +86869 -0.42645263671875 +86870 -0.2581787109375 +86871 -0.068695068359375 +86872 0.09222412109375 +86873 0.232147216796875 +86874 0.3509521484375 +86875 0.410064697265625 +86876 0.372955322265625 +86877 0.2554931640625 +86878 0.10711669921875 +86879 -0.052886962890625 +86880 -0.186279296875 +86881 -0.23291015625 +86882 -0.209442138671875 +86883 -0.174163818359375 +86884 -0.126739501953125 +86885 -0.048126220703125 +86886 0.0426025390625 +86887 0.10748291015625 +86888 0.1409912109375 +86889 0.19708251953125 +86890 0.273651123046875 +86891 0.31768798828125 +86892 0.341094970703125 +86893 0.368011474609375 +86894 0.37249755859375 +86895 0.30072021484375 +86896 0.1517333984375 +86897 -0.01470947265625 +86898 -0.1883544921875 +86899 -0.372711181640625 +86900 -0.51397705078125 +86901 -0.57177734375 +86902 -0.53948974609375 +86903 -0.43511962890625 +86904 -0.2962646484375 +86905 -0.161102294921875 +86906 -0.0435791015625 +86907 0.060394287109375 +86908 0.13665771484375 +86909 0.170135498046875 +86910 0.16552734375 +86911 0.15728759765625 +86912 0.150787353515625 +86913 0.12200927734375 +86914 0.080108642578125 +86915 0.05126953125 +86916 0.062896728515625 +86917 0.09271240234375 +86918 0.092987060546875 +86919 0.07855224609375 +86920 0.06427001953125 +86921 0.0347900390625 +86922 -0.01171875 +86923 -0.056060791015625 +86924 -0.055511474609375 +86925 -0.010467529296875 +86926 0.02508544921875 +86927 0.025665283203125 +86928 0.017333984375 +86929 0.00189208984375 +86930 -0.03173828125 +86931 -0.071502685546875 +86932 -0.13543701171875 +86933 -0.219970703125 +86934 -0.300506591796875 +86935 -0.376312255859375 +86936 -0.416107177734375 +86937 -0.371124267578125 +86938 -0.242279052734375 +86939 -0.069732666015625 +86940 0.125640869140625 +86941 0.31268310546875 +86942 0.45501708984375 +86943 0.554779052734375 +86944 0.61065673828125 +86945 0.610931396484375 +86946 0.531463623046875 +86947 0.3883056640625 +86948 0.23468017578125 +86949 0.095245361328125 +86950 -0.00396728515625 +86951 -0.04852294921875 +86952 -0.055145263671875 +86953 -0.0758056640625 +86954 -0.138702392578125 +86955 -0.209197998046875 +86956 -0.289031982421875 +86957 -0.37884521484375 +86958 -0.456329345703125 +86959 -0.51641845703125 +86960 -0.519287109375 +86961 -0.458251953125 +86962 -0.384796142578125 +86963 -0.323699951171875 +86964 -0.269287109375 +86965 -0.1951904296875 +86966 -0.100006103515625 +86967 -0.01055908203125 +86968 0.1033935546875 +86969 0.24908447265625 +86970 0.373199462890625 +86971 0.45806884765625 +86972 0.511474609375 +86973 0.565399169921875 +86974 0.61138916015625 +86975 0.5897216796875 +86976 0.4906005859375 +86977 0.33148193359375 +86978 0.147796630859375 +86979 -0.01873779296875 +86980 -0.140289306640625 +86981 -0.191986083984375 +86982 -0.184295654296875 +86983 -0.161834716796875 +86984 -0.166595458984375 +86985 -0.19390869140625 +86986 -0.22442626953125 +86987 -0.279754638671875 +86988 -0.3389892578125 +86989 -0.3543701171875 +86990 -0.348175048828125 +86991 -0.32598876953125 +86992 -0.2581787109375 +86993 -0.139801025390625 +86994 0.014617919921875 +86995 0.144378662109375 +86996 0.221038818359375 +86997 0.27069091796875 +86998 0.294036865234375 +86999 0.311767578125 +87000 0.339141845703125 +87001 0.360260009765625 +87002 0.360504150390625 +87003 0.308380126953125 +87004 0.18170166015625 +87005 0.0047607421875 +87006 -0.17559814453125 +87007 -0.3143310546875 +87008 -0.36785888671875 +87009 -0.36248779296875 +87010 -0.343536376953125 +87011 -0.3018798828125 +87012 -0.231414794921875 +87013 -0.117645263671875 +87014 0.007049560546875 +87015 0.087982177734375 +87016 0.13946533203125 +87017 0.17425537109375 +87018 0.188201904296875 +87019 0.171234130859375 +87020 0.118438720703125 +87021 0.05706787109375 +87022 -0.010711669921875 +87023 -0.0914306640625 +87024 -0.162322998046875 +87025 -0.194549560546875 +87026 -0.1492919921875 +87027 -0.02166748046875 +87028 0.124053955078125 +87029 0.211151123046875 +87030 0.240447998046875 +87031 0.242218017578125 +87032 0.2257080078125 +87033 0.194366455078125 +87034 0.115509033203125 +87035 0.0128173828125 +87036 -0.053802490234375 +87037 -0.110626220703125 +87038 -0.199493408203125 +87039 -0.29437255859375 +87040 -0.33221435546875 +87041 -0.27972412109375 +87042 -0.185333251953125 +87043 -0.128204345703125 +87044 -0.115692138671875 +87045 -0.116455078125 +87046 -0.105926513671875 +87047 -0.053955078125 +87048 0.048797607421875 +87049 0.157318115234375 +87050 0.212005615234375 +87051 0.218475341796875 +87052 0.23724365234375 +87053 0.30535888671875 +87054 0.38128662109375 +87055 0.404449462890625 +87056 0.3944091796875 +87057 0.3885498046875 +87058 0.362640380859375 +87059 0.27362060546875 +87060 0.11712646484375 +87061 -0.054901123046875 +87062 -0.19085693359375 +87063 -0.28570556640625 +87064 -0.339263916015625 +87065 -0.3775634765625 +87066 -0.445709228515625 +87067 -0.535064697265625 +87068 -0.629058837890625 +87069 -0.697601318359375 +87070 -0.70391845703125 +87071 -0.6424560546875 +87072 -0.491241455078125 +87073 -0.265716552734375 +87074 -0.023712158203125 +87075 0.201751708984375 +87076 0.375823974609375 +87077 0.485076904296875 +87078 0.56884765625 +87079 0.634765625 +87080 0.63763427734375 +87081 0.5660400390625 +87082 0.4720458984375 +87083 0.40692138671875 +87084 0.3778076171875 +87085 0.376953125 +87086 0.371978759765625 +87087 0.313140869140625 +87088 0.184417724609375 +87089 0.011199951171875 +87090 -0.171051025390625 +87091 -0.33740234375 +87092 -0.47198486328125 +87093 -0.560394287109375 +87094 -0.58056640625 +87095 -0.54754638671875 +87096 -0.508575439453125 +87097 -0.459503173828125 +87098 -0.394378662109375 +87099 -0.35260009765625 +87100 -0.31170654296875 +87101 -0.197418212890625 +87102 -0.007965087890625 +87103 0.207489013671875 +87104 0.409210205078125 +87105 0.57208251953125 +87106 0.66595458984375 +87107 0.65875244140625 +87108 0.56744384765625 +87109 0.431396484375 +87110 0.29443359375 +87111 0.182464599609375 +87112 0.06365966796875 +87113 -0.075958251953125 +87114 -0.189422607421875 +87115 -0.271942138671875 +87116 -0.342529296875 +87117 -0.364166259765625 +87118 -0.327239990234375 +87119 -0.2769775390625 +87120 -0.253692626953125 +87121 -0.24365234375 +87122 -0.1983642578125 +87123 -0.116241455078125 +87124 -0.036834716796875 +87125 0.034881591796875 +87126 0.09124755859375 +87127 0.10888671875 +87128 0.125518798828125 +87129 0.15771484375 +87130 0.17828369140625 +87131 0.17108154296875 +87132 0.129974365234375 +87133 0.082427978515625 +87134 0.027679443359375 +87135 -0.065643310546875 +87136 -0.15936279296875 +87137 -0.21307373046875 +87138 -0.234649658203125 +87139 -0.2001953125 +87140 -0.119171142578125 +87141 -0.024749755859375 +87142 0.085784912109375 +87143 0.178131103515625 +87144 0.215576171875 +87145 0.211456298828125 +87146 0.17523193359375 +87147 0.128753662109375 +87148 0.1019287109375 +87149 0.0743408203125 +87150 0.04327392578125 +87151 0.038177490234375 +87152 0.076263427734375 +87153 0.14105224609375 +87154 0.186431884765625 +87155 0.188812255859375 +87156 0.1390380859375 +87157 0.041778564453125 +87158 -0.079437255859375 +87159 -0.219390869140625 +87160 -0.367828369140625 +87161 -0.494873046875 +87162 -0.556243896484375 +87163 -0.508697509765625 +87164 -0.3756103515625 +87165 -0.218902587890625 +87166 -0.063751220703125 +87167 0.091552734375 +87168 0.23602294921875 +87169 0.342987060546875 +87170 0.39520263671875 +87171 0.389373779296875 +87172 0.324249267578125 +87173 0.224090576171875 +87174 0.124267578125 +87175 0.037078857421875 +87176 -0.010101318359375 +87177 -0.019439697265625 +87178 -0.022796630859375 +87179 -0.001556396484375 +87180 0.056304931640625 +87181 0.106719970703125 +87182 0.096893310546875 +87183 0.042694091796875 +87184 -0.018035888671875 +87185 -0.07586669921875 +87186 -0.11944580078125 +87187 -0.15972900390625 +87188 -0.202606201171875 +87189 -0.24859619140625 +87190 -0.30517578125 +87191 -0.36212158203125 +87192 -0.39141845703125 +87193 -0.35528564453125 +87194 -0.249969482421875 +87195 -0.092864990234375 +87196 0.08905029296875 +87197 0.2352294921875 +87198 0.318817138671875 +87199 0.358642578125 +87200 0.347747802734375 +87201 0.28564453125 +87202 0.223175048828125 +87203 0.196746826171875 +87204 0.179840087890625 +87205 0.155548095703125 +87206 0.151214599609375 +87207 0.156951904296875 +87208 0.13177490234375 +87209 0.100799560546875 +87210 0.087127685546875 +87211 0.05487060546875 +87212 -0.009002685546875 +87213 -0.10400390625 +87214 -0.229400634765625 +87215 -0.35552978515625 +87216 -0.441925048828125 +87217 -0.473846435546875 +87218 -0.464813232421875 +87219 -0.419097900390625 +87220 -0.334320068359375 +87221 -0.227935791015625 +87222 -0.12347412109375 +87223 -0.02764892578125 +87224 0.077667236328125 +87225 0.2132568359375 +87226 0.38885498046875 +87227 0.582794189453125 +87228 0.734039306640625 +87229 0.800140380859375 +87230 0.7783203125 +87231 0.6651611328125 +87232 0.45965576171875 +87233 0.199188232421875 +87234 -0.050689697265625 +87235 -0.23297119140625 +87236 -0.33013916015625 +87237 -0.368408203125 +87238 -0.378936767578125 +87239 -0.376983642578125 +87240 -0.37969970703125 +87241 -0.391510009765625 +87242 -0.385345458984375 +87243 -0.3419189453125 +87244 -0.28289794921875 +87245 -0.251617431640625 +87246 -0.266143798828125 +87247 -0.273345947265625 +87248 -0.216796875 +87249 -0.128265380859375 +87250 -0.068145751953125 +87251 -0.0430908203125 +87252 -0.024444580078125 +87253 0.020721435546875 +87254 0.124481201171875 +87255 0.25787353515625 +87256 0.379119873046875 +87257 0.47991943359375 +87258 0.5281982421875 +87259 0.511138916015625 +87260 0.456207275390625 +87261 0.407470703125 +87262 0.383758544921875 +87263 0.35687255859375 +87264 0.31182861328125 +87265 0.250885009765625 +87266 0.1654052734375 +87267 0.035247802734375 +87268 -0.142059326171875 +87269 -0.33563232421875 +87270 -0.5345458984375 +87271 -0.72186279296875 +87272 -0.836669921875 +87273 -0.8326416015625 +87274 -0.7296142578125 +87275 -0.582550048828125 +87276 -0.440093994140625 +87277 -0.324310302734375 +87278 -0.20147705078125 +87279 -0.044647216796875 +87280 0.103973388671875 +87281 0.202392578125 +87282 0.264495849609375 +87283 0.338897705078125 +87284 0.443817138671875 +87285 0.545074462890625 +87286 0.6173095703125 +87287 0.6524658203125 +87288 0.66339111328125 +87289 0.6561279296875 +87290 0.606781005859375 +87291 0.501190185546875 +87292 0.352783203125 +87293 0.176544189453125 +87294 -0.034820556640625 +87295 -0.258209228515625 +87296 -0.44244384765625 +87297 -0.5753173828125 +87298 -0.65203857421875 +87299 -0.641632080078125 +87300 -0.562164306640625 +87301 -0.458038330078125 +87302 -0.350555419921875 +87303 -0.260528564453125 +87304 -0.192108154296875 +87305 -0.141937255859375 +87306 -0.1021728515625 +87307 -0.062896728515625 +87308 -0.011932373046875 +87309 0.062835693359375 +87310 0.148712158203125 +87311 0.241729736328125 +87312 0.34912109375 +87313 0.457305908203125 +87314 0.54388427734375 +87315 0.5728759765625 +87316 0.506591796875 +87317 0.351226806640625 +87318 0.146514892578125 +87319 -0.05523681640625 +87320 -0.21624755859375 +87321 -0.334930419921875 +87322 -0.402984619140625 +87323 -0.4412841796875 +87324 -0.49578857421875 +87325 -0.5601806640625 +87326 -0.600738525390625 +87327 -0.584228515625 +87328 -0.47930908203125 +87329 -0.27935791015625 +87330 -0.0089111328125 +87331 0.268798828125 +87332 0.482818603515625 +87333 0.60369873046875 +87334 0.650421142578125 +87335 0.66400146484375 +87336 0.6414794921875 +87337 0.572540283203125 +87338 0.498138427734375 +87339 0.439453125 +87340 0.375518798828125 +87341 0.274505615234375 +87342 0.1087646484375 +87343 -0.099395751953125 +87344 -0.3182373046875 +87345 -0.5489501953125 +87346 -0.7738037109375 +87347 -0.86383056640625 +87348 -0.870391845703125 +87349 -0.86895751953125 +87350 -0.861053466796875 +87351 -0.765869140625 +87352 -0.5301513671875 +87353 -0.214691162109375 +87354 0.137359619140625 +87355 0.474822998046875 +87356 0.76239013671875 +87357 0.867462158203125 +87358 0.870361328125 +87359 0.86480712890625 +87360 0.831817626953125 +87361 0.677581787109375 +87362 0.495880126953125 +87363 0.30767822265625 +87364 0.116180419921875 +87365 -0.110748291015625 +87366 -0.381805419921875 +87367 -0.6572265625 +87368 -0.857421875 +87369 -0.870391845703125 +87370 -0.870391845703125 +87371 -0.86444091796875 +87372 -0.85723876953125 +87373 -0.790008544921875 +87374 -0.62847900390625 +87375 -0.3956298828125 +87376 -0.126708984375 +87377 0.150115966796875 +87378 0.424041748046875 +87379 0.670623779296875 +87380 0.854522705078125 +87381 0.866485595703125 +87382 0.86920166015625 +87383 0.8653564453125 +87384 0.857147216796875 +87385 0.766845703125 +87386 0.628509521484375 +87387 0.462127685546875 +87388 0.297210693359375 +87389 0.14862060546875 +87390 -0.00537109375 +87391 -0.15753173828125 +87392 -0.31304931640625 +87393 -0.48876953125 +87394 -0.6416015625 +87395 -0.751373291015625 +87396 -0.84619140625 +87397 -0.861297607421875 +87398 -0.863250732421875 +87399 -0.856597900390625 +87400 -0.7498779296875 +87401 -0.624542236328125 +87402 -0.47808837890625 +87403 -0.253387451171875 +87404 0.003692626953125 +87405 0.2257080078125 +87406 0.427154541015625 +87407 0.643218994140625 +87408 0.855926513671875 +87409 0.870361328125 +87410 0.870361328125 +87411 0.862762451171875 +87412 0.79669189453125 +87413 0.595794677734375 +87414 0.362152099609375 +87415 0.1270751953125 +87416 -0.086944580078125 +87417 -0.2784423828125 +87418 -0.484832763671875 +87419 -0.729583740234375 +87420 -0.86688232421875 +87421 -0.870391845703125 +87422 -0.86859130859375 +87423 -0.86279296875 +87424 -0.817962646484375 +87425 -0.6116943359375 +87426 -0.3128662109375 +87427 0.039398193359375 +87428 0.422821044921875 +87429 0.805145263671875 +87430 0.870361328125 +87431 0.870361328125 +87432 0.860015869140625 +87433 0.727935791015625 +87434 0.48114013671875 +87435 0.2059326171875 +87436 -0.06103515625 +87437 -0.29913330078125 +87438 -0.516204833984375 +87439 -0.7252197265625 +87440 -0.85980224609375 +87441 -0.870391845703125 +87442 -0.870391845703125 +87443 -0.858062744140625 +87444 -0.673004150390625 +87445 -0.42694091796875 +87446 -0.2100830078125 +87447 -0.0362548828125 +87448 0.10943603515625 +87449 0.23516845703125 +87450 0.373687744140625 +87451 0.517791748046875 +87452 0.602783203125 +87453 0.635711669921875 +87454 0.655181884765625 +87455 0.65948486328125 +87456 0.651275634765625 +87457 0.61846923828125 +87458 0.53753662109375 +87459 0.404144287109375 +87460 0.22186279296875 +87461 0.003997802734375 +87462 -0.22100830078125 +87463 -0.42449951171875 +87464 -0.579833984375 +87465 -0.641876220703125 +87466 -0.6177978515625 +87467 -0.575531005859375 +87468 -0.526336669921875 +87469 -0.42645263671875 +87470 -0.2581787109375 +87471 -0.068695068359375 +87472 0.09222412109375 +87473 0.232147216796875 +87474 0.3509521484375 +87475 0.410064697265625 +87476 0.372955322265625 +87477 0.2554931640625 +87478 0.10711669921875 +87479 -0.052886962890625 +87480 -0.186279296875 +87481 -0.23291015625 +87482 -0.209442138671875 +87483 -0.174163818359375 +87484 -0.126739501953125 +87485 -0.048126220703125 +87486 0.0426025390625 +87487 0.10748291015625 +87488 0.1409912109375 +87489 0.19708251953125 +87490 0.273651123046875 +87491 0.31768798828125 +87492 0.341094970703125 +87493 0.368011474609375 +87494 0.37249755859375 +87495 0.30072021484375 +87496 0.1517333984375 +87497 -0.01470947265625 +87498 -0.1883544921875 +87499 -0.372711181640625 +87500 -0.51397705078125 +87501 -0.57177734375 +87502 -0.53948974609375 +87503 -0.43511962890625 +87504 -0.2962646484375 +87505 -0.161102294921875 +87506 -0.0435791015625 +87507 0.060394287109375 +87508 0.13665771484375 +87509 0.170135498046875 +87510 0.16552734375 +87511 0.15728759765625 +87512 0.150787353515625 +87513 0.12200927734375 +87514 0.080108642578125 +87515 0.05126953125 +87516 0.062896728515625 +87517 0.09271240234375 +87518 0.092987060546875 +87519 0.07855224609375 +87520 0.06427001953125 +87521 0.0347900390625 +87522 -0.01171875 +87523 -0.056060791015625 +87524 -0.055511474609375 +87525 -0.010467529296875 +87526 0.02508544921875 +87527 0.025665283203125 +87528 0.017333984375 +87529 0.00189208984375 +87530 -0.03173828125 +87531 -0.071502685546875 +87532 -0.13543701171875 +87533 -0.219970703125 +87534 -0.300506591796875 +87535 -0.376312255859375 +87536 -0.416107177734375 +87537 -0.371124267578125 +87538 -0.242279052734375 +87539 -0.069732666015625 +87540 0.125640869140625 +87541 0.31268310546875 +87542 0.45501708984375 +87543 0.554779052734375 +87544 0.61065673828125 +87545 0.610931396484375 +87546 0.531463623046875 +87547 0.3883056640625 +87548 0.23468017578125 +87549 0.095245361328125 +87550 -0.00396728515625 +87551 -0.04852294921875 +87552 -0.055145263671875 +87553 -0.0758056640625 +87554 -0.138702392578125 +87555 -0.209197998046875 +87556 -0.289031982421875 +87557 -0.37884521484375 +87558 -0.456329345703125 +87559 -0.51641845703125 +87560 -0.519287109375 +87561 -0.458251953125 +87562 -0.384796142578125 +87563 -0.323699951171875 +87564 -0.269287109375 +87565 -0.1951904296875 +87566 -0.100006103515625 +87567 -0.01055908203125 +87568 0.1033935546875 +87569 0.24908447265625 +87570 0.373199462890625 +87571 0.45806884765625 +87572 0.511474609375 +87573 0.565399169921875 +87574 0.61138916015625 +87575 0.5897216796875 +87576 0.4906005859375 +87577 0.33148193359375 +87578 0.147796630859375 +87579 -0.01873779296875 +87580 -0.140289306640625 +87581 -0.191986083984375 +87582 -0.184295654296875 +87583 -0.161834716796875 +87584 -0.166595458984375 +87585 -0.19390869140625 +87586 -0.22442626953125 +87587 -0.279754638671875 +87588 -0.3389892578125 +87589 -0.3543701171875 +87590 -0.348175048828125 +87591 -0.32598876953125 +87592 -0.2581787109375 +87593 -0.139801025390625 +87594 0.014617919921875 +87595 0.144378662109375 +87596 0.221038818359375 +87597 0.27069091796875 +87598 0.294036865234375 +87599 0.311767578125 +87600 0.339141845703125 +87601 0.360260009765625 +87602 0.360504150390625 +87603 0.308380126953125 +87604 0.18170166015625 +87605 0.0047607421875 +87606 -0.17559814453125 +87607 -0.3143310546875 +87608 -0.36785888671875 +87609 -0.36248779296875 +87610 -0.343536376953125 +87611 -0.3018798828125 +87612 -0.231414794921875 +87613 -0.117645263671875 +87614 0.007049560546875 +87615 0.087982177734375 +87616 0.13946533203125 +87617 0.17425537109375 +87618 0.188201904296875 +87619 0.171234130859375 +87620 0.118438720703125 +87621 0.05706787109375 +87622 -0.010711669921875 +87623 -0.0914306640625 +87624 -0.162322998046875 +87625 -0.194549560546875 +87626 -0.1492919921875 +87627 -0.02166748046875 +87628 0.124053955078125 +87629 0.211151123046875 +87630 0.240447998046875 +87631 0.242218017578125 +87632 0.2257080078125 +87633 0.194366455078125 +87634 0.115509033203125 +87635 0.0128173828125 +87636 -0.053802490234375 +87637 -0.110626220703125 +87638 -0.199493408203125 +87639 -0.29437255859375 +87640 -0.33221435546875 +87641 -0.27972412109375 +87642 -0.185333251953125 +87643 -0.128204345703125 +87644 -0.115692138671875 +87645 -0.116455078125 +87646 -0.105926513671875 +87647 -0.053955078125 +87648 0.048797607421875 +87649 0.157318115234375 +87650 0.212005615234375 +87651 0.218475341796875 +87652 0.23724365234375 +87653 0.30535888671875 +87654 0.38128662109375 +87655 0.404449462890625 +87656 0.3944091796875 +87657 0.3885498046875 +87658 0.362640380859375 +87659 0.27362060546875 +87660 0.11712646484375 +87661 -0.054901123046875 +87662 -0.19085693359375 +87663 -0.28570556640625 +87664 -0.339263916015625 +87665 -0.3775634765625 +87666 -0.445709228515625 +87667 -0.535064697265625 +87668 -0.629058837890625 +87669 -0.697601318359375 +87670 -0.70391845703125 +87671 -0.6424560546875 +87672 -0.491241455078125 +87673 -0.265716552734375 +87674 -0.023712158203125 +87675 0.201751708984375 +87676 0.375823974609375 +87677 0.485076904296875 +87678 0.56884765625 +87679 0.634765625 +87680 0.63763427734375 +87681 0.5660400390625 +87682 0.4720458984375 +87683 0.40692138671875 +87684 0.3778076171875 +87685 0.376953125 +87686 0.371978759765625 +87687 0.313140869140625 +87688 0.184417724609375 +87689 0.011199951171875 +87690 -0.171051025390625 +87691 -0.33740234375 +87692 -0.47198486328125 +87693 -0.560394287109375 +87694 -0.58056640625 +87695 -0.54754638671875 +87696 -0.508575439453125 +87697 -0.459503173828125 +87698 -0.394378662109375 +87699 -0.35260009765625 +87700 -0.31170654296875 +87701 -0.197418212890625 +87702 -0.007965087890625 +87703 0.207489013671875 +87704 0.409210205078125 +87705 0.57208251953125 +87706 0.66595458984375 +87707 0.65875244140625 +87708 0.56744384765625 +87709 0.431396484375 +87710 0.29443359375 +87711 0.182464599609375 +87712 0.06365966796875 +87713 -0.075958251953125 +87714 -0.189422607421875 +87715 -0.271942138671875 +87716 -0.342529296875 +87717 -0.364166259765625 +87718 -0.327239990234375 +87719 -0.2769775390625 +87720 -0.253692626953125 +87721 -0.24365234375 +87722 -0.1983642578125 +87723 -0.116241455078125 +87724 -0.036834716796875 +87725 0.034881591796875 +87726 0.09124755859375 +87727 0.10888671875 +87728 0.125518798828125 +87729 0.15771484375 +87730 0.17828369140625 +87731 0.17108154296875 +87732 0.129974365234375 +87733 0.082427978515625 +87734 0.027679443359375 +87735 -0.065643310546875 +87736 -0.15936279296875 +87737 -0.21307373046875 +87738 -0.234649658203125 +87739 -0.2001953125 +87740 -0.119171142578125 +87741 -0.024749755859375 +87742 0.085784912109375 +87743 0.178131103515625 +87744 0.215576171875 +87745 0.211456298828125 +87746 0.17523193359375 +87747 0.128753662109375 +87748 0.1019287109375 +87749 0.0743408203125 +87750 0.04327392578125 +87751 0.038177490234375 +87752 0.076263427734375 +87753 0.14105224609375 +87754 0.186431884765625 +87755 0.188812255859375 +87756 0.1390380859375 +87757 0.041778564453125 +87758 -0.079437255859375 +87759 -0.219390869140625 +87760 -0.367828369140625 +87761 -0.494873046875 +87762 -0.556243896484375 +87763 -0.508697509765625 +87764 -0.3756103515625 +87765 -0.218902587890625 +87766 -0.063751220703125 +87767 0.091552734375 +87768 0.23602294921875 +87769 0.342987060546875 +87770 0.39520263671875 +87771 0.389373779296875 +87772 0.324249267578125 +87773 0.224090576171875 +87774 0.124267578125 +87775 0.037078857421875 +87776 -0.010101318359375 +87777 -0.019439697265625 +87778 -0.022796630859375 +87779 -0.001556396484375 +87780 0.056304931640625 +87781 0.106719970703125 +87782 0.096893310546875 +87783 0.042694091796875 +87784 -0.018035888671875 +87785 -0.07586669921875 +87786 -0.11944580078125 +87787 -0.15972900390625 +87788 -0.202606201171875 +87789 -0.24859619140625 +87790 -0.30517578125 +87791 -0.36212158203125 +87792 -0.39141845703125 +87793 -0.35528564453125 +87794 -0.249969482421875 +87795 -0.092864990234375 +87796 0.08905029296875 +87797 0.2352294921875 +87798 0.318817138671875 +87799 0.358642578125 +87800 0.347747802734375 +87801 0.28564453125 +87802 0.223175048828125 +87803 0.196746826171875 +87804 0.179840087890625 +87805 0.155548095703125 +87806 0.151214599609375 +87807 0.156951904296875 +87808 0.13177490234375 +87809 0.100799560546875 +87810 0.087127685546875 +87811 0.05487060546875 +87812 -0.009002685546875 +87813 -0.10400390625 +87814 -0.229400634765625 +87815 -0.35552978515625 +87816 -0.441925048828125 +87817 -0.473846435546875 +87818 -0.464813232421875 +87819 -0.419097900390625 +87820 -0.334320068359375 +87821 -0.227935791015625 +87822 -0.12347412109375 +87823 -0.02764892578125 +87824 0.077667236328125 +87825 0.2132568359375 +87826 0.38885498046875 +87827 0.582794189453125 +87828 0.734039306640625 +87829 0.800140380859375 +87830 0.7783203125 +87831 0.6651611328125 +87832 0.45965576171875 +87833 0.199188232421875 +87834 -0.050689697265625 +87835 -0.23297119140625 +87836 -0.33013916015625 +87837 -0.368408203125 +87838 -0.378936767578125 +87839 -0.376983642578125 +87840 -0.37969970703125 +87841 -0.391510009765625 +87842 -0.385345458984375 +87843 -0.3419189453125 +87844 -0.28289794921875 +87845 -0.251617431640625 +87846 -0.266143798828125 +87847 -0.273345947265625 +87848 -0.216796875 +87849 -0.128265380859375 +87850 -0.068145751953125 +87851 -0.0430908203125 +87852 -0.024444580078125 +87853 0.020721435546875 +87854 0.124481201171875 +87855 0.25787353515625 +87856 0.379119873046875 +87857 0.47991943359375 +87858 0.5281982421875 +87859 0.511138916015625 +87860 0.456207275390625 +87861 0.407470703125 +87862 0.383758544921875 +87863 0.35687255859375 +87864 0.31182861328125 +87865 0.250885009765625 +87866 0.1654052734375 +87867 0.035247802734375 +87868 -0.142059326171875 +87869 -0.33563232421875 +87870 -0.5345458984375 +87871 -0.72186279296875 +87872 -0.836669921875 +87873 -0.8326416015625 +87874 -0.7296142578125 +87875 -0.582550048828125 +87876 -0.440093994140625 +87877 -0.324310302734375 +87878 -0.20147705078125 +87879 -0.044647216796875 +87880 0.103973388671875 +87881 0.202392578125 +87882 0.264495849609375 +87883 0.338897705078125 +87884 0.443817138671875 +87885 0.545074462890625 +87886 0.6173095703125 +87887 0.6524658203125 +87888 0.66339111328125 +87889 0.6561279296875 +87890 0.606781005859375 +87891 0.501190185546875 +87892 0.352783203125 +87893 0.176544189453125 +87894 -0.034820556640625 +87895 -0.258209228515625 +87896 -0.44244384765625 +87897 -0.5753173828125 +87898 -0.65203857421875 +87899 -0.641632080078125 +87900 -0.562164306640625 +87901 -0.458038330078125 +87902 -0.350555419921875 +87903 -0.260528564453125 +87904 -0.192108154296875 +87905 -0.141937255859375 +87906 -0.1021728515625 +87907 -0.062896728515625 +87908 -0.011932373046875 +87909 0.062835693359375 +87910 0.148712158203125 +87911 0.241729736328125 +87912 0.34912109375 +87913 0.457305908203125 +87914 0.54388427734375 +87915 0.5728759765625 +87916 0.506591796875 +87917 0.351226806640625 +87918 0.146514892578125 +87919 -0.05523681640625 +87920 -0.21624755859375 +87921 -0.334930419921875 +87922 -0.402984619140625 +87923 -0.4412841796875 +87924 -0.49578857421875 +87925 -0.5601806640625 +87926 -0.600738525390625 +87927 -0.584228515625 +87928 -0.47930908203125 +87929 -0.27935791015625 +87930 -0.0089111328125 +87931 0.268798828125 +87932 0.482818603515625 +87933 0.60369873046875 +87934 0.650421142578125 +87935 0.66400146484375 +87936 0.6414794921875 +87937 0.572540283203125 +87938 0.498138427734375 +87939 0.439453125 +87940 0.375518798828125 +87941 0.274505615234375 +87942 0.1087646484375 +87943 -0.099395751953125 +87944 -0.3182373046875 +87945 -0.5489501953125 +87946 -0.7738037109375 +87947 -0.86383056640625 +87948 -0.870391845703125 +87949 -0.86895751953125 +87950 -0.861053466796875 +87951 -0.765869140625 +87952 -0.5301513671875 +87953 -0.214691162109375 +87954 0.137359619140625 +87955 0.474822998046875 +87956 0.76239013671875 +87957 0.867462158203125 +87958 0.870361328125 +87959 0.86480712890625 +87960 0.831817626953125 +87961 0.677581787109375 +87962 0.495880126953125 +87963 0.30767822265625 +87964 0.116180419921875 +87965 -0.110748291015625 +87966 -0.381805419921875 +87967 -0.6572265625 +87968 -0.857421875 +87969 -0.870391845703125 +87970 -0.870391845703125 +87971 -0.86444091796875 +87972 -0.85723876953125 +87973 -0.790008544921875 +87974 -0.62847900390625 +87975 -0.3956298828125 +87976 -0.126708984375 +87977 0.150115966796875 +87978 0.424041748046875 +87979 0.670623779296875 +87980 0.854522705078125 +87981 0.866485595703125 +87982 0.86920166015625 +87983 0.8653564453125 +87984 0.857147216796875 +87985 0.766845703125 +87986 0.628509521484375 +87987 0.462127685546875 +87988 0.297210693359375 +87989 0.14862060546875 +87990 -0.00537109375 +87991 -0.15753173828125 +87992 -0.31304931640625 +87993 -0.48876953125 +87994 -0.6416015625 +87995 -0.751373291015625 +87996 -0.84619140625 +87997 -0.861297607421875 +87998 -0.863250732421875 +87999 -0.856597900390625 +88000 -0.7498779296875 +88001 -0.624542236328125 +88002 -0.47808837890625 +88003 -0.253387451171875 +88004 0.003692626953125 +88005 0.2257080078125 +88006 0.427154541015625 +88007 0.643218994140625 +88008 0.855926513671875 +88009 0.870361328125 +88010 0.870361328125 +88011 0.862762451171875 +88012 0.79669189453125 +88013 0.595794677734375 +88014 0.362152099609375 +88015 0.1270751953125 +88016 -0.086944580078125 +88017 -0.2784423828125 +88018 -0.484832763671875 +88019 -0.729583740234375 +88020 -0.86688232421875 +88021 -0.870391845703125 +88022 -0.86859130859375 +88023 -0.86279296875 +88024 -0.817962646484375 +88025 -0.6116943359375 +88026 -0.3128662109375 +88027 0.039398193359375 +88028 0.422821044921875 +88029 0.805145263671875 +88030 0.870361328125 +88031 0.870361328125 +88032 0.860015869140625 +88033 0.727935791015625 +88034 0.48114013671875 +88035 0.2059326171875 +88036 -0.06103515625 +88037 -0.29913330078125 +88038 -0.516204833984375 +88039 -0.7252197265625 +88040 -0.85980224609375 +88041 -0.870391845703125 +88042 -0.870391845703125 +88043 -0.858062744140625 +88044 -0.673004150390625 +88045 -0.42694091796875 +88046 -0.2100830078125 +88047 -0.0362548828125 +88048 0.10943603515625 +88049 0.23516845703125 +88050 0.373687744140625 +88051 0.517791748046875 +88052 0.602783203125 +88053 0.635711669921875 +88054 0.655181884765625 +88055 0.65948486328125 +88056 0.651275634765625 +88057 0.61846923828125 +88058 0.53753662109375 +88059 0.404144287109375 +88060 0.22186279296875 +88061 0.003997802734375 +88062 -0.22100830078125 +88063 -0.42449951171875 +88064 -0.579833984375 +88065 -0.641876220703125 +88066 -0.6177978515625 +88067 -0.575531005859375 +88068 -0.526336669921875 +88069 -0.42645263671875 +88070 -0.2581787109375 +88071 -0.068695068359375 +88072 0.09222412109375 +88073 0.232147216796875 +88074 0.3509521484375 +88075 0.410064697265625 +88076 0.372955322265625 +88077 0.2554931640625 +88078 0.10711669921875 +88079 -0.052886962890625 +88080 -0.186279296875 +88081 -0.23291015625 +88082 -0.209442138671875 +88083 -0.174163818359375 +88084 -0.126739501953125 +88085 -0.048126220703125 +88086 0.0426025390625 +88087 0.10748291015625 +88088 0.1409912109375 +88089 0.19708251953125 +88090 0.273651123046875 +88091 0.31768798828125 +88092 0.341094970703125 +88093 0.368011474609375 +88094 0.37249755859375 +88095 0.30072021484375 +88096 0.1517333984375 +88097 -0.01470947265625 +88098 -0.1883544921875 +88099 -0.372711181640625 +88100 -0.51397705078125 +88101 -0.57177734375 +88102 -0.53948974609375 +88103 -0.43511962890625 +88104 -0.2962646484375 +88105 -0.161102294921875 +88106 -0.0435791015625 +88107 0.060394287109375 +88108 0.13665771484375 +88109 0.170135498046875 +88110 0.16552734375 +88111 0.15728759765625 +88112 0.150787353515625 +88113 0.12200927734375 +88114 0.080108642578125 +88115 0.05126953125 +88116 0.062896728515625 +88117 0.09271240234375 +88118 0.092987060546875 +88119 0.07855224609375 +88120 0.06427001953125 +88121 0.0347900390625 +88122 -0.01171875 +88123 -0.056060791015625 +88124 -0.055511474609375 +88125 -0.010467529296875 +88126 0.02508544921875 +88127 0.025665283203125 +88128 0.017333984375 +88129 0.00189208984375 +88130 -0.03173828125 +88131 -0.071502685546875 +88132 -0.13543701171875 +88133 -0.219970703125 +88134 -0.300506591796875 +88135 -0.376312255859375 +88136 -0.416107177734375 +88137 -0.371124267578125 +88138 -0.242279052734375 +88139 -0.069732666015625 +88140 0.125640869140625 +88141 0.31268310546875 +88142 0.45501708984375 +88143 0.554779052734375 +88144 0.61065673828125 +88145 0.610931396484375 +88146 0.531463623046875 +88147 0.3883056640625 +88148 0.23468017578125 +88149 0.095245361328125 +88150 -0.00396728515625 +88151 -0.04852294921875 +88152 -0.055145263671875 +88153 -0.0758056640625 +88154 -0.138702392578125 +88155 -0.209197998046875 +88156 -0.289031982421875 +88157 -0.37884521484375 +88158 -0.456329345703125 +88159 -0.51641845703125 +88160 -0.519287109375 +88161 -0.458251953125 +88162 -0.384796142578125 +88163 -0.323699951171875 +88164 -0.269287109375 +88165 -0.1951904296875 +88166 -0.100006103515625 +88167 -0.01055908203125 +88168 0.1033935546875 +88169 0.24908447265625 +88170 0.373199462890625 +88171 0.45806884765625 +88172 0.511474609375 +88173 0.565399169921875 +88174 0.61138916015625 +88175 0.5897216796875 +88176 0.4906005859375 +88177 0.33148193359375 +88178 0.147796630859375 +88179 -0.01873779296875 +88180 -0.140289306640625 +88181 -0.191986083984375 +88182 -0.184295654296875 +88183 -0.161834716796875 +88184 -0.166595458984375 +88185 -0.19390869140625 +88186 -0.22442626953125 +88187 -0.279754638671875 +88188 -0.3389892578125 +88189 -0.3543701171875 +88190 -0.348175048828125 +88191 -0.32598876953125 +88192 -0.2581787109375 +88193 -0.139801025390625 +88194 0.014617919921875 +88195 0.144378662109375 +88196 0.221038818359375 +88197 0.27069091796875 +88198 0.294036865234375 +88199 0.311767578125 +88200 0.339141845703125 +88201 0.360260009765625 +88202 0.360504150390625 +88203 0.308380126953125 +88204 0.18170166015625 +88205 0.0047607421875 +88206 -0.17559814453125 +88207 -0.3143310546875 +88208 -0.36785888671875 +88209 -0.36248779296875 +88210 -0.343536376953125 +88211 -0.3018798828125 +88212 -0.231414794921875 +88213 -0.117645263671875 +88214 0.007049560546875 +88215 0.087982177734375 +88216 0.13946533203125 +88217 0.17425537109375 +88218 0.188201904296875 +88219 0.171234130859375 +88220 0.118438720703125 +88221 0.05706787109375 +88222 -0.010711669921875 +88223 -0.0914306640625 +88224 -0.162322998046875 +88225 -0.194549560546875 +88226 -0.1492919921875 +88227 -0.02166748046875 +88228 0.124053955078125 +88229 0.211151123046875 +88230 0.240447998046875 +88231 0.242218017578125 +88232 0.2257080078125 +88233 0.194366455078125 +88234 0.115509033203125 +88235 0.0128173828125 +88236 -0.053802490234375 +88237 -0.110626220703125 +88238 -0.199493408203125 +88239 -0.29437255859375 +88240 -0.33221435546875 +88241 -0.27972412109375 +88242 -0.185333251953125 +88243 -0.128204345703125 +88244 -0.115692138671875 +88245 -0.116455078125 +88246 -0.105926513671875 +88247 -0.053955078125 +88248 0.048797607421875 +88249 0.157318115234375 +88250 0.212005615234375 +88251 0.218475341796875 +88252 0.23724365234375 +88253 0.30535888671875 +88254 0.38128662109375 +88255 0.404449462890625 +88256 0.3944091796875 +88257 0.3885498046875 +88258 0.362640380859375 +88259 0.27362060546875 +88260 0.11712646484375 +88261 -0.054901123046875 +88262 -0.19085693359375 +88263 -0.28570556640625 +88264 -0.339263916015625 +88265 -0.3775634765625 +88266 -0.445709228515625 +88267 -0.535064697265625 +88268 -0.629058837890625 +88269 -0.697601318359375 +88270 -0.70391845703125 +88271 -0.6424560546875 +88272 -0.491241455078125 +88273 -0.265716552734375 +88274 -0.023712158203125 +88275 0.201751708984375 +88276 0.375823974609375 +88277 0.485076904296875 +88278 0.56884765625 +88279 0.634765625 +88280 0.63763427734375 +88281 0.5660400390625 +88282 0.4720458984375 +88283 0.40692138671875 +88284 0.3778076171875 +88285 0.376953125 +88286 0.371978759765625 +88287 0.313140869140625 +88288 0.184417724609375 +88289 0.011199951171875 +88290 -0.171051025390625 +88291 -0.33740234375 +88292 -0.47198486328125 +88293 -0.560394287109375 +88294 -0.58056640625 +88295 -0.54754638671875 +88296 -0.508575439453125 +88297 -0.459503173828125 +88298 -0.394378662109375 +88299 -0.35260009765625 +88300 -0.31170654296875 +88301 -0.197418212890625 +88302 -0.007965087890625 +88303 0.207489013671875 +88304 0.409210205078125 +88305 0.57208251953125 +88306 0.66595458984375 +88307 0.65875244140625 +88308 0.56744384765625 +88309 0.431396484375 +88310 0.29443359375 +88311 0.182464599609375 +88312 0.06365966796875 +88313 -0.075958251953125 +88314 -0.189422607421875 +88315 -0.271942138671875 +88316 -0.342529296875 +88317 -0.364166259765625 +88318 -0.327239990234375 +88319 -0.2769775390625 +88320 -0.253692626953125 +88321 -0.24365234375 +88322 -0.1983642578125 +88323 -0.116241455078125 +88324 -0.036834716796875 +88325 0.034881591796875 +88326 0.09124755859375 +88327 0.10888671875 +88328 0.125518798828125 +88329 0.15771484375 +88330 0.17828369140625 +88331 0.17108154296875 +88332 0.129974365234375 +88333 0.082427978515625 +88334 0.027679443359375 +88335 -0.065643310546875 +88336 -0.15936279296875 +88337 -0.21307373046875 +88338 -0.234649658203125 +88339 -0.2001953125 +88340 -0.119171142578125 +88341 -0.024749755859375 +88342 0.085784912109375 +88343 0.178131103515625 +88344 0.215576171875 +88345 0.211456298828125 +88346 0.17523193359375 +88347 0.128753662109375 +88348 0.1019287109375 +88349 0.0743408203125 +88350 0.04327392578125 +88351 0.038177490234375 +88352 0.076263427734375 +88353 0.14105224609375 +88354 0.186431884765625 +88355 0.188812255859375 +88356 0.1390380859375 +88357 0.041778564453125 +88358 -0.079437255859375 +88359 -0.219390869140625 +88360 -0.367828369140625 +88361 -0.494873046875 +88362 -0.556243896484375 +88363 -0.508697509765625 +88364 -0.3756103515625 +88365 -0.218902587890625 +88366 -0.063751220703125 +88367 0.091552734375 +88368 0.23602294921875 +88369 0.342987060546875 +88370 0.39520263671875 +88371 0.389373779296875 +88372 0.324249267578125 +88373 0.224090576171875 +88374 0.124267578125 +88375 0.037078857421875 +88376 -0.010101318359375 +88377 -0.019439697265625 +88378 -0.022796630859375 +88379 -0.001556396484375 +88380 0.056304931640625 +88381 0.106719970703125 +88382 0.096893310546875 +88383 0.042694091796875 +88384 -0.018035888671875 +88385 -0.07586669921875 +88386 -0.11944580078125 +88387 -0.15972900390625 +88388 -0.202606201171875 +88389 -0.24859619140625 +88390 -0.30517578125 +88391 -0.36212158203125 +88392 -0.39141845703125 +88393 -0.35528564453125 +88394 -0.249969482421875 +88395 -0.092864990234375 +88396 0.08905029296875 +88397 0.2352294921875 +88398 0.318817138671875 +88399 0.358642578125 +88400 0.347747802734375 +88401 0.28564453125 +88402 0.223175048828125 +88403 0.196746826171875 +88404 0.179840087890625 +88405 0.155548095703125 +88406 0.151214599609375 +88407 0.156951904296875 +88408 0.13177490234375 +88409 0.100799560546875 +88410 0.087127685546875 +88411 0.05487060546875 +88412 -0.009002685546875 +88413 -0.10400390625 +88414 -0.229400634765625 +88415 -0.35552978515625 +88416 -0.441925048828125 +88417 -0.473846435546875 +88418 -0.464813232421875 +88419 -0.419097900390625 +88420 -0.334320068359375 +88421 -0.227935791015625 +88422 -0.12347412109375 +88423 -0.02764892578125 +88424 0.077667236328125 +88425 0.2132568359375 +88426 0.38885498046875 +88427 0.582794189453125 +88428 0.734039306640625 +88429 0.800140380859375 +88430 0.7783203125 +88431 0.6651611328125 +88432 0.45965576171875 +88433 0.199188232421875 +88434 -0.050689697265625 +88435 -0.23297119140625 +88436 -0.33013916015625 +88437 -0.368408203125 +88438 -0.378936767578125 +88439 -0.376983642578125 +88440 -0.37969970703125 +88441 -0.391510009765625 +88442 -0.385345458984375 +88443 -0.3419189453125 +88444 -0.28289794921875 +88445 -0.251617431640625 +88446 -0.266143798828125 +88447 -0.273345947265625 +88448 -0.216796875 +88449 -0.128265380859375 +88450 -0.068145751953125 +88451 -0.0430908203125 +88452 -0.024444580078125 +88453 0.020721435546875 +88454 0.124481201171875 +88455 0.25787353515625 +88456 0.379119873046875 +88457 0.47991943359375 +88458 0.5281982421875 +88459 0.511138916015625 +88460 0.456207275390625 +88461 0.407470703125 +88462 0.383758544921875 +88463 0.35687255859375 +88464 0.31182861328125 +88465 0.250885009765625 +88466 0.1654052734375 +88467 0.035247802734375 +88468 -0.142059326171875 +88469 -0.33563232421875 +88470 -0.5345458984375 +88471 -0.72186279296875 +88472 -0.836669921875 +88473 -0.8326416015625 +88474 -0.7296142578125 +88475 -0.582550048828125 +88476 -0.440093994140625 +88477 -0.324310302734375 +88478 -0.20147705078125 +88479 -0.044647216796875 +88480 0.103973388671875 +88481 0.202392578125 +88482 0.264495849609375 +88483 0.338897705078125 +88484 0.443817138671875 +88485 0.545074462890625 +88486 0.6173095703125 +88487 0.6524658203125 +88488 0.66339111328125 +88489 0.6561279296875 +88490 0.606781005859375 +88491 0.501190185546875 +88492 0.352783203125 +88493 0.176544189453125 +88494 -0.034820556640625 +88495 -0.258209228515625 +88496 -0.44244384765625 +88497 -0.5753173828125 +88498 -0.65203857421875 +88499 -0.641632080078125 +88500 -0.562164306640625 +88501 -0.458038330078125 +88502 -0.350555419921875 +88503 -0.260528564453125 +88504 -0.192108154296875 +88505 -0.141937255859375 +88506 -0.1021728515625 +88507 -0.062896728515625 +88508 -0.011932373046875 +88509 0.062835693359375 +88510 0.148712158203125 +88511 0.241729736328125 +88512 0.34912109375 +88513 0.457305908203125 +88514 0.54388427734375 +88515 0.5728759765625 +88516 0.506591796875 +88517 0.351226806640625 +88518 0.146514892578125 +88519 -0.05523681640625 +88520 -0.21624755859375 +88521 -0.334930419921875 +88522 -0.402984619140625 +88523 -0.4412841796875 +88524 -0.49578857421875 +88525 -0.5601806640625 +88526 -0.600738525390625 +88527 -0.584228515625 +88528 -0.47930908203125 +88529 -0.27935791015625 +88530 -0.0089111328125 +88531 0.268798828125 +88532 0.482818603515625 +88533 0.60369873046875 +88534 0.650421142578125 +88535 0.66400146484375 +88536 0.6414794921875 +88537 0.572540283203125 +88538 0.498138427734375 +88539 0.439453125 +88540 0.375518798828125 +88541 0.274505615234375 +88542 0.1087646484375 +88543 -0.099395751953125 +88544 -0.3182373046875 +88545 -0.5489501953125 +88546 -0.7738037109375 +88547 -0.86383056640625 +88548 -0.870391845703125 +88549 -0.86895751953125 +88550 -0.861053466796875 +88551 -0.765869140625 +88552 -0.5301513671875 +88553 -0.214691162109375 +88554 0.137359619140625 +88555 0.474822998046875 +88556 0.76239013671875 +88557 0.867462158203125 +88558 0.870361328125 +88559 0.86480712890625 +88560 0.831817626953125 +88561 0.677581787109375 +88562 0.495880126953125 +88563 0.30767822265625 +88564 0.116180419921875 +88565 -0.110748291015625 +88566 -0.381805419921875 +88567 -0.6572265625 +88568 -0.857421875 +88569 -0.870391845703125 +88570 -0.870391845703125 +88571 -0.86444091796875 +88572 -0.85723876953125 +88573 -0.790008544921875 +88574 -0.62847900390625 +88575 -0.3956298828125 +88576 -0.126708984375 +88577 0.150115966796875 +88578 0.424041748046875 +88579 0.670623779296875 +88580 0.854522705078125 +88581 0.866485595703125 +88582 0.86920166015625 +88583 0.8653564453125 +88584 0.857147216796875 +88585 0.766845703125 +88586 0.628509521484375 +88587 0.462127685546875 +88588 0.297210693359375 +88589 0.14862060546875 +88590 -0.00537109375 +88591 -0.15753173828125 +88592 -0.31304931640625 +88593 -0.48876953125 +88594 -0.6416015625 +88595 -0.751373291015625 +88596 -0.84619140625 +88597 -0.861297607421875 +88598 -0.863250732421875 +88599 -0.856597900390625 +88600 -0.7498779296875 +88601 -0.624542236328125 +88602 -0.47808837890625 +88603 -0.253387451171875 +88604 0.003692626953125 +88605 0.2257080078125 +88606 0.427154541015625 +88607 0.643218994140625 +88608 0.855926513671875 +88609 0.870361328125 +88610 0.870361328125 +88611 0.862762451171875 +88612 0.79669189453125 +88613 0.595794677734375 +88614 0.362152099609375 +88615 0.1270751953125 +88616 -0.086944580078125 +88617 -0.2784423828125 +88618 -0.484832763671875 +88619 -0.729583740234375 +88620 -0.86688232421875 +88621 -0.870391845703125 +88622 -0.86859130859375 +88623 -0.86279296875 +88624 -0.817962646484375 +88625 -0.6116943359375 +88626 -0.3128662109375 +88627 0.039398193359375 +88628 0.422821044921875 +88629 0.805145263671875 +88630 0.870361328125 +88631 0.870361328125 +88632 0.860015869140625 +88633 0.727935791015625 +88634 0.48114013671875 +88635 0.2059326171875 +88636 -0.06103515625 +88637 -0.29913330078125 +88638 -0.516204833984375 +88639 -0.7252197265625 +88640 -0.85980224609375 +88641 -0.870391845703125 +88642 -0.870391845703125 +88643 -0.858062744140625 +88644 -0.673004150390625 +88645 -0.42694091796875 +88646 -0.2100830078125 +88647 -0.0362548828125 +88648 0.10943603515625 +88649 0.23516845703125 +88650 0.373687744140625 +88651 0.517791748046875 +88652 0.602783203125 +88653 0.635711669921875 +88654 0.655181884765625 +88655 0.65948486328125 +88656 0.651275634765625 +88657 0.61846923828125 +88658 0.53753662109375 +88659 0.404144287109375 +88660 0.22186279296875 +88661 0.003997802734375 +88662 -0.22100830078125 +88663 -0.42449951171875 +88664 -0.579833984375 +88665 -0.641876220703125 +88666 -0.6177978515625 +88667 -0.575531005859375 +88668 -0.526336669921875 +88669 -0.42645263671875 +88670 -0.2581787109375 +88671 -0.068695068359375 +88672 0.09222412109375 +88673 0.232147216796875 +88674 0.3509521484375 +88675 0.410064697265625 +88676 0.372955322265625 +88677 0.2554931640625 +88678 0.10711669921875 +88679 -0.052886962890625 +88680 -0.186279296875 +88681 -0.23291015625 +88682 -0.209442138671875 +88683 -0.174163818359375 +88684 -0.126739501953125 +88685 -0.048126220703125 +88686 0.0426025390625 +88687 0.10748291015625 +88688 0.1409912109375 +88689 0.19708251953125 +88690 0.273651123046875 +88691 0.31768798828125 +88692 0.341094970703125 +88693 0.368011474609375 +88694 0.37249755859375 +88695 0.30072021484375 +88696 0.1517333984375 +88697 -0.01470947265625 +88698 -0.1883544921875 +88699 -0.372711181640625 +88700 -0.51397705078125 +88701 -0.57177734375 +88702 -0.53948974609375 +88703 -0.43511962890625 +88704 -0.2962646484375 +88705 -0.161102294921875 +88706 -0.0435791015625 +88707 0.060394287109375 +88708 0.13665771484375 +88709 0.170135498046875 +88710 0.16552734375 +88711 0.15728759765625 +88712 0.150787353515625 +88713 0.12200927734375 +88714 0.080108642578125 +88715 0.05126953125 +88716 0.062896728515625 +88717 0.09271240234375 +88718 0.092987060546875 +88719 0.07855224609375 +88720 0.06427001953125 +88721 0.0347900390625 +88722 -0.01171875 +88723 -0.056060791015625 +88724 -0.055511474609375 +88725 -0.010467529296875 +88726 0.02508544921875 +88727 0.025665283203125 +88728 0.017333984375 +88729 0.00189208984375 +88730 -0.03173828125 +88731 -0.071502685546875 +88732 -0.13543701171875 +88733 -0.219970703125 +88734 -0.300506591796875 +88735 -0.376312255859375 +88736 -0.416107177734375 +88737 -0.371124267578125 +88738 -0.242279052734375 +88739 -0.069732666015625 +88740 0.125640869140625 +88741 0.31268310546875 +88742 0.45501708984375 +88743 0.554779052734375 +88744 0.61065673828125 +88745 0.610931396484375 +88746 0.531463623046875 +88747 0.3883056640625 +88748 0.23468017578125 +88749 0.095245361328125 +88750 -0.00396728515625 +88751 -0.04852294921875 +88752 -0.055145263671875 +88753 -0.0758056640625 +88754 -0.138702392578125 +88755 -0.209197998046875 +88756 -0.289031982421875 +88757 -0.37884521484375 +88758 -0.456329345703125 +88759 -0.51641845703125 +88760 -0.519287109375 +88761 -0.458251953125 +88762 -0.384796142578125 +88763 -0.323699951171875 +88764 -0.269287109375 +88765 -0.1951904296875 +88766 -0.100006103515625 +88767 -0.01055908203125 +88768 0.1033935546875 +88769 0.24908447265625 +88770 0.373199462890625 +88771 0.45806884765625 +88772 0.511474609375 +88773 0.565399169921875 +88774 0.61138916015625 +88775 0.5897216796875 +88776 0.4906005859375 +88777 0.33148193359375 +88778 0.147796630859375 +88779 -0.01873779296875 +88780 -0.140289306640625 +88781 -0.191986083984375 +88782 -0.184295654296875 +88783 -0.161834716796875 +88784 -0.166595458984375 +88785 -0.19390869140625 +88786 -0.22442626953125 +88787 -0.279754638671875 +88788 -0.3389892578125 +88789 -0.3543701171875 +88790 -0.348175048828125 +88791 -0.32598876953125 +88792 -0.2581787109375 +88793 -0.139801025390625 +88794 0.014617919921875 +88795 0.144378662109375 +88796 0.221038818359375 +88797 0.27069091796875 +88798 0.294036865234375 +88799 0.311767578125 +88800 0.339141845703125 +88801 0.360260009765625 +88802 0.360504150390625 +88803 0.308380126953125 +88804 0.18170166015625 +88805 0.0047607421875 +88806 -0.17559814453125 +88807 -0.3143310546875 +88808 -0.36785888671875 +88809 -0.36248779296875 +88810 -0.343536376953125 +88811 -0.3018798828125 +88812 -0.231414794921875 +88813 -0.117645263671875 +88814 0.007049560546875 +88815 0.087982177734375 +88816 0.13946533203125 +88817 0.17425537109375 +88818 0.188201904296875 +88819 0.171234130859375 +88820 0.118438720703125 +88821 0.05706787109375 +88822 -0.010711669921875 +88823 -0.0914306640625 +88824 -0.162322998046875 +88825 -0.194549560546875 +88826 -0.1492919921875 +88827 -0.02166748046875 +88828 0.124053955078125 +88829 0.211151123046875 +88830 0.240447998046875 +88831 0.242218017578125 +88832 0.2257080078125 +88833 0.194366455078125 +88834 0.115509033203125 +88835 0.0128173828125 +88836 -0.053802490234375 +88837 -0.110626220703125 +88838 -0.199493408203125 +88839 -0.29437255859375 +88840 -0.33221435546875 +88841 -0.27972412109375 +88842 -0.185333251953125 +88843 -0.128204345703125 +88844 -0.115692138671875 +88845 -0.116455078125 +88846 -0.105926513671875 +88847 -0.053955078125 +88848 0.048797607421875 +88849 0.157318115234375 +88850 0.212005615234375 +88851 0.218475341796875 +88852 0.23724365234375 +88853 0.30535888671875 +88854 0.38128662109375 +88855 0.404449462890625 +88856 0.3944091796875 +88857 0.3885498046875 +88858 0.362640380859375 +88859 0.27362060546875 +88860 0.11712646484375 +88861 -0.054901123046875 +88862 -0.19085693359375 +88863 -0.28570556640625 +88864 -0.339263916015625 +88865 -0.3775634765625 +88866 -0.445709228515625 +88867 -0.535064697265625 +88868 -0.629058837890625 +88869 -0.697601318359375 +88870 -0.70391845703125 +88871 -0.6424560546875 +88872 -0.491241455078125 +88873 -0.265716552734375 +88874 -0.023712158203125 +88875 0.201751708984375 +88876 0.375823974609375 +88877 0.485076904296875 +88878 0.56884765625 +88879 0.634765625 +88880 0.63763427734375 +88881 0.5660400390625 +88882 0.4720458984375 +88883 0.40692138671875 +88884 0.3778076171875 +88885 0.376953125 +88886 0.371978759765625 +88887 0.313140869140625 +88888 0.184417724609375 +88889 0.011199951171875 +88890 -0.171051025390625 +88891 -0.33740234375 +88892 -0.47198486328125 +88893 -0.560394287109375 +88894 -0.58056640625 +88895 -0.54754638671875 +88896 -0.508575439453125 +88897 -0.459503173828125 +88898 -0.394378662109375 +88899 -0.35260009765625 +88900 -0.31170654296875 +88901 -0.197418212890625 +88902 -0.007965087890625 +88903 0.207489013671875 +88904 0.409210205078125 +88905 0.57208251953125 +88906 0.66595458984375 +88907 0.65875244140625 +88908 0.56744384765625 +88909 0.431396484375 +88910 0.29443359375 +88911 0.182464599609375 +88912 0.06365966796875 +88913 -0.075958251953125 +88914 -0.189422607421875 +88915 -0.271942138671875 +88916 -0.342529296875 +88917 -0.364166259765625 +88918 -0.327239990234375 +88919 -0.2769775390625 +88920 -0.253692626953125 +88921 -0.24365234375 +88922 -0.1983642578125 +88923 -0.116241455078125 +88924 -0.036834716796875 +88925 0.034881591796875 +88926 0.09124755859375 +88927 0.10888671875 +88928 0.125518798828125 +88929 0.15771484375 +88930 0.17828369140625 +88931 0.17108154296875 +88932 0.129974365234375 +88933 0.082427978515625 +88934 0.027679443359375 +88935 -0.065643310546875 +88936 -0.15936279296875 +88937 -0.21307373046875 +88938 -0.234649658203125 +88939 -0.2001953125 +88940 -0.119171142578125 +88941 -0.024749755859375 +88942 0.085784912109375 +88943 0.178131103515625 +88944 0.215576171875 +88945 0.211456298828125 +88946 0.17523193359375 +88947 0.128753662109375 +88948 0.1019287109375 +88949 0.0743408203125 +88950 0.04327392578125 +88951 0.038177490234375 +88952 0.076263427734375 +88953 0.14105224609375 +88954 0.186431884765625 +88955 0.188812255859375 +88956 0.1390380859375 +88957 0.041778564453125 +88958 -0.079437255859375 +88959 -0.219390869140625 +88960 -0.367828369140625 +88961 -0.494873046875 +88962 -0.556243896484375 +88963 -0.508697509765625 +88964 -0.3756103515625 +88965 -0.218902587890625 +88966 -0.063751220703125 +88967 0.091552734375 +88968 0.23602294921875 +88969 0.342987060546875 +88970 0.39520263671875 +88971 0.389373779296875 +88972 0.324249267578125 +88973 0.224090576171875 +88974 0.124267578125 +88975 0.037078857421875 +88976 -0.010101318359375 +88977 -0.019439697265625 +88978 -0.022796630859375 +88979 -0.001556396484375 +88980 0.056304931640625 +88981 0.106719970703125 +88982 0.096893310546875 +88983 0.042694091796875 +88984 -0.018035888671875 +88985 -0.07586669921875 +88986 -0.11944580078125 +88987 -0.15972900390625 +88988 -0.202606201171875 +88989 -0.24859619140625 +88990 -0.30517578125 +88991 -0.36212158203125 +88992 -0.39141845703125 +88993 -0.35528564453125 +88994 -0.249969482421875 +88995 -0.092864990234375 +88996 0.08905029296875 +88997 0.2352294921875 +88998 0.318817138671875 +88999 0.358642578125 +89000 0.347747802734375 +89001 0.28564453125 +89002 0.223175048828125 +89003 0.196746826171875 +89004 0.179840087890625 +89005 0.155548095703125 +89006 0.151214599609375 +89007 0.156951904296875 +89008 0.13177490234375 +89009 0.100799560546875 +89010 0.087127685546875 +89011 0.05487060546875 +89012 -0.009002685546875 +89013 -0.10400390625 +89014 -0.229400634765625 +89015 -0.35552978515625 +89016 -0.441925048828125 +89017 -0.473846435546875 +89018 -0.464813232421875 +89019 -0.419097900390625 +89020 -0.334320068359375 +89021 -0.227935791015625 +89022 -0.12347412109375 +89023 -0.02764892578125 +89024 0.077667236328125 +89025 0.2132568359375 +89026 0.38885498046875 +89027 0.582794189453125 +89028 0.734039306640625 +89029 0.800140380859375 +89030 0.7783203125 +89031 0.6651611328125 +89032 0.45965576171875 +89033 0.199188232421875 +89034 -0.050689697265625 +89035 -0.23297119140625 +89036 -0.33013916015625 +89037 -0.368408203125 +89038 -0.378936767578125 +89039 -0.376983642578125 +89040 -0.37969970703125 +89041 -0.391510009765625 +89042 -0.385345458984375 +89043 -0.3419189453125 +89044 -0.28289794921875 +89045 -0.251617431640625 +89046 -0.266143798828125 +89047 -0.273345947265625 +89048 -0.216796875 +89049 -0.128265380859375 +89050 -0.068145751953125 +89051 -0.0430908203125 +89052 -0.024444580078125 +89053 0.020721435546875 +89054 0.124481201171875 +89055 0.25787353515625 +89056 0.379119873046875 +89057 0.47991943359375 +89058 0.5281982421875 +89059 0.511138916015625 +89060 0.456207275390625 +89061 0.407470703125 +89062 0.383758544921875 +89063 0.35687255859375 +89064 0.31182861328125 +89065 0.250885009765625 +89066 0.1654052734375 +89067 0.035247802734375 +89068 -0.142059326171875 +89069 -0.33563232421875 +89070 -0.5345458984375 +89071 -0.72186279296875 +89072 -0.836669921875 +89073 -0.8326416015625 +89074 -0.7296142578125 +89075 -0.582550048828125 +89076 -0.440093994140625 +89077 -0.324310302734375 +89078 -0.20147705078125 +89079 -0.044647216796875 +89080 0.103973388671875 +89081 0.202392578125 +89082 0.264495849609375 +89083 0.338897705078125 +89084 0.443817138671875 +89085 0.545074462890625 +89086 0.6173095703125 +89087 0.6524658203125 +89088 0.66339111328125 +89089 0.6561279296875 +89090 0.606781005859375 +89091 0.501190185546875 +89092 0.352783203125 +89093 0.176544189453125 +89094 -0.034820556640625 +89095 -0.258209228515625 +89096 -0.44244384765625 +89097 -0.5753173828125 +89098 -0.65203857421875 +89099 -0.641632080078125 +89100 -0.562164306640625 +89101 -0.458038330078125 +89102 -0.350555419921875 +89103 -0.260528564453125 +89104 -0.192108154296875 +89105 -0.141937255859375 +89106 -0.1021728515625 +89107 -0.062896728515625 +89108 -0.011932373046875 +89109 0.062835693359375 +89110 0.148712158203125 +89111 0.241729736328125 +89112 0.34912109375 +89113 0.457305908203125 +89114 0.54388427734375 +89115 0.5728759765625 +89116 0.506591796875 +89117 0.351226806640625 +89118 0.146514892578125 +89119 -0.05523681640625 +89120 -0.21624755859375 +89121 -0.334930419921875 +89122 -0.402984619140625 +89123 -0.4412841796875 +89124 -0.49578857421875 +89125 -0.5601806640625 +89126 -0.600738525390625 +89127 -0.584228515625 +89128 -0.47930908203125 +89129 -0.27935791015625 +89130 -0.0089111328125 +89131 0.268798828125 +89132 0.482818603515625 +89133 0.60369873046875 +89134 0.650421142578125 +89135 0.66400146484375 +89136 0.6414794921875 +89137 0.572540283203125 +89138 0.498138427734375 +89139 0.439453125 +89140 0.375518798828125 +89141 0.274505615234375 +89142 0.1087646484375 +89143 -0.099395751953125 +89144 -0.3182373046875 +89145 -0.5489501953125 +89146 -0.7738037109375 +89147 -0.86383056640625 +89148 -0.870391845703125 +89149 -0.86895751953125 +89150 -0.861053466796875 +89151 -0.765869140625 +89152 -0.5301513671875 +89153 -0.214691162109375 +89154 0.137359619140625 +89155 0.474822998046875 +89156 0.76239013671875 +89157 0.867462158203125 +89158 0.870361328125 +89159 0.86480712890625 +89160 0.831817626953125 +89161 0.677581787109375 +89162 0.495880126953125 +89163 0.30767822265625 +89164 0.116180419921875 +89165 -0.110748291015625 +89166 -0.381805419921875 +89167 -0.6572265625 +89168 -0.857421875 +89169 -0.870391845703125 +89170 -0.870391845703125 +89171 -0.86444091796875 +89172 -0.85723876953125 +89173 -0.790008544921875 +89174 -0.62847900390625 +89175 -0.3956298828125 +89176 -0.126708984375 +89177 0.150115966796875 +89178 0.424041748046875 +89179 0.670623779296875 +89180 0.854522705078125 +89181 0.866485595703125 +89182 0.86920166015625 +89183 0.8653564453125 +89184 0.857147216796875 +89185 0.766845703125 +89186 0.628509521484375 +89187 0.462127685546875 +89188 0.297210693359375 +89189 0.14862060546875 +89190 -0.00537109375 +89191 -0.15753173828125 +89192 -0.31304931640625 +89193 -0.48876953125 +89194 -0.6416015625 +89195 -0.751373291015625 +89196 -0.84619140625 +89197 -0.861297607421875 +89198 -0.863250732421875 +89199 -0.856597900390625 +89200 -0.7498779296875 +89201 -0.624542236328125 +89202 -0.47808837890625 +89203 -0.253387451171875 +89204 0.003692626953125 +89205 0.2257080078125 +89206 0.427154541015625 +89207 0.643218994140625 +89208 0.855926513671875 +89209 0.870361328125 +89210 0.870361328125 +89211 0.862762451171875 +89212 0.79669189453125 +89213 0.595794677734375 +89214 0.362152099609375 +89215 0.1270751953125 +89216 -0.086944580078125 +89217 -0.2784423828125 +89218 -0.484832763671875 +89219 -0.729583740234375 +89220 -0.86688232421875 +89221 -0.870391845703125 +89222 -0.86859130859375 +89223 -0.86279296875 +89224 -0.817962646484375 +89225 -0.6116943359375 +89226 -0.3128662109375 +89227 0.039398193359375 +89228 0.422821044921875 +89229 0.805145263671875 +89230 0.870361328125 +89231 0.870361328125 +89232 0.860015869140625 +89233 0.727935791015625 +89234 0.48114013671875 +89235 0.2059326171875 +89236 -0.06103515625 +89237 -0.29913330078125 +89238 -0.516204833984375 +89239 -0.7252197265625 +89240 -0.85980224609375 +89241 -0.870391845703125 +89242 -0.870391845703125 +89243 -0.858062744140625 +89244 -0.673004150390625 +89245 -0.42694091796875 +89246 -0.2100830078125 +89247 -0.0362548828125 +89248 0.10943603515625 +89249 0.23516845703125 +89250 0.373687744140625 +89251 0.517791748046875 +89252 0.602783203125 +89253 0.635711669921875 +89254 0.655181884765625 +89255 0.65948486328125 +89256 0.651275634765625 +89257 0.61846923828125 +89258 0.53753662109375 +89259 0.404144287109375 +89260 0.22186279296875 +89261 0.003997802734375 +89262 -0.22100830078125 +89263 -0.42449951171875 +89264 -0.579833984375 +89265 -0.641876220703125 +89266 -0.6177978515625 +89267 -0.575531005859375 +89268 -0.526336669921875 +89269 -0.42645263671875 +89270 -0.2581787109375 +89271 -0.068695068359375 +89272 0.09222412109375 +89273 0.232147216796875 +89274 0.3509521484375 +89275 0.410064697265625 +89276 0.372955322265625 +89277 0.2554931640625 +89278 0.10711669921875 +89279 -0.052886962890625 +89280 -0.186279296875 +89281 -0.23291015625 +89282 -0.209442138671875 +89283 -0.174163818359375 +89284 -0.126739501953125 +89285 -0.048126220703125 +89286 0.0426025390625 +89287 0.10748291015625 +89288 0.1409912109375 +89289 0.19708251953125 +89290 0.273651123046875 +89291 0.31768798828125 +89292 0.341094970703125 +89293 0.368011474609375 +89294 0.37249755859375 +89295 0.30072021484375 +89296 0.1517333984375 +89297 -0.01470947265625 +89298 -0.1883544921875 +89299 -0.372711181640625 +89300 -0.51397705078125 +89301 -0.57177734375 +89302 -0.53948974609375 +89303 -0.43511962890625 +89304 -0.2962646484375 +89305 -0.161102294921875 +89306 -0.0435791015625 +89307 0.060394287109375 +89308 0.13665771484375 +89309 0.170135498046875 +89310 0.16552734375 +89311 0.15728759765625 +89312 0.150787353515625 +89313 0.12200927734375 +89314 0.080108642578125 +89315 0.05126953125 +89316 0.062896728515625 +89317 0.09271240234375 +89318 0.092987060546875 +89319 0.07855224609375 +89320 0.06427001953125 +89321 0.0347900390625 +89322 -0.01171875 +89323 -0.056060791015625 +89324 -0.055511474609375 +89325 -0.010467529296875 +89326 0.02508544921875 +89327 0.025665283203125 +89328 0.017333984375 +89329 0.00189208984375 +89330 -0.03173828125 +89331 -0.071502685546875 +89332 -0.13543701171875 +89333 -0.219970703125 +89334 -0.300506591796875 +89335 -0.376312255859375 +89336 -0.416107177734375 +89337 -0.371124267578125 +89338 -0.242279052734375 +89339 -0.069732666015625 +89340 0.125640869140625 +89341 0.31268310546875 +89342 0.45501708984375 +89343 0.554779052734375 +89344 0.61065673828125 +89345 0.610931396484375 +89346 0.531463623046875 +89347 0.3883056640625 +89348 0.23468017578125 +89349 0.095245361328125 +89350 -0.00396728515625 +89351 -0.04852294921875 +89352 -0.055145263671875 +89353 -0.0758056640625 +89354 -0.138702392578125 +89355 -0.209197998046875 +89356 -0.289031982421875 +89357 -0.37884521484375 +89358 -0.456329345703125 +89359 -0.51641845703125 +89360 -0.519287109375 +89361 -0.458251953125 +89362 -0.384796142578125 +89363 -0.323699951171875 +89364 -0.269287109375 +89365 -0.1951904296875 +89366 -0.100006103515625 +89367 -0.01055908203125 +89368 0.1033935546875 +89369 0.24908447265625 +89370 0.373199462890625 +89371 0.45806884765625 +89372 0.511474609375 +89373 0.565399169921875 +89374 0.61138916015625 +89375 0.5897216796875 +89376 0.4906005859375 +89377 0.33148193359375 +89378 0.147796630859375 +89379 -0.01873779296875 +89380 -0.140289306640625 +89381 -0.191986083984375 +89382 -0.184295654296875 +89383 -0.161834716796875 +89384 -0.166595458984375 +89385 -0.19390869140625 +89386 -0.22442626953125 +89387 -0.279754638671875 +89388 -0.3389892578125 +89389 -0.3543701171875 +89390 -0.348175048828125 +89391 -0.32598876953125 +89392 -0.2581787109375 +89393 -0.139801025390625 +89394 0.014617919921875 +89395 0.144378662109375 +89396 0.221038818359375 +89397 0.27069091796875 +89398 0.294036865234375 +89399 0.311767578125 +89400 0.339141845703125 +89401 0.360260009765625 +89402 0.360504150390625 +89403 0.308380126953125 +89404 0.18170166015625 +89405 0.0047607421875 +89406 -0.17559814453125 +89407 -0.3143310546875 +89408 -0.36785888671875 +89409 -0.36248779296875 +89410 -0.343536376953125 +89411 -0.3018798828125 +89412 -0.231414794921875 +89413 -0.117645263671875 +89414 0.007049560546875 +89415 0.087982177734375 +89416 0.13946533203125 +89417 0.17425537109375 +89418 0.188201904296875 +89419 0.171234130859375 +89420 0.118438720703125 +89421 0.05706787109375 +89422 -0.010711669921875 +89423 -0.0914306640625 +89424 -0.162322998046875 +89425 -0.194549560546875 +89426 -0.1492919921875 +89427 -0.02166748046875 +89428 0.124053955078125 +89429 0.211151123046875 +89430 0.240447998046875 +89431 0.242218017578125 +89432 0.2257080078125 +89433 0.194366455078125 +89434 0.115509033203125 +89435 0.0128173828125 +89436 -0.053802490234375 +89437 -0.110626220703125 +89438 -0.199493408203125 +89439 -0.29437255859375 +89440 -0.33221435546875 +89441 -0.27972412109375 +89442 -0.185333251953125 +89443 -0.128204345703125 +89444 -0.115692138671875 +89445 -0.116455078125 +89446 -0.105926513671875 +89447 -0.053955078125 +89448 0.048797607421875 +89449 0.157318115234375 +89450 0.212005615234375 +89451 0.218475341796875 +89452 0.23724365234375 +89453 0.30535888671875 +89454 0.38128662109375 +89455 0.404449462890625 +89456 0.3944091796875 +89457 0.3885498046875 +89458 0.362640380859375 +89459 0.27362060546875 +89460 0.11712646484375 +89461 -0.054901123046875 +89462 -0.19085693359375 +89463 -0.28570556640625 +89464 -0.339263916015625 +89465 -0.3775634765625 +89466 -0.445709228515625 +89467 -0.535064697265625 +89468 -0.629058837890625 +89469 -0.697601318359375 +89470 -0.70391845703125 +89471 -0.6424560546875 +89472 -0.491241455078125 +89473 -0.265716552734375 +89474 -0.023712158203125 +89475 0.201751708984375 +89476 0.375823974609375 +89477 0.485076904296875 +89478 0.56884765625 +89479 0.634765625 +89480 0.63763427734375 +89481 0.5660400390625 +89482 0.4720458984375 +89483 0.40692138671875 +89484 0.3778076171875 +89485 0.376953125 +89486 0.371978759765625 +89487 0.313140869140625 +89488 0.184417724609375 +89489 0.011199951171875 +89490 -0.171051025390625 +89491 -0.33740234375 +89492 -0.47198486328125 +89493 -0.560394287109375 +89494 -0.58056640625 +89495 -0.54754638671875 +89496 -0.508575439453125 +89497 -0.459503173828125 +89498 -0.394378662109375 +89499 -0.35260009765625 +89500 -0.31170654296875 +89501 -0.197418212890625 +89502 -0.007965087890625 +89503 0.207489013671875 +89504 0.409210205078125 +89505 0.57208251953125 +89506 0.66595458984375 +89507 0.65875244140625 +89508 0.56744384765625 +89509 0.431396484375 +89510 0.29443359375 +89511 0.182464599609375 +89512 0.06365966796875 +89513 -0.075958251953125 +89514 -0.189422607421875 +89515 -0.271942138671875 +89516 -0.342529296875 +89517 -0.364166259765625 +89518 -0.327239990234375 +89519 -0.2769775390625 +89520 -0.253692626953125 +89521 -0.24365234375 +89522 -0.1983642578125 +89523 -0.116241455078125 +89524 -0.036834716796875 +89525 0.034881591796875 +89526 0.09124755859375 +89527 0.10888671875 +89528 0.125518798828125 +89529 0.15771484375 +89530 0.17828369140625 +89531 0.17108154296875 +89532 0.129974365234375 +89533 0.082427978515625 +89534 0.027679443359375 +89535 -0.065643310546875 +89536 -0.15936279296875 +89537 -0.21307373046875 +89538 -0.234649658203125 +89539 -0.2001953125 +89540 -0.119171142578125 +89541 -0.024749755859375 +89542 0.085784912109375 +89543 0.178131103515625 +89544 0.215576171875 +89545 0.211456298828125 +89546 0.17523193359375 +89547 0.128753662109375 +89548 0.1019287109375 +89549 0.0743408203125 +89550 0.04327392578125 +89551 0.038177490234375 +89552 0.076263427734375 +89553 0.14105224609375 +89554 0.186431884765625 +89555 0.188812255859375 +89556 0.1390380859375 +89557 0.041778564453125 +89558 -0.079437255859375 +89559 -0.219390869140625 +89560 -0.367828369140625 +89561 -0.494873046875 +89562 -0.556243896484375 +89563 -0.508697509765625 +89564 -0.3756103515625 +89565 -0.218902587890625 +89566 -0.063751220703125 +89567 0.091552734375 +89568 0.23602294921875 +89569 0.342987060546875 +89570 0.39520263671875 +89571 0.389373779296875 +89572 0.324249267578125 +89573 0.224090576171875 +89574 0.124267578125 +89575 0.037078857421875 +89576 -0.010101318359375 +89577 -0.019439697265625 +89578 -0.022796630859375 +89579 -0.001556396484375 +89580 0.056304931640625 +89581 0.106719970703125 +89582 0.096893310546875 +89583 0.042694091796875 +89584 -0.018035888671875 +89585 -0.07586669921875 +89586 -0.11944580078125 +89587 -0.15972900390625 +89588 -0.202606201171875 +89589 -0.24859619140625 +89590 -0.30517578125 +89591 -0.36212158203125 +89592 -0.39141845703125 +89593 -0.35528564453125 +89594 -0.249969482421875 +89595 -0.092864990234375 +89596 0.08905029296875 +89597 0.2352294921875 +89598 0.318817138671875 +89599 0.358642578125 +89600 0.347747802734375 +89601 0.28564453125 +89602 0.223175048828125 +89603 0.196746826171875 +89604 0.179840087890625 +89605 0.155548095703125 +89606 0.151214599609375 +89607 0.156951904296875 +89608 0.13177490234375 +89609 0.100799560546875 +89610 0.087127685546875 +89611 0.05487060546875 +89612 -0.009002685546875 +89613 -0.10400390625 +89614 -0.229400634765625 +89615 -0.35552978515625 +89616 -0.441925048828125 +89617 -0.473846435546875 +89618 -0.464813232421875 +89619 -0.419097900390625 +89620 -0.334320068359375 +89621 -0.227935791015625 +89622 -0.12347412109375 +89623 -0.02764892578125 +89624 0.077667236328125 +89625 0.2132568359375 +89626 0.38885498046875 +89627 0.582794189453125 +89628 0.734039306640625 +89629 0.800140380859375 +89630 0.7783203125 +89631 0.6651611328125 +89632 0.45965576171875 +89633 0.199188232421875 +89634 -0.050689697265625 +89635 -0.23297119140625 +89636 -0.33013916015625 +89637 -0.368408203125 +89638 -0.378936767578125 +89639 -0.376983642578125 +89640 -0.37969970703125 +89641 -0.391510009765625 +89642 -0.385345458984375 +89643 -0.3419189453125 +89644 -0.28289794921875 +89645 -0.251617431640625 +89646 -0.266143798828125 +89647 -0.273345947265625 +89648 -0.216796875 +89649 -0.128265380859375 +89650 -0.068145751953125 +89651 -0.0430908203125 +89652 -0.024444580078125 +89653 0.020721435546875 +89654 0.124481201171875 +89655 0.25787353515625 +89656 0.379119873046875 +89657 0.47991943359375 +89658 0.5281982421875 +89659 0.511138916015625 +89660 0.456207275390625 +89661 0.407470703125 +89662 0.383758544921875 +89663 0.35687255859375 +89664 0.31182861328125 +89665 0.250885009765625 +89666 0.1654052734375 +89667 0.035247802734375 +89668 -0.142059326171875 +89669 -0.33563232421875 +89670 -0.5345458984375 +89671 -0.72186279296875 +89672 -0.836669921875 +89673 -0.8326416015625 +89674 -0.7296142578125 +89675 -0.582550048828125 +89676 -0.440093994140625 +89677 -0.324310302734375 +89678 -0.20147705078125 +89679 -0.044647216796875 +89680 0.103973388671875 +89681 0.202392578125 +89682 0.264495849609375 +89683 0.338897705078125 +89684 0.443817138671875 +89685 0.545074462890625 +89686 0.6173095703125 +89687 0.6524658203125 +89688 0.66339111328125 +89689 0.6561279296875 +89690 0.606781005859375 +89691 0.501190185546875 +89692 0.352783203125 +89693 0.176544189453125 +89694 -0.034820556640625 +89695 -0.258209228515625 +89696 -0.44244384765625 +89697 -0.5753173828125 +89698 -0.65203857421875 +89699 -0.641632080078125 +89700 -0.562164306640625 +89701 -0.458038330078125 +89702 -0.350555419921875 +89703 -0.260528564453125 +89704 -0.192108154296875 +89705 -0.141937255859375 +89706 -0.1021728515625 +89707 -0.062896728515625 +89708 -0.011932373046875 +89709 0.062835693359375 +89710 0.148712158203125 +89711 0.241729736328125 +89712 0.34912109375 +89713 0.457305908203125 +89714 0.54388427734375 +89715 0.5728759765625 +89716 0.506591796875 +89717 0.351226806640625 +89718 0.146514892578125 +89719 -0.05523681640625 +89720 -0.21624755859375 +89721 -0.334930419921875 +89722 -0.402984619140625 +89723 -0.4412841796875 +89724 -0.49578857421875 +89725 -0.5601806640625 +89726 -0.600738525390625 +89727 -0.584228515625 +89728 -0.47930908203125 +89729 -0.27935791015625 +89730 -0.0089111328125 +89731 0.268798828125 +89732 0.482818603515625 +89733 0.60369873046875 +89734 0.650421142578125 +89735 0.66400146484375 +89736 0.6414794921875 +89737 0.572540283203125 +89738 0.498138427734375 +89739 0.439453125 +89740 0.375518798828125 +89741 0.274505615234375 +89742 0.1087646484375 +89743 -0.099395751953125 +89744 -0.3182373046875 +89745 -0.5489501953125 +89746 -0.7738037109375 +89747 -0.86383056640625 +89748 -0.870391845703125 +89749 -0.86895751953125 +89750 -0.861053466796875 +89751 -0.765869140625 +89752 -0.5301513671875 +89753 -0.214691162109375 +89754 0.137359619140625 +89755 0.474822998046875 +89756 0.76239013671875 +89757 0.867462158203125 +89758 0.870361328125 +89759 0.86480712890625 +89760 0.831817626953125 +89761 0.677581787109375 +89762 0.495880126953125 +89763 0.30767822265625 +89764 0.116180419921875 +89765 -0.110748291015625 +89766 -0.381805419921875 +89767 -0.6572265625 +89768 -0.857421875 +89769 -0.870391845703125 +89770 -0.870391845703125 +89771 -0.86444091796875 +89772 -0.85723876953125 +89773 -0.790008544921875 +89774 -0.62847900390625 +89775 -0.3956298828125 +89776 -0.126708984375 +89777 0.150115966796875 +89778 0.424041748046875 +89779 0.670623779296875 +89780 0.854522705078125 +89781 0.866485595703125 +89782 0.86920166015625 +89783 0.8653564453125 +89784 0.857147216796875 +89785 0.766845703125 +89786 0.628509521484375 +89787 0.462127685546875 +89788 0.297210693359375 +89789 0.14862060546875 +89790 -0.00537109375 +89791 -0.15753173828125 +89792 -0.31304931640625 +89793 -0.48876953125 +89794 -0.6416015625 +89795 -0.751373291015625 +89796 -0.84619140625 +89797 -0.861297607421875 +89798 -0.863250732421875 +89799 -0.856597900390625 +89800 -0.7498779296875 +89801 -0.624542236328125 +89802 -0.47808837890625 +89803 -0.253387451171875 +89804 0.003692626953125 +89805 0.2257080078125 +89806 0.427154541015625 +89807 0.643218994140625 +89808 0.855926513671875 +89809 0.870361328125 +89810 0.870361328125 +89811 0.862762451171875 +89812 0.79669189453125 +89813 0.595794677734375 +89814 0.362152099609375 +89815 0.1270751953125 +89816 -0.086944580078125 +89817 -0.2784423828125 +89818 -0.484832763671875 +89819 -0.729583740234375 +89820 -0.86688232421875 +89821 -0.870391845703125 +89822 -0.86859130859375 +89823 -0.86279296875 +89824 -0.817962646484375 +89825 -0.6116943359375 +89826 -0.3128662109375 +89827 0.039398193359375 +89828 0.422821044921875 +89829 0.805145263671875 +89830 0.870361328125 +89831 0.870361328125 +89832 0.860015869140625 +89833 0.727935791015625 +89834 0.48114013671875 +89835 0.2059326171875 +89836 -0.06103515625 +89837 -0.29913330078125 +89838 -0.516204833984375 +89839 -0.7252197265625 +89840 -0.85980224609375 +89841 -0.870391845703125 +89842 -0.870391845703125 +89843 -0.858062744140625 +89844 -0.673004150390625 +89845 -0.42694091796875 +89846 -0.2100830078125 +89847 -0.0362548828125 +89848 0.10943603515625 +89849 0.23516845703125 +89850 0.373687744140625 +89851 0.517791748046875 +89852 0.602783203125 +89853 0.635711669921875 +89854 0.655181884765625 +89855 0.65948486328125 +89856 0.651275634765625 +89857 0.61846923828125 +89858 0.53753662109375 +89859 0.404144287109375 +89860 0.22186279296875 +89861 0.003997802734375 +89862 -0.22100830078125 +89863 -0.42449951171875 +89864 -0.579833984375 +89865 -0.641876220703125 +89866 -0.6177978515625 +89867 -0.575531005859375 +89868 -0.526336669921875 +89869 -0.42645263671875 +89870 -0.2581787109375 +89871 -0.068695068359375 +89872 0.09222412109375 +89873 0.232147216796875 +89874 0.3509521484375 +89875 0.410064697265625 +89876 0.372955322265625 +89877 0.2554931640625 +89878 0.10711669921875 +89879 -0.052886962890625 +89880 -0.186279296875 +89881 -0.23291015625 +89882 -0.209442138671875 +89883 -0.174163818359375 +89884 -0.126739501953125 +89885 -0.048126220703125 +89886 0.0426025390625 +89887 0.10748291015625 +89888 0.1409912109375 +89889 0.19708251953125 +89890 0.273651123046875 +89891 0.31768798828125 +89892 0.341094970703125 +89893 0.368011474609375 +89894 0.37249755859375 +89895 0.30072021484375 +89896 0.1517333984375 +89897 -0.01470947265625 +89898 -0.1883544921875 +89899 -0.372711181640625 +89900 -0.51397705078125 +89901 -0.57177734375 +89902 -0.53948974609375 +89903 -0.43511962890625 +89904 -0.2962646484375 +89905 -0.161102294921875 +89906 -0.0435791015625 +89907 0.060394287109375 +89908 0.13665771484375 +89909 0.170135498046875 +89910 0.16552734375 +89911 0.15728759765625 +89912 0.150787353515625 +89913 0.12200927734375 +89914 0.080108642578125 +89915 0.05126953125 +89916 0.062896728515625 +89917 0.09271240234375 +89918 0.092987060546875 +89919 0.07855224609375 +89920 0.06427001953125 +89921 0.0347900390625 +89922 -0.01171875 +89923 -0.056060791015625 +89924 -0.055511474609375 +89925 -0.010467529296875 +89926 0.02508544921875 +89927 0.025665283203125 +89928 0.017333984375 +89929 0.00189208984375 +89930 -0.03173828125 +89931 -0.071502685546875 +89932 -0.13543701171875 +89933 -0.219970703125 +89934 -0.300506591796875 +89935 -0.376312255859375 +89936 -0.416107177734375 +89937 -0.371124267578125 +89938 -0.242279052734375 +89939 -0.069732666015625 +89940 0.125640869140625 +89941 0.31268310546875 +89942 0.45501708984375 +89943 0.554779052734375 +89944 0.61065673828125 +89945 0.610931396484375 +89946 0.531463623046875 +89947 0.3883056640625 +89948 0.23468017578125 +89949 0.095245361328125 +89950 -0.00396728515625 +89951 -0.04852294921875 +89952 -0.055145263671875 +89953 -0.0758056640625 +89954 -0.138702392578125 +89955 -0.209197998046875 +89956 -0.289031982421875 +89957 -0.37884521484375 +89958 -0.456329345703125 +89959 -0.51641845703125 +89960 -0.519287109375 +89961 -0.458251953125 +89962 -0.384796142578125 +89963 -0.323699951171875 +89964 -0.269287109375 +89965 -0.1951904296875 +89966 -0.100006103515625 +89967 -0.01055908203125 +89968 0.1033935546875 +89969 0.24908447265625 +89970 0.373199462890625 +89971 0.45806884765625 +89972 0.511474609375 +89973 0.565399169921875 +89974 0.61138916015625 +89975 0.5897216796875 +89976 0.4906005859375 +89977 0.33148193359375 +89978 0.147796630859375 +89979 -0.01873779296875 +89980 -0.140289306640625 +89981 -0.191986083984375 +89982 -0.184295654296875 +89983 -0.161834716796875 +89984 -0.166595458984375 +89985 -0.19390869140625 +89986 -0.22442626953125 +89987 -0.279754638671875 +89988 -0.3389892578125 +89989 -0.3543701171875 +89990 -0.348175048828125 +89991 -0.32598876953125 +89992 -0.2581787109375 +89993 -0.139801025390625 +89994 0.014617919921875 +89995 0.144378662109375 +89996 0.221038818359375 +89997 0.27069091796875 +89998 0.294036865234375 +89999 0.311767578125 +90000 0.339141845703125 +90001 0.360260009765625 +90002 0.360504150390625 +90003 0.308380126953125 +90004 0.18170166015625 +90005 0.0047607421875 +90006 -0.17559814453125 +90007 -0.3143310546875 +90008 -0.36785888671875 +90009 -0.36248779296875 +90010 -0.343536376953125 +90011 -0.3018798828125 +90012 -0.231414794921875 +90013 -0.117645263671875 +90014 0.007049560546875 +90015 0.087982177734375 +90016 0.13946533203125 +90017 0.17425537109375 +90018 0.188201904296875 +90019 0.171234130859375 +90020 0.118438720703125 +90021 0.05706787109375 +90022 -0.010711669921875 +90023 -0.0914306640625 +90024 -0.162322998046875 +90025 -0.194549560546875 +90026 -0.1492919921875 +90027 -0.02166748046875 +90028 0.124053955078125 +90029 0.211151123046875 +90030 0.240447998046875 +90031 0.242218017578125 +90032 0.2257080078125 +90033 0.194366455078125 +90034 0.115509033203125 +90035 0.0128173828125 +90036 -0.053802490234375 +90037 -0.110626220703125 +90038 -0.199493408203125 +90039 -0.29437255859375 +90040 -0.33221435546875 +90041 -0.27972412109375 +90042 -0.185333251953125 +90043 -0.128204345703125 +90044 -0.115692138671875 +90045 -0.116455078125 +90046 -0.105926513671875 +90047 -0.053955078125 +90048 0.048797607421875 +90049 0.157318115234375 +90050 0.212005615234375 +90051 0.218475341796875 +90052 0.23724365234375 +90053 0.30535888671875 +90054 0.38128662109375 +90055 0.404449462890625 +90056 0.3944091796875 +90057 0.3885498046875 +90058 0.362640380859375 +90059 0.27362060546875 +90060 0.11712646484375 +90061 -0.054901123046875 +90062 -0.19085693359375 +90063 -0.28570556640625 +90064 -0.339263916015625 +90065 -0.3775634765625 +90066 -0.445709228515625 +90067 -0.535064697265625 +90068 -0.629058837890625 +90069 -0.697601318359375 +90070 -0.70391845703125 +90071 -0.6424560546875 +90072 -0.491241455078125 +90073 -0.265716552734375 +90074 -0.023712158203125 +90075 0.201751708984375 +90076 0.375823974609375 +90077 0.485076904296875 +90078 0.56884765625 +90079 0.634765625 +90080 0.63763427734375 +90081 0.5660400390625 +90082 0.4720458984375 +90083 0.40692138671875 +90084 0.3778076171875 +90085 0.376953125 +90086 0.371978759765625 +90087 0.313140869140625 +90088 0.184417724609375 +90089 0.011199951171875 +90090 -0.171051025390625 +90091 -0.33740234375 +90092 -0.47198486328125 +90093 -0.560394287109375 +90094 -0.58056640625 +90095 -0.54754638671875 +90096 -0.508575439453125 +90097 -0.459503173828125 +90098 -0.394378662109375 +90099 -0.35260009765625 +90100 -0.31170654296875 +90101 -0.197418212890625 +90102 -0.007965087890625 +90103 0.207489013671875 +90104 0.409210205078125 +90105 0.57208251953125 +90106 0.66595458984375 +90107 0.65875244140625 +90108 0.56744384765625 +90109 0.431396484375 +90110 0.29443359375 +90111 0.182464599609375 +90112 0.06365966796875 +90113 -0.075958251953125 +90114 -0.189422607421875 +90115 -0.271942138671875 +90116 -0.342529296875 +90117 -0.364166259765625 +90118 -0.327239990234375 +90119 -0.2769775390625 +90120 -0.253692626953125 +90121 -0.24365234375 +90122 -0.1983642578125 +90123 -0.116241455078125 +90124 -0.036834716796875 +90125 0.034881591796875 +90126 0.09124755859375 +90127 0.10888671875 +90128 0.125518798828125 +90129 0.15771484375 +90130 0.17828369140625 +90131 0.17108154296875 +90132 0.129974365234375 +90133 0.082427978515625 +90134 0.027679443359375 +90135 -0.065643310546875 +90136 -0.15936279296875 +90137 -0.21307373046875 +90138 -0.234649658203125 +90139 -0.2001953125 +90140 -0.119171142578125 +90141 -0.024749755859375 +90142 0.085784912109375 +90143 0.178131103515625 +90144 0.215576171875 +90145 0.211456298828125 +90146 0.17523193359375 +90147 0.128753662109375 +90148 0.1019287109375 +90149 0.0743408203125 +90150 0.04327392578125 +90151 0.038177490234375 +90152 0.076263427734375 +90153 0.14105224609375 +90154 0.186431884765625 +90155 0.188812255859375 +90156 0.1390380859375 +90157 0.041778564453125 +90158 -0.079437255859375 +90159 -0.219390869140625 +90160 -0.367828369140625 +90161 -0.494873046875 +90162 -0.556243896484375 +90163 -0.508697509765625 +90164 -0.3756103515625 +90165 -0.218902587890625 +90166 -0.063751220703125 +90167 0.091552734375 +90168 0.23602294921875 +90169 0.342987060546875 +90170 0.39520263671875 +90171 0.389373779296875 +90172 0.324249267578125 +90173 0.224090576171875 +90174 0.124267578125 +90175 0.037078857421875 +90176 -0.010101318359375 +90177 -0.019439697265625 +90178 -0.022796630859375 +90179 -0.001556396484375 +90180 0.056304931640625 +90181 0.106719970703125 +90182 0.096893310546875 +90183 0.042694091796875 +90184 -0.018035888671875 +90185 -0.07586669921875 +90186 -0.11944580078125 +90187 -0.15972900390625 +90188 -0.202606201171875 +90189 -0.24859619140625 +90190 -0.30517578125 +90191 -0.36212158203125 +90192 -0.39141845703125 +90193 -0.35528564453125 +90194 -0.249969482421875 +90195 -0.092864990234375 +90196 0.08905029296875 +90197 0.2352294921875 +90198 0.318817138671875 +90199 0.358642578125 +90200 0.347747802734375 +90201 0.28564453125 +90202 0.223175048828125 +90203 0.196746826171875 +90204 0.179840087890625 +90205 0.155548095703125 +90206 0.151214599609375 +90207 0.156951904296875 +90208 0.13177490234375 +90209 0.100799560546875 +90210 0.087127685546875 +90211 0.05487060546875 +90212 -0.009002685546875 +90213 -0.10400390625 +90214 -0.229400634765625 +90215 -0.35552978515625 +90216 -0.441925048828125 +90217 -0.473846435546875 +90218 -0.464813232421875 +90219 -0.419097900390625 +90220 -0.334320068359375 +90221 -0.227935791015625 +90222 -0.12347412109375 +90223 -0.02764892578125 +90224 0.077667236328125 +90225 0.2132568359375 +90226 0.38885498046875 +90227 0.582794189453125 +90228 0.734039306640625 +90229 0.800140380859375 +90230 0.7783203125 +90231 0.6651611328125 +90232 0.45965576171875 +90233 0.199188232421875 +90234 -0.050689697265625 +90235 -0.23297119140625 +90236 -0.33013916015625 +90237 -0.368408203125 +90238 -0.378936767578125 +90239 -0.376983642578125 +90240 -0.37969970703125 +90241 -0.391510009765625 +90242 -0.385345458984375 +90243 -0.3419189453125 +90244 -0.28289794921875 +90245 -0.251617431640625 +90246 -0.266143798828125 +90247 -0.273345947265625 +90248 -0.216796875 +90249 -0.128265380859375 +90250 -0.068145751953125 +90251 -0.0430908203125 +90252 -0.024444580078125 +90253 0.020721435546875 +90254 0.124481201171875 +90255 0.25787353515625 +90256 0.379119873046875 +90257 0.47991943359375 +90258 0.5281982421875 +90259 0.511138916015625 +90260 0.456207275390625 +90261 0.407470703125 +90262 0.383758544921875 +90263 0.35687255859375 +90264 0.31182861328125 +90265 0.250885009765625 +90266 0.1654052734375 +90267 0.035247802734375 +90268 -0.142059326171875 +90269 -0.33563232421875 +90270 -0.5345458984375 +90271 -0.72186279296875 +90272 -0.836669921875 +90273 -0.8326416015625 +90274 -0.7296142578125 +90275 -0.582550048828125 +90276 -0.440093994140625 +90277 -0.324310302734375 +90278 -0.20147705078125 +90279 -0.044647216796875 +90280 0.103973388671875 +90281 0.202392578125 +90282 0.264495849609375 +90283 0.338897705078125 +90284 0.443817138671875 +90285 0.545074462890625 +90286 0.6173095703125 +90287 0.6524658203125 +90288 0.66339111328125 +90289 0.6561279296875 +90290 0.606781005859375 +90291 0.501190185546875 +90292 0.352783203125 +90293 0.176544189453125 +90294 -0.034820556640625 +90295 -0.258209228515625 +90296 -0.44244384765625 +90297 -0.5753173828125 +90298 -0.65203857421875 +90299 -0.641632080078125 +90300 -0.562164306640625 +90301 -0.458038330078125 +90302 -0.350555419921875 +90303 -0.260528564453125 +90304 -0.192108154296875 +90305 -0.141937255859375 +90306 -0.1021728515625 +90307 -0.062896728515625 +90308 -0.011932373046875 +90309 0.062835693359375 +90310 0.148712158203125 +90311 0.241729736328125 +90312 0.34912109375 +90313 0.457305908203125 +90314 0.54388427734375 +90315 0.5728759765625 +90316 0.506591796875 +90317 0.351226806640625 +90318 0.146514892578125 +90319 -0.05523681640625 +90320 -0.21624755859375 +90321 -0.334930419921875 +90322 -0.402984619140625 +90323 -0.4412841796875 +90324 -0.49578857421875 +90325 -0.5601806640625 +90326 -0.600738525390625 +90327 -0.584228515625 +90328 -0.47930908203125 +90329 -0.27935791015625 +90330 -0.0089111328125 +90331 0.268798828125 +90332 0.482818603515625 +90333 0.60369873046875 +90334 0.650421142578125 +90335 0.66400146484375 +90336 0.6414794921875 +90337 0.572540283203125 +90338 0.498138427734375 +90339 0.439453125 +90340 0.375518798828125 +90341 0.274505615234375 +90342 0.1087646484375 +90343 -0.099395751953125 +90344 -0.3182373046875 +90345 -0.5489501953125 +90346 -0.7738037109375 +90347 -0.86383056640625 +90348 -0.870391845703125 +90349 -0.86895751953125 +90350 -0.861053466796875 +90351 -0.765869140625 +90352 -0.5301513671875 +90353 -0.214691162109375 +90354 0.137359619140625 +90355 0.474822998046875 +90356 0.76239013671875 +90357 0.867462158203125 +90358 0.870361328125 +90359 0.86480712890625 +90360 0.831817626953125 +90361 0.677581787109375 +90362 0.495880126953125 +90363 0.30767822265625 +90364 0.116180419921875 +90365 -0.110748291015625 +90366 -0.381805419921875 +90367 -0.6572265625 +90368 -0.857421875 +90369 -0.870391845703125 +90370 -0.870391845703125 +90371 -0.86444091796875 +90372 -0.85723876953125 +90373 -0.790008544921875 +90374 -0.62847900390625 +90375 -0.3956298828125 +90376 -0.126708984375 +90377 0.150115966796875 +90378 0.424041748046875 +90379 0.670623779296875 +90380 0.854522705078125 +90381 0.866485595703125 +90382 0.86920166015625 +90383 0.8653564453125 +90384 0.857147216796875 +90385 0.766845703125 +90386 0.628509521484375 +90387 0.462127685546875 +90388 0.297210693359375 +90389 0.14862060546875 +90390 -0.00537109375 +90391 -0.15753173828125 +90392 -0.31304931640625 +90393 -0.48876953125 +90394 -0.6416015625 +90395 -0.751373291015625 +90396 -0.84619140625 +90397 -0.861297607421875 +90398 -0.863250732421875 +90399 -0.856597900390625 +90400 -0.7498779296875 +90401 -0.624542236328125 +90402 -0.47808837890625 +90403 -0.253387451171875 +90404 0.003692626953125 +90405 0.2257080078125 +90406 0.427154541015625 +90407 0.643218994140625 +90408 0.855926513671875 +90409 0.870361328125 +90410 0.870361328125 +90411 0.862762451171875 +90412 0.79669189453125 +90413 0.595794677734375 +90414 0.362152099609375 +90415 0.1270751953125 +90416 -0.086944580078125 +90417 -0.2784423828125 +90418 -0.484832763671875 +90419 -0.729583740234375 +90420 -0.86688232421875 +90421 -0.870391845703125 +90422 -0.86859130859375 +90423 -0.86279296875 +90424 -0.817962646484375 +90425 -0.6116943359375 +90426 -0.3128662109375 +90427 0.039398193359375 +90428 0.422821044921875 +90429 0.805145263671875 +90430 0.870361328125 +90431 0.870361328125 +90432 0.860015869140625 +90433 0.727935791015625 +90434 0.48114013671875 +90435 0.2059326171875 +90436 -0.06103515625 +90437 -0.29913330078125 +90438 -0.516204833984375 +90439 -0.7252197265625 +90440 -0.85980224609375 +90441 -0.870391845703125 +90442 -0.870391845703125 +90443 -0.858062744140625 +90444 -0.673004150390625 +90445 -0.42694091796875 +90446 -0.2100830078125 +90447 -0.0362548828125 +90448 0.10943603515625 +90449 0.23516845703125 +90450 0.373687744140625 +90451 0.517791748046875 +90452 0.602783203125 +90453 0.635711669921875 +90454 0.655181884765625 +90455 0.65948486328125 +90456 0.651275634765625 +90457 0.61846923828125 +90458 0.53753662109375 +90459 0.404144287109375 +90460 0.22186279296875 +90461 0.003997802734375 +90462 -0.22100830078125 +90463 -0.42449951171875 +90464 -0.579833984375 +90465 -0.641876220703125 +90466 -0.6177978515625 +90467 -0.575531005859375 +90468 -0.526336669921875 +90469 -0.42645263671875 +90470 -0.2581787109375 +90471 -0.068695068359375 +90472 0.09222412109375 +90473 0.232147216796875 +90474 0.3509521484375 +90475 0.410064697265625 +90476 0.372955322265625 +90477 0.2554931640625 +90478 0.10711669921875 +90479 -0.052886962890625 +90480 -0.186279296875 +90481 -0.23291015625 +90482 -0.209442138671875 +90483 -0.174163818359375 +90484 -0.126739501953125 +90485 -0.048126220703125 +90486 0.0426025390625 +90487 0.10748291015625 +90488 0.1409912109375 +90489 0.19708251953125 +90490 0.273651123046875 +90491 0.31768798828125 +90492 0.341094970703125 +90493 0.368011474609375 +90494 0.37249755859375 +90495 0.30072021484375 +90496 0.1517333984375 +90497 -0.01470947265625 +90498 -0.1883544921875 +90499 -0.372711181640625 +90500 -0.51397705078125 +90501 -0.57177734375 +90502 -0.53948974609375 +90503 -0.43511962890625 +90504 -0.2962646484375 +90505 -0.161102294921875 +90506 -0.0435791015625 +90507 0.060394287109375 +90508 0.13665771484375 +90509 0.170135498046875 +90510 0.16552734375 +90511 0.15728759765625 +90512 0.150787353515625 +90513 0.12200927734375 +90514 0.080108642578125 +90515 0.05126953125 +90516 0.062896728515625 +90517 0.09271240234375 +90518 0.092987060546875 +90519 0.07855224609375 +90520 0.06427001953125 +90521 0.0347900390625 +90522 -0.01171875 +90523 -0.056060791015625 +90524 -0.055511474609375 +90525 -0.010467529296875 +90526 0.02508544921875 +90527 0.025665283203125 +90528 0.017333984375 +90529 0.00189208984375 +90530 -0.03173828125 +90531 -0.071502685546875 +90532 -0.13543701171875 +90533 -0.219970703125 +90534 -0.300506591796875 +90535 -0.376312255859375 +90536 -0.416107177734375 +90537 -0.371124267578125 +90538 -0.242279052734375 +90539 -0.069732666015625 +90540 0.125640869140625 +90541 0.31268310546875 +90542 0.45501708984375 +90543 0.554779052734375 +90544 0.61065673828125 +90545 0.610931396484375 +90546 0.531463623046875 +90547 0.3883056640625 +90548 0.23468017578125 +90549 0.095245361328125 +90550 -0.00396728515625 +90551 -0.04852294921875 +90552 -0.055145263671875 +90553 -0.0758056640625 +90554 -0.138702392578125 +90555 -0.209197998046875 +90556 -0.289031982421875 +90557 -0.37884521484375 +90558 -0.456329345703125 +90559 -0.51641845703125 +90560 -0.519287109375 +90561 -0.458251953125 +90562 -0.384796142578125 +90563 -0.323699951171875 +90564 -0.269287109375 +90565 -0.1951904296875 +90566 -0.100006103515625 +90567 -0.01055908203125 +90568 0.1033935546875 +90569 0.24908447265625 +90570 0.373199462890625 +90571 0.45806884765625 +90572 0.511474609375 +90573 0.565399169921875 +90574 0.61138916015625 +90575 0.5897216796875 +90576 0.4906005859375 +90577 0.33148193359375 +90578 0.147796630859375 +90579 -0.01873779296875 +90580 -0.140289306640625 +90581 -0.191986083984375 +90582 -0.184295654296875 +90583 -0.161834716796875 +90584 -0.166595458984375 +90585 -0.19390869140625 +90586 -0.22442626953125 +90587 -0.279754638671875 +90588 -0.3389892578125 +90589 -0.3543701171875 +90590 -0.348175048828125 +90591 -0.32598876953125 +90592 -0.2581787109375 +90593 -0.139801025390625 +90594 0.014617919921875 +90595 0.144378662109375 +90596 0.221038818359375 +90597 0.27069091796875 +90598 0.294036865234375 +90599 0.311767578125 +90600 0.339141845703125 +90601 0.360260009765625 +90602 0.360504150390625 +90603 0.308380126953125 +90604 0.18170166015625 +90605 0.0047607421875 +90606 -0.17559814453125 +90607 -0.3143310546875 +90608 -0.36785888671875 +90609 -0.36248779296875 +90610 -0.343536376953125 +90611 -0.3018798828125 +90612 -0.231414794921875 +90613 -0.117645263671875 +90614 0.007049560546875 +90615 0.087982177734375 +90616 0.13946533203125 +90617 0.17425537109375 +90618 0.188201904296875 +90619 0.171234130859375 +90620 0.118438720703125 +90621 0.05706787109375 +90622 -0.010711669921875 +90623 -0.0914306640625 +90624 -0.162322998046875 +90625 -0.194549560546875 +90626 -0.1492919921875 +90627 -0.02166748046875 +90628 0.124053955078125 +90629 0.211151123046875 +90630 0.240447998046875 +90631 0.242218017578125 +90632 0.2257080078125 +90633 0.194366455078125 +90634 0.115509033203125 +90635 0.0128173828125 +90636 -0.053802490234375 +90637 -0.110626220703125 +90638 -0.199493408203125 +90639 -0.29437255859375 +90640 -0.33221435546875 +90641 -0.27972412109375 +90642 -0.185333251953125 +90643 -0.128204345703125 +90644 -0.115692138671875 +90645 -0.116455078125 +90646 -0.105926513671875 +90647 -0.053955078125 +90648 0.048797607421875 +90649 0.157318115234375 +90650 0.212005615234375 +90651 0.218475341796875 +90652 0.23724365234375 +90653 0.30535888671875 +90654 0.38128662109375 +90655 0.404449462890625 +90656 0.3944091796875 +90657 0.3885498046875 +90658 0.362640380859375 +90659 0.27362060546875 +90660 0.11712646484375 +90661 -0.054901123046875 +90662 -0.19085693359375 +90663 -0.28570556640625 +90664 -0.339263916015625 +90665 -0.3775634765625 +90666 -0.445709228515625 +90667 -0.535064697265625 +90668 -0.629058837890625 +90669 -0.697601318359375 +90670 -0.70391845703125 +90671 -0.6424560546875 +90672 -0.491241455078125 +90673 -0.265716552734375 +90674 -0.023712158203125 +90675 0.201751708984375 +90676 0.375823974609375 +90677 0.485076904296875 +90678 0.56884765625 +90679 0.634765625 +90680 0.63763427734375 +90681 0.5660400390625 +90682 0.4720458984375 +90683 0.40692138671875 +90684 0.3778076171875 +90685 0.376953125 +90686 0.371978759765625 +90687 0.313140869140625 +90688 0.184417724609375 +90689 0.011199951171875 +90690 -0.171051025390625 +90691 -0.33740234375 +90692 -0.47198486328125 +90693 -0.560394287109375 +90694 -0.58056640625 +90695 -0.54754638671875 +90696 -0.508575439453125 +90697 -0.459503173828125 +90698 -0.394378662109375 +90699 -0.35260009765625 +90700 -0.31170654296875 +90701 -0.197418212890625 +90702 -0.007965087890625 +90703 0.207489013671875 +90704 0.409210205078125 +90705 0.57208251953125 +90706 0.66595458984375 +90707 0.65875244140625 +90708 0.56744384765625 +90709 0.431396484375 +90710 0.29443359375 +90711 0.182464599609375 +90712 0.06365966796875 +90713 -0.075958251953125 +90714 -0.189422607421875 +90715 -0.271942138671875 +90716 -0.342529296875 +90717 -0.364166259765625 +90718 -0.327239990234375 +90719 -0.2769775390625 +90720 -0.253692626953125 +90721 -0.24365234375 +90722 -0.1983642578125 +90723 -0.116241455078125 +90724 -0.036834716796875 +90725 0.034881591796875 +90726 0.09124755859375 +90727 0.10888671875 +90728 0.125518798828125 +90729 0.15771484375 +90730 0.17828369140625 +90731 0.17108154296875 +90732 0.129974365234375 +90733 0.082427978515625 +90734 0.027679443359375 +90735 -0.065643310546875 +90736 -0.15936279296875 +90737 -0.21307373046875 +90738 -0.234649658203125 +90739 -0.2001953125 +90740 -0.119171142578125 +90741 -0.024749755859375 +90742 0.085784912109375 +90743 0.178131103515625 +90744 0.215576171875 +90745 0.211456298828125 +90746 0.17523193359375 +90747 0.128753662109375 +90748 0.1019287109375 +90749 0.0743408203125 +90750 0.04327392578125 +90751 0.038177490234375 +90752 0.076263427734375 +90753 0.14105224609375 +90754 0.186431884765625 +90755 0.188812255859375 +90756 0.1390380859375 +90757 0.041778564453125 +90758 -0.079437255859375 +90759 -0.219390869140625 +90760 -0.367828369140625 +90761 -0.494873046875 +90762 -0.556243896484375 +90763 -0.508697509765625 +90764 -0.3756103515625 +90765 -0.218902587890625 +90766 -0.063751220703125 +90767 0.091552734375 +90768 0.23602294921875 +90769 0.342987060546875 +90770 0.39520263671875 +90771 0.389373779296875 +90772 0.324249267578125 +90773 0.224090576171875 +90774 0.124267578125 +90775 0.037078857421875 +90776 -0.010101318359375 +90777 -0.019439697265625 +90778 -0.022796630859375 +90779 -0.001556396484375 +90780 0.056304931640625 +90781 0.106719970703125 +90782 0.096893310546875 +90783 0.042694091796875 +90784 -0.018035888671875 +90785 -0.07586669921875 +90786 -0.11944580078125 +90787 -0.15972900390625 +90788 -0.202606201171875 +90789 -0.24859619140625 +90790 -0.30517578125 +90791 -0.36212158203125 +90792 -0.39141845703125 +90793 -0.35528564453125 +90794 -0.249969482421875 +90795 -0.092864990234375 +90796 0.08905029296875 +90797 0.2352294921875 +90798 0.318817138671875 +90799 0.358642578125 +90800 0.347747802734375 +90801 0.28564453125 +90802 0.223175048828125 +90803 0.196746826171875 +90804 0.179840087890625 +90805 0.155548095703125 +90806 0.151214599609375 +90807 0.156951904296875 +90808 0.13177490234375 +90809 0.100799560546875 +90810 0.087127685546875 +90811 0.05487060546875 +90812 -0.009002685546875 +90813 -0.10400390625 +90814 -0.229400634765625 +90815 -0.35552978515625 +90816 -0.441925048828125 +90817 -0.473846435546875 +90818 -0.464813232421875 +90819 -0.419097900390625 +90820 -0.334320068359375 +90821 -0.227935791015625 +90822 -0.12347412109375 +90823 -0.02764892578125 +90824 0.077667236328125 +90825 0.2132568359375 +90826 0.38885498046875 +90827 0.582794189453125 +90828 0.734039306640625 +90829 0.800140380859375 +90830 0.7783203125 +90831 0.6651611328125 +90832 0.45965576171875 +90833 0.199188232421875 +90834 -0.050689697265625 +90835 -0.23297119140625 +90836 -0.33013916015625 +90837 -0.368408203125 +90838 -0.378936767578125 +90839 -0.376983642578125 +90840 -0.37969970703125 +90841 -0.391510009765625 +90842 -0.385345458984375 +90843 -0.3419189453125 +90844 -0.28289794921875 +90845 -0.251617431640625 +90846 -0.266143798828125 +90847 -0.273345947265625 +90848 -0.216796875 +90849 -0.128265380859375 +90850 -0.068145751953125 +90851 -0.0430908203125 +90852 -0.024444580078125 +90853 0.020721435546875 +90854 0.124481201171875 +90855 0.25787353515625 +90856 0.379119873046875 +90857 0.47991943359375 +90858 0.5281982421875 +90859 0.511138916015625 +90860 0.456207275390625 +90861 0.407470703125 +90862 0.383758544921875 +90863 0.35687255859375 +90864 0.31182861328125 +90865 0.250885009765625 +90866 0.1654052734375 +90867 0.035247802734375 +90868 -0.142059326171875 +90869 -0.33563232421875 +90870 -0.5345458984375 +90871 -0.72186279296875 +90872 -0.836669921875 +90873 -0.8326416015625 +90874 -0.7296142578125 +90875 -0.582550048828125 +90876 -0.440093994140625 +90877 -0.324310302734375 +90878 -0.20147705078125 +90879 -0.044647216796875 +90880 0.103973388671875 +90881 0.202392578125 +90882 0.264495849609375 +90883 0.338897705078125 +90884 0.443817138671875 +90885 0.545074462890625 +90886 0.6173095703125 +90887 0.6524658203125 +90888 0.66339111328125 +90889 0.6561279296875 +90890 0.606781005859375 +90891 0.501190185546875 +90892 0.352783203125 +90893 0.176544189453125 +90894 -0.034820556640625 +90895 -0.258209228515625 +90896 -0.44244384765625 +90897 -0.5753173828125 +90898 -0.65203857421875 +90899 -0.641632080078125 +90900 -0.562164306640625 +90901 -0.458038330078125 +90902 -0.350555419921875 +90903 -0.260528564453125 +90904 -0.192108154296875 +90905 -0.141937255859375 +90906 -0.1021728515625 +90907 -0.062896728515625 +90908 -0.011932373046875 +90909 0.062835693359375 +90910 0.148712158203125 +90911 0.241729736328125 +90912 0.34912109375 +90913 0.457305908203125 +90914 0.54388427734375 +90915 0.5728759765625 +90916 0.506591796875 +90917 0.351226806640625 +90918 0.146514892578125 +90919 -0.05523681640625 +90920 -0.21624755859375 +90921 -0.334930419921875 +90922 -0.402984619140625 +90923 -0.4412841796875 +90924 -0.49578857421875 +90925 -0.5601806640625 +90926 -0.600738525390625 +90927 -0.584228515625 +90928 -0.47930908203125 +90929 -0.27935791015625 +90930 -0.0089111328125 +90931 0.268798828125 +90932 0.482818603515625 +90933 0.60369873046875 +90934 0.650421142578125 +90935 0.66400146484375 +90936 0.6414794921875 +90937 0.572540283203125 +90938 0.498138427734375 +90939 0.439453125 +90940 0.375518798828125 +90941 0.274505615234375 +90942 0.1087646484375 +90943 -0.099395751953125 +90944 -0.3182373046875 +90945 -0.5489501953125 +90946 -0.7738037109375 +90947 -0.86383056640625 +90948 -0.870391845703125 +90949 -0.86895751953125 +90950 -0.861053466796875 +90951 -0.765869140625 +90952 -0.5301513671875 +90953 -0.214691162109375 +90954 0.137359619140625 +90955 0.474822998046875 +90956 0.76239013671875 +90957 0.867462158203125 +90958 0.870361328125 +90959 0.86480712890625 +90960 0.831817626953125 +90961 0.677581787109375 +90962 0.495880126953125 +90963 0.30767822265625 +90964 0.116180419921875 +90965 -0.110748291015625 +90966 -0.381805419921875 +90967 -0.6572265625 +90968 -0.857421875 +90969 -0.870391845703125 +90970 -0.870391845703125 +90971 -0.86444091796875 +90972 -0.85723876953125 +90973 -0.790008544921875 +90974 -0.62847900390625 +90975 -0.3956298828125 +90976 -0.126708984375 +90977 0.150115966796875 +90978 0.424041748046875 +90979 0.670623779296875 +90980 0.854522705078125 +90981 0.866485595703125 +90982 0.86920166015625 +90983 0.8653564453125 +90984 0.857147216796875 +90985 0.766845703125 +90986 0.628509521484375 +90987 0.462127685546875 +90988 0.297210693359375 +90989 0.14862060546875 +90990 -0.00537109375 +90991 -0.15753173828125 +90992 -0.31304931640625 +90993 -0.48876953125 +90994 -0.6416015625 +90995 -0.751373291015625 +90996 -0.84619140625 +90997 -0.861297607421875 +90998 -0.863250732421875 +90999 -0.856597900390625 +91000 -0.7498779296875 +91001 -0.624542236328125 +91002 -0.47808837890625 +91003 -0.253387451171875 +91004 0.003692626953125 +91005 0.2257080078125 +91006 0.427154541015625 +91007 0.643218994140625 +91008 0.855926513671875 +91009 0.870361328125 +91010 0.870361328125 +91011 0.862762451171875 +91012 0.79669189453125 +91013 0.595794677734375 +91014 0.362152099609375 +91015 0.1270751953125 +91016 -0.086944580078125 +91017 -0.2784423828125 +91018 -0.484832763671875 +91019 -0.729583740234375 +91020 -0.86688232421875 +91021 -0.870391845703125 +91022 -0.86859130859375 +91023 -0.86279296875 +91024 -0.817962646484375 +91025 -0.6116943359375 +91026 -0.3128662109375 +91027 0.039398193359375 +91028 0.422821044921875 +91029 0.805145263671875 +91030 0.870361328125 +91031 0.870361328125 +91032 0.860015869140625 +91033 0.727935791015625 +91034 0.48114013671875 +91035 0.2059326171875 +91036 -0.06103515625 +91037 -0.29913330078125 +91038 -0.516204833984375 +91039 -0.7252197265625 +91040 -0.85980224609375 +91041 -0.870391845703125 +91042 -0.870391845703125 +91043 -0.858062744140625 +91044 -0.673004150390625 +91045 -0.42694091796875 +91046 -0.2100830078125 +91047 -0.0362548828125 +91048 0.10943603515625 +91049 0.23516845703125 +91050 0.373687744140625 +91051 0.517791748046875 +91052 0.602783203125 +91053 0.635711669921875 +91054 0.655181884765625 +91055 0.65948486328125 +91056 0.651275634765625 +91057 0.61846923828125 +91058 0.53753662109375 +91059 0.404144287109375 +91060 0.22186279296875 +91061 0.003997802734375 +91062 -0.22100830078125 +91063 -0.42449951171875 +91064 -0.579833984375 +91065 -0.641876220703125 +91066 -0.6177978515625 +91067 -0.575531005859375 +91068 -0.526336669921875 +91069 -0.42645263671875 +91070 -0.2581787109375 +91071 -0.068695068359375 +91072 0.09222412109375 +91073 0.232147216796875 +91074 0.3509521484375 +91075 0.410064697265625 +91076 0.372955322265625 +91077 0.2554931640625 +91078 0.10711669921875 +91079 -0.052886962890625 +91080 -0.186279296875 +91081 -0.23291015625 +91082 -0.209442138671875 +91083 -0.174163818359375 +91084 -0.126739501953125 +91085 -0.048126220703125 +91086 0.0426025390625 +91087 0.10748291015625 +91088 0.1409912109375 +91089 0.19708251953125 +91090 0.273651123046875 +91091 0.31768798828125 +91092 0.341094970703125 +91093 0.368011474609375 +91094 0.37249755859375 +91095 0.30072021484375 +91096 0.1517333984375 +91097 -0.01470947265625 +91098 -0.1883544921875 +91099 -0.372711181640625 +91100 -0.51397705078125 +91101 -0.57177734375 +91102 -0.53948974609375 +91103 -0.43511962890625 +91104 -0.2962646484375 +91105 -0.161102294921875 +91106 -0.0435791015625 +91107 0.060394287109375 +91108 0.13665771484375 +91109 0.170135498046875 +91110 0.16552734375 +91111 0.15728759765625 +91112 0.150787353515625 +91113 0.12200927734375 +91114 0.080108642578125 +91115 0.05126953125 +91116 0.062896728515625 +91117 0.09271240234375 +91118 0.092987060546875 +91119 0.07855224609375 +91120 0.06427001953125 +91121 0.0347900390625 +91122 -0.01171875 +91123 -0.056060791015625 +91124 -0.055511474609375 +91125 -0.010467529296875 +91126 0.02508544921875 +91127 0.025665283203125 +91128 0.017333984375 +91129 0.00189208984375 +91130 -0.03173828125 +91131 -0.071502685546875 +91132 -0.13543701171875 +91133 -0.219970703125 +91134 -0.300506591796875 +91135 -0.376312255859375 +91136 -0.416107177734375 +91137 -0.371124267578125 +91138 -0.242279052734375 +91139 -0.069732666015625 +91140 0.125640869140625 +91141 0.31268310546875 +91142 0.45501708984375 +91143 0.554779052734375 +91144 0.61065673828125 +91145 0.610931396484375 +91146 0.531463623046875 +91147 0.3883056640625 +91148 0.23468017578125 +91149 0.095245361328125 +91150 -0.00396728515625 +91151 -0.04852294921875 +91152 -0.055145263671875 +91153 -0.0758056640625 +91154 -0.138702392578125 +91155 -0.209197998046875 +91156 -0.289031982421875 +91157 -0.37884521484375 +91158 -0.456329345703125 +91159 -0.51641845703125 +91160 -0.519287109375 +91161 -0.458251953125 +91162 -0.384796142578125 +91163 -0.323699951171875 +91164 -0.269287109375 +91165 -0.1951904296875 +91166 -0.100006103515625 +91167 -0.01055908203125 +91168 0.1033935546875 +91169 0.24908447265625 +91170 0.373199462890625 +91171 0.45806884765625 +91172 0.511474609375 +91173 0.565399169921875 +91174 0.61138916015625 +91175 0.5897216796875 +91176 0.4906005859375 +91177 0.33148193359375 +91178 0.147796630859375 +91179 -0.01873779296875 +91180 -0.140289306640625 +91181 -0.191986083984375 +91182 -0.184295654296875 +91183 -0.161834716796875 +91184 -0.166595458984375 +91185 -0.19390869140625 +91186 -0.22442626953125 +91187 -0.279754638671875 +91188 -0.3389892578125 +91189 -0.3543701171875 +91190 -0.348175048828125 +91191 -0.32598876953125 +91192 -0.2581787109375 +91193 -0.139801025390625 +91194 0.014617919921875 +91195 0.144378662109375 +91196 0.221038818359375 +91197 0.27069091796875 +91198 0.294036865234375 +91199 0.311767578125 +91200 0.339141845703125 +91201 0.360260009765625 +91202 0.360504150390625 +91203 0.308380126953125 +91204 0.18170166015625 +91205 0.0047607421875 +91206 -0.17559814453125 +91207 -0.3143310546875 +91208 -0.36785888671875 +91209 -0.36248779296875 +91210 -0.343536376953125 +91211 -0.3018798828125 +91212 -0.231414794921875 +91213 -0.117645263671875 +91214 0.007049560546875 +91215 0.087982177734375 +91216 0.13946533203125 +91217 0.17425537109375 +91218 0.188201904296875 +91219 0.171234130859375 +91220 0.118438720703125 +91221 0.05706787109375 +91222 -0.010711669921875 +91223 -0.0914306640625 +91224 -0.162322998046875 +91225 -0.194549560546875 +91226 -0.1492919921875 +91227 -0.02166748046875 +91228 0.124053955078125 +91229 0.211151123046875 +91230 0.240447998046875 +91231 0.242218017578125 +91232 0.2257080078125 +91233 0.194366455078125 +91234 0.115509033203125 +91235 0.0128173828125 +91236 -0.053802490234375 +91237 -0.110626220703125 +91238 -0.199493408203125 +91239 -0.29437255859375 +91240 -0.33221435546875 +91241 -0.27972412109375 +91242 -0.185333251953125 +91243 -0.128204345703125 +91244 -0.115692138671875 +91245 -0.116455078125 +91246 -0.105926513671875 +91247 -0.053955078125 +91248 0.048797607421875 +91249 0.157318115234375 +91250 0.212005615234375 +91251 0.218475341796875 +91252 0.23724365234375 +91253 0.30535888671875 +91254 0.38128662109375 +91255 0.404449462890625 +91256 0.3944091796875 +91257 0.3885498046875 +91258 0.362640380859375 +91259 0.27362060546875 +91260 0.11712646484375 +91261 -0.054901123046875 +91262 -0.19085693359375 +91263 -0.28570556640625 +91264 -0.339263916015625 +91265 -0.3775634765625 +91266 -0.445709228515625 +91267 -0.535064697265625 +91268 -0.629058837890625 +91269 -0.697601318359375 +91270 -0.70391845703125 +91271 -0.6424560546875 +91272 -0.491241455078125 +91273 -0.265716552734375 +91274 -0.023712158203125 +91275 0.201751708984375 +91276 0.375823974609375 +91277 0.485076904296875 +91278 0.56884765625 +91279 0.634765625 +91280 0.63763427734375 +91281 0.5660400390625 +91282 0.4720458984375 +91283 0.40692138671875 +91284 0.3778076171875 +91285 0.376953125 +91286 0.371978759765625 +91287 0.313140869140625 +91288 0.184417724609375 +91289 0.011199951171875 +91290 -0.171051025390625 +91291 -0.33740234375 +91292 -0.47198486328125 +91293 -0.560394287109375 +91294 -0.58056640625 +91295 -0.54754638671875 +91296 -0.508575439453125 +91297 -0.459503173828125 +91298 -0.394378662109375 +91299 -0.35260009765625 +91300 -0.31170654296875 +91301 -0.197418212890625 +91302 -0.007965087890625 +91303 0.207489013671875 +91304 0.409210205078125 +91305 0.57208251953125 +91306 0.66595458984375 +91307 0.65875244140625 +91308 0.56744384765625 +91309 0.431396484375 +91310 0.29443359375 +91311 0.182464599609375 +91312 0.06365966796875 +91313 -0.075958251953125 +91314 -0.189422607421875 +91315 -0.271942138671875 +91316 -0.342529296875 +91317 -0.364166259765625 +91318 -0.327239990234375 +91319 -0.2769775390625 +91320 -0.253692626953125 +91321 -0.24365234375 +91322 -0.1983642578125 +91323 -0.116241455078125 +91324 -0.036834716796875 +91325 0.034881591796875 +91326 0.09124755859375 +91327 0.10888671875 +91328 0.125518798828125 +91329 0.15771484375 +91330 0.17828369140625 +91331 0.17108154296875 +91332 0.129974365234375 +91333 0.082427978515625 +91334 0.027679443359375 +91335 -0.065643310546875 +91336 -0.15936279296875 +91337 -0.21307373046875 +91338 -0.234649658203125 +91339 -0.2001953125 +91340 -0.119171142578125 +91341 -0.024749755859375 +91342 0.085784912109375 +91343 0.178131103515625 +91344 0.215576171875 +91345 0.211456298828125 +91346 0.17523193359375 +91347 0.128753662109375 +91348 0.1019287109375 +91349 0.0743408203125 +91350 0.04327392578125 +91351 0.038177490234375 +91352 0.076263427734375 +91353 0.14105224609375 +91354 0.186431884765625 +91355 0.188812255859375 +91356 0.1390380859375 +91357 0.041778564453125 +91358 -0.079437255859375 +91359 -0.219390869140625 +91360 -0.367828369140625 +91361 -0.494873046875 +91362 -0.556243896484375 +91363 -0.508697509765625 +91364 -0.3756103515625 +91365 -0.218902587890625 +91366 -0.063751220703125 +91367 0.091552734375 +91368 0.23602294921875 +91369 0.342987060546875 +91370 0.39520263671875 +91371 0.389373779296875 +91372 0.324249267578125 +91373 0.224090576171875 +91374 0.124267578125 +91375 0.037078857421875 +91376 -0.010101318359375 +91377 -0.019439697265625 +91378 -0.022796630859375 +91379 -0.001556396484375 +91380 0.056304931640625 +91381 0.106719970703125 +91382 0.096893310546875 +91383 0.042694091796875 +91384 -0.018035888671875 +91385 -0.07586669921875 +91386 -0.11944580078125 +91387 -0.15972900390625 +91388 -0.202606201171875 +91389 -0.24859619140625 +91390 -0.30517578125 +91391 -0.36212158203125 +91392 -0.39141845703125 +91393 -0.35528564453125 +91394 -0.249969482421875 +91395 -0.092864990234375 +91396 0.08905029296875 +91397 0.2352294921875 +91398 0.318817138671875 +91399 0.358642578125 +91400 0.347747802734375 +91401 0.28564453125 +91402 0.223175048828125 +91403 0.196746826171875 +91404 0.179840087890625 +91405 0.155548095703125 +91406 0.151214599609375 +91407 0.156951904296875 +91408 0.13177490234375 +91409 0.100799560546875 +91410 0.087127685546875 +91411 0.05487060546875 +91412 -0.009002685546875 +91413 -0.10400390625 +91414 -0.229400634765625 +91415 -0.35552978515625 +91416 -0.441925048828125 +91417 -0.473846435546875 +91418 -0.464813232421875 +91419 -0.419097900390625 +91420 -0.334320068359375 +91421 -0.227935791015625 +91422 -0.12347412109375 +91423 -0.02764892578125 +91424 0.077667236328125 +91425 0.2132568359375 +91426 0.38885498046875 +91427 0.582794189453125 +91428 0.734039306640625 +91429 0.800140380859375 +91430 0.7783203125 +91431 0.6651611328125 +91432 0.45965576171875 +91433 0.199188232421875 +91434 -0.050689697265625 +91435 -0.23297119140625 +91436 -0.33013916015625 +91437 -0.368408203125 +91438 -0.378936767578125 +91439 -0.376983642578125 +91440 -0.37969970703125 +91441 -0.391510009765625 +91442 -0.385345458984375 +91443 -0.3419189453125 +91444 -0.28289794921875 +91445 -0.251617431640625 +91446 -0.266143798828125 +91447 -0.273345947265625 +91448 -0.216796875 +91449 -0.128265380859375 +91450 -0.068145751953125 +91451 -0.0430908203125 +91452 -0.024444580078125 +91453 0.020721435546875 +91454 0.124481201171875 +91455 0.25787353515625 +91456 0.379119873046875 +91457 0.47991943359375 +91458 0.5281982421875 +91459 0.511138916015625 +91460 0.456207275390625 +91461 0.407470703125 +91462 0.383758544921875 +91463 0.35687255859375 +91464 0.31182861328125 +91465 0.250885009765625 +91466 0.1654052734375 +91467 0.035247802734375 +91468 -0.142059326171875 +91469 -0.33563232421875 +91470 -0.5345458984375 +91471 -0.72186279296875 +91472 -0.836669921875 +91473 -0.8326416015625 +91474 -0.7296142578125 +91475 -0.582550048828125 +91476 -0.440093994140625 +91477 -0.324310302734375 +91478 -0.20147705078125 +91479 -0.044647216796875 +91480 0.103973388671875 +91481 0.202392578125 +91482 0.264495849609375 +91483 0.338897705078125 +91484 0.443817138671875 +91485 0.545074462890625 +91486 0.6173095703125 +91487 0.6524658203125 +91488 0.66339111328125 +91489 0.6561279296875 +91490 0.606781005859375 +91491 0.501190185546875 +91492 0.352783203125 +91493 0.176544189453125 +91494 -0.034820556640625 +91495 -0.258209228515625 +91496 -0.44244384765625 +91497 -0.5753173828125 +91498 -0.65203857421875 +91499 -0.641632080078125 +91500 -0.562164306640625 +91501 -0.458038330078125 +91502 -0.350555419921875 +91503 -0.260528564453125 +91504 -0.192108154296875 +91505 -0.141937255859375 +91506 -0.1021728515625 +91507 -0.062896728515625 +91508 -0.011932373046875 +91509 0.062835693359375 +91510 0.148712158203125 +91511 0.241729736328125 +91512 0.34912109375 +91513 0.457305908203125 +91514 0.54388427734375 +91515 0.5728759765625 +91516 0.506591796875 +91517 0.351226806640625 +91518 0.146514892578125 +91519 -0.05523681640625 +91520 -0.21624755859375 +91521 -0.334930419921875 +91522 -0.402984619140625 +91523 -0.4412841796875 +91524 -0.49578857421875 +91525 -0.5601806640625 +91526 -0.600738525390625 +91527 -0.584228515625 +91528 -0.47930908203125 +91529 -0.27935791015625 +91530 -0.0089111328125 +91531 0.268798828125 +91532 0.482818603515625 +91533 0.60369873046875 +91534 0.650421142578125 +91535 0.66400146484375 +91536 0.6414794921875 +91537 0.572540283203125 +91538 0.498138427734375 +91539 0.439453125 +91540 0.375518798828125 +91541 0.274505615234375 +91542 0.1087646484375 +91543 -0.099395751953125 +91544 -0.3182373046875 +91545 -0.5489501953125 +91546 -0.7738037109375 +91547 -0.86383056640625 +91548 -0.870391845703125 +91549 -0.86895751953125 +91550 -0.861053466796875 +91551 -0.765869140625 +91552 -0.5301513671875 +91553 -0.214691162109375 +91554 0.137359619140625 +91555 0.474822998046875 +91556 0.76239013671875 +91557 0.867462158203125 +91558 0.870361328125 +91559 0.86480712890625 +91560 0.831817626953125 +91561 0.677581787109375 +91562 0.495880126953125 +91563 0.30767822265625 +91564 0.116180419921875 +91565 -0.110748291015625 +91566 -0.381805419921875 +91567 -0.6572265625 +91568 -0.857421875 +91569 -0.870391845703125 +91570 -0.870391845703125 +91571 -0.86444091796875 +91572 -0.85723876953125 +91573 -0.790008544921875 +91574 -0.62847900390625 +91575 -0.3956298828125 +91576 -0.126708984375 +91577 0.150115966796875 +91578 0.424041748046875 +91579 0.670623779296875 +91580 0.854522705078125 +91581 0.866485595703125 +91582 0.86920166015625 +91583 0.8653564453125 +91584 0.857147216796875 +91585 0.766845703125 +91586 0.628509521484375 +91587 0.462127685546875 +91588 0.297210693359375 +91589 0.14862060546875 +91590 -0.00537109375 +91591 -0.15753173828125 +91592 -0.31304931640625 +91593 -0.48876953125 +91594 -0.6416015625 +91595 -0.751373291015625 +91596 -0.84619140625 +91597 -0.861297607421875 +91598 -0.863250732421875 +91599 -0.856597900390625 +91600 -0.7498779296875 +91601 -0.624542236328125 +91602 -0.47808837890625 +91603 -0.253387451171875 +91604 0.003692626953125 +91605 0.2257080078125 +91606 0.427154541015625 +91607 0.643218994140625 +91608 0.855926513671875 +91609 0.870361328125 +91610 0.870361328125 +91611 0.862762451171875 +91612 0.79669189453125 +91613 0.595794677734375 +91614 0.362152099609375 +91615 0.1270751953125 +91616 -0.086944580078125 +91617 -0.2784423828125 +91618 -0.484832763671875 +91619 -0.729583740234375 +91620 -0.86688232421875 +91621 -0.870391845703125 +91622 -0.86859130859375 +91623 -0.86279296875 +91624 -0.817962646484375 +91625 -0.6116943359375 +91626 -0.3128662109375 +91627 0.039398193359375 +91628 0.422821044921875 +91629 0.805145263671875 +91630 0.870361328125 +91631 0.870361328125 +91632 0.860015869140625 +91633 0.727935791015625 +91634 0.48114013671875 +91635 0.2059326171875 +91636 -0.06103515625 +91637 -0.29913330078125 +91638 -0.516204833984375 +91639 -0.7252197265625 +91640 -0.85980224609375 +91641 -0.870391845703125 +91642 -0.870391845703125 +91643 -0.858062744140625 +91644 -0.673004150390625 +91645 -0.42694091796875 +91646 -0.2100830078125 +91647 -0.0362548828125 +91648 0.10943603515625 +91649 0.23516845703125 +91650 0.373687744140625 +91651 0.517791748046875 +91652 0.602783203125 +91653 0.635711669921875 +91654 0.655181884765625 +91655 0.65948486328125 +91656 0.651275634765625 +91657 0.61846923828125 +91658 0.53753662109375 +91659 0.404144287109375 +91660 0.22186279296875 +91661 0.003997802734375 +91662 -0.22100830078125 +91663 -0.42449951171875 +91664 -0.579833984375 +91665 -0.641876220703125 +91666 -0.6177978515625 +91667 -0.575531005859375 +91668 -0.526336669921875 +91669 -0.42645263671875 +91670 -0.2581787109375 +91671 -0.068695068359375 +91672 0.09222412109375 +91673 0.232147216796875 +91674 0.3509521484375 +91675 0.410064697265625 +91676 0.372955322265625 +91677 0.2554931640625 +91678 0.10711669921875 +91679 -0.052886962890625 +91680 -0.186279296875 +91681 -0.23291015625 +91682 -0.209442138671875 +91683 -0.174163818359375 +91684 -0.126739501953125 +91685 -0.048126220703125 +91686 0.0426025390625 +91687 0.10748291015625 +91688 0.1409912109375 +91689 0.19708251953125 +91690 0.273651123046875 +91691 0.31768798828125 +91692 0.341094970703125 +91693 0.368011474609375 +91694 0.37249755859375 +91695 0.30072021484375 +91696 0.1517333984375 +91697 -0.01470947265625 +91698 -0.1883544921875 +91699 -0.372711181640625 +91700 -0.51397705078125 +91701 -0.57177734375 +91702 -0.53948974609375 +91703 -0.43511962890625 +91704 -0.2962646484375 +91705 -0.161102294921875 +91706 -0.0435791015625 +91707 0.060394287109375 +91708 0.13665771484375 +91709 0.170135498046875 +91710 0.16552734375 +91711 0.15728759765625 +91712 0.150787353515625 +91713 0.12200927734375 +91714 0.080108642578125 +91715 0.05126953125 +91716 0.062896728515625 +91717 0.09271240234375 +91718 0.092987060546875 +91719 0.07855224609375 +91720 0.06427001953125 +91721 0.0347900390625 +91722 -0.01171875 +91723 -0.056060791015625 +91724 -0.055511474609375 +91725 -0.010467529296875 +91726 0.02508544921875 +91727 0.025665283203125 +91728 0.017333984375 +91729 0.00189208984375 +91730 -0.03173828125 +91731 -0.071502685546875 +91732 -0.13543701171875 +91733 -0.219970703125 +91734 -0.300506591796875 +91735 -0.376312255859375 +91736 -0.416107177734375 +91737 -0.371124267578125 +91738 -0.242279052734375 +91739 -0.069732666015625 +91740 0.125640869140625 +91741 0.31268310546875 +91742 0.45501708984375 +91743 0.554779052734375 +91744 0.61065673828125 +91745 0.610931396484375 +91746 0.531463623046875 +91747 0.3883056640625 +91748 0.23468017578125 +91749 0.095245361328125 +91750 -0.00396728515625 +91751 -0.04852294921875 +91752 -0.055145263671875 +91753 -0.0758056640625 +91754 -0.138702392578125 +91755 -0.209197998046875 +91756 -0.289031982421875 +91757 -0.37884521484375 +91758 -0.456329345703125 +91759 -0.51641845703125 +91760 -0.519287109375 +91761 -0.458251953125 +91762 -0.384796142578125 +91763 -0.323699951171875 +91764 -0.269287109375 +91765 -0.1951904296875 +91766 -0.100006103515625 +91767 -0.01055908203125 +91768 0.1033935546875 +91769 0.24908447265625 +91770 0.373199462890625 +91771 0.45806884765625 +91772 0.511474609375 +91773 0.565399169921875 +91774 0.61138916015625 +91775 0.5897216796875 +91776 0.4906005859375 +91777 0.33148193359375 +91778 0.147796630859375 +91779 -0.01873779296875 +91780 -0.140289306640625 +91781 -0.191986083984375 +91782 -0.184295654296875 +91783 -0.161834716796875 +91784 -0.166595458984375 +91785 -0.19390869140625 +91786 -0.22442626953125 +91787 -0.279754638671875 +91788 -0.3389892578125 +91789 -0.3543701171875 +91790 -0.348175048828125 +91791 -0.32598876953125 +91792 -0.2581787109375 +91793 -0.139801025390625 +91794 0.014617919921875 +91795 0.144378662109375 +91796 0.221038818359375 +91797 0.27069091796875 +91798 0.294036865234375 +91799 0.311767578125 +91800 0.339141845703125 +91801 0.360260009765625 +91802 0.360504150390625 +91803 0.308380126953125 +91804 0.18170166015625 +91805 0.0047607421875 +91806 -0.17559814453125 +91807 -0.3143310546875 +91808 -0.36785888671875 +91809 -0.36248779296875 +91810 -0.343536376953125 +91811 -0.3018798828125 +91812 -0.231414794921875 +91813 -0.117645263671875 +91814 0.007049560546875 +91815 0.087982177734375 +91816 0.13946533203125 +91817 0.17425537109375 +91818 0.188201904296875 +91819 0.171234130859375 +91820 0.118438720703125 +91821 0.05706787109375 +91822 -0.010711669921875 +91823 -0.0914306640625 +91824 -0.162322998046875 +91825 -0.194549560546875 +91826 -0.1492919921875 +91827 -0.02166748046875 +91828 0.124053955078125 +91829 0.211151123046875 +91830 0.240447998046875 +91831 0.242218017578125 +91832 0.2257080078125 +91833 0.194366455078125 +91834 0.115509033203125 +91835 0.0128173828125 +91836 -0.053802490234375 +91837 -0.110626220703125 +91838 -0.199493408203125 +91839 -0.29437255859375 +91840 -0.33221435546875 +91841 -0.27972412109375 +91842 -0.185333251953125 +91843 -0.128204345703125 +91844 -0.115692138671875 +91845 -0.116455078125 +91846 -0.105926513671875 +91847 -0.053955078125 +91848 0.048797607421875 +91849 0.157318115234375 +91850 0.212005615234375 +91851 0.218475341796875 +91852 0.23724365234375 +91853 0.30535888671875 +91854 0.38128662109375 +91855 0.404449462890625 +91856 0.3944091796875 +91857 0.3885498046875 +91858 0.362640380859375 +91859 0.27362060546875 +91860 0.11712646484375 +91861 -0.054901123046875 +91862 -0.19085693359375 +91863 -0.28570556640625 +91864 -0.339263916015625 +91865 -0.3775634765625 +91866 -0.445709228515625 +91867 -0.535064697265625 +91868 -0.629058837890625 +91869 -0.697601318359375 +91870 -0.70391845703125 +91871 -0.6424560546875 +91872 -0.491241455078125 +91873 -0.265716552734375 +91874 -0.023712158203125 +91875 0.201751708984375 +91876 0.375823974609375 +91877 0.485076904296875 +91878 0.56884765625 +91879 0.634765625 +91880 0.63763427734375 +91881 0.5660400390625 +91882 0.4720458984375 +91883 0.40692138671875 +91884 0.3778076171875 +91885 0.376953125 +91886 0.371978759765625 +91887 0.313140869140625 +91888 0.184417724609375 +91889 0.011199951171875 +91890 -0.171051025390625 +91891 -0.33740234375 +91892 -0.47198486328125 +91893 -0.560394287109375 +91894 -0.58056640625 +91895 -0.54754638671875 +91896 -0.508575439453125 +91897 -0.459503173828125 +91898 -0.394378662109375 +91899 -0.35260009765625 +91900 -0.31170654296875 +91901 -0.197418212890625 +91902 -0.007965087890625 +91903 0.207489013671875 +91904 0.409210205078125 +91905 0.57208251953125 +91906 0.66595458984375 +91907 0.65875244140625 +91908 0.56744384765625 +91909 0.431396484375 +91910 0.29443359375 +91911 0.182464599609375 +91912 0.06365966796875 +91913 -0.075958251953125 +91914 -0.189422607421875 +91915 -0.271942138671875 +91916 -0.342529296875 +91917 -0.364166259765625 +91918 -0.327239990234375 +91919 -0.2769775390625 +91920 -0.253692626953125 +91921 -0.24365234375 +91922 -0.1983642578125 +91923 -0.116241455078125 +91924 -0.036834716796875 +91925 0.034881591796875 +91926 0.09124755859375 +91927 0.10888671875 +91928 0.125518798828125 +91929 0.15771484375 +91930 0.17828369140625 +91931 0.17108154296875 +91932 0.129974365234375 +91933 0.082427978515625 +91934 0.027679443359375 +91935 -0.065643310546875 +91936 -0.15936279296875 +91937 -0.21307373046875 +91938 -0.234649658203125 +91939 -0.2001953125 +91940 -0.119171142578125 +91941 -0.024749755859375 +91942 0.085784912109375 +91943 0.178131103515625 +91944 0.215576171875 +91945 0.211456298828125 +91946 0.17523193359375 +91947 0.128753662109375 +91948 0.1019287109375 +91949 0.0743408203125 +91950 0.04327392578125 +91951 0.038177490234375 +91952 0.076263427734375 +91953 0.14105224609375 +91954 0.186431884765625 +91955 0.188812255859375 +91956 0.1390380859375 +91957 0.041778564453125 +91958 -0.079437255859375 +91959 -0.219390869140625 +91960 -0.367828369140625 +91961 -0.494873046875 +91962 -0.556243896484375 +91963 -0.508697509765625 +91964 -0.3756103515625 +91965 -0.218902587890625 +91966 -0.063751220703125 +91967 0.091552734375 +91968 0.23602294921875 +91969 0.342987060546875 +91970 0.39520263671875 +91971 0.389373779296875 +91972 0.324249267578125 +91973 0.224090576171875 +91974 0.124267578125 +91975 0.037078857421875 +91976 -0.010101318359375 +91977 -0.019439697265625 +91978 -0.022796630859375 +91979 -0.001556396484375 +91980 0.056304931640625 +91981 0.106719970703125 +91982 0.096893310546875 +91983 0.042694091796875 +91984 -0.018035888671875 +91985 -0.07586669921875 +91986 -0.11944580078125 +91987 -0.15972900390625 +91988 -0.202606201171875 +91989 -0.24859619140625 +91990 -0.30517578125 +91991 -0.36212158203125 +91992 -0.39141845703125 +91993 -0.35528564453125 +91994 -0.249969482421875 +91995 -0.092864990234375 +91996 0.08905029296875 +91997 0.2352294921875 +91998 0.318817138671875 +91999 0.358642578125 +92000 0.347747802734375 +92001 0.28564453125 +92002 0.223175048828125 +92003 0.196746826171875 +92004 0.179840087890625 +92005 0.155548095703125 +92006 0.151214599609375 +92007 0.156951904296875 +92008 0.13177490234375 +92009 0.100799560546875 +92010 0.087127685546875 +92011 0.05487060546875 +92012 -0.009002685546875 +92013 -0.10400390625 +92014 -0.229400634765625 +92015 -0.35552978515625 +92016 -0.441925048828125 +92017 -0.473846435546875 +92018 -0.464813232421875 +92019 -0.419097900390625 +92020 -0.334320068359375 +92021 -0.227935791015625 +92022 -0.12347412109375 +92023 -0.02764892578125 +92024 0.077667236328125 +92025 0.2132568359375 +92026 0.38885498046875 +92027 0.582794189453125 +92028 0.734039306640625 +92029 0.800140380859375 +92030 0.7783203125 +92031 0.6651611328125 +92032 0.45965576171875 +92033 0.199188232421875 +92034 -0.050689697265625 +92035 -0.23297119140625 +92036 -0.33013916015625 +92037 -0.368408203125 +92038 -0.378936767578125 +92039 -0.376983642578125 +92040 -0.37969970703125 +92041 -0.391510009765625 +92042 -0.385345458984375 +92043 -0.3419189453125 +92044 -0.28289794921875 +92045 -0.251617431640625 +92046 -0.266143798828125 +92047 -0.273345947265625 +92048 -0.216796875 +92049 -0.128265380859375 +92050 -0.068145751953125 +92051 -0.0430908203125 +92052 -0.024444580078125 +92053 0.020721435546875 +92054 0.124481201171875 +92055 0.25787353515625 +92056 0.379119873046875 +92057 0.47991943359375 +92058 0.5281982421875 +92059 0.511138916015625 +92060 0.456207275390625 +92061 0.407470703125 +92062 0.383758544921875 +92063 0.35687255859375 +92064 0.31182861328125 +92065 0.250885009765625 +92066 0.1654052734375 +92067 0.035247802734375 +92068 -0.142059326171875 +92069 -0.33563232421875 +92070 -0.5345458984375 +92071 -0.72186279296875 +92072 -0.836669921875 +92073 -0.8326416015625 +92074 -0.7296142578125 +92075 -0.582550048828125 +92076 -0.440093994140625 +92077 -0.324310302734375 +92078 -0.20147705078125 +92079 -0.044647216796875 +92080 0.103973388671875 +92081 0.202392578125 +92082 0.264495849609375 +92083 0.338897705078125 +92084 0.443817138671875 +92085 0.545074462890625 +92086 0.6173095703125 +92087 0.6524658203125 +92088 0.66339111328125 +92089 0.6561279296875 +92090 0.606781005859375 +92091 0.501190185546875 +92092 0.352783203125 +92093 0.176544189453125 +92094 -0.034820556640625 +92095 -0.258209228515625 +92096 -0.44244384765625 +92097 -0.5753173828125 +92098 -0.65203857421875 +92099 -0.641632080078125 +92100 -0.562164306640625 +92101 -0.458038330078125 +92102 -0.350555419921875 +92103 -0.260528564453125 +92104 -0.192108154296875 +92105 -0.141937255859375 +92106 -0.1021728515625 +92107 -0.062896728515625 +92108 -0.011932373046875 +92109 0.062835693359375 +92110 0.148712158203125 +92111 0.241729736328125 +92112 0.34912109375 +92113 0.457305908203125 +92114 0.54388427734375 +92115 0.5728759765625 +92116 0.506591796875 +92117 0.351226806640625 +92118 0.146514892578125 +92119 -0.05523681640625 +92120 -0.21624755859375 +92121 -0.334930419921875 +92122 -0.402984619140625 +92123 -0.4412841796875 +92124 -0.49578857421875 +92125 -0.5601806640625 +92126 -0.600738525390625 +92127 -0.584228515625 +92128 -0.47930908203125 +92129 -0.27935791015625 +92130 -0.0089111328125 +92131 0.268798828125 +92132 0.482818603515625 +92133 0.60369873046875 +92134 0.650421142578125 +92135 0.66400146484375 +92136 0.6414794921875 +92137 0.572540283203125 +92138 0.498138427734375 +92139 0.439453125 +92140 0.375518798828125 +92141 0.274505615234375 +92142 0.1087646484375 +92143 -0.099395751953125 +92144 -0.3182373046875 +92145 -0.5489501953125 +92146 -0.7738037109375 +92147 -0.86383056640625 +92148 -0.870391845703125 +92149 -0.86895751953125 +92150 -0.861053466796875 +92151 -0.765869140625 +92152 -0.5301513671875 +92153 -0.214691162109375 +92154 0.137359619140625 +92155 0.474822998046875 +92156 0.76239013671875 +92157 0.867462158203125 +92158 0.870361328125 +92159 0.86480712890625 +92160 0.831817626953125 +92161 0.677581787109375 +92162 0.495880126953125 +92163 0.30767822265625 +92164 0.116180419921875 +92165 -0.110748291015625 +92166 -0.381805419921875 +92167 -0.6572265625 +92168 -0.857421875 +92169 -0.870391845703125 +92170 -0.870391845703125 +92171 -0.86444091796875 +92172 -0.85723876953125 +92173 -0.790008544921875 +92174 -0.62847900390625 +92175 -0.3956298828125 +92176 -0.126708984375 +92177 0.150115966796875 +92178 0.424041748046875 +92179 0.670623779296875 +92180 0.854522705078125 +92181 0.866485595703125 +92182 0.86920166015625 +92183 0.8653564453125 +92184 0.857147216796875 +92185 0.766845703125 +92186 0.628509521484375 +92187 0.462127685546875 +92188 0.297210693359375 +92189 0.14862060546875 +92190 -0.00537109375 +92191 -0.15753173828125 +92192 -0.31304931640625 +92193 -0.48876953125 +92194 -0.6416015625 +92195 -0.751373291015625 +92196 -0.84619140625 +92197 -0.861297607421875 +92198 -0.863250732421875 +92199 -0.856597900390625 +92200 -0.7498779296875 +92201 -0.624542236328125 +92202 -0.47808837890625 +92203 -0.253387451171875 +92204 0.003692626953125 +92205 0.2257080078125 +92206 0.427154541015625 +92207 0.643218994140625 +92208 0.855926513671875 +92209 0.870361328125 +92210 0.870361328125 +92211 0.862762451171875 +92212 0.79669189453125 +92213 0.595794677734375 +92214 0.362152099609375 +92215 0.1270751953125 +92216 -0.086944580078125 +92217 -0.2784423828125 +92218 -0.484832763671875 +92219 -0.729583740234375 +92220 -0.86688232421875 +92221 -0.870391845703125 +92222 -0.86859130859375 +92223 -0.86279296875 +92224 -0.817962646484375 +92225 -0.6116943359375 +92226 -0.3128662109375 +92227 0.039398193359375 +92228 0.422821044921875 +92229 0.805145263671875 +92230 0.870361328125 +92231 0.870361328125 +92232 0.860015869140625 +92233 0.727935791015625 +92234 0.48114013671875 +92235 0.2059326171875 +92236 -0.06103515625 +92237 -0.29913330078125 +92238 -0.516204833984375 +92239 -0.7252197265625 +92240 -0.85980224609375 +92241 -0.870391845703125 +92242 -0.870391845703125 +92243 -0.858062744140625 +92244 -0.673004150390625 +92245 -0.42694091796875 +92246 -0.2100830078125 +92247 -0.0362548828125 +92248 0.10943603515625 +92249 0.23516845703125 +92250 0.373687744140625 +92251 0.517791748046875 +92252 0.602783203125 +92253 0.635711669921875 +92254 0.655181884765625 +92255 0.65948486328125 +92256 0.651275634765625 +92257 0.61846923828125 +92258 0.53753662109375 +92259 0.404144287109375 +92260 0.22186279296875 +92261 0.003997802734375 +92262 -0.22100830078125 +92263 -0.42449951171875 +92264 -0.579833984375 +92265 -0.641876220703125 +92266 -0.6177978515625 +92267 -0.575531005859375 +92268 -0.526336669921875 +92269 -0.42645263671875 +92270 -0.2581787109375 +92271 -0.068695068359375 +92272 0.09222412109375 +92273 0.232147216796875 +92274 0.3509521484375 +92275 0.410064697265625 +92276 0.372955322265625 +92277 0.2554931640625 +92278 0.10711669921875 +92279 -0.052886962890625 +92280 -0.186279296875 +92281 -0.23291015625 +92282 -0.209442138671875 +92283 -0.174163818359375 +92284 -0.126739501953125 +92285 -0.048126220703125 +92286 0.0426025390625 +92287 0.10748291015625 +92288 0.1409912109375 +92289 0.19708251953125 +92290 0.273651123046875 +92291 0.31768798828125 +92292 0.341094970703125 +92293 0.368011474609375 +92294 0.37249755859375 +92295 0.30072021484375 +92296 0.1517333984375 +92297 -0.01470947265625 +92298 -0.1883544921875 +92299 -0.372711181640625 +92300 -0.51397705078125 +92301 -0.57177734375 +92302 -0.53948974609375 +92303 -0.43511962890625 +92304 -0.2962646484375 +92305 -0.161102294921875 +92306 -0.0435791015625 +92307 0.060394287109375 +92308 0.13665771484375 +92309 0.170135498046875 +92310 0.16552734375 +92311 0.15728759765625 +92312 0.150787353515625 +92313 0.12200927734375 +92314 0.080108642578125 +92315 0.05126953125 +92316 0.062896728515625 +92317 0.09271240234375 +92318 0.092987060546875 +92319 0.07855224609375 +92320 0.06427001953125 +92321 0.0347900390625 +92322 -0.01171875 +92323 -0.056060791015625 +92324 -0.055511474609375 +92325 -0.010467529296875 +92326 0.02508544921875 +92327 0.025665283203125 +92328 0.017333984375 +92329 0.00189208984375 +92330 -0.03173828125 +92331 -0.071502685546875 +92332 -0.13543701171875 +92333 -0.219970703125 +92334 -0.300506591796875 +92335 -0.376312255859375 +92336 -0.416107177734375 +92337 -0.371124267578125 +92338 -0.242279052734375 +92339 -0.069732666015625 +92340 0.125640869140625 +92341 0.31268310546875 +92342 0.45501708984375 +92343 0.554779052734375 +92344 0.61065673828125 +92345 0.610931396484375 +92346 0.531463623046875 +92347 0.3883056640625 +92348 0.23468017578125 +92349 0.095245361328125 +92350 -0.00396728515625 +92351 -0.04852294921875 +92352 -0.055145263671875 +92353 -0.0758056640625 +92354 -0.138702392578125 +92355 -0.209197998046875 +92356 -0.289031982421875 +92357 -0.37884521484375 +92358 -0.456329345703125 +92359 -0.51641845703125 +92360 -0.519287109375 +92361 -0.458251953125 +92362 -0.384796142578125 +92363 -0.323699951171875 +92364 -0.269287109375 +92365 -0.1951904296875 +92366 -0.100006103515625 +92367 -0.01055908203125 +92368 0.1033935546875 +92369 0.24908447265625 +92370 0.373199462890625 +92371 0.45806884765625 +92372 0.511474609375 +92373 0.565399169921875 +92374 0.61138916015625 +92375 0.5897216796875 +92376 0.4906005859375 +92377 0.33148193359375 +92378 0.147796630859375 +92379 -0.01873779296875 +92380 -0.140289306640625 +92381 -0.191986083984375 +92382 -0.184295654296875 +92383 -0.161834716796875 +92384 -0.166595458984375 +92385 -0.19390869140625 +92386 -0.22442626953125 +92387 -0.279754638671875 +92388 -0.3389892578125 +92389 -0.3543701171875 +92390 -0.348175048828125 +92391 -0.32598876953125 +92392 -0.2581787109375 +92393 -0.139801025390625 +92394 0.014617919921875 +92395 0.144378662109375 +92396 0.221038818359375 +92397 0.27069091796875 +92398 0.294036865234375 +92399 0.311767578125 +92400 0.339141845703125 +92401 0.360260009765625 +92402 0.360504150390625 +92403 0.308380126953125 +92404 0.18170166015625 +92405 0.0047607421875 +92406 -0.17559814453125 +92407 -0.3143310546875 +92408 -0.36785888671875 +92409 -0.36248779296875 +92410 -0.343536376953125 +92411 -0.3018798828125 +92412 -0.231414794921875 +92413 -0.117645263671875 +92414 0.007049560546875 +92415 0.087982177734375 +92416 0.13946533203125 +92417 0.17425537109375 +92418 0.188201904296875 +92419 0.171234130859375 +92420 0.118438720703125 +92421 0.05706787109375 +92422 -0.010711669921875 +92423 -0.0914306640625 +92424 -0.162322998046875 +92425 -0.194549560546875 +92426 -0.1492919921875 +92427 -0.02166748046875 +92428 0.124053955078125 +92429 0.211151123046875 +92430 0.240447998046875 +92431 0.242218017578125 +92432 0.2257080078125 +92433 0.194366455078125 +92434 0.115509033203125 +92435 0.0128173828125 +92436 -0.053802490234375 +92437 -0.110626220703125 +92438 -0.199493408203125 +92439 -0.29437255859375 +92440 -0.33221435546875 +92441 -0.27972412109375 +92442 -0.185333251953125 +92443 -0.128204345703125 +92444 -0.115692138671875 +92445 -0.116455078125 +92446 -0.105926513671875 +92447 -0.053955078125 +92448 0.048797607421875 +92449 0.157318115234375 +92450 0.212005615234375 +92451 0.218475341796875 +92452 0.23724365234375 +92453 0.30535888671875 +92454 0.38128662109375 +92455 0.404449462890625 +92456 0.3944091796875 +92457 0.3885498046875 +92458 0.362640380859375 +92459 0.27362060546875 +92460 0.11712646484375 +92461 -0.054901123046875 +92462 -0.19085693359375 +92463 -0.28570556640625 +92464 -0.339263916015625 +92465 -0.3775634765625 +92466 -0.445709228515625 +92467 -0.535064697265625 +92468 -0.629058837890625 +92469 -0.697601318359375 +92470 -0.70391845703125 +92471 -0.6424560546875 +92472 -0.491241455078125 +92473 -0.265716552734375 +92474 -0.023712158203125 +92475 0.201751708984375 +92476 0.375823974609375 +92477 0.485076904296875 +92478 0.56884765625 +92479 0.634765625 +92480 0.63763427734375 +92481 0.5660400390625 +92482 0.4720458984375 +92483 0.40692138671875 +92484 0.3778076171875 +92485 0.376953125 +92486 0.371978759765625 +92487 0.313140869140625 +92488 0.184417724609375 +92489 0.011199951171875 +92490 -0.171051025390625 +92491 -0.33740234375 +92492 -0.47198486328125 +92493 -0.560394287109375 +92494 -0.58056640625 +92495 -0.54754638671875 +92496 -0.508575439453125 +92497 -0.459503173828125 +92498 -0.394378662109375 +92499 -0.35260009765625 +92500 -0.31170654296875 +92501 -0.197418212890625 +92502 -0.007965087890625 +92503 0.207489013671875 +92504 0.409210205078125 +92505 0.57208251953125 +92506 0.66595458984375 +92507 0.65875244140625 +92508 0.56744384765625 +92509 0.431396484375 +92510 0.29443359375 +92511 0.182464599609375 +92512 0.06365966796875 +92513 -0.075958251953125 +92514 -0.189422607421875 +92515 -0.271942138671875 +92516 -0.342529296875 +92517 -0.364166259765625 +92518 -0.327239990234375 +92519 -0.2769775390625 +92520 -0.253692626953125 +92521 -0.24365234375 +92522 -0.1983642578125 +92523 -0.116241455078125 +92524 -0.036834716796875 +92525 0.034881591796875 +92526 0.09124755859375 +92527 0.10888671875 +92528 0.125518798828125 +92529 0.15771484375 +92530 0.17828369140625 +92531 0.17108154296875 +92532 0.129974365234375 +92533 0.082427978515625 +92534 0.027679443359375 +92535 -0.065643310546875 +92536 -0.15936279296875 +92537 -0.21307373046875 +92538 -0.234649658203125 +92539 -0.2001953125 +92540 -0.119171142578125 +92541 -0.024749755859375 +92542 0.085784912109375 +92543 0.178131103515625 +92544 0.215576171875 +92545 0.211456298828125 +92546 0.17523193359375 +92547 0.128753662109375 +92548 0.1019287109375 +92549 0.0743408203125 +92550 0.04327392578125 +92551 0.038177490234375 +92552 0.076263427734375 +92553 0.14105224609375 +92554 0.186431884765625 +92555 0.188812255859375 +92556 0.1390380859375 +92557 0.041778564453125 +92558 -0.079437255859375 +92559 -0.219390869140625 +92560 -0.367828369140625 +92561 -0.494873046875 +92562 -0.556243896484375 +92563 -0.508697509765625 +92564 -0.3756103515625 +92565 -0.218902587890625 +92566 -0.063751220703125 +92567 0.091552734375 +92568 0.23602294921875 +92569 0.342987060546875 +92570 0.39520263671875 +92571 0.389373779296875 +92572 0.324249267578125 +92573 0.224090576171875 +92574 0.124267578125 +92575 0.037078857421875 +92576 -0.010101318359375 +92577 -0.019439697265625 +92578 -0.022796630859375 +92579 -0.001556396484375 +92580 0.056304931640625 +92581 0.106719970703125 +92582 0.096893310546875 +92583 0.042694091796875 +92584 -0.018035888671875 +92585 -0.07586669921875 +92586 -0.11944580078125 +92587 -0.15972900390625 +92588 -0.202606201171875 +92589 -0.24859619140625 +92590 -0.30517578125 +92591 -0.36212158203125 +92592 -0.39141845703125 +92593 -0.35528564453125 +92594 -0.249969482421875 +92595 -0.092864990234375 +92596 0.08905029296875 +92597 0.2352294921875 +92598 0.318817138671875 +92599 0.358642578125 +92600 0.347747802734375 +92601 0.28564453125 +92602 0.223175048828125 +92603 0.196746826171875 +92604 0.179840087890625 +92605 0.155548095703125 +92606 0.151214599609375 +92607 0.156951904296875 +92608 0.13177490234375 +92609 0.100799560546875 +92610 0.087127685546875 +92611 0.05487060546875 +92612 -0.009002685546875 +92613 -0.10400390625 +92614 -0.229400634765625 +92615 -0.35552978515625 +92616 -0.441925048828125 +92617 -0.473846435546875 +92618 -0.464813232421875 +92619 -0.419097900390625 +92620 -0.334320068359375 +92621 -0.227935791015625 +92622 -0.12347412109375 +92623 -0.02764892578125 +92624 0.077667236328125 +92625 0.2132568359375 +92626 0.38885498046875 +92627 0.582794189453125 +92628 0.734039306640625 +92629 0.800140380859375 +92630 0.7783203125 +92631 0.6651611328125 +92632 0.45965576171875 +92633 0.199188232421875 +92634 -0.050689697265625 +92635 -0.23297119140625 +92636 -0.33013916015625 +92637 -0.368408203125 +92638 -0.378936767578125 +92639 -0.376983642578125 +92640 -0.37969970703125 +92641 -0.391510009765625 +92642 -0.385345458984375 +92643 -0.3419189453125 +92644 -0.28289794921875 +92645 -0.251617431640625 +92646 -0.266143798828125 +92647 -0.273345947265625 +92648 -0.216796875 +92649 -0.128265380859375 +92650 -0.068145751953125 +92651 -0.0430908203125 +92652 -0.024444580078125 +92653 0.020721435546875 +92654 0.124481201171875 +92655 0.25787353515625 +92656 0.379119873046875 +92657 0.47991943359375 +92658 0.5281982421875 +92659 0.511138916015625 +92660 0.456207275390625 +92661 0.407470703125 +92662 0.383758544921875 +92663 0.35687255859375 +92664 0.31182861328125 +92665 0.250885009765625 +92666 0.1654052734375 +92667 0.035247802734375 +92668 -0.142059326171875 +92669 -0.33563232421875 +92670 -0.5345458984375 +92671 -0.72186279296875 +92672 -0.836669921875 +92673 -0.8326416015625 +92674 -0.7296142578125 +92675 -0.582550048828125 +92676 -0.440093994140625 +92677 -0.324310302734375 +92678 -0.20147705078125 +92679 -0.044647216796875 +92680 0.103973388671875 +92681 0.202392578125 +92682 0.264495849609375 +92683 0.338897705078125 +92684 0.443817138671875 +92685 0.545074462890625 +92686 0.6173095703125 +92687 0.6524658203125 +92688 0.66339111328125 +92689 0.6561279296875 +92690 0.606781005859375 +92691 0.501190185546875 +92692 0.352783203125 +92693 0.176544189453125 +92694 -0.034820556640625 +92695 -0.258209228515625 +92696 -0.44244384765625 +92697 -0.5753173828125 +92698 -0.65203857421875 +92699 -0.641632080078125 +92700 -0.562164306640625 +92701 -0.458038330078125 +92702 -0.350555419921875 +92703 -0.260528564453125 +92704 -0.192108154296875 +92705 -0.141937255859375 +92706 -0.1021728515625 +92707 -0.062896728515625 +92708 -0.011932373046875 +92709 0.062835693359375 +92710 0.148712158203125 +92711 0.241729736328125 +92712 0.34912109375 +92713 0.457305908203125 +92714 0.54388427734375 +92715 0.5728759765625 +92716 0.506591796875 +92717 0.351226806640625 +92718 0.146514892578125 +92719 -0.05523681640625 +92720 -0.21624755859375 +92721 -0.334930419921875 +92722 -0.402984619140625 +92723 -0.4412841796875 +92724 -0.49578857421875 +92725 -0.5601806640625 +92726 -0.600738525390625 +92727 -0.584228515625 +92728 -0.47930908203125 +92729 -0.27935791015625 +92730 -0.0089111328125 +92731 0.268798828125 +92732 0.482818603515625 +92733 0.60369873046875 +92734 0.650421142578125 +92735 0.66400146484375 +92736 0.6414794921875 +92737 0.572540283203125 +92738 0.498138427734375 +92739 0.439453125 +92740 0.375518798828125 +92741 0.274505615234375 +92742 0.1087646484375 +92743 -0.099395751953125 +92744 -0.3182373046875 +92745 -0.5489501953125 +92746 -0.7738037109375 +92747 -0.86383056640625 +92748 -0.870391845703125 +92749 -0.86895751953125 +92750 -0.861053466796875 +92751 -0.765869140625 +92752 -0.5301513671875 +92753 -0.214691162109375 +92754 0.137359619140625 +92755 0.474822998046875 +92756 0.76239013671875 +92757 0.867462158203125 +92758 0.870361328125 +92759 0.86480712890625 +92760 0.831817626953125 +92761 0.677581787109375 +92762 0.495880126953125 +92763 0.30767822265625 +92764 0.116180419921875 +92765 -0.110748291015625 +92766 -0.381805419921875 +92767 -0.6572265625 +92768 -0.857421875 +92769 -0.870391845703125 +92770 -0.870391845703125 +92771 -0.86444091796875 +92772 -0.85723876953125 +92773 -0.790008544921875 +92774 -0.62847900390625 +92775 -0.3956298828125 +92776 -0.126708984375 +92777 0.150115966796875 +92778 0.424041748046875 +92779 0.670623779296875 +92780 0.854522705078125 +92781 0.866485595703125 +92782 0.86920166015625 +92783 0.8653564453125 +92784 0.857147216796875 +92785 0.766845703125 +92786 0.628509521484375 +92787 0.462127685546875 +92788 0.297210693359375 +92789 0.14862060546875 +92790 -0.00537109375 +92791 -0.15753173828125 +92792 -0.31304931640625 +92793 -0.48876953125 +92794 -0.6416015625 +92795 -0.751373291015625 +92796 -0.84619140625 +92797 -0.861297607421875 +92798 -0.863250732421875 +92799 -0.856597900390625 +92800 -0.7498779296875 +92801 -0.624542236328125 +92802 -0.47808837890625 +92803 -0.253387451171875 +92804 0.003692626953125 +92805 0.2257080078125 +92806 0.427154541015625 +92807 0.643218994140625 +92808 0.855926513671875 +92809 0.870361328125 +92810 0.870361328125 +92811 0.862762451171875 +92812 0.79669189453125 +92813 0.595794677734375 +92814 0.362152099609375 +92815 0.1270751953125 +92816 -0.086944580078125 +92817 -0.2784423828125 +92818 -0.484832763671875 +92819 -0.729583740234375 +92820 -0.86688232421875 +92821 -0.870391845703125 +92822 -0.86859130859375 +92823 -0.86279296875 +92824 -0.817962646484375 +92825 -0.6116943359375 +92826 -0.3128662109375 +92827 0.039398193359375 +92828 0.422821044921875 +92829 0.805145263671875 +92830 0.870361328125 +92831 0.870361328125 +92832 0.860015869140625 +92833 0.727935791015625 +92834 0.48114013671875 +92835 0.2059326171875 +92836 -0.06103515625 +92837 -0.29913330078125 +92838 -0.516204833984375 +92839 -0.7252197265625 +92840 -0.85980224609375 +92841 -0.870391845703125 +92842 -0.870391845703125 +92843 -0.858062744140625 +92844 -0.673004150390625 +92845 -0.42694091796875 +92846 -0.2100830078125 +92847 -0.0362548828125 +92848 0.10943603515625 +92849 0.23516845703125 +92850 0.373687744140625 +92851 0.517791748046875 +92852 0.602783203125 +92853 0.635711669921875 +92854 0.655181884765625 +92855 0.65948486328125 +92856 0.651275634765625 +92857 0.61846923828125 +92858 0.53753662109375 +92859 0.404144287109375 +92860 0.22186279296875 +92861 0.003997802734375 +92862 -0.22100830078125 +92863 -0.42449951171875 +92864 -0.579833984375 +92865 -0.641876220703125 +92866 -0.6177978515625 +92867 -0.575531005859375 +92868 -0.526336669921875 +92869 -0.42645263671875 +92870 -0.2581787109375 +92871 -0.068695068359375 +92872 0.09222412109375 +92873 0.232147216796875 +92874 0.3509521484375 +92875 0.410064697265625 +92876 0.372955322265625 +92877 0.2554931640625 +92878 0.10711669921875 +92879 -0.052886962890625 +92880 -0.186279296875 +92881 -0.23291015625 +92882 -0.209442138671875 +92883 -0.174163818359375 +92884 -0.126739501953125 +92885 -0.048126220703125 +92886 0.0426025390625 +92887 0.10748291015625 +92888 0.1409912109375 +92889 0.19708251953125 +92890 0.273651123046875 +92891 0.31768798828125 +92892 0.341094970703125 +92893 0.368011474609375 +92894 0.37249755859375 +92895 0.30072021484375 +92896 0.1517333984375 +92897 -0.01470947265625 +92898 -0.1883544921875 +92899 -0.372711181640625 +92900 -0.51397705078125 +92901 -0.57177734375 +92902 -0.53948974609375 +92903 -0.43511962890625 +92904 -0.2962646484375 +92905 -0.161102294921875 +92906 -0.0435791015625 +92907 0.060394287109375 +92908 0.13665771484375 +92909 0.170135498046875 +92910 0.16552734375 +92911 0.15728759765625 +92912 0.150787353515625 +92913 0.12200927734375 +92914 0.080108642578125 +92915 0.05126953125 +92916 0.062896728515625 +92917 0.09271240234375 +92918 0.092987060546875 +92919 0.07855224609375 +92920 0.06427001953125 +92921 0.0347900390625 +92922 -0.01171875 +92923 -0.056060791015625 +92924 -0.055511474609375 +92925 -0.010467529296875 +92926 0.02508544921875 +92927 0.025665283203125 +92928 0.017333984375 +92929 0.00189208984375 +92930 -0.03173828125 +92931 -0.071502685546875 +92932 -0.13543701171875 +92933 -0.219970703125 +92934 -0.300506591796875 +92935 -0.376312255859375 +92936 -0.416107177734375 +92937 -0.371124267578125 +92938 -0.242279052734375 +92939 -0.069732666015625 +92940 0.125640869140625 +92941 0.31268310546875 +92942 0.45501708984375 +92943 0.554779052734375 +92944 0.61065673828125 +92945 0.610931396484375 +92946 0.531463623046875 +92947 0.3883056640625 +92948 0.23468017578125 +92949 0.095245361328125 +92950 -0.00396728515625 +92951 -0.04852294921875 +92952 -0.055145263671875 +92953 -0.0758056640625 +92954 -0.138702392578125 +92955 -0.209197998046875 +92956 -0.289031982421875 +92957 -0.37884521484375 +92958 -0.456329345703125 +92959 -0.51641845703125 +92960 -0.519287109375 +92961 -0.458251953125 +92962 -0.384796142578125 +92963 -0.323699951171875 +92964 -0.269287109375 +92965 -0.1951904296875 +92966 -0.100006103515625 +92967 -0.01055908203125 +92968 0.1033935546875 +92969 0.24908447265625 +92970 0.373199462890625 +92971 0.45806884765625 +92972 0.511474609375 +92973 0.565399169921875 +92974 0.61138916015625 +92975 0.5897216796875 +92976 0.4906005859375 +92977 0.33148193359375 +92978 0.147796630859375 +92979 -0.01873779296875 +92980 -0.140289306640625 +92981 -0.191986083984375 +92982 -0.184295654296875 +92983 -0.161834716796875 +92984 -0.166595458984375 +92985 -0.19390869140625 +92986 -0.22442626953125 +92987 -0.279754638671875 +92988 -0.3389892578125 +92989 -0.3543701171875 +92990 -0.348175048828125 +92991 -0.32598876953125 +92992 -0.2581787109375 +92993 -0.139801025390625 +92994 0.014617919921875 +92995 0.144378662109375 +92996 0.221038818359375 +92997 0.27069091796875 +92998 0.294036865234375 +92999 0.311767578125 +93000 0.339141845703125 +93001 0.360260009765625 +93002 0.360504150390625 +93003 0.308380126953125 +93004 0.18170166015625 +93005 0.0047607421875 +93006 -0.17559814453125 +93007 -0.3143310546875 +93008 -0.36785888671875 +93009 -0.36248779296875 +93010 -0.343536376953125 +93011 -0.3018798828125 +93012 -0.231414794921875 +93013 -0.117645263671875 +93014 0.007049560546875 +93015 0.087982177734375 +93016 0.13946533203125 +93017 0.17425537109375 +93018 0.188201904296875 +93019 0.171234130859375 +93020 0.118438720703125 +93021 0.05706787109375 +93022 -0.010711669921875 +93023 -0.0914306640625 +93024 -0.162322998046875 +93025 -0.194549560546875 +93026 -0.1492919921875 +93027 -0.02166748046875 +93028 0.124053955078125 +93029 0.211151123046875 +93030 0.240447998046875 +93031 0.242218017578125 +93032 0.2257080078125 +93033 0.194366455078125 +93034 0.115509033203125 +93035 0.0128173828125 +93036 -0.053802490234375 +93037 -0.110626220703125 +93038 -0.199493408203125 +93039 -0.29437255859375 +93040 -0.33221435546875 +93041 -0.27972412109375 +93042 -0.185333251953125 +93043 -0.128204345703125 +93044 -0.115692138671875 +93045 -0.116455078125 +93046 -0.105926513671875 +93047 -0.053955078125 +93048 0.048797607421875 +93049 0.157318115234375 +93050 0.212005615234375 +93051 0.218475341796875 +93052 0.23724365234375 +93053 0.30535888671875 +93054 0.38128662109375 +93055 0.404449462890625 +93056 0.3944091796875 +93057 0.3885498046875 +93058 0.362640380859375 +93059 0.27362060546875 +93060 0.11712646484375 +93061 -0.054901123046875 +93062 -0.19085693359375 +93063 -0.28570556640625 +93064 -0.339263916015625 +93065 -0.3775634765625 +93066 -0.445709228515625 +93067 -0.535064697265625 +93068 -0.629058837890625 +93069 -0.697601318359375 +93070 -0.70391845703125 +93071 -0.6424560546875 +93072 -0.491241455078125 +93073 -0.265716552734375 +93074 -0.023712158203125 +93075 0.201751708984375 +93076 0.375823974609375 +93077 0.485076904296875 +93078 0.56884765625 +93079 0.634765625 +93080 0.63763427734375 +93081 0.5660400390625 +93082 0.4720458984375 +93083 0.40692138671875 +93084 0.3778076171875 +93085 0.376953125 +93086 0.371978759765625 +93087 0.313140869140625 +93088 0.184417724609375 +93089 0.011199951171875 +93090 -0.171051025390625 +93091 -0.33740234375 +93092 -0.47198486328125 +93093 -0.560394287109375 +93094 -0.58056640625 +93095 -0.54754638671875 +93096 -0.508575439453125 +93097 -0.459503173828125 +93098 -0.394378662109375 +93099 -0.35260009765625 +93100 -0.31170654296875 +93101 -0.197418212890625 +93102 -0.007965087890625 +93103 0.207489013671875 +93104 0.409210205078125 +93105 0.57208251953125 +93106 0.66595458984375 +93107 0.65875244140625 +93108 0.56744384765625 +93109 0.431396484375 +93110 0.29443359375 +93111 0.182464599609375 +93112 0.06365966796875 +93113 -0.075958251953125 +93114 -0.189422607421875 +93115 -0.271942138671875 +93116 -0.342529296875 +93117 -0.364166259765625 +93118 -0.327239990234375 +93119 -0.2769775390625 +93120 -0.253692626953125 +93121 -0.24365234375 +93122 -0.1983642578125 +93123 -0.116241455078125 +93124 -0.036834716796875 +93125 0.034881591796875 +93126 0.09124755859375 +93127 0.10888671875 +93128 0.125518798828125 +93129 0.15771484375 +93130 0.17828369140625 +93131 0.17108154296875 +93132 0.129974365234375 +93133 0.082427978515625 +93134 0.027679443359375 +93135 -0.065643310546875 +93136 -0.15936279296875 +93137 -0.21307373046875 +93138 -0.234649658203125 +93139 -0.2001953125 +93140 -0.119171142578125 +93141 -0.024749755859375 +93142 0.085784912109375 +93143 0.178131103515625 +93144 0.215576171875 +93145 0.211456298828125 +93146 0.17523193359375 +93147 0.128753662109375 +93148 0.1019287109375 +93149 0.0743408203125 +93150 0.04327392578125 +93151 0.038177490234375 +93152 0.076263427734375 +93153 0.14105224609375 +93154 0.186431884765625 +93155 0.188812255859375 +93156 0.1390380859375 +93157 0.041778564453125 +93158 -0.079437255859375 +93159 -0.219390869140625 +93160 -0.367828369140625 +93161 -0.494873046875 +93162 -0.556243896484375 +93163 -0.508697509765625 +93164 -0.3756103515625 +93165 -0.218902587890625 +93166 -0.063751220703125 +93167 0.091552734375 +93168 0.23602294921875 +93169 0.342987060546875 +93170 0.39520263671875 +93171 0.389373779296875 +93172 0.324249267578125 +93173 0.224090576171875 +93174 0.124267578125 +93175 0.037078857421875 +93176 -0.010101318359375 +93177 -0.019439697265625 +93178 -0.022796630859375 +93179 -0.001556396484375 +93180 0.056304931640625 +93181 0.106719970703125 +93182 0.096893310546875 +93183 0.042694091796875 +93184 -0.018035888671875 +93185 -0.07586669921875 +93186 -0.11944580078125 +93187 -0.15972900390625 +93188 -0.202606201171875 +93189 -0.24859619140625 +93190 -0.30517578125 +93191 -0.36212158203125 +93192 -0.39141845703125 +93193 -0.35528564453125 +93194 -0.249969482421875 +93195 -0.092864990234375 +93196 0.08905029296875 +93197 0.2352294921875 +93198 0.318817138671875 +93199 0.358642578125 +93200 0.347747802734375 +93201 0.28564453125 +93202 0.223175048828125 +93203 0.196746826171875 +93204 0.179840087890625 +93205 0.155548095703125 +93206 0.151214599609375 +93207 0.156951904296875 +93208 0.13177490234375 +93209 0.100799560546875 +93210 0.087127685546875 +93211 0.05487060546875 +93212 -0.009002685546875 +93213 -0.10400390625 +93214 -0.229400634765625 +93215 -0.35552978515625 +93216 -0.441925048828125 +93217 -0.473846435546875 +93218 -0.464813232421875 +93219 -0.419097900390625 +93220 -0.334320068359375 +93221 -0.227935791015625 +93222 -0.12347412109375 +93223 -0.02764892578125 +93224 0.077667236328125 +93225 0.2132568359375 +93226 0.38885498046875 +93227 0.582794189453125 +93228 0.734039306640625 +93229 0.800140380859375 +93230 0.7783203125 +93231 0.6651611328125 +93232 0.45965576171875 +93233 0.199188232421875 +93234 -0.050689697265625 +93235 -0.23297119140625 +93236 -0.33013916015625 +93237 -0.368408203125 +93238 -0.378936767578125 +93239 -0.376983642578125 +93240 -0.37969970703125 +93241 -0.391510009765625 +93242 -0.385345458984375 +93243 -0.3419189453125 +93244 -0.28289794921875 +93245 -0.251617431640625 +93246 -0.266143798828125 +93247 -0.273345947265625 +93248 -0.216796875 +93249 -0.128265380859375 +93250 -0.068145751953125 +93251 -0.0430908203125 +93252 -0.024444580078125 +93253 0.020721435546875 +93254 0.124481201171875 +93255 0.25787353515625 +93256 0.379119873046875 +93257 0.47991943359375 +93258 0.5281982421875 +93259 0.511138916015625 +93260 0.456207275390625 +93261 0.407470703125 +93262 0.383758544921875 +93263 0.35687255859375 +93264 0.31182861328125 +93265 0.250885009765625 +93266 0.1654052734375 +93267 0.035247802734375 +93268 -0.142059326171875 +93269 -0.33563232421875 +93270 -0.5345458984375 +93271 -0.72186279296875 +93272 -0.836669921875 +93273 -0.8326416015625 +93274 -0.7296142578125 +93275 -0.582550048828125 +93276 -0.440093994140625 +93277 -0.324310302734375 +93278 -0.20147705078125 +93279 -0.044647216796875 +93280 0.103973388671875 +93281 0.202392578125 +93282 0.264495849609375 +93283 0.338897705078125 +93284 0.443817138671875 +93285 0.545074462890625 +93286 0.6173095703125 +93287 0.6524658203125 +93288 0.66339111328125 +93289 0.6561279296875 +93290 0.606781005859375 +93291 0.501190185546875 +93292 0.352783203125 +93293 0.176544189453125 +93294 -0.034820556640625 +93295 -0.258209228515625 +93296 -0.44244384765625 +93297 -0.5753173828125 +93298 -0.65203857421875 +93299 -0.641632080078125 +93300 -0.562164306640625 +93301 -0.458038330078125 +93302 -0.350555419921875 +93303 -0.260528564453125 +93304 -0.192108154296875 +93305 -0.141937255859375 +93306 -0.1021728515625 +93307 -0.062896728515625 +93308 -0.011932373046875 +93309 0.062835693359375 +93310 0.148712158203125 +93311 0.241729736328125 +93312 0.34912109375 +93313 0.457305908203125 +93314 0.54388427734375 +93315 0.5728759765625 +93316 0.506591796875 +93317 0.351226806640625 +93318 0.146514892578125 +93319 -0.05523681640625 +93320 -0.21624755859375 +93321 -0.334930419921875 +93322 -0.402984619140625 +93323 -0.4412841796875 +93324 -0.49578857421875 +93325 -0.5601806640625 +93326 -0.600738525390625 +93327 -0.584228515625 +93328 -0.47930908203125 +93329 -0.27935791015625 +93330 -0.0089111328125 +93331 0.268798828125 +93332 0.482818603515625 +93333 0.60369873046875 +93334 0.650421142578125 +93335 0.66400146484375 +93336 0.6414794921875 +93337 0.572540283203125 +93338 0.498138427734375 +93339 0.439453125 +93340 0.375518798828125 +93341 0.274505615234375 +93342 0.1087646484375 +93343 -0.099395751953125 +93344 -0.3182373046875 +93345 -0.5489501953125 +93346 -0.7738037109375 +93347 -0.86383056640625 +93348 -0.870391845703125 +93349 -0.86895751953125 +93350 -0.861053466796875 +93351 -0.765869140625 +93352 -0.5301513671875 +93353 -0.214691162109375 +93354 0.137359619140625 +93355 0.474822998046875 +93356 0.76239013671875 +93357 0.867462158203125 +93358 0.870361328125 +93359 0.86480712890625 +93360 0.831817626953125 +93361 0.677581787109375 +93362 0.495880126953125 +93363 0.30767822265625 +93364 0.116180419921875 +93365 -0.110748291015625 +93366 -0.381805419921875 +93367 -0.6572265625 +93368 -0.857421875 +93369 -0.870391845703125 +93370 -0.870391845703125 +93371 -0.86444091796875 +93372 -0.85723876953125 +93373 -0.790008544921875 +93374 -0.62847900390625 +93375 -0.3956298828125 +93376 -0.126708984375 +93377 0.150115966796875 +93378 0.424041748046875 +93379 0.670623779296875 +93380 0.854522705078125 +93381 0.866485595703125 +93382 0.86920166015625 +93383 0.8653564453125 +93384 0.857147216796875 +93385 0.766845703125 +93386 0.628509521484375 +93387 0.462127685546875 +93388 0.297210693359375 +93389 0.14862060546875 +93390 -0.00537109375 +93391 -0.15753173828125 +93392 -0.31304931640625 +93393 -0.48876953125 +93394 -0.6416015625 +93395 -0.751373291015625 +93396 -0.84619140625 +93397 -0.861297607421875 +93398 -0.863250732421875 +93399 -0.856597900390625 +93400 -0.7498779296875 +93401 -0.624542236328125 +93402 -0.47808837890625 +93403 -0.253387451171875 +93404 0.003692626953125 +93405 0.2257080078125 +93406 0.427154541015625 +93407 0.643218994140625 +93408 0.855926513671875 +93409 0.870361328125 +93410 0.870361328125 +93411 0.862762451171875 +93412 0.79669189453125 +93413 0.595794677734375 +93414 0.362152099609375 +93415 0.1270751953125 +93416 -0.086944580078125 +93417 -0.2784423828125 +93418 -0.484832763671875 +93419 -0.729583740234375 +93420 -0.86688232421875 +93421 -0.870391845703125 +93422 -0.86859130859375 +93423 -0.86279296875 +93424 -0.817962646484375 +93425 -0.6116943359375 +93426 -0.3128662109375 +93427 0.039398193359375 +93428 0.422821044921875 +93429 0.805145263671875 +93430 0.870361328125 +93431 0.870361328125 +93432 0.860015869140625 +93433 0.727935791015625 +93434 0.48114013671875 +93435 0.2059326171875 +93436 -0.06103515625 +93437 -0.29913330078125 +93438 -0.516204833984375 +93439 -0.7252197265625 +93440 -0.85980224609375 +93441 -0.870391845703125 +93442 -0.870391845703125 +93443 -0.858062744140625 +93444 -0.673004150390625 +93445 -0.42694091796875 +93446 -0.2100830078125 +93447 -0.0362548828125 +93448 0.10943603515625 +93449 0.23516845703125 +93450 0.373687744140625 +93451 0.517791748046875 +93452 0.602783203125 +93453 0.635711669921875 +93454 0.655181884765625 +93455 0.65948486328125 +93456 0.651275634765625 +93457 0.61846923828125 +93458 0.53753662109375 +93459 0.404144287109375 +93460 0.22186279296875 +93461 0.003997802734375 +93462 -0.22100830078125 +93463 -0.42449951171875 +93464 -0.579833984375 +93465 -0.641876220703125 +93466 -0.6177978515625 +93467 -0.575531005859375 +93468 -0.526336669921875 +93469 -0.42645263671875 +93470 -0.2581787109375 +93471 -0.068695068359375 +93472 0.09222412109375 +93473 0.232147216796875 +93474 0.3509521484375 +93475 0.410064697265625 +93476 0.372955322265625 +93477 0.2554931640625 +93478 0.10711669921875 +93479 -0.052886962890625 +93480 -0.186279296875 +93481 -0.23291015625 +93482 -0.209442138671875 +93483 -0.174163818359375 +93484 -0.126739501953125 +93485 -0.048126220703125 +93486 0.0426025390625 +93487 0.10748291015625 +93488 0.1409912109375 +93489 0.19708251953125 +93490 0.273651123046875 +93491 0.31768798828125 +93492 0.341094970703125 +93493 0.368011474609375 +93494 0.37249755859375 +93495 0.30072021484375 +93496 0.1517333984375 +93497 -0.01470947265625 +93498 -0.1883544921875 +93499 -0.372711181640625 +93500 -0.51397705078125 +93501 -0.57177734375 +93502 -0.53948974609375 +93503 -0.43511962890625 +93504 -0.2962646484375 +93505 -0.161102294921875 +93506 -0.0435791015625 +93507 0.060394287109375 +93508 0.13665771484375 +93509 0.170135498046875 +93510 0.16552734375 +93511 0.15728759765625 +93512 0.150787353515625 +93513 0.12200927734375 +93514 0.080108642578125 +93515 0.05126953125 +93516 0.062896728515625 +93517 0.09271240234375 +93518 0.092987060546875 +93519 0.07855224609375 +93520 0.06427001953125 +93521 0.0347900390625 +93522 -0.01171875 +93523 -0.056060791015625 +93524 -0.055511474609375 +93525 -0.010467529296875 +93526 0.02508544921875 +93527 0.025665283203125 +93528 0.017333984375 +93529 0.00189208984375 +93530 -0.03173828125 +93531 -0.071502685546875 +93532 -0.13543701171875 +93533 -0.219970703125 +93534 -0.300506591796875 +93535 -0.376312255859375 +93536 -0.416107177734375 +93537 -0.371124267578125 +93538 -0.242279052734375 +93539 -0.069732666015625 +93540 0.125640869140625 +93541 0.31268310546875 +93542 0.45501708984375 +93543 0.554779052734375 +93544 0.61065673828125 +93545 0.610931396484375 +93546 0.531463623046875 +93547 0.3883056640625 +93548 0.23468017578125 +93549 0.095245361328125 +93550 -0.00396728515625 +93551 -0.04852294921875 +93552 -0.055145263671875 +93553 -0.0758056640625 +93554 -0.138702392578125 +93555 -0.209197998046875 +93556 -0.289031982421875 +93557 -0.37884521484375 +93558 -0.456329345703125 +93559 -0.51641845703125 +93560 -0.519287109375 +93561 -0.458251953125 +93562 -0.384796142578125 +93563 -0.323699951171875 +93564 -0.269287109375 +93565 -0.1951904296875 +93566 -0.100006103515625 +93567 -0.01055908203125 +93568 0.1033935546875 +93569 0.24908447265625 +93570 0.373199462890625 +93571 0.45806884765625 +93572 0.511474609375 +93573 0.565399169921875 +93574 0.61138916015625 +93575 0.5897216796875 +93576 0.4906005859375 +93577 0.33148193359375 +93578 0.147796630859375 +93579 -0.01873779296875 +93580 -0.140289306640625 +93581 -0.191986083984375 +93582 -0.184295654296875 +93583 -0.161834716796875 +93584 -0.166595458984375 +93585 -0.19390869140625 +93586 -0.22442626953125 +93587 -0.279754638671875 +93588 -0.3389892578125 +93589 -0.3543701171875 +93590 -0.348175048828125 +93591 -0.32598876953125 +93592 -0.2581787109375 +93593 -0.139801025390625 +93594 0.014617919921875 +93595 0.144378662109375 +93596 0.221038818359375 +93597 0.27069091796875 +93598 0.294036865234375 +93599 0.311767578125 +93600 0.339141845703125 +93601 0.360260009765625 +93602 0.360504150390625 +93603 0.308380126953125 +93604 0.18170166015625 +93605 0.0047607421875 +93606 -0.17559814453125 +93607 -0.3143310546875 +93608 -0.36785888671875 +93609 -0.36248779296875 +93610 -0.343536376953125 +93611 -0.3018798828125 +93612 -0.231414794921875 +93613 -0.117645263671875 +93614 0.007049560546875 +93615 0.087982177734375 +93616 0.13946533203125 +93617 0.17425537109375 +93618 0.188201904296875 +93619 0.171234130859375 +93620 0.118438720703125 +93621 0.05706787109375 +93622 -0.010711669921875 +93623 -0.0914306640625 +93624 -0.162322998046875 +93625 -0.194549560546875 +93626 -0.1492919921875 +93627 -0.02166748046875 +93628 0.124053955078125 +93629 0.211151123046875 +93630 0.240447998046875 +93631 0.242218017578125 +93632 0.2257080078125 +93633 0.194366455078125 +93634 0.115509033203125 +93635 0.0128173828125 +93636 -0.053802490234375 +93637 -0.110626220703125 +93638 -0.199493408203125 +93639 -0.29437255859375 +93640 -0.33221435546875 +93641 -0.27972412109375 +93642 -0.185333251953125 +93643 -0.128204345703125 +93644 -0.115692138671875 +93645 -0.116455078125 +93646 -0.105926513671875 +93647 -0.053955078125 +93648 0.048797607421875 +93649 0.157318115234375 +93650 0.212005615234375 +93651 0.218475341796875 +93652 0.23724365234375 +93653 0.30535888671875 +93654 0.38128662109375 +93655 0.404449462890625 +93656 0.3944091796875 +93657 0.3885498046875 +93658 0.362640380859375 +93659 0.27362060546875 +93660 0.11712646484375 +93661 -0.054901123046875 +93662 -0.19085693359375 +93663 -0.28570556640625 +93664 -0.339263916015625 +93665 -0.3775634765625 +93666 -0.445709228515625 +93667 -0.535064697265625 +93668 -0.629058837890625 +93669 -0.697601318359375 +93670 -0.70391845703125 +93671 -0.6424560546875 +93672 -0.491241455078125 +93673 -0.265716552734375 +93674 -0.023712158203125 +93675 0.201751708984375 +93676 0.375823974609375 +93677 0.485076904296875 +93678 0.56884765625 +93679 0.634765625 +93680 0.63763427734375 +93681 0.5660400390625 +93682 0.4720458984375 +93683 0.40692138671875 +93684 0.3778076171875 +93685 0.376953125 +93686 0.371978759765625 +93687 0.313140869140625 +93688 0.184417724609375 +93689 0.011199951171875 +93690 -0.171051025390625 +93691 -0.33740234375 +93692 -0.47198486328125 +93693 -0.560394287109375 +93694 -0.58056640625 +93695 -0.54754638671875 +93696 -0.508575439453125 +93697 -0.459503173828125 +93698 -0.394378662109375 +93699 -0.35260009765625 +93700 -0.31170654296875 +93701 -0.197418212890625 +93702 -0.007965087890625 +93703 0.207489013671875 +93704 0.409210205078125 +93705 0.57208251953125 +93706 0.66595458984375 +93707 0.65875244140625 +93708 0.56744384765625 +93709 0.431396484375 +93710 0.29443359375 +93711 0.182464599609375 +93712 0.06365966796875 +93713 -0.075958251953125 +93714 -0.189422607421875 +93715 -0.271942138671875 +93716 -0.342529296875 +93717 -0.364166259765625 +93718 -0.327239990234375 +93719 -0.2769775390625 +93720 -0.253692626953125 +93721 -0.24365234375 +93722 -0.1983642578125 +93723 -0.116241455078125 +93724 -0.036834716796875 +93725 0.034881591796875 +93726 0.09124755859375 +93727 0.10888671875 +93728 0.125518798828125 +93729 0.15771484375 +93730 0.17828369140625 +93731 0.17108154296875 +93732 0.129974365234375 +93733 0.082427978515625 +93734 0.027679443359375 +93735 -0.065643310546875 +93736 -0.15936279296875 +93737 -0.21307373046875 +93738 -0.234649658203125 +93739 -0.2001953125 +93740 -0.119171142578125 +93741 -0.024749755859375 +93742 0.085784912109375 +93743 0.178131103515625 +93744 0.215576171875 +93745 0.211456298828125 +93746 0.17523193359375 +93747 0.128753662109375 +93748 0.1019287109375 +93749 0.0743408203125 +93750 0.04327392578125 +93751 0.038177490234375 +93752 0.076263427734375 +93753 0.14105224609375 +93754 0.186431884765625 +93755 0.188812255859375 +93756 0.1390380859375 +93757 0.041778564453125 +93758 -0.079437255859375 +93759 -0.219390869140625 +93760 -0.367828369140625 +93761 -0.494873046875 +93762 -0.556243896484375 +93763 -0.508697509765625 +93764 -0.3756103515625 +93765 -0.218902587890625 +93766 -0.063751220703125 +93767 0.091552734375 +93768 0.23602294921875 +93769 0.342987060546875 +93770 0.39520263671875 +93771 0.389373779296875 +93772 0.324249267578125 +93773 0.224090576171875 +93774 0.124267578125 +93775 0.037078857421875 +93776 -0.010101318359375 +93777 -0.019439697265625 +93778 -0.022796630859375 +93779 -0.001556396484375 +93780 0.056304931640625 +93781 0.106719970703125 +93782 0.096893310546875 +93783 0.042694091796875 +93784 -0.018035888671875 +93785 -0.07586669921875 +93786 -0.11944580078125 +93787 -0.15972900390625 +93788 -0.202606201171875 +93789 -0.24859619140625 +93790 -0.30517578125 +93791 -0.36212158203125 +93792 -0.39141845703125 +93793 -0.35528564453125 +93794 -0.249969482421875 +93795 -0.092864990234375 +93796 0.08905029296875 +93797 0.2352294921875 +93798 0.318817138671875 +93799 0.358642578125 +93800 0.347747802734375 +93801 0.28564453125 +93802 0.223175048828125 +93803 0.196746826171875 +93804 0.179840087890625 +93805 0.155548095703125 +93806 0.151214599609375 +93807 0.156951904296875 +93808 0.13177490234375 +93809 0.100799560546875 +93810 0.087127685546875 +93811 0.05487060546875 +93812 -0.009002685546875 +93813 -0.10400390625 +93814 -0.229400634765625 +93815 -0.35552978515625 +93816 -0.441925048828125 +93817 -0.473846435546875 +93818 -0.464813232421875 +93819 -0.419097900390625 +93820 -0.334320068359375 +93821 -0.227935791015625 +93822 -0.12347412109375 +93823 -0.02764892578125 +93824 0.077667236328125 +93825 0.2132568359375 +93826 0.38885498046875 +93827 0.582794189453125 +93828 0.734039306640625 +93829 0.800140380859375 +93830 0.7783203125 +93831 0.6651611328125 +93832 0.45965576171875 +93833 0.199188232421875 +93834 -0.050689697265625 +93835 -0.23297119140625 +93836 -0.33013916015625 +93837 -0.368408203125 +93838 -0.378936767578125 +93839 -0.376983642578125 +93840 -0.37969970703125 +93841 -0.391510009765625 +93842 -0.385345458984375 +93843 -0.3419189453125 +93844 -0.28289794921875 +93845 -0.251617431640625 +93846 -0.266143798828125 +93847 -0.273345947265625 +93848 -0.216796875 +93849 -0.128265380859375 +93850 -0.068145751953125 +93851 -0.0430908203125 +93852 -0.024444580078125 +93853 0.020721435546875 +93854 0.124481201171875 +93855 0.25787353515625 +93856 0.379119873046875 +93857 0.47991943359375 +93858 0.5281982421875 +93859 0.511138916015625 +93860 0.456207275390625 +93861 0.407470703125 +93862 0.383758544921875 +93863 0.35687255859375 +93864 0.31182861328125 +93865 0.250885009765625 +93866 0.1654052734375 +93867 0.035247802734375 +93868 -0.142059326171875 +93869 -0.33563232421875 +93870 -0.5345458984375 +93871 -0.72186279296875 +93872 -0.836669921875 +93873 -0.8326416015625 +93874 -0.7296142578125 +93875 -0.582550048828125 +93876 -0.440093994140625 +93877 -0.324310302734375 +93878 -0.20147705078125 +93879 -0.044647216796875 +93880 0.103973388671875 +93881 0.202392578125 +93882 0.264495849609375 +93883 0.338897705078125 +93884 0.443817138671875 +93885 0.545074462890625 +93886 0.6173095703125 +93887 0.6524658203125 +93888 0.66339111328125 +93889 0.6561279296875 +93890 0.606781005859375 +93891 0.501190185546875 +93892 0.352783203125 +93893 0.176544189453125 +93894 -0.034820556640625 +93895 -0.258209228515625 +93896 -0.44244384765625 +93897 -0.5753173828125 +93898 -0.65203857421875 +93899 -0.641632080078125 +93900 -0.562164306640625 +93901 -0.458038330078125 +93902 -0.350555419921875 +93903 -0.260528564453125 +93904 -0.192108154296875 +93905 -0.141937255859375 +93906 -0.1021728515625 +93907 -0.062896728515625 +93908 -0.011932373046875 +93909 0.062835693359375 +93910 0.148712158203125 +93911 0.241729736328125 +93912 0.34912109375 +93913 0.457305908203125 +93914 0.54388427734375 +93915 0.5728759765625 +93916 0.506591796875 +93917 0.351226806640625 +93918 0.146514892578125 +93919 -0.05523681640625 +93920 -0.21624755859375 +93921 -0.334930419921875 +93922 -0.402984619140625 +93923 -0.4412841796875 +93924 -0.49578857421875 +93925 -0.5601806640625 +93926 -0.600738525390625 +93927 -0.584228515625 +93928 -0.47930908203125 +93929 -0.27935791015625 +93930 -0.0089111328125 +93931 0.268798828125 +93932 0.482818603515625 +93933 0.60369873046875 +93934 0.650421142578125 +93935 0.66400146484375 +93936 0.6414794921875 +93937 0.572540283203125 +93938 0.498138427734375 +93939 0.439453125 +93940 0.375518798828125 +93941 0.274505615234375 +93942 0.1087646484375 +93943 -0.099395751953125 +93944 -0.3182373046875 +93945 -0.5489501953125 +93946 -0.7738037109375 +93947 -0.86383056640625 +93948 -0.870391845703125 +93949 -0.86895751953125 +93950 -0.861053466796875 +93951 -0.765869140625 +93952 -0.5301513671875 +93953 -0.214691162109375 +93954 0.137359619140625 +93955 0.474822998046875 +93956 0.76239013671875 +93957 0.867462158203125 +93958 0.870361328125 +93959 0.86480712890625 +93960 0.831817626953125 +93961 0.677581787109375 +93962 0.495880126953125 +93963 0.30767822265625 +93964 0.116180419921875 +93965 -0.110748291015625 +93966 -0.381805419921875 +93967 -0.6572265625 +93968 -0.857421875 +93969 -0.870391845703125 +93970 -0.870391845703125 +93971 -0.86444091796875 +93972 -0.85723876953125 +93973 -0.790008544921875 +93974 -0.62847900390625 +93975 -0.3956298828125 +93976 -0.126708984375 +93977 0.150115966796875 +93978 0.424041748046875 +93979 0.670623779296875 +93980 0.854522705078125 +93981 0.866485595703125 +93982 0.86920166015625 +93983 0.8653564453125 +93984 0.857147216796875 +93985 0.766845703125 +93986 0.628509521484375 +93987 0.462127685546875 +93988 0.297210693359375 +93989 0.14862060546875 +93990 -0.00537109375 +93991 -0.15753173828125 +93992 -0.31304931640625 +93993 -0.48876953125 +93994 -0.6416015625 +93995 -0.751373291015625 +93996 -0.84619140625 +93997 -0.861297607421875 +93998 -0.863250732421875 +93999 -0.856597900390625 +94000 -0.7498779296875 +94001 -0.624542236328125 +94002 -0.47808837890625 +94003 -0.253387451171875 +94004 0.003692626953125 +94005 0.2257080078125 +94006 0.427154541015625 +94007 0.643218994140625 +94008 0.855926513671875 +94009 0.870361328125 +94010 0.870361328125 +94011 0.862762451171875 +94012 0.79669189453125 +94013 0.595794677734375 +94014 0.362152099609375 +94015 0.1270751953125 +94016 -0.086944580078125 +94017 -0.2784423828125 +94018 -0.484832763671875 +94019 -0.729583740234375 +94020 -0.86688232421875 +94021 -0.870391845703125 +94022 -0.86859130859375 +94023 -0.86279296875 +94024 -0.817962646484375 +94025 -0.6116943359375 +94026 -0.3128662109375 +94027 0.039398193359375 +94028 0.422821044921875 +94029 0.805145263671875 +94030 0.870361328125 +94031 0.870361328125 +94032 0.860015869140625 +94033 0.727935791015625 +94034 0.48114013671875 +94035 0.2059326171875 +94036 -0.06103515625 +94037 -0.29913330078125 +94038 -0.516204833984375 +94039 -0.7252197265625 +94040 -0.85980224609375 +94041 -0.870391845703125 +94042 -0.870391845703125 +94043 -0.858062744140625 +94044 -0.673004150390625 +94045 -0.42694091796875 +94046 -0.2100830078125 +94047 -0.0362548828125 +94048 0.10943603515625 +94049 0.23516845703125 +94050 0.373687744140625 +94051 0.517791748046875 +94052 0.602783203125 +94053 0.635711669921875 +94054 0.655181884765625 +94055 0.65948486328125 +94056 0.651275634765625 +94057 0.61846923828125 +94058 0.53753662109375 +94059 0.404144287109375 +94060 0.22186279296875 +94061 0.003997802734375 +94062 -0.22100830078125 +94063 -0.42449951171875 +94064 -0.579833984375 +94065 -0.641876220703125 +94066 -0.6177978515625 +94067 -0.575531005859375 +94068 -0.526336669921875 +94069 -0.42645263671875 +94070 -0.2581787109375 +94071 -0.068695068359375 +94072 0.09222412109375 +94073 0.232147216796875 +94074 0.3509521484375 +94075 0.410064697265625 +94076 0.372955322265625 +94077 0.2554931640625 +94078 0.10711669921875 +94079 -0.052886962890625 +94080 -0.186279296875 +94081 -0.23291015625 +94082 -0.209442138671875 +94083 -0.174163818359375 +94084 -0.126739501953125 +94085 -0.048126220703125 +94086 0.0426025390625 +94087 0.10748291015625 +94088 0.1409912109375 +94089 0.19708251953125 +94090 0.273651123046875 +94091 0.31768798828125 +94092 0.341094970703125 +94093 0.368011474609375 +94094 0.37249755859375 +94095 0.30072021484375 +94096 0.1517333984375 +94097 -0.01470947265625 +94098 -0.1883544921875 +94099 -0.372711181640625 +94100 -0.51397705078125 +94101 -0.57177734375 +94102 -0.53948974609375 +94103 -0.43511962890625 +94104 -0.2962646484375 +94105 -0.161102294921875 +94106 -0.0435791015625 +94107 0.060394287109375 +94108 0.13665771484375 +94109 0.170135498046875 +94110 0.16552734375 +94111 0.15728759765625 +94112 0.150787353515625 +94113 0.12200927734375 +94114 0.080108642578125 +94115 0.05126953125 +94116 0.062896728515625 +94117 0.09271240234375 +94118 0.092987060546875 +94119 0.07855224609375 +94120 0.06427001953125 +94121 0.0347900390625 +94122 -0.01171875 +94123 -0.056060791015625 +94124 -0.055511474609375 +94125 -0.010467529296875 +94126 0.02508544921875 +94127 0.025665283203125 +94128 0.017333984375 +94129 0.00189208984375 +94130 -0.03173828125 +94131 -0.071502685546875 +94132 -0.13543701171875 +94133 -0.219970703125 +94134 -0.300506591796875 +94135 -0.376312255859375 +94136 -0.416107177734375 +94137 -0.371124267578125 +94138 -0.242279052734375 +94139 -0.069732666015625 +94140 0.125640869140625 +94141 0.31268310546875 +94142 0.45501708984375 +94143 0.554779052734375 +94144 0.61065673828125 +94145 0.610931396484375 +94146 0.531463623046875 +94147 0.3883056640625 +94148 0.23468017578125 +94149 0.095245361328125 +94150 -0.00396728515625 +94151 -0.04852294921875 +94152 -0.055145263671875 +94153 -0.0758056640625 +94154 -0.138702392578125 +94155 -0.209197998046875 +94156 -0.289031982421875 +94157 -0.37884521484375 +94158 -0.456329345703125 +94159 -0.51641845703125 +94160 -0.519287109375 +94161 -0.458251953125 +94162 -0.384796142578125 +94163 -0.323699951171875 +94164 -0.269287109375 +94165 -0.1951904296875 +94166 -0.100006103515625 +94167 -0.01055908203125 +94168 0.1033935546875 +94169 0.24908447265625 +94170 0.373199462890625 +94171 0.45806884765625 +94172 0.511474609375 +94173 0.565399169921875 +94174 0.61138916015625 +94175 0.5897216796875 +94176 0.4906005859375 +94177 0.33148193359375 +94178 0.147796630859375 +94179 -0.01873779296875 +94180 -0.140289306640625 +94181 -0.191986083984375 +94182 -0.184295654296875 +94183 -0.161834716796875 +94184 -0.166595458984375 +94185 -0.19390869140625 +94186 -0.22442626953125 +94187 -0.279754638671875 +94188 -0.3389892578125 +94189 -0.3543701171875 +94190 -0.348175048828125 +94191 -0.32598876953125 +94192 -0.2581787109375 +94193 -0.139801025390625 +94194 0.014617919921875 +94195 0.144378662109375 +94196 0.221038818359375 +94197 0.27069091796875 +94198 0.294036865234375 +94199 0.311767578125 +94200 0.339141845703125 +94201 0.360260009765625 +94202 0.360504150390625 +94203 0.308380126953125 +94204 0.18170166015625 +94205 0.0047607421875 +94206 -0.17559814453125 +94207 -0.3143310546875 +94208 -0.36785888671875 +94209 -0.36248779296875 +94210 -0.343536376953125 +94211 -0.3018798828125 +94212 -0.231414794921875 +94213 -0.117645263671875 +94214 0.007049560546875 +94215 0.087982177734375 +94216 0.13946533203125 +94217 0.17425537109375 +94218 0.188201904296875 +94219 0.171234130859375 +94220 0.118438720703125 +94221 0.05706787109375 +94222 -0.010711669921875 +94223 -0.0914306640625 +94224 -0.162322998046875 +94225 -0.194549560546875 +94226 -0.1492919921875 +94227 -0.02166748046875 +94228 0.124053955078125 +94229 0.211151123046875 +94230 0.240447998046875 +94231 0.242218017578125 +94232 0.2257080078125 +94233 0.194366455078125 +94234 0.115509033203125 +94235 0.0128173828125 +94236 -0.053802490234375 +94237 -0.110626220703125 +94238 -0.199493408203125 +94239 -0.29437255859375 +94240 -0.33221435546875 +94241 -0.27972412109375 +94242 -0.185333251953125 +94243 -0.128204345703125 +94244 -0.115692138671875 +94245 -0.116455078125 +94246 -0.105926513671875 +94247 -0.053955078125 +94248 0.048797607421875 +94249 0.157318115234375 +94250 0.212005615234375 +94251 0.218475341796875 +94252 0.23724365234375 +94253 0.30535888671875 +94254 0.38128662109375 +94255 0.404449462890625 +94256 0.3944091796875 +94257 0.3885498046875 +94258 0.362640380859375 +94259 0.27362060546875 +94260 0.11712646484375 +94261 -0.054901123046875 +94262 -0.19085693359375 +94263 -0.28570556640625 +94264 -0.339263916015625 +94265 -0.3775634765625 +94266 -0.445709228515625 +94267 -0.535064697265625 +94268 -0.629058837890625 +94269 -0.697601318359375 +94270 -0.70391845703125 +94271 -0.6424560546875 +94272 -0.491241455078125 +94273 -0.265716552734375 +94274 -0.023712158203125 +94275 0.201751708984375 +94276 0.375823974609375 +94277 0.485076904296875 +94278 0.56884765625 +94279 0.634765625 +94280 0.63763427734375 +94281 0.5660400390625 +94282 0.4720458984375 +94283 0.40692138671875 +94284 0.3778076171875 +94285 0.376953125 +94286 0.371978759765625 +94287 0.313140869140625 +94288 0.184417724609375 +94289 0.011199951171875 +94290 -0.171051025390625 +94291 -0.33740234375 +94292 -0.47198486328125 +94293 -0.560394287109375 +94294 -0.58056640625 +94295 -0.54754638671875 +94296 -0.508575439453125 +94297 -0.459503173828125 +94298 -0.394378662109375 +94299 -0.35260009765625 +94300 -0.31170654296875 +94301 -0.197418212890625 +94302 -0.007965087890625 +94303 0.207489013671875 +94304 0.409210205078125 +94305 0.57208251953125 +94306 0.66595458984375 +94307 0.65875244140625 +94308 0.56744384765625 +94309 0.431396484375 +94310 0.29443359375 +94311 0.182464599609375 +94312 0.06365966796875 +94313 -0.075958251953125 +94314 -0.189422607421875 +94315 -0.271942138671875 +94316 -0.342529296875 +94317 -0.364166259765625 +94318 -0.327239990234375 +94319 -0.2769775390625 +94320 -0.253692626953125 +94321 -0.24365234375 +94322 -0.1983642578125 +94323 -0.116241455078125 +94324 -0.036834716796875 +94325 0.034881591796875 +94326 0.09124755859375 +94327 0.10888671875 +94328 0.125518798828125 +94329 0.15771484375 +94330 0.17828369140625 +94331 0.17108154296875 +94332 0.129974365234375 +94333 0.082427978515625 +94334 0.027679443359375 +94335 -0.065643310546875 +94336 -0.15936279296875 +94337 -0.21307373046875 +94338 -0.234649658203125 +94339 -0.2001953125 +94340 -0.119171142578125 +94341 -0.024749755859375 +94342 0.085784912109375 +94343 0.178131103515625 +94344 0.215576171875 +94345 0.211456298828125 +94346 0.17523193359375 +94347 0.128753662109375 +94348 0.1019287109375 +94349 0.0743408203125 +94350 0.04327392578125 +94351 0.038177490234375 +94352 0.076263427734375 +94353 0.14105224609375 +94354 0.186431884765625 +94355 0.188812255859375 +94356 0.1390380859375 +94357 0.041778564453125 +94358 -0.079437255859375 +94359 -0.219390869140625 +94360 -0.367828369140625 +94361 -0.494873046875 +94362 -0.556243896484375 +94363 -0.508697509765625 +94364 -0.3756103515625 +94365 -0.218902587890625 +94366 -0.063751220703125 +94367 0.091552734375 +94368 0.23602294921875 +94369 0.342987060546875 +94370 0.39520263671875 +94371 0.389373779296875 +94372 0.324249267578125 +94373 0.224090576171875 +94374 0.124267578125 +94375 0.037078857421875 +94376 -0.010101318359375 +94377 -0.019439697265625 +94378 -0.022796630859375 +94379 -0.001556396484375 +94380 0.056304931640625 +94381 0.106719970703125 +94382 0.096893310546875 +94383 0.042694091796875 +94384 -0.018035888671875 +94385 -0.07586669921875 +94386 -0.11944580078125 +94387 -0.15972900390625 +94388 -0.202606201171875 +94389 -0.24859619140625 +94390 -0.30517578125 +94391 -0.36212158203125 +94392 -0.39141845703125 +94393 -0.35528564453125 +94394 -0.249969482421875 +94395 -0.092864990234375 +94396 0.08905029296875 +94397 0.2352294921875 +94398 0.318817138671875 +94399 0.358642578125 +94400 0.347747802734375 +94401 0.28564453125 +94402 0.223175048828125 +94403 0.196746826171875 +94404 0.179840087890625 +94405 0.155548095703125 +94406 0.151214599609375 +94407 0.156951904296875 +94408 0.13177490234375 +94409 0.100799560546875 +94410 0.087127685546875 +94411 0.05487060546875 +94412 -0.009002685546875 +94413 -0.10400390625 +94414 -0.229400634765625 +94415 -0.35552978515625 +94416 -0.441925048828125 +94417 -0.473846435546875 +94418 -0.464813232421875 +94419 -0.419097900390625 +94420 -0.334320068359375 +94421 -0.227935791015625 +94422 -0.12347412109375 +94423 -0.02764892578125 +94424 0.077667236328125 +94425 0.2132568359375 +94426 0.38885498046875 +94427 0.582794189453125 +94428 0.734039306640625 +94429 0.800140380859375 +94430 0.7783203125 +94431 0.6651611328125 +94432 0.45965576171875 +94433 0.199188232421875 +94434 -0.050689697265625 +94435 -0.23297119140625 +94436 -0.33013916015625 +94437 -0.368408203125 +94438 -0.378936767578125 +94439 -0.376983642578125 +94440 -0.37969970703125 +94441 -0.391510009765625 +94442 -0.385345458984375 +94443 -0.3419189453125 +94444 -0.28289794921875 +94445 -0.251617431640625 +94446 -0.266143798828125 +94447 -0.273345947265625 +94448 -0.216796875 +94449 -0.128265380859375 +94450 -0.068145751953125 +94451 -0.0430908203125 +94452 -0.024444580078125 +94453 0.020721435546875 +94454 0.124481201171875 +94455 0.25787353515625 +94456 0.379119873046875 +94457 0.47991943359375 +94458 0.5281982421875 +94459 0.511138916015625 +94460 0.456207275390625 +94461 0.407470703125 +94462 0.383758544921875 +94463 0.35687255859375 +94464 0.31182861328125 +94465 0.250885009765625 +94466 0.1654052734375 +94467 0.035247802734375 +94468 -0.142059326171875 +94469 -0.33563232421875 +94470 -0.5345458984375 +94471 -0.72186279296875 +94472 -0.836669921875 +94473 -0.8326416015625 +94474 -0.7296142578125 +94475 -0.582550048828125 +94476 -0.440093994140625 +94477 -0.324310302734375 +94478 -0.20147705078125 +94479 -0.044647216796875 +94480 0.103973388671875 +94481 0.202392578125 +94482 0.264495849609375 +94483 0.338897705078125 +94484 0.443817138671875 +94485 0.545074462890625 +94486 0.6173095703125 +94487 0.6524658203125 +94488 0.66339111328125 +94489 0.6561279296875 +94490 0.606781005859375 +94491 0.501190185546875 +94492 0.352783203125 +94493 0.176544189453125 +94494 -0.034820556640625 +94495 -0.258209228515625 +94496 -0.44244384765625 +94497 -0.5753173828125 +94498 -0.65203857421875 +94499 -0.641632080078125 +94500 -0.562164306640625 +94501 -0.458038330078125 +94502 -0.350555419921875 +94503 -0.260528564453125 +94504 -0.192108154296875 +94505 -0.141937255859375 +94506 -0.1021728515625 +94507 -0.062896728515625 +94508 -0.011932373046875 +94509 0.062835693359375 +94510 0.148712158203125 +94511 0.241729736328125 +94512 0.34912109375 +94513 0.457305908203125 +94514 0.54388427734375 +94515 0.5728759765625 +94516 0.506591796875 +94517 0.351226806640625 +94518 0.146514892578125 +94519 -0.05523681640625 +94520 -0.21624755859375 +94521 -0.334930419921875 +94522 -0.402984619140625 +94523 -0.4412841796875 +94524 -0.49578857421875 +94525 -0.5601806640625 +94526 -0.600738525390625 +94527 -0.584228515625 +94528 -0.47930908203125 +94529 -0.27935791015625 +94530 -0.0089111328125 +94531 0.268798828125 +94532 0.482818603515625 +94533 0.60369873046875 +94534 0.650421142578125 +94535 0.66400146484375 +94536 0.6414794921875 +94537 0.572540283203125 +94538 0.498138427734375 +94539 0.439453125 +94540 0.375518798828125 +94541 0.274505615234375 +94542 0.1087646484375 +94543 -0.099395751953125 +94544 -0.3182373046875 +94545 -0.5489501953125 +94546 -0.7738037109375 +94547 -0.86383056640625 +94548 -0.870391845703125 +94549 -0.86895751953125 +94550 -0.861053466796875 +94551 -0.765869140625 +94552 -0.5301513671875 +94553 -0.214691162109375 +94554 0.137359619140625 +94555 0.474822998046875 +94556 0.76239013671875 +94557 0.867462158203125 +94558 0.870361328125 +94559 0.86480712890625 +94560 0.831817626953125 +94561 0.677581787109375 +94562 0.495880126953125 +94563 0.30767822265625 +94564 0.116180419921875 +94565 -0.110748291015625 +94566 -0.381805419921875 +94567 -0.6572265625 +94568 -0.857421875 +94569 -0.870391845703125 +94570 -0.870391845703125 +94571 -0.86444091796875 +94572 -0.85723876953125 +94573 -0.790008544921875 +94574 -0.62847900390625 +94575 -0.3956298828125 +94576 -0.126708984375 +94577 0.150115966796875 +94578 0.424041748046875 +94579 0.670623779296875 +94580 0.854522705078125 +94581 0.866485595703125 +94582 0.86920166015625 +94583 0.8653564453125 +94584 0.857147216796875 +94585 0.766845703125 +94586 0.628509521484375 +94587 0.462127685546875 +94588 0.297210693359375 +94589 0.14862060546875 +94590 -0.00537109375 +94591 -0.15753173828125 +94592 -0.31304931640625 +94593 -0.48876953125 +94594 -0.6416015625 +94595 -0.751373291015625 +94596 -0.84619140625 +94597 -0.861297607421875 +94598 -0.863250732421875 +94599 -0.856597900390625 +94600 -0.7498779296875 +94601 -0.624542236328125 +94602 -0.47808837890625 +94603 -0.253387451171875 +94604 0.003692626953125 +94605 0.2257080078125 +94606 0.427154541015625 +94607 0.643218994140625 +94608 0.855926513671875 +94609 0.870361328125 +94610 0.870361328125 +94611 0.862762451171875 +94612 0.79669189453125 +94613 0.595794677734375 +94614 0.362152099609375 +94615 0.1270751953125 +94616 -0.086944580078125 +94617 -0.2784423828125 +94618 -0.484832763671875 +94619 -0.729583740234375 +94620 -0.86688232421875 +94621 -0.870391845703125 +94622 -0.86859130859375 +94623 -0.86279296875 +94624 -0.817962646484375 +94625 -0.6116943359375 +94626 -0.3128662109375 +94627 0.039398193359375 +94628 0.422821044921875 +94629 0.805145263671875 +94630 0.870361328125 +94631 0.870361328125 +94632 0.860015869140625 +94633 0.727935791015625 +94634 0.48114013671875 +94635 0.2059326171875 +94636 -0.06103515625 +94637 -0.29913330078125 +94638 -0.516204833984375 +94639 -0.7252197265625 +94640 -0.85980224609375 +94641 -0.870391845703125 +94642 -0.870391845703125 +94643 -0.858062744140625 +94644 -0.673004150390625 +94645 -0.42694091796875 +94646 -0.2100830078125 +94647 -0.0362548828125 +94648 0.10943603515625 +94649 0.23516845703125 +94650 0.373687744140625 +94651 0.517791748046875 +94652 0.602783203125 +94653 0.635711669921875 +94654 0.655181884765625 +94655 0.65948486328125 +94656 0.651275634765625 +94657 0.61846923828125 +94658 0.53753662109375 +94659 0.404144287109375 +94660 0.22186279296875 +94661 0.003997802734375 +94662 -0.22100830078125 +94663 -0.42449951171875 +94664 -0.579833984375 +94665 -0.641876220703125 +94666 -0.6177978515625 +94667 -0.575531005859375 +94668 -0.526336669921875 +94669 -0.42645263671875 +94670 -0.2581787109375 +94671 -0.068695068359375 +94672 0.09222412109375 +94673 0.232147216796875 +94674 0.3509521484375 +94675 0.410064697265625 +94676 0.372955322265625 +94677 0.2554931640625 +94678 0.10711669921875 +94679 -0.052886962890625 +94680 -0.186279296875 +94681 -0.23291015625 +94682 -0.209442138671875 +94683 -0.174163818359375 +94684 -0.126739501953125 +94685 -0.048126220703125 +94686 0.0426025390625 +94687 0.10748291015625 +94688 0.1409912109375 +94689 0.19708251953125 +94690 0.273651123046875 +94691 0.31768798828125 +94692 0.341094970703125 +94693 0.368011474609375 +94694 0.37249755859375 +94695 0.30072021484375 +94696 0.1517333984375 +94697 -0.01470947265625 +94698 -0.1883544921875 +94699 -0.372711181640625 +94700 -0.51397705078125 +94701 -0.57177734375 +94702 -0.53948974609375 +94703 -0.43511962890625 +94704 -0.2962646484375 +94705 -0.161102294921875 +94706 -0.0435791015625 +94707 0.060394287109375 +94708 0.13665771484375 +94709 0.170135498046875 +94710 0.16552734375 +94711 0.15728759765625 +94712 0.150787353515625 +94713 0.12200927734375 +94714 0.080108642578125 +94715 0.05126953125 +94716 0.062896728515625 +94717 0.09271240234375 +94718 0.092987060546875 +94719 0.07855224609375 +94720 0.06427001953125 +94721 0.0347900390625 +94722 -0.01171875 +94723 -0.056060791015625 +94724 -0.055511474609375 +94725 -0.010467529296875 +94726 0.02508544921875 +94727 0.025665283203125 +94728 0.017333984375 +94729 0.00189208984375 +94730 -0.03173828125 +94731 -0.071502685546875 +94732 -0.13543701171875 +94733 -0.219970703125 +94734 -0.300506591796875 +94735 -0.376312255859375 +94736 -0.416107177734375 +94737 -0.371124267578125 +94738 -0.242279052734375 +94739 -0.069732666015625 +94740 0.125640869140625 +94741 0.31268310546875 +94742 0.45501708984375 +94743 0.554779052734375 +94744 0.61065673828125 +94745 0.610931396484375 +94746 0.531463623046875 +94747 0.3883056640625 +94748 0.23468017578125 +94749 0.095245361328125 +94750 -0.00396728515625 +94751 -0.04852294921875 +94752 -0.055145263671875 +94753 -0.0758056640625 +94754 -0.138702392578125 +94755 -0.209197998046875 +94756 -0.289031982421875 +94757 -0.37884521484375 +94758 -0.456329345703125 +94759 -0.51641845703125 +94760 -0.519287109375 +94761 -0.458251953125 +94762 -0.384796142578125 +94763 -0.323699951171875 +94764 -0.269287109375 +94765 -0.1951904296875 +94766 -0.100006103515625 +94767 -0.01055908203125 +94768 0.1033935546875 +94769 0.24908447265625 +94770 0.373199462890625 +94771 0.45806884765625 +94772 0.511474609375 +94773 0.565399169921875 +94774 0.61138916015625 +94775 0.5897216796875 +94776 0.4906005859375 +94777 0.33148193359375 +94778 0.147796630859375 +94779 -0.01873779296875 +94780 -0.140289306640625 +94781 -0.191986083984375 +94782 -0.184295654296875 +94783 -0.161834716796875 +94784 -0.166595458984375 +94785 -0.19390869140625 +94786 -0.22442626953125 +94787 -0.279754638671875 +94788 -0.3389892578125 +94789 -0.3543701171875 +94790 -0.348175048828125 +94791 -0.32598876953125 +94792 -0.2581787109375 +94793 -0.139801025390625 +94794 0.014617919921875 +94795 0.144378662109375 +94796 0.221038818359375 +94797 0.27069091796875 +94798 0.294036865234375 +94799 0.311767578125 +94800 0.339141845703125 +94801 0.360260009765625 +94802 0.360504150390625 +94803 0.308380126953125 +94804 0.18170166015625 +94805 0.0047607421875 +94806 -0.17559814453125 +94807 -0.3143310546875 +94808 -0.36785888671875 +94809 -0.36248779296875 +94810 -0.343536376953125 +94811 -0.3018798828125 +94812 -0.231414794921875 +94813 -0.117645263671875 +94814 0.007049560546875 +94815 0.087982177734375 +94816 0.13946533203125 +94817 0.17425537109375 +94818 0.188201904296875 +94819 0.171234130859375 +94820 0.118438720703125 +94821 0.05706787109375 +94822 -0.010711669921875 +94823 -0.0914306640625 +94824 -0.162322998046875 +94825 -0.194549560546875 +94826 -0.1492919921875 +94827 -0.02166748046875 +94828 0.124053955078125 +94829 0.211151123046875 +94830 0.240447998046875 +94831 0.242218017578125 +94832 0.2257080078125 +94833 0.194366455078125 +94834 0.115509033203125 +94835 0.0128173828125 +94836 -0.053802490234375 +94837 -0.110626220703125 +94838 -0.199493408203125 +94839 -0.29437255859375 +94840 -0.33221435546875 +94841 -0.27972412109375 +94842 -0.185333251953125 +94843 -0.128204345703125 +94844 -0.115692138671875 +94845 -0.116455078125 +94846 -0.105926513671875 +94847 -0.053955078125 +94848 0.048797607421875 +94849 0.157318115234375 +94850 0.212005615234375 +94851 0.218475341796875 +94852 0.23724365234375 +94853 0.30535888671875 +94854 0.38128662109375 +94855 0.404449462890625 +94856 0.3944091796875 +94857 0.3885498046875 +94858 0.362640380859375 +94859 0.27362060546875 +94860 0.11712646484375 +94861 -0.054901123046875 +94862 -0.19085693359375 +94863 -0.28570556640625 +94864 -0.339263916015625 +94865 -0.3775634765625 +94866 -0.445709228515625 +94867 -0.535064697265625 +94868 -0.629058837890625 +94869 -0.697601318359375 +94870 -0.70391845703125 +94871 -0.6424560546875 +94872 -0.491241455078125 +94873 -0.265716552734375 +94874 -0.023712158203125 +94875 0.201751708984375 +94876 0.375823974609375 +94877 0.485076904296875 +94878 0.56884765625 +94879 0.634765625 +94880 0.63763427734375 +94881 0.5660400390625 +94882 0.4720458984375 +94883 0.40692138671875 +94884 0.3778076171875 +94885 0.376953125 +94886 0.371978759765625 +94887 0.313140869140625 +94888 0.184417724609375 +94889 0.011199951171875 +94890 -0.171051025390625 +94891 -0.33740234375 +94892 -0.47198486328125 +94893 -0.560394287109375 +94894 -0.58056640625 +94895 -0.54754638671875 +94896 -0.508575439453125 +94897 -0.459503173828125 +94898 -0.394378662109375 +94899 -0.35260009765625 +94900 -0.31170654296875 +94901 -0.197418212890625 +94902 -0.007965087890625 +94903 0.207489013671875 +94904 0.409210205078125 +94905 0.57208251953125 +94906 0.66595458984375 +94907 0.65875244140625 +94908 0.56744384765625 +94909 0.431396484375 +94910 0.29443359375 +94911 0.182464599609375 +94912 0.06365966796875 +94913 -0.075958251953125 +94914 -0.189422607421875 +94915 -0.271942138671875 +94916 -0.342529296875 +94917 -0.364166259765625 +94918 -0.327239990234375 +94919 -0.2769775390625 +94920 -0.253692626953125 +94921 -0.24365234375 +94922 -0.1983642578125 +94923 -0.116241455078125 +94924 -0.036834716796875 +94925 0.034881591796875 +94926 0.09124755859375 +94927 0.10888671875 +94928 0.125518798828125 +94929 0.15771484375 +94930 0.17828369140625 +94931 0.17108154296875 +94932 0.129974365234375 +94933 0.082427978515625 +94934 0.027679443359375 +94935 -0.065643310546875 +94936 -0.15936279296875 +94937 -0.21307373046875 +94938 -0.234649658203125 +94939 -0.2001953125 +94940 -0.119171142578125 +94941 -0.024749755859375 +94942 0.085784912109375 +94943 0.178131103515625 +94944 0.215576171875 +94945 0.211456298828125 +94946 0.17523193359375 +94947 0.128753662109375 +94948 0.1019287109375 +94949 0.0743408203125 +94950 0.04327392578125 +94951 0.038177490234375 +94952 0.076263427734375 +94953 0.14105224609375 +94954 0.186431884765625 +94955 0.188812255859375 +94956 0.1390380859375 +94957 0.041778564453125 +94958 -0.079437255859375 +94959 -0.219390869140625 +94960 -0.367828369140625 +94961 -0.494873046875 +94962 -0.556243896484375 +94963 -0.508697509765625 +94964 -0.3756103515625 +94965 -0.218902587890625 +94966 -0.063751220703125 +94967 0.091552734375 +94968 0.23602294921875 +94969 0.342987060546875 +94970 0.39520263671875 +94971 0.389373779296875 +94972 0.324249267578125 +94973 0.224090576171875 +94974 0.124267578125 +94975 0.037078857421875 +94976 -0.010101318359375 +94977 -0.019439697265625 +94978 -0.022796630859375 +94979 -0.001556396484375 +94980 0.056304931640625 +94981 0.106719970703125 +94982 0.096893310546875 +94983 0.042694091796875 +94984 -0.018035888671875 +94985 -0.07586669921875 +94986 -0.11944580078125 +94987 -0.15972900390625 +94988 -0.202606201171875 +94989 -0.24859619140625 +94990 -0.30517578125 +94991 -0.36212158203125 +94992 -0.39141845703125 +94993 -0.35528564453125 +94994 -0.249969482421875 +94995 -0.092864990234375 +94996 0.08905029296875 +94997 0.2352294921875 +94998 0.318817138671875 +94999 0.358642578125 +95000 0.347747802734375 +95001 0.28564453125 +95002 0.223175048828125 +95003 0.196746826171875 +95004 0.179840087890625 +95005 0.155548095703125 +95006 0.151214599609375 +95007 0.156951904296875 +95008 0.13177490234375 +95009 0.100799560546875 +95010 0.087127685546875 +95011 0.05487060546875 +95012 -0.009002685546875 +95013 -0.10400390625 +95014 -0.229400634765625 +95015 -0.35552978515625 +95016 -0.441925048828125 +95017 -0.473846435546875 +95018 -0.464813232421875 +95019 -0.419097900390625 +95020 -0.334320068359375 +95021 -0.227935791015625 +95022 -0.12347412109375 +95023 -0.02764892578125 +95024 0.077667236328125 +95025 0.2132568359375 +95026 0.38885498046875 +95027 0.582794189453125 +95028 0.734039306640625 +95029 0.800140380859375 +95030 0.7783203125 +95031 0.6651611328125 +95032 0.45965576171875 +95033 0.199188232421875 +95034 -0.050689697265625 +95035 -0.23297119140625 +95036 -0.33013916015625 +95037 -0.368408203125 +95038 -0.378936767578125 +95039 -0.376983642578125 +95040 -0.37969970703125 +95041 -0.391510009765625 +95042 -0.385345458984375 +95043 -0.3419189453125 +95044 -0.28289794921875 +95045 -0.251617431640625 +95046 -0.266143798828125 +95047 -0.273345947265625 +95048 -0.216796875 +95049 -0.128265380859375 +95050 -0.068145751953125 +95051 -0.0430908203125 +95052 -0.024444580078125 +95053 0.020721435546875 +95054 0.124481201171875 +95055 0.25787353515625 +95056 0.379119873046875 +95057 0.47991943359375 +95058 0.5281982421875 +95059 0.511138916015625 +95060 0.456207275390625 +95061 0.407470703125 +95062 0.383758544921875 +95063 0.35687255859375 +95064 0.31182861328125 +95065 0.250885009765625 +95066 0.1654052734375 +95067 0.035247802734375 +95068 -0.142059326171875 +95069 -0.33563232421875 +95070 -0.5345458984375 +95071 -0.72186279296875 +95072 -0.836669921875 +95073 -0.8326416015625 +95074 -0.7296142578125 +95075 -0.582550048828125 +95076 -0.440093994140625 +95077 -0.324310302734375 +95078 -0.20147705078125 +95079 -0.044647216796875 +95080 0.103973388671875 +95081 0.202392578125 +95082 0.264495849609375 +95083 0.338897705078125 +95084 0.443817138671875 +95085 0.545074462890625 +95086 0.6173095703125 +95087 0.6524658203125 +95088 0.66339111328125 +95089 0.6561279296875 +95090 0.606781005859375 +95091 0.501190185546875 +95092 0.352783203125 +95093 0.176544189453125 +95094 -0.034820556640625 +95095 -0.258209228515625 +95096 -0.44244384765625 +95097 -0.5753173828125 +95098 -0.65203857421875 +95099 -0.641632080078125 +95100 -0.562164306640625 +95101 -0.458038330078125 +95102 -0.350555419921875 +95103 -0.260528564453125 +95104 -0.192108154296875 +95105 -0.141937255859375 +95106 -0.1021728515625 +95107 -0.062896728515625 +95108 -0.011932373046875 +95109 0.062835693359375 +95110 0.148712158203125 +95111 0.241729736328125 +95112 0.34912109375 +95113 0.457305908203125 +95114 0.54388427734375 +95115 0.5728759765625 +95116 0.506591796875 +95117 0.351226806640625 +95118 0.146514892578125 +95119 -0.05523681640625 +95120 -0.21624755859375 +95121 -0.334930419921875 +95122 -0.402984619140625 +95123 -0.4412841796875 +95124 -0.49578857421875 +95125 -0.5601806640625 +95126 -0.600738525390625 +95127 -0.584228515625 +95128 -0.47930908203125 +95129 -0.27935791015625 +95130 -0.0089111328125 +95131 0.268798828125 +95132 0.482818603515625 +95133 0.60369873046875 +95134 0.650421142578125 +95135 0.66400146484375 +95136 0.6414794921875 +95137 0.572540283203125 +95138 0.498138427734375 +95139 0.439453125 +95140 0.375518798828125 +95141 0.274505615234375 +95142 0.1087646484375 +95143 -0.099395751953125 +95144 -0.3182373046875 +95145 -0.5489501953125 +95146 -0.7738037109375 +95147 -0.86383056640625 +95148 -0.870391845703125 +95149 -0.86895751953125 +95150 -0.861053466796875 +95151 -0.765869140625 +95152 -0.5301513671875 +95153 -0.214691162109375 +95154 0.137359619140625 +95155 0.474822998046875 +95156 0.76239013671875 +95157 0.867462158203125 +95158 0.870361328125 +95159 0.86480712890625 +95160 0.831817626953125 +95161 0.677581787109375 +95162 0.495880126953125 +95163 0.30767822265625 +95164 0.116180419921875 +95165 -0.110748291015625 +95166 -0.381805419921875 +95167 -0.6572265625 +95168 -0.857421875 +95169 -0.870391845703125 +95170 -0.870391845703125 +95171 -0.86444091796875 +95172 -0.85723876953125 +95173 -0.790008544921875 +95174 -0.62847900390625 +95175 -0.3956298828125 +95176 -0.126708984375 +95177 0.150115966796875 +95178 0.424041748046875 +95179 0.670623779296875 +95180 0.854522705078125 +95181 0.866485595703125 +95182 0.86920166015625 +95183 0.8653564453125 +95184 0.857147216796875 +95185 0.766845703125 +95186 0.628509521484375 +95187 0.462127685546875 +95188 0.297210693359375 +95189 0.14862060546875 +95190 -0.00537109375 +95191 -0.15753173828125 +95192 -0.31304931640625 +95193 -0.48876953125 +95194 -0.6416015625 +95195 -0.751373291015625 +95196 -0.84619140625 +95197 -0.861297607421875 +95198 -0.863250732421875 +95199 -0.856597900390625 +95200 -0.7498779296875 +95201 -0.624542236328125 +95202 -0.47808837890625 +95203 -0.253387451171875 +95204 0.003692626953125 +95205 0.2257080078125 +95206 0.427154541015625 +95207 0.643218994140625 +95208 0.855926513671875 +95209 0.870361328125 +95210 0.870361328125 +95211 0.862762451171875 +95212 0.79669189453125 +95213 0.595794677734375 +95214 0.362152099609375 +95215 0.1270751953125 +95216 -0.086944580078125 +95217 -0.2784423828125 +95218 -0.484832763671875 +95219 -0.729583740234375 +95220 -0.86688232421875 +95221 -0.870391845703125 +95222 -0.86859130859375 +95223 -0.86279296875 +95224 -0.817962646484375 +95225 -0.6116943359375 +95226 -0.3128662109375 +95227 0.039398193359375 +95228 0.422821044921875 +95229 0.805145263671875 +95230 0.870361328125 +95231 0.870361328125 +95232 0.860015869140625 +95233 0.727935791015625 +95234 0.48114013671875 +95235 0.2059326171875 +95236 -0.06103515625 +95237 -0.29913330078125 +95238 -0.516204833984375 +95239 -0.7252197265625 +95240 -0.85980224609375 +95241 -0.870391845703125 +95242 -0.870391845703125 +95243 -0.858062744140625 +95244 -0.673004150390625 +95245 -0.42694091796875 +95246 -0.2100830078125 +95247 -0.0362548828125 +95248 0.10943603515625 +95249 0.23516845703125 +95250 0.373687744140625 +95251 0.517791748046875 +95252 0.602783203125 +95253 0.635711669921875 +95254 0.655181884765625 +95255 0.65948486328125 +95256 0.651275634765625 +95257 0.61846923828125 +95258 0.53753662109375 +95259 0.404144287109375 +95260 0.22186279296875 +95261 0.003997802734375 +95262 -0.22100830078125 +95263 -0.42449951171875 +95264 -0.579833984375 +95265 -0.641876220703125 +95266 -0.6177978515625 +95267 -0.575531005859375 +95268 -0.526336669921875 +95269 -0.42645263671875 +95270 -0.2581787109375 +95271 -0.068695068359375 +95272 0.09222412109375 +95273 0.232147216796875 +95274 0.3509521484375 +95275 0.410064697265625 +95276 0.372955322265625 +95277 0.2554931640625 +95278 0.10711669921875 +95279 -0.052886962890625 +95280 -0.186279296875 +95281 -0.23291015625 +95282 -0.209442138671875 +95283 -0.174163818359375 +95284 -0.126739501953125 +95285 -0.048126220703125 +95286 0.0426025390625 +95287 0.10748291015625 +95288 0.1409912109375 +95289 0.19708251953125 +95290 0.273651123046875 +95291 0.31768798828125 +95292 0.341094970703125 +95293 0.368011474609375 +95294 0.37249755859375 +95295 0.30072021484375 +95296 0.1517333984375 +95297 -0.01470947265625 +95298 -0.1883544921875 +95299 -0.372711181640625 +95300 -0.51397705078125 +95301 -0.57177734375 +95302 -0.53948974609375 +95303 -0.43511962890625 +95304 -0.2962646484375 +95305 -0.161102294921875 +95306 -0.0435791015625 +95307 0.060394287109375 +95308 0.13665771484375 +95309 0.170135498046875 +95310 0.16552734375 +95311 0.15728759765625 +95312 0.150787353515625 +95313 0.12200927734375 +95314 0.080108642578125 +95315 0.05126953125 +95316 0.062896728515625 +95317 0.09271240234375 +95318 0.092987060546875 +95319 0.07855224609375 +95320 0.06427001953125 +95321 0.0347900390625 +95322 -0.01171875 +95323 -0.056060791015625 +95324 -0.055511474609375 +95325 -0.010467529296875 +95326 0.02508544921875 +95327 0.025665283203125 +95328 0.017333984375 +95329 0.00189208984375 +95330 -0.03173828125 +95331 -0.071502685546875 +95332 -0.13543701171875 +95333 -0.219970703125 +95334 -0.300506591796875 +95335 -0.376312255859375 +95336 -0.416107177734375 +95337 -0.371124267578125 +95338 -0.242279052734375 +95339 -0.069732666015625 +95340 0.125640869140625 +95341 0.31268310546875 +95342 0.45501708984375 +95343 0.554779052734375 +95344 0.61065673828125 +95345 0.610931396484375 +95346 0.531463623046875 +95347 0.3883056640625 +95348 0.23468017578125 +95349 0.095245361328125 +95350 -0.00396728515625 +95351 -0.04852294921875 +95352 -0.055145263671875 +95353 -0.0758056640625 +95354 -0.138702392578125 +95355 -0.209197998046875 +95356 -0.289031982421875 +95357 -0.37884521484375 +95358 -0.456329345703125 +95359 -0.51641845703125 +95360 -0.519287109375 +95361 -0.458251953125 +95362 -0.384796142578125 +95363 -0.323699951171875 +95364 -0.269287109375 +95365 -0.1951904296875 +95366 -0.100006103515625 +95367 -0.01055908203125 +95368 0.1033935546875 +95369 0.24908447265625 +95370 0.373199462890625 +95371 0.45806884765625 +95372 0.511474609375 +95373 0.565399169921875 +95374 0.61138916015625 +95375 0.5897216796875 +95376 0.4906005859375 +95377 0.33148193359375 +95378 0.147796630859375 +95379 -0.01873779296875 +95380 -0.140289306640625 +95381 -0.191986083984375 +95382 -0.184295654296875 +95383 -0.161834716796875 +95384 -0.166595458984375 +95385 -0.19390869140625 +95386 -0.22442626953125 +95387 -0.279754638671875 +95388 -0.3389892578125 +95389 -0.3543701171875 +95390 -0.348175048828125 +95391 -0.32598876953125 +95392 -0.2581787109375 +95393 -0.139801025390625 +95394 0.014617919921875 +95395 0.144378662109375 +95396 0.221038818359375 +95397 0.27069091796875 +95398 0.294036865234375 +95399 0.311767578125 +95400 0.339141845703125 +95401 0.360260009765625 +95402 0.360504150390625 +95403 0.308380126953125 +95404 0.18170166015625 +95405 0.0047607421875 +95406 -0.17559814453125 +95407 -0.3143310546875 +95408 -0.36785888671875 +95409 -0.36248779296875 +95410 -0.343536376953125 +95411 -0.3018798828125 +95412 -0.231414794921875 +95413 -0.117645263671875 +95414 0.007049560546875 +95415 0.087982177734375 +95416 0.13946533203125 +95417 0.17425537109375 +95418 0.188201904296875 +95419 0.171234130859375 +95420 0.118438720703125 +95421 0.05706787109375 +95422 -0.010711669921875 +95423 -0.0914306640625 +95424 -0.162322998046875 +95425 -0.194549560546875 +95426 -0.1492919921875 +95427 -0.02166748046875 +95428 0.124053955078125 +95429 0.211151123046875 +95430 0.240447998046875 +95431 0.242218017578125 +95432 0.2257080078125 +95433 0.194366455078125 +95434 0.115509033203125 +95435 0.0128173828125 +95436 -0.053802490234375 +95437 -0.110626220703125 +95438 -0.199493408203125 +95439 -0.29437255859375 +95440 -0.33221435546875 +95441 -0.27972412109375 +95442 -0.185333251953125 +95443 -0.128204345703125 +95444 -0.115692138671875 +95445 -0.116455078125 +95446 -0.105926513671875 +95447 -0.053955078125 +95448 0.048797607421875 +95449 0.157318115234375 +95450 0.212005615234375 +95451 0.218475341796875 +95452 0.23724365234375 +95453 0.30535888671875 +95454 0.38128662109375 +95455 0.404449462890625 +95456 0.3944091796875 +95457 0.3885498046875 +95458 0.362640380859375 +95459 0.27362060546875 +95460 0.11712646484375 +95461 -0.054901123046875 +95462 -0.19085693359375 +95463 -0.28570556640625 +95464 -0.339263916015625 +95465 -0.3775634765625 +95466 -0.445709228515625 +95467 -0.535064697265625 +95468 -0.629058837890625 +95469 -0.697601318359375 +95470 -0.70391845703125 +95471 -0.6424560546875 +95472 -0.491241455078125 +95473 -0.265716552734375 +95474 -0.023712158203125 +95475 0.201751708984375 +95476 0.375823974609375 +95477 0.485076904296875 +95478 0.56884765625 +95479 0.634765625 +95480 0.63763427734375 +95481 0.5660400390625 +95482 0.4720458984375 +95483 0.40692138671875 +95484 0.3778076171875 +95485 0.376953125 +95486 0.371978759765625 +95487 0.313140869140625 +95488 0.184417724609375 +95489 0.011199951171875 +95490 -0.171051025390625 +95491 -0.33740234375 +95492 -0.47198486328125 +95493 -0.560394287109375 +95494 -0.58056640625 +95495 -0.54754638671875 +95496 -0.508575439453125 +95497 -0.459503173828125 +95498 -0.394378662109375 +95499 -0.35260009765625 +95500 -0.31170654296875 +95501 -0.197418212890625 +95502 -0.007965087890625 +95503 0.207489013671875 +95504 0.409210205078125 +95505 0.57208251953125 +95506 0.66595458984375 +95507 0.65875244140625 +95508 0.56744384765625 +95509 0.431396484375 +95510 0.29443359375 +95511 0.182464599609375 +95512 0.06365966796875 +95513 -0.075958251953125 +95514 -0.189422607421875 +95515 -0.271942138671875 +95516 -0.342529296875 +95517 -0.364166259765625 +95518 -0.327239990234375 +95519 -0.2769775390625 +95520 -0.253692626953125 +95521 -0.24365234375 +95522 -0.1983642578125 +95523 -0.116241455078125 +95524 -0.036834716796875 +95525 0.034881591796875 +95526 0.09124755859375 +95527 0.10888671875 +95528 0.125518798828125 +95529 0.15771484375 +95530 0.17828369140625 +95531 0.17108154296875 +95532 0.129974365234375 +95533 0.082427978515625 +95534 0.027679443359375 +95535 -0.065643310546875 +95536 -0.15936279296875 +95537 -0.21307373046875 +95538 -0.234649658203125 +95539 -0.2001953125 +95540 -0.119171142578125 +95541 -0.024749755859375 +95542 0.085784912109375 +95543 0.178131103515625 +95544 0.215576171875 +95545 0.211456298828125 +95546 0.17523193359375 +95547 0.128753662109375 +95548 0.1019287109375 +95549 0.0743408203125 +95550 0.04327392578125 +95551 0.038177490234375 +95552 0.076263427734375 +95553 0.14105224609375 +95554 0.186431884765625 +95555 0.188812255859375 +95556 0.1390380859375 +95557 0.041778564453125 +95558 -0.079437255859375 +95559 -0.219390869140625 +95560 -0.367828369140625 +95561 -0.494873046875 +95562 -0.556243896484375 +95563 -0.508697509765625 +95564 -0.3756103515625 +95565 -0.218902587890625 +95566 -0.063751220703125 +95567 0.091552734375 +95568 0.23602294921875 +95569 0.342987060546875 +95570 0.39520263671875 +95571 0.389373779296875 +95572 0.324249267578125 +95573 0.224090576171875 +95574 0.124267578125 +95575 0.037078857421875 +95576 -0.010101318359375 +95577 -0.019439697265625 +95578 -0.022796630859375 +95579 -0.001556396484375 +95580 0.056304931640625 +95581 0.106719970703125 +95582 0.096893310546875 +95583 0.042694091796875 +95584 -0.018035888671875 +95585 -0.07586669921875 +95586 -0.11944580078125 +95587 -0.15972900390625 +95588 -0.202606201171875 +95589 -0.24859619140625 +95590 -0.30517578125 +95591 -0.36212158203125 +95592 -0.39141845703125 +95593 -0.35528564453125 +95594 -0.249969482421875 +95595 -0.092864990234375 +95596 0.08905029296875 +95597 0.2352294921875 +95598 0.318817138671875 +95599 0.358642578125 +95600 0.347747802734375 +95601 0.28564453125 +95602 0.223175048828125 +95603 0.196746826171875 +95604 0.179840087890625 +95605 0.155548095703125 +95606 0.151214599609375 +95607 0.156951904296875 +95608 0.13177490234375 +95609 0.100799560546875 +95610 0.087127685546875 +95611 0.05487060546875 +95612 -0.009002685546875 +95613 -0.10400390625 +95614 -0.229400634765625 +95615 -0.35552978515625 +95616 -0.441925048828125 +95617 -0.473846435546875 +95618 -0.464813232421875 +95619 -0.419097900390625 +95620 -0.334320068359375 +95621 -0.227935791015625 +95622 -0.12347412109375 +95623 -0.02764892578125 +95624 0.077667236328125 +95625 0.2132568359375 +95626 0.38885498046875 +95627 0.582794189453125 +95628 0.734039306640625 +95629 0.800140380859375 +95630 0.7783203125 +95631 0.6651611328125 +95632 0.45965576171875 +95633 0.199188232421875 +95634 -0.050689697265625 +95635 -0.23297119140625 +95636 -0.33013916015625 +95637 -0.368408203125 +95638 -0.378936767578125 +95639 -0.376983642578125 +95640 -0.37969970703125 +95641 -0.391510009765625 +95642 -0.385345458984375 +95643 -0.3419189453125 +95644 -0.28289794921875 +95645 -0.251617431640625 +95646 -0.266143798828125 +95647 -0.273345947265625 +95648 -0.216796875 +95649 -0.128265380859375 +95650 -0.068145751953125 +95651 -0.0430908203125 +95652 -0.024444580078125 +95653 0.020721435546875 +95654 0.124481201171875 +95655 0.25787353515625 +95656 0.379119873046875 +95657 0.47991943359375 +95658 0.5281982421875 +95659 0.511138916015625 +95660 0.456207275390625 +95661 0.407470703125 +95662 0.383758544921875 +95663 0.35687255859375 +95664 0.31182861328125 +95665 0.250885009765625 +95666 0.1654052734375 +95667 0.035247802734375 +95668 -0.142059326171875 +95669 -0.33563232421875 +95670 -0.5345458984375 +95671 -0.72186279296875 +95672 -0.836669921875 +95673 -0.8326416015625 +95674 -0.7296142578125 +95675 -0.582550048828125 +95676 -0.440093994140625 +95677 -0.324310302734375 +95678 -0.20147705078125 +95679 -0.044647216796875 +95680 0.103973388671875 +95681 0.202392578125 +95682 0.264495849609375 +95683 0.338897705078125 +95684 0.443817138671875 +95685 0.545074462890625 +95686 0.6173095703125 +95687 0.6524658203125 +95688 0.66339111328125 +95689 0.6561279296875 +95690 0.606781005859375 +95691 0.501190185546875 +95692 0.352783203125 +95693 0.176544189453125 +95694 -0.034820556640625 +95695 -0.258209228515625 +95696 -0.44244384765625 +95697 -0.5753173828125 +95698 -0.65203857421875 +95699 -0.641632080078125 +95700 -0.562164306640625 +95701 -0.458038330078125 +95702 -0.350555419921875 +95703 -0.260528564453125 +95704 -0.192108154296875 +95705 -0.141937255859375 +95706 -0.1021728515625 +95707 -0.062896728515625 +95708 -0.011932373046875 +95709 0.062835693359375 +95710 0.148712158203125 +95711 0.241729736328125 +95712 0.34912109375 +95713 0.457305908203125 +95714 0.54388427734375 +95715 0.5728759765625 +95716 0.506591796875 +95717 0.351226806640625 +95718 0.146514892578125 +95719 -0.05523681640625 +95720 -0.21624755859375 +95721 -0.334930419921875 +95722 -0.402984619140625 +95723 -0.4412841796875 +95724 -0.49578857421875 +95725 -0.5601806640625 +95726 -0.600738525390625 +95727 -0.584228515625 +95728 -0.47930908203125 +95729 -0.27935791015625 +95730 -0.0089111328125 +95731 0.268798828125 +95732 0.482818603515625 +95733 0.60369873046875 +95734 0.650421142578125 +95735 0.66400146484375 +95736 0.6414794921875 +95737 0.572540283203125 +95738 0.498138427734375 +95739 0.439453125 +95740 0.375518798828125 +95741 0.274505615234375 +95742 0.1087646484375 +95743 -0.099395751953125 +95744 -0.3182373046875 +95745 -0.5489501953125 +95746 -0.7738037109375 +95747 -0.86383056640625 +95748 -0.870391845703125 +95749 -0.86895751953125 +95750 -0.861053466796875 +95751 -0.765869140625 +95752 -0.5301513671875 +95753 -0.214691162109375 +95754 0.137359619140625 +95755 0.474822998046875 +95756 0.76239013671875 +95757 0.867462158203125 +95758 0.870361328125 +95759 0.86480712890625 +95760 0.831817626953125 +95761 0.677581787109375 +95762 0.495880126953125 +95763 0.30767822265625 +95764 0.116180419921875 +95765 -0.110748291015625 +95766 -0.381805419921875 +95767 -0.6572265625 +95768 -0.857421875 +95769 -0.870391845703125 +95770 -0.870391845703125 +95771 -0.86444091796875 +95772 -0.85723876953125 +95773 -0.790008544921875 +95774 -0.62847900390625 +95775 -0.3956298828125 +95776 -0.126708984375 +95777 0.150115966796875 +95778 0.424041748046875 +95779 0.670623779296875 +95780 0.854522705078125 +95781 0.866485595703125 +95782 0.86920166015625 +95783 0.8653564453125 +95784 0.857147216796875 +95785 0.766845703125 +95786 0.628509521484375 +95787 0.462127685546875 +95788 0.297210693359375 +95789 0.14862060546875 +95790 -0.00537109375 +95791 -0.15753173828125 +95792 -0.31304931640625 +95793 -0.48876953125 +95794 -0.6416015625 +95795 -0.751373291015625 +95796 -0.84619140625 +95797 -0.861297607421875 +95798 -0.863250732421875 +95799 -0.856597900390625 +95800 -0.7498779296875 +95801 -0.624542236328125 +95802 -0.47808837890625 +95803 -0.253387451171875 +95804 0.003692626953125 +95805 0.2257080078125 +95806 0.427154541015625 +95807 0.643218994140625 +95808 0.855926513671875 +95809 0.870361328125 +95810 0.870361328125 +95811 0.862762451171875 +95812 0.79669189453125 +95813 0.595794677734375 +95814 0.362152099609375 +95815 0.1270751953125 +95816 -0.086944580078125 +95817 -0.2784423828125 +95818 -0.484832763671875 +95819 -0.729583740234375 +95820 -0.86688232421875 +95821 -0.870391845703125 +95822 -0.86859130859375 +95823 -0.86279296875 +95824 -0.817962646484375 +95825 -0.6116943359375 +95826 -0.3128662109375 +95827 0.039398193359375 +95828 0.422821044921875 +95829 0.805145263671875 +95830 0.870361328125 +95831 0.870361328125 +95832 0.860015869140625 +95833 0.727935791015625 +95834 0.48114013671875 +95835 0.2059326171875 +95836 -0.06103515625 +95837 -0.29913330078125 +95838 -0.516204833984375 +95839 -0.7252197265625 +95840 -0.85980224609375 +95841 -0.870391845703125 +95842 -0.870391845703125 +95843 -0.858062744140625 +95844 -0.673004150390625 +95845 -0.42694091796875 +95846 -0.2100830078125 +95847 -0.0362548828125 +95848 0.10943603515625 +95849 0.23516845703125 +95850 0.373687744140625 +95851 0.517791748046875 +95852 0.602783203125 +95853 0.635711669921875 +95854 0.655181884765625 +95855 0.65948486328125 +95856 0.651275634765625 +95857 0.61846923828125 +95858 0.53753662109375 +95859 0.404144287109375 +95860 0.22186279296875 +95861 0.003997802734375 +95862 -0.22100830078125 +95863 -0.42449951171875 +95864 -0.579833984375 +95865 -0.641876220703125 +95866 -0.6177978515625 +95867 -0.575531005859375 +95868 -0.526336669921875 +95869 -0.42645263671875 +95870 -0.2581787109375 +95871 -0.068695068359375 +95872 0.09222412109375 +95873 0.232147216796875 +95874 0.3509521484375 +95875 0.410064697265625 +95876 0.372955322265625 +95877 0.2554931640625 +95878 0.10711669921875 +95879 -0.052886962890625 +95880 -0.186279296875 +95881 -0.23291015625 +95882 -0.209442138671875 +95883 -0.174163818359375 +95884 -0.126739501953125 +95885 -0.048126220703125 +95886 0.0426025390625 +95887 0.10748291015625 +95888 0.1409912109375 +95889 0.19708251953125 +95890 0.273651123046875 +95891 0.31768798828125 +95892 0.341094970703125 +95893 0.368011474609375 +95894 0.37249755859375 +95895 0.30072021484375 +95896 0.1517333984375 +95897 -0.01470947265625 +95898 -0.1883544921875 +95899 -0.372711181640625 +95900 -0.51397705078125 +95901 -0.57177734375 +95902 -0.53948974609375 +95903 -0.43511962890625 +95904 -0.2962646484375 +95905 -0.161102294921875 +95906 -0.0435791015625 +95907 0.060394287109375 +95908 0.13665771484375 +95909 0.170135498046875 +95910 0.16552734375 +95911 0.15728759765625 +95912 0.150787353515625 +95913 0.12200927734375 +95914 0.080108642578125 +95915 0.05126953125 +95916 0.062896728515625 +95917 0.09271240234375 +95918 0.092987060546875 +95919 0.07855224609375 +95920 0.06427001953125 +95921 0.0347900390625 +95922 -0.01171875 +95923 -0.056060791015625 +95924 -0.055511474609375 +95925 -0.010467529296875 +95926 0.02508544921875 +95927 0.025665283203125 +95928 0.017333984375 +95929 0.00189208984375 +95930 -0.03173828125 +95931 -0.071502685546875 +95932 -0.13543701171875 +95933 -0.219970703125 +95934 -0.300506591796875 +95935 -0.376312255859375 +95936 -0.416107177734375 +95937 -0.371124267578125 +95938 -0.242279052734375 +95939 -0.069732666015625 +95940 0.125640869140625 +95941 0.31268310546875 +95942 0.45501708984375 +95943 0.554779052734375 +95944 0.61065673828125 +95945 0.610931396484375 +95946 0.531463623046875 +95947 0.3883056640625 +95948 0.23468017578125 +95949 0.095245361328125 +95950 -0.00396728515625 +95951 -0.04852294921875 +95952 -0.055145263671875 +95953 -0.0758056640625 +95954 -0.138702392578125 +95955 -0.209197998046875 +95956 -0.289031982421875 +95957 -0.37884521484375 +95958 -0.456329345703125 +95959 -0.51641845703125 +95960 -0.519287109375 +95961 -0.458251953125 +95962 -0.384796142578125 +95963 -0.323699951171875 +95964 -0.269287109375 +95965 -0.1951904296875 +95966 -0.100006103515625 +95967 -0.01055908203125 +95968 0.1033935546875 +95969 0.24908447265625 +95970 0.373199462890625 +95971 0.45806884765625 +95972 0.511474609375 +95973 0.565399169921875 +95974 0.61138916015625 +95975 0.5897216796875 +95976 0.4906005859375 +95977 0.33148193359375 +95978 0.147796630859375 +95979 -0.01873779296875 +95980 -0.140289306640625 +95981 -0.191986083984375 +95982 -0.184295654296875 +95983 -0.161834716796875 +95984 -0.166595458984375 +95985 -0.19390869140625 +95986 -0.22442626953125 +95987 -0.279754638671875 +95988 -0.3389892578125 +95989 -0.3543701171875 +95990 -0.348175048828125 +95991 -0.32598876953125 +95992 -0.2581787109375 +95993 -0.139801025390625 +95994 0.014617919921875 +95995 0.144378662109375 +95996 0.221038818359375 +95997 0.27069091796875 +95998 0.294036865234375 +95999 0.311767578125 +96000 0.339141845703125 +96001 0.360260009765625 +96002 0.360504150390625 +96003 0.308380126953125 +96004 0.18170166015625 +96005 0.0047607421875 +96006 -0.17559814453125 +96007 -0.3143310546875 +96008 -0.36785888671875 +96009 -0.36248779296875 +96010 -0.343536376953125 +96011 -0.3018798828125 +96012 -0.231414794921875 +96013 -0.117645263671875 +96014 0.007049560546875 +96015 0.087982177734375 +96016 0.13946533203125 +96017 0.17425537109375 +96018 0.188201904296875 +96019 0.171234130859375 +96020 0.118438720703125 +96021 0.05706787109375 +96022 -0.010711669921875 +96023 -0.0914306640625 +96024 -0.162322998046875 +96025 -0.194549560546875 +96026 -0.1492919921875 +96027 -0.02166748046875 +96028 0.124053955078125 +96029 0.211151123046875 +96030 0.240447998046875 +96031 0.242218017578125 +96032 0.2257080078125 +96033 0.194366455078125 +96034 0.115509033203125 +96035 0.0128173828125 +96036 -0.053802490234375 +96037 -0.110626220703125 +96038 -0.199493408203125 +96039 -0.29437255859375 +96040 -0.33221435546875 +96041 -0.27972412109375 +96042 -0.185333251953125 +96043 -0.128204345703125 +96044 -0.115692138671875 +96045 -0.116455078125 +96046 -0.105926513671875 +96047 -0.053955078125 +96048 0.048797607421875 +96049 0.157318115234375 +96050 0.212005615234375 +96051 0.218475341796875 +96052 0.23724365234375 +96053 0.30535888671875 +96054 0.38128662109375 +96055 0.404449462890625 +96056 0.3944091796875 +96057 0.3885498046875 +96058 0.362640380859375 +96059 0.27362060546875 +96060 0.11712646484375 +96061 -0.054901123046875 +96062 -0.19085693359375 +96063 -0.28570556640625 +96064 -0.339263916015625 +96065 -0.3775634765625 +96066 -0.445709228515625 +96067 -0.535064697265625 +96068 -0.629058837890625 +96069 -0.697601318359375 +96070 -0.70391845703125 +96071 -0.6424560546875 +96072 -0.491241455078125 +96073 -0.265716552734375 +96074 -0.023712158203125 +96075 0.201751708984375 +96076 0.375823974609375 +96077 0.485076904296875 +96078 0.56884765625 +96079 0.634765625 +96080 0.63763427734375 +96081 0.5660400390625 +96082 0.4720458984375 +96083 0.40692138671875 +96084 0.3778076171875 +96085 0.376953125 +96086 0.371978759765625 +96087 0.313140869140625 +96088 0.184417724609375 +96089 0.011199951171875 +96090 -0.171051025390625 +96091 -0.33740234375 +96092 -0.47198486328125 +96093 -0.560394287109375 +96094 -0.58056640625 +96095 -0.54754638671875 +96096 -0.508575439453125 +96097 -0.459503173828125 +96098 -0.394378662109375 +96099 -0.35260009765625 +96100 -0.31170654296875 +96101 -0.197418212890625 +96102 -0.007965087890625 +96103 0.207489013671875 +96104 0.409210205078125 +96105 0.57208251953125 +96106 0.66595458984375 +96107 0.65875244140625 +96108 0.56744384765625 +96109 0.431396484375 +96110 0.29443359375 +96111 0.182464599609375 +96112 0.06365966796875 +96113 -0.075958251953125 +96114 -0.189422607421875 +96115 -0.271942138671875 +96116 -0.342529296875 +96117 -0.364166259765625 +96118 -0.327239990234375 +96119 -0.2769775390625 +96120 -0.253692626953125 +96121 -0.24365234375 +96122 -0.1983642578125 +96123 -0.116241455078125 +96124 -0.036834716796875 +96125 0.034881591796875 +96126 0.09124755859375 +96127 0.10888671875 +96128 0.125518798828125 +96129 0.15771484375 +96130 0.17828369140625 +96131 0.17108154296875 +96132 0.129974365234375 +96133 0.082427978515625 +96134 0.027679443359375 +96135 -0.065643310546875 +96136 -0.15936279296875 +96137 -0.21307373046875 +96138 -0.234649658203125 +96139 -0.2001953125 +96140 -0.119171142578125 +96141 -0.024749755859375 +96142 0.085784912109375 +96143 0.178131103515625 +96144 0.215576171875 +96145 0.211456298828125 +96146 0.17523193359375 +96147 0.128753662109375 +96148 0.1019287109375 +96149 0.0743408203125 +96150 0.04327392578125 +96151 0.038177490234375 +96152 0.076263427734375 +96153 0.14105224609375 +96154 0.186431884765625 +96155 0.188812255859375 +96156 0.1390380859375 +96157 0.041778564453125 +96158 -0.079437255859375 +96159 -0.219390869140625 +96160 -0.367828369140625 +96161 -0.494873046875 +96162 -0.556243896484375 +96163 -0.508697509765625 +96164 -0.3756103515625 +96165 -0.218902587890625 +96166 -0.063751220703125 +96167 0.091552734375 +96168 0.23602294921875 +96169 0.342987060546875 +96170 0.39520263671875 +96171 0.389373779296875 +96172 0.324249267578125 +96173 0.224090576171875 +96174 0.124267578125 +96175 0.037078857421875 +96176 -0.010101318359375 +96177 -0.019439697265625 +96178 -0.022796630859375 +96179 -0.001556396484375 +96180 0.056304931640625 +96181 0.106719970703125 +96182 0.096893310546875 +96183 0.042694091796875 +96184 -0.018035888671875 +96185 -0.07586669921875 +96186 -0.11944580078125 +96187 -0.15972900390625 +96188 -0.202606201171875 +96189 -0.24859619140625 +96190 -0.30517578125 +96191 -0.36212158203125 +96192 -0.39141845703125 +96193 -0.35528564453125 +96194 -0.249969482421875 +96195 -0.092864990234375 +96196 0.08905029296875 +96197 0.2352294921875 +96198 0.318817138671875 +96199 0.358642578125 +96200 0.347747802734375 +96201 0.28564453125 +96202 0.223175048828125 +96203 0.196746826171875 +96204 0.179840087890625 +96205 0.155548095703125 +96206 0.151214599609375 +96207 0.156951904296875 +96208 0.13177490234375 +96209 0.100799560546875 +96210 0.087127685546875 +96211 0.05487060546875 +96212 -0.009002685546875 +96213 -0.10400390625 +96214 -0.229400634765625 +96215 -0.35552978515625 +96216 -0.441925048828125 +96217 -0.473846435546875 +96218 -0.464813232421875 +96219 -0.419097900390625 +96220 -0.334320068359375 +96221 -0.227935791015625 +96222 -0.12347412109375 +96223 -0.02764892578125 +96224 0.077667236328125 +96225 0.2132568359375 +96226 0.38885498046875 +96227 0.582794189453125 +96228 0.734039306640625 +96229 0.800140380859375 +96230 0.7783203125 +96231 0.6651611328125 +96232 0.45965576171875 +96233 0.199188232421875 +96234 -0.050689697265625 +96235 -0.23297119140625 +96236 -0.33013916015625 +96237 -0.368408203125 +96238 -0.378936767578125 +96239 -0.376983642578125 +96240 -0.37969970703125 +96241 -0.391510009765625 +96242 -0.385345458984375 +96243 -0.3419189453125 +96244 -0.28289794921875 +96245 -0.251617431640625 +96246 -0.266143798828125 +96247 -0.273345947265625 +96248 -0.216796875 +96249 -0.128265380859375 +96250 -0.068145751953125 +96251 -0.0430908203125 +96252 -0.024444580078125 +96253 0.020721435546875 +96254 0.124481201171875 +96255 0.25787353515625 +96256 0.379119873046875 +96257 0.47991943359375 +96258 0.5281982421875 +96259 0.511138916015625 +96260 0.456207275390625 +96261 0.407470703125 +96262 0.383758544921875 +96263 0.35687255859375 +96264 0.31182861328125 +96265 0.250885009765625 +96266 0.1654052734375 +96267 0.035247802734375 +96268 -0.142059326171875 +96269 -0.33563232421875 +96270 -0.5345458984375 +96271 -0.72186279296875 +96272 -0.836669921875 +96273 -0.8326416015625 +96274 -0.7296142578125 +96275 -0.582550048828125 +96276 -0.440093994140625 +96277 -0.324310302734375 +96278 -0.20147705078125 +96279 -0.044647216796875 +96280 0.103973388671875 +96281 0.202392578125 +96282 0.264495849609375 +96283 0.338897705078125 +96284 0.443817138671875 +96285 0.545074462890625 +96286 0.6173095703125 +96287 0.6524658203125 +96288 0.66339111328125 +96289 0.6561279296875 +96290 0.606781005859375 +96291 0.501190185546875 +96292 0.352783203125 +96293 0.176544189453125 +96294 -0.034820556640625 +96295 -0.258209228515625 +96296 -0.44244384765625 +96297 -0.5753173828125 +96298 -0.65203857421875 +96299 -0.641632080078125 +96300 -0.562164306640625 +96301 -0.458038330078125 +96302 -0.350555419921875 +96303 -0.260528564453125 +96304 -0.192108154296875 +96305 -0.141937255859375 +96306 -0.1021728515625 +96307 -0.062896728515625 +96308 -0.011932373046875 +96309 0.062835693359375 +96310 0.148712158203125 +96311 0.241729736328125 +96312 0.34912109375 +96313 0.457305908203125 +96314 0.54388427734375 +96315 0.5728759765625 +96316 0.506591796875 +96317 0.351226806640625 +96318 0.146514892578125 +96319 -0.05523681640625 +96320 -0.21624755859375 +96321 -0.334930419921875 +96322 -0.402984619140625 +96323 -0.4412841796875 +96324 -0.49578857421875 +96325 -0.5601806640625 +96326 -0.600738525390625 +96327 -0.584228515625 +96328 -0.47930908203125 +96329 -0.27935791015625 +96330 -0.0089111328125 +96331 0.268798828125 +96332 0.482818603515625 +96333 0.60369873046875 +96334 0.650421142578125 +96335 0.66400146484375 +96336 0.6414794921875 +96337 0.572540283203125 +96338 0.498138427734375 +96339 0.439453125 +96340 0.375518798828125 +96341 0.274505615234375 +96342 0.1087646484375 +96343 -0.099395751953125 +96344 -0.3182373046875 +96345 -0.5489501953125 +96346 -0.7738037109375 +96347 -0.86383056640625 +96348 -0.870391845703125 +96349 -0.86895751953125 +96350 -0.861053466796875 +96351 -0.765869140625 +96352 -0.5301513671875 +96353 -0.214691162109375 +96354 0.137359619140625 +96355 0.474822998046875 +96356 0.76239013671875 +96357 0.867462158203125 +96358 0.870361328125 +96359 0.86480712890625 +96360 0.831817626953125 +96361 0.677581787109375 +96362 0.495880126953125 +96363 0.30767822265625 +96364 0.116180419921875 +96365 -0.110748291015625 +96366 -0.381805419921875 +96367 -0.6572265625 +96368 -0.857421875 +96369 -0.870391845703125 +96370 -0.870391845703125 +96371 -0.86444091796875 +96372 -0.85723876953125 +96373 -0.790008544921875 +96374 -0.62847900390625 +96375 -0.3956298828125 +96376 -0.126708984375 +96377 0.150115966796875 +96378 0.424041748046875 +96379 0.670623779296875 +96380 0.854522705078125 +96381 0.866485595703125 +96382 0.86920166015625 +96383 0.8653564453125 +96384 0.857147216796875 +96385 0.766845703125 +96386 0.628509521484375 +96387 0.462127685546875 +96388 0.297210693359375 +96389 0.14862060546875 +96390 -0.00537109375 +96391 -0.15753173828125 +96392 -0.31304931640625 +96393 -0.48876953125 +96394 -0.6416015625 +96395 -0.751373291015625 +96396 -0.84619140625 +96397 -0.861297607421875 +96398 -0.863250732421875 +96399 -0.856597900390625 +96400 -0.7498779296875 +96401 -0.624542236328125 +96402 -0.47808837890625 +96403 -0.253387451171875 +96404 0.003692626953125 +96405 0.2257080078125 +96406 0.427154541015625 +96407 0.643218994140625 +96408 0.855926513671875 +96409 0.870361328125 +96410 0.870361328125 +96411 0.862762451171875 +96412 0.79669189453125 +96413 0.595794677734375 +96414 0.362152099609375 +96415 0.1270751953125 +96416 -0.086944580078125 +96417 -0.2784423828125 +96418 -0.484832763671875 +96419 -0.729583740234375 +96420 -0.86688232421875 +96421 -0.870391845703125 +96422 -0.86859130859375 +96423 -0.86279296875 +96424 -0.817962646484375 +96425 -0.6116943359375 +96426 -0.3128662109375 +96427 0.039398193359375 +96428 0.422821044921875 +96429 0.805145263671875 +96430 0.870361328125 +96431 0.870361328125 +96432 0.860015869140625 +96433 0.727935791015625 +96434 0.48114013671875 +96435 0.2059326171875 +96436 -0.06103515625 +96437 -0.29913330078125 +96438 -0.516204833984375 +96439 -0.7252197265625 +96440 -0.85980224609375 +96441 -0.870391845703125 +96442 -0.870391845703125 +96443 -0.858062744140625 +96444 -0.673004150390625 +96445 -0.42694091796875 +96446 -0.2100830078125 +96447 -0.0362548828125 +96448 0.10943603515625 +96449 0.23516845703125 +96450 0.373687744140625 +96451 0.517791748046875 +96452 0.602783203125 +96453 0.635711669921875 +96454 0.655181884765625 +96455 0.65948486328125 +96456 0.651275634765625 +96457 0.61846923828125 +96458 0.53753662109375 +96459 0.404144287109375 +96460 0.22186279296875 +96461 0.003997802734375 +96462 -0.22100830078125 +96463 -0.42449951171875 +96464 -0.579833984375 +96465 -0.641876220703125 +96466 -0.6177978515625 +96467 -0.575531005859375 +96468 -0.526336669921875 +96469 -0.42645263671875 +96470 -0.2581787109375 +96471 -0.068695068359375 +96472 0.09222412109375 +96473 0.232147216796875 +96474 0.3509521484375 +96475 0.410064697265625 +96476 0.372955322265625 +96477 0.2554931640625 +96478 0.10711669921875 +96479 -0.052886962890625 +96480 -0.186279296875 +96481 -0.23291015625 +96482 -0.209442138671875 +96483 -0.174163818359375 +96484 -0.126739501953125 +96485 -0.048126220703125 +96486 0.0426025390625 +96487 0.10748291015625 +96488 0.1409912109375 +96489 0.19708251953125 +96490 0.273651123046875 +96491 0.31768798828125 +96492 0.341094970703125 +96493 0.368011474609375 +96494 0.37249755859375 +96495 0.30072021484375 +96496 0.1517333984375 +96497 -0.01470947265625 +96498 -0.1883544921875 +96499 -0.372711181640625 +96500 -0.51397705078125 +96501 -0.57177734375 +96502 -0.53948974609375 +96503 -0.43511962890625 +96504 -0.2962646484375 +96505 -0.161102294921875 +96506 -0.0435791015625 +96507 0.060394287109375 +96508 0.13665771484375 +96509 0.170135498046875 +96510 0.16552734375 +96511 0.15728759765625 +96512 0.150787353515625 +96513 0.12200927734375 +96514 0.080108642578125 +96515 0.05126953125 +96516 0.062896728515625 +96517 0.09271240234375 +96518 0.092987060546875 +96519 0.07855224609375 +96520 0.06427001953125 +96521 0.0347900390625 +96522 -0.01171875 +96523 -0.056060791015625 +96524 -0.055511474609375 +96525 -0.010467529296875 +96526 0.02508544921875 +96527 0.025665283203125 +96528 0.017333984375 +96529 0.00189208984375 +96530 -0.03173828125 +96531 -0.071502685546875 +96532 -0.13543701171875 +96533 -0.219970703125 +96534 -0.300506591796875 +96535 -0.376312255859375 +96536 -0.416107177734375 +96537 -0.371124267578125 +96538 -0.242279052734375 +96539 -0.069732666015625 +96540 0.125640869140625 +96541 0.31268310546875 +96542 0.45501708984375 +96543 0.554779052734375 +96544 0.61065673828125 +96545 0.610931396484375 +96546 0.531463623046875 +96547 0.3883056640625 +96548 0.23468017578125 +96549 0.095245361328125 +96550 -0.00396728515625 +96551 -0.04852294921875 +96552 -0.055145263671875 +96553 -0.0758056640625 +96554 -0.138702392578125 +96555 -0.209197998046875 +96556 -0.289031982421875 +96557 -0.37884521484375 +96558 -0.456329345703125 +96559 -0.51641845703125 +96560 -0.519287109375 +96561 -0.458251953125 +96562 -0.384796142578125 +96563 -0.323699951171875 +96564 -0.269287109375 +96565 -0.1951904296875 +96566 -0.100006103515625 +96567 -0.01055908203125 +96568 0.1033935546875 +96569 0.24908447265625 +96570 0.373199462890625 +96571 0.45806884765625 +96572 0.511474609375 +96573 0.565399169921875 +96574 0.61138916015625 +96575 0.5897216796875 +96576 0.4906005859375 +96577 0.33148193359375 +96578 0.147796630859375 +96579 -0.01873779296875 +96580 -0.140289306640625 +96581 -0.191986083984375 +96582 -0.184295654296875 +96583 -0.161834716796875 +96584 -0.166595458984375 +96585 -0.19390869140625 +96586 -0.22442626953125 +96587 -0.279754638671875 +96588 -0.3389892578125 +96589 -0.3543701171875 +96590 -0.348175048828125 +96591 -0.32598876953125 +96592 -0.2581787109375 +96593 -0.139801025390625 +96594 0.014617919921875 +96595 0.144378662109375 +96596 0.221038818359375 +96597 0.27069091796875 +96598 0.294036865234375 +96599 0.311767578125 +96600 0.339141845703125 +96601 0.360260009765625 +96602 0.360504150390625 +96603 0.308380126953125 +96604 0.18170166015625 +96605 0.0047607421875 +96606 -0.17559814453125 +96607 -0.3143310546875 +96608 -0.36785888671875 +96609 -0.36248779296875 +96610 -0.343536376953125 +96611 -0.3018798828125 +96612 -0.231414794921875 +96613 -0.117645263671875 +96614 0.007049560546875 +96615 0.087982177734375 +96616 0.13946533203125 +96617 0.17425537109375 +96618 0.188201904296875 +96619 0.171234130859375 +96620 0.118438720703125 +96621 0.05706787109375 +96622 -0.010711669921875 +96623 -0.0914306640625 +96624 -0.162322998046875 +96625 -0.194549560546875 +96626 -0.1492919921875 +96627 -0.02166748046875 +96628 0.124053955078125 +96629 0.211151123046875 +96630 0.240447998046875 +96631 0.242218017578125 +96632 0.2257080078125 +96633 0.194366455078125 +96634 0.115509033203125 +96635 0.0128173828125 +96636 -0.053802490234375 +96637 -0.110626220703125 +96638 -0.199493408203125 +96639 -0.29437255859375 +96640 -0.33221435546875 +96641 -0.27972412109375 +96642 -0.185333251953125 +96643 -0.128204345703125 +96644 -0.115692138671875 +96645 -0.116455078125 +96646 -0.105926513671875 +96647 -0.053955078125 +96648 0.048797607421875 +96649 0.157318115234375 +96650 0.212005615234375 +96651 0.218475341796875 +96652 0.23724365234375 +96653 0.30535888671875 +96654 0.38128662109375 +96655 0.404449462890625 +96656 0.3944091796875 +96657 0.3885498046875 +96658 0.362640380859375 +96659 0.27362060546875 +96660 0.11712646484375 +96661 -0.054901123046875 +96662 -0.19085693359375 +96663 -0.28570556640625 +96664 -0.339263916015625 +96665 -0.3775634765625 +96666 -0.445709228515625 +96667 -0.535064697265625 +96668 -0.629058837890625 +96669 -0.697601318359375 +96670 -0.70391845703125 +96671 -0.6424560546875 +96672 -0.491241455078125 +96673 -0.265716552734375 +96674 -0.023712158203125 +96675 0.201751708984375 +96676 0.375823974609375 +96677 0.485076904296875 +96678 0.56884765625 +96679 0.634765625 +96680 0.63763427734375 +96681 0.5660400390625 +96682 0.4720458984375 +96683 0.40692138671875 +96684 0.3778076171875 +96685 0.376953125 +96686 0.371978759765625 +96687 0.313140869140625 +96688 0.184417724609375 +96689 0.011199951171875 +96690 -0.171051025390625 +96691 -0.33740234375 +96692 -0.47198486328125 +96693 -0.560394287109375 +96694 -0.58056640625 +96695 -0.54754638671875 +96696 -0.508575439453125 +96697 -0.459503173828125 +96698 -0.394378662109375 +96699 -0.35260009765625 +96700 -0.31170654296875 +96701 -0.197418212890625 +96702 -0.007965087890625 +96703 0.207489013671875 +96704 0.409210205078125 +96705 0.57208251953125 +96706 0.66595458984375 +96707 0.65875244140625 +96708 0.56744384765625 +96709 0.431396484375 +96710 0.29443359375 +96711 0.182464599609375 +96712 0.06365966796875 +96713 -0.075958251953125 +96714 -0.189422607421875 +96715 -0.271942138671875 +96716 -0.342529296875 +96717 -0.364166259765625 +96718 -0.327239990234375 +96719 -0.2769775390625 +96720 -0.253692626953125 +96721 -0.24365234375 +96722 -0.1983642578125 +96723 -0.116241455078125 +96724 -0.036834716796875 +96725 0.034881591796875 +96726 0.09124755859375 +96727 0.10888671875 +96728 0.125518798828125 +96729 0.15771484375 +96730 0.17828369140625 +96731 0.17108154296875 +96732 0.129974365234375 +96733 0.082427978515625 +96734 0.027679443359375 +96735 -0.065643310546875 +96736 -0.15936279296875 +96737 -0.21307373046875 +96738 -0.234649658203125 +96739 -0.2001953125 +96740 -0.119171142578125 +96741 -0.024749755859375 +96742 0.085784912109375 +96743 0.178131103515625 +96744 0.215576171875 +96745 0.211456298828125 +96746 0.17523193359375 +96747 0.128753662109375 +96748 0.1019287109375 +96749 0.0743408203125 +96750 0.04327392578125 +96751 0.038177490234375 +96752 0.076263427734375 +96753 0.14105224609375 +96754 0.186431884765625 +96755 0.188812255859375 +96756 0.1390380859375 +96757 0.041778564453125 +96758 -0.079437255859375 +96759 -0.219390869140625 +96760 -0.367828369140625 +96761 -0.494873046875 +96762 -0.556243896484375 +96763 -0.508697509765625 +96764 -0.3756103515625 +96765 -0.218902587890625 +96766 -0.063751220703125 +96767 0.091552734375 +96768 0.23602294921875 +96769 0.342987060546875 +96770 0.39520263671875 +96771 0.389373779296875 +96772 0.324249267578125 +96773 0.224090576171875 +96774 0.124267578125 +96775 0.037078857421875 +96776 -0.010101318359375 +96777 -0.019439697265625 +96778 -0.022796630859375 +96779 -0.001556396484375 +96780 0.056304931640625 +96781 0.106719970703125 +96782 0.096893310546875 +96783 0.042694091796875 +96784 -0.018035888671875 +96785 -0.07586669921875 +96786 -0.11944580078125 +96787 -0.15972900390625 +96788 -0.202606201171875 +96789 -0.24859619140625 +96790 -0.30517578125 +96791 -0.36212158203125 +96792 -0.39141845703125 +96793 -0.35528564453125 +96794 -0.249969482421875 +96795 -0.092864990234375 +96796 0.08905029296875 +96797 0.2352294921875 +96798 0.318817138671875 +96799 0.358642578125 +96800 0.347747802734375 +96801 0.28564453125 +96802 0.223175048828125 +96803 0.196746826171875 +96804 0.179840087890625 +96805 0.155548095703125 +96806 0.151214599609375 +96807 0.156951904296875 +96808 0.13177490234375 +96809 0.100799560546875 +96810 0.087127685546875 +96811 0.05487060546875 +96812 -0.009002685546875 +96813 -0.10400390625 +96814 -0.229400634765625 +96815 -0.35552978515625 +96816 -0.441925048828125 +96817 -0.473846435546875 +96818 -0.464813232421875 +96819 -0.419097900390625 +96820 -0.334320068359375 +96821 -0.227935791015625 +96822 -0.12347412109375 +96823 -0.02764892578125 +96824 0.077667236328125 +96825 0.2132568359375 +96826 0.38885498046875 +96827 0.582794189453125 +96828 0.734039306640625 +96829 0.800140380859375 +96830 0.7783203125 +96831 0.6651611328125 +96832 0.45965576171875 +96833 0.199188232421875 +96834 -0.050689697265625 +96835 -0.23297119140625 +96836 -0.33013916015625 +96837 -0.368408203125 +96838 -0.378936767578125 +96839 -0.376983642578125 +96840 -0.37969970703125 +96841 -0.391510009765625 +96842 -0.385345458984375 +96843 -0.3419189453125 +96844 -0.28289794921875 +96845 -0.251617431640625 +96846 -0.266143798828125 +96847 -0.273345947265625 +96848 -0.216796875 +96849 -0.128265380859375 +96850 -0.068145751953125 +96851 -0.0430908203125 +96852 -0.024444580078125 +96853 0.020721435546875 +96854 0.124481201171875 +96855 0.25787353515625 +96856 0.379119873046875 +96857 0.47991943359375 +96858 0.5281982421875 +96859 0.511138916015625 +96860 0.456207275390625 +96861 0.407470703125 +96862 0.383758544921875 +96863 0.35687255859375 +96864 0.31182861328125 +96865 0.250885009765625 +96866 0.1654052734375 +96867 0.035247802734375 +96868 -0.142059326171875 +96869 -0.33563232421875 +96870 -0.5345458984375 +96871 -0.72186279296875 +96872 -0.836669921875 +96873 -0.8326416015625 +96874 -0.7296142578125 +96875 -0.582550048828125 +96876 -0.440093994140625 +96877 -0.324310302734375 +96878 -0.20147705078125 +96879 -0.044647216796875 +96880 0.103973388671875 +96881 0.202392578125 +96882 0.264495849609375 +96883 0.338897705078125 +96884 0.443817138671875 +96885 0.545074462890625 +96886 0.6173095703125 +96887 0.6524658203125 +96888 0.66339111328125 +96889 0.6561279296875 +96890 0.606781005859375 +96891 0.501190185546875 +96892 0.352783203125 +96893 0.176544189453125 +96894 -0.034820556640625 +96895 -0.258209228515625 +96896 -0.44244384765625 +96897 -0.5753173828125 +96898 -0.65203857421875 +96899 -0.641632080078125 +96900 -0.562164306640625 +96901 -0.458038330078125 +96902 -0.350555419921875 +96903 -0.260528564453125 +96904 -0.192108154296875 +96905 -0.141937255859375 +96906 -0.1021728515625 +96907 -0.062896728515625 +96908 -0.011932373046875 +96909 0.062835693359375 +96910 0.148712158203125 +96911 0.241729736328125 +96912 0.34912109375 +96913 0.457305908203125 +96914 0.54388427734375 +96915 0.5728759765625 +96916 0.506591796875 +96917 0.351226806640625 +96918 0.146514892578125 +96919 -0.05523681640625 +96920 -0.21624755859375 +96921 -0.334930419921875 +96922 -0.402984619140625 +96923 -0.4412841796875 +96924 -0.49578857421875 +96925 -0.5601806640625 +96926 -0.600738525390625 +96927 -0.584228515625 +96928 -0.47930908203125 +96929 -0.27935791015625 +96930 -0.0089111328125 +96931 0.268798828125 +96932 0.482818603515625 +96933 0.60369873046875 +96934 0.650421142578125 +96935 0.66400146484375 +96936 0.6414794921875 +96937 0.572540283203125 +96938 0.498138427734375 +96939 0.439453125 +96940 0.375518798828125 +96941 0.274505615234375 +96942 0.1087646484375 +96943 -0.099395751953125 +96944 -0.3182373046875 +96945 -0.5489501953125 +96946 -0.7738037109375 +96947 -0.86383056640625 +96948 -0.870391845703125 +96949 -0.86895751953125 +96950 -0.861053466796875 +96951 -0.765869140625 +96952 -0.5301513671875 +96953 -0.214691162109375 +96954 0.137359619140625 +96955 0.474822998046875 +96956 0.76239013671875 +96957 0.867462158203125 +96958 0.870361328125 +96959 0.86480712890625 +96960 0.831817626953125 +96961 0.677581787109375 +96962 0.495880126953125 +96963 0.30767822265625 +96964 0.116180419921875 +96965 -0.110748291015625 +96966 -0.381805419921875 +96967 -0.6572265625 +96968 -0.857421875 +96969 -0.870391845703125 +96970 -0.870391845703125 +96971 -0.86444091796875 +96972 -0.85723876953125 +96973 -0.790008544921875 +96974 -0.62847900390625 +96975 -0.3956298828125 +96976 -0.126708984375 +96977 0.150115966796875 +96978 0.424041748046875 +96979 0.670623779296875 +96980 0.854522705078125 +96981 0.866485595703125 +96982 0.86920166015625 +96983 0.8653564453125 +96984 0.857147216796875 +96985 0.766845703125 +96986 0.628509521484375 +96987 0.462127685546875 +96988 0.297210693359375 +96989 0.14862060546875 +96990 -0.00537109375 +96991 -0.15753173828125 +96992 -0.31304931640625 +96993 -0.48876953125 +96994 -0.6416015625 +96995 -0.751373291015625 +96996 -0.84619140625 +96997 -0.861297607421875 +96998 -0.863250732421875 +96999 -0.856597900390625 +97000 -0.7498779296875 +97001 -0.624542236328125 +97002 -0.47808837890625 +97003 -0.253387451171875 +97004 0.003692626953125 +97005 0.2257080078125 +97006 0.427154541015625 +97007 0.643218994140625 +97008 0.855926513671875 +97009 0.870361328125 +97010 0.870361328125 +97011 0.862762451171875 +97012 0.79669189453125 +97013 0.595794677734375 +97014 0.362152099609375 +97015 0.1270751953125 +97016 -0.086944580078125 +97017 -0.2784423828125 +97018 -0.484832763671875 +97019 -0.729583740234375 +97020 -0.86688232421875 +97021 -0.870391845703125 +97022 -0.86859130859375 +97023 -0.86279296875 +97024 -0.817962646484375 +97025 -0.6116943359375 +97026 -0.3128662109375 +97027 0.039398193359375 +97028 0.422821044921875 +97029 0.805145263671875 +97030 0.870361328125 +97031 0.870361328125 +97032 0.860015869140625 +97033 0.727935791015625 +97034 0.48114013671875 +97035 0.2059326171875 +97036 -0.06103515625 +97037 -0.29913330078125 +97038 -0.516204833984375 +97039 -0.7252197265625 +97040 -0.85980224609375 +97041 -0.870391845703125 +97042 -0.870391845703125 +97043 -0.858062744140625 +97044 -0.673004150390625 +97045 -0.42694091796875 +97046 -0.2100830078125 +97047 -0.0362548828125 +97048 0.10943603515625 +97049 0.23516845703125 +97050 0.373687744140625 +97051 0.517791748046875 +97052 0.602783203125 +97053 0.635711669921875 +97054 0.655181884765625 +97055 0.65948486328125 +97056 0.651275634765625 +97057 0.61846923828125 +97058 0.53753662109375 +97059 0.404144287109375 +97060 0.22186279296875 +97061 0.003997802734375 +97062 -0.22100830078125 +97063 -0.42449951171875 +97064 -0.579833984375 +97065 -0.641876220703125 +97066 -0.6177978515625 +97067 -0.575531005859375 +97068 -0.526336669921875 +97069 -0.42645263671875 +97070 -0.2581787109375 +97071 -0.068695068359375 +97072 0.09222412109375 +97073 0.232147216796875 +97074 0.3509521484375 +97075 0.410064697265625 +97076 0.372955322265625 +97077 0.2554931640625 +97078 0.10711669921875 +97079 -0.052886962890625 +97080 -0.186279296875 +97081 -0.23291015625 +97082 -0.209442138671875 +97083 -0.174163818359375 +97084 -0.126739501953125 +97085 -0.048126220703125 +97086 0.0426025390625 +97087 0.10748291015625 +97088 0.1409912109375 +97089 0.19708251953125 +97090 0.273651123046875 +97091 0.31768798828125 +97092 0.341094970703125 +97093 0.368011474609375 +97094 0.37249755859375 +97095 0.30072021484375 +97096 0.1517333984375 +97097 -0.01470947265625 +97098 -0.1883544921875 +97099 -0.372711181640625 +97100 -0.51397705078125 +97101 -0.57177734375 +97102 -0.53948974609375 +97103 -0.43511962890625 +97104 -0.2962646484375 +97105 -0.161102294921875 +97106 -0.0435791015625 +97107 0.060394287109375 +97108 0.13665771484375 +97109 0.170135498046875 +97110 0.16552734375 +97111 0.15728759765625 +97112 0.150787353515625 +97113 0.12200927734375 +97114 0.080108642578125 +97115 0.05126953125 +97116 0.062896728515625 +97117 0.09271240234375 +97118 0.092987060546875 +97119 0.07855224609375 +97120 0.06427001953125 +97121 0.0347900390625 +97122 -0.01171875 +97123 -0.056060791015625 +97124 -0.055511474609375 +97125 -0.010467529296875 +97126 0.02508544921875 +97127 0.025665283203125 +97128 0.017333984375 +97129 0.00189208984375 +97130 -0.03173828125 +97131 -0.071502685546875 +97132 -0.13543701171875 +97133 -0.219970703125 +97134 -0.300506591796875 +97135 -0.376312255859375 +97136 -0.416107177734375 +97137 -0.371124267578125 +97138 -0.242279052734375 +97139 -0.069732666015625 +97140 0.125640869140625 +97141 0.31268310546875 +97142 0.45501708984375 +97143 0.554779052734375 +97144 0.61065673828125 +97145 0.610931396484375 +97146 0.531463623046875 +97147 0.3883056640625 +97148 0.23468017578125 +97149 0.095245361328125 +97150 -0.00396728515625 +97151 -0.04852294921875 +97152 -0.055145263671875 +97153 -0.0758056640625 +97154 -0.138702392578125 +97155 -0.209197998046875 +97156 -0.289031982421875 +97157 -0.37884521484375 +97158 -0.456329345703125 +97159 -0.51641845703125 +97160 -0.519287109375 +97161 -0.458251953125 +97162 -0.384796142578125 +97163 -0.323699951171875 +97164 -0.269287109375 +97165 -0.1951904296875 +97166 -0.100006103515625 +97167 -0.01055908203125 +97168 0.1033935546875 +97169 0.24908447265625 +97170 0.373199462890625 +97171 0.45806884765625 +97172 0.511474609375 +97173 0.565399169921875 +97174 0.61138916015625 +97175 0.5897216796875 +97176 0.4906005859375 +97177 0.33148193359375 +97178 0.147796630859375 +97179 -0.01873779296875 +97180 -0.140289306640625 +97181 -0.191986083984375 +97182 -0.184295654296875 +97183 -0.161834716796875 +97184 -0.166595458984375 +97185 -0.19390869140625 +97186 -0.22442626953125 +97187 -0.279754638671875 +97188 -0.3389892578125 +97189 -0.3543701171875 +97190 -0.348175048828125 +97191 -0.32598876953125 +97192 -0.2581787109375 +97193 -0.139801025390625 +97194 0.014617919921875 +97195 0.144378662109375 +97196 0.221038818359375 +97197 0.27069091796875 +97198 0.294036865234375 +97199 0.311767578125 +97200 0.339141845703125 +97201 0.360260009765625 +97202 0.360504150390625 +97203 0.308380126953125 +97204 0.18170166015625 +97205 0.0047607421875 +97206 -0.17559814453125 +97207 -0.3143310546875 +97208 -0.36785888671875 +97209 -0.36248779296875 +97210 -0.343536376953125 +97211 -0.3018798828125 +97212 -0.231414794921875 +97213 -0.117645263671875 +97214 0.007049560546875 +97215 0.087982177734375 +97216 0.13946533203125 +97217 0.17425537109375 +97218 0.188201904296875 +97219 0.171234130859375 +97220 0.118438720703125 +97221 0.05706787109375 +97222 -0.010711669921875 +97223 -0.0914306640625 +97224 -0.162322998046875 +97225 -0.194549560546875 +97226 -0.1492919921875 +97227 -0.02166748046875 +97228 0.124053955078125 +97229 0.211151123046875 +97230 0.240447998046875 +97231 0.242218017578125 +97232 0.2257080078125 +97233 0.194366455078125 +97234 0.115509033203125 +97235 0.0128173828125 +97236 -0.053802490234375 +97237 -0.110626220703125 +97238 -0.199493408203125 +97239 -0.29437255859375 +97240 -0.33221435546875 +97241 -0.27972412109375 +97242 -0.185333251953125 +97243 -0.128204345703125 +97244 -0.115692138671875 +97245 -0.116455078125 +97246 -0.105926513671875 +97247 -0.053955078125 +97248 0.048797607421875 +97249 0.157318115234375 +97250 0.212005615234375 +97251 0.218475341796875 +97252 0.23724365234375 +97253 0.30535888671875 +97254 0.38128662109375 +97255 0.404449462890625 +97256 0.3944091796875 +97257 0.3885498046875 +97258 0.362640380859375 +97259 0.27362060546875 +97260 0.11712646484375 +97261 -0.054901123046875 +97262 -0.19085693359375 +97263 -0.28570556640625 +97264 -0.339263916015625 +97265 -0.3775634765625 +97266 -0.445709228515625 +97267 -0.535064697265625 +97268 -0.629058837890625 +97269 -0.697601318359375 +97270 -0.70391845703125 +97271 -0.6424560546875 +97272 -0.491241455078125 +97273 -0.265716552734375 +97274 -0.023712158203125 +97275 0.201751708984375 +97276 0.375823974609375 +97277 0.485076904296875 +97278 0.56884765625 +97279 0.634765625 +97280 0.63763427734375 +97281 0.5660400390625 +97282 0.4720458984375 +97283 0.40692138671875 +97284 0.3778076171875 +97285 0.376953125 +97286 0.371978759765625 +97287 0.313140869140625 +97288 0.184417724609375 +97289 0.011199951171875 +97290 -0.171051025390625 +97291 -0.33740234375 +97292 -0.47198486328125 +97293 -0.560394287109375 +97294 -0.58056640625 +97295 -0.54754638671875 +97296 -0.508575439453125 +97297 -0.459503173828125 +97298 -0.394378662109375 +97299 -0.35260009765625 +97300 -0.31170654296875 +97301 -0.197418212890625 +97302 -0.007965087890625 +97303 0.207489013671875 +97304 0.409210205078125 +97305 0.57208251953125 +97306 0.66595458984375 +97307 0.65875244140625 +97308 0.56744384765625 +97309 0.431396484375 +97310 0.29443359375 +97311 0.182464599609375 +97312 0.06365966796875 +97313 -0.075958251953125 +97314 -0.189422607421875 +97315 -0.271942138671875 +97316 -0.342529296875 +97317 -0.364166259765625 +97318 -0.327239990234375 +97319 -0.2769775390625 +97320 -0.253692626953125 +97321 -0.24365234375 +97322 -0.1983642578125 +97323 -0.116241455078125 +97324 -0.036834716796875 +97325 0.034881591796875 +97326 0.09124755859375 +97327 0.10888671875 +97328 0.125518798828125 +97329 0.15771484375 +97330 0.17828369140625 +97331 0.17108154296875 +97332 0.129974365234375 +97333 0.082427978515625 +97334 0.027679443359375 +97335 -0.065643310546875 +97336 -0.15936279296875 +97337 -0.21307373046875 +97338 -0.234649658203125 +97339 -0.2001953125 +97340 -0.119171142578125 +97341 -0.024749755859375 +97342 0.085784912109375 +97343 0.178131103515625 +97344 0.215576171875 +97345 0.211456298828125 +97346 0.17523193359375 +97347 0.128753662109375 +97348 0.1019287109375 +97349 0.0743408203125 +97350 0.04327392578125 +97351 0.038177490234375 +97352 0.076263427734375 +97353 0.14105224609375 +97354 0.186431884765625 +97355 0.188812255859375 +97356 0.1390380859375 +97357 0.041778564453125 +97358 -0.079437255859375 +97359 -0.219390869140625 +97360 -0.367828369140625 +97361 -0.494873046875 +97362 -0.556243896484375 +97363 -0.508697509765625 +97364 -0.3756103515625 +97365 -0.218902587890625 +97366 -0.063751220703125 +97367 0.091552734375 +97368 0.23602294921875 +97369 0.342987060546875 +97370 0.39520263671875 +97371 0.389373779296875 +97372 0.324249267578125 +97373 0.224090576171875 +97374 0.124267578125 +97375 0.037078857421875 +97376 -0.010101318359375 +97377 -0.019439697265625 +97378 -0.022796630859375 +97379 -0.001556396484375 +97380 0.056304931640625 +97381 0.106719970703125 +97382 0.096893310546875 +97383 0.042694091796875 +97384 -0.018035888671875 +97385 -0.07586669921875 +97386 -0.11944580078125 +97387 -0.15972900390625 +97388 -0.202606201171875 +97389 -0.24859619140625 +97390 -0.30517578125 +97391 -0.36212158203125 +97392 -0.39141845703125 +97393 -0.35528564453125 +97394 -0.249969482421875 +97395 -0.092864990234375 +97396 0.08905029296875 +97397 0.2352294921875 +97398 0.318817138671875 +97399 0.358642578125 +97400 0.347747802734375 +97401 0.28564453125 +97402 0.223175048828125 +97403 0.196746826171875 +97404 0.179840087890625 +97405 0.155548095703125 +97406 0.151214599609375 +97407 0.156951904296875 +97408 0.13177490234375 +97409 0.100799560546875 +97410 0.087127685546875 +97411 0.05487060546875 +97412 -0.009002685546875 +97413 -0.10400390625 +97414 -0.229400634765625 +97415 -0.35552978515625 +97416 -0.441925048828125 +97417 -0.473846435546875 +97418 -0.464813232421875 +97419 -0.419097900390625 +97420 -0.334320068359375 +97421 -0.227935791015625 +97422 -0.12347412109375 +97423 -0.02764892578125 +97424 0.077667236328125 +97425 0.2132568359375 +97426 0.38885498046875 +97427 0.582794189453125 +97428 0.734039306640625 +97429 0.800140380859375 +97430 0.7783203125 +97431 0.6651611328125 +97432 0.45965576171875 +97433 0.199188232421875 +97434 -0.050689697265625 +97435 -0.23297119140625 +97436 -0.33013916015625 +97437 -0.368408203125 +97438 -0.378936767578125 +97439 -0.376983642578125 +97440 -0.37969970703125 +97441 -0.391510009765625 +97442 -0.385345458984375 +97443 -0.3419189453125 +97444 -0.28289794921875 +97445 -0.251617431640625 +97446 -0.266143798828125 +97447 -0.273345947265625 +97448 -0.216796875 +97449 -0.128265380859375 +97450 -0.068145751953125 +97451 -0.0430908203125 +97452 -0.024444580078125 +97453 0.020721435546875 +97454 0.124481201171875 +97455 0.25787353515625 +97456 0.379119873046875 +97457 0.47991943359375 +97458 0.5281982421875 +97459 0.511138916015625 +97460 0.456207275390625 +97461 0.407470703125 +97462 0.383758544921875 +97463 0.35687255859375 +97464 0.31182861328125 +97465 0.250885009765625 +97466 0.1654052734375 +97467 0.035247802734375 +97468 -0.142059326171875 +97469 -0.33563232421875 +97470 -0.5345458984375 +97471 -0.72186279296875 +97472 -0.836669921875 +97473 -0.8326416015625 +97474 -0.7296142578125 +97475 -0.582550048828125 +97476 -0.440093994140625 +97477 -0.324310302734375 +97478 -0.20147705078125 +97479 -0.044647216796875 +97480 0.103973388671875 +97481 0.202392578125 +97482 0.264495849609375 +97483 0.338897705078125 +97484 0.443817138671875 +97485 0.545074462890625 +97486 0.6173095703125 +97487 0.6524658203125 +97488 0.66339111328125 +97489 0.6561279296875 +97490 0.606781005859375 +97491 0.501190185546875 +97492 0.352783203125 +97493 0.176544189453125 +97494 -0.034820556640625 +97495 -0.258209228515625 +97496 -0.44244384765625 +97497 -0.5753173828125 +97498 -0.65203857421875 +97499 -0.641632080078125 +97500 -0.562164306640625 +97501 -0.458038330078125 +97502 -0.350555419921875 +97503 -0.260528564453125 +97504 -0.192108154296875 +97505 -0.141937255859375 +97506 -0.1021728515625 +97507 -0.062896728515625 +97508 -0.011932373046875 +97509 0.062835693359375 +97510 0.148712158203125 +97511 0.241729736328125 +97512 0.34912109375 +97513 0.457305908203125 +97514 0.54388427734375 +97515 0.5728759765625 +97516 0.506591796875 +97517 0.351226806640625 +97518 0.146514892578125 +97519 -0.05523681640625 +97520 -0.21624755859375 +97521 -0.334930419921875 +97522 -0.402984619140625 +97523 -0.4412841796875 +97524 -0.49578857421875 +97525 -0.5601806640625 +97526 -0.600738525390625 +97527 -0.584228515625 +97528 -0.47930908203125 +97529 -0.27935791015625 +97530 -0.0089111328125 +97531 0.268798828125 +97532 0.482818603515625 +97533 0.60369873046875 +97534 0.650421142578125 +97535 0.66400146484375 +97536 0.6414794921875 +97537 0.572540283203125 +97538 0.498138427734375 +97539 0.439453125 +97540 0.375518798828125 +97541 0.274505615234375 +97542 0.1087646484375 +97543 -0.099395751953125 +97544 -0.3182373046875 +97545 -0.5489501953125 +97546 -0.7738037109375 +97547 -0.86383056640625 +97548 -0.870391845703125 +97549 -0.86895751953125 +97550 -0.861053466796875 +97551 -0.765869140625 +97552 -0.5301513671875 +97553 -0.214691162109375 +97554 0.137359619140625 +97555 0.474822998046875 +97556 0.76239013671875 +97557 0.867462158203125 +97558 0.870361328125 +97559 0.86480712890625 +97560 0.831817626953125 +97561 0.677581787109375 +97562 0.495880126953125 +97563 0.30767822265625 +97564 0.116180419921875 +97565 -0.110748291015625 +97566 -0.381805419921875 +97567 -0.6572265625 +97568 -0.857421875 +97569 -0.870391845703125 +97570 -0.870391845703125 +97571 -0.86444091796875 +97572 -0.85723876953125 +97573 -0.790008544921875 +97574 -0.62847900390625 +97575 -0.3956298828125 +97576 -0.126708984375 +97577 0.150115966796875 +97578 0.424041748046875 +97579 0.670623779296875 +97580 0.854522705078125 +97581 0.866485595703125 +97582 0.86920166015625 +97583 0.8653564453125 +97584 0.857147216796875 +97585 0.766845703125 +97586 0.628509521484375 +97587 0.462127685546875 +97588 0.297210693359375 +97589 0.14862060546875 +97590 -0.00537109375 +97591 -0.15753173828125 +97592 -0.31304931640625 +97593 -0.48876953125 +97594 -0.6416015625 +97595 -0.751373291015625 +97596 -0.84619140625 +97597 -0.861297607421875 +97598 -0.863250732421875 +97599 -0.856597900390625 +97600 -0.7498779296875 +97601 -0.624542236328125 +97602 -0.47808837890625 +97603 -0.253387451171875 +97604 0.003692626953125 +97605 0.2257080078125 +97606 0.427154541015625 +97607 0.643218994140625 +97608 0.855926513671875 +97609 0.870361328125 +97610 0.870361328125 +97611 0.862762451171875 +97612 0.79669189453125 +97613 0.595794677734375 +97614 0.362152099609375 +97615 0.1270751953125 +97616 -0.086944580078125 +97617 -0.2784423828125 +97618 -0.484832763671875 +97619 -0.729583740234375 +97620 -0.86688232421875 +97621 -0.870391845703125 +97622 -0.86859130859375 +97623 -0.86279296875 +97624 -0.817962646484375 +97625 -0.6116943359375 +97626 -0.3128662109375 +97627 0.039398193359375 +97628 0.422821044921875 +97629 0.805145263671875 +97630 0.870361328125 +97631 0.870361328125 +97632 0.860015869140625 +97633 0.727935791015625 +97634 0.48114013671875 +97635 0.2059326171875 +97636 -0.06103515625 +97637 -0.29913330078125 +97638 -0.516204833984375 +97639 -0.7252197265625 +97640 -0.85980224609375 +97641 -0.870391845703125 +97642 -0.870391845703125 +97643 -0.858062744140625 +97644 -0.673004150390625 +97645 -0.42694091796875 +97646 -0.2100830078125 +97647 -0.0362548828125 +97648 0.10943603515625 +97649 0.23516845703125 +97650 0.373687744140625 +97651 0.517791748046875 +97652 0.602783203125 +97653 0.635711669921875 +97654 0.655181884765625 +97655 0.65948486328125 +97656 0.651275634765625 +97657 0.61846923828125 +97658 0.53753662109375 +97659 0.404144287109375 +97660 0.22186279296875 +97661 0.003997802734375 +97662 -0.22100830078125 +97663 -0.42449951171875 +97664 -0.579833984375 +97665 -0.641876220703125 +97666 -0.6177978515625 +97667 -0.575531005859375 +97668 -0.526336669921875 +97669 -0.42645263671875 +97670 -0.2581787109375 +97671 -0.068695068359375 +97672 0.09222412109375 +97673 0.232147216796875 +97674 0.3509521484375 +97675 0.410064697265625 +97676 0.372955322265625 +97677 0.2554931640625 +97678 0.10711669921875 +97679 -0.052886962890625 +97680 -0.186279296875 +97681 -0.23291015625 +97682 -0.209442138671875 +97683 -0.174163818359375 +97684 -0.126739501953125 +97685 -0.048126220703125 +97686 0.0426025390625 +97687 0.10748291015625 +97688 0.1409912109375 +97689 0.19708251953125 +97690 0.273651123046875 +97691 0.31768798828125 +97692 0.341094970703125 +97693 0.368011474609375 +97694 0.37249755859375 +97695 0.30072021484375 +97696 0.1517333984375 +97697 -0.01470947265625 +97698 -0.1883544921875 +97699 -0.372711181640625 +97700 -0.51397705078125 +97701 -0.57177734375 +97702 -0.53948974609375 +97703 -0.43511962890625 +97704 -0.2962646484375 +97705 -0.161102294921875 +97706 -0.0435791015625 +97707 0.060394287109375 +97708 0.13665771484375 +97709 0.170135498046875 +97710 0.16552734375 +97711 0.15728759765625 +97712 0.150787353515625 +97713 0.12200927734375 +97714 0.080108642578125 +97715 0.05126953125 +97716 0.062896728515625 +97717 0.09271240234375 +97718 0.092987060546875 +97719 0.07855224609375 +97720 0.06427001953125 +97721 0.0347900390625 +97722 -0.01171875 +97723 -0.056060791015625 +97724 -0.055511474609375 +97725 -0.010467529296875 +97726 0.02508544921875 +97727 0.025665283203125 +97728 0.017333984375 +97729 0.00189208984375 +97730 -0.03173828125 +97731 -0.071502685546875 +97732 -0.13543701171875 +97733 -0.219970703125 +97734 -0.300506591796875 +97735 -0.376312255859375 +97736 -0.416107177734375 +97737 -0.371124267578125 +97738 -0.242279052734375 +97739 -0.069732666015625 +97740 0.125640869140625 +97741 0.31268310546875 +97742 0.45501708984375 +97743 0.554779052734375 +97744 0.61065673828125 +97745 0.610931396484375 +97746 0.531463623046875 +97747 0.3883056640625 +97748 0.23468017578125 +97749 0.095245361328125 +97750 -0.00396728515625 +97751 -0.04852294921875 +97752 -0.055145263671875 +97753 -0.0758056640625 +97754 -0.138702392578125 +97755 -0.209197998046875 +97756 -0.289031982421875 +97757 -0.37884521484375 +97758 -0.456329345703125 +97759 -0.51641845703125 +97760 -0.519287109375 +97761 -0.458251953125 +97762 -0.384796142578125 +97763 -0.323699951171875 +97764 -0.269287109375 +97765 -0.1951904296875 +97766 -0.100006103515625 +97767 -0.01055908203125 +97768 0.1033935546875 +97769 0.24908447265625 +97770 0.373199462890625 +97771 0.45806884765625 +97772 0.511474609375 +97773 0.565399169921875 +97774 0.61138916015625 +97775 0.5897216796875 +97776 0.4906005859375 +97777 0.33148193359375 +97778 0.147796630859375 +97779 -0.01873779296875 +97780 -0.140289306640625 +97781 -0.191986083984375 +97782 -0.184295654296875 +97783 -0.161834716796875 +97784 -0.166595458984375 +97785 -0.19390869140625 +97786 -0.22442626953125 +97787 -0.279754638671875 +97788 -0.3389892578125 +97789 -0.3543701171875 +97790 -0.348175048828125 +97791 -0.32598876953125 +97792 -0.2581787109375 +97793 -0.139801025390625 +97794 0.014617919921875 +97795 0.144378662109375 +97796 0.221038818359375 +97797 0.27069091796875 +97798 0.294036865234375 +97799 0.311767578125 +97800 0.339141845703125 +97801 0.360260009765625 +97802 0.360504150390625 +97803 0.308380126953125 +97804 0.18170166015625 +97805 0.0047607421875 +97806 -0.17559814453125 +97807 -0.3143310546875 +97808 -0.36785888671875 +97809 -0.36248779296875 +97810 -0.343536376953125 +97811 -0.3018798828125 +97812 -0.231414794921875 +97813 -0.117645263671875 +97814 0.007049560546875 +97815 0.087982177734375 +97816 0.13946533203125 +97817 0.17425537109375 +97818 0.188201904296875 +97819 0.171234130859375 +97820 0.118438720703125 +97821 0.05706787109375 +97822 -0.010711669921875 +97823 -0.0914306640625 +97824 -0.162322998046875 +97825 -0.194549560546875 +97826 -0.1492919921875 +97827 -0.02166748046875 +97828 0.124053955078125 +97829 0.211151123046875 +97830 0.240447998046875 +97831 0.242218017578125 +97832 0.2257080078125 +97833 0.194366455078125 +97834 0.115509033203125 +97835 0.0128173828125 +97836 -0.053802490234375 +97837 -0.110626220703125 +97838 -0.199493408203125 +97839 -0.29437255859375 +97840 -0.33221435546875 +97841 -0.27972412109375 +97842 -0.185333251953125 +97843 -0.128204345703125 +97844 -0.115692138671875 +97845 -0.116455078125 +97846 -0.105926513671875 +97847 -0.053955078125 +97848 0.048797607421875 +97849 0.157318115234375 +97850 0.212005615234375 +97851 0.218475341796875 +97852 0.23724365234375 +97853 0.30535888671875 +97854 0.38128662109375 +97855 0.404449462890625 +97856 0.3944091796875 +97857 0.3885498046875 +97858 0.362640380859375 +97859 0.27362060546875 +97860 0.11712646484375 +97861 -0.054901123046875 +97862 -0.19085693359375 +97863 -0.28570556640625 +97864 -0.339263916015625 +97865 -0.3775634765625 +97866 -0.445709228515625 +97867 -0.535064697265625 +97868 -0.629058837890625 +97869 -0.697601318359375 +97870 -0.70391845703125 +97871 -0.6424560546875 +97872 -0.491241455078125 +97873 -0.265716552734375 +97874 -0.023712158203125 +97875 0.201751708984375 +97876 0.375823974609375 +97877 0.485076904296875 +97878 0.56884765625 +97879 0.634765625 +97880 0.63763427734375 +97881 0.5660400390625 +97882 0.4720458984375 +97883 0.40692138671875 +97884 0.3778076171875 +97885 0.376953125 +97886 0.371978759765625 +97887 0.313140869140625 +97888 0.184417724609375 +97889 0.011199951171875 +97890 -0.171051025390625 +97891 -0.33740234375 +97892 -0.47198486328125 +97893 -0.560394287109375 +97894 -0.58056640625 +97895 -0.54754638671875 +97896 -0.508575439453125 +97897 -0.459503173828125 +97898 -0.394378662109375 +97899 -0.35260009765625 +97900 -0.31170654296875 +97901 -0.197418212890625 +97902 -0.007965087890625 +97903 0.207489013671875 +97904 0.409210205078125 +97905 0.57208251953125 +97906 0.66595458984375 +97907 0.65875244140625 +97908 0.56744384765625 +97909 0.431396484375 +97910 0.29443359375 +97911 0.182464599609375 +97912 0.06365966796875 +97913 -0.075958251953125 +97914 -0.189422607421875 +97915 -0.271942138671875 +97916 -0.342529296875 +97917 -0.364166259765625 +97918 -0.327239990234375 +97919 -0.2769775390625 +97920 -0.253692626953125 +97921 -0.24365234375 +97922 -0.1983642578125 +97923 -0.116241455078125 +97924 -0.036834716796875 +97925 0.034881591796875 +97926 0.09124755859375 +97927 0.10888671875 +97928 0.125518798828125 +97929 0.15771484375 +97930 0.17828369140625 +97931 0.17108154296875 +97932 0.129974365234375 +97933 0.082427978515625 +97934 0.027679443359375 +97935 -0.065643310546875 +97936 -0.15936279296875 +97937 -0.21307373046875 +97938 -0.234649658203125 +97939 -0.2001953125 +97940 -0.119171142578125 +97941 -0.024749755859375 +97942 0.085784912109375 +97943 0.178131103515625 +97944 0.215576171875 +97945 0.211456298828125 +97946 0.17523193359375 +97947 0.128753662109375 +97948 0.1019287109375 +97949 0.0743408203125 +97950 0.04327392578125 +97951 0.038177490234375 +97952 0.076263427734375 +97953 0.14105224609375 +97954 0.186431884765625 +97955 0.188812255859375 +97956 0.1390380859375 +97957 0.041778564453125 +97958 -0.079437255859375 +97959 -0.219390869140625 +97960 -0.367828369140625 +97961 -0.494873046875 +97962 -0.556243896484375 +97963 -0.508697509765625 +97964 -0.3756103515625 +97965 -0.218902587890625 +97966 -0.063751220703125 +97967 0.091552734375 +97968 0.23602294921875 +97969 0.342987060546875 +97970 0.39520263671875 +97971 0.389373779296875 +97972 0.324249267578125 +97973 0.224090576171875 +97974 0.124267578125 +97975 0.037078857421875 +97976 -0.010101318359375 +97977 -0.019439697265625 +97978 -0.022796630859375 +97979 -0.001556396484375 +97980 0.056304931640625 +97981 0.106719970703125 +97982 0.096893310546875 +97983 0.042694091796875 +97984 -0.018035888671875 +97985 -0.07586669921875 +97986 -0.11944580078125 +97987 -0.15972900390625 +97988 -0.202606201171875 +97989 -0.24859619140625 +97990 -0.30517578125 +97991 -0.36212158203125 +97992 -0.39141845703125 +97993 -0.35528564453125 +97994 -0.249969482421875 +97995 -0.092864990234375 +97996 0.08905029296875 +97997 0.2352294921875 +97998 0.318817138671875 +97999 0.358642578125 +98000 0.347747802734375 +98001 0.28564453125 +98002 0.223175048828125 +98003 0.196746826171875 +98004 0.179840087890625 +98005 0.155548095703125 +98006 0.151214599609375 +98007 0.156951904296875 +98008 0.13177490234375 +98009 0.100799560546875 +98010 0.087127685546875 +98011 0.05487060546875 +98012 -0.009002685546875 +98013 -0.10400390625 +98014 -0.229400634765625 +98015 -0.35552978515625 +98016 -0.441925048828125 +98017 -0.473846435546875 +98018 -0.464813232421875 +98019 -0.419097900390625 +98020 -0.334320068359375 +98021 -0.227935791015625 +98022 -0.12347412109375 +98023 -0.02764892578125 +98024 0.077667236328125 +98025 0.2132568359375 +98026 0.38885498046875 +98027 0.582794189453125 +98028 0.734039306640625 +98029 0.800140380859375 +98030 0.7783203125 +98031 0.6651611328125 +98032 0.45965576171875 +98033 0.199188232421875 +98034 -0.050689697265625 +98035 -0.23297119140625 +98036 -0.33013916015625 +98037 -0.368408203125 +98038 -0.378936767578125 +98039 -0.376983642578125 +98040 -0.37969970703125 +98041 -0.391510009765625 +98042 -0.385345458984375 +98043 -0.3419189453125 +98044 -0.28289794921875 +98045 -0.251617431640625 +98046 -0.266143798828125 +98047 -0.273345947265625 +98048 -0.216796875 +98049 -0.128265380859375 +98050 -0.068145751953125 +98051 -0.0430908203125 +98052 -0.024444580078125 +98053 0.020721435546875 +98054 0.124481201171875 +98055 0.25787353515625 +98056 0.379119873046875 +98057 0.47991943359375 +98058 0.5281982421875 +98059 0.511138916015625 +98060 0.456207275390625 +98061 0.407470703125 +98062 0.383758544921875 +98063 0.35687255859375 +98064 0.31182861328125 +98065 0.250885009765625 +98066 0.1654052734375 +98067 0.035247802734375 +98068 -0.142059326171875 +98069 -0.33563232421875 +98070 -0.5345458984375 +98071 -0.72186279296875 +98072 -0.836669921875 +98073 -0.8326416015625 +98074 -0.7296142578125 +98075 -0.582550048828125 +98076 -0.440093994140625 +98077 -0.324310302734375 +98078 -0.20147705078125 +98079 -0.044647216796875 +98080 0.103973388671875 +98081 0.202392578125 +98082 0.264495849609375 +98083 0.338897705078125 +98084 0.443817138671875 +98085 0.545074462890625 +98086 0.6173095703125 +98087 0.6524658203125 +98088 0.66339111328125 +98089 0.6561279296875 +98090 0.606781005859375 +98091 0.501190185546875 +98092 0.352783203125 +98093 0.176544189453125 +98094 -0.034820556640625 +98095 -0.258209228515625 +98096 -0.44244384765625 +98097 -0.5753173828125 +98098 -0.65203857421875 +98099 -0.641632080078125 +98100 -0.562164306640625 +98101 -0.458038330078125 +98102 -0.350555419921875 +98103 -0.260528564453125 +98104 -0.192108154296875 +98105 -0.141937255859375 +98106 -0.1021728515625 +98107 -0.062896728515625 +98108 -0.011932373046875 +98109 0.062835693359375 +98110 0.148712158203125 +98111 0.241729736328125 +98112 0.34912109375 +98113 0.457305908203125 +98114 0.54388427734375 +98115 0.5728759765625 +98116 0.506591796875 +98117 0.351226806640625 +98118 0.146514892578125 +98119 -0.05523681640625 +98120 -0.21624755859375 +98121 -0.334930419921875 +98122 -0.402984619140625 +98123 -0.4412841796875 +98124 -0.49578857421875 +98125 -0.5601806640625 +98126 -0.600738525390625 +98127 -0.584228515625 +98128 -0.47930908203125 +98129 -0.27935791015625 +98130 -0.0089111328125 +98131 0.268798828125 +98132 0.482818603515625 +98133 0.60369873046875 +98134 0.650421142578125 +98135 0.66400146484375 +98136 0.6414794921875 +98137 0.572540283203125 +98138 0.498138427734375 +98139 0.439453125 +98140 0.375518798828125 +98141 0.274505615234375 +98142 0.1087646484375 +98143 -0.099395751953125 +98144 -0.3182373046875 +98145 -0.5489501953125 +98146 -0.7738037109375 +98147 -0.86383056640625 +98148 -0.870391845703125 +98149 -0.86895751953125 +98150 -0.861053466796875 +98151 -0.765869140625 +98152 -0.5301513671875 +98153 -0.214691162109375 +98154 0.137359619140625 +98155 0.474822998046875 +98156 0.76239013671875 +98157 0.867462158203125 +98158 0.870361328125 +98159 0.86480712890625 +98160 0.831817626953125 +98161 0.677581787109375 +98162 0.495880126953125 +98163 0.30767822265625 +98164 0.116180419921875 +98165 -0.110748291015625 +98166 -0.381805419921875 +98167 -0.6572265625 +98168 -0.857421875 +98169 -0.870391845703125 +98170 -0.870391845703125 +98171 -0.86444091796875 +98172 -0.85723876953125 +98173 -0.790008544921875 +98174 -0.62847900390625 +98175 -0.3956298828125 +98176 -0.126708984375 +98177 0.150115966796875 +98178 0.424041748046875 +98179 0.670623779296875 +98180 0.854522705078125 +98181 0.866485595703125 +98182 0.86920166015625 +98183 0.8653564453125 +98184 0.857147216796875 +98185 0.766845703125 +98186 0.628509521484375 +98187 0.462127685546875 +98188 0.297210693359375 +98189 0.14862060546875 +98190 -0.00537109375 +98191 -0.15753173828125 +98192 -0.31304931640625 +98193 -0.48876953125 +98194 -0.6416015625 +98195 -0.751373291015625 +98196 -0.84619140625 +98197 -0.861297607421875 +98198 -0.863250732421875 +98199 -0.856597900390625 +98200 -0.7498779296875 +98201 -0.624542236328125 +98202 -0.47808837890625 +98203 -0.253387451171875 +98204 0.003692626953125 +98205 0.2257080078125 +98206 0.427154541015625 +98207 0.643218994140625 +98208 0.855926513671875 +98209 0.870361328125 +98210 0.870361328125 +98211 0.862762451171875 +98212 0.79669189453125 +98213 0.595794677734375 +98214 0.362152099609375 +98215 0.1270751953125 +98216 -0.086944580078125 +98217 -0.2784423828125 +98218 -0.484832763671875 +98219 -0.729583740234375 +98220 -0.86688232421875 +98221 -0.870391845703125 +98222 -0.86859130859375 +98223 -0.86279296875 +98224 -0.817962646484375 +98225 -0.6116943359375 +98226 -0.3128662109375 +98227 0.039398193359375 +98228 0.422821044921875 +98229 0.805145263671875 +98230 0.870361328125 +98231 0.870361328125 +98232 0.860015869140625 +98233 0.727935791015625 +98234 0.48114013671875 +98235 0.2059326171875 +98236 -0.06103515625 +98237 -0.29913330078125 +98238 -0.516204833984375 +98239 -0.7252197265625 +98240 -0.85980224609375 +98241 -0.870391845703125 +98242 -0.870391845703125 +98243 -0.858062744140625 +98244 -0.673004150390625 +98245 -0.42694091796875 +98246 -0.2100830078125 +98247 -0.0362548828125 +98248 0.10943603515625 +98249 0.23516845703125 +98250 0.373687744140625 +98251 0.517791748046875 +98252 0.602783203125 +98253 0.635711669921875 +98254 0.655181884765625 +98255 0.65948486328125 +98256 0.651275634765625 +98257 0.61846923828125 +98258 0.53753662109375 +98259 0.404144287109375 +98260 0.22186279296875 +98261 0.003997802734375 +98262 -0.22100830078125 +98263 -0.42449951171875 +98264 -0.579833984375 +98265 -0.641876220703125 +98266 -0.6177978515625 +98267 -0.575531005859375 +98268 -0.526336669921875 +98269 -0.42645263671875 +98270 -0.2581787109375 +98271 -0.068695068359375 +98272 0.09222412109375 +98273 0.232147216796875 +98274 0.3509521484375 +98275 0.410064697265625 +98276 0.372955322265625 +98277 0.2554931640625 +98278 0.10711669921875 +98279 -0.052886962890625 +98280 -0.186279296875 +98281 -0.23291015625 +98282 -0.209442138671875 +98283 -0.174163818359375 +98284 -0.126739501953125 +98285 -0.048126220703125 +98286 0.0426025390625 +98287 0.10748291015625 +98288 0.1409912109375 +98289 0.19708251953125 +98290 0.273651123046875 +98291 0.31768798828125 +98292 0.341094970703125 +98293 0.368011474609375 +98294 0.37249755859375 +98295 0.30072021484375 +98296 0.1517333984375 +98297 -0.01470947265625 +98298 -0.1883544921875 +98299 -0.372711181640625 +98300 -0.51397705078125 +98301 -0.57177734375 +98302 -0.53948974609375 +98303 -0.43511962890625 +98304 -0.2962646484375 +98305 -0.161102294921875 +98306 -0.0435791015625 +98307 0.060394287109375 +98308 0.13665771484375 +98309 0.170135498046875 +98310 0.16552734375 +98311 0.15728759765625 +98312 0.150787353515625 +98313 0.12200927734375 +98314 0.080108642578125 +98315 0.05126953125 +98316 0.062896728515625 +98317 0.09271240234375 +98318 0.092987060546875 +98319 0.07855224609375 +98320 0.06427001953125 +98321 0.0347900390625 +98322 -0.01171875 +98323 -0.056060791015625 +98324 -0.055511474609375 +98325 -0.010467529296875 +98326 0.02508544921875 +98327 0.025665283203125 +98328 0.017333984375 +98329 0.00189208984375 +98330 -0.03173828125 +98331 -0.071502685546875 +98332 -0.13543701171875 +98333 -0.219970703125 +98334 -0.300506591796875 +98335 -0.376312255859375 +98336 -0.416107177734375 +98337 -0.371124267578125 +98338 -0.242279052734375 +98339 -0.069732666015625 +98340 0.125640869140625 +98341 0.31268310546875 +98342 0.45501708984375 +98343 0.554779052734375 +98344 0.61065673828125 +98345 0.610931396484375 +98346 0.531463623046875 +98347 0.3883056640625 +98348 0.23468017578125 +98349 0.095245361328125 +98350 -0.00396728515625 +98351 -0.04852294921875 +98352 -0.055145263671875 +98353 -0.0758056640625 +98354 -0.138702392578125 +98355 -0.209197998046875 +98356 -0.289031982421875 +98357 -0.37884521484375 +98358 -0.456329345703125 +98359 -0.51641845703125 +98360 -0.519287109375 +98361 -0.458251953125 +98362 -0.384796142578125 +98363 -0.323699951171875 +98364 -0.269287109375 +98365 -0.1951904296875 +98366 -0.100006103515625 +98367 -0.01055908203125 +98368 0.1033935546875 +98369 0.24908447265625 +98370 0.373199462890625 +98371 0.45806884765625 +98372 0.511474609375 +98373 0.565399169921875 +98374 0.61138916015625 +98375 0.5897216796875 +98376 0.4906005859375 +98377 0.33148193359375 +98378 0.147796630859375 +98379 -0.01873779296875 +98380 -0.140289306640625 +98381 -0.191986083984375 +98382 -0.184295654296875 +98383 -0.161834716796875 +98384 -0.166595458984375 +98385 -0.19390869140625 +98386 -0.22442626953125 +98387 -0.279754638671875 +98388 -0.3389892578125 +98389 -0.3543701171875 +98390 -0.348175048828125 +98391 -0.32598876953125 +98392 -0.2581787109375 +98393 -0.139801025390625 +98394 0.014617919921875 +98395 0.144378662109375 +98396 0.221038818359375 +98397 0.27069091796875 +98398 0.294036865234375 +98399 0.311767578125 +98400 0.339141845703125 +98401 0.360260009765625 +98402 0.360504150390625 +98403 0.308380126953125 +98404 0.18170166015625 +98405 0.0047607421875 +98406 -0.17559814453125 +98407 -0.3143310546875 +98408 -0.36785888671875 +98409 -0.36248779296875 +98410 -0.343536376953125 +98411 -0.3018798828125 +98412 -0.231414794921875 +98413 -0.117645263671875 +98414 0.007049560546875 +98415 0.087982177734375 +98416 0.13946533203125 +98417 0.17425537109375 +98418 0.188201904296875 +98419 0.171234130859375 +98420 0.118438720703125 +98421 0.05706787109375 +98422 -0.010711669921875 +98423 -0.0914306640625 +98424 -0.162322998046875 +98425 -0.194549560546875 +98426 -0.1492919921875 +98427 -0.02166748046875 +98428 0.124053955078125 +98429 0.211151123046875 +98430 0.240447998046875 +98431 0.242218017578125 +98432 0.2257080078125 +98433 0.194366455078125 +98434 0.115509033203125 +98435 0.0128173828125 +98436 -0.053802490234375 +98437 -0.110626220703125 +98438 -0.199493408203125 +98439 -0.29437255859375 +98440 -0.33221435546875 +98441 -0.27972412109375 +98442 -0.185333251953125 +98443 -0.128204345703125 +98444 -0.115692138671875 +98445 -0.116455078125 +98446 -0.105926513671875 +98447 -0.053955078125 +98448 0.048797607421875 +98449 0.157318115234375 +98450 0.212005615234375 +98451 0.218475341796875 +98452 0.23724365234375 +98453 0.30535888671875 +98454 0.38128662109375 +98455 0.404449462890625 +98456 0.3944091796875 +98457 0.3885498046875 +98458 0.362640380859375 +98459 0.27362060546875 +98460 0.11712646484375 +98461 -0.054901123046875 +98462 -0.19085693359375 +98463 -0.28570556640625 +98464 -0.339263916015625 +98465 -0.3775634765625 +98466 -0.445709228515625 +98467 -0.535064697265625 +98468 -0.629058837890625 +98469 -0.697601318359375 +98470 -0.70391845703125 +98471 -0.6424560546875 +98472 -0.491241455078125 +98473 -0.265716552734375 +98474 -0.023712158203125 +98475 0.201751708984375 +98476 0.375823974609375 +98477 0.485076904296875 +98478 0.56884765625 +98479 0.634765625 +98480 0.63763427734375 +98481 0.5660400390625 +98482 0.4720458984375 +98483 0.40692138671875 +98484 0.3778076171875 +98485 0.376953125 +98486 0.371978759765625 +98487 0.313140869140625 +98488 0.184417724609375 +98489 0.011199951171875 +98490 -0.171051025390625 +98491 -0.33740234375 +98492 -0.47198486328125 +98493 -0.560394287109375 +98494 -0.58056640625 +98495 -0.54754638671875 +98496 -0.508575439453125 +98497 -0.459503173828125 +98498 -0.394378662109375 +98499 -0.35260009765625 +98500 -0.31170654296875 +98501 -0.197418212890625 +98502 -0.007965087890625 +98503 0.207489013671875 +98504 0.409210205078125 +98505 0.57208251953125 +98506 0.66595458984375 +98507 0.65875244140625 +98508 0.56744384765625 +98509 0.431396484375 +98510 0.29443359375 +98511 0.182464599609375 +98512 0.06365966796875 +98513 -0.075958251953125 +98514 -0.189422607421875 +98515 -0.271942138671875 +98516 -0.342529296875 +98517 -0.364166259765625 +98518 -0.327239990234375 +98519 -0.2769775390625 +98520 -0.253692626953125 +98521 -0.24365234375 +98522 -0.1983642578125 +98523 -0.116241455078125 +98524 -0.036834716796875 +98525 0.034881591796875 +98526 0.09124755859375 +98527 0.10888671875 +98528 0.125518798828125 +98529 0.15771484375 +98530 0.17828369140625 +98531 0.17108154296875 +98532 0.129974365234375 +98533 0.082427978515625 +98534 0.027679443359375 +98535 -0.065643310546875 +98536 -0.15936279296875 +98537 -0.21307373046875 +98538 -0.234649658203125 +98539 -0.2001953125 +98540 -0.119171142578125 +98541 -0.024749755859375 +98542 0.085784912109375 +98543 0.178131103515625 +98544 0.215576171875 +98545 0.211456298828125 +98546 0.17523193359375 +98547 0.128753662109375 +98548 0.1019287109375 +98549 0.0743408203125 +98550 0.04327392578125 +98551 0.038177490234375 +98552 0.076263427734375 +98553 0.14105224609375 +98554 0.186431884765625 +98555 0.188812255859375 +98556 0.1390380859375 +98557 0.041778564453125 +98558 -0.079437255859375 +98559 -0.219390869140625 +98560 -0.367828369140625 +98561 -0.494873046875 +98562 -0.556243896484375 +98563 -0.508697509765625 +98564 -0.3756103515625 +98565 -0.218902587890625 +98566 -0.063751220703125 +98567 0.091552734375 +98568 0.23602294921875 +98569 0.342987060546875 +98570 0.39520263671875 +98571 0.389373779296875 +98572 0.324249267578125 +98573 0.224090576171875 +98574 0.124267578125 +98575 0.037078857421875 +98576 -0.010101318359375 +98577 -0.019439697265625 +98578 -0.022796630859375 +98579 -0.001556396484375 +98580 0.056304931640625 +98581 0.106719970703125 +98582 0.096893310546875 +98583 0.042694091796875 +98584 -0.018035888671875 +98585 -0.07586669921875 +98586 -0.11944580078125 +98587 -0.15972900390625 +98588 -0.202606201171875 +98589 -0.24859619140625 +98590 -0.30517578125 +98591 -0.36212158203125 +98592 -0.39141845703125 +98593 -0.35528564453125 +98594 -0.249969482421875 +98595 -0.092864990234375 +98596 0.08905029296875 +98597 0.2352294921875 +98598 0.318817138671875 +98599 0.358642578125 +98600 0.347747802734375 +98601 0.28564453125 +98602 0.223175048828125 +98603 0.196746826171875 +98604 0.179840087890625 +98605 0.155548095703125 +98606 0.151214599609375 +98607 0.156951904296875 +98608 0.13177490234375 +98609 0.100799560546875 +98610 0.087127685546875 +98611 0.05487060546875 +98612 -0.009002685546875 +98613 -0.10400390625 +98614 -0.229400634765625 +98615 -0.35552978515625 +98616 -0.441925048828125 +98617 -0.473846435546875 +98618 -0.464813232421875 +98619 -0.419097900390625 +98620 -0.334320068359375 +98621 -0.227935791015625 +98622 -0.12347412109375 +98623 -0.02764892578125 +98624 0.077667236328125 +98625 0.2132568359375 +98626 0.38885498046875 +98627 0.582794189453125 +98628 0.734039306640625 +98629 0.800140380859375 +98630 0.7783203125 +98631 0.6651611328125 +98632 0.45965576171875 +98633 0.199188232421875 +98634 -0.050689697265625 +98635 -0.23297119140625 +98636 -0.33013916015625 +98637 -0.368408203125 +98638 -0.378936767578125 +98639 -0.376983642578125 +98640 -0.37969970703125 +98641 -0.391510009765625 +98642 -0.385345458984375 +98643 -0.3419189453125 +98644 -0.28289794921875 +98645 -0.251617431640625 +98646 -0.266143798828125 +98647 -0.273345947265625 +98648 -0.216796875 +98649 -0.128265380859375 +98650 -0.068145751953125 +98651 -0.0430908203125 +98652 -0.024444580078125 +98653 0.020721435546875 +98654 0.124481201171875 +98655 0.25787353515625 +98656 0.379119873046875 +98657 0.47991943359375 +98658 0.5281982421875 +98659 0.511138916015625 +98660 0.456207275390625 +98661 0.407470703125 +98662 0.383758544921875 +98663 0.35687255859375 +98664 0.31182861328125 +98665 0.250885009765625 +98666 0.1654052734375 +98667 0.035247802734375 +98668 -0.142059326171875 +98669 -0.33563232421875 +98670 -0.5345458984375 +98671 -0.72186279296875 +98672 -0.836669921875 +98673 -0.8326416015625 +98674 -0.7296142578125 +98675 -0.582550048828125 +98676 -0.440093994140625 +98677 -0.324310302734375 +98678 -0.20147705078125 +98679 -0.044647216796875 +98680 0.103973388671875 +98681 0.202392578125 +98682 0.264495849609375 +98683 0.338897705078125 +98684 0.443817138671875 +98685 0.545074462890625 +98686 0.6173095703125 +98687 0.6524658203125 +98688 0.66339111328125 +98689 0.6561279296875 +98690 0.606781005859375 +98691 0.501190185546875 +98692 0.352783203125 +98693 0.176544189453125 +98694 -0.034820556640625 +98695 -0.258209228515625 +98696 -0.44244384765625 +98697 -0.5753173828125 +98698 -0.65203857421875 +98699 -0.641632080078125 +98700 -0.562164306640625 +98701 -0.458038330078125 +98702 -0.350555419921875 +98703 -0.260528564453125 +98704 -0.192108154296875 +98705 -0.141937255859375 +98706 -0.1021728515625 +98707 -0.062896728515625 +98708 -0.011932373046875 +98709 0.062835693359375 +98710 0.148712158203125 +98711 0.241729736328125 +98712 0.34912109375 +98713 0.457305908203125 +98714 0.54388427734375 +98715 0.5728759765625 +98716 0.506591796875 +98717 0.351226806640625 +98718 0.146514892578125 +98719 -0.05523681640625 +98720 -0.21624755859375 +98721 -0.334930419921875 +98722 -0.402984619140625 +98723 -0.4412841796875 +98724 -0.49578857421875 +98725 -0.5601806640625 +98726 -0.600738525390625 +98727 -0.584228515625 +98728 -0.47930908203125 +98729 -0.27935791015625 +98730 -0.0089111328125 +98731 0.268798828125 +98732 0.482818603515625 +98733 0.60369873046875 +98734 0.650421142578125 +98735 0.66400146484375 +98736 0.6414794921875 +98737 0.572540283203125 +98738 0.498138427734375 +98739 0.439453125 +98740 0.375518798828125 +98741 0.274505615234375 +98742 0.1087646484375 +98743 -0.099395751953125 +98744 -0.3182373046875 +98745 -0.5489501953125 +98746 -0.7738037109375 +98747 -0.86383056640625 +98748 -0.870391845703125 +98749 -0.86895751953125 +98750 -0.861053466796875 +98751 -0.765869140625 +98752 -0.5301513671875 +98753 -0.214691162109375 +98754 0.137359619140625 +98755 0.474822998046875 +98756 0.76239013671875 +98757 0.867462158203125 +98758 0.870361328125 +98759 0.86480712890625 +98760 0.831817626953125 +98761 0.677581787109375 +98762 0.495880126953125 +98763 0.30767822265625 +98764 0.116180419921875 +98765 -0.110748291015625 +98766 -0.381805419921875 +98767 -0.6572265625 +98768 -0.857421875 +98769 -0.870391845703125 +98770 -0.870391845703125 +98771 -0.86444091796875 +98772 -0.85723876953125 +98773 -0.790008544921875 +98774 -0.62847900390625 +98775 -0.3956298828125 +98776 -0.126708984375 +98777 0.150115966796875 +98778 0.424041748046875 +98779 0.670623779296875 +98780 0.854522705078125 +98781 0.866485595703125 +98782 0.86920166015625 +98783 0.8653564453125 +98784 0.857147216796875 +98785 0.766845703125 +98786 0.628509521484375 +98787 0.462127685546875 +98788 0.297210693359375 +98789 0.14862060546875 +98790 -0.00537109375 +98791 -0.15753173828125 +98792 -0.31304931640625 +98793 -0.48876953125 +98794 -0.6416015625 +98795 -0.751373291015625 +98796 -0.84619140625 +98797 -0.861297607421875 +98798 -0.863250732421875 +98799 -0.856597900390625 +98800 -0.7498779296875 +98801 -0.624542236328125 +98802 -0.47808837890625 +98803 -0.253387451171875 +98804 0.003692626953125 +98805 0.2257080078125 +98806 0.427154541015625 +98807 0.643218994140625 +98808 0.855926513671875 +98809 0.870361328125 +98810 0.870361328125 +98811 0.862762451171875 +98812 0.79669189453125 +98813 0.595794677734375 +98814 0.362152099609375 +98815 0.1270751953125 +98816 -0.086944580078125 +98817 -0.2784423828125 +98818 -0.484832763671875 +98819 -0.729583740234375 +98820 -0.86688232421875 +98821 -0.870391845703125 +98822 -0.86859130859375 +98823 -0.86279296875 +98824 -0.817962646484375 +98825 -0.6116943359375 +98826 -0.3128662109375 +98827 0.039398193359375 +98828 0.422821044921875 +98829 0.805145263671875 +98830 0.870361328125 +98831 0.870361328125 +98832 0.860015869140625 +98833 0.727935791015625 +98834 0.48114013671875 +98835 0.2059326171875 +98836 -0.06103515625 +98837 -0.29913330078125 +98838 -0.516204833984375 +98839 -0.7252197265625 +98840 -0.85980224609375 +98841 -0.870391845703125 +98842 -0.870391845703125 +98843 -0.858062744140625 +98844 -0.673004150390625 +98845 -0.42694091796875 +98846 -0.2100830078125 +98847 -0.0362548828125 +98848 0.10943603515625 +98849 0.23516845703125 +98850 0.373687744140625 +98851 0.517791748046875 +98852 0.602783203125 +98853 0.635711669921875 +98854 0.655181884765625 +98855 0.65948486328125 +98856 0.651275634765625 +98857 0.61846923828125 +98858 0.53753662109375 +98859 0.404144287109375 +98860 0.22186279296875 +98861 0.003997802734375 +98862 -0.22100830078125 +98863 -0.42449951171875 +98864 -0.579833984375 +98865 -0.641876220703125 +98866 -0.6177978515625 +98867 -0.575531005859375 +98868 -0.526336669921875 +98869 -0.42645263671875 +98870 -0.2581787109375 +98871 -0.068695068359375 +98872 0.09222412109375 +98873 0.232147216796875 +98874 0.3509521484375 +98875 0.410064697265625 +98876 0.372955322265625 +98877 0.2554931640625 +98878 0.10711669921875 +98879 -0.052886962890625 +98880 -0.186279296875 +98881 -0.23291015625 +98882 -0.209442138671875 +98883 -0.174163818359375 +98884 -0.126739501953125 +98885 -0.048126220703125 +98886 0.0426025390625 +98887 0.10748291015625 +98888 0.1409912109375 +98889 0.19708251953125 +98890 0.273651123046875 +98891 0.31768798828125 +98892 0.341094970703125 +98893 0.368011474609375 +98894 0.37249755859375 +98895 0.30072021484375 +98896 0.1517333984375 +98897 -0.01470947265625 +98898 -0.1883544921875 +98899 -0.372711181640625 +98900 -0.51397705078125 +98901 -0.57177734375 +98902 -0.53948974609375 +98903 -0.43511962890625 +98904 -0.2962646484375 +98905 -0.161102294921875 +98906 -0.0435791015625 +98907 0.060394287109375 +98908 0.13665771484375 +98909 0.170135498046875 +98910 0.16552734375 +98911 0.15728759765625 +98912 0.150787353515625 +98913 0.12200927734375 +98914 0.080108642578125 +98915 0.05126953125 +98916 0.062896728515625 +98917 0.09271240234375 +98918 0.092987060546875 +98919 0.07855224609375 +98920 0.06427001953125 +98921 0.0347900390625 +98922 -0.01171875 +98923 -0.056060791015625 +98924 -0.055511474609375 +98925 -0.010467529296875 +98926 0.02508544921875 +98927 0.025665283203125 +98928 0.017333984375 +98929 0.00189208984375 +98930 -0.03173828125 +98931 -0.071502685546875 +98932 -0.13543701171875 +98933 -0.219970703125 +98934 -0.300506591796875 +98935 -0.376312255859375 +98936 -0.416107177734375 +98937 -0.371124267578125 +98938 -0.242279052734375 +98939 -0.069732666015625 +98940 0.125640869140625 +98941 0.31268310546875 +98942 0.45501708984375 +98943 0.554779052734375 +98944 0.61065673828125 +98945 0.610931396484375 +98946 0.531463623046875 +98947 0.3883056640625 +98948 0.23468017578125 +98949 0.095245361328125 +98950 -0.00396728515625 +98951 -0.04852294921875 +98952 -0.055145263671875 +98953 -0.0758056640625 +98954 -0.138702392578125 +98955 -0.209197998046875 +98956 -0.289031982421875 +98957 -0.37884521484375 +98958 -0.456329345703125 +98959 -0.51641845703125 +98960 -0.519287109375 +98961 -0.458251953125 +98962 -0.384796142578125 +98963 -0.323699951171875 +98964 -0.269287109375 +98965 -0.1951904296875 +98966 -0.100006103515625 +98967 -0.01055908203125 +98968 0.1033935546875 +98969 0.24908447265625 +98970 0.373199462890625 +98971 0.45806884765625 +98972 0.511474609375 +98973 0.565399169921875 +98974 0.61138916015625 +98975 0.5897216796875 +98976 0.4906005859375 +98977 0.33148193359375 +98978 0.147796630859375 +98979 -0.01873779296875 +98980 -0.140289306640625 +98981 -0.191986083984375 +98982 -0.184295654296875 +98983 -0.161834716796875 +98984 -0.166595458984375 +98985 -0.19390869140625 +98986 -0.22442626953125 +98987 -0.279754638671875 +98988 -0.3389892578125 +98989 -0.3543701171875 +98990 -0.348175048828125 +98991 -0.32598876953125 +98992 -0.2581787109375 +98993 -0.139801025390625 +98994 0.014617919921875 +98995 0.144378662109375 +98996 0.221038818359375 +98997 0.27069091796875 +98998 0.294036865234375 +98999 0.311767578125 +99000 0.339141845703125 +99001 0.360260009765625 +99002 0.360504150390625 +99003 0.308380126953125 +99004 0.18170166015625 +99005 0.0047607421875 +99006 -0.17559814453125 +99007 -0.3143310546875 +99008 -0.36785888671875 +99009 -0.36248779296875 +99010 -0.343536376953125 +99011 -0.3018798828125 +99012 -0.231414794921875 +99013 -0.117645263671875 +99014 0.007049560546875 +99015 0.087982177734375 +99016 0.13946533203125 +99017 0.17425537109375 +99018 0.188201904296875 +99019 0.171234130859375 +99020 0.118438720703125 +99021 0.05706787109375 +99022 -0.010711669921875 +99023 -0.0914306640625 +99024 -0.162322998046875 +99025 -0.194549560546875 +99026 -0.1492919921875 +99027 -0.02166748046875 +99028 0.124053955078125 +99029 0.211151123046875 +99030 0.240447998046875 +99031 0.242218017578125 +99032 0.2257080078125 +99033 0.194366455078125 +99034 0.115509033203125 +99035 0.0128173828125 +99036 -0.053802490234375 +99037 -0.110626220703125 +99038 -0.199493408203125 +99039 -0.29437255859375 +99040 -0.33221435546875 +99041 -0.27972412109375 +99042 -0.185333251953125 +99043 -0.128204345703125 +99044 -0.115692138671875 +99045 -0.116455078125 +99046 -0.105926513671875 +99047 -0.053955078125 +99048 0.048797607421875 +99049 0.157318115234375 +99050 0.212005615234375 +99051 0.218475341796875 +99052 0.23724365234375 +99053 0.30535888671875 +99054 0.38128662109375 +99055 0.404449462890625 +99056 0.3944091796875 +99057 0.3885498046875 +99058 0.362640380859375 +99059 0.27362060546875 +99060 0.11712646484375 +99061 -0.054901123046875 +99062 -0.19085693359375 +99063 -0.28570556640625 +99064 -0.339263916015625 +99065 -0.3775634765625 +99066 -0.445709228515625 +99067 -0.535064697265625 +99068 -0.629058837890625 +99069 -0.697601318359375 +99070 -0.70391845703125 +99071 -0.6424560546875 +99072 -0.491241455078125 +99073 -0.265716552734375 +99074 -0.023712158203125 +99075 0.201751708984375 +99076 0.375823974609375 +99077 0.485076904296875 +99078 0.56884765625 +99079 0.634765625 +99080 0.63763427734375 +99081 0.5660400390625 +99082 0.4720458984375 +99083 0.40692138671875 +99084 0.3778076171875 +99085 0.376953125 +99086 0.371978759765625 +99087 0.313140869140625 +99088 0.184417724609375 +99089 0.011199951171875 +99090 -0.171051025390625 +99091 -0.33740234375 +99092 -0.47198486328125 +99093 -0.560394287109375 +99094 -0.58056640625 +99095 -0.54754638671875 +99096 -0.508575439453125 +99097 -0.459503173828125 +99098 -0.394378662109375 +99099 -0.35260009765625 +99100 -0.31170654296875 +99101 -0.197418212890625 +99102 -0.007965087890625 +99103 0.207489013671875 +99104 0.409210205078125 +99105 0.57208251953125 +99106 0.66595458984375 +99107 0.65875244140625 +99108 0.56744384765625 +99109 0.431396484375 +99110 0.29443359375 +99111 0.182464599609375 +99112 0.06365966796875 +99113 -0.075958251953125 +99114 -0.189422607421875 +99115 -0.271942138671875 +99116 -0.342529296875 +99117 -0.364166259765625 +99118 -0.327239990234375 +99119 -0.2769775390625 +99120 -0.253692626953125 +99121 -0.24365234375 +99122 -0.1983642578125 +99123 -0.116241455078125 +99124 -0.036834716796875 +99125 0.034881591796875 +99126 0.09124755859375 +99127 0.10888671875 +99128 0.125518798828125 +99129 0.15771484375 +99130 0.17828369140625 +99131 0.17108154296875 +99132 0.129974365234375 +99133 0.082427978515625 +99134 0.027679443359375 +99135 -0.065643310546875 +99136 -0.15936279296875 +99137 -0.21307373046875 +99138 -0.234649658203125 +99139 -0.2001953125 +99140 -0.119171142578125 +99141 -0.024749755859375 +99142 0.085784912109375 +99143 0.178131103515625 +99144 0.215576171875 +99145 0.211456298828125 +99146 0.17523193359375 +99147 0.128753662109375 +99148 0.1019287109375 +99149 0.0743408203125 +99150 0.04327392578125 +99151 0.038177490234375 +99152 0.076263427734375 +99153 0.14105224609375 +99154 0.186431884765625 +99155 0.188812255859375 +99156 0.1390380859375 +99157 0.041778564453125 +99158 -0.079437255859375 +99159 -0.219390869140625 +99160 -0.367828369140625 +99161 -0.494873046875 +99162 -0.556243896484375 +99163 -0.508697509765625 +99164 -0.3756103515625 +99165 -0.218902587890625 +99166 -0.063751220703125 +99167 0.091552734375 +99168 0.23602294921875 +99169 0.342987060546875 +99170 0.39520263671875 +99171 0.389373779296875 +99172 0.324249267578125 +99173 0.224090576171875 +99174 0.124267578125 +99175 0.037078857421875 +99176 -0.010101318359375 +99177 -0.019439697265625 +99178 -0.022796630859375 +99179 -0.001556396484375 +99180 0.056304931640625 +99181 0.106719970703125 +99182 0.096893310546875 +99183 0.042694091796875 +99184 -0.018035888671875 +99185 -0.07586669921875 +99186 -0.11944580078125 +99187 -0.15972900390625 +99188 -0.202606201171875 +99189 -0.24859619140625 +99190 -0.30517578125 +99191 -0.36212158203125 +99192 -0.39141845703125 +99193 -0.35528564453125 +99194 -0.249969482421875 +99195 -0.092864990234375 +99196 0.08905029296875 +99197 0.2352294921875 +99198 0.318817138671875 +99199 0.358642578125 +99200 0.347747802734375 +99201 0.28564453125 +99202 0.223175048828125 +99203 0.196746826171875 +99204 0.179840087890625 +99205 0.155548095703125 +99206 0.151214599609375 +99207 0.156951904296875 +99208 0.13177490234375 +99209 0.100799560546875 +99210 0.087127685546875 +99211 0.05487060546875 +99212 -0.009002685546875 +99213 -0.10400390625 +99214 -0.229400634765625 +99215 -0.35552978515625 +99216 -0.441925048828125 +99217 -0.473846435546875 +99218 -0.464813232421875 +99219 -0.419097900390625 +99220 -0.334320068359375 +99221 -0.227935791015625 +99222 -0.12347412109375 +99223 -0.02764892578125 +99224 0.077667236328125 +99225 0.2132568359375 +99226 0.38885498046875 +99227 0.582794189453125 +99228 0.734039306640625 +99229 0.800140380859375 +99230 0.7783203125 +99231 0.6651611328125 +99232 0.45965576171875 +99233 0.199188232421875 +99234 -0.050689697265625 +99235 -0.23297119140625 +99236 -0.33013916015625 +99237 -0.368408203125 +99238 -0.378936767578125 +99239 -0.376983642578125 +99240 -0.37969970703125 +99241 -0.391510009765625 +99242 -0.385345458984375 +99243 -0.3419189453125 +99244 -0.28289794921875 +99245 -0.251617431640625 +99246 -0.266143798828125 +99247 -0.273345947265625 +99248 -0.216796875 +99249 -0.128265380859375 +99250 -0.068145751953125 +99251 -0.0430908203125 +99252 -0.024444580078125 +99253 0.020721435546875 +99254 0.124481201171875 +99255 0.25787353515625 +99256 0.379119873046875 +99257 0.47991943359375 +99258 0.5281982421875 +99259 0.511138916015625 +99260 0.456207275390625 +99261 0.407470703125 +99262 0.383758544921875 +99263 0.35687255859375 +99264 0.31182861328125 +99265 0.250885009765625 +99266 0.1654052734375 +99267 0.035247802734375 +99268 -0.142059326171875 +99269 -0.33563232421875 +99270 -0.5345458984375 +99271 -0.72186279296875 +99272 -0.836669921875 +99273 -0.8326416015625 +99274 -0.7296142578125 +99275 -0.582550048828125 +99276 -0.440093994140625 +99277 -0.324310302734375 +99278 -0.20147705078125 +99279 -0.044647216796875 +99280 0.103973388671875 +99281 0.202392578125 +99282 0.264495849609375 +99283 0.338897705078125 +99284 0.443817138671875 +99285 0.545074462890625 +99286 0.6173095703125 +99287 0.6524658203125 +99288 0.66339111328125 +99289 0.6561279296875 +99290 0.606781005859375 +99291 0.501190185546875 +99292 0.352783203125 +99293 0.176544189453125 +99294 -0.034820556640625 +99295 -0.258209228515625 +99296 -0.44244384765625 +99297 -0.5753173828125 +99298 -0.65203857421875 +99299 -0.641632080078125 +99300 -0.562164306640625 +99301 -0.458038330078125 +99302 -0.350555419921875 +99303 -0.260528564453125 +99304 -0.192108154296875 +99305 -0.141937255859375 +99306 -0.1021728515625 +99307 -0.062896728515625 +99308 -0.011932373046875 +99309 0.062835693359375 +99310 0.148712158203125 +99311 0.241729736328125 +99312 0.34912109375 +99313 0.457305908203125 +99314 0.54388427734375 +99315 0.5728759765625 +99316 0.506591796875 +99317 0.351226806640625 +99318 0.146514892578125 +99319 -0.05523681640625 +99320 -0.21624755859375 +99321 -0.334930419921875 +99322 -0.402984619140625 +99323 -0.4412841796875 +99324 -0.49578857421875 +99325 -0.5601806640625 +99326 -0.600738525390625 +99327 -0.584228515625 +99328 -0.47930908203125 +99329 -0.27935791015625 +99330 -0.0089111328125 +99331 0.268798828125 +99332 0.482818603515625 +99333 0.60369873046875 +99334 0.650421142578125 +99335 0.66400146484375 +99336 0.6414794921875 +99337 0.572540283203125 +99338 0.498138427734375 +99339 0.439453125 +99340 0.375518798828125 +99341 0.274505615234375 +99342 0.1087646484375 +99343 -0.099395751953125 +99344 -0.3182373046875 +99345 -0.5489501953125 +99346 -0.7738037109375 +99347 -0.86383056640625 +99348 -0.870391845703125 +99349 -0.86895751953125 +99350 -0.861053466796875 +99351 -0.765869140625 +99352 -0.5301513671875 +99353 -0.214691162109375 +99354 0.137359619140625 +99355 0.474822998046875 +99356 0.76239013671875 +99357 0.867462158203125 +99358 0.870361328125 +99359 0.86480712890625 +99360 0.831817626953125 +99361 0.677581787109375 +99362 0.495880126953125 +99363 0.30767822265625 +99364 0.116180419921875 +99365 -0.110748291015625 +99366 -0.381805419921875 +99367 -0.6572265625 +99368 -0.857421875 +99369 -0.870391845703125 +99370 -0.870391845703125 +99371 -0.86444091796875 +99372 -0.85723876953125 +99373 -0.790008544921875 +99374 -0.62847900390625 +99375 -0.3956298828125 +99376 -0.126708984375 +99377 0.150115966796875 +99378 0.424041748046875 +99379 0.670623779296875 +99380 0.854522705078125 +99381 0.866485595703125 +99382 0.86920166015625 +99383 0.8653564453125 +99384 0.857147216796875 +99385 0.766845703125 +99386 0.628509521484375 +99387 0.462127685546875 +99388 0.297210693359375 +99389 0.14862060546875 +99390 -0.00537109375 +99391 -0.15753173828125 +99392 -0.31304931640625 +99393 -0.48876953125 +99394 -0.6416015625 +99395 -0.751373291015625 +99396 -0.84619140625 +99397 -0.861297607421875 +99398 -0.863250732421875 +99399 -0.856597900390625 +99400 -0.7498779296875 +99401 -0.624542236328125 +99402 -0.47808837890625 +99403 -0.253387451171875 +99404 0.003692626953125 +99405 0.2257080078125 +99406 0.427154541015625 +99407 0.643218994140625 +99408 0.855926513671875 +99409 0.870361328125 +99410 0.870361328125 +99411 0.862762451171875 +99412 0.79669189453125 +99413 0.595794677734375 +99414 0.362152099609375 +99415 0.1270751953125 +99416 -0.086944580078125 +99417 -0.2784423828125 +99418 -0.484832763671875 +99419 -0.729583740234375 +99420 -0.86688232421875 +99421 -0.870391845703125 +99422 -0.86859130859375 +99423 -0.86279296875 +99424 -0.817962646484375 +99425 -0.6116943359375 +99426 -0.3128662109375 +99427 0.039398193359375 +99428 0.422821044921875 +99429 0.805145263671875 +99430 0.870361328125 +99431 0.870361328125 +99432 0.860015869140625 +99433 0.727935791015625 +99434 0.48114013671875 +99435 0.2059326171875 +99436 -0.06103515625 +99437 -0.29913330078125 +99438 -0.516204833984375 +99439 -0.7252197265625 +99440 -0.85980224609375 +99441 -0.870391845703125 +99442 -0.870391845703125 +99443 -0.858062744140625 +99444 -0.673004150390625 +99445 -0.42694091796875 +99446 -0.2100830078125 +99447 -0.0362548828125 +99448 0.10943603515625 +99449 0.23516845703125 +99450 0.373687744140625 +99451 0.517791748046875 +99452 0.602783203125 +99453 0.635711669921875 +99454 0.655181884765625 +99455 0.65948486328125 +99456 0.651275634765625 +99457 0.61846923828125 +99458 0.53753662109375 +99459 0.404144287109375 +99460 0.22186279296875 +99461 0.003997802734375 +99462 -0.22100830078125 +99463 -0.42449951171875 +99464 -0.579833984375 +99465 -0.641876220703125 +99466 -0.6177978515625 +99467 -0.575531005859375 +99468 -0.526336669921875 +99469 -0.42645263671875 +99470 -0.2581787109375 +99471 -0.068695068359375 +99472 0.09222412109375 +99473 0.232147216796875 +99474 0.3509521484375 +99475 0.410064697265625 +99476 0.372955322265625 +99477 0.2554931640625 +99478 0.10711669921875 +99479 -0.052886962890625 +99480 -0.186279296875 +99481 -0.23291015625 +99482 -0.209442138671875 +99483 -0.174163818359375 +99484 -0.126739501953125 +99485 -0.048126220703125 +99486 0.0426025390625 +99487 0.10748291015625 +99488 0.1409912109375 +99489 0.19708251953125 +99490 0.273651123046875 +99491 0.31768798828125 +99492 0.341094970703125 +99493 0.368011474609375 +99494 0.37249755859375 +99495 0.30072021484375 +99496 0.1517333984375 +99497 -0.01470947265625 +99498 -0.1883544921875 +99499 -0.372711181640625 +99500 -0.51397705078125 +99501 -0.57177734375 +99502 -0.53948974609375 +99503 -0.43511962890625 +99504 -0.2962646484375 +99505 -0.161102294921875 +99506 -0.0435791015625 +99507 0.060394287109375 +99508 0.13665771484375 +99509 0.170135498046875 +99510 0.16552734375 +99511 0.15728759765625 +99512 0.150787353515625 +99513 0.12200927734375 +99514 0.080108642578125 +99515 0.05126953125 +99516 0.062896728515625 +99517 0.09271240234375 +99518 0.092987060546875 +99519 0.07855224609375 +99520 0.06427001953125 +99521 0.0347900390625 +99522 -0.01171875 +99523 -0.056060791015625 +99524 -0.055511474609375 +99525 -0.010467529296875 +99526 0.02508544921875 +99527 0.025665283203125 +99528 0.017333984375 +99529 0.00189208984375 +99530 -0.03173828125 +99531 -0.071502685546875 +99532 -0.13543701171875 +99533 -0.219970703125 +99534 -0.300506591796875 +99535 -0.376312255859375 +99536 -0.416107177734375 +99537 -0.371124267578125 +99538 -0.242279052734375 +99539 -0.069732666015625 +99540 0.125640869140625 +99541 0.31268310546875 +99542 0.45501708984375 +99543 0.554779052734375 +99544 0.61065673828125 +99545 0.610931396484375 +99546 0.531463623046875 +99547 0.3883056640625 +99548 0.23468017578125 +99549 0.095245361328125 +99550 -0.00396728515625 +99551 -0.04852294921875 +99552 -0.055145263671875 +99553 -0.0758056640625 +99554 -0.138702392578125 +99555 -0.209197998046875 +99556 -0.289031982421875 +99557 -0.37884521484375 +99558 -0.456329345703125 +99559 -0.51641845703125 +99560 -0.519287109375 +99561 -0.458251953125 +99562 -0.384796142578125 +99563 -0.323699951171875 +99564 -0.269287109375 +99565 -0.1951904296875 +99566 -0.100006103515625 +99567 -0.01055908203125 +99568 0.1033935546875 +99569 0.24908447265625 +99570 0.373199462890625 +99571 0.45806884765625 +99572 0.511474609375 +99573 0.565399169921875 +99574 0.61138916015625 +99575 0.5897216796875 +99576 0.4906005859375 +99577 0.33148193359375 +99578 0.147796630859375 +99579 -0.01873779296875 +99580 -0.140289306640625 +99581 -0.191986083984375 +99582 -0.184295654296875 +99583 -0.161834716796875 +99584 -0.166595458984375 +99585 -0.19390869140625 +99586 -0.22442626953125 +99587 -0.279754638671875 +99588 -0.3389892578125 +99589 -0.3543701171875 +99590 -0.348175048828125 +99591 -0.32598876953125 +99592 -0.2581787109375 +99593 -0.139801025390625 +99594 0.014617919921875 +99595 0.144378662109375 +99596 0.221038818359375 +99597 0.27069091796875 +99598 0.294036865234375 +99599 0.311767578125 +99600 0.339141845703125 +99601 0.360260009765625 +99602 0.360504150390625 +99603 0.308380126953125 +99604 0.18170166015625 +99605 0.0047607421875 +99606 -0.17559814453125 +99607 -0.3143310546875 +99608 -0.36785888671875 +99609 -0.36248779296875 +99610 -0.343536376953125 +99611 -0.3018798828125 +99612 -0.231414794921875 +99613 -0.117645263671875 +99614 0.007049560546875 +99615 0.087982177734375 +99616 0.13946533203125 +99617 0.17425537109375 +99618 0.188201904296875 +99619 0.171234130859375 +99620 0.118438720703125 +99621 0.05706787109375 +99622 -0.010711669921875 +99623 -0.0914306640625 +99624 -0.162322998046875 +99625 -0.194549560546875 +99626 -0.1492919921875 +99627 -0.02166748046875 +99628 0.124053955078125 +99629 0.211151123046875 +99630 0.240447998046875 +99631 0.242218017578125 +99632 0.2257080078125 +99633 0.194366455078125 +99634 0.115509033203125 +99635 0.0128173828125 +99636 -0.053802490234375 +99637 -0.110626220703125 +99638 -0.199493408203125 +99639 -0.29437255859375 +99640 -0.33221435546875 +99641 -0.27972412109375 +99642 -0.185333251953125 +99643 -0.128204345703125 +99644 -0.115692138671875 +99645 -0.116455078125 +99646 -0.105926513671875 +99647 -0.053955078125 +99648 0.048797607421875 +99649 0.157318115234375 +99650 0.212005615234375 +99651 0.218475341796875 +99652 0.23724365234375 +99653 0.30535888671875 +99654 0.38128662109375 +99655 0.404449462890625 +99656 0.3944091796875 +99657 0.3885498046875 +99658 0.362640380859375 +99659 0.27362060546875 +99660 0.11712646484375 +99661 -0.054901123046875 +99662 -0.19085693359375 +99663 -0.28570556640625 +99664 -0.339263916015625 +99665 -0.3775634765625 +99666 -0.445709228515625 +99667 -0.535064697265625 +99668 -0.629058837890625 +99669 -0.697601318359375 +99670 -0.70391845703125 +99671 -0.6424560546875 +99672 -0.491241455078125 +99673 -0.265716552734375 +99674 -0.023712158203125 +99675 0.201751708984375 +99676 0.375823974609375 +99677 0.485076904296875 +99678 0.56884765625 +99679 0.634765625 +99680 0.63763427734375 +99681 0.5660400390625 +99682 0.4720458984375 +99683 0.40692138671875 +99684 0.3778076171875 +99685 0.376953125 +99686 0.371978759765625 +99687 0.313140869140625 +99688 0.184417724609375 +99689 0.011199951171875 +99690 -0.171051025390625 +99691 -0.33740234375 +99692 -0.47198486328125 +99693 -0.560394287109375 +99694 -0.58056640625 +99695 -0.54754638671875 +99696 -0.508575439453125 +99697 -0.459503173828125 +99698 -0.394378662109375 +99699 -0.35260009765625 +99700 -0.31170654296875 +99701 -0.197418212890625 +99702 -0.007965087890625 +99703 0.207489013671875 +99704 0.409210205078125 +99705 0.57208251953125 +99706 0.66595458984375 +99707 0.65875244140625 +99708 0.56744384765625 +99709 0.431396484375 +99710 0.29443359375 +99711 0.182464599609375 +99712 0.06365966796875 +99713 -0.075958251953125 +99714 -0.189422607421875 +99715 -0.271942138671875 +99716 -0.342529296875 +99717 -0.364166259765625 +99718 -0.327239990234375 +99719 -0.2769775390625 +99720 -0.253692626953125 +99721 -0.24365234375 +99722 -0.1983642578125 +99723 -0.116241455078125 +99724 -0.036834716796875 +99725 0.034881591796875 +99726 0.09124755859375 +99727 0.10888671875 +99728 0.125518798828125 +99729 0.15771484375 +99730 0.17828369140625 +99731 0.17108154296875 +99732 0.129974365234375 +99733 0.082427978515625 +99734 0.027679443359375 +99735 -0.065643310546875 +99736 -0.15936279296875 +99737 -0.21307373046875 +99738 -0.234649658203125 +99739 -0.2001953125 +99740 -0.119171142578125 +99741 -0.024749755859375 +99742 0.085784912109375 +99743 0.178131103515625 +99744 0.215576171875 +99745 0.211456298828125 +99746 0.17523193359375 +99747 0.128753662109375 +99748 0.1019287109375 +99749 0.0743408203125 +99750 0.04327392578125 +99751 0.038177490234375 +99752 0.076263427734375 +99753 0.14105224609375 +99754 0.186431884765625 +99755 0.188812255859375 +99756 0.1390380859375 +99757 0.041778564453125 +99758 -0.079437255859375 +99759 -0.219390869140625 +99760 -0.367828369140625 +99761 -0.494873046875 +99762 -0.556243896484375 +99763 -0.508697509765625 +99764 -0.3756103515625 +99765 -0.218902587890625 +99766 -0.063751220703125 +99767 0.091552734375 +99768 0.23602294921875 +99769 0.342987060546875 +99770 0.39520263671875 +99771 0.389373779296875 +99772 0.324249267578125 +99773 0.224090576171875 +99774 0.124267578125 +99775 0.037078857421875 +99776 -0.010101318359375 +99777 -0.019439697265625 +99778 -0.022796630859375 +99779 -0.001556396484375 +99780 0.056304931640625 +99781 0.106719970703125 +99782 0.096893310546875 +99783 0.042694091796875 +99784 -0.018035888671875 +99785 -0.07586669921875 +99786 -0.11944580078125 +99787 -0.15972900390625 +99788 -0.202606201171875 +99789 -0.24859619140625 +99790 -0.30517578125 +99791 -0.36212158203125 +99792 -0.39141845703125 +99793 -0.35528564453125 +99794 -0.249969482421875 +99795 -0.092864990234375 +99796 0.08905029296875 +99797 0.2352294921875 +99798 0.318817138671875 +99799 0.358642578125 +99800 0.347747802734375 +99801 0.28564453125 +99802 0.223175048828125 +99803 0.196746826171875 +99804 0.179840087890625 +99805 0.155548095703125 +99806 0.151214599609375 +99807 0.156951904296875 +99808 0.13177490234375 +99809 0.100799560546875 +99810 0.087127685546875 +99811 0.05487060546875 +99812 -0.009002685546875 +99813 -0.10400390625 +99814 -0.229400634765625 +99815 -0.35552978515625 +99816 -0.441925048828125 +99817 -0.473846435546875 +99818 -0.464813232421875 +99819 -0.419097900390625 +99820 -0.334320068359375 +99821 -0.227935791015625 +99822 -0.12347412109375 +99823 -0.02764892578125 +99824 0.077667236328125 +99825 0.2132568359375 +99826 0.38885498046875 +99827 0.582794189453125 +99828 0.734039306640625 +99829 0.800140380859375 +99830 0.7783203125 +99831 0.6651611328125 +99832 0.45965576171875 +99833 0.199188232421875 +99834 -0.050689697265625 +99835 -0.23297119140625 +99836 -0.33013916015625 +99837 -0.368408203125 +99838 -0.378936767578125 +99839 -0.376983642578125 +99840 -0.37969970703125 +99841 -0.391510009765625 +99842 -0.385345458984375 +99843 -0.3419189453125 +99844 -0.28289794921875 +99845 -0.251617431640625 +99846 -0.266143798828125 +99847 -0.273345947265625 +99848 -0.216796875 +99849 -0.128265380859375 +99850 -0.068145751953125 +99851 -0.0430908203125 +99852 -0.024444580078125 +99853 0.020721435546875 +99854 0.124481201171875 +99855 0.25787353515625 +99856 0.379119873046875 +99857 0.47991943359375 +99858 0.5281982421875 +99859 0.511138916015625 +99860 0.456207275390625 +99861 0.407470703125 +99862 0.383758544921875 +99863 0.35687255859375 +99864 0.31182861328125 +99865 0.250885009765625 +99866 0.1654052734375 +99867 0.035247802734375 +99868 -0.142059326171875 +99869 -0.33563232421875 +99870 -0.5345458984375 +99871 -0.72186279296875 +99872 -0.836669921875 +99873 -0.8326416015625 +99874 -0.7296142578125 +99875 -0.582550048828125 +99876 -0.440093994140625 +99877 -0.324310302734375 +99878 -0.20147705078125 +99879 -0.044647216796875 +99880 0.103973388671875 +99881 0.202392578125 +99882 0.264495849609375 +99883 0.338897705078125 +99884 0.443817138671875 +99885 0.545074462890625 +99886 0.6173095703125 +99887 0.6524658203125 +99888 0.66339111328125 +99889 0.6561279296875 +99890 0.606781005859375 +99891 0.501190185546875 +99892 0.352783203125 +99893 0.176544189453125 +99894 -0.034820556640625 +99895 -0.258209228515625 +99896 -0.44244384765625 +99897 -0.5753173828125 +99898 -0.65203857421875 +99899 -0.641632080078125 +99900 -0.562164306640625 +99901 -0.458038330078125 +99902 -0.350555419921875 +99903 -0.260528564453125 +99904 -0.192108154296875 +99905 -0.141937255859375 +99906 -0.1021728515625 +99907 -0.062896728515625 +99908 -0.011932373046875 +99909 0.062835693359375 +99910 0.148712158203125 +99911 0.241729736328125 +99912 0.34912109375 +99913 0.457305908203125 +99914 0.54388427734375 +99915 0.5728759765625 +99916 0.506591796875 +99917 0.351226806640625 +99918 0.146514892578125 +99919 -0.05523681640625 +99920 -0.21624755859375 +99921 -0.334930419921875 +99922 -0.402984619140625 +99923 -0.4412841796875 +99924 -0.49578857421875 +99925 -0.5601806640625 +99926 -0.600738525390625 +99927 -0.584228515625 +99928 -0.47930908203125 +99929 -0.27935791015625 +99930 -0.0089111328125 +99931 0.268798828125 +99932 0.482818603515625 +99933 0.60369873046875 +99934 0.650421142578125 +99935 0.66400146484375 +99936 0.6414794921875 +99937 0.572540283203125 +99938 0.498138427734375 +99939 0.439453125 +99940 0.375518798828125 +99941 0.274505615234375 +99942 0.1087646484375 +99943 -0.099395751953125 +99944 -0.3182373046875 +99945 -0.5489501953125 +99946 -0.7738037109375 +99947 -0.86383056640625 +99948 -0.870391845703125 +99949 -0.86895751953125 +99950 -0.861053466796875 +99951 -0.765869140625 +99952 -0.5301513671875 +99953 -0.214691162109375 +99954 0.137359619140625 +99955 0.474822998046875 +99956 0.76239013671875 +99957 0.867462158203125 +99958 0.870361328125 +99959 0.86480712890625 +99960 0.831817626953125 +99961 0.677581787109375 +99962 0.495880126953125 +99963 0.30767822265625 +99964 0.116180419921875 +99965 -0.110748291015625 +99966 -0.381805419921875 +99967 -0.6572265625 +99968 -0.857421875 +99969 -0.870391845703125 +99970 -0.870391845703125 +99971 -0.86444091796875 +99972 -0.85723876953125 +99973 -0.790008544921875 +99974 -0.62847900390625 +99975 -0.3956298828125 +99976 -0.126708984375 +99977 0.150115966796875 +99978 0.424041748046875 +99979 0.670623779296875 +99980 0.854522705078125 +99981 0.866485595703125 +99982 0.86920166015625 +99983 0.8653564453125 +99984 0.857147216796875 +99985 0.766845703125 +99986 0.628509521484375 +99987 0.462127685546875 +99988 0.297210693359375 +99989 0.14862060546875 +99990 -0.00537109375 +99991 -0.15753173828125 +99992 -0.31304931640625 +99993 -0.48876953125 +99994 -0.6416015625 +99995 -0.751373291015625 +99996 -0.84619140625 +99997 -0.861297607421875 +99998 -0.863250732421875 +99999 -0.856597900390625 +100000 -0.7498779296875 +100001 -0.624542236328125 +100002 -0.47808837890625 +100003 -0.253387451171875 +100004 0.003692626953125 +100005 0.2257080078125 +100006 0.427154541015625 +100007 0.643218994140625 +100008 0.855926513671875 +100009 0.870361328125 +100010 0.870361328125 +100011 0.862762451171875 +100012 0.79669189453125 +100013 0.595794677734375 +100014 0.362152099609375 +100015 0.1270751953125 +100016 -0.086944580078125 +100017 -0.2784423828125 +100018 -0.484832763671875 +100019 -0.729583740234375 +100020 -0.86688232421875 +100021 -0.870391845703125 +100022 -0.86859130859375 +100023 -0.86279296875 +100024 -0.817962646484375 +100025 -0.6116943359375 +100026 -0.3128662109375 +100027 0.039398193359375 +100028 0.422821044921875 +100029 0.805145263671875 +100030 0.870361328125 +100031 0.870361328125 +100032 0.860015869140625 +100033 0.727935791015625 +100034 0.48114013671875 +100035 0.2059326171875 +100036 -0.06103515625 +100037 -0.29913330078125 +100038 -0.516204833984375 +100039 -0.7252197265625 +100040 -0.85980224609375 +100041 -0.870391845703125 +100042 -0.870391845703125 +100043 -0.858062744140625 +100044 -0.673004150390625 +100045 -0.42694091796875 +100046 -0.2100830078125 +100047 -0.0362548828125 +100048 0.10943603515625 +100049 0.23516845703125 +100050 0.373687744140625 +100051 0.517791748046875 +100052 0.602783203125 +100053 0.635711669921875 +100054 0.655181884765625 +100055 0.65948486328125 +100056 0.651275634765625 +100057 0.61846923828125 +100058 0.53753662109375 +100059 0.404144287109375 +100060 0.22186279296875 +100061 0.003997802734375 +100062 -0.22100830078125 +100063 -0.42449951171875 +100064 -0.579833984375 +100065 -0.641876220703125 +100066 -0.6177978515625 +100067 -0.575531005859375 +100068 -0.526336669921875 +100069 -0.42645263671875 +100070 -0.2581787109375 +100071 -0.068695068359375 +100072 0.09222412109375 +100073 0.232147216796875 +100074 0.3509521484375 +100075 0.410064697265625 +100076 0.372955322265625 +100077 0.2554931640625 +100078 0.10711669921875 +100079 -0.052886962890625 +100080 -0.186279296875 +100081 -0.23291015625 +100082 -0.209442138671875 +100083 -0.174163818359375 +100084 -0.126739501953125 +100085 -0.048126220703125 +100086 0.0426025390625 +100087 0.10748291015625 +100088 0.1409912109375 +100089 0.19708251953125 +100090 0.273651123046875 +100091 0.31768798828125 +100092 0.341094970703125 +100093 0.368011474609375 +100094 0.37249755859375 +100095 0.30072021484375 +100096 0.1517333984375 +100097 -0.01470947265625 +100098 -0.1883544921875 +100099 -0.372711181640625 +100100 -0.51397705078125 +100101 -0.57177734375 +100102 -0.53948974609375 +100103 -0.43511962890625 +100104 -0.2962646484375 +100105 -0.161102294921875 +100106 -0.0435791015625 +100107 0.060394287109375 +100108 0.13665771484375 +100109 0.170135498046875 +100110 0.16552734375 +100111 0.15728759765625 +100112 0.150787353515625 +100113 0.12200927734375 +100114 0.080108642578125 +100115 0.05126953125 +100116 0.062896728515625 +100117 0.09271240234375 +100118 0.092987060546875 +100119 0.07855224609375 +100120 0.06427001953125 +100121 0.0347900390625 +100122 -0.01171875 +100123 -0.056060791015625 +100124 -0.055511474609375 +100125 -0.010467529296875 +100126 0.02508544921875 +100127 0.025665283203125 +100128 0.017333984375 +100129 0.00189208984375 +100130 -0.03173828125 +100131 -0.071502685546875 +100132 -0.13543701171875 +100133 -0.219970703125 +100134 -0.300506591796875 +100135 -0.376312255859375 +100136 -0.416107177734375 +100137 -0.371124267578125 +100138 -0.242279052734375 +100139 -0.069732666015625 +100140 0.125640869140625 +100141 0.31268310546875 +100142 0.45501708984375 +100143 0.554779052734375 +100144 0.61065673828125 +100145 0.610931396484375 +100146 0.531463623046875 +100147 0.3883056640625 +100148 0.23468017578125 +100149 0.095245361328125 +100150 -0.00396728515625 +100151 -0.04852294921875 +100152 -0.055145263671875 +100153 -0.0758056640625 +100154 -0.138702392578125 +100155 -0.209197998046875 +100156 -0.289031982421875 +100157 -0.37884521484375 +100158 -0.456329345703125 +100159 -0.51641845703125 +100160 -0.519287109375 +100161 -0.458251953125 +100162 -0.384796142578125 +100163 -0.323699951171875 +100164 -0.269287109375 +100165 -0.1951904296875 +100166 -0.100006103515625 +100167 -0.01055908203125 +100168 0.1033935546875 +100169 0.24908447265625 +100170 0.373199462890625 +100171 0.45806884765625 +100172 0.511474609375 +100173 0.565399169921875 +100174 0.61138916015625 +100175 0.5897216796875 +100176 0.4906005859375 +100177 0.33148193359375 +100178 0.147796630859375 +100179 -0.01873779296875 +100180 -0.140289306640625 +100181 -0.191986083984375 +100182 -0.184295654296875 +100183 -0.161834716796875 +100184 -0.166595458984375 +100185 -0.19390869140625 +100186 -0.22442626953125 +100187 -0.279754638671875 +100188 -0.3389892578125 +100189 -0.3543701171875 +100190 -0.348175048828125 +100191 -0.32598876953125 +100192 -0.2581787109375 +100193 -0.139801025390625 +100194 0.014617919921875 +100195 0.144378662109375 +100196 0.221038818359375 +100197 0.27069091796875 +100198 0.294036865234375 +100199 0.311767578125 +100200 0.339141845703125 +100201 0.360260009765625 +100202 0.360504150390625 +100203 0.308380126953125 +100204 0.18170166015625 +100205 0.0047607421875 +100206 -0.17559814453125 +100207 -0.3143310546875 +100208 -0.36785888671875 +100209 -0.36248779296875 +100210 -0.343536376953125 +100211 -0.3018798828125 +100212 -0.231414794921875 +100213 -0.117645263671875 +100214 0.007049560546875 +100215 0.087982177734375 +100216 0.13946533203125 +100217 0.17425537109375 +100218 0.188201904296875 +100219 0.171234130859375 +100220 0.118438720703125 +100221 0.05706787109375 +100222 -0.010711669921875 +100223 -0.0914306640625 +100224 -0.162322998046875 +100225 -0.194549560546875 +100226 -0.1492919921875 +100227 -0.02166748046875 +100228 0.124053955078125 +100229 0.211151123046875 +100230 0.240447998046875 +100231 0.242218017578125 +100232 0.2257080078125 +100233 0.194366455078125 +100234 0.115509033203125 +100235 0.0128173828125 +100236 -0.053802490234375 +100237 -0.110626220703125 +100238 -0.199493408203125 +100239 -0.29437255859375 +100240 -0.33221435546875 +100241 -0.27972412109375 +100242 -0.185333251953125 +100243 -0.128204345703125 +100244 -0.115692138671875 +100245 -0.116455078125 +100246 -0.105926513671875 +100247 -0.053955078125 +100248 0.048797607421875 +100249 0.157318115234375 +100250 0.212005615234375 +100251 0.218475341796875 +100252 0.23724365234375 +100253 0.30535888671875 +100254 0.38128662109375 +100255 0.404449462890625 +100256 0.3944091796875 +100257 0.3885498046875 +100258 0.362640380859375 +100259 0.27362060546875 +100260 0.11712646484375 +100261 -0.054901123046875 +100262 -0.19085693359375 +100263 -0.28570556640625 +100264 -0.339263916015625 +100265 -0.3775634765625 +100266 -0.445709228515625 +100267 -0.535064697265625 +100268 -0.629058837890625 +100269 -0.697601318359375 +100270 -0.70391845703125 +100271 -0.6424560546875 +100272 -0.491241455078125 +100273 -0.265716552734375 +100274 -0.023712158203125 +100275 0.201751708984375 +100276 0.375823974609375 +100277 0.485076904296875 +100278 0.56884765625 +100279 0.634765625 +100280 0.63763427734375 +100281 0.5660400390625 +100282 0.4720458984375 +100283 0.40692138671875 +100284 0.3778076171875 +100285 0.376953125 +100286 0.371978759765625 +100287 0.313140869140625 +100288 0.184417724609375 +100289 0.011199951171875 +100290 -0.171051025390625 +100291 -0.33740234375 +100292 -0.47198486328125 +100293 -0.560394287109375 +100294 -0.58056640625 +100295 -0.54754638671875 +100296 -0.508575439453125 +100297 -0.459503173828125 +100298 -0.394378662109375 +100299 -0.35260009765625 +100300 -0.31170654296875 +100301 -0.197418212890625 +100302 -0.007965087890625 +100303 0.207489013671875 +100304 0.409210205078125 +100305 0.57208251953125 +100306 0.66595458984375 +100307 0.65875244140625 +100308 0.56744384765625 +100309 0.431396484375 +100310 0.29443359375 +100311 0.182464599609375 +100312 0.06365966796875 +100313 -0.075958251953125 +100314 -0.189422607421875 +100315 -0.271942138671875 +100316 -0.342529296875 +100317 -0.364166259765625 +100318 -0.327239990234375 +100319 -0.2769775390625 +100320 -0.253692626953125 +100321 -0.24365234375 +100322 -0.1983642578125 +100323 -0.116241455078125 +100324 -0.036834716796875 +100325 0.034881591796875 +100326 0.09124755859375 +100327 0.10888671875 +100328 0.125518798828125 +100329 0.15771484375 +100330 0.17828369140625 +100331 0.17108154296875 +100332 0.129974365234375 +100333 0.082427978515625 +100334 0.027679443359375 +100335 -0.065643310546875 +100336 -0.15936279296875 +100337 -0.21307373046875 +100338 -0.234649658203125 +100339 -0.2001953125 +100340 -0.119171142578125 +100341 -0.024749755859375 +100342 0.085784912109375 +100343 0.178131103515625 +100344 0.215576171875 +100345 0.211456298828125 +100346 0.17523193359375 +100347 0.128753662109375 +100348 0.1019287109375 +100349 0.0743408203125 +100350 0.04327392578125 +100351 0.038177490234375 +100352 0.076263427734375 +100353 0.14105224609375 +100354 0.186431884765625 +100355 0.188812255859375 +100356 0.1390380859375 +100357 0.041778564453125 +100358 -0.079437255859375 +100359 -0.219390869140625 +100360 -0.367828369140625 +100361 -0.494873046875 +100362 -0.556243896484375 +100363 -0.508697509765625 +100364 -0.3756103515625 +100365 -0.218902587890625 +100366 -0.063751220703125 +100367 0.091552734375 +100368 0.23602294921875 +100369 0.342987060546875 +100370 0.39520263671875 +100371 0.389373779296875 +100372 0.324249267578125 +100373 0.224090576171875 +100374 0.124267578125 +100375 0.037078857421875 +100376 -0.010101318359375 +100377 -0.019439697265625 +100378 -0.022796630859375 +100379 -0.001556396484375 +100380 0.056304931640625 +100381 0.106719970703125 +100382 0.096893310546875 +100383 0.042694091796875 +100384 -0.018035888671875 +100385 -0.07586669921875 +100386 -0.11944580078125 +100387 -0.15972900390625 +100388 -0.202606201171875 +100389 -0.24859619140625 +100390 -0.30517578125 +100391 -0.36212158203125 +100392 -0.39141845703125 +100393 -0.35528564453125 +100394 -0.249969482421875 +100395 -0.092864990234375 +100396 0.08905029296875 +100397 0.2352294921875 +100398 0.318817138671875 +100399 0.358642578125 +100400 0.347747802734375 +100401 0.28564453125 +100402 0.223175048828125 +100403 0.196746826171875 +100404 0.179840087890625 +100405 0.155548095703125 +100406 0.151214599609375 +100407 0.156951904296875 +100408 0.13177490234375 +100409 0.100799560546875 +100410 0.087127685546875 +100411 0.05487060546875 +100412 -0.009002685546875 +100413 -0.10400390625 +100414 -0.229400634765625 +100415 -0.35552978515625 +100416 -0.441925048828125 +100417 -0.473846435546875 +100418 -0.464813232421875 +100419 -0.419097900390625 +100420 -0.334320068359375 +100421 -0.227935791015625 +100422 -0.12347412109375 +100423 -0.02764892578125 +100424 0.077667236328125 +100425 0.2132568359375 +100426 0.38885498046875 +100427 0.582794189453125 +100428 0.734039306640625 +100429 0.800140380859375 +100430 0.7783203125 +100431 0.6651611328125 +100432 0.45965576171875 +100433 0.199188232421875 +100434 -0.050689697265625 +100435 -0.23297119140625 +100436 -0.33013916015625 +100437 -0.368408203125 +100438 -0.378936767578125 +100439 -0.376983642578125 +100440 -0.37969970703125 +100441 -0.391510009765625 +100442 -0.385345458984375 +100443 -0.3419189453125 +100444 -0.28289794921875 +100445 -0.251617431640625 +100446 -0.266143798828125 +100447 -0.273345947265625 +100448 -0.216796875 +100449 -0.128265380859375 +100450 -0.068145751953125 +100451 -0.0430908203125 +100452 -0.024444580078125 +100453 0.020721435546875 +100454 0.124481201171875 +100455 0.25787353515625 +100456 0.379119873046875 +100457 0.47991943359375 +100458 0.5281982421875 +100459 0.511138916015625 +100460 0.456207275390625 +100461 0.407470703125 +100462 0.383758544921875 +100463 0.35687255859375 +100464 0.31182861328125 +100465 0.250885009765625 +100466 0.1654052734375 +100467 0.035247802734375 +100468 -0.142059326171875 +100469 -0.33563232421875 +100470 -0.5345458984375 +100471 -0.72186279296875 +100472 -0.836669921875 +100473 -0.8326416015625 +100474 -0.7296142578125 +100475 -0.582550048828125 +100476 -0.440093994140625 +100477 -0.324310302734375 +100478 -0.20147705078125 +100479 -0.044647216796875 +100480 0.103973388671875 +100481 0.202392578125 +100482 0.264495849609375 +100483 0.338897705078125 +100484 0.443817138671875 +100485 0.545074462890625 +100486 0.6173095703125 +100487 0.6524658203125 +100488 0.66339111328125 +100489 0.6561279296875 +100490 0.606781005859375 +100491 0.501190185546875 +100492 0.352783203125 +100493 0.176544189453125 +100494 -0.034820556640625 +100495 -0.258209228515625 +100496 -0.44244384765625 +100497 -0.5753173828125 +100498 -0.65203857421875 +100499 -0.641632080078125 +100500 -0.562164306640625 +100501 -0.458038330078125 +100502 -0.350555419921875 +100503 -0.260528564453125 +100504 -0.192108154296875 +100505 -0.141937255859375 +100506 -0.1021728515625 +100507 -0.062896728515625 +100508 -0.011932373046875 +100509 0.062835693359375 +100510 0.148712158203125 +100511 0.241729736328125 +100512 0.34912109375 +100513 0.457305908203125 +100514 0.54388427734375 +100515 0.5728759765625 +100516 0.506591796875 +100517 0.351226806640625 +100518 0.146514892578125 +100519 -0.05523681640625 +100520 -0.21624755859375 +100521 -0.334930419921875 +100522 -0.402984619140625 +100523 -0.4412841796875 +100524 -0.49578857421875 +100525 -0.5601806640625 +100526 -0.600738525390625 +100527 -0.584228515625 +100528 -0.47930908203125 +100529 -0.27935791015625 +100530 -0.0089111328125 +100531 0.268798828125 +100532 0.482818603515625 +100533 0.60369873046875 +100534 0.650421142578125 +100535 0.66400146484375 +100536 0.6414794921875 +100537 0.572540283203125 +100538 0.498138427734375 +100539 0.439453125 +100540 0.375518798828125 +100541 0.274505615234375 +100542 0.1087646484375 +100543 -0.099395751953125 +100544 -0.3182373046875 +100545 -0.5489501953125 +100546 -0.7738037109375 +100547 -0.86383056640625 +100548 -0.870391845703125 +100549 -0.86895751953125 +100550 -0.861053466796875 +100551 -0.765869140625 +100552 -0.5301513671875 +100553 -0.214691162109375 +100554 0.137359619140625 +100555 0.474822998046875 +100556 0.76239013671875 +100557 0.867462158203125 +100558 0.870361328125 +100559 0.86480712890625 +100560 0.831817626953125 +100561 0.677581787109375 +100562 0.495880126953125 +100563 0.30767822265625 +100564 0.116180419921875 +100565 -0.110748291015625 +100566 -0.381805419921875 +100567 -0.6572265625 +100568 -0.857421875 +100569 -0.870391845703125 +100570 -0.870391845703125 +100571 -0.86444091796875 +100572 -0.85723876953125 +100573 -0.790008544921875 +100574 -0.62847900390625 +100575 -0.3956298828125 +100576 -0.126708984375 +100577 0.150115966796875 +100578 0.424041748046875 +100579 0.670623779296875 +100580 0.854522705078125 +100581 0.866485595703125 +100582 0.86920166015625 +100583 0.8653564453125 +100584 0.857147216796875 +100585 0.766845703125 +100586 0.628509521484375 +100587 0.462127685546875 +100588 0.297210693359375 +100589 0.14862060546875 +100590 -0.00537109375 +100591 -0.15753173828125 +100592 -0.31304931640625 +100593 -0.48876953125 +100594 -0.6416015625 +100595 -0.751373291015625 +100596 -0.84619140625 +100597 -0.861297607421875 +100598 -0.863250732421875 +100599 -0.856597900390625 +100600 -0.7498779296875 +100601 -0.624542236328125 +100602 -0.47808837890625 +100603 -0.253387451171875 +100604 0.003692626953125 +100605 0.2257080078125 +100606 0.427154541015625 +100607 0.643218994140625 +100608 0.855926513671875 +100609 0.870361328125 +100610 0.870361328125 +100611 0.862762451171875 +100612 0.79669189453125 +100613 0.595794677734375 +100614 0.362152099609375 +100615 0.1270751953125 +100616 -0.086944580078125 +100617 -0.2784423828125 +100618 -0.484832763671875 +100619 -0.729583740234375 +100620 -0.86688232421875 +100621 -0.870391845703125 +100622 -0.86859130859375 +100623 -0.86279296875 +100624 -0.817962646484375 +100625 -0.6116943359375 +100626 -0.3128662109375 +100627 0.039398193359375 +100628 0.422821044921875 +100629 0.805145263671875 +100630 0.870361328125 +100631 0.870361328125 +100632 0.860015869140625 +100633 0.727935791015625 +100634 0.48114013671875 +100635 0.2059326171875 +100636 -0.06103515625 +100637 -0.29913330078125 +100638 -0.516204833984375 +100639 -0.7252197265625 +100640 -0.85980224609375 +100641 -0.870391845703125 +100642 -0.870391845703125 +100643 -0.858062744140625 +100644 -0.673004150390625 +100645 -0.42694091796875 +100646 -0.2100830078125 +100647 -0.0362548828125 +100648 0.10943603515625 +100649 0.23516845703125 +100650 0.373687744140625 +100651 0.517791748046875 +100652 0.602783203125 +100653 0.635711669921875 +100654 0.655181884765625 +100655 0.65948486328125 +100656 0.651275634765625 +100657 0.61846923828125 +100658 0.53753662109375 +100659 0.404144287109375 +100660 0.22186279296875 +100661 0.003997802734375 +100662 -0.22100830078125 +100663 -0.42449951171875 +100664 -0.579833984375 +100665 -0.641876220703125 +100666 -0.6177978515625 +100667 -0.575531005859375 +100668 -0.526336669921875 +100669 -0.42645263671875 +100670 -0.2581787109375 +100671 -0.068695068359375 +100672 0.09222412109375 +100673 0.232147216796875 +100674 0.3509521484375 +100675 0.410064697265625 +100676 0.372955322265625 +100677 0.2554931640625 +100678 0.10711669921875 +100679 -0.052886962890625 +100680 -0.186279296875 +100681 -0.23291015625 +100682 -0.209442138671875 +100683 -0.174163818359375 +100684 -0.126739501953125 +100685 -0.048126220703125 +100686 0.0426025390625 +100687 0.10748291015625 +100688 0.1409912109375 +100689 0.19708251953125 +100690 0.273651123046875 +100691 0.31768798828125 +100692 0.341094970703125 +100693 0.368011474609375 +100694 0.37249755859375 +100695 0.30072021484375 +100696 0.1517333984375 +100697 -0.01470947265625 +100698 -0.1883544921875 +100699 -0.372711181640625 +100700 -0.51397705078125 +100701 -0.57177734375 +100702 -0.53948974609375 +100703 -0.43511962890625 +100704 -0.2962646484375 +100705 -0.161102294921875 +100706 -0.0435791015625 +100707 0.060394287109375 +100708 0.13665771484375 +100709 0.170135498046875 +100710 0.16552734375 +100711 0.15728759765625 +100712 0.150787353515625 +100713 0.12200927734375 +100714 0.080108642578125 +100715 0.05126953125 +100716 0.062896728515625 +100717 0.09271240234375 +100718 0.092987060546875 +100719 0.07855224609375 +100720 0.06427001953125 +100721 0.0347900390625 +100722 -0.01171875 +100723 -0.056060791015625 +100724 -0.055511474609375 +100725 -0.010467529296875 +100726 0.02508544921875 +100727 0.025665283203125 +100728 0.017333984375 +100729 0.00189208984375 +100730 -0.03173828125 +100731 -0.071502685546875 +100732 -0.13543701171875 +100733 -0.219970703125 +100734 -0.300506591796875 +100735 -0.376312255859375 +100736 -0.416107177734375 +100737 -0.371124267578125 +100738 -0.242279052734375 +100739 -0.069732666015625 +100740 0.125640869140625 +100741 0.31268310546875 +100742 0.45501708984375 +100743 0.554779052734375 +100744 0.61065673828125 +100745 0.610931396484375 +100746 0.531463623046875 +100747 0.3883056640625 +100748 0.23468017578125 +100749 0.095245361328125 +100750 -0.00396728515625 +100751 -0.04852294921875 +100752 -0.055145263671875 +100753 -0.0758056640625 +100754 -0.138702392578125 +100755 -0.209197998046875 +100756 -0.289031982421875 +100757 -0.37884521484375 +100758 -0.456329345703125 +100759 -0.51641845703125 +100760 -0.519287109375 +100761 -0.458251953125 +100762 -0.384796142578125 +100763 -0.323699951171875 +100764 -0.269287109375 +100765 -0.1951904296875 +100766 -0.100006103515625 +100767 -0.01055908203125 +100768 0.1033935546875 +100769 0.24908447265625 +100770 0.373199462890625 +100771 0.45806884765625 +100772 0.511474609375 +100773 0.565399169921875 +100774 0.61138916015625 +100775 0.5897216796875 +100776 0.4906005859375 +100777 0.33148193359375 +100778 0.147796630859375 +100779 -0.01873779296875 +100780 -0.140289306640625 +100781 -0.191986083984375 +100782 -0.184295654296875 +100783 -0.161834716796875 +100784 -0.166595458984375 +100785 -0.19390869140625 +100786 -0.22442626953125 +100787 -0.279754638671875 +100788 -0.3389892578125 +100789 -0.3543701171875 +100790 -0.348175048828125 +100791 -0.32598876953125 +100792 -0.2581787109375 +100793 -0.139801025390625 +100794 0.014617919921875 +100795 0.144378662109375 +100796 0.221038818359375 +100797 0.27069091796875 +100798 0.294036865234375 +100799 0.311767578125 +100800 0.339141845703125 +100801 0.360260009765625 +100802 0.360504150390625 +100803 0.308380126953125 +100804 0.18170166015625 +100805 0.0047607421875 +100806 -0.17559814453125 +100807 -0.3143310546875 +100808 -0.36785888671875 +100809 -0.36248779296875 +100810 -0.343536376953125 +100811 -0.3018798828125 +100812 -0.231414794921875 +100813 -0.117645263671875 +100814 0.007049560546875 +100815 0.087982177734375 +100816 0.13946533203125 +100817 0.17425537109375 +100818 0.188201904296875 +100819 0.171234130859375 +100820 0.118438720703125 +100821 0.05706787109375 +100822 -0.010711669921875 +100823 -0.0914306640625 +100824 -0.162322998046875 +100825 -0.194549560546875 +100826 -0.1492919921875 +100827 -0.02166748046875 +100828 0.124053955078125 +100829 0.211151123046875 +100830 0.240447998046875 +100831 0.242218017578125 +100832 0.2257080078125 +100833 0.194366455078125 +100834 0.115509033203125 +100835 0.0128173828125 +100836 -0.053802490234375 +100837 -0.110626220703125 +100838 -0.199493408203125 +100839 -0.29437255859375 +100840 -0.33221435546875 +100841 -0.27972412109375 +100842 -0.185333251953125 +100843 -0.128204345703125 +100844 -0.115692138671875 +100845 -0.116455078125 +100846 -0.105926513671875 +100847 -0.053955078125 +100848 0.048797607421875 +100849 0.157318115234375 +100850 0.212005615234375 +100851 0.218475341796875 +100852 0.23724365234375 +100853 0.30535888671875 +100854 0.38128662109375 +100855 0.404449462890625 +100856 0.3944091796875 +100857 0.3885498046875 +100858 0.362640380859375 +100859 0.27362060546875 +100860 0.11712646484375 +100861 -0.054901123046875 +100862 -0.19085693359375 +100863 -0.28570556640625 +100864 -0.339263916015625 +100865 -0.3775634765625 +100866 -0.445709228515625 +100867 -0.535064697265625 +100868 -0.629058837890625 +100869 -0.697601318359375 +100870 -0.70391845703125 +100871 -0.6424560546875 +100872 -0.491241455078125 +100873 -0.265716552734375 +100874 -0.023712158203125 +100875 0.201751708984375 +100876 0.375823974609375 +100877 0.485076904296875 +100878 0.56884765625 +100879 0.634765625 +100880 0.63763427734375 +100881 0.5660400390625 +100882 0.4720458984375 +100883 0.40692138671875 +100884 0.3778076171875 +100885 0.376953125 +100886 0.371978759765625 +100887 0.313140869140625 +100888 0.184417724609375 +100889 0.011199951171875 +100890 -0.171051025390625 +100891 -0.33740234375 +100892 -0.47198486328125 +100893 -0.560394287109375 +100894 -0.58056640625 +100895 -0.54754638671875 +100896 -0.508575439453125 +100897 -0.459503173828125 +100898 -0.394378662109375 +100899 -0.35260009765625 +100900 -0.31170654296875 +100901 -0.197418212890625 +100902 -0.007965087890625 +100903 0.207489013671875 +100904 0.409210205078125 +100905 0.57208251953125 +100906 0.66595458984375 +100907 0.65875244140625 +100908 0.56744384765625 +100909 0.431396484375 +100910 0.29443359375 +100911 0.182464599609375 +100912 0.06365966796875 +100913 -0.075958251953125 +100914 -0.189422607421875 +100915 -0.271942138671875 +100916 -0.342529296875 +100917 -0.364166259765625 +100918 -0.327239990234375 +100919 -0.2769775390625 +100920 -0.253692626953125 +100921 -0.24365234375 +100922 -0.1983642578125 +100923 -0.116241455078125 +100924 -0.036834716796875 +100925 0.034881591796875 +100926 0.09124755859375 +100927 0.10888671875 +100928 0.125518798828125 +100929 0.15771484375 +100930 0.17828369140625 +100931 0.17108154296875 +100932 0.129974365234375 +100933 0.082427978515625 +100934 0.027679443359375 +100935 -0.065643310546875 +100936 -0.15936279296875 +100937 -0.21307373046875 +100938 -0.234649658203125 +100939 -0.2001953125 +100940 -0.119171142578125 +100941 -0.024749755859375 +100942 0.085784912109375 +100943 0.178131103515625 +100944 0.215576171875 +100945 0.211456298828125 +100946 0.17523193359375 +100947 0.128753662109375 +100948 0.1019287109375 +100949 0.0743408203125 +100950 0.04327392578125 +100951 0.038177490234375 +100952 0.076263427734375 +100953 0.14105224609375 +100954 0.186431884765625 +100955 0.188812255859375 +100956 0.1390380859375 +100957 0.041778564453125 +100958 -0.079437255859375 +100959 -0.219390869140625 +100960 -0.367828369140625 +100961 -0.494873046875 +100962 -0.556243896484375 +100963 -0.508697509765625 +100964 -0.3756103515625 +100965 -0.218902587890625 +100966 -0.063751220703125 +100967 0.091552734375 +100968 0.23602294921875 +100969 0.342987060546875 +100970 0.39520263671875 +100971 0.389373779296875 +100972 0.324249267578125 +100973 0.224090576171875 +100974 0.124267578125 +100975 0.037078857421875 +100976 -0.010101318359375 +100977 -0.019439697265625 +100978 -0.022796630859375 +100979 -0.001556396484375 +100980 0.056304931640625 +100981 0.106719970703125 +100982 0.096893310546875 +100983 0.042694091796875 +100984 -0.018035888671875 +100985 -0.07586669921875 +100986 -0.11944580078125 +100987 -0.15972900390625 +100988 -0.202606201171875 +100989 -0.24859619140625 +100990 -0.30517578125 +100991 -0.36212158203125 +100992 -0.39141845703125 +100993 -0.35528564453125 +100994 -0.249969482421875 +100995 -0.092864990234375 +100996 0.08905029296875 +100997 0.2352294921875 +100998 0.318817138671875 +100999 0.358642578125 +101000 0.347747802734375 +101001 0.28564453125 +101002 0.223175048828125 +101003 0.196746826171875 +101004 0.179840087890625 +101005 0.155548095703125 +101006 0.151214599609375 +101007 0.156951904296875 +101008 0.13177490234375 +101009 0.100799560546875 +101010 0.087127685546875 +101011 0.05487060546875 +101012 -0.009002685546875 +101013 -0.10400390625 +101014 -0.229400634765625 +101015 -0.35552978515625 +101016 -0.441925048828125 +101017 -0.473846435546875 +101018 -0.464813232421875 +101019 -0.419097900390625 +101020 -0.334320068359375 +101021 -0.227935791015625 +101022 -0.12347412109375 +101023 -0.02764892578125 +101024 0.077667236328125 +101025 0.2132568359375 +101026 0.38885498046875 +101027 0.582794189453125 +101028 0.734039306640625 +101029 0.800140380859375 +101030 0.7783203125 +101031 0.6651611328125 +101032 0.45965576171875 +101033 0.199188232421875 +101034 -0.050689697265625 +101035 -0.23297119140625 +101036 -0.33013916015625 +101037 -0.368408203125 +101038 -0.378936767578125 +101039 -0.376983642578125 +101040 -0.37969970703125 +101041 -0.391510009765625 +101042 -0.385345458984375 +101043 -0.3419189453125 +101044 -0.28289794921875 +101045 -0.251617431640625 +101046 -0.266143798828125 +101047 -0.273345947265625 +101048 -0.216796875 +101049 -0.128265380859375 +101050 -0.068145751953125 +101051 -0.0430908203125 +101052 -0.024444580078125 +101053 0.020721435546875 +101054 0.124481201171875 +101055 0.25787353515625 +101056 0.379119873046875 +101057 0.47991943359375 +101058 0.5281982421875 +101059 0.511138916015625 +101060 0.456207275390625 +101061 0.407470703125 +101062 0.383758544921875 +101063 0.35687255859375 +101064 0.31182861328125 +101065 0.250885009765625 +101066 0.1654052734375 +101067 0.035247802734375 +101068 -0.142059326171875 +101069 -0.33563232421875 +101070 -0.5345458984375 +101071 -0.72186279296875 +101072 -0.836669921875 +101073 -0.8326416015625 +101074 -0.7296142578125 +101075 -0.582550048828125 +101076 -0.440093994140625 +101077 -0.324310302734375 +101078 -0.20147705078125 +101079 -0.044647216796875 +101080 0.103973388671875 +101081 0.202392578125 +101082 0.264495849609375 +101083 0.338897705078125 +101084 0.443817138671875 +101085 0.545074462890625 +101086 0.6173095703125 +101087 0.6524658203125 +101088 0.66339111328125 +101089 0.6561279296875 +101090 0.606781005859375 +101091 0.501190185546875 +101092 0.352783203125 +101093 0.176544189453125 +101094 -0.034820556640625 +101095 -0.258209228515625 +101096 -0.44244384765625 +101097 -0.5753173828125 +101098 -0.65203857421875 +101099 -0.641632080078125 +101100 -0.562164306640625 +101101 -0.458038330078125 +101102 -0.350555419921875 +101103 -0.260528564453125 +101104 -0.192108154296875 +101105 -0.141937255859375 +101106 -0.1021728515625 +101107 -0.062896728515625 +101108 -0.011932373046875 +101109 0.062835693359375 +101110 0.148712158203125 +101111 0.241729736328125 +101112 0.34912109375 +101113 0.457305908203125 +101114 0.54388427734375 +101115 0.5728759765625 +101116 0.506591796875 +101117 0.351226806640625 +101118 0.146514892578125 +101119 -0.05523681640625 +101120 -0.21624755859375 +101121 -0.334930419921875 +101122 -0.402984619140625 +101123 -0.4412841796875 +101124 -0.49578857421875 +101125 -0.5601806640625 +101126 -0.600738525390625 +101127 -0.584228515625 +101128 -0.47930908203125 +101129 -0.27935791015625 +101130 -0.0089111328125 +101131 0.268798828125 +101132 0.482818603515625 +101133 0.60369873046875 +101134 0.650421142578125 +101135 0.66400146484375 +101136 0.6414794921875 +101137 0.572540283203125 +101138 0.498138427734375 +101139 0.439453125 +101140 0.375518798828125 +101141 0.274505615234375 +101142 0.1087646484375 +101143 -0.099395751953125 +101144 -0.3182373046875 +101145 -0.5489501953125 +101146 -0.7738037109375 +101147 -0.86383056640625 +101148 -0.870391845703125 +101149 -0.86895751953125 +101150 -0.861053466796875 +101151 -0.765869140625 +101152 -0.5301513671875 +101153 -0.214691162109375 +101154 0.137359619140625 +101155 0.474822998046875 +101156 0.76239013671875 +101157 0.867462158203125 +101158 0.870361328125 +101159 0.86480712890625 +101160 0.831817626953125 +101161 0.677581787109375 +101162 0.495880126953125 +101163 0.30767822265625 +101164 0.116180419921875 +101165 -0.110748291015625 +101166 -0.381805419921875 +101167 -0.6572265625 +101168 -0.857421875 +101169 -0.870391845703125 +101170 -0.870391845703125 +101171 -0.86444091796875 +101172 -0.85723876953125 +101173 -0.790008544921875 +101174 -0.62847900390625 +101175 -0.3956298828125 +101176 -0.126708984375 +101177 0.150115966796875 +101178 0.424041748046875 +101179 0.670623779296875 +101180 0.854522705078125 +101181 0.866485595703125 +101182 0.86920166015625 +101183 0.8653564453125 +101184 0.857147216796875 +101185 0.766845703125 +101186 0.628509521484375 +101187 0.462127685546875 +101188 0.297210693359375 +101189 0.14862060546875 +101190 -0.00537109375 +101191 -0.15753173828125 +101192 -0.31304931640625 +101193 -0.48876953125 +101194 -0.6416015625 +101195 -0.751373291015625 +101196 -0.84619140625 +101197 -0.861297607421875 +101198 -0.863250732421875 +101199 -0.856597900390625 +101200 -0.7498779296875 +101201 -0.624542236328125 +101202 -0.47808837890625 +101203 -0.253387451171875 +101204 0.003692626953125 +101205 0.2257080078125 +101206 0.427154541015625 +101207 0.643218994140625 +101208 0.855926513671875 +101209 0.870361328125 +101210 0.870361328125 +101211 0.862762451171875 +101212 0.79669189453125 +101213 0.595794677734375 +101214 0.362152099609375 +101215 0.1270751953125 +101216 -0.086944580078125 +101217 -0.2784423828125 +101218 -0.484832763671875 +101219 -0.729583740234375 +101220 -0.86688232421875 +101221 -0.870391845703125 +101222 -0.86859130859375 +101223 -0.86279296875 +101224 -0.817962646484375 +101225 -0.6116943359375 +101226 -0.3128662109375 +101227 0.039398193359375 +101228 0.422821044921875 +101229 0.805145263671875 +101230 0.870361328125 +101231 0.870361328125 +101232 0.860015869140625 +101233 0.727935791015625 +101234 0.48114013671875 +101235 0.2059326171875 +101236 -0.06103515625 +101237 -0.29913330078125 +101238 -0.516204833984375 +101239 -0.7252197265625 +101240 -0.85980224609375 +101241 -0.870391845703125 +101242 -0.870391845703125 +101243 -0.858062744140625 +101244 -0.673004150390625 +101245 -0.42694091796875 +101246 -0.2100830078125 +101247 -0.0362548828125 +101248 0.10943603515625 +101249 0.23516845703125 +101250 0.373687744140625 +101251 0.517791748046875 +101252 0.602783203125 +101253 0.635711669921875 +101254 0.655181884765625 +101255 0.65948486328125 +101256 0.651275634765625 +101257 0.61846923828125 +101258 0.53753662109375 +101259 0.404144287109375 +101260 0.22186279296875 +101261 0.003997802734375 +101262 -0.22100830078125 +101263 -0.42449951171875 +101264 -0.579833984375 +101265 -0.641876220703125 +101266 -0.6177978515625 +101267 -0.575531005859375 +101268 -0.526336669921875 +101269 -0.42645263671875 +101270 -0.2581787109375 +101271 -0.068695068359375 +101272 0.09222412109375 +101273 0.232147216796875 +101274 0.3509521484375 +101275 0.410064697265625 +101276 0.372955322265625 +101277 0.2554931640625 +101278 0.10711669921875 +101279 -0.052886962890625 +101280 -0.186279296875 +101281 -0.23291015625 +101282 -0.209442138671875 +101283 -0.174163818359375 +101284 -0.126739501953125 +101285 -0.048126220703125 +101286 0.0426025390625 +101287 0.10748291015625 +101288 0.1409912109375 +101289 0.19708251953125 +101290 0.273651123046875 +101291 0.31768798828125 +101292 0.341094970703125 +101293 0.368011474609375 +101294 0.37249755859375 +101295 0.30072021484375 +101296 0.1517333984375 +101297 -0.01470947265625 +101298 -0.1883544921875 +101299 -0.372711181640625 +101300 -0.51397705078125 +101301 -0.57177734375 +101302 -0.53948974609375 +101303 -0.43511962890625 +101304 -0.2962646484375 +101305 -0.161102294921875 +101306 -0.0435791015625 +101307 0.060394287109375 +101308 0.13665771484375 +101309 0.170135498046875 +101310 0.16552734375 +101311 0.15728759765625 +101312 0.150787353515625 +101313 0.12200927734375 +101314 0.080108642578125 +101315 0.05126953125 +101316 0.062896728515625 +101317 0.09271240234375 +101318 0.092987060546875 +101319 0.07855224609375 +101320 0.06427001953125 +101321 0.0347900390625 +101322 -0.01171875 +101323 -0.056060791015625 +101324 -0.055511474609375 +101325 -0.010467529296875 +101326 0.02508544921875 +101327 0.025665283203125 +101328 0.017333984375 +101329 0.00189208984375 +101330 -0.03173828125 +101331 -0.071502685546875 +101332 -0.13543701171875 +101333 -0.219970703125 +101334 -0.300506591796875 +101335 -0.376312255859375 +101336 -0.416107177734375 +101337 -0.371124267578125 +101338 -0.242279052734375 +101339 -0.069732666015625 +101340 0.125640869140625 +101341 0.31268310546875 +101342 0.45501708984375 +101343 0.554779052734375 +101344 0.61065673828125 +101345 0.610931396484375 +101346 0.531463623046875 +101347 0.3883056640625 +101348 0.23468017578125 +101349 0.095245361328125 +101350 -0.00396728515625 +101351 -0.04852294921875 +101352 -0.055145263671875 +101353 -0.0758056640625 +101354 -0.138702392578125 +101355 -0.209197998046875 +101356 -0.289031982421875 +101357 -0.37884521484375 +101358 -0.456329345703125 +101359 -0.51641845703125 +101360 -0.519287109375 +101361 -0.458251953125 +101362 -0.384796142578125 +101363 -0.323699951171875 +101364 -0.269287109375 +101365 -0.1951904296875 +101366 -0.100006103515625 +101367 -0.01055908203125 +101368 0.1033935546875 +101369 0.24908447265625 +101370 0.373199462890625 +101371 0.45806884765625 +101372 0.511474609375 +101373 0.565399169921875 +101374 0.61138916015625 +101375 0.5897216796875 +101376 0.4906005859375 +101377 0.33148193359375 +101378 0.147796630859375 +101379 -0.01873779296875 +101380 -0.140289306640625 +101381 -0.191986083984375 +101382 -0.184295654296875 +101383 -0.161834716796875 +101384 -0.166595458984375 +101385 -0.19390869140625 +101386 -0.22442626953125 +101387 -0.279754638671875 +101388 -0.3389892578125 +101389 -0.3543701171875 +101390 -0.348175048828125 +101391 -0.32598876953125 +101392 -0.2581787109375 +101393 -0.139801025390625 +101394 0.014617919921875 +101395 0.144378662109375 +101396 0.221038818359375 +101397 0.27069091796875 +101398 0.294036865234375 +101399 0.311767578125 +101400 0.339141845703125 +101401 0.360260009765625 +101402 0.360504150390625 +101403 0.308380126953125 +101404 0.18170166015625 +101405 0.0047607421875 +101406 -0.17559814453125 +101407 -0.3143310546875 +101408 -0.36785888671875 +101409 -0.36248779296875 +101410 -0.343536376953125 +101411 -0.3018798828125 +101412 -0.231414794921875 +101413 -0.117645263671875 +101414 0.007049560546875 +101415 0.087982177734375 +101416 0.13946533203125 +101417 0.17425537109375 +101418 0.188201904296875 +101419 0.171234130859375 +101420 0.118438720703125 +101421 0.05706787109375 +101422 -0.010711669921875 +101423 -0.0914306640625 +101424 -0.162322998046875 +101425 -0.194549560546875 +101426 -0.1492919921875 +101427 -0.02166748046875 +101428 0.124053955078125 +101429 0.211151123046875 +101430 0.240447998046875 +101431 0.242218017578125 +101432 0.2257080078125 +101433 0.194366455078125 +101434 0.115509033203125 +101435 0.0128173828125 +101436 -0.053802490234375 +101437 -0.110626220703125 +101438 -0.199493408203125 +101439 -0.29437255859375 +101440 -0.33221435546875 +101441 -0.27972412109375 +101442 -0.185333251953125 +101443 -0.128204345703125 +101444 -0.115692138671875 +101445 -0.116455078125 +101446 -0.105926513671875 +101447 -0.053955078125 +101448 0.048797607421875 +101449 0.157318115234375 +101450 0.212005615234375 +101451 0.218475341796875 +101452 0.23724365234375 +101453 0.30535888671875 +101454 0.38128662109375 +101455 0.404449462890625 +101456 0.3944091796875 +101457 0.3885498046875 +101458 0.362640380859375 +101459 0.27362060546875 +101460 0.11712646484375 +101461 -0.054901123046875 +101462 -0.19085693359375 +101463 -0.28570556640625 +101464 -0.339263916015625 +101465 -0.3775634765625 +101466 -0.445709228515625 +101467 -0.535064697265625 +101468 -0.629058837890625 +101469 -0.697601318359375 +101470 -0.70391845703125 +101471 -0.6424560546875 +101472 -0.491241455078125 +101473 -0.265716552734375 +101474 -0.023712158203125 +101475 0.201751708984375 +101476 0.375823974609375 +101477 0.485076904296875 +101478 0.56884765625 +101479 0.634765625 +101480 0.63763427734375 +101481 0.5660400390625 +101482 0.4720458984375 +101483 0.40692138671875 +101484 0.3778076171875 +101485 0.376953125 +101486 0.371978759765625 +101487 0.313140869140625 +101488 0.184417724609375 +101489 0.011199951171875 +101490 -0.171051025390625 +101491 -0.33740234375 +101492 -0.47198486328125 +101493 -0.560394287109375 +101494 -0.58056640625 +101495 -0.54754638671875 +101496 -0.508575439453125 +101497 -0.459503173828125 +101498 -0.394378662109375 +101499 -0.35260009765625 +101500 -0.31170654296875 +101501 -0.197418212890625 +101502 -0.007965087890625 +101503 0.207489013671875 +101504 0.409210205078125 +101505 0.57208251953125 +101506 0.66595458984375 +101507 0.65875244140625 +101508 0.56744384765625 +101509 0.431396484375 +101510 0.29443359375 +101511 0.182464599609375 +101512 0.06365966796875 +101513 -0.075958251953125 +101514 -0.189422607421875 +101515 -0.271942138671875 +101516 -0.342529296875 +101517 -0.364166259765625 +101518 -0.327239990234375 +101519 -0.2769775390625 +101520 -0.253692626953125 +101521 -0.24365234375 +101522 -0.1983642578125 +101523 -0.116241455078125 +101524 -0.036834716796875 +101525 0.034881591796875 +101526 0.09124755859375 +101527 0.10888671875 +101528 0.125518798828125 +101529 0.15771484375 +101530 0.17828369140625 +101531 0.17108154296875 +101532 0.129974365234375 +101533 0.082427978515625 +101534 0.027679443359375 +101535 -0.065643310546875 +101536 -0.15936279296875 +101537 -0.21307373046875 +101538 -0.234649658203125 +101539 -0.2001953125 +101540 -0.119171142578125 +101541 -0.024749755859375 +101542 0.085784912109375 +101543 0.178131103515625 +101544 0.215576171875 +101545 0.211456298828125 +101546 0.17523193359375 +101547 0.128753662109375 +101548 0.1019287109375 +101549 0.0743408203125 +101550 0.04327392578125 +101551 0.038177490234375 +101552 0.076263427734375 +101553 0.14105224609375 +101554 0.186431884765625 +101555 0.188812255859375 +101556 0.1390380859375 +101557 0.041778564453125 +101558 -0.079437255859375 +101559 -0.219390869140625 +101560 -0.367828369140625 +101561 -0.494873046875 +101562 -0.556243896484375 +101563 -0.508697509765625 +101564 -0.3756103515625 +101565 -0.218902587890625 +101566 -0.063751220703125 +101567 0.091552734375 +101568 0.23602294921875 +101569 0.342987060546875 +101570 0.39520263671875 +101571 0.389373779296875 +101572 0.324249267578125 +101573 0.224090576171875 +101574 0.124267578125 +101575 0.037078857421875 +101576 -0.010101318359375 +101577 -0.019439697265625 +101578 -0.022796630859375 +101579 -0.001556396484375 +101580 0.056304931640625 +101581 0.106719970703125 +101582 0.096893310546875 +101583 0.042694091796875 +101584 -0.018035888671875 +101585 -0.07586669921875 +101586 -0.11944580078125 +101587 -0.15972900390625 +101588 -0.202606201171875 +101589 -0.24859619140625 +101590 -0.30517578125 +101591 -0.36212158203125 +101592 -0.39141845703125 +101593 -0.35528564453125 +101594 -0.249969482421875 +101595 -0.092864990234375 +101596 0.08905029296875 +101597 0.2352294921875 +101598 0.318817138671875 +101599 0.358642578125 +101600 0.347747802734375 +101601 0.28564453125 +101602 0.223175048828125 +101603 0.196746826171875 +101604 0.179840087890625 +101605 0.155548095703125 +101606 0.151214599609375 +101607 0.156951904296875 +101608 0.13177490234375 +101609 0.100799560546875 +101610 0.087127685546875 +101611 0.05487060546875 +101612 -0.009002685546875 +101613 -0.10400390625 +101614 -0.229400634765625 +101615 -0.35552978515625 +101616 -0.441925048828125 +101617 -0.473846435546875 +101618 -0.464813232421875 +101619 -0.419097900390625 +101620 -0.334320068359375 +101621 -0.227935791015625 +101622 -0.12347412109375 +101623 -0.02764892578125 +101624 0.077667236328125 +101625 0.2132568359375 +101626 0.38885498046875 +101627 0.582794189453125 +101628 0.734039306640625 +101629 0.800140380859375 +101630 0.7783203125 +101631 0.6651611328125 +101632 0.45965576171875 +101633 0.199188232421875 +101634 -0.050689697265625 +101635 -0.23297119140625 +101636 -0.33013916015625 +101637 -0.368408203125 +101638 -0.378936767578125 +101639 -0.376983642578125 +101640 -0.37969970703125 +101641 -0.391510009765625 +101642 -0.385345458984375 +101643 -0.3419189453125 +101644 -0.28289794921875 +101645 -0.251617431640625 +101646 -0.266143798828125 +101647 -0.273345947265625 +101648 -0.216796875 +101649 -0.128265380859375 +101650 -0.068145751953125 +101651 -0.0430908203125 +101652 -0.024444580078125 +101653 0.020721435546875 +101654 0.124481201171875 +101655 0.25787353515625 +101656 0.379119873046875 +101657 0.47991943359375 +101658 0.5281982421875 +101659 0.511138916015625 +101660 0.456207275390625 +101661 0.407470703125 +101662 0.383758544921875 +101663 0.35687255859375 +101664 0.31182861328125 +101665 0.250885009765625 +101666 0.1654052734375 +101667 0.035247802734375 +101668 -0.142059326171875 +101669 -0.33563232421875 +101670 -0.5345458984375 +101671 -0.72186279296875 +101672 -0.836669921875 +101673 -0.8326416015625 +101674 -0.7296142578125 +101675 -0.582550048828125 +101676 -0.440093994140625 +101677 -0.324310302734375 +101678 -0.20147705078125 +101679 -0.044647216796875 +101680 0.103973388671875 +101681 0.202392578125 +101682 0.264495849609375 +101683 0.338897705078125 +101684 0.443817138671875 +101685 0.545074462890625 +101686 0.6173095703125 +101687 0.6524658203125 +101688 0.66339111328125 +101689 0.6561279296875 +101690 0.606781005859375 +101691 0.501190185546875 +101692 0.352783203125 +101693 0.176544189453125 +101694 -0.034820556640625 +101695 -0.258209228515625 +101696 -0.44244384765625 +101697 -0.5753173828125 +101698 -0.65203857421875 +101699 -0.641632080078125 +101700 -0.562164306640625 +101701 -0.458038330078125 +101702 -0.350555419921875 +101703 -0.260528564453125 +101704 -0.192108154296875 +101705 -0.141937255859375 +101706 -0.1021728515625 +101707 -0.062896728515625 +101708 -0.011932373046875 +101709 0.062835693359375 +101710 0.148712158203125 +101711 0.241729736328125 +101712 0.34912109375 +101713 0.457305908203125 +101714 0.54388427734375 +101715 0.5728759765625 +101716 0.506591796875 +101717 0.351226806640625 +101718 0.146514892578125 +101719 -0.05523681640625 +101720 -0.21624755859375 +101721 -0.334930419921875 +101722 -0.402984619140625 +101723 -0.4412841796875 +101724 -0.49578857421875 +101725 -0.5601806640625 +101726 -0.600738525390625 +101727 -0.584228515625 +101728 -0.47930908203125 +101729 -0.27935791015625 +101730 -0.0089111328125 +101731 0.268798828125 +101732 0.482818603515625 +101733 0.60369873046875 +101734 0.650421142578125 +101735 0.66400146484375 +101736 0.6414794921875 +101737 0.572540283203125 +101738 0.498138427734375 +101739 0.439453125 +101740 0.375518798828125 +101741 0.274505615234375 +101742 0.1087646484375 +101743 -0.099395751953125 +101744 -0.3182373046875 +101745 -0.5489501953125 +101746 -0.7738037109375 +101747 -0.86383056640625 +101748 -0.870391845703125 +101749 -0.86895751953125 +101750 -0.861053466796875 +101751 -0.765869140625 +101752 -0.5301513671875 +101753 -0.214691162109375 +101754 0.137359619140625 +101755 0.474822998046875 +101756 0.76239013671875 +101757 0.867462158203125 +101758 0.870361328125 +101759 0.86480712890625 +101760 0.831817626953125 +101761 0.677581787109375 +101762 0.495880126953125 +101763 0.30767822265625 +101764 0.116180419921875 +101765 -0.110748291015625 +101766 -0.381805419921875 +101767 -0.6572265625 +101768 -0.857421875 +101769 -0.870391845703125 +101770 -0.870391845703125 +101771 -0.86444091796875 +101772 -0.85723876953125 +101773 -0.790008544921875 +101774 -0.62847900390625 +101775 -0.3956298828125 +101776 -0.126708984375 +101777 0.150115966796875 +101778 0.424041748046875 +101779 0.670623779296875 +101780 0.854522705078125 +101781 0.866485595703125 +101782 0.86920166015625 +101783 0.8653564453125 +101784 0.857147216796875 +101785 0.766845703125 +101786 0.628509521484375 +101787 0.462127685546875 +101788 0.297210693359375 +101789 0.14862060546875 +101790 -0.00537109375 +101791 -0.15753173828125 +101792 -0.31304931640625 +101793 -0.48876953125 +101794 -0.6416015625 +101795 -0.751373291015625 +101796 -0.84619140625 +101797 -0.861297607421875 +101798 -0.863250732421875 +101799 -0.856597900390625 +101800 -0.7498779296875 +101801 -0.624542236328125 +101802 -0.47808837890625 +101803 -0.253387451171875 +101804 0.003692626953125 +101805 0.2257080078125 +101806 0.427154541015625 +101807 0.643218994140625 +101808 0.855926513671875 +101809 0.870361328125 +101810 0.870361328125 +101811 0.862762451171875 +101812 0.79669189453125 +101813 0.595794677734375 +101814 0.362152099609375 +101815 0.1270751953125 +101816 -0.086944580078125 +101817 -0.2784423828125 +101818 -0.484832763671875 +101819 -0.729583740234375 +101820 -0.86688232421875 +101821 -0.870391845703125 +101822 -0.86859130859375 +101823 -0.86279296875 +101824 -0.817962646484375 +101825 -0.6116943359375 +101826 -0.3128662109375 +101827 0.039398193359375 +101828 0.422821044921875 +101829 0.805145263671875 +101830 0.870361328125 +101831 0.870361328125 +101832 0.860015869140625 +101833 0.727935791015625 +101834 0.48114013671875 +101835 0.2059326171875 +101836 -0.06103515625 +101837 -0.29913330078125 +101838 -0.516204833984375 +101839 -0.7252197265625 +101840 -0.85980224609375 +101841 -0.870391845703125 +101842 -0.870391845703125 +101843 -0.858062744140625 +101844 -0.673004150390625 +101845 -0.42694091796875 +101846 -0.2100830078125 +101847 -0.0362548828125 +101848 0.10943603515625 +101849 0.23516845703125 +101850 0.373687744140625 +101851 0.517791748046875 +101852 0.602783203125 +101853 0.635711669921875 +101854 0.655181884765625 +101855 0.65948486328125 +101856 0.651275634765625 +101857 0.61846923828125 +101858 0.53753662109375 +101859 0.404144287109375 +101860 0.22186279296875 +101861 0.003997802734375 +101862 -0.22100830078125 +101863 -0.42449951171875 +101864 -0.579833984375 +101865 -0.641876220703125 +101866 -0.6177978515625 +101867 -0.575531005859375 +101868 -0.526336669921875 +101869 -0.42645263671875 +101870 -0.2581787109375 +101871 -0.068695068359375 +101872 0.09222412109375 +101873 0.232147216796875 +101874 0.3509521484375 +101875 0.410064697265625 +101876 0.372955322265625 +101877 0.2554931640625 +101878 0.10711669921875 +101879 -0.052886962890625 +101880 -0.186279296875 +101881 -0.23291015625 +101882 -0.209442138671875 +101883 -0.174163818359375 +101884 -0.126739501953125 +101885 -0.048126220703125 +101886 0.0426025390625 +101887 0.10748291015625 +101888 0.1409912109375 +101889 0.19708251953125 +101890 0.273651123046875 +101891 0.31768798828125 +101892 0.341094970703125 +101893 0.368011474609375 +101894 0.37249755859375 +101895 0.30072021484375 +101896 0.1517333984375 +101897 -0.01470947265625 +101898 -0.1883544921875 +101899 -0.372711181640625 +101900 -0.51397705078125 +101901 -0.57177734375 +101902 -0.53948974609375 +101903 -0.43511962890625 +101904 -0.2962646484375 +101905 -0.161102294921875 +101906 -0.0435791015625 +101907 0.060394287109375 +101908 0.13665771484375 +101909 0.170135498046875 +101910 0.16552734375 +101911 0.15728759765625 +101912 0.150787353515625 +101913 0.12200927734375 +101914 0.080108642578125 +101915 0.05126953125 +101916 0.062896728515625 +101917 0.09271240234375 +101918 0.092987060546875 +101919 0.07855224609375 +101920 0.06427001953125 +101921 0.0347900390625 +101922 -0.01171875 +101923 -0.056060791015625 +101924 -0.055511474609375 +101925 -0.010467529296875 +101926 0.02508544921875 +101927 0.025665283203125 +101928 0.017333984375 +101929 0.00189208984375 +101930 -0.03173828125 +101931 -0.071502685546875 +101932 -0.13543701171875 +101933 -0.219970703125 +101934 -0.300506591796875 +101935 -0.376312255859375 +101936 -0.416107177734375 +101937 -0.371124267578125 +101938 -0.242279052734375 +101939 -0.069732666015625 +101940 0.125640869140625 +101941 0.31268310546875 +101942 0.45501708984375 +101943 0.554779052734375 +101944 0.61065673828125 +101945 0.610931396484375 +101946 0.531463623046875 +101947 0.3883056640625 +101948 0.23468017578125 +101949 0.095245361328125 +101950 -0.00396728515625 +101951 -0.04852294921875 +101952 -0.055145263671875 +101953 -0.0758056640625 +101954 -0.138702392578125 +101955 -0.209197998046875 +101956 -0.289031982421875 +101957 -0.37884521484375 +101958 -0.456329345703125 +101959 -0.51641845703125 +101960 -0.519287109375 +101961 -0.458251953125 +101962 -0.384796142578125 +101963 -0.323699951171875 +101964 -0.269287109375 +101965 -0.1951904296875 +101966 -0.100006103515625 +101967 -0.01055908203125 +101968 0.1033935546875 +101969 0.24908447265625 +101970 0.373199462890625 +101971 0.45806884765625 +101972 0.511474609375 +101973 0.565399169921875 +101974 0.61138916015625 +101975 0.5897216796875 +101976 0.4906005859375 +101977 0.33148193359375 +101978 0.147796630859375 +101979 -0.01873779296875 +101980 -0.140289306640625 +101981 -0.191986083984375 +101982 -0.184295654296875 +101983 -0.161834716796875 +101984 -0.166595458984375 +101985 -0.19390869140625 +101986 -0.22442626953125 +101987 -0.279754638671875 +101988 -0.3389892578125 +101989 -0.3543701171875 +101990 -0.348175048828125 +101991 -0.32598876953125 +101992 -0.2581787109375 +101993 -0.139801025390625 +101994 0.014617919921875 +101995 0.144378662109375 +101996 0.221038818359375 +101997 0.27069091796875 +101998 0.294036865234375 +101999 0.311767578125 +102000 0.339141845703125 +102001 0.360260009765625 +102002 0.360504150390625 +102003 0.308380126953125 +102004 0.18170166015625 +102005 0.0047607421875 +102006 -0.17559814453125 +102007 -0.3143310546875 +102008 -0.36785888671875 +102009 -0.36248779296875 +102010 -0.343536376953125 +102011 -0.3018798828125 +102012 -0.231414794921875 +102013 -0.117645263671875 +102014 0.007049560546875 +102015 0.087982177734375 +102016 0.13946533203125 +102017 0.17425537109375 +102018 0.188201904296875 +102019 0.171234130859375 +102020 0.118438720703125 +102021 0.05706787109375 +102022 -0.010711669921875 +102023 -0.0914306640625 +102024 -0.162322998046875 +102025 -0.194549560546875 +102026 -0.1492919921875 +102027 -0.02166748046875 +102028 0.124053955078125 +102029 0.211151123046875 +102030 0.240447998046875 +102031 0.242218017578125 +102032 0.2257080078125 +102033 0.194366455078125 +102034 0.115509033203125 +102035 0.0128173828125 +102036 -0.053802490234375 +102037 -0.110626220703125 +102038 -0.199493408203125 +102039 -0.29437255859375 +102040 -0.33221435546875 +102041 -0.27972412109375 +102042 -0.185333251953125 +102043 -0.128204345703125 +102044 -0.115692138671875 +102045 -0.116455078125 +102046 -0.105926513671875 +102047 -0.053955078125 +102048 0.048797607421875 +102049 0.157318115234375 +102050 0.212005615234375 +102051 0.218475341796875 +102052 0.23724365234375 +102053 0.30535888671875 +102054 0.38128662109375 +102055 0.404449462890625 +102056 0.3944091796875 +102057 0.3885498046875 +102058 0.362640380859375 +102059 0.27362060546875 +102060 0.11712646484375 +102061 -0.054901123046875 +102062 -0.19085693359375 +102063 -0.28570556640625 +102064 -0.339263916015625 +102065 -0.3775634765625 +102066 -0.445709228515625 +102067 -0.535064697265625 +102068 -0.629058837890625 +102069 -0.697601318359375 +102070 -0.70391845703125 +102071 -0.6424560546875 +102072 -0.491241455078125 +102073 -0.265716552734375 +102074 -0.023712158203125 +102075 0.201751708984375 +102076 0.375823974609375 +102077 0.485076904296875 +102078 0.56884765625 +102079 0.634765625 +102080 0.63763427734375 +102081 0.5660400390625 +102082 0.4720458984375 +102083 0.40692138671875 +102084 0.3778076171875 +102085 0.376953125 +102086 0.371978759765625 +102087 0.313140869140625 +102088 0.184417724609375 +102089 0.011199951171875 +102090 -0.171051025390625 +102091 -0.33740234375 +102092 -0.47198486328125 +102093 -0.560394287109375 +102094 -0.58056640625 +102095 -0.54754638671875 +102096 -0.508575439453125 +102097 -0.459503173828125 +102098 -0.394378662109375 +102099 -0.35260009765625 +102100 -0.31170654296875 +102101 -0.197418212890625 +102102 -0.007965087890625 +102103 0.207489013671875 +102104 0.409210205078125 +102105 0.57208251953125 +102106 0.66595458984375 +102107 0.65875244140625 +102108 0.56744384765625 +102109 0.431396484375 +102110 0.29443359375 +102111 0.182464599609375 +102112 0.06365966796875 +102113 -0.075958251953125 +102114 -0.189422607421875 +102115 -0.271942138671875 +102116 -0.342529296875 +102117 -0.364166259765625 +102118 -0.327239990234375 +102119 -0.2769775390625 +102120 -0.253692626953125 +102121 -0.24365234375 +102122 -0.1983642578125 +102123 -0.116241455078125 +102124 -0.036834716796875 +102125 0.034881591796875 +102126 0.09124755859375 +102127 0.10888671875 +102128 0.125518798828125 +102129 0.15771484375 +102130 0.17828369140625 +102131 0.17108154296875 +102132 0.129974365234375 +102133 0.082427978515625 +102134 0.027679443359375 +102135 -0.065643310546875 +102136 -0.15936279296875 +102137 -0.21307373046875 +102138 -0.234649658203125 +102139 -0.2001953125 +102140 -0.119171142578125 +102141 -0.024749755859375 +102142 0.085784912109375 +102143 0.178131103515625 +102144 0.215576171875 +102145 0.211456298828125 +102146 0.17523193359375 +102147 0.128753662109375 +102148 0.1019287109375 +102149 0.0743408203125 +102150 0.04327392578125 +102151 0.038177490234375 +102152 0.076263427734375 +102153 0.14105224609375 +102154 0.186431884765625 +102155 0.188812255859375 +102156 0.1390380859375 +102157 0.041778564453125 +102158 -0.079437255859375 +102159 -0.219390869140625 +102160 -0.367828369140625 +102161 -0.494873046875 +102162 -0.556243896484375 +102163 -0.508697509765625 +102164 -0.3756103515625 +102165 -0.218902587890625 +102166 -0.063751220703125 +102167 0.091552734375 +102168 0.23602294921875 +102169 0.342987060546875 +102170 0.39520263671875 +102171 0.389373779296875 +102172 0.324249267578125 +102173 0.224090576171875 +102174 0.124267578125 +102175 0.037078857421875 +102176 -0.010101318359375 +102177 -0.019439697265625 +102178 -0.022796630859375 +102179 -0.001556396484375 +102180 0.056304931640625 +102181 0.106719970703125 +102182 0.096893310546875 +102183 0.042694091796875 +102184 -0.018035888671875 +102185 -0.07586669921875 +102186 -0.11944580078125 +102187 -0.15972900390625 +102188 -0.202606201171875 +102189 -0.24859619140625 +102190 -0.30517578125 +102191 -0.36212158203125 +102192 -0.39141845703125 +102193 -0.35528564453125 +102194 -0.249969482421875 +102195 -0.092864990234375 +102196 0.08905029296875 +102197 0.2352294921875 +102198 0.318817138671875 +102199 0.358642578125 +102200 0.347747802734375 +102201 0.28564453125 +102202 0.223175048828125 +102203 0.196746826171875 +102204 0.179840087890625 +102205 0.155548095703125 +102206 0.151214599609375 +102207 0.156951904296875 +102208 0.13177490234375 +102209 0.100799560546875 +102210 0.087127685546875 +102211 0.05487060546875 +102212 -0.009002685546875 +102213 -0.10400390625 +102214 -0.229400634765625 +102215 -0.35552978515625 +102216 -0.441925048828125 +102217 -0.473846435546875 +102218 -0.464813232421875 +102219 -0.419097900390625 +102220 -0.334320068359375 +102221 -0.227935791015625 +102222 -0.12347412109375 +102223 -0.02764892578125 +102224 0.077667236328125 +102225 0.2132568359375 +102226 0.38885498046875 +102227 0.582794189453125 +102228 0.734039306640625 +102229 0.800140380859375 +102230 0.7783203125 +102231 0.6651611328125 +102232 0.45965576171875 +102233 0.199188232421875 +102234 -0.050689697265625 +102235 -0.23297119140625 +102236 -0.33013916015625 +102237 -0.368408203125 +102238 -0.378936767578125 +102239 -0.376983642578125 +102240 -0.37969970703125 +102241 -0.391510009765625 +102242 -0.385345458984375 +102243 -0.3419189453125 +102244 -0.28289794921875 +102245 -0.251617431640625 +102246 -0.266143798828125 +102247 -0.273345947265625 +102248 -0.216796875 +102249 -0.128265380859375 +102250 -0.068145751953125 +102251 -0.0430908203125 +102252 -0.024444580078125 +102253 0.020721435546875 +102254 0.124481201171875 +102255 0.25787353515625 +102256 0.379119873046875 +102257 0.47991943359375 +102258 0.5281982421875 +102259 0.511138916015625 +102260 0.456207275390625 +102261 0.407470703125 +102262 0.383758544921875 +102263 0.35687255859375 +102264 0.31182861328125 +102265 0.250885009765625 +102266 0.1654052734375 +102267 0.035247802734375 +102268 -0.142059326171875 +102269 -0.33563232421875 +102270 -0.5345458984375 +102271 -0.72186279296875 +102272 -0.836669921875 +102273 -0.8326416015625 +102274 -0.7296142578125 +102275 -0.582550048828125 +102276 -0.440093994140625 +102277 -0.324310302734375 +102278 -0.20147705078125 +102279 -0.044647216796875 +102280 0.103973388671875 +102281 0.202392578125 +102282 0.264495849609375 +102283 0.338897705078125 +102284 0.443817138671875 +102285 0.545074462890625 +102286 0.6173095703125 +102287 0.6524658203125 +102288 0.66339111328125 +102289 0.6561279296875 +102290 0.606781005859375 +102291 0.501190185546875 +102292 0.352783203125 +102293 0.176544189453125 +102294 -0.034820556640625 +102295 -0.258209228515625 +102296 -0.44244384765625 +102297 -0.5753173828125 +102298 -0.65203857421875 +102299 -0.641632080078125 +102300 -0.562164306640625 +102301 -0.458038330078125 +102302 -0.350555419921875 +102303 -0.260528564453125 +102304 -0.192108154296875 +102305 -0.141937255859375 +102306 -0.1021728515625 +102307 -0.062896728515625 +102308 -0.011932373046875 +102309 0.062835693359375 +102310 0.148712158203125 +102311 0.241729736328125 +102312 0.34912109375 +102313 0.457305908203125 +102314 0.54388427734375 +102315 0.5728759765625 +102316 0.506591796875 +102317 0.351226806640625 +102318 0.146514892578125 +102319 -0.05523681640625 +102320 -0.21624755859375 +102321 -0.334930419921875 +102322 -0.402984619140625 +102323 -0.4412841796875 +102324 -0.49578857421875 +102325 -0.5601806640625 +102326 -0.600738525390625 +102327 -0.584228515625 +102328 -0.47930908203125 +102329 -0.27935791015625 +102330 -0.0089111328125 +102331 0.268798828125 +102332 0.482818603515625 +102333 0.60369873046875 +102334 0.650421142578125 +102335 0.66400146484375 +102336 0.6414794921875 +102337 0.572540283203125 +102338 0.498138427734375 +102339 0.439453125 +102340 0.375518798828125 +102341 0.274505615234375 +102342 0.1087646484375 +102343 -0.099395751953125 +102344 -0.3182373046875 +102345 -0.5489501953125 +102346 -0.7738037109375 +102347 -0.86383056640625 +102348 -0.870391845703125 +102349 -0.86895751953125 +102350 -0.861053466796875 +102351 -0.765869140625 +102352 -0.5301513671875 +102353 -0.214691162109375 +102354 0.137359619140625 +102355 0.474822998046875 +102356 0.76239013671875 +102357 0.867462158203125 +102358 0.870361328125 +102359 0.86480712890625 +102360 0.831817626953125 +102361 0.677581787109375 +102362 0.495880126953125 +102363 0.30767822265625 +102364 0.116180419921875 +102365 -0.110748291015625 +102366 -0.381805419921875 +102367 -0.6572265625 +102368 -0.857421875 +102369 -0.870391845703125 +102370 -0.870391845703125 +102371 -0.86444091796875 +102372 -0.85723876953125 +102373 -0.790008544921875 +102374 -0.62847900390625 +102375 -0.3956298828125 +102376 -0.126708984375 +102377 0.150115966796875 +102378 0.424041748046875 +102379 0.670623779296875 +102380 0.854522705078125 +102381 0.866485595703125 +102382 0.86920166015625 +102383 0.8653564453125 +102384 0.857147216796875 +102385 0.766845703125 +102386 0.628509521484375 +102387 0.462127685546875 +102388 0.297210693359375 +102389 0.14862060546875 +102390 -0.00537109375 +102391 -0.15753173828125 +102392 -0.31304931640625 +102393 -0.48876953125 +102394 -0.6416015625 +102395 -0.751373291015625 +102396 -0.84619140625 +102397 -0.861297607421875 +102398 -0.863250732421875 +102399 -0.856597900390625 diff --git a/tests/circuitpython/audiofilter_filter_stereo.py b/tests/circuitpython/audiofilter_filter_stereo.py new file mode 100644 index 00000000000..f260286f931 --- /dev/null +++ b/tests/circuitpython/audiofilter_filter_stereo.py @@ -0,0 +1,24 @@ +from audiofilters import Filter +from audiofilterhelper import synth_test, sine8k +from audiomixer import Mixer +from synthio import LFO + + +@synth_test +def stereo_filter(): + args = { + "bits_per_sample": 16, + "samples_signed": True, + "channel_count": 2, + } + effect = Filter(**args) + mixer = Mixer(**args) + mixer.voice[0].panning = LFO() + effect.play(mixer) + yield effect, [] + + mixer.play(sine8k, loop=True) + yield 40 + + mixer.stop_voice() + yield 20 diff --git a/tests/circuitpython/audiofilter_filter_stereo.py.exp b/tests/circuitpython/audiofilter_filter_stereo.py.exp new file mode 100644 index 00000000000..960c143a1ef --- /dev/null +++ b/tests/circuitpython/audiofilter_filter_stereo.py.exp @@ -0,0 +1,15360 @@ +0 0.0 +1 0.0 +2 0.0 +3 0.0 +4 0.0 +5 0.0 +6 0.0 +7 0.0 +8 0.0 +9 0.0 +10 0.0 +11 0.0 +12 0.0 +13 0.0 +14 0.0 +15 0.0 +16 0.0 +17 0.0 +18 0.0 +19 0.0 +20 0.0 +21 0.0 +22 0.0 +23 0.0 +24 0.0 +25 0.0 +26 0.0 +27 0.0 +28 0.0 +29 0.0 +30 0.0 +31 0.0 +32 0.0 +33 0.0 +34 0.0 +35 0.0 +36 0.0 +37 0.0 +38 0.0 +39 0.0 +40 0.0 +41 0.0 +42 0.0 +43 0.0 +44 0.0 +45 0.0 +46 0.0 +47 0.0 +48 0.0 +49 0.0 +50 0.0 +51 0.0 +52 0.0 +53 0.0 +54 0.0 +55 0.0 +56 0.0 +57 0.0 +58 0.0 +59 0.0 +60 0.0 +61 0.0 +62 0.0 +63 0.0 +64 0.0 +65 0.0 +66 0.0 +67 0.0 +68 0.0 +69 0.0 +70 0.0 +71 0.0 +72 0.0 +73 0.0 +74 0.0 +75 0.0 +76 0.0 +77 0.0 +78 0.0 +79 0.0 +80 0.0 +81 0.0 +82 0.0 +83 0.0 +84 0.0 +85 0.0 +86 0.0 +87 0.0 +88 0.0 +89 0.0 +90 0.0 +91 0.0 +92 0.0 +93 0.0 +94 0.0 +95 0.0 +96 0.0 +97 0.0 +98 0.0 +99 0.0 +100 0.0 +101 0.0 +102 0.0 +103 0.0 +104 0.0 +105 0.0 +106 0.0 +107 0.0 +108 0.0 +109 0.0 +110 0.0 +111 0.0 +112 0.0 +113 0.0 +114 0.0 +115 0.0 +116 0.0 +117 0.0 +118 0.0 +119 0.0 +120 0.0 +121 0.0 +122 0.0 +123 0.0 +124 0.0 +125 0.0 +126 0.0 +127 0.0 +128 0.0 +129 0.0 +130 0.0 +131 0.0 +132 0.0 +133 0.0 +134 0.0 +135 0.0 +136 0.0 +137 0.0 +138 0.0 +139 0.0 +140 0.0 +141 0.0 +142 0.0 +143 0.0 +144 0.0 +145 0.0 +146 0.0 +147 0.0 +148 0.0 +149 0.0 +150 0.0 +151 0.0 +152 0.0 +153 0.0 +154 0.0 +155 0.0 +156 0.0 +157 0.0 +158 0.0 +159 0.0 +160 0.0 +161 0.0 +162 0.0 +163 0.0 +164 0.0 +165 0.0 +166 0.0 +167 0.0 +168 0.0 +169 0.0 +170 0.0 +171 0.0 +172 0.0 +173 0.0 +174 0.0 +175 0.0 +176 0.0 +177 0.0 +178 0.0 +179 0.0 +180 0.0 +181 0.0 +182 0.0 +183 0.0 +184 0.0 +185 0.0 +186 0.0 +187 0.0 +188 0.0 +189 0.0 +190 0.0 +191 0.0 +192 0.0 +193 0.0 +194 0.0 +195 0.0 +196 0.0 +197 0.0 +198 0.0 +199 0.0 +200 0.0 +201 0.0 +202 0.0 +203 0.0 +204 0.0 +205 0.0 +206 0.0 +207 0.0 +208 0.0 +209 0.0 +210 0.0 +211 0.0 +212 0.0 +213 0.0 +214 0.0 +215 0.0 +216 0.0 +217 0.0 +218 0.0 +219 0.0 +220 0.0 +221 0.0 +222 0.0 +223 0.0 +224 0.0 +225 0.0 +226 0.0 +227 0.0 +228 0.0 +229 0.0 +230 0.0 +231 0.0 +232 0.0 +233 0.0 +234 0.0 +235 0.0 +236 0.0 +237 0.0 +238 0.0 +239 0.0 +240 0.0 +241 0.0 +242 0.0 +243 0.0 +244 0.0 +245 0.0 +246 0.0 +247 0.0 +248 0.0 +249 0.0 +250 0.0 +251 0.0 +252 0.0 +253 0.0 +254 0.0 +255 0.0 +256 0.0 +257 0.0 +258 0.0101318359375 +259 0.010467529296875 +260 0.020263671875 +261 0.02093505859375 +262 0.0303955078125 +263 0.031402587890625 +264 0.04052734375 +265 0.0418701171875 +266 0.050628662109375 +267 0.05230712890625 +268 0.060760498046875 +269 0.062774658203125 +270 0.07086181640625 +271 0.073211669921875 +272 0.080963134765625 +273 0.083648681640625 +274 0.091064453125 +275 0.094085693359375 +276 0.101165771484375 +277 0.104522705078125 +278 0.111236572265625 +279 0.11492919921875 +280 0.12127685546875 +281 0.12530517578125 +282 0.131317138671875 +283 0.13568115234375 +284 0.141357421875 +285 0.14605712890625 +286 0.1513671875 +287 0.156402587890625 +288 0.161407470703125 +289 0.166748046875 +290 0.17138671875 +291 0.17706298828125 +292 0.18133544921875 +293 0.187347412109375 +294 0.1912841796875 +295 0.1976318359375 +296 0.201202392578125 +297 0.2078857421875 +298 0.21112060546875 +299 0.218109130859375 +300 0.22100830078125 +301 0.22833251953125 +302 0.230865478515625 +303 0.238525390625 +304 0.240692138671875 +305 0.2486572265625 +306 0.25048828125 +307 0.2587890625 +308 0.26025390625 +309 0.268890380859375 +310 0.27001953125 +311 0.278961181640625 +312 0.27972412109375 +313 0.28900146484375 +314 0.2894287109375 +315 0.29901123046875 +316 0.299072265625 +317 0.308990478515625 +318 0.3087158203125 +319 0.318939208984375 +320 0.31829833984375 +321 0.328826904296875 +322 0.327850341796875 +323 0.338714599609375 +324 0.337371826171875 +325 0.348541259765625 +326 0.34686279296875 +327 0.35833740234375 +328 0.356292724609375 +329 0.36810302734375 +330 0.365692138671875 +331 0.3778076171875 +332 0.37506103515625 +333 0.387481689453125 +334 0.3843994140625 +335 0.397125244140625 +336 0.3936767578125 +337 0.406707763671875 +338 0.402923583984375 +339 0.416259765625 +340 0.412109375 +341 0.425750732421875 +342 0.4212646484375 +343 0.435211181640625 +344 0.43035888671875 +345 0.444610595703125 +346 0.43939208984375 +347 0.453948974609375 +348 0.44842529296875 +349 0.4632568359375 +350 0.4573974609375 +351 0.4725341796875 +352 0.466278076171875 +353 0.481719970703125 +354 0.47515869140625 +355 0.490875244140625 +356 0.48394775390625 +357 0.499969482421875 +358 0.492706298828125 +359 0.509002685546875 +360 0.50140380859375 +361 0.51800537109375 +362 0.510040283203125 +363 0.52691650390625 +364 0.51861572265625 +365 0.535797119140625 +366 0.52716064453125 +367 0.54461669921875 +368 0.535614013671875 +369 0.5533447265625 +370 0.544036865234375 +371 0.562042236328125 +372 0.552398681640625 +373 0.5706787109375 +374 0.560699462890625 +375 0.579254150390625 +376 0.56890869140625 +377 0.587738037109375 +378 0.57708740234375 +379 0.59619140625 +380 0.585174560546875 +381 0.60455322265625 +382 0.59326171875 +383 0.612884521484375 +384 0.601226806640625 +385 0.621124267578125 +386 0.609100341796875 +387 0.6292724609375 +388 0.616973876953125 +389 0.63739013671875 +390 0.624725341796875 +391 0.645416259765625 +392 0.6324462890625 +393 0.65338134765625 +394 0.640106201171875 +395 0.661285400390625 +396 0.647674560546875 +397 0.669097900390625 +398 0.6551513671875 +399 0.676849365234375 +400 0.662567138671875 +401 0.68450927734375 +402 0.669921875 +403 0.692108154296875 +404 0.677215576171875 +405 0.699615478515625 +406 0.684417724609375 +407 0.707061767578125 +408 0.691558837890625 +409 0.714447021484375 +410 0.698577880859375 +411 0.721710205078125 +412 0.705596923828125 +413 0.72894287109375 +414 0.71246337890625 +415 0.736053466796875 +416 0.71929931640625 +417 0.74310302734375 +418 0.726043701171875 +419 0.75006103515625 +420 0.732696533203125 +421 0.7569580078125 +422 0.739288330078125 +423 0.763763427734375 +424 0.74578857421875 +425 0.770477294921875 +426 0.752197265625 +427 0.777099609375 +428 0.758544921875 +429 0.783660888671875 +430 0.76483154296875 +431 0.790130615234375 +432 0.770965576171875 +433 0.796478271484375 +434 0.77703857421875 +435 0.802764892578125 +436 0.7830810546875 +437 0.808990478515625 +438 0.788970947265625 +439 0.815093994140625 +440 0.7947998046875 +441 0.82110595703125 +442 0.800537109375 +443 0.8270263671875 +444 0.80621337890625 +445 0.8328857421875 +446 0.811767578125 +447 0.838623046875 +448 0.8172607421875 +449 0.84429931640625 +450 0.8226318359375 +451 0.849853515625 +452 0.827911376953125 +453 0.855316162109375 +454 0.8331298828125 +455 0.860687255859375 +456 0.8382568359375 +457 0.865997314453125 +458 0.843292236328125 +459 0.871185302734375 +460 0.848175048828125 +461 0.876251220703125 +462 0.85302734375 +463 0.881256103515625 +464 0.8577880859375 +465 0.88616943359375 +466 0.8624267578125 +467 0.890960693359375 +468 0.866973876953125 +469 0.895660400390625 +470 0.871429443359375 +471 0.9002685546875 +472 0.87579345703125 +473 0.90478515625 +474 0.88006591796875 +475 0.9091796875 +476 0.884246826171875 +477 0.91351318359375 +478 0.888336181640625 +479 0.917724609375 +480 0.89227294921875 +481 0.92181396484375 +482 0.89617919921875 +483 0.92584228515625 +484 0.899932861328125 +485 0.929718017578125 +486 0.90362548828125 +487 0.93353271484375 +488 0.907196044921875 +489 0.937225341796875 +490 0.91070556640625 +491 0.940826416015625 +492 0.914093017578125 +493 0.9443359375 +494 0.9173583984375 +495 0.947723388671875 +496 0.920562744140625 +497 0.951019287109375 +498 0.92364501953125 +499 0.954193115234375 +500 0.926605224609375 +501 0.957275390625 +502 0.929473876953125 +503 0.960235595703125 +504 0.9322509765625 +505 0.963104248046875 +506 0.9349365234375 +507 0.96588134765625 +508 0.9375 +509 0.968536376953125 +510 0.94000244140625 +511 0.971099853515625 +512 0.911224365234375 +513 0.973541259765625 +514 0.91339111328125 +515 0.975860595703125 +516 0.91546630859375 +517 0.97808837890625 +518 0.91748046875 +519 0.980224609375 +520 0.91937255859375 +521 0.98223876953125 +522 0.921173095703125 +523 0.984161376953125 +524 0.9228515625 +525 0.9859619140625 +526 0.924407958984375 +527 0.987640380859375 +528 0.9259033203125 +529 0.989227294921875 +530 0.927276611328125 +531 0.990692138671875 +532 0.928558349609375 +533 0.9920654296875 +534 0.929718017578125 +535 0.993316650390625 +536 0.930816650390625 +537 0.994476318359375 +538 0.931793212890625 +539 0.995513916015625 +540 0.93267822265625 +541 0.9964599609375 +542 0.933441162109375 +543 0.997283935546875 +544 0.934112548828125 +545 0.99798583984375 +546 0.934661865234375 +547 0.99859619140625 +548 0.93511962890625 +549 0.999114990234375 +550 0.93548583984375 +551 0.999481201171875 +552 0.93572998046875 +553 0.999755859375 +554 0.9359130859375 +555 0.99993896484375 +556 0.93597412109375 +557 0.999969482421875 +558 0.9359130859375 +559 0.99993896484375 +560 0.93572998046875 +561 0.999755859375 +562 0.93548583984375 +563 0.999481201171875 +564 0.93511962890625 +565 0.999114990234375 +566 0.934661865234375 +567 0.99859619140625 +568 0.934112548828125 +569 0.99798583984375 +570 0.933441162109375 +571 0.997283935546875 +572 0.93267822265625 +573 0.9964599609375 +574 0.931793212890625 +575 0.995513916015625 +576 0.930816650390625 +577 0.994476318359375 +578 0.929718017578125 +579 0.993316650390625 +580 0.928558349609375 +581 0.9920654296875 +582 0.927276611328125 +583 0.990692138671875 +584 0.9259033203125 +585 0.989227294921875 +586 0.924407958984375 +587 0.987640380859375 +588 0.9228515625 +589 0.9859619140625 +590 0.921173095703125 +591 0.984161376953125 +592 0.91937255859375 +593 0.98223876953125 +594 0.91748046875 +595 0.980224609375 +596 0.91546630859375 +597 0.97808837890625 +598 0.91339111328125 +599 0.975860595703125 +600 0.911224365234375 +601 0.973541259765625 +602 0.908935546875 +603 0.971099853515625 +604 0.906524658203125 +605 0.968536376953125 +606 0.904052734375 +607 0.96588134765625 +608 0.901458740234375 +609 0.963104248046875 +610 0.898773193359375 +611 0.960235595703125 +612 0.89599609375 +613 0.957275390625 +614 0.893096923828125 +615 0.954193115234375 +616 0.89013671875 +617 0.951019287109375 +618 0.887054443359375 +619 0.947723388671875 +620 0.883880615234375 +621 0.9443359375 +622 0.880615234375 +623 0.940826416015625 +624 0.877227783203125 +625 0.937225341796875 +626 0.873779296875 +627 0.93353271484375 +628 0.870208740234375 +629 0.929718017578125 +630 0.8665771484375 +631 0.92584228515625 +632 0.86279296875 +633 0.92181396484375 +634 0.858978271484375 +635 0.917724609375 +636 0.85504150390625 +637 0.91351318359375 +638 0.850982666015625 +639 0.9091796875 +640 0.84686279296875 +641 0.90478515625 +642 0.8426513671875 +643 0.9002685546875 +644 0.83831787109375 +645 0.895660400390625 +646 0.83392333984375 +647 0.890960693359375 +648 0.829437255859375 +649 0.88616943359375 +650 0.8248291015625 +651 0.881256103515625 +652 0.820159912109375 +653 0.876251220703125 +654 0.8154296875 +655 0.871185302734375 +656 0.810546875 +657 0.865997314453125 +658 0.80560302734375 +659 0.860687255859375 +660 0.800567626953125 +661 0.855316162109375 +662 0.795440673828125 +663 0.849853515625 +664 0.790252685546875 +665 0.84429931640625 +666 0.784942626953125 +667 0.838623046875 +668 0.779571533203125 +669 0.8328857421875 +670 0.774078369140625 +671 0.8270263671875 +672 0.7685546875 +673 0.82110595703125 +674 0.762908935546875 +675 0.815093994140625 +676 0.7572021484375 +677 0.808990478515625 +678 0.751373291015625 +679 0.802764892578125 +680 0.7454833984375 +681 0.796478271484375 +682 0.73956298828125 +683 0.790130615234375 +684 0.733489990234375 +685 0.783660888671875 +686 0.72735595703125 +687 0.777099609375 +688 0.721160888671875 +689 0.770477294921875 +690 0.714874267578125 +691 0.763763427734375 +692 0.70849609375 +693 0.7569580078125 +694 0.702056884765625 +695 0.75006103515625 +696 0.695526123046875 +697 0.74310302734375 +698 0.688934326171875 +699 0.736053466796875 +700 0.682281494140625 +701 0.72894287109375 +702 0.675506591796875 +703 0.721710205078125 +704 0.668701171875 +705 0.714447021484375 +706 0.66180419921875 +707 0.707061767578125 +708 0.654815673828125 +709 0.699615478515625 +710 0.647796630859375 +711 0.692108154296875 +712 0.64068603515625 +713 0.68450927734375 +714 0.633514404296875 +715 0.676849365234375 +716 0.626251220703125 +717 0.669097900390625 +718 0.61895751953125 +719 0.661285400390625 +720 0.611541748046875 +721 0.65338134765625 +722 0.604095458984375 +723 0.645416259765625 +724 0.596588134765625 +725 0.63739013671875 +726 0.5889892578125 +727 0.6292724609375 +728 0.58135986328125 +729 0.621124267578125 +730 0.573638916015625 +731 0.612884521484375 +732 0.56585693359375 +733 0.60455322265625 +734 0.558013916015625 +735 0.59619140625 +736 0.55010986328125 +737 0.587738037109375 +738 0.54217529296875 +739 0.579254150390625 +740 0.534149169921875 +741 0.5706787109375 +742 0.52606201171875 +743 0.562042236328125 +744 0.517913818359375 +745 0.5533447265625 +746 0.509735107421875 +747 0.54461669921875 +748 0.501495361328125 +749 0.535797119140625 +750 0.493194580078125 +751 0.52691650390625 +752 0.484832763671875 +753 0.51800537109375 +754 0.476409912109375 +755 0.509002685546875 +756 0.46795654296875 +757 0.499969482421875 +758 0.459442138671875 +759 0.490875244140625 +760 0.45086669921875 +761 0.481719970703125 +762 0.442291259765625 +763 0.4725341796875 +764 0.43359375 +765 0.4632568359375 +766 0.424896240234375 +767 0.453948974609375 +768 0.40191650390625 +769 0.444610595703125 +770 0.393402099609375 +771 0.435211181640625 +772 0.384857177734375 +773 0.425750732421875 +774 0.37628173828125 +775 0.416259765625 +776 0.367645263671875 +777 0.406707763671875 +778 0.358978271484375 +779 0.397125244140625 +780 0.350250244140625 +781 0.387481689453125 +782 0.341522216796875 +783 0.3778076171875 +784 0.332733154296875 +785 0.36810302734375 +786 0.32391357421875 +787 0.35833740234375 +788 0.3150634765625 +789 0.348541259765625 +790 0.306182861328125 +791 0.338714599609375 +792 0.2972412109375 +793 0.328826904296875 +794 0.288299560546875 +795 0.318939208984375 +796 0.279296875 +797 0.308990478515625 +798 0.270294189453125 +799 0.29901123046875 +800 0.26123046875 +801 0.28900146484375 +802 0.252166748046875 +803 0.278961181640625 +804 0.243072509765625 +805 0.268890380859375 +806 0.233917236328125 +807 0.2587890625 +808 0.224761962890625 +809 0.2486572265625 +810 0.215606689453125 +811 0.238525390625 +812 0.206390380859375 +813 0.22833251953125 +814 0.1971435546875 +815 0.218109130859375 +816 0.187896728515625 +817 0.2078857421875 +818 0.17864990234375 +819 0.1976318359375 +820 0.169342041015625 +821 0.187347412109375 +822 0.1600341796875 +823 0.17706298828125 +824 0.150726318359375 +825 0.166748046875 +826 0.141357421875 +827 0.156402587890625 +828 0.13201904296875 +829 0.14605712890625 +830 0.122650146484375 +831 0.13568115234375 +832 0.113250732421875 +833 0.12530517578125 +834 0.1038818359375 +835 0.11492919921875 +836 0.094482421875 +837 0.104522705078125 +838 0.08502197265625 +839 0.094085693359375 +840 0.075592041015625 +841 0.083648681640625 +842 0.066162109375 +843 0.073211669921875 +844 0.056732177734375 +845 0.062774658203125 +846 0.047271728515625 +847 0.05230712890625 +848 0.037841796875 +849 0.0418701171875 +850 0.02838134765625 +851 0.031402587890625 +852 0.0189208984375 +853 0.02093505859375 +854 0.00946044921875 +855 0.010467529296875 +856 0.0 +857 0.0 +858 -0.00946044921875 +859 -0.010467529296875 +860 -0.0189208984375 +861 -0.02093505859375 +862 -0.02838134765625 +863 -0.031402587890625 +864 -0.037841796875 +865 -0.0418701171875 +866 -0.047271728515625 +867 -0.05230712890625 +868 -0.056732177734375 +869 -0.062774658203125 +870 -0.066162109375 +871 -0.073211669921875 +872 -0.075592041015625 +873 -0.083648681640625 +874 -0.08502197265625 +875 -0.094085693359375 +876 -0.094482421875 +877 -0.104522705078125 +878 -0.1038818359375 +879 -0.11492919921875 +880 -0.113250732421875 +881 -0.12530517578125 +882 -0.122650146484375 +883 -0.13568115234375 +884 -0.13201904296875 +885 -0.14605712890625 +886 -0.141357421875 +887 -0.156402587890625 +888 -0.150726318359375 +889 -0.166748046875 +890 -0.1600341796875 +891 -0.17706298828125 +892 -0.169342041015625 +893 -0.187347412109375 +894 -0.17864990234375 +895 -0.1976318359375 +896 -0.187896728515625 +897 -0.2078857421875 +898 -0.1971435546875 +899 -0.218109130859375 +900 -0.206390380859375 +901 -0.22833251953125 +902 -0.215606689453125 +903 -0.238525390625 +904 -0.224761962890625 +905 -0.2486572265625 +906 -0.233917236328125 +907 -0.2587890625 +908 -0.243072509765625 +909 -0.268890380859375 +910 -0.252166748046875 +911 -0.278961181640625 +912 -0.26123046875 +913 -0.28900146484375 +914 -0.270294189453125 +915 -0.29901123046875 +916 -0.279296875 +917 -0.308990478515625 +918 -0.288299560546875 +919 -0.318939208984375 +920 -0.2972412109375 +921 -0.328826904296875 +922 -0.306182861328125 +923 -0.338714599609375 +924 -0.3150634765625 +925 -0.348541259765625 +926 -0.32391357421875 +927 -0.35833740234375 +928 -0.332733154296875 +929 -0.36810302734375 +930 -0.341522216796875 +931 -0.3778076171875 +932 -0.350250244140625 +933 -0.387481689453125 +934 -0.358978271484375 +935 -0.397125244140625 +936 -0.367645263671875 +937 -0.406707763671875 +938 -0.37628173828125 +939 -0.416259765625 +940 -0.384857177734375 +941 -0.425750732421875 +942 -0.393402099609375 +943 -0.435211181640625 +944 -0.40191650390625 +945 -0.444610595703125 +946 -0.41033935546875 +947 -0.453948974609375 +948 -0.41876220703125 +949 -0.4632568359375 +950 -0.427154541015625 +951 -0.4725341796875 +952 -0.435455322265625 +953 -0.481719970703125 +954 -0.4437255859375 +955 -0.490875244140625 +956 -0.45196533203125 +957 -0.499969482421875 +958 -0.460113525390625 +959 -0.509002685546875 +960 -0.46826171875 +961 -0.51800537109375 +962 -0.476318359375 +963 -0.52691650390625 +964 -0.484344482421875 +965 -0.535797119140625 +966 -0.4923095703125 +967 -0.54461669921875 +968 -0.500213623046875 +969 -0.5533447265625 +970 -0.508056640625 +971 -0.562042236328125 +972 -0.515869140625 +973 -0.5706787109375 +974 -0.52362060546875 +975 -0.579254150390625 +976 -0.531280517578125 +977 -0.587738037109375 +978 -0.5389404296875 +979 -0.59619140625 +980 -0.5465087890625 +981 -0.60455322265625 +982 -0.55401611328125 +983 -0.612884521484375 +984 -0.56146240234375 +985 -0.621124267578125 +986 -0.56884765625 +987 -0.6292724609375 +988 -0.576171875 +989 -0.63739013671875 +990 -0.58343505859375 +991 -0.645416259765625 +992 -0.59063720703125 +993 -0.65338134765625 +994 -0.5977783203125 +995 -0.661285400390625 +996 -0.604827880859375 +997 -0.669097900390625 +998 -0.611846923828125 +999 -0.676849365234375 +1000 -0.6187744140625 +1001 -0.68450927734375 +1002 -0.625640869140625 +1003 -0.692108154296875 +1004 -0.632415771484375 +1005 -0.699615478515625 +1006 -0.63916015625 +1007 -0.707061767578125 +1008 -0.645843505859375 +1009 -0.714447021484375 +1010 -0.65240478515625 +1011 -0.721710205078125 +1012 -0.658935546875 +1013 -0.72894287109375 +1014 -0.665374755859375 +1015 -0.736053466796875 +1016 -0.6717529296875 +1017 -0.74310302734375 +1018 -0.67803955078125 +1019 -0.75006103515625 +1020 -0.68426513671875 +1021 -0.7569580078125 +1022 -0.6904296875 +1023 -0.763763427734375 +1024 -0.671844482421875 +1025 -0.770477294921875 +1026 -0.6776123046875 +1027 -0.777099609375 +1028 -0.683349609375 +1029 -0.783660888671875 +1030 -0.688995361328125 +1031 -0.790130615234375 +1032 -0.69451904296875 +1033 -0.796478271484375 +1034 -0.70001220703125 +1035 -0.802764892578125 +1036 -0.705413818359375 +1037 -0.808990478515625 +1038 -0.71075439453125 +1039 -0.815093994140625 +1040 -0.71600341796875 +1041 -0.82110595703125 +1042 -0.721160888671875 +1043 -0.8270263671875 +1044 -0.72625732421875 +1045 -0.8328857421875 +1046 -0.73126220703125 +1047 -0.838623046875 +1048 -0.7362060546875 +1049 -0.84429931640625 +1050 -0.741058349609375 +1051 -0.849853515625 +1052 -0.745819091796875 +1053 -0.855316162109375 +1054 -0.750518798828125 +1055 -0.860687255859375 +1056 -0.755126953125 +1057 -0.865997314453125 +1058 -0.759674072265625 +1059 -0.871185302734375 +1060 -0.764068603515625 +1061 -0.876251220703125 +1062 -0.7684326171875 +1063 -0.881256103515625 +1064 -0.772735595703125 +1065 -0.88616943359375 +1066 -0.77691650390625 +1067 -0.890960693359375 +1068 -0.781005859375 +1069 -0.895660400390625 +1070 -0.7850341796875 +1071 -0.9002685546875 +1072 -0.788970947265625 +1073 -0.90478515625 +1074 -0.79278564453125 +1075 -0.9091796875 +1076 -0.79656982421875 +1077 -0.91351318359375 +1078 -0.80023193359375 +1079 -0.917724609375 +1080 -0.803802490234375 +1081 -0.92181396484375 +1082 -0.80731201171875 +1083 -0.92584228515625 +1084 -0.810699462890625 +1085 -0.929718017578125 +1086 -0.81402587890625 +1087 -0.93353271484375 +1088 -0.8172607421875 +1089 -0.937225341796875 +1090 -0.820404052734375 +1091 -0.940826416015625 +1092 -0.823455810546875 +1093 -0.9443359375 +1094 -0.826416015625 +1095 -0.947723388671875 +1096 -0.82928466796875 +1097 -0.951019287109375 +1098 -0.83203125 +1099 -0.954193115234375 +1100 -0.834747314453125 +1101 -0.957275390625 +1102 -0.837310791015625 +1103 -0.960235595703125 +1104 -0.839813232421875 +1105 -0.963104248046875 +1106 -0.84222412109375 +1107 -0.96588134765625 +1108 -0.84454345703125 +1109 -0.968536376953125 +1110 -0.8468017578125 +1111 -0.971099853515625 +1112 -0.848907470703125 +1113 -0.973541259765625 +1114 -0.8509521484375 +1115 -0.975860595703125 +1116 -0.852874755859375 +1117 -0.97808837890625 +1118 -0.854736328125 +1119 -0.980224609375 +1120 -0.85650634765625 +1121 -0.98223876953125 +1122 -0.858184814453125 +1123 -0.984161376953125 +1124 -0.8597412109375 +1125 -0.9859619140625 +1126 -0.8612060546875 +1127 -0.987640380859375 +1128 -0.86260986328125 +1129 -0.989227294921875 +1130 -0.863861083984375 +1131 -0.990692138671875 +1132 -0.865081787109375 +1133 -0.9920654296875 +1134 -0.86614990234375 +1135 -0.993316650390625 +1136 -0.8671875 +1137 -0.994476318359375 +1138 -0.868072509765625 +1139 -0.995513916015625 +1140 -0.868896484375 +1141 -0.9964599609375 +1142 -0.86962890625 +1143 -0.997283935546875 +1144 -0.8702392578125 +1145 -0.99798583984375 +1146 -0.870758056640625 +1147 -0.99859619140625 +1148 -0.871185302734375 +1149 -0.999114990234375 +1150 -0.87152099609375 +1151 -0.999481201171875 +1152 -0.87176513671875 +1153 -0.999755859375 +1154 -0.871917724609375 +1155 -0.99993896484375 +1156 -0.871978759765625 +1157 -1.0 +1158 -0.871917724609375 +1159 -0.99993896484375 +1160 -0.87176513671875 +1161 -0.999755859375 +1162 -0.87152099609375 +1163 -0.999481201171875 +1164 -0.871185302734375 +1165 -0.999114990234375 +1166 -0.870758056640625 +1167 -0.99859619140625 +1168 -0.8702392578125 +1169 -0.99798583984375 +1170 -0.86962890625 +1171 -0.997283935546875 +1172 -0.868896484375 +1173 -0.9964599609375 +1174 -0.868072509765625 +1175 -0.995513916015625 +1176 -0.8671875 +1177 -0.994476318359375 +1178 -0.86614990234375 +1179 -0.993316650390625 +1180 -0.865081787109375 +1181 -0.9920654296875 +1182 -0.863861083984375 +1183 -0.990692138671875 +1184 -0.86260986328125 +1185 -0.989227294921875 +1186 -0.8612060546875 +1187 -0.987640380859375 +1188 -0.8597412109375 +1189 -0.9859619140625 +1190 -0.858184814453125 +1191 -0.984161376953125 +1192 -0.85650634765625 +1193 -0.98223876953125 +1194 -0.854736328125 +1195 -0.980224609375 +1196 -0.852874755859375 +1197 -0.97808837890625 +1198 -0.8509521484375 +1199 -0.975860595703125 +1200 -0.848907470703125 +1201 -0.973541259765625 +1202 -0.8468017578125 +1203 -0.971099853515625 +1204 -0.84454345703125 +1205 -0.968536376953125 +1206 -0.84222412109375 +1207 -0.96588134765625 +1208 -0.839813232421875 +1209 -0.963104248046875 +1210 -0.837310791015625 +1211 -0.960235595703125 +1212 -0.834747314453125 +1213 -0.957275390625 +1214 -0.83203125 +1215 -0.954193115234375 +1216 -0.82928466796875 +1217 -0.951019287109375 +1218 -0.826416015625 +1219 -0.947723388671875 +1220 -0.823455810546875 +1221 -0.9443359375 +1222 -0.820404052734375 +1223 -0.940826416015625 +1224 -0.8172607421875 +1225 -0.937225341796875 +1226 -0.81402587890625 +1227 -0.93353271484375 +1228 -0.810699462890625 +1229 -0.929718017578125 +1230 -0.80731201171875 +1231 -0.92584228515625 +1232 -0.803802490234375 +1233 -0.92181396484375 +1234 -0.80023193359375 +1235 -0.917724609375 +1236 -0.79656982421875 +1237 -0.91351318359375 +1238 -0.79278564453125 +1239 -0.9091796875 +1240 -0.788970947265625 +1241 -0.90478515625 +1242 -0.7850341796875 +1243 -0.9002685546875 +1244 -0.781005859375 +1245 -0.895660400390625 +1246 -0.77691650390625 +1247 -0.890960693359375 +1248 -0.772735595703125 +1249 -0.88616943359375 +1250 -0.7684326171875 +1251 -0.881256103515625 +1252 -0.764068603515625 +1253 -0.876251220703125 +1254 -0.759674072265625 +1255 -0.871185302734375 +1256 -0.755126953125 +1257 -0.865997314453125 +1258 -0.750518798828125 +1259 -0.860687255859375 +1260 -0.745819091796875 +1261 -0.855316162109375 +1262 -0.741058349609375 +1263 -0.849853515625 +1264 -0.7362060546875 +1265 -0.84429931640625 +1266 -0.73126220703125 +1267 -0.838623046875 +1268 -0.72625732421875 +1269 -0.8328857421875 +1270 -0.721160888671875 +1271 -0.8270263671875 +1272 -0.71600341796875 +1273 -0.82110595703125 +1274 -0.71075439453125 +1275 -0.815093994140625 +1276 -0.705413818359375 +1277 -0.808990478515625 +1278 -0.70001220703125 +1279 -0.802764892578125 +1280 -0.677001953125 +1281 -0.796478271484375 +1282 -0.671600341796875 +1283 -0.790130615234375 +1284 -0.666107177734375 +1285 -0.783660888671875 +1286 -0.6605224609375 +1287 -0.777099609375 +1288 -0.654876708984375 +1289 -0.770477294921875 +1290 -0.649169921875 +1291 -0.763763427734375 +1292 -0.643402099609375 +1293 -0.7569580078125 +1294 -0.637542724609375 +1295 -0.75006103515625 +1296 -0.631622314453125 +1297 -0.74310302734375 +1298 -0.625640869140625 +1299 -0.736053466796875 +1300 -0.619598388671875 +1301 -0.72894287109375 +1302 -0.613433837890625 +1303 -0.721710205078125 +1304 -0.607269287109375 +1305 -0.714447021484375 +1306 -0.600982666015625 +1307 -0.707061767578125 +1308 -0.59466552734375 +1309 -0.699615478515625 +1310 -0.588287353515625 +1311 -0.692108154296875 +1312 -0.581817626953125 +1313 -0.68450927734375 +1314 -0.5753173828125 +1315 -0.676849365234375 +1316 -0.5687255859375 +1317 -0.669097900390625 +1318 -0.56207275390625 +1319 -0.661285400390625 +1320 -0.55535888671875 +1321 -0.65338134765625 +1322 -0.548583984375 +1323 -0.645416259765625 +1324 -0.541778564453125 +1325 -0.63739013671875 +1326 -0.534881591796875 +1327 -0.6292724609375 +1328 -0.5279541015625 +1329 -0.621124267578125 +1330 -0.52093505859375 +1331 -0.612884521484375 +1332 -0.51385498046875 +1333 -0.60455322265625 +1334 -0.506744384765625 +1335 -0.59619140625 +1336 -0.49957275390625 +1337 -0.587738037109375 +1338 -0.492340087890625 +1339 -0.579254150390625 +1340 -0.485076904296875 +1341 -0.5706787109375 +1342 -0.47772216796875 +1343 -0.562042236328125 +1344 -0.4703369140625 +1345 -0.5533447265625 +1346 -0.462921142578125 +1347 -0.54461669921875 +1348 -0.455413818359375 +1349 -0.535797119140625 +1350 -0.4478759765625 +1351 -0.52691650390625 +1352 -0.440277099609375 +1353 -0.51800537109375 +1354 -0.432647705078125 +1355 -0.509002685546875 +1356 -0.424957275390625 +1357 -0.499969482421875 +1358 -0.417236328125 +1359 -0.490875244140625 +1360 -0.409454345703125 +1361 -0.481719970703125 +1362 -0.401641845703125 +1363 -0.4725341796875 +1364 -0.393768310546875 +1365 -0.4632568359375 +1366 -0.385833740234375 +1367 -0.453948974609375 +1368 -0.377899169921875 +1369 -0.444610595703125 +1370 -0.369903564453125 +1371 -0.435211181640625 +1372 -0.36187744140625 +1373 -0.425750732421875 +1374 -0.35382080078125 +1375 -0.416259765625 +1376 -0.345672607421875 +1377 -0.406707763671875 +1378 -0.337554931640625 +1379 -0.397125244140625 +1380 -0.329345703125 +1381 -0.387481689453125 +1382 -0.321136474609375 +1383 -0.3778076171875 +1384 -0.3128662109375 +1385 -0.36810302734375 +1386 -0.3045654296875 +1387 -0.35833740234375 +1388 -0.296234130859375 +1389 -0.348541259765625 +1390 -0.28790283203125 +1391 -0.338714599609375 +1392 -0.27947998046875 +1393 -0.328826904296875 +1394 -0.271087646484375 +1395 -0.318939208984375 +1396 -0.26263427734375 +1397 -0.308990478515625 +1398 -0.254150390625 +1399 -0.29901123046875 +1400 -0.245635986328125 +1401 -0.28900146484375 +1402 -0.237091064453125 +1403 -0.278961181640625 +1404 -0.228546142578125 +1405 -0.268890380859375 +1406 -0.219970703125 +1407 -0.2587890625 +1408 -0.211334228515625 +1409 -0.2486572265625 +1410 -0.202728271484375 +1411 -0.238525390625 +1412 -0.194061279296875 +1413 -0.22833251953125 +1414 -0.18536376953125 +1415 -0.218109130859375 +1416 -0.17669677734375 +1417 -0.2078857421875 +1418 -0.16796875 +1419 -0.1976318359375 +1420 -0.15924072265625 +1421 -0.187347412109375 +1422 -0.150482177734375 +1423 -0.17706298828125 +1424 -0.1417236328125 +1425 -0.166748046875 +1426 -0.1329345703125 +1427 -0.156402587890625 +1428 -0.1241455078125 +1429 -0.14605712890625 +1430 -0.115325927734375 +1431 -0.13568115234375 +1432 -0.10650634765625 +1433 -0.12530517578125 +1434 -0.097686767578125 +1435 -0.11492919921875 +1436 -0.088836669921875 +1437 -0.104522705078125 +1438 -0.0799560546875 +1439 -0.094085693359375 +1440 -0.071075439453125 +1441 -0.083648681640625 +1442 -0.062225341796875 +1443 -0.073211669921875 +1444 -0.0533447265625 +1445 -0.062774658203125 +1446 -0.04443359375 +1447 -0.05230712890625 +1448 -0.03558349609375 +1449 -0.0418701171875 +1450 -0.02667236328125 +1451 -0.031402587890625 +1452 -0.017791748046875 +1453 -0.02093505859375 +1454 -0.008880615234375 +1455 -0.010467529296875 +1456 0.0 +1457 0.0 +1458 0.0087890625 +1459 0.010467529296875 +1460 0.017578125 +1461 0.02093505859375 +1462 0.0263671875 +1463 0.031402587890625 +1464 0.03515625 +1465 0.0418701171875 +1466 0.043914794921875 +1467 0.05230712890625 +1468 0.052703857421875 +1469 0.062774658203125 +1470 0.061492919921875 +1471 0.073211669921875 +1472 0.07025146484375 +1473 0.083648681640625 +1474 0.079010009765625 +1475 0.094085693359375 +1476 0.0877685546875 +1477 0.104522705078125 +1478 0.096527099609375 +1479 0.11492919921875 +1480 0.105255126953125 +1481 0.12530517578125 +1482 0.11395263671875 +1483 0.13568115234375 +1484 0.1226806640625 +1485 0.14605712890625 +1486 0.13134765625 +1487 0.156402587890625 +1488 0.140045166015625 +1489 0.166748046875 +1490 0.148712158203125 +1491 0.17706298828125 +1492 0.1573486328125 +1493 0.187347412109375 +1494 0.165985107421875 +1495 0.1976318359375 +1496 0.17462158203125 +1497 0.2078857421875 +1498 0.183197021484375 +1499 0.218109130859375 +1500 0.1917724609375 +1501 0.22833251953125 +1502 0.200347900390625 +1503 0.238525390625 +1504 0.2088623046875 +1505 0.2486572265625 +1506 0.217376708984375 +1507 0.2587890625 +1508 0.225860595703125 +1509 0.268890380859375 +1510 0.23431396484375 +1511 0.278961181640625 +1512 0.24273681640625 +1513 0.28900146484375 +1514 0.25115966796875 +1515 0.29901123046875 +1516 0.259521484375 +1517 0.308990478515625 +1518 0.26788330078125 +1519 0.318939208984375 +1520 0.27618408203125 +1521 0.328826904296875 +1522 0.284515380859375 +1523 0.338714599609375 +1524 0.292755126953125 +1525 0.348541259765625 +1526 0.300994873046875 +1527 0.35833740234375 +1528 0.309173583984375 +1529 0.36810302734375 +1530 0.317352294921875 +1531 0.3778076171875 +1532 0.325469970703125 +1533 0.387481689453125 +1534 0.33355712890625 +1535 0.397125244140625 +1536 0.32861328125 +1537 0.406707763671875 +1538 0.336334228515625 +1539 0.416259765625 +1540 0.343994140625 +1541 0.425750732421875 +1542 0.351654052734375 +1543 0.435211181640625 +1544 0.359222412109375 +1545 0.444610595703125 +1546 0.366790771484375 +1547 0.453948974609375 +1548 0.374298095703125 +1549 0.4632568359375 +1550 0.381805419921875 +1551 0.4725341796875 +1552 0.38922119140625 +1553 0.481719970703125 +1554 0.3966064453125 +1555 0.490875244140625 +1556 0.403961181640625 +1557 0.499969482421875 +1558 0.4112548828125 +1559 0.509002685546875 +1560 0.418548583984375 +1561 0.51800537109375 +1562 0.425750732421875 +1563 0.52691650390625 +1564 0.43292236328125 +1565 0.535797119140625 +1566 0.440032958984375 +1567 0.54461669921875 +1568 0.44708251953125 +1569 0.5533447265625 +1570 0.454132080078125 +1571 0.562042236328125 +1572 0.461090087890625 +1573 0.5706787109375 +1574 0.468017578125 +1575 0.579254150390625 +1576 0.474884033203125 +1577 0.587738037109375 +1578 0.481719970703125 +1579 0.59619140625 +1580 0.48846435546875 +1581 0.60455322265625 +1582 0.495208740234375 +1583 0.612884521484375 +1584 0.501861572265625 +1585 0.621124267578125 +1586 0.508453369140625 +1587 0.6292724609375 +1588 0.5150146484375 +1589 0.63739013671875 +1590 0.521484375 +1591 0.645416259765625 +1592 0.527923583984375 +1593 0.65338134765625 +1594 0.5343017578125 +1595 0.661285400390625 +1596 0.540618896484375 +1597 0.669097900390625 +1598 0.546875 +1599 0.676849365234375 +1600 0.553070068359375 +1601 0.68450927734375 +1602 0.5592041015625 +1603 0.692108154296875 +1604 0.565277099609375 +1605 0.699615478515625 +1606 0.5712890625 +1607 0.707061767578125 +1608 0.5772705078125 +1609 0.714447021484375 +1610 0.5831298828125 +1611 0.721710205078125 +1612 0.5889892578125 +1613 0.72894287109375 +1614 0.5947265625 +1615 0.736053466796875 +1616 0.60040283203125 +1617 0.74310302734375 +1618 0.606048583984375 +1619 0.75006103515625 +1620 0.611602783203125 +1621 0.7569580078125 +1622 0.61712646484375 +1623 0.763763427734375 +1624 0.622528076171875 +1625 0.770477294921875 +1626 0.627899169921875 +1627 0.777099609375 +1628 0.6331787109375 +1629 0.783660888671875 +1630 0.638427734375 +1631 0.790130615234375 +1632 0.6435546875 +1633 0.796478271484375 +1634 0.64862060546875 +1635 0.802764892578125 +1636 0.653656005859375 +1637 0.808990478515625 +1638 0.658599853515625 +1639 0.815093994140625 +1640 0.6634521484375 +1641 0.82110595703125 +1642 0.668243408203125 +1643 0.8270263671875 +1644 0.6729736328125 +1645 0.8328857421875 +1646 0.6776123046875 +1647 0.838623046875 +1648 0.68218994140625 +1649 0.84429931640625 +1650 0.686676025390625 +1651 0.849853515625 +1652 0.69110107421875 +1653 0.855316162109375 +1654 0.6954345703125 +1655 0.860687255859375 +1656 0.69970703125 +1657 0.865997314453125 +1658 0.70391845703125 +1659 0.871185302734375 +1660 0.7080078125 +1661 0.876251220703125 +1662 0.7120361328125 +1663 0.881256103515625 +1664 0.71600341796875 +1665 0.88616943359375 +1666 0.719879150390625 +1667 0.890960693359375 +1668 0.72369384765625 +1669 0.895660400390625 +1670 0.7274169921875 +1671 0.9002685546875 +1672 0.731048583984375 +1673 0.90478515625 +1674 0.734619140625 +1675 0.9091796875 +1676 0.73809814453125 +1677 0.91351318359375 +1678 0.74151611328125 +1679 0.917724609375 +1680 0.74481201171875 +1681 0.92181396484375 +1682 0.748077392578125 +1683 0.92584228515625 +1684 0.751190185546875 +1685 0.929718017578125 +1686 0.7542724609375 +1687 0.93353271484375 +1688 0.75726318359375 +1689 0.937225341796875 +1690 0.76019287109375 +1691 0.940826416015625 +1692 0.763031005859375 +1693 0.9443359375 +1694 0.7657470703125 +1695 0.947723388671875 +1696 0.768402099609375 +1697 0.951019287109375 +1698 0.770965576171875 +1699 0.954193115234375 +1700 0.773468017578125 +1701 0.957275390625 +1702 0.775848388671875 +1703 0.960235595703125 +1704 0.778167724609375 +1705 0.963104248046875 +1706 0.780426025390625 +1707 0.96588134765625 +1708 0.782562255859375 +1709 0.968536376953125 +1710 0.784637451171875 +1711 0.971099853515625 +1712 0.78662109375 +1713 0.973541259765625 +1714 0.788482666015625 +1715 0.975860595703125 +1716 0.790283203125 +1717 0.97808837890625 +1718 0.792022705078125 +1719 0.980224609375 +1720 0.79364013671875 +1721 0.98223876953125 +1722 0.795196533203125 +1723 0.984161376953125 +1724 0.796661376953125 +1725 0.9859619140625 +1726 0.798004150390625 +1727 0.987640380859375 +1728 0.799285888671875 +1729 0.989227294921875 +1730 0.80047607421875 +1731 0.990692138671875 +1732 0.80157470703125 +1733 0.9920654296875 +1734 0.802581787109375 +1735 0.993316650390625 +1736 0.80352783203125 +1737 0.994476318359375 +1738 0.80438232421875 +1739 0.995513916015625 +1740 0.805145263671875 +1741 0.9964599609375 +1742 0.8057861328125 +1743 0.997283935546875 +1744 0.806365966796875 +1745 0.99798583984375 +1746 0.806854248046875 +1747 0.99859619140625 +1748 0.8072509765625 +1749 0.999114990234375 +1750 0.80755615234375 +1751 0.999481201171875 +1752 0.807769775390625 +1753 0.999755859375 +1754 0.80792236328125 +1755 0.99993896484375 +1756 0.8079833984375 +1757 0.999969482421875 +1758 0.80792236328125 +1759 0.99993896484375 +1760 0.807769775390625 +1761 0.999755859375 +1762 0.80755615234375 +1763 0.999481201171875 +1764 0.8072509765625 +1765 0.999114990234375 +1766 0.806854248046875 +1767 0.99859619140625 +1768 0.806365966796875 +1769 0.99798583984375 +1770 0.8057861328125 +1771 0.997283935546875 +1772 0.805145263671875 +1773 0.9964599609375 +1774 0.80438232421875 +1775 0.995513916015625 +1776 0.80352783203125 +1777 0.994476318359375 +1778 0.802581787109375 +1779 0.993316650390625 +1780 0.80157470703125 +1781 0.9920654296875 +1782 0.80047607421875 +1783 0.990692138671875 +1784 0.799285888671875 +1785 0.989227294921875 +1786 0.798004150390625 +1787 0.987640380859375 +1788 0.796661376953125 +1789 0.9859619140625 +1790 0.795196533203125 +1791 0.984161376953125 +1792 0.76220703125 +1793 0.98223876953125 +1794 0.7606201171875 +1795 0.980224609375 +1796 0.75897216796875 +1797 0.97808837890625 +1798 0.757232666015625 +1799 0.975860595703125 +1800 0.75543212890625 +1801 0.973541259765625 +1802 0.7535400390625 +1803 0.971099853515625 +1804 0.751556396484375 +1805 0.968536376953125 +1806 0.74951171875 +1807 0.96588134765625 +1808 0.747344970703125 +1809 0.963104248046875 +1810 0.7451171875 +1811 0.960235595703125 +1812 0.742828369140625 +1813 0.957275390625 +1814 0.740447998046875 +1815 0.954193115234375 +1816 0.73797607421875 +1817 0.951019287109375 +1818 0.73541259765625 +1819 0.947723388671875 +1820 0.7327880859375 +1821 0.9443359375 +1822 0.730072021484375 +1823 0.940826416015625 +1824 0.727264404296875 +1825 0.937225341796875 +1826 0.724395751953125 +1827 0.93353271484375 +1828 0.721435546875 +1829 0.929718017578125 +1830 0.71844482421875 +1831 0.92584228515625 +1832 0.715301513671875 +1833 0.92181396484375 +1834 0.712127685546875 +1835 0.917724609375 +1836 0.7088623046875 +1837 0.91351318359375 +1838 0.70550537109375 +1839 0.9091796875 +1840 0.70208740234375 +1841 0.90478515625 +1842 0.698577880859375 +1843 0.9002685546875 +1844 0.69500732421875 +1845 0.895660400390625 +1846 0.691375732421875 +1847 0.890960693359375 +1848 0.687652587890625 +1849 0.88616943359375 +1850 0.683837890625 +1851 0.881256103515625 +1852 0.679962158203125 +1853 0.876251220703125 +1854 0.676025390625 +1855 0.871185302734375 +1856 0.6719970703125 +1857 0.865997314453125 +1858 0.667877197265625 +1859 0.860687255859375 +1860 0.6636962890625 +1861 0.855316162109375 +1862 0.659454345703125 +1863 0.849853515625 +1864 0.6551513671875 +1865 0.84429931640625 +1866 0.6507568359375 +1867 0.838623046875 +1868 0.64630126953125 +1869 0.8328857421875 +1870 0.641754150390625 +1871 0.8270263671875 +1872 0.63714599609375 +1873 0.82110595703125 +1874 0.63250732421875 +1875 0.815093994140625 +1876 0.62774658203125 +1877 0.808990478515625 +1878 0.6229248046875 +1879 0.802764892578125 +1880 0.6180419921875 +1881 0.796478271484375 +1882 0.613128662109375 +1883 0.790130615234375 +1884 0.60809326171875 +1885 0.783660888671875 +1886 0.602996826171875 +1887 0.777099609375 +1888 0.597869873046875 +1889 0.770477294921875 +1890 0.5926513671875 +1891 0.763763427734375 +1892 0.587371826171875 +1893 0.7569580078125 +1894 0.58203125 +1895 0.75006103515625 +1896 0.576629638671875 +1897 0.74310302734375 +1898 0.5711669921875 +1899 0.736053466796875 +1900 0.565643310546875 +1901 0.72894287109375 +1902 0.560028076171875 +1903 0.721710205078125 +1904 0.55438232421875 +1905 0.714447021484375 +1906 0.548675537109375 +1907 0.707061767578125 +1908 0.542877197265625 +1909 0.699615478515625 +1910 0.53704833984375 +1911 0.692108154296875 +1912 0.531158447265625 +1913 0.68450927734375 +1914 0.52520751953125 +1915 0.676849365234375 +1916 0.519195556640625 +1917 0.669097900390625 +1918 0.513153076171875 +1919 0.661285400390625 +1920 0.50701904296875 +1921 0.65338134765625 +1922 0.500823974609375 +1923 0.645416259765625 +1924 0.494598388671875 +1925 0.63739013671875 +1926 0.48828125 +1927 0.6292724609375 +1928 0.481964111328125 +1929 0.621124267578125 +1930 0.4755859375 +1931 0.612884521484375 +1932 0.4691162109375 +1933 0.60455322265625 +1934 0.462615966796875 +1935 0.59619140625 +1936 0.4560546875 +1937 0.587738037109375 +1938 0.449493408203125 +1939 0.579254150390625 +1940 0.442840576171875 +1941 0.5706787109375 +1942 0.436126708984375 +1943 0.562042236328125 +1944 0.42938232421875 +1945 0.5533447265625 +1946 0.422607421875 +1947 0.54461669921875 +1948 0.415771484375 +1949 0.535797119140625 +1950 0.40887451171875 +1951 0.52691650390625 +1952 0.401947021484375 +1953 0.51800537109375 +1954 0.39495849609375 +1955 0.509002685546875 +1956 0.387969970703125 +1957 0.499969482421875 +1958 0.380889892578125 +1959 0.490875244140625 +1960 0.373809814453125 +1961 0.481719970703125 +1962 0.366668701171875 +1963 0.4725341796875 +1964 0.359466552734375 +1965 0.4632568359375 +1966 0.35223388671875 +1967 0.453948974609375 +1968 0.345001220703125 +1969 0.444610595703125 +1970 0.33770751953125 +1971 0.435211181640625 +1972 0.330352783203125 +1973 0.425750732421875 +1974 0.322998046875 +1975 0.416259765625 +1976 0.315582275390625 +1977 0.406707763671875 +1978 0.30816650390625 +1979 0.397125244140625 +1980 0.3006591796875 +1981 0.387481689453125 +1982 0.29315185546875 +1983 0.3778076171875 +1984 0.28564453125 +1985 0.36810302734375 +1986 0.278045654296875 +1987 0.35833740234375 +1988 0.27044677734375 +1989 0.348541259765625 +1990 0.2628173828125 +1991 0.338714599609375 +1992 0.255157470703125 +1993 0.328826904296875 +1994 0.247467041015625 +1995 0.318939208984375 +1996 0.23974609375 +1997 0.308990478515625 +1998 0.232025146484375 +1999 0.29901123046875 +2000 0.2242431640625 +2001 0.28900146484375 +2002 0.216461181640625 +2003 0.278961181640625 +2004 0.208648681640625 +2005 0.268890380859375 +2006 0.2008056640625 +2007 0.2587890625 +2008 0.19293212890625 +2009 0.2486572265625 +2010 0.185089111328125 +2011 0.238525390625 +2012 0.177154541015625 +2013 0.22833251953125 +2014 0.16925048828125 +2015 0.218109130859375 +2016 0.16131591796875 +2017 0.2078857421875 +2018 0.153350830078125 +2019 0.1976318359375 +2020 0.145355224609375 +2021 0.187347412109375 +2022 0.13739013671875 +2023 0.17706298828125 +2024 0.12939453125 +2025 0.166748046875 +2026 0.121337890625 +2027 0.156402587890625 +2028 0.113311767578125 +2029 0.14605712890625 +2030 0.10528564453125 +2031 0.13568115234375 +2032 0.09722900390625 +2033 0.12530517578125 +2034 0.08917236328125 +2035 0.11492919921875 +2036 0.081085205078125 +2037 0.104522705078125 +2038 0.072998046875 +2039 0.094085693359375 +2040 0.064910888671875 +2041 0.083648681640625 +2042 0.056793212890625 +2043 0.073211669921875 +2044 0.0487060546875 +2045 0.062774658203125 +2046 0.04058837890625 +2047 0.05230712890625 +2048 0.0311279296875 +2049 0.0418701171875 +2050 0.023345947265625 +2051 0.031402587890625 +2052 0.01556396484375 +2053 0.02093505859375 +2054 0.007781982421875 +2055 0.010467529296875 +2056 0.0 +2057 0.0 +2058 -0.007781982421875 +2059 -0.010467529296875 +2060 -0.01556396484375 +2061 -0.02093505859375 +2062 -0.023345947265625 +2063 -0.031402587890625 +2064 -0.0311279296875 +2065 -0.0418701171875 +2066 -0.038909912109375 +2067 -0.05230712890625 +2068 -0.04669189453125 +2069 -0.062774658203125 +2070 -0.054443359375 +2071 -0.073211669921875 +2072 -0.062225341796875 +2073 -0.083648681640625 +2074 -0.069976806640625 +2075 -0.094085693359375 +2076 -0.0777587890625 +2077 -0.104522705078125 +2078 -0.085479736328125 +2079 -0.11492919921875 +2080 -0.09320068359375 +2081 -0.12530517578125 +2082 -0.100921630859375 +2083 -0.13568115234375 +2084 -0.108642578125 +2085 -0.14605712890625 +2086 -0.116363525390625 +2087 -0.156402587890625 +2088 -0.124053955078125 +2089 -0.166748046875 +2090 -0.1317138671875 +2091 -0.17706298828125 +2092 -0.139373779296875 +2093 -0.187347412109375 +2094 -0.14703369140625 +2095 -0.1976318359375 +2096 -0.1546630859375 +2097 -0.2078857421875 +2098 -0.162261962890625 +2099 -0.218109130859375 +2100 -0.16986083984375 +2101 -0.22833251953125 +2102 -0.177459716796875 +2103 -0.238525390625 +2104 -0.18499755859375 +2105 -0.2486572265625 +2106 -0.192535400390625 +2107 -0.2587890625 +2108 -0.200042724609375 +2109 -0.268890380859375 +2110 -0.207550048828125 +2111 -0.278961181640625 +2112 -0.214996337890625 +2113 -0.28900146484375 +2114 -0.222442626953125 +2115 -0.29901123046875 +2116 -0.229888916015625 +2117 -0.308990478515625 +2118 -0.237274169921875 +2119 -0.318939208984375 +2120 -0.24462890625 +2121 -0.328826904296875 +2122 -0.251983642578125 +2123 -0.338714599609375 +2124 -0.259307861328125 +2125 -0.348541259765625 +2126 -0.2666015625 +2127 -0.35833740234375 +2128 -0.27386474609375 +2129 -0.36810302734375 +2130 -0.28106689453125 +2131 -0.3778076171875 +2132 -0.28826904296875 +2133 -0.387481689453125 +2134 -0.295440673828125 +2135 -0.397125244140625 +2136 -0.302581787109375 +2137 -0.406707763671875 +2138 -0.3096923828125 +2139 -0.416259765625 +2140 -0.316741943359375 +2141 -0.425750732421875 +2142 -0.32379150390625 +2143 -0.435211181640625 +2144 -0.330780029296875 +2145 -0.444610595703125 +2146 -0.337738037109375 +2147 -0.453948974609375 +2148 -0.34466552734375 +2149 -0.4632568359375 +2150 -0.3515625 +2151 -0.4725341796875 +2152 -0.3583984375 +2153 -0.481719970703125 +2154 -0.365203857421875 +2155 -0.490875244140625 +2156 -0.371978759765625 +2157 -0.499969482421875 +2158 -0.378692626953125 +2159 -0.509002685546875 +2160 -0.3853759765625 +2161 -0.51800537109375 +2162 -0.39202880859375 +2163 -0.52691650390625 +2164 -0.39862060546875 +2165 -0.535797119140625 +2166 -0.405181884765625 +2167 -0.54461669921875 +2168 -0.41168212890625 +2169 -0.5533447265625 +2170 -0.41815185546875 +2171 -0.562042236328125 +2172 -0.424591064453125 +2173 -0.5706787109375 +2174 -0.43096923828125 +2175 -0.579254150390625 +2176 -0.437255859375 +2177 -0.587738037109375 +2178 -0.44354248046875 +2179 -0.59619140625 +2180 -0.44976806640625 +2181 -0.60455322265625 +2182 -0.455963134765625 +2183 -0.612884521484375 +2184 -0.46209716796875 +2185 -0.621124267578125 +2186 -0.468170166015625 +2187 -0.6292724609375 +2188 -0.474212646484375 +2189 -0.63739013671875 +2190 -0.480194091796875 +2191 -0.645416259765625 +2192 -0.486114501953125 +2193 -0.65338134765625 +2194 -0.491973876953125 +2195 -0.661285400390625 +2196 -0.497802734375 +2197 -0.669097900390625 +2198 -0.503570556640625 +2199 -0.676849365234375 +2200 -0.50927734375 +2201 -0.68450927734375 +2202 -0.514923095703125 +2203 -0.692108154296875 +2204 -0.5205078125 +2205 -0.699615478515625 +2206 -0.526031494140625 +2207 -0.707061767578125 +2208 -0.53155517578125 +2209 -0.714447021484375 +2210 -0.536956787109375 +2211 -0.721710205078125 +2212 -0.542327880859375 +2213 -0.72894287109375 +2214 -0.547607421875 +2215 -0.736053466796875 +2216 -0.5528564453125 +2217 -0.74310302734375 +2218 -0.55804443359375 +2219 -0.75006103515625 +2220 -0.56317138671875 +2221 -0.7569580078125 +2222 -0.5682373046875 +2223 -0.763763427734375 +2224 -0.5732421875 +2225 -0.770477294921875 +2226 -0.578155517578125 +2227 -0.777099609375 +2228 -0.583038330078125 +2229 -0.783660888671875 +2230 -0.587860107421875 +2231 -0.790130615234375 +2232 -0.592559814453125 +2233 -0.796478271484375 +2234 -0.597259521484375 +2235 -0.802764892578125 +2236 -0.60186767578125 +2237 -0.808990478515625 +2238 -0.606414794921875 +2239 -0.815093994140625 +2240 -0.61090087890625 +2241 -0.82110595703125 +2242 -0.61529541015625 +2243 -0.8270263671875 +2244 -0.619659423828125 +2245 -0.8328857421875 +2246 -0.623931884765625 +2247 -0.838623046875 +2248 -0.628143310546875 +2249 -0.84429931640625 +2250 -0.632293701171875 +2251 -0.849853515625 +2252 -0.6363525390625 +2253 -0.855316162109375 +2254 -0.640350341796875 +2255 -0.860687255859375 +2256 -0.644287109375 +2257 -0.865997314453125 +2258 -0.648162841796875 +2259 -0.871185302734375 +2260 -0.65191650390625 +2261 -0.876251220703125 +2262 -0.6556396484375 +2263 -0.881256103515625 +2264 -0.6593017578125 +2265 -0.88616943359375 +2266 -0.662872314453125 +2267 -0.890960693359375 +2268 -0.666351318359375 +2269 -0.895660400390625 +2270 -0.6697998046875 +2271 -0.9002685546875 +2272 -0.67315673828125 +2273 -0.90478515625 +2274 -0.676422119140625 +2275 -0.9091796875 +2276 -0.679656982421875 +2277 -0.91351318359375 +2278 -0.682769775390625 +2279 -0.917724609375 +2280 -0.685821533203125 +2281 -0.92181396484375 +2282 -0.688812255859375 +2283 -0.92584228515625 +2284 -0.69171142578125 +2285 -0.929718017578125 +2286 -0.694549560546875 +2287 -0.93353271484375 +2288 -0.697296142578125 +2289 -0.937225341796875 +2290 -0.699981689453125 +2291 -0.940826416015625 +2292 -0.70257568359375 +2293 -0.9443359375 +2294 -0.705108642578125 +2295 -0.947723388671875 +2296 -0.707550048828125 +2297 -0.951019287109375 +2298 -0.70989990234375 +2299 -0.954193115234375 +2300 -0.71221923828125 +2301 -0.957275390625 +2302 -0.71441650390625 +2303 -0.960235595703125 +2304 -0.685699462890625 +2305 -0.963104248046875 +2306 -0.68768310546875 +2307 -0.96588134765625 +2308 -0.6895751953125 +2309 -0.968536376953125 +2310 -0.69140625 +2311 -0.971099853515625 +2312 -0.693145751953125 +2313 -0.973541259765625 +2314 -0.694793701171875 +2315 -0.975860595703125 +2316 -0.696380615234375 +2317 -0.97808837890625 +2318 -0.697906494140625 +2319 -0.980224609375 +2320 -0.6993408203125 +2321 -0.98223876953125 +2322 -0.700714111328125 +2323 -0.984161376953125 +2324 -0.701995849609375 +2325 -0.9859619140625 +2326 -0.70318603515625 +2327 -0.987640380859375 +2328 -0.704315185546875 +2329 -0.989227294921875 +2330 -0.705352783203125 +2331 -0.990692138671875 +2332 -0.706329345703125 +2333 -0.9920654296875 +2334 -0.70721435546875 +2335 -0.993316650390625 +2336 -0.708038330078125 +2337 -0.994476318359375 +2338 -0.70880126953125 +2339 -0.995513916015625 +2340 -0.70947265625 +2341 -0.9964599609375 +2342 -0.710052490234375 +2343 -0.997283935546875 +2344 -0.710540771484375 +2345 -0.99798583984375 +2346 -0.710968017578125 +2347 -0.99859619140625 +2348 -0.711334228515625 +2349 -0.999114990234375 +2350 -0.711578369140625 +2351 -0.999481201171875 +2352 -0.7117919921875 +2353 -0.999755859375 +2354 -0.7119140625 +2355 -0.99993896484375 +2356 -0.71197509765625 +2357 -1.0 +2358 -0.7119140625 +2359 -0.99993896484375 +2360 -0.7117919921875 +2361 -0.999755859375 +2362 -0.711578369140625 +2363 -0.999481201171875 +2364 -0.711334228515625 +2365 -0.999114990234375 +2366 -0.710968017578125 +2367 -0.99859619140625 +2368 -0.710540771484375 +2369 -0.99798583984375 +2370 -0.710052490234375 +2371 -0.997283935546875 +2372 -0.70947265625 +2373 -0.9964599609375 +2374 -0.70880126953125 +2375 -0.995513916015625 +2376 -0.708038330078125 +2377 -0.994476318359375 +2378 -0.70721435546875 +2379 -0.993316650390625 +2380 -0.706329345703125 +2381 -0.9920654296875 +2382 -0.705352783203125 +2383 -0.990692138671875 +2384 -0.704315185546875 +2385 -0.989227294921875 +2386 -0.70318603515625 +2387 -0.987640380859375 +2388 -0.701995849609375 +2389 -0.9859619140625 +2390 -0.700714111328125 +2391 -0.984161376953125 +2392 -0.6993408203125 +2393 -0.98223876953125 +2394 -0.697906494140625 +2395 -0.980224609375 +2396 -0.696380615234375 +2397 -0.97808837890625 +2398 -0.694793701171875 +2399 -0.975860595703125 +2400 -0.693145751953125 +2401 -0.973541259765625 +2402 -0.69140625 +2403 -0.971099853515625 +2404 -0.6895751953125 +2405 -0.968536376953125 +2406 -0.68768310546875 +2407 -0.96588134765625 +2408 -0.685699462890625 +2409 -0.963104248046875 +2410 -0.68365478515625 +2411 -0.960235595703125 +2412 -0.681549072265625 +2413 -0.957275390625 +2414 -0.67938232421875 +2415 -0.954193115234375 +2416 -0.677093505859375 +2417 -0.951019287109375 +2418 -0.674774169921875 +2419 -0.947723388671875 +2420 -0.67236328125 +2421 -0.9443359375 +2422 -0.66986083984375 +2423 -0.940826416015625 +2424 -0.66729736328125 +2425 -0.937225341796875 +2426 -0.664642333984375 +2427 -0.93353271484375 +2428 -0.66192626953125 +2429 -0.929718017578125 +2430 -0.6591796875 +2431 -0.92584228515625 +2432 -0.65631103515625 +2433 -0.92181396484375 +2434 -0.653411865234375 +2435 -0.917724609375 +2436 -0.650390625 +2437 -0.91351318359375 +2438 -0.647308349609375 +2439 -0.9091796875 +2440 -0.644195556640625 +2441 -0.90478515625 +2442 -0.640960693359375 +2443 -0.9002685546875 +2444 -0.6376953125 +2445 -0.895660400390625 +2446 -0.63433837890625 +2447 -0.890960693359375 +2448 -0.63092041015625 +2449 -0.88616943359375 +2450 -0.62744140625 +2451 -0.881256103515625 +2452 -0.623870849609375 +2453 -0.876251220703125 +2454 -0.620269775390625 +2455 -0.871185302734375 +2456 -0.6165771484375 +2457 -0.865997314453125 +2458 -0.61279296875 +2459 -0.860687255859375 +2460 -0.608978271484375 +2461 -0.855316162109375 +2462 -0.605072021484375 +2463 -0.849853515625 +2464 -0.60113525390625 +2465 -0.84429931640625 +2466 -0.597076416015625 +2467 -0.838623046875 +2468 -0.592987060546875 +2469 -0.8328857421875 +2470 -0.588836669921875 +2471 -0.8270263671875 +2472 -0.5845947265625 +2473 -0.82110595703125 +2474 -0.580322265625 +2475 -0.815093994140625 +2476 -0.57598876953125 +2477 -0.808990478515625 +2478 -0.571563720703125 +2479 -0.802764892578125 +2480 -0.56707763671875 +2481 -0.796478271484375 +2482 -0.56256103515625 +2483 -0.790130615234375 +2484 -0.557952880859375 +2485 -0.783660888671875 +2486 -0.55328369140625 +2487 -0.777099609375 +2488 -0.548553466796875 +2489 -0.770477294921875 +2490 -0.543792724609375 +2491 -0.763763427734375 +2492 -0.5389404296875 +2493 -0.7569580078125 +2494 -0.534027099609375 +2495 -0.75006103515625 +2496 -0.529083251953125 +2497 -0.74310302734375 +2498 -0.5240478515625 +2499 -0.736053466796875 +2500 -0.51898193359375 +2501 -0.72894287109375 +2502 -0.51385498046875 +2503 -0.721710205078125 +2504 -0.5086669921875 +2505 -0.714447021484375 +2506 -0.50341796875 +2507 -0.707061767578125 +2508 -0.49810791015625 +2509 -0.699615478515625 +2510 -0.492767333984375 +2511 -0.692108154296875 +2512 -0.48736572265625 +2513 -0.68450927734375 +2514 -0.481903076171875 +2515 -0.676849365234375 +2516 -0.47637939453125 +2517 -0.669097900390625 +2518 -0.4708251953125 +2519 -0.661285400390625 +2520 -0.465179443359375 +2521 -0.65338134765625 +2522 -0.45953369140625 +2523 -0.645416259765625 +2524 -0.45379638671875 +2525 -0.63739013671875 +2526 -0.448028564453125 +2527 -0.6292724609375 +2528 -0.442230224609375 +2529 -0.621124267578125 +2530 -0.436370849609375 +2531 -0.612884521484375 +2532 -0.430419921875 +2533 -0.60455322265625 +2534 -0.424468994140625 +2535 -0.59619140625 +2536 -0.41845703125 +2537 -0.587738037109375 +2538 -0.41241455078125 +2539 -0.579254150390625 +2540 -0.40631103515625 +2541 -0.5706787109375 +2542 -0.400146484375 +2543 -0.562042236328125 +2544 -0.393951416015625 +2545 -0.5533447265625 +2546 -0.38775634765625 +2547 -0.54461669921875 +2548 -0.3814697265625 +2549 -0.535797119140625 +2550 -0.375152587890625 +2551 -0.52691650390625 +2552 -0.368804931640625 +2553 -0.51800537109375 +2554 -0.362396240234375 +2555 -0.509002685546875 +2556 -0.35595703125 +2557 -0.499969482421875 +2558 -0.3494873046875 +2559 -0.490875244140625 +2560 -0.337188720703125 +2561 -0.481719970703125 +2562 -0.33074951171875 +2563 -0.4725341796875 +2564 -0.32427978515625 +2565 -0.4632568359375 +2566 -0.3177490234375 +2567 -0.453948974609375 +2568 -0.31121826171875 +2569 -0.444610595703125 +2570 -0.30462646484375 +2571 -0.435211181640625 +2572 -0.298004150390625 +2573 -0.425750732421875 +2574 -0.2913818359375 +2575 -0.416259765625 +2576 -0.28466796875 +2577 -0.406707763671875 +2578 -0.277984619140625 +2579 -0.397125244140625 +2580 -0.271209716796875 +2581 -0.387481689453125 +2582 -0.26446533203125 +2583 -0.3778076171875 +2584 -0.257659912109375 +2585 -0.36810302734375 +2586 -0.250823974609375 +2587 -0.35833740234375 +2588 -0.24395751953125 +2589 -0.348541259765625 +2590 -0.237091064453125 +2591 -0.338714599609375 +2592 -0.23016357421875 +2593 -0.328826904296875 +2594 -0.223236083984375 +2595 -0.318939208984375 +2596 -0.216278076171875 +2597 -0.308990478515625 +2598 -0.20928955078125 +2599 -0.29901123046875 +2600 -0.202301025390625 +2601 -0.28900146484375 +2602 -0.19525146484375 +2603 -0.278961181640625 +2604 -0.188201904296875 +2605 -0.268890380859375 +2606 -0.18115234375 +2607 -0.2587890625 +2608 -0.174041748046875 +2609 -0.2486572265625 +2610 -0.166961669921875 +2611 -0.238525390625 +2612 -0.159820556640625 +2613 -0.22833251953125 +2614 -0.15264892578125 +2615 -0.218109130859375 +2616 -0.1455078125 +2617 -0.2078857421875 +2618 -0.138336181640625 +2619 -0.1976318359375 +2620 -0.131134033203125 +2621 -0.187347412109375 +2622 -0.123931884765625 +2623 -0.17706298828125 +2624 -0.11669921875 +2625 -0.166748046875 +2626 -0.109466552734375 +2627 -0.156402587890625 +2628 -0.10223388671875 +2629 -0.14605712890625 +2630 -0.094970703125 +2631 -0.13568115234375 +2632 -0.08770751953125 +2633 -0.12530517578125 +2634 -0.0804443359375 +2635 -0.11492919921875 +2636 -0.073150634765625 +2637 -0.104522705078125 +2638 -0.06585693359375 +2639 -0.094085693359375 +2640 -0.05853271484375 +2641 -0.083648681640625 +2642 -0.051239013671875 +2643 -0.073211669921875 +2644 -0.043914794921875 +2645 -0.062774658203125 +2646 -0.036590576171875 +2647 -0.05230712890625 +2648 -0.029296875 +2649 -0.0418701171875 +2650 -0.02197265625 +2651 -0.031402587890625 +2652 -0.0146484375 +2653 -0.02093505859375 +2654 -0.00732421875 +2655 -0.010467529296875 +2656 0.0 +2657 0.0 +2658 0.007110595703125 +2659 0.010467529296875 +2660 0.01422119140625 +2661 0.02093505859375 +2662 0.021331787109375 +2663 0.031402587890625 +2664 0.0284423828125 +2665 0.0418701171875 +2666 0.035552978515625 +2667 0.05230712890625 +2668 0.04266357421875 +2669 0.062774658203125 +2670 0.049774169921875 +2671 0.073211669921875 +2672 0.056854248046875 +2673 0.083648681640625 +2674 0.06396484375 +2675 0.094085693359375 +2676 0.071075439453125 +2677 0.104522705078125 +2678 0.078125 +2679 0.11492919921875 +2680 0.085205078125 +2681 0.12530517578125 +2682 0.092254638671875 +2683 0.13568115234375 +2684 0.09930419921875 +2685 0.14605712890625 +2686 0.106353759765625 +2687 0.156402587890625 +2688 0.113372802734375 +2689 0.166748046875 +2690 0.120391845703125 +2691 0.17706298828125 +2692 0.12738037109375 +2693 0.187347412109375 +2694 0.134368896484375 +2695 0.1976318359375 +2696 0.141357421875 +2697 0.2078857421875 +2698 0.1483154296875 +2699 0.218109130859375 +2700 0.155242919921875 +2701 0.22833251953125 +2702 0.16217041015625 +2703 0.238525390625 +2704 0.1690673828125 +2705 0.2486572265625 +2706 0.17596435546875 +2707 0.2587890625 +2708 0.182830810546875 +2709 0.268890380859375 +2710 0.189697265625 +2711 0.278961181640625 +2712 0.196502685546875 +2713 0.28900146484375 +2714 0.20330810546875 +2715 0.29901123046875 +2716 0.210113525390625 +2717 0.308990478515625 +2718 0.21685791015625 +2719 0.318939208984375 +2720 0.223602294921875 +2721 0.328826904296875 +2722 0.230316162109375 +2723 0.338714599609375 +2724 0.23699951171875 +2725 0.348541259765625 +2726 0.24365234375 +2727 0.35833740234375 +2728 0.25030517578125 +2729 0.36810302734375 +2730 0.25689697265625 +2731 0.3778076171875 +2732 0.26348876953125 +2733 0.387481689453125 +2734 0.270050048828125 +2735 0.397125244140625 +2736 0.27655029296875 +2737 0.406707763671875 +2738 0.283050537109375 +2739 0.416259765625 +2740 0.28948974609375 +2741 0.425750732421875 +2742 0.295928955078125 +2743 0.435211181640625 +2744 0.302337646484375 +2745 0.444610595703125 +2746 0.308685302734375 +2747 0.453948974609375 +2748 0.31500244140625 +2749 0.4632568359375 +2750 0.321319580078125 +2751 0.4725341796875 +2752 0.32757568359375 +2753 0.481719970703125 +2754 0.33380126953125 +2755 0.490875244140625 +2756 0.3399658203125 +2757 0.499969482421875 +2758 0.346099853515625 +2759 0.509002685546875 +2760 0.35223388671875 +2761 0.51800537109375 +2762 0.358306884765625 +2763 0.52691650390625 +2764 0.36431884765625 +2765 0.535797119140625 +2766 0.370330810546875 +2767 0.54461669921875 +2768 0.37628173828125 +2769 0.5533447265625 +2770 0.382171630859375 +2771 0.562042236328125 +2772 0.3880615234375 +2773 0.5706787109375 +2774 0.393890380859375 +2775 0.579254150390625 +2776 0.399658203125 +2777 0.587738037109375 +2778 0.4053955078125 +2779 0.59619140625 +2780 0.411102294921875 +2781 0.60455322265625 +2782 0.416748046875 +2783 0.612884521484375 +2784 0.42236328125 +2785 0.621124267578125 +2786 0.427886962890625 +2787 0.6292724609375 +2788 0.43341064453125 +2789 0.63739013671875 +2790 0.438873291015625 +2791 0.645416259765625 +2792 0.444305419921875 +2793 0.65338134765625 +2794 0.449676513671875 +2795 0.661285400390625 +2796 0.454986572265625 +2797 0.669097900390625 +2798 0.46026611328125 +2799 0.676849365234375 +2800 0.4654541015625 +2801 0.68450927734375 +2802 0.47064208984375 +2803 0.692108154296875 +2804 0.475738525390625 +2805 0.699615478515625 +2806 0.480804443359375 +2807 0.707061767578125 +2808 0.485809326171875 +2809 0.714447021484375 +2810 0.490753173828125 +2811 0.721710205078125 +2812 0.49566650390625 +2813 0.72894287109375 +2814 0.500518798828125 +2815 0.736053466796875 +2816 0.48150634765625 +2817 0.74310302734375 +2818 0.48602294921875 +2819 0.75006103515625 +2820 0.490478515625 +2821 0.7569580078125 +2822 0.494903564453125 +2823 0.763763427734375 +2824 0.499267578125 +2825 0.770477294921875 +2826 0.5035400390625 +2827 0.777099609375 +2828 0.507781982421875 +2829 0.783660888671875 +2830 0.511993408203125 +2831 0.790130615234375 +2832 0.51611328125 +2833 0.796478271484375 +2834 0.520172119140625 +2835 0.802764892578125 +2836 0.524200439453125 +2837 0.808990478515625 +2838 0.528167724609375 +2839 0.815093994140625 +2840 0.532073974609375 +2841 0.82110595703125 +2842 0.535888671875 +2843 0.8270263671875 +2844 0.539703369140625 +2845 0.8328857421875 +2846 0.543426513671875 +2847 0.838623046875 +2848 0.547088623046875 +2849 0.84429931640625 +2850 0.550689697265625 +2851 0.849853515625 +2852 0.554229736328125 +2853 0.855316162109375 +2854 0.557708740234375 +2855 0.860687255859375 +2856 0.5611572265625 +2857 0.865997314453125 +2858 0.56451416015625 +2859 0.871185302734375 +2860 0.56781005859375 +2861 0.876251220703125 +2862 0.571044921875 +2863 0.881256103515625 +2864 0.57421875 +2865 0.88616943359375 +2866 0.57733154296875 +2867 0.890960693359375 +2868 0.58038330078125 +2869 0.895660400390625 +2870 0.583343505859375 +2871 0.9002685546875 +2872 0.586273193359375 +2873 0.90478515625 +2874 0.589141845703125 +2875 0.9091796875 +2876 0.591949462890625 +2877 0.91351318359375 +2878 0.59466552734375 +2879 0.917724609375 +2880 0.597320556640625 +2881 0.92181396484375 +2882 0.599945068359375 +2883 0.92584228515625 +2884 0.602447509765625 +2885 0.929718017578125 +2886 0.60491943359375 +2887 0.93353271484375 +2888 0.6072998046875 +2889 0.937225341796875 +2890 0.609649658203125 +2891 0.940826416015625 +2892 0.611907958984375 +2893 0.9443359375 +2894 0.614105224609375 +2895 0.947723388671875 +2896 0.616241455078125 +2897 0.951019287109375 +2898 0.618316650390625 +2899 0.954193115234375 +2900 0.62030029296875 +2901 0.957275390625 +2902 0.622222900390625 +2903 0.960235595703125 +2904 0.62408447265625 +2905 0.963104248046875 +2906 0.625885009765625 +2907 0.96588134765625 +2908 0.627593994140625 +2909 0.968536376953125 +2910 0.629241943359375 +2911 0.971099853515625 +2912 0.630828857421875 +2913 0.973541259765625 +2914 0.632354736328125 +2915 0.975860595703125 +2916 0.6337890625 +2917 0.97808837890625 +2918 0.635162353515625 +2919 0.980224609375 +2920 0.636474609375 +2921 0.98223876953125 +2922 0.637725830078125 +2923 0.984161376953125 +2924 0.638885498046875 +2925 0.9859619140625 +2926 0.639984130859375 +2927 0.987640380859375 +2928 0.6409912109375 +2929 0.989227294921875 +2930 0.6419677734375 +2931 0.990692138671875 +2932 0.642852783203125 +2933 0.9920654296875 +2934 0.643646240234375 +2935 0.993316650390625 +2936 0.6444091796875 +2937 0.994476318359375 +2938 0.64508056640625 +2939 0.995513916015625 +2940 0.64569091796875 +2941 0.9964599609375 +2942 0.646209716796875 +2943 0.997283935546875 +2944 0.64666748046875 +2945 0.99798583984375 +2946 0.647064208984375 +2947 0.99859619140625 +2948 0.64739990234375 +2949 0.999114990234375 +2950 0.647613525390625 +2951 0.999481201171875 +2952 0.647796630859375 +2953 0.999755859375 +2954 0.647918701171875 +2955 0.99993896484375 +2956 0.647979736328125 +2957 0.999969482421875 +2958 0.647918701171875 +2959 0.99993896484375 +2960 0.647796630859375 +2961 0.999755859375 +2962 0.647613525390625 +2963 0.999481201171875 +2964 0.64739990234375 +2965 0.999114990234375 +2966 0.647064208984375 +2967 0.99859619140625 +2968 0.64666748046875 +2969 0.99798583984375 +2970 0.646209716796875 +2971 0.997283935546875 +2972 0.64569091796875 +2973 0.9964599609375 +2974 0.64508056640625 +2975 0.995513916015625 +2976 0.6444091796875 +2977 0.994476318359375 +2978 0.643646240234375 +2979 0.993316650390625 +2980 0.642852783203125 +2981 0.9920654296875 +2982 0.6419677734375 +2983 0.990692138671875 +2984 0.6409912109375 +2985 0.989227294921875 +2986 0.639984130859375 +2987 0.987640380859375 +2988 0.638885498046875 +2989 0.9859619140625 +2990 0.637725830078125 +2991 0.984161376953125 +2992 0.636474609375 +2993 0.98223876953125 +2994 0.635162353515625 +2995 0.980224609375 +2996 0.6337890625 +2997 0.97808837890625 +2998 0.632354736328125 +2999 0.975860595703125 +3000 0.630828857421875 +3001 0.973541259765625 +3002 0.629241943359375 +3003 0.971099853515625 +3004 0.627593994140625 +3005 0.968536376953125 +3006 0.625885009765625 +3007 0.96588134765625 +3008 0.62408447265625 +3009 0.963104248046875 +3010 0.622222900390625 +3011 0.960235595703125 +3012 0.62030029296875 +3013 0.957275390625 +3014 0.618316650390625 +3015 0.954193115234375 +3016 0.616241455078125 +3017 0.951019287109375 +3018 0.614105224609375 +3019 0.947723388671875 +3020 0.611907958984375 +3021 0.9443359375 +3022 0.609649658203125 +3023 0.940826416015625 +3024 0.6072998046875 +3025 0.937225341796875 +3026 0.60491943359375 +3027 0.93353271484375 +3028 0.602447509765625 +3029 0.929718017578125 +3030 0.599945068359375 +3031 0.92584228515625 +3032 0.597320556640625 +3033 0.92181396484375 +3034 0.59466552734375 +3035 0.917724609375 +3036 0.591949462890625 +3037 0.91351318359375 +3038 0.589141845703125 +3039 0.9091796875 +3040 0.586273193359375 +3041 0.90478515625 +3042 0.583343505859375 +3043 0.9002685546875 +3044 0.58038330078125 +3045 0.895660400390625 +3046 0.57733154296875 +3047 0.890960693359375 +3048 0.57421875 +3049 0.88616943359375 +3050 0.571044921875 +3051 0.881256103515625 +3052 0.56781005859375 +3053 0.876251220703125 +3054 0.56451416015625 +3055 0.871185302734375 +3056 0.5611572265625 +3057 0.865997314453125 +3058 0.557708740234375 +3059 0.860687255859375 +3060 0.554229736328125 +3061 0.855316162109375 +3062 0.550689697265625 +3063 0.849853515625 +3064 0.547088623046875 +3065 0.84429931640625 +3066 0.543426513671875 +3067 0.838623046875 +3068 0.539703369140625 +3069 0.8328857421875 +3070 0.535888671875 +3071 0.8270263671875 +3072 0.505767822265625 +3073 0.82110595703125 +3074 0.5020751953125 +3075 0.815093994140625 +3076 0.498321533203125 +3077 0.808990478515625 +3078 0.494476318359375 +3079 0.802764892578125 +3080 0.4906005859375 +3081 0.796478271484375 +3082 0.4866943359375 +3083 0.790130615234375 +3084 0.482696533203125 +3085 0.783660888671875 +3086 0.478668212890625 +3087 0.777099609375 +3088 0.474578857421875 +3089 0.770477294921875 +3090 0.470458984375 +3091 0.763763427734375 +3092 0.46624755859375 +3093 0.7569580078125 +3094 0.462005615234375 +3095 0.75006103515625 +3096 0.457733154296875 +3097 0.74310302734375 +3098 0.453369140625 +3099 0.736053466796875 +3100 0.449005126953125 +3101 0.72894287109375 +3102 0.444549560546875 +3103 0.721710205078125 +3104 0.4400634765625 +3105 0.714447021484375 +3106 0.435516357421875 +3107 0.707061767578125 +3108 0.430938720703125 +3109 0.699615478515625 +3110 0.426300048828125 +3111 0.692108154296875 +3112 0.421630859375 +3113 0.68450927734375 +3114 0.416900634765625 +3115 0.676849365234375 +3116 0.412139892578125 +3117 0.669097900390625 +3118 0.407318115234375 +3119 0.661285400390625 +3120 0.4024658203125 +3121 0.65338134765625 +3122 0.397552490234375 +3123 0.645416259765625 +3124 0.392608642578125 +3125 0.63739013671875 +3126 0.387603759765625 +3127 0.6292724609375 +3128 0.382598876953125 +3129 0.621124267578125 +3130 0.37750244140625 +3131 0.612884521484375 +3132 0.37237548828125 +3133 0.60455322265625 +3134 0.367218017578125 +3135 0.59619140625 +3136 0.362030029296875 +3137 0.587738037109375 +3138 0.3568115234375 +3139 0.579254150390625 +3140 0.35150146484375 +3141 0.5706787109375 +3142 0.34619140625 +3143 0.562042236328125 +3144 0.340850830078125 +3145 0.5533447265625 +3146 0.33544921875 +3147 0.54461669921875 +3148 0.33001708984375 +3149 0.535797119140625 +3150 0.324554443359375 +3151 0.52691650390625 +3152 0.319061279296875 +3153 0.51800537109375 +3154 0.31353759765625 +3155 0.509002685546875 +3156 0.307952880859375 +3157 0.499969482421875 +3158 0.3023681640625 +3159 0.490875244140625 +3160 0.296722412109375 +3161 0.481719970703125 +3162 0.291046142578125 +3163 0.4725341796875 +3164 0.28533935546875 +3165 0.4632568359375 +3166 0.27960205078125 +3167 0.453948974609375 +3168 0.27386474609375 +3169 0.444610595703125 +3170 0.26806640625 +3171 0.435211181640625 +3172 0.262237548828125 +3173 0.425750732421875 +3174 0.25640869140625 +3175 0.416259765625 +3176 0.250518798828125 +3177 0.406707763671875 +3178 0.244598388671875 +3179 0.397125244140625 +3180 0.238677978515625 +3181 0.387481689453125 +3182 0.232696533203125 +3183 0.3778076171875 +3184 0.22674560546875 +3185 0.36810302734375 +3186 0.220703125 +3187 0.35833740234375 +3188 0.214691162109375 +3189 0.348541259765625 +3190 0.2086181640625 +3191 0.338714599609375 +3192 0.202545166015625 +3193 0.328826904296875 +3194 0.196441650390625 +3195 0.318939208984375 +3196 0.1903076171875 +3197 0.308990478515625 +3198 0.184173583984375 +3199 0.29901123046875 +3200 0.178009033203125 +3201 0.28900146484375 +3202 0.17181396484375 +3203 0.278961181640625 +3204 0.165618896484375 +3205 0.268890380859375 +3206 0.159393310546875 +3207 0.2587890625 +3208 0.153167724609375 +3209 0.2486572265625 +3210 0.14691162109375 +3211 0.238525390625 +3212 0.140625 +3213 0.22833251953125 +3214 0.13433837890625 +3215 0.218109130859375 +3216 0.1280517578125 +3217 0.2078857421875 +3218 0.121734619140625 +3219 0.1976318359375 +3220 0.115386962890625 +3221 0.187347412109375 +3222 0.109039306640625 +3223 0.17706298828125 +3224 0.102691650390625 +3225 0.166748046875 +3226 0.0963134765625 +3227 0.156402587890625 +3228 0.0899658203125 +3229 0.14605712890625 +3230 0.08355712890625 +3231 0.13568115234375 +3232 0.077178955078125 +3233 0.12530517578125 +3234 0.070770263671875 +3235 0.11492919921875 +3236 0.064361572265625 +3237 0.104522705078125 +3238 0.057952880859375 +3239 0.094085693359375 +3240 0.051513671875 +3241 0.083648681640625 +3242 0.045074462890625 +3243 0.073211669921875 +3244 0.038665771484375 +3245 0.062774658203125 +3246 0.032196044921875 +3247 0.05230712890625 +3248 0.025787353515625 +3249 0.0418701171875 +3250 0.019317626953125 +3251 0.031402587890625 +3252 0.01287841796875 +3253 0.02093505859375 +3254 0.006439208984375 +3255 0.010467529296875 +3256 0.0 +3257 0.0 +3258 -0.006439208984375 +3259 -0.010467529296875 +3260 -0.01287841796875 +3261 -0.02093505859375 +3262 -0.019317626953125 +3263 -0.031402587890625 +3264 -0.025787353515625 +3265 -0.0418701171875 +3266 -0.032196044921875 +3267 -0.05230712890625 +3268 -0.038665771484375 +3269 -0.062774658203125 +3270 -0.045074462890625 +3271 -0.073211669921875 +3272 -0.051513671875 +3273 -0.083648681640625 +3274 -0.057952880859375 +3275 -0.094085693359375 +3276 -0.064361572265625 +3277 -0.104522705078125 +3278 -0.070770263671875 +3279 -0.11492919921875 +3280 -0.077178955078125 +3281 -0.12530517578125 +3282 -0.08355712890625 +3283 -0.13568115234375 +3284 -0.0899658203125 +3285 -0.14605712890625 +3286 -0.0963134765625 +3287 -0.156402587890625 +3288 -0.102691650390625 +3289 -0.166748046875 +3290 -0.109039306640625 +3291 -0.17706298828125 +3292 -0.115386962890625 +3293 -0.187347412109375 +3294 -0.121734619140625 +3295 -0.1976318359375 +3296 -0.1280517578125 +3297 -0.2078857421875 +3298 -0.13433837890625 +3299 -0.218109130859375 +3300 -0.140625 +3301 -0.22833251953125 +3302 -0.14691162109375 +3303 -0.238525390625 +3304 -0.153167724609375 +3305 -0.2486572265625 +3306 -0.159393310546875 +3307 -0.2587890625 +3308 -0.165618896484375 +3309 -0.268890380859375 +3310 -0.17181396484375 +3311 -0.278961181640625 +3312 -0.178009033203125 +3313 -0.28900146484375 +3314 -0.184173583984375 +3315 -0.29901123046875 +3316 -0.1903076171875 +3317 -0.308990478515625 +3318 -0.196441650390625 +3319 -0.318939208984375 +3320 -0.202545166015625 +3321 -0.328826904296875 +3322 -0.2086181640625 +3323 -0.338714599609375 +3324 -0.214691162109375 +3325 -0.348541259765625 +3326 -0.220703125 +3327 -0.35833740234375 +3328 -0.2149658203125 +3329 -0.36810302734375 +3330 -0.220611572265625 +3331 -0.3778076171875 +3332 -0.226287841796875 +3333 -0.387481689453125 +3334 -0.231903076171875 +3335 -0.397125244140625 +3336 -0.23748779296875 +3337 -0.406707763671875 +3338 -0.243072509765625 +3339 -0.416259765625 +3340 -0.248626708984375 +3341 -0.425750732421875 +3342 -0.254150390625 +3343 -0.435211181640625 +3344 -0.2596435546875 +3345 -0.444610595703125 +3346 -0.265106201171875 +3347 -0.453948974609375 +3348 -0.270538330078125 +3349 -0.4632568359375 +3350 -0.27593994140625 +3351 -0.4725341796875 +3352 -0.28131103515625 +3353 -0.481719970703125 +3354 -0.286651611328125 +3355 -0.490875244140625 +3356 -0.291961669921875 +3357 -0.499969482421875 +3358 -0.2972412109375 +3359 -0.509002685546875 +3360 -0.302490234375 +3361 -0.51800537109375 +3362 -0.307708740234375 +3363 -0.52691650390625 +3364 -0.312896728515625 +3365 -0.535797119140625 +3366 -0.31805419921875 +3367 -0.54461669921875 +3368 -0.323150634765625 +3369 -0.5533447265625 +3370 -0.328216552734375 +3371 -0.562042236328125 +3372 -0.333251953125 +3373 -0.5706787109375 +3374 -0.3382568359375 +3375 -0.579254150390625 +3376 -0.343231201171875 +3377 -0.587738037109375 +3378 -0.348175048828125 +3379 -0.59619140625 +3380 -0.353057861328125 +3381 -0.60455322265625 +3382 -0.35791015625 +3383 -0.612884521484375 +3384 -0.36273193359375 +3385 -0.621124267578125 +3386 -0.36749267578125 +3387 -0.6292724609375 +3388 -0.372222900390625 +3389 -0.63739013671875 +3390 -0.376922607421875 +3391 -0.645416259765625 +3392 -0.381561279296875 +3393 -0.65338134765625 +3394 -0.38616943359375 +3395 -0.661285400390625 +3396 -0.3907470703125 +3397 -0.669097900390625 +3398 -0.395263671875 +3399 -0.676849365234375 +3400 -0.399749755859375 +3401 -0.68450927734375 +3402 -0.4041748046875 +3403 -0.692108154296875 +3404 -0.4085693359375 +3405 -0.699615478515625 +3406 -0.41290283203125 +3407 -0.707061767578125 +3408 -0.417236328125 +3409 -0.714447021484375 +3410 -0.421478271484375 +3411 -0.721710205078125 +3412 -0.425689697265625 +3413 -0.72894287109375 +3414 -0.429840087890625 +3415 -0.736053466796875 +3416 -0.4339599609375 +3417 -0.74310302734375 +3418 -0.438018798828125 +3419 -0.75006103515625 +3420 -0.442047119140625 +3421 -0.7569580078125 +3422 -0.446014404296875 +3423 -0.763763427734375 +3424 -0.449951171875 +3425 -0.770477294921875 +3426 -0.453826904296875 +3427 -0.777099609375 +3428 -0.4576416015625 +3429 -0.783660888671875 +3430 -0.46142578125 +3431 -0.790130615234375 +3432 -0.465118408203125 +3433 -0.796478271484375 +3434 -0.46881103515625 +3435 -0.802764892578125 +3436 -0.472442626953125 +3437 -0.808990478515625 +3438 -0.47601318359375 +3439 -0.815093994140625 +3440 -0.479522705078125 +3441 -0.82110595703125 +3442 -0.48297119140625 +3443 -0.8270263671875 +3444 -0.48638916015625 +3445 -0.8328857421875 +3446 -0.48974609375 +3447 -0.838623046875 +3448 -0.493072509765625 +3449 -0.84429931640625 +3450 -0.496307373046875 +3451 -0.849853515625 +3452 -0.499481201171875 +3453 -0.855316162109375 +3454 -0.50262451171875 +3455 -0.860687255859375 +3456 -0.5057373046875 +3457 -0.865997314453125 +3458 -0.508758544921875 +3459 -0.871185302734375 +3460 -0.51171875 +3461 -0.876251220703125 +3462 -0.5146484375 +3463 -0.881256103515625 +3464 -0.51751708984375 +3465 -0.88616943359375 +3466 -0.520294189453125 +3467 -0.890960693359375 +3468 -0.523040771484375 +3469 -0.895660400390625 +3470 -0.5257568359375 +3471 -0.9002685546875 +3472 -0.52838134765625 +3473 -0.90478515625 +3474 -0.53094482421875 +3475 -0.9091796875 +3476 -0.533477783203125 +3477 -0.91351318359375 +3478 -0.53594970703125 +3479 -0.917724609375 +3480 -0.538330078125 +3481 -0.92181396484375 +3482 -0.540679931640625 +3483 -0.92584228515625 +3484 -0.542938232421875 +3485 -0.929718017578125 +3486 -0.545166015625 +3487 -0.93353271484375 +3488 -0.547332763671875 +3489 -0.937225341796875 +3490 -0.5494384765625 +3491 -0.940826416015625 +3492 -0.551483154296875 +3493 -0.9443359375 +3494 -0.553466796875 +3495 -0.947723388671875 +3496 -0.555389404296875 +3497 -0.951019287109375 +3498 -0.557220458984375 +3499 -0.954193115234375 +3500 -0.55902099609375 +3501 -0.957275390625 +3502 -0.560760498046875 +3503 -0.960235595703125 +3504 -0.56243896484375 +3505 -0.963104248046875 +3506 -0.564056396484375 +3507 -0.96588134765625 +3508 -0.56561279296875 +3509 -0.968536376953125 +3510 -0.567108154296875 +3511 -0.971099853515625 +3512 -0.56854248046875 +3513 -0.973541259765625 +3514 -0.56988525390625 +3515 -0.975860595703125 +3516 -0.571197509765625 +3517 -0.97808837890625 +3518 -0.57244873046875 +3519 -0.980224609375 +3520 -0.5736083984375 +3521 -0.98223876953125 +3522 -0.574737548828125 +3523 -0.984161376953125 +3524 -0.575775146484375 +3525 -0.9859619140625 +3526 -0.5767822265625 +3527 -0.987640380859375 +3528 -0.57769775390625 +3529 -0.989227294921875 +3530 -0.57855224609375 +3531 -0.990692138671875 +3532 -0.579345703125 +3533 -0.9920654296875 +3534 -0.580078125 +3535 -0.993316650390625 +3536 -0.58074951171875 +3537 -0.994476318359375 +3538 -0.58135986328125 +3539 -0.995513916015625 +3540 -0.5819091796875 +3541 -0.9964599609375 +3542 -0.5823974609375 +3543 -0.997283935546875 +3544 -0.58282470703125 +3545 -0.99798583984375 +3546 -0.583160400390625 +3547 -0.99859619140625 +3548 -0.583465576171875 +3549 -0.999114990234375 +3550 -0.58367919921875 +3551 -0.999481201171875 +3552 -0.583831787109375 +3553 -0.999755859375 +3554 -0.58392333984375 +3555 -0.99993896484375 +3556 -0.583984375 +3557 -1.0 +3558 -0.58392333984375 +3559 -0.99993896484375 +3560 -0.583831787109375 +3561 -0.999755859375 +3562 -0.58367919921875 +3563 -0.999481201171875 +3564 -0.583465576171875 +3565 -0.999114990234375 +3566 -0.583160400390625 +3567 -0.99859619140625 +3568 -0.58282470703125 +3569 -0.99798583984375 +3570 -0.5823974609375 +3571 -0.997283935546875 +3572 -0.5819091796875 +3573 -0.9964599609375 +3574 -0.58135986328125 +3575 -0.995513916015625 +3576 -0.58074951171875 +3577 -0.994476318359375 +3578 -0.580078125 +3579 -0.993316650390625 +3580 -0.579345703125 +3581 -0.9920654296875 +3582 -0.57855224609375 +3583 -0.990692138671875 +3584 -0.5460205078125 +3585 -0.989227294921875 +3586 -0.545135498046875 +3587 -0.987640380859375 +3588 -0.544219970703125 +3589 -0.9859619140625 +3590 -0.543243408203125 +3591 -0.984161376953125 +3592 -0.54217529296875 +3593 -0.98223876953125 +3594 -0.541046142578125 +3595 -0.980224609375 +3596 -0.539886474609375 +3597 -0.97808837890625 +3598 -0.53863525390625 +3599 -0.975860595703125 +3600 -0.537353515625 +3601 -0.973541259765625 +3602 -0.5360107421875 +3603 -0.971099853515625 +3604 -0.53460693359375 +3605 -0.968536376953125 +3606 -0.53314208984375 +3607 -0.96588134765625 +3608 -0.5316162109375 +3609 -0.963104248046875 +3610 -0.530029296875 +3611 -0.960235595703125 +3612 -0.52838134765625 +3613 -0.957275390625 +3614 -0.526702880859375 +3615 -0.954193115234375 +3616 -0.524932861328125 +3617 -0.951019287109375 +3618 -0.523101806640625 +3619 -0.947723388671875 +3620 -0.521240234375 +3621 -0.9443359375 +3622 -0.519317626953125 +3623 -0.940826416015625 +3624 -0.517333984375 +3625 -0.937225341796875 +3626 -0.515289306640625 +3627 -0.93353271484375 +3628 -0.51318359375 +3629 -0.929718017578125 +3630 -0.51104736328125 +3631 -0.92584228515625 +3632 -0.508819580078125 +3633 -0.92181396484375 +3634 -0.506561279296875 +3635 -0.917724609375 +3636 -0.504241943359375 +3637 -0.91351318359375 +3638 -0.5018310546875 +3639 -0.9091796875 +3640 -0.499420166015625 +3641 -0.90478515625 +3642 -0.496917724609375 +3643 -0.9002685546875 +3644 -0.494384765625 +3645 -0.895660400390625 +3646 -0.491790771484375 +3647 -0.890960693359375 +3648 -0.4891357421875 +3649 -0.88616943359375 +3650 -0.486419677734375 +3651 -0.881256103515625 +3652 -0.483673095703125 +3653 -0.876251220703125 +3654 -0.480865478515625 +3655 -0.871185302734375 +3656 -0.477996826171875 +3657 -0.865997314453125 +3658 -0.475067138671875 +3659 -0.860687255859375 +3660 -0.47210693359375 +3661 -0.855316162109375 +3662 -0.469085693359375 +3663 -0.849853515625 +3664 -0.466033935546875 +3665 -0.84429931640625 +3666 -0.462890625 +3667 -0.838623046875 +3668 -0.459716796875 +3669 -0.8328857421875 +3670 -0.45648193359375 +3671 -0.8270263671875 +3672 -0.453216552734375 +3673 -0.82110595703125 +3674 -0.449920654296875 +3675 -0.815093994140625 +3676 -0.446533203125 +3677 -0.808990478515625 +3678 -0.443115234375 +3679 -0.802764892578125 +3680 -0.43963623046875 +3681 -0.796478271484375 +3682 -0.436126708984375 +3683 -0.790130615234375 +3684 -0.43255615234375 +3685 -0.783660888671875 +3686 -0.428924560546875 +3687 -0.777099609375 +3688 -0.42529296875 +3689 -0.770477294921875 +3690 -0.42156982421875 +3691 -0.763763427734375 +3692 -0.417816162109375 +3693 -0.7569580078125 +3694 -0.41400146484375 +3695 -0.75006103515625 +3696 -0.41015625 +3697 -0.74310302734375 +3698 -0.406280517578125 +3699 -0.736053466796875 +3700 -0.40234375 +3701 -0.72894287109375 +3702 -0.398345947265625 +3703 -0.721710205078125 +3704 -0.39434814453125 +3705 -0.714447021484375 +3706 -0.390289306640625 +3707 -0.707061767578125 +3708 -0.38616943359375 +3709 -0.699615478515625 +3710 -0.38201904296875 +3711 -0.692108154296875 +3712 -0.377838134765625 +3713 -0.68450927734375 +3714 -0.37359619140625 +3715 -0.676849365234375 +3716 -0.36932373046875 +3717 -0.669097900390625 +3718 -0.365020751953125 +3719 -0.661285400390625 +3720 -0.36065673828125 +3721 -0.65338134765625 +3722 -0.35626220703125 +3723 -0.645416259765625 +3724 -0.351806640625 +3725 -0.63739013671875 +3726 -0.347320556640625 +3727 -0.6292724609375 +3728 -0.34283447265625 +3729 -0.621124267578125 +3730 -0.338287353515625 +3731 -0.612884521484375 +3732 -0.33367919921875 +3733 -0.60455322265625 +3734 -0.329071044921875 +3735 -0.59619140625 +3736 -0.32440185546875 +3737 -0.587738037109375 +3738 -0.319732666015625 +3739 -0.579254150390625 +3740 -0.31500244140625 +3741 -0.5706787109375 +3742 -0.310211181640625 +3743 -0.562042236328125 +3744 -0.305419921875 +3745 -0.5533447265625 +3746 -0.30059814453125 +3747 -0.54461669921875 +3748 -0.295745849609375 +3749 -0.535797119140625 +3750 -0.29083251953125 +3751 -0.52691650390625 +3752 -0.285919189453125 +3753 -0.51800537109375 +3754 -0.28094482421875 +3755 -0.509002685546875 +3756 -0.275970458984375 +3757 -0.499969482421875 +3758 -0.27093505859375 +3759 -0.490875244140625 +3760 -0.265899658203125 +3761 -0.481719970703125 +3762 -0.26080322265625 +3763 -0.4725341796875 +3764 -0.255706787109375 +3765 -0.4632568359375 +3766 -0.25054931640625 +3767 -0.453948974609375 +3768 -0.245391845703125 +3769 -0.444610595703125 +3770 -0.240203857421875 +3771 -0.435211181640625 +3772 -0.2349853515625 +3773 -0.425750732421875 +3774 -0.229766845703125 +3775 -0.416259765625 +3776 -0.2244873046875 +3777 -0.406707763671875 +3778 -0.219207763671875 +3779 -0.397125244140625 +3780 -0.2138671875 +3781 -0.387481689453125 +3782 -0.208526611328125 +3783 -0.3778076171875 +3784 -0.20318603515625 +3785 -0.36810302734375 +3786 -0.197784423828125 +3787 -0.35833740234375 +3788 -0.1923828125 +3789 -0.348541259765625 +3790 -0.18695068359375 +3791 -0.338714599609375 +3792 -0.181488037109375 +3793 -0.328826904296875 +3794 -0.176025390625 +3795 -0.318939208984375 +3796 -0.1705322265625 +3797 -0.308990478515625 +3798 -0.1650390625 +3799 -0.29901123046875 +3800 -0.159515380859375 +3801 -0.28900146484375 +3802 -0.153961181640625 +3803 -0.278961181640625 +3804 -0.148406982421875 +3805 -0.268890380859375 +3806 -0.142822265625 +3807 -0.2587890625 +3808 -0.137237548828125 +3809 -0.2486572265625 +3810 -0.13165283203125 +3811 -0.238525390625 +3812 -0.126007080078125 +3813 -0.22833251953125 +3814 -0.120391845703125 +3815 -0.218109130859375 +3816 -0.11474609375 +3817 -0.2078857421875 +3818 -0.10906982421875 +3819 -0.1976318359375 +3820 -0.1033935546875 +3821 -0.187347412109375 +3822 -0.09771728515625 +3823 -0.17706298828125 +3824 -0.092041015625 +3825 -0.166748046875 +3826 -0.0863037109375 +3827 -0.156402587890625 +3828 -0.080596923828125 +3829 -0.14605712890625 +3830 -0.07489013671875 +3831 -0.13568115234375 +3832 -0.06915283203125 +3833 -0.12530517578125 +3834 -0.06341552734375 +3835 -0.11492919921875 +3836 -0.05767822265625 +3837 -0.104522705078125 +3838 -0.051910400390625 +3839 -0.094085693359375 +3840 -0.045989990234375 +3841 -0.083648681640625 +3842 -0.040252685546875 +3843 -0.073211669921875 +3844 -0.034515380859375 +3845 -0.062774658203125 +3846 -0.02874755859375 +3847 -0.05230712890625 +3848 -0.02301025390625 +3849 -0.0418701171875 +3850 -0.017242431640625 +3851 -0.031402587890625 +3852 -0.011505126953125 +3853 -0.02093505859375 +3854 -0.0057373046875 +3855 -0.010467529296875 +3856 0.0 +3857 0.0 +3858 0.00543212890625 +3859 0.010467529296875 +3860 0.0108642578125 +3861 0.02093505859375 +3862 0.016326904296875 +3863 0.031402587890625 +3864 0.021759033203125 +3865 0.0418701171875 +3866 0.027191162109375 +3867 0.05230712890625 +3868 0.032623291015625 +3869 0.062774658203125 +3870 0.038055419921875 +3871 0.073211669921875 +3872 0.043487548828125 +3873 0.083648681640625 +3874 0.048919677734375 +3875 0.094085693359375 +3876 0.054351806640625 +3877 0.104522705078125 +3878 0.05975341796875 +3879 0.11492919921875 +3880 0.065155029296875 +3881 0.12530517578125 +3882 0.070526123046875 +3883 0.13568115234375 +3884 0.075927734375 +3885 0.14605712890625 +3886 0.081329345703125 +3887 0.156402587890625 +3888 0.086700439453125 +3889 0.166748046875 +3890 0.092071533203125 +3891 0.17706298828125 +3892 0.097412109375 +3893 0.187347412109375 +3894 0.102752685546875 +3895 0.1976318359375 +3896 0.10809326171875 +3897 0.2078857421875 +3898 0.1134033203125 +3899 0.218109130859375 +3900 0.11871337890625 +3901 0.22833251953125 +3902 0.1240234375 +3903 0.238525390625 +3904 0.1292724609375 +3905 0.2486572265625 +3906 0.134552001953125 +3907 0.2587890625 +3908 0.139801025390625 +3909 0.268890380859375 +3910 0.145050048828125 +3911 0.278961181640625 +3912 0.1502685546875 +3913 0.28900146484375 +3914 0.155487060546875 +3915 0.29901123046875 +3916 0.160675048828125 +3917 0.308990478515625 +3918 0.16583251953125 +3919 0.318939208984375 +3920 0.170989990234375 +3921 0.328826904296875 +3922 0.176116943359375 +3923 0.338714599609375 +3924 0.18121337890625 +3925 0.348541259765625 +3926 0.186309814453125 +3927 0.35833740234375 +3928 0.19140625 +3929 0.36810302734375 +3930 0.196441650390625 +3931 0.3778076171875 +3932 0.20147705078125 +3933 0.387481689453125 +3934 0.20648193359375 +3935 0.397125244140625 +3936 0.21148681640625 +3937 0.406707763671875 +3938 0.2164306640625 +3939 0.416259765625 +3940 0.22137451171875 +3941 0.425750732421875 +3942 0.226287841796875 +3943 0.435211181640625 +3944 0.231170654296875 +3945 0.444610595703125 +3946 0.236053466796875 +3947 0.453948974609375 +3948 0.240875244140625 +3949 0.4632568359375 +3950 0.245697021484375 +3951 0.4725341796875 +3952 0.25048828125 +3953 0.481719970703125 +3954 0.2552490234375 +3955 0.490875244140625 +3956 0.259979248046875 +3957 0.499969482421875 +3958 0.264678955078125 +3959 0.509002685546875 +3960 0.26934814453125 +3961 0.51800537109375 +3962 0.27398681640625 +3963 0.52691650390625 +3964 0.278594970703125 +3965 0.535797119140625 +3966 0.283203125 +3967 0.54461669921875 +3968 0.2877197265625 +3969 0.5533447265625 +3970 0.292236328125 +3971 0.562042236328125 +3972 0.2967529296875 +3973 0.5706787109375 +3974 0.30120849609375 +3975 0.579254150390625 +3976 0.30560302734375 +3977 0.587738037109375 +3978 0.30999755859375 +3979 0.59619140625 +3980 0.314361572265625 +3981 0.60455322265625 +3982 0.318695068359375 +3983 0.612884521484375 +3984 0.322967529296875 +3985 0.621124267578125 +3986 0.32720947265625 +3987 0.6292724609375 +3988 0.3314208984375 +3989 0.63739013671875 +3990 0.335601806640625 +3991 0.645416259765625 +3992 0.339752197265625 +3993 0.65338134765625 +3994 0.343841552734375 +3995 0.661285400390625 +3996 0.347930908203125 +3997 0.669097900390625 +3998 0.351959228515625 +3999 0.676849365234375 +4000 0.355926513671875 +4001 0.68450927734375 +4002 0.359893798828125 +4003 0.692108154296875 +4004 0.363800048828125 +4005 0.699615478515625 +4006 0.367645263671875 +4007 0.707061767578125 +4008 0.371490478515625 +4009 0.714447021484375 +4010 0.375274658203125 +4011 0.721710205078125 +4012 0.3790283203125 +4013 0.72894287109375 +4014 0.382720947265625 +4015 0.736053466796875 +4016 0.38641357421875 +4017 0.74310302734375 +4018 0.3900146484375 +4019 0.75006103515625 +4020 0.39361572265625 +4021 0.7569580078125 +4022 0.39715576171875 +4023 0.763763427734375 +4024 0.400634765625 +4025 0.770477294921875 +4026 0.404083251953125 +4027 0.777099609375 +4028 0.407501220703125 +4029 0.783660888671875 +4030 0.410858154296875 +4031 0.790130615234375 +4032 0.414154052734375 +4033 0.796478271484375 +4034 0.41741943359375 +4035 0.802764892578125 +4036 0.420654296875 +4037 0.808990478515625 +4038 0.423828125 +4039 0.815093994140625 +4040 0.426971435546875 +4041 0.82110595703125 +4042 0.4300537109375 +4043 0.8270263671875 +4044 0.433074951171875 +4045 0.8328857421875 +4046 0.436065673828125 +4047 0.838623046875 +4048 0.43902587890625 +4049 0.84429931640625 +4050 0.441925048828125 +4051 0.849853515625 +4052 0.44476318359375 +4053 0.855316162109375 +4054 0.447540283203125 +4055 0.860687255859375 +4056 0.4503173828125 +4057 0.865997314453125 +4058 0.4530029296875 +4059 0.871185302734375 +4060 0.45562744140625 +4061 0.876251220703125 +4062 0.458251953125 +4063 0.881256103515625 +4064 0.460784912109375 +4065 0.88616943359375 +4066 0.463287353515625 +4067 0.890960693359375 +4068 0.465728759765625 +4069 0.895660400390625 +4070 0.4681396484375 +4071 0.9002685546875 +4072 0.470489501953125 +4073 0.90478515625 +4074 0.472747802734375 +4075 0.9091796875 +4076 0.475006103515625 +4077 0.91351318359375 +4078 0.477203369140625 +4079 0.917724609375 +4080 0.479339599609375 +4081 0.92181396484375 +4082 0.481414794921875 +4083 0.92584228515625 +4084 0.483428955078125 +4085 0.929718017578125 +4086 0.48541259765625 +4087 0.93353271484375 +4088 0.487335205078125 +4089 0.937225341796875 +4090 0.489227294921875 +4091 0.940826416015625 +4092 0.491058349609375 +4093 0.9443359375 +4094 0.4927978515625 +4095 0.947723388671875 +4096 0.464080810546875 +4097 0.951019287109375 +4098 0.46563720703125 +4099 0.954193115234375 +4100 0.467132568359375 +4101 0.957275390625 +4102 0.46856689453125 +4103 0.960235595703125 +4104 0.469970703125 +4105 0.963104248046875 +4106 0.4713134765625 +4107 0.96588134765625 +4108 0.472625732421875 +4109 0.968536376953125 +4110 0.473876953125 +4111 0.971099853515625 +4112 0.475067138671875 +4113 0.973541259765625 +4114 0.4761962890625 +4115 0.975860595703125 +4116 0.477294921875 +4117 0.97808837890625 +4118 0.47833251953125 +4119 0.980224609375 +4120 0.47930908203125 +4121 0.98223876953125 +4122 0.480255126953125 +4123 0.984161376953125 +4124 0.48114013671875 +4125 0.9859619140625 +4126 0.48193359375 +4127 0.987640380859375 +4128 0.48272705078125 +4129 0.989227294921875 +4130 0.483428955078125 +4131 0.990692138671875 +4132 0.484100341796875 +4133 0.9920654296875 +4134 0.484710693359375 +4135 0.993316650390625 +4136 0.48529052734375 +4137 0.994476318359375 +4138 0.48577880859375 +4139 0.995513916015625 +4140 0.486236572265625 +4141 0.9964599609375 +4142 0.486663818359375 +4143 0.997283935546875 +4144 0.48699951171875 +4145 0.99798583984375 +4146 0.4873046875 +4147 0.99859619140625 +4148 0.487518310546875 +4149 0.999114990234375 +4150 0.487701416015625 +4151 0.999481201171875 +4152 0.48785400390625 +4153 0.999755859375 +4154 0.487945556640625 +4155 0.99993896484375 +4156 0.48797607421875 +4157 0.999969482421875 +4158 0.487945556640625 +4159 0.99993896484375 +4160 0.48785400390625 +4161 0.999755859375 +4162 0.487701416015625 +4163 0.999481201171875 +4164 0.487518310546875 +4165 0.999114990234375 +4166 0.4873046875 +4167 0.99859619140625 +4168 0.48699951171875 +4169 0.99798583984375 +4170 0.486663818359375 +4171 0.997283935546875 +4172 0.486236572265625 +4173 0.9964599609375 +4174 0.48577880859375 +4175 0.995513916015625 +4176 0.48529052734375 +4177 0.994476318359375 +4178 0.484710693359375 +4179 0.993316650390625 +4180 0.484100341796875 +4181 0.9920654296875 +4182 0.483428955078125 +4183 0.990692138671875 +4184 0.48272705078125 +4185 0.989227294921875 +4186 0.48193359375 +4187 0.987640380859375 +4188 0.48114013671875 +4189 0.9859619140625 +4190 0.480255126953125 +4191 0.984161376953125 +4192 0.47930908203125 +4193 0.98223876953125 +4194 0.47833251953125 +4195 0.980224609375 +4196 0.477294921875 +4197 0.97808837890625 +4198 0.4761962890625 +4199 0.975860595703125 +4200 0.475067138671875 +4201 0.973541259765625 +4202 0.473876953125 +4203 0.971099853515625 +4204 0.472625732421875 +4205 0.968536376953125 +4206 0.4713134765625 +4207 0.96588134765625 +4208 0.469970703125 +4209 0.963104248046875 +4210 0.46856689453125 +4211 0.960235595703125 +4212 0.467132568359375 +4213 0.957275390625 +4214 0.46563720703125 +4215 0.954193115234375 +4216 0.464080810546875 +4217 0.951019287109375 +4218 0.46246337890625 +4219 0.947723388671875 +4220 0.4608154296875 +4221 0.9443359375 +4222 0.4591064453125 +4223 0.940826416015625 +4224 0.45733642578125 +4225 0.937225341796875 +4226 0.455535888671875 +4227 0.93353271484375 +4228 0.45367431640625 +4229 0.929718017578125 +4230 0.4517822265625 +4231 0.92584228515625 +4232 0.4498291015625 +4233 0.92181396484375 +4234 0.44781494140625 +4235 0.917724609375 +4236 0.445770263671875 +4237 0.91351318359375 +4238 0.44366455078125 +4239 0.9091796875 +4240 0.441497802734375 +4241 0.90478515625 +4242 0.439300537109375 +4243 0.9002685546875 +4244 0.43707275390625 +4245 0.895660400390625 +4246 0.43475341796875 +4247 0.890960693359375 +4248 0.43243408203125 +4249 0.88616943359375 +4250 0.430023193359375 +4251 0.881256103515625 +4252 0.427581787109375 +4253 0.876251220703125 +4254 0.42510986328125 +4255 0.871185302734375 +4256 0.422576904296875 +4257 0.865997314453125 +4258 0.41998291015625 +4259 0.860687255859375 +4260 0.4173583984375 +4261 0.855316162109375 +4262 0.414703369140625 +4263 0.849853515625 +4264 0.4119873046875 +4265 0.84429931640625 +4266 0.409210205078125 +4267 0.838623046875 +4268 0.40643310546875 +4269 0.8328857421875 +4270 0.403564453125 +4271 0.8270263671875 +4272 0.400665283203125 +4273 0.82110595703125 +4274 0.397735595703125 +4275 0.815093994140625 +4276 0.394775390625 +4277 0.808990478515625 +4278 0.3917236328125 +4279 0.802764892578125 +4280 0.388671875 +4281 0.796478271484375 +4282 0.38555908203125 +4283 0.790130615234375 +4284 0.382415771484375 +4285 0.783660888671875 +4286 0.37921142578125 +4287 0.777099609375 +4288 0.3759765625 +4289 0.770477294921875 +4290 0.3726806640625 +4291 0.763763427734375 +4292 0.369384765625 +4293 0.7569580078125 +4294 0.365997314453125 +4295 0.75006103515625 +4296 0.36260986328125 +4297 0.74310302734375 +4298 0.359161376953125 +4299 0.736053466796875 +4300 0.355712890625 +4301 0.72894287109375 +4302 0.3521728515625 +4303 0.721710205078125 +4304 0.3486328125 +4305 0.714447021484375 +4306 0.34503173828125 +4307 0.707061767578125 +4308 0.341400146484375 +4309 0.699615478515625 +4310 0.337738037109375 +4311 0.692108154296875 +4312 0.334014892578125 +4313 0.68450927734375 +4314 0.330291748046875 +4315 0.676849365234375 +4316 0.326507568359375 +4317 0.669097900390625 +4318 0.32269287109375 +4319 0.661285400390625 +4320 0.318817138671875 +4321 0.65338134765625 +4322 0.31494140625 +4323 0.645416259765625 +4324 0.31103515625 +4325 0.63739013671875 +4326 0.30706787109375 +4327 0.6292724609375 +4328 0.3031005859375 +4329 0.621124267578125 +4330 0.299072265625 +4331 0.612884521484375 +4332 0.295013427734375 +4333 0.60455322265625 +4334 0.290924072265625 +4335 0.59619140625 +4336 0.28680419921875 +4337 0.587738037109375 +4338 0.28265380859375 +4339 0.579254150390625 +4340 0.278472900390625 +4341 0.5706787109375 +4342 0.274261474609375 +4343 0.562042236328125 +4344 0.27001953125 +4345 0.5533447265625 +4346 0.2657470703125 +4347 0.54461669921875 +4348 0.261444091796875 +4349 0.535797119140625 +4350 0.257110595703125 +4351 0.52691650390625 +4352 0.2362060546875 +4353 0.51800537109375 +4354 0.232086181640625 +4355 0.509002685546875 +4356 0.22796630859375 +4357 0.499969482421875 +4358 0.22381591796875 +4359 0.490875244140625 +4360 0.21966552734375 +4361 0.481719970703125 +4362 0.2154541015625 +4363 0.4725341796875 +4364 0.21124267578125 +4365 0.4632568359375 +4366 0.207000732421875 +4367 0.453948974609375 +4368 0.202728271484375 +4369 0.444610595703125 +4370 0.198455810546875 +4371 0.435211181640625 +4372 0.194122314453125 +4373 0.425750732421875 +4374 0.189788818359375 +4375 0.416259765625 +4376 0.185455322265625 +4377 0.406707763671875 +4378 0.18109130859375 +4379 0.397125244140625 +4380 0.176666259765625 +4381 0.387481689453125 +4382 0.172271728515625 +4383 0.3778076171875 +4384 0.1678466796875 +4385 0.36810302734375 +4386 0.16339111328125 +4387 0.35833740234375 +4388 0.158935546875 +4389 0.348541259765625 +4390 0.154449462890625 +4391 0.338714599609375 +4392 0.149932861328125 +4393 0.328826904296875 +4394 0.145416259765625 +4395 0.318939208984375 +4396 0.140899658203125 +4397 0.308990478515625 +4398 0.136322021484375 +4399 0.29901123046875 +4400 0.13177490234375 +4401 0.28900146484375 +4402 0.127197265625 +4403 0.278961181640625 +4404 0.122589111328125 +4405 0.268890380859375 +4406 0.11798095703125 +4407 0.2587890625 +4408 0.113372802734375 +4409 0.2486572265625 +4410 0.1087646484375 +4411 0.238525390625 +4412 0.104095458984375 +4413 0.22833251953125 +4414 0.099456787109375 +4415 0.218109130859375 +4416 0.09478759765625 +4417 0.2078857421875 +4418 0.090118408203125 +4419 0.1976318359375 +4420 0.085418701171875 +4421 0.187347412109375 +4422 0.080718994140625 +4423 0.17706298828125 +4424 0.076019287109375 +4425 0.166748046875 +4426 0.071319580078125 +4427 0.156402587890625 +4428 0.06658935546875 +4429 0.14605712890625 +4430 0.061859130859375 +4431 0.13568115234375 +4432 0.05712890625 +4433 0.12530517578125 +4434 0.052398681640625 +4435 0.11492919921875 +4436 0.047637939453125 +4437 0.104522705078125 +4438 0.042877197265625 +4439 0.094085693359375 +4440 0.038116455078125 +4441 0.083648681640625 +4442 0.033355712890625 +4443 0.073211669921875 +4444 0.02862548828125 +4445 0.062774658203125 +4446 0.023834228515625 +4447 0.05230712890625 +4448 0.019073486328125 +4449 0.0418701171875 +4450 0.014312744140625 +4451 0.031402587890625 +4452 0.009521484375 +4453 0.02093505859375 +4454 0.0047607421875 +4455 0.010467529296875 +4456 0.0 +4457 0.0 +4458 -0.0047607421875 +4459 -0.010467529296875 +4460 -0.009521484375 +4461 -0.02093505859375 +4462 -0.014312744140625 +4463 -0.031402587890625 +4464 -0.019073486328125 +4465 -0.0418701171875 +4466 -0.023834228515625 +4467 -0.05230712890625 +4468 -0.02862548828125 +4469 -0.062774658203125 +4470 -0.033355712890625 +4471 -0.073211669921875 +4472 -0.038116455078125 +4473 -0.083648681640625 +4474 -0.042877197265625 +4475 -0.094085693359375 +4476 -0.047637939453125 +4477 -0.104522705078125 +4478 -0.052398681640625 +4479 -0.11492919921875 +4480 -0.05712890625 +4481 -0.12530517578125 +4482 -0.061859130859375 +4483 -0.13568115234375 +4484 -0.06658935546875 +4485 -0.14605712890625 +4486 -0.071319580078125 +4487 -0.156402587890625 +4488 -0.076019287109375 +4489 -0.166748046875 +4490 -0.080718994140625 +4491 -0.17706298828125 +4492 -0.085418701171875 +4493 -0.187347412109375 +4494 -0.090118408203125 +4495 -0.1976318359375 +4496 -0.09478759765625 +4497 -0.2078857421875 +4498 -0.099456787109375 +4499 -0.218109130859375 +4500 -0.104095458984375 +4501 -0.22833251953125 +4502 -0.1087646484375 +4503 -0.238525390625 +4504 -0.113372802734375 +4505 -0.2486572265625 +4506 -0.11798095703125 +4507 -0.2587890625 +4508 -0.122589111328125 +4509 -0.268890380859375 +4510 -0.127197265625 +4511 -0.278961181640625 +4512 -0.13177490234375 +4513 -0.28900146484375 +4514 -0.136322021484375 +4515 -0.29901123046875 +4516 -0.140899658203125 +4517 -0.308990478515625 +4518 -0.145416259765625 +4519 -0.318939208984375 +4520 -0.149932861328125 +4521 -0.328826904296875 +4522 -0.154449462890625 +4523 -0.338714599609375 +4524 -0.158935546875 +4525 -0.348541259765625 +4526 -0.16339111328125 +4527 -0.35833740234375 +4528 -0.1678466796875 +4529 -0.36810302734375 +4530 -0.172271728515625 +4531 -0.3778076171875 +4532 -0.176666259765625 +4533 -0.387481689453125 +4534 -0.18109130859375 +4535 -0.397125244140625 +4536 -0.185455322265625 +4537 -0.406707763671875 +4538 -0.189788818359375 +4539 -0.416259765625 +4540 -0.194122314453125 +4541 -0.425750732421875 +4542 -0.198455810546875 +4543 -0.435211181640625 +4544 -0.202728271484375 +4545 -0.444610595703125 +4546 -0.207000732421875 +4547 -0.453948974609375 +4548 -0.21124267578125 +4549 -0.4632568359375 +4550 -0.2154541015625 +4551 -0.4725341796875 +4552 -0.21966552734375 +4553 -0.481719970703125 +4554 -0.22381591796875 +4555 -0.490875244140625 +4556 -0.22796630859375 +4557 -0.499969482421875 +4558 -0.232086181640625 +4559 -0.509002685546875 +4560 -0.2362060546875 +4561 -0.51800537109375 +4562 -0.240264892578125 +4563 -0.52691650390625 +4564 -0.24432373046875 +4565 -0.535797119140625 +4566 -0.248321533203125 +4567 -0.54461669921875 +4568 -0.2523193359375 +4569 -0.5533447265625 +4570 -0.25628662109375 +4571 -0.562042236328125 +4572 -0.260223388671875 +4573 -0.5706787109375 +4574 -0.264129638671875 +4575 -0.579254150390625 +4576 -0.26800537109375 +4577 -0.587738037109375 +4578 -0.2718505859375 +4579 -0.59619140625 +4580 -0.275665283203125 +4581 -0.60455322265625 +4582 -0.27947998046875 +4583 -0.612884521484375 +4584 -0.283233642578125 +4585 -0.621124267578125 +4586 -0.28692626953125 +4587 -0.6292724609375 +4588 -0.2906494140625 +4589 -0.63739013671875 +4590 -0.2943115234375 +4591 -0.645416259765625 +4592 -0.297943115234375 +4593 -0.65338134765625 +4594 -0.301544189453125 +4595 -0.661285400390625 +4596 -0.305084228515625 +4597 -0.669097900390625 +4598 -0.308624267578125 +4599 -0.676849365234375 +4600 -0.3121337890625 +4601 -0.68450927734375 +4602 -0.315582275390625 +4603 -0.692108154296875 +4604 -0.319000244140625 +4605 -0.699615478515625 +4606 -0.322418212890625 +4607 -0.707061767578125 +4608 -0.30291748046875 +4609 -0.714447021484375 +4610 -0.305999755859375 +4611 -0.721710205078125 +4612 -0.309051513671875 +4613 -0.72894287109375 +4614 -0.31207275390625 +4615 -0.736053466796875 +4616 -0.3150634765625 +4617 -0.74310302734375 +4618 -0.3179931640625 +4619 -0.75006103515625 +4620 -0.3209228515625 +4621 -0.7569580078125 +4622 -0.323822021484375 +4623 -0.763763427734375 +4624 -0.32666015625 +4625 -0.770477294921875 +4626 -0.3294677734375 +4627 -0.777099609375 +4628 -0.332244873046875 +4629 -0.783660888671875 +4630 -0.334991455078125 +4631 -0.790130615234375 +4632 -0.337677001953125 +4633 -0.796478271484375 +4634 -0.340362548828125 +4635 -0.802764892578125 +4636 -0.342987060546875 +4637 -0.808990478515625 +4638 -0.3455810546875 +4639 -0.815093994140625 +4640 -0.348114013671875 +4641 -0.82110595703125 +4642 -0.35064697265625 +4643 -0.8270263671875 +4644 -0.353118896484375 +4645 -0.8328857421875 +4646 -0.355560302734375 +4647 -0.838623046875 +4648 -0.35797119140625 +4649 -0.84429931640625 +4650 -0.360321044921875 +4651 -0.849853515625 +4652 -0.362640380859375 +4653 -0.855316162109375 +4654 -0.364898681640625 +4655 -0.860687255859375 +4656 -0.367156982421875 +4657 -0.865997314453125 +4658 -0.369354248046875 +4659 -0.871185302734375 +4660 -0.37152099609375 +4661 -0.876251220703125 +4662 -0.373626708984375 +4663 -0.881256103515625 +4664 -0.375701904296875 +4665 -0.88616943359375 +4666 -0.37774658203125 +4667 -0.890960693359375 +4668 -0.379730224609375 +4669 -0.895660400390625 +4670 -0.381683349609375 +4671 -0.9002685546875 +4672 -0.38360595703125 +4673 -0.90478515625 +4674 -0.385467529296875 +4675 -0.9091796875 +4676 -0.387298583984375 +4677 -0.91351318359375 +4678 -0.38909912109375 +4679 -0.917724609375 +4680 -0.390838623046875 +4681 -0.92181396484375 +4682 -0.392547607421875 +4683 -0.92584228515625 +4684 -0.3941650390625 +4685 -0.929718017578125 +4686 -0.395782470703125 +4687 -0.93353271484375 +4688 -0.397369384765625 +4689 -0.937225341796875 +4690 -0.398895263671875 +4691 -0.940826416015625 +4692 -0.400390625 +4693 -0.9443359375 +4694 -0.401824951171875 +4695 -0.947723388671875 +4696 -0.4031982421875 +4697 -0.951019287109375 +4698 -0.404571533203125 +4699 -0.954193115234375 +4700 -0.405853271484375 +4701 -0.957275390625 +4702 -0.4071044921875 +4703 -0.960235595703125 +4704 -0.4083251953125 +4705 -0.963104248046875 +4706 -0.409515380859375 +4707 -0.96588134765625 +4708 -0.41064453125 +4709 -0.968536376953125 +4710 -0.411712646484375 +4711 -0.971099853515625 +4712 -0.412750244140625 +4713 -0.973541259765625 +4714 -0.41375732421875 +4715 -0.975860595703125 +4716 -0.4146728515625 +4717 -0.97808837890625 +4718 -0.41558837890625 +4719 -0.980224609375 +4720 -0.41644287109375 +4721 -0.98223876953125 +4722 -0.417266845703125 +4723 -0.984161376953125 +4724 -0.41802978515625 +4725 -0.9859619140625 +4726 -0.418731689453125 +4727 -0.987640380859375 +4728 -0.419403076171875 +4729 -0.989227294921875 +4730 -0.4200439453125 +4731 -0.990692138671875 +4732 -0.420623779296875 +4733 -0.9920654296875 +4734 -0.421142578125 +4735 -0.993316650390625 +4736 -0.421630859375 +4737 -0.994476318359375 +4738 -0.422088623046875 +4739 -0.995513916015625 +4740 -0.4224853515625 +4741 -0.9964599609375 +4742 -0.422821044921875 +4743 -0.997283935546875 +4744 -0.423126220703125 +4745 -0.99798583984375 +4746 -0.423370361328125 +4747 -0.99859619140625 +4748 -0.423583984375 +4749 -0.999114990234375 +4750 -0.423736572265625 +4751 -0.999481201171875 +4752 -0.423858642578125 +4753 -0.999755859375 +4754 -0.4239501953125 +4755 -0.99993896484375 +4756 -0.423980712890625 +4757 -1.0 +4758 -0.4239501953125 +4759 -0.99993896484375 +4760 -0.423858642578125 +4761 -0.999755859375 +4762 -0.423736572265625 +4763 -0.999481201171875 +4764 -0.423583984375 +4765 -0.999114990234375 +4766 -0.423370361328125 +4767 -0.99859619140625 +4768 -0.423126220703125 +4769 -0.99798583984375 +4770 -0.422821044921875 +4771 -0.997283935546875 +4772 -0.4224853515625 +4773 -0.9964599609375 +4774 -0.422088623046875 +4775 -0.995513916015625 +4776 -0.421630859375 +4777 -0.994476318359375 +4778 -0.421142578125 +4779 -0.993316650390625 +4780 -0.420623779296875 +4781 -0.9920654296875 +4782 -0.4200439453125 +4783 -0.990692138671875 +4784 -0.419403076171875 +4785 -0.989227294921875 +4786 -0.418731689453125 +4787 -0.987640380859375 +4788 -0.41802978515625 +4789 -0.9859619140625 +4790 -0.417266845703125 +4791 -0.984161376953125 +4792 -0.41644287109375 +4793 -0.98223876953125 +4794 -0.41558837890625 +4795 -0.980224609375 +4796 -0.4146728515625 +4797 -0.97808837890625 +4798 -0.41375732421875 +4799 -0.975860595703125 +4800 -0.412750244140625 +4801 -0.973541259765625 +4802 -0.411712646484375 +4803 -0.971099853515625 +4804 -0.41064453125 +4805 -0.968536376953125 +4806 -0.409515380859375 +4807 -0.96588134765625 +4808 -0.4083251953125 +4809 -0.963104248046875 +4810 -0.4071044921875 +4811 -0.960235595703125 +4812 -0.405853271484375 +4813 -0.957275390625 +4814 -0.404571533203125 +4815 -0.954193115234375 +4816 -0.4031982421875 +4817 -0.951019287109375 +4818 -0.401824951171875 +4819 -0.947723388671875 +4820 -0.400390625 +4821 -0.9443359375 +4822 -0.398895263671875 +4823 -0.940826416015625 +4824 -0.397369384765625 +4825 -0.937225341796875 +4826 -0.395782470703125 +4827 -0.93353271484375 +4828 -0.3941650390625 +4829 -0.929718017578125 +4830 -0.392547607421875 +4831 -0.92584228515625 +4832 -0.390838623046875 +4833 -0.92181396484375 +4834 -0.38909912109375 +4835 -0.917724609375 +4836 -0.387298583984375 +4837 -0.91351318359375 +4838 -0.385467529296875 +4839 -0.9091796875 +4840 -0.38360595703125 +4841 -0.90478515625 +4842 -0.381683349609375 +4843 -0.9002685546875 +4844 -0.379730224609375 +4845 -0.895660400390625 +4846 -0.37774658203125 +4847 -0.890960693359375 +4848 -0.375701904296875 +4849 -0.88616943359375 +4850 -0.373626708984375 +4851 -0.881256103515625 +4852 -0.37152099609375 +4853 -0.876251220703125 +4854 -0.369354248046875 +4855 -0.871185302734375 +4856 -0.367156982421875 +4857 -0.865997314453125 +4858 -0.364898681640625 +4859 -0.860687255859375 +4860 -0.362640380859375 +4861 -0.855316162109375 +4862 -0.360321044921875 +4863 -0.849853515625 +4864 -0.33770751953125 +4865 -0.84429931640625 +4866 -0.33544921875 +4867 -0.838623046875 +4868 -0.3331298828125 +4869 -0.8328857421875 +4870 -0.330810546875 +4871 -0.8270263671875 +4872 -0.32843017578125 +4873 -0.82110595703125 +4874 -0.326019287109375 +4875 -0.815093994140625 +4876 -0.323577880859375 +4877 -0.808990478515625 +4878 -0.32110595703125 +4879 -0.802764892578125 +4880 -0.318572998046875 +4881 -0.796478271484375 +4882 -0.3160400390625 +4883 -0.790130615234375 +4884 -0.313446044921875 +4885 -0.783660888671875 +4886 -0.310821533203125 +4887 -0.777099609375 +4888 -0.30816650390625 +4889 -0.770477294921875 +4890 -0.30548095703125 +4891 -0.763763427734375 +4892 -0.302764892578125 +4893 -0.7569580078125 +4894 -0.300018310546875 +4895 -0.75006103515625 +4896 -0.2972412109375 +4897 -0.74310302734375 +4898 -0.294403076171875 +4899 -0.736053466796875 +4900 -0.29156494140625 +4901 -0.72894287109375 +4902 -0.288665771484375 +4903 -0.721710205078125 +4904 -0.2857666015625 +4905 -0.714447021484375 +4906 -0.282806396484375 +4907 -0.707061767578125 +4908 -0.27984619140625 +4909 -0.699615478515625 +4910 -0.276824951171875 +4911 -0.692108154296875 +4912 -0.2738037109375 +4913 -0.68450927734375 +4914 -0.270721435546875 +4915 -0.676849365234375 +4916 -0.26763916015625 +4917 -0.669097900390625 +4918 -0.264495849609375 +4919 -0.661285400390625 +4920 -0.2613525390625 +4921 -0.65338134765625 +4922 -0.258148193359375 +4923 -0.645416259765625 +4924 -0.25494384765625 +4925 -0.63739013671875 +4926 -0.251708984375 +4927 -0.6292724609375 +4928 -0.248443603515625 +4929 -0.621124267578125 +4930 -0.245147705078125 +4931 -0.612884521484375 +4932 -0.2418212890625 +4933 -0.60455322265625 +4934 -0.23846435546875 +4935 -0.59619140625 +4936 -0.235076904296875 +4937 -0.587738037109375 +4938 -0.231689453125 +4939 -0.579254150390625 +4940 -0.228271484375 +4941 -0.5706787109375 +4942 -0.22479248046875 +4943 -0.562042236328125 +4944 -0.2213134765625 +4945 -0.5533447265625 +4946 -0.21783447265625 +4947 -0.54461669921875 +4948 -0.21429443359375 +4949 -0.535797119140625 +4950 -0.21075439453125 +4951 -0.52691650390625 +4952 -0.207183837890625 +4953 -0.51800537109375 +4954 -0.203582763671875 +4955 -0.509002685546875 +4956 -0.199981689453125 +4957 -0.499969482421875 +4958 -0.19635009765625 +4959 -0.490875244140625 +4960 -0.19268798828125 +4961 -0.481719970703125 +4962 -0.188995361328125 +4963 -0.4725341796875 +4964 -0.185302734375 +4965 -0.4632568359375 +4966 -0.18157958984375 +4967 -0.453948974609375 +4968 -0.177825927734375 +4969 -0.444610595703125 +4970 -0.174072265625 +4971 -0.435211181640625 +4972 -0.1702880859375 +4973 -0.425750732421875 +4974 -0.16650390625 +4975 -0.416259765625 +4976 -0.16265869140625 +4977 -0.406707763671875 +4978 -0.158843994140625 +4979 -0.397125244140625 +4980 -0.15496826171875 +4981 -0.387481689453125 +4982 -0.151123046875 +4983 -0.3778076171875 +4984 -0.147216796875 +4985 -0.36810302734375 +4986 -0.143310546875 +4987 -0.35833740234375 +4988 -0.139404296875 +4989 -0.348541259765625 +4990 -0.135467529296875 +4991 -0.338714599609375 +4992 -0.13153076171875 +4993 -0.328826904296875 +4994 -0.1275634765625 +4995 -0.318939208984375 +4996 -0.12359619140625 +4997 -0.308990478515625 +4998 -0.119598388671875 +4999 -0.29901123046875 +5000 -0.1156005859375 +5001 -0.28900146484375 +5002 -0.111572265625 +5003 -0.278961181640625 +5004 -0.1075439453125 +5005 -0.268890380859375 +5006 -0.103515625 +5007 -0.2587890625 +5008 -0.099456787109375 +5009 -0.2486572265625 +5010 -0.09539794921875 +5011 -0.238525390625 +5012 -0.09130859375 +5013 -0.22833251953125 +5014 -0.08721923828125 +5015 -0.218109130859375 +5016 -0.0831298828125 +5017 -0.2078857421875 +5018 -0.07904052734375 +5019 -0.1976318359375 +5020 -0.074920654296875 +5021 -0.187347412109375 +5022 -0.07080078125 +5023 -0.17706298828125 +5024 -0.066680908203125 +5025 -0.166748046875 +5026 -0.06256103515625 +5027 -0.156402587890625 +5028 -0.05841064453125 +5029 -0.14605712890625 +5030 -0.05426025390625 +5031 -0.13568115234375 +5032 -0.05010986328125 +5033 -0.12530517578125 +5034 -0.04595947265625 +5035 -0.11492919921875 +5036 -0.04180908203125 +5037 -0.104522705078125 +5038 -0.037628173828125 +5039 -0.094085693359375 +5040 -0.033447265625 +5041 -0.083648681640625 +5042 -0.029266357421875 +5043 -0.073211669921875 +5044 -0.02508544921875 +5045 -0.062774658203125 +5046 -0.020904541015625 +5047 -0.05230712890625 +5048 -0.0167236328125 +5049 -0.0418701171875 +5050 -0.012542724609375 +5051 -0.031402587890625 +5052 -0.00836181640625 +5053 -0.02093505859375 +5054 -0.004180908203125 +5055 -0.010467529296875 +5056 0.0 +5057 0.0 +5058 0.00408935546875 +5059 0.010467529296875 +5060 0.0081787109375 +5061 0.02093505859375 +5062 0.012298583984375 +5063 0.031402587890625 +5064 0.016387939453125 +5065 0.0418701171875 +5066 0.020477294921875 +5067 0.05230712890625 +5068 0.02459716796875 +5069 0.062774658203125 +5070 0.0286865234375 +5071 0.073211669921875 +5072 0.03277587890625 +5073 0.083648681640625 +5074 0.036865234375 +5075 0.094085693359375 +5076 0.04095458984375 +5077 0.104522705078125 +5078 0.0450439453125 +5079 0.11492919921875 +5080 0.049102783203125 +5081 0.12530517578125 +5082 0.05316162109375 +5083 0.13568115234375 +5084 0.0572509765625 +5085 0.14605712890625 +5086 0.061309814453125 +5087 0.156402587890625 +5088 0.065338134765625 +5089 0.166748046875 +5090 0.06939697265625 +5091 0.17706298828125 +5092 0.07342529296875 +5093 0.187347412109375 +5094 0.07745361328125 +5095 0.1976318359375 +5096 0.08148193359375 +5097 0.2078857421875 +5098 0.085479736328125 +5099 0.218109130859375 +5100 0.089508056640625 +5101 0.22833251953125 +5102 0.093475341796875 +5103 0.238525390625 +5104 0.09747314453125 +5105 0.2486572265625 +5106 0.1014404296875 +5107 0.2587890625 +5108 0.10540771484375 +5109 0.268890380859375 +5110 0.109344482421875 +5111 0.278961181640625 +5112 0.11328125 +5113 0.28900146484375 +5114 0.1171875 +5115 0.29901123046875 +5116 0.121124267578125 +5117 0.308990478515625 +5118 0.125 +5119 0.318939208984375 +5120 0.11834716796875 +5121 0.328826904296875 +5122 0.121917724609375 +5123 0.338714599609375 +5124 0.125457763671875 +5125 0.348541259765625 +5126 0.128997802734375 +5127 0.35833740234375 +5128 0.13250732421875 +5129 0.36810302734375 +5130 0.135986328125 +5131 0.3778076171875 +5132 0.13946533203125 +5133 0.387481689453125 +5134 0.1429443359375 +5135 0.397125244140625 +5136 0.146392822265625 +5137 0.406707763671875 +5138 0.14984130859375 +5139 0.416259765625 +5140 0.15325927734375 +5141 0.425750732421875 +5142 0.156646728515625 +5143 0.435211181640625 +5144 0.1600341796875 +5145 0.444610595703125 +5146 0.16339111328125 +5147 0.453948974609375 +5148 0.166748046875 +5149 0.4632568359375 +5150 0.17010498046875 +5151 0.4725341796875 +5152 0.17340087890625 +5153 0.481719970703125 +5154 0.17669677734375 +5155 0.490875244140625 +5156 0.179962158203125 +5157 0.499969482421875 +5158 0.1832275390625 +5159 0.509002685546875 +5160 0.18646240234375 +5161 0.51800537109375 +5162 0.189666748046875 +5163 0.52691650390625 +5164 0.19287109375 +5165 0.535797119140625 +5166 0.196044921875 +5167 0.54461669921875 +5168 0.199188232421875 +5169 0.5533447265625 +5170 0.20233154296875 +5171 0.562042236328125 +5172 0.205413818359375 +5173 0.5706787109375 +5174 0.208526611328125 +5175 0.579254150390625 +5176 0.211578369140625 +5177 0.587738037109375 +5178 0.214599609375 +5179 0.59619140625 +5180 0.217620849609375 +5181 0.60455322265625 +5182 0.220611572265625 +5183 0.612884521484375 +5184 0.223602294921875 +5185 0.621124267578125 +5186 0.226531982421875 +5187 0.6292724609375 +5188 0.22943115234375 +5189 0.63739013671875 +5190 0.232330322265625 +5191 0.645416259765625 +5192 0.235198974609375 +5193 0.65338134765625 +5194 0.238037109375 +5195 0.661285400390625 +5196 0.2408447265625 +5197 0.669097900390625 +5198 0.24365234375 +5199 0.676849365234375 +5200 0.24639892578125 +5201 0.68450927734375 +5202 0.2491455078125 +5203 0.692108154296875 +5204 0.2518310546875 +5205 0.699615478515625 +5206 0.2545166015625 +5207 0.707061767578125 +5208 0.257171630859375 +5209 0.714447021484375 +5210 0.259796142578125 +5211 0.721710205078125 +5212 0.26239013671875 +5213 0.72894287109375 +5214 0.26495361328125 +5215 0.736053466796875 +5216 0.267486572265625 +5217 0.74310302734375 +5218 0.269989013671875 +5219 0.75006103515625 +5220 0.272491455078125 +5221 0.7569580078125 +5222 0.274932861328125 +5223 0.763763427734375 +5224 0.27734375 +5225 0.770477294921875 +5226 0.27972412109375 +5227 0.777099609375 +5228 0.2821044921875 +5229 0.783660888671875 +5230 0.284423828125 +5231 0.790130615234375 +5232 0.286712646484375 +5233 0.796478271484375 +5234 0.288970947265625 +5235 0.802764892578125 +5236 0.291229248046875 +5237 0.808990478515625 +5238 0.293426513671875 +5239 0.815093994140625 +5240 0.29559326171875 +5241 0.82110595703125 +5242 0.297698974609375 +5243 0.8270263671875 +5244 0.299835205078125 +5245 0.8328857421875 +5246 0.3018798828125 +5247 0.838623046875 +5248 0.303924560546875 +5249 0.84429931640625 +5250 0.305938720703125 +5251 0.849853515625 +5252 0.307891845703125 +5253 0.855316162109375 +5254 0.309814453125 +5255 0.860687255859375 +5256 0.311737060546875 +5257 0.865997314453125 +5258 0.3135986328125 +5259 0.871185302734375 +5260 0.3154296875 +5261 0.876251220703125 +5262 0.317230224609375 +5263 0.881256103515625 +5264 0.319000244140625 +5265 0.88616943359375 +5266 0.32073974609375 +5267 0.890960693359375 +5268 0.322418212890625 +5269 0.895660400390625 +5270 0.324066162109375 +5271 0.9002685546875 +5272 0.325714111328125 +5273 0.90478515625 +5274 0.327301025390625 +5275 0.9091796875 +5276 0.328857421875 +5277 0.91351318359375 +5278 0.330352783203125 +5279 0.917724609375 +5280 0.33184814453125 +5281 0.92181396484375 +5282 0.333282470703125 +5283 0.92584228515625 +5284 0.334686279296875 +5285 0.929718017578125 +5286 0.3360595703125 +5287 0.93353271484375 +5288 0.337371826171875 +5289 0.937225341796875 +5290 0.33868408203125 +5291 0.940826416015625 +5292 0.339935302734375 +5293 0.9443359375 +5294 0.341156005859375 +5295 0.947723388671875 +5296 0.34234619140625 +5297 0.951019287109375 +5298 0.343505859375 +5299 0.954193115234375 +5300 0.3446044921875 +5301 0.957275390625 +5302 0.345672607421875 +5303 0.960235595703125 +5304 0.346710205078125 +5305 0.963104248046875 +5306 0.347686767578125 +5307 0.96588134765625 +5308 0.348663330078125 +5309 0.968536376953125 +5310 0.349578857421875 +5311 0.971099853515625 +5312 0.3504638671875 +5313 0.973541259765625 +5314 0.351287841796875 +5315 0.975860595703125 +5316 0.352081298828125 +5317 0.97808837890625 +5318 0.352874755859375 +5319 0.980224609375 +5320 0.35357666015625 +5321 0.98223876953125 +5322 0.354278564453125 +5323 0.984161376953125 +5324 0.35491943359375 +5325 0.9859619140625 +5326 0.35552978515625 +5327 0.987640380859375 +5328 0.356109619140625 +5329 0.989227294921875 +5330 0.35662841796875 +5331 0.990692138671875 +5332 0.35711669921875 +5333 0.9920654296875 +5334 0.357574462890625 +5335 0.993316650390625 +5336 0.358001708984375 +5337 0.994476318359375 +5338 0.358367919921875 +5339 0.995513916015625 +5340 0.35870361328125 +5341 0.9964599609375 +5342 0.3590087890625 +5343 0.997283935546875 +5344 0.3592529296875 +5345 0.99798583984375 +5346 0.359466552734375 +5347 0.99859619140625 +5348 0.359649658203125 +5349 0.999114990234375 +5350 0.359771728515625 +5351 0.999481201171875 +5352 0.359893798828125 +5353 0.999755859375 +5354 0.359954833984375 +5355 0.99993896484375 +5356 0.3599853515625 +5357 0.999969482421875 +5358 0.359954833984375 +5359 0.99993896484375 +5360 0.359893798828125 +5361 0.999755859375 +5362 0.359771728515625 +5363 0.999481201171875 +5364 0.359649658203125 +5365 0.999114990234375 +5366 0.359466552734375 +5367 0.99859619140625 +5368 0.3592529296875 +5369 0.99798583984375 +5370 0.3590087890625 +5371 0.997283935546875 +5372 0.35870361328125 +5373 0.9964599609375 +5374 0.358367919921875 +5375 0.995513916015625 +5376 0.326171875 +5377 0.994476318359375 +5378 0.3258056640625 +5379 0.993316650390625 +5380 0.325408935546875 +5381 0.9920654296875 +5382 0.324951171875 +5383 0.990692138671875 +5384 0.324462890625 +5385 0.989227294921875 +5386 0.323944091796875 +5387 0.987640380859375 +5388 0.323394775390625 +5389 0.9859619140625 +5390 0.32281494140625 +5391 0.984161376953125 +5392 0.322174072265625 +5393 0.98223876953125 +5394 0.321502685546875 +5395 0.980224609375 +5396 0.32080078125 +5397 0.97808837890625 +5398 0.320068359375 +5399 0.975860595703125 +5400 0.319305419921875 +5401 0.973541259765625 +5402 0.318511962890625 +5403 0.971099853515625 +5404 0.31768798828125 +5405 0.968536376953125 +5406 0.316802978515625 +5407 0.96588134765625 +5408 0.315887451171875 +5409 0.963104248046875 +5410 0.31494140625 +5411 0.960235595703125 +5412 0.313995361328125 +5413 0.957275390625 +5414 0.312957763671875 +5415 0.954193115234375 +5416 0.311920166015625 +5417 0.951019287109375 +5418 0.31085205078125 +5419 0.947723388671875 +5420 0.30975341796875 +5421 0.9443359375 +5422 0.30859375 +5423 0.940826416015625 +5424 0.307403564453125 +5425 0.937225341796875 +5426 0.306182861328125 +5427 0.93353271484375 +5428 0.304931640625 +5429 0.929718017578125 +5430 0.303680419921875 +5431 0.92584228515625 +5432 0.302337646484375 +5433 0.92181396484375 +5434 0.301025390625 +5435 0.917724609375 +5436 0.29962158203125 +5437 0.91351318359375 +5438 0.2982177734375 +5439 0.9091796875 +5440 0.2967529296875 +5441 0.90478515625 +5442 0.2952880859375 +5443 0.9002685546875 +5444 0.29376220703125 +5445 0.895660400390625 +5446 0.292236328125 +5447 0.890960693359375 +5448 0.2906494140625 +5449 0.88616943359375 +5450 0.2890625 +5451 0.881256103515625 +5452 0.28741455078125 +5453 0.876251220703125 +5454 0.285736083984375 +5455 0.871185302734375 +5456 0.2840576171875 +5457 0.865997314453125 +5458 0.28228759765625 +5459 0.860687255859375 +5460 0.280548095703125 +5461 0.855316162109375 +5462 0.27874755859375 +5463 0.849853515625 +5464 0.27691650390625 +5465 0.84429931640625 +5466 0.275054931640625 +5467 0.838623046875 +5468 0.273193359375 +5469 0.8328857421875 +5470 0.271270751953125 +5471 0.8270263671875 +5472 0.269317626953125 +5473 0.82110595703125 +5474 0.267333984375 +5475 0.815093994140625 +5476 0.265350341796875 +5477 0.808990478515625 +5478 0.2633056640625 +5479 0.802764892578125 +5480 0.26123046875 +5481 0.796478271484375 +5482 0.2591552734375 +5483 0.790130615234375 +5484 0.257049560546875 +5485 0.783660888671875 +5486 0.2548828125 +5487 0.777099609375 +5488 0.252716064453125 +5489 0.770477294921875 +5490 0.250518798828125 +5491 0.763763427734375 +5492 0.248291015625 +5493 0.7569580078125 +5494 0.246002197265625 +5495 0.75006103515625 +5496 0.243743896484375 +5497 0.74310302734375 +5498 0.241424560546875 +5499 0.736053466796875 +5500 0.23907470703125 +5501 0.72894287109375 +5502 0.236724853515625 +5503 0.721710205078125 +5504 0.234344482421875 +5505 0.714447021484375 +5506 0.231903076171875 +5507 0.707061767578125 +5508 0.229461669921875 +5509 0.699615478515625 +5510 0.227020263671875 +5511 0.692108154296875 +5512 0.224517822265625 +5513 0.68450927734375 +5514 0.22198486328125 +5515 0.676849365234375 +5516 0.219451904296875 +5517 0.669097900390625 +5518 0.216888427734375 +5519 0.661285400390625 +5520 0.21429443359375 +5521 0.65338134765625 +5522 0.211700439453125 +5523 0.645416259765625 +5524 0.20904541015625 +5525 0.63739013671875 +5526 0.206390380859375 +5527 0.6292724609375 +5528 0.2037353515625 +5529 0.621124267578125 +5530 0.201019287109375 +5531 0.612884521484375 +5532 0.198272705078125 +5533 0.60455322265625 +5534 0.195556640625 +5535 0.59619140625 +5536 0.192779541015625 +5537 0.587738037109375 +5538 0.19000244140625 +5539 0.579254150390625 +5540 0.187164306640625 +5541 0.5706787109375 +5542 0.184356689453125 +5543 0.562042236328125 +5544 0.181488037109375 +5545 0.5533447265625 +5546 0.178619384765625 +5547 0.54461669921875 +5548 0.17572021484375 +5549 0.535797119140625 +5550 0.172821044921875 +5551 0.52691650390625 +5552 0.169891357421875 +5553 0.51800537109375 +5554 0.16693115234375 +5555 0.509002685546875 +5556 0.163970947265625 +5557 0.499969482421875 +5558 0.1610107421875 +5559 0.490875244140625 +5560 0.157989501953125 +5561 0.481719970703125 +5562 0.15496826171875 +5563 0.4725341796875 +5564 0.151947021484375 +5565 0.4632568359375 +5566 0.148895263671875 +5567 0.453948974609375 +5568 0.14581298828125 +5569 0.444610595703125 +5570 0.142730712890625 +5571 0.435211181640625 +5572 0.1396484375 +5573 0.425750732421875 +5574 0.13653564453125 +5575 0.416259765625 +5576 0.133392333984375 +5577 0.406707763671875 +5578 0.1302490234375 +5579 0.397125244140625 +5580 0.1270751953125 +5581 0.387481689453125 +5582 0.1239013671875 +5583 0.3778076171875 +5584 0.1207275390625 +5585 0.36810302734375 +5586 0.117523193359375 +5587 0.35833740234375 +5588 0.11431884765625 +5589 0.348541259765625 +5590 0.111083984375 +5591 0.338714599609375 +5592 0.10784912109375 +5593 0.328826904296875 +5594 0.1046142578125 +5595 0.318939208984375 +5596 0.101348876953125 +5597 0.308990478515625 +5598 0.098052978515625 +5599 0.29901123046875 +5600 0.09478759765625 +5601 0.28900146484375 +5602 0.09149169921875 +5603 0.278961181640625 +5604 0.08819580078125 +5605 0.268890380859375 +5606 0.084869384765625 +5607 0.2587890625 +5608 0.08154296875 +5609 0.2486572265625 +5610 0.078216552734375 +5611 0.238525390625 +5612 0.07489013671875 +5613 0.22833251953125 +5614 0.071533203125 +5615 0.218109130859375 +5616 0.06817626953125 +5617 0.2078857421875 +5618 0.0648193359375 +5619 0.1976318359375 +5620 0.061431884765625 +5621 0.187347412109375 +5622 0.058074951171875 +5623 0.17706298828125 +5624 0.0546875 +5625 0.166748046875 +5626 0.051300048828125 +5627 0.156402587890625 +5628 0.047882080078125 +5629 0.14605712890625 +5630 0.04449462890625 +5631 0.13568115234375 +5632 0.037078857421875 +5633 0.12530517578125 +5634 0.03399658203125 +5635 0.11492919921875 +5636 0.030914306640625 +5637 0.104522705078125 +5638 0.02783203125 +5639 0.094085693359375 +5640 0.024749755859375 +5641 0.083648681640625 +5642 0.02166748046875 +5643 0.073211669921875 +5644 0.0185546875 +5645 0.062774658203125 +5646 0.015472412109375 +5647 0.05230712890625 +5648 0.01239013671875 +5649 0.0418701171875 +5650 0.00927734375 +5651 0.031402587890625 +5652 0.006195068359375 +5653 0.02093505859375 +5654 0.003082275390625 +5655 0.010467529296875 +5656 0.0 +5657 0.0 +5658 -0.003082275390625 +5659 -0.010467529296875 +5660 -0.006195068359375 +5661 -0.02093505859375 +5662 -0.00927734375 +5663 -0.031402587890625 +5664 -0.01239013671875 +5665 -0.0418701171875 +5666 -0.015472412109375 +5667 -0.05230712890625 +5668 -0.0185546875 +5669 -0.062774658203125 +5670 -0.02166748046875 +5671 -0.073211669921875 +5672 -0.024749755859375 +5673 -0.083648681640625 +5674 -0.02783203125 +5675 -0.094085693359375 +5676 -0.030914306640625 +5677 -0.104522705078125 +5678 -0.03399658203125 +5679 -0.11492919921875 +5680 -0.037078857421875 +5681 -0.12530517578125 +5682 -0.0401611328125 +5683 -0.13568115234375 +5684 -0.043212890625 +5685 -0.14605712890625 +5686 -0.0462646484375 +5687 -0.156402587890625 +5688 -0.049346923828125 +5689 -0.166748046875 +5690 -0.052398681640625 +5691 -0.17706298828125 +5692 -0.055450439453125 +5693 -0.187347412109375 +5694 -0.0584716796875 +5695 -0.1976318359375 +5696 -0.0615234375 +5697 -0.2078857421875 +5698 -0.064544677734375 +5699 -0.218109130859375 +5700 -0.06756591796875 +5701 -0.22833251953125 +5702 -0.070587158203125 +5703 -0.238525390625 +5704 -0.073577880859375 +5705 -0.2486572265625 +5706 -0.07659912109375 +5707 -0.2587890625 +5708 -0.07958984375 +5709 -0.268890380859375 +5710 -0.082550048828125 +5711 -0.278961181640625 +5712 -0.085540771484375 +5713 -0.28900146484375 +5714 -0.0885009765625 +5715 -0.29901123046875 +5716 -0.0914306640625 +5717 -0.308990478515625 +5718 -0.094390869140625 +5719 -0.318939208984375 +5720 -0.097320556640625 +5721 -0.328826904296875 +5722 -0.100250244140625 +5723 -0.338714599609375 +5724 -0.1031494140625 +5725 -0.348541259765625 +5726 -0.106048583984375 +5727 -0.35833740234375 +5728 -0.10894775390625 +5729 -0.36810302734375 +5730 -0.11181640625 +5731 -0.3778076171875 +5732 -0.11468505859375 +5733 -0.387481689453125 +5734 -0.117523193359375 +5735 -0.397125244140625 +5736 -0.120361328125 +5737 -0.406707763671875 +5738 -0.123199462890625 +5739 -0.416259765625 +5740 -0.126007080078125 +5741 -0.425750732421875 +5742 -0.128814697265625 +5743 -0.435211181640625 +5744 -0.131591796875 +5745 -0.444610595703125 +5746 -0.13433837890625 +5747 -0.453948974609375 +5748 -0.137115478515625 +5749 -0.4632568359375 +5750 -0.139862060546875 +5751 -0.4725341796875 +5752 -0.142578125 +5753 -0.481719970703125 +5754 -0.145294189453125 +5755 -0.490875244140625 +5756 -0.147979736328125 +5757 -0.499969482421875 +5758 -0.150634765625 +5759 -0.509002685546875 +5760 -0.1533203125 +5761 -0.51800537109375 +5762 -0.15594482421875 +5763 -0.52691650390625 +5764 -0.1585693359375 +5765 -0.535797119140625 +5766 -0.16119384765625 +5767 -0.54461669921875 +5768 -0.163787841796875 +5769 -0.5533447265625 +5770 -0.166351318359375 +5771 -0.562042236328125 +5772 -0.168914794921875 +5773 -0.5706787109375 +5774 -0.17144775390625 +5775 -0.579254150390625 +5776 -0.1739501953125 +5777 -0.587738037109375 +5778 -0.17645263671875 +5779 -0.59619140625 +5780 -0.178924560546875 +5781 -0.60455322265625 +5782 -0.181396484375 +5783 -0.612884521484375 +5784 -0.183837890625 +5785 -0.621124267578125 +5786 -0.186248779296875 +5787 -0.6292724609375 +5788 -0.18865966796875 +5789 -0.63739013671875 +5790 -0.1910400390625 +5791 -0.645416259765625 +5792 -0.193389892578125 +5793 -0.65338134765625 +5794 -0.19573974609375 +5795 -0.661285400390625 +5796 -0.198028564453125 +5797 -0.669097900390625 +5798 -0.2003173828125 +5799 -0.676849365234375 +5800 -0.202606201171875 +5801 -0.68450927734375 +5802 -0.204833984375 +5803 -0.692108154296875 +5804 -0.207061767578125 +5805 -0.699615478515625 +5806 -0.20928955078125 +5807 -0.707061767578125 +5808 -0.211456298828125 +5809 -0.714447021484375 +5810 -0.213623046875 +5811 -0.721710205078125 +5812 -0.21575927734375 +5813 -0.72894287109375 +5814 -0.217864990234375 +5815 -0.736053466796875 +5816 -0.219940185546875 +5817 -0.74310302734375 +5818 -0.222015380859375 +5819 -0.75006103515625 +5820 -0.224029541015625 +5821 -0.7569580078125 +5822 -0.226043701171875 +5823 -0.763763427734375 +5824 -0.228057861328125 +5825 -0.770477294921875 +5826 -0.230010986328125 +5827 -0.777099609375 +5828 -0.23193359375 +5829 -0.783660888671875 +5830 -0.233856201171875 +5831 -0.790130615234375 +5832 -0.235748291015625 +5833 -0.796478271484375 +5834 -0.23760986328125 +5835 -0.802764892578125 +5836 -0.23944091796875 +5837 -0.808990478515625 +5838 -0.241241455078125 +5839 -0.815093994140625 +5840 -0.2430419921875 +5841 -0.82110595703125 +5842 -0.244781494140625 +5843 -0.8270263671875 +5844 -0.24652099609375 +5845 -0.8328857421875 +5846 -0.24822998046875 +5847 -0.838623046875 +5848 -0.249908447265625 +5849 -0.84429931640625 +5850 -0.25152587890625 +5851 -0.849853515625 +5852 -0.253143310546875 +5853 -0.855316162109375 +5854 -0.2547607421875 +5855 -0.860687255859375 +5856 -0.256317138671875 +5857 -0.865997314453125 +5858 -0.257843017578125 +5859 -0.871185302734375 +5860 -0.259368896484375 +5861 -0.876251220703125 +5862 -0.260833740234375 +5863 -0.881256103515625 +5864 -0.262298583984375 +5865 -0.88616943359375 +5866 -0.263702392578125 +5867 -0.890960693359375 +5868 -0.265106201171875 +5869 -0.895660400390625 +5870 -0.266448974609375 +5871 -0.9002685546875 +5872 -0.267791748046875 +5873 -0.90478515625 +5874 -0.26910400390625 +5875 -0.9091796875 +5876 -0.2703857421875 +5877 -0.91351318359375 +5878 -0.271636962890625 +5879 -0.917724609375 +5880 -0.2728271484375 +5881 -0.92181396484375 +5882 -0.2740478515625 +5883 -0.92584228515625 +5884 -0.275177001953125 +5885 -0.929718017578125 +5886 -0.27630615234375 +5887 -0.93353271484375 +5888 -0.247406005859375 +5889 -0.937225341796875 +5890 -0.24835205078125 +5891 -0.940826416015625 +5892 -0.249267578125 +5893 -0.9443359375 +5894 -0.25018310546875 +5895 -0.947723388671875 +5896 -0.25103759765625 +5897 -0.951019287109375 +5898 -0.25189208984375 +5899 -0.954193115234375 +5900 -0.252685546875 +5901 -0.957275390625 +5902 -0.25347900390625 +5903 -0.960235595703125 +5904 -0.254241943359375 +5905 -0.963104248046875 +5906 -0.254974365234375 +5907 -0.96588134765625 +5908 -0.25567626953125 +5909 -0.968536376953125 +5910 -0.25634765625 +5911 -0.971099853515625 +5912 -0.256988525390625 +5913 -0.973541259765625 +5914 -0.257598876953125 +5915 -0.975860595703125 +5916 -0.2581787109375 +5917 -0.97808837890625 +5918 -0.258758544921875 +5919 -0.980224609375 +5920 -0.25927734375 +5921 -0.98223876953125 +5922 -0.259796142578125 +5923 -0.984161376953125 +5924 -0.26025390625 +5925 -0.9859619140625 +5926 -0.260711669921875 +5927 -0.987640380859375 +5928 -0.261138916015625 +5929 -0.989227294921875 +5930 -0.261505126953125 +5931 -0.990692138671875 +5932 -0.261871337890625 +5933 -0.9920654296875 +5934 -0.26220703125 +5935 -0.993316650390625 +5936 -0.26251220703125 +5937 -0.994476318359375 +5938 -0.262786865234375 +5939 -0.995513916015625 +5940 -0.263031005859375 +5941 -0.9964599609375 +5942 -0.26324462890625 +5943 -0.997283935546875 +5944 -0.263427734375 +5945 -0.99798583984375 +5946 -0.26361083984375 +5947 -0.99859619140625 +5948 -0.26373291015625 +5949 -0.999114990234375 +5950 -0.263824462890625 +5951 -0.999481201171875 +5952 -0.263885498046875 +5953 -0.999755859375 +5954 -0.263946533203125 +5955 -0.99993896484375 +5956 -0.26397705078125 +5957 -1.0 +5958 -0.263946533203125 +5959 -0.99993896484375 +5960 -0.263885498046875 +5961 -0.999755859375 +5962 -0.263824462890625 +5963 -0.999481201171875 +5964 -0.26373291015625 +5965 -0.999114990234375 +5966 -0.26361083984375 +5967 -0.99859619140625 +5968 -0.263427734375 +5969 -0.99798583984375 +5970 -0.26324462890625 +5971 -0.997283935546875 +5972 -0.263031005859375 +5973 -0.9964599609375 +5974 -0.262786865234375 +5975 -0.995513916015625 +5976 -0.26251220703125 +5977 -0.994476318359375 +5978 -0.26220703125 +5979 -0.993316650390625 +5980 -0.261871337890625 +5981 -0.9920654296875 +5982 -0.261505126953125 +5983 -0.990692138671875 +5984 -0.261138916015625 +5985 -0.989227294921875 +5986 -0.260711669921875 +5987 -0.987640380859375 +5988 -0.26025390625 +5989 -0.9859619140625 +5990 -0.259796142578125 +5991 -0.984161376953125 +5992 -0.25927734375 +5993 -0.98223876953125 +5994 -0.258758544921875 +5995 -0.980224609375 +5996 -0.2581787109375 +5997 -0.97808837890625 +5998 -0.257598876953125 +5999 -0.975860595703125 +6000 -0.256988525390625 +6001 -0.973541259765625 +6002 -0.25634765625 +6003 -0.971099853515625 +6004 -0.25567626953125 +6005 -0.968536376953125 +6006 -0.254974365234375 +6007 -0.96588134765625 +6008 -0.254241943359375 +6009 -0.963104248046875 +6010 -0.25347900390625 +6011 -0.960235595703125 +6012 -0.252685546875 +6013 -0.957275390625 +6014 -0.25189208984375 +6015 -0.954193115234375 +6016 -0.25103759765625 +6017 -0.951019287109375 +6018 -0.25018310546875 +6019 -0.947723388671875 +6020 -0.249267578125 +6021 -0.9443359375 +6022 -0.24835205078125 +6023 -0.940826416015625 +6024 -0.247406005859375 +6025 -0.937225341796875 +6026 -0.246429443359375 +6027 -0.93353271484375 +6028 -0.24542236328125 +6029 -0.929718017578125 +6030 -0.244384765625 +6031 -0.92584228515625 +6032 -0.243316650390625 +6033 -0.92181396484375 +6034 -0.24224853515625 +6035 -0.917724609375 +6036 -0.24114990234375 +6037 -0.91351318359375 +6038 -0.239990234375 +6039 -0.9091796875 +6040 -0.23883056640625 +6041 -0.90478515625 +6042 -0.237640380859375 +6043 -0.9002685546875 +6044 -0.236419677734375 +6045 -0.895660400390625 +6046 -0.235198974609375 +6047 -0.890960693359375 +6048 -0.233917236328125 +6049 -0.88616943359375 +6050 -0.232635498046875 +6051 -0.881256103515625 +6052 -0.231292724609375 +6053 -0.876251220703125 +6054 -0.229949951171875 +6055 -0.871185302734375 +6056 -0.228607177734375 +6057 -0.865997314453125 +6058 -0.227203369140625 +6059 -0.860687255859375 +6060 -0.22576904296875 +6061 -0.855316162109375 +6062 -0.224334716796875 +6063 -0.849853515625 +6064 -0.222869873046875 +6065 -0.84429931640625 +6066 -0.22137451171875 +6067 -0.838623046875 +6068 -0.2198486328125 +6069 -0.8328857421875 +6070 -0.218292236328125 +6071 -0.8270263671875 +6072 -0.21673583984375 +6073 -0.82110595703125 +6074 -0.21514892578125 +6075 -0.815093994140625 +6076 -0.213531494140625 +6077 -0.808990478515625 +6078 -0.2119140625 +6079 -0.802764892578125 +6080 -0.210235595703125 +6081 -0.796478271484375 +6082 -0.20855712890625 +6083 -0.790130615234375 +6084 -0.20684814453125 +6085 -0.783660888671875 +6086 -0.20513916015625 +6087 -0.777099609375 +6088 -0.203369140625 +6089 -0.770477294921875 +6090 -0.20159912109375 +6091 -0.763763427734375 +6092 -0.199798583984375 +6093 -0.7569580078125 +6094 -0.197998046875 +6095 -0.75006103515625 +6096 -0.1961669921875 +6097 -0.74310302734375 +6098 -0.194305419921875 +6099 -0.736053466796875 +6100 -0.192413330078125 +6101 -0.72894287109375 +6102 -0.19049072265625 +6103 -0.721710205078125 +6104 -0.1885986328125 +6105 -0.714447021484375 +6106 -0.1866455078125 +6107 -0.707061767578125 +6108 -0.184661865234375 +6109 -0.699615478515625 +6110 -0.18267822265625 +6111 -0.692108154296875 +6112 -0.180694580078125 +6113 -0.68450927734375 +6114 -0.17864990234375 +6115 -0.676849365234375 +6116 -0.176605224609375 +6117 -0.669097900390625 +6118 -0.174560546875 +6119 -0.661285400390625 +6120 -0.172454833984375 +6121 -0.65338134765625 +6122 -0.170379638671875 +6123 -0.645416259765625 +6124 -0.168243408203125 +6125 -0.63739013671875 +6126 -0.166107177734375 +6127 -0.6292724609375 +6128 -0.1639404296875 +6129 -0.621124267578125 +6130 -0.161773681640625 +6131 -0.612884521484375 +6132 -0.159576416015625 +6133 -0.60455322265625 +6134 -0.157379150390625 +6135 -0.59619140625 +6136 -0.1551513671875 +6137 -0.587738037109375 +6138 -0.15289306640625 +6139 -0.579254150390625 +6140 -0.150634765625 +6141 -0.5706787109375 +6142 -0.148345947265625 +6143 -0.562042236328125 +6144 -0.138336181640625 +6145 -0.5533447265625 +6146 -0.136138916015625 +6147 -0.54461669921875 +6148 -0.133941650390625 +6149 -0.535797119140625 +6150 -0.1317138671875 +6151 -0.52691650390625 +6152 -0.129486083984375 +6153 -0.51800537109375 +6154 -0.127227783203125 +6155 -0.509002685546875 +6156 -0.124969482421875 +6157 -0.499969482421875 +6158 -0.122711181640625 +6159 -0.490875244140625 +6160 -0.12042236328125 +6161 -0.481719970703125 +6162 -0.118133544921875 +6163 -0.4725341796875 +6164 -0.115814208984375 +6165 -0.4632568359375 +6166 -0.11346435546875 +6167 -0.453948974609375 +6168 -0.11114501953125 +6169 -0.444610595703125 +6170 -0.108795166015625 +6171 -0.435211181640625 +6172 -0.106414794921875 +6173 -0.425750732421875 +6174 -0.10406494140625 +6175 -0.416259765625 +6176 -0.101654052734375 +6177 -0.406707763671875 +6178 -0.099273681640625 +6179 -0.397125244140625 +6180 -0.09686279296875 +6181 -0.387481689453125 +6182 -0.094451904296875 +6183 -0.3778076171875 +6184 -0.092010498046875 +6185 -0.36810302734375 +6186 -0.089569091796875 +6187 -0.35833740234375 +6188 -0.087127685546875 +6189 -0.348541259765625 +6190 -0.08465576171875 +6191 -0.338714599609375 +6192 -0.082183837890625 +6193 -0.328826904296875 +6194 -0.0797119140625 +6195 -0.318939208984375 +6196 -0.077239990234375 +6197 -0.308990478515625 +6198 -0.074737548828125 +6199 -0.29901123046875 +6200 -0.072235107421875 +6201 -0.28900146484375 +6202 -0.069732666015625 +6203 -0.278961181640625 +6204 -0.06719970703125 +6205 -0.268890380859375 +6206 -0.064697265625 +6207 -0.2587890625 +6208 -0.062164306640625 +6209 -0.2486572265625 +6210 -0.05963134765625 +6211 -0.238525390625 +6212 -0.05706787109375 +6213 -0.22833251953125 +6214 -0.05450439453125 +6215 -0.218109130859375 +6216 -0.051971435546875 +6217 -0.2078857421875 +6218 -0.049407958984375 +6219 -0.1976318359375 +6220 -0.04681396484375 +6221 -0.187347412109375 +6222 -0.04425048828125 +6223 -0.17706298828125 +6224 -0.04168701171875 +6225 -0.166748046875 +6226 -0.039093017578125 +6227 -0.156402587890625 +6228 -0.0364990234375 +6229 -0.14605712890625 +6230 -0.033905029296875 +6231 -0.13568115234375 +6232 -0.03131103515625 +6233 -0.12530517578125 +6234 -0.028717041015625 +6235 -0.11492919921875 +6236 -0.026123046875 +6237 -0.104522705078125 +6238 -0.02349853515625 +6239 -0.094085693359375 +6240 -0.020904541015625 +6241 -0.083648681640625 +6242 -0.018280029296875 +6243 -0.073211669921875 +6244 -0.01568603515625 +6245 -0.062774658203125 +6246 -0.0130615234375 +6247 -0.05230712890625 +6248 -0.010467529296875 +6249 -0.0418701171875 +6250 -0.007843017578125 +6251 -0.031402587890625 +6252 -0.005218505859375 +6253 -0.02093505859375 +6254 -0.002593994140625 +6255 -0.010467529296875 +6256 0.0 +6257 0.0 +6258 0.002410888671875 +6259 0.010467529296875 +6260 0.004852294921875 +6261 0.02093505859375 +6262 0.00726318359375 +6263 0.031402587890625 +6264 0.00970458984375 +6265 0.0418701171875 +6266 0.012115478515625 +6267 0.05230712890625 +6268 0.014556884765625 +6269 0.062774658203125 +6270 0.0169677734375 +6271 0.073211669921875 +6272 0.019378662109375 +6273 0.083648681640625 +6274 0.021820068359375 +6275 0.094085693359375 +6276 0.02423095703125 +6277 0.104522705078125 +6278 0.026641845703125 +6279 0.11492919921875 +6280 0.029052734375 +6281 0.12530517578125 +6282 0.031463623046875 +6283 0.13568115234375 +6284 0.03387451171875 +6285 0.14605712890625 +6286 0.036285400390625 +6287 0.156402587890625 +6288 0.038665771484375 +6289 0.166748046875 +6290 0.04107666015625 +6291 0.17706298828125 +6292 0.04345703125 +6293 0.187347412109375 +6294 0.04583740234375 +6295 0.1976318359375 +6296 0.0482177734375 +6297 0.2078857421875 +6298 0.05059814453125 +6299 0.218109130859375 +6300 0.052947998046875 +6301 0.22833251953125 +6302 0.055328369140625 +6303 0.238525390625 +6304 0.05767822265625 +6305 0.2486572265625 +6306 0.060028076171875 +6307 0.2587890625 +6308 0.0623779296875 +6309 0.268890380859375 +6310 0.064697265625 +6311 0.278961181640625 +6312 0.067047119140625 +6313 0.28900146484375 +6314 0.069366455078125 +6315 0.29901123046875 +6316 0.071685791015625 +6317 0.308990478515625 +6318 0.073974609375 +6319 0.318939208984375 +6320 0.076263427734375 +6321 0.328826904296875 +6322 0.07855224609375 +6323 0.338714599609375 +6324 0.080841064453125 +6325 0.348541259765625 +6326 0.0831298828125 +6327 0.35833740234375 +6328 0.08538818359375 +6329 0.36810302734375 +6330 0.087646484375 +6331 0.3778076171875 +6332 0.089874267578125 +6333 0.387481689453125 +6334 0.092132568359375 +6335 0.397125244140625 +6336 0.094329833984375 +6337 0.406707763671875 +6338 0.0965576171875 +6339 0.416259765625 +6340 0.0987548828125 +6341 0.425750732421875 +6342 0.1009521484375 +6343 0.435211181640625 +6344 0.1031494140625 +6345 0.444610595703125 +6346 0.105316162109375 +6347 0.453948974609375 +6348 0.107452392578125 +6349 0.4632568359375 +6350 0.109619140625 +6351 0.4725341796875 +6352 0.11175537109375 +6353 0.481719970703125 +6354 0.113861083984375 +6355 0.490875244140625 +6356 0.115966796875 +6357 0.499969482421875 +6358 0.118072509765625 +6359 0.509002685546875 +6360 0.120147705078125 +6361 0.51800537109375 +6362 0.122222900390625 +6363 0.52691650390625 +6364 0.124298095703125 +6365 0.535797119140625 +6366 0.1263427734375 +6367 0.54461669921875 +6368 0.12835693359375 +6369 0.5533447265625 +6370 0.13037109375 +6371 0.562042236328125 +6372 0.13238525390625 +6373 0.5706787109375 +6374 0.134368896484375 +6375 0.579254150390625 +6376 0.1363525390625 +6377 0.587738037109375 +6378 0.1383056640625 +6379 0.59619140625 +6380 0.140228271484375 +6381 0.60455322265625 +6382 0.142181396484375 +6383 0.612884521484375 +6384 0.144073486328125 +6385 0.621124267578125 +6386 0.145965576171875 +6387 0.6292724609375 +6388 0.147857666015625 +6389 0.63739013671875 +6390 0.14971923828125 +6391 0.645416259765625 +6392 0.151580810546875 +6393 0.65338134765625 +6394 0.153411865234375 +6395 0.661285400390625 +6396 0.15521240234375 +6397 0.669097900390625 +6398 0.157012939453125 +6399 0.676849365234375 +6400 0.136871337890625 +6401 0.68450927734375 +6402 0.138397216796875 +6403 0.692108154296875 +6404 0.139892578125 +6405 0.699615478515625 +6406 0.141387939453125 +6407 0.707061767578125 +6408 0.142852783203125 +6409 0.714447021484375 +6410 0.144317626953125 +6411 0.721710205078125 +6412 0.145751953125 +6413 0.72894287109375 +6414 0.147186279296875 +6415 0.736053466796875 +6416 0.148590087890625 +6417 0.74310302734375 +6418 0.149993896484375 +6419 0.75006103515625 +6420 0.1513671875 +6421 0.7569580078125 +6422 0.152740478515625 +6423 0.763763427734375 +6424 0.154083251953125 +6425 0.770477294921875 +6426 0.1553955078125 +6427 0.777099609375 +6428 0.156707763671875 +6429 0.783660888671875 +6430 0.157989501953125 +6431 0.790130615234375 +6432 0.159271240234375 +6433 0.796478271484375 +6434 0.1605224609375 +6435 0.802764892578125 +6436 0.161773681640625 +6437 0.808990478515625 +6438 0.162994384765625 +6439 0.815093994140625 +6440 0.1641845703125 +6441 0.82110595703125 +6442 0.165374755859375 +6443 0.8270263671875 +6444 0.16656494140625 +6445 0.8328857421875 +6446 0.167694091796875 +6447 0.838623046875 +6448 0.1688232421875 +6449 0.84429931640625 +6450 0.169952392578125 +6451 0.849853515625 +6452 0.171051025390625 +6453 0.855316162109375 +6454 0.172119140625 +6455 0.860687255859375 +6456 0.173187255859375 +6457 0.865997314453125 +6458 0.174224853515625 +6459 0.871185302734375 +6460 0.17523193359375 +6461 0.876251220703125 +6462 0.176239013671875 +6463 0.881256103515625 +6464 0.177215576171875 +6465 0.88616943359375 +6466 0.17816162109375 +6467 0.890960693359375 +6468 0.179107666015625 +6469 0.895660400390625 +6470 0.180023193359375 +6471 0.9002685546875 +6472 0.180938720703125 +6473 0.90478515625 +6474 0.18182373046875 +6475 0.9091796875 +6476 0.18267822265625 +6477 0.91351318359375 +6478 0.18353271484375 +6479 0.917724609375 +6480 0.184326171875 +6481 0.92181396484375 +6482 0.185150146484375 +6483 0.92584228515625 +6484 0.1859130859375 +6485 0.929718017578125 +6486 0.186676025390625 +6487 0.93353271484375 +6488 0.187408447265625 +6489 0.937225341796875 +6490 0.188140869140625 +6491 0.940826416015625 +6492 0.1888427734375 +6493 0.9443359375 +6494 0.18951416015625 +6495 0.947723388671875 +6496 0.190185546875 +6497 0.951019287109375 +6498 0.190826416015625 +6499 0.954193115234375 +6500 0.191436767578125 +6501 0.957275390625 +6502 0.1920166015625 +6503 0.960235595703125 +6504 0.192596435546875 +6505 0.963104248046875 +6506 0.193145751953125 +6507 0.96588134765625 +6508 0.193695068359375 +6509 0.968536376953125 +6510 0.194183349609375 +6511 0.971099853515625 +6512 0.194671630859375 +6513 0.973541259765625 +6514 0.195159912109375 +6515 0.975860595703125 +6516 0.195587158203125 +6517 0.97808837890625 +6518 0.196014404296875 +6519 0.980224609375 +6520 0.1964111328125 +6521 0.98223876953125 +6522 0.196807861328125 +6523 0.984161376953125 +6524 0.197174072265625 +6525 0.9859619140625 +6526 0.197509765625 +6527 0.987640380859375 +6528 0.19781494140625 +6529 0.989227294921875 +6530 0.1981201171875 +6531 0.990692138671875 +6532 0.198394775390625 +6533 0.9920654296875 +6534 0.198638916015625 +6535 0.993316650390625 +6536 0.198883056640625 +6537 0.994476318359375 +6538 0.199066162109375 +6539 0.995513916015625 +6540 0.19927978515625 +6541 0.9964599609375 +6542 0.199432373046875 +6543 0.997283935546875 +6544 0.1995849609375 +6545 0.99798583984375 +6546 0.19970703125 +6547 0.99859619140625 +6548 0.199798583984375 +6549 0.999114990234375 +6550 0.199859619140625 +6551 0.999481201171875 +6552 0.199920654296875 +6553 0.999755859375 +6554 0.199951171875 +6555 0.99993896484375 +6556 0.199981689453125 +6557 0.999969482421875 +6558 0.199951171875 +6559 0.99993896484375 +6560 0.199920654296875 +6561 0.999755859375 +6562 0.199859619140625 +6563 0.999481201171875 +6564 0.199798583984375 +6565 0.999114990234375 +6566 0.19970703125 +6567 0.99859619140625 +6568 0.1995849609375 +6569 0.99798583984375 +6570 0.199432373046875 +6571 0.997283935546875 +6572 0.19927978515625 +6573 0.9964599609375 +6574 0.199066162109375 +6575 0.995513916015625 +6576 0.198883056640625 +6577 0.994476318359375 +6578 0.198638916015625 +6579 0.993316650390625 +6580 0.198394775390625 +6581 0.9920654296875 +6582 0.1981201171875 +6583 0.990692138671875 +6584 0.19781494140625 +6585 0.989227294921875 +6586 0.197509765625 +6587 0.987640380859375 +6588 0.197174072265625 +6589 0.9859619140625 +6590 0.196807861328125 +6591 0.984161376953125 +6592 0.1964111328125 +6593 0.98223876953125 +6594 0.196014404296875 +6595 0.980224609375 +6596 0.195587158203125 +6597 0.97808837890625 +6598 0.195159912109375 +6599 0.975860595703125 +6600 0.194671630859375 +6601 0.973541259765625 +6602 0.194183349609375 +6603 0.971099853515625 +6604 0.193695068359375 +6605 0.968536376953125 +6606 0.193145751953125 +6607 0.96588134765625 +6608 0.192596435546875 +6609 0.963104248046875 +6610 0.1920166015625 +6611 0.960235595703125 +6612 0.191436767578125 +6613 0.957275390625 +6614 0.190826416015625 +6615 0.954193115234375 +6616 0.190185546875 +6617 0.951019287109375 +6618 0.18951416015625 +6619 0.947723388671875 +6620 0.1888427734375 +6621 0.9443359375 +6622 0.188140869140625 +6623 0.940826416015625 +6624 0.187408447265625 +6625 0.937225341796875 +6626 0.186676025390625 +6627 0.93353271484375 +6628 0.1859130859375 +6629 0.929718017578125 +6630 0.185150146484375 +6631 0.92584228515625 +6632 0.184326171875 +6633 0.92181396484375 +6634 0.18353271484375 +6635 0.917724609375 +6636 0.18267822265625 +6637 0.91351318359375 +6638 0.18182373046875 +6639 0.9091796875 +6640 0.180938720703125 +6641 0.90478515625 +6642 0.180023193359375 +6643 0.9002685546875 +6644 0.179107666015625 +6645 0.895660400390625 +6646 0.17816162109375 +6647 0.890960693359375 +6648 0.177215576171875 +6649 0.88616943359375 +6650 0.176239013671875 +6651 0.881256103515625 +6652 0.17523193359375 +6653 0.876251220703125 +6654 0.174224853515625 +6655 0.871185302734375 +6656 0.145477294921875 +6657 0.865997314453125 +6658 0.14459228515625 +6659 0.860687255859375 +6660 0.1436767578125 +6661 0.855316162109375 +6662 0.14276123046875 +6663 0.849853515625 +6664 0.141845703125 +6665 0.84429931640625 +6666 0.140869140625 +6667 0.838623046875 +6668 0.139923095703125 +6669 0.8328857421875 +6670 0.138916015625 +6671 0.8270263671875 +6672 0.137939453125 +6673 0.82110595703125 +6674 0.136932373046875 +6675 0.815093994140625 +6676 0.135894775390625 +6677 0.808990478515625 +6678 0.134857177734375 +6679 0.802764892578125 +6680 0.1337890625 +6681 0.796478271484375 +6682 0.132720947265625 +6683 0.790130615234375 +6684 0.13165283203125 +6685 0.783660888671875 +6686 0.13055419921875 +6687 0.777099609375 +6688 0.129425048828125 +6689 0.770477294921875 +6690 0.1282958984375 +6691 0.763763427734375 +6692 0.127166748046875 +6693 0.7569580078125 +6694 0.126007080078125 +6695 0.75006103515625 +6696 0.12481689453125 +6697 0.74310302734375 +6698 0.1236572265625 +6699 0.736053466796875 +6700 0.1224365234375 +6701 0.72894287109375 +6702 0.121246337890625 +6703 0.721710205078125 +6704 0.120025634765625 +6705 0.714447021484375 +6706 0.1187744140625 +6707 0.707061767578125 +6708 0.117523193359375 +6709 0.699615478515625 +6710 0.11627197265625 +6711 0.692108154296875 +6712 0.114990234375 +6713 0.68450927734375 +6714 0.11370849609375 +6715 0.676849365234375 +6716 0.112396240234375 +6717 0.669097900390625 +6718 0.111083984375 +6719 0.661285400390625 +6720 0.1097412109375 +6721 0.65338134765625 +6722 0.108428955078125 +6723 0.645416259765625 +6724 0.1070556640625 +6725 0.63739013671875 +6726 0.105712890625 +6727 0.6292724609375 +6728 0.104339599609375 +6729 0.621124267578125 +6730 0.10296630859375 +6731 0.612884521484375 +6732 0.1015625 +6733 0.60455322265625 +6734 0.10015869140625 +6735 0.59619140625 +6736 0.098724365234375 +6737 0.587738037109375 +6738 0.0972900390625 +6739 0.579254150390625 +6740 0.095855712890625 +6741 0.5706787109375 +6742 0.09442138671875 +6743 0.562042236328125 +6744 0.09295654296875 +6745 0.5533447265625 +6746 0.09149169921875 +6747 0.54461669921875 +6748 0.089996337890625 +6749 0.535797119140625 +6750 0.0885009765625 +6751 0.52691650390625 +6752 0.087005615234375 +6753 0.51800537109375 +6754 0.08551025390625 +6755 0.509002685546875 +6756 0.083984375 +6757 0.499969482421875 +6758 0.08245849609375 +6759 0.490875244140625 +6760 0.080902099609375 +6761 0.481719970703125 +6762 0.079376220703125 +6763 0.4725341796875 +6764 0.07781982421875 +6765 0.4632568359375 +6766 0.076263427734375 +6767 0.453948974609375 +6768 0.074676513671875 +6769 0.444610595703125 +6770 0.073089599609375 +6771 0.435211181640625 +6772 0.071502685546875 +6773 0.425750732421875 +6774 0.069915771484375 +6775 0.416259765625 +6776 0.06829833984375 +6777 0.406707763671875 +6778 0.06671142578125 +6779 0.397125244140625 +6780 0.065093994140625 +6781 0.387481689453125 +6782 0.063446044921875 +6783 0.3778076171875 +6784 0.06182861328125 +6785 0.36810302734375 +6786 0.0601806640625 +6787 0.35833740234375 +6788 0.05853271484375 +6789 0.348541259765625 +6790 0.056884765625 +6791 0.338714599609375 +6792 0.05523681640625 +6793 0.328826904296875 +6794 0.053558349609375 +6795 0.318939208984375 +6796 0.051910400390625 +6797 0.308990478515625 +6798 0.05023193359375 +6799 0.29901123046875 +6800 0.048553466796875 +6801 0.28900146484375 +6802 0.046844482421875 +6803 0.278961181640625 +6804 0.045166015625 +6805 0.268890380859375 +6806 0.04345703125 +6807 0.2587890625 +6808 0.041748046875 +6809 0.2486572265625 +6810 0.040069580078125 +6811 0.238525390625 +6812 0.038360595703125 +6813 0.22833251953125 +6814 0.03662109375 +6815 0.218109130859375 +6816 0.034912109375 +6817 0.2078857421875 +6818 0.033172607421875 +6819 0.1976318359375 +6820 0.031463623046875 +6821 0.187347412109375 +6822 0.02972412109375 +6823 0.17706298828125 +6824 0.027984619140625 +6825 0.166748046875 +6826 0.026275634765625 +6827 0.156402587890625 +6828 0.0245361328125 +6829 0.14605712890625 +6830 0.02276611328125 +6831 0.13568115234375 +6832 0.021026611328125 +6833 0.12530517578125 +6834 0.019287109375 +6835 0.11492919921875 +6836 0.017547607421875 +6837 0.104522705078125 +6838 0.015777587890625 +6839 0.094085693359375 +6840 0.0140380859375 +6841 0.083648681640625 +6842 0.012298583984375 +6843 0.073211669921875 +6844 0.010528564453125 +6845 0.062774658203125 +6846 0.008758544921875 +6847 0.05230712890625 +6848 0.00701904296875 +6849 0.0418701171875 +6850 0.0052490234375 +6851 0.031402587890625 +6852 0.003509521484375 +6853 0.02093505859375 +6854 0.001739501953125 +6855 0.010467529296875 +6856 0.0 +6857 0.0 +6858 -0.001739501953125 +6859 -0.010467529296875 +6860 -0.003509521484375 +6861 -0.02093505859375 +6862 -0.0052490234375 +6863 -0.031402587890625 +6864 -0.00701904296875 +6865 -0.0418701171875 +6866 -0.008758544921875 +6867 -0.05230712890625 +6868 -0.010528564453125 +6869 -0.062774658203125 +6870 -0.012298583984375 +6871 -0.073211669921875 +6872 -0.0140380859375 +6873 -0.083648681640625 +6874 -0.015777587890625 +6875 -0.094085693359375 +6876 -0.017547607421875 +6877 -0.104522705078125 +6878 -0.019287109375 +6879 -0.11492919921875 +6880 -0.021026611328125 +6881 -0.12530517578125 +6882 -0.02276611328125 +6883 -0.13568115234375 +6884 -0.0245361328125 +6885 -0.14605712890625 +6886 -0.026275634765625 +6887 -0.156402587890625 +6888 -0.027984619140625 +6889 -0.166748046875 +6890 -0.02972412109375 +6891 -0.17706298828125 +6892 -0.031463623046875 +6893 -0.187347412109375 +6894 -0.033172607421875 +6895 -0.1976318359375 +6896 -0.034912109375 +6897 -0.2078857421875 +6898 -0.03662109375 +6899 -0.218109130859375 +6900 -0.038360595703125 +6901 -0.22833251953125 +6902 -0.040069580078125 +6903 -0.238525390625 +6904 -0.041748046875 +6905 -0.2486572265625 +6906 -0.04345703125 +6907 -0.2587890625 +6908 -0.045166015625 +6909 -0.268890380859375 +6910 -0.046844482421875 +6911 -0.278961181640625 +6912 -0.039276123046875 +6913 -0.28900146484375 +6914 -0.0406494140625 +6915 -0.29901123046875 +6916 -0.0419921875 +6917 -0.308990478515625 +6918 -0.043365478515625 +6919 -0.318939208984375 +6920 -0.044708251953125 +6921 -0.328826904296875 +6922 -0.046051025390625 +6923 -0.338714599609375 +6924 -0.047393798828125 +6925 -0.348541259765625 +6926 -0.0487060546875 +6927 -0.35833740234375 +6928 -0.050048828125 +6929 -0.36810302734375 +6930 -0.051361083984375 +6931 -0.3778076171875 +6932 -0.05267333984375 +6933 -0.387481689453125 +6934 -0.053985595703125 +6935 -0.397125244140625 +6936 -0.0552978515625 +6937 -0.406707763671875 +6938 -0.05657958984375 +6939 -0.416259765625 +6940 -0.057891845703125 +6941 -0.425750732421875 +6942 -0.059173583984375 +6943 -0.435211181640625 +6944 -0.060455322265625 +6945 -0.444610595703125 +6946 -0.06170654296875 +6947 -0.453948974609375 +6948 -0.06298828125 +6949 -0.4632568359375 +6950 -0.064239501953125 +6951 -0.4725341796875 +6952 -0.06549072265625 +6953 -0.481719970703125 +6954 -0.066741943359375 +6955 -0.490875244140625 +6956 -0.067962646484375 +6957 -0.499969482421875 +6958 -0.0692138671875 +6959 -0.509002685546875 +6960 -0.0704345703125 +6961 -0.51800537109375 +6962 -0.0716552734375 +6963 -0.52691650390625 +6964 -0.072845458984375 +6965 -0.535797119140625 +6966 -0.07403564453125 +6967 -0.54461669921875 +6968 -0.075225830078125 +6969 -0.5533447265625 +6970 -0.076416015625 +6971 -0.562042236328125 +6972 -0.077606201171875 +6973 -0.5706787109375 +6974 -0.078765869140625 +6975 -0.579254150390625 +6976 -0.079925537109375 +6977 -0.587738037109375 +6978 -0.0810546875 +6979 -0.59619140625 +6980 -0.082183837890625 +6981 -0.60455322265625 +6982 -0.083343505859375 +6983 -0.612884521484375 +6984 -0.084442138671875 +6985 -0.621124267578125 +6986 -0.0855712890625 +6987 -0.6292724609375 +6988 -0.086669921875 +6989 -0.63739013671875 +6990 -0.0877685546875 +6991 -0.645416259765625 +6992 -0.088836669921875 +6993 -0.65338134765625 +6994 -0.08990478515625 +6995 -0.661285400390625 +6996 -0.090972900390625 +6997 -0.669097900390625 +6998 -0.092041015625 +6999 -0.676849365234375 +7000 -0.09307861328125 +7001 -0.68450927734375 +7002 -0.0941162109375 +7003 -0.692108154296875 +7004 -0.095123291015625 +7005 -0.699615478515625 +7006 -0.09613037109375 +7007 -0.707061767578125 +7008 -0.097137451171875 +7009 -0.714447021484375 +7010 -0.09814453125 +7011 -0.721710205078125 +7012 -0.09912109375 +7013 -0.72894287109375 +7014 -0.100067138671875 +7015 -0.736053466796875 +7016 -0.101043701171875 +7017 -0.74310302734375 +7018 -0.10198974609375 +7019 -0.75006103515625 +7020 -0.102935791015625 +7021 -0.7569580078125 +7022 -0.103851318359375 +7023 -0.763763427734375 +7024 -0.104766845703125 +7025 -0.770477294921875 +7026 -0.10565185546875 +7027 -0.777099609375 +7028 -0.1065673828125 +7029 -0.783660888671875 +7030 -0.107421875 +7031 -0.790130615234375 +7032 -0.108306884765625 +7033 -0.796478271484375 +7034 -0.109161376953125 +7035 -0.802764892578125 +7036 -0.1099853515625 +7037 -0.808990478515625 +7038 -0.11083984375 +7039 -0.815093994140625 +7040 -0.11163330078125 +7041 -0.82110595703125 +7042 -0.112457275390625 +7043 -0.8270263671875 +7044 -0.113250732421875 +7045 -0.8328857421875 +7046 -0.114044189453125 +7047 -0.838623046875 +7048 -0.11480712890625 +7049 -0.84429931640625 +7050 -0.115570068359375 +7051 -0.849853515625 +7052 -0.116302490234375 +7053 -0.855316162109375 +7054 -0.117034912109375 +7055 -0.860687255859375 +7056 -0.117767333984375 +7057 -0.865997314453125 +7058 -0.11846923828125 +7059 -0.871185302734375 +7060 -0.119140625 +7061 -0.876251220703125 +7062 -0.11981201171875 +7063 -0.881256103515625 +7064 -0.1204833984375 +7065 -0.88616943359375 +7066 -0.12115478515625 +7067 -0.890960693359375 +7068 -0.121795654296875 +7069 -0.895660400390625 +7070 -0.122406005859375 +7071 -0.9002685546875 +7072 -0.123016357421875 +7073 -0.90478515625 +7074 -0.123626708984375 +7075 -0.9091796875 +7076 -0.12420654296875 +7077 -0.91351318359375 +7078 -0.124786376953125 +7079 -0.917724609375 +7080 -0.125335693359375 +7081 -0.92181396484375 +7082 -0.125885009765625 +7083 -0.92584228515625 +7084 -0.12640380859375 +7085 -0.929718017578125 +7086 -0.126922607421875 +7087 -0.93353271484375 +7088 -0.12744140625 +7089 -0.937225341796875 +7090 -0.1279296875 +7091 -0.940826416015625 +7092 -0.12841796875 +7093 -0.9443359375 +7094 -0.128875732421875 +7095 -0.947723388671875 +7096 -0.129302978515625 +7097 -0.951019287109375 +7098 -0.1297607421875 +7099 -0.954193115234375 +7100 -0.130157470703125 +7101 -0.957275390625 +7102 -0.13055419921875 +7103 -0.960235595703125 +7104 -0.130950927734375 +7105 -0.963104248046875 +7106 -0.13134765625 +7107 -0.96588134765625 +7108 -0.131683349609375 +7109 -0.968536376953125 +7110 -0.132049560546875 +7111 -0.971099853515625 +7112 -0.13238525390625 +7113 -0.973541259765625 +7114 -0.1326904296875 +7115 -0.975860595703125 +7116 -0.13299560546875 +7117 -0.97808837890625 +7118 -0.13330078125 +7119 -0.980224609375 +7120 -0.133544921875 +7121 -0.98223876953125 +7122 -0.133819580078125 +7123 -0.984161376953125 +7124 -0.134063720703125 +7125 -0.9859619140625 +7126 -0.134307861328125 +7127 -0.987640380859375 +7128 -0.134521484375 +7129 -0.989227294921875 +7130 -0.13470458984375 +7131 -0.990692138671875 +7132 -0.1348876953125 +7133 -0.9920654296875 +7134 -0.13507080078125 +7135 -0.993316650390625 +7136 -0.135223388671875 +7137 -0.994476318359375 +7138 -0.1353759765625 +7139 -0.995513916015625 +7140 -0.135498046875 +7141 -0.9964599609375 +7142 -0.1356201171875 +7143 -0.997283935546875 +7144 -0.135711669921875 +7145 -0.99798583984375 +7146 -0.135772705078125 +7147 -0.99859619140625 +7148 -0.1358642578125 +7149 -0.999114990234375 +7150 -0.135894775390625 +7151 -0.999481201171875 +7152 -0.13592529296875 +7153 -0.999755859375 +7154 -0.135955810546875 +7155 -0.99993896484375 +7156 -0.135986328125 +7157 -1.0 +7158 -0.135955810546875 +7159 -0.99993896484375 +7160 -0.13592529296875 +7161 -0.999755859375 +7162 -0.135894775390625 +7163 -0.999481201171875 +7164 -0.1358642578125 +7165 -0.999114990234375 +7166 -0.135772705078125 +7167 -0.99859619140625 +7168 -0.103790283203125 +7169 -0.99798583984375 +7170 -0.10369873046875 +7171 -0.997283935546875 +7172 -0.1036376953125 +7173 -0.9964599609375 +7174 -0.103515625 +7175 -0.995513916015625 +7176 -0.103424072265625 +7177 -0.994476318359375 +7178 -0.103302001953125 +7179 -0.993316650390625 +7180 -0.103179931640625 +7181 -0.9920654296875 +7182 -0.10302734375 +7183 -0.990692138671875 +7184 -0.102874755859375 +7185 -0.989227294921875 +7186 -0.102691650390625 +7187 -0.987640380859375 +7188 -0.1025390625 +7189 -0.9859619140625 +7190 -0.10235595703125 +7191 -0.984161376953125 +7192 -0.102142333984375 +7193 -0.98223876953125 +7194 -0.1019287109375 +7195 -0.980224609375 +7196 -0.101715087890625 +7197 -0.97808837890625 +7198 -0.101470947265625 +7199 -0.975860595703125 +7200 -0.101226806640625 +7201 -0.973541259765625 +7202 -0.100982666015625 +7203 -0.971099853515625 +7204 -0.1007080078125 +7205 -0.968536376953125 +7206 -0.100433349609375 +7207 -0.96588134765625 +7208 -0.10015869140625 +7209 -0.963104248046875 +7210 -0.099853515625 +7211 -0.960235595703125 +7212 -0.09954833984375 +7213 -0.957275390625 +7214 -0.099212646484375 +7215 -0.954193115234375 +7216 -0.098907470703125 +7217 -0.951019287109375 +7218 -0.098541259765625 +7219 -0.947723388671875 +7220 -0.09820556640625 +7221 -0.9443359375 +7222 -0.09783935546875 +7223 -0.940826416015625 +7224 -0.09747314453125 +7225 -0.937225341796875 +7226 -0.097076416015625 +7227 -0.93353271484375 +7228 -0.0966796875 +7229 -0.929718017578125 +7230 -0.096282958984375 +7231 -0.92584228515625 +7232 -0.095855712890625 +7233 -0.92181396484375 +7234 -0.095428466796875 +7235 -0.917724609375 +7236 -0.095001220703125 +7237 -0.91351318359375 +7238 -0.09454345703125 +7239 -0.9091796875 +7240 -0.094085693359375 +7241 -0.90478515625 +7242 -0.0936279296875 +7243 -0.9002685546875 +7244 -0.0931396484375 +7245 -0.895660400390625 +7246 -0.0926513671875 +7247 -0.890960693359375 +7248 -0.0921630859375 +7249 -0.88616943359375 +7250 -0.091644287109375 +7251 -0.881256103515625 +7252 -0.09112548828125 +7253 -0.876251220703125 +7254 -0.090606689453125 +7255 -0.871185302734375 +7256 -0.090057373046875 +7257 -0.865997314453125 +7258 -0.089508056640625 +7259 -0.860687255859375 +7260 -0.088958740234375 +7261 -0.855316162109375 +7262 -0.08837890625 +7263 -0.849853515625 +7264 -0.087799072265625 +7265 -0.84429931640625 +7266 -0.08721923828125 +7267 -0.838623046875 +7268 -0.08660888671875 +7269 -0.8328857421875 +7270 -0.08599853515625 +7271 -0.8270263671875 +7272 -0.08538818359375 +7273 -0.82110595703125 +7274 -0.084747314453125 +7275 -0.815093994140625 +7276 -0.084136962890625 +7277 -0.808990478515625 +7278 -0.083465576171875 +7279 -0.802764892578125 +7280 -0.08282470703125 +7281 -0.796478271484375 +7282 -0.0821533203125 +7283 -0.790130615234375 +7284 -0.08148193359375 +7285 -0.783660888671875 +7286 -0.080810546875 +7287 -0.777099609375 +7288 -0.080108642578125 +7289 -0.770477294921875 +7290 -0.07940673828125 +7291 -0.763763427734375 +7292 -0.078704833984375 +7293 -0.7569580078125 +7294 -0.0780029296875 +7295 -0.75006103515625 +7296 -0.0772705078125 +7297 -0.74310302734375 +7298 -0.0765380859375 +7299 -0.736053466796875 +7300 -0.0758056640625 +7301 -0.72894287109375 +7302 -0.075042724609375 +7303 -0.721710205078125 +7304 -0.07427978515625 +7305 -0.714447021484375 +7306 -0.073516845703125 +7307 -0.707061767578125 +7308 -0.07275390625 +7309 -0.699615478515625 +7310 -0.07196044921875 +7311 -0.692108154296875 +7312 -0.0711669921875 +7313 -0.68450927734375 +7314 -0.07037353515625 +7315 -0.676849365234375 +7316 -0.069580078125 +7317 -0.669097900390625 +7318 -0.068756103515625 +7319 -0.661285400390625 +7320 -0.06793212890625 +7321 -0.65338134765625 +7322 -0.067108154296875 +7323 -0.645416259765625 +7324 -0.0662841796875 +7325 -0.63739013671875 +7326 -0.0654296875 +7327 -0.6292724609375 +7328 -0.0645751953125 +7329 -0.621124267578125 +7330 -0.063720703125 +7331 -0.612884521484375 +7332 -0.0628662109375 +7333 -0.60455322265625 +7334 -0.061981201171875 +7335 -0.59619140625 +7336 -0.061126708984375 +7337 -0.587738037109375 +7338 -0.06024169921875 +7339 -0.579254150390625 +7340 -0.059326171875 +7341 -0.5706787109375 +7342 -0.058441162109375 +7343 -0.562042236328125 +7344 -0.057525634765625 +7345 -0.5533447265625 +7346 -0.056640625 +7347 -0.54461669921875 +7348 -0.05572509765625 +7349 -0.535797119140625 +7350 -0.054779052734375 +7351 -0.52691650390625 +7352 -0.053863525390625 +7353 -0.51800537109375 +7354 -0.05291748046875 +7355 -0.509002685546875 +7356 -0.051971435546875 +7357 -0.499969482421875 +7358 -0.051025390625 +7359 -0.490875244140625 +7360 -0.050079345703125 +7361 -0.481719970703125 +7362 -0.04913330078125 +7363 -0.4725341796875 +7364 -0.04815673828125 +7365 -0.4632568359375 +7366 -0.047210693359375 +7367 -0.453948974609375 +7368 -0.046234130859375 +7369 -0.444610595703125 +7370 -0.045257568359375 +7371 -0.435211181640625 +7372 -0.044281005859375 +7373 -0.425750732421875 +7374 -0.04327392578125 +7375 -0.416259765625 +7376 -0.04229736328125 +7377 -0.406707763671875 +7378 -0.041290283203125 +7379 -0.397125244140625 +7380 -0.040283203125 +7381 -0.387481689453125 +7382 -0.039276123046875 +7383 -0.3778076171875 +7384 -0.03826904296875 +7385 -0.36810302734375 +7386 -0.037261962890625 +7387 -0.35833740234375 +7388 -0.036224365234375 +7389 -0.348541259765625 +7390 -0.03521728515625 +7391 -0.338714599609375 +7392 -0.0341796875 +7393 -0.328826904296875 +7394 -0.03314208984375 +7395 -0.318939208984375 +7396 -0.032135009765625 +7397 -0.308990478515625 +7398 -0.031097412109375 +7399 -0.29901123046875 +7400 -0.030029296875 +7401 -0.28900146484375 +7402 -0.02899169921875 +7403 -0.278961181640625 +7404 -0.0279541015625 +7405 -0.268890380859375 +7406 -0.026885986328125 +7407 -0.2587890625 +7408 -0.025848388671875 +7409 -0.2486572265625 +7410 -0.0247802734375 +7411 -0.238525390625 +7412 -0.02374267578125 +7413 -0.22833251953125 +7414 -0.022674560546875 +7415 -0.218109130859375 +7416 -0.0216064453125 +7417 -0.2078857421875 +7418 -0.020538330078125 +7419 -0.1976318359375 +7420 -0.01947021484375 +7421 -0.187347412109375 +7422 -0.018402099609375 +7423 -0.17706298828125 +7424 -0.01666259765625 +7425 -0.166748046875 +7426 -0.015625 +7427 -0.156402587890625 +7428 -0.01458740234375 +7429 -0.14605712890625 +7430 -0.0135498046875 +7431 -0.13568115234375 +7432 -0.01251220703125 +7433 -0.12530517578125 +7434 -0.011474609375 +7435 -0.11492919921875 +7436 -0.01043701171875 +7437 -0.104522705078125 +7438 -0.0093994140625 +7439 -0.094085693359375 +7440 -0.00836181640625 +7441 -0.083648681640625 +7442 -0.007293701171875 +7443 -0.073211669921875 +7444 -0.006256103515625 +7445 -0.062774658203125 +7446 -0.005218505859375 +7447 -0.05230712890625 +7448 -0.004180908203125 +7449 -0.0418701171875 +7450 -0.00311279296875 +7451 -0.031402587890625 +7452 -0.0020751953125 +7453 -0.02093505859375 +7454 -0.00103759765625 +7455 -0.010467529296875 +7456 0.0 +7457 0.0 +7458 0.000732421875 +7459 0.010467529296875 +7460 0.001495361328125 +7461 0.02093505859375 +7462 0.00225830078125 +7463 0.031402587890625 +7464 0.00299072265625 +7465 0.0418701171875 +7466 0.003753662109375 +7467 0.05230712890625 +7468 0.0045166015625 +7469 0.062774658203125 +7470 0.0052490234375 +7471 0.073211669921875 +7472 0.006011962890625 +7473 0.083648681640625 +7474 0.006744384765625 +7475 0.094085693359375 +7476 0.00750732421875 +7477 0.104522705078125 +7478 0.008270263671875 +7479 0.11492919921875 +7480 0.009002685546875 +7481 0.12530517578125 +7482 0.009765625 +7483 0.13568115234375 +7484 0.010498046875 +7485 0.14605712890625 +7486 0.01123046875 +7487 0.156402587890625 +7488 0.011993408203125 +7489 0.166748046875 +7490 0.012725830078125 +7491 0.17706298828125 +7492 0.013458251953125 +7493 0.187347412109375 +7494 0.01422119140625 +7495 0.1976318359375 +7496 0.01495361328125 +7497 0.2078857421875 +7498 0.01568603515625 +7499 0.218109130859375 +7500 0.01641845703125 +7501 0.22833251953125 +7502 0.01715087890625 +7503 0.238525390625 +7504 0.01788330078125 +7505 0.2486572265625 +7506 0.01861572265625 +7507 0.2587890625 +7508 0.01934814453125 +7509 0.268890380859375 +7510 0.02008056640625 +7511 0.278961181640625 +7512 0.020782470703125 +7513 0.28900146484375 +7514 0.021514892578125 +7515 0.29901123046875 +7516 0.022216796875 +7517 0.308990478515625 +7518 0.02294921875 +7519 0.318939208984375 +7520 0.023651123046875 +7521 0.328826904296875 +7522 0.024383544921875 +7523 0.338714599609375 +7524 0.02508544921875 +7525 0.348541259765625 +7526 0.025787353515625 +7527 0.35833740234375 +7528 0.0264892578125 +7529 0.36810302734375 +7530 0.027191162109375 +7531 0.3778076171875 +7532 0.02789306640625 +7533 0.387481689453125 +7534 0.028564453125 +7535 0.397125244140625 +7536 0.029266357421875 +7537 0.406707763671875 +7538 0.029937744140625 +7539 0.416259765625 +7540 0.0306396484375 +7541 0.425750732421875 +7542 0.03131103515625 +7543 0.435211181640625 +7544 0.031982421875 +7545 0.444610595703125 +7546 0.03265380859375 +7547 0.453948974609375 +7548 0.0333251953125 +7549 0.4632568359375 +7550 0.03399658203125 +7551 0.4725341796875 +7552 0.03466796875 +7553 0.481719970703125 +7554 0.03533935546875 +7555 0.490875244140625 +7556 0.035980224609375 +7557 0.499969482421875 +7558 0.03662109375 +7559 0.509002685546875 +7560 0.03729248046875 +7561 0.51800537109375 +7562 0.037933349609375 +7563 0.52691650390625 +7564 0.038543701171875 +7565 0.535797119140625 +7566 0.0391845703125 +7567 0.54461669921875 +7568 0.039825439453125 +7569 0.5533447265625 +7570 0.040435791015625 +7571 0.562042236328125 +7572 0.04107666015625 +7573 0.5706787109375 +7574 0.04168701171875 +7575 0.579254150390625 +7576 0.04229736328125 +7577 0.587738037109375 +7578 0.04290771484375 +7579 0.59619140625 +7580 0.04351806640625 +7581 0.60455322265625 +7582 0.044097900390625 +7583 0.612884521484375 +7584 0.044708251953125 +7585 0.621124267578125 +7586 0.0452880859375 +7587 0.6292724609375 +7588 0.045867919921875 +7589 0.63739013671875 +7590 0.04644775390625 +7591 0.645416259765625 +7592 0.047027587890625 +7593 0.65338134765625 +7594 0.047607421875 +7595 0.661285400390625 +7596 0.04815673828125 +7597 0.669097900390625 +7598 0.0487060546875 +7599 0.676849365234375 +7600 0.04925537109375 +7601 0.68450927734375 +7602 0.0498046875 +7603 0.692108154296875 +7604 0.05035400390625 +7605 0.699615478515625 +7606 0.0509033203125 +7607 0.707061767578125 +7608 0.051422119140625 +7609 0.714447021484375 +7610 0.05194091796875 +7611 0.721710205078125 +7612 0.052459716796875 +7613 0.72894287109375 +7614 0.052978515625 +7615 0.736053466796875 +7616 0.053497314453125 +7617 0.74310302734375 +7618 0.053985595703125 +7619 0.75006103515625 +7620 0.054473876953125 +7621 0.7569580078125 +7622 0.054962158203125 +7623 0.763763427734375 +7624 0.055450439453125 +7625 0.770477294921875 +7626 0.055938720703125 +7627 0.777099609375 +7628 0.056396484375 +7629 0.783660888671875 +7630 0.056854248046875 +7631 0.790130615234375 +7632 0.05731201171875 +7633 0.796478271484375 +7634 0.057769775390625 +7635 0.802764892578125 +7636 0.0582275390625 +7637 0.808990478515625 +7638 0.05865478515625 +7639 0.815093994140625 +7640 0.059112548828125 +7641 0.82110595703125 +7642 0.059539794921875 +7643 0.8270263671875 +7644 0.0599365234375 +7645 0.8328857421875 +7646 0.06036376953125 +7647 0.838623046875 +7648 0.060760498046875 +7649 0.84429931640625 +7650 0.0611572265625 +7651 0.849853515625 +7652 0.061553955078125 +7653 0.855316162109375 +7654 0.06195068359375 +7655 0.860687255859375 +7656 0.06231689453125 +7657 0.865997314453125 +7658 0.062713623046875 +7659 0.871185302734375 +7660 0.063079833984375 +7661 0.876251220703125 +7662 0.06341552734375 +7663 0.881256103515625 +7664 0.06378173828125 +7665 0.88616943359375 +7666 0.064117431640625 +7667 0.890960693359375 +7668 0.064453125 +7669 0.895660400390625 +7670 0.064788818359375 +7671 0.9002685546875 +7672 0.06512451171875 +7673 0.90478515625 +7674 0.0654296875 +7675 0.9091796875 +7676 0.065765380859375 +7677 0.91351318359375 +7678 0.0660400390625 +7679 0.917724609375 +7680 0.036865234375 +7681 0.92181396484375 +7682 0.037017822265625 +7683 0.92584228515625 +7684 0.03717041015625 +7685 0.929718017578125 +7686 0.037322998046875 +7687 0.93353271484375 +7688 0.0374755859375 +7689 0.937225341796875 +7690 0.037628173828125 +7691 0.940826416015625 +7692 0.03778076171875 +7693 0.9443359375 +7694 0.03790283203125 +7695 0.947723388671875 +7696 0.03802490234375 +7697 0.951019287109375 +7698 0.03814697265625 +7699 0.954193115234375 +7700 0.038299560546875 +7701 0.957275390625 +7702 0.03839111328125 +7703 0.960235595703125 +7704 0.03851318359375 +7705 0.963104248046875 +7706 0.03863525390625 +7707 0.96588134765625 +7708 0.038726806640625 +7709 0.968536376953125 +7710 0.038848876953125 +7711 0.971099853515625 +7712 0.0389404296875 +7713 0.973541259765625 +7714 0.039031982421875 +7715 0.975860595703125 +7716 0.03912353515625 +7717 0.97808837890625 +7718 0.039215087890625 +7719 0.980224609375 +7720 0.039276123046875 +7721 0.98223876953125 +7722 0.03936767578125 +7723 0.984161376953125 +7724 0.0394287109375 +7725 0.9859619140625 +7726 0.03948974609375 +7727 0.987640380859375 +7728 0.03955078125 +7729 0.989227294921875 +7730 0.03961181640625 +7731 0.990692138671875 +7732 0.0396728515625 +7733 0.9920654296875 +7734 0.03973388671875 +7735 0.993316650390625 +7736 0.039764404296875 +7737 0.994476318359375 +7738 0.039825439453125 +7739 0.995513916015625 +7740 0.03985595703125 +7741 0.9964599609375 +7742 0.039886474609375 +7743 0.997283935546875 +7744 0.0399169921875 +7745 0.99798583984375 +7746 0.039947509765625 +7747 0.99859619140625 +7748 0.039947509765625 +7749 0.999114990234375 +7750 0.03997802734375 +7751 0.999481201171875 +7752 0.03997802734375 +7753 0.999755859375 +7754 0.03997802734375 +7755 0.99993896484375 +7756 0.040008544921875 +7757 0.999969482421875 +7758 0.03997802734375 +7759 0.99993896484375 +7760 0.03997802734375 +7761 0.999755859375 +7762 0.03997802734375 +7763 0.999481201171875 +7764 0.039947509765625 +7765 0.999114990234375 +7766 0.039947509765625 +7767 0.99859619140625 +7768 0.0399169921875 +7769 0.99798583984375 +7770 0.039886474609375 +7771 0.997283935546875 +7772 0.03985595703125 +7773 0.9964599609375 +7774 0.039825439453125 +7775 0.995513916015625 +7776 0.039764404296875 +7777 0.994476318359375 +7778 0.03973388671875 +7779 0.993316650390625 +7780 0.0396728515625 +7781 0.9920654296875 +7782 0.03961181640625 +7783 0.990692138671875 +7784 0.03955078125 +7785 0.989227294921875 +7786 0.03948974609375 +7787 0.987640380859375 +7788 0.0394287109375 +7789 0.9859619140625 +7790 0.03936767578125 +7791 0.984161376953125 +7792 0.039276123046875 +7793 0.98223876953125 +7794 0.039215087890625 +7795 0.980224609375 +7796 0.03912353515625 +7797 0.97808837890625 +7798 0.039031982421875 +7799 0.975860595703125 +7800 0.0389404296875 +7801 0.973541259765625 +7802 0.038848876953125 +7803 0.971099853515625 +7804 0.038726806640625 +7805 0.968536376953125 +7806 0.03863525390625 +7807 0.96588134765625 +7808 0.03851318359375 +7809 0.963104248046875 +7810 0.03839111328125 +7811 0.960235595703125 +7812 0.038299560546875 +7813 0.957275390625 +7814 0.03814697265625 +7815 0.954193115234375 +7816 0.03802490234375 +7817 0.951019287109375 +7818 0.03790283203125 +7819 0.947723388671875 +7820 0.03778076171875 +7821 0.9443359375 +7822 0.037628173828125 +7823 0.940826416015625 +7824 0.0374755859375 +7825 0.937225341796875 +7826 0.037322998046875 +7827 0.93353271484375 +7828 0.03717041015625 +7829 0.929718017578125 +7830 0.037017822265625 +7831 0.92584228515625 +7832 0.036865234375 +7833 0.92181396484375 +7834 0.036712646484375 +7835 0.917724609375 +7836 0.036529541015625 +7837 0.91351318359375 +7838 0.036346435546875 +7839 0.9091796875 +7840 0.03619384765625 +7841 0.90478515625 +7842 0.0360107421875 +7843 0.9002685546875 +7844 0.03582763671875 +7845 0.895660400390625 +7846 0.03564453125 +7847 0.890960693359375 +7848 0.035430908203125 +7849 0.88616943359375 +7850 0.035247802734375 +7851 0.881256103515625 +7852 0.0350341796875 +7853 0.876251220703125 +7854 0.03485107421875 +7855 0.871185302734375 +7856 0.034637451171875 +7857 0.865997314453125 +7858 0.034423828125 +7859 0.860687255859375 +7860 0.034210205078125 +7861 0.855316162109375 +7862 0.03399658203125 +7863 0.849853515625 +7864 0.03375244140625 +7865 0.84429931640625 +7866 0.033538818359375 +7867 0.838623046875 +7868 0.033294677734375 +7869 0.8328857421875 +7870 0.0330810546875 +7871 0.8270263671875 +7872 0.0328369140625 +7873 0.82110595703125 +7874 0.0325927734375 +7875 0.815093994140625 +7876 0.0323486328125 +7877 0.808990478515625 +7878 0.0321044921875 +7879 0.802764892578125 +7880 0.0318603515625 +7881 0.796478271484375 +7882 0.031585693359375 +7883 0.790130615234375 +7884 0.031341552734375 +7885 0.783660888671875 +7886 0.03106689453125 +7887 0.777099609375 +7888 0.03082275390625 +7889 0.770477294921875 +7890 0.030548095703125 +7891 0.763763427734375 +7892 0.0302734375 +7893 0.7569580078125 +7894 0.029998779296875 +7895 0.75006103515625 +7896 0.02972412109375 +7897 0.74310302734375 +7898 0.0294189453125 +7899 0.736053466796875 +7900 0.029144287109375 +7901 0.72894287109375 +7902 0.02886962890625 +7903 0.721710205078125 +7904 0.028564453125 +7905 0.714447021484375 +7906 0.02825927734375 +7907 0.707061767578125 +7908 0.027984619140625 +7909 0.699615478515625 +7910 0.027679443359375 +7911 0.692108154296875 +7912 0.027374267578125 +7913 0.68450927734375 +7914 0.027069091796875 +7915 0.676849365234375 +7916 0.026763916015625 +7917 0.669097900390625 +7918 0.02642822265625 +7919 0.661285400390625 +7920 0.026123046875 +7921 0.65338134765625 +7922 0.02581787109375 +7923 0.645416259765625 +7924 0.025482177734375 +7925 0.63739013671875 +7926 0.025177001953125 +7927 0.6292724609375 +7928 0.02484130859375 +7929 0.621124267578125 +7930 0.024505615234375 +7931 0.612884521484375 +7932 0.024169921875 +7933 0.60455322265625 +7934 0.023834228515625 +7935 0.59619140625 +7936 0.004669189453125 +7937 0.587738037109375 +7938 0.004608154296875 +7939 0.579254150390625 +7940 0.004547119140625 +7941 0.5706787109375 +7942 0.004486083984375 +7943 0.562042236328125 +7944 0.00439453125 +7945 0.5533447265625 +7946 0.00433349609375 +7947 0.54461669921875 +7948 0.0042724609375 +7949 0.535797119140625 +7950 0.00421142578125 +7951 0.52691650390625 +7952 0.004119873046875 +7953 0.51800537109375 +7954 0.004058837890625 +7955 0.509002685546875 +7956 0.00396728515625 +7957 0.499969482421875 +7958 0.00390625 +7959 0.490875244140625 +7960 0.00384521484375 +7961 0.481719970703125 +7962 0.003753662109375 +7963 0.4725341796875 +7964 0.003692626953125 +7965 0.4632568359375 +7966 0.00360107421875 +7967 0.453948974609375 +7968 0.0035400390625 +7969 0.444610595703125 +7970 0.00347900390625 +7971 0.435211181640625 +7972 0.003387451171875 +7973 0.425750732421875 +7974 0.003326416015625 +7975 0.416259765625 +7976 0.00323486328125 +7977 0.406707763671875 +7978 0.003173828125 +7979 0.397125244140625 +7980 0.003082275390625 +7981 0.387481689453125 +7982 0.00299072265625 +7983 0.3778076171875 +7984 0.0029296875 +7985 0.36810302734375 +7986 0.002838134765625 +7987 0.35833740234375 +7988 0.002777099609375 +7989 0.348541259765625 +7990 0.002685546875 +7991 0.338714599609375 +7992 0.00262451171875 +7993 0.328826904296875 +7994 0.002532958984375 +7995 0.318939208984375 +7996 0.00244140625 +7997 0.308990478515625 +7998 0.00238037109375 +7999 0.29901123046875 +8000 0.002288818359375 +8001 0.28900146484375 +8002 0.002227783203125 +8003 0.278961181640625 +8004 0.00213623046875 +8005 0.268890380859375 +8006 0.002044677734375 +8007 0.2587890625 +8008 0.001983642578125 +8009 0.2486572265625 +8010 0.00189208984375 +8011 0.238525390625 +8012 0.001800537109375 +8013 0.22833251953125 +8014 0.001739501953125 +8015 0.218109130859375 +8016 0.00164794921875 +8017 0.2078857421875 +8018 0.001556396484375 +8019 0.1976318359375 +8020 0.001495361328125 +8021 0.187347412109375 +8022 0.00140380859375 +8023 0.17706298828125 +8024 0.001312255859375 +8025 0.166748046875 +8026 0.001220703125 +8027 0.156402587890625 +8028 0.00115966796875 +8029 0.14605712890625 +8030 0.001068115234375 +8031 0.13568115234375 +8032 0.0009765625 +8033 0.12530517578125 +8034 0.00091552734375 +8035 0.11492919921875 +8036 0.000823974609375 +8037 0.104522705078125 +8038 0.000732421875 +8039 0.094085693359375 +8040 0.000640869140625 +8041 0.083648681640625 +8042 0.000579833984375 +8043 0.073211669921875 +8044 0.00048828125 +8045 0.062774658203125 +8046 0.000396728515625 +8047 0.05230712890625 +8048 0.00030517578125 +8049 0.0418701171875 +8050 0.000244140625 +8051 0.031402587890625 +8052 0.000152587890625 +8053 0.02093505859375 +8054 6.103515625e-05 +8055 0.010467529296875 +8056 0.0 +8057 0.0 +8058 -6.103515625e-05 +8059 -0.010467529296875 +8060 -0.000152587890625 +8061 -0.02093505859375 +8062 -0.000244140625 +8063 -0.031402587890625 +8064 -0.00030517578125 +8065 -0.0418701171875 +8066 -0.000396728515625 +8067 -0.05230712890625 +8068 -0.00048828125 +8069 -0.062774658203125 +8070 -0.000579833984375 +8071 -0.073211669921875 +8072 -0.000640869140625 +8073 -0.083648681640625 +8074 -0.000732421875 +8075 -0.094085693359375 +8076 -0.000823974609375 +8077 -0.104522705078125 +8078 -0.00091552734375 +8079 -0.11492919921875 +8080 -0.0009765625 +8081 -0.12530517578125 +8082 -0.001068115234375 +8083 -0.13568115234375 +8084 -0.00115966796875 +8085 -0.14605712890625 +8086 -0.001220703125 +8087 -0.156402587890625 +8088 -0.001312255859375 +8089 -0.166748046875 +8090 -0.00140380859375 +8091 -0.17706298828125 +8092 -0.001495361328125 +8093 -0.187347412109375 +8094 -0.001556396484375 +8095 -0.1976318359375 +8096 -0.00164794921875 +8097 -0.2078857421875 +8098 -0.001739501953125 +8099 -0.218109130859375 +8100 -0.001800537109375 +8101 -0.22833251953125 +8102 -0.00189208984375 +8103 -0.238525390625 +8104 -0.001983642578125 +8105 -0.2486572265625 +8106 -0.002044677734375 +8107 -0.2587890625 +8108 -0.00213623046875 +8109 -0.268890380859375 +8110 -0.002227783203125 +8111 -0.278961181640625 +8112 -0.002288818359375 +8113 -0.28900146484375 +8114 -0.00238037109375 +8115 -0.29901123046875 +8116 -0.00244140625 +8117 -0.308990478515625 +8118 -0.002532958984375 +8119 -0.318939208984375 +8120 -0.00262451171875 +8121 -0.328826904296875 +8122 -0.002685546875 +8123 -0.338714599609375 +8124 -0.002777099609375 +8125 -0.348541259765625 +8126 -0.002838134765625 +8127 -0.35833740234375 +8128 -0.0029296875 +8129 -0.36810302734375 +8130 -0.00299072265625 +8131 -0.3778076171875 +8132 -0.003082275390625 +8133 -0.387481689453125 +8134 -0.003173828125 +8135 -0.397125244140625 +8136 -0.00323486328125 +8137 -0.406707763671875 +8138 -0.003326416015625 +8139 -0.416259765625 +8140 -0.003387451171875 +8141 -0.425750732421875 +8142 -0.00347900390625 +8143 -0.435211181640625 +8144 -0.0035400390625 +8145 -0.444610595703125 +8146 -0.00360107421875 +8147 -0.453948974609375 +8148 -0.003692626953125 +8149 -0.4632568359375 +8150 -0.003753662109375 +8151 -0.4725341796875 +8152 -0.00384521484375 +8153 -0.481719970703125 +8154 -0.00390625 +8155 -0.490875244140625 +8156 -0.00396728515625 +8157 -0.499969482421875 +8158 -0.004058837890625 +8159 -0.509002685546875 +8160 -0.004119873046875 +8161 -0.51800537109375 +8162 -0.00421142578125 +8163 -0.52691650390625 +8164 -0.0042724609375 +8165 -0.535797119140625 +8166 -0.00433349609375 +8167 -0.54461669921875 +8168 -0.00439453125 +8169 -0.5533447265625 +8170 -0.004486083984375 +8171 -0.562042236328125 +8172 -0.004547119140625 +8173 -0.5706787109375 +8174 -0.004608154296875 +8175 -0.579254150390625 +8176 -0.004669189453125 +8177 -0.587738037109375 +8178 -0.0047607421875 +8179 -0.59619140625 +8180 -0.00482177734375 +8181 -0.60455322265625 +8182 -0.0048828125 +8183 -0.612884521484375 +8184 -0.00494384765625 +8185 -0.621124267578125 +8186 -0.0050048828125 +8187 -0.6292724609375 +8188 -0.005096435546875 +8189 -0.63739013671875 +8190 -0.005157470703125 +8191 -0.645416259765625 +8192 -0.015655517578125 +8193 -0.65338134765625 +8194 -0.015838623046875 +8195 -0.661285400390625 +8196 -0.016021728515625 +8197 -0.669097900390625 +8198 -0.0162353515625 +8199 -0.676849365234375 +8200 -0.01641845703125 +8201 -0.68450927734375 +8202 -0.0166015625 +8203 -0.692108154296875 +8204 -0.016754150390625 +8205 -0.699615478515625 +8206 -0.016937255859375 +8207 -0.707061767578125 +8208 -0.017120361328125 +8209 -0.714447021484375 +8210 -0.017303466796875 +8211 -0.721710205078125 +8212 -0.0174560546875 +8213 -0.72894287109375 +8214 -0.01763916015625 +8215 -0.736053466796875 +8216 -0.017822265625 +8217 -0.74310302734375 +8218 -0.017974853515625 +8219 -0.75006103515625 +8220 -0.01812744140625 +8221 -0.7569580078125 +8222 -0.018310546875 +8223 -0.763763427734375 +8224 -0.018463134765625 +8225 -0.770477294921875 +8226 -0.01861572265625 +8227 -0.777099609375 +8228 -0.018768310546875 +8229 -0.783660888671875 +8230 -0.018951416015625 +8231 -0.790130615234375 +8232 -0.01910400390625 +8233 -0.796478271484375 +8234 -0.01922607421875 +8235 -0.802764892578125 +8236 -0.019378662109375 +8237 -0.808990478515625 +8238 -0.01953125 +8239 -0.815093994140625 +8240 -0.019683837890625 +8241 -0.82110595703125 +8242 -0.01983642578125 +8243 -0.8270263671875 +8244 -0.01995849609375 +8245 -0.8328857421875 +8246 -0.020111083984375 +8247 -0.838623046875 +8248 -0.020233154296875 +8249 -0.84429931640625 +8250 -0.0203857421875 +8251 -0.849853515625 +8252 -0.0205078125 +8253 -0.855316162109375 +8254 -0.0206298828125 +8255 -0.860687255859375 +8256 -0.020751953125 +8257 -0.865997314453125 +8258 -0.0208740234375 +8259 -0.871185302734375 +8260 -0.02099609375 +8261 -0.876251220703125 +8262 -0.0211181640625 +8263 -0.881256103515625 +8264 -0.021240234375 +8265 -0.88616943359375 +8266 -0.0213623046875 +8267 -0.890960693359375 +8268 -0.021484375 +8269 -0.895660400390625 +8270 -0.021575927734375 +8271 -0.9002685546875 +8272 -0.021697998046875 +8273 -0.90478515625 +8274 -0.02178955078125 +8275 -0.9091796875 +8276 -0.02191162109375 +8277 -0.91351318359375 +8278 -0.022003173828125 +8279 -0.917724609375 +8280 -0.0220947265625 +8281 -0.92181396484375 +8282 -0.022186279296875 +8283 -0.92584228515625 +8284 -0.02227783203125 +8285 -0.929718017578125 +8286 -0.022369384765625 +8287 -0.93353271484375 +8288 -0.0224609375 +8289 -0.937225341796875 +8290 -0.022552490234375 +8291 -0.940826416015625 +8292 -0.02264404296875 +8293 -0.9443359375 +8294 -0.022705078125 +8295 -0.947723388671875 +8296 -0.022796630859375 +8297 -0.951019287109375 +8298 -0.02288818359375 +8299 -0.954193115234375 +8300 -0.02294921875 +8301 -0.957275390625 +8302 -0.02301025390625 +8303 -0.960235595703125 +8304 -0.023101806640625 +8305 -0.963104248046875 +8306 -0.023162841796875 +8307 -0.96588134765625 +8308 -0.023223876953125 +8309 -0.968536376953125 +8310 -0.023284912109375 +8311 -0.971099853515625 +8312 -0.023345947265625 +8313 -0.973541259765625 +8314 -0.023406982421875 +8315 -0.975860595703125 +8316 -0.0234375 +8317 -0.97808837890625 +8318 -0.02349853515625 +8319 -0.980224609375 +8320 -0.0235595703125 +8321 -0.98223876953125 +8322 -0.023590087890625 +8323 -0.984161376953125 +8324 -0.02362060546875 +8325 -0.9859619140625 +8326 -0.023681640625 +8327 -0.987640380859375 +8328 -0.023712158203125 +8329 -0.989227294921875 +8330 -0.02374267578125 +8331 -0.990692138671875 +8332 -0.023773193359375 +8333 -0.9920654296875 +8334 -0.0238037109375 +8335 -0.993316650390625 +8336 -0.023834228515625 +8337 -0.994476318359375 +8338 -0.02386474609375 +8339 -0.995513916015625 +8340 -0.023895263671875 +8341 -0.9964599609375 +8342 -0.023895263671875 +8343 -0.997283935546875 +8344 -0.02392578125 +8345 -0.99798583984375 +8346 -0.02392578125 +8347 -0.99859619140625 +8348 -0.023956298828125 +8349 -0.999114990234375 +8350 -0.023956298828125 +8351 -0.999481201171875 +8352 -0.023956298828125 +8353 -0.999755859375 +8354 -0.023956298828125 +8355 -0.99993896484375 +8356 -0.02398681640625 +8357 -1.0 +8358 -0.023956298828125 +8359 -0.99993896484375 +8360 -0.023956298828125 +8361 -0.999755859375 +8362 -0.023956298828125 +8363 -0.999481201171875 +8364 -0.023956298828125 +8365 -0.999114990234375 +8366 -0.02392578125 +8367 -0.99859619140625 +8368 -0.02392578125 +8369 -0.99798583984375 +8370 -0.023895263671875 +8371 -0.997283935546875 +8372 -0.023895263671875 +8373 -0.9964599609375 +8374 -0.02386474609375 +8375 -0.995513916015625 +8376 -0.023834228515625 +8377 -0.994476318359375 +8378 -0.0238037109375 +8379 -0.993316650390625 +8380 -0.023773193359375 +8381 -0.9920654296875 +8382 -0.02374267578125 +8383 -0.990692138671875 +8384 -0.023712158203125 +8385 -0.989227294921875 +8386 -0.023681640625 +8387 -0.987640380859375 +8388 -0.02362060546875 +8389 -0.9859619140625 +8390 -0.023590087890625 +8391 -0.984161376953125 +8392 -0.0235595703125 +8393 -0.98223876953125 +8394 -0.02349853515625 +8395 -0.980224609375 +8396 -0.0234375 +8397 -0.97808837890625 +8398 -0.023406982421875 +8399 -0.975860595703125 +8400 -0.023345947265625 +8401 -0.973541259765625 +8402 -0.023284912109375 +8403 -0.971099853515625 +8404 -0.023223876953125 +8405 -0.968536376953125 +8406 -0.023162841796875 +8407 -0.96588134765625 +8408 -0.023101806640625 +8409 -0.963104248046875 +8410 -0.02301025390625 +8411 -0.960235595703125 +8412 -0.02294921875 +8413 -0.957275390625 +8414 -0.02288818359375 +8415 -0.954193115234375 +8416 -0.022796630859375 +8417 -0.951019287109375 +8418 -0.022705078125 +8419 -0.947723388671875 +8420 -0.02264404296875 +8421 -0.9443359375 +8422 -0.022552490234375 +8423 -0.940826416015625 +8424 -0.0224609375 +8425 -0.937225341796875 +8426 -0.022369384765625 +8427 -0.93353271484375 +8428 -0.02227783203125 +8429 -0.929718017578125 +8430 -0.022186279296875 +8431 -0.92584228515625 +8432 -0.0220947265625 +8433 -0.92181396484375 +8434 -0.022003173828125 +8435 -0.917724609375 +8436 -0.02191162109375 +8437 -0.91351318359375 +8438 -0.02178955078125 +8439 -0.9091796875 +8440 -0.021697998046875 +8441 -0.90478515625 +8442 -0.021575927734375 +8443 -0.9002685546875 +8444 -0.021484375 +8445 -0.895660400390625 +8446 -0.0213623046875 +8447 -0.890960693359375 +8448 -0.044281005859375 +8449 -0.88616943359375 +8450 -0.044036865234375 +8451 -0.881256103515625 +8452 -0.043792724609375 +8453 -0.876251220703125 +8454 -0.043548583984375 +8455 -0.871185302734375 +8456 -0.04327392578125 +8457 -0.865997314453125 +8458 -0.042999267578125 +8459 -0.860687255859375 +8460 -0.042755126953125 +8461 -0.855316162109375 +8462 -0.04248046875 +8463 -0.849853515625 +8464 -0.042205810546875 +8465 -0.84429931640625 +8466 -0.041900634765625 +8467 -0.838623046875 +8468 -0.0416259765625 +8469 -0.8328857421875 +8470 -0.04132080078125 +8471 -0.8270263671875 +8472 -0.041046142578125 +8473 -0.82110595703125 +8474 -0.040740966796875 +8475 -0.815093994140625 +8476 -0.040435791015625 +8477 -0.808990478515625 +8478 -0.04010009765625 +8479 -0.802764892578125 +8480 -0.039794921875 +8481 -0.796478271484375 +8482 -0.03948974609375 +8483 -0.790130615234375 +8484 -0.039154052734375 +8485 -0.783660888671875 +8486 -0.038818359375 +8487 -0.777099609375 +8488 -0.03851318359375 +8489 -0.770477294921875 +8490 -0.038177490234375 +8491 -0.763763427734375 +8492 -0.037811279296875 +8493 -0.7569580078125 +8494 -0.0374755859375 +8495 -0.75006103515625 +8496 -0.037139892578125 +8497 -0.74310302734375 +8498 -0.036773681640625 +8499 -0.736053466796875 +8500 -0.03643798828125 +8501 -0.72894287109375 +8502 -0.03607177734375 +8503 -0.721710205078125 +8504 -0.03570556640625 +8505 -0.714447021484375 +8506 -0.03533935546875 +8507 -0.707061767578125 +8508 -0.03497314453125 +8509 -0.699615478515625 +8510 -0.034576416015625 +8511 -0.692108154296875 +8512 -0.034210205078125 +8513 -0.68450927734375 +8514 -0.0338134765625 +8515 -0.676849365234375 +8516 -0.033447265625 +8517 -0.669097900390625 +8518 -0.033050537109375 +8519 -0.661285400390625 +8520 -0.03265380859375 +8521 -0.65338134765625 +8522 -0.032257080078125 +8523 -0.645416259765625 +8524 -0.0318603515625 +8525 -0.63739013671875 +8526 -0.03143310546875 +8527 -0.6292724609375 +8528 -0.031036376953125 +8529 -0.621124267578125 +8530 -0.030609130859375 +8531 -0.612884521484375 +8532 -0.03021240234375 +8533 -0.60455322265625 +8534 -0.02978515625 +8535 -0.59619140625 +8536 -0.02935791015625 +8537 -0.587738037109375 +8538 -0.0289306640625 +8539 -0.579254150390625 +8540 -0.02850341796875 +8541 -0.5706787109375 +8542 -0.028076171875 +8543 -0.562042236328125 +8544 -0.02764892578125 +8545 -0.5533447265625 +8546 -0.0272216796875 +8547 -0.54461669921875 +8548 -0.026763916015625 +8549 -0.535797119140625 +8550 -0.026336669921875 +8551 -0.52691650390625 +8552 -0.02587890625 +8553 -0.51800537109375 +8554 -0.025421142578125 +8555 -0.509002685546875 +8556 -0.02496337890625 +8557 -0.499969482421875 +8558 -0.0245361328125 +8559 -0.490875244140625 +8560 -0.024078369140625 +8561 -0.481719970703125 +8562 -0.02362060546875 +8563 -0.4725341796875 +8564 -0.02313232421875 +8565 -0.4632568359375 +8566 -0.022674560546875 +8567 -0.453948974609375 +8568 -0.022216796875 +8569 -0.444610595703125 +8570 -0.021728515625 +8571 -0.435211181640625 +8572 -0.021270751953125 +8573 -0.425750732421875 +8574 -0.020782470703125 +8575 -0.416259765625 +8576 -0.02032470703125 +8577 -0.406707763671875 +8578 -0.01983642578125 +8579 -0.397125244140625 +8580 -0.01934814453125 +8581 -0.387481689453125 +8582 -0.01885986328125 +8583 -0.3778076171875 +8584 -0.01837158203125 +8585 -0.36810302734375 +8586 -0.01788330078125 +8587 -0.35833740234375 +8588 -0.01739501953125 +8589 -0.348541259765625 +8590 -0.01690673828125 +8591 -0.338714599609375 +8592 -0.01641845703125 +8593 -0.328826904296875 +8594 -0.01593017578125 +8595 -0.318939208984375 +8596 -0.01544189453125 +8597 -0.308990478515625 +8598 -0.014923095703125 +8599 -0.29901123046875 +8600 -0.014434814453125 +8601 -0.28900146484375 +8602 -0.013916015625 +8603 -0.278961181640625 +8604 -0.013427734375 +8605 -0.268890380859375 +8606 -0.012908935546875 +8607 -0.2587890625 +8608 -0.012420654296875 +8609 -0.2486572265625 +8610 -0.01190185546875 +8611 -0.238525390625 +8612 -0.01141357421875 +8613 -0.22833251953125 +8614 -0.010894775390625 +8615 -0.218109130859375 +8616 -0.0103759765625 +8617 -0.2078857421875 +8618 -0.009857177734375 +8619 -0.1976318359375 +8620 -0.00933837890625 +8621 -0.187347412109375 +8622 -0.00885009765625 +8623 -0.17706298828125 +8624 -0.008331298828125 +8625 -0.166748046875 +8626 -0.0078125 +8627 -0.156402587890625 +8628 -0.007293701171875 +8629 -0.14605712890625 +8630 -0.00677490234375 +8631 -0.13568115234375 +8632 -0.006256103515625 +8633 -0.12530517578125 +8634 -0.0057373046875 +8635 -0.11492919921875 +8636 -0.005218505859375 +8637 -0.104522705078125 +8638 -0.00469970703125 +8639 -0.094085693359375 +8640 -0.004180908203125 +8641 -0.083648681640625 +8642 -0.003631591796875 +8643 -0.073211669921875 +8644 -0.00311279296875 +8645 -0.062774658203125 +8646 -0.002593994140625 +8647 -0.05230712890625 +8648 -0.0020751953125 +8649 -0.0418701171875 +8650 -0.001556396484375 +8651 -0.031402587890625 +8652 -0.00103759765625 +8653 -0.02093505859375 +8654 -0.000518798828125 +8655 -0.010467529296875 +8656 0.0 +8657 0.0 +8658 0.000579833984375 +8659 0.010467529296875 +8660 0.00115966796875 +8661 0.02093505859375 +8662 0.001739501953125 +8663 0.031402587890625 +8664 0.0023193359375 +8665 0.0418701171875 +8666 0.002899169921875 +8667 0.05230712890625 +8668 0.003509521484375 +8669 0.062774658203125 +8670 0.00408935546875 +8671 0.073211669921875 +8672 0.004669189453125 +8673 0.083648681640625 +8674 0.0052490234375 +8675 0.094085693359375 +8676 0.005828857421875 +8677 0.104522705078125 +8678 0.00640869140625 +8679 0.11492919921875 +8680 0.006988525390625 +8681 0.12530517578125 +8682 0.007568359375 +8683 0.13568115234375 +8684 0.0081787109375 +8685 0.14605712890625 +8686 0.008758544921875 +8687 0.156402587890625 +8688 0.009307861328125 +8689 0.166748046875 +8690 0.0098876953125 +8691 0.17706298828125 +8692 0.010467529296875 +8693 0.187347412109375 +8694 0.01104736328125 +8695 0.1976318359375 +8696 0.011627197265625 +8697 0.2078857421875 +8698 0.01220703125 +8699 0.218109130859375 +8700 0.012786865234375 +8701 0.22833251953125 +8702 0.013336181640625 +8703 0.238525390625 +8704 0.0218505859375 +8705 0.2486572265625 +8706 0.02276611328125 +8707 0.2587890625 +8708 0.023651123046875 +8709 0.268890380859375 +8710 0.0245361328125 +8711 0.278961181640625 +8712 0.025421142578125 +8713 0.28900146484375 +8714 0.02630615234375 +8715 0.29901123046875 +8716 0.02716064453125 +8717 0.308990478515625 +8718 0.028045654296875 +8719 0.318939208984375 +8720 0.0289306640625 +8721 0.328826904296875 +8722 0.02978515625 +8723 0.338714599609375 +8724 0.0306396484375 +8725 0.348541259765625 +8726 0.031524658203125 +8727 0.35833740234375 +8728 0.032379150390625 +8729 0.36810302734375 +8730 0.033233642578125 +8731 0.3778076171875 +8732 0.034088134765625 +8733 0.387481689453125 +8734 0.034912109375 +8735 0.397125244140625 +8736 0.0357666015625 +8737 0.406707763671875 +8738 0.03662109375 +8739 0.416259765625 +8740 0.037445068359375 +8741 0.425750732421875 +8742 0.03826904296875 +8743 0.435211181640625 +8744 0.039093017578125 +8745 0.444610595703125 +8746 0.0399169921875 +8747 0.453948974609375 +8748 0.040740966796875 +8749 0.4632568359375 +8750 0.04156494140625 +8751 0.4725341796875 +8752 0.0423583984375 +8753 0.481719970703125 +8754 0.043182373046875 +8755 0.490875244140625 +8756 0.043975830078125 +8757 0.499969482421875 +8758 0.044769287109375 +8759 0.509002685546875 +8760 0.045562744140625 +8761 0.51800537109375 +8762 0.046356201171875 +8763 0.52691650390625 +8764 0.047119140625 +8765 0.535797119140625 +8766 0.04791259765625 +8767 0.54461669921875 +8768 0.048675537109375 +8769 0.5533447265625 +8770 0.0494384765625 +8771 0.562042236328125 +8772 0.050201416015625 +8773 0.5706787109375 +8774 0.05096435546875 +8775 0.579254150390625 +8776 0.05169677734375 +8777 0.587738037109375 +8778 0.05242919921875 +8779 0.59619140625 +8780 0.05316162109375 +8781 0.60455322265625 +8782 0.053924560546875 +8783 0.612884521484375 +8784 0.05462646484375 +8785 0.621124267578125 +8786 0.05535888671875 +8787 0.6292724609375 +8788 0.056060791015625 +8789 0.63739013671875 +8790 0.0567626953125 +8791 0.645416259765625 +8792 0.057464599609375 +8793 0.65338134765625 +8794 0.05816650390625 +8795 0.661285400390625 +8796 0.058868408203125 +8797 0.669097900390625 +8798 0.059539794921875 +8799 0.676849365234375 +8800 0.060211181640625 +8801 0.68450927734375 +8802 0.060882568359375 +8803 0.692108154296875 +8804 0.061553955078125 +8805 0.699615478515625 +8806 0.06219482421875 +8807 0.707061767578125 +8808 0.062835693359375 +8809 0.714447021484375 +8810 0.0634765625 +8811 0.721710205078125 +8812 0.064117431640625 +8813 0.72894287109375 +8814 0.06475830078125 +8815 0.736053466796875 +8816 0.06536865234375 +8817 0.74310302734375 +8818 0.06597900390625 +8819 0.75006103515625 +8820 0.06658935546875 +8821 0.7569580078125 +8822 0.067169189453125 +8823 0.763763427734375 +8824 0.067779541015625 +8825 0.770477294921875 +8826 0.068359375 +8827 0.777099609375 +8828 0.068939208984375 +8829 0.783660888671875 +8830 0.06951904296875 +8831 0.790130615234375 +8832 0.070068359375 +8833 0.796478271484375 +8834 0.07061767578125 +8835 0.802764892578125 +8836 0.0711669921875 +8837 0.808990478515625 +8838 0.071685791015625 +8839 0.815093994140625 +8840 0.072235107421875 +8841 0.82110595703125 +8842 0.07275390625 +8843 0.8270263671875 +8844 0.073272705078125 +8845 0.8328857421875 +8846 0.073760986328125 +8847 0.838623046875 +8848 0.07427978515625 +8849 0.84429931640625 +8850 0.07476806640625 +8851 0.849853515625 +8852 0.075225830078125 +8853 0.855316162109375 +8854 0.075714111328125 +8855 0.860687255859375 +8856 0.076171875 +8857 0.865997314453125 +8858 0.076629638671875 +8859 0.871185302734375 +8860 0.07708740234375 +8861 0.876251220703125 +8862 0.0775146484375 +8863 0.881256103515625 +8864 0.07794189453125 +8865 0.88616943359375 +8866 0.078369140625 +8867 0.890960693359375 +8868 0.07879638671875 +8869 0.895660400390625 +8870 0.079193115234375 +8871 0.9002685546875 +8872 0.07958984375 +8873 0.90478515625 +8874 0.079986572265625 +8875 0.9091796875 +8876 0.080352783203125 +8877 0.91351318359375 +8878 0.080718994140625 +8879 0.917724609375 +8880 0.081085205078125 +8881 0.92181396484375 +8882 0.081451416015625 +8883 0.92584228515625 +8884 0.081787109375 +8885 0.929718017578125 +8886 0.082122802734375 +8887 0.93353271484375 +8888 0.08245849609375 +8889 0.937225341796875 +8890 0.082763671875 +8891 0.940826416015625 +8892 0.08306884765625 +8893 0.9443359375 +8894 0.0833740234375 +8895 0.947723388671875 +8896 0.083648681640625 +8897 0.951019287109375 +8898 0.083953857421875 +8899 0.954193115234375 +8900 0.084197998046875 +8901 0.957275390625 +8902 0.08447265625 +8903 0.960235595703125 +8904 0.084716796875 +8905 0.963104248046875 +8906 0.0849609375 +8907 0.96588134765625 +8908 0.085205078125 +8909 0.968536376953125 +8910 0.085418701171875 +8911 0.971099853515625 +8912 0.08563232421875 +8913 0.973541259765625 +8914 0.085845947265625 +8915 0.975860595703125 +8916 0.086029052734375 +8917 0.97808837890625 +8918 0.08624267578125 +8919 0.980224609375 +8920 0.086395263671875 +8921 0.98223876953125 +8922 0.086578369140625 +8923 0.984161376953125 +8924 0.08673095703125 +8925 0.9859619140625 +8926 0.086883544921875 +8927 0.987640380859375 +8928 0.0870361328125 +8929 0.989227294921875 +8930 0.087158203125 +8931 0.990692138671875 +8932 0.0872802734375 +8933 0.9920654296875 +8934 0.087371826171875 +8935 0.993316650390625 +8936 0.087493896484375 +8937 0.994476318359375 +8938 0.08758544921875 +8939 0.995513916015625 +8940 0.087646484375 +8941 0.9964599609375 +8942 0.087738037109375 +8943 0.997283935546875 +8944 0.087799072265625 +8945 0.99798583984375 +8946 0.087860107421875 +8947 0.99859619140625 +8948 0.087890625 +8949 0.999114990234375 +8950 0.087921142578125 +8951 0.999481201171875 +8952 0.08795166015625 +8953 0.999755859375 +8954 0.08795166015625 +8955 0.99993896484375 +8956 0.087982177734375 +8957 0.999969482421875 +8958 0.08795166015625 +8959 0.99993896484375 +8960 0.119964599609375 +8961 0.999755859375 +8962 0.119903564453125 +8963 0.999481201171875 +8964 0.119873046875 +8965 0.999114990234375 +8966 0.11981201171875 +8967 0.99859619140625 +8968 0.1197509765625 +8969 0.99798583984375 +8970 0.119659423828125 +8971 0.997283935546875 +8972 0.11956787109375 +8973 0.9964599609375 +8974 0.11944580078125 +8975 0.995513916015625 +8976 0.11932373046875 +8977 0.994476318359375 +8978 0.119171142578125 +8979 0.993316650390625 +8980 0.1190185546875 +8981 0.9920654296875 +8982 0.118865966796875 +8983 0.990692138671875 +8984 0.118682861328125 +8985 0.989227294921875 +8986 0.118499755859375 +8987 0.987640380859375 +8988 0.1182861328125 +8989 0.9859619140625 +8990 0.118072509765625 +8991 0.984161376953125 +8992 0.11785888671875 +8993 0.98223876953125 +8994 0.11761474609375 +8995 0.980224609375 +8996 0.117340087890625 +8997 0.97808837890625 +8998 0.117095947265625 +8999 0.975860595703125 +9000 0.1168212890625 +9001 0.973541259765625 +9002 0.11651611328125 +9003 0.971099853515625 +9004 0.1162109375 +9005 0.968536376953125 +9006 0.115875244140625 +9007 0.96588134765625 +9008 0.115570068359375 +9009 0.963104248046875 +9010 0.115203857421875 +9011 0.960235595703125 +9012 0.1148681640625 +9013 0.957275390625 +9014 0.114501953125 +9015 0.954193115234375 +9016 0.114105224609375 +9017 0.951019287109375 +9018 0.11370849609375 +9019 0.947723388671875 +9020 0.113311767578125 +9021 0.9443359375 +9022 0.112884521484375 +9023 0.940826416015625 +9024 0.112457275390625 +9025 0.937225341796875 +9026 0.11199951171875 +9027 0.93353271484375 +9028 0.111541748046875 +9029 0.929718017578125 +9030 0.111083984375 +9031 0.92584228515625 +9032 0.110595703125 +9033 0.92181396484375 +9034 0.110107421875 +9035 0.917724609375 +9036 0.109619140625 +9037 0.91351318359375 +9038 0.109100341796875 +9039 0.9091796875 +9040 0.108551025390625 +9041 0.90478515625 +9042 0.108001708984375 +9043 0.9002685546875 +9044 0.107452392578125 +9045 0.895660400390625 +9046 0.106903076171875 +9047 0.890960693359375 +9048 0.1063232421875 +9049 0.88616943359375 +9050 0.105743408203125 +9051 0.881256103515625 +9052 0.105133056640625 +9053 0.876251220703125 +9054 0.104522705078125 +9055 0.871185302734375 +9056 0.103912353515625 +9057 0.865997314453125 +9058 0.103271484375 +9059 0.860687255859375 +9060 0.102630615234375 +9061 0.855316162109375 +9062 0.101959228515625 +9063 0.849853515625 +9064 0.101287841796875 +9065 0.84429931640625 +9066 0.100616455078125 +9067 0.838623046875 +9068 0.099945068359375 +9069 0.8328857421875 +9070 0.099212646484375 +9071 0.8270263671875 +9072 0.0985107421875 +9073 0.82110595703125 +9074 0.097808837890625 +9075 0.815093994140625 +9076 0.097076416015625 +9077 0.808990478515625 +9078 0.0963134765625 +9079 0.802764892578125 +9080 0.095550537109375 +9081 0.796478271484375 +9082 0.09478759765625 +9083 0.790130615234375 +9084 0.094024658203125 +9085 0.783660888671875 +9086 0.093231201171875 +9087 0.777099609375 +9088 0.092437744140625 +9089 0.770477294921875 +9090 0.091644287109375 +9091 0.763763427734375 +9092 0.0908203125 +9093 0.7569580078125 +9094 0.089996337890625 +9095 0.75006103515625 +9096 0.089141845703125 +9097 0.74310302734375 +9098 0.08831787109375 +9099 0.736053466796875 +9100 0.08746337890625 +9101 0.72894287109375 +9102 0.086578369140625 +9103 0.721710205078125 +9104 0.085723876953125 +9105 0.714447021484375 +9106 0.0848388671875 +9107 0.707061767578125 +9108 0.08392333984375 +9109 0.699615478515625 +9110 0.083038330078125 +9111 0.692108154296875 +9112 0.082122802734375 +9113 0.68450927734375 +9114 0.081207275390625 +9115 0.676849365234375 +9116 0.08026123046875 +9117 0.669097900390625 +9118 0.079345703125 +9119 0.661285400390625 +9120 0.078399658203125 +9121 0.65338134765625 +9122 0.077423095703125 +9123 0.645416259765625 +9124 0.07647705078125 +9125 0.63739013671875 +9126 0.07550048828125 +9127 0.6292724609375 +9128 0.07452392578125 +9129 0.621124267578125 +9130 0.073516845703125 +9131 0.612884521484375 +9132 0.072540283203125 +9133 0.60455322265625 +9134 0.071533203125 +9135 0.59619140625 +9136 0.070526123046875 +9137 0.587738037109375 +9138 0.069488525390625 +9139 0.579254150390625 +9140 0.068450927734375 +9141 0.5706787109375 +9142 0.06744384765625 +9143 0.562042236328125 +9144 0.066375732421875 +9145 0.5533447265625 +9146 0.065338134765625 +9147 0.54461669921875 +9148 0.06427001953125 +9149 0.535797119140625 +9150 0.063201904296875 +9151 0.52691650390625 +9152 0.0621337890625 +9153 0.51800537109375 +9154 0.061065673828125 +9155 0.509002685546875 +9156 0.059967041015625 +9157 0.499969482421875 +9158 0.05889892578125 +9159 0.490875244140625 +9160 0.05780029296875 +9161 0.481719970703125 +9162 0.05670166015625 +9163 0.4725341796875 +9164 0.055572509765625 +9165 0.4632568359375 +9166 0.054443359375 +9167 0.453948974609375 +9168 0.0533447265625 +9169 0.444610595703125 +9170 0.052215576171875 +9171 0.435211181640625 +9172 0.05108642578125 +9173 0.425750732421875 +9174 0.0499267578125 +9175 0.416259765625 +9176 0.048797607421875 +9177 0.406707763671875 +9178 0.047637939453125 +9179 0.397125244140625 +9180 0.046478271484375 +9181 0.387481689453125 +9182 0.045318603515625 +9183 0.3778076171875 +9184 0.044158935546875 +9185 0.36810302734375 +9186 0.042999267578125 +9187 0.35833740234375 +9188 0.04180908203125 +9189 0.348541259765625 +9190 0.040618896484375 +9191 0.338714599609375 +9192 0.0394287109375 +9193 0.328826904296875 +9194 0.03826904296875 +9195 0.318939208984375 +9196 0.03704833984375 +9197 0.308990478515625 +9198 0.035858154296875 +9199 0.29901123046875 +9200 0.03466796875 +9201 0.28900146484375 +9202 0.033447265625 +9203 0.278961181640625 +9204 0.032257080078125 +9205 0.268890380859375 +9206 0.031036376953125 +9207 0.2587890625 +9208 0.029815673828125 +9209 0.2486572265625 +9210 0.028594970703125 +9211 0.238525390625 +9212 0.027374267578125 +9213 0.22833251953125 +9214 0.026153564453125 +9215 0.218109130859375 +9216 0.031585693359375 +9217 0.2078857421875 +9218 0.030029296875 +9219 0.1976318359375 +9220 0.028472900390625 +9221 0.187347412109375 +9222 0.026885986328125 +9223 0.17706298828125 +9224 0.02532958984375 +9225 0.166748046875 +9226 0.023773193359375 +9227 0.156402587890625 +9228 0.022186279296875 +9229 0.14605712890625 +9230 0.020599365234375 +9231 0.13568115234375 +9232 0.01904296875 +9233 0.12530517578125 +9234 0.0174560546875 +9235 0.11492919921875 +9236 0.015869140625 +9237 0.104522705078125 +9238 0.0142822265625 +9239 0.094085693359375 +9240 0.0126953125 +9241 0.083648681640625 +9242 0.0111083984375 +9243 0.073211669921875 +9244 0.009521484375 +9245 0.062774658203125 +9246 0.0079345703125 +9247 0.05230712890625 +9248 0.00634765625 +9249 0.0418701171875 +9250 0.0047607421875 +9251 0.031402587890625 +9252 0.003173828125 +9253 0.02093505859375 +9254 0.0015869140625 +9255 0.010467529296875 +9256 0.0 +9257 0.0 +9258 -0.0015869140625 +9259 -0.010467529296875 +9260 -0.003173828125 +9261 -0.02093505859375 +9262 -0.0047607421875 +9263 -0.031402587890625 +9264 -0.00634765625 +9265 -0.0418701171875 +9266 -0.0079345703125 +9267 -0.05230712890625 +9268 -0.009521484375 +9269 -0.062774658203125 +9270 -0.0111083984375 +9271 -0.073211669921875 +9272 -0.0126953125 +9273 -0.083648681640625 +9274 -0.0142822265625 +9275 -0.094085693359375 +9276 -0.015869140625 +9277 -0.104522705078125 +9278 -0.0174560546875 +9279 -0.11492919921875 +9280 -0.01904296875 +9281 -0.12530517578125 +9282 -0.020599365234375 +9283 -0.13568115234375 +9284 -0.022186279296875 +9285 -0.14605712890625 +9286 -0.023773193359375 +9287 -0.156402587890625 +9288 -0.02532958984375 +9289 -0.166748046875 +9290 -0.026885986328125 +9291 -0.17706298828125 +9292 -0.028472900390625 +9293 -0.187347412109375 +9294 -0.030029296875 +9295 -0.1976318359375 +9296 -0.031585693359375 +9297 -0.2078857421875 +9298 -0.03314208984375 +9299 -0.218109130859375 +9300 -0.034698486328125 +9301 -0.22833251953125 +9302 -0.0362548828125 +9303 -0.238525390625 +9304 -0.03778076171875 +9305 -0.2486572265625 +9306 -0.039337158203125 +9307 -0.2587890625 +9308 -0.040863037109375 +9309 -0.268890380859375 +9310 -0.042388916015625 +9311 -0.278961181640625 +9312 -0.043914794921875 +9313 -0.28900146484375 +9314 -0.045440673828125 +9315 -0.29901123046875 +9316 -0.046966552734375 +9317 -0.308990478515625 +9318 -0.0484619140625 +9319 -0.318939208984375 +9320 -0.049957275390625 +9321 -0.328826904296875 +9322 -0.051483154296875 +9323 -0.338714599609375 +9324 -0.052978515625 +9325 -0.348541259765625 +9326 -0.054443359375 +9327 -0.35833740234375 +9328 -0.055938720703125 +9329 -0.36810302734375 +9330 -0.057403564453125 +9331 -0.3778076171875 +9332 -0.05889892578125 +9333 -0.387481689453125 +9334 -0.06036376953125 +9335 -0.397125244140625 +9336 -0.061798095703125 +9337 -0.406707763671875 +9338 -0.063262939453125 +9339 -0.416259765625 +9340 -0.064697265625 +9341 -0.425750732421875 +9342 -0.066131591796875 +9343 -0.435211181640625 +9344 -0.06756591796875 +9345 -0.444610595703125 +9346 -0.069000244140625 +9347 -0.453948974609375 +9348 -0.070404052734375 +9349 -0.4632568359375 +9350 -0.071807861328125 +9351 -0.4725341796875 +9352 -0.073211669921875 +9353 -0.481719970703125 +9354 -0.074615478515625 +9355 -0.490875244140625 +9356 -0.07598876953125 +9357 -0.499969482421875 +9358 -0.077362060546875 +9359 -0.509002685546875 +9360 -0.0787353515625 +9361 -0.51800537109375 +9362 -0.080078125 +9363 -0.52691650390625 +9364 -0.0814208984375 +9365 -0.535797119140625 +9366 -0.082763671875 +9367 -0.54461669921875 +9368 -0.0841064453125 +9369 -0.5533447265625 +9370 -0.085418701171875 +9371 -0.562042236328125 +9372 -0.08673095703125 +9373 -0.5706787109375 +9374 -0.088043212890625 +9375 -0.579254150390625 +9376 -0.089324951171875 +9377 -0.587738037109375 +9378 -0.090606689453125 +9379 -0.59619140625 +9380 -0.091888427734375 +9381 -0.60455322265625 +9382 -0.0931396484375 +9383 -0.612884521484375 +9384 -0.094390869140625 +9385 -0.621124267578125 +9386 -0.09564208984375 +9387 -0.6292724609375 +9388 -0.09686279296875 +9389 -0.63739013671875 +9390 -0.09808349609375 +9391 -0.645416259765625 +9392 -0.09930419921875 +9393 -0.65338134765625 +9394 -0.100494384765625 +9395 -0.661285400390625 +9396 -0.1016845703125 +9397 -0.669097900390625 +9398 -0.102874755859375 +9399 -0.676849365234375 +9400 -0.104034423828125 +9401 -0.68450927734375 +9402 -0.105194091796875 +9403 -0.692108154296875 +9404 -0.1063232421875 +9405 -0.699615478515625 +9406 -0.107452392578125 +9407 -0.707061767578125 +9408 -0.10858154296875 +9409 -0.714447021484375 +9410 -0.10968017578125 +9411 -0.721710205078125 +9412 -0.11077880859375 +9413 -0.72894287109375 +9414 -0.11187744140625 +9415 -0.736053466796875 +9416 -0.112945556640625 +9417 -0.74310302734375 +9418 -0.114013671875 +9419 -0.75006103515625 +9420 -0.11505126953125 +9421 -0.7569580078125 +9422 -0.1160888671875 +9423 -0.763763427734375 +9424 -0.117095947265625 +9425 -0.770477294921875 +9426 -0.11810302734375 +9427 -0.777099609375 +9428 -0.119110107421875 +9429 -0.783660888671875 +9430 -0.120086669921875 +9431 -0.790130615234375 +9432 -0.121063232421875 +9433 -0.796478271484375 +9434 -0.12200927734375 +9435 -0.802764892578125 +9436 -0.122955322265625 +9437 -0.808990478515625 +9438 -0.1239013671875 +9439 -0.815093994140625 +9440 -0.12481689453125 +9441 -0.82110595703125 +9442 -0.125701904296875 +9443 -0.8270263671875 +9444 -0.1265869140625 +9445 -0.8328857421875 +9446 -0.127471923828125 +9447 -0.838623046875 +9448 -0.128326416015625 +9449 -0.84429931640625 +9450 -0.129180908203125 +9451 -0.849853515625 +9452 -0.1300048828125 +9453 -0.855316162109375 +9454 -0.130828857421875 +9455 -0.860687255859375 +9456 -0.131622314453125 +9457 -0.865997314453125 +9458 -0.132415771484375 +9459 -0.871185302734375 +9460 -0.1331787109375 +9461 -0.876251220703125 +9462 -0.133941650390625 +9463 -0.881256103515625 +9464 -0.13470458984375 +9465 -0.88616943359375 +9466 -0.13543701171875 +9467 -0.890960693359375 +9468 -0.136138916015625 +9469 -0.895660400390625 +9470 -0.1368408203125 +9471 -0.9002685546875 +9472 -0.166473388671875 +9473 -0.90478515625 +9474 -0.167266845703125 +9475 -0.9091796875 +9476 -0.168060302734375 +9477 -0.91351318359375 +9478 -0.168853759765625 +9479 -0.917724609375 +9480 -0.169586181640625 +9481 -0.92181396484375 +9482 -0.17034912109375 +9483 -0.92584228515625 +9484 -0.171051025390625 +9485 -0.929718017578125 +9486 -0.1717529296875 +9487 -0.93353271484375 +9488 -0.17242431640625 +9489 -0.937225341796875 +9490 -0.173095703125 +9491 -0.940826416015625 +9492 -0.173736572265625 +9493 -0.9443359375 +9494 -0.174346923828125 +9495 -0.947723388671875 +9496 -0.174957275390625 +9497 -0.951019287109375 +9498 -0.175567626953125 +9499 -0.954193115234375 +9500 -0.176116943359375 +9501 -0.957275390625 +9502 -0.176666259765625 +9503 -0.960235595703125 +9504 -0.17718505859375 +9505 -0.963104248046875 +9506 -0.177703857421875 +9507 -0.96588134765625 +9508 -0.178192138671875 +9509 -0.968536376953125 +9510 -0.17864990234375 +9511 -0.971099853515625 +9512 -0.179107666015625 +9513 -0.973541259765625 +9514 -0.179534912109375 +9515 -0.975860595703125 +9516 -0.179962158203125 +9517 -0.97808837890625 +9518 -0.180328369140625 +9519 -0.980224609375 +9520 -0.18072509765625 +9521 -0.98223876953125 +9522 -0.181060791015625 +9523 -0.984161376953125 +9524 -0.181396484375 +9525 -0.9859619140625 +9526 -0.18170166015625 +9527 -0.987640380859375 +9528 -0.1820068359375 +9529 -0.989227294921875 +9530 -0.182281494140625 +9531 -0.990692138671875 +9532 -0.182525634765625 +9533 -0.9920654296875 +9534 -0.1827392578125 +9535 -0.993316650390625 +9536 -0.182952880859375 +9537 -0.994476318359375 +9538 -0.18316650390625 +9539 -0.995513916015625 +9540 -0.183319091796875 +9541 -0.9964599609375 +9542 -0.1834716796875 +9543 -0.997283935546875 +9544 -0.183624267578125 +9545 -0.99798583984375 +9546 -0.1837158203125 +9547 -0.99859619140625 +9548 -0.183807373046875 +9549 -0.999114990234375 +9550 -0.183868408203125 +9551 -0.999481201171875 +9552 -0.183929443359375 +9553 -0.999755859375 +9554 -0.1839599609375 +9555 -0.99993896484375 +9556 -0.183990478515625 +9557 -1.0 +9558 -0.1839599609375 +9559 -0.99993896484375 +9560 -0.183929443359375 +9561 -0.999755859375 +9562 -0.183868408203125 +9563 -0.999481201171875 +9564 -0.183807373046875 +9565 -0.999114990234375 +9566 -0.1837158203125 +9567 -0.99859619140625 +9568 -0.183624267578125 +9569 -0.99798583984375 +9570 -0.1834716796875 +9571 -0.997283935546875 +9572 -0.183319091796875 +9573 -0.9964599609375 +9574 -0.18316650390625 +9575 -0.995513916015625 +9576 -0.182952880859375 +9577 -0.994476318359375 +9578 -0.1827392578125 +9579 -0.993316650390625 +9580 -0.182525634765625 +9581 -0.9920654296875 +9582 -0.182281494140625 +9583 -0.990692138671875 +9584 -0.1820068359375 +9585 -0.989227294921875 +9586 -0.18170166015625 +9587 -0.987640380859375 +9588 -0.181396484375 +9589 -0.9859619140625 +9590 -0.181060791015625 +9591 -0.984161376953125 +9592 -0.18072509765625 +9593 -0.98223876953125 +9594 -0.180328369140625 +9595 -0.980224609375 +9596 -0.179962158203125 +9597 -0.97808837890625 +9598 -0.179534912109375 +9599 -0.975860595703125 +9600 -0.179107666015625 +9601 -0.973541259765625 +9602 -0.17864990234375 +9603 -0.971099853515625 +9604 -0.178192138671875 +9605 -0.968536376953125 +9606 -0.177703857421875 +9607 -0.96588134765625 +9608 -0.17718505859375 +9609 -0.963104248046875 +9610 -0.176666259765625 +9611 -0.960235595703125 +9612 -0.176116943359375 +9613 -0.957275390625 +9614 -0.175567626953125 +9615 -0.954193115234375 +9616 -0.174957275390625 +9617 -0.951019287109375 +9618 -0.174346923828125 +9619 -0.947723388671875 +9620 -0.173736572265625 +9621 -0.9443359375 +9622 -0.173095703125 +9623 -0.940826416015625 +9624 -0.17242431640625 +9625 -0.937225341796875 +9626 -0.1717529296875 +9627 -0.93353271484375 +9628 -0.171051025390625 +9629 -0.929718017578125 +9630 -0.17034912109375 +9631 -0.92584228515625 +9632 -0.169586181640625 +9633 -0.92181396484375 +9634 -0.168853759765625 +9635 -0.917724609375 +9636 -0.168060302734375 +9637 -0.91351318359375 +9638 -0.167266845703125 +9639 -0.9091796875 +9640 -0.166473388671875 +9641 -0.90478515625 +9642 -0.165618896484375 +9643 -0.9002685546875 +9644 -0.164794921875 +9645 -0.895660400390625 +9646 -0.163909912109375 +9647 -0.890960693359375 +9648 -0.16302490234375 +9649 -0.88616943359375 +9650 -0.162139892578125 +9651 -0.881256103515625 +9652 -0.161224365234375 +9653 -0.876251220703125 +9654 -0.1602783203125 +9655 -0.871185302734375 +9656 -0.159332275390625 +9657 -0.865997314453125 +9658 -0.158355712890625 +9659 -0.860687255859375 +9660 -0.1573486328125 +9661 -0.855316162109375 +9662 -0.156341552734375 +9663 -0.849853515625 +9664 -0.15533447265625 +9665 -0.84429931640625 +9666 -0.154296875 +9667 -0.838623046875 +9668 -0.153228759765625 +9669 -0.8328857421875 +9670 -0.15216064453125 +9671 -0.8270263671875 +9672 -0.15106201171875 +9673 -0.82110595703125 +9674 -0.14996337890625 +9675 -0.815093994140625 +9676 -0.148834228515625 +9677 -0.808990478515625 +9678 -0.147705078125 +9679 -0.802764892578125 +9680 -0.14654541015625 +9681 -0.796478271484375 +9682 -0.145355224609375 +9683 -0.790130615234375 +9684 -0.1441650390625 +9685 -0.783660888671875 +9686 -0.142974853515625 +9687 -0.777099609375 +9688 -0.141754150390625 +9689 -0.770477294921875 +9690 -0.1405029296875 +9691 -0.763763427734375 +9692 -0.139251708984375 +9693 -0.7569580078125 +9694 -0.13800048828125 +9695 -0.75006103515625 +9696 -0.13671875 +9697 -0.74310302734375 +9698 -0.135406494140625 +9699 -0.736053466796875 +9700 -0.13409423828125 +9701 -0.72894287109375 +9702 -0.132781982421875 +9703 -0.721710205078125 +9704 -0.131439208984375 +9705 -0.714447021484375 +9706 -0.130096435546875 +9707 -0.707061767578125 +9708 -0.12872314453125 +9709 -0.699615478515625 +9710 -0.1273193359375 +9711 -0.692108154296875 +9712 -0.125946044921875 +9713 -0.68450927734375 +9714 -0.12451171875 +9715 -0.676849365234375 +9716 -0.12310791015625 +9717 -0.669097900390625 +9718 -0.121673583984375 +9719 -0.661285400390625 +9720 -0.120208740234375 +9721 -0.65338134765625 +9722 -0.118743896484375 +9723 -0.645416259765625 +9724 -0.11724853515625 +9725 -0.63739013671875 +9726 -0.115753173828125 +9727 -0.6292724609375 +9728 -0.12420654296875 +9729 -0.621124267578125 +9730 -0.12255859375 +9731 -0.612884521484375 +9732 -0.120880126953125 +9733 -0.60455322265625 +9734 -0.11920166015625 +9735 -0.59619140625 +9736 -0.117523193359375 +9737 -0.587738037109375 +9738 -0.115814208984375 +9739 -0.579254150390625 +9740 -0.114105224609375 +9741 -0.5706787109375 +9742 -0.112396240234375 +9743 -0.562042236328125 +9744 -0.11065673828125 +9745 -0.5533447265625 +9746 -0.10888671875 +9747 -0.54461669921875 +9748 -0.107147216796875 +9749 -0.535797119140625 +9750 -0.1053466796875 +9751 -0.52691650390625 +9752 -0.10357666015625 +9753 -0.51800537109375 +9754 -0.101776123046875 +9755 -0.509002685546875 +9756 -0.0999755859375 +9757 -0.499969482421875 +9758 -0.09814453125 +9759 -0.490875244140625 +9760 -0.0963134765625 +9761 -0.481719970703125 +9762 -0.094482421875 +9763 -0.4725341796875 +9764 -0.092620849609375 +9765 -0.4632568359375 +9766 -0.09075927734375 +9767 -0.453948974609375 +9768 -0.088897705078125 +9769 -0.444610595703125 +9770 -0.0870361328125 +9771 -0.435211181640625 +9772 -0.08514404296875 +9773 -0.425750732421875 +9774 -0.083221435546875 +9775 -0.416259765625 +9776 -0.081329345703125 +9777 -0.406707763671875 +9778 -0.07940673828125 +9779 -0.397125244140625 +9780 -0.077484130859375 +9781 -0.387481689453125 +9782 -0.075531005859375 +9783 -0.3778076171875 +9784 -0.0736083984375 +9785 -0.36810302734375 +9786 -0.0716552734375 +9787 -0.35833740234375 +9788 -0.0697021484375 +9789 -0.348541259765625 +9790 -0.067718505859375 +9791 -0.338714599609375 +9792 -0.06573486328125 +9793 -0.328826904296875 +9794 -0.06378173828125 +9795 -0.318939208984375 +9796 -0.061767578125 +9797 -0.308990478515625 +9798 -0.059783935546875 +9799 -0.29901123046875 +9800 -0.057769775390625 +9801 -0.28900146484375 +9802 -0.0557861328125 +9803 -0.278961181640625 +9804 -0.05377197265625 +9805 -0.268890380859375 +9806 -0.051727294921875 +9807 -0.2587890625 +9808 -0.049713134765625 +9809 -0.2486572265625 +9810 -0.047698974609375 +9811 -0.238525390625 +9812 -0.045654296875 +9813 -0.22833251953125 +9814 -0.043609619140625 +9815 -0.218109130859375 +9816 -0.04156494140625 +9817 -0.2078857421875 +9818 -0.039520263671875 +9819 -0.1976318359375 +9820 -0.037445068359375 +9821 -0.187347412109375 +9822 -0.035400390625 +9823 -0.17706298828125 +9824 -0.0333251953125 +9825 -0.166748046875 +9826 -0.03125 +9827 -0.156402587890625 +9828 -0.029205322265625 +9829 -0.14605712890625 +9830 -0.027130126953125 +9831 -0.13568115234375 +9832 -0.025054931640625 +9833 -0.12530517578125 +9834 -0.022979736328125 +9835 -0.11492919921875 +9836 -0.0208740234375 +9837 -0.104522705078125 +9838 -0.018798828125 +9839 -0.094085693359375 +9840 -0.0167236328125 +9841 -0.083648681640625 +9842 -0.014617919921875 +9843 -0.073211669921875 +9844 -0.012542724609375 +9845 -0.062774658203125 +9846 -0.01043701171875 +9847 -0.05230712890625 +9848 -0.00836181640625 +9849 -0.0418701171875 +9850 -0.006256103515625 +9851 -0.031402587890625 +9852 -0.004180908203125 +9853 -0.02093505859375 +9854 -0.0020751953125 +9855 -0.010467529296875 +9856 0.0 +9857 0.0 +9858 0.00225830078125 +9859 0.010467529296875 +9860 0.0045166015625 +9861 0.02093505859375 +9862 0.00677490234375 +9863 0.031402587890625 +9864 0.009033203125 +9865 0.0418701171875 +9866 0.01129150390625 +9867 0.05230712890625 +9868 0.0135498046875 +9869 0.062774658203125 +9870 0.01580810546875 +9871 0.073211669921875 +9872 0.01806640625 +9873 0.083648681640625 +9874 0.020294189453125 +9875 0.094085693359375 +9876 0.022552490234375 +9877 0.104522705078125 +9878 0.024810791015625 +9879 0.11492919921875 +9880 0.02703857421875 +9881 0.12530517578125 +9882 0.029296875 +9883 0.13568115234375 +9884 0.031524658203125 +9885 0.14605712890625 +9886 0.033782958984375 +9887 0.156402587890625 +9888 0.0360107421875 +9889 0.166748046875 +9890 0.038238525390625 +9891 0.17706298828125 +9892 0.04046630859375 +9893 0.187347412109375 +9894 0.04266357421875 +9895 0.1976318359375 +9896 0.044891357421875 +9897 0.2078857421875 +9898 0.047088623046875 +9899 0.218109130859375 +9900 0.04931640625 +9901 0.22833251953125 +9902 0.051513671875 +9903 0.238525390625 +9904 0.0537109375 +9905 0.2486572265625 +9906 0.055877685546875 +9907 0.2587890625 +9908 0.058074951171875 +9909 0.268890380859375 +9910 0.06024169921875 +9911 0.278961181640625 +9912 0.062408447265625 +9913 0.28900146484375 +9914 0.0645751953125 +9915 0.29901123046875 +9916 0.066741943359375 +9917 0.308990478515625 +9918 0.068878173828125 +9919 0.318939208984375 +9920 0.071014404296875 +9921 0.328826904296875 +9922 0.073150634765625 +9923 0.338714599609375 +9924 0.075286865234375 +9925 0.348541259765625 +9926 0.077392578125 +9927 0.35833740234375 +9928 0.079498291015625 +9929 0.36810302734375 +9930 0.08160400390625 +9931 0.3778076171875 +9932 0.08367919921875 +9933 0.387481689453125 +9934 0.08575439453125 +9935 0.397125244140625 +9936 0.08782958984375 +9937 0.406707763671875 +9938 0.08990478515625 +9939 0.416259765625 +9940 0.091949462890625 +9941 0.425750732421875 +9942 0.093994140625 +9943 0.435211181640625 +9944 0.096038818359375 +9945 0.444610595703125 +9946 0.098052978515625 +9947 0.453948974609375 +9948 0.100067138671875 +9949 0.4632568359375 +9950 0.10205078125 +9951 0.4725341796875 +9952 0.104034423828125 +9953 0.481719970703125 +9954 0.10601806640625 +9955 0.490875244140625 +9956 0.10797119140625 +9957 0.499969482421875 +9958 0.10992431640625 +9959 0.509002685546875 +9960 0.11187744140625 +9961 0.51800537109375 +9962 0.113800048828125 +9963 0.52691650390625 +9964 0.11572265625 +9965 0.535797119140625 +9966 0.11761474609375 +9967 0.54461669921875 +9968 0.1195068359375 +9969 0.5533447265625 +9970 0.12139892578125 +9971 0.562042236328125 +9972 0.123260498046875 +9973 0.5706787109375 +9974 0.1251220703125 +9975 0.579254150390625 +9976 0.126953125 +9977 0.587738037109375 +9978 0.128753662109375 +9979 0.59619140625 +9980 0.130584716796875 +9981 0.60455322265625 +9982 0.13238525390625 +9983 0.612884521484375 +9984 0.154022216796875 +9985 0.621124267578125 +9986 0.156036376953125 +9987 0.6292724609375 +9988 0.158050537109375 +9989 0.63739013671875 +9990 0.1600341796875 +9991 0.645416259765625 +9992 0.162017822265625 +9993 0.65338134765625 +9994 0.163970947265625 +9995 0.661285400390625 +9996 0.165924072265625 +9997 0.669097900390625 +9998 0.1678466796875 +9999 0.676849365234375 +10000 0.16973876953125 +10001 0.68450927734375 +10002 0.171630859375 +10003 0.692108154296875 +10004 0.173492431640625 +10005 0.699615478515625 +10006 0.175323486328125 +10007 0.707061767578125 +10008 0.177154541015625 +10009 0.714447021484375 +10010 0.178955078125 +10011 0.721710205078125 +10012 0.180755615234375 +10013 0.72894287109375 +10014 0.182525634765625 +10015 0.736053466796875 +10016 0.18426513671875 +10017 0.74310302734375 +10018 0.186004638671875 +10019 0.75006103515625 +10020 0.187713623046875 +10021 0.7569580078125 +10022 0.18939208984375 +10023 0.763763427734375 +10024 0.191070556640625 +10025 0.770477294921875 +10026 0.19268798828125 +10027 0.777099609375 +10028 0.1943359375 +10029 0.783660888671875 +10030 0.1959228515625 +10031 0.790130615234375 +10032 0.197509765625 +10033 0.796478271484375 +10034 0.199066162109375 +10035 0.802764892578125 +10036 0.20062255859375 +10037 0.808990478515625 +10038 0.202117919921875 +10039 0.815093994140625 +10040 0.20361328125 +10041 0.82110595703125 +10042 0.205078125 +10043 0.8270263671875 +10044 0.20654296875 +10045 0.8328857421875 +10046 0.20794677734375 +10047 0.838623046875 +10048 0.2093505859375 +10049 0.84429931640625 +10050 0.21075439453125 +10051 0.849853515625 +10052 0.21209716796875 +10053 0.855316162109375 +10054 0.21343994140625 +10055 0.860687255859375 +10056 0.214752197265625 +10057 0.865997314453125 +10058 0.216033935546875 +10059 0.871185302734375 +10060 0.21728515625 +10061 0.876251220703125 +10062 0.218536376953125 +10063 0.881256103515625 +10064 0.219757080078125 +10065 0.88616943359375 +10066 0.220947265625 +10067 0.890960693359375 +10068 0.22210693359375 +10069 0.895660400390625 +10070 0.223236083984375 +10071 0.9002685546875 +10072 0.224365234375 +10073 0.90478515625 +10074 0.2254638671875 +10075 0.9091796875 +10076 0.226531982421875 +10077 0.91351318359375 +10078 0.227569580078125 +10079 0.917724609375 +10080 0.22857666015625 +10081 0.92181396484375 +10082 0.229583740234375 +10083 0.92584228515625 +10084 0.230560302734375 +10085 0.929718017578125 +10086 0.23150634765625 +10087 0.93353271484375 +10088 0.232421875 +10089 0.937225341796875 +10090 0.233306884765625 +10091 0.940826416015625 +10092 0.234161376953125 +10093 0.9443359375 +10094 0.235015869140625 +10095 0.947723388671875 +10096 0.23583984375 +10097 0.951019287109375 +10098 0.23663330078125 +10099 0.954193115234375 +10100 0.237396240234375 +10101 0.957275390625 +10102 0.238128662109375 +10103 0.960235595703125 +10104 0.23883056640625 +10105 0.963104248046875 +10106 0.239501953125 +10107 0.96588134765625 +10108 0.24017333984375 +10109 0.968536376953125 +10110 0.240814208984375 +10111 0.971099853515625 +10112 0.241424560546875 +10113 0.973541259765625 +10114 0.24200439453125 +10115 0.975860595703125 +10116 0.2425537109375 +10117 0.97808837890625 +10118 0.243072509765625 +10119 0.980224609375 +10120 0.243560791015625 +10121 0.98223876953125 +10122 0.244049072265625 +10123 0.984161376953125 +10124 0.2445068359375 +10125 0.9859619140625 +10126 0.244903564453125 +10127 0.987640380859375 +10128 0.24530029296875 +10129 0.989227294921875 +10130 0.24566650390625 +10131 0.990692138671875 +10132 0.246002197265625 +10133 0.9920654296875 +10134 0.246307373046875 +10135 0.993316650390625 +10136 0.246612548828125 +10137 0.994476318359375 +10138 0.246856689453125 +10139 0.995513916015625 +10140 0.247100830078125 +10141 0.9964599609375 +10142 0.247314453125 +10143 0.997283935546875 +10144 0.247467041015625 +10145 0.99798583984375 +10146 0.24761962890625 +10147 0.99859619140625 +10148 0.24774169921875 +10149 0.999114990234375 +10150 0.247833251953125 +10151 0.999481201171875 +10152 0.2479248046875 +10153 0.999755859375 +10154 0.247955322265625 +10155 0.99993896484375 +10156 0.24798583984375 +10157 0.999969482421875 +10158 0.247955322265625 +10159 0.99993896484375 +10160 0.2479248046875 +10161 0.999755859375 +10162 0.247833251953125 +10163 0.999481201171875 +10164 0.24774169921875 +10165 0.999114990234375 +10166 0.24761962890625 +10167 0.99859619140625 +10168 0.247467041015625 +10169 0.99798583984375 +10170 0.247314453125 +10171 0.997283935546875 +10172 0.247100830078125 +10173 0.9964599609375 +10174 0.246856689453125 +10175 0.995513916015625 +10176 0.246612548828125 +10177 0.994476318359375 +10178 0.246307373046875 +10179 0.993316650390625 +10180 0.246002197265625 +10181 0.9920654296875 +10182 0.24566650390625 +10183 0.990692138671875 +10184 0.24530029296875 +10185 0.989227294921875 +10186 0.244903564453125 +10187 0.987640380859375 +10188 0.2445068359375 +10189 0.9859619140625 +10190 0.244049072265625 +10191 0.984161376953125 +10192 0.243560791015625 +10193 0.98223876953125 +10194 0.243072509765625 +10195 0.980224609375 +10196 0.2425537109375 +10197 0.97808837890625 +10198 0.24200439453125 +10199 0.975860595703125 +10200 0.241424560546875 +10201 0.973541259765625 +10202 0.240814208984375 +10203 0.971099853515625 +10204 0.24017333984375 +10205 0.968536376953125 +10206 0.239501953125 +10207 0.96588134765625 +10208 0.23883056640625 +10209 0.963104248046875 +10210 0.238128662109375 +10211 0.960235595703125 +10212 0.237396240234375 +10213 0.957275390625 +10214 0.23663330078125 +10215 0.954193115234375 +10216 0.23583984375 +10217 0.951019287109375 +10218 0.235015869140625 +10219 0.947723388671875 +10220 0.234161376953125 +10221 0.9443359375 +10222 0.233306884765625 +10223 0.940826416015625 +10224 0.232421875 +10225 0.937225341796875 +10226 0.23150634765625 +10227 0.93353271484375 +10228 0.230560302734375 +10229 0.929718017578125 +10230 0.229583740234375 +10231 0.92584228515625 +10232 0.22857666015625 +10233 0.92181396484375 +10234 0.227569580078125 +10235 0.917724609375 +10236 0.226531982421875 +10237 0.91351318359375 +10238 0.2254638671875 +10239 0.9091796875 +10240 0.0 +10241 0.0 +10242 0.0 +10243 0.0 +10244 0.0 +10245 0.0 +10246 0.0 +10247 0.0 +10248 0.0 +10249 0.0 +10250 0.0 +10251 0.0 +10252 0.0 +10253 0.0 +10254 0.0 +10255 0.0 +10256 0.0 +10257 0.0 +10258 0.0 +10259 0.0 +10260 0.0 +10261 0.0 +10262 0.0 +10263 0.0 +10264 0.0 +10265 0.0 +10266 0.0 +10267 0.0 +10268 0.0 +10269 0.0 +10270 0.0 +10271 0.0 +10272 0.0 +10273 0.0 +10274 0.0 +10275 0.0 +10276 0.0 +10277 0.0 +10278 0.0 +10279 0.0 +10280 0.0 +10281 0.0 +10282 0.0 +10283 0.0 +10284 0.0 +10285 0.0 +10286 0.0 +10287 0.0 +10288 0.0 +10289 0.0 +10290 0.0 +10291 0.0 +10292 0.0 +10293 0.0 +10294 0.0 +10295 0.0 +10296 0.0 +10297 0.0 +10298 0.0 +10299 0.0 +10300 0.0 +10301 0.0 +10302 0.0 +10303 0.0 +10304 0.0 +10305 0.0 +10306 0.0 +10307 0.0 +10308 0.0 +10309 0.0 +10310 0.0 +10311 0.0 +10312 0.0 +10313 0.0 +10314 0.0 +10315 0.0 +10316 0.0 +10317 0.0 +10318 0.0 +10319 0.0 +10320 0.0 +10321 0.0 +10322 0.0 +10323 0.0 +10324 0.0 +10325 0.0 +10326 0.0 +10327 0.0 +10328 0.0 +10329 0.0 +10330 0.0 +10331 0.0 +10332 0.0 +10333 0.0 +10334 0.0 +10335 0.0 +10336 0.0 +10337 0.0 +10338 0.0 +10339 0.0 +10340 0.0 +10341 0.0 +10342 0.0 +10343 0.0 +10344 0.0 +10345 0.0 +10346 0.0 +10347 0.0 +10348 0.0 +10349 0.0 +10350 0.0 +10351 0.0 +10352 0.0 +10353 0.0 +10354 0.0 +10355 0.0 +10356 0.0 +10357 0.0 +10358 0.0 +10359 0.0 +10360 0.0 +10361 0.0 +10362 0.0 +10363 0.0 +10364 0.0 +10365 0.0 +10366 0.0 +10367 0.0 +10368 0.0 +10369 0.0 +10370 0.0 +10371 0.0 +10372 0.0 +10373 0.0 +10374 0.0 +10375 0.0 +10376 0.0 +10377 0.0 +10378 0.0 +10379 0.0 +10380 0.0 +10381 0.0 +10382 0.0 +10383 0.0 +10384 0.0 +10385 0.0 +10386 0.0 +10387 0.0 +10388 0.0 +10389 0.0 +10390 0.0 +10391 0.0 +10392 0.0 +10393 0.0 +10394 0.0 +10395 0.0 +10396 0.0 +10397 0.0 +10398 0.0 +10399 0.0 +10400 0.0 +10401 0.0 +10402 0.0 +10403 0.0 +10404 0.0 +10405 0.0 +10406 0.0 +10407 0.0 +10408 0.0 +10409 0.0 +10410 0.0 +10411 0.0 +10412 0.0 +10413 0.0 +10414 0.0 +10415 0.0 +10416 0.0 +10417 0.0 +10418 0.0 +10419 0.0 +10420 0.0 +10421 0.0 +10422 0.0 +10423 0.0 +10424 0.0 +10425 0.0 +10426 0.0 +10427 0.0 +10428 0.0 +10429 0.0 +10430 0.0 +10431 0.0 +10432 0.0 +10433 0.0 +10434 0.0 +10435 0.0 +10436 0.0 +10437 0.0 +10438 0.0 +10439 0.0 +10440 0.0 +10441 0.0 +10442 0.0 +10443 0.0 +10444 0.0 +10445 0.0 +10446 0.0 +10447 0.0 +10448 0.0 +10449 0.0 +10450 0.0 +10451 0.0 +10452 0.0 +10453 0.0 +10454 0.0 +10455 0.0 +10456 0.0 +10457 0.0 +10458 0.0 +10459 0.0 +10460 0.0 +10461 0.0 +10462 0.0 +10463 0.0 +10464 0.0 +10465 0.0 +10466 0.0 +10467 0.0 +10468 0.0 +10469 0.0 +10470 0.0 +10471 0.0 +10472 0.0 +10473 0.0 +10474 0.0 +10475 0.0 +10476 0.0 +10477 0.0 +10478 0.0 +10479 0.0 +10480 0.0 +10481 0.0 +10482 0.0 +10483 0.0 +10484 0.0 +10485 0.0 +10486 0.0 +10487 0.0 +10488 0.0 +10489 0.0 +10490 0.0 +10491 0.0 +10492 0.0 +10493 0.0 +10494 0.0 +10495 0.0 +10496 0.0 +10497 0.0 +10498 0.0 +10499 0.0 +10500 0.0 +10501 0.0 +10502 0.0 +10503 0.0 +10504 0.0 +10505 0.0 +10506 0.0 +10507 0.0 +10508 0.0 +10509 0.0 +10510 0.0 +10511 0.0 +10512 0.0 +10513 0.0 +10514 0.0 +10515 0.0 +10516 0.0 +10517 0.0 +10518 0.0 +10519 0.0 +10520 0.0 +10521 0.0 +10522 0.0 +10523 0.0 +10524 0.0 +10525 0.0 +10526 0.0 +10527 0.0 +10528 0.0 +10529 0.0 +10530 0.0 +10531 0.0 +10532 0.0 +10533 0.0 +10534 0.0 +10535 0.0 +10536 0.0 +10537 0.0 +10538 0.0 +10539 0.0 +10540 0.0 +10541 0.0 +10542 0.0 +10543 0.0 +10544 0.0 +10545 0.0 +10546 0.0 +10547 0.0 +10548 0.0 +10549 0.0 +10550 0.0 +10551 0.0 +10552 0.0 +10553 0.0 +10554 0.0 +10555 0.0 +10556 0.0 +10557 0.0 +10558 0.0 +10559 0.0 +10560 0.0 +10561 0.0 +10562 0.0 +10563 0.0 +10564 0.0 +10565 0.0 +10566 0.0 +10567 0.0 +10568 0.0 +10569 0.0 +10570 0.0 +10571 0.0 +10572 0.0 +10573 0.0 +10574 0.0 +10575 0.0 +10576 0.0 +10577 0.0 +10578 0.0 +10579 0.0 +10580 0.0 +10581 0.0 +10582 0.0 +10583 0.0 +10584 0.0 +10585 0.0 +10586 0.0 +10587 0.0 +10588 0.0 +10589 0.0 +10590 0.0 +10591 0.0 +10592 0.0 +10593 0.0 +10594 0.0 +10595 0.0 +10596 0.0 +10597 0.0 +10598 0.0 +10599 0.0 +10600 0.0 +10601 0.0 +10602 0.0 +10603 0.0 +10604 0.0 +10605 0.0 +10606 0.0 +10607 0.0 +10608 0.0 +10609 0.0 +10610 0.0 +10611 0.0 +10612 0.0 +10613 0.0 +10614 0.0 +10615 0.0 +10616 0.0 +10617 0.0 +10618 0.0 +10619 0.0 +10620 0.0 +10621 0.0 +10622 0.0 +10623 0.0 +10624 0.0 +10625 0.0 +10626 0.0 +10627 0.0 +10628 0.0 +10629 0.0 +10630 0.0 +10631 0.0 +10632 0.0 +10633 0.0 +10634 0.0 +10635 0.0 +10636 0.0 +10637 0.0 +10638 0.0 +10639 0.0 +10640 0.0 +10641 0.0 +10642 0.0 +10643 0.0 +10644 0.0 +10645 0.0 +10646 0.0 +10647 0.0 +10648 0.0 +10649 0.0 +10650 0.0 +10651 0.0 +10652 0.0 +10653 0.0 +10654 0.0 +10655 0.0 +10656 0.0 +10657 0.0 +10658 0.0 +10659 0.0 +10660 0.0 +10661 0.0 +10662 0.0 +10663 0.0 +10664 0.0 +10665 0.0 +10666 0.0 +10667 0.0 +10668 0.0 +10669 0.0 +10670 0.0 +10671 0.0 +10672 0.0 +10673 0.0 +10674 0.0 +10675 0.0 +10676 0.0 +10677 0.0 +10678 0.0 +10679 0.0 +10680 0.0 +10681 0.0 +10682 0.0 +10683 0.0 +10684 0.0 +10685 0.0 +10686 0.0 +10687 0.0 +10688 0.0 +10689 0.0 +10690 0.0 +10691 0.0 +10692 0.0 +10693 0.0 +10694 0.0 +10695 0.0 +10696 0.0 +10697 0.0 +10698 0.0 +10699 0.0 +10700 0.0 +10701 0.0 +10702 0.0 +10703 0.0 +10704 0.0 +10705 0.0 +10706 0.0 +10707 0.0 +10708 0.0 +10709 0.0 +10710 0.0 +10711 0.0 +10712 0.0 +10713 0.0 +10714 0.0 +10715 0.0 +10716 0.0 +10717 0.0 +10718 0.0 +10719 0.0 +10720 0.0 +10721 0.0 +10722 0.0 +10723 0.0 +10724 0.0 +10725 0.0 +10726 0.0 +10727 0.0 +10728 0.0 +10729 0.0 +10730 0.0 +10731 0.0 +10732 0.0 +10733 0.0 +10734 0.0 +10735 0.0 +10736 0.0 +10737 0.0 +10738 0.0 +10739 0.0 +10740 0.0 +10741 0.0 +10742 0.0 +10743 0.0 +10744 0.0 +10745 0.0 +10746 0.0 +10747 0.0 +10748 0.0 +10749 0.0 +10750 0.0 +10751 0.0 +10752 0.0 +10753 0.0 +10754 0.0 +10755 0.0 +10756 0.0 +10757 0.0 +10758 0.0 +10759 0.0 +10760 0.0 +10761 0.0 +10762 0.0 +10763 0.0 +10764 0.0 +10765 0.0 +10766 0.0 +10767 0.0 +10768 0.0 +10769 0.0 +10770 0.0 +10771 0.0 +10772 0.0 +10773 0.0 +10774 0.0 +10775 0.0 +10776 0.0 +10777 0.0 +10778 0.0 +10779 0.0 +10780 0.0 +10781 0.0 +10782 0.0 +10783 0.0 +10784 0.0 +10785 0.0 +10786 0.0 +10787 0.0 +10788 0.0 +10789 0.0 +10790 0.0 +10791 0.0 +10792 0.0 +10793 0.0 +10794 0.0 +10795 0.0 +10796 0.0 +10797 0.0 +10798 0.0 +10799 0.0 +10800 0.0 +10801 0.0 +10802 0.0 +10803 0.0 +10804 0.0 +10805 0.0 +10806 0.0 +10807 0.0 +10808 0.0 +10809 0.0 +10810 0.0 +10811 0.0 +10812 0.0 +10813 0.0 +10814 0.0 +10815 0.0 +10816 0.0 +10817 0.0 +10818 0.0 +10819 0.0 +10820 0.0 +10821 0.0 +10822 0.0 +10823 0.0 +10824 0.0 +10825 0.0 +10826 0.0 +10827 0.0 +10828 0.0 +10829 0.0 +10830 0.0 +10831 0.0 +10832 0.0 +10833 0.0 +10834 0.0 +10835 0.0 +10836 0.0 +10837 0.0 +10838 0.0 +10839 0.0 +10840 0.0 +10841 0.0 +10842 0.0 +10843 0.0 +10844 0.0 +10845 0.0 +10846 0.0 +10847 0.0 +10848 0.0 +10849 0.0 +10850 0.0 +10851 0.0 +10852 0.0 +10853 0.0 +10854 0.0 +10855 0.0 +10856 0.0 +10857 0.0 +10858 0.0 +10859 0.0 +10860 0.0 +10861 0.0 +10862 0.0 +10863 0.0 +10864 0.0 +10865 0.0 +10866 0.0 +10867 0.0 +10868 0.0 +10869 0.0 +10870 0.0 +10871 0.0 +10872 0.0 +10873 0.0 +10874 0.0 +10875 0.0 +10876 0.0 +10877 0.0 +10878 0.0 +10879 0.0 +10880 0.0 +10881 0.0 +10882 0.0 +10883 0.0 +10884 0.0 +10885 0.0 +10886 0.0 +10887 0.0 +10888 0.0 +10889 0.0 +10890 0.0 +10891 0.0 +10892 0.0 +10893 0.0 +10894 0.0 +10895 0.0 +10896 0.0 +10897 0.0 +10898 0.0 +10899 0.0 +10900 0.0 +10901 0.0 +10902 0.0 +10903 0.0 +10904 0.0 +10905 0.0 +10906 0.0 +10907 0.0 +10908 0.0 +10909 0.0 +10910 0.0 +10911 0.0 +10912 0.0 +10913 0.0 +10914 0.0 +10915 0.0 +10916 0.0 +10917 0.0 +10918 0.0 +10919 0.0 +10920 0.0 +10921 0.0 +10922 0.0 +10923 0.0 +10924 0.0 +10925 0.0 +10926 0.0 +10927 0.0 +10928 0.0 +10929 0.0 +10930 0.0 +10931 0.0 +10932 0.0 +10933 0.0 +10934 0.0 +10935 0.0 +10936 0.0 +10937 0.0 +10938 0.0 +10939 0.0 +10940 0.0 +10941 0.0 +10942 0.0 +10943 0.0 +10944 0.0 +10945 0.0 +10946 0.0 +10947 0.0 +10948 0.0 +10949 0.0 +10950 0.0 +10951 0.0 +10952 0.0 +10953 0.0 +10954 0.0 +10955 0.0 +10956 0.0 +10957 0.0 +10958 0.0 +10959 0.0 +10960 0.0 +10961 0.0 +10962 0.0 +10963 0.0 +10964 0.0 +10965 0.0 +10966 0.0 +10967 0.0 +10968 0.0 +10969 0.0 +10970 0.0 +10971 0.0 +10972 0.0 +10973 0.0 +10974 0.0 +10975 0.0 +10976 0.0 +10977 0.0 +10978 0.0 +10979 0.0 +10980 0.0 +10981 0.0 +10982 0.0 +10983 0.0 +10984 0.0 +10985 0.0 +10986 0.0 +10987 0.0 +10988 0.0 +10989 0.0 +10990 0.0 +10991 0.0 +10992 0.0 +10993 0.0 +10994 0.0 +10995 0.0 +10996 0.0 +10997 0.0 +10998 0.0 +10999 0.0 +11000 0.0 +11001 0.0 +11002 0.0 +11003 0.0 +11004 0.0 +11005 0.0 +11006 0.0 +11007 0.0 +11008 0.0 +11009 0.0 +11010 0.0 +11011 0.0 +11012 0.0 +11013 0.0 +11014 0.0 +11015 0.0 +11016 0.0 +11017 0.0 +11018 0.0 +11019 0.0 +11020 0.0 +11021 0.0 +11022 0.0 +11023 0.0 +11024 0.0 +11025 0.0 +11026 0.0 +11027 0.0 +11028 0.0 +11029 0.0 +11030 0.0 +11031 0.0 +11032 0.0 +11033 0.0 +11034 0.0 +11035 0.0 +11036 0.0 +11037 0.0 +11038 0.0 +11039 0.0 +11040 0.0 +11041 0.0 +11042 0.0 +11043 0.0 +11044 0.0 +11045 0.0 +11046 0.0 +11047 0.0 +11048 0.0 +11049 0.0 +11050 0.0 +11051 0.0 +11052 0.0 +11053 0.0 +11054 0.0 +11055 0.0 +11056 0.0 +11057 0.0 +11058 0.0 +11059 0.0 +11060 0.0 +11061 0.0 +11062 0.0 +11063 0.0 +11064 0.0 +11065 0.0 +11066 0.0 +11067 0.0 +11068 0.0 +11069 0.0 +11070 0.0 +11071 0.0 +11072 0.0 +11073 0.0 +11074 0.0 +11075 0.0 +11076 0.0 +11077 0.0 +11078 0.0 +11079 0.0 +11080 0.0 +11081 0.0 +11082 0.0 +11083 0.0 +11084 0.0 +11085 0.0 +11086 0.0 +11087 0.0 +11088 0.0 +11089 0.0 +11090 0.0 +11091 0.0 +11092 0.0 +11093 0.0 +11094 0.0 +11095 0.0 +11096 0.0 +11097 0.0 +11098 0.0 +11099 0.0 +11100 0.0 +11101 0.0 +11102 0.0 +11103 0.0 +11104 0.0 +11105 0.0 +11106 0.0 +11107 0.0 +11108 0.0 +11109 0.0 +11110 0.0 +11111 0.0 +11112 0.0 +11113 0.0 +11114 0.0 +11115 0.0 +11116 0.0 +11117 0.0 +11118 0.0 +11119 0.0 +11120 0.0 +11121 0.0 +11122 0.0 +11123 0.0 +11124 0.0 +11125 0.0 +11126 0.0 +11127 0.0 +11128 0.0 +11129 0.0 +11130 0.0 +11131 0.0 +11132 0.0 +11133 0.0 +11134 0.0 +11135 0.0 +11136 0.0 +11137 0.0 +11138 0.0 +11139 0.0 +11140 0.0 +11141 0.0 +11142 0.0 +11143 0.0 +11144 0.0 +11145 0.0 +11146 0.0 +11147 0.0 +11148 0.0 +11149 0.0 +11150 0.0 +11151 0.0 +11152 0.0 +11153 0.0 +11154 0.0 +11155 0.0 +11156 0.0 +11157 0.0 +11158 0.0 +11159 0.0 +11160 0.0 +11161 0.0 +11162 0.0 +11163 0.0 +11164 0.0 +11165 0.0 +11166 0.0 +11167 0.0 +11168 0.0 +11169 0.0 +11170 0.0 +11171 0.0 +11172 0.0 +11173 0.0 +11174 0.0 +11175 0.0 +11176 0.0 +11177 0.0 +11178 0.0 +11179 0.0 +11180 0.0 +11181 0.0 +11182 0.0 +11183 0.0 +11184 0.0 +11185 0.0 +11186 0.0 +11187 0.0 +11188 0.0 +11189 0.0 +11190 0.0 +11191 0.0 +11192 0.0 +11193 0.0 +11194 0.0 +11195 0.0 +11196 0.0 +11197 0.0 +11198 0.0 +11199 0.0 +11200 0.0 +11201 0.0 +11202 0.0 +11203 0.0 +11204 0.0 +11205 0.0 +11206 0.0 +11207 0.0 +11208 0.0 +11209 0.0 +11210 0.0 +11211 0.0 +11212 0.0 +11213 0.0 +11214 0.0 +11215 0.0 +11216 0.0 +11217 0.0 +11218 0.0 +11219 0.0 +11220 0.0 +11221 0.0 +11222 0.0 +11223 0.0 +11224 0.0 +11225 0.0 +11226 0.0 +11227 0.0 +11228 0.0 +11229 0.0 +11230 0.0 +11231 0.0 +11232 0.0 +11233 0.0 +11234 0.0 +11235 0.0 +11236 0.0 +11237 0.0 +11238 0.0 +11239 0.0 +11240 0.0 +11241 0.0 +11242 0.0 +11243 0.0 +11244 0.0 +11245 0.0 +11246 0.0 +11247 0.0 +11248 0.0 +11249 0.0 +11250 0.0 +11251 0.0 +11252 0.0 +11253 0.0 +11254 0.0 +11255 0.0 +11256 0.0 +11257 0.0 +11258 0.0 +11259 0.0 +11260 0.0 +11261 0.0 +11262 0.0 +11263 0.0 +11264 0.0 +11265 0.0 +11266 0.0 +11267 0.0 +11268 0.0 +11269 0.0 +11270 0.0 +11271 0.0 +11272 0.0 +11273 0.0 +11274 0.0 +11275 0.0 +11276 0.0 +11277 0.0 +11278 0.0 +11279 0.0 +11280 0.0 +11281 0.0 +11282 0.0 +11283 0.0 +11284 0.0 +11285 0.0 +11286 0.0 +11287 0.0 +11288 0.0 +11289 0.0 +11290 0.0 +11291 0.0 +11292 0.0 +11293 0.0 +11294 0.0 +11295 0.0 +11296 0.0 +11297 0.0 +11298 0.0 +11299 0.0 +11300 0.0 +11301 0.0 +11302 0.0 +11303 0.0 +11304 0.0 +11305 0.0 +11306 0.0 +11307 0.0 +11308 0.0 +11309 0.0 +11310 0.0 +11311 0.0 +11312 0.0 +11313 0.0 +11314 0.0 +11315 0.0 +11316 0.0 +11317 0.0 +11318 0.0 +11319 0.0 +11320 0.0 +11321 0.0 +11322 0.0 +11323 0.0 +11324 0.0 +11325 0.0 +11326 0.0 +11327 0.0 +11328 0.0 +11329 0.0 +11330 0.0 +11331 0.0 +11332 0.0 +11333 0.0 +11334 0.0 +11335 0.0 +11336 0.0 +11337 0.0 +11338 0.0 +11339 0.0 +11340 0.0 +11341 0.0 +11342 0.0 +11343 0.0 +11344 0.0 +11345 0.0 +11346 0.0 +11347 0.0 +11348 0.0 +11349 0.0 +11350 0.0 +11351 0.0 +11352 0.0 +11353 0.0 +11354 0.0 +11355 0.0 +11356 0.0 +11357 0.0 +11358 0.0 +11359 0.0 +11360 0.0 +11361 0.0 +11362 0.0 +11363 0.0 +11364 0.0 +11365 0.0 +11366 0.0 +11367 0.0 +11368 0.0 +11369 0.0 +11370 0.0 +11371 0.0 +11372 0.0 +11373 0.0 +11374 0.0 +11375 0.0 +11376 0.0 +11377 0.0 +11378 0.0 +11379 0.0 +11380 0.0 +11381 0.0 +11382 0.0 +11383 0.0 +11384 0.0 +11385 0.0 +11386 0.0 +11387 0.0 +11388 0.0 +11389 0.0 +11390 0.0 +11391 0.0 +11392 0.0 +11393 0.0 +11394 0.0 +11395 0.0 +11396 0.0 +11397 0.0 +11398 0.0 +11399 0.0 +11400 0.0 +11401 0.0 +11402 0.0 +11403 0.0 +11404 0.0 +11405 0.0 +11406 0.0 +11407 0.0 +11408 0.0 +11409 0.0 +11410 0.0 +11411 0.0 +11412 0.0 +11413 0.0 +11414 0.0 +11415 0.0 +11416 0.0 +11417 0.0 +11418 0.0 +11419 0.0 +11420 0.0 +11421 0.0 +11422 0.0 +11423 0.0 +11424 0.0 +11425 0.0 +11426 0.0 +11427 0.0 +11428 0.0 +11429 0.0 +11430 0.0 +11431 0.0 +11432 0.0 +11433 0.0 +11434 0.0 +11435 0.0 +11436 0.0 +11437 0.0 +11438 0.0 +11439 0.0 +11440 0.0 +11441 0.0 +11442 0.0 +11443 0.0 +11444 0.0 +11445 0.0 +11446 0.0 +11447 0.0 +11448 0.0 +11449 0.0 +11450 0.0 +11451 0.0 +11452 0.0 +11453 0.0 +11454 0.0 +11455 0.0 +11456 0.0 +11457 0.0 +11458 0.0 +11459 0.0 +11460 0.0 +11461 0.0 +11462 0.0 +11463 0.0 +11464 0.0 +11465 0.0 +11466 0.0 +11467 0.0 +11468 0.0 +11469 0.0 +11470 0.0 +11471 0.0 +11472 0.0 +11473 0.0 +11474 0.0 +11475 0.0 +11476 0.0 +11477 0.0 +11478 0.0 +11479 0.0 +11480 0.0 +11481 0.0 +11482 0.0 +11483 0.0 +11484 0.0 +11485 0.0 +11486 0.0 +11487 0.0 +11488 0.0 +11489 0.0 +11490 0.0 +11491 0.0 +11492 0.0 +11493 0.0 +11494 0.0 +11495 0.0 +11496 0.0 +11497 0.0 +11498 0.0 +11499 0.0 +11500 0.0 +11501 0.0 +11502 0.0 +11503 0.0 +11504 0.0 +11505 0.0 +11506 0.0 +11507 0.0 +11508 0.0 +11509 0.0 +11510 0.0 +11511 0.0 +11512 0.0 +11513 0.0 +11514 0.0 +11515 0.0 +11516 0.0 +11517 0.0 +11518 0.0 +11519 0.0 +11520 0.0 +11521 0.0 +11522 0.0 +11523 0.0 +11524 0.0 +11525 0.0 +11526 0.0 +11527 0.0 +11528 0.0 +11529 0.0 +11530 0.0 +11531 0.0 +11532 0.0 +11533 0.0 +11534 0.0 +11535 0.0 +11536 0.0 +11537 0.0 +11538 0.0 +11539 0.0 +11540 0.0 +11541 0.0 +11542 0.0 +11543 0.0 +11544 0.0 +11545 0.0 +11546 0.0 +11547 0.0 +11548 0.0 +11549 0.0 +11550 0.0 +11551 0.0 +11552 0.0 +11553 0.0 +11554 0.0 +11555 0.0 +11556 0.0 +11557 0.0 +11558 0.0 +11559 0.0 +11560 0.0 +11561 0.0 +11562 0.0 +11563 0.0 +11564 0.0 +11565 0.0 +11566 0.0 +11567 0.0 +11568 0.0 +11569 0.0 +11570 0.0 +11571 0.0 +11572 0.0 +11573 0.0 +11574 0.0 +11575 0.0 +11576 0.0 +11577 0.0 +11578 0.0 +11579 0.0 +11580 0.0 +11581 0.0 +11582 0.0 +11583 0.0 +11584 0.0 +11585 0.0 +11586 0.0 +11587 0.0 +11588 0.0 +11589 0.0 +11590 0.0 +11591 0.0 +11592 0.0 +11593 0.0 +11594 0.0 +11595 0.0 +11596 0.0 +11597 0.0 +11598 0.0 +11599 0.0 +11600 0.0 +11601 0.0 +11602 0.0 +11603 0.0 +11604 0.0 +11605 0.0 +11606 0.0 +11607 0.0 +11608 0.0 +11609 0.0 +11610 0.0 +11611 0.0 +11612 0.0 +11613 0.0 +11614 0.0 +11615 0.0 +11616 0.0 +11617 0.0 +11618 0.0 +11619 0.0 +11620 0.0 +11621 0.0 +11622 0.0 +11623 0.0 +11624 0.0 +11625 0.0 +11626 0.0 +11627 0.0 +11628 0.0 +11629 0.0 +11630 0.0 +11631 0.0 +11632 0.0 +11633 0.0 +11634 0.0 +11635 0.0 +11636 0.0 +11637 0.0 +11638 0.0 +11639 0.0 +11640 0.0 +11641 0.0 +11642 0.0 +11643 0.0 +11644 0.0 +11645 0.0 +11646 0.0 +11647 0.0 +11648 0.0 +11649 0.0 +11650 0.0 +11651 0.0 +11652 0.0 +11653 0.0 +11654 0.0 +11655 0.0 +11656 0.0 +11657 0.0 +11658 0.0 +11659 0.0 +11660 0.0 +11661 0.0 +11662 0.0 +11663 0.0 +11664 0.0 +11665 0.0 +11666 0.0 +11667 0.0 +11668 0.0 +11669 0.0 +11670 0.0 +11671 0.0 +11672 0.0 +11673 0.0 +11674 0.0 +11675 0.0 +11676 0.0 +11677 0.0 +11678 0.0 +11679 0.0 +11680 0.0 +11681 0.0 +11682 0.0 +11683 0.0 +11684 0.0 +11685 0.0 +11686 0.0 +11687 0.0 +11688 0.0 +11689 0.0 +11690 0.0 +11691 0.0 +11692 0.0 +11693 0.0 +11694 0.0 +11695 0.0 +11696 0.0 +11697 0.0 +11698 0.0 +11699 0.0 +11700 0.0 +11701 0.0 +11702 0.0 +11703 0.0 +11704 0.0 +11705 0.0 +11706 0.0 +11707 0.0 +11708 0.0 +11709 0.0 +11710 0.0 +11711 0.0 +11712 0.0 +11713 0.0 +11714 0.0 +11715 0.0 +11716 0.0 +11717 0.0 +11718 0.0 +11719 0.0 +11720 0.0 +11721 0.0 +11722 0.0 +11723 0.0 +11724 0.0 +11725 0.0 +11726 0.0 +11727 0.0 +11728 0.0 +11729 0.0 +11730 0.0 +11731 0.0 +11732 0.0 +11733 0.0 +11734 0.0 +11735 0.0 +11736 0.0 +11737 0.0 +11738 0.0 +11739 0.0 +11740 0.0 +11741 0.0 +11742 0.0 +11743 0.0 +11744 0.0 +11745 0.0 +11746 0.0 +11747 0.0 +11748 0.0 +11749 0.0 +11750 0.0 +11751 0.0 +11752 0.0 +11753 0.0 +11754 0.0 +11755 0.0 +11756 0.0 +11757 0.0 +11758 0.0 +11759 0.0 +11760 0.0 +11761 0.0 +11762 0.0 +11763 0.0 +11764 0.0 +11765 0.0 +11766 0.0 +11767 0.0 +11768 0.0 +11769 0.0 +11770 0.0 +11771 0.0 +11772 0.0 +11773 0.0 +11774 0.0 +11775 0.0 +11776 0.0 +11777 0.0 +11778 0.0 +11779 0.0 +11780 0.0 +11781 0.0 +11782 0.0 +11783 0.0 +11784 0.0 +11785 0.0 +11786 0.0 +11787 0.0 +11788 0.0 +11789 0.0 +11790 0.0 +11791 0.0 +11792 0.0 +11793 0.0 +11794 0.0 +11795 0.0 +11796 0.0 +11797 0.0 +11798 0.0 +11799 0.0 +11800 0.0 +11801 0.0 +11802 0.0 +11803 0.0 +11804 0.0 +11805 0.0 +11806 0.0 +11807 0.0 +11808 0.0 +11809 0.0 +11810 0.0 +11811 0.0 +11812 0.0 +11813 0.0 +11814 0.0 +11815 0.0 +11816 0.0 +11817 0.0 +11818 0.0 +11819 0.0 +11820 0.0 +11821 0.0 +11822 0.0 +11823 0.0 +11824 0.0 +11825 0.0 +11826 0.0 +11827 0.0 +11828 0.0 +11829 0.0 +11830 0.0 +11831 0.0 +11832 0.0 +11833 0.0 +11834 0.0 +11835 0.0 +11836 0.0 +11837 0.0 +11838 0.0 +11839 0.0 +11840 0.0 +11841 0.0 +11842 0.0 +11843 0.0 +11844 0.0 +11845 0.0 +11846 0.0 +11847 0.0 +11848 0.0 +11849 0.0 +11850 0.0 +11851 0.0 +11852 0.0 +11853 0.0 +11854 0.0 +11855 0.0 +11856 0.0 +11857 0.0 +11858 0.0 +11859 0.0 +11860 0.0 +11861 0.0 +11862 0.0 +11863 0.0 +11864 0.0 +11865 0.0 +11866 0.0 +11867 0.0 +11868 0.0 +11869 0.0 +11870 0.0 +11871 0.0 +11872 0.0 +11873 0.0 +11874 0.0 +11875 0.0 +11876 0.0 +11877 0.0 +11878 0.0 +11879 0.0 +11880 0.0 +11881 0.0 +11882 0.0 +11883 0.0 +11884 0.0 +11885 0.0 +11886 0.0 +11887 0.0 +11888 0.0 +11889 0.0 +11890 0.0 +11891 0.0 +11892 0.0 +11893 0.0 +11894 0.0 +11895 0.0 +11896 0.0 +11897 0.0 +11898 0.0 +11899 0.0 +11900 0.0 +11901 0.0 +11902 0.0 +11903 0.0 +11904 0.0 +11905 0.0 +11906 0.0 +11907 0.0 +11908 0.0 +11909 0.0 +11910 0.0 +11911 0.0 +11912 0.0 +11913 0.0 +11914 0.0 +11915 0.0 +11916 0.0 +11917 0.0 +11918 0.0 +11919 0.0 +11920 0.0 +11921 0.0 +11922 0.0 +11923 0.0 +11924 0.0 +11925 0.0 +11926 0.0 +11927 0.0 +11928 0.0 +11929 0.0 +11930 0.0 +11931 0.0 +11932 0.0 +11933 0.0 +11934 0.0 +11935 0.0 +11936 0.0 +11937 0.0 +11938 0.0 +11939 0.0 +11940 0.0 +11941 0.0 +11942 0.0 +11943 0.0 +11944 0.0 +11945 0.0 +11946 0.0 +11947 0.0 +11948 0.0 +11949 0.0 +11950 0.0 +11951 0.0 +11952 0.0 +11953 0.0 +11954 0.0 +11955 0.0 +11956 0.0 +11957 0.0 +11958 0.0 +11959 0.0 +11960 0.0 +11961 0.0 +11962 0.0 +11963 0.0 +11964 0.0 +11965 0.0 +11966 0.0 +11967 0.0 +11968 0.0 +11969 0.0 +11970 0.0 +11971 0.0 +11972 0.0 +11973 0.0 +11974 0.0 +11975 0.0 +11976 0.0 +11977 0.0 +11978 0.0 +11979 0.0 +11980 0.0 +11981 0.0 +11982 0.0 +11983 0.0 +11984 0.0 +11985 0.0 +11986 0.0 +11987 0.0 +11988 0.0 +11989 0.0 +11990 0.0 +11991 0.0 +11992 0.0 +11993 0.0 +11994 0.0 +11995 0.0 +11996 0.0 +11997 0.0 +11998 0.0 +11999 0.0 +12000 0.0 +12001 0.0 +12002 0.0 +12003 0.0 +12004 0.0 +12005 0.0 +12006 0.0 +12007 0.0 +12008 0.0 +12009 0.0 +12010 0.0 +12011 0.0 +12012 0.0 +12013 0.0 +12014 0.0 +12015 0.0 +12016 0.0 +12017 0.0 +12018 0.0 +12019 0.0 +12020 0.0 +12021 0.0 +12022 0.0 +12023 0.0 +12024 0.0 +12025 0.0 +12026 0.0 +12027 0.0 +12028 0.0 +12029 0.0 +12030 0.0 +12031 0.0 +12032 0.0 +12033 0.0 +12034 0.0 +12035 0.0 +12036 0.0 +12037 0.0 +12038 0.0 +12039 0.0 +12040 0.0 +12041 0.0 +12042 0.0 +12043 0.0 +12044 0.0 +12045 0.0 +12046 0.0 +12047 0.0 +12048 0.0 +12049 0.0 +12050 0.0 +12051 0.0 +12052 0.0 +12053 0.0 +12054 0.0 +12055 0.0 +12056 0.0 +12057 0.0 +12058 0.0 +12059 0.0 +12060 0.0 +12061 0.0 +12062 0.0 +12063 0.0 +12064 0.0 +12065 0.0 +12066 0.0 +12067 0.0 +12068 0.0 +12069 0.0 +12070 0.0 +12071 0.0 +12072 0.0 +12073 0.0 +12074 0.0 +12075 0.0 +12076 0.0 +12077 0.0 +12078 0.0 +12079 0.0 +12080 0.0 +12081 0.0 +12082 0.0 +12083 0.0 +12084 0.0 +12085 0.0 +12086 0.0 +12087 0.0 +12088 0.0 +12089 0.0 +12090 0.0 +12091 0.0 +12092 0.0 +12093 0.0 +12094 0.0 +12095 0.0 +12096 0.0 +12097 0.0 +12098 0.0 +12099 0.0 +12100 0.0 +12101 0.0 +12102 0.0 +12103 0.0 +12104 0.0 +12105 0.0 +12106 0.0 +12107 0.0 +12108 0.0 +12109 0.0 +12110 0.0 +12111 0.0 +12112 0.0 +12113 0.0 +12114 0.0 +12115 0.0 +12116 0.0 +12117 0.0 +12118 0.0 +12119 0.0 +12120 0.0 +12121 0.0 +12122 0.0 +12123 0.0 +12124 0.0 +12125 0.0 +12126 0.0 +12127 0.0 +12128 0.0 +12129 0.0 +12130 0.0 +12131 0.0 +12132 0.0 +12133 0.0 +12134 0.0 +12135 0.0 +12136 0.0 +12137 0.0 +12138 0.0 +12139 0.0 +12140 0.0 +12141 0.0 +12142 0.0 +12143 0.0 +12144 0.0 +12145 0.0 +12146 0.0 +12147 0.0 +12148 0.0 +12149 0.0 +12150 0.0 +12151 0.0 +12152 0.0 +12153 0.0 +12154 0.0 +12155 0.0 +12156 0.0 +12157 0.0 +12158 0.0 +12159 0.0 +12160 0.0 +12161 0.0 +12162 0.0 +12163 0.0 +12164 0.0 +12165 0.0 +12166 0.0 +12167 0.0 +12168 0.0 +12169 0.0 +12170 0.0 +12171 0.0 +12172 0.0 +12173 0.0 +12174 0.0 +12175 0.0 +12176 0.0 +12177 0.0 +12178 0.0 +12179 0.0 +12180 0.0 +12181 0.0 +12182 0.0 +12183 0.0 +12184 0.0 +12185 0.0 +12186 0.0 +12187 0.0 +12188 0.0 +12189 0.0 +12190 0.0 +12191 0.0 +12192 0.0 +12193 0.0 +12194 0.0 +12195 0.0 +12196 0.0 +12197 0.0 +12198 0.0 +12199 0.0 +12200 0.0 +12201 0.0 +12202 0.0 +12203 0.0 +12204 0.0 +12205 0.0 +12206 0.0 +12207 0.0 +12208 0.0 +12209 0.0 +12210 0.0 +12211 0.0 +12212 0.0 +12213 0.0 +12214 0.0 +12215 0.0 +12216 0.0 +12217 0.0 +12218 0.0 +12219 0.0 +12220 0.0 +12221 0.0 +12222 0.0 +12223 0.0 +12224 0.0 +12225 0.0 +12226 0.0 +12227 0.0 +12228 0.0 +12229 0.0 +12230 0.0 +12231 0.0 +12232 0.0 +12233 0.0 +12234 0.0 +12235 0.0 +12236 0.0 +12237 0.0 +12238 0.0 +12239 0.0 +12240 0.0 +12241 0.0 +12242 0.0 +12243 0.0 +12244 0.0 +12245 0.0 +12246 0.0 +12247 0.0 +12248 0.0 +12249 0.0 +12250 0.0 +12251 0.0 +12252 0.0 +12253 0.0 +12254 0.0 +12255 0.0 +12256 0.0 +12257 0.0 +12258 0.0 +12259 0.0 +12260 0.0 +12261 0.0 +12262 0.0 +12263 0.0 +12264 0.0 +12265 0.0 +12266 0.0 +12267 0.0 +12268 0.0 +12269 0.0 +12270 0.0 +12271 0.0 +12272 0.0 +12273 0.0 +12274 0.0 +12275 0.0 +12276 0.0 +12277 0.0 +12278 0.0 +12279 0.0 +12280 0.0 +12281 0.0 +12282 0.0 +12283 0.0 +12284 0.0 +12285 0.0 +12286 0.0 +12287 0.0 +12288 0.0 +12289 0.0 +12290 0.0 +12291 0.0 +12292 0.0 +12293 0.0 +12294 0.0 +12295 0.0 +12296 0.0 +12297 0.0 +12298 0.0 +12299 0.0 +12300 0.0 +12301 0.0 +12302 0.0 +12303 0.0 +12304 0.0 +12305 0.0 +12306 0.0 +12307 0.0 +12308 0.0 +12309 0.0 +12310 0.0 +12311 0.0 +12312 0.0 +12313 0.0 +12314 0.0 +12315 0.0 +12316 0.0 +12317 0.0 +12318 0.0 +12319 0.0 +12320 0.0 +12321 0.0 +12322 0.0 +12323 0.0 +12324 0.0 +12325 0.0 +12326 0.0 +12327 0.0 +12328 0.0 +12329 0.0 +12330 0.0 +12331 0.0 +12332 0.0 +12333 0.0 +12334 0.0 +12335 0.0 +12336 0.0 +12337 0.0 +12338 0.0 +12339 0.0 +12340 0.0 +12341 0.0 +12342 0.0 +12343 0.0 +12344 0.0 +12345 0.0 +12346 0.0 +12347 0.0 +12348 0.0 +12349 0.0 +12350 0.0 +12351 0.0 +12352 0.0 +12353 0.0 +12354 0.0 +12355 0.0 +12356 0.0 +12357 0.0 +12358 0.0 +12359 0.0 +12360 0.0 +12361 0.0 +12362 0.0 +12363 0.0 +12364 0.0 +12365 0.0 +12366 0.0 +12367 0.0 +12368 0.0 +12369 0.0 +12370 0.0 +12371 0.0 +12372 0.0 +12373 0.0 +12374 0.0 +12375 0.0 +12376 0.0 +12377 0.0 +12378 0.0 +12379 0.0 +12380 0.0 +12381 0.0 +12382 0.0 +12383 0.0 +12384 0.0 +12385 0.0 +12386 0.0 +12387 0.0 +12388 0.0 +12389 0.0 +12390 0.0 +12391 0.0 +12392 0.0 +12393 0.0 +12394 0.0 +12395 0.0 +12396 0.0 +12397 0.0 +12398 0.0 +12399 0.0 +12400 0.0 +12401 0.0 +12402 0.0 +12403 0.0 +12404 0.0 +12405 0.0 +12406 0.0 +12407 0.0 +12408 0.0 +12409 0.0 +12410 0.0 +12411 0.0 +12412 0.0 +12413 0.0 +12414 0.0 +12415 0.0 +12416 0.0 +12417 0.0 +12418 0.0 +12419 0.0 +12420 0.0 +12421 0.0 +12422 0.0 +12423 0.0 +12424 0.0 +12425 0.0 +12426 0.0 +12427 0.0 +12428 0.0 +12429 0.0 +12430 0.0 +12431 0.0 +12432 0.0 +12433 0.0 +12434 0.0 +12435 0.0 +12436 0.0 +12437 0.0 +12438 0.0 +12439 0.0 +12440 0.0 +12441 0.0 +12442 0.0 +12443 0.0 +12444 0.0 +12445 0.0 +12446 0.0 +12447 0.0 +12448 0.0 +12449 0.0 +12450 0.0 +12451 0.0 +12452 0.0 +12453 0.0 +12454 0.0 +12455 0.0 +12456 0.0 +12457 0.0 +12458 0.0 +12459 0.0 +12460 0.0 +12461 0.0 +12462 0.0 +12463 0.0 +12464 0.0 +12465 0.0 +12466 0.0 +12467 0.0 +12468 0.0 +12469 0.0 +12470 0.0 +12471 0.0 +12472 0.0 +12473 0.0 +12474 0.0 +12475 0.0 +12476 0.0 +12477 0.0 +12478 0.0 +12479 0.0 +12480 0.0 +12481 0.0 +12482 0.0 +12483 0.0 +12484 0.0 +12485 0.0 +12486 0.0 +12487 0.0 +12488 0.0 +12489 0.0 +12490 0.0 +12491 0.0 +12492 0.0 +12493 0.0 +12494 0.0 +12495 0.0 +12496 0.0 +12497 0.0 +12498 0.0 +12499 0.0 +12500 0.0 +12501 0.0 +12502 0.0 +12503 0.0 +12504 0.0 +12505 0.0 +12506 0.0 +12507 0.0 +12508 0.0 +12509 0.0 +12510 0.0 +12511 0.0 +12512 0.0 +12513 0.0 +12514 0.0 +12515 0.0 +12516 0.0 +12517 0.0 +12518 0.0 +12519 0.0 +12520 0.0 +12521 0.0 +12522 0.0 +12523 0.0 +12524 0.0 +12525 0.0 +12526 0.0 +12527 0.0 +12528 0.0 +12529 0.0 +12530 0.0 +12531 0.0 +12532 0.0 +12533 0.0 +12534 0.0 +12535 0.0 +12536 0.0 +12537 0.0 +12538 0.0 +12539 0.0 +12540 0.0 +12541 0.0 +12542 0.0 +12543 0.0 +12544 0.0 +12545 0.0 +12546 0.0 +12547 0.0 +12548 0.0 +12549 0.0 +12550 0.0 +12551 0.0 +12552 0.0 +12553 0.0 +12554 0.0 +12555 0.0 +12556 0.0 +12557 0.0 +12558 0.0 +12559 0.0 +12560 0.0 +12561 0.0 +12562 0.0 +12563 0.0 +12564 0.0 +12565 0.0 +12566 0.0 +12567 0.0 +12568 0.0 +12569 0.0 +12570 0.0 +12571 0.0 +12572 0.0 +12573 0.0 +12574 0.0 +12575 0.0 +12576 0.0 +12577 0.0 +12578 0.0 +12579 0.0 +12580 0.0 +12581 0.0 +12582 0.0 +12583 0.0 +12584 0.0 +12585 0.0 +12586 0.0 +12587 0.0 +12588 0.0 +12589 0.0 +12590 0.0 +12591 0.0 +12592 0.0 +12593 0.0 +12594 0.0 +12595 0.0 +12596 0.0 +12597 0.0 +12598 0.0 +12599 0.0 +12600 0.0 +12601 0.0 +12602 0.0 +12603 0.0 +12604 0.0 +12605 0.0 +12606 0.0 +12607 0.0 +12608 0.0 +12609 0.0 +12610 0.0 +12611 0.0 +12612 0.0 +12613 0.0 +12614 0.0 +12615 0.0 +12616 0.0 +12617 0.0 +12618 0.0 +12619 0.0 +12620 0.0 +12621 0.0 +12622 0.0 +12623 0.0 +12624 0.0 +12625 0.0 +12626 0.0 +12627 0.0 +12628 0.0 +12629 0.0 +12630 0.0 +12631 0.0 +12632 0.0 +12633 0.0 +12634 0.0 +12635 0.0 +12636 0.0 +12637 0.0 +12638 0.0 +12639 0.0 +12640 0.0 +12641 0.0 +12642 0.0 +12643 0.0 +12644 0.0 +12645 0.0 +12646 0.0 +12647 0.0 +12648 0.0 +12649 0.0 +12650 0.0 +12651 0.0 +12652 0.0 +12653 0.0 +12654 0.0 +12655 0.0 +12656 0.0 +12657 0.0 +12658 0.0 +12659 0.0 +12660 0.0 +12661 0.0 +12662 0.0 +12663 0.0 +12664 0.0 +12665 0.0 +12666 0.0 +12667 0.0 +12668 0.0 +12669 0.0 +12670 0.0 +12671 0.0 +12672 0.0 +12673 0.0 +12674 0.0 +12675 0.0 +12676 0.0 +12677 0.0 +12678 0.0 +12679 0.0 +12680 0.0 +12681 0.0 +12682 0.0 +12683 0.0 +12684 0.0 +12685 0.0 +12686 0.0 +12687 0.0 +12688 0.0 +12689 0.0 +12690 0.0 +12691 0.0 +12692 0.0 +12693 0.0 +12694 0.0 +12695 0.0 +12696 0.0 +12697 0.0 +12698 0.0 +12699 0.0 +12700 0.0 +12701 0.0 +12702 0.0 +12703 0.0 +12704 0.0 +12705 0.0 +12706 0.0 +12707 0.0 +12708 0.0 +12709 0.0 +12710 0.0 +12711 0.0 +12712 0.0 +12713 0.0 +12714 0.0 +12715 0.0 +12716 0.0 +12717 0.0 +12718 0.0 +12719 0.0 +12720 0.0 +12721 0.0 +12722 0.0 +12723 0.0 +12724 0.0 +12725 0.0 +12726 0.0 +12727 0.0 +12728 0.0 +12729 0.0 +12730 0.0 +12731 0.0 +12732 0.0 +12733 0.0 +12734 0.0 +12735 0.0 +12736 0.0 +12737 0.0 +12738 0.0 +12739 0.0 +12740 0.0 +12741 0.0 +12742 0.0 +12743 0.0 +12744 0.0 +12745 0.0 +12746 0.0 +12747 0.0 +12748 0.0 +12749 0.0 +12750 0.0 +12751 0.0 +12752 0.0 +12753 0.0 +12754 0.0 +12755 0.0 +12756 0.0 +12757 0.0 +12758 0.0 +12759 0.0 +12760 0.0 +12761 0.0 +12762 0.0 +12763 0.0 +12764 0.0 +12765 0.0 +12766 0.0 +12767 0.0 +12768 0.0 +12769 0.0 +12770 0.0 +12771 0.0 +12772 0.0 +12773 0.0 +12774 0.0 +12775 0.0 +12776 0.0 +12777 0.0 +12778 0.0 +12779 0.0 +12780 0.0 +12781 0.0 +12782 0.0 +12783 0.0 +12784 0.0 +12785 0.0 +12786 0.0 +12787 0.0 +12788 0.0 +12789 0.0 +12790 0.0 +12791 0.0 +12792 0.0 +12793 0.0 +12794 0.0 +12795 0.0 +12796 0.0 +12797 0.0 +12798 0.0 +12799 0.0 +12800 0.0 +12801 0.0 +12802 0.0 +12803 0.0 +12804 0.0 +12805 0.0 +12806 0.0 +12807 0.0 +12808 0.0 +12809 0.0 +12810 0.0 +12811 0.0 +12812 0.0 +12813 0.0 +12814 0.0 +12815 0.0 +12816 0.0 +12817 0.0 +12818 0.0 +12819 0.0 +12820 0.0 +12821 0.0 +12822 0.0 +12823 0.0 +12824 0.0 +12825 0.0 +12826 0.0 +12827 0.0 +12828 0.0 +12829 0.0 +12830 0.0 +12831 0.0 +12832 0.0 +12833 0.0 +12834 0.0 +12835 0.0 +12836 0.0 +12837 0.0 +12838 0.0 +12839 0.0 +12840 0.0 +12841 0.0 +12842 0.0 +12843 0.0 +12844 0.0 +12845 0.0 +12846 0.0 +12847 0.0 +12848 0.0 +12849 0.0 +12850 0.0 +12851 0.0 +12852 0.0 +12853 0.0 +12854 0.0 +12855 0.0 +12856 0.0 +12857 0.0 +12858 0.0 +12859 0.0 +12860 0.0 +12861 0.0 +12862 0.0 +12863 0.0 +12864 0.0 +12865 0.0 +12866 0.0 +12867 0.0 +12868 0.0 +12869 0.0 +12870 0.0 +12871 0.0 +12872 0.0 +12873 0.0 +12874 0.0 +12875 0.0 +12876 0.0 +12877 0.0 +12878 0.0 +12879 0.0 +12880 0.0 +12881 0.0 +12882 0.0 +12883 0.0 +12884 0.0 +12885 0.0 +12886 0.0 +12887 0.0 +12888 0.0 +12889 0.0 +12890 0.0 +12891 0.0 +12892 0.0 +12893 0.0 +12894 0.0 +12895 0.0 +12896 0.0 +12897 0.0 +12898 0.0 +12899 0.0 +12900 0.0 +12901 0.0 +12902 0.0 +12903 0.0 +12904 0.0 +12905 0.0 +12906 0.0 +12907 0.0 +12908 0.0 +12909 0.0 +12910 0.0 +12911 0.0 +12912 0.0 +12913 0.0 +12914 0.0 +12915 0.0 +12916 0.0 +12917 0.0 +12918 0.0 +12919 0.0 +12920 0.0 +12921 0.0 +12922 0.0 +12923 0.0 +12924 0.0 +12925 0.0 +12926 0.0 +12927 0.0 +12928 0.0 +12929 0.0 +12930 0.0 +12931 0.0 +12932 0.0 +12933 0.0 +12934 0.0 +12935 0.0 +12936 0.0 +12937 0.0 +12938 0.0 +12939 0.0 +12940 0.0 +12941 0.0 +12942 0.0 +12943 0.0 +12944 0.0 +12945 0.0 +12946 0.0 +12947 0.0 +12948 0.0 +12949 0.0 +12950 0.0 +12951 0.0 +12952 0.0 +12953 0.0 +12954 0.0 +12955 0.0 +12956 0.0 +12957 0.0 +12958 0.0 +12959 0.0 +12960 0.0 +12961 0.0 +12962 0.0 +12963 0.0 +12964 0.0 +12965 0.0 +12966 0.0 +12967 0.0 +12968 0.0 +12969 0.0 +12970 0.0 +12971 0.0 +12972 0.0 +12973 0.0 +12974 0.0 +12975 0.0 +12976 0.0 +12977 0.0 +12978 0.0 +12979 0.0 +12980 0.0 +12981 0.0 +12982 0.0 +12983 0.0 +12984 0.0 +12985 0.0 +12986 0.0 +12987 0.0 +12988 0.0 +12989 0.0 +12990 0.0 +12991 0.0 +12992 0.0 +12993 0.0 +12994 0.0 +12995 0.0 +12996 0.0 +12997 0.0 +12998 0.0 +12999 0.0 +13000 0.0 +13001 0.0 +13002 0.0 +13003 0.0 +13004 0.0 +13005 0.0 +13006 0.0 +13007 0.0 +13008 0.0 +13009 0.0 +13010 0.0 +13011 0.0 +13012 0.0 +13013 0.0 +13014 0.0 +13015 0.0 +13016 0.0 +13017 0.0 +13018 0.0 +13019 0.0 +13020 0.0 +13021 0.0 +13022 0.0 +13023 0.0 +13024 0.0 +13025 0.0 +13026 0.0 +13027 0.0 +13028 0.0 +13029 0.0 +13030 0.0 +13031 0.0 +13032 0.0 +13033 0.0 +13034 0.0 +13035 0.0 +13036 0.0 +13037 0.0 +13038 0.0 +13039 0.0 +13040 0.0 +13041 0.0 +13042 0.0 +13043 0.0 +13044 0.0 +13045 0.0 +13046 0.0 +13047 0.0 +13048 0.0 +13049 0.0 +13050 0.0 +13051 0.0 +13052 0.0 +13053 0.0 +13054 0.0 +13055 0.0 +13056 0.0 +13057 0.0 +13058 0.0 +13059 0.0 +13060 0.0 +13061 0.0 +13062 0.0 +13063 0.0 +13064 0.0 +13065 0.0 +13066 0.0 +13067 0.0 +13068 0.0 +13069 0.0 +13070 0.0 +13071 0.0 +13072 0.0 +13073 0.0 +13074 0.0 +13075 0.0 +13076 0.0 +13077 0.0 +13078 0.0 +13079 0.0 +13080 0.0 +13081 0.0 +13082 0.0 +13083 0.0 +13084 0.0 +13085 0.0 +13086 0.0 +13087 0.0 +13088 0.0 +13089 0.0 +13090 0.0 +13091 0.0 +13092 0.0 +13093 0.0 +13094 0.0 +13095 0.0 +13096 0.0 +13097 0.0 +13098 0.0 +13099 0.0 +13100 0.0 +13101 0.0 +13102 0.0 +13103 0.0 +13104 0.0 +13105 0.0 +13106 0.0 +13107 0.0 +13108 0.0 +13109 0.0 +13110 0.0 +13111 0.0 +13112 0.0 +13113 0.0 +13114 0.0 +13115 0.0 +13116 0.0 +13117 0.0 +13118 0.0 +13119 0.0 +13120 0.0 +13121 0.0 +13122 0.0 +13123 0.0 +13124 0.0 +13125 0.0 +13126 0.0 +13127 0.0 +13128 0.0 +13129 0.0 +13130 0.0 +13131 0.0 +13132 0.0 +13133 0.0 +13134 0.0 +13135 0.0 +13136 0.0 +13137 0.0 +13138 0.0 +13139 0.0 +13140 0.0 +13141 0.0 +13142 0.0 +13143 0.0 +13144 0.0 +13145 0.0 +13146 0.0 +13147 0.0 +13148 0.0 +13149 0.0 +13150 0.0 +13151 0.0 +13152 0.0 +13153 0.0 +13154 0.0 +13155 0.0 +13156 0.0 +13157 0.0 +13158 0.0 +13159 0.0 +13160 0.0 +13161 0.0 +13162 0.0 +13163 0.0 +13164 0.0 +13165 0.0 +13166 0.0 +13167 0.0 +13168 0.0 +13169 0.0 +13170 0.0 +13171 0.0 +13172 0.0 +13173 0.0 +13174 0.0 +13175 0.0 +13176 0.0 +13177 0.0 +13178 0.0 +13179 0.0 +13180 0.0 +13181 0.0 +13182 0.0 +13183 0.0 +13184 0.0 +13185 0.0 +13186 0.0 +13187 0.0 +13188 0.0 +13189 0.0 +13190 0.0 +13191 0.0 +13192 0.0 +13193 0.0 +13194 0.0 +13195 0.0 +13196 0.0 +13197 0.0 +13198 0.0 +13199 0.0 +13200 0.0 +13201 0.0 +13202 0.0 +13203 0.0 +13204 0.0 +13205 0.0 +13206 0.0 +13207 0.0 +13208 0.0 +13209 0.0 +13210 0.0 +13211 0.0 +13212 0.0 +13213 0.0 +13214 0.0 +13215 0.0 +13216 0.0 +13217 0.0 +13218 0.0 +13219 0.0 +13220 0.0 +13221 0.0 +13222 0.0 +13223 0.0 +13224 0.0 +13225 0.0 +13226 0.0 +13227 0.0 +13228 0.0 +13229 0.0 +13230 0.0 +13231 0.0 +13232 0.0 +13233 0.0 +13234 0.0 +13235 0.0 +13236 0.0 +13237 0.0 +13238 0.0 +13239 0.0 +13240 0.0 +13241 0.0 +13242 0.0 +13243 0.0 +13244 0.0 +13245 0.0 +13246 0.0 +13247 0.0 +13248 0.0 +13249 0.0 +13250 0.0 +13251 0.0 +13252 0.0 +13253 0.0 +13254 0.0 +13255 0.0 +13256 0.0 +13257 0.0 +13258 0.0 +13259 0.0 +13260 0.0 +13261 0.0 +13262 0.0 +13263 0.0 +13264 0.0 +13265 0.0 +13266 0.0 +13267 0.0 +13268 0.0 +13269 0.0 +13270 0.0 +13271 0.0 +13272 0.0 +13273 0.0 +13274 0.0 +13275 0.0 +13276 0.0 +13277 0.0 +13278 0.0 +13279 0.0 +13280 0.0 +13281 0.0 +13282 0.0 +13283 0.0 +13284 0.0 +13285 0.0 +13286 0.0 +13287 0.0 +13288 0.0 +13289 0.0 +13290 0.0 +13291 0.0 +13292 0.0 +13293 0.0 +13294 0.0 +13295 0.0 +13296 0.0 +13297 0.0 +13298 0.0 +13299 0.0 +13300 0.0 +13301 0.0 +13302 0.0 +13303 0.0 +13304 0.0 +13305 0.0 +13306 0.0 +13307 0.0 +13308 0.0 +13309 0.0 +13310 0.0 +13311 0.0 +13312 0.0 +13313 0.0 +13314 0.0 +13315 0.0 +13316 0.0 +13317 0.0 +13318 0.0 +13319 0.0 +13320 0.0 +13321 0.0 +13322 0.0 +13323 0.0 +13324 0.0 +13325 0.0 +13326 0.0 +13327 0.0 +13328 0.0 +13329 0.0 +13330 0.0 +13331 0.0 +13332 0.0 +13333 0.0 +13334 0.0 +13335 0.0 +13336 0.0 +13337 0.0 +13338 0.0 +13339 0.0 +13340 0.0 +13341 0.0 +13342 0.0 +13343 0.0 +13344 0.0 +13345 0.0 +13346 0.0 +13347 0.0 +13348 0.0 +13349 0.0 +13350 0.0 +13351 0.0 +13352 0.0 +13353 0.0 +13354 0.0 +13355 0.0 +13356 0.0 +13357 0.0 +13358 0.0 +13359 0.0 +13360 0.0 +13361 0.0 +13362 0.0 +13363 0.0 +13364 0.0 +13365 0.0 +13366 0.0 +13367 0.0 +13368 0.0 +13369 0.0 +13370 0.0 +13371 0.0 +13372 0.0 +13373 0.0 +13374 0.0 +13375 0.0 +13376 0.0 +13377 0.0 +13378 0.0 +13379 0.0 +13380 0.0 +13381 0.0 +13382 0.0 +13383 0.0 +13384 0.0 +13385 0.0 +13386 0.0 +13387 0.0 +13388 0.0 +13389 0.0 +13390 0.0 +13391 0.0 +13392 0.0 +13393 0.0 +13394 0.0 +13395 0.0 +13396 0.0 +13397 0.0 +13398 0.0 +13399 0.0 +13400 0.0 +13401 0.0 +13402 0.0 +13403 0.0 +13404 0.0 +13405 0.0 +13406 0.0 +13407 0.0 +13408 0.0 +13409 0.0 +13410 0.0 +13411 0.0 +13412 0.0 +13413 0.0 +13414 0.0 +13415 0.0 +13416 0.0 +13417 0.0 +13418 0.0 +13419 0.0 +13420 0.0 +13421 0.0 +13422 0.0 +13423 0.0 +13424 0.0 +13425 0.0 +13426 0.0 +13427 0.0 +13428 0.0 +13429 0.0 +13430 0.0 +13431 0.0 +13432 0.0 +13433 0.0 +13434 0.0 +13435 0.0 +13436 0.0 +13437 0.0 +13438 0.0 +13439 0.0 +13440 0.0 +13441 0.0 +13442 0.0 +13443 0.0 +13444 0.0 +13445 0.0 +13446 0.0 +13447 0.0 +13448 0.0 +13449 0.0 +13450 0.0 +13451 0.0 +13452 0.0 +13453 0.0 +13454 0.0 +13455 0.0 +13456 0.0 +13457 0.0 +13458 0.0 +13459 0.0 +13460 0.0 +13461 0.0 +13462 0.0 +13463 0.0 +13464 0.0 +13465 0.0 +13466 0.0 +13467 0.0 +13468 0.0 +13469 0.0 +13470 0.0 +13471 0.0 +13472 0.0 +13473 0.0 +13474 0.0 +13475 0.0 +13476 0.0 +13477 0.0 +13478 0.0 +13479 0.0 +13480 0.0 +13481 0.0 +13482 0.0 +13483 0.0 +13484 0.0 +13485 0.0 +13486 0.0 +13487 0.0 +13488 0.0 +13489 0.0 +13490 0.0 +13491 0.0 +13492 0.0 +13493 0.0 +13494 0.0 +13495 0.0 +13496 0.0 +13497 0.0 +13498 0.0 +13499 0.0 +13500 0.0 +13501 0.0 +13502 0.0 +13503 0.0 +13504 0.0 +13505 0.0 +13506 0.0 +13507 0.0 +13508 0.0 +13509 0.0 +13510 0.0 +13511 0.0 +13512 0.0 +13513 0.0 +13514 0.0 +13515 0.0 +13516 0.0 +13517 0.0 +13518 0.0 +13519 0.0 +13520 0.0 +13521 0.0 +13522 0.0 +13523 0.0 +13524 0.0 +13525 0.0 +13526 0.0 +13527 0.0 +13528 0.0 +13529 0.0 +13530 0.0 +13531 0.0 +13532 0.0 +13533 0.0 +13534 0.0 +13535 0.0 +13536 0.0 +13537 0.0 +13538 0.0 +13539 0.0 +13540 0.0 +13541 0.0 +13542 0.0 +13543 0.0 +13544 0.0 +13545 0.0 +13546 0.0 +13547 0.0 +13548 0.0 +13549 0.0 +13550 0.0 +13551 0.0 +13552 0.0 +13553 0.0 +13554 0.0 +13555 0.0 +13556 0.0 +13557 0.0 +13558 0.0 +13559 0.0 +13560 0.0 +13561 0.0 +13562 0.0 +13563 0.0 +13564 0.0 +13565 0.0 +13566 0.0 +13567 0.0 +13568 0.0 +13569 0.0 +13570 0.0 +13571 0.0 +13572 0.0 +13573 0.0 +13574 0.0 +13575 0.0 +13576 0.0 +13577 0.0 +13578 0.0 +13579 0.0 +13580 0.0 +13581 0.0 +13582 0.0 +13583 0.0 +13584 0.0 +13585 0.0 +13586 0.0 +13587 0.0 +13588 0.0 +13589 0.0 +13590 0.0 +13591 0.0 +13592 0.0 +13593 0.0 +13594 0.0 +13595 0.0 +13596 0.0 +13597 0.0 +13598 0.0 +13599 0.0 +13600 0.0 +13601 0.0 +13602 0.0 +13603 0.0 +13604 0.0 +13605 0.0 +13606 0.0 +13607 0.0 +13608 0.0 +13609 0.0 +13610 0.0 +13611 0.0 +13612 0.0 +13613 0.0 +13614 0.0 +13615 0.0 +13616 0.0 +13617 0.0 +13618 0.0 +13619 0.0 +13620 0.0 +13621 0.0 +13622 0.0 +13623 0.0 +13624 0.0 +13625 0.0 +13626 0.0 +13627 0.0 +13628 0.0 +13629 0.0 +13630 0.0 +13631 0.0 +13632 0.0 +13633 0.0 +13634 0.0 +13635 0.0 +13636 0.0 +13637 0.0 +13638 0.0 +13639 0.0 +13640 0.0 +13641 0.0 +13642 0.0 +13643 0.0 +13644 0.0 +13645 0.0 +13646 0.0 +13647 0.0 +13648 0.0 +13649 0.0 +13650 0.0 +13651 0.0 +13652 0.0 +13653 0.0 +13654 0.0 +13655 0.0 +13656 0.0 +13657 0.0 +13658 0.0 +13659 0.0 +13660 0.0 +13661 0.0 +13662 0.0 +13663 0.0 +13664 0.0 +13665 0.0 +13666 0.0 +13667 0.0 +13668 0.0 +13669 0.0 +13670 0.0 +13671 0.0 +13672 0.0 +13673 0.0 +13674 0.0 +13675 0.0 +13676 0.0 +13677 0.0 +13678 0.0 +13679 0.0 +13680 0.0 +13681 0.0 +13682 0.0 +13683 0.0 +13684 0.0 +13685 0.0 +13686 0.0 +13687 0.0 +13688 0.0 +13689 0.0 +13690 0.0 +13691 0.0 +13692 0.0 +13693 0.0 +13694 0.0 +13695 0.0 +13696 0.0 +13697 0.0 +13698 0.0 +13699 0.0 +13700 0.0 +13701 0.0 +13702 0.0 +13703 0.0 +13704 0.0 +13705 0.0 +13706 0.0 +13707 0.0 +13708 0.0 +13709 0.0 +13710 0.0 +13711 0.0 +13712 0.0 +13713 0.0 +13714 0.0 +13715 0.0 +13716 0.0 +13717 0.0 +13718 0.0 +13719 0.0 +13720 0.0 +13721 0.0 +13722 0.0 +13723 0.0 +13724 0.0 +13725 0.0 +13726 0.0 +13727 0.0 +13728 0.0 +13729 0.0 +13730 0.0 +13731 0.0 +13732 0.0 +13733 0.0 +13734 0.0 +13735 0.0 +13736 0.0 +13737 0.0 +13738 0.0 +13739 0.0 +13740 0.0 +13741 0.0 +13742 0.0 +13743 0.0 +13744 0.0 +13745 0.0 +13746 0.0 +13747 0.0 +13748 0.0 +13749 0.0 +13750 0.0 +13751 0.0 +13752 0.0 +13753 0.0 +13754 0.0 +13755 0.0 +13756 0.0 +13757 0.0 +13758 0.0 +13759 0.0 +13760 0.0 +13761 0.0 +13762 0.0 +13763 0.0 +13764 0.0 +13765 0.0 +13766 0.0 +13767 0.0 +13768 0.0 +13769 0.0 +13770 0.0 +13771 0.0 +13772 0.0 +13773 0.0 +13774 0.0 +13775 0.0 +13776 0.0 +13777 0.0 +13778 0.0 +13779 0.0 +13780 0.0 +13781 0.0 +13782 0.0 +13783 0.0 +13784 0.0 +13785 0.0 +13786 0.0 +13787 0.0 +13788 0.0 +13789 0.0 +13790 0.0 +13791 0.0 +13792 0.0 +13793 0.0 +13794 0.0 +13795 0.0 +13796 0.0 +13797 0.0 +13798 0.0 +13799 0.0 +13800 0.0 +13801 0.0 +13802 0.0 +13803 0.0 +13804 0.0 +13805 0.0 +13806 0.0 +13807 0.0 +13808 0.0 +13809 0.0 +13810 0.0 +13811 0.0 +13812 0.0 +13813 0.0 +13814 0.0 +13815 0.0 +13816 0.0 +13817 0.0 +13818 0.0 +13819 0.0 +13820 0.0 +13821 0.0 +13822 0.0 +13823 0.0 +13824 0.0 +13825 0.0 +13826 0.0 +13827 0.0 +13828 0.0 +13829 0.0 +13830 0.0 +13831 0.0 +13832 0.0 +13833 0.0 +13834 0.0 +13835 0.0 +13836 0.0 +13837 0.0 +13838 0.0 +13839 0.0 +13840 0.0 +13841 0.0 +13842 0.0 +13843 0.0 +13844 0.0 +13845 0.0 +13846 0.0 +13847 0.0 +13848 0.0 +13849 0.0 +13850 0.0 +13851 0.0 +13852 0.0 +13853 0.0 +13854 0.0 +13855 0.0 +13856 0.0 +13857 0.0 +13858 0.0 +13859 0.0 +13860 0.0 +13861 0.0 +13862 0.0 +13863 0.0 +13864 0.0 +13865 0.0 +13866 0.0 +13867 0.0 +13868 0.0 +13869 0.0 +13870 0.0 +13871 0.0 +13872 0.0 +13873 0.0 +13874 0.0 +13875 0.0 +13876 0.0 +13877 0.0 +13878 0.0 +13879 0.0 +13880 0.0 +13881 0.0 +13882 0.0 +13883 0.0 +13884 0.0 +13885 0.0 +13886 0.0 +13887 0.0 +13888 0.0 +13889 0.0 +13890 0.0 +13891 0.0 +13892 0.0 +13893 0.0 +13894 0.0 +13895 0.0 +13896 0.0 +13897 0.0 +13898 0.0 +13899 0.0 +13900 0.0 +13901 0.0 +13902 0.0 +13903 0.0 +13904 0.0 +13905 0.0 +13906 0.0 +13907 0.0 +13908 0.0 +13909 0.0 +13910 0.0 +13911 0.0 +13912 0.0 +13913 0.0 +13914 0.0 +13915 0.0 +13916 0.0 +13917 0.0 +13918 0.0 +13919 0.0 +13920 0.0 +13921 0.0 +13922 0.0 +13923 0.0 +13924 0.0 +13925 0.0 +13926 0.0 +13927 0.0 +13928 0.0 +13929 0.0 +13930 0.0 +13931 0.0 +13932 0.0 +13933 0.0 +13934 0.0 +13935 0.0 +13936 0.0 +13937 0.0 +13938 0.0 +13939 0.0 +13940 0.0 +13941 0.0 +13942 0.0 +13943 0.0 +13944 0.0 +13945 0.0 +13946 0.0 +13947 0.0 +13948 0.0 +13949 0.0 +13950 0.0 +13951 0.0 +13952 0.0 +13953 0.0 +13954 0.0 +13955 0.0 +13956 0.0 +13957 0.0 +13958 0.0 +13959 0.0 +13960 0.0 +13961 0.0 +13962 0.0 +13963 0.0 +13964 0.0 +13965 0.0 +13966 0.0 +13967 0.0 +13968 0.0 +13969 0.0 +13970 0.0 +13971 0.0 +13972 0.0 +13973 0.0 +13974 0.0 +13975 0.0 +13976 0.0 +13977 0.0 +13978 0.0 +13979 0.0 +13980 0.0 +13981 0.0 +13982 0.0 +13983 0.0 +13984 0.0 +13985 0.0 +13986 0.0 +13987 0.0 +13988 0.0 +13989 0.0 +13990 0.0 +13991 0.0 +13992 0.0 +13993 0.0 +13994 0.0 +13995 0.0 +13996 0.0 +13997 0.0 +13998 0.0 +13999 0.0 +14000 0.0 +14001 0.0 +14002 0.0 +14003 0.0 +14004 0.0 +14005 0.0 +14006 0.0 +14007 0.0 +14008 0.0 +14009 0.0 +14010 0.0 +14011 0.0 +14012 0.0 +14013 0.0 +14014 0.0 +14015 0.0 +14016 0.0 +14017 0.0 +14018 0.0 +14019 0.0 +14020 0.0 +14021 0.0 +14022 0.0 +14023 0.0 +14024 0.0 +14025 0.0 +14026 0.0 +14027 0.0 +14028 0.0 +14029 0.0 +14030 0.0 +14031 0.0 +14032 0.0 +14033 0.0 +14034 0.0 +14035 0.0 +14036 0.0 +14037 0.0 +14038 0.0 +14039 0.0 +14040 0.0 +14041 0.0 +14042 0.0 +14043 0.0 +14044 0.0 +14045 0.0 +14046 0.0 +14047 0.0 +14048 0.0 +14049 0.0 +14050 0.0 +14051 0.0 +14052 0.0 +14053 0.0 +14054 0.0 +14055 0.0 +14056 0.0 +14057 0.0 +14058 0.0 +14059 0.0 +14060 0.0 +14061 0.0 +14062 0.0 +14063 0.0 +14064 0.0 +14065 0.0 +14066 0.0 +14067 0.0 +14068 0.0 +14069 0.0 +14070 0.0 +14071 0.0 +14072 0.0 +14073 0.0 +14074 0.0 +14075 0.0 +14076 0.0 +14077 0.0 +14078 0.0 +14079 0.0 +14080 0.0 +14081 0.0 +14082 0.0 +14083 0.0 +14084 0.0 +14085 0.0 +14086 0.0 +14087 0.0 +14088 0.0 +14089 0.0 +14090 0.0 +14091 0.0 +14092 0.0 +14093 0.0 +14094 0.0 +14095 0.0 +14096 0.0 +14097 0.0 +14098 0.0 +14099 0.0 +14100 0.0 +14101 0.0 +14102 0.0 +14103 0.0 +14104 0.0 +14105 0.0 +14106 0.0 +14107 0.0 +14108 0.0 +14109 0.0 +14110 0.0 +14111 0.0 +14112 0.0 +14113 0.0 +14114 0.0 +14115 0.0 +14116 0.0 +14117 0.0 +14118 0.0 +14119 0.0 +14120 0.0 +14121 0.0 +14122 0.0 +14123 0.0 +14124 0.0 +14125 0.0 +14126 0.0 +14127 0.0 +14128 0.0 +14129 0.0 +14130 0.0 +14131 0.0 +14132 0.0 +14133 0.0 +14134 0.0 +14135 0.0 +14136 0.0 +14137 0.0 +14138 0.0 +14139 0.0 +14140 0.0 +14141 0.0 +14142 0.0 +14143 0.0 +14144 0.0 +14145 0.0 +14146 0.0 +14147 0.0 +14148 0.0 +14149 0.0 +14150 0.0 +14151 0.0 +14152 0.0 +14153 0.0 +14154 0.0 +14155 0.0 +14156 0.0 +14157 0.0 +14158 0.0 +14159 0.0 +14160 0.0 +14161 0.0 +14162 0.0 +14163 0.0 +14164 0.0 +14165 0.0 +14166 0.0 +14167 0.0 +14168 0.0 +14169 0.0 +14170 0.0 +14171 0.0 +14172 0.0 +14173 0.0 +14174 0.0 +14175 0.0 +14176 0.0 +14177 0.0 +14178 0.0 +14179 0.0 +14180 0.0 +14181 0.0 +14182 0.0 +14183 0.0 +14184 0.0 +14185 0.0 +14186 0.0 +14187 0.0 +14188 0.0 +14189 0.0 +14190 0.0 +14191 0.0 +14192 0.0 +14193 0.0 +14194 0.0 +14195 0.0 +14196 0.0 +14197 0.0 +14198 0.0 +14199 0.0 +14200 0.0 +14201 0.0 +14202 0.0 +14203 0.0 +14204 0.0 +14205 0.0 +14206 0.0 +14207 0.0 +14208 0.0 +14209 0.0 +14210 0.0 +14211 0.0 +14212 0.0 +14213 0.0 +14214 0.0 +14215 0.0 +14216 0.0 +14217 0.0 +14218 0.0 +14219 0.0 +14220 0.0 +14221 0.0 +14222 0.0 +14223 0.0 +14224 0.0 +14225 0.0 +14226 0.0 +14227 0.0 +14228 0.0 +14229 0.0 +14230 0.0 +14231 0.0 +14232 0.0 +14233 0.0 +14234 0.0 +14235 0.0 +14236 0.0 +14237 0.0 +14238 0.0 +14239 0.0 +14240 0.0 +14241 0.0 +14242 0.0 +14243 0.0 +14244 0.0 +14245 0.0 +14246 0.0 +14247 0.0 +14248 0.0 +14249 0.0 +14250 0.0 +14251 0.0 +14252 0.0 +14253 0.0 +14254 0.0 +14255 0.0 +14256 0.0 +14257 0.0 +14258 0.0 +14259 0.0 +14260 0.0 +14261 0.0 +14262 0.0 +14263 0.0 +14264 0.0 +14265 0.0 +14266 0.0 +14267 0.0 +14268 0.0 +14269 0.0 +14270 0.0 +14271 0.0 +14272 0.0 +14273 0.0 +14274 0.0 +14275 0.0 +14276 0.0 +14277 0.0 +14278 0.0 +14279 0.0 +14280 0.0 +14281 0.0 +14282 0.0 +14283 0.0 +14284 0.0 +14285 0.0 +14286 0.0 +14287 0.0 +14288 0.0 +14289 0.0 +14290 0.0 +14291 0.0 +14292 0.0 +14293 0.0 +14294 0.0 +14295 0.0 +14296 0.0 +14297 0.0 +14298 0.0 +14299 0.0 +14300 0.0 +14301 0.0 +14302 0.0 +14303 0.0 +14304 0.0 +14305 0.0 +14306 0.0 +14307 0.0 +14308 0.0 +14309 0.0 +14310 0.0 +14311 0.0 +14312 0.0 +14313 0.0 +14314 0.0 +14315 0.0 +14316 0.0 +14317 0.0 +14318 0.0 +14319 0.0 +14320 0.0 +14321 0.0 +14322 0.0 +14323 0.0 +14324 0.0 +14325 0.0 +14326 0.0 +14327 0.0 +14328 0.0 +14329 0.0 +14330 0.0 +14331 0.0 +14332 0.0 +14333 0.0 +14334 0.0 +14335 0.0 +14336 0.0 +14337 0.0 +14338 0.0 +14339 0.0 +14340 0.0 +14341 0.0 +14342 0.0 +14343 0.0 +14344 0.0 +14345 0.0 +14346 0.0 +14347 0.0 +14348 0.0 +14349 0.0 +14350 0.0 +14351 0.0 +14352 0.0 +14353 0.0 +14354 0.0 +14355 0.0 +14356 0.0 +14357 0.0 +14358 0.0 +14359 0.0 +14360 0.0 +14361 0.0 +14362 0.0 +14363 0.0 +14364 0.0 +14365 0.0 +14366 0.0 +14367 0.0 +14368 0.0 +14369 0.0 +14370 0.0 +14371 0.0 +14372 0.0 +14373 0.0 +14374 0.0 +14375 0.0 +14376 0.0 +14377 0.0 +14378 0.0 +14379 0.0 +14380 0.0 +14381 0.0 +14382 0.0 +14383 0.0 +14384 0.0 +14385 0.0 +14386 0.0 +14387 0.0 +14388 0.0 +14389 0.0 +14390 0.0 +14391 0.0 +14392 0.0 +14393 0.0 +14394 0.0 +14395 0.0 +14396 0.0 +14397 0.0 +14398 0.0 +14399 0.0 +14400 0.0 +14401 0.0 +14402 0.0 +14403 0.0 +14404 0.0 +14405 0.0 +14406 0.0 +14407 0.0 +14408 0.0 +14409 0.0 +14410 0.0 +14411 0.0 +14412 0.0 +14413 0.0 +14414 0.0 +14415 0.0 +14416 0.0 +14417 0.0 +14418 0.0 +14419 0.0 +14420 0.0 +14421 0.0 +14422 0.0 +14423 0.0 +14424 0.0 +14425 0.0 +14426 0.0 +14427 0.0 +14428 0.0 +14429 0.0 +14430 0.0 +14431 0.0 +14432 0.0 +14433 0.0 +14434 0.0 +14435 0.0 +14436 0.0 +14437 0.0 +14438 0.0 +14439 0.0 +14440 0.0 +14441 0.0 +14442 0.0 +14443 0.0 +14444 0.0 +14445 0.0 +14446 0.0 +14447 0.0 +14448 0.0 +14449 0.0 +14450 0.0 +14451 0.0 +14452 0.0 +14453 0.0 +14454 0.0 +14455 0.0 +14456 0.0 +14457 0.0 +14458 0.0 +14459 0.0 +14460 0.0 +14461 0.0 +14462 0.0 +14463 0.0 +14464 0.0 +14465 0.0 +14466 0.0 +14467 0.0 +14468 0.0 +14469 0.0 +14470 0.0 +14471 0.0 +14472 0.0 +14473 0.0 +14474 0.0 +14475 0.0 +14476 0.0 +14477 0.0 +14478 0.0 +14479 0.0 +14480 0.0 +14481 0.0 +14482 0.0 +14483 0.0 +14484 0.0 +14485 0.0 +14486 0.0 +14487 0.0 +14488 0.0 +14489 0.0 +14490 0.0 +14491 0.0 +14492 0.0 +14493 0.0 +14494 0.0 +14495 0.0 +14496 0.0 +14497 0.0 +14498 0.0 +14499 0.0 +14500 0.0 +14501 0.0 +14502 0.0 +14503 0.0 +14504 0.0 +14505 0.0 +14506 0.0 +14507 0.0 +14508 0.0 +14509 0.0 +14510 0.0 +14511 0.0 +14512 0.0 +14513 0.0 +14514 0.0 +14515 0.0 +14516 0.0 +14517 0.0 +14518 0.0 +14519 0.0 +14520 0.0 +14521 0.0 +14522 0.0 +14523 0.0 +14524 0.0 +14525 0.0 +14526 0.0 +14527 0.0 +14528 0.0 +14529 0.0 +14530 0.0 +14531 0.0 +14532 0.0 +14533 0.0 +14534 0.0 +14535 0.0 +14536 0.0 +14537 0.0 +14538 0.0 +14539 0.0 +14540 0.0 +14541 0.0 +14542 0.0 +14543 0.0 +14544 0.0 +14545 0.0 +14546 0.0 +14547 0.0 +14548 0.0 +14549 0.0 +14550 0.0 +14551 0.0 +14552 0.0 +14553 0.0 +14554 0.0 +14555 0.0 +14556 0.0 +14557 0.0 +14558 0.0 +14559 0.0 +14560 0.0 +14561 0.0 +14562 0.0 +14563 0.0 +14564 0.0 +14565 0.0 +14566 0.0 +14567 0.0 +14568 0.0 +14569 0.0 +14570 0.0 +14571 0.0 +14572 0.0 +14573 0.0 +14574 0.0 +14575 0.0 +14576 0.0 +14577 0.0 +14578 0.0 +14579 0.0 +14580 0.0 +14581 0.0 +14582 0.0 +14583 0.0 +14584 0.0 +14585 0.0 +14586 0.0 +14587 0.0 +14588 0.0 +14589 0.0 +14590 0.0 +14591 0.0 +14592 0.0 +14593 0.0 +14594 0.0 +14595 0.0 +14596 0.0 +14597 0.0 +14598 0.0 +14599 0.0 +14600 0.0 +14601 0.0 +14602 0.0 +14603 0.0 +14604 0.0 +14605 0.0 +14606 0.0 +14607 0.0 +14608 0.0 +14609 0.0 +14610 0.0 +14611 0.0 +14612 0.0 +14613 0.0 +14614 0.0 +14615 0.0 +14616 0.0 +14617 0.0 +14618 0.0 +14619 0.0 +14620 0.0 +14621 0.0 +14622 0.0 +14623 0.0 +14624 0.0 +14625 0.0 +14626 0.0 +14627 0.0 +14628 0.0 +14629 0.0 +14630 0.0 +14631 0.0 +14632 0.0 +14633 0.0 +14634 0.0 +14635 0.0 +14636 0.0 +14637 0.0 +14638 0.0 +14639 0.0 +14640 0.0 +14641 0.0 +14642 0.0 +14643 0.0 +14644 0.0 +14645 0.0 +14646 0.0 +14647 0.0 +14648 0.0 +14649 0.0 +14650 0.0 +14651 0.0 +14652 0.0 +14653 0.0 +14654 0.0 +14655 0.0 +14656 0.0 +14657 0.0 +14658 0.0 +14659 0.0 +14660 0.0 +14661 0.0 +14662 0.0 +14663 0.0 +14664 0.0 +14665 0.0 +14666 0.0 +14667 0.0 +14668 0.0 +14669 0.0 +14670 0.0 +14671 0.0 +14672 0.0 +14673 0.0 +14674 0.0 +14675 0.0 +14676 0.0 +14677 0.0 +14678 0.0 +14679 0.0 +14680 0.0 +14681 0.0 +14682 0.0 +14683 0.0 +14684 0.0 +14685 0.0 +14686 0.0 +14687 0.0 +14688 0.0 +14689 0.0 +14690 0.0 +14691 0.0 +14692 0.0 +14693 0.0 +14694 0.0 +14695 0.0 +14696 0.0 +14697 0.0 +14698 0.0 +14699 0.0 +14700 0.0 +14701 0.0 +14702 0.0 +14703 0.0 +14704 0.0 +14705 0.0 +14706 0.0 +14707 0.0 +14708 0.0 +14709 0.0 +14710 0.0 +14711 0.0 +14712 0.0 +14713 0.0 +14714 0.0 +14715 0.0 +14716 0.0 +14717 0.0 +14718 0.0 +14719 0.0 +14720 0.0 +14721 0.0 +14722 0.0 +14723 0.0 +14724 0.0 +14725 0.0 +14726 0.0 +14727 0.0 +14728 0.0 +14729 0.0 +14730 0.0 +14731 0.0 +14732 0.0 +14733 0.0 +14734 0.0 +14735 0.0 +14736 0.0 +14737 0.0 +14738 0.0 +14739 0.0 +14740 0.0 +14741 0.0 +14742 0.0 +14743 0.0 +14744 0.0 +14745 0.0 +14746 0.0 +14747 0.0 +14748 0.0 +14749 0.0 +14750 0.0 +14751 0.0 +14752 0.0 +14753 0.0 +14754 0.0 +14755 0.0 +14756 0.0 +14757 0.0 +14758 0.0 +14759 0.0 +14760 0.0 +14761 0.0 +14762 0.0 +14763 0.0 +14764 0.0 +14765 0.0 +14766 0.0 +14767 0.0 +14768 0.0 +14769 0.0 +14770 0.0 +14771 0.0 +14772 0.0 +14773 0.0 +14774 0.0 +14775 0.0 +14776 0.0 +14777 0.0 +14778 0.0 +14779 0.0 +14780 0.0 +14781 0.0 +14782 0.0 +14783 0.0 +14784 0.0 +14785 0.0 +14786 0.0 +14787 0.0 +14788 0.0 +14789 0.0 +14790 0.0 +14791 0.0 +14792 0.0 +14793 0.0 +14794 0.0 +14795 0.0 +14796 0.0 +14797 0.0 +14798 0.0 +14799 0.0 +14800 0.0 +14801 0.0 +14802 0.0 +14803 0.0 +14804 0.0 +14805 0.0 +14806 0.0 +14807 0.0 +14808 0.0 +14809 0.0 +14810 0.0 +14811 0.0 +14812 0.0 +14813 0.0 +14814 0.0 +14815 0.0 +14816 0.0 +14817 0.0 +14818 0.0 +14819 0.0 +14820 0.0 +14821 0.0 +14822 0.0 +14823 0.0 +14824 0.0 +14825 0.0 +14826 0.0 +14827 0.0 +14828 0.0 +14829 0.0 +14830 0.0 +14831 0.0 +14832 0.0 +14833 0.0 +14834 0.0 +14835 0.0 +14836 0.0 +14837 0.0 +14838 0.0 +14839 0.0 +14840 0.0 +14841 0.0 +14842 0.0 +14843 0.0 +14844 0.0 +14845 0.0 +14846 0.0 +14847 0.0 +14848 0.0 +14849 0.0 +14850 0.0 +14851 0.0 +14852 0.0 +14853 0.0 +14854 0.0 +14855 0.0 +14856 0.0 +14857 0.0 +14858 0.0 +14859 0.0 +14860 0.0 +14861 0.0 +14862 0.0 +14863 0.0 +14864 0.0 +14865 0.0 +14866 0.0 +14867 0.0 +14868 0.0 +14869 0.0 +14870 0.0 +14871 0.0 +14872 0.0 +14873 0.0 +14874 0.0 +14875 0.0 +14876 0.0 +14877 0.0 +14878 0.0 +14879 0.0 +14880 0.0 +14881 0.0 +14882 0.0 +14883 0.0 +14884 0.0 +14885 0.0 +14886 0.0 +14887 0.0 +14888 0.0 +14889 0.0 +14890 0.0 +14891 0.0 +14892 0.0 +14893 0.0 +14894 0.0 +14895 0.0 +14896 0.0 +14897 0.0 +14898 0.0 +14899 0.0 +14900 0.0 +14901 0.0 +14902 0.0 +14903 0.0 +14904 0.0 +14905 0.0 +14906 0.0 +14907 0.0 +14908 0.0 +14909 0.0 +14910 0.0 +14911 0.0 +14912 0.0 +14913 0.0 +14914 0.0 +14915 0.0 +14916 0.0 +14917 0.0 +14918 0.0 +14919 0.0 +14920 0.0 +14921 0.0 +14922 0.0 +14923 0.0 +14924 0.0 +14925 0.0 +14926 0.0 +14927 0.0 +14928 0.0 +14929 0.0 +14930 0.0 +14931 0.0 +14932 0.0 +14933 0.0 +14934 0.0 +14935 0.0 +14936 0.0 +14937 0.0 +14938 0.0 +14939 0.0 +14940 0.0 +14941 0.0 +14942 0.0 +14943 0.0 +14944 0.0 +14945 0.0 +14946 0.0 +14947 0.0 +14948 0.0 +14949 0.0 +14950 0.0 +14951 0.0 +14952 0.0 +14953 0.0 +14954 0.0 +14955 0.0 +14956 0.0 +14957 0.0 +14958 0.0 +14959 0.0 +14960 0.0 +14961 0.0 +14962 0.0 +14963 0.0 +14964 0.0 +14965 0.0 +14966 0.0 +14967 0.0 +14968 0.0 +14969 0.0 +14970 0.0 +14971 0.0 +14972 0.0 +14973 0.0 +14974 0.0 +14975 0.0 +14976 0.0 +14977 0.0 +14978 0.0 +14979 0.0 +14980 0.0 +14981 0.0 +14982 0.0 +14983 0.0 +14984 0.0 +14985 0.0 +14986 0.0 +14987 0.0 +14988 0.0 +14989 0.0 +14990 0.0 +14991 0.0 +14992 0.0 +14993 0.0 +14994 0.0 +14995 0.0 +14996 0.0 +14997 0.0 +14998 0.0 +14999 0.0 +15000 0.0 +15001 0.0 +15002 0.0 +15003 0.0 +15004 0.0 +15005 0.0 +15006 0.0 +15007 0.0 +15008 0.0 +15009 0.0 +15010 0.0 +15011 0.0 +15012 0.0 +15013 0.0 +15014 0.0 +15015 0.0 +15016 0.0 +15017 0.0 +15018 0.0 +15019 0.0 +15020 0.0 +15021 0.0 +15022 0.0 +15023 0.0 +15024 0.0 +15025 0.0 +15026 0.0 +15027 0.0 +15028 0.0 +15029 0.0 +15030 0.0 +15031 0.0 +15032 0.0 +15033 0.0 +15034 0.0 +15035 0.0 +15036 0.0 +15037 0.0 +15038 0.0 +15039 0.0 +15040 0.0 +15041 0.0 +15042 0.0 +15043 0.0 +15044 0.0 +15045 0.0 +15046 0.0 +15047 0.0 +15048 0.0 +15049 0.0 +15050 0.0 +15051 0.0 +15052 0.0 +15053 0.0 +15054 0.0 +15055 0.0 +15056 0.0 +15057 0.0 +15058 0.0 +15059 0.0 +15060 0.0 +15061 0.0 +15062 0.0 +15063 0.0 +15064 0.0 +15065 0.0 +15066 0.0 +15067 0.0 +15068 0.0 +15069 0.0 +15070 0.0 +15071 0.0 +15072 0.0 +15073 0.0 +15074 0.0 +15075 0.0 +15076 0.0 +15077 0.0 +15078 0.0 +15079 0.0 +15080 0.0 +15081 0.0 +15082 0.0 +15083 0.0 +15084 0.0 +15085 0.0 +15086 0.0 +15087 0.0 +15088 0.0 +15089 0.0 +15090 0.0 +15091 0.0 +15092 0.0 +15093 0.0 +15094 0.0 +15095 0.0 +15096 0.0 +15097 0.0 +15098 0.0 +15099 0.0 +15100 0.0 +15101 0.0 +15102 0.0 +15103 0.0 +15104 0.0 +15105 0.0 +15106 0.0 +15107 0.0 +15108 0.0 +15109 0.0 +15110 0.0 +15111 0.0 +15112 0.0 +15113 0.0 +15114 0.0 +15115 0.0 +15116 0.0 +15117 0.0 +15118 0.0 +15119 0.0 +15120 0.0 +15121 0.0 +15122 0.0 +15123 0.0 +15124 0.0 +15125 0.0 +15126 0.0 +15127 0.0 +15128 0.0 +15129 0.0 +15130 0.0 +15131 0.0 +15132 0.0 +15133 0.0 +15134 0.0 +15135 0.0 +15136 0.0 +15137 0.0 +15138 0.0 +15139 0.0 +15140 0.0 +15141 0.0 +15142 0.0 +15143 0.0 +15144 0.0 +15145 0.0 +15146 0.0 +15147 0.0 +15148 0.0 +15149 0.0 +15150 0.0 +15151 0.0 +15152 0.0 +15153 0.0 +15154 0.0 +15155 0.0 +15156 0.0 +15157 0.0 +15158 0.0 +15159 0.0 +15160 0.0 +15161 0.0 +15162 0.0 +15163 0.0 +15164 0.0 +15165 0.0 +15166 0.0 +15167 0.0 +15168 0.0 +15169 0.0 +15170 0.0 +15171 0.0 +15172 0.0 +15173 0.0 +15174 0.0 +15175 0.0 +15176 0.0 +15177 0.0 +15178 0.0 +15179 0.0 +15180 0.0 +15181 0.0 +15182 0.0 +15183 0.0 +15184 0.0 +15185 0.0 +15186 0.0 +15187 0.0 +15188 0.0 +15189 0.0 +15190 0.0 +15191 0.0 +15192 0.0 +15193 0.0 +15194 0.0 +15195 0.0 +15196 0.0 +15197 0.0 +15198 0.0 +15199 0.0 +15200 0.0 +15201 0.0 +15202 0.0 +15203 0.0 +15204 0.0 +15205 0.0 +15206 0.0 +15207 0.0 +15208 0.0 +15209 0.0 +15210 0.0 +15211 0.0 +15212 0.0 +15213 0.0 +15214 0.0 +15215 0.0 +15216 0.0 +15217 0.0 +15218 0.0 +15219 0.0 +15220 0.0 +15221 0.0 +15222 0.0 +15223 0.0 +15224 0.0 +15225 0.0 +15226 0.0 +15227 0.0 +15228 0.0 +15229 0.0 +15230 0.0 +15231 0.0 +15232 0.0 +15233 0.0 +15234 0.0 +15235 0.0 +15236 0.0 +15237 0.0 +15238 0.0 +15239 0.0 +15240 0.0 +15241 0.0 +15242 0.0 +15243 0.0 +15244 0.0 +15245 0.0 +15246 0.0 +15247 0.0 +15248 0.0 +15249 0.0 +15250 0.0 +15251 0.0 +15252 0.0 +15253 0.0 +15254 0.0 +15255 0.0 +15256 0.0 +15257 0.0 +15258 0.0 +15259 0.0 +15260 0.0 +15261 0.0 +15262 0.0 +15263 0.0 +15264 0.0 +15265 0.0 +15266 0.0 +15267 0.0 +15268 0.0 +15269 0.0 +15270 0.0 +15271 0.0 +15272 0.0 +15273 0.0 +15274 0.0 +15275 0.0 +15276 0.0 +15277 0.0 +15278 0.0 +15279 0.0 +15280 0.0 +15281 0.0 +15282 0.0 +15283 0.0 +15284 0.0 +15285 0.0 +15286 0.0 +15287 0.0 +15288 0.0 +15289 0.0 +15290 0.0 +15291 0.0 +15292 0.0 +15293 0.0 +15294 0.0 +15295 0.0 +15296 0.0 +15297 0.0 +15298 0.0 +15299 0.0 +15300 0.0 +15301 0.0 +15302 0.0 +15303 0.0 +15304 0.0 +15305 0.0 +15306 0.0 +15307 0.0 +15308 0.0 +15309 0.0 +15310 0.0 +15311 0.0 +15312 0.0 +15313 0.0 +15314 0.0 +15315 0.0 +15316 0.0 +15317 0.0 +15318 0.0 +15319 0.0 +15320 0.0 +15321 0.0 +15322 0.0 +15323 0.0 +15324 0.0 +15325 0.0 +15326 0.0 +15327 0.0 +15328 0.0 +15329 0.0 +15330 0.0 +15331 0.0 +15332 0.0 +15333 0.0 +15334 0.0 +15335 0.0 +15336 0.0 +15337 0.0 +15338 0.0 +15339 0.0 +15340 0.0 +15341 0.0 +15342 0.0 +15343 0.0 +15344 0.0 +15345 0.0 +15346 0.0 +15347 0.0 +15348 0.0 +15349 0.0 +15350 0.0 +15351 0.0 +15352 0.0 +15353 0.0 +15354 0.0 +15355 0.0 +15356 0.0 +15357 0.0 +15358 0.0 +15359 0.0 diff --git a/tests/circuitpython/audiofilter_filter_stereo_biquads.py b/tests/circuitpython/audiofilter_filter_stereo_biquads.py new file mode 100644 index 00000000000..262f8139378 --- /dev/null +++ b/tests/circuitpython/audiofilter_filter_stereo_biquads.py @@ -0,0 +1,27 @@ +from audiofilters import Filter +from audiofilterhelper import synth_test, white8k +from audiomixer import Mixer +from synthio import Biquad, FilterMode, LFO + + +@synth_test +def stereo_filter(): + args = { + "bits_per_sample": 16, + "samples_signed": True, + "channel_count": 2, + } + effect = Filter( + filter=[ + Biquad(FilterMode.LOW_PASS, 400), + Biquad(FilterMode.HIGH_PASS, 300, Q=8), + ], + **args, + ) + mixer = Mixer(**args) + mixer.voice[0].panning = LFO() + effect.play(mixer) + yield effect, [] + + mixer.play(white8k, loop=True) + yield 400 diff --git a/tests/circuitpython/audiofilter_filter_stereo_biquads.py.exp b/tests/circuitpython/audiofilter_filter_stereo_biquads.py.exp new file mode 100644 index 00000000000..7901d158079 --- /dev/null +++ b/tests/circuitpython/audiofilter_filter_stereo_biquads.py.exp @@ -0,0 +1,102400 @@ +0 0.0 +1 0.0 +2 0.0 +3 0.0 +4 0.0 +5 0.0 +6 0.0 +7 0.0 +8 0.0 +9 0.0 +10 0.0 +11 0.0 +12 0.0 +13 0.0 +14 0.0 +15 0.0 +16 0.0 +17 0.0 +18 0.0 +19 0.0 +20 0.0 +21 0.0 +22 0.0 +23 0.0 +24 0.0 +25 0.0 +26 0.0 +27 0.0 +28 0.0 +29 0.0 +30 0.0 +31 0.0 +32 0.0 +33 0.0 +34 0.0 +35 0.0 +36 0.0 +37 0.0 +38 0.0 +39 0.0 +40 0.0 +41 0.0 +42 0.0 +43 0.0 +44 0.0 +45 0.0 +46 0.0 +47 0.0 +48 0.0 +49 0.0 +50 0.0 +51 0.0 +52 0.0 +53 0.0 +54 0.0 +55 0.0 +56 0.0 +57 0.0 +58 0.0 +59 0.0 +60 0.0 +61 0.0 +62 0.0 +63 0.0 +64 0.0 +65 0.0 +66 0.0 +67 0.0 +68 0.0 +69 0.0 +70 0.0 +71 0.0 +72 0.0 +73 0.0 +74 0.0 +75 0.0 +76 0.0 +77 0.0 +78 0.0 +79 0.0 +80 0.0 +81 0.0 +82 0.0 +83 0.0 +84 0.0 +85 0.0 +86 0.0 +87 0.0 +88 0.0 +89 0.0 +90 0.0 +91 0.0 +92 0.0 +93 0.0 +94 0.0 +95 0.0 +96 0.0 +97 0.0 +98 0.0 +99 0.0 +100 0.0 +101 0.0 +102 0.0 +103 0.0 +104 0.0 +105 0.0 +106 0.0 +107 0.0 +108 0.0 +109 0.0 +110 0.0 +111 0.0 +112 0.0 +113 0.0 +114 0.0 +115 0.0 +116 0.0 +117 0.0 +118 0.0 +119 0.0 +120 0.0 +121 0.0 +122 0.0 +123 0.0 +124 0.0 +125 0.0 +126 0.0 +127 0.0 +128 0.0 +129 0.0 +130 0.0 +131 0.0 +132 0.0 +133 0.0 +134 0.0 +135 0.0 +136 0.0 +137 0.0 +138 0.0 +139 0.0 +140 0.0 +141 0.0 +142 0.0 +143 0.0 +144 0.0 +145 0.0 +146 0.0 +147 0.0 +148 0.0 +149 0.0 +150 0.0 +151 0.0 +152 0.0 +153 0.0 +154 0.0 +155 0.0 +156 0.0 +157 0.0 +158 0.0 +159 0.0 +160 0.0 +161 0.0 +162 0.0 +163 0.0 +164 0.0 +165 0.0 +166 0.0 +167 0.0 +168 0.0 +169 0.0 +170 0.0 +171 0.0 +172 0.0 +173 0.0 +174 0.0 +175 0.0 +176 0.0 +177 0.0 +178 0.0 +179 0.0 +180 0.0 +181 0.0 +182 0.0 +183 0.0 +184 0.0 +185 0.0 +186 0.0 +187 0.0 +188 0.0 +189 0.0 +190 0.0 +191 0.0 +192 0.0 +193 0.0 +194 0.0 +195 0.0 +196 0.0 +197 0.0 +198 0.0 +199 0.0 +200 0.0 +201 0.0 +202 0.0 +203 0.0 +204 0.0 +205 0.0 +206 0.0 +207 0.0 +208 0.0 +209 0.0 +210 0.0 +211 0.0 +212 0.0 +213 0.0 +214 0.0 +215 0.0 +216 0.0 +217 0.0 +218 0.0 +219 0.0 +220 0.0 +221 0.0 +222 0.0 +223 0.0 +224 0.0 +225 0.0 +226 0.0 +227 0.0 +228 0.0 +229 0.0 +230 0.0 +231 0.0 +232 0.0 +233 0.0 +234 0.0 +235 0.0 +236 0.0 +237 0.0 +238 0.0 +239 0.0 +240 0.0 +241 0.0 +242 0.0 +243 0.0 +244 0.0 +245 0.0 +246 0.0 +247 0.0 +248 0.0 +249 0.0 +250 0.0 +251 0.0 +252 0.0 +253 0.0 +254 0.0 +255 0.0 +256 0.002960205078125 +257 0.0030517578125 +258 0.020904541015625 +259 0.021575927734375 +260 0.049591064453125 +261 0.05120849609375 +262 0.052093505859375 +263 0.053802490234375 +264 9.1552734375e-05 +265 9.1552734375e-05 +266 -0.089752197265625 +267 -0.09271240234375 +268 -0.1788330078125 +269 -0.1846923828125 +270 -0.229644775390625 +271 -0.237152099609375 +272 -0.205322265625 +273 -0.21197509765625 +274 -0.1357421875 +275 -0.140045166015625 +276 -0.068145751953125 +277 -0.070159912109375 +278 0.0040283203125 +279 0.004425048828125 +280 0.085601806640625 +281 0.08868408203125 +282 0.19061279296875 +283 0.1971435546875 +284 0.28875732421875 +285 0.2984619140625 +286 0.32904052734375 +287 0.34002685546875 +288 0.328033447265625 +289 0.338958740234375 +290 0.301422119140625 +291 0.311431884765625 +292 0.248870849609375 +293 0.257110595703125 +294 0.164520263671875 +295 0.169921875 +296 0.047454833984375 +297 0.048919677734375 +298 -0.07232666015625 +299 -0.074859619140625 +300 -0.189605712890625 +301 -0.196044921875 +302 -0.30810546875 +303 -0.3184814453125 +304 -0.40386962890625 +305 -0.41741943359375 +306 -0.44793701171875 +307 -0.462921142578125 +308 -0.402435302734375 +309 -0.4158935546875 +310 -0.26312255859375 +311 -0.27197265625 +312 -0.093475341796875 +313 -0.0966796875 +314 0.030303955078125 +315 0.031219482421875 +316 0.106536865234375 +317 0.110015869140625 +318 0.16162109375 +319 0.166961669921875 +320 0.20147705078125 +321 0.20819091796875 +322 0.226287841796875 +323 0.23388671875 +324 0.201416015625 +325 0.208282470703125 +326 0.1470947265625 +327 0.152252197265625 +328 0.119049072265625 +329 0.123321533203125 +330 0.090087890625 +331 0.093414306640625 +332 0.018585205078125 +333 0.019500732421875 +334 -0.070709228515625 +335 -0.07281494140625 +336 -0.11651611328125 +337 -0.1202392578125 +338 -0.0858154296875 +339 -0.088623046875 +340 -0.024078369140625 +341 -0.024932861328125 +342 -0.006011962890625 +343 -0.00634765625 +344 -0.036468505859375 +345 -0.037872314453125 +346 -0.0826416015625 +347 -0.085601806640625 +348 -0.118194580078125 +349 -0.12237548828125 +350 -0.111480712890625 +351 -0.115478515625 +352 -0.051116943359375 +353 -0.05316162109375 +354 0.021331787109375 +355 0.02166748046875 +356 0.04974365234375 +357 0.051025390625 +358 0.0406494140625 +359 0.041656494140625 +360 0.05322265625 +361 0.0546875 +362 0.12335205078125 +363 0.127197265625 +364 0.210296630859375 +365 0.21710205078125 +366 0.254425048828125 +367 0.262786865234375 +368 0.27325439453125 +369 0.282318115234375 +370 0.30120849609375 +371 0.311279296875 +372 0.312896728515625 +373 0.32342529296875 +374 0.2645263671875 +375 0.273468017578125 +376 0.1497802734375 +377 0.1549072265625 +378 0.016937255859375 +379 0.017669677734375 +380 -0.08575439453125 +381 -0.088409423828125 +382 -0.154876708984375 +383 -0.15985107421875 +384 -0.191314697265625 +385 -0.197540283203125 +386 -0.22088623046875 +387 -0.2281494140625 +388 -0.287445068359375 +389 -0.296966552734375 +390 -0.38238525390625 +391 -0.39508056640625 +392 -0.488983154296875 +393 -0.505218505859375 +394 -0.577056884765625 +395 -0.59619140625 +396 -0.609649658203125 +397 -0.62982177734375 +398 -0.57977294921875 +399 -0.59893798828125 +400 -0.464447021484375 +401 -0.47979736328125 +402 -0.276885986328125 +403 -0.286041259765625 +404 -0.0714111328125 +405 -0.07379150390625 +406 0.12152099609375 +407 0.12548828125 +408 0.269439697265625 +409 0.278289794921875 +410 0.360321044921875 +411 0.3721923828125 +412 0.43292236328125 +413 0.44720458984375 +414 0.494903564453125 +415 0.511260986328125 +416 0.50244140625 +417 0.519073486328125 +418 0.444000244140625 +419 0.458740234375 +420 0.36920166015625 +421 0.38153076171875 +422 0.32666015625 +423 0.337646484375 +424 0.322052001953125 +425 0.332916259765625 +426 0.34649658203125 +427 0.358184814453125 +428 0.367218017578125 +429 0.379608154296875 +430 0.334686279296875 +431 0.34600830078125 +432 0.232086181640625 +433 0.239990234375 +434 0.082855224609375 +435 0.085784912109375 +436 -0.079559326171875 +437 -0.082061767578125 +438 -0.231689453125 +439 -0.239288330078125 +440 -0.358489990234375 +441 -0.370361328125 +442 -0.446044921875 +443 -0.460906982421875 +444 -0.4727783203125 +445 -0.48858642578125 +446 -0.45269775390625 +447 -0.467864990234375 +448 -0.43072509765625 +449 -0.4451904296875 +450 -0.40185546875 +451 -0.4154052734375 +452 -0.359283447265625 +453 -0.371429443359375 +454 -0.339935302734375 +455 -0.3514404296875 +456 -0.320892333984375 +457 -0.331756591796875 +458 -0.229156494140625 +459 -0.236968994140625 +460 -0.062042236328125 +461 -0.064300537109375 +462 0.1336669921875 +463 0.137908935546875 +464 0.320068359375 +465 0.33056640625 +466 0.473236083984375 +467 0.488922119140625 +468 0.56414794921875 +469 0.58294677734375 +470 0.56158447265625 +471 0.580413818359375 +472 0.481597900390625 +473 0.497894287109375 +474 0.36175537109375 +475 0.374176025390625 +476 0.243743896484375 +477 0.252288818359375 +478 0.151763916015625 +479 0.157257080078125 +480 0.0540771484375 +481 0.0562744140625 +482 -0.0638427734375 +483 -0.065643310546875 +484 -0.157470703125 +485 -0.1624755859375 +486 -0.222991943359375 +487 -0.230316162109375 +488 -0.279541015625 +489 -0.288909912109375 +490 -0.291900634765625 +491 -0.30181884765625 +492 -0.25115966796875 +493 -0.25982666015625 +494 -0.20123291015625 +495 -0.20831298828125 +496 -0.181121826171875 +497 -0.18756103515625 +498 -0.17724609375 +499 -0.18359375 +500 -0.142303466796875 +501 -0.147491455078125 +502 -0.074188232421875 +503 -0.077056884765625 +504 -0.01043701171875 +505 -0.011138916015625 +506 0.04486083984375 +507 0.04608154296875 +508 0.0850830078125 +509 0.087738037109375 +510 0.088409423828125 +511 0.091278076171875 +512 0.091705322265625 +513 0.09515380859375 +514 0.11151123046875 +515 0.11663818359375 +516 0.122528076171875 +517 0.1290283203125 +518 0.110137939453125 +519 0.116546630859375 +520 0.0689697265625 +521 0.07330322265625 +522 0.02484130859375 +523 0.026763916015625 +524 -0.02301025390625 +525 -0.02392578125 +526 -0.104278564453125 +527 -0.110504150390625 +528 -0.18359375 +529 -0.195220947265625 +530 -0.223724365234375 +531 -0.23822021484375 +532 -0.232635498046875 +533 -0.248016357421875 +534 -0.18865966796875 +535 -0.201385498046875 +536 -0.101318359375 +537 -0.108489990234375 +538 -0.002288818359375 +539 -0.00311279296875 +540 0.110382080078125 +541 0.11688232421875 +542 0.20416259765625 +543 0.21673583984375 +544 0.24432373046875 +545 0.259368896484375 +546 0.24310302734375 +547 0.257904052734375 +548 0.209259033203125 +549 0.221710205078125 +550 0.163360595703125 +551 0.1727294921875 +552 0.133575439453125 +553 0.141082763671875 +554 0.101165771484375 +555 0.106689453125 +556 0.06396484375 +557 0.0672607421875 +558 0.050018310546875 +559 0.052734375 +560 0.07598876953125 +561 0.08087158203125 +562 0.126983642578125 +563 0.1357421875 +564 0.160369873046875 +565 0.171783447265625 +566 0.154541015625 +567 0.1658935546875 +568 0.101318359375 +569 0.10931396484375 +570 0.005401611328125 +571 0.007080078125 +572 -0.1109619140625 +573 -0.1170654296875 +574 -0.2427978515625 +575 -0.2578125 +576 -0.380523681640625 +577 -0.404937744140625 +578 -0.49627685546875 +579 -0.5286865234375 +580 -0.548828125 +581 -0.58502197265625 +582 -0.498046875 +583 -0.531005859375 +584 -0.366180419921875 +585 -0.390411376953125 +586 -0.21160888671875 +587 -0.225616455078125 +588 -0.058380126953125 +589 -0.062255859375 +590 0.09466552734375 +591 0.100921630859375 +592 0.23687744140625 +593 0.252532958984375 +594 0.3428955078125 +595 0.365509033203125 +596 0.396331787109375 +597 0.422332763671875 +598 0.393890380859375 +599 0.41949462890625 +600 0.334259033203125 +601 0.355621337890625 +602 0.2401123046875 +603 0.254974365234375 +604 0.144622802734375 +605 0.152984619140625 +606 0.0594482421875 +607 0.062103271484375 +608 0.01043701171875 +609 0.00994873046875 +610 -0.004119873046875 +611 -0.00531005859375 +612 -0.013671875 +613 -0.015167236328125 +614 -0.00042724609375 +615 -0.000640869140625 +616 0.0472412109375 +617 0.050628662109375 +618 0.088409423828125 +619 0.094940185546875 +620 0.074005126953125 +621 0.079833984375 +622 0.019134521484375 +623 0.021453857421875 +624 -0.04058837890625 +625 -0.04217529296875 +626 -0.096221923828125 +627 -0.10150146484375 +628 -0.1370849609375 +629 -0.1451416015625 +630 -0.17352294921875 +631 -0.18408203125 +632 -0.21112060546875 +633 -0.224334716796875 +634 -0.250518798828125 +635 -0.2666015625 +636 -0.298919677734375 +637 -0.318572998046875 +638 -0.347076416015625 +639 -0.37030029296875 +640 -0.36907958984375 +641 -0.39410400390625 +642 -0.329833984375 +643 -0.35247802734375 +644 -0.22613525390625 +645 -0.241973876953125 +646 -0.074554443359375 +647 -0.08026123046875 +648 0.09942626953125 +649 0.105438232421875 +650 0.238983154296875 +651 0.25439453125 +652 0.31884765625 +653 0.339630126953125 +654 0.356597900390625 +655 0.379913330078125 +656 0.345703125 +657 0.368316650390625 +658 0.285797119140625 +659 0.304412841796875 +660 0.224578857421875 +661 0.239166259765625 +662 0.196319580078125 +663 0.20916748046875 +664 0.176422119140625 +665 0.188140869140625 +666 0.1492919921875 +667 0.159393310546875 +668 0.14080810546875 +669 0.150543212890625 +670 0.141937255859375 +671 0.151947021484375 +672 0.114501953125 +673 0.122833251953125 +674 0.08221435546875 +675 0.088531494140625 +676 0.06683349609375 +677 0.072296142578125 +678 0.034942626953125 +679 0.038360595703125 +680 -0.02557373046875 +681 -0.026214599609375 +682 -0.1142578125 +683 -0.1209716796875 +684 -0.230499267578125 +685 -0.245208740234375 +686 -0.34661865234375 +687 -0.369354248046875 +688 -0.4248046875 +689 -0.45306396484375 +690 -0.45147705078125 +691 -0.481781005859375 +692 -0.439483642578125 +693 -0.46917724609375 +694 -0.39300537109375 +695 -0.41973876953125 +696 -0.310028076171875 +697 -0.331298828125 +698 -0.207061767578125 +699 -0.221527099609375 +700 -0.106353759765625 +701 -0.1141357421875 +702 -0.014312744140625 +703 -0.015960693359375 +704 0.0859375 +705 0.09100341796875 +706 0.2137451171875 +707 0.22747802734375 +708 0.378204345703125 +709 0.403167724609375 +710 0.559051513671875 +711 0.596435546875 +712 0.69921875 +713 0.74627685546875 +714 0.759063720703125 +715 0.81036376953125 +716 0.736114501953125 +717 0.7860107421875 +718 0.6273193359375 +719 0.66998291015625 +720 0.431915283203125 +721 0.46142578125 +722 0.18505859375 +723 0.197906494140625 +724 -0.051727294921875 +725 -0.05487060546875 +726 -0.22491455078125 +727 -0.23974609375 +728 -0.3179931640625 +729 -0.339080810546875 +730 -0.355377197265625 +731 -0.37896728515625 +732 -0.366180419921875 +733 -0.3905029296875 +734 -0.3646240234375 +735 -0.388916015625 +736 -0.3668212890625 +737 -0.391326904296875 +738 -0.37689208984375 +739 -0.4022216796875 +740 -0.369598388671875 +741 -0.39459228515625 +742 -0.32696533203125 +743 -0.3492431640625 +744 -0.269439697265625 +745 -0.287933349609375 +746 -0.237701416015625 +747 -0.254180908203125 +748 -0.248779296875 +749 -0.26617431640625 +750 -0.25311279296875 +751 -0.270904541015625 +752 -0.197998046875 +753 -0.21209716796875 +754 -0.11328125 +755 -0.121612548828125 +756 -0.055572509765625 +757 -0.059967041015625 +758 -0.031158447265625 +759 -0.03387451171875 +760 -0.013275146484375 +761 -0.01470947265625 +762 0.028900146484375 +763 0.030426025390625 +764 0.125396728515625 +765 0.133636474609375 +766 0.249176025390625 +767 0.2659912109375 +768 0.360626220703125 +769 0.385772705078125 +770 0.4522705078125 +771 0.48480224609375 +772 0.495574951171875 +773 0.531097412109375 +774 0.478851318359375 +775 0.511962890625 +776 0.426971435546875 +777 0.454986572265625 +778 0.3798828125 +779 0.404327392578125 +780 0.354766845703125 +781 0.37890625 +782 0.32635498046875 +783 0.350616455078125 +784 0.281341552734375 +785 0.3045654296875 +786 0.22198486328125 +787 0.243011474609375 +788 0.1407470703125 +789 0.157379150390625 +790 0.0196533203125 +791 0.027496337890625 +792 -0.143341064453125 +793 -0.149139404296875 +794 -0.3201904296875 +795 -0.3416748046875 +796 -0.50091552734375 +797 -0.53924560546875 +798 -0.670166015625 +799 -0.725006103515625 +800 -0.77288818359375 +801 -0.838104248046875 +802 -0.767303466796875 +803 -0.832366943359375 +804 -0.6715087890625 +805 -0.727691650390625 +806 -0.535308837890625 +807 -0.579132080078125 +808 -0.40289306640625 +809 -0.435394287109375 +810 -0.294403076171875 +811 -0.318634033203125 +812 -0.179595947265625 +813 -0.195159912109375 +814 -0.034271240234375 +815 -0.038055419921875 +816 0.10321044921875 +817 0.1104736328125 +818 0.194732666015625 +819 0.208465576171875 +820 0.252716064453125 +821 0.26983642578125 +822 0.321044921875 +823 0.34326171875 +824 0.416107177734375 +825 0.446990966796875 +826 0.507049560546875 +827 0.546905517578125 +828 0.57098388671875 +829 0.61773681640625 +830 0.600738525390625 +831 0.6514892578125 +832 0.608062744140625 +833 0.661102294921875 +834 0.59857177734375 +835 0.652679443359375 +836 0.550811767578125 +837 0.602386474609375 +838 0.4521484375 +839 0.496124267578125 +840 0.314910888671875 +841 0.347320556640625 +842 0.152801513671875 +843 0.170989990234375 +844 -0.04058837890625 +845 -0.0401611328125 +846 -0.2442626953125 +847 -0.263031005859375 +848 -0.41192626953125 +849 -0.446502685546875 +850 -0.532440185546875 +851 -0.578399658203125 +852 -0.60150146484375 +853 -0.65399169921875 +854 -0.591156005859375 +855 -0.642364501953125 +856 -0.517791748046875 +857 -0.561676025390625 +858 -0.421661376953125 +859 -0.456390380859375 +860 -0.322113037109375 +861 -0.347869873046875 +862 -0.23809814453125 +863 -0.256988525390625 +864 -0.173553466796875 +865 -0.18792724609375 +866 -0.1256103515625 +867 -0.137359619140625 +868 -0.087310791015625 +869 -0.09747314453125 +870 -0.0498046875 +871 -0.058319091796875 +872 -0.002166748046875 +873 -0.007720947265625 +874 0.066497802734375 +875 0.06646728515625 +876 0.1446533203125 +877 0.151611328125 +878 0.228668212890625 +879 0.243743896484375 +880 0.32513427734375 +881 0.35015869140625 +882 0.42181396484375 +883 0.457366943359375 +884 0.49853515625 +885 0.542999267578125 +886 0.52288818359375 +887 0.57110595703125 +888 0.460906982421875 +889 0.504058837890625 +890 0.318328857421875 +891 0.34808349609375 +892 0.13116455078125 +893 0.142974853515625 +894 -0.053192138671875 +895 -0.0589599609375 +896 -0.20050048828125 +897 -0.219940185546875 +898 -0.309173583984375 +899 -0.33837890625 +900 -0.3717041015625 +901 -0.406005859375 +902 -0.406890869140625 +903 -0.4437255859375 +904 -0.456268310546875 +905 -0.497528076171875 +906 -0.514129638671875 +907 -0.561126708984375 +908 -0.550018310546875 +909 -0.600860595703125 +910 -0.533935546875 +911 -0.58355712890625 +912 -0.4376220703125 +913 -0.4779052734375 +914 -0.255218505859375 +915 -0.27734375 +916 -0.009002685546875 +917 -0.00640869140625 +918 0.243743896484375 +919 0.271636962890625 +920 0.4388427734375 +921 0.48583984375 +922 0.549591064453125 +923 0.60675048828125 +924 0.593017578125 +925 0.6533203125 +926 0.606170654296875 +927 0.666595458984375 +928 0.586334228515625 +929 0.64361572265625 +930 0.524200439453125 +931 0.5740966796875 +932 0.456756591796875 +933 0.499053955078125 +934 0.403167724609375 +935 0.439697265625 +936 0.34454345703125 +937 0.375091552734375 +938 0.25213623046875 +939 0.2734375 +940 0.10101318359375 +941 0.107147216796875 +942 -0.088592529296875 +943 -0.101470947265625 +944 -0.287841796875 +945 -0.320648193359375 +946 -0.497772216796875 +947 -0.551544189453125 +948 -0.7022705078125 +949 -0.77642822265625 +950 -0.853424072265625 +951 -0.864105224609375 +952 -0.861785888671875 +953 -0.870391845703125 +954 -0.861785888671875 +955 -0.868682861328125 +956 -0.855743408203125 +957 -0.86053466796875 +958 -0.739044189453125 +959 -0.759246826171875 +960 -0.530792236328125 +961 -0.52203369140625 +962 -0.247528076171875 +963 -0.20556640625 +964 0.07177734375 +965 0.146942138671875 +966 0.380706787109375 +967 0.48431396484375 +968 0.64703369140625 +969 0.771270751953125 +970 0.846282958984375 +971 0.868316650390625 +972 0.8680419921875 +973 0.870361328125 +974 0.870361328125 +975 0.86395263671875 +976 0.86505126953125 +977 0.8172607421875 +978 0.854766845703125 +979 0.657073974609375 +980 0.723175048828125 +981 0.470733642578125 +982 0.567535400390625 +983 0.279388427734375 +984 0.39276123046875 +985 0.086395263671875 +986 0.170318603515625 +987 -0.140350341796875 +988 -0.106231689453125 +989 -0.40960693359375 +990 -0.39886474609375 +991 -0.6817626953125 +992 -0.654388427734375 +993 -0.859619140625 +994 -0.83514404296875 +995 -0.870391845703125 +996 -0.8634033203125 +997 -0.870391845703125 +998 -0.8685302734375 +999 -0.86444091796875 +1000 -0.870391845703125 +1001 -0.85723876953125 +1002 -0.86846923828125 +1003 -0.790008544921875 +1004 -0.857635498046875 +1005 -0.62847900390625 +1006 -0.701019287109375 +1007 -0.3956298828125 +1008 -0.466644287109375 +1009 -0.126708984375 +1010 -0.205657958984375 +1011 0.150115966796875 +1012 0.07098388671875 +1013 0.424041748046875 +1014 0.339111328125 +1015 0.670623779296875 +1016 0.56427001953125 +1017 0.854522705078125 +1018 0.731414794921875 +1019 0.866485595703125 +1020 0.827880859375 +1021 0.86920166015625 +1022 0.8563232421875 +1023 0.8653564453125 +1024 0.85687255859375 +1025 0.857147216796875 +1026 0.841522216796875 +1027 0.766845703125 +1028 0.772613525390625 +1029 0.628509521484375 +1030 0.66552734375 +1031 0.462127685546875 +1032 0.544281005859375 +1033 0.297210693359375 +1034 0.421051025390625 +1035 0.14862060546875 +1036 0.2769775390625 +1037 -0.00537109375 +1038 0.119354248046875 +1039 -0.15753173828125 +1040 -0.05450439453125 +1041 -0.31304931640625 +1042 -0.2568359375 +1043 -0.48876953125 +1044 -0.44708251953125 +1045 -0.6416015625 +1046 -0.604278564453125 +1047 -0.751373291015625 +1048 -0.749481201171875 +1049 -0.84619140625 +1050 -0.8563232421875 +1051 -0.861297607421875 +1052 -0.863983154296875 +1053 -0.863250732421875 +1054 -0.863189697265625 +1055 -0.856597900390625 +1056 -0.855255126953125 +1057 -0.7498779296875 +1058 -0.775177001953125 +1059 -0.624542236328125 +1060 -0.657257080078125 +1061 -0.47808837890625 +1062 -0.45770263671875 +1063 -0.253387451171875 +1064 -0.217071533203125 +1065 0.003692626953125 +1066 0.004547119140625 +1067 0.2257080078125 +1068 0.217926025390625 +1069 0.427154541015625 +1070 0.451385498046875 +1071 0.643218994140625 +1072 0.6968994140625 +1073 0.855926513671875 +1074 0.859954833984375 +1075 0.870361328125 +1076 0.870361328125 +1077 0.870361328125 +1078 0.870361328125 +1079 0.862762451171875 +1080 0.8629150390625 +1081 0.79669189453125 +1082 0.790863037109375 +1083 0.595794677734375 +1084 0.6055908203125 +1085 0.362152099609375 +1086 0.402740478515625 +1087 0.1270751953125 +1088 0.2022705078125 +1089 -0.086944580078125 +1090 0.006622314453125 +1091 -0.2784423828125 +1092 -0.214813232421875 +1093 -0.484832763671875 +1094 -0.4798583984375 +1095 -0.729583740234375 +1096 -0.7462158203125 +1097 -0.86688232421875 +1098 -0.86614990234375 +1099 -0.870391845703125 +1100 -0.870391845703125 +1101 -0.86859130859375 +1102 -0.870147705078125 +1103 -0.86279296875 +1104 -0.863006591796875 +1105 -0.817962646484375 +1106 -0.77215576171875 +1107 -0.6116943359375 +1108 -0.5177001953125 +1109 -0.3128662109375 +1110 -0.203094482421875 +1111 0.039398193359375 +1112 0.15142822265625 +1113 0.422821044921875 +1114 0.5162353515625 +1115 0.805145263671875 +1116 0.83343505859375 +1117 0.870361328125 +1118 0.870361328125 +1119 0.870361328125 +1120 0.870361328125 +1121 0.860015869140625 +1122 0.860992431640625 +1123 0.727935791015625 +1124 0.75042724609375 +1125 0.48114013671875 +1126 0.542449951171875 +1127 0.2059326171875 +1128 0.320953369140625 +1129 -0.06103515625 +1130 0.1038818359375 +1131 -0.29913330078125 +1132 -0.114471435546875 +1133 -0.516204833984375 +1134 -0.343231201171875 +1135 -0.7252197265625 +1136 -0.55914306640625 +1137 -0.85980224609375 +1138 -0.733428955078125 +1139 -0.870391845703125 +1140 -0.844024658203125 +1141 -0.870391845703125 +1142 -0.8544921875 +1143 -0.858062744140625 +1144 -0.769134521484375 +1145 -0.673004150390625 +1146 -0.64306640625 +1147 -0.42694091796875 +1148 -0.52520751953125 +1149 -0.2100830078125 +1150 -0.424163818359375 +1151 -0.0362548828125 +1152 -0.324798583984375 +1153 0.10943603515625 +1154 -0.219085693359375 +1155 0.23516845703125 +1156 -0.078948974609375 +1157 0.373687744140625 +1158 0.087554931640625 +1159 0.517791748046875 +1160 0.221160888671875 +1161 0.602783203125 +1162 0.32427978515625 +1163 0.635711669921875 +1164 0.42608642578125 +1165 0.655181884765625 +1166 0.5201416015625 +1167 0.65948486328125 +1168 0.603668212890625 +1169 0.651275634765625 +1170 0.661163330078125 +1171 0.61846923828125 +1172 0.667572021484375 +1173 0.53753662109375 +1174 0.615203857421875 +1175 0.404144287109375 +1176 0.5040283203125 +1177 0.22186279296875 +1178 0.343505859375 +1179 0.003997802734375 +1180 0.157379150390625 +1181 -0.22100830078125 +1182 -0.02935791015625 +1183 -0.42449951171875 +1184 -0.192413330078125 +1185 -0.579833984375 +1186 -0.2904052734375 +1187 -0.641876220703125 +1188 -0.326690673828125 +1189 -0.6177978515625 +1190 -0.357025146484375 +1191 -0.575531005859375 +1192 -0.387298583984375 +1193 -0.526336669921875 +1194 -0.37518310546875 +1195 -0.42645263671875 +1196 -0.30108642578125 +1197 -0.2581787109375 +1198 -0.202239990234375 +1199 -0.068695068359375 +1200 -0.11859130859375 +1201 0.09222412109375 +1202 -0.040740966796875 +1203 0.232147216796875 +1204 0.033233642578125 +1205 0.3509521484375 +1206 0.07086181640625 +1207 0.410064697265625 +1208 0.040618896484375 +1209 0.372955322265625 +1210 -0.044189453125 +1211 0.2554931640625 +1212 -0.14190673828125 +1213 0.10711669921875 +1214 -0.23785400390625 +1215 -0.052886962890625 +1216 -0.3013916015625 +1217 -0.186279296875 +1218 -0.283233642578125 +1219 -0.23291015625 +1220 -0.20123291015625 +1221 -0.209442138671875 +1222 -0.10968017578125 +1223 -0.174163818359375 +1224 -0.011566162109375 +1225 -0.126739501953125 +1226 0.106658935546875 +1227 -0.048126220703125 +1228 0.225921630859375 +1229 0.0426025390625 +1230 0.311187744140625 +1231 0.10748291015625 +1232 0.35638427734375 +1233 0.1409912109375 +1234 0.4080810546875 +1235 0.19708251953125 +1236 0.464691162109375 +1237 0.273651123046875 +1238 0.48089599609375 +1239 0.31768798828125 +1240 0.4686279296875 +1241 0.341094970703125 +1242 0.4510498046875 +1243 0.368011474609375 +1244 0.407989501953125 +1245 0.37249755859375 +1246 0.29522705078125 +1247 0.30072021484375 +1248 0.11474609375 +1249 0.1517333984375 +1250 -0.07855224609375 +1251 -0.01470947265625 +1252 -0.27313232421875 +1253 -0.1883544921875 +1254 -0.469879150390625 +1255 -0.372711181640625 +1256 -0.620147705078125 +1257 -0.51397705078125 +1258 -0.687469482421875 +1259 -0.57177734375 +1260 -0.66546630859375 +1261 -0.53948974609375 +1262 -0.569793701171875 +1263 -0.43511962890625 +1264 -0.433807373046875 +1265 -0.2962646484375 +1266 -0.2918701171875 +1267 -0.161102294921875 +1268 -0.15771484375 +1269 -0.0435791015625 +1270 -0.029754638671875 +1271 0.060394287109375 +1272 0.07745361328125 +1273 0.13665771484375 +1274 0.148468017578125 +1275 0.170135498046875 +1276 0.185089111328125 +1277 0.16552734375 +1278 0.21514892578125 +1279 0.15728759765625 +1280 0.241607666015625 +1281 0.150787353515625 +1282 0.241943359375 +1283 0.12200927734375 +1284 0.222625732421875 +1285 0.080108642578125 +1286 0.205413818359375 +1287 0.05126953125 +1288 0.213592529296875 +1289 0.062896728515625 +1290 0.2286376953125 +1291 0.09271240234375 +1292 0.2108154296875 +1293 0.092987060546875 +1294 0.1739501953125 +1295 0.07855224609375 +1296 0.132232666015625 +1297 0.06427001953125 +1298 0.0743408203125 +1299 0.0347900390625 +1300 0.000518798828125 +1301 -0.01171875 +1302 -0.070953369140625 +1303 -0.056060791015625 +1304 -0.10198974609375 +1305 -0.055511474609375 +1306 -0.09124755859375 +1307 -0.010467529296875 +1308 -0.083221435546875 +1309 0.02508544921875 +1310 -0.0985107421875 +1311 0.025665283203125 +1312 -0.11431884765625 +1313 0.017333984375 +1314 -0.128875732421875 +1315 0.00189208984375 +1316 -0.151702880859375 +1317 -0.03173828125 +1318 -0.17315673828125 +1319 -0.071502685546875 +1320 -0.209381103515625 +1321 -0.13543701171875 +1322 -0.25848388671875 +1323 -0.219970703125 +1324 -0.30096435546875 +1325 -0.300506591796875 +1326 -0.337677001953125 +1327 -0.376312255859375 +1328 -0.343597412109375 +1329 -0.416107177734375 +1330 -0.278778076171875 +1331 -0.371124267578125 +1332 -0.145416259765625 +1333 -0.242279052734375 +1334 0.021087646484375 +1335 -0.069732666015625 +1336 0.201995849609375 +1337 0.125640869140625 +1338 0.370208740234375 +1339 0.31268310546875 +1340 0.494476318359375 +1341 0.45501708984375 +1342 0.57659912109375 +1343 0.554779052734375 +1344 0.615753173828125 +1345 0.61065673828125 +1346 0.602630615234375 +1347 0.610931396484375 +1348 0.517578125 +1349 0.531463623046875 +1350 0.37530517578125 +1351 0.3883056640625 +1352 0.22222900390625 +1353 0.23468017578125 +1354 0.08062744140625 +1355 0.095245361328125 +1356 -0.026092529296875 +1357 -0.00396728515625 +1358 -0.08447265625 +1359 -0.04852294921875 +1360 -0.107635498046875 +1361 -0.055145263671875 +1362 -0.138916015625 +1363 -0.0758056640625 +1364 -0.20166015625 +1365 -0.138702392578125 +1366 -0.266021728515625 +1367 -0.209197998046875 +1368 -0.3333740234375 +1369 -0.289031982421875 +1370 -0.404449462890625 +1371 -0.37884521484375 +1372 -0.460662841796875 +1373 -0.456329345703125 +1374 -0.4984130859375 +1375 -0.51641845703125 +1376 -0.484649658203125 +1377 -0.519287109375 +1378 -0.4146728515625 +1379 -0.458251953125 +1380 -0.33331298828125 +1381 -0.384796142578125 +1382 -0.26263427734375 +1383 -0.323699951171875 +1384 -0.198822021484375 +1385 -0.269287109375 +1386 -0.12042236328125 +1387 -0.1951904296875 +1388 -0.027008056640625 +1389 -0.100006103515625 +1390 0.0579833984375 +1391 -0.01055908203125 +1392 0.159881591796875 +1393 0.1033935546875 +1394 0.28466796875 +1395 0.24908447265625 +1396 0.387115478515625 +1397 0.373199462890625 +1398 0.452484130859375 +1399 0.45806884765625 +1400 0.48785400390625 +1401 0.511474609375 +1402 0.52105712890625 +1403 0.565399169921875 +1404 0.545684814453125 +1405 0.61138916015625 +1406 0.511810302734375 +1407 0.5897216796875 +1408 0.411956787109375 +1409 0.4906005859375 +1410 0.2618408203125 +1411 0.33148193359375 +1412 0.09234619140625 +1413 0.147796630859375 +1414 -0.06036376953125 +1415 -0.01873779296875 +1416 -0.172088623046875 +1417 -0.140289306640625 +1418 -0.221282958984375 +1419 -0.191986083984375 +1420 -0.2166748046875 +1421 -0.184295654296875 +1422 -0.196197509765625 +1423 -0.161834716796875 +1424 -0.1956787109375 +1425 -0.166595458984375 +1426 -0.21148681640625 +1427 -0.19390869140625 +1428 -0.227691650390625 +1429 -0.22442626953125 +1430 -0.26324462890625 +1431 -0.279754638671875 +1432 -0.301055908203125 +1433 -0.3389892578125 +1434 -0.30126953125 +1435 -0.3543701171875 +1436 -0.28350830078125 +1437 -0.348175048828125 +1438 -0.253173828125 +1439 -0.32598876953125 +1440 -0.185699462890625 +1441 -0.2581787109375 +1442 -0.077362060546875 +1443 -0.139801025390625 +1444 0.05914306640625 +1445 0.014617919921875 +1446 0.171966552734375 +1447 0.144378662109375 +1448 0.236907958984375 +1449 0.221038818359375 +1450 0.276214599609375 +1451 0.27069091796875 +1452 0.290740966796875 +1453 0.294036865234375 +1454 0.298431396484375 +1455 0.311767578125 +1456 0.31268310546875 +1457 0.339141845703125 +1458 0.320404052734375 +1459 0.360260009765625 +1460 0.309783935546875 +1461 0.360504150390625 +1462 0.2550048828125 +1463 0.308380126953125 +1464 0.1380615234375 +1465 0.18170166015625 +1466 -0.019989013671875 +1467 0.0047607421875 +1468 -0.1793212890625 +1469 -0.17559814453125 +1470 -0.301727294921875 +1471 -0.3143310546875 +1472 -0.350311279296875 +1473 -0.36785888671875 +1474 -0.3470458984375 +1475 -0.36248779296875 +1476 -0.329986572265625 +1477 -0.343536376953125 +1478 -0.2916259765625 +1479 -0.3018798828125 +1480 -0.227081298828125 +1481 -0.231414794921875 +1482 -0.12451171875 +1483 -0.117645263671875 +1484 -0.011505126953125 +1485 0.007049560546875 +1486 0.06549072265625 +1487 0.087982177734375 +1488 0.117950439453125 +1489 0.13946533203125 +1490 0.156097412109375 +1491 0.17425537109375 +1492 0.175933837890625 +1493 0.188201904296875 +1494 0.1685791015625 +1495 0.171234130859375 +1496 0.12957763671875 +1497 0.118438720703125 +1498 0.081573486328125 +1499 0.05706787109375 +1500 0.026214599609375 +1501 -0.010711669921875 +1502 -0.041961669921875 +1503 -0.0914306640625 +1504 -0.103759765625 +1505 -0.162322998046875 +1506 -0.134796142578125 +1507 -0.194549560546875 +1508 -0.102203369140625 +1509 -0.1492919921875 +1510 -0.00152587890625 +1511 -0.02166748046875 +1512 0.1136474609375 +1513 0.124053955078125 +1514 0.17926025390625 +1515 0.211151123046875 +1516 0.196441650390625 +1517 0.240447998046875 +1518 0.191009521484375 +1519 0.242218017578125 +1520 0.171112060546875 +1521 0.2257080078125 +1522 0.139923095703125 +1523 0.194366455078125 +1524 0.070220947265625 +1525 0.115509033203125 +1526 -0.017913818359375 +1527 0.0128173828125 +1528 -0.074127197265625 +1529 -0.053802490234375 +1530 -0.12054443359375 +1531 -0.110626220703125 +1532 -0.192413330078125 +1533 -0.199493408203125 +1534 -0.26806640625 +1535 -0.29437255859375 +1536 -0.295135498046875 +1537 -0.33221435546875 +1538 -0.246734619140625 +1539 -0.27972412109375 +1540 -0.162811279296875 +1541 -0.185333251953125 +1542 -0.108062744140625 +1543 -0.128204345703125 +1544 -0.089111328125 +1545 -0.115692138671875 +1546 -0.081298828125 +1547 -0.116455078125 +1548 -0.06536865234375 +1549 -0.105926513671875 +1550 -0.017364501953125 +1551 -0.053955078125 +1552 0.06988525390625 +1553 0.048797607421875 +1554 0.159881591796875 +1555 0.157318115234375 +1556 0.204376220703125 +1557 0.212005615234375 +1558 0.207977294921875 +1559 0.218475341796875 +1560 0.219757080078125 +1561 0.23724365234375 +1562 0.2698974609375 +1563 0.30535888671875 +1564 0.32513427734375 +1565 0.38128662109375 +1566 0.3369140625 +1567 0.404449462890625 +1568 0.32147216796875 +1569 0.3944091796875 +1570 0.3094482421875 +1571 0.3885498046875 +1572 0.281707763671875 +1573 0.362640380859375 +1574 0.203765869140625 +1575 0.27362060546875 +1576 0.072418212890625 +1577 0.11712646484375 +1578 -0.070098876953125 +1579 -0.054901123046875 +1580 -0.181915283203125 +1581 -0.19085693359375 +1582 -0.258941650390625 +1583 -0.28570556640625 +1584 -0.30108642578125 +1585 -0.339263916015625 +1586 -0.329437255859375 +1587 -0.3775634765625 +1588 -0.380645751953125 +1589 -0.445709228515625 +1590 -0.447998046875 +1591 -0.535064697265625 +1592 -0.51837158203125 +1593 -0.629058837890625 +1594 -0.567779541015625 +1595 -0.697601318359375 +1596 -0.56683349609375 +1597 -0.70391845703125 +1598 -0.51141357421875 +1599 -0.6424560546875 +1600 -0.384063720703125 +1601 -0.491241455078125 +1602 -0.197479248046875 +1603 -0.265716552734375 +1604 0.0013427734375 +1605 -0.023712158203125 +1606 0.185577392578125 +1607 0.201751708984375 +1608 0.326995849609375 +1609 0.375823974609375 +1610 0.414764404296875 +1611 0.485076904296875 +1612 0.480712890625 +1613 0.56884765625 +1614 0.5311279296875 +1615 0.634765625 +1616 0.529693603515625 +1617 0.63763427734375 +1618 0.4674072265625 +1619 0.5660400390625 +1620 0.3865966796875 +1621 0.4720458984375 +1622 0.328948974609375 +1623 0.40692138671875 +1624 0.300537109375 +1625 0.3778076171875 +1626 0.29534912109375 +1627 0.376953125 +1628 0.287445068359375 +1629 0.371978759765625 +1630 0.236846923828125 +1631 0.313140869140625 +1632 0.1307373046875 +1633 0.184417724609375 +1634 -0.010223388671875 +1635 0.011199951171875 +1636 -0.157379150390625 +1637 -0.171051025390625 +1638 -0.290618896484375 +1639 -0.33740234375 +1640 -0.397216796875 +1641 -0.47198486328125 +1642 -0.465728759765625 +1643 -0.560394287109375 +1644 -0.478485107421875 +1645 -0.58056640625 +1646 -0.447845458984375 +1647 -0.54754638671875 +1648 -0.412200927734375 +1649 -0.508575439453125 +1650 -0.368438720703125 +1651 -0.459503173828125 +1652 -0.311981201171875 +1653 -0.394378662109375 +1654 -0.27484130859375 +1655 -0.35260009765625 +1656 -0.239044189453125 +1657 -0.31170654296875 +1658 -0.14471435546875 +1659 -0.197418212890625 +1660 0.00946044921875 +1661 -0.007965087890625 +1662 0.1837158203125 +1663 0.207489013671875 +1664 0.345977783203125 +1665 0.409210205078125 +1666 0.47601318359375 +1667 0.57208251953125 +1668 0.549560546875 +1669 0.66595458984375 +1670 0.540863037109375 +1671 0.65875244140625 +1672 0.463836669921875 +1673 0.56744384765625 +1674 0.3504638671875 +1675 0.431396484375 +1676 0.236358642578125 +1677 0.29443359375 +1678 0.14263916015625 +1679 0.182464599609375 +1680 0.04376220703125 +1681 0.06365966796875 +1682 -0.0714111328125 +1683 -0.075958251953125 +1684 -0.16485595703125 +1685 -0.189422607421875 +1686 -0.23260498046875 +1687 -0.271942138671875 +1688 -0.28997802734375 +1689 -0.342529296875 +1690 -0.307098388671875 +1691 -0.364166259765625 +1692 -0.276214599609375 +1693 -0.327239990234375 +1694 -0.233917236328125 +1695 -0.2769775390625 +1696 -0.212921142578125 +1697 -0.253692626953125 +1698 -0.20220947265625 +1699 -0.24365234375 +1700 -0.162811279296875 +1701 -0.1983642578125 +1702 -0.093597412109375 +1703 -0.116241455078125 +1704 -0.026641845703125 +1705 -0.036834716796875 +1706 0.033843994140625 +1707 0.034881591796875 +1708 0.08154296875 +1709 0.09124755859375 +1710 0.09747314453125 +1711 0.10888671875 +1712 0.112030029296875 +1713 0.125518798828125 +1714 0.1385498046875 +1715 0.15771484375 +1716 0.155029296875 +1717 0.17828369140625 +1718 0.148468017578125 +1719 0.17108154296875 +1720 0.113983154296875 +1721 0.129974365234375 +1722 0.073822021484375 +1723 0.082427978515625 +1724 0.02752685546875 +1725 0.027679443359375 +1726 -0.050140380859375 +1727 -0.065643310546875 +1728 -0.128173828125 +1729 -0.15936279296875 +1730 -0.173828125 +1731 -0.21307373046875 +1732 -0.193359375 +1733 -0.234649658203125 +1734 -0.1673583984375 +1735 -0.2001953125 +1736 -0.103363037109375 +1737 -0.119171142578125 +1738 -0.02813720703125 +1739 -0.024749755859375 +1740 0.060577392578125 +1741 0.085784912109375 +1742 0.135101318359375 +1743 0.178131103515625 +1744 0.165771484375 +1745 0.215576171875 +1746 0.163299560546875 +1747 0.211456298828125 +1748 0.13525390625 +1749 0.17523193359375 +1750 0.099212646484375 +1751 0.128753662109375 +1752 0.079254150390625 +1753 0.1019287109375 +1754 0.058807373046875 +1755 0.0743408203125 +1756 0.035552978515625 +1757 0.04327392578125 +1758 0.033203125 +1759 0.038177490234375 +1760 0.065582275390625 +1761 0.076263427734375 +1762 0.119293212890625 +1763 0.14105224609375 +1764 0.157012939453125 +1765 0.186431884765625 +1766 0.15960693359375 +1767 0.188812255859375 +1768 0.11962890625 +1769 0.1390380859375 +1770 0.040863037109375 +1771 0.041778564453125 +1772 -0.0576171875 +1773 -0.079437255859375 +1774 -0.17156982421875 +1775 -0.219390869140625 +1776 -0.29266357421875 +1777 -0.367828369140625 +1778 -0.396697998046875 +1779 -0.494873046875 +1780 -0.447784423828125 +1781 -0.556243896484375 +1782 -0.410919189453125 +1783 -0.508697509765625 +1784 -0.304901123046875 +1785 -0.3756103515625 +1786 -0.179656982421875 +1787 -0.218902587890625 +1788 -0.05548095703125 +1789 -0.063751220703125 +1790 0.06903076171875 +1791 0.091552734375 +1792 0.18499755859375 +1793 0.23602294921875 +1794 0.27093505859375 +1795 0.342987060546875 +1796 0.313232421875 +1797 0.39520263671875 +1798 0.309539794921875 +1799 0.389373779296875 +1800 0.259063720703125 +1801 0.324249267578125 +1802 0.180816650390625 +1803 0.224090576171875 +1804 0.1024169921875 +1805 0.124267578125 +1806 0.033538818359375 +1807 0.037078857421875 +1808 -0.004425048828125 +1809 -0.010101318359375 +1810 -0.013092041015625 +1811 -0.019439697265625 +1812 -0.017059326171875 +1813 -0.022796630859375 +1814 -0.0018310546875 +1815 -0.001556396484375 +1816 0.0419921875 +1817 0.056304931640625 +1818 0.080230712890625 +1819 0.106719970703125 +1820 0.07196044921875 +1821 0.096893310546875 +1822 0.029510498046875 +1823 0.042694091796875 +1824 -0.017791748046875 +1825 -0.018035888671875 +1826 -0.062591552734375 +1827 -0.07586669921875 +1828 -0.096099853515625 +1829 -0.11944580078125 +1830 -0.12689208984375 +1831 -0.15972900390625 +1832 -0.1595458984375 +1833 -0.202606201171875 +1834 -0.194488525390625 +1835 -0.24859619140625 +1836 -0.237548828125 +1837 -0.30517578125 +1838 -0.280853271484375 +1839 -0.36212158203125 +1840 -0.302734375 +1841 -0.39141845703125 +1842 -0.273895263671875 +1843 -0.35528564453125 +1844 -0.191497802734375 +1845 -0.249969482421875 +1846 -0.069091796875 +1847 -0.092864990234375 +1848 0.0723876953125 +1849 0.08905029296875 +1850 0.185943603515625 +1851 0.2352294921875 +1852 0.250732421875 +1853 0.318817138671875 +1854 0.2813720703125 +1855 0.358642578125 +1856 0.272491455078125 +1857 0.347747802734375 +1858 0.2237548828125 +1859 0.28564453125 +1860 0.174652099609375 +1861 0.223175048828125 +1862 0.1534423828125 +1863 0.196746826171875 +1864 0.139617919921875 +1865 0.179840087890625 +1866 0.120086669921875 +1867 0.155548095703125 +1868 0.116119384765625 +1869 0.151214599609375 +1870 0.12005615234375 +1871 0.156951904296875 +1872 0.10009765625 +1873 0.13177490234375 +1874 0.075775146484375 +1875 0.100799560546875 +1876 0.06500244140625 +1877 0.087127685546875 +1878 0.03997802734375 +1879 0.05487060546875 +1880 -0.009429931640625 +1881 -0.009002685546875 +1882 -0.08282470703125 +1883 -0.10400390625 +1884 -0.1796875 +1885 -0.229400634765625 +1886 -0.27703857421875 +1887 -0.35552978515625 +1888 -0.343505859375 +1889 -0.441925048828125 +1890 -0.367706298828125 +1891 -0.473846435546875 +1892 -0.360137939453125 +1893 -0.464813232421875 +1894 -0.324127197265625 +1895 -0.419097900390625 +1896 -0.25787353515625 +1897 -0.334320068359375 +1898 -0.1749267578125 +1899 -0.227935791015625 +1900 -0.093597412109375 +1901 -0.12347412109375 +1902 -0.019073486328125 +1903 -0.02764892578125 +1904 0.06268310546875 +1905 0.077667236328125 +1906 0.167816162109375 +1907 0.2132568359375 +1908 0.303863525390625 +1909 0.38885498046875 +1910 0.45404052734375 +1911 0.582794189453125 +1912 0.57098388671875 +1913 0.734039306640625 +1914 0.621795654296875 +1915 0.800140380859375 +1916 0.604339599609375 +1917 0.7783203125 +1918 0.5159912109375 +1919 0.6651611328125 +1920 0.35601806640625 +1921 0.45965576171875 +1922 0.1534423828125 +1923 0.199188232421875 +1924 -0.040802001953125 +1925 -0.050689697265625 +1926 -0.1824951171875 +1927 -0.23297119140625 +1928 -0.258056640625 +1929 -0.33013916015625 +1930 -0.287811279296875 +1931 -0.368408203125 +1932 -0.295928955078125 +1933 -0.378936767578125 +1934 -0.294281005859375 +1935 -0.376983642578125 +1936 -0.296173095703125 +1937 -0.37969970703125 +1938 -0.305023193359375 +1939 -0.391510009765625 +1940 -0.29986572265625 +1941 -0.385345458984375 +1942 -0.2657470703125 +1943 -0.3419189453125 +1944 -0.219512939453125 +1945 -0.28289794921875 +1946 -0.194793701171875 +1947 -0.251617431640625 +1948 -0.205657958984375 +1949 -0.266143798828125 +1950 -0.210906982421875 +1951 -0.273345947265625 +1952 -0.166748046875 +1953 -0.216796875 +1954 -0.09783935546875 +1955 -0.128265380859375 +1956 -0.051055908203125 +1957 -0.068145751953125 +1958 -0.031585693359375 +1959 -0.0430908203125 +1960 -0.017181396484375 +1961 -0.024444580078125 +1962 0.0177001953125 +1963 0.020721435546875 +1964 0.097991943359375 +1965 0.124481201171875 +1966 0.201202392578125 +1967 0.25787353515625 +1968 0.294921875 +1969 0.379119873046875 +1970 0.37274169921875 +1971 0.47991943359375 +1972 0.4097900390625 +1973 0.5281982421875 +1974 0.396148681640625 +1975 0.511138916015625 +1976 0.3531494140625 +1977 0.456207275390625 +1978 0.31500244140625 +1979 0.407470703125 +1980 0.296356201171875 +1981 0.383758544921875 +1982 0.27532958984375 +1983 0.35687255859375 +1984 0.240325927734375 +1985 0.31182861328125 +1986 0.19305419921875 +1987 0.250885009765625 +1988 0.1268310546875 +1989 0.1654052734375 +1990 0.026031494140625 +1991 0.035247802734375 +1992 -0.111297607421875 +1993 -0.142059326171875 +1994 -0.261199951171875 +1995 -0.33563232421875 +1996 -0.415191650390625 +1997 -0.5345458984375 +1998 -0.56011962890625 +1999 -0.72186279296875 +2000 -0.648773193359375 +2001 -0.836669921875 +2002 -0.645233154296875 +2003 -0.8326416015625 +2004 -0.56494140625 +2005 -0.7296142578125 +2006 -0.4505615234375 +2007 -0.582550048828125 +2008 -0.339813232421875 +2009 -0.440093994140625 +2010 -0.249847412109375 +2011 -0.324310302734375 +2012 -0.154510498046875 +2013 -0.20147705078125 +2014 -0.032867431640625 +2015 -0.044647216796875 +2016 0.08233642578125 +2017 0.103973388671875 +2018 0.15850830078125 +2019 0.202392578125 +2020 0.2064208984375 +2021 0.264495849609375 +2022 0.263824462890625 +2023 0.338897705078125 +2024 0.3448486328125 +2025 0.443817138671875 +2026 0.42303466796875 +2027 0.545074462890625 +2028 0.478668212890625 +2029 0.6173095703125 +2030 0.50555419921875 +2031 0.6524658203125 +2032 0.513702392578125 +2033 0.66339111328125 +2034 0.5078125 +2035 0.6561279296875 +2036 0.469329833984375 +2037 0.606781005859375 +2038 0.38726806640625 +2039 0.501190185546875 +2040 0.272064208984375 +2041 0.352783203125 +2042 0.135345458984375 +2043 0.176544189453125 +2044 -0.028533935546875 +2045 -0.034820556640625 +2046 -0.201629638671875 +2047 -0.258209228515625 +2048 -0.344451904296875 +2049 -0.44244384765625 +2050 -0.4473876953125 +2051 -0.5753173828125 +2052 -0.50689697265625 +2053 -0.65203857421875 +2054 -0.5 +2055 -0.641632080078125 +2056 -0.440277099609375 +2057 -0.562164306640625 +2058 -0.36090087890625 +2059 -0.458038330078125 +2060 -0.277923583984375 +2061 -0.350555419921875 +2062 -0.20709228515625 +2063 -0.260528564453125 +2064 -0.15179443359375 +2065 -0.192108154296875 +2066 -0.109771728515625 +2067 -0.141937255859375 +2068 -0.075469970703125 +2069 -0.1021728515625 +2070 -0.041748046875 +2071 -0.062896728515625 +2072 0.00018310546875 +2073 -0.011932373046875 +2074 0.059173583984375 +2075 0.062835693359375 +2076 0.125640869140625 +2077 0.148712158203125 +2078 0.19647216796875 +2079 0.241729736328125 +2080 0.277008056640625 +2081 0.34912109375 +2082 0.357177734375 +2083 0.457305908203125 +2084 0.42034912109375 +2085 0.54388427734375 +2086 0.439849853515625 +2087 0.5728759765625 +2088 0.387786865234375 +2089 0.506591796875 +2090 0.268951416015625 +2091 0.351226806640625 +2092 0.11309814453125 +2093 0.146514892578125 +2094 -0.040679931640625 +2095 -0.05523681640625 +2096 -0.1640625 +2097 -0.21624755859375 +2098 -0.255645751953125 +2099 -0.334930419921875 +2100 -0.30908203125 +2101 -0.402984619140625 +2102 -0.33978271484375 +2103 -0.4412841796875 +2104 -0.3818359375 +2105 -0.49578857421875 +2106 -0.43048095703125 +2107 -0.5601806640625 +2108 -0.460601806640625 +2109 -0.600738525390625 +2110 -0.447509765625 +2111 -0.584228515625 +2112 -0.367950439453125 +2113 -0.47930908203125 +2114 -0.21710205078125 +2115 -0.27935791015625 +2116 -0.01336669921875 +2117 -0.0089111328125 +2118 0.196044921875 +2119 0.268798828125 +2120 0.35821533203125 +2121 0.482818603515625 +2122 0.451080322265625 +2123 0.60369873046875 +2124 0.488555908203125 +2125 0.650421142578125 +2126 0.50103759765625 +2127 0.66400146484375 +2128 0.486175537109375 +2129 0.6414794921875 +2130 0.436248779296875 +2131 0.572540283203125 +2132 0.38165283203125 +2133 0.498138427734375 +2134 0.338104248046875 +2135 0.439453125 +2136 0.2900390625 +2137 0.375518798828125 +2138 0.21380615234375 +2139 0.274505615234375 +2140 0.08892822265625 +2141 0.1087646484375 +2142 -0.067901611328125 +2143 -0.099395751953125 +2144 -0.232940673828125 +2145 -0.3182373046875 +2146 -0.406982421875 +2147 -0.5489501953125 +2148 -0.57666015625 +2149 -0.7738037109375 +2150 -0.702423095703125 +2151 -0.86383056640625 +2152 -0.759429931640625 +2153 -0.870391845703125 +2154 -0.760772705078125 +2155 -0.86895751953125 +2156 -0.716156005859375 +2157 -0.861053466796875 +2158 -0.612640380859375 +2159 -0.765869140625 +2160 -0.441802978515625 +2161 -0.5301513671875 +2162 -0.208953857421875 +2163 -0.214691162109375 +2164 0.0538330078125 +2165 0.137359619140625 +2166 0.308349609375 +2167 0.474822998046875 +2168 0.528106689453125 +2169 0.76239013671875 +2170 0.692901611328125 +2171 0.867462158203125 +2172 0.802978515625 +2173 0.870361328125 +2174 0.849609375 +2175 0.86480712890625 +2176 0.836669921875 +2177 0.831817626953125 +2178 0.78216552734375 +2179 0.677581787109375 +2180 0.690338134765625 +2181 0.495880126953125 +2182 0.574920654296875 +2183 0.30767822265625 +2184 0.4375 +2185 0.116180419921875 +2186 0.254425048828125 +2187 -0.110748291015625 +2188 0.02056884765625 +2189 -0.381805419921875 +2190 -0.232208251953125 +2191 -0.6572265625 +2192 -0.459320068359375 +2193 -0.857421875 +2194 -0.62872314453125 +2195 -0.870391845703125 +2196 -0.73504638671875 +2197 -0.870391845703125 +2198 -0.7982177734375 +2199 -0.86444091796875 +2200 -0.84466552734375 +2201 -0.85723876953125 +2202 -0.855194091796875 +2203 -0.790008544921875 +2204 -0.80572509765625 +2205 -0.62847900390625 +2206 -0.677398681640625 +2207 -0.3956298828125 +2208 -0.50006103515625 +2209 -0.126708984375 +2210 -0.294036865234375 +2211 0.150115966796875 +2212 -0.068023681640625 +2213 0.424041748046875 +2214 0.15789794921875 +2215 0.670623779296875 +2216 0.354888916015625 +2217 0.854522705078125 +2218 0.509765625 +2219 0.866485595703125 +2220 0.610992431640625 +2221 0.86920166015625 +2222 0.6719970703125 +2223 0.8653564453125 +2224 0.702667236328125 +2225 0.857147216796875 +2226 0.700714111328125 +2227 0.766845703125 +2228 0.669891357421875 +2229 0.628509521484375 +2230 0.605072021484375 +2231 0.462127685546875 +2232 0.525390625 +2233 0.297210693359375 +2234 0.44000244140625 +2235 0.14862060546875 +2236 0.3319091796875 +2237 -0.00537109375 +2238 0.2066650390625 +2239 -0.15753173828125 +2240 0.06158447265625 +2241 -0.31304931640625 +2242 -0.11370849609375 +2243 -0.48876953125 +2244 -0.2843017578125 +2245 -0.6416015625 +2246 -0.431732177734375 +2247 -0.751373291015625 +2248 -0.573089599609375 +2249 -0.84619140625 +2250 -0.69732666015625 +2251 -0.861297607421875 +2252 -0.779693603515625 +2253 -0.863250732421875 +2254 -0.796600341796875 +2255 -0.856597900390625 +2256 -0.75701904296875 +2257 -0.7498779296875 +2258 -0.703948974609375 +2259 -0.624542236328125 +2260 -0.620941162109375 +2261 -0.47808837890625 +2262 -0.464508056640625 +2263 -0.253387451171875 +2264 -0.268585205078125 +2265 0.003692626953125 +2266 -0.08404541015625 +2267 0.2257080078125 +2268 0.098358154296875 +2269 0.427154541015625 +2270 0.30267333984375 +2271 0.643218994140625 +2272 0.5216064453125 +2273 0.855926513671875 +2274 0.71197509765625 +2275 0.870361328125 +2276 0.836761474609375 +2277 0.870361328125 +2278 0.859588623046875 +2279 0.862762451171875 +2280 0.859771728515625 +2281 0.79669189453125 +2282 0.835174560546875 +2283 0.595794677734375 +2284 0.719207763671875 +2285 0.362152099609375 +2286 0.57598876953125 +2287 0.1270751953125 +2288 0.4212646484375 +2289 -0.086944580078125 +2290 0.256622314453125 +2291 -0.2784423828125 +2292 0.056243896484375 +2293 -0.484832763671875 +2294 -0.19403076171875 +2295 -0.729583740234375 +2296 -0.45648193359375 +2297 -0.86688232421875 +2298 -0.68389892578125 +2299 -0.870391845703125 +2300 -0.856475830078125 +2301 -0.86859130859375 +2302 -0.870391845703125 +2303 -0.86279296875 +2304 -0.870391845703125 +2305 -0.817962646484375 +2306 -0.860198974609375 +2307 -0.6116943359375 +2308 -0.718719482421875 +2309 -0.3128662109375 +2310 -0.463897705078125 +2311 0.039398193359375 +2312 -0.159515380859375 +2313 0.422821044921875 +2314 0.1685791015625 +2315 0.805145263671875 +2316 0.470794677734375 +2317 0.870361328125 +2318 0.706451416015625 +2319 0.870361328125 +2320 0.85595703125 +2321 0.860015869140625 +2322 0.8651123046875 +2323 0.727935791015625 +2324 0.8656005859375 +2325 0.48114013671875 +2326 0.859619140625 +2327 0.2059326171875 +2328 0.8074951171875 +2329 -0.06103515625 +2330 0.684539794921875 +2331 -0.29913330078125 +2332 0.526153564453125 +2333 -0.516204833984375 +2334 0.324798583984375 +2335 -0.7252197265625 +2336 0.101287841796875 +2337 -0.85980224609375 +2338 -0.1173095703125 +2339 -0.870391845703125 +2340 -0.3079833984375 +2341 -0.870391845703125 +2342 -0.434814453125 +2343 -0.858062744140625 +2344 -0.494354248046875 +2345 -0.673004150390625 +2346 -0.52423095703125 +2347 -0.42694091796875 +2348 -0.5570068359375 +2349 -0.2100830078125 +2350 -0.592803955078125 +2351 -0.0362548828125 +2352 -0.613128662109375 +2353 0.10943603515625 +2354 -0.60638427734375 +2355 0.23516845703125 +2356 -0.54595947265625 +2357 0.373687744140625 +2358 -0.4361572265625 +2359 0.517791748046875 +2360 -0.324737548828125 +2361 0.602783203125 +2362 -0.210723876953125 +2363 0.635711669921875 +2364 -0.072723388671875 +2365 0.655181884765625 +2366 0.080322265625 +2367 0.65948486328125 +2368 0.241363525390625 +2369 0.651275634765625 +2370 0.3922119140625 +2371 0.61846923828125 +2372 0.50640869140625 +2373 0.53753662109375 +2374 0.571563720703125 +2375 0.404144287109375 +2376 0.581817626953125 +2377 0.22186279296875 +2378 0.53961181640625 +2379 0.003997802734375 +2380 0.459808349609375 +2381 -0.22100830078125 +2382 0.359344482421875 +2383 -0.42449951171875 +2384 0.255828857421875 +2385 -0.579833984375 +2386 0.18206787109375 +2387 -0.641876220703125 +2388 0.1356201171875 +2389 -0.6177978515625 +2390 0.07257080078125 +2391 -0.575531005859375 +2392 -0.0091552734375 +2393 -0.526336669921875 +2394 -0.071380615234375 +2395 -0.42645263671875 +2396 -0.093719482421875 +2397 -0.2581787109375 +2398 -0.101776123046875 +2399 -0.068695068359375 +2400 -0.123138427734375 +2401 0.09222412109375 +2402 -0.145233154296875 +2403 0.232147216796875 +2404 -0.161895751953125 +2405 0.3509521484375 +2406 -0.1956787109375 +2407 0.410064697265625 +2408 -0.2691650390625 +2409 0.372955322265625 +2410 -0.36932373046875 +2411 0.2554931640625 +2412 -0.4609375 +2413 0.10711669921875 +2414 -0.531951904296875 +2415 -0.052886962890625 +2416 -0.55828857421875 +2417 -0.186279296875 +2418 -0.501617431640625 +2419 -0.23291015625 +2420 -0.379302978515625 +2421 -0.209442138671875 +2422 -0.239044189453125 +2423 -0.174163818359375 +2424 -0.087188720703125 +2425 -0.126739501953125 +2426 0.083282470703125 +2427 -0.048126220703125 +2428 0.252685546875 +2429 0.0426025390625 +2430 0.3885498046875 +2431 0.10748291015625 +2432 0.48248291015625 +2433 0.1409912109375 +2434 0.56964111328125 +2435 0.19708251953125 +2436 0.646636962890625 +2437 0.273651123046875 +2438 0.675201416015625 +2439 0.31768798828125 +2440 0.6646728515625 +2441 0.341094970703125 +2442 0.634429931640625 +2443 0.368011474609375 +2444 0.569305419921875 +2445 0.37249755859375 +2446 0.435272216796875 +2447 0.30072021484375 +2448 0.236572265625 +2449 0.1517333984375 +2450 0.02105712890625 +2451 -0.01470947265625 +2452 -0.198486328125 +2453 -0.1883544921875 +2454 -0.41937255859375 +2455 -0.372711181640625 +2456 -0.598602294921875 +2457 -0.51397705078125 +2458 -0.703460693359375 +2459 -0.57177734375 +2460 -0.726165771484375 +2461 -0.53948974609375 +2462 -0.677581787109375 +2463 -0.43511962890625 +2464 -0.583648681640625 +2465 -0.2962646484375 +2466 -0.471893310546875 +2467 -0.161102294921875 +2468 -0.353668212890625 +2469 -0.0435791015625 +2470 -0.228515625 +2471 0.060394287109375 +2472 -0.1097412109375 +2473 0.13665771484375 +2474 -0.011962890625 +2475 0.170135498046875 +2476 0.0638427734375 +2477 0.16552734375 +2478 0.137725830078125 +2479 0.15728759765625 +2480 0.209136962890625 +2481 0.150787353515625 +2482 0.2569580078125 +2483 0.12200927734375 +2484 0.284210205078125 +2485 0.080108642578125 +2486 0.3067626953125 +2487 0.05126953125 +2488 0.3421630859375 +2489 0.062896728515625 +2490 0.37353515625 +2491 0.09271240234375 +2492 0.3668212890625 +2493 0.092987060546875 +2494 0.333465576171875 +2495 0.07855224609375 +2496 0.2857666015625 +2497 0.06427001953125 +2498 0.215240478515625 +2499 0.0347900390625 +2500 0.12359619140625 +2501 -0.01171875 +2502 0.0279541015625 +2503 -0.056060791015625 +2504 -0.037567138671875 +2505 -0.055511474609375 +2506 -0.069580078125 +2507 -0.010467529296875 +2508 -0.10308837890625 +2509 0.02508544921875 +2510 -0.153167724609375 +2511 0.025665283203125 +2512 -0.198760986328125 +2513 0.017333984375 +2514 -0.23675537109375 +2515 0.00189208984375 +2516 -0.27392578125 +2517 -0.03173828125 +2518 -0.3013916015625 +2519 -0.071502685546875 +2520 -0.332427978515625 +2521 -0.13543701171875 +2522 -0.36566162109375 +2523 -0.219970703125 +2524 -0.38543701171875 +2525 -0.300506591796875 +2526 -0.393585205078125 +2527 -0.376312255859375 +2528 -0.370513916015625 +2529 -0.416107177734375 +2530 -0.284515380859375 +2531 -0.371124267578125 +2532 -0.13922119140625 +2533 -0.242279052734375 +2534 0.033843994140625 +2535 -0.069732666015625 +2536 0.2171630859375 +2537 0.125640869140625 +2538 0.38629150390625 +2539 0.31268310546875 +2540 0.513641357421875 +2541 0.45501708984375 +2542 0.599578857421875 +2543 0.554779052734375 +2544 0.6427001953125 +2545 0.61065673828125 +2546 0.634796142578125 +2547 0.610931396484375 +2548 0.559478759765625 +2549 0.531463623046875 +2550 0.42950439453125 +2551 0.3883056640625 +2552 0.2845458984375 +2553 0.23468017578125 +2554 0.144317626953125 +2555 0.095245361328125 +2556 0.02972412109375 +2557 -0.00396728515625 +2558 -0.046478271484375 +2559 -0.04852294921875 +2560 -0.09393310546875 +2561 -0.055145263671875 +2562 -0.14727783203125 +2563 -0.0758056640625 +2564 -0.22430419921875 +2565 -0.138702392578125 +2566 -0.299041748046875 +2567 -0.209197998046875 +2568 -0.37139892578125 +2569 -0.289031982421875 +2570 -0.441131591796875 +2571 -0.37884521484375 +2572 -0.492462158203125 +2573 -0.456329345703125 +2574 -0.52227783203125 +2575 -0.51641845703125 +2576 -0.50360107421875 +2577 -0.519287109375 +2578 -0.43310546875 +2579 -0.458251953125 +2580 -0.348541259765625 +2581 -0.384796142578125 +2582 -0.269195556640625 +2583 -0.323699951171875 +2584 -0.19317626953125 +2585 -0.269287109375 +2586 -0.104156494140625 +2587 -0.1951904296875 +2588 -0.003173828125 +2589 -0.100006103515625 +2590 0.08917236328125 +2591 -0.01055908203125 +2592 0.192535400390625 +2593 0.1033935546875 +2594 0.310882568359375 +2595 0.24908447265625 +2596 0.406219482421875 +2597 0.373199462890625 +2598 0.4659423828125 +2599 0.45806884765625 +2600 0.495697021484375 +2601 0.511474609375 +2602 0.518524169921875 +2603 0.565399169921875 +2604 0.529541015625 +2605 0.61138916015625 +2606 0.48828125 +2607 0.5897216796875 +2608 0.389404296875 +2609 0.4906005859375 +2610 0.24688720703125 +2611 0.33148193359375 +2612 0.087249755859375 +2613 0.147796630859375 +2614 -0.05859375 +2615 -0.01873779296875 +2616 -0.16961669921875 +2617 -0.140289306640625 +2618 -0.227081298828125 +2619 -0.191986083984375 +2620 -0.2373046875 +2621 -0.184295654296875 +2622 -0.2308349609375 +2623 -0.161834716796875 +2624 -0.236724853515625 +2625 -0.166595458984375 +2626 -0.25177001953125 +2627 -0.19390869140625 +2628 -0.262847900390625 +2629 -0.22442626953125 +2630 -0.285797119140625 +2631 -0.279754638671875 +2632 -0.307037353515625 +2633 -0.3389892578125 +2634 -0.29437255859375 +2635 -0.3543701171875 +2636 -0.264739990234375 +2637 -0.348175048828125 +2638 -0.223480224609375 +2639 -0.32598876953125 +2640 -0.151275634765625 +2641 -0.2581787109375 +2642 -0.04595947265625 +2643 -0.139801025390625 +2644 0.081146240234375 +2645 0.014617919921875 +2646 0.186553955078125 +2647 0.144378662109375 +2648 0.249725341796875 +2649 0.221038818359375 +2650 0.288543701171875 +2651 0.27069091796875 +2652 0.303436279296875 +2653 0.294036865234375 +2654 0.30914306640625 +2655 0.311767578125 +2656 0.316802978515625 +2657 0.339141845703125 +2658 0.315765380859375 +2659 0.360260009765625 +2660 0.296875 +2661 0.360504150390625 +2662 0.239898681640625 +2663 0.308380126953125 +2664 0.131072998046875 +2665 0.18170166015625 +2666 -0.011688232421875 +2667 0.0047607421875 +2668 -0.155303955078125 +2669 -0.17559814453125 +2670 -0.268035888671875 +2671 -0.3143310546875 +2672 -0.319305419921875 +2673 -0.36785888671875 +2674 -0.326263427734375 +2675 -0.36248779296875 +2676 -0.319305419921875 +2677 -0.343536376953125 +2678 -0.29205322265625 +2679 -0.3018798828125 +2680 -0.24041748046875 +2681 -0.231414794921875 +2682 -0.154876708984375 +2683 -0.117645263671875 +2684 -0.058013916015625 +2685 0.007049560546875 +2686 0.012176513671875 +2687 0.087982177734375 +2688 0.06451416015625 +2689 0.13946533203125 +2690 0.106658935546875 +2691 0.17425537109375 +2692 0.134735107421875 +2693 0.188201904296875 +2694 0.140869140625 +2695 0.171234130859375 +2696 0.120819091796875 +2697 0.118438720703125 +2698 0.09228515625 +2699 0.05706787109375 +2700 0.056060791015625 +2701 -0.010711669921875 +2702 0.00726318359375 +2703 -0.0914306640625 +2704 -0.038787841796875 +2705 -0.162322998046875 +2706 -0.0625 +2707 -0.194549560546875 +2708 -0.03729248046875 +2709 -0.1492919921875 +2710 0.04058837890625 +2711 -0.02166748046875 +2712 0.128021240234375 +2713 0.124053955078125 +2714 0.173553466796875 +2715 0.211151123046875 +2716 0.17852783203125 +2717 0.240447998046875 +2718 0.16436767578125 +2719 0.242218017578125 +2720 0.13824462890625 +2721 0.2257080078125 +2722 0.103302001953125 +2723 0.194366455078125 +2724 0.03802490234375 +2725 0.115509033203125 +2726 -0.0408935546875 +2727 0.0128173828125 +2728 -0.09228515625 +2729 -0.053802490234375 +2730 -0.1337890625 +2731 -0.110626220703125 +2732 -0.19378662109375 +2733 -0.199493408203125 +2734 -0.254730224609375 +2735 -0.29437255859375 +2736 -0.27398681640625 +2737 -0.33221435546875 +2738 -0.229400634765625 +2739 -0.27972412109375 +2740 -0.154449462890625 +2741 -0.185333251953125 +2742 -0.10357666015625 +2743 -0.128204345703125 +2744 -0.08245849609375 +2745 -0.115692138671875 +2746 -0.07049560546875 +2747 -0.116455078125 +2748 -0.051666259765625 +2749 -0.105926513671875 +2750 -0.006072998046875 +2751 -0.053955078125 +2752 0.07208251953125 +2753 0.048797607421875 +2754 0.15179443359375 +2755 0.157318115234375 +2756 0.192291259765625 +2757 0.212005615234375 +2758 0.197265625 +2759 0.218475341796875 +2760 0.207916259765625 +2761 0.23724365234375 +2762 0.2496337890625 +2763 0.30535888671875 +2764 0.29449462890625 +2765 0.38128662109375 +2766 0.301727294921875 +2767 0.404449462890625 +2768 0.28515625 +2769 0.3944091796875 +2770 0.270782470703125 +2771 0.3885498046875 +2772 0.24273681640625 +2773 0.362640380859375 +2774 0.172271728515625 +2775 0.27362060546875 +2776 0.056976318359375 +2777 0.11712646484375 +2778 -0.0673828125 +2779 -0.054901123046875 +2780 -0.16534423828125 +2781 -0.19085693359375 +2782 -0.233245849609375 +2783 -0.28570556640625 +2784 -0.270843505859375 +2785 -0.339263916015625 +2786 -0.29583740234375 +2787 -0.3775634765625 +2788 -0.339019775390625 +2789 -0.445709228515625 +2790 -0.394775390625 +2791 -0.535064697265625 +2792 -0.452117919921875 +2793 -0.629058837890625 +2794 -0.490997314453125 +2795 -0.697601318359375 +2796 -0.48687744140625 +2797 -0.70391845703125 +2798 -0.43646240234375 +2799 -0.6424560546875 +2800 -0.32525634765625 +2801 -0.491241455078125 +2802 -0.164215087890625 +2803 -0.265716552734375 +2804 0.00689697265625 +2805 -0.023712158203125 +2806 0.165313720703125 +2807 0.201751708984375 +2808 0.287078857421875 +2809 0.375823974609375 +2810 0.362945556640625 +2811 0.485076904296875 +2812 0.419647216796875 +2813 0.56884765625 +2814 0.462432861328125 +2815 0.634765625 +2816 0.461212158203125 +2817 0.63763427734375 +2818 0.409210205078125 +2819 0.5660400390625 +2820 0.341064453125 +2821 0.4720458984375 +2822 0.290252685546875 +2823 0.40692138671875 +2824 0.26177978515625 +2825 0.3778076171875 +2826 0.251068115234375 +2827 0.376953125 +2828 0.237640380859375 +2829 0.371978759765625 +2830 0.18975830078125 +2831 0.313140869140625 +2832 0.0975341796875 +2833 0.184417724609375 +2834 -0.022125244140625 +2835 0.011199951171875 +2836 -0.1458740234375 +2837 -0.171051025390625 +2838 -0.257293701171875 +2839 -0.33740234375 +2840 -0.345977783203125 +2841 -0.47198486328125 +2842 -0.402557373046875 +2843 -0.560394287109375 +2844 -0.412841796875 +2845 -0.58056640625 +2846 -0.38677978515625 +2847 -0.54754638671875 +2848 -0.35528564453125 +2849 -0.508575439453125 +2850 -0.3160400390625 +2851 -0.459503173828125 +2852 -0.265625 +2853 -0.394378662109375 +2854 -0.230010986328125 +2855 -0.35260009765625 +2856 -0.195098876953125 +2857 -0.31170654296875 +2858 -0.113250732421875 +2859 -0.197418212890625 +2860 0.016265869140625 +2861 -0.007965087890625 +2862 0.1612548828125 +2863 0.207489013671875 +2864 0.29571533203125 +2865 0.409210205078125 +2866 0.403228759765625 +2867 0.57208251953125 +2868 0.4642333984375 +2869 0.66595458984375 +2870 0.45794677734375 +2871 0.65875244140625 +2872 0.3955078125 +2873 0.56744384765625 +2874 0.302642822265625 +2875 0.431396484375 +2876 0.208038330078125 +2877 0.29443359375 +2878 0.128875732421875 +2879 0.182464599609375 +2880 0.044891357421875 +2881 0.06365966796875 +2882 -0.05255126953125 +2883 -0.075958251953125 +2884 -0.132659912109375 +2885 -0.189422607421875 +2886 -0.19195556640625 +2887 -0.271942138671875 +2888 -0.242462158203125 +2889 -0.342529296875 +2890 -0.260009765625 +2891 -0.364166259765625 +2892 -0.238189697265625 +2893 -0.327239990234375 +2894 -0.20623779296875 +2895 -0.2769775390625 +2896 -0.1903076171875 +2897 -0.253692626953125 +2898 -0.181549072265625 +2899 -0.24365234375 +2900 -0.14874267578125 +2901 -0.1983642578125 +2902 -0.091064453125 +2903 -0.116241455078125 +2904 -0.034393310546875 +2905 -0.036834716796875 +2906 0.0177001953125 +2907 0.034881591796875 +2908 0.0599365234375 +2909 0.09124755859375 +2910 0.076904296875 +2911 0.10888671875 +2912 0.092681884765625 +2913 0.125518798828125 +2914 0.117767333984375 +2915 0.15771484375 +2916 0.13433837890625 +2917 0.17828369140625 +2918 0.13177490234375 +2919 0.17108154296875 +2920 0.106048583984375 +2921 0.129974365234375 +2922 0.074920654296875 +2923 0.082427978515625 +2924 0.037994384765625 +2925 0.027679443359375 +2926 -0.024932861328125 +2927 -0.065643310546875 +2928 -0.0889892578125 +2929 -0.15936279296875 +2930 -0.127777099609375 +2931 -0.21307373046875 +2932 -0.14617919921875 +2933 -0.234649658203125 +2934 -0.12847900390625 +2935 -0.2001953125 +2936 -0.08050537109375 +2937 -0.119171142578125 +2938 -0.0235595703125 +2939 -0.024749755859375 +2940 0.04437255859375 +2941 0.085784912109375 +2942 0.101226806640625 +2943 0.178131103515625 +2944 0.123382568359375 +2945 0.215576171875 +2946 0.119537353515625 +2947 0.211456298828125 +2948 0.09588623046875 +2949 0.17523193359375 +2950 0.066558837890625 +2951 0.128753662109375 +2952 0.05084228515625 +2953 0.1019287109375 +2954 0.035430908203125 +2955 0.0743408203125 +2956 0.01837158203125 +2957 0.04327392578125 +2958 0.01861572265625 +2959 0.038177490234375 +2960 0.047088623046875 +2961 0.076263427734375 +2962 0.0928955078125 +2963 0.14105224609375 +2964 0.12591552734375 +2965 0.186431884765625 +2966 0.13067626953125 +2967 0.188812255859375 +2968 0.101104736328125 +2969 0.1390380859375 +2970 0.040069580078125 +2971 0.041778564453125 +2972 -0.0372314453125 +2973 -0.079437255859375 +2974 -0.12750244140625 +2975 -0.219390869140625 +2976 -0.224029541015625 +2977 -0.367828369140625 +2978 -0.30743408203125 +2979 -0.494873046875 +2980 -0.348968505859375 +2981 -0.556243896484375 +2982 -0.32049560546875 +2983 -0.508697509765625 +2984 -0.23699951171875 +2985 -0.3756103515625 +2986 -0.13848876953125 +2987 -0.218902587890625 +2988 -0.04107666015625 +2989 -0.063751220703125 +2990 0.056488037109375 +2991 0.091552734375 +2992 0.14727783203125 +2993 0.23602294921875 +2994 0.214141845703125 +2995 0.342987060546875 +2996 0.246063232421875 +2997 0.39520263671875 +2998 0.240997314453125 +2999 0.389373779296875 +3000 0.19818115234375 +3001 0.324249267578125 +3002 0.133331298828125 +3003 0.224090576171875 +3004 0.0693359375 +3005 0.124267578125 +3006 0.01409912109375 +3007 0.037078857421875 +3008 -0.014678955078125 +3009 -0.010101318359375 +3010 -0.0185546875 +3011 -0.019439697265625 +3012 -0.018280029296875 +3013 -0.022796630859375 +3014 -0.001953125 +3015 -0.001556396484375 +3016 0.038055419921875 +3017 0.056304931640625 +3018 0.07305908203125 +3019 0.106719970703125 +3020 0.068756103515625 +3021 0.096893310546875 +3022 0.035308837890625 +3023 0.042694091796875 +3024 -0.002838134765625 +3025 -0.018035888671875 +3026 -0.03961181640625 +3027 -0.07586669921875 +3028 -0.06768798828125 +3029 -0.11944580078125 +3030 -0.094146728515625 +3031 -0.15972900390625 +3032 -0.122772216796875 +3033 -0.202606201171875 +3034 -0.15380859375 +3035 -0.24859619140625 +3036 -0.1920166015625 +3037 -0.30517578125 +3038 -0.230743408203125 +3039 -0.36212158203125 +3040 -0.251708984375 +3041 -0.39141845703125 +3042 -0.23028564453125 +3043 -0.35528564453125 +3044 -0.163970947265625 +3045 -0.249969482421875 +3046 -0.06396484375 +3047 -0.092864990234375 +3048 0.0523681640625 +3049 0.08905029296875 +3050 0.145904541015625 +3051 0.2352294921875 +3052 0.199249267578125 +3053 0.318817138671875 +3054 0.22467041015625 +3055 0.358642578125 +3056 0.2176513671875 +3057 0.347747802734375 +3058 0.1778564453125 +3059 0.28564453125 +3060 0.138214111328125 +3061 0.223175048828125 +3062 0.122222900390625 +3063 0.196746826171875 +3064 0.1126708984375 +3065 0.179840087890625 +3066 0.0985107421875 +3067 0.155548095703125 +3068 0.097381591796875 +3069 0.151214599609375 +3070 0.102783203125 +3071 0.156951904296875 +3072 0.08819580078125 +3073 0.13177490234375 +3074 0.069366455078125 +3075 0.100799560546875 +3076 0.06103515625 +3077 0.087127685546875 +3078 0.040924072265625 +3079 0.05487060546875 +3080 0.000885009765625 +3081 -0.009002685546875 +3082 -0.0587158203125 +3083 -0.10400390625 +3084 -0.137420654296875 +3085 -0.229400634765625 +3086 -0.216888427734375 +3087 -0.35552978515625 +3088 -0.272064208984375 +3089 -0.441925048828125 +3090 -0.293792724609375 +3091 -0.473846435546875 +3092 -0.29022216796875 +3093 -0.464813232421875 +3094 -0.26385498046875 +3095 -0.419097900390625 +3096 -0.213104248046875 +3097 -0.334320068359375 +3098 -0.14862060546875 +3099 -0.227935791015625 +3100 -0.084869384765625 +3101 -0.12347412109375 +3102 -0.02593994140625 +3103 -0.02764892578125 +3104 0.039337158203125 +3105 0.077667236328125 +3106 0.12371826171875 +3107 0.2132568359375 +3108 0.233154296875 +3109 0.38885498046875 +3110 0.354217529296875 +3111 0.582794189453125 +3112 0.44921875 +3113 0.734039306640625 +3114 0.49188232421875 +3115 0.800140380859375 +3116 0.480377197265625 +3117 0.7783203125 +3118 0.412506103515625 +3119 0.6651611328125 +3120 0.287567138671875 +3121 0.45965576171875 +3122 0.128509521484375 +3123 0.199188232421875 +3124 -0.024383544921875 +3125 -0.050689697265625 +3126 -0.13604736328125 +3127 -0.23297119140625 +3128 -0.195709228515625 +3129 -0.33013916015625 +3130 -0.219482421875 +3131 -0.368408203125 +3132 -0.226531982421875 +3133 -0.378936767578125 +3134 -0.22625732421875 +3135 -0.376983642578125 +3136 -0.229156494140625 +3137 -0.37969970703125 +3138 -0.237884521484375 +3139 -0.391510009765625 +3140 -0.235687255859375 +3141 -0.385345458984375 +3142 -0.2105712890625 +3143 -0.3419189453125 +3144 -0.175811767578125 +3145 -0.28289794921875 +3146 -0.15802001953125 +3147 -0.251617431640625 +3148 -0.168212890625 +3149 -0.266143798828125 +3150 -0.17364501953125 +3151 -0.273345947265625 +3152 -0.13946533203125 +3153 -0.216796875 +3154 -0.085205078125 +3155 -0.128265380859375 +3156 -0.048095703125 +3157 -0.068145751953125 +3158 -0.0322265625 +3159 -0.0430908203125 +3160 -0.02001953125 +3161 -0.024444580078125 +3162 0.0087890625 +3163 0.020721435546875 +3164 0.073883056640625 +3165 0.124481201171875 +3166 0.1573486328125 +3167 0.25787353515625 +3168 0.23333740234375 +3169 0.379119873046875 +3170 0.296722412109375 +3171 0.47991943359375 +3172 0.32763671875 +3173 0.5281982421875 +3174 0.318145751953125 +3175 0.511138916015625 +3176 0.285125732421875 +3177 0.456207275390625 +3178 0.255706787109375 +3179 0.407470703125 +3180 0.241424560546875 +3181 0.383758544921875 +3182 0.224884033203125 +3183 0.35687255859375 +3184 0.1968994140625 +3185 0.31182861328125 +3186 0.158843994140625 +3187 0.250885009765625 +3188 0.105438232421875 +3189 0.1654052734375 +3190 0.02435302734375 +3191 0.035247802734375 +3192 -0.085906982421875 +3193 -0.142059326171875 +3194 -0.20623779296875 +3195 -0.33563232421875 +3196 -0.329803466796875 +3197 -0.5345458984375 +3198 -0.446136474609375 +3199 -0.72186279296875 +3200 -0.5177001953125 +3201 -0.836669921875 +3202 -0.515899658203125 +3203 -0.8326416015625 +3204 -0.452911376953125 +3205 -0.7296142578125 +3206 -0.36260986328125 +3207 -0.582550048828125 +3208 -0.274932861328125 +3209 -0.440093994140625 +3210 -0.203460693359375 +3211 -0.324310302734375 +3212 -0.12744140625 +3213 -0.20147705078125 +3214 -0.0302734375 +3215 -0.044647216796875 +3216 0.061981201171875 +3217 0.103973388671875 +3218 0.1234130859375 +3219 0.202392578125 +3220 0.16253662109375 +3221 0.264495849609375 +3222 0.209228515625 +3223 0.338897705078125 +3224 0.274658203125 +3225 0.443817138671875 +3226 0.337738037109375 +3227 0.545074462890625 +3228 0.382781982421875 +3229 0.6173095703125 +3230 0.40484619140625 +3231 0.6524658203125 +3232 0.41180419921875 +3233 0.66339111328125 +3234 0.4073486328125 +3235 0.6561279296875 +3236 0.376800537109375 +3237 0.606781005859375 +3238 0.311431884765625 +3239 0.501190185546875 +3240 0.21954345703125 +3241 0.352783203125 +3242 0.110382080078125 +3243 0.176544189453125 +3244 -0.020477294921875 +3245 -0.034820556640625 +3246 -0.15875244140625 +3247 -0.258209228515625 +3248 -0.27288818359375 +3249 -0.44244384765625 +3250 -0.355316162109375 +3251 -0.5753173828125 +3252 -0.403076171875 +3253 -0.65203857421875 +3254 -0.397064208984375 +3255 -0.641632080078125 +3256 -0.348388671875 +3257 -0.562164306640625 +3258 -0.284393310546875 +3259 -0.458038330078125 +3260 -0.21820068359375 +3261 -0.350555419921875 +3262 -0.162628173828125 +3263 -0.260528564453125 +3264 -0.120269775390625 +3265 -0.192108154296875 +3266 -0.08905029296875 +3267 -0.141937255859375 +3268 -0.06414794921875 +3269 -0.1021728515625 +3270 -0.03948974609375 +3271 -0.062896728515625 +3272 -0.007568359375 +3273 -0.011932373046875 +3274 0.03900146484375 +3275 0.062835693359375 +3276 0.0924072265625 +3277 0.148712158203125 +3278 0.150146484375 +3279 0.241729736328125 +3280 0.2166748046875 +3281 0.34912109375 +3282 0.283599853515625 +3283 0.457305908203125 +3284 0.33709716796875 +3285 0.54388427734375 +3286 0.355010986328125 +3287 0.5728759765625 +3288 0.31414794921875 +3289 0.506591796875 +3290 0.218292236328125 +3291 0.351226806640625 +3292 0.0919189453125 +3293 0.146514892578125 +3294 -0.032684326171875 +3295 -0.05523681640625 +3296 -0.132232666015625 +3297 -0.21624755859375 +3298 -0.205718994140625 +3299 -0.334930419921875 +3300 -0.248016357421875 +3301 -0.402984619140625 +3302 -0.27197265625 +3303 -0.4412841796875 +3304 -0.305908203125 +3305 -0.49578857421875 +3306 -0.345855712890625 +3307 -0.5601806640625 +3308 -0.371063232421875 +3309 -0.600738525390625 +3310 -0.361053466796875 +3311 -0.584228515625 +3312 -0.2965087890625 +3313 -0.47930908203125 +3314 -0.173370361328125 +3315 -0.27935791015625 +3316 -0.006744384765625 +3317 -0.0089111328125 +3318 0.164398193359375 +3319 0.268798828125 +3320 0.29638671875 +3321 0.482818603515625 +3322 0.371063232421875 +3323 0.60369873046875 +3324 0.40008544921875 +3325 0.650421142578125 +3326 0.408721923828125 +3327 0.66400146484375 +3328 0.395355224609375 +3329 0.6414794921875 +3330 0.353546142578125 +3331 0.572540283203125 +3332 0.307373046875 +3333 0.498138427734375 +3334 0.26947021484375 +3335 0.439453125 +3336 0.227874755859375 +3337 0.375518798828125 +3338 0.164276123046875 +3339 0.274505615234375 +3340 0.06280517578125 +3341 0.1087646484375 +3342 -0.063201904296875 +3343 -0.099395751953125 +3344 -0.1949462890625 +3345 -0.3182373046875 +3346 -0.33294677734375 +3347 -0.5489501953125 +3348 -0.4666748046875 +3349 -0.7738037109375 +3350 -0.56512451171875 +3351 -0.86383056640625 +3352 -0.60882568359375 +3353 -0.870391845703125 +3354 -0.608154296875 +3355 -0.86895751953125 +3356 -0.570831298828125 +3357 -0.861053466796875 +3358 -0.486846923828125 +3359 -0.765869140625 +3360 -0.349761962890625 +3361 -0.5301513671875 +3362 -0.163909912109375 +3363 -0.214691162109375 +3364 0.045379638671875 +3365 0.137359619140625 +3366 0.2479248046875 +3367 0.474822998046875 +3368 0.422760009765625 +3369 0.76239013671875 +3370 0.553924560546875 +3371 0.867462158203125 +3372 0.641510009765625 +3373 0.870361328125 +3374 0.678619384765625 +3375 0.86480712890625 +3376 0.668304443359375 +3377 0.831817626953125 +3378 0.624725341796875 +3379 0.677581787109375 +3380 0.55126953125 +3381 0.495880126953125 +3382 0.458831787109375 +3383 0.30767822265625 +3384 0.3487548828125 +3385 0.116180419921875 +3386 0.20263671875 +3387 -0.110748291015625 +3388 0.01654052734375 +3389 -0.381805419921875 +3390 -0.184326171875 +3391 -0.6572265625 +3392 -0.364837646484375 +3393 -0.857421875 +3394 -0.499755859375 +3395 -0.870391845703125 +3396 -0.584747314453125 +3397 -0.870391845703125 +3398 -0.635406494140625 +3399 -0.86444091796875 +3400 -0.67242431640625 +3401 -0.85723876953125 +3402 -0.68499755859375 +3403 -0.790008544921875 +3404 -0.641387939453125 +3405 -0.62847900390625 +3406 -0.539703369140625 +3407 -0.3956298828125 +3408 -0.39910888671875 +3409 -0.126708984375 +3410 -0.23565673828125 +3411 0.150115966796875 +3412 -0.0562744140625 +3413 0.424041748046875 +3414 0.123138427734375 +3415 0.670623779296875 +3416 0.279815673828125 +3417 0.854522705078125 +3418 0.403289794921875 +3419 0.866485595703125 +3420 0.48443603515625 +3421 0.86920166015625 +3422 0.53369140625 +3423 0.8653564453125 +3424 0.558746337890625 +3425 0.857147216796875 +3426 0.55780029296875 +3427 0.766845703125 +3428 0.533721923828125 +3429 0.628509521484375 +3430 0.482513427734375 +3431 0.462127685546875 +3432 0.41925048828125 +3433 0.297210693359375 +3434 0.351165771484375 +3435 0.14862060546875 +3436 0.26495361328125 +3437 -0.00537109375 +3438 0.16510009765625 +3439 -0.15753173828125 +3440 0.049560546875 +3441 -0.31304931640625 +3442 -0.0897216796875 +3443 -0.48876953125 +3444 -0.2252197265625 +3445 -0.6416015625 +3446 -0.34234619140625 +3447 -0.751373291015625 +3448 -0.4544677734375 +3449 -0.84619140625 +3450 -0.5528564453125 +3451 -0.861297607421875 +3452 -0.6180419921875 +3453 -0.863250732421875 +3454 -0.631500244140625 +3455 -0.856597900390625 +3456 -0.60028076171875 +3457 -0.7498779296875 +3458 -0.558135986328125 +3459 -0.624542236328125 +3460 -0.492218017578125 +3461 -0.47808837890625 +3462 -0.368408203125 +3463 -0.253387451171875 +3464 -0.21343994140625 +3465 0.003692626953125 +3466 -0.06732177734375 +3467 0.2257080078125 +3468 0.077178955078125 +3469 0.427154541015625 +3470 0.23883056640625 +3471 0.643218994140625 +3472 0.411865234375 +3473 0.855926513671875 +3474 0.56231689453125 +3475 0.870361328125 +3476 0.66107177734375 +3477 0.870361328125 +3478 0.712188720703125 +3479 0.862762451171875 +3480 0.7138671875 +3481 0.79669189453125 +3482 0.6605224609375 +3483 0.595794677734375 +3484 0.5692138671875 +3485 0.362152099609375 +3486 0.456298828125 +3487 0.1270751953125 +3488 0.33416748046875 +3489 -0.086944580078125 +3490 0.2041015625 +3491 -0.2784423828125 +3492 0.04583740234375 +3493 -0.484832763671875 +3494 -0.15167236328125 +3495 -0.729583740234375 +3496 -0.358734130859375 +3497 -0.86688232421875 +3498 -0.538238525390625 +3499 -0.870391845703125 +3500 -0.687103271484375 +3501 -0.86859130859375 +3502 -0.803955078125 +3503 -0.86279296875 +3504 -0.85595703125 +3505 -0.817962646484375 +3506 -0.851593017578125 +3507 -0.6116943359375 +3508 -0.751495361328125 +3509 -0.3128662109375 +3510 -0.5870361328125 +3511 0.039398193359375 +3512 -0.369903564453125 +3513 0.422821044921875 +3514 -0.119598388671875 +3515 0.805145263671875 +3516 0.1240234375 +3517 0.870361328125 +3518 0.3275146484375 +3519 0.870361328125 +3520 0.48382568359375 +3521 0.860015869140625 +3522 0.588226318359375 +3523 0.727935791015625 +3524 0.637176513671875 +3525 0.48114013671875 +3526 0.644561767578125 +3527 0.2059326171875 +3528 0.62335205078125 +3529 -0.06103515625 +3530 0.579193115234375 +3531 -0.29913330078125 +3532 0.503448486328125 +3533 -0.516204833984375 +3534 0.3870849609375 +3535 -0.7252197265625 +3536 0.24462890625 +3537 -0.85980224609375 +3538 0.096221923828125 +3539 -0.870391845703125 +3540 -0.0406494140625 +3541 -0.870391845703125 +3542 -0.13726806640625 +3543 -0.858062744140625 +3544 -0.190826416015625 +3545 -0.673004150390625 +3546 -0.231597900390625 +3547 -0.42694091796875 +3548 -0.285125732421875 +3549 -0.2100830078125 +3550 -0.3497314453125 +3551 -0.0362548828125 +3552 -0.4080810546875 +3553 0.10943603515625 +3554 -0.448211669921875 +3555 0.23516845703125 +3556 -0.4456787109375 +3557 0.373687744140625 +3558 -0.40142822265625 +3559 0.517791748046875 +3560 -0.352142333984375 +3561 0.602783203125 +3562 -0.294830322265625 +3563 0.635711669921875 +3564 -0.21014404296875 +3565 0.655181884765625 +3566 -0.104095458984375 +3567 0.65948486328125 +3568 0.018341064453125 +3569 0.651275634765625 +3570 0.142486572265625 +3571 0.61846923828125 +3572 0.246307373046875 +3573 0.53753662109375 +3574 0.318817138671875 +3575 0.404144287109375 +3576 0.353912353515625 +3577 0.22186279296875 +3578 0.351959228515625 +3579 0.003997802734375 +3580 0.32318115234375 +3581 -0.22100830078125 +3582 0.279327392578125 +3583 -0.42449951171875 +3584 0.23236083984375 +3585 -0.579833984375 +3586 0.206451416015625 +3587 -0.641876220703125 +3588 0.19830322265625 +3589 -0.6177978515625 +3590 0.17205810546875 +3591 -0.575531005859375 +3592 0.124725341796875 +3593 -0.526336669921875 +3594 0.084991455078125 +3595 -0.42645263671875 +3596 0.068267822265625 +3597 -0.2581787109375 +3598 0.0548095703125 +3599 -0.068695068359375 +3600 0.023773193359375 +3601 0.09222412109375 +3602 -0.014068603515625 +3603 0.232147216796875 +3604 -0.052642822265625 +3605 0.3509521484375 +3606 -0.107879638671875 +3607 0.410064697265625 +3608 -0.19561767578125 +3609 0.372955322265625 +3610 -0.303955078125 +3611 0.2554931640625 +3612 -0.4039306640625 +3613 0.10711669921875 +3614 -0.484588623046875 +3615 -0.052886962890625 +3616 -0.52593994140625 +3617 -0.186279296875 +3618 -0.497314453125 +3619 -0.23291015625 +3620 -0.411468505859375 +3621 -0.209442138671875 +3622 -0.3050537109375 +3623 -0.174163818359375 +3624 -0.183013916015625 +3625 -0.126739501953125 +3626 -0.040313720703125 +3627 -0.048126220703125 +3628 0.106964111328125 +3629 0.0426025390625 +3630 0.232635498046875 +3631 0.10748291015625 +3632 0.32891845703125 +3633 0.1409912109375 +3634 0.4217529296875 +3635 0.19708251953125 +3636 0.507049560546875 +3637 0.273651123046875 +3638 0.553741455078125 +3639 0.31768798828125 +3640 0.567779541015625 +3641 0.341094970703125 +3642 0.56304931640625 +3643 0.368011474609375 +3644 0.526885986328125 +3645 0.37249755859375 +3646 0.432220458984375 +3647 0.30072021484375 +3648 0.282012939453125 +3649 0.1517333984375 +3650 0.113311767578125 +3651 -0.01470947265625 +3652 -0.063751220703125 +3653 -0.1883544921875 +3654 -0.24658203125 +3655 -0.372711181640625 +3656 -0.401092529296875 +3657 -0.51397705078125 +3658 -0.50091552734375 +3659 -0.57177734375 +3660 -0.5389404296875 +3661 -0.53948974609375 +3662 -0.52239990234375 +3663 -0.43511962890625 +3664 -0.470245361328125 +3665 -0.2962646484375 +3666 -0.4027099609375 +3667 -0.161102294921875 +3668 -0.32757568359375 +3669 -0.0435791015625 +3670 -0.24365234375 +3671 0.060394287109375 +3672 -0.16064453125 +3673 0.13665771484375 +3674 -0.089508056640625 +3675 0.170135498046875 +3676 -0.0308837890625 +3677 0.16552734375 +3678 0.0306396484375 +3679 0.15728759765625 +3680 0.09429931640625 +3681 0.150787353515625 +3682 0.14312744140625 +3683 0.12200927734375 +3684 0.1787109375 +3685 0.080108642578125 +3686 0.212493896484375 +3687 0.05126953125 +3688 0.25714111328125 +3689 0.062896728515625 +3690 0.298583984375 +3691 0.09271240234375 +3692 0.309539794921875 +3693 0.092987060546875 +3694 0.2979736328125 +3695 0.07855224609375 +3696 0.272735595703125 +3697 0.06427001953125 +3698 0.2266845703125 +3699 0.0347900390625 +3700 0.1607666015625 +3701 -0.01171875 +3702 0.08807373046875 +3703 -0.056060791015625 +3704 0.0350341796875 +3705 -0.055511474609375 +3706 0.0045166015625 +3707 -0.010467529296875 +3708 -0.030181884765625 +3709 0.02508544921875 +3710 -0.0802001953125 +3711 0.025665283203125 +3712 -0.128509521484375 +3713 0.017333984375 +3714 -0.17193603515625 +3715 0.00189208984375 +3716 -0.214935302734375 +3717 -0.03173828125 +3718 -0.249847412109375 +3719 -0.071502685546875 +3720 -0.2862548828125 +3721 -0.13543701171875 +3722 -0.322479248046875 +3723 -0.219970703125 +3724 -0.3458251953125 +3725 -0.300506591796875 +3726 -0.357330322265625 +3727 -0.376312255859375 +3728 -0.341644287109375 +3729 -0.416107177734375 +3730 -0.27410888671875 +3731 -0.371124267578125 +3732 -0.157745361328125 +3733 -0.242279052734375 +3734 -0.017242431640625 +3735 -0.069732666015625 +3736 0.133392333984375 +3737 0.125640869140625 +3738 0.274688720703125 +3739 0.31268310546875 +3740 0.3846435546875 +3741 0.45501708984375 +3742 0.462921142578125 +3743 0.554779052734375 +3744 0.507781982421875 +3745 0.61065673828125 +3746 0.512237548828125 +3747 0.610931396484375 +3748 0.4630126953125 +3749 0.531463623046875 +3750 0.36956787109375 +3751 0.3883056640625 +3752 0.262298583984375 +3753 0.23468017578125 +3754 0.15631103515625 +3755 0.095245361328125 +3756 0.06768798828125 +3757 -0.00396728515625 +3758 0.006378173828125 +3759 -0.04852294921875 +3760 -0.03472900390625 +3761 -0.055145263671875 +3762 -0.082275390625 +3763 -0.0758056640625 +3764 -0.149871826171875 +3765 -0.138702392578125 +3766 -0.216705322265625 +3767 -0.209197998046875 +3768 -0.2823486328125 +3769 -0.289031982421875 +3770 -0.346160888671875 +3771 -0.37884521484375 +3772 -0.395263671875 +3773 -0.456329345703125 +3774 -0.4267578125 +3775 -0.51641845703125 +3776 -0.418975830078125 +3777 -0.519287109375 +3778 -0.368988037109375 +3779 -0.458251953125 +3780 -0.3062744140625 +3781 -0.384796142578125 +3782 -0.245880126953125 +3783 -0.323699951171875 +3784 -0.186248779296875 +3785 -0.269287109375 +3786 -0.114532470703125 +3787 -0.1951904296875 +3788 -0.03167724609375 +3789 -0.100006103515625 +3790 0.04583740234375 +3791 -0.01055908203125 +3792 0.13323974609375 +3793 0.1033935546875 +3794 0.233306884765625 +3795 0.24908447265625 +3796 0.315673828125 +3797 0.373199462890625 +3798 0.370025634765625 +3799 0.45806884765625 +3800 0.400390625 +3801 0.511474609375 +3802 0.424591064453125 +3803 0.565399169921875 +3804 0.43841552734375 +3805 0.61138916015625 +3806 0.40972900390625 +3807 0.5897216796875 +3808 0.334136962890625 +3809 0.4906005859375 +3810 0.222564697265625 +3811 0.33148193359375 +3812 0.095947265625 +3813 0.147796630859375 +3814 -0.021240234375 +3815 -0.01873779296875 +3816 -0.112274169921875 +3817 -0.140289306640625 +3818 -0.162139892578125 +3819 -0.191986083984375 +3820 -0.175537109375 +3821 -0.184295654296875 +3822 -0.176239013671875 +3823 -0.161834716796875 +3824 -0.18682861328125 +3825 -0.166595458984375 +3826 -0.204437255859375 +3827 -0.19390869140625 +3828 -0.218414306640625 +3829 -0.22442626953125 +3830 -0.240997314453125 +3831 -0.279754638671875 +3832 -0.26123046875 +3833 -0.3389892578125 +3834 -0.253570556640625 +3835 -0.3543701171875 +3836 -0.231292724609375 +3837 -0.348175048828125 +3838 -0.198577880859375 +3839 -0.32598876953125 +3840 -0.1402587890625 +3841 -0.2581787109375 +3842 -0.054779052734375 +3843 -0.139801025390625 +3844 0.04876708984375 +3845 0.014617919921875 +3846 0.135955810546875 +3847 0.144378662109375 +3848 0.1904296875 +3849 0.221038818359375 +3850 0.225921630859375 +3851 0.27069091796875 +3852 0.24249267578125 +3853 0.294036865234375 +3854 0.25146484375 +3855 0.311767578125 +3856 0.261322021484375 +3857 0.339141845703125 +3858 0.263336181640625 +3859 0.360260009765625 +3860 0.250213623046875 +3861 0.360504150390625 +3862 0.20654296875 +3863 0.308380126953125 +3864 0.121856689453125 +3865 0.18170166015625 +3866 0.010009765625 +3867 0.0047607421875 +3868 -0.10345458984375 +3869 -0.17559814453125 +3870 -0.194000244140625 +3871 -0.3143310546875 +3872 -0.238006591796875 +3873 -0.36785888671875 +3874 -0.248321533203125 +3875 -0.36248779296875 +3876 -0.247894287109375 +3877 -0.343536376953125 +3878 -0.2315673828125 +3879 -0.3018798828125 +3880 -0.19598388671875 +3881 -0.231414794921875 +3882 -0.133697509765625 +3883 -0.117645263671875 +3884 -0.06182861328125 +3885 0.007049560546875 +3886 -0.009307861328125 +3887 0.087982177734375 +3888 0.030609130859375 +3889 0.13946533203125 +3890 0.06378173828125 +3891 0.17425537109375 +3892 0.087158203125 +3893 0.188201904296875 +3894 0.094573974609375 +3895 0.171234130859375 +3896 0.08258056640625 +3897 0.118438720703125 +3898 0.064544677734375 +3899 0.05706787109375 +3900 0.040863037109375 +3901 -0.010711669921875 +3902 0.007568359375 +3903 -0.0914306640625 +3904 -0.023834228515625 +3905 -0.162322998046875 +3906 -0.03857421875 +3907 -0.194549560546875 +3908 -0.0164794921875 +3909 -0.1492919921875 +3910 0.045135498046875 +3911 -0.02166748046875 +3912 0.11322021484375 +3913 0.124053955078125 +3914 0.14837646484375 +3915 0.211151123046875 +3916 0.151641845703125 +3917 0.240447998046875 +3918 0.13946533203125 +3919 0.242218017578125 +3920 0.117431640625 +3921 0.2257080078125 +3922 0.08807373046875 +3923 0.194366455078125 +3924 0.03509521484375 +3925 0.115509033203125 +3926 -0.028533935546875 +3927 0.0128173828125 +3928 -0.0711669921875 +3929 -0.053802490234375 +3930 -0.1060791015625 +3931 -0.110626220703125 +3932 -0.15484619140625 +3933 -0.199493408203125 +3934 -0.203887939453125 +3935 -0.29437255859375 +3936 -0.220458984375 +3937 -0.33221435546875 +3938 -0.187530517578125 +3939 -0.27972412109375 +3940 -0.13067626953125 +3941 -0.185333251953125 +3942 -0.091522216796875 +3943 -0.128204345703125 +3944 -0.074462890625 +3945 -0.115692138671875 +3946 -0.0638427734375 +3947 -0.116455078125 +3948 -0.047454833984375 +3949 -0.105926513671875 +3950 -0.01025390625 +3951 -0.053955078125 +3952 0.052093505859375 +3953 0.048797607421875 +3954 0.115753173828125 +3955 0.157318115234375 +3956 0.14935302734375 +3957 0.212005615234375 +3958 0.155609130859375 +3959 0.218475341796875 +3960 0.165863037109375 +3961 0.23724365234375 +3962 0.199432373046875 +3963 0.30535888671875 +3964 0.234893798828125 +3965 0.38128662109375 +3966 0.24102783203125 +3967 0.404449462890625 +3968 0.228363037109375 +3969 0.3944091796875 +3970 0.216827392578125 +3971 0.3885498046875 +3972 0.194305419921875 +3973 0.362640380859375 +3974 0.138916015625 +3975 0.27362060546875 +3976 0.04888916015625 +3977 0.11712646484375 +3978 -0.04827880859375 +3979 -0.054901123046875 +3980 -0.125335693359375 +3981 -0.19085693359375 +3982 -0.17938232421875 +3983 -0.28570556640625 +3984 -0.21014404296875 +3985 -0.339263916015625 +3986 -0.23101806640625 +3987 -0.3775634765625 +3988 -0.2655029296875 +3989 -0.445709228515625 +3990 -0.309173583984375 +3991 -0.535064697265625 +3992 -0.3536376953125 +3993 -0.629058837890625 +3994 -0.383514404296875 +3995 -0.697601318359375 +3996 -0.38006591796875 +3997 -0.70391845703125 +3998 -0.340789794921875 +3999 -0.6424560546875 +4000 -0.254669189453125 +4001 -0.491241455078125 +4002 -0.130157470703125 +4003 -0.265716552734375 +4004 0.00225830078125 +4005 -0.023712158203125 +4006 0.125091552734375 +4007 0.201751708984375 +4008 0.219940185546875 +4009 0.375823974609375 +4010 0.27960205078125 +4011 0.485076904296875 +4012 0.324432373046875 +4013 0.56884765625 +4014 0.3583984375 +4015 0.634765625 +4016 0.3580322265625 +4017 0.63763427734375 +4018 0.317535400390625 +4019 0.5660400390625 +4020 0.26422119140625 +4021 0.4720458984375 +4022 0.225006103515625 +4023 0.40692138671875 +4024 0.203948974609375 +4025 0.3778076171875 +4026 0.197357177734375 +4027 0.376953125 +4028 0.188720703125 +4029 0.371978759765625 +4030 0.15252685546875 +4031 0.313140869140625 +4032 0.0806884765625 +4033 0.184417724609375 +4034 -0.0133056640625 +4035 0.011199951171875 +4036 -0.110809326171875 +4037 -0.171051025390625 +4038 -0.198760986328125 +4039 -0.33740234375 +4040 -0.268829345703125 +4041 -0.47198486328125 +4042 -0.3135986328125 +4043 -0.560394287109375 +4044 -0.321685791015625 +4045 -0.58056640625 +4046 -0.30108642578125 +4047 -0.54754638671875 +4048 -0.276580810546875 +4049 -0.508575439453125 +4050 -0.24627685546875 +4051 -0.459503173828125 +4052 -0.207366943359375 +4053 -0.394378662109375 +4054 -0.18060302734375 +4055 -0.35260009765625 +4056 -0.154571533203125 +4057 -0.31170654296875 +4058 -0.090911865234375 +4059 -0.197418212890625 +4060 0.01104736328125 +4061 -0.007965087890625 +4062 0.125579833984375 +4063 0.207489013671875 +4064 0.23193359375 +4065 0.409210205078125 +4066 0.3170166015625 +4067 0.57208251953125 +4068 0.365142822265625 +4069 0.66595458984375 +4070 0.359710693359375 +4071 0.65875244140625 +4072 0.30963134765625 +4073 0.56744384765625 +4074 0.235565185546875 +4075 0.431396484375 +4076 0.1605224609375 +4077 0.29443359375 +4078 0.098175048828125 +4079 0.182464599609375 +4080 0.0322265625 +4081 0.06365966796875 +4082 -0.044342041015625 +4083 -0.075958251953125 +4084 -0.10693359375 +4085 -0.189422607421875 +4086 -0.152862548828125 +4087 -0.271942138671875 +4088 -0.19183349609375 +4089 -0.342529296875 +4090 -0.204559326171875 +4091 -0.364166259765625 +4092 -0.18597412109375 +4093 -0.327239990234375 +4094 -0.159576416015625 +4095 -0.2769775390625 +4096 -0.146087646484375 +4097 -0.253692626953125 +4098 -0.138702392578125 +4099 -0.24365234375 +4100 -0.1134033203125 +4101 -0.1983642578125 +4102 -0.069488525390625 +4103 -0.116241455078125 +4104 -0.026336669921875 +4105 -0.036834716796875 +4106 0.013427734375 +4107 0.034881591796875 +4108 0.04583740234375 +4109 0.09124755859375 +4110 0.059234619140625 +4111 0.10888671875 +4112 0.071746826171875 +4113 0.125518798828125 +4114 0.09124755859375 +4115 0.15771484375 +4116 0.104248046875 +4117 0.17828369140625 +4118 0.10272216796875 +4119 0.17108154296875 +4120 0.083587646484375 +4121 0.129974365234375 +4122 0.060211181640625 +4123 0.082427978515625 +4124 0.032257080078125 +4125 0.027679443359375 +4126 -0.015472412109375 +4127 -0.065643310546875 +4128 -0.064178466796875 +4129 -0.15936279296875 +4130 -0.093994140625 +4131 -0.21307373046875 +4132 -0.108551025390625 +4133 -0.234649658203125 +4134 -0.095947265625 +4135 -0.2001953125 +4136 -0.060577392578125 +4137 -0.119171142578125 +4138 -0.018402099609375 +4139 -0.024749755859375 +4140 0.032073974609375 +4141 0.085784912109375 +4142 0.074310302734375 +4143 0.178131103515625 +4144 0.09051513671875 +4145 0.215576171875 +4146 0.0872802734375 +4147 0.211456298828125 +4148 0.06927490234375 +4149 0.17523193359375 +4150 0.04718017578125 +4151 0.128753662109375 +4152 0.0355224609375 +4153 0.1019287109375 +4154 0.02423095703125 +4155 0.0743408203125 +4156 0.0118408203125 +4157 0.04327392578125 +4158 0.012542724609375 +4159 0.038177490234375 +4160 0.034576416015625 +4161 0.076263427734375 +4162 0.069671630859375 +4163 0.14105224609375 +4164 0.09515380859375 +4165 0.186431884765625 +4166 0.099334716796875 +4167 0.188812255859375 +4168 0.07757568359375 +4169 0.1390380859375 +4170 0.03204345703125 +4171 0.041778564453125 +4172 -0.025848388671875 +4173 -0.079437255859375 +4174 -0.093597412109375 +4175 -0.219390869140625 +4176 -0.16619873046875 +4177 -0.367828369140625 +4178 -0.229034423828125 +4179 -0.494873046875 +4180 -0.260467529296875 +4181 -0.556243896484375 +4182 -0.239288330078125 +4183 -0.508697509765625 +4184 -0.176788330078125 +4185 -0.3756103515625 +4186 -0.10302734375 +4187 -0.218902587890625 +4188 -0.030120849609375 +4189 -0.063751220703125 +4190 0.042877197265625 +4191 0.091552734375 +4192 0.110748291015625 +4193 0.23602294921875 +4194 0.160614013671875 +4195 0.342987060546875 +4196 0.1842041015625 +4197 0.39520263671875 +4198 0.17999267578125 +4199 0.389373779296875 +4200 0.147430419921875 +4201 0.324249267578125 +4202 0.098388671875 +4203 0.224090576171875 +4204 0.050140380859375 +4205 0.124267578125 +4206 0.00860595703125 +4207 0.037078857421875 +4208 -0.012908935546875 +4209 -0.010101318359375 +4210 -0.01556396484375 +4211 -0.019439697265625 +4212 -0.0150146484375 +4213 -0.022796630859375 +4214 -0.002288818359375 +4215 -0.001556396484375 +4216 0.0283203125 +4217 0.056304931640625 +4218 0.05517578125 +4219 0.106719970703125 +4220 0.05242919921875 +4221 0.096893310546875 +4222 0.027679443359375 +4223 0.042694091796875 +4224 -0.00067138671875 +4225 -0.018035888671875 +4226 -0.028076171875 +4227 -0.07586669921875 +4228 -0.04901123046875 +4229 -0.11944580078125 +4230 -0.06884765625 +4231 -0.15972900390625 +4232 -0.0904541015625 +4233 -0.202606201171875 +4234 -0.113983154296875 +4235 -0.24859619140625 +4236 -0.143035888671875 +4237 -0.30517578125 +4238 -0.17254638671875 +4239 -0.36212158203125 +4240 -0.188720703125 +4241 -0.39141845703125 +4242 -0.173004150390625 +4243 -0.35528564453125 +4244 -0.12347412109375 +4245 -0.249969482421875 +4246 -0.04852294921875 +4247 -0.092864990234375 +4248 0.03875732421875 +4249 0.08905029296875 +4250 0.10888671875 +4251 0.2352294921875 +4252 0.148834228515625 +4253 0.318817138671875 +4254 0.167816162109375 +4255 0.358642578125 +4256 0.162445068359375 +4257 0.347747802734375 +4258 0.132476806640625 +4259 0.28564453125 +4260 0.102691650390625 +4261 0.223175048828125 +4262 0.090789794921875 +4263 0.196746826171875 +4264 0.08380126953125 +4265 0.179840087890625 +4266 0.073394775390625 +4267 0.155548095703125 +4268 0.07281494140625 +4269 0.151214599609375 +4270 0.0771484375 +4271 0.156951904296875 +4272 0.066314697265625 +4273 0.13177490234375 +4274 0.052520751953125 +4275 0.100799560546875 +4276 0.04693603515625 +4277 0.087127685546875 +4278 0.032012939453125 +4279 0.05487060546875 +4280 0.0013427734375 +4281 -0.009002685546875 +4282 -0.044830322265625 +4283 -0.10400390625 +4284 -0.10614013671875 +4285 -0.229400634765625 +4286 -0.1680908203125 +4287 -0.35552978515625 +4288 -0.210906982421875 +4289 -0.441925048828125 +4290 -0.227386474609375 +4291 -0.473846435546875 +4292 -0.22406005859375 +4293 -0.464813232421875 +4294 -0.202911376953125 +4295 -0.419097900390625 +4296 -0.1627197265625 +4297 -0.334320068359375 +4298 -0.111968994140625 +4299 -0.227935791015625 +4300 -0.06207275390625 +4301 -0.12347412109375 +4302 -0.0162353515625 +4303 -0.02764892578125 +4304 0.034423828125 +4305 0.077667236328125 +4306 0.100067138671875 +4307 0.2132568359375 +4308 0.185455322265625 +4309 0.38885498046875 +4310 0.280029296875 +4311 0.582794189453125 +4312 0.35400390625 +4313 0.734039306640625 +4314 0.38665771484375 +4315 0.800140380859375 +4316 0.3765869140625 +4317 0.7783203125 +4318 0.322113037109375 +4319 0.6651611328125 +4320 0.222686767578125 +4321 0.45965576171875 +4322 0.09649658203125 +4323 0.199188232421875 +4324 -0.024505615234375 +4325 -0.050689697265625 +4326 -0.112548828125 +4327 -0.23297119140625 +4328 -0.159149169921875 +4329 -0.33013916015625 +4330 -0.177093505859375 +4331 -0.368408203125 +4332 -0.181640625 +4333 -0.378936767578125 +4334 -0.1802978515625 +4335 -0.376983642578125 +4336 -0.18145751953125 +4337 -0.37969970703125 +4338 -0.187255859375 +4339 -0.391510009765625 +4340 -0.1844482421875 +4341 -0.385345458984375 +4342 -0.16363525390625 +4343 -0.3419189453125 +4344 -0.1353759765625 +4345 -0.28289794921875 +4346 -0.12078857421875 +4347 -0.251617431640625 +4348 -0.12860107421875 +4349 -0.266143798828125 +4350 -0.13287353515625 +4351 -0.273345947265625 +4352 -0.106170654296875 +4353 -0.216796875 +4354 -0.06365966796875 +4355 -0.128265380859375 +4356 -0.0338134765625 +4357 -0.068145751953125 +4358 -0.019805908203125 +4359 -0.0430908203125 +4360 -0.008697509765625 +4361 -0.024444580078125 +4362 0.01434326171875 +4363 0.020721435546875 +4364 0.06378173828125 +4365 0.124481201171875 +4366 0.126312255859375 +4367 0.25787353515625 +4368 0.182769775390625 +4369 0.379119873046875 +4370 0.229339599609375 +4371 0.47991943359375 +4372 0.251373291015625 +4373 0.5281982421875 +4374 0.243011474609375 +4375 0.511138916015625 +4376 0.216827392578125 +4377 0.456207275390625 +4378 0.193023681640625 +4379 0.407470703125 +4380 0.1802978515625 +4381 0.383758544921875 +4382 0.1658935546875 +4383 0.35687255859375 +4384 0.143096923828125 +4385 0.31182861328125 +4386 0.113037109375 +4387 0.250885009765625 +4388 0.071929931640625 +4389 0.1654052734375 +4390 0.010711669921875 +4391 0.035247802734375 +4392 -0.071624755859375 +4393 -0.142059326171875 +4394 -0.160919189453125 +4395 -0.33563232421875 +4396 -0.252166748046875 +4397 -0.5345458984375 +4398 -0.337615966796875 +4399 -0.72186279296875 +4400 -0.389495849609375 +4401 -0.836669921875 +4402 -0.386749267578125 +4403 -0.8326416015625 +4404 -0.3385009765625 +4405 -0.7296142578125 +4406 -0.2698974609375 +4407 -0.582550048828125 +4408 -0.20318603515625 +4409 -0.440093994140625 +4410 -0.1485595703125 +4411 -0.324310302734375 +4412 -0.0906982421875 +4413 -0.20147705078125 +4414 -0.017425537109375 +4415 -0.044647216796875 +4416 0.051910400390625 +4417 0.103973388671875 +4418 0.098052978515625 +4419 0.202392578125 +4420 0.12725830078125 +4421 0.264495849609375 +4422 0.16168212890625 +4423 0.338897705078125 +4424 0.209625244140625 +4425 0.443817138671875 +4426 0.2554931640625 +4427 0.545074462890625 +4428 0.287750244140625 +4429 0.6173095703125 +4430 0.302764892578125 +4431 0.6524658203125 +4432 0.30645751953125 +4433 0.66339111328125 +4434 0.301666259765625 +4435 0.6561279296875 +4436 0.277587890625 +4437 0.606781005859375 +4438 0.22784423828125 +4439 0.501190185546875 +4440 0.158660888671875 +4441 0.352783203125 +4442 0.076934814453125 +4443 0.176544189453125 +4444 -0.020538330078125 +4445 -0.034820556640625 +4446 -0.1231689453125 +4447 -0.258209228515625 +4448 -0.20758056640625 +4449 -0.44244384765625 +4450 -0.268218994140625 +4451 -0.5753173828125 +4452 -0.30291748046875 +4453 -0.65203857421875 +4454 -0.297576904296875 +4455 -0.641632080078125 +4456 -0.260467529296875 +4457 -0.562164306640625 +4458 -0.2119140625 +4459 -0.458038330078125 +4460 -0.16168212890625 +4461 -0.350555419921875 +4462 -0.11932373046875 +4463 -0.260528564453125 +4464 -0.086822509765625 +4465 -0.192108154296875 +4466 -0.062713623046875 +4467 -0.141937255859375 +4468 -0.043487548828125 +4469 -0.1021728515625 +4470 -0.024658203125 +4471 -0.062896728515625 +4472 -0.000701904296875 +4473 -0.011932373046875 +4474 0.033843994140625 +4475 0.062835693359375 +4476 0.07318115234375 +4477 0.148712158203125 +4478 0.115478515625 +4479 0.241729736328125 +4480 0.164031982421875 +4481 0.34912109375 +4482 0.212677001953125 +4483 0.457305908203125 +4484 0.251251220703125 +4485 0.54388427734375 +4486 0.263427734375 +4487 0.5728759765625 +4488 0.232086181640625 +4489 0.506591796875 +4490 0.16009521484375 +4491 0.351226806640625 +4492 0.065643310546875 +4493 0.146514892578125 +4494 -0.02734375 +4495 -0.05523681640625 +4496 -0.101593017578125 +4497 -0.21624755859375 +4498 -0.156341552734375 +4499 -0.334930419921875 +4500 -0.187774658203125 +4501 -0.402984619140625 +4502 -0.20538330078125 +4503 -0.4412841796875 +4504 -0.230133056640625 +4505 -0.49578857421875 +4506 -0.2591552734375 +4507 -0.5601806640625 +4508 -0.277099609375 +4509 -0.600738525390625 +4510 -0.268829345703125 +4511 -0.584228515625 +4512 -0.220123291015625 +4513 -0.47930908203125 +4514 -0.128021240234375 +4515 -0.27935791015625 +4516 -0.003753662109375 +4517 -0.0089111328125 +4518 0.123748779296875 +4519 0.268798828125 +4520 0.222137451171875 +4521 0.482818603515625 +4522 0.277923583984375 +4523 0.60369873046875 +4524 0.299713134765625 +4525 0.650421142578125 +4526 0.30621337890625 +4527 0.66400146484375 +4528 0.296051025390625 +4529 0.6414794921875 +4530 0.2645263671875 +4531 0.572540283203125 +4532 0.230316162109375 +4533 0.498138427734375 +4534 0.203094482421875 +4535 0.439453125 +4536 0.173370361328125 +4537 0.375518798828125 +4538 0.12664794921875 +4539 0.274505615234375 +4540 0.05035400390625 +4541 0.1087646484375 +4542 -0.0452880859375 +4543 -0.099395751953125 +4544 -0.145782470703125 +4545 -0.3182373046875 +4546 -0.251617431640625 +4547 -0.5489501953125 +4548 -0.35467529296875 +4549 -0.7738037109375 +4550 -0.4307861328125 +4551 -0.86383056640625 +4552 -0.464752197265625 +4553 -0.870391845703125 +4554 -0.46466064453125 +4555 -0.86895751953125 +4556 -0.436492919921875 +4557 -0.861053466796875 +4558 -0.37237548828125 +4559 -0.765869140625 +4560 -0.26715087890625 +4561 -0.5301513671875 +4562 -0.124114990234375 +4563 -0.214691162109375 +4564 0.037078857421875 +4565 0.137359619140625 +4566 0.1929931640625 +4567 0.474822998046875 +4568 0.327362060546875 +4569 0.76239013671875 +4570 0.427825927734375 +4571 0.867462158203125 +4572 0.49456787109375 +4573 0.870361328125 +4574 0.522308349609375 +4575 0.86480712890625 +4576 0.513458251953125 +4577 0.831817626953125 +4578 0.4791259765625 +4579 0.677581787109375 +4580 0.42193603515625 +4581 0.495880126953125 +4582 0.35040283203125 +4583 0.30767822265625 +4584 0.2655029296875 +4585 0.116180419921875 +4586 0.152801513671875 +4587 -0.110748291015625 +4588 0.009185791015625 +4589 -0.381805419921875 +4590 -0.14581298828125 +4591 -0.6572265625 +4592 -0.28485107421875 +4593 -0.857421875 +4594 -0.388336181640625 +4595 -0.870391845703125 +4596 -0.4530029296875 +4597 -0.870391845703125 +4598 -0.4910888671875 +4599 -0.86444091796875 +4600 -0.518829345703125 +4601 -0.85723876953125 +4602 -0.52783203125 +4603 -0.790008544921875 +4604 -0.49334716796875 +4605 -0.62847900390625 +4606 -0.413909912109375 +4607 -0.3956298828125 +4608 -0.3045654296875 +4609 -0.126708984375 +4610 -0.17779541015625 +4611 0.150115966796875 +4612 -0.039276123046875 +4613 0.424041748046875 +4614 0.098876953125 +4615 0.670623779296875 +4616 0.21966552734375 +4617 0.854522705078125 +4618 0.315093994140625 +4619 0.866485595703125 +4620 0.37823486328125 +4621 0.86920166015625 +4622 0.41650390625 +4623 0.8653564453125 +4624 0.4354248046875 +4625 0.857147216796875 +4626 0.433685302734375 +4627 0.766845703125 +4628 0.413543701171875 +4629 0.628509521484375 +4630 0.372314453125 +4631 0.462127685546875 +4632 0.3211669921875 +4633 0.297210693359375 +4634 0.265716552734375 +4635 0.14862060546875 +4636 0.1966552734375 +4637 -0.00537109375 +4638 0.11761474609375 +4639 -0.15753173828125 +4640 0.027496337890625 +4641 -0.31304931640625 +4642 -0.079193115234375 +4643 -0.48876953125 +4644 -0.182220458984375 +4645 -0.6416015625 +4646 -0.270751953125 +4647 -0.751373291015625 +4648 -0.35430908203125 +4649 -0.84619140625 +4650 -0.426513671875 +4651 -0.861297607421875 +4652 -0.47320556640625 +4653 -0.863250732421875 +4654 -0.480987548828125 +4655 -0.856597900390625 +4656 -0.455108642578125 +4657 -0.7498779296875 +4658 -0.420318603515625 +4659 -0.624542236328125 +4660 -0.367523193359375 +4661 -0.47808837890625 +4662 -0.27227783203125 +4663 -0.253387451171875 +4664 -0.154266357421875 +4665 0.003692626953125 +4666 -0.042877197265625 +4667 0.2257080078125 +4668 0.066802978515625 +4669 0.427154541015625 +4670 0.188201904296875 +4671 0.643218994140625 +4672 0.31695556640625 +4673 0.855926513671875 +4674 0.42822265625 +4675 0.870361328125 +4676 0.500823974609375 +4677 0.870361328125 +4678 0.537689208984375 +4679 0.862762451171875 +4680 0.53753662109375 +4681 0.79669189453125 +4682 0.496429443359375 +4683 0.595794677734375 +4684 0.4268798828125 +4685 0.362152099609375 +4686 0.340972900390625 +4687 0.1270751953125 +4688 0.2479248046875 +4689 -0.086944580078125 +4690 0.148956298828125 +4691 -0.2784423828125 +4692 0.02960205078125 +4693 -0.484832763671875 +4694 -0.117889404296875 +4695 -0.729583740234375 +4696 -0.27178955078125 +4697 -0.86688232421875 +4698 -0.404937744140625 +4699 -0.870391845703125 +4700 -0.514984130859375 +4701 -0.86859130859375 +4702 -0.600830078125 +4703 -0.86279296875 +4704 -0.6470947265625 +4705 -0.817962646484375 +4706 -0.634490966796875 +4707 -0.6116943359375 +4708 -0.56005859375 +4709 -0.3128662109375 +4710 -0.43817138671875 +4711 0.039398193359375 +4712 -0.2774658203125 +4713 0.422821044921875 +4714 -0.092254638671875 +4715 0.805145263671875 +4716 0.0882568359375 +4717 0.870361328125 +4718 0.239593505859375 +4719 0.870361328125 +4720 0.356475830078125 +4721 0.860015869140625 +4722 0.435302734375 +4723 0.727935791015625 +4724 0.473358154296875 +4725 0.48114013671875 +4726 0.480560302734375 +4727 0.2059326171875 +4728 0.46624755859375 +4729 -0.06103515625 +4730 0.43450927734375 +4731 -0.29913330078125 +4732 0.37908935546875 +4733 -0.516204833984375 +4734 0.29345703125 +4735 -0.7252197265625 +4736 0.188262939453125 +4737 -0.85980224609375 +4738 0.0782470703125 +4739 -0.870391845703125 +4740 -0.023773193359375 +4741 -0.870391845703125 +4742 -0.0968017578125 +4743 -0.858062744140625 +4744 -0.138641357421875 +4745 -0.673004150390625 +4746 -0.171112060546875 +4747 -0.42694091796875 +4748 -0.212615966796875 +4749 -0.2100830078125 +4750 -0.26177978515625 +4751 -0.0362548828125 +4752 -0.305877685546875 +4753 0.10943603515625 +4754 -0.336151123046875 +4755 0.23516845703125 +4756 -0.334808349609375 +4757 0.373687744140625 +4758 -0.302520751953125 +4759 0.517791748046875 +4760 -0.2659912109375 +4761 0.602783203125 +4762 -0.22308349609375 +4763 0.635711669921875 +4764 -0.15985107421875 +4765 0.655181884765625 +4766 -0.080718994140625 +4767 0.65948486328125 +4768 0.010498046875 +4769 0.651275634765625 +4770 0.10302734375 +4771 0.61846923828125 +4772 0.180755615234375 +4773 0.53753662109375 +4774 0.235565185546875 +4775 0.404144287109375 +4776 0.262939453125 +4777 0.22186279296875 +4778 0.263031005859375 +4779 0.003997802734375 +4780 0.243194580078125 +4781 -0.22100830078125 +4782 0.2119140625 +4783 -0.42449951171875 +4784 0.1781005859375 +4785 -0.579833984375 +4786 0.159820556640625 +4787 -0.641876220703125 +4788 0.154266357421875 +4789 -0.6177978515625 +4790 0.134185791015625 +4791 -0.575531005859375 +4792 0.097503662109375 +4793 -0.526336669921875 +4794 0.06646728515625 +4795 -0.42645263671875 +4796 0.053009033203125 +4797 -0.2581787109375 +4798 0.0421142578125 +4799 -0.068695068359375 +4800 0.017852783203125 +4801 0.09222412109375 +4802 -0.011474609375 +4803 0.232147216796875 +4804 -0.041168212890625 +4805 0.3509521484375 +4806 -0.08349609375 +4807 0.410064697265625 +4808 -0.150604248046875 +4809 0.372955322265625 +4810 -0.23345947265625 +4811 0.2554931640625 +4812 -0.309814453125 +4813 0.10711669921875 +4814 -0.371337890625 +4815 -0.052886962890625 +4816 -0.4027099609375 +4817 -0.186279296875 +4818 -0.380340576171875 +4819 -0.23291015625 +4820 -0.3140869140625 +4821 -0.209442138671875 +4822 -0.232147216796875 +4823 -0.174163818359375 +4824 -0.138336181640625 +4825 -0.126739501953125 +4826 -0.02880859375 +4827 -0.048126220703125 +4828 0.084136962890625 +4829 0.0426025390625 +4830 0.180389404296875 +4831 0.10748291015625 +4832 0.2540283203125 +4833 0.1409912109375 +4834 0.32489013671875 +4835 0.19708251953125 +4836 0.389923095703125 +4837 0.273651123046875 +4838 0.42529296875 +4839 0.31768798828125 +4840 0.43560791015625 +4841 0.341094970703125 +4842 0.4315185546875 +4843 0.368011474609375 +4844 0.403350830078125 +4845 0.37249755859375 +4846 0.330322265625 +4847 0.30072021484375 +4848 0.2147216796875 +4849 0.1517333984375 +4850 0.08502197265625 +4851 -0.01470947265625 +4852 -0.05096435546875 +4853 -0.1883544921875 +4854 -0.191253662109375 +4855 -0.372711181640625 +4856 -0.309661865234375 +4857 -0.51397705078125 +4858 -0.385986328125 +4859 -0.57177734375 +4860 -0.414794921875 +4861 -0.53948974609375 +4862 -0.40167236328125 +4863 -0.43511962890625 +4864 -0.3614501953125 +4865 -0.2962646484375 +4866 -0.309814453125 +4867 -0.161102294921875 +4868 -0.252593994140625 +4869 -0.0435791015625 +4870 -0.188812255859375 +4871 0.060394287109375 +4872 -0.125457763671875 +4873 0.13665771484375 +4874 -0.070465087890625 +4875 0.170135498046875 +4876 -0.02435302734375 +4877 0.16552734375 +4878 0.023895263671875 +4879 0.15728759765625 +4880 0.0736083984375 +4881 0.150787353515625 +4882 0.1123046875 +4883 0.12200927734375 +4884 0.1409912109375 +4885 0.080108642578125 +4886 0.16778564453125 +4887 0.05126953125 +4888 0.201751708984375 +4889 0.062896728515625 +4890 0.23260498046875 +4891 0.09271240234375 +4892 0.240509033203125 +4893 0.092987060546875 +4894 0.231292724609375 +4895 0.07855224609375 +4896 0.21136474609375 +4897 0.06427001953125 +4898 0.1756591796875 +4899 0.0347900390625 +4900 0.125 +4901 -0.01171875 +4902 0.069061279296875 +4903 -0.056060791015625 +4904 0.027191162109375 +4905 -0.055511474609375 +4906 0.001617431640625 +4907 -0.010467529296875 +4908 -0.02679443359375 +4909 0.02508544921875 +4910 -0.06591796875 +4911 0.025665283203125 +4912 -0.103302001953125 +4913 0.017333984375 +4914 -0.13653564453125 +4915 0.00189208984375 +4916 -0.16876220703125 +4917 -0.03173828125 +4918 -0.19439697265625 +4919 -0.071502685546875 +4920 -0.220367431640625 +4921 -0.13543701171875 +4922 -0.245513916015625 +4923 -0.219970703125 +4924 -0.26068115234375 +4925 -0.300506591796875 +4926 -0.266754150390625 +4927 -0.376312255859375 +4928 -0.252777099609375 +4929 -0.416107177734375 +4930 -0.2010498046875 +4931 -0.371124267578125 +4932 -0.113861083984375 +4933 -0.242279052734375 +4934 -0.00927734375 +4935 -0.069732666015625 +4936 0.102386474609375 +4937 0.125640869140625 +4938 0.206878662109375 +4939 0.31268310546875 +4940 0.288177490234375 +4941 0.45501708984375 +4942 0.345947265625 +4943 0.554779052734375 +4944 0.37890625 +4945 0.61065673828125 +4946 0.381988525390625 +4947 0.610931396484375 +4948 0.3455810546875 +4949 0.531463623046875 +4950 0.276580810546875 +4951 0.3883056640625 +4952 0.1971435546875 +4953 0.23468017578125 +4954 0.1182861328125 +4955 0.095245361328125 +4956 0.05181884765625 +4957 -0.00396728515625 +4958 0.00506591796875 +4959 -0.04852294921875 +4960 -0.027008056640625 +4961 -0.055145263671875 +4962 -0.063568115234375 +4963 -0.0758056640625 +4964 -0.1143798828125 +4965 -0.138702392578125 +4966 -0.164276123046875 +4967 -0.209197998046875 +4968 -0.212860107421875 +4969 -0.289031982421875 +4970 -0.259674072265625 +4971 -0.37884521484375 +4972 -0.295318603515625 +4973 -0.456329345703125 +4974 -0.31768798828125 +4975 -0.51641845703125 +4976 -0.3111572265625 +4977 -0.519287109375 +4978 -0.27362060546875 +4979 -0.458251953125 +4980 -0.2265625 +4981 -0.384796142578125 +4982 -0.18096923828125 +4983 -0.323699951171875 +4984 -0.13580322265625 +4985 -0.269287109375 +4986 -0.081878662109375 +4987 -0.1951904296875 +4988 -0.019989013671875 +4989 -0.100006103515625 +4990 0.037841796875 +4991 -0.01055908203125 +4992 0.1025390625 +4993 0.1033935546875 +4994 0.176055908203125 +4995 0.24908447265625 +4996 0.236328125 +4997 0.373199462890625 +4998 0.275848388671875 +4999 0.45806884765625 +5000 0.297576904296875 +5001 0.511474609375 +5002 0.314422607421875 +5003 0.565399169921875 +5004 0.32342529296875 +5005 0.61138916015625 +5006 0.30133056640625 +5007 0.5897216796875 +5008 0.24505615234375 +5009 0.4906005859375 +5010 0.16259765625 +5011 0.33148193359375 +5012 0.0692138671875 +5013 0.147796630859375 +5014 -0.01727294921875 +5015 -0.01873779296875 +5016 -0.084625244140625 +5017 -0.140289306640625 +5018 -0.121917724609375 +5019 -0.191986083984375 +5020 -0.13250732421875 +5021 -0.184295654296875 +5022 -0.133575439453125 +5023 -0.161834716796875 +5024 -0.141448974609375 +5025 -0.166595458984375 +5026 -0.154083251953125 +5027 -0.19390869140625 +5028 -0.163726806640625 +5029 -0.22442626953125 +5030 -0.179290771484375 +5031 -0.279754638671875 +5032 -0.192901611328125 +5033 -0.3389892578125 +5034 -0.1861572265625 +5035 -0.3543701171875 +5036 -0.168731689453125 +5037 -0.348175048828125 +5038 -0.143707275390625 +5039 -0.32598876953125 +5040 -0.100189208984375 +5041 -0.2581787109375 +5042 -0.037078857421875 +5043 -0.139801025390625 +5044 0.038970947265625 +5045 0.014617919921875 +5046 0.1029052734375 +5047 0.144378662109375 +5048 0.142822265625 +5049 0.221038818359375 +5050 0.168701171875 +5051 0.27069091796875 +5052 0.18060302734375 +5053 0.294036865234375 +5054 0.186737060546875 +5055 0.311767578125 +5056 0.193328857421875 +5057 0.339141845703125 +5058 0.194305419921875 +5059 0.360260009765625 +5060 0.184295654296875 +5061 0.360504150390625 +5062 0.151611328125 +5063 0.308380126953125 +5064 0.088348388671875 +5065 0.18170166015625 +5066 0.004852294921875 +5067 0.0047607421875 +5068 -0.0797119140625 +5069 -0.17559814453125 +5070 -0.146942138671875 +5071 -0.3143310546875 +5072 -0.179107666015625 +5073 -0.36785888671875 +5074 -0.185943603515625 +5075 -0.36248779296875 +5076 -0.184783935546875 +5077 -0.343536376953125 +5078 -0.17181396484375 +5079 -0.3018798828125 +5080 -0.144500732421875 +5081 -0.231414794921875 +5082 -0.097259521484375 +5083 -0.117645263671875 +5084 -0.042999267578125 +5085 0.007049560546875 +5086 -0.0035400390625 +5087 0.087982177734375 +5088 0.026214599609375 +5089 0.13946533203125 +5090 0.05072021484375 +5091 0.17425537109375 +5092 0.06768798828125 +5093 0.188201904296875 +5094 0.072540283203125 +5095 0.171234130859375 +5096 0.062744140625 +5097 0.118438720703125 +5098 0.04840087890625 +5099 0.05706787109375 +5100 0.02984619140625 +5101 -0.010711669921875 +5102 0.004119873046875 +5103 -0.0914306640625 +5104 -0.02008056640625 +5105 -0.162322998046875 +5106 -0.031585693359375 +5107 -0.194549560546875 +5108 -0.015167236328125 +5109 -0.1492919921875 +5110 0.031219482421875 +5111 -0.02166748046875 +5112 0.0826416015625 +5113 0.124053955078125 +5114 0.109375 +5115 0.211151123046875 +5116 0.112213134765625 +5117 0.240447998046875 +5118 0.103515625 +5119 0.242218017578125 +5120 0.086944580078125 +5121 0.2257080078125 +5122 0.06463623046875 +5123 0.194366455078125 +5124 0.025970458984375 +5125 0.115509033203125 +5126 -0.019927978515625 +5127 0.0128173828125 +5128 -0.05108642578125 +5129 -0.053802490234375 +5130 -0.076629638671875 +5131 -0.110626220703125 +5132 -0.111480712890625 +5133 -0.199493408203125 +5134 -0.146148681640625 +5135 -0.29437255859375 +5136 -0.15802001953125 +5137 -0.33221435546875 +5138 -0.13531494140625 +5139 -0.27972412109375 +5140 -0.095703125 +5141 -0.185333251953125 +5142 -0.06805419921875 +5143 -0.128204345703125 +5144 -0.055450439453125 +5145 -0.115692138671875 +5146 -0.047088623046875 +5147 -0.116455078125 +5148 -0.03460693359375 +5149 -0.105926513671875 +5150 -0.00762939453125 +5151 -0.053955078125 +5152 0.0367431640625 +5153 0.048797607421875 +5154 0.081939697265625 +5155 0.157318115234375 +5156 0.106201171875 +5157 0.212005615234375 +5158 0.111328125 +5159 0.218475341796875 +5160 0.1190185546875 +5161 0.23724365234375 +5162 0.142608642578125 +5163 0.30535888671875 +5164 0.167236328125 +5165 0.38128662109375 +5166 0.1712646484375 +5167 0.404449462890625 +5168 0.16204833984375 +5169 0.3944091796875 +5170 0.153411865234375 +5171 0.3885498046875 +5172 0.13702392578125 +5173 0.362640380859375 +5174 0.0977783203125 +5175 0.27362060546875 +5176 0.034515380859375 +5177 0.11712646484375 +5178 -0.03369140625 +5179 -0.054901123046875 +5180 -0.087921142578125 +5181 -0.19085693359375 +5182 -0.126129150390625 +5183 -0.28570556640625 +5184 -0.148101806640625 +5185 -0.339263916015625 +5186 -0.163055419921875 +5187 -0.3775634765625 +5188 -0.187225341796875 +5189 -0.445709228515625 +5190 -0.217559814453125 +5191 -0.535064697265625 +5192 -0.248260498046875 +5193 -0.629058837890625 +5194 -0.2686767578125 +5195 -0.697601318359375 +5196 -0.26580810546875 +5197 -0.70391845703125 +5198 -0.23797607421875 +5199 -0.6424560546875 +5200 -0.1776123046875 +5201 -0.491241455078125 +5202 -0.090606689453125 +5203 -0.265716552734375 +5204 0.00189208984375 +5205 -0.023712158203125 +5206 0.08770751953125 +5207 0.201751708984375 +5208 0.154052734375 +5209 0.375823974609375 +5210 0.1959228515625 +5211 0.485076904296875 +5212 0.227386474609375 +5213 0.56884765625 +5214 0.25115966796875 +5215 0.634765625 +5216 0.2509765625 +5217 0.63763427734375 +5218 0.22283935546875 +5219 0.5660400390625 +5220 0.185638427734375 +5221 0.4720458984375 +5222 0.158050537109375 +5223 0.40692138671875 +5224 0.1429443359375 +5225 0.3778076171875 +5226 0.137786865234375 +5227 0.376953125 +5228 0.13116455078125 +5229 0.371978759765625 +5230 0.10540771484375 +5231 0.313140869140625 +5232 0.055023193359375 +5233 0.184417724609375 +5234 -0.0106201171875 +5235 0.011199951171875 +5236 -0.078582763671875 +5237 -0.171051025390625 +5238 -0.139801025390625 +5239 -0.33740234375 +5240 -0.18853759765625 +5241 -0.47198486328125 +5242 -0.2196044921875 +5243 -0.560394287109375 +5244 -0.225128173828125 +5245 -0.58056640625 +5246 -0.210662841796875 +5247 -0.54754638671875 +5248 -0.193389892578125 +5249 -0.508575439453125 +5250 -0.1719970703125 +5251 -0.459503173828125 +5252 -0.144561767578125 +5253 -0.394378662109375 +5254 -0.125457763671875 +5255 -0.35260009765625 +5256 -0.106842041015625 +5257 -0.31170654296875 +5258 -0.06219482421875 +5259 -0.197418212890625 +5260 0.0089111328125 +5261 -0.007965087890625 +5262 0.088653564453125 +5263 0.207489013671875 +5264 0.16259765625 +5265 0.409210205078125 +5266 0.2216796875 +5267 0.57208251953125 +5268 0.25506591796875 +5269 0.66595458984375 +5270 0.251251220703125 +5271 0.65875244140625 +5272 0.2164306640625 +5273 0.56744384765625 +5274 0.164886474609375 +5275 0.431396484375 +5276 0.112579345703125 +5277 0.29443359375 +5278 0.069000244140625 +5279 0.182464599609375 +5280 0.02288818359375 +5281 0.06365966796875 +5282 -0.03057861328125 +5283 -0.075958251953125 +5284 -0.0743408203125 +5285 -0.189422607421875 +5286 -0.10650634765625 +5287 -0.271942138671875 +5288 -0.1337890625 +5289 -0.342529296875 +5290 -0.142822265625 +5291 -0.364166259765625 +5292 -0.130096435546875 +5293 -0.327239990234375 +5294 -0.111846923828125 +5295 -0.2769775390625 +5296 -0.1026611328125 +5297 -0.253692626953125 +5298 -0.097625732421875 +5299 -0.24365234375 +5300 -0.079376220703125 +5301 -0.1983642578125 +5302 -0.0474853515625 +5303 -0.116241455078125 +5304 -0.01629638671875 +5305 -0.036834716796875 +5306 0.01220703125 +5307 0.034881591796875 +5308 0.035125732421875 +5309 0.09124755859375 +5310 0.043914794921875 +5311 0.10888671875 +5312 0.052001953125 +5313 0.125518798828125 +5314 0.065277099609375 +5315 0.15771484375 +5316 0.0738525390625 +5317 0.17828369140625 +5318 0.071868896484375 +5319 0.17108154296875 +5320 0.057098388671875 +5321 0.129974365234375 +5322 0.039459228515625 +5323 0.082427978515625 +5324 0.018707275390625 +5325 0.027679443359375 +5326 -0.016357421875 +5327 -0.065643310546875 +5328 -0.0518798828125 +5329 -0.15936279296875 +5330 -0.0732421875 +5331 -0.21307373046875 +5332 -0.0831298828125 +5333 -0.234649658203125 +5334 -0.072845458984375 +5335 -0.2001953125 +5336 -0.045684814453125 +5337 -0.119171142578125 +5338 -0.013458251953125 +5339 -0.024749755859375 +5340 0.024871826171875 +5341 0.085784912109375 +5342 0.0570068359375 +5343 0.178131103515625 +5344 0.06976318359375 +5345 0.215576171875 +5346 0.0679931640625 +5347 0.211456298828125 +5348 0.05511474609375 +5349 0.17523193359375 +5350 0.038970947265625 +5351 0.128753662109375 +5352 0.030303955078125 +5353 0.1019287109375 +5354 0.021697998046875 +5355 0.0743408203125 +5356 0.012054443359375 +5357 0.04327392578125 +5358 0.01190185546875 +5359 0.038177490234375 +5360 0.027374267578125 +5361 0.076263427734375 +5362 0.052398681640625 +5363 0.14105224609375 +5364 0.070281982421875 +5365 0.186431884765625 +5366 0.07244873046875 +5367 0.188812255859375 +5368 0.055572509765625 +5369 0.1390380859375 +5370 0.02130126953125 +5371 0.041778564453125 +5372 -0.021942138671875 +5373 -0.079437255859375 +5374 -0.072296142578125 +5375 -0.219390869140625 +5376 -0.125701904296875 +5377 -0.367828369140625 +5378 -0.170928955078125 +5379 -0.494873046875 +5380 -0.192962646484375 +5381 -0.556243896484375 +5382 -0.1778564453125 +5383 -0.508697509765625 +5384 -0.133514404296875 +5385 -0.3756103515625 +5386 -0.080535888671875 +5387 -0.218902587890625 +5388 -0.027435302734375 +5389 -0.063751220703125 +5390 0.02606201171875 +5391 0.091552734375 +5392 0.07611083984375 +5393 0.23602294921875 +5394 0.113800048828125 +5395 0.342987060546875 +5396 0.13330078125 +5397 0.39520263671875 +5398 0.133392333984375 +5399 0.389373779296875 +5400 0.11358642578125 +5401 0.324249267578125 +5402 0.081787109375 +5403 0.224090576171875 +5404 0.049560546875 +5405 0.124267578125 +5406 0.02093505859375 +5407 0.037078857421875 +5408 0.0048828125 +5409 -0.010101318359375 +5410 0.000732421875 +5411 -0.019439697265625 +5412 -0.0018310546875 +5413 -0.022796630859375 +5414 0.003387451171875 +5415 -0.001556396484375 +5416 0.02044677734375 +5417 0.056304931640625 +5418 0.035003662109375 +5419 0.106719970703125 +5420 0.02984619140625 +5421 0.096893310546875 +5422 0.01031494140625 +5423 0.042694091796875 +5424 -0.011077880859375 +5425 -0.018035888671875 +5426 -0.031158447265625 +5427 -0.07586669921875 +5428 -0.046173095703125 +5429 -0.11944580078125 +5430 -0.0596923828125 +5431 -0.15972900390625 +5432 -0.073638916015625 +5433 -0.202606201171875 +5434 -0.088165283203125 +5435 -0.24859619140625 +5436 -0.10577392578125 +5437 -0.30517578125 +5438 -0.123199462890625 +5439 -0.36212158203125 +5440 -0.131317138671875 +5441 -0.39141845703125 +5442 -0.117828369140625 +5443 -0.35528564453125 +5444 -0.08160400390625 +5445 -0.249969482421875 +5446 -0.028472900390625 +5447 -0.092864990234375 +5448 0.032623291015625 +5449 0.08905029296875 +5450 0.081756591796875 +5451 0.2352294921875 +5452 0.110076904296875 +5453 0.318817138671875 +5454 0.12371826171875 +5455 0.358642578125 +5456 0.120391845703125 +5457 0.347747802734375 +5458 0.09991455078125 +5459 0.28564453125 +5460 0.0789794921875 +5461 0.223175048828125 +5462 0.069549560546875 +5463 0.196746826171875 +5464 0.06298828125 +5465 0.179840087890625 +5466 0.053802490234375 +5467 0.155548095703125 +5468 0.051055908203125 +5469 0.151214599609375 +5470 0.05157470703125 +5471 0.156951904296875 +5472 0.041961669921875 +5473 0.13177490234375 +5474 0.030548095703125 +5475 0.100799560546875 +5476 0.02496337890625 +5477 0.087127685546875 +5478 0.013519287109375 +5479 0.05487060546875 +5480 -0.00799560546875 +5481 -0.009002685546875 +5482 -0.039398193359375 +5483 -0.10400390625 +5484 -0.0804443359375 +5485 -0.229400634765625 +5486 -0.121429443359375 +5487 -0.35552978515625 +5488 -0.14910888671875 +5489 -0.441925048828125 +5490 -0.15869140625 +5491 -0.473846435546875 +5492 -0.1546630859375 +5493 -0.464813232421875 +5494 -0.13848876953125 +5495 -0.419097900390625 +5496 -0.109466552734375 +5497 -0.334320068359375 +5498 -0.0733642578125 +5499 -0.227935791015625 +5500 -0.0379638671875 +5501 -0.12347412109375 +5502 -0.00555419921875 +5503 -0.02764892578125 +5504 0.029754638671875 +5505 0.077667236328125 +5506 0.074737548828125 +5507 0.2132568359375 +5508 0.132568359375 +5509 0.38885498046875 +5510 0.196136474609375 +5511 0.582794189453125 +5512 0.24542236328125 +5513 0.734039306640625 +5514 0.266510009765625 +5515 0.800140380859375 +5516 0.258544921875 +5517 0.7783203125 +5518 0.220458984375 +5519 0.6651611328125 +5520 0.1519775390625 +5521 0.45965576171875 +5522 0.0654296875 +5523 0.199188232421875 +5524 -0.017608642578125 +5525 -0.050689697265625 +5526 -0.078338623046875 +5527 -0.23297119140625 +5528 -0.11102294921875 +5529 -0.33013916015625 +5530 -0.12420654296875 +5531 -0.368408203125 +5532 -0.1280517578125 +5533 -0.378936767578125 +5534 -0.127593994140625 +5535 -0.376983642578125 +5536 -0.128448486328125 +5537 -0.37969970703125 +5538 -0.132080078125 +5539 -0.391510009765625 +5540 -0.129608154296875 +5541 -0.385345458984375 +5542 -0.11474609375 +5543 -0.3419189453125 +5544 -0.094635009765625 +5545 -0.28289794921875 +5546 -0.08349609375 +5547 -0.251617431640625 +5548 -0.087310791015625 +5549 -0.266143798828125 +5550 -0.0887451171875 +5551 -0.273345947265625 +5552 -0.069305419921875 +5553 -0.216796875 +5554 -0.039459228515625 +5555 -0.128265380859375 +5556 -0.01904296875 +5557 -0.068145751953125 +5558 -0.01031494140625 +5559 -0.0430908203125 +5560 -0.003875732421875 +5561 -0.024444580078125 +5562 0.01104736328125 +5563 0.020721435546875 +5564 0.044921875 +5565 0.124481201171875 +5566 0.088287353515625 +5567 0.25787353515625 +5568 0.127471923828125 +5569 0.379119873046875 +5570 0.1597900390625 +5571 0.47991943359375 +5572 0.174774169921875 +5573 0.5281982421875 +5574 0.16827392578125 +5575 0.511138916015625 +5576 0.14935302734375 +5577 0.456207275390625 +5578 0.13250732421875 +5579 0.407470703125 +5580 0.12396240234375 +5581 0.383758544921875 +5582 0.114471435546875 +5583 0.35687255859375 +5584 0.099151611328125 +5585 0.31182861328125 +5586 0.078765869140625 +5587 0.250885009765625 +5588 0.050506591796875 +5589 0.1654052734375 +5590 0.0078125 +5591 0.035247802734375 +5592 -0.05010986328125 +5593 -0.142059326171875 +5594 -0.1131591796875 +5595 -0.33563232421875 +5596 -0.17779541015625 +5597 -0.5345458984375 +5598 -0.23846435546875 +5599 -0.72186279296875 +5600 -0.275238037109375 +5601 -0.836669921875 +5602 -0.272979736328125 +5603 -0.8326416015625 +5604 -0.238250732421875 +5605 -0.7296142578125 +5606 -0.18914794921875 +5607 -0.582550048828125 +5608 -0.14166259765625 +5609 -0.440093994140625 +5610 -0.10308837890625 +5611 -0.324310302734375 +5612 -0.0623779296875 +5613 -0.20147705078125 +5614 -0.01068115234375 +5615 -0.044647216796875 +5616 0.038116455078125 +5617 0.103973388671875 +5618 0.070220947265625 +5619 0.202392578125 +5620 0.090179443359375 +5621 0.264495849609375 +5622 0.113983154296875 +5623 0.338897705078125 +5624 0.14764404296875 +5625 0.443817138671875 +5626 0.17999267578125 +5627 0.545074462890625 +5628 0.202789306640625 +5629 0.6173095703125 +5630 0.21343994140625 +5631 0.6524658203125 +5632 0.2158203125 +5633 0.66339111328125 +5634 0.211822509765625 +5635 0.6561279296875 +5636 0.194244384765625 +5637 0.606781005859375 +5638 0.15911865234375 +5639 0.501190185546875 +5640 0.11065673828125 +5641 0.352783203125 +5642 0.053619384765625 +5643 0.176544189453125 +5644 -0.013824462890625 +5645 -0.034820556640625 +5646 -0.08453369140625 +5647 -0.258209228515625 +5648 -0.14312744140625 +5649 -0.44244384765625 +5650 -0.18572998046875 +5651 -0.5753173828125 +5652 -0.210784912109375 +5653 -0.65203857421875 +5654 -0.209014892578125 +5655 -0.641632080078125 +5656 -0.18572998046875 +5657 -0.562164306640625 +5658 -0.154083251953125 +5659 -0.458038330078125 +5660 -0.12042236328125 +5661 -0.350555419921875 +5662 -0.091064453125 +5663 -0.260528564453125 +5664 -0.067413330078125 +5665 -0.192108154296875 +5666 -0.04864501953125 +5667 -0.141937255859375 +5668 -0.03265380859375 +5669 -0.1021728515625 +5670 -0.016754150390625 +5671 -0.062896728515625 +5672 0.00238037109375 +5673 -0.011932373046875 +5674 0.02813720703125 +5675 0.062835693359375 +5676 0.05657958984375 +5677 0.148712158203125 +5678 0.086334228515625 +5679 0.241729736328125 +5680 0.119476318359375 +5681 0.34912109375 +5682 0.151947021484375 +5683 0.457305908203125 +5684 0.177093505859375 +5685 0.54388427734375 +5686 0.184326171875 +5687 0.5728759765625 +5688 0.16259765625 +5689 0.506591796875 +5690 0.1138916015625 +5691 0.351226806640625 +5692 0.05010986328125 +5693 0.146514892578125 +5694 -0.013031005859375 +5695 -0.05523681640625 +5696 -0.064178466796875 +5697 -0.21624755859375 +5698 -0.102630615234375 +5699 -0.334930419921875 +5700 -0.12579345703125 +5701 -0.402984619140625 +5702 -0.1396484375 +5703 -0.4412841796875 +5704 -0.15771484375 +5705 -0.49578857421875 +5706 -0.17803955078125 +5707 -0.5601806640625 +5708 -0.190582275390625 +5709 -0.600738525390625 +5710 -0.18548583984375 +5711 -0.584228515625 +5712 -0.15350341796875 +5713 -0.47930908203125 +5714 -0.0927734375 +5715 -0.27935791015625 +5716 -0.010650634765625 +5717 -0.0089111328125 +5718 0.073974609375 +5719 0.268798828125 +5720 0.139984130859375 +5721 0.482818603515625 +5722 0.178497314453125 +5723 0.60369873046875 +5724 0.194976806640625 +5725 0.650421142578125 +5726 0.201416015625 +5727 0.66400146484375 +5728 0.19683837890625 +5729 0.6414794921875 +5730 0.178070068359375 +5731 0.572540283203125 +5732 0.15716552734375 +5733 0.498138427734375 +5734 0.140380859375 +5735 0.439453125 +5736 0.1214599609375 +5737 0.375518798828125 +5738 0.09100341796875 +5739 0.274505615234375 +5740 0.0408935546875 +5741 0.1087646484375 +5742 -0.022186279296875 +5743 -0.099395751953125 +5744 -0.0887451171875 +5745 -0.3182373046875 +5746 -0.1590576171875 +5747 -0.5489501953125 +5748 -0.22772216796875 +5749 -0.7738037109375 +5750 -0.2789306640625 +5751 -0.86383056640625 +5752 -0.302764892578125 +5753 -0.870391845703125 +5754 -0.304351806640625 +5755 -0.86895751953125 +5756 -0.287506103515625 +5757 -0.861053466796875 +5758 -0.247039794921875 +5759 -0.765869140625 +5760 -0.179595947265625 +5761 -0.5301513671875 +5762 -0.087249755859375 +5763 -0.214691162109375 +5764 0.017242431640625 +5765 0.137359619140625 +5766 0.118682861328125 +5767 0.474822998046875 +5768 0.206512451171875 +5769 0.76239013671875 +5770 0.27264404296875 +5771 0.867462158203125 +5772 0.317138671875 +5773 0.870361328125 +5774 0.33648681640625 +5775 0.86480712890625 +5776 0.3321533203125 +5777 0.831817626953125 +5778 0.311279296875 +5779 0.677581787109375 +5780 0.2755126953125 +5781 0.495880126953125 +5782 0.23028564453125 +5783 0.30767822265625 +5784 0.17620849609375 +5785 0.116180419921875 +5786 0.103851318359375 +5787 -0.110748291015625 +5788 0.0111083984375 +5789 -0.381805419921875 +5790 -0.08929443359375 +5791 -0.6572265625 +5792 -0.179595947265625 +5793 -0.857421875 +5794 -0.247100830078125 +5795 -0.870391845703125 +5796 -0.289642333984375 +5797 -0.870391845703125 +5798 -0.315155029296875 +5799 -0.86444091796875 +5800 -0.3341064453125 +5801 -0.85723876953125 +5802 -0.34100341796875 +5803 -0.790008544921875 +5804 -0.3197021484375 +5805 -0.62847900390625 +5806 -0.26922607421875 +5807 -0.3956298828125 +5808 -0.199249267578125 +5809 -0.126708984375 +5810 -0.1177978515625 +5811 0.150115966796875 +5812 -0.0283203125 +5813 0.424041748046875 +5814 0.061187744140625 +5815 0.670623779296875 +5816 0.1392822265625 +5817 0.854522705078125 +5818 0.200714111328125 +5819 0.866485595703125 +5820 0.240936279296875 +5821 0.86920166015625 +5822 0.2652587890625 +5823 0.8653564453125 +5824 0.277618408203125 +5825 0.857147216796875 +5826 0.277099609375 +5827 0.766845703125 +5828 0.265167236328125 +5829 0.628509521484375 +5830 0.239776611328125 +5831 0.462127685546875 +5832 0.208526611328125 +5833 0.297210693359375 +5834 0.175018310546875 +5835 0.14862060546875 +5836 0.1324462890625 +5837 -0.00537109375 +5838 0.0830078125 +5839 -0.15753173828125 +5840 0.025634765625 +5841 -0.31304931640625 +5842 -0.0438232421875 +5843 -0.48876953125 +5844 -0.111480712890625 +5845 -0.6416015625 +5846 -0.16998291015625 +5847 -0.751373291015625 +5848 -0.22613525390625 +5849 -0.84619140625 +5850 -0.275543212890625 +5851 -0.861297607421875 +5852 -0.308380126953125 +5853 -0.863250732421875 +5854 -0.31524658203125 +5855 -0.856597900390625 +5856 -0.2996826171875 +5857 -0.7498779296875 +5858 -0.278778076171875 +5859 -0.624542236328125 +5860 -0.246002197265625 +5861 -0.47808837890625 +5862 -0.184051513671875 +5863 -0.253387451171875 +5864 -0.106414794921875 +5865 0.003692626953125 +5866 -0.0333251953125 +5867 0.2257080078125 +5868 0.038909912109375 +5869 0.427154541015625 +5870 0.119873046875 +5871 0.643218994140625 +5872 0.206695556640625 +5873 0.855926513671875 +5874 0.282196044921875 +5875 0.870361328125 +5876 0.3316650390625 +5877 0.870361328125 +5878 0.357208251953125 +5879 0.862762451171875 +5880 0.35791015625 +5881 0.79669189453125 +5882 0.330963134765625 +5883 0.595794677734375 +5884 0.28497314453125 +5885 0.362152099609375 +5886 0.22821044921875 +5887 0.1270751953125 +5888 0.166351318359375 +5889 -0.086944580078125 +5890 0.0997314453125 +5891 -0.2784423828125 +5892 0.01947021484375 +5893 -0.484832763671875 +5894 -0.078582763671875 +5895 -0.729583740234375 +5896 -0.1802978515625 +5897 -0.86688232421875 +5898 -0.268310546875 +5899 -0.870391845703125 +5900 -0.3408203125 +5901 -0.86859130859375 +5902 -0.3968505859375 +5903 -0.86279296875 +5904 -0.426727294921875 +5905 -0.817962646484375 +5906 -0.418426513671875 +5907 -0.6116943359375 +5908 -0.37017822265625 +5909 -0.3128662109375 +5910 -0.291107177734375 +5911 0.039398193359375 +5912 -0.186798095703125 +5913 0.422821044921875 +5914 -0.066497802734375 +5915 0.805145263671875 +5916 0.051300048828125 +5917 0.870361328125 +5918 0.15106201171875 +5919 0.870361328125 +5920 0.2291259765625 +5921 0.860015869140625 +5922 0.282958984375 +5923 0.727935791015625 +5924 0.310638427734375 +5925 0.48114013671875 +5926 0.318145751953125 +5927 0.2059326171875 +5928 0.3111572265625 +5929 -0.06103515625 +5930 0.292083740234375 +5931 -0.29913330078125 +5932 0.257049560546875 +5933 -0.516204833984375 +5934 0.202056884765625 +5935 -0.7252197265625 +5936 0.13385009765625 +5937 -0.85980224609375 +5938 0.061798095703125 +5939 -0.870391845703125 +5940 -0.005889892578125 +5941 -0.870391845703125 +5942 -0.055877685546875 +5943 -0.858062744140625 +5944 -0.0865478515625 +5945 -0.673004150390625 +5946 -0.111236572265625 +5947 -0.42694091796875 +5948 -0.141143798828125 +5949 -0.2100830078125 +5950 -0.17523193359375 +5951 -0.0362548828125 +5952 -0.205413818359375 +5953 0.10943603515625 +5954 -0.226043701171875 +5955 0.23516845703125 +5956 -0.225982666015625 +5957 0.373687744140625 +5958 -0.2056884765625 +5959 0.517791748046875 +5960 -0.181793212890625 +5961 0.602783203125 +5962 -0.153076171875 +5963 0.635711669921875 +5964 -0.1109619140625 +5965 0.655181884765625 +5966 -0.05841064453125 +5967 0.65948486328125 +5968 0.00201416015625 +5969 0.651275634765625 +5970 0.06341552734375 +5971 0.61846923828125 +5972 0.115509033203125 +5973 0.53753662109375 +5974 0.153076171875 +5975 0.404144287109375 +5976 0.173095703125 +5977 0.22186279296875 +5978 0.175537109375 +5979 0.003997802734375 +5980 0.16485595703125 +5981 -0.22100830078125 +5982 0.14630126953125 +5983 -0.42449951171875 +5984 0.125335693359375 +5985 -0.579833984375 +5986 0.113250732421875 +5987 -0.641876220703125 +5988 0.108367919921875 +5989 -0.6177978515625 +5990 0.09381103515625 +5991 -0.575531005859375 +5992 0.06842041015625 +5993 -0.526336669921875 +5994 0.04620361328125 +5995 -0.42645263671875 +5996 0.03472900390625 +5997 -0.2581787109375 +5998 0.02484130859375 +5999 -0.068695068359375 +6000 0.006805419921875 +6001 0.09222412109375 +6002 -0.0140380859375 +6003 0.232147216796875 +6004 -0.034637451171875 +6005 0.3509521484375 +6006 -0.062530517578125 +6007 0.410064697265625 +6008 -0.105224609375 +6009 0.372955322265625 +6010 -0.157073974609375 +6011 0.2554931640625 +6012 -0.2042236328125 +6013 0.10711669921875 +6014 -0.241485595703125 +6015 -0.052886962890625 +6016 -0.2593994140625 +6017 -0.186279296875 +6018 -0.243438720703125 +6019 -0.23291015625 +6020 -0.1998291015625 +6021 -0.209442138671875 +6022 -0.146270751953125 +6023 -0.174163818359375 +6024 -0.085296630859375 +6025 -0.126739501953125 +6026 -0.014617919921875 +6027 -0.048126220703125 +6028 0.05792236328125 +6029 0.0426025390625 +6030 0.11968994140625 +6031 0.10748291015625 +6032 0.166900634765625 +6033 0.1409912109375 +6034 0.211883544921875 +6035 0.19708251953125 +6036 0.252685546875 +6037 0.273651123046875 +6038 0.27447509765625 +6039 0.31768798828125 +6040 0.2801513671875 +6041 0.341094970703125 +6042 0.27642822265625 +6043 0.368011474609375 +6044 0.25732421875 +6045 0.37249755859375 +6046 0.209991455078125 +6047 0.30072021484375 +6048 0.135955810546875 +6049 0.1517333984375 +6050 0.053070068359375 +6051 -0.01470947265625 +6052 -0.03369140625 +6053 -0.1883544921875 +6054 -0.122955322265625 +6055 -0.372711181640625 +6056 -0.198333740234375 +6057 -0.51397705078125 +6058 -0.24713134765625 +6059 -0.57177734375 +6060 -0.26593017578125 +6061 -0.53948974609375 +6062 -0.258148193359375 +6063 -0.43511962890625 +6064 -0.232879638671875 +6065 -0.2962646484375 +6066 -0.199798583984375 +6067 -0.161102294921875 +6068 -0.162689208984375 +6069 -0.0435791015625 +6070 -0.121063232421875 +6071 0.060394287109375 +6072 -0.079681396484375 +6073 0.13665771484375 +6074 -0.04388427734375 +6075 0.170135498046875 +6076 -0.0140380859375 +6077 0.16552734375 +6078 0.017120361328125 +6079 0.15728759765625 +6080 0.049102783203125 +6081 0.150787353515625 +6082 0.07373046875 +6083 0.12200927734375 +6084 0.091705322265625 +6085 0.080108642578125 +6086 0.108428955078125 +6087 0.05126953125 +6088 0.129974365234375 +6089 0.062896728515625 +6090 0.14959716796875 +6091 0.09271240234375 +6092 0.154266357421875 +6093 0.092987060546875 +6094 0.1478271484375 +6095 0.07855224609375 +6096 0.13458251953125 +6097 0.06427001953125 +6098 0.111175537109375 +6099 0.0347900390625 +6100 0.078125 +6101 -0.01171875 +6102 0.041839599609375 +6103 -0.056060791015625 +6104 0.0150146484375 +6105 -0.055511474609375 +6106 -0.000885009765625 +6107 -0.010467529296875 +6108 -0.0185546875 +6109 0.02508544921875 +6110 -0.04327392578125 +6111 0.025665283203125 +6112 -0.066864013671875 +6113 0.017333984375 +6114 -0.087799072265625 +6115 0.00189208984375 +6116 -0.10821533203125 +6117 -0.03173828125 +6118 -0.12445068359375 +6119 -0.071502685546875 +6120 -0.14111328125 +6121 -0.13543701171875 +6122 -0.157470703125 +6123 -0.219970703125 +6124 -0.16748046875 +6125 -0.300506591796875 +6126 -0.171722412109375 +6127 -0.376312255859375 +6128 -0.1629638671875 +6129 -0.416107177734375 +6130 -0.12945556640625 +6131 -0.371124267578125 +6132 -0.072662353515625 +6133 -0.242279052734375 +6134 -0.004486083984375 +6135 -0.069732666015625 +6136 0.06829833984375 +6137 0.125640869140625 +6138 0.136322021484375 +6139 0.31268310546875 +6140 0.189056396484375 +6141 0.45501708984375 +6142 0.226348876953125 +6143 0.554779052734375 +6144 0.247161865234375 +6145 0.61065673828125 +6146 0.24835205078125 +6147 0.610931396484375 +6148 0.224212646484375 +6149 0.531463623046875 +6150 0.179229736328125 +6151 0.3883056640625 +6152 0.12738037109375 +6153 0.23468017578125 +6154 0.07574462890625 +6155 0.095245361328125 +6156 0.0318603515625 +6157 -0.00396728515625 +6158 0.000396728515625 +6159 -0.04852294921875 +6160 -0.021636962890625 +6161 -0.055145263671875 +6162 -0.046112060546875 +6163 -0.0758056640625 +6164 -0.079071044921875 +6165 -0.138702392578125 +6166 -0.1109619140625 +6167 -0.209197998046875 +6168 -0.14154052734375 +6169 -0.289031982421875 +6170 -0.170501708984375 +6171 -0.37884521484375 +6172 -0.1920166015625 +6173 -0.456329345703125 +6174 -0.204864501953125 +6175 -0.51641845703125 +6176 -0.199310302734375 +6177 -0.519287109375 +6178 -0.174163818359375 +6179 -0.458251953125 +6180 -0.142913818359375 +6181 -0.384796142578125 +6182 -0.112548828125 +6183 -0.323699951171875 +6184 -0.082489013671875 +6185 -0.269287109375 +6186 -0.047149658203125 +6187 -0.1951904296875 +6188 -0.007080078125 +6189 -0.100006103515625 +6190 0.030120849609375 +6191 -0.01055908203125 +6192 0.07122802734375 +6193 0.1033935546875 +6194 0.117431640625 +6195 0.24908447265625 +6196 0.15496826171875 +6197 0.373199462890625 +6198 0.17913818359375 +6199 0.45806884765625 +6200 0.191802978515625 +6201 0.511474609375 +6202 0.20111083984375 +6203 0.565399169921875 +6204 0.205291748046875 +6205 0.61138916015625 +6206 0.189910888671875 +6207 0.5897216796875 +6208 0.153106689453125 +6209 0.4906005859375 +6210 0.100006103515625 +6211 0.33148193359375 +6212 0.04022216796875 +6213 0.147796630859375 +6214 -0.015045166015625 +6215 -0.01873779296875 +6216 -0.058074951171875 +6217 -0.140289306640625 +6218 -0.082000732421875 +6219 -0.191986083984375 +6220 -0.088897705078125 +6221 -0.184295654296875 +6222 -0.089508056640625 +6223 -0.161834716796875 +6224 -0.094024658203125 +6225 -0.166595458984375 +6226 -0.1011962890625 +6227 -0.19390869140625 +6228 -0.10626220703125 +6229 -0.22442626953125 +6230 -0.114837646484375 +6231 -0.279754638671875 +6232 -0.1220703125 +6233 -0.3389892578125 +6234 -0.11651611328125 +6235 -0.3543701171875 +6236 -0.10430908203125 +6237 -0.348175048828125 +6238 -0.087432861328125 +6239 -0.32598876953125 +6240 -0.059112548828125 +6241 -0.2581787109375 +6242 -0.01873779296875 +6243 -0.139801025390625 +6244 0.029449462890625 +6245 0.014617919921875 +6246 0.069793701171875 +6247 0.144378662109375 +6248 0.09478759765625 +6249 0.221038818359375 +6250 0.110687255859375 +6251 0.27069091796875 +6252 0.117584228515625 +6253 0.294036865234375 +6254 0.12066650390625 +6255 0.311767578125 +6256 0.123809814453125 +6257 0.339141845703125 +6258 0.123077392578125 +6259 0.360260009765625 +6260 0.115264892578125 +6261 0.360504150390625 +6262 0.093658447265625 +6263 0.308380126953125 +6264 0.0537109375 +6265 0.18170166015625 +6266 0.001739501953125 +6267 0.0047607421875 +6268 -0.05072021484375 +6269 -0.17559814453125 +6270 -0.0926513671875 +6271 -0.3143310546875 +6272 -0.113433837890625 +6273 -0.36785888671875 +6274 -0.118743896484375 +6275 -0.36248779296875 +6276 -0.1187744140625 +6277 -0.343536376953125 +6278 -0.111236572265625 +6279 -0.3018798828125 +6280 -0.09466552734375 +6281 -0.231414794921875 +6282 -0.0657958984375 +6283 -0.117645263671875 +6284 -0.032318115234375 +6285 0.007049560546875 +6286 -0.007232666015625 +6287 0.087982177734375 +6288 0.012359619140625 +6289 0.13946533203125 +6290 0.028961181640625 +6291 0.17425537109375 +6292 0.041107177734375 +6293 0.188201904296875 +6294 0.04595947265625 +6295 0.171234130859375 +6296 0.041900634765625 +6297 0.118438720703125 +6298 0.034881591796875 +6299 0.05706787109375 +6300 0.02496337890625 +6301 -0.010711669921875 +6302 0.0103759765625 +6303 -0.0914306640625 +6304 -0.00372314453125 +6305 -0.162322998046875 +6306 -0.0107421875 +6307 -0.194549560546875 +6308 -0.001678466796875 +6309 -0.1492919921875 +6310 0.02471923828125 +6311 -0.02166748046875 +6312 0.053802490234375 +6313 0.124053955078125 +6314 0.068023681640625 +6315 0.211151123046875 +6316 0.067962646484375 +6317 0.240447998046875 +6318 0.061065673828125 +6319 0.242218017578125 +6320 0.049896240234375 +6321 0.2257080078125 +6322 0.035614013671875 +6323 0.194366455078125 +6324 0.011016845703125 +6325 0.115509033203125 +6326 -0.01800537109375 +6327 0.0128173828125 +6328 -0.037322998046875 +6329 -0.053802490234375 +6330 -0.0528564453125 +6331 -0.110626220703125 +6332 -0.074249267578125 +6333 -0.199493408203125 +6334 -0.095458984375 +6335 -0.29437255859375 +6336 -0.101959228515625 +6337 -0.33221435546875 +6338 -0.086181640625 +6339 -0.27972412109375 +6340 -0.059600830078125 +6341 -0.185333251953125 +6342 -0.0408935546875 +6343 -0.128204345703125 +6344 -0.032073974609375 +6345 -0.115692138671875 +6346 -0.02618408203125 +6347 -0.116455078125 +6348 -0.01788330078125 +6349 -0.105926513671875 +6350 -0.00048828125 +6351 -0.053955078125 +6352 0.02789306640625 +6353 0.048797607421875 +6354 0.05657958984375 +6355 0.157318115234375 +6356 0.071563720703125 +6357 0.212005615234375 +6358 0.074066162109375 +6359 0.218475341796875 +6360 0.078125 +6361 0.23724365234375 +6362 0.092376708984375 +6363 0.30535888671875 +6364 0.1072998046875 +6365 0.38128662109375 +6366 0.1090087890625 +6367 0.404449462890625 +6368 0.102294921875 +6369 0.3944091796875 +6370 0.0960693359375 +6371 0.3885498046875 +6372 0.08502197265625 +6373 0.362640380859375 +6374 0.0594482421875 +6375 0.27362060546875 +6376 0.018585205078125 +6377 0.11712646484375 +6378 -0.0252685546875 +6379 -0.054901123046875 +6380 -0.0599365234375 +6381 -0.19085693359375 +6382 -0.084075927734375 +6383 -0.28570556640625 +6384 -0.097564697265625 +6385 -0.339263916015625 +6386 -0.106414794921875 +6387 -0.3775634765625 +6388 -0.121124267578125 +6389 -0.445709228515625 +6390 -0.139801025390625 +6391 -0.535064697265625 +6392 -0.15875244140625 +6393 -0.629058837890625 +6394 -0.171142578125 +6395 -0.697601318359375 +6396 -0.168670654296875 +6397 -0.70391845703125 +6398 -0.150238037109375 +6399 -0.6424560546875 +6400 -0.111480712890625 +6401 -0.491241455078125 +6402 -0.056365966796875 +6403 -0.265716552734375 +6404 0.002227783203125 +6405 -0.023712158203125 +6406 0.056976318359375 +6407 0.201751708984375 +6408 0.10028076171875 +6409 0.375823974609375 +6410 0.12896728515625 +6411 0.485076904296875 +6412 0.1505126953125 +6413 0.56884765625 +6414 0.166229248046875 +6415 0.634765625 +6416 0.1669921875 +6417 0.63763427734375 +6418 0.150604248046875 +6419 0.5660400390625 +6420 0.127655029296875 +6421 0.4720458984375 +6422 0.10870361328125 +6423 0.40692138671875 +6424 0.095550537109375 +6425 0.3778076171875 +6426 0.087127685546875 +6427 0.376953125 +6428 0.077423095703125 +6429 0.371978759765625 +6430 0.056976318359375 +6431 0.313140869140625 +6432 0.023101806640625 +6433 0.184417724609375 +6434 -0.0186767578125 +6435 0.011199951171875 +6436 -0.060882568359375 +6437 -0.171051025390625 +6438 -0.098236083984375 +6439 -0.33740234375 +6440 -0.127410888671875 +6441 -0.47198486328125 +6442 -0.14544677734375 +6443 -0.560394287109375 +6444 -0.147979736328125 +6445 -0.58056640625 +6446 -0.13812255859375 +6447 -0.54754638671875 +6448 -0.1256103515625 +6449 -0.508575439453125 +6450 -0.109893798828125 +6451 -0.459503173828125 +6452 -0.090118408203125 +6453 -0.394378662109375 +6454 -0.074554443359375 +6455 -0.35260009765625 +6456 -0.059112548828125 +6457 -0.31170654296875 +6458 -0.02935791015625 +6459 -0.197418212890625 +6460 0.014678955078125 +6461 -0.007965087890625 +6462 0.06280517578125 +6463 0.207489013671875 +6464 0.10687255859375 +6465 0.409210205078125 +6466 0.141693115234375 +6467 0.57208251953125 +6468 0.161163330078125 +6469 0.66595458984375 +6470 0.158843994140625 +6471 0.65875244140625 +6472 0.138275146484375 +6473 0.56744384765625 +6474 0.107452392578125 +6475 0.431396484375 +6476 0.075408935546875 +6477 0.29443359375 +6478 0.047607421875 +6479 0.182464599609375 +6480 0.01800537109375 +6481 0.06365966796875 +6482 -0.015838623046875 +6483 -0.075958251953125 +6484 -0.044219970703125 +6485 -0.189422607421875 +6486 -0.06585693359375 +6487 -0.271942138671875 +6488 -0.08428955078125 +6489 -0.342529296875 +6490 -0.091949462890625 +6491 -0.364166259765625 +6492 -0.086761474609375 +6493 -0.327239990234375 +6494 -0.077667236328125 +6495 -0.2769775390625 +6496 -0.072723388671875 +6497 -0.253692626953125 +6498 -0.0692138671875 +6499 -0.24365234375 +6500 -0.05755615234375 +6501 -0.1983642578125 +6502 -0.03759765625 +6503 -0.116241455078125 +6504 -0.0174560546875 +6505 -0.036834716796875 +6506 0.0015869140625 +6507 0.034881591796875 +6508 0.0177001953125 +6509 0.09124755859375 +6510 0.025970458984375 +6511 0.10888671875 +6512 0.03369140625 +6513 0.125518798828125 +6514 0.043914794921875 +6515 0.15771484375 +6516 0.051025390625 +6517 0.17828369140625 +6518 0.0516357421875 +6519 0.17108154296875 +6520 0.044464111328125 +6521 0.129974365234375 +6522 0.034942626953125 +6523 0.082427978515625 +6524 0.022979736328125 +6525 0.027679443359375 +6526 0.00238037109375 +6527 -0.065643310546875 +6528 -0.01904296875 +6529 -0.15936279296875 +6530 -0.033050537109375 +6531 -0.21307373046875 +6532 -0.041046142578125 +6533 -0.234649658203125 +6534 -0.03802490234375 +6535 -0.2001953125 +6536 -0.025665283203125 +6537 -0.119171142578125 +6538 -0.010406494140625 +6539 -0.024749755859375 +6540 0.008453369140625 +6541 0.085784912109375 +6542 0.024200439453125 +6543 0.178131103515625 +6544 0.0296630859375 +6545 0.215576171875 +6546 0.027587890625 +6547 0.211456298828125 +6548 0.01995849609375 +6549 0.17523193359375 +6550 0.011138916015625 +6551 0.128753662109375 +6552 0.007049560546875 +6553 0.1019287109375 +6554 0.003509521484375 +6555 0.0743408203125 +6556 -0.000152587890625 +6557 0.04327392578125 +6558 0.001800537109375 +6559 0.038177490234375 +6560 0.012603759765625 +6561 0.076263427734375 +6562 0.028778076171875 +6563 0.14105224609375 +6564 0.040924072265625 +6565 0.186431884765625 +6566 0.044158935546875 +6567 0.188812255859375 +6568 0.036529541015625 +6569 0.1390380859375 +6570 0.018890380859375 +6571 0.041778564453125 +6572 -0.004150390625 +6573 -0.079437255859375 +6574 -0.031585693359375 +6575 -0.219390869140625 +6576 -0.06134033203125 +6577 -0.367828369140625 +6578 -0.08746337890625 +6579 -0.494873046875 +6580 -0.101043701171875 +6581 -0.556243896484375 +6582 -0.09332275390625 +6583 -0.508697509765625 +6584 -0.068878173828125 +6585 -0.3756103515625 +6586 -0.039947509765625 +6587 -0.218902587890625 +6588 -0.011444091796875 +6589 -0.063751220703125 +6590 0.01702880859375 +6591 0.091552734375 +6592 0.04345703125 +6593 0.23602294921875 +6594 0.062652587890625 +6595 0.342987060546875 +6596 0.0712890625 +6597 0.39520263671875 +6598 0.06878662109375 +6599 0.389373779296875 +6600 0.054962158203125 +6601 0.324249267578125 +6602 0.034698486328125 +6603 0.224090576171875 +6604 0.01507568359375 +6605 0.124267578125 +6606 -0.001495361328125 +6607 0.037078857421875 +6608 -0.009552001953125 +6609 -0.010101318359375 +6610 -0.0096435546875 +6611 -0.019439697265625 +6612 -0.008270263671875 +6613 -0.022796630859375 +6614 -0.0018310546875 +6615 -0.001556396484375 +6616 0.011932373046875 +6617 0.056304931640625 +6618 0.024078369140625 +6619 0.106719970703125 +6620 0.02398681640625 +6621 0.096893310546875 +6622 0.01470947265625 +6623 0.042694091796875 +6624 0.003753662109375 +6625 -0.018035888671875 +6626 -0.00701904296875 +6627 -0.07586669921875 +6628 -0.015380859375 +6629 -0.11944580078125 +6630 -0.023529052734375 +6631 -0.15972900390625 +6632 -0.032623291015625 +6633 -0.202606201171875 +6634 -0.042694091796875 +6635 -0.24859619140625 +6636 -0.05517578125 +6637 -0.30517578125 +6638 -0.0679931640625 +6639 -0.36212158203125 +6640 -0.075469970703125 +6641 -0.39141845703125 +6642 -0.0699462890625 +6643 -0.35528564453125 +6644 -0.050567626953125 +6645 -0.249969482421875 +6646 -0.020751953125 +6647 -0.092864990234375 +6648 0.01416015625 +6649 0.08905029296875 +6650 0.04217529296875 +6651 0.2352294921875 +6652 0.0579833984375 +6653 0.318817138671875 +6654 0.06536865234375 +6655 0.358642578125 +6656 0.063568115234375 +6657 0.347747802734375 +6658 0.053131103515625 +6659 0.28564453125 +6660 0.042999267578125 +6661 0.223175048828125 +6662 0.039031982421875 +6663 0.196746826171875 +6664 0.03656005859375 +6665 0.179840087890625 +6666 0.0325927734375 +6667 0.155548095703125 +6668 0.0316162109375 +6669 0.151214599609375 +6670 0.031951904296875 +6671 0.156951904296875 +6672 0.026702880859375 +6673 0.13177490234375 +6674 0.0201416015625 +6675 0.100799560546875 +6676 0.0162353515625 +6677 0.087127685546875 +6678 0.009063720703125 +6679 0.05487060546875 +6680 -0.00341796875 +6681 -0.009002685546875 +6682 -0.021026611328125 +6683 -0.10400390625 +6684 -0.043548583984375 +6685 -0.229400634765625 +6686 -0.065887451171875 +6687 -0.35552978515625 +6688 -0.081207275390625 +6689 -0.441925048828125 +6690 -0.08697509765625 +6691 -0.473846435546875 +6692 -0.085418701171875 +6693 -0.464813232421875 +6694 -0.0772705078125 +6695 -0.419097900390625 +6696 -0.062164306640625 +6697 -0.334320068359375 +6698 -0.0430908203125 +6699 -0.227935791015625 +6700 -0.024078369140625 +6701 -0.12347412109375 +6702 -0.00634765625 +6703 -0.02764892578125 +6704 0.013031005859375 +6705 0.077667236328125 +6706 0.037445068359375 +6707 0.2132568359375 +6708 0.06842041015625 +6709 0.38885498046875 +6710 0.102294921875 +6711 0.582794189453125 +6712 0.12872314453125 +6713 0.734039306640625 +6714 0.1405029296875 +6715 0.800140380859375 +6716 0.13714599609375 +6717 0.7783203125 +6718 0.118072509765625 +6719 0.6651611328125 +6720 0.083160400390625 +6721 0.45965576171875 +6722 0.038726806640625 +6723 0.199188232421875 +6724 -0.004150390625 +6725 -0.050689697265625 +6726 -0.035858154296875 +6727 -0.23297119140625 +6728 -0.05340576171875 +6729 -0.33013916015625 +6730 -0.06109619140625 +6731 -0.368408203125 +6732 -0.064117431640625 +6733 -0.378936767578125 +6734 -0.064971923828125 +6735 -0.376983642578125 +6736 -0.06646728515625 +6737 -0.37969970703125 +6738 -0.069305419921875 +6739 -0.391510009765625 +6740 -0.068878173828125 +6741 -0.385345458984375 +6742 -0.061920166015625 +6743 -0.3419189453125 +6744 -0.05206298828125 +6745 -0.28289794921875 +6746 -0.046600341796875 +6747 -0.251617431640625 +6748 -0.048583984375 +6749 -0.266143798828125 +6750 -0.049102783203125 +6751 -0.273345947265625 +6752 -0.03875732421875 +6753 -0.216796875 +6754 -0.02288818359375 +6755 -0.128265380859375 +6756 -0.011688232421875 +6757 -0.068145751953125 +6758 -0.006378173828125 +6759 -0.0430908203125 +6760 -0.002166748046875 +6761 -0.024444580078125 +6762 0.006378173828125 +6763 0.020721435546875 +6764 0.024566650390625 +6765 0.124481201171875 +6766 0.047515869140625 +6767 0.25787353515625 +6768 0.06817626953125 +6769 0.379119873046875 +6770 0.08514404296875 +6771 0.47991943359375 +6772 0.093048095703125 +6773 0.5281982421875 +6774 0.0897216796875 +6775 0.511138916015625 +6776 0.079833984375 +6777 0.456207275390625 +6778 0.070831298828125 +6779 0.407470703125 +6780 0.065948486328125 +6781 0.383758544921875 +6782 0.060455322265625 +6783 0.35687255859375 +6784 0.0518798828125 +6785 0.31182861328125 +6786 0.0406494140625 +6787 0.250885009765625 +6788 0.025421142578125 +6789 0.1654052734375 +6790 0.002838134765625 +6791 0.035247802734375 +6792 -0.027435302734375 +6793 -0.142059326171875 +6794 -0.060211181640625 +6795 -0.33563232421875 +6796 -0.0936279296875 +6797 -0.5345458984375 +6798 -0.124847412109375 +6799 -0.72186279296875 +6800 -0.143646240234375 +6801 -0.836669921875 +6802 -0.142303466796875 +6803 -0.8326416015625 +6804 -0.124176025390625 +6805 -0.7296142578125 +6806 -0.09857177734375 +6807 -0.582550048828125 +6808 -0.07373046875 +6809 -0.440093994140625 +6810 -0.053375244140625 +6811 -0.324310302734375 +6812 -0.031890869140625 +6813 -0.20147705078125 +6814 -0.004791259765625 +6815 -0.044647216796875 +6816 0.020751953125 +6817 0.103973388671875 +6818 0.03765869140625 +6819 0.202392578125 +6820 0.048248291015625 +6821 0.264495849609375 +6822 0.0606689453125 +6823 0.338897705078125 +6824 0.0780029296875 +6825 0.443817138671875 +6826 0.09454345703125 +6827 0.545074462890625 +6828 0.106048583984375 +6829 0.6173095703125 +6830 0.111236572265625 +6831 0.6524658203125 +6832 0.1123046875 +6833 0.66339111328125 +6834 0.11029052734375 +6835 0.6561279296875 +6836 0.1011962890625 +6837 0.606781005859375 +6838 0.08270263671875 +6839 0.501190185546875 +6840 0.05712890625 +6841 0.352783203125 +6842 0.027008056640625 +6843 0.176544189453125 +6844 -0.008819580078125 +6845 -0.034820556640625 +6846 -0.046417236328125 +6847 -0.258209228515625 +6848 -0.077239990234375 +6849 -0.44244384765625 +6850 -0.0992431640625 +6851 -0.5753173828125 +6852 -0.11163330078125 +6853 -0.65203857421875 +6854 -0.109283447265625 +6855 -0.641632080078125 +6856 -0.095245361328125 +6857 -0.562164306640625 +6858 -0.077056884765625 +6859 -0.458038330078125 +6860 -0.058319091796875 +6861 -0.350555419921875 +6862 -0.04254150390625 +6863 -0.260528564453125 +6864 -0.03045654296875 +6865 -0.192108154296875 +6866 -0.02154541015625 +6867 -0.141937255859375 +6868 -0.01446533203125 +6869 -0.1021728515625 +6870 -0.007598876953125 +6871 -0.062896728515625 +6872 0.001068115234375 +6873 -0.011932373046875 +6874 0.013580322265625 +6875 0.062835693359375 +6876 0.027801513671875 +6877 0.148712158203125 +6878 0.043060302734375 +6879 0.241729736328125 +6880 0.06060791015625 +6881 0.34912109375 +6882 0.078216552734375 +6883 0.457305908203125 +6884 0.092132568359375 +6885 0.54388427734375 +6886 0.096343994140625 +6887 0.5728759765625 +6888 0.084564208984375 +6889 0.506591796875 +6890 0.057861328125 +6891 0.351226806640625 +6892 0.02294921875 +6893 0.146514892578125 +6894 -0.011322021484375 +6895 -0.05523681640625 +6896 -0.038604736328125 +6897 -0.21624755859375 +6898 -0.058624267578125 +6899 -0.334930419921875 +6900 -0.0699462890625 +6901 -0.402984619140625 +6902 -0.07611083984375 +6903 -0.4412841796875 +6904 -0.084869384765625 +6905 -0.49578857421875 +6906 -0.095184326171875 +6907 -0.5601806640625 +6908 -0.1014404296875 +6909 -0.600738525390625 +6910 -0.09808349609375 +6911 -0.584228515625 +6912 -0.0802001953125 +6913 -0.47930908203125 +6914 -0.04736328125 +6915 -0.27935791015625 +6916 -0.00390625 +6917 -0.0089111328125 +6918 0.04083251953125 +6919 0.268798828125 +6920 0.0765380859375 +6921 0.482818603515625 +6922 0.098724365234375 +6923 0.60369873046875 +6924 0.109588623046875 +6925 0.650421142578125 +6926 0.11444091796875 +6927 0.66400146484375 +6928 0.112762451171875 +6929 0.6414794921875 +6930 0.103118896484375 +6931 0.572540283203125 +6932 0.091156005859375 +6933 0.498138427734375 +6934 0.0799560546875 +6935 0.439453125 +6936 0.066925048828125 +6937 0.375518798828125 +6938 0.048004150390625 +6939 0.274505615234375 +6940 0.019775390625 +6941 0.1087646484375 +6942 -0.01434326171875 +6943 -0.099395751953125 +6944 -0.0496826171875 +6945 -0.3182373046875 +6946 -0.086090087890625 +6947 -0.5489501953125 +6948 -0.120880126953125 +6949 -0.7738037109375 +6950 -0.14666748046875 +6951 -0.86383056640625 +6952 -0.15875244140625 +6953 -0.870391845703125 +6954 -0.15948486328125 +6955 -0.86895751953125 +6956 -0.150665283203125 +6957 -0.861053466796875 +6958 -0.1300048828125 +6959 -0.765869140625 +6960 -0.096099853515625 +6961 -0.5301513671875 +6962 -0.050079345703125 +6963 -0.214691162109375 +6964 0.001983642578125 +6965 0.137359619140625 +6966 0.0528564453125 +6967 0.474822998046875 +6968 0.097442626953125 +6969 0.76239013671875 +6970 0.131805419921875 +6971 0.867462158203125 +6972 0.155731201171875 +6973 0.870361328125 +6974 0.16741943359375 +6975 0.86480712890625 +6976 0.167449951171875 +6977 0.831817626953125 +6978 0.159027099609375 +6979 0.677581787109375 +6980 0.142852783203125 +6981 0.495880126953125 +6982 0.121429443359375 +6983 0.30767822265625 +6984 0.0950927734375 +6985 0.116180419921875 +6986 0.05963134765625 +6987 -0.110748291015625 +6988 0.01422119140625 +6989 -0.381805419921875 +6990 -0.03509521484375 +6991 -0.6572265625 +6992 -0.0799560546875 +6993 -0.857421875 +6994 -0.114349365234375 +6995 -0.870391845703125 +6996 -0.137115478515625 +6997 -0.870391845703125 +6998 -0.1517333984375 +6999 -0.86444091796875 +7000 -0.162872314453125 +7001 -0.85723876953125 +7002 -0.167877197265625 +7003 -0.790008544921875 +7004 -0.15924072265625 +7005 -0.62847900390625 +7006 -0.136474609375 +7007 -0.3956298828125 +7008 -0.10400390625 +7009 -0.126708984375 +7010 -0.06561279296875 +7011 0.150115966796875 +7012 -0.02294921875 +7013 0.424041748046875 +7014 0.020233154296875 +7015 0.670623779296875 +7016 0.058563232421875 +7017 0.854522705078125 +7018 0.089447021484375 +7019 0.866485595703125 +7020 0.11065673828125 +7021 0.86920166015625 +7022 0.124481201171875 +7023 0.8653564453125 +7024 0.132598876953125 +7025 0.857147216796875 +7026 0.13446044921875 +7027 0.766845703125 +7028 0.130645751953125 +7029 0.628509521484375 +7030 0.1201171875 +7031 0.462127685546875 +7032 0.1063232421875 +7033 0.297210693359375 +7034 0.09088134765625 +7035 0.14862060546875 +7036 0.0706787109375 +7037 -0.00537109375 +7038 0.04681396484375 +7039 -0.15753173828125 +7040 0.01885986328125 +7041 -0.31304931640625 +7042 -0.01495361328125 +7043 -0.48876953125 +7044 -0.048126220703125 +7045 -0.6416015625 +7046 -0.077178955078125 +7047 -0.751373291015625 +7048 -0.105133056640625 +7049 -0.84619140625 +7050 -0.129852294921875 +7051 -0.861297607421875 +7052 -0.146697998046875 +7053 -0.863250732421875 +7054 -0.151275634765625 +7055 -0.856597900390625 +7056 -0.1451416015625 +7057 -0.7498779296875 +7058 -0.1361083984375 +7059 -0.624542236328125 +7060 -0.12115478515625 +7061 -0.47808837890625 +7062 -0.092315673828125 +7063 -0.253387451171875 +7064 -0.055816650390625 +7065 0.003692626953125 +7066 -0.021026611328125 +7067 0.2257080078125 +7068 0.013641357421875 +7069 0.427154541015625 +7070 0.052490234375 +7071 0.643218994140625 +7072 0.094085693359375 +7073 0.855926513671875 +7074 0.130462646484375 +7075 0.870361328125 +7076 0.154754638671875 +7077 0.870361328125 +7078 0.167877197265625 +7079 0.862762451171875 +7080 0.16937255859375 +7081 0.79669189453125 +7082 0.157867431640625 +7083 0.595794677734375 +7084 0.137298583984375 +7085 0.362152099609375 +7086 0.111419677734375 +7087 0.1270751953125 +7088 0.083099365234375 +7089 -0.086944580078125 +7090 0.052642822265625 +7091 -0.2784423828125 +7092 0.015350341796875 +7093 -0.484832763671875 +7094 -0.031280517578125 +7095 -0.729583740234375 +7096 -0.080291748046875 +7097 -0.86688232421875 +7098 -0.123016357421875 +7099 -0.870391845703125 +7100 -0.158660888671875 +7101 -0.86859130859375 +7102 -0.186859130859375 +7103 -0.86279296875 +7104 -0.20263671875 +7105 -0.817962646484375 +7106 -0.199737548828125 +7107 -0.6116943359375 +7108 -0.177154541015625 +7109 -0.3128662109375 +7110 -0.139434814453125 +7111 0.039398193359375 +7112 -0.089263916015625 +7113 0.422821044921875 +7114 -0.031158447265625 +7115 0.805145263671875 +7116 0.025543212890625 +7117 0.870361328125 +7118 0.07305908203125 +7119 0.870361328125 +7120 0.1097412109375 +7121 0.860015869140625 +7122 0.134490966796875 +7123 0.727935791015625 +7124 0.146453857421875 +7125 0.48114013671875 +7126 0.148834228515625 +7127 0.2059326171875 +7128 0.14459228515625 +7129 -0.06103515625 +7130 0.135009765625 +7131 -0.29913330078125 +7132 0.1180419921875 +7133 -0.516204833984375 +7134 0.091583251953125 +7135 -0.7252197265625 +7136 0.0589599609375 +7137 -0.85980224609375 +7138 0.02484130859375 +7139 -0.870391845703125 +7140 -0.0067138671875 +7141 -0.870391845703125 +7142 -0.029052734375 +7143 -0.858062744140625 +7144 -0.04150390625 +7145 -0.673004150390625 +7146 -0.051116943359375 +7147 -0.42694091796875 +7148 -0.0638427734375 +7149 -0.2100830078125 +7150 -0.07928466796875 +7151 -0.0362548828125 +7152 -0.093353271484375 +7153 0.10943603515625 +7154 -0.10321044921875 +7155 0.23516845703125 +7156 -0.1031494140625 +7157 0.373687744140625 +7158 -0.093353271484375 +7159 0.517791748046875 +7160 -0.08233642578125 +7161 0.602783203125 +7162 -0.06939697265625 +7163 0.635711669921875 +7164 -0.050018310546875 +7165 0.655181884765625 +7166 -0.02557373046875 +7167 0.65948486328125 +7168 0.002471923828125 +7169 0.651275634765625 +7170 0.030731201171875 +7171 0.61846923828125 +7172 0.05462646484375 +7173 0.53753662109375 +7174 0.071990966796875 +7175 0.404144287109375 +7176 0.08154296875 +7177 0.22186279296875 +7178 0.083282470703125 +7179 0.003997802734375 +7180 0.0789794921875 +7181 -0.22100830078125 +7182 0.070770263671875 +7183 -0.42449951171875 +7184 0.0609130859375 +7185 -0.579833984375 +7186 0.053955078125 +7187 -0.641876220703125 +7188 0.049346923828125 +7189 -0.6177978515625 +7190 0.0406494140625 +7191 -0.575531005859375 +7192 0.027587890625 +7193 -0.526336669921875 +7194 0.015838623046875 +7195 -0.42645263671875 +7196 0.008544921875 +7197 -0.2581787109375 +7198 0.002197265625 +7199 -0.068695068359375 +7200 -0.0068359375 +7201 0.09222412109375 +7202 -0.016387939453125 +7203 0.232147216796875 +7204 -0.025177001953125 +7205 0.3509521484375 +7206 -0.036163330078125 +7207 0.410064697265625 +7208 -0.05230712890625 +7209 0.372955322265625 +7210 -0.071441650390625 +7211 0.2554931640625 +7212 -0.08819580078125 +7213 0.10711669921875 +7214 -0.10064697265625 +7215 -0.052886962890625 +7216 -0.105194091796875 +7217 -0.186279296875 +7218 -0.096282958984375 +7219 -0.23291015625 +7220 -0.076507568359375 +7221 -0.209442138671875 +7222 -0.053009033203125 +7223 -0.174163818359375 +7224 -0.026885986328125 +7225 -0.126739501953125 +7226 0.002593994140625 +7227 -0.048126220703125 +7228 0.03228759765625 +7229 0.0426025390625 +7230 0.057159423828125 +7231 0.10748291015625 +7232 0.07574462890625 +7233 0.1409912109375 +7234 0.0928955078125 +7235 0.19708251953125 +7236 0.107879638671875 +7237 0.273651123046875 +7238 0.114959716796875 +7239 0.31768798828125 +7240 0.1153564453125 +7241 0.341094970703125 +7242 0.11181640625 +7243 0.368011474609375 +7244 0.10211181640625 +7245 0.37249755859375 +7246 0.081298828125 +7247 0.30072021484375 +7248 0.050140380859375 +7249 0.1517333984375 +7250 0.0157470703125 +7251 -0.01470947265625 +7252 -0.019805908203125 +7253 -0.1883544921875 +7254 -0.055938720703125 +7255 -0.372711181640625 +7256 -0.08612060546875 +7257 -0.51397705078125 +7258 -0.105377197265625 +7259 -0.57177734375 +7260 -0.112335205078125 +7261 -0.53948974609375 +7262 -0.1083984375 +7263 -0.43511962890625 +7264 -0.097198486328125 +7265 -0.2962646484375 +7266 -0.0826416015625 +7267 -0.161102294921875 +7268 -0.066314697265625 +7269 -0.0435791015625 +7270 -0.048126220703125 +7271 0.060394287109375 +7272 -0.030029296875 +7273 0.13665771484375 +7274 -0.01422119140625 +7275 0.170135498046875 +7276 -0.0009765625 +7277 0.16552734375 +7278 0.01251220703125 +7279 0.15728759765625 +7280 0.025970458984375 +7281 0.150787353515625 +7282 0.0361328125 +7283 0.12200927734375 +7284 0.043304443359375 +7285 0.080108642578125 +7286 0.049591064453125 +7287 0.05126953125 +7288 0.057403564453125 +7289 0.062896728515625 +7290 0.06414794921875 +7291 0.09271240234375 +7292 0.064727783203125 +7293 0.092987060546875 +7294 0.060760498046875 +7295 0.07855224609375 +7296 0.05401611328125 +7297 0.06427001953125 +7298 0.043243408203125 +7299 0.0347900390625 +7300 0.02874755859375 +7301 -0.01171875 +7302 0.01312255859375 +7303 -0.056060791015625 +7304 0.001434326171875 +7305 -0.055511474609375 +7306 -0.00567626953125 +7307 -0.010467529296875 +7308 -0.013153076171875 +7309 0.02508544921875 +7310 -0.023040771484375 +7311 0.025665283203125 +7312 -0.032135009765625 +7313 0.017333984375 +7314 -0.039825439453125 +7315 0.00189208984375 +7316 -0.047027587890625 +7317 -0.03173828125 +7318 -0.052337646484375 +7319 -0.071502685546875 +7320 -0.05767822265625 +7321 -0.13543701171875 +7322 -0.06280517578125 +7323 -0.219970703125 +7324 -0.065399169921875 +7325 -0.300506591796875 +7326 -0.06573486328125 +7327 -0.376312255859375 +7328 -0.061065673828125 +7329 -0.416107177734375 +7330 -0.04681396484375 +7331 -0.371124267578125 +7332 -0.023651123046875 +7333 -0.242279052734375 +7334 0.003692626953125 +7335 -0.069732666015625 +7336 0.03253173828125 +7337 0.125640869140625 +7338 0.059173583984375 +7339 0.31268310546875 +7340 0.0794677734375 +7341 0.45501708984375 +7342 0.0933837890625 +7343 0.554779052734375 +7344 0.100677490234375 +7345 0.61065673828125 +7346 0.10009765625 +7347 0.610931396484375 +7348 0.0892333984375 +7349 0.531463623046875 +7350 0.0699462890625 +7351 0.3883056640625 +7352 0.048095703125 +7353 0.23468017578125 +7354 0.026641845703125 +7355 0.095245361328125 +7356 0.008697509765625 +7357 -0.00396728515625 +7358 -0.00384521484375 +7359 -0.04852294921875 +7360 -0.01226806640625 +7361 -0.055145263671875 +7362 -0.02154541015625 +7363 -0.0758056640625 +7364 -0.03424072265625 +7365 -0.138702392578125 +7366 -0.046417236328125 +7367 -0.209197998046875 +7368 -0.05804443359375 +7369 -0.289031982421875 +7370 -0.069061279296875 +7371 -0.37884521484375 +7372 -0.07708740234375 +7373 -0.456329345703125 +7374 -0.0816650390625 +7375 -0.51641845703125 +7376 -0.07879638671875 +7377 -0.519287109375 +7378 -0.0679931640625 +7379 -0.458251953125 +7380 -0.054901123046875 +7381 -0.384796142578125 +7382 -0.04241943359375 +7383 -0.323699951171875 +7384 -0.0302734375 +7385 -0.269287109375 +7386 -0.01611328125 +7387 -0.1951904296875 +7388 -0.000152587890625 +7389 -0.100006103515625 +7390 0.014495849609375 +7391 -0.01055908203125 +7392 0.03070068359375 +7393 0.1033935546875 +7394 0.048980712890625 +7395 0.24908447265625 +7396 0.06365966796875 +7397 0.373199462890625 +7398 0.072845458984375 +7399 0.45806884765625 +7400 0.077392578125 +7401 0.511474609375 +7402 0.080718994140625 +7403 0.565399169921875 +7404 0.082061767578125 +7405 0.61138916015625 +7406 0.075439453125 +7407 0.5897216796875 +7408 0.06011962890625 +7409 0.4906005859375 +7410 0.0382080078125 +7411 0.33148193359375 +7412 0.013702392578125 +7413 0.147796630859375 +7414 -0.00872802734375 +7415 -0.01873779296875 +7416 -0.02593994140625 +7417 -0.140289306640625 +7418 -0.03509521484375 +7419 -0.191986083984375 +7420 -0.037109375 +7421 -0.184295654296875 +7422 -0.0364990234375 +7423 -0.161834716796875 +7424 -0.03753662109375 +7425 -0.166595458984375 +7426 -0.039764404296875 +7427 -0.19390869140625 +7428 -0.041229248046875 +7429 -0.22442626953125 +7430 -0.044189453125 +7431 -0.279754638671875 +7432 -0.046722412109375 +7433 -0.3389892578125 +7434 -0.04425048828125 +7435 -0.3543701171875 +7436 -0.039215087890625 +7437 -0.348175048828125 +7438 -0.032440185546875 +7439 -0.32598876953125 +7440 -0.021209716796875 +7441 -0.2581787109375 +7442 -0.005279541015625 +7443 -0.139801025390625 +7444 0.013641357421875 +7445 0.014617919921875 +7446 0.029327392578125 +7447 0.144378662109375 +7448 0.038818359375 +7449 0.221038818359375 +7450 0.044647216796875 +7451 0.27069091796875 +7452 0.046875 +7453 0.294036865234375 +7454 0.047607421875 +7455 0.311767578125 +7456 0.048370361328125 +7457 0.339141845703125 +7458 0.047332763671875 +7459 0.360260009765625 +7460 0.0433349609375 +7461 0.360504150390625 +7462 0.03448486328125 +7463 0.308380126953125 +7464 0.01959228515625 +7465 0.18170166015625 +7466 0.00079345703125 +7467 0.0047607421875 +7468 -0.018096923828125 +7469 -0.17559814453125 +7470 -0.033477783203125 +7471 -0.3143310546875 +7472 -0.041900634765625 +7473 -0.36785888671875 +7474 -0.0450439453125 +7475 -0.36248779296875 +7476 -0.0460205078125 +7477 -0.343536376953125 +7478 -0.0440673828125 +7479 -0.3018798828125 +7480 -0.038726806640625 +7481 -0.231414794921875 +7482 -0.029022216796875 +7483 -0.117645263671875 +7484 -0.017425537109375 +7485 0.007049560546875 +7486 -0.008026123046875 +7487 0.087982177734375 +7488 -3.0517578125e-05 +7489 0.13946533203125 +7490 0.0072021484375 +7491 0.17425537109375 +7492 0.013092041015625 +7493 0.188201904296875 +7494 0.016632080078125 +7495 0.171234130859375 +7496 0.017242431640625 +7497 0.118438720703125 +7498 0.01666259765625 +7499 0.05706787109375 +7500 0.01483154296875 +7501 -0.010711669921875 +7502 0.011138916015625 +7503 -0.0914306640625 +7504 0.007110595703125 +7505 -0.162322998046875 +7506 0.004791259765625 +7507 -0.194549560546875 +7508 0.00701904296875 +7509 -0.1492919921875 +7510 0.01422119140625 +7511 -0.02166748046875 +7512 0.02191162109375 +7513 0.124053955078125 +7514 0.02471923828125 +7515 0.211151123046875 +7516 0.022918701171875 +7517 0.240447998046875 +7518 0.018951416015625 +7519 0.242218017578125 +7520 0.013702392578125 +7521 0.2257080078125 +7522 0.007659912109375 +7523 0.194366455078125 +7524 -0.001312255859375 +7525 0.115509033203125 +7526 -0.011322021484375 +7527 0.0128173828125 +7528 -0.0179443359375 +7529 -0.053802490234375 +7530 -0.02301025390625 +7531 -0.110626220703125 +7532 -0.02947998046875 +7533 -0.199493408203125 +7534 -0.035552978515625 +7535 -0.29437255859375 +7536 -0.036712646484375 +7537 -0.33221435546875 +7538 -0.03070068359375 +7539 -0.27972412109375 +7540 -0.021148681640625 +7541 -0.185333251953125 +7542 -0.013916015625 +7543 -0.128204345703125 +7544 -0.00970458984375 +7545 -0.115692138671875 +7546 -0.006439208984375 +7547 -0.116455078125 +7548 -0.002532958984375 +7549 -0.105926513671875 +7550 0.00396728515625 +7551 -0.053955078125 +7552 0.01361083984375 +7553 0.048797607421875 +7554 0.0230712890625 +7555 0.157318115234375 +7556 0.027984619140625 +7557 0.212005615234375 +7558 0.0286865234375 +7559 0.218475341796875 +7560 0.029541015625 +7561 0.23724365234375 +7562 0.03326416015625 +7563 0.30535888671875 +7564 0.03692626953125 +7565 0.38128662109375 +7566 0.03631591796875 +7567 0.404449462890625 +7568 0.032989501953125 +7569 0.3944091796875 +7570 0.02978515625 +7571 0.3885498046875 +7572 0.025146484375 +7573 0.362640380859375 +7574 0.016082763671875 +7575 0.27362060546875 +7576 0.00244140625 +7577 0.11712646484375 +7578 -0.01190185546875 +7579 -0.054901123046875 +7580 -0.023101806640625 +7581 -0.19085693359375 +7582 -0.03076171875 +7583 -0.28570556640625 +7584 -0.034820556640625 +7585 -0.339263916015625 +7586 -0.037200927734375 +7587 -0.3775634765625 +7588 -0.041168212890625 +7589 -0.445709228515625 +7590 -0.046173095703125 +7591 -0.535064697265625 +7592 -0.05108642578125 +7593 -0.629058837890625 +7594 -0.0538330078125 +7595 -0.697601318359375 +7596 -0.05194091796875 +7597 -0.70391845703125 +7598 -0.045135498046875 +7599 -0.6424560546875 +7600 -0.031982421875 +7601 -0.491241455078125 +7602 -0.013702392578125 +7603 -0.265716552734375 +7604 0.005401611328125 +7605 -0.023712158203125 +7606 0.022857666015625 +7607 0.201751708984375 +7608 0.0361328125 +7609 0.375823974609375 +7610 0.044219970703125 +7611 0.485076904296875 +7612 0.049957275390625 +7613 0.56884765625 +7614 0.053924560546875 +7615 0.634765625 +7616 0.05291748046875 +7617 0.63763427734375 +7618 0.04620361328125 +7619 0.5660400390625 +7620 0.03759765625 +7621 0.4720458984375 +7622 0.030914306640625 +7623 0.40692138671875 +7624 0.02679443359375 +7625 0.3778076171875 +7626 0.0247802734375 +7627 0.376953125 +7628 0.022674560546875 +7629 0.371978759765625 +7630 0.016937255859375 +7631 0.313140869140625 +7632 0.006500244140625 +7633 0.184417724609375 +7634 -0.0067138671875 +7635 0.011199951171875 +7636 -0.02008056640625 +7637 -0.171051025390625 +7638 -0.031829833984375 +7639 -0.33740234375 +7640 -0.040863037109375 +7641 -0.47198486328125 +7642 -0.04620361328125 +7643 -0.560394287109375 +7644 -0.04632568359375 +7645 -0.58056640625 +7646 -0.042388916015625 +7647 -0.54754638671875 +7648 -0.037872314453125 +7649 -0.508575439453125 +7650 -0.0325927734375 +7651 -0.459503173828125 +7652 -0.026214599609375 +7653 -0.394378662109375 +7654 -0.0216064453125 +7655 -0.35260009765625 +7656 -0.017242431640625 +7657 -0.31170654296875 +7658 -0.00787353515625 +7659 -0.197418212890625 +7660 0.00653076171875 +7661 -0.007965087890625 +7662 0.022369384765625 +7663 0.207489013671875 +7664 0.036773681640625 +7665 0.409210205078125 +7666 0.0479736328125 +7667 0.57208251953125 +7668 0.053863525390625 +7669 0.66595458984375 +7670 0.052154541015625 +7671 0.65875244140625 +7672 0.044189453125 +7673 0.56744384765625 +7674 0.032867431640625 +7675 0.431396484375 +7676 0.02142333984375 +7677 0.29443359375 +7678 0.011810302734375 +7679 0.182464599609375 +7680 0.0023193359375 +7681 0.06365966796875 +7682 -0.00787353515625 +7683 -0.075958251953125 +7684 -0.0167236328125 +7685 -0.189422607421875 +7686 -0.02374267578125 +7687 -0.271942138671875 +7688 -0.029449462890625 +7689 -0.342529296875 +7690 -0.032196044921875 +7691 -0.364166259765625 +7692 -0.031494140625 +7693 -0.327239990234375 +7694 -0.029144287109375 +7695 -0.2769775390625 +7696 -0.026824951171875 +7697 -0.253692626953125 +7698 -0.024078369140625 +7699 -0.24365234375 +7700 -0.019134521484375 +7701 -0.1983642578125 +7702 -0.01214599609375 +7703 -0.116241455078125 +7704 -0.004913330078125 +7705 -0.036834716796875 +7706 0.0020751953125 +7707 0.034881591796875 +7708 0.00830078125 +7709 0.09124755859375 +7710 0.01263427734375 +7711 0.10888671875 +7712 0.016387939453125 +7713 0.125518798828125 +7714 0.020050048828125 +7715 0.15771484375 +7716 0.022430419921875 +7717 0.17828369140625 +7718 0.022796630859375 +7719 0.17108154296875 +7720 0.02093505859375 +7721 0.129974365234375 +7722 0.0179443359375 +7723 0.082427978515625 +7724 0.013885498046875 +7725 0.027679443359375 +7726 0.007659912109375 +7727 -0.065643310546875 +7728 0.000946044921875 +7729 -0.15936279296875 +7730 -0.004425048828125 +7731 -0.21307373046875 +7732 -0.008636474609375 +7733 -0.234649658203125 +7734 -0.010528564453125 +7735 -0.2001953125 +7736 -0.01031494140625 +7737 -0.119171142578125 +7738 -0.0091552734375 +7739 -0.024749755859375 +7740 -0.00677490234375 +7741 0.085784912109375 +7742 -0.0045166015625 +7743 0.178131103515625 +7744 -0.003753662109375 +7745 0.215576171875 +7746 -0.003936767578125 +7747 0.211456298828125 +7748 -0.004669189453125 +7749 0.17523193359375 +7750 -0.005157470703125 +7751 0.128753662109375 +7752 -0.004302978515625 +7753 0.1019287109375 +7754 -0.003021240234375 +7755 0.0743408203125 +7756 -0.0015869140625 +7757 0.04327392578125 +7758 0.0009765625 +7759 0.038177490234375 +7760 0.00518798828125 +7761 0.076263427734375 +7762 0.01025390625 +7763 0.14105224609375 +7764 0.014190673828125 +7765 0.186431884765625 +7766 0.0159912109375 +7767 0.188812255859375 +7768 0.01519775390625 +7769 0.1390380859375 +7770 0.011932373046875 +7771 0.041778564453125 +7772 0.00714111328125 +7773 -0.079437255859375 +7774 0.00103759765625 +7775 -0.219390869140625 +7776 -0.005859375 +7777 -0.367828369140625 +7778 -0.012298583984375 +7779 -0.494873046875 +7780 -0.01641845703125 +7781 -0.556243896484375 +7782 -0.01641845703125 +7783 -0.508697509765625 +7784 -0.01312255859375 +7785 -0.3756103515625 +7786 -0.0089111328125 +7787 -0.218902587890625 +7788 -0.004730224609375 +7789 -0.063751220703125 +7790 -0.0003662109375 +7791 0.091552734375 +7792 0.00384521484375 +7793 0.23602294921875 +7794 0.00689697265625 +7795 0.342987060546875 +7796 0.008148193359375 +7797 0.39520263671875 +7798 0.007537841796875 +7799 0.389373779296875 +7800 0.005035400390625 +7801 0.324249267578125 +7802 0.0015869140625 +7803 0.224090576171875 +7804 -0.00140380859375 +7805 0.124267578125 +7806 -0.0035400390625 +7807 0.037078857421875 +7808 -0.003814697265625 +7809 -0.010101318359375 +7810 -0.00238037109375 +7811 -0.019439697265625 +7812 -0.000640869140625 +7813 -0.022796630859375 +7814 0.00201416015625 +7815 -0.001556396484375 +7816 0.005950927734375 +7817 0.056304931640625 +7818 0.00933837890625 +7819 0.106719970703125 +7820 0.009979248046875 +7821 0.096893310546875 +7822 0.00848388671875 +7823 0.042694091796875 +7824 0.006317138671875 +7825 -0.018035888671875 +7826 0.003875732421875 +7827 -0.07586669921875 +7828 0.00164794921875 +7829 -0.11944580078125 +7830 -0.000762939453125 +7831 -0.15972900390625 +7832 -0.0035400390625 +7833 -0.202606201171875 +7834 -0.006591796875 +7835 -0.24859619140625 +7836 -0.010162353515625 +7837 -0.30517578125 +7838 -0.0137939453125 +7839 -0.36212158203125 +7840 -0.016265869140625 +7841 -0.39141845703125 +7842 -0.016021728515625 +7843 -0.35528564453125 +7844 -0.01287841796875 +7845 -0.249969482421875 +7846 -0.0074462890625 +7847 -0.092864990234375 +7848 -0.000762939453125 +7849 0.08905029296875 +7850 0.004730224609375 +7851 0.2352294921875 +7852 0.00799560546875 +7853 0.318817138671875 +7854 0.009796142578125 +7855 0.358642578125 +7856 0.009796142578125 +7857 0.347747802734375 +7858 0.007965087890625 +7859 0.28564453125 +7860 0.00628662109375 +7861 0.223175048828125 +7862 0.00616455078125 +7863 0.196746826171875 +7864 0.0064697265625 +7865 0.179840087890625 +7866 0.006500244140625 +7867 0.155548095703125 +7868 0.00726318359375 +7869 0.151214599609375 +7870 0.00836181640625 +7871 0.156951904296875 +7872 0.008087158203125 +7873 0.13177490234375 +7874 0.007415771484375 +7875 0.100799560546875 +7876 0.007232666015625 +7877 0.087127685546875 +7878 0.006103515625 +7879 0.05487060546875 +7880 0.00347900390625 +7881 -0.009002685546875 +7882 -0.00054931640625 +7883 -0.10400390625 +7884 -0.005950927734375 +7885 -0.229400634765625 +7886 -0.01153564453125 +7887 -0.35552978515625 +7888 -0.015655517578125 +7889 -0.441925048828125 +7890 -0.01763916015625 +7891 -0.473846435546875 +7892 -0.01800537109375 +7893 -0.464813232421875 +7894 -0.016876220703125 +7895 -0.419097900390625 +7896 -0.01416015625 +7897 -0.334320068359375 +7898 -0.010467529296875 +7899 -0.227935791015625 +7900 -0.0067138671875 +7901 -0.12347412109375 +7902 -0.003173828125 +7903 -0.02764892578125 +7904 0.000885009765625 +7905 0.077667236328125 +7906 0.006256103515625 +7907 0.2132568359375 +7908 0.01336669921875 +7909 0.38885498046875 +7910 0.021331787109375 +7911 0.582794189453125 +7912 0.0277099609375 +7913 0.734039306640625 +7914 0.030731201171875 +7915 0.800140380859375 +7916 0.0302734375 +7917 0.7783203125 +7918 0.02618408203125 +7919 0.6651611328125 +7920 0.018402099609375 +7921 0.45965576171875 +7922 0.008453369140625 +7923 0.199188232421875 +7924 -0.00103759765625 +7925 -0.050689697265625 +7926 -0.007843017578125 +7927 -0.23297119140625 +7928 -0.01129150390625 +7929 -0.33013916015625 +7930 -0.012481689453125 +7931 -0.368408203125 +7932 -0.012664794921875 +7933 -0.378936767578125 +7934 -0.01251220703125 +7935 -0.376983642578125 +7936 -0.012603759765625 +7937 -0.37969970703125 +7938 -0.013092041015625 +7939 -0.391510009765625 +7940 -0.013519287109375 +7941 -0.385345458984375 +7942 -0.013458251953125 +7943 -0.3419189453125 +7944 -0.012908935546875 +7945 -0.28289794921875 +7946 -0.0120849609375 +7947 -0.251617431640625 +7948 -0.011077880859375 +7949 -0.266143798828125 +7950 -0.00946044921875 +7951 -0.273345947265625 +7952 -0.006866455078125 +7953 -0.216796875 +7954 -0.003662109375 +7955 -0.128265380859375 +7956 -0.00048828125 +7957 -0.068145751953125 +7958 0.00244140625 +7959 -0.0430908203125 +7960 0.00518798828125 +7961 -0.024444580078125 +7962 0.00787353515625 +7963 0.020721435546875 +7964 0.010589599609375 +7965 0.124481201171875 +7966 0.01300048828125 +7967 0.25787353515625 +7968 0.014678955078125 +7969 0.379119873046875 +7970 0.015533447265625 +7971 0.47991943359375 +7972 0.015350341796875 +7973 0.5281982421875 +7974 0.014068603515625 +7975 0.511138916015625 +7976 0.011962890625 +7977 0.456207275390625 +7978 0.009490966796875 +7979 0.407470703125 +7980 0.00689697265625 +7981 0.383758544921875 +7982 0.00408935546875 +7983 0.35687255859375 +7984 0.001129150390625 +7985 0.31182861328125 +7986 -0.00177001953125 +7987 0.250885009765625 +7988 -0.00457763671875 +7989 0.1654052734375 +7990 -0.00732421875 +7991 0.035247802734375 +7992 -0.00994873046875 +7993 -0.142059326171875 +7994 -0.012176513671875 +7995 -0.33563232421875 +7996 -0.013885498046875 +7997 -0.5345458984375 +7998 -0.014923095703125 +7999 -0.72186279296875 +8000 -0.01483154296875 +8001 -0.836669921875 +8002 -0.0133056640625 +8003 -0.8326416015625 +8004 -0.0106201171875 +8005 -0.7296142578125 +8006 -0.00738525390625 +8007 -0.582550048828125 +8008 -0.00408935546875 +8009 -0.440093994140625 +8010 -0.001007080078125 +8011 -0.324310302734375 +8012 0.001983642578125 +8013 -0.20147705078125 +8014 0.0050048828125 +8015 -0.044647216796875 +8016 0.007598876953125 +8017 0.103973388671875 +8018 0.009368896484375 +8019 0.202392578125 +8020 0.010406494140625 +8021 0.264495849609375 +8022 0.011077880859375 +8023 0.338897705078125 +8024 0.01153564453125 +8025 0.443817138671875 +8026 0.01153564453125 +8027 0.545074462890625 +8028 0.01092529296875 +8029 0.6173095703125 +8030 0.00970458984375 +8031 0.6524658203125 +8032 0.008087158203125 +8033 0.66339111328125 +8034 0.006195068359375 +8035 0.6561279296875 +8036 0.00396728515625 +8037 0.606781005859375 +8038 0.001373291015625 +8039 0.501190185546875 +8040 -0.0013427734375 +8041 0.352783203125 +8042 -0.003997802734375 +8043 0.176544189453125 +8044 -0.006561279296875 +8045 -0.034820556640625 +8046 -0.0087890625 +8047 -0.258209228515625 +8048 -0.01025390625 +8049 -0.44244384765625 +8050 -0.010894775390625 +8051 -0.5753173828125 +8052 -0.010711669921875 +8053 -0.65203857421875 +8054 -0.009521484375 +8055 -0.641632080078125 +8056 -0.007537841796875 +8057 -0.562164306640625 +8058 -0.005218505859375 +8059 -0.458038330078125 +8060 -0.0028076171875 +8061 -0.350555419921875 +8062 -0.00054931640625 +8063 -0.260528564453125 +8064 0.00140380859375 +8065 -0.192108154296875 +8066 0.003021240234375 +8067 -0.141937255859375 +8068 0.0042724609375 +8069 -0.1021728515625 +8070 0.005218505859375 +8071 -0.062896728515625 +8072 0.005950927734375 +8073 -0.011932373046875 +8074 0.00653076171875 +8075 0.062835693359375 +8076 0.00689697265625 +8077 0.148712158203125 +8078 0.00701904296875 +8079 0.241729736328125 +8080 0.006988525390625 +8081 0.34912109375 +8082 0.006744384765625 +8083 0.457305908203125 +8084 0.006195068359375 +8085 0.54388427734375 +8086 0.005126953125 +8087 0.5728759765625 +8088 0.0032958984375 +8089 0.506591796875 +8090 0.000823974609375 +8091 0.351226806640625 +8092 -0.001861572265625 +8093 0.146514892578125 +8094 -0.004302978515625 +8095 -0.05523681640625 +8096 -0.006134033203125 +8097 -0.21624755859375 +8098 -0.007354736328125 +8099 -0.334930419921875 +8100 -0.00787353515625 +8101 -0.402984619140625 +8102 -0.00787353515625 +8103 -0.4412841796875 +8104 -0.00775146484375 +8105 -0.49578857421875 +8106 -0.007476806640625 +8107 -0.5601806640625 +8108 -0.0068359375 +8109 -0.600738525390625 +8110 -0.005645751953125 +8111 -0.584228515625 +8112 -0.003692626953125 +8113 -0.47930908203125 +8114 -0.001007080078125 +8115 -0.27935791015625 +8116 0.00213623046875 +8117 -0.0089111328125 +8118 0.005157470703125 +8119 0.268798828125 +8120 0.0074462890625 +8121 0.482818603515625 +8122 0.008758544921875 +8123 0.60369873046875 +8124 0.009246826171875 +8125 0.650421142578125 +8126 0.009246826171875 +8127 0.66400146484375 +8128 0.008758544921875 +8129 0.6414794921875 +8130 0.007720947265625 +8131 0.572540283203125 +8132 0.006500244140625 +8133 0.498138427734375 +8134 0.005279541015625 +8135 0.439453125 +8136 0.00396728515625 +8137 0.375518798828125 +8138 0.0023193359375 +8139 0.274505615234375 +8140 0.00018310546875 +8141 0.1087646484375 +8142 -0.002197265625 +8143 -0.099395751953125 +8144 -0.004547119140625 +8145 -0.3182373046875 +8146 -0.0068359375 +8147 -0.5489501953125 +8148 -0.008880615234375 +8149 -0.7738037109375 +8150 -0.01025390625 +8151 -0.86383056640625 +8152 -0.010711669921875 +8153 -0.870391845703125 +8154 -0.010406494140625 +8155 -0.86895751953125 +8156 -0.00946044921875 +8157 -0.861053466796875 +8158 -0.007781982421875 +8159 -0.765869140625 +8160 -0.00531005859375 +8161 -0.5301513671875 +8162 -0.00213623046875 +8163 -0.214691162109375 +8164 0.0013427734375 +8165 0.137359619140625 +8166 0.004669189453125 +8167 0.474822998046875 +8168 0.007537841796875 +8169 0.76239013671875 +8170 0.00970458984375 +8171 0.867462158203125 +8172 0.011138916015625 +8173 0.870361328125 +8174 0.01171875 +8175 0.86480712890625 +8176 0.011505126953125 +8177 0.831817626953125 +8178 0.010711669921875 +8179 0.677581787109375 +8180 0.009429931640625 +8181 0.495880126953125 +8182 0.007781982421875 +8183 0.30767822265625 +8184 0.005859375 +8185 0.116180419921875 +8186 0.00341796875 +8187 -0.110748291015625 +8188 0.00042724609375 +8189 -0.381805419921875 +8190 -0.00274658203125 +8191 -0.6572265625 +8192 -0.005462646484375 +8193 -0.857421875 +8194 -0.00732421875 +8195 -0.870391845703125 +8196 -0.00836181640625 +8197 -0.870391845703125 +8198 -0.00921630859375 +8199 -0.86444091796875 +8200 -0.010650634765625 +8201 -0.85723876953125 +8202 -0.012115478515625 +8203 -0.790008544921875 +8204 -0.012176513671875 +8205 -0.62847900390625 +8206 -0.01055908203125 +8207 -0.3956298828125 +8208 -0.007843017578125 +8209 -0.126708984375 +8210 -0.0045166015625 +8211 0.150115966796875 +8212 -0.000640869140625 +8213 0.424041748046875 +8214 0.0032958984375 +8215 0.670623779296875 +8216 0.00653076171875 +8217 0.854522705078125 +8218 0.008819580078125 +8219 0.866485595703125 +8220 0.009918212890625 +8221 0.86920166015625 +8222 0.01031494140625 +8223 0.8653564453125 +8224 0.010406494140625 +8225 0.857147216796875 +8226 0.010162353515625 +8227 0.766845703125 +8228 0.009674072265625 +8229 0.628509521484375 +8230 0.00872802734375 +8231 0.462127685546875 +8232 0.00787353515625 +8233 0.297210693359375 +8234 0.00726318359375 +8235 0.14862060546875 +8236 0.0062255859375 +8237 -0.00537109375 +8238 0.004791259765625 +8239 -0.15753173828125 +8240 0.00274658203125 +8241 -0.31304931640625 +8242 -0.0003662109375 +8243 -0.48876953125 +8244 -0.0035400390625 +8245 -0.6416015625 +8246 -0.006317138671875 +8247 -0.751373291015625 +8248 -0.009307861328125 +8249 -0.84619140625 +8250 -0.01226806640625 +8251 -0.861297607421875 +8252 -0.014404296875 +8253 -0.863250732421875 +8254 -0.014984130859375 +8255 -0.856597900390625 +8256 -0.0142822265625 +8257 -0.7498779296875 +8258 -0.01361083984375 +8259 -0.624542236328125 +8260 -0.012420654296875 +8261 -0.47808837890625 +8262 -0.009185791015625 +8263 -0.253387451171875 +8264 -0.004913330078125 +8265 0.003692626953125 +8266 -0.00115966796875 +8267 0.2257080078125 +8268 0.00250244140625 +8269 0.427154541015625 +8270 0.0069580078125 +8271 0.643218994140625 +8272 0.012054443359375 +8273 0.855926513671875 +8274 0.01654052734375 +8275 0.870361328125 +8276 0.019317626953125 +8277 0.870361328125 +8278 0.020599365234375 +8279 0.862762451171875 +8280 0.020355224609375 +8281 0.79669189453125 +8282 0.018341064453125 +8283 0.595794677734375 +8284 0.015228271484375 +8285 0.362152099609375 +8286 0.011627197265625 +8287 0.1270751953125 +8288 0.00799560546875 +8289 -0.086944580078125 +8290 0.00433349609375 +8291 -0.2784423828125 +8292 -0.000274658203125 +8293 -0.484832763671875 +8294 -0.00640869140625 +8295 -0.729583740234375 +8296 -0.012969970703125 +8297 -0.86688232421875 +8298 -0.018524169921875 +8299 -0.870391845703125 +8300 -0.02301025390625 +8301 -0.86859130859375 +8302 -0.026458740234375 +8303 -0.86279296875 +8304 -0.028106689453125 +8305 -0.817962646484375 +8306 -0.02685546875 +8307 -0.6116943359375 +8308 -0.022613525390625 +8309 -0.3128662109375 +8310 -0.01617431640625 +8311 0.039398193359375 +8312 -0.007965087890625 +8313 0.422821044921875 +8314 0.001220703125 +8315 0.805145263671875 +8316 0.009796142578125 +8317 0.870361328125 +8318 0.0164794921875 +8319 0.870361328125 +8320 0.021087646484375 +8321 0.860015869140625 +8322 0.0235595703125 +8323 0.727935791015625 +8324 0.023834228515625 +8325 0.48114013671875 +8326 0.022552490234375 +8327 0.2059326171875 +8328 0.020355224609375 +8329 -0.06103515625 +8330 0.017547607421875 +8331 -0.29913330078125 +8332 0.0137939453125 +8333 -0.516204833984375 +8334 0.0087890625 +8335 -0.7252197265625 +8336 0.00311279296875 +8337 -0.85980224609375 +8338 -0.00238037109375 +8339 -0.870391845703125 +8340 -0.00701904296875 +8341 -0.870391845703125 +8342 -0.00970458984375 +8343 -0.858062744140625 +8344 -0.010406494140625 +8345 -0.673004150390625 +8346 -0.010498046875 +8347 -0.42694091796875 +8348 -0.011077880859375 +8349 -0.2100830078125 +8350 -0.012176513671875 +8351 -0.0362548828125 +8352 -0.01318359375 +8353 0.10943603515625 +8354 -0.01361083984375 +8355 0.23516845703125 +8356 -0.012542724609375 +8357 0.373687744140625 +8358 -0.01007080078125 +8359 0.517791748046875 +8360 -0.007720947265625 +8361 0.602783203125 +8362 -0.00537109375 +8363 0.635711669921875 +8364 -0.002227783203125 +8365 0.655181884765625 +8366 0.00146484375 +8367 0.65948486328125 +8368 0.0054931640625 +8369 0.651275634765625 +8370 0.009307861328125 +8371 0.61846923828125 +8372 0.012115478515625 +8373 0.53753662109375 +8374 0.0135498046875 +8375 0.404144287109375 +8376 0.013458251953125 +8377 0.22186279296875 +8378 0.011993408203125 +8379 0.003997802734375 +8380 0.009613037109375 +8381 -0.22100830078125 +8382 0.006866455078125 +8383 -0.42449951171875 +8384 0.004302978515625 +8385 -0.579833984375 +8386 0.002960205078125 +8387 -0.641876220703125 +8388 0.002685546875 +8389 -0.6177978515625 +8390 0.001922607421875 +8391 -0.575531005859375 +8392 0.000518798828125 +8393 -0.526336669921875 +8394 -0.00030517578125 +8395 -0.42645263671875 +8396 3.0517578125e-05 +8397 -0.2581787109375 +8398 0.0006103515625 +8399 -0.068695068359375 +8400 0.00048828125 +8401 0.09222412109375 +8402 6.103515625e-05 +8403 0.232147216796875 +8404 -0.000457763671875 +8405 0.3509521484375 +8406 -0.001800537109375 +8407 0.410064697265625 +8408 -0.00469970703125 +8409 0.372955322265625 +8410 -0.008697509765625 +8411 0.2554931640625 +8412 -0.012542724609375 +8413 0.10711669921875 +8414 -0.015777587890625 +8415 -0.052886962890625 +8416 -0.017547607421875 +8417 -0.186279296875 +8418 -0.01654052734375 +8419 -0.23291015625 +8420 -0.0133056640625 +8421 -0.209442138671875 +8422 -0.009368896484375 +8423 -0.174163818359375 +8424 -0.004913330078125 +8425 -0.126739501953125 +8426 0.000274658203125 +8427 -0.048126220703125 +8428 0.00555419921875 +8429 0.0426025390625 +8430 0.0098876953125 +8431 0.10748291015625 +8432 0.012969970703125 +8433 0.1409912109375 +8434 0.0159912109375 +8435 0.19708251953125 +8436 0.018829345703125 +8437 0.273651123046875 +8438 0.020172119140625 +8439 0.31768798828125 +8440 0.02032470703125 +8441 0.341094970703125 +8442 0.019927978515625 +8443 0.368011474609375 +8444 0.0184326171875 +8445 0.37249755859375 +8446 0.0146484375 +8447 0.30072021484375 +8448 0.00885009765625 +8449 0.1517333984375 +8450 0.00274658203125 +8451 -0.01470947265625 +8452 -0.004058837890625 +8453 -0.1883544921875 +8454 -0.011932373046875 +8455 -0.372711181640625 +8456 -0.018310546875 +8457 -0.51397705078125 +8458 -0.021148681640625 +8459 -0.57177734375 +8460 -0.0201416015625 +8461 -0.53948974609375 +8462 -0.01611328125 +8463 -0.43511962890625 +8464 -0.010772705078125 +8465 -0.2962646484375 +8466 -0.00592041015625 +8467 -0.161102294921875 +8468 -0.002105712890625 +8469 -0.0435791015625 +8470 0.00103759765625 +8471 0.060394287109375 +8472 0.002899169921875 +8473 0.13665771484375 +8474 0.00286865234375 +8475 0.170135498046875 +8476 0.00128173828125 +8477 0.16552734375 +8478 -3.0517578125e-05 +8479 0.15728759765625 +8480 -0.000762939453125 +8481 0.150787353515625 +8482 -0.0020751953125 +8483 0.12200927734375 +8484 -0.003570556640625 +8485 0.080108642578125 +8486 -0.00396728515625 +8487 0.05126953125 +8488 -0.001983642578125 +8489 0.062896728515625 +8490 0.00115966796875 +8491 0.09271240234375 +8492 0.002960205078125 +8493 0.092987060546875 +8494 0.004058837890625 +8495 0.07855224609375 +8496 0.005126953125 +8497 0.06427001953125 +8498 0.005279541015625 +8499 0.0347900390625 +8500 0.00433349609375 +8501 -0.01171875 +8502 0.003173828125 +8503 -0.056060791015625 +8504 0.00390625 +8505 -0.055511474609375 +8506 0.0064697265625 +8507 -0.010467529296875 +8508 0.008148193359375 +8509 0.02508544921875 +8510 0.0076904296875 +8511 0.025665283203125 +8512 0.006439208984375 +8513 0.017333984375 +8514 0.004547119140625 +8515 0.00189208984375 +8516 0.001556396484375 +8517 -0.03173828125 +8518 -0.001861572265625 +8519 -0.071502685546875 +8520 -0.006500244140625 +8521 -0.13543701171875 +8522 -0.012115478515625 +8523 -0.219970703125 +8524 -0.01739501953125 +8525 -0.300506591796875 +8526 -0.022216796875 +8527 -0.376312255859375 +8528 -0.02496337890625 +8529 -0.416107177734375 +8530 -0.023193359375 +8531 -0.371124267578125 +8532 -0.016937255859375 +8533 -0.242279052734375 +8534 -0.008209228515625 +8535 -0.069732666015625 +8536 0.00189208984375 +8537 0.125640869140625 +8538 0.011810302734375 +8539 0.31268310546875 +8540 0.0196533203125 +8541 0.45501708984375 +8542 0.025482177734375 +8543 0.554779052734375 +8544 0.029205322265625 +8545 0.61065673828125 +8546 0.030181884765625 +8547 0.610931396484375 +8548 0.02716064453125 +8549 0.531463623046875 +8550 0.020904541015625 +8551 0.3883056640625 +8552 0.014007568359375 +8553 0.23468017578125 +8554 0.0076904296875 +8555 0.095245361328125 +8556 0.003204345703125 +8557 -0.00396728515625 +8558 0.001220703125 +8559 -0.04852294921875 +8560 0.00091552734375 +8561 -0.055145263671875 +8562 -0.000274658203125 +8563 -0.0758056640625 +8564 -0.00372314453125 +8565 -0.138702392578125 +8566 -0.0076904296875 +8567 -0.209197998046875 +8568 -0.01220703125 +8569 -0.289031982421875 +8570 -0.017303466796875 +8571 -0.37884521484375 +8572 -0.0218505859375 +8573 -0.456329345703125 +8574 -0.0255126953125 +8575 -0.51641845703125 +8576 -0.026275634765625 +8577 -0.519287109375 +8578 -0.023773193359375 +8579 -0.458251953125 +8580 -0.020538330078125 +8581 -0.384796142578125 +8582 -0.017822265625 +8583 -0.323699951171875 +8584 -0.015289306640625 +8585 -0.269287109375 +8586 -0.0115966796875 +8587 -0.1951904296875 +8588 -0.0067138671875 +8589 -0.100006103515625 +8590 -0.001983642578125 +8591 -0.01055908203125 +8592 0.0040283203125 +8593 0.1033935546875 +8594 0.01165771484375 +8595 0.24908447265625 +8596 0.018218994140625 +8597 0.373199462890625 +8598 0.0228271484375 +8599 0.45806884765625 +8600 0.025848388671875 +8601 0.511474609375 +8602 0.028900146484375 +8603 0.565399169921875 +8604 0.031494140625 +8605 0.61138916015625 +8606 0.0306396484375 +8607 0.5897216796875 +8608 0.025848388671875 +8609 0.4906005859375 +8610 0.017974853515625 +8611 0.33148193359375 +8612 0.0087890625 +8613 0.147796630859375 +8614 0.000396728515625 +8615 -0.01873779296875 +8616 -0.00579833984375 +8617 -0.140289306640625 +8618 -0.008544921875 +8619 -0.191986083984375 +8620 -0.00836181640625 +8621 -0.184295654296875 +8622 -0.0074462890625 +8623 -0.161834716796875 +8624 -0.007904052734375 +8625 -0.166595458984375 +8626 -0.00946044921875 +8627 -0.19390869140625 +8628 -0.01116943359375 +8629 -0.22442626953125 +8630 -0.01409912109375 +8631 -0.279754638671875 +8632 -0.017181396484375 +8633 -0.3389892578125 +8634 -0.018035888671875 +8635 -0.3543701171875 +8636 -0.01776123046875 +8637 -0.348175048828125 +8638 -0.0166015625 +8639 -0.32598876953125 +8640 -0.01312255859375 +8641 -0.2581787109375 +8642 -0.007080078125 +8643 -0.139801025390625 +8644 0.000762939453125 +8645 0.014617919921875 +8646 0.00732421875 +8647 0.144378662109375 +8648 0.011199951171875 +8649 0.221038818359375 +8650 0.013702392578125 +8651 0.27069091796875 +8652 0.014892578125 +8653 0.294036865234375 +8654 0.01580810546875 +8655 0.311767578125 +8656 0.017242431640625 +8657 0.339141845703125 +8658 0.0184326171875 +8659 0.360260009765625 +8660 0.018646240234375 +8661 0.360504150390625 +8662 0.01605224609375 +8663 0.308380126953125 +8664 0.0093994140625 +8665 0.18170166015625 +8666 3.0517578125e-05 +8667 0.0047607421875 +8668 -0.009490966796875 +8669 -0.17559814453125 +8670 -0.016693115234375 +8671 -0.3143310546875 +8672 -0.019195556640625 +8673 -0.36785888671875 +8674 -0.018463134765625 +8675 -0.36248779296875 +8676 -0.017059326171875 +8677 -0.343536376953125 +8678 -0.014495849609375 +8679 -0.3018798828125 +8680 -0.01043701171875 +8681 -0.231414794921875 +8682 -0.00408935546875 +8683 -0.117645263671875 +8684 0.002685546875 +8685 0.007049560546875 +8686 0.006866455078125 +8687 0.087982177734375 +8688 0.009307861328125 +8689 0.13946533203125 +8690 0.0107421875 +8691 0.17425537109375 +8692 0.010986328125 +8693 0.188201904296875 +8694 0.009490966796875 +8695 0.171234130859375 +8696 0.006011962890625 +8697 0.118438720703125 +8698 0.00213623046875 +8699 0.05706787109375 +8700 -0.001983642578125 +8701 -0.010711669921875 +8702 -0.0067138671875 +8703 -0.0914306640625 +8704 -0.011199951171875 +8705 -0.162322998046875 +8706 -0.013641357421875 +8707 -0.194549560546875 +8708 -0.01031494140625 +8709 -0.1492919921875 +8710 -0.000396728515625 +8711 -0.02166748046875 +8712 0.0107421875 +8713 0.124053955078125 +8714 0.016632080078125 +8715 0.211151123046875 +8716 0.017608642578125 +8717 0.240447998046875 +8718 0.016510009765625 +8719 0.242218017578125 +8720 0.014251708984375 +8721 0.2257080078125 +8722 0.011199951171875 +8723 0.194366455078125 +8724 0.00445556640625 +8725 0.115509033203125 +8726 -0.003875732421875 +8727 0.0128173828125 +8728 -0.00860595703125 +8729 -0.053802490234375 +8730 -0.012176513671875 +8731 -0.110626220703125 +8732 -0.01837158203125 +8733 -0.199493408203125 +8734 -0.0250244140625 +8735 -0.29437255859375 +8736 -0.02667236328125 +8737 -0.33221435546875 +8738 -0.0205078125 +8739 -0.27972412109375 +8740 -0.010894775390625 +8741 -0.185333251953125 +8742 -0.004852294921875 +8743 -0.128204345703125 +8744 -0.00311279296875 +8745 -0.115692138671875 +8746 -0.002899169921875 +8747 -0.116455078125 +8748 -0.0020751953125 +8749 -0.105926513671875 +8750 0.001983642578125 +8751 -0.053955078125 +8752 0.010162353515625 +8753 0.048797607421875 +8754 0.0185546875 +8755 0.157318115234375 +8756 0.02197265625 +8757 0.212005615234375 +8758 0.02099609375 +8759 0.218475341796875 +8760 0.021026611328125 +8761 0.23724365234375 +8762 0.025421142578125 +8763 0.30535888671875 +8764 0.03057861328125 +8765 0.38128662109375 +8766 0.031280517578125 +8767 0.404449462890625 +8768 0.029327392578125 +8769 0.3944091796875 +8770 0.028045654296875 +8771 0.3885498046875 +8772 0.025360107421875 +8773 0.362640380859375 +8774 0.017486572265625 +8775 0.27362060546875 +8776 0.004058837890625 +8777 0.11712646484375 +8778 -0.0103759765625 +8779 -0.054901123046875 +8780 -0.02130126953125 +8781 -0.19085693359375 +8782 -0.02838134765625 +8783 -0.28570556640625 +8784 -0.03167724609375 +8785 -0.339263916015625 +8786 -0.033538818359375 +8787 -0.3775634765625 +8788 -0.03802490234375 +8789 -0.445709228515625 +8790 -0.04443359375 +8791 -0.535064697265625 +8792 -0.051422119140625 +8793 -0.629058837890625 +8794 -0.056365966796875 +8795 -0.697601318359375 +8796 -0.056121826171875 +8797 -0.70391845703125 +8798 -0.050201416015625 +8799 -0.6424560546875 +8800 -0.0367431640625 +8801 -0.491241455078125 +8802 -0.017059326171875 +8803 -0.265716552734375 +8804 0.00372314453125 +8805 -0.023712158203125 +8806 0.022735595703125 +8807 0.201751708984375 +8808 0.036956787109375 +8809 0.375823974609375 +8810 0.0452880859375 +8811 0.485076904296875 +8812 0.05126953125 +8813 0.56884765625 +8814 0.0556640625 +8815 0.634765625 +8816 0.054595947265625 +8817 0.63763427734375 +8818 0.047088623046875 +8819 0.5660400390625 +8820 0.03778076171875 +8821 0.4720458984375 +8822 0.03125 +8823 0.40692138671875 +8824 0.028167724609375 +8825 0.3778076171875 +8826 0.027862548828125 +8827 0.376953125 +8828 0.027496337890625 +8829 0.371978759765625 +8830 0.02264404296875 +8831 0.313140869140625 +8832 0.01190185546875 +8833 0.184417724609375 +8834 -0.00250244140625 +8835 0.011199951171875 +8836 -0.017486572265625 +8837 -0.171051025390625 +8838 -0.03094482421875 +8839 -0.33740234375 +8840 -0.041534423828125 +8841 -0.47198486328125 +8842 -0.048065185546875 +8843 -0.560394287109375 +8844 -0.048675537109375 +8845 -0.58056640625 +8846 -0.04473876953125 +8847 -0.54754638671875 +8848 -0.040496826171875 +8849 -0.508575439453125 +8850 -0.035614013671875 +8851 -0.459503173828125 +8852 -0.029571533203125 +8853 -0.394378662109375 +8854 -0.02581787109375 +8855 -0.35260009765625 +8856 -0.022369384765625 +8857 -0.31170654296875 +8858 -0.0126953125 +8859 -0.197418212890625 +8860 0.00335693359375 +8861 -0.007965087890625 +8862 0.021453857421875 +8863 0.207489013671875 +8864 0.038177490234375 +8865 0.409210205078125 +8866 0.0513916015625 +8867 0.57208251953125 +8868 0.058502197265625 +8869 0.66595458984375 +8870 0.0567626953125 +8871 0.65875244140625 +8872 0.047698974609375 +8873 0.56744384765625 +8874 0.03485107421875 +8875 0.431396484375 +8876 0.022125244140625 +8877 0.29443359375 +8878 0.011810302734375 +8879 0.182464599609375 +8880 0.00115966796875 +8881 0.06365966796875 +8882 -0.01104736328125 +8883 -0.075958251953125 +8884 -0.02069091796875 +8885 -0.189422607421875 +8886 -0.027313232421875 +8887 -0.271942138671875 +8888 -0.032684326171875 +8889 -0.342529296875 +8890 -0.03363037109375 +8891 -0.364166259765625 +8892 -0.02935791015625 +8893 -0.327239990234375 +8894 -0.023895263671875 +8895 -0.2769775390625 +8896 -0.02081298828125 +8897 -0.253692626953125 +8898 -0.01898193359375 +8899 -0.24365234375 +8900 -0.014190673828125 +8901 -0.1983642578125 +8902 -0.006317138671875 +8903 -0.116241455078125 +8904 0.001068115234375 +8905 -0.036834716796875 +8906 0.007537841796875 +8907 0.034881591796875 +8908 0.01239013671875 +8909 0.09124755859375 +8910 0.013580322265625 +8911 0.10888671875 +8912 0.01446533203125 +8913 0.125518798828125 +8914 0.01654052734375 +8915 0.15771484375 +8916 0.017486572265625 +8917 0.17828369140625 +8918 0.015899658203125 +8919 0.17108154296875 +8920 0.011322021484375 +8921 0.129974365234375 +8922 0.006195068359375 +8923 0.082427978515625 +8924 0.000518798828125 +8925 0.027679443359375 +8926 -0.00836181640625 +8927 -0.065643310546875 +8928 -0.017059326171875 +8929 -0.15936279296875 +8930 -0.02203369140625 +8931 -0.21307373046875 +8932 -0.023956298828125 +8933 -0.234649658203125 +8934 -0.020751953125 +8935 -0.2001953125 +8936 -0.013275146484375 +8937 -0.119171142578125 +8938 -0.00445556640625 +8939 -0.024749755859375 +8940 0.005889892578125 +8941 0.085784912109375 +8942 0.014678955078125 +8943 0.178131103515625 +8944 0.018646240234375 +8945 0.215576171875 +8946 0.018951416015625 +8947 0.211456298828125 +8948 0.01641845703125 +8949 0.17523193359375 +8950 0.012939453125 +8951 0.128753662109375 +8952 0.011077880859375 +8953 0.1019287109375 +8954 0.009033203125 +8955 0.0743408203125 +8956 0.006561279296875 +8957 0.04327392578125 +8958 0.006195068359375 +8959 0.038177490234375 +8960 0.010009765625 +8961 0.076263427734375 +8962 0.01702880859375 +8963 0.14105224609375 +8964 0.022308349609375 +8965 0.186431884765625 +8966 0.022857666015625 +8967 0.188812255859375 +8968 0.017425537109375 +8969 0.1390380859375 +8970 0.006439208984375 +8971 0.041778564453125 +8972 -0.007354736328125 +8973 -0.079437255859375 +8974 -0.0234375 +8975 -0.219390869140625 +8976 -0.040618896484375 +8977 -0.367828369140625 +8978 -0.055419921875 +8979 -0.494873046875 +8980 -0.06256103515625 +8981 -0.556243896484375 +8982 -0.056884765625 +8983 -0.508697509765625 +8984 -0.041168212890625 +8985 -0.3756103515625 +8986 -0.022857666015625 +8987 -0.218902587890625 +8988 -0.004913330078125 +8989 -0.063751220703125 +8990 0.012847900390625 +8991 0.091552734375 +8992 0.029205322265625 +8993 0.23602294921875 +8994 0.041015625 +8995 0.342987060546875 +8996 0.0462646484375 +8997 0.39520263671875 +8998 0.04461669921875 +8999 0.389373779296875 +9000 0.0360107421875 +9001 0.324249267578125 +9002 0.023406982421875 +9003 0.224090576171875 +9004 0.011077880859375 +9005 0.124267578125 +9006 0.00048828125 +9007 0.037078857421875 +9008 -0.005035400390625 +9009 -0.010101318359375 +9010 -0.00579833984375 +9011 -0.019439697265625 +9012 -0.005615234375 +9013 -0.022796630859375 +9014 -0.0023193359375 +9015 -0.001556396484375 +9016 0.00543212890625 +9017 0.056304931640625 +9018 0.012298583984375 +9019 0.106719970703125 +9020 0.011962890625 +9021 0.096893310546875 +9022 0.006256103515625 +9023 0.042694091796875 +9024 -0.00030517578125 +9025 -0.018035888671875 +9026 -0.006591796875 +9027 -0.07586669921875 +9028 -0.01129150390625 +9029 -0.11944580078125 +9030 -0.0157470703125 +9031 -0.15972900390625 +9032 -0.020660400390625 +9033 -0.202606201171875 +9034 -0.026123046875 +9035 -0.24859619140625 +9036 -0.032989501953125 +9037 -0.30517578125 +9038 -0.0400390625 +9039 -0.36212158203125 +9040 -0.0439453125 +9041 -0.39141845703125 +9042 -0.040130615234375 +9043 -0.35528564453125 +9044 -0.02813720703125 +9045 -0.249969482421875 +9046 -0.010009765625 +9047 -0.092864990234375 +9048 0.01104736328125 +9049 0.08905029296875 +9050 0.027801513671875 +9051 0.2352294921875 +9052 0.037109375 +9053 0.318817138671875 +9054 0.041259765625 +9055 0.358642578125 +9056 0.0394287109375 +9057 0.347747802734375 +9058 0.031585693359375 +9059 0.28564453125 +9060 0.023834228515625 +9061 0.223175048828125 +9062 0.020599365234375 +9063 0.196746826171875 +9064 0.0186767578125 +9065 0.179840087890625 +9066 0.016021728515625 +9067 0.155548095703125 +9068 0.015899658203125 +9069 0.151214599609375 +9070 0.01708984375 +9071 0.156951904296875 +9072 0.0146484375 +9073 0.13177490234375 +9074 0.011566162109375 +9075 0.100799560546875 +9076 0.010589599609375 +9077 0.087127685546875 +9078 0.007354736328125 +9079 0.05487060546875 +9080 0.000244140625 +9081 -0.009002685546875 +9082 -0.010650634765625 +9083 -0.10400390625 +9084 -0.0252685546875 +9085 -0.229400634765625 +9086 -0.040069580078125 +9087 -0.35552978515625 +9088 -0.05023193359375 +9089 -0.441925048828125 +9090 -0.053985595703125 +9091 -0.473846435546875 +9092 -0.052978515625 +9093 -0.464813232421875 +9094 -0.047698974609375 +9095 -0.419097900390625 +9096 -0.037841796875 +9097 -0.334320068359375 +9098 -0.025482177734375 +9099 -0.227935791015625 +9100 -0.013427734375 +9101 -0.12347412109375 +9102 -0.00244140625 +9103 -0.02764892578125 +9104 0.009674072265625 +9105 0.077667236328125 +9106 0.025421142578125 +9107 0.2132568359375 +9108 0.045989990234375 +9109 0.38885498046875 +9110 0.06878662109375 +9111 0.582794189453125 +9112 0.086517333984375 +9113 0.734039306640625 +9114 0.094085693359375 +9115 0.800140380859375 +9116 0.091217041015625 +9117 0.7783203125 +9118 0.0775146484375 +9119 0.6651611328125 +9120 0.0528564453125 +9121 0.45965576171875 +9122 0.021759033203125 +9123 0.199188232421875 +9124 -0.007904052734375 +9125 -0.050689697265625 +9126 -0.029296875 +9127 -0.23297119140625 +9128 -0.040374755859375 +9129 -0.33013916015625 +9130 -0.044342041015625 +9131 -0.368408203125 +9132 -0.04498291015625 +9133 -0.378936767578125 +9134 -0.044158935546875 +9135 -0.376983642578125 +9136 -0.043975830078125 +9137 -0.37969970703125 +9138 -0.044952392578125 +9139 -0.391510009765625 +9140 -0.043853759765625 +9141 -0.385345458984375 +9142 -0.038421630859375 +9143 -0.3419189453125 +9144 -0.031219482421875 +9145 -0.28289794921875 +9146 -0.0274658203125 +9147 -0.251617431640625 +9148 -0.029327392578125 +9149 -0.266143798828125 +9150 -0.030426025390625 +9151 -0.273345947265625 +9152 -0.023956298828125 +9153 -0.216796875 +9154 -0.01373291015625 +9155 -0.128265380859375 +9156 -0.006927490234375 +9157 -0.068145751953125 +9158 -0.00433349609375 +9159 -0.0430908203125 +9160 -0.00250244140625 +9161 -0.024444580078125 +9162 0.00250244140625 +9163 0.020721435546875 +9164 0.014556884765625 +9165 0.124481201171875 +9166 0.030181884765625 +9167 0.25787353515625 +9168 0.044403076171875 +9169 0.379119873046875 +9170 0.05621337890625 +9171 0.47991943359375 +9172 0.061798095703125 +9173 0.5281982421875 +9174 0.059600830078125 +9175 0.511138916015625 +9176 0.052947998046875 +9177 0.456207275390625 +9178 0.047119140625 +9179 0.407470703125 +9180 0.044403076171875 +9181 0.383758544921875 +9182 0.041351318359375 +9183 0.35687255859375 +9184 0.03619384765625 +9185 0.31182861328125 +9186 0.0291748046875 +9187 0.250885009765625 +9188 0.019256591796875 +9189 0.1654052734375 +9190 0.003997802734375 +9191 0.035247802734375 +9192 -0.016876220703125 +9193 -0.142059326171875 +9194 -0.039703369140625 +9195 -0.33563232421875 +9196 -0.06317138671875 +9197 -0.5345458984375 +9198 -0.08526611328125 +9199 -0.72186279296875 +9200 -0.098663330078125 +9201 -0.836669921875 +9202 -0.097869873046875 +9203 -0.8326416015625 +9204 -0.08526611328125 +9205 -0.7296142578125 +9206 -0.0675048828125 +9207 -0.582550048828125 +9208 -0.0504150390625 +9209 -0.440093994140625 +9210 -0.036651611328125 +9211 -0.324310302734375 +9212 -0.022125244140625 +9213 -0.20147705078125 +9214 -0.003570556640625 +9215 -0.044647216796875 +9216 0.013336181640625 +9217 0.103973388671875 +9218 0.022918701171875 +9219 0.202392578125 +9220 0.02752685546875 +9221 0.264495849609375 +9222 0.034820556640625 +9223 0.338897705078125 +9224 0.04779052734375 +9225 0.443817138671875 +9226 0.061370849609375 +9227 0.545074462890625 +9228 0.07177734375 +9229 0.6173095703125 +9230 0.0777587890625 +9231 0.6524658203125 +9232 0.08123779296875 +9233 0.66339111328125 +9234 0.082977294921875 +9235 0.6561279296875 +9236 0.079132080078125 +9237 0.606781005859375 +9238 0.067352294921875 +9239 0.501190185546875 +9240 0.049407958984375 +9241 0.352783203125 +9242 0.02734375 +9243 0.176544189453125 +9244 -0.000213623046875 +9245 -0.034820556640625 +9246 -0.02996826171875 +9247 -0.258209228515625 +9248 -0.054351806640625 +9249 -0.44244384765625 +9250 -0.071685791015625 +9251 -0.5753173828125 +9252 -0.081390380859375 +9253 -0.65203857421875 +9254 -0.078857421875 +9255 -0.641632080078125 +9256 -0.066864013671875 +9257 -0.562164306640625 +9258 -0.0521240234375 +9259 -0.458038330078125 +9260 -0.037750244140625 +9261 -0.350555419921875 +9262 -0.02679443359375 +9263 -0.260528564453125 +9264 -0.01971435546875 +9265 -0.192108154296875 +9266 -0.01580810546875 +9267 -0.141937255859375 +9268 -0.013671875 +9269 -0.1021728515625 +9270 -0.011566162109375 +9271 -0.062896728515625 +9272 -0.0074462890625 +9273 -0.011932373046875 +9274 0.000701904296875 +9275 0.062835693359375 +9276 0.011138916015625 +9277 0.148712158203125 +9278 0.02337646484375 +9279 0.241729736328125 +9280 0.03857421875 +9281 0.34912109375 +9282 0.0546875 +9283 0.457305908203125 +9284 0.068328857421875 +9285 0.54388427734375 +9286 0.074005126953125 +9287 0.5728759765625 +9288 0.06585693359375 +9289 0.506591796875 +9290 0.044708251953125 +9291 0.351226806640625 +9292 0.016448974609375 +9293 0.146514892578125 +9294 -0.0111083984375 +9295 -0.05523681640625 +9296 -0.032379150390625 +9297 -0.21624755859375 +9298 -0.04730224609375 +9299 -0.334930419921875 +9300 -0.054779052734375 +9301 -0.402984619140625 +9302 -0.058135986328125 +9303 -0.4412841796875 +9304 -0.064483642578125 +9305 -0.49578857421875 +9306 -0.07293701171875 +9307 -0.5601806640625 +9308 -0.078460693359375 +9309 -0.600738525390625 +9310 -0.076019287109375 +9311 -0.584228515625 +9312 -0.060821533203125 +9313 -0.47930908203125 +9314 -0.03179931640625 +9315 -0.27935791015625 +9316 0.00738525390625 +9317 -0.0089111328125 +9318 0.047271728515625 +9319 0.268798828125 +9320 0.077178955078125 +9321 0.482818603515625 +9322 0.092803955078125 +9323 0.60369873046875 +9324 0.09716796875 +9325 0.650421142578125 +9326 0.096649169921875 +9327 0.66400146484375 +9328 0.0909423828125 +9329 0.6414794921875 +9330 0.07861328125 +9331 0.572540283203125 +9332 0.06597900390625 +9333 0.498138427734375 +9334 0.056304931640625 +9335 0.439453125 +9336 0.04644775390625 +9337 0.375518798828125 +9338 0.031524658203125 +9339 0.274505615234375 +9340 0.007293701171875 +9341 0.1087646484375 +9342 -0.022857666015625 +9343 -0.099395751953125 +9344 -0.054229736328125 +9345 -0.3182373046875 +9346 -0.087127685546875 +9347 -0.5489501953125 +9348 -0.11895751953125 +9349 -0.7738037109375 +9350 -0.14178466796875 +9351 -0.86383056640625 +9352 -0.15069580078125 +9353 -0.870391845703125 +9354 -0.148529052734375 +9355 -0.86895751953125 +9356 -0.137420654296875 +9357 -0.861053466796875 +9358 -0.11480712890625 +9359 -0.765869140625 +9360 -0.079010009765625 +9361 -0.5301513671875 +9362 -0.031158447265625 +9363 -0.214691162109375 +9364 0.02215576171875 +9365 0.137359619140625 +9366 0.07318115234375 +9367 0.474822998046875 +9368 0.1165771484375 +9369 0.76239013671875 +9370 0.1483154296875 +9371 0.867462158203125 +9372 0.1685791015625 +9373 0.870361328125 +9374 0.1756591796875 +9375 0.86480712890625 +9376 0.170501708984375 +9377 0.831817626953125 +9378 0.156951904296875 +9379 0.677581787109375 +9380 0.136016845703125 +9381 0.495880126953125 +9382 0.110626220703125 +9383 0.30767822265625 +9384 0.081146240234375 +9385 0.116180419921875 +9386 0.0428466796875 +9387 -0.110748291015625 +9388 -0.0052490234375 +9389 -0.381805419921875 +9390 -0.056671142578125 +9391 -0.6572265625 +9392 -0.102294921875 +9393 -0.857421875 +9394 -0.135650634765625 +9395 -0.870391845703125 +9396 -0.155731201171875 +9397 -0.870391845703125 +9398 -0.16668701171875 +9399 -0.86444091796875 +9400 -0.174041748046875 +9401 -0.85723876953125 +9402 -0.175140380859375 +9403 -0.790008544921875 +9404 -0.161834716796875 +9405 -0.62847900390625 +9406 -0.13372802734375 +9407 -0.3956298828125 +9408 -0.095916748046875 +9409 -0.126708984375 +9410 -0.0526123046875 +9411 0.150115966796875 +9412 -0.005645751953125 +9413 0.424041748046875 +9414 0.040802001953125 +9415 0.670623779296875 +9416 0.08087158203125 +9417 0.854522705078125 +9418 0.11187744140625 +9419 0.866485595703125 +9420 0.131500244140625 +9421 0.86920166015625 +9422 0.142547607421875 +9423 0.8653564453125 +9424 0.14715576171875 +9425 0.857147216796875 +9426 0.14495849609375 +9427 0.766845703125 +9428 0.136810302734375 +9429 0.628509521484375 +9430 0.12176513671875 +9431 0.462127685546875 +9432 0.103851318359375 +9433 0.297210693359375 +9434 0.084991455078125 +9435 0.14862060546875 +9436 0.061767578125 +9437 -0.00537109375 +9438 0.035400390625 +9439 -0.15753173828125 +9440 0.00537109375 +9441 -0.31304931640625 +9442 -0.0303955078125 +9443 -0.48876953125 +9444 -0.064788818359375 +9445 -0.6416015625 +9446 -0.09405517578125 +9447 -0.751373291015625 +9448 -0.121734619140625 +9449 -0.84619140625 +9450 -0.145660400390625 +9451 -0.861297607421875 +9452 -0.160858154296875 +9453 -0.863250732421875 +9454 -0.162567138671875 +9455 -0.856597900390625 +9456 -0.152740478515625 +9457 -0.7498779296875 +9458 -0.1402587890625 +9459 -0.624542236328125 +9460 -0.12188720703125 +9461 -0.47808837890625 +9462 -0.088836669921875 +9463 -0.253387451171875 +9464 -0.048065185546875 +9465 0.003692626953125 +9466 -0.010009765625 +9467 0.2257080078125 +9468 0.027191162109375 +9469 0.427154541015625 +9470 0.0684814453125 +9471 0.643218994140625 +9472 0.11285400390625 +9473 0.855926513671875 +9474 0.151580810546875 +9475 0.870361328125 +9476 0.176483154296875 +9477 0.870361328125 +9478 0.18890380859375 +9479 0.862762451171875 +9480 0.188232421875 +9481 0.79669189453125 +9482 0.17254638671875 +9483 0.595794677734375 +9484 0.14697265625 +9485 0.362152099609375 +9486 0.1163330078125 +9487 0.1270751953125 +9488 0.084136962890625 +9489 -0.086944580078125 +9490 0.050384521484375 +9491 -0.2784423828125 +9492 0.008270263671875 +9493 -0.484832763671875 +9494 -0.046142578125 +9495 -0.729583740234375 +9496 -0.103912353515625 +9497 -0.86688232421875 +9498 -0.153778076171875 +9499 -0.870391845703125 +9500 -0.195037841796875 +9501 -0.86859130859375 +9502 -0.227569580078125 +9503 -0.86279296875 +9504 -0.244903564453125 +9505 -0.817962646484375 +9506 -0.238739013671875 +9507 -0.6116943359375 +9508 -0.207763671875 +9509 -0.3128662109375 +9510 -0.158050537109375 +9511 0.039398193359375 +9512 -0.0931396484375 +9513 0.422821044921875 +9514 -0.0189208984375 +9515 0.805145263671875 +9516 0.052276611328125 +9517 0.870361328125 +9518 0.1102294921875 +9519 0.870361328125 +9520 0.153106689453125 +9521 0.860015869140625 +9522 0.179779052734375 +9523 0.727935791015625 +9524 0.189483642578125 +9525 0.48114013671875 +9526 0.186859130859375 +9527 0.2059326171875 +9528 0.17626953125 +9529 -0.06103515625 +9530 0.15966796875 +9531 -0.29913330078125 +9532 0.134429931640625 +9533 -0.516204833984375 +9534 0.0977783203125 +9535 -0.7252197265625 +9536 0.054229736328125 +9537 -0.85980224609375 +9538 0.010009765625 +9539 -0.870391845703125 +9540 -0.029510498046875 +9541 -0.870391845703125 +9542 -0.055511474609375 +9543 -0.858062744140625 +9544 -0.0673828125 +9545 -0.673004150390625 +9546 -0.07501220703125 +9547 -0.42694091796875 +9548 -0.086700439453125 +9549 -0.2100830078125 +9550 -0.102203369140625 +9551 -0.0362548828125 +9552 -0.11627197265625 +9553 0.10943603515625 +9554 -0.125335693359375 +9555 0.23516845703125 +9556 -0.12188720703125 +9557 0.373687744140625 +9558 -0.106353759765625 +9559 0.517791748046875 +9560 -0.090362548828125 +9561 0.602783203125 +9562 -0.07293701171875 +9563 0.635711669921875 +9564 -0.047943115234375 +9565 0.655181884765625 +9566 -0.01715087890625 +9567 0.65948486328125 +9568 0.018035888671875 +9569 0.651275634765625 +9570 0.053192138671875 +9571 0.61846923828125 +9572 0.08160400390625 +9573 0.53753662109375 +9574 0.10003662109375 +9575 0.404144287109375 +9576 0.1068115234375 +9577 0.22186279296875 +9578 0.102325439453125 +9579 0.003997802734375 +9580 0.0899658203125 +9581 -0.22100830078125 +9582 0.0736083984375 +9583 -0.42449951171875 +9584 0.0572509765625 +9585 -0.579833984375 +9586 0.04876708984375 +9587 -0.641876220703125 +9588 0.04693603515625 +9589 -0.6177978515625 +9590 0.039886474609375 +9591 -0.575531005859375 +9592 0.02655029296875 +9593 -0.526336669921875 +9594 0.016448974609375 +9595 -0.42645263671875 +9596 0.014556884765625 +9597 -0.2581787109375 +9598 0.01409912109375 +9599 -0.068695068359375 +9600 0.0079345703125 +9601 0.09222412109375 +9602 -0.000518798828125 +9603 0.232147216796875 +9604 -0.00946044921875 +9605 0.3509521484375 +9606 -0.0244140625 +9607 0.410064697265625 +9608 -0.050872802734375 +9609 0.372955322265625 +9610 -0.08502197265625 +9611 0.2554931640625 +9612 -0.11724853515625 +9613 0.10711669921875 +9614 -0.143951416015625 +9615 -0.052886962890625 +9616 -0.158477783203125 +9617 -0.186279296875 +9618 -0.150543212890625 +9619 -0.23291015625 +9620 -0.124267578125 +9621 -0.209442138671875 +9622 -0.091766357421875 +9623 -0.174163818359375 +9624 -0.054473876953125 +9625 -0.126739501953125 +9626 -0.010528564453125 +9627 -0.048126220703125 +9628 0.03485107421875 +9629 0.0426025390625 +9630 0.07318115234375 +9631 0.10748291015625 +9632 0.10205078125 +9633 0.1409912109375 +9634 0.1302490234375 +9635 0.19708251953125 +9636 0.15655517578125 +9637 0.273651123046875 +9638 0.17071533203125 +9639 0.31768798828125 +9640 0.1748046875 +9641 0.341094970703125 +9642 0.173431396484375 +9643 0.368011474609375 +9644 0.162353515625 +9645 0.37249755859375 +9646 0.132476806640625 +9647 0.30072021484375 +9648 0.08465576171875 +9649 0.1517333984375 +9650 0.0311279296875 +9651 -0.01470947265625 +9652 -0.024871826171875 +9653 -0.1883544921875 +9654 -0.0826416015625 +9655 -0.372711181640625 +9656 -0.131011962890625 +9657 -0.51397705078125 +9658 -0.161346435546875 +9659 -0.57177734375 +9660 -0.17144775390625 +9661 -0.53948974609375 +9662 -0.16387939453125 +9663 -0.43511962890625 +9664 -0.145050048828125 +9665 -0.2962646484375 +9666 -0.12176513671875 +9667 -0.161102294921875 +9668 -0.096649169921875 +9669 -0.0435791015625 +9670 -0.06927490234375 +9671 0.060394287109375 +9672 -0.042816162109375 +9673 0.13665771484375 +9674 -0.020843505859375 +9675 0.170135498046875 +9676 -0.003448486328125 +9677 0.16552734375 +9678 0.014617919921875 +9679 0.15728759765625 +9680 0.033233642578125 +9681 0.150787353515625 +9682 0.046875 +9683 0.12200927734375 +9684 0.056243896484375 +9685 0.080108642578125 +9686 0.06524658203125 +9687 0.05126953125 +9688 0.0782470703125 +9689 0.062896728515625 +9690 0.09063720703125 +9691 0.09271240234375 +9692 0.093414306640625 +9693 0.092987060546875 +9694 0.089263916015625 +9695 0.07855224609375 +9696 0.08111572265625 +9697 0.06427001953125 +9698 0.066558837890625 +9699 0.0347900390625 +9700 0.04583740234375 +9701 -0.01171875 +9702 0.02325439453125 +9703 -0.056060791015625 +9704 0.00750732421875 +9705 -0.055511474609375 +9706 -0.00054931640625 +9707 -0.010467529296875 +9708 -0.009918212890625 +9709 0.02508544921875 +9710 -0.024444580078125 +9711 0.025665283203125 +9712 -0.038543701171875 +9713 0.017333984375 +9714 -0.051300048828125 +9715 0.00189208984375 +9716 -0.06427001953125 +9717 -0.03173828125 +9718 -0.074951171875 +9719 -0.071502685546875 +9720 -0.086578369140625 +9721 -0.13543701171875 +9722 -0.098602294921875 +9723 -0.219970703125 +9724 -0.106781005859375 +9725 -0.300506591796875 +9726 -0.111419677734375 +9727 -0.376312255859375 +9728 -0.107269287109375 +9729 -0.416107177734375 +9730 -0.08587646484375 +9731 -0.371124267578125 +9732 -0.048187255859375 +9733 -0.242279052734375 +9734 -0.002593994140625 +9735 -0.069732666015625 +9736 0.046295166015625 +9737 0.125640869140625 +9738 0.0919189453125 +9739 0.31268310546875 +9740 0.126708984375 +9741 0.45501708984375 +9742 0.15087890625 +9743 0.554779052734375 +9744 0.1640625 +9745 0.61065673828125 +9746 0.16387939453125 +9747 0.610931396484375 +9748 0.145599365234375 +9749 0.531463623046875 +9750 0.11260986328125 +9751 0.3883056640625 +9752 0.07586669921875 +9753 0.23468017578125 +9754 0.040679931640625 +9755 0.095245361328125 +9756 0.012664794921875 +9757 -0.00396728515625 +9758 -0.004852294921875 +9759 -0.04852294921875 +9760 -0.014739990234375 +9761 -0.055145263671875 +9762 -0.026947021484375 +9763 -0.0758056640625 +9764 -0.046722412109375 +9765 -0.138702392578125 +9766 -0.066741943359375 +9767 -0.209197998046875 +9768 -0.08709716796875 +9769 -0.289031982421875 +9770 -0.107696533203125 +9771 -0.37884521484375 +9772 -0.123992919921875 +9773 -0.456329345703125 +9774 -0.134979248046875 +9775 -0.51641845703125 +9776 -0.1328125 +9777 -0.519287109375 +9778 -0.116363525390625 +9779 -0.458251953125 +9780 -0.09619140625 +9781 -0.384796142578125 +9782 -0.077545166015625 +9783 -0.323699951171875 +9784 -0.0596923828125 +9785 -0.269287109375 +9786 -0.0377197265625 +9787 -0.1951904296875 +9788 -0.01177978515625 +9789 -0.100006103515625 +9790 0.012359619140625 +9791 -0.01055908203125 +9792 0.0404052734375 +9793 0.1033935546875 +9794 0.073577880859375 +9795 0.24908447265625 +9796 0.10101318359375 +9797 0.373199462890625 +9798 0.11907958984375 +9799 0.45806884765625 +9800 0.129302978515625 +9801 0.511474609375 +9802 0.13818359375 +9803 0.565399169921875 +9804 0.144134521484375 +9805 0.61138916015625 +9806 0.13543701171875 +9807 0.5897216796875 +9808 0.11041259765625 +9809 0.4906005859375 +9810 0.0728759765625 +9811 0.33148193359375 +9812 0.030242919921875 +9813 0.147796630859375 +9814 -0.008819580078125 +9815 -0.01873779296875 +9816 -0.038421630859375 +9817 -0.140289306640625 +9818 -0.053314208984375 +9819 -0.191986083984375 +9820 -0.055389404296875 +9821 -0.184295654296875 +9822 -0.053375244140625 +9823 -0.161834716796875 +9824 -0.055572509765625 +9825 -0.166595458984375 +9826 -0.061004638671875 +9827 -0.19390869140625 +9828 -0.065826416015625 +9829 -0.22442626953125 +9830 -0.074493408203125 +9831 -0.279754638671875 +9832 -0.082977294921875 +9833 -0.3389892578125 +9834 -0.081939697265625 +9835 -0.3543701171875 +9836 -0.076080322265625 +9837 -0.348175048828125 +9838 -0.0667724609375 +9839 -0.32598876953125 +9840 -0.04840087890625 +9841 -0.2581787109375 +9842 -0.02020263671875 +9843 -0.139801025390625 +9844 0.014678955078125 +9845 0.014617919921875 +9846 0.043853759765625 +9847 0.144378662109375 +9848 0.061492919921875 +9849 0.221038818359375 +9850 0.072723388671875 +9851 0.27069091796875 +9852 0.07763671875 +9853 0.294036865234375 +9854 0.080413818359375 +9855 0.311767578125 +9856 0.084228515625 +9857 0.339141845703125 +9858 0.086181640625 +9859 0.360260009765625 +9860 0.083465576171875 +9861 0.360504150390625 +9862 0.069366455078125 +9863 0.308380126953125 +9864 0.0391845703125 +9865 0.18170166015625 +9866 -0.001678466796875 +9867 0.0047607421875 +9868 -0.042999267578125 +9869 -0.17559814453125 +9870 -0.074951171875 +9871 -0.3143310546875 +9872 -0.088043212890625 +9873 -0.36785888671875 +9874 -0.087890625 +9875 -0.36248779296875 +9876 -0.084259033203125 +9877 -0.343536376953125 +9878 -0.0751953125 +9879 -0.3018798828125 +9880 -0.05938720703125 +9881 -0.231414794921875 +9882 -0.033721923828125 +9883 -0.117645263671875 +9884 -0.005279541015625 +9885 0.007049560546875 +9886 0.0140380859375 +9887 0.087982177734375 +9888 0.027191162109375 +9889 0.13946533203125 +9890 0.036834716796875 +9891 0.17425537109375 +9892 0.041961669921875 +9893 0.188201904296875 +9894 0.040252685546875 +9895 0.171234130859375 +9896 0.03057861328125 +9897 0.118438720703125 +9898 0.018768310546875 +9899 0.05706787109375 +9900 0.00518798828125 +9901 -0.010711669921875 +9902 -0.0115966796875 +9903 -0.0914306640625 +9904 -0.026702880859375 +9905 -0.162322998046875 +9906 -0.033905029296875 +9907 -0.194549560546875 +9908 -0.0247802734375 +9909 -0.1492919921875 +9910 0.001739501953125 +9911 -0.02166748046875 +9912 0.0318603515625 +9913 0.124053955078125 +9914 0.049041748046875 +9915 0.211151123046875 +9916 0.0535888671875 +9917 0.240447998046875 +9918 0.052154541015625 +9919 0.242218017578125 +9920 0.04681396484375 +9921 0.2257080078125 +9922 0.038421630859375 +9923 0.194366455078125 +9924 0.019989013671875 +9925 0.115509033203125 +9926 -0.003204345703125 +9927 0.0128173828125 +9928 -0.0181884765625 +9929 -0.053802490234375 +9930 -0.0306396484375 +9931 -0.110626220703125 +9932 -0.049591064453125 +9933 -0.199493408203125 +9934 -0.069488525390625 +9935 -0.29437255859375 +9936 -0.076751708984375 +9937 -0.33221435546875 +9938 -0.06427001953125 +9939 -0.27972412109375 +9940 -0.04254150390625 +9941 -0.185333251953125 +9942 -0.028717041015625 +9943 -0.128204345703125 +9944 -0.024505615234375 +9945 -0.115692138671875 +9946 -0.023193359375 +9947 -0.116455078125 +9948 -0.01959228515625 +9949 -0.105926513671875 +9950 -0.007232666015625 +9951 -0.053955078125 +9952 0.01580810546875 +9953 0.048797607421875 +9954 0.039794921875 +9955 0.157318115234375 +9956 0.05181884765625 +9957 0.212005615234375 +9958 0.053070068359375 +9959 0.218475341796875 +9960 0.056671142578125 +9961 0.23724365234375 +9962 0.070648193359375 +9963 0.30535888671875 +9964 0.0860595703125 +9965 0.38128662109375 +9966 0.089874267578125 +9967 0.404449462890625 +9968 0.086395263671875 +9969 0.3944091796875 +9970 0.08380126953125 +9971 0.3885498046875 +9972 0.076934814453125 +9973 0.362640380859375 +9974 0.056549072265625 +9975 0.27362060546875 +9976 0.021759033203125 +9977 0.11712646484375 +9978 -0.01611328125 +9979 -0.054901123046875 +9980 -0.0458984375 +9981 -0.19085693359375 +9982 -0.066497802734375 +9983 -0.28570556640625 +9984 -0.0772705078125 +9985 -0.339263916015625 +9986 -0.0841064453125 +9987 -0.3775634765625 +9988 -0.0982666015625 +9989 -0.445709228515625 +9990 -0.118011474609375 +9991 -0.535064697265625 +9992 -0.13958740234375 +9993 -0.629058837890625 +9994 -0.15576171875 +9995 -0.697601318359375 +9996 -0.15753173828125 +9997 -0.70391845703125 +9998 -0.143524169921875 +9999 -0.6424560546875 +10000 -0.10821533203125 +10001 -0.491241455078125 +10002 -0.0552978515625 +10003 -0.265716552734375 +10004 0.001068115234375 +10005 -0.023712158203125 +10006 0.05291748046875 +10007 0.201751708984375 +10008 0.091888427734375 +10009 0.375823974609375 +10010 0.1148681640625 +10011 0.485076904296875 +10012 0.131866455078125 +10013 0.56884765625 +10014 0.144989013671875 +10015 0.634765625 +10016 0.143218994140625 +10017 0.63763427734375 +10018 0.12384033203125 +10019 0.5660400390625 +10020 0.099853515625 +10021 0.4720458984375 +10022 0.083953857421875 +10023 0.40692138671875 +10024 0.077911376953125 +10025 0.3778076171875 +10026 0.0797119140625 +10027 0.376953125 +10028 0.0811767578125 +10029 0.371978759765625 +10030 0.06982421875 +10031 0.313140869140625 +10032 0.041473388671875 +10033 0.184417724609375 +10034 0.002227783203125 +10035 0.011199951171875 +10036 -0.039276123046875 +10037 -0.171051025390625 +10038 -0.07708740234375 +10039 -0.33740234375 +10040 -0.107452392578125 +10041 -0.47198486328125 +10042 -0.126922607421875 +10043 -0.560394287109375 +10044 -0.13018798828125 +10045 -0.58056640625 +10046 -0.12103271484375 +10047 -0.54754638671875 +10048 -0.111236572265625 +10049 -0.508575439453125 +10050 -0.0997314453125 +10051 -0.459503173828125 +10052 -0.084991455078125 +10053 -0.394378662109375 +10054 -0.07666015625 +10055 -0.35260009765625 +10056 -0.06903076171875 +10057 -0.31170654296875 +10058 -0.04351806640625 +10059 -0.197418212890625 +10060 0.00042724609375 +10061 -0.007965087890625 +10062 0.050750732421875 +10063 0.207489013671875 +10064 0.0977783203125 +10065 0.409210205078125 +10066 0.135467529296875 +10067 0.57208251953125 +10068 0.156463623046875 +10069 0.66595458984375 +10070 0.152923583984375 +10071 0.65875244140625 +10072 0.129119873046875 +10073 0.56744384765625 +10074 0.09490966796875 +10075 0.431396484375 +10076 0.061126708984375 +10077 0.29443359375 +10078 0.034210205078125 +10079 0.182464599609375 +10080 0.00616455078125 +10081 0.06365966796875 +10082 -0.02655029296875 +10083 -0.075958251953125 +10084 -0.052398681640625 +10085 -0.189422607421875 +10086 -0.070281982421875 +10087 -0.271942138671875 +10088 -0.085052490234375 +10089 -0.342529296875 +10090 -0.0877685546875 +10091 -0.364166259765625 +10092 -0.076171875 +10093 -0.327239990234375 +10094 -0.06158447265625 +10095 -0.2769775390625 +10096 -0.054107666015625 +10097 -0.253692626953125 +10098 -0.0504150390625 +10099 -0.24365234375 +10100 -0.03857421875 +10101 -0.1983642578125 +10102 -0.0181884765625 +10103 -0.116241455078125 +10104 0.000946044921875 +10105 -0.036834716796875 +10106 0.01763916015625 +10107 0.034881591796875 +10108 0.030059814453125 +10109 0.09124755859375 +10110 0.032501220703125 +10111 0.10888671875 +10112 0.034423828125 +10113 0.125518798828125 +10114 0.04010009765625 +10115 0.15771484375 +10116 0.042877197265625 +10117 0.17828369140625 +10118 0.038909912109375 +10119 0.17108154296875 +10120 0.02679443359375 +10121 0.129974365234375 +10122 0.013458251953125 +10123 0.082427978515625 +10124 -0.001220703125 +10125 0.027679443359375 +10126 -0.024932861328125 +10127 -0.065643310546875 +10128 -0.0482177734375 +10129 -0.15936279296875 +10130 -0.06109619140625 +10131 -0.21307373046875 +10132 -0.0655517578125 +10133 -0.234649658203125 +10134 -0.05572509765625 +10135 -0.2001953125 +10136 -0.034027099609375 +10137 -0.119171142578125 +10138 -0.008819580078125 +10139 -0.024749755859375 +10140 0.020477294921875 +10141 0.085784912109375 +10142 0.04522705078125 +10143 0.178131103515625 +10144 0.056243896484375 +10145 0.215576171875 +10146 0.056732177734375 +10147 0.211456298828125 +10148 0.04901123046875 +10149 0.17523193359375 +10150 0.038421630859375 +10151 0.128753662109375 +10152 0.032318115234375 +10153 0.1019287109375 +10154 0.025634765625 +10155 0.0743408203125 +10156 0.0177001953125 +10157 0.04327392578125 +10158 0.01580810546875 +10159 0.038177490234375 +10160 0.0242919921875 +10161 0.076263427734375 +10162 0.039093017578125 +10163 0.14105224609375 +10164 0.04888916015625 +10165 0.186431884765625 +10166 0.04791259765625 +10167 0.188812255859375 +10168 0.03399658203125 +10169 0.1390380859375 +10170 0.008392333984375 +10171 0.041778564453125 +10172 -0.02294921875 +10173 -0.079437255859375 +10174 -0.058685302734375 +10175 -0.219390869140625 +10176 -0.096221923828125 +10177 -0.367828369140625 +10178 -0.12811279296875 +10179 -0.494873046875 +10180 -0.14337158203125 +10181 -0.556243896484375 +10182 -0.13128662109375 +10183 -0.508697509765625 +10184 -0.09771728515625 +10185 -0.3756103515625 +10186 -0.05804443359375 +10187 -0.218902587890625 +10188 -0.018585205078125 +10189 -0.063751220703125 +10190 0.02099609375 +10191 0.091552734375 +10192 0.057952880859375 +10193 0.23602294921875 +10194 0.0855712890625 +10195 0.342987060546875 +10196 0.099578857421875 +10197 0.39520263671875 +10198 0.099090576171875 +10199 0.389373779296875 +10200 0.083709716796875 +10201 0.324249267578125 +10202 0.0594482421875 +10203 0.224090576171875 +10204 0.0350341796875 +10205 0.124267578125 +10206 0.0135498046875 +10207 0.037078857421875 +10208 0.001739501953125 +10209 -0.010101318359375 +10210 -0.000885009765625 +10211 -0.019439697265625 +10212 -0.002197265625 +10213 -0.022796630859375 +10214 0.002410888671875 +10215 -0.001556396484375 +10216 0.015960693359375 +10217 0.056304931640625 +10218 0.02752685546875 +10219 0.106719970703125 +10220 0.02410888671875 +10221 0.096893310546875 +10222 0.00970458984375 +10223 0.042694091796875 +10224 -0.0062255859375 +10225 -0.018035888671875 +10226 -0.021270751953125 +10227 -0.07586669921875 +10228 -0.0325927734375 +10229 -0.11944580078125 +10230 -0.04290771484375 +10231 -0.15972900390625 +10232 -0.05364990234375 +10233 -0.202606201171875 +10234 -0.064910888671875 +10235 -0.24859619140625 +10236 -0.078582763671875 +10237 -0.30517578125 +10238 -0.0921630859375 +10239 -0.36212158203125 +10240 -0.0986328125 +10241 -0.39141845703125 +10242 -0.088531494140625 +10243 -0.35528564453125 +10244 -0.06103515625 +10245 -0.249969482421875 +10246 -0.0203857421875 +10247 -0.092864990234375 +10248 0.026458740234375 +10249 0.08905029296875 +10250 0.0631103515625 +10251 0.2352294921875 +10252 0.082489013671875 +10253 0.318817138671875 +10254 0.0902099609375 +10255 0.358642578125 +10256 0.084564208984375 +10257 0.347747802734375 +10258 0.065582275390625 +10259 0.28564453125 +10260 0.04754638671875 +10261 0.223175048828125 +10262 0.0406494140625 +10263 0.196746826171875 +10264 0.037384033203125 +10265 0.179840087890625 +10266 0.032867431640625 +10267 0.155548095703125 +10268 0.034576416015625 +10269 0.151214599609375 +10270 0.03955078125 +10271 0.156951904296875 +10272 0.03607177734375 +10273 0.13177490234375 +10274 0.030975341796875 +10275 0.100799560546875 +10276 0.030487060546875 +10277 0.087127685546875 +10278 0.024383544921875 +10279 0.05487060546875 +10280 0.00885009765625 +10281 -0.009002685546875 +10282 -0.01605224609375 +10283 -0.10400390625 +10284 -0.05023193359375 +10285 -0.229400634765625 +10286 -0.085418701171875 +10287 -0.35552978515625 +10288 -0.110260009765625 +10289 -0.441925048828125 +10290 -0.120574951171875 +10291 -0.473846435546875 +10292 -0.120025634765625 +10293 -0.464813232421875 +10294 -0.10968017578125 +10295 -0.419097900390625 +10296 -0.088714599609375 +10297 -0.334320068359375 +10298 -0.061859130859375 +10299 -0.227935791015625 +10300 -0.035552978515625 +10301 -0.12347412109375 +10302 -0.011505126953125 +10303 -0.02764892578125 +10304 0.015472412109375 +10305 0.077667236328125 +10306 0.05133056640625 +10307 0.2132568359375 +10308 0.098907470703125 +10309 0.38885498046875 +10310 0.1522216796875 +10311 0.582794189453125 +10312 0.194183349609375 +10313 0.734039306640625 +10314 0.212890625 +10315 0.800140380859375 +10316 0.207550048828125 +10317 0.7783203125 +10318 0.177154541015625 +10319 0.6651611328125 +10320 0.12139892578125 +10321 0.45965576171875 +10322 0.050628662109375 +10323 0.199188232421875 +10324 -0.01690673828125 +10325 -0.050689697265625 +10326 -0.065399169921875 +10327 -0.23297119140625 +10328 -0.090087890625 +10329 -0.33013916015625 +10330 -0.098480224609375 +10331 -0.368408203125 +10332 -0.099395751953125 +10333 -0.378936767578125 +10334 -0.09722900390625 +10335 -0.376983642578125 +10336 -0.096893310546875 +10337 -0.37969970703125 +10338 -0.099609375 +10339 -0.391510009765625 +10340 -0.097869873046875 +10341 -0.385345458984375 +10342 -0.086212158203125 +10343 -0.3419189453125 +10344 -0.0706787109375 +10345 -0.28289794921875 +10346 -0.063323974609375 +10347 -0.251617431640625 +10348 -0.069091796875 +10349 -0.266143798828125 +10350 -0.073028564453125 +10351 -0.273345947265625 +10352 -0.059234619140625 +10353 -0.216796875 +10354 -0.0364990234375 +10355 -0.128265380859375 +10356 -0.0216064453125 +10357 -0.068145751953125 +10358 -0.01629638671875 +10359 -0.0430908203125 +10360 -0.012481689453125 +10361 -0.024444580078125 +10362 -0.0008544921875 +10363 0.020721435546875 +10364 0.027587890625 +10365 0.124481201171875 +10366 0.064727783203125 +10367 0.25787353515625 +10368 0.098876953125 +10369 0.379119873046875 +10370 0.127685546875 +10371 0.47991943359375 +10372 0.142120361328125 +10373 0.5281982421875 +10374 0.1385498046875 +10375 0.511138916015625 +10376 0.124603271484375 +10377 0.456207275390625 +10378 0.112518310546875 +10379 0.407470703125 +10380 0.10748291015625 +10381 0.383758544921875 +10382 0.101470947265625 +10383 0.35687255859375 +10384 0.090240478515625 +10385 0.31182861328125 +10386 0.0743408203125 +10387 0.250885009765625 +10388 0.051300048828125 +10389 0.1654052734375 +10390 0.01544189453125 +10391 0.035247802734375 +10392 -0.033935546875 +10393 -0.142059326171875 +10394 -0.088165283203125 +10395 -0.33563232421875 +10396 -0.1441650390625 +10397 -0.5345458984375 +10398 -0.197174072265625 +10399 -0.72186279296875 +10400 -0.230072021484375 +10401 -0.836669921875 +10402 -0.229888916015625 +10403 -0.8326416015625 +10404 -0.202117919921875 +10405 -0.7296142578125 +10406 -0.162109375 +10407 -0.582550048828125 +10408 -0.1234130859375 +10409 -0.440093994140625 +10410 -0.092132568359375 +10411 -0.324310302734375 +10412 -0.058746337890625 +10413 -0.20147705078125 +10414 -0.015655517578125 +10415 -0.044647216796875 +10416 0.02532958984375 +10417 0.103973388671875 +10418 0.052490234375 +10419 0.202392578125 +10420 0.069732666015625 +10421 0.264495849609375 +10422 0.090667724609375 +10423 0.338897705078125 +10424 0.120361328125 +10425 0.443817138671875 +10426 0.14923095703125 +10427 0.545074462890625 +10428 0.170135498046875 +10429 0.6173095703125 +10430 0.1807861328125 +10431 0.6524658203125 +10432 0.18475341796875 +10433 0.66339111328125 +10434 0.18365478515625 +10435 0.6561279296875 +10436 0.170745849609375 +10437 0.606781005859375 +10438 0.141998291015625 +10439 0.501190185546875 +10440 0.10113525390625 +10441 0.352783203125 +10442 0.05230712890625 +10443 0.176544189453125 +10444 -0.0064697265625 +10445 -0.034820556640625 +10446 -0.068756103515625 +10447 -0.258209228515625 +10448 -0.1202392578125 +10449 -0.44244384765625 +10450 -0.15753173828125 +10451 -0.5753173828125 +10452 -0.17926025390625 +10453 -0.65203857421875 +10454 -0.176727294921875 +10455 -0.641632080078125 +10456 -0.154998779296875 +10457 -0.562164306640625 +10458 -0.126495361328125 +10459 -0.458038330078125 +10460 -0.09710693359375 +10461 -0.350555419921875 +10462 -0.072601318359375 +10463 -0.260528564453125 +10464 -0.05413818359375 +10465 -0.192108154296875 +10466 -0.040740966796875 +10467 -0.141937255859375 +10468 -0.030181884765625 +10469 -0.1021728515625 +10470 -0.0196533203125 +10471 -0.062896728515625 +10472 -0.00567626953125 +10473 -0.011932373046875 +10474 0.01507568359375 +10475 0.062835693359375 +10476 0.039093017578125 +10477 0.148712158203125 +10478 0.06524658203125 +10479 0.241729736328125 +10480 0.095550537109375 +10481 0.34912109375 +10482 0.126220703125 +10483 0.457305908203125 +10484 0.15093994140625 +10485 0.54388427734375 +10486 0.15960693359375 +10487 0.5728759765625 +10488 0.141632080078125 +10489 0.506591796875 +10490 0.098724365234375 +10491 0.351226806640625 +10492 0.041961669921875 +10493 0.146514892578125 +10494 -0.0140380859375 +10495 -0.05523681640625 +10496 -0.058990478515625 +10497 -0.21624755859375 +10498 -0.09228515625 +10499 -0.334930419921875 +10500 -0.11077880859375 +10501 -0.402984619140625 +10502 -0.121063232421875 +10503 -0.4412841796875 +10504 -0.13751220703125 +10505 -0.49578857421875 +10506 -0.1580810546875 +10507 -0.5601806640625 +10508 -0.17218017578125 +10509 -0.600738525390625 +10510 -0.1693115234375 +10511 -0.584228515625 +10512 -0.1395263671875 +10513 -0.47930908203125 +10514 -0.08056640625 +10515 -0.27935791015625 +10516 9.1552734375e-05 +10517 -0.0089111328125 +10518 0.082977294921875 +10519 0.268798828125 +10520 0.146148681640625 +10521 0.482818603515625 +10522 0.18060302734375 +10523 0.60369873046875 +10524 0.192413330078125 +10525 0.650421142578125 +10526 0.194549560546875 +10527 0.66400146484375 +10528 0.1861572265625 +10529 0.6414794921875 +10530 0.164093017578125 +10531 0.572540283203125 +10532 0.141143798828125 +10533 0.498138427734375 +10534 0.123870849609375 +10535 0.439453125 +10536 0.10565185546875 +10537 0.375518798828125 +10538 0.07647705078125 +10539 0.274505615234375 +10540 0.02752685546875 +10541 0.1087646484375 +10542 -0.03436279296875 +10543 -0.099395751953125 +10544 -0.099456787109375 +10545 -0.3182373046875 +10546 -0.1683349609375 +10547 -0.5489501953125 +10548 -0.235565185546875 +10549 -0.7738037109375 +10550 -0.284820556640625 +10551 -0.86383056640625 +10552 -0.30584716796875 +10553 -0.870391845703125 +10554 -0.304290771484375 +10555 -0.86895751953125 +10556 -0.2843017578125 +10557 -0.861053466796875 +10558 -0.240509033203125 +10559 -0.765869140625 +10560 -0.16937255859375 +10561 -0.5301513671875 +10562 -0.07305908203125 +10563 -0.214691162109375 +10564 0.035064697265625 +10565 0.137359619140625 +10566 0.13909912109375 +10567 0.474822998046875 +10568 0.22808837890625 +10569 0.76239013671875 +10570 0.29376220703125 +10571 0.867462158203125 +10572 0.336395263671875 +10573 0.870361328125 +10574 0.3525390625 +10575 0.86480712890625 +10576 0.343994140625 +10577 0.831817626953125 +10578 0.3184814453125 +10579 0.677581787109375 +10580 0.277923583984375 +10581 0.495880126953125 +10582 0.2281494140625 +10583 0.30767822265625 +10584 0.169891357421875 +10585 0.116180419921875 +10586 0.09326171875 +10587 -0.110748291015625 +10588 -0.00390625 +10589 -0.381805419921875 +10590 -0.10833740234375 +10591 -0.6572265625 +10592 -0.201385498046875 +10593 -0.857421875 +10594 -0.269805908203125 +10595 -0.870391845703125 +10596 -0.311492919921875 +10597 -0.870391845703125 +10598 -0.3349609375 +10599 -0.86444091796875 +10600 -0.351470947265625 +10601 -0.85723876953125 +10602 -0.35540771484375 +10603 -0.790008544921875 +10604 -0.3299560546875 +10605 -0.62847900390625 +10606 -0.27423095703125 +10607 -0.3956298828125 +10608 -0.198516845703125 +10609 -0.126708984375 +10610 -0.111419677734375 +10611 0.150115966796875 +10612 -0.0166015625 +10613 0.424041748046875 +10614 0.0775146484375 +10615 0.670623779296875 +10616 0.158905029296875 +10617 0.854522705078125 +10618 0.22210693359375 +10619 0.866485595703125 +10620 0.26239013671875 +10621 0.86920166015625 +10622 0.2855224609375 +10623 0.8653564453125 +10624 0.295806884765625 +10625 0.857147216796875 +10626 0.29241943359375 +10627 0.766845703125 +10628 0.277069091796875 +10629 0.628509521484375 +10630 0.24774169921875 +10631 0.462127685546875 +10632 0.21258544921875 +10633 0.297210693359375 +10634 0.17547607421875 +10635 0.14862060546875 +10636 0.129364013671875 +10637 -0.00537109375 +10638 0.07659912109375 +10639 -0.15753173828125 +10640 0.016082763671875 +10641 -0.31304931640625 +10642 -0.056549072265625 +10643 -0.48876953125 +10644 -0.126708984375 +10645 -0.6416015625 +10646 -0.186767578125 +10647 -0.751373291015625 +10648 -0.243988037109375 +10649 -0.84619140625 +10650 -0.293853759765625 +10651 -0.861297607421875 +10652 -0.32611083984375 +10653 -0.863250732421875 +10654 -0.33099365234375 +10655 -0.856597900390625 +10656 -0.312408447265625 +10657 -0.7498779296875 +10658 -0.288482666015625 +10659 -0.624542236328125 +10660 -0.252410888671875 +10661 -0.47808837890625 +10662 -0.186004638671875 +10663 -0.253387451171875 +10664 -0.103546142578125 +10665 0.003692626953125 +10666 -0.0263671875 +10667 0.2257080078125 +10668 0.0494384765625 +10669 0.427154541015625 +10670 0.13397216796875 +10671 0.643218994140625 +10672 0.224273681640625 +10673 0.855926513671875 +10674 0.302337646484375 +10675 0.870361328125 +10676 0.352752685546875 +10677 0.870361328125 +10678 0.3778076171875 +10679 0.862762451171875 +10680 0.37664794921875 +10681 0.79669189453125 +10682 0.346405029296875 +10683 0.595794677734375 +10684 0.2962646484375 +10685 0.362152099609375 +10686 0.23504638671875 +10687 0.1270751953125 +10688 0.169403076171875 +10689 -0.086944580078125 +10690 0.10003662109375 +10691 -0.2784423828125 +10692 0.01611328125 +10693 -0.484832763671875 +10694 -0.08831787109375 +10695 -0.729583740234375 +10696 -0.19744873046875 +10697 -0.86688232421875 +10698 -0.29156494140625 +10699 -0.870391845703125 +10700 -0.369140625 +10701 -0.86859130859375 +10702 -0.429534912109375 +10703 -0.86279296875 +10704 -0.461578369140625 +10705 -0.817962646484375 +10706 -0.451171875 +10707 -0.6116943359375 +10708 -0.3961181640625 +10709 -0.3128662109375 +10710 -0.3070068359375 +10711 0.039398193359375 +10712 -0.190155029296875 +10713 0.422821044921875 +10714 -0.055999755859375 +10715 0.805145263671875 +10716 0.074127197265625 +10717 0.870361328125 +10718 0.182373046875 +10719 0.870361328125 +10720 0.2650146484375 +10721 0.860015869140625 +10722 0.319580078125 +10723 0.727935791015625 +10724 0.344268798828125 +10725 0.48114013671875 +10726 0.34661865234375 +10727 0.2059326171875 +10728 0.3336181640625 +10729 -0.06103515625 +10730 0.308349609375 +10731 -0.29913330078125 +10732 0.266326904296875 +10733 -0.516204833984375 +10734 0.20281982421875 +10735 -0.7252197265625 +10736 0.125640869140625 +10737 -0.85980224609375 +10738 0.045623779296875 +10739 -0.870391845703125 +10740 -0.027862548828125 +10741 -0.870391845703125 +10742 -0.0794677734375 +10743 -0.858062744140625 +10744 -0.10772705078125 +10745 -0.673004150390625 +10746 -0.12884521484375 +10747 -0.42694091796875 +10748 -0.156524658203125 +10749 -0.2100830078125 +10750 -0.189910888671875 +10751 -0.0362548828125 +10752 -0.22015380859375 +10753 0.10943603515625 +10754 -0.24102783203125 +10755 0.23516845703125 +10756 -0.238311767578125 +10757 0.373687744140625 +10758 -0.212554931640625 +10759 0.517791748046875 +10760 -0.185272216796875 +10761 0.602783203125 +10762 -0.154510498046875 +10763 0.635711669921875 +10764 -0.108612060546875 +10765 0.655181884765625 +10766 -0.050872802734375 +10767 0.65948486328125 +10768 0.016082763671875 +10769 0.651275634765625 +10770 0.083892822265625 +10771 0.61846923828125 +10772 0.139892578125 +10773 0.53753662109375 +10774 0.17791748046875 +10775 0.404144287109375 +10776 0.194580078125 +10777 0.22186279296875 +10778 0.1903076171875 +10779 0.003997802734375 +10780 0.1712646484375 +10781 -0.22100830078125 +10782 0.14447021484375 +10783 -0.42449951171875 +10784 0.117156982421875 +10785 -0.579833984375 +10786 0.103912353515625 +10787 -0.641876220703125 +10788 0.10235595703125 +10789 -0.6177978515625 +10790 0.090179443359375 +10791 -0.575531005859375 +10792 0.065460205078125 +10793 -0.526336669921875 +10794 0.045928955078125 +10795 -0.42645263671875 +10796 0.04095458984375 +10797 -0.2581787109375 +10798 0.037994384765625 +10799 -0.068695068359375 +10800 0.023834228515625 +10801 0.09222412109375 +10802 0.004852294921875 +10803 0.232147216796875 +10804 -0.01531982421875 +10805 0.3509521484375 +10806 -0.046844482421875 +10807 0.410064697265625 +10808 -0.099700927734375 +10809 0.372955322265625 +10810 -0.16656494140625 +10811 0.2554931640625 +10812 -0.229400634765625 +10813 0.10711669921875 +10814 -0.281341552734375 +10815 -0.052886962890625 +10816 -0.309814453125 +10817 -0.186279296875 +10818 -0.295501708984375 +10819 -0.23291015625 +10820 -0.246185302734375 +10821 -0.209442138671875 +10822 -0.184478759765625 +10823 -0.174163818359375 +10824 -0.11322021484375 +10825 -0.126739501953125 +10826 -0.029022216796875 +10827 -0.048126220703125 +10828 0.058380126953125 +10829 0.0426025390625 +10830 0.13287353515625 +10831 0.10748291015625 +10832 0.1898193359375 +10833 0.1409912109375 +10834 0.2454833984375 +10835 0.19708251953125 +10836 0.297454833984375 +10837 0.273651123046875 +10838 0.326416015625 +10839 0.31768798828125 +10840 0.336029052734375 +10841 0.341094970703125 +10842 0.33489990234375 +10843 0.368011474609375 +10844 0.31500244140625 +10845 0.37249755859375 +10846 0.259307861328125 +10847 0.30072021484375 +10848 0.16943359375 +10849 0.1517333984375 +10850 0.0682373046875 +10851 -0.01470947265625 +10852 -0.03814697265625 +10853 -0.1883544921875 +10854 -0.148284912109375 +10855 -0.372711181640625 +10856 -0.24114990234375 +10857 -0.51397705078125 +10858 -0.300506591796875 +10859 -0.57177734375 +10860 -0.322052001953125 +10861 -0.53948974609375 +10862 -0.3104248046875 +10863 -0.43511962890625 +10864 -0.2774658203125 +10865 -0.2962646484375 +10866 -0.235748291015625 +10867 -0.161102294921875 +10868 -0.190093994140625 +10869 -0.0435791015625 +10870 -0.13970947265625 +10871 0.060394287109375 +10872 -0.090484619140625 +10873 0.13665771484375 +10874 -0.049102783203125 +10875 0.170135498046875 +10876 -0.015777587890625 +10877 0.16552734375 +10878 0.019256591796875 +10879 0.15728759765625 +10880 0.055694580078125 +10881 0.150787353515625 +10882 0.083160400390625 +10883 0.12200927734375 +10884 0.102813720703125 +10885 0.080108642578125 +10886 0.12188720703125 +10887 0.05126953125 +10888 0.14837646484375 +10889 0.062896728515625 +10890 0.173583984375 +10891 0.09271240234375 +10892 0.18048095703125 +10893 0.092987060546875 +10894 0.17401123046875 +10895 0.07855224609375 +10896 0.159637451171875 +10897 0.06427001953125 +10898 0.1328125 +10899 0.0347900390625 +10900 0.093994140625 +10901 -0.01171875 +10902 0.051239013671875 +10903 -0.056060791015625 +10904 0.0208740234375 +10905 -0.055511474609375 +10906 0.0045166015625 +10907 -0.010467529296875 +10908 -0.014617919921875 +10909 0.02508544921875 +10910 -0.0435791015625 +10911 0.025665283203125 +10912 -0.0718994140625 +10913 0.017333984375 +10914 -0.09765625 +10915 0.00189208984375 +10916 -0.123687744140625 +10917 -0.03173828125 +10918 -0.145263671875 +10919 -0.071502685546875 +10920 -0.1683349609375 +10921 -0.13543701171875 +10922 -0.191802978515625 +10923 -0.219970703125 +10924 -0.207672119140625 +10925 -0.300506591796875 +10926 -0.216552734375 +10927 -0.376312255859375 +10928 -0.208770751953125 +10929 -0.416107177734375 +10930 -0.1688232421875 +10931 -0.371124267578125 +10932 -0.09844970703125 +10933 -0.242279052734375 +10934 -0.012939453125 +10935 -0.069732666015625 +10936 0.07904052734375 +10937 0.125640869140625 +10938 0.16546630859375 +10939 0.31268310546875 +10940 0.232696533203125 +10941 0.45501708984375 +10942 0.280609130859375 +10943 0.554779052734375 +10944 0.308135986328125 +10945 0.61065673828125 +10946 0.310943603515625 +10947 0.610931396484375 +10948 0.28076171875 +10949 0.531463623046875 +10950 0.223419189453125 +10951 0.3883056640625 +10952 0.157806396484375 +10953 0.23468017578125 +10954 0.093292236328125 +10955 0.095245361328125 +10956 0.039794921875 +10957 -0.00396728515625 +10958 0.00341796875 +10959 -0.04852294921875 +10960 -0.0203857421875 +10961 -0.055145263671875 +10962 -0.04833984375 +10963 -0.0758056640625 +10964 -0.0889892578125 +10965 -0.138702392578125 +10966 -0.129425048828125 +10967 -0.209197998046875 +10968 -0.16943359375 +10969 -0.289031982421875 +10970 -0.20867919921875 +10971 -0.37884521484375 +10972 -0.239166259765625 +10973 -0.456329345703125 +10974 -0.259063720703125 +10975 -0.51641845703125 +10976 -0.25482177734375 +10977 -0.519287109375 +10978 -0.22454833984375 +10979 -0.458251953125 +10980 -0.186614990234375 +10981 -0.384796142578125 +10982 -0.150299072265625 +10983 -0.323699951171875 +10984 -0.114532470703125 +10985 -0.269287109375 +10986 -0.071258544921875 +10987 -0.1951904296875 +10988 -0.02099609375 +10989 -0.100006103515625 +10990 0.026031494140625 +10991 -0.01055908203125 +10992 0.07940673828125 +10993 0.1033935546875 +10994 0.140899658203125 +10995 0.24908447265625 +10996 0.191650390625 +10997 0.373199462890625 +10998 0.2252197265625 +10999 0.45806884765625 +11000 0.244140625 +11001 0.511474609375 +11002 0.259490966796875 +11003 0.565399169921875 +11004 0.268646240234375 +11005 0.61138916015625 +11006 0.25152587890625 +11007 0.5897216796875 +11008 0.205291748046875 +11009 0.4906005859375 +11010 0.13653564453125 +11011 0.33148193359375 +11012 0.058380126953125 +11013 0.147796630859375 +11014 -0.013763427734375 +11015 -0.01873779296875 +11016 -0.069366455078125 +11017 -0.140289306640625 +11018 -0.099029541015625 +11019 -0.191986083984375 +11020 -0.1058349609375 +11021 -0.184295654296875 +11022 -0.104888916015625 +11023 -0.161834716796875 +11024 -0.110595703125 +11025 -0.166595458984375 +11026 -0.1212158203125 +11027 -0.19390869140625 +11028 -0.1300048828125 +11029 -0.22442626953125 +11030 -0.144683837890625 +11031 -0.279754638671875 +11032 -0.158294677734375 +11033 -0.3389892578125 +11034 -0.154571533203125 +11035 -0.3543701171875 +11036 -0.141876220703125 +11037 -0.348175048828125 +11038 -0.122772216796875 +11039 -0.32598876953125 +11040 -0.0875244140625 +11041 -0.2581787109375 +11042 -0.035064697265625 +11043 -0.139801025390625 +11044 0.0289306640625 +11045 0.014617919921875 +11046 0.08270263671875 +11047 0.144378662109375 +11048 0.115875244140625 +11049 0.221038818359375 +11050 0.137298583984375 +11051 0.27069091796875 +11052 0.1470947265625 +11053 0.294036865234375 +11054 0.1524658203125 +11055 0.311767578125 +11056 0.15899658203125 +11057 0.339141845703125 +11058 0.161651611328125 +11059 0.360260009765625 +11060 0.155548095703125 +11061 0.360504150390625 +11062 0.129058837890625 +11063 0.308380126953125 +11064 0.07415771484375 +11065 0.18170166015625 +11066 0.0003662109375 +11067 0.0047607421875 +11068 -0.0743408203125 +11069 -0.17559814453125 +11070 -0.132720947265625 +11071 -0.3143310546875 +11072 -0.158111572265625 +11073 -0.36785888671875 +11074 -0.160125732421875 +11075 -0.36248779296875 +11076 -0.1556396484375 +11077 -0.343536376953125 +11078 -0.141143798828125 +11079 -0.3018798828125 +11080 -0.114288330078125 +11081 -0.231414794921875 +11082 -0.0697021484375 +11083 -0.117645263671875 +11084 -0.019683837890625 +11085 0.007049560546875 +11086 0.01495361328125 +11087 0.087982177734375 +11088 0.03936767578125 +11089 0.13946533203125 +11090 0.058074951171875 +11091 0.17425537109375 +11092 0.069183349609375 +11093 0.188201904296875 +11094 0.068572998046875 +11095 0.171234130859375 +11096 0.054107666015625 +11097 0.118438720703125 +11098 0.035736083984375 +11099 0.05706787109375 +11100 0.0140380859375 +11101 -0.010711669921875 +11102 -0.013580322265625 +11103 -0.0914306640625 +11104 -0.0386962890625 +11105 -0.162322998046875 +11106 -0.050537109375 +11107 -0.194549560546875 +11108 -0.03448486328125 +11109 -0.1492919921875 +11110 0.011383056640625 +11111 -0.02166748046875 +11112 0.06304931640625 +11113 0.124053955078125 +11114 0.09185791015625 +11115 0.211151123046875 +11116 0.098358154296875 +11117 0.240447998046875 +11118 0.09417724609375 +11119 0.242218017578125 +11120 0.083099365234375 +11121 0.2257080078125 +11122 0.066680908203125 +11123 0.194366455078125 +11124 0.03289794921875 +11125 0.115509033203125 +11126 -0.00909423828125 +11127 0.0128173828125 +11128 -0.03662109375 +11129 -0.053802490234375 +11130 -0.0594482421875 +11131 -0.110626220703125 +11132 -0.093292236328125 +11133 -0.199493408203125 +11134 -0.128387451171875 +11135 -0.29437255859375 +11136 -0.14105224609375 +11137 -0.33221435546875 +11138 -0.118896484375 +11139 -0.27972412109375 +11140 -0.080291748046875 +11141 -0.185333251953125 +11142 -0.055206298828125 +11143 -0.128204345703125 +11144 -0.04656982421875 +11145 -0.115692138671875 +11146 -0.0428466796875 +11147 -0.116455078125 +11148 -0.0350341796875 +11149 -0.105926513671875 +11150 -0.011993408203125 +11151 -0.053955078125 +11152 0.029571533203125 +11153 0.048797607421875 +11154 0.072601318359375 +11155 0.157318115234375 +11156 0.0946044921875 +11157 0.212005615234375 +11158 0.097625732421875 +11159 0.218475341796875 +11160 0.104400634765625 +11161 0.23724365234375 +11162 0.12890625 +11163 0.30535888671875 +11164 0.155609130859375 +11165 0.38128662109375 +11166 0.161865234375 +11167 0.404449462890625 +11168 0.1551513671875 +11169 0.3944091796875 +11170 0.14971923828125 +11171 0.3885498046875 +11172 0.136627197265625 +11173 0.362640380859375 +11174 0.099884033203125 +11175 0.27362060546875 +11176 0.038055419921875 +11177 0.11712646484375 +11178 -0.0291748046875 +11179 -0.054901123046875 +11180 -0.082275390625 +11181 -0.19085693359375 +11182 -0.1192626953125 +11183 -0.28570556640625 +11184 -0.1400146484375 +11185 -0.339263916015625 +11186 -0.154327392578125 +11187 -0.3775634765625 +11188 -0.179168701171875 +11189 -0.445709228515625 +11190 -0.21136474609375 +11191 -0.535064697265625 +11192 -0.2447509765625 +11193 -0.629058837890625 +11194 -0.26812744140625 +11195 -0.697601318359375 +11196 -0.267852783203125 +11197 -0.70391845703125 +11198 -0.241973876953125 +11199 -0.6424560546875 +11200 -0.182373046875 +11201 -0.491241455078125 +11202 -0.09503173828125 +11203 -0.265716552734375 +11204 -0.0018310546875 +11205 -0.023712158203125 +11206 0.084686279296875 +11207 0.201751708984375 +11208 0.151336669921875 +11209 0.375823974609375 +11210 0.193023681640625 +11211 0.485076904296875 +11212 0.22454833984375 +11213 0.56884765625 +11214 0.248779296875 +11215 0.634765625 +11216 0.248779296875 +11217 0.63763427734375 +11218 0.2203369140625 +11219 0.5660400390625 +11220 0.18310546875 +11221 0.4720458984375 +11222 0.156463623046875 +11223 0.40692138671875 +11224 0.143218994140625 +11225 0.3778076171875 +11226 0.140625 +11227 0.376953125 +11228 0.136627197265625 +11229 0.371978759765625 +11230 0.11260986328125 +11231 0.313140869140625 +11232 0.0626220703125 +11233 0.184417724609375 +11234 -0.003662109375 +11235 0.011199951171875 +11236 -0.07281494140625 +11237 -0.171051025390625 +11238 -0.135467529296875 +11239 -0.33740234375 +11240 -0.1856689453125 +11241 -0.47198486328125 +11242 -0.218048095703125 +11243 -0.560394287109375 +11244 -0.224365234375 +11245 -0.58056640625 +11246 -0.21038818359375 +11247 -0.54754638671875 +11248 -0.1939697265625 +11249 -0.508575439453125 +11250 -0.17364501953125 +11251 -0.459503173828125 +11252 -0.14727783203125 +11253 -0.394378662109375 +11254 -0.1297607421875 +11255 -0.35260009765625 +11256 -0.112762451171875 +11257 -0.31170654296875 +11258 -0.06842041015625 +11259 -0.197418212890625 +11260 0.003814697265625 +11261 -0.007965087890625 +11262 0.08538818359375 +11263 0.207489013671875 +11264 0.161407470703125 +11265 0.409210205078125 +11266 0.2230224609375 +11267 0.57208251953125 +11268 0.25848388671875 +11269 0.66595458984375 +11270 0.254425048828125 +11271 0.65875244140625 +11272 0.2174072265625 +11273 0.56744384765625 +11274 0.1632080078125 +11275 0.431396484375 +11276 0.109405517578125 +11277 0.29443359375 +11278 0.066314697265625 +11279 0.182464599609375 +11280 0.020721435546875 +11281 0.06365966796875 +11282 -0.03326416015625 +11283 -0.075958251953125 +11284 -0.07666015625 +11285 -0.189422607421875 +11286 -0.107696533203125 +11287 -0.271942138671875 +11288 -0.134246826171875 +11289 -0.342529296875 +11290 -0.141326904296875 +11291 -0.364166259765625 +11292 -0.12506103515625 +11293 -0.327239990234375 +11294 -0.10394287109375 +11295 -0.2769775390625 +11296 -0.094390869140625 +11297 -0.253692626953125 +11298 -0.09075927734375 +11299 -0.24365234375 +11300 -0.073211669921875 +11301 -0.1983642578125 +11302 -0.041015625 +11303 -0.116241455078125 +11304 -0.010223388671875 +11305 -0.036834716796875 +11306 0.0172119140625 +11307 0.034881591796875 +11308 0.03826904296875 +11309 0.09124755859375 +11310 0.043548583984375 +11311 0.10888671875 +11312 0.04852294921875 +11313 0.125518798828125 +11314 0.06005859375 +11315 0.15771484375 +11316 0.067138671875 +11317 0.17828369140625 +11318 0.063232421875 +11319 0.17108154296875 +11320 0.0458984375 +11321 0.129974365234375 +11322 0.026336669921875 +11323 0.082427978515625 +11324 0.004241943359375 +11325 0.027679443359375 +11326 -0.033172607421875 +11327 -0.065643310546875 +11328 -0.070404052734375 +11329 -0.15936279296875 +11330 -0.091033935546875 +11331 -0.21307373046875 +11332 -0.09832763671875 +11333 -0.234649658203125 +11334 -0.0826416015625 +11335 -0.2001953125 +11336 -0.047943115234375 +11337 -0.119171142578125 +11338 -0.00787353515625 +11339 -0.024749755859375 +11340 0.038604736328125 +11341 0.085784912109375 +11342 0.077392578125 +11343 0.178131103515625 +11344 0.093505859375 +11345 0.215576171875 +11346 0.09234619140625 +11347 0.211456298828125 +11348 0.0777587890625 +11349 0.17523193359375 +11350 0.05865478515625 +11351 0.128753662109375 +11352 0.0472412109375 +11353 0.1019287109375 +11354 0.035247802734375 +11355 0.0743408203125 +11356 0.021575927734375 +11357 0.04327392578125 +11358 0.018310546875 +11359 0.038177490234375 +11360 0.03253173828125 +11361 0.076263427734375 +11362 0.057586669921875 +11363 0.14105224609375 +11364 0.074737548828125 +11365 0.186431884765625 +11366 0.074432373046875 +11367 0.188812255859375 +11368 0.053009033203125 +11369 0.1390380859375 +11370 0.012451171875 +11371 0.041778564453125 +11372 -0.03759765625 +11373 -0.079437255859375 +11374 -0.095001220703125 +11375 -0.219390869140625 +11376 -0.155517578125 +11377 -0.367828369140625 +11378 -0.20697021484375 +11379 -0.494873046875 +11380 -0.2313232421875 +11381 -0.556243896484375 +11382 -0.21099853515625 +11383 -0.508697509765625 +11384 -0.15557861328125 +11385 -0.3756103515625 +11386 -0.090423583984375 +11387 -0.218902587890625 +11388 -0.025848388671875 +11389 -0.063751220703125 +11390 0.038726806640625 +11391 0.091552734375 +11392 0.0987548828125 +11393 0.23602294921875 +11394 0.143310546875 +11395 0.342987060546875 +11396 0.165313720703125 +11397 0.39520263671875 +11398 0.16339111328125 +11399 0.389373779296875 +11400 0.13702392578125 +11401 0.324249267578125 +11402 0.096099853515625 +11403 0.224090576171875 +11404 0.055084228515625 +11405 0.124267578125 +11406 0.01898193359375 +11407 0.037078857421875 +11408 -0.0009765625 +11409 -0.010101318359375 +11410 -0.005615234375 +11411 -0.019439697265625 +11412 -0.00787353515625 +11413 -0.022796630859375 +11414 -0.000152587890625 +11415 -0.001556396484375 +11416 0.022491455078125 +11417 0.056304931640625 +11418 0.042144775390625 +11419 0.106719970703125 +11420 0.037353515625 +11421 0.096893310546875 +11422 0.014617919921875 +11423 0.042694091796875 +11424 -0.010589599609375 +11425 -0.018035888671875 +11426 -0.034393310546875 +11427 -0.07586669921875 +11428 -0.052154541015625 +11429 -0.11944580078125 +11430 -0.068359375 +11431 -0.15972900390625 +11432 -0.08544921875 +11433 -0.202606201171875 +11434 -0.103607177734375 +11435 -0.24859619140625 +11436 -0.125946044921875 +11437 -0.30517578125 +11438 -0.14837646484375 +11439 -0.36212158203125 +11440 -0.159515380859375 +11441 -0.39141845703125 +11442 -0.143951416015625 +11443 -0.35528564453125 +11444 -0.1002197265625 +11445 -0.249969482421875 +11446 -0.03546142578125 +11447 -0.092864990234375 +11448 0.03924560546875 +11449 0.08905029296875 +11450 0.09918212890625 +11451 0.2352294921875 +11452 0.133392333984375 +11453 0.318817138671875 +11454 0.149566650390625 +11455 0.358642578125 +11456 0.144866943359375 +11457 0.347747802734375 +11458 0.119110107421875 +11459 0.28564453125 +11460 0.09307861328125 +11461 0.223175048828125 +11462 0.0816650390625 +11463 0.196746826171875 +11464 0.0740966796875 +11465 0.179840087890625 +11466 0.0634765625 +11467 0.155548095703125 +11468 0.06103515625 +11469 0.151214599609375 +11470 0.062744140625 +11471 0.156951904296875 +11472 0.051910400390625 +11473 0.13177490234375 +11474 0.038818359375 +11475 0.100799560546875 +11476 0.032928466796875 +11477 0.087127685546875 +11478 0.019622802734375 +11479 0.05487060546875 +11480 -0.00640869140625 +11481 -0.009002685546875 +11482 -0.044952392578125 +11483 -0.10400390625 +11484 -0.095733642578125 +11485 -0.229400634765625 +11486 -0.146728515625 +11487 -0.35552978515625 +11488 -0.181396484375 +11489 -0.441925048828125 +11490 -0.19378662109375 +11491 -0.473846435546875 +11492 -0.189453125 +11493 -0.464813232421875 +11494 -0.170166015625 +11495 -0.419097900390625 +11496 -0.134979248046875 +11497 -0.334320068359375 +11498 -0.091033935546875 +11499 -0.227935791015625 +11500 -0.0479736328125 +11501 -0.12347412109375 +11502 -0.008575439453125 +11503 -0.02764892578125 +11504 0.0345458984375 +11505 0.077667236328125 +11506 0.08984375 +11507 0.2132568359375 +11508 0.161285400390625 +11509 0.38885498046875 +11510 0.240081787109375 +11511 0.582794189453125 +11512 0.30133056640625 +11513 0.734039306640625 +11514 0.3277587890625 +11515 0.800140380859375 +11516 0.3182373046875 +11517 0.7783203125 +11518 0.27142333984375 +11519 0.6651611328125 +11520 0.186492919921875 +11521 0.45965576171875 +11522 0.078155517578125 +11523 0.199188232421875 +11524 -0.025848388671875 +11525 -0.050689697265625 +11526 -0.100555419921875 +11527 -0.23297119140625 +11528 -0.138427734375 +11529 -0.33013916015625 +11530 -0.151123046875 +11531 -0.368408203125 +11532 -0.1524658203125 +11533 -0.378936767578125 +11534 -0.149261474609375 +11535 -0.376983642578125 +11536 -0.149078369140625 +11537 -0.37969970703125 +11538 -0.153900146484375 +11539 -0.391510009765625 +11540 -0.151763916015625 +11541 -0.385345458984375 +11542 -0.134124755859375 +11543 -0.3419189453125 +11544 -0.110382080078125 +11545 -0.28289794921875 +11546 -0.099456787109375 +11547 -0.251617431640625 +11548 -0.109130859375 +11549 -0.266143798828125 +11550 -0.115875244140625 +11551 -0.273345947265625 +11552 -0.09466552734375 +11553 -0.216796875 +11554 -0.05926513671875 +11555 -0.128265380859375 +11556 -0.03607177734375 +11557 -0.068145751953125 +11558 -0.027862548828125 +11559 -0.0430908203125 +11560 -0.021881103515625 +11561 -0.024444580078125 +11562 -0.003509521484375 +11563 0.020721435546875 +11564 0.0413818359375 +11565 0.124481201171875 +11566 0.100067138671875 +11567 0.25787353515625 +11568 0.15411376953125 +11569 0.379119873046875 +11570 0.1998291015625 +11571 0.47991943359375 +11572 0.2230224609375 +11573 0.5281982421875 +11574 0.2178955078125 +11575 0.511138916015625 +11576 0.1964111328125 +11577 0.456207275390625 +11578 0.17779541015625 +11579 0.407470703125 +11580 0.170196533203125 +11581 0.383758544921875 +11582 0.161041259765625 +11583 0.35687255859375 +11584 0.143585205078125 +11585 0.31182861328125 +11586 0.11871337890625 +11587 0.250885009765625 +11588 0.082550048828125 +11589 0.1654052734375 +11590 0.026153564453125 +11591 0.035247802734375 +11592 -0.05157470703125 +11593 -0.142059326171875 +11594 -0.137054443359375 +11595 -0.33563232421875 +11596 -0.225433349609375 +11597 -0.5345458984375 +11598 -0.3092041015625 +11599 -0.72186279296875 +11600 -0.3614501953125 +11601 -0.836669921875 +11602 -0.3616943359375 +11603 -0.8326416015625 +11604 -0.31854248046875 +11605 -0.7296142578125 +11606 -0.256103515625 +11607 -0.582550048828125 +11608 -0.19561767578125 +11609 -0.440093994140625 +11610 -0.14666748046875 +11611 -0.324310302734375 +11612 -0.094329833984375 +11613 -0.20147705078125 +11614 -0.026641845703125 +11615 -0.044647216796875 +11616 0.037841796875 +11617 0.103973388671875 +11618 0.0806884765625 +11619 0.202392578125 +11620 0.1080322265625 +11621 0.264495849609375 +11622 0.1412353515625 +11623 0.338897705078125 +11624 0.188262939453125 +11625 0.443817138671875 +11626 0.234039306640625 +11627 0.545074462890625 +11628 0.267303466796875 +11629 0.6173095703125 +11630 0.284454345703125 +11631 0.6524658203125 +11632 0.291046142578125 +11633 0.66339111328125 +11634 0.28961181640625 +11635 0.6561279296875 +11636 0.269561767578125 +11637 0.606781005859375 +11638 0.224578857421875 +11639 0.501190185546875 +11640 0.16046142578125 +11641 0.352783203125 +11642 0.083770751953125 +11643 0.176544189453125 +11644 -0.00872802734375 +11645 -0.034820556640625 +11646 -0.106842041015625 +11647 -0.258209228515625 +11648 -0.188079833984375 +11649 -0.44244384765625 +11650 -0.247039794921875 +11651 -0.5753173828125 +11652 -0.281585693359375 +11653 -0.65203857421875 +11654 -0.278045654296875 +11655 -0.641632080078125 +11656 -0.24432373046875 +11657 -0.562164306640625 +11658 -0.19989013671875 +11659 -0.458038330078125 +11660 -0.154022216796875 +11661 -0.350555419921875 +11662 -0.11578369140625 +11663 -0.260528564453125 +11664 -0.086944580078125 +11665 -0.192108154296875 +11666 -0.065948486328125 +11667 -0.141937255859375 +11668 -0.049285888671875 +11669 -0.1021728515625 +11670 -0.0325927734375 +11671 -0.062896728515625 +11672 -0.01043701171875 +11673 -0.011932373046875 +11674 0.0224609375 +11675 0.062835693359375 +11676 0.060546875 +11677 0.148712158203125 +11678 0.10205078125 +11679 0.241729736328125 +11680 0.15008544921875 +11681 0.34912109375 +11682 0.198638916015625 +11683 0.457305908203125 +11684 0.237823486328125 +11685 0.54388427734375 +11686 0.251739501953125 +11687 0.5728759765625 +11688 0.223724365234375 +11689 0.506591796875 +11690 0.15643310546875 +11691 0.351226806640625 +11692 0.067291259765625 +11693 0.146514892578125 +11694 -0.02069091796875 +11695 -0.05523681640625 +11696 -0.0909423828125 +11697 -0.21624755859375 +11698 -0.142791748046875 +11699 -0.334930419921875 +11700 -0.172576904296875 +11701 -0.402984619140625 +11702 -0.18951416015625 +11703 -0.4412841796875 +11704 -0.21380615234375 +11705 -0.49578857421875 +11706 -0.242645263671875 +11707 -0.5601806640625 +11708 -0.26116943359375 +11709 -0.600738525390625 +11710 -0.254730224609375 +11711 -0.584228515625 +11712 -0.20947265625 +11713 -0.47930908203125 +11714 -0.1224365234375 +11715 -0.27935791015625 +11716 -0.00439453125 +11717 -0.0089111328125 +11718 0.11688232421875 +11719 0.268798828125 +11720 0.210235595703125 +11721 0.482818603515625 +11722 0.26275634765625 +11723 0.60369873046875 +11724 0.282806396484375 +11725 0.650421142578125 +11726 0.2884521484375 +11727 0.66400146484375 +11728 0.278411865234375 +11729 0.6414794921875 +11730 0.248138427734375 +11731 0.572540283203125 +11732 0.21563720703125 +11733 0.498138427734375 +11734 0.190277099609375 +11735 0.439453125 +11736 0.16278076171875 +11737 0.375518798828125 +11738 0.11907958984375 +11739 0.274505615234375 +11740 0.046966552734375 +11741 0.1087646484375 +11742 -0.04376220703125 +11743 -0.099395751953125 +11744 -0.139190673828125 +11745 -0.3182373046875 +11746 -0.239898681640625 +11747 -0.5489501953125 +11748 -0.338104248046875 +11749 -0.7738037109375 +11750 -0.410552978515625 +11751 -0.86383056640625 +11752 -0.442657470703125 +11753 -0.870391845703125 +11754 -0.442230224609375 +11755 -0.86895751953125 +11756 -0.4150390625 +11757 -0.861053466796875 +11758 -0.353485107421875 +11759 -0.765869140625 +11760 -0.252593994140625 +11761 -0.5301513671875 +11762 -0.115509033203125 +11763 -0.214691162109375 +11764 0.038848876953125 +11765 0.137359619140625 +11766 0.187957763671875 +11767 0.474822998046875 +11768 0.316253662109375 +11769 0.76239013671875 +11770 0.411865234375 +11771 0.867462158203125 +11772 0.47503662109375 +11773 0.870361328125 +11774 0.500701904296875 +11775 0.86480712890625 +11776 0.491455078125 +11777 0.831817626953125 +11778 0.4581298828125 +11779 0.677581787109375 +11780 0.403228759765625 +11781 0.495880126953125 +11782 0.335205078125 +11783 0.30767822265625 +11784 0.254730224609375 +11785 0.116180419921875 +11786 0.1463623046875 +11787 -0.110748291015625 +11788 0.006378173828125 +11789 -0.381805419921875 +11790 -0.145477294921875 +11791 -0.6572265625 +11792 -0.2813720703125 +11793 -0.857421875 +11794 -0.381439208984375 +11795 -0.870391845703125 +11796 -0.442657470703125 +11797 -0.870391845703125 +11798 -0.47796630859375 +11799 -0.86444091796875 +11800 -0.504364013671875 +11801 -0.85723876953125 +11802 -0.51324462890625 +11803 -0.790008544921875 +11804 -0.47894287109375 +11805 -0.62847900390625 +11806 -0.399810791015625 +11807 -0.3956298828125 +11808 -0.2911376953125 +11809 -0.126708984375 +11810 -0.16558837890625 +11811 0.150115966796875 +11812 -0.0283203125 +11813 0.424041748046875 +11814 0.1082763671875 +11815 0.670623779296875 +11816 0.22625732421875 +11817 0.854522705078125 +11818 0.317657470703125 +11819 0.866485595703125 +11820 0.375518798828125 +11821 0.86920166015625 +11822 0.40869140625 +11823 0.8653564453125 +11824 0.423736572265625 +11825 0.857147216796875 +11826 0.419403076171875 +11827 0.766845703125 +11828 0.398223876953125 +11829 0.628509521484375 +11830 0.35699462890625 +11831 0.462127685546875 +11832 0.307830810546875 +11833 0.297210693359375 +11834 0.25640869140625 +11835 0.14862060546875 +11836 0.19171142578125 +11837 -0.00537109375 +11838 0.1170654296875 +11839 -0.15753173828125 +11840 0.03045654296875 +11841 -0.31304931640625 +11842 -0.07501220703125 +11843 -0.48876953125 +11844 -0.177490234375 +11845 -0.6416015625 +11846 -0.26556396484375 +11847 -0.751373291015625 +11848 -0.35040283203125 +11849 -0.84619140625 +11850 -0.42523193359375 +11851 -0.861297607421875 +11852 -0.474517822265625 +11853 -0.863250732421875 +11854 -0.483428955078125 +11855 -0.856597900390625 +11856 -0.457733154296875 +11857 -0.7498779296875 +11858 -0.424713134765625 +11859 -0.624542236328125 +11860 -0.373870849609375 +11861 -0.47808837890625 +11862 -0.2774658203125 +11863 -0.253387451171875 +11864 -0.1568603515625 +11865 0.003692626953125 +11866 -0.044097900390625 +11867 0.2257080078125 +11868 0.066925048828125 +11869 0.427154541015625 +11870 0.19171142578125 +11871 0.643218994140625 +11872 0.325958251953125 +11873 0.855926513671875 +11874 0.4425048828125 +11875 0.870361328125 +11876 0.51806640625 +11877 0.870361328125 +11878 0.556121826171875 +11879 0.862762451171875 +11880 0.555389404296875 +11881 0.79669189453125 +11882 0.511444091796875 +11883 0.595794677734375 +11884 0.43804931640625 +11885 0.362152099609375 +11886 0.348358154296875 +11887 0.1270751953125 +11888 0.252288818359375 +11889 -0.086944580078125 +11890 0.15069580078125 +11891 -0.2784423828125 +11892 0.0269775390625 +11893 -0.484832763671875 +11894 -0.128021240234375 +11895 -0.729583740234375 +11896 -0.29058837890625 +11897 -0.86688232421875 +11898 -0.43096923828125 +11899 -0.870391845703125 +11900 -0.54693603515625 +11901 -0.86859130859375 +11902 -0.637603759765625 +11903 -0.86279296875 +11904 -0.686065673828125 +11905 -0.817962646484375 +11906 -0.67095947265625 +11907 -0.6116943359375 +11908 -0.588958740234375 +11909 -0.3128662109375 +11910 -0.455963134765625 +11911 0.039398193359375 +11912 -0.281402587890625 +11913 0.422821044921875 +11914 -0.0809326171875 +11915 0.805145263671875 +11916 0.113311767578125 +11917 0.870361328125 +11918 0.27447509765625 +11919 0.870361328125 +11920 0.3970947265625 +11921 0.860015869140625 +11922 0.4775390625 +11923 0.727935791015625 +11924 0.51318359375 +11925 0.48114013671875 +11926 0.51544189453125 +11927 0.2059326171875 +11928 0.4949951171875 +11929 -0.06103515625 +11930 0.456573486328125 +11931 -0.29913330078125 +11932 0.393341064453125 +11933 -0.516204833984375 +11934 0.298095703125 +11935 -0.7252197265625 +11936 0.1826171875 +11937 -0.85980224609375 +11938 0.06317138671875 +11939 -0.870391845703125 +11940 -0.046173095703125 +11941 -0.870391845703125 +11942 -0.122283935546875 +11943 -0.858062744140625 +11944 -0.16302490234375 +11945 -0.673004150390625 +11946 -0.193023681640625 +11947 -0.42694091796875 +11948 -0.23309326171875 +11949 -0.2100830078125 +11950 -0.282073974609375 +11951 -0.0362548828125 +11952 -0.32611083984375 +11953 0.10943603515625 +11954 -0.355712890625 +11955 0.23516845703125 +11956 -0.35125732421875 +11957 0.373687744140625 +11958 -0.3135986328125 +11959 0.517791748046875 +11960 -0.272491455078125 +11961 0.602783203125 +11962 -0.225616455078125 +11963 0.635711669921875 +11964 -0.157318115234375 +11965 0.655181884765625 +11966 -0.072418212890625 +11967 0.65948486328125 +11968 0.02508544921875 +11969 0.651275634765625 +11970 0.12347412109375 +11971 0.61846923828125 +11972 0.205047607421875 +11973 0.53753662109375 +11974 0.26104736328125 +11975 0.404144287109375 +11976 0.286712646484375 +11977 0.22186279296875 +11978 0.282470703125 +11979 0.003997802734375 +11980 0.2567138671875 +11981 -0.22100830078125 +11982 0.2191162109375 +11983 -0.42449951171875 +11984 0.179718017578125 +11985 -0.579833984375 +11986 0.158660888671875 +11987 -0.641876220703125 +11988 0.152862548828125 +11989 -0.6177978515625 +11990 0.13189697265625 +11991 -0.575531005859375 +11992 0.0933837890625 +11993 -0.526336669921875 +11994 0.0618896484375 +11995 -0.42645263671875 +11996 0.050567626953125 +11997 -0.2581787109375 +11998 0.042449951171875 +11999 -0.068695068359375 +12000 0.01959228515625 +12001 0.09222412109375 +12002 -0.009033203125 +12003 0.232147216796875 +12004 -0.03839111328125 +12005 0.3509521484375 +12006 -0.082305908203125 +12007 0.410064697265625 +12008 -0.154510498046875 +12009 0.372955322265625 +12010 -0.245025634765625 +12011 0.2554931640625 +12012 -0.32916259765625 +12013 0.10711669921875 +12014 -0.39764404296875 +12015 -0.052886962890625 +12016 -0.43341064453125 +12017 -0.186279296875 +12018 -0.410186767578125 +12019 -0.23291015625 +12020 -0.338775634765625 +12021 -0.209442138671875 +12022 -0.250457763671875 +12023 -0.174163818359375 +12024 -0.149261474609375 +12025 -0.126739501953125 +12026 -0.030731201171875 +12027 -0.048126220703125 +12028 0.09161376953125 +12029 0.0426025390625 +12030 0.195556640625 +12031 0.10748291015625 +12032 0.275177001953125 +12033 0.1409912109375 +12034 0.353485107421875 +12035 0.19708251953125 +12036 0.426361083984375 +12037 0.273651123046875 +12038 0.4659423828125 +12039 0.31768798828125 +12040 0.477813720703125 +12041 0.341094970703125 +12042 0.474609375 +12043 0.368011474609375 +12044 0.444793701171875 +12045 0.37249755859375 +12046 0.363677978515625 +12047 0.30072021484375 +12048 0.233612060546875 +12049 0.1517333984375 +12050 0.087799072265625 +12051 -0.01470947265625 +12052 -0.064971923828125 +12053 -0.1883544921875 +12054 -0.222747802734375 +12055 -0.372711181640625 +12056 -0.355072021484375 +12057 -0.51397705078125 +12058 -0.4384765625 +12059 -0.57177734375 +12060 -0.466888427734375 +12061 -0.53948974609375 +12062 -0.44720458984375 +12063 -0.43511962890625 +12064 -0.39678955078125 +12065 -0.2962646484375 +12066 -0.334075927734375 +12067 -0.161102294921875 +12068 -0.266204833984375 +12069 -0.0435791015625 +12070 -0.192047119140625 +12071 0.060394287109375 +12072 -0.1202392578125 +12073 0.13665771484375 +12074 -0.060455322265625 +12075 0.170135498046875 +12076 -0.012969970703125 +12077 0.16552734375 +12078 0.0364990234375 +12079 0.15728759765625 +12080 0.08758544921875 +12081 0.150787353515625 +12082 0.12530517578125 +12083 0.12200927734375 +12084 0.151458740234375 +12085 0.080108642578125 +12086 0.17669677734375 +12087 0.05126953125 +12088 0.21282958984375 +12089 0.062896728515625 +12090 0.247283935546875 +12091 0.09271240234375 +12092 0.255462646484375 +12093 0.092987060546875 +12094 0.244659423828125 +12095 0.07855224609375 +12096 0.22283935546875 +12097 0.06427001953125 +12098 0.183441162109375 +12099 0.0347900390625 +12100 0.127166748046875 +12101 -0.01171875 +12102 0.065673828125 +12103 -0.056060791015625 +12104 0.022613525390625 +12105 -0.055511474609375 +12106 0.00030517578125 +12107 -0.010467529296875 +12108 -0.025726318359375 +12109 0.02508544921875 +12110 -0.06585693359375 +12111 0.025665283203125 +12112 -0.104949951171875 +12113 0.017333984375 +12114 -0.140380859375 +12115 0.00189208984375 +12116 -0.176361083984375 +12117 -0.03173828125 +12118 -0.20611572265625 +12119 -0.071502685546875 +12120 -0.238372802734375 +12121 -0.13543701171875 +12122 -0.2716064453125 +12123 -0.219970703125 +12124 -0.29425048828125 +12125 -0.300506591796875 +12126 -0.307159423828125 +12127 -0.376312255859375 +12128 -0.296234130859375 +12129 -0.416107177734375 +12130 -0.238983154296875 +12131 -0.371124267578125 +12132 -0.13787841796875 +12133 -0.242279052734375 +12134 -0.015045166015625 +12135 -0.069732666015625 +12136 0.117034912109375 +12137 0.125640869140625 +12138 0.240997314453125 +12139 0.31268310546875 +12140 0.33709716796875 +12141 0.45501708984375 +12142 0.40521240234375 +12143 0.554779052734375 +12144 0.443878173828125 +12145 0.61065673828125 +12146 0.4468994140625 +12147 0.610931396484375 +12148 0.40228271484375 +12149 0.531463623046875 +12150 0.318511962890625 +12151 0.3883056640625 +12152 0.22308349609375 +12153 0.23468017578125 +12154 0.12957763671875 +12155 0.095245361328125 +12156 0.052398681640625 +12157 -0.00396728515625 +12158 0.0003662109375 +12159 -0.04852294921875 +12160 -0.033172607421875 +12161 -0.055145263671875 +12162 -0.07257080078125 +12163 -0.0758056640625 +12164 -0.130340576171875 +12165 -0.138702392578125 +12166 -0.187835693359375 +12167 -0.209197998046875 +12168 -0.24481201171875 +12169 -0.289031982421875 +12170 -0.300811767578125 +12171 -0.37884521484375 +12172 -0.34423828125 +12173 -0.456329345703125 +12174 -0.37249755859375 +12175 -0.51641845703125 +12176 -0.365966796875 +12177 -0.519287109375 +12178 -0.321868896484375 +12179 -0.458251953125 +12180 -0.26690673828125 +12181 -0.384796142578125 +12182 -0.21453857421875 +12183 -0.323699951171875 +12184 -0.163238525390625 +12185 -0.269287109375 +12186 -0.101226806640625 +12187 -0.1951904296875 +12188 -0.0291748046875 +12189 -0.100006103515625 +12190 0.03814697265625 +12191 -0.01055908203125 +12192 0.11468505859375 +12193 0.1033935546875 +12194 0.203094482421875 +12195 0.24908447265625 +12196 0.275970458984375 +12197 0.373199462890625 +12198 0.32403564453125 +12199 0.45806884765625 +12200 0.35101318359375 +12201 0.511474609375 +12202 0.373077392578125 +12203 0.565399169921875 +12204 0.386383056640625 +12205 0.61138916015625 +12206 0.36175537109375 +12207 0.5897216796875 +12208 0.295135498046875 +12209 0.4906005859375 +12210 0.196319580078125 +12211 0.33148193359375 +12212 0.0841064453125 +12213 0.147796630859375 +12214 -0.019500732421875 +12215 -0.01873779296875 +12216 -0.0994873046875 +12217 -0.140289306640625 +12218 -0.14239501953125 +12219 -0.191986083984375 +12220 -0.152587890625 +12221 -0.184295654296875 +12222 -0.15167236328125 +12223 -0.161834716796875 +12224 -0.160186767578125 +12225 -0.166595458984375 +12226 -0.17559814453125 +12227 -0.19390869140625 +12228 -0.188262939453125 +12229 -0.22442626953125 +12230 -0.209259033203125 +12231 -0.279754638671875 +12232 -0.228607177734375 +12233 -0.3389892578125 +12234 -0.223114013671875 +12235 -0.3543701171875 +12236 -0.204681396484375 +12237 -0.348175048828125 +12238 -0.176971435546875 +12239 -0.32598876953125 +12240 -0.12615966796875 +12241 -0.2581787109375 +12242 -0.050689697265625 +12243 -0.139801025390625 +12244 0.041290283203125 +12245 0.014617919921875 +12246 0.11865234375 +12247 0.144378662109375 +12248 0.16656494140625 +12249 0.221038818359375 +12250 0.1976318359375 +12251 0.27069091796875 +12252 0.21197509765625 +12253 0.294036865234375 +12254 0.21990966796875 +12255 0.311767578125 +12256 0.229217529296875 +12257 0.339141845703125 +12258 0.23236083984375 +12259 0.360260009765625 +12260 0.222503662109375 +12261 0.360504150390625 +12262 0.184326171875 +12263 0.308380126953125 +12264 0.10736083984375 +12265 0.18170166015625 +12266 0.004638671875 +12267 0.0047607421875 +12268 -0.099517822265625 +12269 -0.17559814453125 +12270 -0.18170166015625 +12271 -0.3143310546875 +12272 -0.21929931640625 +12273 -0.36785888671875 +12274 -0.225067138671875 +12275 -0.36248779296875 +12276 -0.221435546875 +12277 -0.343536376953125 +12278 -0.20355224609375 +12279 -0.3018798828125 +12280 -0.16827392578125 +12281 -0.231414794921875 +12282 -0.10833740234375 +12283 -0.117645263671875 +12284 -0.040283203125 +12285 0.007049560546875 +12286 0.007965087890625 +12287 0.087982177734375 +12288 0.0430908203125 +12289 0.13946533203125 +12290 0.071014404296875 +12291 0.17425537109375 +12292 0.089080810546875 +12293 0.188201904296875 +12294 0.091156005859375 +12295 0.171234130859375 +12296 0.073883056640625 +12297 0.118438720703125 +12298 0.051177978515625 +12299 0.05706787109375 +12300 0.02362060546875 +12301 -0.010711669921875 +12302 -0.01275634765625 +12303 -0.0914306640625 +12304 -0.04608154296875 +12305 -0.162322998046875 +12306 -0.06109619140625 +12307 -0.194549560546875 +12308 -0.037078857421875 +12309 -0.1492919921875 +12310 0.0286865234375 +12311 -0.02166748046875 +12312 0.10198974609375 +12313 0.124053955078125 +12314 0.14202880859375 +12315 0.211151123046875 +12316 0.149688720703125 +12317 0.240447998046875 +12318 0.141632080078125 +12319 0.242218017578125 +12320 0.123382568359375 +12321 0.2257080078125 +12322 0.0972900390625 +12323 0.194366455078125 +12324 0.046356201171875 +12325 0.115509033203125 +12326 -0.0162353515625 +12327 0.0128173828125 +12328 -0.0579833984375 +12329 -0.053802490234375 +12330 -0.092681884765625 +12331 -0.110626220703125 +12332 -0.142608642578125 +12333 -0.199493408203125 +12334 -0.1937255859375 +12335 -0.29437255859375 +12336 -0.2122802734375 +12337 -0.33221435546875 +12338 -0.180572509765625 +12339 -0.27972412109375 +12340 -0.124847412109375 +12341 -0.185333251953125 +12342 -0.08782958984375 +12343 -0.128204345703125 +12344 -0.0738525390625 +12345 -0.115692138671875 +12346 -0.0665283203125 +12347 -0.116455078125 +12348 -0.053131103515625 +12349 -0.105926513671875 +12350 -0.0179443359375 +12351 -0.053955078125 +12352 0.04364013671875 +12353 0.048797607421875 +12354 0.107177734375 +12355 0.157318115234375 +12356 0.140472412109375 +12357 0.212005615234375 +12358 0.1463623046875 +12359 0.218475341796875 +12360 0.157196044921875 +12361 0.23724365234375 +12362 0.19281005859375 +12363 0.30535888671875 +12364 0.231048583984375 +12365 0.38128662109375 +12366 0.23956298828125 +12367 0.404449462890625 +12368 0.2291259765625 +12369 0.3944091796875 +12370 0.2200927734375 +12371 0.3885498046875 +12372 0.199859619140625 +12373 0.362640380859375 +12374 0.14569091796875 +12375 0.27362060546875 +12376 0.05560302734375 +12377 0.11712646484375 +12378 -0.042236328125 +12379 -0.054901123046875 +12380 -0.119842529296875 +12381 -0.19085693359375 +12382 -0.17431640625 +12383 -0.28570556640625 +12384 -0.20538330078125 +12385 -0.339263916015625 +12386 -0.2269287109375 +12387 -0.3775634765625 +12388 -0.2630615234375 +12389 -0.445709228515625 +12390 -0.309234619140625 +12391 -0.535064697265625 +12392 -0.356719970703125 +12393 -0.629058837890625 +12394 -0.389556884765625 +12395 -0.697601318359375 +12396 -0.3883056640625 +12397 -0.70391845703125 +12398 -0.3502197265625 +12399 -0.6424560546875 +12400 -0.26385498046875 +12401 -0.491241455078125 +12402 -0.13775634765625 +12403 -0.265716552734375 +12404 -0.003204345703125 +12405 -0.023712158203125 +12406 0.121826171875 +12407 0.201751708984375 +12408 0.21844482421875 +12409 0.375823974609375 +12410 0.279327392578125 +12411 0.485076904296875 +12412 0.325439453125 +12413 0.56884765625 +12414 0.360809326171875 +12415 0.634765625 +12416 0.36126708984375 +12417 0.63763427734375 +12418 0.320770263671875 +12419 0.5660400390625 +12420 0.267364501953125 +12421 0.4720458984375 +12422 0.228729248046875 +12423 0.40692138671875 +12424 0.208953857421875 +12425 0.3778076171875 +12426 0.204071044921875 +12427 0.376953125 +12428 0.196990966796875 +12429 0.371978759765625 +12430 0.16131591796875 +12431 0.313140869140625 +12432 0.088653564453125 +12433 0.184417724609375 +12434 -0.007171630859375 +12435 0.011199951171875 +12436 -0.107025146484375 +12437 -0.171051025390625 +12438 -0.197418212890625 +12439 -0.33740234375 +12440 -0.26983642578125 +12441 -0.47198486328125 +12442 -0.316558837890625 +12443 -0.560394287109375 +12444 -0.325836181640625 +12445 -0.58056640625 +12446 -0.30584716796875 +12447 -0.54754638671875 +12448 -0.282073974609375 +12449 -0.508575439453125 +12450 -0.25244140625 +12451 -0.459503173828125 +12452 -0.213958740234375 +12453 -0.394378662109375 +12454 -0.187896728515625 +12455 -0.35260009765625 +12456 -0.162445068359375 +12457 -0.31170654296875 +12458 -0.097991943359375 +12459 -0.197418212890625 +12460 0.0062255859375 +12461 -0.007965087890625 +12462 0.12371826171875 +12463 0.207489013671875 +12464 0.23309326171875 +12465 0.409210205078125 +12466 0.32086181640625 +12467 0.57208251953125 +12468 0.370849609375 +12469 0.66595458984375 +12470 0.36590576171875 +12471 0.65875244140625 +12472 0.315216064453125 +12473 0.56744384765625 +12474 0.239990234375 +12475 0.431396484375 +12476 0.16387939453125 +12477 0.29443359375 +12478 0.100921630859375 +12479 0.182464599609375 +12480 0.034210205078125 +12481 0.06365966796875 +12482 -0.043548583984375 +12483 -0.075958251953125 +12484 -0.107025146484375 +12485 -0.189422607421875 +12486 -0.153533935546875 +12487 -0.271942138671875 +12488 -0.193115234375 +12489 -0.342529296875 +12490 -0.205902099609375 +12491 -0.364166259765625 +12492 -0.186676025390625 +12493 -0.327239990234375 +12494 -0.15966796875 +12495 -0.2769775390625 +12496 -0.146514892578125 +12497 -0.253692626953125 +12498 -0.139862060546875 +12499 -0.24365234375 +12500 -0.113861083984375 +12501 -0.1983642578125 +12502 -0.0677490234375 +12503 -0.116241455078125 +12504 -0.0228271484375 +12505 -0.036834716796875 +12506 0.01806640625 +12507 0.034881591796875 +12508 0.050689697265625 +12509 0.09124755859375 +12510 0.062408447265625 +12511 0.10888671875 +12512 0.07330322265625 +12513 0.125518798828125 +12514 0.0921630859375 +12515 0.15771484375 +12516 0.104339599609375 +12517 0.17828369140625 +12518 0.101104736328125 +12519 0.17108154296875 +12520 0.079193115234375 +12521 0.129974365234375 +12522 0.05328369140625 +12523 0.082427978515625 +12524 0.023040771484375 +12525 0.027679443359375 +12526 -0.02825927734375 +12527 -0.065643310546875 +12528 -0.080108642578125 +12529 -0.15936279296875 +12530 -0.110748291015625 +12531 -0.21307373046875 +12532 -0.124298095703125 +12533 -0.234649658203125 +12534 -0.107818603515625 +12535 -0.2001953125 +12536 -0.0662841796875 +12537 -0.119171142578125 +12538 -0.017364501953125 +12539 -0.024749755859375 +12540 0.04046630859375 +12541 0.085784912109375 +12542 0.088897705078125 +12543 0.178131103515625 +12544 0.1080322265625 +12545 0.215576171875 +12546 0.104949951171875 +12547 0.211456298828125 +12548 0.0845947265625 +12549 0.17523193359375 +12550 0.059326171875 +12551 0.128753662109375 +12552 0.045989990234375 +12553 0.1019287109375 +12554 0.0328369140625 +12555 0.0743408203125 +12556 0.018157958984375 +12557 0.04327392578125 +12558 0.018463134765625 +12559 0.038177490234375 +12560 0.043365478515625 +12561 0.076263427734375 +12562 0.08331298828125 +12563 0.14105224609375 +12564 0.1119384765625 +12565 0.186431884765625 +12566 0.115692138671875 +12567 0.188812255859375 +12568 0.089263916015625 +12569 0.1390380859375 +12570 0.035247802734375 +12571 0.041778564453125 +12572 -0.03302001953125 +12573 -0.079437255859375 +12574 -0.11260986328125 +12575 -0.219390869140625 +12576 -0.1976318359375 +12577 -0.367828369140625 +12578 -0.271087646484375 +12579 -0.494873046875 +12580 -0.307708740234375 +12581 -0.556243896484375 +12582 -0.282867431640625 +12583 -0.508697509765625 +12584 -0.209686279296875 +12585 -0.3756103515625 +12586 -0.12322998046875 +12587 -0.218902587890625 +12588 -0.037628173828125 +12589 -0.063751220703125 +12590 0.048187255859375 +12591 0.091552734375 +12592 0.12811279296875 +12593 0.23602294921875 +12594 0.1871337890625 +12595 0.342987060546875 +12596 0.215545654296875 +12597 0.39520263671875 +12598 0.211517333984375 +12599 0.389373779296875 +12600 0.174346923828125 +12601 0.324249267578125 +12602 0.117828369140625 +12603 0.224090576171875 +12604 0.06201171875 +12605 0.124267578125 +12606 0.0137939453125 +12607 0.037078857421875 +12608 -0.01129150390625 +12609 -0.010101318359375 +12610 -0.014617919921875 +12611 -0.019439697265625 +12612 -0.014373779296875 +12613 -0.022796630859375 +12614 -0.0001220703125 +12615 -0.001556396484375 +12616 0.0347900390625 +12617 0.056304931640625 +12618 0.06524658203125 +12619 0.106719970703125 +12620 0.0611572265625 +12621 0.096893310546875 +12622 0.031494140625 +12623 0.042694091796875 +12624 -0.002288818359375 +12625 -0.018035888671875 +12626 -0.03485107421875 +12627 -0.07586669921875 +12628 -0.05975341796875 +12629 -0.11944580078125 +12630 -0.08319091796875 +12631 -0.15972900390625 +12632 -0.108489990234375 +12633 -0.202606201171875 +12634 -0.1358642578125 +12635 -0.24859619140625 +12636 -0.16949462890625 +12637 -0.30517578125 +12638 -0.2034912109375 +12639 -0.36212158203125 +12640 -0.22186279296875 +12641 -0.39141845703125 +12642 -0.2030029296875 +12643 -0.35528564453125 +12644 -0.14471435546875 +12645 -0.249969482421875 +12646 -0.05682373046875 +12647 -0.092864990234375 +12648 0.04541015625 +12649 0.08905029296875 +12650 0.127655029296875 +12651 0.2352294921875 +12652 0.174713134765625 +12653 0.318817138671875 +12654 0.197265625 +12655 0.358642578125 +12656 0.191375732421875 +12657 0.347747802734375 +12658 0.15673828125 +12659 0.28564453125 +12660 0.1221923828125 +12661 0.223175048828125 +12662 0.10833740234375 +12663 0.196746826171875 +12664 0.10003662109375 +12665 0.179840087890625 +12666 0.087615966796875 +12667 0.155548095703125 +12668 0.0865478515625 +12669 0.151214599609375 +12670 0.09112548828125 +12671 0.156951904296875 +12672 0.0780029296875 +12673 0.13177490234375 +12674 0.061370849609375 +12675 0.100799560546875 +12676 0.054290771484375 +12677 0.087127685546875 +12678 0.036376953125 +12679 0.05487060546875 +12680 0.00018310546875 +12681 -0.009002685546875 +12682 -0.053955078125 +12683 -0.10400390625 +12684 -0.125640869140625 +12685 -0.229400634765625 +12686 -0.197967529296875 +12687 -0.35552978515625 +12688 -0.247894287109375 +12689 -0.441925048828125 +12690 -0.26702880859375 +12691 -0.473846435546875 +12692 -0.262939453125 +12693 -0.464813232421875 +12694 -0.238006591796875 +12695 -0.419097900390625 +12696 -0.19085693359375 +12697 -0.334320068359375 +12698 -0.131317138671875 +12699 -0.227935791015625 +12700 -0.072723388671875 +12701 -0.12347412109375 +12702 -0.018829345703125 +12703 -0.02764892578125 +12704 0.0406494140625 +12705 0.077667236328125 +12706 0.117523193359375 +12707 0.2132568359375 +12708 0.217315673828125 +12709 0.38885498046875 +12710 0.32769775390625 +12711 0.582794189453125 +12712 0.41400146484375 +12713 0.734039306640625 +12714 0.45208740234375 +12715 0.800140380859375 +12716 0.4403076171875 +12717 0.7783203125 +12718 0.376708984375 +12719 0.6651611328125 +12720 0.260711669921875 +12721 0.45965576171875 +12722 0.113525390625 +12723 0.199188232421875 +12724 -0.027679443359375 +12725 -0.050689697265625 +12726 -0.13055419921875 +12727 -0.23297119140625 +12728 -0.185211181640625 +12729 -0.33013916015625 +12730 -0.206512451171875 +12731 -0.368408203125 +12732 -0.21221923828125 +12733 -0.378936767578125 +12734 -0.21099853515625 +12735 -0.376983642578125 +12736 -0.212615966796875 +12737 -0.37969970703125 +12738 -0.21954345703125 +12739 -0.391510009765625 +12740 -0.216400146484375 +12741 -0.385345458984375 +12742 -0.19219970703125 +12743 -0.3419189453125 +12744 -0.15924072265625 +12745 -0.28289794921875 +12746 -0.14208984375 +12747 -0.251617431640625 +12748 -0.150970458984375 +12749 -0.266143798828125 +12750 -0.155670166015625 +12751 -0.273345947265625 +12752 -0.124114990234375 +12753 -0.216796875 +12754 -0.074310302734375 +12755 -0.128265380859375 +12756 -0.040557861328125 +12757 -0.068145751953125 +12758 -0.02655029296875 +12759 -0.0430908203125 +12760 -0.01605224609375 +12761 -0.024444580078125 +12762 0.0096435546875 +12763 0.020721435546875 +12764 0.0687255859375 +12765 0.124481201171875 +12766 0.144744873046875 +12767 0.25787353515625 +12768 0.213958740234375 +12769 0.379119873046875 +12770 0.271636962890625 +12771 0.47991943359375 +12772 0.29949951171875 +12773 0.5281982421875 +12774 0.290283203125 +12775 0.511138916015625 +12776 0.259552001953125 +12777 0.456207275390625 +12778 0.232330322265625 +12779 0.407470703125 +12780 0.21923828125 +12781 0.383758544921875 +12782 0.204254150390625 +12783 0.35687255859375 +12784 0.178863525390625 +12785 0.31182861328125 +12786 0.14434814453125 +12787 0.250885009765625 +12788 0.095794677734375 +12789 0.1654052734375 +12790 0.021759033203125 +12791 0.035247802734375 +12792 -0.079132080078125 +12793 -0.142059326171875 +12794 -0.1893310546875 +12795 -0.33563232421875 +12796 -0.3026123046875 +12797 -0.5345458984375 +12798 -0.409332275390625 +12799 -0.72186279296875 +12800 -0.474395751953125 +12801 -0.836669921875 +12802 -0.470855712890625 +12803 -0.8326416015625 +12804 -0.410552978515625 +12805 -0.7296142578125 +12806 -0.326019287109375 +12807 -0.582550048828125 +12808 -0.24591064453125 +12809 -0.440093994140625 +12810 -0.18292236328125 +12811 -0.324310302734375 +12812 -0.116241455078125 +12813 -0.20147705078125 +12814 -0.029205322265625 +12815 -0.044647216796875 +12816 0.053314208984375 +12817 0.103973388671875 +12818 0.106475830078125 +12819 0.202392578125 +12820 0.138916015625 +12821 0.264495849609375 +12822 0.180084228515625 +12823 0.338897705078125 +12824 0.24102783203125 +12825 0.443817138671875 +12826 0.301300048828125 +12827 0.545074462890625 +12828 0.34564208984375 +12829 0.6173095703125 +12830 0.369140625 +12831 0.6524658203125 +12832 0.379302978515625 +12833 0.66339111328125 +12834 0.3795166015625 +12835 0.6561279296875 +12836 0.355133056640625 +12837 0.606781005859375 +12838 0.29736328125 +12839 0.501190185546875 +12840 0.21392822265625 +12841 0.352783203125 +12842 0.113525390625 +12843 0.176544189453125 +12844 -0.008514404296875 +12845 -0.034820556640625 +12846 -0.1385498046875 +12847 -0.258209228515625 +12848 -0.24609375 +12849 -0.44244384765625 +12850 -0.323944091796875 +12851 -0.5753173828125 +12852 -0.36932373046875 +12853 -0.65203857421875 +12854 -0.3636474609375 +12855 -0.641632080078125 +12856 -0.31768798828125 +12857 -0.562164306640625 +12858 -0.257965087890625 +12859 -0.458038330078125 +12860 -0.197052001953125 +12861 -0.350555419921875 +12862 -0.147216796875 +12863 -0.260528564453125 +12864 -0.110687255859375 +12865 -0.192108154296875 +12866 -0.085235595703125 +12867 -0.141937255859375 +12868 -0.06585693359375 +12869 -0.1021728515625 +12870 -0.04638671875 +12871 -0.062896728515625 +12872 -0.019317626953125 +12873 -0.011932373046875 +12874 0.022796630859375 +12875 0.062835693359375 +12876 0.072479248046875 +12877 0.148712158203125 +12878 0.127410888671875 +12879 0.241729736328125 +12880 0.191925048828125 +12881 0.34912109375 +12882 0.25787353515625 +12883 0.457305908203125 +12884 0.311737060546875 +12885 0.54388427734375 +12886 0.331817626953125 +12887 0.5728759765625 +12888 0.295318603515625 +12889 0.506591796875 +12890 0.20574951171875 +12891 0.351226806640625 +12892 0.08673095703125 +12893 0.146514892578125 +12894 -0.030548095703125 +12895 -0.05523681640625 +12896 -0.123626708984375 +12897 -0.21624755859375 +12898 -0.19171142578125 +12899 -0.334930419921875 +12900 -0.22998046875 +12901 -0.402984619140625 +12902 -0.2510986328125 +12903 -0.4412841796875 +12904 -0.28271484375 +12905 -0.49578857421875 +12906 -0.321075439453125 +12907 -0.5601806640625 +12908 -0.345947265625 +12909 -0.600738525390625 +12910 -0.33734130859375 +12911 -0.584228515625 +12912 -0.2763671875 +12913 -0.47930908203125 +12914 -0.158905029296875 +12915 -0.27935791015625 +12916 0.00042724609375 +12917 -0.0089111328125 +12918 0.16387939453125 +12919 0.268798828125 +12920 0.2890625 +12921 0.482818603515625 +12922 0.358489990234375 +12923 0.60369873046875 +12924 0.383697509765625 +12925 0.650421142578125 +12926 0.38946533203125 +12927 0.66400146484375 +12928 0.3741455078125 +12929 0.6414794921875 +12930 0.33160400390625 +12931 0.572540283203125 +12932 0.286468505859375 +12933 0.498138427734375 +12934 0.25146484375 +12935 0.439453125 +12936 0.213958740234375 +12937 0.375518798828125 +12938 0.154815673828125 +12939 0.274505615234375 +12940 0.057342529296875 +12941 0.1087646484375 +12942 -0.065185546875 +12943 -0.099395751953125 +12944 -0.193878173828125 +12945 -0.3182373046875 +12946 -0.32958984375 +12947 -0.5489501953125 +12948 -0.461822509765625 +12949 -0.7738037109375 +12950 -0.5589599609375 +12951 -0.86383056640625 +12952 -0.601165771484375 +12953 -0.870391845703125 +12954 -0.599212646484375 +12955 -0.86895751953125 +12956 -0.56103515625 +12957 -0.861053466796875 +12958 -0.476318359375 +12959 -0.765869140625 +12960 -0.33831787109375 +12961 -0.5301513671875 +12962 -0.151275634765625 +12963 -0.214691162109375 +12964 0.05902099609375 +12965 0.137359619140625 +12966 0.2618408203125 +12967 0.474822998046875 +12968 0.43597412109375 +12969 0.76239013671875 +12970 0.565338134765625 +12971 0.867462158203125 +12972 0.65032958984375 +12973 0.870361328125 +12974 0.684112548828125 +12975 0.86480712890625 +12976 0.670013427734375 +12977 0.831817626953125 +12978 0.622772216796875 +12979 0.677581787109375 +12980 0.545928955078125 +12981 0.495880126953125 +12982 0.45074462890625 +12983 0.30767822265625 +12984 0.33856201171875 +12985 0.116180419921875 +12986 0.190399169921875 +12987 -0.110748291015625 +12988 0.002105712890625 +12989 -0.381805419921875 +12990 -0.200653076171875 +12991 -0.6572265625 +12992 -0.381988525390625 +12993 -0.857421875 +12994 -0.5162353515625 +12995 -0.870391845703125 +12996 -0.59918212890625 +12997 -0.870391845703125 +12998 -0.647064208984375 +12999 -0.86444091796875 +13000 -0.68133544921875 +13001 -0.85723876953125 +13002 -0.69110107421875 +13003 -0.790008544921875 +13004 -0.643890380859375 +13005 -0.62847900390625 +13006 -0.53790283203125 +13007 -0.3956298828125 +13008 -0.392913818359375 +13009 -0.126708984375 +13010 -0.225433349609375 +13011 0.150115966796875 +13012 -0.042510986328125 +13013 0.424041748046875 +13014 0.1396484375 +13015 0.670623779296875 +13016 0.297821044921875 +13017 0.854522705078125 +13018 0.421417236328125 +13019 0.866485595703125 +13020 0.501220703125 +13021 0.86920166015625 +13022 0.548187255859375 +13023 0.8653564453125 +13024 0.570404052734375 +13025 0.857147216796875 +13026 0.566192626953125 +13027 0.766845703125 +13028 0.5386962890625 +13029 0.628509521484375 +13030 0.483978271484375 +13031 0.462127685546875 +13032 0.417572021484375 +13033 0.297210693359375 +13034 0.346954345703125 +13035 0.14862060546875 +13036 0.258514404296875 +13037 -0.00537109375 +13038 0.156768798828125 +13039 -0.15753173828125 +13040 0.039581298828125 +13041 -0.31304931640625 +13042 -0.101409912109375 +13043 -0.48876953125 +13044 -0.238067626953125 +13045 -0.6416015625 +13046 -0.3555908203125 +13047 -0.751373291015625 +13048 -0.46783447265625 +13049 -0.84619140625 +13050 -0.566009521484375 +13051 -0.861297607421875 +13052 -0.630279541015625 +13053 -0.863250732421875 +13054 -0.6417236328125 +13055 -0.856597900390625 +13056 -0.608306884765625 +13057 -0.7498779296875 +13058 -0.565582275390625 +13059 -0.624542236328125 +13060 -0.49896240234375 +13061 -0.47808837890625 +13062 -0.371246337890625 +13063 -0.253387451171875 +13064 -0.211029052734375 +13065 0.003692626953125 +13066 -0.06121826171875 +13067 0.2257080078125 +13068 0.086456298828125 +13069 0.427154541015625 +13070 0.252777099609375 +13071 0.643218994140625 +13072 0.431976318359375 +13073 0.855926513671875 +13074 0.58770751953125 +13075 0.870361328125 +13076 0.6888427734375 +13077 0.870361328125 +13078 0.74005126953125 +13079 0.862762451171875 +13080 0.739532470703125 +13081 0.79669189453125 +13082 0.68133544921875 +13083 0.595794677734375 +13084 0.583831787109375 +13085 0.362152099609375 +13086 0.464630126953125 +13087 0.1270751953125 +13088 0.336944580078125 +13089 -0.086944580078125 +13090 0.20184326171875 +13091 -0.2784423828125 +13092 0.037109375 +13093 -0.484832763671875 +13094 -0.169586181640625 +13095 -0.729583740234375 +13096 -0.38653564453125 +13097 -0.86688232421875 +13098 -0.573944091796875 +13099 -0.870391845703125 +13100 -0.728851318359375 +13101 -0.86859130859375 +13102 -0.85009765625 +13103 -0.86279296875 +13104 -0.861114501953125 +13105 -0.817962646484375 +13106 -0.85894775390625 +13107 -0.6116943359375 +13108 -0.78582763671875 +13109 -0.3128662109375 +13110 -0.608367919921875 +13111 0.039398193359375 +13112 -0.375335693359375 +13113 0.422821044921875 +13114 -0.107696533203125 +13115 0.805145263671875 +13116 0.151580810546875 +13117 0.870361328125 +13118 0.366607666015625 +13119 0.870361328125 +13120 0.53009033203125 +13121 0.860015869140625 +13122 0.637237548828125 +13123 0.727935791015625 +13124 0.68450927734375 +13125 0.48114013671875 +13126 0.687225341796875 +13127 0.2059326171875 +13128 0.659698486328125 +13129 -0.06103515625 +13130 0.6082763671875 +13131 -0.29913330078125 +13132 0.5238037109375 +13133 -0.516204833984375 +13134 0.396575927734375 +13135 -0.7252197265625 +13136 0.24237060546875 +13137 -0.85980224609375 +13138 0.08294677734375 +13139 -0.870391845703125 +13140 -0.0628662109375 +13141 -0.870391845703125 +13142 -0.164154052734375 +13143 -0.858062744140625 +13144 -0.218109130859375 +13145 -0.673004150390625 +13146 -0.257720947265625 +13147 -0.42694091796875 +13148 -0.31085205078125 +13149 -0.2100830078125 +13150 -0.376007080078125 +13151 -0.0362548828125 +13152 -0.43463134765625 +13153 0.10943603515625 +13154 -0.474029541015625 +13155 0.23516845703125 +13156 -0.467987060546875 +13157 0.373687744140625 +13158 -0.41766357421875 +13159 0.517791748046875 +13160 -0.362884521484375 +13161 0.602783203125 +13162 -0.300445556640625 +13163 0.635711669921875 +13164 -0.209381103515625 +13165 0.655181884765625 +13166 -0.09613037109375 +13167 0.65948486328125 +13168 0.033966064453125 +13169 0.651275634765625 +13170 0.165191650390625 +13171 0.61846923828125 +13172 0.27392578125 +13173 0.53753662109375 +13174 0.3485107421875 +13175 0.404144287109375 +13176 0.382568359375 +13177 0.22186279296875 +13178 0.37664794921875 +13179 0.003997802734375 +13180 0.342010498046875 +13181 -0.22100830078125 +13182 0.291595458984375 +13183 -0.42449951171875 +13184 0.23883056640625 +13185 -0.579833984375 +13186 0.210723876953125 +13187 -0.641876220703125 +13188 0.203125 +13189 -0.6177978515625 +13190 0.17529296875 +13191 -0.575531005859375 +13192 0.123992919921875 +13193 -0.526336669921875 +13194 0.082183837890625 +13195 -0.42645263671875 +13196 0.067413330078125 +13197 -0.2581787109375 +13198 0.056915283203125 +13199 -0.068695068359375 +13200 0.026641845703125 +13201 0.09222412109375 +13202 -0.011322021484375 +13203 0.232147216796875 +13204 -0.05035400390625 +13205 0.3509521484375 +13206 -0.10894775390625 +13207 0.410064697265625 +13208 -0.20550537109375 +13209 0.372955322265625 +13210 -0.32666015625 +13211 0.2554931640625 +13212 -0.439361572265625 +13213 0.10711669921875 +13214 -0.531219482421875 +13215 -0.052886962890625 +13216 -0.579345703125 +13217 -0.186279296875 +13218 -0.548492431640625 +13219 -0.23291015625 +13220 -0.45318603515625 +13221 -0.209442138671875 +13222 -0.335235595703125 +13223 -0.174163818359375 +13224 -0.200042724609375 +13225 -0.126739501953125 +13226 -0.0416259765625 +13227 -0.048126220703125 +13228 0.121917724609375 +13229 0.0426025390625 +13230 0.260894775390625 +13231 0.10748291015625 +13232 0.36669921875 +13233 0.1409912109375 +13234 0.469207763671875 +13235 0.19708251953125 +13236 0.56396484375 +13237 0.273651123046875 +13238 0.615509033203125 +13239 0.31768798828125 +13240 0.630706787109375 +13241 0.341094970703125 +13242 0.62548828125 +13243 0.368011474609375 +13244 0.5853271484375 +13245 0.37249755859375 +13246 0.479156494140625 +13247 0.30072021484375 +13248 0.3101806640625 +13249 0.1517333984375 +13250 0.12060546875 +13251 -0.01470947265625 +13252 -0.078155517578125 +13253 -0.1883544921875 +13254 -0.283355712890625 +13255 -0.372711181640625 +13256 -0.456146240234375 +13257 -0.51397705078125 +13258 -0.56658935546875 +13259 -0.57177734375 +13260 -0.606781005859375 +13261 -0.53948974609375 +13262 -0.585174560546875 +13263 -0.43511962890625 +13264 -0.523590087890625 +13265 -0.2962646484375 +13266 -0.44525146484375 +13267 -0.161102294921875 +13268 -0.359100341796875 +13269 -0.0435791015625 +13270 -0.2637939453125 +13271 0.060394287109375 +13272 -0.17034912109375 +13273 0.13665771484375 +13274 -0.091217041015625 +13275 0.170135498046875 +13276 -0.026947021484375 +13277 0.16552734375 +13278 0.040252685546875 +13279 0.15728759765625 +13280 0.1097412109375 +13281 0.150787353515625 +13282 0.1622314453125 +13283 0.12200927734375 +13284 0.19976806640625 +13285 0.080108642578125 +13286 0.235595703125 +13287 0.05126953125 +13288 0.284393310546875 +13289 0.062896728515625 +13290 0.33013916015625 +13291 0.09271240234375 +13292 0.341644287109375 +13293 0.092987060546875 +13294 0.328094482421875 +13295 0.07855224609375 +13296 0.299591064453125 +13297 0.06427001953125 +13298 0.2479248046875 +13299 0.0347900390625 +13300 0.174072265625 +13301 -0.01171875 +13302 0.09295654296875 +13303 -0.056060791015625 +13304 0.03472900390625 +13305 -0.055511474609375 +13306 0.00250244140625 +13307 -0.010467529296875 +13308 -0.034454345703125 +13309 0.02508544921875 +13310 -0.089019775390625 +13311 0.025665283203125 +13312 -0.14166259765625 +13313 0.017333984375 +13314 -0.18902587890625 +13315 0.00189208984375 +13316 -0.236572265625 +13317 -0.03173828125 +13318 -0.2755126953125 +13319 -0.071502685546875 +13320 -0.3172607421875 +13321 -0.13543701171875 +13322 -0.359954833984375 +13323 -0.219970703125 +13324 -0.38861083984375 +13325 -0.300506591796875 +13326 -0.404388427734375 +13327 -0.376312255859375 +13328 -0.389068603515625 +13329 -0.416107177734375 +13330 -0.31341552734375 +13331 -0.371124267578125 +13332 -0.180694580078125 +13333 -0.242279052734375 +13334 -0.019744873046875 +13335 -0.069732666015625 +13336 0.153167724609375 +13337 0.125640869140625 +13338 0.315399169921875 +13339 0.31268310546875 +13340 0.4412841796875 +13341 0.45501708984375 +13342 0.53057861328125 +13343 0.554779052734375 +13344 0.581390380859375 +13345 0.61065673828125 +13346 0.5855712890625 +13347 0.610931396484375 +13348 0.527557373046875 +13349 0.531463623046875 +13350 0.41839599609375 +13351 0.3883056640625 +13352 0.293853759765625 +13353 0.23468017578125 +13354 0.17156982421875 +13355 0.095245361328125 +13356 0.070343017578125 +13357 -0.00396728515625 +13358 0.001708984375 +13359 -0.04852294921875 +13360 -0.04290771484375 +13361 -0.055145263671875 +13362 -0.095123291015625 +13363 -0.0758056640625 +13364 -0.171173095703125 +13365 -0.138702392578125 +13366 -0.2467041015625 +13367 -0.209197998046875 +13368 -0.321380615234375 +13369 -0.289031982421875 +13370 -0.394622802734375 +13371 -0.37884521484375 +13372 -0.451324462890625 +13373 -0.456329345703125 +13374 -0.48809814453125 +13375 -0.51641845703125 +13376 -0.47943115234375 +13377 -0.519287109375 +13378 -0.421783447265625 +13379 -0.458251953125 +13380 -0.34979248046875 +13381 -0.384796142578125 +13382 -0.281097412109375 +13383 -0.323699951171875 +13384 -0.21368408203125 +13385 -0.269287109375 +13386 -0.132293701171875 +13387 -0.1951904296875 +13388 -0.037841796875 +13389 -0.100006103515625 +13390 0.050445556640625 +13391 -0.01055908203125 +13392 0.150665283203125 +13393 0.1033935546875 +13394 0.2662353515625 +13395 0.24908447265625 +13396 0.361480712890625 +13397 0.373199462890625 +13398 0.42431640625 +13399 0.45806884765625 +13400 0.4595947265625 +13401 0.511474609375 +13402 0.48828125 +13403 0.565399169921875 +13404 0.505401611328125 +13405 0.61138916015625 +13406 0.473052978515625 +13407 0.5897216796875 +13408 0.385986328125 +13409 0.4906005859375 +13410 0.256927490234375 +13411 0.33148193359375 +13412 0.110382080078125 +13413 0.147796630859375 +13414 -0.0250244140625 +13415 -0.01873779296875 +13416 -0.129730224609375 +13417 -0.140289306640625 +13418 -0.1861572265625 +13419 -0.191986083984375 +13420 -0.199981689453125 +13421 -0.184295654296875 +13422 -0.19927978515625 +13423 -0.161834716796875 +13424 -0.210723876953125 +13425 -0.166595458984375 +13426 -0.230987548828125 +13427 -0.19390869140625 +13428 -0.24749755859375 +13429 -0.22442626953125 +13430 -0.274658203125 +13431 -0.279754638671875 +13432 -0.299530029296875 +13433 -0.3389892578125 +13434 -0.2919921875 +13435 -0.3543701171875 +13436 -0.267578125 +13437 -0.348175048828125 +13438 -0.2310791015625 +13439 -0.32598876953125 +13440 -0.164520263671875 +13441 -0.2581787109375 +13442 -0.065887451171875 +13443 -0.139801025390625 +13444 0.05419921875 +13445 0.014617919921875 +13446 0.155242919921875 +13447 0.144378662109375 +13448 0.217926025390625 +13449 0.221038818359375 +13450 0.258636474609375 +13451 0.27069091796875 +13452 0.27752685546875 +13453 0.294036865234375 +13454 0.2879638671875 +13455 0.311767578125 +13456 0.30010986328125 +13457 0.339141845703125 +13458 0.30419921875 +13459 0.360260009765625 +13460 0.2913818359375 +13461 0.360504150390625 +13462 0.241455078125 +13463 0.308380126953125 +13464 0.140533447265625 +13465 0.18170166015625 +13466 0.0057373046875 +13467 0.0047607421875 +13468 -0.13092041015625 +13469 -0.17559814453125 +13470 -0.238677978515625 +13471 -0.3143310546875 +13472 -0.28778076171875 +13473 -0.36785888671875 +13474 -0.295013427734375 +13475 -0.36248779296875 +13476 -0.289947509765625 +13477 -0.343536376953125 +13478 -0.266265869140625 +13479 -0.3018798828125 +13480 -0.219757080078125 +13481 -0.231414794921875 +13482 -0.140899658203125 +13483 -0.117645263671875 +13484 -0.05145263671875 +13485 0.007049560546875 +13486 0.011810302734375 +13487 0.087982177734375 +13488 0.057769775390625 +13489 0.13946533203125 +13490 0.094207763671875 +13491 0.17425537109375 +13492 0.117584228515625 +13493 0.188201904296875 +13494 0.120452880859375 +13495 0.171234130859375 +13496 0.0987548828125 +13497 0.118438720703125 +13498 0.06988525390625 +13499 0.05706787109375 +13500 0.03466796875 +13501 -0.010711669921875 +13502 -0.011688232421875 +13503 -0.0914306640625 +13504 -0.05438232421875 +13505 -0.162322998046875 +13506 -0.074432373046875 +13507 -0.194549560546875 +13508 -0.046051025390625 +13509 -0.1492919921875 +13510 0.034149169921875 +13511 -0.02166748046875 +13512 0.12384033203125 +13513 0.124053955078125 +13514 0.172515869140625 +13515 0.211151123046875 +13516 0.181304931640625 +13517 0.240447998046875 +13518 0.170928955078125 +13519 0.242218017578125 +13520 0.148223876953125 +13521 0.2257080078125 +13522 0.1160888671875 +13523 0.194366455078125 +13524 0.053436279296875 +13525 0.115509033203125 +13526 -0.0234375 +13527 0.0128173828125 +13528 -0.074371337890625 +13529 -0.053802490234375 +13530 -0.116455078125 +13531 -0.110626220703125 +13532 -0.177337646484375 +13533 -0.199493408203125 +13534 -0.239715576171875 +13535 -0.29437255859375 +13536 -0.261810302734375 +13537 -0.33221435546875 +13538 -0.221771240234375 +13539 -0.27972412109375 +13540 -0.152099609375 +13541 -0.185333251953125 +13542 -0.10577392578125 +13543 -0.128204345703125 +13544 -0.088134765625 +13545 -0.115692138671875 +13546 -0.078948974609375 +13547 -0.116455078125 +13548 -0.06243896484375 +13549 -0.105926513671875 +13550 -0.01910400390625 +13551 -0.053955078125 +13552 0.056793212890625 +13553 0.048797607421875 +13554 0.134979248046875 +13555 0.157318115234375 +13556 0.17559814453125 +13557 0.212005615234375 +13558 0.182159423828125 +13559 0.218475341796875 +13560 0.194793701171875 +13561 0.23724365234375 +13562 0.2381591796875 +13563 0.30535888671875 +13564 0.284820556640625 +13565 0.38128662109375 +13566 0.2947998046875 +13567 0.404449462890625 +13568 0.28204345703125 +13569 0.3944091796875 +13570 0.27239990234375 +13571 0.3885498046875 +13572 0.249267578125 +13573 0.362640380859375 +13574 0.18280029296875 +13575 0.27362060546875 +13576 0.070068359375 +13577 0.11712646484375 +13578 -0.052642822265625 +13579 -0.054901123046875 +13580 -0.14935302734375 +13581 -0.19085693359375 +13582 -0.216522216796875 +13583 -0.28570556640625 +13584 -0.253997802734375 +13585 -0.339263916015625 +13586 -0.279937744140625 +13587 -0.3775634765625 +13588 -0.3258056640625 +13589 -0.445709228515625 +13590 -0.38568115234375 +13591 -0.535064697265625 +13592 -0.44818115234375 +13593 -0.629058837890625 +13594 -0.49249267578125 +13595 -0.697601318359375 +13596 -0.49322509765625 +13597 -0.70391845703125 +13598 -0.446746826171875 +13599 -0.6424560546875 +13600 -0.33795166015625 +13601 -0.491241455078125 +13602 -0.177734375 +13603 -0.265716552734375 +13604 -0.00653076171875 +13605 -0.023712158203125 +13606 0.15252685546875 +13607 0.201751708984375 +13608 0.27508544921875 +13609 0.375823974609375 +13610 0.35174560546875 +13611 0.485076904296875 +13612 0.409881591796875 +13613 0.56884765625 +13614 0.454864501953125 +13615 0.634765625 +13616 0.455291748046875 +13617 0.63763427734375 +13618 0.4033203125 +13619 0.5660400390625 +13620 0.3353271484375 +13621 0.4720458984375 +13622 0.287109375 +13623 0.40692138671875 +13624 0.263824462890625 +13625 0.3778076171875 +13626 0.260223388671875 +13627 0.376953125 +13628 0.25396728515625 +13629 0.371978759765625 +13630 0.2105712890625 +13631 0.313140869140625 +13632 0.1190185546875 +13633 0.184417724609375 +13634 -0.002899169921875 +13635 0.011199951171875 +13636 -0.130462646484375 +13637 -0.171051025390625 +13638 -0.246337890625 +13639 -0.33740234375 +13640 -0.339447021484375 +13641 -0.47198486328125 +13642 -0.39984130859375 +13643 -0.560394287109375 +13644 -0.4122314453125 +13645 -0.58056640625 +13646 -0.38720703125 +13647 -0.54754638671875 +13648 -0.357757568359375 +13649 -0.508575439453125 +13650 -0.321136474609375 +13651 -0.459503173828125 +13652 -0.273345947265625 +13653 -0.394378662109375 +13654 -0.241943359375 +13655 -0.35260009765625 +13656 -0.211395263671875 +13657 -0.31170654296875 +13658 -0.130096435546875 +13659 -0.197418212890625 +13660 0.0030517578125 +13661 -0.007965087890625 +13662 0.153778076171875 +13663 0.207489013671875 +13664 0.294403076171875 +13665 0.409210205078125 +13666 0.407470703125 +13667 0.57208251953125 +13668 0.47198486328125 +13669 0.66595458984375 +13670 0.4656982421875 +13671 0.65875244140625 +13672 0.4005126953125 +13673 0.56744384765625 +13674 0.303955078125 +13675 0.431396484375 +13676 0.206634521484375 +13677 0.29443359375 +13678 0.126678466796875 +13679 0.182464599609375 +13680 0.04205322265625 +13681 0.06365966796875 +13682 -0.056884765625 +13683 -0.075958251953125 +13684 -0.137359619140625 +13685 -0.189422607421875 +13686 -0.1959228515625 +13687 -0.271942138671875 +13688 -0.245758056640625 +13689 -0.342529296875 +13690 -0.2611083984375 +13691 -0.364166259765625 +13692 -0.23529052734375 +13693 -0.327239990234375 +13694 -0.19976806640625 +13695 -0.2769775390625 +13696 -0.182647705078125 +13697 -0.253692626953125 +13698 -0.1744384765625 +13699 -0.24365234375 +13700 -0.1414794921875 +13701 -0.1983642578125 +13702 -0.082733154296875 +13703 -0.116241455078125 +13704 -0.025787353515625 +13705 -0.036834716796875 +13706 0.0257568359375 +13707 0.034881591796875 +13708 0.066497802734375 +13709 0.09124755859375 +13710 0.080078125 +13711 0.10888671875 +13712 0.0926513671875 +13713 0.125518798828125 +13714 0.115753173828125 +13715 0.15771484375 +13716 0.13043212890625 +13717 0.17828369140625 +13718 0.12542724609375 +13719 0.17108154296875 +13720 0.09649658203125 +13721 0.129974365234375 +13722 0.062744140625 +13723 0.082427978515625 +13724 0.023712158203125 +13725 0.027679443359375 +13726 -0.0423583984375 +13727 -0.065643310546875 +13728 -0.10882568359375 +13729 -0.15936279296875 +13730 -0.14752197265625 +13731 -0.21307373046875 +13732 -0.163848876953125 +13733 -0.234649658203125 +13734 -0.14111328125 +13735 -0.2001953125 +13736 -0.0858154296875 +13737 -0.119171142578125 +13738 -0.02099609375 +13739 -0.024749755859375 +13740 0.055267333984375 +13741 0.085784912109375 +13742 0.119110107421875 +13743 0.178131103515625 +13744 0.14501953125 +13745 0.215576171875 +13746 0.142242431640625 +13747 0.211456298828125 +13748 0.117401123046875 +13749 0.17523193359375 +13750 0.085662841796875 +13751 0.128753662109375 +13752 0.06781005859375 +13753 0.1019287109375 +13754 0.049591064453125 +13755 0.0743408203125 +13756 0.029052734375 +13757 0.04327392578125 +13758 0.026611328125 +13759 0.038177490234375 +13760 0.054168701171875 +13761 0.076263427734375 +13762 0.100189208984375 +13763 0.14105224609375 +13764 0.132568359375 +13765 0.186431884765625 +13766 0.13482666015625 +13767 0.188812255859375 +13768 0.100555419921875 +13769 0.1390380859375 +13770 0.033050537109375 +13771 0.041778564453125 +13772 -0.05133056640625 +13773 -0.079437255859375 +13774 -0.148956298828125 +13775 -0.219390869140625 +13776 -0.252655029296875 +13777 -0.367828369140625 +13778 -0.34161376953125 +13779 -0.494873046875 +13780 -0.385009765625 +13781 -0.556243896484375 +13782 -0.352691650390625 +13783 -0.508697509765625 +13784 -0.2608642578125 +13785 -0.3756103515625 +13786 -0.152618408203125 +13787 -0.218902587890625 +13788 -0.045379638671875 +13789 -0.063751220703125 +13790 0.06201171875 +13791 0.091552734375 +13792 0.161956787109375 +13793 0.23602294921875 +13794 0.235931396484375 +13795 0.342987060546875 +13796 0.27197265625 +13797 0.39520263671875 +13798 0.267791748046875 +13799 0.389373779296875 +13800 0.2225341796875 +13801 0.324249267578125 +13802 0.153076171875 +13803 0.224090576171875 +13804 0.084014892578125 +13805 0.124267578125 +13806 0.023834228515625 +13807 0.037078857421875 +13808 -0.008392333984375 +13809 -0.010101318359375 +13810 -0.01422119140625 +13811 -0.019439697265625 +13812 -0.015869140625 +13813 -0.022796630859375 +13814 -0.000396728515625 +13815 -0.001556396484375 +13816 0.040496826171875 +13817 0.056304931640625 +13818 0.07611083984375 +13819 0.106719970703125 +13820 0.069671630859375 +13821 0.096893310546875 +13822 0.0322265625 +13823 0.042694091796875 +13824 -0.010223388671875 +13825 -0.018035888671875 +13826 -0.0509033203125 +13827 -0.07586669921875 +13828 -0.081329345703125 +13829 -0.11944580078125 +13830 -0.109619140625 +13831 -0.15972900390625 +13832 -0.140167236328125 +13833 -0.202606201171875 +13834 -0.173370361328125 +13835 -0.24859619140625 +13836 -0.2147216796875 +13837 -0.30517578125 +13838 -0.256805419921875 +13839 -0.36212158203125 +13840 -0.279205322265625 +13841 -0.39141845703125 +13842 -0.254302978515625 +13843 -0.35528564453125 +13844 -0.17926025390625 +13845 -0.249969482421875 +13846 -0.066680908203125 +13847 -0.092864990234375 +13848 0.063934326171875 +13849 0.08905029296875 +13850 0.168609619140625 +13851 0.2352294921875 +13852 0.2279052734375 +13853 0.318817138671875 +13854 0.255615234375 +13855 0.358642578125 +13856 0.246734619140625 +13857 0.347747802734375 +13858 0.200927734375 +13859 0.28564453125 +13860 0.155242919921875 +13861 0.223175048828125 +13862 0.136199951171875 +13863 0.196746826171875 +13864 0.124481201171875 +13865 0.179840087890625 +13866 0.107757568359375 +13867 0.155548095703125 +13868 0.1058349609375 +13869 0.151214599609375 +13870 0.1114501953125 +13871 0.156951904296875 +13872 0.09466552734375 +13873 0.13177490234375 +13874 0.07366943359375 +13875 0.100799560546875 +13876 0.065185546875 +13877 0.087127685546875 +13878 0.04302978515625 +13879 0.05487060546875 +13880 -0.002349853515625 +13881 -0.009002685546875 +13882 -0.07061767578125 +13883 -0.10400390625 +13884 -0.16131591796875 +13885 -0.229400634765625 +13886 -0.252899169921875 +13887 -0.35552978515625 +13888 -0.31585693359375 +13889 -0.441925048828125 +13890 -0.3394775390625 +13891 -0.473846435546875 +13892 -0.33355712890625 +13893 -0.464813232421875 +13894 -0.3011474609375 +13895 -0.419097900390625 +13896 -0.240447998046875 +13897 -0.334320068359375 +13898 -0.16412353515625 +13899 -0.227935791015625 +13900 -0.089263916015625 +13901 -0.12347412109375 +13902 -0.020660400390625 +13903 -0.02764892578125 +13904 0.054931640625 +13905 0.077667236328125 +13906 0.152679443359375 +13907 0.2132568359375 +13908 0.279693603515625 +13909 0.38885498046875 +13910 0.420257568359375 +13911 0.582794189453125 +13912 0.52996826171875 +13913 0.734039306640625 +13914 0.57794189453125 +13915 0.800140380859375 +13916 0.5621337890625 +13917 0.7783203125 +13918 0.480072021484375 +13919 0.6651611328125 +13920 0.331024169921875 +13921 0.45965576171875 +13922 0.14215087890625 +13923 0.199188232421875 +13924 -0.038848876953125 +13925 -0.050689697265625 +13926 -0.170562744140625 +13927 -0.23297119140625 +13928 -0.24029541015625 +13929 -0.33013916015625 +13930 -0.26715087890625 +13931 -0.368408203125 +13932 -0.27386474609375 +13933 -0.378936767578125 +13934 -0.271636962890625 +13935 -0.376983642578125 +13936 -0.27301025390625 +13937 -0.37969970703125 +13938 -0.281219482421875 +13939 -0.391510009765625 +13940 -0.276580810546875 +13941 -0.385345458984375 +13942 -0.245025634765625 +13943 -0.3419189453125 +13944 -0.202301025390625 +13945 -0.28289794921875 +13946 -0.179962158203125 +13947 -0.251617431640625 +13948 -0.19110107421875 +13949 -0.266143798828125 +13950 -0.197052001953125 +13951 -0.273345947265625 +13952 -0.15667724609375 +13953 -0.216796875 +13954 -0.093017578125 +13955 -0.128265380859375 +13956 -0.050018310546875 +13957 -0.068145751953125 +13958 -0.032501220703125 +13959 -0.0430908203125 +13960 -0.019561767578125 +13961 -0.024444580078125 +13962 0.0128173828125 +13963 0.020721435546875 +13964 0.087982177734375 +13965 0.124481201171875 +13966 0.184844970703125 +13967 0.25787353515625 +13968 0.27301025390625 +13969 0.379119873046875 +13970 0.346466064453125 +13971 0.47991943359375 +13972 0.3818359375 +13973 0.5281982421875 +13974 0.369781494140625 +13975 0.511138916015625 +13976 0.330291748046875 +13977 0.456207275390625 +13978 0.29541015625 +13979 0.407470703125 +13980 0.27880859375 +13981 0.383758544921875 +13982 0.259918212890625 +13983 0.35687255859375 +13984 0.227752685546875 +13985 0.31182861328125 +13986 0.1839599609375 +13987 0.250885009765625 +13988 0.1221923828125 +13989 0.1654052734375 +13990 0.027801513671875 +13991 0.035247802734375 +13992 -0.101043701171875 +13993 -0.142059326171875 +13994 -0.241851806640625 +13995 -0.33563232421875 +13996 -0.38665771484375 +13997 -0.5345458984375 +13998 -0.52313232421875 +13999 -0.72186279296875 +14000 -0.606903076171875 +14001 -0.836669921875 +14002 -0.604278564453125 +14003 -0.8326416015625 +14004 -0.5296630859375 +14005 -0.7296142578125 +14006 -0.42303466796875 +14007 -0.582550048828125 +14008 -0.319793701171875 +14009 -0.440093994140625 +14010 -0.235992431640625 +14011 -0.324310302734375 +14012 -0.14703369140625 +14013 -0.20147705078125 +14014 -0.03326416015625 +14015 -0.044647216796875 +14016 0.0745849609375 +14017 0.103973388671875 +14018 0.145965576171875 +14019 0.202392578125 +14020 0.19097900390625 +14021 0.264495849609375 +14022 0.245025634765625 +14023 0.338897705078125 +14024 0.321380615234375 +14025 0.443817138671875 +14026 0.395172119140625 +14027 0.545074462890625 +14028 0.447906494140625 +14029 0.6173095703125 +14030 0.473724365234375 +14031 0.6524658203125 +14032 0.481964111328125 +14033 0.66339111328125 +14034 0.477020263671875 +14035 0.6561279296875 +14036 0.441436767578125 +14037 0.606781005859375 +14038 0.364898681640625 +14039 0.501190185546875 +14040 0.25714111328125 +14041 0.352783203125 +14042 0.12908935546875 +14043 0.176544189453125 +14044 -0.024566650390625 +14045 -0.034820556640625 +14046 -0.18701171875 +14047 -0.258209228515625 +14048 -0.321014404296875 +14049 -0.44244384765625 +14050 -0.417633056640625 +14051 -0.5753173828125 +14052 -0.473419189453125 +14053 -0.65203857421875 +14054 -0.4658203125 +14055 -0.641632080078125 +14056 -0.40802001953125 +14057 -0.562164306640625 +14058 -0.33233642578125 +14059 -0.458038330078125 +14060 -0.254241943359375 +14061 -0.350555419921875 +14062 -0.18890380859375 +14063 -0.260528564453125 +14064 -0.13934326171875 +14065 -0.192108154296875 +14066 -0.103118896484375 +14067 -0.141937255859375 +14068 -0.074493408203125 +14069 -0.1021728515625 +14070 -0.04620361328125 +14071 -0.062896728515625 +14072 -0.009368896484375 +14073 -0.011932373046875 +14074 0.044830322265625 +14075 0.062835693359375 +14076 0.107177734375 +14077 0.148712158203125 +14078 0.1748046875 +14079 0.241729736328125 +14080 0.253265380859375 +14081 0.34912109375 +14082 0.33343505859375 +14083 0.457305908203125 +14084 0.398895263671875 +14085 0.54388427734375 +14086 0.4219970703125 +14087 0.5728759765625 +14088 0.37371826171875 +14089 0.506591796875 +14090 0.258453369140625 +14091 0.351226806640625 +14092 0.106109619140625 +14093 0.146514892578125 +14094 -0.043853759765625 +14095 -0.05523681640625 +14096 -0.1629638671875 +14097 -0.21624755859375 +14098 -0.25018310546875 +14099 -0.334930419921875 +14100 -0.299407958984375 +14101 -0.402984619140625 +14102 -0.326568603515625 +14103 -0.4412841796875 +14104 -0.366668701171875 +14105 -0.49578857421875 +14106 -0.41497802734375 +14107 -0.5601806640625 +14108 -0.445831298828125 +14109 -0.600738525390625 +14110 -0.4339599609375 +14111 -0.584228515625 +14112 -0.355438232421875 +14113 -0.47930908203125 +14114 -0.20513916015625 +14115 -0.27935791015625 +14116 -0.001617431640625 +14117 -0.0089111328125 +14118 0.207183837890625 +14119 0.268798828125 +14120 0.36749267578125 +14121 0.482818603515625 +14122 0.457061767578125 +14123 0.60369873046875 +14124 0.490386962890625 +14125 0.650421142578125 +14126 0.498809814453125 +14127 0.66400146484375 +14128 0.48016357421875 +14129 0.6414794921875 +14130 0.42669677734375 +14131 0.572540283203125 +14132 0.36956787109375 +14133 0.498138427734375 +14134 0.32489013671875 +14135 0.439453125 +14136 0.2767333984375 +14137 0.375518798828125 +14138 0.200836181640625 +14139 0.274505615234375 +14140 0.076141357421875 +14141 0.1087646484375 +14142 -0.080474853515625 +14143 -0.099395751953125 +14144 -0.244964599609375 +14145 -0.3182373046875 +14146 -0.418365478515625 +14147 -0.5489501953125 +14148 -0.5872802734375 +14149 -0.7738037109375 +14150 -0.711578369140625 +14151 -0.86383056640625 +14152 -0.766082763671875 +14153 -0.870391845703125 +14154 -0.76434326171875 +14155 -0.86895751953125 +14156 -0.716400146484375 +14157 -0.861053466796875 +14158 -0.60919189453125 +14159 -0.765869140625 +14160 -0.434173583984375 +14161 -0.5301513671875 +14162 -0.19671630859375 +14163 -0.214691162109375 +14164 0.070465087890625 +14165 0.137359619140625 +14166 0.328399658203125 +14167 0.474822998046875 +14168 0.550140380859375 +14169 0.76239013671875 +14170 0.715240478515625 +14171 0.867462158203125 +14172 0.8240966796875 +14173 0.870361328125 +14174 0.85595703125 +14175 0.86480712890625 +14176 0.851287841796875 +14177 0.831817626953125 +14178 0.792327880859375 +14179 0.677581787109375 +14180 0.695709228515625 +14181 0.495880126953125 +14182 0.5755615234375 +14183 0.30767822265625 +14184 0.433624267578125 +14185 0.116180419921875 +14186 0.245849609375 +14187 -0.110748291015625 +14188 0.0069580078125 +14189 -0.381805419921875 +14190 -0.25048828125 +14191 -0.6572265625 +14192 -0.48101806640625 +14193 -0.857421875 +14194 -0.652008056640625 +14195 -0.870391845703125 +14196 -0.758056640625 +14197 -0.870391845703125 +14198 -0.8197021484375 +14199 -0.86444091796875 +14200 -0.855560302734375 +14201 -0.85723876953125 +14202 -0.85699462890625 +14203 -0.790008544921875 +14204 -0.818389892578125 +14205 -0.62847900390625 +14206 -0.684783935546875 +14207 -0.3956298828125 +14208 -0.5015869140625 +14209 -0.126708984375 +14210 -0.2896728515625 +14211 0.150115966796875 +14212 -0.0579833984375 +14213 0.424041748046875 +14214 0.1729736328125 +14215 0.670623779296875 +14216 0.373748779296875 +14217 0.854522705078125 +14218 0.530914306640625 +14219 0.866485595703125 +14220 0.63275146484375 +14221 0.86920166015625 +14222 0.693084716796875 +14223 0.8653564453125 +14224 0.722137451171875 +14225 0.857147216796875 +14226 0.71771240234375 +14227 0.766845703125 +14228 0.6837158203125 +14229 0.628509521484375 +14230 0.615081787109375 +14231 0.462127685546875 +14232 0.531494140625 +14233 0.297210693359375 +14234 0.442474365234375 +14235 0.14862060546875 +14236 0.3306884765625 +14237 -0.00537109375 +14238 0.201873779296875 +14239 -0.15753173828125 +14240 0.053314208984375 +14241 -0.31304931640625 +14242 -0.125579833984375 +14243 -0.48876953125 +14244 -0.299163818359375 +14245 -0.6416015625 +14246 -0.4486083984375 +14247 -0.751373291015625 +14248 -0.591461181640625 +14249 -0.84619140625 +14250 -0.716552734375 +14251 -0.861297607421875 +14252 -0.7987060546875 +14253 -0.863250732421875 +14254 -0.813934326171875 +14255 -0.856597900390625 +14256 -0.771514892578125 +14257 -0.7498779296875 +14258 -0.7154541015625 +14259 -0.624542236328125 +14260 -0.62908935546875 +14261 -0.47808837890625 +14262 -0.468017578125 +14263 -0.253387451171875 +14264 -0.26702880859375 +14265 0.003692626953125 +14266 -0.078125 +14267 0.2257080078125 +14268 0.108184814453125 +14269 0.427154541015625 +14270 0.316436767578125 +14271 0.643218994140625 +14272 0.539276123046875 +14273 0.855926513671875 +14274 0.73260498046875 +14275 0.870361328125 +14276 0.854949951171875 +14277 0.870361328125 +14278 0.8619384765625 +14279 0.862762451171875 +14280 0.861968994140625 +14281 0.79669189453125 +14282 0.852203369140625 +14283 0.595794677734375 +14284 0.732208251953125 +14285 0.362152099609375 +14286 0.5845947265625 +14287 0.1270751953125 +14288 0.425506591796875 +14289 -0.086944580078125 +14290 0.256561279296875 +14291 -0.2784423828125 +14292 0.051422119140625 +14293 -0.484832763671875 +14294 -0.204376220703125 +14295 -0.729583740234375 +14296 -0.472259521484375 +14297 -0.86688232421875 +14298 -0.704010009765625 +14299 -0.870391845703125 +14300 -0.8590087890625 +14301 -0.86859130859375 +14302 -0.870391845703125 +14303 -0.86279296875 +14304 -0.870391845703125 +14305 -0.817962646484375 +14306 -0.860076904296875 +14307 -0.6116943359375 +14308 -0.714996337890625 +14309 -0.3128662109375 +14310 -0.45672607421875 +14311 0.039398193359375 +14312 -0.14794921875 +14313 0.422821044921875 +14314 0.18505859375 +14315 0.805145263671875 +14316 0.490570068359375 +14317 0.870361328125 +14318 0.726226806640625 +14319 0.870361328125 +14320 0.857818603515625 +14321 0.860015869140625 +14322 0.866363525390625 +14323 0.727935791015625 +14324 0.8660888671875 +14325 0.48114013671875 +14326 0.85931396484375 +14327 0.2059326171875 +14328 0.79827880859375 +14329 -0.06103515625 +14330 0.67071533203125 +14331 -0.29913330078125 +14332 0.508636474609375 +14333 -0.516204833984375 +14334 0.303466796875 +14335 -0.7252197265625 +14336 0.076995849609375 +14337 -0.85980224609375 +14338 -0.14306640625 +14339 -0.870391845703125 +14340 -0.3330078125 +14341 -0.870391845703125 +14342 -0.453765869140625 +14343 -0.858062744140625 +14344 -0.502288818359375 +14345 -0.673004150390625 +14346 -0.52117919921875 +14347 -0.42694091796875 +14348 -0.547210693359375 +14349 -0.2100830078125 +14350 -0.58087158203125 +14351 -0.0362548828125 +14352 -0.60174560546875 +14353 0.10943603515625 +14354 -0.59686279296875 +14355 0.23516845703125 +14356 -0.53631591796875 +14357 0.373687744140625 +14358 -0.4244384765625 +14359 0.517791748046875 +14360 -0.313690185546875 +14361 0.602783203125 +14362 -0.202178955078125 +14363 0.635711669921875 +14364 -0.065216064453125 +14365 0.655181884765625 +14366 0.088134765625 +14367 0.65948486328125 +14368 0.2509765625 +14369 0.651275634765625 +14370 0.403900146484375 +14371 0.61846923828125 +14372 0.51824951171875 +14373 0.53753662109375 +14374 0.580902099609375 +14375 0.404144287109375 +14376 0.585784912109375 +14377 0.22186279296875 +14378 0.535858154296875 +14379 0.003997802734375 +14380 0.44769287109375 +14381 -0.22100830078125 +14382 0.339996337890625 +14383 -0.42449951171875 +14384 0.232025146484375 +14385 -0.579833984375 +14386 0.159820556640625 +14387 -0.641876220703125 +14388 0.12005615234375 +14389 -0.6177978515625 +14390 0.063140869140625 +14391 -0.575531005859375 +14392 -0.01397705078125 +14393 -0.526336669921875 +14394 -0.069610595703125 +14395 -0.42645263671875 +14396 -0.081817626953125 +14397 -0.2581787109375 +14398 -0.0797119140625 +14399 -0.068695068359375 +14400 -0.094573974609375 +14401 0.09222412109375 +14402 -0.112823486328125 +14403 0.232147216796875 +14404 -0.12786865234375 +14405 0.3509521484375 +14406 -0.164886474609375 +14407 0.410064697265625 +14408 -0.248992919921875 +14409 0.372955322265625 +14410 -0.365447998046875 +14411 0.2554931640625 +14412 -0.4747314453125 +14413 0.10711669921875 +14414 -0.562957763671875 +14415 -0.052886962890625 +14416 -0.602813720703125 +14417 -0.186279296875 +14418 -0.551025390625 +14419 -0.23291015625 +14420 -0.42626953125 +14421 -0.209442138671875 +14422 -0.281005859375 +14423 -0.174163818359375 +14424 -0.1217041015625 +14425 -0.126739501953125 +14426 0.059906005859375 +14427 -0.048126220703125 +14428 0.2423095703125 +14429 0.0426025390625 +14430 0.389678955078125 +14431 0.10748291015625 +14432 0.49285888671875 +14433 0.1409912109375 +14434 0.590911865234375 +14435 0.19708251953125 +14436 0.679962158203125 +14437 0.273651123046875 +14438 0.717193603515625 +14439 0.31768798828125 +14440 0.712646484375 +14441 0.341094970703125 +14442 0.687408447265625 +14443 0.368011474609375 +14444 0.6241455078125 +14445 0.37249755859375 +14446 0.484466552734375 +14447 0.30072021484375 +14448 0.2725830078125 +14449 0.1517333984375 +14450 0.041229248046875 +14451 -0.01470947265625 +14452 -0.195831298828125 +14453 -0.1883544921875 +14454 -0.43597412109375 +14455 -0.372711181640625 +14456 -0.631622314453125 +14457 -0.51397705078125 +14458 -0.746490478515625 +14459 -0.57177734375 +14460 -0.772003173828125 +14461 -0.53948974609375 +14462 -0.72015380859375 +14463 -0.43511962890625 +14464 -0.61962890625 +14465 -0.2962646484375 +14466 -0.500762939453125 +14467 -0.161102294921875 +14468 -0.3758544921875 +14469 -0.0435791015625 +14470 -0.24395751953125 +14471 0.060394287109375 +14472 -0.1195068359375 +14473 0.13665771484375 +14474 -0.018310546875 +14475 0.170135498046875 +14476 0.058929443359375 +14477 0.16552734375 +14478 0.1348876953125 +14479 0.15728759765625 +14480 0.209320068359375 +14481 0.150787353515625 +14482 0.2589111328125 +14483 0.12200927734375 +14484 0.28717041015625 +14485 0.080108642578125 +14486 0.311798095703125 +14487 0.05126953125 +14488 0.35235595703125 +14489 0.062896728515625 +14490 0.389923095703125 +14491 0.09271240234375 +14492 0.386444091796875 +14493 0.092987060546875 +14494 0.3543701171875 +14495 0.07855224609375 +14496 0.30706787109375 +14497 0.06427001953125 +14498 0.23480224609375 +14499 0.0347900390625 +14500 0.139129638671875 +14501 -0.01171875 +14502 0.038726806640625 +14503 -0.056060791015625 +14504 -0.028778076171875 +14505 -0.055511474609375 +14506 -0.05987548828125 +14507 -0.010467529296875 +14508 -0.09368896484375 +14509 0.02508544921875 +14510 -0.147186279296875 +14511 0.025665283203125 +14512 -0.197021484375 +14513 0.017333984375 +14514 -0.23974609375 +14515 0.00189208984375 +14516 -0.2828369140625 +14517 -0.03173828125 +14518 -0.3162841796875 +14519 -0.071502685546875 +14520 -0.35467529296875 +14521 -0.13543701171875 +14522 -0.396240234375 +14523 -0.219970703125 +14524 -0.423248291015625 +14525 -0.300506591796875 +14526 -0.437469482421875 +14527 -0.376312255859375 +14528 -0.4168701171875 +14529 -0.416107177734375 +14530 -0.325836181640625 +14531 -0.371124267578125 +14532 -0.168212890625 +14533 -0.242279052734375 +14534 0.021148681640625 +14535 -0.069732666015625 +14536 0.222869873046875 +14537 0.125640869140625 +14538 0.409912109375 +14539 0.31268310546875 +14540 0.55157470703125 +14541 0.45501708984375 +14542 0.648284912109375 +14543 0.554779052734375 +14544 0.698333740234375 +14545 0.61065673828125 +14546 0.692474365234375 +14547 0.610931396484375 +14548 0.612274169921875 +14549 0.531463623046875 +14550 0.471710205078125 +14551 0.3883056640625 +14552 0.314697265625 +14553 0.23468017578125 +14554 0.162933349609375 +14555 0.095245361328125 +14556 0.0394287109375 +14557 -0.00396728515625 +14558 -0.041839599609375 +14559 -0.04852294921875 +14560 -0.091522216796875 +14561 -0.055145263671875 +14562 -0.1484375 +14563 -0.0758056640625 +14564 -0.232818603515625 +14565 -0.138702392578125 +14566 -0.315521240234375 +14567 -0.209197998046875 +14568 -0.39666748046875 +14569 -0.289031982421875 +14570 -0.476043701171875 +14571 -0.37884521484375 +14572 -0.535797119140625 +14573 -0.456329345703125 +14574 -0.57232666015625 +14575 -0.51641845703125 +14576 -0.554962158203125 +14577 -0.519287109375 +14578 -0.479736328125 +14579 -0.458251953125 +14580 -0.389068603515625 +14581 -0.384796142578125 +14582 -0.30450439453125 +14583 -0.323699951171875 +14584 -0.2236328125 +14585 -0.269287109375 +14586 -0.127716064453125 +14587 -0.1951904296875 +14588 -0.01763916015625 +14589 -0.100006103515625 +14590 0.083526611328125 +14591 -0.01055908203125 +14592 0.1983642578125 +14593 0.1033935546875 +14594 0.331390380859375 +14595 0.24908447265625 +14596 0.439300537109375 +14597 0.373199462890625 +14598 0.507781982421875 +14599 0.45806884765625 +14600 0.543304443359375 +14601 0.511474609375 +14602 0.5721435546875 +14603 0.565399169921875 +14604 0.588531494140625 +14605 0.61138916015625 +14606 0.545989990234375 +14607 0.5897216796875 +14608 0.438201904296875 +14609 0.4906005859375 +14610 0.280792236328125 +14611 0.33148193359375 +14612 0.103759765625 +14613 0.147796630859375 +14614 -0.057861328125 +14615 -0.01873779296875 +14616 -0.180328369140625 +14617 -0.140289306640625 +14618 -0.242462158203125 +14619 -0.191986083984375 +14620 -0.251617431640625 +14621 -0.184295654296875 +14622 -0.24285888671875 +14623 -0.161834716796875 +14624 -0.249420166015625 +14625 -0.166595458984375 +14626 -0.267578125 +14627 -0.19390869140625 +14628 -0.282257080078125 +14629 -0.22442626953125 +14630 -0.311431884765625 +14631 -0.279754638671875 +14632 -0.33941650390625 +14633 -0.3389892578125 +14634 -0.32916259765625 +14635 -0.3543701171875 +14636 -0.2998046875 +14637 -0.348175048828125 +14638 -0.257171630859375 +14639 -0.32598876953125 +14640 -0.178955078125 +14641 -0.2581787109375 +14642 -0.062469482421875 +14643 -0.139801025390625 +14644 0.079559326171875 +14645 0.014617919921875 +14646 0.1976318359375 +14647 0.144378662109375 +14648 0.268341064453125 +14649 0.221038818359375 +14650 0.31219482421875 +14651 0.27069091796875 +14652 0.329681396484375 +14653 0.294036865234375 +14654 0.337554931640625 +14655 0.311767578125 +14656 0.348602294921875 +14657 0.339141845703125 +14658 0.351104736328125 +14659 0.360260009765625 +14660 0.334228515625 +14661 0.360504150390625 +14662 0.27288818359375 +14663 0.308380126953125 +14664 0.149749755859375 +14665 0.18170166015625 +14666 -0.014129638671875 +14667 0.0047607421875 +14668 -0.179290771484375 +14669 -0.17559814453125 +14670 -0.30780029296875 +14671 -0.3143310546875 +14672 -0.363067626953125 +14673 -0.36785888671875 +14674 -0.3662109375 +14675 -0.36248779296875 +14676 -0.354278564453125 +14677 -0.343536376953125 +14678 -0.3197021484375 +14679 -0.3018798828125 +14680 -0.257568359375 +14681 -0.231414794921875 +14682 -0.15625 +14683 -0.117645263671875 +14684 -0.04290771484375 +14685 0.007049560546875 +14686 0.036712646484375 +14687 0.087982177734375 +14688 0.093658447265625 +14689 0.13946533203125 +14690 0.137603759765625 +14691 0.17425537109375 +14692 0.16424560546875 +14693 0.188201904296875 +14694 0.164459228515625 +14695 0.171234130859375 +14696 0.13348388671875 +14697 0.118438720703125 +14698 0.0931396484375 +14699 0.05706787109375 +14700 0.044677734375 +14701 -0.010711669921875 +14702 -0.017578125 +14703 -0.0914306640625 +14704 -0.074981689453125 +14705 -0.162322998046875 +14706 -0.103759765625 +14707 -0.194549560546875 +14708 -0.071746826171875 +14709 -0.1492919921875 +14710 0.02545166015625 +14711 -0.02166748046875 +14712 0.13543701171875 +14713 0.124053955078125 +14714 0.19561767578125 +14715 0.211151123046875 +14716 0.20733642578125 +14717 0.240447998046875 +14718 0.196197509765625 +14719 0.242218017578125 +14720 0.170562744140625 +14721 0.2257080078125 +14722 0.1339111328125 +14723 0.194366455078125 +14724 0.059844970703125 +14725 0.115509033203125 +14726 -0.031646728515625 +14727 0.0128173828125 +14728 -0.090911865234375 +14729 -0.053802490234375 +14730 -0.139434814453125 +14731 -0.110626220703125 +14732 -0.211700439453125 +14733 -0.199493408203125 +14734 -0.286376953125 +14735 -0.29437255859375 +14736 -0.311767578125 +14737 -0.33221435546875 +14738 -0.26080322265625 +14739 -0.27972412109375 +14740 -0.17388916015625 +14741 -0.185333251953125 +14742 -0.11676025390625 +14743 -0.128204345703125 +14744 -0.096038818359375 +14745 -0.115692138671875 +14746 -0.086517333984375 +14747 -0.116455078125 +14748 -0.0684814453125 +14749 -0.105926513671875 +14750 -0.017578125 +14751 -0.053955078125 +14752 0.073455810546875 +14753 0.048797607421875 +14754 0.167236328125 +14755 0.157318115234375 +14756 0.214508056640625 +14757 0.212005615234375 +14758 0.219818115234375 +14759 0.218475341796875 +14760 0.23309326171875 +14761 0.23724365234375 +14762 0.2850341796875 +14763 0.30535888671875 +14764 0.341705322265625 +14765 0.38128662109375 +14766 0.35357666015625 +14767 0.404449462890625 +14768 0.337158203125 +14769 0.3944091796875 +14770 0.32373046875 +14771 0.3885498046875 +14772 0.29388427734375 +14773 0.362640380859375 +14774 0.2125244140625 +14775 0.27362060546875 +14776 0.076507568359375 +14777 0.11712646484375 +14778 -0.07098388671875 +14779 -0.054901123046875 +14780 -0.1871337890625 +14781 -0.19085693359375 +14782 -0.26763916015625 +14783 -0.28570556640625 +14784 -0.31231689453125 +14785 -0.339263916015625 +14786 -0.342620849609375 +14787 -0.3775634765625 +14788 -0.395843505859375 +14789 -0.445709228515625 +14790 -0.465057373046875 +14791 -0.535064697265625 +14792 -0.536895751953125 +14793 -0.629058837890625 +14794 -0.586944580078125 +14795 -0.697601318359375 +14796 -0.585235595703125 +14797 -0.70391845703125 +14798 -0.527587890625 +14799 -0.6424560546875 +14800 -0.39630126953125 +14801 -0.491241455078125 +14802 -0.20440673828125 +14803 -0.265716552734375 +14804 9.1552734375e-05 +14805 -0.023712158203125 +14806 0.189727783203125 +14807 0.201751708984375 +14808 0.33563232421875 +14809 0.375823974609375 +14810 0.4266357421875 +14811 0.485076904296875 +14812 0.495147705078125 +14813 0.56884765625 +14814 0.54754638671875 +14815 0.634765625 +14816 0.546722412109375 +14817 0.63763427734375 +14818 0.483428955078125 +14819 0.5660400390625 +14820 0.400848388671875 +14821 0.4720458984375 +14822 0.341552734375 +14823 0.40692138671875 +14824 0.311737060546875 +14825 0.3778076171875 +14826 0.30535888671875 +14827 0.376953125 +14828 0.2960205078125 +14829 0.371978759765625 +14830 0.243011474609375 +14831 0.313140869140625 +14832 0.13336181640625 +14833 0.184417724609375 +14834 -0.01177978515625 +14835 0.011199951171875 +14836 -0.16314697265625 +14837 -0.171051025390625 +14838 -0.3001708984375 +14839 -0.33740234375 +14840 -0.4097900390625 +14841 -0.47198486328125 +14842 -0.480255126953125 +14843 -0.560394287109375 +14844 -0.493560791015625 +14845 -0.58056640625 +14846 -0.462310791015625 +14847 -0.54754638671875 +14848 -0.42578125 +14849 -0.508575439453125 +14850 -0.380584716796875 +14851 -0.459503173828125 +14852 -0.32232666015625 +14853 -0.394378662109375 +14854 -0.284881591796875 +14855 -0.35260009765625 +14856 -0.24908447265625 +14857 -0.31170654296875 +14858 -0.151397705078125 +14859 -0.197418212890625 +14860 0.00970458984375 +14861 -0.007965087890625 +14862 0.19219970703125 +14863 0.207489013671875 +14864 0.3621826171875 +14865 0.409210205078125 +14866 0.498321533203125 +14867 0.57208251953125 +14868 0.574981689453125 +14869 0.66595458984375 +14870 0.56494140625 +14871 0.65875244140625 +14872 0.48291015625 +14873 0.56744384765625 +14874 0.362823486328125 +14875 0.431396484375 +14876 0.242401123046875 +14877 0.29443359375 +14878 0.14398193359375 +14879 0.182464599609375 +14880 0.04046630859375 +14881 0.06365966796875 +14882 -0.080047607421875 +14883 -0.075958251953125 +14884 -0.17730712890625 +14885 -0.189422607421875 +14886 -0.24725341796875 +14887 -0.271942138671875 +14888 -0.306182861328125 +14889 -0.342529296875 +14890 -0.322540283203125 +14891 -0.364166259765625 +14892 -0.288238525390625 +14893 -0.327239990234375 +14894 -0.242156982421875 +14895 -0.2769775390625 +14896 -0.218994140625 +14897 -0.253692626953125 +14898 -0.2071533203125 +14899 -0.24365234375 +14900 -0.165313720703125 +14901 -0.1983642578125 +14902 -0.09228515625 +14903 -0.116241455078125 +14904 -0.02203369140625 +14905 -0.036834716796875 +14906 0.041046142578125 +14907 0.034881591796875 +14908 0.090301513671875 +14909 0.09124755859375 +14910 0.105743408203125 +14911 0.10888671875 +14912 0.11962890625 +14913 0.125518798828125 +14914 0.146209716796875 +14915 0.15771484375 +14916 0.1622314453125 +14917 0.17828369140625 +14918 0.153961181640625 +14919 0.17108154296875 +14920 0.1163330078125 +14921 0.129974365234375 +14922 0.072967529296875 +14923 0.082427978515625 +14924 0.023406982421875 +14925 0.027679443359375 +14926 -0.059051513671875 +14927 -0.065643310546875 +14928 -0.141571044921875 +14929 -0.15936279296875 +14930 -0.189483642578125 +14931 -0.21307373046875 +14932 -0.209442138671875 +14933 -0.234649658203125 +14934 -0.180908203125 +14935 -0.2001953125 +14936 -0.111968994140625 +14937 -0.119171142578125 +14938 -0.031005859375 +14939 -0.024749755859375 +14940 0.06427001953125 +14941 0.085784912109375 +14942 0.14447021484375 +14943 0.178131103515625 +14944 0.1781005859375 +14945 0.215576171875 +14946 0.176422119140625 +14947 0.211456298828125 +14948 0.147430419921875 +14949 0.17523193359375 +14950 0.1097412109375 +14951 0.128753662109375 +14952 0.088836669921875 +14953 0.1019287109375 +14954 0.067169189453125 +14955 0.0743408203125 +14956 0.04229736328125 +14957 0.04327392578125 +14958 0.039337158203125 +14959 0.038177490234375 +14960 0.07293701171875 +14961 0.076263427734375 +14962 0.128936767578125 +14963 0.14105224609375 +14964 0.167877197265625 +14965 0.186431884765625 +14966 0.1695556640625 +14967 0.188812255859375 +14968 0.126129150390625 +14969 0.1390380859375 +14970 0.04168701171875 +14971 0.041778564453125 +14972 -0.06353759765625 +14973 -0.079437255859375 +14974 -0.18499755859375 +14975 -0.219390869140625 +14976 -0.31378173828125 +14977 -0.367828369140625 +14978 -0.42425537109375 +14979 -0.494873046875 +14980 -0.478424072265625 +14981 -0.556243896484375 +14982 -0.439178466796875 +14983 -0.508697509765625 +14984 -0.326446533203125 +14985 -0.3756103515625 +14986 -0.193206787109375 +14987 -0.218902587890625 +14988 -0.060943603515625 +14989 -0.063751220703125 +14990 0.07177734375 +14991 0.091552734375 +14992 0.195587158203125 +14993 0.23602294921875 +14994 0.287628173828125 +14995 0.342987060546875 +14996 0.3331298828125 +14997 0.39520263671875 +14998 0.329193115234375 +14999 0.389373779296875 +15000 0.27471923828125 +15001 0.324249267578125 +15002 0.19036865234375 +15003 0.224090576171875 +15004 0.106353759765625 +15005 0.124267578125 +15006 0.0330810546875 +15007 0.037078857421875 +15008 -0.00604248046875 +15009 -0.010101318359375 +15010 -0.012969970703125 +15011 -0.019439697265625 +15012 -0.014984130859375 +15013 -0.022796630859375 +15014 0.003753662109375 +15015 -0.001556396484375 +15016 0.053558349609375 +15017 0.056304931640625 +15018 0.096710205078125 +15019 0.106719970703125 +15020 0.087982177734375 +15021 0.096893310546875 +15022 0.041015625 +15023 0.042694091796875 +15024 -0.011749267578125 +15025 -0.018035888671875 +15026 -0.06219482421875 +15027 -0.07586669921875 +15028 -0.100555419921875 +15029 -0.11944580078125 +15030 -0.13616943359375 +15031 -0.15972900390625 +15032 -0.17401123046875 +15033 -0.202606201171875 +15034 -0.21441650390625 +15035 -0.24859619140625 +15036 -0.26373291015625 +15037 -0.30517578125 +15038 -0.31317138671875 +15039 -0.36212158203125 +15040 -0.338775634765625 +15041 -0.39141845703125 +15042 -0.308135986328125 +15043 -0.35528564453125 +15044 -0.218048095703125 +15045 -0.249969482421875 +15046 -0.083404541015625 +15047 -0.092864990234375 +15048 0.07269287109375 +15049 0.08905029296875 +15050 0.1983642578125 +15051 0.2352294921875 +15052 0.270599365234375 +15053 0.318817138671875 +15054 0.30548095703125 +15055 0.358642578125 +15056 0.2969970703125 +15057 0.347747802734375 +15058 0.24468994140625 +15059 0.28564453125 +15060 0.192047119140625 +15061 0.223175048828125 +15062 0.170166015625 +15063 0.196746826171875 +15064 0.156341552734375 +15065 0.179840087890625 +15066 0.136077880859375 +15067 0.155548095703125 +15068 0.13275146484375 +15069 0.151214599609375 +15070 0.13787841796875 +15071 0.156951904296875 +15072 0.116302490234375 +15073 0.13177490234375 +15074 0.089569091796875 +15075 0.100799560546875 +15076 0.07745361328125 +15077 0.087127685546875 +15078 0.049285888671875 +15079 0.05487060546875 +15080 -0.00604248046875 +15081 -0.009002685546875 +15082 -0.08807373046875 +15083 -0.10400390625 +15084 -0.196136474609375 +15085 -0.229400634765625 +15086 -0.3048095703125 +15087 -0.35552978515625 +15088 -0.37939453125 +15089 -0.441925048828125 +15090 -0.40728759765625 +15091 -0.473846435546875 +15092 -0.39996337890625 +15093 -0.464813232421875 +15094 -0.361114501953125 +15095 -0.419097900390625 +15096 -0.288665771484375 +15097 -0.334320068359375 +15098 -0.19757080078125 +15099 -0.227935791015625 +15100 -0.10797119140625 +15101 -0.12347412109375 +15102 -0.025634765625 +15103 -0.02764892578125 +15104 0.06488037109375 +15105 0.077667236328125 +15106 0.181610107421875 +15107 0.2132568359375 +15108 0.333648681640625 +15109 0.38885498046875 +15110 0.502349853515625 +15111 0.582794189453125 +15112 0.634002685546875 +15113 0.734039306640625 +15114 0.691253662109375 +15115 0.800140380859375 +15116 0.6717529296875 +15117 0.7783203125 +15118 0.572509765625 +15119 0.6651611328125 +15120 0.392486572265625 +15121 0.45965576171875 +15122 0.16473388671875 +15123 0.199188232421875 +15124 -0.05279541015625 +15125 -0.050689697265625 +15126 -0.20977783203125 +15127 -0.23297119140625 +15128 -0.291015625 +15129 -0.33013916015625 +15130 -0.320098876953125 +15131 -0.368408203125 +15132 -0.324951171875 +15133 -0.378936767578125 +15134 -0.319427490234375 +15135 -0.376983642578125 +15136 -0.319000244140625 +15137 -0.37969970703125 +15138 -0.32769775390625 +15139 -0.391510009765625 +15140 -0.32159423828125 +15141 -0.385345458984375 +15142 -0.283538818359375 +15143 -0.3419189453125 +15144 -0.23272705078125 +15145 -0.28289794921875 +15146 -0.207550048828125 +15147 -0.251617431640625 +15148 -0.223846435546875 +15149 -0.266143798828125 +15150 -0.2342529296875 +15151 -0.273345947265625 +15152 -0.18841552734375 +15153 -0.216796875 +15154 -0.1142578125 +15155 -0.128265380859375 +15156 -0.065185546875 +15157 -0.068145751953125 +15158 -0.046875 +15159 -0.0430908203125 +15160 -0.03369140625 +15161 -0.024444580078125 +15162 0.0037841796875 +15163 0.020721435546875 +15164 0.09417724609375 +15165 0.124481201171875 +15166 0.211822509765625 +15167 0.25787353515625 +15168 0.319610595703125 +15169 0.379119873046875 +15170 0.410186767578125 +15171 0.47991943359375 +15172 0.4549560546875 +15173 0.5281982421875 +15174 0.44244384765625 +15175 0.511138916015625 +15176 0.3968505859375 +15177 0.456207275390625 +15178 0.357147216796875 +15179 0.407470703125 +15180 0.339813232421875 +15181 0.383758544921875 +15182 0.319610595703125 +15183 0.35687255859375 +15184 0.283050537109375 +15185 0.31182861328125 +15186 0.231903076171875 +15187 0.250885009765625 +15188 0.158355712890625 +15189 0.1654052734375 +15190 0.04443359375 +15191 0.035247802734375 +15192 -0.112091064453125 +15193 -0.142059326171875 +15194 -0.283843994140625 +15195 -0.33563232421875 +15196 -0.461090087890625 +15197 -0.5345458984375 +15198 -0.628753662109375 +15199 -0.72186279296875 +15200 -0.732635498046875 +15201 -0.836669921875 +15202 -0.73150634765625 +15203 -0.8326416015625 +15204 -0.642852783203125 +15205 -0.7296142578125 +15206 -0.5152587890625 +15207 -0.582550048828125 +15208 -0.39178466796875 +15209 -0.440093994140625 +15210 -0.2918701171875 +15211 -0.324310302734375 +15212 -0.1854248046875 +15213 -0.20147705078125 +15214 -0.048309326171875 +15215 -0.044647216796875 +15216 0.08203125 +15217 0.103973388671875 +15218 0.168426513671875 +15219 0.202392578125 +15220 0.22320556640625 +15221 0.264495849609375 +15222 0.28955078125 +15223 0.338897705078125 +15224 0.38360595703125 +15225 0.443817138671875 +15226 0.4749755859375 +15227 0.545074462890625 +15228 0.541015625 +15229 0.6173095703125 +15230 0.574493408203125 +15231 0.6524658203125 +15232 0.586639404296875 +15233 0.66339111328125 +15234 0.58270263671875 +15235 0.6561279296875 +15236 0.54132080078125 +15237 0.606781005859375 +15238 0.449798583984375 +15239 0.501190185546875 +15240 0.31988525390625 +15241 0.352783203125 +15242 0.164825439453125 +15243 0.176544189453125 +15244 -0.021881103515625 +15245 -0.034820556640625 +15246 -0.219757080078125 +15247 -0.258209228515625 +15248 -0.3834228515625 +15249 -0.44244384765625 +15250 -0.501953125 +15251 -0.5753173828125 +15252 -0.571075439453125 +15253 -0.65203857421875 +15254 -0.563232421875 +15255 -0.641632080078125 +15256 -0.494384765625 +15257 -0.562164306640625 +15258 -0.40386962890625 +15259 -0.458038330078125 +15260 -0.3104248046875 +15261 -0.350555419921875 +15262 -0.23248291015625 +15263 -0.260528564453125 +15264 -0.173614501953125 +15265 -0.192108154296875 +15266 -0.1307373046875 +15267 -0.141937255859375 +15268 -0.0968017578125 +15269 -0.1021728515625 +15270 -0.06292724609375 +15271 -0.062896728515625 +15272 -0.01824951171875 +15273 -0.011932373046875 +15274 0.048004150390625 +15275 0.062835693359375 +15276 0.12457275390625 +15277 0.148712158203125 +15278 0.207855224609375 +15279 0.241729736328125 +15280 0.30426025390625 +15281 0.34912109375 +15282 0.401641845703125 +15283 0.457305908203125 +15284 0.480010986328125 +15285 0.54388427734375 +15286 0.50738525390625 +15287 0.5728759765625 +15288 0.4501953125 +15289 0.506591796875 +15290 0.3138427734375 +15291 0.351226806640625 +15292 0.133514404296875 +15293 0.146514892578125 +15294 -0.044403076171875 +15295 -0.05523681640625 +15296 -0.1864013671875 +15297 -0.21624755859375 +15298 -0.2911376953125 +15299 -0.334930419921875 +15300 -0.351287841796875 +15301 -0.402984619140625 +15302 -0.3853759765625 +15303 -0.4412841796875 +15304 -0.434173583984375 +15305 -0.49578857421875 +15306 -0.492034912109375 +15307 -0.5601806640625 +15308 -0.52899169921875 +15309 -0.600738525390625 +15310 -0.5155029296875 +15311 -0.584228515625 +15312 -0.42364501953125 +15313 -0.47930908203125 +15314 -0.24749755859375 +15315 -0.27935791015625 +15316 -0.008758544921875 +15317 -0.0089111328125 +15318 0.23651123046875 +15319 0.268798828125 +15320 0.425384521484375 +15321 0.482818603515625 +15322 0.53179931640625 +15323 0.60369873046875 +15324 0.5726318359375 +15325 0.650421142578125 +15326 0.584320068359375 +15327 0.66400146484375 +15328 0.564239501953125 +15329 0.6414794921875 +15330 0.50323486328125 +15331 0.572540283203125 +15332 0.437652587890625 +15333 0.498138427734375 +15334 0.386260986328125 +15335 0.439453125 +15336 0.33038330078125 +15337 0.375518798828125 +15338 0.241729736328125 +15339 0.274505615234375 +15340 0.095672607421875 +15341 0.1087646484375 +15342 -0.088043212890625 +15343 -0.099395751953125 +15344 -0.28125 +15345 -0.3182373046875 +15346 -0.485107421875 +15347 -0.5489501953125 +15348 -0.683929443359375 +15349 -0.7738037109375 +15350 -0.830718994140625 +15351 -0.86383056640625 +15352 -0.859039306640625 +15353 -0.870391845703125 +15354 -0.858978271484375 +15355 -0.86895751953125 +15356 -0.84075927734375 +15357 -0.861053466796875 +15358 -0.716583251953125 +15359 -0.765869140625 +15360 -0.512786865234375 +15361 -0.5301513671875 +15362 -0.23516845703125 +15363 -0.214691162109375 +15364 0.077911376953125 +15365 0.137359619140625 +15366 0.380279541015625 +15367 0.474822998046875 +15368 0.640106201171875 +15369 0.76239013671875 +15370 0.833221435546875 +15371 0.867462158203125 +15372 0.866058349609375 +15373 0.870361328125 +15374 0.870361328125 +15375 0.86480712890625 +15376 0.86700439453125 +15377 0.831817626953125 +15378 0.8585205078125 +15379 0.677581787109375 +15380 0.772491455078125 +15381 0.495880126953125 +15382 0.628936767578125 +15383 0.30767822265625 +15384 0.46282958984375 +15385 0.116180419921875 +15386 0.24456787109375 +15387 -0.110748291015625 +15388 -0.032806396484375 +15389 -0.381805419921875 +15390 -0.330718994140625 +15391 -0.6572265625 +15392 -0.59490966796875 +15393 -0.857421875 +15394 -0.786773681640625 +15395 -0.870391845703125 +15396 -0.859527587890625 +15397 -0.870391845703125 +15398 -0.866241455078125 +15399 -0.86444091796875 +15400 -0.870391845703125 +15401 -0.85723876953125 +15402 -0.870391845703125 +15403 -0.790008544921875 +15404 -0.86126708984375 +15405 -0.62847900390625 +15406 -0.746856689453125 +15407 -0.3956298828125 +15408 -0.522003173828125 +15409 -0.126708984375 +15410 -0.267120361328125 +15411 0.150115966796875 +15412 0.007171630859375 +15413 0.424041748046875 +15414 0.27655029296875 +15415 0.670623779296875 +15416 0.50604248046875 +15417 0.854522705078125 +15418 0.68017578125 +15419 0.866485595703125 +15420 0.785736083984375 +15421 0.86920166015625 +15422 0.840484619140625 +15423 0.8653564453125 +15424 0.854827880859375 +15425 0.857147216796875 +15426 0.835968017578125 +15427 0.766845703125 +15428 0.780670166015625 +15429 0.628509521484375 +15430 0.686431884765625 +15431 0.462127685546875 +15432 0.577606201171875 +15433 0.297210693359375 +15434 0.46600341796875 +15435 0.14862060546875 +15436 0.33074951171875 +15437 -0.00537109375 +15438 0.17864990234375 +15439 -0.15753173828125 +15440 0.006134033203125 +15441 -0.31304931640625 +15442 -0.20013427734375 +15443 -0.48876953125 +15444 -0.397674560546875 +15445 -0.6416015625 +15446 -0.564453125 +15447 -0.751373291015625 +15448 -0.722503662109375 +15449 -0.84619140625 +15450 -0.855010986328125 +15451 -0.861297607421875 +15452 -0.864349365234375 +15453 -0.863250732421875 +15454 -0.865020751953125 +15455 -0.856597900390625 +15456 -0.85833740234375 +15457 -0.7498779296875 +15458 -0.8143310546875 +15459 -0.624542236328125 +15460 -0.70550537109375 +15461 -0.47808837890625 +15462 -0.509429931640625 +15463 -0.253387451171875 +15464 -0.268157958984375 +15465 0.003692626953125 +15466 -0.04443359375 +15467 0.2257080078125 +15468 0.17352294921875 +15469 0.427154541015625 +15470 0.41595458984375 +15471 0.643218994140625 +15472 0.674530029296875 +15473 0.855926513671875 +15474 0.85906982421875 +15475 0.870361328125 +15476 0.870361328125 +15477 0.870361328125 +15478 0.870361328125 +15479 0.862762451171875 +15480 0.862823486328125 +15481 0.79669189453125 +15482 0.7880859375 +15483 0.595794677734375 +15484 0.6007080078125 +15485 0.362152099609375 +15486 0.396636962890625 +15487 0.1270751953125 +15488 0.196319580078125 +15489 -0.086944580078125 +15490 0.001708984375 +15491 -0.2784423828125 +15492 -0.220123291015625 +15493 -0.484832763671875 +15494 -0.4886474609375 +15495 -0.729583740234375 +15496 -0.7598876953125 +15497 -0.86688232421875 +15498 -0.8680419921875 +15499 -0.870391845703125 +15500 -0.870391845703125 +15501 -0.86859130859375 +15502 -0.868377685546875 +15503 -0.86279296875 +15504 -0.85955810546875 +15505 -0.817962646484375 +15506 -0.724853515625 +15507 -0.6116943359375 +15508 -0.45458984375 +15509 -0.3128662109375 +15510 -0.125885009765625 +15511 0.039398193359375 +15512 0.240203857421875 +15513 0.422821044921875 +15514 0.613006591796875 +15515 0.805145263671875 +15516 0.862945556640625 +15517 0.870361328125 +15518 0.870361328125 +15519 0.870361328125 +15520 0.8675537109375 +15521 0.860015869140625 +15522 0.85540771484375 +15523 0.727935791015625 +15524 0.6759033203125 +15525 0.48114013671875 +15526 0.44873046875 +15527 0.2059326171875 +15528 0.2142333984375 +15529 -0.06103515625 +15530 -0.008758544921875 +15531 -0.29913330078125 +15532 -0.226837158203125 +15533 -0.516204833984375 +15534 -0.45050048828125 +15535 -0.7252197265625 +15536 -0.656280517578125 +15537 -0.85980224609375 +15538 -0.815155029296875 +15539 -0.870391845703125 +15540 -0.86004638671875 +15541 -0.870391845703125 +15542 -0.858367919921875 +15543 -0.858062744140625 +15544 -0.77459716796875 +15545 -0.673004150390625 +15546 -0.619171142578125 +15547 -0.42694091796875 +15548 -0.47625732421875 +15549 -0.2100830078125 +15550 -0.355865478515625 +15551 -0.0362548828125 +15552 -0.242645263671875 +15553 0.10943603515625 +15554 -0.128448486328125 +15555 0.23516845703125 +15556 0.016326904296875 +15557 0.373687744140625 +15558 0.18359375 +15559 0.517791748046875 +15560 0.311431884765625 +15561 0.602783203125 +15562 0.403228759765625 +15563 0.635711669921875 +15564 0.490753173828125 +15565 0.655181884765625 +15566 0.56842041015625 +15567 0.65948486328125 +15568 0.634521484375 +15569 0.651275634765625 +15570 0.673919677734375 +15571 0.61846923828125 +15572 0.661346435546875 +15573 0.53753662109375 +15574 0.58966064453125 +15575 0.404144287109375 +15576 0.45965576171875 +15577 0.22186279296875 +15578 0.281890869140625 +15579 0.003997802734375 +15580 0.08172607421875 +15581 -0.22100830078125 +15582 -0.114410400390625 +15583 -0.42449951171875 +15584 -0.281005859375 +15585 -0.579833984375 +15586 -0.374847412109375 +15587 -0.641876220703125 +15588 -0.400177001953125 +15589 -0.6177978515625 +15590 -0.41656494140625 +15591 -0.575531005859375 +15592 -0.431121826171875 +15593 -0.526336669921875 +15594 -0.4002685546875 +15595 -0.42645263671875 +15596 -0.304290771484375 +15597 -0.2581787109375 +15598 -0.183441162109375 +15599 -0.068695068359375 +15600 -0.080718994140625 +15601 0.09222412109375 +15602 0.01300048828125 +15603 0.232147216796875 +15604 0.0992431640625 +15605 0.3509521484375 +15606 0.143402099609375 +15607 0.410064697265625 +15608 0.112091064453125 +15609 0.372955322265625 +15610 0.019378662109375 +15611 0.2554931640625 +15612 -0.0904541015625 +15613 0.10711669921875 +15614 -0.201446533203125 +15615 -0.052886962890625 +15616 -0.28021240234375 +15617 -0.186279296875 +15618 -0.273590087890625 +15619 -0.23291015625 +15620 -0.20050048828125 +15621 -0.209442138671875 +15622 -0.11865234375 +15623 -0.174163818359375 +15624 -0.0299072265625 +15625 -0.126739501953125 +15626 0.081817626953125 +15627 -0.048126220703125 +15628 0.19683837890625 +15629 0.0426025390625 +15630 0.2779541015625 +15631 0.10748291015625 +15632 0.319183349609375 +15633 0.1409912109375 +15634 0.37164306640625 +15635 0.19708251953125 +15636 0.4337158203125 +15637 0.273651123046875 +15638 0.45587158203125 +15639 0.31768798828125 +15640 0.45074462890625 +15641 0.341094970703125 +15642 0.4429931640625 +15643 0.368011474609375 +15644 0.409912109375 +15645 0.37249755859375 +15646 0.302490234375 +15647 0.30072021484375 +15648 0.121978759765625 +15649 0.1517333984375 +15650 -0.07275390625 +15651 -0.01470947265625 +15652 -0.27001953125 +15653 -0.1883544921875 +15654 -0.471588134765625 +15655 -0.372711181640625 +15656 -0.625091552734375 +15657 -0.51397705078125 +15658 -0.691253662109375 +15659 -0.57177734375 +15660 -0.663421630859375 +15661 -0.53948974609375 +15662 -0.558807373046875 +15663 -0.43511962890625 +15664 -0.413665771484375 +15665 -0.2962646484375 +15666 -0.265228271484375 +15667 -0.161102294921875 +15668 -0.12799072265625 +15669 -0.0435791015625 +15670 0.000335693359375 +15671 0.060394287109375 +15672 0.104583740234375 +15673 0.13665771484375 +15674 0.16864013671875 +15675 0.170135498046875 +15676 0.195220947265625 +15677 0.16552734375 +15678 0.21539306640625 +15679 0.15728759765625 +15680 0.232818603515625 +15681 0.150787353515625 +15682 0.2235107421875 +15683 0.12200927734375 +15684 0.195343017578125 +15685 0.080108642578125 +15686 0.172760009765625 +15687 0.05126953125 +15688 0.181732177734375 +15689 0.062896728515625 +15690 0.201385498046875 +15691 0.09271240234375 +15692 0.18707275390625 +15693 0.092987060546875 +15694 0.15380859375 +15695 0.07855224609375 +15696 0.116943359375 +15697 0.06427001953125 +15698 0.063262939453125 +15699 0.0347900390625 +15700 -0.007537841796875 +15701 -0.01171875 +15702 -0.07568359375 +15703 -0.056060791015625 +15704 -0.099212646484375 +15705 -0.055511474609375 +15706 -0.077239990234375 +15707 -0.010467529296875 +15708 -0.059967041015625 +15709 0.02508544921875 +15710 -0.070831298828125 +15711 0.025665283203125 +15712 -0.0845947265625 +15713 0.017333984375 +15714 -0.099395751953125 +15715 0.00189208984375 +15716 -0.125946044921875 +15717 -0.03173828125 +15718 -0.15325927734375 +15719 -0.071502685546875 +15720 -0.199188232421875 +15721 -0.13543701171875 +15722 -0.261260986328125 +15723 -0.219970703125 +15724 -0.317230224609375 +15725 -0.300506591796875 +15726 -0.3675537109375 +15727 -0.376312255859375 +15728 -0.38372802734375 +15729 -0.416107177734375 +15730 -0.320587158203125 +15731 -0.371124267578125 +15732 -0.180084228515625 +15733 -0.242279052734375 +15734 -0.001312255859375 +15735 -0.069732666015625 +15736 0.195159912109375 +15737 0.125640869140625 +15738 0.3792724609375 +15739 0.31268310546875 +15740 0.516265869140625 +15741 0.45501708984375 +15742 0.608184814453125 +15743 0.554779052734375 +15744 0.654083251953125 +15745 0.61065673828125 +15746 0.643341064453125 +15747 0.610931396484375 +15748 0.553741455078125 +15749 0.531463623046875 +15750 0.401397705078125 +15751 0.3883056640625 +15752 0.23779296875 +15753 0.23468017578125 +15754 0.087371826171875 +15755 0.095245361328125 +15756 -0.024139404296875 +15757 -0.00396728515625 +15758 -0.082122802734375 +15759 -0.04852294921875 +15760 -0.10162353515625 +15761 -0.055145263671875 +15762 -0.13140869140625 +15763 -0.0758056640625 +15764 -0.197784423828125 +15765 -0.138702392578125 +15766 -0.267578125 +15767 -0.209197998046875 +15768 -0.3424072265625 +15769 -0.289031982421875 +15770 -0.423065185546875 +15771 -0.37884521484375 +15772 -0.488677978515625 +15773 -0.456329345703125 +15774 -0.535003662109375 +15775 -0.51641845703125 +15776 -0.52484130859375 +15777 -0.519287109375 +15778 -0.452606201171875 +15779 -0.458251953125 +15780 -0.3680419921875 +15781 -0.384796142578125 +15782 -0.29547119140625 +15783 -0.323699951171875 +15784 -0.23028564453125 +15785 -0.269287109375 +15786 -0.148193359375 +15787 -0.1951904296875 +15788 -0.048431396484375 +15789 -0.100006103515625 +15790 0.04302978515625 +15791 -0.01055908203125 +15792 0.1546630859375 +15793 0.1033935546875 +15794 0.293243408203125 +15795 0.24908447265625 +15796 0.408233642578125 +15797 0.373199462890625 +15798 0.48309326171875 +15799 0.45806884765625 +15800 0.525604248046875 +15801 0.511474609375 +15802 0.56671142578125 +15803 0.565399169921875 +15804 0.598968505859375 +15805 0.61138916015625 +15806 0.5662841796875 +15807 0.5897216796875 +15808 0.46002197265625 +15809 0.4906005859375 +15810 0.297454833984375 +15811 0.33148193359375 +15812 0.112823486328125 +15813 0.147796630859375 +15814 -0.053741455078125 +15815 -0.01873779296875 +15816 -0.17535400390625 +15817 -0.140289306640625 +15818 -0.2281494140625 +15819 -0.191986083984375 +15820 -0.221923828125 +15821 -0.184295654296875 +15822 -0.1990966796875 +15823 -0.161834716796875 +15824 -0.199676513671875 +15825 -0.166595458984375 +15826 -0.219512939453125 +15827 -0.19390869140625 +15828 -0.240631103515625 +15829 -0.22442626953125 +15830 -0.284027099609375 +15831 -0.279754638671875 +15832 -0.330413818359375 +15833 -0.3389892578125 +15834 -0.3349609375 +15835 -0.3543701171875 +15836 -0.31939697265625 +15837 -0.348175048828125 +15838 -0.28955078125 +15839 -0.32598876953125 +15840 -0.21771240234375 +15841 -0.2581787109375 +15842 -0.09954833984375 +15843 -0.139801025390625 +15844 0.0509033203125 +15845 0.014617919921875 +15846 0.17578125 +15847 0.144378662109375 +15848 0.248077392578125 +15849 0.221038818359375 +15850 0.292633056640625 +15851 0.27069091796875 +15852 0.31036376953125 +15853 0.294036865234375 +15854 0.321197509765625 +15855 0.311767578125 +15856 0.34002685546875 +15857 0.339141845703125 +15858 0.3521728515625 +15859 0.360260009765625 +15860 0.34423828125 +15861 0.360504150390625 +15862 0.28662109375 +15863 0.308380126953125 +15864 0.15863037109375 +15865 0.18170166015625 +15866 -0.016143798828125 +15867 0.0047607421875 +15868 -0.192840576171875 +15869 -0.17559814453125 +15870 -0.328369140625 +15871 -0.3143310546875 +15872 -0.3807373046875 +15873 -0.36785888671875 +15874 -0.37530517578125 +15875 -0.36248779296875 +15876 -0.35589599609375 +15877 -0.343536376953125 +15878 -0.31341552734375 +15879 -0.3018798828125 +15880 -0.241790771484375 +15881 -0.231414794921875 +15882 -0.126800537109375 +15883 -0.117645263671875 +15884 -0.000396728515625 +15885 0.007049560546875 +15886 0.0833740234375 +15887 0.087982177734375 +15888 0.138397216796875 +15889 0.13946533203125 +15890 0.176971435546875 +15891 0.17425537109375 +15892 0.1947021484375 +15893 0.188201904296875 +15894 0.18145751953125 +15895 0.171234130859375 +15896 0.132232666015625 +15897 0.118438720703125 +15898 0.073699951171875 +15899 0.05706787109375 +15900 0.007843017578125 +15901 -0.010711669921875 +15902 -0.071746826171875 +15903 -0.0914306640625 +15904 -0.142608642578125 +15905 -0.162322998046875 +15906 -0.17633056640625 +15907 -0.194549560546875 +15908 -0.13458251953125 +15909 -0.1492919921875 +15910 -0.01239013671875 +15911 -0.02166748046875 +15912 0.127227783203125 +15913 0.124053955078125 +15914 0.208984375 +15915 0.211151123046875 +15916 0.233917236328125 +15917 0.240447998046875 +15918 0.23199462890625 +15919 0.242218017578125 +15920 0.212554931640625 +15921 0.2257080078125 +15922 0.179107666015625 +15923 0.194366455078125 +15924 0.099639892578125 +15925 0.115509033203125 +15926 -0.002471923828125 +15927 0.0128173828125 +15928 -0.0682373046875 +15929 -0.053802490234375 +15930 -0.123504638671875 +15931 -0.110626220703125 +15932 -0.20953369140625 +15933 -0.199493408203125 +15934 -0.300811767578125 +15935 -0.29437255859375 +15936 -0.335418701171875 +15937 -0.33221435546875 +15938 -0.28076171875 +15939 -0.27972412109375 +15940 -0.184661865234375 +15941 -0.185333251953125 +15942 -0.12518310546875 +15943 -0.128204345703125 +15944 -0.109710693359375 +15945 -0.115692138671875 +15946 -0.10760498046875 +15947 -0.116455078125 +15948 -0.0948486328125 +15949 -0.105926513671875 +15950 -0.04193115234375 +15951 -0.053955078125 +15952 0.060272216796875 +15953 0.048797607421875 +15954 0.16748046875 +15955 0.157318115234375 +15956 0.22100830078125 +15957 0.212005615234375 +15958 0.2264404296875 +15959 0.218475341796875 +15960 0.243377685546875 +15961 0.23724365234375 +15962 0.308380126953125 +15963 0.30535888671875 +15964 0.380706787109375 +15965 0.38128662109375 +15966 0.40087890625 +15967 0.404449462890625 +15968 0.388275146484375 +15969 0.3944091796875 +15970 0.379852294921875 +15971 0.3885498046875 +15972 0.3519287109375 +15973 0.362640380859375 +15974 0.26220703125 +15975 0.27362060546875 +15976 0.106536865234375 +15977 0.11712646484375 +15978 -0.063873291015625 +15979 -0.054901123046875 +15980 -0.198211669921875 +15981 -0.19085693359375 +15982 -0.291534423828125 +15983 -0.28570556640625 +15984 -0.343658447265625 +15985 -0.339263916015625 +15986 -0.3802490234375 +15987 -0.3775634765625 +15988 -0.445770263671875 +15989 -0.445709228515625 +15990 -0.531829833984375 +15991 -0.535064697265625 +15992 -0.6221923828125 +15993 -0.629058837890625 +15994 -0.687408447265625 +15995 -0.697601318359375 +15996 -0.69140625 +15997 -0.70391845703125 +15998 -0.628814697265625 +15999 -0.6424560546875 +16000 -0.4781494140625 +16001 -0.491241455078125 +16002 -0.25469970703125 +16003 -0.265716552734375 +16004 -0.015411376953125 +16005 -0.023712158203125 +16006 0.207122802734375 +16007 0.201751708984375 +16008 0.37860107421875 +16009 0.375823974609375 +16010 0.485809326171875 +16011 0.485076904296875 +16012 0.5675048828125 +16013 0.56884765625 +16014 0.6312255859375 +16015 0.634765625 +16016 0.632568359375 +16017 0.63763427734375 +16018 0.560394287109375 +16019 0.5660400390625 +16020 0.466033935546875 +16021 0.4720458984375 +16022 0.400054931640625 +16023 0.40692138671875 +16024 0.369598388671875 +16025 0.3778076171875 +16026 0.367095947265625 +16027 0.376953125 +16028 0.360809326171875 +16029 0.371978759765625 +16030 0.3018798828125 +16031 0.313140869140625 +16032 0.174530029296875 +16033 0.184417724609375 +16034 0.003814697265625 +16035 0.011199951171875 +16036 -0.1754150390625 +16037 -0.171051025390625 +16038 -0.338623046875 +16039 -0.33740234375 +16040 -0.470184326171875 +16041 -0.47198486328125 +16042 -0.5560302734375 +16043 -0.560394287109375 +16044 -0.574554443359375 +16045 -0.58056640625 +16046 -0.540618896484375 +16047 -0.54754638671875 +16048 -0.500762939453125 +16049 -0.508575439453125 +16050 -0.45098876953125 +16051 -0.459503173828125 +16052 -0.385528564453125 +16053 -0.394378662109375 +16054 -0.343231201171875 +16055 -0.35260009765625 +16056 -0.302032470703125 +16057 -0.31170654296875 +16058 -0.188873291015625 +16059 -0.197418212890625 +16060 -0.002044677734375 +16061 -0.007965087890625 +16062 0.21002197265625 +16063 0.207489013671875 +16064 0.40826416015625 +16065 0.409210205078125 +16066 0.567962646484375 +16067 0.57208251953125 +16068 0.659515380859375 +16069 0.66595458984375 +16070 0.6513671875 +16071 0.65875244140625 +16072 0.560302734375 +16073 0.56744384765625 +16074 0.425140380859375 +16075 0.431396484375 +16076 0.2890625 +16077 0.29443359375 +16078 0.177642822265625 +16079 0.182464599609375 +16080 0.059661865234375 +16081 0.06365966796875 +16082 -0.078582763671875 +16083 -0.075958251953125 +16084 -0.19085693359375 +16085 -0.189422607421875 +16086 -0.27239990234375 +16087 -0.271942138671875 +16088 -0.3419189453125 +16089 -0.342529296875 +16090 -0.363037109375 +16091 -0.364166259765625 +16092 -0.3262939453125 +16093 -0.327239990234375 +16094 -0.276214599609375 +16095 -0.2769775390625 +16096 -0.25250244140625 +16097 -0.253692626953125 +16098 -0.24169921875 +16099 -0.24365234375 +16100 -0.196136474609375 +16101 -0.1983642578125 +16102 -0.11431884765625 +16103 -0.116241455078125 +16104 -0.035186767578125 +16105 -0.036834716796875 +16106 0.036285400390625 +16107 0.034881591796875 +16108 0.092498779296875 +16109 0.09124755859375 +16110 0.110443115234375 +16111 0.10888671875 +16112 0.127197265625 +16113 0.125518798828125 +16114 0.159088134765625 +16115 0.15771484375 +16116 0.1793212890625 +16117 0.17828369140625 +16118 0.1719970703125 +16119 0.17108154296875 +16120 0.131134033203125 +16121 0.129974365234375 +16122 0.083770751953125 +16123 0.082427978515625 +16124 0.02923583984375 +16125 0.027679443359375 +16126 -0.0633544921875 +16127 -0.065643310546875 +16128 -0.15618896484375 +16129 -0.159515380859375 +16130 -0.209686279296875 +16131 -0.21337890625 +16132 -0.23187255859375 +16133 -0.2347412109375 +16134 -0.1986083984375 +16135 -0.200286865234375 +16136 -0.119110107421875 +16137 -0.11956787109375 +16138 -0.0263671875 +16139 -0.025421142578125 +16140 0.082550048828125 +16141 0.084686279296875 +16142 0.173492431640625 +16143 0.1768798828125 +16144 0.20989990234375 +16145 0.21490478515625 +16146 0.205108642578125 +16147 0.211761474609375 +16148 0.16864013671875 +16149 0.176727294921875 +16150 0.12237548828125 +16151 0.13128662109375 +16152 0.096160888671875 +16153 0.1048583984375 +16154 0.069580078125 +16155 0.077423095703125 +16156 0.039794921875 +16157 0.046295166015625 +16158 0.036163330078125 +16159 0.040496826171875 +16160 0.0758056640625 +16161 0.0770263671875 +16162 0.14215087890625 +16163 0.13970947265625 +16164 0.18902587890625 +16165 0.18328857421875 +16166 0.192718505859375 +16167 0.184600830078125 +16168 0.144012451171875 +16169 0.134674072265625 +16170 0.047515869140625 +16171 0.038177490234375 +16172 -0.073272705078125 +16173 -0.08172607421875 +16174 -0.213165283203125 +16175 -0.219879150390625 +16176 -0.361846923828125 +16177 -0.366119384765625 +16178 -0.489471435546875 +16179 -0.4910888671875 +16180 -0.551727294921875 +16181 -0.551239013671875 +16182 -0.505279541015625 +16183 -0.5040283203125 +16184 -0.373443603515625 +16185 -0.3724365234375 +16186 -0.218109130859375 +16187 -0.21746826171875 +16188 -0.0643310546875 +16189 -0.063934326171875 +16190 0.08966064453125 +16191 0.08978271484375 +16192 0.232940673828125 +16193 0.232818603515625 +16194 0.338897705078125 +16195 0.3388671875 +16196 0.390380859375 +16197 0.390960693359375 +16198 0.38409423828125 +16199 0.38580322265625 +16200 0.318817138671875 +16201 0.3221435546875 +16202 0.21881103515625 +16203 0.22381591796875 +16204 0.119415283203125 +16205 0.125640869140625 +16206 0.032867431640625 +16207 0.0396728515625 +16208 -0.013427734375 +16209 -0.007080078125 +16210 -0.021728515625 +16211 -0.016754150390625 +16212 -0.023956298828125 +16213 -0.0206298828125 +16214 -0.001556396484375 +16215 -0.0003662109375 +16216 0.05743408203125 +16217 0.055877685546875 +16218 0.108856201171875 +16219 0.104766845703125 +16220 0.099884033203125 +16221 0.09442138671875 +16222 0.046356201171875 +16223 0.040496826171875 +16224 -0.013916015625 +16225 -0.019744873046875 +16226 -0.071533203125 +16227 -0.076995849609375 +16228 -0.115142822265625 +16229 -0.12005615234375 +16230 -0.15570068359375 +16231 -0.159759521484375 +16232 -0.199066162109375 +16233 -0.201904296875 +16234 -0.2457275390625 +16235 -0.2469482421875 +16236 -0.3031005859375 +16237 -0.302276611328125 +16238 -0.360931396484375 +16239 -0.357879638671875 +16240 -0.39117431640625 +16241 -0.38623046875 +16242 -0.35595703125 +16243 -0.350128173828125 +16244 -0.251495361328125 +16245 -0.245941162109375 +16246 -0.09515380859375 +16247 -0.090850830078125 +16248 0.086151123046875 +16249 0.088623046875 +16250 0.231903076171875 +16251 0.232879638671875 +16252 0.315277099609375 +16253 0.31549072265625 +16254 0.355072021484375 +16255 0.35491943359375 +16256 0.3443603515625 +16257 0.344329833984375 +16258 0.282623291015625 +16259 0.283233642578125 +16260 0.220672607421875 +16261 0.221649169921875 +16262 0.19488525390625 +16263 0.195404052734375 +16264 0.1787109375 +16265 0.178436279296875 +16266 0.15521240234375 +16267 0.154144287109375 +16268 0.15167236328125 +16269 0.149444580078125 +16270 0.158172607421875 +16271 0.154632568359375 +16272 0.1336669921875 +16273 0.12939453125 +16274 0.103240966796875 +16275 0.098480224609375 +16276 0.0899658203125 +16277 0.084625244140625 +16278 0.05792236328125 +16279 0.05255126953125 +16280 -0.005889892578125 +16281 -0.01055908203125 +16282 -0.10101318359375 +16283 -0.104156494140625 +16284 -0.2266845703125 +16285 -0.227569580078125 +16286 -0.353240966796875 +16287 -0.351593017578125 +16288 -0.440155029296875 +16289 -0.4364013671875 +16290 -0.472686767578125 +16291 -0.467559814453125 +16292 -0.46429443359375 +16293 -0.45831298828125 +16294 -0.419219970703125 +16295 -0.41290283203125 +16296 -0.335052490234375 +16297 -0.32904052734375 +16298 -0.229217529296875 +16299 -0.223907470703125 +16300 -0.125213623046875 +16301 -0.120697021484375 +16302 -0.02972412109375 +16303 -0.026031494140625 +16304 0.07537841796875 +16305 0.07794189453125 +16306 0.21087646484375 +16307 0.21160888671875 +16308 0.38653564453125 +16309 0.384521484375 +16310 0.580657958984375 +16311 0.575347900390625 +16312 0.732177734375 +16313 0.72406005859375 +16314 0.79864501953125 +16315 0.788909912109375 +16316 0.777252197265625 +16317 0.76715087890625 +16318 0.664581298828125 +16319 0.65545654296875 +16320 0.459564208984375 +16321 0.452850341796875 +16322 0.1995849609375 +16323 0.196136474609375 +16324 -0.04986572265625 +16325 -0.050140380859375 +16326 -0.231781005859375 +16327 -0.229888916015625 +16328 -0.32867431640625 +16329 -0.325836181640625 +16330 -0.36676025390625 +16331 -0.36376953125 +16332 -0.377197265625 +16333 -0.37432861328125 +16334 -0.375244140625 +16335 -0.372528076171875 +16336 -0.3780517578125 +16337 -0.375244140625 +16338 -0.390045166015625 +16339 -0.386810302734375 +16340 -0.3841552734375 +16341 -0.380615234375 +16342 -0.341064453125 +16343 -0.337677001953125 +16344 -0.28240966796875 +16345 -0.27935791015625 +16346 -0.25152587890625 +16347 -0.248291015625 +16348 -0.266448974609375 +16349 -0.26226806640625 +16350 -0.274017333984375 +16351 -0.26904296875 +16352 -0.2177734375 +16353 -0.21307373046875 +16354 -0.129486083984375 +16355 -0.1256103515625 +16356 -0.069549560546875 +16357 -0.066162109375 +16358 -0.044586181640625 +16359 -0.041259765625 +16360 -0.02593994140625 +16361 -0.022735595703125 +16362 0.019317626953125 +16363 0.021820068359375 +16364 0.12322998046875 +16365 0.12396240234375 +16366 0.2568359375 +16367 0.255157470703125 +16368 0.378326416015625 +16369 0.37432861328125 +16370 0.47943115234375 +16371 0.473358154296875 +16372 0.528045654296875 +16373 0.5206298828125 +16374 0.511322021484375 +16375 0.503570556640625 +16376 0.45672607421875 +16377 0.449249267578125 +16378 0.408294677734375 +16379 0.401031494140625 +16380 0.38482666015625 +16381 0.37744140625 +16382 0.358123779296875 +16383 0.350738525390625 +16384 0.313201904296875 +16385 0.305694580078125 +16386 0.252288818359375 +16387 0.24420166015625 +16388 0.166748046875 +16389 0.158447265625 +16390 0.036468505859375 +16391 0.029754638671875 +16392 -0.141021728515625 +16393 -0.143768310546875 +16394 -0.3348388671875 +16395 -0.33233642578125 +16396 -0.534027099609375 +16397 -0.52520751953125 +16398 -0.721649169921875 +16399 -0.706024169921875 +16400 -0.836761474609375 +16401 -0.816650390625 +16402 -0.833038330078125 +16403 -0.81292724609375 +16404 -0.73028564453125 +16405 -0.713775634765625 +16406 -0.58343505859375 +16407 -0.57159423828125 +16408 -0.441131591796875 +16409 -0.432830810546875 +16410 -0.325439453125 +16411 -0.3187255859375 +16412 -0.20263671875 +16413 -0.19744873046875 +16414 -0.0457763671875 +16415 -0.043548583984375 +16416 0.102935791015625 +16417 0.102508544921875 +16418 0.201507568359375 +16419 0.200469970703125 +16420 0.263824462890625 +16421 0.263336181640625 +16422 0.338470458984375 +16423 0.337188720703125 +16424 0.443634033203125 +16425 0.439178466796875 +16426 0.545135498046875 +16427 0.536712646484375 +16428 0.61761474609375 +16429 0.605621337890625 +16430 0.652984619140625 +16431 0.63824462890625 +16432 0.664093017578125 +16433 0.646881103515625 +16434 0.656951904296875 +16435 0.637420654296875 +16436 0.607696533203125 +16437 0.587249755859375 +16438 0.50213623046875 +16439 0.48309326171875 +16440 0.35369873046875 +16441 0.33795166015625 +16442 0.1773681640625 +16443 0.16632080078125 +16444 -0.034149169921875 +16445 -0.038543701171875 +16446 -0.257720947265625 +16447 -0.25445556640625 +16448 -0.442169189453125 +16449 -0.432525634765625 +16450 -0.57525634765625 +16451 -0.56097412109375 +16452 -0.652191162109375 +16453 -0.63519287109375 +16454 -0.6419677734375 +16455 -0.625640869140625 +16456 -0.562652587890625 +16457 -0.54949951171875 +16458 -0.458648681640625 +16459 -0.449127197265625 +16460 -0.351226806640625 +16461 -0.344879150390625 +16462 -0.26123046875 +16463 -0.256683349609375 +16464 -0.19281005859375 +16465 -0.18865966796875 +16466 -0.142608642578125 +16467 -0.137786865234375 +16468 -0.102783203125 +16469 -0.096771240234375 +16470 -0.06341552734375 +16471 -0.056365966796875 +16472 -0.0123291015625 +16473 -0.005096435546875 +16474 0.062591552734375 +16475 0.06842041015625 +16476 0.148651123046875 +16477 0.1519775390625 +16478 0.241851806640625 +16479 0.24169921875 +16480 0.34942626953125 +16481 0.344451904296875 +16482 0.457794189453125 +16483 0.447296142578125 +16484 0.544525146484375 +16485 0.5289306640625 +16486 0.5736083984375 +16487 0.55517578125 +16488 0.507354736328125 +16489 0.490234375 +16490 0.35198974609375 +16491 0.340118408203125 +16492 0.147247314453125 +16493 0.14276123046875 +16494 -0.0545654296875 +16495 -0.0518798828125 +16496 -0.215667724609375 +16497 -0.20770263671875 +16498 -0.33447265625 +16499 -0.32305908203125 +16500 -0.402679443359375 +16501 -0.389923095703125 +16502 -0.441131591796875 +16503 -0.42803955078125 +16504 -0.49578857421875 +16505 -0.4810791015625 +16506 -0.560333251953125 +16507 -0.542999267578125 +16508 -0.60101318359375 +16509 -0.581695556640625 +16510 -0.584625244140625 +16511 -0.565521240234375 +16512 -0.47979736328125 +16513 -0.46466064453125 +16514 -0.2799072265625 +16515 -0.27288818359375 +16516 -0.009490966796875 +16517 -0.013671875 +16518 0.268218994140625 +16519 0.252655029296875 +16520 0.482269287109375 +16521 0.45849609375 +16522 0.60321044921875 +16523 0.575714111328125 +16524 0.649993896484375 +16525 0.6221923828125 +16526 0.663665771484375 +16527 0.63690185546875 +16528 0.6412353515625 +16529 0.616912841796875 +16530 0.5723876953125 +16531 0.5523681640625 +16532 0.498077392578125 +16533 0.482177734375 +16534 0.439483642578125 +16535 0.426483154296875 +16536 0.375640869140625 +16537 0.365325927734375 +16538 0.274688720703125 +16539 0.268463134765625 +16540 0.1090087890625 +16541 0.109619140625 +16542 -0.09912109375 +16543 -0.08990478515625 +16544 -0.31793212890625 +16545 -0.2998046875 +16546 -0.54864501953125 +16547 -0.521148681640625 +16548 -0.773529052734375 +16549 -0.7369384765625 +16550 -0.863800048828125 +16551 -0.859100341796875 +16552 -0.870391845703125 +16553 -0.866973876953125 +16554 -0.868988037109375 +16555 -0.8670654296875 +16556 -0.861114501953125 +16557 -0.86077880859375 +16558 -0.766510009765625 +16559 -0.779083251953125 +16560 -0.53094482421875 +16561 -0.560455322265625 +16562 -0.215576171875 +16563 -0.262725830078125 +16564 0.13641357421875 +16565 0.0731201171875 +16566 0.473846435546875 +16567 0.398193359375 +16568 0.761444091796875 +16569 0.6785888671875 +16570 0.86737060546875 +16571 0.858184814453125 +16572 0.870361328125 +16573 0.870361328125 +16574 0.864898681640625 +16575 0.870361328125 +16576 0.833465576171875 +16577 0.86273193359375 +16578 0.679901123046875 +16579 0.816436767578125 +16580 0.498748779296875 +16581 0.666229248046875 +16582 0.3109130859375 +16583 0.49859619140625 +16584 0.119598388671875 +16585 0.3162841796875 +16586 -0.107330322265625 +16587 0.08905029296875 +16588 -0.378570556640625 +16589 -0.190460205078125 +16590 -0.654327392578125 +16591 -0.482940673828125 +16592 -0.857147216796875 +16593 -0.733367919921875 +16594 -0.870391845703125 +16595 -0.859832763671875 +16596 -0.870391845703125 +16597 -0.869110107421875 +16598 -0.86444091796875 +16599 -0.870391845703125 +16600 -0.85723876953125 +16601 -0.869659423828125 +16602 -0.790008544921875 +16603 -0.86541748046875 +16604 -0.62847900390625 +16605 -0.834625244140625 +16606 -0.3956298828125 +16607 -0.632965087890625 +16608 -0.126708984375 +16609 -0.38238525390625 +16610 0.150115966796875 +16611 -0.109832763671875 +16612 0.424041748046875 +16613 0.173492431640625 +16614 0.670623779296875 +16615 0.44268798828125 +16616 0.854522705078125 +16617 0.662322998046875 +16618 0.866485595703125 +16619 0.817657470703125 +16620 0.86920166015625 +16621 0.85906982421875 +16622 0.8653564453125 +16623 0.861541748046875 +16624 0.857147216796875 +16625 0.859588623046875 +16626 0.766845703125 +16627 0.84326171875 +16628 0.628509521484375 +16629 0.752777099609375 +16630 0.462127685546875 +16631 0.625946044921875 +16632 0.297210693359375 +16633 0.489471435546875 +16634 0.14862060546875 +16635 0.356658935546875 +16636 -0.00537109375 +16637 0.20672607421875 +16638 -0.15753173828125 +16639 0.047088623046875 +16640 -0.31304931640625 +16641 -0.125640869140625 +16642 -0.48876953125 +16643 -0.32574462890625 +16644 -0.6416015625 +16645 -0.511383056640625 +16646 -0.751373291015625 +16647 -0.661041259765625 +16648 -0.84619140625 +16649 -0.79754638671875 +16650 -0.861297607421875 +16651 -0.860504150390625 +16652 -0.863250732421875 +16653 -0.86688232421875 +16654 -0.856597900390625 +16655 -0.86456298828125 +16656 -0.7498779296875 +16657 -0.85498046875 +16658 -0.624542236328125 +16659 -0.75927734375 +16660 -0.47808837890625 +16661 -0.629669189453125 +16662 -0.253387451171875 +16663 -0.41741943359375 +16664 0.003692626953125 +16665 -0.165313720703125 +16666 0.2257080078125 +16667 0.06341552734375 +16668 0.427154541015625 +16669 0.28045654296875 +16670 0.643218994140625 +16671 0.5162353515625 +16672 0.855926513671875 +16673 0.762908935546875 +16674 0.870361328125 +16675 0.866912841796875 +16676 0.870361328125 +16677 0.870361328125 +16678 0.862762451171875 +16679 0.866241455078125 +16680 0.79669189453125 +16681 0.85491943359375 +16682 0.595794677734375 +16683 0.68603515625 +16684 0.362152099609375 +16685 0.47540283203125 +16686 0.1270751953125 +16687 0.255584716796875 +16688 -0.086944580078125 +16689 0.047637939453125 +16690 -0.2784423828125 +16691 -0.146270751953125 +16692 -0.484832763671875 +16693 -0.359344482421875 +16694 -0.729583740234375 +16695 -0.611785888671875 +16696 -0.86688232421875 +16697 -0.855194091796875 +16698 -0.870391845703125 +16699 -0.870391845703125 +16700 -0.86859130859375 +16701 -0.870391845703125 +16702 -0.86279296875 +16703 -0.866119384765625 +16704 -0.817962646484375 +16705 -0.855224609375 +16706 -0.6116943359375 +16707 -0.6688232421875 +16708 -0.3128662109375 +16709 -0.38580322265625 +16710 0.039398193359375 +16711 -0.0484619140625 +16712 0.422821044921875 +16713 0.32177734375 +16714 0.805145263671875 +16715 0.69415283203125 +16716 0.870361328125 +16717 0.870361328125 +16718 0.870361328125 +16719 0.870361328125 +16720 0.860015869140625 +16721 0.860382080078125 +16722 0.727935791015625 +16723 0.736968994140625 +16724 0.48114013671875 +16725 0.49810791015625 +16726 0.2059326171875 +16727 0.23040771484375 +16728 -0.06103515625 +16729 -0.031494140625 +16730 -0.29913330078125 +16731 -0.267730712890625 +16732 -0.516204833984375 +16733 -0.48455810546875 +16734 -0.7252197265625 +16735 -0.69293212890625 +16736 -0.85980224609375 +16737 -0.85626220703125 +16738 -0.870391845703125 +16739 -0.869354248046875 +16740 -0.870391845703125 +16741 -0.870391845703125 +16742 -0.858062744140625 +16743 -0.85955810546875 +16744 -0.673004150390625 +16745 -0.70391845703125 +16746 -0.42694091796875 +16747 -0.472930908203125 +16748 -0.2100830078125 +16749 -0.26458740234375 +16750 -0.0362548828125 +16751 -0.092193603515625 +16752 0.10943603515625 +16753 0.05712890625 +16754 0.23516845703125 +16755 0.190032958984375 +16756 0.373687744140625 +16757 0.33563232421875 +16758 0.517791748046875 +16759 0.48626708984375 +16760 0.602783203125 +16761 0.581451416015625 +16762 0.635711669921875 +16763 0.626800537109375 +16764 0.655181884765625 +16765 0.65704345703125 +16766 0.65948486328125 +16767 0.670013427734375 +16768 0.651275634765625 +16769 0.667755126953125 +16770 0.61846923828125 +16771 0.638946533203125 +16772 0.53753662109375 +16773 0.56201171875 +16774 0.404144287109375 +16775 0.4332275390625 +16776 0.22186279296875 +16777 0.25628662109375 +16778 0.003997802734375 +16779 0.044036865234375 +16780 -0.22100830078125 +16781 -0.1766357421875 +16782 -0.42449951171875 +16783 -0.37860107421875 +16784 -0.579833984375 +16785 -0.536468505859375 +16786 -0.641876220703125 +16787 -0.60791015625 +16788 -0.6177978515625 +16789 -0.598785400390625 +16790 -0.575531005859375 +16791 -0.570892333984375 +16792 -0.526336669921875 +16793 -0.534027099609375 +16794 -0.42645263671875 +16795 -0.447601318359375 +16796 -0.2581787109375 +16797 -0.295074462890625 +16798 -0.068695068359375 +16799 -0.11981201171875 +16800 0.09222412109375 +16801 0.032257080078125 +16802 0.232147216796875 +16803 0.167755126953125 +16804 0.3509521484375 +16805 0.2861328125 +16806 0.410064697265625 +16807 0.351318359375 +16808 0.372955322265625 +16809 0.329071044921875 +16810 0.2554931640625 +16811 0.23333740234375 +16812 0.10711669921875 +16813 0.10888671875 +16814 -0.052886962890625 +16815 -0.027191162109375 +16816 -0.186279296875 +16817 -0.1402587890625 +16818 -0.23291015625 +16819 -0.17547607421875 +16820 -0.209442138671875 +16821 -0.148529052734375 +16822 -0.174163818359375 +16823 -0.11328125 +16824 -0.126739501953125 +16825 -0.069488525390625 +16826 -0.048126220703125 +16827 0.000396728515625 +16828 0.0426025390625 +16829 0.07904052734375 +16830 0.10748291015625 +16831 0.131866455078125 +16832 0.1409912109375 +16833 0.15423583984375 +16834 0.19708251953125 +16835 0.196258544921875 +16836 0.273651123046875 +16837 0.256591796875 +16838 0.31768798828125 +16839 0.287017822265625 +16840 0.341094970703125 +16841 0.299041748046875 +16842 0.368011474609375 +16843 0.315399169921875 +16844 0.37249755859375 +16845 0.312591552734375 +16846 0.30072021484375 +16847 0.241455078125 +16848 0.1517333984375 +16849 0.101318359375 +16850 -0.01470947265625 +16851 -0.052734375 +16852 -0.1883544921875 +16853 -0.21124267578125 +16854 -0.372711181640625 +16855 -0.3775634765625 +16856 -0.51397705078125 +16857 -0.50244140625 +16858 -0.57177734375 +16859 -0.549072265625 +16860 -0.53948974609375 +16861 -0.511749267578125 +16862 -0.43511962890625 +16863 -0.407501220703125 +16864 -0.2962646484375 +16865 -0.2713623046875 +16866 -0.161102294921875 +16867 -0.138916015625 +16868 -0.0435791015625 +16869 -0.02337646484375 +16870 0.060394287109375 +16871 0.07855224609375 +16872 0.13665771484375 +16873 0.153564453125 +16874 0.170135498046875 +16875 0.18756103515625 +16876 0.16552734375 +16877 0.18475341796875 +16878 0.15728759765625 +16879 0.176788330078125 +16880 0.150787353515625 +16881 0.168701171875 +16882 0.12200927734375 +16883 0.138519287109375 +16884 0.080108642578125 +16885 0.094940185546875 +16886 0.05126953125 +16887 0.062347412109375 +16888 0.062896728515625 +16889 0.06634521484375 +16890 0.09271240234375 +16891 0.086822509765625 +16892 0.092987060546875 +16893 0.08026123046875 +16894 0.07855224609375 +16895 0.060638427734375 +16896 0.06427001953125 +16897 0.0421142578125 +16898 0.0347900390625 +16899 0.010772705078125 +16900 -0.01171875 +16901 -0.03497314453125 +16902 -0.056060791015625 +16903 -0.077484130859375 +16904 -0.055511474609375 +16905 -0.078125 +16906 -0.010467529296875 +16907 -0.037139892578125 +16908 0.02508544921875 +16909 -0.00311279296875 +16910 0.025665283203125 +16911 0.0008544921875 +16912 0.017333984375 +16913 -0.001953125 +16914 0.00189208984375 +16915 -0.01025390625 +16916 -0.03173828125 +16917 -0.034332275390625 +16918 -0.071502685546875 +16919 -0.063751220703125 +16920 -0.13543701171875 +16921 -0.115081787109375 +16922 -0.219970703125 +16923 -0.18548583984375 +16924 -0.300506591796875 +16925 -0.25311279296875 +16926 -0.376312255859375 +16927 -0.317535400390625 +16928 -0.416107177734375 +16929 -0.35076904296875 +16930 -0.371124267578125 +16931 -0.309051513671875 +16932 -0.242279052734375 +16933 -0.1932373046875 +16934 -0.069732666015625 +16935 -0.0394287109375 +16936 0.125640869140625 +16937 0.1336669921875 +16938 0.31268310546875 +16939 0.2982177734375 +16940 0.45501708984375 +16941 0.421722412109375 +16942 0.554779052734375 +16943 0.506378173828125 +16944 0.61065673828125 +16945 0.551300048828125 +16946 0.610931396484375 +16947 0.546234130859375 +16948 0.531463623046875 +16949 0.46978759765625 +16950 0.3883056640625 +16951 0.33660888671875 +16952 0.23468017578125 +16953 0.19482421875 +16954 0.095245361328125 +16955 0.06683349609375 +16956 -0.00396728515625 +16957 -0.02386474609375 +16958 -0.04852294921875 +16959 -0.064239501953125 +16960 -0.055145263671875 +16961 -0.069305419921875 +16962 -0.0758056640625 +16963 -0.085968017578125 +16964 -0.138702392578125 +16965 -0.139739990234375 +16966 -0.209197998046875 +16967 -0.199615478515625 +16968 -0.289031982421875 +16969 -0.26739501953125 +16970 -0.37884521484375 +16971 -0.343902587890625 +16972 -0.456329345703125 +16973 -0.409271240234375 +16974 -0.51641845703125 +16975 -0.45916748046875 +16976 -0.519287109375 +16977 -0.457977294921875 +16978 -0.458251953125 +16979 -0.399871826171875 +16980 -0.384796142578125 +16981 -0.33135986328125 +16982 -0.323699951171875 +16983 -0.27484130859375 +16984 -0.269287109375 +16985 -0.225250244140625 +16986 -0.1951904296875 +16987 -0.158905029296875 +16988 -0.100006103515625 +16989 -0.074462890625 +16990 -0.01055908203125 +16991 0.003997802734375 +16992 0.1033935546875 +16993 0.10382080078125 +16994 0.24908447265625 +16995 0.231689453125 +16996 0.373199462890625 +16997 0.339813232421875 +16998 0.45806884765625 +16999 0.412506103515625 +17000 0.511474609375 +17001 0.456939697265625 +17002 0.565399169921875 +17003 0.50213623046875 +17004 0.61138916015625 +17005 0.540679931640625 +17006 0.5897216796875 +17007 0.5189208984375 +17008 0.4906005859375 +17009 0.42816162109375 +17010 0.33148193359375 +17011 0.284210205078125 +17012 0.147796630859375 +17013 0.118927001953125 +17014 -0.01873779296875 +17015 -0.0301513671875 +17016 -0.140289306640625 +17017 -0.1380615234375 +17018 -0.191986083984375 +17019 -0.182464599609375 +17020 -0.184295654296875 +17021 -0.172943115234375 +17022 -0.161834716796875 +17023 -0.149810791015625 +17024 -0.166595458984375 +17025 -0.151031494140625 +17026 -0.19390869140625 +17027 -0.172576904296875 +17028 -0.22442626953125 +17029 -0.197174072265625 +17030 -0.279754638671875 +17031 -0.244415283203125 +17032 -0.3389892578125 +17033 -0.295623779296875 +17034 -0.3543701171875 +17035 -0.307952880859375 +17036 -0.348175048828125 +17037 -0.301513671875 +17038 -0.32598876953125 +17039 -0.281341552734375 +17040 -0.2581787109375 +17041 -0.220794677734375 +17042 -0.139801025390625 +17043 -0.1153564453125 +17044 0.014617919921875 +17045 0.022003173828125 +17046 0.144378662109375 +17047 0.13671875 +17048 0.221038818359375 +17049 0.203338623046875 +17050 0.27069091796875 +17051 0.2454833984375 +17052 0.294036865234375 +17053 0.263916015625 +17054 0.311767578125 +17055 0.277435302734375 +17056 0.339141845703125 +17057 0.29986572265625 +17058 0.360260009765625 +17059 0.316802978515625 +17060 0.360504150390625 +17061 0.315277099609375 +17062 0.308380126953125 +17063 0.2674560546875 +17064 0.18170166015625 +17065 0.15374755859375 +17066 0.0047607421875 +17067 -0.004150390625 +17068 -0.17559814453125 +17069 -0.16461181640625 +17070 -0.3143310546875 +17071 -0.287628173828125 +17072 -0.36785888671875 +17073 -0.33453369140625 +17074 -0.36248779296875 +17075 -0.32867431640625 +17076 -0.343536376953125 +17077 -0.310394287109375 +17078 -0.3018798828125 +17079 -0.27166748046875 +17080 -0.231414794921875 +17081 -0.207183837890625 +17082 -0.117645263671875 +17083 -0.10418701171875 +17084 0.007049560546875 +17085 0.008453369140625 +17086 0.087982177734375 +17087 0.082061767578125 +17088 0.13946533203125 +17089 0.1292724609375 +17090 0.17425537109375 +17091 0.161346435546875 +17092 0.188201904296875 +17093 0.17449951171875 +17094 0.171234130859375 +17095 0.1597900390625 +17096 0.118438720703125 +17097 0.112823486328125 +17098 0.05706787109375 +17099 0.057830810546875 +17100 -0.010711669921875 +17101 -0.00323486328125 +17102 -0.0914306640625 +17103 -0.07611083984375 +17104 -0.162322998046875 +17105 -0.140472412109375 +17106 -0.194549560546875 +17107 -0.170684814453125 +17108 -0.1492919921875 +17109 -0.132171630859375 +17110 -0.02166748046875 +17111 -0.020477294921875 +17112 0.124053955078125 +17113 0.107391357421875 +17114 0.211151123046875 +17115 0.18341064453125 +17116 0.240447998046875 +17117 0.2083740234375 +17118 0.242218017578125 +17119 0.209197998046875 +17120 0.2257080078125 +17121 0.19415283203125 +17122 0.194366455078125 +17123 0.166290283203125 +17124 0.115509033203125 +17125 0.096588134765625 +17126 0.0128173828125 +17127 0.00604248046875 +17128 -0.053802490234375 +17129 -0.052215576171875 +17130 -0.110626220703125 +17131 -0.101531982421875 +17132 -0.199493408203125 +17133 -0.179168701171875 +17134 -0.29437255859375 +17135 -0.262054443359375 +17136 -0.33221435546875 +17137 -0.294281005859375 +17138 -0.27972412109375 +17139 -0.246368408203125 +17140 -0.185333251953125 +17141 -0.16143798828125 +17142 -0.128204345703125 +17143 -0.109771728515625 +17144 -0.115692138671875 +17145 -0.09796142578125 +17146 -0.116455078125 +17147 -0.09820556640625 +17148 -0.105926513671875 +17149 -0.088714599609375 +17150 -0.053955078125 +17151 -0.042724609375 +17152 0.048797607421875 +17153 0.0478515625 +17154 0.157318115234375 +17155 0.1434326171875 +17156 0.212005615234375 +17157 0.192230224609375 +17158 0.218475341796875 +17159 0.198883056640625 +17160 0.23724365234375 +17161 0.21514892578125 +17162 0.30535888671875 +17163 0.272796630859375 +17164 0.38128662109375 +17165 0.3363037109375 +17166 0.404449462890625 +17167 0.353973388671875 +17168 0.3944091796875 +17169 0.34271240234375 +17170 0.3885498046875 +17171 0.334716796875 +17172 0.362640380859375 +17173 0.309478759765625 +17174 0.27362060546875 +17175 0.230316162109375 +17176 0.11712646484375 +17177 0.09368896484375 +17178 -0.054901123046875 +17179 -0.055816650390625 +17180 -0.19085693359375 +17181 -0.173858642578125 +17182 -0.28570556640625 +17183 -0.256072998046875 +17184 -0.339263916015625 +17185 -0.302276611328125 +17186 -0.3775634765625 +17187 -0.334747314453125 +17188 -0.445709228515625 +17189 -0.392120361328125 +17190 -0.535064697265625 +17191 -0.46710205078125 +17192 -0.629058837890625 +17193 -0.54559326171875 +17194 -0.697601318359375 +17195 -0.601959228515625 +17196 -0.70391845703125 +17197 -0.6048583984375 +17198 -0.6424560546875 +17199 -0.5496826171875 +17200 -0.491241455078125 +17201 -0.417755126953125 +17202 -0.265716552734375 +17203 -0.222412109375 +17204 -0.023712158203125 +17205 -0.0133056640625 +17206 0.201751708984375 +17207 0.181182861328125 +17208 0.375823974609375 +17209 0.3311767578125 +17210 0.485076904296875 +17211 0.425140380859375 +17212 0.56884765625 +17213 0.496734619140625 +17214 0.634765625 +17215 0.552520751953125 +17216 0.63763427734375 +17217 0.553863525390625 +17218 0.5660400390625 +17219 0.491058349609375 +17220 0.4720458984375 +17221 0.40875244140625 +17222 0.40692138671875 +17223 0.3509521484375 +17224 0.3778076171875 +17225 0.323883056640625 +17226 0.376953125 +17227 0.321044921875 +17228 0.371978759765625 +17229 0.3148193359375 +17230 0.313140869140625 +17231 0.26275634765625 +17232 0.184417724609375 +17233 0.151214599609375 +17234 0.011199951171875 +17235 0.001983642578125 +17236 -0.171051025390625 +17237 -0.154510498046875 +17238 -0.33740234375 +17239 -0.29693603515625 +17240 -0.47198486328125 +17241 -0.411712646484375 +17242 -0.560394287109375 +17243 -0.486572265625 +17244 -0.58056640625 +17245 -0.502685546875 +17246 -0.54754638671875 +17247 -0.472991943359375 +17248 -0.508575439453125 +17249 -0.438018798828125 +17250 -0.459503173828125 +17251 -0.394287109375 +17252 -0.394378662109375 +17253 -0.336822509765625 +17254 -0.35260009765625 +17255 -0.2994384765625 +17256 -0.31170654296875 +17257 -0.262969970703125 +17258 -0.197418212890625 +17259 -0.1639404296875 +17260 -0.007965087890625 +17261 -0.0008544921875 +17262 0.207489013671875 +17263 0.18414306640625 +17264 0.409210205078125 +17265 0.35699462890625 +17266 0.57208251953125 +17267 0.4962158203125 +17268 0.66595458984375 +17269 0.57598876953125 +17270 0.65875244140625 +17271 0.56890869140625 +17272 0.56744384765625 +17273 0.48956298828125 +17274 0.431396484375 +17275 0.371734619140625 +17276 0.29443359375 +17277 0.2530517578125 +17278 0.182464599609375 +17279 0.15576171875 +17280 0.06365966796875 +17281 0.05267333984375 +17282 -0.075958251953125 +17283 -0.068084716796875 +17284 -0.189422607421875 +17285 -0.166229248046875 +17286 -0.271942138671875 +17287 -0.23760986328125 +17288 -0.342529296875 +17289 -0.2984619140625 +17290 -0.364166259765625 +17291 -0.317108154296875 +17292 -0.327239990234375 +17293 -0.285369873046875 +17294 -0.2769775390625 +17295 -0.241943359375 +17296 -0.253692626953125 +17297 -0.22137451171875 +17298 -0.24365234375 +17299 -0.2119140625 +17300 -0.1983642578125 +17301 -0.172119140625 +17302 -0.116241455078125 +17303 -0.1007080078125 +17304 -0.036834716796875 +17305 -0.03155517578125 +17306 0.034881591796875 +17307 0.030975341796875 +17308 0.09124755859375 +17309 0.080291748046875 +17310 0.10888671875 +17311 0.0963134765625 +17312 0.125518798828125 +17313 0.11126708984375 +17314 0.15771484375 +17315 0.13934326171875 +17316 0.17828369140625 +17317 0.157196044921875 +17318 0.17108154296875 +17319 0.150970458984375 +17320 0.129974365234375 +17321 0.115478515625 +17322 0.082427978515625 +17323 0.074249267578125 +17324 0.027679443359375 +17325 0.02667236328125 +17326 -0.065643310546875 +17327 -0.054046630859375 +17328 -0.15936279296875 +17329 -0.135162353515625 +17330 -0.21307373046875 +17331 -0.18206787109375 +17332 -0.234649658203125 +17333 -0.201446533203125 +17334 -0.2001953125 +17335 -0.17279052734375 +17336 -0.119171142578125 +17337 -0.10418701171875 +17338 -0.024749755859375 +17339 -0.02398681640625 +17340 0.085784912109375 +17341 0.070159912109375 +17342 0.178131103515625 +17343 0.14892578125 +17344 0.215576171875 +17345 0.180908203125 +17346 0.211456298828125 +17347 0.177490234375 +17348 0.17523193359375 +17349 0.146759033203125 +17350 0.128753662109375 +17351 0.107421875 +17352 0.1019287109375 +17353 0.085052490234375 +17354 0.0743408203125 +17355 0.062164306640625 +17356 0.04327392578125 +17357 0.036376953125 +17358 0.038177490234375 +17359 0.0328369140625 +17360 0.076263427734375 +17361 0.06622314453125 +17362 0.14105224609375 +17363 0.12237548828125 +17364 0.186431884765625 +17365 0.16180419921875 +17366 0.188812255859375 +17367 0.164276123046875 +17368 0.1390380859375 +17369 0.121917724609375 +17370 0.041778564453125 +17371 0.038726806640625 +17372 -0.079437255859375 +17373 -0.06512451171875 +17374 -0.219390869140625 +17375 -0.1851806640625 +17376 -0.367828369140625 +17377 -0.312591552734375 +17378 -0.494873046875 +17379 -0.421783447265625 +17380 -0.556243896484375 +17381 -0.474853515625 +17382 -0.508697509765625 +17383 -0.43475341796875 +17384 -0.3756103515625 +17385 -0.321441650390625 +17386 -0.218902587890625 +17387 -0.187896728515625 +17388 -0.063751220703125 +17389 -0.055633544921875 +17390 0.091552734375 +17391 0.076812744140625 +17392 0.23602294921875 +17393 0.2000732421875 +17394 0.342987060546875 +17395 0.29132080078125 +17396 0.39520263671875 +17397 0.335845947265625 +17398 0.389373779296875 +17399 0.330810546875 +17400 0.324249267578125 +17401 0.275177001953125 +17402 0.224090576171875 +17403 0.189666748046875 +17404 0.124267578125 +17405 0.10455322265625 +17406 0.037078857421875 +17407 0.030303955078125 +17408 -0.010101318359375 +17409 -0.01007080078125 +17410 -0.019439697265625 +17411 -0.01824951171875 +17412 -0.022796630859375 +17413 -0.020843505859375 +17414 -0.001556396484375 +17415 -0.00274658203125 +17416 0.056304931640625 +17417 0.045745849609375 +17418 0.106719970703125 +17419 0.088134765625 +17420 0.096893310546875 +17421 0.080780029296875 +17422 0.042694091796875 +17423 0.03668212890625 +17424 -0.018035888671875 +17425 -0.01300048828125 +17426 -0.07586669921875 +17427 -0.060516357421875 +17428 -0.11944580078125 +17429 -0.09649658203125 +17430 -0.15972900390625 +17431 -0.129974365234375 +17432 -0.202606201171875 +17433 -0.165771484375 +17434 -0.24859619140625 +17435 -0.2042236328125 +17436 -0.30517578125 +17437 -0.251434326171875 +17438 -0.36212158203125 +17439 -0.298980712890625 +17440 -0.39141845703125 +17441 -0.32373046875 +17442 -0.35528564453125 +17443 -0.294464111328125 +17444 -0.249969482421875 +17445 -0.208099365234375 +17446 -0.092864990234375 +17447 -0.07891845703125 +17448 0.08905029296875 +17449 0.07086181640625 +17450 0.2352294921875 +17451 0.191314697265625 +17452 0.318817138671875 +17453 0.260345458984375 +17454 0.358642578125 +17455 0.293426513671875 +17456 0.347747802734375 +17457 0.284820556640625 +17458 0.28564453125 +17459 0.234130859375 +17460 0.223175048828125 +17461 0.183197021484375 +17462 0.196746826171875 +17463 0.161956787109375 +17464 0.179840087890625 +17465 0.1485595703125 +17466 0.155548095703125 +17467 0.129058837890625 +17468 0.151214599609375 +17469 0.1259765625 +17470 0.156951904296875 +17471 0.131103515625 +17472 0.13177490234375 +17473 0.11065673828125 +17474 0.100799560546875 +17475 0.085296630859375 +17476 0.087127685546875 +17477 0.074066162109375 +17478 0.05487060546875 +17479 0.047393798828125 +17480 -0.009002685546875 +17481 -0.00543212890625 +17482 -0.10400390625 +17483 -0.083984375 +17484 -0.229400634765625 +17485 -0.18768310546875 +17486 -0.35552978515625 +17487 -0.29205322265625 +17488 -0.441925048828125 +17489 -0.36370849609375 +17490 -0.473846435546875 +17491 -0.3905029296875 +17492 -0.464813232421875 +17493 -0.383514404296875 +17494 -0.419097900390625 +17495 -0.346221923828125 +17496 -0.334320068359375 +17497 -0.27667236328125 +17498 -0.227935791015625 +17499 -0.189239501953125 +17500 -0.12347412109375 +17501 -0.103302001953125 +17502 -0.02764892578125 +17503 -0.02435302734375 +17504 0.077667236328125 +17505 0.062530517578125 +17506 0.2132568359375 +17507 0.1744384765625 +17508 0.38885498046875 +17509 0.319366455078125 +17510 0.582794189453125 +17511 0.479461669921875 +17512 0.734039306640625 +17513 0.604400634765625 +17514 0.800140380859375 +17515 0.659210205078125 +17516 0.7783203125 +17517 0.64154052734375 +17518 0.6651611328125 +17519 0.548583984375 +17520 0.45965576171875 +17521 0.3795166015625 +17522 0.199188232421875 +17523 0.16510009765625 +17524 -0.050689697265625 +17525 -0.0406494140625 +17526 -0.23297119140625 +17527 -0.190765380859375 +17528 -0.33013916015625 +17529 -0.27081298828125 +17530 -0.368408203125 +17531 -0.3023681640625 +17532 -0.378936767578125 +17533 -0.31109619140625 +17534 -0.376983642578125 +17535 -0.30963134765625 +17536 -0.37969970703125 +17537 -0.31207275390625 +17538 -0.391510009765625 +17539 -0.322052001953125 +17540 -0.385345458984375 +17541 -0.3172607421875 +17542 -0.3419189453125 +17543 -0.281768798828125 +17544 -0.28289794921875 +17545 -0.233428955078125 +17546 -0.251617431640625 +17547 -0.207916259765625 +17548 -0.266143798828125 +17549 -0.2200927734375 +17550 -0.273345947265625 +17551 -0.2261962890625 +17552 -0.216796875 +17553 -0.179718017578125 +17554 -0.128265380859375 +17555 -0.1068115234375 +17556 -0.068145751953125 +17557 -0.0572509765625 +17558 -0.0430908203125 +17559 -0.0364990234375 +17560 -0.024444580078125 +17561 -0.020965576171875 +17562 0.020721435546875 +17563 0.0164794921875 +17564 0.124481201171875 +17565 0.10223388671875 +17566 0.25787353515625 +17567 0.21240234375 +17568 0.379119873046875 +17569 0.31256103515625 +17570 0.47991943359375 +17571 0.3958740234375 +17572 0.5281982421875 +17573 0.435882568359375 +17574 0.511138916015625 +17575 0.4219970703125 +17576 0.456207275390625 +17577 0.376861572265625 +17578 0.407470703125 +17579 0.3367919921875 +17580 0.383758544921875 +17581 0.317291259765625 +17582 0.35687255859375 +17583 0.29510498046875 +17584 0.31182861328125 +17585 0.257904052734375 +17586 0.250885009765625 +17587 0.20751953125 +17588 0.1654052734375 +17589 0.136871337890625 +17590 0.035247802734375 +17591 0.029388427734375 +17592 -0.142059326171875 +17593 -0.116943359375 +17594 -0.33563232421875 +17595 -0.27667236328125 +17596 -0.5345458984375 +17597 -0.440765380859375 +17598 -0.72186279296875 +17599 -0.595245361328125 +17600 -0.836669921875 +17601 -0.68994140625 +17602 -0.8326416015625 +17603 -0.68670654296875 +17604 -0.7296142578125 +17605 -0.60186767578125 +17606 -0.582550048828125 +17607 -0.480712890625 +17608 -0.440093994140625 +17609 -0.363311767578125 +17610 -0.324310302734375 +17611 -0.267852783203125 +17612 -0.20147705078125 +17613 -0.16656494140625 +17614 -0.044647216796875 +17615 -0.0372314453125 +17616 0.103973388671875 +17617 0.085357666015625 +17618 0.202392578125 +17619 0.166595458984375 +17620 0.264495849609375 +17621 0.2178955078125 +17622 0.338897705078125 +17623 0.279327392578125 +17624 0.443817138671875 +17625 0.365875244140625 +17626 0.545074462890625 +17627 0.44940185546875 +17628 0.6173095703125 +17629 0.50897216796875 +17630 0.6524658203125 +17631 0.537994384765625 +17632 0.66339111328125 +17633 0.547027587890625 +17634 0.6561279296875 +17635 0.541046142578125 +17636 0.606781005859375 +17637 0.500335693359375 +17638 0.501190185546875 +17639 0.413238525390625 +17640 0.352783203125 +17641 0.29083251953125 +17642 0.176544189453125 +17643 0.145477294921875 +17644 -0.034820556640625 +17645 -0.02880859375 +17646 -0.258209228515625 +17647 -0.212982177734375 +17648 -0.44244384765625 +17649 -0.364898681640625 +17650 -0.5753173828125 +17651 -0.47442626953125 +17652 -0.65203857421875 +17653 -0.53765869140625 +17654 -0.641632080078125 +17655 -0.529083251953125 +17656 -0.562164306640625 +17657 -0.463592529296875 +17658 -0.458038330078125 +17659 -0.377777099609375 +17660 -0.350555419921875 +17661 -0.289154052734375 +17662 -0.260528564453125 +17663 -0.214874267578125 +17664 -0.192108154296875 +17665 -0.158233642578125 +17666 -0.141937255859375 +17667 -0.11639404296875 +17668 -0.1021728515625 +17669 -0.08319091796875 +17670 -0.062896728515625 +17671 -0.050567626953125 +17672 -0.011932373046875 +17673 -0.00872802734375 +17674 0.062835693359375 +17675 0.05194091796875 +17676 0.148712158203125 +17677 0.121368408203125 +17678 0.241729736328125 +17679 0.19635009765625 +17680 0.34912109375 +17681 0.2825927734375 +17682 0.457305908203125 +17683 0.369293212890625 +17684 0.54388427734375 +17685 0.438629150390625 +17686 0.5728759765625 +17687 0.462066650390625 +17688 0.506591796875 +17689 0.409698486328125 +17690 0.351226806640625 +17691 0.286407470703125 +17692 0.146514892578125 +17693 0.123626708984375 +17694 -0.05523681640625 +17695 -0.037139892578125 +17696 -0.21624755859375 +17697 -0.165924072265625 +17698 -0.334930419921875 +17699 -0.26141357421875 +17700 -0.402984619140625 +17701 -0.31695556640625 +17702 -0.4412841796875 +17703 -0.3489990234375 +17704 -0.49578857421875 +17705 -0.39385986328125 +17706 -0.5601806640625 +17707 -0.4464111328125 +17708 -0.600738525390625 +17709 -0.479888916015625 +17710 -0.584228515625 +17711 -0.4678955078125 +17712 -0.47930908203125 +17713 -0.38555908203125 +17714 -0.27935791015625 +17715 -0.227630615234375 +17716 -0.0089111328125 +17717 -0.013519287109375 +17718 0.268798828125 +17719 0.206695556640625 +17720 0.482818603515625 +17721 0.376800537109375 +17722 0.60369873046875 +17723 0.473419189453125 +17724 0.650421142578125 +17725 0.51153564453125 +17726 0.66400146484375 +17727 0.5235595703125 +17728 0.6414794921875 +17729 0.507080078125 +17730 0.572540283203125 +17731 0.453857421875 +17732 0.498138427734375 +17733 0.396240234375 +17734 0.439453125 +17735 0.3509521484375 +17736 0.375518798828125 +17737 0.301300048828125 +17738 0.274505615234375 +17739 0.222015380859375 +17740 0.1087646484375 +17741 0.0911865234375 +17742 -0.099395751953125 +17743 -0.073516845703125 +17744 -0.3182373046875 +17745 -0.2469482421875 +17746 -0.5489501953125 +17747 -0.4300537109375 +17748 -0.7738037109375 +17749 -0.608734130859375 +17750 -0.86383056640625 +17751 -0.74102783203125 +17752 -0.870391845703125 +17753 -0.800567626953125 +17754 -0.86895751953125 +17755 -0.801300048828125 +17756 -0.861053466796875 +17757 -0.7535400390625 +17758 -0.765869140625 +17759 -0.6435546875 +17760 -0.5301513671875 +17761 -0.462371826171875 +17762 -0.214691162109375 +17763 -0.215576171875 +17764 0.137359619140625 +17765 0.062774658203125 +17766 0.474822998046875 +17767 0.33209228515625 +17768 0.76239013671875 +17769 0.564208984375 +17770 0.867462158203125 +17771 0.737762451171875 +17772 0.870361328125 +17773 0.85308837890625 +17774 0.86480712890625 +17775 0.85955810546875 +17776 0.831817626953125 +17777 0.857879638671875 +17778 0.677581787109375 +17779 0.82666015625 +17780 0.495880126953125 +17781 0.7281494140625 +17782 0.30767822265625 +17783 0.60491943359375 +17784 0.116180419921875 +17785 0.45867919921875 +17786 -0.110748291015625 +17787 0.26422119140625 +17788 -0.381805419921875 +17789 0.016021728515625 +17790 -0.6572265625 +17791 -0.25201416015625 +17792 -0.857421875 +17793 -0.49249267578125 +17794 -0.870391845703125 +17795 -0.67138671875 +17796 -0.870391845703125 +17797 -0.783050537109375 +17798 -0.86444091796875 +17799 -0.8487548828125 +17800 -0.85723876953125 +17801 -0.859130859375 +17802 -0.790008544921875 +17803 -0.86083984375 +17804 -0.62847900390625 +17805 -0.852935791015625 +17806 -0.3956298828125 +17807 -0.715576171875 +17808 -0.126708984375 +17809 -0.5263671875 +17810 0.150115966796875 +17811 -0.30694580078125 +17812 0.424041748046875 +17813 -0.066558837890625 +17814 0.670623779296875 +17815 0.173431396484375 +17816 0.854522705078125 +17817 0.382354736328125 +17818 0.866485595703125 +17819 0.54620361328125 +17820 0.86920166015625 +17821 0.652801513671875 +17822 0.8653564453125 +17823 0.71649169921875 +17824 0.857147216796875 +17825 0.747833251953125 +17826 0.766845703125 +17827 0.7445068359375 +17828 0.628509521484375 +17829 0.710540771484375 +17830 0.462127685546875 +17831 0.64056396484375 +17832 0.297210693359375 +17833 0.555023193359375 +17834 0.14862060546875 +17835 0.46368408203125 +17836 -0.00537109375 +17837 0.348419189453125 +17838 -0.15753173828125 +17839 0.21514892578125 +17840 -0.31304931640625 +17841 0.061004638671875 +17842 -0.48876953125 +17843 -0.125091552734375 +17844 -0.6416015625 +17845 -0.30596923828125 +17846 -0.751373291015625 +17847 -0.4620361328125 +17848 -0.84619140625 +17849 -0.61151123046875 +17850 -0.861297607421875 +17851 -0.74273681640625 +17852 -0.863250732421875 +17853 -0.829376220703125 +17854 -0.856597900390625 +17855 -0.846435546875 +17856 -0.7498779296875 +17857 -0.803497314453125 +17858 -0.624542236328125 +17859 -0.746337890625 +17860 -0.47808837890625 +17861 -0.657501220703125 +17862 -0.253387451171875 +17863 -0.490692138671875 +17864 0.003692626953125 +17865 -0.282073974609375 +17866 0.2257080078125 +17867 -0.085784912109375 +17868 0.427154541015625 +17869 0.1080322265625 +17870 0.643218994140625 +17871 0.32501220703125 +17872 0.855926513671875 +17873 0.55743408203125 +17874 0.870361328125 +17875 0.759368896484375 +17876 0.870361328125 +17877 0.8585205078125 +17878 0.862762451171875 +17879 0.86590576171875 +17880 0.79669189453125 +17881 0.86602783203125 +17882 0.595794677734375 +17883 0.858062744140625 +17884 0.362152099609375 +17885 0.763336181640625 +17886 0.1270751953125 +17887 0.610443115234375 +17888 -0.086944580078125 +17889 0.44549560546875 +17890 -0.2784423828125 +17891 0.270172119140625 +17892 -0.484832763671875 +17893 0.056976318359375 +17894 -0.729583740234375 +17895 -0.209197998046875 +17896 -0.86688232421875 +17897 -0.48822021484375 +17898 -0.870391845703125 +17899 -0.729827880859375 +17900 -0.86859130859375 +17901 -0.86273193359375 +17902 -0.86279296875 +17903 -0.870391845703125 +17904 -0.817962646484375 +17905 -0.870391845703125 +17906 -0.6116943359375 +17907 -0.859893798828125 +17908 -0.3128662109375 +17909 -0.709716796875 +17910 0.039398193359375 +17911 -0.44677734375 +17912 0.422821044921875 +17913 -0.132598876953125 +17914 0.805145263671875 +17915 0.205841064453125 +17916 0.870361328125 +17917 0.515167236328125 +17918 0.870361328125 +17919 0.751739501953125 +17920 0.860015869140625 +17921 0.860382080078125 +17922 0.727935791015625 +17923 0.868499755859375 +17924 0.48114013671875 +17925 0.86761474609375 +17926 0.2059326171875 +17927 0.860137939453125 +17928 -0.06103515625 +17929 0.799102783203125 +17930 -0.29913330078125 +17931 0.664947509765625 +17932 -0.516204833984375 +17933 0.496826171875 +17934 -0.7252197265625 +17935 0.28656005859375 +17936 -0.85980224609375 +17937 0.055999755859375 +17938 -0.870391845703125 +17939 -0.166534423828125 +17940 -0.870391845703125 +17941 -0.357177734375 +17942 -0.858062744140625 +17943 -0.4783935546875 +17944 -0.673004150390625 +17945 -0.527313232421875 +17946 -0.42694091796875 +17947 -0.544921875 +17948 -0.2100830078125 +17949 -0.566802978515625 +17950 -0.0362548828125 +17951 -0.593780517578125 +17952 0.10943603515625 +17953 -0.606658935546875 +17954 0.23516845703125 +17955 -0.593505859375 +17956 0.373687744140625 +17957 -0.526123046875 +17958 0.517791748046875 +17959 -0.40924072265625 +17960 0.602783203125 +17961 -0.293701171875 +17962 0.635711669921875 +17963 -0.17816162109375 +17964 0.655181884765625 +17965 -0.03936767578125 +17966 0.65948486328125 +17967 0.113616943359375 +17968 0.651275634765625 +17969 0.273895263671875 +17970 0.61846923828125 +17971 0.422698974609375 +17972 0.53753662109375 +17973 0.532501220703125 +17974 0.404144287109375 +17975 0.59075927734375 +17976 0.22186279296875 +17977 0.591796875 +17978 0.003997802734375 +17979 0.538726806640625 +17980 -0.22100830078125 +17981 0.447784423828125 +17982 -0.42449951171875 +17983 0.337310791015625 +17984 -0.579833984375 +17985 0.226165771484375 +17986 -0.641876220703125 +17987 0.14935302734375 +17988 -0.6177978515625 +17989 0.104095458984375 +17990 -0.575531005859375 +17991 0.043182373046875 +17992 -0.526336669921875 +17993 -0.035980224609375 +17994 -0.42645263671875 +17995 -0.0931396484375 +17996 -0.2581787109375 +17997 -0.1070556640625 +17998 -0.068695068359375 +17999 -0.105621337890625 +18000 0.09222412109375 +18001 -0.118865966796875 +18002 0.232147216796875 +18003 -0.133819580078125 +18004 0.3509521484375 +18005 -0.144378662109375 +18006 0.410064697265625 +18007 -0.17498779296875 +18008 0.372955322265625 +18009 -0.25 +18010 0.2554931640625 +18011 -0.3555908203125 +18012 0.10711669921875 +18013 -0.454193115234375 +18014 -0.052886962890625 +18015 -0.5328369140625 +18016 -0.186279296875 +18017 -0.56561279296875 +18018 -0.23291015625 +18019 -0.511322021484375 +18020 -0.209442138671875 +18021 -0.38812255859375 +18022 -0.174163818359375 +18023 -0.2464599609375 +18024 -0.126739501953125 +18025 -0.0926513671875 +18026 -0.048126220703125 +18027 0.08123779296875 +18028 0.0426025390625 +18029 0.254638671875 +18030 0.10748291015625 +18031 0.393280029296875 +18032 0.1409912109375 +18033 0.488525390625 +18034 0.19708251953125 +18035 0.578094482421875 +18036 0.273651123046875 +18037 0.658538818359375 +18038 0.31768798828125 +18039 0.689056396484375 +18040 0.341094970703125 +18041 0.679595947265625 +18042 0.368011474609375 +18043 0.65069580078125 +18044 0.37249755859375 +18045 0.5859375 +18046 0.30072021484375 +18047 0.44866943359375 +18048 0.1517333984375 +18049 0.243072509765625 +18050 -0.01470947265625 +18051 0.019866943359375 +18052 -0.1883544921875 +18053 -0.20770263671875 +18054 -0.372711181640625 +18055 -0.4371337890625 +18056 -0.51397705078125 +18057 -0.62286376953125 +18058 -0.57177734375 +18059 -0.730224609375 +18060 -0.53948974609375 +18061 -0.751190185546875 +18062 -0.43511962890625 +18063 -0.697479248046875 +18064 -0.2962646484375 +18065 -0.596832275390625 +18066 -0.161102294921875 +18067 -0.478607177734375 +18068 -0.0435791015625 +18069 -0.35479736328125 +18070 0.060394287109375 +18071 -0.2247314453125 +18072 0.13665771484375 +18073 -0.102386474609375 +18074 0.170135498046875 +18075 -0.003143310546875 +18076 0.16552734375 +18077 0.072265625 +18078 0.15728759765625 +18079 0.14556884765625 +18080 0.150787353515625 +18081 0.21649169921875 +18082 0.12200927734375 +18083 0.26275634765625 +18084 0.080108642578125 +18085 0.287811279296875 +18086 0.05126953125 +18087 0.308807373046875 +18088 0.062896728515625 +18089 0.344635009765625 +18090 0.09271240234375 +18091 0.3773193359375 +18092 0.092987060546875 +18093 0.37054443359375 +18094 0.07855224609375 +18095 0.33642578125 +18096 0.06427001953125 +18097 0.287994384765625 +18098 0.0347900390625 +18099 0.216064453125 +18100 -0.01171875 +18101 0.122222900390625 +18102 -0.056060791015625 +18103 0.024566650390625 +18104 -0.055511474609375 +18105 -0.040802001953125 +18106 -0.010467529296875 +18107 -0.07049560546875 +18108 0.02508544921875 +18109 -0.10211181640625 +18110 0.025665283203125 +18111 -0.1519775390625 +18112 0.017333984375 +18113 -0.197784423828125 +18114 0.00189208984375 +18115 -0.236328125 +18116 -0.03173828125 +18117 -0.274932861328125 +18118 -0.071502685546875 +18119 -0.304168701171875 +18120 -0.13543701171875 +18121 -0.338165283203125 +18122 -0.219970703125 +18123 -0.37542724609375 +18124 -0.300506591796875 +18125 -0.399078369140625 +18126 -0.376312255859375 +18127 -0.410888671875 +18128 -0.416107177734375 +18129 -0.389801025390625 +18130 -0.371124267578125 +18131 -0.301727294921875 +18132 -0.242279052734375 +18133 -0.150360107421875 +18134 -0.069732666015625 +18135 0.030853271484375 +18136 0.125640869140625 +18137 0.223388671875 +18138 0.31268310546875 +18139 0.401336669921875 +18140 0.45501708984375 +18141 0.535369873046875 +18142 0.554779052734375 +18143 0.625946044921875 +18144 0.61065673828125 +18145 0.671600341796875 +18146 0.610931396484375 +18147 0.66357421875 +18148 0.531463623046875 +18149 0.5843505859375 +18150 0.3883056640625 +18151 0.447418212890625 +18152 0.23468017578125 +18153 0.2950439453125 +18154 0.095245361328125 +18155 0.14813232421875 +18156 -0.00396728515625 +18157 0.02880859375 +18158 -0.04852294921875 +18159 -0.0494384765625 +18160 -0.055145263671875 +18161 -0.09686279296875 +18162 -0.0758056640625 +18163 -0.1507568359375 +18164 -0.138702392578125 +18165 -0.230560302734375 +18166 -0.209197998046875 +18167 -0.308380126953125 +18168 -0.289031982421875 +18169 -0.38446044921875 +18170 -0.37884521484375 +18171 -0.458709716796875 +18172 -0.456329345703125 +18173 -0.51409912109375 +18174 -0.51641845703125 +18175 -0.5472412109375 +18176 -0.519287109375 +18177 -0.52899169921875 +18178 -0.458251953125 +18179 -0.45562744140625 +18180 -0.384796142578125 +18181 -0.3675537109375 +18182 -0.323699951171875 +18183 -0.285308837890625 +18184 -0.269287109375 +18185 -0.20672607421875 +18186 -0.1951904296875 +18187 -0.1141357421875 +18188 -0.100006103515625 +18189 -0.008514404296875 +18190 -0.01055908203125 +18191 0.08819580078125 +18192 0.1033935546875 +18193 0.19720458984375 +18194 0.24908447265625 +18195 0.32281494140625 +18196 0.373199462890625 +18197 0.42437744140625 +18198 0.45806884765625 +18199 0.488372802734375 +18200 0.511474609375 +18201 0.520843505859375 +18202 0.565399169921875 +18203 0.546417236328125 +18204 0.61138916015625 +18205 0.559814453125 +18206 0.5897216796875 +18207 0.517547607421875 +18208 0.4906005859375 +18209 0.413818359375 +18210 0.33148193359375 +18211 0.263427734375 +18212 0.147796630859375 +18213 0.09466552734375 +18214 -0.01873779296875 +18215 -0.059478759765625 +18216 -0.140289306640625 +18217 -0.176544189453125 +18218 -0.191986083984375 +18219 -0.236572265625 +18220 -0.184295654296875 +18221 -0.24639892578125 +18222 -0.161834716796875 +18223 -0.238800048828125 +18224 -0.166595458984375 +18225 -0.24493408203125 +18226 -0.19390869140625 +18227 -0.2613525390625 +18228 -0.22442626953125 +18229 -0.27392578125 +18230 -0.279754638671875 +18231 -0.29962158203125 +18232 -0.3389892578125 +18233 -0.32379150390625 +18234 -0.3543701171875 +18235 -0.3118896484375 +18236 -0.348175048828125 +18237 -0.281951904296875 +18238 -0.32598876953125 +18239 -0.239593505859375 +18240 -0.2581787109375 +18241 -0.164031982421875 +18242 -0.139801025390625 +18243 -0.0528564453125 +18244 0.014617919921875 +18245 0.081878662109375 +18246 0.144378662109375 +18247 0.193695068359375 +18248 0.221038818359375 +18249 0.2606201171875 +18250 0.27069091796875 +18251 0.301849365234375 +18252 0.294036865234375 +18253 0.317840576171875 +18254 0.311767578125 +18255 0.324371337890625 +18256 0.339141845703125 +18257 0.33331298828125 +18258 0.360260009765625 +18259 0.333251953125 +18260 0.360504150390625 +18261 0.314300537109375 +18262 0.308380126953125 +18263 0.254730224609375 +18264 0.18170166015625 +18265 0.139739990234375 +18266 0.0047607421875 +18267 -0.011627197265625 +18268 -0.17559814453125 +18269 -0.164031982421875 +18270 -0.3143310546875 +18271 -0.283538818359375 +18272 -0.36785888671875 +18273 -0.337493896484375 +18274 -0.36248779296875 +18275 -0.34429931640625 +18276 -0.343536376953125 +18277 -0.336456298828125 +18278 -0.3018798828125 +18279 -0.307159423828125 +18280 -0.231414794921875 +18281 -0.252044677734375 +18282 -0.117645263671875 +18283 -0.160919189453125 +18284 0.007049560546875 +18285 -0.057952880859375 +18286 0.087982177734375 +18287 0.016265869140625 +18288 0.13946533203125 +18289 0.07122802734375 +18290 0.17425537109375 +18291 0.115203857421875 +18292 0.188201904296875 +18293 0.14410400390625 +18294 0.171234130859375 +18295 0.1495361328125 +18296 0.118438720703125 +18297 0.12701416015625 +18298 0.05706787109375 +18299 0.0955810546875 +18300 -0.010711669921875 +18301 0.056121826171875 +18302 -0.0914306640625 +18303 0.003448486328125 +18304 -0.162322998046875 +18305 -0.0460205078125 +18306 -0.194549560546875 +18307 -0.07135009765625 +18308 -0.1492919921875 +18309 -0.0440673828125 +18310 -0.02166748046875 +18311 0.039794921875 +18312 0.124053955078125 +18313 0.134063720703125 +18314 0.211151123046875 +18315 0.183624267578125 +18316 0.240447998046875 +18317 0.18988037109375 +18318 0.242218017578125 +18319 0.175689697265625 +18320 0.2257080078125 +18321 0.148681640625 +18322 0.194366455078125 +18323 0.1121826171875 +18324 0.115509033203125 +18325 0.043060302734375 +18326 0.0128173828125 +18327 -0.040802001953125 +18328 -0.053802490234375 +18329 -0.095367431640625 +18330 -0.110626220703125 +18331 -0.139556884765625 +18332 -0.199493408203125 +18333 -0.20379638671875 +18334 -0.29437255859375 +18335 -0.26922607421875 +18336 -0.33221435546875 +18337 -0.290252685546875 +18338 -0.27972412109375 +18339 -0.243072509765625 +18340 -0.185333251953125 +18341 -0.16351318359375 +18342 -0.128204345703125 +18343 -0.10980224609375 +18344 -0.115692138671875 +18345 -0.087982177734375 +18346 -0.116455078125 +18347 -0.07598876953125 +18348 -0.105926513671875 +18349 -0.056610107421875 +18350 -0.053955078125 +18351 -0.008544921875 +18352 0.048797607421875 +18353 0.07452392578125 +18354 0.157318115234375 +18355 0.159423828125 +18356 0.212005615234375 +18357 0.2025146484375 +18358 0.218475341796875 +18359 0.207794189453125 +18360 0.23724365234375 +18361 0.219329833984375 +18362 0.30535888671875 +18363 0.264312744140625 +18364 0.38128662109375 +18365 0.31280517578125 +18366 0.404449462890625 +18367 0.321136474609375 +18368 0.3944091796875 +18369 0.3040771484375 +18370 0.3885498046875 +18371 0.289398193359375 +18372 0.362640380859375 +18373 0.26007080078125 +18374 0.27362060546875 +18375 0.185302734375 +18376 0.11712646484375 +18377 0.06243896484375 +18378 -0.054901123046875 +18379 -0.070220947265625 +18380 -0.19085693359375 +18381 -0.174713134765625 +18382 -0.28570556640625 +18383 -0.247161865234375 +18384 -0.339263916015625 +18385 -0.287322998046875 +18386 -0.3775634765625 +18387 -0.314117431640625 +18388 -0.445709228515625 +18389 -0.36053466796875 +18390 -0.535064697265625 +18391 -0.4205322265625 +18392 -0.629058837890625 +18393 -0.48236083984375 +18394 -0.697601318359375 +18395 -0.524505615234375 +18396 -0.70391845703125 +18397 -0.520660400390625 +18398 -0.6424560546875 +18399 -0.467254638671875 +18400 -0.491241455078125 +18401 -0.348785400390625 +18402 -0.265716552734375 +18403 -0.176910400390625 +18404 -0.023712158203125 +18405 0.00579833984375 +18406 0.201751708984375 +18407 0.17498779296875 +18408 0.375823974609375 +18409 0.305084228515625 +18410 0.485076904296875 +18411 0.386199951171875 +18412 0.56884765625 +18413 0.4468994140625 +18414 0.634765625 +18415 0.492828369140625 +18416 0.63763427734375 +18417 0.49127197265625 +18418 0.5660400390625 +18419 0.434112548828125 +18420 0.4720458984375 +18421 0.35955810546875 +18422 0.40692138671875 +18423 0.305328369140625 +18424 0.3778076171875 +18425 0.277008056640625 +18426 0.376953125 +18427 0.26934814453125 +18428 0.371978759765625 +18429 0.2591552734375 +18430 0.313140869140625 +18431 0.2105712890625 +18432 0.184417724609375 +18433 0.112457275390625 +18434 0.011199951171875 +18435 -0.016204833984375 +18436 -0.171051025390625 +18437 -0.14971923828125 +18438 -0.33740234375 +18439 -0.2703857421875 +18440 -0.47198486328125 +18441 -0.36688232421875 +18442 -0.560394287109375 +18443 -0.429046630859375 +18444 -0.58056640625 +18445 -0.441558837890625 +18446 -0.54754638671875 +18447 -0.415008544921875 +18448 -0.508575439453125 +18449 -0.382537841796875 +18450 -0.459503173828125 +18451 -0.34161376953125 +18452 -0.394378662109375 +18453 -0.288482666015625 +18454 -0.35260009765625 +18455 -0.25103759765625 +18456 -0.31170654296875 +18457 -0.214080810546875 +18458 -0.197418212890625 +18459 -0.12640380859375 +18460 -0.007965087890625 +18461 0.012786865234375 +18462 0.207489013671875 +18463 0.16888427734375 +18464 0.409210205078125 +18465 0.31390380859375 +18466 0.57208251953125 +18467 0.430145263671875 +18468 0.66595458984375 +18469 0.496551513671875 +18470 0.65875244140625 +18471 0.490753173828125 +18472 0.56744384765625 +18473 0.4246826171875 +18474 0.431396484375 +18475 0.325897216796875 +18476 0.29443359375 +18477 0.2252197265625 +18478 0.182464599609375 +18479 0.140960693359375 +18480 0.06365966796875 +18481 0.0513916015625 +18482 -0.075958251953125 +18483 -0.0528564453125 +18484 -0.189422607421875 +18485 -0.138671875 +18486 -0.271942138671875 +18487 -0.202362060546875 +18488 -0.342529296875 +18489 -0.2568359375 +18490 -0.364166259765625 +18491 -0.276092529296875 +18492 -0.327239990234375 +18493 -0.25323486328125 +18494 -0.2769775390625 +18495 -0.219635009765625 +18496 -0.253692626953125 +18497 -0.20330810546875 +18498 -0.24365234375 +18499 -0.194732666015625 +18500 -0.1983642578125 +18501 -0.160308837890625 +18502 -0.116241455078125 +18503 -0.09912109375 +18504 -0.036834716796875 +18505 -0.038909912109375 +18506 0.034881591796875 +18507 0.01654052734375 +18508 0.09124755859375 +18509 0.06158447265625 +18510 0.10888671875 +18511 0.079620361328125 +18512 0.125518798828125 +18513 0.0965576171875 +18514 0.15771484375 +18515 0.1236572265625 +18516 0.17828369140625 +18517 0.14178466796875 +18518 0.17108154296875 +18519 0.139495849609375 +18520 0.129974365234375 +18521 0.1124267578125 +18522 0.082427978515625 +18523 0.079620361328125 +18524 0.027679443359375 +18525 0.04058837890625 +18526 -0.065643310546875 +18527 -0.026397705078125 +18528 -0.15936279296875 +18529 -0.0946044921875 +18530 -0.21307373046875 +18531 -0.135772705078125 +18532 -0.234649658203125 +18533 -0.1551513671875 +18534 -0.2001953125 +18535 -0.135833740234375 +18536 -0.119171142578125 +18537 -0.08416748046875 +18538 -0.024749755859375 +18539 -0.02294921875 +18540 0.085784912109375 +18541 0.0499267578125 +18542 0.178131103515625 +18543 0.11077880859375 +18544 0.215576171875 +18545 0.134246826171875 +18546 0.211456298828125 +18547 0.12969970703125 +18548 0.17523193359375 +18549 0.10382080078125 +18550 0.128753662109375 +18551 0.071807861328125 +18552 0.1019287109375 +18553 0.054443359375 +18554 0.0743408203125 +18555 0.037445068359375 +18556 0.04327392578125 +18557 0.01873779296875 +18558 0.038177490234375 +18559 0.018646240234375 +18560 0.076263427734375 +18561 0.048919677734375 +18562 0.14105224609375 +18563 0.097869873046875 +18564 0.186431884765625 +18565 0.13323974609375 +18566 0.188812255859375 +18567 0.13836669921875 +18568 0.1390380859375 +18569 0.106689453125 +18570 0.041778564453125 +18571 0.041351318359375 +18572 -0.079437255859375 +18573 -0.0413818359375 +18574 -0.219390869140625 +18575 -0.137969970703125 +18576 -0.367828369140625 +18577 -0.24127197265625 +18578 -0.494873046875 +18579 -0.330474853515625 +18580 -0.556243896484375 +18581 -0.374725341796875 +18582 -0.508697509765625 +18583 -0.343780517578125 +18584 -0.3756103515625 +18585 -0.2537841796875 +18586 -0.218902587890625 +18587 -0.147705078125 +18588 -0.063751220703125 +18589 -0.0428466796875 +18590 0.091552734375 +18591 0.062103271484375 +18592 0.23602294921875 +18593 0.15966796875 +18594 0.342987060546875 +18595 0.2314453125 +18596 0.39520263671875 +18597 0.265625 +18598 0.389373779296875 +18599 0.259979248046875 +18600 0.324249267578125 +18601 0.213714599609375 +18602 0.224090576171875 +18603 0.14373779296875 +18604 0.124267578125 +18605 0.074676513671875 +18606 0.037078857421875 +18607 0.0150146484375 +18608 -0.010101318359375 +18609 -0.016204833984375 +18610 -0.019439697265625 +18611 -0.0206298828125 +18612 -0.022796630859375 +18613 -0.02056884765625 +18614 -0.001556396484375 +18615 -0.003204345703125 +18616 0.056304931640625 +18617 0.0396728515625 +18618 0.106719970703125 +18619 0.0772705078125 +18620 0.096893310546875 +18621 0.07269287109375 +18622 0.042694091796875 +18623 0.036895751953125 +18624 -0.018035888671875 +18625 -0.003875732421875 +18626 -0.07586669921875 +18627 -0.04315185546875 +18628 -0.11944580078125 +18629 -0.07305908203125 +18630 -0.15972900390625 +18631 -0.101226806640625 +18632 -0.202606201171875 +18633 -0.1317138671875 +18634 -0.24859619140625 +18635 -0.164825439453125 +18636 -0.30517578125 +18637 -0.2056884765625 +18638 -0.36212158203125 +18639 -0.24713134765625 +18640 -0.39141845703125 +18641 -0.269561767578125 +18642 -0.35528564453125 +18643 -0.246551513671875 +18644 -0.249969482421875 +18645 -0.175384521484375 +18646 -0.092864990234375 +18647 -0.06805419921875 +18648 0.08905029296875 +18649 0.056793212890625 +18650 0.2352294921875 +18651 0.1571044921875 +18652 0.318817138671875 +18653 0.214263916015625 +18654 0.358642578125 +18655 0.24139404296875 +18656 0.347747802734375 +18657 0.233673095703125 +18658 0.28564453125 +18659 0.190765380859375 +18660 0.223175048828125 +18661 0.148040771484375 +18662 0.196746826171875 +18663 0.13079833984375 +18664 0.179840087890625 +18665 0.1204833984375 +18666 0.155548095703125 +18667 0.105255126953125 +18668 0.151214599609375 +18669 0.104034423828125 +18670 0.156951904296875 +18671 0.10986328125 +18672 0.13177490234375 +18673 0.094085693359375 +18674 0.100799560546875 +18675 0.0740966796875 +18676 0.087127685546875 +18677 0.06585693359375 +18678 0.05487060546875 +18679 0.04437255859375 +18680 -0.009002685546875 +18681 0.000518798828125 +18682 -0.10400390625 +18683 -0.06536865234375 +18684 -0.229400634765625 +18685 -0.15283203125 +18686 -0.35552978515625 +18687 -0.24114990234375 +18688 -0.441925048828125 +18689 -0.301910400390625 +18690 -0.473846435546875 +18691 -0.32452392578125 +18692 -0.464813232421875 +18693 -0.318206787109375 +18694 -0.419097900390625 +18695 -0.286285400390625 +18696 -0.334320068359375 +18697 -0.227691650390625 +18698 -0.227935791015625 +18699 -0.154388427734375 +18700 -0.12347412109375 +18701 -0.082366943359375 +18702 -0.02764892578125 +18703 -0.01629638671875 +18704 0.077667236328125 +18705 0.055694580078125 +18706 0.2132568359375 +18707 0.14727783203125 +18708 0.38885498046875 +18709 0.264801025390625 +18710 0.582794189453125 +18711 0.3939208984375 +18712 0.734039306640625 +18713 0.494110107421875 +18714 0.800140380859375 +18715 0.537261962890625 +18716 0.7783203125 +18717 0.5216064453125 +18718 0.6651611328125 +18719 0.444976806640625 +18720 0.45965576171875 +18721 0.30682373046875 +18722 0.199188232421875 +18723 0.13214111328125 +18724 -0.050689697265625 +18725 -0.035430908203125 +18726 -0.23297119140625 +18727 -0.157958984375 +18728 -0.33013916015625 +18729 -0.2237548828125 +18730 -0.368408203125 +18731 -0.2501220703125 +18732 -0.378936767578125 +18733 -0.2576904296875 +18734 -0.376983642578125 +18735 -0.256591796875 +18736 -0.37969970703125 +18737 -0.25823974609375 +18738 -0.391510009765625 +18739 -0.265594482421875 +18740 -0.385345458984375 +18741 -0.260711669921875 +18742 -0.3419189453125 +18743 -0.2308349609375 +18744 -0.28289794921875 +18745 -0.1904296875 +18746 -0.251617431640625 +18747 -0.168304443359375 +18748 -0.266143798828125 +18749 -0.176544189453125 +18750 -0.273345947265625 +18751 -0.179962158203125 +18752 -0.216796875 +18753 -0.14117431640625 +18754 -0.128265380859375 +18755 -0.081298828125 +18756 -0.068145751953125 +18757 -0.04052734375 +18758 -0.0430908203125 +18759 -0.0233154296875 +18760 -0.024444580078125 +18761 -0.010650634765625 +18762 0.020721435546875 +18763 0.019317626953125 +18764 0.124481201171875 +18765 0.087890625 +18766 0.25787353515625 +18767 0.175872802734375 +18768 0.379119873046875 +18769 0.25555419921875 +18770 0.47991943359375 +18771 0.32147216796875 +18772 0.5281982421875 +18773 0.352386474609375 +18774 0.511138916015625 +18775 0.339874267578125 +18776 0.456207275390625 +18777 0.302215576171875 +18778 0.407470703125 +18779 0.26873779296875 +18780 0.383758544921875 +18781 0.25201416015625 +18782 0.35687255859375 +18783 0.233367919921875 +18784 0.31182861328125 +18785 0.202880859375 +18786 0.250885009765625 +18787 0.16204833984375 +18788 0.1654052734375 +18789 0.10516357421875 +18790 0.035247802734375 +18791 0.01885986328125 +18792 -0.142059326171875 +18793 -0.0985107421875 +18794 -0.33563232421875 +18795 -0.2264404296875 +18796 -0.5345458984375 +18797 -0.357696533203125 +18798 -0.72186279296875 +18799 -0.481109619140625 +18800 -0.836669921875 +18801 -0.5562744140625 +18802 -0.8326416015625 +18803 -0.552520751953125 +18804 -0.7296142578125 +18805 -0.483062744140625 +18806 -0.582550048828125 +18807 -0.38446044921875 +18808 -0.440093994140625 +18809 -0.2890625 +18810 -0.324310302734375 +18811 -0.2115478515625 +18812 -0.20147705078125 +18813 -0.12957763671875 +18814 -0.044647216796875 +18815 -0.025238037109375 +18816 0.103973388671875 +18817 0.07342529296875 +18818 0.202392578125 +18819 0.13848876953125 +18820 0.264495849609375 +18821 0.179229736328125 +18822 0.338897705078125 +18823 0.22796630859375 +18824 0.443817138671875 +18825 0.29681396484375 +18826 0.545074462890625 +18827 0.363128662109375 +18828 0.6173095703125 +18829 0.410125732421875 +18830 0.6524658203125 +18831 0.432525634765625 +18832 0.66339111328125 +18833 0.43890380859375 +18834 0.6561279296875 +18835 0.433319091796875 +18836 0.606781005859375 +18837 0.399932861328125 +18838 0.501190185546875 +18839 0.329376220703125 +18840 0.352783203125 +18841 0.2305908203125 +18842 0.176544189453125 +18843 0.113525390625 +18844 -0.034820556640625 +18845 -0.026641845703125 +18846 -0.258209228515625 +18847 -0.174591064453125 +18848 -0.44244384765625 +18849 -0.296356201171875 +18850 -0.5753173828125 +18851 -0.383880615234375 +18852 -0.65203857421875 +18853 -0.43402099609375 +18854 -0.641632080078125 +18855 -0.42626953125 +18856 -0.562164306640625 +18857 -0.3726806640625 +18858 -0.458038330078125 +18859 -0.30279541015625 +18860 -0.350555419921875 +18861 -0.230743408203125 +18862 -0.260528564453125 +18863 -0.17041015625 +18864 -0.192108154296875 +18865 -0.12457275390625 +18866 -0.141937255859375 +18867 -0.091033935546875 +18868 -0.1021728515625 +18869 -0.0645751953125 +18870 -0.062896728515625 +18871 -0.038604736328125 +18872 -0.011932373046875 +18873 -0.005035400390625 +18874 0.062835693359375 +18875 0.044189453125 +18876 0.148712158203125 +18877 0.100677490234375 +18878 0.241729736328125 +18879 0.16180419921875 +18880 0.34912109375 +18881 0.232421875 +18882 0.457305908203125 +18883 0.303558349609375 +18884 0.54388427734375 +18885 0.360382080078125 +18886 0.5728759765625 +18887 0.379058837890625 +18888 0.506591796875 +18889 0.334564208984375 +18890 0.351226806640625 +18891 0.231048583984375 +18892 0.146514892578125 +18893 0.094879150390625 +18894 -0.05523681640625 +18895 -0.039154052734375 +18896 -0.21624755859375 +18897 -0.14599609375 +18898 -0.334930419921875 +18899 -0.224578857421875 +18900 -0.402984619140625 +18901 -0.269439697265625 +18902 -0.4412841796875 +18903 -0.29443359375 +18904 -0.49578857421875 +18905 -0.330108642578125 +18906 -0.5601806640625 +18907 -0.372314453125 +18908 -0.600738525390625 +18909 -0.398681640625 +18910 -0.584228515625 +18911 -0.38714599609375 +18912 -0.47930908203125 +18913 -0.31695556640625 +18914 -0.27935791015625 +18915 -0.183746337890625 +18916 -0.0089111328125 +18917 -0.003814697265625 +18918 0.268798828125 +18919 0.1807861328125 +18920 0.482818603515625 +18921 0.322967529296875 +18922 0.60369873046875 +18923 0.403167724609375 +18924 0.650421142578125 +18925 0.433990478515625 +18926 0.66400146484375 +18927 0.442718505859375 +18928 0.6414794921875 +18929 0.427398681640625 +18930 0.572540283203125 +18931 0.381195068359375 +18932 0.498138427734375 +18933 0.331329345703125 +18934 0.439453125 +18935 0.291900634765625 +18936 0.375518798828125 +18937 0.248992919921875 +18938 0.274505615234375 +18939 0.181488037109375 +18940 0.1087646484375 +18941 0.071044921875 +18942 -0.099395751953125 +18943 -0.0675048828125 +18944 -0.3182373046875 +18945 -0.2125244140625 +18946 -0.5489501953125 +18947 -0.364013671875 +18948 -0.7738037109375 +18949 -0.5103759765625 +18950 -0.86383056640625 +18951 -0.61798095703125 +18952 -0.870391845703125 +18953 -0.665740966796875 +18954 -0.86895751953125 +18955 -0.664886474609375 +18956 -0.861053466796875 +18957 -0.62384033203125 +18958 -0.765869140625 +18959 -0.5318603515625 +18960 -0.5301513671875 +18961 -0.382110595703125 +18962 -0.214691162109375 +18963 -0.17938232421875 +18964 0.137359619140625 +18965 0.04876708984375 +18966 0.474822998046875 +18967 0.26959228515625 +18968 0.76239013671875 +18969 0.4603271484375 +18970 0.867462158203125 +18971 0.603607177734375 +18972 0.870361328125 +18973 0.699462890625 +18974 0.86480712890625 +18975 0.74041748046875 +18976 0.831817626953125 +18977 0.729705810546875 +18978 0.677581787109375 +18979 0.682647705078125 +18980 0.495880126953125 +18981 0.602874755859375 +18982 0.30767822265625 +18983 0.502197265625 +18984 0.116180419921875 +18985 0.38214111328125 +18986 -0.110748291015625 +18987 0.22283935546875 +18988 -0.381805419921875 +18989 0.020111083984375 +18990 -0.6572265625 +18991 -0.198699951171875 +18992 -0.857421875 +18993 -0.3955078125 +18994 -0.870391845703125 +18995 -0.542877197265625 +18996 -0.870391845703125 +18997 -0.636077880859375 +18998 -0.86444091796875 +18999 -0.69189453125 +19000 -0.85723876953125 +19001 -0.732696533203125 +19002 -0.790008544921875 +19003 -0.746734619140625 +19004 -0.62847900390625 +19005 -0.69964599609375 +19006 -0.3956298828125 +19007 -0.58941650390625 +19008 -0.126708984375 +19009 -0.43682861328125 +19010 0.150115966796875 +19011 -0.25927734375 +19012 0.424041748046875 +19013 -0.064300537109375 +19014 0.670623779296875 +19015 0.130859375 +19016 0.854522705078125 +19017 0.301544189453125 +19018 0.866485595703125 +19019 0.43634033203125 +19020 0.86920166015625 +19021 0.525299072265625 +19022 0.8653564453125 +19023 0.57965087890625 +19024 0.857147216796875 +19025 0.607666015625 +19026 0.766845703125 +19027 0.607330322265625 +19028 0.628509521484375 +19029 0.581756591796875 +19030 0.462127685546875 +19031 0.526611328125 +19032 0.297210693359375 +19033 0.458160400390625 +19034 0.14862060546875 +19035 0.384246826171875 +19036 -0.00537109375 +19037 0.290496826171875 +19038 -0.15753173828125 +19039 0.1817626953125 +19040 -0.31304931640625 +19041 0.055908203125 +19042 -0.48876953125 +19043 -0.095733642578125 +19044 -0.6416015625 +19045 -0.24334716796875 +19046 -0.751373291015625 +19047 -0.371124267578125 +19048 -0.84619140625 +19049 -0.493438720703125 +19050 -0.861297607421875 +19051 -0.60076904296875 +19052 -0.863250732421875 +19053 -0.672027587890625 +19054 -0.856597900390625 +19055 -0.687103271484375 +19056 -0.7498779296875 +19057 -0.653594970703125 +19058 -0.624542236328125 +19059 -0.6080322265625 +19060 -0.47808837890625 +19061 -0.5364990234375 +19062 -0.253387451171875 +19063 -0.402130126953125 +19064 0.003692626953125 +19065 -0.233856201171875 +19066 0.2257080078125 +19067 -0.07501220703125 +19068 0.427154541015625 +19069 0.082183837890625 +19070 0.643218994140625 +19071 0.25799560546875 +19072 0.855926513671875 +19073 0.446136474609375 +19074 0.870361328125 +19075 0.609771728515625 +19076 0.870361328125 +19077 0.717376708984375 +19078 0.862762451171875 +19079 0.7733154296875 +19080 0.79669189453125 +19081 0.775604248046875 +19082 0.595794677734375 +19083 0.718170166015625 +19084 0.362152099609375 +19085 0.61944580078125 +19086 0.1270751953125 +19087 0.49713134765625 +19088 -0.086944580078125 +19089 0.364654541015625 +19090 -0.2784423828125 +19091 0.223419189453125 +19092 -0.484832763671875 +19093 0.05157470703125 +19094 -0.729583740234375 +19095 -0.162841796875 +19096 -0.86688232421875 +19097 -0.38763427734375 +19098 -0.870391845703125 +19099 -0.582611083984375 +19100 -0.86859130859375 +19101 -0.744415283203125 +19102 -0.86279296875 +19103 -0.856353759765625 +19104 -0.817962646484375 +19105 -0.86395263671875 +19106 -0.6116943359375 +19107 -0.862091064453125 +19108 -0.3128662109375 +19109 -0.816009521484375 +19110 0.039398193359375 +19111 -0.638153076171875 +19112 0.422821044921875 +19113 -0.40313720703125 +19114 0.805145263671875 +19115 -0.132049560546875 +19116 0.870361328125 +19117 0.131927490234375 +19118 0.870361328125 +19119 0.35260009765625 +19120 0.860015869140625 +19121 0.522308349609375 +19122 0.727935791015625 +19123 0.63592529296875 +19124 0.48114013671875 +19125 0.689544677734375 +19126 0.2059326171875 +19127 0.698150634765625 +19128 -0.06103515625 +19129 0.675750732421875 +19130 -0.29913330078125 +19131 0.628448486328125 +19132 -0.516204833984375 +19133 0.546875 +19134 -0.7252197265625 +19135 0.42120361328125 +19136 -0.85980224609375 +19137 0.267181396484375 +19138 -0.870391845703125 +19139 0.106597900390625 +19140 -0.870391845703125 +19141 -0.0416259765625 +19142 -0.858062744140625 +19143 -0.14642333984375 +19144 -0.673004150390625 +19145 -0.204742431640625 +19146 -0.42694091796875 +19147 -0.24932861328125 +19148 -0.2100830078125 +19149 -0.307769775390625 +19150 -0.0362548828125 +19151 -0.37823486328125 +19152 0.10943603515625 +19153 -0.441925048828125 +19154 0.23516845703125 +19155 -0.48583984375 +19156 0.373687744140625 +19157 -0.4835205078125 +19158 0.517791748046875 +19159 -0.435943603515625 +19160 0.602783203125 +19161 -0.382843017578125 +19162 0.635711669921875 +19163 -0.320953369140625 +19164 0.655181884765625 +19165 -0.22930908203125 +19166 0.65948486328125 +19167 -0.114410400390625 +19168 0.651275634765625 +19169 0.018280029296875 +19170 0.61846923828125 +19171 0.15289306640625 +19172 0.53753662109375 +19173 0.26556396484375 +19174 0.404144287109375 +19175 0.34442138671875 +19176 0.22186279296875 +19177 0.382843017578125 +19178 0.003997802734375 +19179 0.381134033203125 +19180 -0.22100830078125 +19181 0.350341796875 +19182 -0.42449951171875 +19183 0.30322265625 +19184 -0.579833984375 +19185 0.2530517578125 +19186 -0.641876220703125 +19187 0.2266845703125 +19188 -0.6177978515625 +19189 0.21990966796875 +19190 -0.575531005859375 +19191 0.191986083984375 +19192 -0.526336669921875 +19193 0.139678955078125 +19194 -0.42645263671875 +19195 0.096038818359375 +19196 -0.2581787109375 +19197 0.0787353515625 +19198 -0.068695068359375 +19199 0.065185546875 +19200 0.09222412109375 +19201 0.031005859375 +19202 0.232147216796875 +19203 -0.01214599609375 +19204 0.3509521484375 +19205 -0.056854248046875 +19206 0.410064697265625 +19207 -0.11993408203125 +19208 0.372955322265625 +19209 -0.21820068359375 +19210 0.2554931640625 +19211 -0.33843994140625 +19212 0.10711669921875 +19213 -0.44891357421875 +19214 -0.052886962890625 +19215 -0.53765869140625 +19216 -0.186279296875 +19217 -0.5828857421875 +19218 -0.23291015625 +19219 -0.55120849609375 +19220 -0.209442138671875 +19221 -0.45660400390625 +19222 -0.174163818359375 +19223 -0.339019775390625 +19224 -0.126739501953125 +19225 -0.2039794921875 +19226 -0.048126220703125 +19227 -0.04620361328125 +19228 0.0426025390625 +19229 0.116668701171875 +19230 0.10748291015625 +19231 0.2559814453125 +19232 0.1409912109375 +19233 0.3631591796875 +19234 0.19708251953125 +19235 0.466217041015625 +19236 0.273651123046875 +19237 0.560638427734375 +19238 0.31768798828125 +19239 0.612518310546875 +19240 0.341094970703125 +19241 0.6282958984375 +19242 0.368011474609375 +19243 0.623046875 +19244 0.37249755859375 +19245 0.5830078125 +19246 0.30072021484375 +19247 0.478851318359375 +19248 0.1517333984375 +19249 0.3138427734375 +19250 -0.01470947265625 +19251 0.128326416015625 +19252 -0.1883544921875 +19253 -0.066497802734375 +19254 -0.372711181640625 +19255 -0.267669677734375 +19256 -0.51397705078125 +19257 -0.437957763671875 +19258 -0.57177734375 +19259 -0.54864501953125 +19260 -0.53948974609375 +19261 -0.591888427734375 +19262 -0.43511962890625 +19263 -0.575469970703125 +19264 -0.2962646484375 +19265 -0.5198974609375 +19266 -0.161102294921875 +19267 -0.44708251953125 +19268 -0.0435791015625 +19269 -0.365478515625 +19270 0.060394287109375 +19271 -0.2738037109375 +19272 0.13665771484375 +19273 -0.182647705078125 +19274 0.170135498046875 +19275 -0.10400390625 +19276 0.16552734375 +19277 -0.03863525390625 +19278 0.15728759765625 +19279 0.03009033203125 +19280 0.150787353515625 +19281 0.101287841796875 +19282 0.12200927734375 +19283 0.1563720703125 +19284 0.080108642578125 +19285 0.19696044921875 +19286 0.05126953125 +19287 0.235382080078125 +19288 0.062896728515625 +19289 0.28533935546875 +19290 0.09271240234375 +19291 0.33148193359375 +19292 0.092987060546875 +19293 0.34405517578125 +19294 0.07855224609375 +19295 0.33172607421875 +19296 0.06427001953125 +19297 0.304107666015625 +19298 0.0347900390625 +19299 0.253448486328125 +19300 -0.01171875 +19301 0.180816650390625 +19302 -0.056060791015625 +19303 0.100494384765625 +19304 -0.055511474609375 +19305 0.04132080078125 +19306 -0.010467529296875 +19307 0.0064697265625 +19308 0.02508544921875 +19309 -0.032958984375 +19310 0.025665283203125 +19311 -0.088958740234375 +19312 0.017333984375 +19313 -0.1429443359375 +19314 0.00189208984375 +19315 -0.19140625 +19316 -0.03173828125 +19317 -0.2391357421875 +19318 -0.071502685546875 +19319 -0.27777099609375 +19320 -0.13543701171875 +19321 -0.31768798828125 +19322 -0.219970703125 +19323 -0.357025146484375 +19324 -0.300506591796875 +19325 -0.381988525390625 +19326 -0.376312255859375 +19327 -0.393768310546875 +19328 -0.416107177734375 +19329 -0.375701904296875 +19330 -0.371124267578125 +19331 -0.30108642578125 +19332 -0.242279052734375 +19333 -0.1732177734375 +19334 -0.069732666015625 +19335 -0.01904296875 +19336 0.125640869140625 +19337 0.1461181640625 +19338 0.31268310546875 +19339 0.301025390625 +19340 0.45501708984375 +19341 0.42169189453125 +19342 0.554779052734375 +19343 0.5076904296875 +19344 0.61065673828125 +19345 0.55706787109375 +19346 0.610931396484375 +19347 0.562225341796875 +19348 0.531463623046875 +19349 0.50872802734375 +19350 0.3883056640625 +19351 0.4068603515625 +19352 0.23468017578125 +19353 0.289703369140625 +19354 0.095245361328125 +19355 0.1737060546875 +19356 -0.00396728515625 +19357 0.076416015625 +19358 -0.04852294921875 +19359 0.0086669921875 +19360 -0.055145263671875 +19361 -0.03717041015625 +19362 -0.0758056640625 +19363 -0.09002685546875 +19364 -0.138702392578125 +19365 -0.164642333984375 +19366 -0.209197998046875 +19367 -0.23828125 +19368 -0.289031982421875 +19369 -0.310455322265625 +19370 -0.37884521484375 +19371 -0.380462646484375 +19372 -0.456329345703125 +19373 -0.434234619140625 +19374 -0.51641845703125 +19375 -0.468597412109375 +19376 -0.519287109375 +19377 -0.46002197265625 +19378 -0.458251953125 +19379 -0.405303955078125 +19380 -0.384796142578125 +19381 -0.3365478515625 +19382 -0.323699951171875 +19383 -0.2701416015625 +19384 -0.269287109375 +19385 -0.20440673828125 +19386 -0.1951904296875 +19387 -0.12548828125 +19388 -0.100006103515625 +19389 -0.034423828125 +19390 -0.01055908203125 +19391 0.05084228515625 +19392 0.1033935546875 +19393 0.146759033203125 +19394 0.24908447265625 +19395 0.256317138671875 +19396 0.373199462890625 +19397 0.346466064453125 +19398 0.45806884765625 +19399 0.405914306640625 +19400 0.511474609375 +19401 0.4390869140625 +19402 0.565399169921875 +19403 0.46533203125 +19404 0.61138916015625 +19405 0.4801025390625 +19406 0.5897216796875 +19407 0.448455810546875 +19408 0.4906005859375 +19409 0.36572265625 +19410 0.33148193359375 +19411 0.2437744140625 +19412 0.147796630859375 +19413 0.105377197265625 +19414 -0.01873779296875 +19415 -0.0228271484375 +19416 -0.140289306640625 +19417 -0.12255859375 +19418 -0.191986083984375 +19419 -0.177490234375 +19420 -0.184295654296875 +19421 -0.19268798828125 +19422 -0.161834716796875 +19423 -0.1939697265625 +19424 -0.166595458984375 +19425 -0.20587158203125 +19426 -0.19390869140625 +19427 -0.225250244140625 +19428 -0.22442626953125 +19429 -0.240509033203125 +19430 -0.279754638671875 +19431 -0.26495361328125 +19432 -0.3389892578125 +19433 -0.28668212890625 +19434 -0.3543701171875 +19435 -0.2779541015625 +19436 -0.348175048828125 +19437 -0.25323486328125 +19438 -0.32598876953125 +19439 -0.217071533203125 +19440 -0.2581787109375 +19441 -0.15301513671875 +19442 -0.139801025390625 +19443 -0.05938720703125 +19444 0.014617919921875 +19445 0.05389404296875 +19446 0.144378662109375 +19447 0.1492919921875 +19448 0.221038818359375 +19449 0.208892822265625 +19450 0.27069091796875 +19451 0.24774169921875 +19452 0.294036865234375 +19453 0.26593017578125 +19454 0.311767578125 +19455 0.2757568359375 +19456 0.339141845703125 +19457 0.286468505859375 +19458 0.360260009765625 +19459 0.288543701171875 +19460 0.360504150390625 +19461 0.2740478515625 +19462 0.308380126953125 +19463 0.226165771484375 +19464 0.18170166015625 +19465 0.13348388671875 +19466 0.0047607421875 +19467 0.011138916015625 +19468 -0.17559814453125 +19469 -0.11297607421875 +19470 -0.3143310546875 +19471 -0.21209716796875 +19472 -0.36785888671875 +19473 -0.2603759765625 +19474 -0.36248779296875 +19475 -0.271820068359375 +19476 -0.343536376953125 +19477 -0.271453857421875 +19478 -0.3018798828125 +19479 -0.253692626953125 +19480 -0.231414794921875 +19481 -0.214874267578125 +19482 -0.117645263671875 +19483 -0.14678955078125 +19484 0.007049560546875 +19485 -0.068206787109375 +19486 0.087982177734375 +19487 -0.010711669921875 +19488 0.13946533203125 +19489 0.033050537109375 +19490 0.17425537109375 +19491 0.0694580078125 +19492 0.188201904296875 +19493 0.09515380859375 +19494 0.171234130859375 +19495 0.103424072265625 +19496 0.118438720703125 +19497 0.09051513671875 +19498 0.05706787109375 +19499 0.07098388671875 +19500 -0.010711669921875 +19501 0.04522705078125 +19502 -0.0914306640625 +19503 0.008941650390625 +19504 -0.162322998046875 +19505 -0.02532958984375 +19506 -0.194549560546875 +19507 -0.04144287109375 +19508 -0.1492919921875 +19509 -0.017364501953125 +19510 -0.02166748046875 +19511 0.049835205078125 +19512 0.124053955078125 +19513 0.12408447265625 +19514 0.211151123046875 +19515 0.162353515625 +19516 0.240447998046875 +19517 0.165802001953125 +19518 0.242218017578125 +19519 0.152374267578125 +19520 0.2257080078125 +19521 0.128173828125 +19522 0.194366455078125 +19523 0.095977783203125 +19524 0.115509033203125 +19525 0.0379638671875 +19526 0.0128173828125 +19527 -0.03167724609375 +19528 -0.053802490234375 +19529 -0.078369140625 +19530 -0.110626220703125 +19531 -0.116607666015625 +19532 -0.199493408203125 +19533 -0.169921875 +19534 -0.29437255859375 +19535 -0.223480224609375 +19536 -0.33221435546875 +19537 -0.2415771484375 +19538 -0.27972412109375 +19539 -0.205596923828125 +19540 -0.185333251953125 +19541 -0.143463134765625 +19542 -0.128204345703125 +19543 -0.100616455078125 +19544 -0.115692138671875 +19545 -0.081878662109375 +19546 -0.116455078125 +19547 -0.070098876953125 +19548 -0.105926513671875 +19549 -0.052001953125 +19550 -0.053955078125 +19551 -0.011138916015625 +19552 0.048797607421875 +19553 0.057159423828125 +19554 0.157318115234375 +19555 0.126861572265625 +19556 0.212005615234375 +19557 0.1636962890625 +19558 0.218475341796875 +19559 0.170623779296875 +19560 0.23724365234375 +19561 0.181915283203125 +19562 0.30535888671875 +19563 0.218658447265625 +19564 0.38128662109375 +19565 0.257415771484375 +19566 0.404449462890625 +19567 0.264068603515625 +19568 0.3944091796875 +19569 0.25018310546875 +19570 0.3885498046875 +19571 0.23748779296875 +19572 0.362640380859375 +19573 0.2127685546875 +19574 0.27362060546875 +19575 0.152130126953125 +19576 0.11712646484375 +19577 0.05364990234375 +19578 -0.054901123046875 +19579 -0.05267333984375 +19580 -0.19085693359375 +19581 -0.137054443359375 +19582 -0.28570556640625 +19583 -0.1962890625 +19584 -0.339263916015625 +19585 -0.230072021484375 +19586 -0.3775634765625 +19587 -0.2530517578125 +19588 -0.445709228515625 +19589 -0.29083251953125 +19590 -0.535064697265625 +19591 -0.338623046875 +19592 -0.629058837890625 +19593 -0.387237548828125 +19594 -0.697601318359375 +19595 -0.41986083984375 +19596 -0.70391845703125 +19597 -0.415985107421875 +19598 -0.6424560546875 +19599 -0.3729248046875 +19600 -0.491241455078125 +19601 -0.2786865234375 +19602 -0.265716552734375 +19603 -0.142486572265625 +19604 -0.023712158203125 +19605 0.00238037109375 +19606 0.201751708984375 +19607 0.136749267578125 +19608 0.375823974609375 +19609 0.240509033203125 +19610 0.485076904296875 +19611 0.30584716796875 +19612 0.56884765625 +19613 0.35498046875 +19614 0.634765625 +19615 0.392181396484375 +19616 0.63763427734375 +19617 0.391876220703125 +19618 0.5660400390625 +19619 0.34771728515625 +19620 0.4720458984375 +19621 0.28948974609375 +19622 0.40692138671875 +19623 0.246612548828125 +19624 0.3778076171875 +19625 0.2235107421875 +19626 0.376953125 +19627 0.216156005859375 +19628 0.371978759765625 +19629 0.20654296875 +19630 0.313140869140625 +19631 0.166778564453125 +19632 0.184417724609375 +19633 0.088104248046875 +19634 0.011199951171875 +19635 -0.0147705078125 +19636 -0.171051025390625 +19637 -0.121490478515625 +19638 -0.33740234375 +19639 -0.217742919921875 +19640 -0.47198486328125 +19641 -0.294464111328125 +19642 -0.560394287109375 +19643 -0.343505859375 +19644 -0.58056640625 +19645 -0.352447509765625 +19646 -0.54754638671875 +19647 -0.329986572265625 +19648 -0.508575439453125 +19649 -0.303192138671875 +19650 -0.459503173828125 +19651 -0.269989013671875 +19652 -0.394378662109375 +19653 -0.227325439453125 +19654 -0.35260009765625 +19655 -0.1978759765625 +19656 -0.31170654296875 +19657 -0.169189453125 +19658 -0.197418212890625 +19659 -0.099395751953125 +19660 -0.007965087890625 +19661 0.01226806640625 +19662 0.207489013671875 +19663 0.13763427734375 +19664 0.409210205078125 +19665 0.2540283203125 +19666 0.57208251953125 +19667 0.34710693359375 +19668 0.66595458984375 +19669 0.399749755859375 +19670 0.65875244140625 +19671 0.393829345703125 +19672 0.56744384765625 +19673 0.339111328125 +19674 0.431396484375 +19675 0.258148193359375 +19676 0.29443359375 +19677 0.176055908203125 +19678 0.182464599609375 +19679 0.107818603515625 +19680 0.06365966796875 +19681 0.035614013671875 +19682 -0.075958251953125 +19683 -0.0482177734375 +19684 -0.189422607421875 +19685 -0.116790771484375 +19686 -0.271942138671875 +19687 -0.1671142578125 +19688 -0.342529296875 +19689 -0.2098388671875 +19690 -0.364166259765625 +19691 -0.223846435546875 +19692 -0.327239990234375 +19693 -0.20361328125 +19694 -0.2769775390625 +19695 -0.174835205078125 +19696 -0.253692626953125 +19697 -0.160430908203125 +19698 -0.24365234375 +19699 -0.152679443359375 +19700 -0.1983642578125 +19701 -0.124176025390625 +19702 -0.116241455078125 +19703 -0.074188232421875 +19704 -0.036834716796875 +19705 -0.025360107421875 +19706 0.034881591796875 +19707 0.01922607421875 +19708 0.09124755859375 +19709 0.055023193359375 +19710 0.10888671875 +19711 0.06854248046875 +19712 0.125518798828125 +19713 0.08062744140625 +19714 0.15771484375 +19715 0.100433349609375 +19716 0.17828369140625 +19717 0.112884521484375 +19718 0.17108154296875 +19719 0.109405517578125 +19720 0.129974365234375 +19721 0.086822509765625 +19722 0.082427978515625 +19723 0.059967041015625 +19724 0.027679443359375 +19725 0.028564453125 +19726 -0.065643310546875 +19727 -0.0240478515625 +19728 -0.15936279296875 +19729 -0.077239990234375 +19730 -0.21307373046875 +19731 -0.109222412109375 +19732 -0.234649658203125 +19733 -0.124053955078125 +19734 -0.2001953125 +19735 -0.1087646484375 +19736 -0.119171142578125 +19737 -0.068267822265625 +19738 -0.024749755859375 +19739 -0.020233154296875 +19740 0.085784912109375 +19741 0.036895751953125 +19742 0.178131103515625 +19743 0.0848388671875 +19744 0.215576171875 +19745 0.10400390625 +19746 0.211456298828125 +19747 0.101531982421875 +19748 0.17523193359375 +19749 0.082489013671875 +19750 0.128753662109375 +19751 0.058563232421875 +19752 0.1019287109375 +19753 0.04571533203125 +19754 0.0743408203125 +19755 0.03289794921875 +19756 0.04327392578125 +19757 0.018524169921875 +19758 0.038177490234375 +19759 0.01824951171875 +19760 0.076263427734375 +19761 0.041168212890625 +19762 0.14105224609375 +19763 0.07830810546875 +19764 0.186431884765625 +19765 0.104827880859375 +19766 0.188812255859375 +19767 0.10797119140625 +19768 0.1390380859375 +19769 0.082733154296875 +19770 0.041778564453125 +19771 0.03155517578125 +19772 -0.079437255859375 +19773 -0.032958984375 +19774 -0.219390869140625 +19775 -0.108062744140625 +19776 -0.367828369140625 +19777 -0.188201904296875 +19778 -0.494873046875 +19779 -0.25732421875 +19780 -0.556243896484375 +19781 -0.2916259765625 +19782 -0.508697509765625 +19783 -0.26788330078125 +19784 -0.3756103515625 +19785 -0.198486328125 +19786 -0.218902587890625 +19787 -0.11651611328125 +19788 -0.063751220703125 +19789 -0.035369873046875 +19790 0.091552734375 +19791 0.04595947265625 +19792 0.23602294921875 +19793 0.1217041015625 +19794 0.342987060546875 +19795 0.177642822265625 +19796 0.39520263671875 +19797 0.204620361328125 +19798 0.389373779296875 +19799 0.200927734375 +19800 0.324249267578125 +19801 0.1658935546875 +19802 0.224090576171875 +19803 0.112518310546875 +19804 0.124267578125 +19805 0.059722900390625 +19806 0.037078857421875 +19807 0.014068603515625 +19808 -0.010101318359375 +19809 -0.00982666015625 +19810 -0.019439697265625 +19811 -0.01324462890625 +19812 -0.022796630859375 +19813 -0.013336181640625 +19814 -0.001556396484375 +19815 -0.000213623046875 +19816 0.056304931640625 +19817 0.032440185546875 +19818 0.106719970703125 +19819 0.0609130859375 +19820 0.096893310546875 +19821 0.056854248046875 +19822 0.042694091796875 +19823 0.028717041015625 +19824 -0.018035888671875 +19825 -0.003265380859375 +19826 -0.07586669921875 +19827 -0.034027099609375 +19828 -0.11944580078125 +19829 -0.057525634765625 +19830 -0.15972900390625 +19831 -0.079620361328125 +19832 -0.202606201171875 +19833 -0.103424072265625 +19834 -0.24859619140625 +19835 -0.129119873046875 +19836 -0.30517578125 +19837 -0.160614013671875 +19838 -0.36212158203125 +19839 -0.192413330078125 +19840 -0.39141845703125 +19841 -0.209442138671875 +19842 -0.35528564453125 +19843 -0.191375732421875 +19844 -0.249969482421875 +19845 -0.136138916015625 +19846 -0.092864990234375 +19847 -0.053009033203125 +19848 0.08905029296875 +19849 0.04364013671875 +19850 0.2352294921875 +19851 0.121368408203125 +19852 0.318817138671875 +19853 0.16583251953125 +19854 0.358642578125 +19855 0.187103271484375 +19856 0.347747802734375 +19857 0.181488037109375 +19858 0.28564453125 +19859 0.148681640625 +19860 0.223175048828125 +19861 0.11590576171875 +19862 0.196746826171875 +19863 0.102630615234375 +19864 0.179840087890625 +19865 0.0946044921875 +19866 0.155548095703125 +19867 0.08270263671875 +19868 0.151214599609375 +19869 0.081512451171875 +19870 0.156951904296875 +19871 0.085662841796875 +19872 0.13177490234375 +19873 0.073089599609375 +19874 0.100799560546875 +19875 0.0572509765625 +19876 0.087127685546875 +19877 0.05047607421875 +19878 0.05487060546875 +19879 0.033538818359375 +19880 -0.009002685546875 +19881 -0.000579833984375 +19882 -0.10400390625 +19883 -0.051605224609375 +19884 -0.229400634765625 +19885 -0.119110107421875 +19886 -0.35552978515625 +19887 -0.18719482421875 +19888 -0.441925048828125 +19889 -0.234130859375 +19890 -0.473846435546875 +19891 -0.25201416015625 +19892 -0.464813232421875 +19893 -0.248016357421875 +19894 -0.419097900390625 +19895 -0.224365234375 +19896 -0.334320068359375 +19897 -0.17974853515625 +19898 -0.227935791015625 +19899 -0.12347412109375 +19900 -0.12347412109375 +19901 -0.068145751953125 +19902 -0.02764892578125 +19903 -0.017303466796875 +19904 0.077667236328125 +19905 0.038787841796875 +19906 0.2132568359375 +19907 0.11126708984375 +19908 0.38885498046875 +19909 0.205352783203125 +19910 0.582794189453125 +19911 0.3094482421875 +19912 0.734039306640625 +19913 0.39080810546875 +19914 0.800140380859375 +19915 0.426666259765625 +19916 0.7783203125 +19917 0.415496826171875 +19918 0.6651611328125 +19919 0.355438232421875 +19920 0.45965576171875 +19921 0.245941162109375 +19922 0.199188232421875 +19923 0.10699462890625 +19924 -0.050689697265625 +19925 -0.026275634765625 +19926 -0.23297119140625 +19927 -0.123382568359375 +19928 -0.33013916015625 +19929 -0.174957275390625 +19930 -0.368408203125 +19931 -0.195068359375 +19932 -0.378936767578125 +19933 -0.200439453125 +19934 -0.376983642578125 +19935 -0.19927978515625 +19936 -0.37969970703125 +19937 -0.200775146484375 +19938 -0.391510009765625 +19939 -0.207275390625 +19940 -0.385345458984375 +19941 -0.20428466796875 +19942 -0.3419189453125 +19943 -0.181427001953125 +19944 -0.28289794921875 +19945 -0.150299072265625 +19946 -0.251617431640625 +19947 -0.134063720703125 +19948 -0.266143798828125 +19949 -0.142364501953125 +19950 -0.273345947265625 +19951 -0.146728515625 +19952 -0.216796875 +19953 -0.11688232421875 +19954 -0.128265380859375 +19955 -0.069793701171875 +19956 -0.068145751953125 +19957 -0.037841796875 +19958 -0.0430908203125 +19959 -0.02459716796875 +19960 -0.024444580078125 +19961 -0.014678955078125 +19962 0.020721435546875 +19963 0.009552001953125 +19964 0.124481201171875 +19965 0.065277099609375 +19966 0.25787353515625 +19967 0.136962890625 +19968 0.379119873046875 +19969 0.201629638671875 +19970 0.47991943359375 +19971 0.255035400390625 +19972 0.5281982421875 +19973 0.28131103515625 +19974 0.511138916015625 +19975 0.2738037109375 +19976 0.456207275390625 +19977 0.246246337890625 +19978 0.407470703125 +19979 0.2208251953125 +19980 0.383758544921875 +19981 0.20709228515625 +19982 0.35687255859375 +19983 0.190948486328125 +19984 0.31182861328125 +19985 0.165008544921875 +19986 0.250885009765625 +19987 0.130615234375 +19988 0.1654052734375 +19989 0.0836181640625 +19990 0.035247802734375 +19991 0.014129638671875 +19992 -0.142059326171875 +19993 -0.078857421875 +19994 -0.33563232421875 +19995 -0.1795654296875 +19996 -0.5345458984375 +19997 -0.282318115234375 +19998 -0.72186279296875 +19999 -0.378448486328125 +20000 -0.836669921875 +20001 -0.437164306640625 +20002 -0.8326416015625 +20003 -0.435089111328125 +20004 -0.7296142578125 +20005 -0.382232666015625 +20006 -0.582550048828125 +20007 -0.306427001953125 +20008 -0.440093994140625 +20009 -0.232269287109375 +20010 -0.324310302734375 +20011 -0.171051025390625 +20012 -0.20147705078125 +20013 -0.105926513671875 +20014 -0.044647216796875 +20015 -0.02349853515625 +20016 0.103973388671875 +20017 0.05474853515625 +20018 0.202392578125 +20019 0.10748291015625 +20020 0.264495849609375 +20021 0.141510009765625 +20022 0.338897705078125 +20023 0.18121337890625 +20024 0.443817138671875 +20025 0.23565673828125 +20026 0.545074462890625 +20027 0.287567138671875 +20028 0.6173095703125 +20029 0.324127197265625 +20030 0.6524658203125 +20031 0.341278076171875 +20032 0.66339111328125 +20033 0.3455810546875 +20034 0.6561279296875 +20035 0.340118408203125 +20036 0.606781005859375 +20037 0.31298828125 +20038 0.501190185546875 +20039 0.257171630859375 +20040 0.352783203125 +20041 0.1795654296875 +20042 0.176544189453125 +20043 0.087921142578125 +20044 -0.034820556640625 +20045 -0.021270751953125 +20046 -0.258209228515625 +20047 -0.136199951171875 +20048 -0.44244384765625 +20049 -0.23095703125 +20050 -0.5753173828125 +20051 -0.29931640625 +20052 -0.65203857421875 +20053 -0.33880615234375 +20054 -0.641632080078125 +20055 -0.33380126953125 +20056 -0.562164306640625 +20057 -0.293426513671875 +20058 -0.458038330078125 +20059 -0.240081787109375 +20060 -0.350555419921875 +20061 -0.184539794921875 +20062 -0.260528564453125 +20063 -0.13739013671875 +20064 -0.192108154296875 +20065 -0.100830078125 +20066 -0.141937255859375 +20067 -0.07330322265625 +20068 -0.1021728515625 +20069 -0.05096435546875 +20070 -0.062896728515625 +20071 -0.028961181640625 +20072 -0.011932373046875 +20073 -0.00128173828125 +20074 0.062835693359375 +20075 0.0380859375 +20076 0.148712158203125 +20077 0.082672119140625 +20078 0.241729736328125 +20079 0.130401611328125 +20080 0.34912109375 +20081 0.18487548828125 +20082 0.457305908203125 +20083 0.2392578125 +20084 0.54388427734375 +20085 0.282257080078125 +20086 0.5728759765625 +20087 0.295806884765625 +20088 0.506591796875 +20089 0.260986328125 +20090 0.351226806640625 +20091 0.1810302734375 +20092 0.146514892578125 +20093 0.076019287109375 +20094 -0.05523681640625 +20095 -0.02752685546875 +20096 -0.21624755859375 +20097 -0.110504150390625 +20098 -0.334930419921875 +20099 -0.1719970703125 +20100 -0.402984619140625 +20101 -0.207733154296875 +20102 -0.4412841796875 +20103 -0.2281494140625 +20104 -0.49578857421875 +20105 -0.256378173828125 +20106 -0.5601806640625 +20107 -0.2891845703125 +20108 -0.600738525390625 +20109 -0.3095703125 +20110 -0.584228515625 +20111 -0.300811767578125 +20112 -0.47930908203125 +20113 -0.24713134765625 +20114 -0.27935791015625 +20115 -0.145263671875 +20116 -0.0089111328125 +20117 -0.00762939453125 +20118 0.268798828125 +20119 0.1337890625 +20120 0.482818603515625 +20121 0.243133544921875 +20122 0.60369873046875 +20123 0.305511474609375 +20124 0.650421142578125 +20125 0.330413818359375 +20126 0.66400146484375 +20127 0.33843994140625 +20128 0.6414794921875 +20129 0.328033447265625 +20130 0.572540283203125 +20131 0.2939453125 +20132 0.498138427734375 +20133 0.256805419921875 +20134 0.439453125 +20135 0.227264404296875 +20136 0.375518798828125 +20137 0.19476318359375 +20138 0.274505615234375 +20139 0.14324951171875 +20140 0.1087646484375 +20141 0.058868408203125 +20142 -0.099395751953125 +20143 -0.04705810546875 +20144 -0.3182373046875 +20145 -0.158477783203125 +20146 -0.5489501953125 +20147 -0.27593994140625 +20148 -0.7738037109375 +20149 -0.390411376953125 +20150 -0.86383056640625 +20151 -0.475189208984375 +20152 -0.870391845703125 +20153 -0.513427734375 +20154 -0.86895751953125 +20155 -0.514007568359375 +20156 -0.861053466796875 +20157 -0.4835205078125 +20158 -0.765869140625 +20159 -0.4132080078125 +20160 -0.5301513671875 +20161 -0.297393798828125 +20162 -0.214691162109375 +20163 -0.1396484375 +20164 0.137359619140625 +20165 0.038299560546875 +20166 0.474822998046875 +20167 0.2105712890625 +20168 0.76239013671875 +20169 0.35919189453125 +20170 0.867462158203125 +20171 0.470489501953125 +20172 0.870361328125 +20173 0.544677734375 +20174 0.86480712890625 +20175 0.57586669921875 +20176 0.831817626953125 +20177 0.566680908203125 +20178 0.677581787109375 +20179 0.52935791015625 +20180 0.495880126953125 +20181 0.466766357421875 +20182 0.30767822265625 +20183 0.38824462890625 +20184 0.116180419921875 +20185 0.294921875 +20186 -0.110748291015625 +20187 0.1707763671875 +20188 -0.381805419921875 +20189 0.0123291015625 +20190 -0.6572265625 +20191 -0.158843994140625 +20192 -0.857421875 +20193 -0.312530517578125 +20194 -0.870391845703125 +20195 -0.42706298828125 +20196 -0.870391845703125 +20197 -0.498809814453125 +20198 -0.86444091796875 +20199 -0.541259765625 +20200 -0.85723876953125 +20201 -0.572357177734375 +20202 -0.790008544921875 +20203 -0.58282470703125 +20204 -0.62847900390625 +20205 -0.545257568359375 +20206 -0.3956298828125 +20207 -0.4580078125 +20208 -0.126708984375 +20209 -0.33758544921875 +20210 0.150115966796875 +20211 -0.19781494140625 +20212 0.424041748046875 +20213 -0.044586181640625 +20214 0.670623779296875 +20215 0.1085205078125 +20216 0.854522705078125 +20217 0.241943359375 +20218 0.866485595703125 +20219 0.34674072265625 +20220 0.86920166015625 +20221 0.415130615234375 +20222 0.8653564453125 +20223 0.456207275390625 +20224 0.857147216796875 +20225 0.4769287109375 +20226 0.766845703125 +20227 0.47552490234375 +20228 0.628509521484375 +20229 0.454193115234375 +20230 0.462127685546875 +20231 0.4097900390625 +20232 0.297210693359375 +20233 0.354644775390625 +20234 0.14862060546875 +20235 0.2947998046875 +20236 -0.00537109375 +20237 0.219818115234375 +20238 -0.15753173828125 +20239 0.133575439453125 +20240 -0.31304931640625 +20241 0.0347900390625 +20242 -0.48876953125 +20243 -0.082794189453125 +20244 -0.6416015625 +20245 -0.1966552734375 +20246 -0.751373291015625 +20247 -0.294769287109375 +20248 -0.84619140625 +20249 -0.387786865234375 +20250 -0.861297607421875 +20251 -0.468536376953125 +20252 -0.863250732421875 +20253 -0.521240234375 +20254 -0.856597900390625 +20255 -0.53094482421875 +20256 -0.7498779296875 +20257 -0.503448486328125 +20258 -0.624542236328125 +20259 -0.4661865234375 +20260 -0.47808837890625 +20261 -0.408966064453125 +20262 -0.253387451171875 +20263 -0.304473876953125 +20264 0.003692626953125 +20265 -0.174530029296875 +20266 0.2257080078125 +20267 -0.051727294921875 +20268 0.427154541015625 +20269 0.069488525390625 +20270 0.643218994140625 +20271 0.20404052734375 +20272 0.855926513671875 +20273 0.34710693359375 +20274 0.870361328125 +20275 0.4710693359375 +20276 0.870361328125 +20277 0.552276611328125 +20278 0.862762451171875 +20279 0.593963623046875 +20280 0.79669189453125 +20281 0.594696044921875 +20282 0.595794677734375 +20283 0.550018310546875 +20284 0.362152099609375 +20285 0.473785400390625 +20286 0.1270751953125 +20287 0.37939453125 +20288 -0.086944580078125 +20289 0.277069091796875 +20290 -0.2784423828125 +20291 0.16802978515625 +20292 -0.484832763671875 +20293 0.0361328125 +20294 -0.729583740234375 +20295 -0.1273193359375 +20296 -0.86688232421875 +20297 -0.298126220703125 +20298 -0.870391845703125 +20299 -0.446075439453125 +20300 -0.86859130859375 +20301 -0.568572998046875 +20302 -0.86279296875 +20303 -0.664398193359375 +20304 -0.817962646484375 +20305 -0.7164306640625 +20306 -0.6116943359375 +20307 -0.703155517578125 +20308 -0.3128662109375 +20309 -0.621185302734375 +20310 0.039398193359375 +20311 -0.486480712890625 +20312 0.422821044921875 +20313 -0.30859375 +20314 0.805145263671875 +20315 -0.103424072265625 +20316 0.870361328125 +20317 0.09661865234375 +20318 0.870361328125 +20319 0.264312744140625 +20320 0.860015869140625 +20321 0.393829345703125 +20322 0.727935791015625 +20323 0.481170654296875 +20324 0.48114013671875 +20325 0.5233154296875 +20326 0.2059326171875 +20327 0.531341552734375 +20328 -0.06103515625 +20329 0.515625 +20330 -0.29913330078125 +20331 0.480682373046875 +20332 -0.516204833984375 +20333 0.41949462890625 +20334 -0.7252197265625 +20335 0.324798583984375 +20336 -0.85980224609375 +20337 0.2083740234375 +20338 -0.870391845703125 +20339 0.08660888671875 +20340 -0.870391845703125 +20341 -0.0262451171875 +20342 -0.858062744140625 +20343 -0.10687255859375 +20344 -0.673004150390625 +20345 -0.15283203125 +20346 -0.42694091796875 +20347 -0.188446044921875 +20348 -0.2100830078125 +20349 -0.234222412109375 +20350 -0.0362548828125 +20351 -0.2886962890625 +20352 0.10943603515625 +20353 -0.33770751953125 +20354 0.23516845703125 +20355 -0.371490478515625 +20356 0.373687744140625 +20357 -0.3702392578125 +20358 0.517791748046875 +20359 -0.33465576171875 +20360 0.602783203125 +20361 -0.29443359375 +20362 0.635711669921875 +20363 -0.247222900390625 +20364 0.655181884765625 +20365 -0.17742919921875 +20366 0.65948486328125 +20367 -0.0899658203125 +20368 0.651275634765625 +20369 0.010986328125 +20370 0.61846923828125 +20371 0.113494873046875 +20372 0.53753662109375 +20373 0.199615478515625 +20374 0.404144287109375 +20375 0.260345458984375 +20376 0.22186279296875 +20377 0.290618896484375 +20378 0.003997802734375 +20379 0.290618896484375 +20380 -0.22100830078125 +20381 0.2685546875 +20382 -0.42449951171875 +20383 0.233917236328125 +20384 -0.579833984375 +20385 0.196563720703125 +20386 -0.641876220703125 +20387 0.17657470703125 +20388 -0.6177978515625 +20389 0.17083740234375 +20390 -0.575531005859375 +20391 0.148956298828125 +20392 -0.526336669921875 +20393 0.108612060546875 +20394 -0.42645263671875 +20395 0.07452392578125 +20396 -0.2581787109375 +20397 0.05999755859375 +20398 -0.068695068359375 +20399 0.048248291015625 +20400 0.09222412109375 +20401 0.02154541015625 +20402 0.232147216796875 +20403 -0.010894775390625 +20404 0.3509521484375 +20405 -0.043853759765625 +20406 0.410064697265625 +20407 -0.090972900390625 +20408 0.372955322265625 +20409 -0.165802001953125 +20410 0.2554931640625 +20411 -0.25823974609375 +20412 0.10711669921875 +20413 -0.343536376953125 +20414 -0.052886962890625 +20415 -0.412384033203125 +20416 -0.186279296875 +20417 -0.44769287109375 +20418 -0.23291015625 +20419 -0.423248291015625 +20420 -0.209442138671875 +20421 -0.349945068359375 +20422 -0.174163818359375 +20423 -0.2591552734375 +20424 -0.126739501953125 +20425 -0.15509033203125 +20426 -0.048126220703125 +20427 -0.033447265625 +20428 0.0426025390625 +20429 0.092071533203125 +20430 0.10748291015625 +20431 0.1990966796875 +20432 0.1409912109375 +20433 0.281036376953125 +20434 0.19708251953125 +20435 0.360015869140625 +20436 0.273651123046875 +20437 0.4326171875 +20438 0.31768798828125 +20439 0.4722900390625 +20440 0.341094970703125 +20441 0.484100341796875 +20442 0.368011474609375 +20443 0.47991943359375 +20444 0.37249755859375 +20445 0.448944091796875 +20446 0.30072021484375 +20447 0.3680419921875 +20448 0.1517333984375 +20449 0.239715576171875 +20450 -0.01470947265625 +20451 0.09564208984375 +20452 -0.1883544921875 +20453 -0.0555419921875 +20454 -0.372711181640625 +20455 -0.211578369140625 +20456 -0.51397705078125 +20457 -0.343353271484375 +20458 -0.57177734375 +20459 -0.4283447265625 +20460 -0.53948974609375 +20461 -0.460479736328125 +20462 -0.43511962890625 +20463 -0.446014404296875 +20464 -0.2962646484375 +20465 -0.401123046875 +20466 -0.161102294921875 +20467 -0.3431396484375 +20468 -0.0435791015625 +20469 -0.27874755859375 +20470 0.060394287109375 +20471 -0.2069091796875 +20472 0.13665771484375 +20473 -0.135955810546875 +20474 0.170135498046875 +20475 -0.075225830078125 +20476 0.16552734375 +20477 -0.025238037109375 +20478 0.15728759765625 +20479 0.02716064453125 +20480 0.150787353515625 +20481 0.081512451171875 +20482 0.12200927734375 +20483 0.12335205078125 +20484 0.080108642578125 +20485 0.15374755859375 +20486 0.05126953125 +20487 0.182098388671875 +20488 0.062896728515625 +20489 0.218841552734375 +20490 0.09271240234375 +20491 0.2525634765625 +20492 0.092987060546875 +20493 0.26104736328125 +20494 0.07855224609375 +20495 0.2508544921875 +20496 0.06427001953125 +20497 0.229217529296875 +20498 0.0347900390625 +20499 0.19036865234375 +20500 -0.01171875 +20501 0.1351318359375 +20502 -0.056060791015625 +20503 0.074249267578125 +20504 -0.055511474609375 +20505 0.02935791015625 +20506 -0.010467529296875 +20507 0.00286865234375 +20508 0.02508544921875 +20509 -0.02691650390625 +20510 0.025665283203125 +20511 -0.0689697265625 +20512 0.017333984375 +20513 -0.109375 +20514 0.00189208984375 +20515 -0.1455078125 +20516 -0.03173828125 +20517 -0.18096923828125 +20518 -0.071502685546875 +20519 -0.20953369140625 +20520 -0.13543701171875 +20521 -0.239013671875 +20522 -0.219970703125 +20523 -0.268035888671875 +20524 -0.300506591796875 +20525 -0.28631591796875 +20526 -0.376312255859375 +20527 -0.294708251953125 +20528 -0.416107177734375 +20529 -0.28076171875 +20530 -0.371124267578125 +20531 -0.224456787109375 +20532 -0.242279052734375 +20533 -0.128326416015625 +20534 -0.069732666015625 +20535 -0.0125732421875 +20536 0.125640869140625 +20537 0.111297607421875 +20538 0.31268310546875 +20539 0.2274169921875 +20540 0.45501708984375 +20541 0.317779541015625 +20542 0.554779052734375 +20543 0.382049560546875 +20544 0.61065673828125 +20545 0.418792724609375 +20546 0.610931396484375 +20547 0.422332763671875 +20548 0.531463623046875 +20549 0.381866455078125 +20550 0.3883056640625 +20551 0.30511474609375 +20552 0.23468017578125 +20553 0.2169189453125 +20554 0.095245361328125 +20555 0.129608154296875 +20556 -0.00396728515625 +20557 0.056365966796875 +20558 -0.04852294921875 +20559 0.005340576171875 +20560 -0.055145263671875 +20561 -0.029205322265625 +20562 -0.0758056640625 +20563 -0.06890869140625 +20564 -0.138702392578125 +20565 -0.124847412109375 +20566 -0.209197998046875 +20567 -0.17999267578125 +20568 -0.289031982421875 +20569 -0.23394775390625 +20570 -0.37884521484375 +20571 -0.286224365234375 +20572 -0.456329345703125 +20573 -0.326263427734375 +20574 -0.51641845703125 +20575 -0.35174560546875 +20576 -0.519287109375 +20577 -0.345001220703125 +20578 -0.458251953125 +20579 -0.303619384765625 +20580 -0.384796142578125 +20581 -0.251708984375 +20582 -0.323699951171875 +20583 -0.20159912109375 +20584 -0.269287109375 +20585 -0.152069091796875 +20586 -0.1951904296875 +20587 -0.09271240234375 +20588 -0.100006103515625 +20589 -0.024322509765625 +20590 -0.01055908203125 +20591 0.03961181640625 +20592 0.1033935546875 +20593 0.1114501953125 +20594 0.24908447265625 +20595 0.19342041015625 +20596 0.373199462890625 +20597 0.260772705078125 +20598 0.45806884765625 +20599 0.305084228515625 +20600 0.511474609375 +20601 0.32965087890625 +20602 0.565399169921875 +20603 0.3489990234375 +20604 0.61138916015625 +20605 0.359771728515625 +20606 0.5897216796875 +20607 0.33575439453125 +20608 0.4906005859375 +20609 0.273468017578125 +20610 0.33148193359375 +20611 0.18182373046875 +20612 0.147796630859375 +20613 0.077911376953125 +20614 -0.01873779296875 +20615 -0.018310546875 +20616 -0.140289306640625 +20617 -0.093109130859375 +20618 -0.191986083984375 +20619 -0.134246826171875 +20620 -0.184295654296875 +20621 -0.1455078125 +20622 -0.161834716796875 +20623 -0.146270751953125 +20624 -0.166595458984375 +20625 -0.154937744140625 +20626 -0.19390869140625 +20627 -0.169219970703125 +20628 -0.22442626953125 +20629 -0.180389404296875 +20630 -0.279754638671875 +20631 -0.19842529296875 +20632 -0.3389892578125 +20633 -0.214447021484375 +20634 -0.3543701171875 +20635 -0.207672119140625 +20636 -0.348175048828125 +20637 -0.188934326171875 +20638 -0.32598876953125 +20639 -0.16168212890625 +20640 -0.2581787109375 +20641 -0.11358642578125 +20642 -0.139801025390625 +20643 -0.043365478515625 +20644 0.014617919921875 +20645 0.041534423828125 +20646 0.144378662109375 +20647 0.11297607421875 +20648 0.221038818359375 +20649 0.15753173828125 +20650 0.27069091796875 +20651 0.18646240234375 +20652 0.294036865234375 +20653 0.199859619140625 +20654 0.311767578125 +20655 0.207000732421875 +20656 0.339141845703125 +20657 0.21484375 +20658 0.360260009765625 +20659 0.2164306640625 +20660 0.360504150390625 +20661 0.205780029296875 +20662 0.308380126953125 +20663 0.169708251953125 +20664 0.18170166015625 +20665 0.099273681640625 +20666 0.0047607421875 +20667 0.006072998046875 +20668 -0.17559814453125 +20669 -0.08837890625 +20670 -0.3143310546875 +20671 -0.1634521484375 +20672 -0.36785888671875 +20673 -0.199249267578125 +20674 -0.36248779296875 +20675 -0.206695556640625 +20676 -0.343536376953125 +20677 -0.20526123046875 +20678 -0.3018798828125 +20679 -0.190704345703125 +20680 -0.231414794921875 +20681 -0.160186767578125 +20682 -0.117645263671875 +20683 -0.107391357421875 +20684 0.007049560546875 +20685 -0.04681396484375 +20686 0.087982177734375 +20687 -0.002899169921875 +20688 0.13946533203125 +20689 0.03009033203125 +20690 0.17425537109375 +20691 0.057159423828125 +20692 0.188201904296875 +20693 0.075775146484375 +20694 0.171234130859375 +20695 0.080810546875 +20696 0.118438720703125 +20697 0.069427490234375 +20698 0.05706787109375 +20699 0.053009033203125 +20700 -0.010711669921875 +20701 0.031951904296875 +20702 -0.0914306640625 +20703 0.0029296875 +20704 -0.162322998046875 +20705 -0.0242919921875 +20706 -0.194549560546875 +20707 -0.03717041015625 +20708 -0.1492919921875 +20709 -0.018646240234375 +20710 -0.02166748046875 +20711 0.033599853515625 +20712 0.124053955078125 +20713 0.091552734375 +20714 0.211151123046875 +20715 0.121856689453125 +20716 0.240447998046875 +20717 0.125396728515625 +20718 0.242218017578125 +20719 0.115997314453125 +20720 0.2257080078125 +20721 0.098358154296875 +20722 0.194366455078125 +20723 0.074554443359375 +20724 0.115509033203125 +20725 0.030731201171875 +20726 0.0128173828125 +20727 -0.022186279296875 +20728 -0.053802490234375 +20729 -0.057464599609375 +20730 -0.110626220703125 +20731 -0.086395263671875 +20732 -0.199493408203125 +20733 -0.12725830078125 +20734 -0.29437255859375 +20735 -0.168548583984375 +20736 -0.33221435546875 +20737 -0.1829833984375 +20738 -0.27972412109375 +20739 -0.156829833984375 +20740 -0.185333251953125 +20741 -0.11065673828125 +20742 -0.128204345703125 +20743 -0.077545166015625 +20744 -0.115692138671875 +20745 -0.061309814453125 +20746 -0.116455078125 +20747 -0.049957275390625 +20748 -0.105926513671875 +20749 -0.03424072265625 +20750 -0.053955078125 +20751 -0.002532958984375 +20752 0.048797607421875 +20753 0.048370361328125 +20754 0.157318115234375 +20755 0.09967041015625 +20756 0.212005615234375 +20757 0.126708984375 +20758 0.218475341796875 +20759 0.131622314453125 +20760 0.23724365234375 +20761 0.139068603515625 +20762 0.30535888671875 +20763 0.164276123046875 +20764 0.38128662109375 +20765 0.190521240234375 +20766 0.404449462890625 +20767 0.19342041015625 +20768 0.3944091796875 +20769 0.181365966796875 +20770 0.3885498046875 +20771 0.17010498046875 +20772 0.362640380859375 +20773 0.1502685546875 +20774 0.27362060546875 +20775 0.104827880859375 +20776 0.11712646484375 +20777 0.032501220703125 +20778 -0.054901123046875 +20779 -0.0450439453125 +20780 -0.19085693359375 +20781 -0.10638427734375 +20782 -0.28570556640625 +20783 -0.149200439453125 +20784 -0.339263916015625 +20785 -0.173248291015625 +20786 -0.3775634765625 +20787 -0.1890869140625 +20788 -0.445709228515625 +20789 -0.215179443359375 +20790 -0.535064697265625 +20791 -0.248138427734375 +20792 -0.629058837890625 +20793 -0.28143310546875 +20794 -0.697601318359375 +20795 -0.3031005859375 +20796 -0.70391845703125 +20797 -0.29852294921875 +20798 -0.6424560546875 +20799 -0.265869140625 +20800 -0.491241455078125 +20801 -0.19659423828125 +20802 -0.265716552734375 +20803 -0.097412109375 +20804 -0.023712158203125 +20805 0.007659912109375 +20806 0.201751708984375 +20807 0.1048583984375 +20808 0.375823974609375 +20809 0.1796875 +20810 0.485076904296875 +20811 0.226531982421875 +20812 0.56884765625 +20813 0.2613525390625 +20814 0.634765625 +20815 0.287261962890625 +20816 0.63763427734375 +20817 0.28594970703125 +20818 0.5660400390625 +20819 0.2529296875 +20820 0.4720458984375 +20821 0.209686279296875 +20822 0.40692138671875 +20823 0.177398681640625 +20824 0.3778076171875 +20825 0.159332275390625 +20826 0.376953125 +20827 0.152679443359375 +20828 0.371978759765625 +20829 0.14459228515625 +20830 0.313140869140625 +20831 0.115081787109375 +20832 0.184417724609375 +20833 0.057891845703125 +20834 0.011199951171875 +20835 -0.016357421875 +20836 -0.171051025390625 +20837 -0.093017578125 +20838 -0.33740234375 +20839 -0.161834716796875 +20840 -0.47198486328125 +20841 -0.21630859375 +20842 -0.560394287109375 +20843 -0.250640869140625 +20844 -0.58056640625 +20845 -0.2559814453125 +20846 -0.54754638671875 +20847 -0.2386474609375 +20848 -0.508575439453125 +20849 -0.218170166015625 +20850 -0.459503173828125 +20851 -0.193115234375 +20852 -0.394378662109375 +20853 -0.161346435546875 +20854 -0.35260009765625 +20855 -0.139190673828125 +20856 -0.31170654296875 +20857 -0.117767333984375 +20858 -0.197418212890625 +20859 -0.0670166015625 +20860 -0.007965087890625 +20861 0.0135498046875 +20862 0.207489013671875 +20863 0.10369873046875 +20864 0.409210205078125 +20865 0.187103271484375 +20866 0.57208251953125 +20867 0.253509521484375 +20868 0.66595458984375 +20869 0.2906494140625 +20870 0.65875244140625 +20871 0.285552978515625 +20872 0.56744384765625 +20873 0.24530029296875 +20874 0.431396484375 +20875 0.186126708984375 +20876 0.29443359375 +20877 0.126129150390625 +20878 0.182464599609375 +20879 0.07611083984375 +20880 0.06365966796875 +20881 0.023345947265625 +20882 -0.075958251953125 +20883 -0.037628173828125 +20884 -0.189422607421875 +20885 -0.087432861328125 +20886 -0.271942138671875 +20887 -0.123931884765625 +20888 -0.342529296875 +20889 -0.15472412109375 +20890 -0.364166259765625 +20891 -0.1646728515625 +20892 -0.327239990234375 +20893 -0.149810791015625 +20894 -0.2769775390625 +20895 -0.12860107421875 +20896 -0.253692626953125 +20897 -0.1175537109375 +20898 -0.24365234375 +20899 -0.111175537109375 +20900 -0.1983642578125 +20901 -0.089813232421875 +20902 -0.116241455078125 +20903 -0.053009033203125 +20904 -0.036834716796875 +20905 -0.017059326171875 +20906 0.034881591796875 +20907 0.0157470703125 +20908 0.09124755859375 +20909 0.042083740234375 +20910 0.10888671875 +20911 0.05224609375 +20912 0.125518798828125 +20913 0.061492919921875 +20914 0.15771484375 +20915 0.07647705078125 +20916 0.17828369140625 +20917 0.08599853515625 +20918 0.17108154296875 +20919 0.08343505859375 +20920 0.129974365234375 +20921 0.0662841796875 +20922 0.082427978515625 +20923 0.0457763671875 +20924 0.027679443359375 +20925 0.021697998046875 +20926 -0.065643310546875 +20927 -0.018585205078125 +20928 -0.15936279296875 +20929 -0.059356689453125 +20930 -0.21307373046875 +20931 -0.084014892578125 +20932 -0.234649658203125 +20933 -0.09564208984375 +20934 -0.2001953125 +20935 -0.084320068359375 +20936 -0.119171142578125 +20937 -0.05377197265625 +20938 -0.024749755859375 +20939 -0.01739501953125 +20940 0.085784912109375 +20941 0.0260009765625 +20942 0.178131103515625 +20943 0.0625 +20944 0.215576171875 +20945 0.077178955078125 +20946 0.211456298828125 +20947 0.07550048828125 +20948 0.17523193359375 +20949 0.06134033203125 +20950 0.128753662109375 +20951 0.04351806640625 +20952 0.1019287109375 +20953 0.0341796875 +20954 0.0743408203125 +20955 0.02490234375 +20956 0.04327392578125 +20957 0.014434814453125 +20958 0.038177490234375 +20959 0.014678955078125 +20960 0.076263427734375 +20961 0.032501220703125 +20962 0.14105224609375 +20963 0.061065673828125 +20964 0.186431884765625 +20965 0.081451416015625 +20966 0.188812255859375 +20967 0.08392333984375 +20968 0.1390380859375 +20969 0.064697265625 +20970 0.041778564453125 +20971 0.025634765625 +20972 -0.079437255859375 +20973 -0.023681640625 +20974 -0.219390869140625 +20975 -0.08111572265625 +20976 -0.367828369140625 +20977 -0.142425537109375 +20978 -0.494873046875 +20979 -0.19537353515625 +20980 -0.556243896484375 +20981 -0.221832275390625 +20982 -0.508697509765625 +20983 -0.204071044921875 +20984 -0.3756103515625 +20985 -0.151519775390625 +20986 -0.218902587890625 +20987 -0.08935546875 +20988 -0.063751220703125 +20989 -0.027740478515625 +20990 0.091552734375 +20991 0.0340576171875 +20992 0.23602294921875 +20993 0.091583251953125 +20994 0.342987060546875 +20995 0.134033203125 +20996 0.39520263671875 +20997 0.15472412109375 +20998 0.389373779296875 +20999 0.152679443359375 +21000 0.324249267578125 +21001 0.127655029296875 +21002 0.224090576171875 +21003 0.0889892578125 +21004 0.124267578125 +21005 0.0501708984375 +21006 0.037078857421875 +21007 0.0159912109375 +21008 -0.010101318359375 +21009 -0.00311279296875 +21010 -0.019439697265625 +21011 -0.007843017578125 +21012 -0.022796630859375 +21013 -0.0101318359375 +21014 -0.001556396484375 +21015 -0.0029296875 +21016 0.056304931640625 +21017 0.018280029296875 +21018 0.106719970703125 +21019 0.03692626953125 +21020 0.096893310546875 +21021 0.03314208984375 +21022 0.042694091796875 +21023 0.012908935546875 +21024 -0.018035888671875 +21025 -0.009552001953125 +21026 -0.07586669921875 +21027 -0.030731201171875 +21028 -0.11944580078125 +21029 -0.046417236328125 +21030 -0.15972900390625 +21031 -0.060791015625 +21032 -0.202606201171875 +21033 -0.076080322265625 +21034 -0.24859619140625 +21035 -0.092529296875 +21036 -0.30517578125 +21037 -0.113006591796875 +21038 -0.36212158203125 +21039 -0.133697509765625 +21040 -0.39141845703125 +21041 -0.144134521484375 +21042 -0.35528564453125 +21043 -0.130157470703125 +21044 -0.249969482421875 +21045 -0.090362548828125 +21046 -0.092864990234375 +21047 -0.03131103515625 +21048 0.08905029296875 +21049 0.036865234375 +21050 0.2352294921875 +21051 0.0914306640625 +21052 0.318817138671875 +21053 0.122314453125 +21054 0.358642578125 +21055 0.136627197265625 +21056 0.347747802734375 +21057 0.13177490234375 +21058 0.28564453125 +21059 0.107635498046875 +21060 0.223175048828125 +21061 0.0833740234375 +21062 0.196746826171875 +21063 0.072723388671875 +21064 0.179840087890625 +21065 0.06573486328125 +21066 0.155548095703125 +21067 0.056121826171875 +21068 0.151214599609375 +21069 0.054168701171875 +21070 0.156951904296875 +21071 0.056182861328125 +21072 0.13177490234375 +21073 0.046722412109375 +21074 0.100799560546875 +21075 0.03521728515625 +21076 0.087127685546875 +21077 0.03033447265625 +21078 0.05487060546875 +21079 0.01861572265625 +21080 -0.009002685546875 +21081 -0.0048828125 +21082 -0.10400390625 +21083 -0.03997802734375 +21084 -0.229400634765625 +21085 -0.086456298828125 +21086 -0.35552978515625 +21087 -0.133209228515625 +21088 -0.441925048828125 +21089 -0.1650390625 +21090 -0.473846435546875 +21091 -0.176483154296875 +21092 -0.464813232421875 +21093 -0.172607421875 +21094 -0.419097900390625 +21095 -0.155029296875 +21096 -0.334320068359375 +21097 -0.1229248046875 +21098 -0.227935791015625 +21099 -0.082855224609375 +21100 -0.12347412109375 +21101 -0.043670654296875 +21102 -0.02764892578125 +21103 -0.007843017578125 +21104 0.077667236328125 +21105 0.031463623046875 +21106 0.2132568359375 +21107 0.082061767578125 +21108 0.38885498046875 +21109 0.1475830078125 +21110 0.582794189453125 +21111 0.219940185546875 +21112 0.734039306640625 +21113 0.276214599609375 +21114 0.800140380859375 +21115 0.30047607421875 +21116 0.7783203125 +21117 0.291717529296875 +21118 0.6651611328125 +21119 0.248687744140625 +21120 0.45965576171875 +21121 0.1710205078125 +21122 0.199188232421875 +21123 0.072784423828125 +21124 -0.050689697265625 +21125 -0.02130126953125 +21126 -0.23297119140625 +21127 -0.08984375 +21128 -0.33013916015625 +21129 -0.126251220703125 +21130 -0.368408203125 +21131 -0.140380859375 +21132 -0.378936767578125 +21133 -0.143951416015625 +21134 -0.376983642578125 +21135 -0.14276123046875 +21136 -0.37969970703125 +21137 -0.143280029296875 +21138 -0.391510009765625 +21139 -0.147186279296875 +21140 -0.385345458984375 +21141 -0.14434814453125 +21142 -0.3419189453125 +21143 -0.127532958984375 +21144 -0.28289794921875 +21145 -0.104888916015625 +21146 -0.251617431640625 +21147 -0.092742919921875 +21148 -0.266143798828125 +21149 -0.097900390625 +21150 -0.273345947265625 +21151 -0.100433349609375 +21152 -0.216796875 +21153 -0.0791015625 +21154 -0.128265380859375 +21155 -0.045867919921875 +21156 -0.068145751953125 +21157 -0.023406982421875 +21158 -0.0430908203125 +21159 -0.014190673828125 +21160 -0.024444580078125 +21161 -0.0074462890625 +21162 0.020721435546875 +21163 0.009185791015625 +21164 0.124481201171875 +21165 0.047760009765625 +21166 0.25787353515625 +21167 0.097412109375 +21168 0.379119873046875 +21169 0.1424560546875 +21170 0.47991943359375 +21171 0.179840087890625 +21172 0.5281982421875 +21173 0.197509765625 +21174 0.511138916015625 +21175 0.190673828125 +21176 0.456207275390625 +21177 0.169708251953125 +21178 0.407470703125 +21179 0.15118408203125 +21180 0.383758544921875 +21181 0.142181396484375 +21182 0.35687255859375 +21183 0.132110595703125 +21184 0.31182861328125 +21185 0.11529541015625 +21186 0.250885009765625 +21187 0.09259033203125 +21188 0.1654052734375 +21189 0.06072998046875 +21190 0.035247802734375 +21191 0.01214599609375 +21192 -0.142059326171875 +21193 -0.054107666015625 +21194 -0.33563232421875 +21195 -0.126434326171875 +21196 -0.5345458984375 +21197 -0.20074462890625 +21198 -0.72186279296875 +21199 -0.27069091796875 +21200 -0.836669921875 +21201 -0.313385009765625 +21202 -0.8326416015625 +21203 -0.31146240234375 +21204 -0.7296142578125 +21205 -0.27239990234375 +21206 -0.582550048828125 +21207 -0.216888427734375 +21208 -0.440093994140625 +21209 -0.163238525390625 +21210 -0.324310302734375 +21211 -0.119720458984375 +21212 -0.20147705078125 +21213 -0.07366943359375 +21214 -0.044647216796875 +21215 -0.014892578125 +21216 0.103973388671875 +21217 0.040679931640625 +21218 0.202392578125 +21219 0.077301025390625 +21220 0.264495849609375 +21221 0.100189208984375 +21222 0.338897705078125 +21223 0.127655029296875 +21224 0.443817138671875 +21225 0.166595458984375 +21226 0.545074462890625 +21227 0.204193115234375 +21228 0.6173095703125 +21229 0.230926513671875 +21230 0.6524658203125 +21231 0.243804931640625 +21232 0.66339111328125 +21233 0.247650146484375 +21234 0.6561279296875 +21235 0.244781494140625 +21236 0.606781005859375 +21237 0.2261962890625 +21238 0.501190185546875 +21239 0.186553955078125 +21240 0.352783203125 +21241 0.130889892578125 +21242 0.176544189453125 +21243 0.064849853515625 +21244 -0.034820556640625 +21245 -0.014312744140625 +21246 -0.258209228515625 +21247 -0.097900390625 +21248 -0.44244384765625 +21249 -0.1668701171875 +21250 -0.5753173828125 +21251 -0.216522216796875 +21252 -0.65203857421875 +21253 -0.2452392578125 +21254 -0.641632080078125 +21255 -0.242431640625 +21256 -0.562164306640625 +21257 -0.2144775390625 +21258 -0.458038330078125 +21259 -0.176788330078125 +21260 -0.350555419921875 +21261 -0.13690185546875 +21262 -0.260528564453125 +21263 -0.102203369140625 +21264 -0.192108154296875 +21265 -0.07440185546875 +21266 -0.141937255859375 +21267 -0.0526123046875 +21268 -0.1021728515625 +21269 -0.03436279296875 +21270 -0.062896728515625 +21271 -0.0164794921875 +21272 -0.011932373046875 +21273 0.004974365234375 +21274 0.062835693359375 +21275 0.033966064453125 +21276 0.148712158203125 +21277 0.06597900390625 +21278 0.241729736328125 +21279 0.099517822265625 +21280 0.34912109375 +21281 0.137054443359375 +21282 0.457305908203125 +21283 0.17388916015625 +21284 0.54388427734375 +21285 0.202392578125 +21286 0.5728759765625 +21287 0.210296630859375 +21288 0.506591796875 +21289 0.18475341796875 +21290 0.351226806640625 +21291 0.12811279296875 +21292 0.146514892578125 +21293 0.05419921875 +21294 -0.05523681640625 +21295 -0.018768310546875 +21296 -0.21624755859375 +21297 -0.077606201171875 +21298 -0.334930419921875 +21299 -0.121551513671875 +21300 -0.402984619140625 +21301 -0.147613525390625 +21302 -0.4412841796875 +21303 -0.162841796875 +21304 -0.49578857421875 +21305 -0.182952880859375 +21306 -0.5601806640625 +21307 -0.205718994140625 +21308 -0.600738525390625 +21309 -0.21954345703125 +21310 -0.584228515625 +21311 -0.2130126953125 +21312 -0.47930908203125 +21313 -0.1754150390625 +21314 -0.27935791015625 +21315 -0.104583740234375 +21316 -0.0089111328125 +21317 -0.00909423828125 +21318 0.268798828125 +21319 0.089141845703125 +21320 0.482818603515625 +21321 0.16558837890625 +21322 0.60369873046875 +21323 0.209930419921875 +21324 0.650421142578125 +21325 0.22857666015625 +21326 0.66400146484375 +21327 0.2354736328125 +21328 0.6414794921875 +21329 0.229522705078125 +21330 0.572540283203125 +21331 0.20709228515625 +21332 0.498138427734375 +21333 0.18218994140625 +21334 0.439453125 +21335 0.162078857421875 +21336 0.375518798828125 +21337 0.13958740234375 +21338 0.274505615234375 +21339 0.103790283203125 +21340 0.1087646484375 +21341 0.04522705078125 +21342 -0.099395751953125 +21343 -0.028289794921875 +21344 -0.3182373046875 +21345 -0.105712890625 +21346 -0.5489501953125 +21347 -0.187347412109375 +21348 -0.7738037109375 +21349 -0.266937255859375 +21350 -0.86383056640625 +21351 -0.326171875 +21352 -0.870391845703125 +21353 -0.353485107421875 +21354 -0.86895751953125 +21355 -0.354888916015625 +21356 -0.861053466796875 +21357 -0.3348388671875 +21358 -0.765869140625 +21359 -0.287322998046875 +21360 -0.5301513671875 +21361 -0.20843505859375 +21362 -0.214691162109375 +21363 -0.10064697265625 +21364 0.137359619140625 +21365 0.021209716796875 +21366 0.474822998046875 +21367 0.139404296875 +21368 0.76239013671875 +21369 0.241668701171875 +21370 0.867462158203125 +21371 0.318634033203125 +21372 0.870361328125 +21373 0.370361328125 +21374 0.86480712890625 +21375 0.39276123046875 +21376 0.831817626953125 +21377 0.387603759765625 +21378 0.677581787109375 +21379 0.3631591796875 +21380 0.495880126953125 +21381 0.32135009765625 +21382 0.30767822265625 +21383 0.26849365234375 +21384 0.116180419921875 +21385 0.205322265625 +21386 -0.110748291015625 +21387 0.120880126953125 +21388 -0.381805419921875 +21389 0.01275634765625 +21390 -0.6572265625 +21391 -0.104248046875 +21392 -0.857421875 +21393 -0.209503173828125 +21394 -0.870391845703125 +21395 -0.2882080078125 +21396 -0.870391845703125 +21397 -0.337860107421875 +21398 -0.86444091796875 +21399 -0.367645263671875 +21400 -0.85723876953125 +21401 -0.389739990234375 +21402 -0.790008544921875 +21403 -0.39776611328125 +21404 -0.62847900390625 +21405 -0.37298583984375 +21406 -0.3956298828125 +21407 -0.314239501953125 +21408 -0.126708984375 +21409 -0.232757568359375 +21410 0.150115966796875 +21411 -0.137908935546875 +21412 0.424041748046875 +21413 -0.033660888671875 +21414 0.670623779296875 +21415 0.0706787109375 +21416 0.854522705078125 +21417 0.16180419921875 +21418 0.866485595703125 +21419 0.23358154296875 +21420 0.86920166015625 +21421 0.280670166015625 +21422 0.8653564453125 +21423 0.30926513671875 +21424 0.857147216796875 +21425 0.323883056640625 +21426 0.766845703125 +21427 0.323455810546875 +21428 0.628509521484375 +21429 0.3096923828125 +21430 0.462127685546875 +21431 0.28021240234375 +21432 0.297210693359375 +21433 0.24383544921875 +21434 0.14862060546875 +21435 0.204742431640625 +21436 -0.00537109375 +21437 0.155059814453125 +21438 -0.15753173828125 +21439 0.09735107421875 +21440 -0.31304931640625 +21441 0.0303955078125 +21442 -0.48876953125 +21443 -0.050628662109375 +21444 -0.6416015625 +21445 -0.129547119140625 +21446 -0.751373291015625 +21447 -0.197845458984375 +21448 -0.84619140625 +21449 -0.263427734375 +21450 -0.861297607421875 +21451 -0.3211669921875 +21452 -0.863250732421875 +21453 -0.359588623046875 +21454 -0.856597900390625 +21455 -0.367767333984375 +21456 -0.7498779296875 +21457 -0.349822998046875 +21458 -0.624542236328125 +21459 -0.325592041015625 +21460 -0.47808837890625 +21461 -0.287506103515625 +21462 -0.253387451171875 +21463 -0.215423583984375 +21464 0.003692626953125 +21465 -0.125030517578125 +21466 0.2257080078125 +21467 -0.03985595703125 +21468 0.427154541015625 +21469 0.044403076171875 +21470 0.643218994140625 +21471 0.13885498046875 +21472 0.855926513671875 +21473 0.240142822265625 +21474 0.870361328125 +21475 0.3282470703125 +21476 0.870361328125 +21477 0.386077880859375 +21478 0.862762451171875 +21479 0.416046142578125 +21480 0.79669189453125 +21481 0.4171142578125 +21482 0.595794677734375 +21483 0.385955810546875 +21484 0.362152099609375 +21485 0.33258056640625 +21486 0.1270751953125 +21487 0.2666015625 +21488 -0.086944580078125 +21489 0.195281982421875 +21490 -0.2784423828125 +21491 0.119354248046875 +21492 -0.484832763671875 +21493 0.026885986328125 +21494 -0.729583740234375 +21495 -0.08868408203125 +21496 -0.86688232421875 +21497 -0.209930419921875 +21498 -0.870391845703125 +21499 -0.315032958984375 +21500 -0.86859130859375 +21501 -0.402191162109375 +21502 -0.86279296875 +21503 -0.47064208984375 +21504 -0.817962646484375 +21505 -0.50787353515625 +21506 -0.6116943359375 +21507 -0.49853515625 +21508 -0.3128662109375 +21509 -0.4404296875 +21510 0.039398193359375 +21511 -0.344879150390625 +21512 0.422821044921875 +21513 -0.21905517578125 +21514 0.805145263671875 +21515 -0.07427978515625 +21516 0.870361328125 +21517 0.06719970703125 +21518 0.870361328125 +21519 0.186767578125 +21520 0.860015869140625 +21521 0.280029296875 +21522 0.727935791015625 +21523 0.343902587890625 +21524 0.48114013671875 +21525 0.3760986328125 +21526 0.2059326171875 +21527 0.3837890625 +21528 -0.06103515625 +21529 0.373748779296875 +21530 -0.29913330078125 +21531 0.349029541015625 +21532 -0.516204833984375 +21533 0.305206298828125 +21534 -0.7252197265625 +21535 0.23773193359375 +21536 -0.85980224609375 +21537 0.15472412109375 +21538 -0.870391845703125 +21539 0.0673828125 +21540 -0.870391845703125 +21541 -0.014434814453125 +21542 -0.858062744140625 +21543 -0.07489013671875 +21544 -0.673004150390625 +21545 -0.11199951171875 +21546 -0.42694091796875 +21547 -0.1414794921875 +21548 -0.2100830078125 +21549 -0.176544189453125 +21550 -0.0362548828125 +21551 -0.21600341796875 +21552 0.10943603515625 +21553 -0.2503662109375 +21554 0.23516845703125 +21555 -0.273101806640625 +21556 0.373687744140625 +21557 -0.2711181640625 +21558 0.517791748046875 +21559 -0.245025634765625 +21560 0.602783203125 +21561 -0.214630126953125 +21562 0.635711669921875 +21563 -0.1785888671875 +21564 0.655181884765625 +21565 -0.12689208984375 +21566 0.65948486328125 +21567 -0.063140869140625 +21568 0.651275634765625 +21569 0.009552001953125 +21570 0.61846923828125 +21571 0.08294677734375 +21572 0.53753662109375 +21573 0.1448974609375 +21574 0.404144287109375 +21575 0.189178466796875 +21576 0.22186279296875 +21577 0.2122802734375 +21578 0.003997802734375 +21579 0.214202880859375 +21580 -0.22100830078125 +21581 0.2003173828125 +21582 -0.42449951171875 +21583 0.17681884765625 +21584 -0.579833984375 +21585 0.15032958984375 +21586 -0.641876220703125 +21587 0.13427734375 +21588 -0.6177978515625 +21589 0.12677001953125 +21590 -0.575531005859375 +21591 0.107940673828125 +21592 -0.526336669921875 +21593 0.076507568359375 +21594 -0.42645263671875 +21595 0.049102783203125 +21596 -0.2581787109375 +21597 0.034759521484375 +21598 -0.068695068359375 +21599 0.02264404296875 +21600 0.09222412109375 +21601 0.00128173828125 +21602 0.232147216796875 +21603 -0.023040771484375 +21604 0.3509521484375 +21605 -0.046783447265625 +21606 0.410064697265625 +21607 -0.078857421875 +21608 0.372955322265625 +21609 -0.128204345703125 +21610 0.2554931640625 +21611 -0.18817138671875 +21612 0.10711669921875 +21613 -0.24249267578125 +21614 -0.052886962890625 +21615 -0.285125732421875 +21616 -0.186279296875 +21617 -0.304962158203125 +21618 -0.23291015625 +21619 -0.284881591796875 +21620 -0.209442138671875 +21621 -0.232330322265625 +21622 -0.174163818359375 +21623 -0.16827392578125 +21624 -0.126739501953125 +21625 -0.095733642578125 +21626 -0.048126220703125 +21627 -0.012054443359375 +21628 0.0426025390625 +21629 0.073516845703125 +21630 0.10748291015625 +21631 0.146087646484375 +21632 0.1409912109375 +21633 0.20123291015625 +21634 0.19708251953125 +21635 0.253509521484375 +21636 0.273651123046875 +21637 0.300689697265625 +21638 0.31768798828125 +21639 0.3253173828125 +21640 0.341094970703125 +21641 0.330841064453125 +21642 0.368011474609375 +21643 0.325286865234375 +21644 0.37249755859375 +21645 0.301666259765625 +21646 0.30072021484375 +21647 0.244873046875 +21648 0.1517333984375 +21649 0.156768798828125 +21650 -0.01470947265625 +21651 0.058441162109375 +21652 -0.1883544921875 +21653 -0.044189453125 +21654 -0.372711181640625 +21655 -0.1495361328125 +21656 -0.51397705078125 +21657 -0.238250732421875 +21658 -0.57177734375 +21659 -0.295379638671875 +21660 -0.53948974609375 +21661 -0.31689453125 +21662 -0.43511962890625 +21663 -0.306915283203125 +21664 -0.2962646484375 +21665 -0.276153564453125 +21666 -0.161102294921875 +21667 -0.23614501953125 +21668 -0.0435791015625 +21669 -0.19140625 +21670 0.060394287109375 +21671 -0.14141845703125 +21672 0.13665771484375 +21673 -0.091796875 +21674 0.170135498046875 +21675 -0.04888916015625 +21676 0.16552734375 +21677 -0.013214111328125 +21678 0.15728759765625 +21679 0.023773193359375 +21680 0.150787353515625 +21681 0.061553955078125 +21682 0.12200927734375 +21683 0.0904541015625 +21684 0.080108642578125 +21685 0.111297607421875 +21686 0.05126953125 +21687 0.13055419921875 +21688 0.062896728515625 +21689 0.1553955078125 +21690 0.09271240234375 +21691 0.17791748046875 +21692 0.092987060546875 +21693 0.1827392578125 +21694 0.07855224609375 +21695 0.174468994140625 +21696 0.06427001953125 +21697 0.158172607421875 +21698 0.0347900390625 +21699 0.129913330078125 +21700 -0.01171875 +21701 0.09039306640625 +21702 -0.056060791015625 +21703 0.047149658203125 +21704 -0.055511474609375 +21705 0.015228271484375 +21706 -0.010467529296875 +21707 -0.003631591796875 +21708 0.02508544921875 +21709 -0.024444580078125 +21710 0.025665283203125 +21711 -0.053466796875 +21712 0.017333984375 +21713 -0.0810546875 +21714 0.00189208984375 +21715 -0.105377197265625 +21716 -0.03173828125 +21717 -0.128997802734375 +21718 -0.071502685546875 +21719 -0.14764404296875 +21720 -0.13543701171875 +21721 -0.166778564453125 +21722 -0.219970703125 +21723 -0.185546875 +21724 -0.300506591796875 +21725 -0.196868896484375 +21726 -0.376312255859375 +21727 -0.20147705078125 +21728 -0.416107177734375 +21729 -0.1907958984375 +21730 -0.371124267578125 +21731 -0.150970458984375 +21732 -0.242279052734375 +21733 -0.08380126953125 +21734 -0.069732666015625 +21735 -0.003326416015625 +21736 0.125640869140625 +21737 0.082489013671875 +21738 0.31268310546875 +21739 0.162628173828125 +21740 0.45501708984375 +21741 0.224639892578125 +21742 0.554779052734375 +21743 0.268310546875 +21744 0.61065673828125 +21745 0.292755126953125 +21746 0.610931396484375 +21747 0.2940673828125 +21748 0.531463623046875 +21749 0.26483154296875 +21750 0.3883056640625 +21751 0.21044921875 +21752 0.23468017578125 +21753 0.148193359375 +21754 0.095245361328125 +21755 0.086700439453125 +21756 -0.00396728515625 +21757 0.035186767578125 +21758 -0.04852294921875 +21759 -0.000640869140625 +21760 -0.055145263671875 +21761 -0.024993896484375 +21762 -0.0758056640625 +21763 -0.052734375 +21764 -0.138702392578125 +21765 -0.09124755859375 +21766 -0.209197998046875 +21767 -0.1290283203125 +21768 -0.289031982421875 +21769 -0.1656494140625 +21770 -0.37884521484375 +21771 -0.20068359375 +21772 -0.456329345703125 +21773 -0.22705078125 +21774 -0.51641845703125 +21775 -0.2431640625 +21776 -0.519287109375 +21777 -0.2373046875 +21778 -0.458251953125 +21779 -0.207977294921875 +21780 -0.384796142578125 +21781 -0.17132568359375 +21782 -0.323699951171875 +21783 -0.13568115234375 +21784 -0.269287109375 +21785 -0.100341796875 +21786 -0.1951904296875 +21787 -0.05853271484375 +21788 -0.100006103515625 +21789 -0.010894775390625 +21790 -0.01055908203125 +21791 0.033447265625 +21792 0.1033935546875 +21793 0.0826416015625 +21794 0.24908447265625 +21795 0.13812255859375 +21796 0.373199462890625 +21797 0.183349609375 +21798 0.45806884765625 +21799 0.212677001953125 +21800 0.511474609375 +21801 0.228363037109375 +21802 0.565399169921875 +21803 0.240142822265625 +21804 0.61138916015625 +21805 0.245819091796875 +21806 0.5897216796875 +21807 0.22802734375 +21808 0.4906005859375 +21809 0.184539794921875 +21810 0.33148193359375 +21811 0.12139892578125 +21812 0.147796630859375 +21813 0.050140380859375 +21814 -0.01873779296875 +21815 -0.01580810546875 +21816 -0.140289306640625 +21817 -0.0672607421875 +21818 -0.191986083984375 +21819 -0.095947265625 +21820 -0.184295654296875 +21821 -0.104339599609375 +21822 -0.161834716796875 +21823 -0.10528564453125 +21824 -0.166595458984375 +21825 -0.111053466796875 +21826 -0.19390869140625 +21827 -0.120086669921875 +21828 -0.22442626953125 +21829 -0.12664794921875 +21830 -0.279754638671875 +21831 -0.137481689453125 +21832 -0.3389892578125 +21833 -0.146697998046875 +21834 -0.3543701171875 +21835 -0.140533447265625 +21836 -0.348175048828125 +21837 -0.126312255859375 +21838 -0.32598876953125 +21839 -0.1064453125 +21840 -0.2581787109375 +21841 -0.072784423828125 +21842 -0.139801025390625 +21843 -0.02459716796875 +21844 0.014617919921875 +21845 0.033111572265625 +21846 0.144378662109375 +21847 0.081512451171875 +21848 0.221038818359375 +21849 0.11163330078125 +21850 0.27069091796875 +21851 0.1309814453125 +21852 0.294036865234375 +21853 0.139617919921875 +21854 0.311767578125 +21855 0.143707275390625 +21856 0.339141845703125 +21857 0.14794921875 +21858 0.360260009765625 +21859 0.1475830078125 +21860 0.360504150390625 +21861 0.13873291015625 +21862 0.308380126953125 +21863 0.11322021484375 +21864 0.18170166015625 +21865 0.065582275390625 +21866 0.0047607421875 +21867 0.00335693359375 +21868 -0.17559814453125 +21869 -0.059539794921875 +21870 -0.3143310546875 +21871 -0.109832763671875 +21872 -0.36785888671875 +21873 -0.13470458984375 +21874 -0.36248779296875 +21875 -0.141021728515625 +21876 -0.343536376953125 +21877 -0.14111328125 +21878 -0.3018798828125 +21879 -0.1322021484375 +21880 -0.231414794921875 +21881 -0.11248779296875 +21882 -0.117645263671875 +21883 -0.0780029296875 +21884 0.007049560546875 +21885 -0.038055419921875 +21886 0.087982177734375 +21887 -0.008270263671875 +21888 0.13946533203125 +21889 0.014892578125 +21890 0.17425537109375 +21891 0.034454345703125 +21892 0.188201904296875 +21893 0.0487060546875 +21894 0.171234130859375 +21895 0.054229736328125 +21896 0.118438720703125 +21897 0.049072265625 +21898 0.05706787109375 +21899 0.040374755859375 +21900 -0.010711669921875 +21901 0.028289794921875 +21902 -0.0914306640625 +21903 0.01068115234375 +21904 -0.162322998046875 +21905 -0.006256103515625 +21906 -0.194549560546875 +21907 -0.014556884765625 +21908 -0.1492919921875 +21909 -0.00335693359375 +21910 -0.02166748046875 +21911 0.028839111328125 +21912 0.124053955078125 +21913 0.064300537109375 +21914 0.211151123046875 +21915 0.08184814453125 +21916 0.240447998046875 +21917 0.082183837890625 +21918 0.242218017578125 +21919 0.07421875 +21920 0.2257080078125 +21921 0.06103515625 +21922 0.194366455078125 +21923 0.0440673828125 +21924 0.115509033203125 +21925 0.01458740234375 +21926 0.0128173828125 +21927 -0.020355224609375 +21928 -0.053802490234375 +21929 -0.043701171875 +21930 -0.110626220703125 +21931 -0.06256103515625 +21932 -0.199493408203125 +21933 -0.08856201171875 +21934 -0.29437255859375 +21935 -0.114410400390625 +21936 -0.33221435546875 +21937 -0.122528076171875 +21938 -0.27972412109375 +21939 -0.103790283203125 +21940 -0.185333251953125 +21941 -0.072021484375 +21942 -0.128204345703125 +21943 -0.049713134765625 +21944 -0.115692138671875 +21945 -0.039306640625 +21946 -0.116455078125 +21947 -0.032379150390625 +21948 -0.105926513671875 +21949 -0.022491455078125 +21950 -0.053955078125 +21951 -0.0015869140625 +21952 0.048797607421875 +21953 0.0325927734375 +21954 0.157318115234375 +21955 0.06719970703125 +21956 0.212005615234375 +21957 0.085357666015625 +21958 0.218475341796875 +21959 0.088531494140625 +21960 0.23724365234375 +21961 0.093597412109375 +21962 0.30535888671875 +21963 0.110992431640625 +21964 0.38128662109375 +21965 0.12921142578125 +21966 0.404449462890625 +21967 0.131500244140625 +21968 0.3944091796875 +21969 0.123626708984375 +21970 0.3885498046875 +21971 0.116363525390625 +21972 0.362640380859375 +21973 0.103240966796875 +21974 0.27362060546875 +21975 0.072540283203125 +21976 0.11712646484375 +21977 0.023345947265625 +21978 -0.054901123046875 +21979 -0.029510498046875 +21980 -0.19085693359375 +21981 -0.071319580078125 +21982 -0.28570556640625 +21983 -0.100494384765625 +21984 -0.339263916015625 +21985 -0.11688232421875 +21986 -0.3775634765625 +21987 -0.12774658203125 +21988 -0.445709228515625 +21989 -0.145751953125 +21990 -0.535064697265625 +21991 -0.1685791015625 +21992 -0.629058837890625 +21993 -0.19171142578125 +21994 -0.697601318359375 +21995 -0.206939697265625 +21996 -0.70391845703125 +21997 -0.204193115234375 +21998 -0.6424560546875 +21999 -0.18218994140625 +22000 -0.491241455078125 +22001 -0.135040283203125 +22002 -0.265716552734375 +22003 -0.067352294921875 +22004 -0.023712158203125 +22005 0.004425048828125 +22006 0.201751708984375 +22007 0.070831298828125 +22008 0.375823974609375 +22009 0.121978759765625 +22010 0.485076904296875 +22011 0.15399169921875 +22012 0.56884765625 +22013 0.177825927734375 +22014 0.634765625 +22015 0.195648193359375 +22016 0.63763427734375 +22017 0.195343017578125 +22018 0.5660400390625 +22019 0.174591064453125 +22020 0.4720458984375 +22021 0.14703369140625 +22022 0.40692138671875 +22023 0.125457763671875 +22024 0.3778076171875 +22025 0.11181640625 +22026 0.376953125 +22027 0.104461669921875 +22028 0.371978759765625 +22029 0.095733642578125 +22030 0.313140869140625 +22031 0.0736083984375 +22032 0.184417724609375 +22033 0.034515380859375 +22034 0.011199951171875 +22035 -0.01483154296875 +22036 -0.171051025390625 +22037 -0.0653076171875 +22038 -0.33740234375 +22039 -0.1104736328125 +22040 -0.47198486328125 +22041 -0.146209716796875 +22042 -0.560394287109375 +22043 -0.168853759765625 +22044 -0.58056640625 +22045 -0.172943115234375 +22046 -0.54754638671875 +22047 -0.16229248046875 +22048 -0.508575439453125 +22049 -0.148834228515625 +22050 -0.459503173828125 +22051 -0.131744384765625 +22052 -0.394378662109375 +22053 -0.10986328125 +22054 -0.35260009765625 +22055 -0.093231201171875 +22056 -0.31170654296875 +22057 -0.07666015625 +22058 -0.197418212890625 +22059 -0.04205322265625 +22060 -0.007965087890625 +22061 0.010650634765625 +22062 0.207489013671875 +22063 0.06890869140625 +22064 0.409210205078125 +22065 0.122650146484375 +22066 0.57208251953125 +22067 0.165496826171875 +22068 0.66595458984375 +22069 0.18988037109375 +22070 0.65875244140625 +22071 0.18780517578125 +22072 0.56744384765625 +22073 0.16357421875 +22074 0.431396484375 +22075 0.127044677734375 +22076 0.29443359375 +22077 0.08929443359375 +22078 0.182464599609375 +22079 0.05694580078125 +22080 0.06365966796875 +22081 0.02239990234375 +22082 -0.075958251953125 +22083 -0.01751708984375 +22084 -0.189422607421875 +22085 -0.05084228515625 +22086 -0.271942138671875 +22087 -0.076080322265625 +22088 -0.342529296875 +22089 -0.097686767578125 +22090 -0.364166259765625 +22091 -0.106353759765625 +22092 -0.327239990234375 +22093 -0.099517822265625 +22094 -0.2769775390625 +22095 -0.088287353515625 +22096 -0.253692626953125 +22097 -0.082611083984375 +22098 -0.24365234375 +22099 -0.079132080078125 +22100 -0.1983642578125 +22101 -0.06591796875 +22102 -0.116241455078125 +22103 -0.042694091796875 +22104 -0.036834716796875 +22105 -0.019439697265625 +22106 0.034881591796875 +22107 0.00238037109375 +22108 0.09124755859375 +22109 0.0206298828125 +22110 0.10888671875 +22111 0.02923583984375 +22112 0.125518798828125 +22113 0.037322998046875 +22114 0.15771484375 +22115 0.048828125 +22116 0.17828369140625 +22117 0.056793212890625 +22118 0.17108154296875 +22119 0.057098388671875 +22120 0.129974365234375 +22121 0.048126220703125 +22122 0.082427978515625 +22123 0.03668212890625 +22124 0.027679443359375 +22125 0.022552490234375 +22126 -0.065643310546875 +22127 -0.001922607421875 +22128 -0.15936279296875 +22129 -0.027191162109375 +22130 -0.21307373046875 +22131 -0.043121337890625 +22132 -0.234649658203125 +22133 -0.051513671875 +22134 -0.2001953125 +22135 -0.0462646484375 +22136 -0.119171142578125 +22137 -0.029541015625 +22138 -0.024749755859375 +22139 -0.0093994140625 +22140 0.085784912109375 +22141 0.0150146484375 +22142 0.178131103515625 +22143 0.03533935546875 +22144 0.215576171875 +22145 0.0426025390625 +22146 0.211456298828125 +22147 0.040191650390625 +22148 0.17523193359375 +22149 0.030548095703125 +22150 0.128753662109375 +22151 0.01910400390625 +22152 0.1019287109375 +22153 0.01324462890625 +22154 0.0743408203125 +22155 0.007843017578125 +22156 0.04327392578125 +22157 0.002105712890625 +22158 0.038177490234375 +22159 0.003204345703125 +22160 0.076263427734375 +22161 0.015289306640625 +22162 0.14105224609375 +22163 0.034088134765625 +22164 0.186431884765625 +22165 0.04803466796875 +22166 0.188812255859375 +22167 0.051116943359375 +22168 0.1390380859375 +22169 0.040985107421875 +22170 0.041778564453125 +22171 0.0186767578125 +22172 -0.079437255859375 +22173 -0.010040283203125 +22174 -0.219390869140625 +22175 -0.0439453125 +22176 -0.367828369140625 +22177 -0.08050537109375 +22178 -0.494873046875 +22179 -0.1123046875 +22180 -0.556243896484375 +22181 -0.12835693359375 +22182 -0.508697509765625 +22183 -0.117889404296875 +22184 -0.3756103515625 +22185 -0.08660888671875 +22186 -0.218902587890625 +22187 -0.04974365234375 +22188 -0.063751220703125 +22189 -0.013458251953125 +22190 0.091552734375 +22191 0.02276611328125 +22192 0.23602294921875 +22193 0.056365966796875 +22194 0.342987060546875 +22195 0.080810546875 +22196 0.39520263671875 +22197 0.09197998046875 +22198 0.389373779296875 +22199 0.089141845703125 +22200 0.324249267578125 +22201 0.072021484375 +22202 0.224090576171875 +22203 0.046722412109375 +22204 0.124267578125 +22205 0.022003173828125 +22206 0.037078857421875 +22207 0.00091552734375 +22208 -0.010101318359375 +22209 -0.009796142578125 +22210 -0.019439697265625 +22211 -0.0107421875 +22212 -0.022796630859375 +22213 -0.0098876953125 +22214 -0.001556396484375 +22215 -0.00274658203125 +22216 0.056304931640625 +22217 0.0135498046875 +22218 0.106719970703125 +22219 0.027923583984375 +22220 0.096893310546875 +22221 0.0272216796875 +22222 0.042694091796875 +22223 0.015289306640625 +22224 -0.018035888671875 +22225 0.00140380859375 +22226 -0.07586669921875 +22227 -0.0120849609375 +22228 -0.11944580078125 +22229 -0.02239990234375 +22230 -0.15972900390625 +22231 -0.03228759765625 +22232 -0.202606201171875 +22233 -0.043182373046875 +22234 -0.24859619140625 +22235 -0.05517578125 +22236 -0.30517578125 +22237 -0.070098876953125 +22238 -0.36212158203125 +22239 -0.085357666015625 +22240 -0.39141845703125 +22241 -0.093963623046875 +22242 -0.35528564453125 +22243 -0.086456298828125 +22244 -0.249969482421875 +22245 -0.061798095703125 +22246 -0.092864990234375 +22247 -0.02423095703125 +22248 0.08905029296875 +22249 0.01959228515625 +22250 0.2352294921875 +22251 0.054718017578125 +22252 0.318817138671875 +22253 0.074554443359375 +22254 0.358642578125 +22255 0.08380126953125 +22256 0.347747802734375 +22257 0.080780029296875 +22258 0.28564453125 +22259 0.06536865234375 +22260 0.223175048828125 +22261 0.0501708984375 +22262 0.196746826171875 +22263 0.044189453125 +22264 0.179840087890625 +22265 0.040802001953125 +22266 0.155548095703125 +22267 0.0357666015625 +22268 0.151214599609375 +22269 0.035797119140625 +22270 0.156951904296875 +22271 0.03839111328125 +22272 0.13177490234375 +22273 0.033447265625 +22274 0.100799560546875 +22275 0.026702880859375 +22276 0.087127685546875 +22277 0.023681640625 +22278 0.05487060546875 +22279 0.016448974609375 +22280 -0.009002685546875 +22281 0.00213623046875 +22282 -0.10400390625 +22283 -0.0191650390625 +22284 -0.229400634765625 +22285 -0.047332763671875 +22286 -0.35552978515625 +22287 -0.07586669921875 +22288 -0.441925048828125 +22289 -0.095947265625 +22290 -0.473846435546875 +22291 -0.10430908203125 +22292 -0.464813232421875 +22293 -0.103790283203125 +22294 -0.419097900390625 +22295 -0.095184326171875 +22296 -0.334320068359375 +22297 -0.077911376953125 +22298 -0.227935791015625 +22299 -0.055633544921875 +22300 -0.12347412109375 +22301 -0.033416748046875 +22302 -0.02764892578125 +22303 -0.0126953125 +22304 0.077667236328125 +22305 0.01043701171875 +22306 0.2132568359375 +22307 0.040435791015625 +22308 0.38885498046875 +22309 0.079345703125 +22310 0.582794189453125 +22311 0.122467041015625 +22312 0.734039306640625 +22313 0.156524658203125 +22314 0.800140380859375 +22315 0.172271728515625 +22316 0.7783203125 +22317 0.16900634765625 +22318 0.6651611328125 +22319 0.145904541015625 +22320 0.45965576171875 +22321 0.10272216796875 +22322 0.199188232421875 +22323 0.0474853515625 +22324 -0.050689697265625 +22325 -0.005706787109375 +22326 -0.23297119140625 +22327 -0.0445556640625 +22328 -0.33013916015625 +22329 -0.0653076171875 +22330 -0.368408203125 +22331 -0.07366943359375 +22332 -0.378936767578125 +22333 -0.076324462890625 +22334 -0.376983642578125 +22335 -0.076568603515625 +22336 -0.37969970703125 +22337 -0.07806396484375 +22338 -0.391510009765625 +22339 -0.081695556640625 +22340 -0.385345458984375 +22341 -0.081573486328125 +22342 -0.3419189453125 +22343 -0.073455810546875 +22344 -0.28289794921875 +22345 -0.061920166015625 +22346 -0.251617431640625 +22347 -0.0562744140625 +22348 -0.266143798828125 +22349 -0.06036376953125 +22350 -0.273345947265625 +22351 -0.062652587890625 +22352 -0.216796875 +22353 -0.050933837890625 +22354 -0.128265380859375 +22355 -0.03204345703125 +22356 -0.068145751953125 +22357 -0.01898193359375 +22358 -0.0430908203125 +22359 -0.013214111328125 +22360 -0.024444580078125 +22361 -0.00860595703125 +22362 0.020721435546875 +22363 0.00189208984375 +22364 0.124481201171875 +22365 0.025146484375 +22366 0.25787353515625 +22367 0.05487060546875 +22368 0.379119873046875 +22369 0.08197021484375 +22370 0.47991943359375 +22371 0.1046142578125 +22372 0.5281982421875 +22373 0.1158447265625 +22374 0.511138916015625 +22375 0.11285400390625 +22376 0.456207275390625 +22377 0.10150146484375 +22378 0.407470703125 +22379 0.09130859375 +22380 0.383758544921875 +22381 0.086334228515625 +22382 0.35687255859375 +22383 0.0804443359375 +22384 0.31182861328125 +22385 0.0704345703125 +22386 0.250885009765625 +22387 0.05682373046875 +22388 0.1654052734375 +22389 0.03778076171875 +22390 0.035247802734375 +22391 0.009002685546875 +22392 -0.142059326171875 +22393 -0.02996826171875 +22394 -0.33563232421875 +22395 -0.07244873046875 +22396 -0.5345458984375 +22397 -0.11602783203125 +22398 -0.72186279296875 +22399 -0.157012939453125 +22400 -0.836669921875 +22401 -0.182220458984375 +22402 -0.8326416015625 +22403 -0.181640625 +22404 -0.7296142578125 +22405 -0.1595458984375 +22406 -0.582550048828125 +22407 -0.1278076171875 +22408 -0.440093994140625 +22409 -0.096954345703125 +22410 -0.324310302734375 +22411 -0.071746826171875 +22412 -0.20147705078125 +22413 -0.044891357421875 +22414 -0.044647216796875 +22415 -0.010589599609375 +22416 0.103973388671875 +22417 0.02197265625 +22418 0.202392578125 +22419 0.043701171875 +22420 0.264495849609375 +22421 0.05755615234375 +22422 0.338897705078125 +22423 0.07403564453125 +22424 0.443817138671875 +22425 0.0970458984375 +22426 0.545074462890625 +22427 0.119171142578125 +22428 0.6173095703125 +22429 0.13494873046875 +22430 0.6524658203125 +22431 0.142608642578125 +22432 0.66339111328125 +22433 0.14495849609375 +22434 0.6561279296875 +22435 0.143280029296875 +22436 0.606781005859375 +22437 0.132415771484375 +22438 0.501190185546875 +22439 0.10931396484375 +22440 0.352783203125 +22441 0.076904296875 +22442 0.176544189453125 +22443 0.0384521484375 +22444 -0.034820556640625 +22445 -0.007568359375 +22446 -0.258209228515625 +22447 -0.056121826171875 +22448 -0.44244384765625 +22449 -0.09613037109375 +22450 -0.5753173828125 +22451 -0.124969482421875 +22452 -0.65203857421875 +22453 -0.1416015625 +22454 -0.641632080078125 +22455 -0.13934326171875 +22456 -0.562164306640625 +22457 -0.12213134765625 +22458 -0.458038330078125 +22459 -0.099517822265625 +22460 -0.350555419921875 +22461 -0.076141357421875 +22462 -0.260528564453125 +22463 -0.056488037109375 +22464 -0.192108154296875 +22465 -0.041473388671875 +22466 -0.141937255859375 +22467 -0.0303955078125 +22468 -0.1021728515625 +22469 -0.021575927734375 +22470 -0.062896728515625 +22471 -0.01287841796875 +22472 -0.011932373046875 +22473 -0.001678466796875 +22474 0.062835693359375 +22475 0.014617919921875 +22476 0.148712158203125 +22477 0.03326416015625 +22478 0.241729736328125 +22479 0.053375244140625 +22480 0.34912109375 +22481 0.0765380859375 +22482 0.457305908203125 +22483 0.099822998046875 +22484 0.54388427734375 +22485 0.118377685546875 +22486 0.5728759765625 +22487 0.12445068359375 +22488 0.506591796875 +22489 0.109893798828125 +22490 0.351226806640625 +22491 0.076080322265625 +22492 0.146514892578125 +22493 0.031585693359375 +22494 -0.05523681640625 +22495 -0.012237548828125 +22496 -0.21624755859375 +22497 -0.047210693359375 +22498 -0.334930419921875 +22499 -0.072967529296875 +22500 -0.402984619140625 +22501 -0.08770751953125 +22502 -0.4412841796875 +22503 -0.095947265625 +22504 -0.49578857421875 +22505 -0.10760498046875 +22506 -0.5601806640625 +22507 -0.121337890625 +22508 -0.600738525390625 +22509 -0.129913330078125 +22510 -0.584228515625 +22511 -0.12615966796875 +22512 -0.47930908203125 +22513 -0.103302001953125 +22514 -0.27935791015625 +22515 -0.0599365234375 +22516 -0.0089111328125 +22517 -0.0013427734375 +22518 0.268798828125 +22519 0.05877685546875 +22520 0.482818603515625 +22521 0.105072021484375 +22522 0.60369873046875 +22523 0.131195068359375 +22524 0.650421142578125 +22525 0.141265869140625 +22526 0.66400146484375 +22527 0.144134521484375 +22528 0.6414794921875 +22529 0.139404296875 +22530 0.572540283203125 +22531 0.124786376953125 +22532 0.498138427734375 +22533 0.10797119140625 +22534 0.439453125 +22535 0.093170166015625 +22536 0.375518798828125 +22537 0.07684326171875 +22538 0.274505615234375 +22539 0.05340576171875 +22540 0.1087646484375 +22541 0.018096923828125 +22542 -0.099395751953125 +22543 -0.02471923828125 +22544 -0.3182373046875 +22545 -0.068939208984375 +22546 -0.5489501953125 +22547 -0.114593505859375 +22548 -0.7738037109375 +22549 -0.158233642578125 +22550 -0.86383056640625 +22551 -0.190032958984375 +22552 -0.870391845703125 +22553 -0.203857421875 +22554 -0.86895751953125 +22555 -0.2030029296875 +22556 -0.861053466796875 +22557 -0.18994140625 +22558 -0.765869140625 +22559 -0.161651611328125 +22560 -0.5301513671875 +22561 -0.1162109375 +22562 -0.214691162109375 +22563 -0.05511474609375 +22564 0.137359619140625 +22565 0.013458251953125 +22566 0.474822998046875 +22567 0.079864501953125 +22568 0.76239013671875 +22569 0.137359619140625 +22570 0.867462158203125 +22571 0.180816650390625 +22572 0.870361328125 +22573 0.21014404296875 +22574 0.86480712890625 +22575 0.223052978515625 +22576 0.831817626953125 +22577 0.220458984375 +22578 0.677581787109375 +22579 0.20684814453125 +22580 0.495880126953125 +22581 0.18328857421875 +22582 0.30767822265625 +22583 0.153228759765625 +22584 0.116180419921875 +22585 0.117156982421875 +22586 -0.110748291015625 +22587 0.06939697265625 +22588 -0.381805419921875 +22589 0.0087890625 +22590 -0.6572265625 +22591 -0.05657958984375 +22592 -0.857421875 +22593 -0.115509033203125 +22594 -0.870391845703125 +22595 -0.159942626953125 +22596 -0.870391845703125 +22597 -0.188446044921875 +22598 -0.86444091796875 +22599 -0.205841064453125 +22600 -0.85723876953125 +22601 -0.21856689453125 +22602 -0.790008544921875 +22603 -0.223175048828125 +22604 -0.62847900390625 +22605 -0.20965576171875 +22606 -0.3956298828125 +22607 -0.177398681640625 +22608 -0.126708984375 +22609 -0.132476806640625 +22610 0.150115966796875 +22611 -0.079986572265625 +22612 0.424041748046875 +22613 -0.022186279296875 +22614 0.670623779296875 +22615 0.035858154296875 +22616 0.854522705078125 +22617 0.086883544921875 +22618 0.866485595703125 +22619 0.127471923828125 +22620 0.86920166015625 +22621 0.1546630859375 +22622 0.8653564453125 +22623 0.171630859375 +22624 0.857147216796875 +22625 0.180755615234375 +22626 0.766845703125 +22627 0.181396484375 +22628 0.628509521484375 +22629 0.174407958984375 +22630 0.462127685546875 +22631 0.15850830078125 +22632 0.297210693359375 +22633 0.138458251953125 +22634 0.14862060546875 +22635 0.11651611328125 +22636 -0.00537109375 +22637 0.08856201171875 +22638 -0.15753173828125 +22639 0.056060791015625 +22640 -0.31304931640625 +22641 0.0184326171875 +22642 -0.48876953125 +22643 -0.026763916015625 +22644 -0.6416015625 +22645 -0.07080078125 +22646 -0.751373291015625 +22647 -0.1090087890625 +22648 -0.84619140625 +22649 -0.1455078125 +22650 -0.861297607421875 +22651 -0.177520751953125 +22652 -0.863250732421875 +22653 -0.198822021484375 +22654 -0.856597900390625 +22655 -0.20355224609375 +22656 -0.7498779296875 +22657 -0.19390869140625 +22658 -0.624542236328125 +22659 -0.1805419921875 +22660 -0.47808837890625 +22661 -0.159423828125 +22662 -0.253387451171875 +22663 -0.11981201171875 +22664 0.003692626953125 +22665 -0.0701904296875 +22666 0.2257080078125 +22667 -0.023193359375 +22668 0.427154541015625 +22669 0.02337646484375 +22670 0.643218994140625 +22671 0.07537841796875 +22672 0.855926513671875 +22673 0.13092041015625 +22674 0.870361328125 +22675 0.17919921875 +22676 0.870361328125 +22677 0.211029052734375 +22678 0.862762451171875 +22679 0.227691650390625 +22680 0.79669189453125 +22681 0.22857666015625 +22682 0.595794677734375 +22683 0.2119140625 +22684 0.362152099609375 +22685 0.183074951171875 +22686 0.1270751953125 +22687 0.147216796875 +22688 -0.086944580078125 +22689 0.1082763671875 +22690 -0.2784423828125 +22691 0.066680908203125 +22692 -0.484832763671875 +22693 0.01611328125 +22694 -0.729583740234375 +22695 -0.046875 +22696 -0.86688232421875 +22697 -0.112884521484375 +22698 -0.870391845703125 +22699 -0.170166015625 +22700 -0.86859130859375 +22701 -0.21771240234375 +22702 -0.86279296875 +22703 -0.255035400390625 +22704 -0.817962646484375 +22705 -0.275482177734375 +22706 -0.6116943359375 +22707 -0.2706298828125 +22708 -0.3128662109375 +22709 -0.2391357421875 +22710 0.039398193359375 +22711 -0.18719482421875 +22712 0.422821044921875 +22713 -0.1185302734375 +22714 0.805145263671875 +22715 -0.039306640625 +22716 0.870361328125 +22717 0.037841796875 +22718 0.870361328125 +22719 0.102386474609375 +22720 0.860015869140625 +22721 0.152069091796875 +22722 0.727935791015625 +22723 0.1854248046875 +22724 0.48114013671875 +22725 0.2012939453125 +22726 0.2059326171875 +22727 0.204010009765625 +22728 -0.06103515625 +22729 0.197662353515625 +22730 -0.29913330078125 +22731 0.18402099609375 +22732 -0.516204833984375 +22733 0.16033935546875 +22734 -0.7252197265625 +22735 0.123779296875 +22736 -0.85980224609375 +22737 0.07891845703125 +22738 -0.870391845703125 +22739 0.032073974609375 +22740 -0.870391845703125 +22741 -0.011199951171875 +22742 -0.858062744140625 +22743 -0.041839599609375 +22744 -0.673004150390625 +22745 -0.0589599609375 +22746 -0.42694091796875 +22747 -0.0721435546875 +22748 -0.2100830078125 +22749 -0.089385986328125 +22750 -0.0362548828125 +22751 -0.110137939453125 +22752 0.10943603515625 +22753 -0.128875732421875 +22754 0.23516845703125 +22755 -0.14178466796875 +22756 0.373687744140625 +22757 -0.14117431640625 +22758 0.517791748046875 +22759 -0.127349853515625 +22760 0.602783203125 +22761 -0.11187744140625 +22762 0.635711669921875 +22763 -0.093780517578125 +22764 0.655181884765625 +22765 -0.066986083984375 +22766 0.65948486328125 +22767 -0.03338623046875 +22768 0.651275634765625 +22769 0.005401611328125 +22770 0.61846923828125 +22771 0.04473876953125 +22772 0.53753662109375 +22773 0.077667236328125 +22774 0.404144287109375 +22775 0.1007080078125 +22776 0.22186279296875 +22777 0.1119384765625 +22778 0.003997802734375 +22779 0.111480712890625 +22780 -0.22100830078125 +22781 0.1025390625 +22782 -0.42449951171875 +22783 0.088836669921875 +22784 -0.579833984375 +22785 0.073883056640625 +22786 -0.641876220703125 +22787 0.0648193359375 +22788 -0.6177978515625 +22789 0.06103515625 +22790 -0.575531005859375 +22791 0.05242919921875 +22792 -0.526336669921875 +22793 0.03802490234375 +22794 -0.42645263671875 +22795 0.025634765625 +22796 -0.2581787109375 +22797 0.01947021484375 +22798 -0.068695068359375 +22799 0.01409912109375 +22800 0.09222412109375 +22801 0.003875732421875 +22802 0.232147216796875 +22803 -0.008148193359375 +22804 0.3509521484375 +22805 -0.020172119140625 +22806 0.410064697265625 +22807 -0.036529541015625 +22808 0.372955322265625 +22809 -0.061492919921875 +22810 0.2554931640625 +22811 -0.091766357421875 +22812 0.10711669921875 +22813 -0.11932373046875 +22814 -0.052886962890625 +22815 -0.14111328125 +22816 -0.186279296875 +22817 -0.15167236328125 +22818 -0.23291015625 +22819 -0.142608642578125 +22820 -0.209442138671875 +22821 -0.11749267578125 +22822 -0.174163818359375 +22823 -0.086517333984375 +22824 -0.126739501953125 +22825 -0.051116943359375 +22826 -0.048126220703125 +22827 -0.010040283203125 +22828 0.0426025390625 +22829 0.032196044921875 +22830 0.10748291015625 +22831 0.06829833984375 +22832 0.1409912109375 +22833 0.096038818359375 +22834 0.19708251953125 +22835 0.122467041015625 +22836 0.273651123046875 +22837 0.146453857421875 +22838 0.31768798828125 +22839 0.159423828125 +22840 0.341094970703125 +22841 0.162994384765625 +22842 0.368011474609375 +22843 0.161041259765625 +22844 0.37249755859375 +22845 0.150115966796875 +22846 0.30072021484375 +22847 0.122833251953125 +22848 0.1517333984375 +22849 0.080078125 +22850 -0.01470947265625 +22851 0.032135009765625 +22852 -0.1883544921875 +22853 -0.01806640625 +22854 -0.372711181640625 +22855 -0.06976318359375 +22856 -0.51397705078125 +22857 -0.11346435546875 +22858 -0.57177734375 +22859 -0.14190673828125 +22860 -0.53948974609375 +22861 -0.153076171875 +22862 -0.43511962890625 +22863 -0.14892578125 +22864 -0.2962646484375 +22865 -0.1346435546875 +22866 -0.161102294921875 +22867 -0.115814208984375 +22868 -0.0435791015625 +22869 -0.094635009765625 +22870 0.060394287109375 +22871 -0.070770263671875 +22872 0.13665771484375 +22873 -0.046966552734375 +22874 0.170135498046875 +22875 -0.02630615234375 +22876 0.16552734375 +22877 -0.009033203125 +22878 0.15728759765625 +22879 0.009033203125 +22880 0.150787353515625 +22881 0.027618408203125 +22882 0.12200927734375 +22883 0.0419921875 +22884 0.080108642578125 +22885 0.05255126953125 +22886 0.05126953125 +22887 0.062408447265625 +22888 0.062896728515625 +22889 0.075042724609375 +22890 0.09271240234375 +22891 0.0865478515625 +22892 0.092987060546875 +22893 0.08941650390625 +22894 0.07855224609375 +22895 0.08587646484375 +22896 0.06427001953125 +22897 0.078338623046875 +22898 0.0347900390625 +22899 0.064910888671875 +22900 -0.01171875 +22901 0.0458984375 +22902 -0.056060791015625 +22903 0.02496337890625 +22904 -0.055511474609375 +22905 0.009429931640625 +22906 -0.010467529296875 +22907 0.0001220703125 +22908 0.02508544921875 +22909 -0.010223388671875 +22910 0.025665283203125 +22911 -0.024627685546875 +22912 0.017333984375 +22913 -0.038360595703125 +22914 0.00189208984375 +22915 -0.050567626953125 +22916 -0.03173828125 +22917 -0.062469482421875 +22918 -0.071502685546875 +22919 -0.071929931640625 +22920 -0.13543701171875 +22921 -0.08160400390625 +22922 -0.219970703125 +22923 -0.091064453125 +22924 -0.300506591796875 +22925 -0.096832275390625 +22926 -0.376312255859375 +22927 -0.0992431640625 +22928 -0.416107177734375 +22929 -0.094085693359375 +22930 -0.371124267578125 +22931 -0.074676513671875 +22932 -0.242279052734375 +22933 -0.0418701171875 +22934 -0.069732666015625 +22935 -0.00250244140625 +22936 0.125640869140625 +22937 0.039520263671875 +22938 0.31268310546875 +22939 0.07879638671875 +22940 0.45501708984375 +22941 0.109222412109375 +22942 0.554779052734375 +22943 0.130706787109375 +22944 0.61065673828125 +22945 0.142791748046875 +22946 0.610931396484375 +22947 0.14361572265625 +22948 0.531463623046875 +22949 0.1295166015625 +22950 0.3883056640625 +22951 0.103118896484375 +22952 0.23468017578125 +22953 0.0728759765625 +22954 0.095245361328125 +22955 0.042999267578125 +22956 -0.00396728515625 +22957 0.0179443359375 +22958 -0.04852294921875 +22959 0.000457763671875 +22960 -0.055145263671875 +22961 -0.0113525390625 +22962 -0.0758056640625 +22963 -0.024810791015625 +22964 -0.138702392578125 +22965 -0.04364013671875 +22966 -0.209197998046875 +22967 -0.062103271484375 +22968 -0.289031982421875 +22969 -0.080078125 +22970 -0.37884521484375 +22971 -0.097412109375 +22972 -0.456329345703125 +22973 -0.110565185546875 +22974 -0.51641845703125 +22975 -0.1187744140625 +22976 -0.519287109375 +22977 -0.1160888671875 +22978 -0.458251953125 +22979 -0.101715087890625 +22980 -0.384796142578125 +22981 -0.08380126953125 +22982 -0.323699951171875 +22983 -0.066558837890625 +22984 -0.269287109375 +22985 -0.049560546875 +22986 -0.1951904296875 +22987 -0.029296875 +22988 -0.100006103515625 +22989 -0.006072998046875 +22990 -0.01055908203125 +22991 0.0155029296875 +22992 0.1033935546875 +22993 0.039642333984375 +22994 0.24908447265625 +22995 0.067108154296875 +22996 0.373199462890625 +22997 0.08953857421875 +22998 0.45806884765625 +22999 0.104095458984375 +23000 0.511474609375 +23001 0.1119384765625 +23002 0.565399169921875 +23003 0.11798095703125 +23004 0.61138916015625 +23005 0.121124267578125 +23006 0.5897216796875 +23007 0.112548828125 +23008 0.4906005859375 +23009 0.091094970703125 +23010 0.33148193359375 +23011 0.059814453125 +23012 0.147796630859375 +23013 0.02447509765625 +23014 -0.01873779296875 +23015 -0.00811767578125 +23016 -0.140289306640625 +23017 -0.0333251953125 +23018 -0.191986083984375 +23019 -0.047027587890625 +23020 -0.184295654296875 +23021 -0.050537109375 +23022 -0.161834716796875 +23023 -0.0504150390625 +23024 -0.166595458984375 +23025 -0.05291748046875 +23026 -0.19390869140625 +23027 -0.057281494140625 +23028 -0.22442626953125 +23029 -0.060577392578125 +23030 -0.279754638671875 +23031 -0.066192626953125 +23032 -0.3389892578125 +23033 -0.0711669921875 +23034 -0.3543701171875 +23035 -0.068511962890625 +23036 -0.348175048828125 +23037 -0.0618896484375 +23038 -0.32598876953125 +23039 -0.052459716796875 +23040 -0.2581787109375 +23041 -0.036102294921875 +23042 -0.139801025390625 +23043 -0.01239013671875 +23044 0.014617919921875 +23045 0.016082763671875 +23046 0.144378662109375 +23047 0.0399169921875 +23048 0.221038818359375 +23049 0.05462646484375 +23050 0.27069091796875 +23051 0.063995361328125 +23052 0.294036865234375 +23053 0.068084716796875 +23054 0.311767578125 +23055 0.07000732421875 +23056 0.339141845703125 +23057 0.072021484375 +23058 0.360260009765625 +23059 0.071533203125 +23060 0.360504150390625 +23061 0.066680908203125 +23062 0.308380126953125 +23063 0.054107666015625 +23064 0.18170166015625 +23065 0.03167724609375 +23066 0.0047607421875 +23067 0.0028076171875 +23068 -0.17559814453125 +23069 -0.0263671875 +23070 -0.3143310546875 +23071 -0.04998779296875 +23072 -0.36785888671875 +23073 -0.062469482421875 +23074 -0.36248779296875 +23075 -0.066650390625 +23076 -0.343536376953125 +23077 -0.067718505859375 +23078 -0.3018798828125 +23079 -0.064453125 +23080 -0.231414794921875 +23081 -0.05609130859375 +23082 -0.117645263671875 +23083 -0.040924072265625 +23084 0.007049560546875 +23085 -0.02301025390625 +23086 0.087982177734375 +23087 -0.009063720703125 +23088 0.13946533203125 +23089 0.0023193359375 +23090 0.17425537109375 +23091 0.012359619140625 +23092 0.188201904296875 +23093 0.02020263671875 +23094 0.171234130859375 +23095 0.0242919921875 +23096 0.118438720703125 +23097 0.023712158203125 +23098 0.05706787109375 +23099 0.021453857421875 +23100 -0.010711669921875 +23101 0.017486572265625 +23102 -0.0914306640625 +23103 0.010833740234375 +23104 -0.162322998046875 +23105 0.00408935546875 +23106 -0.194549560546875 +23107 0.000640869140625 +23108 -0.1492919921875 +23109 0.00518798828125 +23110 -0.02166748046875 +23111 0.01837158203125 +23112 0.124053955078125 +23113 0.032623291015625 +23114 0.211151123046875 +23115 0.0389404296875 +23116 0.240447998046875 +23117 0.03765869140625 +23118 0.242218017578125 +23119 0.03271484375 +23120 0.2257080078125 +23121 0.025543212890625 +23122 0.194366455078125 +23123 0.016815185546875 +23124 0.115509033203125 +23125 0.00286865234375 +23126 0.0128173828125 +23127 -0.013153076171875 +23128 -0.053802490234375 +23129 -0.023895263671875 +23130 -0.110626220703125 +23131 -0.03240966796875 +23132 -0.199493408203125 +23133 -0.043670654296875 +23134 -0.29437255859375 +23135 -0.054534912109375 +23136 -0.33221435546875 +23137 -0.0574951171875 +23138 -0.27972412109375 +23139 -0.048675537109375 +23140 -0.185333251953125 +23141 -0.034088134765625 +23142 -0.128204345703125 +23143 -0.023406982421875 +23144 -0.115692138671875 +23145 -0.017730712890625 +23146 -0.116455078125 +23147 -0.013519287109375 +23148 -0.105926513671875 +23149 -0.008056640625 +23150 -0.053955078125 +23151 0.001983642578125 +23152 0.048797607421875 +23153 0.017547607421875 +23154 0.157318115234375 +23155 0.0330810546875 +23156 0.212005615234375 +23157 0.041290283203125 +23158 0.218475341796875 +23159 0.042816162109375 +23160 0.23724365234375 +23161 0.044891357421875 +23162 0.30535888671875 +23163 0.052001953125 +23164 0.38128662109375 +23165 0.059234619140625 +23166 0.404449462890625 +23167 0.059417724609375 +23168 0.3944091796875 +23169 0.055084228515625 +23170 0.3885498046875 +23171 0.050933837890625 +23172 0.362640380859375 +23173 0.04425048828125 +23174 0.27362060546875 +23175 0.030059814453125 +23176 0.11712646484375 +23177 0.008026123046875 +23178 -0.054901123046875 +23179 -0.015411376953125 +23180 -0.19085693359375 +23181 -0.033935546875 +23182 -0.28570556640625 +23183 -0.046844482421875 +23184 -0.339263916015625 +23185 -0.054046630859375 +23186 -0.3775634765625 +23187 -0.058624267578125 +23188 -0.445709228515625 +23189 -0.066009521484375 +23190 -0.535064697265625 +23191 -0.07525634765625 +23192 -0.629058837890625 +23193 -0.08447265625 +23194 -0.697601318359375 +23195 -0.09014892578125 +23196 -0.70391845703125 +23197 -0.088043212890625 +23198 -0.6424560546875 +23199 -0.077667236328125 +23200 -0.491241455078125 +23201 -0.056549072265625 +23202 -0.265716552734375 +23203 -0.026702880859375 +23204 -0.023712158203125 +23205 0.0047607421875 +23206 0.201751708984375 +23207 0.03375244140625 +23208 0.375823974609375 +23209 0.05596923828125 +23210 0.485076904296875 +23211 0.069793701171875 +23212 0.56884765625 +23213 0.07989501953125 +23214 0.634765625 +23215 0.08721923828125 +23216 0.63763427734375 +23217 0.086395263671875 +23218 0.5660400390625 +23219 0.07611083984375 +23220 0.4720458984375 +23221 0.062744140625 +23222 0.40692138671875 +23223 0.052581787109375 +23224 0.3778076171875 +23225 0.046600341796875 +23226 0.376953125 +23227 0.04400634765625 +23228 0.371978759765625 +23229 0.041046142578125 +23230 0.313140869140625 +23231 0.0318603515625 +23232 0.184417724609375 +23233 0.0146484375 +23234 0.011199951171875 +23235 -0.0074462890625 +23236 -0.171051025390625 +23237 -0.030029296875 +23238 -0.33740234375 +23239 -0.05010986328125 +23240 -0.47198486328125 +23241 -0.065826416015625 +23242 -0.560394287109375 +23243 -0.075469970703125 +23244 -0.58056640625 +23245 -0.07647705078125 +23246 -0.54754638671875 +23247 -0.07073974609375 +23248 -0.508575439453125 +23249 -0.064056396484375 +23250 -0.459503173828125 +23251 -0.0560302734375 +23252 -0.394378662109375 +23253 -0.04608154296875 +23254 -0.35260009765625 +23255 -0.03900146484375 +23256 -0.31170654296875 +23257 -0.0322265625 +23258 -0.197418212890625 +23259 -0.016937255859375 +23260 -0.007965087890625 +23261 0.006927490234375 +23262 0.207489013671875 +23263 0.033416748046875 +23264 0.409210205078125 +23265 0.057769775390625 +23266 0.57208251953125 +23267 0.07696533203125 +23268 0.66595458984375 +23269 0.087432861328125 +23270 0.65875244140625 +23271 0.08538818359375 +23272 0.56744384765625 +23273 0.072967529296875 +23274 0.431396484375 +23275 0.054962158203125 +23276 0.29443359375 +23277 0.0367431640625 +23278 0.182464599609375 +23279 0.021484375 +23280 0.06365966796875 +23281 0.005462646484375 +23282 -0.075958251953125 +23283 -0.012847900390625 +23284 -0.189422607421875 +23285 -0.027740478515625 +23286 -0.271942138671875 +23287 -0.038543701171875 +23288 -0.342529296875 +23289 -0.047515869140625 +23290 -0.364166259765625 +23291 -0.05023193359375 +23292 -0.327239990234375 +23293 -0.045562744140625 +23294 -0.2769775390625 +23295 -0.0389404296875 +23296 -0.253692626953125 +23297 -0.03497314453125 +23298 -0.24365234375 +23299 -0.03228759765625 +23300 -0.1983642578125 +23301 -0.0262451171875 +23302 -0.116241455078125 +23303 -0.016693115234375 +23304 -0.036834716796875 +23305 -0.00714111328125 +23306 0.034881591796875 +23307 0.00189208984375 +23308 0.09124755859375 +23309 0.009613037109375 +23310 0.10888671875 +23311 0.01385498046875 +23312 0.125518798828125 +23313 0.017791748046875 +23314 0.15771484375 +23315 0.02276611328125 +23316 0.17828369140625 +23317 0.026275634765625 +23318 0.17108154296875 +23319 0.02679443359375 +23320 0.129974365234375 +23321 0.023712158203125 +23322 0.082427978515625 +23323 0.019439697265625 +23324 0.027679443359375 +23325 0.013916015625 +23326 -0.065643310546875 +23327 0.00445556640625 +23328 -0.15936279296875 +23329 -0.005523681640625 +23330 -0.21307373046875 +23331 -0.012359619140625 +23332 -0.234649658203125 +23333 -0.016632080078125 +23334 -0.2001953125 +23335 -0.016082763671875 +23336 -0.119171142578125 +23337 -0.011444091796875 +23338 -0.024749755859375 +23339 -0.0054931640625 +23340 0.085784912109375 +23341 0.00213623046875 +23342 0.178131103515625 +23343 0.00848388671875 +23344 0.215576171875 +23345 0.010406494140625 +23346 0.211456298828125 +23347 0.0091552734375 +23348 0.17523193359375 +23349 0.005645751953125 +23350 0.128753662109375 +23351 0.00177001953125 +23352 0.1019287109375 +23353 0.000152587890625 +23354 0.0743408203125 +23355 -0.00103759765625 +23356 0.04327392578125 +23357 -0.00213623046875 +23358 0.038177490234375 +23359 -0.000640869140625 +23360 0.076263427734375 +23361 0.00482177734375 +23362 0.14105224609375 +23363 0.012664794921875 +23364 0.186431884765625 +23365 0.018707275390625 +23366 0.188812255859375 +23367 0.020782470703125 +23368 0.1390380859375 +23369 0.017974853515625 +23370 0.041778564453125 +23371 0.010650634765625 +23372 -0.079437255859375 +23373 0.00079345703125 +23374 -0.219390869140625 +23375 -0.011138916015625 +23376 -0.367828369140625 +23377 -0.024200439453125 +23378 -0.494873046875 +23379 -0.0357666015625 +23380 -0.556243896484375 +23381 -0.04193115234375 +23382 -0.508697509765625 +23383 -0.038848876953125 +23384 -0.3756103515625 +23385 -0.02850341796875 +23386 -0.218902587890625 +23387 -0.016265869140625 +23388 -0.063751220703125 +23389 -0.0042724609375 +23390 0.091552734375 +23391 0.007659912109375 +23392 0.23602294921875 +23393 0.018707275390625 +23394 0.342987060546875 +23395 0.026611328125 +23396 0.39520263671875 +23397 0.029937744140625 +23398 0.389373779296875 +23399 0.0284423828125 +23400 0.324249267578125 +23401 0.0220947265625 +23402 0.224090576171875 +23403 0.0130615234375 +23404 0.124267578125 +23405 0.004425048828125 +23406 0.037078857421875 +23407 -0.002716064453125 +23408 -0.010101318359375 +23409 -0.0059814453125 +23410 -0.019439697265625 +23411 -0.005645751953125 +23412 -0.022796630859375 +23413 -0.00457763671875 +23414 -0.001556396484375 +23415 -0.001220703125 +23416 0.056304931640625 +23417 0.005340576171875 +23418 0.106719970703125 +23419 0.01116943359375 +23420 0.096893310546875 +23421 0.011566162109375 +23422 0.042694091796875 +23423 0.007843017578125 +23424 -0.018035888671875 +23425 0.0032958984375 +23426 -0.07586669921875 +23427 -0.00128173828125 +23428 -0.11944580078125 +23429 -0.0048828125 +23430 -0.15972900390625 +23431 -0.00848388671875 +23432 -0.202606201171875 +23433 -0.0125732421875 +23434 -0.24859619140625 +23435 -0.01715087890625 +23436 -0.30517578125 +23437 -0.022857666015625 +23438 -0.36212158203125 +23439 -0.02874755859375 +23440 -0.39141845703125 +23441 -0.032318115234375 +23442 -0.35528564453125 +23443 -0.030181884765625 +23444 -0.249969482421875 +23445 -0.021942138671875 +23446 -0.092864990234375 +23447 -0.00909423828125 +23448 0.08905029296875 +23449 0.006011962890625 +23450 0.2352294921875 +23451 0.01806640625 +23452 0.318817138671875 +23453 0.0247802734375 +23454 0.358642578125 +23455 0.02783203125 +23456 0.347747802734375 +23457 0.026641845703125 +23458 0.28564453125 +23459 0.021148681640625 +23460 0.223175048828125 +23461 0.01580810546875 +23462 0.196746826171875 +23463 0.013824462890625 +23464 0.179840087890625 +23465 0.01287841796875 +23466 0.155548095703125 +23467 0.011444091796875 +23468 0.151214599609375 +23469 0.011871337890625 +23470 0.156951904296875 +23471 0.01324462890625 +23472 0.13177490234375 +23473 0.01190185546875 +23474 0.100799560546875 +23475 0.010009765625 +23476 0.087127685546875 +23477 0.009552001953125 +23478 0.05487060546875 +23479 0.007354736328125 +23480 -0.009002685546875 +23481 0.002227783203125 +23482 -0.10400390625 +23483 -0.005767822265625 +23484 -0.229400634765625 +23485 -0.0166015625 +23486 -0.35552978515625 +23487 -0.027679443359375 +23488 -0.441925048828125 +23489 -0.035430908203125 +23490 -0.473846435546875 +23491 -0.03857421875 +23492 -0.464813232421875 +23493 -0.038238525390625 +23494 -0.419097900390625 +23495 -0.0347900390625 +23496 -0.334320068359375 +23497 -0.027984619140625 +23498 -0.227935791015625 +23499 -0.019317626953125 +23500 -0.12347412109375 +23501 -0.01080322265625 +23502 -0.02764892578125 +23503 -0.003021240234375 +23504 0.077667236328125 +23505 0.005645751953125 +23506 0.2132568359375 +23507 0.017059326171875 +23508 0.38885498046875 +23509 0.0321044921875 +23510 0.582794189453125 +23511 0.04888916015625 +23512 0.734039306640625 +23513 0.062042236328125 +23514 0.800140380859375 +23515 0.06781005859375 +23516 0.7783203125 +23517 0.06597900390625 +23518 0.6651611328125 +23519 0.056243896484375 +23520 0.45965576171875 +23521 0.03851318359375 +23522 0.199188232421875 +23523 0.016082763671875 +23524 -0.050689697265625 +23525 -0.00531005859375 +23526 -0.23297119140625 +23527 -0.02069091796875 +23528 -0.33013916015625 +23529 -0.028564453125 +23530 -0.368408203125 +23531 -0.031280517578125 +23532 -0.378936767578125 +23533 -0.031585693359375 +23534 -0.376983642578125 +23535 -0.030914306640625 +23536 -0.37969970703125 +23537 -0.03076171875 +23538 -0.391510009765625 +23539 -0.03155517578125 +23540 -0.385345458984375 +23541 -0.030914306640625 +23542 -0.3419189453125 +23543 -0.02716064453125 +23544 -0.28289794921875 +23545 -0.02215576171875 +23546 -0.251617431640625 +23547 -0.01971435546875 +23548 -0.266143798828125 +23549 -0.021392822265625 +23550 -0.273345947265625 +23551 -0.02252197265625 +23552 -0.216796875 +23553 -0.018218994140625 +23554 -0.128265380859375 +23555 -0.010986328125 +23556 -0.068145751953125 +23557 -0.005096435546875 +23558 -0.0430908203125 +23559 -0.0010986328125 +23560 -0.024444580078125 +23561 0.002471923828125 +23562 0.020721435546875 +23563 0.007293701171875 +23564 0.124481201171875 +23565 0.0150146484375 +23566 0.25787353515625 +23567 0.023895263671875 +23568 0.379119873046875 +23569 0.03155517578125 +23570 0.47991943359375 +23571 0.0374755859375 +23572 0.5281982421875 +23573 0.039886474609375 +23574 0.511138916015625 +23575 0.0380859375 +23576 0.456207275390625 +23577 0.033660888671875 +23578 0.407470703125 +23579 0.0291748046875 +23580 0.383758544921875 +23581 0.025787353515625 +23582 0.35687255859375 +23583 0.022003173828125 +23584 0.31182861328125 +23585 0.01715087890625 +23586 0.250885009765625 +23587 0.011474609375 +23588 0.1654052734375 +23589 0.004638671875 +23590 0.035247802734375 +23591 -0.004364013671875 +23592 -0.142059326171875 +23593 -0.01556396484375 +23594 -0.33563232421875 +23595 -0.027191162109375 +23596 -0.5345458984375 +23597 -0.038604736328125 +23598 -0.72186279296875 +23599 -0.048828125 +23600 -0.836669921875 +23601 -0.054473876953125 +23602 -0.8326416015625 +23603 -0.05303955078125 +23604 -0.7296142578125 +23605 -0.045684814453125 +23606 -0.582550048828125 +23607 -0.03564453125 +23608 -0.440093994140625 +23609 -0.025726318359375 +23610 -0.324310302734375 +23611 -0.017303466796875 +23612 -0.20147705078125 +23613 -0.008544921875 +23614 -0.044647216796875 +23615 0.001922607421875 +23616 0.103973388671875 +23617 0.01165771484375 +23618 0.202392578125 +23619 0.018218994140625 +23620 0.264495849609375 +23621 0.022308349609375 +23622 0.338897705078125 +23623 0.02667236328125 +23624 0.443817138671875 +23625 0.032318115234375 +23626 0.545074462890625 +23627 0.037353515625 +23628 0.6173095703125 +23629 0.0404052734375 +23630 0.6524658203125 +23631 0.04107666015625 +23632 0.66339111328125 +23633 0.0401611328125 +23634 0.6561279296875 +23635 0.038116455078125 +23636 0.606781005859375 +23637 0.033660888671875 +23638 0.501190185546875 +23639 0.026092529296875 +23640 0.352783203125 +23641 0.01629638671875 +23642 0.176544189453125 +23643 0.005157470703125 +23644 -0.034820556640625 +23645 -0.00762939453125 +23646 -0.258209228515625 +23647 -0.020660400390625 +23648 -0.44244384765625 +23649 -0.031097412109375 +23650 -0.5753173828125 +23651 -0.03826904296875 +23652 -0.65203857421875 +23653 -0.04193115234375 +23654 -0.641632080078125 +23655 -0.0404052734375 +23656 -0.562164306640625 +23657 -0.0347900390625 +23658 -0.458038330078125 +23659 -0.02764892578125 +23660 -0.350555419921875 +23661 -0.020233154296875 +23662 -0.260528564453125 +23663 -0.013763427734375 +23664 -0.192108154296875 +23665 -0.008575439453125 +23666 -0.141937255859375 +23667 -0.0045166015625 +23668 -0.1021728515625 +23669 -0.001251220703125 +23670 -0.062896728515625 +23671 0.001708984375 +23672 -0.011932373046875 +23673 0.005035400390625 +23674 0.062835693359375 +23675 0.0093994140625 +23676 0.148712158203125 +23677 0.0140380859375 +23678 0.241729736328125 +23679 0.018768310546875 +23680 0.34912109375 +23681 0.024017333984375 +23682 0.457305908203125 +23683 0.02911376953125 +23684 0.54388427734375 +23685 0.0328369140625 +23686 0.5728759765625 +23687 0.033233642578125 +23688 0.506591796875 +23689 0.028289794921875 +23690 0.351226806640625 +23691 0.018402099609375 +23692 0.146514892578125 +23693 0.005859375 +23694 -0.05523681640625 +23695 -0.00634765625 +23696 -0.21624755859375 +23697 -0.01605224609375 +23698 -0.334930419921875 +23699 -0.02313232421875 +23700 -0.402984619140625 +23701 -0.027099609375 +23702 -0.4412841796875 +23703 -0.029083251953125 +23704 -0.49578857421875 +23705 -0.031707763671875 +23706 -0.5601806640625 +23707 -0.03466796875 +23708 -0.600738525390625 +23709 -0.036102294921875 +23710 -0.584228515625 +23711 -0.034210205078125 +23712 -0.47930908203125 +23713 -0.027313232421875 +23714 -0.27935791015625 +23715 -0.01507568359375 +23716 -0.0089111328125 +23717 0.00103759765625 +23718 0.268798828125 +23719 0.017425537109375 +23720 0.482818603515625 +23721 0.03009033203125 +23722 0.60369873046875 +23723 0.037353515625 +23724 0.650421142578125 +23725 0.04022216796875 +23726 0.66400146484375 +23727 0.041015625 +23728 0.6414794921875 +23729 0.039581298828125 +23730 0.572540283203125 +23731 0.03533935546875 +23732 0.498138427734375 +23733 0.0306396484375 +23734 0.439453125 +23735 0.026702880859375 +23736 0.375518798828125 +23737 0.022369384765625 +23738 0.274505615234375 +23739 0.01593017578125 +23740 0.1087646484375 +23741 0.005859375 +23742 -0.099395751953125 +23743 -0.00653076171875 +23744 -0.3182373046875 +23745 -0.0194091796875 +23746 -0.5489501953125 +23747 -0.032806396484375 +23748 -0.7738037109375 +23749 -0.045684814453125 +23750 -0.86383056640625 +23751 -0.055084228515625 +23752 -0.870391845703125 +23753 -0.059173583984375 +23754 -0.86895751953125 +23755 -0.058929443359375 +23756 -0.861053466796875 +23757 -0.05511474609375 +23758 -0.765869140625 +23759 -0.046783447265625 +23760 -0.5301513671875 +23761 -0.033355712890625 +23762 -0.214691162109375 +23763 -0.0152587890625 +23764 0.137359619140625 +23765 0.005035400390625 +23766 0.474822998046875 +23767 0.024658203125 +23768 0.76239013671875 +23769 0.04156494140625 +23770 0.867462158203125 +23771 0.05419921875 +23772 0.870361328125 +23773 0.062591552734375 +23774 0.86480712890625 +23775 0.066070556640625 +23776 0.831817626953125 +23777 0.06494140625 +23778 0.677581787109375 +23779 0.060577392578125 +23780 0.495880126953125 +23781 0.053314208984375 +23782 0.30767822265625 +23783 0.044219970703125 +23784 0.116180419921875 +23785 0.033447265625 +23786 -0.110748291015625 +23787 0.01922607421875 +23788 -0.381805419921875 +23789 0.001190185546875 +23790 -0.6572265625 +23791 -0.0181884765625 +23792 -0.857421875 +23793 -0.0355224609375 +23794 -0.870391845703125 +23795 -0.04840087890625 +23796 -0.870391845703125 +23797 -0.056427001953125 +23798 -0.86444091796875 +23799 -0.061126708984375 +23800 -0.85723876953125 +23801 -0.064483642578125 +23802 -0.790008544921875 +23803 -0.065460205078125 +23804 -0.62847900390625 +23805 -0.061065673828125 +23806 -0.3956298828125 +23807 -0.05108642578125 +23808 -0.126708984375 +23809 -0.037445068359375 +23810 0.150115966796875 +23811 -0.02166748046875 +23812 0.424041748046875 +23813 -0.0047607421875 +23814 0.670623779296875 +23815 0.011962890625 +23816 0.854522705078125 +23817 0.0269775390625 +23818 0.866485595703125 +23819 0.03936767578125 +23820 0.86920166015625 +23821 0.04840087890625 +23822 0.8653564453125 +23823 0.054229736328125 +23824 0.857147216796875 +23825 0.05706787109375 +23826 0.766845703125 +23827 0.056793212890625 +23828 0.628509521484375 +23829 0.05364990234375 +23830 0.462127685546875 +23831 0.047637939453125 +23832 0.297210693359375 +23833 0.039642333984375 +23834 0.14862060546875 +23835 0.03033447265625 +23836 -0.00537109375 +23837 0.01959228515625 +23838 -0.15753173828125 +23839 0.00799560546875 +23840 -0.31304931640625 +23841 -0.004058837890625 +23842 -0.48876953125 +23843 -0.016510009765625 +23844 -0.6416015625 +23845 -0.02789306640625 +23846 -0.751373291015625 +23847 -0.03729248046875 +23848 -0.84619140625 +23849 -0.0450439453125 +23850 -0.861297607421875 +23851 -0.0506591796875 +23852 -0.863250732421875 +23853 -0.053314208984375 +23854 -0.856597900390625 +23855 -0.052276611328125 +23856 -0.7498779296875 +23857 -0.047943115234375 +23858 -0.624542236328125 +23859 -0.04193115234375 +23860 -0.47808837890625 +23861 -0.034027099609375 +23862 -0.253387451171875 +23863 -0.023101806640625 +23864 0.003692626953125 +23865 -0.0106201171875 +23866 0.2257080078125 +23867 0.00140380859375 +23868 0.427154541015625 +23869 0.012939453125 +23870 0.643218994140625 +23871 0.02447509765625 +23872 0.855926513671875 +23873 0.035491943359375 +23874 0.870361328125 +23875 0.04443359375 +23876 0.870361328125 +23877 0.050018310546875 +23878 0.862762451171875 +23879 0.0523681640625 +23880 0.79669189453125 +23881 0.05145263671875 +23882 0.595794677734375 +23883 0.047119140625 +23884 0.362152099609375 +23885 0.040191650390625 +23886 0.1270751953125 +23887 0.031524658203125 +23888 -0.086944580078125 +23889 0.021881103515625 +23890 -0.2784423828125 +23891 0.011627197265625 +23892 -0.484832763671875 +23893 0.000213623046875 +23894 -0.729583740234375 +23895 -0.012542724609375 +23896 -0.86688232421875 +23897 -0.02520751953125 +23898 -0.870391845703125 +23899 -0.0360107421875 +23900 -0.86859130859375 +23901 -0.04461669921875 +23902 -0.86279296875 +23903 -0.0509033203125 +23904 -0.817962646484375 +23905 -0.053955078125 +23906 -0.6116943359375 +23907 -0.05267333984375 +23908 -0.3128662109375 +23909 -0.0469970703125 +23910 0.039398193359375 +23911 -0.037811279296875 +23912 0.422821044921875 +23913 -0.0257568359375 +23914 0.805145263671875 +23915 -0.0118408203125 +23916 0.870361328125 +23917 0.002044677734375 +23918 0.870361328125 +23919 0.014312744140625 +23920 0.860015869140625 +23921 0.02447509765625 +23922 0.727935791015625 +23923 0.03216552734375 +23924 0.48114013671875 +23925 0.03704833984375 +23926 0.2059326171875 +23927 0.039520263671875 +23928 -0.06103515625 +23929 0.0400390625 +23930 -0.29913330078125 +23931 0.038818359375 +23932 -0.516204833984375 +23933 0.03546142578125 +23934 -0.7252197265625 +23935 0.0296630859375 +23936 -0.85980224609375 +23937 0.0220947265625 +23938 -0.870391845703125 +23939 0.013702392578125 +23940 -0.870391845703125 +23941 0.005340576171875 +23942 -0.858062744140625 +23943 -0.00164794921875 +23944 -0.673004150390625 +23945 -0.006988525390625 +23946 -0.42694091796875 +23947 -0.011749267578125 +23948 -0.2100830078125 +23949 -0.01678466796875 +23950 -0.0362548828125 +23951 -0.021881103515625 +23952 0.10943603515625 +23953 -0.0262451171875 +23954 0.23516845703125 +23955 -0.02923583984375 +23956 0.373687744140625 +23957 -0.029815673828125 +23958 0.517791748046875 +23959 -0.02801513671875 +23960 0.602783203125 +23961 -0.02532958984375 +23962 0.635711669921875 +23963 -0.021697998046875 +23964 0.655181884765625 +23965 -0.01641845703125 +23966 0.65948486328125 +23967 -0.009857177734375 +23968 0.651275634765625 +23969 -0.00238037109375 +23970 0.61846923828125 +23971 0.005218505859375 +23972 0.53753662109375 +23973 0.011932373046875 +23974 0.404144287109375 +23975 0.017181396484375 +23976 0.22186279296875 +23977 0.020599365234375 +23978 0.003997802734375 +23979 0.02215576171875 +23980 -0.22100830078125 +23981 0.02215576171875 +23982 -0.42449951171875 +23983 0.021026611328125 +23984 -0.579833984375 +23985 0.019256591796875 +23986 -0.641876220703125 +23987 0.01788330078125 +23988 -0.6177978515625 +23989 0.016754150390625 +23990 -0.575531005859375 +23991 0.014373779296875 +23992 -0.526336669921875 +23993 0.010711669921875 +23994 -0.42645263671875 +23995 0.007110595703125 +23996 -0.2581787109375 +23997 0.004364013671875 +23998 -0.068695068359375 +23999 0.001739501953125 +24000 0.09222412109375 +24001 -0.00152587890625 +24002 0.232147216796875 +24003 -0.004852294921875 +24004 0.3509521484375 +24005 -0.007904052734375 +24006 0.410064697265625 +24007 -0.01129150390625 +24008 0.372955322265625 +24009 -0.015655517578125 +24010 0.2554931640625 +24011 -0.020477294921875 +24012 0.10711669921875 +24013 -0.02447509765625 +24014 -0.052886962890625 +24015 -0.027191162109375 +24016 -0.186279296875 +24017 -0.02783203125 +24018 -0.23291015625 +24019 -0.025146484375 +24020 -0.209442138671875 +24021 -0.019805908203125 +24022 -0.174163818359375 +24023 -0.01348876953125 +24024 -0.126739501953125 +24025 -0.006500244140625 +24026 -0.048126220703125 +24027 0.001220703125 +24028 0.0426025390625 +24029 0.0089111328125 +24030 0.10748291015625 +24031 0.015380859375 +24032 0.1409912109375 +24033 0.020233154296875 +24034 0.19708251953125 +24035 0.02459716796875 +24036 0.273651123046875 +24037 0.02825927734375 +24038 0.31768798828125 +24039 0.029876708984375 +24040 0.341094970703125 +24041 0.029754638671875 +24042 0.368011474609375 +24043 0.028564453125 +24044 0.37249755859375 +24045 0.02581787109375 +24046 0.30072021484375 +24047 0.020416259765625 +24048 0.1517333984375 +24049 0.0125732421875 +24050 -0.01470947265625 +24051 0.003936767578125 +24052 -0.1883544921875 +24053 -0.00494384765625 +24054 -0.372711181640625 +24055 -0.013885498046875 +24056 -0.51397705078125 +24057 -0.0213623046875 +24058 -0.57177734375 +24059 -0.02618408203125 +24060 -0.53948974609375 +24061 -0.028045654296875 +24062 -0.43511962890625 +24063 -0.027252197265625 +24064 -0.2962646484375 +24065 -0.024932861328125 +24066 -0.161102294921875 +24067 -0.0220947265625 +24068 -0.0435791015625 +24069 -0.0189208984375 +24070 0.060394287109375 +24071 -0.01531982421875 +24072 0.13665771484375 +24073 -0.01129150390625 +24074 0.170135498046875 +24075 -0.006866455078125 +24076 0.16552734375 +24077 -0.002197265625 +24078 0.15728759765625 +24079 0.002471923828125 +24080 0.150787353515625 +24081 0.0069580078125 +24082 0.12200927734375 +24083 0.01104736328125 +24084 0.080108642578125 +24085 0.014556884765625 +24086 0.05126953125 +24087 0.017303466796875 +24088 0.062896728515625 +24089 0.019134521484375 +24090 0.09271240234375 +24091 0.019989013671875 +24092 0.092987060546875 +24093 0.019805908203125 +24094 0.07855224609375 +24095 0.01861572265625 +24096 0.06427001953125 +24097 0.0164794921875 +24098 0.0347900390625 +24099 0.01348876953125 +24100 -0.01171875 +24101 0.009857177734375 +24102 -0.056060791015625 +24103 0.00579833984375 +24104 -0.055511474609375 +24105 0.001495361328125 +24106 -0.010467529296875 +24107 -0.00274658203125 +24108 0.02508544921875 +24109 -0.006683349609375 +24110 0.025665283203125 +24111 -0.010101318359375 +24112 0.017333984375 +24113 -0.012847900390625 +24114 0.00189208984375 +24115 -0.0147705078125 +24116 -0.03173828125 +24117 -0.01580810546875 +24118 -0.071502685546875 +24119 -0.01593017578125 +24120 -0.13543701171875 +24121 -0.01513671875 +24122 -0.219970703125 +24123 -0.013519287109375 +24124 -0.300506591796875 +24125 -0.01116943359375 +24126 -0.376312255859375 +24127 -0.00823974609375 +24128 -0.416107177734375 +24129 -0.004913330078125 +24130 -0.371124267578125 +24131 -0.001373291015625 +24132 -0.242279052734375 +24133 0.00213623046875 +24134 -0.069732666015625 +24135 0.00543212890625 +24136 0.125640869140625 +24137 0.008331298828125 +24138 0.31268310546875 +24139 0.01068115234375 +24140 0.45501708984375 +24141 0.01239013671875 +24142 0.554779052734375 +24143 0.01336669921875 +24144 0.61065673828125 +24145 0.013580322265625 +24146 0.610931396484375 +24147 0.0130615234375 +24148 0.531463623046875 +24149 0.0118408203125 +24150 0.3883056640625 +24151 0.010009765625 +24152 0.23468017578125 +24153 0.0076904296875 +24154 0.095245361328125 +24155 0.0050048828125 +24156 -0.00396728515625 +24157 0.00213623046875 +24158 -0.04852294921875 +24159 -0.000732421875 +24160 -0.055145263671875 +24161 -0.003448486328125 +24162 -0.0758056640625 +24163 -0.005859375 +24164 -0.138702392578125 +24165 -0.007843017578125 +24166 -0.209197998046875 +24167 -0.009307861328125 +24168 -0.289031982421875 +24169 -0.01019287109375 +24170 -0.37884521484375 +24171 -0.010467529296875 +24172 -0.456329345703125 +24173 -0.0101318359375 +24174 -0.51641845703125 +24175 -0.00921630859375 +24176 -0.519287109375 +24177 -0.007781982421875 +24178 -0.458251953125 +24179 -0.00592041015625 +24180 -0.384796142578125 +24181 -0.003753662109375 +24182 -0.323699951171875 +24183 -0.00140380859375 +24184 -0.269287109375 +24185 0.000946044921875 +24186 -0.1951904296875 +24187 0.003173828125 +24188 -0.100006103515625 +24189 0.005157470703125 +24190 -0.01055908203125 +24191 0.006805419921875 +24192 0.1033935546875 +24193 0.008026123046875 +24194 0.24908447265625 +24195 0.0087890625 +24196 0.373199462890625 +24197 0.009063720703125 +24198 0.45806884765625 +24199 0.00885009765625 +24200 0.511474609375 +24201 0.008148193359375 +24202 0.565399169921875 +24203 0.00701904296875 +24204 0.61138916015625 +24205 0.00555419921875 +24206 0.5897216796875 +24207 0.003814697265625 +24208 0.4906005859375 +24209 0.001922607421875 +24210 0.33148193359375 +24211 0.0 +24212 0.147796630859375 +24213 -0.0018310546875 +24214 -0.01873779296875 +24215 -0.00347900390625 +24216 -0.140289306640625 +24217 -0.004852294921875 +24218 -0.191986083984375 +24219 -0.005889892578125 +24220 -0.184295654296875 +24221 -0.006561279296875 +24222 -0.161834716796875 +24223 -0.0068359375 +24224 -0.166595458984375 +24225 -0.0067138671875 +24226 -0.19390869140625 +24227 -0.006195068359375 +24228 -0.22442626953125 +24229 -0.00531005859375 +24230 -0.279754638671875 +24231 -0.004119873046875 +24232 -0.3389892578125 +24233 -0.002716064453125 +24234 -0.3543701171875 +24235 -0.00115966796875 +24236 -0.348175048828125 +24237 0.00042724609375 +24238 -0.32598876953125 +24239 0.001953125 +24240 -0.2581787109375 +24241 0.003326416015625 +24242 -0.139801025390625 +24243 0.004486083984375 +24244 0.014617919921875 +24245 0.00537109375 +24246 0.144378662109375 +24247 0.005950927734375 +24248 0.221038818359375 +24249 0.006195068359375 +24250 0.27069091796875 +24251 0.006103515625 +24252 0.294036865234375 +24253 0.00567626953125 +24254 0.311767578125 +24255 0.00494384765625 +24256 0.339141845703125 +24257 0.003997802734375 +24258 0.360260009765625 +24259 0.00299072265625 +24260 0.360504150390625 +24261 0.001953125 +24262 0.308380126953125 +24263 0.00067138671875 +24264 0.18170166015625 +24265 -0.001007080078125 +24266 0.0047607421875 +24267 -0.002838134765625 +24268 -0.17559814453125 +24269 -0.00445556640625 +24270 -0.3143310546875 +24271 -0.00555419921875 +24272 -0.36785888671875 +24273 -0.00579833984375 +24274 -0.36248779296875 +24275 -0.00543212890625 +24276 -0.343536376953125 +24277 -0.00482177734375 +24278 -0.3018798828125 +24279 -0.00390625 +24280 -0.231414794921875 +24281 -0.002685546875 +24282 -0.117645263671875 +24283 -0.001129150390625 +24284 0.007049560546875 +24285 0.00048828125 +24286 0.087982177734375 +24287 0.001708984375 +24288 0.13946533203125 +24289 0.002593994140625 +24290 0.17425537109375 +24291 0.003265380859375 +24292 0.188201904296875 +24293 0.003662109375 +24294 0.171234130859375 +24295 0.003692626953125 +24296 0.118438720703125 +24297 0.003326416015625 +24298 0.05706787109375 +24299 0.002777099609375 +24300 -0.010711669921875 +24301 0.002105712890625 +24302 -0.0914306640625 +24303 0.001220703125 +24304 -0.162322998046875 +24305 0.000335693359375 +24306 -0.194549560546875 +24307 -0.000274658203125 +24308 -0.1492919921875 +24309 -0.00030517578125 +24310 -0.02166748046875 +24311 0.000274658203125 +24312 0.124053955078125 +24313 0.0009765625 +24314 0.211151123046875 +24315 0.001190185546875 +24316 0.240447998046875 +24317 0.0009765625 +24318 0.242218017578125 +24319 0.0006103515625 +24320 0.2257080078125 +24321 0.000732421875 +24322 0.194366455078125 +24323 0.001068115234375 +24324 0.115509033203125 +24325 -0.00030517578125 +24326 0.0128173828125 +24327 -0.00250244140625 +24328 -0.053802490234375 +24329 -0.00323486328125 +24330 -0.110626220703125 +24331 -0.003631591796875 +24332 -0.199493408203125 +24333 -0.005462646484375 +24334 -0.29437255859375 +24335 -0.00775146484375 +24336 -0.33221435546875 +24337 -0.008026123046875 +24338 -0.27972412109375 +24339 -0.0050048828125 +24340 -0.185333251953125 +24341 -0.00067138671875 +24342 -0.128204345703125 +24343 0.00177001953125 +24344 -0.115692138671875 +24345 0.002044677734375 +24346 -0.116455078125 +24347 0.001434326171875 +24348 -0.105926513671875 +24349 0.0009765625 +24350 -0.053955078125 +24351 0.001922607421875 +24352 0.048797607421875 +24353 0.00469970703125 +24354 0.157318115234375 +24355 0.00762939453125 +24356 0.212005615234375 +24357 0.00836181640625 +24358 0.218475341796875 +24359 0.007232666015625 +24360 0.23724365234375 +24361 0.0067138671875 +24362 0.30535888671875 +24363 0.00836181640625 +24364 0.38128662109375 +24365 0.010528564453125 +24366 0.404449462890625 +24367 0.010833740234375 +24368 0.3944091796875 +24369 0.0101318359375 +24370 0.3885498046875 +24371 0.009918212890625 +24372 0.362640380859375 +24373 0.00921630859375 +24374 0.27362060546875 +24375 0.00628662109375 +24376 0.11712646484375 +24377 0.00091552734375 +24378 -0.054901123046875 +24379 -0.004852294921875 +24380 -0.19085693359375 +24381 -0.009033203125 +24382 -0.28570556640625 +24383 -0.011505126953125 +24384 -0.339263916015625 +24385 -0.0123291015625 +24386 -0.3775634765625 +24387 -0.01263427734375 +24388 -0.445709228515625 +24389 -0.014251708984375 +24390 -0.535064697265625 +24391 -0.01690673828125 +24392 -0.629058837890625 +24393 -0.019989013671875 +24394 -0.697601318359375 +24395 -0.022308349609375 +24396 -0.70391845703125 +24397 -0.02239990234375 +24398 -0.6424560546875 +24399 -0.020050048828125 +24400 -0.491241455078125 +24401 -0.014404296875 +24402 -0.265716552734375 +24403 -0.00604248046875 +24404 -0.023712158203125 +24405 0.00274658203125 +24406 0.201751708984375 +24407 0.01068115234375 +24408 0.375823974609375 +24409 0.01641845703125 +24410 0.485076904296875 +24411 0.01953125 +24412 0.56884765625 +24413 0.021636962890625 +24414 0.634765625 +24415 0.02313232421875 +24416 0.63763427734375 +24417 0.022247314453125 +24418 0.5660400390625 +24419 0.01861572265625 +24420 0.4720458984375 +24421 0.01434326171875 +24422 0.40692138671875 +24423 0.011474609375 +24424 0.3778076171875 +24425 0.01031494140625 +24426 0.376953125 +24427 0.01055908203125 +24428 0.371978759765625 +24429 0.0108642578125 +24430 0.313140869140625 +24431 0.009185791015625 +24432 0.184417724609375 +24433 0.004852294921875 +24434 0.011199951171875 +24435 -0.001129150390625 +24436 -0.171051025390625 +24437 -0.007354736328125 +24438 -0.33740234375 +24439 -0.012908935546875 +24440 -0.47198486328125 +24441 -0.0172119140625 +24442 -0.560394287109375 +24443 -0.019744873046875 +24444 -0.58056640625 +24445 -0.01971435546875 +24446 -0.54754638671875 +24447 -0.01776123046875 +24448 -0.508575439453125 +24449 -0.01580810546875 +24450 -0.459503173828125 +24451 -0.013671875 +24452 -0.394378662109375 +24453 -0.0111083984375 +24454 -0.35260009765625 +24455 -0.009674072265625 +24456 -0.31170654296875 +24457 -0.008453369140625 +24458 -0.197418212890625 +24459 -0.00445556640625 +24460 -0.007965087890625 +24461 0.00238037109375 +24462 0.207489013671875 +24463 0.010101318359375 +24464 0.409210205078125 +24465 0.017181396484375 +24466 0.57208251953125 +24467 0.022674560546875 +24468 0.66595458984375 +24469 0.02545166015625 +24470 0.65875244140625 +24471 0.024261474609375 +24472 0.56744384765625 +24473 0.019866943359375 +24474 0.431396484375 +24475 0.01385498046875 +24476 0.29443359375 +24477 0.008026123046875 +24478 0.182464599609375 +24479 0.00341796875 +24480 0.06365966796875 +24481 -0.001220703125 +24482 -0.075958251953125 +24483 -0.0064697265625 +24484 -0.189422607421875 +24485 -0.01043701171875 +24486 -0.271942138671875 +24487 -0.012969970703125 +24488 -0.342529296875 +24489 -0.014862060546875 +24490 -0.364166259765625 +24491 -0.0147705078125 +24492 -0.327239990234375 +24493 -0.0123291015625 +24494 -0.2769775390625 +24495 -0.0093994140625 +24496 -0.253692626953125 +24497 -0.00762939453125 +24498 -0.24365234375 +24499 -0.00653076171875 +24500 -0.1983642578125 +24501 -0.004180908203125 +24502 -0.116241455078125 +24503 -0.00054931640625 +24504 -0.036834716796875 +24505 0.00274658203125 +24506 0.034881591796875 +24507 0.0054931640625 +24508 0.09124755859375 +24509 0.00738525390625 +24510 0.10888671875 +24511 0.007537841796875 +24512 0.125518798828125 +24513 0.007476806640625 +24514 0.15771484375 +24515 0.0079345703125 +24516 0.17828369140625 +24517 0.007843017578125 +24518 0.17108154296875 +24519 0.006622314453125 +24520 0.129974365234375 +24521 0.00408935546875 +24522 0.082427978515625 +24523 0.001373291015625 +24524 0.027679443359375 +24525 -0.00146484375 +24526 -0.065643310546875 +24527 -0.005615234375 +24528 -0.15936279296875 +24529 -0.009552001953125 +24530 -0.21307373046875 +24531 -0.01165771484375 +24532 -0.234649658203125 +24533 -0.012298583984375 +24534 -0.2001953125 +24535 -0.010528564453125 +24536 -0.119171142578125 +24537 -0.006744384765625 +24538 -0.024749755859375 +24539 -0.0023193359375 +24540 0.085784912109375 +24541 0.0028076171875 +24542 0.178131103515625 +24543 0.0072021484375 +24544 0.215576171875 +24545 0.009368896484375 +24546 0.211456298828125 +24547 0.009796142578125 +24548 0.17523193359375 +24549 0.008880615234375 +24550 0.128753662109375 +24551 0.0074462890625 +24552 0.1019287109375 +24553 0.00665283203125 +24554 0.0743408203125 +24555 0.005706787109375 +24556 0.04327392578125 +24557 0.004486083984375 +24558 0.038177490234375 +24559 0.004150390625 +24560 0.076263427734375 +24561 0.00537109375 +24562 0.14105224609375 +24563 0.00750732421875 +24564 0.186431884765625 +24565 0.008758544921875 +24566 0.188812255859375 +24567 0.00823974609375 +24568 0.1390380859375 +24569 0.005615234375 +24570 0.041778564453125 +24571 0.0010986328125 +24572 -0.079437255859375 +24573 -0.004302978515625 +24574 -0.219390869140625 +24575 -0.010345458984375 +24576 -0.367828369140625 +24577 -0.01690673828125 +24578 -0.494873046875 +24579 -0.023223876953125 +24580 -0.556243896484375 +24581 -0.026580810546875 +24582 -0.508697509765625 +24583 -0.023590087890625 +24584 -0.3756103515625 +24585 -0.015655517578125 +24586 -0.218902587890625 +24587 -0.006927490234375 +24588 -0.063751220703125 +24589 0.001068115234375 +24590 0.091552734375 +24591 0.0087890625 +24592 0.23602294921875 +24593 0.01568603515625 +24594 0.342987060546875 +24595 0.020111083984375 +24596 0.39520263671875 +24597 0.021026611328125 +24598 0.389373779296875 +24599 0.018341064453125 +24600 0.324249267578125 +24601 0.0120849609375 +24602 0.224090576171875 +24603 0.00408935546875 +24604 0.124267578125 +24605 -0.003082275390625 +24606 0.037078857421875 +24607 -0.00860595703125 +24608 -0.010101318359375 +24609 -0.010589599609375 +24610 -0.019439697265625 +24611 -0.009307861328125 +24612 -0.022796630859375 +24613 -0.007171630859375 +24614 -0.001556396484375 +24615 -0.00299072265625 +24616 0.056304931640625 +24617 0.003875732421875 +24618 0.106719970703125 +24619 0.0101318359375 +24620 0.096893310546875 +24621 0.0118408203125 +24622 0.042694091796875 +24623 0.010040283203125 +24624 -0.018035888671875 +24625 0.00732421875 +24626 -0.07586669921875 +24627 0.0042724609375 +24628 -0.11944580078125 +24629 0.001708984375 +24630 -0.15972900390625 +24631 -0.00115966796875 +24632 -0.202606201171875 +24633 -0.004730224609375 +24634 -0.24859619140625 +24635 -0.009002685546875 +24636 -0.30517578125 +24637 -0.014434814453125 +24638 -0.36212158203125 +24639 -0.020233154296875 +24640 -0.39141845703125 +24641 -0.0242919921875 +24642 -0.35528564453125 +24643 -0.023773193359375 +24644 -0.249969482421875 +24645 -0.018280029296875 +24646 -0.092864990234375 +24647 -0.00897216796875 +24648 0.08905029296875 +24649 0.002288818359375 +24650 0.2352294921875 +24651 0.011260986328125 +24652 0.318817138671875 +24653 0.016082763671875 +24654 0.358642578125 +24655 0.018157958984375 +24656 0.347747802734375 +24657 0.01702880859375 +24658 0.28564453125 +24659 0.012664794921875 +24660 0.223175048828125 +24661 0.00872802734375 +24662 0.196746826171875 +24663 0.00775146484375 +24664 0.179840087890625 +24665 0.007781982421875 +24666 0.155548095703125 +24667 0.007537841796875 +24668 0.151214599609375 +24669 0.008880615234375 +24670 0.156951904296875 +24671 0.011016845703125 +24672 0.13177490234375 +24673 0.010894775390625 +24674 0.100799560546875 +24675 0.01025390625 +24676 0.087127685546875 +24677 0.010650634765625 +24678 0.05487060546875 +24679 0.00946044921875 +24680 -0.009002685546875 +24681 0.005645751953125 +24682 -0.10400390625 +24683 -0.000732421875 +24684 -0.229400634765625 +24685 -0.0096435546875 +24686 -0.35552978515625 +24687 -0.018951416015625 +24688 -0.441925048828125 +24689 -0.025726318359375 +24690 -0.473846435546875 +24691 -0.028900146484375 +24692 -0.464813232421875 +24693 -0.02935791015625 +24694 -0.419097900390625 +24695 -0.02734375 +24696 -0.334320068359375 +24697 -0.0225830078125 +24698 -0.227935791015625 +24699 -0.01629638671875 +24700 -0.12347412109375 +24701 -0.010101318359375 +24702 -0.02764892578125 +24703 -0.00439453125 +24704 0.077667236328125 +24705 0.002166748046875 +24706 0.2132568359375 +24707 0.0111083984375 +24708 0.38885498046875 +24709 0.023193359375 +24710 0.582794189453125 +24711 0.036865234375 +24712 0.734039306640625 +24713 0.047760009765625 +24714 0.800140380859375 +24715 0.052764892578125 +24716 0.7783203125 +24717 0.05169677734375 +24718 0.6651611328125 +24719 0.044281005859375 +24720 0.45965576171875 +24721 0.0303955078125 +24722 0.199188232421875 +24723 0.0126953125 +24724 -0.050689697265625 +24725 -0.004150390625 +24726 -0.23297119140625 +24727 -0.01611328125 +24728 -0.33013916015625 +24729 -0.022003173828125 +24730 -0.368408203125 +24731 -0.02374267578125 +24732 -0.378936767578125 +24733 -0.02362060546875 +24734 -0.376983642578125 +24735 -0.0228271484375 +24736 -0.37969970703125 +24737 -0.022613525390625 +24738 -0.391510009765625 +24739 -0.0233154296875 +24740 -0.385345458984375 +24741 -0.02294921875 +24742 -0.3419189453125 +24743 -0.020111083984375 +24744 -0.28289794921875 +24745 -0.016357421875 +24746 -0.251617431640625 +24747 -0.014801025390625 +24748 -0.266143798828125 +24749 -0.01666259765625 +24750 -0.273345947265625 +24751 -0.01806640625 +24752 -0.216796875 +24753 -0.014923095703125 +24754 -0.128265380859375 +24755 -0.00946044921875 +24756 -0.068145751953125 +24757 -0.005950927734375 +24758 -0.0430908203125 +24759 -0.00482177734375 +24760 -0.024444580078125 +24761 -0.003997802734375 +24762 0.020721435546875 +24763 -0.0010986328125 +24764 0.124481201171875 +24765 0.00616455078125 +24766 0.25787353515625 +24767 0.015716552734375 +24768 0.379119873046875 +24769 0.024566650390625 +24770 0.47991943359375 +24771 0.0321044921875 +24772 0.5281982421875 +24773 0.035980224609375 +24774 0.511138916015625 +24775 0.035247802734375 +24776 0.456207275390625 +24777 0.031829833984375 +24778 0.407470703125 +24779 0.02886962890625 +24780 0.383758544921875 +24781 0.0277099609375 +24782 0.35687255859375 +24783 0.026275634765625 +24784 0.31182861328125 +24785 0.023468017578125 +24786 0.250885009765625 +24787 0.019439697265625 +24788 0.1654052734375 +24789 0.0135498046875 +24790 0.035247802734375 +24791 0.004364013671875 +24792 -0.142059326171875 +24793 -0.008270263671875 +24794 -0.33563232421875 +24795 -0.022125244140625 +24796 -0.5345458984375 +24797 -0.03643798828125 +24798 -0.72186279296875 +24799 -0.04998779296875 +24800 -0.836669921875 +24801 -0.058380126953125 +24802 -0.8326416015625 +24803 -0.05828857421875 +24804 -0.7296142578125 +24805 -0.051116943359375 +24806 -0.582550048828125 +24807 -0.040863037109375 +24808 -0.440093994140625 +24809 -0.030975341796875 +24810 -0.324310302734375 +24811 -0.02301025390625 +24812 -0.20147705078125 +24813 -0.014495849609375 +24814 -0.044647216796875 +24815 -0.00347900390625 +24816 0.103973388671875 +24817 0.0069580078125 +24818 0.202392578125 +24819 0.0137939453125 +24820 0.264495849609375 +24821 0.01806640625 +24822 0.338897705078125 +24823 0.023284912109375 +24824 0.443817138671875 +24825 0.03076171875 +24826 0.545074462890625 +24827 0.03802490234375 +24828 0.6173095703125 +24829 0.04327392578125 +24830 0.6524658203125 +24831 0.0458984375 +24832 0.66339111328125 +24833 0.04718017578125 +24834 0.6561279296875 +24835 0.047698974609375 +24836 0.606781005859375 +24837 0.045074462890625 +24838 0.501190185546875 +24839 0.03765869140625 +24840 0.352783203125 +24841 0.026611328125 +24842 0.176544189453125 +24843 0.01324462890625 +24844 -0.034820556640625 +24845 -0.00347900390625 +24846 -0.258209228515625 +24847 -0.021453857421875 +24848 -0.44244384765625 +24849 -0.035675048828125 +24850 -0.5753173828125 +24851 -0.045166015625 +24852 -0.65203857421875 +24853 -0.049652099609375 +24854 -0.641632080078125 +24855 -0.046112060546875 +24856 -0.562164306640625 +24857 -0.03656005859375 +24858 -0.458038330078125 +24859 -0.025665283203125 +24860 -0.350555419921875 +24861 -0.015625 +24862 -0.260528564453125 +24863 -0.00848388671875 +24864 -0.192108154296875 +24865 -0.0045166015625 +24866 -0.141937255859375 +24867 -0.003173828125 +24868 -0.1021728515625 +24869 -0.00341796875 +24870 -0.062896728515625 +24871 -0.003936767578125 +24872 -0.011932373046875 +24873 -0.003204345703125 +24874 0.062835693359375 +24875 0.000244140625 +24876 0.148712158203125 +24877 0.005340576171875 +24878 0.241729736328125 +24879 0.0118408203125 +24880 0.34912109375 +24881 0.020660400390625 +24882 0.457305908203125 +24883 0.030487060546875 +24884 0.54388427734375 +24885 0.0390625 +24886 0.5728759765625 +24887 0.042633056640625 +24888 0.506591796875 +24889 0.037200927734375 +24890 0.351226806640625 +24891 0.0233154296875 +24892 0.146514892578125 +24893 0.00494384765625 +24894 -0.05523681640625 +24895 -0.012603759765625 +24896 -0.21624755859375 +24897 -0.025604248046875 +24898 -0.334930419921875 +24899 -0.03411865234375 +24900 -0.402984619140625 +24901 -0.0374755859375 +24902 -0.4412841796875 +24903 -0.03802490234375 +24904 -0.49578857421875 +24905 -0.040771484375 +24906 -0.5601806640625 +24907 -0.045196533203125 +24908 -0.600738525390625 +24909 -0.047882080078125 +24910 -0.584228515625 +24911 -0.045440673828125 +24912 -0.47930908203125 +24913 -0.03466796875 +24914 -0.27935791015625 +24915 -0.014801025390625 +24916 -0.0089111328125 +24917 0.011627197265625 +24918 0.268798828125 +24919 0.038177490234375 +24920 0.482818603515625 +24921 0.057586669921875 +24922 0.60369873046875 +24923 0.066986083984375 +24924 0.650421142578125 +24925 0.068511962890625 +24926 0.66400146484375 +24927 0.066650390625 +24928 0.6414794921875 +24929 0.061279296875 +24930 0.572540283203125 +24931 0.051483154296875 +24932 0.498138427734375 +24933 0.0416259765625 +24934 0.439453125 +24935 0.034027099609375 +24936 0.375518798828125 +24937 0.026580810546875 +24938 0.274505615234375 +24939 0.0159912109375 +24940 0.1087646484375 +24941 -0.0006103515625 +24942 -0.099395751953125 +24943 -0.020965576171875 +24944 -0.3182373046875 +24945 -0.041839599609375 +24946 -0.5489501953125 +24947 -0.0634765625 +24948 -0.7738037109375 +24949 -0.08416748046875 +24950 -0.86383056640625 +24951 -0.09857177734375 +24952 -0.870391845703125 +24953 -0.1033935546875 +24954 -0.86895751953125 +24955 -0.10064697265625 +24956 -0.861053466796875 +24957 -0.091827392578125 +24958 -0.765869140625 +24959 -0.075286865234375 +24960 -0.5301513671875 +24961 -0.049957275390625 +24962 -0.214691162109375 +24963 -0.0166015625 +24964 0.137359619140625 +24965 0.020233154296875 +24966 0.474822998046875 +24967 0.055206298828125 +24968 0.76239013671875 +24969 0.084686279296875 +24970 0.867462158203125 +24971 0.105926513671875 +24972 0.870361328125 +24973 0.119049072265625 +24974 0.86480712890625 +24975 0.122955322265625 +24976 0.831817626953125 +24977 0.11834716796875 +24978 0.677581787109375 +24979 0.10791015625 +24980 0.495880126953125 +24981 0.092437744140625 +24982 0.30767822265625 +24983 0.073974609375 +24984 0.116180419921875 +24985 0.0528564453125 +24986 -0.110748291015625 +24987 0.02587890625 +24988 -0.381805419921875 +24989 -0.007598876953125 +24990 -0.6572265625 +24991 -0.0430908203125 +24992 -0.857421875 +24993 -0.0743408203125 +24994 -0.870391845703125 +24995 -0.096954345703125 +24996 -0.870391845703125 +24997 -0.110260009765625 +24998 -0.86444091796875 +24999 -0.117156982421875 +25000 -0.85723876953125 +25001 -0.121429443359375 +25002 -0.790008544921875 +25003 -0.121307373046875 +25004 -0.62847900390625 +25005 -0.11126708984375 +25006 -0.3956298828125 +25007 -0.091094970703125 +25008 -0.126708984375 +25009 -0.064300537109375 +25010 0.150115966796875 +25011 -0.0338134765625 +25012 0.424041748046875 +25013 -0.0009765625 +25014 0.670623779296875 +25015 0.031341552734375 +25016 0.854522705078125 +25017 0.059051513671875 +25018 0.866485595703125 +25019 0.080352783203125 +25020 0.86920166015625 +25021 0.093658447265625 +25022 0.8653564453125 +25023 0.100921630859375 +25024 0.857147216796875 +25025 0.103607177734375 +25026 0.766845703125 +25027 0.10150146484375 +25028 0.628509521484375 +25029 0.09521484375 +25030 0.462127685546875 +25031 0.08416748046875 +25032 0.297210693359375 +25033 0.071136474609375 +25034 0.14862060546875 +25035 0.057464599609375 +25036 -0.00537109375 +25037 0.040863037109375 +25038 -0.15753173828125 +25039 0.022186279296875 +25040 -0.31304931640625 +25041 0.00115966796875 +25042 -0.48876953125 +25043 -0.02362060546875 +25044 -0.6416015625 +25045 -0.04730224609375 +25046 -0.751373291015625 +25047 -0.06732177734375 +25048 -0.84619140625 +25049 -0.086090087890625 +25050 -0.861297607421875 +25051 -0.102142333984375 +25052 -0.863250732421875 +25053 -0.112091064453125 +25054 -0.856597900390625 +25055 -0.112701416015625 +25056 -0.7498779296875 +25057 -0.1053466796875 +25058 -0.624542236328125 +25059 -0.09613037109375 +25060 -0.47808837890625 +25061 -0.0828857421875 +25062 -0.253387451171875 +25063 -0.059600830078125 +25064 0.003692626953125 +25065 -0.031097412109375 +25066 0.2257080078125 +25067 -0.00457763671875 +25068 0.427154541015625 +25069 0.021209716796875 +25070 0.643218994140625 +25071 0.049652099609375 +25072 0.855926513671875 +25073 0.0797119140625 +25074 0.870361328125 +25075 0.105438232421875 +25076 0.870361328125 +25077 0.121673583984375 +25078 0.862762451171875 +25079 0.1292724609375 +25080 0.79669189453125 +25081 0.127960205078125 +25082 0.595794677734375 +25083 0.116851806640625 +25084 0.362152099609375 +25085 0.09906005859375 +25086 0.1270751953125 +25087 0.077606201171875 +25088 -0.086944580078125 +25089 0.0552978515625 +25090 -0.2784423828125 +25091 0.03271484375 +25092 -0.484832763671875 +25093 0.0048828125 +25094 -0.729583740234375 +25095 -0.0316162109375 +25096 -0.86688232421875 +25097 -0.07061767578125 +25098 -0.870391845703125 +25099 -0.104156494140625 +25100 -0.86859130859375 +25101 -0.131988525390625 +25102 -0.86279296875 +25103 -0.154205322265625 +25104 -0.817962646484375 +25105 -0.1661376953125 +25106 -0.6116943359375 +25107 -0.161712646484375 +25108 -0.3128662109375 +25109 -0.139892578125 +25110 0.039398193359375 +25111 -0.105072021484375 +25112 0.422821044921875 +25113 -0.059722900390625 +25114 0.805145263671875 +25115 -0.008026123046875 +25116 0.870361328125 +25117 0.041107177734375 +25118 0.870361328125 +25119 0.08038330078125 +25120 0.860015869140625 +25121 0.108673095703125 +25122 0.727935791015625 +25123 0.12530517578125 +25124 0.48114013671875 +25125 0.1298828125 +25126 0.2059326171875 +25127 0.126007080078125 +25128 -0.06103515625 +25129 0.116943359375 +25130 -0.29913330078125 +25131 0.10418701171875 +25132 -0.516204833984375 +25133 0.0858154296875 +25134 -0.7252197265625 +25135 0.05975341796875 +25136 -0.85980224609375 +25137 0.029266357421875 +25138 -0.870391845703125 +25139 -0.0010986328125 +25140 -0.870391845703125 +25141 -0.027587890625 +25142 -0.858062744140625 +25143 -0.0438232421875 +25144 -0.673004150390625 +25145 -0.049560546875 +25146 -0.42694091796875 +25147 -0.05224609375 +25148 -0.2100830078125 +25149 -0.05816650390625 +25150 -0.0362548828125 +25151 -0.067291259765625 +25152 0.10943603515625 +25153 -0.07586669921875 +25154 0.23516845703125 +25155 -0.081329345703125 +25156 0.373687744140625 +25157 -0.07818603515625 +25158 0.517791748046875 +25159 -0.066741943359375 +25160 0.602783203125 +25161 -0.055572509765625 +25162 0.635711669921875 +25163 -0.0439453125 +25164 0.655181884765625 +25165 -0.0272216796875 +25166 0.65948486328125 +25167 -0.006591796875 +25168 0.651275634765625 +25169 0.016998291015625 +25170 0.61846923828125 +25171 0.0404052734375 +25172 0.53753662109375 +25173 0.058837890625 +25174 0.404144287109375 +25175 0.070037841796875 +25176 0.22186279296875 +25177 0.072906494140625 +25178 0.003997802734375 +25179 0.067840576171875 +25180 -0.22100830078125 +25181 0.05743408203125 +25182 -0.42449951171875 +25183 0.04461669921875 +25184 -0.579833984375 +25185 0.0323486328125 +25186 -0.641876220703125 +25187 0.026458740234375 +25188 -0.6177978515625 +25189 0.0260009765625 +25190 -0.575531005859375 +25191 0.022125244140625 +25192 -0.526336669921875 +25193 0.01397705078125 +25194 -0.42645263671875 +25195 0.00848388671875 +25196 -0.2581787109375 +25197 0.009185791015625 +25198 -0.068695068359375 +25199 0.010955810546875 +25200 0.09222412109375 +25201 0.0084228515625 +25202 0.232147216796875 +25203 0.00396728515625 +25204 0.3509521484375 +25205 -0.001129150390625 +25206 0.410064697265625 +25207 -0.011016845703125 +25208 0.372955322265625 +25209 -0.029815673828125 +25210 0.2554931640625 +25211 -0.054718017578125 +25212 0.10711669921875 +25213 -0.078643798828125 +25214 -0.052886962890625 +25215 -0.098907470703125 +25216 -0.186279296875 +25217 -0.110565185546875 +25218 -0.23291015625 +25219 -0.105926513671875 +25220 -0.209442138671875 +25221 -0.087982177734375 +25222 -0.174163818359375 +25223 -0.065582275390625 +25224 -0.126739501953125 +25225 -0.03973388671875 +25226 -0.048126220703125 +25227 -0.00897216796875 +25228 0.0426025390625 +25229 0.02301025390625 +25230 0.10748291015625 +25231 0.049957275390625 +25232 0.1409912109375 +25233 0.070159912109375 +25234 0.19708251953125 +25235 0.090179443359375 +25236 0.273651123046875 +25237 0.109161376953125 +25238 0.31768798828125 +25239 0.119537353515625 +25240 0.341094970703125 +25241 0.122833251953125 +25242 0.368011474609375 +25243 0.1224365234375 +25244 0.37249755859375 +25245 0.11517333984375 +25246 0.30072021484375 +25247 0.09423828125 +25248 0.1517333984375 +25249 0.060211181640625 +25250 -0.01470947265625 +25251 0.02203369140625 +25252 -0.1883544921875 +25253 -0.0179443359375 +25254 -0.372711181640625 +25255 -0.059295654296875 +25256 -0.51397705078125 +25257 -0.09381103515625 +25258 -0.57177734375 +25259 -0.115203857421875 +25260 -0.53948974609375 +25261 -0.12188720703125 +25262 -0.43511962890625 +25263 -0.11578369140625 +25264 -0.2962646484375 +25265 -0.101654052734375 +25266 -0.161102294921875 +25267 -0.08453369140625 +25268 -0.0435791015625 +25269 -0.066314697265625 +25270 0.060394287109375 +25271 -0.046661376953125 +25272 0.13665771484375 +25273 -0.02789306640625 +25274 0.170135498046875 +25275 -0.01263427734375 +25276 0.16552734375 +25277 -0.000885009765625 +25278 0.15728759765625 +25279 0.01129150390625 +25280 0.150787353515625 +25281 0.02386474609375 +25282 0.12200927734375 +25283 0.0328369140625 +25284 0.080108642578125 +25285 0.03875732421875 +25286 0.05126953125 +25287 0.04461669921875 +25288 0.062896728515625 +25289 0.05364990234375 +25290 0.09271240234375 +25291 0.062469482421875 +25292 0.092987060546875 +25293 0.064422607421875 +25294 0.07855224609375 +25295 0.061492919921875 +25296 0.06427001953125 +25297 0.055816650390625 +25298 0.0347900390625 +25299 0.04559326171875 +25300 -0.01171875 +25301 0.031005859375 +25302 -0.056060791015625 +25303 0.015167236328125 +25304 -0.055511474609375 +25305 0.004486083984375 +25306 -0.010467529296875 +25307 -0.000457763671875 +25308 0.02508544921875 +25309 -0.006378173828125 +25310 0.025665283203125 +25311 -0.01617431640625 +25312 0.017333984375 +25313 -0.02581787109375 +25314 0.00189208984375 +25315 -0.03460693359375 +25316 -0.03173828125 +25317 -0.04376220703125 +25318 -0.071502685546875 +25319 -0.05145263671875 +25320 -0.13543701171875 +25321 -0.06005859375 +25322 -0.219970703125 +25323 -0.069183349609375 +25324 -0.300506591796875 +25325 -0.075653076171875 +25326 -0.376312255859375 +25327 -0.079681396484375 +25328 -0.416107177734375 +25329 -0.077423095703125 +25330 -0.371124267578125 +25331 -0.06268310546875 +25332 -0.242279052734375 +25333 -0.036102294921875 +25334 -0.069732666015625 +25335 -0.003631591796875 +25336 0.125640869140625 +25337 0.0313720703125 +25338 0.31268310546875 +25339 0.064208984375 +25340 0.45501708984375 +25341 0.08953857421875 +25342 0.554779052734375 +25343 0.107391357421875 +25344 0.61065673828125 +25345 0.11761474609375 +25346 0.610931396484375 +25347 0.118408203125 +25348 0.531463623046875 +25349 0.105865478515625 +25350 0.3883056640625 +25351 0.08245849609375 +25352 0.23468017578125 +25353 0.0562744140625 +25354 0.095245361328125 +25355 0.03118896484375 +25356 -0.00396728515625 +25357 0.011322021484375 +25358 -0.04852294921875 +25359 -0.000885009765625 +25360 -0.055145263671875 +25361 -0.007598876953125 +25362 -0.0758056640625 +25363 -0.016326904296875 +25364 -0.138702392578125 +25365 -0.030975341796875 +25366 -0.209197998046875 +25367 -0.046051025390625 +25368 -0.289031982421875 +25369 -0.06158447265625 +25370 -0.37884521484375 +25371 -0.077484130859375 +25372 -0.456329345703125 +25373 -0.090301513671875 +25374 -0.51641845703125 +25375 -0.0992431640625 +25376 -0.519287109375 +25377 -0.098388671875 +25378 -0.458251953125 +25379 -0.08685302734375 +25380 -0.384796142578125 +25381 -0.072509765625 +25382 -0.323699951171875 +25383 -0.059295654296875 +25384 -0.269287109375 +25385 -0.046539306640625 +25386 -0.1951904296875 +25387 -0.03057861328125 +25388 -0.100006103515625 +25389 -0.011474609375 +25390 -0.01055908203125 +25391 0.006439208984375 +25392 0.1033935546875 +25393 0.027435302734375 +25394 0.24908447265625 +25395 0.05242919921875 +25396 0.373199462890625 +25397 0.073272705078125 +25398 0.45806884765625 +25399 0.08721923828125 +25400 0.511474609375 +25401 0.09539794921875 +25402 0.565399169921875 +25403 0.102630615234375 +25404 0.61138916015625 +25405 0.10772705078125 +25406 0.5897216796875 +25407 0.101837158203125 +25408 0.4906005859375 +25409 0.08367919921875 +25410 0.33148193359375 +25411 0.056060791015625 +25412 0.147796630859375 +25413 0.024505615234375 +25414 -0.01873779296875 +25415 -0.004486083984375 +25416 -0.140289306640625 +25417 -0.0264892578125 +25418 -0.191986083984375 +25419 -0.037567138671875 +25420 -0.184295654296875 +25421 -0.03912353515625 +25422 -0.161834716796875 +25423 -0.0377197265625 +25424 -0.166595458984375 +25425 -0.039581298828125 +25426 -0.19390869140625 +25427 -0.043975830078125 +25428 -0.22442626953125 +25429 -0.048004150390625 +25430 -0.279754638671875 +25431 -0.054962158203125 +25432 -0.3389892578125 +25433 -0.061798095703125 +25434 -0.3543701171875 +25435 -0.0615234375 +25436 -0.348175048828125 +25437 -0.0576171875 +25438 -0.32598876953125 +25439 -0.051055908203125 +25440 -0.2581787109375 +25441 -0.03759765625 +25442 -0.139801025390625 +25443 -0.016693115234375 +25444 0.014617919921875 +25445 0.009307861328125 +25446 0.144378662109375 +25447 0.0311279296875 +25448 0.221038818359375 +25449 0.044403076171875 +25450 0.27069091796875 +25451 0.052947998046875 +25452 0.294036865234375 +25453 0.056854248046875 +25454 0.311767578125 +25455 0.0592041015625 +25456 0.339141845703125 +25457 0.0623779296875 +25458 0.360260009765625 +25459 0.064300537109375 +25460 0.360504150390625 +25461 0.06280517578125 +25462 0.308380126953125 +25463 0.052581787109375 +25464 0.18170166015625 +25465 0.029937744140625 +25466 0.0047607421875 +25467 -0.000946044921875 +25468 -0.17559814453125 +25469 -0.032196044921875 +25470 -0.3143310546875 +25471 -0.056243896484375 +25472 -0.36785888671875 +25473 -0.065765380859375 +25474 -0.36248779296875 +25475 -0.06512451171875 +25476 -0.343536376953125 +25477 -0.06195068359375 +25478 -0.3018798828125 +25479 -0.05474853515625 +25480 -0.231414794921875 +25481 -0.042510986328125 +25482 -0.117645263671875 +25483 -0.0228271484375 +25484 0.007049560546875 +25485 -0.001190185546875 +25486 0.087982177734375 +25487 0.01318359375 +25488 0.13946533203125 +25489 0.02264404296875 +25490 0.17425537109375 +25491 0.029327392578125 +25492 0.188201904296875 +25493 0.032470703125 +25494 0.171234130859375 +25495 0.03033447265625 +25496 0.118438720703125 +25497 0.0220947265625 +25498 0.05706787109375 +25499 0.012298583984375 +25500 -0.010711669921875 +25501 0.00128173828125 +25502 -0.0914306640625 +25503 -0.01202392578125 +25504 -0.162322998046875 +25505 -0.023834228515625 +25506 -0.194549560546875 +25507 -0.029327392578125 +25508 -0.1492919921875 +25509 -0.02197265625 +25510 -0.02166748046875 +25511 -0.000946044921875 +25512 0.124053955078125 +25513 0.02301025390625 +25514 0.211151123046875 +25515 0.0369873046875 +25516 0.240447998046875 +25517 0.041168212890625 +25518 0.242218017578125 +25519 0.04071044921875 +25520 0.2257080078125 +25521 0.037200927734375 +25522 0.194366455078125 +25523 0.03125 +25524 0.115509033203125 +25525 0.017425537109375 +25526 0.0128173828125 +25527 -0.000244140625 +25528 -0.053802490234375 +25529 -0.01165771484375 +25530 -0.110626220703125 +25531 -0.021240234375 +25532 -0.199493408203125 +25533 -0.036041259765625 +25534 -0.29437255859375 +25535 -0.05169677734375 +25536 -0.33221435546875 +25537 -0.0576171875 +25538 -0.27972412109375 +25539 -0.04827880859375 +25540 -0.185333251953125 +25541 -0.031829833984375 +25542 -0.128204345703125 +25543 -0.0216064453125 +25544 -0.115692138671875 +25545 -0.01885986328125 +25546 -0.116455078125 +25547 -0.01837158203125 +25548 -0.105926513671875 +25549 -0.016021728515625 +25550 -0.053955078125 +25551 -0.006805419921875 +25552 0.048797607421875 +25553 0.01080322265625 +25554 0.157318115234375 +25555 0.02923583984375 +25556 0.212005615234375 +25557 0.0384521484375 +25558 0.218475341796875 +25559 0.039398193359375 +25560 0.23724365234375 +25561 0.042266845703125 +25562 0.30535888671875 +25563 0.053314208984375 +25564 0.38128662109375 +25565 0.065582275390625 +25566 0.404449462890625 +25567 0.068878173828125 +25568 0.3944091796875 +25569 0.066558837890625 +25570 0.3885498046875 +25571 0.06494140625 +25572 0.362640380859375 +25573 0.059967041015625 +25574 0.27362060546875 +25575 0.044464111328125 +25576 0.11712646484375 +25577 0.017730712890625 +25578 -0.054901123046875 +25579 -0.011444091796875 +25580 -0.19085693359375 +25581 -0.034393310546875 +25582 -0.28570556640625 +25583 -0.050262451171875 +25584 -0.339263916015625 +25585 -0.059051513671875 +25586 -0.3775634765625 +25587 -0.065155029296875 +25588 -0.445709228515625 +25589 -0.076171875 +25590 -0.535064697265625 +25591 -0.090667724609375 +25592 -0.629058837890625 +25593 -0.10589599609375 +25594 -0.697601318359375 +25595 -0.1168212890625 +25596 -0.70391845703125 +25597 -0.117279052734375 +25598 -0.6424560546875 +25599 -0.10638427734375 +25600 -0.491241455078125 +25601 -0.080047607421875 +25602 -0.265716552734375 +25603 -0.04071044921875 +25604 -0.023712158203125 +25605 0.0010986328125 +25606 0.201751708984375 +25607 0.039276123046875 +25608 0.375823974609375 +25609 0.0673828125 +25610 0.485076904296875 +25611 0.083221435546875 +25612 0.56884765625 +25613 0.095001220703125 +25614 0.634765625 +25615 0.1044921875 +25616 0.63763427734375 +25617 0.102813720703125 +25618 0.5660400390625 +25619 0.0877685546875 +25620 0.4720458984375 +25621 0.069732666015625 +25622 0.40692138671875 +25623 0.058868408203125 +25624 0.3778076171875 +25625 0.056427001953125 +25626 0.376953125 +25627 0.06060791015625 +25628 0.371978759765625 +25629 0.064697265625 +25630 0.313140869140625 +25631 0.05841064453125 +25632 0.184417724609375 +25633 0.0382080078125 +25634 0.011199951171875 +25635 0.008880615234375 +25636 -0.171051025390625 +25637 -0.022735595703125 +25638 -0.33740234375 +25639 -0.051910400390625 +25640 -0.47198486328125 +25641 -0.075653076171875 +25642 -0.560394287109375 +25643 -0.09124755859375 +25644 -0.58056640625 +25645 -0.0943603515625 +25646 -0.54754638671875 +25647 -0.0880126953125 +25648 -0.508575439453125 +25649 -0.081634521484375 +25650 -0.459503173828125 +25651 -0.07427978515625 +25652 -0.394378662109375 +25653 -0.064605712890625 +25654 -0.35260009765625 +25655 -0.06024169921875 +25656 -0.31170654296875 +25657 -0.05645751953125 +25658 -0.197418212890625 +25659 -0.038177490234375 +25660 -0.007965087890625 +25661 -0.004791259765625 +25662 0.207489013671875 +25663 0.0340576171875 +25664 0.409210205078125 +25665 0.0706787109375 +25666 0.57208251953125 +25667 0.1002197265625 +25668 0.66595458984375 +25669 0.1168212890625 +25670 0.65875244140625 +25671 0.1141357421875 +25672 0.56744384765625 +25673 0.09564208984375 +25674 0.431396484375 +25675 0.069183349609375 +25676 0.29443359375 +25677 0.04345703125 +25678 0.182464599609375 +25679 0.023529052734375 +25680 0.06365966796875 +25681 0.002899169921875 +25682 -0.075958251953125 +25683 -0.02142333984375 +25684 -0.189422607421875 +25685 -0.040252685546875 +25686 -0.271942138671875 +25687 -0.052825927734375 +25688 -0.342529296875 +25689 -0.06317138671875 +25690 -0.364166259765625 +25691 -0.064117431640625 +25692 -0.327239990234375 +25693 -0.053924560546875 +25694 -0.2769775390625 +25695 -0.041778564453125 +25696 -0.253692626953125 +25697 -0.035797119140625 +25698 -0.24365234375 +25699 -0.033294677734375 +25700 -0.1983642578125 +25701 -0.024566650390625 +25702 -0.116241455078125 +25703 -0.00927734375 +25704 -0.036834716796875 +25705 0.004730224609375 +25706 0.034881591796875 +25707 0.0166015625 +25708 0.09124755859375 +25709 0.024932861328125 +25710 0.10888671875 +25711 0.025238037109375 +25712 0.125518798828125 +25713 0.025238037109375 +25714 0.15771484375 +25715 0.0284423828125 +25716 0.17828369140625 +25717 0.02960205078125 +25718 0.17108154296875 +25719 0.025604248046875 +25720 0.129974365234375 +25721 0.015380859375 +25722 0.082427978515625 +25723 0.0045166015625 +25724 0.027679443359375 +25725 -0.007049560546875 +25726 -0.065643310546875 +25727 -0.02557373046875 +25728 -0.15936279296875 +25729 -0.04345703125 +25730 -0.21307373046875 +25731 -0.052703857421875 +25732 -0.234649658203125 +25733 -0.05499267578125 +25734 -0.2001953125 +25735 -0.045684814453125 +25736 -0.119171142578125 +25737 -0.026824951171875 +25738 -0.024749755859375 +25739 -0.00518798828125 +25740 0.085784912109375 +25741 0.01959228515625 +25742 0.178131103515625 +25743 0.040496826171875 +25744 0.215576171875 +25745 0.050079345703125 +25746 0.211456298828125 +25747 0.0509033203125 +25748 0.17523193359375 +25749 0.0447998046875 +25750 0.128753662109375 +25751 0.036102294921875 +25752 0.1019287109375 +25753 0.03076171875 +25754 0.0743408203125 +25755 0.02471923828125 +25756 0.04327392578125 +25757 0.0174560546875 +25758 0.038177490234375 +25759 0.01495361328125 +25760 0.076263427734375 +25761 0.020721435546875 +25762 0.14105224609375 +25763 0.031585693359375 +25764 0.186431884765625 +25765 0.038421630859375 +25766 0.188812255859375 +25767 0.036651611328125 +25768 0.1390380859375 +25769 0.024566650390625 +25770 0.041778564453125 +25771 0.00323486328125 +25772 -0.079437255859375 +25773 -0.02252197265625 +25774 -0.219390869140625 +25775 -0.051605224609375 +25776 -0.367828369140625 +25777 -0.081878662109375 +25778 -0.494873046875 +25779 -0.107391357421875 +25780 -0.556243896484375 +25781 -0.119293212890625 +25782 -0.508697509765625 +25783 -0.10894775390625 +25784 -0.3756103515625 +25785 -0.081085205078125 +25786 -0.218902587890625 +25787 -0.048187255859375 +25788 -0.063751220703125 +25789 -0.015380859375 +25790 0.091552734375 +25791 0.017486572265625 +25792 0.23602294921875 +25793 0.04815673828125 +25794 0.342987060546875 +25795 0.07122802734375 +25796 0.39520263671875 +25797 0.083160400390625 +25798 0.389373779296875 +25799 0.083221435546875 +25800 0.324249267578125 +25801 0.07110595703125 +25802 0.224090576171875 +25803 0.0516357421875 +25804 0.124267578125 +25805 0.0318603515625 +25806 0.037078857421875 +25807 0.01422119140625 +25808 -0.010101318359375 +25809 0.004241943359375 +25810 -0.019439697265625 +25811 0.001495361328125 +25812 -0.022796630859375 +25813 -0.00030517578125 +25814 -0.001556396484375 +25815 0.002593994140625 +25816 0.056304931640625 +25817 0.0126953125 +25818 0.106719970703125 +25819 0.021240234375 +25820 0.096893310546875 +25821 0.017791748046875 +25822 0.042694091796875 +25823 0.005584716796875 +25824 -0.018035888671875 +25825 -0.0076904296875 +25826 -0.07586669921875 +25827 -0.020111083984375 +25828 -0.11944580078125 +25829 -0.02935791015625 +25830 -0.15972900390625 +25831 -0.03759765625 +25832 -0.202606201171875 +25833 -0.0460205078125 +25834 -0.24859619140625 +25835 -0.054718017578125 +25836 -0.30517578125 +25837 -0.065216064453125 +25838 -0.36212158203125 +25839 -0.0755615234375 +25840 -0.39141845703125 +25841 -0.0802001953125 +25842 -0.35528564453125 +25843 -0.0716552734375 +25844 -0.249969482421875 +25845 -0.04925537109375 +25846 -0.092864990234375 +25847 -0.016571044921875 +25848 0.08905029296875 +25849 0.020904541015625 +25850 0.2352294921875 +25851 0.051025390625 +25852 0.318817138671875 +25853 0.068389892578125 +25854 0.358642578125 +25855 0.07672119140625 +25856 0.347747802734375 +25857 0.07403564453125 +25858 0.28564453125 +25859 0.0595703125 +25860 0.223175048828125 +25861 0.04473876953125 +25862 0.196746826171875 +25863 0.0382080078125 +25864 0.179840087890625 +25865 0.034088134765625 +25866 0.155548095703125 +25867 0.028594970703125 +25868 0.151214599609375 +25869 0.02813720703125 +25870 0.156951904296875 +25871 0.030426025390625 +25872 0.13177490234375 +25873 0.025909423828125 +25874 0.100799560546875 +25875 0.0203857421875 +25876 0.087127685546875 +25877 0.01910400390625 +25878 0.05487060546875 +25879 0.01361083984375 +25880 -0.009002685546875 +25881 0.000762939453125 +25882 -0.10400390625 +25883 -0.0194091796875 +25884 -0.229400634765625 +25885 -0.046875 +25886 -0.35552978515625 +25887 -0.074859619140625 +25888 -0.441925048828125 +25889 -0.094024658203125 +25890 -0.473846435546875 +25891 -0.10101318359375 +25892 -0.464813232421875 +25893 -0.098968505859375 +25894 -0.419097900390625 +25895 -0.0888671875 +25896 -0.334320068359375 +25897 -0.07012939453125 +25898 -0.227935791015625 +25899 -0.0467529296875 +25900 -0.12347412109375 +25901 -0.02410888671875 +25902 -0.02764892578125 +25903 -0.003631591796875 +25904 0.077667236328125 +25905 0.018951416015625 +25906 0.2132568359375 +25907 0.048553466796875 +25908 0.38885498046875 +25909 0.0875244140625 +25910 0.582794189453125 +25911 0.130950927734375 +25912 0.734039306640625 +25913 0.16473388671875 +25914 0.800140380859375 +25915 0.1790771484375 +25916 0.7783203125 +25917 0.17340087890625 +25918 0.6651611328125 +25919 0.146942138671875 +25920 0.45965576171875 +25921 0.0994873046875 +25922 0.199188232421875 +25923 0.039703369140625 +25924 -0.050689697265625 +25925 -0.01727294921875 +25926 -0.23297119140625 +25927 -0.058258056640625 +25928 -0.33013916015625 +25929 -0.07928466796875 +25930 -0.368408203125 +25931 -0.086517333984375 +25932 -0.378936767578125 +25933 -0.0872802734375 +25934 -0.376983642578125 +25935 -0.085235595703125 +25936 -0.37969970703125 +25937 -0.084442138671875 +25938 -0.391510009765625 +25939 -0.085968017578125 +25940 -0.385345458984375 +25941 -0.083587646484375 +25942 -0.3419189453125 +25943 -0.072906494140625 +25944 -0.28289794921875 +25945 -0.0589599609375 +25946 -0.251617431640625 +25947 -0.051788330078125 +25948 -0.266143798828125 +25949 -0.0555419921875 +25950 -0.273345947265625 +25951 -0.05792236328125 +25952 -0.216796875 +25953 -0.0457763671875 +25954 -0.128265380859375 +25955 -0.0263671875 +25956 -0.068145751953125 +25957 -0.013671875 +25958 -0.0430908203125 +25959 -0.009124755859375 +25960 -0.024444580078125 +25961 -0.00604248046875 +25962 0.020721435546875 +25963 0.00323486328125 +25964 0.124481201171875 +25965 0.026214599609375 +25966 0.25787353515625 +25967 0.056243896484375 +25968 0.379119873046875 +25969 0.08367919921875 +25970 0.47991943359375 +25971 0.10662841796875 +25972 0.5281982421875 +25973 0.117645263671875 +25974 0.511138916015625 +25975 0.11376953125 +25976 0.456207275390625 +25977 0.101348876953125 +25978 0.407470703125 +25979 0.090606689453125 +25980 0.383758544921875 +25981 0.085845947265625 +25982 0.35687255859375 +25983 0.080474853515625 +25984 0.31182861328125 +25985 0.07098388671875 +25986 0.250885009765625 +25987 0.057830810546875 +25988 0.1654052734375 +25989 0.038970947265625 +25990 0.035247802734375 +25991 0.009674072265625 +25992 -0.142059326171875 +25993 -0.0306396484375 +25994 -0.33563232421875 +25995 -0.074859619140625 +25996 -0.5345458984375 +25997 -0.120452880859375 +25998 -0.72186279296875 +25999 -0.163543701171875 +26000 -0.836669921875 +26001 -0.189971923828125 +26002 -0.8326416015625 +26003 -0.18902587890625 +26004 -0.7296142578125 +26005 -0.165313720703125 +26006 -0.582550048828125 +26007 -0.131591796875 +26008 -0.440093994140625 +26009 -0.09912109375 +26010 -0.324310302734375 +26011 -0.07293701171875 +26012 -0.20147705078125 +26013 -0.045196533203125 +26014 -0.044647216796875 +26015 -0.00958251953125 +26016 0.103973388671875 +26017 0.02410888671875 +26018 0.202392578125 +26019 0.046173095703125 +26020 0.264495849609375 +26021 0.05987548828125 +26022 0.338897705078125 +26023 0.0765380859375 +26024 0.443817138671875 +26025 0.10040283203125 +26026 0.545074462890625 +26027 0.123565673828125 +26028 0.6173095703125 +26029 0.140167236328125 +26030 0.6524658203125 +26031 0.1483154296875 +26032 0.66339111328125 +26033 0.1510009765625 +26034 0.6561279296875 +26035 0.149627685546875 +26036 0.606781005859375 +26037 0.13861083984375 +26038 0.501190185546875 +26039 0.1146240234375 +26040 0.352783203125 +26041 0.080780029296875 +26042 0.176544189453125 +26043 0.040496826171875 +26044 -0.034820556640625 +26045 -0.007904052734375 +26046 -0.258209228515625 +26047 -0.059051513671875 +26048 -0.44244384765625 +26049 -0.10113525390625 +26050 -0.5753173828125 +26051 -0.131378173828125 +26052 -0.65203857421875 +26053 -0.148681640625 +26054 -0.641632080078125 +26055 -0.145904541015625 +26056 -0.562164306640625 +26057 -0.127288818359375 +26058 -0.458038330078125 +26059 -0.103118896484375 +26060 -0.350555419921875 +26061 -0.078338623046875 +26062 -0.260528564453125 +26063 -0.0577392578125 +26064 -0.192108154296875 +26065 -0.042266845703125 +26066 -0.141937255859375 +26067 -0.031097412109375 +26068 -0.1021728515625 +26069 -0.02239990234375 +26070 -0.062896728515625 +26071 -0.01385498046875 +26072 -0.011932373046875 +26073 -0.0025634765625 +26074 0.062835693359375 +26075 0.0142822265625 +26076 0.148712158203125 +26077 0.033721923828125 +26078 0.241729736328125 +26079 0.05487060546875 +26080 0.34912109375 +26081 0.079437255859375 +26082 0.457305908203125 +26083 0.104278564453125 +26084 0.54388427734375 +26085 0.12420654296875 +26086 0.5728759765625 +26087 0.130889892578125 +26088 0.506591796875 +26089 0.1156005859375 +26090 0.351226806640625 +26091 0.07977294921875 +26092 0.146514892578125 +26093 0.0325927734375 +26094 -0.05523681640625 +26095 -0.0137939453125 +26096 -0.21624755859375 +26097 -0.050689697265625 +26098 -0.334930419921875 +26099 -0.07769775390625 +26100 -0.402984619140625 +26101 -0.092926025390625 +26102 -0.4412841796875 +26103 -0.10125732421875 +26104 -0.49578857421875 +26105 -0.1134033203125 +26106 -0.5601806640625 +26107 -0.1279296875 +26108 -0.600738525390625 +26109 -0.13702392578125 +26110 -0.584228515625 +26111 -0.133026123046875 +26112 -0.47930908203125 +26113 -0.10833740234375 +26114 -0.27935791015625 +26115 -0.06072998046875 +26116 -0.0089111328125 +26117 0.004241943359375 +26118 0.268798828125 +26119 0.070587158203125 +26120 0.482818603515625 +26121 0.1202392578125 +26122 0.60369873046875 +26123 0.145965576171875 +26124 0.650421142578125 +26125 0.153167724609375 +26126 0.66400146484375 +26127 0.15301513671875 +26128 0.6414794921875 +26129 0.144866943359375 +26130 0.572540283203125 +26131 0.1260986328125 +26132 0.498138427734375 +26133 0.107452392578125 +26134 0.439453125 +26135 0.09442138671875 +26136 0.375518798828125 +26137 0.08123779296875 +26138 0.274505615234375 +26139 0.059234619140625 +26140 0.1087646484375 +26141 0.02081298828125 +26142 -0.099395751953125 +26143 -0.028472900390625 +26144 -0.3182373046875 +26145 -0.080535888671875 +26146 -0.5489501953125 +26147 -0.13604736328125 +26148 -0.7738037109375 +26149 -0.190582275390625 +26150 -0.86383056640625 +26151 -0.23046875 +26152 -0.870391845703125 +26153 -0.247100830078125 +26154 -0.86895751953125 +26155 -0.24530029296875 +26156 -0.861053466796875 +26157 -0.22857666015625 +26158 -0.765869140625 +26159 -0.192352294921875 +26160 -0.5301513671875 +26161 -0.13360595703125 +26162 -0.214691162109375 +26163 -0.054046630859375 +26164 0.137359619140625 +26165 0.03509521484375 +26166 0.474822998046875 +26167 0.12054443359375 +26168 0.76239013671875 +26169 0.19317626953125 +26170 0.867462158203125 +26171 0.24615478515625 +26172 0.870361328125 +26173 0.279876708984375 +26174 0.86480712890625 +26175 0.29150390625 +26176 0.831817626953125 +26177 0.28265380859375 +26178 0.677581787109375 +26179 0.259918212890625 +26180 0.495880126953125 +26181 0.225006103515625 +26182 0.30767822265625 +26183 0.182861328125 +26184 0.116180419921875 +26185 0.13409423828125 +26186 -0.110748291015625 +26187 0.070281982421875 +26188 -0.381805419921875 +26189 -0.01043701171875 +26190 -0.6572265625 +26191 -0.096923828125 +26192 -0.857421875 +26193 -0.173553466796875 +26194 -0.870391845703125 +26195 -0.229217529296875 +26196 -0.870391845703125 +26197 -0.26226806640625 +26198 -0.86444091796875 +26199 -0.280029296875 +26200 -0.85723876953125 +26201 -0.29217529296875 +26202 -0.790008544921875 +26203 -0.29400634765625 +26204 -0.62847900390625 +26205 -0.271392822265625 +26206 -0.3956298828125 +26207 -0.223602294921875 +26208 -0.126708984375 +26209 -0.159393310546875 +26210 0.150115966796875 +26211 -0.08599853515625 +26212 0.424041748046875 +26213 -0.006500244140625 +26214 0.670623779296875 +26215 0.072021484375 +26216 0.854522705078125 +26217 0.139434814453125 +26218 0.866485595703125 +26219 0.19122314453125 +26220 0.86920166015625 +26221 0.2235107421875 +26222 0.8653564453125 +26223 0.24127197265625 +26224 0.857147216796875 +26225 0.24822998046875 +26226 0.766845703125 +26227 0.243804931640625 +26228 0.628509521484375 +26229 0.229522705078125 +26230 0.462127685546875 +26231 0.203704833984375 +26232 0.297210693359375 +26233 0.173309326171875 +26234 0.14862060546875 +26235 0.141632080078125 +26236 -0.00537109375 +26237 0.102691650390625 +26238 -0.15753173828125 +26239 0.058502197265625 +26240 -0.31304931640625 +26241 0.008087158203125 +26242 -0.48876953125 +26243 -0.05230712890625 +26244 -0.6416015625 +26245 -0.11041259765625 +26246 -0.751373291015625 +26247 -0.159820556640625 +26248 -0.84619140625 +26249 -0.206787109375 +26250 -0.861297607421875 +26251 -0.24755859375 +26252 -0.863250732421875 +26253 -0.2735595703125 +26254 -0.856597900390625 +26255 -0.276580810546875 +26256 -0.7498779296875 +26257 -0.259918212890625 +26258 -0.624542236328125 +26259 -0.239013671875 +26260 -0.47808837890625 +26261 -0.208099365234375 +26262 -0.253387451171875 +26263 -0.15179443359375 +26264 0.003692626953125 +26265 -0.082183837890625 +26266 0.2257080078125 +26267 -0.017333984375 +26268 0.427154541015625 +26269 0.04608154296875 +26270 0.643218994140625 +26271 0.11669921875 +26272 0.855926513671875 +26273 0.192047119140625 +26274 0.870361328125 +26275 0.256927490234375 +26276 0.870361328125 +26277 0.298370361328125 +26278 0.862762451171875 +26279 0.31842041015625 +26280 0.79669189453125 +26281 0.31640625 +26282 0.595794677734375 +26283 0.289947509765625 +26284 0.362152099609375 +26285 0.246856689453125 +26286 0.1270751953125 +26287 0.194610595703125 +26288 -0.086944580078125 +26289 0.13885498046875 +26290 -0.2784423828125 +26291 0.0802001953125 +26292 -0.484832763671875 +26293 0.009490966796875 +26294 -0.729583740234375 +26295 -0.078338623046875 +26296 -0.86688232421875 +26297 -0.169952392578125 +26298 -0.870391845703125 +26299 -0.24871826171875 +26300 -0.86859130859375 +26301 -0.313385009765625 +26302 -0.86279296875 +26303 -0.36346435546875 +26304 -0.817962646484375 +26305 -0.38958740234375 +26306 -0.6116943359375 +26307 -0.379852294921875 +26308 -0.3128662109375 +26309 -0.332489013671875 +26310 0.039398193359375 +26311 -0.2564697265625 +26312 0.422821044921875 +26313 -0.15716552734375 +26314 0.805145263671875 +26315 -0.043426513671875 +26316 0.870361328125 +26317 0.066680908203125 +26318 0.870361328125 +26319 0.158050537109375 +26320 0.860015869140625 +26321 0.227569580078125 +26322 0.727935791015625 +26323 0.273162841796875 +26324 0.48114013671875 +26325 0.293365478515625 +26326 0.2059326171875 +26327 0.294525146484375 +26328 -0.06103515625 +26329 0.28265380859375 +26330 -0.29913330078125 +26331 0.26043701171875 +26332 -0.516204833984375 +26333 0.224090576171875 +26334 -0.7252197265625 +26335 0.169647216796875 +26336 -0.85980224609375 +26337 0.103759765625 +26338 -0.870391845703125 +26339 0.035614013671875 +26340 -0.870391845703125 +26341 -0.02685546875 +26342 -0.858062744140625 +26343 -0.070648193359375 +26344 -0.673004150390625 +26345 -0.094512939453125 +26346 -0.42694091796875 +26347 -0.112152099609375 +26348 -0.2100830078125 +26349 -0.135162353515625 +26350 -0.0362548828125 +26351 -0.162872314453125 +26352 0.10943603515625 +26353 -0.187530517578125 +26354 0.23516845703125 +26355 -0.203765869140625 +26356 0.373687744140625 +26357 -0.20068359375 +26358 0.517791748046875 +26359 -0.178802490234375 +26360 0.602783203125 +26361 -0.15484619140625 +26362 0.635711669921875 +26363 -0.127532958984375 +26364 0.655181884765625 +26365 -0.088165283203125 +26366 0.65948486328125 +26367 -0.039520263671875 +26368 0.651275634765625 +26369 0.016387939453125 +26370 0.61846923828125 +26371 0.0728759765625 +26372 0.53753662109375 +26373 0.11944580078125 +26374 0.404144287109375 +26375 0.15081787109375 +26376 0.22186279296875 +26377 0.164154052734375 +26378 0.003997802734375 +26379 0.1597900390625 +26380 -0.22100830078125 +26381 0.143035888671875 +26382 -0.42449951171875 +26383 0.119903564453125 +26384 -0.579833984375 +26385 0.09661865234375 +26386 -0.641876220703125 +26387 0.085662841796875 +26388 -0.6177978515625 +26389 0.084991455078125 +26390 -0.575531005859375 +26391 0.0753173828125 +26392 -0.526336669921875 +26393 0.054901123046875 +26394 -0.42645263671875 +26395 0.03900146484375 +26396 -0.2581787109375 +26397 0.035614013671875 +26398 -0.068695068359375 +26399 0.03387451171875 +26400 0.09222412109375 +26401 0.02239990234375 +26402 0.232147216796875 +26403 0.00665283203125 +26404 0.3509521484375 +26405 -0.010284423828125 +26406 0.410064697265625 +26407 -0.037139892578125 +26408 0.372955322265625 +26409 -0.08251953125 +26410 0.2554931640625 +26411 -0.14013671875 +26412 0.10711669921875 +26413 -0.1944580078125 +26414 -0.052886962890625 +26415 -0.23956298828125 +26416 -0.186279296875 +26417 -0.264617919921875 +26418 -0.23291015625 +26419 -0.252960205078125 +26420 -0.209442138671875 +26421 -0.21124267578125 +26422 -0.174163818359375 +26423 -0.158843994140625 +26424 -0.126739501953125 +26425 -0.09820556640625 +26426 -0.048126220703125 +26427 -0.0263671875 +26428 0.0426025390625 +26429 0.048309326171875 +26430 0.10748291015625 +26431 0.11199951171875 +26432 0.1409912109375 +26433 0.1607666015625 +26434 0.19708251953125 +26435 0.208587646484375 +26436 0.273651123046875 +26437 0.253387451171875 +26438 0.31768798828125 +26439 0.278533935546875 +26440 0.341094970703125 +26441 0.287139892578125 +26442 0.368011474609375 +26443 0.28662109375 +26444 0.37249755859375 +26445 0.27001953125 +26446 0.30072021484375 +26447 0.22265625 +26448 0.1517333984375 +26449 0.1458740234375 +26450 -0.01470947265625 +26451 0.059326171875 +26452 -0.1883544921875 +26453 -0.031707763671875 +26454 -0.372711181640625 +26455 -0.12603759765625 +26456 -0.51397705078125 +26457 -0.205596923828125 +26458 -0.57177734375 +26459 -0.25640869140625 +26460 -0.53948974609375 +26461 -0.274810791015625 +26462 -0.43511962890625 +26463 -0.2647705078125 +26464 -0.2962646484375 +26465 -0.236480712890625 +26466 -0.161102294921875 +26467 -0.2008056640625 +26468 -0.0435791015625 +26469 -0.161865234375 +26470 0.060394287109375 +26471 -0.118896484375 +26472 0.13665771484375 +26473 -0.076995849609375 +26474 0.170135498046875 +26475 -0.041900634765625 +26476 0.16552734375 +26477 -0.01373291015625 +26478 0.15728759765625 +26479 0.015899658203125 +26480 0.150787353515625 +26481 0.04681396484375 +26482 0.12200927734375 +26483 0.070068359375 +26484 0.080108642578125 +26485 0.086669921875 +26486 0.05126953125 +26487 0.102874755859375 +26488 0.062896728515625 +26489 0.125579833984375 +26490 0.09271240234375 +26491 0.14727783203125 +26492 0.092987060546875 +26493 0.1533203125 +26494 0.07855224609375 +26495 0.147979736328125 +26496 0.06427001953125 +26497 0.13592529296875 +26498 0.0347900390625 +26499 0.11322021484375 +26500 -0.01171875 +26501 0.08026123046875 +26502 -0.056060791015625 +26503 0.0439453125 +26504 -0.055511474609375 +26505 0.018280029296875 +26506 -0.010467529296875 +26507 0.004638671875 +26508 0.02508544921875 +26509 -0.01141357421875 +26510 0.025665283203125 +26511 -0.035980224609375 +26512 0.017333984375 +26513 -0.060089111328125 +26514 0.00189208984375 +26515 -0.08209228515625 +26516 -0.03173828125 +26517 -0.104461669921875 +26518 -0.071502685546875 +26519 -0.12310791015625 +26520 -0.13543701171875 +26521 -0.14312744140625 +26522 -0.219970703125 +26523 -0.16357421875 +26524 -0.300506591796875 +26525 -0.17755126953125 +26526 -0.376312255859375 +26527 -0.185546875 +26528 -0.416107177734375 +26529 -0.179229736328125 +26530 -0.371124267578125 +26531 -0.145263671875 +26532 -0.242279052734375 +26533 -0.085113525390625 +26534 -0.069732666015625 +26535 -0.01190185546875 +26536 0.125640869140625 +26537 0.06695556640625 +26538 0.31268310546875 +26539 0.141082763671875 +26540 0.45501708984375 +26541 0.198760986328125 +26542 0.554779052734375 +26543 0.239898681640625 +26544 0.61065673828125 +26545 0.263580322265625 +26546 0.610931396484375 +26547 0.266082763671875 +26548 0.531463623046875 +26549 0.240264892578125 +26550 0.3883056640625 +26551 0.191162109375 +26552 0.23468017578125 +26553 0.135009765625 +26554 0.095245361328125 +26555 0.079803466796875 +26556 -0.00396728515625 +26557 0.034088134765625 +26558 -0.04852294921875 +26559 0.003082275390625 +26560 -0.055145263671875 +26561 -0.017120361328125 +26562 -0.0758056640625 +26563 -0.0408935546875 +26564 -0.138702392578125 +26565 -0.07562255859375 +26566 -0.209197998046875 +26567 -0.110260009765625 +26568 -0.289031982421875 +26569 -0.14459228515625 +26570 -0.37884521484375 +26571 -0.1783447265625 +26572 -0.456329345703125 +26573 -0.204620361328125 +26574 -0.51641845703125 +26575 -0.221832275390625 +26576 -0.519287109375 +26577 -0.21832275390625 +26578 -0.458251953125 +26579 -0.192474365234375 +26580 -0.384796142578125 +26581 -0.160064697265625 +26582 -0.323699951171875 +26583 -0.12908935546875 +26584 -0.269287109375 +26585 -0.098602294921875 +26586 -0.1951904296875 +26587 -0.061614990234375 +26588 -0.100006103515625 +26589 -0.018585205078125 +26590 -0.01055908203125 +26591 0.021728515625 +26592 0.1033935546875 +26593 0.067535400390625 +26594 0.24908447265625 +26595 0.120361328125 +26596 0.373199462890625 +26597 0.163970947265625 +26598 0.45806884765625 +26599 0.192840576171875 +26600 0.511474609375 +26601 0.20916748046875 +26602 0.565399169921875 +26603 0.222503662109375 +26604 0.61138916015625 +26605 0.230560302734375 +26606 0.5897216796875 +26607 0.216033935546875 +26608 0.4906005859375 +26609 0.176544189453125 +26610 0.33148193359375 +26611 0.117889404296875 +26612 0.147796630859375 +26613 0.05120849609375 +26614 -0.01873779296875 +26615 -0.01043701171875 +26616 -0.140289306640625 +26617 -0.05810546875 +26618 -0.191986083984375 +26619 -0.0838623046875 +26620 -0.184295654296875 +26621 -0.090240478515625 +26622 -0.161834716796875 +26623 -0.09002685546875 +26624 -0.166595458984375 +26625 -0.095367431640625 +26626 -0.19390869140625 +26627 -0.104766845703125 +26628 -0.22442626953125 +26629 -0.11248779296875 +26630 -0.279754638671875 +26631 -0.125152587890625 +26632 -0.3389892578125 +26633 -0.136810302734375 +26634 -0.3543701171875 +26635 -0.133514404296875 +26636 -0.348175048828125 +26637 -0.122467041015625 +26638 -0.32598876953125 +26639 -0.105865478515625 +26640 -0.2581787109375 +26641 -0.075408935546875 +26642 -0.139801025390625 +26643 -0.030181884765625 +26644 0.014617919921875 +26645 0.024932861328125 +26646 0.144378662109375 +26647 0.071258544921875 +26648 0.221038818359375 +26649 0.09991455078125 +26650 0.27069091796875 +26651 0.118438720703125 +26652 0.294036865234375 +26653 0.126953125 +26654 0.311767578125 +26655 0.131622314453125 +26656 0.339141845703125 +26657 0.137237548828125 +26658 0.360260009765625 +26659 0.1395263671875 +26660 0.360504150390625 +26661 0.134307861328125 +26662 0.308380126953125 +26663 0.1114501953125 +26664 0.18170166015625 +26665 0.063934326171875 +26666 0.0047607421875 +26667 0.0 +26668 -0.17559814453125 +26669 -0.064727783203125 +26670 -0.3143310546875 +26671 -0.115234375 +26672 -0.36785888671875 +26673 -0.136993408203125 +26674 -0.36248779296875 +26675 -0.138427734375 +26676 -0.343536376953125 +26677 -0.13427734375 +26678 -0.3018798828125 +26679 -0.1214599609375 +26680 -0.231414794921875 +26681 -0.09796142578125 +26682 -0.117645263671875 +26683 -0.05908203125 +26684 0.007049560546875 +26685 -0.01556396484375 +26686 0.087982177734375 +26687 0.01446533203125 +26688 0.13946533203125 +26689 0.0355224609375 +26690 0.17425537109375 +26691 0.051544189453125 +26692 0.188201904296875 +26693 0.060882568359375 +26694 0.171234130859375 +26695 0.05999755859375 +26696 0.118438720703125 +26697 0.0469970703125 +26698 0.05706787109375 +26699 0.0306396484375 +26700 -0.010711669921875 +26701 0.01141357421875 +26702 -0.0914306640625 +26703 -0.012908935546875 +26704 -0.162322998046875 +26705 -0.03497314453125 +26706 -0.194549560546875 +26707 -0.045379638671875 +26708 -0.1492919921875 +26709 -0.0313720703125 +26710 -0.02166748046875 +26711 0.00872802734375 +26712 0.124053955078125 +26713 0.053955078125 +26714 0.211151123046875 +26715 0.07928466796875 +26716 0.240447998046875 +26717 0.085205078125 +26718 0.242218017578125 +26719 0.081817626953125 +26720 0.2257080078125 +26721 0.07244873046875 +26722 0.194366455078125 +26723 0.05841064453125 +26724 0.115509033203125 +26725 0.0291748046875 +26726 0.0128173828125 +26727 -0.007232666015625 +26728 -0.053802490234375 +26729 -0.03106689453125 +26730 -0.110626220703125 +26731 -0.050872802734375 +26732 -0.199493408203125 +26733 -0.080352783203125 +26734 -0.29437255859375 +26735 -0.1109619140625 +26736 -0.33221435546875 +26737 -0.1220703125 +26738 -0.27972412109375 +26739 -0.10284423828125 +26740 -0.185333251953125 +26741 -0.069305419921875 +26742 -0.128204345703125 +26743 -0.047576904296875 +26744 -0.115692138671875 +26745 -0.040252685546875 +26746 -0.116455078125 +26747 -0.0372314453125 +26748 -0.105926513671875 +26749 -0.0306396484375 +26750 -0.053955078125 +26751 -0.010772705078125 +26752 0.048797607421875 +26753 0.0252685546875 +26754 0.157318115234375 +26755 0.0626220703125 +26756 0.212005615234375 +26757 0.0816650390625 +26758 0.218475341796875 +26759 0.084197998046875 +26760 0.23724365234375 +26761 0.090087890625 +26762 0.30535888671875 +26763 0.11151123046875 +26764 0.38128662109375 +26765 0.134918212890625 +26766 0.404449462890625 +26767 0.140472412109375 +26768 0.3944091796875 +26769 0.134765625 +26770 0.3885498046875 +26771 0.13018798828125 +26772 0.362640380859375 +26773 0.11895751953125 +26774 0.27362060546875 +26775 0.087127685546875 +26776 0.11712646484375 +26777 0.03338623046875 +26778 -0.054901123046875 +26779 -0.02508544921875 +26780 -0.19085693359375 +26781 -0.071258544921875 +26782 -0.28570556640625 +26783 -0.103424072265625 +26784 -0.339263916015625 +26785 -0.1214599609375 +26786 -0.3775634765625 +26787 -0.1339111328125 +26788 -0.445709228515625 +26789 -0.15557861328125 +26790 -0.535064697265625 +26791 -0.183685302734375 +26792 -0.629058837890625 +26793 -0.212860107421875 +26794 -0.697601318359375 +26795 -0.233367919921875 +26796 -0.70391845703125 +26797 -0.233245849609375 +26798 -0.6424560546875 +26799 -0.2108154296875 +26800 -0.491241455078125 +26801 -0.15899658203125 +26802 -0.265716552734375 +26803 -0.08294677734375 +26804 -0.023712158203125 +26805 -0.00177001953125 +26806 0.201751708984375 +26807 0.073577880859375 +26808 0.375823974609375 +26809 0.131622314453125 +26810 0.485076904296875 +26811 0.16790771484375 +26812 0.56884765625 +26813 0.195343017578125 +26814 0.634765625 +26815 0.2164306640625 +26816 0.63763427734375 +26817 0.2164306640625 +26818 0.5660400390625 +26819 0.191650390625 +26820 0.4720458984375 +26821 0.159210205078125 +26822 0.40692138671875 +26823 0.13604736328125 +26824 0.3778076171875 +26825 0.124603271484375 +26826 0.376953125 +26827 0.1224365234375 +26828 0.371978759765625 +26829 0.1190185546875 +26830 0.313140869140625 +26831 0.098114013671875 +26832 0.184417724609375 +26833 0.0545654296875 +26834 0.011199951171875 +26835 -0.003204345703125 +26836 -0.171051025390625 +26837 -0.063507080078125 +26838 -0.33740234375 +26839 -0.118133544921875 +26840 -0.47198486328125 +26841 -0.161895751953125 +26842 -0.560394287109375 +26843 -0.19012451171875 +26844 -0.58056640625 +26845 -0.195648193359375 +26846 -0.54754638671875 +26847 -0.1834716796875 +26848 -0.508575439453125 +26849 -0.169189453125 +26850 -0.459503173828125 +26851 -0.1514892578125 +26852 -0.394378662109375 +26853 -0.128509521484375 +26854 -0.35260009765625 +26855 -0.113250732421875 +26856 -0.31170654296875 +26857 -0.098419189453125 +26858 -0.197418212890625 +26859 -0.059722900390625 +26860 -0.007965087890625 +26861 0.0032958984375 +26862 0.207489013671875 +26863 0.074462890625 +26864 0.409210205078125 +26865 0.1407470703125 +26866 0.57208251953125 +26867 0.19390869140625 +26868 0.66595458984375 +26869 0.22412109375 +26870 0.65875244140625 +26871 0.22088623046875 +26872 0.56744384765625 +26873 0.1898193359375 +26874 0.431396484375 +26875 0.143890380859375 +26876 0.29443359375 +26877 0.097564697265625 +26878 0.182464599609375 +26879 0.059417724609375 +26880 0.06365966796875 +26881 0.018585205078125 +26882 -0.075958251953125 +26883 -0.029449462890625 +26884 -0.189422607421875 +26885 -0.067840576171875 +26886 -0.271942138671875 +26887 -0.0950927734375 +26888 -0.342529296875 +26889 -0.118255615234375 +26890 -0.364166259765625 +26891 -0.124176025390625 +26892 -0.327239990234375 +26893 -0.1094970703125 +26894 -0.2769775390625 +26895 -0.090545654296875 +26896 -0.253692626953125 +26897 -0.081878662109375 +26898 -0.24365234375 +26899 -0.078521728515625 +26900 -0.1983642578125 +26901 -0.06298828125 +26902 -0.116241455078125 +26903 -0.034637451171875 +26904 -0.036834716796875 +26905 -0.00762939453125 +26906 0.034881591796875 +26907 0.016326904296875 +26908 0.09124755859375 +26909 0.034576416015625 +26910 0.10888671875 +26911 0.038848876953125 +26912 0.125518798828125 +26913 0.0428466796875 +26914 0.15771484375 +26915 0.052642822265625 +26916 0.17828369140625 +26917 0.058502197265625 +26918 0.17108154296875 +26919 0.054718017578125 +26920 0.129974365234375 +26921 0.039154052734375 +26922 0.082427978515625 +26923 0.021728515625 +26924 0.027679443359375 +26925 0.002166748046875 +26926 -0.065643310546875 +26927 -0.03082275390625 +26928 -0.15936279296875 +26929 -0.063568115234375 +26930 -0.21307373046875 +26931 -0.081573486328125 +26932 -0.234649658203125 +26933 -0.0877685546875 +26934 -0.2001953125 +26935 -0.073638916015625 +26936 -0.119171142578125 +26937 -0.042694091796875 +26938 -0.024749755859375 +26939 -0.0069580078125 +26940 0.085784912109375 +26941 0.034423828125 +26942 0.178131103515625 +26943 0.069000244140625 +26944 0.215576171875 +26945 0.08349609375 +26946 0.211456298828125 +26947 0.082672119140625 +26948 0.17523193359375 +26949 0.069915771484375 +26950 0.128753662109375 +26951 0.0531005859375 +26952 0.1019287109375 +26953 0.042999267578125 +26954 0.0743408203125 +26955 0.03228759765625 +26956 0.04327392578125 +26957 0.02008056640625 +26958 0.038177490234375 +26959 0.016998291015625 +26960 0.076263427734375 +26961 0.029296875 +26962 0.14105224609375 +26963 0.051116943359375 +26964 0.186431884765625 +26965 0.065948486328125 +26966 0.188812255859375 +26967 0.065399169921875 +26968 0.1390380859375 +26969 0.0462646484375 +26970 0.041778564453125 +26971 0.010284423828125 +26972 -0.079437255859375 +26973 -0.03399658203125 +26974 -0.219390869140625 +26975 -0.084716796875 +26976 -0.367828369140625 +26977 -0.138153076171875 +26978 -0.494873046875 +26979 -0.18353271484375 +26980 -0.556243896484375 +26981 -0.2049560546875 +26982 -0.508697509765625 +26983 -0.186920166015625 +26984 -0.3756103515625 +26985 -0.13787841796875 +26986 -0.218902587890625 +26987 -0.0802001953125 +26988 -0.063751220703125 +26989 -0.023040771484375 +26990 0.091552734375 +26991 0.03411865234375 +26992 0.23602294921875 +26993 0.0872802734375 +26994 0.342987060546875 +26995 0.12677001953125 +26996 0.39520263671875 +26997 0.1463623046875 +26998 0.389373779296875 +26999 0.144805908203125 +27000 0.324249267578125 +27001 0.12164306640625 +27002 0.224090576171875 +27003 0.085601806640625 +27004 0.124267578125 +27005 0.0494384765625 +27006 0.037078857421875 +27007 0.017578125 +27008 -0.010101318359375 +27009 -9.1552734375e-05 +27010 -0.019439697265625 +27011 -0.0042724609375 +27012 -0.022796630859375 +27013 -0.00640869140625 +27014 -0.001556396484375 +27015 0.000244140625 +27016 0.056304931640625 +27017 0.020050048828125 +27018 0.106719970703125 +27019 0.03717041015625 +27020 0.096893310546875 +27021 0.032684326171875 +27022 0.042694091796875 +27023 0.012359619140625 +27024 -0.018035888671875 +27025 -0.010101318359375 +27026 -0.07586669921875 +27027 -0.031280517578125 +27028 -0.11944580078125 +27029 -0.047088623046875 +27030 -0.15972900390625 +27031 -0.06146240234375 +27032 -0.202606201171875 +27033 -0.076507568359375 +27034 -0.24859619140625 +27035 -0.092437744140625 +27036 -0.30517578125 +27037 -0.111968994140625 +27038 -0.36212158203125 +27039 -0.131500244140625 +27040 -0.39141845703125 +27041 -0.14105224609375 +27042 -0.35528564453125 +27043 -0.1270751953125 +27044 -0.249969482421875 +27045 -0.088226318359375 +27046 -0.092864990234375 +27047 -0.030853271484375 +27048 0.08905029296875 +27049 0.0352783203125 +27050 0.2352294921875 +27051 0.08831787109375 +27052 0.318817138671875 +27053 0.118621826171875 +27054 0.358642578125 +27055 0.132965087890625 +27056 0.347747802734375 +27057 0.128814697265625 +27058 0.28564453125 +27059 0.106048583984375 +27060 0.223175048828125 +27061 0.0830078125 +27062 0.196746826171875 +27063 0.07281494140625 +27064 0.179840087890625 +27065 0.06597900390625 +27066 0.155548095703125 +27067 0.056427001953125 +27068 0.151214599609375 +27069 0.0540771484375 +27070 0.156951904296875 +27071 0.055419921875 +27072 0.13177490234375 +27073 0.045684814453125 +27074 0.100799560546875 +27075 0.033966064453125 +27076 0.087127685546875 +27077 0.028594970703125 +27078 0.05487060546875 +27079 0.016693115234375 +27080 -0.009002685546875 +27081 -0.00640869140625 +27082 -0.10400390625 +27083 -0.040496826171875 +27084 -0.229400634765625 +27085 -0.0853271484375 +27086 -0.35552978515625 +27087 -0.130279541015625 +27088 -0.441925048828125 +27089 -0.160797119140625 +27090 -0.473846435546875 +27091 -0.171600341796875 +27092 -0.464813232421875 +27093 -0.1676025390625 +27094 -0.419097900390625 +27095 -0.150390625 +27096 -0.334320068359375 +27097 -0.119140625 +27098 -0.227935791015625 +27099 -0.080169677734375 +27100 -0.12347412109375 +27101 -0.0419921875 +27102 -0.02764892578125 +27103 -0.007049560546875 +27104 0.077667236328125 +27105 0.0311279296875 +27106 0.2132568359375 +27107 0.08001708984375 +27108 0.38885498046875 +27109 0.14312744140625 +27110 0.582794189453125 +27111 0.212677001953125 +27112 0.734039306640625 +27113 0.2667236328125 +27114 0.800140380859375 +27115 0.28997802734375 +27116 0.7783203125 +27117 0.281494140625 +27118 0.6651611328125 +27119 0.240081787109375 +27120 0.45965576171875 +27121 0.165435791015625 +27122 0.199188232421875 +27123 0.071044921875 +27124 -0.050689697265625 +27125 -0.01947021484375 +27126 -0.23297119140625 +27127 -0.085540771484375 +27128 -0.33013916015625 +27129 -0.120880126953125 +27130 -0.368408203125 +27131 -0.1348876953125 +27132 -0.378936767578125 +27133 -0.13873291015625 +27134 -0.376983642578125 +27135 -0.137969970703125 +27136 -0.37969970703125 +27137 -0.13885498046875 +27138 -0.391510009765625 +27139 -0.1429443359375 +27140 -0.385345458984375 +27141 -0.139923095703125 +27142 -0.3419189453125 +27143 -0.122467041015625 +27144 -0.28289794921875 +27145 -0.099273681640625 +27146 -0.251617431640625 +27147 -0.087432861328125 +27148 -0.266143798828125 +27149 -0.094085693359375 +27150 -0.273345947265625 +27151 -0.098419189453125 +27152 -0.216796875 +27153 -0.0782470703125 +27154 -0.128265380859375 +27155 -0.0458984375 +27156 -0.068145751953125 +27157 -0.02490234375 +27158 -0.0430908203125 +27159 -0.017730712890625 +27160 -0.024444580078125 +27161 -0.01300048828125 +27162 0.020721435546875 +27163 0.0023193359375 +27164 0.124481201171875 +27165 0.040924072265625 +27166 0.25787353515625 +27167 0.091583251953125 +27168 0.379119873046875 +27169 0.138031005859375 +27170 0.47991943359375 +27171 0.177032470703125 +27172 0.5281982421875 +27173 0.196044921875 +27174 0.511138916015625 +27175 0.190032958984375 +27176 0.456207275390625 +27177 0.169708251953125 +27178 0.407470703125 +27179 0.15228271484375 +27180 0.383758544921875 +27181 0.14501953125 +27182 0.35687255859375 +27183 0.136749267578125 +27184 0.31182861328125 +27185 0.1214599609375 +27186 0.250885009765625 +27187 0.09991455078125 +27188 0.1654052734375 +27189 0.068572998046875 +27190 0.035247802734375 +27191 0.01947021484375 +27192 -0.142059326171875 +27193 -0.0484619140625 +27194 -0.33563232421875 +27195 -0.123199462890625 +27196 -0.5345458984375 +27197 -0.20050048828125 +27198 -0.72186279296875 +27199 -0.27374267578125 +27200 -0.836669921875 +27201 -0.31903076171875 +27202 -0.8326416015625 +27203 -0.31817626953125 +27204 -0.7296142578125 +27205 -0.278900146484375 +27206 -0.582550048828125 +27207 -0.22271728515625 +27208 -0.440093994140625 +27209 -0.1685791015625 +27210 -0.324310302734375 +27211 -0.12506103515625 +27212 -0.20147705078125 +27213 -0.078826904296875 +27214 -0.044647216796875 +27215 -0.019195556640625 +27216 0.103973388671875 +27217 0.037353515625 +27218 0.202392578125 +27219 0.074462890625 +27220 0.264495849609375 +27221 0.097625732421875 +27222 0.338897705078125 +27223 0.125946044921875 +27224 0.443817138671875 +27225 0.1666259765625 +27226 0.545074462890625 +27227 0.206268310546875 +27228 0.6173095703125 +27229 0.23492431640625 +27230 0.6524658203125 +27231 0.249420166015625 +27232 0.66339111328125 +27233 0.254730224609375 +27234 0.6561279296875 +27235 0.253173828125 +27236 0.606781005859375 +27237 0.23529052734375 +27238 0.501190185546875 +27239 0.195465087890625 +27240 0.352783203125 +27241 0.13885498046875 +27242 0.176544189453125 +27243 0.071258544921875 +27244 -0.034820556640625 +27245 -0.01025390625 +27246 -0.258209228515625 +27247 -0.0966796875 +27248 -0.44244384765625 +27249 -0.16802978515625 +27250 -0.5753173828125 +27251 -0.21954345703125 +27252 -0.65203857421875 +27253 -0.249359130859375 +27254 -0.641632080078125 +27255 -0.245330810546875 +27256 -0.562164306640625 +27257 -0.21453857421875 +27258 -0.458038330078125 +27259 -0.17437744140625 +27260 -0.350555419921875 +27261 -0.133148193359375 +27262 -0.260528564453125 +27263 -0.098968505859375 +27264 -0.192108154296875 +27265 -0.073394775390625 +27266 -0.141937255859375 +27267 -0.055023193359375 +27268 -0.1021728515625 +27269 -0.04071044921875 +27270 -0.062896728515625 +27271 -0.0264892578125 +27272 -0.011932373046875 +27273 -0.007537841796875 +27274 0.062835693359375 +27275 0.02093505859375 +27276 0.148712158203125 +27277 0.05401611328125 +27278 0.241729736328125 +27279 0.09014892578125 +27280 0.34912109375 +27281 0.132171630859375 +27282 0.457305908203125 +27283 0.174774169921875 +27284 0.54388427734375 +27285 0.209136962890625 +27286 0.5728759765625 +27287 0.22113037109375 +27288 0.506591796875 +27289 0.195953369140625 +27290 0.351226806640625 +27291 0.135955810546875 +27292 0.146514892578125 +27293 0.056671142578125 +27294 -0.05523681640625 +27295 -0.021392822265625 +27296 -0.21624755859375 +27297 -0.083526611328125 +27298 -0.334930419921875 +27299 -0.129150390625 +27300 -0.402984619140625 +27301 -0.155029296875 +27302 -0.4412841796875 +27303 -0.16937255859375 +27304 -0.49578857421875 +27305 -0.190277099609375 +27306 -0.5601806640625 +27307 -0.21527099609375 +27308 -0.600738525390625 +27309 -0.23114013671875 +27310 -0.584228515625 +27311 -0.224884033203125 +27312 -0.47930908203125 +27313 -0.18414306640625 +27314 -0.27935791015625 +27315 -0.1063232421875 +27316 -0.0089111328125 +27317 -0.00103759765625 +27318 0.268798828125 +27319 0.106964111328125 +27320 0.482818603515625 +27321 0.189910888671875 +27322 0.60369873046875 +27323 0.236328125 +27324 0.650421142578125 +27325 0.253692626953125 +27326 0.66400146484375 +27327 0.258148193359375 +27328 0.6414794921875 +27329 0.24859619140625 +27330 0.572540283203125 +27331 0.221038818359375 +27332 0.498138427734375 +27333 0.1915283203125 +27334 0.439453125 +27335 0.16839599609375 +27336 0.375518798828125 +27337 0.1434326171875 +27338 0.274505615234375 +27339 0.104156494140625 +27340 0.1087646484375 +27341 0.0396728515625 +27342 -0.099395751953125 +27343 -0.041290283203125 +27344 -0.3182373046875 +27345 -0.126312255859375 +27346 -0.5489501953125 +27347 -0.21588134765625 +27348 -0.7738037109375 +27349 -0.3031005859375 +27350 -0.86383056640625 +27351 -0.367279052734375 +27352 -0.870391845703125 +27353 -0.39544677734375 +27354 -0.86895751953125 +27355 -0.394561767578125 +27356 -0.861053466796875 +27357 -0.36981201171875 +27358 -0.765869140625 +27359 -0.314453125 +27360 -0.5301513671875 +27361 -0.22412109375 +27362 -0.214691162109375 +27363 -0.101593017578125 +27364 0.137359619140625 +27365 0.036285400390625 +27366 0.474822998046875 +27367 0.16937255859375 +27368 0.76239013671875 +27369 0.2838134765625 +27370 0.867462158203125 +27371 0.3690185546875 +27372 0.870361328125 +27373 0.42523193359375 +27374 0.86480712890625 +27375 0.44793701171875 +27376 0.831817626953125 +27377 0.439300537109375 +27378 0.677581787109375 +27379 0.408905029296875 +27380 0.495880126953125 +27381 0.359039306640625 +27382 0.30767822265625 +27383 0.297027587890625 +27384 0.116180419921875 +27385 0.223785400390625 +27386 -0.110748291015625 +27387 0.12689208984375 +27388 -0.381805419921875 +27389 0.003662109375 +27390 -0.6572265625 +27391 -0.129119873046875 +27392 -0.857421875 +27393 -0.247833251953125 +27394 -0.870391845703125 +27395 -0.335540771484375 +27396 -0.870391845703125 +27397 -0.389617919921875 +27398 -0.86444091796875 +27399 -0.4215087890625 +27400 -0.85723876953125 +27401 -0.446197509765625 +27402 -0.790008544921875 +27403 -0.4556884765625 +27404 -0.62847900390625 +27405 -0.4267578125 +27406 -0.3956298828125 +27407 -0.35772705078125 +27408 -0.126708984375 +27409 -0.262176513671875 +27410 0.150115966796875 +27411 -0.151275634765625 +27412 0.424041748046875 +27413 -0.02960205078125 +27414 0.670623779296875 +27415 0.091827392578125 +27416 0.854522705078125 +27417 0.19696044921875 +27418 0.866485595703125 +27419 0.278656005859375 +27420 0.86920166015625 +27421 0.3306884765625 +27422 0.8653564453125 +27423 0.3609619140625 +27424 0.857147216796875 +27425 0.37530517578125 +27426 0.766845703125 +27427 0.37255859375 +27428 0.628509521484375 +27429 0.3548583984375 +27430 0.462127685546875 +27431 0.31927490234375 +27432 0.297210693359375 +27433 0.276580810546875 +27434 0.14862060546875 +27435 0.231781005859375 +27436 -0.00537109375 +27437 0.174957275390625 +27438 -0.15753173828125 +27439 0.108978271484375 +27440 -0.31304931640625 +27441 0.032012939453125 +27442 -0.48876953125 +27443 -0.062164306640625 +27444 -0.6416015625 +27445 -0.153961181640625 +27446 -0.751373291015625 +27447 -0.233123779296875 +27448 -0.84619140625 +27449 -0.30963134765625 +27450 -0.861297607421875 +27451 -0.377410888671875 +27452 -0.863250732421875 +27453 -0.4224853515625 +27454 -0.856597900390625 +27455 -0.43145751953125 +27456 -0.7498779296875 +27457 -0.40948486328125 +27458 -0.624542236328125 +27459 -0.3809814453125 +27460 -0.47808837890625 +27461 -0.336456298828125 +27462 -0.253387451171875 +27463 -0.250946044921875 +27464 0.003692626953125 +27465 -0.1435546875 +27466 0.2257080078125 +27467 -0.043060302734375 +27468 0.427154541015625 +27469 0.05609130859375 +27470 0.643218994140625 +27471 0.1678466796875 +27472 0.855926513671875 +27473 0.288330078125 +27474 0.870361328125 +27475 0.39312744140625 +27476 0.870361328125 +27477 0.461334228515625 +27478 0.862762451171875 +27479 0.49609375 +27480 0.79669189453125 +27481 0.49615478515625 +27482 0.595794677734375 +27483 0.45751953125 +27484 0.362152099609375 +27485 0.39251708984375 +27486 0.1270751953125 +27487 0.312896728515625 +27488 -0.086944580078125 +27489 0.227508544921875 +27490 -0.2784423828125 +27491 0.1370849609375 +27492 -0.484832763671875 +27493 0.02667236328125 +27494 -0.729583740234375 +27495 -0.111968994140625 +27496 -0.86688232421875 +27497 -0.257568359375 +27498 -0.870391845703125 +27499 -0.3834228515625 +27500 -0.86859130859375 +27501 -0.487548828125 +27502 -0.86279296875 +27503 -0.569122314453125 +27504 -0.817962646484375 +27505 -0.613006591796875 +27506 -0.6116943359375 +27507 -0.599945068359375 +27508 -0.3128662109375 +27509 -0.526947021484375 +27510 0.039398193359375 +27511 -0.408233642578125 +27512 0.422821044921875 +27513 -0.252227783203125 +27514 0.805145263671875 +27515 -0.072967529296875 +27516 0.870361328125 +27517 0.100738525390625 +27518 0.870361328125 +27519 0.24481201171875 +27520 0.860015869140625 +27521 0.354339599609375 +27522 0.727935791015625 +27523 0.426116943359375 +27524 0.48114013671875 +27525 0.45782470703125 +27526 0.2059326171875 +27527 0.459716796875 +27528 -0.06103515625 +27529 0.441375732421875 +27530 -0.29913330078125 +27531 0.407073974609375 +27532 -0.516204833984375 +27533 0.35064697265625 +27534 -0.7252197265625 +27535 0.26556396484375 +27536 -0.85980224609375 +27537 0.162445068359375 +27538 -0.870391845703125 +27539 0.05584716796875 +27540 -0.870391845703125 +27541 -0.0416259765625 +27542 -0.858062744140625 +27543 -0.1092529296875 +27544 -0.673004150390625 +27545 -0.145172119140625 +27546 -0.42694091796875 +27547 -0.171539306640625 +27548 -0.2100830078125 +27549 -0.20709228515625 +27550 -0.0362548828125 +27551 -0.250762939453125 +27552 0.10943603515625 +27553 -0.290130615234375 +27554 0.23516845703125 +27555 -0.316680908203125 +27556 0.373687744140625 +27557 -0.312774658203125 +27558 0.517791748046875 +27559 -0.279205322265625 +27560 0.602783203125 +27561 -0.242706298828125 +27562 0.635711669921875 +27563 -0.201080322265625 +27564 0.655181884765625 +27565 -0.140289306640625 +27566 0.65948486328125 +27567 -0.064605712890625 +27568 0.651275634765625 +27569 0.02239990234375 +27570 0.61846923828125 +27571 0.110198974609375 +27572 0.53753662109375 +27573 0.182952880859375 +27574 0.404144287109375 +27575 0.232818603515625 +27576 0.22186279296875 +27577 0.255523681640625 +27578 0.003997802734375 +27579 0.251495361328125 +27580 -0.22100830078125 +27581 0.228302001953125 +27582 -0.42449951171875 +27583 0.194580078125 +27584 -0.579833984375 +27585 0.15936279296875 +27586 -0.641876220703125 +27587 0.1407470703125 +27588 -0.6177978515625 +27589 0.13592529296875 +27590 -0.575531005859375 +27591 0.1175537109375 +27592 -0.526336669921875 +27593 0.08343505859375 +27594 -0.42645263671875 +27595 0.0556640625 +27596 -0.2581787109375 +27597 0.045989990234375 +27598 -0.068695068359375 +27599 0.039154052734375 +27600 0.09222412109375 +27601 0.01898193359375 +27602 0.232147216796875 +27603 -0.00640869140625 +27604 0.3509521484375 +27605 -0.032562255859375 +27606 0.410064697265625 +27607 -0.0718994140625 +27608 0.372955322265625 +27609 -0.136749267578125 +27610 0.2554931640625 +27611 -0.2181396484375 +27612 0.10711669921875 +27613 -0.293914794921875 +27614 -0.052886962890625 +27615 -0.355743408203125 +27616 -0.186279296875 +27617 -0.38824462890625 +27618 -0.23291015625 +27619 -0.367767333984375 +27620 -0.209442138671875 +27621 -0.304046630859375 +27622 -0.174163818359375 +27623 -0.22509765625 +27624 -0.126739501953125 +27625 -0.13458251953125 +27626 -0.048126220703125 +27627 -0.028472900390625 +27628 0.0426025390625 +27629 0.08111572265625 +27630 0.10748291015625 +27631 0.17425537109375 +27632 0.1409912109375 +27633 0.245208740234375 +27634 0.19708251953125 +27635 0.31396484375 +27636 0.273651123046875 +27637 0.377532958984375 +27638 0.31768798828125 +27639 0.41217041015625 +27640 0.341094970703125 +27641 0.4224853515625 +27642 0.368011474609375 +27643 0.41912841796875 +27644 0.37249755859375 +27645 0.392333984375 +27646 0.30072021484375 +27647 0.321258544921875 +27648 0.1517333984375 +27649 0.208221435546875 +27650 -0.01470947265625 +27651 0.081695556640625 +27652 -0.1883544921875 +27653 -0.051513671875 +27654 -0.372711181640625 +27655 -0.189971923828125 +27656 -0.51397705078125 +27657 -0.306488037109375 +27658 -0.57177734375 +27659 -0.38006591796875 +27660 -0.53948974609375 +27661 -0.4052734375 +27662 -0.43511962890625 +27663 -0.388275146484375 +27664 -0.2962646484375 +27665 -0.344573974609375 +27666 -0.161102294921875 +27667 -0.290618896484375 +27668 -0.0435791015625 +27669 -0.232574462890625 +27670 0.060394287109375 +27671 -0.169219970703125 +27672 0.13665771484375 +27673 -0.10809326171875 +27674 0.170135498046875 +27675 -0.0577392578125 +27676 0.16552734375 +27677 -0.018218994140625 +27678 0.15728759765625 +27679 0.023529052734375 +27680 0.150787353515625 +27681 0.06732177734375 +27682 0.12200927734375 +27683 0.099761962890625 +27684 0.080108642578125 +27685 0.12255859375 +27686 0.05126953125 +27687 0.14532470703125 +27688 0.062896728515625 +27689 0.17864990234375 +27690 0.09271240234375 +27691 0.211151123046875 +27692 0.092987060546875 +27693 0.2205810546875 +27694 0.07855224609375 +27695 0.21337890625 +27696 0.06427001953125 +27697 0.196563720703125 +27698 0.0347900390625 +27699 0.164093017578125 +27700 -0.01171875 +27701 0.11639404296875 +27702 -0.056060791015625 +27703 0.063812255859375 +27704 -0.055511474609375 +27705 0.027496337890625 +27706 -0.010467529296875 +27707 0.009368896484375 +27708 0.02508544921875 +27709 -0.012664794921875 +27710 0.025665283203125 +27711 -0.048004150390625 +27712 0.017333984375 +27713 -0.08306884765625 +27714 0.00189208984375 +27715 -0.115447998046875 +27716 -0.03173828125 +27717 -0.14892578125 +27718 -0.071502685546875 +27719 -0.17730712890625 +27720 -0.13543701171875 +27721 -0.208343505859375 +27722 -0.219970703125 +27723 -0.24053955078125 +27724 -0.300506591796875 +27725 -0.26336669921875 +27726 -0.376312255859375 +27727 -0.277435302734375 +27728 -0.416107177734375 +27729 -0.269927978515625 +27730 -0.371124267578125 +27731 -0.220489501953125 +27732 -0.242279052734375 +27733 -0.131195068359375 +27734 -0.069732666015625 +27735 -0.02191162109375 +27736 0.125640869140625 +27737 0.09619140625 +27738 0.31268310546875 +27739 0.207489013671875 +27740 0.45501708984375 +27741 0.29425048828125 +27742 0.554779052734375 +27743 0.3563232421875 +27744 0.61065673828125 +27745 0.392364501953125 +27746 0.610931396484375 +27747 0.39666748046875 +27748 0.531463623046875 +27749 0.35833740234375 +27750 0.3883056640625 +27751 0.284912109375 +27752 0.23468017578125 +27753 0.201019287109375 +27754 0.095245361328125 +27755 0.118743896484375 +27756 -0.00396728515625 +27757 0.050994873046875 +27758 -0.04852294921875 +27759 0.005615234375 +27760 -0.055145263671875 +27761 -0.023468017578125 +27762 -0.0758056640625 +27763 -0.05816650390625 +27764 -0.138702392578125 +27765 -0.109832763671875 +27766 -0.209197998046875 +27767 -0.161651611328125 +27768 -0.289031982421875 +27769 -0.213409423828125 +27770 -0.37884521484375 +27771 -0.264617919921875 +27772 -0.456329345703125 +27773 -0.3048095703125 +27774 -0.51641845703125 +27775 -0.33160400390625 +27776 -0.519287109375 +27777 -0.327239990234375 +27778 -0.458251953125 +27779 -0.289154052734375 +27780 -0.384796142578125 +27781 -0.241241455078125 +27782 -0.323699951171875 +27783 -0.195587158203125 +27784 -0.269287109375 +27785 -0.15069580078125 +27786 -0.1951904296875 +27787 -0.095916748046875 +27788 -0.100006103515625 +27789 -0.03179931640625 +27790 -0.01055908203125 +27791 0.02838134765625 +27792 0.1033935546875 +27793 0.09716796875 +27794 0.24908447265625 +27795 0.17694091796875 +27796 0.373199462890625 +27797 0.243072509765625 +27798 0.45806884765625 +27799 0.28717041015625 +27800 0.511474609375 +27801 0.3125 +27802 0.565399169921875 +27803 0.333526611328125 +27804 0.61138916015625 +27805 0.346771240234375 +27806 0.5897216796875 +27807 0.32586669921875 +27808 0.4906005859375 +27809 0.267120361328125 +27810 0.33148193359375 +27811 0.17926025390625 +27812 0.147796630859375 +27813 0.07916259765625 +27814 -0.01873779296875 +27815 -0.013397216796875 +27816 -0.140289306640625 +27817 -0.08489990234375 +27818 -0.191986083984375 +27819 -0.123291015625 +27820 -0.184295654296875 +27821 -0.13250732421875 +27822 -0.161834716796875 +27823 -0.13201904296875 +27824 -0.166595458984375 +27825 -0.1402587890625 +27826 -0.19390869140625 +27827 -0.1549072265625 +27828 -0.22442626953125 +27829 -0.167205810546875 +27830 -0.279754638671875 +27831 -0.18707275390625 +27832 -0.3389892578125 +27833 -0.205474853515625 +27834 -0.3543701171875 +27835 -0.201507568359375 +27836 -0.348175048828125 +27837 -0.18585205078125 +27838 -0.32598876953125 +27839 -0.161773681640625 +27840 -0.2581787109375 +27841 -0.11676025390625 +27842 -0.139801025390625 +27843 -0.049346923828125 +27844 0.014617919921875 +27845 0.03314208984375 +27846 0.144378662109375 +27847 0.102691650390625 +27848 0.221038818359375 +27849 0.145965576171875 +27850 0.27069091796875 +27851 0.174285888671875 +27852 0.294036865234375 +27853 0.187744140625 +27854 0.311767578125 +27855 0.195587158203125 +27856 0.339141845703125 +27857 0.204803466796875 +27858 0.360260009765625 +27859 0.20855712890625 +27860 0.360504150390625 +27861 0.20062255859375 +27862 0.308380126953125 +27863 0.1671142578125 +27864 0.18170166015625 +27865 0.098480224609375 +27866 0.0047607421875 +27867 0.006439208984375 +27868 -0.17559814453125 +27869 -0.087005615234375 +27870 -0.3143310546875 +27871 -0.1607666015625 +27872 -0.36785888671875 +27873 -0.194427490234375 +27874 -0.36248779296875 +27875 -0.199493408203125 +27876 -0.343536376953125 +27877 -0.196258544921875 +27878 -0.3018798828125 +27879 -0.18035888671875 +27880 -0.231414794921875 +27881 -0.148895263671875 +27882 -0.117645263671875 +27883 -0.095306396484375 +27884 0.007049560546875 +27885 -0.034515380859375 +27886 0.087982177734375 +27887 0.008270263671875 +27888 0.13946533203125 +27889 0.0391845703125 +27890 0.17425537109375 +27891 0.0635986328125 +27892 0.188201904296875 +27893 0.079132080078125 +27894 0.171234130859375 +27895 0.080657958984375 +27896 0.118438720703125 +27897 0.065460205078125 +27898 0.05706787109375 +27899 0.045501708984375 +27900 -0.010711669921875 +27901 0.021331787109375 +27902 -0.0914306640625 +27903 -0.0103759765625 +27904 -0.162322998046875 +27905 -0.03985595703125 +27906 -0.194549560546875 +27907 -0.053924560546875 +27908 -0.1492919921875 +27909 -0.033355712890625 +27910 -0.02166748046875 +27911 0.02471923828125 +27912 0.124053955078125 +27913 0.08953857421875 +27914 0.211151123046875 +27915 0.124237060546875 +27916 0.240447998046875 +27917 0.12982177734375 +27918 0.242218017578125 +27919 0.121612548828125 +27920 0.2257080078125 +27921 0.104736328125 +27922 0.194366455078125 +27923 0.081329345703125 +27924 0.115509033203125 +27925 0.035858154296875 +27926 0.0128173828125 +27927 -0.01971435546875 +27928 -0.053802490234375 +27929 -0.05596923828125 +27930 -0.110626220703125 +27931 -0.0855712890625 +27932 -0.199493408203125 +27933 -0.128936767578125 +27934 -0.29437255859375 +27935 -0.1734619140625 +27936 -0.33221435546875 +27937 -0.18853759765625 +27938 -0.27972412109375 +27939 -0.158172607421875 +27940 -0.185333251953125 +27941 -0.106292724609375 +27942 -0.128204345703125 +27943 -0.071868896484375 +27944 -0.115692138671875 +27945 -0.058868408203125 +27946 -0.116455078125 +27947 -0.0523681640625 +27948 -0.105926513671875 +27949 -0.040802001953125 +27950 -0.053955078125 +27951 -0.009765625 +27952 0.048797607421875 +27953 0.04498291015625 +27954 0.157318115234375 +27955 0.10125732421875 +27956 0.212005615234375 +27957 0.129852294921875 +27958 0.218475341796875 +27959 0.133392333984375 +27960 0.23724365234375 +27961 0.141448974609375 +27962 0.30535888671875 +27963 0.172210693359375 +27964 0.38128662109375 +27965 0.20556640625 +27966 0.404449462890625 +27967 0.212188720703125 +27968 0.3944091796875 +27969 0.201934814453125 +27970 0.3885498046875 +27971 0.193359375 +27972 0.362640380859375 +27973 0.174957275390625 +27974 0.27362060546875 +27975 0.12603759765625 +27976 0.11712646484375 +27977 0.04473876953125 +27978 -0.054901123046875 +27979 -0.04327392578125 +27980 -0.19085693359375 +27981 -0.112640380859375 +27982 -0.28570556640625 +27983 -0.1607666015625 +27984 -0.339263916015625 +27985 -0.187530517578125 +27986 -0.3775634765625 +27987 -0.20562744140625 +27988 -0.445709228515625 +27989 -0.23712158203125 +27990 -0.535064697265625 +27991 -0.277923583984375 +27992 -0.629058837890625 +27993 -0.320159912109375 +27994 -0.697601318359375 +27995 -0.349334716796875 +27996 -0.70391845703125 +27997 -0.347747802734375 +27998 -0.6424560546875 +27999 -0.31298828125 +28000 -0.491241455078125 +28001 -0.234588623046875 +28002 -0.265716552734375 +28003 -0.120330810546875 +28004 -0.023712158203125 +28005 0.001312255859375 +28006 0.201751708984375 +28007 0.11407470703125 +28008 0.375823974609375 +28009 0.200836181640625 +28010 0.485076904296875 +28011 0.254974365234375 +28012 0.56884765625 +28013 0.295654296875 +28014 0.634765625 +28015 0.326629638671875 +28016 0.63763427734375 +28017 0.325958251953125 +28018 0.5660400390625 +28019 0.2882080078125 +28020 0.4720458984375 +28021 0.23895263671875 +28022 0.40692138671875 +28023 0.203399658203125 +28024 0.3778076171875 +28025 0.18524169921875 +28026 0.376953125 +28027 0.180938720703125 +28028 0.371978759765625 +28029 0.174896240234375 +28030 0.313140869140625 +28031 0.143035888671875 +28032 0.184417724609375 +28033 0.07769775390625 +28034 0.011199951171875 +28035 -0.00860595703125 +28036 -0.171051025390625 +28037 -0.09844970703125 +28038 -0.33740234375 +28039 -0.179656982421875 +28040 -0.47198486328125 +28041 -0.244537353515625 +28042 -0.560394287109375 +28043 -0.2861328125 +28044 -0.58056640625 +28045 -0.293792724609375 +28046 -0.54754638671875 +28047 -0.27496337890625 +28048 -0.508575439453125 +28049 -0.252899169921875 +28050 -0.459503173828125 +28051 -0.2257080078125 +28052 -0.394378662109375 +28053 -0.190704345703125 +28054 -0.35260009765625 +28055 -0.167266845703125 +28056 -0.31170654296875 +28057 -0.14459228515625 +28058 -0.197418212890625 +28059 -0.086578369140625 +28060 -0.007965087890625 +28061 0.007537841796875 +28062 0.207489013671875 +28063 0.113677978515625 +28064 0.409210205078125 +28065 0.212371826171875 +28066 0.57208251953125 +28067 0.291412353515625 +28068 0.66595458984375 +28069 0.33612060546875 +28070 0.65875244140625 +28071 0.3309326171875 +28072 0.56744384765625 +28073 0.284210205078125 +28074 0.431396484375 +28075 0.21533203125 +28076 0.29443359375 +28077 0.145843505859375 +28078 0.182464599609375 +28079 0.0885009765625 +28080 0.06365966796875 +28081 0.027923583984375 +28082 -0.075958251953125 +28083 -0.04254150390625 +28084 -0.189422607421875 +28085 -0.099853515625 +28086 -0.271942138671875 +28087 -0.141571044921875 +28088 -0.342529296875 +28089 -0.176910400390625 +28090 -0.364166259765625 +28091 -0.18780517578125 +28092 -0.327239990234375 +28093 -0.169586181640625 +28094 -0.2769775390625 +28095 -0.144317626953125 +28096 -0.253692626953125 +28097 -0.1317138671875 +28098 -0.24365234375 +28099 -0.12518310546875 +28100 -0.1983642578125 +28101 -0.101165771484375 +28102 -0.116241455078125 +28103 -0.058990478515625 +28104 -0.036834716796875 +28105 -0.018035888671875 +28106 0.034881591796875 +28107 0.01910400390625 +28108 0.09124755859375 +28109 0.048583984375 +28110 0.10888671875 +28111 0.05889892578125 +28112 0.125518798828125 +28113 0.068328857421875 +28114 0.15771484375 +28115 0.084930419921875 +28116 0.17828369140625 +28117 0.09539794921875 +28118 0.17108154296875 +28119 0.09185791015625 +28120 0.129974365234375 +28121 0.071319580078125 +28122 0.082427978515625 +28123 0.047210693359375 +28124 0.027679443359375 +28125 0.01922607421875 +28126 -0.065643310546875 +28127 -0.027801513671875 +28128 -0.15936279296875 +28129 -0.075164794921875 +28130 -0.21307373046875 +28131 -0.10308837890625 +28132 -0.234649658203125 +28133 -0.11529541015625 +28134 -0.2001953125 +28135 -0.10003662109375 +28136 -0.119171142578125 +28137 -0.061859130859375 +28138 -0.024749755859375 +28139 -0.01690673828125 +28140 0.085784912109375 +28141 0.03619384765625 +28142 0.178131103515625 +28143 0.080718994140625 +28144 0.215576171875 +28145 0.098785400390625 +28146 0.211456298828125 +28147 0.096923828125 +28148 0.17523193359375 +28149 0.079742431640625 +28150 0.128753662109375 +28151 0.057861328125 +28152 0.1019287109375 +28153 0.04583740234375 +28154 0.0743408203125 +28155 0.033660888671875 +28156 0.04327392578125 +28157 0.0198974609375 +28158 0.038177490234375 +28159 0.018829345703125 +28160 0.076263427734375 +28161 0.039337158203125 +28162 0.14105224609375 +28163 0.073760986328125 +28164 0.186431884765625 +28165 0.0986328125 +28166 0.188812255859375 +28167 0.1014404296875 +28168 0.1390380859375 +28169 0.07720947265625 +28170 0.041778564453125 +28171 0.0281982421875 +28172 -0.079437255859375 +28173 -0.03350830078125 +28174 -0.219390869140625 +28175 -0.1053466796875 +28176 -0.367828369140625 +28177 -0.182037353515625 +28178 -0.494873046875 +28179 -0.24810791015625 +28180 -0.556243896484375 +28181 -0.280548095703125 +28182 -0.508697509765625 +28183 -0.256866455078125 +28184 -0.3756103515625 +28185 -0.189117431640625 +28186 -0.218902587890625 +28187 -0.109405517578125 +28188 -0.063751220703125 +28189 -0.03070068359375 +28190 0.091552734375 +28191 0.047943115234375 +28192 0.23602294921875 +28193 0.1209716796875 +28194 0.342987060546875 +28195 0.17462158203125 +28196 0.39520263671875 +28197 0.200042724609375 +28198 0.389373779296875 +28199 0.19561767578125 +28200 0.324249267578125 +28201 0.1607666015625 +28202 0.224090576171875 +28203 0.108154296875 +28204 0.124267578125 +28205 0.05621337890625 +28206 0.037078857421875 +28207 0.01129150390625 +28208 -0.010101318359375 +28209 -0.01239013671875 +28210 -0.019439697265625 +28211 -0.016021728515625 +28212 -0.022796630859375 +28213 -0.0162353515625 +28214 -0.001556396484375 +28215 -0.00341796875 +28216 0.056304931640625 +28217 0.028533935546875 +28218 0.106719970703125 +28219 0.05657958984375 +28220 0.096893310546875 +28221 0.053192138671875 +28222 0.042694091796875 +28223 0.026519775390625 +28224 -0.018035888671875 +28225 -0.003814697265625 +28226 -0.07586669921875 +28227 -0.032958984375 +28228 -0.11944580078125 +28229 -0.0550537109375 +28230 -0.15972900390625 +28231 -0.075836181640625 +28232 -0.202606201171875 +28233 -0.098358154296875 +28234 -0.24859619140625 +28235 -0.12286376953125 +28236 -0.30517578125 +28237 -0.153167724609375 +28238 -0.36212158203125 +28239 -0.183929443359375 +28240 -0.39141845703125 +28241 -0.20050048828125 +28242 -0.35528564453125 +28243 -0.183135986328125 +28244 -0.249969482421875 +28245 -0.129852294921875 +28246 -0.092864990234375 +28247 -0.049591064453125 +28248 0.08905029296875 +28249 0.043670654296875 +28250 0.2352294921875 +28251 0.1185302734375 +28252 0.318817138671875 +28253 0.16107177734375 +28254 0.358642578125 +28255 0.181121826171875 +28256 0.347747802734375 +28257 0.17510986328125 +28258 0.28564453125 +28259 0.142791748046875 +28260 0.223175048828125 +28261 0.110595703125 +28262 0.196746826171875 +28263 0.097442626953125 +28264 0.179840087890625 +28265 0.089508056640625 +28266 0.155548095703125 +28267 0.07794189453125 +28268 0.151214599609375 +28269 0.076873779296875 +28270 0.156951904296875 +28271 0.08111572265625 +28272 0.13177490234375 +28273 0.069244384765625 +28274 0.100799560546875 +28275 0.05426025390625 +28276 0.087127685546875 +28277 0.04815673828125 +28278 0.05487060546875 +28279 0.0322265625 +28280 -0.009002685546875 +28281 -0.0003662109375 +28282 -0.10400390625 +28283 -0.04937744140625 +28284 -0.229400634765625 +28285 -0.11444091796875 +28286 -0.35552978515625 +28287 -0.180145263671875 +28288 -0.441925048828125 +28289 -0.22540283203125 +28290 -0.473846435546875 +28291 -0.2425537109375 +28292 -0.464813232421875 +28293 -0.238555908203125 +28294 -0.419097900390625 +28295 -0.215606689453125 +28296 -0.334320068359375 +28297 -0.17242431640625 +28298 -0.227935791015625 +28299 -0.118011474609375 +28300 -0.12347412109375 +28301 -0.064605712890625 +28302 -0.02764892578125 +28303 -0.015655517578125 +28304 0.077667236328125 +28305 0.038330078125 +28306 0.2132568359375 +28307 0.108184814453125 +28308 0.38885498046875 +28309 0.199005126953125 +28310 0.582794189453125 +28311 0.299560546875 +28312 0.734039306640625 +28313 0.37811279296875 +28314 0.800140380859375 +28315 0.41259765625 +28316 0.7783203125 +28317 0.401519775390625 +28318 0.6651611328125 +28319 0.343109130859375 +28320 0.45965576171875 +28321 0.23681640625 +28322 0.199188232421875 +28323 0.10205078125 +28324 -0.050689697265625 +28325 -0.027099609375 +28326 -0.23297119140625 +28327 -0.121063232421875 +28328 -0.33013916015625 +28329 -0.1707763671875 +28330 -0.368408203125 +28331 -0.18994140625 +28332 -0.378936767578125 +28333 -0.19476318359375 +28334 -0.376983642578125 +28335 -0.1932373046875 +28336 -0.37969970703125 +28337 -0.194305419921875 +28338 -0.391510009765625 +28339 -0.20025634765625 +28340 -0.385345458984375 +28341 -0.197052001953125 +28342 -0.3419189453125 +28343 -0.17462158203125 +28344 -0.28289794921875 +28345 -0.14422607421875 +28346 -0.251617431640625 +28347 -0.128387451171875 +28348 -0.266143798828125 +28349 -0.136474609375 +28350 -0.273345947265625 +28351 -0.140838623046875 +28352 -0.216796875 +28353 -0.112091064453125 +28354 -0.128265380859375 +28355 -0.06671142578125 +28356 -0.068145751953125 +28357 -0.036041259765625 +28358 -0.0430908203125 +28359 -0.02349853515625 +28360 -0.024444580078125 +28361 -0.014190673828125 +28362 0.020721435546875 +28363 0.009002685546875 +28364 0.124481201171875 +28365 0.062744140625 +28366 0.25787353515625 +28367 0.131988525390625 +28368 0.379119873046875 +28369 0.19500732421875 +28370 0.47991943359375 +28371 0.247528076171875 +28372 0.5281982421875 +28373 0.272857666015625 +28374 0.511138916015625 +28375 0.2642822265625 +28376 0.456207275390625 +28377 0.236083984375 +28378 0.407470703125 +28379 0.211151123046875 +28380 0.383758544921875 +28381 0.19927978515625 +28382 0.35687255859375 +28383 0.185760498046875 +28384 0.31182861328125 +28385 0.16278076171875 +28386 0.250885009765625 +28387 0.1314697265625 +28388 0.1654052734375 +28389 0.087310791015625 +28390 0.035247802734375 +28391 0.01983642578125 +28392 -0.142059326171875 +28393 -0.072235107421875 +28394 -0.33563232421875 +28395 -0.1728515625 +28396 -0.5345458984375 +28397 -0.27630615234375 +28398 -0.72186279296875 +28399 -0.373779296875 +28400 -0.836669921875 +28401 -0.43359375 +28402 -0.8326416015625 +28403 -0.431671142578125 +28404 -0.7296142578125 +28405 -0.378326416015625 +28406 -0.582550048828125 +28407 -0.3021240234375 +28408 -0.440093994140625 +28409 -0.22833251953125 +28410 -0.324310302734375 +28411 -0.168426513671875 +28412 -0.20147705078125 +28413 -0.1048583984375 +28414 -0.044647216796875 +28415 -0.023590087890625 +28416 0.103973388671875 +28417 0.052886962890625 +28418 0.202392578125 +28419 0.102081298828125 +28420 0.264495849609375 +28421 0.131866455078125 +28422 0.338897705078125 +28423 0.169342041015625 +28424 0.443817138671875 +28425 0.2247314453125 +28426 0.545074462890625 +28427 0.279296875 +28428 0.6173095703125 +28429 0.319061279296875 +28430 0.6524658203125 +28431 0.33953857421875 +28432 0.66339111328125 +28433 0.347747802734375 +28434 0.6561279296875 +28435 0.346893310546875 +28436 0.606781005859375 +28437 0.32354736328125 +28438 0.501190185546875 +28439 0.2696533203125 +28440 0.352783203125 +28441 0.1923828125 +28442 0.176544189453125 +28443 0.099761962890625 +28444 -0.034820556640625 +28445 -0.012481689453125 +28446 -0.258209228515625 +28447 -0.1318359375 +28448 -0.44244384765625 +28449 -0.230255126953125 +28450 -0.5753173828125 +28451 -0.301116943359375 +28452 -0.65203857421875 +28453 -0.3419189453125 +28454 -0.641632080078125 +28455 -0.335662841796875 +28456 -0.562164306640625 +28457 -0.29229736328125 +28458 -0.458038330078125 +28459 -0.236297607421875 +28460 -0.350555419921875 +28461 -0.179290771484375 +28462 -0.260528564453125 +28463 -0.132598876953125 +28464 -0.192108154296875 +28465 -0.098358154296875 +28466 -0.141937255859375 +28467 -0.07452392578125 +28468 -0.1021728515625 +28469 -0.0565185546875 +28470 -0.062896728515625 +28471 -0.038665771484375 +28472 -0.011932373046875 +28473 -0.0140380859375 +28474 0.062835693359375 +28475 0.02423095703125 +28476 0.148712158203125 +28477 0.069305419921875 +28478 0.241729736328125 +28479 0.11907958984375 +28480 0.34912109375 +28481 0.177642822265625 +28482 0.457305908203125 +28483 0.23748779296875 +28484 0.54388427734375 +28485 0.28619384765625 +28486 0.5728759765625 +28487 0.303863525390625 +28488 0.506591796875 +28489 0.269561767578125 +28490 0.351226806640625 +28491 0.18658447265625 +28492 0.146514892578125 +28493 0.076690673828125 +28494 -0.05523681640625 +28495 -0.031402587890625 +28496 -0.21624755859375 +28497 -0.1170654296875 +28498 -0.334930419921875 +28499 -0.1795654296875 +28500 -0.402984619140625 +28501 -0.2144775390625 +28502 -0.4412841796875 +28503 -0.23345947265625 +28504 -0.49578857421875 +28505 -0.261993408203125 +28506 -0.5601806640625 +28507 -0.296630859375 +28508 -0.600738525390625 +28509 -0.318817138671875 +28510 -0.584228515625 +28511 -0.310211181640625 +28512 -0.47930908203125 +28513 -0.253448486328125 +28514 -0.27935791015625 +28515 -0.144775390625 +28516 -0.0089111328125 +28517 0.002349853515625 +28518 0.268798828125 +28519 0.15313720703125 +28520 0.482818603515625 +28521 0.268585205078125 +28522 0.60369873046875 +28523 0.33258056640625 +28524 0.650421142578125 +28525 0.355712890625 +28526 0.66400146484375 +28527 0.360809326171875 +28528 0.6414794921875 +28529 0.346343994140625 +28530 0.572540283203125 +28531 0.306732177734375 +28532 0.498138427734375 +28533 0.2646484375 +28534 0.439453125 +28535 0.231842041015625 +28536 0.375518798828125 +28537 0.19671630859375 +28538 0.274505615234375 +28539 0.141693115234375 +28540 0.1087646484375 +28541 0.05145263671875 +28542 -0.099395751953125 +28543 -0.061767578125 +28544 -0.3182373046875 +28545 -0.1805419921875 +28546 -0.5489501953125 +28547 -0.3056640625 +28548 -0.7738037109375 +28549 -0.42742919921875 +28550 -0.86383056640625 +28551 -0.516754150390625 +28552 -0.870391845703125 +28553 -0.555419921875 +28554 -0.86895751953125 +28555 -0.553314208984375 +28556 -0.861053466796875 +28557 -0.517791748046875 +28558 -0.765869140625 +28559 -0.439361572265625 +28560 -0.5301513671875 +28561 -0.311859130859375 +28562 -0.214691162109375 +28563 -0.13922119140625 +28564 0.137359619140625 +28565 0.054779052734375 +28566 0.474822998046875 +28567 0.24188232421875 +28568 0.76239013671875 +28569 0.402496337890625 +28570 0.867462158203125 +28571 0.521820068359375 +28572 0.870361328125 +28573 0.600189208984375 +28574 0.86480712890625 +28575 0.63134765625 +28576 0.831817626953125 +28577 0.618316650390625 +28578 0.677581787109375 +28579 0.574676513671875 +28580 0.495880126953125 +28581 0.503753662109375 +28582 0.30767822265625 +28583 0.415863037109375 +28584 0.116180419921875 +28585 0.312286376953125 +28586 -0.110748291015625 +28587 0.175567626953125 +28588 -0.381805419921875 +28589 0.001922607421875 +28590 -0.6572265625 +28591 -0.185028076171875 +28592 -0.857421875 +28593 -0.352203369140625 +28594 -0.870391845703125 +28595 -0.475982666015625 +28596 -0.870391845703125 +28597 -0.552490234375 +28598 -0.86444091796875 +28599 -0.596649169921875 +28600 -0.85723876953125 +28601 -0.62823486328125 +28602 -0.790008544921875 +28603 -0.63720703125 +28604 -0.62847900390625 +28605 -0.59368896484375 +28606 -0.3956298828125 +28607 -0.496002197265625 +28608 -0.126708984375 +28609 -0.36236572265625 +28610 0.150115966796875 +28611 -0.207977294921875 +28612 0.424041748046875 +28613 -0.03936767578125 +28614 0.670623779296875 +28615 0.128570556640625 +28616 0.854522705078125 +28617 0.2744140625 +28618 0.866485595703125 +28619 0.388427734375 +28620 0.86920166015625 +28621 0.46209716796875 +28622 0.8653564453125 +28623 0.505462646484375 +28624 0.857147216796875 +28625 0.5260009765625 +28626 0.766845703125 +28627 0.522186279296875 +28628 0.628509521484375 +28629 0.49688720703125 +28630 0.462127685546875 +28631 0.446441650390625 +28632 0.297210693359375 +28633 0.38519287109375 +28634 0.14862060546875 +28635 0.32000732421875 +28636 -0.00537109375 +28637 0.238372802734375 +28638 -0.15753173828125 +28639 0.144500732421875 +28640 -0.31304931640625 +28641 0.03643798828125 +28642 -0.48876953125 +28643 -0.093536376953125 +28644 -0.6416015625 +28645 -0.219512939453125 +28646 -0.751373291015625 +28647 -0.32781982421875 +28648 -0.84619140625 +28649 -0.43121337890625 +28650 -0.861297607421875 +28651 -0.521636962890625 +28652 -0.863250732421875 +28653 -0.580780029296875 +28654 -0.856597900390625 +28655 -0.591278076171875 +28656 -0.7498779296875 +28657 -0.559906005859375 +28658 -0.624542236328125 +28659 -0.5186767578125 +28660 -0.47808837890625 +28661 -0.45550537109375 +28662 -0.253387451171875 +28663 -0.338165283203125 +28664 0.003692626953125 +28665 -0.191925048828125 +28666 0.2257080078125 +28667 -0.0545654296875 +28668 0.427154541015625 +28669 0.080780029296875 +28670 0.643218994140625 +28671 0.231964111328125 +28672 0.855926513671875 +28673 0.39410400390625 +28674 0.870361328125 +28675 0.53521728515625 +28676 0.870361328125 +28677 0.627197265625 +28678 0.862762451171875 +28679 0.674224853515625 +28680 0.79669189453125 +28681 0.674468994140625 +28682 0.595794677734375 +28683 0.622161865234375 +28684 0.362152099609375 +28685 0.534088134765625 +28686 0.1270751953125 +28687 0.42626953125 +28688 -0.086944580078125 +28689 0.310699462890625 +28690 -0.2784423828125 +28691 0.188232421875 +28692 -0.484832763671875 +28693 0.0382080078125 +28694 -0.729583740234375 +28695 -0.15093994140625 +28696 -0.86688232421875 +28697 -0.3499755859375 +28698 -0.870391845703125 +28699 -0.522186279296875 +28700 -0.86859130859375 +28701 -0.664886474609375 +28702 -0.86279296875 +28703 -0.777008056640625 +28704 -0.817962646484375 +28705 -0.837615966796875 +28706 -0.6116943359375 +28707 -0.820220947265625 +28708 -0.3128662109375 +28709 -0.7205810546875 +28710 0.039398193359375 +28711 -0.558258056640625 +28712 0.422821044921875 +28713 -0.34478759765625 +28714 0.805145263671875 +28715 -0.099395751953125 +28716 0.870361328125 +28717 0.138336181640625 +28718 0.870361328125 +28719 0.3353271484375 +28720 0.860015869140625 +28721 0.48492431640625 +28722 0.727935791015625 +28723 0.582763671875 +28724 0.48114013671875 +28725 0.625640869140625 +28726 0.2059326171875 +28727 0.62774658203125 +28728 -0.06103515625 +28729 0.602294921875 +28730 -0.29913330078125 +28731 0.555145263671875 +28732 -0.516204833984375 +28733 0.477813720703125 +28734 -0.7252197265625 +28735 0.361297607421875 +28736 -0.85980224609375 +28737 0.2200927734375 +28738 -0.870391845703125 +28739 0.07427978515625 +28740 -0.870391845703125 +28741 -0.058837890625 +28742 -0.858062744140625 +28743 -0.15081787109375 +28744 -0.673004150390625 +28745 -0.19915771484375 +28746 -0.42694091796875 +28747 -0.234405517578125 +28748 -0.2100830078125 +28749 -0.28240966796875 +28750 -0.0362548828125 +28751 -0.341796875 +28752 0.10943603515625 +28753 -0.3955078125 +28754 0.23516845703125 +28755 -0.43182373046875 +28756 0.373687744140625 +28757 -0.426483154296875 +28758 0.517791748046875 +28759 -0.38055419921875 +28760 0.602783203125 +28761 -0.330780029296875 +28762 0.635711669921875 +28763 -0.274169921875 +28764 0.655181884765625 +28765 -0.1912841796875 +28766 0.65948486328125 +28767 -0.0880126953125 +28768 0.651275634765625 +28769 0.030853271484375 +28770 0.61846923828125 +28771 0.15081787109375 +28772 0.53753662109375 +28773 0.2501220703125 +28774 0.404144287109375 +28775 0.31805419921875 +28776 0.22186279296875 +28777 0.348785400390625 +28778 0.003997802734375 +28779 0.342864990234375 +28780 -0.22100830078125 +28781 0.31072998046875 +28782 -0.42449951171875 +28783 0.264312744140625 +28784 -0.579833984375 +28785 0.21600341796875 +28786 -0.641876220703125 +28787 0.190704345703125 +28788 -0.6177978515625 +28789 0.184539794921875 +28790 -0.575531005859375 +28791 0.159820556640625 +28792 -0.526336669921875 +28793 0.113525390625 +28794 -0.42645263671875 +28795 0.076019287109375 +28796 -0.2581787109375 +28797 0.063446044921875 +28798 -0.068695068359375 +28799 0.05474853515625 +28800 0.09222412109375 +28801 0.02764892578125 +28802 0.232147216796875 +28803 -0.00677490234375 +28804 0.3509521484375 +28805 -0.042388916015625 +28806 0.410064697265625 +28807 -0.0963134765625 +28808 0.372955322265625 +28809 -0.185577392578125 +28810 0.2554931640625 +28811 -0.29779052734375 +28812 0.10711669921875 +28813 -0.40240478515625 +28814 -0.052886962890625 +28815 -0.4879150390625 +28816 -0.186279296875 +28817 -0.533172607421875 +28818 -0.23291015625 +28819 -0.50555419921875 +28820 -0.209442138671875 +28821 -0.418426513671875 +28822 -0.174163818359375 +28823 -0.31036376953125 +28824 -0.126739501953125 +28825 -0.18634033203125 +28826 -0.048126220703125 +28827 -0.040740966796875 +28828 0.0426025390625 +28829 0.1097412109375 +28830 0.10748291015625 +28831 0.237701416015625 +28832 0.1409912109375 +28833 0.335205078125 +28834 0.19708251953125 +28835 0.42987060546875 +28836 0.273651123046875 +28837 0.517547607421875 +28838 0.31768798828125 +28839 0.56549072265625 +28840 0.341094970703125 +28841 0.580047607421875 +28842 0.368011474609375 +28843 0.575897216796875 +28844 0.37249755859375 +28845 0.539520263671875 +28846 0.30072021484375 +28847 0.442169189453125 +28848 0.1517333984375 +28849 0.286773681640625 +28850 -0.01470947265625 +28851 0.1123046875 +28852 -0.1883544921875 +28853 -0.070709228515625 +28854 -0.372711181640625 +28855 -0.259765625 +28856 -0.51397705078125 +28857 -0.419036865234375 +28858 -0.57177734375 +28859 -0.520843505859375 +28860 -0.53948974609375 +28861 -0.557861328125 +28862 -0.43511962890625 +28863 -0.537933349609375 +28864 -0.2962646484375 +28865 -0.481231689453125 +28866 -0.161102294921875 +28867 -0.4091796875 +28868 -0.0435791015625 +28869 -0.33001708984375 +28870 0.060394287109375 +28871 -0.242431640625 +28872 0.13665771484375 +28873 -0.156646728515625 +28874 0.170135498046875 +28875 -0.0841064453125 +28876 0.16552734375 +28877 -0.025299072265625 +28878 0.15728759765625 +28879 0.036285400390625 +28880 0.150787353515625 +28881 0.100006103515625 +28882 0.12200927734375 +28883 0.148101806640625 +28884 0.080108642578125 +28885 0.182464599609375 +28886 0.05126953125 +28887 0.21539306640625 +28888 0.062896728515625 +28889 0.26043701171875 +28890 0.09271240234375 +28891 0.30279541015625 +28892 0.092987060546875 +28893 0.313629150390625 +28894 0.07855224609375 +28895 0.301422119140625 +28896 0.06427001953125 +28897 0.2755126953125 +28898 0.0347900390625 +28899 0.228240966796875 +28900 -0.01171875 +28901 0.160552978515625 +28902 -0.056060791015625 +28903 0.086151123046875 +28904 -0.055511474609375 +28905 0.032867431640625 +28906 -0.010467529296875 +28907 0.003570556640625 +28908 0.02508544921875 +28909 -0.0301513671875 +28910 0.025665283203125 +28911 -0.08026123046875 +28912 0.017333984375 +28913 -0.12890625 +28914 0.00189208984375 +28915 -0.1728515625 +28916 -0.03173828125 +28917 -0.2169189453125 +28918 -0.071502685546875 +28919 -0.2530517578125 +28920 -0.13543701171875 +28921 -0.291412353515625 +28922 -0.219970703125 +28923 -0.3302001953125 +28924 -0.300506591796875 +28925 -0.355926513671875 +28926 -0.376312255859375 +28927 -0.36962890625 +28928 -0.416107177734375 +28929 -0.354888916015625 +28930 -0.371124267578125 +28931 -0.28533935546875 +28932 -0.242279052734375 +28933 -0.164031982421875 +28934 -0.069732666015625 +28935 -0.017242431640625 +28936 0.125640869140625 +28937 0.14031982421875 +28938 0.31268310546875 +28939 0.28802490234375 +28940 0.45501708984375 +28941 0.402374267578125 +28942 0.554779052734375 +28943 0.48333740234375 +28944 0.61065673828125 +28945 0.52923583984375 +28946 0.610931396484375 +28947 0.53265380859375 +28948 0.531463623046875 +28949 0.479217529296875 +28950 0.3883056640625 +28951 0.37908935546875 +28952 0.23468017578125 +28953 0.26519775390625 +28954 0.095245361328125 +28955 0.153778076171875 +28956 -0.00396728515625 +28957 0.06207275390625 +28958 -0.04852294921875 +28959 0.000579833984375 +28960 -0.055145263671875 +28961 -0.0386962890625 +28962 -0.0758056640625 +28963 -0.085052490234375 +28964 -0.138702392578125 +28965 -0.153594970703125 +28966 -0.209197998046875 +28967 -0.221954345703125 +28968 -0.289031982421875 +28969 -0.289886474609375 +28970 -0.37884521484375 +28971 -0.356903076171875 +28972 -0.456329345703125 +28973 -0.409027099609375 +28974 -0.51641845703125 +28975 -0.44317626953125 +28976 -0.519287109375 +28977 -0.435791015625 +28978 -0.458251953125 +28979 -0.383544921875 +28980 -0.384796142578125 +28981 -0.318359375 +28982 -0.323699951171875 +28983 -0.25640869140625 +28984 -0.269287109375 +28985 -0.19580078125 +28986 -0.1951904296875 +28987 -0.122314453125 +28988 -0.100006103515625 +28989 -0.036712646484375 +28990 -0.01055908203125 +28991 0.0433349609375 +28992 0.1033935546875 +28993 0.134613037109375 +28994 0.24908447265625 +28995 0.240325927734375 +28996 0.373199462890625 +28997 0.327606201171875 +28998 0.45806884765625 +28999 0.385284423828125 +29000 0.511474609375 +29001 0.4178466796875 +29002 0.565399169921875 +29003 0.444671630859375 +29004 0.61138916015625 +29005 0.461151123046875 +29006 0.5897216796875 +29007 0.432220458984375 +29008 0.4906005859375 +29009 0.352996826171875 +29010 0.33148193359375 +29011 0.23516845703125 +29012 0.147796630859375 +29013 0.101226806640625 +29014 -0.01873779296875 +29015 -0.022430419921875 +29016 -0.140289306640625 +29017 -0.117767333984375 +29018 -0.191986083984375 +29019 -0.168701171875 +29020 -0.184295654296875 +29021 -0.18048095703125 +29022 -0.161834716796875 +29023 -0.179107666015625 +29024 -0.166595458984375 +29025 -0.189239501953125 +29026 -0.19390869140625 +29027 -0.207794189453125 +29028 -0.22442626953125 +29029 -0.22320556640625 +29030 -0.279754638671875 +29031 -0.24871826171875 +29032 -0.3389892578125 +29033 -0.272369384765625 +29034 -0.3543701171875 +29035 -0.26629638671875 +29036 -0.348175048828125 +29037 -0.244781494140625 +29038 -0.32598876953125 +29039 -0.212188720703125 +29040 -0.2581787109375 +29041 -0.151885986328125 +29042 -0.139801025390625 +29043 -0.06195068359375 +29044 0.014617919921875 +29045 0.047882080078125 +29046 0.144378662109375 +29047 0.1402587890625 +29048 0.221038818359375 +29049 0.197418212890625 +29050 0.27069091796875 +29051 0.234527587890625 +29052 0.294036865234375 +29053 0.251739501953125 +29054 0.311767578125 +29055 0.261383056640625 +29056 0.339141845703125 +29057 0.272857666015625 +29058 0.360260009765625 +29059 0.277191162109375 +29060 0.360504150390625 +29061 0.266143798828125 +29062 0.308380126953125 +29063 0.22088623046875 +29064 0.18170166015625 +29065 0.12847900390625 +29066 0.0047607421875 +29067 0.00469970703125 +29068 -0.17559814453125 +29069 -0.120819091796875 +29070 -0.3143310546875 +29071 -0.2196044921875 +29072 -0.36785888671875 +29073 -0.26409912109375 +29074 -0.36248779296875 +29075 -0.269927978515625 +29076 -0.343536376953125 +29077 -0.264617919921875 +29078 -0.3018798828125 +29079 -0.242279052734375 +29080 -0.231414794921875 +29081 -0.19903564453125 +29082 -0.117645263671875 +29083 -0.12603759765625 +29084 0.007049560546875 +29085 -0.043487548828125 +29086 0.087982177734375 +29087 0.0145263671875 +29088 0.13946533203125 +29089 0.056304931640625 +29090 0.17425537109375 +29091 0.089141845703125 +29092 0.188201904296875 +29093 0.10980224609375 +29094 0.171234130859375 +29095 0.11138916015625 +29096 0.118438720703125 +29097 0.090240478515625 +29098 0.05706787109375 +29099 0.06256103515625 +29100 -0.010711669921875 +29101 0.02911376953125 +29102 -0.0914306640625 +29103 -0.01446533203125 +29104 -0.162322998046875 +29105 -0.054412841796875 +29106 -0.194549560546875 +29107 -0.073150634765625 +29108 -0.1492919921875 +29109 -0.0467529296875 +29110 -0.02166748046875 +29111 0.0279541015625 +29112 0.124053955078125 +29113 0.1116943359375 +29114 0.211151123046875 +29115 0.157562255859375 +29116 0.240447998046875 +29117 0.16656494140625 +29118 0.242218017578125 +29119 0.1578369140625 +29120 0.2257080078125 +29121 0.137664794921875 +29122 0.194366455078125 +29123 0.108734130859375 +29124 0.115509033203125 +29125 0.0513916015625 +29126 0.0128173828125 +29127 -0.019256591796875 +29128 -0.053802490234375 +29129 -0.06597900390625 +29130 -0.110626220703125 +29131 -0.104705810546875 +29132 -0.199493408203125 +29133 -0.161041259765625 +29134 -0.29437255859375 +29135 -0.218963623046875 +29136 -0.33221435546875 +29137 -0.239715576171875 +29138 -0.27972412109375 +29139 -0.2030029296875 +29140 -0.185333251953125 +29141 -0.138916015625 +29142 -0.128204345703125 +29143 -0.0965576171875 +29144 -0.115692138671875 +29145 -0.08087158203125 +29146 -0.116455078125 +29147 -0.07305908203125 +29148 -0.105926513671875 +29149 -0.0584716796875 +29150 -0.053955078125 +29151 -0.018951416015625 +29152 0.048797607421875 +29153 0.05084228515625 +29154 0.157318115234375 +29155 0.122894287109375 +29156 0.212005615234375 +29157 0.16021728515625 +29158 0.218475341796875 +29159 0.166107177734375 +29160 0.23724365234375 +29161 0.17779541015625 +29162 0.30535888671875 +29163 0.218170166015625 +29164 0.38128662109375 +29165 0.261749267578125 +29166 0.404449462890625 +29167 0.27142333984375 +29168 0.3944091796875 +29169 0.259552001953125 +29170 0.3885498046875 +29171 0.24951171875 +29172 0.362640380859375 +29173 0.22674560546875 +29174 0.27362060546875 +29175 0.165130615234375 +29176 0.11712646484375 +29177 0.06231689453125 +29178 -0.054901123046875 +29179 -0.04931640625 +29180 -0.19085693359375 +29181 -0.1376953125 +29182 -0.28570556640625 +29183 -0.19952392578125 +29184 -0.339263916015625 +29185 -0.233917236328125 +29186 -0.3775634765625 +29187 -0.257110595703125 +29188 -0.445709228515625 +29189 -0.29833984375 +29190 -0.535064697265625 +29191 -0.352508544921875 +29192 -0.629058837890625 +29193 -0.409271240234375 +29194 -0.697601318359375 +29195 -0.449554443359375 +29196 -0.70391845703125 +29197 -0.4498291015625 +29198 -0.6424560546875 +29199 -0.406768798828125 +29200 -0.491241455078125 +29201 -0.306304931640625 +29202 -0.265716552734375 +29203 -0.1585693359375 +29204 -0.023712158203125 +29205 -0.001068115234375 +29206 0.201751708984375 +29207 0.144775390625 +29208 0.375823974609375 +29209 0.256439208984375 +29210 0.485076904296875 +29211 0.325347900390625 +29212 0.56884765625 +29213 0.37713623046875 +29214 0.634765625 +29215 0.416900634765625 +29216 0.63763427734375 +29217 0.415557861328125 +29218 0.5660400390625 +29219 0.36590576171875 +29220 0.4720458984375 +29221 0.301849365234375 +29222 0.40692138671875 +29223 0.256805419921875 +29224 0.3778076171875 +29225 0.23553466796875 +29226 0.376953125 +29227 0.233154296875 +29228 0.371978759765625 +29229 0.228790283203125 +29230 0.313140869140625 +29231 0.190216064453125 +29232 0.184417724609375 +29233 0.1070556640625 +29234 0.011199951171875 +29235 -0.004241943359375 +29236 -0.171051025390625 +29237 -0.120758056640625 +29238 -0.33740234375 +29239 -0.2264404296875 +29240 -0.47198486328125 +29241 -0.311126708984375 +29242 -0.560394287109375 +29243 -0.365692138671875 +29244 -0.58056640625 +29245 -0.3759765625 +29246 -0.54754638671875 +29247 -0.351898193359375 +29248 -0.508575439453125 +29249 -0.324188232421875 +29250 -0.459503173828125 +29251 -0.290283203125 +29252 -0.394378662109375 +29253 -0.2464599609375 +29254 -0.35260009765625 +29255 -0.218292236328125 +29256 -0.31170654296875 +29257 -0.191253662109375 +29258 -0.197418212890625 +29259 -0.11724853515625 +29260 -0.007965087890625 +29261 0.004852294921875 +29262 0.207489013671875 +29263 0.14324951171875 +29264 0.409210205078125 +29265 0.27227783203125 +29266 0.57208251953125 +29267 0.37579345703125 +29268 0.66595458984375 +29269 0.434356689453125 +29270 0.65875244140625 +29271 0.427337646484375 +29272 0.56744384765625 +29273 0.3658447265625 +29274 0.431396484375 +29275 0.2755126953125 +29276 0.29443359375 +29277 0.18487548828125 +29278 0.182464599609375 +29279 0.11077880859375 +29280 0.06365966796875 +29281 0.03271484375 +29282 -0.075958251953125 +29283 -0.058319091796875 +29284 -0.189422607421875 +29285 -0.131866455078125 +29286 -0.271942138671875 +29287 -0.184844970703125 +29288 -0.342529296875 +29289 -0.2296142578125 +29290 -0.364166259765625 +29291 -0.242279052734375 +29292 -0.327239990234375 +29293 -0.216705322265625 +29294 -0.2769775390625 +29295 -0.182281494140625 +29296 -0.253692626953125 +29297 -0.165252685546875 +29298 -0.24365234375 +29299 -0.15679931640625 +29300 -0.1983642578125 +29301 -0.125640869140625 +29302 -0.116241455078125 +29303 -0.070831298828125 +29304 -0.036834716796875 +29305 -0.018035888671875 +29306 0.034881591796875 +29307 0.0294189453125 +29308 0.09124755859375 +29309 0.0665283203125 +29310 0.10888671875 +29311 0.078155517578125 +29312 0.125518798828125 +29313 0.08868408203125 +29314 0.15771484375 +29315 0.108917236328125 +29316 0.17828369140625 +29317 0.12127685546875 +29318 0.17108154296875 +29319 0.115325927734375 +29320 0.129974365234375 +29321 0.08721923828125 +29322 0.082427978515625 +29323 0.0548095703125 +29324 0.027679443359375 +29325 0.017730712890625 +29326 -0.065643310546875 +29327 -0.04425048828125 +29328 -0.15936279296875 +29329 -0.1063232421875 +29330 -0.21307373046875 +29331 -0.142242431640625 +29332 -0.234649658203125 +29333 -0.1571044921875 +29334 -0.2001953125 +29335 -0.135345458984375 +29336 -0.119171142578125 +29337 -0.08306884765625 +29338 -0.024749755859375 +29339 -0.02178955078125 +29340 0.085784912109375 +29341 0.050262451171875 +29342 0.178131103515625 +29343 0.110809326171875 +29344 0.215576171875 +29345 0.136016845703125 +29346 0.211456298828125 +29347 0.13446044921875 +29348 0.17523193359375 +29349 0.112213134765625 +29350 0.128753662109375 +29351 0.0833740234375 +29352 0.1019287109375 +29353 0.067230224609375 +29354 0.0743408203125 +29355 0.050506591796875 +29356 0.04327392578125 +29357 0.0313720703125 +29358 0.038177490234375 +29359 0.028839111328125 +29360 0.076263427734375 +29361 0.054046630859375 +29362 0.14105224609375 +29363 0.096282958984375 +29364 0.186431884765625 +29365 0.12567138671875 +29366 0.188812255859375 +29367 0.126922607421875 +29368 0.1390380859375 +29369 0.094146728515625 +29370 0.041778564453125 +29371 0.0303955078125 +29372 -0.079437255859375 +29373 -0.04901123046875 +29374 -0.219390869140625 +29375 -0.140655517578125 +29376 -0.367828369140625 +29377 -0.237823486328125 +29378 -0.494873046875 +29379 -0.32110595703125 +29380 -0.556243896484375 +29381 -0.36175537109375 +29382 -0.508697509765625 +29383 -0.33172607421875 +29384 -0.3756103515625 +29385 -0.246124267578125 +29386 -0.218902587890625 +29387 -0.145050048828125 +29388 -0.063751220703125 +29389 -0.0447998046875 +29390 0.091552734375 +29391 0.05572509765625 +29392 0.23602294921875 +29393 0.149444580078125 +29394 0.342987060546875 +29395 0.219024658203125 +29396 0.39520263671875 +29397 0.2532958984375 +29398 0.389373779296875 +29399 0.2501220703125 +29400 0.324249267578125 +29401 0.208648681640625 +29402 0.224090576171875 +29403 0.14453125 +29404 0.124267578125 +29405 0.08062744140625 +29406 0.037078857421875 +29407 0.024871826171875 +29408 -0.010101318359375 +29409 -0.0050048828125 +29410 -0.019439697265625 +29411 -0.010467529296875 +29412 -0.022796630859375 +29413 -0.012176513671875 +29414 -0.001556396484375 +29415 0.001861572265625 +29416 0.056304931640625 +29417 0.039459228515625 +29418 0.106719970703125 +29419 0.072052001953125 +29420 0.096893310546875 +29421 0.065460205078125 +29422 0.042694091796875 +29423 0.02996826171875 +29424 -0.018035888671875 +29425 -0.0098876953125 +29426 -0.07586669921875 +29427 -0.047943115234375 +29428 -0.11944580078125 +29429 -0.0767822265625 +29430 -0.15972900390625 +29431 -0.103515625 +29432 -0.202606201171875 +29433 -0.13189697265625 +29434 -0.24859619140625 +29435 -0.162200927734375 +29436 -0.30517578125 +29437 -0.199249267578125 +29438 -0.36212158203125 +29439 -0.236419677734375 +29440 -0.39141845703125 +29441 -0.255462646484375 +29442 -0.35528564453125 +29443 -0.231719970703125 +29444 -0.249969482421875 +29445 -0.162872314453125 +29446 -0.092864990234375 +29447 -0.060028076171875 +29448 0.08905029296875 +29449 0.05908203125 +29450 0.2352294921875 +29451 0.15386962890625 +29452 0.318817138671875 +29453 0.206512451171875 +29454 0.358642578125 +29455 0.23016357421875 +29456 0.347747802734375 +29457 0.220367431640625 +29458 0.28564453125 +29459 0.176910400390625 +29460 0.223175048828125 +29461 0.1343994140625 +29462 0.196746826171875 +29463 0.1175537109375 +29464 0.179840087890625 +29465 0.10821533203125 +29466 0.155548095703125 +29467 0.094696044921875 +29468 0.151214599609375 +29469 0.09539794921875 +29470 0.156951904296875 +29471 0.10333251953125 +29472 0.13177490234375 +29473 0.090362548828125 +29474 0.100799560546875 +29475 0.073333740234375 +29476 0.087127685546875 +29477 0.06768798828125 +29478 0.05487060546875 +29479 0.048858642578125 +29480 -0.009002685546875 +29481 0.0078125 +29482 -0.10400390625 +29483 -0.05523681640625 +29484 -0.229400634765625 +29485 -0.139862060546875 +29486 -0.35552978515625 +29487 -0.22589111328125 +29488 -0.441925048828125 +29489 -0.285736083984375 +29490 -0.473846435546875 +29491 -0.309326171875 +29492 -0.464813232421875 +29493 -0.305694580078125 +29494 -0.419097900390625 +29495 -0.277618408203125 +29496 -0.334320068359375 +29497 -0.223297119140625 +29498 -0.227935791015625 +29499 -0.154388427734375 +29500 -0.12347412109375 +29501 -0.08673095703125 +29502 -0.02764892578125 +29503 -0.024688720703125 +29504 0.077667236328125 +29505 0.044219970703125 +29506 0.2132568359375 +29507 0.134246826171875 +29508 0.38885498046875 +29509 0.252105712890625 +29510 0.582794189453125 +29511 0.383148193359375 +29512 0.734039306640625 +29513 0.48590087890625 +29514 0.800140380859375 +29515 0.531494140625 +29516 0.7783203125 +29517 0.5179443359375 +29518 0.6651611328125 +29519 0.442840576171875 +29520 0.45965576171875 +29521 0.305419921875 +29522 0.199188232421875 +29523 0.1309814453125 +29524 -0.050689697265625 +29525 -0.03607177734375 +29526 -0.23297119140625 +29527 -0.157135009765625 +29528 -0.33013916015625 +29529 -0.220458984375 +29530 -0.368408203125 +29531 -0.2440185546875 +29532 -0.378936767578125 +29533 -0.249114990234375 +29534 -0.376983642578125 +29535 -0.246246337890625 +29536 -0.37969970703125 +29537 -0.247161865234375 +29538 -0.391510009765625 +29539 -0.254913330078125 +29540 -0.385345458984375 +29541 -0.251068115234375 +29542 -0.3419189453125 +29543 -0.22247314453125 +29544 -0.28289794921875 +29545 -0.183807373046875 +29546 -0.251617431640625 +29547 -0.1644287109375 +29548 -0.266143798828125 +29549 -0.176483154296875 +29550 -0.273345947265625 +29551 -0.183746337890625 +29552 -0.216796875 +29553 -0.147674560546875 +29554 -0.128265380859375 +29555 -0.0897216796875 +29556 -0.068145751953125 +29557 -0.050872802734375 +29558 -0.0430908203125 +29559 -0.035552978515625 +29560 -0.024444580078125 +29561 -0.024200439453125 +29562 0.020721435546875 +29563 0.005645751953125 +29564 0.124481201171875 +29565 0.075836181640625 +29566 0.25787353515625 +29567 0.1666259765625 +29568 0.379119873046875 +29569 0.249603271484375 +29570 0.47991943359375 +29571 0.319122314453125 +29572 0.5281982421875 +29573 0.353302001953125 +29574 0.511138916015625 +29575 0.34332275390625 +29576 0.456207275390625 +29577 0.307769775390625 +29578 0.407470703125 +29579 0.276519775390625 +29580 0.383758544921875 +29581 0.26226806640625 +29582 0.35687255859375 +29583 0.2457275390625 +29584 0.31182861328125 +29585 0.21661376953125 +29586 0.250885009765625 +29587 0.1763916015625 +29588 0.1654052734375 +29589 0.119140625 +29590 0.035247802734375 +29591 0.031097412109375 +29592 -0.142059326171875 +29593 -0.089385986328125 +29594 -0.33563232421875 +29595 -0.2213134765625 +29596 -0.5345458984375 +29597 -0.357208251953125 +29598 -0.72186279296875 +29599 -0.48553466796875 +29600 -0.836669921875 +29601 -0.564788818359375 +29602 -0.8326416015625 +29603 -0.56341552734375 +29604 -0.7296142578125 +29605 -0.49481201171875 +29606 -0.582550048828125 +29607 -0.396270751953125 +29608 -0.440093994140625 +29609 -0.30078125 +29610 -0.324310302734375 +29611 -0.22332763671875 +29612 -0.20147705078125 +29613 -0.140869140625 +29614 -0.044647216796875 +29615 -0.0350341796875 +29616 0.103973388671875 +29617 0.065521240234375 +29618 0.202392578125 +29619 0.132232666015625 +29620 0.264495849609375 +29621 0.174530029296875 +29622 0.338897705078125 +29623 0.2254638671875 +29624 0.443817138671875 +29625 0.29742431640625 +29626 0.545074462890625 +29627 0.36712646484375 +29628 0.6173095703125 +29629 0.417236328125 +29630 0.6524658203125 +29631 0.4422607421875 +29632 0.66339111328125 +29633 0.45086669921875 +29634 0.6561279296875 +29635 0.44708251953125 +29636 0.606781005859375 +29637 0.41455078125 +29638 0.501190185546875 +29639 0.3436279296875 +29640 0.352783203125 +29641 0.243377685546875 +29642 0.176544189453125 +29643 0.123992919921875 +29644 -0.034820556640625 +29645 -0.01947021484375 +29646 -0.258209228515625 +29647 -0.17132568359375 +29648 -0.44244384765625 +29649 -0.296783447265625 +29650 -0.5753173828125 +29651 -0.38751220703125 +29652 -0.65203857421875 +29653 -0.440216064453125 +29654 -0.641632080078125 +29655 -0.433807373046875 +29656 -0.562164306640625 +29657 -0.38055419921875 +29658 -0.458038330078125 +29659 -0.31060791015625 +29660 -0.350555419921875 +29661 -0.238372802734375 +29662 -0.260528564453125 +29663 -0.177978515625 +29664 -0.192108154296875 +29665 -0.1322021484375 +29666 -0.141937255859375 +29667 -0.098724365234375 +29668 -0.1021728515625 +29669 -0.07220458984375 +29670 -0.062896728515625 +29671 -0.04583740234375 +29672 -0.011932373046875 +29673 -0.011322021484375 +29674 0.062835693359375 +29675 0.03955078125 +29676 0.148712158203125 +29677 0.098175048828125 +29678 0.241729736328125 +29679 0.16180419921875 +29680 0.34912109375 +29681 0.2353515625 +29682 0.457305908203125 +29683 0.309539794921875 +29684 0.54388427734375 +29685 0.369110107421875 +29686 0.5728759765625 +29687 0.389556884765625 +29688 0.506591796875 +29689 0.345184326171875 +29690 0.351226806640625 +29691 0.240203857421875 +29692 0.146514892578125 +29693 0.1015625 +29694 -0.05523681640625 +29695 -0.03515625 +29696 -0.21624755859375 +29697 -0.144622802734375 +29698 -0.334930419921875 +29699 -0.225555419921875 +29700 -0.402984619140625 +29701 -0.271484375 +29702 -0.4412841796875 +29703 -0.297332763671875 +29704 -0.49578857421875 +29705 -0.335845947265625 +29706 -0.5601806640625 +29707 -0.382476806640625 +29708 -0.600738525390625 +29709 -0.4130859375 +29710 -0.584228515625 +29711 -0.40386962890625 +29712 -0.47930908203125 +29713 -0.332305908203125 +29714 -0.27935791015625 +29715 -0.193511962890625 +29716 -0.0089111328125 +29717 -0.00469970703125 +29718 0.268798828125 +29719 0.189300537109375 +29720 0.482818603515625 +29721 0.33819580078125 +29722 0.60369873046875 +29723 0.421173095703125 +29724 0.650421142578125 +29725 0.451904296875 +29726 0.66400146484375 +29727 0.459716796875 +29728 0.6414794921875 +29729 0.442596435546875 +29730 0.572540283203125 +29731 0.39324951171875 +29732 0.498138427734375 +29733 0.340789794921875 +29734 0.439453125 +29735 0.300262451171875 +29736 0.375518798828125 +29737 0.25665283203125 +29738 0.274505615234375 +29739 0.187164306640625 +29740 0.1087646484375 +29741 0.07196044921875 +29742 -0.099395751953125 +29743 -0.073211669921875 +29744 -0.3182373046875 +29745 -0.225921630859375 +29746 -0.5489501953125 +29747 -0.38720703125 +29748 -0.7738037109375 +29749 -0.544586181640625 +29750 -0.86383056640625 +29751 -0.6605224609375 +29752 -0.870391845703125 +29753 -0.71142578125 +29754 -0.86895751953125 +29755 -0.71002197265625 +29756 -0.861053466796875 +29757 -0.665679931640625 +29758 -0.765869140625 +29759 -0.56610107421875 +29760 -0.5301513671875 +29761 -0.403228759765625 +29762 -0.214691162109375 +29763 -0.182037353515625 +29764 0.137359619140625 +29765 0.06689453125 +29766 0.474822998046875 +29767 0.30712890625 +29768 0.76239013671875 +29769 0.513519287109375 +29770 0.867462158203125 +29771 0.666961669921875 +29772 0.870361328125 +29773 0.767913818359375 +29774 0.86480712890625 +29775 0.808319091796875 +29776 0.831817626953125 +29777 0.792083740234375 +29778 0.677581787109375 +29779 0.736663818359375 +29780 0.495880126953125 +29781 0.646270751953125 +29782 0.30767822265625 +29783 0.534149169921875 +29784 0.116180419921875 +29785 0.401885986328125 +29786 -0.110748291015625 +29787 0.226898193359375 +29788 -0.381805419921875 +29789 0.00421142578125 +29790 -0.6572265625 +29791 -0.23577880859375 +29792 -0.857421875 +29793 -0.450531005859375 +29794 -0.870391845703125 +29795 -0.60955810546875 +29796 -0.870391845703125 +29797 -0.707855224609375 +29798 -0.86444091796875 +29799 -0.76470947265625 +29800 -0.85723876953125 +29801 -0.805633544921875 +29802 -0.790008544921875 +29803 -0.817626953125 +29804 -0.62847900390625 +29805 -0.762176513671875 +29806 -0.3956298828125 +29807 -0.6370849609375 +29808 -0.126708984375 +29809 -0.46575927734375 +29810 0.150115966796875 +29811 -0.2677001953125 +29812 0.424041748046875 +29813 -0.05126953125 +29814 0.670623779296875 +29815 0.164306640625 +29816 0.854522705078125 +29817 0.35150146484375 +29818 0.866485595703125 +29819 0.497772216796875 +29820 0.86920166015625 +29821 0.59222412109375 +29822 0.8653564453125 +29823 0.6478271484375 +29824 0.857147216796875 +29825 0.6741943359375 +29826 0.766845703125 +29827 0.669342041015625 +29828 0.628509521484375 +29829 0.63702392578125 +29830 0.462127685546875 +29831 0.572479248046875 +29832 0.297210693359375 +29833 0.494171142578125 +29834 0.14862060546875 +29835 0.41094970703125 +29836 -0.00537109375 +29837 0.30657958984375 +29838 -0.15753173828125 +29839 0.186431884765625 +29840 -0.31304931640625 +29841 0.04791259765625 +29842 -0.48876953125 +29843 -0.118927001953125 +29844 -0.6416015625 +29845 -0.28076171875 +29846 -0.751373291015625 +29847 -0.41998291015625 +29848 -0.84619140625 +29849 -0.553070068359375 +29850 -0.861297607421875 +29851 -0.669586181640625 +29852 -0.863250732421875 +29853 -0.746002197265625 +29854 -0.856597900390625 +29855 -0.759857177734375 +29856 -0.7498779296875 +29857 -0.7198486328125 +29858 -0.624542236328125 +29859 -0.667205810546875 +29860 -0.47808837890625 +29861 -0.586334228515625 +29862 -0.253387451171875 +29863 -0.4356689453125 +29864 0.003692626953125 +29865 -0.24774169921875 +29866 0.2257080078125 +29867 -0.071258544921875 +29868 0.427154541015625 +29869 0.102691650390625 +29870 0.643218994140625 +29871 0.297119140625 +29872 0.855926513671875 +29873 0.50518798828125 +29874 0.870361328125 +29875 0.685638427734375 +29876 0.870361328125 +29877 0.80316162109375 +29878 0.862762451171875 +29879 0.85540771484375 +29880 0.79669189453125 +29881 0.855377197265625 +29882 0.595794677734375 +29883 0.795928955078125 +29884 0.362152099609375 +29885 0.683380126953125 +29886 0.1270751953125 +29887 0.54510498046875 +29888 -0.086944580078125 +29889 0.396209716796875 +29890 -0.2784423828125 +29891 0.238250732421875 +29892 -0.484832763671875 +29893 0.0465087890625 +29894 -0.729583740234375 +29895 -0.192626953125 +29896 -0.86688232421875 +29897 -0.44305419921875 +29898 -0.870391845703125 +29899 -0.65960693359375 +29900 -0.86859130859375 +29901 -0.8387451171875 +29902 -0.86279296875 +29903 -0.868072509765625 +29904 -0.817962646484375 +29905 -0.870391845703125 +29906 -0.6116943359375 +29907 -0.86260986328125 +29908 -0.3128662109375 +29909 -0.76226806640625 +29910 0.039398193359375 +29911 -0.527099609375 +29912 0.422821044921875 +29913 -0.238983154296875 +29914 0.805145263671875 +29915 0.07733154296875 +29916 0.870361328125 +29917 0.373016357421875 +29918 0.870361328125 +29919 0.60772705078125 +29920 0.860015869140625 +29921 0.77392578125 +29922 0.727935791015625 +29923 0.85589599609375 +29924 0.48114013671875 +29925 0.857940673828125 +29926 0.2059326171875 +29927 0.849639892578125 +29928 -0.06103515625 +29929 0.775909423828125 +29930 -0.29913330078125 +29931 0.6746826171875 +29932 -0.516204833984375 +29933 0.538055419921875 +29934 -0.7252197265625 +29935 0.357269287109375 +29936 -0.85980224609375 +29937 0.15203857421875 +29938 -0.870391845703125 +29939 -0.051513671875 +29940 -0.870391845703125 +29941 -0.231170654296875 +29942 -0.858062744140625 +29943 -0.351470947265625 +29944 -0.673004150390625 +29945 -0.409210205078125 +29946 -0.42694091796875 +29947 -0.441986083984375 +29948 -0.2100830078125 +29949 -0.4820556640625 +29950 -0.0362548828125 +29951 -0.529052734375 +29952 0.10943603515625 +29953 -0.564056396484375 +29954 0.23516845703125 +29955 -0.57476806640625 +29956 0.373687744140625 +29957 -0.5323486328125 +29958 0.517791748046875 +29959 -0.440032958984375 +29960 0.602783203125 +29961 -0.346405029296875 +29962 0.635711669921875 +29963 -0.249114990234375 +29964 0.655181884765625 +29965 -0.124603271484375 +29966 0.65948486328125 +29967 0.018798828125 +29968 0.651275634765625 +29969 0.174560546875 +29970 0.61846923828125 +29971 0.324249267578125 +29972 0.53753662109375 +29973 0.4405517578125 +29974 0.404144287109375 +29975 0.510528564453125 +29976 0.22186279296875 +29977 0.527862548828125 +29978 0.003997802734375 +29979 0.49456787109375 +29980 -0.22100830078125 +29981 0.425445556640625 +29982 -0.42449951171875 +29983 0.33734130859375 +29984 -0.579833984375 +29985 0.24761962890625 +29986 -0.641876220703125 +29987 0.189544677734375 +29988 -0.6177978515625 +29989 0.159515380859375 +29990 -0.575531005859375 +29991 0.110626220703125 +29992 -0.526336669921875 +29993 0.039825439453125 +29994 -0.42645263671875 +29995 -0.013702392578125 +29996 -0.2581787109375 +29997 -0.029205322265625 +29998 -0.068695068359375 +29999 -0.03375244140625 +30000 0.09222412109375 +30001 -0.056304931640625 +30002 0.232147216796875 +30003 -0.083526611328125 +30004 0.3509521484375 +30005 -0.108673095703125 +30006 0.410064697265625 +30007 -0.15478515625 +30008 0.372955322265625 +30009 -0.24481201171875 +30010 0.2554931640625 +30011 -0.36431884765625 +30012 0.10711669921875 +30013 -0.47564697265625 +30014 -0.052886962890625 +30015 -0.565338134765625 +30016 -0.186279296875 +30017 -0.60736083984375 +30018 -0.23291015625 +30019 -0.560943603515625 +30020 -0.209442138671875 +30021 -0.443572998046875 +30022 -0.174163818359375 +30023 -0.304595947265625 +30024 -0.126739501953125 +30025 -0.1502685546875 +30026 -0.048126220703125 +30027 0.02685546875 +30028 0.0426025390625 +30029 0.2061767578125 +30030 0.10748291015625 +30031 0.353546142578125 +30032 0.1409912109375 +30033 0.459808349609375 +30034 0.19708251953125 +30035 0.561187744140625 +30036 0.273651123046875 +30037 0.65350341796875 +30038 0.31768798828125 +30039 0.69610595703125 +30040 0.341094970703125 +30041 0.697998046875 +30042 0.368011474609375 +30043 0.678741455078125 +30044 0.37249755859375 +30045 0.621856689453125 +30046 0.30072021484375 +30047 0.49114990234375 +30048 0.1517333984375 +30049 0.290618896484375 +30050 -0.01470947265625 +30051 0.0699462890625 +30052 -0.1883544921875 +30053 -0.157684326171875 +30054 -0.372711181640625 +30055 -0.389495849609375 +30056 -0.51397705078125 +30057 -0.58038330078125 +30058 -0.57177734375 +30059 -0.695892333984375 +30060 -0.53948974609375 +30061 -0.727569580078125 +30062 -0.43511962890625 +30063 -0.68621826171875 +30064 -0.2962646484375 +30065 -0.598388671875 +30066 -0.161102294921875 +30067 -0.49224853515625 +30068 -0.0435791015625 +30069 -0.379058837890625 +30070 0.060394287109375 +30071 -0.257781982421875 +30072 0.13665771484375 +30073 -0.141876220703125 +30074 0.170135498046875 +30075 -0.04620361328125 +30076 0.16552734375 +30077 0.028533935546875 +30078 0.15728759765625 +30079 0.103485107421875 +30080 0.150787353515625 +30081 0.17816162109375 +30082 0.12200927734375 +30083 0.230377197265625 +30084 0.080108642578125 +30085 0.263092041015625 +30086 0.05126953125 +30087 0.2926025390625 +30088 0.062896728515625 +30089 0.3369140625 +30090 0.09271240234375 +30091 0.377899169921875 +30092 0.092987060546875 +30093 0.379547119140625 +30094 0.07855224609375 +30095 0.353271484375 +30096 0.06427001953125 +30097 0.311492919921875 +30098 0.0347900390625 +30099 0.244903564453125 +30100 -0.01171875 +30101 0.154937744140625 +30102 -0.056060791015625 +30103 0.059234619140625 +30104 -0.055511474609375 +30105 -0.006744384765625 +30106 -0.010467529296875 +30107 -0.039581298828125 +30108 0.02508544921875 +30109 -0.075775146484375 +30110 0.025665283203125 +30111 -0.1309814453125 +30112 0.017333984375 +30113 -0.183013916015625 +30114 0.00189208984375 +30115 -0.22833251953125 +30116 -0.03173828125 +30117 -0.273681640625 +30118 -0.071502685546875 +30119 -0.30938720703125 +30120 -0.13543701171875 +30121 -0.348907470703125 +30122 -0.219970703125 +30123 -0.390472412109375 +30124 -0.300506591796875 +30125 -0.41729736328125 +30126 -0.376312255859375 +30127 -0.430999755859375 +30128 -0.416107177734375 +30129 -0.410888671875 +30130 -0.371124267578125 +30131 -0.3236083984375 +30132 -0.242279052734375 +30133 -0.172882080078125 +30134 -0.069732666015625 +30135 0.008392333984375 +30136 0.125640869140625 +30137 0.20184326171875 +30138 0.31268310546875 +30139 0.38177490234375 +30140 0.45501708984375 +30141 0.519134521484375 +30142 0.554779052734375 +30143 0.61407470703125 +30144 0.61065673828125 +30145 0.664794921875 +30146 0.610931396484375 +30147 0.662384033203125 +30148 0.531463623046875 +30149 0.58941650390625 +30150 0.3883056640625 +30151 0.458892822265625 +30152 0.23468017578125 +30153 0.31201171875 +30154 0.095245361328125 +30155 0.16912841796875 +30156 -0.00396728515625 +30157 0.051910400390625 +30158 -0.04852294921875 +30159 -0.026397705078125 +30160 -0.055145263671875 +30161 -0.075714111328125 +30162 -0.0758056640625 +30163 -0.132293701171875 +30164 -0.138702392578125 +30165 -0.214996337890625 +30166 -0.209197998046875 +30167 -0.29620361328125 +30168 -0.289031982421875 +30169 -0.375885009765625 +30170 -0.37884521484375 +30171 -0.453643798828125 +30172 -0.456329345703125 +30173 -0.51251220703125 +30174 -0.51641845703125 +30175 -0.5489501953125 +30176 -0.519287109375 +30177 -0.534088134765625 +30178 -0.458251953125 +30179 -0.464111328125 +30180 -0.384796142578125 +30181 -0.37884521484375 +30182 -0.323699951171875 +30183 -0.298614501953125 +30184 -0.269287109375 +30185 -0.221160888671875 +30186 -0.1951904296875 +30187 -0.128997802734375 +30188 -0.100006103515625 +30189 -0.0230712890625 +30190 -0.01055908203125 +30191 0.074737548828125 +30192 0.1033935546875 +30193 0.18536376953125 +30194 0.24908447265625 +30195 0.31292724609375 +30196 0.373199462890625 +30197 0.416961669921875 +30198 0.45806884765625 +30199 0.483856201171875 +30200 0.511474609375 +30201 0.519439697265625 +30202 0.565399169921875 +30203 0.5479736328125 +30204 0.61138916015625 +30205 0.563995361328125 +30206 0.5897216796875 +30207 0.524261474609375 +30208 0.4906005859375 +30209 0.42279052734375 +30210 0.33148193359375 +30211 0.274078369140625 +30212 0.147796630859375 +30213 0.1063232421875 +30214 -0.01873779296875 +30215 -0.047515869140625 +30216 -0.140289306640625 +30217 -0.16497802734375 +30218 -0.191986083984375 +30219 -0.22601318359375 +30220 -0.184295654296875 +30221 -0.237396240234375 +30222 -0.161834716796875 +30223 -0.2318115234375 +30224 -0.166595458984375 +30225 -0.240264892578125 +30226 -0.19390869140625 +30227 -0.2591552734375 +30228 -0.22442626953125 +30229 -0.274261474609375 +30230 -0.279754638671875 +30231 -0.302398681640625 +30232 -0.3389892578125 +30233 -0.32879638671875 +30234 -0.3543701171875 +30235 -0.318756103515625 +30236 -0.348175048828125 +30237 -0.290252685546875 +30238 -0.32598876953125 +30239 -0.248809814453125 +30240 -0.2581787109375 +30241 -0.17364501953125 +30242 -0.139801025390625 +30243 -0.062347412109375 +30244 0.014617919921875 +30245 0.073028564453125 +30246 0.144378662109375 +30247 0.185943603515625 +30248 0.221038818359375 +30249 0.254364013671875 +30250 0.27069091796875 +30251 0.29736328125 +30252 0.294036865234375 +30253 0.31536865234375 +30254 0.311767578125 +30255 0.323974609375 +30256 0.339141845703125 +30257 0.335113525390625 +30258 0.360260009765625 +30259 0.33782958984375 +30260 0.360504150390625 +30261 0.321929931640625 +30262 0.308380126953125 +30263 0.2637939453125 +30264 0.18170166015625 +30265 0.147125244140625 +30266 0.0047607421875 +30267 -0.008209228515625 +30268 -0.17559814453125 +30269 -0.16497802734375 +30270 -0.3143310546875 +30271 -0.287384033203125 +30272 -0.36785888671875 +30273 -0.34088134765625 +30274 -0.36248779296875 +30275 -0.3453369140625 +30276 -0.343536376953125 +30277 -0.335540771484375 +30278 -0.3018798828125 +30279 -0.30426025390625 +30280 -0.231414794921875 +30281 -0.246826171875 +30282 -0.117645263671875 +30283 -0.1522216796875 +30284 0.007049560546875 +30285 -0.0460205078125 +30286 0.087982177734375 +30287 0.02874755859375 +30288 0.13946533203125 +30289 0.082489013671875 +30290 0.17425537109375 +30291 0.124298095703125 +30292 0.188201904296875 +30293 0.15008544921875 +30294 0.171234130859375 +30295 0.15118408203125 +30296 0.118438720703125 +30297 0.123077392578125 +30298 0.05706787109375 +30299 0.08624267578125 +30300 -0.010711669921875 +30301 0.04180908203125 +30302 -0.0914306640625 +30303 -0.015625 +30304 -0.162322998046875 +30305 -0.068603515625 +30306 -0.194549560546875 +30307 -0.09478759765625 +30308 -0.1492919921875 +30309 -0.063873291015625 +30310 -0.02166748046875 +30311 0.028228759765625 +30312 0.124053955078125 +30313 0.13214111328125 +30314 0.211151123046875 +30315 0.188873291015625 +30316 0.240447998046875 +30317 0.19970703125 +30318 0.242218017578125 +30319 0.18878173828125 +30320 0.2257080078125 +30321 0.16400146484375 +30322 0.194366455078125 +30323 0.128692626953125 +30324 0.115509033203125 +30325 0.058013916015625 +30326 0.0128173828125 +30327 -0.029144287109375 +30328 -0.053802490234375 +30329 -0.085968017578125 +30330 -0.110626220703125 +30331 -0.13262939453125 +30332 -0.199493408203125 +30333 -0.2015380859375 +30334 -0.29437255859375 +30335 -0.2725830078125 +30336 -0.33221435546875 +30337 -0.2969970703125 +30338 -0.27972412109375 +30339 -0.24932861328125 +30340 -0.185333251953125 +30341 -0.167572021484375 +30342 -0.128204345703125 +30343 -0.113677978515625 +30344 -0.115692138671875 +30345 -0.0938720703125 +30346 -0.116455078125 +30347 -0.08441162109375 +30348 -0.105926513671875 +30349 -0.066802978515625 +30350 -0.053955078125 +30351 -0.01812744140625 +30352 0.048797607421875 +30353 0.06842041015625 +30354 0.157318115234375 +30355 0.1575927734375 +30356 0.212005615234375 +30357 0.202911376953125 +30358 0.218475341796875 +30359 0.208648681640625 +30360 0.23724365234375 +30361 0.221771240234375 +30362 0.30535888671875 +30363 0.27117919921875 +30364 0.38128662109375 +30365 0.324859619140625 +30366 0.404449462890625 +30367 0.336151123046875 +30368 0.3944091796875 +30369 0.320648193359375 +30370 0.3885498046875 +30371 0.30780029296875 +30372 0.362640380859375 +30373 0.279327392578125 +30374 0.27362060546875 +30375 0.202239990234375 +30376 0.11712646484375 +30377 0.073577880859375 +30378 -0.054901123046875 +30379 -0.065948486328125 +30380 -0.19085693359375 +30381 -0.176025390625 +30382 -0.28570556640625 +30383 -0.252532958984375 +30384 -0.339263916015625 +30385 -0.295257568359375 +30386 -0.3775634765625 +30387 -0.3243408203125 +30388 -0.445709228515625 +30389 -0.3748779296875 +30390 -0.535064697265625 +30391 -0.44036865234375 +30392 -0.629058837890625 +30393 -0.5081787109375 +30394 -0.697601318359375 +30395 -0.5552978515625 +30396 -0.70391845703125 +30397 -0.55352783203125 +30398 -0.6424560546875 +30399 -0.498931884765625 +30400 -0.491241455078125 +30401 -0.3748779296875 +30402 -0.265716552734375 +30403 -0.19366455078125 +30404 -0.023712158203125 +30405 -0.000518798828125 +30406 0.201751708984375 +30407 0.17864990234375 +30408 0.375823974609375 +30409 0.316619873046875 +30410 0.485076904296875 +30411 0.40283203125 +30412 0.56884765625 +30413 0.4677734375 +30414 0.634765625 +30415 0.517425537109375 +30416 0.63763427734375 +30417 0.516845703125 +30418 0.5660400390625 +30419 0.457366943359375 +30420 0.4720458984375 +30421 0.379638671875 +30422 0.40692138671875 +30423 0.323699951171875 +30424 0.3778076171875 +30425 0.295440673828125 +30426 0.376953125 +30427 0.289154052734375 +30428 0.371978759765625 +30429 0.280029296875 +30430 0.313140869140625 +30431 0.229736328125 +30432 0.184417724609375 +30433 0.126068115234375 +30434 0.011199951171875 +30435 -0.011077880859375 +30436 -0.171051025390625 +30437 -0.154083251953125 +30438 -0.33740234375 +30439 -0.283538818359375 +30440 -0.47198486328125 +30441 -0.387115478515625 +30442 -0.560394287109375 +30443 -0.4537353515625 +30444 -0.58056640625 +30445 -0.466461181640625 +30446 -0.54754638671875 +30447 -0.437103271484375 +30448 -0.508575439453125 +30449 -0.402587890625 +30450 -0.459503173828125 +30451 -0.359893798828125 +30452 -0.394378662109375 +30453 -0.304718017578125 +30454 -0.35260009765625 +30455 -0.267852783203125 +30456 -0.31170654296875 +30457 -0.232086181640625 +30458 -0.197418212890625 +30459 -0.139984130859375 +30460 -0.007965087890625 +30461 0.009613037109375 +30462 0.207489013671875 +30463 0.178436279296875 +30464 0.409210205078125 +30465 0.33563232421875 +30466 0.57208251953125 +30467 0.462310791015625 +30468 0.66595458984375 +30469 0.534698486328125 +30470 0.65875244140625 +30471 0.526580810546875 +30472 0.56744384765625 +30473 0.451416015625 +30474 0.431396484375 +30475 0.340850830078125 +30476 0.29443359375 +30477 0.2301025390625 +30478 0.182464599609375 +30479 0.13995361328125 +30480 0.06365966796875 +30481 0.044586181640625 +30482 -0.075958251953125 +30483 -0.0673828125 +30484 -0.189422607421875 +30485 -0.158050537109375 +30486 -0.271942138671875 +30487 -0.223602294921875 +30488 -0.342529296875 +30489 -0.27947998046875 +30490 -0.364166259765625 +30491 -0.29583740234375 +30492 -0.327239990234375 +30493 -0.264923095703125 +30494 -0.2769775390625 +30495 -0.22332763671875 +30496 -0.253692626953125 +30497 -0.203643798828125 +30498 -0.24365234375 +30499 -0.194793701171875 +30500 -0.1983642578125 +30501 -0.157623291015625 +30502 -0.116241455078125 +30503 -0.090850830078125 +30504 -0.036834716796875 +30505 -0.02642822265625 +30506 0.034881591796875 +30507 0.031585693359375 +30508 0.09124755859375 +30509 0.076995849609375 +30510 0.10888671875 +30511 0.090972900390625 +30512 0.125518798828125 +30513 0.103973388671875 +30514 0.15771484375 +30515 0.129425048828125 +30516 0.17828369140625 +30517 0.145355224609375 +30518 0.17108154296875 +30519 0.1387939453125 +30520 0.129974365234375 +30521 0.104827880859375 +30522 0.082427978515625 +30523 0.065673828125 +30524 0.027679443359375 +30525 0.02081298828125 +30526 -0.065643310546875 +30527 -0.055084228515625 +30528 -0.15936279296875 +30529 -0.131134033203125 +30530 -0.21307373046875 +30531 -0.174713134765625 +30532 -0.234649658203125 +30533 -0.192169189453125 +30534 -0.2001953125 +30535 -0.164215087890625 +30536 -0.119171142578125 +30537 -0.0985107421875 +30538 -0.024749755859375 +30539 -0.021881103515625 +30540 0.085784912109375 +30541 0.06787109375 +30542 0.178131103515625 +30543 0.14300537109375 +30544 0.215576171875 +30545 0.173828125 +30546 0.211456298828125 +30547 0.171051025390625 +30548 0.17523193359375 +30549 0.142303466796875 +30550 0.128753662109375 +30551 0.105194091796875 +30552 0.1019287109375 +30553 0.083892822265625 +30554 0.0743408203125 +30555 0.0618896484375 +30556 0.04327392578125 +30557 0.036956787109375 +30558 0.038177490234375 +30559 0.03289794921875 +30560 0.076263427734375 +30561 0.063629150390625 +30562 0.14105224609375 +30563 0.1158447265625 +30564 0.186431884765625 +30565 0.15228271484375 +30566 0.188812255859375 +30567 0.153900146484375 +30568 0.1390380859375 +30569 0.11328125 +30570 0.041778564453125 +30571 0.03424072265625 +30572 -0.079437255859375 +30573 -0.06414794921875 +30574 -0.219390869140625 +30575 -0.17767333984375 +30576 -0.367828369140625 +30577 -0.298004150390625 +30578 -0.494873046875 +30579 -0.4010009765625 +30580 -0.556243896484375 +30581 -0.450836181640625 +30582 -0.508697509765625 +30583 -0.412567138671875 +30584 -0.3756103515625 +30585 -0.305084228515625 +30586 -0.218902587890625 +30587 -0.178436279296875 +30588 -0.063751220703125 +30589 -0.052978515625 +30590 0.091552734375 +30591 0.072662353515625 +30592 0.23602294921875 +30593 0.189605712890625 +30594 0.342987060546875 +30595 0.27630615234375 +30596 0.39520263671875 +30597 0.318817138671875 +30598 0.389373779296875 +30599 0.314453125 +30600 0.324249267578125 +30601 0.26220703125 +30602 0.224090576171875 +30603 0.181640625 +30604 0.124267578125 +30605 0.101287841796875 +30606 0.037078857421875 +30607 0.03106689453125 +30608 -0.010101318359375 +30609 -0.006866455078125 +30610 -0.019439697265625 +30611 -0.014312744140625 +30612 -0.022796630859375 +30613 -0.016998291015625 +30614 -0.001556396484375 +30615 9.1552734375e-05 +30616 0.056304931640625 +30617 0.04669189453125 +30618 0.106719970703125 +30619 0.08721923828125 +30620 0.096893310546875 +30621 0.079010009765625 +30622 0.042694091796875 +30623 0.034942626953125 +30624 -0.018035888671875 +30625 -0.014434814453125 +30626 -0.07586669921875 +30627 -0.06146240234375 +30628 -0.11944580078125 +30629 -0.096954345703125 +30630 -0.15972900390625 +30631 -0.1297607421875 +30632 -0.202606201171875 +30633 -0.16461181640625 +30634 -0.24859619140625 +30635 -0.201904296875 +30636 -0.30517578125 +30637 -0.2476806640625 +30638 -0.36212158203125 +30639 -0.293670654296875 +30640 -0.39141845703125 +30641 -0.317291259765625 +30642 -0.35528564453125 +30643 -0.2879638671875 +30644 -0.249969482421875 +30645 -0.20269775390625 +30646 -0.092864990234375 +30647 -0.0755615234375 +30648 0.08905029296875 +30649 0.0716552734375 +30650 0.2352294921875 +30651 0.19000244140625 +30652 0.318817138671875 +30653 0.257781982421875 +30654 0.358642578125 +30655 0.290191650390625 +30656 0.347747802734375 +30657 0.281585693359375 +30658 0.28564453125 +30659 0.2315673828125 +30660 0.223175048828125 +30661 0.18121337890625 +30662 0.196746826171875 +30663 0.159942626953125 +30664 0.179840087890625 +30665 0.146331787109375 +30666 0.155548095703125 +30667 0.126678466796875 +30668 0.151214599609375 +30669 0.12310791015625 +30670 0.156951904296875 +30671 0.12762451171875 +30672 0.13177490234375 +30673 0.10711669921875 +30674 0.100799560546875 +30675 0.0819091796875 +30676 0.087127685546875 +30677 0.070648193359375 +30678 0.05487060546875 +30679 0.044342041015625 +30680 -0.009002685546875 +30681 -0.00750732421875 +30682 -0.10400390625 +30683 -0.08447265625 +30684 -0.229400634765625 +30685 -0.18597412109375 +30686 -0.35552978515625 +30687 -0.28802490234375 +30688 -0.441925048828125 +30689 -0.357879638671875 +30690 -0.473846435546875 +30691 -0.383697509765625 +30692 -0.464813232421875 +30693 -0.3763427734375 +30694 -0.419097900390625 +30695 -0.33929443359375 +30696 -0.334320068359375 +30697 -0.2706298828125 +30698 -0.227935791015625 +30699 -0.1844482421875 +30700 -0.12347412109375 +30701 -0.099822998046875 +30702 -0.02764892578125 +30703 -0.022186279296875 +30704 0.077667236328125 +30705 0.063140869140625 +30706 0.2132568359375 +30707 0.17291259765625 +30708 0.38885498046875 +30709 0.314971923828125 +30710 0.582794189453125 +30711 0.4718017578125 +30712 0.734039306640625 +30713 0.594085693359375 +30714 0.800140380859375 +30715 0.64752197265625 +30716 0.7783203125 +30717 0.629852294921875 +30718 0.6651611328125 +30719 0.538299560546875 +30720 0.45965576171875 +30721 0.371612548828125 +30722 0.199188232421875 +30723 0.159454345703125 +30724 -0.050689697265625 +30725 -0.044219970703125 +30726 -0.23297119140625 +30727 -0.19171142578125 +30728 -0.33013916015625 +30729 -0.2684326171875 +30730 -0.368408203125 +30731 -0.2965087890625 +30732 -0.378936767578125 +30733 -0.302215576171875 +30734 -0.376983642578125 +30735 -0.2984619140625 +30736 -0.37969970703125 +30737 -0.29974365234375 +30738 -0.391510009765625 +30739 -0.309722900390625 +30740 -0.385345458984375 +30741 -0.30560302734375 +30742 -0.3419189453125 +30743 -0.271087646484375 +30744 -0.28289794921875 +30745 -0.2242431640625 +30746 -0.251617431640625 +30747 -0.2012939453125 +30748 -0.266143798828125 +30749 -0.21722412109375 +30750 -0.273345947265625 +30751 -0.227203369140625 +30752 -0.216796875 +30753 -0.18359375 +30754 -0.128265380859375 +30755 -0.112884521484375 +30756 -0.068145751953125 +30757 -0.065643310546875 +30758 -0.0430908203125 +30759 -0.04730224609375 +30760 -0.024444580078125 +30761 -0.03363037109375 +30762 0.020721435546875 +30763 0.00311279296875 +30764 0.124481201171875 +30765 0.08990478515625 +30766 0.25787353515625 +30767 0.202392578125 +30768 0.379119873046875 +30769 0.305389404296875 +30770 0.47991943359375 +30771 0.39190673828125 +30772 0.5281982421875 +30773 0.434844970703125 +30774 0.511138916015625 +30775 0.423309326171875 +30776 0.456207275390625 +30777 0.380218505859375 +30778 0.407470703125 +30779 0.3424072265625 +30780 0.383758544921875 +30781 0.325531005859375 +30782 0.35687255859375 +30783 0.30572509765625 +30784 0.31182861328125 +30785 0.270263671875 +30786 0.250885009765625 +30787 0.220916748046875 +30788 0.1654052734375 +30789 0.150360107421875 +30790 0.035247802734375 +30791 0.0416259765625 +30792 -0.142059326171875 +30793 -0.10736083984375 +30794 -0.33563232421875 +30795 -0.270660400390625 +30796 -0.5345458984375 +30797 -0.43902587890625 +30798 -0.72186279296875 +30799 -0.59814453125 +30800 -0.836669921875 +30801 -0.696746826171875 +30802 -0.8326416015625 +30803 -0.69580078125 +30804 -0.7296142578125 +30805 -0.611846923828125 +30806 -0.582550048828125 +30807 -0.490875244140625 +30808 -0.440093994140625 +30809 -0.37359619140625 +30810 -0.324310302734375 +30811 -0.2784423828125 +30812 -0.20147705078125 +30813 -0.177001953125 +30814 -0.044647216796875 +30815 -0.0465087890625 +30816 0.103973388671875 +30817 0.07763671875 +30818 0.202392578125 +30819 0.16015625 +30820 0.264495849609375 +30821 0.21270751953125 +30822 0.338897705078125 +30823 0.276092529296875 +30824 0.443817138671875 +30825 0.36553955078125 +30826 0.545074462890625 +30827 0.452239990234375 +30828 0.6173095703125 +30829 0.514801025390625 +30830 0.6524658203125 +30831 0.54638671875 +30832 0.66339111328125 +30833 0.557647705078125 +30834 0.6561279296875 +30835 0.553558349609375 +30836 0.606781005859375 +30837 0.513916015625 +30838 0.501190185546875 +30839 0.426727294921875 +30840 0.352783203125 +30841 0.30322265625 +30842 0.176544189453125 +30843 0.155914306640625 +30844 -0.034820556640625 +30845 -0.02130126953125 +30846 -0.258209228515625 +30847 -0.20904541015625 +30848 -0.44244384765625 +30849 -0.36431884765625 +30850 -0.5753173828125 +30851 -0.476806640625 +30852 -0.65203857421875 +30853 -0.542449951171875 +30854 -0.641632080078125 +30855 -0.535125732421875 +30856 -0.562164306640625 +30857 -0.469940185546875 +30858 -0.458038330078125 +30859 -0.384124755859375 +30860 -0.350555419921875 +30861 -0.29547119140625 +30862 -0.260528564453125 +30863 -0.221343994140625 +30864 -0.192108154296875 +30865 -0.165191650390625 +30866 -0.141937255859375 +30867 -0.1241455078125 +30868 -0.1021728515625 +30869 -0.091552734375 +30870 -0.062896728515625 +30871 -0.05902099609375 +30872 -0.011932373046875 +30873 -0.01629638671875 +30874 0.062835693359375 +30875 0.046783447265625 +30876 0.148712158203125 +30877 0.119537353515625 +30878 0.241729736328125 +30879 0.19854736328125 +30880 0.34912109375 +30881 0.28985595703125 +30882 0.457305908203125 +30883 0.381988525390625 +30884 0.54388427734375 +30885 0.4560546875 +30886 0.5728759765625 +30887 0.481781005859375 +30888 0.506591796875 +30889 0.427398681640625 +30890 0.351226806640625 +30891 0.298065185546875 +30892 0.146514892578125 +30893 0.127105712890625 +30894 -0.05523681640625 +30895 -0.041595458984375 +30896 -0.21624755859375 +30897 -0.176361083984375 +30898 -0.334930419921875 +30899 -0.27587890625 +30900 -0.402984619140625 +30901 -0.333160400390625 +30902 -0.4412841796875 +30903 -0.36572265625 +30904 -0.49578857421875 +30905 -0.412139892578125 +30906 -0.5601806640625 +30907 -0.467071533203125 +30908 -0.600738525390625 +30909 -0.50213623046875 +30910 -0.584228515625 +30911 -0.489349365234375 +30912 -0.47930908203125 +30913 -0.402313232421875 +30914 -0.27935791015625 +30915 -0.235443115234375 +30916 -0.0089111328125 +30917 -0.00927734375 +30918 0.268798828125 +30919 0.22308349609375 +30920 0.482818603515625 +30921 0.402130126953125 +30922 0.60369873046875 +30923 0.503143310546875 +30924 0.650421142578125 +30925 0.542083740234375 +30926 0.66400146484375 +30927 0.553436279296875 +30928 0.6414794921875 +30929 0.53466796875 +30930 0.572540283203125 +30931 0.47711181640625 +30932 0.498138427734375 +30933 0.4151611328125 +30934 0.439453125 +30935 0.3665771484375 +30936 0.375518798828125 +30937 0.313690185546875 +30938 0.274505615234375 +30939 0.229705810546875 +30940 0.1087646484375 +30941 0.09136962890625 +30942 -0.099395751953125 +30943 -0.0826416015625 +30944 -0.3182373046875 +30945 -0.265655517578125 +30946 -0.5489501953125 +30947 -0.458770751953125 +30948 -0.7738037109375 +30949 -0.647064208984375 +30950 -0.86383056640625 +30951 -0.7861328125 +30952 -0.870391845703125 +30953 -0.848052978515625 +30954 -0.86895751953125 +30955 -0.847686767578125 +30956 -0.861053466796875 +30957 -0.79608154296875 +30958 -0.765869140625 +30959 -0.678680419921875 +30960 -0.5301513671875 +30961 -0.485992431640625 +30962 -0.214691162109375 +30963 -0.223968505859375 +30964 0.137359619140625 +30965 0.071258544921875 +30966 0.474822998046875 +30967 0.35662841796875 +30968 0.76239013671875 +30969 0.602325439453125 +30970 0.867462158203125 +30971 0.78570556640625 +30972 0.870361328125 +30973 0.8602294921875 +30974 0.86480712890625 +30975 0.86566162109375 +30976 0.831817626953125 +30977 0.863800048828125 +30978 0.677581787109375 +30979 0.856903076171875 +30980 0.495880126953125 +30981 0.77191162109375 +30982 0.30767822265625 +30983 0.64141845703125 +30984 0.116180419921875 +30985 0.48681640625 +30986 -0.110748291015625 +30987 0.27996826171875 +30988 -0.381805419921875 +30989 0.014312744140625 +30990 -0.6572265625 +30991 -0.273223876953125 +30992 -0.857421875 +30993 -0.5308837890625 +30994 -0.870391845703125 +30995 -0.72161865234375 +30996 -0.870391845703125 +30997 -0.8394775390625 +30998 -0.86444091796875 +30999 -0.8603515625 +31000 -0.85723876953125 +31001 -0.86590576171875 +31002 -0.790008544921875 +31003 -0.86773681640625 +31004 -0.62847900390625 +31005 -0.8607177734375 +31006 -0.3956298828125 +31007 -0.762725830078125 +31008 -0.126708984375 +31009 -0.558319091796875 +31010 0.150115966796875 +31011 -0.321685791015625 +31012 0.424041748046875 +31013 -0.062744140625 +31014 0.670623779296875 +31015 0.195343017578125 +31016 0.854522705078125 +31017 0.419158935546875 +31018 0.866485595703125 +31019 0.5936279296875 +31020 0.86920166015625 +31021 0.70562744140625 +31022 0.8653564453125 +31023 0.771270751953125 +31024 0.857147216796875 +31025 0.80242919921875 +31026 0.766845703125 +31027 0.796661376953125 +31028 0.628509521484375 +31029 0.758453369140625 +31030 0.462127685546875 +31031 0.68194580078125 +31032 0.297210693359375 +31033 0.58953857421875 +31034 0.14862060546875 +31035 0.491851806640625 +31036 -0.00537109375 +31037 0.3687744140625 +31038 -0.15753173828125 +31039 0.226593017578125 +31040 -0.31304931640625 +31041 0.0618896484375 +31042 -0.48876953125 +31043 -0.137847900390625 +31044 -0.6416015625 +31045 -0.332000732421875 +31046 -0.751373291015625 +31047 -0.499237060546875 +31048 -0.84619140625 +31049 -0.659881591796875 +31050 -0.861297607421875 +31051 -0.80126953125 +31052 -0.863250732421875 +31053 -0.85888671875 +31054 -0.856597900390625 +31055 -0.860809326171875 +31056 -0.7498779296875 +31057 -0.855682373046875 +31058 -0.624542236328125 +31059 -0.8033447265625 +31060 -0.47808837890625 +31061 -0.7076416015625 +31062 -0.253387451171875 +31063 -0.526947021484375 +31064 0.003692626953125 +31065 -0.300872802734375 +31066 0.2257080078125 +31067 -0.08880615234375 +31068 0.427154541015625 +31069 0.120361328125 +31070 0.643218994140625 +31071 0.35504150390625 +31072 0.855926513671875 +31073 0.607025146484375 +31074 0.870361328125 +31075 0.825927734375 +31076 0.870361328125 +31077 0.866912841796875 +31078 0.862762451171875 +31079 0.870361328125 +31080 0.79669189453125 +31081 0.866241455078125 +31082 0.595794677734375 +31083 0.849365234375 +31084 0.362152099609375 +31085 0.688079833984375 +31086 0.1270751953125 +31087 0.5040283203125 +31088 -0.086944580078125 +31089 0.316253662109375 +31090 -0.2784423828125 +31091 0.126708984375 +31092 -0.484832763671875 +31093 -0.095306396484375 +31094 -0.729583740234375 +31095 -0.367431640625 +31096 -0.86688232421875 +31097 -0.646820068359375 +31098 -0.870391845703125 +31099 -0.857269287109375 +31100 -0.86859130859375 +31101 -0.870391845703125 +31102 -0.86279296875 +31103 -0.870391845703125 +31104 -0.817962646484375 +31105 -0.86346435546875 +31106 -0.6116943359375 +31107 -0.778167724609375 +31108 -0.3128662109375 +31109 -0.52508544921875 +31110 0.039398193359375 +31111 -0.211395263671875 +31112 0.422821044921875 +31113 0.142669677734375 +31114 0.805145263671875 +31115 0.50750732421875 +31116 0.870361328125 +31117 0.8251953125 +31118 0.870361328125 +31119 0.870361328125 +31120 0.860015869140625 +31121 0.870361328125 +31122 0.727935791015625 +31123 0.860992431640625 +31124 0.48114013671875 +31125 0.75042724609375 +31126 0.2059326171875 +31127 0.542449951171875 +31128 -0.06103515625 +31129 0.320953369140625 +31130 -0.29913330078125 +31131 0.1038818359375 +31132 -0.516204833984375 +31133 -0.114471435546875 +31134 -0.7252197265625 +31135 -0.343231201171875 +31136 -0.85980224609375 +31137 -0.55914306640625 +31138 -0.870391845703125 +31139 -0.733428955078125 +31140 -0.870391845703125 +31141 -0.844024658203125 +31142 -0.858062744140625 +31143 -0.8544921875 +31144 -0.673004150390625 +31145 -0.769134521484375 +31146 -0.42694091796875 +31147 -0.64306640625 +31148 -0.2100830078125 +31149 -0.525177001953125 +31150 -0.0362548828125 +31151 -0.424102783203125 +31152 0.10943603515625 +31153 -0.32470703125 +31154 0.23516845703125 +31155 -0.219024658203125 +31156 0.373687744140625 +31157 -0.07891845703125 +31158 0.517791748046875 +31159 0.0875244140625 +31160 0.602783203125 +31161 0.221099853515625 +31162 0.635711669921875 +31163 0.324188232421875 +31164 0.655181884765625 +31165 0.425933837890625 +31166 0.65948486328125 +31167 0.519927978515625 +31168 0.651275634765625 +31169 0.603424072265625 +31170 0.61846923828125 +31171 0.660919189453125 +31172 0.53753662109375 +31173 0.667327880859375 +31174 0.404144287109375 +31175 0.614959716796875 +31176 0.22186279296875 +31177 0.503814697265625 +31178 0.003997802734375 +31179 0.3433837890625 +31180 -0.22100830078125 +31181 0.1573486328125 +31182 -0.42449951171875 +31183 -0.029296875 +31184 -0.579833984375 +31185 -0.1922607421875 +31186 -0.641876220703125 +31187 -0.2901611328125 +31188 -0.6177978515625 +31189 -0.326385498046875 +31190 -0.575531005859375 +31191 -0.356689453125 +31192 -0.526336669921875 +31193 -0.386932373046875 +31194 -0.42645263671875 +31195 -0.374847412109375 +31196 -0.2581787109375 +31197 -0.30078125 +31198 -0.068695068359375 +31199 -0.20196533203125 +31200 0.09222412109375 +31201 -0.11834716796875 +31202 0.232147216796875 +31203 -0.04052734375 +31204 0.3509521484375 +31205 0.03338623046875 +31206 0.410064697265625 +31207 0.070953369140625 +31208 0.372955322265625 +31209 0.0406494140625 +31210 0.2554931640625 +31211 -0.044219970703125 +31212 0.10711669921875 +31213 -0.141998291015625 +31214 -0.052886962890625 +31215 -0.238006591796875 +31216 -0.186279296875 +31217 -0.30157470703125 +31218 -0.23291015625 +31219 -0.283416748046875 +31220 -0.209442138671875 +31221 -0.201446533203125 +31222 -0.174163818359375 +31223 -0.109893798828125 +31224 -0.126739501953125 +31225 -0.01177978515625 +31226 -0.048126220703125 +31227 0.106475830078125 +31228 0.0426025390625 +31229 0.22576904296875 +31230 0.10748291015625 +31231 0.31109619140625 +31232 0.1409912109375 +31233 0.35687255859375 +31234 0.19708251953125 +31235 0.410369873046875 +31236 0.273651123046875 +31237 0.469207763671875 +31238 0.31768798828125 +31239 0.4866943359375 +31240 0.341094970703125 +31241 0.47515869140625 +31242 0.368011474609375 +31243 0.458465576171875 +31244 0.37249755859375 +31245 0.415771484375 +31246 0.30072021484375 +31247 0.3013916015625 +31248 0.1517333984375 +31249 0.117279052734375 +31250 -0.01470947265625 +31251 -0.080047607421875 +31252 -0.1883544921875 +31253 -0.278839111328125 +31254 -0.372711181640625 +31255 -0.480072021484375 +31256 -0.51397705078125 +31257 -0.63360595703125 +31258 -0.57177734375 +31259 -0.701873779296875 +31260 -0.53948974609375 +31261 -0.678375244140625 +31262 -0.43511962890625 +31263 -0.579315185546875 +31264 -0.2962646484375 +31265 -0.439117431640625 +31266 -0.161102294921875 +31267 -0.29327392578125 +31268 -0.0435791015625 +31269 -0.1558837890625 +31270 0.060394287109375 +31271 -0.025238037109375 +31272 0.13665771484375 +31273 0.083740234375 +31274 0.170135498046875 +31275 0.15521240234375 +31276 0.16552734375 +31277 0.191131591796875 +31278 0.15728759765625 +31279 0.2203369140625 +31280 0.150787353515625 +31281 0.24578857421875 +31282 0.12200927734375 +31283 0.244293212890625 +31284 0.080108642578125 +31285 0.222930908203125 +31286 0.05126953125 +31287 0.204620361328125 +31288 0.062896728515625 +31289 0.213897705078125 +31290 0.09271240234375 +31291 0.230987548828125 +31292 0.092987060546875 +31293 0.2137451171875 +31294 0.07855224609375 +31295 0.176666259765625 +31296 0.06427001953125 +31297 0.1346435546875 +31298 0.0347900390625 +31299 0.075592041015625 +31300 -0.01171875 +31301 -0.000274658203125 +31302 -0.056060791015625 +31303 -0.073760986328125 +31304 -0.055511474609375 +31305 -0.1046142578125 +31306 -0.010467529296875 +31307 -0.091522216796875 +31308 0.02508544921875 +31309 -0.081695556640625 +31310 0.025665283203125 +31311 -0.09698486328125 +31312 0.017333984375 +31313 -0.113250732421875 +31314 0.00189208984375 +31315 -0.12860107421875 +31316 -0.03173828125 +31317 -0.15313720703125 +31318 -0.071502685546875 +31319 -0.176605224609375 +31320 -0.13543701171875 +31321 -0.216064453125 +31322 -0.219970703125 +31323 -0.26947021484375 +31324 -0.300506591796875 +31325 -0.3160400390625 +31326 -0.376312255859375 +31327 -0.356597900390625 +31328 -0.416107177734375 +31329 -0.364532470703125 +31330 -0.371124267578125 +31331 -0.2974853515625 +31332 -0.242279052734375 +31333 -0.15771484375 +31334 -0.069732666015625 +31335 0.01739501953125 +31336 0.125640869140625 +31337 0.208099365234375 +31338 0.31268310546875 +31339 0.385650634765625 +31340 0.45501708984375 +31341 0.51702880859375 +31342 0.554779052734375 +31343 0.6041259765625 +31344 0.61065673828125 +31345 0.646087646484375 +31346 0.610931396484375 +31347 0.63299560546875 +31348 0.531463623046875 +31349 0.54400634765625 +31350 0.3883056640625 +31351 0.394622802734375 +31352 0.23468017578125 +31353 0.23394775390625 +31354 0.095245361328125 +31355 0.08544921875 +31356 -0.00396728515625 +31357 -0.02618408203125 +31358 -0.04852294921875 +31359 -0.086761474609375 +31360 -0.055145263671875 +31361 -0.1102294921875 +31362 -0.0758056640625 +31363 -0.14251708984375 +31364 -0.138702392578125 +31365 -0.2083740234375 +31366 -0.209197998046875 +31367 -0.2762451171875 +31368 -0.289031982421875 +31369 -0.347625732421875 +31370 -0.37884521484375 +31371 -0.423248291015625 +31372 -0.456329345703125 +31373 -0.483428955078125 +31374 -0.51641845703125 +31375 -0.524261474609375 +31376 -0.519287109375 +31377 -0.5107421875 +31378 -0.458251953125 +31379 -0.43780517578125 +31380 -0.384796142578125 +31381 -0.35284423828125 +31382 -0.323699951171875 +31383 -0.2791748046875 +31384 -0.269287109375 +31385 -0.21270751953125 +31386 -0.1951904296875 +31387 -0.130645751953125 +31388 -0.100006103515625 +31389 -0.032501220703125 +31390 -0.01055908203125 +31391 0.056976318359375 +31392 0.1033935546875 +31393 0.16461181640625 +31394 0.24908447265625 +31395 0.2967529296875 +31396 0.373199462890625 +31397 0.405487060546875 +31398 0.45806884765625 +31399 0.4752197265625 +31400 0.511474609375 +31401 0.51336669921875 +31402 0.565399169921875 +31403 0.54937744140625 +31404 0.61138916015625 +31405 0.576416015625 +31406 0.5897216796875 +31407 0.541534423828125 +31408 0.4906005859375 +31409 0.436798095703125 +31410 0.33148193359375 +31411 0.278778076171875 +31412 0.147796630859375 +31413 0.100128173828125 +31414 -0.01873779296875 +31415 -0.0609130859375 +31416 -0.140289306640625 +31417 -0.178741455078125 +31418 -0.191986083984375 +31419 -0.230560302734375 +31420 -0.184295654296875 +31421 -0.225616455078125 +31422 -0.161834716796875 +31423 -0.204071044921875 +31424 -0.166595458984375 +31425 -0.203887939453125 +31426 -0.19390869140625 +31427 -0.22119140625 +31428 -0.22442626953125 +31429 -0.239013671875 +31430 -0.279754638671875 +31431 -0.27740478515625 +31432 -0.3389892578125 +31433 -0.3182373046875 +31434 -0.3543701171875 +31435 -0.319244384765625 +31436 -0.348175048828125 +31437 -0.301177978515625 +31438 -0.32598876953125 +31439 -0.269744873046875 +31440 -0.2581787109375 +31441 -0.198883056640625 +31442 -0.139801025390625 +31443 -0.084625244140625 +31444 0.014617919921875 +31445 0.05963134765625 +31446 0.144378662109375 +31447 0.178985595703125 +31448 0.221038818359375 +31449 0.247802734375 +31450 0.27069091796875 +31451 0.289642333984375 +31452 0.294036865234375 +31453 0.305389404296875 +31454 0.311767578125 +31455 0.31402587890625 +31456 0.339141845703125 +31457 0.329742431640625 +31458 0.360260009765625 +31459 0.33880615234375 +31460 0.360504150390625 +31461 0.328643798828125 +31462 0.308380126953125 +31463 0.27130126953125 +31464 0.18170166015625 +31465 0.14727783203125 +31466 0.0047607421875 +31467 -0.02093505859375 +31468 -0.17559814453125 +31469 -0.190582275390625 +31470 -0.3143310546875 +31471 -0.3206787109375 +31472 -0.36785888671875 +31473 -0.37164306640625 +31474 -0.36248779296875 +31475 -0.367156982421875 +31476 -0.343536376953125 +31477 -0.348236083984375 +31478 -0.3018798828125 +31479 -0.30682373046875 +31480 -0.231414794921875 +31481 -0.23760986328125 +31482 -0.117645263671875 +31483 -0.127838134765625 +31484 0.007049560546875 +31485 -0.0072021484375 +31486 0.087982177734375 +31487 0.074371337890625 +31488 0.13946533203125 +31489 0.12933349609375 +31490 0.17425537109375 +31491 0.168792724609375 +31492 0.188201904296875 +31493 0.1885986328125 +31494 0.171234130859375 +31495 0.178802490234375 +31496 0.118438720703125 +31497 0.134429931640625 +31498 0.05706787109375 +31499 0.08062744140625 +31500 -0.010711669921875 +31501 0.0191650390625 +31502 -0.0914306640625 +31503 -0.05609130859375 +31504 -0.162322998046875 +31505 -0.123809814453125 +31506 -0.194549560546875 +31507 -0.15692138671875 +31508 -0.1492919921875 +31509 -0.118865966796875 +31510 -0.02166748046875 +31511 -0.004791259765625 +31512 0.124053955078125 +31513 0.12548828125 +31514 0.211151123046875 +31515 0.20050048828125 +31516 0.240447998046875 +31517 0.221435546875 +31518 0.242218017578125 +31519 0.216949462890625 +31520 0.2257080078125 +31521 0.196075439453125 +31522 0.194366455078125 +31523 0.16229248046875 +31524 0.115509033203125 +31525 0.085205078125 +31526 0.0128173828125 +31527 -0.0128173828125 +31528 -0.053802490234375 +31529 -0.07568359375 +31530 -0.110626220703125 +31531 -0.127960205078125 +31532 -0.199493408203125 +31533 -0.20892333984375 +31534 -0.29437255859375 +31535 -0.29437255859375 +31536 -0.33221435546875 +31537 -0.325469970703125 +31538 -0.27972412109375 +31539 -0.2713623046875 +31540 -0.185333251953125 +31541 -0.17767333984375 +31542 -0.128204345703125 +31543 -0.1187744140625 +31544 -0.115692138671875 +31545 -0.101806640625 +31546 -0.116455078125 +31547 -0.097747802734375 +31548 -0.105926513671875 +31549 -0.0838623046875 +31550 -0.053955078125 +31551 -0.032135009765625 +31552 0.048797607421875 +31553 0.066009521484375 +31554 0.157318115234375 +31555 0.16839599609375 +31556 0.212005615234375 +31557 0.219207763671875 +31558 0.218475341796875 +31559 0.223785400390625 +31560 0.23724365234375 +31561 0.2388916015625 +31562 0.30535888671875 +31563 0.299346923828125 +31564 0.38128662109375 +31565 0.366455078125 +31566 0.404449462890625 +31567 0.383758544921875 +31568 0.3944091796875 +31569 0.36981201171875 +31570 0.3885498046875 +31571 0.35986328125 +31572 0.362640380859375 +31573 0.331512451171875 +31574 0.27362060546875 +31575 0.24462890625 +31576 0.11712646484375 +31577 0.095306396484375 +31578 -0.054901123046875 +31579 -0.06768798828125 +31580 -0.19085693359375 +31581 -0.195953369140625 +31582 -0.28570556640625 +31583 -0.284759521484375 +31584 -0.339263916015625 +31585 -0.333984375 +31586 -0.3775634765625 +31587 -0.3680419921875 +31588 -0.445709228515625 +31589 -0.429290771484375 +31590 -0.535064697265625 +31591 -0.50982666015625 +31592 -0.629058837890625 +31593 -0.59429931640625 +31594 -0.697601318359375 +31595 -0.654754638671875 +31596 -0.70391845703125 +31597 -0.656951904296875 +31598 -0.6424560546875 +31599 -0.595916748046875 +31600 -0.491241455078125 +31601 -0.451263427734375 +31602 -0.265716552734375 +31603 -0.23760986328125 +31604 -0.023712158203125 +31605 -0.009185791015625 +31606 0.201751708984375 +31607 0.202972412109375 +31608 0.375823974609375 +31609 0.366241455078125 +31610 0.485076904296875 +31611 0.468048095703125 +31612 0.56884765625 +31613 0.545257568359375 +31614 0.634765625 +31615 0.6051025390625 +31616 0.63763427734375 +31617 0.60540771484375 +31618 0.5660400390625 +31619 0.535614013671875 +31620 0.4720458984375 +31621 0.444610595703125 +31622 0.40692138671875 +31623 0.38055419921875 +31624 0.3778076171875 +31625 0.350311279296875 +31626 0.376953125 +31627 0.3468017578125 +31628 0.371978759765625 +31629 0.33984375 +31630 0.313140869140625 +31631 0.282989501953125 +31632 0.184417724609375 +31633 0.16131591796875 +31634 0.011199951171875 +31635 -0.0013427734375 +31636 -0.171051025390625 +31637 -0.17181396484375 +31638 -0.33740234375 +31639 -0.3267822265625 +31640 -0.47198486328125 +31641 -0.451416015625 +31642 -0.560394287109375 +31643 -0.5323486328125 +31644 -0.58056640625 +31645 -0.549072265625 +31646 -0.54754638671875 +31647 -0.5157470703125 +31648 -0.508575439453125 +31649 -0.47674560546875 +31650 -0.459503173828125 +31651 -0.4283447265625 +31652 -0.394378662109375 +31653 -0.3651123046875 +31654 -0.35260009765625 +31655 -0.324005126953125 +31656 -0.31170654296875 +31657 -0.284088134765625 +31658 -0.197418212890625 +31659 -0.175933837890625 +31660 -0.007965087890625 +31661 0.0020751953125 +31662 0.207489013671875 +31663 0.203857421875 +31664 0.409210205078125 +31665 0.392242431640625 +31666 0.57208251953125 +31667 0.54376220703125 +31668 0.66595458984375 +31669 0.6302490234375 +31670 0.65875244140625 +31671 0.621795654296875 +31672 0.56744384765625 +31673 0.53436279296875 +31674 0.431396484375 +31675 0.404937744140625 +31676 0.29443359375 +31677 0.274658203125 +31678 0.182464599609375 +31679 0.167877197265625 +31680 0.06365966796875 +31681 0.054931640625 +31682 -0.075958251953125 +31683 -0.077178955078125 +31684 -0.189422607421875 +31685 -0.1844482421875 +31686 -0.271942138671875 +31687 -0.2623291015625 +31688 -0.342529296875 +31689 -0.328582763671875 +31690 -0.364166259765625 +31691 -0.348602294921875 +31692 -0.327239990234375 +31693 -0.31341552734375 +31694 -0.2769775390625 +31695 -0.265380859375 +31696 -0.253692626953125 +31697 -0.242279052734375 +31698 -0.24365234375 +31699 -0.231353759765625 +31700 -0.1983642578125 +31701 -0.18731689453125 +31702 -0.116241455078125 +31703 -0.1087646484375 +31704 -0.036834716796875 +31705 -0.03277587890625 +31706 0.034881591796875 +31707 0.035858154296875 +31708 0.09124755859375 +31709 0.08990478515625 +31710 0.10888671875 +31711 0.107452392578125 +31712 0.125518798828125 +31713 0.12371826171875 +31714 0.15771484375 +31715 0.1541748046875 +31716 0.17828369140625 +31717 0.173370361328125 +31718 0.17108154296875 +31719 0.166229248046875 +31720 0.129974365234375 +31721 0.127044677734375 +31722 0.082427978515625 +31723 0.08154296875 +31724 0.027679443359375 +31725 0.02911376953125 +31726 -0.065643310546875 +31727 -0.059539794921875 +31728 -0.15936279296875 +31729 -0.148590087890625 +31730 -0.21307373046875 +31731 -0.200164794921875 +31732 -0.234649658203125 +31733 -0.221588134765625 +31734 -0.2001953125 +31735 -0.1904296875 +31736 -0.119171142578125 +31737 -0.115478515625 +31738 -0.024749755859375 +31739 -0.027740478515625 +31740 0.085784912109375 +31741 0.07537841796875 +31742 0.178131103515625 +31743 0.1617431640625 +31744 0.215576171875 +31745 0.196807861328125 +31746 0.211456298828125 +31747 0.192840576171875 +31748 0.17523193359375 +31749 0.1585693359375 +31750 0.128753662109375 +31751 0.115020751953125 +31752 0.1019287109375 +31753 0.09100341796875 +31754 0.0743408203125 +31755 0.066650390625 +31756 0.04327392578125 +31757 0.039154052734375 +31758 0.038177490234375 +31759 0.036834716796875 +31760 0.076263427734375 +31761 0.07623291015625 +31762 0.14105224609375 +31763 0.141265869140625 +31764 0.186431884765625 +31765 0.1871337890625 +31766 0.188812255859375 +31767 0.19091796875 +31768 0.1390380859375 +31769 0.1436767578125 +31770 0.041778564453125 +31771 0.0499267578125 +31772 -0.079437255859375 +31773 -0.067535400390625 +31774 -0.219390869140625 +31775 -0.20367431640625 +31776 -0.367828369140625 +31777 -0.348480224609375 +31778 -0.494873046875 +31779 -0.47296142578125 +31780 -0.556243896484375 +31781 -0.5341796875 +31782 -0.508697509765625 +31783 -0.490142822265625 +31784 -0.3756103515625 +31785 -0.363372802734375 +31786 -0.218902587890625 +31787 -0.213714599609375 +31788 -0.063751220703125 +31789 -0.065399169921875 +31790 0.091552734375 +31791 0.08331298828125 +31792 0.23602294921875 +31793 0.22186279296875 +31794 0.342987060546875 +31795 0.32452392578125 +31796 0.39520263671875 +31797 0.3746337890625 +31798 0.389373779296875 +31799 0.3690185546875 +31800 0.324249267578125 +31801 0.306427001953125 +31802 0.224090576171875 +31803 0.210296630859375 +31804 0.124267578125 +31805 0.114837646484375 +31806 0.037078857421875 +31807 0.0318603515625 +31808 -0.010101318359375 +31809 -0.01220703125 +31810 -0.019439697265625 +31811 -0.019561767578125 +31812 -0.022796630859375 +31813 -0.0211181640625 +31814 -0.001556396484375 +31815 0.001007080078125 +31816 0.056304931640625 +31817 0.058380126953125 +31818 0.106719970703125 +31819 0.1082763671875 +31820 0.096893310546875 +31821 0.09954833984375 +31822 0.042694091796875 +31823 0.04754638671875 +31824 -0.018035888671875 +31825 -0.01116943359375 +31826 -0.07586669921875 +31827 -0.067413330078125 +31828 -0.11944580078125 +31829 -0.11016845703125 +31830 -0.15972900390625 +31831 -0.150054931640625 +31832 -0.202606201171875 +31833 -0.19268798828125 +31834 -0.24859619140625 +31835 -0.23846435546875 +31836 -0.30517578125 +31837 -0.2945556640625 +31838 -0.36212158203125 +31839 -0.35101318359375 +31840 -0.39141845703125 +31841 -0.380645751953125 +31842 -0.35528564453125 +31843 -0.3468017578125 +31844 -0.249969482421875 +31845 -0.245819091796875 +31846 -0.092864990234375 +31847 -0.094482421875 +31848 0.08905029296875 +31849 0.081146240234375 +31850 0.2352294921875 +31851 0.22247314453125 +31852 0.318817138671875 +31853 0.303497314453125 +31854 0.358642578125 +31855 0.342437744140625 +31856 0.347747802734375 +31857 0.33251953125 +31858 0.28564453125 +31859 0.273223876953125 +31860 0.223175048828125 +31861 0.2137451171875 +31862 0.196746826171875 +31863 0.189239501953125 +31864 0.179840087890625 +31865 0.17401123046875 +31866 0.155548095703125 +31867 0.151611328125 +31868 0.151214599609375 +31869 0.1484375 +31870 0.156951904296875 +31871 0.154876708984375 +31872 0.13177490234375 +31873 0.131195068359375 +31874 0.100799560546875 +31875 0.1016845703125 +31876 0.087127685546875 +31877 0.088653564453125 +31878 0.05487060546875 +31879 0.057403564453125 +31880 -0.009002685546875 +31881 -0.004669189453125 +31882 -0.10400390625 +31883 -0.0970458984375 +31884 -0.229400634765625 +31885 -0.21905517578125 +31886 -0.35552978515625 +31887 -0.3419189453125 +31888 -0.441925048828125 +31889 -0.4263916015625 +31890 -0.473846435546875 +31891 -0.458221435546875 +31892 -0.464813232421875 +31893 -0.45037841796875 +31894 -0.419097900390625 +31895 -0.406951904296875 +31896 -0.334320068359375 +31897 -0.32562255859375 +31898 -0.227935791015625 +31899 -0.223236083984375 +31900 -0.12347412109375 +31901 -0.12255859375 +31902 -0.02764892578125 +31903 -0.030059814453125 +31904 0.077667236328125 +31905 0.07183837890625 +31906 0.2132568359375 +31907 0.203216552734375 +31908 0.38885498046875 +31909 0.37347412109375 +31910 0.582794189453125 +31911 0.5616455078125 +31912 0.734039306640625 +31913 0.7086181640625 +31914 0.800140380859375 +31915 0.77325439453125 +31916 0.7783203125 +31917 0.752838134765625 +31918 0.6651611328125 +31919 0.644012451171875 +31920 0.45965576171875 +31921 0.445770263671875 +31922 0.199188232421875 +31923 0.194244384765625 +31924 -0.050689697265625 +31925 -0.047149658203125 +31926 -0.23297119140625 +31927 -0.223236083984375 +31928 -0.33013916015625 +31929 -0.31707763671875 +31930 -0.368408203125 +31931 -0.354034423828125 +31932 -0.378936767578125 +31933 -0.3642578125 +31934 -0.376983642578125 +31935 -0.362548828125 +31936 -0.37969970703125 +31937 -0.365509033203125 +31938 -0.391510009765625 +31939 -0.377349853515625 +31940 -0.385345458984375 +31941 -0.37188720703125 +31942 -0.3419189453125 +31943 -0.330413818359375 +31944 -0.28289794921875 +31945 -0.27386474609375 +31946 -0.251617431640625 +31947 -0.244140625 +31948 -0.266143798828125 +31949 -0.258697509765625 +31950 -0.273345947265625 +31951 -0.266082763671875 +31952 -0.216796875 +31953 -0.211669921875 +31954 -0.128265380859375 +31955 -0.12615966796875 +31956 -0.068145751953125 +31957 -0.06805419921875 +31958 -0.0430908203125 +31959 -0.04376220703125 +31960 -0.024444580078125 +31961 -0.025543212890625 +31962 0.020721435546875 +31963 0.018463134765625 +31964 0.124481201171875 +31965 0.1192626953125 +31966 0.25787353515625 +31967 0.248779296875 +31968 0.379119873046875 +31969 0.3665771484375 +31970 0.47991943359375 +31971 0.464599609375 +31972 0.5281982421875 +31973 0.511749267578125 +31974 0.511138916015625 +31975 0.495635986328125 +31976 0.456207275390625 +31977 0.44281005859375 +31978 0.407470703125 +31979 0.39593505859375 +31980 0.383758544921875 +31981 0.373199462890625 +31982 0.35687255859375 +31983 0.3472900390625 +31984 0.31182861328125 +31985 0.3037109375 +31986 0.250885009765625 +31987 0.24462890625 +31988 0.1654052734375 +31989 0.16168212890625 +31990 0.035247802734375 +31991 0.035400390625 +31992 -0.142059326171875 +31993 -0.1365966796875 +31994 -0.33563232421875 +31995 -0.32440185546875 +31996 -0.5345458984375 +31997 -0.517364501953125 +31998 -0.72186279296875 +31999 -0.699066162109375 +32000 -0.836669921875 +32001 -0.81005859375 +32002 -0.8326416015625 +32003 -0.804901123046875 +32004 -0.7296142578125 +32005 -0.703369140625 +32006 -0.582550048828125 +32007 -0.5599365234375 +32008 -0.440093994140625 +32009 -0.422698974609375 +32010 -0.324310302734375 +32011 -0.313232421875 +32012 -0.20147705078125 +32013 -0.197296142578125 +32014 -0.044647216796875 +32015 -0.047393798828125 +32016 0.103973388671875 +32017 0.094696044921875 +32018 0.202392578125 +32019 0.1873779296875 +32020 0.264495849609375 +32021 0.24481201171875 +32022 0.338897705078125 +32023 0.315887451171875 +32024 0.443817138671875 +32025 0.4189453125 +32026 0.545074462890625 +32027 0.519866943359375 +32028 0.6173095703125 +32029 0.59320068359375 +32030 0.6524658203125 +32031 0.63079833984375 +32032 0.66339111328125 +32033 0.64532470703125 +32034 0.6561279296875 +32035 0.642578125 +32036 0.606781005859375 +32037 0.598358154296875 +32038 0.501190185546875 +32039 0.498199462890625 +32040 0.352783203125 +32041 0.355224609375 +32042 0.176544189453125 +32043 0.184112548828125 +32044 -0.034820556640625 +32045 -0.022674560546875 +32046 -0.258209228515625 +32047 -0.242279052734375 +32048 -0.44244384765625 +32049 -0.4237060546875 +32050 -0.5753173828125 +32051 -0.55487060546875 +32052 -0.65203857421875 +32053 -0.63104248046875 +32054 -0.641632080078125 +32055 -0.621246337890625 +32056 -0.562164306640625 +32057 -0.543487548828125 +32058 -0.458038330078125 +32059 -0.442047119140625 +32060 -0.350555419921875 +32061 -0.338043212890625 +32062 -0.260528564453125 +32063 -0.2520751953125 +32064 -0.192108154296875 +32065 -0.188079833984375 +32066 -0.141937255859375 +32067 -0.1424560546875 +32068 -0.1021728515625 +32069 -0.107086181640625 +32070 -0.062896728515625 +32071 -0.07183837890625 +32072 -0.011932373046875 +32073 -0.0242919921875 +32074 0.062835693359375 +32075 0.047821044921875 +32076 0.148712158203125 +32077 0.131988525390625 +32078 0.241729736328125 +32079 0.2242431640625 +32080 0.34912109375 +32081 0.33184814453125 +32082 0.457305908203125 +32083 0.441192626953125 +32084 0.54388427734375 +32085 0.52978515625 +32086 0.5728759765625 +32087 0.561492919921875 +32088 0.506591796875 +32089 0.49847412109375 +32090 0.351226806640625 +32091 0.34674072265625 +32092 0.146514892578125 +32093 0.145782470703125 +32094 -0.05523681640625 +32095 -0.052276611328125 +32096 -0.21624755859375 +32097 -0.2098388671875 +32098 -0.334930419921875 +32099 -0.325469970703125 +32100 -0.402984619140625 +32101 -0.391082763671875 +32102 -0.4412841796875 +32103 -0.427642822265625 +32104 -0.49578857421875 +32105 -0.481201171875 +32106 -0.5601806640625 +32107 -0.54547119140625 +32108 -0.600738525390625 +32109 -0.586700439453125 +32110 -0.584228515625 +32111 -0.571624755859375 +32112 -0.47930908203125 +32113 -0.468780517578125 +32114 -0.27935791015625 +32115 -0.27142333984375 +32116 -0.0089111328125 +32117 -0.00390625 +32118 0.268798828125 +32119 0.270660400390625 +32120 0.482818603515625 +32121 0.4815673828125 +32122 0.60369873046875 +32123 0.5994873046875 +32124 0.650421142578125 +32125 0.6435546875 +32126 0.66400146484375 +32127 0.654937744140625 +32128 0.6414794921875 +32129 0.630767822265625 +32130 0.572540283203125 +32131 0.560821533203125 +32132 0.498138427734375 +32133 0.486053466796875 +32134 0.439453125 +32135 0.42767333984375 +32136 0.375518798828125 +32137 0.36468505859375 +32138 0.274505615234375 +32139 0.265167236328125 +32140 0.1087646484375 +32141 0.10137939453125 +32142 -0.099395751953125 +32143 -0.1044921875 +32144 -0.3182373046875 +32145 -0.320831298828125 +32146 -0.5489501953125 +32147 -0.548980712890625 +32148 -0.7738037109375 +32149 -0.771331787109375 +32150 -0.86383056640625 +32151 -0.863311767578125 +32152 -0.870391845703125 +32153 -0.870391845703125 +32154 -0.86895751953125 +32155 -0.869476318359375 +32156 -0.861053466796875 +32157 -0.862030029296875 +32158 -0.765869140625 +32159 -0.77838134765625 +32160 -0.5301513671875 +32161 -0.5455322265625 +32162 -0.214691162109375 +32163 -0.232025146484375 +32164 0.137359619140625 +32165 0.119049072265625 +32166 0.474822998046875 +32167 0.45654296875 +32168 0.76239013671875 +32169 0.7451171875 +32170 0.867462158203125 +32171 0.86578369140625 +32172 0.870361328125 +32173 0.870361328125 +32174 0.86480712890625 +32175 0.866424560546875 +32176 0.831817626953125 +32177 0.855133056640625 +32178 0.677581787109375 +32179 0.7178955078125 +32180 0.495880126953125 +32181 0.545379638671875 +32182 0.30767822265625 +32183 0.3634033203125 +32184 0.116180419921875 +32185 0.1749267578125 +32186 -0.110748291015625 +32187 -0.05224609375 +32188 -0.381805419921875 +32189 -0.32672119140625 +32190 -0.6572265625 +32191 -0.60845947265625 +32192 -0.857421875 +32193 -0.841217041015625 +32194 -0.870391845703125 +32195 -0.868896484375 +32196 -0.870391845703125 +32197 -0.870391845703125 +32198 -0.86444091796875 +32199 -0.865875244140625 +32200 -0.85723876953125 +32201 -0.860015869140625 +32202 -0.790008544921875 +32203 -0.825897216796875 +32204 -0.62847900390625 +32205 -0.67254638671875 +32206 -0.3956298828125 +32207 -0.445220947265625 +32208 -0.126708984375 +32209 -0.178955078125 +32210 0.150115966796875 +32211 0.09814453125 +32212 0.424041748046875 +32213 0.375152587890625 +32214 0.670623779296875 +32215 0.627410888671875 +32216 0.854522705078125 +32217 0.819610595703125 +32218 0.866485595703125 +32219 0.8636474609375 +32220 0.86920166015625 +32221 0.8675537109375 +32222 0.8653564453125 +32223 0.86492919921875 +32224 0.857147216796875 +32225 0.857940673828125 +32226 0.766845703125 +32227 0.784393310546875 +32228 0.628509521484375 +32229 0.655181884765625 +32230 0.462127685546875 +32231 0.4962158203125 +32232 0.297210693359375 +32233 0.336639404296875 +32234 0.14862060546875 +32235 0.19110107421875 +32236 -0.00537109375 +32237 0.0377197265625 +32238 -0.15753173828125 +32239 -0.116180419921875 +32240 -0.31304931640625 +32241 -0.275634765625 +32242 -0.48876953125 +32243 -0.45721435546875 +32244 -0.6416015625 +32245 -0.617462158203125 +32246 -0.751373291015625 +32247 -0.735748291015625 +32248 -0.84619140625 +32249 -0.839691162109375 +32250 -0.861297607421875 +32251 -0.861572265625 +32252 -0.863250732421875 +32253 -0.864501953125 +32254 -0.856597900390625 +32255 -0.85870361328125 +32256 -0.749298095703125 +32257 -0.775909423828125 +32258 -0.62200927734375 +32259 -0.655609130859375 +32260 -0.473663330078125 +32261 -0.512359619140625 +32262 -0.249298095703125 +32263 -0.288909912109375 +32264 0.00634765625 +32265 -0.03106689453125 +32266 0.227630615234375 +32267 0.193603515625 +32268 0.42828369140625 +32269 0.39935302734375 +32270 0.642120361328125 +32271 0.621124267578125 +32272 0.85540771484375 +32273 0.8524169921875 +32274 0.870361328125 +32275 0.870361328125 +32276 0.870361328125 +32277 0.870361328125 +32278 0.862823486328125 +32279 0.862762451171875 +32280 0.798126220703125 +32281 0.79669189453125 +32282 0.598968505859375 +32283 0.595794677734375 +32284 0.3670654296875 +32285 0.362152099609375 +32286 0.133056640625 +32287 0.1270751953125 +32288 -0.080902099609375 +32289 -0.086944580078125 +32290 -0.2730712890625 +32291 -0.2784423828125 +32292 -0.479248046875 +32293 -0.484832763671875 +32294 -0.72186279296875 +32295 -0.729583740234375 +32296 -0.86572265625 +32297 -0.86688232421875 +32298 -0.870391845703125 +32299 -0.870391845703125 +32300 -0.86968994140625 +32301 -0.86859130859375 +32302 -0.8648681640625 +32303 -0.86279296875 +32304 -0.8447265625 +32305 -0.817962646484375 +32306 -0.64630126953125 +32307 -0.6116943359375 +32308 -0.35528564453125 +32309 -0.3128662109375 +32310 -0.00970458984375 +32311 0.039398193359375 +32312 0.3685302734375 +32313 0.422821044921875 +32314 0.747711181640625 +32315 0.805145263671875 +32316 0.870361328125 +32317 0.870361328125 +32318 0.870361328125 +32319 0.870361328125 +32320 0.86016845703125 +32321 0.860015869140625 +32322 0.7315673828125 +32323 0.727935791015625 +32324 0.48797607421875 +32325 0.48114013671875 +32326 0.215789794921875 +32327 0.2059326171875 +32328 -0.049163818359375 +32329 -0.06103515625 +32330 -0.28656005859375 +32331 -0.29913330078125 +32332 -0.50360107421875 +32333 -0.516204833984375 +32334 -0.71240234375 +32335 -0.7252197265625 +32336 -0.8583984375 +32337 -0.85980224609375 +32338 -0.870391845703125 +32339 -0.870391845703125 +32340 -0.870391845703125 +32341 -0.870391845703125 +32342 -0.8582763671875 +32343 -0.858062744140625 +32344 -0.6783447265625 +32345 -0.673004150390625 +32346 -0.435394287109375 +32347 -0.42694091796875 +32348 -0.219696044921875 +32349 -0.2100830078125 +32350 -0.044921875 +32351 -0.0362548828125 +32352 0.10296630859375 +32353 0.10943603515625 +32354 0.23150634765625 +32355 0.23516845703125 +32356 0.37200927734375 +32357 0.373687744140625 +32358 0.51715087890625 +32359 0.517791748046875 +32360 0.604034423828125 +32361 0.602783203125 +32362 0.639312744140625 +32363 0.635711669921875 +32364 0.66015625 +32365 0.655181884765625 +32366 0.66485595703125 +32367 0.65948486328125 +32368 0.655975341796875 +32369 0.651275634765625 +32370 0.62188720703125 +32371 0.61846923828125 +32372 0.540008544921875 +32373 0.53753662109375 +32374 0.4063720703125 +32375 0.404144287109375 +32376 0.224700927734375 +32377 0.22186279296875 +32378 0.008209228515625 +32379 0.003997802734375 +32380 -0.21527099609375 +32381 -0.22100830078125 +32382 -0.417724609375 +32383 -0.42449951171875 +32384 -0.573028564453125 +32385 -0.579833984375 +32386 -0.637237548828125 +32387 -0.641876220703125 +32388 -0.617095947265625 +32389 -0.6177978515625 +32390 -0.578216552734375 +32391 -0.575531005859375 +32392 -0.53143310546875 +32393 -0.526336669921875 +32394 -0.43438720703125 +32395 -0.42645263671875 +32396 -0.269927978515625 +32397 -0.2581787109375 +32398 -0.083892822265625 +32399 -0.068695068359375 +32400 0.07537841796875 +32401 0.09222412109375 +32402 0.2149658203125 +32403 0.232147216796875 +32404 0.33453369140625 +32405 0.3509521484375 +32406 0.396453857421875 +32407 0.410064697265625 +32408 0.3651123046875 +32409 0.372955322265625 +32410 0.255645751953125 +32411 0.2554931640625 +32412 0.115692138671875 +32413 0.10711669921875 +32414 -0.036285400390625 +32415 -0.052886962890625 +32416 -0.163360595703125 +32417 -0.186279296875 +32418 -0.20745849609375 +32419 -0.23291015625 +32420 -0.1846923828125 +32421 -0.209442138671875 +32422 -0.151458740234375 +32423 -0.174163818359375 +32424 -0.107391357421875 +32425 -0.126739501953125 +32426 -0.033935546875 +32427 -0.048126220703125 +32428 0.050628662109375 +32429 0.0426025390625 +32430 0.109771728515625 +32431 0.10748291015625 +32432 0.138336181640625 +32433 0.1409912109375 +32434 0.188751220703125 +32435 0.19708251953125 +32436 0.25921630859375 +32437 0.273651123046875 +32438 0.298614501953125 +32439 0.31768798828125 +32440 0.318603515625 +32441 0.341094970703125 +32442 0.34271240234375 +32443 0.368011474609375 +32444 0.34588623046875 +32445 0.37249755859375 +32446 0.27606201171875 +32447 0.30072021484375 +32448 0.132293701171875 +32449 0.1517333984375 +32450 -0.027618408203125 +32451 -0.01470947265625 +32452 -0.193817138671875 +32453 -0.1883544921875 +32454 -0.36981201171875 +32455 -0.372711181640625 +32456 -0.503692626953125 +32457 -0.51397705078125 +32458 -0.556488037109375 +32459 -0.57177734375 +32460 -0.522003173828125 +32461 -0.53948974609375 +32462 -0.4178466796875 +32463 -0.43511962890625 +32464 -0.280609130859375 +32465 -0.2962646484375 +32466 -0.147369384765625 +32467 -0.161102294921875 +32468 -0.031707763671875 +32469 -0.0435791015625 +32470 0.0701904296875 +32471 0.060394287109375 +32472 0.144561767578125 +32473 0.13665771484375 +32474 0.176849365234375 +32475 0.170135498046875 +32476 0.171630859375 +32477 0.16552734375 +32478 0.16229248046875 +32479 0.15728759765625 +32480 0.154144287109375 +32481 0.150787353515625 +32482 0.1240234375 +32483 0.12200927734375 +32484 0.0809326171875 +32485 0.080108642578125 +32486 0.05035400390625 +32487 0.05126953125 +32488 0.05902099609375 +32489 0.062896728515625 +32490 0.08544921875 +32491 0.09271240234375 +32492 0.0836181640625 +32493 0.092987060546875 +32494 0.067962646484375 +32495 0.07855224609375 +32496 0.052947998046875 +32497 0.06427001953125 +32498 0.02374267578125 +32499 0.0347900390625 +32500 -0.021392822265625 +32501 -0.01171875 +32502 -0.06390380859375 +32503 -0.056060791015625 +32504 -0.06243896484375 +32505 -0.055511474609375 +32506 -0.0174560546875 +32507 -0.010467529296875 +32508 0.01873779296875 +32509 0.02508544921875 +32510 0.0213623046875 +32511 0.025665283203125 +32512 0.015289306640625 +32513 0.017333984375 +32514 0.00225830078125 +32515 0.00189208984375 +32516 -0.028289794921875 +32517 -0.03173828125 +32518 -0.06494140625 +32519 -0.071502685546875 +32520 -0.124755859375 +32521 -0.13543701171875 +32522 -0.204345703125 +32523 -0.219970703125 +32524 -0.28033447265625 +32525 -0.300506591796875 +32526 -0.352020263671875 +32527 -0.376312255859375 +32528 -0.38970947265625 +32529 -0.416107177734375 +32530 -0.347076416015625 +32531 -0.371124267578125 +32532 -0.2249755859375 +32533 -0.242279052734375 +32534 -0.061553955078125 +32535 -0.069732666015625 +32536 0.12335205078125 +32537 0.125640869140625 +32538 0.3001708984375 +32539 0.31268310546875 +32540 0.43438720703125 +32541 0.45501708984375 +32542 0.528076171875 +32543 0.554779052734375 +32544 0.580047607421875 +32545 0.61065673828125 +32546 0.579254150390625 +32547 0.610931396484375 +32548 0.502838134765625 +32549 0.531463623046875 +32550 0.366058349609375 +32551 0.3883056640625 +32552 0.219482421875 +32553 0.23468017578125 +32554 0.08660888671875 +32555 0.095245361328125 +32556 -0.007843017578125 +32557 -0.00396728515625 +32558 -0.050140380859375 +32559 -0.04852294921875 +32560 -0.05615234375 +32561 -0.055145263671875 +32562 -0.075347900390625 +32563 -0.0758056640625 +32564 -0.134490966796875 +32565 -0.138702392578125 +32566 -0.200714111328125 +32567 -0.209197998046875 +32568 -0.275726318359375 +32569 -0.289031982421875 +32570 -0.360198974609375 +32571 -0.37884521484375 +32572 -0.432952880859375 +32573 -0.456329345703125 +32574 -0.4892578125 +32575 -0.51641845703125 +32576 -0.491302490234375 +32577 -0.519287109375 +32578 -0.432769775390625 +32579 -0.458251953125 +32580 -0.36260986328125 +32581 -0.384796142578125 +32582 -0.304351806640625 +32583 -0.323699951171875 +32584 -0.252593994140625 +32585 -0.269287109375 +32586 -0.18231201171875 +32587 -0.1951904296875 +32588 -0.0921630859375 +32589 -0.100006103515625 +32590 -0.00762939453125 +32591 -0.01055908203125 +32592 0.10003662109375 +32593 0.1033935546875 +32594 0.237762451171875 +32595 0.24908447265625 +32596 0.354949951171875 +32597 0.373199462890625 +32598 0.43487548828125 +32599 0.45806884765625 +32600 0.48492431640625 +32601 0.511474609375 +32602 0.535552978515625 +32603 0.565399169921875 +32604 0.5787353515625 +32605 0.61138916015625 +32606 0.557769775390625 +32607 0.5897216796875 +32608 0.463348388671875 +32609 0.4906005859375 +32610 0.312103271484375 +32611 0.33148193359375 +32612 0.137664794921875 +32613 0.147796630859375 +32614 -0.020355224609375 +32615 -0.01873779296875 +32616 -0.135498046875 +32617 -0.140289306640625 +32618 -0.184173583984375 +32619 -0.191986083984375 +32620 -0.17633056640625 +32621 -0.184295654296875 +32622 -0.1544189453125 +32623 -0.161834716796875 +32624 -0.1583251953125 +32625 -0.166595458984375 +32626 -0.18365478515625 +32627 -0.19390869140625 +32628 -0.212066650390625 +32629 -0.22442626953125 +32630 -0.26409912109375 +32631 -0.279754638671875 +32632 -0.319976806640625 +32633 -0.3389892578125 +32634 -0.334320068359375 +32635 -0.3543701171875 +32636 -0.32830810546875 +32637 -0.348175048828125 +32638 -0.3072509765625 +32639 -0.32598876953125 +32640 -0.24298095703125 +32641 -0.2581787109375 +32642 -0.13079833984375 +32643 -0.139801025390625 +32644 0.015533447265625 +32645 0.014617919921875 +32646 0.138336181640625 +32647 0.144378662109375 +32648 0.21063232421875 +32649 0.221038818359375 +32650 0.257232666015625 +32651 0.27069091796875 +32652 0.278900146484375 +32653 0.294036865234375 +32654 0.2952880859375 +32655 0.311767578125 +32656 0.320892333984375 +32657 0.339141845703125 +32658 0.34039306640625 +32659 0.360260009765625 +32660 0.339996337890625 +32661 0.360504150390625 +32662 0.290313720703125 +32663 0.308380126953125 +32664 0.17071533203125 +32665 0.18170166015625 +32666 0.004058837890625 +32667 0.0047607421875 +32668 -0.165740966796875 +32669 -0.17559814453125 +32670 -0.2965087890625 +32671 -0.3143310546875 +32672 -0.347381591796875 +32673 -0.36785888671875 +32674 -0.3428955078125 +32675 -0.36248779296875 +32676 -0.325439453125 +32677 -0.343536376953125 +32678 -0.2864990234375 +32679 -0.3018798828125 +32680 -0.220367431640625 +32681 -0.231414794921875 +32682 -0.11346435546875 +32683 -0.117645263671875 +32684 0.00384521484375 +32685 0.007049560546875 +32686 0.080352783203125 +32687 0.087982177734375 +32688 0.12939453125 +32689 0.13946533203125 +32690 0.162872314453125 +32691 0.17425537109375 +32692 0.17681884765625 +32693 0.188201904296875 +32694 0.1617431640625 +32695 0.171234130859375 +32696 0.113006591796875 +32697 0.118438720703125 +32698 0.05609130859375 +32699 0.05706787109375 +32700 -0.006988525390625 +32701 -0.010711669921875 +32702 -0.082366943359375 +32703 -0.0914306640625 +32704 -0.148712158203125 +32705 -0.162322998046875 +32706 -0.179046630859375 +32707 -0.194549560546875 +32708 -0.137054443359375 +32709 -0.1492919921875 +32710 -0.01806640625 +32711 -0.02166748046875 +32712 0.117767333984375 +32713 0.124053955078125 +32714 0.19866943359375 +32715 0.211151123046875 +32716 0.2254638671875 +32717 0.240447998046875 +32718 0.226470947265625 +32719 0.242218017578125 +32720 0.210418701171875 +32721 0.2257080078125 +32722 0.1805419921875 +32723 0.194366455078125 +32724 0.10626220703125 +32725 0.115509033203125 +32726 0.009765625 +32727 0.0128173828125 +32728 -0.052825927734375 +32729 -0.053802490234375 +32730 -0.1060791015625 +32731 -0.110626220703125 +32732 -0.189208984375 +32733 -0.199493408203125 +32734 -0.277801513671875 +32735 -0.29437255859375 +32736 -0.3128662109375 +32737 -0.33221435546875 +32738 -0.2633056640625 +32739 -0.27972412109375 +32740 -0.174468994140625 +32741 -0.185333251953125 +32742 -0.120452880859375 +32743 -0.128204345703125 +32744 -0.108154296875 +32745 -0.115692138671875 +32746 -0.1082763671875 +32747 -0.116455078125 +32748 -0.097900390625 +32749 -0.105926513671875 +32750 -0.048797607421875 +32751 -0.053955078125 +32752 0.0477294921875 +32753 0.048797607421875 +32754 0.1495361328125 +32755 0.157318115234375 +32756 0.2008056640625 +32757 0.212005615234375 +32758 0.206817626953125 +32759 0.218475341796875 +32760 0.2242431640625 +32761 0.23724365234375 +32762 0.287750244140625 +32763 0.30535888671875 +32764 0.35845947265625 +32765 0.38128662109375 +32766 0.37969970703125 +32767 0.404449462890625 +32768 0.36920166015625 +32769 0.3944091796875 +32770 0.361358642578125 +32771 0.3885498046875 +32772 0.334503173828125 +32773 0.362640380859375 +32774 0.25006103515625 +32775 0.27362060546875 +32776 0.10443115234375 +32777 0.11712646484375 +32778 -0.055084228515625 +32779 -0.054901123046875 +32780 -0.181549072265625 +32781 -0.19085693359375 +32782 -0.270233154296875 +32783 -0.28570556640625 +32784 -0.320831298828125 +32785 -0.339263916015625 +32786 -0.35675048828125 +32787 -0.3775634765625 +32788 -0.418701171875 +32789 -0.445709228515625 +32790 -0.4989013671875 +32791 -0.535064697265625 +32792 -0.582427978515625 +32793 -0.629058837890625 +32794 -0.642181396484375 +32795 -0.697601318359375 +32796 -0.64508056640625 +32797 -0.70391845703125 +32798 -0.5863037109375 +32799 -0.6424560546875 +32800 -0.4461669921875 +32801 -0.491241455078125 +32802 -0.238800048828125 +32803 -0.265716552734375 +32804 -0.016693115234375 +32805 -0.023712158203125 +32806 0.190093994140625 +32807 0.201751708984375 +32808 0.34991455078125 +32809 0.375823974609375 +32810 0.45050048828125 +32811 0.485076904296875 +32812 0.52734375 +32813 0.56884765625 +32814 0.58734130859375 +32815 0.634765625 +32816 0.589599609375 +32817 0.63763427734375 +32818 0.523834228515625 +32819 0.5660400390625 +32820 0.437164306640625 +32821 0.4720458984375 +32822 0.376068115234375 +32823 0.40692138671875 +32824 0.347137451171875 +32825 0.3778076171875 +32826 0.343505859375 +32827 0.376953125 +32828 0.3360595703125 +32829 0.371978759765625 +32830 0.280029296875 +32831 0.313140869140625 +32832 0.16107177734375 +32833 0.184417724609375 +32834 0.002288818359375 +32835 0.011199951171875 +32836 -0.1641845703125 +32837 -0.171051025390625 +32838 -0.315704345703125 +32839 -0.33740234375 +32840 -0.437896728515625 +32841 -0.47198486328125 +32842 -0.517730712890625 +32843 -0.560394287109375 +32844 -0.5352783203125 +32845 -0.58056640625 +32846 -0.504180908203125 +32847 -0.54754638671875 +32848 -0.46722412109375 +32849 -0.508575439453125 +32850 -0.4207763671875 +32851 -0.459503173828125 +32852 -0.359588623046875 +32853 -0.394378662109375 +32854 -0.319427490234375 +32855 -0.35260009765625 +32856 -0.28009033203125 +32857 -0.31170654296875 +32858 -0.174560546875 +32859 -0.197418212890625 +32860 -0.001312255859375 +32861 -0.007965087890625 +32862 0.195068359375 +32863 0.207489013671875 +32864 0.3785400390625 +32865 0.409210205078125 +32866 0.5263671875 +32867 0.57208251953125 +32868 0.611297607421875 +32869 0.66595458984375 +32870 0.604339599609375 +32871 0.65875244140625 +32872 0.5208740234375 +32873 0.56744384765625 +32874 0.39654541015625 +32875 0.431396484375 +32876 0.271087646484375 +32877 0.29443359375 +32878 0.167999267578125 +32879 0.182464599609375 +32880 0.058624267578125 +32881 0.06365966796875 +32882 -0.069549560546875 +32883 -0.075958251953125 +32884 -0.1739501953125 +32885 -0.189422607421875 +32886 -0.25018310546875 +32887 -0.271942138671875 +32888 -0.315338134765625 +32889 -0.342529296875 +32890 -0.335906982421875 +32891 -0.364166259765625 +32892 -0.30316162109375 +32893 -0.327239990234375 +32894 -0.2579345703125 +32895 -0.2769775390625 +32896 -0.236663818359375 +32897 -0.253692626953125 +32898 -0.226959228515625 +32899 -0.24365234375 +32900 -0.18505859375 +32901 -0.1983642578125 +32902 -0.10955810546875 +32903 -0.116241455078125 +32904 -0.036285400390625 +32905 -0.036834716796875 +32906 0.0301513671875 +32907 0.034881591796875 +32908 0.082733154296875 +32909 0.09124755859375 +32910 0.100250244140625 +32911 0.10888671875 +32912 0.11669921875 +32913 0.125518798828125 +32914 0.147003173828125 +32915 0.15771484375 +32916 0.16650390625 +32917 0.17828369140625 +32918 0.160552978515625 +32919 0.17108154296875 +32920 0.123626708984375 +32921 0.129974365234375 +32922 0.080535888671875 +32923 0.082427978515625 +32924 0.0306396484375 +32925 0.027679443359375 +32926 -0.054412841796875 +32927 -0.065643310546875 +32928 -0.140045166015625 +32929 -0.15936279296875 +32930 -0.189727783203125 +32931 -0.21307373046875 +32932 -0.210479736328125 +32933 -0.234649658203125 +32934 -0.180633544921875 +32935 -0.2001953125 +32936 -0.108673095703125 +32937 -0.119171142578125 +32938 -0.024505615234375 +32939 -0.024749755859375 +32940 0.074371337890625 +32941 0.085784912109375 +32942 0.157012939453125 +32943 0.178131103515625 +32944 0.190277099609375 +32945 0.215576171875 +32946 0.18621826171875 +32947 0.211456298828125 +32948 0.153411865234375 +32949 0.17523193359375 +32950 0.111602783203125 +32951 0.128753662109375 +32952 0.087799072265625 +32953 0.1019287109375 +32954 0.06353759765625 +32955 0.0743408203125 +32956 0.03631591796875 +32957 0.04327392578125 +32958 0.032684326171875 +32959 0.038177490234375 +32960 0.06817626953125 +32961 0.076263427734375 +32962 0.127838134765625 +32963 0.14105224609375 +32964 0.169921875 +32965 0.186431884765625 +32966 0.17303466796875 +32967 0.188812255859375 +32968 0.12884521484375 +32969 0.1390380859375 +32970 0.04156494140625 +32971 0.041778564453125 +32972 -0.06756591796875 +32973 -0.079437255859375 +32974 -0.19390869140625 +32975 -0.219390869140625 +32976 -0.328155517578125 +32977 -0.367828369140625 +32978 -0.44329833984375 +32979 -0.494873046875 +32980 -0.499298095703125 +32981 -0.556243896484375 +32982 -0.45703125 +32983 -0.508697509765625 +32984 -0.337554931640625 +32985 -0.3756103515625 +32986 -0.196807861328125 +32987 -0.218902587890625 +32988 -0.0574951171875 +32989 -0.063751220703125 +32990 0.08197021484375 +32991 0.091552734375 +32992 0.211700439453125 +32993 0.23602294921875 +32994 0.3076171875 +32995 0.342987060546875 +32996 0.354217529296875 +32997 0.39520263671875 +32998 0.348541259765625 +32999 0.389373779296875 +33000 0.289459228515625 +33001 0.324249267578125 +33002 0.198883056640625 +33003 0.224090576171875 +33004 0.10882568359375 +33005 0.124267578125 +33006 0.03033447265625 +33007 0.037078857421875 +33008 -0.0118408203125 +33009 -0.010101318359375 +33010 -0.019683837890625 +33011 -0.019439697265625 +33012 -0.022003173828125 +33013 -0.022796630859375 +33014 -0.00201416015625 +33015 -0.001556396484375 +33016 0.05108642578125 +33017 0.056304931640625 +33018 0.097412109375 +33019 0.106719970703125 +33020 0.089202880859375 +33021 0.096893310546875 +33022 0.040802001953125 +33023 0.042694091796875 +33024 -0.01336669921875 +33025 -0.018035888671875 +33026 -0.06494140625 +33027 -0.07586669921875 +33028 -0.104248046875 +33029 -0.11944580078125 +33030 -0.140716552734375 +33031 -0.15972900390625 +33032 -0.179351806640625 +33033 -0.202606201171875 +33034 -0.220489501953125 +33035 -0.24859619140625 +33036 -0.270538330078125 +33037 -0.30517578125 +33038 -0.320587158203125 +33039 -0.36212158203125 +33040 -0.34619140625 +33041 -0.39141845703125 +33042 -0.31439208984375 +33043 -0.35528564453125 +33044 -0.22198486328125 +33045 -0.249969482421875 +33046 -0.084197998046875 +33047 -0.092864990234375 +33048 0.075408935546875 +33049 0.08905029296875 +33050 0.2039794921875 +33051 0.2352294921875 +33052 0.27801513671875 +33053 0.318817138671875 +33054 0.313873291015625 +33055 0.358642578125 +33056 0.305419921875 +33057 0.347747802734375 +33058 0.252166748046875 +33059 0.28564453125 +33060 0.198394775390625 +33061 0.223175048828125 +33062 0.175811767578125 +33063 0.196746826171875 +33064 0.16131591796875 +33065 0.179840087890625 +33066 0.14013671875 +33067 0.155548095703125 +33068 0.1361083984375 +33069 0.151214599609375 +33070 0.140625 +33071 0.156951904296875 +33072 0.11798095703125 +33073 0.13177490234375 +33074 0.090118408203125 +33075 0.100799560546875 +33076 0.07720947265625 +33077 0.087127685546875 +33078 0.048065185546875 +33079 0.05487060546875 +33080 -0.008636474609375 +33081 -0.009002685546875 +33082 -0.092376708984375 +33083 -0.10400390625 +33084 -0.2025146484375 +33085 -0.229400634765625 +33086 -0.3131103515625 +33087 -0.35552978515625 +33088 -0.38885498046875 +33089 -0.441925048828125 +33090 -0.41693115234375 +33091 -0.473846435546875 +33092 -0.4090576171875 +33093 -0.464813232421875 +33094 -0.36895751953125 +33095 -0.419097900390625 +33096 -0.29461669921875 +33097 -0.334320068359375 +33098 -0.20123291015625 +33099 -0.227935791015625 +33100 -0.109405517578125 +33101 -0.12347412109375 +33102 -0.0250244140625 +33103 -0.02764892578125 +33104 0.06768798828125 +33105 0.077667236328125 +33106 0.186767578125 +33107 0.2132568359375 +33108 0.340667724609375 +33109 0.38885498046875 +33110 0.51043701171875 +33111 0.582794189453125 +33112 0.642822265625 +33113 0.734039306640625 +33114 0.7008056640625 +33115 0.800140380859375 +33116 0.68194580078125 +33117 0.7783203125 +33118 0.583282470703125 +33119 0.6651611328125 +33120 0.4039306640625 +33121 0.45965576171875 +33122 0.176483154296875 +33123 0.199188232421875 +33124 -0.0418701171875 +33125 -0.050689697265625 +33126 -0.201385498046875 +33127 -0.23297119140625 +33128 -0.286773681640625 +33129 -0.33013916015625 +33130 -0.32086181640625 +33131 -0.368408203125 +33132 -0.33074951171875 +33133 -0.378936767578125 +33134 -0.3297119140625 +33135 -0.376983642578125 +33136 -0.332672119140625 +33137 -0.37969970703125 +33138 -0.34344482421875 +33139 -0.391510009765625 +33140 -0.338409423828125 +33141 -0.385345458984375 +33142 -0.300750732421875 +33143 -0.3419189453125 +33144 -0.249359130859375 +33145 -0.28289794921875 +33146 -0.22198486328125 +33147 -0.251617431640625 +33148 -0.234405517578125 +33149 -0.266143798828125 +33150 -0.24029541015625 +33151 -0.273345947265625 +33152 -0.19049072265625 +33153 -0.216796875 +33154 -0.112701416015625 +33155 -0.128265380859375 +33156 -0.0596923828125 +33157 -0.068145751953125 +33158 -0.037261962890625 +33159 -0.0430908203125 +33160 -0.02044677734375 +33161 -0.024444580078125 +33162 0.01947021484375 +33163 0.020721435546875 +33164 0.11041259765625 +33165 0.124481201171875 +33166 0.22705078125 +33167 0.25787353515625 +33168 0.33294677734375 +33169 0.379119873046875 +33170 0.4208984375 +33171 0.47991943359375 +33172 0.462921142578125 +33173 0.5281982421875 +33174 0.447845458984375 +33175 0.511138916015625 +33176 0.399627685546875 +33177 0.456207275390625 +33178 0.356719970703125 +33179 0.407470703125 +33180 0.335601806640625 +33181 0.383758544921875 +33182 0.311676025390625 +33183 0.35687255859375 +33184 0.271881103515625 +33185 0.31182861328125 +33186 0.218231201171875 +33187 0.250885009765625 +33188 0.143218994140625 +33189 0.1654052734375 +33190 0.029327392578125 +33191 0.035247802734375 +33192 -0.125579833984375 +33193 -0.142059326171875 +33194 -0.294586181640625 +33195 -0.33563232421875 +33196 -0.4681396484375 +33197 -0.5345458984375 +33198 -0.631439208984375 +33199 -0.72186279296875 +33200 -0.73138427734375 +33201 -0.836669921875 +33202 -0.72760009765625 +33203 -0.8326416015625 +33204 -0.637420654296875 +33205 -0.7296142578125 +33206 -0.508758544921875 +33207 -0.582550048828125 +33208 -0.384063720703125 +33209 -0.440093994140625 +33210 -0.282623291015625 +33211 -0.324310302734375 +33212 -0.175079345703125 +33213 -0.20147705078125 +33214 -0.03790283203125 +33215 -0.044647216796875 +33216 0.092071533203125 +33217 0.103973388671875 +33218 0.17816162109375 +33219 0.202392578125 +33220 0.23248291015625 +33221 0.264495849609375 +33222 0.29742431640625 +33223 0.338897705078125 +33224 0.38885498046875 +33225 0.443817138671875 +33226 0.47698974609375 +33227 0.545074462890625 +33228 0.539703369140625 +33229 0.6173095703125 +33230 0.57000732421875 +33231 0.6524658203125 +33232 0.579132080078125 +33233 0.66339111328125 +33234 0.572357177734375 +33235 0.6561279296875 +33236 0.528900146484375 +33237 0.606781005859375 +33238 0.436431884765625 +33239 0.501190185546875 +33240 0.306671142578125 +33241 0.352783203125 +33242 0.152679443359375 +33243 0.176544189453125 +33244 -0.031829833984375 +33245 -0.034820556640625 +33246 -0.22674560546875 +33247 -0.258209228515625 +33248 -0.387451171875 +33249 -0.44244384765625 +33250 -0.503265380859375 +33251 -0.5753173828125 +33252 -0.57000732421875 +33253 -0.65203857421875 +33254 -0.560699462890625 +33255 -0.641632080078125 +33256 -0.491119384765625 +33257 -0.562164306640625 +33258 -0.399993896484375 +33259 -0.458038330078125 +33260 -0.305877685546875 +33261 -0.350555419921875 +33262 -0.22698974609375 +33263 -0.260528564453125 +33264 -0.166961669921875 +33265 -0.192108154296875 +33266 -0.1229248046875 +33267 -0.141937255859375 +33268 -0.0880126953125 +33269 -0.1021728515625 +33270 -0.0535888671875 +33271 -0.062896728515625 +33272 -0.009033203125 +33273 -0.011932373046875 +33274 0.05621337890625 +33275 0.062835693359375 +33276 0.131072998046875 +33277 0.148712158203125 +33278 0.212066650390625 +33279 0.241729736328125 +33280 0.305206298828125 +33281 0.34912109375 +33282 0.397918701171875 +33283 0.457305908203125 +33284 0.47076416015625 +33285 0.54388427734375 +33286 0.493896484375 +33287 0.5728759765625 +33288 0.436004638671875 +33289 0.506591796875 +33290 0.302642822265625 +33291 0.351226806640625 +33292 0.127471923828125 +33293 0.146514892578125 +33294 -0.0452880859375 +33295 -0.05523681640625 +33296 -0.183685302734375 +33297 -0.21624755859375 +33298 -0.286163330078125 +33299 -0.334930419921875 +33300 -0.345611572265625 +33301 -0.402984619140625 +33302 -0.37945556640625 +33303 -0.4412841796875 +33304 -0.42626953125 +33305 -0.49578857421875 +33306 -0.480712890625 +33307 -0.5601806640625 +33308 -0.51446533203125 +33309 -0.600738525390625 +33310 -0.49969482421875 +33311 -0.584228515625 +33312 -0.410125732421875 +33313 -0.47930908203125 +33314 -0.2403564453125 +33315 -0.27935791015625 +33316 -0.0111083984375 +33317 -0.0089111328125 +33318 0.224365234375 +33319 0.268798828125 +33320 0.4063720703125 +33321 0.482818603515625 +33322 0.510040283203125 +33323 0.60369873046875 +33324 0.551177978515625 +33325 0.650421142578125 +33326 0.56414794921875 +33327 0.66400146484375 +33328 0.54638671875 +33329 0.6414794921875 +33330 0.489166259765625 +33331 0.572540283203125 +33332 0.4268798828125 +33333 0.498138427734375 +33334 0.3773193359375 +33335 0.439453125 +33336 0.322906494140625 +33337 0.375518798828125 +33338 0.2369384765625 +33339 0.274505615234375 +33340 0.096282958984375 +33341 0.1087646484375 +33342 -0.080230712890625 +33343 -0.099395751953125 +33344 -0.265838623046875 +33345 -0.3182373046875 +33346 -0.461456298828125 +33347 -0.5489501953125 +33348 -0.65203857421875 +33349 -0.7738037109375 +33350 -0.793060302734375 +33351 -0.86383056640625 +33352 -0.854736328125 +33353 -0.870391845703125 +33354 -0.85479736328125 +33355 -0.86895751953125 +33356 -0.806060791015625 +33357 -0.861053466796875 +33358 -0.6885986328125 +33359 -0.765869140625 +33360 -0.495330810546875 +33361 -0.5301513671875 +33362 -0.23223876953125 +33363 -0.214691162109375 +33364 0.064453125 +33365 0.137359619140625 +33366 0.351593017578125 +33367 0.474822998046875 +33368 0.599273681640625 +33369 0.76239013671875 +33370 0.784759521484375 +33371 0.867462158203125 +33372 0.8603515625 +33373 0.870361328125 +33374 0.865997314453125 +33375 0.86480712890625 +33376 0.86431884765625 +33377 0.831817626953125 +33378 0.8575439453125 +33379 0.677581787109375 +33380 0.778106689453125 +33381 0.495880126953125 +33382 0.647186279296875 +33383 0.30767822265625 +33384 0.491546630859375 +33385 0.116180419921875 +33386 0.284515380859375 +33387 -0.110748291015625 +33388 0.020294189453125 +33389 -0.381805419921875 +33390 -0.26513671875 +33391 -0.6572265625 +33392 -0.52142333984375 +33393 -0.857421875 +33394 -0.712432861328125 +33395 -0.870391845703125 +33396 -0.83209228515625 +33397 -0.870391845703125 +33398 -0.85980224609375 +33399 -0.86444091796875 +33400 -0.865447998046875 +33401 -0.85723876953125 +33402 -0.867340087890625 +33403 -0.790008544921875 +33404 -0.860504150390625 +33405 -0.62847900390625 +33406 -0.76409912109375 +33407 -0.3956298828125 +33408 -0.563323974609375 +33409 -0.126708984375 +33410 -0.33026123046875 +33411 0.150115966796875 +33412 -0.074737548828125 +33413 0.424041748046875 +33414 0.180572509765625 +33415 0.670623779296875 +33416 0.403106689453125 +33417 0.854522705078125 +33418 0.577972412109375 +33419 0.866485595703125 +33420 0.692138671875 +33421 0.86920166015625 +33422 0.760772705078125 +33423 0.8653564453125 +33424 0.7950439453125 +33425 0.857147216796875 +33426 0.79241943359375 +33427 0.766845703125 +33428 0.757110595703125 +33429 0.628509521484375 +33430 0.683380126953125 +33431 0.462127685546875 +33432 0.5928955078125 +33433 0.297210693359375 +33434 0.49603271484375 +33435 0.14862060546875 +33436 0.37359619140625 +33437 -0.00537109375 +33438 0.231842041015625 +33439 -0.15753173828125 +33440 0.067779541015625 +33441 -0.31304931640625 +33442 -0.13031005859375 +33443 -0.48876953125 +33444 -0.322998046875 +33445 -0.6416015625 +33446 -0.48944091796875 +33447 -0.751373291015625 +33448 -0.64892578125 +33449 -0.84619140625 +33450 -0.788970947265625 +33451 -0.861297607421875 +33452 -0.85748291015625 +33453 -0.863250732421875 +33454 -0.859527587890625 +33455 -0.856597900390625 +33456 -0.854583740234375 +33457 -0.7498779296875 +33458 -0.794952392578125 +33459 -0.624542236328125 +33460 -0.700836181640625 +33461 -0.47808837890625 +33462 -0.52386474609375 +33463 -0.253387451171875 +33464 -0.3023681640625 +33465 0.003692626953125 +33466 -0.09381103515625 +33467 0.2257080078125 +33468 0.112274169921875 +33469 0.427154541015625 +33470 0.343017578125 +33471 0.643218994140625 +33472 0.590240478515625 +33473 0.855926513671875 +33474 0.805145263671875 +33475 0.870361328125 +33476 0.86444091796875 +33477 0.870361328125 +33478 0.870361328125 +33479 0.862762451171875 +33480 0.868682861328125 +33481 0.79669189453125 +33482 0.85870361328125 +33483 0.595794677734375 +33484 0.75067138671875 +33485 0.362152099609375 +33486 0.580963134765625 +33487 0.1270751953125 +33488 0.40228271484375 +33489 -0.086944580078125 +33490 0.216522216796875 +33491 -0.2784423828125 +33492 -0.005584716796875 +33493 -0.484832763671875 +33494 -0.280426025390625 +33495 -0.729583740234375 +33496 -0.56591796875 +33497 -0.86688232421875 +33498 -0.80938720703125 +33499 -0.870391845703125 +33500 -0.870391845703125 +33501 -0.86859130859375 +33502 -0.870391845703125 +33503 -0.86279296875 +33504 -0.863494873046875 +33505 -0.817962646484375 +33506 -0.780487060546875 +33507 -0.6116943359375 +33508 -0.531280517578125 +33509 -0.3128662109375 +33510 -0.22247314453125 +33511 0.039398193359375 +33512 0.126068115234375 +33513 0.422821044921875 +33514 0.48541259765625 +33515 0.805145263671875 +33516 0.79931640625 +33517 0.870361328125 +33518 0.870361328125 +33519 0.870361328125 +33520 0.870361328125 +33521 0.860015869140625 +33522 0.861114501953125 +33523 0.727935791015625 +33524 0.75372314453125 +33525 0.48114013671875 +33526 0.5479736328125 +33527 0.2059326171875 +33528 0.327972412109375 +33529 -0.06103515625 +33530 0.111358642578125 +33531 -0.29913330078125 +33532 -0.10687255859375 +33533 -0.516204833984375 +33534 -0.335113525390625 +33535 -0.7252197265625 +33536 -0.550689697265625 +33537 -0.85980224609375 +33538 -0.72503662109375 +33539 -0.870391845703125 +33540 -0.836578369140625 +33541 -0.870391845703125 +33542 -0.8514404296875 +33543 -0.858062744140625 +33544 -0.773651123046875 +33545 -0.673004150390625 +33546 -0.654541015625 +33547 -0.42694091796875 +33548 -0.539764404296875 +33549 -0.2100830078125 +33550 -0.43780517578125 +33551 -0.0362548828125 +33552 -0.33526611328125 +33553 0.10943603515625 +33554 -0.225372314453125 +33555 0.23516845703125 +33556 -0.08282470703125 +33557 0.373687744140625 +33558 0.084197998046875 +33559 0.517791748046875 +33560 0.220123291015625 +33561 0.602783203125 +33562 0.3265380859375 +33563 0.635711669921875 +33564 0.429931640625 +33565 0.655181884765625 +33566 0.52392578125 +33567 0.65948486328125 +33568 0.60565185546875 +33569 0.651275634765625 +33570 0.66058349609375 +33571 0.61846923828125 +33572 0.66546630859375 +33573 0.53753662109375 +33574 0.613311767578125 +33575 0.404144287109375 +33576 0.504425048828125 +33577 0.22186279296875 +33578 0.347991943359375 +33579 0.003997802734375 +33580 0.166412353515625 +33581 -0.22100830078125 +33582 -0.0166015625 +33583 -0.42449951171875 +33584 -0.17791748046875 +33585 -0.579833984375 +33586 -0.278656005859375 +33587 -0.641876220703125 +33588 -0.321441650390625 +33589 -0.6177978515625 +33590 -0.357421875 +33591 -0.575531005859375 +33592 -0.391632080078125 +33593 -0.526336669921875 +33594 -0.384613037109375 +33595 -0.42645263671875 +33596 -0.3179931640625 +33597 -0.2581787109375 +33598 -0.22625732421875 +33599 -0.068695068359375 +33600 -0.146484375 +33601 0.09222412109375 +33602 -0.070159912109375 +33603 0.232147216796875 +33604 0.00421142578125 +33605 0.3509521484375 +33606 0.046173095703125 +33607 0.410064697265625 +33608 0.026123046875 +33609 0.372955322265625 +33610 -0.0440673828125 +33611 0.2554931640625 +33612 -0.12628173828125 +33613 0.10711669921875 +33614 -0.207366943359375 +33615 -0.052886962890625 +33616 -0.25933837890625 +33617 -0.186279296875 +33618 -0.23687744140625 +33619 -0.23291015625 +33620 -0.1568603515625 +33621 -0.209442138671875 +33622 -0.069732666015625 +33623 -0.174163818359375 +33624 0.021636962890625 +33625 -0.126739501953125 +33626 0.129913330078125 +33627 -0.048126220703125 +33628 0.23748779296875 +33629 0.0426025390625 +33630 0.3121337890625 +33631 0.10748291015625 +33632 0.3485107421875 +33633 0.1409912109375 +33634 0.390045166015625 +33635 0.19708251953125 +33636 0.4356689453125 +33637 0.273651123046875 +33638 0.44378662109375 +33639 0.31768798828125 +33640 0.425811767578125 +33641 0.341094970703125 +33642 0.403564453125 +33643 0.368011474609375 +33644 0.358673095703125 +33645 0.37249755859375 +33646 0.250396728515625 +33647 0.30072021484375 +33648 0.08074951171875 +33649 0.1517333984375 +33650 -0.09930419921875 +33651 -0.01470947265625 +33652 -0.279083251953125 +33653 -0.1883544921875 +33654 -0.45947265625 +33655 -0.372711181640625 +33656 -0.59552001953125 +33657 -0.51397705078125 +33658 -0.653656005859375 +33659 -0.57177734375 +33660 -0.62823486328125 +33661 -0.53948974609375 +33662 -0.5340576171875 +33663 -0.43511962890625 +33664 -0.40234375 +33665 -0.2962646484375 +33666 -0.265289306640625 +33667 -0.161102294921875 +33668 -0.135894775390625 +33669 -0.0435791015625 +33670 -0.012939453125 +33671 0.060394287109375 +33672 0.08984375 +33673 0.13665771484375 +33674 0.15802001953125 +33675 0.170135498046875 +33676 0.193115234375 +33677 0.16552734375 +33678 0.220916748046875 +33679 0.15728759765625 +33680 0.244049072265625 +33681 0.150787353515625 +33682 0.24169921875 +33683 0.12200927734375 +33684 0.2203369140625 +33685 0.080108642578125 +33686 0.20068359375 +33687 0.05126953125 +33688 0.204986572265625 +33689 0.062896728515625 +33690 0.215728759765625 +33691 0.09271240234375 +33692 0.1953125 +33693 0.092987060546875 +33694 0.15704345703125 +33695 0.07855224609375 +33696 0.11456298828125 +33697 0.06427001953125 +33698 0.057281494140625 +33699 0.0347900390625 +33700 -0.014404296875 +33701 -0.01171875 +33702 -0.083099365234375 +33703 -0.056060791015625 +33704 -0.112518310546875 +33705 -0.055511474609375 +33706 -0.101409912109375 +33707 -0.010467529296875 +33708 -0.092132568359375 +33709 0.02508544921875 +33710 -0.104400634765625 +33711 0.025665283203125 +33712 -0.116607666015625 +33713 0.017333984375 +33714 -0.127288818359375 +33715 0.00189208984375 +33716 -0.14569091796875 +33717 -0.03173828125 +33718 -0.16278076171875 +33719 -0.071502685546875 +33720 -0.194091796875 +33721 -0.13543701171875 +33722 -0.238006591796875 +33723 -0.219970703125 +33724 -0.276123046875 +33725 -0.300506591796875 +33726 -0.309356689453125 +33727 -0.376312255859375 +33728 -0.31396484375 +33729 -0.416107177734375 +33730 -0.252044677734375 +33731 -0.371124267578125 +33732 -0.12567138671875 +33733 -0.242279052734375 +33734 0.03155517578125 +33735 -0.069732666015625 +33736 0.201873779296875 +33737 0.125640869140625 +33738 0.359619140625 +33739 0.31268310546875 +33740 0.4752197265625 +33741 0.45501708984375 +33742 0.550537109375 +33743 0.554779052734375 +33744 0.5849609375 +33745 0.61065673828125 +33746 0.569793701171875 +33747 0.610931396484375 +33748 0.48651123046875 +33749 0.531463623046875 +33750 0.349212646484375 +33751 0.3883056640625 +33752 0.2021484375 +33753 0.23468017578125 +33754 0.0665283203125 +33755 0.095245361328125 +33756 -0.035369873046875 +33757 -0.00396728515625 +33758 -0.090728759765625 +33759 -0.04852294921875 +33760 -0.112060546875 +33761 -0.055145263671875 +33762 -0.140594482421875 +33763 -0.0758056640625 +33764 -0.198577880859375 +33765 -0.138702392578125 +33766 -0.25775146484375 +33767 -0.209197998046875 +33768 -0.319580078125 +33769 -0.289031982421875 +33770 -0.3848876953125 +33771 -0.37884521484375 +33772 -0.436126708984375 +33773 -0.456329345703125 +33774 -0.469970703125 +33775 -0.51641845703125 +33776 -0.45513916015625 +33777 -0.519287109375 +33778 -0.38720703125 +33779 -0.458251953125 +33780 -0.308837890625 +33781 -0.384796142578125 +33782 -0.2410888671875 +33783 -0.323699951171875 +33784 -0.18035888671875 +33785 -0.269287109375 +33786 -0.106231689453125 +33787 -0.1951904296875 +33788 -0.018280029296875 +33789 -0.100006103515625 +33790 0.061279296875 +33791 -0.01055908203125 +33792 0.156463623046875 +33793 0.1033935546875 +33794 0.27313232421875 +33795 0.24908447265625 +33796 0.368682861328125 +33797 0.373199462890625 +33798 0.429229736328125 +33799 0.45806884765625 +33800 0.461456298828125 +33801 0.511474609375 +33802 0.4915771484375 +33803 0.565399169921875 +33804 0.5135498046875 +33805 0.61138916015625 +33806 0.48046875 +33807 0.5897216796875 +33808 0.385345458984375 +33809 0.4906005859375 +33810 0.2430419921875 +33811 0.33148193359375 +33812 0.08270263671875 +33813 0.147796630859375 +33814 -0.061614990234375 +33815 -0.01873779296875 +33816 -0.1671142578125 +33817 -0.140289306640625 +33818 -0.2135009765625 +33819 -0.191986083984375 +33820 -0.208984375 +33821 -0.184295654296875 +33822 -0.18927001953125 +33823 -0.161834716796875 +33824 -0.188140869140625 +33825 -0.166595458984375 +33826 -0.20220947265625 +33827 -0.19390869140625 +33828 -0.21649169921875 +33829 -0.22442626953125 +33830 -0.248870849609375 +33831 -0.279754638671875 +33832 -0.2833251953125 +33833 -0.3389892578125 +33834 -0.28240966796875 +33835 -0.3543701171875 +33836 -0.264678955078125 +33837 -0.348175048828125 +33838 -0.235260009765625 +33839 -0.32598876953125 +33840 -0.17108154296875 +33841 -0.2581787109375 +33842 -0.06866455078125 +33843 -0.139801025390625 +33844 0.060028076171875 +33845 0.014617919921875 +33846 0.166168212890625 +33847 0.144378662109375 +33848 0.227020263671875 +33849 0.221038818359375 +33850 0.2635498046875 +33851 0.27069091796875 +33852 0.276580810546875 +33853 0.294036865234375 +33854 0.28302001953125 +33855 0.311767578125 +33856 0.295501708984375 +33857 0.339141845703125 +33858 0.30157470703125 +33859 0.360260009765625 +33860 0.29022216796875 +33861 0.360504150390625 +33862 0.237762451171875 +33863 0.308380126953125 +33864 0.127716064453125 +33865 0.18170166015625 +33866 -0.020294189453125 +33867 0.0047607421875 +33868 -0.169342041015625 +33869 -0.17559814453125 +33870 -0.284027099609375 +33871 -0.3143310546875 +33872 -0.330169677734375 +33873 -0.36785888671875 +33874 -0.3280029296875 +33875 -0.36248779296875 +33876 -0.312652587890625 +33877 -0.343536376953125 +33878 -0.27716064453125 +33879 -0.3018798828125 +33880 -0.217010498046875 +33881 -0.231414794921875 +33882 -0.121337890625 +33883 -0.117645263671875 +33884 -0.015716552734375 +33885 0.007049560546875 +33886 0.056884765625 +33887 0.087982177734375 +33888 0.10699462890625 +33889 0.13946533203125 +33890 0.143951416015625 +33891 0.17425537109375 +33892 0.163970947265625 +33893 0.188201904296875 +33894 0.15875244140625 +33895 0.171234130859375 +33896 0.12408447265625 +33897 0.118438720703125 +33898 0.080841064453125 +33899 0.05706787109375 +33900 0.03045654296875 +33901 -0.010711669921875 +33902 -0.032135009765625 +33903 -0.0914306640625 +33904 -0.08917236328125 +33905 -0.162322998046875 +33906 -0.1181640625 +33907 -0.194549560546875 +33908 -0.088714599609375 +33909 -0.1492919921875 +33910 0.003326416015625 +33911 -0.02166748046875 +33912 0.108489990234375 +33913 0.124053955078125 +33914 0.167724609375 +33915 0.211151123046875 +33916 0.182159423828125 +33917 0.240447998046875 +33918 0.175689697265625 +33919 0.242218017578125 +33920 0.15594482421875 +33921 0.2257080078125 +33922 0.125946044921875 +33923 0.194366455078125 +33924 0.060577392578125 +33925 0.115509033203125 +33926 -0.02154541015625 +33927 0.0128173828125 +33928 -0.073883056640625 +33929 -0.053802490234375 +33930 -0.1168212890625 +33931 -0.110626220703125 +33932 -0.1829833984375 +33933 -0.199493408203125 +33934 -0.25238037109375 +33935 -0.29437255859375 +33936 -0.27630615234375 +33937 -0.33221435546875 +33938 -0.22930908203125 +33939 -0.27972412109375 +33940 -0.149322509765625 +33941 -0.185333251953125 +33942 -0.098114013671875 +33943 -0.128204345703125 +33944 -0.081756591796875 +33945 -0.115692138671875 +33946 -0.0762939453125 +33947 -0.116455078125 +33948 -0.06298828125 +33949 -0.105926513671875 +33950 -0.018707275390625 +33951 -0.053955078125 +33952 0.0635986328125 +33953 0.048797607421875 +33954 0.14892578125 +33955 0.157318115234375 +33956 0.19097900390625 +33957 0.212005615234375 +33958 0.194183349609375 +33959 0.218475341796875 +33960 0.20562744140625 +33961 0.23724365234375 +33962 0.2542724609375 +33963 0.30535888671875 +33964 0.308135986328125 +33965 0.38128662109375 +33966 0.320526123046875 +33967 0.404449462890625 +33968 0.30694580078125 +33969 0.3944091796875 +33970 0.296722412109375 +33971 0.3885498046875 +33972 0.271392822265625 +33973 0.362640380859375 +33974 0.197784423828125 +33975 0.27362060546875 +33976 0.072723388671875 +33977 0.11712646484375 +33978 -0.063262939453125 +33979 -0.054901123046875 +33980 -0.1700439453125 +33981 -0.19085693359375 +33982 -0.243682861328125 +33983 -0.28570556640625 +33984 -0.284088134765625 +33985 -0.339263916015625 +33986 -0.3115234375 +33987 -0.3775634765625 +33988 -0.36114501953125 +33989 -0.445709228515625 +33990 -0.426513671875 +33991 -0.535064697265625 +33992 -0.494964599609375 +33993 -0.629058837890625 +33994 -0.543426513671875 +33995 -0.697601318359375 +33996 -0.543609619140625 +33997 -0.70391845703125 +33998 -0.491455078125 +33999 -0.6424560546875 +34000 -0.37017822265625 +34001 -0.491241455078125 +34002 -0.191925048828125 +34003 -0.265716552734375 +34004 -0.001739501953125 +34005 -0.023712158203125 +34006 0.17462158203125 +34007 0.201751708984375 +34008 0.310089111328125 +34009 0.375823974609375 +34010 0.39422607421875 +34011 0.485076904296875 +34012 0.4576416015625 +34013 0.56884765625 +34014 0.506378173828125 +34015 0.634765625 +34016 0.5054931640625 +34017 0.63763427734375 +34018 0.446319580078125 +34019 0.5660400390625 +34020 0.369476318359375 +34021 0.4720458984375 +34022 0.314971923828125 +34023 0.40692138671875 +34024 0.28857421875 +34025 0.3778076171875 +34026 0.284454345703125 +34027 0.376953125 +34028 0.277679443359375 +34029 0.371978759765625 +34030 0.22979736328125 +34031 0.313140869140625 +34032 0.12847900390625 +34033 0.184417724609375 +34034 -0.006500244140625 +34035 0.011199951171875 +34036 -0.14764404296875 +34037 -0.171051025390625 +34038 -0.275634765625 +34039 -0.33740234375 +34040 -0.378204345703125 +34041 -0.47198486328125 +34042 -0.4443359375 +34043 -0.560394287109375 +34044 -0.45709228515625 +34045 -0.58056640625 +34046 -0.42828369140625 +34047 -0.54754638671875 +34048 -0.3946533203125 +34049 -0.508575439453125 +34050 -0.353363037109375 +34051 -0.459503173828125 +34052 -0.299774169921875 +34053 -0.394378662109375 +34054 -0.263458251953125 +34055 -0.35260009765625 +34056 -0.227935791015625 +34057 -0.31170654296875 +34058 -0.13818359375 +34059 -0.197418212890625 +34060 0.006866455078125 +34061 -0.007965087890625 +34062 0.17041015625 +34063 0.207489013671875 +34064 0.32275390625 +34065 0.409210205078125 +34066 0.44512939453125 +34067 0.57208251953125 +34068 0.515106201171875 +34069 0.66595458984375 +34070 0.5087890625 +34071 0.65875244140625 +34072 0.43890380859375 +34073 0.56744384765625 +34074 0.334869384765625 +34075 0.431396484375 +34076 0.229522705078125 +34077 0.29443359375 +34078 0.142303466796875 +34079 0.182464599609375 +34080 0.049774169921875 +34081 0.06365966796875 +34082 -0.0582275390625 +34083 -0.075958251953125 +34084 -0.14654541015625 +34085 -0.189422607421875 +34086 -0.211395263671875 +34087 -0.271942138671875 +34088 -0.26678466796875 +34089 -0.342529296875 +34090 -0.2850341796875 +34091 -0.364166259765625 +34092 -0.258880615234375 +34093 -0.327239990234375 +34094 -0.221923828125 +34095 -0.2769775390625 +34096 -0.20416259765625 +34097 -0.253692626953125 +34098 -0.1954345703125 +34099 -0.24365234375 +34100 -0.159759521484375 +34101 -0.1983642578125 +34102 -0.096099853515625 +34103 -0.116241455078125 +34104 -0.03399658203125 +34105 -0.036834716796875 +34106 0.02264404296875 +34107 0.034881591796875 +34108 0.067962646484375 +34109 0.09124755859375 +34110 0.084381103515625 +34111 0.10888671875 +34112 0.099761962890625 +34113 0.125518798828125 +34114 0.12628173828125 +34115 0.15771484375 +34116 0.143585205078125 +34117 0.17828369140625 +34118 0.139556884765625 +34119 0.17108154296875 +34120 0.109619140625 +34121 0.129974365234375 +34122 0.07415771484375 +34123 0.082427978515625 +34124 0.03265380859375 +34125 0.027679443359375 +34126 -0.03814697265625 +34127 -0.065643310546875 +34128 -0.1097412109375 +34129 -0.15936279296875 +34130 -0.152008056640625 +34131 -0.21307373046875 +34132 -0.170654296875 +34133 -0.234649658203125 +34134 -0.147735595703125 +34135 -0.2001953125 +34136 -0.09014892578125 +34137 -0.119171142578125 +34138 -0.0224609375 +34139 -0.024749755859375 +34140 0.057525634765625 +34141 0.085784912109375 +34142 0.1243896484375 +34143 0.178131103515625 +34144 0.150909423828125 +34145 0.215576171875 +34146 0.14703369140625 +34147 0.211456298828125 +34148 0.119873046875 +34149 0.17523193359375 +34150 0.085662841796875 +34151 0.128753662109375 +34152 0.066619873046875 +34153 0.1019287109375 +34154 0.047515869140625 +34155 0.0743408203125 +34156 0.026214599609375 +34157 0.04327392578125 +34158 0.024505615234375 +34159 0.038177490234375 +34160 0.0550537109375 +34161 0.076263427734375 +34162 0.10546875 +34163 0.14105224609375 +34164 0.141357421875 +34165 0.186431884765625 +34166 0.145050048828125 +34167 0.188812255859375 +34168 0.109619140625 +34169 0.1390380859375 +34170 0.038482666015625 +34171 0.041778564453125 +34172 -0.0509033203125 +34173 -0.079437255859375 +34174 -0.154693603515625 +34175 -0.219390869140625 +34176 -0.2652587890625 +34177 -0.367828369140625 +34178 -0.3603515625 +34179 -0.494873046875 +34180 -0.406982421875 +34181 -0.556243896484375 +34182 -0.3729248046875 +34183 -0.508697509765625 +34184 -0.27545166015625 +34185 -0.3756103515625 +34186 -0.16058349609375 +34187 -0.218902587890625 +34188 -0.04693603515625 +34189 -0.063751220703125 +34190 0.066802978515625 +34191 0.091552734375 +34192 0.172576904296875 +34193 0.23602294921875 +34194 0.250640869140625 +34195 0.342987060546875 +34196 0.28826904296875 +34197 0.39520263671875 +34198 0.2830810546875 +34199 0.389373779296875 +34200 0.234161376953125 +34201 0.324249267578125 +34202 0.159576416015625 +34203 0.224090576171875 +34204 0.085601806640625 +34205 0.124267578125 +34206 0.0213623046875 +34207 0.037078857421875 +34208 -0.01275634765625 +34209 -0.010101318359375 +34210 -0.018463134765625 +34211 -0.019439697265625 +34212 -0.01953125 +34213 -0.022796630859375 +34214 -0.002166748046875 +34215 -0.001556396484375 +34216 0.04241943359375 +34217 0.056304931640625 +34218 0.081390380859375 +34219 0.106719970703125 +34220 0.07537841796875 +34221 0.096893310546875 +34222 0.036163330078125 +34223 0.042694091796875 +34224 -0.008209228515625 +34225 -0.018035888671875 +34226 -0.05072021484375 +34227 -0.07586669921875 +34228 -0.08294677734375 +34229 -0.11944580078125 +34230 -0.113037109375 +34231 -0.15972900390625 +34232 -0.145355224609375 +34233 -0.202606201171875 +34234 -0.18023681640625 +34235 -0.24859619140625 +34236 -0.22320556640625 +34237 -0.30517578125 +34238 -0.266632080078125 +34239 -0.36212158203125 +34240 -0.28961181640625 +34241 -0.39141845703125 +34242 -0.263946533203125 +34243 -0.35528564453125 +34244 -0.186767578125 +34245 -0.249969482421875 +34246 -0.071014404296875 +34247 -0.092864990234375 +34248 0.063323974609375 +34249 0.08905029296875 +34250 0.1712646484375 +34251 0.2352294921875 +34252 0.232879638671875 +34253 0.318817138671875 +34254 0.262176513671875 +34255 0.358642578125 +34256 0.253997802734375 +34257 0.347747802734375 +34258 0.207977294921875 +34259 0.28564453125 +34260 0.161956787109375 +34261 0.223175048828125 +34262 0.1429443359375 +34263 0.196746826171875 +34264 0.131195068359375 +34265 0.179840087890625 +34266 0.114105224609375 +34267 0.155548095703125 +34268 0.1119384765625 +34269 0.151214599609375 +34270 0.117279052734375 +34271 0.156951904296875 +34272 0.099517822265625 +34273 0.13177490234375 +34274 0.07733154296875 +34275 0.100799560546875 +34276 0.06787109375 +34277 0.087127685546875 +34278 0.044403076171875 +34279 0.05487060546875 +34280 -0.002777099609375 +34281 -0.009002685546875 +34282 -0.07330322265625 +34283 -0.10400390625 +34284 -0.166656494140625 +34285 -0.229400634765625 +34286 -0.260772705078125 +34287 -0.35552978515625 +34288 -0.32550048828125 +34289 -0.441925048828125 +34290 -0.349884033203125 +34291 -0.473846435546875 +34292 -0.343902587890625 +34293 -0.464813232421875 +34294 -0.3106689453125 +34295 -0.419097900390625 +34296 -0.248382568359375 +34297 -0.334320068359375 +34298 -0.170013427734375 +34299 -0.227935791015625 +34300 -0.093017578125 +34301 -0.12347412109375 +34302 -0.0223388671875 +34303 -0.02764892578125 +34304 0.055572509765625 +34305 0.077667236328125 +34306 0.15594482421875 +34307 0.2132568359375 +34308 0.28521728515625 +34309 0.38885498046875 +34310 0.42730712890625 +34311 0.582794189453125 +34312 0.53826904296875 +34313 0.734039306640625 +34314 0.587554931640625 +34315 0.800140380859375 +34316 0.572967529296875 +34317 0.7783203125 +34318 0.49200439453125 +34319 0.6651611328125 +34320 0.344024658203125 +34321 0.45965576171875 +34322 0.15576171875 +34323 0.199188232421875 +34324 -0.02587890625 +34325 -0.050689697265625 +34326 -0.1600341796875 +34327 -0.23297119140625 +34328 -0.233978271484375 +34329 -0.33013916015625 +34330 -0.266021728515625 +34331 -0.368408203125 +34332 -0.278045654296875 +34333 -0.378936767578125 +34334 -0.2806396484375 +34335 -0.376983642578125 +34336 -0.285797119140625 +34337 -0.37969970703125 +34338 -0.2965087890625 +34339 -0.391510009765625 +34340 -0.29339599609375 +34341 -0.385345458984375 +34342 -0.262664794921875 +34343 -0.3419189453125 +34344 -0.21978759765625 +34345 -0.28289794921875 +34346 -0.1956787109375 +34347 -0.251617431640625 +34348 -0.20330810546875 +34349 -0.266143798828125 +34350 -0.205047607421875 +34351 -0.273345947265625 +34352 -0.160888671875 +34353 -0.216796875 +34354 -0.093658447265625 +34355 -0.128265380859375 +34356 -0.046630859375 +34357 -0.068145751953125 +34358 -0.0247802734375 +34359 -0.0430908203125 +34360 -0.007904052734375 +34361 -0.024444580078125 +34362 0.027252197265625 +34363 0.020721435546875 +34364 0.10333251953125 +34365 0.124481201171875 +34366 0.199615478515625 +34367 0.25787353515625 +34368 0.28631591796875 +34369 0.379119873046875 +34370 0.357574462890625 +34371 0.47991943359375 +34372 0.390594482421875 +34373 0.5281982421875 +34374 0.3763427734375 +34375 0.511138916015625 +34376 0.334503173828125 +34377 0.456207275390625 +34378 0.296630859375 +34379 0.407470703125 +34380 0.27630615234375 +34381 0.383758544921875 +34382 0.253631591796875 +34383 0.35687255859375 +34384 0.2181396484375 +34385 0.31182861328125 +34386 0.171630859375 +34387 0.250885009765625 +34388 0.108123779296875 +34389 0.1654052734375 +34390 0.013397216796875 +34391 0.035247802734375 +34392 -0.11419677734375 +34393 -0.142059326171875 +34394 -0.252593994140625 +34395 -0.33563232421875 +34396 -0.394012451171875 +34397 -0.5345458984375 +34398 -0.52642822265625 +34399 -0.72186279296875 +34400 -0.606536865234375 +34401 -0.836669921875 +34402 -0.601470947265625 +34403 -0.8326416015625 +34404 -0.5255126953125 +34405 -0.7296142578125 +34406 -0.41796875 +34407 -0.582550048828125 +34408 -0.3135986328125 +34409 -0.440093994140625 +34410 -0.228302001953125 +34411 -0.324310302734375 +34412 -0.138214111328125 +34413 -0.20147705078125 +34414 -0.024261474609375 +34415 -0.044647216796875 +34416 0.0833740234375 +34417 0.103973388671875 +34418 0.15472412109375 +34419 0.202392578125 +34420 0.199615478515625 +34421 0.264495849609375 +34422 0.25262451171875 +34423 0.338897705078125 +34424 0.32672119140625 +34425 0.443817138671875 +34426 0.39764404296875 +34427 0.545074462890625 +34428 0.447418212890625 +34429 0.6173095703125 +34430 0.47039794921875 +34431 0.6524658203125 +34432 0.475860595703125 +34433 0.66339111328125 +34434 0.46826171875 +34435 0.6561279296875 +34436 0.430694580078125 +34437 0.606781005859375 +34438 0.353240966796875 +34439 0.501190185546875 +34440 0.245574951171875 +34441 0.352783203125 +34442 0.118438720703125 +34443 0.176544189453125 +34444 -0.03326416015625 +34445 -0.034820556640625 +34446 -0.1929931640625 +34447 -0.258209228515625 +34448 -0.324310302734375 +34449 -0.44244384765625 +34450 -0.41851806640625 +34451 -0.5753173828125 +34452 -0.4722900390625 +34453 -0.65203857421875 +34454 -0.463592529296875 +34455 -0.641632080078125 +34456 -0.4053955078125 +34457 -0.562164306640625 +34458 -0.32940673828125 +34459 -0.458038330078125 +34460 -0.250885009765625 +34461 -0.350555419921875 +34462 -0.184783935546875 +34463 -0.260528564453125 +34464 -0.1341552734375 +34465 -0.192108154296875 +34466 -0.096710205078125 +34467 -0.141937255859375 +34468 -0.06695556640625 +34469 -0.1021728515625 +34470 -0.037872314453125 +34471 -0.062896728515625 +34472 -0.0008544921875 +34473 -0.011932373046875 +34474 0.05267333984375 +34475 0.062835693359375 +34476 0.113677978515625 +34477 0.148712158203125 +34478 0.179351806640625 +34479 0.241729736328125 +34480 0.254852294921875 +34481 0.34912109375 +34482 0.330596923828125 +34483 0.457305908203125 +34484 0.3907470703125 +34485 0.54388427734375 +34486 0.409759521484375 +34487 0.5728759765625 +34488 0.360870361328125 +34489 0.506591796875 +34490 0.24859619140625 +34491 0.351226806640625 +34492 0.101318359375 +34493 0.146514892578125 +34494 -0.04364013671875 +34495 -0.05523681640625 +34496 -0.1593017578125 +34497 -0.21624755859375 +34498 -0.244476318359375 +34499 -0.334930419921875 +34500 -0.29327392578125 +34501 -0.402984619140625 +34502 -0.32049560546875 +34503 -0.4412841796875 +34504 -0.35888671875 +34505 -0.49578857421875 +34506 -0.40399169921875 +34507 -0.5601806640625 +34508 -0.431854248046875 +34509 -0.600738525390625 +34510 -0.41888427734375 +34511 -0.584228515625 +34512 -0.34283447265625 +34513 -0.47930908203125 +34514 -0.199066162109375 +34515 -0.27935791015625 +34516 -0.005126953125 +34517 -0.0089111328125 +34518 0.19384765625 +34519 0.268798828125 +34520 0.347320556640625 +34521 0.482818603515625 +34522 0.43426513671875 +34523 0.60369873046875 +34524 0.4681396484375 +34525 0.650421142578125 +34526 0.478118896484375 +34527 0.66400146484375 +34528 0.462066650390625 +34529 0.6414794921875 +34530 0.41265869140625 +34531 0.572540283203125 +34532 0.359100341796875 +34533 0.498138427734375 +34534 0.3165283203125 +34535 0.439453125 +34536 0.270050048828125 +34537 0.375518798828125 +34538 0.197052001953125 +34539 0.274505615234375 +34540 0.077911376953125 +34541 0.1087646484375 +34542 -0.0714111328125 +34543 -0.099395751953125 +34544 -0.228240966796875 +34545 -0.3182373046875 +34546 -0.3934326171875 +34547 -0.5489501953125 +34548 -0.55426025390625 +34549 -0.7738037109375 +34550 -0.673004150390625 +34551 -0.86383056640625 +34552 -0.7259521484375 +34553 -0.870391845703125 +34554 -0.7257080078125 +34555 -0.86895751953125 +34556 -0.681640625 +34557 -0.861053466796875 +34558 -0.581451416015625 +34559 -0.765869140625 +34560 -0.417205810546875 +34561 -0.5301513671875 +34562 -0.19451904296875 +34563 -0.214691162109375 +34564 0.05609130859375 +34565 0.137359619140625 +34566 0.2987060546875 +34567 0.474822998046875 +34568 0.508270263671875 +34569 0.76239013671875 +34570 0.665740966796875 +34571 0.867462158203125 +34572 0.770904541015625 +34573 0.870361328125 +34574 0.81561279296875 +34575 0.86480712890625 +34576 0.8033447265625 +34577 0.831817626953125 +34578 0.750701904296875 +34579 0.677581787109375 +34580 0.66180419921875 +34581 0.495880126953125 +34582 0.549591064453125 +34583 0.30767822265625 +34584 0.415985107421875 +34585 0.116180419921875 +34586 0.2398681640625 +34587 -0.110748291015625 +34588 0.01708984375 +34589 -0.381805419921875 +34590 -0.222686767578125 +34591 -0.6572265625 +34592 -0.43817138671875 +34593 -0.857421875 +34594 -0.599700927734375 +34595 -0.870391845703125 +34596 -0.701995849609375 +34597 -0.870391845703125 +34598 -0.763031005859375 +34599 -0.86444091796875 +34600 -0.806854248046875 +34601 -0.85723876953125 +34602 -0.82086181640625 +34603 -0.790008544921875 +34604 -0.7681884765625 +34605 -0.62847900390625 +34606 -0.646759033203125 +34607 -0.3956298828125 +34608 -0.4791259765625 +34609 -0.126708984375 +34610 -0.28424072265625 +34611 0.150115966796875 +34612 -0.0704345703125 +34613 0.424041748046875 +34614 0.1435546875 +34615 0.670623779296875 +34616 0.3309326171875 +34617 0.854522705078125 +34618 0.479217529296875 +34619 0.866485595703125 +34620 0.577545166015625 +34621 0.86920166015625 +34622 0.637908935546875 +34623 0.8653564453125 +34624 0.66912841796875 +34625 0.857147216796875 +34626 0.668975830078125 +34627 0.766845703125 +34628 0.64080810546875 +34629 0.628509521484375 +34630 0.580047607421875 +34631 0.462127685546875 +34632 0.5042724609375 +34633 0.297210693359375 +34634 0.42205810546875 +34635 0.14862060546875 +34636 0.318145751953125 +34637 -0.00537109375 +34638 0.1978759765625 +34639 -0.15753173828125 +34640 0.05914306640625 +34641 -0.31304931640625 +34642 -0.107177734375 +34643 -0.48876953125 +34644 -0.268829345703125 +34645 -0.6416015625 +34646 -0.408660888671875 +34647 -0.751373291015625 +34648 -0.542022705078125 +34649 -0.84619140625 +34650 -0.65863037109375 +34651 -0.861297607421875 +34652 -0.7357177734375 +34653 -0.863250732421875 +34654 -0.751678466796875 +34655 -0.856597900390625 +34656 -0.714691162109375 +34657 -0.7498779296875 +34658 -0.66412353515625 +34659 -0.624542236328125 +34660 -0.58514404296875 +34661 -0.47808837890625 +34662 -0.43817138671875 +34663 -0.253387451171875 +34664 -0.254486083984375 +34665 0.003692626953125 +34666 -0.08087158203125 +34667 0.2257080078125 +34668 0.09088134765625 +34669 0.427154541015625 +34670 0.282470703125 +34671 0.643218994140625 +34672 0.486968994140625 +34673 0.855926513671875 +34674 0.6646728515625 +34675 0.870361328125 +34676 0.781585693359375 +34677 0.870361328125 +34678 0.84234619140625 +34679 0.862762451171875 +34680 0.84478759765625 +34681 0.79669189453125 +34682 0.78240966796875 +34683 0.595794677734375 +34684 0.675079345703125 +34685 0.362152099609375 +34686 0.54193115234375 +34687 0.1270751953125 +34688 0.397491455078125 +34689 -0.086944580078125 +34690 0.243408203125 +34691 -0.2784423828125 +34692 0.0562744140625 +34693 -0.484832763671875 +34694 -0.1766357421875 +34695 -0.729583740234375 +34696 -0.420562744140625 +34697 -0.86688232421875 +34698 -0.63214111328125 +34699 -0.870391845703125 +34700 -0.80767822265625 +34701 -0.86859130859375 +34702 -0.86444091796875 +34703 -0.86279296875 +34704 -0.870391845703125 +34705 -0.817962646484375 +34706 -0.8663330078125 +34707 -0.6116943359375 +34708 -0.829803466796875 +34709 -0.3128662109375 +34710 -0.62481689453125 +34711 0.039398193359375 +34712 -0.362091064453125 +34713 0.422821044921875 +34714 -0.06475830078125 +34715 0.805145263671875 +34716 0.220550537109375 +34717 0.870361328125 +34718 0.454925537109375 +34719 0.870361328125 +34720 0.630401611328125 +34721 0.860015869140625 +34722 0.741973876953125 +34723 0.727935791015625 +34724 0.786163330078125 +34725 0.48114013671875 +34726 0.7799072265625 +34727 0.2059326171875 +34728 0.739166259765625 +34729 -0.06103515625 +34730 0.67144775390625 +34731 -0.29913330078125 +34732 0.567596435546875 +34733 -0.516204833984375 +34734 0.41790771484375 +34735 -0.7252197265625 +34736 0.24005126953125 +34737 -0.85980224609375 +34738 0.05804443359375 +34739 -0.870391845703125 +34740 -0.107330322265625 +34741 -0.870391845703125 +34742 -0.222381591796875 +34743 -0.858062744140625 +34744 -0.2838134765625 +34745 -0.673004150390625 +34746 -0.3270263671875 +34747 -0.42694091796875 +34748 -0.382080078125 +34749 -0.2100830078125 +34750 -0.447540283203125 +34751 -0.0362548828125 +34752 -0.5037841796875 +34753 0.10943603515625 +34754 -0.537567138671875 +34755 0.23516845703125 +34756 -0.52117919921875 +34757 0.373687744140625 +34758 -0.45648193359375 +34759 0.517791748046875 +34760 -0.38690185546875 +34761 0.602783203125 +34762 -0.309600830078125 +34763 0.635711669921875 +34764 -0.20257568359375 +34765 0.655181884765625 +34766 -0.073211669921875 +34767 0.65948486328125 +34768 0.072418212890625 +34769 0.651275634765625 +34770 0.2171630859375 +34771 0.61846923828125 +34772 0.335479736328125 +34773 0.53753662109375 +34774 0.414794921875 +34775 0.404144287109375 +34776 0.448333740234375 +34777 0.22186279296875 +34778 0.43695068359375 +34779 0.003997802734375 +34780 0.393096923828125 +34781 -0.22100830078125 +34782 0.331085205078125 +34783 -0.42449951171875 +34784 0.265838623046875 +34785 -0.579833984375 +34786 0.22686767578125 +34787 -0.641876220703125 +34788 0.210205078125 +34789 -0.6177978515625 +34790 0.1724853515625 +34791 -0.575531005859375 +34792 0.110626220703125 +34793 -0.526336669921875 +34794 0.060394287109375 +34795 -0.42645263671875 +34796 0.04095458984375 +34797 -0.2581787109375 +34798 0.0279541015625 +34799 -0.068695068359375 +34800 -0.004425048828125 +34801 0.09222412109375 +34802 -0.043304443359375 +34803 0.232147216796875 +34804 -0.0816650390625 +34805 0.3509521484375 +34806 -0.139678955078125 +34807 0.410064697265625 +34808 -0.237457275390625 +34809 0.372955322265625 +34810 -0.360992431640625 +34811 0.2554931640625 +34812 -0.475128173828125 +34813 0.10711669921875 +34814 -0.566925048828125 +34815 -0.052886962890625 +34816 -0.612579345703125 +34817 -0.186279296875 +34818 -0.574951171875 +34819 -0.23291015625 +34820 -0.46905517578125 +34821 -0.209442138671875 +34822 -0.3388671875 +34823 -0.174163818359375 +34824 -0.19085693359375 +34825 -0.126739501953125 +34826 -0.0196533203125 +34827 -0.048126220703125 +34828 0.155517578125 +34829 0.0426025390625 +34830 0.3035888671875 +34831 0.10748291015625 +34832 0.4154052734375 +34833 0.1409912109375 +34834 0.521514892578125 +34835 0.19708251953125 +34836 0.617340087890625 +34837 0.273651123046875 +34838 0.66656494140625 +34839 0.31768798828125 +34840 0.676544189453125 +34841 0.341094970703125 +34842 0.66400146484375 +34843 0.368011474609375 +34844 0.614471435546875 +34845 0.37249755859375 +34846 0.496490478515625 +34847 0.30072021484375 +34848 0.313873291015625 +34849 0.1517333984375 +34850 0.110595703125 +34851 -0.01470947265625 +34852 -0.1011962890625 +34853 -0.1883544921875 +34854 -0.318267822265625 +34855 -0.372711181640625 +34856 -0.500396728515625 +34857 -0.51397705078125 +34858 -0.6165771484375 +34859 -0.57177734375 +34860 -0.6585693359375 +34861 -0.53948974609375 +34862 -0.635101318359375 +34863 -0.43511962890625 +34864 -0.5687255859375 +34865 -0.2962646484375 +34866 -0.4835205078125 +34867 -0.161102294921875 +34868 -0.389007568359375 +34869 -0.0435791015625 +34870 -0.284149169921875 +34871 0.060394287109375 +34872 -0.180694580078125 +34873 0.13665771484375 +34874 -0.091888427734375 +34875 0.170135498046875 +34876 -0.018707275390625 +34877 0.16552734375 +34878 0.056793212890625 +34879 0.15728759765625 +34880 0.133575439453125 +34881 0.150787353515625 +34882 0.191619873046875 +34883 0.12200927734375 +34884 0.2327880859375 +34885 0.080108642578125 +34886 0.2706298828125 +34887 0.05126953125 +34888 0.32025146484375 +34889 0.062896728515625 +34890 0.365264892578125 +34891 0.09271240234375 +34892 0.373748779296875 +34893 0.092987060546875 +34894 0.3553466796875 +34895 0.07855224609375 +34896 0.320709228515625 +34897 0.06427001953125 +34898 0.261688232421875 +34899 0.0347900390625 +34900 0.1796875 +34901 -0.01171875 +34902 0.09033203125 +34903 -0.056060791015625 +34904 0.02496337890625 +34905 -0.055511474609375 +34906 -0.012908935546875 +34907 -0.010467529296875 +34908 -0.054656982421875 +34909 0.02508544921875 +34910 -0.11334228515625 +34911 0.025665283203125 +34912 -0.16900634765625 +34913 0.017333984375 +34914 -0.217987060546875 +34915 0.00189208984375 +34916 -0.26568603515625 +34917 -0.03173828125 +34918 -0.30328369140625 +34919 -0.071502685546875 +34920 -0.342254638671875 +34921 -0.13543701171875 +34922 -0.380828857421875 +34923 -0.219970703125 +34924 -0.404266357421875 +34925 -0.300506591796875 +34926 -0.4140625 +34927 -0.376312255859375 +34928 -0.392303466796875 +34929 -0.416107177734375 +34930 -0.310150146484375 +34931 -0.371124267578125 +34932 -0.171234130859375 +34933 -0.242279052734375 +34934 -0.004730224609375 +34935 -0.069732666015625 +34936 0.172821044921875 +34937 0.125640869140625 +34938 0.338531494140625 +34939 0.31268310546875 +34940 0.466552734375 +34941 0.45501708984375 +34942 0.55657958984375 +34943 0.554779052734375 +34944 0.606689453125 +34945 0.61065673828125 +34946 0.60882568359375 +34947 0.610931396484375 +34948 0.54754638671875 +34949 0.531463623046875 +34950 0.434112548828125 +34951 0.3883056640625 +34952 0.304534912109375 +34953 0.23468017578125 +34954 0.1767578125 +34955 0.095245361328125 +34956 0.069915771484375 +34957 -0.00396728515625 +34958 -0.004150390625 +34959 -0.04852294921875 +34960 -0.053741455078125 +34961 -0.055145263671875 +34962 -0.110198974609375 +34963 -0.0758056640625 +34964 -0.189544677734375 +34965 -0.138702392578125 +34966 -0.26727294921875 +34967 -0.209197998046875 +34968 -0.342987060546875 +34969 -0.289031982421875 +34970 -0.416046142578125 +34971 -0.37884521484375 +34972 -0.471405029296875 +34973 -0.456329345703125 +34974 -0.505767822265625 +34975 -0.51641845703125 +34976 -0.493804931640625 +34977 -0.519287109375 +34978 -0.432159423828125 +34979 -0.458251953125 +34980 -0.355743408203125 +34981 -0.384796142578125 +34982 -0.28240966796875 +34983 -0.323699951171875 +34984 -0.210418701171875 +34985 -0.269287109375 +34986 -0.124755859375 +34987 -0.1951904296875 +34988 -0.026580810546875 +34989 -0.100006103515625 +34990 0.064697265625 +34991 -0.01055908203125 +34992 0.167022705078125 +34993 0.1033935546875 +34994 0.283721923828125 +34995 0.24908447265625 +34996 0.379119873046875 +34997 0.373199462890625 +34998 0.441162109375 +34999 0.45806884765625 +35000 0.4747314453125 +35001 0.511474609375 +35002 0.50091552734375 +35003 0.565399169921875 +35004 0.514923095703125 +35005 0.61138916015625 +35006 0.47900390625 +35007 0.5897216796875 +35008 0.388153076171875 +35009 0.4906005859375 +35010 0.25531005859375 +35011 0.33148193359375 +35012 0.10516357421875 +35013 0.147796630859375 +35014 -0.033447265625 +35015 -0.01873779296875 +35016 -0.140777587890625 +35017 -0.140289306640625 +35018 -0.19915771484375 +35019 -0.191986083984375 +35020 -0.21417236328125 +35021 -0.184295654296875 +35022 -0.213836669921875 +35023 -0.161834716796875 +35024 -0.224853515625 +35025 -0.166595458984375 +35026 -0.243927001953125 +35027 -0.19390869140625 +35028 -0.258575439453125 +35029 -0.22442626953125 +35030 -0.2833251953125 +35031 -0.279754638671875 +35032 -0.305389404296875 +35033 -0.3389892578125 +35034 -0.2947998046875 +35035 -0.3543701171875 +35036 -0.267242431640625 +35037 -0.348175048828125 +35038 -0.22772216796875 +35039 -0.32598876953125 +35040 -0.158416748046875 +35041 -0.2581787109375 +35042 -0.057464599609375 +35043 -0.139801025390625 +35044 0.064422607421875 +35045 0.014617919921875 +35046 0.166656494140625 +35047 0.144378662109375 +35048 0.229888916015625 +35049 0.221038818359375 +35050 0.270477294921875 +35051 0.27069091796875 +35052 0.288604736328125 +35053 0.294036865234375 +35054 0.297698974609375 +35055 0.311767578125 +35056 0.307952880859375 +35057 0.339141845703125 +35058 0.309539794921875 +35059 0.360260009765625 +35060 0.293792724609375 +35061 0.360504150390625 +35062 0.241241455078125 +35063 0.308380126953125 +35064 0.138641357421875 +35065 0.18170166015625 +35066 0.002960205078125 +35067 0.0047607421875 +35068 -0.13427734375 +35069 -0.17559814453125 +35070 -0.242828369140625 +35071 -0.3143310546875 +35072 -0.29388427734375 +35073 -0.36785888671875 +35074 -0.30328369140625 +35075 -0.36248779296875 +35076 -0.2991943359375 +35077 -0.343536376953125 +35078 -0.27593994140625 +35079 -0.3018798828125 +35080 -0.229888916015625 +35081 -0.231414794921875 +35082 -0.15252685546875 +35083 -0.117645263671875 +35084 -0.06439208984375 +35085 0.007049560546875 +35086 6.103515625e-05 +35087 0.087982177734375 +35088 0.04876708984375 +35089 0.13946533203125 +35090 0.088592529296875 +35091 0.17425537109375 +35092 0.115936279296875 +35093 0.188201904296875 +35094 0.12359619140625 +35095 0.171234130859375 +35096 0.10760498046875 +35097 0.118438720703125 +35098 0.08392333984375 +35099 0.05706787109375 +35100 0.05316162109375 +35101 -0.010711669921875 +35102 0.01080322265625 +35103 -0.0914306640625 +35104 -0.029388427734375 +35105 -0.162322998046875 +35106 -0.04974365234375 +35107 -0.194549560546875 +35108 -0.02618408203125 +35109 -0.1492919921875 +35110 0.044647216796875 +35111 -0.02166748046875 +35112 0.123687744140625 +35113 0.124053955078125 +35114 0.164337158203125 +35115 0.211151123046875 +35116 0.16790771484375 +35117 0.240447998046875 +35118 0.15386962890625 +35119 0.242218017578125 +35120 0.128753662109375 +35121 0.2257080078125 +35122 0.095489501953125 +35123 0.194366455078125 +35124 0.034698486328125 +35125 0.115509033203125 +35126 -0.03839111328125 +35127 0.0128173828125 +35128 -0.08642578125 +35129 -0.053802490234375 +35130 -0.125274658203125 +35131 -0.110626220703125 +35132 -0.180633544921875 +35133 -0.199493408203125 +35134 -0.23651123046875 +35135 -0.29437255859375 +35136 -0.254302978515625 +35137 -0.33221435546875 +35138 -0.213897705078125 +35139 -0.27972412109375 +35140 -0.1456298828125 +35141 -0.185333251953125 +35142 -0.098876953125 +35143 -0.128204345703125 +35144 -0.078826904296875 +35145 -0.115692138671875 +35146 -0.066864013671875 +35147 -0.116455078125 +35148 -0.048583984375 +35149 -0.105926513671875 +35150 -0.006011962890625 +35151 -0.053955078125 +35152 0.0660400390625 +35153 0.048797607421875 +35154 0.13946533203125 +35155 0.157318115234375 +35156 0.177215576171875 +35157 0.212005615234375 +35158 0.182586669921875 +35159 0.218475341796875 +35160 0.19287109375 +35161 0.23724365234375 +35162 0.231048583984375 +35163 0.30535888671875 +35164 0.27178955078125 +35165 0.38128662109375 +35166 0.278167724609375 +35167 0.404449462890625 +35168 0.262725830078125 +35169 0.3944091796875 +35170 0.2490234375 +35171 0.3885498046875 +35172 0.22271728515625 +35173 0.362640380859375 +35174 0.157867431640625 +35175 0.27362060546875 +35176 0.052337646484375 +35177 0.11712646484375 +35178 -0.061370849609375 +35179 -0.054901123046875 +35180 -0.151123046875 +35181 -0.19085693359375 +35182 -0.213531494140625 +35183 -0.28570556640625 +35184 -0.248321533203125 +35185 -0.339263916015625 +35186 -0.271484375 +35187 -0.3775634765625 +35188 -0.3109130859375 +35189 -0.445709228515625 +35190 -0.361480712890625 +35191 -0.535064697265625 +35192 -0.413299560546875 +35193 -0.629058837890625 +35194 -0.44818115234375 +35195 -0.697601318359375 +35196 -0.443939208984375 +35197 -0.70391845703125 +35198 -0.3975830078125 +35199 -0.6424560546875 +35200 -0.296051025390625 +35201 -0.491241455078125 +35202 -0.149322509765625 +35203 -0.265716552734375 +35204 0.00653076171875 +35205 -0.023712158203125 +35206 0.150848388671875 +35207 0.201751708984375 +35208 0.261871337890625 +35209 0.375823974609375 +35210 0.331207275390625 +35211 0.485076904296875 +35212 0.383026123046875 +35213 0.56884765625 +35214 0.42205810546875 +35215 0.634765625 +35216 0.420623779296875 +35217 0.63763427734375 +35218 0.37188720703125 +35219 0.5660400390625 +35220 0.308197021484375 +35221 0.4720458984375 +35222 0.261505126953125 +35223 0.40692138671875 +35224 0.236602783203125 +35225 0.3778076171875 +35226 0.229095458984375 +35227 0.376953125 +35228 0.219390869140625 +35229 0.371978759765625 +35230 0.17724609375 +35231 0.313140869140625 +35232 0.09307861328125 +35233 0.184417724609375 +35234 -0.0172119140625 +35235 0.011199951171875 +35236 -0.13165283203125 +35237 -0.171051025390625 +35238 -0.23480224609375 +35239 -0.33740234375 +35240 -0.316864013671875 +35241 -0.47198486328125 +35242 -0.369049072265625 +35243 -0.560394287109375 +35244 -0.377960205078125 +35245 -0.58056640625 +35246 -0.353118896484375 +35247 -0.54754638671875 +35248 -0.3238525390625 +35249 -0.508575439453125 +35250 -0.2879638671875 +35251 -0.459503173828125 +35252 -0.2420654296875 +35253 -0.394378662109375 +35254 -0.21075439453125 +35255 -0.35260009765625 +35256 -0.18048095703125 +35257 -0.31170654296875 +35258 -0.10577392578125 +35259 -0.197418212890625 +35260 0.014251708984375 +35261 -0.007965087890625 +35262 0.149139404296875 +35263 0.207489013671875 +35264 0.274322509765625 +35265 0.409210205078125 +35266 0.374298095703125 +35267 0.57208251953125 +35268 0.430572509765625 +35269 0.66595458984375 +35270 0.42352294921875 +35271 0.65875244140625 +35272 0.36376953125 +35273 0.56744384765625 +35274 0.2757568359375 +35275 0.431396484375 +35276 0.186737060546875 +35277 0.29443359375 +35278 0.11297607421875 +35279 0.182464599609375 +35280 0.035125732421875 +35281 0.06365966796875 +35282 -0.05517578125 +35283 -0.075958251953125 +35284 -0.1287841796875 +35285 -0.189422607421875 +35286 -0.182525634765625 +35287 -0.271942138671875 +35288 -0.22796630859375 +35289 -0.342529296875 +35290 -0.242279052734375 +35291 -0.364166259765625 +35292 -0.219512939453125 +35293 -0.327239990234375 +35294 -0.187530517578125 +35295 -0.2769775390625 +35296 -0.171295166015625 +35297 -0.253692626953125 +35298 -0.162445068359375 +35299 -0.24365234375 +35300 -0.13128662109375 +35301 -0.1983642578125 +35302 -0.0770263671875 +35303 -0.116241455078125 +35304 -0.02423095703125 +35305 -0.036834716796875 +35306 0.0238037109375 +35307 0.034881591796875 +35308 0.0621337890625 +35309 0.09124755859375 +35310 0.076171875 +35311 0.10888671875 +35312 0.0889892578125 +35313 0.125518798828125 +35314 0.1107177734375 +35315 0.15771484375 +35316 0.124481201171875 +35317 0.17828369140625 +35318 0.12030029296875 +35319 0.17108154296875 +35320 0.09442138671875 +35321 0.129974365234375 +35322 0.063812255859375 +35323 0.082427978515625 +35324 0.028106689453125 +35325 0.027679443359375 +35326 -0.031890869140625 +35327 -0.065643310546875 +35328 -0.092864990234375 +35329 -0.15936279296875 +35330 -0.129364013671875 +35331 -0.21307373046875 +35332 -0.145416259765625 +35333 -0.234649658203125 +35334 -0.12725830078125 +35335 -0.2001953125 +35336 -0.0806884765625 +35337 -0.119171142578125 +35338 -0.02532958984375 +35339 -0.024749755859375 +35340 0.0401611328125 +35341 0.085784912109375 +35342 0.095550537109375 +35343 0.178131103515625 +35344 0.119232177734375 +35345 0.215576171875 +35346 0.11883544921875 +35347 0.211456298828125 +35348 0.099761962890625 +35349 0.17523193359375 +35350 0.07464599609375 +35351 0.128753662109375 +35352 0.06085205078125 +35353 0.1019287109375 +35354 0.04638671875 +35355 0.0743408203125 +35356 0.02960205078125 +35357 0.04327392578125 +35358 0.027618408203125 +35359 0.038177490234375 +35360 0.05047607421875 +35361 0.076263427734375 +35362 0.08856201171875 +35363 0.14105224609375 +35364 0.11492919921875 +35365 0.186431884765625 +35366 0.115814208984375 +35367 0.188812255859375 +35368 0.0859375 +35369 0.1390380859375 +35370 0.028106689453125 +35371 0.041778564453125 +35372 -0.043853759765625 +35373 -0.079437255859375 +35374 -0.1268310546875 +35375 -0.219390869140625 +35376 -0.21478271484375 +35377 -0.367828369140625 +35378 -0.290191650390625 +35379 -0.494873046875 +35380 -0.327117919921875 +35381 -0.556243896484375 +35382 -0.300262451171875 +35383 -0.508697509765625 +35384 -0.223236083984375 +35385 -0.3756103515625 +35386 -0.1322021484375 +35387 -0.218902587890625 +35388 -0.04180908203125 +35389 -0.063751220703125 +35390 0.04888916015625 +35391 0.091552734375 +35392 0.133514404296875 +35393 0.23602294921875 +35394 0.196441650390625 +35395 0.342987060546875 +35396 0.22760009765625 +35397 0.39520263671875 +35398 0.225006103515625 +35399 0.389373779296875 +35400 0.187896728515625 +35401 0.324249267578125 +35402 0.130401611328125 +35403 0.224090576171875 +35404 0.0731201171875 +35405 0.124267578125 +35406 0.02313232421875 +35407 0.037078857421875 +35408 -0.003570556640625 +35409 -0.010101318359375 +35410 -0.008331298828125 +35411 -0.019439697265625 +35412 -0.009765625 +35413 -0.022796630859375 +35414 0.0029296875 +35415 -0.001556396484375 +35416 0.036773681640625 +35417 0.056304931640625 +35418 0.0660400390625 +35419 0.106719970703125 +35420 0.0599365234375 +35421 0.096893310546875 +35422 0.027740478515625 +35423 0.042694091796875 +35424 -0.008392333984375 +35425 -0.018035888671875 +35426 -0.04290771484375 +35427 -0.07586669921875 +35428 -0.06915283203125 +35429 -0.11944580078125 +35430 -0.093475341796875 +35431 -0.15972900390625 +35432 -0.1192626953125 +35433 -0.202606201171875 +35434 -0.146728515625 +35435 -0.24859619140625 +35436 -0.18023681640625 +35437 -0.30517578125 +35438 -0.21380615234375 +35439 -0.36212158203125 +35440 -0.231109619140625 +35441 -0.39141845703125 +35442 -0.210052490234375 +35443 -0.35528564453125 +35444 -0.148468017578125 +35445 -0.249969482421875 +35446 -0.056488037109375 +35447 -0.092864990234375 +35448 0.050079345703125 +35449 0.08905029296875 +35450 0.1358642578125 +35451 0.2352294921875 +35452 0.1851806640625 +35453 0.318817138671875 +35454 0.208953857421875 +35455 0.358642578125 +35456 0.203125 +35457 0.347747802734375 +35458 0.167388916015625 +35459 0.28564453125 +35460 0.131378173828125 +35461 0.223175048828125 +35462 0.1163330078125 +35463 0.196746826171875 +35464 0.106781005859375 +35465 0.179840087890625 +35466 0.092803955078125 +35467 0.155548095703125 +35468 0.090362548828125 +35469 0.151214599609375 +35470 0.09368896484375 +35471 0.156951904296875 +35472 0.078857421875 +35473 0.13177490234375 +35474 0.060546875 +35475 0.100799560546875 +35476 0.05224609375 +35477 0.087127685546875 +35478 0.03302001953125 +35479 0.05487060546875 +35480 -0.00469970703125 +35481 -0.009002685546875 +35482 -0.06060791015625 +35483 -0.10400390625 +35484 -0.13427734375 +35485 -0.229400634765625 +35486 -0.20831298828125 +35487 -0.35552978515625 +35488 -0.259063720703125 +35489 -0.441925048828125 +35490 -0.2779541015625 +35491 -0.473846435546875 +35492 -0.2728271484375 +35493 -0.464813232421875 +35494 -0.246185302734375 +35495 -0.419097900390625 +35496 -0.1966552734375 +35497 -0.334320068359375 +35498 -0.1343994140625 +35499 -0.227935791015625 +35500 -0.07318115234375 +35501 -0.12347412109375 +35502 -0.016937255859375 +35503 -0.02764892578125 +35504 0.044921875 +35505 0.077667236328125 +35506 0.124481201171875 +35507 0.2132568359375 +35508 0.227386474609375 +35509 0.38885498046875 +35510 0.340972900390625 +35511 0.582794189453125 +35512 0.4295654296875 +35513 0.734039306640625 +35514 0.4683837890625 +35515 0.800140380859375 +35516 0.455780029296875 +35517 0.7783203125 +35518 0.389739990234375 +35519 0.6651611328125 +35520 0.26971435546875 +35521 0.45965576171875 +35522 0.117523193359375 +35523 0.199188232421875 +35524 -0.02850341796875 +35525 -0.050689697265625 +35526 -0.135101318359375 +35527 -0.23297119140625 +35528 -0.1920166015625 +35529 -0.33013916015625 +35530 -0.21453857421875 +35531 -0.368408203125 +35532 -0.220855712890625 +35533 -0.378936767578125 +35534 -0.21990966796875 +35535 -0.376983642578125 +35536 -0.221710205078125 +35537 -0.37969970703125 +35538 -0.22882080078125 +35539 -0.391510009765625 +35540 -0.225433349609375 +35541 -0.385345458984375 +35542 -0.20025634765625 +35543 -0.3419189453125 +35544 -0.165924072265625 +35545 -0.28289794921875 +35546 -0.147735595703125 +35547 -0.251617431640625 +35548 -0.156219482421875 +35549 -0.266143798828125 +35550 -0.160369873046875 +35551 -0.273345947265625 +35552 -0.12725830078125 +35553 -0.216796875 +35554 -0.075408935546875 +35555 -0.128265380859375 +35556 -0.04010009765625 +35557 -0.068145751953125 +35558 -0.02520751953125 +35559 -0.0430908203125 +35560 -0.0140380859375 +35561 -0.024444580078125 +35562 0.012603759765625 +35563 0.020721435546875 +35564 0.07342529296875 +35565 0.124481201171875 +35566 0.1514892578125 +35567 0.25787353515625 +35568 0.222381591796875 +35569 0.379119873046875 +35570 0.281280517578125 +35571 0.47991943359375 +35572 0.3094482421875 +35573 0.5281982421875 +35574 0.299407958984375 +35575 0.511138916015625 +35576 0.2672119140625 +35577 0.456207275390625 +35578 0.238616943359375 +35579 0.407470703125 +35580 0.224609375 +35581 0.383758544921875 +35582 0.208740234375 +35583 0.35687255859375 +35584 0.181732177734375 +35585 0.31182861328125 +35586 0.14459228515625 +35587 0.250885009765625 +35588 0.09295654296875 +35589 0.1654052734375 +35590 0.0162353515625 +35591 0.035247802734375 +35592 -0.08648681640625 +35593 -0.142059326171875 +35594 -0.19775390625 +35595 -0.33563232421875 +35596 -0.311187744140625 +35597 -0.5345458984375 +35598 -0.41717529296875 +35599 -0.72186279296875 +35600 -0.481964111328125 +35601 -0.836669921875 +35602 -0.47991943359375 +35603 -0.8326416015625 +35604 -0.4219970703125 +35605 -0.7296142578125 +35606 -0.338653564453125 +35607 -0.582550048828125 +35608 -0.25689697265625 +35609 -0.440093994140625 +35610 -0.189117431640625 +35611 -0.324310302734375 +35612 -0.116912841796875 +35613 -0.20147705078125 +35614 -0.02569580078125 +35615 -0.044647216796875 +35616 0.060943603515625 +35617 0.103973388671875 +35618 0.11956787109375 +35619 0.202392578125 +35620 0.1575927734375 +35621 0.264495849609375 +35622 0.201690673828125 +35623 0.338897705078125 +35624 0.261749267578125 +35625 0.443817138671875 +35626 0.318817138671875 +35627 0.545074462890625 +35628 0.358856201171875 +35629 0.6173095703125 +35630 0.37744140625 +35631 0.6524658203125 +35632 0.3817138671875 +35633 0.66339111328125 +35634 0.375152587890625 +35635 0.6561279296875 +35636 0.3447265625 +35637 0.606781005859375 +35638 0.282806396484375 +35639 0.501190185546875 +35640 0.196990966796875 +35641 0.352783203125 +35642 0.095794677734375 +35643 0.176544189453125 +35644 -0.024566650390625 +35645 -0.034820556640625 +35646 -0.151123046875 +35647 -0.258209228515625 +35648 -0.2554931640625 +35649 -0.44244384765625 +35650 -0.330810546875 +35651 -0.5753173828125 +35652 -0.37432861328125 +35653 -0.65203857421875 +35654 -0.368927001953125 +35655 -0.641632080078125 +35656 -0.3245849609375 +35657 -0.562164306640625 +35658 -0.265869140625 +35659 -0.458038330078125 +35660 -0.204620361328125 +35661 -0.350555419921875 +35662 -0.152435302734375 +35663 -0.260528564453125 +35664 -0.111785888671875 +35665 -0.192108154296875 +35666 -0.080963134765625 +35667 -0.141937255859375 +35668 -0.055816650390625 +35669 -0.1021728515625 +35670 -0.03106689453125 +35671 -0.062896728515625 +35672 -0.0001220703125 +35673 -0.011932373046875 +35674 0.04351806640625 +35675 0.062835693359375 +35676 0.092742919921875 +35677 0.148712158203125 +35678 0.145263671875 +35679 0.241729736328125 +35680 0.205047607421875 +35681 0.34912109375 +35682 0.26458740234375 +35683 0.457305908203125 +35684 0.3115234375 +35685 0.54388427734375 +35686 0.326080322265625 +35687 0.5728759765625 +35688 0.287567138671875 +35689 0.506591796875 +35690 0.199493408203125 +35691 0.351226806640625 +35692 0.083953857421875 +35693 0.146514892578125 +35694 -0.030029296875 +35695 -0.05523681640625 +35696 -0.121490478515625 +35697 -0.21624755859375 +35698 -0.189361572265625 +35699 -0.334930419921875 +35700 -0.22894287109375 +35701 -0.402984619140625 +35702 -0.251678466796875 +35703 -0.4412841796875 +35704 -0.282867431640625 +35705 -0.49578857421875 +35706 -0.318939208984375 +35707 -0.5601806640625 +35708 -0.34130859375 +35709 -0.600738525390625 +35710 -0.331634521484375 +35711 -0.584228515625 +35712 -0.27264404296875 +35713 -0.47930908203125 +35714 -0.1607666015625 +35715 -0.27935791015625 +35716 -0.0096435546875 +35717 -0.0089111328125 +35718 0.145660400390625 +35719 0.268798828125 +35720 0.265899658203125 +35721 0.482818603515625 +35722 0.334686279296875 +35723 0.60369873046875 +35724 0.36236572265625 +35725 0.650421142578125 +35726 0.37152099609375 +35727 0.66400146484375 +35728 0.360443115234375 +35729 0.6414794921875 +35730 0.3233642578125 +35731 0.572540283203125 +35732 0.2828369140625 +35733 0.498138427734375 +35734 0.25054931640625 +35735 0.439453125 +35736 0.21490478515625 +35737 0.375518798828125 +35738 0.15838623046875 +35739 0.274505615234375 +35740 0.0657958984375 +35741 0.1087646484375 +35742 -0.05047607421875 +35743 -0.099395751953125 +35744 -0.172821044921875 +35745 -0.3182373046875 +35746 -0.301849365234375 +35747 -0.5489501953125 +35748 -0.4276123046875 +35749 -0.7738037109375 +35750 -0.52081298828125 +35751 -0.86383056640625 +35752 -0.563018798828125 +35753 -0.870391845703125 +35754 -0.563934326171875 +35755 -0.86895751953125 +35756 -0.53076171875 +35757 -0.861053466796875 +35758 -0.45391845703125 +35759 -0.765869140625 +35760 -0.3271484375 +35761 -0.5301513671875 +35762 -0.154388427734375 +35763 -0.214691162109375 +35764 0.040557861328125 +35765 0.137359619140625 +35766 0.2293701171875 +35767 0.474822998046875 +35768 0.392333984375 +35769 0.76239013671875 +35770 0.514495849609375 +35771 0.867462158203125 +35772 0.596038818359375 +35773 0.870361328125 +35774 0.6304931640625 +35775 0.86480712890625 +35776 0.6207275390625 +35777 0.831817626953125 +35778 0.58013916015625 +35779 0.677581787109375 +35780 0.511871337890625 +35781 0.495880126953125 +35782 0.426116943359375 +35783 0.30767822265625 +35784 0.32403564453125 +35785 0.116180419921875 +35786 0.1881103515625 +35787 -0.110748291015625 +35788 0.014556884765625 +35789 -0.381805419921875 +35790 -0.1729736328125 +35791 -0.6572265625 +35792 -0.34136962890625 +35793 -0.857421875 +35794 -0.4669189453125 +35795 -0.870391845703125 +35796 -0.545654296875 +35797 -0.870391845703125 +35798 -0.59234619140625 +35799 -0.86444091796875 +35800 -0.626617431640625 +35801 -0.85723876953125 +35802 -0.6383056640625 +35803 -0.790008544921875 +35804 -0.59735107421875 +35805 -0.62847900390625 +35806 -0.501953125 +35807 -0.3956298828125 +35808 -0.370208740234375 +35809 -0.126708984375 +35810 -0.21722412109375 +35811 0.150115966796875 +35812 -0.049468994140625 +35813 0.424041748046875 +35814 0.1181640625 +35815 0.670623779296875 +35816 0.2642822265625 +35817 0.854522705078125 +35818 0.37908935546875 +35819 0.866485595703125 +35820 0.45404052734375 +35821 0.86920166015625 +35822 0.49908447265625 +35823 0.8653564453125 +35824 0.5216064453125 +35825 0.857147216796875 +35826 0.51995849609375 +35827 0.766845703125 +35828 0.496856689453125 +35829 0.628509521484375 +35830 0.44854736328125 +35831 0.462127685546875 +35832 0.389251708984375 +35833 0.297210693359375 +35834 0.32574462890625 +35835 0.14862060546875 +35836 0.24542236328125 +35837 -0.00537109375 +35838 0.152435302734375 +35839 -0.15753173828125 +35840 0.04522705078125 +35841 -0.31304931640625 +35842 -0.083831787109375 +35843 -0.48876953125 +35844 -0.210174560546875 +35845 -0.6416015625 +35846 -0.320098876953125 +35847 -0.751373291015625 +35848 -0.4249267578125 +35849 -0.84619140625 +35850 -0.51641845703125 +35851 -0.861297607421875 +35852 -0.576934814453125 +35853 -0.863250732421875 +35854 -0.58978271484375 +35855 -0.856597900390625 +35856 -0.5611572265625 +35857 -0.7498779296875 +35858 -0.52117919921875 +35859 -0.624542236328125 +35860 -0.458587646484375 +35861 -0.47808837890625 +35862 -0.34332275390625 +35863 -0.253387451171875 +35864 -0.199493408203125 +35865 0.003692626953125 +35866 -0.063079833984375 +35867 0.2257080078125 +35868 0.07196044921875 +35869 0.427154541015625 +35870 0.22198486328125 +35871 0.643218994140625 +35872 0.381500244140625 +35873 0.855926513671875 +35874 0.51995849609375 +35875 0.870361328125 +35876 0.611236572265625 +35877 0.870361328125 +35878 0.6588134765625 +35879 0.862762451171875 +35880 0.66094970703125 +35881 0.79669189453125 +35882 0.612701416015625 +35883 0.595794677734375 +35884 0.529296875 +35885 0.362152099609375 +35886 0.425445556640625 +35887 0.1270751953125 +35888 0.312408447265625 +35889 -0.086944580078125 +35890 0.191619873046875 +35891 -0.2784423828125 +35892 0.04534912109375 +35893 -0.484832763671875 +35894 -0.135955810546875 +35895 -0.729583740234375 +35896 -0.325592041015625 +35897 -0.86688232421875 +35898 -0.490203857421875 +35899 -0.870391845703125 +35900 -0.626800537109375 +35901 -0.86859130859375 +35902 -0.733978271484375 +35903 -0.86279296875 +35904 -0.792724609375 +35905 -0.817962646484375 +35906 -0.779266357421875 +35907 -0.6116943359375 +35908 -0.689849853515625 +35909 -0.3128662109375 +35910 -0.5419921875 +35911 0.039398193359375 +35912 -0.346221923828125 +35913 0.422821044921875 +35914 -0.120025634765625 +35915 0.805145263671875 +35916 0.100830078125 +35917 0.870361328125 +35918 0.286346435546875 +35919 0.870361328125 +35920 0.42999267578125 +35921 0.860015869140625 +35922 0.52734375 +35923 0.727935791015625 +35924 0.57501220703125 +35925 0.48114013671875 +35926 0.58514404296875 +35927 0.2059326171875 +35928 0.569091796875 +35929 -0.06103515625 +35930 0.531768798828125 +35931 -0.29913330078125 +35932 0.46539306640625 +35933 -0.516204833984375 +35934 0.36187744140625 +35935 -0.7252197265625 +35936 0.23419189453125 +35937 -0.85980224609375 +35938 0.100341796875 +35939 -0.870391845703125 +35940 -0.02398681640625 +35941 -0.870391845703125 +35942 -0.11309814453125 +35943 -0.858062744140625 +35944 -0.164306640625 +35945 -0.673004150390625 +35946 -0.204345703125 +35947 -0.42694091796875 +35948 -0.255706787109375 +35949 -0.2100830078125 +35950 -0.31671142578125 +35951 -0.0362548828125 +35952 -0.37176513671875 +35953 0.10943603515625 +35954 -0.4100341796875 +35955 0.23516845703125 +35956 -0.409637451171875 +35957 0.373687744140625 +35958 -0.371307373046875 +35959 0.517791748046875 +35960 -0.327728271484375 +35961 0.602783203125 +35962 -0.27618408203125 +35963 0.635711669921875 +35964 -0.19952392578125 +35965 0.655181884765625 +35966 -0.103179931640625 +35967 0.65948486328125 +35968 0.008270263671875 +35969 0.651275634765625 +35970 0.12158203125 +35971 0.61846923828125 +35972 0.217010498046875 +35973 0.53753662109375 +35974 0.28460693359375 +35975 0.404144287109375 +35976 0.31878662109375 +35977 0.22186279296875 +35978 0.3197021484375 +35979 0.003997802734375 +35980 0.29632568359375 +35981 -0.22100830078125 +35982 0.259002685546875 +35983 -0.42449951171875 +35984 0.21856689453125 +35985 -0.579833984375 +35986 0.1971435546875 +35987 -0.641876220703125 +35988 0.19122314453125 +35989 -0.6177978515625 +35990 0.167327880859375 +35991 -0.575531005859375 +35992 0.122894287109375 +35993 -0.526336669921875 +35994 0.085174560546875 +35995 -0.42645263671875 +35996 0.06884765625 +35997 -0.2581787109375 +35998 0.05548095703125 +35999 -0.068695068359375 +36000 0.0255126953125 +36001 0.09222412109375 +36002 -0.0108642578125 +36003 0.232147216796875 +36004 -0.0478515625 +36005 0.3509521484375 +36006 -0.1004638671875 +36007 0.410064697265625 +36008 -0.18359375 +36009 0.372955322265625 +36010 -0.286041259765625 +36011 0.2554931640625 +36012 -0.380523681640625 +36013 0.10711669921875 +36014 -0.456756591796875 +36015 -0.052886962890625 +36016 -0.49591064453125 +36017 -0.186279296875 +36018 -0.46905517578125 +36019 -0.23291015625 +36020 -0.38824462890625 +36021 -0.209442138671875 +36022 -0.28802490234375 +36023 -0.174163818359375 +36024 -0.173065185546875 +36025 -0.126739501953125 +36026 -0.038665771484375 +36027 -0.048126220703125 +36028 0.10009765625 +36029 0.0426025390625 +36030 0.218536376953125 +36031 0.10748291015625 +36032 0.309356689453125 +36033 0.1409912109375 +36034 0.396942138671875 +36035 0.19708251953125 +36036 0.4774169921875 +36037 0.273651123046875 +36038 0.52154541015625 +36039 0.31768798828125 +36040 0.534912109375 +36041 0.341094970703125 +36042 0.530609130859375 +36043 0.368011474609375 +36044 0.496673583984375 +36045 0.37249755859375 +36046 0.4075927734375 +36047 0.30072021484375 +36048 0.26617431640625 +36049 0.1517333984375 +36050 0.107269287109375 +36051 -0.01470947265625 +36052 -0.059539794921875 +36053 -0.1883544921875 +36054 -0.2318115234375 +36055 -0.372711181640625 +36056 -0.37738037109375 +36057 -0.51397705078125 +36058 -0.471435546875 +36059 -0.57177734375 +36060 -0.50732421875 +36061 -0.53948974609375 +36062 -0.491851806640625 +36063 -0.43511962890625 +36064 -0.442840576171875 +36065 -0.2962646484375 +36066 -0.379364013671875 +36067 -0.161102294921875 +36068 -0.3087158203125 +36069 -0.0435791015625 +36070 -0.229766845703125 +36071 0.060394287109375 +36072 -0.151702880859375 +36073 0.13665771484375 +36074 -0.084808349609375 +36075 0.170135498046875 +36076 -0.0296630859375 +36077 0.16552734375 +36078 0.028228759765625 +36079 0.15728759765625 +36080 0.088165283203125 +36081 0.150787353515625 +36082 0.134185791015625 +36083 0.12200927734375 +36084 0.167755126953125 +36085 0.080108642578125 +36086 0.19964599609375 +36087 0.05126953125 +36088 0.2418212890625 +36089 0.062896728515625 +36090 0.281036376953125 +36091 0.09271240234375 +36092 0.291534423828125 +36093 0.092987060546875 +36094 0.28082275390625 +36095 0.07855224609375 +36096 0.25732421875 +36097 0.06427001953125 +36098 0.21429443359375 +36099 0.0347900390625 +36100 0.15252685546875 +36101 -0.01171875 +36102 0.084136962890625 +36103 -0.056060791015625 +36104 0.0333251953125 +36105 -0.055511474609375 +36106 0.002899169921875 +36107 -0.010467529296875 +36108 -0.0311279296875 +36109 0.02508544921875 +36110 -0.07867431640625 +36111 0.025665283203125 +36112 -0.124176025390625 +36113 0.017333984375 +36114 -0.16473388671875 +36115 0.00189208984375 +36116 -0.204315185546875 +36117 -0.03173828125 +36118 -0.235992431640625 +36119 -0.071502685546875 +36120 -0.2684326171875 +36121 -0.13543701171875 +36122 -0.3001708984375 +36123 -0.219970703125 +36124 -0.31976318359375 +36125 -0.300506591796875 +36126 -0.32830810546875 +36127 -0.376312255859375 +36128 -0.31201171875 +36129 -0.416107177734375 +36130 -0.248687744140625 +36131 -0.371124267578125 +36132 -0.141143798828125 +36133 -0.242279052734375 +36134 -0.011871337890625 +36135 -0.069732666015625 +36136 0.126312255859375 +36137 0.125640869140625 +36138 0.25567626953125 +36139 0.31268310546875 +36140 0.356231689453125 +36141 0.45501708984375 +36142 0.427642822265625 +36143 0.554779052734375 +36144 0.468292236328125 +36145 0.61065673828125 +36146 0.471893310546875 +36147 0.610931396484375 +36148 0.426483154296875 +36149 0.531463623046875 +36150 0.340606689453125 +36151 0.3883056640625 +36152 0.241912841796875 +36153 0.23468017578125 +36154 0.1441650390625 +36155 0.095245361328125 +36156 0.06207275390625 +36157 -0.00396728515625 +36158 0.00469970703125 +36159 -0.04852294921875 +36160 -0.03424072265625 +36161 -0.055145263671875 +36162 -0.07879638671875 +36163 -0.0758056640625 +36164 -0.1412353515625 +36165 -0.138702392578125 +36166 -0.202667236328125 +36167 -0.209197998046875 +36168 -0.262664794921875 +36169 -0.289031982421875 +36170 -0.32061767578125 +36171 -0.37884521484375 +36172 -0.3648681640625 +36173 -0.456329345703125 +36174 -0.392791748046875 +36175 -0.51641845703125 +36176 -0.38482666015625 +36177 -0.519287109375 +36178 -0.33831787109375 +36179 -0.458251953125 +36180 -0.28009033203125 +36181 -0.384796142578125 +36182 -0.223846435546875 +36183 -0.323699951171875 +36184 -0.16827392578125 +36185 -0.269287109375 +36186 -0.101837158203125 +36187 -0.1951904296875 +36188 -0.02545166015625 +36189 -0.100006103515625 +36190 0.0458984375 +36191 -0.01055908203125 +36192 0.12591552734375 +36193 0.1033935546875 +36194 0.21710205078125 +36195 0.24908447265625 +36196 0.291900634765625 +36197 0.373199462890625 +36198 0.340972900390625 +36199 0.45806884765625 +36200 0.368011474609375 +36201 0.511474609375 +36202 0.389190673828125 +36203 0.565399169921875 +36204 0.4007568359375 +36205 0.61138916015625 +36206 0.3736572265625 +36207 0.5897216796875 +36208 0.303985595703125 +36209 0.4906005859375 +36210 0.20172119140625 +36211 0.33148193359375 +36212 0.085845947265625 +36213 0.147796630859375 +36214 -0.021392822265625 +36215 -0.01873779296875 +36216 -0.10479736328125 +36217 -0.140289306640625 +36218 -0.150726318359375 +36219 -0.191986083984375 +36220 -0.16339111328125 +36221 -0.184295654296875 +36222 -0.164276123046875 +36223 -0.161834716796875 +36224 -0.173858642578125 +36225 -0.166595458984375 +36226 -0.189544677734375 +36227 -0.19390869140625 +36228 -0.20172119140625 +36229 -0.22442626953125 +36230 -0.22149658203125 +36231 -0.279754638671875 +36232 -0.238983154296875 +36233 -0.3389892578125 +36234 -0.231109619140625 +36235 -0.3543701171875 +36236 -0.209930419921875 +36237 -0.348175048828125 +36238 -0.179290771484375 +36239 -0.32598876953125 +36240 -0.125518798828125 +36241 -0.2581787109375 +36242 -0.047210693359375 +36243 -0.139801025390625 +36244 0.04736328125 +36245 0.014617919921875 +36246 0.126922607421875 +36247 0.144378662109375 +36248 0.176513671875 +36249 0.221038818359375 +36250 0.20867919921875 +36251 0.27069091796875 +36252 0.223480224609375 +36253 0.294036865234375 +36254 0.231231689453125 +36255 0.311767578125 +36256 0.239715576171875 +36257 0.339141845703125 +36258 0.2412109375 +36259 0.360260009765625 +36260 0.22906494140625 +36261 0.360504150390625 +36262 0.188690185546875 +36263 0.308380126953125 +36264 0.110198974609375 +36265 0.18170166015625 +36266 0.006439208984375 +36267 0.0047607421875 +36268 -0.09869384765625 +36269 -0.17559814453125 +36270 -0.18231201171875 +36271 -0.3143310546875 +36272 -0.2222900390625 +36273 -0.36785888671875 +36274 -0.230743408203125 +36275 -0.36248779296875 +36276 -0.229278564453125 +36277 -0.343536376953125 +36278 -0.213134765625 +36279 -0.3018798828125 +36280 -0.17919921875 +36281 -0.231414794921875 +36282 -0.120452880859375 +36283 -0.117645263671875 +36284 -0.053009033203125 +36285 0.007049560546875 +36286 -0.0040283203125 +36287 0.087982177734375 +36288 0.032867431640625 +36289 0.13946533203125 +36290 0.063201904296875 +36291 0.17425537109375 +36292 0.08416748046875 +36293 0.188201904296875 +36294 0.09002685546875 +36295 0.171234130859375 +36296 0.07763671875 +36297 0.118438720703125 +36298 0.05963134765625 +36299 0.05706787109375 +36300 0.03643798828125 +36301 -0.010711669921875 +36302 0.004364013671875 +36303 -0.0914306640625 +36304 -0.025787353515625 +36305 -0.162322998046875 +36306 -0.04010009765625 +36307 -0.194549560546875 +36308 -0.019622802734375 +36309 -0.1492919921875 +36310 0.038177490234375 +36311 -0.02166748046875 +36312 0.102264404296875 +36313 0.124053955078125 +36314 0.135650634765625 +36315 0.211151123046875 +36316 0.139312744140625 +36317 0.240447998046875 +36318 0.128631591796875 +36319 0.242218017578125 +36320 0.10882568359375 +36321 0.2257080078125 +36322 0.08221435546875 +36323 0.194366455078125 +36324 0.033447265625 +36325 0.115509033203125 +36326 -0.025390625 +36327 0.0128173828125 +36328 -0.06463623046875 +36329 -0.053802490234375 +36330 -0.0968017578125 +36331 -0.110626220703125 +36332 -0.142120361328125 +36333 -0.199493408203125 +36334 -0.187835693359375 +36335 -0.29437255859375 +36336 -0.20330810546875 +36337 -0.33221435546875 +36338 -0.17254638671875 +36339 -0.27972412109375 +36340 -0.1195068359375 +36341 -0.185333251953125 +36342 -0.083251953125 +36343 -0.128204345703125 +36344 -0.067840576171875 +36345 -0.115692138671875 +36346 -0.058502197265625 +36347 -0.116455078125 +36348 -0.0438232421875 +36349 -0.105926513671875 +36350 -0.009613037109375 +36351 -0.053955078125 +36352 0.048004150390625 +36353 0.048797607421875 +36354 0.10699462890625 +36355 0.157318115234375 +36356 0.139068603515625 +36357 0.212005615234375 +36358 0.14642333984375 +36359 0.218475341796875 +36360 0.156463623046875 +36361 0.23724365234375 +36362 0.186126708984375 +36363 0.30535888671875 +36364 0.216644287109375 +36365 0.38128662109375 +36366 0.220703125 +36367 0.404449462890625 +36368 0.20770263671875 +36369 0.3944091796875 +36370 0.195220947265625 +36371 0.3885498046875 +36372 0.172821044921875 +36373 0.362640380859375 +36374 0.121490478515625 +36375 0.27362060546875 +36376 0.03985595703125 +36377 0.11712646484375 +36378 -0.047821044921875 +36379 -0.054901123046875 +36380 -0.117523193359375 +36381 -0.19085693359375 +36382 -0.16656494140625 +36383 -0.28570556640625 +36384 -0.194610595703125 +36385 -0.339263916015625 +36386 -0.21337890625 +36387 -0.3775634765625 +36388 -0.243438720703125 +36389 -0.445709228515625 +36390 -0.281005859375 +36391 -0.535064697265625 +36392 -0.3187255859375 +36393 -0.629058837890625 +36394 -0.34320068359375 +36395 -0.697601318359375 +36396 -0.338104248046875 +36397 -0.70391845703125 +36398 -0.301361083984375 +36399 -0.6424560546875 +36400 -0.223480224609375 +36401 -0.491241455078125 +36402 -0.111968994140625 +36403 -0.265716552734375 +36404 0.00628662109375 +36405 -0.023712158203125 +36406 0.115814208984375 +36407 0.201751708984375 +36408 0.200408935546875 +36409 0.375823974609375 +36410 0.253692626953125 +36411 0.485076904296875 +36412 0.293487548828125 +36413 0.56884765625 +36414 0.323272705078125 +36415 0.634765625 +36416 0.322479248046875 +36417 0.63763427734375 +36418 0.28607177734375 +36419 0.5660400390625 +36420 0.238037109375 +36421 0.4720458984375 +36422 0.202056884765625 +36423 0.40692138671875 +36424 0.181793212890625 +36425 0.3778076171875 +36426 0.174102783203125 +36427 0.376953125 +36428 0.16461181640625 +36429 0.371978759765625 +36430 0.13104248046875 +36431 0.313140869140625 +36432 0.06640625 +36433 0.184417724609375 +36434 -0.017364501953125 +36435 0.011199951171875 +36436 -0.103851318359375 +36437 -0.171051025390625 +36438 -0.181549072265625 +36439 -0.33740234375 +36440 -0.2431640625 +36441 -0.47198486328125 +36442 -0.28216552734375 +36443 -0.560394287109375 +36444 -0.28863525390625 +36445 -0.58056640625 +36446 -0.26959228515625 +36447 -0.54754638671875 +36448 -0.24688720703125 +36449 -0.508575439453125 +36450 -0.2188720703125 +36451 -0.459503173828125 +36452 -0.18316650390625 +36453 -0.394378662109375 +36454 -0.1580810546875 +36455 -0.35260009765625 +36456 -0.133697509765625 +36457 -0.31170654296875 +36458 -0.076446533203125 +36459 -0.197418212890625 +36460 0.014190673828125 +36461 -0.007965087890625 +36462 0.115570068359375 +36463 0.207489013671875 +36464 0.20941162109375 +36465 0.409210205078125 +36466 0.28424072265625 +36467 0.57208251953125 +36468 0.326324462890625 +36469 0.66595458984375 +36470 0.321075439453125 +36471 0.65875244140625 +36472 0.276397705078125 +36473 0.56744384765625 +36474 0.210418701171875 +36475 0.431396484375 +36476 0.143402099609375 +36477 0.29443359375 +36478 0.08740234375 +36479 0.182464599609375 +36480 0.028228759765625 +36481 0.06365966796875 +36482 -0.040252685546875 +36483 -0.075958251953125 +36484 -0.096343994140625 +36485 -0.189422607421875 +36486 -0.13763427734375 +36487 -0.271942138671875 +36488 -0.172607421875 +36489 -0.342529296875 +36490 -0.18426513671875 +36491 -0.364166259765625 +36492 -0.16815185546875 +36493 -0.327239990234375 +36494 -0.1448974609375 +36495 -0.2769775390625 +36496 -0.1329345703125 +36497 -0.253692626953125 +36498 -0.1260986328125 +36499 -0.24365234375 +36500 -0.102447509765625 +36501 -0.1983642578125 +36502 -0.061431884765625 +36503 -0.116241455078125 +36504 -0.021270751953125 +36505 -0.036834716796875 +36506 0.0155029296875 +36507 0.034881591796875 +36508 0.045166015625 +36509 0.09124755859375 +36510 0.056884765625 +36511 0.10888671875 +36512 0.067657470703125 +36513 0.125518798828125 +36514 0.084869384765625 +36515 0.15771484375 +36516 0.095977783203125 +36517 0.17828369140625 +36518 0.09356689453125 +36519 0.17108154296875 +36520 0.0748291015625 +36521 0.129974365234375 +36522 0.05230712890625 +36523 0.082427978515625 +36524 0.025726318359375 +36525 0.027679443359375 +36526 -0.019073486328125 +36527 -0.065643310546875 +36528 -0.064544677734375 +36529 -0.15936279296875 +36530 -0.09210205078125 +36531 -0.21307373046875 +36532 -0.105194091796875 +36533 -0.234649658203125 +36534 -0.092742919921875 +36535 -0.2001953125 +36536 -0.058868408203125 +36537 -0.119171142578125 +36538 -0.0185546875 +36539 -0.024749755859375 +36540 0.029571533203125 +36541 0.085784912109375 +36542 0.069976806640625 +36543 0.178131103515625 +36544 0.08599853515625 +36545 0.215576171875 +36546 0.083770751953125 +36547 0.211456298828125 +36548 0.067596435546875 +36549 0.17523193359375 +36550 0.047393798828125 +36551 0.128753662109375 +36552 0.0367431640625 +36553 0.1019287109375 +36554 0.0262451171875 +36555 0.0743408203125 +36556 0.0145263671875 +36557 0.04327392578125 +36558 0.014862060546875 +36559 0.038177490234375 +36560 0.034942626953125 +36561 0.076263427734375 +36562 0.067108154296875 +36563 0.14105224609375 +36564 0.090179443359375 +36565 0.186431884765625 +36566 0.093292236328125 +36567 0.188812255859375 +36568 0.0721435546875 +36569 0.1390380859375 +36570 0.028839111328125 +36571 0.041778564453125 +36572 -0.025909423828125 +36573 -0.079437255859375 +36574 -0.08978271484375 +36575 -0.219390869140625 +36576 -0.158050537109375 +36577 -0.367828369140625 +36578 -0.217041015625 +36579 -0.494873046875 +36580 -0.246490478515625 +36581 -0.556243896484375 +36582 -0.226593017578125 +36583 -0.508697509765625 +36584 -0.16790771484375 +36585 -0.3756103515625 +36586 -0.09857177734375 +36587 -0.218902587890625 +36588 -0.029937744140625 +36589 -0.063751220703125 +36590 0.038848876953125 +36591 0.091552734375 +36592 0.102874755859375 +36593 0.23602294921875 +36594 0.150115966796875 +36595 0.342987060546875 +36596 0.17279052734375 +36597 0.39520263671875 +36598 0.16943359375 +36599 0.389373779296875 +36600 0.1395263671875 +36601 0.324249267578125 +36602 0.0941162109375 +36603 0.224090576171875 +36604 0.04931640625 +36605 0.124267578125 +36606 0.010650634765625 +36607 0.037078857421875 +36608 -0.0098876953125 +36609 -0.010101318359375 +36610 -0.013153076171875 +36611 -0.019439697265625 +36612 -0.01312255859375 +36613 -0.022796630859375 +36614 -0.002197265625 +36615 -0.001556396484375 +36616 0.024444580078125 +36617 0.056304931640625 +36618 0.047821044921875 +36619 0.106719970703125 +36620 0.04541015625 +36621 0.096893310546875 +36622 0.0238037109375 +36623 0.042694091796875 +36624 -0.00103759765625 +36625 -0.018035888671875 +36626 -0.025146484375 +36627 -0.07586669921875 +36628 -0.043701171875 +36629 -0.11944580078125 +36630 -0.06134033203125 +36631 -0.15972900390625 +36632 -0.080474853515625 +36633 -0.202606201171875 +36634 -0.1011962890625 +36635 -0.24859619140625 +36636 -0.126617431640625 +36637 -0.30517578125 +36638 -0.152313232421875 +36639 -0.36212158203125 +36640 -0.16632080078125 +36641 -0.39141845703125 +36642 -0.15252685546875 +36643 -0.35528564453125 +36644 -0.1092529296875 +36645 -0.249969482421875 +36646 -0.043792724609375 +36647 -0.092864990234375 +36648 0.032470703125 +36649 0.08905029296875 +36650 0.093902587890625 +36651 0.2352294921875 +36652 0.129150390625 +36653 0.318817138671875 +36654 0.14617919921875 +36655 0.358642578125 +36656 0.14202880859375 +36657 0.347747802734375 +36658 0.116424560546875 +36659 0.28564453125 +36660 0.090911865234375 +36661 0.223175048828125 +36662 0.080841064453125 +36663 0.196746826171875 +36664 0.074920654296875 +36665 0.179840087890625 +36666 0.06591796875 +36667 0.155548095703125 +36668 0.065338134765625 +36669 0.151214599609375 +36670 0.068939208984375 +36671 0.156951904296875 +36672 0.05926513671875 +36673 0.13177490234375 +36674 0.046905517578125 +36675 0.100799560546875 +36676 0.0416259765625 +36677 0.087127685546875 +36678 0.0281982421875 +36679 0.05487060546875 +36680 0.001068115234375 +36681 -0.009002685546875 +36682 -0.03948974609375 +36683 -0.10400390625 +36684 -0.093170166015625 +36685 -0.229400634765625 +36686 -0.1473388671875 +36687 -0.35552978515625 +36688 -0.184783935546875 +36689 -0.441925048828125 +36690 -0.199249267578125 +36691 -0.473846435546875 +36692 -0.1964111328125 +36693 -0.464813232421875 +36694 -0.178009033203125 +36695 -0.419097900390625 +36696 -0.142974853515625 +36697 -0.334320068359375 +36698 -0.098663330078125 +36699 -0.227935791015625 +36700 -0.055023193359375 +36701 -0.12347412109375 +36702 -0.014862060546875 +36703 -0.02764892578125 +36704 0.029541015625 +36705 0.077667236328125 +36706 0.08697509765625 +36707 0.2132568359375 +36708 0.16156005859375 +36709 0.38885498046875 +36710 0.24407958984375 +36711 0.582794189453125 +36712 0.30865478515625 +36713 0.734039306640625 +36714 0.337249755859375 +36715 0.800140380859375 +36716 0.328643798828125 +36717 0.7783203125 +36718 0.2813720703125 +36719 0.6651611328125 +36720 0.194976806640625 +36721 0.45965576171875 +36722 0.08526611328125 +36723 0.199188232421875 +36724 -0.019989013671875 +36725 -0.050689697265625 +36726 -0.096649169921875 +36727 -0.23297119140625 +36728 -0.1373291015625 +36729 -0.33013916015625 +36730 -0.1531982421875 +36731 -0.368408203125 +36732 -0.157440185546875 +36733 -0.378936767578125 +36734 -0.15655517578125 +36735 -0.376983642578125 +36736 -0.1578369140625 +36737 -0.37969970703125 +36738 -0.16314697265625 +36739 -0.391510009765625 +36740 -0.160980224609375 +36741 -0.385345458984375 +36742 -0.143096923828125 +36743 -0.3419189453125 +36744 -0.118682861328125 +36745 -0.28289794921875 +36746 -0.1060791015625 +36747 -0.251617431640625 +36748 -0.112884521484375 +36749 -0.266143798828125 +36750 -0.116546630859375 +36751 -0.273345947265625 +36752 -0.093109130859375 +36753 -0.216796875 +36754 -0.055999755859375 +36755 -0.128265380859375 +36756 -0.03082275390625 +36757 -0.068145751953125 +36758 -0.0203857421875 +36759 -0.0430908203125 +36760 -0.01251220703125 +36761 -0.024444580078125 +36762 0.006744384765625 +36763 0.020721435546875 +36764 0.050933837890625 +36765 0.124481201171875 +36766 0.1077880859375 +36767 0.25787353515625 +36768 0.159576416015625 +36769 0.379119873046875 +36770 0.2027587890625 +36771 0.47991943359375 +36772 0.22369384765625 +36773 0.5281982421875 +36774 0.2169189453125 +36775 0.511138916015625 +36776 0.194061279296875 +36777 0.456207275390625 +36778 0.17376708984375 +36779 0.407470703125 +36780 0.16400146484375 +36781 0.383758544921875 +36782 0.152801513671875 +36783 0.35687255859375 +36784 0.1337890625 +36785 0.31182861328125 +36786 0.107940673828125 +36787 0.250885009765625 +36788 0.071624755859375 +36789 0.1654052734375 +36790 0.016265869140625 +36791 0.035247802734375 +36792 -0.059112548828125 +36793 -0.142059326171875 +36794 -0.141448974609375 +36795 -0.33563232421875 +36796 -0.226043701171875 +36797 -0.5345458984375 +36798 -0.30572509765625 +36799 -0.72186279296875 +36800 -0.3546142578125 +36801 -0.836669921875 +36802 -0.353118896484375 +36803 -0.8326416015625 +36804 -0.309600830078125 +36805 -0.7296142578125 +36806 -0.247406005859375 +36807 -0.582550048828125 +36808 -0.1871337890625 +36809 -0.440093994140625 +36810 -0.13812255859375 +36811 -0.324310302734375 +36812 -0.0860595703125 +36813 -0.20147705078125 +36814 -0.01953125 +36815 -0.044647216796875 +36816 0.0435791015625 +36817 0.103973388671875 +36818 0.085418701171875 +36819 0.202392578125 +36820 0.11187744140625 +36821 0.264495849609375 +36822 0.1435546875 +36823 0.338897705078125 +36824 0.18817138671875 +36825 0.443817138671875 +36826 0.231231689453125 +36827 0.545074462890625 +36828 0.261962890625 +36829 0.6173095703125 +36830 0.2769775390625 +36831 0.6524658203125 +36832 0.28167724609375 +36833 0.66339111328125 +36834 0.27862548828125 +36835 0.6561279296875 +36836 0.2576904296875 +36837 0.606781005859375 +36838 0.212860107421875 +36839 0.501190185546875 +36840 0.14984130859375 +36841 0.352783203125 +36842 0.07501220703125 +36843 0.176544189453125 +36844 -0.014678955078125 +36845 -0.034820556640625 +36846 -0.10943603515625 +36847 -0.258209228515625 +36848 -0.18756103515625 +36849 -0.44244384765625 +36850 -0.243865966796875 +36851 -0.5753173828125 +36852 -0.2763671875 +36853 -0.65203857421875 +36854 -0.271942138671875 +36855 -0.641632080078125 +36856 -0.23822021484375 +36857 -0.562164306640625 +36858 -0.194061279296875 +36859 -0.458038330078125 +36860 -0.148468017578125 +36861 -0.350555419921875 +36862 -0.110260009765625 +36863 -0.260528564453125 +36864 -0.081024169921875 +36865 -0.192108154296875 +36866 -0.059295654296875 +36867 -0.141937255859375 +36868 -0.042022705078125 +36869 -0.1021728515625 +36870 -0.025115966796875 +36871 -0.062896728515625 +36872 -0.00372314453125 +36873 -0.011932373046875 +36874 0.026947021484375 +36875 0.062835693359375 +36876 0.06195068359375 +36877 0.148712158203125 +36878 0.099700927734375 +36879 0.241729736328125 +36880 0.1429443359375 +36881 0.34912109375 +36882 0.186309814453125 +36883 0.457305908203125 +36884 0.220947265625 +36885 0.54388427734375 +36886 0.23272705078125 +36887 0.5728759765625 +36888 0.206787109375 +36889 0.506591796875 +36890 0.14556884765625 +36891 0.351226806640625 +36892 0.06463623046875 +36893 0.146514892578125 +36894 -0.01544189453125 +36895 -0.05523681640625 +36896 -0.079833984375 +36897 -0.21624755859375 +36898 -0.1278076171875 +36899 -0.334930419921875 +36900 -0.156036376953125 +36901 -0.402984619140625 +36902 -0.172637939453125 +36903 -0.4412841796875 +36904 -0.195556640625 +36905 -0.49578857421875 +36906 -0.22222900390625 +36907 -0.5601806640625 +36908 -0.2393798828125 +36909 -0.600738525390625 +36910 -0.233917236328125 +36911 -0.584228515625 +36912 -0.1934814453125 +36913 -0.47930908203125 +36914 -0.115478515625 +36915 -0.27935791015625 +36916 -0.009490966796875 +36917 -0.0089111328125 +36918 0.09967041015625 +36919 0.268798828125 +36920 0.18414306640625 +36921 0.482818603515625 +36922 0.23236083984375 +36923 0.60369873046875 +36924 0.251708984375 +36925 0.650421142578125 +36926 0.258209228515625 +36927 0.66400146484375 +36928 0.250640869140625 +36929 0.6414794921875 +36930 0.224884033203125 +36931 0.572540283203125 +36932 0.196929931640625 +36933 0.498138427734375 +36934 0.175018310546875 +36935 0.439453125 +36936 0.15087890625 +36937 0.375518798828125 +36938 0.11199951171875 +36939 0.274505615234375 +36940 0.0474853515625 +36941 0.1087646484375 +36942 -0.033935546875 +36943 -0.099395751953125 +36944 -0.11981201171875 +36945 -0.3182373046875 +36946 -0.210601806640625 +36947 -0.5489501953125 +36948 -0.299285888671875 +36949 -0.7738037109375 +36950 -0.365081787109375 +36951 -0.86383056640625 +36952 -0.394927978515625 +36953 -0.870391845703125 +36954 -0.395721435546875 +36955 -0.86895751953125 +36956 -0.37255859375 +36957 -0.861053466796875 +36958 -0.318603515625 +36959 -0.765869140625 +36960 -0.229400634765625 +36961 -0.5301513671875 +36962 -0.107666015625 +36963 -0.214691162109375 +36964 0.029754638671875 +36965 0.137359619140625 +36966 0.162750244140625 +36967 0.474822998046875 +36968 0.277435302734375 +36969 0.76239013671875 +36970 0.36322021484375 +36971 0.867462158203125 +36972 0.420318603515625 +36973 0.870361328125 +36974 0.44415283203125 +36975 0.86480712890625 +36976 0.436798095703125 +36977 0.831817626953125 +36978 0.40777587890625 +36979 0.677581787109375 +36980 0.35931396484375 +36981 0.495880126953125 +36982 0.29864501953125 +36983 0.30767822265625 +36984 0.22662353515625 +36985 0.116180419921875 +36986 0.130767822265625 +36987 -0.110748291015625 +36988 0.008331298828125 +36989 -0.381805419921875 +36990 -0.123931884765625 +36991 -0.6572265625 +36992 -0.242584228515625 +36993 -0.857421875 +36994 -0.330810546875 +36995 -0.870391845703125 +36996 -0.385833740234375 +36997 -0.870391845703125 +36998 -0.418182373046875 +36999 -0.86444091796875 +37000 -0.441864013671875 +37001 -0.85723876953125 +37002 -0.449676513671875 +37003 -0.790008544921875 +37004 -0.420318603515625 +37005 -0.62847900390625 +37006 -0.352508544921875 +37007 -0.3956298828125 +37008 -0.25909423828125 +37009 -0.126708984375 +37010 -0.150787353515625 +37011 0.150115966796875 +37012 -0.03216552734375 +37013 0.424041748046875 +37014 0.086212158203125 +37015 0.670623779296875 +37016 0.189178466796875 +37017 0.854522705078125 +37018 0.26983642578125 +37019 0.866485595703125 +37020 0.32220458984375 +37021 0.86920166015625 +37022 0.3533935546875 +37023 0.8653564453125 +37024 0.36865234375 +37025 0.857147216796875 +37026 0.366851806640625 +37027 0.766845703125 +37028 0.3499755859375 +37029 0.628509521484375 +37030 0.31536865234375 +37031 0.462127685546875 +37032 0.27313232421875 +37033 0.297210693359375 +37034 0.228118896484375 +37035 0.14862060546875 +37036 0.171356201171875 +37037 -0.00537109375 +37038 0.105712890625 +37039 -0.15753173828125 +37040 0.02978515625 +37041 -0.31304931640625 +37042 -0.061920166015625 +37043 -0.48876953125 +37044 -0.151031494140625 +37045 -0.6416015625 +37046 -0.227874755859375 +37047 -0.751373291015625 +37048 -0.301513671875 +37049 -0.84619140625 +37050 -0.366180419921875 +37051 -0.861297607421875 +37052 -0.408843994140625 +37053 -0.863250732421875 +37054 -0.4171142578125 +37055 -0.856597900390625 +37056 -0.395751953125 +37057 -0.7498779296875 +37058 -0.367431640625 +37059 -0.624542236328125 +37060 -0.32354736328125 +37061 -0.47808837890625 +37062 -0.24114990234375 +37063 -0.253387451171875 +37064 -0.13812255859375 +37065 0.003692626953125 +37066 -0.041259765625 +37067 0.2257080078125 +37068 0.0543212890625 +37069 0.427154541015625 +37070 0.16131591796875 +37071 0.643218994140625 +37072 0.27593994140625 +37073 0.855926513671875 +37074 0.375457763671875 +37075 0.870361328125 +37076 0.440399169921875 +37077 0.870361328125 +37078 0.473602294921875 +37079 0.862762451171875 +37080 0.473907470703125 +37081 0.79669189453125 +37082 0.437591552734375 +37083 0.595794677734375 +37084 0.376129150390625 +37085 0.362152099609375 +37086 0.300506591796875 +37087 0.1270751953125 +37088 0.218994140625 +37089 -0.086944580078125 +37090 0.132415771484375 +37091 -0.2784423828125 +37092 0.02716064453125 +37093 -0.484832763671875 +37094 -0.104248046875 +37095 -0.729583740234375 +37096 -0.241943359375 +37097 -0.86688232421875 +37098 -0.361114501953125 +37099 -0.870391845703125 +37100 -0.459747314453125 +37101 -0.86859130859375 +37102 -0.537017822265625 +37103 -0.86279296875 +37104 -0.578765869140625 +37105 -0.817962646484375 +37106 -0.567169189453125 +37107 -0.6116943359375 +37108 -0.49945068359375 +37109 -0.3128662109375 +37110 -0.3887939453125 +37111 0.039398193359375 +37112 -0.243072509765625 +37113 0.422821044921875 +37114 -0.075347900390625 +37115 0.805145263671875 +37116 0.087615966796875 +37117 0.870361328125 +37118 0.223419189453125 +37119 0.870361328125 +37120 0.327178955078125 +37121 0.860015869140625 +37122 0.396270751953125 +37123 0.727935791015625 +37124 0.428741455078125 +37125 0.48114013671875 +37126 0.43328857421875 +37127 0.2059326171875 +37128 0.41815185546875 +37129 -0.06103515625 +37130 0.387054443359375 +37131 -0.29913330078125 +37132 0.335052490234375 +37133 -0.516204833984375 +37134 0.256927490234375 +37135 -0.7252197265625 +37136 0.16204833984375 +37137 -0.85980224609375 +37138 0.063232421875 +37139 -0.870391845703125 +37140 -0.0283203125 +37141 -0.870391845703125 +37142 -0.094573974609375 +37143 -0.858062744140625 +37144 -0.13348388671875 +37145 -0.673004150390625 +37146 -0.163421630859375 +37147 -0.42694091796875 +37148 -0.19989013671875 +37149 -0.2100830078125 +37150 -0.241729736328125 +37151 -0.0362548828125 +37152 -0.278167724609375 +37153 0.10943603515625 +37154 -0.3018798828125 +37155 0.23516845703125 +37156 -0.297882080078125 +37157 0.373687744140625 +37158 -0.2669677734375 +37159 0.517791748046875 +37160 -0.23199462890625 +37161 0.602783203125 +37162 -0.191375732421875 +37163 0.635711669921875 +37164 -0.133514404296875 +37165 0.655181884765625 +37166 -0.062408447265625 +37167 0.65948486328125 +37168 0.018524169921875 +37169 0.651275634765625 +37170 0.099945068359375 +37171 0.61846923828125 +37172 0.16802978515625 +37173 0.53753662109375 +37174 0.2158203125 +37175 0.404144287109375 +37176 0.239410400390625 +37177 0.22186279296875 +37178 0.23895263671875 +37179 0.003997802734375 +37180 0.220733642578125 +37181 -0.22100830078125 +37182 0.19207763671875 +37183 -0.42449951171875 +37184 0.160675048828125 +37185 -0.579833984375 +37186 0.141998291015625 +37187 -0.641876220703125 +37188 0.133880615234375 +37189 -0.6177978515625 +37190 0.113372802734375 +37191 -0.575531005859375 +37192 0.078887939453125 +37193 -0.526336669921875 +37194 0.049530029296875 +37195 -0.42645263671875 +37196 0.03558349609375 +37197 -0.2581787109375 +37198 0.0244140625 +37199 -0.068695068359375 +37200 0.0025634765625 +37201 0.09222412109375 +37202 -0.022857666015625 +37203 0.232147216796875 +37204 -0.047882080078125 +37205 0.3509521484375 +37206 -0.082916259765625 +37207 0.410064697265625 +37208 -0.138397216796875 +37209 0.372955322265625 +37210 -0.206695556640625 +37211 0.2554931640625 +37212 -0.269073486328125 +37213 0.10711669921875 +37214 -0.31854248046875 +37215 -0.052886962890625 +37216 -0.34228515625 +37217 -0.186279296875 +37218 -0.320465087890625 +37219 -0.23291015625 +37220 -0.2615966796875 +37221 -0.209442138671875 +37222 -0.18975830078125 +37223 -0.174163818359375 +37224 -0.108306884765625 +37225 -0.126739501953125 +37226 -0.014068603515625 +37227 -0.048126220703125 +37228 0.082427978515625 +37229 0.0426025390625 +37230 0.16412353515625 +37231 0.10748291015625 +37232 0.22601318359375 +37233 0.1409912109375 +37234 0.285003662109375 +37235 0.19708251953125 +37236 0.33856201171875 +37237 0.273651123046875 +37238 0.3665771484375 +37239 0.31768798828125 +37240 0.373077392578125 +37241 0.341094970703125 +37242 0.367279052734375 +37243 0.368011474609375 +37244 0.341064453125 +37245 0.37249755859375 +37246 0.276885986328125 +37247 0.30072021484375 +37248 0.17681884765625 +37249 0.1517333984375 +37250 0.06512451171875 +37251 -0.01470947265625 +37252 -0.051483154296875 +37253 -0.1883544921875 +37254 -0.171234130859375 +37255 -0.372711181640625 +37256 -0.27191162109375 +37257 -0.51397705078125 +37258 -0.336334228515625 +37259 -0.57177734375 +37260 -0.35992431640625 +37261 -0.53948974609375 +37262 -0.347503662109375 +37263 -0.43511962890625 +37264 -0.311553955078125 +37265 -0.2962646484375 +37266 -0.265350341796875 +37267 -0.161102294921875 +37268 -0.214080810546875 +37269 -0.0435791015625 +37270 -0.1571044921875 +37271 0.060394287109375 +37272 -0.10089111328125 +37273 0.13665771484375 +37274 -0.052703857421875 +37275 0.170135498046875 +37276 -0.013031005859375 +37277 0.16552734375 +37278 0.028106689453125 +37279 0.15728759765625 +37280 0.070159912109375 +37281 0.150787353515625 +37282 0.10205078125 +37283 0.12200927734375 +37284 0.124847412109375 +37285 0.080108642578125 +37286 0.146026611328125 +37287 0.05126953125 +37288 0.173919677734375 +37289 0.062896728515625 +37290 0.199432373046875 +37291 0.09271240234375 +37292 0.204864501953125 +37293 0.092987060546875 +37294 0.19549560546875 +37295 0.07855224609375 +37296 0.17718505859375 +37297 0.06427001953125 +37298 0.1453857421875 +37299 0.0347900390625 +37300 0.100799560546875 +37301 -0.01171875 +37302 0.05206298828125 +37303 -0.056060791015625 +37304 0.0164794921875 +37305 -0.055511474609375 +37306 -0.003997802734375 +37307 -0.010467529296875 +37308 -0.02679443359375 +37309 0.02508544921875 +37310 -0.059173583984375 +37311 0.025665283203125 +37312 -0.090057373046875 +37313 0.017333984375 +37314 -0.117431640625 +37315 0.00189208984375 +37316 -0.144256591796875 +37317 -0.03173828125 +37318 -0.165618896484375 +37319 -0.071502685546875 +37320 -0.187835693359375 +37321 -0.13543701171875 +37322 -0.20989990234375 +37323 -0.219970703125 +37324 -0.223602294921875 +37325 -0.300506591796875 +37326 -0.229736328125 +37327 -0.376312255859375 +37328 -0.21832275390625 +37329 -0.416107177734375 +37330 -0.173370361328125 +37331 -0.371124267578125 +37332 -0.09686279296875 +37333 -0.242279052734375 +37334 -0.00494384765625 +37335 -0.069732666015625 +37336 0.09320068359375 +37337 0.125640869140625 +37338 0.1849365234375 +37339 0.31268310546875 +37340 0.25592041015625 +37341 0.45501708984375 +37342 0.30596923828125 +37343 0.554779052734375 +37344 0.334014892578125 +37345 0.61065673828125 +37346 0.335601806640625 +37347 0.610931396484375 +37348 0.302154541015625 +37349 0.531463623046875 +37350 0.2398681640625 +37351 0.3883056640625 +37352 0.168670654296875 +37353 0.23468017578125 +37354 0.098480224609375 +37355 0.095245361328125 +37356 0.039825439453125 +37357 -0.00396728515625 +37358 -0.000732421875 +37359 -0.04852294921875 +37360 -0.027801513671875 +37361 -0.055145263671875 +37362 -0.05877685546875 +37363 -0.0758056640625 +37364 -0.1025390625 +37365 -0.138702392578125 +37366 -0.145538330078125 +37367 -0.209197998046875 +37368 -0.18756103515625 +37369 -0.289031982421875 +37370 -0.228240966796875 +37371 -0.37884521484375 +37372 -0.259185791015625 +37373 -0.456329345703125 +37374 -0.278594970703125 +37375 -0.51641845703125 +37376 -0.272552490234375 +37377 -0.519287109375 +37378 -0.23919677734375 +37379 -0.458251953125 +37380 -0.19744873046875 +37381 -0.384796142578125 +37382 -0.156951904296875 +37383 -0.323699951171875 +37384 -0.116851806640625 +37385 -0.269287109375 +37386 -0.06915283203125 +37387 -0.1951904296875 +37388 -0.014617919921875 +37389 -0.100006103515625 +37390 0.03619384765625 +37391 -0.01055908203125 +37392 0.092864990234375 +37393 0.1033935546875 +37394 0.15704345703125 +37395 0.24908447265625 +37396 0.20947265625 +37397 0.373199462890625 +37398 0.243621826171875 +37399 0.45806884765625 +37400 0.2620849609375 +37401 0.511474609375 +37402 0.276214599609375 +37403 0.565399169921875 +37404 0.283416748046875 +37405 0.61138916015625 +37406 0.263397216796875 +37407 0.5897216796875 +37408 0.213531494140625 +37409 0.4906005859375 +37410 0.140838623046875 +37411 0.33148193359375 +37412 0.058685302734375 +37413 0.147796630859375 +37414 -0.017333984375 +37415 -0.01873779296875 +37416 -0.07647705078125 +37417 -0.140289306640625 +37418 -0.10919189453125 +37419 -0.191986083984375 +37420 -0.118408203125 +37421 -0.184295654296875 +37422 -0.119140625 +37423 -0.161834716796875 +37424 -0.125732421875 +37425 -0.166595458984375 +37426 -0.136383056640625 +37427 -0.19390869140625 +37428 -0.144378662109375 +37429 -0.22442626953125 +37430 -0.15753173828125 +37431 -0.279754638671875 +37432 -0.1689453125 +37433 -0.3389892578125 +37434 -0.162506103515625 +37435 -0.3543701171875 +37436 -0.146728515625 +37437 -0.348175048828125 +37438 -0.124359130859375 +37439 -0.32598876953125 +37440 -0.085845947265625 +37441 -0.2581787109375 +37442 -0.030303955078125 +37443 -0.139801025390625 +37444 0.03643798828125 +37445 0.014617919921875 +37446 0.09246826171875 +37447 0.144378662109375 +37448 0.1273193359375 +37449 0.221038818359375 +37450 0.149749755859375 +37451 0.27069091796875 +37452 0.159820556640625 +37453 0.294036865234375 +37454 0.164764404296875 +37455 0.311767578125 +37456 0.170013427734375 +37457 0.339141845703125 +37458 0.1700439453125 +37459 0.360260009765625 +37460 0.16033935546875 +37461 0.360504150390625 +37462 0.131256103515625 +37463 0.308380126953125 +37464 0.076263427734375 +37465 0.18170166015625 +37466 0.00421142578125 +37467 0.0047607421875 +37468 -0.068695068359375 +37469 -0.17559814453125 +37470 -0.126922607421875 +37471 -0.3143310546875 +37472 -0.155487060546875 +37473 -0.36785888671875 +37474 -0.1624755859375 +37475 -0.36248779296875 +37476 -0.162322998046875 +37477 -0.343536376953125 +37478 -0.15179443359375 +37479 -0.3018798828125 +37480 -0.1287841796875 +37481 -0.231414794921875 +37482 -0.088653564453125 +37483 -0.117645263671875 +37484 -0.042266845703125 +37485 0.007049560546875 +37486 -0.0079345703125 +37487 0.087982177734375 +37488 0.018524169921875 +37489 0.13946533203125 +37490 0.04071044921875 +37491 0.17425537109375 +37492 0.056671142578125 +37493 0.188201904296875 +37494 0.06243896484375 +37495 0.171234130859375 +37496 0.0557861328125 +37497 0.118438720703125 +37498 0.045135498046875 +37499 0.05706787109375 +37500 0.030670166015625 +37501 -0.010711669921875 +37502 0.0098876953125 +37503 -0.0914306640625 +37504 -0.010009765625 +37505 -0.162322998046875 +37506 -0.019683837890625 +37507 -0.194549560546875 +37508 -0.00634765625 +37509 -0.1492919921875 +37510 0.031707763671875 +37511 -0.02166748046875 +37512 0.07366943359375 +37513 0.124053955078125 +37514 0.094757080078125 +37515 0.211151123046875 +37516 0.095703125 +37517 0.240447998046875 +37518 0.0869140625 +37519 0.242218017578125 +37520 0.072021484375 +37521 0.2257080078125 +37522 0.052642822265625 +37523 0.194366455078125 +37524 0.0185546875 +37525 0.115509033203125 +37526 -0.02203369140625 +37527 0.0128173828125 +37528 -0.04913330078125 +37529 -0.053802490234375 +37530 -0.07110595703125 +37531 -0.110626220703125 +37532 -0.101593017578125 +37533 -0.199493408203125 +37534 -0.13201904296875 +37535 -0.29437255859375 +37536 -0.14178466796875 +37537 -0.33221435546875 +37538 -0.120208740234375 +37539 -0.27972412109375 +37540 -0.08343505859375 +37541 -0.185333251953125 +37542 -0.05780029296875 +37543 -0.128204345703125 +37544 -0.046112060546875 +37545 -0.115692138671875 +37546 -0.038543701171875 +37547 -0.116455078125 +37548 -0.0274658203125 +37549 -0.105926513671875 +37550 -0.003387451171875 +37551 -0.053955078125 +37552 0.036346435546875 +37553 0.048797607421875 +37554 0.076690673828125 +37555 0.157318115234375 +37556 0.097869873046875 +37557 0.212005615234375 +37558 0.101593017578125 +37559 0.218475341796875 +37560 0.107696533203125 +37561 0.23724365234375 +37562 0.12835693359375 +37563 0.30535888671875 +37564 0.15008544921875 +37565 0.38128662109375 +37566 0.1531982421875 +37567 0.404449462890625 +37568 0.144439697265625 +37569 0.3944091796875 +37570 0.1363525390625 +37571 0.3885498046875 +37572 0.12139892578125 +37573 0.362640380859375 +37574 0.0858154296875 +37575 0.27362060546875 +37576 0.02850341796875 +37577 0.11712646484375 +37578 -0.033172607421875 +37579 -0.054901123046875 +37580 -0.082000732421875 +37581 -0.19085693359375 +37582 -0.11614990234375 +37583 -0.28570556640625 +37584 -0.13543701171875 +37585 -0.339263916015625 +37586 -0.148345947265625 +37587 -0.3775634765625 +37588 -0.169677734375 +37589 -0.445709228515625 +37590 -0.196685791015625 +37591 -0.535064697265625 +37592 -0.224090576171875 +37593 -0.629058837890625 +37594 -0.24224853515625 +37595 -0.697601318359375 +37596 -0.239349365234375 +37597 -0.70391845703125 +37598 -0.2138671875 +37599 -0.6424560546875 +37600 -0.158905029296875 +37601 -0.491241455078125 +37602 -0.079803466796875 +37603 -0.265716552734375 +37604 0.004119873046875 +37605 -0.023712158203125 +37606 0.081817626953125 +37607 0.201751708984375 +37608 0.141693115234375 +37609 0.375823974609375 +37610 0.179229736328125 +37611 0.485076904296875 +37612 0.207244873046875 +37613 0.56884765625 +37614 0.228271484375 +37615 0.634765625 +37616 0.227569580078125 +37617 0.63763427734375 +37618 0.201507568359375 +37619 0.5660400390625 +37620 0.16729736328125 +37621 0.4720458984375 +37622 0.1419677734375 +37623 0.40692138671875 +37624 0.12811279296875 +37625 0.3778076171875 +37626 0.1234130859375 +37627 0.376953125 +37628 0.11749267578125 +37629 0.371978759765625 +37630 0.09423828125 +37631 0.313140869140625 +37632 0.048828125 +37633 0.184417724609375 +37634 -0.009918212890625 +37635 0.011199951171875 +37636 -0.07049560546875 +37637 -0.171051025390625 +37638 -0.1251220703125 +37639 -0.33740234375 +37640 -0.168792724609375 +37641 -0.47198486328125 +37642 -0.19708251953125 +37643 -0.560394287109375 +37644 -0.203369140625 +37645 -0.58056640625 +37646 -0.192138671875 +37647 -0.54754638671875 +37648 -0.177490234375 +37649 -0.508575439453125 +37650 -0.158416748046875 +37651 -0.459503173828125 +37652 -0.133453369140625 +37653 -0.394378662109375 +37654 -0.114593505859375 +37655 -0.35260009765625 +37656 -0.0955810546875 +37657 -0.31170654296875 +37658 -0.0548095703125 +37659 -0.197418212890625 +37660 0.007843017578125 +37661 -0.007965087890625 +37662 0.077423095703125 +37663 0.207489013671875 +37664 0.141876220703125 +37665 0.409210205078125 +37666 0.193572998046875 +37667 0.57208251953125 +37668 0.223419189453125 +37669 0.66595458984375 +37670 0.22186279296875 +37671 0.65875244140625 +37672 0.193939208984375 +37673 0.56744384765625 +37674 0.1513671875 +37675 0.431396484375 +37676 0.1072998046875 +37677 0.29443359375 +37678 0.069610595703125 +37679 0.182464599609375 +37680 0.0291748046875 +37681 0.06365966796875 +37682 -0.017791748046875 +37683 -0.075958251953125 +37684 -0.057098388671875 +37685 -0.189422607421875 +37686 -0.087005615234375 +37687 -0.271942138671875 +37688 -0.112823486328125 +37689 -0.342529296875 +37690 -0.123382568359375 +37691 -0.364166259765625 +37692 -0.115631103515625 +37693 -0.327239990234375 +37694 -0.102813720703125 +37695 -0.2769775390625 +37696 -0.096771240234375 +37697 -0.253692626953125 +37698 -0.09344482421875 +37699 -0.24365234375 +37700 -0.0784912109375 +37701 -0.1983642578125 +37702 -0.051605224609375 +37703 -0.116241455078125 +37704 -0.02459716796875 +37705 -0.036834716796875 +37706 0.00079345703125 +37707 0.034881591796875 +37708 0.02203369140625 +37709 0.09124755859375 +37710 0.031982421875 +37711 0.10888671875 +37712 0.04150390625 +37713 0.125518798828125 +37714 0.055267333984375 +37715 0.15771484375 +37716 0.06500244140625 +37717 0.17828369140625 +37718 0.06573486328125 +37719 0.17108154296875 +37720 0.0555419921875 +37721 0.129974365234375 +37722 0.042449951171875 +37723 0.082427978515625 +37724 0.026214599609375 +37725 0.027679443359375 +37726 -0.00238037109375 +37727 -0.065643310546875 +37728 -0.031951904296875 +37729 -0.15936279296875 +37730 -0.0504150390625 +37731 -0.21307373046875 +37732 -0.059967041015625 +37733 -0.234649658203125 +37734 -0.0533447265625 +37735 -0.2001953125 +37736 -0.03314208984375 +37737 -0.119171142578125 +37738 -0.00897216796875 +37739 -0.024749755859375 +37740 0.0201416015625 +37741 0.085784912109375 +37742 0.04425048828125 +37743 0.178131103515625 +37744 0.052642822265625 +37745 0.215576171875 +37746 0.049407958984375 +37747 0.211456298828125 +37748 0.0374755859375 +37749 0.17523193359375 +37750 0.023345947265625 +37751 0.128753662109375 +37752 0.015869140625 +37753 0.1019287109375 +37754 0.00897216796875 +37755 0.0743408203125 +37756 0.001739501953125 +37757 0.04327392578125 +37758 0.002716064453125 +37759 0.038177490234375 +37760 0.016876220703125 +37761 0.076263427734375 +37762 0.039154052734375 +37763 0.14105224609375 +37764 0.05572509765625 +37765 0.186431884765625 +37766 0.0594482421875 +37767 0.188812255859375 +37768 0.047454833984375 +37769 0.1390380859375 +37770 0.02099609375 +37771 0.041778564453125 +37772 -0.0130615234375 +37773 -0.079437255859375 +37774 -0.053253173828125 +37775 -0.219390869140625 +37776 -0.0965576171875 +37777 -0.367828369140625 +37778 -0.134185791015625 +37779 -0.494873046875 +37780 -0.15301513671875 +37781 -0.556243896484375 +37782 -0.14019775390625 +37783 -0.508697509765625 +37784 -0.102569580078125 +37785 -0.3756103515625 +37786 -0.058349609375 +37787 -0.218902587890625 +37788 -0.014862060546875 +37789 -0.063751220703125 +37790 0.028472900390625 +37791 0.091552734375 +37792 0.068603515625 +37793 0.23602294921875 +37794 0.097747802734375 +37795 0.342987060546875 +37796 0.1109619140625 +37797 0.39520263671875 +37798 0.107391357421875 +37799 0.389373779296875 +37800 0.08673095703125 +37801 0.324249267578125 +37802 0.0562744140625 +37803 0.224090576171875 +37804 0.0264892578125 +37805 0.124267578125 +37806 0.001007080078125 +37807 0.037078857421875 +37808 -0.0120849609375 +37809 -0.010101318359375 +37810 -0.01348876953125 +37811 -0.019439697265625 +37812 -0.012725830078125 +37813 -0.022796630859375 +37814 -0.004364013671875 +37815 -0.001556396484375 +37816 0.014984130859375 +37817 0.056304931640625 +37818 0.032135009765625 +37819 0.106719970703125 +37820 0.031341552734375 +37821 0.096893310546875 +37822 0.017242431640625 +37823 0.042694091796875 +37824 0.000885009765625 +37825 -0.018035888671875 +37826 -0.01495361328125 +37827 -0.07586669921875 +37828 -0.027008056640625 +37829 -0.11944580078125 +37830 -0.038543701171875 +37831 -0.15972900390625 +37832 -0.05133056640625 +37833 -0.202606201171875 +37834 -0.065460205078125 +37835 -0.24859619140625 +37836 -0.083099365234375 +37837 -0.30517578125 +37838 -0.1011962890625 +37839 -0.36212158203125 +37840 -0.11138916015625 +37841 -0.39141845703125 +37842 -0.102386474609375 +37843 -0.35528564453125 +37844 -0.072998046875 +37845 -0.249969482421875 +37846 -0.028289794921875 +37847 -0.092864990234375 +37848 0.02386474609375 +37849 0.08905029296875 +37850 0.06561279296875 +37851 0.2352294921875 +37852 0.089080810546875 +37853 0.318817138671875 +37854 0.099945068359375 +37855 0.358642578125 +37856 0.096160888671875 +37857 0.347747802734375 +37858 0.077606201171875 +37859 0.28564453125 +37860 0.059326171875 +37861 0.223175048828125 +37862 0.05206298828125 +37863 0.196746826171875 +37864 0.047943115234375 +37865 0.179840087890625 +37866 0.041900634765625 +37867 0.155548095703125 +37868 0.041961669921875 +37869 0.151214599609375 +37870 0.045135498046875 +37871 0.156951904296875 +37872 0.0391845703125 +37873 0.13177490234375 +37874 0.031463623046875 +37875 0.100799560546875 +37876 0.028717041015625 +37877 0.087127685546875 +37878 0.020263671875 +37879 0.05487060546875 +37880 0.002197265625 +37881 -0.009002685546875 +37882 -0.025360107421875 +37883 -0.10400390625 +37884 -0.06219482421875 +37885 -0.229400634765625 +37886 -0.099517822265625 +37887 -0.35552978515625 +37888 -0.12518310546875 +37889 -0.441925048828125 +37890 -0.13446044921875 +37891 -0.473846435546875 +37892 -0.1312255859375 +37893 -0.464813232421875 +37894 -0.117156982421875 +37895 -0.419097900390625 +37896 -0.092132568359375 +37897 -0.334320068359375 +37898 -0.061126708984375 +37899 -0.227935791015625 +37900 -0.030731201171875 +37901 -0.12347412109375 +37902 -0.0029296875 +37903 -0.02764892578125 +37904 0.02685546875 +37905 0.077667236328125 +37906 0.06396484375 +37907 0.2132568359375 +37908 0.110931396484375 +37909 0.38885498046875 +37910 0.16204833984375 +37911 0.582794189453125 +37912 0.201263427734375 +37913 0.734039306640625 +37914 0.21746826171875 +37915 0.800140380859375 +37916 0.210052490234375 +37917 0.7783203125 +37918 0.17822265625 +37919 0.6651611328125 +37920 0.12188720703125 +37921 0.45965576171875 +37922 0.051055908203125 +37923 0.199188232421875 +37924 -0.016815185546875 +37925 -0.050689697265625 +37926 -0.066558837890625 +37927 -0.23297119140625 +37928 -0.093475341796875 +37929 -0.33013916015625 +37930 -0.10443115234375 +37931 -0.368408203125 +37932 -0.10760498046875 +37933 -0.378936767578125 +37934 -0.1070556640625 +37935 -0.376983642578125 +37936 -0.1072998046875 +37937 -0.37969970703125 +37938 -0.10955810546875 +37939 -0.391510009765625 +37940 -0.106719970703125 +37941 -0.385345458984375 +37942 -0.093780517578125 +37943 -0.3419189453125 +37944 -0.0765380859375 +37945 -0.28289794921875 +37946 -0.0665283203125 +37947 -0.251617431640625 +37948 -0.068634033203125 +37949 -0.266143798828125 +37950 -0.068939208984375 +37951 -0.273345947265625 +37952 -0.0526123046875 +37953 -0.216796875 +37954 -0.028106689453125 +37955 -0.128265380859375 +37956 -0.01141357421875 +37957 -0.068145751953125 +37958 -0.00433349609375 +37959 -0.0430908203125 +37960 0.000640869140625 +37961 -0.024444580078125 +37962 0.012237548828125 +37963 0.020721435546875 +37964 0.0389404296875 +37965 0.124481201171875 +37966 0.073150634765625 +37967 0.25787353515625 +37968 0.103912353515625 +37969 0.379119873046875 +37970 0.129119873046875 +37971 0.47991943359375 +37972 0.140380859375 +37973 0.5281982421875 +37974 0.134368896484375 +37975 0.511138916015625 +37976 0.118438720703125 +37977 0.456207275390625 +37978 0.10430908203125 +37979 0.407470703125 +37980 0.097015380859375 +37981 0.383758544921875 +37982 0.089111328125 +37983 0.35687255859375 +37984 0.076690673828125 +37985 0.31182861328125 +37986 0.060394287109375 +37987 0.250885009765625 +37988 0.037933349609375 +37989 0.1654052734375 +37990 0.003997802734375 +37991 0.035247802734375 +37992 -0.042083740234375 +37993 -0.142059326171875 +37994 -0.092193603515625 +37995 -0.33563232421875 +37996 -0.143524169921875 +37997 -0.5345458984375 +37998 -0.191680908203125 +37999 -0.72186279296875 +38000 -0.220611572265625 +38001 -0.836669921875 +38002 -0.218170166015625 +38003 -0.8326416015625 +38004 -0.189697265625 +38005 -0.7296142578125 +38006 -0.149810791015625 +38007 -0.582550048828125 +38008 -0.11138916015625 +38009 -0.440093994140625 +38010 -0.080291748046875 +38011 -0.324310302734375 +38012 -0.047607421875 +38013 -0.20147705078125 +38014 -0.006195068359375 +38015 -0.044647216796875 +38016 0.03277587890625 +38017 0.103973388671875 +38018 0.0582275390625 +38019 0.202392578125 +38020 0.0738525390625 +38021 0.264495849609375 +38022 0.092498779296875 +38023 0.338897705078125 +38024 0.11907958984375 +38025 0.443817138671875 +38026 0.14459228515625 +38027 0.545074462890625 +38028 0.162445068359375 +38029 0.6173095703125 +38030 0.170562744140625 +38031 0.6524658203125 +38032 0.17242431640625 +38033 0.66339111328125 +38034 0.169677734375 +38035 0.6561279296875 +38036 0.156005859375 +38037 0.606781005859375 +38038 0.127685546875 +38039 0.501190185546875 +38040 0.08831787109375 +38041 0.352783203125 +38042 0.0418701171875 +38043 0.176544189453125 +38044 -0.0135498046875 +38045 -0.034820556640625 +38046 -0.071868896484375 +38047 -0.258209228515625 +38048 -0.11962890625 +38049 -0.44244384765625 +38050 -0.1536865234375 +38051 -0.5753173828125 +38052 -0.1728515625 +38053 -0.65203857421875 +38054 -0.16900634765625 +38055 -0.641632080078125 +38056 -0.14697265625 +38057 -0.562164306640625 +38058 -0.118499755859375 +38059 -0.458038330078125 +38060 -0.08929443359375 +38061 -0.350555419921875 +38062 -0.06488037109375 +38063 -0.260528564453125 +38064 -0.04638671875 +38065 -0.192108154296875 +38066 -0.032928466796875 +38067 -0.141937255859375 +38068 -0.0224609375 +38069 -0.1021728515625 +38070 -0.012359619140625 +38071 -0.062896728515625 +38072 0.0006103515625 +38073 -0.011932373046875 +38074 0.019683837890625 +38075 0.062835693359375 +38076 0.04156494140625 +38077 0.148712158203125 +38078 0.06524658203125 +38079 0.241729736328125 +38080 0.092681884765625 +38081 0.34912109375 +38082 0.120330810546875 +38083 0.457305908203125 +38084 0.142303466796875 +38085 0.54388427734375 +38086 0.149169921875 +38087 0.5728759765625 +38088 0.131011962890625 +38089 0.506591796875 +38090 0.089508056640625 +38091 0.351226806640625 +38092 0.035186767578125 +38093 0.146514892578125 +38094 -0.01812744140625 +38095 -0.05523681640625 +38096 -0.060455322265625 +38097 -0.21624755859375 +38098 -0.0914306640625 +38099 -0.334930419921875 +38100 -0.108856201171875 +38101 -0.402984619140625 +38102 -0.1182861328125 +38103 -0.4412841796875 +38104 -0.13189697265625 +38105 -0.49578857421875 +38106 -0.148040771484375 +38107 -0.5601806640625 +38108 -0.157867431640625 +38109 -0.600738525390625 +38110 -0.152679443359375 +38111 -0.584228515625 +38112 -0.124237060546875 +38113 -0.47930908203125 +38114 -0.070831298828125 +38115 -0.27935791015625 +38116 0.0009765625 +38117 -0.0089111328125 +38118 0.074493408203125 +38119 0.268798828125 +38120 0.1309814453125 +38121 0.482818603515625 +38122 0.162689208984375 +38123 0.60369873046875 +38124 0.17462158203125 +38125 0.650421142578125 +38126 0.17767333984375 +38127 0.66400146484375 +38128 0.17108154296875 +38129 0.6414794921875 +38130 0.15216064453125 +38131 0.572540283203125 +38132 0.13177490234375 +38133 0.498138427734375 +38134 0.115570068359375 +38135 0.439453125 +38136 0.098052978515625 +38137 0.375518798828125 +38138 0.070831298828125 +38139 0.274505615234375 +38140 0.026611328125 +38141 0.1087646484375 +38142 -0.0286865234375 +38143 -0.099395751953125 +38144 -0.08612060546875 +38145 -0.3182373046875 +38146 -0.14520263671875 +38147 -0.5489501953125 +38148 -0.201446533203125 +38149 -0.7738037109375 +38150 -0.242431640625 +38151 -0.86383056640625 +38152 -0.2603759765625 +38153 -0.870391845703125 +38154 -0.25946044921875 +38155 -0.86895751953125 +38156 -0.24285888671875 +38157 -0.861053466796875 +38158 -0.206756591796875 +38159 -0.765869140625 +38160 -0.1488037109375 +38161 -0.5301513671875 +38162 -0.070953369140625 +38163 -0.214691162109375 +38164 0.01641845703125 +38165 0.137359619140625 +38166 0.101104736328125 +38167 0.474822998046875 +38168 0.174530029296875 +38169 0.76239013671875 +38170 0.230133056640625 +38171 0.867462158203125 +38172 0.26776123046875 +38173 0.870361328125 +38174 0.284515380859375 +38175 0.86480712890625 +38176 0.28155517578125 +38177 0.831817626953125 +38178 0.26446533203125 +38179 0.677581787109375 +38180 0.234619140625 +38181 0.495880126953125 +38182 0.196380615234375 +38183 0.30767822265625 +38184 0.150390625 +38185 0.116180419921875 +38186 0.0894775390625 +38187 -0.110748291015625 +38188 0.01226806640625 +38189 -0.381805419921875 +38190 -0.071014404296875 +38191 -0.6572265625 +38192 -0.14617919921875 +38193 -0.857421875 +38194 -0.203033447265625 +38195 -0.870391845703125 +38196 -0.23968505859375 +38197 -0.870391845703125 +38198 -0.26214599609375 +38199 -0.86444091796875 +38200 -0.278564453125 +38201 -0.85723876953125 +38202 -0.284576416015625 +38203 -0.790008544921875 +38204 -0.267547607421875 +38205 -0.62847900390625 +38206 -0.226715087890625 +38207 -0.3956298828125 +38208 -0.169769287109375 +38209 -0.126708984375 +38210 -0.1031494140625 +38211 0.150115966796875 +38212 -0.02972412109375 +38213 0.424041748046875 +38214 0.0440673828125 +38215 0.670623779296875 +38216 0.1090087890625 +38217 0.854522705078125 +38218 0.160797119140625 +38219 0.866485595703125 +38220 0.195648193359375 +38221 0.86920166015625 +38222 0.21759033203125 +38223 0.8653564453125 +38224 0.22955322265625 +38225 0.857147216796875 +38226 0.230712890625 +38227 0.766845703125 +38228 0.222137451171875 +38229 0.628509521484375 +38230 0.20220947265625 +38231 0.462127685546875 +38232 0.176910400390625 +38233 0.297210693359375 +38234 0.14910888671875 +38235 0.14862060546875 +38236 0.11358642578125 +38237 -0.00537109375 +38238 0.07220458984375 +38239 -0.15753173828125 +38240 0.024322509765625 +38241 -0.31304931640625 +38242 -0.03314208984375 +38243 -0.48876953125 +38244 -0.08917236328125 +38245 -0.6416015625 +38246 -0.137847900390625 +38247 -0.751373291015625 +38248 -0.184356689453125 +38249 -0.84619140625 +38250 -0.22515869140625 +38251 -0.861297607421875 +38252 -0.252410888671875 +38253 -0.863250732421875 +38254 -0.2586669921875 +38255 -0.856597900390625 +38256 -0.2467041015625 +38257 -0.7498779296875 +38258 -0.22991943359375 +38259 -0.624542236328125 +38260 -0.203216552734375 +38261 -0.47808837890625 +38262 -0.153106689453125 +38263 -0.253387451171875 +38264 -0.090240478515625 +38265 0.003692626953125 +38266 -0.030609130859375 +38267 0.2257080078125 +38268 0.028533935546875 +38269 0.427154541015625 +38270 0.09454345703125 +38271 0.643218994140625 +38272 0.1650390625 +38273 0.855926513671875 +38274 0.226409912109375 +38275 0.870361328125 +38276 0.26702880859375 +38277 0.870361328125 +38278 0.288421630859375 +38279 0.862762451171875 +38280 0.28985595703125 +38281 0.79669189453125 +38282 0.269073486328125 +38283 0.595794677734375 +38284 0.232818603515625 +38285 0.362152099609375 +38286 0.1876220703125 +38287 0.1270751953125 +38288 0.138427734375 +38289 -0.086944580078125 +38290 0.085784912109375 +38291 -0.2784423828125 +38292 0.021728515625 +38293 -0.484832763671875 +38294 -0.05804443359375 +38295 -0.729583740234375 +38296 -0.14166259765625 +38297 -0.86688232421875 +38298 -0.214324951171875 +38299 -0.870391845703125 +38300 -0.27471923828125 +38301 -0.86859130859375 +38302 -0.322235107421875 +38303 -0.86279296875 +38304 -0.34844970703125 +38305 -0.817962646484375 +38306 -0.34271240234375 +38307 -0.6116943359375 +38308 -0.3033447265625 +38309 -0.3128662109375 +38310 -0.23809814453125 +38311 0.039398193359375 +38312 -0.151641845703125 +38313 0.422821044921875 +38314 -0.0517578125 +38315 0.805145263671875 +38316 0.045684814453125 +38317 0.870361328125 +38318 0.127349853515625 +38319 0.870361328125 +38320 0.190399169921875 +38321 0.860015869140625 +38322 0.232879638671875 +38323 0.727935791015625 +38324 0.25335693359375 +38325 0.48114013671875 +38326 0.257293701171875 +38327 0.2059326171875 +38328 0.249755859375 +38329 -0.06103515625 +38330 0.23297119140625 +38331 -0.29913330078125 +38332 0.203460693359375 +38333 -0.516204833984375 +38334 0.157623291015625 +38335 -0.7252197265625 +38336 0.101226806640625 +38337 -0.85980224609375 +38338 0.042236328125 +38339 -0.870391845703125 +38340 -0.01239013671875 +38341 -0.870391845703125 +38342 -0.051177978515625 +38343 -0.858062744140625 +38344 -0.072998046875 +38345 -0.673004150390625 +38346 -0.089874267578125 +38347 -0.42694091796875 +38348 -0.111907958984375 +38349 -0.2100830078125 +38350 -0.138397216796875 +38351 -0.0362548828125 +38352 -0.162384033203125 +38353 0.10943603515625 +38354 -0.179046630859375 +38355 0.23516845703125 +38356 -0.17864990234375 +38357 0.373687744140625 +38358 -0.16156005859375 +38359 0.517791748046875 +38360 -0.142333984375 +38361 0.602783203125 +38362 -0.1197509765625 +38363 0.635711669921875 +38364 -0.08612060546875 +38365 0.655181884765625 +38366 -0.0438232421875 +38367 0.65948486328125 +38368 0.00506591796875 +38369 0.651275634765625 +38370 0.05474853515625 +38371 0.61846923828125 +38372 0.096435546875 +38373 0.53753662109375 +38374 0.125732421875 +38375 0.404144287109375 +38376 0.140228271484375 +38377 0.22186279296875 +38378 0.1400146484375 +38379 0.003997802734375 +38380 0.129119873046875 +38381 -0.22100830078125 +38382 0.112213134765625 +38383 -0.42449951171875 +38384 0.0941162109375 +38385 -0.579833984375 +38386 0.084686279296875 +38387 -0.641876220703125 +38388 0.082366943359375 +38389 -0.6177978515625 +38390 0.072174072265625 +38391 -0.575531005859375 +38392 0.052947998046875 +38393 -0.526336669921875 +38394 0.036773681640625 +38395 -0.42645263671875 +38396 0.0301513671875 +38397 -0.2581787109375 +38398 0.02484130859375 +38399 -0.068695068359375 +38400 0.0115966796875 +38401 0.09222412109375 +38402 -0.005615234375 +38403 0.232147216796875 +38404 -0.023712158203125 +38405 0.3509521484375 +38406 -0.047882080078125 +38407 0.410064697265625 +38408 -0.083404541015625 +38409 0.372955322265625 +38410 -0.125640869140625 +38411 0.2554931640625 +38412 -0.163818359375 +38413 0.10711669921875 +38414 -0.193817138671875 +38415 -0.052886962890625 +38416 -0.208343505859375 +38417 -0.186279296875 +38418 -0.19635009765625 +38419 -0.23291015625 +38420 -0.16259765625 +38421 -0.209442138671875 +38422 -0.120574951171875 +38423 -0.174163818359375 +38424 -0.07232666015625 +38425 -0.126739501953125 +38426 -0.016265869140625 +38427 -0.048126220703125 +38428 0.041473388671875 +38429 0.0426025390625 +38430 0.091156005859375 +38431 0.10748291015625 +38432 0.129730224609375 +38433 0.1409912109375 +38434 0.166351318359375 +38435 0.19708251953125 +38436 0.19940185546875 +38437 0.273651123046875 +38438 0.217559814453125 +38439 0.31768798828125 +38440 0.222930908203125 +38441 0.341094970703125 +38442 0.220550537109375 +38443 0.368011474609375 +38444 0.205902099609375 +38445 0.37249755859375 +38446 0.1693115234375 +38447 0.30072021484375 +38448 0.111968994140625 +38449 0.1517333984375 +38450 0.0474853515625 +38451 -0.01470947265625 +38452 -0.020263671875 +38453 -0.1883544921875 +38454 -0.090118408203125 +38455 -0.372711181640625 +38456 -0.149566650390625 +38457 -0.51397705078125 +38458 -0.188873291015625 +38459 -0.57177734375 +38460 -0.20526123046875 +38461 -0.53948974609375 +38462 -0.20123291015625 +38463 -0.43511962890625 +38464 -0.183563232421875 +38465 -0.2962646484375 +38466 -0.1595458984375 +38467 -0.161102294921875 +38468 -0.131988525390625 +38469 -0.0435791015625 +38470 -0.10052490234375 +38471 0.060394287109375 +38472 -0.0687255859375 +38473 0.13665771484375 +38474 -0.040679931640625 +38475 0.170135498046875 +38476 -0.01678466796875 +38477 0.16552734375 +38478 0.00836181640625 +38479 0.15728759765625 +38480 0.034332275390625 +38481 0.150787353515625 +38482 0.054840087890625 +38483 0.12200927734375 +38484 0.0703125 +38485 0.080108642578125 +38486 0.084747314453125 +38487 0.05126953125 +38488 0.102630615234375 +38489 0.062896728515625 +38490 0.118804931640625 +38491 0.09271240234375 +38492 0.123321533203125 +38493 0.092987060546875 +38494 0.119049072265625 +38495 0.07855224609375 +38496 0.109222412109375 +38497 0.06427001953125 +38498 0.09130859375 +38499 0.0347900390625 +38500 0.06573486328125 +38501 -0.01171875 +38502 0.037353515625 +38503 -0.056060791015625 +38504 0.015869140625 +38505 -0.055511474609375 +38506 0.00244140625 +38507 -0.010467529296875 +38508 -0.012451171875 +38509 0.02508544921875 +38510 -0.032745361328125 +38511 0.025665283203125 +38512 -0.052154541015625 +38513 0.017333984375 +38514 -0.06939697265625 +38515 0.00189208984375 +38516 -0.086029052734375 +38517 -0.03173828125 +38518 -0.0992431640625 +38519 -0.071502685546875 +38520 -0.11248779296875 +38521 -0.13543701171875 +38522 -0.125152587890625 +38523 -0.219970703125 +38524 -0.1326904296875 +38525 -0.300506591796875 +38526 -0.135528564453125 +38527 -0.376312255859375 +38528 -0.128204345703125 +38529 -0.416107177734375 +38530 -0.10186767578125 +38531 -0.371124267578125 +38532 -0.0577392578125 +38533 -0.242279052734375 +38534 -0.0048828125 +38535 -0.069732666015625 +38536 0.051483154296875 +38537 0.125640869140625 +38538 0.104248046875 +38539 0.31268310546875 +38540 0.14532470703125 +38541 0.45501708984375 +38542 0.174530029296875 +38543 0.554779052734375 +38544 0.19122314453125 +38545 0.61065673828125 +38546 0.19287109375 +38547 0.610931396484375 +38548 0.1746826171875 +38549 0.531463623046875 +38550 0.140106201171875 +38551 0.3883056640625 +38552 0.1002197265625 +38553 0.23468017578125 +38554 0.060546875 +38555 0.095245361328125 +38556 0.027008056640625 +38557 -0.00396728515625 +38558 0.003265380859375 +38559 -0.04852294921875 +38560 -0.013153076171875 +38561 -0.055145263671875 +38562 -0.031829833984375 +38563 -0.0758056640625 +38564 -0.0576171875 +38565 -0.138702392578125 +38566 -0.0828857421875 +38567 -0.209197998046875 +38568 -0.107452392578125 +38569 -0.289031982421875 +38570 -0.13104248046875 +38571 -0.37884521484375 +38572 -0.148956298828125 +38573 -0.456329345703125 +38574 -0.16015625 +38575 -0.51641845703125 +38576 -0.156829833984375 +38577 -0.519287109375 +38578 -0.137939453125 +38579 -0.458251953125 +38580 -0.11419677734375 +38581 -0.384796142578125 +38582 -0.09112548828125 +38583 -0.323699951171875 +38584 -0.0682373046875 +38585 -0.269287109375 +38586 -0.040924072265625 +38587 -0.1951904296875 +38588 -0.009613037109375 +38589 -0.100006103515625 +38590 0.019622802734375 +38591 -0.01055908203125 +38592 0.052215576171875 +38593 0.1033935546875 +38594 0.089141845703125 +38595 0.24908447265625 +38596 0.119384765625 +38597 0.373199462890625 +38598 0.13916015625 +38599 0.45806884765625 +38600 0.14996337890625 +38601 0.511474609375 +38602 0.15826416015625 +38603 0.565399169921875 +38604 0.162567138671875 +38605 0.61138916015625 +38606 0.151275634765625 +38607 0.5897216796875 +38608 0.12286376953125 +38609 0.4906005859375 +38610 0.08135986328125 +38611 0.33148193359375 +38612 0.034423828125 +38613 0.147796630859375 +38614 -0.009033203125 +38615 -0.01873779296875 +38616 -0.042877197265625 +38617 -0.140289306640625 +38618 -0.0616455078125 +38619 -0.191986083984375 +38620 -0.0670166015625 +38621 -0.184295654296875 +38622 -0.06756591796875 +38623 -0.161834716796875 +38624 -0.07147216796875 +38625 -0.166595458984375 +38626 -0.07769775390625 +38627 -0.19390869140625 +38628 -0.0823974609375 +38629 -0.22442626953125 +38630 -0.09002685546875 +38631 -0.279754638671875 +38632 -0.096649169921875 +38633 -0.3389892578125 +38634 -0.09307861328125 +38635 -0.3543701171875 +38636 -0.084136962890625 +38637 -0.348175048828125 +38638 -0.0714111328125 +38639 -0.32598876953125 +38640 -0.049468994140625 +38641 -0.2581787109375 +38642 -0.01776123046875 +38643 -0.139801025390625 +38644 0.0203857421875 +38645 0.014617919921875 +38646 0.052398681640625 +38647 0.144378662109375 +38648 0.07232666015625 +38649 0.221038818359375 +38650 0.085174560546875 +38651 0.27069091796875 +38652 0.09100341796875 +38653 0.294036865234375 +38654 0.09393310546875 +38655 0.311767578125 +38656 0.09698486328125 +38657 0.339141845703125 +38658 0.096771240234375 +38659 0.360260009765625 +38660 0.09075927734375 +38661 0.360504150390625 +38662 0.074188232421875 +38663 0.308380126953125 +38664 0.043914794921875 +38665 0.18170166015625 +38666 0.004608154296875 +38667 0.0047607421875 +38668 -0.035186767578125 +38669 -0.17559814453125 +38670 -0.0673828125 +38671 -0.3143310546875 +38672 -0.084136962890625 +38673 -0.36785888671875 +38674 -0.0894775390625 +38675 -0.36248779296875 +38676 -0.090728759765625 +38677 -0.343536376953125 +38678 -0.086181640625 +38679 -0.3018798828125 +38680 -0.074737548828125 +38681 -0.231414794921875 +38682 -0.053985595703125 +38683 -0.117645263671875 +38684 -0.029541015625 +38685 0.007049560546875 +38686 -0.010833740234375 +38687 0.087982177734375 +38688 0.004180908203125 +38689 0.13946533203125 +38690 0.01727294921875 +38691 0.17425537109375 +38692 0.027313232421875 +38693 0.188201904296875 +38694 0.03216552734375 +38695 0.171234130859375 +38696 0.03057861328125 +38697 0.118438720703125 +38698 0.02679443359375 +38699 0.05706787109375 +38700 0.02081298828125 +38701 -0.010711669921875 +38702 0.011260986328125 +38703 -0.0914306640625 +38704 0.001800537109375 +38705 -0.162322998046875 +38706 -0.0028076171875 +38707 -0.194549560546875 +38708 0.003936767578125 +38709 -0.1492919921875 +38710 0.02294921875 +38711 -0.02166748046875 +38712 0.04364013671875 +38713 0.124053955078125 +38714 0.053314208984375 +38715 0.211151123046875 +38716 0.05242919921875 +38717 0.240447998046875 +38718 0.046417236328125 +38719 0.242218017578125 +38720 0.0372314453125 +38721 0.2257080078125 +38722 0.025787353515625 +38723 0.194366455078125 +38724 0.006927490234375 +38725 0.115509033203125 +38726 -0.015045166015625 +38727 0.0128173828125 +38728 -0.02984619140625 +38729 -0.053802490234375 +38730 -0.041748046875 +38731 -0.110626220703125 +38732 -0.05767822265625 +38733 -0.199493408203125 +38734 -0.0732421875 +38735 -0.29437255859375 +38736 -0.077911376953125 +38737 -0.33221435546875 +38738 -0.066253662109375 +38739 -0.27972412109375 +38740 -0.04656982421875 +38741 -0.185333251953125 +38742 -0.032379150390625 +38743 -0.128204345703125 +38744 -0.02520751953125 +38745 -0.115692138671875 +38746 -0.02008056640625 +38747 -0.116455078125 +38748 -0.013153076171875 +38749 -0.105926513671875 +38750 0.00030517578125 +38751 -0.053955078125 +38752 0.021636962890625 +38753 0.048797607421875 +38754 0.0430908203125 +38755 0.157318115234375 +38756 0.05450439453125 +38757 0.212005615234375 +38758 0.05670166015625 +38759 0.218475341796875 +38760 0.059844970703125 +38761 0.23724365234375 +38762 0.0701904296875 +38763 0.30535888671875 +38764 0.08087158203125 +38765 0.38128662109375 +38766 0.081787109375 +38767 0.404449462890625 +38768 0.076446533203125 +38769 0.3944091796875 +38770 0.07135009765625 +38771 0.3885498046875 +38772 0.062652587890625 +38773 0.362640380859375 +38774 0.043365478515625 +38775 0.27362060546875 +38776 0.01300048828125 +38777 0.11712646484375 +38778 -0.01947021484375 +38779 -0.054901123046875 +38780 -0.045166015625 +38781 -0.19085693359375 +38782 -0.0631103515625 +38783 -0.28570556640625 +38784 -0.073211669921875 +38785 -0.339263916015625 +38786 -0.079803466796875 +38787 -0.3775634765625 +38788 -0.090484619140625 +38789 -0.445709228515625 +38790 -0.1038818359375 +38791 -0.535064697265625 +38792 -0.1173095703125 +38793 -0.629058837890625 +38794 -0.1258544921875 +38795 -0.697601318359375 +38796 -0.123504638671875 +38797 -0.70391845703125 +38798 -0.109527587890625 +38799 -0.6424560546875 +38800 -0.0804443359375 +38801 -0.491241455078125 +38802 -0.039093017578125 +38803 -0.265716552734375 +38804 0.004608154296875 +38805 -0.023712158203125 +38806 0.044952392578125 +38807 0.201751708984375 +38808 0.07598876953125 +38809 0.375823974609375 +38810 0.095367431640625 +38811 0.485076904296875 +38812 0.10968017578125 +38813 0.56884765625 +38814 0.120208740234375 +38815 0.634765625 +38816 0.11944580078125 +38817 0.63763427734375 +38818 0.10552978515625 +38819 0.5660400390625 +38820 0.08734130859375 +38821 0.4720458984375 +38822 0.073638916015625 +38823 0.40692138671875 +38824 0.065765380859375 +38825 0.3778076171875 +38826 0.062591552734375 +38827 0.376953125 +38828 0.058868408203125 +38829 0.371978759765625 +38830 0.046356201171875 +38831 0.313140869140625 +38832 0.02252197265625 +38833 0.184417724609375 +38834 -0.00823974609375 +38835 0.011199951171875 +38836 -0.039886474609375 +38837 -0.171051025390625 +38838 -0.06817626953125 +38839 -0.33740234375 +38840 -0.0904541015625 +38841 -0.47198486328125 +38842 -0.104339599609375 +38843 -0.560394287109375 +38844 -0.106201171875 +38845 -0.58056640625 +38846 -0.09869384765625 +38847 -0.54754638671875 +38848 -0.089874267578125 +38849 -0.508575439453125 +38850 -0.07916259765625 +38851 -0.459503173828125 +38852 -0.065704345703125 +38853 -0.394378662109375 +38854 -0.056243896484375 +38855 -0.35260009765625 +38856 -0.047088623046875 +38857 -0.31170654296875 +38858 -0.02593994140625 +38859 -0.197418212890625 +38860 0.007415771484375 +38861 -0.007965087890625 +38862 0.044586181640625 +38863 0.207489013671875 +38864 0.078887939453125 +38865 0.409210205078125 +38866 0.1060791015625 +38867 0.57208251953125 +38868 0.121124267578125 +38869 0.66595458984375 +38870 0.118682861328125 +38871 0.65875244140625 +38872 0.101715087890625 +38873 0.56744384765625 +38874 0.076934814453125 +38875 0.431396484375 +38876 0.05181884765625 +38877 0.29443359375 +38878 0.03082275390625 +38879 0.182464599609375 +38880 0.008758544921875 +38881 0.06365966796875 +38882 -0.016632080078125 +38883 -0.075958251953125 +38884 -0.037322998046875 +38885 -0.189422607421875 +38886 -0.05242919921875 +38887 -0.271942138671875 +38888 -0.0650634765625 +38889 -0.342529296875 +38890 -0.06903076171875 +38891 -0.364166259765625 +38892 -0.062713623046875 +38893 -0.327239990234375 +38894 -0.0537109375 +38895 -0.2769775390625 +38896 -0.048828125 +38897 -0.253692626953125 +38898 -0.04583740234375 +38899 -0.24365234375 +38900 -0.03668212890625 +38901 -0.1983642578125 +38902 -0.02117919921875 +38903 -0.116241455078125 +38904 -0.006072998046875 +38905 -0.036834716796875 +38906 0.0076904296875 +38907 0.034881591796875 +38908 0.01873779296875 +38909 0.09124755859375 +38910 0.023040771484375 +38911 0.10888671875 +38912 0.0264892578125 +38913 0.125518798828125 +38914 0.031707763671875 +38915 0.15771484375 +38916 0.03460693359375 +38917 0.17828369140625 +38918 0.03314208984375 +38919 0.17108154296875 +38920 0.026580810546875 +38921 0.129974365234375 +38922 0.018798828125 +38923 0.082427978515625 +38924 0.009765625 +38925 0.027679443359375 +38926 -0.004608154296875 +38927 -0.065643310546875 +38928 -0.019073486328125 +38929 -0.15936279296875 +38930 -0.028045654296875 +38931 -0.21307373046875 +38932 -0.03253173828125 +38933 -0.234649658203125 +38934 -0.02923583984375 +38935 -0.2001953125 +38936 -0.0194091796875 +38937 -0.119171142578125 +38938 -0.00750732421875 +38939 -0.024749755859375 +38940 0.006866455078125 +38941 0.085784912109375 +38942 0.01904296875 +38943 0.178131103515625 +38944 0.0240478515625 +38945 0.215576171875 +38946 0.023681640625 +38947 0.211456298828125 +38948 0.019256591796875 +38949 0.17523193359375 +38950 0.013671875 +38951 0.128753662109375 +38952 0.010955810546875 +38953 0.1019287109375 +38954 0.008270263671875 +38955 0.0743408203125 +38956 0.00518798828125 +38957 0.04327392578125 +38958 0.005615234375 +38959 0.038177490234375 +38960 0.011871337890625 +38961 0.076263427734375 +38962 0.0216064453125 +38963 0.14105224609375 +38964 0.028533935546875 +38965 0.186431884765625 +38966 0.0294189453125 +38967 0.188812255859375 +38968 0.02301025390625 +38969 0.1390380859375 +38970 0.009918212890625 +38971 0.041778564453125 +38972 -0.006622314453125 +38973 -0.079437255859375 +38974 -0.025909423828125 +38975 -0.219390869140625 +38976 -0.046478271484375 +38977 -0.367828369140625 +38978 -0.06427001953125 +38979 -0.494873046875 +38980 -0.0732421875 +38981 -0.556243896484375 +38982 -0.0675048828125 +38983 -0.508697509765625 +38984 -0.0501708984375 +38985 -0.3756103515625 +38986 -0.0296630859375 +38987 -0.218902587890625 +38988 -0.009307861328125 +38989 -0.063751220703125 +38990 0.011077880859375 +38991 0.091552734375 +38992 0.030059814453125 +38993 0.23602294921875 +38994 0.0440673828125 +38995 0.342987060546875 +38996 0.05078125 +38997 0.39520263671875 +38998 0.04974365234375 +38999 0.389373779296875 +39000 0.04083251953125 +39001 0.324249267578125 +39002 0.027374267578125 +39003 0.224090576171875 +39004 0.01416015625 +39005 0.124267578125 +39006 0.0028076171875 +39007 0.037078857421875 +39008 -0.002960205078125 +39009 -0.010101318359375 +39010 -0.003509521484375 +39011 -0.019439697265625 +39012 -0.003204345703125 +39013 -0.022796630859375 +39014 0.00042724609375 +39015 -0.001556396484375 +39016 0.008941650390625 +39017 0.056304931640625 +39018 0.016326904296875 +39019 0.106719970703125 +39020 0.015411376953125 +39021 0.096893310546875 +39022 0.00830078125 +39023 0.042694091796875 +39024 0.00018310546875 +39025 -0.018035888671875 +39026 -0.007659912109375 +39027 -0.07586669921875 +39028 -0.013671875 +39029 -0.11944580078125 +39030 -0.01934814453125 +39031 -0.15972900390625 +39032 -0.025482177734375 +39033 -0.202606201171875 +39034 -0.0321044921875 +39035 -0.24859619140625 +39036 -0.040191650390625 +39037 -0.30517578125 +39038 -0.04833984375 +39039 -0.36212158203125 +39040 -0.052764892578125 +39041 -0.39141845703125 +39042 -0.04827880859375 +39043 -0.35528564453125 +39044 -0.034332275390625 +39045 -0.249969482421875 +39046 -0.0133056640625 +39047 -0.092864990234375 +39048 0.011138916015625 +39049 0.08905029296875 +39050 0.030792236328125 +39051 0.2352294921875 +39052 0.0419921875 +39053 0.318817138671875 +39054 0.047332763671875 +39055 0.358642578125 +39056 0.04583740234375 +39057 0.347747802734375 +39058 0.0374755859375 +39059 0.28564453125 +39060 0.02911376953125 +39061 0.223175048828125 +39062 0.025726318359375 +39063 0.196746826171875 +39064 0.023681640625 +39065 0.179840087890625 +39066 0.020660400390625 +39067 0.155548095703125 +39068 0.020355224609375 +39069 0.151214599609375 +39070 0.02142333984375 +39071 0.156951904296875 +39072 0.018280029296875 +39073 0.13177490234375 +39074 0.014312744140625 +39075 0.100799560546875 +39076 0.01263427734375 +39077 0.087127685546875 +39078 0.008392333984375 +39079 0.05487060546875 +39080 -0.000152587890625 +39081 -0.009002685546875 +39082 -0.012939453125 +39083 -0.10400390625 +39084 -0.0299072265625 +39085 -0.229400634765625 +39086 -0.047027587890625 +39087 -0.35552978515625 +39088 -0.05877685546875 +39089 -0.441925048828125 +39090 -0.063140869140625 +39091 -0.473846435546875 +39092 -0.061981201171875 +39093 -0.464813232421875 +39094 -0.055877685546875 +39095 -0.419097900390625 +39096 -0.04449462890625 +39097 -0.334320068359375 +39098 -0.03021240234375 +39099 -0.227935791015625 +39100 -0.016204833984375 +39101 -0.12347412109375 +39102 -0.003387451171875 +39103 -0.02764892578125 +39104 0.010711669921875 +39105 0.077667236328125 +39106 0.0289306640625 +39107 0.2132568359375 +39108 0.0526123046875 +39109 0.38885498046875 +39110 0.07879638671875 +39111 0.582794189453125 +39112 0.099212646484375 +39113 0.734039306640625 +39114 0.108062744140625 +39115 0.800140380859375 +39116 0.10498046875 +39117 0.7783203125 +39118 0.08953857421875 +39119 0.6651611328125 +39120 0.06158447265625 +39121 0.45965576171875 +39122 0.0262451171875 +39123 0.199188232421875 +39124 -0.007568359375 +39125 -0.050689697265625 +39126 -0.032135009765625 +39127 -0.23297119140625 +39128 -0.045074462890625 +39129 -0.33013916015625 +39130 -0.049957275390625 +39131 -0.368408203125 +39132 -0.051055908203125 +39133 -0.378936767578125 +39134 -0.050506591796875 +39135 -0.376983642578125 +39136 -0.050628662109375 +39137 -0.37969970703125 +39138 -0.052032470703125 +39139 -0.391510009765625 +39140 -0.051025390625 +39141 -0.385345458984375 +39142 -0.045013427734375 +39143 -0.3419189453125 +39144 -0.036956787109375 +39145 -0.28289794921875 +39146 -0.03271484375 +39147 -0.251617431640625 +39148 -0.034759521484375 +39149 -0.266143798828125 +39150 -0.035858154296875 +39151 -0.273345947265625 +39152 -0.0283203125 +39153 -0.216796875 +39154 -0.016448974609375 +39155 -0.128265380859375 +39156 -0.0084228515625 +39157 -0.068145751953125 +39158 -0.005157470703125 +39159 -0.0430908203125 +39160 -0.002777099609375 +39161 -0.024444580078125 +39162 0.003173828125 +39163 0.020721435546875 +39164 0.01708984375 +39165 0.124481201171875 +39166 0.035003662109375 +39167 0.25787353515625 +39168 0.050689697265625 +39169 0.379119873046875 +39170 0.063262939453125 +39171 0.47991943359375 +39172 0.0697021484375 +39173 0.5281982421875 +39174 0.06854248046875 +39175 0.511138916015625 +39176 0.062530517578125 +39177 0.456207275390625 +39178 0.056243896484375 +39179 0.407470703125 +39180 0.051727294921875 +39181 0.383758544921875 +39182 0.046142578125 +39183 0.35687255859375 +39184 0.038116455078125 +39185 0.31182861328125 +39186 0.02813720703125 +39187 0.250885009765625 +39188 0.0155029296875 +39189 0.1654052734375 +39190 -0.001617431640625 +39191 0.035247802734375 +39192 -0.02325439453125 +39193 -0.142059326171875 +39194 -0.0460205078125 +39195 -0.33563232421875 +39196 -0.068634033203125 +39197 -0.5345458984375 +39198 -0.089263916015625 +39199 -0.72186279296875 +39200 -0.10150146484375 +39201 -0.836669921875 +39202 -0.10052490234375 +39203 -0.8326416015625 +39204 -0.0885009765625 +39205 -0.7296142578125 +39206 -0.07122802734375 +39207 -0.582550048828125 +39208 -0.05389404296875 +39209 -0.440093994140625 +39210 -0.0389404296875 +39211 -0.324310302734375 +39212 -0.02301025390625 +39213 -0.20147705078125 +39214 -0.00347900390625 +39215 -0.044647216796875 +39216 0.015045166015625 +39217 0.103973388671875 +39218 0.028045654296875 +39219 0.202392578125 +39220 0.03680419921875 +39221 0.264495849609375 +39222 0.0462646484375 +39223 0.338897705078125 +39224 0.0582275390625 +39225 0.443817138671875 +39226 0.069091796875 +39227 0.545074462890625 +39228 0.076263427734375 +39229 0.6173095703125 +39230 0.07891845703125 +39231 0.6524658203125 +39232 0.078460693359375 +39233 0.66339111328125 +39234 0.075653076171875 +39235 0.6561279296875 +39236 0.068084716796875 +39237 0.606781005859375 +39238 0.054443359375 +39239 0.501190185546875 +39240 0.036285400390625 +39241 0.352783203125 +39242 0.015350341796875 +39243 0.176544189453125 +39244 -0.00897216796875 +39245 -0.034820556640625 +39246 -0.03411865234375 +39247 -0.258209228515625 +39248 -0.0546875 +39249 -0.44244384765625 +39250 -0.069366455078125 +39251 -0.5753173828125 +39252 -0.077606201171875 +39253 -0.65203857421875 +39254 -0.076202392578125 +39255 -0.641632080078125 +39256 -0.067108154296875 +39257 -0.562164306640625 +39258 -0.05499267578125 +39259 -0.458038330078125 +39260 -0.042144775390625 +39261 -0.350555419921875 +39262 -0.03082275390625 +39263 -0.260528564453125 +39264 -0.021575927734375 +39265 -0.192108154296875 +39266 -0.014190673828125 +39267 -0.141937255859375 +39268 -0.007965087890625 +39269 -0.1021728515625 +39270 -0.001953125 +39271 -0.062896728515625 +39272 0.004974365234375 +39273 -0.011932373046875 +39274 0.014007568359375 +39275 0.062835693359375 +39276 0.023773193359375 +39277 0.148712158203125 +39278 0.0338134765625 +39279 0.241729736328125 +39280 0.04486083984375 +39281 0.34912109375 +39282 0.055511474609375 +39283 0.457305908203125 +39284 0.063507080078125 +39285 0.54388427734375 +39286 0.065185546875 +39287 0.5728759765625 +39288 0.056671142578125 +39289 0.506591796875 +39290 0.038726806640625 +39291 0.351226806640625 +39292 0.01556396484375 +39293 0.146514892578125 +39294 -0.007232666015625 +39295 -0.05523681640625 +39296 -0.025634765625 +39297 -0.21624755859375 +39298 -0.03936767578125 +39299 -0.334930419921875 +39300 -0.047515869140625 +39301 -0.402984619140625 +39302 -0.05218505859375 +39303 -0.4412841796875 +39304 -0.058135986328125 +39305 -0.49578857421875 +39306 -0.064727783203125 +39307 -0.5601806640625 +39308 -0.068450927734375 +39309 -0.600738525390625 +39310 -0.065887451171875 +39311 -0.584228515625 +39312 -0.0538330078125 +39313 -0.47930908203125 +39314 -0.031707763671875 +39315 -0.27935791015625 +39316 -0.002105712890625 +39317 -0.0089111328125 +39318 0.02825927734375 +39319 0.268798828125 +39320 0.051910400390625 +39321 0.482818603515625 +39322 0.065704345703125 +39323 0.60369873046875 +39324 0.071563720703125 +39325 0.650421142578125 +39326 0.07373046875 +39327 0.66400146484375 +39328 0.071868896484375 +39329 0.6414794921875 +39330 0.064910888671875 +39331 0.572540283203125 +39332 0.05706787109375 +39333 0.498138427734375 +39334 0.050567626953125 +39335 0.439453125 +39336 0.04327392578125 +39337 0.375518798828125 +39338 0.031890869140625 +39339 0.274505615234375 +39340 0.013641357421875 +39341 0.1087646484375 +39342 -0.00909423828125 +39343 -0.099395751953125 +39344 -0.032928466796875 +39345 -0.3182373046875 +39346 -0.05792236328125 +39347 -0.5489501953125 +39348 -0.082183837890625 +39349 -0.7738037109375 +39350 -0.10015869140625 +39351 -0.86383056640625 +39352 -0.1083984375 +39353 -0.870391845703125 +39354 -0.108673095703125 +39355 -0.86895751953125 +39356 -0.10235595703125 +39357 -0.861053466796875 +39358 -0.087677001953125 +39359 -0.765869140625 +39360 -0.0634765625 +39361 -0.5301513671875 +39362 -0.030487060546875 +39363 -0.214691162109375 +39364 0.006744384765625 +39365 0.137359619140625 +39366 0.0428466796875 +39367 0.474822998046875 +39368 0.0740966796875 +39369 0.76239013671875 +39370 0.097625732421875 +39371 0.867462158203125 +39372 0.113433837890625 +39373 0.870361328125 +39374 0.120269775390625 +39375 0.86480712890625 +39376 0.11865234375 +39377 0.831817626953125 +39378 0.111114501953125 +39379 0.677581787109375 +39380 0.0982666015625 +39381 0.495880126953125 +39382 0.08203125 +39383 0.30767822265625 +39384 0.062652587890625 +39385 0.116180419921875 +39386 0.036834716796875 +39387 -0.110748291015625 +39388 0.00384521484375 +39389 -0.381805419921875 +39390 -0.03179931640625 +39391 -0.6572265625 +39392 -0.063812255859375 +39393 -0.857421875 +39394 -0.087738037109375 +39395 -0.870391845703125 +39396 -0.102813720703125 +39397 -0.870391845703125 +39398 -0.11181640625 +39399 -0.86444091796875 +39400 -0.118438720703125 +39401 -0.85723876953125 +39402 -0.120758056640625 +39403 -0.790008544921875 +39404 -0.11309814453125 +39405 -0.62847900390625 +39406 -0.095123291015625 +39407 -0.3956298828125 +39408 -0.07025146484375 +39409 -0.126708984375 +39410 -0.04132080078125 +39411 0.150115966796875 +39412 -0.00958251953125 +39413 0.424041748046875 +39414 0.02215576171875 +39415 0.670623779296875 +39416 0.0498046875 +39417 0.854522705078125 +39418 0.071533203125 +39419 0.866485595703125 +39420 0.08575439453125 +39421 0.86920166015625 +39422 0.094329833984375 +39423 0.8653564453125 +39424 0.098907470703125 +39425 0.857147216796875 +39426 0.098907470703125 +39427 0.766845703125 +39428 0.094482421875 +39429 0.628509521484375 +39430 0.085205078125 +39431 0.462127685546875 +39432 0.0731201171875 +39433 0.297210693359375 +39434 0.059326171875 +39435 0.14862060546875 +39436 0.042510986328125 +39437 -0.00537109375 +39438 0.023590087890625 +39439 -0.15753173828125 +39440 0.002716064453125 +39441 -0.31304931640625 +39442 -0.02069091796875 +39443 -0.48876953125 +39444 -0.04290771484375 +39445 -0.6416015625 +39446 -0.0618896484375 +39447 -0.751373291015625 +39448 -0.07904052734375 +39449 -0.84619140625 +39450 -0.0931396484375 +39451 -0.861297607421875 +39452 -0.1016845703125 +39453 -0.863250732421875 +39454 -0.102386474609375 +39455 -0.856597900390625 +39456 -0.09625244140625 +39457 -0.7498779296875 +39458 -0.08758544921875 +39459 -0.624542236328125 +39460 -0.07501220703125 +39461 -0.47808837890625 +39462 -0.05462646484375 +39463 -0.253387451171875 +39464 -0.030029296875 +39465 0.003692626953125 +39466 -0.0064697265625 +39467 0.2257080078125 +39468 0.016632080078125 +39469 0.427154541015625 +39470 0.04132080078125 +39471 0.643218994140625 +39472 0.066619873046875 +39473 0.855926513671875 +39474 0.088165283203125 +39475 0.870361328125 +39476 0.102203369140625 +39477 0.870361328125 +39478 0.109161376953125 +39479 0.862762451171875 +39480 0.108856201171875 +39481 0.79669189453125 +39482 0.100677490234375 +39483 0.595794677734375 +39484 0.0867919921875 +39485 0.362152099609375 +39486 0.069427490234375 +39487 0.1270751953125 +39488 0.050323486328125 +39489 -0.086944580078125 +39490 0.02984619140625 +39491 -0.2784423828125 +39492 0.005767822265625 +39493 -0.484832763671875 +39494 -0.02301025390625 +39495 -0.729583740234375 +39496 -0.052581787109375 +39497 -0.86688232421875 +39498 -0.078125 +39499 -0.870391845703125 +39500 -0.099090576171875 +39501 -0.86859130859375 +39502 -0.115203857421875 +39503 -0.86279296875 +39504 -0.123809814453125 +39505 -0.817962646484375 +39506 -0.121612548828125 +39507 -0.6116943359375 +39508 -0.108123779296875 +39509 -0.3128662109375 +39510 -0.08587646484375 +39511 0.039398193359375 +39512 -0.05645751953125 +39513 0.422821044921875 +39514 -0.022430419921875 +39515 0.805145263671875 +39516 0.011077880859375 +39517 0.870361328125 +39518 0.039764404296875 +39519 0.870361328125 +39520 0.06256103515625 +39521 0.860015869140625 +39522 0.07867431640625 +39523 0.727935791015625 +39524 0.0875244140625 +39525 0.48114013671875 +39526 0.0906982421875 +39527 0.2059326171875 +39528 0.08966064453125 +39529 -0.06103515625 +39530 0.0850830078125 +39531 -0.29913330078125 +39532 0.075836181640625 +39533 -0.516204833984375 +39534 0.06085205078125 +39535 -0.7252197265625 +39536 0.041961669921875 +39537 -0.85980224609375 +39538 0.021728515625 +39539 -0.870391845703125 +39540 0.00244140625 +39541 -0.870391845703125 +39542 -0.012176513671875 +39543 -0.858062744140625 +39544 -0.021636962890625 +39545 -0.673004150390625 +39546 -0.029541015625 +39547 -0.42694091796875 +39548 -0.03887939453125 +39549 -0.2100830078125 +39550 -0.04925537109375 +39551 -0.0362548828125 +39552 -0.058441162109375 +39553 0.10943603515625 +39554 -0.0648193359375 +39555 0.23516845703125 +39556 -0.065338134765625 +39557 0.373687744140625 +39558 -0.060089111328125 +39559 0.517791748046875 +39560 -0.053619384765625 +39561 0.602783203125 +39562 -0.045562744140625 +39563 0.635711669921875 +39564 -0.03363037109375 +39565 0.655181884765625 +39566 -0.0186767578125 +39567 0.65948486328125 +39568 -0.00140380859375 +39569 0.651275634765625 +39570 0.016204833984375 +39571 0.61846923828125 +39572 0.03131103515625 +39573 0.53753662109375 +39574 0.04241943359375 +39575 0.404144287109375 +39576 0.048675537109375 +39577 0.22186279296875 +39578 0.050048828125 +39579 0.003997802734375 +39580 0.0477294921875 +39581 -0.22100830078125 +39582 0.043121337890625 +39583 -0.42449951171875 +39584 0.03765869140625 +39585 -0.579833984375 +39586 0.034423828125 +39587 -0.641876220703125 +39588 0.032958984375 +39589 -0.6177978515625 +39590 0.0286865234375 +39591 -0.575531005859375 +39592 0.021270751953125 +39593 -0.526336669921875 +39594 0.01458740234375 +39595 -0.42645263671875 +39596 0.010711669921875 +39597 -0.2581787109375 +39598 0.007232666015625 +39599 -0.068695068359375 +39600 0.001495361328125 +39601 0.09222412109375 +39602 -0.00494384765625 +39603 0.232147216796875 +39604 -0.01123046875 +39605 0.3509521484375 +39606 -0.019378662109375 +39607 0.410064697265625 +39608 -0.031402587890625 +39609 0.372955322265625 +39610 -0.04571533203125 +39611 0.2554931640625 +39612 -0.058563232421875 +39613 0.10711669921875 +39614 -0.068511962890625 +39615 -0.052886962890625 +39616 -0.073028564453125 +39617 -0.186279296875 +39618 -0.068145751953125 +39619 -0.23291015625 +39620 -0.055633544921875 +39621 -0.209442138671875 +39622 -0.04034423828125 +39623 -0.174163818359375 +39624 -0.02301025390625 +39625 -0.126739501953125 +39626 -0.0030517578125 +39627 -0.048126220703125 +39628 0.017333984375 +39629 0.0426025390625 +39630 0.03466796875 +39631 0.10748291015625 +39632 0.047882080078125 +39633 0.1409912109375 +39634 0.060333251953125 +39635 0.19708251953125 +39636 0.07147216796875 +39637 0.273651123046875 +39638 0.0772705078125 +39639 0.31768798828125 +39640 0.07855224609375 +39641 0.341094970703125 +39642 0.077178955078125 +39643 0.368011474609375 +39644 0.071533203125 +39645 0.37249755859375 +39646 0.058135986328125 +39647 0.30072021484375 +39648 0.037445068359375 +39649 0.1517333984375 +39650 0.01434326171875 +39651 -0.01470947265625 +39652 -0.009765625 +39653 -0.1883544921875 +39654 -0.03448486328125 +39655 -0.372711181640625 +39656 -0.0552978515625 +39657 -0.51397705078125 +39658 -0.068756103515625 +39659 -0.57177734375 +39660 -0.07391357421875 +39661 -0.53948974609375 +39662 -0.071746826171875 +39663 -0.43511962890625 +39664 -0.064727783203125 +39665 -0.2962646484375 +39666 -0.05548095703125 +39667 -0.161102294921875 +39668 -0.045074462890625 +39669 -0.0435791015625 +39670 -0.033355712890625 +39671 0.060394287109375 +39672 -0.02166748046875 +39673 0.13665771484375 +39674 -0.011505126953125 +39675 0.170135498046875 +39676 -0.002960205078125 +39677 0.16552734375 +39678 0.005889892578125 +39679 0.15728759765625 +39680 0.015045166015625 +39681 0.150787353515625 +39682 0.022308349609375 +39683 0.12200927734375 +39684 0.027557373046875 +39685 0.080108642578125 +39686 0.0318603515625 +39687 0.05126953125 +39688 0.03643798828125 +39689 0.062896728515625 +39690 0.040069580078125 +39691 0.09271240234375 +39692 0.04034423828125 +39693 0.092987060546875 +39694 0.038055419921875 +39695 0.07855224609375 +39696 0.034088134765625 +39697 0.06427001953125 +39698 0.02789306640625 +39699 0.0347900390625 +39700 0.0196533203125 +39701 -0.01171875 +39702 0.01068115234375 +39703 -0.056060791015625 +39704 0.003448486328125 +39705 -0.055511474609375 +39706 -0.0015869140625 +39707 -0.010467529296875 +39708 -0.00677490234375 +39709 0.02508544921875 +39710 -0.013031005859375 +39711 0.025665283203125 +39712 -0.01873779296875 +39713 0.017333984375 +39714 -0.0235595703125 +39715 0.00189208984375 +39716 -0.027862548828125 +39717 -0.03173828125 +39718 -0.03094482421875 +39719 -0.071502685546875 +39720 -0.03369140625 +39721 -0.13543701171875 +39722 -0.035980224609375 +39723 -0.219970703125 +39724 -0.036712646484375 +39725 -0.300506591796875 +39726 -0.03607177734375 +39727 -0.376312255859375 +39728 -0.032806396484375 +39729 -0.416107177734375 +39730 -0.0247802734375 +39731 -0.371124267578125 +39732 -0.012359619140625 +39733 -0.242279052734375 +39734 0.0020751953125 +39735 -0.069732666015625 +39736 0.017181396484375 +39737 0.125640869140625 +39738 0.0311279296875 +39739 0.31268310546875 +39740 0.041839599609375 +39741 0.45501708984375 +39742 0.04925537109375 +39743 0.554779052734375 +39744 0.053253173828125 +39745 0.61065673828125 +39746 0.053192138671875 +39747 0.610931396484375 +39748 0.04791259765625 +39749 0.531463623046875 +39750 0.038330078125 +39751 0.3883056640625 +39752 0.027252197265625 +39753 0.23468017578125 +39754 0.01617431640625 +39755 0.095245361328125 +39756 0.006622314453125 +39757 -0.00396728515625 +39758 -0.00042724609375 +39759 -0.04852294921875 +39760 -0.005523681640625 +39761 -0.055145263671875 +39762 -0.011016845703125 +39763 -0.0758056640625 +39764 -0.01806640625 +39765 -0.138702392578125 +39766 -0.024749755859375 +39767 -0.209197998046875 +39768 -0.030975341796875 +39769 -0.289031982421875 +39770 -0.036712646484375 +39771 -0.37884521484375 +39772 -0.040802001953125 +39773 -0.456329345703125 +39774 -0.04302978515625 +39775 -0.51641845703125 +39776 -0.04144287109375 +39777 -0.519287109375 +39778 -0.03582763671875 +39779 -0.458251953125 +39780 -0.0289306640625 +39781 -0.384796142578125 +39782 -0.022186279296875 +39783 -0.323699951171875 +39784 -0.0155029296875 +39785 -0.269287109375 +39786 -0.007781982421875 +39787 -0.1951904296875 +39788 0.000762939453125 +39789 -0.100006103515625 +39790 0.00860595703125 +39791 -0.01055908203125 +39792 0.017059326171875 +39793 0.1033935546875 +39794 0.0263671875 +39795 0.24908447265625 +39796 0.033782958984375 +39797 0.373199462890625 +39798 0.038360595703125 +39799 0.45806884765625 +39800 0.040496826171875 +39801 0.511474609375 +39802 0.041839599609375 +39803 0.565399169921875 +39804 0.042083740234375 +39805 0.61138916015625 +39806 0.038360595703125 +39807 0.5897216796875 +39808 0.03033447265625 +39809 0.4906005859375 +39810 0.019073486328125 +39811 0.33148193359375 +39812 0.006561279296875 +39813 0.147796630859375 +39814 -0.004913330078125 +39815 -0.01873779296875 +39816 -0.0137939453125 +39817 -0.140289306640625 +39818 -0.018707275390625 +39819 -0.191986083984375 +39820 -0.02008056640625 +39821 -0.184295654296875 +39822 -0.020050048828125 +39823 -0.161834716796875 +39824 -0.02069091796875 +39825 -0.166595458984375 +39826 -0.021728515625 +39827 -0.19390869140625 +39828 -0.02227783203125 +39829 -0.22442626953125 +39830 -0.023468017578125 +39831 -0.279754638671875 +39832 -0.02435302734375 +39833 -0.3389892578125 +39834 -0.022674560546875 +39835 -0.3543701171875 +39836 -0.019683837890625 +39837 -0.348175048828125 +39838 -0.01580810546875 +39839 -0.32598876953125 +39840 -0.009735107421875 +39841 -0.2581787109375 +39842 -0.0013427734375 +39843 -0.139801025390625 +39844 0.00848388671875 +39845 0.014617919921875 +39846 0.016571044921875 +39847 0.144378662109375 +39848 0.02142333984375 +39849 0.221038818359375 +39850 0.024322509765625 +39851 0.27069091796875 +39852 0.025299072265625 +39853 0.294036865234375 +39854 0.025421142578125 +39855 0.311767578125 +39856 0.025482177734375 +39857 0.339141845703125 +39858 0.024658203125 +39859 0.360260009765625 +39860 0.022369384765625 +39861 0.360504150390625 +39862 0.017547607421875 +39863 0.308380126953125 +39864 0.00946044921875 +39865 0.18170166015625 +39866 -0.00067138671875 +39867 0.0047607421875 +39868 -0.010772705078125 +39869 -0.17559814453125 +39870 -0.01885986328125 +39871 -0.3143310546875 +39872 -0.0230712890625 +39873 -0.36785888671875 +39874 -0.02435302734375 +39875 -0.36248779296875 +39876 -0.02447509765625 +39877 -0.343536376953125 +39878 -0.023040771484375 +39879 -0.3018798828125 +39880 -0.01983642578125 +39881 -0.231414794921875 +39882 -0.014312744140625 +39883 -0.117645263671875 +39884 -0.007843017578125 +39885 0.007049560546875 +39886 -0.002716064453125 +39887 0.087982177734375 +39888 0.00152587890625 +39889 0.13946533203125 +39890 0.005279541015625 +39891 0.17425537109375 +39892 0.008209228515625 +39893 0.188201904296875 +39894 0.009796142578125 +39895 0.171234130859375 +39896 0.009735107421875 +39897 0.118438720703125 +39898 0.009033203125 +39899 0.05706787109375 +39900 0.0076904296875 +39901 -0.010711669921875 +39902 0.00537109375 +39903 -0.0914306640625 +39904 0.0029296875 +39905 -0.162322998046875 +39906 0.00152587890625 +39907 -0.194549560546875 +39908 0.002716064453125 +39909 -0.1492919921875 +39910 0.0067138671875 +39911 -0.02166748046875 +39912 0.011016845703125 +39913 0.124053955078125 +39914 0.012664794921875 +39915 0.211151123046875 +39916 0.011810302734375 +39917 0.240447998046875 +39918 0.009765625 +39919 0.242218017578125 +39920 0.007049560546875 +39921 0.2257080078125 +39922 0.00390625 +39923 0.194366455078125 +39924 -0.0008544921875 +39925 0.115509033203125 +39926 -0.006134033203125 +39927 0.0128173828125 +39928 -0.009521484375 +39929 -0.053802490234375 +39930 -0.012054443359375 +39931 -0.110626220703125 +39932 -0.015411376953125 +39933 -0.199493408203125 +39934 -0.018585205078125 +39935 -0.29437255859375 +39936 -0.01947021484375 +39937 -0.33221435546875 +39938 -0.01751708984375 +39939 -0.27972412109375 +39940 -0.013671875 +39941 -0.185333251953125 +39942 -0.00909423828125 +39943 -0.128204345703125 +39944 -0.004302978515625 +39945 -0.115692138671875 +39946 0.000457763671875 +39947 -0.116455078125 +39948 0.005035400390625 +39949 -0.105926513671875 +39950 0.0093994140625 +39951 -0.053955078125 +39952 0.01336669921875 +39953 0.048797607421875 +39954 0.01641845703125 +39955 0.157318115234375 +39956 0.01800537109375 +39957 0.212005615234375 +39958 0.018157958984375 +39959 0.218475341796875 +39960 0.01739501953125 +39961 0.23724365234375 +39962 0.01611328125 +39963 0.30535888671875 +39964 0.01409912109375 +39965 0.38128662109375 +39966 0.011077880859375 +39967 0.404449462890625 +39968 0.007415771484375 +39969 0.3944091796875 +39970 0.003631591796875 +39971 0.3885498046875 +39972 -0.000213623046875 +39973 0.362640380859375 +39974 -0.0042724609375 +39975 0.27362060546875 +39976 -0.008392333984375 +39977 0.11712646484375 +39978 -0.011993408203125 +39979 -0.054901123046875 +39980 -0.014556884765625 +39981 -0.19085693359375 +39982 -0.0159912109375 +39983 -0.28570556640625 +39984 -0.01629638671875 +39985 -0.339263916015625 +39986 -0.015716552734375 +39987 -0.3775634765625 +39988 -0.014678955078125 +39989 -0.445709228515625 +39990 -0.01318359375 +39991 -0.535064697265625 +39992 -0.01129150390625 +39993 -0.629058837890625 +39994 -0.008880615234375 +39995 -0.697601318359375 +39996 -0.005828857421875 +39997 -0.70391845703125 +39998 -0.002288818359375 +39999 -0.6424560546875 +40000 0.001708984375 +40001 -0.491241455078125 +40002 0.00592041015625 +40003 -0.265716552734375 +40004 0.009735107421875 +40005 -0.023712158203125 +40006 0.012786865234375 +40007 0.201751708984375 +40008 0.0147705078125 +40009 0.375823974609375 +40010 0.015594482421875 +40011 0.485076904296875 +40012 0.015594482421875 +40013 0.56884765625 +40014 0.014862060546875 +40015 0.634765625 +40016 0.01312255859375 +40017 0.63763427734375 +40018 0.010406494140625 +40019 0.5660400390625 +40020 0.00726318359375 +40021 0.4720458984375 +40022 0.004241943359375 +40023 0.40692138671875 +40024 0.00152587890625 +40025 0.3778076171875 +40026 -0.000823974609375 +40027 0.376953125 +40028 -0.0029296875 +40029 0.371978759765625 +40030 -0.005096435546875 +40031 0.313140869140625 +40032 -0.00732421875 +40033 0.184417724609375 +40034 -0.009368896484375 +40035 0.011199951171875 +40036 -0.010894775390625 +40037 -0.171051025390625 +40038 -0.01171875 +40039 -0.33740234375 +40040 -0.011749267578125 +40041 -0.47198486328125 +40042 -0.010955810546875 +40043 -0.560394287109375 +40044 -0.009246826171875 +40045 -0.58056640625 +40046 -0.00689697265625 +40047 -0.54754638671875 +40048 -0.004425048828125 +40049 -0.508575439453125 +40050 -0.00189208984375 +40051 -0.459503173828125 +40052 0.0006103515625 +40053 -0.394378662109375 +40054 0.002685546875 +40055 -0.35260009765625 +40056 0.00439453125 +40057 -0.31170654296875 +40058 0.00628662109375 +40059 -0.197418212890625 +40060 0.00830078125 +40061 -0.007965087890625 +40062 0.010040283203125 +40063 0.207489013671875 +40064 0.01116943359375 +40065 0.409210205078125 +40066 0.011566162109375 +40067 0.57208251953125 +40068 0.01104736328125 +40069 0.66595458984375 +40070 0.00946044921875 +40071 0.65875244140625 +40072 0.00701904296875 +40073 0.56744384765625 +40074 0.004150390625 +40075 0.431396484375 +40076 0.00128173828125 +40077 0.29443359375 +40078 -0.001251220703125 +40079 0.182464599609375 +40080 -0.00360107421875 +40081 0.06365966796875 +40082 -0.005828857421875 +40083 -0.075958251953125 +40084 -0.00750732421875 +40085 -0.189422607421875 +40086 -0.008544921875 +40087 -0.271942138671875 +40088 -0.009063720703125 +40089 -0.342529296875 +40090 -0.00885009765625 +40091 -0.364166259765625 +40092 -0.007843017578125 +40093 -0.327239990234375 +40094 -0.006439208984375 +40095 -0.2769775390625 +40096 -0.005035400390625 +40097 -0.253692626953125 +40098 -0.00360107421875 +40099 -0.24365234375 +40100 -0.001800537109375 +40101 -0.1983642578125 +40102 0.000244140625 +40103 -0.116241455078125 +40104 0.002166748046875 +40105 -0.036834716796875 +40106 0.00384521484375 +40107 0.034881591796875 +40108 0.00518798828125 +40109 0.09124755859375 +40110 0.0059814453125 +40111 0.10888671875 +40112 0.006500244140625 +40113 0.125518798828125 +40114 0.0068359375 +40115 0.15771484375 +40116 0.00677490234375 +40117 0.17828369140625 +40118 0.006195068359375 +40119 0.17108154296875 +40120 0.005126953125 +40121 0.129974365234375 +40122 0.003814697265625 +40123 0.082427978515625 +40124 0.002288818359375 +40125 0.027679443359375 +40126 0.000396728515625 +40127 -0.065643310546875 +40128 -0.00146484375 +40129 -0.15936279296875 +40130 -0.0029296875 +40131 -0.21307373046875 +40132 -0.0040283203125 +40133 -0.234649658203125 +40134 -0.0045166015625 +40135 -0.2001953125 +40136 -0.004425048828125 +40137 -0.119171142578125 +40138 -0.003997802734375 +40139 -0.024749755859375 +40140 -0.003173828125 +40141 0.085784912109375 +40142 -0.002288818359375 +40143 0.178131103515625 +40144 -0.001617431640625 +40145 0.215576171875 +40146 -0.0010986328125 +40147 0.211456298828125 +40148 -0.00067138671875 +40149 0.17523193359375 +40150 -0.00018310546875 +40151 0.128753662109375 +40152 0.00054931640625 +40153 0.1019287109375 +40154 0.001251220703125 +40155 0.0743408203125 +40156 0.001861572265625 +40157 0.04327392578125 +40158 0.002593994140625 +40159 0.038177490234375 +40160 0.00347900390625 +40161 0.076263427734375 +40162 0.00439453125 +40163 0.14105224609375 +40164 0.00494384765625 +40165 0.186431884765625 +40166 0.00494384765625 +40167 0.188812255859375 +40168 0.00433349609375 +40169 0.1390380859375 +40170 0.003173828125 +40171 0.041778564453125 +40172 0.001708984375 +40173 -0.079437255859375 +40174 0.0 +40175 -0.219390869140625 +40176 -0.001800537109375 +40177 -0.367828369140625 +40178 -0.00341796875 +40179 -0.494873046875 +40180 -0.004486083984375 +40181 -0.556243896484375 +40182 -0.004638671875 +40183 -0.508697509765625 +40184 -0.0040283203125 +40185 -0.3756103515625 +40186 -0.00311279296875 +40187 -0.218902587890625 +40188 -0.00213623046875 +40189 -0.063751220703125 +40190 -0.001068115234375 +40191 0.091552734375 +40192 3.0517578125e-05 +40193 0.23602294921875 +40194 0.000946044921875 +40195 0.342987060546875 +40196 0.00140380859375 +40197 0.39520263671875 +40198 0.001251220703125 +40199 0.389373779296875 +40200 0.000335693359375 +40201 0.324249267578125 +40202 -0.000885009765625 +40203 0.224090576171875 +40204 -0.001739501953125 +40205 0.124267578125 +40206 -0.002044677734375 +40207 0.037078857421875 +40208 -0.00128173828125 +40209 -0.010101318359375 +40210 0.000335693359375 +40211 -0.019439697265625 +40212 0.001953125 +40213 -0.022796630859375 +40214 0.003936767578125 +40215 -0.001556396484375 +40216 0.006439208984375 +40217 0.056304931640625 +40218 0.008392333984375 +40219 0.106719970703125 +40220 0.008514404296875 +40221 0.096893310546875 +40222 0.0072021484375 +40223 0.042694091796875 +40224 0.005401611328125 +40225 -0.018035888671875 +40226 0.00335693359375 +40227 -0.07586669921875 +40228 0.00140380859375 +40229 -0.11944580078125 +40230 -0.00067138671875 +40231 -0.15972900390625 +40232 -0.0029296875 +40233 -0.202606201171875 +40234 -0.0052490234375 +40235 -0.24859619140625 +40236 -0.007781982421875 +40237 -0.30517578125 +40238 -0.010223388671875 +40239 -0.36212158203125 +40240 -0.011871337890625 +40241 -0.39141845703125 +40242 -0.011749267578125 +40243 -0.35528564453125 +40244 -0.009735107421875 +40245 -0.249969482421875 +40246 -0.0062255859375 +40247 -0.092864990234375 +40248 -0.00189208984375 +40249 0.08905029296875 +40250 0.001800537109375 +40251 0.2352294921875 +40252 0.004180908203125 +40253 0.318817138671875 +40254 0.005706787109375 +40255 0.358642578125 +40256 0.00616455078125 +40257 0.347747802734375 +40258 0.005462646484375 +40259 0.28564453125 +40260 0.00482177734375 +40261 0.223175048828125 +40262 0.005035400390625 +40263 0.196746826171875 +40264 0.00543212890625 +40265 0.179840087890625 +40266 0.005584716796875 +40267 0.155548095703125 +40268 0.006072998046875 +40269 0.151214599609375 +40270 0.00665283203125 +40271 0.156951904296875 +40272 0.006317138671875 +40273 0.13177490234375 +40274 0.005645751953125 +40275 0.100799560546875 +40276 0.005218505859375 +40277 0.087127685546875 +40278 0.004180908203125 +40279 0.05487060546875 +40280 0.002227783203125 +40281 -0.009002685546875 +40282 -0.00054931640625 +40283 -0.10400390625 +40284 -0.004150390625 +40285 -0.229400634765625 +40286 -0.0078125 +40287 -0.35552978515625 +40288 -0.010498046875 +40289 -0.441925048828125 +40290 -0.011810302734375 +40291 -0.473846435546875 +40292 -0.0120849609375 +40293 -0.464813232421875 +40294 -0.011383056640625 +40295 -0.419097900390625 +40296 -0.0096435546875 +40297 -0.334320068359375 +40298 -0.00726318359375 +40299 -0.227935791015625 +40300 -0.004791259765625 +40301 -0.12347412109375 +40302 -0.00238037109375 +40303 -0.02764892578125 +40304 0.0003662109375 +40305 0.077667236328125 +40306 0.00390625 +40307 0.2132568359375 +40308 0.008453369140625 +40309 0.38885498046875 +40310 0.01348876953125 +40311 0.582794189453125 +40312 0.01751708984375 +40313 0.734039306640625 +40314 0.01947021484375 +40315 0.800140380859375 +40316 0.019256591796875 +40317 0.7783203125 +40318 0.016815185546875 +40319 0.6651611328125 +40320 0.012115478515625 +40321 0.45965576171875 +40322 0.006072998046875 +40323 0.199188232421875 +40324 0.000244140625 +40325 -0.050689697265625 +40326 -0.003997802734375 +40327 -0.23297119140625 +40328 -0.006256103515625 +40329 -0.33013916015625 +40330 -0.007171630859375 +40331 -0.368408203125 +40332 -0.007476806640625 +40333 -0.378936767578125 +40334 -0.007568359375 +40335 -0.376983642578125 +40336 -0.007843017578125 +40337 -0.37969970703125 +40338 -0.00836181640625 +40339 -0.391510009765625 +40340 -0.008453369140625 +40341 -0.385345458984375 +40342 -0.007659912109375 +40343 -0.3419189453125 +40344 -0.0064697265625 +40345 -0.28289794921875 +40346 -0.00592041015625 +40347 -0.251617431640625 +40348 -0.006439208984375 +40349 -0.266143798828125 +40350 -0.006744384765625 +40351 -0.273345947265625 +40352 -0.0054931640625 +40353 -0.216796875 +40354 -0.003448486328125 +40355 -0.128265380859375 +40356 -0.00201416015625 +40357 -0.068145751953125 +40358 -0.0013427734375 +40359 -0.0430908203125 +40360 -0.000762939453125 +40361 -0.024444580078125 +40362 0.000457763671875 +40363 0.020721435546875 +40364 0.003082275390625 +40365 0.124481201171875 +40366 0.00640869140625 +40367 0.25787353515625 +40368 0.0093994140625 +40369 0.379119873046875 +40370 0.011871337890625 +40371 0.47991943359375 +40372 0.0130615234375 +40373 0.5281982421875 +40374 0.01263427734375 +40375 0.511138916015625 +40376 0.01129150390625 +40377 0.456207275390625 +40378 0.01007080078125 +40379 0.407470703125 +40380 0.009429931640625 +40381 0.383758544921875 +40382 0.008636474609375 +40383 0.35687255859375 +40384 0.00738525390625 +40385 0.31182861328125 +40386 0.0057373046875 +40387 0.250885009765625 +40388 0.0035400390625 +40389 0.1654052734375 +40390 0.00030517578125 +40391 0.035247802734375 +40392 -0.00396728515625 +40393 -0.142059326171875 +40394 -0.008544921875 +40395 -0.33563232421875 +40396 -0.01318359375 +40397 -0.5345458984375 +40398 -0.01751708984375 +40399 -0.72186279296875 +40400 -0.02001953125 +40401 -0.836669921875 +40402 -0.019622802734375 +40403 -0.8326416015625 +40404 -0.016845703125 +40405 -0.7296142578125 +40406 -0.0130615234375 +40407 -0.582550048828125 +40408 -0.009429931640625 +40409 -0.440093994140625 +40410 -0.006500244140625 +40411 -0.324310302734375 +40412 -0.00341796875 +40413 -0.20147705078125 +40414 0.00042724609375 +40415 -0.044647216796875 +40416 0.003997802734375 +40417 0.103973388671875 +40418 0.006256103515625 +40419 0.202392578125 +40420 0.007568359375 +40421 0.264495849609375 +40422 0.009124755859375 +40423 0.338897705078125 +40424 0.0113525390625 +40425 0.443817138671875 +40426 0.013458251953125 +40427 0.545074462890625 +40428 0.014862060546875 +40429 0.6173095703125 +40430 0.015380859375 +40431 0.6524658203125 +40432 0.01531982421875 +40433 0.66339111328125 +40434 0.014862060546875 +40435 0.6561279296875 +40436 0.013427734375 +40437 0.606781005859375 +40438 0.01068115234375 +40439 0.501190185546875 +40440 0.006988525390625 +40441 0.352783203125 +40442 0.002685546875 +40443 0.176544189453125 +40444 -0.0023193359375 +40445 -0.034820556640625 +40446 -0.007476806640625 +40447 -0.258209228515625 +40448 -0.011383056640625 +40449 -0.44244384765625 +40450 -0.013946533203125 +40451 -0.5753173828125 +40452 -0.01495361328125 +40453 -0.65203857421875 +40454 -0.0126953125 +40455 -0.641632080078125 +40456 -0.008056640625 +40457 -0.562164306640625 +40458 -0.00341796875 +40459 -0.458038330078125 +40460 0.000213623046875 +40461 -0.350555419921875 +40462 0.00189208984375 +40463 -0.260528564453125 +40464 0.001617431640625 +40465 -0.192108154296875 +40466 -0.0001220703125 +40467 -0.141937255859375 +40468 -0.00262451171875 +40469 -0.1021728515625 +40470 -0.005096435546875 +40471 -0.062896728515625 +40472 -0.006591796875 +40473 -0.011932373046875 +40474 -0.0062255859375 +40475 0.062835693359375 +40476 -0.0045166015625 +40477 0.148712158203125 +40478 -0.0015869140625 +40479 0.241729736328125 +40480 0.0030517578125 +40481 0.34912109375 +40482 0.0086669921875 +40483 0.457305908203125 +40484 0.014007568359375 +40485 0.54388427734375 +40486 0.016998291015625 +40487 0.5728759765625 +40488 0.01544189453125 +40489 0.506591796875 +40490 0.009552001953125 +40491 0.351226806640625 +40492 0.001373291015625 +40493 0.146514892578125 +40494 -0.00634765625 +40495 -0.05523681640625 +40496 -0.011688232421875 +40497 -0.21624755859375 +40498 -0.014739990234375 +40499 -0.334930419921875 +40500 -0.01519775390625 +40501 -0.402984619140625 +40502 -0.01446533203125 +40503 -0.4412841796875 +40504 -0.0152587890625 +40505 -0.49578857421875 +40506 -0.017333984375 +40507 -0.5601806640625 +40508 -0.01885986328125 +40509 -0.600738525390625 +40510 -0.01800537109375 +40511 -0.584228515625 +40512 -0.012969970703125 +40513 -0.47930908203125 +40514 -0.003326416015625 +40515 -0.27935791015625 +40516 0.0096435546875 +40517 -0.0089111328125 +40518 0.02252197265625 +40519 0.268798828125 +40520 0.031494140625 +40521 0.482818603515625 +40522 0.03509521484375 +40523 0.60369873046875 +40524 0.0345458984375 +40525 0.650421142578125 +40526 0.0323486328125 +40527 0.66400146484375 +40528 0.028472900390625 +40529 0.6414794921875 +40530 0.0224609375 +40531 0.572540283203125 +40532 0.0167236328125 +40533 0.498138427734375 +40534 0.01251220703125 +40535 0.439453125 +40536 0.008697509765625 +40537 0.375518798828125 +40538 0.003509521484375 +40539 0.274505615234375 +40540 -0.004638671875 +40541 0.1087646484375 +40542 -0.01458740234375 +40543 -0.099395751953125 +40544 -0.024658203125 +40545 -0.3182373046875 +40546 -0.035064697265625 +40547 -0.5489501953125 +40548 -0.044921875 +40549 -0.7738037109375 +40550 -0.051422119140625 +40551 -0.86383056640625 +40552 -0.052886962890625 +40553 -0.870391845703125 +40554 -0.050445556640625 +40555 -0.86895751953125 +40556 -0.044952392578125 +40557 -0.861053466796875 +40558 -0.0355224609375 +40559 -0.765869140625 +40560 -0.021636962890625 +40561 -0.5301513671875 +40562 -0.00372314453125 +40563 -0.214691162109375 +40564 0.015777587890625 +40565 0.137359619140625 +40566 0.034027099609375 +40567 0.474822998046875 +40568 0.049102783203125 +40569 0.76239013671875 +40570 0.0595703125 +40571 0.867462158203125 +40572 0.065582275390625 +40573 0.870361328125 +40574 0.066558837890625 +40575 0.86480712890625 +40576 0.062957763671875 +40577 0.831817626953125 +40578 0.056304931640625 +40579 0.677581787109375 +40580 0.047027587890625 +40581 0.495880126953125 +40582 0.03631591796875 +40583 0.30767822265625 +40584 0.0244140625 +40585 0.116180419921875 +40586 0.00958251953125 +40587 -0.110748291015625 +40588 -0.00848388671875 +40589 -0.381805419921875 +40590 -0.027374267578125 +40591 -0.6572265625 +40592 -0.043731689453125 +40593 -0.857421875 +40594 -0.055206298828125 +40595 -0.870391845703125 +40596 -0.061492919921875 +40597 -0.870391845703125 +40598 -0.064208984375 +40599 -0.86444091796875 +40600 -0.06549072265625 +40601 -0.85723876953125 +40602 -0.064422607421875 +40603 -0.790008544921875 +40604 -0.05810546875 +40605 -0.62847900390625 +40606 -0.046417236328125 +40607 -0.3956298828125 +40608 -0.03131103515625 +40609 -0.126708984375 +40610 -0.014434814453125 +40611 0.150115966796875 +40612 0.00347900390625 +40613 0.424041748046875 +40614 0.020904541015625 +40615 0.670623779296875 +40616 0.03564453125 +40617 0.854522705078125 +40618 0.046722412109375 +40619 0.866485595703125 +40620 0.053314208984375 +40621 0.86920166015625 +40622 0.0565185546875 +40623 0.8653564453125 +40624 0.05712890625 +40625 0.857147216796875 +40626 0.05511474609375 +40627 0.766845703125 +40628 0.050872802734375 +40629 0.628509521484375 +40630 0.044097900390625 +40631 0.462127685546875 +40632 0.03631591796875 +40633 0.297210693359375 +40634 0.028289794921875 +40635 0.14862060546875 +40636 0.01885986328125 +40637 -0.00537109375 +40638 0.00848388671875 +40639 -0.15753173828125 +40640 -0.002960205078125 +40641 -0.31304931640625 +40642 -0.016204833984375 +40643 -0.48876953125 +40644 -0.02862548828125 +40645 -0.6416015625 +40646 -0.03887939453125 +40647 -0.751373291015625 +40648 -0.048309326171875 +40649 -0.84619140625 +40650 -0.056182861328125 +40651 -0.861297607421875 +40652 -0.060699462890625 +40653 -0.863250732421875 +40654 -0.0601806640625 +40655 -0.856597900390625 +40656 -0.055419921875 +40657 -0.7498779296875 +40658 -0.04974365234375 +40659 -0.624542236328125 +40660 -0.042022705078125 +40661 -0.47808837890625 +40662 -0.029052734375 +40663 -0.253387451171875 +40664 -0.013458251953125 +40665 0.003692626953125 +40666 0.000885009765625 +40667 0.2257080078125 +40668 0.014678955078125 +40669 0.427154541015625 +40670 0.029693603515625 +40671 0.643218994140625 +40672 0.04541015625 +40673 0.855926513671875 +40674 0.05865478515625 +40675 0.870361328125 +40676 0.06671142578125 +40677 0.870361328125 +40678 0.070068359375 +40679 0.862762451171875 +40680 0.068634033203125 +40681 0.79669189453125 +40682 0.06195068359375 +40683 0.595794677734375 +40684 0.0517578125 +40685 0.362152099609375 +40686 0.039703369140625 +40687 0.1270751953125 +40688 0.027008056640625 +40689 -0.086944580078125 +40690 0.01385498046875 +40691 -0.2784423828125 +40692 -0.001617431640625 +40693 -0.484832763671875 +40694 -0.020477294921875 +40695 -0.729583740234375 +40696 -0.0399169921875 +40697 -0.86688232421875 +40698 -0.056396484375 +40699 -0.870391845703125 +40700 -0.06964111328125 +40701 -0.86859130859375 +40702 -0.07958984375 +40703 -0.86279296875 +40704 -0.084381103515625 +40705 -0.817962646484375 +40706 -0.081207275390625 +40707 -0.6116943359375 +40708 -0.069488525390625 +40709 -0.3128662109375 +40710 -0.051361083984375 +40711 0.039398193359375 +40712 -0.0277099609375 +40713 0.422821044921875 +40714 -0.000640869140625 +40715 0.805145263671875 +40716 0.024688720703125 +40717 0.870361328125 +40718 0.044036865234375 +40719 0.870361328125 +40720 0.057037353515625 +40721 0.860015869140625 +40722 0.0635986328125 +40723 0.727935791015625 +40724 0.06365966796875 +40725 0.48114013671875 +40726 0.05963134765625 +40727 0.2059326171875 +40728 0.053680419921875 +40729 -0.06103515625 +40730 0.04669189453125 +40731 -0.29913330078125 +40732 0.03729248046875 +40733 -0.516204833984375 +40734 0.02392578125 +40735 -0.7252197265625 +40736 0.00848388671875 +40737 -0.85980224609375 +40738 -0.00640869140625 +40739 -0.870391845703125 +40740 -0.0185546875 +40741 -0.870391845703125 +40742 -0.024169921875 +40743 -0.858062744140625 +40744 -0.023345947265625 +40745 -0.673004150390625 +40746 -0.021148681640625 +40747 -0.42694091796875 +40748 -0.0218505859375 +40749 -0.2100830078125 +40750 -0.02557373046875 +40751 -0.0362548828125 +40752 -0.029998779296875 +40753 0.10943603515625 +40754 -0.033447265625 +40755 0.23516845703125 +40756 -0.0323486328125 +40757 0.373687744140625 +40758 -0.02685546875 +40759 0.517791748046875 +40760 -0.022369384765625 +40761 0.602783203125 +40762 -0.01824951171875 +40763 0.635711669921875 +40764 -0.01129150390625 +40765 0.655181884765625 +40766 -0.00201416015625 +40767 0.65948486328125 +40768 0.009185791015625 +40769 0.651275634765625 +40770 0.020477294921875 +40771 0.61846923828125 +40772 0.0289306640625 +40773 0.53753662109375 +40774 0.033294677734375 +40775 0.404144287109375 +40776 0.03302001953125 +40777 0.22186279296875 +40778 0.0284423828125 +40779 0.003997802734375 +40780 0.021331787109375 +40781 -0.22100830078125 +40782 0.013519287109375 +40783 -0.42449951171875 +40784 0.00689697265625 +40785 -0.579833984375 +40786 0.005126953125 +40787 -0.641876220703125 +40788 0.0074462890625 +40789 -0.6177978515625 +40790 0.00799560546875 +40791 -0.575531005859375 +40792 0.00604248046875 +40793 -0.526336669921875 +40794 0.005859375 +40795 -0.42645263671875 +40796 0.009552001953125 +40797 -0.2581787109375 +40798 0.013641357421875 +40799 -0.068695068359375 +40800 0.014495849609375 +40801 0.09222412109375 +40802 0.013519287109375 +40803 0.232147216796875 +40804 0.011444091796875 +40805 0.3509521484375 +40806 0.00555419921875 +40807 0.410064697265625 +40808 -0.00677490234375 +40809 0.372955322265625 +40810 -0.023712158203125 +40811 0.2554931640625 +40812 -0.040618896484375 +40813 0.10711669921875 +40814 -0.055633544921875 +40815 -0.052886962890625 +40816 -0.065460205078125 +40817 -0.186279296875 +40818 -0.06500244140625 +40819 -0.23291015625 +40820 -0.0560302734375 +40821 -0.209442138671875 +40822 -0.04412841796875 +40823 -0.174163818359375 +40824 -0.029815673828125 +40825 -0.126739501953125 +40826 -0.01202392578125 +40827 -0.048126220703125 +40828 0.0069580078125 +40829 0.0426025390625 +40830 0.023162841796875 +40831 0.10748291015625 +40832 0.0355224609375 +40833 0.1409912109375 +40834 0.04827880859375 +40835 0.19708251953125 +40836 0.0609130859375 +40837 0.273651123046875 +40838 0.068511962890625 +40839 0.31768798828125 +40840 0.071990966796875 +40841 0.341094970703125 +40842 0.073455810546875 +40843 0.368011474609375 +40844 0.07073974609375 +40845 0.37249755859375 +40846 0.059356689453125 +40847 0.30072021484375 +40848 0.039520263671875 +40849 0.1517333984375 +40850 0.01690673828125 +40851 -0.01470947265625 +40852 -0.007080078125 +40853 -0.1883544921875 +40854 -0.032257080078125 +40855 -0.372711181640625 +40856 -0.053375244140625 +40857 -0.51397705078125 +40858 -0.06640625 +40859 -0.57177734375 +40860 -0.07037353515625 +40861 -0.53948974609375 +40862 -0.0665283203125 +40863 -0.43511962890625 +40864 -0.05792236328125 +40865 -0.2962646484375 +40866 -0.047760009765625 +40867 -0.161102294921875 +40868 -0.0372314453125 +40869 -0.0435791015625 +40870 -0.026031494140625 +40871 0.060394287109375 +40872 -0.01556396484375 +40873 0.13665771484375 +40874 -0.007415771484375 +40875 0.170135498046875 +40876 -0.00152587890625 +40877 0.16552734375 +40878 0.0047607421875 +40879 0.15728759765625 +40880 0.011505126953125 +40881 0.150787353515625 +40882 0.016143798828125 +40883 0.12200927734375 +40884 0.01910400390625 +40885 0.080108642578125 +40886 0.022369384765625 +40887 0.05126953125 +40888 0.028045654296875 +40889 0.062896728515625 +40890 0.033966064453125 +40891 0.09271240234375 +40892 0.035797119140625 +40893 0.092987060546875 +40894 0.0347900390625 +40895 0.07855224609375 +40896 0.032257080078125 +40897 0.06427001953125 +40898 0.0269775390625 +40899 0.0347900390625 +40900 0.018951416015625 +40901 -0.01171875 +40902 0.010162353515625 +40903 -0.056060791015625 +40904 0.004638671875 +40905 -0.055511474609375 +40906 0.002655029296875 +40907 -0.010467529296875 +40908 -0.000152587890625 +40909 0.02508544921875 +40910 -0.005706787109375 +40911 0.025665283203125 +40912 -0.01141357421875 +40913 0.017333984375 +40914 -0.016876220703125 +40915 0.00189208984375 +40916 -0.022857666015625 +40917 -0.03173828125 +40918 -0.028167724609375 +40919 -0.071502685546875 +40920 -0.034332275390625 +40921 -0.13543701171875 +40922 -0.041015625 +40923 -0.219970703125 +40924 -0.046142578125 +40925 -0.300506591796875 +40926 -0.0498046875 +40927 -0.376312255859375 +40928 -0.0494384765625 +40929 -0.416107177734375 +40930 -0.041015625 +40931 -0.371124267578125 +40932 -0.024871826171875 +40933 -0.242279052734375 +40934 -0.00482177734375 +40935 -0.069732666015625 +40936 0.01702880859375 +40937 0.125640869140625 +40938 0.037689208984375 +40939 0.31268310546875 +40940 0.0537109375 +40941 0.45501708984375 +40942 0.06512451171875 +40943 0.554779052734375 +40944 0.07171630859375 +40945 0.61065673828125 +40946 0.072357177734375 +40947 0.610931396484375 +40948 0.06494140625 +40949 0.531463623046875 +40950 0.05096435546875 +40951 0.3883056640625 +40952 0.03521728515625 +40953 0.23468017578125 +40954 0.02001953125 +40955 0.095245361328125 +40956 0.0078125 +40957 -0.00396728515625 +40958 3.0517578125e-05 +40959 -0.04852294921875 +40960 -0.004302978515625 +40961 -0.055145263671875 +40962 -0.009674072265625 +40963 -0.0758056640625 +40964 -0.018646240234375 +40965 -0.138702392578125 +40966 -0.027740478515625 +40967 -0.209197998046875 +40968 -0.037139892578125 +40969 -0.289031982421875 +40970 -0.04693603515625 +40971 -0.37884521484375 +40972 -0.054931640625 +40973 -0.456329345703125 +40974 -0.060638427734375 +40975 -0.51641845703125 +40976 -0.060150146484375 +40977 -0.519287109375 +40978 -0.0528564453125 +40979 -0.458251953125 +40980 -0.043975830078125 +40981 -0.384796142578125 +40982 -0.036102294921875 +40983 -0.323699951171875 +40984 -0.028717041015625 +40985 -0.269287109375 +40986 -0.019317626953125 +40987 -0.1951904296875 +40988 -0.00787353515625 +40989 -0.100006103515625 +40990 0.0028076171875 +40991 -0.01055908203125 +40992 0.015625 +40993 0.1033935546875 +40994 0.03125 +40995 0.24908447265625 +40996 0.044342041015625 +40997 0.373199462890625 +40998 0.0531005859375 +40999 0.45806884765625 +41000 0.05828857421875 +41001 0.511474609375 +41002 0.063140869140625 +41003 0.565399169921875 +41004 0.06683349609375 +41005 0.61138916015625 +41006 0.0634765625 +41007 0.5897216796875 +41008 0.052154541015625 +41009 0.4906005859375 +41010 0.034698486328125 +41011 0.33148193359375 +41012 0.0147705078125 +41013 0.147796630859375 +41014 -0.00335693359375 +41015 -0.01873779296875 +41016 -0.016845703125 +41017 -0.140289306640625 +41018 -0.02313232421875 +41019 -0.191986083984375 +41020 -0.023223876953125 +41021 -0.184295654296875 +41022 -0.021514892578125 +41023 -0.161834716796875 +41024 -0.022216796875 +41025 -0.166595458984375 +41026 -0.02484130859375 +41027 -0.19390869140625 +41028 -0.0274658203125 +41029 -0.22442626953125 +41030 -0.03228759765625 +41031 -0.279754638671875 +41032 -0.037261962890625 +41033 -0.3389892578125 +41034 -0.03765869140625 +41035 -0.3543701171875 +41036 -0.035797119140625 +41037 -0.348175048828125 +41038 -0.032318115234375 +41039 -0.32598876953125 +41040 -0.0242919921875 +41041 -0.2581787109375 +41042 -0.01129150390625 +41043 -0.139801025390625 +41044 0.005126953125 +41045 0.014617919921875 +41046 0.018829345703125 +41047 0.144378662109375 +41048 0.026947021484375 +41049 0.221038818359375 +41050 0.032073974609375 +41051 0.27069091796875 +41052 0.034271240234375 +41053 0.294036865234375 +41054 0.03564453125 +41055 0.311767578125 +41056 0.037811279296875 +41057 0.339141845703125 +41058 0.03948974609375 +41059 0.360260009765625 +41060 0.0391845703125 +41061 0.360504150390625 +41062 0.03302001953125 +41063 0.308380126953125 +41064 0.018218994140625 +41065 0.18170166015625 +41066 -0.002288818359375 +41067 0.0047607421875 +41068 -0.02301025390625 +41069 -0.17559814453125 +41070 -0.038604736328125 +41071 -0.3143310546875 +41072 -0.043975830078125 +41073 -0.36785888671875 +41074 -0.042327880859375 +41075 -0.36248779296875 +41076 -0.039154052734375 +41077 -0.343536376953125 +41078 -0.033416748046875 +41079 -0.3018798828125 +41080 -0.0244140625 +41081 -0.231414794921875 +41082 -0.01043701171875 +41083 -0.117645263671875 +41084 0.004608154296875 +41085 0.007049560546875 +41086 0.01416015625 +41087 0.087982177734375 +41088 0.01995849609375 +41089 0.13946533203125 +41090 0.023590087890625 +41091 0.17425537109375 +41092 0.02459716796875 +41093 0.188201904296875 +41094 0.02178955078125 +41095 0.171234130859375 +41096 0.0146484375 +41097 0.118438720703125 +41098 0.00653076171875 +41099 0.05706787109375 +41100 -0.00225830078125 +41101 -0.010711669921875 +41102 -0.012481689453125 +41103 -0.0914306640625 +41104 -0.021392822265625 +41105 -0.162322998046875 +41106 -0.025543212890625 +41107 -0.194549560546875 +41108 -0.020233154296875 +41109 -0.1492919921875 +41110 -0.0048828125 +41111 -0.02166748046875 +41112 0.01275634765625 +41113 0.124053955078125 +41114 0.0234375 +41115 0.211151123046875 +41116 0.027252197265625 +41117 0.240447998046875 +41118 0.02783203125 +41119 0.242218017578125 +41120 0.026275634765625 +41121 0.2257080078125 +41122 0.022979736328125 +41123 0.194366455078125 +41124 0.01397705078125 +41125 0.115509033203125 +41126 0.00213623046875 +41127 0.0128173828125 +41128 -0.00537109375 +41129 -0.053802490234375 +41130 -0.011749267578125 +41131 -0.110626220703125 +41132 -0.02203369140625 +41133 -0.199493408203125 +41134 -0.03314208984375 +41135 -0.29437255859375 +41136 -0.037506103515625 +41137 -0.33221435546875 +41138 -0.031158447265625 +41139 -0.27972412109375 +41140 -0.0198974609375 +41141 -0.185333251953125 +41142 -0.013214111328125 +41143 -0.128204345703125 +41144 -0.011962890625 +41145 -0.115692138671875 +41146 -0.01239013671875 +41147 -0.116455078125 +41148 -0.011505126953125 +41149 -0.105926513671875 +41150 -0.00567626953125 +41151 -0.053955078125 +41152 0.0062255859375 +41153 0.048797607421875 +41154 0.018798828125 +41155 0.157318115234375 +41156 0.02490234375 +41157 0.212005615234375 +41158 0.0252685546875 +41159 0.218475341796875 +41160 0.027191162109375 +41161 0.23724365234375 +41162 0.035125732421875 +41163 0.30535888671875 +41164 0.044097900390625 +41165 0.38128662109375 +41166 0.046783447265625 +41167 0.404449462890625 +41168 0.045562744140625 +41169 0.3944091796875 +41170 0.044952392578125 +41171 0.3885498046875 +41172 0.042022705078125 +41173 0.362640380859375 +41174 0.0316162109375 +41175 0.27362060546875 +41176 0.01318359375 +41177 0.11712646484375 +41178 -0.007049560546875 +41179 -0.054901123046875 +41180 -0.022918701171875 +41181 -0.19085693359375 +41182 -0.033843994140625 +41183 -0.28570556640625 +41184 -0.039825439453125 +41185 -0.339263916015625 +41186 -0.04400634765625 +41187 -0.3775634765625 +41188 -0.05181884765625 +41189 -0.445709228515625 +41190 -0.062255859375 +41191 -0.535064697265625 +41192 -0.073333740234375 +41193 -0.629058837890625 +41194 -0.0814208984375 +41195 -0.697601318359375 +41196 -0.082122802734375 +41197 -0.70391845703125 +41198 -0.074798583984375 +41199 -0.6424560546875 +41200 -0.05682373046875 +41201 -0.491241455078125 +41202 -0.029998779296875 +41203 -0.265716552734375 +41204 -0.00128173828125 +41205 -0.023712158203125 +41206 0.025360107421875 +41207 0.201751708984375 +41208 0.045745849609375 +41209 0.375823974609375 +41210 0.058349609375 +41211 0.485076904296875 +41212 0.06787109375 +41213 0.56884765625 +41214 0.075286865234375 +41215 0.634765625 +41216 0.07470703125 +41217 0.63763427734375 +41218 0.064056396484375 +41219 0.5660400390625 +41220 0.0506591796875 +41221 0.4720458984375 +41222 0.04241943359375 +41223 0.40692138671875 +41224 0.04046630859375 +41225 0.3778076171875 +41226 0.043548583984375 +41227 0.376953125 +41228 0.046630859375 +41229 0.371978759765625 +41230 0.0419921875 +41231 0.313140869140625 +41232 0.026947021484375 +41233 0.184417724609375 +41234 0.005126953125 +41235 0.011199951171875 +41236 -0.01824951171875 +41237 -0.171051025390625 +41238 -0.039642333984375 +41239 -0.33740234375 +41240 -0.056854248046875 +41241 -0.47198486328125 +41242 -0.06787109375 +41243 -0.560394287109375 +41244 -0.0694580078125 +41245 -0.58056640625 +41246 -0.06396484375 +41247 -0.54754638671875 +41248 -0.058624267578125 +41249 -0.508575439453125 +41250 -0.052703857421875 +41251 -0.459503173828125 +41252 -0.045196533203125 +41253 -0.394378662109375 +41254 -0.041900634765625 +41255 -0.35260009765625 +41256 -0.039276123046875 +41257 -0.31170654296875 +41258 -0.02581787109375 +41259 -0.197418212890625 +41260 -0.001007080078125 +41261 -0.007965087890625 +41262 0.02783203125 +41263 0.207489013671875 +41264 0.054901123046875 +41265 0.409210205078125 +41266 0.0765380859375 +41267 0.57208251953125 +41268 0.088348388671875 +41269 0.66595458984375 +41270 0.0855712890625 +41271 0.65875244140625 +41272 0.07086181640625 +41273 0.56744384765625 +41274 0.05023193359375 +41275 0.431396484375 +41276 0.030303955078125 +41277 0.29443359375 +41278 0.014923095703125 +41279 0.182464599609375 +41280 -0.00079345703125 +41281 0.06365966796875 +41282 -0.019134521484375 +41283 -0.075958251953125 +41284 -0.03314208984375 +41285 -0.189422607421875 +41286 -0.042266845703125 +41287 -0.271942138671875 +41288 -0.049591064453125 +41289 -0.342529296875 +41290 -0.049713134765625 +41291 -0.364166259765625 +41292 -0.04132080078125 +41293 -0.327239990234375 +41294 -0.03143310546875 +41295 -0.2769775390625 +41296 -0.026275634765625 +41297 -0.253692626953125 +41298 -0.0238037109375 +41299 -0.24365234375 +41300 -0.016693115234375 +41301 -0.1983642578125 +41302 -0.00469970703125 +41303 -0.116241455078125 +41304 0.00616455078125 +41305 -0.036834716796875 +41306 0.0152587890625 +41307 0.034881591796875 +41308 0.02154541015625 +41309 0.09124755859375 +41310 0.021575927734375 +41311 0.10888671875 +41312 0.021270751953125 +41313 0.125518798828125 +41314 0.0233154296875 +41315 0.15771484375 +41316 0.023712158203125 +41317 0.17828369140625 +41318 0.0201416015625 +41319 0.17108154296875 +41320 0.011810302734375 +41321 0.129974365234375 +41322 0.00299072265625 +41323 0.082427978515625 +41324 -0.00628662109375 +41325 0.027679443359375 +41326 -0.020782470703125 +41327 -0.065643310546875 +41328 -0.034698486328125 +41329 -0.15936279296875 +41330 -0.04193115234375 +41331 -0.21307373046875 +41332 -0.04376220703125 +41333 -0.234649658203125 +41334 -0.036651611328125 +41335 -0.2001953125 +41336 -0.02215576171875 +41337 -0.119171142578125 +41338 -0.00543212890625 +41339 -0.024749755859375 +41340 0.01373291015625 +41341 0.085784912109375 +41342 0.029998779296875 +41343 0.178131103515625 +41344 0.037689208984375 +41345 0.215576171875 +41346 0.038726806640625 +41347 0.211456298828125 +41348 0.034515380859375 +41349 0.17523193359375 +41350 0.0283203125 +41351 0.128753662109375 +41352 0.024627685546875 +41353 0.1019287109375 +41354 0.02032470703125 +41355 0.0743408203125 +41356 0.0150146484375 +41357 0.04327392578125 +41358 0.01318359375 +41359 0.038177490234375 +41360 0.017547607421875 +41361 0.076263427734375 +41362 0.025665283203125 +41363 0.14105224609375 +41364 0.0306396484375 +41365 0.186431884765625 +41366 0.02899169921875 +41367 0.188812255859375 +41368 0.01947021484375 +41369 0.1390380859375 +41370 0.00286865234375 +41371 0.041778564453125 +41372 -0.01708984375 +41373 -0.079437255859375 +41374 -0.03955078125 +41375 -0.219390869140625 +41376 -0.062896728515625 +41377 -0.367828369140625 +41378 -0.08251953125 +41379 -0.494873046875 +41380 -0.091705322265625 +41381 -0.556243896484375 +41382 -0.083953857421875 +41383 -0.508697509765625 +41384 -0.062835693359375 +41385 -0.3756103515625 +41386 -0.037841796875 +41387 -0.218902587890625 +41388 -0.012847900390625 +41389 -0.063751220703125 +41390 0.01226806640625 +41391 0.091552734375 +41392 0.0357666015625 +41393 0.23602294921875 +41394 0.05352783203125 +41395 0.342987060546875 +41396 0.062835693359375 +41397 0.39520263671875 +41398 0.063140869140625 +41399 0.389373779296875 +41400 0.054168701171875 +41401 0.324249267578125 +41402 0.039581298828125 +41403 0.224090576171875 +41404 0.024749755859375 +41405 0.124267578125 +41406 0.011505126953125 +41407 0.037078857421875 +41408 0.0040283203125 +41409 -0.010101318359375 +41410 0.00201416015625 +41411 -0.019439697265625 +41412 0.000640869140625 +41413 -0.022796630859375 +41414 0.0028076171875 +41415 -0.001556396484375 +41416 0.0103759765625 +41417 0.056304931640625 +41418 0.016754150390625 +41419 0.106719970703125 +41420 0.01397705078125 +41421 0.096893310546875 +41422 0.0045166015625 +41423 0.042694091796875 +41424 -0.005767822265625 +41425 -0.018035888671875 +41426 -0.015380859375 +41427 -0.07586669921875 +41428 -0.022552490234375 +41429 -0.11944580078125 +41430 -0.0289306640625 +41431 -0.15972900390625 +41432 -0.035430908203125 +41433 -0.202606201171875 +41434 -0.042083740234375 +41435 -0.24859619140625 +41436 -0.050079345703125 +41437 -0.30517578125 +41438 -0.057891845703125 +41439 -0.36212158203125 +41440 -0.06134033203125 +41441 -0.39141845703125 +41442 -0.05474853515625 +41443 -0.35528564453125 +41444 -0.037628173828125 +41445 -0.249969482421875 +41446 -0.012664794921875 +41447 -0.092864990234375 +41448 0.015960693359375 +41449 0.08905029296875 +41450 0.03900146484375 +41451 0.2352294921875 +41452 0.05230712890625 +41453 0.318817138671875 +41454 0.058746337890625 +41455 0.358642578125 +41456 0.057220458984375 +41457 0.347747802734375 +41458 0.04766845703125 +41459 0.28564453125 +41460 0.037841796875 +41461 0.223175048828125 +41462 0.033294677734375 +41463 0.196746826171875 +41464 0.030029296875 +41465 0.179840087890625 +41466 0.025482177734375 +41467 0.155548095703125 +41468 0.023895263671875 +41469 0.151214599609375 +41470 0.0238037109375 +41471 0.156951904296875 +41472 0.018890380859375 +41473 0.13177490234375 +41474 0.013458251953125 +41475 0.100799560546875 +41476 0.011260986328125 +41477 0.087127685546875 +41478 0.005828857421875 +41479 0.05487060546875 +41480 -0.005126953125 +41481 -0.009002685546875 +41482 -0.021514892578125 +41483 -0.10400390625 +41484 -0.043243408203125 +41485 -0.229400634765625 +41486 -0.064910888671875 +41487 -0.35552978515625 +41488 -0.07916259765625 +41489 -0.441925048828125 +41490 -0.083404541015625 +41491 -0.473846435546875 +41492 -0.080230712890625 +41493 -0.464813232421875 +41494 -0.070526123046875 +41495 -0.419097900390625 +41496 -0.053924560546875 +41497 -0.334320068359375 +41498 -0.033721923828125 +41499 -0.227935791015625 +41500 -0.0142822265625 +41501 -0.12347412109375 +41502 0.00311279296875 +41503 -0.02764892578125 +41504 0.021820068359375 +41505 0.077667236328125 +41506 0.045684814453125 +41507 0.2132568359375 +41508 0.076568603515625 +41509 0.38885498046875 +41510 0.110565185546875 +41511 0.582794189453125 +41512 0.136566162109375 +41513 0.734039306640625 +41514 0.1468505859375 +41515 0.800140380859375 +41516 0.1409912109375 +41517 0.7783203125 +41518 0.118499755859375 +41519 0.6651611328125 +41520 0.07928466796875 +41521 0.45965576171875 +41522 0.03033447265625 +41523 0.199188232421875 +41524 -0.0162353515625 +41525 -0.050689697265625 +41526 -0.049957275390625 +41527 -0.23297119140625 +41528 -0.067626953125 +41529 -0.33013916015625 +41530 -0.074066162109375 +41531 -0.368408203125 +41532 -0.075042724609375 +41533 -0.378936767578125 +41534 -0.073486328125 +41535 -0.376983642578125 +41536 -0.072601318359375 +41537 -0.37969970703125 +41538 -0.0732421875 +41539 -0.391510009765625 +41540 -0.070526123046875 +41541 -0.385345458984375 +41542 -0.06097412109375 +41543 -0.3419189453125 +41544 -0.048675537109375 +41545 -0.28289794921875 +41546 -0.04168701171875 +41547 -0.251617431640625 +41548 -0.04339599609375 +41549 -0.266143798828125 +41550 -0.0440673828125 +41551 -0.273345947265625 +41552 -0.0333251953125 +41553 -0.216796875 +41554 -0.01702880859375 +41555 -0.128265380859375 +41556 -0.006256103515625 +41557 -0.068145751953125 +41558 -0.002227783203125 +41559 -0.0430908203125 +41560 0.000335693359375 +41561 -0.024444580078125 +41562 0.007568359375 +41563 0.020721435546875 +41564 0.025390625 +41565 0.124481201171875 +41566 0.048553466796875 +41567 0.25787353515625 +41568 0.0694580078125 +41569 0.379119873046875 +41570 0.086669921875 +41571 0.47991943359375 +41572 0.094329833984375 +41573 0.5281982421875 +41574 0.09014892578125 +41575 0.511138916015625 +41576 0.079254150390625 +41577 0.456207275390625 +41578 0.069793701171875 +41579 0.407470703125 +41580 0.065216064453125 +41581 0.383758544921875 +41582 0.060333251953125 +41583 0.35687255859375 +41584 0.052398681640625 +41585 0.31182861328125 +41586 0.041778564453125 +41587 0.250885009765625 +41588 0.026885986328125 +41589 0.1654052734375 +41590 0.00396728515625 +41591 0.035247802734375 +41592 -0.027496337890625 +41593 -0.142059326171875 +41594 -0.0618896484375 +41595 -0.33563232421875 +41596 -0.097259521484375 +41597 -0.5345458984375 +41598 -0.13055419921875 +41599 -0.72186279296875 +41600 -0.150604248046875 +41601 -0.836669921875 +41602 -0.148956298828125 +41603 -0.8326416015625 +41604 -0.12933349609375 +41605 -0.7296142578125 +41606 -0.101898193359375 +41607 -0.582550048828125 +41608 -0.075592041015625 +41609 -0.440093994140625 +41610 -0.054473876953125 +41611 -0.324310302734375 +41612 -0.03228759765625 +41613 -0.20147705078125 +41614 -0.004058837890625 +41615 -0.044647216796875 +41616 0.022491455078125 +41617 0.103973388671875 +41618 0.039642333984375 +41619 0.202392578125 +41620 0.050018310546875 +41621 0.264495849609375 +41622 0.0626220703125 +41623 0.338897705078125 +41624 0.080841064453125 +41625 0.443817138671875 +41626 0.09844970703125 +41627 0.545074462890625 +41628 0.11083984375 +41629 0.6173095703125 +41630 0.1165771484375 +41631 0.6524658203125 +41632 0.1180419921875 +41633 0.66339111328125 +41634 0.11639404296875 +41635 0.6561279296875 +41636 0.107208251953125 +41637 0.606781005859375 +41638 0.087890625 +41639 0.501190185546875 +41640 0.0609130859375 +41641 0.352783203125 +41642 0.029022216796875 +41643 0.176544189453125 +41644 -0.009124755859375 +41645 -0.034820556640625 +41646 -0.049285888671875 +41647 -0.258209228515625 +41648 -0.082122802734375 +41649 -0.44244384765625 +41650 -0.105438232421875 +41651 -0.5753173828125 +41652 -0.118438720703125 +41653 -0.65203857421875 +41654 -0.115478515625 +41655 -0.641632080078125 +41656 -0.0999755859375 +41657 -0.562164306640625 +41658 -0.08013916015625 +41659 -0.458038330078125 +41660 -0.059906005859375 +41661 -0.350555419921875 +41662 -0.043121337890625 +41663 -0.260528564453125 +41664 -0.030548095703125 +41665 -0.192108154296875 +41666 -0.021575927734375 +41667 -0.141937255859375 +41668 -0.01470947265625 +41669 -0.1021728515625 +41670 -0.00811767578125 +41671 -0.062896728515625 +41672 0.000457763671875 +41673 -0.011932373046875 +41674 0.0133056640625 +41675 0.062835693359375 +41676 0.02813720703125 +41677 0.148712158203125 +41678 0.044281005859375 +41679 0.241729736328125 +41680 0.063079833984375 +41681 0.34912109375 +41682 0.082122802734375 +41683 0.457305908203125 +41684 0.097320556640625 +41685 0.54388427734375 +41686 0.10211181640625 +41687 0.5728759765625 +41688 0.089569091796875 +41689 0.506591796875 +41690 0.06085205078125 +41691 0.351226806640625 +41692 0.02325439453125 +41693 0.146514892578125 +41694 -0.013580322265625 +41695 -0.05523681640625 +41696 -0.042724609375 +41697 -0.21624755859375 +41698 -0.06390380859375 +41699 -0.334930419921875 +41700 -0.07562255859375 +41701 -0.402984619140625 +41702 -0.081787109375 +41703 -0.4412841796875 +41704 -0.09088134765625 +41705 -0.49578857421875 +41706 -0.101806640625 +41707 -0.5601806640625 +41708 -0.1083984375 +41709 -0.600738525390625 +41710 -0.1046142578125 +41711 -0.584228515625 +41712 -0.084747314453125 +41713 -0.47930908203125 +41714 -0.047576904296875 +41715 -0.27935791015625 +41716 0.0023193359375 +41717 -0.0089111328125 +41718 0.053314208984375 +41719 0.268798828125 +41720 0.09234619140625 +41721 0.482818603515625 +41722 0.114044189453125 +41723 0.60369873046875 +41724 0.121917724609375 +41725 0.650421142578125 +41726 0.12359619140625 +41727 0.66400146484375 +41728 0.11834716796875 +41729 0.6414794921875 +41730 0.104400634765625 +41731 0.572540283203125 +41732 0.09051513671875 +41733 0.498138427734375 +41734 0.08099365234375 +41735 0.439453125 +41736 0.071044921875 +41737 0.375518798828125 +41738 0.05352783203125 +41739 0.274505615234375 +41740 0.022186279296875 +41741 0.1087646484375 +41742 -0.018402099609375 +41743 -0.099395751953125 +41744 -0.061614990234375 +41745 -0.3182373046875 +41746 -0.107940673828125 +41747 -0.5489501953125 +41748 -0.1536865234375 +41749 -0.7738037109375 +41750 -0.187530517578125 +41751 -0.86383056640625 +41752 -0.202362060546875 +41753 -0.870391845703125 +41754 -0.20208740234375 +41755 -0.86895751953125 +41756 -0.189483642578125 +41757 -0.861053466796875 +41758 -0.1607666015625 +41759 -0.765869140625 +41760 -0.1134033203125 +41761 -0.5301513671875 +41762 -0.04876708984375 +41763 -0.214691162109375 +41764 0.02398681640625 +41765 0.137359619140625 +41766 0.093994140625 +41767 0.474822998046875 +41768 0.15374755859375 +41769 0.76239013671875 +41770 0.197662353515625 +41771 0.867462158203125 +41772 0.225982666015625 +41773 0.870361328125 +41774 0.236358642578125 +41775 0.86480712890625 +41776 0.230072021484375 +41777 0.831817626953125 +41778 0.212493896484375 +41779 0.677581787109375 +41780 0.184906005859375 +41781 0.495880126953125 +41782 0.1513671875 +41783 0.30767822265625 +41784 0.1123046875 +41785 0.116180419921875 +41786 0.060760498046875 +41787 -0.110748291015625 +41788 -0.00482177734375 +41789 -0.381805419921875 +41790 -0.075347900390625 +41791 -0.6572265625 +41792 -0.138031005859375 +41793 -0.857421875 +41794 -0.18377685546875 +41795 -0.870391845703125 +41796 -0.211212158203125 +41797 -0.870391845703125 +41798 -0.226318359375 +41799 -0.86444091796875 +41800 -0.2369384765625 +41801 -0.85723876953125 +41802 -0.239227294921875 +41803 -0.790008544921875 +41804 -0.2215576171875 +41805 -0.62847900390625 +41806 -0.183258056640625 +41807 -0.3956298828125 +41808 -0.1314697265625 +41809 -0.126708984375 +41810 -0.072113037109375 +41811 0.150115966796875 +41812 -0.00762939453125 +41813 0.424041748046875 +41814 0.056182861328125 +41815 0.670623779296875 +41816 0.111083984375 +41817 0.854522705078125 +41818 0.15338134765625 +41819 0.866485595703125 +41820 0.17987060546875 +41821 0.86920166015625 +41822 0.19464111328125 +41823 0.8653564453125 +41824 0.200714111328125 +41825 0.857147216796875 +41826 0.19757080078125 +41827 0.766845703125 +41828 0.18646240234375 +41829 0.628509521484375 +41830 0.165985107421875 +41831 0.462127685546875 +41832 0.141754150390625 +41833 0.297210693359375 +41834 0.116455078125 +41835 0.14862060546875 +41836 0.085174560546875 +41837 -0.00537109375 +41838 0.049530029296875 +41839 -0.15753173828125 +41840 0.0086669921875 +41841 -0.31304931640625 +41842 -0.040496826171875 +41843 -0.48876953125 +41844 -0.087921142578125 +41845 -0.6416015625 +41846 -0.12835693359375 +41847 -0.751373291015625 +41848 -0.16693115234375 +41849 -0.84619140625 +41850 -0.2005615234375 +41851 -0.861297607421875 +41852 -0.22216796875 +41853 -0.863250732421875 +41854 -0.22503662109375 +41855 -0.856597900390625 +41856 -0.211883544921875 +41857 -0.7498779296875 +41858 -0.195281982421875 +41859 -0.624542236328125 +41860 -0.170501708984375 +41861 -0.47808837890625 +41862 -0.124908447265625 +41863 -0.253387451171875 +41864 -0.068389892578125 +41865 0.003692626953125 +41866 -0.015655517578125 +41867 0.2257080078125 +41868 0.0360107421875 +41869 0.427154541015625 +41870 0.093658447265625 +41871 0.643218994140625 +41872 0.1552734375 +41873 0.855926513671875 +41874 0.20843505859375 +41875 0.870361328125 +41876 0.24249267578125 +41877 0.870361328125 +41878 0.25909423828125 +41879 0.862762451171875 +41880 0.257720947265625 +41881 0.79669189453125 +41882 0.236419677734375 +41883 0.595794677734375 +41884 0.2015380859375 +41885 0.362152099609375 +41886 0.1591796875 +41887 0.1270751953125 +41888 0.11395263671875 +41889 -0.086944580078125 +41890 0.066314697265625 +41891 -0.2784423828125 +41892 0.008758544921875 +41893 -0.484832763671875 +41894 -0.0628662109375 +41895 -0.729583740234375 +41896 -0.137664794921875 +41897 -0.86688232421875 +41898 -0.201995849609375 +41899 -0.870391845703125 +41900 -0.254852294921875 +41901 -0.86859130859375 +41902 -0.295867919921875 +41903 -0.86279296875 +41904 -0.317352294921875 +41905 -0.817962646484375 +41906 -0.3095703125 +41907 -0.6116943359375 +41908 -0.27105712890625 +41909 -0.3128662109375 +41910 -0.209136962890625 +41911 0.039398193359375 +41912 -0.128204345703125 +41913 0.422821044921875 +41914 -0.035491943359375 +41915 0.805145263671875 +41916 0.054229736328125 +41917 0.870361328125 +41918 0.128662109375 +41919 0.870361328125 +41920 0.18524169921875 +41921 0.860015869140625 +41922 0.222320556640625 +41923 0.727935791015625 +41924 0.238677978515625 +41925 0.48114013671875 +41926 0.239532470703125 +41927 0.2059326171875 +41928 0.22979736328125 +41929 -0.06103515625 +41930 0.211669921875 +41931 -0.29913330078125 +41932 0.18206787109375 +41933 -0.516204833984375 +41934 0.137725830078125 +41935 -0.7252197265625 +41936 0.0841064453125 +41937 -0.85980224609375 +41938 0.028656005859375 +41939 -0.870391845703125 +41940 -0.0220947265625 +41941 -0.870391845703125 +41942 -0.05755615234375 +41943 -0.858062744140625 +41944 -0.07672119140625 +41945 -0.673004150390625 +41946 -0.090850830078125 +41947 -0.42694091796875 +41948 -0.109405517578125 +41949 -0.2100830078125 +41950 -0.131866455078125 +41951 -0.0362548828125 +41952 -0.151885986328125 +41953 0.10943603515625 +41954 -0.165130615234375 +41955 0.23516845703125 +41956 -0.16265869140625 +41957 0.373687744140625 +41958 -0.1448974609375 +41959 0.517791748046875 +41960 -0.125457763671875 +41961 0.602783203125 +41962 -0.10333251953125 +41963 0.635711669921875 +41964 -0.0714111328125 +41965 0.655181884765625 +41966 -0.031951904296875 +41967 0.65948486328125 +41968 0.01318359375 +41969 0.651275634765625 +41970 0.058624267578125 +41971 0.61846923828125 +41972 0.096221923828125 +41973 0.53753662109375 +41974 0.121978759765625 +41975 0.404144287109375 +41976 0.133697509765625 +41977 0.22186279296875 +41978 0.131622314453125 +41979 0.003997802734375 +41980 0.119598388671875 +41981 -0.22100830078125 +41982 0.10205078125 +41983 -0.42449951171875 +41984 0.08392333984375 +41985 -0.579833984375 +41986 0.07513427734375 +41987 -0.641876220703125 +41988 0.073699951171875 +41989 -0.6177978515625 +41990 0.06396484375 +41991 -0.575531005859375 +41992 0.044891357421875 +41993 -0.526336669921875 +41994 0.029541015625 +41995 -0.42645263671875 +41996 0.02490234375 +41997 -0.2581787109375 +41998 0.0220947265625 +41999 -0.068695068359375 +42000 0.01165771484375 +42001 0.09222412109375 +42002 -0.001739501953125 +42003 0.232147216796875 +42004 -0.015533447265625 +42005 0.3509521484375 +42006 -0.037109375 +42007 0.410064697265625 +42008 -0.073760986328125 +42009 0.372955322265625 +42010 -0.120361328125 +42011 0.2554931640625 +42012 -0.16400146484375 +42013 0.10711669921875 +42014 -0.1998291015625 +42015 -0.052886962890625 +42016 -0.218902587890625 +42017 -0.186279296875 +42018 -0.2073974609375 +42019 -0.23291015625 +42020 -0.170989990234375 +42021 -0.209442138671875 +42022 -0.126007080078125 +42023 -0.174163818359375 +42024 -0.07452392578125 +42025 -0.126739501953125 +42026 -0.014068603515625 +42027 -0.048126220703125 +42028 0.048309326171875 +42029 0.0426025390625 +42030 0.101043701171875 +42031 0.10748291015625 +42032 0.140869140625 +42033 0.1409912109375 +42034 0.179595947265625 +42035 0.19708251953125 +42036 0.215545654296875 +42037 0.273651123046875 +42038 0.23486328125 +42039 0.31768798828125 +42040 0.240325927734375 +42041 0.341094970703125 +42042 0.2381591796875 +42043 0.368011474609375 +42044 0.222686767578125 +42045 0.37249755859375 +42046 0.181671142578125 +42047 0.30072021484375 +42048 0.116363525390625 +42049 0.1517333984375 +42050 0.043243408203125 +42051 -0.01470947265625 +42052 -0.03326416015625 +42053 -0.1883544921875 +42054 -0.112152099609375 +42055 -0.372711181640625 +42056 -0.178314208984375 +42057 -0.51397705078125 +42058 -0.220062255859375 +42059 -0.57177734375 +42060 -0.234375 +42061 -0.53948974609375 +42062 -0.22467041015625 +42063 -0.43511962890625 +42064 -0.199554443359375 +42065 -0.2962646484375 +42066 -0.168212890625 +42067 -0.161102294921875 +42068 -0.1341552734375 +42069 -0.0435791015625 +42070 -0.09686279296875 +42071 0.060394287109375 +42072 -0.060638427734375 +42073 0.13665771484375 +42074 -0.03033447265625 +42075 0.170135498046875 +42076 -0.006134033203125 +42077 0.16552734375 +42078 0.019012451171875 +42079 0.15728759765625 +42080 0.044891357421875 +42081 0.150787353515625 +42082 0.064056396484375 +42083 0.12200927734375 +42084 0.077362060546875 +42085 0.080108642578125 +42086 0.090087890625 +42087 0.05126953125 +42088 0.108062744140625 +42089 0.062896728515625 +42090 0.12506103515625 +42091 0.09271240234375 +42092 0.12890625 +42093 0.092987060546875 +42094 0.123199462890625 +42095 0.07855224609375 +42096 0.1119384765625 +42097 0.06427001953125 +42098 0.091888427734375 +42099 0.0347900390625 +42100 0.06341552734375 +42101 -0.01171875 +42102 0.0323486328125 +42103 -0.056060791015625 +42104 0.010467529296875 +42105 -0.055511474609375 +42106 -0.00103759765625 +42107 -0.010467529296875 +42108 -0.0142822265625 +42109 0.02508544921875 +42110 -0.034423828125 +42111 0.025665283203125 +42112 -0.053955078125 +42113 0.017333984375 +42114 -0.071533203125 +42115 0.00189208984375 +42116 -0.089263916015625 +42117 -0.03173828125 +42118 -0.103790283203125 +42119 -0.071502685546875 +42120 -0.11944580078125 +42121 -0.13543701171875 +42122 -0.135528564453125 +42123 -0.219970703125 +42124 -0.14630126953125 +42125 -0.300506591796875 +42126 -0.152191162109375 +42127 -0.376312255859375 +42128 -0.14630126953125 +42129 -0.416107177734375 +42130 -0.117462158203125 +42131 -0.371124267578125 +42132 -0.066925048828125 +42133 -0.242279052734375 +42134 -0.00567626953125 +42135 -0.069732666015625 +42136 0.06005859375 +42137 0.125640869140625 +42138 0.12164306640625 +42139 0.31268310546875 +42140 0.169281005859375 +42141 0.45501708984375 +42142 0.202911376953125 +42143 0.554779052734375 +42144 0.221832275390625 +42145 0.61065673828125 +42146 0.222991943359375 +42147 0.610931396484375 +42148 0.200439453125 +42149 0.531463623046875 +42150 0.158447265625 +42151 0.3883056640625 +42152 0.11065673828125 +42153 0.23468017578125 +42154 0.063812255859375 +42155 0.095245361328125 +42156 0.02508544921875 +42157 -0.00396728515625 +42158 -0.001068115234375 +42159 -0.04852294921875 +42160 -0.0179443359375 +42161 -0.055145263671875 +42162 -0.037628173828125 +42163 -0.0758056640625 +42164 -0.066314697265625 +42165 -0.138702392578125 +42166 -0.094757080078125 +42167 -0.209197998046875 +42168 -0.122833251953125 +42169 -0.289031982421875 +42170 -0.150360107421875 +42171 -0.37884521484375 +42172 -0.17156982421875 +42173 -0.456329345703125 +42174 -0.1851806640625 +42175 -0.51641845703125 +42176 -0.1815185546875 +42177 -0.519287109375 +42178 -0.15924072265625 +42179 -0.458251953125 +42180 -0.131561279296875 +42181 -0.384796142578125 +42182 -0.105224609375 +42183 -0.323699951171875 +42184 -0.0794677734375 +42185 -0.269287109375 +42186 -0.0484619140625 +42187 -0.1951904296875 +42188 -0.0125732421875 +42189 -0.100006103515625 +42190 0.0208740234375 +42191 -0.01055908203125 +42192 0.05877685546875 +42193 0.1033935546875 +42194 0.102447509765625 +42195 0.24908447265625 +42196 0.138336181640625 +42197 0.373199462890625 +42198 0.161865234375 +42199 0.45806884765625 +42200 0.17486572265625 +42201 0.511474609375 +42202 0.18536376953125 +42203 0.565399169921875 +42204 0.191497802734375 +42205 0.61138916015625 +42206 0.1788330078125 +42207 0.5897216796875 +42208 0.1453857421875 +42209 0.4906005859375 +42210 0.096038818359375 +42211 0.33148193359375 +42212 0.040130615234375 +42213 0.147796630859375 +42214 -0.01141357421875 +42215 -0.01873779296875 +42216 -0.051116943359375 +42217 -0.140289306640625 +42218 -0.072296142578125 +42219 -0.191986083984375 +42220 -0.0771484375 +42221 -0.184295654296875 +42222 -0.076416015625 +42223 -0.161834716796875 +42224 -0.080291748046875 +42225 -0.166595458984375 +42226 -0.0875244140625 +42227 -0.19390869140625 +42228 -0.093353271484375 +42229 -0.22442626953125 +42230 -0.103302001953125 +42231 -0.279754638671875 +42232 -0.112457275390625 +42233 -0.3389892578125 +42234 -0.10931396484375 +42235 -0.3543701171875 +42236 -0.099822998046875 +42237 -0.348175048828125 +42238 -0.085845947265625 +42239 -0.32598876953125 +42240 -0.06048583984375 +42241 -0.2581787109375 +42242 -0.02294921875 +42243 -0.139801025390625 +42244 0.022705078125 +42245 0.014617919921875 +42246 0.0609130859375 +42247 0.144378662109375 +42248 0.084320068359375 +42249 0.221038818359375 +42250 0.099273681640625 +42251 0.27069091796875 +42252 0.105865478515625 +42253 0.294036865234375 +42254 0.109283447265625 +42255 0.311767578125 +42256 0.113525390625 +42257 0.339141845703125 +42258 0.115203857421875 +42259 0.360260009765625 +42260 0.11077880859375 +42261 0.360504150390625 +42262 0.091583251953125 +42263 0.308380126953125 +42264 0.051544189453125 +42265 0.18170166015625 +42266 -0.0023193359375 +42267 0.0047607421875 +42268 -0.056732177734375 +42269 -0.17559814453125 +42270 -0.09893798828125 +42271 -0.3143310546875 +42272 -0.1165771484375 +42273 -0.36785888671875 +42274 -0.116943359375 +42275 -0.36248779296875 +42276 -0.112640380859375 +42277 -0.343536376953125 +42278 -0.101104736328125 +42279 -0.3018798828125 +42280 -0.08062744140625 +42281 -0.231414794921875 +42282 -0.047210693359375 +42283 -0.117645263671875 +42284 -0.010009765625 +42285 0.007049560546875 +42286 0.015472412109375 +42287 0.087982177734375 +42288 0.033111572265625 +42289 0.13946533203125 +42290 0.046295166015625 +42291 0.17425537109375 +42292 0.053680419921875 +42293 0.188201904296875 +42294 0.05224609375 +42295 0.171234130859375 +42296 0.040435791015625 +42297 0.118438720703125 +42298 0.025787353515625 +42299 0.05706787109375 +42300 0.00872802734375 +42301 -0.010711669921875 +42302 -0.012603759765625 +42303 -0.0914306640625 +42304 -0.031890869140625 +42305 -0.162322998046875 +42306 -0.04107666015625 +42307 -0.194549560546875 +42308 -0.029266357421875 +42309 -0.1492919921875 +42310 0.004913330078125 +42311 -0.02166748046875 +42312 0.043609619140625 +42313 0.124053955078125 +42314 0.0654296875 +42315 0.211151123046875 +42316 0.070770263671875 +42317 0.240447998046875 +42318 0.068267822265625 +42319 0.242218017578125 +42320 0.06072998046875 +42321 0.2257080078125 +42322 0.04925537109375 +42323 0.194366455078125 +42324 0.02484130859375 +42325 0.115509033203125 +42326 -0.005706787109375 +42327 0.0128173828125 +42328 -0.025543212890625 +42329 -0.053802490234375 +42330 -0.0419921875 +42331 -0.110626220703125 +42332 -0.0667724609375 +42333 -0.199493408203125 +42334 -0.092620849609375 +42335 -0.29437255859375 +42336 -0.1019287109375 +42337 -0.33221435546875 +42338 -0.085479736328125 +42339 -0.27972412109375 +42340 -0.05694580078125 +42341 -0.185333251953125 +42342 -0.038604736328125 +42343 -0.128204345703125 +42344 -0.03265380859375 +42345 -0.115692138671875 +42346 -0.03045654296875 +42347 -0.116455078125 +42348 -0.0252685546875 +42349 -0.105926513671875 +42350 -0.008758544921875 +42351 -0.053955078125 +42352 0.021575927734375 +42353 0.048797607421875 +42354 0.05303955078125 +42355 0.157318115234375 +42356 0.06890869140625 +42357 0.212005615234375 +42358 0.07073974609375 +42359 0.218475341796875 +42360 0.07550048828125 +42361 0.23724365234375 +42362 0.093597412109375 +42363 0.30535888671875 +42364 0.11346435546875 +42365 0.38128662109375 +42366 0.11822509765625 +42367 0.404449462890625 +42368 0.11346435546875 +42369 0.3944091796875 +42370 0.109771728515625 +42371 0.3885498046875 +42372 0.1004638671875 +42373 0.362640380859375 +42374 0.0736083984375 +42375 0.27362060546875 +42376 0.028076171875 +42377 0.11712646484375 +42378 -0.021484375 +42379 -0.054901123046875 +42380 -0.060516357421875 +42381 -0.19085693359375 +42382 -0.08758544921875 +42383 -0.28570556640625 +42384 -0.1026611328125 +42385 -0.339263916015625 +42386 -0.113006591796875 +42387 -0.3775634765625 +42388 -0.131317138671875 +42389 -0.445709228515625 +42390 -0.15521240234375 +42391 -0.535064697265625 +42392 -0.18011474609375 +42393 -0.629058837890625 +42394 -0.197662353515625 +42395 -0.697601318359375 +42396 -0.197662353515625 +42397 -0.70391845703125 +42398 -0.1787109375 +42399 -0.6424560546875 +42400 -0.134735107421875 +42401 -0.491241455078125 +42402 -0.07012939453125 +42403 -0.265716552734375 +42404 -0.00115966796875 +42405 -0.023712158203125 +42406 0.062835693359375 +42407 0.201751708984375 +42408 0.112060546875 +42409 0.375823974609375 +42410 0.14276123046875 +42411 0.485076904296875 +42412 0.165924072265625 +42413 0.56884765625 +42414 0.183746337890625 +42415 0.634765625 +42416 0.18359375 +42417 0.63763427734375 +42418 0.162353515625 +42419 0.5660400390625 +42420 0.1346435546875 +42421 0.4720458984375 +42422 0.114898681640625 +42423 0.40692138671875 +42424 0.105255126953125 +42425 0.3778076171875 +42426 0.10357666015625 +42427 0.376953125 +42428 0.10089111328125 +42429 0.371978759765625 +42430 0.08331298828125 +42431 0.313140869140625 +42432 0.046417236328125 +42433 0.184417724609375 +42434 -0.002593994140625 +42435 0.011199951171875 +42436 -0.05377197265625 +42437 -0.171051025390625 +42438 -0.100128173828125 +42439 -0.33740234375 +42440 -0.13726806640625 +42441 -0.47198486328125 +42442 -0.16119384765625 +42443 -0.560394287109375 +42444 -0.165802001953125 +42445 -0.58056640625 +42446 -0.15533447265625 +42447 -0.54754638671875 +42448 -0.14312744140625 +42449 -0.508575439453125 +42450 -0.128082275390625 +42451 -0.459503173828125 +42452 -0.10858154296875 +42453 -0.394378662109375 +42454 -0.095703125 +42455 -0.35260009765625 +42456 -0.083221435546875 +42457 -0.31170654296875 +42458 -0.0504150390625 +42459 -0.197418212890625 +42460 0.003143310546875 +42461 -0.007965087890625 +42462 0.06365966796875 +42463 0.207489013671875 +42464 0.1199951171875 +42465 0.409210205078125 +42466 0.165130615234375 +42467 0.57208251953125 +42468 0.190673828125 +42469 0.66595458984375 +42470 0.187713623046875 +42471 0.65875244140625 +42472 0.161041259765625 +42473 0.56744384765625 +42474 0.12176513671875 +42475 0.431396484375 +42476 0.082244873046875 +42477 0.29443359375 +42478 0.049774169921875 +42479 0.182464599609375 +42480 0.0155029296875 +42481 0.06365966796875 +42482 -0.0244140625 +42483 -0.075958251953125 +42484 -0.056793212890625 +42485 -0.189422607421875 +42486 -0.08026123046875 +42487 -0.271942138671875 +42488 -0.10009765625 +42489 -0.342529296875 +42490 -0.105987548828125 +42491 -0.364166259765625 +42492 -0.095245361328125 +42493 -0.327239990234375 +42494 -0.08056640625 +42495 -0.2769775390625 +42496 -0.07354736328125 +42497 -0.253692626953125 +42498 -0.070159912109375 +42499 -0.24365234375 +42500 -0.0557861328125 +42501 -0.1983642578125 +42502 -0.030059814453125 +42503 -0.116241455078125 +42504 -0.00543212890625 +42505 -0.036834716796875 +42506 0.016448974609375 +42507 0.034881591796875 +42508 0.033172607421875 +42509 0.09124755859375 +42510 0.037506103515625 +42511 0.10888671875 +42512 0.041259765625 +42513 0.125518798828125 +42514 0.049713134765625 +42515 0.15771484375 +42516 0.054473876953125 +42517 0.17828369140625 +42518 0.050567626953125 +42519 0.17108154296875 +42520 0.0362548828125 +42521 0.129974365234375 +42522 0.020172119140625 +42523 0.082427978515625 +42524 0.00213623046875 +42525 0.027679443359375 +42526 -0.02752685546875 +42527 -0.065643310546875 +42528 -0.056884765625 +42529 -0.15936279296875 +42530 -0.073333740234375 +42531 -0.21307373046875 +42532 -0.079376220703125 +42533 -0.234649658203125 +42534 -0.067596435546875 +42535 -0.2001953125 +42536 -0.041015625 +42537 -0.119171142578125 +42538 -0.01007080078125 +42539 -0.024749755859375 +42540 0.0260009765625 +42541 0.085784912109375 +42542 0.056396484375 +42543 0.178131103515625 +42544 0.069549560546875 +42545 0.215576171875 +42546 0.069549560546875 +42547 0.211456298828125 +42548 0.059326171875 +42549 0.17523193359375 +42550 0.045623779296875 +42551 0.128753662109375 +42552 0.037750244140625 +42553 0.1019287109375 +42554 0.029327392578125 +42555 0.0743408203125 +42556 0.019500732421875 +42557 0.04327392578125 +42558 0.017425537109375 +42559 0.038177490234375 +42560 0.028564453125 +42561 0.076263427734375 +42562 0.047760009765625 +42563 0.14105224609375 +42564 0.06072998046875 +42565 0.186431884765625 +42566 0.0601806640625 +42567 0.188812255859375 +42568 0.043304443359375 +42569 0.1390380859375 +42570 0.011688232421875 +42571 0.041778564453125 +42572 -0.027252197265625 +42573 -0.079437255859375 +42574 -0.071868896484375 +42575 -0.219390869140625 +42576 -0.118865966796875 +42577 -0.367828369140625 +42578 -0.158905029296875 +42579 -0.494873046875 +42580 -0.178192138671875 +42581 -0.556243896484375 +42582 -0.1632080078125 +42583 -0.508697509765625 +42584 -0.12127685546875 +42585 -0.3756103515625 +42586 -0.071746826171875 +42587 -0.218902587890625 +42588 -0.02252197265625 +42589 -0.063751220703125 +42590 0.02685546875 +42591 0.091552734375 +42592 0.072906494140625 +42593 0.23602294921875 +42594 0.10723876953125 +42595 0.342987060546875 +42596 0.12445068359375 +42597 0.39520263671875 +42598 0.12347412109375 +42599 0.389373779296875 +42600 0.1038818359375 +42601 0.324249267578125 +42602 0.073211669921875 +42603 0.224090576171875 +42604 0.042449951171875 +42605 0.124267578125 +42606 0.015411376953125 +42607 0.037078857421875 +42608 0.000640869140625 +42609 -0.010101318359375 +42610 -0.00250244140625 +42611 -0.019439697265625 +42612 -0.003936767578125 +42613 -0.022796630859375 +42614 0.00213623046875 +42615 -0.001556396484375 +42616 0.019500732421875 +42617 0.056304931640625 +42618 0.034454345703125 +42619 0.106719970703125 +42620 0.030548095703125 +42621 0.096893310546875 +42622 0.0128173828125 +42623 0.042694091796875 +42624 -0.00689697265625 +42625 -0.018035888671875 +42626 -0.025604248046875 +42627 -0.07586669921875 +42628 -0.039703369140625 +42629 -0.11944580078125 +42630 -0.0526123046875 +42631 -0.15972900390625 +42632 -0.066131591796875 +42633 -0.202606201171875 +42634 -0.080413818359375 +42635 -0.24859619140625 +42636 -0.0977783203125 +42637 -0.30517578125 +42638 -0.115081787109375 +42639 -0.36212158203125 +42640 -0.1236572265625 +42641 -0.39141845703125 +42642 -0.111724853515625 +42643 -0.35528564453125 +42644 -0.07818603515625 +42645 -0.249969482421875 +42646 -0.02850341796875 +42647 -0.092864990234375 +42648 0.02886962890625 +42649 0.08905029296875 +42650 0.07501220703125 +42651 0.2352294921875 +42652 0.101531982421875 +42653 0.318817138671875 +42654 0.114288330078125 +42655 0.358642578125 +42656 0.111083984375 +42657 0.347747802734375 +42658 0.09173583984375 +42659 0.28564453125 +42660 0.0721435546875 +42661 0.223175048828125 +42662 0.06365966796875 +42663 0.196746826171875 +42664 0.05804443359375 +42665 0.179840087890625 +42666 0.050048828125 +42667 0.155548095703125 +42668 0.0482177734375 +42669 0.151214599609375 +42670 0.049468994140625 +42671 0.156951904296875 +42672 0.041046142578125 +42673 0.13177490234375 +42674 0.030853271484375 +42675 0.100799560546875 +42676 0.026092529296875 +42677 0.087127685546875 +42678 0.015594482421875 +42679 0.05487060546875 +42680 -0.004638671875 +42681 -0.009002685546875 +42682 -0.034454345703125 +42683 -0.10400390625 +42684 -0.073638916015625 +42685 -0.229400634765625 +42686 -0.1129150390625 +42687 -0.35552978515625 +42688 -0.1396484375 +42689 -0.441925048828125 +42690 -0.149261474609375 +42691 -0.473846435546875 +42692 -0.14599609375 +42693 -0.464813232421875 +42694 -0.1312255859375 +42695 -0.419097900390625 +42696 -0.104248046875 +42697 -0.334320068359375 +42698 -0.070526123046875 +42699 -0.227935791015625 +42700 -0.037445068359375 +42701 -0.12347412109375 +42702 -0.007110595703125 +42703 -0.02764892578125 +42704 0.026092529296875 +42705 0.077667236328125 +42706 0.068634033203125 +42707 0.2132568359375 +42708 0.12353515625 +42709 0.38885498046875 +42710 0.184051513671875 +42711 0.582794189453125 +42712 0.231109619140625 +42713 0.734039306640625 +42714 0.25146484375 +42715 0.800140380859375 +42716 0.244293212890625 +42717 0.7783203125 +42718 0.20855712890625 +42719 0.6651611328125 +42720 0.144012451171875 +42721 0.45965576171875 +42722 0.06231689453125 +42723 0.199188232421875 +42724 -0.016021728515625 +42725 -0.050689697265625 +42726 -0.0732421875 +42727 -0.23297119140625 +42728 -0.103851318359375 +42729 -0.33013916015625 +42730 -0.11602783203125 +42731 -0.368408203125 +42732 -0.11944580078125 +42733 -0.378936767578125 +42734 -0.118927001953125 +42735 -0.376983642578125 +42736 -0.11981201171875 +42737 -0.37969970703125 +42738 -0.1234130859375 +42739 -0.391510009765625 +42740 -0.121307373046875 +42741 -0.385345458984375 +42742 -0.107513427734375 +42743 -0.3419189453125 +42744 -0.08880615234375 +42745 -0.28289794921875 +42746 -0.078704833984375 +42747 -0.251617431640625 +42748 -0.082855224609375 +42749 -0.266143798828125 +42750 -0.084716796875 +42751 -0.273345947265625 +42752 -0.066558837890625 +42753 -0.216796875 +42754 -0.038604736328125 +42755 -0.128265380859375 +42756 -0.02069091796875 +42757 -0.068145751953125 +42758 -0.014923095703125 +42759 -0.0430908203125 +42760 -0.01129150390625 +42761 -0.024444580078125 +42762 0.001678466796875 +42763 0.020721435546875 +42764 0.03515625 +42765 0.124481201171875 +42766 0.07928466796875 +42767 0.25787353515625 +42768 0.1197509765625 +42769 0.379119873046875 +42770 0.15380859375 +42771 0.47991943359375 +42772 0.17041015625 +42773 0.5281982421875 +42774 0.165130615234375 +42775 0.511138916015625 +42776 0.147369384765625 +42777 0.456207275390625 +42778 0.132232666015625 +42779 0.407470703125 +42780 0.1260986328125 +42781 0.383758544921875 +42782 0.119110107421875 +42783 0.35687255859375 +42784 0.10601806640625 +42785 0.31182861328125 +42786 0.087432861328125 +42787 0.250885009765625 +42788 0.060272216796875 +42789 0.1654052734375 +42790 0.017486572265625 +42791 0.035247802734375 +42792 -0.041839599609375 +42793 -0.142059326171875 +42794 -0.107147216796875 +42795 -0.33563232421875 +42796 -0.174774169921875 +42797 -0.5345458984375 +42798 -0.2388916015625 +42799 -0.72186279296875 +42800 -0.278564453125 +42801 -0.836669921875 +42802 -0.27783203125 +42803 -0.8326416015625 +42804 -0.24346923828125 +42805 -0.7296142578125 +42806 -0.1943359375 +42807 -0.582550048828125 +42808 -0.147064208984375 +42809 -0.440093994140625 +42810 -0.109161376953125 +42811 -0.324310302734375 +42812 -0.068878173828125 +42813 -0.20147705078125 +42814 -0.016845703125 +42815 -0.044647216796875 +42816 0.032501220703125 +42817 0.103973388671875 +42818 0.0648193359375 +42819 0.202392578125 +42820 0.0849609375 +42821 0.264495849609375 +42822 0.10968017578125 +42823 0.338897705078125 +42824 0.145294189453125 +42825 0.443817138671875 +42826 0.1800537109375 +42827 0.545074462890625 +42828 0.205230712890625 +42829 0.6173095703125 +42830 0.218017578125 +42831 0.6524658203125 +42832 0.222808837890625 +42833 0.66339111328125 +42834 0.22161865234375 +42835 0.6561279296875 +42836 0.20611572265625 +42837 0.606781005859375 +42838 0.17132568359375 +42839 0.501190185546875 +42840 0.121826171875 +42841 0.352783203125 +42842 0.06268310546875 +42843 0.176544189453125 +42844 -0.0086669921875 +42845 -0.034820556640625 +42846 -0.084320068359375 +42847 -0.258209228515625 +42848 -0.146759033203125 +42849 -0.44244384765625 +42850 -0.191802978515625 +42851 -0.5753173828125 +42852 -0.217864990234375 +42853 -0.65203857421875 +42854 -0.21429443359375 +42855 -0.641632080078125 +42856 -0.18731689453125 +42857 -0.562164306640625 +42858 -0.152191162109375 +42859 -0.458038330078125 +42860 -0.11614990234375 +42861 -0.350555419921875 +42862 -0.086334228515625 +42863 -0.260528564453125 +42864 -0.0640869140625 +42865 -0.192108154296875 +42866 -0.048187255859375 +42867 -0.141937255859375 +42868 -0.035858154296875 +42869 -0.1021728515625 +42870 -0.023590087890625 +42871 -0.062896728515625 +42872 -0.00714111328125 +42873 -0.011932373046875 +42874 0.0177001953125 +42875 0.062835693359375 +42876 0.046630859375 +42877 0.148712158203125 +42878 0.078277587890625 +42879 0.241729736328125 +42880 0.11517333984375 +42881 0.34912109375 +42882 0.152618408203125 +42883 0.457305908203125 +42884 0.182891845703125 +42885 0.54388427734375 +42886 0.193572998046875 +42887 0.5728759765625 +42888 0.171661376953125 +42889 0.506591796875 +42890 0.119232177734375 +42891 0.351226806640625 +42892 0.049896240234375 +42893 0.146514892578125 +42894 -0.018402099609375 +42895 -0.05523681640625 +42896 -0.072723388671875 +42897 -0.21624755859375 +42898 -0.112579345703125 +42899 -0.334930419921875 +42900 -0.135162353515625 +42901 -0.402984619140625 +42902 -0.147674560546875 +42903 -0.4412841796875 +42904 -0.165985107421875 +42905 -0.49578857421875 +42906 -0.187957763671875 +42907 -0.5601806640625 +42908 -0.20196533203125 +42909 -0.600738525390625 +42910 -0.19659423828125 +42911 -0.584228515625 +42912 -0.1610107421875 +42913 -0.47930908203125 +42914 -0.092926025390625 +42915 -0.27935791015625 +42916 -0.000732421875 +42917 -0.0089111328125 +42918 0.093841552734375 +42919 0.268798828125 +42920 0.166473388671875 +42921 0.482818603515625 +42922 0.207061767578125 +42923 0.60369873046875 +42924 0.222198486328125 +42925 0.650421142578125 +42926 0.226043701171875 +42927 0.66400146484375 +42928 0.21759033203125 +42929 0.6414794921875 +42930 0.193359375 +42931 0.572540283203125 +42932 0.16748046875 +42933 0.498138427734375 +42934 0.147216796875 +42935 0.439453125 +42936 0.125396728515625 +42937 0.375518798828125 +42938 0.091033935546875 +42939 0.274505615234375 +42940 0.034576416015625 +42941 0.1087646484375 +42942 -0.03631591796875 +42943 -0.099395751953125 +42944 -0.110748291015625 +42945 -0.3182373046875 +42946 -0.189208984375 +42947 -0.5489501953125 +42948 -0.265594482421875 +42949 -0.7738037109375 +42950 -0.32177734375 +42951 -0.86383056640625 +42952 -0.34637451171875 +42953 -0.870391845703125 +42954 -0.345550537109375 +42955 -0.86895751953125 +42956 -0.323822021484375 +42957 -0.861053466796875 +42958 -0.2752685546875 +42959 -0.765869140625 +42960 -0.196014404296875 +42961 -0.5301513671875 +42962 -0.088531494140625 +42963 -0.214691162109375 +42964 0.032379150390625 +42965 0.137359619140625 +42966 0.1490478515625 +42967 0.474822998046875 +42968 0.24932861328125 +42969 0.76239013671875 +42970 0.323944091796875 +42971 0.867462158203125 +42972 0.37310791015625 +42973 0.870361328125 +42974 0.39288330078125 +42975 0.86480712890625 +42976 0.385162353515625 +42977 0.831817626953125 +42978 0.358367919921875 +42979 0.677581787109375 +42980 0.314544677734375 +42981 0.495880126953125 +42982 0.260101318359375 +42983 0.30767822265625 +42984 0.195831298828125 +42985 0.116180419921875 +42986 0.11083984375 +42987 -0.110748291015625 +42988 0.002716064453125 +42989 -0.381805419921875 +42990 -0.113739013671875 +42991 -0.6572265625 +42992 -0.21795654296875 +42993 -0.857421875 +42994 -0.295196533203125 +42995 -0.870391845703125 +42996 -0.343017578125 +42997 -0.870391845703125 +42998 -0.3707275390625 +42999 -0.86444091796875 +43000 -0.390625 +43001 -0.85723876953125 +43002 -0.396453857421875 +43003 -0.790008544921875 +43004 -0.36962890625 +43005 -0.62847900390625 +43006 -0.30908203125 +43007 -0.3956298828125 +43008 -0.22607421875 +43009 -0.126708984375 +43010 -0.130035400390625 +43011 0.150115966796875 +43012 -0.024749755859375 +43013 0.424041748046875 +43014 0.080291748046875 +43015 0.670623779296875 +43016 0.171051025390625 +43017 0.854522705078125 +43018 0.24139404296875 +43019 0.866485595703125 +43020 0.285919189453125 +43021 0.86920166015625 +43022 0.31170654296875 +43023 0.8653564453125 +43024 0.323974609375 +43025 0.857147216796875 +43026 0.321685791015625 +43027 0.766845703125 +43028 0.30670166015625 +43029 0.628509521484375 +43030 0.276336669921875 +43031 0.462127685546875 +43032 0.24005126953125 +43033 0.297210693359375 +43034 0.202178955078125 +43035 0.14862060546875 +43036 0.153778076171875 +43037 -0.00537109375 +43038 0.0972900390625 +43039 -0.15753173828125 +43040 0.030975341796875 +43041 -0.31304931640625 +43042 -0.05078125 +43043 -0.48876953125 +43044 -0.130706787109375 +43045 -0.6416015625 +43046 -0.199798583984375 +43047 -0.751373291015625 +43048 -0.2669677734375 +43049 -0.84619140625 +43050 -0.32684326171875 +43051 -0.861297607421875 +43052 -0.367034912109375 +43053 -0.863250732421875 +43054 -0.3756103515625 +43055 -0.856597900390625 +43056 -0.357086181640625 +43057 -0.7498779296875 +43058 -0.33306884765625 +43059 -0.624542236328125 +43060 -0.2950439453125 +43061 -0.47808837890625 +43062 -0.220794677734375 +43063 -0.253387451171875 +43064 -0.127197265625 +43065 0.003692626953125 +43066 -0.0396728515625 +43067 0.2257080078125 +43068 0.046783447265625 +43069 0.427154541015625 +43070 0.1446533203125 +43071 0.643218994140625 +43072 0.250518798828125 +43073 0.855926513671875 +43074 0.342803955078125 +43075 0.870361328125 +43076 0.402984619140625 +43077 0.870361328125 +43078 0.433837890625 +43079 0.862762451171875 +43080 0.43426513671875 +43081 0.79669189453125 +43082 0.400665283203125 +43083 0.595794677734375 +43084 0.34393310546875 +43085 0.362152099609375 +43086 0.274444580078125 +43087 0.1270751953125 +43088 0.199981689453125 +43089 -0.086944580078125 +43090 0.121124267578125 +43091 -0.2784423828125 +43092 0.0245361328125 +43093 -0.484832763671875 +43094 -0.097198486328125 +43095 -0.729583740234375 +43096 -0.225250244140625 +43097 -0.86688232421875 +43098 -0.335968017578125 +43099 -0.870391845703125 +43100 -0.427642822265625 +43101 -0.86859130859375 +43102 -0.4996337890625 +43103 -0.86279296875 +43104 -0.5384521484375 +43105 -0.817962646484375 +43106 -0.52703857421875 +43107 -0.6116943359375 +43108 -0.46270751953125 +43109 -0.3128662109375 +43110 -0.358062744140625 +43111 0.039398193359375 +43112 -0.220550537109375 +43113 0.422821044921875 +43114 -0.06256103515625 +43115 0.805145263671875 +43116 0.090423583984375 +43117 0.870361328125 +43118 0.217071533203125 +43119 0.870361328125 +43120 0.313140869140625 +43121 0.860015869140625 +43122 0.3758544921875 +43123 0.727935791015625 +43124 0.403167724609375 +43125 0.48114013671875 +43126 0.404205322265625 +43127 0.2059326171875 +43128 0.38751220703125 +43129 -0.06103515625 +43130 0.35687255859375 +43131 -0.29913330078125 +43132 0.306854248046875 +43133 -0.516204833984375 +43134 0.231658935546875 +43135 -0.7252197265625 +43136 0.140625 +43137 -0.85980224609375 +43138 0.04669189453125 +43139 -0.870391845703125 +43140 -0.03900146484375 +43141 -0.870391845703125 +43142 -0.09814453125 +43143 -0.858062744140625 +43144 -0.129119873046875 +43145 -0.673004150390625 +43146 -0.151641845703125 +43147 -0.42694091796875 +43148 -0.182342529296875 +43149 -0.2100830078125 +43150 -0.2203369140625 +43151 -0.0362548828125 +43152 -0.254638671875 +43153 0.10943603515625 +43154 -0.2777099609375 +43155 0.23516845703125 +43156 -0.273956298828125 +43157 0.373687744140625 +43158 -0.244110107421875 +43159 0.517791748046875 +43160 -0.21185302734375 +43161 0.602783203125 +43162 -0.17523193359375 +43163 0.635711669921875 +43164 -0.121734619140625 +43165 0.655181884765625 +43166 -0.05517578125 +43167 0.65948486328125 +43168 0.021331787109375 +43169 0.651275634765625 +43170 0.098480224609375 +43171 0.61846923828125 +43172 0.162261962890625 +43173 0.53753662109375 +43174 0.20574951171875 +43175 0.404144287109375 +43176 0.2252197265625 +43177 0.22186279296875 +43178 0.2210693359375 +43179 0.003997802734375 +43180 0.200042724609375 +43181 -0.22100830078125 +43182 0.16986083984375 +43183 -0.42449951171875 +43184 0.13848876953125 +43185 -0.579833984375 +43186 0.121978759765625 +43187 -0.641876220703125 +43188 0.117828369140625 +43189 -0.6177978515625 +43190 0.101806640625 +43191 -0.575531005859375 +43192 0.07196044921875 +43193 -0.526336669921875 +43194 0.047821044921875 +43195 -0.42645263671875 +43196 0.039794921875 +43197 -0.2581787109375 +43198 0.0343017578125 +43199 -0.068695068359375 +43200 0.0169677734375 +43201 0.09222412109375 +43202 -0.005035400390625 +43203 0.232147216796875 +43204 -0.02777099609375 +43205 0.3509521484375 +43206 -0.062286376953125 +43207 0.410064697265625 +43208 -0.1195068359375 +43209 0.372955322265625 +43210 -0.191497802734375 +43211 0.2554931640625 +43212 -0.25860595703125 +43213 0.10711669921875 +43214 -0.31341552734375 +43215 -0.052886962890625 +43216 -0.342315673828125 +43217 -0.186279296875 +43218 -0.3243408203125 +43219 -0.23291015625 +43220 -0.268096923828125 +43221 -0.209442138671875 +43222 -0.19842529296875 +43223 -0.174163818359375 +43224 -0.1185302734375 +43225 -0.126739501953125 +43226 -0.02484130859375 +43227 -0.048126220703125 +43228 0.071929931640625 +43229 0.0426025390625 +43230 0.154144287109375 +43231 0.10748291015625 +43232 0.216705322265625 +43233 0.1409912109375 +43234 0.277374267578125 +43235 0.19708251953125 +43236 0.333526611328125 +43237 0.273651123046875 +43238 0.36407470703125 +43239 0.31768798828125 +43240 0.373138427734375 +43241 0.341094970703125 +43242 0.37017822265625 +43243 0.368011474609375 +43244 0.346527099609375 +43245 0.37249755859375 +43246 0.283660888671875 +43247 0.30072021484375 +43248 0.183502197265625 +43249 0.1517333984375 +43250 0.071136474609375 +43251 -0.01470947265625 +43252 -0.046661376953125 +43253 -0.1883544921875 +43254 -0.168304443359375 +43255 -0.372711181640625 +43256 -0.27069091796875 +43257 -0.51397705078125 +43258 -0.336029052734375 +43259 -0.57177734375 +43260 -0.359619140625 +43261 -0.53948974609375 +43262 -0.346527099609375 +43263 -0.43511962890625 +43264 -0.3094482421875 +43265 -0.2962646484375 +43266 -0.2620849609375 +43267 -0.161102294921875 +43268 -0.209930419921875 +43269 -0.0435791015625 +43270 -0.15228271484375 +43271 0.060394287109375 +43272 -0.096221923828125 +43273 0.13665771484375 +43274 -0.049591064453125 +43275 0.170135498046875 +43276 -0.012664794921875 +43277 0.16552734375 +43278 0.02593994140625 +43279 0.15728759765625 +43280 0.065948486328125 +43281 0.150787353515625 +43282 0.09539794921875 +43283 0.12200927734375 +43284 0.115753173828125 +43285 0.080108642578125 +43286 0.135589599609375 +43287 0.05126953125 +43288 0.164337158203125 +43289 0.062896728515625 +43290 0.191986083984375 +43291 0.09271240234375 +43292 0.1988525390625 +43293 0.092987060546875 +43294 0.190765380859375 +43295 0.07855224609375 +43296 0.174072265625 +43297 0.06427001953125 +43298 0.14349365234375 +43299 0.0347900390625 +43300 0.099578857421875 +43301 -0.01171875 +43302 0.051544189453125 +43303 -0.056060791015625 +43304 0.018310546875 +43305 -0.055511474609375 +43306 0.001617431640625 +43307 -0.010467529296875 +43308 -0.018157958984375 +43309 0.02508544921875 +43310 -0.04937744140625 +43311 0.025665283203125 +43312 -0.0799560546875 +43313 0.017333984375 +43314 -0.107818603515625 +43315 0.00189208984375 +43316 -0.136383056640625 +43317 -0.03173828125 +43318 -0.16021728515625 +43319 -0.071502685546875 +43320 -0.186279296875 +43321 -0.13543701171875 +43322 -0.21337890625 +43323 -0.219970703125 +43324 -0.232177734375 +43325 -0.300506591796875 +43326 -0.243316650390625 +43327 -0.376312255859375 +43328 -0.23553466796875 +43329 -0.416107177734375 +43330 -0.190765380859375 +43331 -0.371124267578125 +43332 -0.11090087890625 +43333 -0.242279052734375 +43334 -0.013580322265625 +43335 -0.069732666015625 +43336 0.091278076171875 +43337 0.125640869140625 +43338 0.189788818359375 +43339 0.31268310546875 +43340 0.266204833984375 +43341 0.45501708984375 +43342 0.3204345703125 +43343 0.554779052734375 +43344 0.351348876953125 +43345 0.61065673828125 +43346 0.35394287109375 +43347 0.610931396484375 +43348 0.318603515625 +43349 0.531463623046875 +43350 0.252105712890625 +43351 0.3883056640625 +43352 0.176422119140625 +43353 0.23468017578125 +43354 0.10235595703125 +43355 0.095245361328125 +43356 0.041412353515625 +43357 -0.00396728515625 +43358 0.000579833984375 +43359 -0.04852294921875 +43360 -0.025482177734375 +43361 -0.055145263671875 +43362 -0.0562744140625 +43363 -0.0758056640625 +43364 -0.101898193359375 +43365 -0.138702392578125 +43366 -0.147430419921875 +43367 -0.209197998046875 +43368 -0.19268798828125 +43369 -0.289031982421875 +43370 -0.23736572265625 +43371 -0.37884521484375 +43372 -0.27215576171875 +43373 -0.456329345703125 +43374 -0.29498291015625 +43375 -0.51641845703125 +43376 -0.290130615234375 +43377 -0.519287109375 +43378 -0.25537109375 +43379 -0.458251953125 +43380 -0.212005615234375 +43381 -0.384796142578125 +43382 -0.1707763671875 +43383 -0.323699951171875 +43384 -0.130401611328125 +43385 -0.269287109375 +43386 -0.081451416015625 +43387 -0.1951904296875 +43388 -0.0244140625 +43389 -0.100006103515625 +43390 0.0289306640625 +43391 -0.01055908203125 +43392 0.089752197265625 +43393 0.1033935546875 +43394 0.160186767578125 +43395 0.24908447265625 +43396 0.21832275390625 +43397 0.373199462890625 +43398 0.256744384765625 +43399 0.45806884765625 +43400 0.2784423828125 +43401 0.511474609375 +43402 0.296295166015625 +43403 0.565399169921875 +43404 0.307281494140625 +43405 0.61138916015625 +43406 0.287994384765625 +43407 0.5897216796875 +43408 0.23516845703125 +43409 0.4906005859375 +43410 0.156585693359375 +43411 0.33148193359375 +43412 0.067291259765625 +43413 0.147796630859375 +43414 -0.015106201171875 +43415 -0.01873779296875 +43416 -0.07861328125 +43417 -0.140289306640625 +43418 -0.112518310546875 +43419 -0.191986083984375 +43420 -0.120330810546875 +43421 -0.184295654296875 +43422 -0.119354248046875 +43423 -0.161834716796875 +43424 -0.126007080078125 +43425 -0.166595458984375 +43426 -0.1383056640625 +43427 -0.19390869140625 +43428 -0.14849853515625 +43429 -0.22442626953125 +43430 -0.165435791015625 +43431 -0.279754638671875 +43432 -0.18115234375 +43433 -0.3389892578125 +43434 -0.177093505859375 +43435 -0.3543701171875 +43436 -0.162750244140625 +43437 -0.348175048828125 +43438 -0.14105224609375 +43439 -0.32598876953125 +43440 -0.10089111328125 +43441 -0.2581787109375 +43442 -0.040985107421875 +43443 -0.139801025390625 +43444 0.03216552734375 +43445 0.014617919921875 +43446 0.093658447265625 +43447 0.144378662109375 +43448 0.131683349609375 +43449 0.221038818359375 +43450 0.156341552734375 +43451 0.27069091796875 +43452 0.167724609375 +43453 0.294036865234375 +43454 0.174072265625 +43455 0.311767578125 +43456 0.181640625 +43457 0.339141845703125 +43458 0.184417724609375 +43459 0.360260009765625 +43460 0.176910400390625 +43461 0.360504150390625 +43462 0.146728515625 +43463 0.308380126953125 +43464 0.085296630859375 +43465 0.18170166015625 +43466 0.003082275390625 +43467 0.0047607421875 +43468 -0.08026123046875 +43469 -0.17559814453125 +43470 -0.145843505859375 +43471 -0.3143310546875 +43472 -0.175445556640625 +43473 -0.36785888671875 +43474 -0.179412841796875 +43475 -0.36248779296875 +43476 -0.175933837890625 +43477 -0.343536376953125 +43478 -0.1611328125 +43479 -0.3018798828125 +43480 -0.132415771484375 +43481 -0.231414794921875 +43482 -0.083953857421875 +43483 -0.117645263671875 +43484 -0.029144287109375 +43485 0.007049560546875 +43486 0.009429931640625 +43487 0.087982177734375 +43488 0.037261962890625 +43489 0.13946533203125 +43490 0.059173583984375 +43491 0.17425537109375 +43492 0.073028564453125 +43493 0.188201904296875 +43494 0.07421875 +43495 0.171234130859375 +43496 0.060333251953125 +43497 0.118438720703125 +43498 0.0421142578125 +43499 0.05706787109375 +43500 0.020050048828125 +43501 -0.010711669921875 +43502 -0.0087890625 +43503 -0.0914306640625 +43504 -0.035247802734375 +43505 -0.162322998046875 +43506 -0.047698974609375 +43507 -0.194549560546875 +43508 -0.0302734375 +43509 -0.1492919921875 +43510 0.01910400390625 +43511 -0.02166748046875 +43512 0.074432373046875 +43513 0.124053955078125 +43514 0.104644775390625 +43515 0.211151123046875 +43516 0.11041259765625 +43517 0.240447998046875 +43518 0.104461669921875 +43519 0.242218017578125 +43520 0.091461181640625 +43521 0.2257080078125 +43522 0.07293701171875 +43523 0.194366455078125 +43524 0.034149169921875 +43525 0.115509033203125 +43526 -0.014190673828125 +43527 0.0128173828125 +43528 -0.04559326171875 +43529 -0.053802490234375 +43530 -0.071502685546875 +43531 -0.110626220703125 +43532 -0.11029052734375 +43533 -0.199493408203125 +43534 -0.150543212890625 +43535 -0.29437255859375 +43536 -0.16461181640625 +43537 -0.33221435546875 +43538 -0.13800048828125 +43539 -0.27972412109375 +43540 -0.092254638671875 +43541 -0.185333251953125 +43542 -0.06243896484375 +43543 -0.128204345703125 +43544 -0.052032470703125 +43545 -0.115692138671875 +43546 -0.047515869140625 +43547 -0.116455078125 +43548 -0.038330078125 +43549 -0.105926513671875 +43550 -0.011474609375 +43551 -0.053955078125 +43552 0.036956787109375 +43553 0.048797607421875 +43554 0.087005615234375 +43555 0.157318115234375 +43556 0.112335205078125 +43557 0.212005615234375 +43558 0.115386962890625 +43559 0.218475341796875 +43560 0.122802734375 +43561 0.23724365234375 +43562 0.150970458984375 +43563 0.30535888671875 +43564 0.18170166015625 +43565 0.38128662109375 +43566 0.188507080078125 +43567 0.404449462890625 +43568 0.180206298828125 +43569 0.3944091796875 +43570 0.1734619140625 +43571 0.3885498046875 +43572 0.157867431640625 +43573 0.362640380859375 +43574 0.114715576171875 +43575 0.27362060546875 +43576 0.042327880859375 +43577 0.11712646484375 +43578 -0.0362548828125 +43579 -0.054901123046875 +43580 -0.09820556640625 +43581 -0.19085693359375 +43582 -0.141204833984375 +43583 -0.28570556640625 +43584 -0.165130615234375 +43585 -0.339263916015625 +43586 -0.18145751953125 +43587 -0.3775634765625 +43588 -0.210052490234375 +43589 -0.445709228515625 +43590 -0.24725341796875 +43591 -0.535064697265625 +43592 -0.285888671875 +43593 -0.629058837890625 +43594 -0.3128662109375 +43595 -0.697601318359375 +43596 -0.31219482421875 +43597 -0.70391845703125 +43598 -0.281646728515625 +43599 -0.6424560546875 +43600 -0.21173095703125 +43601 -0.491241455078125 +43602 -0.10943603515625 +43603 -0.265716552734375 +43604 -0.0003662109375 +43605 -0.023712158203125 +43606 0.10076904296875 +43607 0.201751708984375 +43608 0.1785888671875 +43609 0.375823974609375 +43610 0.227142333984375 +43611 0.485076904296875 +43612 0.26373291015625 +43613 0.56884765625 +43614 0.291748046875 +43615 0.634765625 +43616 0.2913818359375 +43617 0.63763427734375 +43618 0.2576904296875 +43619 0.5660400390625 +43620 0.213714599609375 +43621 0.4720458984375 +43622 0.182159423828125 +43623 0.40692138671875 +43624 0.166351318359375 +43625 0.3778076171875 +43626 0.163055419921875 +43627 0.376953125 +43628 0.158172607421875 +43629 0.371978759765625 +43630 0.129974365234375 +43631 0.313140869140625 +43632 0.071502685546875 +43633 0.184417724609375 +43634 -0.005950927734375 +43635 0.011199951171875 +43636 -0.08673095703125 +43637 -0.171051025390625 +43638 -0.15985107421875 +43639 -0.33740234375 +43640 -0.21832275390625 +43641 -0.47198486328125 +43642 -0.25592041015625 +43643 -0.560394287109375 +43644 -0.26300048828125 +43645 -0.58056640625 +43646 -0.24627685546875 +43647 -0.54754638671875 +43648 -0.226715087890625 +43649 -0.508575439453125 +43650 -0.20263671875 +43651 -0.459503173828125 +43652 -0.171539306640625 +43653 -0.394378662109375 +43654 -0.150848388671875 +43655 -0.35260009765625 +43656 -0.13079833984375 +43657 -0.31170654296875 +43658 -0.078826904296875 +43659 -0.197418212890625 +43660 0.0057373046875 +43661 -0.007965087890625 +43662 0.101165771484375 +43663 0.207489013671875 +43664 0.189971923828125 +43665 0.409210205078125 +43666 0.2611083984375 +43667 0.57208251953125 +43668 0.301361083984375 +43669 0.66595458984375 +43670 0.296722412109375 +43671 0.65875244140625 +43672 0.254730224609375 +43673 0.56744384765625 +43674 0.192840576171875 +43675 0.431396484375 +43676 0.130462646484375 +43677 0.29443359375 +43678 0.079071044921875 +43679 0.182464599609375 +43680 0.024810791015625 +43681 0.06365966796875 +43682 -0.038360595703125 +43683 -0.075958251953125 +43684 -0.089691162109375 +43685 -0.189422607421875 +43686 -0.126983642578125 +43687 -0.271942138671875 +43688 -0.1585693359375 +43689 -0.342529296875 +43690 -0.168182373046875 +43691 -0.364166259765625 +43692 -0.151580810546875 +43693 -0.327239990234375 +43694 -0.128692626953125 +43695 -0.2769775390625 +43696 -0.117340087890625 +43697 -0.253692626953125 +43698 -0.11151123046875 +43699 -0.24365234375 +43700 -0.089996337890625 +43701 -0.1983642578125 +43702 -0.052154541015625 +43703 -0.116241455078125 +43704 -0.015472412109375 +43705 -0.036834716796875 +43706 0.017730712890625 +43707 0.034881591796875 +43708 0.04400634765625 +43709 0.09124755859375 +43710 0.053009033203125 +43711 0.10888671875 +43712 0.061248779296875 +43713 0.125518798828125 +43714 0.07598876953125 +43715 0.15771484375 +43716 0.085235595703125 +43717 0.17828369140625 +43718 0.08184814453125 +43719 0.17108154296875 +43720 0.063201904296875 +43721 0.129974365234375 +43722 0.041412353515625 +43723 0.082427978515625 +43724 0.016204833984375 +43725 0.027679443359375 +43726 -0.026123046875 +43727 -0.065643310546875 +43728 -0.0687255859375 +43729 -0.15936279296875 +43730 -0.09375 +43731 -0.21307373046875 +43732 -0.104583740234375 +43733 -0.234649658203125 +43734 -0.09063720703125 +43735 -0.2001953125 +43736 -0.055999755859375 +43737 -0.119171142578125 +43738 -0.015228271484375 +43739 -0.024749755859375 +43740 0.03289794921875 +43741 0.085784912109375 +43742 0.073272705078125 +43743 0.178131103515625 +43744 0.08978271484375 +43745 0.215576171875 +43746 0.0882568359375 +43747 0.211456298828125 +43748 0.072845458984375 +43749 0.17523193359375 +43750 0.053131103515625 +43751 0.128753662109375 +43752 0.042236328125 +43753 0.1019287109375 +43754 0.0311279296875 +43755 0.0743408203125 +43756 0.0185546875 +43757 0.04327392578125 +43758 0.01739501953125 +43759 0.038177490234375 +43760 0.03515625 +43761 0.076263427734375 +43762 0.064544677734375 +43763 0.14105224609375 +43764 0.085235595703125 +43765 0.186431884765625 +43766 0.0867919921875 +43767 0.188812255859375 +43768 0.065185546875 +43769 0.1390380859375 +43770 0.0224609375 +43771 0.041778564453125 +43772 -0.031005859375 +43773 -0.079437255859375 +43774 -0.0928955078125 +43775 -0.219390869140625 +43776 -0.15899658203125 +43777 -0.367828369140625 +43778 -0.21661376953125 +43779 -0.494873046875 +43780 -0.2452392578125 +43781 -0.556243896484375 +43782 -0.224151611328125 +43783 -0.508697509765625 +43784 -0.164031982421875 +43785 -0.3756103515625 +43786 -0.093719482421875 +43787 -0.218902587890625 +43788 -0.0247802734375 +43789 -0.063751220703125 +43790 0.043975830078125 +43791 0.091552734375 +43792 0.107696533203125 +43793 0.23602294921875 +43794 0.15411376953125 +43795 0.342987060546875 +43796 0.17535400390625 +43797 0.39520263671875 +43798 0.16998291015625 +43799 0.389373779296875 +43800 0.137542724609375 +43801 0.324249267578125 +43802 0.08953857421875 +43803 0.224090576171875 +43804 0.042694091796875 +43805 0.124267578125 +43806 0.002716064453125 +43807 0.037078857421875 +43808 -0.017547607421875 +43809 -0.010101318359375 +43810 -0.019287109375 +43811 -0.019439697265625 +43812 -0.0177001953125 +43813 -0.022796630859375 +43814 -0.004180908203125 +43815 -0.001556396484375 +43816 0.026702880859375 +43817 0.056304931640625 +43818 0.053924560546875 +43819 0.106719970703125 +43820 0.05242919921875 +43821 0.096893310546875 +43822 0.029541015625 +43823 0.042694091796875 +43824 0.002960205078125 +43825 -0.018035888671875 +43826 -0.022918701171875 +43827 -0.07586669921875 +43828 -0.04278564453125 +43829 -0.11944580078125 +43830 -0.061859130859375 +43831 -0.15972900390625 +43832 -0.0828857421875 +43833 -0.202606201171875 +43834 -0.10601806640625 +43835 -0.24859619140625 +43836 -0.134674072265625 +43837 -0.30517578125 +43838 -0.1639404296875 +43839 -0.36212158203125 +43840 -0.180450439453125 +43841 -0.39141845703125 +43842 -0.16619873046875 +43843 -0.35528564453125 +43844 -0.1192626953125 +43845 -0.249969482421875 +43846 -0.0477294921875 +43847 -0.092864990234375 +43848 0.035797119140625 +43849 0.08905029296875 +43850 0.102874755859375 +43851 0.2352294921875 +43852 0.140899658203125 +43853 0.318817138671875 +43854 0.1588134765625 +43855 0.358642578125 +43856 0.15338134765625 +43857 0.347747802734375 +43858 0.1243896484375 +43859 0.28564453125 +43860 0.09576416015625 +43861 0.223175048828125 +43862 0.084625244140625 +43863 0.196746826171875 +43864 0.078399658203125 +43865 0.179840087890625 +43866 0.069000244140625 +43867 0.155548095703125 +43868 0.069183349609375 +43869 0.151214599609375 +43870 0.074188232421875 +43871 0.156951904296875 +43872 0.06451416015625 +43873 0.13177490234375 +43874 0.051910400390625 +43875 0.100799560546875 +43876 0.04718017578125 +43877 0.087127685546875 +43878 0.0333251953125 +43879 0.05487060546875 +43880 0.004119873046875 +43881 -0.009002685546875 +43882 -0.040252685546875 +43883 -0.10400390625 +43884 -0.099456787109375 +43885 -0.229400634765625 +43886 -0.159454345703125 +43887 -0.35552978515625 +43888 -0.20111083984375 +43889 -0.441925048828125 +43890 -0.217437744140625 +43891 -0.473846435546875 +43892 -0.2147216796875 +43893 -0.464813232421875 +43894 -0.19488525390625 +43895 -0.419097900390625 +43896 -0.156707763671875 +43897 -0.334320068359375 +43898 -0.1082763671875 +43899 -0.227935791015625 +43900 -0.060638427734375 +43901 -0.12347412109375 +43902 -0.01690673828125 +43903 -0.02764892578125 +43904 0.03155517578125 +43905 0.077667236328125 +43906 0.0946044921875 +43907 0.2132568359375 +43908 0.1768798828125 +43909 0.38885498046875 +43910 0.2681884765625 +43911 0.582794189453125 +43912 0.3397216796875 +43913 0.734039306640625 +43914 0.371429443359375 +43915 0.800140380859375 +43916 0.361968994140625 +43917 0.7783203125 +43918 0.309661865234375 +43919 0.6651611328125 +43920 0.2139892578125 +43921 0.45965576171875 +43922 0.092529296875 +43923 0.199188232421875 +43924 -0.02386474609375 +43925 -0.050689697265625 +43926 -0.108367919921875 +43927 -0.23297119140625 +43928 -0.15283203125 +43929 -0.33013916015625 +43930 -0.169677734375 +43931 -0.368408203125 +43932 -0.173675537109375 +43933 -0.378936767578125 +43934 -0.172088623046875 +43935 -0.376983642578125 +43936 -0.173065185546875 +43937 -0.37969970703125 +43938 -0.178680419921875 +43939 -0.391510009765625 +43940 -0.176116943359375 +43941 -0.385345458984375 +43942 -0.15625 +43943 -0.3419189453125 +43944 -0.1292724609375 +43945 -0.28289794921875 +43946 -0.115570068359375 +43947 -0.251617431640625 +43948 -0.12359619140625 +43949 -0.266143798828125 +43950 -0.12823486328125 +43951 -0.273345947265625 +43952 -0.102752685546875 +43953 -0.216796875 +43954 -0.06207275390625 +43955 -0.128265380859375 +43956 -0.03466796875 +43957 -0.068145751953125 +43958 -0.02362060546875 +43959 -0.0430908203125 +43960 -0.015380859375 +43961 -0.024444580078125 +43962 0.005615234375 +43963 0.020721435546875 +43964 0.05450439453125 +43965 0.124481201171875 +43966 0.117584228515625 +43967 0.25787353515625 +43968 0.175140380859375 +43969 0.379119873046875 +43970 0.223236083984375 +43971 0.47991943359375 +43972 0.2467041015625 +43973 0.5281982421875 +43974 0.239471435546875 +43975 0.511138916015625 +43976 0.214447021484375 +43977 0.456207275390625 +43978 0.192352294921875 +43979 0.407470703125 +43980 0.182037353515625 +43981 0.383758544921875 +43982 0.170135498046875 +43983 0.35687255859375 +43984 0.1495361328125 +43985 0.31182861328125 +43986 0.121246337890625 +43987 0.250885009765625 +43988 0.081207275390625 +43989 0.1654052734375 +43990 0.019927978515625 +43991 0.035247802734375 +43992 -0.063751220703125 +43993 -0.142059326171875 +43994 -0.155242919921875 +43995 -0.33563232421875 +43996 -0.249420166015625 +43997 -0.5345458984375 +43998 -0.3382568359375 +43999 -0.72186279296875 +44000 -0.392974853515625 +44001 -0.836669921875 +44002 -0.391693115234375 +44003 -0.8326416015625 +44004 -0.343719482421875 +44005 -0.7296142578125 +44006 -0.27496337890625 +44007 -0.582550048828125 +44008 -0.208343505859375 +44009 -0.440093994140625 +44010 -0.154266357421875 +44011 -0.324310302734375 +44012 -0.09674072265625 +44013 -0.20147705078125 +44014 -0.02301025390625 +44015 -0.044647216796875 +44016 0.04693603515625 +44017 0.103973388671875 +44018 0.093292236328125 +44019 0.202392578125 +44020 0.122650146484375 +44021 0.264495849609375 +44022 0.157928466796875 +44023 0.338897705078125 +44024 0.20770263671875 +44025 0.443817138671875 +44026 0.255859375 +44027 0.545074462890625 +44028 0.290374755859375 +44029 0.6173095703125 +44030 0.30743408203125 +44031 0.6524658203125 +44032 0.31341552734375 +44033 0.66339111328125 +44034 0.311309814453125 +44035 0.6561279296875 +44036 0.289154052734375 +44037 0.606781005859375 +44038 0.239654541015625 +44039 0.501190185546875 +44040 0.169342041015625 +44041 0.352783203125 +44042 0.085479736328125 +44043 0.176544189453125 +44044 -0.015899658203125 +44045 -0.034820556640625 +44046 -0.123443603515625 +44047 -0.258209228515625 +44048 -0.211669921875 +44049 -0.44244384765625 +44050 -0.274658203125 +44051 -0.5753173828125 +44052 -0.31024169921875 +44053 -0.65203857421875 +44054 -0.302978515625 +44055 -0.641632080078125 +44056 -0.262054443359375 +44057 -0.562164306640625 +44058 -0.20989990234375 +44059 -0.458038330078125 +44060 -0.15716552734375 +44061 -0.350555419921875 +44062 -0.114227294921875 +44063 -0.260528564453125 +44064 -0.083038330078125 +44065 -0.192108154296875 +44066 -0.06170654296875 +44067 -0.141937255859375 +44068 -0.046051025390625 +44069 -0.1021728515625 +44070 -0.030792236328125 +44071 -0.062896728515625 +44072 -0.009552001953125 +44073 -0.011932373046875 +44074 0.02398681640625 +44075 0.062835693359375 +44076 0.063690185546875 +44077 0.148712158203125 +44078 0.107696533203125 +44079 0.241729736328125 +44080 0.159820556640625 +44081 0.34912109375 +44082 0.2132568359375 +44083 0.457305908203125 +44084 0.25677490234375 +44085 0.54388427734375 +44086 0.272216796875 +44087 0.5728759765625 +44088 0.240509033203125 +44089 0.506591796875 +44090 0.1646728515625 +44091 0.351226806640625 +44092 0.0645751953125 +44093 0.146514892578125 +44094 -0.033599853515625 +44095 -0.05523681640625 +44096 -0.11102294921875 +44097 -0.21624755859375 +44098 -0.167083740234375 +44099 -0.334930419921875 +44100 -0.19781494140625 +44101 -0.402984619140625 +44102 -0.21392822265625 +44103 -0.4412841796875 +44104 -0.238739013671875 +44105 -0.49578857421875 +44106 -0.269195556640625 +44107 -0.5601806640625 +44108 -0.288360595703125 +44109 -0.600738525390625 +44110 -0.279571533203125 +44111 -0.584228515625 +44112 -0.227020263671875 +44113 -0.47930908203125 +44114 -0.127349853515625 +44115 -0.27935791015625 +44116 0.007110595703125 +44117 -0.0089111328125 +44118 0.1446533203125 +44119 0.268798828125 +44120 0.249664306640625 +44121 0.482818603515625 +44122 0.307464599609375 +44123 0.60369873046875 +44124 0.3277587890625 +44125 0.650421142578125 +44126 0.331451416015625 +44127 0.66400146484375 +44128 0.31719970703125 +44129 0.6414794921875 +44130 0.279998779296875 +44131 0.572540283203125 +44132 0.2406005859375 +44133 0.498138427734375 +44134 0.209747314453125 +44135 0.439453125 +44136 0.176910400390625 +44137 0.375518798828125 +44138 0.126068115234375 +44139 0.274505615234375 +44140 0.04327392578125 +44141 0.1087646484375 +44142 -0.060272216796875 +44143 -0.099395751953125 +44144 -0.16864013671875 +44145 -0.3182373046875 +44146 -0.2825927734375 +44147 -0.5489501953125 +44148 -0.393280029296875 +44149 -0.7738037109375 +44150 -0.474212646484375 +44151 -0.86383056640625 +44152 -0.5087890625 +44153 -0.870391845703125 +44154 -0.506072998046875 +44155 -0.86895751953125 +44156 -0.472808837890625 +44157 -0.861053466796875 +44158 -0.400390625 +44159 -0.765869140625 +44160 -0.283203125 +44161 -0.5301513671875 +44162 -0.124908447265625 +44163 -0.214691162109375 +44164 0.052764892578125 +44165 0.137359619140625 +44166 0.223968505859375 +44167 0.474822998046875 +44168 0.370819091796875 +44169 0.76239013671875 +44170 0.479766845703125 +44171 0.867462158203125 +44172 0.5511474609375 +44173 0.870361328125 +44174 0.579254150390625 +44175 0.86480712890625 +44176 0.56689453125 +44177 0.831817626953125 +44178 0.5264892578125 +44179 0.677581787109375 +44180 0.4610595703125 +44181 0.495880126953125 +44182 0.380096435546875 +44183 0.30767822265625 +44184 0.28485107421875 +44185 0.116180419921875 +44186 0.15936279296875 +44187 -0.110748291015625 +44188 0.000213623046875 +44189 -0.381805419921875 +44190 -0.170989990234375 +44191 -0.6572265625 +44192 -0.32403564453125 +44193 -0.857421875 +44194 -0.43731689453125 +44195 -0.870391845703125 +44196 -0.50726318359375 +44197 -0.870391845703125 +44198 -0.5474853515625 +44199 -0.86444091796875 +44200 -0.576080322265625 +44201 -0.85723876953125 +44202 -0.583892822265625 +44203 -0.790008544921875 +44204 -0.543701171875 +44205 -0.62847900390625 +44206 -0.454010009765625 +44207 -0.3956298828125 +44208 -0.331451416015625 +44209 -0.126708984375 +44210 -0.18994140625 +44211 0.150115966796875 +44212 -0.035430908203125 +44213 0.424041748046875 +44214 0.118408203125 +44215 0.670623779296875 +44216 0.251983642578125 +44217 0.854522705078125 +44218 0.35638427734375 +44219 0.866485595703125 +44220 0.423858642578125 +44221 0.86920166015625 +44222 0.46356201171875 +44223 0.8653564453125 +44224 0.482330322265625 +44225 0.857147216796875 +44226 0.478729248046875 +44227 0.766845703125 +44228 0.455413818359375 +44229 0.628509521484375 +44230 0.409088134765625 +44231 0.462127685546875 +44232 0.352813720703125 +44233 0.297210693359375 +44234 0.292938232421875 +44235 0.14862060546875 +44236 0.218017578125 +44237 -0.00537109375 +44238 0.13189697265625 +44239 -0.15753173828125 +44240 0.032806396484375 +44241 -0.31304931640625 +44242 -0.08624267578125 +44243 -0.48876953125 +44244 -0.20159912109375 +44245 -0.6416015625 +44246 -0.300750732421875 +44247 -0.751373291015625 +44248 -0.395355224609375 +44249 -0.84619140625 +44250 -0.477996826171875 +44251 -0.861297607421875 +44252 -0.532012939453125 +44253 -0.863250732421875 +44254 -0.54150390625 +44255 -0.856597900390625 +44256 -0.512664794921875 +44257 -0.7498779296875 +44258 -0.4747314453125 +44259 -0.624542236328125 +44260 -0.41668701171875 +44261 -0.47808837890625 +44262 -0.30914306640625 +44263 -0.253387451171875 +44264 -0.175201416015625 +44265 0.003692626953125 +44266 -0.04937744140625 +44267 0.2257080078125 +44268 0.074554443359375 +44269 0.427154541015625 +44270 0.212860107421875 +44271 0.643218994140625 +44272 0.36065673828125 +44273 0.855926513671875 +44274 0.488739013671875 +44275 0.870361328125 +44276 0.57208251953125 +44277 0.870361328125 +44278 0.614288330078125 +44279 0.862762451171875 +44280 0.6138916015625 +44281 0.79669189453125 +44282 0.566192626953125 +44283 0.595794677734375 +44284 0.4859619140625 +44285 0.362152099609375 +44286 0.38739013671875 +44287 0.1270751953125 +44288 0.281768798828125 +44289 -0.086944580078125 +44290 0.17059326171875 +44291 -0.2784423828125 +44292 0.034942626953125 +44293 -0.484832763671875 +44294 -0.136199951171875 +44295 -0.729583740234375 +44296 -0.316375732421875 +44297 -0.86688232421875 +44298 -0.47222900390625 +44299 -0.870391845703125 +44300 -0.60150146484375 +44301 -0.86859130859375 +44302 -0.703338623046875 +44303 -0.86279296875 +44304 -0.75860595703125 +44305 -0.817962646484375 +44306 -0.74298095703125 +44307 -0.6116943359375 +44308 -0.65252685546875 +44309 -0.3128662109375 +44310 -0.505126953125 +44311 0.039398193359375 +44312 -0.31121826171875 +44313 0.422821044921875 +44314 -0.08831787109375 +44315 0.805145263671875 +44316 0.12738037109375 +44317 0.870361328125 +44318 0.3056640625 +44319 0.870361328125 +44320 0.440582275390625 +44321 0.860015869140625 +44322 0.528289794921875 +44323 0.727935791015625 +44324 0.565948486328125 +44325 0.48114013671875 +44326 0.566680908203125 +44327 0.2059326171875 +44328 0.542694091796875 +44329 -0.06103515625 +44330 0.499359130859375 +44331 -0.29913330078125 +44332 0.42889404296875 +44333 -0.516204833984375 +44334 0.322998046875 +44335 -0.7252197265625 +44336 0.19488525390625 +44337 -0.85980224609375 +44338 0.0628662109375 +44339 -0.870391845703125 +44340 -0.057281494140625 +44341 -0.870391845703125 +44342 -0.1395263671875 +44343 -0.858062744140625 +44344 -0.18170166015625 +44345 -0.673004150390625 +44346 -0.21197509765625 +44347 -0.42694091796875 +44348 -0.254180908203125 +44349 -0.2100830078125 +44350 -0.30718994140625 +44351 -0.0362548828125 +44352 -0.355377197265625 +44353 0.10943603515625 +44354 -0.388031005859375 +44355 0.23516845703125 +44356 -0.382904052734375 +44357 0.373687744140625 +44358 -0.340972900390625 +44359 0.517791748046875 +44360 -0.29595947265625 +44361 0.602783203125 +44362 -0.24505615234375 +44363 0.635711669921875 +44364 -0.17034912109375 +44365 0.655181884765625 +44366 -0.077178955078125 +44367 0.65948486328125 +44368 0.030120849609375 +44369 0.651275634765625 +44370 0.138427734375 +44371 0.61846923828125 +44372 0.22784423828125 +44373 0.53753662109375 +44374 0.288604736328125 +44375 0.404144287109375 +44376 0.3154296875 +44377 0.22186279296875 +44378 0.30889892578125 +44379 0.003997802734375 +44380 0.278656005859375 +44381 -0.22100830078125 +44382 0.235687255859375 +44383 -0.42449951171875 +44384 0.191375732421875 +44385 -0.579833984375 +44386 0.168548583984375 +44387 -0.641876220703125 +44388 0.16363525390625 +44389 -0.6177978515625 +44390 0.141998291015625 +44391 -0.575531005859375 +44392 0.100799560546875 +44393 -0.526336669921875 +44394 0.06781005859375 +44395 -0.42645263671875 +44396 0.05780029296875 +44397 -0.2581787109375 +44398 0.05133056640625 +44399 -0.068695068359375 +44400 0.027862548828125 +44401 0.09222412109375 +44402 -0.00250244140625 +44403 0.232147216796875 +44404 -0.034210205078125 +44405 0.3509521484375 +44406 -0.083038330078125 +44407 0.410064697265625 +44408 -0.164581298828125 +44409 0.372955322265625 +44410 -0.26751708984375 +44411 0.2554931640625 +44412 -0.363800048828125 +44413 0.10711669921875 +44414 -0.44287109375 +44415 -0.052886962890625 +44416 -0.4852294921875 +44417 -0.186279296875 +44418 -0.46087646484375 +44419 -0.23291015625 +44420 -0.382049560546875 +44421 -0.209442138671875 +44422 -0.2840576171875 +44423 -0.174163818359375 +44424 -0.171417236328125 +44425 -0.126739501953125 +44426 -0.0389404296875 +44427 -0.048126220703125 +44428 0.09814453125 +44429 0.0426025390625 +44430 0.2147216796875 +44431 0.10748291015625 +44432 0.303558349609375 +44433 0.1409912109375 +44434 0.3900146484375 +44435 0.19708251953125 +44436 0.470306396484375 +44437 0.273651123046875 +44438 0.514404296875 +44439 0.31768798828125 +44440 0.528106689453125 +44441 0.341094970703125 +44442 0.52484130859375 +44443 0.368011474609375 +44444 0.4921875 +44445 0.37249755859375 +44446 0.403717041015625 +44447 0.30072021484375 +44448 0.2620849609375 +44449 0.1517333984375 +44450 0.102996826171875 +44451 -0.01470947265625 +44452 -0.06396484375 +44453 -0.1883544921875 +44454 -0.236541748046875 +44455 -0.372711181640625 +44456 -0.38189697265625 +44457 -0.51397705078125 +44458 -0.474700927734375 +44459 -0.57177734375 +44460 -0.508270263671875 +44461 -0.53948974609375 +44462 -0.489776611328125 +44463 -0.43511962890625 +44464 -0.437744140625 +44465 -0.2962646484375 +44466 -0.371826171875 +44467 -0.161102294921875 +44468 -0.299591064453125 +44469 -0.0435791015625 +44470 -0.219818115234375 +44471 0.060394287109375 +44472 -0.141815185546875 +44473 0.13665771484375 +44474 -0.0760498046875 +44475 0.170135498046875 +44476 -0.022918701171875 +44477 0.16552734375 +44478 0.032745361328125 +44479 0.15728759765625 +44480 0.0904541015625 +44481 0.150787353515625 +44482 0.133941650390625 +44483 0.12200927734375 +44484 0.164947509765625 +44485 0.080108642578125 +44486 0.19476318359375 +44487 0.05126953125 +44488 0.235870361328125 +44489 0.062896728515625 +44490 0.274688720703125 +44491 0.09271240234375 +44492 0.284759521484375 +44493 0.092987060546875 +44494 0.27386474609375 +44495 0.07855224609375 +44496 0.250518798828125 +44497 0.06427001953125 +44498 0.20770263671875 +44499 0.0347900390625 +44500 0.146209716796875 +44501 -0.01171875 +44502 0.07861328125 +44503 -0.056060791015625 +44504 0.030426025390625 +44505 -0.055511474609375 +44506 0.004180908203125 +44507 -0.010467529296875 +44508 -0.02618408203125 +44509 0.02508544921875 +44510 -0.0716552734375 +44511 0.025665283203125 +44512 -0.11590576171875 +44513 0.017333984375 +44514 -0.155975341796875 +44515 0.00189208984375 +44516 -0.1962890625 +44517 -0.03173828125 +44518 -0.2294921875 +44519 -0.071502685546875 +44520 -0.264862060546875 +44521 -0.13543701171875 +44522 -0.30078125 +44523 -0.219970703125 +44524 -0.3248291015625 +44525 -0.300506591796875 +44526 -0.33795166015625 +44527 -0.376312255859375 +44528 -0.325103759765625 +44529 -0.416107177734375 +44530 -0.26220703125 +44531 -0.371124267578125 +44532 -0.15203857421875 +44533 -0.242279052734375 +44534 -0.01837158203125 +44535 -0.069732666015625 +44536 0.12530517578125 +44537 0.125640869140625 +44538 0.260223388671875 +44539 0.31268310546875 +44540 0.3651123046875 +44541 0.45501708984375 +44542 0.439727783203125 +44543 0.554779052734375 +44544 0.482666015625 +44545 0.61065673828125 +44546 0.487060546875 +44547 0.610931396484375 +44548 0.43939208984375 +44549 0.531463623046875 +44550 0.348846435546875 +44551 0.3883056640625 +44552 0.24554443359375 +44553 0.23468017578125 +44554 0.144287109375 +44555 0.095245361328125 +44556 0.060821533203125 +44557 -0.00396728515625 +44558 0.0047607421875 +44559 -0.04852294921875 +44560 -0.03125 +44561 -0.055145263671875 +44562 -0.07403564453125 +44563 -0.0758056640625 +44564 -0.13739013671875 +44565 -0.138702392578125 +44566 -0.200775146484375 +44567 -0.209197998046875 +44568 -0.263916015625 +44569 -0.289031982421875 +44570 -0.3262939453125 +44571 -0.37884521484375 +44572 -0.375091552734375 +44573 -0.456329345703125 +44574 -0.407379150390625 +44575 -0.51641845703125 +44576 -0.4014892578125 +44577 -0.519287109375 +44578 -0.354339599609375 +44579 -0.458251953125 +44580 -0.295166015625 +44581 -0.384796142578125 +44582 -0.238739013671875 +44583 -0.323699951171875 +44584 -0.18328857421875 +44585 -0.269287109375 +44586 -0.11578369140625 +44587 -0.1951904296875 +44588 -0.036956787109375 +44589 -0.100006103515625 +44590 0.036956787109375 +44591 -0.01055908203125 +44592 0.121307373046875 +44593 0.1033935546875 +44594 0.218963623046875 +44595 0.24908447265625 +44596 0.299774169921875 +44597 0.373199462890625 +44598 0.353515625 +44599 0.45806884765625 +44600 0.384185791015625 +44601 0.511474609375 +44602 0.40948486328125 +44603 0.565399169921875 +44604 0.4251708984375 +44605 0.61138916015625 +44606 0.399078369140625 +44607 0.5897216796875 +44608 0.32672119140625 +44609 0.4906005859375 +44610 0.21875 +44611 0.33148193359375 +44612 0.095855712890625 +44613 0.147796630859375 +44614 -0.01776123046875 +44615 -0.01873779296875 +44616 -0.1055908203125 +44617 -0.140289306640625 +44618 -0.15283203125 +44619 -0.191986083984375 +44620 -0.164276123046875 +44621 -0.184295654296875 +44622 -0.1636962890625 +44623 -0.161834716796875 +44624 -0.173675537109375 +44625 -0.166595458984375 +44626 -0.19134521484375 +44627 -0.19390869140625 +44628 -0.2060546875 +44629 -0.22442626953125 +44630 -0.22991943359375 +44631 -0.279754638671875 +44632 -0.251983642578125 +44633 -0.3389892578125 +44634 -0.24664306640625 +44635 -0.3543701171875 +44636 -0.22698974609375 +44637 -0.348175048828125 +44638 -0.197052001953125 +44639 -0.32598876953125 +44640 -0.141571044921875 +44641 -0.2581787109375 +44642 -0.058807373046875 +44643 -0.139801025390625 +44644 0.04229736328125 +44645 0.014617919921875 +44646 0.127471923828125 +44647 0.144378662109375 +44648 0.180450439453125 +44649 0.221038818359375 +44650 0.21502685546875 +44651 0.27069091796875 +44652 0.231353759765625 +44653 0.294036865234375 +44654 0.24072265625 +44655 0.311767578125 +44656 0.251708984375 +44657 0.339141845703125 +44658 0.256103515625 +44659 0.360260009765625 +44660 0.246307373046875 +44661 0.360504150390625 +44662 0.2049560546875 +44663 0.308380126953125 +44664 0.120086669921875 +44665 0.18170166015625 +44666 0.006195068359375 +44667 0.0047607421875 +44668 -0.109375 +44669 -0.17559814453125 +44670 -0.20037841796875 +44671 -0.3143310546875 +44672 -0.241455078125 +44673 -0.36785888671875 +44674 -0.24700927734375 +44675 -0.36248779296875 +44676 -0.24237060546875 +44677 -0.343536376953125 +44678 -0.222137451171875 +44679 -0.3018798828125 +44680 -0.18267822265625 +44681 -0.231414794921875 +44682 -0.115814208984375 +44683 -0.117645263671875 +44684 -0.040130615234375 +44685 0.007049560546875 +44686 0.012969970703125 +44687 0.087982177734375 +44688 0.0511474609375 +44689 0.13946533203125 +44690 0.08111572265625 +44691 0.17425537109375 +44692 0.09991455078125 +44693 0.188201904296875 +44694 0.101226806640625 +44695 0.171234130859375 +44696 0.081634521484375 +44697 0.118438720703125 +44698 0.056121826171875 +44699 0.05706787109375 +44700 0.025421142578125 +44701 -0.010711669921875 +44702 -0.014556884765625 +44703 -0.0914306640625 +44704 -0.0511474609375 +44705 -0.162322998046875 +44706 -0.068115234375 +44707 -0.194549560546875 +44708 -0.04345703125 +44709 -0.1492919921875 +44710 0.0257568359375 +44711 -0.02166748046875 +44712 0.103271484375 +44713 0.124053955078125 +44714 0.145843505859375 +44715 0.211151123046875 +44716 0.15435791015625 +44717 0.240447998046875 +44718 0.146484375 +44719 0.242218017578125 +44720 0.12799072265625 +44721 0.2257080078125 +44722 0.101348876953125 +44723 0.194366455078125 +44724 0.0484619140625 +44725 0.115509033203125 +44726 -0.016754150390625 +44727 0.0128173828125 +44728 -0.059967041015625 +44729 -0.053802490234375 +44730 -0.0958251953125 +44731 -0.110626220703125 +44732 -0.147979736328125 +44733 -0.199493408203125 +44734 -0.20159912109375 +44735 -0.29437255859375 +44736 -0.220947265625 +44737 -0.33221435546875 +44738 -0.187286376953125 +44739 -0.27972412109375 +44740 -0.128387451171875 +44741 -0.185333251953125 +44742 -0.089508056640625 +44743 -0.128204345703125 +44744 -0.075225830078125 +44745 -0.115692138671875 +44746 -0.068145751953125 +44747 -0.116455078125 +44748 -0.054718017578125 +44749 -0.105926513671875 +44750 -0.01824951171875 +44751 -0.053955078125 +44752 0.046173095703125 +44753 0.048797607421875 +44754 0.112701416015625 +44755 0.157318115234375 +44756 0.147247314453125 +44757 0.212005615234375 +44758 0.15283203125 +44759 0.218475341796875 +44760 0.163787841796875 +44761 0.23724365234375 +44762 0.201202392578125 +44763 0.30535888671875 +44764 0.241546630859375 +44765 0.38128662109375 +44766 0.2506103515625 +44767 0.404449462890625 +44768 0.239776611328125 +44769 0.3944091796875 +44770 0.2305908203125 +44771 0.3885498046875 +44772 0.20965576171875 +44773 0.362640380859375 +44774 0.152862548828125 +44775 0.27362060546875 +44776 0.058074951171875 +44777 0.11712646484375 +44778 -0.044891357421875 +44779 -0.054901123046875 +44780 -0.126434326171875 +44781 -0.19085693359375 +44782 -0.183502197265625 +44783 -0.28570556640625 +44784 -0.21588134765625 +44785 -0.339263916015625 +44786 -0.23828125 +44787 -0.3775634765625 +44788 -0.27630615234375 +44789 -0.445709228515625 +44790 -0.325103759765625 +44791 -0.535064697265625 +44792 -0.37542724609375 +44793 -0.629058837890625 +44794 -0.410369873046875 +44795 -0.697601318359375 +44796 -0.409271240234375 +44797 -0.70391845703125 +44798 -0.369293212890625 +44799 -0.6424560546875 +44800 -0.27777099609375 +44801 -0.491241455078125 +44802 -0.143585205078125 +44803 -0.265716552734375 +44804 -0.0006103515625 +44805 -0.023712158203125 +44806 0.131622314453125 +44807 0.201751708984375 +44808 0.232513427734375 +44809 0.375823974609375 +44810 0.294281005859375 +44811 0.485076904296875 +44812 0.340789794921875 +44813 0.56884765625 +44814 0.376861572265625 +44815 0.634765625 +44816 0.37554931640625 +44817 0.63763427734375 +44818 0.33013916015625 +44819 0.5660400390625 +44820 0.27197265625 +44821 0.4720458984375 +44822 0.23187255859375 +44823 0.40692138671875 +44824 0.214141845703125 +44825 0.3778076171875 +44826 0.214080810546875 +44827 0.376953125 +44828 0.21221923828125 +44829 0.371978759765625 +44830 0.178619384765625 +44831 0.313140869140625 +44832 0.103546142578125 +44833 0.184417724609375 +44834 0.002105712890625 +44835 0.011199951171875 +44836 -0.10455322265625 +44837 -0.171051025390625 +44838 -0.20166015625 +44839 -0.33740234375 +44840 -0.279815673828125 +44841 -0.47198486328125 +44842 -0.33050537109375 +44843 -0.560394287109375 +44844 -0.34063720703125 +44845 -0.58056640625 +44846 -0.3193359375 +44847 -0.54754638671875 +44848 -0.295013427734375 +44849 -0.508575439453125 +44850 -0.265228271484375 +44851 -0.459503173828125 +44852 -0.226409912109375 +44853 -0.394378662109375 +44854 -0.202117919921875 +44855 -0.35260009765625 +44856 -0.1788330078125 +44857 -0.31170654296875 +44858 -0.111907958984375 +44859 -0.197418212890625 +44860 -0.000152587890625 +44861 -0.007965087890625 +44862 0.126983642578125 +44863 0.207489013671875 +44864 0.24578857421875 +44865 0.409210205078125 +44866 0.34130859375 +44867 0.57208251953125 +44868 0.395599365234375 +44869 0.66595458984375 +44870 0.389495849609375 +44871 0.65875244140625 +44872 0.333282470703125 +44873 0.56744384765625 +44874 0.25067138671875 +44875 0.431396484375 +44876 0.16796875 +44877 0.29443359375 +44878 0.10076904296875 +44879 0.182464599609375 +44880 0.029937744140625 +44881 0.06365966796875 +44882 -0.05291748046875 +44883 -0.075958251953125 +44884 -0.119720458984375 +44885 -0.189422607421875 +44886 -0.167633056640625 +44887 -0.271942138671875 +44888 -0.208160400390625 +44889 -0.342529296875 +44890 -0.21923828125 +44891 -0.364166259765625 +44892 -0.1951904296875 +44893 -0.327239990234375 +44894 -0.163238525390625 +44895 -0.2769775390625 +44896 -0.147705078125 +44897 -0.253692626953125 +44898 -0.140380859375 +44899 -0.24365234375 +44900 -0.112274169921875 +44901 -0.1983642578125 +44902 -0.06243896484375 +44903 -0.116241455078125 +44904 -0.0146484375 +44905 -0.036834716796875 +44906 0.028106689453125 +44907 0.034881591796875 +44908 0.061279296875 +44909 0.09124755859375 +44910 0.07086181640625 +44911 0.10888671875 +44912 0.079559326171875 +44913 0.125518798828125 +44914 0.097412109375 +44915 0.15771484375 +44916 0.108154296875 +44917 0.17828369140625 +44918 0.102203369140625 +44919 0.17108154296875 +44920 0.07598876953125 +44921 0.129974365234375 +44922 0.046051025390625 +44923 0.082427978515625 +44924 0.01202392578125 +44925 0.027679443359375 +44926 -0.04486083984375 +44927 -0.065643310546875 +44928 -0.101654052734375 +44929 -0.15936279296875 +44930 -0.134063720703125 +44931 -0.21307373046875 +44932 -0.1468505859375 +44933 -0.234649658203125 +44934 -0.12567138671875 +44935 -0.2001953125 +44936 -0.076263427734375 +44937 -0.119171142578125 +44938 -0.0185546875 +44939 -0.024749755859375 +44940 0.048980712890625 +44941 0.085784912109375 +44942 0.105712890625 +44943 0.178131103515625 +44944 0.129547119140625 +44945 0.215576171875 +44946 0.12835693359375 +44947 0.211456298828125 +44948 0.1077880859375 +44949 0.17523193359375 +44950 0.080902099609375 +44951 0.128753662109375 +44952 0.065582275390625 +44953 0.1019287109375 +44954 0.049560546875 +44955 0.0743408203125 +44956 0.03118896484375 +44957 0.04327392578125 +44958 0.028106689453125 +44959 0.038177490234375 +44960 0.0506591796875 +44961 0.076263427734375 +44962 0.088958740234375 +44963 0.14105224609375 +44964 0.115386962890625 +44965 0.186431884765625 +44966 0.1158447265625 +44967 0.188812255859375 +44968 0.084869384765625 +44969 0.1390380859375 +44970 0.025360107421875 +44971 0.041778564453125 +44972 -0.0484619140625 +44973 -0.079437255859375 +44974 -0.133453369140625 +44975 -0.219390869140625 +44976 -0.223358154296875 +44977 -0.367828369140625 +44978 -0.300262451171875 +44979 -0.494873046875 +44980 -0.337554931640625 +44981 -0.556243896484375 +44982 -0.309234619140625 +44983 -0.508697509765625 +44984 -0.229339599609375 +44985 -0.3756103515625 +44986 -0.135040283203125 +44987 -0.218902587890625 +44988 -0.041473388671875 +44989 -0.063751220703125 +44990 0.05230712890625 +44991 0.091552734375 +44992 0.13970947265625 +44993 0.23602294921875 +44994 0.204681396484375 +44995 0.342987060546875 +44996 0.236846923828125 +44997 0.39520263671875 +44998 0.234161376953125 +44999 0.389373779296875 +45000 0.19586181640625 +45001 0.324249267578125 +45002 0.136444091796875 +45003 0.224090576171875 +45004 0.077117919921875 +45005 0.124267578125 +45006 0.02520751953125 +45007 0.037078857421875 +45008 -0.002838134765625 +45009 -0.010101318359375 +45010 -0.00836181640625 +45011 -0.019439697265625 +45012 -0.01043701171875 +45013 -0.022796630859375 +45014 0.0020751953125 +45015 -0.001556396484375 +45016 0.036407470703125 +45017 0.056304931640625 +45018 0.066131591796875 +45019 0.106719970703125 +45020 0.059600830078125 +45021 0.096893310546875 +45022 0.026397705078125 +45023 0.042694091796875 +45024 -0.010772705078125 +45025 -0.018035888671875 +45026 -0.046173095703125 +45027 -0.07586669921875 +45028 -0.07293701171875 +45029 -0.11944580078125 +45030 -0.09765625 +45031 -0.15972900390625 +45032 -0.123809814453125 +45033 -0.202606201171875 +45034 -0.15167236328125 +45035 -0.24859619140625 +45036 -0.185699462890625 +45037 -0.30517578125 +45038 -0.21978759765625 +45039 -0.36212158203125 +45040 -0.237152099609375 +45041 -0.39141845703125 +45042 -0.215087890625 +45043 -0.35528564453125 +45044 -0.151397705078125 +45045 -0.249969482421875 +45046 -0.05657958984375 +45047 -0.092864990234375 +45048 0.053131103515625 +45049 0.08905029296875 +45050 0.141387939453125 +45051 0.2352294921875 +45052 0.192047119140625 +45053 0.318817138671875 +45054 0.21636962890625 +45055 0.358642578125 +45056 0.2095947265625 +45057 0.347747802734375 +45058 0.170745849609375 +45059 0.28564453125 +45060 0.13153076171875 +45061 0.223175048828125 +45062 0.11517333984375 +45063 0.196746826171875 +45064 0.1051025390625 +45065 0.179840087890625 +45066 0.090728759765625 +45067 0.155548095703125 +45068 0.08935546875 +45069 0.151214599609375 +45070 0.0947265625 +45071 0.156951904296875 +45072 0.080841064453125 +45073 0.13177490234375 +45074 0.0634765625 +45075 0.100799560546875 +45076 0.057098388671875 +45077 0.087127685546875 +45078 0.038909912109375 +45079 0.05487060546875 +45080 0.000518798828125 +45081 -0.009002685546875 +45082 -0.057861328125 +45083 -0.10400390625 +45084 -0.1358642578125 +45085 -0.229400634765625 +45086 -0.214813232421875 +45087 -0.35552978515625 +45088 -0.2691650390625 +45089 -0.441925048828125 +45090 -0.28961181640625 +45091 -0.473846435546875 +45092 -0.284698486328125 +45093 -0.464813232421875 +45094 -0.257049560546875 +45095 -0.419097900390625 +45096 -0.205078125 +45097 -0.334320068359375 +45098 -0.139739990234375 +45099 -0.227935791015625 +45100 -0.0758056640625 +45101 -0.12347412109375 +45102 -0.017364501953125 +45103 -0.02764892578125 +45104 0.047149658203125 +45105 0.077667236328125 +45106 0.130950927734375 +45107 0.2132568359375 +45108 0.24029541015625 +45109 0.38885498046875 +45110 0.361541748046875 +45111 0.582794189453125 +45112 0.456207275390625 +45113 0.734039306640625 +45114 0.49749755859375 +45115 0.800140380859375 +45116 0.483673095703125 +45117 0.7783203125 +45118 0.412567138671875 +45119 0.6651611328125 +45120 0.283538818359375 +45121 0.45965576171875 +45122 0.120147705078125 +45123 0.199188232421875 +45124 -0.0362548828125 +45125 -0.050689697265625 +45126 -0.149749755859375 +45127 -0.23297119140625 +45128 -0.209381103515625 +45129 -0.33013916015625 +45130 -0.231781005859375 +45131 -0.368408203125 +45132 -0.23675537109375 +45133 -0.378936767578125 +45134 -0.2340087890625 +45135 -0.376983642578125 +45136 -0.2344970703125 +45137 -0.37969970703125 +45138 -0.241058349609375 +45139 -0.391510009765625 +45140 -0.23663330078125 +45141 -0.385345458984375 +45142 -0.20904541015625 +45143 -0.3419189453125 +45144 -0.1719970703125 +45145 -0.28289794921875 +45146 -0.15283203125 +45147 -0.251617431640625 +45148 -0.16290283203125 +45149 -0.266143798828125 +45150 -0.1685791015625 +45151 -0.273345947265625 +45152 -0.1341552734375 +45153 -0.216796875 +45154 -0.079620361328125 +45155 -0.128265380859375 +45156 -0.0430908203125 +45157 -0.068145751953125 +45158 -0.02862548828125 +45159 -0.0430908203125 +45160 -0.018096923828125 +45161 -0.024444580078125 +45162 0.009368896484375 +45163 0.020721435546875 +45164 0.0740966796875 +45165 0.124481201171875 +45166 0.157806396484375 +45167 0.25787353515625 +45168 0.234130859375 +45169 0.379119873046875 +45170 0.2978515625 +45171 0.47991943359375 +45172 0.32867431640625 +45173 0.5281982421875 +45174 0.3184814453125 +45175 0.511138916015625 +45176 0.284576416015625 +45177 0.456207275390625 +45178 0.2547607421875 +45179 0.407470703125 +45180 0.240875244140625 +45181 0.383758544921875 +45182 0.22503662109375 +45183 0.35687255859375 +45184 0.197723388671875 +45185 0.31182861328125 +45186 0.160308837890625 +45187 0.250885009765625 +45188 0.10723876953125 +45189 0.1654052734375 +45190 0.0257568359375 +45191 0.035247802734375 +45192 -0.085723876953125 +45193 -0.142059326171875 +45194 -0.20770263671875 +45195 -0.33563232421875 +45196 -0.333282470703125 +45197 -0.5345458984375 +45198 -0.4517822265625 +45199 -0.72186279296875 +45200 -0.524658203125 +45201 -0.836669921875 +45202 -0.52264404296875 +45203 -0.8326416015625 +45204 -0.458221435546875 +45205 -0.7296142578125 +45206 -0.366119384765625 +45207 -0.582550048828125 +45208 -0.277008056640625 +45209 -0.440093994140625 +45210 -0.20477294921875 +45211 -0.324310302734375 +45212 -0.1280517578125 +45213 -0.20147705078125 +45214 -0.029754638671875 +45215 -0.044647216796875 +45216 0.0634765625 +45217 0.103973388671875 +45218 0.1251220703125 +45219 0.202392578125 +45220 0.163970947265625 +45221 0.264495849609375 +45222 0.210784912109375 +45223 0.338897705078125 +45224 0.277069091796875 +45225 0.443817138671875 +45226 0.34124755859375 +45227 0.545074462890625 +45228 0.387237548828125 +45229 0.6173095703125 +45230 0.409942626953125 +45231 0.6524658203125 +45232 0.417449951171875 +45233 0.66339111328125 +45234 0.413543701171875 +45235 0.6561279296875 +45236 0.383056640625 +45237 0.606781005859375 +45238 0.3170166015625 +45239 0.501190185546875 +45240 0.223846435546875 +45241 0.352783203125 +45242 0.113037109375 +45243 0.176544189453125 +45244 -0.020050048828125 +45245 -0.034820556640625 +45246 -0.16082763671875 +45247 -0.258209228515625 +45248 -0.2769775390625 +45249 -0.44244384765625 +45250 -0.360809326171875 +45251 -0.5753173828125 +45252 -0.4093017578125 +45253 -0.65203857421875 +45254 -0.402862548828125 +45255 -0.641632080078125 +45256 -0.3529052734375 +45257 -0.562164306640625 +45258 -0.287506103515625 +45259 -0.458038330078125 +45260 -0.220062255859375 +45261 -0.350555419921875 +45262 -0.163726806640625 +45263 -0.260528564453125 +45264 -0.121063232421875 +45265 -0.192108154296875 +45266 -0.089935302734375 +45267 -0.141937255859375 +45268 -0.065338134765625 +45269 -0.1021728515625 +45270 -0.040985107421875 +45271 -0.062896728515625 +45272 -0.009124755859375 +45273 -0.011932373046875 +45274 0.037872314453125 +45275 0.062835693359375 +45276 0.092010498046875 +45277 0.148712158203125 +45278 0.1507568359375 +45279 0.241729736328125 +45280 0.21868896484375 +45281 0.34912109375 +45282 0.2872314453125 +45283 0.457305908203125 +45284 0.342193603515625 +45285 0.54388427734375 +45286 0.36083984375 +45287 0.5728759765625 +45288 0.3193359375 +45289 0.506591796875 +45290 0.2215576171875 +45291 0.351226806640625 +45292 0.092620849609375 +45293 0.146514892578125 +45294 -0.034454345703125 +45295 -0.05523681640625 +45296 -0.13580322265625 +45297 -0.21624755859375 +45298 -0.210418701171875 +45299 -0.334930419921875 +45300 -0.253082275390625 +45301 -0.402984619140625 +45302 -0.277008056640625 +45303 -0.4412841796875 +45304 -0.311279296875 +45305 -0.49578857421875 +45306 -0.351898193359375 +45307 -0.5601806640625 +45308 -0.3775634765625 +45309 -0.600738525390625 +45310 -0.36724853515625 +45311 -0.584228515625 +45312 -0.30084228515625 +45313 -0.47930908203125 +45314 -0.173492431640625 +45315 -0.27935791015625 +45316 -0.000518798828125 +45317 -0.0089111328125 +45318 0.17681884765625 +45319 0.268798828125 +45320 0.31207275390625 +45321 0.482818603515625 +45322 0.386199951171875 +45323 0.60369873046875 +45324 0.412200927734375 +45325 0.650421142578125 +45326 0.417633056640625 +45327 0.66400146484375 +45328 0.400665283203125 +45329 0.6414794921875 +45330 0.35455322265625 +45331 0.572540283203125 +45332 0.306427001953125 +45333 0.498138427734375 +45334 0.270172119140625 +45335 0.439453125 +45336 0.231689453125 +45337 0.375518798828125 +45338 0.169525146484375 +45339 0.274505615234375 +45340 0.065032958984375 +45341 0.1087646484375 +45342 -0.067352294921875 +45343 -0.099395751953125 +45344 -0.206878662109375 +45345 -0.3182373046875 +45346 -0.35467529296875 +45347 -0.5489501953125 +45348 -0.499237060546875 +45349 -0.7738037109375 +45350 -0.60565185546875 +45351 -0.86383056640625 +45352 -0.65203857421875 +45353 -0.870391845703125 +45354 -0.6502685546875 +45355 -0.86895751953125 +45356 -0.609130859375 +45357 -0.861053466796875 +45358 -0.51708984375 +45359 -0.765869140625 +45360 -0.3665771484375 +45361 -0.5301513671875 +45362 -0.16217041015625 +45363 -0.214691162109375 +45364 0.0677490234375 +45365 0.137359619140625 +45366 0.28936767578125 +45367 0.474822998046875 +45368 0.479339599609375 +45369 0.76239013671875 +45370 0.6199951171875 +45371 0.867462158203125 +45372 0.7119140625 +45373 0.870361328125 +45374 0.747650146484375 +45375 0.86480712890625 +45376 0.73095703125 +45377 0.831817626953125 +45378 0.67816162109375 +45379 0.677581787109375 +45380 0.593231201171875 +45381 0.495880126953125 +45382 0.48858642578125 +45383 0.30767822265625 +45384 0.365692138671875 +45385 0.116180419921875 +45386 0.20343017578125 +45387 -0.110748291015625 +45388 -0.002899169921875 +45389 -0.381805419921875 +45390 -0.225006103515625 +45391 -0.6572265625 +45392 -0.42333984375 +45393 -0.857421875 +45394 -0.569580078125 +45395 -0.870391845703125 +45396 -0.6591796875 +45397 -0.870391845703125 +45398 -0.710205078125 +45399 -0.86444091796875 +45400 -0.74658203125 +45401 -0.85723876953125 +45402 -0.75628662109375 +45403 -0.790008544921875 +45404 -0.703460693359375 +45405 -0.62847900390625 +45406 -0.586090087890625 +45407 -0.3956298828125 +45408 -0.426055908203125 +45409 -0.126708984375 +45410 -0.2415771484375 +45411 0.150115966796875 +45412 -0.0404052734375 +45413 0.424041748046875 +45414 0.159576416015625 +45415 0.670623779296875 +45416 0.332763671875 +45417 0.854522705078125 +45418 0.467559814453125 +45419 0.866485595703125 +45420 0.55389404296875 +45421 0.86920166015625 +45422 0.603973388671875 +45423 0.8653564453125 +45424 0.626861572265625 +45425 0.857147216796875 +45426 0.620758056640625 +45427 0.766845703125 +45428 0.5892333984375 +45429 0.628509521484375 +45430 0.5279541015625 +45431 0.462127685546875 +45432 0.454193115234375 +45433 0.297210693359375 +45434 0.376251220703125 +45435 0.14862060546875 +45436 0.278961181640625 +45437 -0.00537109375 +45438 0.167327880859375 +45439 -0.15753173828125 +45440 0.038909912109375 +45441 -0.31304931640625 +45442 -0.115631103515625 +45443 -0.48876953125 +45444 -0.2652587890625 +45445 -0.6416015625 +45446 -0.3936767578125 +45447 -0.751373291015625 +45448 -0.51629638671875 +45449 -0.84619140625 +45450 -0.62347412109375 +45451 -0.861297607421875 +45452 -0.693328857421875 +45453 -0.863250732421875 +45454 -0.70501708984375 +45455 -0.856597900390625 +45456 -0.66668701171875 +45457 -0.7498779296875 +45458 -0.61688232421875 +45459 -0.624542236328125 +45460 -0.541046142578125 +45461 -0.47808837890625 +45462 -0.400421142578125 +45463 -0.253387451171875 +45464 -0.225372314453125 +45465 0.003692626953125 +45466 -0.061279296875 +45467 0.2257080078125 +45468 0.10015869140625 +45469 0.427154541015625 +45470 0.280517578125 +45471 0.643218994140625 +45472 0.47344970703125 +45473 0.855926513671875 +45474 0.6405029296875 +45475 0.870361328125 +45476 0.74884033203125 +45477 0.870361328125 +45478 0.803314208984375 +45479 0.862762451171875 +45480 0.80206298828125 +45481 0.79669189453125 +45482 0.7388916015625 +45483 0.595794677734375 +45484 0.63323974609375 +45485 0.362152099609375 +45486 0.503814697265625 +45487 0.1270751953125 +45488 0.36474609375 +45489 -0.086944580078125 +45490 0.21746826171875 +45491 -0.2784423828125 +45492 0.038909912109375 +45493 -0.484832763671875 +45494 -0.18359375 +45495 -0.729583740234375 +45496 -0.416412353515625 +45497 -0.86688232421875 +45498 -0.617462158203125 +45499 -0.870391845703125 +45500 -0.78350830078125 +45501 -0.86859130859375 +45502 -0.86090087890625 +45503 -0.86279296875 +45504 -0.86846923828125 +45505 -0.817962646484375 +45506 -0.866180419921875 +45507 -0.6116943359375 +45508 -0.845306396484375 +45509 -0.3128662109375 +45510 -0.65655517578125 +45511 0.039398193359375 +45512 -0.408538818359375 +45513 0.422821044921875 +45514 -0.123504638671875 +45515 0.805145263671875 +45516 0.153228759765625 +45517 0.870361328125 +45518 0.3836669921875 +45519 0.870361328125 +45520 0.55987548828125 +45521 0.860015869140625 +45522 0.676605224609375 +45523 0.727935791015625 +45524 0.72991943359375 +45525 0.48114013671875 +45526 0.73577880859375 +45527 0.2059326171875 +45528 0.70904541015625 +45529 -0.06103515625 +45530 0.656280517578125 +45531 -0.29913330078125 +45532 0.56781005859375 +45533 -0.516204833984375 +45534 0.4334716796875 +45535 -0.7252197265625 +45536 0.269866943359375 +45537 -0.85980224609375 +45538 0.100006103515625 +45539 -0.870391845703125 +45540 -0.056182861328125 +45541 -0.870391845703125 +45542 -0.166046142578125 +45543 -0.858062744140625 +45544 -0.226409912109375 +45545 -0.673004150390625 +45546 -0.271759033203125 +45547 -0.42694091796875 +45548 -0.331146240234375 +45549 -0.2100830078125 +45550 -0.402801513671875 +45551 -0.0362548828125 +45552 -0.46710205078125 +45553 0.10943603515625 +45554 -0.51055908203125 +45555 0.23516845703125 +45556 -0.505523681640625 +45557 0.373687744140625 +45558 -0.45318603515625 +45559 0.517791748046875 +45560 -0.3953857421875 +45561 0.602783203125 +45562 -0.32879638671875 +45563 0.635711669921875 +45564 -0.231475830078125 +45565 0.655181884765625 +45566 -0.11029052734375 +45567 0.65948486328125 +45568 0.02935791015625 +45569 0.651275634765625 +45570 0.170745849609375 +45571 0.61846923828125 +45572 0.288299560546875 +45573 0.53753662109375 +45574 0.369232177734375 +45575 0.404144287109375 +45576 0.406524658203125 +45577 0.22186279296875 +45578 0.4007568359375 +45579 0.003997802734375 +45580 0.36419677734375 +45581 -0.22100830078125 +45582 0.31097412109375 +45583 -0.42449951171875 +45584 0.25567626953125 +45585 -0.579833984375 +45586 0.227874755859375 +45587 -0.641876220703125 +45588 0.2227783203125 +45589 -0.6177978515625 +45590 0.19537353515625 +45591 -0.575531005859375 +45592 0.14190673828125 +45593 -0.526336669921875 +45594 0.0985107421875 +45595 -0.42645263671875 +45596 0.084381103515625 +45597 -0.2581787109375 +45598 0.074371337890625 +45599 -0.068695068359375 +45600 0.0418701171875 +45601 0.09222412109375 +45602 0.0001220703125 +45603 0.232147216796875 +45604 -0.043487548828125 +45605 0.3509521484375 +45606 -0.10931396484375 +45607 0.410064697265625 +45608 -0.217498779296875 +45609 0.372955322265625 +45610 -0.35321044921875 +45611 0.2554931640625 +45612 -0.47991943359375 +45613 0.10711669921875 +45614 -0.58380126953125 +45615 -0.052886962890625 +45616 -0.6395263671875 +45617 -0.186279296875 +45618 -0.608154296875 +45619 -0.23291015625 +45620 -0.5054931640625 +45621 -0.209442138671875 +45622 -0.377471923828125 +45623 -0.174163818359375 +45624 -0.230010986328125 +45625 -0.126739501953125 +45626 -0.056396484375 +45627 -0.048126220703125 +45628 0.123504638671875 +45629 0.0426025390625 +45630 0.276947021484375 +45631 0.10748291015625 +45632 0.3944091796875 +45633 0.1409912109375 +45634 0.508697509765625 +45635 0.19708251953125 +45636 0.614837646484375 +45637 0.273651123046875 +45638 0.673675537109375 +45639 0.31768798828125 +45640 0.69268798828125 +45641 0.341094970703125 +45642 0.68927001953125 +45643 0.368011474609375 +45644 0.647247314453125 +45645 0.37249755859375 +45646 0.53228759765625 +45647 0.30072021484375 +45648 0.34783935546875 +45649 0.1517333984375 +45650 0.14031982421875 +45651 -0.01470947265625 +45652 -0.0777587890625 +45653 -0.1883544921875 +45654 -0.30340576171875 +45655 -0.372711181640625 +45656 -0.493865966796875 +45657 -0.51397705078125 +45658 -0.616119384765625 +45659 -0.57177734375 +45660 -0.661407470703125 +45661 -0.53948974609375 +45662 -0.639007568359375 +45663 -0.43511962890625 +45664 -0.57281494140625 +45665 -0.2962646484375 +45666 -0.488311767578125 +45667 -0.161102294921875 +45668 -0.395294189453125 +45669 -0.0435791015625 +45670 -0.292144775390625 +45671 0.060394287109375 +45672 -0.190948486328125 +45673 0.13665771484375 +45674 -0.10528564453125 +45675 0.170135498046875 +45676 -0.03570556640625 +45677 0.16552734375 +45678 0.037506103515625 +45679 0.15728759765625 +45680 0.11358642578125 +45681 0.150787353515625 +45682 0.17138671875 +45683 0.12200927734375 +45684 0.213104248046875 +45685 0.080108642578125 +45686 0.253265380859375 +45687 0.05126953125 +45688 0.308013916015625 +45689 0.062896728515625 +45690 0.35968017578125 +45691 0.09271240234375 +45692 0.373809814453125 +45693 0.092987060546875 +45694 0.360443115234375 +45695 0.07855224609375 +45696 0.33062744140625 +45697 0.06427001953125 +45698 0.27520751953125 +45699 0.0347900390625 +45700 0.195220947265625 +45701 -0.01171875 +45702 0.10699462890625 +45703 -0.056060791015625 +45704 0.043670654296875 +45705 -0.055511474609375 +45706 0.008636474609375 +45707 -0.010467529296875 +45708 -0.031951904296875 +45709 0.02508544921875 +45710 -0.092254638671875 +45711 0.025665283203125 +45712 -0.150970458984375 +45713 0.017333984375 +45714 -0.2042236328125 +45715 0.00189208984375 +45716 -0.2576904296875 +45717 -0.03173828125 +45718 -0.301727294921875 +45719 -0.071502685546875 +45720 -0.348388671875 +45721 -0.13543701171875 +45722 -0.39544677734375 +45723 -0.219970703125 +45724 -0.426849365234375 +45725 -0.300506591796875 +45726 -0.44378662109375 +45727 -0.376312255859375 +45728 -0.4267578125 +45729 -0.416107177734375 +45730 -0.34454345703125 +45731 -0.371124267578125 +45732 -0.200714111328125 +45733 -0.242279052734375 +45734 -0.0262451171875 +45735 -0.069732666015625 +45736 0.16131591796875 +45737 0.125640869140625 +45738 0.337554931640625 +45739 0.31268310546875 +45740 0.474822998046875 +45741 0.45501708984375 +45742 0.57275390625 +45743 0.554779052734375 +45744 0.629180908203125 +45745 0.61065673828125 +45746 0.635284423828125 +45747 0.610931396484375 +45748 0.57427978515625 +45749 0.531463623046875 +45750 0.457977294921875 +45751 0.3883056640625 +45752 0.324615478515625 +45753 0.23468017578125 +45754 0.193115234375 +45755 0.095245361328125 +45756 0.08367919921875 +45757 -0.00396728515625 +45758 0.00872802734375 +45759 -0.04852294921875 +45760 -0.040863037109375 +45761 -0.055145263671875 +45762 -0.098785400390625 +45763 -0.0758056640625 +45764 -0.182342529296875 +45765 -0.138702392578125 +45766 -0.265350341796875 +45767 -0.209197998046875 +45768 -0.34735107421875 +45769 -0.289031982421875 +45770 -0.427581787109375 +45771 -0.37884521484375 +45772 -0.489776611328125 +45773 -0.456329345703125 +45774 -0.53021240234375 +45775 -0.51641845703125 +45776 -0.52154541015625 +45777 -0.519287109375 +45778 -0.4599609375 +45779 -0.458251953125 +45780 -0.382568359375 +45781 -0.384796142578125 +45782 -0.308258056640625 +45783 -0.323699951171875 +45784 -0.2349853515625 +45785 -0.269287109375 +45786 -0.146453857421875 +45787 -0.1951904296875 +45788 -0.043701171875 +45789 -0.100006103515625 +45790 0.052581787109375 +45791 -0.01055908203125 +45792 0.161651611328125 +45793 0.1033935546875 +45794 0.28704833984375 +45795 0.24908447265625 +45796 0.39056396484375 +45797 0.373199462890625 +45798 0.459136962890625 +45799 0.45806884765625 +45800 0.49786376953125 +45801 0.511474609375 +45802 0.5291748046875 +45803 0.565399169921875 +45804 0.547760009765625 +45805 0.61138916015625 +45806 0.512969970703125 +45807 0.5897216796875 +45808 0.41925048828125 +45809 0.4906005859375 +45810 0.280242919921875 +45811 0.33148193359375 +45812 0.12225341796875 +45813 0.147796630859375 +45814 -0.02398681640625 +45815 -0.01873779296875 +45816 -0.137451171875 +45817 -0.140289306640625 +45818 -0.19927978515625 +45819 -0.191986083984375 +45820 -0.2154541015625 +45821 -0.184295654296875 +45822 -0.215972900390625 +45823 -0.161834716796875 +45824 -0.229339599609375 +45825 -0.166595458984375 +45826 -0.251953125 +45827 -0.19390869140625 +45828 -0.270294189453125 +45829 -0.22442626953125 +45830 -0.29986572265625 +45831 -0.279754638671875 +45832 -0.32672119140625 +45833 -0.3389892578125 +45834 -0.318389892578125 +45835 -0.3543701171875 +45836 -0.2916259765625 +45837 -0.348175048828125 +45838 -0.251678466796875 +45839 -0.32598876953125 +45840 -0.179229736328125 +45841 -0.2581787109375 +45842 -0.072174072265625 +45843 -0.139801025390625 +45844 0.058013916015625 +45845 0.014617919921875 +45846 0.167694091796875 +45847 0.144378662109375 +45848 0.236053466796875 +45849 0.221038818359375 +45850 0.2806396484375 +45851 0.27069091796875 +45852 0.301544189453125 +45853 0.294036865234375 +45854 0.31317138671875 +45855 0.311767578125 +45856 0.326507568359375 +45857 0.339141845703125 +45858 0.331207275390625 +45859 0.360260009765625 +45860 0.317626953125 +45861 0.360504150390625 +45862 0.263580322265625 +45863 0.308380126953125 +45864 0.15374755859375 +45865 0.18170166015625 +45866 0.00677490234375 +45867 0.0047607421875 +45868 -0.14227294921875 +45869 -0.17559814453125 +45870 -0.259735107421875 +45871 -0.3143310546875 +45872 -0.313018798828125 +45873 -0.36785888671875 +45874 -0.320556640625 +45875 -0.36248779296875 +45876 -0.3148193359375 +45877 -0.343536376953125 +45878 -0.288848876953125 +45879 -0.3018798828125 +45880 -0.238067626953125 +45881 -0.231414794921875 +45882 -0.1519775390625 +45883 -0.117645263671875 +45884 -0.054412841796875 +45885 0.007049560546875 +45886 0.01434326171875 +45887 0.087982177734375 +45888 0.0640869140625 +45889 0.13946533203125 +45890 0.103363037109375 +45891 0.17425537109375 +45892 0.128326416015625 +45893 0.188201904296875 +45894 0.13079833984375 +45895 0.171234130859375 +45896 0.1064453125 +45897 0.118438720703125 +45898 0.0743408203125 +45899 0.05706787109375 +45900 0.035400390625 +45901 -0.010711669921875 +45902 -0.015625 +45903 -0.0914306640625 +45904 -0.0625 +45905 -0.162322998046875 +45906 -0.084381103515625 +45907 -0.194549560546875 +45908 -0.05303955078125 +45909 -0.1492919921875 +45910 0.035247802734375 +45911 -0.02166748046875 +45912 0.134063720703125 +45913 0.124053955078125 +45914 0.188018798828125 +45915 0.211151123046875 +45916 0.19830322265625 +45917 0.240447998046875 +45918 0.18756103515625 +45919 0.242218017578125 +45920 0.16326904296875 +45921 0.2257080078125 +45922 0.128570556640625 +45923 0.194366455078125 +45924 0.060333251953125 +45925 0.115509033203125 +45926 -0.02362060546875 +45927 0.0128173828125 +45928 -0.079254150390625 +45929 -0.053802490234375 +45930 -0.125335693359375 +45931 -0.110626220703125 +45932 -0.192169189453125 +45933 -0.199493408203125 +45934 -0.2607421875 +45935 -0.29437255859375 +45936 -0.285247802734375 +45937 -0.33221435546875 +45938 -0.24169921875 +45939 -0.27972412109375 +45940 -0.165740966796875 +45941 -0.185333251953125 +45942 -0.11541748046875 +45943 -0.128204345703125 +45944 -0.096588134765625 +45945 -0.115692138671875 +45946 -0.087005615234375 +45947 -0.116455078125 +45948 -0.069366455078125 +45949 -0.105926513671875 +45950 -0.02227783203125 +45951 -0.053955078125 +45952 0.060577392578125 +45953 0.048797607421875 +45954 0.146026611328125 +45955 0.157318115234375 +45956 0.190399169921875 +45957 0.212005615234375 +45958 0.19757080078125 +45959 0.218475341796875 +45960 0.211517333984375 +45961 0.23724365234375 +45962 0.25927734375 +45963 0.30535888671875 +45964 0.310760498046875 +45965 0.38128662109375 +45966 0.322113037109375 +45967 0.404449462890625 +45968 0.30792236328125 +45969 0.3944091796875 +45970 0.29583740234375 +45971 0.3885498046875 +45972 0.2686767578125 +45973 0.362640380859375 +45974 0.195556640625 +45975 0.27362060546875 +45976 0.07373046875 +45977 0.11712646484375 +45978 -0.05853271484375 +45979 -0.054901123046875 +45980 -0.16326904296875 +45981 -0.19085693359375 +45982 -0.236572265625 +45983 -0.28570556640625 +45984 -0.27813720703125 +45985 -0.339263916015625 +45986 -0.306793212890625 +45987 -0.3775634765625 +45988 -0.35540771484375 +45989 -0.445709228515625 +45990 -0.417816162109375 +45991 -0.535064697265625 +45992 -0.48211669921875 +45993 -0.629058837890625 +45994 -0.52667236328125 +45995 -0.697601318359375 +45996 -0.525054931640625 +45997 -0.70391845703125 +45998 -0.47357177734375 +45999 -0.6424560546875 +46000 -0.356597900390625 +46001 -0.491241455078125 +46002 -0.185791015625 +46003 -0.265716552734375 +46004 -0.003570556640625 +46005 -0.023712158203125 +46006 0.1656494140625 +46007 0.201751708984375 +46008 0.296295166015625 +46009 0.375823974609375 +46010 0.37841796875 +46011 0.485076904296875 +46012 0.440521240234375 +46013 0.56884765625 +46014 0.4881591796875 +46015 0.634765625 +46016 0.488494873046875 +46017 0.63763427734375 +46018 0.433349609375 +46019 0.5660400390625 +46020 0.36083984375 +46021 0.4720458984375 +46022 0.308502197265625 +46023 0.40692138671875 +46024 0.2818603515625 +46025 0.3778076171875 +46026 0.27557373046875 +46027 0.376953125 +46028 0.266387939453125 +46029 0.371978759765625 +46030 0.218414306640625 +46031 0.313140869140625 +46032 0.1202392578125 +46033 0.184417724609375 +46034 -0.0093994140625 +46035 0.011199951171875 +46036 -0.144561767578125 +46037 -0.171051025390625 +46038 -0.2669677734375 +46039 -0.33740234375 +46040 -0.365020751953125 +46041 -0.47198486328125 +46042 -0.42828369140625 +46043 -0.560394287109375 +46044 -0.440826416015625 +46045 -0.58056640625 +46046 -0.4136962890625 +46047 -0.54754638671875 +46048 -0.381500244140625 +46049 -0.508575439453125 +46050 -0.341461181640625 +46051 -0.459503173828125 +46052 -0.28948974609375 +46053 -0.394378662109375 +46054 -0.254486083984375 +46055 -0.35260009765625 +46056 -0.2203369140625 +46057 -0.31170654296875 +46058 -0.13323974609375 +46059 -0.197418212890625 +46060 0.00787353515625 +46061 -0.007965087890625 +46062 0.167083740234375 +46063 0.207489013671875 +46064 0.315338134765625 +46065 0.409210205078125 +46066 0.434295654296875 +46067 0.57208251953125 +46068 0.502044677734375 +46069 0.66595458984375 +46070 0.495269775390625 +46071 0.65875244140625 +46072 0.42645263671875 +46073 0.56744384765625 +46074 0.324371337890625 +46075 0.431396484375 +46076 0.221160888671875 +46077 0.29443359375 +46078 0.135894775390625 +46079 0.182464599609375 +46080 0.04510498046875 +46081 0.06365966796875 +46082 -0.06121826171875 +46083 -0.075958251953125 +46084 -0.1473388671875 +46085 -0.189422607421875 +46086 -0.209686279296875 +46087 -0.271942138671875 +46088 -0.262786865234375 +46089 -0.342529296875 +46090 -0.278594970703125 +46091 -0.364166259765625 +46092 -0.2498779296875 +46093 -0.327239990234375 +46094 -0.211029052734375 +46095 -0.2769775390625 +46096 -0.1927490234375 +46097 -0.253692626953125 +46098 -0.184600830078125 +46099 -0.24365234375 +46100 -0.149749755859375 +46101 -0.1983642578125 +46102 -0.087005615234375 +46103 -0.116241455078125 +46104 -0.026397705078125 +46105 -0.036834716796875 +46106 0.028228759765625 +46107 0.034881591796875 +46108 0.071075439453125 +46109 0.09124755859375 +46110 0.08441162109375 +46111 0.10888671875 +46112 0.096893310546875 +46113 0.125518798828125 +46114 0.121124267578125 +46115 0.15771484375 +46116 0.136444091796875 +46117 0.17828369140625 +46118 0.130584716796875 +46119 0.17108154296875 +46120 0.098968505859375 +46121 0.129974365234375 +46122 0.06243896484375 +46123 0.082427978515625 +46124 0.020477294921875 +46125 0.027679443359375 +46126 -0.05072021484375 +46127 -0.065643310546875 +46128 -0.122161865234375 +46129 -0.15936279296875 +46130 -0.163116455078125 +46131 -0.21307373046875 +46132 -0.179595947265625 +46133 -0.234649658203125 +46134 -0.153411865234375 +46135 -0.2001953125 +46136 -0.091766357421875 +46137 -0.119171142578125 +46138 -0.019866943359375 +46139 -0.024749755859375 +46140 0.0643310546875 +46141 0.085784912109375 +46142 0.134735107421875 +46143 0.178131103515625 +46144 0.1634521484375 +46145 0.215576171875 +46146 0.16058349609375 +46147 0.211456298828125 +46148 0.133331298828125 +46149 0.17523193359375 +46150 0.0982666015625 +46151 0.128753662109375 +46152 0.078094482421875 +46153 0.1019287109375 +46154 0.057342529296875 +46155 0.0743408203125 +46156 0.033905029296875 +46157 0.04327392578125 +46158 0.0301513671875 +46159 0.038177490234375 +46160 0.05914306640625 +46161 0.076263427734375 +46162 0.10833740234375 +46163 0.14105224609375 +46164 0.1427001953125 +46165 0.186431884765625 +46166 0.144317626953125 +46167 0.188812255859375 +46168 0.10626220703125 +46169 0.1390380859375 +46170 0.0321044921875 +46171 0.041778564453125 +46172 -0.06024169921875 +46173 -0.079437255859375 +46174 -0.16680908203125 +46175 -0.219390869140625 +46176 -0.27978515625 +46177 -0.367828369140625 +46178 -0.376495361328125 +46179 -0.494873046875 +46180 -0.42327880859375 +46181 -0.556243896484375 +46182 -0.38726806640625 +46183 -0.508697509765625 +46184 -0.28619384765625 +46185 -0.3756103515625 +46186 -0.1671142578125 +46187 -0.218902587890625 +46188 -0.049163818359375 +46189 -0.063751220703125 +46190 0.06890869140625 +46191 0.091552734375 +46192 0.178802490234375 +46193 0.23602294921875 +46194 0.260223388671875 +46195 0.342987060546875 +46196 0.300048828125 +46197 0.39520263671875 +46198 0.2957763671875 +46199 0.389373779296875 +46200 0.246429443359375 +46201 0.324249267578125 +46202 0.170440673828125 +46203 0.224090576171875 +46204 0.094696044921875 +46205 0.124267578125 +46206 0.02850341796875 +46207 0.037078857421875 +46208 -0.007293701171875 +46209 -0.010101318359375 +46210 -0.01434326171875 +46211 -0.019439697265625 +46212 -0.016845703125 +46213 -0.022796630859375 +46214 -0.00067138671875 +46215 -0.001556396484375 +46216 0.04327392578125 +46217 0.056304931640625 +46218 0.081512451171875 +46219 0.106719970703125 +46220 0.073944091796875 +46221 0.096893310546875 +46222 0.03265380859375 +46223 0.042694091796875 +46224 -0.01361083984375 +46225 -0.018035888671875 +46226 -0.057647705078125 +46227 -0.07586669921875 +46228 -0.090850830078125 +46229 -0.11944580078125 +46230 -0.121551513671875 +46231 -0.15972900390625 +46232 -0.154205322265625 +46233 -0.202606201171875 +46234 -0.189178466796875 +46235 -0.24859619140625 +46236 -0.232147216796875 +46237 -0.30517578125 +46238 -0.275360107421875 +46239 -0.36212158203125 +46240 -0.297576904296875 +46241 -0.39141845703125 +46242 -0.270050048828125 +46243 -0.35528564453125 +46244 -0.18994140625 +46245 -0.249969482421875 +46246 -0.07049560546875 +46247 -0.092864990234375 +46248 0.067779541015625 +46249 0.08905029296875 +46250 0.17889404296875 +46251 0.2352294921875 +46252 0.242462158203125 +46253 0.318817138671875 +46254 0.272735595703125 +46255 0.358642578125 +46256 0.26446533203125 +46257 0.347747802734375 +46258 0.21728515625 +46259 0.28564453125 +46260 0.169830322265625 +46261 0.223175048828125 +46262 0.14971923828125 +46263 0.196746826171875 +46264 0.1368408203125 +46265 0.179840087890625 +46266 0.118377685546875 +46267 0.155548095703125 +46268 0.115081787109375 +46269 0.151214599609375 +46270 0.11944580078125 +46271 0.156951904296875 +46272 0.10028076171875 +46273 0.13177490234375 +46274 0.07672119140625 +46275 0.100799560546875 +46276 0.0662841796875 +46277 0.087127685546875 +46278 0.041717529296875 +46279 0.05487060546875 +46280 -0.006866455078125 +46281 -0.009002685546875 +46282 -0.079071044921875 +46283 -0.10400390625 +46284 -0.17437744140625 +46285 -0.229400634765625 +46286 -0.270233154296875 +46287 -0.35552978515625 +46288 -0.33587646484375 +46289 -0.441925048828125 +46290 -0.360137939453125 +46291 -0.473846435546875 +46292 -0.353240966796875 +46293 -0.464813232421875 +46294 -0.318450927734375 +46295 -0.419097900390625 +46296 -0.25396728515625 +46297 -0.334320068359375 +46298 -0.173065185546875 +46299 -0.227935791015625 +46300 -0.093658447265625 +46301 -0.12347412109375 +46302 -0.02081298828125 +46303 -0.02764892578125 +46304 0.05926513671875 +46305 0.077667236328125 +46306 0.162322998046875 +46307 0.2132568359375 +46308 0.295745849609375 +46309 0.38885498046875 +46310 0.443084716796875 +46311 0.582794189453125 +46312 0.5579833984375 +46313 0.734039306640625 +46314 0.608184814453125 +46315 0.800140380859375 +46316 0.591552734375 +46317 0.7783203125 +46318 0.505523681640625 +46319 0.6651611328125 +46320 0.349334716796875 +46321 0.45965576171875 +46322 0.1513671875 +46323 0.199188232421875 +46324 -0.038543701171875 +46325 -0.050689697265625 +46326 -0.17706298828125 +46327 -0.23297119140625 +46328 -0.250885009765625 +46329 -0.33013916015625 +46330 -0.279937744140625 +46331 -0.368408203125 +46332 -0.28790283203125 +46333 -0.378936767578125 +46334 -0.286376953125 +46335 -0.376983642578125 +46336 -0.28851318359375 +46337 -0.37969970703125 +46338 -0.297607421875 +46339 -0.391510009765625 +46340 -0.292510986328125 +46341 -0.385345458984375 +46342 -0.2581787109375 +46343 -0.3419189453125 +46344 -0.2119140625 +46345 -0.28289794921875 +46346 -0.188140869140625 +46347 -0.251617431640625 +46348 -0.201202392578125 +46349 -0.266143798828125 +46350 -0.208984375 +46351 -0.273345947265625 +46352 -0.166717529296875 +46353 -0.216796875 +46354 -0.099365234375 +46355 -0.128265380859375 +46356 -0.054656982421875 +46357 -0.068145751953125 +46358 -0.037689208984375 +46359 -0.0430908203125 +46360 -0.02557373046875 +46361 -0.024444580078125 +46362 0.007904052734375 +46363 0.020721435546875 +46364 0.088287353515625 +46365 0.124481201171875 +46366 0.19268798828125 +46367 0.25787353515625 +46368 0.2880859375 +46369 0.379119873046875 +46370 0.36798095703125 +46371 0.47991943359375 +46372 0.40692138671875 +46373 0.5281982421875 +46374 0.39471435546875 +46375 0.511138916015625 +46376 0.352996826171875 +46377 0.456207275390625 +46378 0.31658935546875 +46379 0.407470703125 +46380 0.30029296875 +46381 0.383758544921875 +46382 0.2816162109375 +46383 0.35687255859375 +46384 0.24853515625 +46385 0.31182861328125 +46386 0.202667236328125 +46387 0.250885009765625 +46388 0.1370849609375 +46389 0.1654052734375 +46390 0.035736083984375 +46391 0.035247802734375 +46392 -0.103424072265625 +46393 -0.142059326171875 +46394 -0.256011962890625 +46395 -0.33563232421875 +46396 -0.413360595703125 +46397 -0.5345458984375 +46398 -0.562042236328125 +46399 -0.72186279296875 +46400 -0.65380859375 +46401 -0.836669921875 +46402 -0.65191650390625 +46403 -0.8326416015625 +46404 -0.571990966796875 +46405 -0.7296142578125 +46406 -0.45745849609375 +46407 -0.582550048828125 +46408 -0.346710205078125 +46409 -0.440093994140625 +46410 -0.257110595703125 +46411 -0.324310302734375 +46412 -0.161865234375 +46413 -0.20147705078125 +46414 -0.03948974609375 +46415 -0.044647216796875 +46416 0.076690673828125 +46417 0.103973388671875 +46418 0.153472900390625 +46419 0.202392578125 +46420 0.201873779296875 +46421 0.264495849609375 +46422 0.260467529296875 +46423 0.338897705078125 +46424 0.343658447265625 +46425 0.443817138671875 +46426 0.424346923828125 +46427 0.545074462890625 +46428 0.482452392578125 +46429 0.6173095703125 +46430 0.51153564453125 +46431 0.6524658203125 +46432 0.52166748046875 +46433 0.66339111328125 +46434 0.517547607421875 +46435 0.6561279296875 +46436 0.480133056640625 +46437 0.606781005859375 +46438 0.39813232421875 +46439 0.501190185546875 +46440 0.2821044921875 +46441 0.352783203125 +46442 0.143829345703125 +46443 0.176544189453125 +46444 -0.022491455078125 +46445 -0.034820556640625 +46446 -0.1986083984375 +46447 -0.258209228515625 +46448 -0.34405517578125 +46449 -0.44244384765625 +46450 -0.44915771484375 +46451 -0.5753173828125 +46452 -0.5101318359375 +46453 -0.65203857421875 +46454 -0.502410888671875 +46455 -0.641632080078125 +46456 -0.4403076171875 +46457 -0.562164306640625 +46458 -0.358917236328125 +46459 -0.458038330078125 +46460 -0.275054931640625 +46461 -0.350555419921875 +46462 -0.205108642578125 +46463 -0.260528564453125 +46464 -0.152313232421875 +46465 -0.192108154296875 +46466 -0.113922119140625 +46467 -0.141937255859375 +46468 -0.083648681640625 +46469 -0.1021728515625 +46470 -0.0535888671875 +46471 -0.062896728515625 +46472 -0.014007568359375 +46473 -0.011932373046875 +46474 0.044708251953125 +46475 0.062835693359375 +46476 0.112518310546875 +46477 0.148712158203125 +46478 0.186248779296875 +46479 0.241729736328125 +46480 0.271636962890625 +46481 0.34912109375 +46482 0.35791015625 +46483 0.457305908203125 +46484 0.427276611328125 +46485 0.54388427734375 +46486 0.451202392578125 +46487 0.5728759765625 +46488 0.3997802734375 +46489 0.506591796875 +46490 0.277862548828125 +46491 0.351226806640625 +46492 0.1168212890625 +46493 0.146514892578125 +46494 -0.04193115234375 +46495 -0.05523681640625 +46496 -0.168548583984375 +46497 -0.21624755859375 +46498 -0.261810302734375 +46499 -0.334930419921875 +46500 -0.315185546875 +46501 -0.402984619140625 +46502 -0.345184326171875 +46503 -0.4412841796875 +46504 -0.38824462890625 +46505 -0.49578857421875 +46506 -0.439361572265625 +46507 -0.5601806640625 +46508 -0.471832275390625 +46509 -0.600738525390625 +46510 -0.45928955078125 +46511 -0.584228515625 +46512 -0.37689208984375 +46513 -0.47930908203125 +46514 -0.2193603515625 +46515 -0.27935791015625 +46516 -0.006072998046875 +46517 -0.0089111328125 +46518 0.212921142578125 +46519 0.268798828125 +46520 0.381500244140625 +46521 0.482818603515625 +46522 0.47637939453125 +46523 0.60369873046875 +46524 0.51263427734375 +46525 0.650421142578125 +46526 0.522796630859375 +46527 0.66400146484375 +46528 0.5045166015625 +46529 0.6414794921875 +46530 0.449676513671875 +46531 0.572540283203125 +46532 0.390716552734375 +46533 0.498138427734375 +46534 0.34442138671875 +46535 0.439453125 +46536 0.294158935546875 +46537 0.375518798828125 +46538 0.2147216796875 +46539 0.274505615234375 +46540 0.08416748046875 +46541 0.1087646484375 +46542 -0.079925537109375 +46543 -0.099395751953125 +46544 -0.252410888671875 +46545 -0.3182373046875 +46546 -0.434295654296875 +46547 -0.5489501953125 +46548 -0.611572265625 +46549 -0.7738037109375 +46550 -0.742340087890625 +46551 -0.86383056640625 +46552 -0.800323486328125 +46553 -0.870391845703125 +46554 -0.799560546875 +46555 -0.86895751953125 +46556 -0.75048828125 +46557 -0.861053466796875 +46558 -0.639404296875 +46559 -0.765869140625 +46560 -0.457366943359375 +46561 -0.5301513671875 +46562 -0.209991455078125 +46563 -0.214691162109375 +46564 0.068603515625 +46565 0.137359619140625 +46566 0.33782958984375 +46567 0.474822998046875 +46568 0.569549560546875 +46569 0.76239013671875 +46570 0.742431640625 +46571 0.867462158203125 +46572 0.854736328125 +46573 0.870361328125 +46574 0.85986328125 +46575 0.86480712890625 +46576 0.858062744140625 +46577 0.831817626953125 +46578 0.826934814453125 +46579 0.677581787109375 +46580 0.7271728515625 +46581 0.495880126953125 +46582 0.602783203125 +46583 0.30767822265625 +46584 0.45550537109375 +46585 0.116180419921875 +46586 0.260223388671875 +46587 -0.110748291015625 +46588 0.011444091796875 +46589 -0.381805419921875 +46590 -0.25689697265625 +46591 -0.6572265625 +46592 -0.49725341796875 +46593 -0.857421875 +46594 -0.67547607421875 +46595 -0.870391845703125 +46596 -0.7861328125 +46597 -0.870391845703125 +46598 -0.851348876953125 +46599 -0.86444091796875 +46600 -0.859527587890625 +46601 -0.85723876953125 +46602 -0.861419677734375 +46603 -0.790008544921875 +46604 -0.85498046875 +46605 -0.62847900390625 +46606 -0.72039794921875 +46607 -0.3956298828125 +46608 -0.52911376953125 +46609 -0.126708984375 +46610 -0.30718994140625 +46611 0.150115966796875 +46612 -0.063873291015625 +46613 0.424041748046875 +46614 0.17901611328125 +46615 0.670623779296875 +46616 0.389923095703125 +46617 0.854522705078125 +46618 0.55462646484375 +46619 0.866485595703125 +46620 0.660736083984375 +46621 0.86920166015625 +46622 0.723388671875 +46623 0.8653564453125 +46624 0.7537841796875 +46625 0.857147216796875 +46626 0.74951171875 +46627 0.766845703125 +46628 0.71478271484375 +46629 0.628509521484375 +46630 0.643890380859375 +46631 0.462127685546875 +46632 0.5579833984375 +46633 0.297210693359375 +46634 0.467010498046875 +46635 0.14862060546875 +46636 0.351898193359375 +46637 -0.00537109375 +46638 0.218505859375 +46639 -0.15753173828125 +46640 0.063568115234375 +46641 -0.31304931640625 +46642 -0.124755859375 +46643 -0.48876953125 +46644 -0.30810546875 +46645 -0.6416015625 +46646 -0.466339111328125 +46647 -0.751373291015625 +46648 -0.618621826171875 +46649 -0.84619140625 +46650 -0.75299072265625 +46651 -0.861297607421875 +46652 -0.842132568359375 +46653 -0.863250732421875 +46654 -0.8551025390625 +46655 -0.856597900390625 +46656 -0.81658935546875 +46657 -0.7498779296875 +46658 -0.7593994140625 +46659 -0.624542236328125 +46660 -0.670135498046875 +46661 -0.47808837890625 +46662 -0.50042724609375 +46663 -0.253387451171875 +46664 -0.287628173828125 +46665 0.003692626953125 +46666 -0.087860107421875 +46667 0.2257080078125 +46668 0.109405517578125 +46669 0.427154541015625 +46670 0.3310546875 +46671 0.643218994140625 +46672 0.56927490234375 +46673 0.855926513671875 +46674 0.77642822265625 +46675 0.870361328125 +46676 0.8607177734375 +46677 0.870361328125 +46678 0.8682861328125 +46679 0.862762451171875 +46680 0.868408203125 +46681 0.79669189453125 +46682 0.860198974609375 +46683 0.595794677734375 +46684 0.779296875 +46685 0.362152099609375 +46686 0.62255859375 +46687 0.1270751953125 +46688 0.453857421875 +46689 -0.086944580078125 +46690 0.274810791015625 +46691 -0.2784423828125 +46692 0.05657958984375 +46693 -0.484832763671875 +46694 -0.21673583984375 +46695 -0.729583740234375 +46696 -0.5035400390625 +46697 -0.86688232421875 +46698 -0.751739501953125 +46699 -0.870391845703125 +46700 -0.86572265625 +46701 -0.86859130859375 +46702 -0.870391845703125 +46703 -0.86279296875 +46704 -0.8680419921875 +46705 -0.817962646484375 +46706 -0.855224609375 +46707 -0.6116943359375 +46708 -0.646514892578125 +46709 -0.3128662109375 +46710 -0.365692138671875 +46711 0.039398193359375 +46712 -0.03717041015625 +46713 0.422821044921875 +46714 0.311065673828125 +46715 0.805145263671875 +46716 0.62384033203125 +46717 0.870361328125 +46718 0.85467529296875 +46719 0.870361328125 +46720 0.870361328125 +46721 0.860015869140625 +46722 0.870361328125 +46723 0.727935791015625 +46724 0.86126708984375 +46725 0.48114013671875 +46726 0.778228759765625 +46727 0.2059326171875 +46728 0.610809326171875 +46729 -0.06103515625 +46730 0.429595947265625 +46731 -0.29913330078125 +46732 0.228363037109375 +46733 -0.516204833984375 +46734 -0.001220703125 +46735 -0.7252197265625 +46736 -0.235870361328125 +46737 -0.85980224609375 +46738 -0.44622802734375 +46739 -0.870391845703125 +46740 -0.608551025390625 +46741 -0.870391845703125 +46742 -0.684906005859375 +46743 -0.858062744140625 +46744 -0.675445556640625 +46745 -0.673004150390625 +46746 -0.628265380859375 +46747 -0.42694091796875 +46748 -0.58563232421875 +46749 -0.2100830078125 +46750 -0.55206298828125 +46751 -0.0362548828125 +46752 -0.510040283203125 +46753 0.10943603515625 +46754 -0.449493408203125 +46755 0.23516845703125 +46756 -0.34210205078125 +46757 0.373687744140625 +46758 -0.1944580078125 +46759 0.517791748046875 +46760 -0.062469482421875 +46761 0.602783203125 +46762 0.055328369140625 +46763 0.635711669921875 +46764 0.184967041015625 +46765 0.655181884765625 +46766 0.31817626953125 +46767 0.65948486328125 +46768 0.449615478515625 +46769 0.651275634765625 +46770 0.561553955078125 +46771 0.61846923828125 +46772 0.62701416015625 +46773 0.53753662109375 +46774 0.635406494140625 +46775 0.404144287109375 +46776 0.583648681640625 +46777 0.22186279296875 +46778 0.4779052734375 +46779 0.003997802734375 +46780 0.3382568359375 +46781 -0.22100830078125 +46782 0.186614990234375 +46783 -0.42449951171875 +46784 0.044952392578125 +46785 -0.579833984375 +46786 -0.047943115234375 +46787 -0.641876220703125 +46788 -0.094879150390625 +46789 -0.6177978515625 +46790 -0.147491455078125 +46791 -0.575531005859375 +46792 -0.209686279296875 +46793 -0.526336669921875 +46794 -0.2393798828125 +46795 -0.42645263671875 +46796 -0.215606689453125 +46797 -0.2581787109375 +46798 -0.1708984375 +46799 -0.068695068359375 +46800 -0.1402587890625 +46801 0.09222412109375 +46802 -0.1121826171875 +46803 0.232147216796875 +46804 -0.082427978515625 +46805 0.3509521484375 +46806 -0.079620361328125 +46807 0.410064697265625 +46808 -0.131988525390625 +46809 0.372955322265625 +46810 -0.2259521484375 +46811 0.2554931640625 +46812 -0.321624755859375 +46813 0.10711669921875 +46814 -0.405303955078125 +46815 -0.052886962890625 +46816 -0.448699951171875 +46817 -0.186279296875 +46818 -0.40643310546875 +46819 -0.23291015625 +46820 -0.297027587890625 +46821 -0.209442138671875 +46822 -0.173675537109375 +46823 -0.174163818359375 +46824 -0.0413818359375 +46825 -0.126739501953125 +46826 0.110443115234375 +46827 -0.048126220703125 +46828 0.261566162109375 +46829 0.0426025390625 +46830 0.376861572265625 +46831 0.10748291015625 +46832 0.448822021484375 +46833 0.1409912109375 +46834 0.51995849609375 +46835 0.19708251953125 +46836 0.587799072265625 +46837 0.273651123046875 +46838 0.60894775390625 +46839 0.31768798828125 +46840 0.5946044921875 +46841 0.341094970703125 +46842 0.567047119140625 +46843 0.368011474609375 +46844 0.508056640625 +46845 0.37249755859375 +46846 0.377044677734375 +46847 0.30072021484375 +46848 0.17755126953125 +46849 0.1517333984375 +46850 -0.03668212890625 +46851 -0.01470947265625 +46852 -0.2537841796875 +46853 -0.1883544921875 +46854 -0.473114013671875 +46855 -0.372711181640625 +46856 -0.645751953125 +46857 -0.51397705078125 +46858 -0.73480224609375 +46859 -0.57177734375 +46860 -0.732818603515625 +46861 -0.53948974609375 +46862 -0.65411376953125 +46863 -0.43511962890625 +46864 -0.530517578125 +46865 -0.2962646484375 +46866 -0.395172119140625 +46867 -0.161102294921875 +46868 -0.26141357421875 +46869 -0.0435791015625 +46870 -0.127960205078125 +46871 0.060394287109375 +46872 -0.00958251953125 +46873 0.13665771484375 +46874 0.077728271484375 +46875 0.170135498046875 +46876 0.134613037109375 +46877 0.16552734375 +46878 0.186981201171875 +46879 0.15728759765625 +46880 0.236236572265625 +46881 0.150787353515625 +46882 0.25909423828125 +46883 0.12200927734375 +46884 0.260955810546875 +46885 0.080108642578125 +46886 0.2623291015625 +46887 0.05126953125 +46888 0.28546142578125 +46889 0.062896728515625 +46890 0.31103515625 +46891 0.09271240234375 +46892 0.298858642578125 +46893 0.092987060546875 +46894 0.262542724609375 +46895 0.07855224609375 +46896 0.216400146484375 +46897 0.06427001953125 +46898 0.149505615234375 +46899 0.0347900390625 +46900 0.062774658203125 +46901 -0.01171875 +46902 -0.02471923828125 +46903 -0.056060791015625 +46904 -0.073883056640625 +46905 -0.055511474609375 +46906 -0.08233642578125 +46907 -0.010467529296875 +46908 -0.093475341796875 +46909 0.02508544921875 +46910 -0.126861572265625 +46911 0.025665283203125 +46912 -0.15869140625 +46913 0.017333984375 +46914 -0.186370849609375 +46915 0.00189208984375 +46916 -0.21881103515625 +46917 -0.03173828125 +46918 -0.245941162109375 +46919 -0.071502685546875 +46920 -0.283721923828125 +46921 -0.13543701171875 +46922 -0.330291748046875 +46923 -0.219970703125 +46924 -0.366363525390625 +46925 -0.300506591796875 +46926 -0.393280029296875 +46927 -0.376312255859375 +46928 -0.38665771484375 +46929 -0.416107177734375 +46930 -0.30731201171875 +46931 -0.371124267578125 +46932 -0.158294677734375 +46933 -0.242279052734375 +46934 0.02410888671875 +46935 -0.069732666015625 +46936 0.220306396484375 +46937 0.125640869140625 +46938 0.402374267578125 +46939 0.31268310546875 +46940 0.538360595703125 +46941 0.45501708984375 +46942 0.62945556640625 +46943 0.554779052734375 +46944 0.674468994140625 +46945 0.61065673828125 +46946 0.663848876953125 +46947 0.610931396484375 +46948 0.577911376953125 +46949 0.531463623046875 +46950 0.431488037109375 +46951 0.3883056640625 +46952 0.271331787109375 +46953 0.23468017578125 +46954 0.12017822265625 +46955 0.095245361328125 +46956 0.00201416015625 +46957 -0.00396728515625 +46958 -0.06903076171875 +46959 -0.04852294921875 +46960 -0.1053466796875 +46961 -0.055145263671875 +46962 -0.1495361328125 +46963 -0.0758056640625 +46964 -0.2242431640625 +46965 -0.138702392578125 +46966 -0.29901123046875 +46967 -0.209197998046875 +46968 -0.374664306640625 +46969 -0.289031982421875 +46970 -0.4515380859375 +46971 -0.37884521484375 +46972 -0.510833740234375 +46973 -0.456329345703125 +46974 -0.548828125 +46975 -0.51641845703125 +46976 -0.532562255859375 +46977 -0.519287109375 +46978 -0.457550048828125 +46979 -0.458251953125 +46980 -0.36895751953125 +46981 -0.384796142578125 +46982 -0.289306640625 +46983 -0.323699951171875 +46984 -0.21533203125 +46985 -0.269287109375 +46986 -0.12615966796875 +46987 -0.1951904296875 +46988 -0.02197265625 +46989 -0.100006103515625 +46990 0.073211669921875 +46991 -0.01055908203125 +46992 0.184173583984375 +46993 0.1033935546875 +46994 0.316436767578125 +46995 0.24908447265625 +46996 0.424407958984375 +46997 0.373199462890625 +46998 0.49310302734375 +46999 0.45806884765625 +47000 0.52947998046875 +47001 0.511474609375 +47002 0.5614013671875 +47003 0.565399169921875 +47004 0.58258056640625 +47005 0.61138916015625 +47006 0.5433349609375 +47007 0.5897216796875 +47008 0.436553955078125 +47009 0.4906005859375 +47010 0.27838134765625 +47011 0.33148193359375 +47012 0.10015869140625 +47013 0.147796630859375 +47014 -0.06146240234375 +47015 -0.01873779296875 +47016 -0.181793212890625 +47017 -0.140289306640625 +47018 -0.23883056640625 +47019 -0.191986083984375 +47020 -0.24090576171875 +47021 -0.184295654296875 +47022 -0.225616455078125 +47023 -0.161834716796875 +47024 -0.228546142578125 +47025 -0.166595458984375 +47026 -0.24591064453125 +47027 -0.19390869140625 +47028 -0.261749267578125 +47029 -0.22442626953125 +47030 -0.295074462890625 +47031 -0.279754638671875 +47032 -0.3289794921875 +47033 -0.3389892578125 +47034 -0.3238525390625 +47035 -0.3543701171875 +47036 -0.2996826171875 +47037 -0.348175048828125 +47038 -0.262237548828125 +47039 -0.32598876953125 +47040 -0.1873779296875 +47041 -0.2581787109375 +47042 -0.07177734375 +47043 -0.139801025390625 +47044 0.07147216796875 +47045 0.014617919921875 +47046 0.190185546875 +47047 0.144378662109375 +47048 0.259857177734375 +47049 0.221038818359375 +47050 0.302490234375 +47051 0.27069091796875 +47052 0.318817138671875 +47053 0.294036865234375 +47054 0.32672119140625 +47055 0.311767578125 +47056 0.339691162109375 +47057 0.339141845703125 +47058 0.344940185546875 +47059 0.360260009765625 +47060 0.330780029296875 +47061 0.360504150390625 +47062 0.27105712890625 +47063 0.308380126953125 +47064 0.1475830078125 +47065 0.18170166015625 +47066 -0.017974853515625 +47067 0.0047607421875 +47068 -0.184814453125 +47069 -0.17559814453125 +47070 -0.31378173828125 +47071 -0.3143310546875 +47072 -0.367095947265625 +47073 -0.36785888671875 +47074 -0.366912841796875 +47075 -0.36248779296875 +47076 -0.351898193359375 +47077 -0.343536376953125 +47078 -0.314300537109375 +47079 -0.3018798828125 +47080 -0.249053955078125 +47081 -0.231414794921875 +47082 -0.14410400390625 +47083 -0.117645263671875 +47084 -0.02764892578125 +47085 0.007049560546875 +47086 0.05291748046875 +47087 0.087982177734375 +47088 0.10919189453125 +47089 0.13946533203125 +47090 0.151397705078125 +47091 0.17425537109375 +47092 0.175262451171875 +47093 0.188201904296875 +47094 0.171539306640625 +47095 0.171234130859375 +47096 0.135467529296875 +47097 0.118438720703125 +47098 0.089935302734375 +47099 0.05706787109375 +47100 0.03643798828125 +47101 -0.010711669921875 +47102 -0.03076171875 +47103 -0.0914306640625 +47104 -0.09259033203125 +47105 -0.162322998046875 +47106 -0.12408447265625 +47107 -0.194549560546875 +47108 -0.090240478515625 +47109 -0.1492919921875 +47110 0.0140380859375 +47111 -0.02166748046875 +47112 0.132537841796875 +47113 0.124053955078125 +47114 0.197967529296875 +47115 0.211151123046875 +47116 0.211883544921875 +47117 0.240447998046875 +47118 0.201873779296875 +47119 0.242218017578125 +47120 0.176849365234375 +47121 0.2257080078125 +47122 0.140411376953125 +47123 0.194366455078125 +47124 0.063934326171875 +47125 0.115509033203125 +47126 -0.03125 +47127 0.0128173828125 +47128 -0.091827392578125 +47129 -0.053802490234375 +47130 -0.141143798828125 +47131 -0.110626220703125 +47132 -0.216552734375 +47133 -0.199493408203125 +47134 -0.295196533203125 +47135 -0.29437255859375 +47136 -0.32147216796875 +47137 -0.33221435546875 +47138 -0.26629638671875 +47139 -0.27972412109375 +47140 -0.173187255859375 +47141 -0.185333251953125 +47142 -0.112945556640625 +47143 -0.128204345703125 +47144 -0.092620849609375 +47145 -0.115692138671875 +47146 -0.084869384765625 +47147 -0.116455078125 +47148 -0.068359375 +47149 -0.105926513671875 +47150 -0.01666259765625 +47151 -0.053955078125 +47152 0.0782470703125 +47153 0.048797607421875 +47154 0.17626953125 +47155 0.157318115234375 +47156 0.22442626953125 +47157 0.212005615234375 +47158 0.227783203125 +47159 0.218475341796875 +47160 0.24029541015625 +47161 0.23724365234375 +47162 0.295135498046875 +47163 0.30535888671875 +47164 0.355743408203125 +47165 0.38128662109375 +47166 0.368743896484375 +47167 0.404449462890625 +47168 0.3519287109375 +47169 0.3944091796875 +47170 0.338958740234375 +47171 0.3885498046875 +47172 0.308746337890625 +47173 0.362640380859375 +47174 0.223419189453125 +47175 0.27362060546875 +47176 0.07940673828125 +47177 0.11712646484375 +47178 -0.076873779296875 +47179 -0.054901123046875 +47180 -0.199432373046875 +47181 -0.19085693359375 +47182 -0.283782958984375 +47183 -0.28570556640625 +47184 -0.329833984375 +47185 -0.339263916015625 +47186 -0.36083984375 +47187 -0.3775634765625 +47188 -0.417022705078125 +47189 -0.445709228515625 +47190 -0.49102783203125 +47191 -0.535064697265625 +47192 -0.568450927734375 +47193 -0.629058837890625 +47194 -0.622894287109375 +47195 -0.697601318359375 +47196 -0.6220703125 +47197 -0.70391845703125 +47198 -0.5614013671875 +47199 -0.6424560546875 +47200 -0.421722412109375 +47201 -0.491241455078125 +47202 -0.21697998046875 +47203 -0.265716552734375 +47204 0.001220703125 +47205 -0.023712158203125 +47206 0.203399658203125 +47207 0.201751708984375 +47208 0.358551025390625 +47209 0.375823974609375 +47210 0.45477294921875 +47211 0.485076904296875 +47212 0.527099609375 +47213 0.56884765625 +47214 0.582427978515625 +47215 0.634765625 +47216 0.580841064453125 +47217 0.63763427734375 +47218 0.512420654296875 +47219 0.5660400390625 +47220 0.4237060546875 +47221 0.4720458984375 +47222 0.360504150390625 +47223 0.40692138671875 +47224 0.329498291015625 +47225 0.3778076171875 +47226 0.324066162109375 +47227 0.376953125 +47228 0.315704345703125 +47229 0.371978759765625 +47230 0.26043701171875 +47231 0.313140869140625 +47232 0.1441650390625 +47233 0.184417724609375 +47234 -0.010467529296875 +47235 0.011199951171875 +47236 -0.171966552734375 +47237 -0.171051025390625 +47238 -0.318267822265625 +47239 -0.33740234375 +47240 -0.43536376953125 +47241 -0.47198486328125 +47242 -0.510650634765625 +47243 -0.560394287109375 +47244 -0.52471923828125 +47245 -0.58056640625 +47246 -0.491180419921875 +47247 -0.54754638671875 +47248 -0.45220947265625 +47249 -0.508575439453125 +47250 -0.40435791015625 +47251 -0.459503173828125 +47252 -0.34259033203125 +47253 -0.394378662109375 +47254 -0.30206298828125 +47255 -0.35260009765625 +47256 -0.26300048828125 +47257 -0.31170654296875 +47258 -0.159576416015625 +47259 -0.197418212890625 +47260 0.009674072265625 +47261 -0.007965087890625 +47262 0.2010498046875 +47263 0.207489013671875 +47264 0.3792724609375 +47265 0.409210205078125 +47266 0.52215576171875 +47267 0.57208251953125 +47268 0.60302734375 +47269 0.66595458984375 +47270 0.59356689453125 +47271 0.65875244140625 +47272 0.509033203125 +47273 0.56744384765625 +47274 0.38458251953125 +47275 0.431396484375 +47276 0.259368896484375 +47277 0.29443359375 +47278 0.156585693359375 +47279 0.182464599609375 +47280 0.048126220703125 +47281 0.06365966796875 +47282 -0.0782470703125 +47283 -0.075958251953125 +47284 -0.180755615234375 +47285 -0.189422607421875 +47286 -0.255035400390625 +47287 -0.271942138671875 +47288 -0.31793212890625 +47289 -0.342529296875 +47290 -0.336639404296875 +47291 -0.364166259765625 +47292 -0.302642822265625 +47293 -0.327239990234375 +47294 -0.256195068359375 +47295 -0.2769775390625 +47296 -0.233184814453125 +47297 -0.253692626953125 +47298 -0.2215576171875 +47299 -0.24365234375 +47300 -0.178436279296875 +47301 -0.1983642578125 +47302 -0.102569580078125 +47303 -0.116241455078125 +47304 -0.029205322265625 +47305 -0.036834716796875 +47306 0.03704833984375 +47307 0.034881591796875 +47308 0.089263916015625 +47309 0.09124755859375 +47310 0.1065673828125 +47311 0.10888671875 +47312 0.12237548828125 +47313 0.125518798828125 +47314 0.1513671875 +47315 0.15771484375 +47316 0.169403076171875 +47317 0.17828369140625 +47318 0.16217041015625 +47319 0.17108154296875 +47320 0.12432861328125 +47321 0.129974365234375 +47322 0.080322265625 +47323 0.082427978515625 +47324 0.02960205078125 +47325 0.027679443359375 +47326 -0.05560302734375 +47327 -0.065643310546875 +47328 -0.1412353515625 +47329 -0.15936279296875 +47330 -0.1912841796875 +47331 -0.21307373046875 +47332 -0.212615966796875 +47333 -0.234649658203125 +47334 -0.18389892578125 +47335 -0.2001953125 +47336 -0.113433837890625 +47337 -0.119171142578125 +47338 -0.030609130859375 +47339 -0.024749755859375 +47340 0.0670166015625 +47341 0.085784912109375 +47342 0.149017333984375 +47343 0.178131103515625 +47344 0.182769775390625 +47345 0.215576171875 +47346 0.1800537109375 +47347 0.211456298828125 +47348 0.149200439453125 +47349 0.17523193359375 +47350 0.10955810546875 +47351 0.128753662109375 +47352 0.08758544921875 +47353 0.1019287109375 +47354 0.0650634765625 +47355 0.0743408203125 +47356 0.039459228515625 +47357 0.04327392578125 +47358 0.03680419921875 +47359 0.038177490234375 +47360 0.072845458984375 +47361 0.076263427734375 +47362 0.13330078125 +47363 0.14105224609375 +47364 0.17626953125 +47365 0.186431884765625 +47366 0.1798095703125 +47367 0.188812255859375 +47368 0.135284423828125 +47369 0.1390380859375 +47370 0.046875 +47371 0.041778564453125 +47372 -0.06390380859375 +47373 -0.079437255859375 +47374 -0.192413330078125 +47375 -0.219390869140625 +47376 -0.3292236328125 +47377 -0.367828369140625 +47378 -0.446868896484375 +47379 -0.494873046875 +47380 -0.504547119140625 +47381 -0.556243896484375 +47382 -0.462432861328125 +47383 -0.508697509765625 +47384 -0.3419189453125 +47385 -0.3756103515625 +47386 -0.19989013671875 +47387 -0.218902587890625 +47388 -0.059356689453125 +47389 -0.063751220703125 +47390 0.08135986328125 +47391 0.091552734375 +47392 0.212310791015625 +47393 0.23602294921875 +47394 0.309051513671875 +47395 0.342987060546875 +47396 0.355804443359375 +47397 0.39520263671875 +47398 0.349609375 +47399 0.389373779296875 +47400 0.28936767578125 +47401 0.324249267578125 +47402 0.1973876953125 +47403 0.224090576171875 +47404 0.106201171875 +47405 0.124267578125 +47406 0.02703857421875 +47407 0.037078857421875 +47408 -0.01495361328125 +47409 -0.010101318359375 +47410 -0.0218505859375 +47411 -0.019439697265625 +47412 -0.023040771484375 +47413 -0.022796630859375 +47414 -0.00152587890625 +47415 -0.001556396484375 +47416 0.053619384765625 +47417 0.056304931640625 +47418 0.10174560546875 +47419 0.106719970703125 +47420 0.094207763671875 +47421 0.096893310546875 +47422 0.0455322265625 +47423 0.042694091796875 +47424 -0.009552001953125 +47425 -0.018035888671875 +47426 -0.062347412109375 +47427 -0.07586669921875 +47428 -0.102447509765625 +47429 -0.11944580078125 +47430 -0.139923095703125 +47431 -0.15972900390625 +47432 -0.18017578125 +47433 -0.202606201171875 +47434 -0.223602294921875 +47435 -0.24859619140625 +47436 -0.277008056640625 +47437 -0.30517578125 +47438 -0.3309326171875 +47439 -0.36212158203125 +47440 -0.3594970703125 +47441 -0.39141845703125 +47442 -0.32781982421875 +47443 -0.35528564453125 +47444 -0.23236083984375 +47445 -0.249969482421875 +47446 -0.089111328125 +47447 -0.092864990234375 +47448 0.077178955078125 +47449 0.08905029296875 +47450 0.210906982421875 +47451 0.2352294921875 +47452 0.287384033203125 +47453 0.318817138671875 +47454 0.323944091796875 +47455 0.358642578125 +47456 0.314178466796875 +47457 0.347747802734375 +47458 0.25762939453125 +47459 0.28564453125 +47460 0.201019287109375 +47461 0.223175048828125 +47462 0.177734375 +47463 0.196746826171875 +47464 0.163360595703125 +47465 0.179840087890625 +47466 0.14227294921875 +47467 0.155548095703125 +47468 0.139556884765625 +47469 0.151214599609375 +47470 0.14605712890625 +47471 0.156951904296875 +47472 0.123992919921875 +47473 0.13177490234375 +47474 0.096405029296875 +47475 0.100799560546875 +47476 0.084503173828125 +47477 0.087127685546875 +47478 0.055267333984375 +47479 0.05487060546875 +47480 -0.0032958984375 +47481 -0.009002685546875 +47482 -0.09075927734375 +47483 -0.10400390625 +47484 -0.20648193359375 +47485 -0.229400634765625 +47486 -0.3231201171875 +47487 -0.35552978515625 +47488 -0.40338134765625 +47489 -0.441925048828125 +47490 -0.433685302734375 +47491 -0.473846435546875 +47492 -0.4263916015625 +47493 -0.464813232421875 +47494 -0.3853759765625 +47495 -0.419097900390625 +47496 -0.308380126953125 +47497 -0.334320068359375 +47498 -0.211395263671875 +47499 -0.227935791015625 +47500 -0.1160888671875 +47501 -0.12347412109375 +47502 -0.028564453125 +47503 -0.02764892578125 +47504 0.067901611328125 +47505 0.077667236328125 +47506 0.19244384765625 +47507 0.2132568359375 +47508 0.35400390625 +47509 0.38885498046875 +47510 0.532623291015625 +47511 0.582794189453125 +47512 0.672149658203125 +47513 0.734039306640625 +47514 0.7335205078125 +47515 0.800140380859375 +47516 0.714111328125 +47517 0.7783203125 +47518 0.610748291015625 +47519 0.6651611328125 +47520 0.4224853515625 +47521 0.45965576171875 +47522 0.18365478515625 +47523 0.199188232421875 +47524 -0.04547119140625 +47525 -0.050689697265625 +47526 -0.212493896484375 +47527 -0.23297119140625 +47528 -0.30133056640625 +47529 -0.33013916015625 +47530 -0.33612060546875 +47531 -0.368408203125 +47532 -0.345550537109375 +47533 -0.378936767578125 +47534 -0.34368896484375 +47535 -0.376983642578125 +47536 -0.3463134765625 +47537 -0.37969970703125 +47538 -0.357452392578125 +47539 -0.391510009765625 +47540 -0.352203369140625 +47541 -0.385345458984375 +47542 -0.312774658203125 +47543 -0.3419189453125 +47544 -0.25909423828125 +47545 -0.28289794921875 +47546 -0.230987548828125 +47547 -0.251617431640625 +47548 -0.2449951171875 +47549 -0.266143798828125 +47550 -0.25225830078125 +47551 -0.273345947265625 +47552 -0.2008056640625 +47553 -0.216796875 +47554 -0.11981201171875 +47555 -0.128265380859375 +47556 -0.06488037109375 +47557 -0.068145751953125 +47558 -0.042083740234375 +47559 -0.0430908203125 +47560 -0.0250244140625 +47561 -0.024444580078125 +47562 0.016571044921875 +47563 0.020721435546875 +47564 0.112213134765625 +47565 0.124481201171875 +47566 0.2352294921875 +47567 0.25787353515625 +47568 0.34716796875 +47569 0.379119873046875 +47570 0.44036865234375 +47571 0.47991943359375 +47572 0.48529052734375 +47573 0.5281982421875 +47574 0.470123291015625 +47575 0.511138916015625 +47576 0.42010498046875 +47577 0.456207275390625 +47578 0.375762939453125 +47579 0.407470703125 +47580 0.354400634765625 +47581 0.383758544921875 +47582 0.33001708984375 +47583 0.35687255859375 +47584 0.288818359375 +47585 0.31182861328125 +47586 0.23284912109375 +47587 0.250885009765625 +47588 0.154205322265625 +47589 0.1654052734375 +47590 0.03436279296875 +47591 0.035247802734375 +47592 -0.128936767578125 +47593 -0.142059326171875 +47594 -0.30731201171875 +47595 -0.33563232421875 +47596 -0.49066162109375 +47597 -0.5345458984375 +47598 -0.663360595703125 +47599 -0.72186279296875 +47600 -0.769378662109375 +47601 -0.836669921875 +47602 -0.766082763671875 +47603 -0.8326416015625 +47604 -0.67169189453125 +47605 -0.7296142578125 +47606 -0.5367431640625 +47607 -0.582550048828125 +47608 -0.405975341796875 +47609 -0.440093994140625 +47610 -0.299713134765625 +47611 -0.324310302734375 +47612 -0.1868896484375 +47613 -0.20147705078125 +47614 -0.042694091796875 +47615 -0.044647216796875 +47616 0.093475341796875 +47617 0.103973388671875 +47618 0.18231201171875 +47619 0.202392578125 +47620 0.23724365234375 +47621 0.264495849609375 +47622 0.3048095703125 +47623 0.338897705078125 +47624 0.402496337890625 +47625 0.443817138671875 +47626 0.49786376953125 +47627 0.545074462890625 +47628 0.5667724609375 +47629 0.6173095703125 +47630 0.601531982421875 +47631 0.6524658203125 +47632 0.614288330078125 +47633 0.66339111328125 +47634 0.610626220703125 +47635 0.6561279296875 +47636 0.567596435546875 +47637 0.606781005859375 +47638 0.471466064453125 +47639 0.501190185546875 +47640 0.334747314453125 +47641 0.352783203125 +47642 0.17144775390625 +47643 0.176544189453125 +47644 -0.025604248046875 +47645 -0.034820556640625 +47646 -0.234649658203125 +47647 -0.258209228515625 +47648 -0.407135009765625 +47649 -0.44244384765625 +47650 -0.53155517578125 +47651 -0.5753173828125 +47652 -0.60345458984375 +47653 -0.65203857421875 +47654 -0.5933837890625 +47655 -0.641632080078125 +47656 -0.518524169921875 +47657 -0.562164306640625 +47658 -0.42108154296875 +47659 -0.458038330078125 +47660 -0.321197509765625 +47661 -0.350555419921875 +47662 -0.238555908203125 +47663 -0.260528564453125 +47664 -0.176910400390625 +47665 -0.192108154296875 +47666 -0.13287353515625 +47667 -0.141937255859375 +47668 -0.0987548828125 +47669 -0.1021728515625 +47670 -0.06494140625 +47671 -0.062896728515625 +47672 -0.01959228515625 +47673 -0.011932373046875 +47674 0.0489501953125 +47675 0.062835693359375 +47676 0.128753662109375 +47677 0.148712158203125 +47678 0.216094970703125 +47679 0.241729736328125 +47680 0.317901611328125 +47681 0.34912109375 +47682 0.421295166015625 +47683 0.457305908203125 +47684 0.5048828125 +47685 0.54388427734375 +47686 0.534332275390625 +47687 0.5728759765625 +47688 0.4736328125 +47689 0.506591796875 +47690 0.32855224609375 +47691 0.351226806640625 +47692 0.13671875 +47693 0.146514892578125 +47694 -0.052215576171875 +47695 -0.05523681640625 +47696 -0.202484130859375 +47697 -0.21624755859375 +47698 -0.312713623046875 +47699 -0.334930419921875 +47700 -0.37518310546875 +47701 -0.402984619140625 +47702 -0.409820556640625 +47703 -0.4412841796875 +47704 -0.460479736328125 +47705 -0.49578857421875 +47706 -0.521209716796875 +47707 -0.5601806640625 +47708 -0.5599365234375 +47709 -0.600738525390625 +47710 -0.54498291015625 +47711 -0.584228515625 +47712 -0.446441650390625 +47713 -0.47930908203125 +47714 -0.2579345703125 +47715 -0.27935791015625 +47716 -0.002685546875 +47717 -0.0089111328125 +47718 0.259185791015625 +47719 0.268798828125 +47720 0.4603271484375 +47721 0.482818603515625 +47722 0.5728759765625 +47723 0.60369873046875 +47724 0.614990234375 +47725 0.650421142578125 +47726 0.6258544921875 +47727 0.66400146484375 +47728 0.60272216796875 +47729 0.6414794921875 +47730 0.535888671875 +47731 0.572540283203125 +47732 0.46435546875 +47733 0.498138427734375 +47734 0.4083251953125 +47735 0.439453125 +47736 0.34783935546875 +47737 0.375518798828125 +47738 0.2525634765625 +47739 0.274505615234375 +47740 0.09613037109375 +47741 0.1087646484375 +47742 -0.100311279296875 +47743 -0.099395751953125 +47744 -0.306640625 +47745 -0.3182373046875 +47746 -0.524139404296875 +47747 -0.5489501953125 +47748 -0.73602294921875 +47749 -0.7738037109375 +47750 -0.858612060546875 +47751 -0.86383056640625 +47752 -0.8660888671875 +47753 -0.870391845703125 +47754 -0.865875244140625 +47755 -0.86895751953125 +47756 -0.859344482421875 +47757 -0.861053466796875 +47758 -0.764617919921875 +47759 -0.765869140625 +47760 -0.54541015625 +47761 -0.5301513671875 +47762 -0.247955322265625 +47763 -0.214691162109375 +47764 0.086822509765625 +47765 0.137359619140625 +47766 0.41009521484375 +47767 0.474822998046875 +47768 0.688079833984375 +47769 0.76239013671875 +47770 0.858917236328125 +47771 0.867462158203125 +47772 0.870361328125 +47773 0.870361328125 +47774 0.870361328125 +47775 0.86480712890625 +47776 0.86273193359375 +47777 0.831817626953125 +47778 0.816436767578125 +47779 0.677581787109375 +47780 0.666229248046875 +47781 0.495880126953125 +47782 0.49859619140625 +47783 0.30767822265625 +47784 0.3162841796875 +47785 0.116180419921875 +47786 0.08905029296875 +47787 -0.110748291015625 +47788 -0.190460205078125 +47789 -0.381805419921875 +47790 -0.482940673828125 +47791 -0.6572265625 +47792 -0.733367919921875 +47793 -0.857421875 +47794 -0.859832763671875 +47795 -0.870391845703125 +47796 -0.869110107421875 +47797 -0.870391845703125 +47798 -0.870391845703125 +47799 -0.86444091796875 +47800 -0.869659423828125 +47801 -0.85723876953125 +47802 -0.86541748046875 +47803 -0.790008544921875 +47804 -0.834625244140625 +47805 -0.62847900390625 +47806 -0.632965087890625 +47807 -0.3956298828125 +47808 -0.38238525390625 +47809 -0.126708984375 +47810 -0.109832763671875 +47811 0.150115966796875 +47812 0.173492431640625 +47813 0.424041748046875 +47814 0.44268798828125 +47815 0.670623779296875 +47816 0.662322998046875 +47817 0.854522705078125 +47818 0.817657470703125 +47819 0.866485595703125 +47820 0.85906982421875 +47821 0.86920166015625 +47822 0.861541748046875 +47823 0.8653564453125 +47824 0.859588623046875 +47825 0.857147216796875 +47826 0.84326171875 +47827 0.766845703125 +47828 0.752777099609375 +47829 0.628509521484375 +47830 0.625946044921875 +47831 0.462127685546875 +47832 0.489471435546875 +47833 0.297210693359375 +47834 0.356658935546875 +47835 0.14862060546875 +47836 0.20672607421875 +47837 -0.00537109375 +47838 0.047088623046875 +47839 -0.15753173828125 +47840 -0.126068115234375 +47841 -0.31304931640625 +47842 -0.32708740234375 +47843 -0.48876953125 +47844 -0.51287841796875 +47845 -0.6416015625 +47846 -0.661834716796875 +47847 -0.751373291015625 +47848 -0.7982177734375 +47849 -0.84619140625 +47850 -0.860626220703125 +47851 -0.861297607421875 +47852 -0.8670654296875 +47853 -0.863250732421875 +47854 -0.86468505859375 +47855 -0.856597900390625 +47856 -0.85498046875 +47857 -0.7498779296875 +47858 -0.759735107421875 +47859 -0.624542236328125 +47860 -0.630950927734375 +47861 -0.47808837890625 +47862 -0.41778564453125 +47863 -0.253387451171875 +47864 -0.164093017578125 +47865 0.003692626953125 +47866 0.065093994140625 +47867 0.2257080078125 +47868 0.2823486328125 +47869 0.427154541015625 +47870 0.519561767578125 +47871 0.643218994140625 +47872 0.769500732421875 +47873 0.855926513671875 +47874 0.8680419921875 +47875 0.870361328125 +47876 0.870361328125 +47877 0.870361328125 +47878 0.8651123046875 +47879 0.862762451171875 +47880 0.83843994140625 +47881 0.79669189453125 +47882 0.655731201171875 +47883 0.595794677734375 +47884 0.436767578125 +47885 0.362152099609375 +47886 0.2117919921875 +47887 0.1270751953125 +47888 0.00262451171875 +47889 -0.086944580078125 +47890 -0.189300537109375 +47891 -0.2784423828125 +47892 -0.400421142578125 +47893 -0.484832763671875 +47894 -0.6533203125 +47895 -0.729583740234375 +47896 -0.85980224609375 +47897 -0.86688232421875 +47898 -0.870391845703125 +47899 -0.870391845703125 +47900 -0.870391845703125 +47901 -0.86859130859375 +47902 -0.866241455078125 +47903 -0.86279296875 +47904 -0.855377197265625 +47905 -0.817962646484375 +47906 -0.667388916015625 +47907 -0.6116943359375 +47908 -0.37738037109375 +47909 -0.3128662109375 +47910 -0.0308837890625 +47911 0.039398193359375 +47912 0.35009765625 +47913 0.422821044921875 +47914 0.73345947265625 +47915 0.805145263671875 +47916 0.870361328125 +47917 0.870361328125 +47918 0.870361328125 +47919 0.870361328125 +47920 0.860076904296875 +47921 0.860015869140625 +47922 0.729766845703125 +47923 0.727935791015625 +47924 0.48455810546875 +47925 0.48114013671875 +47926 0.210845947265625 +47927 0.2059326171875 +47928 -0.05511474609375 +47929 -0.06103515625 +47930 -0.292877197265625 +47931 -0.29913330078125 +47932 -0.50994873046875 +47933 -0.516204833984375 +47934 -0.7188720703125 +47935 -0.7252197265625 +47936 -0.859100341796875 +47937 -0.85980224609375 +47938 -0.870391845703125 +47939 -0.870391845703125 +47940 -0.870391845703125 +47941 -0.870391845703125 +47942 -0.858184814453125 +47943 -0.858062744140625 +47944 -0.675689697265625 +47945 -0.673004150390625 +47946 -0.43121337890625 +47947 -0.42694091796875 +47948 -0.2149658203125 +47949 -0.2100830078125 +47950 -0.040679931640625 +47951 -0.0362548828125 +47952 0.1060791015625 +47953 0.10943603515625 +47954 0.233184814453125 +47955 0.23516845703125 +47956 0.3726806640625 +47957 0.373687744140625 +47958 0.517303466796875 +47959 0.517791748046875 +47960 0.603271484375 +47961 0.602783203125 +47962 0.63739013671875 +47963 0.635711669921875 +47964 0.657562255859375 +47965 0.655181884765625 +47966 0.662078857421875 +47967 0.65948486328125 +47968 0.653533935546875 +47969 0.651275634765625 +47970 0.620086669921875 +47971 0.61846923828125 +47972 0.538665771484375 +47973 0.53753662109375 +47974 0.4051513671875 +47975 0.404144287109375 +47976 0.22320556640625 +47977 0.22186279296875 +47978 0.00604248046875 +47979 0.003997802734375 +47980 -0.21820068359375 +47981 -0.22100830078125 +47982 -0.421173095703125 +47983 -0.42449951171875 +47984 -0.57647705078125 +47985 -0.579833984375 +47986 -0.63958740234375 +47987 -0.641876220703125 +47988 -0.617462158203125 +47989 -0.6177978515625 +47990 -0.576873779296875 +47991 -0.575531005859375 +47992 -0.52886962890625 +47993 -0.526336669921875 +47994 -0.430389404296875 +47995 -0.42645263671875 +47996 -0.264007568359375 +47997 -0.2581787109375 +47998 -0.076202392578125 +47999 -0.068695068359375 +48000 0.083953857421875 +48001 0.09222412109375 +48002 0.2237548828125 +48003 0.232147216796875 +48004 0.34295654296875 +48005 0.3509521484375 +48006 0.403472900390625 +48007 0.410064697265625 +48008 0.369232177734375 +48009 0.372955322265625 +48010 0.2557373046875 +48011 0.2554931640625 +48012 0.11151123046875 +48013 0.10711669921875 +48014 -0.0445556640625 +48015 -0.052886962890625 +48016 -0.17486572265625 +48017 -0.186279296875 +48018 -0.22027587890625 +48019 -0.23291015625 +48020 -0.19720458984375 +48021 -0.209442138671875 +48022 -0.162994384765625 +48023 -0.174163818359375 +48024 -0.11724853515625 +48025 -0.126739501953125 +48026 -0.04119873046875 +48027 -0.048126220703125 +48028 0.046478271484375 +48029 0.0426025390625 +48030 0.1085205078125 +48031 0.10748291015625 +48032 0.13958740234375 +48033 0.1409912109375 +48034 0.19287109375 +48035 0.19708251953125 +48036 0.266448974609375 +48037 0.273651123046875 +48038 0.3082275390625 +48039 0.31768798828125 +48040 0.329986572265625 +48041 0.341094970703125 +48042 0.355560302734375 +48043 0.368011474609375 +48044 0.35943603515625 +48045 0.37249755859375 +48046 0.288665771484375 +48047 0.30072021484375 +48048 0.14227294921875 +48049 0.1517333984375 +48050 -0.02093505859375 +48051 -0.01470947265625 +48052 -0.190887451171875 +48053 -0.1883544921875 +48054 -0.37109375 +48055 -0.372711181640625 +48056 -0.50872802734375 +48057 -0.51397705078125 +48058 -0.564117431640625 +48059 -0.57177734375 +48060 -0.53082275390625 +48061 -0.53948974609375 +48062 -0.426666259765625 +48063 -0.43511962890625 +48064 -0.2886962890625 +48065 -0.2962646484375 +48066 -0.154541015625 +48067 -0.161102294921875 +48068 -0.0379638671875 +48069 -0.0435791015625 +48070 0.06494140625 +48071 0.060394287109375 +48072 0.1402587890625 +48073 0.13665771484375 +48074 0.17315673828125 +48075 0.170135498046875 +48076 0.16827392578125 +48077 0.16552734375 +48078 0.1595458984375 +48079 0.15728759765625 +48080 0.152313232421875 +48081 0.150787353515625 +48082 0.12298583984375 +48083 0.12200927734375 +48084 0.08062744140625 +48085 0.080108642578125 +48086 0.051055908203125 +48087 0.05126953125 +48088 0.06134033203125 +48089 0.062896728515625 +48090 0.089569091796875 +48091 0.09271240234375 +48092 0.088836669921875 +48093 0.092987060546875 +48094 0.07379150390625 +48095 0.07855224609375 +48096 0.059112548828125 +48097 0.06427001953125 +48098 0.029693603515625 +48099 0.0347900390625 +48100 -0.016265869140625 +48101 -0.01171875 +48102 -0.059814453125 +48103 -0.056060791015625 +48104 -0.058929443359375 +48105 -0.055511474609375 +48106 -0.014007568359375 +48107 -0.010467529296875 +48108 0.02178955078125 +48109 0.02508544921875 +48110 0.0233154296875 +48111 0.025665283203125 +48112 0.01617431640625 +48113 0.017333984375 +48114 0.002044677734375 +48115 0.00189208984375 +48116 -0.029998779296875 +48117 -0.03173828125 +48118 -0.068206787109375 +48119 -0.071502685546875 +48120 -0.130340576171875 +48121 -0.13543701171875 +48122 -0.212921142578125 +48123 -0.219970703125 +48124 -0.291778564453125 +48125 -0.300506591796875 +48126 -0.3662109375 +48127 -0.376312255859375 +48128 -0.40533447265625 +48129 -0.416107177734375 +48130 -0.360992431640625 +48131 -0.371124267578125 +48132 -0.23406982421875 +48133 -0.242279052734375 +48134 -0.0643310546875 +48135 -0.069732666015625 +48136 0.127716064453125 +48137 0.125640869140625 +48138 0.311248779296875 +48139 0.31268310546875 +48140 0.450225830078125 +48141 0.45501708984375 +48142 0.547027587890625 +48143 0.554779052734375 +48144 0.600555419921875 +48145 0.61065673828125 +48146 0.599212646484375 +48147 0.610931396484375 +48148 0.518951416015625 +48149 0.531463623046875 +48150 0.37579345703125 +48151 0.3883056640625 +48152 0.222930908203125 +48153 0.23468017578125 +48154 0.0849609375 +48155 0.095245361328125 +48156 -0.01220703125 +48157 -0.00396728515625 +48158 -0.05426025390625 +48159 -0.04852294921875 +48160 -0.05810546875 +48161 -0.055145263671875 +48162 -0.075897216796875 +48163 -0.0758056640625 +48164 -0.136016845703125 +48165 -0.138702392578125 +48166 -0.203948974609375 +48167 -0.209197998046875 +48168 -0.281585693359375 +48169 -0.289031982421875 +48170 -0.36968994140625 +48171 -0.37884521484375 +48172 -0.446014404296875 +48173 -0.456329345703125 +48174 -0.505523681640625 +48175 -0.51641845703125 +48176 -0.5084228515625 +48177 -0.519287109375 +48178 -0.448028564453125 +48179 -0.458251953125 +48180 -0.37579345703125 +48181 -0.384796142578125 +48182 -0.31634521484375 +48183 -0.323699951171875 +48184 -0.263946533203125 +48185 -0.269287109375 +48186 -0.192108154296875 +48187 -0.1951904296875 +48188 -0.099273681640625 +48189 -0.100006103515625 +48190 -0.012115478515625 +48191 -0.01055908203125 +48192 0.09967041015625 +48193 0.1033935546875 +48194 0.24346923828125 +48195 0.24908447265625 +48196 0.366058349609375 +48197 0.373199462890625 +48198 0.4498291015625 +48199 0.45806884765625 +48200 0.502593994140625 +48201 0.511474609375 +48202 0.556396484375 +48203 0.565399169921875 +48204 0.602783203125 +48205 0.61138916015625 +48206 0.58197021484375 +48207 0.5897216796875 +48208 0.484100341796875 +48209 0.4906005859375 +48210 0.326568603515625 +48211 0.33148193359375 +48212 0.144683837890625 +48213 0.147796630859375 +48214 -0.01995849609375 +48215 -0.01873779296875 +48216 -0.139617919921875 +48217 -0.140289306640625 +48218 -0.18951416015625 +48219 -0.191986083984375 +48220 -0.180206298828125 +48221 -0.184295654296875 +48222 -0.1563720703125 +48223 -0.161834716796875 +48224 -0.16009521484375 +48225 -0.166595458984375 +48226 -0.186737060546875 +48227 -0.19390869140625 +48228 -0.217010498046875 +48229 -0.22442626953125 +48230 -0.272491455078125 +48231 -0.279754638671875 +48232 -0.332244873046875 +48233 -0.3389892578125 +48234 -0.348541259765625 +48235 -0.3543701171875 +48236 -0.34356689453125 +48237 -0.348175048828125 +48238 -0.322784423828125 +48239 -0.32598876953125 +48240 -0.25653076171875 +48241 -0.2581787109375 +48242 -0.139739990234375 +48243 -0.139801025390625 +48244 0.013153076171875 +48245 0.014617919921875 +48246 0.141510009765625 +48247 0.144378662109375 +48248 0.21697998046875 +48249 0.221038818359375 +48250 0.26568603515625 +48251 0.27069091796875 +48252 0.28839111328125 +48253 0.294036865234375 +48254 0.305816650390625 +48255 0.311767578125 +48256 0.333251953125 +48257 0.339111328125 +48258 0.354766845703125 +48259 0.35992431640625 +48260 0.355712890625 +48261 0.35968017578125 +48262 0.30450439453125 +48263 0.3074951171875 +48264 0.17889404296875 +48265 0.181640625 +48266 0.003173828125 +48267 0.00616455078125 +48268 -0.1759033203125 +48269 -0.1727294921875 +48270 -0.3133544921875 +48271 -0.310638427734375 +48272 -0.365692138671875 +48273 -0.364593505859375 +48274 -0.359283447265625 +48275 -0.3603515625 +48276 -0.3394775390625 +48277 -0.342498779296875 +48278 -0.297210693359375 +48279 -0.302032470703125 +48280 -0.226409912109375 +48281 -0.232879638671875 +48282 -0.112579345703125 +48283 -0.120819091796875 +48284 0.01190185546875 +48285 0.00225830078125 +48286 0.092376708984375 +48287 0.082550048828125 +48288 0.143157958984375 +48289 0.13409423828125 +48290 0.177093505859375 +48291 0.169403076171875 +48292 0.190032958984375 +48293 0.184295654296875 +48294 0.17193603515625 +48295 0.16876220703125 +48296 0.118011474609375 +48297 0.117919921875 +48298 0.0555419921875 +48299 0.05853271484375 +48300 -0.01324462890625 +48301 -0.00732421875 +48302 -0.094818115234375 +48303 -0.08612060546875 +48304 -0.166351318359375 +48305 -0.15545654296875 +48306 -0.198974609375 +48307 -0.18701171875 +48308 -0.15386962890625 +48309 -0.142608642578125 +48310 -0.026153564453125 +48311 -0.01739501953125 +48312 0.119903564453125 +48313 0.12542724609375 +48314 0.207550048828125 +48315 0.210418701171875 +48316 0.237579345703125 +48317 0.238433837890625 +48318 0.240203857421875 +48319 0.2392578125 +48320 0.224639892578125 +48321 0.222076416015625 +48322 0.19427490234375 +48323 0.190338134765625 +48324 0.116363525390625 +48325 0.111907958984375 +48326 0.0145263671875 +48327 0.010101318359375 +48328 -0.051361083984375 +48329 -0.056060791015625 +48330 -0.10760498046875 +48331 -0.11236572265625 +48332 -0.196075439453125 +48333 -0.20001220703125 +48334 -0.290771484375 +48335 -0.293365478515625 +48336 -0.32861328125 +48337 -0.330352783203125 +48338 -0.27630615234375 +48339 -0.278289794921875 +48340 -0.182281494140625 +48341 -0.18487548828125 +48342 -0.12567138671875 +48343 -0.12799072265625 +48344 -0.113800048828125 +48345 -0.1148681640625 +48346 -0.11529541015625 +48347 -0.11474609375 +48348 -0.10552978515625 +48349 -0.103546142578125 +48350 -0.0543212890625 +48351 -0.051666259765625 +48352 0.047698974609375 +48353 0.050079345703125 +48354 0.15557861328125 +48355 0.157379150390625 +48356 0.209716796875 +48357 0.2115478515625 +48358 0.215789794921875 +48359 0.218109130859375 +48360 0.23431396484375 +48361 0.236602783203125 +48362 0.3023681640625 +48363 0.303497314453125 +48364 0.378387451171875 +48365 0.377899169921875 +48366 0.40179443359375 +48367 0.400238037109375 +48368 0.392120361328125 +48369 0.3897705078125 +48370 0.386749267578125 +48371 0.383331298828125 +48372 0.361419677734375 +48373 0.357147216796875 +48374 0.273040771484375 +48375 0.26885986328125 +48376 0.1171875 +48377 0.114227294921875 +48378 -0.054229736328125 +48379 -0.05560302734375 +48380 -0.189605712890625 +48381 -0.189788818359375 +48382 -0.283935546875 +48383 -0.283416748046875 +48384 -0.33709716796875 +48385 -0.3369140625 +48386 -0.375152587890625 +48387 -0.375579833984375 +48388 -0.443206787109375 +48389 -0.4423828125 +48390 -0.532623291015625 +48391 -0.528717041015625 +48392 -0.626800537109375 +48393 -0.618560791015625 +48394 -0.695648193359375 +48395 -0.68310546875 +48396 -0.702392578125 +48397 -0.68731689453125 +48398 -0.641448974609375 +48399 -0.6259765625 +48400 -0.49078369140625 +48401 -0.478363037109375 +48402 -0.26580810546875 +48403 -0.25933837890625 +48404 -0.024322509765625 +48405 -0.02423095703125 +48406 0.200653076171875 +48407 0.195220947265625 +48408 0.37432861328125 +48409 0.36553955078125 +48410 0.4832763671875 +48411 0.47369384765625 +48412 0.56683349609375 +48413 0.556884765625 +48414 0.632659912109375 +48415 0.6221923828125 +48416 0.63555908203125 +48417 0.62646484375 +48418 0.564117431640625 +48419 0.558746337890625 +48420 0.470367431640625 +48421 0.468597412109375 +48422 0.405548095703125 +48423 0.404876708984375 +48424 0.376800537109375 +48425 0.374542236328125 +48426 0.3763427734375 +48427 0.370361328125 +48428 0.371795654296875 +48429 0.361724853515625 +48430 0.313385009765625 +48431 0.301513671875 +48432 0.18505859375 +48433 0.1746826171875 +48434 0.012176513671875 +48435 0.00567626953125 +48436 -0.1697998046875 +48437 -0.171539306640625 +48438 -0.335968017578125 +48439 -0.333038330078125 +48440 -0.470428466796875 +48441 -0.46356201171875 +48442 -0.558807373046875 +48443 -0.54931640625 +48444 -0.57904052734375 +48445 -0.569244384765625 +48446 -0.546142578125 +48447 -0.53759765625 +48448 -0.50738525390625 +48449 -0.4993896484375 +48450 -0.458587646484375 +48451 -0.45074462890625 +48452 -0.393798828125 +48453 -0.38616943359375 +48454 -0.352386474609375 +48455 -0.343292236328125 +48456 -0.311859130859375 +48457 -0.3009033203125 +48458 -0.197906494140625 +48459 -0.188507080078125 +48460 -0.008758544921875 +48461 -0.004608154296875 +48462 0.2064208984375 +48463 0.203765869140625 +48464 0.407928466796875 +48465 0.398590087890625 +48466 0.5706787109375 +48467 0.55584716796875 +48468 0.664520263671875 +48469 0.646728515625 +48470 0.6573486328125 +48471 0.640625 +48472 0.566131591796875 +48473 0.5537109375 +48474 0.43023681640625 +48475 0.4234619140625 +48476 0.293487548828125 +48477 0.291656494140625 +48478 0.181793212890625 +48479 0.183074951171875 +48480 0.06329345703125 +48481 0.067535400390625 +48482 -0.076019287109375 +48483 -0.068115234375 +48484 -0.189178466796875 +48485 -0.179046630859375 +48486 -0.27142333984375 +48487 -0.260498046875 +48488 -0.341766357421875 +48489 -0.33038330078125 +48490 -0.36322021484375 +48491 -0.353363037109375 +48492 -0.326171875 +48493 -0.320159912109375 +48494 -0.275848388671875 +48495 -0.27374267578125 +48496 -0.2525634765625 +48497 -0.252410888671875 +48498 -0.242584228515625 +48499 -0.243072509765625 +48500 -0.197418212890625 +48501 -0.1995849609375 +48502 -0.115478515625 +48503 -0.120452880859375 +48504 -0.036285400390625 +48505 -0.04339599609375 +48506 0.035186767578125 +48507 0.0267333984375 +48508 0.091278076171875 +48509 0.08251953125 +48510 0.108642578125 +48511 0.101654052734375 +48512 0.125 +48513 0.119842529296875 +48514 0.156982421875 +48515 0.15277099609375 +48516 0.1773681640625 +48517 0.174407958984375 +48518 0.170013427734375 +48519 0.169281005859375 +48520 0.128814697265625 +48521 0.131500244140625 +48522 0.08123779296875 +48523 0.087127685546875 +48524 0.026519775390625 +48525 0.035430908203125 +48526 -0.06671142578125 +48527 -0.053497314453125 +48528 -0.1602783203125 +48529 -0.143280029296875 +48530 -0.21380615234375 +48531 -0.195404052734375 +48532 -0.235137939453125 +48533 -0.217315673828125 +48534 -0.200408935546875 +48535 -0.1861572265625 +48536 -0.119110107421875 +48537 -0.110870361328125 +48538 -0.0244140625 +48539 -0.02294921875 +48540 0.08636474609375 +48541 0.080352783203125 +48542 0.178924560546875 +48543 0.166473388671875 +48544 0.216522216796875 +48545 0.200592041015625 +48546 0.212493896484375 +48547 0.195404052734375 +48548 0.176300048828125 +48549 0.160003662109375 +48550 0.129791259765625 +48551 0.115234375 +48552 0.102874755859375 +48553 0.089599609375 +48554 0.075164794921875 +48555 0.063690185546875 +48556 0.0439453125 +48557 0.03485107421875 +48558 0.038665771484375 +48559 0.03106689453125 +48560 0.0765380859375 +48561 0.06866455078125 +48562 0.141082763671875 +48563 0.131866455078125 +48564 0.18621826171875 +48565 0.17669677734375 +48566 0.1883544921875 +48567 0.180572509765625 +48568 0.13836669921875 +48569 0.134674072265625 +48570 0.04095458984375 +48571 0.043426513671875 +48572 -0.080352783203125 +48573 -0.07086181640625 +48574 -0.2203369140625 +48575 -0.20330810546875 +48576 -0.3687744140625 +48577 -0.344146728515625 +48578 -0.49578857421875 +48579 -0.4649658203125 +48580 -0.557098388671875 +48581 -0.52362060546875 +48582 -0.50946044921875 +48583 -0.4788818359375 +48584 -0.376251220703125 +48585 -0.352996826171875 +48586 -0.219390869140625 +48587 -0.204864501953125 +48588 -0.064056396484375 +48589 -0.058349609375 +48590 0.0914306640625 +48591 0.08819580078125 +48592 0.236083984375 +48593 0.22442626953125 +48594 0.34320068359375 +48595 0.32501220703125 +48596 0.395538330078125 +48597 0.37359619140625 +48598 0.389801025390625 +48599 0.367095947265625 +48600 0.324737548828125 +48601 0.30438232421875 +48602 0.224609375 +48603 0.20855712890625 +48604 0.124786376953125 +48605 0.113311767578125 +48606 0.037567138671875 +48607 0.030364990234375 +48608 -0.009674072265625 +48609 -0.01422119140625 +48610 -0.01910400390625 +48611 -0.022552490234375 +48612 -0.022552490234375 +48613 -0.02496337890625 +48614 -0.00140380859375 +48615 -0.003814697265625 +48616 0.056365966796875 +48617 0.05230712890625 +48618 0.106658935546875 +48619 0.10137939453125 +48620 0.096710205078125 +48621 0.09307861328125 +48622 0.04241943359375 +48623 0.04248046875 +48624 -0.01837158203125 +48625 -0.01446533203125 +48626 -0.07623291015625 +48627 -0.068817138671875 +48628 -0.11981201171875 +48629 -0.109832763671875 +48630 -0.16009521484375 +48631 -0.14794921875 +48632 -0.20294189453125 +48633 -0.18878173828125 +48634 -0.2489013671875 +48635 -0.232818603515625 +48636 -0.305419921875 +48637 -0.287109375 +48638 -0.3623046875 +48639 -0.3419189453125 +48640 -0.39154052734375 +48641 -0.370697021484375 +48642 -0.3553466796875 +48643 -0.337493896484375 +48644 -0.249969482421875 +48645 -0.2386474609375 +48646 -0.092803955078125 +48647 -0.090850830078125 +48648 0.08917236328125 +48649 0.08050537109375 +48650 0.23541259765625 +48651 0.21917724609375 +48652 0.319061279296875 +48653 0.300048828125 +48654 0.358917236328125 +48655 0.340057373046875 +48656 0.348052978515625 +48657 0.33258056640625 +48658 0.285980224609375 +48659 0.27703857421875 +48660 0.2235107421875 +48661 0.220123291015625 +48662 0.197052001953125 +48663 0.195343017578125 +48664 0.18011474609375 +48665 0.178375244140625 +48666 0.155792236328125 +48667 0.15380859375 +48668 0.15142822265625 +48669 0.14697265625 +48670 0.157135009765625 +48671 0.14898681640625 +48672 0.13189697265625 +48673 0.122344970703125 +48674 0.100860595703125 +48675 0.09033203125 +48676 0.087127685546875 +48677 0.074432373046875 +48678 0.0548095703125 +48679 0.041839599609375 +48680 -0.00909423828125 +48681 -0.019256591796875 +48682 -0.1041259765625 +48683 -0.108306884765625 +48684 -0.22955322265625 +48685 -0.224578857421875 +48686 -0.355712890625 +48687 -0.34075927734375 +48688 -0.442108154296875 +48689 -0.41961669921875 +48690 -0.474029541015625 +48691 -0.447662353515625 +48692 -0.4649658203125 +48693 -0.437408447265625 +48694 -0.419219970703125 +48695 -0.392913818359375 +48696 -0.334381103515625 +48697 -0.3121337890625 +48698 -0.227935791015625 +48699 -0.211273193359375 +48700 -0.1234130859375 +48701 -0.112152099609375 +48702 -0.02752685546875 +48703 -0.021148681640625 +48704 0.077850341796875 +48705 0.078277587890625 +48706 0.2135009765625 +48707 0.205108642578125 +48708 0.38916015625 +48709 0.368194580078125 +48710 0.583160400390625 +48711 0.547515869140625 +48712 0.73443603515625 +48713 0.686920166015625 +48714 0.800537109375 +48715 0.747344970703125 +48716 0.7786865234375 +48717 0.72625732421875 +48718 0.665496826171875 +48719 0.62060546875 +48720 0.459930419921875 +48721 0.429595947265625 +48722 0.19940185546875 +48723 0.187713623046875 +48724 -0.050567626953125 +48725 -0.044586181640625 +48726 -0.232940673828125 +48727 -0.2147216796875 +48728 -0.3302001953125 +48729 -0.30645751953125 +48730 -0.3685302734375 +48731 -0.343780517578125 +48732 -0.379119873046875 +48733 -0.355224609375 +48734 -0.377227783203125 +48735 -0.354766845703125 +48736 -0.379974365234375 +48737 -0.358154296875 +48738 -0.391815185546875 +48739 -0.369384765625 +48740 -0.38568115234375 +48741 -0.36358642578125 +48742 -0.34228515625 +48743 -0.322998046875 +48744 -0.28326416015625 +48745 -0.267608642578125 +48746 -0.251983642578125 +48747 -0.23736572265625 +48748 -0.2664794921875 +48749 -0.248992919921875 +48750 -0.27362060546875 +48751 -0.25372314453125 +48752 -0.217010498046875 +48753 -0.199737548828125 +48754 -0.128387451171875 +48755 -0.1163330078125 +48756 -0.06817626953125 +48757 -0.059234619140625 +48758 -0.04302978515625 +48759 -0.034637451171875 +48760 -0.0242919921875 +48761 -0.0162353515625 +48762 0.020965576171875 +48763 0.02618408203125 +48764 0.12481689453125 +48765 0.122100830078125 +48766 0.258270263671875 +48767 0.244842529296875 +48768 0.379547119140625 +48769 0.355987548828125 +48770 0.480377197265625 +48771 0.44793701171875 +48772 0.528656005859375 +48773 0.491241455078125 +48774 0.5115966796875 +48775 0.474151611328125 +48776 0.456634521484375 +48777 0.422027587890625 +48778 0.4078369140625 +48779 0.37554931640625 +48780 0.384033203125 +48781 0.35211181640625 +48782 0.357025146484375 +48783 0.325836181640625 +48784 0.311859130859375 +48785 0.28302001953125 +48786 0.25079345703125 +48787 0.225799560546875 +48788 0.165191650390625 +48789 0.14630126953125 +48790 0.034912109375 +48791 0.026031494140625 +48792 -0.14251708984375 +48793 -0.137237548828125 +48794 -0.336181640625 +48795 -0.31512451171875 +48796 -0.53515625 +48797 -0.49755859375 +48798 -0.722503662109375 +48799 -0.668975830078125 +48800 -0.8372802734375 +48801 -0.7734375 +48802 -0.83319091796875 +48803 -0.768402099609375 +48804 -0.730072021484375 +48805 -0.672210693359375 +48806 -0.5828857421875 +48807 -0.535491943359375 +48808 -0.440277099609375 +48809 -0.403045654296875 +48810 -0.3243408203125 +48811 -0.2952880859375 +48812 -0.20135498046875 +48813 -0.1812744140625 +48814 -0.04437255859375 +48815 -0.036224365234375 +48816 0.1043701171875 +48817 0.100982666015625 +48818 0.202911376953125 +48819 0.191680908203125 +48820 0.265106201171875 +48821 0.2486572265625 +48822 0.339569091796875 +48823 0.316680908203125 +48824 0.444488525390625 +48825 0.412506103515625 +48826 0.545684814453125 +48827 0.504791259765625 +48828 0.617828369140625 +48829 0.570220947265625 +48830 0.652862548828125 +48831 0.6014404296875 +48832 0.66363525390625 +48833 0.6103515625 +48834 0.65618896484375 +48835 0.602569580078125 +48836 0.606658935546875 +48837 0.55615234375 +48838 0.500885009765625 +48839 0.4581298828125 +48840 0.352325439453125 +48841 0.32086181640625 +48842 0.17596435546875 +48843 0.158203125 +48844 -0.035491943359375 +48845 -0.036529541015625 +48846 -0.258941650390625 +48847 -0.2420654296875 +48848 -0.443206787109375 +48849 -0.41131591796875 +48850 -0.5760498046875 +48851 -0.5330810546875 +48852 -0.6527099609375 +48853 -0.602996826171875 +48854 -0.6422119140625 +48855 -0.59259033203125 +48856 -0.5626220703125 +48857 -0.518524169921875 +48858 -0.4583740234375 +48859 -0.4217529296875 +48860 -0.350738525390625 +48861 -0.3218994140625 +48862 -0.26055908203125 +48863 -0.2381591796875 +48864 -0.191986083984375 +48865 -0.174407958984375 +48866 -0.141693115234375 +48867 -0.12762451171875 +48868 -0.101837158203125 +48869 -0.090606689453125 +48870 -0.062469482421875 +48871 -0.054229736328125 +48872 -0.011444091796875 +48873 -0.007293701171875 +48874 0.0633544921875 +48875 0.06134033203125 +48876 0.149261474609375 +48877 0.1400146484375 +48878 0.242279052734375 +48879 0.225067138671875 +48880 0.349639892578125 +48881 0.323211669921875 +48882 0.457794189453125 +48883 0.4219970703125 +48884 0.5443115234375 +48885 0.5008544921875 +48886 0.573211669921875 +48887 0.5267333984375 +48888 0.506805419921875 +48889 0.464996337890625 +48890 0.351318359375 +48891 0.321380615234375 +48892 0.146484375 +48893 0.132476806640625 +48894 -0.055389404296875 +48895 -0.053558349609375 +48896 -0.21649169921875 +48897 -0.201629638671875 +48898 -0.335235595703125 +48899 -0.310455322265625 +48900 -0.403350830078125 +48901 -0.373291015625 +48902 -0.441680908203125 +48903 -0.408538818359375 +48904 -0.496185302734375 +48905 -0.457061767578125 +48906 -0.560546875 +48907 -0.5133056640625 +48908 -0.601043701171875 +48909 -0.547454833984375 +48910 -0.58447265625 +48911 -0.5301513671875 +48912 -0.479461669921875 +48913 -0.433746337890625 +48914 -0.2794189453125 +48915 -0.252593994140625 +48916 -0.008880615234375 +48917 -0.0086669921875 +48918 0.268890380859375 +48919 0.24163818359375 +48920 0.48297119140625 +48921 0.43511962890625 +48922 0.603912353515625 +48923 0.545440673828125 +48924 0.650665283203125 +48925 0.58929443359375 +48926 0.66424560546875 +48927 0.602996826171875 +48928 0.641693115234375 +48929 0.5838623046875 +48930 0.572723388671875 +48931 0.522705078125 +48932 0.498291015625 +48933 0.455902099609375 +48934 0.4395751953125 +48935 0.402313232421875 +48936 0.3756103515625 +48937 0.34344482421875 +48938 0.274566650390625 +48939 0.251129150390625 +48940 0.108795166015625 +48941 0.100982666015625 +48942 -0.099395751953125 +48943 -0.08697509765625 +48944 -0.318267822265625 +48945 -0.28436279296875 +48946 -0.54901123046875 +48947 -0.492095947265625 +48948 -0.773895263671875 +48949 -0.694305419921875 +48950 -0.86383056640625 +48951 -0.843841552734375 +48952 -0.870391845703125 +48953 -0.860687255859375 +48954 -0.86895751953125 +48955 -0.860748291015625 +48956 -0.86102294921875 +48957 -0.85479736328125 +48958 -0.765625 +48959 -0.732086181640625 +48960 -0.529876708984375 +48961 -0.52679443359375 +48962 -0.21441650390625 +48963 -0.247528076171875 +48964 0.137603759765625 +48965 0.067352294921875 +48966 0.475006103515625 +48967 0.372161865234375 +48968 0.76251220703125 +48969 0.63519287109375 +48970 0.867462158203125 +48971 0.83233642578125 +48972 0.870361328125 +48973 0.866424560546875 +48974 0.864776611328125 +48975 0.870361328125 +48976 0.831695556640625 +48977 0.866668701171875 +48978 0.677398681640625 +48979 0.85784912109375 +48980 0.49566650390625 +48981 0.762847900390625 +48982 0.30743408203125 +48983 0.615936279296875 +48984 0.115936279296875 +48985 0.44683837890625 +48986 -0.1109619140625 +48987 0.227508544921875 +48988 -0.381988525390625 +48989 -0.048248291015625 +48990 -0.6573486328125 +48991 -0.34271240234375 +48992 -0.857421875 +48993 -0.603179931640625 +48994 -0.870391845703125 +48995 -0.7921142578125 +48996 -0.870391845703125 +48997 -0.859893798828125 +48998 -0.86444091796875 +48999 -0.866363525390625 +49000 -0.85723876953125 +49001 -0.870391845703125 +49002 -0.790008544921875 +49003 -0.870391845703125 +49004 -0.62847900390625 +49005 -0.861358642578125 +49006 -0.3956298828125 +49007 -0.75006103515625 +49008 -0.126708984375 +49009 -0.527862548828125 +49010 0.150115966796875 +49011 -0.2755126953125 +49012 0.424041748046875 +49013 -0.003631591796875 +49014 0.670623779296875 +49015 0.26385498046875 +49016 0.854522705078125 +49017 0.492767333984375 +49018 0.866485595703125 +49019 0.667816162109375 +49020 0.86920166015625 +49021 0.775909423828125 +49022 0.8653564453125 +49023 0.83380126953125 +49024 0.857147216796875 +49025 0.854156494140625 +49026 0.766845703125 +49027 0.835235595703125 +49028 0.628509521484375 +49029 0.782379150390625 +49030 0.462127685546875 +49031 0.69036865234375 +49032 0.297210693359375 +49033 0.582794189453125 +49034 0.14862060546875 +49035 0.47119140625 +49036 -0.00537109375 +49037 0.335693359375 +49038 -0.15753173828125 +49039 0.183197021484375 +49040 -0.31304931640625 +49041 0.010589599609375 +49042 -0.48876953125 +49043 -0.194671630859375 +49044 -0.6416015625 +49045 -0.3912353515625 +49046 -0.751373291015625 +49047 -0.557525634765625 +49048 -0.84619140625 +49049 -0.71453857421875 +49050 -0.861297607421875 +49051 -0.849822998046875 +49052 -0.863250732421875 +49053 -0.863250732421875 +49054 -0.856597900390625 +49055 -0.863983154296875 +49056 -0.7498779296875 +49057 -0.85748291015625 +49058 -0.624542236328125 +49059 -0.80743408203125 +49060 -0.47808837890625 +49061 -0.699554443359375 +49062 -0.253387451171875 +49063 -0.50653076171875 +49064 0.003692626953125 +49065 -0.269195556640625 +49066 0.2257080078125 +49067 -0.048370361328125 +49068 0.427154541015625 +49069 0.16705322265625 +49070 0.643218994140625 +49071 0.405975341796875 +49072 0.855926513671875 +49073 0.660064697265625 +49074 0.870361328125 +49075 0.857086181640625 +49076 0.870361328125 +49077 0.870361328125 +49078 0.862762451171875 +49079 0.870361328125 +49080 0.79669189453125 +49081 0.862884521484375 +49082 0.595794677734375 +49083 0.789947509765625 +49084 0.362152099609375 +49085 0.60394287109375 +49086 0.1270751953125 +49087 0.400665283203125 +49088 -0.086944580078125 +49089 0.200225830078125 +49090 -0.2784423828125 +49091 0.004913330078125 +49092 -0.484832763671875 +49093 -0.21661376953125 +49094 -0.729583740234375 +49095 -0.482757568359375 +49096 -0.86688232421875 +49097 -0.750701904296875 +49098 -0.870391845703125 +49099 -0.86676025390625 +49100 -0.86859130859375 +49101 -0.870391845703125 +49102 -0.86279296875 +49103 -0.86956787109375 +49104 -0.817962646484375 +49105 -0.86187744140625 +49106 -0.6116943359375 +49107 -0.756622314453125 +49108 -0.3128662109375 +49109 -0.496978759765625 +49110 0.039398193359375 +49111 -0.177703857421875 +49112 0.422821044921875 +49113 0.1806640625 +49114 0.805145263671875 +49115 0.548126220703125 +49116 0.870361328125 +49117 0.855743408203125 +49118 0.870361328125 +49119 0.870361328125 +49120 0.860015869140625 +49121 0.870361328125 +49122 0.727935791015625 +49123 0.86090087890625 +49124 0.48114013671875 +49125 0.74871826171875 +49126 0.2059326171875 +49127 0.539642333984375 +49128 -0.06103515625 +49129 0.317413330078125 +49130 -0.29913330078125 +49131 0.100067138671875 +49132 -0.516204833984375 +49133 -0.118377685546875 +49134 -0.7252197265625 +49135 -0.34747314453125 +49136 -0.85980224609375 +49137 -0.563720703125 +49138 -0.870391845703125 +49139 -0.73797607421875 +49140 -0.870391845703125 +49141 -0.84796142578125 +49142 -0.858062744140625 +49143 -0.854736328125 +49144 -0.673004150390625 +49145 -0.768707275390625 +49146 -0.42694091796875 +49147 -0.640045166015625 +49148 -0.2100830078125 +49149 -0.520538330078125 +49150 -0.0362548828125 +49151 -0.418914794921875 +49152 0.10943603515625 +49153 -0.319366455078125 +49154 0.23516845703125 +49155 -0.213470458984375 +49156 0.373687744140625 +49157 -0.073699951171875 +49158 0.517791748046875 +49159 0.091888427734375 +49160 0.602783203125 +49161 0.224945068359375 +49162 0.635711669921875 +49163 0.32769775390625 +49164 0.655181884765625 +49165 0.42864990234375 +49166 0.65948486328125 +49167 0.52142333984375 +49168 0.651275634765625 +49169 0.603271484375 +49170 0.61846923828125 +49171 0.65899658203125 +49172 0.53753662109375 +49173 0.664031982421875 +49174 0.404144287109375 +49175 0.61090087890625 +49176 0.22186279296875 +49177 0.49969482421875 +49178 0.003997802734375 +49179 0.339874267578125 +49180 -0.22100830078125 +49181 0.15478515625 +49182 -0.42449951171875 +49183 -0.030853271484375 +49184 -0.579833984375 +49185 -0.19305419921875 +49186 -0.641876220703125 +49187 -0.29107666015625 +49188 -0.6177978515625 +49189 -0.328155517578125 +49190 -0.575531005859375 +49191 -0.35894775390625 +49192 -0.526336669921875 +49193 -0.389190673828125 +49194 -0.42645263671875 +49195 -0.3773193359375 +49196 -0.2581787109375 +49197 -0.304107666015625 +49198 -0.068695068359375 +49199 -0.2061767578125 +49200 0.09222412109375 +49201 -0.12274169921875 +49202 0.232147216796875 +49203 -0.044677734375 +49204 0.3509521484375 +49205 0.02978515625 +49206 0.410064697265625 +49207 0.06866455078125 +49208 0.372955322265625 +49209 0.040924072265625 +49210 0.2554931640625 +49211 -0.040496826171875 +49212 0.10711669921875 +49213 -0.134796142578125 +49214 -0.052886962890625 +49215 -0.227630615234375 +49216 -0.186279296875 +49217 -0.288970947265625 +49218 -0.23291015625 +49219 -0.2705078125 +49220 -0.209442138671875 +49221 -0.1898193359375 +49222 -0.174163818359375 +49223 -0.100189208984375 +49224 -0.126739501953125 +49225 -0.0045166015625 +49226 -0.048126220703125 +49227 0.110565185546875 +49228 0.0426025390625 +49229 0.22637939453125 +49230 0.10748291015625 +49231 0.308624267578125 +49232 0.1409912109375 +49233 0.351409912109375 +49234 0.19708251953125 +49235 0.400543212890625 +49236 0.273651123046875 +49237 0.454559326171875 +49238 0.31768798828125 +49239 0.46905517578125 +49240 0.341094970703125 +49241 0.455810546875 +49242 0.368011474609375 +49243 0.4376220703125 +49244 0.37249755859375 +49245 0.394744873046875 +49246 0.30072021484375 +49247 0.28375244140625 +49248 0.1517333984375 +49249 0.10662841796875 +49250 -0.01470947265625 +49251 -0.082763671875 +49252 -0.1883544921875 +49253 -0.27313232421875 +49254 -0.372711181640625 +49255 -0.465362548828125 +49256 -0.51397705078125 +49257 -0.61175537109375 +49258 -0.57177734375 +49259 -0.67657470703125 +49260 -0.53948974609375 +49261 -0.653656005859375 +49262 -0.43511962890625 +49263 -0.558441162109375 +49264 -0.2962646484375 +49265 -0.423736572265625 +49266 -0.161102294921875 +49267 -0.283355712890625 +49268 -0.0435791015625 +49269 -0.15081787109375 +49270 0.060394287109375 +49271 -0.024627685546875 +49272 0.13665771484375 +49273 0.0809326171875 +49274 0.170135498046875 +49275 0.150665283203125 +49276 0.16552734375 +49277 0.18634033203125 +49278 0.15728759765625 +49279 0.21533203125 +49280 0.150787353515625 +49281 0.24041748046875 +49282 0.12200927734375 +49283 0.239471435546875 +49284 0.080108642578125 +49285 0.21923828125 +49286 0.05126953125 +49287 0.201507568359375 +49288 0.062896728515625 +49289 0.20965576171875 +49290 0.09271240234375 +49291 0.22491455078125 +49292 0.092987060546875 +49293 0.207275390625 +49294 0.07855224609375 +49295 0.17059326171875 +49296 0.06427001953125 +49297 0.12908935546875 +49298 0.0347900390625 +49299 0.071380615234375 +49300 -0.01171875 +49301 -0.00225830078125 +49302 -0.056060791015625 +49303 -0.073486328125 +49304 -0.055511474609375 +49305 -0.10394287109375 +49306 -0.010467529296875 +49307 -0.092315673828125 +49308 0.02508544921875 +49309 -0.083465576171875 +49310 0.025665283203125 +49311 -0.098175048828125 +49312 0.017333984375 +49313 -0.113494873046875 +49314 0.00189208984375 +49315 -0.127655029296875 +49316 -0.03173828125 +49317 -0.1502685546875 +49318 -0.071502685546875 +49319 -0.171600341796875 +49320 -0.13543701171875 +49321 -0.207977294921875 +49322 -0.219970703125 +49323 -0.25750732421875 +49324 -0.300506591796875 +49325 -0.30047607421875 +49326 -0.376312255859375 +49327 -0.337799072265625 +49328 -0.416107177734375 +49329 -0.344207763671875 +49330 -0.371124267578125 +49331 -0.27947998046875 +49332 -0.242279052734375 +49333 -0.145782470703125 +49334 -0.069732666015625 +49335 0.021270751953125 +49336 0.125640869140625 +49337 0.202850341796875 +49338 0.31268310546875 +49339 0.371673583984375 +49340 0.45501708984375 +49341 0.496307373046875 +49342 0.554779052734375 +49343 0.57861328125 +49344 0.61065673828125 +49345 0.6177978515625 +49346 0.610931396484375 +49347 0.60443115234375 +49348 0.531463623046875 +49349 0.518768310546875 +49350 0.3883056640625 +49351 0.3756103515625 +49352 0.23468017578125 +49353 0.22174072265625 +49354 0.095245361328125 +49355 0.079559326171875 +49356 -0.00396728515625 +49357 -0.027435302734375 +49358 -0.04852294921875 +49359 -0.085693359375 +49360 -0.055145263671875 +49361 -0.108489990234375 +49362 -0.0758056640625 +49363 -0.139495849609375 +49364 -0.138702392578125 +49365 -0.20220947265625 +49366 -0.209197998046875 +49367 -0.2666015625 +49368 -0.289031982421875 +49369 -0.3341064453125 +49370 -0.37884521484375 +49371 -0.40545654296875 +49372 -0.456329345703125 +49373 -0.46197509765625 +49374 -0.51641845703125 +49375 -0.5 +49376 -0.519287109375 +49377 -0.48626708984375 +49378 -0.458251953125 +49379 -0.416015625 +49380 -0.384796142578125 +49381 -0.3343505859375 +49382 -0.323699951171875 +49383 -0.2635498046875 +49384 -0.269287109375 +49385 -0.19970703125 +49386 -0.1951904296875 +49387 -0.1212158203125 +49388 -0.100006103515625 +49389 -0.027587890625 +49390 -0.01055908203125 +49391 0.057586669921875 +49392 0.1033935546875 +49393 0.15985107421875 +49394 0.24908447265625 +49395 0.285247802734375 +49396 0.373199462890625 +49397 0.38824462890625 +49398 0.45806884765625 +49399 0.4539794921875 +49400 0.511474609375 +49401 0.489593505859375 +49402 0.565399169921875 +49403 0.52313232421875 +49404 0.61138916015625 +49405 0.548095703125 +49406 0.5897216796875 +49407 0.514190673828125 +49408 0.4906005859375 +49409 0.41400146484375 +49410 0.33148193359375 +49411 0.26348876953125 +49412 0.147796630859375 +49413 0.09356689453125 +49414 -0.01873779296875 +49415 -0.059600830078125 +49416 -0.140289306640625 +49417 -0.171783447265625 +49418 -0.191986083984375 +49419 -0.221435546875 +49420 -0.184295654296875 +49421 -0.21728515625 +49422 -0.161834716796875 +49423 -0.19720458984375 +49424 -0.166595458984375 +49425 -0.197021484375 +49426 -0.19390869140625 +49427 -0.213134765625 +49428 -0.22442626953125 +49429 -0.229522705078125 +49430 -0.279754638671875 +49431 -0.26513671875 +49432 -0.3389892578125 +49433 -0.30291748046875 +49434 -0.3543701171875 +49435 -0.302978515625 +49436 -0.348175048828125 +49437 -0.28497314453125 +49438 -0.32598876953125 +49439 -0.254364013671875 +49440 -0.2581787109375 +49441 -0.186553955078125 +49442 -0.139801025390625 +49443 -0.077850341796875 +49444 0.014617919921875 +49445 0.05902099609375 +49446 0.144378662109375 +49447 0.172210693359375 +49448 0.221038818359375 +49449 0.23748779296875 +49450 0.27069091796875 +49451 0.277130126953125 +49452 0.294036865234375 +49453 0.29193115234375 +49454 0.311767578125 +49455 0.299835205078125 +49456 0.339141845703125 +49457 0.314178466796875 +49458 0.360260009765625 +49459 0.321624755859375 +49460 0.360504150390625 +49461 0.310455322265625 +49462 0.308380126953125 +49463 0.2554931640625 +49464 0.18170166015625 +49465 0.13922119140625 +49466 0.0047607421875 +49467 -0.017578125 +49468 -0.17559814453125 +49469 -0.17572021484375 +49470 -0.3143310546875 +49471 -0.297607421875 +49472 -0.36785888671875 +49473 -0.346923828125 +49474 -0.36248779296875 +49475 -0.345123291015625 +49476 -0.343536376953125 +49477 -0.3294677734375 +49478 -0.3018798828125 +49479 -0.29254150390625 +49480 -0.231414794921875 +49481 -0.229522705078125 +49482 -0.117645263671875 +49483 -0.128814697265625 +49484 0.007049560546875 +49485 -0.017547607421875 +49486 0.087982177734375 +49487 0.0587158203125 +49488 0.13946533203125 +49489 0.111236572265625 +49490 0.17425537109375 +49491 0.149932861328125 +49492 0.188201904296875 +49493 0.17083740234375 +49494 0.171234130859375 +49495 0.165130615234375 +49496 0.118438720703125 +49497 0.128326416015625 +49498 0.05706787109375 +49499 0.08258056640625 +49500 -0.010711669921875 +49501 0.029449462890625 +49502 -0.0914306640625 +49503 -0.0364990234375 +49504 -0.162322998046875 +49505 -0.096466064453125 +49506 -0.194549560546875 +49507 -0.1265869140625 +49508 -0.1492919921875 +49509 -0.094635009765625 +49510 -0.02166748046875 +49511 0.003753662109375 +49512 0.124053955078125 +49513 0.1160888671875 +49514 0.211151123046875 +49515 0.179595947265625 +49516 0.240447998046875 +49517 0.195404052734375 +49518 0.242218017578125 +49519 0.18890380859375 +49520 0.2257080078125 +49521 0.168182373046875 +49522 0.194366455078125 +49523 0.13641357421875 +49524 0.115509033203125 +49525 0.06695556640625 +49526 0.0128173828125 +49527 -0.02044677734375 +49528 -0.053802490234375 +49529 -0.076324462890625 +49530 -0.110626220703125 +49531 -0.122344970703125 +49532 -0.199493408203125 +49533 -0.193115234375 +49534 -0.29437255859375 +49535 -0.267333984375 +49536 -0.33221435546875 +49537 -0.293304443359375 +49538 -0.27972412109375 +49539 -0.243927001953125 +49540 -0.185333251953125 +49541 -0.15948486328125 +49542 -0.128204345703125 +49543 -0.105560302734375 +49544 -0.115692138671875 +49545 -0.08856201171875 +49546 -0.116455078125 +49547 -0.08306884765625 +49548 -0.105926513671875 +49549 -0.069122314453125 +49550 -0.053955078125 +49551 -0.02215576171875 +49552 0.048797607421875 +49553 0.0653076171875 +49554 0.157318115234375 +49555 0.15606689453125 +49556 0.212005615234375 +49557 0.201019287109375 +49558 0.218475341796875 +49559 0.204803466796875 +49560 0.23724365234375 +49561 0.2174072265625 +49562 0.30535888671875 +49563 0.269561767578125 +49564 0.38128662109375 +49565 0.3272705078125 +49566 0.404449462890625 +49567 0.340911865234375 +49568 0.3944091796875 +49569 0.326904296875 +49570 0.3885498046875 +49571 0.31640625 +49572 0.362640380859375 +49573 0.289794921875 +49574 0.27362060546875 +49575 0.211822509765625 +49576 0.11712646484375 +49577 0.079132080078125 +49578 -0.054901123046875 +49579 -0.065277099609375 +49580 -0.19085693359375 +49581 -0.178741455078125 +49582 -0.28570556640625 +49583 -0.257110595703125 +49584 -0.339263916015625 +49585 -0.30029296875 +49586 -0.3775634765625 +49587 -0.32977294921875 +49588 -0.445709228515625 +49589 -0.38287353515625 +49590 -0.535064697265625 +49591 -0.452667236328125 +49592 -0.629058837890625 +49593 -0.5257568359375 +49594 -0.697601318359375 +49595 -0.577606201171875 +49596 -0.70391845703125 +49597 -0.578155517578125 +49598 -0.6424560546875 +49599 -0.523101806640625 +49600 -0.491241455078125 +49601 -0.394561767578125 +49602 -0.265716552734375 +49603 -0.2054443359375 +49604 -0.023712158203125 +49605 -0.003570556640625 +49606 0.201751708984375 +49607 0.1837158203125 +49608 0.375823974609375 +49609 0.327667236328125 +49610 0.485076904296875 +49611 0.417205810546875 +49612 0.56884765625 +49613 0.48480224609375 +49614 0.634765625 +49615 0.536865234375 +49616 0.63763427734375 +49617 0.53631591796875 +49618 0.5660400390625 +49619 0.473876953125 +49620 0.4720458984375 +49621 0.392669677734375 +49622 0.40692138671875 +49623 0.33514404296875 +49624 0.3778076171875 +49625 0.307403564453125 +49626 0.376953125 +49627 0.30328369140625 +49628 0.371978759765625 +49629 0.2962646484375 +49630 0.313140869140625 +49631 0.245513916015625 +49632 0.184417724609375 +49633 0.137939453125 +49634 0.011199951171875 +49635 -0.00543212890625 +49636 -0.171051025390625 +49637 -0.155426025390625 +49638 -0.33740234375 +49639 -0.291534423828125 +49640 -0.47198486328125 +49641 -0.4007568359375 +49642 -0.560394287109375 +49643 -0.4713134765625 +49644 -0.58056640625 +49645 -0.485198974609375 +49646 -0.54754638671875 +49647 -0.454986572265625 +49648 -0.508575439453125 +49649 -0.41973876953125 +49650 -0.459503173828125 +49651 -0.376220703125 +49652 -0.394378662109375 +49653 -0.3197021484375 +49654 -0.35260009765625 +49655 -0.282806396484375 +49656 -0.31170654296875 +49657 -0.24713134765625 +49658 -0.197418212890625 +49659 -0.15155029296875 +49660 -0.007965087890625 +49661 0.00531005859375 +49662 0.207489013671875 +49663 0.18292236328125 +49664 0.409210205078125 +49665 0.348480224609375 +49666 0.57208251953125 +49667 0.48077392578125 +49668 0.66595458984375 +49669 0.5555419921875 +49670 0.65875244140625 +49671 0.54779052734375 +49672 0.56744384765625 +49673 0.47149658203125 +49674 0.431396484375 +49675 0.358367919921875 +49676 0.29443359375 +49677 0.24365234375 +49678 0.182464599609375 +49679 0.148345947265625 +49680 0.06365966796875 +49681 0.0477294921875 +49682 -0.075958251953125 +49683 -0.068878173828125 +49684 -0.189422607421875 +49685 -0.163970947265625 +49686 -0.271942138671875 +49687 -0.233489990234375 +49688 -0.342529296875 +49689 -0.29229736328125 +49690 -0.364166259765625 +49691 -0.311004638671875 +49692 -0.327239990234375 +49693 -0.281951904296875 +49694 -0.2769775390625 +49695 -0.240997314453125 +49696 -0.253692626953125 +49697 -0.22021484375 +49698 -0.24365234375 +49699 -0.208892822265625 +49700 -0.1983642578125 +49701 -0.168853759765625 +49702 -0.116241455078125 +49703 -0.09912109375 +49704 -0.036834716796875 +49705 -0.031280517578125 +49706 0.034881591796875 +49707 0.030426025390625 +49708 0.09124755859375 +49709 0.079681396484375 +49710 0.10888671875 +49711 0.097747802734375 +49712 0.125518798828125 +49713 0.114227294921875 +49714 0.15771484375 +49715 0.142120361328125 +49716 0.17828369140625 +49717 0.159759521484375 +49718 0.17108154296875 +49719 0.154327392578125 +49720 0.129974365234375 +49721 0.12103271484375 +49722 0.082427978515625 +49723 0.0816650390625 +49724 0.027679443359375 +49725 0.0357666015625 +49726 -0.065643310546875 +49727 -0.041351318359375 +49728 -0.15936279296875 +49729 -0.1192626953125 +49730 -0.21307373046875 +49731 -0.165771484375 +49732 -0.234649658203125 +49733 -0.1868896484375 +49734 -0.2001953125 +49735 -0.1634521484375 +49736 -0.119171142578125 +49737 -0.10272216796875 +49738 -0.024749755859375 +49739 -0.03082275390625 +49740 0.085784912109375 +49741 0.054534912109375 +49742 0.178131103515625 +49743 0.12628173828125 +49744 0.215576171875 +49745 0.1553955078125 +49746 0.211456298828125 +49747 0.152435302734375 +49748 0.17523193359375 +49749 0.124847412109375 +49750 0.128753662109375 +49751 0.089874267578125 +49752 0.1019287109375 +49753 0.07110595703125 +49754 0.0743408203125 +49755 0.052215576171875 +49756 0.04327392578125 +49757 0.030853271484375 +49758 0.038177490234375 +49759 0.0301513671875 +49760 0.076263427734375 +49761 0.063568115234375 +49762 0.14105224609375 +49763 0.11785888671875 +49764 0.186431884765625 +49765 0.1563720703125 +49766 0.188812255859375 +49767 0.1602783203125 +49768 0.1390380859375 +49769 0.122222900390625 +49770 0.041778564453125 +49771 0.045867919921875 +49772 -0.079437255859375 +49773 -0.0501708984375 +49774 -0.219390869140625 +49775 -0.1617431640625 +49776 -0.367828369140625 +49777 -0.280670166015625 +49778 -0.494873046875 +49779 -0.3831787109375 +49780 -0.556243896484375 +49781 -0.43408203125 +49782 -0.508697509765625 +49783 -0.399017333984375 +49784 -0.3756103515625 +49785 -0.29632568359375 +49786 -0.218902587890625 +49787 -0.1749267578125 +49788 -0.063751220703125 +49789 -0.0545654296875 +49790 0.091552734375 +49791 0.066192626953125 +49792 0.23602294921875 +49793 0.17877197265625 +49794 0.342987060546875 +49795 0.26214599609375 +49796 0.39520263671875 +49797 0.302703857421875 +49798 0.389373779296875 +49799 0.297882080078125 +49800 0.324249267578125 +49801 0.246673583984375 +49802 0.224090576171875 +49803 0.168243408203125 +49804 0.124267578125 +49805 0.090545654296875 +49806 0.037078857421875 +49807 0.023223876953125 +49808 -0.010101318359375 +49809 -0.012115478515625 +49810 -0.019439697265625 +49811 -0.017333984375 +49812 -0.022796630859375 +49813 -0.017730712890625 +49814 -0.001556396484375 +49815 0.001251220703125 +49816 0.056304931640625 +49817 0.049041748046875 +49818 0.106719970703125 +49819 0.090606689453125 +49820 0.096893310546875 +49821 0.0841064453125 +49822 0.042694091796875 +49823 0.042022705078125 +49824 -0.018035888671875 +49825 -0.005706787109375 +49826 -0.07586669921875 +49827 -0.051605224609375 +49828 -0.11944580078125 +49829 -0.086669921875 +49830 -0.15972900390625 +49831 -0.11956787109375 +49832 -0.202606201171875 +49833 -0.154876708984375 +49834 -0.24859619140625 +49835 -0.192901611328125 +49836 -0.30517578125 +49837 -0.239471435546875 +49838 -0.36212158203125 +49839 -0.286376953125 +49840 -0.39141845703125 +49841 -0.311370849609375 +49842 -0.35528564453125 +49843 -0.284393310546875 +49844 -0.249969482421875 +49845 -0.202392578125 +49846 -0.092864990234375 +49847 -0.0791015625 +49848 0.08905029296875 +49849 0.064178466796875 +49850 0.2352294921875 +49851 0.179534912109375 +49852 0.318817138671875 +49853 0.2457275390625 +49854 0.358642578125 +49855 0.277618408203125 +49856 0.347747802734375 +49857 0.269683837890625 +49858 0.28564453125 +49859 0.221466064453125 +49860 0.223175048828125 +49861 0.173187255859375 +49862 0.196746826171875 +49863 0.15362548828125 +49864 0.179840087890625 +49865 0.141693115234375 +49866 0.155548095703125 +49867 0.123931884765625 +49868 0.151214599609375 +49869 0.121917724609375 +49870 0.156951904296875 +49871 0.12774658203125 +49872 0.13177490234375 +49873 0.10882568359375 +49874 0.100799560546875 +49875 0.08502197265625 +49876 0.087127685546875 +49877 0.0745849609375 +49878 0.05487060546875 +49879 0.049102783203125 +49880 -0.009002685546875 +49881 -0.001708984375 +49882 -0.10400390625 +49883 -0.077423095703125 +49884 -0.229400634765625 +49885 -0.177459716796875 +49886 -0.35552978515625 +49887 -0.278289794921875 +49888 -0.441925048828125 +49889 -0.347747802734375 +49890 -0.473846435546875 +49891 -0.374176025390625 +49892 -0.464813232421875 +49893 -0.3681640625 +49894 -0.419097900390625 +49895 -0.333038330078125 +49896 -0.334320068359375 +49897 -0.266876220703125 +49898 -0.227935791015625 +49899 -0.183441162109375 +49900 -0.12347412109375 +49901 -0.101348876953125 +49902 -0.02764892578125 +49903 -0.02587890625 +49904 0.077667236328125 +49905 0.057342529296875 +49906 0.2132568359375 +49907 0.164764404296875 +49908 0.38885498046875 +49909 0.3040771484375 +49910 0.582794189453125 +49911 0.4581298828125 +49912 0.734039306640625 +49913 0.578521728515625 +49914 0.800140380859375 +49915 0.631622314453125 +49916 0.7783203125 +49917 0.61517333984375 +49918 0.6651611328125 +49919 0.52642822265625 +49920 0.45965576171875 +49921 0.36505126953125 +49922 0.199188232421875 +49923 0.161163330078125 +49924 -0.050689697265625 +49925 -0.03436279296875 +49926 -0.23297119140625 +49927 -0.178070068359375 +49928 -0.33013916015625 +49929 -0.25653076171875 +49930 -0.368408203125 +49931 -0.289520263671875 +49932 -0.378936767578125 +49933 -0.3006591796875 +49934 -0.376983642578125 +49935 -0.30145263671875 +49936 -0.37969970703125 +49937 -0.304901123046875 +49938 -0.391510009765625 +49939 -0.314361572265625 +49940 -0.385345458984375 +49941 -0.30926513671875 +49942 -0.3419189453125 +49943 -0.274993896484375 +49944 -0.28289794921875 +49945 -0.2281494140625 +49946 -0.251617431640625 +49947 -0.2017822265625 +49948 -0.266143798828125 +49949 -0.209747314453125 +49950 -0.273345947265625 +49951 -0.21185302734375 +49952 -0.216796875 +49953 -0.1654052734375 +49954 -0.128265380859375 +49955 -0.094696044921875 +49956 -0.068145751953125 +49957 -0.045867919921875 +49958 -0.0430908203125 +49959 -0.024078369140625 +49960 -0.024444580078125 +49961 -0.007720947265625 +49962 0.020721435546875 +49963 0.02813720703125 +49964 0.124481201171875 +49965 0.1077880859375 +49966 0.25787353515625 +49967 0.209197998046875 +49968 0.379119873046875 +49969 0.3006591796875 +49970 0.47991943359375 +49971 0.37591552734375 +49972 0.5281982421875 +49973 0.41070556640625 +49974 0.511138916015625 +49975 0.3953857421875 +49976 0.456207275390625 +49977 0.350982666015625 +49978 0.407470703125 +49979 0.3111572265625 +49980 0.383758544921875 +49981 0.290374755859375 +49982 0.35687255859375 +49983 0.267333984375 +49984 0.31182861328125 +49985 0.23077392578125 +49986 0.250885009765625 +49987 0.1824951171875 +49988 0.1654052734375 +49989 0.116058349609375 +49990 0.035247802734375 +49991 0.0162353515625 +49992 -0.142059326171875 +49993 -0.11883544921875 +49994 -0.33563232421875 +49995 -0.265655517578125 +49996 -0.5345458984375 +49997 -0.415924072265625 +49998 -0.72186279296875 +49999 -0.556854248046875 +50000 -0.836669921875 +50001 -0.64227294921875 +50002 -0.8326416015625 +50003 -0.6370849609375 +50004 -0.7296142578125 +50005 -0.5565185546875 +50006 -0.582550048828125 +50007 -0.44244384765625 +50008 -0.440093994140625 +50009 -0.331939697265625 +50010 -0.324310302734375 +50011 -0.241912841796875 +50012 -0.20147705078125 +50013 -0.146820068359375 +50014 -0.044647216796875 +50015 -0.0262451171875 +50016 0.103973388671875 +50017 0.087646484375 +50018 0.202392578125 +50019 0.16290283203125 +50020 0.264495849609375 +50021 0.21002197265625 +50022 0.338897705078125 +50023 0.2659912109375 +50024 0.443817138671875 +50025 0.3447265625 +50026 0.545074462890625 +50027 0.4202880859375 +50028 0.6173095703125 +50029 0.4735107421875 +50030 0.6524658203125 +50031 0.49835205078125 +50032 0.66339111328125 +50033 0.50469970703125 +50034 0.6561279296875 +50035 0.49725341796875 +50036 0.606781005859375 +50037 0.457977294921875 +50038 0.501190185546875 +50039 0.376190185546875 +50040 0.352783203125 +50041 0.262115478515625 +50042 0.176544189453125 +50043 0.12725830078125 +50044 -0.034820556640625 +50045 -0.03387451171875 +50046 -0.258209228515625 +50047 -0.203704833984375 +50048 -0.44244384765625 +50049 -0.3433837890625 +50050 -0.5753173828125 +50051 -0.443603515625 +50052 -0.65203857421875 +50053 -0.50079345703125 +50054 -0.641632080078125 +50055 -0.49151611328125 +50056 -0.562164306640625 +50057 -0.429595947265625 +50058 -0.458038330078125 +50059 -0.348846435546875 +50060 -0.350555419921875 +50061 -0.265533447265625 +50062 -0.260528564453125 +50063 -0.195556640625 +50064 -0.192108154296875 +50065 -0.142181396484375 +50066 -0.141937255859375 +50067 -0.1029052734375 +50068 -0.1021728515625 +50069 -0.07183837890625 +50070 -0.062896728515625 +50071 -0.04150390625 +50072 -0.011932373046875 +50073 -0.00262451171875 +50074 0.062835693359375 +50075 0.053985595703125 +50076 0.148712158203125 +50077 0.11871337890625 +50078 0.241729736328125 +50079 0.188568115234375 +50080 0.34912109375 +50081 0.26910400390625 +50082 0.457305908203125 +50083 0.35009765625 +50084 0.54388427734375 +50085 0.414581298828125 +50086 0.5728759765625 +50087 0.435272216796875 +50088 0.506591796875 +50089 0.38360595703125 +50090 0.351226806640625 +50091 0.264373779296875 +50092 0.146514892578125 +50093 0.107818603515625 +50094 -0.05523681640625 +50095 -0.0462646484375 +50096 -0.21624755859375 +50097 -0.16912841796875 +50098 -0.334930419921875 +50099 -0.259521484375 +50100 -0.402984619140625 +50101 -0.3111572265625 +50102 -0.4412841796875 +50103 -0.33990478515625 +50104 -0.49578857421875 +50105 -0.380706787109375 +50106 -0.5601806640625 +50107 -0.4288330078125 +50108 -0.600738525390625 +50109 -0.45867919921875 +50110 -0.584228515625 +50111 -0.445037841796875 +50112 -0.47930908203125 +50113 -0.364166259765625 +50114 -0.27935791015625 +50115 -0.21112060546875 +50116 -0.0089111328125 +50117 -0.004608154296875 +50118 0.268798828125 +50119 0.207244873046875 +50120 0.482818603515625 +50121 0.37054443359375 +50122 0.60369873046875 +50123 0.462860107421875 +50124 0.650421142578125 +50125 0.498565673828125 +50126 0.66400146484375 +50127 0.508819580078125 +50128 0.6414794921875 +50129 0.49139404296875 +50130 0.572540283203125 +50131 0.4384765625 +50132 0.498138427734375 +50133 0.381256103515625 +50134 0.439453125 +50135 0.335845947265625 +50136 0.375518798828125 +50137 0.286376953125 +50138 0.274505615234375 +50139 0.20867919921875 +50140 0.1087646484375 +50141 0.081817626953125 +50142 -0.099395751953125 +50143 -0.07720947265625 +50144 -0.3182373046875 +50145 -0.244232177734375 +50146 -0.5489501953125 +50147 -0.42010498046875 +50148 -0.7738037109375 +50149 -0.591339111328125 +50150 -0.86383056640625 +50151 -0.717681884765625 +50152 -0.870391845703125 +50153 -0.77386474609375 +50154 -0.86895751953125 +50155 -0.773345947265625 +50156 -0.861053466796875 +50157 -0.726104736328125 +50158 -0.765869140625 +50159 -0.619049072265625 +50160 -0.5301513671875 +50161 -0.443634033203125 +50162 -0.214691162109375 +50163 -0.205291748046875 +50164 0.137359619140625 +50165 0.063201904296875 +50166 0.474822998046875 +50167 0.322784423828125 +50168 0.76239013671875 +50169 0.546417236328125 +50170 0.867462158203125 +50171 0.71356201171875 +50172 0.870361328125 +50173 0.824493408203125 +50174 0.86480712890625 +50175 0.856231689453125 +50176 0.831817626953125 +50177 0.85455322265625 +50178 0.677581787109375 +50179 0.797454833984375 +50180 0.495880126953125 +50181 0.701385498046875 +50182 0.30767822265625 +50183 0.5809326171875 +50184 0.116180419921875 +50185 0.438140869140625 +50186 -0.110748291015625 +50187 0.2503662109375 +50188 -0.381805419921875 +50189 0.0130615234375 +50190 -0.6572265625 +50191 -0.24212646484375 +50192 -0.857421875 +50193 -0.47113037109375 +50194 -0.870391845703125 +50195 -0.64227294921875 +50196 -0.870391845703125 +50197 -0.75006103515625 +50198 -0.86444091796875 +50199 -0.813812255859375 +50200 -0.85723876953125 +50201 -0.85504150390625 +50202 -0.790008544921875 +50203 -0.8565673828125 +50204 -0.62847900390625 +50205 -0.816131591796875 +50206 -0.3956298828125 +50207 -0.685791015625 +50208 -0.126708984375 +50209 -0.50634765625 +50210 0.150115966796875 +50211 -0.298095703125 +50212 0.424041748046875 +50213 -0.069915771484375 +50214 0.670623779296875 +50215 0.158172607421875 +50216 0.854522705078125 +50217 0.3575439453125 +50218 0.866485595703125 +50219 0.514923095703125 +50220 0.86920166015625 +50221 0.6187744140625 +50222 0.8653564453125 +50223 0.6820068359375 +50224 0.857147216796875 +50225 0.714111328125 +50226 0.766845703125 +50227 0.7127685546875 +50228 0.628509521484375 +50229 0.681671142578125 +50230 0.462127685546875 +50231 0.61590576171875 +50232 0.297210693359375 +50233 0.534393310546875 +50234 0.14862060546875 +50235 0.4462890625 +50236 -0.00537109375 +50237 0.335235595703125 +50238 -0.15753173828125 +50239 0.20697021484375 +50240 -0.31304931640625 +50241 0.0592041015625 +50242 -0.48876953125 +50243 -0.117919921875 +50244 -0.6416015625 +50245 -0.2899169921875 +50246 -0.751373291015625 +50247 -0.438446044921875 +50248 -0.84619140625 +50249 -0.580047607421875 +50250 -0.861297607421875 +50251 -0.703765869140625 +50252 -0.863250732421875 +50253 -0.7852783203125 +50254 -0.856597900390625 +50255 -0.801513671875 +50256 -0.7498779296875 +50257 -0.76129150390625 +50258 -0.624542236328125 +50259 -0.706787109375 +50260 -0.47808837890625 +50261 -0.62213134765625 +50262 -0.253387451171875 +50263 -0.46490478515625 +50264 0.003692626953125 +50265 -0.26861572265625 +50266 0.2257080078125 +50267 -0.083282470703125 +50268 0.427154541015625 +50269 0.099884033203125 +50270 0.643218994140625 +50271 0.30413818359375 +50272 0.855926513671875 +50273 0.52215576171875 +50274 0.870361328125 +50275 0.71148681640625 +50276 0.870361328125 +50277 0.83575439453125 +50278 0.862762451171875 +50279 0.85943603515625 +50280 0.79669189453125 +50281 0.859649658203125 +50282 0.595794677734375 +50283 0.83465576171875 +50284 0.362152099609375 +50285 0.71942138671875 +50286 0.1270751953125 +50287 0.57672119140625 +50288 -0.086944580078125 +50289 0.422149658203125 +50290 -0.2784423828125 +50291 0.257415771484375 +50292 -0.484832763671875 +50293 0.0574951171875 +50294 -0.729583740234375 +50295 -0.191314697265625 +50296 -0.86688232421875 +50297 -0.45184326171875 +50298 -0.870391845703125 +50299 -0.67767333984375 +50300 -0.86859130859375 +50301 -0.85565185546875 +50302 -0.86279296875 +50303 -0.870391845703125 +50304 -0.817962646484375 +50305 -0.870391845703125 +50306 -0.6116943359375 +50307 -0.860260009765625 +50308 -0.3128662109375 +50309 -0.7203369140625 +50310 0.039398193359375 +50311 -0.46673583984375 +50312 0.422821044921875 +50313 -0.163330078125 +50314 0.805145263671875 +50315 0.16424560546875 +50316 0.870361328125 +50317 0.4659423828125 +50318 0.870361328125 +50319 0.700714111328125 +50320 0.860015869140625 +50321 0.855224609375 +50322 0.727935791015625 +50323 0.8642578125 +50324 0.48114013671875 +50325 0.8646240234375 +50326 0.2059326171875 +50327 0.858642578125 +50328 -0.06103515625 +50329 0.79901123046875 +50330 -0.29913330078125 +50331 0.677520751953125 +50332 -0.516204833984375 +50333 0.521026611328125 +50334 -0.7252197265625 +50335 0.32147216796875 +50336 -0.85980224609375 +50337 0.099761962890625 +50338 -0.870391845703125 +50339 -0.11688232421875 +50340 -0.870391845703125 +50341 -0.305328369140625 +50342 -0.858062744140625 +50343 -0.42919921875 +50344 -0.673004150390625 +50345 -0.4852294921875 +50346 -0.42694091796875 +50347 -0.512176513671875 +50348 -0.2100830078125 +50349 -0.54351806640625 +50350 -0.0362548828125 +50351 -0.5794677734375 +50352 0.10943603515625 +50353 -0.60107421875 +50354 0.23516845703125 +50355 -0.596405029296875 +50356 0.373687744140625 +50357 -0.538055419921875 +50358 0.517791748046875 +50359 -0.430267333984375 +50360 0.602783203125 +50361 -0.321563720703125 +50362 0.635711669921875 +50363 -0.21063232421875 +50364 0.655181884765625 +50365 -0.07525634765625 +50366 0.65948486328125 +50367 0.07568359375 +50368 0.651275634765625 +50369 0.235321044921875 +50370 0.61846923828125 +50371 0.385284423828125 +50372 0.53753662109375 +50373 0.498748779296875 +50374 0.404144287109375 +50375 0.563232421875 +50376 0.22186279296875 +50377 0.57281494140625 +50378 0.003997802734375 +50379 0.529998779296875 +50380 -0.22100830078125 +50381 0.449920654296875 +50382 -0.42449951171875 +50383 0.349761962890625 +50384 -0.579833984375 +50385 0.247344970703125 +50386 -0.641876220703125 +50387 0.176055908203125 +50388 -0.6177978515625 +50389 0.13311767578125 +50390 -0.575531005859375 +50391 0.0733642578125 +50392 -0.526336669921875 +50393 -0.005584716796875 +50394 -0.42645263671875 +50395 -0.06494140625 +50396 -0.2581787109375 +50397 -0.084075927734375 +50398 -0.068695068359375 +50399 -0.08935546875 +50400 0.09222412109375 +50401 -0.109100341796875 +50402 0.232147216796875 +50403 -0.13055419921875 +50404 0.3509521484375 +50405 -0.147491455078125 +50406 0.410064697265625 +50407 -0.182891845703125 +50408 0.372955322265625 +50409 -0.25982666015625 +50410 0.2554931640625 +50411 -0.364837646484375 +50412 0.10711669921875 +50413 -0.461761474609375 +50414 -0.052886962890625 +50415 -0.53802490234375 +50416 -0.186279296875 +50417 -0.56878662109375 +50418 -0.23291015625 +50419 -0.514678955078125 +50420 -0.209442138671875 +50421 -0.39324951171875 +50422 -0.174163818359375 +50423 -0.25311279296875 +50424 -0.126739501953125 +50425 -0.10052490234375 +50426 -0.048126220703125 +50427 0.07177734375 +50428 0.0426025390625 +50429 0.2437744140625 +50430 0.10748291015625 +50431 0.38232421875 +50432 0.1409912109375 +50433 0.478363037109375 +50434 0.19708251953125 +50435 0.567047119140625 +50436 0.273651123046875 +50437 0.645599365234375 +50438 0.31768798828125 +50439 0.6761474609375 +50440 0.341094970703125 +50441 0.667694091796875 +50442 0.368011474609375 +50443 0.639129638671875 +50444 0.37249755859375 +50445 0.575469970703125 +50446 0.30072021484375 +50447 0.44317626953125 +50448 0.1517333984375 +50449 0.2464599609375 +50450 -0.01470947265625 +50451 0.032470703125 +50452 -0.1883544921875 +50453 -0.18609619140625 +50454 -0.372711181640625 +50455 -0.40643310546875 +50456 -0.51397705078125 +50457 -0.586090087890625 +50458 -0.57177734375 +50459 -0.692657470703125 +50460 -0.53948974609375 +50461 -0.71832275390625 +50462 -0.43511962890625 +50463 -0.673614501953125 +50464 -0.2962646484375 +50465 -0.583831787109375 +50466 -0.161102294921875 +50467 -0.475921630859375 +50468 -0.0435791015625 +50469 -0.360931396484375 +50470 0.060394287109375 +50471 -0.238372802734375 +50472 0.13665771484375 +50473 -0.121307373046875 +50474 0.170135498046875 +50475 -0.024169921875 +50476 0.16552734375 +50477 0.052032470703125 +50478 0.15728759765625 +50479 0.12689208984375 +50480 0.150787353515625 +50481 0.19976806640625 +50482 0.12200927734375 +50483 0.24969482421875 +50484 0.080108642578125 +50485 0.27947998046875 +50486 0.05126953125 +50487 0.304534912109375 +50488 0.062896728515625 +50489 0.34197998046875 +50490 0.09271240234375 +50491 0.37506103515625 +50492 0.092987060546875 +50493 0.37017822265625 +50494 0.07855224609375 +50495 0.3385009765625 +50496 0.06427001953125 +50497 0.292083740234375 +50498 0.0347900390625 +50499 0.22259521484375 +50500 -0.01171875 +50501 0.131744384765625 +50502 -0.056060791015625 +50503 0.03643798828125 +50504 -0.055511474609375 +50505 -0.029693603515625 +50506 -0.010467529296875 +50507 -0.063232421875 +50508 0.02508544921875 +50509 -0.09844970703125 +50510 0.025665283203125 +50511 -0.150054931640625 +50512 0.017333984375 +50513 -0.197235107421875 +50514 0.00189208984375 +50515 -0.23675537109375 +50516 -0.03173828125 +50517 -0.27520751953125 +50518 -0.071502685546875 +50519 -0.30377197265625 +50520 -0.13543701171875 +50521 -0.33538818359375 +50522 -0.219970703125 +50523 -0.368682861328125 +50524 -0.300506591796875 +50525 -0.38818359375 +50526 -0.376312255859375 +50527 -0.395721435546875 +50528 -0.416107177734375 +50529 -0.37213134765625 +50530 -0.371124267578125 +50531 -0.2862548828125 +50532 -0.242279052734375 +50533 -0.14178466796875 +50534 -0.069732666015625 +50535 0.030181884765625 +50536 0.125640869140625 +50537 0.212310791015625 +50538 0.31268310546875 +50539 0.380523681640625 +50540 0.45501708984375 +50541 0.507568359375 +50542 0.554779052734375 +50543 0.593719482421875 +50544 0.61065673828125 +50545 0.63751220703125 +50546 0.610931396484375 +50547 0.630828857421875 +50548 0.531463623046875 +50549 0.557464599609375 +50550 0.3883056640625 +50551 0.429931640625 +50552 0.23468017578125 +50553 0.2872314453125 +50554 0.095245361328125 +50555 0.148773193359375 +50556 -0.00396728515625 +50557 0.03515625 +50558 -0.04852294921875 +50559 -0.041015625 +50560 -0.055145263671875 +50561 -0.08892822265625 +50562 -0.0758056640625 +50563 -0.1427001953125 +50564 -0.138702392578125 +50565 -0.22003173828125 +50566 -0.209197998046875 +50567 -0.295013427734375 +50568 -0.289031982421875 +50569 -0.367706298828125 +50570 -0.37884521484375 +50571 -0.4378662109375 +50572 -0.456329345703125 +50573 -0.48974609375 +50574 -0.51641845703125 +50575 -0.520233154296875 +50576 -0.519287109375 +50577 -0.5023193359375 +50578 -0.458251953125 +50579 -0.432647705078125 +50580 -0.384796142578125 +50581 -0.348968505859375 +50582 -0.323699951171875 +50583 -0.2705078125 +50584 -0.269287109375 +50585 -0.195343017578125 +50586 -0.1951904296875 +50587 -0.107086181640625 +50588 -0.100006103515625 +50589 -0.0067138671875 +50590 -0.01055908203125 +50591 0.085205078125 +50592 0.1033935546875 +50593 0.188385009765625 +50594 0.24908447265625 +50595 0.306793212890625 +50596 0.373199462890625 +50597 0.40240478515625 +50598 0.45806884765625 +50599 0.46258544921875 +50600 0.511474609375 +50601 0.49298095703125 +50602 0.565399169921875 +50603 0.516571044921875 +50604 0.61138916015625 +50605 0.528411865234375 +50606 0.5897216796875 +50607 0.488006591796875 +50608 0.4906005859375 +50609 0.389984130859375 +50610 0.33148193359375 +50611 0.248291015625 +50612 0.147796630859375 +50613 0.08935546875 +50614 -0.01873779296875 +50615 -0.055938720703125 +50616 -0.140289306640625 +50617 -0.16656494140625 +50618 -0.191986083984375 +50619 -0.22381591796875 +50620 -0.184295654296875 +50621 -0.2340087890625 +50622 -0.161834716796875 +50623 -0.227691650390625 +50624 -0.166595458984375 +50625 -0.233917236328125 +50626 -0.19390869140625 +50627 -0.249420166015625 +50628 -0.22442626953125 +50629 -0.26104736328125 +50630 -0.279754638671875 +50631 -0.28466796875 +50632 -0.3389892578125 +50633 -0.306610107421875 +50634 -0.3543701171875 +50635 -0.294647216796875 +50636 -0.348175048828125 +50637 -0.26568603515625 +50638 -0.32598876953125 +50639 -0.22503662109375 +50640 -0.2581787109375 +50641 -0.153350830078125 +50642 -0.139801025390625 +50643 -0.048431396484375 +50644 0.014617919921875 +50645 0.07843017578125 +50646 0.144378662109375 +50647 0.183746337890625 +50648 0.221038818359375 +50649 0.246978759765625 +50650 0.27069091796875 +50651 0.2860107421875 +50652 0.294036865234375 +50653 0.301239013671875 +50654 0.311767578125 +50655 0.307373046875 +50656 0.339141845703125 +50657 0.3155517578125 +50658 0.360260009765625 +50659 0.315338134765625 +50660 0.360504150390625 +50661 0.297454833984375 +50662 0.308380126953125 +50663 0.241058349609375 +50664 0.18170166015625 +50665 0.131866455078125 +50666 0.0047607421875 +50667 -0.011962890625 +50668 -0.17559814453125 +50669 -0.15673828125 +50670 -0.3143310546875 +50671 -0.270111083984375 +50672 -0.36785888671875 +50673 -0.320892333984375 +50674 -0.36248779296875 +50675 -0.32672119140625 +50676 -0.343536376953125 +50677 -0.318756103515625 +50678 -0.3018798828125 +50679 -0.290496826171875 +50680 -0.231414794921875 +50681 -0.237762451171875 +50682 -0.117645263671875 +50683 -0.150787353515625 +50684 0.007049560546875 +50685 -0.05267333984375 +50686 0.087982177734375 +50687 0.017822265625 +50688 0.13946533203125 +50689 0.069793701171875 +50690 0.17425537109375 +50691 0.1112060546875 +50692 0.188201904296875 +50693 0.13812255859375 +50694 0.171234130859375 +50695 0.143035888671875 +50696 0.118438720703125 +50697 0.121978759765625 +50698 0.05706787109375 +50699 0.092437744140625 +50700 -0.010711669921875 +50701 0.055328369140625 +50702 -0.0914306640625 +50703 0.006011962890625 +50704 -0.162322998046875 +50705 -0.04046630859375 +50706 -0.194549560546875 +50707 -0.06488037109375 +50708 -0.1492919921875 +50709 -0.04119873046875 +50710 -0.02166748046875 +50711 0.03424072265625 +50712 0.124053955078125 +50713 0.119384765625 +50714 0.211151123046875 +50715 0.1639404296875 +50716 0.240447998046875 +50717 0.16925048828125 +50718 0.242218017578125 +50719 0.15618896484375 +50720 0.2257080078125 +50721 0.131683349609375 +50722 0.194366455078125 +50723 0.098724365234375 +50724 0.115509033203125 +50725 0.03619384765625 +50726 0.0128173828125 +50727 -0.03961181640625 +50728 -0.053802490234375 +50729 -0.088623046875 +50730 -0.110626220703125 +50731 -0.128082275390625 +50732 -0.199493408203125 +50733 -0.185791015625 +50734 -0.29437255859375 +50735 -0.24462890625 +50736 -0.33221435546875 +50737 -0.263031005859375 +50738 -0.27972412109375 +50739 -0.219329833984375 +50740 -0.185333251953125 +50741 -0.146240234375 +50742 -0.128204345703125 +50743 -0.096923828125 +50744 -0.115692138671875 +50745 -0.076904296875 +50746 -0.116455078125 +50747 -0.066009521484375 +50748 -0.105926513671875 +50749 -0.04852294921875 +50750 -0.053955078125 +50751 -0.0050048828125 +50752 0.048797607421875 +50753 0.070281982421875 +50754 0.157318115234375 +50755 0.14715576171875 +50756 0.212005615234375 +50757 0.185791015625 +50758 0.218475341796875 +50759 0.18988037109375 +50760 0.23724365234375 +50761 0.19970703125 +50762 0.30535888671875 +50763 0.2401123046875 +50764 0.38128662109375 +50765 0.2838134765625 +50766 0.404449462890625 +50767 0.290985107421875 +50768 0.3944091796875 +50769 0.275115966796875 +50770 0.3885498046875 +50771 0.261566162109375 +50772 0.362640380859375 +50773 0.23480224609375 +50774 0.27362060546875 +50775 0.166717529296875 +50776 0.11712646484375 +50777 0.054901123046875 +50778 -0.054901123046875 +50779 -0.06573486328125 +50780 -0.19085693359375 +50781 -0.160614013671875 +50782 -0.28570556640625 +50783 -0.2261962890625 +50784 -0.339263916015625 +50785 -0.262298583984375 +50786 -0.3775634765625 +50787 -0.286224365234375 +50788 -0.445709228515625 +50789 -0.32806396484375 +50790 -0.535064697265625 +50791 -0.38232421875 +50792 -0.629058837890625 +50793 -0.438323974609375 +50794 -0.697601318359375 +50795 -0.476470947265625 +50796 -0.70391845703125 +50797 -0.4727783203125 +50798 -0.6424560546875 +50799 -0.423980712890625 +50800 -0.491241455078125 +50801 -0.315948486328125 +50802 -0.265716552734375 +50803 -0.159332275390625 +50804 -0.023712158203125 +50805 0.007080078125 +50806 0.201751708984375 +50807 0.16107177734375 +50808 0.375823974609375 +50809 0.27935791015625 +50810 0.485076904296875 +50811 0.352874755859375 +50812 0.56884765625 +50813 0.40777587890625 +50814 0.634765625 +50815 0.449188232421875 +50816 0.63763427734375 +50817 0.447296142578125 +50818 0.5660400390625 +50819 0.394775390625 +50820 0.4720458984375 +50821 0.326507568359375 +50822 0.40692138671875 +50823 0.27685546875 +50824 0.3778076171875 +50825 0.25091552734375 +50826 0.376953125 +50827 0.243896484375 +50828 0.371978759765625 +50829 0.23468017578125 +50830 0.313140869140625 +50831 0.1905517578125 +50832 0.184417724609375 +50833 0.101104736328125 +50834 0.011199951171875 +50835 -0.016571044921875 +50836 -0.171051025390625 +50837 -0.138824462890625 +50838 -0.33740234375 +50839 -0.249114990234375 +50840 -0.47198486328125 +50841 -0.336944580078125 +50842 -0.560394287109375 +50843 -0.39288330078125 +50844 -0.58056640625 +50845 -0.4024658203125 +50846 -0.54754638671875 +50847 -0.375885009765625 +50848 -0.508575439453125 +50849 -0.344818115234375 +50850 -0.459503173828125 +50851 -0.306793212890625 +50852 -0.394378662109375 +50853 -0.2581787109375 +50854 -0.35260009765625 +50855 -0.22540283203125 +50856 -0.31170654296875 +50857 -0.19378662109375 +50858 -0.197418212890625 +50859 -0.114288330078125 +50860 -0.007965087890625 +50861 0.01409912109375 +50862 0.207489013671875 +50863 0.158599853515625 +50864 0.409210205078125 +50865 0.292755126953125 +50866 0.57208251953125 +50867 0.399932861328125 +50868 0.66595458984375 +50869 0.460205078125 +50870 0.65875244140625 +50871 0.45245361328125 +50872 0.56744384765625 +50873 0.388092041015625 +50874 0.431396484375 +50875 0.29351806640625 +50876 0.29443359375 +50877 0.198089599609375 +50878 0.182464599609375 +50879 0.1192626953125 +50880 0.06365966796875 +50881 0.0361328125 +50882 -0.075958251953125 +50883 -0.060333251953125 +50884 -0.189422607421875 +50885 -0.1387939453125 +50886 -0.271942138671875 +50887 -0.195892333984375 +50888 -0.342529296875 +50889 -0.244140625 +50890 -0.364166259765625 +50891 -0.258941650390625 +50892 -0.327239990234375 +50893 -0.233917236328125 +50894 -0.2769775390625 +50895 -0.19915771484375 +50896 -0.253692626953125 +50897 -0.1815185546875 +50898 -0.24365234375 +50899 -0.1719970703125 +50900 -0.1983642578125 +50901 -0.13861083984375 +50902 -0.116241455078125 +50903 -0.080474853515625 +50904 -0.036834716796875 +50905 -0.0240478515625 +50906 0.034881591796875 +50907 0.027130126953125 +50908 0.09124755859375 +50909 0.067779541015625 +50910 0.10888671875 +50911 0.082244873046875 +50912 0.125518798828125 +50913 0.095428466796875 +50914 0.15771484375 +50915 0.118255615234375 +50916 0.17828369140625 +50917 0.132568359375 +50918 0.17108154296875 +50919 0.127655029296875 +50920 0.129974365234375 +50921 0.099456787109375 +50922 0.082427978515625 +50923 0.0662841796875 +50924 0.027679443359375 +50925 0.027740478515625 +50926 -0.065643310546875 +50927 -0.036834716796875 +50928 -0.15936279296875 +50929 -0.1019287109375 +50930 -0.21307373046875 +50931 -0.140594482421875 +50932 -0.234649658203125 +50933 -0.157867431640625 +50934 -0.2001953125 +50935 -0.1376953125 +50936 -0.119171142578125 +50937 -0.086273193359375 +50938 -0.024749755859375 +50939 -0.025482177734375 +50940 0.085784912109375 +50941 0.046539306640625 +50942 0.178131103515625 +50943 0.107086181640625 +50944 0.215576171875 +50945 0.13201904296875 +50946 0.211456298828125 +50947 0.13031005859375 +50948 0.17523193359375 +50949 0.108306884765625 +50950 0.128753662109375 +50951 0.079833984375 +50952 0.1019287109375 +50953 0.063812255859375 +50954 0.0743408203125 +50955 0.047332763671875 +50956 0.04327392578125 +50957 0.02862548828125 +50958 0.038177490234375 +50959 0.0262451171875 +50960 0.076263427734375 +50961 0.051025390625 +50962 0.14105224609375 +50963 0.092498779296875 +50964 0.186431884765625 +50965 0.121551513671875 +50966 0.188812255859375 +50967 0.12322998046875 +50968 0.1390380859375 +50969 0.09173583984375 +50970 0.041778564453125 +50971 0.030029296875 +50972 -0.079437255859375 +50973 -0.046966552734375 +50974 -0.219390869140625 +50975 -0.135986328125 +50976 -0.367828369140625 +50977 -0.23046875 +50978 -0.494873046875 +50979 -0.3115234375 +50980 -0.556243896484375 +50981 -0.351104736328125 +50982 -0.508697509765625 +50983 -0.32183837890625 +50984 -0.3756103515625 +50985 -0.238433837890625 +50986 -0.218902587890625 +50987 -0.1400146484375 +50988 -0.063751220703125 +50989 -0.042449951171875 +50990 0.091552734375 +50991 0.0552978515625 +50992 0.23602294921875 +50993 0.146331787109375 +50994 0.342987060546875 +50995 0.21380615234375 +50996 0.39520263671875 +50997 0.246856689453125 +50998 0.389373779296875 +50999 0.243377685546875 +51000 0.324249267578125 +51001 0.20257568359375 +51002 0.224090576171875 +51003 0.139739990234375 +51004 0.124267578125 +51005 0.07720947265625 +51006 0.037078857421875 +51007 0.022705078125 +51008 -0.010101318359375 +51009 -0.0064697265625 +51010 -0.019439697265625 +51011 -0.01171875 +51012 -0.022796630859375 +51013 -0.01324462890625 +51014 -0.001556396484375 +51015 0.00067138671875 +51016 0.056304931640625 +51017 0.037628173828125 +51018 0.106719970703125 +51019 0.06976318359375 +51020 0.096893310546875 +51021 0.063690185546875 +51022 0.042694091796875 +51023 0.0294189453125 +51024 -0.018035888671875 +51025 -0.009124755859375 +51026 -0.07586669921875 +51027 -0.04595947265625 +51028 -0.11944580078125 +51029 -0.0738525390625 +51030 -0.15972900390625 +51031 -0.0997314453125 +51032 -0.202606201171875 +51033 -0.127288818359375 +51034 -0.24859619140625 +51035 -0.156829833984375 +51036 -0.30517578125 +51037 -0.193023681640625 +51038 -0.36212158203125 +51039 -0.229400634765625 +51040 -0.39141845703125 +51041 -0.248291015625 +51042 -0.35528564453125 +51043 -0.225738525390625 +51044 -0.249969482421875 +51045 -0.15936279296875 +51046 -0.092864990234375 +51047 -0.0601806640625 +51048 0.08905029296875 +51049 0.054779052734375 +51050 0.2352294921875 +51051 0.147216796875 +51052 0.318817138671875 +51053 0.200164794921875 +51054 0.358642578125 +51055 0.22552490234375 +51056 0.347747802734375 +51057 0.2188720703125 +51058 0.28564453125 +51059 0.179901123046875 +51060 0.223175048828125 +51061 0.1407470703125 +51062 0.196746826171875 +51063 0.124359130859375 +51064 0.179840087890625 +51065 0.113983154296875 +51066 0.155548095703125 +51067 0.098907470703125 +51068 0.151214599609375 +51069 0.096405029296875 +51070 0.156951904296875 +51071 0.100250244140625 +51072 0.13177490234375 +51073 0.084503173828125 +51074 0.100799560546875 +51075 0.065032958984375 +51076 0.087127685546875 +51077 0.056396484375 +51078 0.05487060546875 +51079 0.03594970703125 +51080 -0.009002685546875 +51081 -0.004547119140625 +51082 -0.10400390625 +51083 -0.06475830078125 +51084 -0.229400634765625 +51085 -0.14422607421875 +51086 -0.35552978515625 +51087 -0.22418212890625 +51088 -0.441925048828125 +51089 -0.279022216796875 +51090 -0.473846435546875 +51091 -0.299407958984375 +51092 -0.464813232421875 +51093 -0.29388427734375 +51094 -0.419097900390625 +51095 -0.26513671875 +51096 -0.334320068359375 +51097 -0.211669921875 +51098 -0.227935791015625 +51099 -0.144500732421875 +51100 -0.12347412109375 +51101 -0.0784912109375 +51102 -0.02764892578125 +51103 -0.01788330078125 +51104 0.077667236328125 +51105 0.04876708984375 +51106 0.2132568359375 +51107 0.134552001953125 +51108 0.38885498046875 +51109 0.245635986328125 +51110 0.582794189453125 +51111 0.3682861328125 +51112 0.734039306640625 +51113 0.463958740234375 +51114 0.800140380859375 +51115 0.505828857421875 +51116 0.7783203125 +51117 0.492095947265625 +51118 0.6651611328125 +51119 0.420623779296875 +51120 0.45965576171875 +51121 0.290771484375 +51122 0.199188232421875 +51123 0.12615966796875 +51124 -0.050689697265625 +51125 -0.031768798828125 +51126 -0.23297119140625 +51127 -0.147003173828125 +51128 -0.33013916015625 +51129 -0.208465576171875 +51130 -0.368408203125 +51131 -0.232666015625 +51132 -0.378936767578125 +51133 -0.23931884765625 +51134 -0.376983642578125 +51135 -0.23809814453125 +51136 -0.37969970703125 +51137 -0.239837646484375 +51138 -0.391510009765625 +51139 -0.247314453125 +51140 -0.385345458984375 +51141 -0.243408203125 +51142 -0.3419189453125 +51143 -0.2159423828125 +51144 -0.28289794921875 +51145 -0.178619384765625 +51146 -0.251617431640625 +51147 -0.158843994140625 +51148 -0.266143798828125 +51149 -0.167999267578125 +51150 -0.273345947265625 +51151 -0.17254638671875 +51152 -0.216796875 +51153 -0.136810302734375 +51154 -0.128265380859375 +51155 -0.080841064453125 +51156 -0.068145751953125 +51157 -0.0428466796875 +51158 -0.0430908203125 +51159 -0.027008056640625 +51160 -0.024444580078125 +51161 -0.015228271484375 +51162 0.020721435546875 +51163 0.013336181640625 +51164 0.124481201171875 +51165 0.07891845703125 +51166 0.25787353515625 +51167 0.1632080078125 +51168 0.379119873046875 +51169 0.23980712890625 +51170 0.47991943359375 +51171 0.303466796875 +51172 0.5281982421875 +51173 0.33392333984375 +51174 0.511138916015625 +51175 0.323089599609375 +51176 0.456207275390625 +51177 0.288299560546875 +51178 0.407470703125 +51179 0.257415771484375 +51180 0.383758544921875 +51181 0.242340087890625 +51182 0.35687255859375 +51183 0.225250244140625 +51184 0.31182861328125 +51185 0.196685791015625 +51186 0.250885009765625 +51187 0.158111572265625 +51188 0.1654052734375 +51189 0.104034423828125 +51190 0.035247802734375 +51191 0.021759033203125 +51192 -0.142059326171875 +51193 -0.09027099609375 +51194 -0.33563232421875 +51195 -0.2125244140625 +51196 -0.5345458984375 +51197 -0.338104248046875 +51198 -0.72186279296875 +51199 -0.456329345703125 +51200 -0.836669921875 +51201 -0.5291748046875 +51202 -0.8326416015625 +51203 -0.528045654296875 +51204 -0.7296142578125 +51205 -0.46484375 +51206 -0.582550048828125 +51207 -0.373016357421875 +51208 -0.440093994140625 +51209 -0.28228759765625 +51210 -0.324310302734375 +51211 -0.206451416015625 +51212 -0.20147705078125 +51213 -0.12579345703125 +51214 -0.044647216796875 +51215 -0.02459716796875 +51216 0.103973388671875 +51217 0.0712890625 +51218 0.202392578125 +51219 0.136260986328125 +51220 0.264495849609375 +51221 0.1783447265625 +51222 0.338897705078125 +51223 0.22650146484375 +51224 0.443817138671875 +51225 0.291473388671875 +51226 0.545074462890625 +51227 0.35272216796875 +51228 0.6173095703125 +51229 0.39508056640625 +51230 0.6524658203125 +51231 0.413787841796875 +51232 0.66339111328125 +51233 0.416748046875 +51234 0.6561279296875 +51235 0.4078369140625 +51236 0.606781005859375 +51237 0.373016357421875 +51238 0.501190185546875 +51239 0.304107666015625 +51240 0.352783203125 +51241 0.209442138671875 +51242 0.176544189453125 +51243 0.098358154296875 +51244 -0.034820556640625 +51245 -0.033233642578125 +51246 -0.258209228515625 +51247 -0.171173095703125 +51248 -0.44244384765625 +51249 -0.28460693359375 +51250 -0.5753173828125 +51251 -0.366058349609375 +51252 -0.65203857421875 +51253 -0.41259765625 +51254 -0.641632080078125 +51255 -0.405670166015625 +51256 -0.562164306640625 +51257 -0.356170654296875 +51258 -0.458038330078125 +51259 -0.2908935546875 +51260 -0.350555419921875 +51261 -0.2227783203125 +51262 -0.260528564453125 +51263 -0.164520263671875 +51264 -0.192108154296875 +51265 -0.118865966796875 +51266 -0.141937255859375 +51267 -0.0841064453125 +51268 -0.1021728515625 +51269 -0.055755615234375 +51270 -0.062896728515625 +51271 -0.028106689453125 +51272 -0.011932373046875 +51273 0.005889892578125 +51274 0.062835693359375 +51275 0.0533447265625 +51276 0.148712158203125 +51277 0.106536865234375 +51278 0.241729736328125 +51279 0.16302490234375 +51280 0.34912109375 +51281 0.22711181640625 +51282 0.457305908203125 +51283 0.290740966796875 +51284 0.54388427734375 +51285 0.340545654296875 +51286 0.5728759765625 +51287 0.3551025390625 +51288 0.506591796875 +51289 0.311981201171875 +51290 0.351226806640625 +51291 0.215057373046875 +51292 0.146514892578125 +51293 0.088409423828125 +51294 -0.05523681640625 +51295 -0.036376953125 +51296 -0.21624755859375 +51297 -0.136444091796875 +51298 -0.334930419921875 +51299 -0.21063232421875 +51300 -0.402984619140625 +51301 -0.2537841796875 +51302 -0.4412841796875 +51303 -0.2783203125 +51304 -0.49578857421875 +51305 -0.311767578125 +51306 -0.5601806640625 +51307 -0.350341796875 +51308 -0.600738525390625 +51309 -0.37384033203125 +51310 -0.584228515625 +51311 -0.36236572265625 +51312 -0.47930908203125 +51313 -0.2972412109375 +51314 -0.27935791015625 +51315 -0.17462158203125 +51316 -0.0089111328125 +51317 -0.0093994140625 +51318 0.268798828125 +51319 0.160308837890625 +51320 0.482818603515625 +51321 0.291748046875 +51322 0.60369873046875 +51323 0.367095947265625 +51324 0.650421142578125 +51325 0.3975830078125 +51326 0.66400146484375 +51327 0.40771484375 +51328 0.6414794921875 +51329 0.3956298828125 +51330 0.572540283203125 +51331 0.355072021484375 +51332 0.498138427734375 +51333 0.31060791015625 +51334 0.439453125 +51335 0.274932861328125 +51336 0.375518798828125 +51337 0.235504150390625 +51338 0.274505615234375 +51339 0.173309326171875 +51340 0.1087646484375 +51341 0.071868896484375 +51342 -0.099395751953125 +51343 -0.055328369140625 +51344 -0.3182373046875 +51345 -0.1890869140625 +51346 -0.5489501953125 +51347 -0.329986572265625 +51348 -0.7738037109375 +51349 -0.467254638671875 +51350 -0.86383056640625 +51351 -0.569000244140625 +51352 -0.870391845703125 +51353 -0.615142822265625 +51354 -0.86895751953125 +51355 -0.616241455078125 +51356 -0.861053466796875 +51357 -0.580078125 +51358 -0.765869140625 +51359 -0.49627685546875 +51360 -0.5301513671875 +51361 -0.358062744140625 +51362 -0.214691162109375 +51363 -0.16973876953125 +51364 0.137359619140625 +51365 0.042816162109375 +51366 0.474822998046875 +51367 0.24871826171875 +51368 0.76239013671875 +51369 0.426544189453125 +51370 0.867462158203125 +51371 0.55999755859375 +51372 0.870361328125 +51373 0.64923095703125 +51374 0.86480712890625 +51375 0.68719482421875 +51376 0.831817626953125 +51377 0.677001953125 +51378 0.677581787109375 +51379 0.6331787109375 +51380 0.495880126953125 +51381 0.559112548828125 +51382 0.30767822265625 +51383 0.46588134765625 +51384 0.116180419921875 +51385 0.354766845703125 +51386 -0.110748291015625 +51387 0.206756591796875 +51388 -0.381805419921875 +51389 0.0177001953125 +51390 -0.6572265625 +51391 -0.1866455078125 +51392 -0.857421875 +51393 -0.37030029296875 +51394 -0.870391845703125 +51395 -0.507415771484375 +51396 -0.870391845703125 +51397 -0.5936279296875 +51398 -0.86444091796875 +51399 -0.644989013671875 +51400 -0.85723876953125 +51401 -0.682769775390625 +51402 -0.790008544921875 +51403 -0.69586181640625 +51404 -0.62847900390625 +51405 -0.651641845703125 +51406 -0.3956298828125 +51407 -0.548126220703125 +51408 -0.126708984375 +51409 -0.40496826171875 +51410 0.150115966796875 +51411 -0.23858642578125 +51412 0.424041748046875 +51413 -0.055999755859375 +51414 0.670623779296875 +51415 0.126556396484375 +51416 0.854522705078125 +51417 0.28582763671875 +51418 0.866485595703125 +51419 0.411163330078125 +51420 0.86920166015625 +51421 0.49322509765625 +51422 0.8653564453125 +51423 0.542816162109375 +51424 0.857147216796875 +51425 0.56787109375 +51426 0.766845703125 +51427 0.566558837890625 +51428 0.628509521484375 +51429 0.541839599609375 +51430 0.462127685546875 +51431 0.4896240234375 +51432 0.297210693359375 +51433 0.425323486328125 +51434 0.14862060546875 +51435 0.3563232421875 +51436 -0.00537109375 +51437 0.2689208984375 +51438 -0.15753173828125 +51439 0.167633056640625 +51440 -0.31304931640625 +51441 0.05029296875 +51442 -0.48876953125 +51443 -0.0914306640625 +51444 -0.6416015625 +51445 -0.229339599609375 +51446 -0.751373291015625 +51447 -0.34857177734375 +51448 -0.84619140625 +51449 -0.462860107421875 +51450 -0.861297607421875 +51451 -0.56329345703125 +51452 -0.863250732421875 +51453 -0.629913330078125 +51454 -0.856597900390625 +51455 -0.6436767578125 +51456 -0.7498779296875 +51457 -0.611236572265625 +51458 -0.624542236328125 +51459 -0.566436767578125 +51460 -0.47808837890625 +51461 -0.497528076171875 +51462 -0.253387451171875 +51463 -0.371551513671875 +51464 0.003692626953125 +51465 -0.21478271484375 +51466 0.2257080078125 +51467 -0.066436767578125 +51468 0.427154541015625 +51469 0.080169677734375 +51470 0.643218994140625 +51471 0.24298095703125 +51472 0.855926513671875 +51473 0.416107177734375 +51474 0.870361328125 +51475 0.5662841796875 +51476 0.870361328125 +51477 0.665008544921875 +51478 0.862762451171875 +51479 0.716156005859375 +51480 0.79669189453125 +51481 0.717926025390625 +51482 0.595794677734375 +51483 0.6649169921875 +51484 0.362152099609375 +51485 0.573760986328125 +51486 0.1270751953125 +51487 0.4605712890625 +51488 -0.086944580078125 +51489 0.33758544921875 +51490 -0.2784423828125 +51491 0.206329345703125 +51492 -0.484832763671875 +51493 0.047393798828125 +51494 -0.729583740234375 +51495 -0.14971923828125 +51496 -0.86688232421875 +51497 -0.3558349609375 +51498 -0.870391845703125 +51499 -0.53460693359375 +51500 -0.86859130859375 +51501 -0.682861328125 +51502 -0.86279296875 +51503 -0.799102783203125 +51504 -0.817962646484375 +51505 -0.85540771484375 +51506 -0.6116943359375 +51507 -0.847564697265625 +51508 -0.3128662109375 +51509 -0.749664306640625 +51510 0.039398193359375 +51511 -0.588134765625 +51512 0.422821044921875 +51513 -0.374481201171875 +51514 0.805145263671875 +51515 -0.1278076171875 +51516 0.870361328125 +51517 0.11285400390625 +51518 0.870361328125 +51519 0.314788818359375 +51520 0.860015869140625 +51521 0.470916748046875 +51522 0.727935791015625 +51523 0.576446533203125 +51524 0.48114013671875 +51525 0.627716064453125 +51526 0.2059326171875 +51527 0.63800048828125 +51528 -0.06103515625 +51529 0.619781494140625 +51530 -0.29913330078125 +51531 0.57843017578125 +51532 -0.516204833984375 +51533 0.505523681640625 +51534 -0.7252197265625 +51535 0.3922119140625 +51536 -0.85980224609375 +51537 0.252685546875 +51538 -0.870391845703125 +51539 0.106597900390625 +51540 -0.870391845703125 +51541 -0.028900146484375 +51542 -0.858062744140625 +51543 -0.125762939453125 +51544 -0.673004150390625 +51545 -0.18109130859375 +51546 -0.42694091796875 +51547 -0.22412109375 +51548 -0.2100830078125 +51549 -0.279510498046875 +51550 -0.0362548828125 +51551 -0.345458984375 +51552 0.10943603515625 +51553 -0.4049072265625 +51554 0.23516845703125 +51555 -0.446136474609375 +51556 0.373687744140625 +51557 -0.44525146484375 +51558 0.517791748046875 +51559 -0.403106689453125 +51560 0.602783203125 +51561 -0.3553466796875 +51562 0.635711669921875 +51563 -0.299072265625 +51564 0.655181884765625 +51565 -0.21551513671875 +51566 0.65948486328125 +51567 -0.110595703125 +51568 0.651275634765625 +51569 0.010711669921875 +51570 0.61846923828125 +51571 0.134002685546875 +51572 0.53753662109375 +51573 0.237701416015625 +51574 0.404144287109375 +51575 0.31097412109375 +51576 0.22186279296875 +51577 0.347747802734375 +51578 0.003997802734375 +51579 0.34820556640625 +51580 -0.22100830078125 +51581 0.322174072265625 +51582 -0.42449951171875 +51583 0.281036376953125 +51584 -0.579833984375 +51585 0.23663330078125 +51586 -0.641876220703125 +51587 0.213104248046875 +51588 -0.6177978515625 +51589 0.206634521484375 +51590 -0.575531005859375 +51591 0.1806640625 +51592 -0.526336669921875 +51593 0.13238525390625 +51594 -0.42645263671875 +51595 0.091552734375 +51596 -0.2581787109375 +51597 0.07415771484375 +51598 -0.068695068359375 +51599 0.05999755859375 +51600 0.09222412109375 +51601 0.0277099609375 +51602 0.232147216796875 +51603 -0.011566162109375 +51604 0.3509521484375 +51605 -0.05157470703125 +51606 0.410064697265625 +51607 -0.108673095703125 +51608 0.372955322265625 +51609 -0.19915771484375 +51610 0.2554931640625 +51611 -0.31085205078125 +51612 0.10711669921875 +51613 -0.4139404296875 +51614 -0.052886962890625 +51615 -0.4971923828125 +51616 -0.186279296875 +51617 -0.540069580078125 +51618 -0.23291015625 +51619 -0.51092529296875 +51620 -0.209442138671875 +51621 -0.42291259765625 +51622 -0.174163818359375 +51623 -0.313751220703125 +51624 -0.126739501953125 +51625 -0.18853759765625 +51626 -0.048126220703125 +51627 -0.042083740234375 +51628 0.0426025390625 +51629 0.109130859375 +51630 0.10748291015625 +51631 0.2381591796875 +51632 0.1409912109375 +51633 0.337066650390625 +51634 0.19708251953125 +51635 0.4324951171875 +51636 0.273651123046875 +51637 0.520263671875 +51638 0.31768798828125 +51639 0.568389892578125 +51640 0.341094970703125 +51641 0.5830078125 +51642 0.368011474609375 +51643 0.578369140625 +51644 0.37249755859375 +51645 0.541412353515625 +51646 0.30072021484375 +51647 0.444305419921875 +51648 0.1517333984375 +51649 0.2900390625 +51650 -0.01470947265625 +51651 0.11669921875 +51652 -0.1883544921875 +51653 -0.06524658203125 +51654 -0.372711181640625 +51655 -0.253143310546875 +51656 -0.51397705078125 +51657 -0.411895751953125 +51658 -0.57177734375 +51659 -0.514404296875 +51660 -0.53948974609375 +51661 -0.553375244140625 +51662 -0.43511962890625 +51663 -0.536285400390625 +51664 -0.2962646484375 +51665 -0.482635498046875 +51666 -0.161102294921875 +51667 -0.4132080078125 +51668 -0.0435791015625 +51669 -0.336029052734375 +51670 0.060394287109375 +51671 -0.249847412109375 +51672 0.13665771484375 +51673 -0.1646728515625 +51674 0.170135498046875 +51675 -0.091766357421875 +51676 0.16552734375 +51677 -0.03173828125 +51678 0.15728759765625 +51679 0.03125 +51680 0.150787353515625 +51681 0.096435546875 +51682 0.12200927734375 +51683 0.146392822265625 +51684 0.080108642578125 +51685 0.18280029296875 +51686 0.05126953125 +51687 0.2174072265625 +51688 0.062896728515625 +51689 0.263275146484375 +51690 0.09271240234375 +51691 0.305938720703125 +51692 0.092987060546875 +51693 0.317291259765625 +51694 0.07855224609375 +51695 0.3055419921875 +51696 0.06427001953125 +51697 0.279754638671875 +51698 0.0347900390625 +51699 0.232574462890625 +51700 -0.01171875 +51701 0.16497802734375 +51702 -0.056060791015625 +51703 0.0904541015625 +51704 -0.055511474609375 +51705 0.036163330078125 +51706 -0.010467529296875 +51707 0.005035400390625 +51708 0.02508544921875 +51709 -0.0303955078125 +51710 0.025665283203125 +51711 -0.081634521484375 +51712 0.017333984375 +51713 -0.131378173828125 +51714 0.00189208984375 +51715 -0.176239013671875 +51716 -0.03173828125 +51717 -0.220550537109375 +51718 -0.071502685546875 +51719 -0.25653076171875 +51720 -0.13543701171875 +51721 -0.293548583984375 +51722 -0.219970703125 +51723 -0.329833984375 +51724 -0.300506591796875 +51725 -0.35272216796875 +51726 -0.376312255859375 +51727 -0.36328125 +51728 -0.416107177734375 +51729 -0.346282958984375 +51730 -0.371124267578125 +51731 -0.27728271484375 +51732 -0.242279052734375 +51733 -0.15936279296875 +51734 -0.069732666015625 +51735 -0.01727294921875 +51736 0.125640869140625 +51737 0.134918212890625 +51738 0.31268310546875 +51739 0.277679443359375 +51740 0.45501708984375 +51741 0.388946533203125 +51742 0.554779052734375 +51743 0.46832275390625 +51744 0.61065673828125 +51745 0.51397705078125 +51746 0.610931396484375 +51747 0.5189208984375 +51748 0.531463623046875 +51749 0.46990966796875 +51750 0.3883056640625 +51751 0.3763427734375 +51752 0.23468017578125 +51753 0.268585205078125 +51754 0.095245361328125 +51755 0.161712646484375 +51756 -0.00396728515625 +51757 0.07183837890625 +51758 -0.04852294921875 +51759 0.009002685546875 +51760 -0.055145263671875 +51761 -0.0338134765625 +51762 -0.0758056640625 +51763 -0.083038330078125 +51764 -0.138702392578125 +51765 -0.152130126953125 +51766 -0.209197998046875 +51767 -0.22027587890625 +51768 -0.289031982421875 +51769 -0.286956787109375 +51770 -0.37884521484375 +51771 -0.351470947265625 +51772 -0.456329345703125 +51773 -0.40093994140625 +51774 -0.51641845703125 +51775 -0.432464599609375 +51776 -0.519287109375 +51777 -0.424468994140625 +51778 -0.458251953125 +51779 -0.3740234375 +51780 -0.384796142578125 +51781 -0.310577392578125 +51782 -0.323699951171875 +51783 -0.249176025390625 +51784 -0.269287109375 +51785 -0.188323974609375 +51786 -0.1951904296875 +51787 -0.115325927734375 +51788 -0.100006103515625 +51789 -0.03118896484375 +51790 -0.01055908203125 +51791 0.047576904296875 +51792 0.1033935546875 +51793 0.136016845703125 +51794 0.24908447265625 +51795 0.236846923828125 +51796 0.373199462890625 +51797 0.31976318359375 +51798 0.45806884765625 +51799 0.37445068359375 +51800 0.511474609375 +51801 0.4049072265625 +51802 0.565399169921875 +51803 0.42889404296875 +51804 0.61138916015625 +51805 0.4422607421875 +51806 0.5897216796875 +51807 0.412994384765625 +51808 0.4906005859375 +51809 0.3367919921875 +51810 0.33148193359375 +51811 0.224578857421875 +51812 0.147796630859375 +51813 0.097259521484375 +51814 -0.01873779296875 +51815 -0.020751953125 +51816 -0.140289306640625 +51817 -0.1126708984375 +51818 -0.191986083984375 +51819 -0.163482666015625 +51820 -0.184295654296875 +51821 -0.177825927734375 +51822 -0.161834716796875 +51823 -0.1793212890625 +51824 -0.166595458984375 +51825 -0.190460205078125 +51826 -0.19390869140625 +51827 -0.2083740234375 +51828 -0.22442626953125 +51829 -0.222381591796875 +51830 -0.279754638671875 +51831 -0.244720458984375 +51832 -0.3389892578125 +51833 -0.26446533203125 +51834 -0.3543701171875 +51835 -0.256195068359375 +51836 -0.348175048828125 +51837 -0.233184814453125 +51838 -0.32598876953125 +51839 -0.19964599609375 +51840 -0.2581787109375 +51841 -0.140533447265625 +51842 -0.139801025390625 +51843 -0.0543212890625 +51844 0.014617919921875 +51845 0.04986572265625 +51846 0.144378662109375 +51847 0.13763427734375 +51848 0.221038818359375 +51849 0.19256591796875 +51850 0.27069091796875 +51851 0.2283935546875 +51852 0.294036865234375 +51853 0.245208740234375 +51854 0.311767578125 +51855 0.2542724609375 +51856 0.339141845703125 +51857 0.26409912109375 +51858 0.360260009765625 +51859 0.26617431640625 +51860 0.360504150390625 +51861 0.253173828125 +51862 0.308380126953125 +51863 0.209075927734375 +51864 0.18170166015625 +51865 0.123016357421875 +51866 0.0047607421875 +51867 0.009124755859375 +51868 -0.17559814453125 +51869 -0.106414794921875 +51870 -0.3143310546875 +51871 -0.19842529296875 +51872 -0.36785888671875 +51873 -0.242584228515625 +51874 -0.36248779296875 +51875 -0.252227783203125 +51876 -0.343536376953125 +51877 -0.25103759765625 +51878 -0.3018798828125 +51879 -0.233734130859375 +51880 -0.231414794921875 +51881 -0.1968994140625 +51882 -0.117645263671875 +51883 -0.132843017578125 +51884 0.007049560546875 +51885 -0.059173583984375 +51886 0.087982177734375 +51887 -0.005706787109375 +51888 0.13946533203125 +51889 0.034576416015625 +51890 0.17425537109375 +51891 0.0677490234375 +51892 0.188201904296875 +51893 0.090728759765625 +51894 0.171234130859375 +51895 0.097259521484375 +51896 0.118438720703125 +51897 0.083831787109375 +51898 0.05706787109375 +51899 0.064300537109375 +51900 -0.010711669921875 +51901 0.039093017578125 +51902 -0.0914306640625 +51903 0.004180908203125 +51904 -0.162322998046875 +51905 -0.028594970703125 +51906 -0.194549560546875 +51907 -0.043975830078125 +51908 -0.1492919921875 +51909 -0.02117919921875 +51910 -0.02166748046875 +51911 0.042572021484375 +51912 0.124053955078125 +51913 0.11322021484375 +51914 0.211151123046875 +51915 0.15008544921875 +51916 0.240447998046875 +51917 0.15423583984375 +51918 0.242218017578125 +51919 0.142547607421875 +51920 0.2257080078125 +51921 0.120758056640625 +51922 0.194366455078125 +51923 0.091400146484375 +51924 0.115509033203125 +51925 0.037628173828125 +51926 0.0128173828125 +51927 -0.027252197265625 +51928 -0.053802490234375 +51929 -0.07061767578125 +51930 -0.110626220703125 +51931 -0.106201171875 +51932 -0.199493408203125 +51933 -0.15625 +51934 -0.29437255859375 +51935 -0.206756591796875 +51936 -0.33221435546875 +51937 -0.2239990234375 +51938 -0.27972412109375 +51939 -0.1904296875 +51940 -0.185333251953125 +51941 -0.132354736328125 +51942 -0.128204345703125 +51943 -0.0926513671875 +51944 -0.115692138671875 +51945 -0.0758056640625 +51946 -0.116455078125 +51947 -0.06561279296875 +51948 -0.105926513671875 +51949 -0.04949951171875 +51950 -0.053955078125 +51951 -0.011871337890625 +51952 0.048797607421875 +51953 0.0517578125 +51954 0.157318115234375 +51955 0.116851806640625 +51956 0.212005615234375 +51957 0.151123046875 +51958 0.218475341796875 +51959 0.157379150390625 +51960 0.23724365234375 +51961 0.167938232421875 +51962 0.30535888671875 +51963 0.20269775390625 +51964 0.38128662109375 +51965 0.23956298828125 +51966 0.404449462890625 +51967 0.246337890625 +51968 0.3944091796875 +51969 0.2332763671875 +51970 0.3885498046875 +51971 0.220184326171875 +51972 0.362640380859375 +51973 0.195556640625 +51974 0.27362060546875 +51975 0.13848876953125 +51976 0.11712646484375 +51977 0.047607421875 +51978 -0.054901123046875 +51979 -0.0501708984375 +51980 -0.19085693359375 +51981 -0.128204345703125 +51982 -0.28570556640625 +51983 -0.183441162109375 +51984 -0.339263916015625 +51985 -0.215423583984375 +51986 -0.3775634765625 +51987 -0.237091064453125 +51988 -0.445709228515625 +51989 -0.2711181640625 +51990 -0.535064697265625 +51991 -0.313232421875 +51992 -0.629058837890625 +51993 -0.355316162109375 +51994 -0.697601318359375 +51995 -0.382537841796875 +51996 -0.70391845703125 +51997 -0.376861572265625 +51998 -0.6424560546875 +51999 -0.336029052734375 +52000 -0.491241455078125 +52001 -0.249542236328125 +52002 -0.265716552734375 +52003 -0.125762939453125 +52004 -0.023712158203125 +52005 0.005584716796875 +52006 0.201751708984375 +52007 0.12738037109375 +52008 0.375823974609375 +52009 0.22161865234375 +52010 0.485076904296875 +52011 0.281219482421875 +52012 0.56884765625 +52013 0.32586669921875 +52014 0.634765625 +52015 0.35931396484375 +52016 0.63763427734375 +52017 0.35882568359375 +52018 0.5660400390625 +52019 0.318817138671875 +52020 0.4720458984375 +52021 0.265777587890625 +52022 0.40692138671875 +52023 0.225921630859375 +52024 0.3778076171875 +52025 0.203277587890625 +52026 0.376953125 +52027 0.194427490234375 +52028 0.371978759765625 +52029 0.183502197265625 +52030 0.313140869140625 +52031 0.145904541015625 +52032 0.184417724609375 +52033 0.073944091796875 +52034 0.011199951171875 +52035 -0.0191650390625 +52036 -0.171051025390625 +52037 -0.11529541015625 +52038 -0.33740234375 +52039 -0.20166015625 +52040 -0.47198486328125 +52041 -0.27020263671875 +52042 -0.560394287109375 +52043 -0.313690185546875 +52044 -0.58056640625 +52045 -0.32110595703125 +52046 -0.54754638671875 +52047 -0.300201416015625 +52048 -0.508575439453125 +52049 -0.275115966796875 +52050 -0.459503173828125 +52051 -0.244049072265625 +52052 -0.394378662109375 +52053 -0.20440673828125 +52054 -0.35260009765625 +52055 -0.176422119140625 +52056 -0.31170654296875 +52057 -0.14910888671875 +52058 -0.197418212890625 +52059 -0.085418701171875 +52060 -0.007965087890625 +52061 0.01519775390625 +52062 0.207489013671875 +52063 0.127685546875 +52064 0.409210205078125 +52065 0.23187255859375 +52066 0.57208251953125 +52067 0.31500244140625 +52068 0.66595458984375 +52069 0.36187744140625 +52070 0.65875244140625 +52071 0.35638427734375 +52072 0.56744384765625 +52073 0.3072509765625 +52074 0.431396484375 +52075 0.2344970703125 +52076 0.29443359375 +52077 0.160491943359375 +52078 0.182464599609375 +52079 0.098541259765625 +52080 0.06365966796875 +52081 0.032928466796875 +52082 -0.075958251953125 +52083 -0.04302978515625 +52084 -0.189422607421875 +52085 -0.1053466796875 +52086 -0.271942138671875 +52087 -0.151336669921875 +52088 -0.342529296875 +52089 -0.19036865234375 +52090 -0.364166259765625 +52091 -0.20367431640625 +52092 -0.327239990234375 +52093 -0.186309814453125 +52094 -0.2769775390625 +52095 -0.161041259765625 +52096 -0.253692626953125 +52097 -0.148193359375 +52098 -0.24365234375 +52099 -0.14093017578125 +52100 -0.1983642578125 +52101 -0.114990234375 +52102 -0.116241455078125 +52103 -0.069732666015625 +52104 -0.036834716796875 +52105 -0.02532958984375 +52106 0.034881591796875 +52107 0.01544189453125 +52108 0.09124755859375 +52109 0.0484619140625 +52110 0.10888671875 +52111 0.06170654296875 +52112 0.125518798828125 +52113 0.073944091796875 +52114 0.15771484375 +52115 0.09332275390625 +52116 0.17828369140625 +52117 0.105987548828125 +52118 0.17108154296875 +52119 0.10369873046875 +52120 0.129974365234375 +52121 0.0833740234375 +52122 0.082427978515625 +52123 0.058807373046875 +52124 0.027679443359375 +52125 0.029693603515625 +52126 -0.065643310546875 +52127 -0.019622802734375 +52128 -0.15936279296875 +52129 -0.06976318359375 +52130 -0.21307373046875 +52131 -0.1002197265625 +52132 -0.234649658203125 +52133 -0.114776611328125 +52134 -0.2001953125 +52135 -0.10113525390625 +52136 -0.119171142578125 +52137 -0.06390380859375 +52138 -0.024749755859375 +52139 -0.01959228515625 +52140 0.085784912109375 +52141 0.0333251953125 +52142 0.178131103515625 +52143 0.077667236328125 +52144 0.215576171875 +52145 0.095062255859375 +52146 0.211456298828125 +52147 0.09228515625 +52148 0.17523193359375 +52149 0.07415771484375 +52150 0.128753662109375 +52151 0.0516357421875 +52152 0.1019287109375 +52153 0.03973388671875 +52154 0.0743408203125 +52155 0.028045654296875 +52156 0.04327392578125 +52157 0.015045166015625 +52158 0.038177490234375 +52159 0.015411376953125 +52160 0.076263427734375 +52161 0.03765869140625 +52162 0.14105224609375 +52163 0.07330322265625 +52164 0.186431884765625 +52165 0.09893798828125 +52166 0.188812255859375 +52167 0.1025390625 +52168 0.1390380859375 +52169 0.079376220703125 +52170 0.041778564453125 +52171 0.03173828125 +52172 -0.079437255859375 +52173 -0.028533935546875 +52174 -0.219390869140625 +52175 -0.098907470703125 +52176 -0.367828369140625 +52177 -0.17413330078125 +52178 -0.494873046875 +52179 -0.239166259765625 +52180 -0.556243896484375 +52181 -0.2716064453125 +52182 -0.508697509765625 +52183 -0.24957275390625 +52184 -0.3756103515625 +52185 -0.184722900390625 +52186 -0.218902587890625 +52187 -0.108154296875 +52188 -0.063751220703125 +52189 -0.03240966796875 +52190 0.091552734375 +52191 0.04345703125 +52192 0.23602294921875 +52193 0.11407470703125 +52194 0.342987060546875 +52195 0.166107177734375 +52196 0.39520263671875 +52197 0.19097900390625 +52198 0.389373779296875 +52199 0.187103271484375 +52200 0.324249267578125 +52201 0.15386962890625 +52202 0.224090576171875 +52203 0.103546142578125 +52204 0.124267578125 +52205 0.05389404296875 +52206 0.037078857421875 +52207 0.011077880859375 +52208 -0.010101318359375 +52209 -0.01116943359375 +52210 -0.019439697265625 +52211 -0.0140380859375 +52212 -0.022796630859375 +52213 -0.013702392578125 +52214 -0.001556396484375 +52215 -0.000885009765625 +52216 0.056304931640625 +52217 0.030303955078125 +52218 0.106719970703125 +52219 0.057586669921875 +52220 0.096893310546875 +52221 0.05426025390625 +52222 0.042694091796875 +52223 0.028228759765625 +52224 -0.018035888671875 +52225 -0.00115966796875 +52226 -0.07586669921875 +52227 -0.029388427734375 +52228 -0.11944580078125 +52229 -0.051361083984375 +52230 -0.15972900390625 +52231 -0.07208251953125 +52232 -0.202606201171875 +52233 -0.094146728515625 +52234 -0.24859619140625 +52235 -0.117645263671875 +52236 -0.30517578125 +52237 -0.145965576171875 +52238 -0.36212158203125 +52239 -0.174224853515625 +52240 -0.39141845703125 +52241 -0.18914794921875 +52242 -0.35528564453125 +52243 -0.172821044921875 +52244 -0.249969482421875 +52245 -0.12347412109375 +52246 -0.092864990234375 +52247 -0.049346923828125 +52248 0.08905029296875 +52249 0.036834716796875 +52250 0.2352294921875 +52251 0.106475830078125 +52252 0.318817138671875 +52253 0.1468505859375 +52254 0.358642578125 +52255 0.166717529296875 +52256 0.347747802734375 +52257 0.162750244140625 +52258 0.28564453125 +52259 0.134674072265625 +52260 0.223175048828125 +52261 0.10638427734375 +52262 0.196746826171875 +52263 0.095001220703125 +52264 0.179840087890625 +52265 0.087982177734375 +52266 0.155548095703125 +52267 0.077301025390625 +52268 0.151214599609375 +52269 0.075836181640625 +52270 0.156951904296875 +52271 0.078857421875 +52272 0.13177490234375 +52273 0.0670166015625 +52274 0.100799560546875 +52275 0.052154541015625 +52276 0.087127685546875 +52277 0.045196533203125 +52278 0.05487060546875 +52279 0.029266357421875 +52280 -0.009002685546875 +52281 -0.001739501953125 +52282 -0.10400390625 +52283 -0.04754638671875 +52284 -0.229400634765625 +52285 -0.107757568359375 +52286 -0.35552978515625 +52287 -0.168304443359375 +52288 -0.441925048828125 +52289 -0.21002197265625 +52290 -0.473846435546875 +52291 -0.225921630859375 +52292 -0.464813232421875 +52293 -0.222320556640625 +52294 -0.419097900390625 +52295 -0.201202392578125 +52296 -0.334320068359375 +52297 -0.16143798828125 +52298 -0.227935791015625 +52299 -0.111236572265625 +52300 -0.12347412109375 +52301 -0.06170654296875 +52302 -0.02764892578125 +52303 -0.016082763671875 +52304 0.077667236328125 +52305 0.0341796875 +52306 0.2132568359375 +52307 0.098846435546875 +52308 0.38885498046875 +52309 0.182464599609375 +52310 0.582794189453125 +52311 0.2747802734375 +52312 0.734039306640625 +52313 0.346954345703125 +52314 0.800140380859375 +52315 0.37890625 +52316 0.7783203125 +52317 0.3692626953125 +52318 0.6651611328125 +52319 0.316375732421875 +52320 0.45965576171875 +52321 0.219757080078125 +52322 0.199188232421875 +52323 0.0970458984375 +52324 -0.050689697265625 +52325 -0.02081298828125 +52326 -0.23297119140625 +52327 -0.106903076171875 +52328 -0.33013916015625 +52329 -0.152984619140625 +52330 -0.368408203125 +52331 -0.17138671875 +52332 -0.378936767578125 +52333 -0.176788330078125 +52334 -0.376983642578125 +52335 -0.1763916015625 +52336 -0.37969970703125 +52337 -0.17828369140625 +52338 -0.391510009765625 +52339 -0.18450927734375 +52340 -0.385345458984375 +52341 -0.182220458984375 +52342 -0.3419189453125 +52343 -0.16229248046875 +52344 -0.28289794921875 +52345 -0.134918212890625 +52346 -0.251617431640625 +52347 -0.120513916015625 +52348 -0.266143798828125 +52349 -0.127593994140625 +52350 -0.273345947265625 +52351 -0.131103515625 +52352 -0.216796875 +52353 -0.1043701171875 +52354 -0.128265380859375 +52355 -0.062408447265625 +52356 -0.068145751953125 +52357 -0.033721923828125 +52358 -0.0430908203125 +52359 -0.021484375 +52360 -0.024444580078125 +52361 -0.01220703125 +52362 0.020721435546875 +52363 0.0096435546875 +52364 0.124481201171875 +52365 0.05914306640625 +52366 0.25787353515625 +52367 0.12255859375 +52368 0.379119873046875 +52369 0.18017578125 +52370 0.47991943359375 +52371 0.228057861328125 +52372 0.5281982421875 +52373 0.25103759765625 +52374 0.511138916015625 +52375 0.24310302734375 +52376 0.456207275390625 +52377 0.217193603515625 +52378 0.407470703125 +52379 0.194091796875 +52380 0.383758544921875 +52381 0.182708740234375 +52382 0.35687255859375 +52383 0.16973876953125 +52384 0.31182861328125 +52385 0.14813232421875 +52386 0.250885009765625 +52387 0.11895751953125 +52388 0.1654052734375 +52389 0.07818603515625 +52390 0.035247802734375 +52391 0.016357421875 +52392 -0.142059326171875 +52393 -0.067657470703125 +52394 -0.33563232421875 +52395 -0.159271240234375 +52396 -0.5345458984375 +52397 -0.253326416015625 +52398 -0.72186279296875 +52399 -0.341827392578125 +52400 -0.836669921875 +52401 -0.396026611328125 +52402 -0.8326416015625 +52403 -0.394073486328125 +52404 -0.7296142578125 +52405 -0.345306396484375 +52406 -0.582550048828125 +52407 -0.27569580078125 +52408 -0.440093994140625 +52409 -0.208221435546875 +52410 -0.324310302734375 +52411 -0.1533203125 +52412 -0.20147705078125 +52413 -0.095062255859375 +52414 -0.044647216796875 +52415 -0.020721435546875 +52416 0.103973388671875 +52417 0.049713134765625 +52418 0.202392578125 +52419 0.096405029296875 +52420 0.264495849609375 +52421 0.12591552734375 +52422 0.338897705078125 +52423 0.161163330078125 +52424 0.443817138671875 +52425 0.210723876953125 +52426 0.545074462890625 +52427 0.258514404296875 +52428 0.6173095703125 +52429 0.29254150390625 +52430 0.6524658203125 +52431 0.308990478515625 +52432 0.66339111328125 +52433 0.313934326171875 +52434 0.6561279296875 +52435 0.310272216796875 +52436 0.606781005859375 +52437 0.286712646484375 +52438 0.501190185546875 +52439 0.236572265625 +52440 0.352783203125 +52441 0.166229248046875 +52442 0.176544189453125 +52443 0.082763671875 +52444 -0.034820556640625 +52445 -0.017242431640625 +52446 -0.258209228515625 +52447 -0.122833251953125 +52448 -0.44244384765625 +52449 -0.2098388671875 +52450 -0.5753173828125 +52451 -0.27252197265625 +52452 -0.65203857421875 +52453 -0.30865478515625 +52454 -0.641632080078125 +52455 -0.3035888671875 +52456 -0.562164306640625 +52457 -0.265899658203125 +52458 -0.458038330078125 +52459 -0.216552734375 +52460 -0.350555419921875 +52461 -0.16558837890625 +52462 -0.260528564453125 +52463 -0.122833251953125 +52464 -0.192108154296875 +52465 -0.09027099609375 +52466 -0.141937255859375 +52467 -0.06634521484375 +52468 -0.1021728515625 +52469 -0.04736328125 +52470 -0.062896728515625 +52471 -0.028656005859375 +52472 -0.011932373046875 +52473 -0.004486083984375 +52474 0.062835693359375 +52475 0.030853271484375 +52476 0.148712158203125 +52477 0.071380615234375 +52478 0.241729736328125 +52479 0.11517333984375 +52480 0.34912109375 +52481 0.165374755859375 +52482 0.457305908203125 +52483 0.21484375 +52484 0.54388427734375 +52485 0.25311279296875 +52486 0.5728759765625 +52487 0.264739990234375 +52488 0.506591796875 +52489 0.23345947265625 +52490 0.351226806640625 +52491 0.162322998046875 +52492 0.146514892578125 +52493 0.069091796875 +52494 -0.05523681640625 +52495 -0.022918701171875 +52496 -0.21624755859375 +52497 -0.096832275390625 +52498 -0.334930419921875 +52499 -0.151763916015625 +52500 -0.402984619140625 +52501 -0.183929443359375 +52502 -0.4412841796875 +52503 -0.202423095703125 +52504 -0.49578857421875 +52505 -0.2274169921875 +52506 -0.5601806640625 +52507 -0.256072998046875 +52508 -0.600738525390625 +52509 -0.27362060546875 +52510 -0.584228515625 +52511 -0.265472412109375 +52512 -0.47930908203125 +52513 -0.217926025390625 +52514 -0.27935791015625 +52515 -0.128173828125 +52516 -0.0089111328125 +52517 -0.007171630859375 +52518 0.268798828125 +52519 0.11712646484375 +52520 0.482818603515625 +52521 0.213409423828125 +52522 0.60369873046875 +52523 0.268585205078125 +52524 0.650421142578125 +52525 0.2908935546875 +52526 0.66400146484375 +52527 0.298309326171875 +52528 0.6414794921875 +52529 0.289459228515625 +52530 0.572540283203125 +52531 0.259735107421875 +52532 0.498138427734375 +52533 0.227142333984375 +52534 0.439453125 +52535 0.201019287109375 +52536 0.375518798828125 +52537 0.17218017578125 +52538 0.274505615234375 +52539 0.12664794921875 +52540 0.1087646484375 +52541 0.052337646484375 +52542 -0.099395751953125 +52543 -0.040802001953125 +52544 -0.3182373046875 +52545 -0.13873291015625 +52546 -0.5489501953125 +52547 -0.24188232421875 +52548 -0.7738037109375 +52549 -0.34234619140625 +52550 -0.86383056640625 +52551 -0.416748046875 +52552 -0.870391845703125 +52553 -0.45037841796875 +52554 -0.86895751953125 +52555 -0.451019287109375 +52556 -0.861053466796875 +52557 -0.424407958984375 +52558 -0.765869140625 +52559 -0.3629150390625 +52560 -0.5301513671875 +52561 -0.261566162109375 +52562 -0.214691162109375 +52563 -0.12353515625 +52564 0.137359619140625 +52565 0.032196044921875 +52566 0.474822998046875 +52567 0.183013916015625 +52568 0.76239013671875 +52569 0.313232421875 +52570 0.867462158203125 +52571 0.410888671875 +52572 0.870361328125 +52573 0.476104736328125 +52574 0.86480712890625 +52575 0.503692626953125 +52576 0.831817626953125 +52577 0.4959716796875 +52578 0.677581787109375 +52579 0.463592529296875 +52580 0.495880126953125 +52581 0.409088134765625 +52582 0.30767822265625 +52583 0.340576171875 +52584 0.116180419921875 +52585 0.259033203125 +52586 -0.110748291015625 +52587 0.150482177734375 +52588 -0.381805419921875 +52589 0.01190185546875 +52590 -0.6572265625 +52591 -0.1378173828125 +52592 -0.857421875 +52593 -0.27227783203125 +52594 -0.870391845703125 +52595 -0.372589111328125 +52596 -0.870391845703125 +52597 -0.435516357421875 +52598 -0.86444091796875 +52599 -0.472869873046875 +52600 -0.85723876953125 +52601 -0.500274658203125 +52602 -0.790008544921875 +52603 -0.509613037109375 +52604 -0.62847900390625 +52605 -0.476959228515625 +52606 -0.3956298828125 +52607 -0.40087890625 +52608 -0.126708984375 +52609 -0.2957763671875 +52610 0.150115966796875 +52611 -0.173675537109375 +52612 0.424041748046875 +52613 -0.039764404296875 +52614 0.670623779296875 +52615 0.09405517578125 +52616 0.854522705078125 +52617 0.210723876953125 +52618 0.866485595703125 +52619 0.30242919921875 +52620 0.86920166015625 +52621 0.362335205078125 +52622 0.8653564453125 +52623 0.398406982421875 +52624 0.857147216796875 +52625 0.416473388671875 +52626 0.766845703125 +52627 0.41522216796875 +52628 0.628509521484375 +52629 0.3968505859375 +52630 0.462127685546875 +52631 0.358367919921875 +52632 0.297210693359375 +52633 0.311065673828125 +52634 0.14862060546875 +52635 0.260345458984375 +52636 -0.00537109375 +52637 0.1961669921875 +52638 -0.15753173828125 +52639 0.121856689453125 +52640 -0.31304931640625 +52641 0.035858154296875 +52642 -0.48876953125 +52643 -0.0679931640625 +52644 -0.6416015625 +52645 -0.16900634765625 +52646 -0.751373291015625 +52647 -0.256256103515625 +52648 -0.84619140625 +52649 -0.33984375 +52650 -0.861297607421875 +52651 -0.413238525390625 +52652 -0.863250732421875 +52653 -0.461822509765625 +52654 -0.856597900390625 +52655 -0.471649169921875 +52656 -0.7498779296875 +52657 -0.447998046875 +52658 -0.624542236328125 +52659 -0.41632080078125 +52660 -0.47808837890625 +52661 -0.366943359375 +52662 -0.253387451171875 +52663 -0.274169921875 +52664 0.003692626953125 +52665 -0.158050537109375 +52666 0.2257080078125 +52667 -0.048736572265625 +52668 0.427154541015625 +52669 0.05926513671875 +52670 0.643218994140625 +52671 0.180145263671875 +52672 0.855926513671875 +52673 0.30963134765625 +52674 0.870361328125 +52675 0.422149658203125 +52676 0.870361328125 +52677 0.495819091796875 +52678 0.862762451171875 +52679 0.53375244140625 +52680 0.79669189453125 +52681 0.53460693359375 +52682 0.595794677734375 +52683 0.49420166015625 +52684 0.362152099609375 +52685 0.425384521484375 +52686 0.1270751953125 +52687 0.3404541015625 +52688 -0.086944580078125 +52689 0.248748779296875 +52690 -0.2784423828125 +52691 0.151214599609375 +52692 -0.484832763671875 +52693 0.032562255859375 +52694 -0.729583740234375 +52695 -0.115570068359375 +52696 -0.86688232421875 +52697 -0.27081298828125 +52698 -0.870391845703125 +52699 -0.4052734375 +52700 -0.86859130859375 +52701 -0.516693115234375 +52702 -0.86279296875 +52703 -0.60406494140625 +52704 -0.817962646484375 +52705 -0.6514892578125 +52706 -0.6116943359375 +52707 -0.638916015625 +52708 -0.3128662109375 +52709 -0.563201904296875 +52710 0.039398193359375 +52711 -0.43914794921875 +52712 0.422821044921875 +52713 -0.27557373046875 +52714 0.805145263671875 +52715 -0.087188720703125 +52716 0.870361328125 +52717 0.09600830078125 +52718 0.870361328125 +52719 0.24884033203125 +52720 0.860015869140625 +52721 0.36602783203125 +52722 0.727935791015625 +52723 0.444061279296875 +52724 0.48114013671875 +52725 0.48028564453125 +52726 0.2059326171875 +52727 0.485198974609375 +52728 -0.06103515625 +52729 0.4686279296875 +52730 -0.29913330078125 +52731 0.434814453125 +52732 -0.516204833984375 +52733 0.3773193359375 +52734 -0.7252197265625 +52735 0.289337158203125 +52736 -0.85980224609375 +52737 0.181640625 +52738 -0.870391845703125 +52739 0.069854736328125 +52740 -0.870391845703125 +52741 -0.032806396484375 +52742 -0.858062744140625 +52743 -0.106201171875 +52744 -0.673004150390625 +52745 -0.148345947265625 +52746 -0.42694091796875 +52747 -0.18035888671875 +52748 -0.2100830078125 +52749 -0.22003173828125 +52750 -0.0362548828125 +52751 -0.2662353515625 +52752 0.10943603515625 +52753 -0.306854248046875 +52754 0.23516845703125 +52755 -0.3336181640625 +52756 0.373687744140625 +52757 -0.329559326171875 +52758 0.517791748046875 +52759 -0.2955322265625 +52760 0.602783203125 +52761 -0.257354736328125 +52762 0.635711669921875 +52763 -0.213165283203125 +52764 0.655181884765625 +52765 -0.149627685546875 +52766 0.65948486328125 +52767 -0.071197509765625 +52768 0.651275634765625 +52769 0.018402099609375 +52770 0.61846923828125 +52771 0.108734130859375 +52772 0.53753662109375 +52773 0.18426513671875 +52774 0.404144287109375 +52775 0.2371826171875 +52776 0.22186279296875 +52777 0.263092041015625 +52778 0.003997802734375 +52779 0.26220703125 +52780 -0.22100830078125 +52781 0.24169921875 +52782 -0.42449951171875 +52783 0.2098388671875 +52784 -0.579833984375 +52785 0.17529296875 +52786 -0.641876220703125 +52787 0.155548095703125 +52788 -0.6177978515625 +52789 0.14801025390625 +52790 -0.575531005859375 +52791 0.1265869140625 +52792 -0.526336669921875 +52793 0.089385986328125 +52794 -0.42645263671875 +52795 0.057891845703125 +52796 -0.2581787109375 +52797 0.043731689453125 +52798 -0.068695068359375 +52799 0.032470703125 +52800 0.09222412109375 +52801 0.008819580078125 +52802 0.232147216796875 +52803 -0.01922607421875 +52804 0.3509521484375 +52805 -0.047210693359375 +52806 0.410064697265625 +52807 -0.0869140625 +52808 0.372955322265625 +52809 -0.150146484375 +52810 0.2554931640625 +52811 -0.228271484375 +52812 0.10711669921875 +52813 -0.29998779296875 +52814 -0.052886962890625 +52815 -0.35736083984375 +52816 -0.186279296875 +52817 -0.385772705078125 +52818 -0.23291015625 +52819 -0.362640380859375 +52820 -0.209442138671875 +52821 -0.297515869140625 +52822 -0.174163818359375 +52823 -0.21759033203125 +52824 -0.126739501953125 +52825 -0.1265869140625 +52826 -0.048126220703125 +52827 -0.02081298828125 +52828 0.0426025390625 +52829 0.087860107421875 +52830 0.10748291015625 +52831 0.180084228515625 +52832 0.1409912109375 +52833 0.25018310546875 +52834 0.19708251953125 +52835 0.317352294921875 +52836 0.273651123046875 +52837 0.378662109375 +52838 0.31768798828125 +52839 0.411285400390625 +52840 0.341094970703125 +52841 0.419708251953125 +52842 0.368011474609375 +52843 0.414337158203125 +52844 0.37249755859375 +52845 0.385894775390625 +52846 0.30072021484375 +52847 0.314453125 +52848 0.1517333984375 +52849 0.2022705078125 +52850 -0.01470947265625 +52851 0.076751708984375 +52852 -0.1883544921875 +52853 -0.054534912109375 +52854 -0.372711181640625 +52855 -0.18963623046875 +52856 -0.51397705078125 +52857 -0.303375244140625 +52858 -0.57177734375 +52859 -0.376312255859375 +52860 -0.53948974609375 +52861 -0.40325927734375 +52862 -0.43511962890625 +52863 -0.3896484375 +52864 -0.2962646484375 +52865 -0.34954833984375 +52866 -0.161102294921875 +52867 -0.2979736328125 +52868 -0.0435791015625 +52869 -0.240814208984375 +52870 0.060394287109375 +52871 -0.177276611328125 +52872 0.13665771484375 +52873 -0.1146240234375 +52874 0.170135498046875 +52875 -0.061004638671875 +52876 0.16552734375 +52877 -0.016937255859375 +52878 0.15728759765625 +52879 0.0289306640625 +52880 0.150787353515625 +52881 0.076019287109375 +52882 0.12200927734375 +52883 0.111785888671875 +52884 0.080108642578125 +52885 0.137451171875 +52886 0.05126953125 +52887 0.1614990234375 +52888 0.062896728515625 +52889 0.193359375 +52890 0.09271240234375 +52891 0.22271728515625 +52892 0.092987060546875 +52893 0.229461669921875 +52894 0.07855224609375 +52895 0.219573974609375 +52896 0.06427001953125 +52897 0.199676513671875 +52898 0.0347900390625 +52899 0.164520263671875 +52900 -0.01171875 +52901 0.1148681640625 +52902 -0.056060791015625 +52903 0.060455322265625 +52904 -0.055511474609375 +52905 0.020843505859375 +52906 -0.010467529296875 +52907 -0.001800537109375 +52908 0.02508544921875 +52909 -0.0272216796875 +52910 0.025665283203125 +52911 -0.063690185546875 +52912 0.017333984375 +52913 -0.098663330078125 +52914 0.00189208984375 +52915 -0.12982177734375 +52916 -0.03173828125 +52917 -0.160552978515625 +52918 -0.071502685546875 +52919 -0.185272216796875 +52920 -0.13543701171875 +52921 -0.211090087890625 +52922 -0.219970703125 +52923 -0.23681640625 +52924 -0.300506591796875 +52925 -0.25311279296875 +52926 -0.376312255859375 +52927 -0.26080322265625 +52928 -0.416107177734375 +52929 -0.24859619140625 +52930 -0.371124267578125 +52931 -0.19830322265625 +52932 -0.242279052734375 +52933 -0.11212158203125 +52934 -0.069732666015625 +52935 -0.008331298828125 +52936 0.125640869140625 +52937 0.102691650390625 +52938 0.31268310546875 +52939 0.20660400390625 +52940 0.45501708984375 +52941 0.28717041015625 +52942 0.554779052734375 +52943 0.34417724609375 +52944 0.61065673828125 +52945 0.37640380859375 +52946 0.610931396484375 +52947 0.37872314453125 +52948 0.531463623046875 +52949 0.341400146484375 +52950 0.3883056640625 +52951 0.271453857421875 +52952 0.23468017578125 +52953 0.19140625 +52954 0.095245361328125 +52955 0.112457275390625 +52956 -0.00396728515625 +52957 0.04656982421875 +52958 -0.04852294921875 +52959 0.001068115234375 +52960 -0.055145263671875 +52961 -0.029296875 +52962 -0.0758056640625 +52963 -0.064208984375 +52964 -0.138702392578125 +52965 -0.113739013671875 +52966 -0.209197998046875 +52967 -0.162567138671875 +52968 -0.289031982421875 +52969 -0.21038818359375 +52970 -0.37884521484375 +52971 -0.25677490234375 +52972 -0.456329345703125 +52973 -0.292266845703125 +52974 -0.51641845703125 +52975 -0.31475830078125 +52976 -0.519287109375 +52977 -0.308258056640625 +52978 -0.458251953125 +52979 -0.2706298828125 +52980 -0.384796142578125 +52981 -0.223724365234375 +52982 -0.323699951171875 +52983 -0.1787109375 +52984 -0.269287109375 +52985 -0.134429931640625 +52986 -0.1951904296875 +52987 -0.081390380859375 +52988 -0.100006103515625 +52989 -0.020263671875 +52990 -0.01055908203125 +52991 0.036773681640625 +52992 0.1033935546875 +52993 0.100830078125 +52994 0.24908447265625 +52995 0.17401123046875 +52996 0.373199462890625 +52997 0.234283447265625 +52998 0.45806884765625 +52999 0.2740478515625 +53000 0.511474609375 +53001 0.296142578125 +53002 0.565399169921875 +53003 0.313446044921875 +53004 0.61138916015625 +53005 0.32293701171875 +53006 0.5897216796875 +53007 0.30133056640625 +53008 0.4906005859375 +53009 0.245513916015625 +53010 0.33148193359375 +53011 0.1634521484375 +53012 0.147796630859375 +53013 0.07037353515625 +53014 -0.01873779296875 +53015 -0.015899658203125 +53016 -0.140289306640625 +53017 -0.083160400390625 +53018 -0.191986083984375 +53019 -0.120452880859375 +53020 -0.184295654296875 +53021 -0.131134033203125 +53022 -0.161834716796875 +53023 -0.13238525390625 +53024 -0.166595458984375 +53025 -0.140533447265625 +53026 -0.19390869140625 +53027 -0.153472900390625 +53028 -0.22442626953125 +53029 -0.163482666015625 +53030 -0.279754638671875 +53031 -0.179412841796875 +53032 -0.3389892578125 +53033 -0.193389892578125 +53034 -0.3543701171875 +53035 -0.186920166015625 +53036 -0.348175048828125 +53037 -0.169708251953125 +53038 -0.32598876953125 +53039 -0.14483642578125 +53040 -0.2581787109375 +53041 -0.10137939453125 +53042 -0.139801025390625 +53043 -0.038238525390625 +53044 0.014617919921875 +53045 0.03790283203125 +53046 0.144378662109375 +53047 0.10198974609375 +53048 0.221038818359375 +53049 0.14208984375 +53050 0.27069091796875 +53051 0.168182373046875 +53052 0.294036865234375 +53053 0.180328369140625 +53054 0.311767578125 +53055 0.18670654296875 +53056 0.339141845703125 +53057 0.193511962890625 +53058 0.360260009765625 +53059 0.19439697265625 +53060 0.360504150390625 +53061 0.18408203125 +53062 0.308380126953125 +53063 0.151519775390625 +53064 0.18170166015625 +53065 0.089202880859375 +53066 0.0047607421875 +53067 0.007232666015625 +53068 -0.17559814453125 +53069 -0.07586669921875 +53070 -0.3143310546875 +53071 -0.142333984375 +53072 -0.36785888671875 +53073 -0.175018310546875 +53074 -0.36248779296875 +53075 -0.183135986328125 +53076 -0.343536376953125 +53077 -0.183258056640625 +53078 -0.3018798828125 +53079 -0.171630859375 +53080 -0.231414794921875 +53081 -0.14581298828125 +53082 -0.117645263671875 +53083 -0.100433349609375 +53084 0.007049560546875 +53085 -0.04791259765625 +53086 0.087982177734375 +53087 -0.00921630859375 +53088 0.13946533203125 +53089 0.020477294921875 +53090 0.17425537109375 +53091 0.04534912109375 +53092 0.188201904296875 +53093 0.063140869140625 +53094 0.171234130859375 +53095 0.069366455078125 +53096 0.118438720703125 +53097 0.061492919921875 +53098 0.05706787109375 +53099 0.049163818359375 +53100 -0.010711669921875 +53101 0.032623291015625 +53102 -0.0914306640625 +53103 0.008941650390625 +53104 -0.162322998046875 +53105 -0.0135498046875 +53106 -0.194549560546875 +53107 -0.024200439453125 +53108 -0.1492919921875 +53109 -0.0084228515625 +53110 -0.02166748046875 +53111 0.035736083984375 +53112 0.124053955078125 +53113 0.08441162109375 +53114 0.211151123046875 +53115 0.109130859375 +53116 0.240447998046875 +53117 0.1107177734375 +53118 0.242218017578125 +53119 0.101104736328125 +53120 0.2257080078125 +53121 0.084381103515625 +53122 0.194366455078125 +53123 0.062408447265625 +53124 0.115509033203125 +53125 0.023468017578125 +53126 0.0128173828125 +53127 -0.023040771484375 +53128 -0.053802490234375 +53129 -0.05419921875 +53130 -0.110626220703125 +53131 -0.079620361328125 +53132 -0.199493408203125 +53133 -0.114898681640625 +53134 -0.29437255859375 +53135 -0.15020751953125 +53136 -0.33221435546875 +53137 -0.161895751953125 +53138 -0.27972412109375 +53139 -0.137664794921875 +53140 -0.185333251953125 +53141 -0.096038818359375 +53142 -0.128204345703125 +53143 -0.067169189453125 +53144 -0.115692138671875 +53145 -0.05419921875 +53146 -0.116455078125 +53147 -0.045867919921875 +53148 -0.105926513671875 +53149 -0.033416748046875 +53150 -0.053955078125 +53151 -0.0059814453125 +53152 0.048797607421875 +53153 0.039520263671875 +53154 0.157318115234375 +53155 0.085845947265625 +53156 0.212005615234375 +53157 0.110321044921875 +53158 0.218475341796875 +53159 0.1148681640625 +53160 0.23724365234375 +53161 0.1221923828125 +53162 0.30535888671875 +53163 0.146270751953125 +53164 0.38128662109375 +53165 0.171630859375 +53166 0.404449462890625 +53167 0.175689697265625 +53168 0.3944091796875 +53169 0.16607666015625 +53170 0.3885498046875 +53171 0.1572265625 +53172 0.362640380859375 +53173 0.140411376953125 +53174 0.27362060546875 +53175 0.099853515625 +53176 0.11712646484375 +53177 0.0343017578125 +53178 -0.054901123046875 +53179 -0.036346435546875 +53180 -0.19085693359375 +53181 -0.092376708984375 +53182 -0.28570556640625 +53183 -0.13165283203125 +53184 -0.339263916015625 +53185 -0.153961181640625 +53186 -0.3775634765625 +53187 -0.16900634765625 +53188 -0.445709228515625 +53189 -0.193756103515625 +53190 -0.535064697265625 +53191 -0.225067138671875 +53192 -0.629058837890625 +53193 -0.256866455078125 +53194 -0.697601318359375 +53195 -0.278045654296875 +53196 -0.70391845703125 +53197 -0.27508544921875 +53198 -0.6424560546875 +53199 -0.2462158203125 +53200 -0.491241455078125 +53201 -0.1834716796875 +53202 -0.265716552734375 +53203 -0.093017578125 +53204 -0.023712158203125 +53205 0.003082275390625 +53206 0.201751708984375 +53207 0.0921630859375 +53208 0.375823974609375 +53209 0.160919189453125 +53210 0.485076904296875 +53211 0.204132080078125 +53212 0.56884765625 +53213 0.23651123046875 +53214 0.634765625 +53215 0.26092529296875 +53216 0.63763427734375 +53217 0.26043701171875 +53218 0.5660400390625 +53219 0.230865478515625 +53220 0.4720458984375 +53221 0.19195556640625 +53222 0.40692138671875 +53223 0.1632080078125 +53224 0.3778076171875 +53225 0.147552490234375 +53226 0.376953125 +53227 0.142364501953125 +53228 0.371978759765625 +53229 0.1357421875 +53230 0.313140869140625 +53231 0.109222412109375 +53232 0.184417724609375 +53233 0.056976318359375 +53234 0.011199951171875 +53235 -0.011199951171875 +53236 -0.171051025390625 +53237 -0.081787109375 +53238 -0.33740234375 +53239 -0.145355224609375 +53240 -0.47198486328125 +53241 -0.1959228515625 +53242 -0.560394287109375 +53243 -0.22808837890625 +53244 -0.58056640625 +53245 -0.233673095703125 +53246 -0.54754638671875 +53247 -0.218475341796875 +53248 -0.508575439453125 +53249 -0.2003173828125 +53250 -0.459503173828125 +53251 -0.17803955078125 +53252 -0.394378662109375 +53253 -0.1494140625 +53254 -0.35260009765625 +53255 -0.1282958984375 +53256 -0.31170654296875 +53257 -0.107330322265625 +53258 -0.197418212890625 +53259 -0.06134033203125 +53260 -0.007965087890625 +53261 0.009918212890625 +53262 0.207489013671875 +53263 0.0892333984375 +53264 0.409210205078125 +53265 0.162689208984375 +53266 0.57208251953125 +53267 0.22149658203125 +53268 0.66595458984375 +53269 0.255157470703125 +53270 0.65875244140625 +53271 0.25262451171875 +53272 0.56744384765625 +53273 0.219757080078125 +53274 0.431396484375 +53275 0.17022705078125 +53276 0.29443359375 +53277 0.1192626953125 +53278 0.182464599609375 +53279 0.0760498046875 +53280 0.06365966796875 +53281 0.0299072265625 +53282 -0.075958251953125 +53283 -0.023651123046875 +53284 -0.189422607421875 +53285 -0.068145751953125 +53286 -0.271942138671875 +53287 -0.10162353515625 +53288 -0.342529296875 +53289 -0.13037109375 +53290 -0.364166259765625 +53291 -0.141448974609375 +53292 -0.327239990234375 +53293 -0.131378173828125 +53294 -0.2769775390625 +53295 -0.115631103515625 +53296 -0.253692626953125 +53297 -0.108001708984375 +53298 -0.24365234375 +53299 -0.103790283203125 +53300 -0.1983642578125 +53301 -0.08636474609375 +53302 -0.116241455078125 +53303 -0.055328369140625 +53304 -0.036834716796875 +53305 -0.0244140625 +53306 0.034881591796875 +53307 0.00439453125 +53308 0.09124755859375 +53309 0.028228759765625 +53310 0.10888671875 +53311 0.038787841796875 +53312 0.125518798828125 +53313 0.048797607421875 +53314 0.15771484375 +53315 0.063720703125 +53316 0.17828369140625 +53317 0.074005126953125 +53318 0.17108154296875 +53319 0.073944091796875 +53320 0.129974365234375 +53321 0.06134033203125 +53322 0.082427978515625 +53323 0.045562744140625 +53324 0.027679443359375 +53325 0.0263671875 +53326 -0.065643310546875 +53327 -0.0069580078125 +53328 -0.15936279296875 +53329 -0.04119873046875 +53330 -0.21307373046875 +53331 -0.06231689453125 +53332 -0.234649658203125 +53333 -0.0728759765625 +53334 -0.2001953125 +53335 -0.064483642578125 +53336 -0.119171142578125 +53337 -0.04022216796875 +53338 -0.024749755859375 +53339 -0.01129150390625 +53340 0.085784912109375 +53341 0.0234375 +53342 0.178131103515625 +53343 0.05230712890625 +53344 0.215576171875 +53345 0.0628662109375 +53346 0.211456298828125 +53347 0.059783935546875 +53348 0.17523193359375 +53349 0.04644775390625 +53350 0.128753662109375 +53351 0.030364990234375 +53352 0.1019287109375 +53353 0.021820068359375 +53354 0.0743408203125 +53355 0.01373291015625 +53356 0.04327392578125 +53357 0.005035400390625 +53358 0.038177490234375 +53359 0.0057373046875 +53360 0.076263427734375 +53361 0.0216064453125 +53362 0.14105224609375 +53363 0.04681396484375 +53364 0.186431884765625 +53365 0.06536865234375 +53366 0.188812255859375 +53367 0.0689697265625 +53368 0.1390380859375 +53369 0.0543212890625 +53370 0.041778564453125 +53371 0.022918701171875 +53372 -0.079437255859375 +53373 -0.0172119140625 +53374 -0.219390869140625 +53375 -0.064361572265625 +53376 -0.367828369140625 +53377 -0.115020751953125 +53378 -0.494873046875 +53379 -0.158935546875 +53380 -0.556243896484375 +53381 -0.18084716796875 +53382 -0.508697509765625 +53383 -0.165802001953125 +53384 -0.3756103515625 +53385 -0.12176513671875 +53386 -0.218902587890625 +53387 -0.0699462890625 +53388 -0.063751220703125 +53389 -0.018890380859375 +53390 0.091552734375 +53391 0.032073974609375 +53392 0.23602294921875 +53393 0.079345703125 +53394 0.342987060546875 +53395 0.113861083984375 +53396 0.39520263671875 +53397 0.129852294921875 +53398 0.389373779296875 +53399 0.126251220703125 +53400 0.324249267578125 +53401 0.10272216796875 +53402 0.224090576171875 +53403 0.067657470703125 +53404 0.124267578125 +53405 0.03326416015625 +53406 0.037078857421875 +53407 0.003753662109375 +53408 -0.010101318359375 +53409 -0.011505126953125 +53410 -0.019439697265625 +53411 -0.013336181640625 +53412 -0.022796630859375 +53413 -0.012786865234375 +53414 -0.001556396484375 +53415 -0.0035400390625 +53416 0.056304931640625 +53417 0.018402099609375 +53418 0.106719970703125 +53419 0.037750244140625 +53420 0.096893310546875 +53421 0.036285400390625 +53422 0.042694091796875 +53423 0.01934814453125 +53424 -0.018035888671875 +53425 -0.0001220703125 +53426 -0.07586669921875 +53427 -0.018951416015625 +53428 -0.11944580078125 +53429 -0.03326416015625 +53430 -0.15972900390625 +53431 -0.046875 +53432 -0.202606201171875 +53433 -0.061798095703125 +53434 -0.24859619140625 +53435 -0.07818603515625 +53436 -0.30517578125 +53437 -0.09857177734375 +53438 -0.36212158203125 +53439 -0.119384765625 +53440 -0.39141845703125 +53441 -0.13092041015625 +53442 -0.35528564453125 +53443 -0.120086669921875 +53444 -0.249969482421875 +53445 -0.08551025390625 +53446 -0.092864990234375 +53447 -0.0330810546875 +53448 0.08905029296875 +53449 0.027984619140625 +53450 0.2352294921875 +53451 0.07696533203125 +53452 0.318817138671875 +53453 0.10467529296875 +53454 0.358642578125 +53455 0.11761474609375 +53456 0.347747802734375 +53457 0.11346435546875 +53458 0.28564453125 +53459 0.092041015625 +53460 0.223175048828125 +53461 0.070831298828125 +53462 0.196746826171875 +53463 0.062347412109375 +53464 0.179840087890625 +53465 0.057403564453125 +53466 0.155548095703125 +53467 0.0501708984375 +53468 0.151214599609375 +53469 0.049957275390625 +53470 0.156951904296875 +53471 0.05328369140625 +53472 0.13177490234375 +53473 0.04595947265625 +53474 0.100799560546875 +53475 0.03656005859375 +53476 0.087127685546875 +53477 0.032989501953125 +53478 0.05487060546875 +53479 0.0228271484375 +53480 -0.009002685546875 +53481 0.00152587890625 +53482 -0.10400390625 +53483 -0.030731201171875 +53484 -0.229400634765625 +53485 -0.07373046875 +53486 -0.35552978515625 +53487 -0.11724853515625 +53488 -0.441925048828125 +53489 -0.1473388671875 +53490 -0.473846435546875 +53491 -0.158905029296875 +53492 -0.464813232421875 +53493 -0.15655517578125 +53494 -0.419097900390625 +53495 -0.1417236328125 +53496 -0.334320068359375 +53497 -0.113525390625 +53498 -0.227935791015625 +53499 -0.07794189453125 +53500 -0.12347412109375 +53501 -0.04296875 +53502 -0.02764892578125 +53503 -0.010894775390625 +53504 0.077667236328125 +53505 0.02459716796875 +53506 0.2132568359375 +53507 0.0704345703125 +53508 0.38885498046875 +53509 0.129180908203125 +53510 0.582794189453125 +53511 0.1934814453125 +53512 0.734039306640625 +53513 0.243743896484375 +53514 0.800140380859375 +53515 0.26641845703125 +53516 0.7783203125 +53517 0.260467529296875 +53518 0.6651611328125 +53519 0.2247314453125 +53520 0.45965576171875 +53521 0.158966064453125 +53522 0.199188232421875 +53523 0.074981689453125 +53524 -0.050689697265625 +53525 -0.00653076171875 +53526 -0.23297119140625 +53527 -0.067535400390625 +53528 -0.33013916015625 +53529 -0.102264404296875 +53530 -0.368408203125 +53531 -0.11865234375 +53532 -0.378936767578125 +53533 -0.1260986328125 +53534 -0.376983642578125 +53535 -0.129150390625 +53536 -0.37969970703125 +53537 -0.132965087890625 +53538 -0.391510009765625 +53539 -0.13873291015625 +53540 -0.385345458984375 +53541 -0.137908935546875 +53542 -0.3419189453125 +53543 -0.124420166015625 +53544 -0.28289794921875 +53545 -0.105072021484375 +53546 -0.251617431640625 +53547 -0.09344482421875 +53548 -0.266143798828125 +53549 -0.095306396484375 +53550 -0.273345947265625 +53551 -0.094268798828125 +53552 -0.216796875 +53553 -0.072906494140625 +53554 -0.128265380859375 +53555 -0.04132080078125 +53556 -0.068145751953125 +53557 -0.018585205078125 +53558 -0.0430908203125 +53559 -0.006988525390625 +53560 -0.024444580078125 +53561 0.00213623046875 +53562 0.020721435546875 +53563 0.0189208984375 +53564 0.124481201171875 +53565 0.05322265625 +53566 0.25787353515625 +53567 0.095916748046875 +53568 0.379119873046875 +53569 0.133941650390625 +53570 0.47991943359375 +53571 0.16473388671875 +53572 0.5281982421875 +53573 0.1783447265625 +53574 0.511138916015625 +53575 0.170867919921875 +53576 0.456207275390625 +53577 0.1510009765625 +53578 0.407470703125 +53579 0.132659912109375 +53580 0.383758544921875 +53581 0.121917724609375 +53582 0.35687255859375 +53583 0.110137939453125 +53584 0.31182861328125 +53585 0.09283447265625 +53586 0.250885009765625 +53587 0.0709228515625 +53588 0.1654052734375 +53589 0.0418701171875 +53590 0.035247802734375 +53591 -0.00048828125 +53592 -0.142059326171875 +53593 -0.056854248046875 +53594 -0.33563232421875 +53595 -0.1175537109375 +53596 -0.5345458984375 +53597 -0.179168701171875 +53598 -0.72186279296875 +53599 -0.236480712890625 +53600 -0.836669921875 +53601 -0.27056884765625 +53602 -0.8326416015625 +53603 -0.267059326171875 +53604 -0.7296142578125 +53605 -0.2322998046875 +53606 -0.582550048828125 +53607 -0.183624267578125 +53608 -0.440093994140625 +53609 -0.1363525390625 +53610 -0.324310302734375 +53611 -0.097503662109375 +53612 -0.20147705078125 +53613 -0.05670166015625 +53614 -0.044647216796875 +53615 -0.00567626953125 +53616 0.103973388671875 +53617 0.04229736328125 +53618 0.202392578125 +53619 0.07403564453125 +53620 0.264495849609375 +53621 0.093841552734375 +53622 0.338897705078125 +53623 0.116851806640625 +53624 0.443817138671875 +53625 0.148773193359375 +53626 0.545074462890625 +53627 0.178985595703125 +53628 0.6173095703125 +53629 0.199676513671875 +53630 0.6524658203125 +53631 0.208465576171875 +53632 0.66339111328125 +53633 0.209503173828125 +53634 0.6561279296875 +53635 0.204803466796875 +53636 0.606781005859375 +53637 0.187042236328125 +53638 0.501190185546875 +53639 0.15191650390625 +53640 0.352783203125 +53641 0.10369873046875 +53642 0.176544189453125 +53643 0.047210693359375 +53644 -0.034820556640625 +53645 -0.019744873046875 +53646 -0.258209228515625 +53647 -0.08990478515625 +53648 -0.44244384765625 +53649 -0.14727783203125 +53650 -0.5753173828125 +53651 -0.188079833984375 +53652 -0.65203857421875 +53653 -0.210906982421875 +53654 -0.641632080078125 +53655 -0.206146240234375 +53656 -0.562164306640625 +53657 -0.179534912109375 +53658 -0.458038330078125 +53659 -0.145050048828125 +53660 -0.350555419921875 +53661 -0.10943603515625 +53662 -0.260528564453125 +53663 -0.07928466796875 +53664 -0.192108154296875 +53665 -0.0560302734375 +53666 -0.141937255859375 +53667 -0.038726806640625 +53668 -0.1021728515625 +53669 -0.024993896484375 +53670 -0.062896728515625 +53671 -0.011810302734375 +53672 -0.011932373046875 +53673 0.00457763671875 +53674 0.062835693359375 +53675 0.027923583984375 +53676 0.148712158203125 +53677 0.054290771484375 +53678 0.241729736328125 +53679 0.082489013671875 +53680 0.34912109375 +53681 0.11480712890625 +53682 0.457305908203125 +53683 0.1470947265625 +53684 0.54388427734375 +53685 0.172454833984375 +53686 0.5728759765625 +53687 0.17974853515625 +53688 0.506591796875 +53689 0.157318115234375 +53690 0.351226806640625 +53691 0.107208251953125 +53692 0.146514892578125 +53693 0.0418701171875 +53694 -0.05523681640625 +53695 -0.02227783203125 +53696 -0.21624755859375 +53697 -0.0733642578125 +53698 -0.334930419921875 +53699 -0.110870361328125 +53700 -0.402984619140625 +53701 -0.132171630859375 +53702 -0.4412841796875 +53703 -0.143798828125 +53704 -0.49578857421875 +53705 -0.160125732421875 +53706 -0.5601806640625 +53707 -0.179229736328125 +53708 -0.600738525390625 +53709 -0.190673828125 +53710 -0.584228515625 +53711 -0.18414306640625 +53712 -0.47930908203125 +53713 -0.149932861328125 +53714 -0.27935791015625 +53715 -0.086090087890625 +53716 -0.0089111328125 +53717 -0.000335693359375 +53718 0.268798828125 +53719 0.087493896484375 +53720 0.482818603515625 +53721 0.15521240234375 +53722 0.60369873046875 +53723 0.193603515625 +53724 0.650421142578125 +53725 0.208526611328125 +53726 0.66400146484375 +53727 0.2127685546875 +53728 0.6414794921875 +53729 0.2054443359375 +53730 0.572540283203125 +53731 0.183380126953125 +53732 0.498138427734375 +53733 0.15936279296875 +53734 0.439453125 +53735 0.14007568359375 +53736 0.375518798828125 +53737 0.1190185546875 +53738 0.274505615234375 +53739 0.086334228515625 +53740 0.1087646484375 +53741 0.033447265625 +53742 -0.099395751953125 +53743 -0.0325927734375 +53744 -0.3182373046875 +53745 -0.101806640625 +53746 -0.5489501953125 +53747 -0.174560546875 +53748 -0.7738037109375 +53749 -0.245269775390625 +53750 -0.86383056640625 +53751 -0.29736328125 +53752 -0.870391845703125 +53753 -0.320465087890625 +53754 -0.86895751953125 +53755 -0.32012939453125 +53756 -0.861053466796875 +53757 -0.300445556640625 +53758 -0.765869140625 +53759 -0.25604248046875 +53760 -0.5301513671875 +53761 -0.183563232421875 +53762 -0.214691162109375 +53763 -0.085784912109375 +53764 0.137359619140625 +53765 0.02398681640625 +53766 0.474822998046875 +53767 0.13037109375 +53768 0.76239013671875 +53769 0.2225341796875 +53770 0.867462158203125 +53771 0.292205810546875 +53772 0.870361328125 +53773 0.339019775390625 +53774 0.86480712890625 +53775 0.35943603515625 +53776 0.831817626953125 +53777 0.354827880859375 +53778 0.677581787109375 +53779 0.33209228515625 +53780 0.495880126953125 +53781 0.293060302734375 +53782 0.30767822265625 +53783 0.243255615234375 +53784 0.116180419921875 +53785 0.1837158203125 +53786 -0.110748291015625 +53787 0.106048583984375 +53788 -0.381805419921875 +53789 0.008880615234375 +53790 -0.6572265625 +53791 -0.095245361328125 +53792 -0.857421875 +53793 -0.188995361328125 +53794 -0.870391845703125 +53795 -0.2598876953125 +53796 -0.870391845703125 +53797 -0.3055419921875 +53798 -0.86444091796875 +53799 -0.33319091796875 +53800 -0.85723876953125 +53801 -0.352630615234375 +53802 -0.790008544921875 +53803 -0.358612060546875 +53804 -0.62847900390625 +53805 -0.335968017578125 +53806 -0.3956298828125 +53807 -0.283935546875 +53808 -0.126708984375 +53809 -0.211944580078125 +53810 0.150115966796875 +53811 -0.128021240234375 +53812 0.424041748046875 +53813 -0.035797119140625 +53814 0.670623779296875 +53815 0.056732177734375 +53816 0.854522705078125 +53817 0.1383056640625 +53818 0.866485595703125 +53819 0.20355224609375 +53820 0.86920166015625 +53821 0.247772216796875 +53822 0.8653564453125 +53823 0.27569580078125 +53824 0.857147216796875 +53825 0.290802001953125 +53826 0.766845703125 +53827 0.2921142578125 +53828 0.628509521484375 +53829 0.28094482421875 +53830 0.462127685546875 +53831 0.255401611328125 +53832 0.297210693359375 +53833 0.2227783203125 +53834 0.14862060546875 +53835 0.186737060546875 +53836 -0.00537109375 +53837 0.141082763671875 +53838 -0.15753173828125 +53839 0.088226318359375 +53840 -0.31304931640625 +53841 0.027496337890625 +53842 -0.48876953125 +53843 -0.044647216796875 +53844 -0.6416015625 +53845 -0.114715576171875 +53846 -0.751373291015625 +53847 -0.175445556640625 +53848 -0.84619140625 +53849 -0.233001708984375 +53850 -0.861297607421875 +53851 -0.28302001953125 +53852 -0.863250732421875 +53853 -0.316070556640625 +53854 -0.856597900390625 +53855 -0.32318115234375 +53856 -0.7498779296875 +53857 -0.307708740234375 +53858 -0.624542236328125 +53859 -0.285919189453125 +53860 -0.47808837890625 +53861 -0.251739501953125 +53862 -0.253387451171875 +53863 -0.188995361328125 +53864 0.003692626953125 +53865 -0.1107177734375 +53866 0.2257080078125 +53867 -0.03631591796875 +53868 0.427154541015625 +53869 0.037384033203125 +53870 0.643218994140625 +53871 0.119140625 +53872 0.855926513671875 +53873 0.205963134765625 +53874 0.870361328125 +53875 0.2813720703125 +53876 0.870361328125 +53877 0.33123779296875 +53878 0.862762451171875 +53879 0.357421875 +53880 0.79669189453125 +53881 0.358978271484375 +53882 0.595794677734375 +53883 0.333251953125 +53884 0.362152099609375 +53885 0.288421630859375 +53886 0.1270751953125 +53887 0.232421875 +53888 -0.086944580078125 +53889 0.171295166015625 +53890 -0.2784423828125 +53891 0.1058349609375 +53892 -0.484832763671875 +53893 0.026519775390625 +53894 -0.729583740234375 +53895 -0.07171630859375 +53896 -0.86688232421875 +53897 -0.174468994140625 +53898 -0.870391845703125 +53899 -0.263763427734375 +53900 -0.86859130859375 +53901 -0.33795166015625 +53902 -0.86279296875 +53903 -0.396209716796875 +53904 -0.817962646484375 +53905 -0.428314208984375 +53906 -0.6116943359375 +53907 -0.42144775390625 +53908 -0.3128662109375 +53909 -0.37353515625 +53910 0.039398193359375 +53911 -0.294036865234375 +53912 0.422821044921875 +53913 -0.1885986328125 +53914 0.805145263671875 +53915 -0.066650390625 +53916 0.870361328125 +53917 0.052520751953125 +53918 0.870361328125 +53919 0.152740478515625 +53920 0.860015869140625 +53921 0.23046875 +53922 0.727935791015625 +53923 0.2833251953125 +53924 0.48114013671875 +53925 0.3094482421875 +53926 0.2059326171875 +53927 0.315338134765625 +53928 -0.06103515625 +53929 0.307098388671875 +53930 -0.29913330078125 +53931 0.287384033203125 +53932 -0.516204833984375 +53933 0.251983642578125 +53934 -0.7252197265625 +53935 0.196502685546875 +53936 -0.85980224609375 +53937 0.1279296875 +53938 -0.870391845703125 +53939 0.055938720703125 +53940 -0.870391845703125 +53941 -0.011016845703125 +53942 -0.858062744140625 +53943 -0.05908203125 +53944 -0.673004150390625 +53945 -0.086822509765625 +53946 -0.42694091796875 +53947 -0.108642578125 +53948 -0.2100830078125 +53949 -0.136627197265625 +53950 -0.0362548828125 +53951 -0.16986083984375 +53952 0.10943603515625 +53953 -0.19989013671875 +53954 0.23516845703125 +53955 -0.220855712890625 +53956 0.373687744140625 +53957 -0.220977783203125 +53958 0.517791748046875 +53959 -0.20062255859375 +53960 0.602783203125 +53961 -0.1773681640625 +53962 0.635711669921875 +53963 -0.1497802734375 +53964 0.655181884765625 +53965 -0.10858154296875 +53966 0.65948486328125 +53967 -0.05670166015625 +53968 0.651275634765625 +53969 0.00335693359375 +53970 0.61846923828125 +53971 0.064483642578125 +53972 0.53753662109375 +53973 0.115997314453125 +53974 0.404144287109375 +53975 0.152557373046875 +53976 0.22186279296875 +53977 0.171142578125 +53978 0.003997802734375 +53979 0.171844482421875 +53980 -0.22100830078125 +53981 0.15948486328125 +53982 -0.42449951171875 +53983 0.139617919921875 +53984 -0.579833984375 +53985 0.118072509765625 +53986 -0.641876220703125 +53987 0.106719970703125 +53988 -0.6177978515625 +53989 0.103668212890625 +53990 -0.575531005859375 +53991 0.090911865234375 +53992 -0.526336669921875 +53993 0.067047119140625 +53994 -0.42645263671875 +53995 0.046783447265625 +53996 -0.2581787109375 +53997 0.0379638671875 +53998 -0.068695068359375 +53999 0.030670166015625 +54000 0.09222412109375 +54001 0.014373779296875 +54002 0.232147216796875 +54003 -0.00537109375 +54004 0.3509521484375 +54005 -0.025482177734375 +54006 0.410064697265625 +54007 -0.053985595703125 +54008 0.372955322265625 +54009 -0.098907470703125 +54010 0.2554931640625 +54011 -0.154205322265625 +54012 0.10711669921875 +54013 -0.205169677734375 +54014 -0.052886962890625 +54015 -0.24627685546875 +54016 -0.186279296875 +54017 -0.267791748046875 +54018 -0.23291015625 +54019 -0.254608154296875 +54020 -0.209442138671875 +54021 -0.21234130859375 +54022 -0.174163818359375 +54023 -0.158355712890625 +54024 -0.126739501953125 +54025 -0.09564208984375 +54026 -0.048126220703125 +54027 -0.022705078125 +54028 0.0426025390625 +54029 0.052490234375 +54030 0.10748291015625 +54031 0.117431640625 +54032 0.1409912109375 +54033 0.1680908203125 +54034 0.19708251953125 +54035 0.215789794921875 +54036 0.273651123046875 +54037 0.25836181640625 +54038 0.31768798828125 +54039 0.281585693359375 +54040 0.341094970703125 +54041 0.288116455078125 +54042 0.368011474609375 +54043 0.284332275390625 +54044 0.37249755859375 +54045 0.2646484375 +54046 0.30072021484375 +54047 0.217041015625 +54048 0.1517333984375 +54049 0.1431884765625 +54050 -0.01470947265625 +54051 0.06024169921875 +54052 -0.1883544921875 +54053 -0.02679443359375 +54054 -0.372711181640625 +54055 -0.116363525390625 +54056 -0.51397705078125 +54057 -0.192626953125 +54058 -0.57177734375 +54059 -0.243316650390625 +54060 -0.53948974609375 +54061 -0.264923095703125 +54062 -0.43511962890625 +54063 -0.26055908203125 +54064 -0.2962646484375 +54065 -0.2386474609375 +54066 -0.161102294921875 +54067 -0.208282470703125 +54068 -0.0435791015625 +54069 -0.17303466796875 +54070 0.060394287109375 +54071 -0.132476806640625 +54072 0.13665771484375 +54073 -0.0911865234375 +54074 0.170135498046875 +54075 -0.054351806640625 +54076 0.16552734375 +54077 -0.02252197265625 +54078 0.15728759765625 +54079 0.01092529296875 +54080 0.150787353515625 +54081 0.04534912109375 +54082 0.12200927734375 +54083 0.07275390625 +54084 0.080108642578125 +54085 0.093597412109375 +54086 0.05126953125 +54087 0.11279296875 +54088 0.062896728515625 +54089 0.135894775390625 +54090 0.09271240234375 +54091 0.156402587890625 +54092 0.092987060546875 +54093 0.161895751953125 +54094 0.07855224609375 +54095 0.156005859375 +54096 0.06427001953125 +54097 0.142791748046875 +54098 0.0347900390625 +54099 0.119110107421875 +54100 -0.01171875 +54101 0.085601806640625 +54102 -0.056060791015625 +54103 0.048431396484375 +54104 -0.055511474609375 +54105 0.01983642578125 +54106 -0.010467529296875 +54107 0.0013427734375 +54108 0.02508544921875 +54109 -0.01885986328125 +54110 0.025665283203125 +54111 -0.045562744140625 +54112 0.017333984375 +54113 -0.07086181640625 +54114 0.00189208984375 +54115 -0.0931396484375 +54116 -0.03173828125 +54117 -0.114288330078125 +54118 -0.071502685546875 +54119 -0.13079833984375 +54120 -0.13543701171875 +54121 -0.14697265625 +54122 -0.219970703125 +54123 -0.162109375 +54124 -0.300506591796875 +54125 -0.1705322265625 +54126 -0.376312255859375 +54127 -0.1728515625 +54128 -0.416107177734375 +54129 -0.162322998046875 +54130 -0.371124267578125 +54131 -0.12799072265625 +54132 -0.242279052734375 +54133 -0.0714111328125 +54134 -0.069732666015625 +54135 -0.003997802734375 +54136 0.125640869140625 +54137 0.06768798828125 +54138 0.31268310546875 +54139 0.1346435546875 +54140 0.45501708984375 +54141 0.186737060546875 +54142 0.554779052734375 +54143 0.223724365234375 +54144 0.61065673828125 +54145 0.2447509765625 +54146 0.610931396484375 +54147 0.246673583984375 +54148 0.531463623046875 +54149 0.2235107421875 +54150 0.3883056640625 +54151 0.1795654296875 +54152 0.23468017578125 +54153 0.128753662109375 +54154 0.095245361328125 +54155 0.07806396484375 +54156 -0.00396728515625 +54157 0.034942626953125 +54158 -0.04852294921875 +54159 0.0040283203125 +54160 -0.055145263671875 +54161 -0.0177001953125 +54162 -0.0758056640625 +54163 -0.042144775390625 +54164 -0.138702392578125 +54165 -0.0753173828125 +54166 -0.209197998046875 +54167 -0.107635498046875 +54168 -0.289031982421875 +54169 -0.138824462890625 +54170 -0.37884521484375 +54171 -0.16851806640625 +54172 -0.456329345703125 +54173 -0.190887451171875 +54174 -0.51641845703125 +54175 -0.204620361328125 +54176 -0.519287109375 +54177 -0.199951171875 +54178 -0.458251953125 +54179 -0.17559814453125 +54180 -0.384796142578125 +54181 -0.145050048828125 +54182 -0.323699951171875 +54183 -0.115234375 +54184 -0.269287109375 +54185 -0.085601806640625 +54186 -0.1951904296875 +54187 -0.050506591796875 +54188 -0.100006103515625 +54189 -0.010498046875 +54190 -0.01055908203125 +54191 0.02679443359375 +54192 0.1033935546875 +54193 0.06817626953125 +54194 0.24908447265625 +54195 0.11480712890625 +54196 0.373199462890625 +54197 0.15289306640625 +54198 0.45806884765625 +54199 0.177734375 +54200 0.511474609375 +54201 0.191131591796875 +54202 0.565399169921875 +54203 0.201202392578125 +54204 0.61138916015625 +54205 0.20611572265625 +54206 0.5897216796875 +54207 0.19140625 +54208 0.4906005859375 +54209 0.15521240234375 +54210 0.33148193359375 +54211 0.102569580078125 +54212 0.147796630859375 +54213 0.043060302734375 +54214 -0.01873779296875 +54215 -0.0120849609375 +54216 -0.140289306640625 +54217 -0.05517578125 +54218 -0.191986083984375 +54219 -0.079315185546875 +54220 -0.184295654296875 +54221 -0.086578369140625 +54222 -0.161834716796875 +54223 -0.087677001953125 +54224 -0.166595458984375 +54225 -0.0927734375 +54226 -0.19390869140625 +54227 -0.1005859375 +54228 -0.22442626953125 +54229 -0.1063232421875 +54230 -0.279754638671875 +54231 -0.115570068359375 +54232 -0.3389892578125 +54233 -0.1234130859375 +54234 -0.3543701171875 +54235 -0.118377685546875 +54236 -0.348175048828125 +54237 -0.1065673828125 +54238 -0.32598876953125 +54239 -0.0899658203125 +54240 -0.2581787109375 +54241 -0.061798095703125 +54242 -0.139801025390625 +54243 -0.02142333984375 +54244 0.014617919921875 +54245 0.02691650390625 +54246 0.144378662109375 +54247 0.067535400390625 +54248 0.221038818359375 +54249 0.092926025390625 +54250 0.27069091796875 +54251 0.10931396484375 +54252 0.294036865234375 +54253 0.11676025390625 +54254 0.311767578125 +54255 0.12042236328125 +54256 0.339141845703125 +54257 0.12420654296875 +54258 0.360260009765625 +54259 0.12432861328125 +54260 0.360504150390625 +54261 0.11749267578125 +54262 0.308380126953125 +54263 0.0963134765625 +54264 0.18170166015625 +54265 0.0557861328125 +54266 0.0047607421875 +54267 0.00250244140625 +54268 -0.17559814453125 +54269 -0.0513916015625 +54270 -0.3143310546875 +54271 -0.09423828125 +54272 -0.36785888671875 +54273 -0.11517333984375 +54274 -0.36248779296875 +54275 -0.119964599609375 +54276 -0.343536376953125 +54277 -0.11895751953125 +54278 -0.3018798828125 +54279 -0.110321044921875 +54280 -0.231414794921875 +54281 -0.092926025390625 +54282 -0.117645263671875 +54283 -0.063934326171875 +54284 0.007049560546875 +54285 -0.030731201171875 +54286 0.087982177734375 +54287 -0.005523681640625 +54288 0.13946533203125 +54289 0.0142822265625 +54290 0.17425537109375 +54291 0.03094482421875 +54292 0.188201904296875 +54293 0.0430908203125 +54294 0.171234130859375 +54295 0.048065185546875 +54296 0.118438720703125 +54297 0.04437255859375 +54298 0.05706787109375 +54299 0.037567138671875 +54300 -0.010711669921875 +54301 0.02777099609375 +54302 -0.0914306640625 +54303 0.01336669921875 +54304 -0.162322998046875 +54305 -0.00079345703125 +54306 -0.194549560546875 +54307 -0.008514404296875 +54308 -0.1492919921875 +54309 -0.00128173828125 +54310 -0.02166748046875 +54311 0.022125244140625 +54312 0.124053955078125 +54313 0.048095703125 +54314 0.211151123046875 +54315 0.06036376953125 +54316 0.240447998046875 +54317 0.059539794921875 +54318 0.242218017578125 +54319 0.05255126953125 +54320 0.2257080078125 +54321 0.04180908203125 +54322 0.194366455078125 +54323 0.0284423828125 +54324 0.115509033203125 +54325 0.0057373046875 +54326 0.0128173828125 +54327 -0.020843505859375 +54328 -0.053802490234375 +54329 -0.038177490234375 +54330 -0.110626220703125 +54331 -0.05181884765625 +54332 -0.199493408203125 +54333 -0.070770263671875 +54334 -0.29437255859375 +54335 -0.089508056640625 +54336 -0.33221435546875 +54337 -0.09454345703125 +54338 -0.27972412109375 +54339 -0.07891845703125 +54340 -0.185333251953125 +54341 -0.053314208984375 +54342 -0.128204345703125 +54343 -0.03515625 +54344 -0.115692138671875 +54345 -0.0263671875 +54346 -0.116455078125 +54347 -0.0205078125 +54348 -0.105926513671875 +54349 -0.01263427734375 +54350 -0.053955078125 +54351 0.003448486328125 +54352 0.048797607421875 +54353 0.029541015625 +54354 0.157318115234375 +54355 0.05572509765625 +54356 0.212005615234375 +54357 0.069000244140625 +54358 0.218475341796875 +54359 0.070556640625 +54360 0.23724365234375 +54361 0.073516845703125 +54362 0.30535888671875 +54363 0.085968017578125 +54364 0.38128662109375 +54365 0.09906005859375 +54366 0.404449462890625 +54367 0.09991455078125 +54368 0.3944091796875 +54369 0.093017578125 +54370 0.3885498046875 +54371 0.086700439453125 +54372 0.362640380859375 +54373 0.0760498046875 +54374 0.27362060546875 +54375 0.052032470703125 +54376 0.11712646484375 +54377 0.01397705078125 +54378 -0.054901123046875 +54379 -0.026641845703125 +54380 -0.19085693359375 +54381 -0.05853271484375 +54382 -0.28570556640625 +54383 -0.08050537109375 +54384 -0.339263916015625 +54385 -0.092437744140625 +54386 -0.3775634765625 +54387 -0.100006103515625 +54388 -0.445709228515625 +54389 -0.113006591796875 +54390 -0.535064697265625 +54391 -0.12969970703125 +54392 -0.629058837890625 +54393 -0.14666748046875 +54394 -0.697601318359375 +54395 -0.1575927734375 +54396 -0.70391845703125 +54397 -0.15478515625 +54398 -0.6424560546875 +54399 -0.13726806640625 +54400 -0.491241455078125 +54401 -0.100555419921875 +54402 -0.265716552734375 +54403 -0.0482177734375 +54404 -0.023712158203125 +54405 0.007049560546875 +54406 0.201751708984375 +54407 0.058013916015625 +54408 0.375823974609375 +54409 0.097015380859375 +54410 0.485076904296875 +54411 0.12109375 +54412 0.56884765625 +54413 0.138763427734375 +54414 0.634765625 +54415 0.151702880859375 +54416 0.63763427734375 +54417 0.1502685546875 +54418 0.5660400390625 +54419 0.132110595703125 +54420 0.4720458984375 +54421 0.108642578125 +54422 0.40692138671875 +54423 0.091156005859375 +54424 0.3778076171875 +54425 0.08135986328125 +54426 0.376953125 +54427 0.0777587890625 +54428 0.371978759765625 +54429 0.07354736328125 +54430 0.313140869140625 +54431 0.05816650390625 +54432 0.184417724609375 +54433 0.028289794921875 +54434 0.011199951171875 +54435 -0.010498046875 +54436 -0.171051025390625 +54437 -0.050445556640625 +54438 -0.33740234375 +54439 -0.086181640625 +54440 -0.47198486328125 +54441 -0.114288330078125 +54442 -0.560394287109375 +54443 -0.131744384765625 +54444 -0.58056640625 +54445 -0.133880615234375 +54446 -0.54754638671875 +54447 -0.124114990234375 +54448 -0.508575439453125 +54449 -0.112823486328125 +54450 -0.459503173828125 +54451 -0.099273681640625 +54452 -0.394378662109375 +54453 -0.08233642578125 +54454 -0.35260009765625 +54455 -0.07061767578125 +54456 -0.31170654296875 +54457 -0.0594482421875 +54458 -0.197418212890625 +54459 -0.03289794921875 +54460 -0.007965087890625 +54461 0.009307861328125 +54462 0.207489013671875 +54463 0.05645751953125 +54464 0.409210205078125 +54465 0.0999755859375 +54466 0.57208251953125 +54467 0.134490966796875 +54468 0.66595458984375 +54469 0.153533935546875 +54470 0.65875244140625 +54471 0.150238037109375 +54472 0.56744384765625 +54473 0.12841796875 +54474 0.431396484375 +54475 0.0966796875 +54476 0.29443359375 +54477 0.064605712890625 +54478 0.182464599609375 +54479 0.037933349609375 +54480 0.06365966796875 +54481 0.009918212890625 +54482 -0.075958251953125 +54483 -0.02227783203125 +54484 -0.189422607421875 +54485 -0.048431396484375 +54486 -0.271942138671875 +54487 -0.0673828125 +54488 -0.342529296875 +54489 -0.083221435546875 +54490 -0.364166259765625 +54491 -0.08795166015625 +54492 -0.327239990234375 +54493 -0.079498291015625 +54494 -0.2769775390625 +54495 -0.06768798828125 +54496 -0.253692626953125 +54497 -0.061279296875 +54498 -0.24365234375 +54499 -0.057373046875 +54500 -0.1983642578125 +54501 -0.045654296875 +54502 -0.116241455078125 +54503 -0.025848388671875 +54504 -0.036834716796875 +54505 -0.006622314453125 +54506 0.034881591796875 +54507 0.01080322265625 +54508 0.09124755859375 +54509 0.024688720703125 +54510 0.10888671875 +54511 0.029876708984375 +54512 0.125518798828125 +54513 0.03448486328125 +54514 0.15771484375 +54515 0.042022705078125 +54516 0.17828369140625 +54517 0.046600341796875 +54518 0.17108154296875 +54519 0.04473876953125 +54520 0.129974365234375 +54521 0.035125732421875 +54522 0.082427978515625 +54523 0.02374267578125 +54524 0.027679443359375 +54525 0.010498046875 +54526 -0.065643310546875 +54527 -0.01123046875 +54528 -0.15936279296875 +54529 -0.033477783203125 +54530 -0.21307373046875 +54531 -0.047027587890625 +54532 -0.234649658203125 +54533 -0.0528564453125 +54534 -0.2001953125 +54535 -0.046875 +54536 -0.119171142578125 +54537 -0.03118896484375 +54538 -0.024749755859375 +54539 -0.01220703125 +54540 0.085784912109375 +54541 0.01025390625 +54542 0.178131103515625 +54543 0.029571533203125 +54544 0.215576171875 +54545 0.038818359375 +54546 0.211456298828125 +54547 0.040252685546875 +54548 0.17523193359375 +54549 0.0355224609375 +54550 0.128753662109375 +54551 0.028533935546875 +54552 0.1019287109375 +54553 0.02471923828125 +54554 0.0743408203125 +54555 0.020294189453125 +54556 0.04327392578125 +54557 0.0147705078125 +54558 0.038177490234375 +54559 0.0135498046875 +54560 0.076263427734375 +54561 0.019866943359375 +54562 0.14105224609375 +54563 0.030731201171875 +54564 0.186431884765625 +54565 0.03778076171875 +54566 0.188812255859375 +54567 0.0367431640625 +54568 0.1390380859375 +54569 0.026031494140625 +54570 0.041778564453125 +54571 0.006622314453125 +54572 -0.079437255859375 +54573 -0.017059326171875 +54574 -0.219390869140625 +54575 -0.04400634765625 +54576 -0.367828369140625 +54577 -0.072235107421875 +54578 -0.494873046875 +54579 -0.09619140625 +54580 -0.556243896484375 +54581 -0.10772705078125 +54582 -0.508697509765625 +54583 -0.098876953125 +54584 -0.3756103515625 +54585 -0.073974609375 +54586 -0.218902587890625 +54587 -0.044464111328125 +54588 -0.063751220703125 +54589 -0.0150146484375 +54590 0.091552734375 +54591 0.01458740234375 +54592 0.23602294921875 +54593 0.042236328125 +54594 0.342987060546875 +54595 0.06298828125 +54596 0.39520263671875 +54597 0.07366943359375 +54598 0.389373779296875 +54599 0.073577880859375 +54600 0.324249267578125 +54601 0.06243896484375 +54602 0.224090576171875 +54603 0.044708251953125 +54604 0.124267578125 +54605 0.026824951171875 +54606 0.037078857421875 +54607 0.01104736328125 +54608 -0.010101318359375 +54609 0.00238037109375 +54610 -0.019439697265625 +54611 0.000457763671875 +54612 -0.022796630859375 +54613 -0.00054931640625 +54614 -0.001556396484375 +54615 0.002777099609375 +54616 0.056304931640625 +54617 0.012664794921875 +54618 0.106719970703125 +54619 0.02105712890625 +54620 0.096893310546875 +54621 0.018310546875 +54622 0.042694091796875 +54623 0.007415771484375 +54624 -0.018035888671875 +54625 -0.004608154296875 +54626 -0.07586669921875 +54627 -0.015960693359375 +54628 -0.11944580078125 +54629 -0.024505615234375 +54630 -0.15972900390625 +54631 -0.032257080078125 +54632 -0.202606201171875 +54633 -0.040283203125 +54634 -0.24859619140625 +54635 -0.048675537109375 +54636 -0.30517578125 +54637 -0.058807373046875 +54638 -0.36212158203125 +54639 -0.06884765625 +54640 -0.39141845703125 +54641 -0.07366943359375 +54642 -0.35528564453125 +54643 -0.06634521484375 +54644 -0.249969482421875 +54645 -0.046234130859375 +54646 -0.092864990234375 +54647 -0.016571044921875 +54648 0.08905029296875 +54649 0.017578125 +54650 0.2352294921875 +54651 0.045074462890625 +54652 0.318817138671875 +54653 0.060943603515625 +54654 0.358642578125 +54655 0.068603515625 +54656 0.347747802734375 +54657 0.0667724609375 +54658 0.28564453125 +54659 0.05535888671875 +54660 0.223175048828125 +54661 0.043731689453125 +54662 0.196746826171875 +54663 0.038604736328125 +54664 0.179840087890625 +54665 0.035125732421875 +54666 0.155548095703125 +54667 0.030181884765625 +54668 0.151214599609375 +54669 0.028839111328125 +54670 0.156951904296875 +54671 0.029327392578125 +54672 0.13177490234375 +54673 0.02410888671875 +54674 0.100799560546875 +54675 0.017852783203125 +54676 0.087127685546875 +54677 0.01483154296875 +54678 0.05487060546875 +54679 0.00848388671875 +54680 -0.009002685546875 +54681 -0.003570556640625 +54682 -0.10400390625 +54683 -0.02117919921875 +54684 -0.229400634765625 +54685 -0.04425048828125 +54686 -0.35552978515625 +54687 -0.06732177734375 +54688 -0.441925048828125 +54689 -0.08294677734375 +54690 -0.473846435546875 +54691 -0.08843994140625 +54692 -0.464813232421875 +54693 -0.0863037109375 +54694 -0.419097900390625 +54695 -0.077362060546875 +54696 -0.334320068359375 +54697 -0.06121826171875 +54698 -0.227935791015625 +54699 -0.041107177734375 +54700 -0.12347412109375 +54701 -0.021392822265625 +54702 -0.02764892578125 +54703 -0.003326416015625 +54704 0.077667236328125 +54705 0.016387939453125 +54706 0.2132568359375 +54707 0.04156494140625 +54708 0.38885498046875 +54709 0.073944091796875 +54710 0.582794189453125 +54711 0.10955810546875 +54712 0.734039306640625 +54713 0.13720703125 +54714 0.800140380859375 +54715 0.1490478515625 +54716 0.7783203125 +54717 0.144622802734375 +54718 0.6651611328125 +54719 0.123291015625 +54720 0.45965576171875 +54721 0.084930419921875 +54722 0.199188232421875 +54723 0.0364990234375 +54724 -0.050689697265625 +54725 -0.009918212890625 +54726 -0.23297119140625 +54727 -0.0438232421875 +54728 -0.33013916015625 +54729 -0.06195068359375 +54730 -0.368408203125 +54731 -0.06915283203125 +54732 -0.378936767578125 +54733 -0.0711669921875 +54734 -0.376983642578125 +54735 -0.07080078125 +54736 -0.37969970703125 +54737 -0.07122802734375 +54738 -0.391510009765625 +54739 -0.073211669921875 +54740 -0.385345458984375 +54741 -0.071807861328125 +54742 -0.3419189453125 +54743 -0.0634765625 +54744 -0.28289794921875 +54745 -0.052215576171875 +54746 -0.251617431640625 +54747 -0.0460205078125 +54748 -0.266143798828125 +54749 -0.048248291015625 +54750 -0.273345947265625 +54751 -0.04913330078125 +54752 -0.216796875 +54753 -0.038360595703125 +54754 -0.128265380859375 +54755 -0.021759033203125 +54756 -0.068145751953125 +54757 -0.01043701171875 +54758 -0.0430908203125 +54759 -0.005645751953125 +54760 -0.024444580078125 +54761 -0.00213623046875 +54762 0.020721435546875 +54763 0.006103515625 +54764 0.124481201171875 +54765 0.024993896484375 +54766 0.25787353515625 +54767 0.049224853515625 +54768 0.379119873046875 +54769 0.071136474609375 +54770 0.47991943359375 +54771 0.0892333984375 +54772 0.5281982421875 +54773 0.097625732421875 +54774 0.511138916015625 +54775 0.093994140625 +54776 0.456207275390625 +54777 0.083404541015625 +54778 0.407470703125 +54779 0.074005126953125 +54780 0.383758544921875 +54781 0.06927490234375 +54782 0.35687255859375 +54783 0.06402587890625 +54784 0.31182861328125 +54785 0.05499267578125 +54786 0.250885009765625 +54787 0.042327880859375 +54788 0.1654052734375 +54789 0.02508544921875 +54790 0.035247802734375 +54791 0.000701904296875 +54792 -0.142059326171875 +54793 -0.030731201171875 +54794 -0.33563232421875 +54795 -0.064117431640625 +54796 -0.5345458984375 +54797 -0.097503662109375 +54798 -0.72186279296875 +54799 -0.128082275390625 +54800 -0.836669921875 +54801 -0.146484375 +54802 -0.8326416015625 +54803 -0.145599365234375 +54804 -0.7296142578125 +54805 -0.1285400390625 +54806 -0.582550048828125 +54807 -0.103790283203125 +54808 -0.440093994140625 +54809 -0.078857421875 +54810 -0.324310302734375 +54811 -0.057342529296875 +54812 -0.20147705078125 +54813 -0.034332275390625 +54814 -0.044647216796875 +54815 -0.0059814453125 +54816 0.103973388671875 +54817 0.02099609375 +54818 0.202392578125 +54819 0.03997802734375 +54820 0.264495849609375 +54821 0.052825927734375 +54822 0.338897705078125 +54823 0.066741943359375 +54824 0.443817138671875 +54825 0.084381103515625 +54826 0.545074462890625 +54827 0.100494384765625 +54828 0.6173095703125 +54829 0.1112060546875 +54830 0.6524658203125 +54831 0.1153564453125 +54832 0.66339111328125 +54833 0.114959716796875 +54834 0.6561279296875 +54835 0.111053466796875 +54836 0.606781005859375 +54837 0.10015869140625 +54838 0.501190185546875 +54839 0.080352783203125 +54840 0.352783203125 +54841 0.053924560546875 +54842 0.176544189453125 +54843 0.023345947265625 +54844 -0.034820556640625 +54845 -0.01226806640625 +54846 -0.258209228515625 +54847 -0.0491943359375 +54848 -0.44244384765625 +54849 -0.079498291015625 +54850 -0.5753173828125 +54851 -0.101226806640625 +54852 -0.65203857421875 +54853 -0.11358642578125 +54854 -0.641632080078125 +54855 -0.11187744140625 +54856 -0.562164306640625 +54857 -0.098907470703125 +54858 -0.458038330078125 +54859 -0.08148193359375 +54860 -0.350555419921875 +54861 -0.062896728515625 +54862 -0.260528564453125 +54863 -0.046478271484375 +54864 -0.192108154296875 +54865 -0.03302001953125 +54866 -0.141937255859375 +54867 -0.022186279296875 +54868 -0.1021728515625 +54869 -0.012969970703125 +54870 -0.062896728515625 +54871 -0.0040283203125 +54872 -0.011932373046875 +54873 0.00628662109375 +54874 0.062835693359375 +54875 0.01971435546875 +54876 0.148712158203125 +54877 0.03424072265625 +54878 0.241729736328125 +54879 0.0491943359375 +54880 0.34912109375 +54881 0.065643310546875 +54882 0.457305908203125 +54883 0.081512451171875 +54884 0.54388427734375 +54885 0.093475341796875 +54886 0.5728759765625 +54887 0.09613037109375 +54888 0.506591796875 +54889 0.0838623046875 +54890 0.351226806640625 +54891 0.0577392578125 +54892 0.146514892578125 +54893 0.02392578125 +54894 -0.05523681640625 +54895 -0.009429931640625 +54896 -0.21624755859375 +54897 -0.036407470703125 +54898 -0.334930419921875 +54899 -0.056640625 +54900 -0.402984619140625 +54901 -0.068756103515625 +54902 -0.4412841796875 +54903 -0.07586669921875 +54904 -0.49578857421875 +54905 -0.08489990234375 +54906 -0.5601806640625 +54907 -0.0948486328125 +54908 -0.600738525390625 +54909 -0.100616455078125 +54910 -0.584228515625 +54911 -0.097198486328125 +54912 -0.47930908203125 +54913 -0.07989501953125 +54914 -0.27935791015625 +54915 -0.04779052734375 +54916 -0.0089111328125 +54917 -0.004730224609375 +54918 0.268798828125 +54919 0.039581298828125 +54920 0.482818603515625 +54921 0.074188232421875 +54922 0.60369873046875 +54923 0.09454345703125 +54924 0.650421142578125 +54925 0.1033935546875 +54926 0.66400146484375 +54927 0.10687255859375 +54928 0.6414794921875 +54929 0.1044921875 +54930 0.572540283203125 +54931 0.094635009765625 +54932 0.498138427734375 +54933 0.083526611328125 +54934 0.439453125 +54935 0.074371337890625 +54936 0.375518798828125 +54937 0.06402587890625 +54938 0.274505615234375 +54939 0.04766845703125 +54940 0.1087646484375 +54941 0.02117919921875 +54942 -0.099395751953125 +54943 -0.011932373046875 +54944 -0.3182373046875 +54945 -0.0467529296875 +54946 -0.5489501953125 +54947 -0.083404541015625 +54948 -0.7738037109375 +54949 -0.11907958984375 +54950 -0.86383056640625 +54951 -0.1456298828125 +54952 -0.870391845703125 +54953 -0.157958984375 +54954 -0.86895751953125 +54955 -0.158721923828125 +54956 -0.861053466796875 +54957 -0.14990234375 +54958 -0.765869140625 +54959 -0.12884521484375 +54960 -0.5301513671875 +54961 -0.09381103515625 +54962 -0.214691162109375 +54963 -0.0458984375 +54964 0.137359619140625 +54965 0.008270263671875 +54966 0.474822998046875 +54967 0.060882568359375 +54968 0.76239013671875 +54969 0.10650634765625 +54970 0.867462158203125 +54971 0.140960693359375 +54972 0.870361328125 +54973 0.16424560546875 +54974 0.86480712890625 +54975 0.17449951171875 +54976 0.831817626953125 +54977 0.1724853515625 +54978 0.677581787109375 +54979 0.161865234375 +54980 0.495880126953125 +54981 0.14349365234375 +54982 0.30767822265625 +54983 0.12017822265625 +54984 0.116180419921875 +54985 0.092193603515625 +54986 -0.110748291015625 +54987 0.05474853515625 +54988 -0.381805419921875 +54989 0.006805419921875 +54990 -0.6572265625 +54991 -0.04510498046875 +54992 -0.857421875 +54993 -0.09185791015625 +54994 -0.870391845703125 +54995 -0.12689208984375 +54996 -0.870391845703125 +54997 -0.149078369140625 +54998 -0.86444091796875 +54999 -0.162445068359375 +55000 -0.85723876953125 +55001 -0.172393798828125 +55002 -0.790008544921875 +55003 -0.17608642578125 +55004 -0.62847900390625 +55005 -0.165252685546875 +55006 -0.3956298828125 +55007 -0.139373779296875 +55008 -0.126708984375 +55009 -0.1033935546875 +55010 0.150115966796875 +55011 -0.061431884765625 +55012 0.424041748046875 +55013 -0.015289306640625 +55014 0.670623779296875 +55015 0.0308837890625 +55016 0.854522705078125 +55017 0.07122802734375 +55018 0.866485595703125 +55019 0.10302734375 +55020 0.86920166015625 +55021 0.1239013671875 +55022 0.8653564453125 +55023 0.1365966796875 +55024 0.857147216796875 +55025 0.143157958984375 +55026 0.766845703125 +55027 0.14306640625 +55028 0.628509521484375 +55029 0.1370849609375 +55030 0.462127685546875 +55031 0.1241455078125 +55032 0.297210693359375 +55033 0.108123779296875 +55034 0.14862060546875 +55035 0.09088134765625 +55036 -0.00537109375 +55037 0.06890869140625 +55038 -0.15753173828125 +55039 0.043365478515625 +55040 -0.31304931640625 +55041 0.01416015625 +55042 -0.48876953125 +55043 -0.020721435546875 +55044 -0.6416015625 +55045 -0.05548095703125 +55046 -0.751373291015625 +55047 -0.08636474609375 +55048 -0.84619140625 +55049 -0.115478515625 +55050 -0.861297607421875 +55051 -0.1405029296875 +55052 -0.863250732421875 +55053 -0.1571044921875 +55054 -0.856597900390625 +55055 -0.161224365234375 +55056 -0.7498779296875 +55057 -0.15423583984375 +55058 -0.624542236328125 +55059 -0.143096923828125 +55060 -0.47808837890625 +55061 -0.125396728515625 +55062 -0.253387451171875 +55063 -0.094390869140625 +55064 0.003692626953125 +55065 -0.05596923828125 +55066 0.2257080078125 +55067 -0.018768310546875 +55068 0.427154541015625 +55069 0.01824951171875 +55070 0.643218994140625 +55071 0.058502197265625 +55072 0.855926513671875 +55073 0.100433349609375 +55074 0.870361328125 +55075 0.13665771484375 +55076 0.870361328125 +55077 0.16094970703125 +55078 0.862762451171875 +55079 0.1739501953125 +55080 0.79669189453125 +55081 0.17523193359375 +55082 0.595794677734375 +55083 0.16363525390625 +55084 0.362152099609375 +55085 0.1427001953125 +55086 0.1270751953125 +55087 0.115997314453125 +55088 -0.086944580078125 +55089 0.0863037109375 +55090 -0.2784423828125 +55091 0.05413818359375 +55092 -0.484832763671875 +55093 0.01568603515625 +55094 -0.729583740234375 +55095 -0.030975341796875 +55096 -0.86688232421875 +55097 -0.07940673828125 +55098 -0.870391845703125 +55099 -0.121673583984375 +55100 -0.86859130859375 +55101 -0.156829833984375 +55102 -0.86279296875 +55103 -0.18438720703125 +55104 -0.817962646484375 +55105 -0.199859619140625 +55106 -0.6116943359375 +55107 -0.197662353515625 +55108 -0.3128662109375 +55109 -0.176910400390625 +55110 0.039398193359375 +55111 -0.141693115234375 +55112 0.422821044921875 +55113 -0.09454345703125 +55114 0.805145263671875 +55115 -0.03961181640625 +55116 0.870361328125 +55117 0.014617919921875 +55118 0.870361328125 +55119 0.061065673828125 +55120 0.860015869140625 +55121 0.0980224609375 +55122 0.727935791015625 +55123 0.124267578125 +55124 0.48114013671875 +55125 0.1387939453125 +55126 0.2059326171875 +55127 0.144195556640625 +55128 -0.06103515625 +55129 0.142974853515625 +55130 -0.29913330078125 +55131 0.136138916015625 +55132 -0.516204833984375 +55133 0.121856689453125 +55134 -0.7252197265625 +55135 0.098236083984375 +55136 -0.85980224609375 +55137 0.0682373046875 +55138 -0.870391845703125 +55139 0.03607177734375 +55140 -0.870391845703125 +55141 0.005401611328125 +55142 -0.858062744140625 +55143 -0.01763916015625 +55144 -0.673004150390625 +55145 -0.03228759765625 +55146 -0.42694091796875 +55147 -0.04461669921875 +55148 -0.2100830078125 +55149 -0.05963134765625 +55150 -0.0362548828125 +55151 -0.07672119140625 +55152 0.10943603515625 +55153 -0.092132568359375 +55154 0.23516845703125 +55155 -0.10321044921875 +55156 0.373687744140625 +55157 -0.10479736328125 +55158 0.517791748046875 +55159 -0.097015380859375 +55160 0.602783203125 +55161 -0.08734130859375 +55162 0.635711669921875 +55163 -0.075164794921875 +55164 0.655181884765625 +55165 -0.056549072265625 +55166 0.65948486328125 +55167 -0.0328369140625 +55168 0.651275634765625 +55169 -0.005157470703125 +55170 0.61846923828125 +55171 0.023284912109375 +55172 0.53753662109375 +55173 0.047760009765625 +55174 0.404144287109375 +55175 0.065887451171875 +55176 0.22186279296875 +55177 0.07623291015625 +55178 0.003997802734375 +55179 0.07867431640625 +55180 -0.22100830078125 +55181 0.0751953125 +55182 -0.42449951171875 +55183 0.068084716796875 +55184 -0.579833984375 +55185 0.059783935546875 +55186 -0.641876220703125 +55187 0.055328369140625 +55188 -0.6177978515625 +55189 0.053924560546875 +55190 -0.575531005859375 +55191 0.0478515625 +55192 -0.526336669921875 +55193 0.03656005859375 +55194 -0.42645263671875 +55195 0.026397705078125 +55196 -0.2581787109375 +55197 0.02081298828125 +55198 -0.068695068359375 +55199 0.01568603515625 +55200 0.09222412109375 +55201 0.006622314453125 +55202 0.232147216796875 +55203 -0.003875732421875 +55204 0.3509521484375 +55205 -0.014373779296875 +55206 0.410064697265625 +55207 -0.0281982421875 +55208 0.372955322265625 +55209 -0.0487060546875 +55210 0.2554931640625 +55211 -0.073272705078125 +55212 0.10711669921875 +55213 -0.095550537109375 +55214 -0.052886962890625 +55215 -0.11309814453125 +55216 -0.186279296875 +55217 -0.12164306640625 +55218 -0.23291015625 +55219 -0.114532470703125 +55220 -0.209442138671875 +55221 -0.0946044921875 +55222 -0.174163818359375 +55223 -0.0699462890625 +55224 -0.126739501953125 +55225 -0.041748046875 +55226 -0.048126220703125 +55227 -0.009002685546875 +55228 0.0426025390625 +55229 0.024688720703125 +55230 0.10748291015625 +55231 0.053558349609375 +55232 0.1409912109375 +55233 0.075836181640625 +55234 0.19708251953125 +55235 0.097076416015625 +55236 0.273651123046875 +55237 0.1163330078125 +55238 0.31768798828125 +55239 0.126861572265625 +55240 0.341094970703125 +55241 0.12994384765625 +55242 0.368011474609375 +55243 0.128570556640625 +55244 0.37249755859375 +55245 0.120025634765625 +55246 0.30072021484375 +55247 0.098480224609375 +55248 0.1517333984375 +55249 0.06463623046875 +55250 -0.01470947265625 +55251 0.026641845703125 +55252 -0.1883544921875 +55253 -0.013214111328125 +55254 -0.372711181640625 +55255 -0.054290771484375 +55256 -0.51397705078125 +55257 -0.089080810546875 +55258 -0.57177734375 +55259 -0.11181640625 +55260 -0.53948974609375 +55261 -0.120880126953125 +55262 -0.43511962890625 +55263 -0.11785888671875 +55264 -0.2962646484375 +55265 -0.106842041015625 +55266 -0.161102294921875 +55267 -0.092193603515625 +55268 -0.0435791015625 +55269 -0.07562255859375 +55270 0.060394287109375 +55271 -0.056884765625 +55272 0.13665771484375 +55273 -0.03814697265625 +55274 0.170135498046875 +55275 -0.021820068359375 +55276 0.16552734375 +55277 -0.008056640625 +55278 0.15728759765625 +55279 0.006378173828125 +55280 0.150787353515625 +55281 0.021270751953125 +55282 0.12200927734375 +55283 0.03289794921875 +55284 0.080108642578125 +55285 0.04150390625 +55286 0.05126953125 +55287 0.049560546875 +55288 0.062896728515625 +55289 0.059783935546875 +55290 0.09271240234375 +55291 0.069091796875 +55292 0.092987060546875 +55293 0.071533203125 +55294 0.07855224609375 +55295 0.06884765625 +55296 0.06427001953125 +55297 0.0631103515625 +55298 0.0347900390625 +55299 0.052764892578125 +55300 -0.01171875 +55301 0.037933349609375 +55302 -0.056060791015625 +55303 0.02130126953125 +55304 -0.055511474609375 +55305 0.007965087890625 +55306 -0.010467529296875 +55307 -0.001251220703125 +55308 0.02508544921875 +55309 -0.01092529296875 +55310 0.025665283203125 +55311 -0.02288818359375 +55312 0.017333984375 +55313 -0.033905029296875 +55314 0.00189208984375 +55315 -0.043304443359375 +55316 -0.03173828125 +55317 -0.05181884765625 +55318 -0.071502685546875 +55319 -0.058074951171875 +55320 -0.13543701171875 +55321 -0.0638427734375 +55322 -0.219970703125 +55323 -0.06890869140625 +55324 -0.300506591796875 +55325 -0.071014404296875 +55326 -0.376312255859375 +55327 -0.070526123046875 +55328 -0.416107177734375 +55329 -0.064849853515625 +55330 -0.371124267578125 +55331 -0.049652099609375 +55332 -0.242279052734375 +55333 -0.025665283203125 +55334 -0.069732666015625 +55335 0.00244140625 +55336 0.125640869140625 +55337 0.031982421875 +55338 0.31268310546875 +55339 0.059356689453125 +55340 0.45501708984375 +55341 0.0804443359375 +55342 0.554779052734375 +55343 0.09515380859375 +55344 0.61065673828125 +55345 0.1031494140625 +55346 0.610931396484375 +55347 0.10321044921875 +55348 0.531463623046875 +55349 0.093017578125 +55350 0.3883056640625 +55351 0.0743408203125 +55352 0.23468017578125 +55353 0.05279541015625 +55354 0.095245361328125 +55355 0.031280517578125 +55356 -0.00396728515625 +55357 0.012847900390625 +55358 -0.04852294921875 +55359 -0.000579833984375 +55360 -0.055145263671875 +55361 -0.01019287109375 +55362 -0.0758056640625 +55363 -0.020660400390625 +55364 -0.138702392578125 +55365 -0.03436279296875 +55366 -0.209197998046875 +55367 -0.047454833984375 +55368 -0.289031982421875 +55369 -0.059844970703125 +55370 -0.37884521484375 +55371 -0.0714111328125 +55372 -0.456329345703125 +55373 -0.079833984375 +55374 -0.51641845703125 +55375 -0.084625244140625 +55376 -0.519287109375 +55377 -0.0819091796875 +55378 -0.458251953125 +55379 -0.07122802734375 +55380 -0.384796142578125 +55381 -0.05804443359375 +55382 -0.323699951171875 +55383 -0.045166015625 +55384 -0.269287109375 +55385 -0.032379150390625 +55386 -0.1951904296875 +55387 -0.017486572265625 +55388 -0.100006103515625 +55389 -0.00079345703125 +55390 -0.01055908203125 +55391 0.014617919921875 +55392 0.1033935546875 +55393 0.03143310546875 +55394 0.24908447265625 +55395 0.05010986328125 +55396 0.373199462890625 +55397 0.06512451171875 +55398 0.45806884765625 +55399 0.074615478515625 +55400 0.511474609375 +55401 0.079345703125 +55402 0.565399169921875 +55403 0.08258056640625 +55404 0.61138916015625 +55405 0.083648681640625 +55406 0.5897216796875 +55407 0.07684326171875 +55408 0.4906005859375 +55409 0.06146240234375 +55410 0.33148193359375 +55411 0.03955078125 +55412 0.147796630859375 +55413 0.0150146484375 +55414 -0.01873779296875 +55415 -0.00762939453125 +55416 -0.140289306640625 +55417 -0.0252685546875 +55418 -0.191986083984375 +55419 -0.035125732421875 +55420 -0.184295654296875 +55421 -0.03802490234375 +55422 -0.161834716796875 +55423 -0.03826904296875 +55424 -0.166595458984375 +55425 -0.0399169921875 +55426 -0.19390869140625 +55427 -0.04248046875 +55428 -0.22442626953125 +55429 -0.0440673828125 +55430 -0.279754638671875 +55431 -0.046966552734375 +55432 -0.3389892578125 +55433 -0.04925537109375 +55434 -0.3543701171875 +55435 -0.04638671875 +55436 -0.348175048828125 +55437 -0.040863037109375 +55438 -0.32598876953125 +55439 -0.033538818359375 +55440 -0.2581787109375 +55441 -0.021728515625 +55442 -0.139801025390625 +55443 -0.00518798828125 +55444 0.014617919921875 +55445 0.01434326171875 +55446 0.144378662109375 +55447 0.03057861328125 +55448 0.221038818359375 +55449 0.04052734375 +55450 0.27069091796875 +55451 0.04669189453125 +55452 0.294036865234375 +55453 0.049102783203125 +55454 0.311767578125 +55455 0.04986572265625 +55456 0.339141845703125 +55457 0.05059814453125 +55458 0.360260009765625 +55459 0.0496826171875 +55460 0.360504150390625 +55461 0.045867919921875 +55462 0.308380126953125 +55463 0.036651611328125 +55464 0.18170166015625 +55465 0.020416259765625 +55466 0.0047607421875 +55467 -0.000335693359375 +55468 -0.17559814453125 +55469 -0.021148681640625 +55470 -0.3143310546875 +55471 -0.037811279296875 +55472 -0.36785888671875 +55473 -0.0462646484375 +55474 -0.36248779296875 +55475 -0.04864501953125 +55476 -0.343536376953125 +55477 -0.04876708984375 +55478 -0.3018798828125 +55479 -0.0457763671875 +55480 -0.231414794921875 +55481 -0.039154052734375 +55482 -0.117645263671875 +55483 -0.027679443359375 +55484 0.007049560546875 +55485 -0.01434326171875 +55486 0.087982177734375 +55487 -0.00408935546875 +55488 0.13946533203125 +55489 0.004119873046875 +55490 0.17425537109375 +55491 0.01123046875 +55492 0.188201904296875 +55493 0.0166015625 +55494 0.171234130859375 +55495 0.019134521484375 +55496 0.118438720703125 +55497 0.0181884765625 +55498 0.05706787109375 +55499 0.0159912109375 +55500 -0.010711669921875 +55501 0.0125732421875 +55502 -0.0914306640625 +55503 0.0072021484375 +55504 -0.162322998046875 +55505 0.0018310546875 +55506 -0.194549560546875 +55507 -0.001007080078125 +55508 -0.1492919921875 +55509 0.002105712890625 +55510 -0.02166748046875 +55511 0.01165771484375 +55512 0.124053955078125 +55513 0.0220947265625 +55514 0.211151123046875 +55515 0.02679443359375 +55516 0.240447998046875 +55517 0.0260009765625 +55518 0.242218017578125 +55519 0.0225830078125 +55520 0.2257080078125 +55521 0.017578125 +55522 0.194366455078125 +55523 0.011505126953125 +55524 0.115509033203125 +55525 0.00164794921875 +55526 0.0128173828125 +55527 -0.009674072265625 +55528 -0.053802490234375 +55529 -0.017120361328125 +55530 -0.110626220703125 +55531 -0.02294921875 +55532 -0.199493408203125 +55533 -0.03082275390625 +55534 -0.29437255859375 +55535 -0.038482666015625 +55536 -0.33221435546875 +55537 -0.0404052734375 +55538 -0.27972412109375 +55539 -0.033782958984375 +55540 -0.185333251953125 +55541 -0.02301025390625 +55542 -0.128204345703125 +55543 -0.01519775390625 +55544 -0.115692138671875 +55545 -0.011138916015625 +55546 -0.116455078125 +55547 -0.00823974609375 +55548 -0.105926513671875 +55549 -0.0045166015625 +55550 -0.053955078125 +55551 0.00250244140625 +55552 0.048797607421875 +55553 0.0133056640625 +55554 0.157318115234375 +55555 0.024169921875 +55556 0.212005615234375 +55557 0.0308837890625 +55558 0.218475341796875 +55559 0.033538818359375 +55560 0.23724365234375 +55561 0.035430908203125 +55562 0.30535888671875 +55563 0.03863525390625 +55564 0.38128662109375 +55565 0.0408935546875 +55566 0.404449462890625 +55567 0.039031982421875 +55568 0.3944091796875 +55569 0.034393310546875 +55570 0.3885498046875 +55571 0.02935791015625 +55572 0.362640380859375 +55573 0.022857666015625 +55574 0.27362060546875 +55575 0.012786865234375 +55576 0.11712646484375 +55577 -0.000762939453125 +55578 -0.054901123046875 +55579 -0.014617919921875 +55580 -0.19085693359375 +55581 -0.025665283203125 +55582 -0.28570556640625 +55583 -0.033447265625 +55584 -0.339263916015625 +55585 -0.037841796875 +55586 -0.3775634765625 +55587 -0.040283203125 +55588 -0.445709228515625 +55589 -0.043304443359375 +55590 -0.535064697265625 +55591 -0.046478271484375 +55592 -0.629058837890625 +55593 -0.04901123046875 +55594 -0.697601318359375 +55595 -0.04937744140625 +55596 -0.70391845703125 +55597 -0.045745849609375 +55598 -0.6424560546875 +55599 -0.038055419921875 +55600 -0.491241455078125 +55601 -0.025299072265625 +55602 -0.265716552734375 +55603 -0.00860595703125 +55604 -0.023712158203125 +55605 0.008544921875 +55606 0.201751708984375 +55607 0.02410888671875 +55608 0.375823974609375 +55609 0.0360107421875 +55610 0.485076904296875 +55611 0.04339599609375 +55612 0.56884765625 +55613 0.04840087890625 +55614 0.634765625 +55615 0.051483154296875 +55616 0.63763427734375 +55617 0.050201416015625 +55618 0.5660400390625 +55619 0.04400634765625 +55620 0.4720458984375 +55621 0.03594970703125 +55622 0.40692138671875 +55623 0.029083251953125 +55624 0.3778076171875 +55625 0.02398681640625 +55626 0.376953125 +55627 0.020416259765625 +55628 0.371978759765625 +55629 0.016754150390625 +55630 0.313140869140625 +55631 0.0103759765625 +55632 0.184417724609375 +55633 0.00054931640625 +55634 0.011199951171875 +55635 -0.011138916015625 +55636 -0.171051025390625 +55637 -0.0225830078125 +55638 -0.33740234375 +55639 -0.0323486328125 +55640 -0.47198486328125 +55641 -0.03955078125 +55642 -0.560394287109375 +55643 -0.043426513671875 +55644 -0.58056640625 +55645 -0.042816162109375 +55646 -0.54754638671875 +55647 -0.038665771484375 +55648 -0.508575439453125 +55649 -0.033843994140625 +55650 -0.459503173828125 +55651 -0.028228759765625 +55652 -0.394378662109375 +55653 -0.021636962890625 +55654 -0.35260009765625 +55655 -0.016387939453125 +55656 -0.31170654296875 +55657 -0.01141357421875 +55658 -0.197418212890625 +55659 -0.002685546875 +55660 -0.007965087890625 +55661 0.009735107421875 +55662 0.207489013671875 +55663 0.022979736328125 +55664 0.409210205078125 +55665 0.0347900390625 +55666 0.57208251953125 +55667 0.043731689453125 +55668 0.66595458984375 +55669 0.04815673828125 +55670 0.65875244140625 +55671 0.046356201171875 +55672 0.56744384765625 +55673 0.03936767578125 +55674 0.431396484375 +55675 0.029510498046875 +55676 0.29443359375 +55677 0.019378662109375 +55678 0.182464599609375 +55679 0.01055908203125 +55680 0.06365966796875 +55681 0.00140380859375 +55682 -0.075958251953125 +55683 -0.008697509765625 +55684 -0.189422607421875 +55685 -0.016998291015625 +55686 -0.271942138671875 +55687 -0.023101806640625 +55688 -0.342529296875 +55689 -0.02801513671875 +55690 -0.364166259765625 +55691 -0.0296630859375 +55692 -0.327239990234375 +55693 -0.027496337890625 +55694 -0.2769775390625 +55695 -0.024078369140625 +55696 -0.253692626953125 +55697 -0.021697998046875 +55698 -0.24365234375 +55699 -0.0196533203125 +55700 -0.1983642578125 +55701 -0.01531982421875 +55702 -0.116241455078125 +55703 -0.00872802734375 +55704 -0.036834716796875 +55705 -0.002197265625 +55706 0.034881591796875 +55707 0.00384521484375 +55708 0.09124755859375 +55709 0.008880615234375 +55710 0.10888671875 +55711 0.011474609375 +55712 0.125518798828125 +55713 0.013671875 +55714 0.15771484375 +55715 0.016357421875 +55716 0.17828369140625 +55717 0.0179443359375 +55718 0.17108154296875 +55719 0.01751708984375 +55720 0.129974365234375 +55721 0.014739990234375 +55722 0.082427978515625 +55723 0.011199951171875 +55724 0.027679443359375 +55725 0.0069580078125 +55726 -0.065643310546875 +55727 0.000335693359375 +55728 -0.15936279296875 +55729 -0.006439208984375 +55730 -0.21307373046875 +55731 -0.01104736328125 +55732 -0.234649658203125 +55733 -0.013824462890625 +55734 -0.2001953125 +55735 -0.01336669921875 +55736 -0.119171142578125 +55737 -0.010101318359375 +55738 -0.024749755859375 +55739 -0.005859375 +55740 0.085784912109375 +55741 -0.000396728515625 +55742 0.178131103515625 +55743 0.004302978515625 +55744 0.215576171875 +55745 0.0062255859375 +55746 0.211456298828125 +55747 0.006134033203125 +55748 0.17523193359375 +55749 0.00457763671875 +55750 0.128753662109375 +55751 0.002716064453125 +55752 0.1019287109375 +55753 0.002197265625 +55754 0.0743408203125 +55755 0.001800537109375 +55756 0.04327392578125 +55757 0.001312255859375 +55758 0.038177490234375 +55759 0.0023193359375 +55760 0.076263427734375 +55761 0.005706787109375 +55762 0.14105224609375 +55763 0.01043701171875 +55764 0.186431884765625 +55765 0.013885498046875 +55766 0.188812255859375 +55767 0.01470947265625 +55768 0.1390380859375 +55769 0.012359619140625 +55770 0.041778564453125 +55771 0.007080078125 +55772 -0.079437255859375 +55773 0.000213623046875 +55774 -0.219390869140625 +55775 -0.0079345703125 +55776 -0.367828369140625 +55777 -0.0167236328125 +55778 -0.494873046875 +55779 -0.02447509765625 +55780 -0.556243896484375 +55781 -0.028656005859375 +55782 -0.508697509765625 +55783 -0.026824951171875 +55784 -0.3756103515625 +55785 -0.020233154296875 +55786 -0.218902587890625 +55787 -0.012298583984375 +55788 -0.063751220703125 +55789 -0.004425048828125 +55790 0.091552734375 +55791 0.00347900390625 +55792 0.23602294921875 +55793 0.0108642578125 +55794 0.342987060546875 +55795 0.01629638671875 +55796 0.39520263671875 +55797 0.01885986328125 +55798 0.389373779296875 +55799 0.01837158203125 +55800 0.324249267578125 +55801 0.0147705078125 +55802 0.224090576171875 +55803 0.0093994140625 +55804 0.124267578125 +55805 0.004241943359375 +55806 0.037078857421875 +55807 -6.103515625e-05 +55808 -0.010101318359375 +55809 -0.00244140625 +55810 -0.019439697265625 +55811 -0.002838134765625 +55812 -0.022796630859375 +55813 -0.002410888671875 +55814 -0.001556396484375 +55815 -0.0009765625 +55816 0.056304931640625 +55817 0.001495361328125 +55818 0.106719970703125 +55819 0.0037841796875 +55820 0.096893310546875 +55821 0.004425048828125 +55822 0.042694091796875 +55823 0.003753662109375 +55824 -0.018035888671875 +55825 0.00262451171875 +55826 -0.07586669921875 +55827 0.001251220703125 +55828 -0.11944580078125 +55829 -3.0517578125e-05 +55830 -0.15972900390625 +55831 -0.001434326171875 +55832 -0.202606201171875 +55833 -0.003082275390625 +55834 -0.24859619140625 +55835 -0.0048828125 +55836 -0.30517578125 +55837 -0.006988525390625 +55838 -0.36212158203125 +55839 -0.00909423828125 +55840 -0.39141845703125 +55841 -0.010467529296875 +55842 -0.35528564453125 +55843 -0.01019287109375 +55844 -0.249969482421875 +55845 -0.00811767578125 +55846 -0.092864990234375 +55847 -0.004638671875 +55848 0.08905029296875 +55849 -0.000396728515625 +55850 0.2352294921875 +55851 0.00311279296875 +55852 0.318817138671875 +55853 0.0052490234375 +55854 0.358642578125 +55855 0.0064697265625 +55856 0.347747802734375 +55857 0.006561279296875 +55858 0.28564453125 +55859 0.005523681640625 +55860 0.223175048828125 +55861 0.004547119140625 +55862 0.196746826171875 +55863 0.00445556640625 +55864 0.179840087890625 +55865 0.004608154296875 +55866 0.155548095703125 +55867 0.00457763671875 +55868 0.151214599609375 +55869 0.00494384765625 +55870 0.156951904296875 +55871 0.005462646484375 +55872 0.13177490234375 +55873 0.005126953125 +55874 0.100799560546875 +55875 0.0045166015625 +55876 0.087127685546875 +55877 0.00421142578125 +55878 0.05487060546875 +55879 0.00335693359375 +55880 -0.009002685546875 +55881 0.001617431640625 +55882 -0.10400390625 +55883 -0.00091552734375 +55884 -0.229400634765625 +55885 -0.004241943359375 +55886 -0.35552978515625 +55887 -0.00762939453125 +55888 -0.441925048828125 +55889 -0.01007080078125 +55890 -0.473846435546875 +55891 -0.01116943359375 +55892 -0.464813232421875 +55893 -0.011260986328125 +55894 -0.419097900390625 +55895 -0.01043701171875 +55896 -0.334320068359375 +55897 -0.008636474609375 +55898 -0.227935791015625 +55899 -0.0062255859375 +55900 -0.12347412109375 +55901 -0.0037841796875 +55902 -0.02764892578125 +55903 -0.00146484375 +55904 0.077667236328125 +55905 0.001129150390625 +55906 0.2132568359375 +55907 0.004486083984375 +55908 0.38885498046875 +55909 0.00885009765625 +55910 0.582794189453125 +55911 0.013671875 +55912 0.734039306640625 +55913 0.017486572265625 +55914 0.800140380859375 +55915 0.01922607421875 +55916 0.7783203125 +55917 0.018829345703125 +55918 0.6651611328125 +55919 0.0162353515625 +55920 0.45965576171875 +55921 0.01141357421875 +55922 0.199188232421875 +55923 0.005279541015625 +55924 -0.050689697265625 +55925 -0.000579833984375 +55926 -0.23297119140625 +55927 -0.00482177734375 +55928 -0.33013916015625 +55929 -0.007049560546875 +55930 -0.368408203125 +55931 -0.00787353515625 +55932 -0.378936767578125 +55933 -0.008056640625 +55934 -0.376983642578125 +55935 -0.00799560546875 +55936 -0.37969970703125 +55937 -0.008087158203125 +55938 -0.391510009765625 +55939 -0.0084228515625 +55940 -0.385345458984375 +55941 -0.00836181640625 +55942 -0.3419189453125 +55943 -0.007415771484375 +55944 -0.28289794921875 +55945 -0.006103515625 +55946 -0.251617431640625 +55947 -0.00543212890625 +55948 -0.266143798828125 +55949 -0.005859375 +55950 -0.273345947265625 +55951 -0.006103515625 +55952 -0.216796875 +55953 -0.00482177734375 +55954 -0.128265380859375 +55955 -0.002777099609375 +55956 -0.068145751953125 +55957 -0.001373291015625 +55958 -0.0430908203125 +55959 -0.000762939453125 +55960 -0.024444580078125 +55961 -0.000274658203125 +55962 0.020721435546875 +55963 0.000823974609375 +55964 0.124481201171875 +55965 0.0032958984375 +55966 0.25787353515625 +55967 0.0064697265625 +55968 0.379119873046875 +55969 0.009307861328125 +55970 0.47991943359375 +55971 0.01165771484375 +55972 0.5281982421875 +55973 0.01275634765625 +55974 0.511138916015625 +55975 0.01226806640625 +55976 0.456207275390625 +55977 0.010894775390625 +55978 0.407470703125 +55979 0.009674072265625 +55980 0.383758544921875 +55981 0.009063720703125 +55982 0.35687255859375 +55983 0.008331298828125 +55984 0.31182861328125 +55985 0.007171630859375 +55986 0.250885009765625 +55987 0.005615234375 +55988 0.1654052734375 +55989 0.003509521484375 +55990 0.035247802734375 +55991 0.0003662109375 +55992 -0.142059326171875 +55993 -0.00384521484375 +55994 -0.33563232421875 +55995 -0.008392333984375 +55996 -0.5345458984375 +55997 -0.01300048828125 +55998 -0.72186279296875 +55999 -0.017303466796875 +56000 -0.836669921875 +56001 -0.019805908203125 +56002 -0.8326416015625 +56003 -0.019439697265625 +56004 -0.7296142578125 +56005 -0.016693115234375 +56006 -0.582550048828125 +56007 -0.012939453125 +56008 -0.440093994140625 +56009 -0.009368896484375 +56010 -0.324310302734375 +56011 -0.006500244140625 +56012 -0.20147705078125 +56013 -0.00347900390625 +56014 -0.044647216796875 +56015 0.00030517578125 +56016 0.103973388671875 +56017 0.003814697265625 +56018 0.202392578125 +56019 0.00604248046875 +56020 0.264495849609375 +56021 0.007354736328125 +56022 0.338897705078125 +56023 0.0089111328125 +56024 0.443817138671875 +56025 0.011138916015625 +56026 0.545074462890625 +56027 0.01324462890625 +56028 0.6173095703125 +56029 0.0146484375 +56030 0.6524658203125 +56031 0.01519775390625 +56032 0.66339111328125 +56033 0.015167236328125 +56034 0.6561279296875 +56035 0.0147705078125 +56036 0.606781005859375 +56037 0.013397216796875 +56038 0.501190185546875 +56039 0.010711669921875 +56040 0.352783203125 +56041 0.007080078125 +56042 0.176544189453125 +56043 0.002838134765625 +56044 -0.034820556640625 +56045 -0.002105712890625 +56046 -0.258209228515625 +56047 -0.0072021484375 +56048 -0.44244384765625 +56049 -0.011260986328125 +56050 -0.5753173828125 +56051 -0.0140380859375 +56052 -0.65203857421875 +56053 -0.01544189453125 +56054 -0.641632080078125 +56055 -0.014739990234375 +56056 -0.562164306640625 +56057 -0.012420654296875 +56058 -0.458038330078125 +56059 -0.00958251953125 +56060 -0.350555419921875 +56061 -0.0067138671875 +56062 -0.260528564453125 +56063 -0.00433349609375 +56064 -0.192108154296875 +56065 -0.002471923828125 +56066 -0.141937255859375 +56067 -0.00103759765625 +56068 -0.1021728515625 +56069 3.0517578125e-05 +56070 -0.062896728515625 +56071 0.000885009765625 +56072 -0.011932373046875 +56073 0.001708984375 +56074 0.062835693359375 +56075 0.002655029296875 +56076 0.148712158203125 +56077 0.003631591796875 +56078 0.241729736328125 +56079 0.00457763671875 +56080 0.34912109375 +56081 0.005584716796875 +56082 0.457305908203125 +56083 0.00653076171875 +56084 0.54388427734375 +56085 0.007232666015625 +56086 0.5728759765625 +56087 0.007415771484375 +56088 0.506591796875 +56089 0.006744384765625 +56090 0.351226806640625 +56091 0.0052490234375 +56092 0.146514892578125 +56093 0.003265380859375 +56094 -0.05523681640625 +56095 0.001220703125 +56096 -0.21624755859375 +56097 -0.00054931640625 +56098 -0.334930419921875 +56099 -0.001983642578125 +56100 -0.402984619140625 +56101 -0.00299072265625 +56102 -0.4412841796875 +56103 -0.00372314453125 +56104 -0.49578857421875 +56105 -0.0045166015625 +56106 -0.5601806640625 +56107 -0.005340576171875 +56108 -0.600738525390625 +56109 -0.00592041015625 +56110 -0.584228515625 +56111 -0.005950927734375 +56112 -0.47930908203125 +56113 -0.00518798828125 +56114 -0.27935791015625 +56115 -0.003570556640625 +56116 -0.0089111328125 +56117 -0.001312255859375 +56118 0.268798828125 +56119 0.00103759765625 +56120 0.482818603515625 +56121 0.002899169921875 +56122 0.60369873046875 +56123 0.004058837890625 +56124 0.650421142578125 +56125 0.004669189453125 +56126 0.66400146484375 +56127 0.005035400390625 +56128 0.6414794921875 +56129 0.005126953125 +56130 0.572540283203125 +56131 0.004852294921875 +56132 0.498138427734375 +56133 0.0045166015625 +56134 0.439453125 +56135 0.0042724609375 +56136 0.375518798828125 +56137 0.003936767578125 +56138 0.274505615234375 +56139 0.00323486328125 +56140 0.1087646484375 +56141 0.001953125 +56142 -0.099395751953125 +56143 0.000274658203125 +56144 -0.3182373046875 +56145 -0.00152587890625 +56146 -0.5489501953125 +56147 -0.00341796875 +56148 -0.7738037109375 +56149 -0.0052490234375 +56150 -0.86383056640625 +56151 -0.006622314453125 +56152 -0.870391845703125 +56153 -0.00726318359375 +56154 -0.86895751953125 +56155 -0.00732421875 +56156 -0.861053466796875 +56157 -0.006927490234375 +56158 -0.765869140625 +56159 -0.00592041015625 +56160 -0.5301513671875 +56161 -0.00421142578125 +56162 -0.214691162109375 +56163 -0.001861572265625 +56164 0.137359619140625 +56165 0.00079345703125 +56166 0.474822998046875 +56167 0.00335693359375 +56168 0.76239013671875 +56169 0.00555419921875 +56170 0.867462158203125 +56171 0.007171630859375 +56172 0.870361328125 +56173 0.008209228515625 +56174 0.86480712890625 +56175 0.008575439453125 +56176 0.831817626953125 +56177 0.00830078125 +56178 0.677581787109375 +56179 0.007598876953125 +56180 0.495880126953125 +56181 0.006561279296875 +56182 0.30767822265625 +56183 0.00531005859375 +56184 0.116180419921875 +56185 0.00390625 +56186 -0.110748291015625 +56187 0.0020751953125 +56188 -0.381805419921875 +56189 -0.000244140625 +56190 -0.6572265625 +56191 -0.002716064453125 +56192 -0.857421875 +56193 -0.004852294921875 +56194 -0.870391845703125 +56195 -0.00634765625 +56196 -0.870391845703125 +56197 -0.007171630859375 +56198 -0.86444091796875 +56199 -0.007537841796875 +56200 -0.85723876953125 +56201 -0.00775146484375 +56202 -0.790008544921875 +56203 -0.0076904296875 +56204 -0.62847900390625 +56205 -0.0069580078125 +56206 -0.3956298828125 +56207 -0.005523681640625 +56208 -0.126708984375 +56209 -0.003631591796875 +56210 0.150115966796875 +56211 -0.001495361328125 +56212 0.424041748046875 +56213 0.000762939453125 +56214 0.670623779296875 +56215 0.0029296875 +56216 0.854522705078125 +56217 0.00469970703125 +56218 0.866485595703125 +56219 0.005950927734375 +56220 0.86920166015625 +56221 0.006622314453125 +56222 0.8653564453125 +56223 0.00689697265625 +56224 0.857147216796875 +56225 0.006866455078125 +56226 0.766845703125 +56227 0.006561279296875 +56228 0.628509521484375 +56229 0.0059814453125 +56230 0.462127685546875 +56231 0.005126953125 +56232 0.297210693359375 +56233 0.004180908203125 +56234 0.14862060546875 +56235 0.00323486328125 +56236 -0.00537109375 +56237 0.002105712890625 +56238 -0.15753173828125 +56239 0.0008544921875 +56240 -0.31304931640625 +56241 -0.000518798828125 +56242 -0.48876953125 +56243 -0.002105712890625 +56244 -0.6416015625 +56245 -0.003570556640625 +56246 -0.751373291015625 +56247 -0.004730224609375 +56248 -0.84619140625 +56249 -0.00579833984375 +56250 -0.861297607421875 +56251 -0.00665283203125 +56252 -0.863250732421875 +56253 -0.007080078125 +56254 -0.856597900390625 +56255 -0.006805419921875 +56256 -0.7498779296875 +56257 -0.0059814453125 +56258 -0.624542236328125 +56259 -0.005096435546875 +56260 -0.47808837890625 +56261 -0.003997802734375 +56262 -0.253387451171875 +56263 -0.002227783203125 +56264 0.003692626953125 +56265 -0.000152587890625 +56266 0.2257080078125 +56267 0.00164794921875 +56268 0.427154541015625 +56269 0.003265380859375 +56270 0.643218994140625 +56271 0.004974365234375 +56272 0.855926513671875 +56273 0.0067138671875 +56274 0.870361328125 +56275 0.008087158203125 +56276 0.870361328125 +56277 0.00872802734375 +56278 0.862762451171875 +56279 0.008758544921875 +56280 0.79669189453125 +56281 0.0081787109375 +56282 0.595794677734375 +56283 0.0069580078125 +56284 0.362152099609375 +56285 0.005340576171875 +56286 0.1270751953125 +56287 0.003570556640625 +56288 -0.086944580078125 +56289 0.0018310546875 +56290 -0.2784423828125 +56291 0.0001220703125 +56292 -0.484832763671875 +56293 -0.00177001953125 +56294 -0.729583740234375 +56295 -0.004058837890625 +56296 -0.86688232421875 +56297 -0.006317138671875 +56298 -0.870391845703125 +56299 -0.00811767578125 +56300 -0.86859130859375 +56301 -0.009429931640625 +56302 -0.86279296875 +56303 -0.010284423828125 +56304 -0.817962646484375 +56305 -0.01043701171875 +56306 -0.6116943359375 +56307 -0.00958251953125 +56308 -0.3128662109375 +56309 -0.007659912109375 +56310 0.039398193359375 +56311 -0.004974365234375 +56312 0.422821044921875 +56313 -0.001739501953125 +56314 0.805145263671875 +56315 0.001708984375 +56316 0.870361328125 +56317 0.0048828125 +56318 0.870361328125 +56319 0.00732421875 +56320 0.860015869140625 +56321 0.0091552734375 +56322 0.727935791015625 +56323 0.0098876953125 +56324 0.48114013671875 +56325 0.0091552734375 +56326 0.2059326171875 +56327 0.00787353515625 +56328 -0.06103515625 +56329 0.006805419921875 +56330 -0.29913330078125 +56331 0.006103515625 +56332 -0.516204833984375 +56333 0.00494384765625 +56334 -0.7252197265625 +56335 0.00238037109375 +56336 -0.85980224609375 +56337 -0.00091552734375 +56338 -0.870391845703125 +56339 -0.003936767578125 +56340 -0.870391845703125 +56341 -0.005889892578125 +56342 -0.858062744140625 +56343 -0.005218505859375 +56344 -0.673004150390625 +56345 -0.0020751953125 +56346 -0.42694091796875 +56347 0.00103759765625 +56348 -0.2100830078125 +56349 0.00213623046875 +56350 -0.0362548828125 +56351 0.0010986328125 +56352 0.10943603515625 +56353 -0.0009765625 +56354 0.23516845703125 +56355 -0.003265380859375 +56356 0.373687744140625 +56357 -0.00408935546875 +56358 0.517791748046875 +56359 -0.00341796875 +56360 0.602783203125 +56361 -0.003631591796875 +56362 0.635711669921875 +56363 -0.004302978515625 +56364 0.655181884765625 +56365 -0.003814697265625 +56366 0.65948486328125 +56367 -0.002227783203125 +56368 0.651275634765625 +56369 0.000396728515625 +56370 0.61846923828125 +56371 0.0032958984375 +56372 0.53753662109375 +56373 0.00531005859375 +56374 0.404144287109375 +56375 0.005950927734375 +56376 0.22186279296875 +56377 0.005035400390625 +56378 0.003997802734375 +56379 0.00274658203125 +56380 -0.22100830078125 +56381 -9.1552734375e-05 +56382 -0.42449951171875 +56383 -0.002655029296875 +56384 -0.579833984375 +56385 -0.00421142578125 +56386 -0.641876220703125 +56387 -0.003173828125 +56388 -0.6177978515625 +56389 0.0 +56390 -0.575531005859375 +56391 0.00250244140625 +56392 -0.526336669921875 +56393 0.003875732421875 +56394 -0.42645263671875 +56395 0.00592041015625 +56396 -0.2581787109375 +56397 0.009490966796875 +56398 -0.068695068359375 +56399 0.01287841796875 +56400 0.09222412109375 +56401 0.014404296875 +56402 0.232147216796875 +56403 0.014617919921875 +56404 0.3509521484375 +56405 0.01385498046875 +56406 0.410064697265625 +56407 0.0108642578125 +56408 0.372955322265625 +56409 0.004486083984375 +56410 0.2554931640625 +56411 -0.004364013671875 +56412 0.10711669921875 +56413 -0.01348876953125 +56414 -0.052886962890625 +56415 -0.021942138671875 +56416 -0.186279296875 +56417 -0.028167724609375 +56418 -0.23291015625 +56419 -0.02972412109375 +56420 -0.209442138671875 +56421 -0.027374267578125 +56422 -0.174163818359375 +56423 -0.023529052734375 +56424 -0.126739501953125 +56425 -0.018341064453125 +56426 -0.048126220703125 +56427 -0.011260986328125 +56428 0.0426025390625 +56429 -0.003265380859375 +56430 0.10748291015625 +56431 0.00384521484375 +56432 0.1409912109375 +56433 0.00958251953125 +56434 0.19708251953125 +56435 0.015838623046875 +56436 0.273651123046875 +56437 0.0223388671875 +56438 0.31768798828125 +56439 0.026824951171875 +56440 0.341094970703125 +56441 0.029632568359375 +56442 0.368011474609375 +56443 0.03167724609375 +56444 0.37249755859375 +56445 0.031890869140625 +56446 0.30072021484375 +56447 0.02813720703125 +56448 0.1517333984375 +56449 0.020477294921875 +56450 -0.01470947265625 +56451 0.011383056640625 +56452 -0.1883544921875 +56453 0.001434326171875 +56454 -0.372711181640625 +56455 -0.009307861328125 +56456 -0.51397705078125 +56457 -0.018524169921875 +56458 -0.57177734375 +56459 -0.024383544921875 +56460 -0.53948974609375 +56461 -0.02642822265625 +56462 -0.43511962890625 +56463 -0.02520751953125 +56464 -0.2962646484375 +56465 -0.022064208984375 +56466 -0.161102294921875 +56467 -0.018402099609375 +56468 -0.0435791015625 +56469 -0.01470947265625 +56470 0.060394287109375 +56471 -0.01080322265625 +56472 0.13665771484375 +56473 -0.00726318359375 +56474 0.170135498046875 +56475 -0.004730224609375 +56476 0.16552734375 +56477 -0.00311279296875 +56478 0.15728759765625 +56479 -0.001129150390625 +56480 0.150787353515625 +56481 0.00128173828125 +56482 0.12200927734375 +56483 0.00299072265625 +56484 0.080108642578125 +56485 0.004180908203125 +56486 0.05126953125 +56487 0.005767822265625 +56488 0.062896728515625 +56489 0.008697509765625 +56490 0.09271240234375 +56491 0.011962890625 +56492 0.092987060546875 +56493 0.013519287109375 +56494 0.07855224609375 +56495 0.013916015625 +56496 0.06427001953125 +56497 0.013702392578125 +56498 0.0347900390625 +56499 0.01226806640625 +56500 -0.01171875 +56501 0.009552001953125 +56502 -0.056060791015625 +56503 0.006378173828125 +56504 -0.055511474609375 +56505 0.00457763671875 +56506 -0.010467529296875 +56507 0.004241943359375 +56508 0.02508544921875 +56509 0.003326416015625 +56510 0.025665283203125 +56511 0.000946044921875 +56512 0.017333984375 +56513 -0.001678466796875 +56514 0.00189208984375 +56515 -0.00433349609375 +56516 -0.03173828125 +56517 -0.00738525390625 +56518 -0.071502685546875 +56519 -0.010284423828125 +56520 -0.13543701171875 +56521 -0.013671875 +56522 -0.219970703125 +56523 -0.017364501953125 +56524 -0.300506591796875 +56525 -0.020355224609375 +56526 -0.376312255859375 +56527 -0.022674560546875 +56528 -0.416107177734375 +56529 -0.02313232421875 +56530 -0.371124267578125 +56531 -0.019866943359375 +56532 -0.242279052734375 +56533 -0.01300048828125 +56534 -0.069732666015625 +56535 -0.004241943359375 +56536 0.125640869140625 +56537 0.00543212890625 +56538 0.31268310546875 +56539 0.014678955078125 +56540 0.45501708984375 +56541 0.021942138671875 +56542 0.554779052734375 +56543 0.027252197265625 +56544 0.61065673828125 +56545 0.030487060546875 +56546 0.610931396484375 +56547 0.0311279296875 +56548 0.531463623046875 +56549 0.028228759765625 +56550 0.3883056640625 +56551 0.02239990234375 +56552 0.23468017578125 +56553 0.015777587890625 +56554 0.095245361328125 +56555 0.009429931640625 +56556 -0.00396728515625 +56557 0.004425048828125 +56558 -0.04852294921875 +56559 0.001373291015625 +56560 -0.055145263671875 +56561 -0.000274658203125 +56562 -0.0758056640625 +56563 -0.002532958984375 +56564 -0.138702392578125 +56565 -0.006439208984375 +56566 -0.209197998046875 +56567 -0.010528564453125 +56568 -0.289031982421875 +56569 -0.014801025390625 +56570 -0.37884521484375 +56571 -0.01922607421875 +56572 -0.456329345703125 +56573 -0.02288818359375 +56574 -0.51641845703125 +56575 -0.025543212890625 +56576 -0.519287109375 +56577 -0.025421142578125 +56578 -0.458251953125 +56579 -0.02227783203125 +56580 -0.384796142578125 +56581 -0.01861572265625 +56582 -0.323699951171875 +56583 -0.015655517578125 +56584 -0.269287109375 +56585 -0.0130615234375 +56586 -0.1951904296875 +56587 -0.009490966796875 +56588 -0.100006103515625 +56589 -0.0048828125 +56590 -0.01055908203125 +56591 -0.00054931640625 +56592 0.1033935546875 +56593 0.0050048828125 +56594 0.24908447265625 +56595 0.01214599609375 +56596 0.373199462890625 +56597 0.01824951171875 +56598 0.45806884765625 +56599 0.02239990234375 +56600 0.511474609375 +56601 0.024993896484375 +56602 0.565399169921875 +56603 0.02764892578125 +56604 0.61138916015625 +56605 0.029937744140625 +56606 0.5897216796875 +56607 0.028900146484375 +56608 0.4906005859375 +56609 0.0240478515625 +56610 0.33148193359375 +56611 0.016204833984375 +56612 0.147796630859375 +56613 0.00714111328125 +56614 -0.01873779296875 +56615 -0.001007080078125 +56616 -0.140289306640625 +56617 -0.006866455078125 +56618 -0.191986083984375 +56619 -0.00921630859375 +56620 -0.184295654296875 +56621 -0.008636474609375 +56622 -0.161834716796875 +56623 -0.00732421875 +56624 -0.166595458984375 +56625 -0.00738525390625 +56626 -0.19390869140625 +56627 -0.008575439453125 +56628 -0.22442626953125 +56629 -0.009979248046875 +56630 -0.279754638671875 +56631 -0.012664794921875 +56632 -0.3389892578125 +56633 -0.015594482421875 +56634 -0.3543701171875 +56635 -0.016387939453125 +56636 -0.348175048828125 +56637 -0.016143798828125 +56638 -0.32598876953125 +56639 -0.015106201171875 +56640 -0.2581787109375 +56641 -0.011810302734375 +56642 -0.139801025390625 +56643 -0.006011962890625 +56644 0.014617919921875 +56645 0.001556396484375 +56646 0.144378662109375 +56647 0.0078125 +56648 0.221038818359375 +56649 0.0113525390625 +56650 0.27069091796875 +56651 0.013519287109375 +56652 0.294036865234375 +56653 0.014373779296875 +56654 0.311767578125 +56655 0.014984130859375 +56656 0.339141845703125 +56657 0.01617431640625 +56658 0.360260009765625 +56659 0.0174560546875 +56660 0.360504150390625 +56661 0.01800537109375 +56662 0.308380126953125 +56663 0.015411376953125 +56664 0.18170166015625 +56665 0.0079345703125 +56666 0.0047607421875 +56667 -0.0028076171875 +56668 -0.17559814453125 +56669 -0.01361083984375 +56670 -0.3143310546875 +56671 -0.0213623046875 +56672 -0.36785888671875 +56673 -0.023101806640625 +56674 -0.36248779296875 +56675 -0.0208740234375 +56676 -0.343536376953125 +56677 -0.01800537109375 +56678 -0.3018798828125 +56679 -0.013946533203125 +56680 -0.231414794921875 +56681 -0.008270263671875 +56682 -0.117645263671875 +56683 0.0 +56684 0.007049560546875 +56685 0.008544921875 +56686 0.087982177734375 +56687 0.013458251953125 +56688 0.13946533203125 +56689 0.015869140625 +56690 0.17425537109375 +56691 0.01678466796875 +56692 0.188201904296875 +56693 0.016021728515625 +56694 0.171234130859375 +56695 0.012939453125 +56696 0.118438720703125 +56697 0.00732421875 +56698 0.05706787109375 +56699 0.001251220703125 +56700 -0.010711669921875 +56701 -0.005035400390625 +56702 -0.0914306640625 +56703 -0.011932373046875 +56704 -0.162322998046875 +56705 -0.01776123046875 +56706 -0.194549560546875 +56707 -0.02044677734375 +56708 -0.1492919921875 +56709 -0.01715087890625 +56710 -0.02166748046875 +56711 -0.007568359375 +56712 0.124053955078125 +56713 0.003631591796875 +56714 0.211151123046875 +56715 0.010833740234375 +56716 0.240447998046875 +56717 0.014068603515625 +56718 0.242218017578125 +56719 0.015472412109375 +56720 0.2257080078125 +56721 0.015625 +56722 0.194366455078125 +56723 0.01470947265625 +56724 0.115509033203125 +56725 0.010284423828125 +56726 0.0128173828125 +56727 0.0040283203125 +56728 -0.053802490234375 +56729 0.000152587890625 +56730 -0.110626220703125 +56731 -0.00323486328125 +56732 -0.199493408203125 +56733 -0.0091552734375 +56734 -0.29437255859375 +56735 -0.015777587890625 +56736 -0.33221435546875 +56737 -0.0185546875 +56738 -0.27972412109375 +56739 -0.015106201171875 +56740 -0.185333251953125 +56741 -0.008880615234375 +56742 -0.128204345703125 +56743 -0.005523681640625 +56744 -0.115692138671875 +56745 -0.005523681640625 +56746 -0.116455078125 +56747 -0.006591796875 +56748 -0.105926513671875 +56749 -0.00689697265625 +56750 -0.053955078125 +56751 -0.00421142578125 +56752 0.048797607421875 +56753 0.002166748046875 +56754 0.157318115234375 +56755 0.009033203125 +56756 0.212005615234375 +56757 0.012176513671875 +56758 0.218475341796875 +56759 0.012054443359375 +56760 0.23724365234375 +56761 0.013031005859375 +56762 0.30535888671875 +56763 0.017791748046875 +56764 0.38128662109375 +56765 0.0233154296875 +56766 0.404449462890625 +56767 0.025238037109375 +56768 0.3944091796875 +56769 0.024993896484375 +56770 0.3885498046875 +56771 0.025238037109375 +56772 0.362640380859375 +56773 0.024200439453125 +56774 0.27362060546875 +56775 0.018707275390625 +56776 0.11712646484375 +56777 0.00836181640625 +56778 -0.054901123046875 +56779 -0.003082275390625 +56780 -0.19085693359375 +56781 -0.011962890625 +56782 -0.28570556640625 +56783 -0.017974853515625 +56784 -0.339263916015625 +56785 -0.021148681640625 +56786 -0.3775634765625 +56787 -0.023406982421875 +56788 -0.445709228515625 +56789 -0.02801513671875 +56790 -0.535064697265625 +56791 -0.034332275390625 +56792 -0.629058837890625 +56793 -0.041168212890625 +56794 -0.697601318359375 +56795 -0.04632568359375 +56796 -0.70391845703125 +56797 -0.04718017578125 +56798 -0.6424560546875 +56799 -0.043304443359375 +56800 -0.491241455078125 +56801 -0.0330810546875 +56802 -0.265716552734375 +56803 -0.017578125 +56804 -0.023712158203125 +56805 -0.000946044921875 +56806 0.201751708984375 +56807 0.01446533203125 +56808 0.375823974609375 +56809 0.026214599609375 +56810 0.485076904296875 +56811 0.033355712890625 +56812 0.56884765625 +56813 0.03875732421875 +56814 0.634765625 +56815 0.04302978515625 +56816 0.63763427734375 +56817 0.04290771484375 +56818 0.5660400390625 +56819 0.03759765625 +56820 0.4720458984375 +56821 0.03082275390625 +56822 0.40692138671875 +56823 0.02630615234375 +56824 0.3778076171875 +56825 0.0245361328125 +56826 0.376953125 +56827 0.024932861328125 +56828 0.371978759765625 +56829 0.025146484375 +56830 0.313140869140625 +56831 0.021514892578125 +56832 0.184417724609375 +56833 0.01263427734375 +56834 0.011199951171875 +56835 6.103515625e-05 +56836 -0.171051025390625 +56837 -0.013336181640625 +56838 -0.33740234375 +56839 -0.025360107421875 +56840 -0.47198486328125 +56841 -0.03466796875 +56842 -0.560394287109375 +56843 -0.040069580078125 +56844 -0.58056640625 +56845 -0.03948974609375 +56846 -0.54754638671875 +56847 -0.03460693359375 +56848 -0.508575439453125 +56849 -0.030364990234375 +56850 -0.459503173828125 +56851 -0.026336669921875 +56852 -0.394378662109375 +56853 -0.02178955078125 +56854 -0.35260009765625 +56855 -0.0206298828125 +56856 -0.31170654296875 +56857 -0.02032470703125 +56858 -0.197418212890625 +56859 -0.012908935546875 +56860 -0.007965087890625 +56861 0.00201416015625 +56862 0.207489013671875 +56863 0.01959228515625 +56864 0.409210205078125 +56865 0.03594970703125 +56866 0.57208251953125 +56867 0.048736572265625 +56868 0.66595458984375 +56869 0.0550537109375 +56870 0.65875244140625 +56871 0.051727294921875 +56872 0.56744384765625 +56873 0.040618896484375 +56874 0.431396484375 +56875 0.025909423828125 +56876 0.29443359375 +56877 0.012176513671875 +56878 0.182464599609375 +56879 0.002044677734375 +56880 0.06365966796875 +56881 -0.00787353515625 +56882 -0.075958251953125 +56883 -0.01922607421875 +56884 -0.189422607421875 +56885 -0.027313232421875 +56886 -0.271942138671875 +56887 -0.03179931640625 +56888 -0.342529296875 +56889 -0.034912109375 +56890 -0.364166259765625 +56891 -0.0330810546875 +56892 -0.327239990234375 +56893 -0.0255126953125 +56894 -0.2769775390625 +56895 -0.01708984375 +56896 -0.253692626953125 +56897 -0.012176513671875 +56898 -0.24365234375 +56899 -0.00946044921875 +56900 -0.1983642578125 +56901 -0.00396728515625 +56902 -0.116241455078125 +56903 0.004425048828125 +56904 -0.036834716796875 +56905 0.01165771484375 +56906 0.034881591796875 +56907 0.01727294921875 +56908 0.09124755859375 +56909 0.020599365234375 +56910 0.10888671875 +56911 0.01934814453125 +56912 0.125518798828125 +56913 0.01763916015625 +56914 0.15771484375 +56915 0.01739501953125 +56916 0.17828369140625 +56917 0.0159912109375 +56918 0.17108154296875 +56919 0.011932373046875 +56920 0.129974365234375 +56921 0.0047607421875 +56922 0.082427978515625 +56923 -0.00250244140625 +56924 0.027679443359375 +56925 -0.009796142578125 +56926 -0.065643310546875 +56927 -0.02032470703125 +56928 -0.15936279296875 +56929 -0.03009033203125 +56930 -0.21307373046875 +56931 -0.034912109375 +56932 -0.234649658203125 +56933 -0.03570556640625 +56934 -0.2001953125 +56935 -0.03009033203125 +56936 -0.119171142578125 +56937 -0.0191650390625 +56938 -0.024749755859375 +56939 -0.00653076171875 +56940 0.085784912109375 +56941 0.007904052734375 +56942 0.178131103515625 +56943 0.0203857421875 +56944 0.215576171875 +56945 0.026947021484375 +56946 0.211456298828125 +56947 0.02886962890625 +56948 0.17523193359375 +56949 0.02703857421875 +56950 0.128753662109375 +56951 0.023651123046875 +56952 0.1019287109375 +56953 0.021697998046875 +56954 0.0743408203125 +56955 0.019073486328125 +56956 0.04327392578125 +56957 0.01544189453125 +56958 0.038177490234375 +56959 0.013916015625 +56960 0.076263427734375 +56961 0.016357421875 +56962 0.14105224609375 +56963 0.0211181640625 +56964 0.186431884765625 +56965 0.0235595703125 +56966 0.188812255859375 +56967 0.0213623046875 +56968 0.1390380859375 +56969 0.01373291015625 +56970 0.041778564453125 +56971 0.00128173828125 +56972 -0.079437255859375 +56973 -0.013397216796875 +56974 -0.219390869140625 +56975 -0.0296630859375 +56976 -0.367828369140625 +56977 -0.04632568359375 +56978 -0.494873046875 +56979 -0.06024169921875 +56980 -0.556243896484375 +56981 -0.066802978515625 +56982 -0.508697509765625 +56983 -0.061492919921875 +56984 -0.3756103515625 +56985 -0.046783447265625 +56986 -0.218902587890625 +56987 -0.029205322265625 +56988 -0.063751220703125 +56989 -0.011444091796875 +56990 0.091552734375 +56991 0.00653076171875 +56992 0.23602294921875 +56993 0.023468017578125 +56994 0.342987060546875 +56995 0.0364990234375 +56996 0.39520263671875 +56997 0.043731689453125 +56998 0.389373779296875 +56999 0.04473876953125 +57000 0.324249267578125 +57001 0.039306640625 +57002 0.224090576171875 +57003 0.029937744140625 +57004 0.124267578125 +57005 0.020233154296875 +57006 0.037078857421875 +57007 0.01141357421875 +57008 -0.010101318359375 +57009 0.00634765625 +57010 -0.019439697265625 +57011 0.00482177734375 +57012 -0.022796630859375 +57013 0.0035400390625 +57014 -0.001556396484375 +57015 0.0045166015625 +57016 0.056304931640625 +57017 0.009033203125 +57018 0.106719970703125 +57019 0.01263427734375 +57020 0.096893310546875 +57021 0.009918212890625 +57022 0.042694091796875 +57023 0.002655029296875 +57024 -0.018035888671875 +57025 -0.005126953125 +57026 -0.07586669921875 +57027 -0.012359619140625 +57028 -0.11944580078125 +57029 -0.017791748046875 +57030 -0.15972900390625 +57031 -0.022552490234375 +57032 -0.202606201171875 +57033 -0.0272216796875 +57034 -0.24859619140625 +57035 -0.03179931640625 +57036 -0.30517578125 +57037 -0.037109375 +57038 -0.36212158203125 +57039 -0.042144775390625 +57040 -0.39141845703125 +57041 -0.0440673828125 +57042 -0.35528564453125 +57043 -0.03900146484375 +57044 -0.249969482421875 +57045 -0.026641845703125 +57046 -0.092864990234375 +57047 -0.008880615234375 +57048 0.08905029296875 +57049 0.011383056640625 +57050 0.2352294921875 +57051 0.02777099609375 +57052 0.318817138671875 +57053 0.03741455078125 +57054 0.358642578125 +57055 0.042236328125 +57056 0.347747802734375 +57057 0.041473388671875 +57058 0.28564453125 +57059 0.03509521484375 +57060 0.223175048828125 +57061 0.02838134765625 +57062 0.196746826171875 +57063 0.025115966796875 +57064 0.179840087890625 +57065 0.0225830078125 +57066 0.155548095703125 +57067 0.01910400390625 +57068 0.151214599609375 +57069 0.017547607421875 +57070 0.156951904296875 +57071 0.0169677734375 +57072 0.13177490234375 +57073 0.013153076171875 +57074 0.100799560546875 +57075 0.008819580078125 +57076 0.087127685546875 +57077 0.00640869140625 +57078 0.05487060546875 +57079 0.002227783203125 +57080 -0.009002685546875 +57081 -0.0050048828125 +57082 -0.10400390625 +57083 -0.01519775390625 +57084 -0.229400634765625 +57085 -0.02825927734375 +57086 -0.35552978515625 +57087 -0.0411376953125 +57088 -0.441925048828125 +57089 -0.049835205078125 +57090 -0.473846435546875 +57091 -0.05316162109375 +57092 -0.464813232421875 +57093 -0.052703857421875 +57094 -0.419097900390625 +57095 -0.048492431640625 +57096 -0.334320068359375 +57097 -0.039703369140625 +57098 -0.227935791015625 +57099 -0.02825927734375 +57100 -0.12347412109375 +57101 -0.01702880859375 +57102 -0.02764892578125 +57103 -0.006683349609375 +57104 0.077667236328125 +57105 0.00543212890625 +57106 0.2132568359375 +57107 0.022247314453125 +57108 0.38885498046875 +57109 0.045166015625 +57110 0.582794189453125 +57111 0.071258544921875 +57112 0.734039306640625 +57113 0.0921630859375 +57114 0.800140380859375 +57115 0.102020263671875 +57116 0.7783203125 +57117 0.100372314453125 +57118 0.6651611328125 +57119 0.086639404296875 +57120 0.45965576171875 +57121 0.06060791015625 +57122 0.199188232421875 +57123 0.027191162109375 +57124 -0.050689697265625 +57125 -0.004791259765625 +57126 -0.23297119140625 +57127 -0.027740478515625 +57128 -0.33013916015625 +57129 -0.039337158203125 +57130 -0.368408203125 +57131 -0.04327392578125 +57132 -0.378936767578125 +57133 -0.0438232421875 +57134 -0.376983642578125 +57135 -0.04315185546875 +57136 -0.37969970703125 +57137 -0.043548583984375 +57138 -0.391510009765625 +57139 -0.045623779296875 +57140 -0.385345458984375 +57141 -0.045623779296875 +57142 -0.3419189453125 +57143 -0.0408935546875 +57144 -0.28289794921875 +57145 -0.0343017578125 +57146 -0.251617431640625 +57147 -0.031646728515625 +57148 -0.266143798828125 +57149 -0.0352783203125 +57150 -0.273345947265625 +57151 -0.03790283203125 +57152 -0.216796875 +57153 -0.03173828125 +57154 -0.128265380859375 +57155 -0.021026611328125 +57156 -0.068145751953125 +57157 -0.01385498046875 +57158 -0.0430908203125 +57159 -0.0111083984375 +57160 -0.024444580078125 +57161 -0.0089111328125 +57162 0.020721435546875 +57163 -0.00274658203125 +57164 0.124481201171875 +57165 0.011688232421875 +57166 0.25787353515625 +57167 0.030426025390625 +57168 0.379119873046875 +57169 0.0477294921875 +57170 0.47991943359375 +57171 0.06243896484375 +57172 0.5281982421875 +57173 0.07012939453125 +57174 0.511138916015625 +57175 0.069000244140625 +57176 0.456207275390625 +57177 0.06268310546875 +57178 0.407470703125 +57179 0.05712890625 +57180 0.383758544921875 +57181 0.054840087890625 +57182 0.35687255859375 +57183 0.051910400390625 +57184 0.31182861328125 +57185 0.046295166015625 +57186 0.250885009765625 +57187 0.038299560546875 +57188 0.1654052734375 +57189 0.0267333984375 +57190 0.035247802734375 +57191 0.008880615234375 +57192 -0.142059326171875 +57193 -0.01556396484375 +57194 -0.33563232421875 +57195 -0.042388916015625 +57196 -0.5345458984375 +57197 -0.070068359375 +57198 -0.72186279296875 +57199 -0.09625244140625 +57200 -0.836669921875 +57201 -0.11260986328125 +57202 -0.8326416015625 +57203 -0.11279296875 +57204 -0.7296142578125 +57205 -0.099456787109375 +57206 -0.582550048828125 +57207 -0.080108642578125 +57208 -0.440093994140625 +57209 -0.061309814453125 +57210 -0.324310302734375 +57211 -0.0460205078125 +57212 -0.20147705078125 +57213 -0.02960205078125 +57214 -0.044647216796875 +57215 -0.008392333984375 +57216 0.103973388671875 +57217 0.0118408203125 +57218 0.202392578125 +57219 0.025390625 +57220 0.264495849609375 +57221 0.03411865234375 +57222 0.338897705078125 +57223 0.044586181640625 +57224 0.443817138671875 +57225 0.05926513671875 +57226 0.545074462890625 +57227 0.073486328125 +57228 0.6173095703125 +57229 0.083770751953125 +57230 0.6524658203125 +57231 0.089019775390625 +57232 0.66339111328125 +57233 0.0909423828125 +57234 0.6561279296875 +57235 0.09033203125 +57236 0.606781005859375 +57237 0.083892822265625 +57238 0.501190185546875 +57239 0.0697021484375 +57240 0.352783203125 +57241 0.049591064453125 +57242 0.176544189453125 +57243 0.025604248046875 +57244 -0.034820556640625 +57245 -0.003204345703125 +57246 -0.258209228515625 +57247 -0.03369140625 +57248 -0.44244384765625 +57249 -0.05889892578125 +57250 -0.5753173828125 +57251 -0.0771484375 +57252 -0.65203857421875 +57253 -0.087799072265625 +57254 -0.641632080078125 +57255 -0.08660888671875 +57256 -0.562164306640625 +57257 -0.0760498046875 +57258 -0.458038330078125 +57259 -0.062164306640625 +57260 -0.350555419921875 +57261 -0.047821044921875 +57262 -0.260528564453125 +57263 -0.035797119140625 +57264 -0.192108154296875 +57265 -0.026641845703125 +57266 -0.141937255859375 +57267 -0.019927978515625 +57268 -0.1021728515625 +57269 -0.01458740234375 +57270 -0.062896728515625 +57271 -0.00921630859375 +57272 -0.011932373046875 +57273 -0.002197265625 +57274 0.062835693359375 +57275 0.008087158203125 +57276 0.148712158203125 +57277 0.0198974609375 +57278 0.241729736328125 +57279 0.032684326171875 +57280 0.34912109375 +57281 0.047454833984375 +57282 0.457305908203125 +57283 0.06231689453125 +57284 0.54388427734375 +57285 0.074249267578125 +57286 0.5728759765625 +57287 0.07830810546875 +57288 0.506591796875 +57289 0.06939697265625 +57290 0.351226806640625 +57291 0.048370361328125 +57292 0.146514892578125 +57293 0.020599365234375 +57294 -0.05523681640625 +57295 -0.00677490234375 +57296 -0.21624755859375 +57297 -0.02862548828125 +57298 -0.334930419921875 +57299 -0.04473876953125 +57300 -0.402984619140625 +57301 -0.053985595703125 +57302 -0.4412841796875 +57303 -0.0592041015625 +57304 -0.49578857421875 +57305 -0.066650390625 +57306 -0.5601806640625 +57307 -0.075439453125 +57308 -0.600738525390625 +57309 -0.081024169921875 +57310 -0.584228515625 +57311 -0.078857421875 +57312 -0.47930908203125 +57313 -0.064666748046875 +57314 -0.27935791015625 +57315 -0.037567138671875 +57316 -0.0089111328125 +57317 -0.0008544921875 +57318 0.268798828125 +57319 0.036834716796875 +57320 0.482818603515625 +57321 0.065826416015625 +57322 0.60369873046875 +57323 0.082122802734375 +57324 0.650421142578125 +57325 0.08831787109375 +57326 0.66400146484375 +57327 0.09002685546875 +57328 0.6414794921875 +57329 0.08685302734375 +57330 0.572540283203125 +57331 0.077392578125 +57332 0.498138427734375 +57333 0.067230224609375 +57334 0.439453125 +57335 0.059234619140625 +57336 0.375518798828125 +57337 0.050567626953125 +57338 0.274505615234375 +57339 0.036895751953125 +57340 0.1087646484375 +57341 0.01446533203125 +57342 -0.099395751953125 +57343 -0.013671875 +57344 -0.3182373046875 +57345 -0.04376220703125 +57346 -0.5489501953125 +57347 -0.0767822265625 +57348 -0.7738037109375 +57349 -0.110107421875 +57350 -0.86383056640625 +57351 -0.135009765625 +57352 -0.870391845703125 +57353 -0.14599609375 +57354 -0.86895751953125 +57355 -0.146026611328125 +57356 -0.861053466796875 +57357 -0.137237548828125 +57358 -0.765869140625 +57359 -0.116546630859375 +57360 -0.5301513671875 +57361 -0.08184814453125 +57362 -0.214691162109375 +57363 -0.034027099609375 +57364 0.137359619140625 +57365 0.019927978515625 +57366 0.474822998046875 +57367 0.07171630859375 +57368 0.76239013671875 +57369 0.115692138671875 +57370 0.867462158203125 +57371 0.147613525390625 +57372 0.870361328125 +57373 0.167816162109375 +57374 0.86480712890625 +57375 0.174560546875 +57376 0.831817626953125 +57377 0.16888427734375 +57378 0.677581787109375 +57379 0.154998779296875 +57380 0.495880126953125 +57381 0.1339111328125 +57382 0.30767822265625 +57383 0.108734130859375 +57384 0.116180419921875 +57385 0.0797119140625 +57386 -0.110748291015625 +57387 0.0413818359375 +57388 -0.381805419921875 +57389 -0.007598876953125 +57390 -0.6572265625 +57391 -0.060272216796875 +57392 -0.857421875 +57393 -0.106781005859375 +57394 -0.870391845703125 +57395 -0.14019775390625 +57396 -0.870391845703125 +57397 -0.159576416015625 +57398 -0.86444091796875 +57399 -0.169677734375 +57400 -0.85723876953125 +57401 -0.176666259765625 +57402 -0.790008544921875 +57403 -0.1776123046875 +57404 -0.62847900390625 +57405 -0.16351318359375 +57406 -0.3956298828125 +57407 -0.133880615234375 +57408 -0.126708984375 +57409 -0.094207763671875 +57410 0.150115966796875 +57411 -0.049041748046875 +57412 0.424041748046875 +57413 -0.000244140625 +57414 0.670623779296875 +57415 0.047760009765625 +57416 0.854522705078125 +57417 0.088653564453125 +57418 0.866485595703125 +57419 0.119659423828125 +57420 0.86920166015625 +57421 0.138427734375 +57422 0.8653564453125 +57423 0.148193359375 +57424 0.857147216796875 +57425 0.151397705078125 +57426 0.766845703125 +57427 0.147735595703125 +57428 0.628509521484375 +57429 0.13824462890625 +57430 0.462127685546875 +57431 0.12188720703125 +57432 0.297210693359375 +57433 0.10302734375 +57434 0.14862060546875 +57435 0.083709716796875 +57436 -0.00537109375 +57437 0.06011962890625 +57438 -0.15753173828125 +57439 0.033416748046875 +57440 -0.31304931640625 +57441 0.0029296875 +57442 -0.48876953125 +57443 -0.033843994140625 +57444 -0.6416015625 +57445 -0.069183349609375 +57446 -0.751373291015625 +57447 -0.099090576171875 +57448 -0.84619140625 +57449 -0.127593994140625 +57450 -0.861297607421875 +57451 -0.152374267578125 +57452 -0.863250732421875 +57453 -0.168060302734375 +57454 -0.856597900390625 +57455 -0.16943359375 +57456 -0.7498779296875 +57457 -0.158660888671875 +57458 -0.624542236328125 +57459 -0.1455078125 +57460 -0.47808837890625 +57461 -0.1263427734375 +57462 -0.253387451171875 +57463 -0.091339111328125 +57464 0.003692626953125 +57465 -0.048126220703125 +57466 0.2257080078125 +57467 -0.00811767578125 +57468 0.427154541015625 +57469 0.030853271484375 +57470 0.643218994140625 +57471 0.0743408203125 +57472 0.855926513671875 +57473 0.120849609375 +57474 0.870361328125 +57475 0.160797119140625 +57476 0.870361328125 +57477 0.18603515625 +57478 0.862762451171875 +57479 0.1978759765625 +57480 0.79669189453125 +57481 0.195953369140625 +57482 0.595794677734375 +57483 0.178802490234375 +57484 0.362152099609375 +57485 0.151397705078125 +57486 0.1270751953125 +57487 0.118499755859375 +57488 -0.086944580078125 +57489 0.083648681640625 +57490 -0.2784423828125 +57491 0.047210693359375 +57492 -0.484832763671875 +57493 0.003265380859375 +57494 -0.729583740234375 +57495 -0.051422119140625 +57496 -0.86688232421875 +57497 -0.10845947265625 +57498 -0.870391845703125 +57499 -0.157318115234375 +57500 -0.86859130859375 +57501 -0.197265625 +57502 -0.86279296875 +57503 -0.228057861328125 +57504 -0.817962646484375 +57505 -0.243804931640625 +57506 -0.6116943359375 +57507 -0.236968994140625 +57508 -0.3128662109375 +57509 -0.2064208984375 +57510 0.039398193359375 +57511 -0.157928466796875 +57512 0.422821044921875 +57513 -0.094879150390625 +57514 0.805145263671875 +57515 -0.022918701171875 +57516 0.870361328125 +57517 0.046478271484375 +57518 0.870361328125 +57519 0.103759765625 +57520 0.860015869140625 +57521 0.14697265625 +57522 0.727935791015625 +57523 0.17486572265625 +57524 0.48114013671875 +57525 0.186553955078125 +57526 0.2059326171875 +57527 0.186187744140625 +57528 -0.06103515625 +57529 0.1776123046875 +57530 -0.29913330078125 +57531 0.16259765625 +57532 -0.516204833984375 +57533 0.1387939453125 +57534 -0.7252197265625 +57535 0.103729248046875 +57536 -0.85980224609375 +57537 0.0616455078125 +57538 -0.870391845703125 +57539 0.01837158203125 +57540 -0.870391845703125 +57541 -0.021026611328125 +57542 -0.858062744140625 +57543 -0.048309326171875 +57544 -0.673004150390625 +57545 -0.062713623046875 +57546 -0.42694091796875 +57547 -0.07305908203125 +57548 -0.2100830078125 +57549 -0.086761474609375 +57550 -0.0362548828125 +57551 -0.103424072265625 +57552 0.10943603515625 +57553 -0.118194580078125 +57554 0.23516845703125 +57555 -0.127685546875 +57556 0.373687744140625 +57557 -0.125 +57558 0.517791748046875 +57559 -0.110504150390625 +57560 0.602783203125 +57561 -0.0948486328125 +57562 0.635711669921875 +57563 -0.0772705078125 +57564 0.655181884765625 +57565 -0.05224609375 +57566 0.65948486328125 +57567 -0.02154541015625 +57568 0.651275634765625 +57569 0.013397216796875 +57570 0.61846923828125 +57571 0.048370361328125 +57572 0.53753662109375 +57573 0.07708740234375 +57574 0.404144287109375 +57575 0.096466064453125 +57576 0.22186279296875 +57577 0.1048583984375 +57578 0.003997802734375 +57579 0.102508544921875 +57580 -0.22100830078125 +57581 0.092437744140625 +57582 -0.42449951171875 +57583 0.078125 +57584 -0.579833984375 +57585 0.063201904296875 +57586 -0.641876220703125 +57587 0.05487060546875 +57588 -0.6177978515625 +57589 0.05206298828125 +57590 -0.575531005859375 +57591 0.04400634765625 +57592 -0.526336669921875 +57593 0.029876708984375 +57594 -0.42645263671875 +57595 0.0184326171875 +57596 -0.2581787109375 +57597 0.01434326171875 +57598 -0.068695068359375 +57599 0.011566162109375 +57600 0.09222412109375 +57601 0.00421142578125 +57602 0.232147216796875 +57603 -0.003936767578125 +57604 0.3509521484375 +57605 -0.01165771484375 +57606 0.410064697265625 +57607 -0.025390625 +57608 0.372955322265625 +57609 -0.05145263671875 +57610 0.2554931640625 +57611 -0.086029052734375 +57612 0.10711669921875 +57613 -0.118988037109375 +57614 -0.052886962890625 +57615 -0.146575927734375 +57616 -0.186279296875 +57617 -0.161651611328125 +57618 -0.23291015625 +57619 -0.153076171875 +57620 -0.209442138671875 +57621 -0.125335693359375 +57622 -0.174163818359375 +57623 -0.091461181640625 +57624 -0.126739501953125 +57625 -0.05291748046875 +57626 -0.048126220703125 +57627 -0.007568359375 +57628 0.0426025390625 +57629 0.039154052734375 +57630 0.10748291015625 +57631 0.078155517578125 +57632 0.1409912109375 +57633 0.10699462890625 +57634 0.19708251953125 +57635 0.1353759765625 +57636 0.273651123046875 +57637 0.162109375 +57638 0.31768798828125 +57639 0.1761474609375 +57640 0.341094970703125 +57641 0.179779052734375 +57642 0.368011474609375 +57643 0.178070068359375 +57644 0.37249755859375 +57645 0.1663818359375 +57646 0.30072021484375 +57647 0.134796142578125 +57648 0.1517333984375 +57649 0.084197998046875 +57650 -0.01470947265625 +57651 0.027801513671875 +57652 -0.1883544921875 +57653 -0.031005859375 +57654 -0.372711181640625 +57655 -0.091583251953125 +57656 -0.51397705078125 +57657 -0.14190673828125 +57658 -0.57177734375 +57659 -0.172760009765625 +57660 -0.53948974609375 +57661 -0.18182373046875 +57662 -0.43511962890625 +57663 -0.171966552734375 +57664 -0.2962646484375 +57665 -0.150238037109375 +57666 -0.161102294921875 +57667 -0.12408447265625 +57668 -0.0435791015625 +57669 -0.096405029296875 +57670 0.060394287109375 +57671 -0.0667724609375 +57672 0.13665771484375 +57673 -0.038604736328125 +57674 0.170135498046875 +57675 -0.0157470703125 +57676 0.16552734375 +57677 0.001739501953125 +57678 0.15728759765625 +57679 0.019683837890625 +57680 0.150787353515625 +57681 0.038055419921875 +57682 0.12200927734375 +57683 0.05096435546875 +57684 0.080108642578125 +57685 0.05926513671875 +57686 0.05126953125 +57687 0.06732177734375 +57688 0.062896728515625 +57689 0.0799560546875 +57690 0.09271240234375 +57691 0.092254638671875 +57692 0.092987060546875 +57693 0.094451904296875 +57694 0.07855224609375 +57695 0.089508056640625 +57696 0.06427001953125 +57697 0.080657958984375 +57698 0.0347900390625 +57699 0.06524658203125 +57700 -0.01171875 +57701 0.04351806640625 +57702 -0.056060791015625 +57703 0.02008056640625 +57704 -0.055511474609375 +57705 0.004364013671875 +57706 -0.010467529296875 +57707 -0.0028076171875 +57708 0.02508544921875 +57709 -0.0113525390625 +57710 0.025665283203125 +57711 -0.025543212890625 +57712 0.017333984375 +57713 -0.0394287109375 +57714 0.00189208984375 +57715 -0.052001953125 +57716 -0.03173828125 +57717 -0.0650634765625 +57718 -0.071502685546875 +57719 -0.075958251953125 +57720 -0.13543701171875 +57721 -0.088226318359375 +57722 -0.219970703125 +57723 -0.10125732421875 +57724 -0.300506591796875 +57725 -0.110443115234375 +57726 -0.376312255859375 +57727 -0.1160888671875 +57728 -0.416107177734375 +57729 -0.112548828125 +57730 -0.371124267578125 +57731 -0.09075927734375 +57732 -0.242279052734375 +57733 -0.051666259765625 +57734 -0.069732666015625 +57735 -0.0040283203125 +57736 0.125640869140625 +57737 0.0472412109375 +57738 0.31268310546875 +57739 0.095306396484375 +57740 0.45501708984375 +57741 0.13232421875 +57742 0.554779052734375 +57743 0.158294677734375 +57744 0.61065673828125 +57745 0.1727294921875 +57746 0.610931396484375 +57747 0.173187255859375 +57748 0.531463623046875 +57749 0.1549072265625 +57750 0.3883056640625 +57751 0.121337890625 +57752 0.23468017578125 +57753 0.083465576171875 +57754 0.095245361328125 +57755 0.046661376953125 +57756 -0.00396728515625 +57757 0.01666259765625 +57758 -0.04852294921875 +57759 -0.0030517578125 +57760 -0.055145263671875 +57761 -0.01519775390625 +57762 -0.0758056640625 +57763 -0.02960205078125 +57764 -0.138702392578125 +57765 -0.051361083984375 +57766 -0.209197998046875 +57767 -0.07305908203125 +57768 -0.289031982421875 +57769 -0.094696044921875 +57770 -0.37884521484375 +57771 -0.116119384765625 +57772 -0.456329345703125 +57773 -0.132720947265625 +57774 -0.51641845703125 +57775 -0.1435546875 +57776 -0.519287109375 +57777 -0.140777587890625 +57778 -0.458251953125 +57779 -0.123291015625 +57780 -0.384796142578125 +57781 -0.101715087890625 +57782 -0.323699951171875 +57783 -0.0814208984375 +57784 -0.269287109375 +57785 -0.061737060546875 +57786 -0.1951904296875 +57787 -0.03790283203125 +57788 -0.100006103515625 +57789 -0.0101318359375 +57790 -0.01055908203125 +57791 0.015716552734375 +57792 0.1033935546875 +57793 0.045257568359375 +57794 0.24908447265625 +57795 0.079620361328125 +57796 0.373199462890625 +57797 0.107879638671875 +57798 0.45806884765625 +57799 0.126373291015625 +57800 0.511474609375 +57801 0.136627197265625 +57802 0.565399169921875 +57803 0.1451416015625 +57804 0.61138916015625 +57805 0.150360107421875 +57806 0.5897216796875 +57807 0.140625 +57808 0.4906005859375 +57809 0.11431884765625 +57810 0.33148193359375 +57811 0.0753173828125 +57812 0.147796630859375 +57813 0.0311279296875 +57814 -0.01873779296875 +57815 -0.009490966796875 +57816 -0.140289306640625 +57817 -0.040557861328125 +57818 -0.191986083984375 +57819 -0.056732177734375 +57820 -0.184295654296875 +57821 -0.059844970703125 +57822 -0.161834716796875 +57823 -0.05859375 +57824 -0.166595458984375 +57825 -0.061248779296875 +57826 -0.19390869140625 +57827 -0.066802978515625 +57828 -0.22442626953125 +57829 -0.071441650390625 +57830 -0.279754638671875 +57831 -0.079620361328125 +57832 -0.3389892578125 +57833 -0.08734130859375 +57834 -0.3543701171875 +57835 -0.0853271484375 +57836 -0.348175048828125 +57837 -0.078338623046875 +57838 -0.32598876953125 +57839 -0.06781005859375 +57840 -0.2581787109375 +57841 -0.048187255859375 +57842 -0.139801025390625 +57843 -0.018798828125 +57844 0.014617919921875 +57845 0.01715087890625 +57846 0.144378662109375 +57847 0.047210693359375 +57848 0.221038818359375 +57849 0.065521240234375 +57850 0.27069091796875 +57851 0.077178955078125 +57852 0.294036865234375 +57853 0.082275390625 +57854 0.311767578125 +57855 0.0849609375 +57856 0.339141845703125 +57857 0.088470458984375 +57858 0.360260009765625 +57859 0.090179443359375 +57860 0.360504150390625 +57861 0.08721923828125 +57862 0.308380126953125 +57863 0.072296142578125 +57864 0.18170166015625 +57865 0.040313720703125 +57866 0.0047607421875 +57867 -0.002960205078125 +57868 -0.17559814453125 +57869 -0.046661376953125 +57870 -0.3143310546875 +57871 -0.080291748046875 +57872 -0.36785888671875 +57873 -0.093719482421875 +57874 -0.36248779296875 +57875 -0.093017578125 +57876 -0.343536376953125 +57877 -0.08868408203125 +57878 -0.3018798828125 +57879 -0.078643798828125 +57880 -0.231414794921875 +57881 -0.061492919921875 +57882 -0.117645263671875 +57883 -0.033905029296875 +57884 0.007049560546875 +57885 -0.00347900390625 +57886 0.087982177734375 +57887 0.016998291015625 +57888 0.13946533203125 +57889 0.03076171875 +57890 0.17425537109375 +57891 0.040679931640625 +57892 0.188201904296875 +57893 0.045684814453125 +57894 0.171234130859375 +57895 0.0433349609375 +57896 0.118438720703125 +57897 0.032440185546875 +57898 0.05706787109375 +57899 0.019256591796875 +57900 -0.010711669921875 +57901 0.004241943359375 +57902 -0.0914306640625 +57903 -0.014129638671875 +57904 -0.162322998046875 +57905 -0.03057861328125 +57906 -0.194549560546875 +57907 -0.038421630859375 +57908 -0.1492919921875 +57909 -0.02862548828125 +57910 -0.02166748046875 +57911 -3.0517578125e-05 +57912 0.124053955078125 +57913 0.03253173828125 +57914 0.211151123046875 +57915 0.051300048828125 +57916 0.240447998046875 +57917 0.056549072265625 +57918 0.242218017578125 +57919 0.055389404296875 +57920 0.2257080078125 +57921 0.050079345703125 +57922 0.194366455078125 +57923 0.04150390625 +57924 0.115509033203125 +57925 0.022125244140625 +57926 0.0128173828125 +57927 -0.00244140625 +57928 -0.053802490234375 +57929 -0.018280029296875 +57930 -0.110626220703125 +57931 -0.031494140625 +57932 -0.199493408203125 +57933 -0.05181884765625 +57934 -0.29437255859375 +57935 -0.073211669921875 +57936 -0.33221435546875 +57937 -0.081085205078125 +57938 -0.27972412109375 +57939 -0.067779541015625 +57940 -0.185333251953125 +57941 -0.04461669921875 +57942 -0.128204345703125 +57943 -0.030029296875 +57944 -0.115692138671875 +57945 -0.025787353515625 +57946 -0.116455078125 +57947 -0.024688720703125 +57948 -0.105926513671875 +57949 -0.0211181640625 +57950 -0.053955078125 +57951 -0.00811767578125 +57952 0.048797607421875 +57953 0.016387939453125 +57954 0.157318115234375 +57955 0.04193115234375 +57956 0.212005615234375 +57957 0.054656982421875 +57958 0.218475341796875 +57959 0.055877685546875 +57960 0.23724365234375 +57961 0.0596923828125 +57962 0.30535888671875 +57963 0.07470703125 +57964 0.38128662109375 +57965 0.091339111328125 +57966 0.404449462890625 +57967 0.0955810546875 +57968 0.3944091796875 +57969 0.092071533203125 +57970 0.3885498046875 +57971 0.089508056640625 +57972 0.362640380859375 +57973 0.082366943359375 +57974 0.27362060546875 +57975 0.060699462890625 +57976 0.11712646484375 +57977 0.0235595703125 +57978 -0.054901123046875 +57979 -0.01690673828125 +57980 -0.19085693359375 +57981 -0.0487060546875 +57982 -0.28570556640625 +57983 -0.070709228515625 +57984 -0.339263916015625 +57985 -0.082855224609375 +57986 -0.3775634765625 +57987 -0.091217041015625 +57988 -0.445709228515625 +57989 -0.106292724609375 +57990 -0.535064697265625 +57991 -0.12615966796875 +57992 -0.629058837890625 +57993 -0.147003173828125 +57994 -0.697601318359375 +57995 -0.161865234375 +57996 -0.70391845703125 +57997 -0.16229248046875 +57998 -0.6424560546875 +57999 -0.14703369140625 +58000 -0.491241455078125 +58001 -0.111053466796875 +58002 -0.265716552734375 +58003 -0.058013916015625 +58004 -0.023712158203125 +58005 -0.0013427734375 +58006 0.201751708984375 +58007 0.051239013671875 +58008 0.375823974609375 +58009 0.09161376953125 +58010 0.485076904296875 +58011 0.11669921875 +58012 0.56884765625 +58013 0.135650634765625 +58014 0.634765625 +58015 0.1502685546875 +58016 0.63763427734375 +58017 0.150115966796875 +58018 0.5660400390625 +58019 0.132598876953125 +58020 0.4720458984375 +58021 0.109832763671875 +58022 0.40692138671875 +58023 0.093780517578125 +58024 0.3778076171875 +58025 0.08612060546875 +58026 0.376953125 +58027 0.085113525390625 +58028 0.371978759765625 +58029 0.083282470703125 +58030 0.313140869140625 +58031 0.069122314453125 +58032 0.184417724609375 +58033 0.0389404296875 +58034 0.011199951171875 +58035 -0.001312255859375 +58036 -0.171051025390625 +58037 -0.04339599609375 +58038 -0.33740234375 +58039 -0.08154296875 +58040 -0.47198486328125 +58041 -0.11212158203125 +58042 -0.560394287109375 +58043 -0.1318359375 +58044 -0.58056640625 +58045 -0.135650634765625 +58046 -0.54754638671875 +58047 -0.1270751953125 +58048 -0.508575439453125 +58049 -0.117156982421875 +58050 -0.459503173828125 +58051 -0.104949951171875 +58052 -0.394378662109375 +58053 -0.089111328125 +58054 -0.35260009765625 +58055 -0.078765869140625 +58056 -0.31170654296875 +58057 -0.06878662109375 +58058 -0.197418212890625 +58059 -0.04193115234375 +58060 -0.007965087890625 +58061 0.00213623046875 +58062 0.207489013671875 +58063 0.052001953125 +58064 0.409210205078125 +58065 0.09844970703125 +58066 0.57208251953125 +58067 0.135711669921875 +58068 0.66595458984375 +58069 0.156829833984375 +58070 0.65875244140625 +58071 0.154388427734375 +58072 0.56744384765625 +58073 0.132354736328125 +58074 0.431396484375 +58075 0.099945068359375 +58076 0.29443359375 +58077 0.067352294921875 +58078 0.182464599609375 +58079 0.040618896484375 +58080 0.06365966796875 +58081 0.012420654296875 +58082 -0.075958251953125 +58083 -0.020416259765625 +58084 -0.189422607421875 +58085 -0.0469970703125 +58086 -0.271942138671875 +58087 -0.066192626953125 +58088 -0.342529296875 +58089 -0.082427978515625 +58090 -0.364166259765625 +58091 -0.087158203125 +58092 -0.327239990234375 +58093 -0.078155517578125 +58094 -0.2769775390625 +58095 -0.06591796875 +58096 -0.253692626953125 +58097 -0.059844970703125 +58098 -0.24365234375 +58099 -0.056793212890625 +58100 -0.1983642578125 +58101 -0.0455322265625 +58102 -0.116241455078125 +58103 -0.025726318359375 +58104 -0.036834716796875 +58105 -0.006591796875 +58106 0.034881591796875 +58107 0.0106201171875 +58108 0.09124755859375 +58109 0.02410888671875 +58110 0.10888671875 +58111 0.028411865234375 +58112 0.125518798828125 +58113 0.032684326171875 +58114 0.15771484375 +58115 0.0408935546875 +58116 0.17828369140625 +58117 0.046234130859375 +58118 0.17108154296875 +58119 0.044342041015625 +58120 0.129974365234375 +58121 0.03350830078125 +58122 0.082427978515625 +58123 0.02093505859375 +58124 0.027679443359375 +58125 0.00640869140625 +58126 -0.065643310546875 +58127 -0.018341064453125 +58128 -0.15936279296875 +58129 -0.043212890625 +58130 -0.21307373046875 +58131 -0.057525634765625 +58132 -0.234649658203125 +58133 -0.063323974609375 +58134 -0.2001953125 +58135 -0.054290771484375 +58136 -0.119171142578125 +58137 -0.032928466796875 +58138 -0.024749755859375 +58139 -0.00799560546875 +58140 0.085784912109375 +58141 0.021240234375 +58142 0.178131103515625 +58143 0.04571533203125 +58144 0.215576171875 +58145 0.055755615234375 +58146 0.211456298828125 +58147 0.05487060546875 +58148 0.17523193359375 +58149 0.045562744140625 +58150 0.128753662109375 +58151 0.033599853515625 +58152 0.1019287109375 +58153 0.02685546875 +58154 0.0743408203125 +58155 0.0198974609375 +58156 0.04327392578125 +58157 0.011993408203125 +58158 0.038177490234375 +58159 0.010894775390625 +58160 0.076263427734375 +58161 0.021148681640625 +58162 0.14105224609375 +58163 0.03839111328125 +58164 0.186431884765625 +58165 0.050445556640625 +58166 0.188812255859375 +58167 0.051055908203125 +58168 0.1390380859375 +58169 0.037841796875 +58170 0.041778564453125 +58171 0.012054443359375 +58172 -0.079437255859375 +58173 -0.02008056640625 +58174 -0.219390869140625 +58175 -0.05718994140625 +58176 -0.367828369140625 +58177 -0.096527099609375 +58178 -0.494873046875 +58179 -0.130218505859375 +58180 -0.556243896484375 +58181 -0.14654541015625 +58182 -0.508697509765625 +58183 -0.13409423828125 +58184 -0.3756103515625 +58185 -0.09906005859375 +58186 -0.218902587890625 +58187 -0.057769775390625 +58188 -0.063751220703125 +58189 -0.016845703125 +58190 0.091552734375 +58191 0.024078369140625 +58192 0.23602294921875 +58193 0.0621337890625 +58194 0.342987060546875 +58195 0.09027099609375 +58196 0.39520263671875 +58197 0.103973388671875 +58198 0.389373779296875 +58199 0.10235595703125 +58200 0.324249267578125 +58201 0.085113525390625 +58202 0.224090576171875 +58203 0.05865478515625 +58204 0.124267578125 +58205 0.0323486328125 +58206 0.037078857421875 +58207 0.0093994140625 +58208 -0.010101318359375 +58209 -0.0029296875 +58210 -0.019439697265625 +58211 -0.0052490234375 +58212 -0.022796630859375 +58213 -0.0059814453125 +58214 -0.001556396484375 +58215 -0.00018310546875 +58216 0.056304931640625 +58217 0.0152587890625 +58218 0.106719970703125 +58219 0.0286865234375 +58220 0.096893310546875 +58221 0.026153564453125 +58222 0.042694091796875 +58223 0.011871337890625 +58224 -0.018035888671875 +58225 -0.004150390625 +58226 -0.07586669921875 +58227 -0.0194091796875 +58228 -0.11944580078125 +58229 -0.030914306640625 +58230 -0.15972900390625 +58231 -0.04156494140625 +58232 -0.202606201171875 +58233 -0.05291748046875 +58234 -0.24859619140625 +58235 -0.0650634765625 +58236 -0.30517578125 +58237 -0.079986572265625 +58238 -0.36212158203125 +58239 -0.095001220703125 +58240 -0.39141845703125 +58241 -0.102752685546875 +58242 -0.35528564453125 +58243 -0.093231201171875 +58244 -0.249969482421875 +58245 -0.065460205078125 +58246 -0.092864990234375 +58247 -0.024017333984375 +58248 0.08905029296875 +58249 0.02392578125 +58250 0.2352294921875 +58251 0.062408447265625 +58252 0.318817138671875 +58253 0.084381103515625 +58254 0.358642578125 +58255 0.09478759765625 +58256 0.347747802734375 +58257 0.091796875 +58258 0.28564453125 +58259 0.075286865234375 +58260 0.223175048828125 +58261 0.058685302734375 +58262 0.196746826171875 +58263 0.051605224609375 +58264 0.179840087890625 +58265 0.047088623046875 +58266 0.155548095703125 +58267 0.0406494140625 +58268 0.151214599609375 +58269 0.039520263671875 +58270 0.156951904296875 +58271 0.04107666015625 +58272 0.13177490234375 +58273 0.03448486328125 +58274 0.100799560546875 +58275 0.026397705078125 +58276 0.087127685546875 +58277 0.02288818359375 +58278 0.05487060546875 +58279 0.01446533203125 +58280 -0.009002685546875 +58281 -0.002288818359375 +58282 -0.10400390625 +58283 -0.027252197265625 +58284 -0.229400634765625 +58285 -0.06024169921875 +58286 -0.35552978515625 +58287 -0.093414306640625 +58288 -0.441925048828125 +58289 -0.1160888671875 +58290 -0.473846435546875 +58291 -0.124420166015625 +58292 -0.464813232421875 +58293 -0.1219482421875 +58294 -0.419097900390625 +58295 -0.10980224609375 +58296 -0.334320068359375 +58297 -0.087371826171875 +58298 -0.227935791015625 +58299 -0.059234619140625 +58300 -0.12347412109375 +58301 -0.031646728515625 +58302 -0.02764892578125 +58303 -0.00634765625 +58304 0.077667236328125 +58305 0.021392822265625 +58306 0.2132568359375 +58307 0.05706787109375 +58308 0.38885498046875 +58309 0.103271484375 +58310 0.582794189453125 +58311 0.154296875 +58312 0.734039306640625 +58313 0.19403076171875 +58314 0.800140380859375 +58315 0.21124267578125 +58316 0.7783203125 +58317 0.205230712890625 +58318 0.6651611328125 +58319 0.17510986328125 +58320 0.45965576171875 +58321 0.12066650390625 +58322 0.199188232421875 +58323 0.051788330078125 +58324 -0.050689697265625 +58325 -0.01422119140625 +58326 -0.23297119140625 +58327 -0.06231689453125 +58328 -0.33013916015625 +58329 -0.087890625 +58330 -0.368408203125 +58331 -0.09783935546875 +58332 -0.378936767578125 +58333 -0.10040283203125 +58334 -0.376983642578125 +58335 -0.099639892578125 +58336 -0.37969970703125 +58337 -0.10009765625 +58338 -0.391510009765625 +58339 -0.102935791015625 +58340 -0.385345458984375 +58341 -0.101043701171875 +58342 -0.3419189453125 +58343 -0.089324951171875 +58344 -0.28289794921875 +58345 -0.073516845703125 +58346 -0.251617431640625 +58347 -0.0650634765625 +58348 -0.266143798828125 +58349 -0.068756103515625 +58350 -0.273345947265625 +58351 -0.070587158203125 +58352 -0.216796875 +58353 -0.055633544921875 +58354 -0.128265380859375 +58355 -0.03228759765625 +58356 -0.068145751953125 +58357 -0.0164794921875 +58358 -0.0430908203125 +58359 -0.009979248046875 +58360 -0.024444580078125 +58361 -0.005218505859375 +58362 0.020721435546875 +58363 0.0064697265625 +58364 0.124481201171875 +58365 0.0335693359375 +58366 0.25787353515625 +58367 0.068450927734375 +58368 0.379119873046875 +58369 0.100677490234375 +58370 0.47991943359375 +58371 0.127899169921875 +58372 0.5281982421875 +58373 0.140289306640625 +58374 0.511138916015625 +58375 0.134246826171875 +58376 0.456207275390625 +58377 0.118011474609375 +58378 0.407470703125 +58379 0.104644775390625 +58380 0.383758544921875 +58381 0.099639892578125 +58382 0.35687255859375 +58383 0.094482421875 +58384 0.31182861328125 +58385 0.0845947265625 +58386 0.250885009765625 +58387 0.070404052734375 +58388 0.1654052734375 +58389 0.04913330078125 +58390 0.035247802734375 +58391 0.01458740234375 +58392 -0.142059326171875 +58393 -0.0341796875 +58394 -0.33563232421875 +58395 -0.0882568359375 +58396 -0.5345458984375 +58397 -0.14453125 +58398 -0.72186279296875 +58399 -0.198150634765625 +58400 -0.836669921875 +58401 -0.23114013671875 +58402 -0.8326416015625 +58403 -0.2298583984375 +58404 -0.7296142578125 +58405 -0.200164794921875 +58406 -0.582550048828125 +58407 -0.15826416015625 +58408 -0.440093994140625 +58409 -0.118438720703125 +58410 -0.324310302734375 +58411 -0.08709716796875 +58412 -0.20147705078125 +58413 -0.054046630859375 +58414 -0.044647216796875 +58415 -0.0111083984375 +58416 0.103973388671875 +58417 0.029388427734375 +58418 0.202392578125 +58419 0.055206298828125 +58420 0.264495849609375 +58421 0.07061767578125 +58422 0.338897705078125 +58423 0.09014892578125 +58424 0.443817138671875 +58425 0.11932373046875 +58426 0.545074462890625 +58427 0.14813232421875 +58428 0.6173095703125 +58429 0.169097900390625 +58430 0.6524658203125 +58431 0.179840087890625 +58432 0.66339111328125 +58433 0.184112548828125 +58434 0.6561279296875 +58435 0.183624267578125 +58436 0.606781005859375 +58437 0.171173095703125 +58438 0.501190185546875 +58439 0.1424560546875 +58440 0.352783203125 +58441 0.101318359375 +58442 0.176544189453125 +58443 0.052001953125 +58444 -0.034820556640625 +58445 -0.00775146484375 +58446 -0.258209228515625 +58447 -0.07122802734375 +58448 -0.44244384765625 +58449 -0.1234130859375 +58450 -0.5753173828125 +58451 -0.160858154296875 +58452 -0.65203857421875 +58453 -0.182220458984375 +58454 -0.641632080078125 +58455 -0.178375244140625 +58456 -0.562164306640625 +58457 -0.154754638671875 +58458 -0.458038330078125 +58459 -0.124481201171875 +58460 -0.350555419921875 +58461 -0.093780517578125 +58462 -0.260528564453125 +58463 -0.0687255859375 +58464 -0.192108154296875 +58465 -0.05047607421875 +58466 -0.141937255859375 +58467 -0.03790283203125 +58468 -0.1021728515625 +58469 -0.028564453125 +58470 -0.062896728515625 +58471 -0.01934814453125 +58472 -0.011932373046875 +58473 -0.006561279296875 +58474 0.062835693359375 +58475 0.013519287109375 +58476 0.148712158203125 +58477 0.0372314453125 +58478 0.241729736328125 +58479 0.0634765625 +58480 0.34912109375 +58481 0.09442138671875 +58482 0.457305908203125 +58483 0.126129150390625 +58484 0.54388427734375 +58485 0.151947021484375 +58486 0.5728759765625 +58487 0.16119384765625 +58488 0.506591796875 +58489 0.142669677734375 +58490 0.351226806640625 +58491 0.09814453125 +58492 0.146514892578125 +58493 0.039276123046875 +58494 -0.05523681640625 +58495 -0.01849365234375 +58496 -0.21624755859375 +58497 -0.064117431640625 +58498 -0.334930419921875 +58499 -0.09722900390625 +58500 -0.402984619140625 +58501 -0.115478515625 +58502 -0.4412841796875 +58503 -0.1251220703125 +58504 -0.49578857421875 +58505 -0.139892578125 +58506 -0.5601806640625 +58507 -0.157958984375 +58508 -0.600738525390625 +58509 -0.169403076171875 +58510 -0.584228515625 +58511 -0.164398193359375 +58512 -0.47930908203125 +58513 -0.1336669921875 +58514 -0.27935791015625 +58515 -0.075225830078125 +58516 -0.0089111328125 +58517 0.003662109375 +58518 0.268798828125 +58519 0.0843505859375 +58520 0.482818603515625 +58521 0.145965576171875 +58522 0.60369873046875 +58523 0.17987060546875 +58524 0.650421142578125 +58525 0.191802978515625 +58526 0.66400146484375 +58527 0.194000244140625 +58528 0.6414794921875 +58529 0.185699462890625 +58530 0.572540283203125 +58531 0.1639404296875 +58532 0.498138427734375 +58533 0.140899658203125 +58534 0.439453125 +58535 0.1229248046875 +58536 0.375518798828125 +58537 0.10382080078125 +58538 0.274505615234375 +58539 0.07415771484375 +58540 0.1087646484375 +58541 0.025726318359375 +58542 -0.099395751953125 +58543 -0.034912109375 +58544 -0.3182373046875 +58545 -0.098388671875 +58546 -0.5489501953125 +58547 -0.165191650390625 +58548 -0.7738037109375 +58549 -0.2301025390625 +58550 -0.86383056640625 +58551 -0.277557373046875 +58552 -0.870391845703125 +58553 -0.297821044921875 +58554 -0.86895751953125 +58555 -0.296234130859375 +58556 -0.861053466796875 +58557 -0.276763916015625 +58558 -0.765869140625 +58559 -0.234344482421875 +58560 -0.5301513671875 +58561 -0.165679931640625 +58562 -0.214691162109375 +58563 -0.072906494140625 +58564 0.137359619140625 +58565 0.031219482421875 +58566 0.474822998046875 +58567 0.13153076171875 +58568 0.76239013671875 +58569 0.217559814453125 +58570 0.867462158203125 +58571 0.281341552734375 +58572 0.870361328125 +58573 0.323089599609375 +58574 0.86480712890625 +58575 0.339447021484375 +58576 0.831817626953125 +58577 0.332061767578125 +58578 0.677581787109375 +58579 0.308258056640625 +58580 0.495880126953125 +58581 0.269805908203125 +58582 0.30767822265625 +58583 0.2222900390625 +58584 0.116180419921875 +58585 0.166412353515625 +58586 -0.110748291015625 +58587 0.09283447265625 +58588 -0.381805419921875 +58589 -0.000457763671875 +58590 -0.6572265625 +58591 -0.10076904296875 +58592 -0.857421875 +58593 -0.19036865234375 +58594 -0.870391845703125 +58595 -0.256591796875 +58596 -0.870391845703125 +58597 -0.29736328125 +58598 -0.86444091796875 +58599 -0.320709228515625 +58600 -0.85723876953125 +58601 -0.337249755859375 +58602 -0.790008544921875 +58603 -0.341644287109375 +58604 -0.62847900390625 +58605 -0.31787109375 +58606 -0.3956298828125 +58607 -0.26507568359375 +58608 -0.126708984375 +58609 -0.19305419921875 +58610 0.150115966796875 +58611 -0.109954833984375 +58612 0.424041748046875 +58613 -0.019317626953125 +58614 0.670623779296875 +58615 0.070831298828125 +58616 0.854522705078125 +58617 0.149017333984375 +58618 0.866485595703125 +58619 0.21002197265625 +58620 0.86920166015625 +58621 0.249298095703125 +58622 0.8653564453125 +58623 0.272247314453125 +58624 0.857147216796875 +58625 0.282623291015625 +58626 0.766845703125 +58627 0.2799072265625 +58628 0.628509521484375 +58629 0.266021728515625 +58630 0.462127685546875 +58631 0.23870849609375 +58632 0.297210693359375 +58633 0.20635986328125 +58634 0.14862060546875 +58635 0.17279052734375 +58636 -0.00537109375 +58637 0.130279541015625 +58638 -0.15753173828125 +58639 0.080963134765625 +58640 -0.31304931640625 +58641 0.023345947265625 +58642 -0.48876953125 +58643 -0.04754638671875 +58644 -0.6416015625 +58645 -0.11663818359375 +58646 -0.751373291015625 +58647 -0.176116943359375 +58648 -0.84619140625 +58649 -0.233795166015625 +58650 -0.861297607421875 +58651 -0.285064697265625 +58652 -0.863250732421875 +58653 -0.319183349609375 +58654 -0.856597900390625 +58655 -0.3258056640625 +58656 -0.7498779296875 +58657 -0.30889892578125 +58658 -0.624542236328125 +58659 -0.287353515625 +58660 -0.47808837890625 +58661 -0.2537841796875 +58662 -0.253387451171875 +58663 -0.1888427734375 +58664 0.003692626953125 +58665 -0.10723876953125 +58666 0.2257080078125 +58667 -0.0311279296875 +58668 0.427154541015625 +58669 0.04388427734375 +58670 0.643218994140625 +58671 0.128662109375 +58672 0.855926513671875 +58673 0.220306396484375 +58674 0.870361328125 +58675 0.300018310546875 +58676 0.870361328125 +58677 0.3516845703125 +58678 0.862762451171875 +58679 0.377777099609375 +58680 0.79669189453125 +58681 0.37738037109375 +58682 0.595794677734375 +58683 0.347412109375 +58684 0.362152099609375 +58685 0.29742431640625 +58686 0.1270751953125 +58687 0.2364501953125 +58688 -0.086944580078125 +58689 0.171295166015625 +58690 -0.2784423828125 +58691 0.10247802734375 +58692 -0.484832763671875 +58693 0.018402099609375 +58694 -0.729583740234375 +58695 -0.087432861328125 +58696 -0.86688232421875 +58697 -0.19866943359375 +58698 -0.870391845703125 +58699 -0.294708251953125 +58700 -0.86859130859375 +58701 -0.37408447265625 +58702 -0.86279296875 +58703 -0.43621826171875 +58704 -0.817962646484375 +58705 -0.46942138671875 +58706 -0.6116943359375 +58707 -0.4588623046875 +58708 -0.3128662109375 +58709 -0.402191162109375 +58710 0.039398193359375 +58711 -0.310455322265625 +58712 0.422821044921875 +58713 -0.190155029296875 +58714 0.805145263671875 +58715 -0.0521240234375 +58716 0.870361328125 +58717 0.081390380859375 +58718 0.870361328125 +58719 0.191802978515625 +58720 0.860015869140625 +58721 0.275421142578125 +58722 0.727935791015625 +58723 0.329803466796875 +58724 0.48114013671875 +58725 0.353179931640625 +58726 0.2059326171875 +58727 0.35357666015625 +58728 -0.06103515625 +58729 0.3385009765625 +58730 -0.29913330078125 +58731 0.311248779296875 +58732 -0.516204833984375 +58733 0.26708984375 +58734 -0.7252197265625 +58735 0.2010498046875 +58736 -0.85980224609375 +58737 0.12127685546875 +58738 -0.870391845703125 +58739 0.0390625 +58740 -0.870391845703125 +58741 -0.035858154296875 +58742 -0.858062744140625 +58743 -0.087493896484375 +58744 -0.673004150390625 +58745 -0.11444091796875 +58746 -0.42694091796875 +58747 -0.133941650390625 +58748 -0.2100830078125 +58749 -0.16046142578125 +58750 -0.0362548828125 +58751 -0.193267822265625 +58752 0.10943603515625 +58753 -0.222808837890625 +58754 0.23516845703125 +58755 -0.242523193359375 +58756 0.373687744140625 +58757 -0.23883056640625 +58758 0.517791748046875 +58759 -0.212371826171875 +58760 0.602783203125 +58761 -0.183807373046875 +58762 0.635711669921875 +58763 -0.1514892578125 +58764 0.655181884765625 +58765 -0.10455322265625 +58766 0.65948486328125 +58767 -0.04632568359375 +58768 0.651275634765625 +58769 0.020477294921875 +58770 0.61846923828125 +58771 0.087738037109375 +58772 0.53753662109375 +58773 0.143218994140625 +58774 0.404144287109375 +58775 0.180938720703125 +58776 0.22186279296875 +58777 0.1976318359375 +58778 0.003997802734375 +58779 0.19366455078125 +58780 -0.22100830078125 +58781 0.1749267578125 +58782 -0.42449951171875 +58783 0.148162841796875 +58784 -0.579833984375 +58785 0.120391845703125 +58786 -0.641876220703125 +58787 0.105621337890625 +58788 -0.6177978515625 +58789 0.1016845703125 +58790 -0.575531005859375 +58791 0.08746337890625 +58792 -0.526336669921875 +58793 0.061248779296875 +58794 -0.42645263671875 +58795 0.04010009765625 +58796 -0.2581787109375 +58797 0.0330810546875 +58798 -0.068695068359375 +58799 0.02838134765625 +58800 0.09222412109375 +58801 0.013458251953125 +58802 0.232147216796875 +58803 -0.0054931640625 +58804 0.3509521484375 +58805 -0.0250244140625 +58806 0.410064697265625 +58807 -0.0548095703125 +58808 0.372955322265625 +58809 -0.1043701171875 +58810 0.2554931640625 +58811 -0.16680908203125 +58812 0.10711669921875 +58813 -0.225006103515625 +58814 -0.052886962890625 +58815 -0.27252197265625 +58816 -0.186279296875 +58817 -0.2974853515625 +58818 -0.23291015625 +58819 -0.2816162109375 +58820 -0.209442138671875 +58821 -0.232452392578125 +58822 -0.174163818359375 +58823 -0.171630859375 +58824 -0.126739501953125 +58825 -0.10198974609375 +58826 -0.048126220703125 +58827 -0.020355224609375 +58828 0.0426025390625 +58829 0.063873291015625 +58830 0.10748291015625 +58831 0.135345458984375 +58832 0.1409912109375 +58833 0.189605712890625 +58834 0.19708251953125 +58835 0.2421875 +58836 0.273651123046875 +58837 0.29083251953125 +58838 0.31768798828125 +58839 0.317169189453125 +58840 0.341094970703125 +58841 0.32476806640625 +58842 0.368011474609375 +58843 0.321929931640625 +58844 0.37249755859375 +58845 0.301116943359375 +58846 0.30072021484375 +58847 0.246185302734375 +58848 0.1517333984375 +58849 0.15875244140625 +58850 -0.01470947265625 +58851 0.060760498046875 +58852 -0.1883544921875 +58853 -0.041900634765625 +58854 -0.372711181640625 +58855 -0.147796630859375 +58856 -0.51397705078125 +58857 -0.236846923828125 +58858 -0.57177734375 +58859 -0.293548583984375 +58860 -0.53948974609375 +58861 -0.313812255859375 +58862 -0.43511962890625 +58863 -0.30206298828125 +58864 -0.2962646484375 +58865 -0.2696533203125 +58866 -0.161102294921875 +58867 -0.228668212890625 +58868 -0.0435791015625 +58869 -0.183746337890625 +58870 0.060394287109375 +58871 -0.134185791015625 +58872 0.13665771484375 +58873 -0.08575439453125 +58874 0.170135498046875 +58875 -0.04486083984375 +58876 0.16552734375 +58877 -0.01177978515625 +58878 0.15728759765625 +58879 0.022705078125 +58880 0.150787353515625 +58881 0.058074951171875 +58882 0.12200927734375 +58883 0.0843505859375 +58884 0.080108642578125 +58885 0.10296630859375 +58886 0.05126953125 +58887 0.121185302734375 +58888 0.062896728515625 +58889 0.147125244140625 +58890 0.09271240234375 +58891 0.171905517578125 +58892 0.092987060546875 +58893 0.17822265625 +58894 0.07855224609375 +58895 0.171142578125 +58896 0.06427001953125 +58897 0.15625 +58898 0.0347900390625 +58899 0.12890625 +58900 -0.01171875 +58901 0.089630126953125 +58902 -0.056060791015625 +58903 0.04656982421875 +58904 -0.055511474609375 +58905 0.016326904296875 +58906 -0.010467529296875 +58907 0.00054931640625 +58908 0.02508544921875 +58909 -0.017852783203125 +58910 0.025665283203125 +58911 -0.046142578125 +58912 0.017333984375 +58913 -0.073699951171875 +58914 0.00189208984375 +58915 -0.098663330078125 +58916 -0.03173828125 +58917 -0.123992919921875 +58918 -0.071502685546875 +58919 -0.144927978515625 +58920 -0.13543701171875 +58921 -0.16754150390625 +58922 -0.219970703125 +58923 -0.1907958984375 +58924 -0.300506591796875 +58925 -0.20660400390625 +58926 -0.376312255859375 +58927 -0.21551513671875 +58928 -0.416107177734375 +58929 -0.207733154296875 +58930 -0.371124267578125 +58931 -0.16748046875 +58932 -0.242279052734375 +58933 -0.09649658203125 +58934 -0.069732666015625 +58935 -0.01031494140625 +58936 0.125640869140625 +58937 0.082305908203125 +58938 0.31268310546875 +58939 0.169219970703125 +58940 0.45501708984375 +58941 0.236572265625 +58942 0.554779052734375 +58943 0.2843017578125 +58944 0.61065673828125 +58945 0.3114013671875 +58946 0.610931396484375 +58947 0.313507080078125 +58948 0.531463623046875 +58949 0.282196044921875 +58950 0.3883056640625 +58951 0.223480224609375 +58952 0.23468017578125 +58953 0.15655517578125 +58954 0.095245361328125 +58955 0.0909423828125 +58956 -0.00396728515625 +58957 0.036773681640625 +58958 -0.04852294921875 +58959 0.00018310546875 +58960 -0.055145263671875 +58961 -0.0234375 +58962 -0.0758056640625 +58963 -0.051116943359375 +58964 -0.138702392578125 +58965 -0.091644287109375 +58966 -0.209197998046875 +58967 -0.131927490234375 +58968 -0.289031982421875 +58969 -0.17181396484375 +58970 -0.37884521484375 +58971 -0.210968017578125 +58972 -0.456329345703125 +58973 -0.241302490234375 +58974 -0.51641845703125 +58975 -0.260986328125 +58976 -0.519287109375 +58977 -0.256256103515625 +58978 -0.458251953125 +58979 -0.225250244140625 +58980 -0.384796142578125 +58981 -0.186614990234375 +58982 -0.323699951171875 +58983 -0.14984130859375 +58984 -0.269287109375 +58985 -0.11383056640625 +58986 -0.1951904296875 +58987 -0.0703125 +58988 -0.100006103515625 +58989 -0.019805908203125 +58990 -0.01055908203125 +58991 0.027374267578125 +58992 0.1033935546875 +58993 0.080963134765625 +58994 0.24908447265625 +58995 0.142852783203125 +58996 0.373199462890625 +58997 0.19384765625 +58998 0.45806884765625 +58999 0.227447509765625 +59000 0.511474609375 +59001 0.24627685546875 +59002 0.565399169921875 +59003 0.261627197265625 +59004 0.61138916015625 +59005 0.27081298828125 +59006 0.5897216796875 +59007 0.25341796875 +59008 0.4906005859375 +59009 0.20660400390625 +59010 0.33148193359375 +59011 0.137237548828125 +59012 0.147796630859375 +59013 0.058502197265625 +59014 -0.01873779296875 +59015 -0.01416015625 +59016 -0.140289306640625 +59017 -0.070220947265625 +59018 -0.191986083984375 +59019 -0.10028076171875 +59020 -0.184295654296875 +59021 -0.107391357421875 +59022 -0.161834716796875 +59023 -0.106689453125 +59024 -0.166595458984375 +59025 -0.112548828125 +59026 -0.19390869140625 +59027 -0.123199462890625 +59028 -0.22442626953125 +59029 -0.13189697265625 +59030 -0.279754638671875 +59031 -0.146392822265625 +59032 -0.3389892578125 +59033 -0.15972900390625 +59034 -0.3543701171875 +59035 -0.155670166015625 +59036 -0.348175048828125 +59037 -0.142578125 +59038 -0.32598876953125 +59039 -0.123077392578125 +59040 -0.2581787109375 +59041 -0.08746337890625 +59042 -0.139801025390625 +59043 -0.034637451171875 +59044 0.014617919921875 +59045 0.02972412109375 +59046 0.144378662109375 +59047 0.08380126953125 +59048 0.221038818359375 +59049 0.117218017578125 +59050 0.27069091796875 +59051 0.1387939453125 +59052 0.294036865234375 +59053 0.148651123046875 +59054 0.311767578125 +59055 0.154022216796875 +59056 0.339141845703125 +59057 0.160400390625 +59058 0.360260009765625 +59059 0.162567138671875 +59060 0.360504150390625 +59061 0.155731201171875 +59062 0.308380126953125 +59063 0.128936767578125 +59064 0.18170166015625 +59065 0.074615478515625 +59066 0.0047607421875 +59067 0.00201416015625 +59068 -0.17559814453125 +59069 -0.071502685546875 +59070 -0.3143310546875 +59071 -0.129302978515625 +59072 -0.36785888671875 +59073 -0.155303955078125 +59074 -0.36248779296875 +59075 -0.15869140625 +59076 -0.343536376953125 +59077 -0.155487060546875 +59078 -0.3018798828125 +59079 -0.142303466796875 +59080 -0.231414794921875 +59081 -0.11688232421875 +59082 -0.117645263671875 +59083 -0.07403564453125 +59084 0.007049560546875 +59085 -0.02557373046875 +59086 0.087982177734375 +59087 0.008575439453125 +59088 0.13946533203125 +59089 0.033233642578125 +59090 0.17425537109375 +59091 0.052642822265625 +59092 0.188201904296875 +59093 0.06488037109375 +59094 0.171234130859375 +59095 0.06591796875 +59096 0.118438720703125 +59097 0.0535888671875 +59098 0.05706787109375 +59099 0.03741455078125 +59100 -0.010711669921875 +59101 0.017822265625 +59102 -0.0914306640625 +59103 -0.007720947265625 +59104 -0.162322998046875 +59105 -0.03118896484375 +59106 -0.194549560546875 +59107 -0.042266845703125 +59108 -0.1492919921875 +59109 -0.026947021484375 +59110 -0.02166748046875 +59111 0.016571044921875 +59112 0.124053955078125 +59113 0.065338134765625 +59114 0.211151123046875 +59115 0.091949462890625 +59116 0.240447998046875 +59117 0.097015380859375 +59118 0.242218017578125 +59119 0.091766357421875 +59120 0.2257080078125 +59121 0.079864501953125 +59122 0.194366455078125 +59123 0.062896728515625 +59124 0.115509033203125 +59125 0.02935791015625 +59126 0.0128173828125 +59127 -0.01190185546875 +59128 -0.053802490234375 +59129 -0.039093017578125 +59130 -0.110626220703125 +59131 -0.061553955078125 +59132 -0.199493408203125 +59133 -0.094268798828125 +59134 -0.29437255859375 +59135 -0.12786865234375 +59136 -0.33221435546875 +59137 -0.139373779296875 +59138 -0.27972412109375 +59139 -0.116180419921875 +59140 -0.185333251953125 +59141 -0.076995849609375 +59142 -0.128204345703125 +59143 -0.052642822265625 +59144 -0.115692138671875 +59145 -0.0458984375 +59146 -0.116455078125 +59147 -0.044403076171875 +59148 -0.105926513671875 +59149 -0.038543701171875 +59150 -0.053955078125 +59151 -0.016510009765625 +59152 0.048797607421875 +59153 0.025238037109375 +59154 0.157318115234375 +59155 0.06903076171875 +59156 0.212005615234375 +59157 0.0914306640625 +59158 0.218475341796875 +59159 0.0946044921875 +59160 0.23724365234375 +59161 0.102203369140625 +59162 0.30535888671875 +59163 0.12872314453125 +59164 0.38128662109375 +59165 0.157867431640625 +59166 0.404449462890625 +59167 0.165924072265625 +59168 0.3944091796875 +59169 0.160614013671875 +59170 0.3885498046875 +59171 0.15667724609375 +59172 0.362640380859375 +59173 0.144683837890625 +59174 0.27362060546875 +59175 0.10784912109375 +59176 0.11712646484375 +59177 0.044586181640625 +59178 -0.054901123046875 +59179 -0.024627685546875 +59180 -0.19085693359375 +59181 -0.079437255859375 +59182 -0.28570556640625 +59183 -0.1177978515625 +59184 -0.339263916015625 +59185 -0.139617919921875 +59186 -0.3775634765625 +59187 -0.155029296875 +59188 -0.445709228515625 +59189 -0.1817626953125 +59190 -0.535064697265625 +59191 -0.2164306640625 +59192 -0.629058837890625 +59193 -0.252532958984375 +59194 -0.697601318359375 +59195 -0.2783203125 +59196 -0.70391845703125 +59197 -0.279449462890625 +59198 -0.6424560546875 +59199 -0.25384521484375 +59200 -0.491241455078125 +59201 -0.1929931640625 +59202 -0.265716552734375 +59203 -0.10302734375 +59204 -0.023712158203125 +59205 -0.006683349609375 +59206 0.201751708984375 +59207 0.082977294921875 +59208 0.375823974609375 +59209 0.152252197265625 +59210 0.485076904296875 +59211 0.19580078125 +59212 0.56884765625 +59213 0.229034423828125 +59214 0.634765625 +59215 0.25494384765625 +59216 0.63763427734375 +59217 0.25579833984375 +59218 0.5660400390625 +59219 0.227142333984375 +59220 0.4720458984375 +59221 0.189422607421875 +59222 0.40692138671875 +59223 0.16278076171875 +59224 0.3778076171875 +59225 0.150115966796875 +59226 0.376953125 +59227 0.1484375 +59228 0.371978759765625 +59229 0.1451416015625 +59230 0.313140869140625 +59231 0.12078857421875 +59232 0.184417724609375 +59233 0.06915283203125 +59234 0.011199951171875 +59235 0.000274658203125 +59236 -0.171051025390625 +59237 -0.071868896484375 +59238 -0.33740234375 +59239 -0.137451171875 +59240 -0.47198486328125 +59241 -0.19024658203125 +59242 -0.560394287109375 +59243 -0.224639892578125 +59244 -0.58056640625 +59245 -0.23199462890625 +59246 -0.54754638671875 +59247 -0.21826171875 +59248 -0.508575439453125 +59249 -0.2020263671875 +59250 -0.459503173828125 +59251 -0.18170166015625 +59252 -0.394378662109375 +59253 -0.155029296875 +59254 -0.35260009765625 +59255 -0.137481689453125 +59256 -0.31170654296875 +59257 -0.120330810546875 +59258 -0.197418212890625 +59259 -0.07452392578125 +59260 -0.007965087890625 +59261 0.00054931640625 +59262 0.207489013671875 +59263 0.0855712890625 +59264 0.409210205078125 +59265 0.164947509765625 +59266 0.57208251953125 +59267 0.228851318359375 +59268 0.66595458984375 +59269 0.26544189453125 +59270 0.65875244140625 +59271 0.262176513671875 +59272 0.56744384765625 +59273 0.22576904296875 +59274 0.431396484375 +59275 0.171661376953125 +59276 0.29443359375 +59277 0.1170654296875 +59278 0.182464599609375 +59279 0.07220458984375 +59280 0.06365966796875 +59281 0.024658203125 +59282 -0.075958251953125 +59283 -0.030975341796875 +59284 -0.189422607421875 +59285 -0.076263427734375 +59286 -0.271942138671875 +59287 -0.1092529296875 +59288 -0.342529296875 +59289 -0.13739013671875 +59290 -0.364166259765625 +59291 -0.14617919921875 +59292 -0.327239990234375 +59293 -0.131805419921875 +59294 -0.2769775390625 +59295 -0.11199951171875 +59296 -0.253692626953125 +59297 -0.10260009765625 +59298 -0.24365234375 +59299 -0.09820556640625 +59300 -0.1983642578125 +59301 -0.079833984375 +59302 -0.116241455078125 +59303 -0.04693603515625 +59304 -0.036834716796875 +59305 -0.0150146484375 +59306 0.034881591796875 +59307 0.013885498046875 +59308 0.09124755859375 +59309 0.036712646484375 +59310 0.10888671875 +59311 0.0443115234375 +59312 0.125518798828125 +59313 0.051422119140625 +59314 0.15771484375 +59315 0.064483642578125 +59316 0.17828369140625 +59317 0.07281494140625 +59318 0.17108154296875 +59319 0.070068359375 +59320 0.129974365234375 +59321 0.05389404296875 +59322 0.082427978515625 +59323 0.0350341796875 +59324 0.027679443359375 +59325 0.013214111328125 +59326 -0.065643310546875 +59327 -0.0238037109375 +59328 -0.15936279296875 +59329 -0.06103515625 +59330 -0.21307373046875 +59331 -0.082611083984375 +59332 -0.234649658203125 +59333 -0.09161376953125 +59334 -0.2001953125 +59335 -0.078643798828125 +59336 -0.119171142578125 +59337 -0.04736328125 +59338 -0.024749755859375 +59339 -0.010772705078125 +59340 0.085784912109375 +59341 0.032196044921875 +59342 0.178131103515625 +59343 0.068115234375 +59344 0.215576171875 +59345 0.082611083984375 +59346 0.211456298828125 +59347 0.08087158203125 +59348 0.17523193359375 +59349 0.066680908203125 +59350 0.128753662109375 +59351 0.048583984375 +59352 0.1019287109375 +59353 0.038299560546875 +59354 0.0743408203125 +59355 0.02783203125 +59356 0.04327392578125 +59357 0.01605224609375 +59358 0.038177490234375 +59359 0.01446533203125 +59360 0.076263427734375 +59361 0.029815673828125 +59362 0.14105224609375 +59363 0.05560302734375 +59364 0.186431884765625 +59365 0.073760986328125 +59366 0.188812255859375 +59367 0.07501220703125 +59368 0.1390380859375 +59369 0.055755615234375 +59370 0.041778564453125 +59371 0.017822265625 +59372 -0.079437255859375 +59373 -0.029571533203125 +59374 -0.219390869140625 +59375 -0.084381103515625 +59376 -0.367828369140625 +59377 -0.142578125 +59378 -0.494873046875 +59379 -0.19244384765625 +59380 -0.556243896484375 +59381 -0.21661376953125 +59382 -0.508697509765625 +59383 -0.198150634765625 +59384 -0.3756103515625 +59385 -0.14617919921875 +59386 -0.218902587890625 +59387 -0.084991455078125 +59388 -0.063751220703125 +59389 -0.0244140625 +59390 0.091552734375 +59391 0.036163330078125 +59392 0.23602294921875 +59393 0.092529296875 +59394 0.342987060546875 +59395 0.13421630859375 +59396 0.39520263671875 +59397 0.15423583984375 +59398 0.389373779296875 +59399 0.1510009765625 +59400 0.324249267578125 +59401 0.123748779296875 +59402 0.224090576171875 +59403 0.08258056640625 +59404 0.124267578125 +59405 0.042236328125 +59406 0.037078857421875 +59407 0.007720947265625 +59408 -0.010101318359375 +59409 -0.009521484375 +59410 -0.019439697265625 +59411 -0.010589599609375 +59412 -0.022796630859375 +59413 -0.0091552734375 +59414 -0.001556396484375 +59415 0.002471923828125 +59416 0.056304931640625 +59417 0.029266357421875 +59418 0.106719970703125 +59419 0.052459716796875 +59420 0.096893310546875 +59421 0.049591064453125 +59422 0.042694091796875 +59423 0.027374267578125 +59424 -0.018035888671875 +59425 0.001800537109375 +59426 -0.07586669921875 +59427 -0.0230712890625 +59428 -0.11944580078125 +59429 -0.042388916015625 +59430 -0.15972900390625 +59431 -0.06072998046875 +59432 -0.202606201171875 +59433 -0.080474853515625 +59434 -0.24859619140625 +59435 -0.10174560546875 +59436 -0.30517578125 +59437 -0.12762451171875 +59438 -0.36212158203125 +59439 -0.153656005859375 +59440 -0.39141845703125 +59441 -0.167877197265625 +59442 -0.35528564453125 +59443 -0.1541748046875 +59444 -0.249969482421875 +59445 -0.11090087890625 +59446 -0.092864990234375 +59447 -0.04534912109375 +59448 0.08905029296875 +59449 0.03106689453125 +59450 0.2352294921875 +59451 0.09271240234375 +59452 0.318817138671875 +59453 0.12823486328125 +59454 0.358642578125 +59455 0.14556884765625 +59456 0.347747802734375 +59457 0.141754150390625 +59458 0.28564453125 +59459 0.116546630859375 +59460 0.223175048828125 +59461 0.091400146484375 +59462 0.196746826171875 +59463 0.0816650390625 +59464 0.179840087890625 +59465 0.076019287109375 +59466 0.155548095703125 +59467 0.067230224609375 +59468 0.151214599609375 +59469 0.0667724609375 +59470 0.156951904296875 +59471 0.070404052734375 +59472 0.13177490234375 +59473 0.0606689453125 +59474 0.100799560546875 +59475 0.048187255859375 +59476 0.087127685546875 +59477 0.042724609375 +59478 0.05487060546875 +59479 0.029083251953125 +59480 -0.009002685546875 +59481 0.001708984375 +59482 -0.10400390625 +59483 -0.03912353515625 +59484 -0.229400634765625 +59485 -0.09307861328125 +59486 -0.35552978515625 +59487 -0.14752197265625 +59488 -0.441925048828125 +59489 -0.18524169921875 +59490 -0.473846435546875 +59491 -0.199951171875 +59492 -0.464813232421875 +59493 -0.19732666015625 +59494 -0.419097900390625 +59495 -0.1790771484375 +59496 -0.334320068359375 +59497 -0.144134521484375 +59498 -0.227935791015625 +59499 -0.099853515625 +59500 -0.12347412109375 +59501 -0.056182861328125 +59502 -0.02764892578125 +59503 -0.01593017578125 +59504 0.077667236328125 +59505 0.028594970703125 +59506 0.2132568359375 +59507 0.086181640625 +59508 0.38885498046875 +59509 0.16094970703125 +59510 0.582794189453125 +59511 0.243682861328125 +59512 0.734039306640625 +59513 0.3084716796875 +59514 0.800140380859375 +59515 0.3372802734375 +59516 0.7783203125 +59517 0.328857421875 +59518 0.6651611328125 +59519 0.28173828125 +59520 0.45965576171875 +59521 0.195465087890625 +59522 0.199188232421875 +59523 0.085845947265625 +59524 -0.050689697265625 +59525 -0.019378662109375 +59526 -0.23297119140625 +59527 -0.096038818359375 +59528 -0.33013916015625 +59529 -0.136749267578125 +59530 -0.368408203125 +59531 -0.152679443359375 +59532 -0.378936767578125 +59533 -0.157012939453125 +59534 -0.376983642578125 +59535 -0.15625 +59536 -0.37969970703125 +59537 -0.157684326171875 +59538 -0.391510009765625 +59539 -0.16314697265625 +59540 -0.385345458984375 +59541 -0.1611328125 +59542 -0.3419189453125 +59543 -0.143402099609375 +59544 -0.28289794921875 +59545 -0.119110107421875 +59546 -0.251617431640625 +59547 -0.106597900390625 +59548 -0.266143798828125 +59549 -0.11346435546875 +59550 -0.273345947265625 +59551 -0.117156982421875 +59552 -0.216796875 +59553 -0.093719482421875 +59554 -0.128265380859375 +59555 -0.056549072265625 +59556 -0.068145751953125 +59557 -0.031280517578125 +59558 -0.0430908203125 +59559 -0.020721435546875 +59560 -0.024444580078125 +59561 -0.012725830078125 +59562 0.020721435546875 +59563 0.00665283203125 +59564 0.124481201171875 +59565 0.050994873046875 +59566 0.25787353515625 +59567 0.10797119140625 +59568 0.379119873046875 +59569 0.15985107421875 +59570 0.47991943359375 +59571 0.203094482421875 +59572 0.5281982421875 +59573 0.22406005859375 +59574 0.511138916015625 +59575 0.21728515625 +59576 0.456207275390625 +59577 0.194427490234375 +59578 0.407470703125 +59579 0.17413330078125 +59580 0.383758544921875 +59581 0.16436767578125 +59582 0.35687255859375 +59583 0.153167724609375 +59584 0.31182861328125 +59585 0.1341552734375 +59586 0.250885009765625 +59587 0.1082763671875 +59588 0.1654052734375 +59589 0.0718994140625 +59590 0.035247802734375 +59591 0.0164794921875 +59592 -0.142059326171875 +59593 -0.058990478515625 +59594 -0.33563232421875 +59595 -0.14141845703125 +59596 -0.5345458984375 +59597 -0.226104736328125 +59598 -0.72186279296875 +59599 -0.305877685546875 +59600 -0.836669921875 +59601 -0.3548583984375 +59602 -0.8326416015625 +59603 -0.353424072265625 +59604 -0.7296142578125 +59605 -0.309967041015625 +59606 -0.582550048828125 +59607 -0.247802734375 +59608 -0.440093994140625 +59609 -0.187530517578125 +59610 -0.324310302734375 +59611 -0.13848876953125 +59612 -0.20147705078125 +59613 -0.08636474609375 +59614 -0.044647216796875 +59615 -0.019744873046875 +59616 0.103973388671875 +59617 0.04345703125 +59618 0.202392578125 +59619 0.08538818359375 +59620 0.264495849609375 +59621 0.1119384765625 +59622 0.338897705078125 +59623 0.143707275390625 +59624 0.443817138671875 +59625 0.18841552734375 +59626 0.545074462890625 +59627 0.231536865234375 +59628 0.6173095703125 +59629 0.2623291015625 +59630 0.6524658203125 +59631 0.277374267578125 +59632 0.66339111328125 +59633 0.2821044921875 +59634 0.6561279296875 +59635 0.279052734375 +59636 0.606781005859375 +59637 0.258087158203125 +59638 0.501190185546875 +59639 0.213226318359375 +59640 0.352783203125 +59641 0.150177001953125 +59642 0.176544189453125 +59643 0.075286865234375 +59644 -0.034820556640625 +59645 -0.014495849609375 +59646 -0.258209228515625 +59647 -0.109375 +59648 -0.44244384765625 +59649 -0.18743896484375 +59650 -0.5753173828125 +59651 -0.24365234375 +59652 -0.65203857421875 +59653 -0.275848388671875 +59654 -0.641632080078125 +59655 -0.269866943359375 +59656 -0.562164306640625 +59657 -0.233856201171875 +59658 -0.458038330078125 +59659 -0.18792724609375 +59660 -0.350555419921875 +59661 -0.141571044921875 +59662 -0.260528564453125 +59663 -0.10406494140625 +59664 -0.192108154296875 +59665 -0.077056884765625 +59666 -0.141937255859375 +59667 -0.058746337890625 +59668 -0.1021728515625 +59669 -0.0452880859375 +59670 -0.062896728515625 +59671 -0.03192138671875 +59672 -0.011932373046875 +59673 -0.012847900390625 +59674 0.062835693359375 +59675 0.017669677734375 +59676 0.148712158203125 +59677 0.053985595703125 +59678 0.241729736328125 +59679 0.09442138671875 +59680 0.34912109375 +59681 0.142364501953125 +59682 0.457305908203125 +59683 0.191650390625 +59684 0.54388427734375 +59685 0.23199462890625 +59686 0.5728759765625 +59687 0.246917724609375 +59688 0.506591796875 +59689 0.2191162109375 +59690 0.351226806640625 +59691 0.151275634765625 +59692 0.146514892578125 +59693 0.06134033203125 +59694 -0.05523681640625 +59695 -0.027008056640625 +59696 -0.21624755859375 +59697 -0.09674072265625 +59698 -0.334930419921875 +59699 -0.147369384765625 +59700 -0.402984619140625 +59701 -0.17529296875 +59702 -0.4412841796875 +59703 -0.190155029296875 +59704 -0.49578857421875 +59705 -0.21307373046875 +59706 -0.5601806640625 +59707 -0.241241455078125 +59708 -0.600738525390625 +59709 -0.25933837890625 +59710 -0.584228515625 +59711 -0.252227783203125 +59712 -0.47930908203125 +59713 -0.20556640625 +59714 -0.27935791015625 +59715 -0.11627197265625 +59716 -0.0089111328125 +59717 0.00457763671875 +59718 0.268798828125 +59719 0.128326416015625 +59720 0.482818603515625 +59721 0.222808837890625 +59722 0.60369873046875 +59723 0.2747802734375 +59724 0.650421142578125 +59725 0.293060302734375 +59726 0.66400146484375 +59727 0.2965087890625 +59728 0.6414794921875 +59729 0.283905029296875 +59730 0.572540283203125 +59731 0.25067138671875 +59732 0.498138427734375 +59733 0.215545654296875 +59734 0.439453125 +59735 0.188262939453125 +59736 0.375518798828125 +59737 0.159271240234375 +59738 0.274505615234375 +59739 0.114044189453125 +59740 0.1087646484375 +59741 0.039886474609375 +59742 -0.099395751953125 +59743 -0.053131103515625 +59744 -0.3182373046875 +59745 -0.150634765625 +59746 -0.5489501953125 +59747 -0.2532958984375 +59748 -0.7738037109375 +59749 -0.353179931640625 +59750 -0.86383056640625 +59751 -0.42626953125 +59752 -0.870391845703125 +59753 -0.457550048828125 +59754 -0.86895751953125 +59755 -0.455230712890625 +59756 -0.861053466796875 +59757 -0.4254150390625 +59758 -0.765869140625 +59759 -0.36029052734375 +59760 -0.5301513671875 +59761 -0.2547607421875 +59762 -0.214691162109375 +59763 -0.112091064453125 +59764 0.137359619140625 +59765 0.048065185546875 +59766 0.474822998046875 +59767 0.202362060546875 +59768 0.76239013671875 +59769 0.33465576171875 +59770 0.867462158203125 +59771 0.432708740234375 +59772 0.870361328125 +59773 0.496856689453125 +59774 0.86480712890625 +59775 0.52197265625 +59776 0.831817626953125 +59777 0.510589599609375 +59778 0.677581787109375 +59779 0.473968505859375 +59780 0.495880126953125 +59781 0.41485595703125 +59782 0.30767822265625 +59783 0.341827392578125 +59784 0.116180419921875 +59785 0.255950927734375 +59786 -0.110748291015625 +59787 0.142822265625 +59788 -0.381805419921875 +59789 -0.000640869140625 +59790 -0.6572265625 +59791 -0.15496826171875 +59792 -0.857421875 +59793 -0.2928466796875 +59794 -0.870391845703125 +59795 -0.394775390625 +59796 -0.870391845703125 +59797 -0.45758056640625 +59798 -0.86444091796875 +59799 -0.493621826171875 +59800 -0.85723876953125 +59801 -0.519256591796875 +59802 -0.790008544921875 +59803 -0.526214599609375 +59804 -0.62847900390625 +59805 -0.489837646484375 +59806 -0.3956298828125 +59807 -0.40875244140625 +59808 -0.126708984375 +59809 -0.298004150390625 +59810 0.150115966796875 +59811 -0.170196533203125 +59812 0.424041748046875 +59813 -0.030731201171875 +59814 0.670623779296875 +59815 0.108062744140625 +59816 0.854522705078125 +59817 0.228485107421875 +59818 0.866485595703125 +59819 0.322479248046875 +59820 0.86920166015625 +59821 0.383087158203125 +59822 0.8653564453125 +59823 0.418609619140625 +59824 0.857147216796875 +59825 0.435211181640625 +59826 0.766845703125 +59827 0.431640625 +59828 0.628509521484375 +59829 0.410308837890625 +59830 0.462127685546875 +59831 0.36822509765625 +59832 0.297210693359375 +59833 0.3172607421875 +59834 0.14862060546875 +59835 0.26312255859375 +59836 -0.00537109375 +59837 0.195465087890625 +59838 -0.15753173828125 +59839 0.117767333984375 +59840 -0.31304931640625 +59841 0.0284423828125 +59842 -0.48876953125 +59843 -0.078887939453125 +59844 -0.6416015625 +59845 -0.182830810546875 +59846 -0.751373291015625 +59847 -0.2720947265625 +59848 -0.84619140625 +59849 -0.35723876953125 +59850 -0.861297607421875 +59851 -0.43157958984375 +59852 -0.863250732421875 +59853 -0.480072021484375 +59854 -0.856597900390625 +59855 -0.488372802734375 +59856 -0.7498779296875 +59857 -0.462066650390625 +59858 -0.624542236328125 +59859 -0.427642822265625 +59860 -0.47808837890625 +59861 -0.375152587890625 +59862 -0.253387451171875 +59863 -0.277984619140625 +59864 0.003692626953125 +59865 -0.157012939453125 +59866 0.2257080078125 +59867 -0.04345703125 +59868 0.427154541015625 +59869 0.068359375 +59870 0.643218994140625 +59871 0.193145751953125 +59872 0.855926513671875 +59873 0.326507568359375 +59874 0.870361328125 +59875 0.4420166015625 +59876 0.870361328125 +59877 0.51702880859375 +59878 0.862762451171875 +59879 0.55487060546875 +59880 0.79669189453125 +59881 0.554229736328125 +59882 0.595794677734375 +59883 0.5108642578125 +59884 0.362152099609375 +59885 0.438140869140625 +59886 0.1270751953125 +59887 0.34893798828125 +59888 -0.086944580078125 +59889 0.252960205078125 +59890 -0.2784423828125 +59891 0.151214599609375 +59892 -0.484832763671875 +59893 0.027923583984375 +59894 -0.729583740234375 +59895 -0.125579833984375 +59896 -0.86688232421875 +59897 -0.286163330078125 +59898 -0.870391845703125 +59899 -0.424896240234375 +59900 -0.86859130859375 +59901 -0.53948974609375 +59902 -0.86279296875 +59903 -0.62896728515625 +59904 -0.817962646484375 +59905 -0.677001953125 +59906 -0.6116943359375 +59907 -0.66253662109375 +59908 -0.3128662109375 +59909 -0.58209228515625 +59910 0.039398193359375 +59911 -0.4512939453125 +59912 0.422821044921875 +59913 -0.279052734375 +59914 0.805145263671875 +59915 -0.080780029296875 +59916 0.870361328125 +59917 0.111053466796875 +59918 0.870361328125 +59919 0.26934814453125 +59920 0.860015869140625 +59921 0.388946533203125 +59922 0.727935791015625 +59923 0.466552734375 +59924 0.48114013671875 +59925 0.499664306640625 +59926 0.2059326171875 +59927 0.500244140625 +59928 -0.06103515625 +59929 0.479339599609375 +59930 -0.29913330078125 +59931 0.4417724609375 +59932 -0.516204833984375 +59933 0.380279541015625 +59934 -0.7252197265625 +59935 0.287109375 +59936 -0.85980224609375 +59937 0.174072265625 +59938 -0.870391845703125 +59939 0.0576171875 +59940 -0.870391845703125 +59941 -0.048126220703125 +59942 -0.858062744140625 +59943 -0.11968994140625 +59944 -0.673004150390625 +59945 -0.1552734375 +59946 -0.42694091796875 +59947 -0.180694580078125 +59948 -0.2100830078125 +59949 -0.21771240234375 +59950 -0.0362548828125 +59951 -0.265350341796875 +59952 0.10943603515625 +59953 -0.309417724609375 +59954 0.23516845703125 +59955 -0.340087890625 +59956 0.373687744140625 +59957 -0.3370361328125 +59958 0.517791748046875 +59959 -0.30108642578125 +59960 0.602783203125 +59961 -0.262786865234375 +59962 0.635711669921875 +59963 -0.21942138671875 +59964 0.655181884765625 +59965 -0.154510498046875 +59966 0.65948486328125 +59967 -0.072723388671875 +59968 0.651275634765625 +59969 0.02215576171875 +59970 0.61846923828125 +59971 0.1182861328125 +59972 0.53753662109375 +59973 0.19769287109375 +59974 0.404144287109375 +59975 0.251617431640625 +59976 0.22186279296875 +59977 0.275299072265625 +59978 0.003997802734375 +59979 0.269287109375 +59980 -0.22100830078125 +59981 0.242340087890625 +59982 -0.42449951171875 +59983 0.204376220703125 +59984 -0.579833984375 +59985 0.16571044921875 +59986 -0.641876220703125 +59987 0.14703369140625 +59988 -0.6177978515625 +59989 0.144927978515625 +59990 -0.575531005859375 +59991 0.12774658203125 +59992 -0.526336669921875 +59993 0.092742919921875 +59994 -0.42645263671875 +59995 0.065093994140625 +59996 -0.2581787109375 +59997 0.05810546875 +59998 -0.068695068359375 +59999 0.053985595703125 +60000 0.09222412109375 +60001 0.033935546875 +60002 0.232147216796875 +60003 0.007080078125 +60004 0.3509521484375 +60005 -0.021514892578125 +60006 0.410064697265625 +60007 -0.06622314453125 +60008 0.372955322265625 +60009 -0.1412353515625 +60010 0.2554931640625 +60011 -0.23614501953125 +60012 0.10711669921875 +60013 -0.32537841796875 +60014 -0.052886962890625 +60015 -0.399169921875 +60016 -0.186279296875 +60017 -0.439697265625 +60018 -0.23291015625 +60019 -0.4195556640625 +60020 -0.209442138671875 +60021 -0.349761962890625 +60022 -0.174163818359375 +60023 -0.262359619140625 +60024 -0.126739501953125 +60025 -0.161346435546875 +60026 -0.048126220703125 +60027 -0.04193115234375 +60028 0.0426025390625 +60029 0.082061767578125 +60030 0.10748291015625 +60031 0.18780517578125 +60032 0.1409912109375 +60033 0.268707275390625 +60034 0.19708251953125 +60035 0.347869873046875 +60036 0.273651123046875 +60037 0.42181396484375 +60038 0.31768798828125 +60039 0.463104248046875 +60040 0.341094970703125 +60041 0.47698974609375 +60042 0.368011474609375 +60043 0.4755859375 +60044 0.37249755859375 +60045 0.447540283203125 +60046 0.30072021484375 +60047 0.368682861328125 +60048 0.1517333984375 +60049 0.241302490234375 +60050 -0.01470947265625 +60051 0.09783935546875 +60052 -0.1883544921875 +60053 -0.053070068359375 +60054 -0.372711181640625 +60055 -0.20941162109375 +60056 -0.51397705078125 +60057 -0.34130859375 +60058 -0.57177734375 +60059 -0.425689697265625 +60060 -0.53948974609375 +60061 -0.456512451171875 +60062 -0.43511962890625 +60063 -0.440277099609375 +60064 -0.2962646484375 +60065 -0.393768310546875 +60066 -0.161102294921875 +60067 -0.3348388671875 +60068 -0.0435791015625 +60069 -0.270294189453125 +60070 0.060394287109375 +60071 -0.198974609375 +60072 0.13665771484375 +60073 -0.1292724609375 +60074 0.170135498046875 +60075 -0.0706787109375 +60076 0.16552734375 +60077 -0.023468017578125 +60078 0.15728759765625 +60079 0.026214599609375 +60080 0.150787353515625 +60081 0.077972412109375 +60082 0.12200927734375 +60083 0.117034912109375 +60084 0.080108642578125 +60085 0.14501953125 +60086 0.05126953125 +60087 0.172210693359375 +60088 0.062896728515625 +60089 0.2099609375 +60090 0.09271240234375 +60091 0.245880126953125 +60092 0.092987060546875 +60093 0.255828857421875 +60094 0.07855224609375 +60095 0.246856689453125 +60096 0.06427001953125 +60097 0.226654052734375 +60098 0.0347900390625 +60099 0.18878173828125 +60100 -0.01171875 +60101 0.133880615234375 +60102 -0.056060791015625 +60103 0.073333740234375 +60104 -0.055511474609375 +60105 0.030303955078125 +60106 -0.010467529296875 +60107 0.007080078125 +60108 0.02508544921875 +60109 -0.020111083984375 +60110 0.025665283203125 +60111 -0.061309814453125 +60112 0.017333984375 +60113 -0.101593017578125 +60114 0.00189208984375 +60115 -0.138275146484375 +60116 -0.03173828125 +60117 -0.175384521484375 +60118 -0.071502685546875 +60119 -0.2061767578125 +60120 -0.13543701171875 +60121 -0.23907470703125 +60122 -0.219970703125 +60123 -0.27252197265625 +60124 -0.300506591796875 +60125 -0.295196533203125 +60126 -0.376312255859375 +60127 -0.30792236328125 +60128 -0.416107177734375 +60129 -0.296966552734375 +60130 -0.371124267578125 +60131 -0.240386962890625 +60132 -0.242279052734375 +60133 -0.140655517578125 +60134 -0.069732666015625 +60135 -0.0194091796875 +60136 0.125640869140625 +60137 0.111114501953125 +60138 0.31268310546875 +60139 0.233856201171875 +60140 0.45501708984375 +60141 0.329437255859375 +60142 0.554779052734375 +60143 0.39764404296875 +60144 0.61065673828125 +60145 0.43695068359375 +60146 0.610931396484375 +60147 0.441192626953125 +60148 0.531463623046875 +60149 0.398590087890625 +60150 0.3883056640625 +60151 0.317413330078125 +60152 0.23468017578125 +60153 0.2244873046875 +60154 0.095245361328125 +60155 0.133026123046875 +60156 -0.00396728515625 +60157 0.057159423828125 +60158 -0.04852294921875 +60159 0.005523681640625 +60160 -0.055145263671875 +60161 -0.028106689453125 +60162 -0.0758056640625 +60163 -0.067535400390625 +60164 -0.138702392578125 +60165 -0.125244140625 +60166 -0.209197998046875 +60167 -0.182647705078125 +60168 -0.289031982421875 +60169 -0.2396240234375 +60170 -0.37884521484375 +60171 -0.295806884765625 +60172 -0.456329345703125 +60173 -0.339630126953125 +60174 -0.51641845703125 +60175 -0.3685302734375 +60176 -0.519287109375 +60177 -0.36285400390625 +60178 -0.458251953125 +60179 -0.31982421875 +60180 -0.384796142578125 +60181 -0.266021728515625 +60182 -0.323699951171875 +60183 -0.21490478515625 +60184 -0.269287109375 +60185 -0.16485595703125 +60186 -0.1951904296875 +60187 -0.10400390625 +60188 -0.100006103515625 +60189 -0.032928466796875 +60190 -0.01055908203125 +60191 0.03363037109375 +60192 0.1033935546875 +60193 0.109649658203125 +60194 0.24908447265625 +60195 0.197784423828125 +60196 0.373199462890625 +60197 0.27069091796875 +60198 0.45806884765625 +60199 0.319091796875 +60200 0.511474609375 +60201 0.3466796875 +60202 0.565399169921875 +60203 0.36956787109375 +60204 0.61138916015625 +60205 0.383880615234375 +60206 0.5897216796875 +60207 0.3603515625 +60208 0.4906005859375 +60209 0.29486083984375 +60210 0.33148193359375 +60211 0.1971435546875 +60212 0.147796630859375 +60213 0.0859375 +60214 -0.01873779296875 +60215 -0.01678466796875 +60216 -0.140289306640625 +60217 -0.096038818359375 +60218 -0.191986083984375 +60219 -0.138397216796875 +60220 -0.184295654296875 +60221 -0.14825439453125 +60222 -0.161834716796875 +60223 -0.147247314453125 +60224 -0.166595458984375 +60225 -0.155914306640625 +60226 -0.19390869140625 +60227 -0.17169189453125 +60228 -0.22442626953125 +60229 -0.1849365234375 +60230 -0.279754638671875 +60231 -0.206634521484375 +60232 -0.3389892578125 +60233 -0.226806640625 +60234 -0.3543701171875 +60235 -0.222198486328125 +60236 -0.348175048828125 +60237 -0.204681396484375 +60238 -0.32598876953125 +60239 -0.17791748046875 +60240 -0.2581787109375 +60241 -0.12799072265625 +60242 -0.139801025390625 +60243 -0.05328369140625 +60244 0.014617919921875 +60245 0.038116455078125 +60246 0.144378662109375 +60247 0.115081787109375 +60248 0.221038818359375 +60249 0.162811279296875 +60250 0.27069091796875 +60251 0.19390869140625 +60252 0.294036865234375 +60253 0.208465576171875 +60254 0.311767578125 +60255 0.216796875 +60256 0.339141845703125 +60257 0.226715087890625 +60258 0.360260009765625 +60259 0.230804443359375 +60260 0.360504150390625 +60261 0.222137451171875 +60262 0.308380126953125 +60263 0.184783935546875 +60264 0.18170166015625 +60265 0.107757568359375 +60266 0.0047607421875 +60267 0.004302978515625 +60268 -0.17559814453125 +60269 -0.10064697265625 +60270 -0.3143310546875 +60271 -0.18310546875 +60272 -0.36785888671875 +60273 -0.21990966796875 +60274 -0.36248779296875 +60275 -0.224273681640625 +60276 -0.343536376953125 +60277 -0.21942138671875 +60278 -0.3018798828125 +60279 -0.200439453125 +60280 -0.231414794921875 +60281 -0.164031982421875 +60282 -0.117645263671875 +60283 -0.10272216796875 +60284 0.007049560546875 +60285 -0.033538818359375 +60286 0.087982177734375 +60287 0.0147705078125 +60288 0.13946533203125 +60289 0.04925537109375 +60290 0.17425537109375 +60291 0.07611083984375 +60292 0.188201904296875 +60293 0.0926513671875 +60294 0.171234130859375 +60295 0.093109130859375 +60296 0.118438720703125 +60297 0.074432373046875 +60298 0.05706787109375 +60299 0.05035400390625 +60300 -0.010711669921875 +60301 0.021575927734375 +60302 -0.0914306640625 +60303 -0.015594482421875 +60304 -0.162322998046875 +60305 -0.04949951171875 +60306 -0.194549560546875 +60307 -0.065277099609375 +60308 -0.1492919921875 +60309 -0.042755126953125 +60310 -0.02166748046875 +60311 0.020721435546875 +60312 0.124053955078125 +60313 0.091949462890625 +60314 0.211151123046875 +60315 0.131317138671875 +60316 0.240447998046875 +60317 0.1396484375 +60318 0.242218017578125 +60319 0.133026123046875 +60320 0.2257080078125 +60321 0.116729736328125 +60322 0.194366455078125 +60323 0.092987060546875 +60324 0.115509033203125 +60325 0.045196533203125 +60326 0.0128173828125 +60327 -0.013946533203125 +60328 -0.053802490234375 +60329 -0.05303955078125 +60330 -0.110626220703125 +60331 -0.08551025390625 +60332 -0.199493408203125 +60333 -0.133026123046875 +60334 -0.29437255859375 +60335 -0.182037353515625 +60336 -0.33221435546875 +60337 -0.199798583984375 +60338 -0.27972412109375 +60339 -0.169158935546875 +60340 -0.185333251953125 +60341 -0.115509033203125 +60342 -0.128204345703125 +60343 -0.080291748046875 +60344 -0.115692138671875 +60345 -0.067657470703125 +60346 -0.116455078125 +60347 -0.061676025390625 +60348 -0.105926513671875 +60349 -0.0499267578125 +60350 -0.053955078125 +60351 -0.017059326171875 +60352 0.048797607421875 +60353 0.04144287109375 +60354 0.157318115234375 +60355 0.101898193359375 +60356 0.212005615234375 +60357 0.133148193359375 +60358 0.218475341796875 +60359 0.13800048828125 +60360 0.23724365234375 +60361 0.147857666015625 +60362 0.30535888671875 +60363 0.182037353515625 +60364 0.38128662109375 +60365 0.21905517578125 +60366 0.404449462890625 +60367 0.227569580078125 +60368 0.3944091796875 +60369 0.217987060546875 +60370 0.3885498046875 +60371 0.209991455078125 +60372 0.362640380859375 +60373 0.1912841796875 +60374 0.27362060546875 +60375 0.1397705078125 +60376 0.11712646484375 +60377 0.053466796875 +60378 -0.054901123046875 +60379 -0.04034423828125 +60380 -0.19085693359375 +60381 -0.1146240234375 +60382 -0.28570556640625 +60383 -0.166595458984375 +60384 -0.339263916015625 +60385 -0.196044921875 +60386 -0.3775634765625 +60387 -0.2164306640625 +60388 -0.445709228515625 +60389 -0.251190185546875 +60390 -0.535064697265625 +60391 -0.295928955078125 +60392 -0.629058837890625 +60393 -0.3421630859375 +60394 -0.697601318359375 +60395 -0.3743896484375 +60396 -0.70391845703125 +60397 -0.373687744140625 +60398 -0.6424560546875 +60399 -0.337432861328125 +60400 -0.491241455078125 +60401 -0.254425048828125 +60402 -0.265716552734375 +60403 -0.1329345703125 +60404 -0.023712158203125 +60405 -0.003265380859375 +60406 0.201751708984375 +60407 0.1171875 +60408 0.375823974609375 +60409 0.21014404296875 +60410 0.485076904296875 +60411 0.26849365234375 +60412 0.56884765625 +60413 0.31268310546875 +60414 0.634765625 +60415 0.346649169921875 +60416 0.63763427734375 +60417 0.346435546875 +60418 0.5660400390625 +60419 0.305450439453125 +60420 0.4720458984375 +60421 0.251983642578125 +60422 0.40692138671875 +60423 0.214599609375 +60424 0.3778076171875 +60425 0.197479248046875 +60426 0.376953125 +60427 0.196502685546875 +60428 0.371978759765625 +60429 0.19390869140625 +60430 0.313140869140625 +60431 0.1622314453125 +60432 0.184417724609375 +60433 0.092559814453125 +60434 0.011199951171875 +60435 -0.0010986328125 +60436 -0.171051025390625 +60437 -0.09930419921875 +60438 -0.33740234375 +60439 -0.188446044921875 +60440 -0.47198486328125 +60441 -0.259918212890625 +60442 -0.560394287109375 +60443 -0.305938720703125 +60444 -0.58056640625 +60445 -0.31451416015625 +60446 -0.54754638671875 +60447 -0.2940673828125 +60448 -0.508575439453125 +60449 -0.270843505859375 +60450 -0.459503173828125 +60451 -0.24261474609375 +60452 -0.394378662109375 +60453 -0.206146240234375 +60454 -0.35260009765625 +60455 -0.183197021484375 +60456 -0.31170654296875 +60457 -0.161346435546875 +60458 -0.197418212890625 +60459 -0.099517822265625 +60460 -0.007965087890625 +60461 0.0032958984375 +60462 0.207489013671875 +60463 0.120086669921875 +60464 0.409210205078125 +60465 0.229034423828125 +60466 0.57208251953125 +60467 0.316436767578125 +60468 0.66595458984375 +60469 0.36578369140625 +60470 0.65875244140625 +60471 0.3594970703125 +60472 0.56744384765625 +60473 0.30706787109375 +60474 0.431396484375 +60475 0.230316162109375 +60476 0.29443359375 +60477 0.153533935546875 +60478 0.182464599609375 +60479 0.091094970703125 +60480 0.06365966796875 +60481 0.025421142578125 +60482 -0.075958251953125 +60483 -0.051177978515625 +60484 -0.189422607421875 +60485 -0.11285400390625 +60486 -0.271942138671875 +60487 -0.156982421875 +60488 -0.342529296875 +60489 -0.19415283203125 +60490 -0.364166259765625 +60491 -0.204071044921875 +60492 -0.327239990234375 +60493 -0.181549072265625 +60494 -0.2769775390625 +60495 -0.15167236328125 +60496 -0.253692626953125 +60497 -0.136810302734375 +60498 -0.24365234375 +60499 -0.129486083984375 +60500 -0.1983642578125 +60501 -0.10302734375 +60502 -0.116241455078125 +60503 -0.056610107421875 +60504 -0.036834716796875 +60505 -0.012115478515625 +60506 0.034881591796875 +60507 0.02764892578125 +60508 0.09124755859375 +60509 0.0584716796875 +60510 0.10888671875 +60511 0.0675048828125 +60512 0.125518798828125 +60513 0.075592041015625 +60514 0.15771484375 +60515 0.091949462890625 +60516 0.17828369140625 +60517 0.10162353515625 +60518 0.17108154296875 +60519 0.0958251953125 +60520 0.129974365234375 +60521 0.0712890625 +60522 0.082427978515625 +60523 0.04327392578125 +60524 0.027679443359375 +60525 0.011474609375 +60526 -0.065643310546875 +60527 -0.04132080078125 +60528 -0.15936279296875 +60529 -0.093994140625 +60530 -0.21307373046875 +60531 -0.12420654296875 +60532 -0.234649658203125 +60533 -0.13629150390625 +60534 -0.2001953125 +60535 -0.117034912109375 +60536 -0.119171142578125 +60537 -0.07171630859375 +60538 -0.024749755859375 +60539 -0.0186767578125 +60540 0.085784912109375 +60541 0.043487548828125 +60542 0.178131103515625 +60543 0.09576416015625 +60544 0.215576171875 +60545 0.11785888671875 +60546 0.211456298828125 +60547 0.117034912109375 +60548 0.17523193359375 +60549 0.09844970703125 +60550 0.128753662109375 +60551 0.0740966796875 +60552 0.1019287109375 +60553 0.06036376953125 +60554 0.0743408203125 +60555 0.04595947265625 +60556 0.04327392578125 +60557 0.02935791015625 +60558 0.038177490234375 +60559 0.02679443359375 +60560 0.076263427734375 +60561 0.047760009765625 +60562 0.14105224609375 +60563 0.0831298828125 +60564 0.186431884765625 +60565 0.10748291015625 +60566 0.188812255859375 +60567 0.10784912109375 +60568 0.1390380859375 +60569 0.079254150390625 +60570 0.041778564453125 +60571 0.02435302734375 +60572 -0.079437255859375 +60573 -0.04376220703125 +60574 -0.219390869140625 +60575 -0.1221923828125 +60576 -0.367828369140625 +60577 -0.205169677734375 +60578 -0.494873046875 +60579 -0.27618408203125 +60580 -0.556243896484375 +60581 -0.31072998046875 +60582 -0.508697509765625 +60583 -0.284912109375 +60584 -0.3756103515625 +60585 -0.211639404296875 +60586 -0.218902587890625 +60587 -0.125091552734375 +60588 -0.063751220703125 +60589 -0.039154052734375 +60590 0.091552734375 +60591 0.047027587890625 +60592 0.23602294921875 +60593 0.127410888671875 +60594 0.342987060546875 +60595 0.187225341796875 +60596 0.39520263671875 +60597 0.2169189453125 +60598 0.389373779296875 +60599 0.214630126953125 +60600 0.324249267578125 +60601 0.179595947265625 +60602 0.224090576171875 +60603 0.125152587890625 +60604 0.124267578125 +60605 0.07080078125 +60606 0.037078857421875 +60607 0.023284912109375 +60608 -0.010101318359375 +60609 -0.002288818359375 +60610 -0.019439697265625 +60611 -0.00714111328125 +60612 -0.022796630859375 +60613 -0.008880615234375 +60614 -0.001556396484375 +60615 0.002716064453125 +60616 0.056304931640625 +60617 0.034332275390625 +60618 0.106719970703125 +60619 0.0616455078125 +60620 0.096893310546875 +60621 0.055572509765625 +60622 0.042694091796875 +60623 0.024932861328125 +60624 -0.018035888671875 +60625 -0.009368896484375 +60626 -0.07586669921875 +60627 -0.04205322265625 +60628 -0.11944580078125 +60629 -0.06683349609375 +60630 -0.15972900390625 +60631 -0.0897216796875 +60632 -0.202606201171875 +60633 -0.11395263671875 +60634 -0.24859619140625 +60635 -0.139739990234375 +60636 -0.30517578125 +60637 -0.17120361328125 +60638 -0.36212158203125 +60639 -0.20269775390625 +60640 -0.39141845703125 +60641 -0.21875 +60642 -0.35528564453125 +60643 -0.19854736328125 +60644 -0.249969482421875 +60645 -0.1400146484375 +60646 -0.092864990234375 +60647 -0.05279541015625 +60648 0.08905029296875 +60649 0.048187255859375 +60650 0.2352294921875 +60651 0.12945556640625 +60652 0.318817138671875 +60653 0.176177978515625 +60654 0.358642578125 +60655 0.19873046875 +60656 0.347747802734375 +60657 0.1932373046875 +60658 0.28564453125 +60659 0.159393310546875 +60660 0.223175048828125 +60661 0.125244140625 +60662 0.196746826171875 +60663 0.11083984375 +60664 0.179840087890625 +60665 0.101593017578125 +60666 0.155548095703125 +60667 0.088134765625 +60668 0.151214599609375 +60669 0.0855712890625 +60670 0.156951904296875 +60671 0.088470458984375 +60672 0.13177490234375 +60673 0.07403564453125 +60674 0.100799560546875 +60675 0.056610107421875 +60676 0.087127685546875 +60677 0.04913330078125 +60678 0.05487060546875 +60679 0.030792236328125 +60680 -0.009002685546875 +60681 -0.005889892578125 +60682 -0.10400390625 +60683 -0.06060791015625 +60684 -0.229400634765625 +60685 -0.132965087890625 +60686 -0.35552978515625 +60687 -0.205657958984375 +60688 -0.441925048828125 +60689 -0.255096435546875 +60690 -0.473846435546875 +60691 -0.27276611328125 +60692 -0.464813232421875 +60693 -0.266632080078125 +60694 -0.419097900390625 +60695 -0.2392578125 +60696 -0.334320068359375 +60697 -0.1893310546875 +60698 -0.227935791015625 +60699 -0.127044677734375 +60700 -0.12347412109375 +60701 -0.066162109375 +60702 -0.02764892578125 +60703 -0.010589599609375 +60704 0.077667236328125 +60705 0.050262451171875 +60706 0.2132568359375 +60707 0.1285400390625 +60708 0.38885498046875 +60709 0.22998046875 +60710 0.582794189453125 +60711 0.34197998046875 +60712 0.734039306640625 +60713 0.428985595703125 +60714 0.800140380859375 +60715 0.466278076171875 +60716 0.7783203125 +60717 0.452301025390625 +60718 0.6651611328125 +60719 0.3851318359375 +60720 0.45965576171875 +60721 0.264251708984375 +60722 0.199188232421875 +60723 0.111541748046875 +60724 -0.050689697265625 +60725 -0.03466796875 +60726 -0.23297119140625 +60727 -0.14111328125 +60728 -0.33013916015625 +60729 -0.19757080078125 +60730 -0.368408203125 +60731 -0.2193603515625 +60732 -0.378936767578125 +60733 -0.224700927734375 +60734 -0.376983642578125 +60735 -0.22259521484375 +60736 -0.37969970703125 +60737 -0.22314453125 +60738 -0.391510009765625 +60739 -0.228973388671875 +60740 -0.385345458984375 +60741 -0.224334716796875 +60742 -0.3419189453125 +60743 -0.197998046875 +60744 -0.28289794921875 +60745 -0.16265869140625 +60746 -0.251617431640625 +60747 -0.1436767578125 +60748 -0.266143798828125 +60749 -0.151611328125 +60750 -0.273345947265625 +60751 -0.155487060546875 +60752 -0.216796875 +60753 -0.122344970703125 +60754 -0.128265380859375 +60755 -0.07073974609375 +60756 -0.068145751953125 +60757 -0.035919189453125 +60758 -0.0430908203125 +60759 -0.021728515625 +60760 -0.024444580078125 +60761 -0.011444091796875 +60762 0.020721435546875 +60763 0.01422119140625 +60764 0.124481201171875 +60765 0.074005126953125 +60766 0.25787353515625 +60767 0.151031494140625 +60768 0.379119873046875 +60769 0.220947265625 +60770 0.47991943359375 +60771 0.27899169921875 +60772 0.5281982421875 +60773 0.30645751953125 +60774 0.511138916015625 +60775 0.2958984375 +60776 0.456207275390625 +60777 0.26336669921875 +60778 0.407470703125 +60779 0.234649658203125 +60780 0.383758544921875 +60781 0.220733642578125 +60782 0.35687255859375 +60783 0.20513916015625 +60784 0.31182861328125 +60785 0.179107666015625 +60786 0.250885009765625 +60787 0.1439208984375 +60788 0.1654052734375 +60789 0.09454345703125 +60790 0.035247802734375 +60791 0.019195556640625 +60792 -0.142059326171875 +60793 -0.0836181640625 +60794 -0.33563232421875 +60795 -0.195892333984375 +60796 -0.5345458984375 +60797 -0.311279296875 +60798 -0.72186279296875 +60799 -0.419952392578125 +60800 -0.836669921875 +60801 -0.486358642578125 +60802 -0.8326416015625 +60803 -0.483489990234375 +60804 -0.7296142578125 +60805 -0.4229736328125 +60806 -0.582550048828125 +60807 -0.336944580078125 +60808 -0.440093994140625 +60809 -0.2537841796875 +60810 -0.324310302734375 +60811 -0.186370849609375 +60812 -0.20147705078125 +60813 -0.114990234375 +60814 -0.044647216796875 +60815 -0.02386474609375 +60816 0.103973388671875 +60817 0.062347412109375 +60818 0.202392578125 +60819 0.119171142578125 +60820 0.264495849609375 +60821 0.154754638671875 +60822 0.338897705078125 +60823 0.197509765625 +60824 0.443817138671875 +60825 0.25811767578125 +60826 0.545074462890625 +60827 0.316680908203125 +60828 0.6173095703125 +60829 0.3583984375 +60830 0.6524658203125 +60831 0.378570556640625 +60832 0.66339111328125 +60833 0.384735107421875 +60834 0.6561279296875 +60835 0.38043212890625 +60836 0.606781005859375 +60837 0.3516845703125 +60838 0.501190185546875 +60839 0.29022216796875 +60840 0.352783203125 +60841 0.203857421875 +60842 0.176544189453125 +60843 0.101318359375 +60844 -0.034820556640625 +60845 -0.021636962890625 +60846 -0.258209228515625 +60847 -0.151519775390625 +60848 -0.44244384765625 +60849 -0.25848388671875 +60850 -0.5753173828125 +60851 -0.33544921875 +60852 -0.65203857421875 +60853 -0.379669189453125 +60854 -0.641632080078125 +60855 -0.373046875 +60856 -0.562164306640625 +60857 -0.326202392578125 +60858 -0.458038330078125 +60859 -0.265106201171875 +60860 -0.350555419921875 +60861 -0.202178955078125 +60862 -0.260528564453125 +60863 -0.149566650390625 +60864 -0.192108154296875 +60865 -0.109710693359375 +60866 -0.141937255859375 +60867 -0.08062744140625 +60868 -0.1021728515625 +60869 -0.057708740234375 +60870 -0.062896728515625 +60871 -0.03515625 +60872 -0.011932373046875 +60873 -0.005859375 +60874 0.062835693359375 +60875 0.03729248046875 +60876 0.148712158203125 +60877 0.0869140625 +60878 0.241729736328125 +60879 0.14068603515625 +60880 0.34912109375 +60881 0.202880859375 +60882 0.457305908203125 +60883 0.265594482421875 +60884 0.54388427734375 +60885 0.3157958984375 +60886 0.5728759765625 +60887 0.332489013671875 +60888 0.506591796875 +60889 0.293670654296875 +60890 0.351226806640625 +60891 0.202972412109375 +60892 0.146514892578125 +60893 0.08355712890625 +60894 -0.05523681640625 +60895 -0.034027099609375 +60896 -0.21624755859375 +60897 -0.127716064453125 +60898 -0.334930419921875 +60899 -0.19659423828125 +60900 -0.402984619140625 +60901 -0.23583984375 +60902 -0.4412841796875 +60903 -0.257659912109375 +60904 -0.49578857421875 +60905 -0.288909912109375 +60906 -0.5601806640625 +60907 -0.325958251953125 +60908 -0.600738525390625 +60909 -0.349151611328125 +60910 -0.584228515625 +60911 -0.339111328125 +60912 -0.47930908203125 +60913 -0.27752685546875 +60914 -0.27935791015625 +60915 -0.16058349609375 +60916 -0.0089111328125 +60917 -0.00262451171875 +60918 0.268798828125 +60919 0.159423828125 +60920 0.482818603515625 +60921 0.284149169921875 +60922 0.60369873046875 +60923 0.3543701171875 +60924 0.650421142578125 +60925 0.38116455078125 +60926 0.66400146484375 +60927 0.3885498046875 +60928 0.6414794921875 +60929 0.37457275390625 +60930 0.572540283203125 +60931 0.333343505859375 +60932 0.498138427734375 +60933 0.2899169921875 +60934 0.439453125 +60935 0.257110595703125 +60936 0.375518798828125 +60937 0.221771240234375 +60938 0.274505615234375 +60939 0.163970947265625 +60940 0.1087646484375 +60941 0.06640625 +60942 -0.099395751953125 +60943 -0.05743408203125 +60944 -0.3182373046875 +60945 -0.188201904296875 +60946 -0.5489501953125 +60947 -0.326873779296875 +60948 -0.7738037109375 +60949 -0.462677001953125 +60950 -0.86383056640625 +60951 -0.563140869140625 +60952 -0.870391845703125 +60953 -0.607818603515625 +60954 -0.86895751953125 +60955 -0.607635498046875 +60956 -0.861053466796875 +60957 -0.570648193359375 +60958 -0.765869140625 +60959 -0.486114501953125 +60960 -0.5301513671875 +60961 -0.34698486328125 +60962 -0.214691162109375 +60963 -0.157470703125 +60964 0.137359619140625 +60965 0.05609130859375 +60966 0.474822998046875 +60967 0.262298583984375 +60968 0.76239013671875 +60969 0.439453125 +60970 0.867462158203125 +60971 0.571136474609375 +60972 0.870361328125 +60973 0.65777587890625 +60974 0.86480712890625 +60975 0.692413330078125 +60976 0.831817626953125 +60977 0.678436279296875 +60978 0.677581787109375 +60979 0.630950927734375 +60980 0.495880126953125 +60981 0.55352783203125 +60982 0.30767822265625 +60983 0.45758056640625 +60984 0.116180419921875 +60985 0.34442138671875 +60986 -0.110748291015625 +60987 0.194427490234375 +60988 -0.381805419921875 +60989 0.003204345703125 +60990 -0.6572265625 +60991 -0.202972412109375 +60992 -0.857421875 +60993 -0.38739013671875 +60994 -0.870391845703125 +60995 -0.52374267578125 +60996 -0.870391845703125 +60997 -0.6077880859375 +60998 -0.86444091796875 +60999 -0.65625 +61000 -0.85723876953125 +61001 -0.69122314453125 +61002 -0.790008544921875 +61003 -0.701507568359375 +61004 -0.62847900390625 +61005 -0.65374755859375 +61006 -0.3956298828125 +61007 -0.5460205078125 +61008 -0.126708984375 +61009 -0.398529052734375 +61010 0.150115966796875 +61011 -0.2281494140625 +61012 0.424041748046875 +61013 -0.04205322265625 +61014 0.670623779296875 +61015 0.143218994140625 +61016 0.854522705078125 +61017 0.303924560546875 +61018 0.866485595703125 +61019 0.42926025390625 +61020 0.86920166015625 +61021 0.5098876953125 +61022 0.8653564453125 +61023 0.557098388671875 +61024 0.857147216796875 +61025 0.5792236328125 +61026 0.766845703125 +61027 0.574615478515625 +61028 0.628509521484375 +61029 0.546478271484375 +61030 0.462127685546875 +61031 0.49072265625 +61032 0.297210693359375 +61033 0.42327880859375 +61034 0.14862060546875 +61035 0.351776123046875 +61036 -0.00537109375 +61037 0.262176513671875 +61038 -0.15753173828125 +61039 0.1590576171875 +61040 -0.31304931640625 +61041 0.0401611328125 +61042 -0.48876953125 +61043 -0.10321044921875 +61044 -0.6416015625 +61045 -0.24224853515625 +61046 -0.751373291015625 +61047 -0.36181640625 +61048 -0.84619140625 +61049 -0.476165771484375 +61050 -0.861297607421875 +61051 -0.57635498046875 +61052 -0.863250732421875 +61053 -0.64202880859375 +61054 -0.856597900390625 +61055 -0.653778076171875 +61056 -0.7498779296875 +61057 -0.619140625 +61058 -0.624542236328125 +61059 -0.57379150390625 +61060 -0.47808837890625 +61061 -0.504180908203125 +61062 -0.253387451171875 +61063 -0.37432861328125 +61064 0.003692626953125 +61065 -0.21234130859375 +61066 0.2257080078125 +61067 -0.060302734375 +61068 0.427154541015625 +61069 0.089508056640625 +61070 0.643218994140625 +61071 0.257049560546875 +61072 0.855926513671875 +61073 0.4364013671875 +61074 0.870361328125 +61075 0.5919189453125 +61076 0.870361328125 +61077 0.69305419921875 +61078 0.862762451171875 +61079 0.744293212890625 +61080 0.79669189453125 +61081 0.74383544921875 +61082 0.595794677734375 +61083 0.6859130859375 +61084 0.362152099609375 +61085 0.58856201171875 +61086 0.1270751953125 +61087 0.469085693359375 +61088 -0.086944580078125 +61089 0.340545654296875 +61090 -0.2784423828125 +61091 0.204254150390625 +61092 -0.484832763671875 +61093 0.038818359375 +61094 -0.729583740234375 +61095 -0.16754150390625 +61096 -0.86688232421875 +61097 -0.38360595703125 +61098 -0.870391845703125 +61099 -0.57037353515625 +61100 -0.86859130859375 +61101 -0.72479248046875 +61102 -0.86279296875 +61103 -0.84552001953125 +61104 -0.817962646484375 +61105 -0.860595703125 +61106 -0.6116943359375 +61107 -0.8585205078125 +61108 -0.3128662109375 +61109 -0.78424072265625 +61110 0.039398193359375 +61111 -0.60968017578125 +61112 0.422821044921875 +61113 -0.380126953125 +61114 0.805145263671875 +61115 -0.116119384765625 +61116 0.870361328125 +61117 0.140289306640625 +61118 0.870361328125 +61119 0.353851318359375 +61120 0.860015869140625 +61121 0.5172119140625 +61122 0.727935791015625 +61123 0.62548828125 +61124 0.48114013671875 +61125 0.675079345703125 +61126 0.2059326171875 +61127 0.68072509765625 +61128 -0.06103515625 +61129 0.656219482421875 +61130 -0.29913330078125 +61131 0.607635498046875 +61132 -0.516204833984375 +61133 0.5260009765625 +61134 -0.7252197265625 +61135 0.401824951171875 +61136 -0.85980224609375 +61137 0.25054931640625 +61138 -0.870391845703125 +61139 0.09344482421875 +61140 -0.870391845703125 +61141 -0.051025390625 +61142 -0.858062744140625 +61143 -0.152587890625 +61144 -0.673004150390625 +61145 -0.20831298828125 +61146 -0.42694091796875 +61147 -0.250213623046875 +61148 -0.2100830078125 +61149 -0.30523681640625 +61150 -0.0362548828125 +61151 -0.37176513671875 +61152 0.10943603515625 +61153 -0.43157958984375 +61154 0.23516845703125 +61155 -0.472137451171875 +61156 0.373687744140625 +61157 -0.4677734375 +61158 0.517791748046875 +61159 -0.4195556640625 +61160 0.602783203125 +61161 -0.366302490234375 +61162 0.635711669921875 +61163 -0.304901123046875 +61164 0.655181884765625 +61165 -0.2149658203125 +61166 0.65948486328125 +61167 -0.102874755859375 +61168 0.651275634765625 +61169 0.026123046875 +61170 0.61846923828125 +61171 0.15655517578125 +61172 0.53753662109375 +61173 0.26519775390625 +61174 0.404144287109375 +61175 0.340576171875 +61176 0.22186279296875 +61177 0.3763427734375 +61178 0.003997802734375 +61179 0.372894287109375 +61180 -0.22100830078125 +61181 0.341064453125 +61182 -0.42449951171875 +61183 0.293365478515625 +61184 -0.579833984375 +61185 0.2431640625 +61186 -0.641876220703125 +61187 0.217437744140625 +61188 -0.6177978515625 +61189 0.211517333984375 +61190 -0.575531005859375 +61191 0.183990478515625 +61192 -0.526336669921875 +61193 0.131805419921875 +61194 -0.42645263671875 +61195 0.08892822265625 +61196 -0.2581787109375 +61197 0.073516845703125 +61198 -0.068695068359375 +61199 0.062408447265625 +61200 0.09222412109375 +61201 0.030975341796875 +61202 0.232147216796875 +61203 -0.008392333984375 +61204 0.3509521484375 +61205 -0.048858642578125 +61206 0.410064697265625 +61207 -0.109375 +61208 0.372955322265625 +61209 -0.208770751953125 +61210 0.2554931640625 +61211 -0.333343505859375 +61212 0.10711669921875 +61213 -0.449249267578125 +61214 -0.052886962890625 +61215 -0.54376220703125 +61216 -0.186279296875 +61217 -0.59344482421875 +61218 -0.23291015625 +61219 -0.562164306640625 +61220 -0.209442138671875 +61221 -0.46478271484375 +61222 -0.174163818359375 +61223 -0.344146728515625 +61224 -0.126739501953125 +61225 -0.205841064453125 +61226 -0.048126220703125 +61227 -0.043670654296875 +61228 0.0426025390625 +61229 0.123809814453125 +61230 0.10748291015625 +61231 0.26617431640625 +61232 0.1409912109375 +61233 0.374603271484375 +61234 0.19708251953125 +61235 0.479705810546875 +61236 0.273651123046875 +61237 0.576904296875 +61238 0.31768798828125 +61239 0.629852294921875 +61240 0.341094970703125 +61241 0.645599365234375 +61242 0.368011474609375 +61243 0.640472412109375 +61244 0.37249755859375 +61245 0.59954833984375 +61246 0.30072021484375 +61247 0.490936279296875 +61248 0.1517333984375 +61249 0.31793212890625 +61250 -0.01470947265625 +61251 0.123809814453125 +61252 -0.1883544921875 +61253 -0.079742431640625 +61254 -0.372711181640625 +61255 -0.2899169921875 +61256 -0.51397705078125 +61257 -0.4669189453125 +61258 -0.57177734375 +61259 -0.580047607421875 +61260 -0.53948974609375 +61261 -0.6212158203125 +61262 -0.43511962890625 +61263 -0.59906005859375 +61264 -0.2962646484375 +61265 -0.53594970703125 +61266 -0.161102294921875 +61267 -0.455718994140625 +61268 -0.0435791015625 +61269 -0.367523193359375 +61270 0.060394287109375 +61271 -0.26995849609375 +61272 0.13665771484375 +61273 -0.174346923828125 +61274 0.170135498046875 +61275 -0.093414306640625 +61276 0.16552734375 +61277 -0.027740478515625 +61278 0.15728759765625 +61279 0.04095458984375 +61280 0.150787353515625 +61281 0.11199951171875 +61282 0.12200927734375 +61283 0.165679931640625 +61284 0.080108642578125 +61285 0.20404052734375 +61286 0.05126953125 +61287 0.24066162109375 +61288 0.062896728515625 +61289 0.2906494140625 +61290 0.09271240234375 +61291 0.337554931640625 +61292 0.092987060546875 +61293 0.349395751953125 +61294 0.07855224609375 +61295 0.33563232421875 +61296 0.06427001953125 +61297 0.30657958984375 +61298 0.0347900390625 +61299 0.253814697265625 +61300 -0.01171875 +61301 0.1783447265625 +61302 -0.056060791015625 +61303 0.095428466796875 +61304 -0.055511474609375 +61305 0.03594970703125 +61306 -0.010467529296875 +61307 0.003082275390625 +61308 0.02508544921875 +61309 -0.034637451171875 +61310 0.025665283203125 +61311 -0.0904541015625 +61312 0.017333984375 +61313 -0.144561767578125 +61314 0.00189208984375 +61315 -0.193359375 +61316 -0.03173828125 +61317 -0.242218017578125 +61318 -0.071502685546875 +61319 -0.282196044921875 +61320 -0.13543701171875 +61321 -0.3245849609375 +61322 -0.219970703125 +61323 -0.36737060546875 +61324 -0.300506591796875 +61325 -0.3956298828125 +61326 -0.376312255859375 +61327 -0.4105224609375 +61328 -0.416107177734375 +61329 -0.393951416015625 +61330 -0.371124267578125 +61331 -0.316864013671875 +61332 -0.242279052734375 +61333 -0.1826171875 +61334 -0.069732666015625 +61335 -0.020111083984375 +61336 0.125640869140625 +61337 0.154327392578125 +61338 0.31268310546875 +61339 0.318023681640625 +61340 0.45501708984375 +61341 0.445220947265625 +61342 0.554779052734375 +61343 0.535614013671875 +61344 0.61065673828125 +61345 0.58721923828125 +61346 0.610931396484375 +61347 0.5919189453125 +61348 0.531463623046875 +61349 0.534149169921875 +61350 0.3883056640625 +61351 0.424957275390625 +61352 0.23468017578125 +61353 0.29998779296875 +61354 0.095245361328125 +61355 0.176910400390625 +61356 -0.00396728515625 +61357 0.074554443359375 +61358 -0.04852294921875 +61359 0.004486083984375 +61360 -0.055145263671875 +61361 -0.041748046875 +61362 -0.0758056640625 +61363 -0.095550537109375 +61364 -0.138702392578125 +61365 -0.17303466796875 +61366 -0.209197998046875 +61367 -0.249847412109375 +61368 -0.289031982421875 +61369 -0.325592041015625 +61370 -0.37884521484375 +61371 -0.399566650390625 +61372 -0.456329345703125 +61373 -0.4566650390625 +61374 -0.51641845703125 +61375 -0.493499755859375 +61376 -0.519287109375 +61377 -0.484649658203125 +61378 -0.458251953125 +61379 -0.4266357421875 +61380 -0.384796142578125 +61381 -0.354034423828125 +61382 -0.323699951171875 +61383 -0.284423828125 +61384 -0.269287109375 +61385 -0.215911865234375 +61386 -0.1951904296875 +61387 -0.133331298828125 +61388 -0.100006103515625 +61389 -0.037689208984375 +61390 -0.01055908203125 +61391 0.0517578125 +61392 0.1033935546875 +61393 0.1529541015625 +61394 0.24908447265625 +61395 0.269256591796875 +61396 0.373199462890625 +61397 0.365081787109375 +61398 0.45806884765625 +61399 0.428314208984375 +61400 0.511474609375 +61401 0.463714599609375 +61402 0.565399169921875 +61403 0.492218017578125 +61404 0.61138916015625 +61405 0.5089111328125 +61406 0.5897216796875 +61407 0.475982666015625 +61408 0.4906005859375 +61409 0.388275146484375 +61410 0.33148193359375 +61411 0.258544921875 +61412 0.147796630859375 +61413 0.11126708984375 +61414 -0.01873779296875 +61415 -0.024932861328125 +61416 -0.140289306640625 +61417 -0.130462646484375 +61418 -0.191986083984375 +61419 -0.187774658203125 +61420 -0.184295654296875 +61421 -0.20245361328125 +61422 -0.161834716796875 +61423 -0.20245361328125 +61424 -0.166595458984375 +61425 -0.21435546875 +61426 -0.19390869140625 +61427 -0.23480224609375 +61428 -0.22442626953125 +61429 -0.251251220703125 +61430 -0.279754638671875 +61431 -0.278106689453125 +61432 -0.3389892578125 +61433 -0.302459716796875 +61434 -0.3543701171875 +61435 -0.294281005859375 +61436 -0.348175048828125 +61437 -0.26910400390625 +61438 -0.32598876953125 +61439 -0.231781005859375 +61440 -0.2581787109375 +61441 -0.1644287109375 +61442 -0.139801025390625 +61443 -0.065093994140625 +61444 0.014617919921875 +61445 0.055633544921875 +61446 0.144378662109375 +61447 0.1572265625 +61448 0.221038818359375 +61449 0.220367431640625 +61450 0.27069091796875 +61451 0.261383056640625 +61452 0.294036865234375 +61453 0.280426025390625 +61454 0.311767578125 +61455 0.29083251953125 +61456 0.339141845703125 +61457 0.3028564453125 +61458 0.360260009765625 +61459 0.30694580078125 +61460 0.360504150390625 +61461 0.294189453125 +61462 0.308380126953125 +61463 0.2437744140625 +61464 0.18170166015625 +61465 0.14141845703125 +61466 0.0047607421875 +61467 0.0045166015625 +61468 -0.17559814453125 +61469 -0.134246826171875 +61470 -0.3143310546875 +61471 -0.243438720703125 +61472 -0.36785888671875 +61473 -0.29266357421875 +61474 -0.36248779296875 +61475 -0.2991943359375 +61476 -0.343536376953125 +61477 -0.2933349609375 +61478 -0.3018798828125 +61479 -0.26861572265625 +61480 -0.231414794921875 +61481 -0.220794677734375 +61482 -0.117645263671875 +61483 -0.140106201171875 +61484 0.007049560546875 +61485 -0.048828125 +61486 0.087982177734375 +61487 0.015411376953125 +61488 0.13946533203125 +61489 0.061767578125 +61490 0.17425537109375 +61491 0.0982666015625 +61492 0.188201904296875 +61493 0.121307373046875 +61494 0.171234130859375 +61495 0.123291015625 +61496 0.118438720703125 +61497 0.100128173828125 +61498 0.05706787109375 +61499 0.0697021484375 +61500 -0.010711669921875 +61501 0.032867431640625 +61502 -0.0914306640625 +61503 -0.015228271484375 +61504 -0.162322998046875 +61505 -0.059356689453125 +61506 -0.194549560546875 +61507 -0.080078125 +61508 -0.1492919921875 +61509 -0.050994873046875 +61510 -0.02166748046875 +61511 0.031341552734375 +61512 0.124053955078125 +61513 0.12359619140625 +61514 0.211151123046875 +61515 0.174041748046875 +61516 0.240447998046875 +61517 0.183807373046875 +61518 0.242218017578125 +61519 0.17401123046875 +61520 0.2257080078125 +61521 0.151611328125 +61522 0.194366455078125 +61523 0.119537353515625 +61524 0.115509033203125 +61525 0.05615234375 +61526 0.0128173828125 +61527 -0.02191162109375 +61528 -0.053802490234375 +61529 -0.073516845703125 +61530 -0.110626220703125 +61531 -0.116241455078125 +61532 -0.199493408203125 +61533 -0.17840576171875 +61534 -0.29437255859375 +61535 -0.242279052734375 +61536 -0.33221435546875 +61537 -0.26507568359375 +61538 -0.27972412109375 +61539 -0.22442626953125 +61540 -0.185333251953125 +61541 -0.153533935546875 +61542 -0.128204345703125 +61543 -0.106658935546875 +61544 -0.115692138671875 +61545 -0.089263916015625 +61546 -0.116455078125 +61547 -0.08056640625 +61548 -0.105926513671875 +61549 -0.064361572265625 +61550 -0.053955078125 +61551 -0.020660400390625 +61552 0.048797607421875 +61553 0.056427001953125 +61554 0.157318115234375 +61555 0.135955810546875 +61556 0.212005615234375 +61557 0.1771240234375 +61558 0.218475341796875 +61559 0.18359375 +61560 0.23724365234375 +61561 0.196441650390625 +61562 0.30535888671875 +61563 0.240966796875 +61564 0.38128662109375 +61565 0.289031982421875 +61566 0.404449462890625 +61567 0.2996826171875 +61568 0.3944091796875 +61569 0.286529541015625 +61570 0.3885498046875 +61571 0.275390625 +61572 0.362640380859375 +61573 0.250244140625 +61574 0.27362060546875 +61575 0.18218994140625 +61576 0.11712646484375 +61577 0.068695068359375 +61578 -0.054901123046875 +61579 -0.054534912109375 +61580 -0.19085693359375 +61581 -0.152099609375 +61582 -0.28570556640625 +61583 -0.2203369140625 +61584 -0.339263916015625 +61585 -0.25897216796875 +61586 -0.3775634765625 +61587 -0.285614013671875 +61588 -0.445709228515625 +61589 -0.330963134765625 +61590 -0.535064697265625 +61591 -0.389251708984375 +61592 -0.629058837890625 +61593 -0.449371337890625 +61594 -0.697601318359375 +61595 -0.4910888671875 +61596 -0.70391845703125 +61597 -0.489715576171875 +61598 -0.6424560546875 +61599 -0.441802978515625 +61600 -0.491241455078125 +61601 -0.332733154296875 +61602 -0.265716552734375 +61603 -0.173370361328125 +61604 -0.023712158203125 +61605 -0.00335693359375 +61606 0.201751708984375 +61607 0.154541015625 +61608 0.375823974609375 +61609 0.276397705078125 +61610 0.485076904296875 +61611 0.352935791015625 +61612 0.56884765625 +61613 0.41082763671875 +61614 0.634765625 +61615 0.45526123046875 +61616 0.63763427734375 +61617 0.45556640625 +61618 0.5660400390625 +61619 0.404083251953125 +61620 0.4720458984375 +61621 0.336395263671875 +61622 0.40692138671875 +61623 0.28759765625 +61624 0.3778076171875 +61625 0.2628173828125 +61626 0.376953125 +61627 0.257080078125 +61628 0.371978759765625 +61629 0.2486572265625 +61630 0.313140869140625 +61631 0.204010009765625 +61632 0.184417724609375 +61633 0.112457275390625 +61634 0.011199951171875 +61635 -0.008514404296875 +61636 -0.171051025390625 +61637 -0.1346435546875 +61638 -0.33740234375 +61639 -0.2489013671875 +61640 -0.47198486328125 +61641 -0.340423583984375 +61642 -0.560394287109375 +61643 -0.39947509765625 +61644 -0.58056640625 +61645 -0.411163330078125 +61646 -0.54754638671875 +61647 -0.385833740234375 +61648 -0.508575439453125 +61649 -0.355804443359375 +61650 -0.459503173828125 +61651 -0.318450927734375 +61652 -0.394378662109375 +61653 -0.269989013671875 +61654 -0.35260009765625 +61655 -0.237396240234375 +61656 -0.31170654296875 +61657 -0.20562744140625 +61658 -0.197418212890625 +61659 -0.124420166015625 +61660 -0.007965087890625 +61661 0.007232666015625 +61662 0.207489013671875 +61663 0.155792236328125 +61664 0.409210205078125 +61665 0.29412841796875 +61666 0.57208251953125 +61667 0.405120849609375 +61668 0.66595458984375 +61669 0.468292236328125 +61670 0.65875244140625 +61671 0.4619140625 +61672 0.56744384765625 +61673 0.397613525390625 +61674 0.431396484375 +61675 0.302337646484375 +61676 0.29443359375 +61677 0.2060546875 +61678 0.182464599609375 +61679 0.126556396484375 +61680 0.06365966796875 +61681 0.0423583984375 +61682 -0.075958251953125 +61683 -0.055816650390625 +61684 -0.189422607421875 +61685 -0.1358642578125 +61686 -0.271942138671875 +61687 -0.19439697265625 +61688 -0.342529296875 +61689 -0.24420166015625 +61690 -0.364166259765625 +61691 -0.26007080078125 +61692 -0.327239990234375 +61693 -0.23541259765625 +61694 -0.2769775390625 +61695 -0.20098876953125 +61696 -0.253692626953125 +61697 -0.184478759765625 +61698 -0.24365234375 +61699 -0.176361083984375 +61700 -0.1983642578125 +61701 -0.1427001953125 +61702 -0.116241455078125 +61703 -0.08258056640625 +61704 -0.036834716796875 +61705 -0.024383544921875 +61706 0.034881591796875 +61707 0.028167724609375 +61708 0.09124755859375 +61709 0.06951904296875 +61710 0.10888671875 +61711 0.082916259765625 +61712 0.125518798828125 +61713 0.095184326171875 +61714 0.15771484375 +61715 0.118133544921875 +61716 0.17828369140625 +61717 0.13238525390625 +61718 0.17108154296875 +61719 0.126495361328125 +61720 0.129974365234375 +61721 0.09619140625 +61722 0.082427978515625 +61723 0.06109619140625 +61724 0.027679443359375 +61725 0.020751953125 +61726 -0.065643310546875 +61727 -0.047088623046875 +61728 -0.15936279296875 +61729 -0.115142822265625 +61730 -0.21307373046875 +61731 -0.154571533203125 +61732 -0.234649658203125 +61733 -0.1708984375 +61734 -0.2001953125 +61735 -0.1470947265625 +61736 -0.119171142578125 +61737 -0.08984375 +61738 -0.024749755859375 +61739 -0.02276611328125 +61740 0.085784912109375 +61741 0.056060791015625 +61742 0.178131103515625 +61743 0.122222900390625 +61744 0.215576171875 +61745 0.1495361328125 +61746 0.211456298828125 +61747 0.1474609375 +61748 0.17523193359375 +61749 0.1226806640625 +61750 0.128753662109375 +61751 0.090667724609375 +61752 0.1019287109375 +61753 0.072662353515625 +61754 0.0743408203125 +61755 0.054107666015625 +61756 0.04327392578125 +61757 0.032989501953125 +61758 0.038177490234375 +61759 0.03021240234375 +61760 0.076263427734375 +61761 0.0579833984375 +61762 0.14105224609375 +61763 0.10455322265625 +61764 0.186431884765625 +61765 0.137054443359375 +61766 0.188812255859375 +61767 0.138702392578125 +61768 0.1390380859375 +61769 0.102996826171875 +61770 0.041778564453125 +61771 0.03326416015625 +61772 -0.079437255859375 +61773 -0.05364990234375 +61774 -0.219390869140625 +61775 -0.154052734375 +61776 -0.367828369140625 +61777 -0.260589599609375 +61778 -0.494873046875 +61779 -0.3519287109375 +61780 -0.556243896484375 +61781 -0.396514892578125 +61782 -0.508697509765625 +61783 -0.363494873046875 +61784 -0.3756103515625 +61785 -0.26947021484375 +61786 -0.218902587890625 +61787 -0.15850830078125 +61788 -0.063751220703125 +61789 -0.0484619140625 +61790 0.091552734375 +61791 0.061859130859375 +61792 0.23602294921875 +61793 0.164642333984375 +61794 0.342987060546875 +61795 0.24090576171875 +61796 0.39520263671875 +61797 0.278350830078125 +61798 0.389373779296875 +61799 0.274627685546875 +61800 0.324249267578125 +61801 0.22882080078125 +61802 0.224090576171875 +61803 0.158172607421875 +61804 0.124267578125 +61805 0.08782958984375 +61806 0.037078857421875 +61807 0.026458740234375 +61808 -0.010101318359375 +61809 -0.006439208984375 +61810 -0.019439697265625 +61811 -0.012451171875 +61812 -0.022796630859375 +61813 -0.0142822265625 +61814 -0.001556396484375 +61815 0.00128173828125 +61816 0.056304931640625 +61817 0.042755126953125 +61818 0.106719970703125 +61819 0.0787353515625 +61820 0.096893310546875 +61821 0.071685791015625 +61822 0.042694091796875 +61823 0.03289794921875 +61824 -0.018035888671875 +61825 -0.010650634765625 +61826 -0.07586669921875 +61827 -0.05224609375 +61828 -0.11944580078125 +61829 -0.083740234375 +61830 -0.15972900390625 +61831 -0.11297607421875 +61832 -0.202606201171875 +61833 -0.144073486328125 +61834 -0.24859619140625 +61835 -0.177337646484375 +61836 -0.30517578125 +61837 -0.21807861328125 +61838 -0.36212158203125 +61839 -0.259033203125 +61840 -0.39141845703125 +61841 -0.280242919921875 +61842 -0.35528564453125 +61843 -0.254730224609375 +61844 -0.249969482421875 +61845 -0.179840087890625 +61846 -0.092864990234375 +61847 -0.0679931640625 +61848 0.08905029296875 +61849 0.061614990234375 +61850 0.2352294921875 +61851 0.165863037109375 +61852 0.318817138671875 +61853 0.225616455078125 +61854 0.358642578125 +61855 0.2542724609375 +61856 0.347747802734375 +61857 0.246856689453125 +61858 0.28564453125 +61859 0.2030029296875 +61860 0.223175048828125 +61861 0.158905029296875 +61862 0.196746826171875 +61863 0.140472412109375 +61864 0.179840087890625 +61865 0.128814697265625 +61866 0.155548095703125 +61867 0.111846923828125 +61868 0.151214599609375 +61869 0.109039306640625 +61870 0.156951904296875 +61871 0.11334228515625 +61872 0.13177490234375 +61873 0.09552001953125 +61874 0.100799560546875 +61875 0.073486328125 +61876 0.087127685546875 +61877 0.06365966796875 +61878 0.05487060546875 +61879 0.040496826171875 +61880 -0.009002685546875 +61881 -0.0052490234375 +61882 -0.10400390625 +61883 -0.07318115234375 +61884 -0.229400634765625 +61885 -0.16278076171875 +61886 -0.35552978515625 +61887 -0.252899169921875 +61888 -0.441925048828125 +61889 -0.314697265625 +61890 -0.473846435546875 +61891 -0.33770751953125 +61892 -0.464813232421875 +61893 -0.331512451171875 +61894 -0.419097900390625 +61895 -0.29913330078125 +61896 -0.334320068359375 +61897 -0.2388916015625 +61898 -0.227935791015625 +61899 -0.1632080078125 +61900 -0.12347412109375 +61901 -0.088836669921875 +61902 -0.02764892578125 +61903 -0.020538330078125 +61904 0.077667236328125 +61905 0.0545654296875 +61906 0.2132568359375 +61907 0.151275634765625 +61908 0.38885498046875 +61909 0.2764892578125 +61910 0.582794189453125 +61911 0.414794921875 +61912 0.734039306640625 +61913 0.522705078125 +61914 0.800140380859375 +61915 0.569976806640625 +61916 0.7783203125 +61917 0.554595947265625 +61918 0.6651611328125 +61919 0.474151611328125 +61920 0.45965576171875 +61921 0.32794189453125 +61922 0.199188232421875 +61923 0.142547607421875 +61924 -0.050689697265625 +61925 -0.03533935546875 +61926 -0.23297119140625 +61927 -0.165130615234375 +61928 -0.33013916015625 +61929 -0.234375 +61930 -0.368408203125 +61931 -0.26171875 +61932 -0.378936767578125 +61933 -0.269317626953125 +61934 -0.376983642578125 +61935 -0.268035888671875 +61936 -0.37969970703125 +61937 -0.270111083984375 +61938 -0.391510009765625 +61939 -0.278656005859375 +61940 -0.385345458984375 +61941 -0.2744140625 +61942 -0.3419189453125 +61943 -0.243621826171875 +61944 -0.28289794921875 +61945 -0.20172119140625 +61946 -0.251617431640625 +61947 -0.179534912109375 +61948 -0.266143798828125 +61949 -0.189910888671875 +61950 -0.273345947265625 +61951 -0.195037841796875 +61952 -0.216796875 +61953 -0.154632568359375 +61954 -0.128265380859375 +61955 -0.091522216796875 +61956 -0.068145751953125 +61957 -0.04974365234375 +61958 -0.0430908203125 +61959 -0.034027099609375 +61960 -0.024444580078125 +61961 -0.022918701171875 +61962 0.020721435546875 +61963 0.008270263671875 +61964 0.124481201171875 +61965 0.083465576171875 +61966 0.25787353515625 +61967 0.181243896484375 +61968 0.379119873046875 +61969 0.27056884765625 +61970 0.47991943359375 +61971 0.3453369140625 +61972 0.5281982421875 +61973 0.38165283203125 +61974 0.511138916015625 +61975 0.369964599609375 +61976 0.456207275390625 +61977 0.330657958984375 +61978 0.407470703125 +61979 0.296417236328125 +61980 0.383758544921875 +61981 0.281097412109375 +61982 0.35687255859375 +61983 0.263580322265625 +61984 0.31182861328125 +61985 0.232574462890625 +61986 0.250885009765625 +61987 0.18963623046875 +61988 0.1654052734375 +61989 0.128173828125 +61990 0.035247802734375 +61991 0.03314208984375 +61992 -0.142059326171875 +61993 -0.097381591796875 +61994 -0.33563232421875 +61995 -0.240478515625 +61996 -0.5345458984375 +61997 -0.388031005859375 +61998 -0.72186279296875 +61999 -0.527496337890625 +62000 -0.836669921875 +62001 -0.613525390625 +62002 -0.8326416015625 +62003 -0.611602783203125 +62004 -0.7296142578125 +62005 -0.536407470703125 +62006 -0.582550048828125 +62007 -0.428741455078125 +62008 -0.440093994140625 +62009 -0.32470703125 +62010 -0.324310302734375 +62011 -0.2406005859375 +62012 -0.20147705078125 +62013 -0.151214599609375 +62014 -0.044647216796875 +62015 -0.036376953125 +62016 0.103973388671875 +62017 0.07257080078125 +62018 0.202392578125 +62019 0.14447021484375 +62020 0.264495849609375 +62021 0.189727783203125 +62022 0.338897705078125 +62023 0.24456787109375 +62024 0.443817138671875 +62025 0.322540283203125 +62026 0.545074462890625 +62027 0.398193359375 +62028 0.6173095703125 +62029 0.45263671875 +62030 0.6524658203125 +62031 0.479827880859375 +62032 0.66339111328125 +62033 0.4892578125 +62034 0.6561279296875 +62035 0.4853515625 +62036 0.606781005859375 +62037 0.450225830078125 +62038 0.501190185546875 +62039 0.373260498046875 +62040 0.352783203125 +62041 0.264373779296875 +62042 0.176544189453125 +62043 0.134613037109375 +62044 -0.034820556640625 +62045 -0.021484375 +62046 -0.258209228515625 +62047 -0.186798095703125 +62048 -0.44244384765625 +62049 -0.32330322265625 +62050 -0.5753173828125 +62051 -0.421905517578125 +62052 -0.65203857421875 +62053 -0.47906494140625 +62054 -0.641632080078125 +62055 -0.471710205078125 +62056 -0.562164306640625 +62057 -0.413299560546875 +62058 -0.458038330078125 +62059 -0.3367919921875 +62060 -0.350555419921875 +62061 -0.257965087890625 +62062 -0.260528564453125 +62063 -0.192230224609375 +62064 -0.192108154296875 +62065 -0.142608642578125 +62066 -0.141937255859375 +62067 -0.106536865234375 +62068 -0.1021728515625 +62069 -0.078094482421875 +62070 -0.062896728515625 +62071 -0.04986572265625 +62072 -0.011932373046875 +62073 -0.012725830078125 +62074 0.062835693359375 +62075 0.0423583984375 +62076 0.148712158203125 +62077 0.105987548828125 +62078 0.241729736328125 +62079 0.1751708984375 +62080 0.34912109375 +62081 0.25531005859375 +62082 0.457305908203125 +62083 0.336273193359375 +62084 0.54388427734375 +62085 0.4013671875 +62086 0.5728759765625 +62087 0.42376708984375 +62088 0.506591796875 +62089 0.375396728515625 +62090 0.351226806640625 +62091 0.26080322265625 +62092 0.146514892578125 +62093 0.109466552734375 +62094 -0.05523681640625 +62095 -0.03973388671875 +62096 -0.21624755859375 +62097 -0.158721923828125 +62098 -0.334930419921875 +62099 -0.246337890625 +62100 -0.402984619140625 +62101 -0.29644775390625 +62102 -0.4412841796875 +62103 -0.3245849609375 +62104 -0.49578857421875 +62105 -0.364990234375 +62106 -0.5601806640625 +62107 -0.412933349609375 +62108 -0.600738525390625 +62109 -0.443328857421875 +62110 -0.584228515625 +62111 -0.43145751953125 +62112 -0.47930908203125 +62113 -0.35394287109375 +62114 -0.27935791015625 +62115 -0.20587158203125 +62116 -0.0089111328125 +62117 -0.00543212890625 +62118 0.268798828125 +62119 0.200347900390625 +62120 0.482818603515625 +62121 0.3587646484375 +62122 0.60369873046875 +62123 0.447967529296875 +62124 0.650421142578125 +62125 0.4820556640625 +62126 0.66400146484375 +62127 0.4915771484375 +62128 0.6414794921875 +62129 0.474395751953125 +62130 0.572540283203125 +62131 0.422821044921875 +62132 0.498138427734375 +62133 0.36737060546875 +62134 0.439453125 +62135 0.32379150390625 +62136 0.375518798828125 +62137 0.2764892578125 +62138 0.274505615234375 +62139 0.201751708984375 +62140 0.1087646484375 +62141 0.0789794921875 +62142 -0.099395751953125 +62143 -0.075286865234375 +62144 -0.3182373046875 +62145 -0.2374267578125 +62146 -0.5489501953125 +62147 -0.408355712890625 +62148 -0.7738037109375 +62149 -0.574920654296875 +62150 -0.86383056640625 +62151 -0.697784423828125 +62152 -0.870391845703125 +62153 -0.752227783203125 +62154 -0.86895751953125 +62155 -0.751495361328125 +62156 -0.861053466796875 +62157 -0.705322265625 +62158 -0.765869140625 +62159 -0.600860595703125 +62160 -0.5301513671875 +62161 -0.42974853515625 +62162 -0.214691162109375 +62163 -0.197296142578125 +62164 0.137359619140625 +62165 0.064483642578125 +62166 0.474822998046875 +62167 0.31744384765625 +62168 0.76239013671875 +62169 0.535186767578125 +62170 0.867462158203125 +62171 0.6976318359375 +62172 0.870361328125 +62173 0.80517578125 +62174 0.86480712890625 +62175 0.849212646484375 +62176 0.831817626953125 +62177 0.833770751953125 +62178 0.677581787109375 +62179 0.777008056640625 +62180 0.495880126953125 +62181 0.683258056640625 +62182 0.30767822265625 +62183 0.56634521484375 +62184 0.116180419921875 +62185 0.427947998046875 +62186 -0.110748291015625 +62187 0.24444580078125 +62188 -0.381805419921875 +62189 0.010711669921875 +62190 -0.6572265625 +62191 -0.241424560546875 +62192 -0.857421875 +62193 -0.4674072265625 +62194 -0.870391845703125 +62195 -0.635284423828125 +62196 -0.870391845703125 +62197 -0.739776611328125 +62198 -0.86444091796875 +62199 -0.8009033203125 +62200 -0.85723876953125 +62201 -0.84521484375 +62202 -0.790008544921875 +62203 -0.855010986328125 +62204 -0.62847900390625 +62205 -0.802215576171875 +62206 -0.3956298828125 +62207 -0.67218017578125 +62208 -0.126708984375 +62209 -0.493408203125 +62210 0.150115966796875 +62211 -0.28631591796875 +62212 0.424041748046875 +62213 -0.059326171875 +62214 0.670623779296875 +62215 0.167266845703125 +62216 0.854522705078125 +62217 0.3638916015625 +62218 0.866485595703125 +62219 0.517333984375 +62220 0.86920166015625 +62221 0.615997314453125 +62222 0.8653564453125 +62223 0.674224853515625 +62224 0.857147216796875 +62225 0.70257568359375 +62226 0.766845703125 +62227 0.69879150390625 +62228 0.628509521484375 +62229 0.666778564453125 +62230 0.462127685546875 +62231 0.60113525390625 +62232 0.297210693359375 +62233 0.521636962890625 +62234 0.14862060546875 +62235 0.43756103515625 +62236 -0.00537109375 +62237 0.330841064453125 +62238 -0.15753173828125 +62239 0.2069091796875 +62240 -0.31304931640625 +62241 0.06256103515625 +62242 -0.48876953125 +62243 -0.1134033203125 +62244 -0.6416015625 +62245 -0.284942626953125 +62246 -0.751373291015625 +62247 -0.433135986328125 +62248 -0.84619140625 +62249 -0.57611083984375 +62250 -0.861297607421875 +62251 -0.70257568359375 +62252 -0.863250732421875 +62253 -0.78680419921875 +62254 -0.856597900390625 +62255 -0.80426025390625 +62256 -0.7498779296875 +62257 -0.7642822265625 +62258 -0.624542236328125 +62259 -0.7115478515625 +62260 -0.47808837890625 +62261 -0.6287841796875 +62262 -0.253387451171875 +62263 -0.4703369140625 +62264 0.003692626953125 +62265 -0.271331787109375 +62266 0.2257080078125 +62267 -0.084564208984375 +62268 0.427154541015625 +62269 0.0999755859375 +62270 0.643218994140625 +62271 0.30767822265625 +62272 0.855926513671875 +62273 0.531219482421875 +62274 0.870361328125 +62275 0.725830078125 +62276 0.870361328125 +62277 0.853057861328125 +62278 0.862762451171875 +62279 0.8614501953125 +62280 0.79669189453125 +62281 0.861602783203125 +62282 0.595794677734375 +62283 0.849761962890625 +62284 0.362152099609375 +62285 0.73065185546875 +62286 0.1270751953125 +62287 0.58416748046875 +62288 -0.086944580078125 +62289 0.426513671875 +62290 -0.2784423828125 +62291 0.259124755859375 +62292 -0.484832763671875 +62293 0.0548095703125 +62294 -0.729583740234375 +62295 -0.201507568359375 +62296 -0.86688232421875 +62297 -0.470703125 +62298 -0.870391845703125 +62299 -0.703765869140625 +62300 -0.86859130859375 +62301 -0.859130859375 +62302 -0.86279296875 +62303 -0.870391845703125 +62304 -0.817962646484375 +62305 -0.870391845703125 +62306 -0.6116943359375 +62307 -0.8599853515625 +62308 -0.3128662109375 +62309 -0.712371826171875 +62310 0.039398193359375 +62311 -0.4517822265625 +62312 0.422821044921875 +62313 -0.140289306640625 +62314 0.805145263671875 +62315 0.195465087890625 +62316 0.870361328125 +62317 0.5029296875 +62318 0.870361328125 +62319 0.739105224609375 +62320 0.860015869140625 +62321 0.859100341796875 +62322 0.727935791015625 +62323 0.867462158203125 +62324 0.48114013671875 +62325 0.8668212890625 +62326 0.2059326171875 +62327 0.85968017578125 +62328 -0.06103515625 +62329 0.798126220703125 +62330 -0.29913330078125 +62331 0.66748046875 +62332 -0.516204833984375 +62333 0.502532958984375 +62334 -0.7252197265625 +62335 0.29449462890625 +62336 -0.85980224609375 +62337 0.0653076171875 +62338 -0.870391845703125 +62339 -0.15643310546875 +62340 -0.870391845703125 +62341 -0.34661865234375 +62342 -0.858062744140625 +62343 -0.467132568359375 +62344 -0.673004150390625 +62345 -0.515167236328125 +62346 -0.42694091796875 +62347 -0.53265380859375 +62348 -0.2100830078125 +62349 -0.55584716796875 +62350 -0.0362548828125 +62351 -0.58551025390625 +62352 0.10943603515625 +62353 -0.60186767578125 +62354 0.23516845703125 +62355 -0.592529296875 +62356 0.373687744140625 +62357 -0.528472900390625 +62358 0.517791748046875 +62359 -0.4141845703125 +62360 0.602783203125 +62361 -0.30133056640625 +62362 0.635711669921875 +62363 -0.188262939453125 +62364 0.655181884765625 +62365 -0.05096435546875 +62366 0.65948486328125 +62367 0.101531982421875 +62368 0.651275634765625 +62369 0.26239013671875 +62370 0.61846923828125 +62371 0.41259765625 +62372 0.53753662109375 +62373 0.524078369140625 +62374 0.404144287109375 +62375 0.584014892578125 +62376 0.22186279296875 +62377 0.586578369140625 +62378 0.003997802734375 +62379 0.534820556640625 +62380 -0.22100830078125 +62381 0.44512939453125 +62382 -0.42449951171875 +62383 0.336029052734375 +62384 -0.579833984375 +62385 0.22662353515625 +62386 -0.641876220703125 +62387 0.15240478515625 +62388 -0.6177978515625 +62389 0.11029052734375 +62390 -0.575531005859375 +62391 0.0518798828125 +62392 -0.526336669921875 +62393 -0.02569580078125 +62394 -0.42645263671875 +62395 -0.08148193359375 +62396 -0.2581787109375 +62397 -0.093963623046875 +62398 -0.068695068359375 +62399 -0.091644287109375 +62400 0.09222412109375 +62401 -0.105194091796875 +62402 0.232147216796875 +62403 -0.12139892578125 +62404 0.3509521484375 +62405 -0.133941650390625 +62406 0.410064697265625 +62407 -0.167633056640625 +62408 0.372955322265625 +62409 -0.247161865234375 +62410 0.2554931640625 +62411 -0.3582763671875 +62412 0.10711669921875 +62413 -0.46246337890625 +62414 -0.052886962890625 +62415 -0.5462646484375 +62416 -0.186279296875 +62417 -0.5830078125 +62418 -0.23291015625 +62419 -0.530426025390625 +62420 -0.209442138671875 +62421 -0.40692138671875 +62422 -0.174163818359375 +62423 -0.263946533203125 +62424 -0.126739501953125 +62425 -0.10784912109375 +62426 -0.048126220703125 +62427 0.06951904296875 +62428 0.0426025390625 +62429 0.247100830078125 +62430 0.10748291015625 +62431 0.389892578125 +62432 0.1409912109375 +62433 0.48895263671875 +62434 0.19708251953125 +62435 0.582733154296875 +62436 0.273651123046875 +62437 0.66754150390625 +62438 0.31768798828125 +62439 0.701568603515625 +62440 0.341094970703125 +62441 0.694793701171875 +62442 0.368011474609375 +62443 0.66802978515625 +62444 0.37249755859375 +62445 0.6043701171875 +62446 0.30072021484375 +62447 0.466278076171875 +62448 0.1517333984375 +62449 0.2579345703125 +62450 -0.01470947265625 +62451 0.031036376953125 +62452 -0.1883544921875 +62453 -0.200958251953125 +62454 -0.372711181640625 +62455 -0.43548583984375 +62456 -0.51397705078125 +62457 -0.6259765625 +62458 -0.57177734375 +62459 -0.736968994140625 +62460 -0.53948974609375 +62461 -0.760162353515625 +62462 -0.43511962890625 +62463 -0.707427978515625 +62464 -0.2962646484375 +62465 -0.606689453125 +62466 -0.161102294921875 +62467 -0.487640380859375 +62468 -0.0435791015625 +62469 -0.362579345703125 +62470 0.060394287109375 +62471 -0.2308349609375 +62472 0.13665771484375 +62473 -0.107086181640625 +62474 0.170135498046875 +62475 -0.00738525390625 +62476 0.16552734375 +62477 0.067626953125 +62478 0.15728759765625 +62479 0.14093017578125 +62480 0.150787353515625 +62481 0.21240234375 +62482 0.12200927734375 +62483 0.25872802734375 +62484 0.080108642578125 +62485 0.283660888671875 +62486 0.05126953125 +62487 0.3052978515625 +62488 0.062896728515625 +62489 0.343536376953125 +62490 0.09271240234375 +62491 0.379425048828125 +62492 0.092987060546875 +62493 0.3746337890625 +62494 0.07855224609375 +62495 0.341796875 +62496 0.06427001953125 +62497 0.29443359375 +62498 0.0347900390625 +62499 0.22265625 +62500 -0.01171875 +62501 0.127960205078125 +62502 -0.056060791015625 +62503 0.029144287109375 +62504 -0.055511474609375 +62505 -0.035980224609375 +62506 -0.010467529296875 +62507 -0.064056396484375 +62508 0.02508544921875 +62509 -0.094818115234375 +62510 0.025665283203125 +62511 -0.145538330078125 +62512 0.017333984375 +62513 -0.19281005859375 +62514 0.00189208984375 +62515 -0.233306884765625 +62516 -0.03173828125 +62517 -0.27471923828125 +62518 -0.071502685546875 +62519 -0.30706787109375 +62520 -0.13543701171875 +62521 -0.3450927734375 +62522 -0.219970703125 +62523 -0.387054443359375 +62524 -0.300506591796875 +62525 -0.4150390625 +62526 -0.376312255859375 +62527 -0.430755615234375 +62528 -0.416107177734375 +62529 -0.411865234375 +62530 -0.371124267578125 +62531 -0.322296142578125 +62532 -0.242279052734375 +62533 -0.165771484375 +62534 -0.069732666015625 +62535 0.02264404296875 +62536 0.125640869140625 +62537 0.22357177734375 +62538 0.31268310546875 +62539 0.409820556640625 +62540 0.45501708984375 +62541 0.550537109375 +62542 0.554779052734375 +62543 0.646270751953125 +62544 0.61065673828125 +62545 0.695404052734375 +62546 0.610931396484375 +62547 0.688629150390625 +62548 0.531463623046875 +62549 0.60736083984375 +62550 0.3883056640625 +62551 0.465728759765625 +62552 0.23468017578125 +62553 0.308074951171875 +62554 0.095245361328125 +62555 0.156219482421875 +62556 -0.00396728515625 +62557 0.0333251953125 +62558 -0.04852294921875 +62559 -0.046600341796875 +62560 -0.055145263671875 +62561 -0.094451904296875 +62562 -0.0758056640625 +62563 -0.149566650390625 +62564 -0.138702392578125 +62565 -0.232513427734375 +62566 -0.209197998046875 +62567 -0.31396484375 +62568 -0.289031982421875 +62569 -0.394195556640625 +62570 -0.37884521484375 +62571 -0.473052978515625 +62572 -0.456329345703125 +62573 -0.532562255859375 +62574 -0.51641845703125 +62575 -0.569091796875 +62576 -0.519287109375 +62577 -0.551666259765625 +62578 -0.458251953125 +62579 -0.47625732421875 +62580 -0.384796142578125 +62581 -0.38568115234375 +62582 -0.323699951171875 +62583 -0.301666259765625 +62584 -0.269287109375 +62585 -0.221649169921875 +62586 -0.1951904296875 +62587 -0.1265869140625 +62588 -0.100006103515625 +62589 -0.01727294921875 +62590 -0.01055908203125 +62591 0.083038330078125 +62592 0.1033935546875 +62593 0.197113037109375 +62594 0.24908447265625 +62595 0.329681396484375 +62596 0.373199462890625 +62597 0.437408447265625 +62598 0.45806884765625 +62599 0.50592041015625 +62600 0.511474609375 +62601 0.5416259765625 +62602 0.565399169921875 +62603 0.570770263671875 +62604 0.61138916015625 +62605 0.5875244140625 +62606 0.5897216796875 +62607 0.545379638671875 +62608 0.4906005859375 +62609 0.43792724609375 +62610 0.33148193359375 +62611 0.280792236328125 +62612 0.147796630859375 +62613 0.10400390625 +62614 -0.01873779296875 +62615 -0.05743408203125 +62616 -0.140289306640625 +62617 -0.17974853515625 +62618 -0.191986083984375 +62619 -0.241790771484375 +62620 -0.184295654296875 +62621 -0.25091552734375 +62622 -0.161834716796875 +62623 -0.242156982421875 +62624 -0.166595458984375 +62625 -0.248748779296875 +62626 -0.19390869140625 +62627 -0.2669677734375 +62628 -0.22442626953125 +62629 -0.28173828125 +62630 -0.279754638671875 +62631 -0.31103515625 +62632 -0.3389892578125 +62633 -0.339111328125 +62634 -0.3543701171875 +62635 -0.3289794921875 +62636 -0.348175048828125 +62637 -0.29974365234375 +62638 -0.32598876953125 +62639 -0.257232666015625 +62640 -0.2581787109375 +62641 -0.17913818359375 +62642 -0.139801025390625 +62643 -0.062774658203125 +62644 0.014617919921875 +62645 0.07916259765625 +62646 0.144378662109375 +62647 0.1971435546875 +62648 0.221038818359375 +62649 0.267791748046875 +62650 0.27069091796875 +62651 0.311614990234375 +62652 0.294036865234375 +62653 0.3291015625 +62654 0.311767578125 +62655 0.337005615234375 +62656 0.339141845703125 +62657 0.34808349609375 +62658 0.360260009765625 +62659 0.35040283203125 +62660 0.360504150390625 +62661 0.333160400390625 +62662 0.308380126953125 +62663 0.271881103515625 +62664 0.18170166015625 +62665 0.14971923828125 +62666 0.0047607421875 +62667 -0.0125732421875 +62668 -0.17559814453125 +62669 -0.1761474609375 +62670 -0.3143310546875 +62671 -0.3037109375 +62672 -0.36785888671875 +62673 -0.359283447265625 +62674 -0.36248779296875 +62675 -0.363494873046875 +62676 -0.343536376953125 +62677 -0.352630615234375 +62678 -0.3018798828125 +62679 -0.319244384765625 +62680 -0.231414794921875 +62681 -0.258453369140625 +62682 -0.117645263671875 +62683 -0.158905029296875 +62684 0.007049560546875 +62685 -0.047271728515625 +62686 0.087982177734375 +62687 0.031585693359375 +62688 0.13946533203125 +62689 0.088409423828125 +62690 0.17425537109375 +62691 0.13262939453125 +62692 0.188201904296875 +62693 0.15997314453125 +62694 0.171234130859375 +62695 0.16143798828125 +62696 0.118438720703125 +62697 0.13226318359375 +62698 0.05706787109375 +62699 0.093780517578125 +62700 -0.010711669921875 +62701 0.04718017578125 +62702 -0.0914306640625 +62703 -0.013153076171875 +62704 -0.162322998046875 +62705 -0.0689697265625 +62706 -0.194549560546875 +62707 -0.09698486328125 +62708 -0.1492919921875 +62709 -0.06561279296875 +62710 -0.02166748046875 +62711 0.029449462890625 +62712 0.124053955078125 +62713 0.136810302734375 +62714 0.211151123046875 +62715 0.195098876953125 +62716 0.240447998046875 +62717 0.205718994140625 +62718 0.242218017578125 +62719 0.19384765625 +62720 0.2257080078125 +62721 0.168243408203125 +62722 0.194366455078125 +62723 0.132080078125 +62724 0.115509033203125 +62725 0.05780029296875 +62726 0.0128173828125 +62727 -0.03424072265625 +62728 -0.053802490234375 +62729 -0.093475341796875 +62730 -0.110626220703125 +62731 -0.141845703125 +62732 -0.199493408203125 +62733 -0.21453857421875 +62734 -0.29437255859375 +62735 -0.289825439453125 +62736 -0.33221435546875 +62737 -0.315032958984375 +62738 -0.27972412109375 +62739 -0.26263427734375 +62740 -0.185333251953125 +62741 -0.17376708984375 +62742 -0.128204345703125 +62743 -0.115478515625 +62744 -0.115692138671875 +62745 -0.094512939453125 +62746 -0.116455078125 +62747 -0.08514404296875 +62748 -0.105926513671875 +62749 -0.0672607421875 +62750 -0.053955078125 +62751 -0.016021728515625 +62752 0.048797607421875 +62753 0.0760498046875 +62754 0.157318115234375 +62755 0.1708984375 +62756 0.212005615234375 +62757 0.21832275390625 +62758 0.218475341796875 +62759 0.222991943359375 +62760 0.23724365234375 +62761 0.235870361328125 +62762 0.30535888671875 +62763 0.288299560546875 +62764 0.38128662109375 +62765 0.345703125 +62766 0.404449462890625 +62767 0.3575439453125 +62768 0.3944091796875 +62769 0.34075927734375 +62770 0.3885498046875 +62771 0.32720947265625 +62772 0.362640380859375 +62773 0.297027587890625 +62774 0.27362060546875 +62775 0.2144775390625 +62776 0.11712646484375 +62777 0.0762939453125 +62778 -0.054901123046875 +62779 -0.073486328125 +62780 -0.19085693359375 +62781 -0.1912841796875 +62782 -0.28570556640625 +62783 -0.27276611328125 +62784 -0.339263916015625 +62785 -0.317718505859375 +62786 -0.3775634765625 +62787 -0.34808349609375 +62788 -0.445709228515625 +62789 -0.401885986328125 +62790 -0.535064697265625 +62791 -0.47210693359375 +62792 -0.629058837890625 +62793 -0.54510498046875 +62794 -0.697601318359375 +62795 -0.59600830078125 +62796 -0.70391845703125 +62797 -0.594268798828125 +62798 -0.6424560546875 +62799 -0.535614013671875 +62800 -0.491241455078125 +62801 -0.4019775390625 +62802 -0.265716552734375 +62803 -0.206695556640625 +62804 -0.023712158203125 +62805 0.001373291015625 +62806 0.201751708984375 +62807 0.1942138671875 +62808 0.375823974609375 +62809 0.3424072265625 +62810 0.485076904296875 +62811 0.43463134765625 +62812 0.56884765625 +62813 0.503997802734375 +62814 0.634765625 +62815 0.556976318359375 +62816 0.63763427734375 +62817 0.555755615234375 +62818 0.5660400390625 +62819 0.490966796875 +62820 0.4720458984375 +62821 0.406646728515625 +62822 0.40692138671875 +62823 0.346160888671875 +62824 0.3778076171875 +62825 0.31585693359375 +62826 0.376953125 +62827 0.309539794921875 +62828 0.371978759765625 +62829 0.30029296875 +62830 0.313140869140625 +62831 0.246612548828125 +62832 0.184417724609375 +62833 0.135223388671875 +62834 0.011199951171875 +62835 -0.0123291015625 +62836 -0.171051025390625 +62837 -0.16619873046875 +62838 -0.33740234375 +62839 -0.305450439453125 +62840 -0.47198486328125 +62841 -0.41680908203125 +62842 -0.560394287109375 +62843 -0.48834228515625 +62844 -0.58056640625 +62845 -0.501678466796875 +62846 -0.54754638671875 +62847 -0.46966552734375 +62848 -0.508575439453125 +62849 -0.4322509765625 +62850 -0.459503173828125 +62851 -0.386199951171875 +62852 -0.394378662109375 +62853 -0.326812744140625 +62854 -0.35260009765625 +62855 -0.28741455078125 +62856 -0.31170654296875 +62857 -0.249359130859375 +62858 -0.197418212890625 +62859 -0.150421142578125 +62860 -0.007965087890625 +62861 0.0107421875 +62862 0.207489013671875 +62863 0.192718505859375 +62864 0.409210205078125 +62865 0.362091064453125 +62866 0.57208251953125 +62867 0.497802734375 +62868 0.66595458984375 +62869 0.57464599609375 +62870 0.65875244140625 +62871 0.5657958984375 +62872 0.56744384765625 +62873 0.485687255859375 +62874 0.431396484375 +62875 0.36761474609375 +62876 0.29443359375 +62877 0.24859619140625 +62878 0.182464599609375 +62879 0.150634765625 +62880 0.06365966796875 +62881 0.04718017578125 +62882 -0.075958251953125 +62883 -0.07330322265625 +62884 -0.189422607421875 +62885 -0.17120361328125 +62886 -0.271942138671875 +62887 -0.24237060546875 +62888 -0.342529296875 +62889 -0.30267333984375 +62890 -0.364166259765625 +62891 -0.321014404296875 +62892 -0.327239990234375 +62893 -0.28936767578125 +62894 -0.2769775390625 +62895 -0.245758056640625 +62896 -0.253692626953125 +62897 -0.224151611328125 +62898 -0.24365234375 +62899 -0.213104248046875 +62900 -0.1983642578125 +62901 -0.172088623046875 +62902 -0.116241455078125 +62903 -0.09991455078125 +62904 -0.036834716796875 +62905 -0.029937744140625 +62906 0.034881591796875 +62907 0.033416748046875 +62908 0.09124755859375 +62909 0.083526611328125 +62910 0.10888671875 +62911 0.100677490234375 +62912 0.125518798828125 +62913 0.116424560546875 +62914 0.15771484375 +62915 0.14459228515625 +62916 0.17828369140625 +62917 0.16229248046875 +62918 0.17108154296875 +62919 0.15594482421875 +62920 0.129974365234375 +62921 0.120452880859375 +62922 0.082427978515625 +62923 0.0789794921875 +62924 0.027679443359375 +62925 0.030975341796875 +62926 -0.065643310546875 +62927 -0.049774169921875 +62928 -0.15936279296875 +62929 -0.131072998046875 +62930 -0.21307373046875 +62931 -0.1788330078125 +62932 -0.234649658203125 +62933 -0.19952392578125 +62934 -0.2001953125 +62935 -0.172943115234375 +62936 -0.119171142578125 +62937 -0.106903076171875 +62938 -0.024749755859375 +62939 -0.0291748046875 +62940 0.085784912109375 +62941 0.062591552734375 +62942 0.178131103515625 +62943 0.139617919921875 +62944 0.215576171875 +62945 0.171112060546875 +62946 0.211456298828125 +62947 0.168212890625 +62948 0.17523193359375 +62949 0.13885498046875 +62950 0.128753662109375 +62951 0.101318359375 +62952 0.1019287109375 +62953 0.080596923828125 +62954 0.0743408203125 +62955 0.059478759765625 +62956 0.04327392578125 +62957 0.035552978515625 +62958 0.038177490234375 +62959 0.033416748046875 +62960 0.076263427734375 +62961 0.067413330078125 +62962 0.14105224609375 +62963 0.12359619140625 +62964 0.186431884765625 +62965 0.16314697265625 +62966 0.188812255859375 +62967 0.166168212890625 +62968 0.1390380859375 +62969 0.124908447265625 +62970 0.041778564453125 +62971 0.043304443359375 +62972 -0.079437255859375 +62973 -0.058837890625 +62974 -0.219390869140625 +62975 -0.177154541015625 +62976 -0.367828369140625 +62977 -0.303253173828125 +62978 -0.494873046875 +62979 -0.412445068359375 +62980 -0.556243896484375 +62981 -0.466522216796875 +62982 -0.508697509765625 +62983 -0.427398681640625 +62984 -0.3756103515625 +62985 -0.315032958984375 +62986 -0.218902587890625 +62987 -0.1829833984375 +62988 -0.063751220703125 +62989 -0.05279541015625 +62990 0.091552734375 +62991 0.07745361328125 +62992 0.23602294921875 +62993 0.19854736328125 +62994 0.342987060546875 +62995 0.28753662109375 +62996 0.39520263671875 +62997 0.329620361328125 +62998 0.389373779296875 +62999 0.322113037109375 +63000 0.324249267578125 +63001 0.264007568359375 +63002 0.224090576171875 +63003 0.176483154296875 +63004 0.124267578125 +63005 0.090362548828125 +63006 0.037078857421875 +63007 0.0162353515625 +63008 -0.010101318359375 +63009 -0.022125244140625 +63010 -0.019439697265625 +63011 -0.026824951171875 +63012 -0.022796630859375 +63013 -0.02581787109375 +63014 -0.001556396484375 +63015 -0.003143310546875 +63016 0.056304931640625 +63017 0.05145263671875 +63018 0.106719970703125 +63019 0.09930419921875 +63020 0.096893310546875 +63021 0.09417724609375 +63022 0.042694091796875 +63023 0.04974365234375 +63024 -0.018035888671875 +63025 -0.00115966796875 +63026 -0.07586669921875 +63027 -0.05035400390625 +63028 -0.11944580078125 +63029 -0.0880126953125 +63030 -0.15972900390625 +63031 -0.12371826171875 +63032 -0.202606201171875 +63033 -0.16253662109375 +63034 -0.24859619140625 +63035 -0.20477294921875 +63036 -0.30517578125 +63037 -0.256805419921875 +63038 -0.36212158203125 +63039 -0.3095703125 +63040 -0.39141845703125 +63041 -0.338470458984375 +63042 -0.35528564453125 +63043 -0.31036376953125 +63044 -0.249969482421875 +63045 -0.2218017578125 +63046 -0.092864990234375 +63047 -0.08782958984375 +63048 0.08905029296875 +63049 0.0682373046875 +63050 0.2352294921875 +63051 0.1937255859375 +63052 0.318817138671875 +63053 0.26531982421875 +63054 0.358642578125 +63055 0.299468994140625 +63056 0.347747802734375 +63057 0.290130615234375 +63058 0.28564453125 +63059 0.23687744140625 +63060 0.223175048828125 +63061 0.183929443359375 +63062 0.196746826171875 +63063 0.162933349609375 +63064 0.179840087890625 +63065 0.150665283203125 +63066 0.155548095703125 +63067 0.132232666015625 +63068 0.151214599609375 +63069 0.131317138671875 +63070 0.156951904296875 +63071 0.13916015625 +63072 0.13177490234375 +63073 0.119842529296875 +63074 0.100799560546875 +63075 0.095123291015625 +63076 0.087127685546875 +63077 0.08502197265625 +63078 0.05487060546875 +63079 0.05816650390625 +63080 -0.009002685546875 +63081 0.00311279296875 +63082 -0.10400390625 +63083 -0.079681396484375 +63084 -0.229400634765625 +63085 -0.1895751953125 +63086 -0.35552978515625 +63087 -0.3006591796875 +63088 -0.441925048828125 +63089 -0.3775634765625 +63090 -0.473846435546875 +63091 -0.4073486328125 +63092 -0.464813232421875 +63093 -0.40167236328125 +63094 -0.419097900390625 +63095 -0.3641357421875 +63096 -0.334320068359375 +63097 -0.29254150390625 +63098 -0.227935791015625 +63099 -0.201934814453125 +63100 -0.12347412109375 +63101 -0.112762451171875 +63102 -0.02764892578125 +63103 -0.030792236328125 +63104 0.077667236328125 +63105 0.05987548828125 +63106 0.2132568359375 +63107 0.177398681640625 +63108 0.38885498046875 +63109 0.330291748046875 +63110 0.582794189453125 +63111 0.499664306640625 +63112 0.734039306640625 +63113 0.63226318359375 +63114 0.800140380859375 +63115 0.6910400390625 +63116 0.7783203125 +63117 0.6734619140625 +63118 0.6651611328125 +63119 0.57647705078125 +63120 0.45965576171875 +63121 0.399139404296875 +63122 0.199188232421875 +63123 0.173919677734375 +63124 -0.050689697265625 +63125 -0.042144775390625 +63126 -0.23297119140625 +63127 -0.19940185546875 +63128 -0.33013916015625 +63129 -0.28271484375 +63130 -0.368408203125 +63131 -0.31500244140625 +63132 -0.378936767578125 +63133 -0.323455810546875 +63134 -0.376983642578125 +63135 -0.3214111328125 +63136 -0.37969970703125 +63137 -0.3238525390625 +63138 -0.391510009765625 +63139 -0.3345947265625 +63140 -0.385345458984375 +63141 -0.33001708984375 +63142 -0.3419189453125 +63143 -0.29327392578125 +63144 -0.28289794921875 +63145 -0.2431640625 +63146 -0.251617431640625 +63147 -0.217376708984375 +63148 -0.266143798828125 +63149 -0.231597900390625 +63150 -0.273345947265625 +63151 -0.239410400390625 +63152 -0.216796875 +63153 -0.1915283203125 +63154 -0.128265380859375 +63155 -0.11553955078125 +63156 -0.068145751953125 +63157 -0.064117431640625 +63158 -0.0430908203125 +63159 -0.04296875 +63160 -0.024444580078125 +63161 -0.027069091796875 +63162 0.020721435546875 +63163 0.012298583984375 +63164 0.124481201171875 +63165 0.10308837890625 +63166 0.25787353515625 +63167 0.219970703125 +63168 0.379119873046875 +63169 0.32647705078125 +63170 0.47991943359375 +63171 0.415374755859375 +63172 0.5281982421875 +63173 0.4586181640625 +63174 0.511138916015625 +63175 0.4449462890625 +63176 0.456207275390625 +63177 0.39825439453125 +63178 0.407470703125 +63179 0.356903076171875 +63180 0.383758544921875 +63181 0.3372802734375 +63182 0.35687255859375 +63183 0.314727783203125 +63184 0.31182861328125 +63185 0.276123046875 +63186 0.250885009765625 +63187 0.223388671875 +63188 0.1654052734375 +63189 0.14898681640625 +63190 0.035247802734375 +63191 0.035369873046875 +63192 -0.142059326171875 +63193 -0.119598388671875 +63194 -0.33563232421875 +63195 -0.28900146484375 +63196 -0.5345458984375 +63197 -0.463226318359375 +63198 -0.72186279296875 +63199 -0.627471923828125 +63200 -0.836669921875 +63201 -0.728546142578125 +63202 -0.8326416015625 +63203 -0.72601318359375 +63204 -0.7296142578125 +63205 -0.63714599609375 +63206 -0.582550048828125 +63207 -0.509796142578125 +63208 -0.440093994140625 +63209 -0.386322021484375 +63210 -0.324310302734375 +63211 -0.28594970703125 +63212 -0.20147705078125 +63213 -0.17926025390625 +63214 -0.044647216796875 +63215 -0.042694091796875 +63216 0.103973388671875 +63217 0.086944580078125 +63218 0.202392578125 +63219 0.173004150390625 +63220 0.264495849609375 +63221 0.22760009765625 +63222 0.338897705078125 +63223 0.2930908203125 +63224 0.443817138671875 +63225 0.385284423828125 +63226 0.545074462890625 +63227 0.474365234375 +63228 0.6173095703125 +63229 0.53814697265625 +63230 0.6524658203125 +63231 0.569580078125 +63232 0.66339111328125 +63233 0.5802001953125 +63234 0.6561279296875 +63235 0.57537841796875 +63236 0.606781005859375 +63237 0.5335693359375 +63238 0.501190185546875 +63239 0.441802978515625 +63240 0.352783203125 +63241 0.311981201171875 +63242 0.176544189453125 +63243 0.15740966796875 +63244 -0.034820556640625 +63245 -0.02880859375 +63246 -0.258209228515625 +63247 -0.22607421875 +63248 -0.44244384765625 +63249 -0.388397216796875 +63250 -0.5753173828125 +63251 -0.504974365234375 +63252 -0.65203857421875 +63253 -0.571685791015625 +63254 -0.641632080078125 +63255 -0.560638427734375 +63256 -0.562164306640625 +63257 -0.488250732421875 +63258 -0.458038330078125 +63259 -0.394683837890625 +63260 -0.350555419921875 +63261 -0.299102783203125 +63262 -0.260528564453125 +63263 -0.22021484375 +63264 -0.192108154296875 +63265 -0.16162109375 +63266 -0.141937255859375 +63267 -0.1201171875 +63268 -0.1021728515625 +63269 -0.08837890625 +63270 -0.062896728515625 +63271 -0.057159423828125 +63272 -0.011932373046875 +63273 -0.01519775390625 +63274 0.062835693359375 +63275 0.048614501953125 +63276 0.148712158203125 +63277 0.123046875 +63278 0.241729736328125 +63279 0.204620361328125 +63280 0.34912109375 +63281 0.300018310546875 +63282 0.457305908203125 +63283 0.397064208984375 +63284 0.54388427734375 +63285 0.475494384765625 +63286 0.5728759765625 +63287 0.50274658203125 +63288 0.506591796875 +63289 0.444671630859375 +63290 0.351226806640625 +63291 0.306732177734375 +63292 0.146514892578125 +63293 0.124664306640625 +63294 -0.05523681640625 +63295 -0.05438232421875 +63296 -0.21624755859375 +63297 -0.19647216796875 +63298 -0.334930419921875 +63299 -0.300323486328125 +63300 -0.402984619140625 +63301 -0.358642578125 +63302 -0.4412841796875 +63303 -0.39044189453125 +63304 -0.49578857421875 +63305 -0.437408447265625 +63306 -0.5601806640625 +63307 -0.49395751953125 +63308 -0.600738525390625 +63309 -0.5296630859375 +63310 -0.584228515625 +63311 -0.5145263671875 +63312 -0.47930908203125 +63313 -0.42022705078125 +63314 -0.27935791015625 +63315 -0.24072265625 +63316 -0.0089111328125 +63317 0.001861572265625 +63318 0.268798828125 +63319 0.250518798828125 +63320 0.482818603515625 +63321 0.441253662109375 +63322 0.60369873046875 +63323 0.547637939453125 +63324 0.650421142578125 +63325 0.586944580078125 +63326 0.66400146484375 +63327 0.596435546875 +63328 0.6414794921875 +63329 0.57354736328125 +63330 0.572540283203125 +63331 0.50909423828125 +63332 0.498138427734375 +63333 0.440216064453125 +63334 0.439453125 +63335 0.386138916015625 +63336 0.375518798828125 +63337 0.327972412109375 +63338 0.274505615234375 +63339 0.2369384765625 +63340 0.1087646484375 +63341 0.087982177734375 +63342 -0.099395751953125 +63343 -0.09881591796875 +63344 -0.3182373046875 +63345 -0.2947998046875 +63346 -0.5489501953125 +63347 -0.501190185546875 +63348 -0.7738037109375 +63349 -0.702056884765625 +63350 -0.86383056640625 +63351 -0.84967041015625 +63352 -0.870391845703125 +63353 -0.86102294921875 +63354 -0.86895751953125 +63355 -0.860748291015625 +63356 -0.861053466796875 +63357 -0.85394287109375 +63358 -0.765869140625 +63359 -0.725738525390625 +63360 -0.5301513671875 +63361 -0.516815185546875 +63362 -0.214691162109375 +63363 -0.233642578125 +63364 0.137359619140625 +63365 0.084808349609375 +63366 0.474822998046875 +63367 0.392181396484375 +63368 0.76239013671875 +63369 0.6563720703125 +63370 0.867462158203125 +63371 0.853057861328125 +63372 0.870361328125 +63373 0.86846923828125 +63374 0.86480712890625 +63375 0.870361328125 +63376 0.831817626953125 +63377 0.864654541015625 +63378 0.677581787109375 +63379 0.849761962890625 +63380 0.495880126953125 +63381 0.71282958984375 +63382 0.30767822265625 +63383 0.554840087890625 +63384 0.116180419921875 +63385 0.37847900390625 +63386 -0.110748291015625 +63387 0.1552734375 +63388 -0.381805419921875 +63389 -0.1212158203125 +63390 -0.6572265625 +63391 -0.4129638671875 +63392 -0.857421875 +63393 -0.666839599609375 +63394 -0.870391845703125 +63395 -0.8453369140625 +63396 -0.870391845703125 +63397 -0.864227294921875 +63398 -0.86444091796875 +63399 -0.8690185546875 +63400 -0.85723876953125 +63401 -0.870391845703125 +63402 -0.790008544921875 +63403 -0.868011474609375 +63404 -0.62847900390625 +63405 -0.856781005859375 +63406 -0.3956298828125 +63407 -0.689697265625 +63408 -0.126708984375 +63409 -0.4527587890625 +63410 0.150115966796875 +63411 -0.190032958984375 +63412 0.424041748046875 +63413 0.08746337890625 +63414 0.670623779296875 +63415 0.355499267578125 +63416 0.854522705078125 +63417 0.579681396484375 +63418 0.866485595703125 +63419 0.745025634765625 +63420 0.86920166015625 +63421 0.8389892578125 +63422 0.8653564453125 +63423 0.857208251953125 +63424 0.857147216796875 +63425 0.85736083984375 +63426 0.766845703125 +63427 0.842193603515625 +63428 0.628509521484375 +63429 0.7698974609375 +63430 0.462127685546875 +63431 0.659698486328125 +63432 0.297210693359375 +63433 0.5364990234375 +63434 0.14862060546875 +63435 0.412689208984375 +63436 -0.00537109375 +63437 0.268524169921875 +63438 -0.15753173828125 +63439 0.111236572265625 +63440 -0.31304931640625 +63441 -0.062347412109375 +63442 -0.48876953125 +63443 -0.265289306640625 +63444 -0.6416015625 +63445 -0.455902099609375 +63446 -0.751373291015625 +63447 -0.61285400390625 +63448 -0.84619140625 +63449 -0.758270263671875 +63450 -0.861297607421875 +63451 -0.857330322265625 +63452 -0.863250732421875 +63453 -0.864990234375 +63454 -0.856597900390625 +63455 -0.864044189453125 +63456 -0.7498779296875 +63457 -0.8558349609375 +63458 -0.624542236328125 +63459 -0.779022216796875 +63460 -0.47808837890625 +63461 -0.659759521484375 +63462 -0.253387451171875 +63463 -0.45697021484375 +63464 0.003692626953125 +63465 -0.212432861328125 +63466 0.2257080078125 +63467 0.0118408203125 +63468 0.427154541015625 +63469 0.227294921875 +63470 0.643218994140625 +63471 0.463653564453125 +63472 0.855926513671875 +63473 0.712921142578125 +63474 0.870361328125 +63475 0.862030029296875 +63476 0.870361328125 +63477 0.870361328125 +63478 0.862762451171875 +63479 0.870361328125 +63480 0.79669189453125 +63481 0.86285400390625 +63482 0.595794677734375 +63483 0.78900146484375 +63484 0.362152099609375 +63485 0.602325439453125 +63486 0.1270751953125 +63487 0.398681640625 +63488 -0.086944580078125 +63489 0.19891357421875 +63490 -0.2784423828125 +63491 0.00543212890625 +63492 -0.484832763671875 +63493 -0.215362548828125 +63494 -0.729583740234375 +63495 -0.48388671875 +63496 -0.86688232421875 +63497 -0.755859375 +63498 -0.870391845703125 +63499 -0.867706298828125 +63500 -0.86859130859375 +63501 -0.870391845703125 +63502 -0.86279296875 +63503 -0.868743896484375 +63504 -0.817962646484375 +63505 -0.86029052734375 +63506 -0.6116943359375 +63507 -0.73370361328125 +63508 -0.3128662109375 +63509 -0.464111328125 +63510 0.039398193359375 +63511 -0.134979248046875 +63512 0.422821044921875 +63513 0.23260498046875 +63514 0.805145263671875 +63515 0.607666015625 +63516 0.870361328125 +63517 0.86260986328125 +63518 0.870361328125 +63519 0.870361328125 +63520 0.860015869140625 +63521 0.8677978515625 +63522 0.727935791015625 +63523 0.8558349609375 +63524 0.48114013671875 +63525 0.680572509765625 +63526 0.2059326171875 +63527 0.4537353515625 +63528 -0.06103515625 +63529 0.219512939453125 +63530 -0.29913330078125 +63531 -0.00323486328125 +63532 -0.516204833984375 +63533 -0.221405029296875 +63534 -0.7252197265625 +63535 -0.44586181640625 +63536 -0.85980224609375 +63537 -0.652923583984375 +63538 -0.870391845703125 +63539 -0.8131103515625 +63540 -0.870391845703125 +63541 -0.859954833984375 +63542 -0.858062744140625 +63543 -0.8582763671875 +63544 -0.673004150390625 +63545 -0.7730712890625 +63546 -0.42694091796875 +63547 -0.617034912109375 +63548 -0.2100830078125 +63549 -0.474365234375 +63550 -0.0362548828125 +63551 -0.3551025390625 +63552 0.10943603515625 +63553 -0.243408203125 +63554 0.23516845703125 +63555 -0.13079833984375 +63556 0.373687744140625 +63557 0.0130615234375 +63558 0.517791748046875 +63559 0.180084228515625 +63560 0.602783203125 +63561 0.307464599609375 +63562 0.635711669921875 +63563 0.39874267578125 +63564 0.655181884765625 +63565 0.486358642578125 +63566 0.65948486328125 +63567 0.564697265625 +63568 0.651275634765625 +63569 0.632049560546875 +63570 0.61846923828125 +63571 0.6729736328125 +63572 0.53753662109375 +63573 0.661651611328125 +63574 0.404144287109375 +63575 0.590728759765625 +63576 0.22186279296875 +63577 0.460906982421875 +63578 0.003997802734375 +63579 0.282806396484375 +63580 -0.22100830078125 +63581 0.08203125 +63582 -0.42449951171875 +63583 -0.114654541015625 +63584 -0.579833984375 +63585 -0.281494140625 +63586 -0.641876220703125 +63587 -0.374603271484375 +63588 -0.6177978515625 +63589 -0.3984375 +63590 -0.575531005859375 +63591 -0.413726806640625 +63592 -0.526336669921875 +63593 -0.427764892578125 +63594 -0.42645263671875 +63595 -0.39617919921875 +63596 -0.2581787109375 +63597 -0.2989501953125 +63598 -0.068695068359375 +63599 -0.176971435546875 +63600 0.09222412109375 +63601 -0.073944091796875 +63602 0.232147216796875 +63603 0.01953125 +63604 0.3509521484375 +63605 0.1051025390625 +63606 0.410064697265625 +63607 0.147705078125 +63608 0.372955322265625 +63609 0.11346435546875 +63610 0.2554931640625 +63611 0.016845703125 +63612 0.10711669921875 +63613 -0.096923828125 +63614 -0.052886962890625 +63615 -0.2115478515625 +63616 -0.186279296875 +63617 -0.293426513671875 +63618 -0.23291015625 +63619 -0.288848876953125 +63620 -0.209442138671875 +63621 -0.2161865234375 +63622 -0.174163818359375 +63623 -0.1328125 +63624 -0.126739501953125 +63625 -0.0411376953125 +63626 -0.048126220703125 +63627 0.0740966796875 +63628 0.0426025390625 +63629 0.192962646484375 +63630 0.10748291015625 +63631 0.2783203125 +63632 0.1409912109375 +63633 0.32391357421875 +63634 0.19708251953125 +63635 0.3797607421875 +63636 0.273651123046875 +63637 0.444061279296875 +63638 0.31768798828125 +63639 0.4678955078125 +63640 0.341094970703125 +63641 0.463623046875 +63642 0.368011474609375 +63643 0.455535888671875 +63644 0.37249755859375 +63645 0.421356201171875 +63646 0.30072021484375 +63647 0.31292724609375 +63648 0.1517333984375 +63649 0.13165283203125 +63650 -0.01470947265625 +63651 -0.064208984375 +63652 -0.1883544921875 +63653 -0.262908935546875 +63654 -0.372711181640625 +63655 -0.46588134765625 +63656 -0.51397705078125 +63657 -0.62127685546875 +63658 -0.57177734375 +63659 -0.690216064453125 +63660 -0.53948974609375 +63661 -0.66595458984375 +63662 -0.43511962890625 +63663 -0.565277099609375 +63664 -0.2962646484375 +63665 -0.423828125 +63666 -0.161102294921875 +63667 -0.278167724609375 +63668 -0.0435791015625 +63669 -0.142608642578125 +63670 0.060394287109375 +63671 -0.014892578125 +63672 0.13665771484375 +63673 0.08990478515625 +63674 0.170135498046875 +63675 0.155792236328125 +63676 0.16552734375 +63677 0.18524169921875 +63678 0.15728759765625 +63679 0.208648681640625 +63680 0.150787353515625 +63681 0.229461669921875 +63682 0.12200927734375 +63683 0.223846435546875 +63684 0.080108642578125 +63685 0.199371337890625 +63686 0.05126953125 +63687 0.179901123046875 +63688 0.062896728515625 +63689 0.19091796875 +63690 0.09271240234375 +63691 0.21173095703125 +63692 0.092987060546875 +63693 0.19830322265625 +63694 0.07855224609375 +63695 0.165435791015625 +63696 0.06427001953125 +63697 0.128265380859375 +63698 0.0347900390625 +63699 0.07379150390625 +63700 -0.01171875 +63701 0.001861572265625 +63702 -0.056060791015625 +63703 -0.06793212890625 +63704 -0.055511474609375 +63705 -0.09405517578125 +63706 -0.010467529296875 +63707 -0.075439453125 +63708 0.02508544921875 +63709 -0.0614013671875 +63710 0.025665283203125 +63711 -0.074859619140625 +63712 0.017333984375 +63713 -0.0908203125 +63714 0.00189208984375 +63715 -0.107330322265625 +63716 -0.03173828125 +63717 -0.134857177734375 +63718 -0.071502685546875 +63719 -0.16253662109375 +63720 -0.13543701171875 +63721 -0.2078857421875 +63722 -0.219970703125 +63723 -0.268524169921875 +63724 -0.300506591796875 +63725 -0.322540283203125 +63726 -0.376312255859375 +63727 -0.370513916015625 +63728 -0.416107177734375 +63729 -0.384429931640625 +63730 -0.371124267578125 +63731 -0.319915771484375 +63732 -0.242279052734375 +63733 -0.17901611328125 +63734 -0.069732666015625 +63735 -0.000396728515625 +63736 0.125640869140625 +63737 0.195526123046875 +63738 0.31268310546875 +63739 0.3790283203125 +63740 0.45501708984375 +63741 0.5157470703125 +63742 0.554779052734375 +63743 0.60760498046875 +63744 0.61065673828125 +63745 0.653839111328125 +63746 0.610931396484375 +63747 0.643829345703125 +63748 0.531463623046875 +63749 0.5550537109375 +63750 0.3883056640625 +63751 0.403472900390625 +63752 0.23468017578125 +63753 0.24053955078125 +63754 0.095245361328125 +63755 0.09063720703125 +63756 -0.00396728515625 +63757 -0.02056884765625 +63758 -0.04852294921875 +63759 -0.0784912109375 +63760 -0.055145263671875 +63761 -0.098175048828125 +63762 -0.0758056640625 +63763 -0.128387451171875 +63764 -0.138702392578125 +63765 -0.19537353515625 +63766 -0.209197998046875 +63767 -0.26593017578125 +63768 -0.289031982421875 +63769 -0.34161376953125 +63770 -0.37884521484375 +63771 -0.42315673828125 +63772 -0.456329345703125 +63773 -0.489654541015625 +63774 -0.51641845703125 +63775 -0.536773681640625 +63776 -0.519287109375 +63777 -0.527313232421875 +63778 -0.458251953125 +63779 -0.45562744140625 +63780 -0.384796142578125 +63781 -0.371429443359375 +63782 -0.323699951171875 +63783 -0.299072265625 +63784 -0.269287109375 +63785 -0.233917236328125 +63786 -0.1951904296875 +63787 -0.151641845703125 +63788 -0.100006103515625 +63789 -0.051513671875 +63790 -0.01055908203125 +63791 0.040496826171875 +63792 0.1033935546875 +63793 0.152801513671875 +63794 0.24908447265625 +63795 0.292144775390625 +63796 0.373199462890625 +63797 0.407958984375 +63798 0.45806884765625 +63799 0.483642578125 +63800 0.511474609375 +63801 0.52691650390625 +63802 0.565399169921875 +63803 0.56866455078125 +63804 0.61138916015625 +63805 0.601409912109375 +63806 0.5897216796875 +63807 0.569091796875 +63808 0.4906005859375 +63809 0.4630126953125 +63810 0.33148193359375 +63811 0.300445556640625 +63812 0.147796630859375 +63813 0.11566162109375 +63814 -0.01873779296875 +63815 -0.05120849609375 +63816 -0.140289306640625 +63817 -0.173248291015625 +63818 -0.191986083984375 +63819 -0.2265625 +63820 -0.184295654296875 +63821 -0.220916748046875 +63822 -0.161834716796875 +63823 -0.198699951171875 +63824 -0.166595458984375 +63825 -0.19989013671875 +63826 -0.19390869140625 +63827 -0.220306396484375 +63828 -0.22442626953125 +63829 -0.241943359375 +63830 -0.279754638671875 +63831 -0.2857666015625 +63832 -0.3389892578125 +63833 -0.332489013671875 +63834 -0.3543701171875 +63835 -0.337249755859375 +63836 -0.348175048828125 +63837 -0.32177734375 +63838 -0.32598876953125 +63839 -0.2918701171875 +63840 -0.2581787109375 +63841 -0.2198486328125 +63842 -0.139801025390625 +63843 -0.101409912109375 +63844 0.014617919921875 +63845 0.049407958984375 +63846 0.144378662109375 +63847 0.174713134765625 +63848 0.221038818359375 +63849 0.247467041015625 +63850 0.27069091796875 +63851 0.292510986328125 +63852 0.294036865234375 +63853 0.31072998046875 +63854 0.311767578125 +63855 0.322021484375 +63856 0.339141845703125 +63857 0.34130859375 +63858 0.360260009765625 +63859 0.35406494140625 +63860 0.360504150390625 +63861 0.3468017578125 +63862 0.308380126953125 +63863 0.289337158203125 +63864 0.18170166015625 +63865 0.160491943359375 +63866 0.0047607421875 +63867 -0.015869140625 +63868 -0.17559814453125 +63869 -0.194244384765625 +63870 -0.3143310546875 +63871 -0.33087158203125 +63872 -0.36785888671875 +63873 -0.383544921875 +63874 -0.36248779296875 +63875 -0.377685546875 +63876 -0.343536376953125 +63877 -0.35723876953125 +63878 -0.3018798828125 +63879 -0.313568115234375 +63880 -0.231414794921875 +63881 -0.240966796875 +63882 -0.117645263671875 +63883 -0.12567138671875 +63884 0.007049560546875 +63885 0.00067138671875 +63886 0.087982177734375 +63887 0.084808349609375 +63888 0.13946533203125 +63889 0.14031982421875 +63890 0.17425537109375 +63891 0.179229736328125 +63892 0.188201904296875 +63893 0.197235107421875 +63894 0.171234130859375 +63895 0.184326171875 +63896 0.118438720703125 +63897 0.135650634765625 +63898 0.05706787109375 +63899 0.07745361328125 +63900 -0.010711669921875 +63901 0.011749267578125 +63902 -0.0914306640625 +63903 -0.067718505859375 +63904 -0.162322998046875 +63905 -0.13873291015625 +63906 -0.194549560546875 +63907 -0.173248291015625 +63908 -0.1492919921875 +63909 -0.133514404296875 +63910 -0.02166748046875 +63911 -0.0145263671875 +63912 0.124053955078125 +63913 0.12176513671875 +63914 0.211151123046875 +63915 0.201385498046875 +63916 0.240447998046875 +63917 0.225372314453125 +63918 0.242218017578125 +63919 0.22320556640625 +63920 0.2257080078125 +63921 0.2041015625 +63922 0.194366455078125 +63923 0.1715087890625 +63924 0.115509033203125 +63925 0.0938720703125 +63926 0.0128173828125 +63927 -0.00579833984375 +63928 -0.053802490234375 +63929 -0.069580078125 +63930 -0.110626220703125 +63931 -0.1229248046875 +63932 -0.199493408203125 +63933 -0.20648193359375 +63934 -0.29437255859375 +63935 -0.29522705078125 +63936 -0.33221435546875 +63937 -0.328277587890625 +63938 -0.27972412109375 +63939 -0.27362060546875 +63940 -0.185333251953125 +63941 -0.1783447265625 +63942 -0.128204345703125 +63943 -0.119293212890625 +63944 -0.115692138671875 +63945 -0.103759765625 +63946 -0.116455078125 +63947 -0.10162353515625 +63948 -0.105926513671875 +63949 -0.0892333984375 +63950 -0.053955078125 +63951 -0.03753662109375 +63952 0.048797607421875 +63953 0.06243896484375 +63954 0.157318115234375 +63955 0.16717529296875 +63956 0.212005615234375 +63957 0.218994140625 +63958 0.218475341796875 +63959 0.223388671875 +63960 0.23724365234375 +63961 0.239105224609375 +63962 0.30535888671875 +63963 0.302154541015625 +63964 0.38128662109375 +63965 0.372467041015625 +63966 0.404449462890625 +63967 0.3916015625 +63968 0.3944091796875 +63969 0.378662109375 +63970 0.3885498046875 +63971 0.370025634765625 +63972 0.362640380859375 +63973 0.3424072265625 +63974 0.27362060546875 +63975 0.2542724609375 +63976 0.11712646484375 +63977 0.101470947265625 +63978 -0.054901123046875 +63979 -0.065673828125 +63980 -0.19085693359375 +63981 -0.197174072265625 +63982 -0.28570556640625 +63983 -0.2882080078125 +63984 -0.339263916015625 +63985 -0.33868408203125 +63986 -0.3775634765625 +63987 -0.37384033203125 +63988 -0.445709228515625 +63989 -0.437469482421875 +63990 -0.535064697265625 +63991 -0.521392822265625 +63992 -0.629058837890625 +63993 -0.609710693359375 +63994 -0.697601318359375 +63995 -0.673431396484375 +63996 -0.70391845703125 +63997 -0.6771240234375 +63998 -0.6424560546875 +63999 -0.615509033203125 +64000 -0.491241455078125 +64001 -0.466949462890625 +64002 -0.265716552734375 +64003 -0.246307373046875 +64004 -0.023712158203125 +64005 -0.010406494140625 +64006 0.201751708984375 +64007 0.208251953125 +64008 0.375823974609375 +64009 0.37530517578125 +64010 0.485076904296875 +64011 0.477813720703125 +64012 0.56884765625 +64013 0.555511474609375 +64014 0.634765625 +64015 0.61639404296875 +64016 0.63763427734375 +64017 0.615509033203125 +64018 0.5660400390625 +64019 0.54156494140625 +64020 0.4720458984375 +64021 0.44671630859375 +64022 0.40692138671875 +64023 0.382232666015625 +64024 0.3778076171875 +64025 0.35516357421875 +64026 0.376953125 +64027 0.357574462890625 +64028 0.371978759765625 +64029 0.35687255859375 +64030 0.313140869140625 +64031 0.30303955078125 +64032 0.184417724609375 +64033 0.17974853515625 +64034 0.011199951171875 +64035 0.012054443359375 +64036 -0.171051025390625 +64037 -0.164886474609375 +64038 -0.33740234375 +64039 -0.326416015625 +64040 -0.47198486328125 +64041 -0.456939697265625 +64042 -0.560394287109375 +64043 -0.542236328125 +64044 -0.58056640625 +64045 -0.560394287109375 +64046 -0.54754638671875 +64047 -0.526519775390625 +64048 -0.508575439453125 +64049 -0.48785400390625 +64050 -0.459503173828125 +64051 -0.440216064453125 +64052 -0.394378662109375 +64053 -0.377532958984375 +64054 -0.35260009765625 +64055 -0.33905029296875 +64056 -0.31170654296875 +64057 -0.302093505859375 +64058 -0.197418212890625 +64059 -0.192169189453125 +64060 -0.007965087890625 +64061 -0.007232666015625 +64062 0.207489013671875 +64063 0.203765869140625 +64064 0.409210205078125 +64065 0.4013671875 +64066 0.57208251953125 +64067 0.560638427734375 +64068 0.66595458984375 +64069 0.651641845703125 +64070 0.65875244140625 +64071 0.642425537109375 +64072 0.56744384765625 +64073 0.550048828125 +64074 0.431396484375 +64075 0.413909912109375 +64076 0.29443359375 +64077 0.27783203125 +64078 0.182464599609375 +64079 0.167633056640625 +64080 0.06365966796875 +64081 0.051361083984375 +64082 -0.075958251953125 +64083 -0.08514404296875 +64084 -0.189422607421875 +64085 -0.195068359375 +64086 -0.271942138671875 +64087 -0.273834228515625 +64088 -0.342529296875 +64089 -0.340667724609375 +64090 -0.364166259765625 +64091 -0.3587646484375 +64092 -0.327239990234375 +64093 -0.3187255859375 +64094 -0.2769775390625 +64095 -0.265899658203125 +64096 -0.253692626953125 +64097 -0.240753173828125 +64098 -0.24365234375 +64099 -0.2296142578125 +64100 -0.1983642578125 +64101 -0.184051513671875 +64102 -0.116241455078125 +64103 -0.102447509765625 +64104 -0.036834716796875 +64105 -0.0242919921875 +64106 0.034881591796875 +64107 0.0455322265625 +64108 0.09124755859375 +64109 0.099456787109375 +64110 0.10888671875 +64111 0.114288330078125 +64112 0.125518798828125 +64113 0.127899169921875 +64114 0.15771484375 +64115 0.15704345703125 +64116 0.17828369140625 +64117 0.1746826171875 +64118 0.17108154296875 +64119 0.164825439453125 +64120 0.129974365234375 +64121 0.121490478515625 +64122 0.082427978515625 +64123 0.07220458984375 +64124 0.027679443359375 +64125 0.016326904296875 +64126 -0.065643310546875 +64127 -0.07745361328125 +64128 -0.15936279296875 +64129 -0.17095947265625 +64130 -0.21307373046875 +64131 -0.22381591796875 +64132 -0.234649658203125 +64133 -0.24395751953125 +64134 -0.2001953125 +64135 -0.20758056640625 +64136 -0.119171142578125 +64137 -0.124298095703125 +64138 -0.024749755859375 +64139 -0.02740478515625 +64140 0.085784912109375 +64141 0.085662841796875 +64142 0.178131103515625 +64143 0.18048095703125 +64144 0.215576171875 +64145 0.220184326171875 +64146 0.211456298828125 +64147 0.217987060546875 +64148 0.17523193359375 +64149 0.183258056640625 +64150 0.128753662109375 +64151 0.137786865234375 +64152 0.1019287109375 +64153 0.1114501953125 +64154 0.0743408203125 +64155 0.083831787109375 +64156 0.04327392578125 +64157 0.05224609375 +64158 0.038177490234375 +64159 0.046173095703125 +64160 0.076263427734375 +64161 0.0828857421875 +64162 0.14105224609375 +64163 0.145965576171875 +64164 0.186431884765625 +64165 0.189422607421875 +64166 0.188812255859375 +64167 0.18975830078125 +64168 0.1390380859375 +64169 0.137939453125 +64170 0.041778564453125 +64171 0.03875732421875 +64172 -0.079437255859375 +64173 -0.08416748046875 +64174 -0.219390869140625 +64175 -0.22552490234375 +64176 -0.367828369140625 +64177 -0.375 +64178 -0.494873046875 +64179 -0.502685546875 +64180 -0.556243896484375 +64181 -0.56427001953125 +64182 -0.508697509765625 +64183 -0.516510009765625 +64184 -0.3756103515625 +64185 -0.382781982421875 +64186 -0.218902587890625 +64187 -0.225067138671875 +64188 -0.063751220703125 +64189 -0.068603515625 +64190 0.091552734375 +64191 0.088226318359375 +64192 0.23602294921875 +64193 0.234375 +64194 0.342987060546875 +64195 0.343048095703125 +64196 0.39520263671875 +64197 0.39691162109375 +64198 0.389373779296875 +64199 0.392578125 +64200 0.324249267578125 +64201 0.3287353515625 +64202 0.224090576171875 +64203 0.229583740234375 +64204 0.124267578125 +64205 0.13043212890625 +64206 0.037078857421875 +64207 0.043548583984375 +64208 -0.010101318359375 +64209 -0.003692626953125 +64210 -0.019439697265625 +64211 -0.013458251953125 +64212 -0.022796630859375 +64213 -0.017547607421875 +64214 -0.001556396484375 +64215 0.002655029296875 +64216 0.056304931640625 +64217 0.05926513671875 +64218 0.106719970703125 +64219 0.1082763671875 +64220 0.096893310546875 +64221 0.09698486328125 +64222 0.042694091796875 +64223 0.041351318359375 +64224 -0.018035888671875 +64225 -0.02069091796875 +64226 -0.07586669921875 +64227 -0.07965087890625 +64228 -0.11944580078125 +64229 -0.124114990234375 +64230 -0.15972900390625 +64231 -0.165008544921875 +64232 -0.202606201171875 +64233 -0.20819091796875 +64234 -0.24859619140625 +64235 -0.254180908203125 +64236 -0.30517578125 +64237 -0.310455322265625 +64238 -0.36212158203125 +64239 -0.3668212890625 +64240 -0.39141845703125 +64241 -0.395294189453125 +64242 -0.35528564453125 +64243 -0.358154296875 +64244 -0.249969482421875 +64245 -0.251708984375 +64246 -0.092864990234375 +64247 -0.093414306640625 +64248 0.08905029296875 +64249 0.089691162109375 +64250 0.2352294921875 +64251 0.23699951171875 +64252 0.318817138671875 +64253 0.32159423828125 +64254 0.358642578125 +64255 0.36224365234375 +64256 0.348358154296875 +64257 0.351959228515625 +64258 0.288116455078125 +64259 0.29022216796875 +64260 0.227569580078125 +64261 0.22784423828125 +64262 0.201690673828125 +64263 0.20123291015625 +64264 0.184661865234375 +64265 0.183929443359375 +64266 0.1600341796875 +64267 0.159027099609375 +64268 0.15423583984375 +64269 0.1539306640625 +64270 0.157745361328125 +64271 0.158782958984375 +64272 0.1309814453125 +64273 0.13262939453125 +64274 0.098358154296875 +64275 0.10064697265625 +64276 0.082366943359375 +64277 0.08599853515625 +64278 0.0484619140625 +64279 0.0528564453125 +64280 -0.015777587890625 +64281 -0.011749267578125 +64282 -0.1097412109375 +64283 -0.1072998046875 +64284 -0.232635498046875 +64285 -0.233062744140625 +64286 -0.355682373046875 +64287 -0.359344482421875 +64288 -0.439605712890625 +64289 -0.4456787109375 +64290 -0.470184326171875 +64291 -0.47735595703125 +64292 -0.46051025390625 +64293 -0.4678955078125 +64294 -0.414764404296875 +64295 -0.421600341796875 +64296 -0.33074951171875 +64297 -0.33612060546875 +64298 -0.2254638671875 +64299 -0.22894287109375 +64300 -0.121856689453125 +64301 -0.1236572265625 +64302 -0.02655029296875 +64303 -0.027008056640625 +64304 0.077880859375 +64305 0.0791015625 +64306 0.21142578125 +64307 0.21539306640625 +64308 0.383331298828125 +64309 0.391571044921875 +64310 0.57257080078125 +64311 0.5859375 +64312 0.719970703125 +64313 0.7374267578125 +64314 0.784423828125 +64315 0.8035888671875 +64316 0.763214111328125 +64317 0.781646728515625 +64318 0.653045654296875 +64319 0.668182373046875 +64320 0.453033447265625 +64321 0.46221923828125 +64322 0.19940185546875 +64323 0.201171875 +64324 -0.0443115234375 +64325 -0.04937744140625 +64326 -0.222808837890625 +64327 -0.232391357421875 +64328 -0.319000244140625 +64329 -0.330322265625 +64330 -0.358123779296875 +64331 -0.36932373046875 +64332 -0.3702392578125 +64333 -0.380523681640625 +64334 -0.370025634765625 +64335 -0.379150390625 +64336 -0.3740234375 +64337 -0.382293701171875 +64338 -0.38641357421875 +64339 -0.394378662109375 +64340 -0.3809814453125 +64341 -0.388336181640625 +64342 -0.33905029296875 +64343 -0.344879150390625 +64344 -0.281585693359375 +64345 -0.28564453125 +64346 -0.25054931640625 +64347 -0.2540283203125 +64348 -0.263458251953125 +64349 -0.268096923828125 +64350 -0.26898193359375 +64351 -0.274749755859375 +64352 -0.212615966796875 +64353 -0.21759033203125 +64354 -0.125152587890625 +64355 -0.12841796875 +64356 -0.065216064453125 +64357 -0.06768798828125 +64358 -0.039306640625 +64359 -0.04205322265625 +64360 -0.019775390625 +64361 -0.02288818359375 +64362 0.02520751953125 +64363 0.022705078125 +64364 0.1265869140625 +64365 0.12677001953125 +64366 0.25628662109375 +64367 0.260345458984375 +64368 0.37384033203125 +64369 0.381622314453125 +64370 0.471221923828125 +64371 0.482330322265625 +64372 0.51739501953125 +64373 0.5303955078125 +64374 0.500030517578125 +64375 0.513031005859375 +64376 0.44573974609375 +64377 0.45770263671875 +64378 0.39727783203125 +64379 0.40850830078125 +64380 0.3729248046875 +64381 0.384307861328125 +64382 0.345458984375 +64383 0.356903076171875 +64384 0.300445556640625 +64385 0.311370849609375 +64386 0.240142822265625 +64387 0.249969482421875 +64388 0.15625 +64389 0.164093017578125 +64390 0.02935791015625 +64391 0.03363037109375 +64392 -0.14288330078125 +64393 -0.143890380859375 +64394 -0.33056640625 +64395 -0.33758544921875 +64396 -0.5230712890625 +64397 -0.5364990234375 +64398 -0.704010009765625 +64399 -0.723724365234375 +64400 -0.81451416015625 +64401 -0.83831787109375 +64402 -0.80975341796875 +64403 -0.834014892578125 +64404 -0.708984375 +64405 -0.73065185546875 +64406 -0.565460205078125 +64407 -0.58319091796875 +64408 -0.42633056640625 +64409 -0.4403076171875 +64410 -0.31304931640625 +64411 -0.3240966796875 +64412 -0.19305419921875 +64413 -0.20086669921875 +64414 -0.040252685546875 +64415 -0.043670654296875 +64416 0.10443115234375 +64417 0.105255126953125 +64418 0.200286865234375 +64419 0.20391845703125 +64420 0.2607421875 +64421 0.26617431640625 +64422 0.332855224609375 +64423 0.34063720703125 +64424 0.434234619140625 +64425 0.44549560546875 +64426 0.531829833984375 +64427 0.546600341796875 +64428 0.601104736328125 +64429 0.61859130859375 +64430 0.63433837890625 +64431 0.6534423828125 +64432 0.64398193359375 +64433 0.664031982421875 +64434 0.635955810546875 +64435 0.656402587890625 +64436 0.587158203125 +64437 0.606689453125 +64438 0.48394775390625 +64439 0.500732421875 +64440 0.339385986328125 +64441 0.35198974609375 +64442 0.16802978515625 +64443 0.17547607421875 +64444 -0.037139892578125 +64445 -0.036102294921875 +64446 -0.253753662109375 +64447 -0.259613037109375 +64448 -0.4322509765625 +64449 -0.443878173828125 +64450 -0.560791015625 +64451 -0.576690673828125 +64452 -0.634765625 +64453 -0.653289794921875 +64454 -0.624237060546875 +64455 -0.6427001953125 +64456 -0.54669189453125 +64457 -0.563018798828125 +64458 -0.445159912109375 +64459 -0.458648681640625 +64460 -0.34027099609375 +64461 -0.35089111328125 +64462 -0.25225830078125 +64463 -0.26055908203125 +64464 -0.1851806640625 +64465 -0.191864013671875 +64466 -0.135833740234375 +64467 -0.141448974609375 +64468 -0.0966796875 +64469 -0.101470947265625 +64470 -0.058135986328125 +64471 -0.06201171875 +64472 -0.0084228515625 +64473 -0.010894775390625 +64474 0.06414794921875 +64475 0.06396484375 +64476 0.147308349609375 +64477 0.149871826171875 +64478 0.2371826171875 +64479 0.24285888671875 +64480 0.340789794921875 +64481 0.35015869140625 +64482 0.445037841796875 +64483 0.458221435546875 +64484 0.52825927734375 +64485 0.54461669921875 +64486 0.5556640625 +64487 0.573394775390625 +64488 0.49078369140625 +64489 0.506866455078125 +64490 0.339691162109375 +64491 0.35125732421875 +64492 0.140869140625 +64493 0.146331787109375 +64494 -0.05499267578125 +64495 -0.05560302734375 +64496 -0.211334228515625 +64497 -0.216766357421875 +64498 -0.326568603515625 +64499 -0.3355712890625 +64500 -0.392669677734375 +64501 -0.403717041015625 +64502 -0.4298095703125 +64503 -0.442047119140625 +64504 -0.482513427734375 +64505 -0.49652099609375 +64506 -0.54461669921875 +64507 -0.560821533203125 +64508 -0.583526611328125 +64509 -0.60125732421875 +64510 -0.56707763671875 +64511 -0.584625244140625 +64512 -0.46527099609375 +64513 -0.47955322265625 +64514 -0.272430419921875 +64515 -0.279449462890625 +64516 -0.012481689453125 +64517 -0.00885009765625 +64518 0.254608154296875 +64519 0.26898193359375 +64520 0.461822509765625 +64521 0.483123779296875 +64522 0.581085205078125 +64523 0.6041259765625 +64524 0.62969970703125 +64525 0.65093994140625 +64526 0.645782470703125 +64527 0.664581298828125 +64528 0.62640380859375 +64529 0.64208984375 +64530 0.5618896484375 +64531 0.573150634765625 +64532 0.490631103515625 +64533 0.49871826171875 +64534 0.4326171875 +64535 0.439971923828125 +64536 0.36846923828125 +64537 0.375946044921875 +64538 0.268707275390625 +64539 0.274810791015625 +64540 0.1077880859375 +64541 0.10894775390625 +64542 -0.09307861328125 +64543 -0.099365234375 +64544 -0.30377197265625 +64545 -0.318359375 +64546 -0.525115966796875 +64547 -0.549224853515625 +64548 -0.74017333984375 +64549 -0.77423095703125 +64550 -0.859375 +64551 -0.8638916015625 +64552 -0.8671875 +64553 -0.870391845703125 +64554 -0.867279052734375 +64555 -0.868896484375 +64556 -0.8609619140625 +64557 -0.860931396484375 +64558 -0.780975341796875 +64559 -0.764373779296875 +64560 -0.563140869140625 +64561 -0.528350830078125 +64562 -0.2669677734375 +64563 -0.21270751953125 +64564 0.0670166015625 +64565 0.139404296875 +64566 0.39056396484375 +64567 0.476806640625 +64568 0.670135498046875 +64569 0.764190673828125 +64570 0.857269287109375 +64571 0.86761474609375 +64572 0.870361328125 +64573 0.870361328125 +64574 0.870361328125 +64575 0.8646240234375 +64576 0.862762451171875 +64577 0.828948974609375 +64578 0.81683349609375 +64579 0.673553466796875 +64580 0.66668701171875 +64581 0.490966796875 +64582 0.49884033203125 +64583 0.30218505859375 +64584 0.316192626953125 +64585 0.11041259765625 +64586 0.08917236328125 +64587 -0.116455078125 +64588 -0.189239501953125 +64589 -0.38714599609375 +64590 -0.480194091796875 +64591 -0.66192626953125 +64592 -0.729400634765625 +64593 -0.85784912109375 +64594 -0.859344482421875 +64595 -0.870391845703125 +64596 -0.868682861328125 +64597 -0.870391845703125 +64598 -0.870391845703125 +64599 -0.86444091796875 +64600 -0.870025634765625 +64601 -0.85723876953125 +64602 -0.8660888671875 +64603 -0.790008544921875 +64604 -0.84332275390625 +64605 -0.62847900390625 +64606 -0.644500732421875 +64607 -0.3956298828125 +64608 -0.39642333984375 +64609 -0.126708984375 +64610 -0.12567138671875 +64611 0.150115966796875 +64612 0.15655517578125 +64613 0.424041748046875 +64614 0.425537109375 +64615 0.670623779296875 +64616 0.64617919921875 +64617 0.854522705078125 +64618 0.8037109375 +64619 0.866485595703125 +64620 0.85791015625 +64621 0.86920166015625 +64622 0.860809326171875 +64623 0.8653564453125 +64624 0.85931396484375 +64625 0.857147216796875 +64626 0.84466552734375 +64627 0.766845703125 +64628 0.7576904296875 +64629 0.628509521484375 +64630 0.634002685546875 +64631 0.462127685546875 +64632 0.499786376953125 +64633 0.297210693359375 +64634 0.3681640625 +64635 0.14862060546875 +64636 0.218780517578125 +64637 -0.00537109375 +64638 0.05902099609375 +64639 -0.15753173828125 +64640 -0.114654541015625 +64641 -0.31304931640625 +64642 -0.316162109375 +64643 -0.48876953125 +64644 -0.50286865234375 +64645 -0.6416015625 +64646 -0.6533203125 +64647 -0.751373291015625 +64648 -0.7911376953125 +64649 -0.84619140625 +64650 -0.8599853515625 +64651 -0.861297607421875 +64652 -0.866607666015625 +64653 -0.863250732421875 +64654 -0.864501953125 +64655 -0.856597900390625 +64656 -0.855072021484375 +64657 -0.7498779296875 +64658 -0.76239013671875 +64659 -0.624542236328125 +64660 -0.6351318359375 +64661 -0.47808837890625 +64662 -0.424102783203125 +64663 -0.253387451171875 +64664 -0.17254638671875 +64665 0.003692626953125 +64666 0.05548095703125 +64667 0.2257080078125 +64668 0.27215576171875 +64669 0.427154541015625 +64670 0.5086669921875 +64671 0.643218994140625 +64672 0.757232666015625 +64673 0.855926513671875 +64674 0.866546630859375 +64675 0.870361328125 +64676 0.870361328125 +64677 0.870361328125 +64678 0.8665771484375 +64679 0.862762451171875 +64680 0.855560302734375 +64681 0.79669189453125 +64682 0.693359375 +64683 0.595794677734375 +64684 0.483917236328125 +64685 0.362152099609375 +64686 0.264984130859375 +64687 0.1270751953125 +64688 0.0577392578125 +64689 -0.086944580078125 +64690 -0.13580322265625 +64691 -0.2784423828125 +64692 -0.34967041015625 +64693 -0.484832763671875 +64694 -0.60455322265625 +64695 -0.729583740234375 +64696 -0.854766845703125 +64697 -0.86688232421875 +64698 -0.870391845703125 +64699 -0.870391845703125 +64700 -0.870391845703125 +64701 -0.86859130859375 +64702 -0.86614990234375 +64703 -0.86279296875 +64704 -0.855255126953125 +64705 -0.817962646484375 +64706 -0.668487548828125 +64707 -0.6116943359375 +64708 -0.38372802734375 +64709 -0.3128662109375 +64710 -0.044097900390625 +64711 0.039398193359375 +64712 0.328857421875 +64713 0.422821044921875 +64714 0.704010009765625 +64715 0.805145263671875 +64716 0.870361328125 +64717 0.870361328125 +64718 0.870361328125 +64719 0.870361328125 +64720 0.86029052734375 +64721 0.860015869140625 +64722 0.73516845703125 +64723 0.727935791015625 +64724 0.494720458984375 +64725 0.48114013671875 +64726 0.22552490234375 +64727 0.2059326171875 +64728 -0.037384033203125 +64729 -0.06103515625 +64730 -0.27398681640625 +64731 -0.29913330078125 +64732 -0.490875244140625 +64733 -0.516204833984375 +64734 -0.69940185546875 +64735 -0.7252197265625 +64736 -0.85699462890625 +64737 -0.85980224609375 +64738 -0.870025634765625 +64739 -0.870391845703125 +64740 -0.870391845703125 +64741 -0.870391845703125 +64742 -0.85882568359375 +64743 -0.858062744140625 +64744 -0.6898193359375 +64745 -0.673004150390625 +64746 -0.45257568359375 +64747 -0.42694091796875 +64748 -0.240020751953125 +64749 -0.2100830078125 +64750 -0.065643310546875 +64751 -0.0362548828125 +64752 0.083770751953125 +64753 0.10943603515625 +64754 0.21514892578125 +64755 0.23516845703125 +64756 0.358367919921875 +64757 0.373687744140625 +64758 0.505950927734375 +64759 0.517791748046875 +64760 0.5966796875 +64761 0.602783203125 +64762 0.6365966796875 +64763 0.635711669921875 +64764 0.661376953125 +64765 0.655181884765625 +64766 0.669158935546875 +64767 0.65948486328125 +64768 0.6619873046875 +64769 0.651275634765625 +64770 0.628631591796875 +64771 0.61846923828125 +64772 0.547821044921875 +64773 0.53753662109375 +64774 0.416229248046875 +64775 0.404144287109375 +64776 0.237823486328125 +64777 0.22186279296875 +64778 0.025482177734375 +64779 0.003997802734375 +64780 -0.19415283203125 +64781 -0.22100830078125 +64782 -0.394256591796875 +64783 -0.42449951171875 +64784 -0.5498046875 +64785 -0.579833984375 +64786 -0.61920166015625 +64787 -0.641876220703125 +64788 -0.608245849609375 +64789 -0.6177978515625 +64790 -0.57781982421875 +64791 -0.575531005859375 +64792 -0.53778076171875 +64793 -0.526336669921875 +64794 -0.44842529296875 +64795 -0.42645263671875 +64796 -0.29376220703125 +64797 -0.2581787109375 +64798 -0.116668701171875 +64799 -0.068695068359375 +64800 0.03741455078125 +64801 0.09222412109375 +64802 0.174774169921875 +64803 0.232147216796875 +64804 0.294677734375 +64805 0.3509521484375 +64806 0.361480712890625 +64807 0.410064697265625 +64808 0.3414306640625 +64809 0.372955322265625 +64810 0.248138427734375 +64811 0.2554931640625 +64812 0.1256103515625 +64813 0.10711669921875 +64814 -0.009307861328125 +64815 -0.052886962890625 +64816 -0.122528076171875 +64817 -0.186279296875 +64818 -0.1600341796875 +64819 -0.23291015625 +64820 -0.137054443359375 +64821 -0.209442138671875 +64822 -0.1063232421875 +64823 -0.174163818359375 +64824 -0.067352294921875 +64825 -0.126739501953125 +64826 -0.002655029296875 +64827 -0.048126220703125 +64828 0.070953369140625 +64829 0.0426025390625 +64830 0.119659423828125 +64831 0.10748291015625 +64832 0.139068603515625 +64833 0.1409912109375 +64834 0.178558349609375 +64835 0.19708251953125 +64836 0.23687744140625 +64837 0.273651123046875 +64838 0.266693115234375 +64839 0.31768798828125 +64840 0.279266357421875 +64841 0.341094970703125 +64842 0.296844482421875 +64843 0.368011474609375 +64844 0.2962646484375 +64845 0.37249755859375 +64846 0.229095458984375 +64847 0.30072021484375 +64848 0.094482421875 +64849 0.1517333984375 +64850 -0.0535888671875 +64851 -0.01470947265625 +64852 -0.206024169921875 +64853 -0.1883544921875 +64854 -0.366302490234375 +64855 -0.372711181640625 +64856 -0.486236572265625 +64857 -0.51397705078125 +64858 -0.529754638671875 +64859 -0.57177734375 +64860 -0.49139404296875 +64861 -0.53948974609375 +64862 -0.387969970703125 +64863 -0.43511962890625 +64864 -0.25390625 +64865 -0.2962646484375 +64866 -0.124176025390625 +64867 -0.161102294921875 +64868 -0.011749267578125 +64869 -0.0435791015625 +64870 0.086700439453125 +64871 0.060394287109375 +64872 0.158203125 +64873 0.13665771484375 +64874 0.1890869140625 +64875 0.170135498046875 +64876 0.18365478515625 +64877 0.16552734375 +64878 0.173095703125 +64879 0.15728759765625 +64880 0.16253662109375 +64881 0.150787353515625 +64882 0.13055419921875 +64883 0.12200927734375 +64884 0.085784912109375 +64885 0.080108642578125 +64886 0.052276611328125 +64887 0.05126953125 +64888 0.055267333984375 +64889 0.062896728515625 +64890 0.07501220703125 +64891 0.09271240234375 +64892 0.068756103515625 +64893 0.092987060546875 +64894 0.050201416015625 +64895 0.07855224609375 +64896 0.0330810546875 +64897 0.06427001953125 +64898 0.003692626953125 +64899 0.0347900390625 +64900 -0.039520263671875 +64901 -0.01171875 +64902 -0.07916259765625 +64903 -0.056060791015625 +64904 -0.076690673828125 +64905 -0.055511474609375 +64906 -0.0325927734375 +64907 -0.010467529296875 +64908 0.00408935546875 +64909 0.02508544921875 +64910 0.01007080078125 +64911 0.025665283203125 +64912 0.008575439453125 +64913 0.017333984375 +64914 0.0008544921875 +64915 0.00189208984375 +64916 -0.0234375 +64917 -0.03173828125 +64918 -0.05377197265625 +64919 -0.071502685546875 +64920 -0.106719970703125 +64921 -0.13543701171875 +64922 -0.17926025390625 +64923 -0.219970703125 +64924 -0.249359130859375 +64925 -0.300506591796875 +64926 -0.316497802734375 +64927 -0.376312255859375 +64928 -0.352386474609375 +64929 -0.416107177734375 +64930 -0.31292724609375 +64931 -0.371124267578125 +64932 -0.198822021484375 +64933 -0.242279052734375 +64934 -0.046234130859375 +64935 -0.069732666015625 +64936 0.12615966796875 +64937 0.125640869140625 +64938 0.290435791015625 +64939 0.31268310546875 +64940 0.414031982421875 +64941 0.45501708984375 +64942 0.4991455078125 +64943 0.554779052734375 +64944 0.54486083984375 +64945 0.61065673828125 +64946 0.54083251953125 +64947 0.610931396484375 +64948 0.465484619140625 +64949 0.531463623046875 +64950 0.333465576171875 +64951 0.3883056640625 +64952 0.1929931640625 +64953 0.23468017578125 +64954 0.066436767578125 +64955 0.095245361328125 +64956 -0.022674560546875 +64957 -0.00396728515625 +64958 -0.061370849609375 +64959 -0.04852294921875 +64960 -0.064849853515625 +64961 -0.055145263671875 +64962 -0.08026123046875 +64963 -0.0758056640625 +64964 -0.13330078125 +64965 -0.138702392578125 +64966 -0.192901611328125 +64967 -0.209197998046875 +64968 -0.260833740234375 +64969 -0.289031982421875 +64970 -0.337921142578125 +64971 -0.37884521484375 +64972 -0.404205322265625 +64973 -0.456329345703125 +64974 -0.455322265625 +64975 -0.51641845703125 +64976 -0.4554443359375 +64977 -0.519287109375 +64978 -0.39862060546875 +64979 -0.458251953125 +64980 -0.331451416015625 +64981 -0.384796142578125 +64982 -0.276397705078125 +64983 -0.323699951171875 +64984 -0.228240966796875 +64985 -0.269287109375 +64986 -0.1630859375 +64987 -0.1951904296875 +64988 -0.07952880859375 +64989 -0.100006103515625 +64990 -0.001678466796875 +64991 -0.01055908203125 +64992 0.09796142578125 +64993 0.1033935546875 +64994 0.22613525390625 +64995 0.24908447265625 +64996 0.334869384765625 +64997 0.373199462890625 +64998 0.40838623046875 +64999 0.45806884765625 +65000 0.453826904296875 +65001 0.511474609375 +65002 0.500274658203125 +65003 0.565399169921875 +65004 0.54022216796875 +65005 0.61138916015625 +65006 0.519744873046875 +65007 0.5897216796875 +65008 0.429962158203125 +65009 0.4906005859375 +65010 0.286712646484375 +65011 0.33148193359375 +65012 0.1219482421875 +65013 0.147796630859375 +65014 -0.026702880859375 +65015 -0.01873779296875 +65016 -0.134185791015625 +65017 -0.140289306640625 +65018 -0.178192138671875 +65019 -0.191986083984375 +65020 -0.1683349609375 +65021 -0.184295654296875 +65022 -0.145111083984375 +65023 -0.161834716796875 +65024 -0.1466064453125 +65025 -0.166595458984375 +65026 -0.16876220703125 +65027 -0.19390869140625 +65028 -0.1942138671875 +65029 -0.22442626953125 +65030 -0.242523193359375 +65031 -0.279754638671875 +65032 -0.294952392578125 +65033 -0.3389892578125 +65034 -0.30853271484375 +65035 -0.3543701171875 +65036 -0.30328369140625 +65037 -0.348175048828125 +65038 -0.2841796875 +65039 -0.32598876953125 +65040 -0.2244873046875 +65041 -0.2581787109375 +65042 -0.11968994140625 +65043 -0.139801025390625 +65044 0.01727294921875 +65045 0.014617919921875 +65046 0.131866455078125 +65047 0.144378662109375 +65048 0.19866943359375 +65049 0.221038818359375 +65050 0.241241455078125 +65051 0.27069091796875 +65052 0.260345458984375 +65053 0.294036865234375 +65054 0.27471923828125 +65055 0.311767578125 +65056 0.298065185546875 +65057 0.339141845703125 +65058 0.315765380859375 +65059 0.360260009765625 +65060 0.3148193359375 +65061 0.360504150390625 +65062 0.2679443359375 +65063 0.308380126953125 +65064 0.155975341796875 +65065 0.18170166015625 +65066 0.000274658203125 +65067 0.0047607421875 +65068 -0.158172607421875 +65069 -0.17559814453125 +65070 -0.279998779296875 +65071 -0.3143310546875 +65072 -0.327178955078125 +65073 -0.36785888671875 +65074 -0.32257080078125 +65075 -0.36248779296875 +65076 -0.30572509765625 +65077 -0.343536376953125 +65078 -0.268707275390625 +65079 -0.3018798828125 +65080 -0.20623779296875 +65081 -0.231414794921875 +65082 -0.105743408203125 +65083 -0.117645263671875 +65084 0.004425048828125 +65085 0.007049560546875 +65086 0.0765380859375 +65087 0.087982177734375 +65088 0.12298583984375 +65089 0.13946533203125 +65090 0.15478515625 +65091 0.17425537109375 +65092 0.168212890625 +65093 0.188201904296875 +65094 0.1544189453125 +65095 0.171234130859375 +65096 0.10906982421875 +65097 0.118438720703125 +65098 0.055908203125 +65099 0.05706787109375 +65100 -0.003204345703125 +65101 -0.010711669921875 +65102 -0.073974609375 +65103 -0.0914306640625 +65104 -0.136474609375 +65105 -0.162322998046875 +65106 -0.16552734375 +65107 -0.194549560546875 +65108 -0.127227783203125 +65109 -0.1492919921875 +65110 -0.0172119140625 +65111 -0.02166748046875 +65112 0.1085205078125 +65113 0.124053955078125 +65114 0.18316650390625 +65115 0.211151123046875 +65116 0.20751953125 +65117 0.240447998046875 +65118 0.2080078125 +65119 0.242218017578125 +65120 0.192779541015625 +65121 0.2257080078125 +65122 0.16485595703125 +65123 0.194366455078125 +65124 0.09576416015625 +65125 0.115509033203125 +65126 0.00616455078125 +65127 0.0128173828125 +65128 -0.05169677734375 +65129 -0.053802490234375 +65130 -0.100738525390625 +65131 -0.110626220703125 +65132 -0.177520751953125 +65133 -0.199493408203125 +65134 -0.259368896484375 +65135 -0.29437255859375 +65136 -0.291351318359375 +65137 -0.33221435546875 +65138 -0.2445068359375 +65139 -0.27972412109375 +65140 -0.161102294921875 +65141 -0.185333251953125 +65142 -0.1102294921875 +65143 -0.128204345703125 +65144 -0.098358154296875 +65145 -0.115692138671875 +65146 -0.09820556640625 +65147 -0.116455078125 +65148 -0.088409423828125 +65149 -0.105926513671875 +65150 -0.042724609375 +65151 -0.053955078125 +65152 0.046966552734375 +65153 0.048797607421875 +65154 0.141448974609375 +65155 0.157318115234375 +65156 0.188751220703125 +65157 0.212005615234375 +65158 0.19378662109375 +65159 0.218475341796875 +65160 0.209381103515625 +65161 0.23724365234375 +65162 0.267913818359375 +65163 0.30535888671875 +65164 0.333160400390625 +65165 0.38128662109375 +65166 0.35235595703125 +65167 0.404449462890625 +65168 0.342620849609375 +65169 0.3944091796875 +65170 0.33660888671875 +65171 0.3885498046875 +65172 0.31329345703125 +65173 0.362640380859375 +65174 0.235137939453125 +65175 0.27362060546875 +65176 0.098358154296875 +65177 0.11712646484375 +65178 -0.051727294921875 +65179 -0.054901123046875 +65180 -0.170135498046875 +65181 -0.19085693359375 +65182 -0.25250244140625 +65183 -0.28570556640625 +65184 -0.2987060546875 +65185 -0.339263916015625 +65186 -0.331451416015625 +65187 -0.3775634765625 +65188 -0.390106201171875 +65189 -0.445709228515625 +65190 -0.46722412109375 +65191 -0.535064697265625 +65192 -0.548370361328125 +65193 -0.629058837890625 +65194 -0.60736083984375 +65195 -0.697601318359375 +65196 -0.612152099609375 +65197 -0.70391845703125 +65198 -0.557952880859375 +65199 -0.6424560546875 +65200 -0.425628662109375 +65201 -0.491241455078125 +65202 -0.2286376953125 +65203 -0.265716552734375 +65204 -0.0174560546875 +65205 -0.023712158203125 +65206 0.179107666015625 +65207 0.201751708984375 +65208 0.3306884765625 +65209 0.375823974609375 +65210 0.42559814453125 +65211 0.485076904296875 +65212 0.498138427734375 +65213 0.56884765625 +65214 0.55499267578125 +65215 0.634765625 +65216 0.55682373046875 +65217 0.63763427734375 +65218 0.49371337890625 +65219 0.5660400390625 +65220 0.41107177734375 +65221 0.4720458984375 +65222 0.3536376953125 +65223 0.40692138671875 +65224 0.327667236328125 +65225 0.3778076171875 +65226 0.326446533203125 +65227 0.376953125 +65228 0.32177734375 +65229 0.371978759765625 +65230 0.27032470703125 +65231 0.313140869140625 +65232 0.158111572265625 +65233 0.184417724609375 +65234 0.00726318359375 +65235 0.011199951171875 +65236 -0.151336669921875 +65237 -0.171051025390625 +65238 -0.29595947265625 +65239 -0.33740234375 +65240 -0.41278076171875 +65241 -0.47198486328125 +65242 -0.489288330078125 +65243 -0.560394287109375 +65244 -0.50628662109375 +65245 -0.58056640625 +65246 -0.476898193359375 +65247 -0.54754638671875 +65248 -0.4423828125 +65249 -0.508575439453125 +65250 -0.399139404296875 +65251 -0.459503173828125 +65252 -0.342010498046875 +65253 -0.394378662109375 +65254 -0.30535888671875 +65255 -0.35260009765625 +65256 -0.26959228515625 +65257 -0.31170654296875 +65258 -0.169952392578125 +65259 -0.197418212890625 +65260 -0.0048828125 +65261 -0.007965087890625 +65262 0.1827392578125 +65263 0.207489013671875 +65264 0.3582763671875 +65265 0.409210205078125 +65266 0.499847412109375 +65267 0.57208251953125 +65268 0.581207275390625 +65269 0.66595458984375 +65270 0.57440185546875 +65271 0.65875244140625 +65272 0.4942626953125 +65273 0.56744384765625 +65274 0.375152587890625 +65275 0.431396484375 +65276 0.255340576171875 +65277 0.29443359375 +65278 0.15740966796875 +65279 0.182464599609375 +65280 0.05413818359375 +65281 0.06365966796875 +65282 -0.066650390625 +65283 -0.075958251953125 +65284 -0.16534423828125 +65285 -0.189422607421875 +65286 -0.237640380859375 +65287 -0.271942138671875 +65288 -0.29931640625 +65289 -0.342529296875 +65290 -0.31915283203125 +65291 -0.364166259765625 +65292 -0.28900146484375 +65293 -0.327239990234375 +65294 -0.246826171875 +65295 -0.2769775390625 +65296 -0.22650146484375 +65297 -0.253692626953125 +65298 -0.216522216796875 +65299 -0.24365234375 +65300 -0.176300048828125 +65301 -0.1983642578125 +65302 -0.104644775390625 +65303 -0.116241455078125 +65304 -0.034912109375 +65305 -0.036834716796875 +65306 0.02850341796875 +65307 0.034881591796875 +65308 0.0789794921875 +65309 0.09124755859375 +65310 0.09674072265625 +65311 0.10888671875 +65312 0.11328125 +65313 0.125518798828125 +65314 0.14239501953125 +65315 0.15771484375 +65316 0.1611328125 +65317 0.17828369140625 +65318 0.155853271484375 +65319 0.17108154296875 +65320 0.121429443359375 +65321 0.129974365234375 +65322 0.0809326171875 +65323 0.082427978515625 +65324 0.033782958984375 +65325 0.027679443359375 +65326 -0.046295166015625 +65327 -0.065643310546875 +65328 -0.12713623046875 +65329 -0.15936279296875 +65330 -0.174652099609375 +65331 -0.21307373046875 +65332 -0.195343017578125 +65333 -0.234649658203125 +65334 -0.168975830078125 +65335 -0.2001953125 +65336 -0.103363037109375 +65337 -0.119171142578125 +65338 -0.0262451171875 +65339 -0.024749755859375 +65340 0.06475830078125 +65341 0.085784912109375 +65342 0.14093017578125 +65343 0.178131103515625 +65344 0.1715087890625 +65345 0.215576171875 +65346 0.167694091796875 +65347 0.211456298828125 +65348 0.137451171875 +65349 0.17523193359375 +65350 0.099090576171875 +65351 0.128753662109375 +65352 0.077728271484375 +65353 0.1019287109375 +65354 0.05615234375 +65355 0.0743408203125 +65356 0.031951904296875 +65357 0.04327392578125 +65358 0.029754638671875 +65359 0.038177490234375 +65360 0.063873291015625 +65361 0.076263427734375 +65362 0.120361328125 +65363 0.14105224609375 +65364 0.160400390625 +65365 0.186431884765625 +65366 0.1640625 +65367 0.188812255859375 +65368 0.123565673828125 +65369 0.1390380859375 +65370 0.04278564453125 +65371 0.041778564453125 +65372 -0.058563232421875 +65373 -0.079437255859375 +65374 -0.176116943359375 +65375 -0.219390869140625 +65376 -0.30120849609375 +65377 -0.367828369140625 +65378 -0.40875244140625 +65379 -0.494873046875 +65380 -0.461456298828125 +65381 -0.556243896484375 +65382 -0.422943115234375 +65383 -0.508697509765625 +65384 -0.312774658203125 +65385 -0.3756103515625 +65386 -0.182891845703125 +65387 -0.218902587890625 +65388 -0.0543212890625 +65389 -0.063751220703125 +65390 0.074432373046875 +65391 0.091552734375 +65392 0.19427490234375 +65393 0.23602294921875 +65394 0.282867431640625 +65395 0.342987060546875 +65396 0.3258056640625 +65397 0.39520263671875 +65398 0.320343017578125 +65399 0.389373779296875 +65400 0.26544189453125 +65401 0.324249267578125 +65402 0.181488037109375 +65403 0.224090576171875 +65404 0.098175048828125 +65405 0.124267578125 +65406 0.025787353515625 +65407 0.037078857421875 +65408 -0.012725830078125 +65409 -0.010101318359375 +65410 -0.019256591796875 +65411 -0.019439697265625 +65412 -0.0206298828125 +65413 -0.022796630859375 +65414 -0.00128173828125 +65415 -0.001556396484375 +65416 0.048797607421875 +65417 0.056304931640625 +65418 0.092498779296875 +65419 0.106719970703125 +65420 0.085418701171875 +65421 0.096893310546875 +65422 0.04083251953125 +65423 0.042694091796875 +65424 -0.009521484375 +65425 -0.018035888671875 +65426 -0.057769775390625 +65427 -0.07586669921875 +65428 -0.0943603515625 +65429 -0.11944580078125 +65430 -0.128509521484375 +65431 -0.15972900390625 +65432 -0.165130615234375 +65433 -0.202606201171875 +65434 -0.204620361328125 +65435 -0.24859619140625 +65436 -0.253173828125 +65437 -0.30517578125 +65438 -0.30218505859375 +65439 -0.36212158203125 +65440 -0.32806396484375 +65441 -0.39141845703125 +65442 -0.298980712890625 +65443 -0.35528564453125 +65444 -0.211700439453125 +65445 -0.249969482421875 +65446 -0.080810546875 +65447 -0.092864990234375 +65448 0.07110595703125 +65449 0.08905029296875 +65450 0.1932373046875 +65451 0.2352294921875 +65452 0.2630615234375 +65453 0.318817138671875 +65454 0.29638671875 +65455 0.358642578125 +65456 0.287384033203125 +65457 0.347747802734375 +65458 0.235626220703125 +65459 0.28564453125 +65460 0.18377685546875 +65461 0.223175048828125 +65462 0.162353515625 +65463 0.196746826171875 +65464 0.149078369140625 +65465 0.179840087890625 +65466 0.129669189453125 +65467 0.155548095703125 +65468 0.1270751953125 +65469 0.151214599609375 +65470 0.132904052734375 +65471 0.156951904296875 +65472 0.1126708984375 +65473 0.13177490234375 +65474 0.087432861328125 +65475 0.100799560546875 +65476 0.076507568359375 +65477 0.087127685546875 +65478 0.049774169921875 +65479 0.05487060546875 +65480 -0.003692626953125 +65481 -0.009002685546875 +65482 -0.08349609375 +65483 -0.10400390625 +65484 -0.189056396484375 +65485 -0.229400634765625 +65486 -0.29541015625 +65487 -0.35552978515625 +65488 -0.368499755859375 +65489 -0.441925048828125 +65490 -0.39599609375 +65491 -0.473846435546875 +65492 -0.38916015625 +65493 -0.464813232421875 +65494 -0.351531982421875 +65495 -0.419097900390625 +65496 -0.281097412109375 +65497 -0.334320068359375 +65498 -0.192474365234375 +65499 -0.227935791015625 +65500 -0.105377197265625 +65501 -0.12347412109375 +65502 -0.025421142578125 +65503 -0.02764892578125 +65504 0.062652587890625 +65505 0.077667236328125 +65506 0.17633056640625 +65507 0.2132568359375 +65508 0.323760986328125 +65509 0.38885498046875 +65510 0.48675537109375 +65511 0.582794189453125 +65512 0.614044189453125 +65513 0.734039306640625 +65514 0.669952392578125 +65515 0.800140380859375 +65516 0.652099609375 +65517 0.7783203125 +65518 0.557586669921875 +65519 0.6651611328125 +65520 0.385528564453125 +65521 0.45965576171875 +65522 0.167327880859375 +65523 0.199188232421875 +65524 -0.0419921875 +65525 -0.050689697265625 +65526 -0.194549560546875 +65527 -0.23297119140625 +65528 -0.27569580078125 +65529 -0.33013916015625 +65530 -0.307464599609375 +65531 -0.368408203125 +65532 -0.3160400390625 +65533 -0.378936767578125 +65534 -0.31427001953125 +65535 -0.376983642578125 +65536 -0.316497802734375 +65537 -0.37969970703125 +65538 -0.326416015625 +65539 -0.391510009765625 +65540 -0.321868896484375 +65541 -0.385345458984375 +65542 -0.28704833984375 +65543 -0.3419189453125 +65544 -0.239288330078125 +65545 -0.28289794921875 +65546 -0.213470458984375 +65547 -0.251617431640625 +65548 -0.22412109375 +65549 -0.266143798828125 +65550 -0.228363037109375 +65551 -0.273345947265625 +65552 -0.1806640625 +65553 -0.216796875 +65554 -0.10675048828125 +65555 -0.128265380859375 +65556 -0.05560302734375 +65557 -0.068145751953125 +65558 -0.032745361328125 +65559 -0.0430908203125 +65560 -0.015167236328125 +65561 -0.024444580078125 +65562 0.023590087890625 +65563 0.020721435546875 +65564 0.10931396484375 +65565 0.124481201171875 +65566 0.218475341796875 +65567 0.25787353515625 +65568 0.3172607421875 +65569 0.379119873046875 +65570 0.398956298828125 +65571 0.47991943359375 +65572 0.437591552734375 +65573 0.5281982421875 +65574 0.4228515625 +65575 0.511138916015625 +65576 0.37701416015625 +65577 0.456207275390625 +65578 0.33575439453125 +65579 0.407470703125 +65580 0.31439208984375 +65581 0.383758544921875 +65582 0.290313720703125 +65583 0.35687255859375 +65584 0.25152587890625 +65585 0.31182861328125 +65586 0.199951171875 +65587 0.250885009765625 +65588 0.128753662109375 +65589 0.1654052734375 +65590 0.02178955078125 +65591 0.035247802734375 +65592 -0.12286376953125 +65593 -0.142059326171875 +65594 -0.2801513671875 +65595 -0.33563232421875 +65596 -0.441192626953125 +65597 -0.5345458984375 +65598 -0.59234619140625 +65599 -0.72186279296875 +65600 -0.684417724609375 +65601 -0.836669921875 +65602 -0.680023193359375 +65603 -0.8326416015625 +65604 -0.595306396484375 +65605 -0.7296142578125 +65606 -0.4747314453125 +65607 -0.582550048828125 +65608 -0.357696533203125 +65609 -0.440093994140625 +65610 -0.26214599609375 +65611 -0.324310302734375 +65612 -0.16094970703125 +65613 -0.20147705078125 +65614 -0.03240966796875 +65615 -0.044647216796875 +65616 0.089263916015625 +65617 0.103973388671875 +65618 0.1700439453125 +65619 0.202392578125 +65620 0.2210693359375 +65621 0.264495849609375 +65622 0.2816162109375 +65623 0.338897705078125 +65624 0.366363525390625 +65625 0.443817138671875 +65626 0.44775390625 +65627 0.545074462890625 +65628 0.50531005859375 +65629 0.6173095703125 +65630 0.532562255859375 +65631 0.6524658203125 +65632 0.53997802734375 +65633 0.66339111328125 +65634 0.53253173828125 +65635 0.6561279296875 +65636 0.490997314453125 +65637 0.606781005859375 +65638 0.40399169921875 +65639 0.501190185546875 +65640 0.282470703125 +65641 0.352783203125 +65642 0.138641357421875 +65643 0.176544189453125 +65644 -0.033294677734375 +65645 -0.034820556640625 +65646 -0.214599609375 +65647 -0.258209228515625 +65648 -0.363922119140625 +65649 -0.44244384765625 +65650 -0.471343994140625 +65651 -0.5753173828125 +65652 -0.53302001953125 +65653 -0.65203857421875 +65654 -0.52398681640625 +65655 -0.641632080078125 +65656 -0.4588623046875 +65657 -0.562164306640625 +65658 -0.37359619140625 +65659 -0.458038330078125 +65660 -0.285430908203125 +65661 -0.350555419921875 +65662 -0.211273193359375 +65663 -0.260528564453125 +65664 -0.154571533203125 +65665 -0.192108154296875 +65666 -0.112701416015625 +65667 -0.141937255859375 +65668 -0.07940673828125 +65669 -0.1021728515625 +65670 -0.04669189453125 +65671 -0.062896728515625 +65672 -0.004791259765625 +65673 -0.011932373046875 +65674 0.056060791015625 +65675 0.062835693359375 +65676 0.1256103515625 +65677 0.148712158203125 +65678 0.20062255859375 +65679 0.241729736328125 +65680 0.286956787109375 +65681 0.34912109375 +65682 0.373687744140625 +65683 0.457305908203125 +65684 0.4427490234375 +65685 0.54388427734375 +65686 0.46514892578125 +65687 0.5728759765625 +65688 0.41046142578125 +65689 0.506591796875 +65690 0.283782958984375 +65691 0.351226806640625 +65692 0.117279052734375 +65693 0.146514892578125 +65694 -0.0467529296875 +65695 -0.05523681640625 +65696 -0.177703857421875 +65697 -0.21624755859375 +65698 -0.27423095703125 +65699 -0.334930419921875 +65700 -0.329620361328125 +65701 -0.402984619140625 +65702 -0.3607177734375 +65703 -0.4412841796875 +65704 -0.404693603515625 +65705 -0.49578857421875 +65706 -0.4564208984375 +65707 -0.5601806640625 +65708 -0.488677978515625 +65709 -0.600738525390625 +65710 -0.474639892578125 +65711 -0.584228515625 +65712 -0.3890380859375 +65713 -0.47930908203125 +65714 -0.2265625 +65715 -0.27935791015625 +65716 -0.007110595703125 +65717 -0.0089111328125 +65718 0.218170166015625 +65719 0.268798828125 +65720 0.39190673828125 +65721 0.482818603515625 +65722 0.49029541015625 +65723 0.60369873046875 +65724 0.528564453125 +65725 0.650421142578125 +65726 0.539886474609375 +65727 0.66400146484375 +65728 0.5218505859375 +65729 0.6414794921875 +65730 0.466094970703125 +65731 0.572540283203125 +65732 0.405731201171875 +65733 0.498138427734375 +65734 0.357879638671875 +65735 0.439453125 +65736 0.3056640625 +65737 0.375518798828125 +65738 0.223358154296875 +65739 0.274505615234375 +65740 0.088714599609375 +65741 0.1087646484375 +65742 -0.080230712890625 +65743 -0.099395751953125 +65744 -0.257781982421875 +65745 -0.3182373046875 +65746 -0.444854736328125 +65747 -0.5489501953125 +65748 -0.627105712890625 +65749 -0.7738037109375 +65750 -0.76171875 +65751 -0.86383056640625 +65752 -0.82177734375 +65753 -0.870391845703125 +65754 -0.82159423828125 +65755 -0.86895751953125 +65756 -0.771759033203125 +65757 -0.861053466796875 +65758 -0.6583251953125 +65759 -0.765869140625 +65760 -0.47216796875 +65761 -0.5301513671875 +65762 -0.219085693359375 +65763 -0.214691162109375 +65764 0.066070556640625 +65765 0.137359619140625 +65766 0.341827392578125 +65767 0.474822998046875 +65768 0.5794677734375 +65769 0.76239013671875 +65770 0.75714111328125 +65771 0.867462158203125 +65772 0.856719970703125 +65773 0.870361328125 +65774 0.862091064453125 +65775 0.86480712890625 +65776 0.8603515625 +65777 0.831817626953125 +65778 0.84765625 +65779 0.677581787109375 +65780 0.7464599609375 +65781 0.495880126953125 +65782 0.619842529296875 +65783 0.30767822265625 +65784 0.4696044921875 +65785 0.116180419921875 +65786 0.2701416015625 +65787 -0.110748291015625 +65788 0.015869140625 +65789 -0.381805419921875 +65790 -0.25860595703125 +65791 -0.6572265625 +65792 -0.504974365234375 +65793 -0.857421875 +65794 -0.68865966796875 +65795 -0.870391845703125 +65796 -0.803680419921875 +65797 -0.870391845703125 +65798 -0.856292724609375 +65799 -0.86444091796875 +65800 -0.8614501953125 +65801 -0.85723876953125 +65802 -0.8629150390625 +65803 -0.790008544921875 +65804 -0.8560791015625 +65805 -0.62847900390625 +65806 -0.72833251953125 +65807 -0.3956298828125 +65808 -0.53570556640625 +65809 -0.126708984375 +65810 -0.31268310546875 +65811 0.150115966796875 +65812 -0.06878662109375 +65813 0.424041748046875 +65814 0.174591064453125 +65815 0.670623779296875 +65816 0.386962890625 +65817 0.854522705078125 +65818 0.55419921875 +65819 0.866485595703125 +65820 0.664031982421875 +65821 0.86920166015625 +65822 0.73028564453125 +65823 0.8653564453125 +65824 0.763153076171875 +65825 0.857147216796875 +65826 0.76031494140625 +65827 0.766845703125 +65828 0.72576904296875 +65829 0.628509521484375 +65830 0.65435791015625 +65831 0.462127685546875 +65832 0.566314697265625 +65833 0.297210693359375 +65834 0.47149658203125 +65835 0.14862060546875 +65836 0.352447509765625 +65837 -0.00537109375 +65838 0.215362548828125 +65839 -0.15753173828125 +65840 0.057769775390625 +65841 -0.31304931640625 +65842 -0.13079833984375 +65843 -0.48876953125 +65844 -0.313629150390625 +65845 -0.6416015625 +65846 -0.471221923828125 +65847 -0.751373291015625 +65848 -0.621246337890625 +65849 -0.84619140625 +65850 -0.752044677734375 +65851 -0.861297607421875 +65852 -0.837799072265625 +65853 -0.863250732421875 +65854 -0.853973388671875 +65855 -0.856597900390625 +65856 -0.810028076171875 +65857 -0.7498779296875 +65858 -0.750946044921875 +65859 -0.624542236328125 +65860 -0.65985107421875 +65861 -0.47808837890625 +65862 -0.49163818359375 +65863 -0.253387451171875 +65864 -0.282012939453125 +65865 0.003692626953125 +65866 -0.0843505859375 +65867 0.2257080078125 +65868 0.110748291015625 +65869 0.427154541015625 +65870 0.328094482421875 +65871 0.643218994140625 +65872 0.5599365234375 +65873 0.855926513671875 +65874 0.761016845703125 +65875 0.870361328125 +65876 0.858642578125 +65877 0.870361328125 +65878 0.865997314453125 +65879 0.862762451171875 +65880 0.866119384765625 +65881 0.79669189453125 +65882 0.85821533203125 +65883 0.595794677734375 +65884 0.764984130859375 +65885 0.362152099609375 +65886 0.612213134765625 +65887 0.1270751953125 +65888 0.446929931640625 +65889 -0.086944580078125 +65890 0.271026611328125 +65891 -0.2784423828125 +65892 0.057769775390625 +65893 -0.484832763671875 +65894 -0.2073974609375 +65895 -0.729583740234375 +65896 -0.484893798828125 +65897 -0.86688232421875 +65898 -0.725250244140625 +65899 -0.870391845703125 +65900 -0.86212158203125 +65901 -0.86859130859375 +65902 -0.870391845703125 +65903 -0.86279296875 +65904 -0.870391845703125 +65905 -0.817962646484375 +65906 -0.8599853515625 +65907 -0.6116943359375 +65908 -0.712371826171875 +65909 -0.3128662109375 +65910 -0.4517822265625 +65911 0.039398193359375 +65912 -0.140289306640625 +65913 0.422821044921875 +65914 0.195465087890625 +65915 0.805145263671875 +65916 0.502899169921875 +65917 0.870361328125 +65918 0.739044189453125 +65919 0.870361328125 +65920 0.859100341796875 +65921 0.860015869140625 +65922 0.867462158203125 +65923 0.727935791015625 +65924 0.8668212890625 +65925 0.48114013671875 +65926 0.85968017578125 +65927 0.2059326171875 +65928 0.798187255859375 +65929 -0.06103515625 +65930 0.667572021484375 +65931 -0.29913330078125 +65932 0.50262451171875 +65933 -0.516204833984375 +65934 0.294586181640625 +65935 -0.7252197265625 +65936 0.065399169921875 +65937 -0.85980224609375 +65938 -0.156341552734375 +65939 -0.870391845703125 +65940 -0.346527099609375 +65941 -0.870391845703125 +65942 -0.467071533203125 +65943 -0.858062744140625 +65944 -0.51513671875 +65945 -0.673004150390625 +65946 -0.53265380859375 +65947 -0.42694091796875 +65948 -0.555877685546875 +65949 -0.2100830078125 +65950 -0.5855712890625 +65951 -0.0362548828125 +65952 -0.601959228515625 +65953 0.10943603515625 +65954 -0.5926513671875 +65955 0.23516845703125 +65956 -0.52862548828125 +65957 0.373687744140625 +65958 -0.41436767578125 +65959 0.517791748046875 +65960 -0.301544189453125 +65961 0.602783203125 +65962 -0.1884765625 +65963 0.635711669921875 +65964 -0.051177978515625 +65965 0.655181884765625 +65966 0.101348876953125 +65967 0.65948486328125 +65968 0.262237548828125 +65969 0.651275634765625 +65970 0.4124755859375 +65971 0.61846923828125 +65972 0.52398681640625 +65973 0.53753662109375 +65974 0.583953857421875 +65975 0.404144287109375 +65976 0.5865478515625 +65977 0.22186279296875 +65978 0.534820556640625 +65979 0.003997802734375 +65980 0.445159912109375 +65981 -0.22100830078125 +65982 0.336090087890625 +65983 -0.42449951171875 +65984 0.226715087890625 +65985 -0.579833984375 +65986 0.152496337890625 +65987 -0.641876220703125 +65988 0.110382080078125 +65989 -0.6177978515625 +65990 0.051971435546875 +65991 -0.575531005859375 +65992 -0.025604248046875 +65993 -0.526336669921875 +65994 -0.081390380859375 +65995 -0.42645263671875 +65996 -0.0938720703125 +65997 -0.2581787109375 +65998 -0.091552734375 +65999 -0.068695068359375 +66000 -0.1051025390625 +66001 0.09222412109375 +66002 -0.121307373046875 +66003 0.232147216796875 +66004 -0.13385009765625 +66005 0.3509521484375 +66006 -0.16754150390625 +66007 0.410064697265625 +66008 -0.2470703125 +66009 0.372955322265625 +66010 -0.358184814453125 +66011 0.2554931640625 +66012 -0.462371826171875 +66013 0.10711669921875 +66014 -0.546173095703125 +66015 -0.052886962890625 +66016 -0.58294677734375 +66017 -0.186279296875 +66018 -0.5303955078125 +66019 -0.23291015625 +66020 -0.40692138671875 +66021 -0.209442138671875 +66022 -0.26397705078125 +66023 -0.174163818359375 +66024 -0.10791015625 +66025 -0.126739501953125 +66026 0.069427490234375 +66027 -0.048126220703125 +66028 0.246978759765625 +66029 0.0426025390625 +66030 0.389739990234375 +66031 0.10748291015625 +66032 0.488800048828125 +66033 0.1409912109375 +66034 0.58258056640625 +66035 0.19708251953125 +66036 0.667388916015625 +66037 0.273651123046875 +66038 0.701416015625 +66039 0.31768798828125 +66040 0.694671630859375 +66041 0.341094970703125 +66042 0.667938232421875 +66043 0.368011474609375 +66044 0.60430908203125 +66045 0.37249755859375 +66046 0.46624755859375 +66047 0.30072021484375 +66048 0.25775146484375 +66049 0.1517333984375 +66050 0.0303955078125 +66051 -0.01470947265625 +66052 -0.201507568359375 +66053 -0.1883544921875 +66054 -0.43499755859375 +66055 -0.372711181640625 +66056 -0.62469482421875 +66057 -0.51397705078125 +66058 -0.73602294921875 +66059 -0.57177734375 +66060 -0.76080322265625 +66061 -0.53948974609375 +66062 -0.710479736328125 +66063 -0.43511962890625 +66064 -0.61236572265625 +66065 -0.2962646484375 +66066 -0.49542236328125 +66067 -0.161102294921875 +66068 -0.371612548828125 +66069 -0.0435791015625 +66070 -0.24041748046875 +66071 0.060394287109375 +66072 -0.115875244140625 +66073 0.13665771484375 +66074 -0.013397216796875 +66075 0.170135498046875 +66076 0.066009521484375 +66077 0.16552734375 +66078 0.143463134765625 +66079 0.15728759765625 +66080 0.218414306640625 +66081 0.150787353515625 +66082 0.26861572265625 +66083 0.12200927734375 +66084 0.2972412109375 +66085 0.080108642578125 +66086 0.321014404296875 +66087 0.05126953125 +66088 0.358428955078125 +66089 0.062896728515625 +66090 0.391693115234375 +66091 0.09271240234375 +66092 0.38494873046875 +66093 0.092987060546875 +66094 0.350189208984375 +66095 0.07855224609375 +66096 0.30035400390625 +66097 0.06427001953125 +66098 0.226470947265625 +66099 0.0347900390625 +66100 0.13031005859375 +66101 -0.01171875 +66102 0.029937744140625 +66103 -0.056060791015625 +66104 -0.03875732421875 +66105 -0.055511474609375 +66106 -0.072235107421875 +66107 -0.010467529296875 +66108 -0.107330322265625 +66109 0.02508544921875 +66110 -0.159942626953125 +66111 0.025665283203125 +66112 -0.207916259765625 +66113 0.017333984375 +66114 -0.247955322265625 +66115 0.00189208984375 +66116 -0.287200927734375 +66117 -0.03173828125 +66118 -0.3162841796875 +66119 -0.071502685546875 +66120 -0.34918212890625 +66121 -0.13543701171875 +66122 -0.38446044921875 +66123 -0.219970703125 +66124 -0.40557861328125 +66125 -0.300506591796875 +66126 -0.414459228515625 +66127 -0.376312255859375 +66128 -0.3905029296875 +66129 -0.416107177734375 +66130 -0.300201416015625 +66131 -0.371124267578125 +66132 -0.147430419921875 +66133 -0.242279052734375 +66134 0.03460693359375 +66135 -0.069732666015625 +66136 0.227508544921875 +66137 0.125640869140625 +66138 0.405548095703125 +66139 0.31268310546875 +66140 0.539642333984375 +66141 0.45501708984375 +66142 0.630218505859375 +66143 0.554779052734375 +66144 0.67578125 +66145 0.61065673828125 +66146 0.66766357421875 +66147 0.610931396484375 +66148 0.588592529296875 +66149 0.531463623046875 +66150 0.451934814453125 +66151 0.3883056640625 +66152 0.29949951171875 +66153 0.23468017578125 +66154 0.152069091796875 +66155 0.095245361328125 +66156 0.031646728515625 +66157 -0.00396728515625 +66158 -0.048370361328125 +66159 -0.04852294921875 +66160 -0.097930908203125 +66161 -0.055145263671875 +66162 -0.153656005859375 +66163 -0.0758056640625 +66164 -0.234619140625 +66165 -0.138702392578125 +66166 -0.31317138671875 +66167 -0.209197998046875 +66168 -0.38946533203125 +66169 -0.289031982421875 +66170 -0.46337890625 +66171 -0.37884521484375 +66172 -0.518035888671875 +66173 -0.456329345703125 +66174 -0.5501708984375 +66175 -0.51641845703125 +66176 -0.530914306640625 +66177 -0.519287109375 +66178 -0.45660400390625 +66179 -0.458251953125 +66180 -0.367645263671875 +66181 -0.384796142578125 +66182 -0.28460693359375 +66183 -0.323699951171875 +66184 -0.205352783203125 +66185 -0.269287109375 +66186 -0.112274169921875 +66187 -0.1951904296875 +66188 -0.00628662109375 +66189 -0.100006103515625 +66190 0.09063720703125 +66191 -0.01055908203125 +66192 0.199676513671875 +66193 0.1033935546875 +66194 0.3251953125 +66195 0.24908447265625 +66196 0.426513671875 +66197 0.373199462890625 +66198 0.49017333984375 +66199 0.45806884765625 +66200 0.522247314453125 +66201 0.511474609375 +66202 0.547393798828125 +66203 0.565399169921875 +66204 0.560302734375 +66205 0.61138916015625 +66206 0.517547607421875 +66207 0.5897216796875 +66208 0.413360595703125 +66209 0.4906005859375 +66210 0.262603759765625 +66211 0.33148193359375 +66212 0.09356689453125 +66213 0.147796630859375 +66214 -0.060791015625 +66215 -0.01873779296875 +66216 -0.178009033203125 +66217 -0.140289306640625 +66218 -0.23809814453125 +66219 -0.191986083984375 +66220 -0.247894287109375 +66221 -0.184295654296875 +66222 -0.24017333984375 +66223 -0.161834716796875 +66224 -0.24609375 +66225 -0.166595458984375 +66226 -0.262237548828125 +66227 -0.19390869140625 +66228 -0.2745361328125 +66229 -0.22442626953125 +66230 -0.2999267578125 +66231 -0.279754638671875 +66232 -0.32379150390625 +66233 -0.3389892578125 +66234 -0.31158447265625 +66235 -0.3543701171875 +66236 -0.2813720703125 +66237 -0.348175048828125 +66238 -0.23876953125 +66239 -0.32598876953125 +66240 -0.16302490234375 +66241 -0.2581787109375 +66242 -0.051727294921875 +66243 -0.139801025390625 +66244 0.08306884765625 +66245 0.014617919921875 +66246 0.194854736328125 +66247 0.144378662109375 +66248 0.261688232421875 +66249 0.221038818359375 +66250 0.302764892578125 +66251 0.27069091796875 +66252 0.318572998046875 +66253 0.294036865234375 +66254 0.32489013671875 +66255 0.311767578125 +66256 0.33367919921875 +66257 0.339141845703125 +66258 0.333709716796875 +66259 0.360260009765625 +66260 0.31500244140625 +66261 0.360504150390625 +66262 0.2552490234375 +66263 0.308380126953125 +66264 0.139190673828125 +66265 0.18170166015625 +66266 -0.0137939453125 +66267 0.0047607421875 +66268 -0.167755126953125 +66269 -0.17559814453125 +66270 -0.28814697265625 +66271 -0.3143310546875 +66272 -0.3416748046875 +66273 -0.36785888671875 +66274 -0.347259521484375 +66275 -0.36248779296875 +66276 -0.338226318359375 +66277 -0.343536376953125 +66278 -0.3076171875 +66279 -0.3018798828125 +66280 -0.25103759765625 +66281 -0.231414794921875 +66282 -0.15802001953125 +66283 -0.117645263671875 +66284 -0.053253173828125 +66285 0.007049560546875 +66286 0.02178955078125 +66287 0.087982177734375 +66288 0.076873779296875 +66289 0.13946533203125 +66290 0.12054443359375 +66291 0.17425537109375 +66292 0.148681640625 +66293 0.188201904296875 +66294 0.15283203125 +66295 0.171234130859375 +66296 0.128448486328125 +66297 0.118438720703125 +66298 0.095062255859375 +66299 0.05706787109375 +66300 0.05364990234375 +66301 -0.010711669921875 +66302 -0.001007080078125 +66303 -0.0914306640625 +66304 -0.051727294921875 +66305 -0.162322998046875 +66306 -0.07720947265625 +66307 -0.194549560546875 +66308 -0.0499267578125 +66309 -0.1492919921875 +66310 0.033599853515625 +66311 -0.02166748046875 +66312 0.127838134765625 +66313 0.124053955078125 +66314 0.178558349609375 +66315 0.211151123046875 +66316 0.186920166015625 +66317 0.240447998046875 +66318 0.175048828125 +66319 0.242218017578125 +66320 0.1502685546875 +66321 0.2257080078125 +66322 0.11572265625 +66323 0.194366455078125 +66324 0.048736572265625 +66325 0.115509033203125 +66326 -0.033203125 +66327 0.0128173828125 +66328 -0.087005615234375 +66329 -0.053802490234375 +66330 -0.131072998046875 +66331 -0.110626220703125 +66332 -0.195098876953125 +66333 -0.199493408203125 +66334 -0.26055908203125 +66335 -0.29437255859375 +66336 -0.28271484375 +66337 -0.33221435546875 +66338 -0.23822021484375 +66339 -0.27972412109375 +66340 -0.161956787109375 +66341 -0.185333251953125 +66342 -0.110809326171875 +66343 -0.128204345703125 +66344 -0.09063720703125 +66345 -0.115692138671875 +66346 -0.07977294921875 +66347 -0.116455078125 +66348 -0.061370849609375 +66349 -0.105926513671875 +66350 -0.014556884765625 +66351 -0.053955078125 +66352 0.06683349609375 +66353 0.048797607421875 +66354 0.150360107421875 +66355 0.157318115234375 +66356 0.19329833984375 +66357 0.212005615234375 +66358 0.199493408203125 +66359 0.218475341796875 +66360 0.212005615234375 +66361 0.23724365234375 +66362 0.25732421875 +66363 0.30535888671875 +66364 0.306121826171875 +66365 0.38128662109375 +66366 0.315582275390625 +66367 0.404449462890625 +66368 0.300079345703125 +66369 0.3944091796875 +66370 0.2867431640625 +66371 0.3885498046875 +66372 0.25885009765625 +66373 0.362640380859375 +66374 0.186248779296875 +66375 0.27362060546875 +66376 0.06634521484375 +66377 0.11712646484375 +66378 -0.063446044921875 +66379 -0.054901123046875 +66380 -0.165985107421875 +66381 -0.19085693359375 +66382 -0.2374267578125 +66383 -0.28570556640625 +66384 -0.277496337890625 +66385 -0.339263916015625 +66386 -0.3046875 +66387 -0.3775634765625 +66388 -0.3511962890625 +66389 -0.445709228515625 +66390 -0.4110107421875 +66391 -0.535064697265625 +66392 -0.47259521484375 +66393 -0.629058837890625 +66394 -0.51483154296875 +66395 -0.697601318359375 +66396 -0.511962890625 +66397 -0.70391845703125 +66398 -0.46044921875 +66399 -0.6424560546875 +66400 -0.3450927734375 +66401 -0.491241455078125 +66402 -0.177276611328125 +66403 -0.265716552734375 +66404 0.00140380859375 +66405 -0.023712158203125 +66406 0.167144775390625 +66407 0.201751708984375 +66408 0.29486083984375 +66409 0.375823974609375 +66410 0.374847412109375 +66411 0.485076904296875 +66412 0.43499755859375 +66413 0.56884765625 +66414 0.48077392578125 +66415 0.634765625 +66416 0.480133056640625 +66417 0.63763427734375 +66418 0.42510986328125 +66419 0.5660400390625 +66420 0.35302734375 +66421 0.4720458984375 +66422 0.30072021484375 +66423 0.40692138671875 +66424 0.273651123046875 +66425 0.3778076171875 +66426 0.266632080078125 +66427 0.376953125 +66428 0.2569580078125 +66429 0.371978759765625 +66430 0.20953369140625 +66431 0.313140869140625 +66432 0.11322021484375 +66433 0.184417724609375 +66434 -0.01361083984375 +66435 0.011199951171875 +66436 -0.14556884765625 +66437 -0.171051025390625 +66438 -0.264862060546875 +66439 -0.33740234375 +66440 -0.360137939453125 +66441 -0.47198486328125 +66442 -0.421234130859375 +66443 -0.560394287109375 +66444 -0.432586669921875 +66445 -0.58056640625 +66446 -0.40509033203125 +66447 -0.54754638671875 +66448 -0.372650146484375 +66449 -0.508575439453125 +66450 -0.33258056640625 +66451 -0.459503173828125 +66452 -0.28094482421875 +66453 -0.394378662109375 +66454 -0.246063232421875 +66455 -0.35260009765625 +66456 -0.21221923828125 +66457 -0.31170654296875 +66458 -0.12677001953125 +66459 -0.197418212890625 +66460 0.01129150390625 +66461 -0.007965087890625 +66462 0.166839599609375 +66463 0.207489013671875 +66464 0.311492919921875 +66465 0.409210205078125 +66466 0.4273681640625 +66467 0.57208251953125 +66468 0.4930419921875 +66469 0.66595458984375 +66470 0.485748291015625 +66471 0.65875244140625 +66472 0.417724609375 +66473 0.56744384765625 +66474 0.317169189453125 +66475 0.431396484375 +66476 0.215545654296875 +66477 0.29443359375 +66478 0.131500244140625 +66479 0.182464599609375 +66480 0.042633056640625 +66481 0.06365966796875 +66482 -0.060760498046875 +66483 -0.075958251953125 +66484 -0.145050048828125 +66485 -0.189422607421875 +66486 -0.20660400390625 +66487 -0.271942138671875 +66488 -0.25885009765625 +66489 -0.342529296875 +66490 -0.275360107421875 +66491 -0.364166259765625 +66492 -0.249267578125 +66493 -0.327239990234375 +66494 -0.2127685546875 +66495 -0.2769775390625 +66496 -0.19464111328125 +66497 -0.253692626953125 +66498 -0.185211181640625 +66499 -0.24365234375 +66500 -0.150115966796875 +66501 -0.1983642578125 +66502 -0.08837890625 +66503 -0.116241455078125 +66504 -0.028350830078125 +66505 -0.036834716796875 +66506 0.026214599609375 +66507 0.034881591796875 +66508 0.06964111328125 +66509 0.09124755859375 +66510 0.08514404296875 +66511 0.10888671875 +66512 0.099456787109375 +66513 0.125518798828125 +66514 0.124237060546875 +66515 0.15771484375 +66516 0.1400146484375 +66517 0.17828369140625 +66518 0.13525390625 +66519 0.17108154296875 +66520 0.105621337890625 +66521 0.129974365234375 +66522 0.070709228515625 +66523 0.082427978515625 +66524 0.030059814453125 +66525 0.027679443359375 +66526 -0.038543701171875 +66527 -0.065643310546875 +66528 -0.1077880859375 +66529 -0.15936279296875 +66530 -0.148773193359375 +66531 -0.21307373046875 +66532 -0.166961669921875 +66533 -0.234649658203125 +66534 -0.1451416015625 +66535 -0.2001953125 +66536 -0.089935302734375 +66537 -0.119171142578125 +66538 -0.02484130859375 +66539 -0.024749755859375 +66540 0.052154541015625 +66541 0.085784912109375 +66542 0.116729736328125 +66543 0.178131103515625 +66544 0.142791748046875 +66545 0.215576171875 +66546 0.139862060546875 +66547 0.211456298828125 +66548 0.114654541015625 +66549 0.17523193359375 +66550 0.082672119140625 +66551 0.128753662109375 +66552 0.06512451171875 +66553 0.1019287109375 +66554 0.047454833984375 +66555 0.0743408203125 +66556 0.027557373046875 +66557 0.04327392578125 +66558 0.0262451171875 +66559 0.038177490234375 +66560 0.05511474609375 +66561 0.076263427734375 +66562 0.10186767578125 +66563 0.14105224609375 +66564 0.13446044921875 +66565 0.186431884765625 +66566 0.13690185546875 +66567 0.188812255859375 +66568 0.103057861328125 +66569 0.1390380859375 +66570 0.036224365234375 +66571 0.041778564453125 +66572 -0.04742431640625 +66573 -0.079437255859375 +66574 -0.144195556640625 +66575 -0.219390869140625 +66576 -0.2469482421875 +66577 -0.367828369140625 +66578 -0.335235595703125 +66579 -0.494873046875 +66580 -0.37884521484375 +66581 -0.556243896484375 +66582 -0.3482666015625 +66583 -0.508697509765625 +66584 -0.259307861328125 +66585 -0.3756103515625 +66586 -0.15399169921875 +66587 -0.218902587890625 +66588 -0.04937744140625 +66589 -0.063751220703125 +66590 0.055694580078125 +66591 0.091552734375 +66592 0.153778076171875 +66593 0.23602294921875 +66594 0.22674560546875 +66595 0.342987060546875 +66596 0.262847900390625 +66597 0.39520263671875 +66598 0.259796142578125 +66599 0.389373779296875 +66600 0.2166748046875 +66601 0.324249267578125 +66602 0.149932861328125 +66603 0.224090576171875 +66604 0.083526611328125 +66605 0.124267578125 +66606 0.02569580078125 +66607 0.037078857421875 +66608 -0.004974365234375 +66609 -0.010101318359375 +66610 -0.01007080078125 +66611 -0.019439697265625 +66612 -0.01129150390625 +66613 -0.022796630859375 +66614 0.003936767578125 +66615 -0.001556396484375 +66616 0.04376220703125 +66617 0.056304931640625 +66618 0.07818603515625 +66619 0.106719970703125 +66620 0.071319580078125 +66621 0.096893310546875 +66622 0.03399658203125 +66623 0.042694091796875 +66624 -0.008026123046875 +66625 -0.018035888671875 +66626 -0.04827880859375 +66627 -0.07586669921875 +66628 -0.078948974609375 +66629 -0.11944580078125 +66630 -0.10748291015625 +66631 -0.15972900390625 +66632 -0.137786865234375 +66633 -0.202606201171875 +66634 -0.170135498046875 +66635 -0.24859619140625 +66636 -0.209564208984375 +66637 -0.30517578125 +66638 -0.249114990234375 +66639 -0.36212158203125 +66640 -0.269683837890625 +66641 -0.39141845703125 +66642 -0.24554443359375 +66643 -0.35528564453125 +66644 -0.17413330078125 +66645 -0.249969482421875 +66646 -0.0672607421875 +66647 -0.092864990234375 +66648 0.05670166015625 +66649 0.08905029296875 +66650 0.156585693359375 +66651 0.2352294921875 +66652 0.214080810546875 +66653 0.318817138671875 +66654 0.241943359375 +66655 0.358642578125 +66656 0.23541259765625 +66657 0.347747802734375 +66658 0.194091796875 +66659 0.28564453125 +66660 0.152496337890625 +66661 0.223175048828125 +66662 0.135345458984375 +66663 0.196746826171875 +66664 0.12457275390625 +66665 0.179840087890625 +66666 0.108642578125 +66667 0.155548095703125 +66668 0.106109619140625 +66669 0.151214599609375 +66670 0.1102294921875 +66671 0.156951904296875 +66672 0.0931396484375 +66673 0.13177490234375 +66674 0.0718994140625 +66675 0.100799560546875 +66676 0.062225341796875 +66677 0.087127685546875 +66678 0.039764404296875 +66679 0.05487060546875 +66680 -0.004302978515625 +66681 -0.009002685546875 +66682 -0.069610595703125 +66683 -0.10400390625 +66684 -0.155609130859375 +66685 -0.229400634765625 +66686 -0.242095947265625 +66687 -0.35552978515625 +66688 -0.301513671875 +66689 -0.441925048828125 +66690 -0.323822021484375 +66691 -0.473846435546875 +66692 -0.318145751953125 +66693 -0.464813232421875 +66694 -0.287353515625 +66695 -0.419097900390625 +66696 -0.2298583984375 +66697 -0.334320068359375 +66698 -0.157501220703125 +66699 -0.227935791015625 +66700 -0.0863037109375 +66701 -0.12347412109375 +66702 -0.0208740234375 +66703 -0.02764892578125 +66704 0.051116943359375 +66705 0.077667236328125 +66706 0.143768310546875 +66707 0.2132568359375 +66708 0.263702392578125 +66709 0.38885498046875 +66710 0.396148681640625 +66711 0.582794189453125 +66712 0.499542236328125 +66713 0.734039306640625 +66714 0.545013427734375 +66715 0.800140380859375 +66716 0.5306396484375 +66717 0.7783203125 +66718 0.454071044921875 +66719 0.6651611328125 +66720 0.314605712890625 +66721 0.45965576171875 +66722 0.13763427734375 +66723 0.199188232421875 +66724 -0.032257080078125 +66725 -0.050689697265625 +66726 -0.156280517578125 +66727 -0.23297119140625 +66728 -0.2225341796875 +66729 -0.33013916015625 +66730 -0.248809814453125 +66731 -0.368408203125 +66732 -0.25628662109375 +66733 -0.378936767578125 +66734 -0.25537109375 +66735 -0.376983642578125 +66736 -0.2576904296875 +66737 -0.37969970703125 +66738 -0.26617431640625 +66739 -0.391510009765625 +66740 -0.262420654296875 +66741 -0.385345458984375 +66742 -0.2332763671875 +66743 -0.3419189453125 +66744 -0.1934814453125 +66745 -0.28289794921875 +66746 -0.172454833984375 +66747 -0.251617431640625 +66748 -0.182464599609375 +66749 -0.266143798828125 +66750 -0.187408447265625 +66751 -0.273345947265625 +66752 -0.148895263671875 +66753 -0.216796875 +66754 -0.0885009765625 +66755 -0.128265380859375 +66756 -0.04736328125 +66757 -0.068145751953125 +66758 -0.029998779296875 +66759 -0.0430908203125 +66760 -0.0169677734375 +66761 -0.024444580078125 +66762 0.014129638671875 +66763 0.020721435546875 +66764 0.085052490234375 +66765 0.124481201171875 +66766 0.176055908203125 +66767 0.25787353515625 +66768 0.25872802734375 +66769 0.379119873046875 +66770 0.32745361328125 +66771 0.47991943359375 +66772 0.36041259765625 +66773 0.5281982421875 +66774 0.348876953125 +66775 0.511138916015625 +66776 0.3115234375 +66777 0.456207275390625 +66778 0.2783203125 +66779 0.407470703125 +66780 0.2620849609375 +66781 0.383758544921875 +66782 0.243621826171875 +66783 0.35687255859375 +66784 0.2127685546875 +66785 0.31182861328125 +66786 0.171051025390625 +66787 0.250885009765625 +66788 0.112640380859375 +66789 0.1654052734375 +66790 0.023834228515625 +66791 0.035247802734375 +66792 -0.097015380859375 +66793 -0.142059326171875 +66794 -0.2288818359375 +66795 -0.33563232421875 +66796 -0.364288330078125 +66797 -0.5345458984375 +66798 -0.491729736328125 +66799 -0.72186279296875 +66800 -0.56982421875 +66801 -0.836669921875 +66802 -0.56707763671875 +66803 -0.8326416015625 +66804 -0.4969482421875 +66805 -0.7296142578125 +66806 -0.396820068359375 +66807 -0.582550048828125 +66808 -0.299774169921875 +66809 -0.440093994140625 +66810 -0.220855712890625 +66811 -0.324310302734375 +66812 -0.137115478515625 +66813 -0.20147705078125 +66814 -0.030242919921875 +66815 -0.044647216796875 +66816 0.071624755859375 +66817 0.103973388671875 +66818 0.14056396484375 +66819 0.202392578125 +66820 0.185333251953125 +66821 0.264495849609375 +66822 0.2371826171875 +66823 0.338897705078125 +66824 0.307708740234375 +66825 0.443817138671875 +66826 0.37469482421875 +66827 0.545074462890625 +66828 0.421630859375 +66829 0.6173095703125 +66830 0.443359375 +66831 0.6524658203125 +66832 0.448272705078125 +66833 0.66339111328125 +66834 0.440460205078125 +66835 0.6561279296875 +66836 0.40460205078125 +66837 0.606781005859375 +66838 0.331756591796875 +66839 0.501190185546875 +66840 0.230865478515625 +66841 0.352783203125 +66842 0.111968994140625 +66843 0.176544189453125 +66844 -0.029388427734375 +66845 -0.034820556640625 +66846 -0.178009033203125 +66847 -0.258209228515625 +66848 -0.300537109375 +66849 -0.44244384765625 +66850 -0.388916015625 +66851 -0.5753173828125 +66852 -0.439971923828125 +66853 -0.65203857421875 +66854 -0.433563232421875 +66855 -0.641632080078125 +66856 -0.381439208984375 +66857 -0.562164306640625 +66858 -0.31243896484375 +66859 -0.458038330078125 +66860 -0.24041748046875 +66861 -0.350555419921875 +66862 -0.17901611328125 +66863 -0.260528564453125 +66864 -0.131134033203125 +66865 -0.192108154296875 +66866 -0.0948486328125 +66867 -0.141937255859375 +66868 -0.06524658203125 +66869 -0.1021728515625 +66870 -0.036102294921875 +66871 -0.062896728515625 +66872 0.000244140625 +66873 -0.011932373046875 +66874 0.051483154296875 +66875 0.062835693359375 +66876 0.1092529296875 +66877 0.148712158203125 +66878 0.170867919921875 +66879 0.241729736328125 +66880 0.240966796875 +66881 0.34912109375 +66882 0.310760498046875 +66883 0.457305908203125 +66884 0.365753173828125 +66885 0.54388427734375 +66886 0.38275146484375 +66887 0.5728759765625 +66888 0.337432861328125 +66889 0.506591796875 +66890 0.233978271484375 +66891 0.351226806640625 +66892 0.098297119140625 +66893 0.146514892578125 +66894 -0.035552978515625 +66895 -0.05523681640625 +66896 -0.142913818359375 +66897 -0.21624755859375 +66898 -0.22259521484375 +66899 -0.334930419921875 +66900 -0.269073486328125 +66901 -0.402984619140625 +66902 -0.29571533203125 +66903 -0.4412841796875 +66904 -0.332244873046875 +66905 -0.49578857421875 +66906 -0.374542236328125 +66907 -0.5601806640625 +66908 -0.400726318359375 +66909 -0.600738525390625 +66910 -0.389312744140625 +66911 -0.584228515625 +66912 -0.320037841796875 +66913 -0.47930908203125 +66914 -0.188690185546875 +66915 -0.27935791015625 +66916 -0.01129150390625 +66917 -0.0089111328125 +66918 0.1710205078125 +66919 0.268798828125 +66920 0.312164306640625 +66921 0.482818603515625 +66922 0.3929443359375 +66923 0.60369873046875 +66924 0.42547607421875 +66925 0.650421142578125 +66926 0.436248779296875 +66927 0.66400146484375 +66928 0.4232177734375 +66929 0.6414794921875 +66930 0.379669189453125 +66931 0.572540283203125 +66932 0.332061767578125 +66933 0.498138427734375 +66934 0.29412841796875 +66935 0.439453125 +66936 0.252288818359375 +66937 0.375518798828125 +66938 0.185943603515625 +66939 0.274505615234375 +66940 0.07720947265625 +66941 0.1087646484375 +66942 -0.059326171875 +66943 -0.099395751953125 +66944 -0.202972412109375 +66945 -0.3182373046875 +66946 -0.35443115234375 +66947 -0.5489501953125 +66948 -0.502105712890625 +66949 -0.7738037109375 +66950 -0.611541748046875 +66951 -0.86383056640625 +66952 -0.6611328125 +66953 -0.870391845703125 +66954 -0.662261962890625 +66955 -0.86895751953125 +66956 -0.623382568359375 +66957 -0.861053466796875 +66958 -0.533203125 +66959 -0.765869140625 +66960 -0.3843994140625 +66961 -0.5301513671875 +66962 -0.181610107421875 +66963 -0.214691162109375 +66964 0.047271728515625 +66965 0.137359619140625 +66966 0.2689208984375 +66967 0.474822998046875 +66968 0.46026611328125 +66969 0.76239013671875 +66970 0.603729248046875 +66971 0.867462158203125 +66972 0.699493408203125 +66973 0.870361328125 +66974 0.739990234375 +66975 0.86480712890625 +66976 0.728607177734375 +66977 0.831817626953125 +66978 0.6810302734375 +66979 0.677581787109375 +66980 0.6009521484375 +66981 0.495880126953125 +66982 0.500335693359375 +66983 0.30767822265625 +66984 0.380584716796875 +66985 0.116180419921875 +66986 0.221099853515625 +66987 -0.110748291015625 +66988 0.01739501953125 +66989 -0.381805419921875 +66990 -0.2027587890625 +66991 -0.6572265625 +66992 -0.4005126953125 +66993 -0.857421875 +66994 -0.548004150390625 +66995 -0.870391845703125 +66996 -0.6405029296875 +66997 -0.870391845703125 +66998 -0.695404052734375 +66999 -0.86444091796875 +67000 -0.735748291015625 +67001 -0.85723876953125 +67002 -0.749542236328125 +67003 -0.790008544921875 +67004 -0.701568603515625 +67005 -0.62847900390625 +67006 -0.589691162109375 +67007 -0.3956298828125 +67008 -0.435150146484375 +67009 -0.126708984375 +67010 -0.255645751953125 +67011 0.150115966796875 +67012 -0.058746337890625 +67013 0.424041748046875 +67014 0.138031005859375 +67015 0.670623779296875 +67016 0.309600830078125 +67017 0.854522705078125 +67018 0.4444580078125 +67019 0.866485595703125 +67020 0.5325927734375 +67021 0.86920166015625 +67022 0.585662841796875 +67023 0.8653564453125 +67024 0.612274169921875 +67025 0.857147216796875 +67026 0.6104736328125 +67027 0.766845703125 +67028 0.583526611328125 +67029 0.628509521484375 +67030 0.5269775390625 +67031 0.462127685546875 +67032 0.457489013671875 +67033 0.297210693359375 +67034 0.383026123046875 +67035 0.14862060546875 +67036 0.288787841796875 +67037 -0.00537109375 +67038 0.179656982421875 +67039 -0.15753173828125 +67040 0.05328369140625 +67041 -0.31304931640625 +67042 -0.099395751953125 +67043 -0.48876953125 +67044 -0.247955322265625 +67045 -0.6416015625 +67046 -0.376312255859375 +67047 -0.751373291015625 +67048 -0.499359130859375 +67049 -0.84619140625 +67050 -0.60748291015625 +67051 -0.861297607421875 +67052 -0.679107666015625 +67053 -0.863250732421875 +67054 -0.693756103515625 +67055 -0.856597900390625 +67056 -0.659210205078125 +67057 -0.7498779296875 +67058 -0.612884521484375 +67059 -0.624542236328125 +67060 -0.540496826171875 +67061 -0.47808837890625 +67062 -0.404144287109375 +67063 -0.253387451171875 +67064 -0.233428955078125 +67065 0.003692626953125 +67066 -0.072662353515625 +67067 0.2257080078125 +67068 0.086212158203125 +67069 0.427154541015625 +67070 0.264129638671875 +67071 0.643218994140625 +67072 0.45428466796875 +67073 0.855926513671875 +67074 0.619049072265625 +67075 0.870361328125 +67076 0.726898193359375 +67077 0.870361328125 +67078 0.78216552734375 +67079 0.862762451171875 +67080 0.783111572265625 +67081 0.79669189453125 +67082 0.72412109375 +67083 0.595794677734375 +67084 0.62347412109375 +67085 0.362152099609375 +67086 0.498809814453125 +67087 0.1270751953125 +67088 0.36358642578125 +67089 -0.086944580078125 +67090 0.2196044921875 +67091 -0.2784423828125 +67092 0.045928955078125 +67093 -0.484832763671875 +67094 -0.16876220703125 +67095 -0.729583740234375 +67096 -0.392822265625 +67097 -0.86688232421875 +67098 -0.5867919921875 +67099 -0.870391845703125 +67100 -0.747222900390625 +67101 -0.86859130859375 +67102 -0.856475830078125 +67103 -0.86279296875 +67104 -0.863861083984375 +67105 -0.817962646484375 +67106 -0.8619384765625 +67107 -0.6116943359375 +67108 -0.81488037109375 +67109 -0.3128662109375 +67110 -0.63812255859375 +67111 0.039398193359375 +67112 -0.404876708984375 +67113 0.422821044921875 +67114 -0.135955810546875 +67115 0.805145263671875 +67116 0.126312255859375 +67117 0.870361328125 +67118 0.346343994140625 +67119 0.870361328125 +67120 0.516387939453125 +67121 0.860015869140625 +67122 0.631195068359375 +67123 0.727935791015625 +67124 0.68682861328125 +67125 0.48114013671875 +67126 0.69769287109375 +67127 0.2059326171875 +67128 0.677337646484375 +67129 -0.06103515625 +67130 0.631622314453125 +67131 -0.29913330078125 +67132 0.55145263671875 +67133 -0.516204833984375 +67134 0.42730712890625 +67135 -0.7252197265625 +67136 0.274658203125 +67137 -0.85980224609375 +67138 0.114898681640625 +67139 -0.870391845703125 +67140 -0.0333251953125 +67141 -0.870391845703125 +67142 -0.139495849609375 +67143 -0.858062744140625 +67144 -0.200408935546875 +67145 -0.673004150390625 +67146 -0.24774169921875 +67147 -0.42694091796875 +67148 -0.308197021484375 +67149 -0.2100830078125 +67150 -0.37982177734375 +67151 -0.0362548828125 +67152 -0.44415283203125 +67153 0.10943603515625 +67154 -0.4884033203125 +67155 0.23516845703125 +67156 -0.48675537109375 +67157 0.373687744140625 +67158 -0.440185546875 +67159 0.517791748046875 +67160 -0.38739013671875 +67161 0.602783203125 +67162 -0.325286865234375 +67163 0.635711669921875 +67164 -0.233551025390625 +67165 0.655181884765625 +67166 -0.11871337890625 +67167 0.65948486328125 +67168 0.0137939453125 +67169 0.651275634765625 +67170 0.148284912109375 +67171 0.61846923828125 +67172 0.261322021484375 +67173 0.53753662109375 +67174 0.3411865234375 +67175 0.404144287109375 +67176 0.3812255859375 +67177 0.22186279296875 +67178 0.38165283203125 +67179 0.003997802734375 +67180 0.3531494140625 +67181 -0.22100830078125 +67182 0.308013916015625 +67183 -0.42449951171875 +67184 0.259185791015625 +67185 -0.579833984375 +67186 0.232879638671875 +67187 -0.641876220703125 +67188 0.225006103515625 +67189 -0.6177978515625 +67190 0.195953369140625 +67191 -0.575531005859375 +67192 0.142730712890625 +67193 -0.526336669921875 +67194 0.09765625 +67195 -0.42645263671875 +67196 0.078094482421875 +67197 -0.2581787109375 +67198 0.06219482421875 +67199 -0.068695068359375 +67200 0.02679443359375 +67201 0.09222412109375 +67202 -0.0159912109375 +67203 0.232147216796875 +67204 -0.05938720703125 +67205 0.3509521484375 +67206 -0.12115478515625 +67207 0.410064697265625 +67208 -0.218963623046875 +67209 0.372955322265625 +67210 -0.339599609375 +67211 0.2554931640625 +67212 -0.450775146484375 +67213 0.10711669921875 +67214 -0.54034423828125 +67215 -0.052886962890625 +67216 -0.586090087890625 +67217 -0.186279296875 +67218 -0.553741455078125 +67219 -0.23291015625 +67220 -0.45758056640625 +67221 -0.209442138671875 +67222 -0.33856201171875 +67223 -0.174163818359375 +67224 -0.202239990234375 +67225 -0.126739501953125 +67226 -0.042999267578125 +67227 -0.048126220703125 +67228 0.121246337890625 +67229 0.0426025390625 +67230 0.261260986328125 +67231 0.10748291015625 +67232 0.368438720703125 +67233 0.1409912109375 +67234 0.4716796875 +67235 0.19708251953125 +67236 0.56646728515625 +67237 0.273651123046875 +67238 0.6181640625 +67239 0.31768798828125 +67240 0.633392333984375 +67241 0.341094970703125 +67242 0.627685546875 +67243 0.368011474609375 +67244 0.586944580078125 +67245 0.37249755859375 +67246 0.48095703125 +67247 0.30072021484375 +67248 0.31304931640625 +67249 0.1517333984375 +67250 0.124603271484375 +67251 -0.01470947265625 +67252 -0.073089599609375 +67253 -0.1883544921875 +67254 -0.277099609375 +67255 -0.372711181640625 +67256 -0.449371337890625 +67257 -0.51397705078125 +67258 -0.560516357421875 +67259 -0.57177734375 +67260 -0.602630615234375 +67261 -0.53948974609375 +67262 -0.58380126953125 +67263 -0.43511962890625 +67264 -0.52520751953125 +67265 -0.2962646484375 +67266 -0.44940185546875 +67267 -0.161102294921875 +67268 -0.365142822265625 +67269 -0.0435791015625 +67270 -0.2711181640625 +67271 0.060394287109375 +67272 -0.178192138671875 +67273 0.13665771484375 +67274 -0.098602294921875 +67275 0.170135498046875 +67276 -0.03302001953125 +67277 0.16552734375 +67278 0.03570556640625 +67279 0.15728759765625 +67280 0.106719970703125 +67281 0.150787353515625 +67282 0.161102294921875 +67283 0.12200927734375 +67284 0.200653076171875 +67285 0.080108642578125 +67286 0.238128662109375 +67287 0.05126953125 +67288 0.2877197265625 +67289 0.062896728515625 +67290 0.333709716796875 +67291 0.09271240234375 +67292 0.34564208984375 +67293 0.092987060546875 +67294 0.33245849609375 +67295 0.07855224609375 +67296 0.303985595703125 +67297 0.06427001953125 +67298 0.252288818359375 +67299 0.0347900390625 +67300 0.178436279296875 +67301 -0.01171875 +67302 0.09710693359375 +67303 -0.056060791015625 +67304 0.037811279296875 +67305 -0.055511474609375 +67306 0.003692626953125 +67307 -0.010467529296875 +67308 -0.035003662109375 +67309 0.02508544921875 +67310 -0.0906982421875 +67311 0.025665283203125 +67312 -0.1444091796875 +67313 0.017333984375 +67314 -0.192626953125 +67315 0.00189208984375 +67316 -0.2403564453125 +67317 -0.03173828125 +67318 -0.279052734375 +67319 -0.071502685546875 +67320 -0.31939697265625 +67321 -0.13543701171875 +67322 -0.359527587890625 +67323 -0.219970703125 +67324 -0.38531494140625 +67325 -0.300506591796875 +67326 -0.397918701171875 +67327 -0.376312255859375 +67328 -0.380340576171875 +67329 -0.416107177734375 +67330 -0.30523681640625 +67331 -0.371124267578125 +67332 -0.1759033203125 +67333 -0.242279052734375 +67334 -0.0196533203125 +67335 -0.069732666015625 +67336 0.147857666015625 +67337 0.125640869140625 +67338 0.30511474609375 +67339 0.31268310546875 +67340 0.427886962890625 +67341 0.45501708984375 +67342 0.515533447265625 +67343 0.554779052734375 +67344 0.566009521484375 +67345 0.61065673828125 +67346 0.5716552734375 +67347 0.610931396484375 +67348 0.51800537109375 +67349 0.531463623046875 +67350 0.41534423828125 +67351 0.3883056640625 +67352 0.296844482421875 +67353 0.23468017578125 +67354 0.1790771484375 +67355 0.095245361328125 +67356 0.0797119140625 +67357 -0.00396728515625 +67358 0.009735107421875 +67359 -0.04852294921875 +67360 -0.03839111328125 +67361 -0.055145263671875 +67362 -0.093414306640625 +67363 -0.0758056640625 +67364 -0.169952392578125 +67365 -0.138702392578125 +67366 -0.245208740234375 +67367 -0.209197998046875 +67368 -0.318572998046875 +67369 -0.289031982421875 +67370 -0.389251708984375 +67371 -0.37884521484375 +67372 -0.44317626953125 +67373 -0.456329345703125 +67374 -0.477203369140625 +67375 -0.51641845703125 +67376 -0.467803955078125 +67377 -0.519287109375 +67378 -0.411865234375 +67379 -0.458251953125 +67380 -0.341552734375 +67381 -0.384796142578125 +67382 -0.27337646484375 +67383 -0.323699951171875 +67384 -0.20574951171875 +67385 -0.269287109375 +67386 -0.124908447265625 +67387 -0.1951904296875 +67388 -0.032012939453125 +67389 -0.100006103515625 +67390 0.05487060546875 +67391 -0.01055908203125 +67392 0.15216064453125 +67393 0.1033935546875 +67394 0.26275634765625 +67395 0.24908447265625 +67396 0.35357666015625 +67397 0.373199462890625 +67398 0.413299560546875 +67399 0.45806884765625 +67400 0.446319580078125 +67401 0.511474609375 +67402 0.4720458984375 +67403 0.565399169921875 +67404 0.4859619140625 +67405 0.61138916015625 +67406 0.45318603515625 +67407 0.5897216796875 +67408 0.369110107421875 +67409 0.4906005859375 +67410 0.24566650390625 +67411 0.33148193359375 +67412 0.105712890625 +67413 0.147796630859375 +67414 -0.024017333984375 +67415 -0.01873779296875 +67416 -0.12518310546875 +67417 -0.140289306640625 +67418 -0.181365966796875 +67419 -0.191986083984375 +67420 -0.19757080078125 +67421 -0.184295654296875 +67422 -0.1995849609375 +67423 -0.161834716796875 +67424 -0.211883544921875 +67425 -0.166595458984375 +67426 -0.2313232421875 +67427 -0.19390869140625 +67428 -0.246307373046875 +67429 -0.22442626953125 +67430 -0.2701416015625 +67431 -0.279754638671875 +67432 -0.290985107421875 +67433 -0.3389892578125 +67434 -0.281158447265625 +67435 -0.3543701171875 +67436 -0.25518798828125 +67437 -0.348175048828125 +67438 -0.21771240234375 +67439 -0.32598876953125 +67440 -0.15234375 +67441 -0.2581787109375 +67442 -0.057464599609375 +67443 -0.139801025390625 +67444 0.056915283203125 +67445 0.014617919921875 +67446 0.153228759765625 +67447 0.144378662109375 +67448 0.2135009765625 +67449 0.221038818359375 +67450 0.25274658203125 +67451 0.27069091796875 +67452 0.271026611328125 +67453 0.294036865234375 +67454 0.2806396484375 +67455 0.311767578125 +67456 0.290924072265625 +67457 0.339141845703125 +67458 0.292633056640625 +67459 0.360260009765625 +67460 0.27777099609375 +67461 0.360504150390625 +67462 0.22894287109375 +67463 0.308380126953125 +67464 0.13433837890625 +67465 0.18170166015625 +67466 0.0093994140625 +67467 0.0047607421875 +67468 -0.117279052734375 +67469 -0.17559814453125 +67470 -0.218231201171875 +67471 -0.3143310546875 +67472 -0.26690673828125 +67473 -0.36785888671875 +67474 -0.277801513671875 +67475 -0.36248779296875 +67476 -0.2767333984375 +67477 -0.343536376953125 +67478 -0.2579345703125 +67479 -0.3018798828125 +67480 -0.2176513671875 +67481 -0.231414794921875 +67482 -0.14752197265625 +67483 -0.117645263671875 +67484 -0.066802978515625 +67485 0.007049560546875 +67486 -0.007965087890625 +67487 0.087982177734375 +67488 0.036590576171875 +67489 0.13946533203125 +67490 0.073455810546875 +67491 0.17425537109375 +67492 0.0992431640625 +67493 0.188201904296875 +67494 0.1070556640625 +67495 0.171234130859375 +67496 0.093048095703125 +67497 0.118438720703125 +67498 0.072265625 +67499 0.05706787109375 +67500 0.045135498046875 +67501 -0.010711669921875 +67502 0.007293701171875 +67503 -0.0914306640625 +67504 -0.02838134765625 +67505 -0.162322998046875 +67506 -0.045257568359375 +67507 -0.194549560546875 +67508 -0.020660400390625 +67509 -0.1492919921875 +67510 0.048431396484375 +67511 -0.02166748046875 +67512 0.124908447265625 +67513 0.124053955078125 +67514 0.164520263671875 +67515 0.211151123046875 +67516 0.16845703125 +67517 0.240447998046875 +67518 0.1551513671875 +67519 0.242218017578125 +67520 0.130859375 +67521 0.2257080078125 +67522 0.098388671875 +67523 0.194366455078125 +67524 0.039398193359375 +67525 0.115509033203125 +67526 -0.031585693359375 +67527 0.0128173828125 +67528 -0.079010009765625 +67529 -0.053802490234375 +67530 -0.11785888671875 +67531 -0.110626220703125 +67532 -0.172332763671875 +67533 -0.199493408203125 +67534 -0.227203369140625 +67535 -0.29437255859375 +67536 -0.245758056640625 +67537 -0.33221435546875 +67538 -0.208831787109375 +67539 -0.27972412109375 +67540 -0.1451416015625 +67541 -0.185333251953125 +67542 -0.1014404296875 +67543 -0.128204345703125 +67544 -0.08258056640625 +67545 -0.115692138671875 +67546 -0.07098388671875 +67547 -0.116455078125 +67548 -0.052978515625 +67549 -0.105926513671875 +67550 -0.0115966796875 +67551 -0.053955078125 +67552 0.05804443359375 +67553 0.048797607421875 +67554 0.129180908203125 +67555 0.157318115234375 +67556 0.166656494140625 +67557 0.212005615234375 +67558 0.1734619140625 +67559 0.218475341796875 +67560 0.184844970703125 +67561 0.23724365234375 +67562 0.2225341796875 +67563 0.30535888671875 +67564 0.262420654296875 +67565 0.38128662109375 +67566 0.269439697265625 +67567 0.404449462890625 +67568 0.25543212890625 +67569 0.3944091796875 +67570 0.242706298828125 +67571 0.3885498046875 +67572 0.21771240234375 +67573 0.362640380859375 +67574 0.15582275390625 +67575 0.27362060546875 +67576 0.055023193359375 +67577 0.11712646484375 +67578 -0.0538330078125 +67579 -0.054901123046875 +67580 -0.140167236328125 +67581 -0.19085693359375 +67582 -0.200714111328125 +67583 -0.28570556640625 +67584 -0.235748291015625 +67585 -0.339263916015625 +67586 -0.26007080078125 +67587 -0.3775634765625 +67588 -0.298583984375 +67589 -0.445709228515625 +67590 -0.346282958984375 +67591 -0.535064697265625 +67592 -0.39398193359375 +67593 -0.629058837890625 +67594 -0.425201416015625 +67595 -0.697601318359375 +67596 -0.41998291015625 +67597 -0.70391845703125 +67598 -0.375732421875 +67599 -0.6424560546875 +67600 -0.280914306640625 +67601 -0.491241455078125 +67602 -0.144683837890625 +67603 -0.265716552734375 +67604 0.0003662109375 +67605 -0.023712158203125 +67606 0.135345458984375 +67607 0.201751708984375 +67608 0.240447998046875 +67609 0.375823974609375 +67610 0.30780029296875 +67611 0.485076904296875 +67612 0.3587646484375 +67613 0.56884765625 +67614 0.3973388671875 +67615 0.634765625 +67616 0.398529052734375 +67617 0.63763427734375 +67618 0.3560791015625 +67619 0.5660400390625 +67620 0.298980712890625 +67621 0.4720458984375 +67622 0.255859375 +67623 0.40692138671875 +67624 0.231109619140625 +67625 0.3778076171875 +67626 0.220977783203125 +67627 0.376953125 +67628 0.2081298828125 +67629 0.371978759765625 +67630 0.165679931640625 +67631 0.313140869140625 +67632 0.0853271484375 +67633 0.184417724609375 +67634 -0.018402099609375 +67635 0.011199951171875 +67636 -0.125518798828125 +67637 -0.171051025390625 +67638 -0.221954345703125 +67639 -0.33740234375 +67640 -0.298736572265625 +67641 -0.47198486328125 +67642 -0.347869873046875 +67643 -0.560394287109375 +67644 -0.35723876953125 +67645 -0.58056640625 +67646 -0.335296630859375 +67647 -0.54754638671875 +67648 -0.308380126953125 +67649 -0.508575439453125 +67650 -0.2745361328125 +67651 -0.459503173828125 +67652 -0.23089599609375 +67653 -0.394378662109375 +67654 -0.199615478515625 +67655 -0.35260009765625 +67656 -0.16876220703125 +67657 -0.31170654296875 +67658 -0.097808837890625 +67659 -0.197418212890625 +67660 0.013824462890625 +67661 -0.007965087890625 +67662 0.13861083984375 +67663 0.207489013671875 +67664 0.254302978515625 +67665 0.409210205078125 +67666 0.34686279296875 +67667 0.57208251953125 +67668 0.3995361328125 +67669 0.66595458984375 +67670 0.3946533203125 +67671 0.65875244140625 +67672 0.3416748046875 +67673 0.56744384765625 +67674 0.26251220703125 +67675 0.431396484375 +67676 0.181640625 +67677 0.29443359375 +67678 0.113677978515625 +67679 0.182464599609375 +67680 0.041412353515625 +67681 0.06365966796875 +67682 -0.04248046875 +67683 -0.075958251953125 +67684 -0.1116943359375 +67685 -0.189422607421875 +67686 -0.1632080078125 +67687 -0.271942138671875 +67688 -0.20721435546875 +67689 -0.342529296875 +67690 -0.223052978515625 +67691 -0.364166259765625 +67692 -0.205291748046875 +67693 -0.327239990234375 +67694 -0.178741455078125 +67695 -0.2769775390625 +67696 -0.1656494140625 +67697 -0.253692626953125 +67698 -0.158447265625 +67699 -0.24365234375 +67700 -0.130523681640625 +67701 -0.1983642578125 +67702 -0.0811767578125 +67703 -0.116241455078125 +67704 -0.032501220703125 +67705 -0.036834716796875 +67706 0.012451171875 +67707 0.034881591796875 +67708 0.04913330078125 +67709 0.09124755859375 +67710 0.064361572265625 +67711 0.10888671875 +67712 0.078643798828125 +67713 0.125518798828125 +67714 0.100860595703125 +67715 0.15771484375 +67716 0.11578369140625 +67717 0.17828369140625 +67718 0.11431884765625 +67719 0.17108154296875 +67720 0.092987060546875 +67721 0.129974365234375 +67722 0.06689453125 +67723 0.082427978515625 +67724 0.03564453125 +67725 0.027679443359375 +67726 -0.0179443359375 +67727 -0.065643310546875 +67728 -0.072662353515625 +67729 -0.15936279296875 +67730 -0.106048583984375 +67731 -0.21307373046875 +67732 -0.122222900390625 +67733 -0.234649658203125 +67734 -0.10772705078125 +67735 -0.2001953125 +67736 -0.067535400390625 +67737 -0.119171142578125 +67738 -0.01971435546875 +67739 -0.024749755859375 +67740 0.037445068359375 +67741 0.085784912109375 +67742 0.085205078125 +67743 0.178131103515625 +67744 0.103485107421875 +67745 0.215576171875 +67746 0.0997314453125 +67747 0.211456298828125 +67748 0.0792236328125 +67749 0.17523193359375 +67750 0.05401611328125 +67751 0.128753662109375 +67752 0.04058837890625 +67753 0.1019287109375 +67754 0.027557373046875 +67755 0.0743408203125 +67756 0.013275146484375 +67757 0.04327392578125 +67758 0.013824462890625 +67759 0.038177490234375 +67760 0.03851318359375 +67761 0.076263427734375 +67762 0.0780029296875 +67763 0.14105224609375 +67764 0.106658935546875 +67765 0.186431884765625 +67766 0.11126708984375 +67767 0.188812255859375 +67768 0.08660888671875 +67769 0.1390380859375 +67770 0.035125732421875 +67771 0.041778564453125 +67772 -0.030303955078125 +67773 -0.079437255859375 +67774 -0.106842041015625 +67775 -0.219390869140625 +67776 -0.188812255859375 +67777 -0.367828369140625 +67778 -0.25970458984375 +67779 -0.494873046875 +67780 -0.2950439453125 +67781 -0.556243896484375 +67782 -0.2708740234375 +67783 -0.508697509765625 +67784 -0.199951171875 +67785 -0.3756103515625 +67786 -0.116302490234375 +67787 -0.218902587890625 +67788 -0.033660888671875 +67789 -0.063751220703125 +67790 0.049041748046875 +67791 0.091552734375 +67792 0.12591552734375 +67793 0.23602294921875 +67794 0.182373046875 +67795 0.342987060546875 +67796 0.20904541015625 +67797 0.39520263671875 +67798 0.204254150390625 +67799 0.389373779296875 +67800 0.167388916015625 +67801 0.324249267578125 +67802 0.111846923828125 +67803 0.224090576171875 +67804 0.057159423828125 +67805 0.124267578125 +67806 0.01007080078125 +67807 0.037078857421875 +67808 -0.014373779296875 +67809 -0.010101318359375 +67810 -0.017486572265625 +67811 -0.019439697265625 +67812 -0.0169677734375 +67813 -0.022796630859375 +67814 -0.002685546875 +67815 -0.001556396484375 +67816 0.031829833984375 +67817 0.056304931640625 +67818 0.062103271484375 +67819 0.106719970703125 +67820 0.058868408203125 +67821 0.096893310546875 +67822 0.030792236328125 +67823 0.042694091796875 +67824 -0.0013427734375 +67825 -0.018035888671875 +67826 -0.0323486328125 +67827 -0.07586669921875 +67828 -0.055999755859375 +67829 -0.11944580078125 +67830 -0.078369140625 +67831 -0.15972900390625 +67832 -0.102691650390625 +67833 -0.202606201171875 +67834 -0.129180908203125 +67835 -0.24859619140625 +67836 -0.161895751953125 +67837 -0.30517578125 +67838 -0.195098876953125 +67839 -0.36212158203125 +67840 -0.21337890625 +67841 -0.39141845703125 +67842 -0.19586181640625 +67843 -0.35528564453125 +67844 -0.14031982421875 +67845 -0.249969482421875 +67846 -0.056396484375 +67847 -0.092864990234375 +67848 0.04132080078125 +67849 0.08905029296875 +67850 0.120880126953125 +67851 0.2352294921875 +67852 0.16790771484375 +67853 0.318817138671875 +67854 0.191864013671875 +67855 0.358642578125 +67856 0.18890380859375 +67857 0.347747802734375 +67858 0.158599853515625 +67859 0.28564453125 +67860 0.12725830078125 +67861 0.223175048828125 +67862 0.113800048828125 +67863 0.196746826171875 +67864 0.1044921875 +67865 0.179840087890625 +67866 0.09063720703125 +67867 0.155548095703125 +67868 0.0865478515625 +67869 0.151214599609375 +67870 0.087249755859375 +67871 0.156951904296875 +67872 0.071563720703125 +67873 0.13177490234375 +67874 0.052734375 +67875 0.100799560546875 +67876 0.042938232421875 +67877 0.087127685546875 +67878 0.023681640625 +67879 0.05487060546875 +67880 -0.011688232421875 +67881 -0.009002685546875 +67882 -0.062744140625 +67883 -0.10400390625 +67884 -0.12908935546875 +67885 -0.229400634765625 +67886 -0.195220947265625 +67887 -0.35552978515625 +67888 -0.240081787109375 +67889 -0.441925048828125 +67890 -0.25604248046875 +67891 -0.473846435546875 +67892 -0.250152587890625 +67893 -0.464813232421875 +67894 -0.2247314453125 +67895 -0.419097900390625 +67896 -0.17864990234375 +67897 -0.334320068359375 +67898 -0.12109375 +67899 -0.227935791015625 +67900 -0.064422607421875 +67901 -0.12347412109375 +67902 -0.01226806640625 +67903 -0.02764892578125 +67904 0.044647216796875 +67905 0.077667236328125 +67906 0.11700439453125 +67907 0.2132568359375 +67908 0.20977783203125 +67909 0.38885498046875 +67910 0.311614990234375 +67911 0.582794189453125 +67912 0.3907470703125 +67913 0.734039306640625 +67914 0.425079345703125 +67915 0.800140380859375 +67916 0.413177490234375 +67917 0.7783203125 +67918 0.353363037109375 +67919 0.6651611328125 +67920 0.245147705078125 +67921 0.45965576171875 +67922 0.10809326171875 +67923 0.199188232421875 +67924 -0.023651123046875 +67925 -0.050689697265625 +67926 -0.120330810546875 +67927 -0.23297119140625 +67928 -0.1727294921875 +67929 -0.33013916015625 +67930 -0.19439697265625 +67931 -0.368408203125 +67932 -0.201416015625 +67933 -0.378936767578125 +67934 -0.20166015625 +67935 -0.376983642578125 +67936 -0.2039794921875 +67937 -0.37969970703125 +67938 -0.21063232421875 +67939 -0.391510009765625 +67940 -0.207550048828125 +67941 -0.385345458984375 +67942 -0.184661865234375 +67943 -0.3419189453125 +67944 -0.153289794921875 +67945 -0.28289794921875 +67946 -0.136016845703125 +67947 -0.251617431640625 +67948 -0.142303466796875 +67949 -0.266143798828125 +67950 -0.14459228515625 +67951 -0.273345947265625 +67952 -0.113616943359375 +67953 -0.216796875 +67954 -0.06597900390625 +67955 -0.128265380859375 +67956 -0.033172607421875 +67957 -0.068145751953125 +67958 -0.018707275390625 +67959 -0.0430908203125 +67960 -0.007781982421875 +67961 -0.024444580078125 +67962 0.016632080078125 +67963 0.020721435546875 +67964 0.071136474609375 +67965 0.124481201171875 +67966 0.140655517578125 +67967 0.25787353515625 +67968 0.2034912109375 +67969 0.379119873046875 +67970 0.25537109375 +67971 0.47991943359375 +67972 0.2796630859375 +67973 0.5281982421875 +67974 0.26971435546875 +67975 0.511138916015625 +67976 0.239898681640625 +67977 0.456207275390625 +67978 0.21319580078125 +67979 0.407470703125 +67980 0.199493408203125 +67981 0.383758544921875 +67982 0.184173583984375 +67983 0.35687255859375 +67984 0.159515380859375 +67985 0.31182861328125 +67986 0.126739501953125 +67987 0.250885009765625 +67988 0.0814208984375 +67989 0.1654052734375 +67990 0.013153076171875 +67991 0.035247802734375 +67992 -0.079315185546875 +67993 -0.142059326171875 +67994 -0.179931640625 +67995 -0.33563232421875 +67996 -0.28302001953125 +67997 -0.5345458984375 +67998 -0.3797607421875 +67999 -0.72186279296875 +68000 -0.43853759765625 +68001 -0.836669921875 +68002 -0.435333251953125 +68003 -0.8326416015625 +68004 -0.38055419921875 +68005 -0.7296142578125 +68006 -0.302825927734375 +68007 -0.582550048828125 +68008 -0.2275390625 +68009 -0.440093994140625 +68010 -0.166229248046875 +68011 -0.324310302734375 +68012 -0.101409912109375 +68013 -0.20147705078125 +68014 -0.01910400390625 +68015 -0.044647216796875 +68016 0.0587158203125 +68017 0.103973388671875 +68018 0.11016845703125 +68019 0.202392578125 +68020 0.1424560546875 +68021 0.264495849609375 +68022 0.180877685546875 +68023 0.338897705078125 +68024 0.23492431640625 +68025 0.443817138671875 +68026 0.286865234375 +68027 0.545074462890625 +68028 0.32354736328125 +68029 0.6173095703125 +68030 0.3408203125 +68031 0.6524658203125 +68032 0.345428466796875 +68033 0.66339111328125 +68034 0.340576171875 +68035 0.6561279296875 +68036 0.31390380859375 +68037 0.606781005859375 +68038 0.25811767578125 +68039 0.501190185546875 +68040 0.18023681640625 +68041 0.352783203125 +68042 0.08807373046875 +68043 0.176544189453125 +68044 -0.0220947265625 +68045 -0.034820556640625 +68046 -0.138275146484375 +68047 -0.258209228515625 +68048 -0.233856201171875 +68049 -0.44244384765625 +68050 -0.302490234375 +68051 -0.5753173828125 +68052 -0.34173583984375 +68053 -0.65203857421875 +68054 -0.335540771484375 +68055 -0.641632080078125 +68056 -0.2933349609375 +68057 -0.562164306640625 +68058 -0.23828125 +68059 -0.458038330078125 +68060 -0.181488037109375 +68061 -0.350555419921875 +68062 -0.133819580078125 +68063 -0.260528564453125 +68064 -0.097503662109375 +68065 -0.192108154296875 +68066 -0.070831298828125 +68067 -0.141937255859375 +68068 -0.04974365234375 +68069 -0.1021728515625 +68070 -0.029083251953125 +68071 -0.062896728515625 +68072 -0.002532958984375 +68073 -0.011932373046875 +68074 0.03619384765625 +68075 0.062835693359375 +68076 0.080535888671875 +68077 0.148712158203125 +68078 0.12841796875 +68079 0.241729736328125 +68080 0.18365478515625 +68081 0.34912109375 +68082 0.239227294921875 +68083 0.457305908203125 +68084 0.28350830078125 +68085 0.54388427734375 +68086 0.297821044921875 +68087 0.5728759765625 +68088 0.262603759765625 +68089 0.506591796875 +68090 0.18115234375 +68091 0.351226806640625 +68092 0.074127197265625 +68093 0.146514892578125 +68094 -0.031219482421875 +68095 -0.05523681640625 +68096 -0.114898681640625 +68097 -0.21624755859375 +68098 -0.17626953125 +68099 -0.334930419921875 +68100 -0.211883544921875 +68101 -0.402984619140625 +68102 -0.231842041015625 +68103 -0.4412841796875 +68104 -0.258575439453125 +68105 -0.49578857421875 +68106 -0.2890625 +68107 -0.5601806640625 +68108 -0.306976318359375 +68109 -0.600738525390625 +68110 -0.296234130859375 +68111 -0.584228515625 +68112 -0.24176025390625 +68113 -0.47930908203125 +68114 -0.14056396484375 +68115 -0.27935791015625 +68116 -0.00482177734375 +68117 -0.0089111328125 +68118 0.134368896484375 +68119 0.268798828125 +68120 0.2421875 +68121 0.482818603515625 +68122 0.304107666015625 +68123 0.60369873046875 +68124 0.3292236328125 +68125 0.650421142578125 +68126 0.337432861328125 +68127 0.66400146484375 +68128 0.32720947265625 +68129 0.6414794921875 +68130 0.293548583984375 +68131 0.572540283203125 +68132 0.256439208984375 +68133 0.498138427734375 +68134 0.226287841796875 +68135 0.439453125 +68136 0.192962646484375 +68137 0.375518798828125 +68138 0.14105224609375 +68139 0.274505615234375 +68140 0.0572509765625 +68141 0.1087646484375 +68142 -0.047393798828125 +68143 -0.099395751953125 +68144 -0.157196044921875 +68145 -0.3182373046875 +68146 -0.2725830078125 +68147 -0.5489501953125 +68148 -0.384735107421875 +68149 -0.7738037109375 +68150 -0.46771240234375 +68151 -0.86383056640625 +68152 -0.50518798828125 +68153 -0.870391845703125 +68154 -0.5057373046875 +68155 -0.86895751953125 +68156 -0.47576904296875 +68157 -0.861053466796875 +68158 -0.406829833984375 +68159 -0.765869140625 +68160 -0.293487548828125 +68161 -0.5301513671875 +68162 -0.1392822265625 +68163 -0.214691162109375 +68164 0.034637451171875 +68165 0.137359619140625 +68166 0.203125 +68167 0.474822998046875 +68168 0.34869384765625 +68169 0.76239013671875 +68170 0.458038330078125 +68171 0.867462158203125 +68172 0.53125 +68173 0.870361328125 +68174 0.56256103515625 +68175 0.86480712890625 +68176 0.554473876953125 +68177 0.831817626953125 +68178 0.518798828125 +68179 0.677581787109375 +68180 0.458343505859375 +68181 0.495880126953125 +68182 0.382110595703125 +68183 0.30767822265625 +68184 0.29119873046875 +68185 0.116180419921875 +68186 0.170135498046875 +68187 -0.110748291015625 +68188 0.015594482421875 +68189 -0.381805419921875 +68190 -0.15142822265625 +68191 -0.6572265625 +68192 -0.301605224609375 +68193 -0.857421875 +68194 -0.41387939453125 +68195 -0.870391845703125 +68196 -0.484649658203125 +68197 -0.870391845703125 +68198 -0.526947021484375 +68199 -0.86444091796875 +68200 -0.55804443359375 +68201 -0.85723876953125 +68202 -0.568878173828125 +68203 -0.790008544921875 +68204 -0.532928466796875 +68205 -0.62847900390625 +68206 -0.448577880859375 +68207 -0.3956298828125 +68208 -0.33184814453125 +68209 -0.126708984375 +68210 -0.19610595703125 +68211 0.150115966796875 +68212 -0.047088623046875 +68213 0.424041748046875 +68214 0.10198974609375 +68215 0.670623779296875 +68216 0.232147216796875 +68217 0.854522705078125 +68218 0.33465576171875 +68219 0.866485595703125 +68220 0.401947021484375 +68221 0.86920166015625 +68222 0.4427490234375 +68223 0.8653564453125 +68224 0.463531494140625 +68225 0.857147216796875 +68226 0.4627685546875 +68227 0.766845703125 +68228 0.442901611328125 +68229 0.628509521484375 +68230 0.400543212890625 +68231 0.462127685546875 +68232 0.348236083984375 +68233 0.297210693359375 +68234 0.2919921875 +68235 0.14862060546875 +68236 0.220672607421875 +68237 -0.00537109375 +68238 0.137939453125 +68239 -0.15753173828125 +68240 0.042083740234375 +68241 -0.31304931640625 +68242 -0.07366943359375 +68243 -0.48876953125 +68244 -0.18634033203125 +68245 -0.6416015625 +68246 -0.2838134765625 +68247 -0.751373291015625 +68248 -0.377227783203125 +68249 -0.84619140625 +68250 -0.459320068359375 +68251 -0.861297607421875 +68252 -0.513824462890625 +68253 -0.863250732421875 +68254 -0.525238037109375 +68255 -0.856597900390625 +68256 -0.499420166015625 +68257 -0.7498779296875 +68258 -0.464569091796875 +68259 -0.624542236328125 +68260 -0.409942626953125 +68261 -0.47808837890625 +68262 -0.3070068359375 +68263 -0.253387451171875 +68264 -0.17803955078125 +68265 0.003692626953125 +68266 -0.05645751953125 +68267 0.2257080078125 +68268 0.06378173828125 +68269 0.427154541015625 +68270 0.19842529296875 +68271 0.643218994140625 +68272 0.3426513671875 +68273 0.855926513671875 +68274 0.46807861328125 +68275 0.870361328125 +68276 0.5504150390625 +68277 0.870361328125 +68278 0.593048095703125 +68279 0.862762451171875 +68280 0.594512939453125 +68281 0.79669189453125 +68282 0.55010986328125 +68283 0.595794677734375 +68284 0.474029541015625 +68285 0.362152099609375 +68286 0.379974365234375 +68287 0.1270751953125 +68288 0.27825927734375 +68289 -0.086944580078125 +68290 0.169952392578125 +68291 -0.2784423828125 +68292 0.03814697265625 +68293 -0.484832763671875 +68294 -0.12646484375 +68295 -0.729583740234375 +68296 -0.299102783203125 +68297 -0.86688232421875 +68298 -0.44873046875 +68299 -0.870391845703125 +68300 -0.572845458984375 +68301 -0.86859130859375 +68302 -0.6702880859375 +68303 -0.86279296875 +68304 -0.723419189453125 +68305 -0.817962646484375 +68306 -0.7099609375 +68307 -0.6116943359375 +68308 -0.62640380859375 +68309 -0.3128662109375 +68310 -0.4891357421875 +68311 0.039398193359375 +68312 -0.30792236328125 +68313 0.422821044921875 +68314 -0.099029541015625 +68315 0.805145263671875 +68316 0.104217529296875 +68317 0.870361328125 +68318 0.273895263671875 +68319 0.870361328125 +68320 0.404144287109375 +68321 0.860015869140625 +68322 0.49102783203125 +68323 0.727935791015625 +68324 0.5316162109375 +68325 0.48114013671875 +68326 0.53753662109375 +68327 0.2059326171875 +68328 0.519622802734375 +68329 -0.06103515625 +68330 0.48260498046875 +68331 -0.29913330078125 +68332 0.4193115234375 +68333 -0.516204833984375 +68334 0.3221435546875 +68335 -0.7252197265625 +68336 0.2032470703125 +68337 -0.85980224609375 +68338 0.079437255859375 +68339 -0.870391845703125 +68340 -0.03466796875 +68341 -0.870391845703125 +68342 -0.115081787109375 +68343 -0.858062744140625 +68344 -0.159515380859375 +68345 -0.673004150390625 +68346 -0.193267822265625 +68347 -0.42694091796875 +68348 -0.2376708984375 +68349 -0.2100830078125 +68350 -0.2913818359375 +68351 -0.0362548828125 +68352 -0.339599609375 +68353 0.10943603515625 +68354 -0.372161865234375 +68355 0.23516845703125 +68356 -0.369873046875 +68357 0.373687744140625 +68358 -0.3336181640625 +68359 0.517791748046875 +68360 -0.292236328125 +68361 0.602783203125 +68362 -0.243621826171875 +68363 0.635711669921875 +68364 -0.172943115234375 +68365 0.655181884765625 +68366 -0.085205078125 +68367 0.65948486328125 +68368 0.015380859375 +68369 0.651275634765625 +68370 0.117095947265625 +68371 0.61846923828125 +68372 0.202484130859375 +68373 0.53753662109375 +68374 0.262725830078125 +68375 0.404144287109375 +68376 0.292877197265625 +68377 0.22186279296875 +68378 0.2930908203125 +68379 0.003997802734375 +68380 0.27130126953125 +68381 -0.22100830078125 +68382 0.2366943359375 +68383 -0.42449951171875 +68384 0.19891357421875 +68385 -0.579833984375 +68386 0.177459716796875 +68387 -0.641876220703125 +68388 0.16943359375 +68389 -0.6177978515625 +68390 0.1456298828125 +68391 -0.575531005859375 +68392 0.103973388671875 +68393 -0.526336669921875 +68394 0.068511962890625 +68395 -0.42645263671875 +68396 0.05218505859375 +68397 -0.2581787109375 +68398 0.0389404296875 +68399 -0.068695068359375 +68400 0.011688232421875 +68401 0.09222412109375 +68402 -0.020538330078125 +68403 0.232147216796875 +68404 -0.052703857421875 +68405 0.3509521484375 +68406 -0.097991943359375 +68407 0.410064697265625 +68408 -0.16949462890625 +68409 0.372955322265625 +68410 -0.257537841796875 +68411 0.2554931640625 +68412 -0.3382568359375 +68413 0.10711669921875 +68414 -0.402801513671875 +68415 -0.052886962890625 +68416 -0.434783935546875 +68417 -0.186279296875 +68418 -0.408935546875 +68419 -0.23291015625 +68420 -0.335968017578125 +68421 -0.209442138671875 +68422 -0.24627685546875 +68423 -0.174163818359375 +68424 -0.14404296875 +68425 -0.126739501953125 +68426 -0.02520751953125 +68427 -0.048126220703125 +68428 0.096954345703125 +68429 0.0426025390625 +68430 0.200775146484375 +68431 0.10748291015625 +68432 0.279876708984375 +68433 0.1409912109375 +68434 0.355682373046875 +68435 0.19708251953125 +68436 0.424896240234375 +68437 0.273651123046875 +68438 0.461944580078125 +68439 0.31768798828125 +68440 0.4718017578125 +68441 0.341094970703125 +68442 0.466033935546875 +68443 0.368011474609375 +68444 0.434326171875 +68445 0.37249755859375 +68446 0.354400634765625 +68447 0.30072021484375 +68448 0.228759765625 +68449 0.1517333984375 +68450 0.08807373046875 +68451 -0.01470947265625 +68452 -0.059173583984375 +68453 -0.1883544921875 +68454 -0.210784912109375 +68455 -0.372711181640625 +68456 -0.33856201171875 +68457 -0.51397705078125 +68458 -0.420745849609375 +68459 -0.57177734375 +68460 -0.451507568359375 +68461 -0.53948974609375 +68462 -0.436859130859375 +68463 -0.43511962890625 +68464 -0.392547607421875 +68465 -0.2962646484375 +68466 -0.3353271484375 +68467 -0.161102294921875 +68468 -0.271697998046875 +68469 -0.0435791015625 +68470 -0.200775146484375 +68471 0.060394287109375 +68472 -0.130706787109375 +68473 0.13665771484375 +68474 -0.070587158203125 +68475 0.170135498046875 +68476 -0.021026611328125 +68477 0.16552734375 +68478 0.0306396484375 +68479 0.15728759765625 +68480 0.083740234375 +68481 0.150787353515625 +68482 0.124237060546875 +68483 0.12200927734375 +68484 0.153472900390625 +68485 0.080108642578125 +68486 0.180908203125 +68487 0.05126953125 +68488 0.217071533203125 +68489 0.062896728515625 +68490 0.2503662109375 +68491 0.09271240234375 +68492 0.25830078125 +68493 0.092987060546875 +68494 0.247528076171875 +68495 0.07855224609375 +68496 0.22540283203125 +68497 0.06427001953125 +68498 0.18609619140625 +68499 0.0347900390625 +68500 0.130462646484375 +68501 -0.01171875 +68502 0.06939697265625 +68503 -0.056060791015625 +68504 0.0247802734375 +68505 -0.055511474609375 +68506 -0.000946044921875 +68507 -0.010467529296875 +68508 -0.02984619140625 +68509 0.02508544921875 +68510 -0.071136474609375 +68511 0.025665283203125 +68512 -0.110748291015625 +68513 0.017333984375 +68514 -0.14605712890625 +68515 0.00189208984375 +68516 -0.180816650390625 +68517 -0.03173828125 +68518 -0.208770751953125 +68519 -0.071502685546875 +68520 -0.237823486328125 +68521 -0.13543701171875 +68522 -0.26666259765625 +68523 -0.219970703125 +68524 -0.28485107421875 +68525 -0.300506591796875 +68526 -0.2933349609375 +68527 -0.376312255859375 +68528 -0.27947998046875 +68529 -0.416107177734375 +68530 -0.22296142578125 +68531 -0.371124267578125 +68532 -0.126312255859375 +68533 -0.242279052734375 +68534 -0.00994873046875 +68535 -0.069732666015625 +68536 0.114532470703125 +68537 0.125640869140625 +68538 0.231048583984375 +68539 0.31268310546875 +68540 0.321441650390625 +68541 0.45501708984375 +68542 0.385498046875 +68543 0.554779052734375 +68544 0.421783447265625 +68545 0.61065673828125 +68546 0.424591064453125 +68547 0.610931396484375 +68548 0.383026123046875 +68549 0.531463623046875 +68550 0.304901123046875 +68551 0.3883056640625 +68552 0.21539306640625 +68553 0.23468017578125 +68554 0.127044677734375 +68555 0.095245361328125 +68556 0.053192138671875 +68557 -0.00396728515625 +68558 0.002044677734375 +68559 -0.04852294921875 +68560 -0.0322265625 +68561 -0.055145263671875 +68562 -0.071624755859375 +68563 -0.0758056640625 +68564 -0.12738037109375 +68565 -0.138702392578125 +68566 -0.18231201171875 +68567 -0.209197998046875 +68568 -0.236083984375 +68569 -0.289031982421875 +68570 -0.2882080078125 +68571 -0.37884521484375 +68572 -0.328094482421875 +68573 -0.456329345703125 +68574 -0.353363037109375 +68575 -0.51641845703125 +68576 -0.346160888671875 +68577 -0.519287109375 +68578 -0.3040771484375 +68579 -0.458251953125 +68580 -0.251556396484375 +68581 -0.384796142578125 +68582 -0.2010498046875 +68583 -0.323699951171875 +68584 -0.15130615234375 +68585 -0.269287109375 +68586 -0.091705322265625 +68587 -0.1951904296875 +68588 -0.0230712890625 +68589 -0.100006103515625 +68590 0.040985107421875 +68591 -0.01055908203125 +68592 0.113037109375 +68593 0.1033935546875 +68594 0.195404052734375 +68595 0.24908447265625 +68596 0.26300048828125 +68597 0.373199462890625 +68598 0.30731201171875 +68599 0.45806884765625 +68600 0.33172607421875 +68601 0.511474609375 +68602 0.35101318359375 +68603 0.565399169921875 +68604 0.36175537109375 +68605 0.61138916015625 +68606 0.33740234375 +68607 0.5897216796875 +68608 0.274505615234375 +68609 0.4906005859375 +68610 0.182220458984375 +68611 0.33148193359375 +68612 0.077728271484375 +68613 0.147796630859375 +68614 -0.01898193359375 +68615 -0.01873779296875 +68616 -0.094207763671875 +68617 -0.140289306640625 +68618 -0.135711669921875 +68619 -0.191986083984375 +68620 -0.14727783203125 +68621 -0.184295654296875 +68622 -0.14825439453125 +68623 -0.161834716796875 +68624 -0.157012939453125 +68625 -0.166595458984375 +68626 -0.1712646484375 +68627 -0.19390869140625 +68628 -0.182281494140625 +68629 -0.22442626953125 +68630 -0.200103759765625 +68631 -0.279754638671875 +68632 -0.2158203125 +68633 -0.3389892578125 +68634 -0.20867919921875 +68635 -0.3543701171875 +68636 -0.189544677734375 +68637 -0.348175048828125 +68638 -0.161865234375 +68639 -0.32598876953125 +68640 -0.11334228515625 +68641 -0.2581787109375 +68642 -0.042755126953125 +68643 -0.139801025390625 +68644 0.042449951171875 +68645 0.014617919921875 +68646 0.1141357421875 +68647 0.144378662109375 +68648 0.158843994140625 +68649 0.221038818359375 +68650 0.1878662109375 +68651 0.27069091796875 +68652 0.201263427734375 +68653 0.294036865234375 +68654 0.208282470703125 +68655 0.311767578125 +68656 0.215911865234375 +68657 0.339141845703125 +68658 0.217010498046875 +68659 0.360260009765625 +68660 0.205657958984375 +68661 0.360504150390625 +68662 0.1693115234375 +68663 0.308380126953125 +68664 0.099517822265625 +68665 0.18170166015625 +68666 0.007598876953125 +68667 0.0047607421875 +68668 -0.085601806640625 +68669 -0.17559814453125 +68670 -0.160064697265625 +68671 -0.3143310546875 +68672 -0.19647216796875 +68673 -0.36785888671875 +68674 -0.20526123046875 +68675 -0.36248779296875 +68676 -0.205108642578125 +68677 -0.343536376953125 +68678 -0.19183349609375 +68679 -0.3018798828125 +68680 -0.16265869140625 +68681 -0.231414794921875 +68682 -0.11151123046875 +68683 -0.117645263671875 +68684 -0.05242919921875 +68685 0.007049560546875 +68686 -0.009002685546875 +68687 0.087982177734375 +68688 0.024200439453125 +68689 0.13946533203125 +68690 0.051910400390625 +68691 0.17425537109375 +68692 0.07159423828125 +68693 0.188201904296875 +68694 0.078216552734375 +68695 0.171234130859375 +68696 0.0689697265625 +68697 0.118438720703125 +68698 0.054718017578125 +68699 0.05706787109375 +68700 0.035736083984375 +68701 -0.010711669921875 +68702 0.008758544921875 +68703 -0.0914306640625 +68704 -0.016815185546875 +68705 -0.162322998046875 +68706 -0.028961181640625 +68707 -0.194549560546875 +68708 -0.011199951171875 +68709 -0.1492919921875 +68710 0.038665771484375 +68711 -0.02166748046875 +68712 0.093719482421875 +68713 0.124053955078125 +68714 0.121856689453125 +68715 0.211151123046875 +68716 0.12396240234375 +68717 0.240447998046875 +68718 0.11346435546875 +68719 0.242218017578125 +68720 0.094970703125 +68721 0.2257080078125 +68722 0.070556640625 +68723 0.194366455078125 +68724 0.026947021484375 +68725 0.115509033203125 +68726 -0.02520751953125 +68727 0.0128173828125 +68728 -0.06011962890625 +68729 -0.053802490234375 +68730 -0.088623046875 +68731 -0.110626220703125 +68732 -0.1282958984375 +68733 -0.199493408203125 +68734 -0.1680908203125 +68735 -0.29437255859375 +68736 -0.18133544921875 +68737 -0.33221435546875 +68738 -0.154144287109375 +68739 -0.27972412109375 +68740 -0.10736083984375 +68741 -0.185333251953125 +68742 -0.074981689453125 +68743 -0.128204345703125 +68744 -0.06060791015625 +68745 -0.115692138671875 +68746 -0.051483154296875 +68747 -0.116455078125 +68748 -0.0377197265625 +68749 -0.105926513671875 +68750 -0.007049560546875 +68751 -0.053955078125 +68752 0.044036865234375 +68753 0.048797607421875 +68754 0.0960693359375 +68755 0.157318115234375 +68756 0.123504638671875 +68757 0.212005615234375 +68758 0.1285400390625 +68759 0.218475341796875 +68760 0.13677978515625 +68761 0.23724365234375 +68762 0.163970947265625 +68763 0.30535888671875 +68764 0.192626953125 +68765 0.38128662109375 +68766 0.197296142578125 +68767 0.404449462890625 +68768 0.186614990234375 +68769 0.3944091796875 +68770 0.176849365234375 +68771 0.3885498046875 +68772 0.15814208984375 +68773 0.362640380859375 +68774 0.1126708984375 +68775 0.27362060546875 +68776 0.03900146484375 +68777 0.11712646484375 +68778 -0.040435791015625 +68779 -0.054901123046875 +68780 -0.103424072265625 +68781 -0.19085693359375 +68782 -0.1475830078125 +68783 -0.28570556640625 +68784 -0.17266845703125 +68785 -0.339263916015625 +68786 -0.189605712890625 +68787 -0.3775634765625 +68788 -0.217559814453125 +68789 -0.445709228515625 +68790 -0.252960205078125 +68791 -0.535064697265625 +68792 -0.2889404296875 +68793 -0.629058837890625 +68794 -0.31298828125 +68795 -0.697601318359375 +68796 -0.309814453125 +68797 -0.70391845703125 +68798 -0.27740478515625 +68799 -0.6424560546875 +68800 -0.20684814453125 +68801 -0.491241455078125 +68802 -0.10504150390625 +68803 -0.265716552734375 +68804 0.003143310546875 +68805 -0.023712158203125 +68806 0.103424072265625 +68807 0.201751708984375 +68808 0.1807861328125 +68809 0.375823974609375 +68810 0.2293701171875 +68811 0.485076904296875 +68812 0.26580810546875 +68813 0.56884765625 +68814 0.293304443359375 +68815 0.634765625 +68816 0.292755126953125 +68817 0.63763427734375 +68818 0.259490966796875 +68819 0.5660400390625 +68820 0.215728759765625 +68821 0.4720458984375 +68822 0.183441162109375 +68823 0.40692138671875 +68824 0.16595458984375 +68825 0.3778076171875 +68826 0.1602783203125 +68827 0.376953125 +68828 0.15301513671875 +68829 0.371978759765625 +68830 0.123321533203125 +68831 0.313140869140625 +68832 0.06463623046875 +68833 0.184417724609375 +68834 -0.01202392578125 +68835 0.011199951171875 +68836 -0.09149169921875 +68837 -0.171051025390625 +68838 -0.1630859375 +68839 -0.33740234375 +68840 -0.220062255859375 +68841 -0.47198486328125 +68842 -0.25634765625 +68843 -0.560394287109375 +68844 -0.2626953125 +68845 -0.58056640625 +68846 -0.245635986328125 +68847 -0.54754638671875 +68848 -0.22540283203125 +68849 -0.508575439453125 +68850 -0.200469970703125 +68851 -0.459503173828125 +68852 -0.16851806640625 +68853 -0.394378662109375 +68854 -0.146514892578125 +68855 -0.35260009765625 +68856 -0.1251220703125 +68857 -0.31170654296875 +68858 -0.073089599609375 +68859 -0.197418212890625 +68860 0.010101318359375 +68861 -0.007965087890625 +68862 0.103485107421875 +68863 0.207489013671875 +68864 0.1900634765625 +68865 0.409210205078125 +68866 0.25860595703125 +68867 0.57208251953125 +68868 0.296783447265625 +68869 0.66595458984375 +68870 0.29248046875 +68871 0.65875244140625 +68872 0.252838134765625 +68873 0.56744384765625 +68874 0.19378662109375 +68875 0.431396484375 +68876 0.133087158203125 +68877 0.29443359375 +68878 0.081451416015625 +68879 0.182464599609375 +68880 0.02691650390625 +68881 0.06365966796875 +68882 -0.035491943359375 +68883 -0.075958251953125 +68884 -0.086944580078125 +68885 -0.189422607421875 +68886 -0.12518310546875 +68887 -0.271942138671875 +68888 -0.157379150390625 +68889 -0.342529296875 +68890 -0.168853759765625 +68891 -0.364166259765625 +68892 -0.15576171875 +68893 -0.327239990234375 +68894 -0.135833740234375 +68895 -0.2769775390625 +68896 -0.12493896484375 +68897 -0.253692626953125 +68898 -0.117828369140625 +68899 -0.24365234375 +68900 -0.095733642578125 +68901 -0.1983642578125 +68902 -0.058319091796875 +68903 -0.116241455078125 +68904 -0.021392822265625 +68905 -0.036834716796875 +68906 0.012725830078125 +68907 0.034881591796875 +68908 0.040679931640625 +68909 0.09124755859375 +68910 0.053009033203125 +68911 0.10888671875 +68912 0.064239501953125 +68913 0.125518798828125 +68914 0.080596923828125 +68915 0.15771484375 +68916 0.09124755859375 +68917 0.17828369140625 +68918 0.089752197265625 +68919 0.17108154296875 +68920 0.07366943359375 +68921 0.129974365234375 +68922 0.0538330078125 +68923 0.082427978515625 +68924 0.030029296875 +68925 0.027679443359375 +68926 -0.00982666015625 +68927 -0.065643310546875 +68928 -0.050567626953125 +68929 -0.15936279296875 +68930 -0.076141357421875 +68931 -0.21307373046875 +68932 -0.089385986328125 +68933 -0.234649658203125 +68934 -0.080657958984375 +68935 -0.2001953125 +68936 -0.05340576171875 +68937 -0.119171142578125 +68938 -0.020416259765625 +68939 -0.024749755859375 +68940 0.01959228515625 +68941 0.085784912109375 +68942 0.053314208984375 +68943 0.178131103515625 +68944 0.06646728515625 +68945 0.215576171875 +68946 0.064361572265625 +68947 0.211456298828125 +68948 0.05072021484375 +68949 0.17523193359375 +68950 0.034027099609375 +68951 0.128753662109375 +68952 0.025909423828125 +68953 0.1019287109375 +68954 0.018218994140625 +68955 0.0743408203125 +68956 0.009674072265625 +68957 0.04327392578125 +68958 0.0115966796875 +68959 0.038177490234375 +68960 0.030517578125 +68961 0.076263427734375 +68962 0.05975341796875 +68963 0.14105224609375 +68964 0.081024169921875 +68965 0.186431884765625 +68966 0.08489990234375 +68967 0.188812255859375 +68968 0.067657470703125 +68969 0.1390380859375 +68970 0.031036376953125 +68971 0.041778564453125 +68972 -0.01580810546875 +68973 -0.079437255859375 +68974 -0.070831298828125 +68975 -0.219390869140625 +68976 -0.129974365234375 +68977 -0.367828369140625 +68978 -0.18145751953125 +68979 -0.494873046875 +68980 -0.207794189453125 +68981 -0.556243896484375 +68982 -0.19189453125 +68983 -0.508697509765625 +68984 -0.14276123046875 +68985 -0.3756103515625 +68986 -0.08453369140625 +68987 -0.218902587890625 +68988 -0.026885986328125 +68989 -0.063751220703125 +68990 0.030975341796875 +68991 0.091552734375 +68992 0.084930419921875 +68993 0.23602294921875 +68994 0.124664306640625 +68995 0.342987060546875 +68996 0.143524169921875 +68997 0.39520263671875 +68998 0.14031982421875 +68999 0.389373779296875 +69000 0.11456298828125 +69001 0.324249267578125 +69002 0.075775146484375 +69003 0.224090576171875 +69004 0.03778076171875 +69005 0.124267578125 +69006 0.005279541015625 +69007 0.037078857421875 +69008 -0.01104736328125 +69009 -0.010101318359375 +69010 -0.01220703125 +69011 -0.019439697265625 +69012 -0.01080322265625 +69013 -0.022796630859375 +69014 0.000244140625 +69015 -0.001556396484375 +69016 0.025482177734375 +69017 0.056304931640625 +69018 0.04754638671875 +69019 0.106719970703125 +69020 0.045623779296875 +69021 0.096893310546875 +69022 0.025848388671875 +69023 0.042694091796875 +69024 0.002960205078125 +69025 -0.018035888671875 +69026 -0.01934814453125 +69027 -0.07586669921875 +69028 -0.036651611328125 +69029 -0.11944580078125 +69030 -0.05322265625 +69031 -0.15972900390625 +69032 -0.0712890625 +69033 -0.202606201171875 +69034 -0.0909423828125 +69035 -0.24859619140625 +69036 -0.115020751953125 +69037 -0.30517578125 +69038 -0.139404296875 +69039 -0.36212158203125 +69040 -0.15301513671875 +69041 -0.39141845703125 +69042 -0.140899658203125 +69043 -0.35528564453125 +69044 -0.10150146484375 +69045 -0.249969482421875 +69046 -0.04156494140625 +69047 -0.092864990234375 +69048 0.0284423828125 +69049 0.08905029296875 +69050 0.0848388671875 +69051 0.2352294921875 +69052 0.11712646484375 +69053 0.318817138671875 +69054 0.1326904296875 +69055 0.358642578125 +69056 0.128814697265625 +69057 0.347747802734375 +69058 0.105255126953125 +69059 0.28564453125 +69060 0.081878662109375 +69061 0.223175048828125 +69062 0.072906494140625 +69063 0.196746826171875 +69064 0.06787109375 +69065 0.179840087890625 +69066 0.060028076171875 +69067 0.155548095703125 +69068 0.060028076171875 +69069 0.151214599609375 +69070 0.063873291015625 +69071 0.156951904296875 +69072 0.055419921875 +69073 0.13177490234375 +69074 0.044464111328125 +69075 0.100799560546875 +69076 0.03997802734375 +69077 0.087127685546875 +69078 0.027862548828125 +69079 0.05487060546875 +69080 0.00299072265625 +69081 -0.009002685546875 +69082 -0.034393310546875 +69083 -0.10400390625 +69084 -0.084014892578125 +69085 -0.229400634765625 +69086 -0.13421630859375 +69087 -0.35552978515625 +69088 -0.1690673828125 +69089 -0.441925048828125 +69090 -0.1827392578125 +69091 -0.473846435546875 +69092 -0.18048095703125 +69093 -0.464813232421875 +69094 -0.16387939453125 +69095 -0.419097900390625 +69096 -0.131927490234375 +69097 -0.334320068359375 +69098 -0.091400146484375 +69099 -0.227935791015625 +69100 -0.051483154296875 +69101 -0.12347412109375 +69102 -0.014739990234375 +69103 -0.02764892578125 +69104 0.025970458984375 +69105 0.077667236328125 +69106 0.078826904296875 +69107 0.2132568359375 +69108 0.14764404296875 +69109 0.38885498046875 +69110 0.223907470703125 +69111 0.582794189453125 +69112 0.283660888671875 +69113 0.734039306640625 +69114 0.31024169921875 +69115 0.800140380859375 +69116 0.302520751953125 +69117 0.7783203125 +69118 0.25909423828125 +69119 0.6651611328125 +69120 0.180023193359375 +69121 0.45965576171875 +69122 0.080474853515625 +69123 0.199188232421875 +69124 -0.01483154296875 +69125 -0.050689697265625 +69126 -0.085296630859375 +69127 -0.23297119140625 +69128 -0.12451171875 +69129 -0.33013916015625 +69130 -0.141845703125 +69131 -0.368408203125 +69132 -0.1484375 +69133 -0.378936767578125 +69134 -0.149749755859375 +69135 -0.376983642578125 +69136 -0.15191650390625 +69137 -0.37969970703125 +69138 -0.156494140625 +69139 -0.391510009765625 +69140 -0.153778076171875 +69141 -0.385345458984375 +69142 -0.136871337890625 +69143 -0.3419189453125 +69144 -0.113677978515625 +69145 -0.28289794921875 +69146 -0.09991455078125 +69147 -0.251617431640625 +69148 -0.10223388671875 +69149 -0.266143798828125 +69150 -0.1016845703125 +69151 -0.273345947265625 +69152 -0.078094482421875 +69153 -0.216796875 +69154 -0.043060302734375 +69155 -0.128265380859375 +69156 -0.01849365234375 +69157 -0.068145751953125 +69158 -0.006927490234375 +69159 -0.0430908203125 +69160 0.00177001953125 +69161 -0.024444580078125 +69162 0.0194091796875 +69163 0.020721435546875 +69164 0.05743408203125 +69165 0.124481201171875 +69166 0.10540771484375 +69167 0.25787353515625 +69168 0.1483154296875 +69169 0.379119873046875 +69170 0.1832275390625 +69171 0.47991943359375 +69172 0.198699951171875 +69173 0.5281982421875 +69174 0.19024658203125 +69175 0.511138916015625 +69176 0.16790771484375 +69177 0.456207275390625 +69178 0.147674560546875 +69179 0.407470703125 +69180 0.136474609375 +69181 0.383758544921875 +69182 0.124298095703125 +69183 0.35687255859375 +69184 0.105865478515625 +69185 0.31182861328125 +69186 0.08209228515625 +69187 0.250885009765625 +69188 0.04998779296875 +69189 0.1654052734375 +69190 0.002349853515625 +69191 0.035247802734375 +69192 -0.0616455078125 +69193 -0.142059326171875 +69194 -0.130889892578125 +69195 -0.33563232421875 +69196 -0.201507568359375 +69197 -0.5345458984375 +69198 -0.2674560546875 +69199 -0.72186279296875 +69200 -0.306915283203125 +69201 -0.836669921875 +69202 -0.30328369140625 +69203 -0.8326416015625 +69204 -0.26385498046875 +69205 -0.7296142578125 +69206 -0.20855712890625 +69207 -0.582550048828125 +69208 -0.155059814453125 +69209 -0.440093994140625 +69210 -0.111419677734375 +69211 -0.324310302734375 +69212 -0.0655517578125 +69213 -0.20147705078125 +69214 -0.007843017578125 +69215 -0.044647216796875 +69216 0.04644775390625 +69217 0.103973388671875 +69218 0.0821533203125 +69219 0.202392578125 +69220 0.104248046875 +69221 0.264495849609375 +69222 0.130279541015625 +69223 0.338897705078125 +69224 0.1668701171875 +69225 0.443817138671875 +69226 0.201812744140625 +69227 0.545074462890625 +69228 0.226043701171875 +69229 0.6173095703125 +69230 0.236785888671875 +69231 0.6524658203125 +69232 0.23876953125 +69233 0.66339111328125 +69234 0.234283447265625 +69235 0.6561279296875 +69236 0.21478271484375 +69237 0.606781005859375 +69238 0.175262451171875 +69239 0.501190185546875 +69240 0.120635986328125 +69241 0.352783203125 +69242 0.056365966796875 +69243 0.176544189453125 +69244 -0.020111083984375 +69245 -0.034820556640625 +69246 -0.1004638671875 +69247 -0.258209228515625 +69248 -0.166290283203125 +69249 -0.44244384765625 +69250 -0.21319580078125 +69251 -0.5753173828125 +69252 -0.23956298828125 +69253 -0.65203857421875 +69254 -0.23431396484375 +69255 -0.641632080078125 +69256 -0.204071044921875 +69257 -0.562164306640625 +69258 -0.164886474609375 +69259 -0.458038330078125 +69260 -0.12451171875 +69261 -0.350555419921875 +69262 -0.090545654296875 +69263 -0.260528564453125 +69264 -0.064544677734375 +69265 -0.192108154296875 +69266 -0.045379638671875 +69267 -0.141937255859375 +69268 -0.0302734375 +69269 -0.1021728515625 +69270 -0.015716552734375 +69271 -0.062896728515625 +69272 0.002655029296875 +69273 -0.011932373046875 +69274 0.02923583984375 +69275 0.062835693359375 +69276 0.059478759765625 +69277 0.148712158203125 +69278 0.09197998046875 +69279 0.241729736328125 +69280 0.12939453125 +69281 0.34912109375 +69282 0.16693115234375 +69283 0.457305908203125 +69284 0.19659423828125 +69285 0.54388427734375 +69286 0.205535888671875 +69287 0.5728759765625 +69288 0.180267333984375 +69289 0.506591796875 +69290 0.123077392578125 +69291 0.351226806640625 +69292 0.04833984375 +69293 0.146514892578125 +69294 -0.025054931640625 +69295 -0.05523681640625 +69296 -0.08343505859375 +69297 -0.21624755859375 +69298 -0.126251220703125 +69299 -0.334930419921875 +69300 -0.150482177734375 +69301 -0.402984619140625 +69302 -0.163665771484375 +69303 -0.4412841796875 +69304 -0.182403564453125 +69305 -0.49578857421875 +69306 -0.2044677734375 +69307 -0.5601806640625 +69308 -0.217803955078125 +69309 -0.600738525390625 +69310 -0.210540771484375 +69311 -0.584228515625 +69312 -0.17144775390625 +69313 -0.47930908203125 +69314 -0.098236083984375 +69315 -0.27935791015625 +69316 0.00018310546875 +69317 -0.0089111328125 +69318 0.100982666015625 +69319 0.268798828125 +69320 0.1785888671875 +69321 0.482818603515625 +69322 0.222381591796875 +69323 0.60369873046875 +69324 0.239166259765625 +69325 0.650421142578125 +69326 0.243743896484375 +69327 0.66400146484375 +69328 0.235076904296875 +69329 0.6414794921875 +69330 0.20947265625 +69331 0.572540283203125 +69332 0.1817626953125 +69333 0.498138427734375 +69334 0.159637451171875 +69335 0.439453125 +69336 0.135589599609375 +69337 0.375518798828125 +69338 0.09820556640625 +69339 0.274505615234375 +69340 0.03759765625 +69341 0.1087646484375 +69342 -0.03814697265625 +69343 -0.099395751953125 +69344 -0.1175537109375 +69345 -0.3182373046875 +69346 -0.2010498046875 +69347 -0.5489501953125 +69348 -0.282196044921875 +69349 -0.7738037109375 +69350 -0.341949462890625 +69351 -0.86383056640625 +69352 -0.36834716796875 +69353 -0.870391845703125 +69354 -0.367767333984375 +69355 -0.86895751953125 +69356 -0.345001220703125 +69357 -0.861053466796875 +69358 -0.293853759765625 +69359 -0.765869140625 +69360 -0.210296630859375 +69361 -0.5301513671875 +69362 -0.096923828125 +69363 -0.214691162109375 +69364 0.03070068359375 +69365 0.137359619140625 +69366 0.154052734375 +69367 0.474822998046875 +69368 0.26031494140625 +69369 0.76239013671875 +69370 0.3397216796875 +69371 0.867462158203125 +69372 0.392425537109375 +69373 0.870361328125 +69374 0.414215087890625 +69375 0.86480712890625 +69376 0.4068603515625 +69377 0.831817626953125 +69378 0.3790283203125 +69379 0.677581787109375 +69380 0.332916259765625 +69381 0.495880126953125 +69382 0.27496337890625 +69383 0.30767822265625 +69384 0.206329345703125 +69385 0.116180419921875 +69386 0.1170654296875 +69387 -0.110748291015625 +69388 0.005401611328125 +69389 -0.381805419921875 +69390 -0.114105224609375 +69391 -0.6572265625 +69392 -0.22137451171875 +69393 -0.857421875 +69394 -0.301910400390625 +69395 -0.870391845703125 +69396 -0.35308837890625 +69397 -0.870391845703125 +69398 -0.383514404296875 +69399 -0.86444091796875 +69400 -0.40472412109375 +69401 -0.85723876953125 +69402 -0.41070556640625 +69403 -0.790008544921875 +69404 -0.38372802734375 +69405 -0.62847900390625 +69406 -0.322906494140625 +69407 -0.3956298828125 +69408 -0.2392578125 +69409 -0.126708984375 +69410 -0.14208984375 +69411 0.150115966796875 +69412 -0.035614013671875 +69413 0.424041748046875 +69414 0.0709228515625 +69415 0.670623779296875 +69416 0.1644287109375 +69417 0.854522705078125 +69418 0.238739013671875 +69419 0.866485595703125 +69420 0.288482666015625 +69421 0.86920166015625 +69422 0.319305419921875 +69423 0.8653564453125 +69424 0.33538818359375 +69425 0.857147216796875 +69426 0.33563232421875 +69427 0.766845703125 +69428 0.3216552734375 +69429 0.628509521484375 +69430 0.291259765625 +69431 0.462127685546875 +69432 0.2530517578125 +69433 0.297210693359375 +69434 0.21124267578125 +69435 0.14862060546875 +69436 0.158599853515625 +69437 -0.00537109375 +69438 0.097869873046875 +69439 -0.15753173828125 +69440 0.028167724609375 +69441 -0.31304931640625 +69442 -0.05474853515625 +69443 -0.48876953125 +69444 -0.135162353515625 +69445 -0.6416015625 +69446 -0.20465087890625 +69447 -0.751373291015625 +69448 -0.270538330078125 +69449 -0.84619140625 +69450 -0.3277587890625 +69451 -0.861297607421875 +69452 -0.365325927734375 +69453 -0.863250732421875 +69454 -0.372802734375 +69455 -0.856597900390625 +69456 -0.354156494140625 +69457 -0.7498779296875 +69458 -0.328460693359375 +69459 -0.624542236328125 +69460 -0.28863525390625 +69461 -0.47808837890625 +69462 -0.2156982421875 +69463 -0.253387451171875 +69464 -0.124847412109375 +69465 0.003692626953125 +69466 -0.038787841796875 +69467 0.2257080078125 +69468 0.046295166015625 +69469 0.427154541015625 +69470 0.1407470703125 +69471 0.643218994140625 +69472 0.241119384765625 +69473 0.855926513671875 +69474 0.328155517578125 +69475 0.870361328125 +69476 0.385406494140625 +69477 0.870361328125 +69478 0.415069580078125 +69479 0.862762451171875 +69480 0.4161376953125 +69481 0.79669189453125 +69482 0.385467529296875 +69483 0.595794677734375 +69484 0.332672119140625 +69485 0.362152099609375 +69486 0.26708984375 +69487 0.1270751953125 +69488 0.19580078125 +69489 -0.086944580078125 +69490 0.11968994140625 +69491 -0.2784423828125 +69492 0.027587890625 +69493 -0.484832763671875 +69494 -0.0865478515625 +69495 -0.729583740234375 +69496 -0.205902099609375 +69497 -0.86688232421875 +69498 -0.309417724609375 +69499 -0.870391845703125 +69500 -0.395263671875 +69501 -0.86859130859375 +69502 -0.4625244140625 +69503 -0.86279296875 +69504 -0.499298095703125 +69505 -0.817962646484375 +69506 -0.490570068359375 +69507 -0.6116943359375 +69508 -0.4339599609375 +69509 -0.3128662109375 +69510 -0.340545654296875 +69511 0.039398193359375 +69512 -0.21697998046875 +69513 0.422821044921875 +69514 -0.074310302734375 +69515 0.805145263671875 +69516 0.06494140625 +69517 0.870361328125 +69518 0.18182373046875 +69519 0.870361328125 +69520 0.27227783203125 +69521 0.860015869140625 +69522 0.33349609375 +69523 0.727935791015625 +69524 0.363311767578125 +69525 0.48114013671875 +69526 0.369415283203125 +69527 0.2059326171875 +69528 0.3590087890625 +69529 -0.06103515625 +69530 0.335174560546875 +69531 -0.29913330078125 +69532 0.29302978515625 +69533 -0.516204833984375 +69534 0.227508544921875 +69535 -0.7252197265625 +69536 0.14678955078125 +69537 -0.85980224609375 +69538 0.062255859375 +69539 -0.870391845703125 +69540 -0.01617431640625 +69541 -0.870391845703125 +69542 -0.072296142578125 +69543 -0.858062744140625 +69544 -0.10443115234375 +69545 -0.673004150390625 +69546 -0.1295166015625 +69547 -0.42694091796875 +69548 -0.161712646484375 +69549 -0.2100830078125 +69550 -0.199981689453125 +69551 -0.0362548828125 +69552 -0.234466552734375 +69553 0.10943603515625 +69554 -0.25836181640625 +69555 0.23516845703125 +69556 -0.25787353515625 +69557 0.373687744140625 +69558 -0.233489990234375 +69559 0.517791748046875 +69560 -0.205810546875 +69561 0.602783203125 +69562 -0.17315673828125 +69563 0.635711669921875 +69564 -0.12469482421875 +69565 0.655181884765625 +69566 -0.063873291015625 +69567 0.65948486328125 +69568 0.00640869140625 +69569 0.651275634765625 +69570 0.07781982421875 +69571 0.61846923828125 +69572 0.13787841796875 +69573 0.53753662109375 +69574 0.180328369140625 +69575 0.404144287109375 +69576 0.201629638671875 +69577 0.22186279296875 +69578 0.201934814453125 +69579 0.003997802734375 +69580 0.1868896484375 +69581 -0.22100830078125 +69582 0.1630859375 +69583 -0.42449951171875 +69584 0.137359619140625 +69585 -0.579833984375 +69586 0.123626708984375 +69587 -0.641876220703125 +69588 0.1197509765625 +69589 -0.6177978515625 +69590 0.104583740234375 +69591 -0.575531005859375 +69592 0.0765380859375 +69593 -0.526336669921875 +69594 0.05279541015625 +69595 -0.42645263671875 +69596 0.042572021484375 +69597 -0.2581787109375 +69598 0.03424072265625 +69599 -0.068695068359375 +69600 0.015472412109375 +69601 0.09222412109375 +69602 -0.00732421875 +69603 0.232147216796875 +69604 -0.030487060546875 +69605 0.3509521484375 +69606 -0.0634765625 +69607 0.410064697265625 +69608 -0.11566162109375 +69609 0.372955322265625 +69610 -0.180023193359375 +69611 0.2554931640625 +69612 -0.2393798828125 +69613 0.10711669921875 +69614 -0.2872314453125 +69615 -0.052886962890625 +69616 -0.311737060546875 +69617 -0.186279296875 +69618 -0.294647216796875 +69619 -0.23291015625 +69620 -0.24359130859375 +69621 -0.209442138671875 +69622 -0.180328369140625 +69623 -0.174163818359375 +69624 -0.10784912109375 +69625 -0.126739501953125 +69626 -0.023162841796875 +69627 -0.048126220703125 +69628 0.064178466796875 +69629 0.0426025390625 +69630 0.138671875 +69631 0.10748291015625 +69632 0.195220947265625 +69633 0.1409912109375 +69634 0.24847412109375 +69635 0.19708251953125 +69636 0.29681396484375 +69637 0.273651123046875 +69638 0.32318115234375 +69639 0.31768798828125 +69640 0.330718994140625 +69641 0.341094970703125 +69642 0.326934814453125 +69643 0.368011474609375 +69644 0.30499267578125 +69645 0.37249755859375 +69646 0.250335693359375 +69647 0.30072021484375 +69648 0.16473388671875 +69649 0.1517333984375 +69650 0.06854248046875 +69651 -0.01470947265625 +69652 -0.032470703125 +69653 -0.1883544921875 +69654 -0.136627197265625 +69655 -0.372711181640625 +69656 -0.225128173828125 +69657 -0.51397705078125 +69658 -0.28338623046875 +69659 -0.57177734375 +69660 -0.307342529296875 +69661 -0.53948974609375 +69662 -0.30078125 +69663 -0.43511962890625 +69664 -0.27386474609375 +69665 -0.2962646484375 +69666 -0.237548828125 +69667 -0.161102294921875 +69668 -0.196075439453125 +69669 -0.0435791015625 +69670 -0.148834228515625 +69671 0.060394287109375 +69672 -0.10125732421875 +69673 0.13665771484375 +69674 -0.0594482421875 +69675 0.170135498046875 +69676 -0.023895263671875 +69677 0.16552734375 +69678 0.013519287109375 +69679 0.15728759765625 +69680 0.052154541015625 +69681 0.150787353515625 +69682 0.082550048828125 +69683 0.12200927734375 +69684 0.105377197265625 +69685 0.080108642578125 +69686 0.126678466796875 +69687 0.05126953125 +69688 0.153228759765625 +69689 0.062896728515625 +69690 0.17724609375 +69691 0.09271240234375 +69692 0.183807373046875 +69693 0.092987060546875 +69694 0.177276611328125 +69695 0.07855224609375 +69696 0.1624755859375 +69697 0.06427001953125 +69698 0.135589599609375 +69699 0.0347900390625 +69700 0.0972900390625 +69701 -0.01171875 +69702 0.054840087890625 +69703 -0.056060791015625 +69704 0.022796630859375 +69705 -0.055511474609375 +69706 0.00286865234375 +69707 -0.010467529296875 +69708 -0.01922607421875 +69709 0.02508544921875 +69710 -0.04937744140625 +69711 0.025665283203125 +69712 -0.07818603515625 +69713 0.017333984375 +69714 -0.103790283203125 +69715 0.00189208984375 +69716 -0.1285400390625 +69717 -0.03173828125 +69718 -0.148223876953125 +69719 -0.071502685546875 +69720 -0.167999267578125 +69721 -0.13543701171875 +69722 -0.186981201171875 +69723 -0.219970703125 +69724 -0.19830322265625 +69725 -0.300506591796875 +69726 -0.20263671875 +69727 -0.376312255859375 +69728 -0.1917724609375 +69729 -0.416107177734375 +69730 -0.152435302734375 +69731 -0.371124267578125 +69732 -0.08642578125 +69733 -0.242279052734375 +69734 -0.007293701171875 +69735 -0.069732666015625 +69736 0.0771484375 +69737 0.125640869140625 +69738 0.15618896484375 +69739 0.31268310546875 +69740 0.217742919921875 +69741 0.45501708984375 +69742 0.26153564453125 +69743 0.554779052734375 +69744 0.286590576171875 +69745 0.61065673828125 +69746 0.2890625 +69747 0.610931396484375 +69748 0.261810302734375 +69749 0.531463623046875 +69750 0.209991455078125 +69751 0.3883056640625 +69752 0.15020751953125 +69753 0.23468017578125 +69754 0.09075927734375 +69755 0.095245361328125 +69756 0.040496826171875 +69757 -0.00396728515625 +69758 0.004913330078125 +69759 -0.04852294921875 +69760 -0.01971435546875 +69761 -0.055145263671875 +69762 -0.0477294921875 +69763 -0.0758056640625 +69764 -0.086395263671875 +69765 -0.138702392578125 +69766 -0.12432861328125 +69767 -0.209197998046875 +69768 -0.16119384765625 +69769 -0.289031982421875 +69770 -0.196624755859375 +69771 -0.37884521484375 +69772 -0.223541259765625 +69773 -0.456329345703125 +69774 -0.24041748046875 +69775 -0.51641845703125 +69776 -0.2354736328125 +69777 -0.519287109375 +69778 -0.2071533203125 +69779 -0.458251953125 +69780 -0.17156982421875 +69781 -0.384796142578125 +69782 -0.136993408203125 +69783 -0.323699951171875 +69784 -0.102691650390625 +69785 -0.269287109375 +69786 -0.061767578125 +69787 -0.1951904296875 +69788 -0.014862060546875 +69789 -0.100006103515625 +69790 0.028961181640625 +69791 -0.01055908203125 +69792 0.077911376953125 +69793 0.1033935546875 +69794 0.133392333984375 +69795 0.24908447265625 +69796 0.178863525390625 +69797 0.373199462890625 +69798 0.20867919921875 +69799 0.45806884765625 +69800 0.225006103515625 +69801 0.511474609375 +69802 0.237579345703125 +69803 0.565399169921875 +69804 0.244171142578125 +69805 0.61138916015625 +69806 0.22735595703125 +69807 0.5897216796875 +69808 0.184844970703125 +69809 0.4906005859375 +69810 0.122650146484375 +69811 0.33148193359375 +69812 0.05224609375 +69813 0.147796630859375 +69814 -0.01300048828125 +69815 -0.01873779296875 +69816 -0.063873291015625 +69817 -0.140289306640625 +69818 -0.092193603515625 +69819 -0.191986083984375 +69820 -0.100433349609375 +69821 -0.184295654296875 +69822 -0.101470947265625 +69823 -0.161834716796875 +69824 -0.1075439453125 +69825 -0.166595458984375 +69826 -0.1170654296875 +69827 -0.19390869140625 +69828 -0.124298095703125 +69829 -0.22442626953125 +69830 -0.1358642578125 +69831 -0.279754638671875 +69832 -0.145904541015625 +69833 -0.3389892578125 +69834 -0.140594482421875 +69835 -0.3543701171875 +69836 -0.127197265625 +69837 -0.348175048828125 +69838 -0.10809326171875 +69839 -0.32598876953125 +69840 -0.0750732421875 +69841 -0.2581787109375 +69842 -0.027374267578125 +69843 -0.139801025390625 +69844 0.029998779296875 +69845 0.014617919921875 +69846 0.0782470703125 +69847 0.144378662109375 +69848 0.1083984375 +69849 0.221038818359375 +69850 0.127960205078125 +69851 0.27069091796875 +69852 0.136962890625 +69853 0.294036865234375 +69854 0.141571044921875 +69855 0.311767578125 +69856 0.146453857421875 +69857 0.339141845703125 +69858 0.147064208984375 +69859 0.360260009765625 +69860 0.139404296875 +69861 0.360504150390625 +69862 0.1146240234375 +69863 0.308380126953125 +69864 0.066741943359375 +69865 0.18170166015625 +69866 0.00360107421875 +69867 0.0047607421875 +69868 -0.060333251953125 +69869 -0.17559814453125 +69870 -0.11114501953125 +69871 -0.3143310546875 +69872 -0.13543701171875 +69873 -0.36785888671875 +69874 -0.140594482421875 +69875 -0.36248779296875 +69876 -0.139678955078125 +69877 -0.343536376953125 +69878 -0.12982177734375 +69879 -0.3018798828125 +69880 -0.109130859375 +69881 -0.231414794921875 +69882 -0.073394775390625 +69883 -0.117645263671875 +69884 -0.032379150390625 +69885 0.007049560546875 +69886 -0.0025634765625 +69887 0.087982177734375 +69888 0.01995849609375 +69889 0.13946533203125 +69890 0.03851318359375 +69891 0.17425537109375 +69892 0.051361083984375 +69893 0.188201904296875 +69894 0.055450439453125 +69895 0.171234130859375 +69896 0.049163818359375 +69897 0.118438720703125 +69898 0.039398193359375 +69899 0.05706787109375 +69900 0.02642822265625 +69901 -0.010711669921875 +69902 0.00836181640625 +69903 -0.0914306640625 +69904 -0.008880615234375 +69905 -0.162322998046875 +69906 -0.017730712890625 +69907 -0.194549560546875 +69908 -0.00787353515625 +69909 -0.1492919921875 +69910 0.022125244140625 +69911 -0.02166748046875 +69912 0.0555419921875 +69913 0.124053955078125 +69914 0.0723876953125 +69915 0.211151123046875 +69916 0.073272705078125 +69917 0.240447998046875 +69918 0.06658935546875 +69919 0.242218017578125 +69920 0.05517578125 +69921 0.2257080078125 +69922 0.040313720703125 +69923 0.194366455078125 +69924 0.013671875 +69925 0.115509033203125 +69926 -0.018096923828125 +69927 0.0128173828125 +69928 -0.03900146484375 +69929 -0.053802490234375 +69930 -0.05584716796875 +69931 -0.110626220703125 +69932 -0.079620361328125 +69933 -0.199493408203125 +69934 -0.103485107421875 +69935 -0.29437255859375 +69936 -0.11090087890625 +69937 -0.33221435546875 +69938 -0.093292236328125 +69939 -0.27972412109375 +69940 -0.06365966796875 +69941 -0.185333251953125 +69942 -0.043182373046875 +69943 -0.128204345703125 +69944 -0.034088134765625 +69945 -0.115692138671875 +69946 -0.0284423828125 +69947 -0.116455078125 +69948 -0.020111083984375 +69949 -0.105926513671875 +69950 -0.00140380859375 +69951 -0.053955078125 +69952 0.029876708984375 +69953 0.048797607421875 +69954 0.061614990234375 +69955 0.157318115234375 +69956 0.077972412109375 +69957 0.212005615234375 +69958 0.080322265625 +69959 0.218475341796875 +69960 0.08465576171875 +69961 0.23724365234375 +69962 0.100830078125 +69963 0.30535888671875 +69964 0.118011474609375 +69965 0.38128662109375 +69966 0.120361328125 +69967 0.404449462890625 +69968 0.11328125 +69969 0.3944091796875 +69970 0.10693359375 +69971 0.3885498046875 +69972 0.09521484375 +69973 0.362640380859375 +69974 0.0670166015625 +69975 0.27362060546875 +69976 0.021453857421875 +69977 0.11712646484375 +69978 -0.027557373046875 +69979 -0.054901123046875 +69980 -0.06622314453125 +69981 -0.19085693359375 +69982 -0.093048095703125 +69983 -0.28570556640625 +69984 -0.107940673828125 +69985 -0.339263916015625 +69986 -0.11773681640625 +69987 -0.3775634765625 +69988 -0.134429931640625 +69989 -0.445709228515625 +69990 -0.15582275390625 +69991 -0.535064697265625 +69992 -0.177703857421875 +69993 -0.629058837890625 +69994 -0.1922607421875 +69995 -0.697601318359375 +69996 -0.19000244140625 +69997 -0.70391845703125 +69998 -0.169708251953125 +69999 -0.6424560546875 +70000 -0.12579345703125 +70001 -0.491241455078125 +70002 -0.06256103515625 +70003 -0.265716552734375 +70004 0.004486083984375 +70005 -0.023712158203125 +70006 0.066497802734375 +70007 0.201751708984375 +70008 0.1141357421875 +70009 0.375823974609375 +70010 0.143798828125 +70011 0.485076904296875 +70012 0.16583251953125 +70013 0.56884765625 +70014 0.182281494140625 +70015 0.634765625 +70016 0.181304931640625 +70017 0.63763427734375 +70018 0.160003662109375 +70019 0.5660400390625 +70020 0.132293701171875 +70021 0.4720458984375 +70022 0.11187744140625 +70023 0.40692138671875 +70024 0.100799560546875 +70025 0.3778076171875 +70026 0.09722900390625 +70027 0.376953125 +70028 0.092803955078125 +70029 0.371978759765625 +70030 0.07452392578125 +70031 0.313140869140625 +70032 0.038330078125 +70033 0.184417724609375 +70034 -0.00897216796875 +70035 0.011199951171875 +70036 -0.05792236328125 +70037 -0.171051025390625 +70038 -0.1019287109375 +70039 -0.33740234375 +70040 -0.136810302734375 +70041 -0.47198486328125 +70042 -0.1588134765625 +70043 -0.560394287109375 +70044 -0.1622314453125 +70045 -0.58056640625 +70046 -0.151153564453125 +70047 -0.54754638671875 +70048 -0.138214111328125 +70049 -0.508575439453125 +70050 -0.1224365234375 +70051 -0.459503173828125 +70052 -0.1024169921875 +70053 -0.394378662109375 +70054 -0.08868408203125 +70055 -0.35260009765625 +70056 -0.075469970703125 +70057 -0.31170654296875 +70058 -0.043304443359375 +70059 -0.197418212890625 +70060 0.008148193359375 +70061 -0.007965087890625 +70062 0.065826416015625 +70063 0.207489013671875 +70064 0.119232177734375 +70065 0.409210205078125 +70066 0.1617431640625 +70067 0.57208251953125 +70068 0.185455322265625 +70069 0.66595458984375 +70070 0.1820068359375 +70071 0.65875244140625 +70072 0.15594482421875 +70073 0.56744384765625 +70074 0.1177978515625 +70075 0.431396484375 +70076 0.07928466796875 +70077 0.29443359375 +70078 0.047332763671875 +70079 0.182464599609375 +70080 0.013702392578125 +70081 0.06365966796875 +70082 -0.025177001953125 +70083 -0.075958251953125 +70084 -0.056793212890625 +70085 -0.189422607421875 +70086 -0.07977294921875 +70087 -0.271942138671875 +70088 -0.099090576171875 +70089 -0.342529296875 +70090 -0.105010986328125 +70091 -0.364166259765625 +70092 -0.094970703125 +70093 -0.327239990234375 +70094 -0.0809326171875 +70095 -0.2769775390625 +70096 -0.0736083984375 +70097 -0.253692626953125 +70098 -0.069427490234375 +70099 -0.24365234375 +70100 -0.055694580078125 +70101 -0.1983642578125 +70102 -0.032073974609375 +70103 -0.116241455078125 +70104 -0.009124755859375 +70105 -0.036834716796875 +70106 0.011688232421875 +70107 0.034881591796875 +70108 0.02825927734375 +70109 0.09124755859375 +70110 0.034332275390625 +70111 0.10888671875 +70112 0.039794921875 +70113 0.125518798828125 +70114 0.048980712890625 +70115 0.15771484375 +70116 0.054656982421875 +70117 0.17828369140625 +70118 0.052581787109375 +70119 0.17108154296875 +70120 0.041168212890625 +70121 0.129974365234375 +70122 0.027679443359375 +70123 0.082427978515625 +70124 0.011993408203125 +70125 0.027679443359375 +70126 -0.014068603515625 +70127 -0.065643310546875 +70128 -0.04034423828125 +70129 -0.15936279296875 +70130 -0.056060791015625 +70131 -0.21307373046875 +70132 -0.063262939453125 +70133 -0.234649658203125 +70134 -0.0555419921875 +70135 -0.2001953125 +70136 -0.035308837890625 +70137 -0.119171142578125 +70138 -0.01129150390625 +70139 -0.024749755859375 +70140 0.01727294921875 +70141 0.085784912109375 +70142 0.04132080078125 +70143 0.178131103515625 +70144 0.0513916015625 +70145 0.215576171875 +70146 0.0511474609375 +70147 0.211456298828125 +70148 0.043212890625 +70149 0.17523193359375 +70150 0.032684326171875 +70151 0.128753662109375 +70152 0.026519775390625 +70153 0.1019287109375 +70154 0.020050048828125 +70155 0.0743408203125 +70156 0.01263427734375 +70157 0.04327392578125 +70158 0.0111083984375 +70159 0.038177490234375 +70160 0.01953125 +70161 0.076263427734375 +70162 0.0340576171875 +70163 0.14105224609375 +70164 0.044036865234375 +70165 0.186431884765625 +70166 0.044036865234375 +70167 0.188812255859375 +70168 0.03192138671875 +70169 0.1390380859375 +70170 0.00885009765625 +70171 0.041778564453125 +70172 -0.019683837890625 +70173 -0.079437255859375 +70174 -0.052459716796875 +70175 -0.219390869140625 +70176 -0.0870361328125 +70177 -0.367828369140625 +70178 -0.116485595703125 +70179 -0.494873046875 +70180 -0.130584716796875 +70181 -0.556243896484375 +70182 -0.11932373046875 +70183 -0.508697509765625 +70184 -0.088104248046875 +70185 -0.3756103515625 +70186 -0.051361083984375 +70187 -0.218902587890625 +70188 -0.01495361328125 +70189 -0.063751220703125 +70190 0.021453857421875 +70191 0.091552734375 +70192 0.055328369140625 +70193 0.23602294921875 +70194 0.0804443359375 +70195 0.342987060546875 +70196 0.092803955078125 +70197 0.39520263671875 +70198 0.09161376953125 +70199 0.389373779296875 +70200 0.07659912109375 +70201 0.324249267578125 +70202 0.05340576171875 +70203 0.224090576171875 +70204 0.03021240234375 +70205 0.124267578125 +70206 0.0098876953125 +70207 0.037078857421875 +70208 -0.001190185546875 +70209 -0.010101318359375 +70210 -0.003509521484375 +70211 -0.019439697265625 +70212 -0.004486083984375 +70213 -0.022796630859375 +70214 0.000213623046875 +70215 -0.001556396484375 +70216 0.01336669921875 +70217 0.056304931640625 +70218 0.024749755859375 +70219 0.106719970703125 +70220 0.02215576171875 +70221 0.096893310546875 +70222 0.00927734375 +70223 0.042694091796875 +70224 -0.005035400390625 +70225 -0.018035888671875 +70226 -0.01861572265625 +70227 -0.07586669921875 +70228 -0.02880859375 +70229 -0.11944580078125 +70230 -0.03814697265625 +70231 -0.15972900390625 +70232 -0.048004150390625 +70233 -0.202606201171875 +70234 -0.0584716796875 +70235 -0.24859619140625 +70236 -0.071319580078125 +70237 -0.30517578125 +70238 -0.084197998046875 +70239 -0.36212158203125 +70240 -0.09063720703125 +70241 -0.39141845703125 +70242 -0.081878662109375 +70243 -0.35528564453125 +70244 -0.057098388671875 +70245 -0.249969482421875 +70246 -0.02032470703125 +70247 -0.092864990234375 +70248 0.0220947265625 +70249 0.08905029296875 +70250 0.056121826171875 +70251 0.2352294921875 +70252 0.0755615234375 +70253 0.318817138671875 +70254 0.084747314453125 +70255 0.358642578125 +70256 0.08209228515625 +70257 0.347747802734375 +70258 0.0675048828125 +70259 0.28564453125 +70260 0.052764892578125 +70261 0.223175048828125 +70262 0.046356201171875 +70263 0.196746826171875 +70264 0.0421142578125 +70265 0.179840087890625 +70266 0.0361328125 +70267 0.155548095703125 +70268 0.0347900390625 +70269 0.151214599609375 +70270 0.035797119140625 +70271 0.156951904296875 +70272 0.0296630859375 +70273 0.13177490234375 +70274 0.022247314453125 +70275 0.100799560546875 +70276 0.0189208984375 +70277 0.087127685546875 +70278 0.0113525390625 +70279 0.05487060546875 +70280 -0.003448486328125 +70281 -0.009002685546875 +70282 -0.025390625 +70283 -0.10400390625 +70284 -0.054290771484375 +70285 -0.229400634765625 +70286 -0.083282470703125 +70287 -0.35552978515625 +70288 -0.102996826171875 +70289 -0.441925048828125 +70290 -0.110015869140625 +70291 -0.473846435546875 +70292 -0.107513427734375 +70293 -0.464813232421875 +70294 -0.096527099609375 +70295 -0.419097900390625 +70296 -0.076507568359375 +70297 -0.334320068359375 +70298 -0.051513671875 +70299 -0.227935791015625 +70300 -0.02703857421875 +70301 -0.12347412109375 +70302 -0.004638671875 +70303 -0.02764892578125 +70304 0.019866943359375 +70305 0.077667236328125 +70306 0.051300048828125 +70307 0.2132568359375 +70308 0.0919189453125 +70309 0.38885498046875 +70310 0.13671875 +70311 0.582794189453125 +70312 0.171539306640625 +70313 0.734039306640625 +70314 0.1865234375 +70315 0.800140380859375 +70316 0.181060791015625 +70317 0.7783203125 +70318 0.154388427734375 +70319 0.6651611328125 +70320 0.1063232421875 +70321 0.45965576171875 +70322 0.0455322265625 +70323 0.199188232421875 +70324 -0.012725830078125 +70325 -0.050689697265625 +70326 -0.055206298828125 +70327 -0.23297119140625 +70328 -0.077850341796875 +70329 -0.33013916015625 +70330 -0.08673095703125 +70331 -0.368408203125 +70332 -0.089080810546875 +70333 -0.378936767578125 +70334 -0.088470458984375 +70335 -0.376983642578125 +70336 -0.0888671875 +70337 -0.37969970703125 +70338 -0.09130859375 +70339 -0.391510009765625 +70340 -0.089569091796875 +70341 -0.385345458984375 +70342 -0.07916259765625 +70343 -0.3419189453125 +70344 -0.06512451171875 +70345 -0.28289794921875 +70346 -0.057525634765625 +70347 -0.251617431640625 +70348 -0.060577392578125 +70349 -0.266143798828125 +70350 -0.061981201171875 +70351 -0.273345947265625 +70352 -0.048675537109375 +70353 -0.216796875 +70354 -0.027984619140625 +70355 -0.128265380859375 +70356 -0.013946533203125 +70357 -0.068145751953125 +70358 -0.008087158203125 +70359 -0.0430908203125 +70360 -0.0037841796875 +70361 -0.024444580078125 +70362 0.006561279296875 +70363 0.020721435546875 +70364 0.0303955078125 +70365 0.124481201171875 +70366 0.06103515625 +70367 0.25787353515625 +70368 0.08880615234375 +70369 0.379119873046875 +70370 0.111785888671875 +70371 0.47991943359375 +70372 0.12255859375 +70373 0.5281982421875 +70374 0.118194580078125 +70375 0.511138916015625 +70376 0.105072021484375 +70377 0.456207275390625 +70378 0.093414306640625 +70379 0.407470703125 +70380 0.087615966796875 +70381 0.383758544921875 +70382 0.081146240234375 +70383 0.35687255859375 +70384 0.070556640625 +70385 0.31182861328125 +70386 0.056365966796875 +70387 0.250885009765625 +70388 0.03656005859375 +70389 0.1654052734375 +70390 0.006500244140625 +70391 0.035247802734375 +70392 -0.034393310546875 +70393 -0.142059326171875 +70394 -0.0789794921875 +70395 -0.33563232421875 +70396 -0.124725341796875 +70397 -0.5345458984375 +70398 -0.167724609375 +70399 -0.72186279296875 +70400 -0.1943359375 +70401 -0.836669921875 +70402 -0.194488525390625 +70403 -0.8326416015625 +70404 -0.172210693359375 +70405 -0.7296142578125 +70406 -0.138946533203125 +70407 -0.582550048828125 +70408 -0.105010986328125 +70409 -0.440093994140625 +70410 -0.0753173828125 +70411 -0.324310302734375 +70412 -0.043670654296875 +70413 -0.20147705078125 +70414 -0.00518798828125 +70415 -0.044647216796875 +70416 0.03118896484375 +70417 0.103973388671875 +70418 0.056671142578125 +70419 0.202392578125 +70420 0.073699951171875 +70421 0.264495849609375 +70422 0.091796875 +70423 0.338897705078125 +70424 0.114471435546875 +70425 0.443817138671875 +70426 0.134857177734375 +70427 0.545074462890625 +70428 0.14794921875 +70429 0.6173095703125 +70430 0.15228271484375 +70431 0.6524658203125 +70432 0.150604248046875 +70433 0.66339111328125 +70434 0.144378662109375 +70435 0.6561279296875 +70436 0.12908935546875 +70437 0.606781005859375 +70438 0.102264404296875 +70439 0.501190185546875 +70440 0.066925048828125 +70441 0.352783203125 +70442 0.0263671875 +70443 0.176544189453125 +70444 -0.020538330078125 +70445 -0.034820556640625 +70446 -0.06890869140625 +70447 -0.258209228515625 +70448 -0.108367919921875 +70449 -0.44244384765625 +70450 -0.1363525390625 +70451 -0.5753173828125 +70452 -0.15185546875 +70453 -0.65203857421875 +70454 -0.148712158203125 +70455 -0.641632080078125 +70456 -0.13067626953125 +70457 -0.562164306640625 +70458 -0.106781005859375 +70459 -0.458038330078125 +70460 -0.081451416015625 +70461 -0.350555419921875 +70462 -0.05908203125 +70463 -0.260528564453125 +70464 -0.040740966796875 +70465 -0.192108154296875 +70466 -0.026031494140625 +70467 -0.141937255859375 +70468 -0.013641357421875 +70469 -0.1021728515625 +70470 -0.001800537109375 +70471 -0.062896728515625 +70472 0.01165771484375 +70473 -0.011932373046875 +70474 0.029022216796875 +70475 0.062835693359375 +70476 0.04766845703125 +70477 0.148712158203125 +70478 0.066741943359375 +70479 0.241729736328125 +70480 0.087677001953125 +70481 0.34912109375 +70482 0.1077880859375 +70483 0.457305908203125 +70484 0.122711181640625 +70485 0.54388427734375 +70486 0.125457763671875 +70487 0.5728759765625 +70488 0.108642578125 +70489 0.506591796875 +70490 0.07373046875 +70491 0.351226806640625 +70492 0.02886962890625 +70493 0.146514892578125 +70494 -0.015228271484375 +70495 -0.05523681640625 +70496 -0.050811767578125 +70497 -0.21624755859375 +70498 -0.077392578125 +70499 -0.334930419921875 +70500 -0.0931396484375 +70501 -0.402984619140625 +70502 -0.102142333984375 +70503 -0.4412841796875 +70504 -0.113555908203125 +70505 -0.49578857421875 +70506 -0.126129150390625 +70507 -0.5601806640625 +70508 -0.133148193359375 +70509 -0.600738525390625 +70510 -0.1280517578125 +70511 -0.584228515625 +70512 -0.104705810546875 +70513 -0.47930908203125 +70514 -0.061920166015625 +70515 -0.27935791015625 +70516 -0.0047607421875 +70517 -0.0089111328125 +70518 0.053924560546875 +70519 0.268798828125 +70520 0.0997314453125 +70521 0.482818603515625 +70522 0.12664794921875 +70523 0.60369873046875 +70524 0.138336181640625 +70525 0.650421142578125 +70526 0.142852783203125 +70527 0.66400146484375 +70528 0.139556884765625 +70529 0.6414794921875 +70530 0.1263427734375 +70531 0.572540283203125 +70532 0.111358642578125 +70533 0.498138427734375 +70534 0.098907470703125 +70535 0.439453125 +70536 0.0848388671875 +70537 0.375518798828125 +70538 0.0628662109375 +70539 0.274505615234375 +70540 0.027557373046875 +70541 0.1087646484375 +70542 -0.016448974609375 +70543 -0.099395751953125 +70544 -0.06268310546875 +70545 -0.3182373046875 +70546 -0.11126708984375 +70547 -0.5489501953125 +70548 -0.158477783203125 +70549 -0.7738037109375 +70550 -0.193603515625 +70551 -0.86383056640625 +70552 -0.209930419921875 +70553 -0.870391845703125 +70554 -0.2109375 +70555 -0.86895751953125 +70556 -0.199188232421875 +70557 -0.861053466796875 +70558 -0.171234130859375 +70559 -0.765869140625 +70560 -0.12481689453125 +70561 -0.5301513671875 +70562 -0.0614013671875 +70563 -0.214691162109375 +70564 0.010345458984375 +70565 0.137359619140625 +70566 0.080047607421875 +70567 0.474822998046875 +70568 0.1405029296875 +70569 0.76239013671875 +70570 0.18621826171875 +70571 0.867462158203125 +70572 0.2171630859375 +70573 0.870361328125 +70574 0.230926513671875 +70575 0.86480712890625 +70576 0.228485107421875 +70577 0.831817626953125 +70578 0.214630126953125 +70579 0.677581787109375 +70580 0.19049072265625 +70581 0.495880126953125 +70582 0.15972900390625 +70583 0.30767822265625 +70584 0.122772216796875 +70585 0.116180419921875 +70586 0.073272705078125 +70587 -0.110748291015625 +70588 0.009857177734375 +70589 -0.381805419921875 +70590 -0.058837890625 +70591 -0.6572265625 +70592 -0.120758056640625 +70593 -0.857421875 +70594 -0.167266845703125 +70595 -0.870391845703125 +70596 -0.196868896484375 +70597 -0.870391845703125 +70598 -0.21484375 +70599 -0.86444091796875 +70600 -0.228271484375 +70601 -0.85723876953125 +70602 -0.2333984375 +70603 -0.790008544921875 +70604 -0.21929931640625 +70605 -0.62847900390625 +70606 -0.185272216796875 +70607 -0.3956298828125 +70608 -0.13787841796875 +70609 -0.126708984375 +70610 -0.082550048828125 +70611 0.150115966796875 +70612 -0.021636962890625 +70613 0.424041748046875 +70614 0.039459228515625 +70615 0.670623779296875 +70616 0.092926025390625 +70617 0.854522705078125 +70618 0.13519287109375 +70619 0.866485595703125 +70620 0.163116455078125 +70621 0.86920166015625 +70622 0.180267333984375 +70623 0.8653564453125 +70624 0.18927001953125 +70625 0.857147216796875 +70626 0.189453125 +70627 0.766845703125 +70628 0.181793212890625 +70629 0.628509521484375 +70630 0.164886474609375 +70631 0.462127685546875 +70632 0.143829345703125 +70633 0.297210693359375 +70634 0.12109375 +70635 0.14862060546875 +70636 0.092071533203125 +70637 -0.00537109375 +70638 0.058258056640625 +70639 -0.15753173828125 +70640 0.01898193359375 +70641 -0.31304931640625 +70642 -0.028533935546875 +70643 -0.48876953125 +70644 -0.074859619140625 +70645 -0.6416015625 +70646 -0.114990234375 +70647 -0.751373291015625 +70648 -0.15350341796875 +70649 -0.84619140625 +70650 -0.187408447265625 +70651 -0.861297607421875 +70652 -0.209991455078125 +70653 -0.863250732421875 +70654 -0.21490478515625 +70655 -0.856597900390625 +70656 -0.203948974609375 +70657 -0.7498779296875 +70658 -0.187896728515625 +70659 -0.624542236328125 +70660 -0.163787841796875 +70661 -0.47808837890625 +70662 -0.1220703125 +70663 -0.253387451171875 +70664 -0.070770263671875 +70665 0.003692626953125 +70666 -0.021728515625 +70667 0.2257080078125 +70668 0.0267333984375 +70669 0.427154541015625 +70670 0.079681396484375 +70671 0.643218994140625 +70672 0.135101318359375 +70673 0.855926513671875 +70674 0.182952880859375 +70675 0.870361328125 +70676 0.21466064453125 +70677 0.870361328125 +70678 0.23126220703125 +70679 0.862762451171875 +70680 0.232177734375 +70681 0.79669189453125 +70682 0.2158203125 +70683 0.595794677734375 +70684 0.187164306640625 +70685 0.362152099609375 +70686 0.151092529296875 +70687 0.1270751953125 +70688 0.111419677734375 +70689 -0.086944580078125 +70690 0.068756103515625 +70691 -0.2784423828125 +70692 0.017608642578125 +70693 -0.484832763671875 +70694 -0.044891357421875 +70695 -0.729583740234375 +70696 -0.109893798828125 +70697 -0.86688232421875 +70698 -0.166412353515625 +70699 -0.870391845703125 +70700 -0.21331787109375 +70701 -0.86859130859375 +70702 -0.25 +70703 -0.86279296875 +70704 -0.270294189453125 +70705 -0.817962646484375 +70706 -0.26641845703125 +70707 -0.6116943359375 +70708 -0.237152099609375 +70709 -0.3128662109375 +70710 -0.188232421875 +70711 0.039398193359375 +70712 -0.123138427734375 +70713 0.422821044921875 +70714 -0.04766845703125 +70715 0.805145263671875 +70716 0.0264892578125 +70717 0.870361328125 +70718 0.0894775390625 +70719 0.870361328125 +70720 0.139007568359375 +70721 0.860015869140625 +70722 0.173492431640625 +70723 0.727935791015625 +70724 0.191650390625 +70725 0.48114013671875 +70726 0.197296142578125 +70727 0.2059326171875 +70728 0.193939208984375 +70729 -0.06103515625 +70730 0.18310546875 +70731 -0.29913330078125 +70732 0.162261962890625 +70733 -0.516204833984375 +70734 0.1287841796875 +70735 -0.7252197265625 +70736 0.086883544921875 +70737 -0.85980224609375 +70738 0.042388916015625 +70739 -0.870391845703125 +70740 0.000457763671875 +70741 -0.870391845703125 +70742 -0.03045654296875 +70743 -0.858062744140625 +70744 -0.049346923828125 +70745 -0.673004150390625 +70746 -0.06475830078125 +70747 -0.42694091796875 +70748 -0.083831787109375 +70749 -0.2100830078125 +70750 -0.10589599609375 +70751 -0.0362548828125 +70752 -0.125762939453125 +70753 0.10943603515625 +70754 -0.139801025390625 +70755 0.23516845703125 +70756 -0.140869140625 +70757 0.373687744140625 +70758 -0.129150390625 +70759 0.517791748046875 +70760 -0.11517333984375 +70761 0.602783203125 +70762 -0.098114013671875 +70763 0.635711669921875 +70764 -0.07244873046875 +70765 0.655181884765625 +70766 -0.040008544921875 +70767 0.65948486328125 +70768 -0.002349853515625 +70769 0.651275634765625 +70770 0.0361328125 +70771 0.61846923828125 +70772 0.068939208984375 +70773 0.53753662109375 +70774 0.092742919921875 +70775 0.404144287109375 +70776 0.10565185546875 +70777 0.22186279296875 +70778 0.107666015625 +70779 0.003997802734375 +70780 0.1015625 +70781 -0.22100830078125 +70782 0.090606689453125 +70783 -0.42449951171875 +70784 0.0782470703125 +70785 -0.579833984375 +70786 0.07159423828125 +70787 -0.641876220703125 +70788 0.06951904296875 +70789 -0.6177978515625 +70790 0.06121826171875 +70791 -0.575531005859375 +70792 0.0458984375 +70793 -0.526336669921875 +70794 0.032440185546875 +70795 -0.42645263671875 +70796 0.025634765625 +70797 -0.2581787109375 +70798 0.019622802734375 +70799 -0.068695068359375 +70800 0.008209228515625 +70801 0.09222412109375 +70802 -0.005218505859375 +70803 0.232147216796875 +70804 -0.0186767578125 +70805 0.3509521484375 +70806 -0.03692626953125 +70807 0.410064697265625 +70808 -0.064697265625 +70809 0.372955322265625 +70810 -0.098388671875 +70811 0.2554931640625 +70812 -0.129119873046875 +70813 0.10711669921875 +70814 -0.153564453125 +70815 -0.052886962890625 +70816 -0.165679931640625 +70817 -0.186279296875 +70818 -0.156158447265625 +70819 -0.23291015625 +70820 -0.12896728515625 +70821 -0.209442138671875 +70822 -0.095306396484375 +70823 -0.174163818359375 +70824 -0.056793212890625 +70825 -0.126739501953125 +70826 -0.011962890625 +70827 -0.048126220703125 +70828 0.034210205078125 +70829 0.0426025390625 +70830 0.07366943359375 +70831 0.10748291015625 +70832 0.10400390625 +70833 0.1409912109375 +70834 0.133026123046875 +70835 0.19708251953125 +70836 0.159454345703125 +70837 0.273651123046875 +70838 0.173858642578125 +70839 0.31768798828125 +70840 0.178009033203125 +70841 0.341094970703125 +70842 0.176177978515625 +70843 0.368011474609375 +70844 0.164520263671875 +70845 0.37249755859375 +70846 0.134857177734375 +70847 0.30072021484375 +70848 0.088134765625 +70849 0.1517333984375 +70850 0.03570556640625 +70851 -0.01470947265625 +70852 -0.019256591796875 +70853 -0.1883544921875 +70854 -0.075927734375 +70855 -0.372711181640625 +70856 -0.123870849609375 +70857 -0.51397705078125 +70858 -0.155029296875 +70859 -0.57177734375 +70860 -0.167205810546875 +70861 -0.53948974609375 +70862 -0.162567138671875 +70863 -0.43511962890625 +70864 -0.1468505859375 +70865 -0.2962646484375 +70866 -0.126220703125 +70867 -0.161102294921875 +70868 -0.103057861328125 +70869 -0.0435791015625 +70870 -0.0770263671875 +70871 0.060394287109375 +70872 -0.0511474609375 +70873 0.13665771484375 +70874 -0.028778076171875 +70875 0.170135498046875 +70876 -0.010101318359375 +70877 0.16552734375 +70878 0.009490966796875 +70879 0.15728759765625 +70880 0.029693603515625 +70881 0.150787353515625 +70882 0.0452880859375 +70883 0.12200927734375 +70884 0.0567626953125 +70885 0.080108642578125 +70886 0.067535400390625 +70887 0.05126953125 +70888 0.0814208984375 +70889 0.062896728515625 +70890 0.094146728515625 +70891 0.09271240234375 +70892 0.097442626953125 +70893 0.092987060546875 +70894 0.093719482421875 +70895 0.07855224609375 +70896 0.085662841796875 +70897 0.06427001953125 +70898 0.07110595703125 +70899 0.0347900390625 +70900 0.050384521484375 +70901 -0.01171875 +70902 0.02752685546875 +70903 -0.056060791015625 +70904 0.0106201171875 +70905 -0.055511474609375 +70906 0.000579833984375 +70907 -0.010467529296875 +70908 -0.0106201171875 +70909 0.02508544921875 +70910 -0.026336669921875 +70911 0.025665283203125 +70912 -0.041595458984375 +70913 0.017333984375 +70914 -0.055267333984375 +70915 0.00189208984375 +70916 -0.068511962890625 +70917 -0.03173828125 +70918 -0.07904052734375 +70919 -0.071502685546875 +70920 -0.089324951171875 +70921 -0.13543701171875 +70922 -0.098846435546875 +70923 -0.219970703125 +70924 -0.104156494140625 +70925 -0.300506591796875 +70926 -0.1055908203125 +70927 -0.376312255859375 +70928 -0.09912109375 +70929 -0.416107177734375 +70930 -0.07818603515625 +70931 -0.371124267578125 +70932 -0.04376220703125 +70933 -0.242279052734375 +70934 -0.00274658203125 +70935 -0.069732666015625 +70936 0.040863037109375 +70937 0.125640869140625 +70938 0.081634521484375 +70939 0.31268310546875 +70940 0.113433837890625 +70941 0.45501708984375 +70942 0.136077880859375 +70943 0.554779052734375 +70944 0.1490478515625 +70945 0.61065673828125 +70946 0.150421142578125 +70947 0.610931396484375 +70948 0.136627197265625 +70949 0.531463623046875 +70950 0.1102294921875 +70951 0.3883056640625 +70952 0.079559326171875 +70953 0.23468017578125 +70954 0.048858642578125 +70955 0.095245361328125 +70956 0.022613525390625 +70957 -0.00396728515625 +70958 0.00360107421875 +70959 -0.04852294921875 +70960 -0.00994873046875 +70961 -0.055145263671875 +70962 -0.025146484375 +70963 -0.0758056640625 +70964 -0.0455322265625 +70965 -0.138702392578125 +70966 -0.06536865234375 +70967 -0.209197998046875 +70968 -0.084442138671875 +70969 -0.289031982421875 +70970 -0.1025390625 +70971 -0.37884521484375 +70972 -0.116119384765625 +70973 -0.456329345703125 +70974 -0.1243896484375 +70975 -0.51641845703125 +70976 -0.12152099609375 +70977 -0.519287109375 +70978 -0.106781005859375 +70979 -0.458251953125 +70980 -0.0882568359375 +70981 -0.384796142578125 +70982 -0.070098876953125 +70983 -0.323699951171875 +70984 -0.051971435546875 +70985 -0.269287109375 +70986 -0.030487060546875 +70987 -0.1951904296875 +70988 -0.00604248046875 +70989 -0.100006103515625 +70990 0.016754150390625 +70991 -0.01055908203125 +70992 0.04193115234375 +70993 0.1033935546875 +70994 0.0701904296875 +70995 0.24908447265625 +70996 0.09326171875 +70997 0.373199462890625 +70998 0.1082763671875 +70999 0.45806884765625 +71000 0.1163330078125 +71001 0.511474609375 +71002 0.122283935546875 +71003 0.565399169921875 +71004 0.125091552734375 +71005 0.61138916015625 +71006 0.116058349609375 +71007 0.5897216796875 +71008 0.094085693359375 +71009 0.4906005859375 +71010 0.06219482421875 +71011 0.33148193359375 +71012 0.02618408203125 +71013 0.147796630859375 +71014 -0.007232666015625 +71015 -0.01873779296875 +71016 -0.03338623046875 +71017 -0.140289306640625 +71018 -0.048126220703125 +71019 -0.191986083984375 +71020 -0.05267333984375 +71021 -0.184295654296875 +71022 -0.053436279296875 +71023 -0.161834716796875 +71024 -0.056549072265625 +71025 -0.166595458984375 +71026 -0.061248779296875 +71027 -0.19390869140625 +71028 -0.06463623046875 +71029 -0.22442626953125 +71030 -0.070068359375 +71031 -0.279754638671875 +71032 -0.074615478515625 +71033 -0.3389892578125 +71034 -0.0714111328125 +71035 -0.3543701171875 +71036 -0.064117431640625 +71037 -0.348175048828125 +71038 -0.053924560546875 +71039 -0.32598876953125 +71040 -0.036773681640625 +71041 -0.2581787109375 +71042 -0.0123291015625 +71043 -0.139801025390625 +71044 0.016845703125 +71045 0.014617919921875 +71046 0.04132080078125 +71047 0.144378662109375 +71048 0.056610107421875 +71049 0.221038818359375 +71050 0.066436767578125 +71051 0.27069091796875 +71052 0.07086181640625 +71053 0.294036865234375 +71054 0.072967529296875 +71055 0.311767578125 +71056 0.0750732421875 +71057 0.339141845703125 +71058 0.07476806640625 +71059 0.360260009765625 +71060 0.07012939453125 +71061 0.360504150390625 +71062 0.057220458984375 +71063 0.308380126953125 +71064 0.033416748046875 +71065 0.18170166015625 +71066 0.002471923828125 +71067 0.0047607421875 +71068 -0.02880859375 +71069 -0.17559814453125 +71070 -0.053955078125 +71071 -0.3143310546875 +71072 -0.066680908203125 +71073 -0.36785888671875 +71074 -0.070281982421875 +71075 -0.36248779296875 +71076 -0.070709228515625 +71077 -0.343536376953125 +71078 -0.066619873046875 +71079 -0.3018798828125 +71080 -0.057159423828125 +71081 -0.231414794921875 +71082 -0.040374755859375 +71083 -0.117645263671875 +71084 -0.02081298828125 +71085 0.007049560546875 +71086 -0.00604248046875 +71087 0.087982177734375 +71088 0.005615234375 +71089 0.13946533203125 +71090 0.015594482421875 +71091 0.17425537109375 +71092 0.023040771484375 +71093 0.188201904296875 +71094 0.0262451171875 +71095 0.171234130859375 +71096 0.0242919921875 +71097 0.118438720703125 +71098 0.020599365234375 +71099 0.05706787109375 +71100 0.01519775390625 +71101 -0.010711669921875 +71102 0.00701904296875 +71103 -0.0914306640625 +71104 -0.00091552734375 +71105 -0.162322998046875 +71106 -0.0047607421875 +71107 -0.194549560546875 +71108 0.000732421875 +71109 -0.1492919921875 +71110 0.01629638671875 +71111 -0.02166748046875 +71112 0.0333251953125 +71113 0.124053955078125 +71114 0.04156494140625 +71115 0.211151123046875 +71116 0.041351318359375 +71117 0.240447998046875 +71118 0.037017822265625 +71119 0.242218017578125 +71120 0.030120849609375 +71121 0.2257080078125 +71122 0.0213623046875 +71123 0.194366455078125 +71124 0.006561279296875 +71125 0.115509033203125 +71126 -0.01080322265625 +71127 0.0128173828125 +71128 -0.0224609375 +71129 -0.053802490234375 +71130 -0.0318603515625 +71131 -0.110626220703125 +71132 -0.04461669921875 +71133 -0.199493408203125 +71134 -0.05718994140625 +71135 -0.29437255859375 +71136 -0.061065673828125 +71137 -0.33221435546875 +71138 -0.051788330078125 +71139 -0.27972412109375 +71140 -0.036102294921875 +71141 -0.185333251953125 +71142 -0.02496337890625 +71143 -0.128204345703125 +71144 -0.01953125 +71145 -0.115692138671875 +71146 -0.01580810546875 +71147 -0.116455078125 +71148 -0.010650634765625 +71149 -0.105926513671875 +71150 -0.0001220703125 +71151 -0.053955078125 +71152 0.016815185546875 +71153 0.048797607421875 +71154 0.033905029296875 +71155 0.157318115234375 +71156 0.042938232421875 +71157 0.212005615234375 +71158 0.044586181640625 +71159 0.218475341796875 +71160 0.047088623046875 +71161 0.23724365234375 +71162 0.05548095703125 +71163 0.30535888671875 +71164 0.064208984375 +71165 0.38128662109375 +71166 0.065093994140625 +71167 0.404449462890625 +71168 0.06036376953125 +71169 0.3944091796875 +71170 0.054656982421875 +71171 0.3885498046875 +71172 0.04583740234375 +71173 0.362640380859375 +71174 0.029937744140625 +71175 0.27362060546875 +71176 0.006988525390625 +71177 0.11712646484375 +71178 -0.017120361328125 +71179 -0.054901123046875 +71180 -0.036651611328125 +71181 -0.19085693359375 +71182 -0.05078125 +71183 -0.28570556640625 +71184 -0.05926513671875 +71185 -0.339263916015625 +71186 -0.064697265625 +71187 -0.3775634765625 +71188 -0.071685791015625 +71189 -0.445709228515625 +71190 -0.07940673828125 +71191 -0.535064697265625 +71192 -0.086273193359375 +71193 -0.629058837890625 +71194 -0.089324951171875 +71195 -0.697601318359375 +71196 -0.085052490234375 +71197 -0.70391845703125 +71198 -0.073150634765625 +71199 -0.6424560546875 +71200 -0.05169677734375 +71201 -0.491241455078125 +71202 -0.022613525390625 +71203 -0.265716552734375 +71204 0.00775146484375 +71205 -0.023712158203125 +71206 0.03570556640625 +71207 0.201751708984375 +71208 0.057373046875 +71209 0.375823974609375 +71210 0.071197509765625 +71211 0.485076904296875 +71212 0.081146240234375 +71213 0.56884765625 +71214 0.087982177734375 +71215 0.634765625 +71216 0.087066650390625 +71217 0.63763427734375 +71218 0.077301025390625 +71219 0.5660400390625 +71220 0.06427001953125 +71221 0.4720458984375 +71222 0.053466796875 +71223 0.40692138671875 +71224 0.0458984375 +71225 0.3778076171875 +71226 0.041015625 +71227 0.376953125 +71228 0.0357666015625 +71229 0.371978759765625 +71230 0.025177001953125 +71231 0.313140869140625 +71232 0.007843017578125 +71233 0.184417724609375 +71234 -0.01336669921875 +71235 0.011199951171875 +71236 -0.034576416015625 +71237 -0.171051025390625 +71238 -0.0531005859375 +71239 -0.33740234375 +71240 -0.067291259765625 +71241 -0.47198486328125 +71242 -0.075653076171875 +71243 -0.560394287109375 +71244 -0.075958251953125 +71245 -0.58056640625 +71246 -0.06988525390625 +71247 -0.54754638671875 +71248 -0.06256103515625 +71249 -0.508575439453125 +71250 -0.05377197265625 +71251 -0.459503173828125 +71252 -0.043060302734375 +71253 -0.394378662109375 +71254 -0.03472900390625 +71255 -0.35260009765625 +71256 -0.02667236328125 +71257 -0.31170654296875 +71258 -0.011383056640625 +71259 -0.197418212890625 +71260 0.011138916015625 +71261 -0.007965087890625 +71262 0.035614013671875 +71263 0.207489013671875 +71264 0.057830810546875 +71265 0.409210205078125 +71266 0.07513427734375 +71267 0.57208251953125 +71268 0.084381103515625 +71269 0.66595458984375 +71270 0.082305908203125 +71271 0.65875244140625 +71272 0.07080078125 +71273 0.56744384765625 +71274 0.054046630859375 +71275 0.431396484375 +71276 0.036773681640625 +71277 0.29443359375 +71278 0.0218505859375 +71279 0.182464599609375 +71280 0.00616455078125 +71281 0.06365966796875 +71282 -0.01153564453125 +71283 -0.075958251953125 +71284 -0.02618408203125 +71285 -0.189422607421875 +71286 -0.037109375 +71287 -0.271942138671875 +71288 -0.04620361328125 +71289 -0.342529296875 +71290 -0.049591064453125 +71291 -0.364166259765625 +71292 -0.04620361328125 +71293 -0.327239990234375 +71294 -0.04071044921875 +71295 -0.2769775390625 +71296 -0.037353515625 +71297 -0.253692626953125 +71298 -0.0347900390625 +71299 -0.24365234375 +71300 -0.028045654296875 +71301 -0.1983642578125 +71302 -0.01708984375 +71303 -0.116241455078125 +71304 -0.00616455078125 +71305 -0.036834716796875 +71306 0.003997802734375 +71307 0.034881591796875 +71308 0.012451171875 +71309 0.09124755859375 +71310 0.016632080078125 +71311 0.10888671875 +71312 0.020355224609375 +71313 0.125518798828125 +71314 0.025238037109375 +71315 0.15771484375 +71316 0.028411865234375 +71317 0.17828369140625 +71318 0.02813720703125 +71319 0.17108154296875 +71320 0.02374267578125 +71321 0.129974365234375 +71322 0.01812744140625 +71323 0.082427978515625 +71324 0.011260986328125 +71325 0.027679443359375 +71326 0.0 +71327 -0.065643310546875 +71328 -0.0115966796875 +71329 -0.15936279296875 +71330 -0.019195556640625 +71331 -0.21307373046875 +71332 -0.023529052734375 +71333 -0.234649658203125 +71334 -0.022003173828125 +71335 -0.2001953125 +71336 -0.0155029296875 +71337 -0.119171142578125 +71338 -0.007354736328125 +71339 -0.024749755859375 +71340 0.002777099609375 +71341 0.085784912109375 +71342 0.011383056640625 +71343 0.178131103515625 +71344 0.014678955078125 +71345 0.215576171875 +71346 0.01409912109375 +71347 0.211456298828125 +71348 0.0106201171875 +71349 0.17523193359375 +71350 0.006500244140625 +71351 0.128753662109375 +71352 0.004791259765625 +71353 0.1019287109375 +71354 0.003326416015625 +71355 0.0743408203125 +71356 0.001678466796875 +71357 0.04327392578125 +71358 0.002838134765625 +71359 0.038177490234375 +71360 0.00848388671875 +71361 0.076263427734375 +71362 0.01678466796875 +71363 0.14105224609375 +71364 0.02288818359375 +71365 0.186431884765625 +71366 0.024261474609375 +71367 0.188812255859375 +71368 0.019927978515625 +71369 0.1390380859375 +71370 0.010345458984375 +71371 0.041778564453125 +71372 -0.002044677734375 +71373 -0.079437255859375 +71374 -0.016693115234375 +71375 -0.219390869140625 +71376 -0.032501220703125 +71377 -0.367828369140625 +71378 -0.046356201171875 +71379 -0.494873046875 +71380 -0.053619384765625 +71381 -0.556243896484375 +71382 -0.049713134765625 +71383 -0.508697509765625 +71384 -0.037017822265625 +71385 -0.3756103515625 +71386 -0.021942138671875 +71387 -0.218902587890625 +71388 -0.00701904296875 +71389 -0.063751220703125 +71390 0.0079345703125 +71391 0.091552734375 +71392 0.0218505859375 +71393 0.23602294921875 +71394 0.03204345703125 +71395 0.342987060546875 +71396 0.0367431640625 +71397 0.39520263671875 +71398 0.03564453125 +71399 0.389373779296875 +71400 0.028656005859375 +71401 0.324249267578125 +71402 0.018341064453125 +71403 0.224090576171875 +71404 0.00836181640625 +71405 0.124267578125 +71406 -3.0517578125e-05 +71407 0.037078857421875 +71408 -0.0040283203125 +71409 -0.010101318359375 +71410 -0.003936767578125 +71411 -0.019439697265625 +71412 -0.00311279296875 +71413 -0.022796630859375 +71414 0.000274658203125 +71415 -0.001556396484375 +71416 0.00738525390625 +71417 0.056304931640625 +71418 0.013580322265625 +71419 0.106719970703125 +71420 0.013336181640625 +71421 0.096893310546875 +71422 0.008270263671875 +71423 0.042694091796875 +71424 0.002593994140625 +71425 -0.018035888671875 +71426 -0.00286865234375 +71427 -0.07586669921875 +71428 -0.007537841796875 +71429 -0.11944580078125 +71430 -0.01202392578125 +71431 -0.15972900390625 +71432 -0.0166015625 +71433 -0.202606201171875 +71434 -0.02117919921875 +71435 -0.24859619140625 +71436 -0.02618408203125 +71437 -0.30517578125 +71438 -0.030853271484375 +71439 -0.36212158203125 +71440 -0.033172607421875 +71441 -0.39141845703125 +71442 -0.030426025390625 +71443 -0.35528564453125 +71444 -0.022369384765625 +71445 -0.249969482421875 +71446 -0.010284423828125 +71447 -0.092864990234375 +71448 0.0037841796875 +71449 0.08905029296875 +71450 0.015411376953125 +71451 0.2352294921875 +71452 0.022613525390625 +71453 0.318817138671875 +71454 0.026641845703125 +71455 0.358642578125 +71456 0.026947021484375 +71457 0.347747802734375 +71458 0.0234375 +71459 0.28564453125 +71460 0.01971435546875 +71461 0.223175048828125 +71462 0.018341064453125 +71463 0.196746826171875 +71464 0.01739501953125 +71465 0.179840087890625 +71466 0.01568603515625 +71467 0.155548095703125 +71468 0.015167236328125 +71469 0.151214599609375 +71470 0.01513671875 +71471 0.156951904296875 +71472 0.0126953125 +71473 0.13177490234375 +71474 0.00970458984375 +71475 0.100799560546875 +71476 0.007843017578125 +71477 0.087127685546875 +71478 0.004608154296875 +71479 0.05487060546875 +71480 -0.000885009765625 +71481 -0.009002685546875 +71482 -0.008544921875 +71483 -0.10400390625 +71484 -0.018280029296875 +71485 -0.229400634765625 +71486 -0.027923583984375 +71487 -0.35552978515625 +71488 -0.034515380859375 +71489 -0.441925048828125 +71490 -0.037017822265625 +71491 -0.473846435546875 +71492 -0.036376953125 +71493 -0.464813232421875 +71494 -0.03289794921875 +71495 -0.419097900390625 +71496 -0.02642822265625 +71497 -0.334320068359375 +71498 -0.01824951171875 +71499 -0.227935791015625 +71500 -0.010101318359375 +71501 -0.12347412109375 +71502 -0.00250244140625 +71503 -0.02764892578125 +71504 0.00579833984375 +71505 0.077667236328125 +71506 0.0162353515625 +71507 0.2132568359375 +71508 0.02947998046875 +71509 0.38885498046875 +71510 0.0439453125 +71511 0.582794189453125 +71512 0.055206298828125 +71513 0.734039306640625 +71514 0.0601806640625 +71515 0.800140380859375 +71516 0.058685302734375 +71517 0.7783203125 +71518 0.05047607421875 +71519 0.6651611328125 +71520 0.035491943359375 +71521 0.45965576171875 +71522 0.016448974609375 +71523 0.199188232421875 +71524 -0.00189208984375 +71525 -0.050689697265625 +71526 -0.015411376953125 +71527 -0.23297119140625 +71528 -0.0228271484375 +71529 -0.33013916015625 +71530 -0.0260009765625 +71531 -0.368408203125 +71532 -0.02716064453125 +71533 -0.378936767578125 +71534 -0.027435302734375 +71535 -0.376983642578125 +71536 -0.02801513671875 +71537 -0.37969970703125 +71538 -0.0291748046875 +71539 -0.391510009765625 +71540 -0.028961181640625 +71541 -0.385345458984375 +71542 -0.025970458984375 +71543 -0.3419189453125 +71544 -0.021728515625 +71545 -0.28289794921875 +71546 -0.019378662109375 +71547 -0.251617431640625 +71548 -0.020233154296875 +71549 -0.266143798828125 +71550 -0.020477294921875 +71551 -0.273345947265625 +71552 -0.016082763671875 +71553 -0.216796875 +71554 -0.00933837890625 +71555 -0.128265380859375 +71556 -0.00457763671875 +71557 -0.068145751953125 +71558 -0.0023193359375 +71559 -0.0430908203125 +71560 -0.000518798828125 +71561 -0.024444580078125 +71562 0.00311279296875 +71563 0.020721435546875 +71564 0.0108642578125 +71565 0.124481201171875 +71566 0.0206298828125 +71567 0.25787353515625 +71568 0.0294189453125 +71569 0.379119873046875 +71570 0.03662109375 +71571 0.47991943359375 +71572 0.0399169921875 +71573 0.5281982421875 +71574 0.03839111328125 +71575 0.511138916015625 +71576 0.0340576171875 +71577 0.456207275390625 +71578 0.03009033203125 +71579 0.407470703125 +71580 0.02789306640625 +71581 0.383758544921875 +71582 0.02545166015625 +71583 0.35687255859375 +71584 0.021728515625 +71585 0.31182861328125 +71586 0.01690673828125 +71587 0.250885009765625 +71588 0.0103759765625 +71589 0.1654052734375 +71590 0.000732421875 +71591 0.035247802734375 +71592 -0.01214599609375 +71593 -0.142059326171875 +71594 -0.026031494140625 +71595 -0.33563232421875 +71596 -0.0401611328125 +71597 -0.5345458984375 +71598 -0.053314208984375 +71599 -0.72186279296875 +71600 -0.061126708984375 +71601 -0.836669921875 +71602 -0.060302734375 +71603 -0.8326416015625 +71604 -0.05230712890625 +71605 -0.7296142578125 +71606 -0.04119873046875 +71607 -0.582550048828125 +71608 -0.030487060546875 +71609 -0.440093994140625 +71610 -0.021728515625 +71611 -0.324310302734375 +71612 -0.01251220703125 +71613 -0.20147705078125 +71614 -0.00091552734375 +71615 -0.044647216796875 +71616 0.00994873046875 +71617 0.103973388671875 +71618 0.017059326171875 +71619 0.202392578125 +71620 0.02142333984375 +71621 0.264495849609375 +71622 0.02655029296875 +71623 0.338897705078125 +71624 0.03375244140625 +71625 0.443817138671875 +71626 0.04058837890625 +71627 0.545074462890625 +71628 0.0452880859375 +71629 0.6173095703125 +71630 0.047271728515625 +71631 0.6524658203125 +71632 0.047515869140625 +71633 0.66339111328125 +71634 0.046478271484375 +71635 0.6561279296875 +71636 0.04241943359375 +71637 0.606781005859375 +71638 0.034393310546875 +71639 0.501190185546875 +71640 0.02337646484375 +71641 0.352783203125 +71642 0.010467529296875 +71643 0.176544189453125 +71644 -0.004791259765625 +71645 -0.034820556640625 +71646 -0.020751953125 +71647 -0.258209228515625 +71648 -0.033721923828125 +71649 -0.44244384765625 +71650 -0.0428466796875 +71651 -0.5753173828125 +71652 -0.047821044921875 +71653 -0.65203857421875 +71654 -0.04644775390625 +71655 -0.641632080078125 +71656 -0.040130615234375 +71657 -0.562164306640625 +71658 -0.032073974609375 +71659 -0.458038330078125 +71660 -0.023834228515625 +71661 -0.350555419921875 +71662 -0.01690673828125 +71663 -0.260528564453125 +71664 -0.011627197265625 +71665 -0.192108154296875 +71666 -0.00775146484375 +71667 -0.141937255859375 +71668 -0.004730224609375 +71669 -0.1021728515625 +71670 -0.001861572265625 +71671 -0.062896728515625 +71672 0.001708984375 +71673 -0.011932373046875 +71674 0.006866455078125 +71675 0.062835693359375 +71676 0.012725830078125 +71677 0.148712158203125 +71678 0.019012451171875 +71679 0.241729736328125 +71680 0.02593994140625 +71681 0.34912109375 +71682 0.031829833984375 +71683 0.457305908203125 +71684 0.03515625 +71685 0.54388427734375 +71686 0.034881591796875 +71687 0.5728759765625 +71688 0.02984619140625 +71689 0.506591796875 +71690 0.020660400390625 +71691 0.351226806640625 +71692 0.00921630859375 +71693 0.146514892578125 +71694 -0.002105712890625 +71695 -0.05523681640625 +71696 -0.011566162109375 +71697 -0.21624755859375 +71698 -0.018951416015625 +71699 -0.334930419921875 +71700 -0.02374267578125 +71701 -0.402984619140625 +71702 -0.02667236328125 +71703 -0.4412841796875 +71704 -0.029541015625 +71705 -0.49578857421875 +71706 -0.032135009765625 +71707 -0.5601806640625 +71708 -0.03314208984375 +71709 -0.600738525390625 +71710 -0.03131103515625 +71711 -0.584228515625 +71712 -0.025482177734375 +71713 -0.47930908203125 +71714 -0.0155029296875 +71715 -0.27935791015625 +71716 -0.00250244140625 +71717 -0.0089111328125 +71718 0.0108642578125 +71719 0.268798828125 +71720 0.021575927734375 +71721 0.482818603515625 +71722 0.02838134765625 +71723 0.60369873046875 +71724 0.031890869140625 +71725 0.650421142578125 +71726 0.033721923828125 +71727 0.66400146484375 +71728 0.033660888671875 +71729 0.6414794921875 +71730 0.031280517578125 +71731 0.572540283203125 +71732 0.0281982421875 +71733 0.498138427734375 +71734 0.025299072265625 +71735 0.439453125 +71736 0.02178955078125 +71737 0.375518798828125 +71738 0.016448974609375 +71739 0.274505615234375 +71740 0.008270263671875 +71741 0.1087646484375 +71742 -0.001739501953125 +71743 -0.099395751953125 +71744 -0.012237548828125 +71745 -0.3182373046875 +71746 -0.023162841796875 +71747 -0.5489501953125 +71748 -0.033660888671875 +71749 -0.7738037109375 +71750 -0.04156494140625 +71751 -0.86383056640625 +71752 -0.045501708984375 +71753 -0.870391845703125 +71754 -0.046142578125 +71755 -0.86895751953125 +71756 -0.043975830078125 +71757 -0.861053466796875 +71758 -0.038330078125 +71759 -0.765869140625 +71760 -0.02874755859375 +71761 -0.5301513671875 +71762 -0.01556396484375 +71763 -0.214691162109375 +71764 -0.000518798828125 +71765 0.137359619140625 +71766 0.014251708984375 +71767 0.474822998046875 +71768 0.0272216796875 +71769 0.76239013671875 +71770 0.037261962890625 +71771 0.867462158203125 +71772 0.0443115234375 +71773 0.870361328125 +71774 0.047821044921875 +71775 0.86480712890625 +71776 0.0479736328125 +71777 0.831817626953125 +71778 0.045684814453125 +71779 0.677581787109375 +71780 0.041168212890625 +71781 0.495880126953125 +71782 0.03515625 +71783 0.30767822265625 +71784 0.027740478515625 +71785 0.116180419921875 +71786 0.017669677734375 +71787 -0.110748291015625 +71788 0.004669189453125 +71789 -0.381805419921875 +71790 -0.009490966796875 +71791 -0.6572265625 +71792 -0.022369384765625 +71793 -0.857421875 +71794 -0.032196044921875 +71795 -0.870391845703125 +71796 -0.03863525390625 +71797 -0.870391845703125 +71798 -0.042755126953125 +71799 -0.86444091796875 +71800 -0.045928955078125 +71801 -0.85723876953125 +71802 -0.047393798828125 +71803 -0.790008544921875 +71804 -0.044952392578125 +71805 -0.62847900390625 +71806 -0.0384521484375 +71807 -0.3956298828125 +71808 -0.0291748046875 +71809 -0.126708984375 +71810 -0.0181884765625 +71811 0.150115966796875 +71812 -0.005950927734375 +71813 0.424041748046875 +71814 0.00640869140625 +71815 0.670623779296875 +71816 0.017303466796875 +71817 0.854522705078125 +71818 0.026031494140625 +71819 0.866485595703125 +71820 0.03192138671875 +71821 0.86920166015625 +71822 0.03570556640625 +71823 0.8653564453125 +71824 0.037872314453125 +71825 0.857147216796875 +71826 0.03826904296875 +71827 0.766845703125 +71828 0.037078857421875 +71829 0.628509521484375 +71830 0.03399658203125 +71831 0.462127685546875 +71832 0.029998779296875 +71833 0.297210693359375 +71834 0.025543212890625 +71835 0.14862060546875 +71836 0.019744873046875 +71837 -0.00537109375 +71838 0.012908935546875 +71839 -0.15753173828125 +71840 0.004913330078125 +71841 -0.31304931640625 +71842 -0.0047607421875 +71843 -0.48876953125 +71844 -0.01422119140625 +71845 -0.6416015625 +71846 -0.0224609375 +71847 -0.751373291015625 +71848 -0.030364990234375 +71849 -0.84619140625 +71850 -0.03729248046875 +71851 -0.861297607421875 +71852 -0.04193115234375 +71853 -0.863250732421875 +71854 -0.042999267578125 +71855 -0.856597900390625 +71856 -0.040985107421875 +71857 -0.7498779296875 +71858 -0.038177490234375 +71859 -0.624542236328125 +71860 -0.03369140625 +71861 -0.47808837890625 +71862 -0.02520751953125 +71863 -0.253387451171875 +71864 -0.014556884765625 +71865 0.003692626953125 +71866 -0.004486083984375 +71867 0.2257080078125 +71868 0.005462646484375 +71869 0.427154541015625 +71870 0.01654052734375 +71871 0.643218994140625 +71872 0.028350830078125 +71873 0.855926513671875 +71874 0.03857421875 +71875 0.870361328125 +71876 0.045257568359375 +71877 0.870361328125 +71878 0.048675537109375 +71879 0.862762451171875 +71880 0.0487060546875 +71881 0.79669189453125 +71882 0.04498291015625 +71883 0.595794677734375 +71884 0.038665771484375 +71885 0.362152099609375 +71886 0.0308837890625 +71887 0.1270751953125 +71888 0.022491455078125 +71889 -0.086944580078125 +71890 0.013580322265625 +71891 -0.2784423828125 +71892 0.00274658203125 +71893 -0.484832763671875 +71894 -0.010711669921875 +71895 -0.729583740234375 +71896 -0.0247802734375 +71897 -0.86688232421875 +71898 -0.036956787109375 +71899 -0.870391845703125 +71900 -0.046966552734375 +71901 -0.86859130859375 +71902 -0.05474853515625 +71903 -0.86279296875 +71904 -0.058868408203125 +71905 -0.817962646484375 +71906 -0.057525634765625 +71907 -0.6116943359375 +71908 -0.050445556640625 +71909 -0.3128662109375 +71910 -0.03900146484375 +71911 0.039398193359375 +71912 -0.024017333984375 +71913 0.422821044921875 +71914 -0.006805419921875 +71915 0.805145263671875 +71916 0.00982666015625 +71917 0.870361328125 +71918 0.02362060546875 +71919 0.870361328125 +71920 0.034088134765625 +71921 0.860015869140625 +71922 0.04095458984375 +71923 0.727935791015625 +71924 0.04400634765625 +71925 0.48114013671875 +71926 0.044219970703125 +71927 0.2059326171875 +71928 0.04248046875 +71929 -0.06103515625 +71930 0.0391845703125 +71931 -0.29913330078125 +71932 0.03375244140625 +71933 -0.516204833984375 +71934 0.025634765625 +71935 -0.7252197265625 +71936 0.015625 +71937 -0.85980224609375 +71938 0.005523681640625 +71939 -0.870391845703125 +71940 -0.003387451171875 +71941 -0.870391845703125 +71942 -0.010711669921875 +71943 -0.858062744140625 +71944 -0.016326904296875 +71945 -0.673004150390625 +71946 -0.020599365234375 +71947 -0.42694091796875 +71948 -0.02386474609375 +71949 -0.2100830078125 +71950 -0.026092529296875 +71951 -0.0362548828125 +71952 -0.02703857421875 +71953 0.10943603515625 +71954 -0.026641845703125 +71955 0.23516845703125 +71956 -0.024658203125 +71957 0.373687744140625 +71958 -0.021209716796875 +71959 0.517791748046875 +71960 -0.016998291015625 +71961 0.602783203125 +71962 -0.01214599609375 +71963 0.635711669921875 +71964 -0.00665283203125 +71965 0.655181884765625 +71966 -0.00079345703125 +71967 0.65948486328125 +71968 0.00506591796875 +71969 0.651275634765625 +71970 0.010498046875 +71971 0.61846923828125 +71972 0.015045166015625 +71973 0.53753662109375 +71974 0.0184326171875 +71975 0.404144287109375 +71976 0.02044677734375 +71977 0.22186279296875 +71978 0.0211181640625 +71979 0.003997802734375 +71980 0.020538330078125 +71981 -0.22100830078125 +71982 0.018890380859375 +71983 -0.42449951171875 +71984 0.016448974609375 +71985 -0.579833984375 +71986 0.013641357421875 +71987 -0.641876220703125 +71988 0.01055908203125 +71989 -0.6177978515625 +71990 0.006866455078125 +71991 -0.575531005859375 +71992 0.002716064453125 +71993 -0.526336669921875 +71994 -0.00128173828125 +71995 -0.42645263671875 +71996 -0.00469970703125 +71997 -0.2581787109375 +71998 -0.00762939453125 +71999 -0.068695068359375 +72000 -0.010223388671875 +72001 0.09222412109375 +72002 -0.012237548828125 +72003 0.232147216796875 +72004 -0.013519287109375 +72005 0.3509521484375 +72006 -0.0142822265625 +72007 0.410064697265625 +72008 -0.0147705078125 +72009 0.372955322265625 +72010 -0.014892578125 +72011 0.2554931640625 +72012 -0.014312744140625 +72013 0.10711669921875 +72014 -0.01300048828125 +72015 -0.052886962890625 +72016 -0.01080322265625 +72017 -0.186279296875 +72018 -0.0074462890625 +72019 -0.23291015625 +72020 -0.0032958984375 +72021 -0.209442138671875 +72022 0.00091552734375 +72023 -0.174163818359375 +72024 0.004974365234375 +72025 -0.126739501953125 +72026 0.008819580078125 +72027 -0.048126220703125 +72028 0.01214599609375 +72029 0.0426025390625 +72030 0.014495849609375 +72031 0.10748291015625 +72032 0.015777587890625 +72033 0.1409912109375 +72034 0.016387939453125 +72035 0.19708251953125 +72036 0.016357421875 +72037 0.273651123046875 +72038 0.01531982421875 +72039 0.31768798828125 +72040 0.01348876953125 +72041 0.341094970703125 +72042 0.01116943359375 +72043 0.368011474609375 +72044 0.00830078125 +72045 0.37249755859375 +72046 0.004608154296875 +72047 0.30072021484375 +72048 0.000274658203125 +72049 0.1517333984375 +72050 -0.003997802734375 +72051 -0.01470947265625 +72052 -0.00799560546875 +72053 -0.1883544921875 +72054 -0.011627197265625 +72055 -0.372711181640625 +72056 -0.01434326171875 +72057 -0.51397705078125 +72058 -0.015777587890625 +72059 -0.57177734375 +72060 -0.015838623046875 +72061 -0.53948974609375 +72062 -0.0146484375 +72063 -0.43511962890625 +72064 -0.012542724609375 +72065 -0.2962646484375 +72066 -0.0098876953125 +72067 -0.161102294921875 +72068 -0.006927490234375 +72069 -0.0435791015625 +72070 -0.003753662109375 +72071 0.060394287109375 +72072 -0.0006103515625 +72073 0.13665771484375 +72074 0.002197265625 +72075 0.170135498046875 +72076 0.004608154296875 +72077 0.16552734375 +72078 0.0067138671875 +72079 0.15728759765625 +72080 0.00848388671875 +72081 0.150787353515625 +72082 0.009613037109375 +72083 0.12200927734375 +72084 0.0101318359375 +72085 0.080108642578125 +72086 0.010223388671875 +72087 0.05126953125 +72088 0.01007080078125 +72089 0.062896728515625 +72090 0.009552001953125 +72091 0.09271240234375 +72092 0.00836181640625 +72093 0.092987060546875 +72094 0.00665283203125 +72095 0.07855224609375 +72096 0.004669189453125 +72097 0.06427001953125 +72098 0.002410888671875 +72099 0.0347900390625 +72100 0.0 +72101 -0.01171875 +72102 -0.0023193359375 +72103 -0.056060791015625 +72104 -0.00408935546875 +72105 -0.055511474609375 +72106 -0.005218505859375 +72107 -0.010467529296875 +72108 -0.006103515625 +72109 0.02508544921875 +72110 -0.006866455078125 +72111 0.025665283203125 +72112 -0.00726318359375 +72113 0.017333984375 +72114 -0.007293701171875 +72115 0.00189208984375 +72116 -0.007049560546875 +72117 -0.03173828125 +72118 -0.0064697265625 +72119 -0.071502685546875 +72120 -0.005767822265625 +72121 -0.13543701171875 +72122 -0.004974365234375 +72123 -0.219970703125 +72124 -0.00396728515625 +72125 -0.300506591796875 +72126 -0.002838134765625 +72127 -0.376312255859375 +72128 -0.001434326171875 +72129 -0.416107177734375 +72130 0.000518798828125 +72131 -0.371124267578125 +72132 0.002899169921875 +72133 -0.242279052734375 +72134 0.00531005859375 +72135 -0.069732666015625 +72136 0.007537841796875 +72137 0.125640869140625 +72138 0.009307861328125 +72139 0.31268310546875 +72140 0.01031494140625 +72141 0.45501708984375 +72142 0.0106201171875 +72143 0.554779052734375 +72144 0.01025390625 +72145 0.61065673828125 +72146 0.0091552734375 +72147 0.610931396484375 +72148 0.0072021484375 +72149 0.531463623046875 +72150 0.004608154296875 +72151 0.3883056640625 +72152 0.00189208984375 +72153 0.23468017578125 +72154 -0.0006103515625 +72155 0.095245361328125 +72156 -0.00262451171875 +72157 -0.00396728515625 +72158 -0.0040283203125 +72159 -0.04852294921875 +72160 -0.0048828125 +72161 -0.055145263671875 +72162 -0.00555419921875 +72163 -0.0758056640625 +72164 -0.0062255859375 +72165 -0.138702392578125 +72166 -0.00665283203125 +72167 -0.209197998046875 +72168 -0.006866455078125 +72169 -0.289031982421875 +72170 -0.006866455078125 +72171 -0.37884521484375 +72172 -0.006561279296875 +72173 -0.456329345703125 +72174 -0.005950927734375 +72175 -0.51641845703125 +72176 -0.0047607421875 +72177 -0.519287109375 +72178 -0.003021240234375 +72179 -0.458251953125 +72180 -0.001220703125 +72181 -0.384796142578125 +72182 0.000335693359375 +72183 -0.323699951171875 +72184 0.001678466796875 +72185 -0.269287109375 +72186 0.002960205078125 +72187 -0.1951904296875 +72188 0.004150390625 +72189 -0.100006103515625 +72190 0.005035400390625 +72191 -0.01055908203125 +72192 0.00567626953125 +72193 0.1033935546875 +72194 0.006195068359375 +72195 0.24908447265625 +72196 0.00653076171875 +72197 0.373199462890625 +72198 0.006591796875 +72199 0.45806884765625 +72200 0.00634765625 +72201 0.511474609375 +72202 0.005767822265625 +72203 0.565399169921875 +72204 0.004852294921875 +72205 0.61138916015625 +72206 0.003662109375 +72207 0.5897216796875 +72208 0.00225830078125 +72209 0.4906005859375 +72210 0.000701904296875 +72211 0.33148193359375 +72212 -0.0008544921875 +72213 0.147796630859375 +72214 -0.0023193359375 +72215 -0.01873779296875 +72216 -0.00360107421875 +72217 -0.140289306640625 +72218 -0.004608154296875 +72219 -0.191986083984375 +72220 -0.00531005859375 +72221 -0.184295654296875 +72222 -0.00567626953125 +72223 -0.161834716796875 +72224 -0.005706787109375 +72225 -0.166595458984375 +72226 -0.005401611328125 +72227 -0.19390869140625 +72228 -0.004791259765625 +72229 -0.22442626953125 +72230 -0.00390625 +72231 -0.279754638671875 +72232 -0.0028076171875 +72233 -0.3389892578125 +72234 -0.001556396484375 +72235 -0.3543701171875 +72236 -0.000213623046875 +72237 -0.348175048828125 +72238 0.0010986328125 +72239 -0.32598876953125 +72240 0.0023193359375 +72241 -0.2581787109375 +72242 0.003387451171875 +72243 -0.139801025390625 +72244 0.004241943359375 +72245 0.014617919921875 +72246 0.004852294921875 +72247 0.144378662109375 +72248 0.00518798828125 +72249 0.221038818359375 +72250 0.005218505859375 +72251 0.27069091796875 +72252 0.004974365234375 +72253 0.294036865234375 +72254 0.00445556640625 +72255 0.311767578125 +72256 0.003753662109375 +72257 0.339141845703125 +72258 0.00323486328125 +72259 0.360260009765625 +72260 0.002838134765625 +72261 0.360504150390625 +72262 0.001739501953125 +72263 0.308380126953125 +72264 -0.00067138671875 +72265 0.18170166015625 +72266 -0.003875732421875 +72267 0.0047607421875 +72268 -0.00689697265625 +72269 -0.17559814453125 +72270 -0.008758544921875 +72271 -0.3143310546875 +72272 -0.008544921875 +72273 -0.36785888671875 +72274 -0.006988525390625 +72275 -0.36248779296875 +72276 -0.0052490234375 +72277 -0.343536376953125 +72278 -0.003173828125 +72279 -0.3018798828125 +72280 -0.00067138671875 +72281 -0.231414794921875 +72282 0.002532958984375 +72283 -0.117645263671875 +72284 0.005615234375 +72285 0.007049560546875 +72286 0.00732421875 +72287 0.087982177734375 +72288 0.008026123046875 +72289 0.13946533203125 +72290 0.008056640625 +72291 0.17425537109375 +72292 0.007415771484375 +72293 0.188201904296875 +72294 0.00592041015625 +72295 0.171234130859375 +72296 0.00347900390625 +72297 0.118438720703125 +72298 0.0008544921875 +72299 0.05706787109375 +72300 -0.001800537109375 +72301 -0.010711669921875 +72302 -0.004608154296875 +72303 -0.0914306640625 +72304 -0.006988525390625 +72305 -0.162322998046875 +72306 -0.00823974609375 +72307 -0.194549560546875 +72308 -0.007415771484375 +72309 -0.1492919921875 +72310 -0.004364013671875 +72311 -0.02166748046875 +72312 -0.00067138671875 +72313 0.124053955078125 +72314 0.001800537109375 +72315 0.211151123046875 +72316 0.003021240234375 +72317 0.240447998046875 +72318 0.00372314453125 +72319 0.242218017578125 +72320 0.00408935546875 +72321 0.2257080078125 +72322 0.004119873046875 +72323 0.194366455078125 +72324 0.003021240234375 +72325 0.115509033203125 +72326 0.0013427734375 +72327 0.0128173828125 +72328 0.000457763671875 +72329 -0.053802490234375 +72330 -0.000274658203125 +72331 -0.110626220703125 +72332 -0.00189208984375 +72333 -0.199493408203125 +72334 -0.003814697265625 +72335 -0.29437255859375 +72336 -0.0045166015625 +72337 -0.33221435546875 +72338 -0.00323486328125 +72339 -0.27972412109375 +72340 -0.0010986328125 +72341 -0.185333251953125 +72342 0.0 +72343 -0.128204345703125 +72344 -9.1552734375e-05 +72345 -0.115692138671875 +72346 -0.0006103515625 +72347 -0.116455078125 +72348 -0.000946044921875 +72349 -0.105926513671875 +72350 -0.000335693359375 +72351 -0.053955078125 +72352 0.00146484375 +72353 0.048797607421875 +72354 0.003387451171875 +72355 0.157318115234375 +72356 0.004058837890625 +72357 0.212005615234375 +72358 0.003631591796875 +72359 0.218475341796875 +72360 0.003570556640625 +72361 0.23724365234375 +72362 0.00482177734375 +72363 0.30535888671875 +72364 0.006378173828125 +72365 0.38128662109375 +72366 0.0068359375 +72367 0.404449462890625 +72368 0.00665283203125 +72369 0.3944091796875 +72370 0.006744384765625 +72371 0.3885498046875 +72372 0.006500244140625 +72373 0.362640380859375 +72374 0.0048828125 +72375 0.27362060546875 +72376 0.001739501953125 +72377 0.11712646484375 +72378 -0.001708984375 +72379 -0.054901123046875 +72380 -0.004241943359375 +72381 -0.19085693359375 +72382 -0.005828857421875 +72383 -0.28570556640625 +72384 -0.0064697265625 +72385 -0.339263916015625 +72386 -0.0068359375 +72387 -0.3775634765625 +72388 -0.008026123046875 +72389 -0.445709228515625 +72390 -0.00982666015625 +72391 -0.535064697265625 +72392 -0.011871337890625 +72393 -0.629058837890625 +72394 -0.013427734375 +72395 -0.697601318359375 +72396 -0.013641357421875 +72397 -0.70391845703125 +72398 -0.012359619140625 +72399 -0.6424560546875 +72400 -0.009033203125 +72401 -0.491241455078125 +72402 -0.0040283203125 +72403 -0.265716552734375 +72404 0.001220703125 +72405 -0.023712158203125 +72406 0.0059814453125 +72407 0.201751708984375 +72408 0.009429931640625 +72409 0.375823974609375 +72410 0.011322021484375 +72411 0.485076904296875 +72412 0.012664794921875 +72413 0.56884765625 +72414 0.013671875 +72415 0.634765625 +72416 0.01324462890625 +72417 0.63763427734375 +72418 0.01116943359375 +72419 0.5660400390625 +72420 0.008697509765625 +72421 0.4720458984375 +72422 0.007080078125 +72423 0.40692138671875 +72424 0.006500244140625 +72425 0.3778076171875 +72426 0.006744384765625 +72427 0.376953125 +72428 0.006988525390625 +72429 0.371978759765625 +72430 0.006011962890625 +72431 0.313140869140625 +72432 0.003387451171875 +72433 0.184417724609375 +72434 -0.000244140625 +72435 0.011199951171875 +72436 -0.0040283203125 +72437 -0.171051025390625 +72438 -0.00738525390625 +72439 -0.33740234375 +72440 -0.010009765625 +72441 -0.47198486328125 +72442 -0.0115966796875 +72443 -0.560394287109375 +72444 -0.01165771484375 +72445 -0.58056640625 +72446 -0.01055908203125 +72447 -0.54754638671875 +72448 -0.00958251953125 +72449 -0.508575439453125 +72450 -0.008392333984375 +72451 -0.459503173828125 +72452 -0.007049560546875 +72453 -0.394378662109375 +72454 -0.00762939453125 +72455 -0.35260009765625 +72456 -0.00872802734375 +72457 -0.31170654296875 +72458 -0.006011962890625 +72459 -0.197418212890625 +72460 0.00079345703125 +72461 -0.007965087890625 +72462 0.00909423828125 +72463 0.207489013671875 +72464 0.016845703125 +72465 0.409210205078125 +72466 0.0228271484375 +72467 0.57208251953125 +72468 0.0255126953125 +72469 0.66595458984375 +72470 0.023223876953125 +72471 0.65875244140625 +72472 0.016998291015625 +72473 0.56744384765625 +72474 0.00909423828125 +72475 0.431396484375 +72476 0.001953125 +72477 0.29443359375 +72478 -0.00299072265625 +72479 0.182464599609375 +72480 -0.00762939453125 +72481 0.06365966796875 +72482 -0.012847900390625 +72483 -0.075958251953125 +72484 -0.01617431640625 +72485 -0.189422607421875 +72486 -0.017486572265625 +72487 -0.271942138671875 +72488 -0.01806640625 +72489 -0.342529296875 +72490 -0.01605224609375 +72491 -0.364166259765625 +72492 -0.011077880859375 +72493 -0.327239990234375 +72494 -0.005828857421875 +72495 -0.2769775390625 +72496 -0.002655029296875 +72497 -0.253692626953125 +72498 -0.000885009765625 +72499 -0.24365234375 +72500 0.00213623046875 +72501 -0.1983642578125 +72502 0.006500244140625 +72503 -0.116241455078125 +72504 0.010009765625 +72505 -0.036834716796875 +72506 0.012451171875 +72507 0.034881591796875 +72508 0.013519287109375 +72509 0.09124755859375 +72510 0.012054443359375 +72511 0.10888671875 +72512 0.010284423828125 +72513 0.125518798828125 +72514 0.00927734375 +72515 0.15771484375 +72516 0.007659912109375 +72517 0.17828369140625 +72518 0.00469970703125 +72519 0.17108154296875 +72520 0.00018310546875 +72521 0.129974365234375 +72522 -0.00421142578125 +72523 0.082427978515625 +72524 -0.0084228515625 +72525 0.027679443359375 +72526 -0.01416015625 +72527 -0.065643310546875 +72528 -0.019287109375 +72529 -0.15936279296875 +72530 -0.021575927734375 +72531 -0.21307373046875 +72532 -0.021514892578125 +72533 -0.234649658203125 +72534 -0.01788330078125 +72535 -0.2001953125 +72536 -0.01129150390625 +72537 -0.119171142578125 +72538 -0.003753662109375 +72539 -0.024749755859375 +72540 0.0047607421875 +72541 0.085784912109375 +72542 0.01214599609375 +72543 0.178131103515625 +72544 0.016265869140625 +72545 0.215576171875 +72546 0.01776123046875 +72547 0.211456298828125 +72548 0.017120361328125 +72549 0.17523193359375 +72550 0.015472412109375 +72551 0.128753662109375 +72552 0.01446533203125 +72553 0.1019287109375 +72554 0.012939453125 +72555 0.0743408203125 +72556 0.0107421875 +72557 0.04327392578125 +72558 0.009552001953125 +72559 0.038177490234375 +72560 0.010406494140625 +72561 0.076263427734375 +72562 0.012420654296875 +72563 0.14105224609375 +72564 0.01312255859375 +72565 0.186431884765625 +72566 0.011322021484375 +72567 0.188812255859375 +72568 0.006622314453125 +72569 0.1390380859375 +72570 -0.000579833984375 +72571 0.041778564453125 +72572 -0.008880615234375 +72573 -0.079437255859375 +72574 -0.017913818359375 +72575 -0.219390869140625 +72576 -0.027008056640625 +72577 -0.367828369140625 +72578 -0.03448486328125 +72579 -0.494873046875 +72580 -0.037841796875 +72581 -0.556243896484375 +72582 -0.034698486328125 +72583 -0.508697509765625 +72584 -0.026397705078125 +72585 -0.3756103515625 +72586 -0.0164794921875 +72587 -0.218902587890625 +72588 -0.006439208984375 +72589 -0.063751220703125 +72590 0.003692626953125 +72591 0.091552734375 +72592 0.01324462890625 +72593 0.23602294921875 +72594 0.0206298828125 +72595 0.342987060546875 +72596 0.02484130859375 +72597 0.39520263671875 +72598 0.025634765625 +72599 0.389373779296875 +72600 0.022857666015625 +72601 0.324249267578125 +72602 0.017852783203125 +72603 0.224090576171875 +72604 0.0125732421875 +72605 0.124267578125 +72606 0.007720947265625 +72607 0.037078857421875 +72608 0.004791259765625 +72609 -0.010101318359375 +72610 0.003692626953125 +72611 -0.019439697265625 +72612 0.002685546875 +72613 -0.022796630859375 +72614 0.00286865234375 +72615 -0.001556396484375 +72616 0.00494384765625 +72617 0.056304931640625 +72618 0.006500244140625 +72619 0.106719970703125 +72620 0.004669189453125 +72621 0.096893310546875 +72622 0.00042724609375 +72623 0.042694091796875 +72624 -0.003997802734375 +72625 -0.018035888671875 +72626 -0.008056640625 +72627 -0.07586669921875 +72628 -0.01104736328125 +72629 -0.11944580078125 +72630 -0.0135498046875 +72631 -0.15972900390625 +72632 -0.015899658203125 +72633 -0.202606201171875 +72634 -0.01812744140625 +72635 -0.24859619140625 +72636 -0.02069091796875 +72637 -0.30517578125 +72638 -0.0230712890625 +72639 -0.36212158203125 +72640 -0.02374267578125 +72641 -0.39141845703125 +72642 -0.020660400390625 +72643 -0.35528564453125 +72644 -0.013671875 +72645 -0.249969482421875 +72646 -0.0037841796875 +72647 -0.092864990234375 +72648 0.007354736328125 +72649 0.08905029296875 +72650 0.016357421875 +72651 0.2352294921875 +72652 0.02166748046875 +72653 0.318817138671875 +72654 0.0242919921875 +72655 0.358642578125 +72656 0.023834228515625 +72657 0.347747802734375 +72658 0.020294189453125 +72659 0.28564453125 +72660 0.0164794921875 +72661 0.223175048828125 +72662 0.014495849609375 +72663 0.196746826171875 +72664 0.01287841796875 +72665 0.179840087890625 +72666 0.01068115234375 +72667 0.155548095703125 +72668 0.009521484375 +72669 0.151214599609375 +72670 0.008880615234375 +72671 0.156951904296875 +72672 0.00653076171875 +72673 0.13177490234375 +72674 0.00396728515625 +72675 0.100799560546875 +72676 0.002471923828125 +72677 0.087127685546875 +72678 9.1552734375e-05 +72679 0.05487060546875 +72680 -0.00384521484375 +72681 -0.009002685546875 +72682 -0.009307861328125 +72683 -0.10400390625 +72684 -0.0162353515625 +72685 -0.229400634765625 +72686 -0.02301025390625 +72687 -0.35552978515625 +72688 -0.02734375 +72689 -0.441925048828125 +72690 -0.028472900390625 +72691 -0.473846435546875 +72692 -0.027191162109375 +72693 -0.464813232421875 +72694 -0.023773193359375 +72695 -0.419097900390625 +72696 -0.018157958984375 +72697 -0.334320068359375 +72698 -0.0113525390625 +72699 -0.227935791015625 +72700 -0.004730224609375 +72701 -0.12347412109375 +72702 0.001251220703125 +72703 -0.02764892578125 +72704 0.007537841796875 +72705 0.077667236328125 +72706 0.015533447265625 +72707 0.2132568359375 +72708 0.026580810546875 +72709 0.38885498046875 +72710 0.039459228515625 +72711 0.582794189453125 +72712 0.04925537109375 +72713 0.734039306640625 +72714 0.0526123046875 +72715 0.800140380859375 +72716 0.04949951171875 +72717 0.7783203125 +72718 0.039703369140625 +72719 0.6651611328125 +72720 0.023101806640625 +72721 0.45965576171875 +72722 0.002899169921875 +72723 0.199188232421875 +72724 -0.015380859375 +72725 -0.050689697265625 +72726 -0.0269775390625 +72727 -0.23297119140625 +72728 -0.030670166015625 +72729 -0.33013916015625 +72730 -0.029083251953125 +72731 -0.368408203125 +72732 -0.025238037109375 +72733 -0.378936767578125 +72734 -0.02081298828125 +72735 -0.376983642578125 +72736 -0.017547607421875 +72737 -0.37969970703125 +72738 -0.016021728515625 +72739 -0.391510009765625 +72740 -0.01397705078125 +72741 -0.385345458984375 +72742 -0.009765625 +72743 -0.3419189453125 +72744 -0.005279541015625 +72745 -0.28289794921875 +72746 -0.004241943359375 +72747 -0.251617431640625 +72748 -0.008148193359375 +72749 -0.266143798828125 +72750 -0.01214599609375 +72751 -0.273345947265625 +72752 -0.011077880859375 +72753 -0.216796875 +72754 -0.00750732421875 +72755 -0.128265380859375 +72756 -0.0064697265625 +72757 -0.068145751953125 +72758 -0.008331298828125 +72759 -0.0430908203125 +72760 -0.0103759765625 +72761 -0.024444580078125 +72762 -0.009521484375 +72763 0.020721435546875 +72764 -0.002777099609375 +72765 0.124481201171875 +72766 0.00738525390625 +72767 0.25787353515625 +72768 0.017364501953125 +72769 0.379119873046875 +72770 0.02642822265625 +72771 0.47991943359375 +72772 0.031707763671875 +72773 0.5281982421875 +72774 0.032012939453125 +72775 0.511138916015625 +72776 0.029632568359375 +72777 0.456207275390625 +72778 0.028289794921875 +72779 0.407470703125 +72780 0.02947998046875 +72781 0.383758544921875 +72782 0.030517578125 +72783 0.35687255859375 +72784 0.029876708984375 +72785 0.31182861328125 +72786 0.027587890625 +72787 0.250885009765625 +72788 0.022735595703125 +72789 0.1654052734375 +72790 0.013427734375 +72791 0.035247802734375 +72792 -0.0006103515625 +72793 -0.142059326171875 +72794 -0.0167236328125 +72795 -0.33563232421875 +72796 -0.034027099609375 +72797 -0.5345458984375 +72798 -0.050994873046875 +72799 -0.72186279296875 +72800 -0.062164306640625 +72801 -0.836669921875 +72802 -0.06341552734375 +72803 -0.8326416015625 +72804 -0.056396484375 +72805 -0.7296142578125 +72806 -0.045867919921875 +72807 -0.582550048828125 +72808 -0.03594970703125 +72809 -0.440093994140625 +72810 -0.0284423828125 +72811 -0.324310302734375 +72812 -0.02020263671875 +72813 -0.20147705078125 +72814 -0.00872802734375 +72815 -0.044647216796875 +72816 0.002349853515625 +72817 0.103973388671875 +72818 0.00946044921875 +72819 0.202392578125 +72820 0.013885498046875 +72821 0.264495849609375 +72822 0.019927978515625 +72823 0.338897705078125 +72824 0.029205322265625 +72825 0.443817138671875 +72826 0.0386962890625 +72827 0.545074462890625 +72828 0.046112060546875 +72829 0.6173095703125 +72830 0.050689697265625 +72831 0.6524658203125 +72832 0.053436279296875 +72833 0.66339111328125 +72834 0.054779052734375 +72835 0.6561279296875 +72836 0.052490234375 +72837 0.606781005859375 +72838 0.045196533203125 +72839 0.501190185546875 +72840 0.034027099609375 +72841 0.352783203125 +72842 0.02020263671875 +72843 0.176544189453125 +72844 0.002960205078125 +72845 -0.034820556640625 +72846 -0.015625 +72847 -0.258209228515625 +72848 -0.0311279296875 +72849 -0.44244384765625 +72850 -0.04254150390625 +72851 -0.5753173828125 +72852 -0.0494384765625 +72853 -0.65203857421875 +72854 -0.049041748046875 +72855 -0.641632080078125 +72856 -0.04296875 +72857 -0.562164306640625 +72858 -0.035064697265625 +72859 -0.458038330078125 +72860 -0.027069091796875 +72861 -0.350555419921875 +72862 -0.020721435546875 +72863 -0.260528564453125 +72864 -0.016326904296875 +72865 -0.192108154296875 +72866 -0.013519287109375 +72867 -0.141937255859375 +72868 -0.011474609375 +72869 -0.1021728515625 +72870 -0.00927734375 +72871 -0.062896728515625 +72872 -0.005767822265625 +72873 -0.011932373046875 +72874 0.0001220703125 +72875 0.062835693359375 +72876 0.00732421875 +72877 0.148712158203125 +72878 0.0155029296875 +72879 0.241729736328125 +72880 0.0252685546875 +72881 0.34912109375 +72882 0.035400390625 +72883 0.457305908203125 +72884 0.04388427734375 +72885 0.54388427734375 +72886 0.0474853515625 +72887 0.5728759765625 +72888 0.0428466796875 +72889 0.506591796875 +72890 0.030426025390625 +72891 0.351226806640625 +72892 0.013641357421875 +72893 0.146514892578125 +72894 -0.0029296875 +72895 -0.05523681640625 +72896 -0.016021728515625 +72897 -0.21624755859375 +72898 -0.025543212890625 +72899 -0.334930419921875 +72900 -0.03082275390625 +72901 -0.402984619140625 +72902 -0.03369140625 +72903 -0.4412841796875 +72904 -0.03826904296875 +72905 -0.49578857421875 +72906 -0.043975830078125 +72907 -0.5601806640625 +72908 -0.0478515625 +72909 -0.600738525390625 +72910 -0.04693603515625 +72911 -0.584228515625 +72912 -0.0384521484375 +72913 -0.47930908203125 +72914 -0.021759033203125 +72915 -0.27935791015625 +72916 0.0009765625 +72917 -0.0089111328125 +72918 0.0242919921875 +72919 0.268798828125 +72920 0.041961669921875 +72921 0.482818603515625 +72922 0.051483154296875 +72923 0.60369873046875 +72924 0.054595947265625 +72925 0.650421142578125 +72926 0.054962158203125 +72927 0.66400146484375 +72928 0.052337646484375 +72929 0.6414794921875 +72930 0.045867919921875 +72931 0.572540283203125 +72932 0.0391845703125 +72933 0.498138427734375 +72934 0.034149169921875 +72935 0.439453125 +72936 0.028900146484375 +72937 0.375518798828125 +72938 0.020599365234375 +72939 0.274505615234375 +72940 0.00677490234375 +72941 0.1087646484375 +72942 -0.0106201171875 +72943 -0.099395751953125 +72944 -0.02886962890625 +72945 -0.3182373046875 +72946 -0.048095703125 +72947 -0.5489501953125 +72948 -0.0667724609375 +72949 -0.7738037109375 +72950 -0.080352783203125 +72951 -0.86383056640625 +72952 -0.085968017578125 +72953 -0.870391845703125 +72954 -0.085235595703125 +72955 -0.86895751953125 +72956 -0.079315185546875 +72957 -0.861053466796875 +72958 -0.06671142578125 +72959 -0.765869140625 +72960 -0.04638671875 +72961 -0.5301513671875 +72962 -0.0184326171875 +72963 -0.214691162109375 +72964 0.013153076171875 +72965 0.137359619140625 +72966 0.043243408203125 +72967 0.474822998046875 +72968 0.068450927734375 +72969 0.76239013671875 +72970 0.086212158203125 +72971 0.867462158203125 +72972 0.097076416015625 +72973 0.870361328125 +72974 0.10003662109375 +72975 0.86480712890625 +72976 0.095855712890625 +72977 0.831817626953125 +72978 0.087493896484375 +72979 0.677581787109375 +72980 0.075469970703125 +72981 0.495880126953125 +72982 0.061737060546875 +72983 0.30767822265625 +72984 0.04620361328125 +72985 0.116180419921875 +72986 0.024566650390625 +72987 -0.110748291015625 +72988 -0.00445556640625 +72989 -0.381805419921875 +72990 -0.036285400390625 +72991 -0.6572265625 +72992 -0.064208984375 +72993 -0.857421875 +72994 -0.08355712890625 +72995 -0.870391845703125 +72996 -0.093902587890625 +72997 -0.870391845703125 +72998 -0.09881591796875 +72999 -0.86444091796875 +73000 -0.102813720703125 +73001 -0.85723876953125 +73002 -0.10382080078125 +73003 -0.790008544921875 +73004 -0.0953369140625 +73005 -0.62847900390625 +73006 -0.076873779296875 +73007 -0.3956298828125 +73008 -0.05218505859375 +73009 -0.126708984375 +73010 -0.0242919921875 +73011 0.150115966796875 +73012 0.005706787109375 +73013 0.424041748046875 +73014 0.034942626953125 +73015 0.670623779296875 +73016 0.0592041015625 +73017 0.854522705078125 +73018 0.0767822265625 +73019 0.866485595703125 +73020 0.086212158203125 +73021 0.86920166015625 +73022 0.09002685546875 +73023 0.8653564453125 +73024 0.090118408203125 +73025 0.857147216796875 +73026 0.08636474609375 +73027 0.766845703125 +73028 0.079498291015625 +73029 0.628509521484375 +73030 0.068756103515625 +73031 0.462127685546875 +73032 0.05718994140625 +73033 0.297210693359375 +73034 0.046173095703125 +73035 0.14862060546875 +73036 0.032745361328125 +73037 -0.00537109375 +73038 0.017547607421875 +73039 -0.15753173828125 +73040 -9.1552734375e-05 +73041 -0.31304931640625 +73042 -0.022216796875 +73043 -0.48876953125 +73044 -0.04351806640625 +73045 -0.6416015625 +73046 -0.061370849609375 +73047 -0.751373291015625 +73048 -0.078826904296875 +73049 -0.84619140625 +73050 -0.094390869140625 +73051 -0.861297607421875 +73052 -0.104278564453125 +73053 -0.863250732421875 +73054 -0.104827880859375 +73055 -0.856597900390625 +73056 -0.097564697265625 +73057 -0.7498779296875 +73058 -0.0894775390625 +73059 -0.624542236328125 +73060 -0.077850341796875 +73061 -0.47808837890625 +73062 -0.055511474609375 +73063 -0.253387451171875 +73064 -0.02777099609375 +73065 0.003692626953125 +73066 -0.0025634765625 +73067 0.2257080078125 +73068 0.021820068359375 +73069 0.427154541015625 +73070 0.049530029296875 +73071 0.643218994140625 +73072 0.079681396484375 +73073 0.855926513671875 +73074 0.1055908203125 +73075 0.870361328125 +73076 0.121551513671875 +73077 0.870361328125 +73078 0.128631591796875 +73079 0.862762451171875 +73080 0.126617431640625 +73081 0.79669189453125 +73082 0.114471435546875 +73083 0.595794677734375 +73084 0.095733642578125 +73085 0.362152099609375 +73086 0.073699951171875 +73087 0.1270751953125 +73088 0.05084228515625 +73089 -0.086944580078125 +73090 0.027252197265625 +73091 -0.2784423828125 +73092 -0.001373291015625 +73093 -0.484832763671875 +73094 -0.037567138671875 +73095 -0.729583740234375 +73096 -0.075439453125 +73097 -0.86688232421875 +73098 -0.107666015625 +73099 -0.870391845703125 +73100 -0.13385009765625 +73101 -0.86859130859375 +73102 -0.1539306640625 +73103 -0.86279296875 +73104 -0.163787841796875 +73105 -0.817962646484375 +73106 -0.158111572265625 +73107 -0.6116943359375 +73108 -0.136138916015625 +73109 -0.3128662109375 +73110 -0.101959228515625 +73111 0.039398193359375 +73112 -0.057952880859375 +73113 0.422821044921875 +73114 -0.008087158203125 +73115 0.805145263671875 +73116 0.039520263671875 +73117 0.870361328125 +73118 0.07818603515625 +73119 0.870361328125 +73120 0.10662841796875 +73121 0.860015869140625 +73122 0.124114990234375 +73123 0.727935791015625 +73124 0.130157470703125 +73125 0.48114013671875 +73126 0.1278076171875 +73127 0.2059326171875 +73128 0.119964599609375 +73129 -0.06103515625 +73130 0.107940673828125 +73131 -0.29913330078125 +73132 0.090118408203125 +73133 -0.516204833984375 +73134 0.064788818359375 +73135 -0.7252197265625 +73136 0.03497314453125 +73137 -0.85980224609375 +73138 0.004791259765625 +73139 -0.870391845703125 +73140 -0.022186279296875 +73141 -0.870391845703125 +73142 -0.0401611328125 +73143 -0.858062744140625 +73144 -0.048675537109375 +73145 -0.673004150390625 +73146 -0.05413818359375 +73147 -0.42694091796875 +73148 -0.06195068359375 +73149 -0.2100830078125 +73150 -0.071929931640625 +73151 -0.0362548828125 +73152 -0.0806884765625 +73153 0.10943603515625 +73154 -0.0859375 +73155 0.23516845703125 +73156 -0.082794189453125 +73157 0.373687744140625 +73158 -0.07159423828125 +73159 0.517791748046875 +73160 -0.05999755859375 +73161 0.602783203125 +73162 -0.04742431640625 +73163 0.635711669921875 +73164 -0.02996826171875 +73165 0.655181884765625 +73166 -0.008819580078125 +73167 0.65948486328125 +73168 0.0150146484375 +73169 0.651275634765625 +73170 0.03863525390625 +73171 0.61846923828125 +73172 0.0576171875 +73173 0.53753662109375 +73174 0.069854736328125 +73175 0.404144287109375 +73176 0.074249267578125 +73177 0.22186279296875 +73178 0.071044921875 +73179 0.003997802734375 +73180 0.0625 +73181 -0.22100830078125 +73182 0.0511474609375 +73183 -0.42449951171875 +73184 0.039642333984375 +73185 -0.579833984375 +73186 0.033172607421875 +73187 -0.641876220703125 +73188 0.031005859375 +73189 -0.6177978515625 +73190 0.025421142578125 +73191 -0.575531005859375 +73192 0.015838623046875 +73193 -0.526336669921875 +73194 0.008453369140625 +73195 -0.42645263671875 +73196 0.00653076171875 +73197 -0.2581787109375 +73198 0.0057373046875 +73199 -0.068695068359375 +73200 0.001434326171875 +73201 0.09222412109375 +73202 -0.004150390625 +73203 0.232147216796875 +73204 -0.009857177734375 +73205 0.3509521484375 +73206 -0.019287109375 +73207 0.410064697265625 +73208 -0.036041259765625 +73209 0.372955322265625 +73210 -0.0576171875 +73211 0.2554931640625 +73212 -0.077850341796875 +73213 0.10711669921875 +73214 -0.09442138671875 +73215 -0.052886962890625 +73216 -0.10260009765625 +73217 -0.186279296875 +73218 -0.09527587890625 +73219 -0.23291015625 +73220 -0.0760498046875 +73221 -0.209442138671875 +73222 -0.054107666015625 +73223 -0.174163818359375 +73224 -0.02996826171875 +73225 -0.126739501953125 +73226 -0.00140380859375 +73227 -0.048126220703125 +73228 0.027984619140625 +73229 0.0426025390625 +73230 0.051788330078125 +73231 0.10748291015625 +73232 0.068572998046875 +73233 0.1409912109375 +73234 0.085968017578125 +73235 0.19708251953125 +73236 0.103271484375 +73237 0.273651123046875 +73238 0.1123046875 +73239 0.31768798828125 +73240 0.11480712890625 +73241 0.341094970703125 +73242 0.114532470703125 +73243 0.368011474609375 +73244 0.10791015625 +73245 0.37249755859375 +73246 0.087310791015625 +73247 0.30072021484375 +73248 0.053192138671875 +73249 0.1517333984375 +73250 0.015167236328125 +73251 -0.01470947265625 +73252 -0.024444580078125 +73253 -0.1883544921875 +73254 -0.0654296875 +73255 -0.372711181640625 +73256 -0.0989990234375 +73257 -0.51397705078125 +73258 -0.11846923828125 +73259 -0.57177734375 +73260 -0.122314453125 +73261 -0.53948974609375 +73262 -0.112823486328125 +73263 -0.43511962890625 +73264 -0.095367431640625 +73265 -0.2962646484375 +73266 -0.075592041015625 +73267 -0.161102294921875 +73268 -0.05560302734375 +73269 -0.0435791015625 +73270 -0.0350341796875 +73271 0.060394287109375 +73272 -0.016326904296875 +73273 0.13665771484375 +73274 -0.002227783203125 +73275 0.170135498046875 +73276 0.007415771484375 +73277 0.16552734375 +73278 0.017181396484375 +73279 0.15728759765625 +73280 0.027252197265625 +73281 0.150787353515625 +73282 0.033416748046875 +73283 0.12200927734375 +73284 0.0364990234375 +73285 0.080108642578125 +73286 0.039947509765625 +73287 0.05126953125 +73288 0.0474853515625 +73289 0.062896728515625 +73290 0.055511474609375 +73291 0.09271240234375 +73292 0.0567626953125 +73293 0.092987060546875 +73294 0.053436279296875 +73295 0.07855224609375 +73296 0.047882080078125 +73297 0.06427001953125 +73298 0.038055419921875 +73299 0.0347900390625 +73300 0.0240478515625 +73301 -0.01171875 +73302 0.0091552734375 +73303 -0.056060791015625 +73304 0.000274658203125 +73305 -0.055511474609375 +73306 -0.002105712890625 +73307 -0.010467529296875 +73308 -0.005584716796875 +73309 0.02508544921875 +73310 -0.013519287109375 +73311 0.025665283203125 +73312 -0.021575927734375 +73313 0.017333984375 +73314 -0.0291748046875 +73315 0.00189208984375 +73316 -0.0377197265625 +73317 -0.03173828125 +73318 -0.045257568359375 +73319 -0.071502685546875 +73320 -0.054473876953125 +73321 -0.13543701171875 +73322 -0.06488037109375 +73323 -0.219970703125 +73324 -0.072967529296875 +73325 -0.300506591796875 +73326 -0.078887939453125 +73327 -0.376312255859375 +73328 -0.07830810546875 +73329 -0.416107177734375 +73330 -0.064300537109375 +73331 -0.371124267578125 +73332 -0.03741455078125 +73333 -0.242279052734375 +73334 -0.00408935546875 +73335 -0.069732666015625 +73336 0.0321044921875 +73337 0.125640869140625 +73338 0.066131591796875 +73339 0.31268310546875 +73340 0.092193603515625 +73341 0.45501708984375 +73342 0.11041259765625 +73343 0.554779052734375 +73344 0.120452880859375 +73345 0.61065673828125 +73346 0.120513916015625 +73347 0.610931396484375 +73348 0.1070556640625 +73349 0.531463623046875 +73350 0.082611083984375 +73351 0.3883056640625 +73352 0.05535888671875 +73353 0.23468017578125 +73354 0.029296875 +73355 0.095245361328125 +73356 0.00860595703125 +73357 -0.00396728515625 +73358 -0.00421142578125 +73359 -0.04852294921875 +73360 -0.01129150390625 +73361 -0.055145263671875 +73362 -0.020111083984375 +73363 -0.0758056640625 +73364 -0.03460693359375 +73365 -0.138702392578125 +73366 -0.04931640625 +73367 -0.209197998046875 +73368 -0.064300537109375 +73369 -0.289031982421875 +73370 -0.07952880859375 +73371 -0.37884521484375 +73372 -0.091583251953125 +73373 -0.456329345703125 +73374 -0.0997314453125 +73375 -0.51641845703125 +73376 -0.09808349609375 +73377 -0.519287109375 +73378 -0.085784912109375 +73379 -0.458251953125 +73380 -0.070770263671875 +73381 -0.384796142578125 +73382 -0.056976318359375 +73383 -0.323699951171875 +73384 -0.043792724609375 +73385 -0.269287109375 +73386 -0.027557373046875 +73387 -0.1951904296875 +73388 -0.00836181640625 +73389 -0.100006103515625 +73390 0.00946044921875 +73391 -0.01055908203125 +73392 0.03021240234375 +73393 0.1033935546875 +73394 0.0548095703125 +73395 0.24908447265625 +73396 0.07513427734375 +73397 0.373199462890625 +73398 0.088470458984375 +73399 0.45806884765625 +73400 0.095977783203125 +73401 0.511474609375 +73402 0.102508544921875 +73403 0.565399169921875 +73404 0.10693359375 +73405 0.61138916015625 +73406 0.1004638671875 +73407 0.5897216796875 +73408 0.081817626953125 +73409 0.4906005859375 +73410 0.0538330078125 +73411 0.33148193359375 +73412 0.022064208984375 +73413 0.147796630859375 +73414 -0.006988525390625 +73415 -0.01873779296875 +73416 -0.0289306640625 +73417 -0.140289306640625 +73418 -0.039825439453125 +73419 -0.191986083984375 +73420 -0.04107666015625 +73421 -0.184295654296875 +73422 -0.039276123046875 +73423 -0.161834716796875 +73424 -0.040679931640625 +73425 -0.166595458984375 +73426 -0.044586181640625 +73427 -0.19390869140625 +73428 -0.048126220703125 +73429 -0.22442626953125 +73430 -0.054595947265625 +73431 -0.279754638671875 +73432 -0.06097412109375 +73433 -0.3389892578125 +73434 -0.060272216796875 +73435 -0.3543701171875 +73436 -0.055999755859375 +73437 -0.348175048828125 +73438 -0.0491943359375 +73439 -0.32598876953125 +73440 -0.035614013671875 +73441 -0.2581787109375 +73442 -0.01470947265625 +73443 -0.139801025390625 +73444 0.01116943359375 +73445 0.014617919921875 +73446 0.032745361328125 +73447 0.144378662109375 +73448 0.045684814453125 +73449 0.221038818359375 +73450 0.0538330078125 +73451 0.27069091796875 +73452 0.05731201171875 +73453 0.294036865234375 +73454 0.059234619140625 +73455 0.311767578125 +73456 0.061981201171875 +73457 0.339141845703125 +73458 0.063262939453125 +73459 0.360260009765625 +73460 0.061004638671875 +73461 0.360504150390625 +73462 0.050537109375 +73463 0.308380126953125 +73464 0.02862548828125 +73465 0.18170166015625 +73466 -0.000823974609375 +73467 0.0047607421875 +73468 -0.030609130859375 +73469 -0.17559814453125 +73470 -0.053741455078125 +73471 -0.3143310546875 +73472 -0.063140869140625 +73473 -0.36785888671875 +73474 -0.063140869140625 +73475 -0.36248779296875 +73476 -0.061187744140625 +73477 -0.343536376953125 +73478 -0.0552978515625 +73479 -0.3018798828125 +73480 -0.044097900390625 +73481 -0.231414794921875 +73482 -0.02471923828125 +73483 -0.117645263671875 +73484 -0.003021240234375 +73485 0.007049560546875 +73486 0.011016845703125 +73487 0.087982177734375 +73488 0.02008056640625 +73489 0.13946533203125 +73490 0.02655029296875 +73491 0.17425537109375 +73492 0.02960205078125 +73493 0.188201904296875 +73494 0.02734375 +73495 0.171234130859375 +73496 0.018768310546875 +73497 0.118438720703125 +73498 0.008819580078125 +73499 0.05706787109375 +73500 -0.002166748046875 +73501 -0.010711669921875 +73502 -0.0155029296875 +73503 -0.0914306640625 +73504 -0.027099609375 +73505 -0.162322998046875 +73506 -0.03173828125 +73507 -0.194549560546875 +73508 -0.0223388671875 +73509 -0.1492919921875 +73510 0.00189208984375 +73511 -0.02166748046875 +73512 0.029083251953125 +73513 0.124053955078125 +73514 0.04510498046875 +73515 0.211151123046875 +73516 0.050140380859375 +73517 0.240447998046875 +73518 0.049774169921875 +73519 0.242218017578125 +73520 0.0457763671875 +73521 0.2257080078125 +73522 0.038848876953125 +73523 0.194366455078125 +73524 0.0230712890625 +73525 0.115509033203125 +73526 0.00286865234375 +73527 0.0128173828125 +73528 -0.010650634765625 +73529 -0.053802490234375 +73530 -0.022247314453125 +73531 -0.110626220703125 +73532 -0.039581298828125 +73533 -0.199493408203125 +73534 -0.057830810546875 +73535 -0.29437255859375 +73536 -0.065338134765625 +73537 -0.33221435546875 +73538 -0.05596923828125 +73539 -0.27972412109375 +73540 -0.03863525390625 +73541 -0.185333251953125 +73542 -0.02789306640625 +73543 -0.128204345703125 +73544 -0.025115966796875 +73545 -0.115692138671875 +73546 -0.0245361328125 +73547 -0.116455078125 +73548 -0.021728515625 +73549 -0.105926513671875 +73550 -0.01116943359375 +73551 -0.053955078125 +73552 0.008758544921875 +73553 0.048797607421875 +73554 0.029754638671875 +73555 0.157318115234375 +73556 0.040740966796875 +73557 0.212005615234375 +73558 0.042724609375 +73559 0.218475341796875 +73560 0.04681396484375 +73561 0.23724365234375 +73562 0.059814453125 +73563 0.30535888671875 +73564 0.07403564453125 +73565 0.38128662109375 +73566 0.07830810546875 +73567 0.404449462890625 +73568 0.076263427734375 +73569 0.3944091796875 +73570 0.07476806640625 +73571 0.3885498046875 +73572 0.069427490234375 +73573 0.362640380859375 +73574 0.0523681640625 +73575 0.27362060546875 +73576 0.022796630859375 +73577 0.11712646484375 +73578 -0.009674072265625 +73579 -0.054901123046875 +73580 -0.03546142578125 +73581 -0.19085693359375 +73582 -0.053619384765625 +73583 -0.28570556640625 +73584 -0.064056396484375 +73585 -0.339263916015625 +73586 -0.071563720703125 +73587 -0.3775634765625 +73588 -0.084381103515625 +73589 -0.445709228515625 +73590 -0.1009521484375 +73591 -0.535064697265625 +73592 -0.11822509765625 +73593 -0.629058837890625 +73594 -0.130645751953125 +73595 -0.697601318359375 +73596 -0.131439208984375 +73597 -0.70391845703125 +73598 -0.119659423828125 +73599 -0.6424560546875 +73600 -0.091278076171875 +73601 -0.491241455078125 +73602 -0.049163818359375 +73603 -0.265716552734375 +73604 -0.003997802734375 +73605 -0.023712158203125 +73606 0.0380859375 +73607 0.201751708984375 +73608 0.070648193359375 +73609 0.375823974609375 +73610 0.0911865234375 +73611 0.485076904296875 +73612 0.106903076171875 +73613 0.56884765625 +73614 0.11920166015625 +73615 0.634765625 +73616 0.1197509765625 +73617 0.63763427734375 +73618 0.106475830078125 +73619 0.5660400390625 +73620 0.088958740234375 +73621 0.4720458984375 +73622 0.07666015625 +73623 0.40692138671875 +73624 0.070892333984375 +73625 0.3778076171875 +73626 0.070281982421875 +73627 0.376953125 +73628 0.068878173828125 +73629 0.371978759765625 +73630 0.057525634765625 +73631 0.313140869140625 +73632 0.033294677734375 +73633 0.184417724609375 +73634 0.00091552734375 +73635 0.011199951171875 +73636 -0.03302001953125 +73637 -0.171051025390625 +73638 -0.063873291015625 +73639 -0.33740234375 +73640 -0.088714599609375 +73641 -0.47198486328125 +73642 -0.10491943359375 +73643 -0.560394287109375 +73644 -0.10845947265625 +73645 -0.58056640625 +73646 -0.10211181640625 +73647 -0.54754638671875 +73648 -0.0946044921875 +73649 -0.508575439453125 +73650 -0.085174560546875 +73651 -0.459503173828125 +73652 -0.07275390625 +73653 -0.394378662109375 +73654 -0.0645751953125 +73655 -0.35260009765625 +73656 -0.056549072265625 +73657 -0.31170654296875 +73658 -0.035064697265625 +73659 -0.197418212890625 +73660 0.00018310546875 +73661 -0.007965087890625 +73662 0.04010009765625 +73663 0.207489013671875 +73664 0.077362060546875 +73665 0.409210205078125 +73666 0.10736083984375 +73667 0.57208251953125 +73668 0.124542236328125 +73669 0.66595458984375 +73670 0.123016357421875 +73671 0.65875244140625 +73672 0.105926513671875 +73673 0.56744384765625 +73674 0.080535888671875 +73675 0.431396484375 +73676 0.054931640625 +73677 0.29443359375 +73678 0.033905029296875 +73679 0.182464599609375 +73680 0.011627197265625 +73681 0.06365966796875 +73682 -0.014434814453125 +73683 -0.075958251953125 +73684 -0.035614013671875 +73685 -0.189422607421875 +73686 -0.05096435546875 +73687 -0.271942138671875 +73688 -0.06402587890625 +73689 -0.342529296875 +73690 -0.068023681640625 +73691 -0.364166259765625 +73692 -0.061187744140625 +73693 -0.327239990234375 +73694 -0.051849365234375 +73695 -0.2769775390625 +73696 -0.047393798828125 +73697 -0.253692626953125 +73698 -0.045318603515625 +73699 -0.24365234375 +73700 -0.0367431640625 +73701 -0.1983642578125 +73702 -0.0213623046875 +73703 -0.116241455078125 +73704 -0.006439208984375 +73705 -0.036834716796875 +73706 0.007049560546875 +73707 0.034881591796875 +73708 0.017669677734375 +73709 0.09124755859375 +73710 0.0211181640625 +73711 0.10888671875 +73712 0.024322509765625 +73713 0.125518798828125 +73714 0.03033447265625 +73715 0.15771484375 +73716 0.03411865234375 +73717 0.17828369140625 +73718 0.03271484375 +73719 0.17108154296875 +73720 0.024993896484375 +73721 0.129974365234375 +73722 0.01605224609375 +73723 0.082427978515625 +73724 0.0057373046875 +73725 0.027679443359375 +73726 -0.01165771484375 +73727 -0.065643310546875 +73728 -0.02874755859375 +73729 -0.15936279296875 +73730 -0.038482666015625 +73731 -0.21307373046875 +73732 -0.04296875 +73733 -0.234649658203125 +73734 -0.036651611328125 +73735 -0.2001953125 +73736 -0.021148681640625 +73737 -0.119171142578125 +73738 -0.00323486328125 +73739 -0.024749755859375 +73740 0.017974853515625 +73741 0.085784912109375 +73742 0.035308837890625 +73743 0.178131103515625 +73744 0.04107666015625 +73745 0.215576171875 +73746 0.038330078125 +73747 0.211456298828125 +73748 0.029266357421875 +73749 0.17523193359375 +73750 0.01861572265625 +73751 0.128753662109375 +73752 0.01287841796875 +73753 0.1019287109375 +73754 0.007598876953125 +73755 0.0743408203125 +73756 0.002105712890625 +73757 0.04327392578125 +73758 0.002655029296875 +73759 0.038177490234375 +73760 0.012847900390625 +73761 0.076263427734375 +73762 0.028961181640625 +73763 0.14105224609375 +73764 0.040924072265625 +73765 0.186431884765625 +73766 0.04351806640625 +73767 0.188812255859375 +73768 0.034637451171875 +73769 0.1390380859375 +73770 0.01519775390625 +73771 0.041778564453125 +73772 -0.009796142578125 +73773 -0.079437255859375 +73774 -0.039276123046875 +73775 -0.219390869140625 +73776 -0.07098388671875 +73777 -0.367828369140625 +73778 -0.0985107421875 +73779 -0.494873046875 +73780 -0.112274169921875 +73781 -0.556243896484375 +73782 -0.1029052734375 +73783 -0.508697509765625 +73784 -0.075408935546875 +73785 -0.3756103515625 +73786 -0.0430908203125 +73787 -0.218902587890625 +73788 -0.01129150390625 +73789 -0.063751220703125 +73790 0.02044677734375 +73791 0.091552734375 +73792 0.049835205078125 +73793 0.23602294921875 +73794 0.07122802734375 +73795 0.342987060546875 +73796 0.08099365234375 +73797 0.39520263671875 +73798 0.0784912109375 +73799 0.389373779296875 +73800 0.06353759765625 +73801 0.324249267578125 +73802 0.041412353515625 +73803 0.224090576171875 +73804 0.019775390625 +73805 0.124267578125 +73806 0.001251220703125 +73807 0.037078857421875 +73808 -0.00823974609375 +73809 -0.010101318359375 +73810 -0.009246826171875 +73811 -0.019439697265625 +73812 -0.0086669921875 +73813 -0.022796630859375 +73814 -0.002593994140625 +73815 -0.001556396484375 +73816 0.01141357421875 +73817 0.056304931640625 +73818 0.0238037109375 +73819 0.106719970703125 +73820 0.023101806640625 +73821 0.096893310546875 +73822 0.01263427734375 +73823 0.042694091796875 +73824 0.000518798828125 +73825 -0.018035888671875 +73826 -0.01123046875 +73827 -0.07586669921875 +73828 -0.02020263671875 +73829 -0.11944580078125 +73830 -0.028778076171875 +73831 -0.15972900390625 +73832 -0.0382080078125 +73833 -0.202606201171875 +73834 -0.048553466796875 +73835 -0.24859619140625 +73836 -0.0614013671875 +73837 -0.30517578125 +73838 -0.074493408203125 +73839 -0.36212158203125 +73840 -0.081756591796875 +73841 -0.39141845703125 +73842 -0.074981689453125 +73843 -0.35528564453125 +73844 -0.053314208984375 +73845 -0.249969482421875 +73846 -0.020477294921875 +73847 -0.092864990234375 +73848 0.01776123046875 +73849 0.08905029296875 +73850 0.04840087890625 +73851 0.2352294921875 +73852 0.065673828125 +73853 0.318817138671875 +73854 0.07366943359375 +73855 0.358642578125 +73856 0.0709228515625 +73857 0.347747802734375 +73858 0.057373046875 +73859 0.28564453125 +73860 0.04400634765625 +73861 0.223175048828125 +73862 0.038665771484375 +73863 0.196746826171875 +73864 0.03558349609375 +73865 0.179840087890625 +73866 0.03106689453125 +73867 0.155548095703125 +73868 0.030975341796875 +73869 0.151214599609375 +73870 0.033111572265625 +73871 0.156951904296875 +73872 0.028564453125 +73873 0.13177490234375 +73874 0.022735595703125 +73875 0.100799560546875 +73876 0.020538330078125 +73877 0.087127685546875 +73878 0.014190673828125 +73879 0.05487060546875 +73880 0.000885009765625 +73881 -0.009002685546875 +73882 -0.019287109375 +73883 -0.10400390625 +73884 -0.04620361328125 +73885 -0.229400634765625 +73886 -0.073455810546875 +73887 -0.35552978515625 +73888 -0.092254638671875 +73889 -0.441925048828125 +73890 -0.09942626953125 +73891 -0.473846435546875 +73892 -0.09783935546875 +73893 -0.464813232421875 +73894 -0.08843994140625 +73895 -0.419097900390625 +73896 -0.0706787109375 +73897 -0.334320068359375 +73898 -0.048309326171875 +73899 -0.227935791015625 +73900 -0.026336669921875 +73901 -0.12347412109375 +73902 -0.006195068359375 +73903 -0.02764892578125 +73904 0.016021728515625 +73905 0.077667236328125 +73906 0.044830322265625 +73907 0.2132568359375 +73908 0.082366943359375 +73909 0.38885498046875 +73910 0.123992919921875 +73911 0.582794189453125 +73912 0.156494140625 +73913 0.734039306640625 +73914 0.170684814453125 +73915 0.800140380859375 +73916 0.165985107421875 +73917 0.7783203125 +73918 0.14166259765625 +73919 0.6651611328125 +73920 0.09747314453125 +73921 0.45965576171875 +73922 0.041534423828125 +73923 0.199188232421875 +73924 -0.011993408203125 +73925 -0.050689697265625 +73926 -0.05084228515625 +73927 -0.23297119140625 +73928 -0.071258544921875 +73929 -0.33013916015625 +73930 -0.07891845703125 +73931 -0.368408203125 +73932 -0.080596923828125 +73933 -0.378936767578125 +73934 -0.079681396484375 +73935 -0.376983642578125 +73936 -0.079864501953125 +73937 -0.37969970703125 +73938 -0.082122802734375 +73939 -0.391510009765625 +73940 -0.080596923828125 +73941 -0.385345458984375 +73942 -0.0711669921875 +73943 -0.3419189453125 +73944 -0.0584716796875 +73945 -0.28289794921875 +73946 -0.0518798828125 +73947 -0.251617431640625 +73948 -0.0552978515625 +73949 -0.266143798828125 +73950 -0.057220458984375 +73951 -0.273345947265625 +73952 -0.045440673828125 +73953 -0.216796875 +73954 -0.026763916015625 +73955 -0.128265380859375 +73956 -0.01422119140625 +73957 -0.068145751953125 +73958 -0.00921630859375 +73959 -0.0430908203125 +73960 -0.00555419921875 +73961 -0.024444580078125 +73962 0.00384521484375 +73963 0.020721435546875 +73964 0.02593994140625 +73965 0.124481201171875 +73966 0.05450439453125 +73967 0.25787353515625 +73968 0.08050537109375 +73969 0.379119873046875 +73970 0.1021728515625 +73971 0.47991943359375 +73972 0.112579345703125 +73973 0.5281982421875 +73974 0.10894775390625 +73975 0.511138916015625 +73976 0.097198486328125 +73977 0.456207275390625 +73978 0.08685302734375 +73979 0.407470703125 +73980 0.08197021484375 +73981 0.383758544921875 +73982 0.076416015625 +73983 0.35687255859375 +73984 0.067474365234375 +73985 0.31182861328125 +73986 0.055908203125 +73987 0.250885009765625 +73988 0.0391845703125 +73989 0.1654052734375 +73990 0.0118408203125 +73991 0.035247802734375 +73992 -0.027191162109375 +73993 -0.142059326171875 +73994 -0.070648193359375 +73995 -0.33563232421875 +73996 -0.11614990234375 +73997 -0.5345458984375 +73998 -0.159759521484375 +73999 -0.72186279296875 +74000 -0.186553955078125 +74001 -0.836669921875 +74002 -0.18511962890625 +74003 -0.8326416015625 +74004 -0.160369873046875 +74005 -0.7296142578125 +74006 -0.125885009765625 +74007 -0.582550048828125 +74008 -0.09356689453125 +74009 -0.440093994140625 +74010 -0.06866455078125 +74011 -0.324310302734375 +74012 -0.042572021484375 +74013 -0.20147705078125 +74014 -0.008331298828125 +74015 -0.044647216796875 +74016 0.023834228515625 +74017 0.103973388671875 +74018 0.043792724609375 +74019 0.202392578125 +74020 0.055206298828125 +74021 0.264495849609375 +74022 0.070343017578125 +74023 0.338897705078125 +74024 0.0938720703125 +74025 0.443817138671875 +74026 0.117431640625 +74027 0.545074462890625 +74028 0.134796142578125 +74029 0.6173095703125 +74030 0.143951416015625 +74031 0.6524658203125 +74032 0.148040771484375 +74033 0.66339111328125 +74034 0.148468017578125 +74035 0.6561279296875 +74036 0.13916015625 +74037 0.606781005859375 +74038 0.116424560546875 +74039 0.501190185546875 +74040 0.083404541015625 +74041 0.352783203125 +74042 0.0435791015625 +74043 0.176544189453125 +74044 -0.0050048828125 +74045 -0.034820556640625 +74046 -0.05682373046875 +74047 -0.258209228515625 +74048 -0.099395751953125 +74049 -0.44244384765625 +74050 -0.129852294921875 +74051 -0.5753173828125 +74052 -0.147125244140625 +74053 -0.65203857421875 +74054 -0.14361572265625 +74055 -0.641632080078125 +74056 -0.123870849609375 +74057 -0.562164306640625 +74058 -0.098846435546875 +74059 -0.458038330078125 +74060 -0.073760986328125 +74061 -0.350555419921875 +74062 -0.05364990234375 +74063 -0.260528564453125 +74064 -0.039398193359375 +74065 -0.192108154296875 +74066 -0.030029296875 +74067 -0.141937255859375 +74068 -0.023406982421875 +74069 -0.1021728515625 +74070 -0.016876220703125 +74071 -0.062896728515625 +74072 -0.007232666015625 +74073 -0.011932373046875 +74074 0.008636474609375 +74075 0.062835693359375 +74076 0.027740478515625 +74077 0.148712158203125 +74078 0.049163818359375 +74079 0.241729736328125 +74080 0.07476806640625 +74081 0.34912109375 +74082 0.10125732421875 +74083 0.457305908203125 +74084 0.123077392578125 +74085 0.54388427734375 +74086 0.131256103515625 +74087 0.5728759765625 +74088 0.11639404296875 +74089 0.506591796875 +74090 0.07989501953125 +74091 0.351226806640625 +74092 0.031494140625 +74093 0.146514892578125 +74094 -0.015960693359375 +74095 -0.05523681640625 +74096 -0.05322265625 +74097 -0.21624755859375 +74098 -0.080047607421875 +74099 -0.334930419921875 +74100 -0.094512939453125 +74101 -0.402984619140625 +74102 -0.1019287109375 +74103 -0.4412841796875 +74104 -0.113800048828125 +74105 -0.49578857421875 +74106 -0.128662109375 +74107 -0.5601806640625 +74108 -0.13818359375 +74109 -0.600738525390625 +74110 -0.1341552734375 +74111 -0.584228515625 +74112 -0.1087646484375 +74113 -0.47930908203125 +74114 -0.060302734375 +74115 -0.27935791015625 +74116 0.00518798828125 +74117 -0.0089111328125 +74118 0.072113037109375 +74119 0.268798828125 +74120 0.12298583984375 +74121 0.482818603515625 +74122 0.150665283203125 +74123 0.60369873046875 +74124 0.15997314453125 +74125 0.650421142578125 +74126 0.16119384765625 +74127 0.66400146484375 +74128 0.153717041015625 +74129 0.6414794921875 +74130 0.13507080078125 +74131 0.572540283203125 +74132 0.115509033203125 +74133 0.498138427734375 +74134 0.100311279296875 +74135 0.439453125 +74136 0.08428955078125 +74137 0.375518798828125 +74138 0.0595703125 +74139 0.274505615234375 +74140 0.019256591796875 +74141 0.1087646484375 +74142 -0.031158447265625 +74143 -0.099395751953125 +74144 -0.0838623046875 +74145 -0.3182373046875 +74146 -0.139251708984375 +74147 -0.5489501953125 +74148 -0.193023681640625 +74149 -0.7738037109375 +74150 -0.232177734375 +74151 -0.86383056640625 +74152 -0.24859619140625 +74153 -0.870391845703125 +74154 -0.246734619140625 +74155 -0.86895751953125 +74156 -0.229949951171875 +74157 -0.861053466796875 +74158 -0.194061279296875 +74159 -0.765869140625 +74160 -0.136322021484375 +74161 -0.5301513671875 +74162 -0.058502197265625 +74163 -0.214691162109375 +74164 0.028656005859375 +74165 0.137359619140625 +74166 0.11248779296875 +74167 0.474822998046875 +74168 0.184234619140625 +74169 0.76239013671875 +74170 0.237274169921875 +74171 0.867462158203125 +74172 0.271759033203125 +74173 0.870361328125 +74174 0.284912109375 +74175 0.86480712890625 +74176 0.278167724609375 +74177 0.831817626953125 +74178 0.257659912109375 +74179 0.677581787109375 +74180 0.224945068359375 +74181 0.495880126953125 +74182 0.1846923828125 +74183 0.30767822265625 +74184 0.137542724609375 +74185 0.116180419921875 +74186 0.07568359375 +74187 -0.110748291015625 +74188 -0.0025634765625 +74189 -0.381805419921875 +74190 -0.0865478515625 +74191 -0.6572265625 +74192 -0.16143798828125 +74193 -0.857421875 +74194 -0.21661376953125 +74195 -0.870391845703125 +74196 -0.250396728515625 +74197 -0.870391845703125 +74198 -0.26953125 +74199 -0.86444091796875 +74200 -0.282958984375 +74201 -0.85723876953125 +74202 -0.28619384765625 +74203 -0.790008544921875 +74204 -0.265869140625 +74205 -0.62847900390625 +74206 -0.221282958984375 +74207 -0.3956298828125 +74208 -0.16064453125 +74209 -0.126708984375 +74210 -0.090789794921875 +74211 0.150115966796875 +74212 -0.014678955078125 +74213 0.424041748046875 +74214 0.060943603515625 +74215 0.670623779296875 +74216 0.12646484375 +74217 0.854522705078125 +74218 0.177490234375 +74219 0.866485595703125 +74220 0.210235595703125 +74221 0.86920166015625 +74222 0.229248046875 +74223 0.8653564453125 +74224 0.237884521484375 +74225 0.857147216796875 +74226 0.235504150390625 +74227 0.766845703125 +74228 0.22344970703125 +74229 0.628509521484375 +74230 0.20013427734375 +74231 0.462127685546875 +74232 0.1719970703125 +74233 0.297210693359375 +74234 0.14215087890625 +74235 0.14862060546875 +74236 0.105010986328125 +74237 -0.00537109375 +74238 0.0625 +74239 -0.15753173828125 +74240 0.0133056640625 +74241 -0.31304931640625 +74242 -0.04608154296875 +74243 -0.48876953125 +74244 -0.102691650390625 +74245 -0.6416015625 +74246 -0.150390625 +74247 -0.751373291015625 +74248 -0.1962890625 +74249 -0.84619140625 +74250 -0.236846923828125 +74251 -0.861297607421875 +74252 -0.263214111328125 +74253 -0.863250732421875 +74254 -0.266754150390625 +74255 -0.856597900390625 +74256 -0.25103759765625 +74257 -0.7498779296875 +74258 -0.232269287109375 +74259 -0.624542236328125 +74260 -0.204132080078125 +74261 -0.47808837890625 +74262 -0.1500244140625 +74263 -0.253387451171875 +74264 -0.082366943359375 +74265 0.003692626953125 +74266 -0.019927978515625 +74267 0.2257080078125 +74268 0.041168212890625 +74269 0.427154541015625 +74270 0.11041259765625 +74271 0.643218994140625 +74272 0.185516357421875 +74273 0.855926513671875 +74274 0.250640869140625 +74275 0.870361328125 +74276 0.292205810546875 +74277 0.870361328125 +74278 0.312469482421875 +74279 0.862762451171875 +74280 0.310760498046875 +74281 0.79669189453125 +74282 0.28448486328125 +74283 0.595794677734375 +74284 0.24176025390625 +74285 0.362152099609375 +74286 0.190338134765625 +74287 0.1270751953125 +74288 0.135986328125 +74289 -0.086944580078125 +74290 0.079010009765625 +74291 -0.2784423828125 +74292 0.0093994140625 +74293 -0.484832763671875 +74294 -0.0784912109375 +74295 -0.729583740234375 +74296 -0.170806884765625 +74297 -0.86688232421875 +74298 -0.250152587890625 +74299 -0.870391845703125 +74300 -0.3154296875 +74301 -0.86859130859375 +74302 -0.36627197265625 +74303 -0.86279296875 +74304 -0.392822265625 +74305 -0.817962646484375 +74306 -0.382476806640625 +74307 -0.6116943359375 +74308 -0.33331298828125 +74309 -0.3128662109375 +74310 -0.254791259765625 +74311 0.039398193359375 +74312 -0.152435302734375 +74313 0.422821044921875 +74314 -0.03546142578125 +74315 0.805145263671875 +74316 0.077178955078125 +74317 0.870361328125 +74318 0.169708251953125 +74319 0.870361328125 +74320 0.239044189453125 +74321 0.860015869140625 +74322 0.28326416015625 +74323 0.727935791015625 +74324 0.301025390625 +74325 0.48114013671875 +74326 0.29925537109375 +74327 0.2059326171875 +74328 0.284454345703125 +74329 -0.06103515625 +74330 0.25958251953125 +74331 -0.29913330078125 +74332 0.220672607421875 +74333 -0.516204833984375 +74334 0.163482666015625 +74335 -0.7252197265625 +74336 0.095062255859375 +74337 -0.85980224609375 +74338 0.024993896484375 +74339 -0.870391845703125 +74340 -0.03839111328125 +74341 -0.870391845703125 +74342 -0.08148193359375 +74343 -0.858062744140625 +74344 -0.103179931640625 +74345 -0.673004150390625 +74346 -0.118255615234375 +74347 -0.42694091796875 +74348 -0.139190673828125 +74349 -0.2100830078125 +74350 -0.165435791015625 +74351 -0.0362548828125 +74352 -0.18890380859375 +74353 0.10943603515625 +74354 -0.2041015625 +74355 0.23516845703125 +74356 -0.19952392578125 +74357 0.373687744140625 +74358 -0.17578125 +74359 0.517791748046875 +74360 -0.15057373046875 +74361 0.602783203125 +74362 -0.122528076171875 +74363 0.635711669921875 +74364 -0.082366943359375 +74365 0.655181884765625 +74366 -0.032928466796875 +74367 0.65948486328125 +74368 0.023468017578125 +74369 0.651275634765625 +74370 0.079925537109375 +74371 0.61846923828125 +74372 0.126068115234375 +74373 0.53753662109375 +74374 0.1568603515625 +74375 0.404144287109375 +74376 0.16961669921875 +74377 0.22186279296875 +74378 0.164764404296875 +74379 0.003997802734375 +74380 0.14739990234375 +74381 -0.22100830078125 +74382 0.123321533203125 +74383 -0.42449951171875 +74384 0.09857177734375 +74385 -0.579833984375 +74386 0.085174560546875 +74387 -0.641876220703125 +74388 0.081329345703125 +74389 -0.6177978515625 +74390 0.069000244140625 +74391 -0.575531005859375 +74392 0.0467529296875 +74393 -0.526336669921875 +74394 0.029144287109375 +74395 -0.42645263671875 +74396 0.02386474609375 +74397 -0.2581787109375 +74398 0.020782470703125 +74399 -0.068695068359375 +74400 0.009124755859375 +74401 0.09222412109375 +74402 -0.005828857421875 +74403 0.232147216796875 +74404 -0.021240234375 +74405 0.3509521484375 +74406 -0.04541015625 +74407 0.410064697265625 +74408 -0.086578369140625 +74409 0.372955322265625 +74410 -0.138916015625 +74411 0.2554931640625 +74412 -0.187835693359375 +74413 0.10711669921875 +74414 -0.2279052734375 +74415 -0.052886962890625 +74416 -0.248992919921875 +74417 -0.186279296875 +74418 -0.235504150390625 +74419 -0.23291015625 +74420 -0.19384765625 +74421 -0.209442138671875 +74422 -0.142486572265625 +74423 -0.174163818359375 +74424 -0.08380126953125 +74425 -0.126739501953125 +74426 -0.015045166015625 +74427 -0.048126220703125 +74428 0.05584716796875 +74429 0.0426025390625 +74430 0.11578369140625 +74431 0.10748291015625 +74432 0.16107177734375 +74433 0.1409912109375 +74434 0.204986572265625 +74435 0.19708251953125 +74436 0.245635986328125 +74437 0.273651123046875 +74438 0.26739501953125 +74439 0.31768798828125 +74440 0.27337646484375 +74441 0.341094970703125 +74442 0.270660400390625 +74443 0.368011474609375 +74444 0.2528076171875 +74445 0.37249755859375 +74446 0.2060546875 +74447 0.30072021484375 +74448 0.1318359375 +74449 0.1517333984375 +74450 0.048797607421875 +74451 -0.01470947265625 +74452 -0.0380859375 +74453 -0.1883544921875 +74454 -0.12762451171875 +74455 -0.372711181640625 +74456 -0.20269775390625 +74457 -0.51397705078125 +74458 -0.250152587890625 +74459 -0.57177734375 +74460 -0.266571044921875 +74461 -0.53948974609375 +74462 -0.255767822265625 +74463 -0.43511962890625 +74464 -0.227447509765625 +74465 -0.2962646484375 +74466 -0.19195556640625 +74467 -0.161102294921875 +74468 -0.1533203125 +74469 -0.0435791015625 +74470 -0.11090087890625 +74471 0.060394287109375 +74472 -0.069610595703125 +74473 0.13665771484375 +74474 -0.03497314453125 +74475 0.170135498046875 +74476 -0.0072021484375 +74477 0.16552734375 +74478 0.021636962890625 +74479 0.15728759765625 +74480 0.05126953125 +74481 0.150787353515625 +74482 0.073272705078125 +74483 0.12200927734375 +74484 0.088592529296875 +74485 0.080108642578125 +74486 0.103179931640625 +74487 0.05126953125 +74488 0.123626708984375 +74489 0.062896728515625 +74490 0.14288330078125 +74491 0.09271240234375 +74492 0.147186279296875 +74493 0.092987060546875 +74494 0.140655517578125 +74495 0.07855224609375 +74496 0.12762451171875 +74497 0.06427001953125 +74498 0.104522705078125 +74499 0.0347900390625 +74500 0.071868896484375 +74501 -0.01171875 +74502 0.03643798828125 +74503 -0.056060791015625 +74504 0.012298583984375 +74505 -0.055511474609375 +74506 0.000640869140625 +74507 -0.010467529296875 +74508 -0.01336669921875 +74509 0.02508544921875 +74510 -0.036041259765625 +74511 0.025665283203125 +74512 -0.058380126953125 +74513 0.017333984375 +74514 -0.078887939453125 +74515 0.00189208984375 +74516 -0.100128173828125 +74517 -0.03173828125 +74518 -0.118011474609375 +74519 -0.071502685546875 +74520 -0.137725830078125 +74521 -0.13543701171875 +74522 -0.1583251953125 +74523 -0.219970703125 +74524 -0.172821044921875 +74525 -0.300506591796875 +74526 -0.181671142578125 +74527 -0.376312255859375 +74528 -0.176361083984375 +74529 -0.416107177734375 +74530 -0.143280029296875 +74531 -0.371124267578125 +74532 -0.0838623046875 +74533 -0.242279052734375 +74534 -0.011322021484375 +74535 -0.069732666015625 +74536 0.066925048828125 +74537 0.125640869140625 +74538 0.140533447265625 +74539 0.31268310546875 +74540 0.197662353515625 +74541 0.45501708984375 +74542 0.238250732421875 +74543 0.554779052734375 +74544 0.261444091796875 +74545 0.61065673828125 +74546 0.263519287109375 +74547 0.610931396484375 +74548 0.23724365234375 +74549 0.531463623046875 +74550 0.18768310546875 +74551 0.3883056640625 +74552 0.131317138671875 +74553 0.23468017578125 +74554 0.076202392578125 +74555 0.095245361328125 +74556 0.03094482421875 +74557 -0.00396728515625 +74558 0.000762939453125 +74559 -0.04852294921875 +74560 -0.018402099609375 +74561 -0.055145263671875 +74562 -0.041168212890625 +74563 -0.0758056640625 +74564 -0.075103759765625 +74565 -0.138702392578125 +74566 -0.109039306640625 +74567 -0.209197998046875 +74568 -0.14288330078125 +74569 -0.289031982421875 +74570 -0.176361083984375 +74571 -0.37884521484375 +74572 -0.202484130859375 +74573 -0.456329345703125 +74574 -0.219696044921875 +74575 -0.51641845703125 +74576 -0.216217041015625 +74577 -0.519287109375 +74578 -0.19036865234375 +74579 -0.458251953125 +74580 -0.1580810546875 +74581 -0.384796142578125 +74582 -0.12744140625 +74583 -0.323699951171875 +74584 -0.097442626953125 +74585 -0.269287109375 +74586 -0.061004638671875 +74587 -0.1951904296875 +74588 -0.01849365234375 +74589 -0.100006103515625 +74590 0.021240234375 +74591 -0.01055908203125 +74592 0.066619873046875 +74593 0.1033935546875 +74594 0.1192626953125 +74595 0.24908447265625 +74596 0.162750244140625 +74597 0.373199462890625 +74598 0.1915283203125 +74599 0.45806884765625 +74600 0.20782470703125 +74601 0.511474609375 +74602 0.221282958984375 +74603 0.565399169921875 +74604 0.2296142578125 +74605 0.61138916015625 +74606 0.21527099609375 +74607 0.5897216796875 +74608 0.175811767578125 +74609 0.4906005859375 +74610 0.1170654296875 +74611 0.33148193359375 +74612 0.05029296875 +74613 0.147796630859375 +74614 -0.01129150390625 +74615 -0.01873779296875 +74616 -0.0587158203125 +74617 -0.140289306640625 +74618 -0.083953857421875 +74619 -0.191986083984375 +74620 -0.08966064453125 +74621 -0.184295654296875 +74622 -0.088836669921875 +74623 -0.161834716796875 +74624 -0.093780517578125 +74625 -0.166595458984375 +74626 -0.10296630859375 +74627 -0.19390869140625 +74628 -0.110626220703125 +74629 -0.22442626953125 +74630 -0.12335205078125 +74631 -0.279754638671875 +74632 -0.13519287109375 +74633 -0.3389892578125 +74634 -0.1322021484375 +74635 -0.3543701171875 +74636 -0.12152099609375 +74637 -0.348175048828125 +74638 -0.1053466796875 +74639 -0.32598876953125 +74640 -0.0753173828125 +74641 -0.2581787109375 +74642 -0.030517578125 +74643 -0.139801025390625 +74644 0.024200439453125 +74645 0.014617919921875 +74646 0.0701904296875 +74647 0.144378662109375 +74648 0.09857177734375 +74649 0.221038818359375 +74650 0.116943359375 +74651 0.27069091796875 +74652 0.125396728515625 +74653 0.294036865234375 +74654 0.130096435546875 +74655 0.311767578125 +74656 0.1357421875 +74657 0.339141845703125 +74658 0.137908935546875 +74659 0.360260009765625 +74660 0.132476806640625 +74661 0.360504150390625 +74662 0.109893798828125 +74663 0.308380126953125 +74664 0.06353759765625 +74665 0.18170166015625 +74666 0.00140380859375 +74667 0.0047607421875 +74668 -0.061553955078125 +74669 -0.17559814453125 +74670 -0.1109619140625 +74671 -0.3143310546875 +74672 -0.132904052734375 +74673 -0.36785888671875 +74674 -0.13531494140625 +74675 -0.36248779296875 +74676 -0.13214111328125 +74677 -0.343536376953125 +74678 -0.120452880859375 +74679 -0.3018798828125 +74680 -0.09832763671875 +74681 -0.231414794921875 +74682 -0.061279296875 +74683 -0.117645263671875 +74684 -0.01953125 +74685 0.007049560546875 +74686 0.0096435546875 +74687 0.087982177734375 +74688 0.030487060546875 +74689 0.13946533203125 +74690 0.04669189453125 +74691 0.17425537109375 +74692 0.056640625 +74693 0.188201904296875 +74694 0.056884765625 +74695 0.171234130859375 +74696 0.04559326171875 +74697 0.118438720703125 +74698 0.031005859375 +74699 0.05706787109375 +74700 0.013580322265625 +74701 -0.010711669921875 +74702 -0.008880615234375 +74703 -0.0914306640625 +74704 -0.029388427734375 +74705 -0.162322998046875 +74706 -0.039031982421875 +74707 -0.194549560546875 +74708 -0.02569580078125 +74709 -0.1492919921875 +74710 0.01220703125 +74711 -0.02166748046875 +74712 0.05474853515625 +74713 0.124053955078125 +74714 0.07818603515625 +74715 0.211151123046875 +74716 0.0830078125 +74717 0.240447998046875 +74718 0.07891845703125 +74719 0.242218017578125 +74720 0.069091796875 +74721 0.2257080078125 +74722 0.05487060546875 +74723 0.194366455078125 +74724 0.026275634765625 +74725 0.115509033203125 +74726 -0.009063720703125 +74727 0.0128173828125 +74728 -0.03228759765625 +74729 -0.053802490234375 +74730 -0.051513671875 +74731 -0.110626220703125 +74732 -0.079742431640625 +74733 -0.199493408203125 +74734 -0.108856201171875 +74735 -0.29437255859375 +74736 -0.119232177734375 +74737 -0.33221435546875 +74738 -0.1005859375 +74739 -0.27972412109375 +74740 -0.068206787109375 +74741 -0.185333251953125 +74742 -0.04693603515625 +74743 -0.128204345703125 +74744 -0.03924560546875 +74745 -0.115692138671875 +74746 -0.035614013671875 +74747 -0.116455078125 +74748 -0.028594970703125 +74749 -0.105926513671875 +74750 -0.00897216796875 +74751 -0.053955078125 +74752 0.02618408203125 +74753 0.048797607421875 +74754 0.0623779296875 +74755 0.157318115234375 +74756 0.079803466796875 +74757 0.212005615234375 +74758 0.08050537109375 +74759 0.218475341796875 +74760 0.085418701171875 +74761 0.23724365234375 +74762 0.10736083984375 +74763 0.30535888671875 +74764 0.132110595703125 +74765 0.38128662109375 +74766 0.138824462890625 +74767 0.404449462890625 +74768 0.13427734375 +74769 0.3944091796875 +74770 0.131378173828125 +74771 0.3885498046875 +74772 0.121826171875 +74773 0.362640380859375 +74774 0.090789794921875 +74775 0.27362060546875 +74776 0.036773681640625 +74777 0.11712646484375 +74778 -0.0223388671875 +74779 -0.054901123046875 +74780 -0.06884765625 +74781 -0.19085693359375 +74782 -0.101043701171875 +74783 -0.28570556640625 +74784 -0.118896484375 +74785 -0.339263916015625 +74786 -0.131378173828125 +74787 -0.3775634765625 +74788 -0.154052734375 +74789 -0.445709228515625 +74790 -0.183990478515625 +74791 -0.535064697265625 +74792 -0.21551513671875 +74793 -0.629058837890625 +74794 -0.238311767578125 +74795 -0.697601318359375 +74796 -0.239776611328125 +74797 -0.70391845703125 +74798 -0.218048095703125 +74799 -0.6424560546875 +74800 -0.16558837890625 +74801 -0.491241455078125 +74802 -0.087738037109375 +74803 -0.265716552734375 +74804 -0.00439453125 +74805 -0.023712158203125 +74806 0.073028564453125 +74807 0.201751708984375 +74808 0.132568359375 +74809 0.375823974609375 +74810 0.169647216796875 +74811 0.485076904296875 +74812 0.19781494140625 +74813 0.56884765625 +74814 0.2197265625 +74815 0.634765625 +74816 0.21990966796875 +74817 0.63763427734375 +74818 0.1944580078125 +74819 0.5660400390625 +74820 0.161346435546875 +74821 0.4720458984375 +74822 0.13824462890625 +74823 0.40692138671875 +74824 0.127655029296875 +74825 0.3778076171875 +74826 0.126922607421875 +74827 0.376953125 +74828 0.12493896484375 +74829 0.371978759765625 +74830 0.104583740234375 +74831 0.313140869140625 +74832 0.06036376953125 +74833 0.184417724609375 +74834 0.001007080078125 +74835 0.011199951171875 +74836 -0.061279296875 +74837 -0.171051025390625 +74838 -0.117950439453125 +74839 -0.33740234375 +74840 -0.16357421875 +74841 -0.47198486328125 +74842 -0.1932373046875 +74843 -0.560394287109375 +74844 -0.19940185546875 +74845 -0.58056640625 +74846 -0.18731689453125 +74847 -0.54754638671875 +74848 -0.173248291015625 +74849 -0.508575439453125 +74850 -0.155792236328125 +74851 -0.459503173828125 +74852 -0.132965087890625 +74853 -0.394378662109375 +74854 -0.1182861328125 +74855 -0.35260009765625 +74856 -0.104034423828125 +74857 -0.31170654296875 +74858 -0.064666748046875 +74859 -0.197418212890625 +74860 0.0003662109375 +74861 -0.007965087890625 +74862 0.07415771484375 +74863 0.207489013671875 +74864 0.14306640625 +74865 0.409210205078125 +74866 0.198486328125 +74867 0.57208251953125 +74868 0.2301025390625 +74869 0.66595458984375 +74870 0.226898193359375 +74871 0.65875244140625 +74872 0.19476318359375 +74873 0.56744384765625 +74874 0.14727783203125 +74875 0.431396484375 +74876 0.099578857421875 +74877 0.29443359375 +74878 0.060577392578125 +74879 0.182464599609375 +74880 0.019378662109375 +74881 0.06365966796875 +74882 -0.02880859375 +74883 -0.075958251953125 +74884 -0.06781005859375 +74885 -0.189422607421875 +74886 -0.095977783203125 +74887 -0.271942138671875 +74888 -0.119873046875 +74889 -0.342529296875 +74890 -0.126861572265625 +74891 -0.364166259765625 +74892 -0.113616943359375 +74893 -0.327239990234375 +74894 -0.095733642578125 +74895 -0.2769775390625 +74896 -0.087127685546875 +74897 -0.253692626953125 +74898 -0.08306884765625 +74899 -0.24365234375 +74900 -0.066925048828125 +74901 -0.1983642578125 +74902 -0.0382080078125 +74903 -0.116241455078125 +74904 -0.010498046875 +74905 -0.036834716796875 +74906 0.014434814453125 +74907 0.034881591796875 +74908 0.033935546875 +74909 0.09124755859375 +74910 0.03997802734375 +74911 0.10888671875 +74912 0.0455322265625 +74913 0.125518798828125 +74914 0.056304931640625 +74915 0.15771484375 +74916 0.062957763671875 +74917 0.17828369140625 +74918 0.059967041015625 +74919 0.17108154296875 +74920 0.0452880859375 +74921 0.129974365234375 +74922 0.02838134765625 +74923 0.082427978515625 +74924 0.009033203125 +74925 0.027679443359375 +74926 -0.02349853515625 +74927 -0.065643310546875 +74928 -0.056060791015625 +74929 -0.15936279296875 +74930 -0.074737548828125 +74931 -0.21307373046875 +74932 -0.082244873046875 +74933 -0.234649658203125 +74934 -0.07037353515625 +74935 -0.2001953125 +74936 -0.042388916015625 +74937 -0.119171142578125 +74938 -0.00970458984375 +74939 -0.024749755859375 +74940 0.028564453125 +74941 0.085784912109375 +74942 0.060577392578125 +74943 0.178131103515625 +74944 0.07373046875 +74945 0.215576171875 +74946 0.07257080078125 +74947 0.211456298828125 +74948 0.060394287109375 +74949 0.17523193359375 +74950 0.044677734375 +74951 0.128753662109375 +74952 0.03570556640625 +74953 0.1019287109375 +74954 0.02642822265625 +74955 0.0743408203125 +74956 0.015899658203125 +74957 0.04327392578125 +74958 0.014251708984375 +74959 0.038177490234375 +74960 0.027374267578125 +74961 0.076263427734375 +74962 0.049591064453125 +74963 0.14105224609375 +74964 0.065093994140625 +74965 0.186431884765625 +74966 0.06573486328125 +74967 0.188812255859375 +74968 0.048370361328125 +74969 0.1390380859375 +74970 0.0146484375 +74971 0.041778564453125 +74972 -0.027313232421875 +74973 -0.079437255859375 +74974 -0.07568359375 +74975 -0.219390869140625 +74976 -0.12689208984375 +74977 -0.367828369140625 +74978 -0.170684814453125 +74979 -0.494873046875 +74980 -0.19183349609375 +74981 -0.556243896484375 +74982 -0.175445556640625 +74983 -0.508697509765625 +74984 -0.12957763671875 +74985 -0.3756103515625 +74986 -0.0755615234375 +74987 -0.218902587890625 +74988 -0.022064208984375 +74989 -0.063751220703125 +74990 0.031463623046875 +74991 0.091552734375 +74992 0.081268310546875 +74993 0.23602294921875 +74994 0.1181640625 +74995 0.342987060546875 +74996 0.13623046875 +74997 0.39520263671875 +74998 0.134307861328125 +74999 0.389373779296875 +75000 0.111968994140625 +75001 0.324249267578125 +75002 0.077545166015625 +75003 0.224090576171875 +75004 0.043243408203125 +75005 0.124267578125 +75006 0.013275146484375 +75007 0.037078857421875 +75008 -0.00250244140625 +75009 -0.010101318359375 +75010 -0.00506591796875 +75011 -0.019439697265625 +75012 -0.00604248046875 +75013 -0.022796630859375 +75014 0.00177001953125 +75015 -0.001556396484375 +75016 0.023040771484375 +75017 0.056304931640625 +75018 0.0413818359375 +75019 0.106719970703125 +75020 0.037078857421875 +75021 0.096893310546875 +75022 0.016204833984375 +75023 0.042694091796875 +75024 -0.0069580078125 +75025 -0.018035888671875 +75026 -0.02886962890625 +75027 -0.07586669921875 +75028 -0.045257568359375 +75029 -0.11944580078125 +75030 -0.060272216796875 +75031 -0.15972900390625 +75032 -0.076171875 +75033 -0.202606201171875 +75034 -0.0931396484375 +75035 -0.24859619140625 +75036 -0.114044189453125 +75037 -0.30517578125 +75038 -0.13507080078125 +75039 -0.36212158203125 +75040 -0.145721435546875 +75041 -0.39141845703125 +75042 -0.1318359375 +75043 -0.35528564453125 +75044 -0.092041015625 +75045 -0.249969482421875 +75046 -0.03289794921875 +75047 -0.092864990234375 +75048 0.03546142578125 +75049 0.08905029296875 +75050 0.09027099609375 +75051 0.2352294921875 +75052 0.121429443359375 +75053 0.318817138671875 +75054 0.13604736328125 +75055 0.358642578125 +75056 0.13153076171875 +75057 0.347747802734375 +75058 0.10772705078125 +75059 0.28564453125 +75060 0.083770751953125 +75061 0.223175048828125 +75062 0.073394775390625 +75063 0.196746826171875 +75064 0.066650390625 +75065 0.179840087890625 +75066 0.05718994140625 +75067 0.155548095703125 +75068 0.055328369140625 +75069 0.151214599609375 +75070 0.057342529296875 +75071 0.156951904296875 +75072 0.047821044921875 +75073 0.13177490234375 +75074 0.03619384765625 +75075 0.100799560546875 +75076 0.03118896484375 +75077 0.087127685546875 +75078 0.019287109375 +75079 0.05487060546875 +75080 -0.004425048828125 +75081 -0.009002685546875 +75082 -0.039764404296875 +75083 -0.10400390625 +75084 -0.08648681640625 +75085 -0.229400634765625 +75086 -0.133453369140625 +75087 -0.35552978515625 +75088 -0.16546630859375 +75089 -0.441925048828125 +75090 -0.17706298828125 +75091 -0.473846435546875 +75092 -0.173309326171875 +75093 -0.464813232421875 +75094 -0.15582275390625 +75095 -0.419097900390625 +75096 -0.123748779296875 +75097 -0.334320068359375 +75098 -0.083648681640625 +75099 -0.227935791015625 +75100 -0.04437255859375 +75101 -0.12347412109375 +75102 -0.0084228515625 +75103 -0.02764892578125 +75104 0.031036376953125 +75105 0.077667236328125 +75106 0.081787109375 +75107 0.2132568359375 +75108 0.147491455078125 +75109 0.38885498046875 +75110 0.22003173828125 +75111 0.582794189453125 +75112 0.2764892578125 +75113 0.734039306640625 +75114 0.300933837890625 +75115 0.800140380859375 +75116 0.292327880859375 +75117 0.7783203125 +75118 0.249420166015625 +75119 0.6651611328125 +75120 0.171844482421875 +75121 0.45965576171875 +75122 0.07366943359375 +75123 0.199188232421875 +75124 -0.020416259765625 +75125 -0.050689697265625 +75126 -0.0889892578125 +75127 -0.23297119140625 +75128 -0.125457763671875 +75129 -0.33013916015625 +75130 -0.139678955078125 +75131 -0.368408203125 +75132 -0.14337158203125 +75133 -0.378936767578125 +75134 -0.142303466796875 +75135 -0.376983642578125 +75136 -0.142974853515625 +75137 -0.37969970703125 +75138 -0.14703369140625 +75139 -0.391510009765625 +75140 -0.14434814453125 +75141 -0.385345458984375 +75142 -0.127685546875 +75143 -0.3419189453125 +75144 -0.105194091796875 +75145 -0.28289794921875 +75146 -0.09320068359375 +75147 -0.251617431640625 +75148 -0.098480224609375 +75149 -0.266143798828125 +75150 -0.10107421875 +75151 -0.273345947265625 +75152 -0.079742431640625 +75153 -0.216796875 +75154 -0.04644775390625 +75155 -0.128265380859375 +75156 -0.023895263671875 +75157 -0.068145751953125 +75158 -0.014556884765625 +75159 -0.0430908203125 +75160 -0.0076904296875 +75161 -0.024444580078125 +75162 0.009063720703125 +75163 0.020721435546875 +75164 0.047760009765625 +75165 0.124481201171875 +75166 0.0975341796875 +75167 0.25787353515625 +75168 0.1427001953125 +75169 0.379119873046875 +75170 0.18017578125 +75171 0.47991943359375 +75172 0.197906494140625 +75173 0.5281982421875 +75174 0.19110107421875 +75175 0.511138916015625 +75176 0.170135498046875 +75177 0.456207275390625 +75178 0.151580810546875 +75179 0.407470703125 +75180 0.142547607421875 +75181 0.383758544921875 +75182 0.132415771484375 +75183 0.35687255859375 +75184 0.11553955078125 +75185 0.31182861328125 +75186 0.0927734375 +75187 0.250885009765625 +75188 0.06085205078125 +75189 0.1654052734375 +75190 0.01220703125 +75191 0.035247802734375 +75192 -0.054107666015625 +75193 -0.142059326171875 +75194 -0.126495361328125 +75195 -0.33563232421875 +75196 -0.20086669921875 +75197 -0.5345458984375 +75198 -0.2708740234375 +75199 -0.72186279296875 +75200 -0.3135986328125 +75201 -0.836669921875 +75202 -0.311676025390625 +75203 -0.8326416015625 +75204 -0.2725830078125 +75205 -0.7296142578125 +75206 -0.217041015625 +75207 -0.582550048828125 +75208 -0.163330078125 +75209 -0.440093994140625 +75210 -0.1197509765625 +75211 -0.324310302734375 +75212 -0.073638916015625 +75213 -0.20147705078125 +75214 -0.014801025390625 +75215 -0.044647216796875 +75216 0.04083251953125 +75217 0.103973388671875 +75218 0.0775146484375 +75219 0.202392578125 +75220 0.1004638671875 +75221 0.264495849609375 +75222 0.12799072265625 +75223 0.338897705078125 +75224 0.166961669921875 +75225 0.443817138671875 +75226 0.204559326171875 +75227 0.545074462890625 +75228 0.23126220703125 +75229 0.6173095703125 +75230 0.24407958984375 +75231 0.6524658203125 +75232 0.24786376953125 +75233 0.66339111328125 +75234 0.244903564453125 +75235 0.6561279296875 +75236 0.226226806640625 +75237 0.606781005859375 +75238 0.186492919921875 +75239 0.501190185546875 +75240 0.1307373046875 +75241 0.352783203125 +75242 0.06463623046875 +75243 0.176544189453125 +75244 -0.014556884765625 +75245 -0.034820556640625 +75246 -0.09814453125 +75247 -0.258209228515625 +75248 -0.16693115234375 +75249 -0.44244384765625 +75250 -0.21636962890625 +75251 -0.5753173828125 +75252 -0.244659423828125 +75253 -0.65203857421875 +75254 -0.240203857421875 +75255 -0.641632080078125 +75256 -0.2098388671875 +75257 -0.562164306640625 +75258 -0.170318603515625 +75259 -0.458038330078125 +75260 -0.129638671875 +75261 -0.350555419921875 +75262 -0.09564208984375 +75263 -0.260528564453125 +75264 -0.070037841796875 +75265 -0.192108154296875 +75266 -0.0516357421875 +75267 -0.141937255859375 +75268 -0.037200927734375 +75269 -0.1021728515625 +75270 -0.022857666015625 +75271 -0.062896728515625 +75272 -0.00372314453125 +75273 -0.011932373046875 +75274 0.025054931640625 +75275 0.062835693359375 +75276 0.058319091796875 +75277 0.148712158203125 +75278 0.094512939453125 +75279 0.241729736328125 +75280 0.136688232421875 +75281 0.34912109375 +75282 0.179351806640625 +75283 0.457305908203125 +75284 0.213470458984375 +75285 0.54388427734375 +75286 0.224456787109375 +75287 0.5728759765625 +75288 0.196990966796875 +75289 0.506591796875 +75290 0.133636474609375 +75291 0.351226806640625 +75292 0.05059814453125 +75293 0.146514892578125 +75294 -0.03076171875 +75295 -0.05523681640625 +75296 -0.0950927734375 +75297 -0.21624755859375 +75298 -0.141815185546875 +75299 -0.334930419921875 +75300 -0.1676025390625 +75301 -0.402984619140625 +75302 -0.181121826171875 +75303 -0.4412841796875 +75304 -0.20123291015625 +75305 -0.49578857421875 +75306 -0.2254638671875 +75307 -0.5601806640625 +75308 -0.24017333984375 +75309 -0.600738525390625 +75310 -0.231903076171875 +75311 -0.584228515625 +75312 -0.187896728515625 +75313 -0.47930908203125 +75314 -0.10552978515625 +75315 -0.27935791015625 +75316 0.005096435546875 +75317 -0.0089111328125 +75318 0.1181640625 +75319 0.268798828125 +75320 0.20477294921875 +75321 0.482818603515625 +75322 0.252960205078125 +75323 0.60369873046875 +75324 0.270538330078125 +75325 0.650421142578125 +75326 0.27435302734375 +75327 0.66400146484375 +75328 0.2633056640625 +75329 0.6414794921875 +75330 0.233306884765625 +75331 0.572540283203125 +75332 0.201141357421875 +75333 0.498138427734375 +75334 0.175537109375 +75335 0.439453125 +75336 0.148040771484375 +75337 0.375518798828125 +75338 0.105743408203125 +75339 0.274505615234375 +75340 0.03741455078125 +75341 0.1087646484375 +75342 -0.047821044921875 +75343 -0.099395751953125 +75344 -0.136993408203125 +75345 -0.3182373046875 +75346 -0.230621337890625 +75347 -0.5489501953125 +75348 -0.32147216796875 +75349 -0.7738037109375 +75350 -0.38800048828125 +75351 -0.86383056640625 +75352 -0.416717529296875 +75353 -0.870391845703125 +75354 -0.414947509765625 +75355 -0.86895751953125 +75356 -0.388153076171875 +75357 -0.861053466796875 +75358 -0.329376220703125 +75359 -0.765869140625 +75360 -0.234100341796875 +75361 -0.5301513671875 +75362 -0.10528564453125 +75363 -0.214691162109375 +75364 0.0394287109375 +75365 0.137359619140625 +75366 0.179046630859375 +75367 0.474822998046875 +75368 0.299041748046875 +75369 0.76239013671875 +75370 0.388397216796875 +75371 0.867462158203125 +75372 0.447296142578125 +75373 0.870361328125 +75374 0.471038818359375 +75375 0.86480712890625 +75376 0.461883544921875 +75377 0.831817626953125 +75378 0.429840087890625 +75379 0.677581787109375 +75380 0.377349853515625 +75381 0.495880126953125 +75382 0.31207275390625 +75383 0.30767822265625 +75384 0.2349853515625 +75385 0.116180419921875 +75386 0.1331787109375 +75387 -0.110748291015625 +75388 0.00390625 +75389 -0.381805419921875 +75390 -0.13531494140625 +75391 -0.6572265625 +75392 -0.259979248046875 +75393 -0.857421875 +75394 -0.3525390625 +75395 -0.870391845703125 +75396 -0.41009521484375 +75397 -0.870391845703125 +75398 -0.443572998046875 +75399 -0.86444091796875 +75400 -0.467559814453125 +75401 -0.85723876953125 +75402 -0.474639892578125 +75403 -0.790008544921875 +75404 -0.442718505859375 +75405 -0.62847900390625 +75406 -0.37054443359375 +75407 -0.3956298828125 +75408 -0.271575927734375 +75409 -0.126708984375 +75410 -0.157073974609375 +75411 0.150115966796875 +75412 -0.0318603515625 +75413 0.424041748046875 +75414 0.092987060546875 +75415 0.670623779296875 +75416 0.20159912109375 +75417 0.854522705078125 +75418 0.286712646484375 +75419 0.866485595703125 +75420 0.342010498046875 +75421 0.86920166015625 +75422 0.3748779296875 +75423 0.8653564453125 +75424 0.390777587890625 +75425 0.857147216796875 +75426 0.3885498046875 +75427 0.766845703125 +75428 0.370269775390625 +75429 0.628509521484375 +75430 0.333221435546875 +75431 0.462127685546875 +75432 0.287994384765625 +75433 0.297210693359375 +75434 0.239715576171875 +75435 0.14862060546875 +75436 0.179107666015625 +75437 -0.00537109375 +75438 0.1092529296875 +75439 -0.15753173828125 +75440 0.028778076171875 +75441 -0.31304931640625 +75442 -0.067962646484375 +75443 -0.48876953125 +75444 -0.161773681640625 +75445 -0.6416015625 +75446 -0.242523193359375 +75447 -0.751373291015625 +75448 -0.31964111328125 +75449 -0.84619140625 +75450 -0.3870849609375 +75451 -0.861297607421875 +75452 -0.431304931640625 +75453 -0.863250732421875 +75454 -0.439453125 +75455 -0.856597900390625 +75456 -0.416473388671875 +75457 -0.7498779296875 +75458 -0.386016845703125 +75459 -0.624542236328125 +75460 -0.339202880859375 +75461 -0.47808837890625 +75462 -0.252227783203125 +75463 -0.253387451171875 +75464 -0.143768310546875 +75465 0.003692626953125 +75466 -0.041778564453125 +75467 0.2257080078125 +75468 0.05877685546875 +75469 0.427154541015625 +75470 0.17108154296875 +75471 0.643218994140625 +75472 0.2911376953125 +75473 0.855926513671875 +75474 0.395263671875 +75475 0.870361328125 +75476 0.463165283203125 +75477 0.870361328125 +75478 0.497772216796875 +75479 0.862762451171875 +75480 0.49786376953125 +75481 0.79669189453125 +75482 0.4595947265625 +75483 0.595794677734375 +75484 0.3948974609375 +75485 0.362152099609375 +75486 0.315277099609375 +75487 0.1270751953125 +75488 0.229400634765625 +75489 -0.086944580078125 +75490 0.138214111328125 +75491 -0.2784423828125 +75492 0.027618408203125 +75493 -0.484832763671875 +75494 -0.110137939453125 +75495 -0.729583740234375 +75496 -0.25433349609375 +75497 -0.86688232421875 +75498 -0.379058837890625 +75499 -0.870391845703125 +75500 -0.48223876953125 +75501 -0.86859130859375 +75502 -0.56292724609375 +75503 -0.86279296875 +75504 -0.606414794921875 +75505 -0.817962646484375 +75506 -0.59417724609375 +75507 -0.6116943359375 +75508 -0.523284912109375 +75509 -0.3128662109375 +75510 -0.40753173828125 +75511 0.039398193359375 +75512 -0.255126953125 +75513 0.422821044921875 +75514 -0.079742431640625 +75515 0.805145263671875 +75516 0.090728759765625 +75517 0.870361328125 +75518 0.23291015625 +75519 0.870361328125 +75520 0.342071533203125 +75521 0.860015869140625 +75522 0.41448974609375 +75523 0.727935791015625 +75524 0.447357177734375 +75525 0.48114013671875 +75526 0.451080322265625 +75527 0.2059326171875 +75528 0.435302734375 +75529 -0.06103515625 +75530 0.404083251953125 +75531 -0.29913330078125 +75532 0.350738525390625 +75533 -0.516204833984375 +75534 0.26812744140625 +75535 -0.7252197265625 +75536 0.1668701171875 +75537 -0.85980224609375 +75538 0.061798095703125 +75539 -0.870391845703125 +75540 -0.0343017578125 +75541 -0.870391845703125 +75542 -0.10015869140625 +75543 -0.858062744140625 +75544 -0.134033203125 +75545 -0.673004150390625 +75546 -0.1590576171875 +75547 -0.42694091796875 +75548 -0.1947021484375 +75549 -0.2100830078125 +75550 -0.239990234375 +75551 -0.0362548828125 +75552 -0.281951904296875 +75553 0.10943603515625 +75554 -0.311614990234375 +75555 0.23516845703125 +75556 -0.310546875 +75557 0.373687744140625 +75558 -0.279388427734375 +75559 0.517791748046875 +75560 -0.245635986328125 +75561 0.602783203125 +75562 -0.206787109375 +75563 0.635711669921875 +75564 -0.14801025390625 +75565 0.655181884765625 +75566 -0.07354736328125 +75567 0.65948486328125 +75568 0.013153076171875 +75569 0.651275634765625 +75570 0.101318359375 +75571 0.61846923828125 +75572 0.174652099609375 +75573 0.53753662109375 +75574 0.22515869140625 +75575 0.404144287109375 +75576 0.2484130859375 +75577 0.22186279296875 +75578 0.24481201171875 +75579 0.003997802734375 +75580 0.22216796875 +75581 -0.22100830078125 +75582 0.189361572265625 +75583 -0.42449951171875 +75584 0.155609130859375 +75585 -0.579833984375 +75586 0.1395263671875 +75587 -0.641876220703125 +75588 0.138031005859375 +75589 -0.6177978515625 +75590 0.122528076171875 +75591 -0.575531005859375 +75592 0.090545654296875 +75593 -0.526336669921875 +75594 0.0648193359375 +75595 -0.42645263671875 +75596 0.057403564453125 +75597 -0.2581787109375 +75598 0.05230712890625 +75599 -0.068695068359375 +75600 0.032684326171875 +75601 0.09222412109375 +75602 0.006866455078125 +75603 0.232147216796875 +75604 -0.0205078125 +75605 0.3509521484375 +75606 -0.062286376953125 +75607 0.410064697265625 +75608 -0.131195068359375 +75609 0.372955322265625 +75610 -0.21783447265625 +75611 0.2554931640625 +75612 -0.299041748046875 +75613 0.10711669921875 +75614 -0.365997314453125 +75615 -0.052886962890625 +75616 -0.402618408203125 +75617 -0.186279296875 +75618 -0.38421630859375 +75619 -0.23291015625 +75620 -0.320709228515625 +75621 -0.209442138671875 +75622 -0.24102783203125 +75623 -0.174163818359375 +75624 -0.14886474609375 +75625 -0.126739501953125 +75626 -0.039947509765625 +75627 -0.048126220703125 +75628 0.07318115234375 +75629 0.0426025390625 +75630 0.169830322265625 +75631 0.10748291015625 +75632 0.2440185546875 +75633 0.1409912109375 +75634 0.316497802734375 +75635 0.19708251953125 +75636 0.38409423828125 +75637 0.273651123046875 +75638 0.422027587890625 +75639 0.31768798828125 +75640 0.4349365234375 +75641 0.341094970703125 +75642 0.43377685546875 +75643 0.368011474609375 +75644 0.4083251953125 +75645 0.37249755859375 +75646 0.3367919921875 +75647 0.30072021484375 +75648 0.221282958984375 +75649 0.1517333984375 +75650 0.091094970703125 +75651 -0.01470947265625 +75652 -0.045928955078125 +75653 -0.1883544921875 +75654 -0.18792724609375 +75655 -0.372711181640625 +75656 -0.307891845703125 +75657 -0.51397705078125 +75658 -0.384979248046875 +75659 -0.57177734375 +75660 -0.413665771484375 +75661 -0.53948974609375 +75662 -0.3997802734375 +75663 -0.43511962890625 +75664 -0.358428955078125 +75665 -0.2962646484375 +75666 -0.3056640625 +75667 -0.161102294921875 +75668 -0.247650146484375 +75669 -0.0435791015625 +75670 -0.18328857421875 +75671 0.060394287109375 +75672 -0.120208740234375 +75673 0.13665771484375 +75674 -0.066925048828125 +75675 0.170135498046875 +75676 -0.02374267578125 +75677 0.16552734375 +75678 0.02178955078125 +75679 0.15728759765625 +75680 0.06927490234375 +75681 0.150787353515625 +75682 0.105316162109375 +75683 0.12200927734375 +75684 0.131378173828125 +75685 0.080108642578125 +75686 0.156646728515625 +75687 0.05126953125 +75688 0.19134521484375 +75689 0.062896728515625 +75690 0.224273681640625 +75691 0.09271240234375 +75692 0.233642578125 +75693 0.092987060546875 +75694 0.22576904296875 +75695 0.07855224609375 +75696 0.20758056640625 +75697 0.06427001953125 +75698 0.173248291015625 +75699 0.0347900390625 +75700 0.1234130859375 +75701 -0.01171875 +75702 0.068328857421875 +75703 -0.056060791015625 +75704 0.0289306640625 +75705 -0.055511474609375 +75706 0.007354736328125 +75707 -0.010467529296875 +75708 -0.017822265625 +75709 0.02508544921875 +75710 -0.05560302734375 +75711 0.025665283203125 +75712 -0.092529296875 +75713 0.017333984375 +75714 -0.126129150390625 +75715 0.00189208984375 +75716 -0.160003662109375 +75717 -0.03173828125 +75718 -0.18804931640625 +75719 -0.071502685546875 +75720 -0.2178955078125 +75721 -0.13543701171875 +75722 -0.24810791015625 +75723 -0.219970703125 +75724 -0.268463134765625 +75725 -0.300506591796875 +75726 -0.27972412109375 +75727 -0.376312255859375 +75728 -0.269500732421875 +75729 -0.416107177734375 +75730 -0.218048095703125 +75731 -0.371124267578125 +75732 -0.127593994140625 +75733 -0.242279052734375 +75734 -0.0177001953125 +75735 -0.069732666015625 +75736 0.10052490234375 +75737 0.125640869140625 +75738 0.211639404296875 +75739 0.31268310546875 +75740 0.2982177734375 +75741 0.45501708984375 +75742 0.36004638671875 +75743 0.554779052734375 +75744 0.395721435546875 +75745 0.61065673828125 +75746 0.399688720703125 +75747 0.610931396484375 +75748 0.361328125 +75749 0.531463623046875 +75750 0.2880859375 +75751 0.3883056640625 +75752 0.20416259765625 +75753 0.23468017578125 +75754 0.121490478515625 +75755 0.095245361328125 +75756 0.05279541015625 +75757 -0.00396728515625 +75758 0.005859375 +75759 -0.04852294921875 +75760 -0.025054931640625 +75761 -0.055145263671875 +75762 -0.061279296875 +75763 -0.0758056640625 +75764 -0.11376953125 +75765 -0.138702392578125 +75766 -0.165985107421875 +75767 -0.209197998046875 +75768 -0.2176513671875 +75769 -0.289031982421875 +75770 -0.268280029296875 +75771 -0.37884521484375 +75772 -0.3076171875 +75773 -0.456329345703125 +75774 -0.33331298828125 +75775 -0.51641845703125 +75776 -0.327911376953125 +75777 -0.519287109375 +75778 -0.2889404296875 +75779 -0.458251953125 +75780 -0.240264892578125 +75781 -0.384796142578125 +75782 -0.194000244140625 +75783 -0.323699951171875 +75784 -0.148651123046875 +75785 -0.269287109375 +75786 -0.09356689453125 +75787 -0.1951904296875 +75788 -0.029296875 +75789 -0.100006103515625 +75790 0.0308837890625 +75791 -0.01055908203125 +75792 0.09954833984375 +75793 0.1033935546875 +75794 0.1790771484375 +75795 0.24908447265625 +75796 0.244842529296875 +75797 0.373199462890625 +75798 0.2884521484375 +75799 0.45806884765625 +75800 0.313262939453125 +75801 0.511474609375 +75802 0.333740234375 +75803 0.565399169921875 +75804 0.346435546875 +75805 0.61138916015625 +75806 0.32501220703125 +75807 0.5897216796875 +75808 0.26580810546875 +75809 0.4906005859375 +75810 0.17755126953125 +75811 0.33148193359375 +75812 0.077178955078125 +75813 0.147796630859375 +75814 -0.015533447265625 +75815 -0.01873779296875 +75816 -0.087066650390625 +75817 -0.140289306640625 +75818 -0.1253662109375 +75819 -0.191986083984375 +75820 -0.134368896484375 +75821 -0.184295654296875 +75822 -0.133575439453125 +75823 -0.161834716796875 +75824 -0.14141845703125 +75825 -0.166595458984375 +75826 -0.155609130859375 +75827 -0.19390869140625 +75828 -0.167449951171875 +75829 -0.22442626953125 +75830 -0.1868896484375 +75831 -0.279754638671875 +75832 -0.20489501953125 +75833 -0.3389892578125 +75834 -0.2005615234375 +75835 -0.3543701171875 +75836 -0.184600830078125 +75837 -0.348175048828125 +75838 -0.1602783203125 +75839 -0.32598876953125 +75840 -0.1151123046875 +75841 -0.2581787109375 +75842 -0.047637939453125 +75843 -0.139801025390625 +75844 0.034820556640625 +75845 0.014617919921875 +75846 0.104248046875 +75847 0.144378662109375 +75848 0.147308349609375 +75849 0.221038818359375 +75850 0.17535400390625 +75851 0.27069091796875 +75852 0.188507080078125 +75853 0.294036865234375 +75854 0.196014404296875 +75855 0.311767578125 +75856 0.20489501953125 +75857 0.339141845703125 +75858 0.20855712890625 +75859 0.360260009765625 +75860 0.200775146484375 +75861 0.360504150390625 +75862 0.167022705078125 +75863 0.308380126953125 +75864 0.097320556640625 +75865 0.18170166015625 +75866 0.003631591796875 +75867 0.0047607421875 +75868 -0.091400146484375 +75869 -0.17559814453125 +75870 -0.166015625 +75871 -0.3143310546875 +75872 -0.19921875 +75873 -0.36785888671875 +75874 -0.2030029296875 +75875 -0.36248779296875 +75876 -0.198486328125 +75877 -0.343536376953125 +75878 -0.181182861328125 +75879 -0.3018798828125 +75880 -0.14813232421875 +75881 -0.231414794921875 +75882 -0.092529296875 +75883 -0.117645263671875 +75884 -0.029815673828125 +75885 0.007049560546875 +75886 0.013916015625 +75887 0.087982177734375 +75888 0.045074462890625 +75889 0.13946533203125 +75890 0.06927490234375 +75891 0.17425537109375 +75892 0.0841064453125 +75893 0.188201904296875 +75894 0.084381103515625 +75895 0.171234130859375 +75896 0.06732177734375 +75897 0.118438720703125 +75898 0.045379638671875 +75899 0.05706787109375 +75900 0.019195556640625 +75901 -0.010711669921875 +75902 -0.01458740234375 +75903 -0.0914306640625 +75904 -0.045379638671875 +75905 -0.162322998046875 +75906 -0.0596923828125 +75907 -0.194549560546875 +75908 -0.039215087890625 +75909 -0.1492919921875 +75910 0.0184326171875 +75911 -0.02166748046875 +75912 0.083160400390625 +75913 0.124053955078125 +75914 0.118988037109375 +75915 0.211151123046875 +75916 0.126617431640625 +75917 0.240447998046875 +75918 0.120697021484375 +75919 0.242218017578125 +75920 0.105987548828125 +75921 0.2257080078125 +75922 0.08453369140625 +75923 0.194366455078125 +75924 0.041229248046875 +75925 0.115509033203125 +75926 -0.01239013671875 +75927 0.0128173828125 +75928 -0.04779052734375 +75929 -0.053802490234375 +75930 -0.077178955078125 +75931 -0.110626220703125 +75932 -0.1202392578125 +75933 -0.199493408203125 +75934 -0.1646728515625 +75935 -0.29437255859375 +75936 -0.1807861328125 +75937 -0.33221435546875 +75938 -0.15301513671875 +75939 -0.27972412109375 +75940 -0.1043701171875 +75941 -0.185333251953125 +75942 -0.072479248046875 +75943 -0.128204345703125 +75944 -0.06109619140625 +75945 -0.115692138671875 +75946 -0.055755615234375 +75947 -0.116455078125 +75948 -0.045196533203125 +75949 -0.105926513671875 +75950 -0.0155029296875 +75951 -0.053955078125 +75952 0.0374755859375 +75953 0.048797607421875 +75954 0.092254638671875 +75955 0.157318115234375 +75956 0.120513916015625 +75957 0.212005615234375 +75958 0.12481689453125 +75959 0.218475341796875 +75960 0.133697509765625 +75961 0.23724365234375 +75962 0.164703369140625 +75963 0.30535888671875 +75964 0.19830322265625 +75965 0.38128662109375 +75966 0.206024169921875 +75967 0.404449462890625 +75968 0.19732666015625 +75969 0.3944091796875 +75970 0.190093994140625 +75971 0.3885498046875 +75972 0.17315673828125 +75973 0.362640380859375 +75974 0.12646484375 +75975 0.27362060546875 +75976 0.0482177734375 +75977 0.11712646484375 +75978 -0.03680419921875 +75979 -0.054901123046875 +75980 -0.10406494140625 +75981 -0.19085693359375 +75982 -0.15106201171875 +75983 -0.28570556640625 +75984 -0.1776123046875 +75985 -0.339263916015625 +75986 -0.195953369140625 +75987 -0.3775634765625 +75988 -0.227386474609375 +75989 -0.445709228515625 +75990 -0.267913818359375 +75991 -0.535064697265625 +75992 -0.309814453125 +75993 -0.629058837890625 +75994 -0.33905029296875 +75995 -0.697601318359375 +75996 -0.338470458984375 +75997 -0.70391845703125 +75998 -0.305633544921875 +75999 -0.6424560546875 +76000 -0.230377197265625 +76001 -0.491241455078125 +76002 -0.120208740234375 +76003 -0.265716552734375 +76004 -0.002655029296875 +76005 -0.023712158203125 +76006 0.106536865234375 +76007 0.201751708984375 +76008 0.190765380859375 +76009 0.375823974609375 +76010 0.24359130859375 +76011 0.485076904296875 +76012 0.283538818359375 +76013 0.56884765625 +76014 0.314239501953125 +76015 0.634765625 +76016 0.314422607421875 +76017 0.63763427734375 +76018 0.27874755859375 +76019 0.5660400390625 +76020 0.231903076171875 +76021 0.4720458984375 +76022 0.1982421875 +76023 0.40692138671875 +76024 0.18133544921875 +76025 0.3778076171875 +76026 0.177703857421875 +76027 0.376953125 +76028 0.1722412109375 +76029 0.371978759765625 +76030 0.141632080078125 +76031 0.313140869140625 +76032 0.078216552734375 +76033 0.184417724609375 +76034 -0.006103515625 +76035 0.011199951171875 +76036 -0.09423828125 +76037 -0.171051025390625 +76038 -0.173919677734375 +76039 -0.33740234375 +76040 -0.2374267578125 +76041 -0.47198486328125 +76042 -0.277801513671875 +76043 -0.560394287109375 +76044 -0.284149169921875 +76045 -0.58056640625 +76046 -0.2642822265625 +76047 -0.54754638671875 +76048 -0.2421875 +76049 -0.508575439453125 +76050 -0.215850830078125 +76051 -0.459503173828125 +76052 -0.182373046875 +76053 -0.394378662109375 +76054 -0.16156005859375 +76055 -0.35260009765625 +76056 -0.142059326171875 +76057 -0.31170654296875 +76058 -0.08636474609375 +76059 -0.197418212890625 +76060 0.00653076171875 +76061 -0.007965087890625 +76062 0.11199951171875 +76063 0.207489013671875 +76064 0.210235595703125 +76065 0.409210205078125 +76066 0.28875732421875 +76067 0.57208251953125 +76068 0.33258056640625 +76069 0.66595458984375 +76070 0.325714111328125 +76071 0.65875244140625 +76072 0.27691650390625 +76073 0.56744384765625 +76074 0.206146240234375 +76075 0.431396484375 +76076 0.1356201171875 +76077 0.29443359375 +76078 0.07843017578125 +76079 0.182464599609375 +76080 0.0185546875 +76081 0.06365966796875 +76082 -0.051055908203125 +76083 -0.075958251953125 +76084 -0.1068115234375 +76085 -0.189422607421875 +76086 -0.1463623046875 +76087 -0.271942138671875 +76088 -0.179412841796875 +76089 -0.342529296875 +76090 -0.1875 +76091 -0.364166259765625 +76092 -0.16595458984375 +76093 -0.327239990234375 +76094 -0.1376953125 +76095 -0.2769775390625 +76096 -0.123199462890625 +76097 -0.253692626953125 +76098 -0.115692138671875 +76099 -0.24365234375 +76100 -0.090850830078125 +76101 -0.1983642578125 +76102 -0.048004150390625 +76103 -0.116241455078125 +76104 -0.00714111328125 +76105 -0.036834716796875 +76106 0.029205322265625 +76107 0.034881591796875 +76108 0.05718994140625 +76109 0.09124755859375 +76110 0.065093994140625 +76111 0.10888671875 +76112 0.07196044921875 +76113 0.125518798828125 +76114 0.08624267578125 +76115 0.15771484375 +76116 0.094329833984375 +76117 0.17828369140625 +76118 0.088226318359375 +76119 0.17108154296875 +76120 0.06500244140625 +76121 0.129974365234375 +76122 0.03863525390625 +76123 0.082427978515625 +76124 0.008880615234375 +76125 0.027679443359375 +76126 -0.039947509765625 +76127 -0.065643310546875 +76128 -0.0885009765625 +76129 -0.15936279296875 +76130 -0.11639404296875 +76131 -0.21307373046875 +76132 -0.1275634765625 +76133 -0.234649658203125 +76134 -0.109954833984375 +76135 -0.2001953125 +76136 -0.068389892578125 +76137 -0.119171142578125 +76138 -0.019622802734375 +76139 -0.024749755859375 +76140 0.037628173828125 +76141 0.085784912109375 +76142 0.0859375 +76143 0.178131103515625 +76144 0.106719970703125 +76145 0.215576171875 +76146 0.106597900390625 +76147 0.211456298828125 +76148 0.09027099609375 +76149 0.17523193359375 +76150 0.068634033203125 +76151 0.128753662109375 +76152 0.056671142578125 +76153 0.1019287109375 +76154 0.04400634765625 +76155 0.0743408203125 +76156 0.0291748046875 +76157 0.04327392578125 +76158 0.027008056640625 +76159 0.038177490234375 +76160 0.046142578125 +76161 0.076263427734375 +76162 0.078277587890625 +76163 0.14105224609375 +76164 0.100250244140625 +76165 0.186431884765625 +76166 0.1002197265625 +76167 0.188812255859375 +76168 0.07366943359375 +76169 0.1390380859375 +76170 0.023040771484375 +76171 0.041778564453125 +76172 -0.0396728515625 +76173 -0.079437255859375 +76174 -0.111785888671875 +76175 -0.219390869140625 +76176 -0.188018798828125 +76177 -0.367828369140625 +76178 -0.253265380859375 +76179 -0.494873046875 +76180 -0.28515625 +76181 -0.556243896484375 +76182 -0.2618408203125 +76183 -0.508697509765625 +76184 -0.195068359375 +76185 -0.3756103515625 +76186 -0.1160888671875 +76187 -0.218902587890625 +76188 -0.037567138671875 +76189 -0.063751220703125 +76190 0.041290283203125 +76191 0.091552734375 +76192 0.11492919921875 +76193 0.23602294921875 +76194 0.16986083984375 +76195 0.342987060546875 +76196 0.19732666015625 +76197 0.39520263671875 +76198 0.19561767578125 +76199 0.389373779296875 +76200 0.16400146484375 +76201 0.324249267578125 +76202 0.11468505859375 +76203 0.224090576171875 +76204 0.065399169921875 +76205 0.124267578125 +76206 0.022308349609375 +76207 0.037078857421875 +76208 -0.000823974609375 +76209 -0.010101318359375 +76210 -0.005126953125 +76211 -0.019439697265625 +76212 -0.006683349609375 +76213 -0.022796630859375 +76214 0.003875732421875 +76215 -0.001556396484375 +76216 0.032623291015625 +76217 0.056304931640625 +76218 0.057403564453125 +76219 0.106719970703125 +76220 0.0516357421875 +76221 0.096893310546875 +76222 0.02337646484375 +76223 0.042694091796875 +76224 -0.00823974609375 +76225 -0.018035888671875 +76226 -0.03839111328125 +76227 -0.07586669921875 +76228 -0.061309814453125 +76229 -0.11944580078125 +76230 -0.082489013671875 +76231 -0.15972900390625 +76232 -0.104827880859375 +76233 -0.202606201171875 +76234 -0.128509521484375 +76235 -0.24859619140625 +76236 -0.15728759765625 +76237 -0.30517578125 +76238 -0.18603515625 +76239 -0.36212158203125 +76240 -0.20068359375 +76241 -0.39141845703125 +76242 -0.18212890625 +76243 -0.35528564453125 +76244 -0.1285400390625 +76245 -0.249969482421875 +76246 -0.0487060546875 +76247 -0.092864990234375 +76248 0.043701171875 +76249 0.08905029296875 +76250 0.118133544921875 +76251 0.2352294921875 +76252 0.161041259765625 +76253 0.318817138671875 +76254 0.18182373046875 +76255 0.358642578125 +76256 0.176971435546875 +76257 0.347747802734375 +76258 0.14617919921875 +76259 0.28564453125 +76260 0.115081787109375 +76261 0.223175048828125 +76262 0.10198974609375 +76263 0.196746826171875 +76264 0.093536376953125 +76265 0.179840087890625 +76266 0.081207275390625 +76267 0.155548095703125 +76268 0.07879638671875 +76269 0.151214599609375 +76270 0.081329345703125 +76271 0.156951904296875 +76272 0.06817626953125 +76273 0.13177490234375 +76274 0.052001953125 +76275 0.100799560546875 +76276 0.04449462890625 +76277 0.087127685546875 +76278 0.027587890625 +76279 0.05487060546875 +76280 -0.005218505859375 +76281 -0.009002685546875 +76282 -0.053619384765625 +76283 -0.10400390625 +76284 -0.11724853515625 +76285 -0.229400634765625 +76286 -0.18115234375 +76287 -0.35552978515625 +76288 -0.225067138671875 +76289 -0.441925048828125 +76290 -0.241912841796875 +76291 -0.473846435546875 +76292 -0.238616943359375 +76293 -0.464813232421875 +76294 -0.21685791015625 +76295 -0.419097900390625 +76296 -0.174835205078125 +76297 -0.334320068359375 +76298 -0.121429443359375 +76299 -0.227935791015625 +76300 -0.06890869140625 +76301 -0.12347412109375 +76302 -0.02056884765625 +76303 -0.02764892578125 +76304 0.03350830078125 +76305 0.077667236328125 +76306 0.10455322265625 +76307 0.2132568359375 +76308 0.197845458984375 +76309 0.38885498046875 +76310 0.3017578125 +76311 0.582794189453125 +76312 0.383544921875 +76313 0.734039306640625 +76314 0.42034912109375 +76315 0.800140380859375 +76316 0.410552978515625 +76317 0.7783203125 +76318 0.3521728515625 +76319 0.6651611328125 +76320 0.244537353515625 +76321 0.45965576171875 +76322 0.107513427734375 +76323 0.199188232421875 +76324 -0.023895263671875 +76325 -0.050689697265625 +76326 -0.11932373046875 +76327 -0.23297119140625 +76328 -0.16949462890625 +76329 -0.33013916015625 +76330 -0.18853759765625 +76331 -0.368408203125 +76332 -0.1932373046875 +76333 -0.378936767578125 +76334 -0.19183349609375 +76335 -0.376983642578125 +76336 -0.193511962890625 +76337 -0.37969970703125 +76338 -0.200592041015625 +76339 -0.391510009765625 +76340 -0.198516845703125 +76341 -0.385345458984375 +76342 -0.1768798828125 +76343 -0.3419189453125 +76344 -0.147186279296875 +76345 -0.28289794921875 +76346 -0.132537841796875 +76347 -0.251617431640625 +76348 -0.14251708984375 +76349 -0.266143798828125 +76350 -0.14849853515625 +76351 -0.273345947265625 +76352 -0.1201171875 +76353 -0.216796875 +76354 -0.07427978515625 +76355 -0.128265380859375 +76356 -0.043304443359375 +76357 -0.068145751953125 +76358 -0.03070068359375 +76359 -0.0430908203125 +76360 -0.021087646484375 +76361 -0.024444580078125 +76362 0.003204345703125 +76363 0.020721435546875 +76364 0.059356689453125 +76365 0.124481201171875 +76366 0.13177490234375 +76367 0.25787353515625 +76368 0.197998046875 +76369 0.379119873046875 +76370 0.253509521484375 +76371 0.47991943359375 +76372 0.281036376953125 +76373 0.5281982421875 +76374 0.273590087890625 +76375 0.511138916015625 +76376 0.245819091796875 +76377 0.456207275390625 +76378 0.22125244140625 +76379 0.407470703125 +76380 0.20989990234375 +76381 0.383758544921875 +76382 0.196563720703125 +76383 0.35687255859375 +76384 0.17315673828125 +76385 0.31182861328125 +76386 0.140869140625 +76387 0.250885009765625 +76388 0.095062255859375 +76389 0.1654052734375 +76390 0.024993896484375 +76391 0.035247802734375 +76392 -0.070648193359375 +76393 -0.142059326171875 +76394 -0.175262451171875 +76395 -0.33563232421875 +76396 -0.282958984375 +76397 -0.5345458984375 +76398 -0.384552001953125 +76399 -0.72186279296875 +76400 -0.447357177734375 +76401 -0.836669921875 +76402 -0.44647216796875 +76403 -0.8326416015625 +76404 -0.392486572265625 +76405 -0.7296142578125 +76406 -0.31475830078125 +76407 -0.582550048828125 +76408 -0.23931884765625 +76409 -0.440093994140625 +76410 -0.177947998046875 +76411 -0.324310302734375 +76412 -0.112548828125 +76413 -0.20147705078125 +76414 -0.02862548828125 +76415 -0.044647216796875 +76416 0.0511474609375 +76417 0.103973388671875 +76418 0.104248046875 +76419 0.202392578125 +76420 0.138092041015625 +76421 0.264495849609375 +76422 0.1787109375 +76423 0.338897705078125 +76424 0.23583984375 +76425 0.443817138671875 +76426 0.29107666015625 +76427 0.545074462890625 +76428 0.330780029296875 +76429 0.6173095703125 +76430 0.3505859375 +76431 0.6524658203125 +76432 0.357330322265625 +76433 0.66339111328125 +76434 0.35418701171875 +76435 0.6561279296875 +76436 0.32830810546875 +76437 0.606781005859375 +76438 0.2720947265625 +76439 0.501190185546875 +76440 0.192718505859375 +76441 0.352783203125 +76442 0.09820556640625 +76443 0.176544189453125 +76444 -0.01531982421875 +76445 -0.034820556640625 +76446 -0.13543701171875 +76447 -0.258209228515625 +76448 -0.23468017578125 +76449 -0.44244384765625 +76450 -0.30645751953125 +76451 -0.5753173828125 +76452 -0.348236083984375 +76453 -0.65203857421875 +76454 -0.343353271484375 +76455 -0.641632080078125 +76456 -0.301483154296875 +76457 -0.562164306640625 +76458 -0.246368408203125 +76459 -0.458038330078125 +76460 -0.18939208984375 +76461 -0.350555419921875 +76462 -0.14166259765625 +76463 -0.260528564453125 +76464 -0.105377197265625 +76465 -0.192108154296875 +76466 -0.0787353515625 +76467 -0.141937255859375 +76468 -0.0574951171875 +76469 -0.1021728515625 +76470 -0.036346435546875 +76471 -0.062896728515625 +76472 -0.008758544921875 +76473 -0.011932373046875 +76474 0.031707763671875 +76475 0.062835693359375 +76476 0.0782470703125 +76477 0.148712158203125 +76478 0.128662109375 +76479 0.241729736328125 +76480 0.186798095703125 +76481 0.34912109375 +76482 0.245361328125 +76483 0.457305908203125 +76484 0.29229736328125 +76485 0.54388427734375 +76486 0.30828857421875 +76487 0.5728759765625 +76488 0.27313232421875 +76489 0.506591796875 +76490 0.19012451171875 +76491 0.351226806640625 +76492 0.08056640625 +76493 0.146514892578125 +76494 -0.027496337890625 +76495 -0.05523681640625 +76496 -0.113800048828125 +76497 -0.21624755859375 +76498 -0.177520751953125 +76499 -0.334930419921875 +76500 -0.214202880859375 +76501 -0.402984619140625 +76502 -0.235015869140625 +76503 -0.4412841796875 +76504 -0.26458740234375 +76505 -0.49578857421875 +76506 -0.299468994140625 +76507 -0.5601806640625 +76508 -0.32159423828125 +76509 -0.600738525390625 +76510 -0.3131103515625 +76511 -0.584228515625 +76512 -0.2572021484375 +76513 -0.47930908203125 +76514 -0.15032958984375 +76515 -0.27935791015625 +76516 -0.005615234375 +76517 -0.0089111328125 +76518 0.14300537109375 +76519 0.268798828125 +76520 0.257537841796875 +76521 0.482818603515625 +76522 0.322235107421875 +76523 0.60369873046875 +76524 0.347259521484375 +76525 0.650421142578125 +76526 0.354583740234375 +76527 0.66400146484375 +76528 0.3426513671875 +76529 0.6414794921875 +76530 0.305877685546875 +76531 0.572540283203125 +76532 0.266204833984375 +76533 0.498138427734375 +76534 0.2349853515625 +76535 0.439453125 +76536 0.20098876953125 +76537 0.375518798828125 +76538 0.147125244140625 +76539 0.274505615234375 +76540 0.058563232421875 +76541 0.1087646484375 +76542 -0.052734375 +76543 -0.099395751953125 +76544 -0.170257568359375 +76545 -0.3182373046875 +76546 -0.2955322265625 +76547 -0.5489501953125 +76548 -0.418792724609375 +76549 -0.7738037109375 +76550 -0.510162353515625 +76551 -0.86383056640625 +76552 -0.550872802734375 +76553 -0.870391845703125 +76554 -0.550933837890625 +76555 -0.86895751953125 +76556 -0.5177001953125 +76557 -0.861053466796875 +76558 -0.441192626953125 +76559 -0.765869140625 +76560 -0.314727783203125 +76561 -0.5301513671875 +76562 -0.14208984375 +76563 -0.214691162109375 +76564 0.052581787109375 +76565 0.137359619140625 +76566 0.240447998046875 +76567 0.474822998046875 +76568 0.40167236328125 +76569 0.76239013671875 +76570 0.521209716796875 +76571 0.867462158203125 +76572 0.59954833984375 +76573 0.870361328125 +76574 0.630340576171875 +76575 0.86480712890625 +76576 0.616790771484375 +76577 0.831817626953125 +76578 0.572845458984375 +76579 0.677581787109375 +76580 0.5018310546875 +76581 0.495880126953125 +76582 0.414215087890625 +76583 0.30767822265625 +76584 0.311126708984375 +76585 0.116180419921875 +76586 0.174407958984375 +76587 -0.110748291015625 +76588 -6.103515625e-05 +76589 -0.381805419921875 +76590 -0.188232421875 +76591 -0.6572265625 +76592 -0.3563232421875 +76593 -0.857421875 +76594 -0.480194091796875 +76595 -0.870391845703125 +76596 -0.5560302734375 +76597 -0.870391845703125 +76598 -0.599334716796875 +76599 -0.86444091796875 +76600 -0.63055419921875 +76601 -0.85723876953125 +76602 -0.639404296875 +76603 -0.790008544921875 +76604 -0.595184326171875 +76605 -0.62847900390625 +76606 -0.49609375 +76607 -0.3956298828125 +76608 -0.36077880859375 +76609 -0.126708984375 +76610 -0.2047119140625 +76611 0.150115966796875 +76612 -0.034393310546875 +76613 0.424041748046875 +76614 0.134979248046875 +76615 0.670623779296875 +76616 0.28155517578125 +76617 0.854522705078125 +76618 0.395477294921875 +76619 0.866485595703125 +76620 0.468231201171875 +76621 0.86920166015625 +76622 0.51031494140625 +76623 0.8653564453125 +76624 0.529510498046875 +76625 0.857147216796875 +76626 0.524322509765625 +76627 0.766845703125 +76628 0.497772216796875 +76629 0.628509521484375 +76630 0.44610595703125 +76631 0.462127685546875 +76632 0.384002685546875 +76633 0.297210693359375 +76634 0.318511962890625 +76635 0.14862060546875 +76636 0.23663330078125 +76637 -0.00537109375 +76638 0.142547607421875 +76639 -0.15753173828125 +76640 0.03411865234375 +76641 -0.31304931640625 +76642 -0.09674072265625 +76643 -0.48876953125 +76644 -0.2235107421875 +76645 -0.6416015625 +76646 -0.332305908203125 +76647 -0.751373291015625 +76648 -0.4364013671875 +76649 -0.84619140625 +76650 -0.527587890625 +76651 -0.861297607421875 +76652 -0.587158203125 +76653 -0.863250732421875 +76654 -0.5972900390625 +76655 -0.856597900390625 +76656 -0.564971923828125 +76657 -0.7498779296875 +76658 -0.523101806640625 +76659 -0.624542236328125 +76660 -0.459197998046875 +76661 -0.47808837890625 +76662 -0.340057373046875 +76663 -0.253387451171875 +76664 -0.1915283203125 +76665 0.003692626953125 +76666 -0.052398681640625 +76667 0.2257080078125 +76668 0.084503173828125 +76669 0.427154541015625 +76670 0.237701416015625 +76671 0.643218994140625 +76672 0.40179443359375 +76673 0.855926513671875 +76674 0.543975830078125 +76675 0.870361328125 +76676 0.63616943359375 +76677 0.870361328125 +76678 0.682525634765625 +76679 0.862762451171875 +76680 0.68145751953125 +76681 0.79669189453125 +76682 0.627685546875 +76683 0.595794677734375 +76684 0.537811279296875 +76685 0.362152099609375 +76686 0.42779541015625 +76687 0.1270751953125 +76688 0.3096923828125 +76689 -0.086944580078125 +76690 0.1846923828125 +76691 -0.2784423828125 +76692 0.032989501953125 +76693 -0.484832763671875 +76694 -0.15631103515625 +76695 -0.729583740234375 +76696 -0.3544921875 +76697 -0.86688232421875 +76698 -0.525634765625 +76699 -0.870391845703125 +76700 -0.666961669921875 +76701 -0.86859130859375 +76702 -0.77734375 +76703 -0.86279296875 +76704 -0.83636474609375 +76705 -0.817962646484375 +76706 -0.818267822265625 +76707 -0.6116943359375 +76708 -0.71905517578125 +76709 -0.3128662109375 +76710 -0.55792236328125 +76711 0.039398193359375 +76712 -0.3463134765625 +76713 0.422821044921875 +76714 -0.103179931640625 +76715 0.805145263671875 +76716 0.132720947265625 +76717 0.870361328125 +76718 0.328948974609375 +76719 0.870361328125 +76720 0.478759765625 +76721 0.860015869140625 +76722 0.577728271484375 +76723 0.727935791015625 +76724 0.62255859375 +76725 0.48114013671875 +76726 0.62689208984375 +76727 0.2059326171875 +76728 0.603485107421875 +76729 -0.06103515625 +76730 0.5579833984375 +76731 -0.29913330078125 +76732 0.482147216796875 +76733 -0.516204833984375 +76734 0.36724853515625 +76735 -0.7252197265625 +76736 0.2275390625 +76737 -0.85980224609375 +76738 0.0826416015625 +76739 -0.870391845703125 +76740 -0.0504150390625 +76741 -0.870391845703125 +76742 -0.14373779296875 +76743 -0.858062744140625 +76744 -0.19464111328125 +76745 -0.673004150390625 +76746 -0.232635498046875 +76747 -0.42694091796875 +76748 -0.28265380859375 +76749 -0.2100830078125 +76750 -0.343231201171875 +76751 -0.0362548828125 +76752 -0.3975830078125 +76753 0.10943603515625 +76754 -0.4342041015625 +76755 0.23516845703125 +76756 -0.42950439453125 +76757 0.373687744140625 +76758 -0.384490966796875 +76759 0.517791748046875 +76760 -0.3349609375 +76761 0.602783203125 +76762 -0.278076171875 +76763 0.635711669921875 +76764 -0.195068359375 +76765 0.655181884765625 +76766 -0.091796875 +76767 0.65948486328125 +76768 0.026885986328125 +76769 0.651275634765625 +76770 0.146728515625 +76771 0.61846923828125 +76772 0.246368408203125 +76773 0.53753662109375 +76774 0.31524658203125 +76775 0.404144287109375 +76776 0.3475341796875 +76777 0.22186279296875 +76778 0.3436279296875 +76779 0.003997802734375 +76780 0.3135986328125 +76781 -0.22100830078125 +76782 0.26904296875 +76783 -0.42449951171875 +76784 0.221954345703125 +76785 -0.579833984375 +76786 0.19659423828125 +76787 -0.641876220703125 +76788 0.18927001953125 +76789 -0.6177978515625 +76790 0.163421630859375 +76791 -0.575531005859375 +76792 0.116180419921875 +76793 -0.526336669921875 +76794 0.077239990234375 +76795 -0.42645263671875 +76796 0.062469482421875 +76797 -0.2581787109375 +76798 0.051513671875 +76799 -0.068695068359375 +76800 0.0233154296875 +76801 0.09222412109375 +76802 -0.010650634765625 +76803 0.232147216796875 +76804 -0.044830322265625 +76805 0.3509521484375 +76806 -0.097320556640625 +76807 0.410064697265625 +76808 -0.186004638671875 +76809 0.372955322265625 +76810 -0.29852294921875 +76811 0.2554931640625 +76812 -0.40374755859375 +76813 0.10711669921875 +76814 -0.49005126953125 +76815 -0.052886962890625 +76816 -0.535797119140625 +76817 -0.186279296875 +76818 -0.50750732421875 +76819 -0.23291015625 +76820 -0.41888427734375 +76821 -0.209442138671875 +76822 -0.309478759765625 +76823 -0.174163818359375 +76824 -0.18426513671875 +76825 -0.126739501953125 +76826 -0.037322998046875 +76827 -0.048126220703125 +76828 0.114410400390625 +76829 0.0426025390625 +76830 0.242950439453125 +76831 0.10748291015625 +76832 0.340301513671875 +76833 0.1409912109375 +76834 0.435028076171875 +76835 0.19708251953125 +76836 0.52301025390625 +76837 0.273651123046875 +76838 0.570709228515625 +76839 0.31768798828125 +76840 0.584716796875 +76841 0.341094970703125 +76842 0.580108642578125 +76843 0.368011474609375 +76844 0.543060302734375 +76845 0.37249755859375 +76846 0.4439697265625 +76847 0.30072021484375 +76848 0.285797119140625 +76849 0.1517333984375 +76850 0.108489990234375 +76851 -0.01470947265625 +76852 -0.077301025390625 +76853 -0.1883544921875 +76854 -0.269073486328125 +76855 -0.372711181640625 +76856 -0.43017578125 +76857 -0.51397705078125 +76858 -0.5323486328125 +76859 -0.57177734375 +76860 -0.56817626953125 +76861 -0.53948974609375 +76862 -0.54583740234375 +76863 -0.43511962890625 +76864 -0.486114501953125 +76865 -0.2962646484375 +76866 -0.411102294921875 +76867 -0.161102294921875 +76868 -0.329345703125 +76869 -0.0435791015625 +76870 -0.239501953125 +76871 0.060394287109375 +76872 -0.152008056640625 +76873 0.13665771484375 +76874 -0.078582763671875 +76875 0.170135498046875 +76876 -0.0196533203125 +76877 0.16552734375 +76878 0.041778564453125 +76879 0.15728759765625 +76880 0.105224609375 +76881 0.150787353515625 +76882 0.152557373046875 +76883 0.12200927734375 +76884 0.18585205078125 +76885 0.080108642578125 +76886 0.2177734375 +76887 0.05126953125 +76888 0.26239013671875 +76889 0.062896728515625 +76890 0.304595947265625 +76891 0.09271240234375 +76892 0.3148193359375 +76893 0.092987060546875 +76894 0.301788330078125 +76895 0.07855224609375 +76896 0.275115966796875 +76897 0.06427001953125 +76898 0.226959228515625 +76899 0.0347900390625 +76900 0.158203125 +76901 -0.01171875 +76902 0.0828857421875 +76903 -0.056060791015625 +76904 0.029541015625 +76905 -0.055511474609375 +76906 0.001007080078125 +76907 -0.010467529296875 +76908 -0.031982421875 +76909 0.02508544921875 +76910 -0.081787109375 +76911 0.025665283203125 +76912 -0.130157470703125 +76913 0.017333984375 +76914 -0.173858642578125 +76915 0.00189208984375 +76916 -0.217926025390625 +76917 -0.03173828125 +76918 -0.254150390625 +76919 -0.071502685546875 +76920 -0.292999267578125 +76921 -0.13543701171875 +76922 -0.3326416015625 +76923 -0.219970703125 +76924 -0.3592529296875 +76925 -0.300506591796875 +76926 -0.373870849609375 +76927 -0.376312255859375 +76928 -0.35968017578125 +76929 -0.416107177734375 +76930 -0.289703369140625 +76931 -0.371124267578125 +76932 -0.166961669921875 +76933 -0.242279052734375 +76934 -0.01812744140625 +76935 -0.069732666015625 +76936 0.141815185546875 +76937 0.125640869140625 +76938 0.291900634765625 +76939 0.31268310546875 +76940 0.40838623046875 +76941 0.45501708984375 +76942 0.491058349609375 +76943 0.554779052734375 +76944 0.538116455078125 +76945 0.61065673828125 +76946 0.54205322265625 +76947 0.610931396484375 +76948 0.48846435546875 +76949 0.531463623046875 +76950 0.387603759765625 +76951 0.3883056640625 +76952 0.2724609375 +76953 0.23468017578125 +76954 0.159332275390625 +76955 0.095245361328125 +76956 0.06561279296875 +76957 -0.00396728515625 +76958 0.001953125 +76959 -0.04852294921875 +76960 -0.039581298828125 +76961 -0.055145263671875 +76962 -0.08807373046875 +76963 -0.0758056640625 +76964 -0.1585693359375 +76965 -0.138702392578125 +76966 -0.228546142578125 +76967 -0.209197998046875 +76968 -0.297698974609375 +76969 -0.289031982421875 +76970 -0.365447998046875 +76971 -0.37884521484375 +76972 -0.417816162109375 +76973 -0.456329345703125 +76974 -0.45172119140625 +76975 -0.51641845703125 +76976 -0.443634033203125 +76977 -0.519287109375 +76978 -0.3902587890625 +76979 -0.458251953125 +76980 -0.3236083984375 +76981 -0.384796142578125 +76982 -0.25994873046875 +76983 -0.323699951171875 +76984 -0.19744873046875 +76985 -0.269287109375 +76986 -0.122039794921875 +76987 -0.1951904296875 +76988 -0.034576416015625 +76989 -0.100006103515625 +76990 0.04718017578125 +76991 -0.01055908203125 +76992 0.139892578125 +76993 0.1033935546875 +76994 0.2467041015625 +76995 0.24908447265625 +76996 0.334716796875 +76997 0.373199462890625 +76998 0.392730712890625 +76999 0.45806884765625 +77000 0.42523193359375 +77001 0.511474609375 +77002 0.451568603515625 +77003 0.565399169921875 +77004 0.467193603515625 +77005 0.61138916015625 +77006 0.437103271484375 +77007 0.5897216796875 +77008 0.35650634765625 +77009 0.4906005859375 +77010 0.237152099609375 +77011 0.33148193359375 +77012 0.10162353515625 +77013 0.147796630859375 +77014 -0.023590087890625 +77015 -0.01873779296875 +77016 -0.120391845703125 +77017 -0.140289306640625 +77018 -0.172607421875 +77019 -0.191986083984375 +77020 -0.1854248046875 +77021 -0.184295654296875 +77022 -0.184783935546875 +77023 -0.161834716796875 +77024 -0.1953125 +77025 -0.166595458984375 +77026 -0.21392822265625 +77027 -0.19390869140625 +77028 -0.22906494140625 +77029 -0.22442626953125 +77030 -0.253997802734375 +77031 -0.279754638671875 +77032 -0.27679443359375 +77033 -0.3389892578125 +77034 -0.2696533203125 +77035 -0.3543701171875 +77036 -0.246917724609375 +77037 -0.348175048828125 +77038 -0.213043212890625 +77039 -0.32598876953125 +77040 -0.15142822265625 +77041 -0.2581787109375 +77042 -0.06024169921875 +77043 -0.139801025390625 +77044 0.05072021484375 +77045 0.014617919921875 +77046 0.14404296875 +77047 0.144378662109375 +77048 0.201904296875 +77049 0.221038818359375 +77050 0.23944091796875 +77051 0.27069091796875 +77052 0.256805419921875 +77053 0.294036865234375 +77054 0.266326904296875 +77055 0.311767578125 +77056 0.2774658203125 +77057 0.339141845703125 +77058 0.281463623046875 +77059 0.360260009765625 +77060 0.270050048828125 +77061 0.360504150390625 +77062 0.223876953125 +77063 0.308380126953125 +77064 0.12957763671875 +77065 0.18170166015625 +77066 0.00323486328125 +77067 0.0047607421875 +77068 -0.12481689453125 +77069 -0.17559814453125 +77070 -0.225372314453125 +77071 -0.3143310546875 +77072 -0.270294189453125 +77073 -0.36785888671875 +77074 -0.275634765625 +77075 -0.36248779296875 +77076 -0.2696533203125 +77077 -0.343536376953125 +77078 -0.246337890625 +77079 -0.3018798828125 +77080 -0.201751708984375 +77081 -0.231414794921875 +77082 -0.12677001953125 +77083 -0.117645263671875 +77084 -0.042144775390625 +77085 0.007049560546875 +77086 0.01715087890625 +77087 0.087982177734375 +77088 0.0596923828125 +77089 0.13946533203125 +77090 0.09295654296875 +77091 0.17425537109375 +77092 0.1136474609375 +77093 0.188201904296875 +77094 0.11474609375 +77095 0.171234130859375 +77096 0.092498779296875 +77097 0.118438720703125 +77098 0.063568115234375 +77099 0.05706787109375 +77100 0.028778076171875 +77101 -0.010711669921875 +77102 -0.016326904296875 +77103 -0.0914306640625 +77104 -0.057647705078125 +77105 -0.162322998046875 +77106 -0.07708740234375 +77107 -0.194549560546875 +77108 -0.050079345703125 +77109 -0.1492919921875 +77110 0.026611328125 +77111 -0.02166748046875 +77112 0.112640380859375 +77113 0.124053955078125 +77114 0.159912109375 +77115 0.211151123046875 +77116 0.16943359375 +77117 0.240447998046875 +77118 0.160858154296875 +77119 0.242218017578125 +77120 0.140625 +77121 0.2257080078125 +77122 0.111419677734375 +77123 0.194366455078125 +77124 0.053070068359375 +77125 0.115509033203125 +77126 -0.01898193359375 +77127 0.0128173828125 +77128 -0.0665283203125 +77129 -0.053802490234375 +77130 -0.10589599609375 +77131 -0.110626220703125 +77132 -0.1634521484375 +77133 -0.199493408203125 +77134 -0.22271728515625 +77135 -0.29437255859375 +77136 -0.243927001953125 +77137 -0.33221435546875 +77138 -0.206298828125 +77139 -0.27972412109375 +77140 -0.140716552734375 +77141 -0.185333251953125 +77142 -0.097564697265625 +77143 -0.128204345703125 +77144 -0.081878662109375 +77145 -0.115692138671875 +77146 -0.074310302734375 +77147 -0.116455078125 +77148 -0.059783935546875 +77149 -0.105926513671875 +77150 -0.019683837890625 +77151 -0.053955078125 +77152 0.051513671875 +77153 0.048797607421875 +77154 0.125030517578125 +77155 0.157318115234375 +77156 0.162994384765625 +77157 0.212005615234375 +77158 0.168792724609375 +77159 0.218475341796875 +77160 0.1806640625 +77161 0.23724365234375 +77162 0.222076416015625 +77163 0.30535888671875 +77164 0.266876220703125 +77165 0.38128662109375 +77166 0.2769775390625 +77167 0.404449462890625 +77168 0.265045166015625 +77169 0.3944091796875 +77170 0.25506591796875 +77171 0.3885498046875 +77172 0.232086181640625 +77173 0.362640380859375 +77174 0.16925048828125 +77175 0.27362060546875 +77176 0.064178466796875 +77177 0.11712646484375 +77178 -0.04998779296875 +77179 -0.054901123046875 +77180 -0.14031982421875 +77181 -0.19085693359375 +77182 -0.20343017578125 +77183 -0.28570556640625 +77184 -0.239105224609375 +77185 -0.339263916015625 +77186 -0.26373291015625 +77187 -0.3775634765625 +77188 -0.30584716796875 +77189 -0.445709228515625 +77190 -0.360076904296875 +77191 -0.535064697265625 +77192 -0.416107177734375 +77193 -0.629058837890625 +77194 -0.455108642578125 +77195 -0.697601318359375 +77196 -0.454132080078125 +77197 -0.70391845703125 +77198 -0.409942626953125 +77199 -0.6424560546875 +77200 -0.3089599609375 +77201 -0.491241455078125 +77202 -0.161224365234375 +77203 -0.265716552734375 +77204 -0.003570556640625 +77205 -0.023712158203125 +77206 0.142852783203125 +77207 0.201751708984375 +77208 0.255828857421875 +77209 0.375823974609375 +77210 0.326751708984375 +77211 0.485076904296875 +77212 0.38043212890625 +77213 0.56884765625 +77214 0.42169189453125 +77215 0.634765625 +77216 0.4219970703125 +77217 0.63763427734375 +77218 0.374237060546875 +77219 0.5660400390625 +77220 0.311492919921875 +77221 0.4720458984375 +77222 0.266357421875 +77223 0.40692138671875 +77224 0.24359130859375 +77225 0.3778076171875 +77226 0.238555908203125 +77227 0.376953125 +77228 0.23101806640625 +77229 0.371978759765625 +77230 0.189788818359375 +77231 0.313140869140625 +77232 0.104949951171875 +77233 0.184417724609375 +77234 -0.00726318359375 +77235 0.011199951171875 +77236 -0.124298095703125 +77237 -0.171051025390625 +77238 -0.2303466796875 +77239 -0.33740234375 +77240 -0.315338134765625 +77241 -0.47198486328125 +77242 -0.370208740234375 +77243 -0.560394287109375 +77244 -0.381103515625 +77245 -0.58056640625 +77246 -0.357666015625 +77247 -0.54754638671875 +77248 -0.329925537109375 +77249 -0.508575439453125 +77250 -0.295440673828125 +77251 -0.459503173828125 +77252 -0.250640869140625 +77253 -0.394378662109375 +77254 -0.220611572265625 +77255 -0.35260009765625 +77256 -0.19134521484375 +77257 -0.31170654296875 +77258 -0.116058349609375 +77259 -0.197418212890625 +77260 0.00616455078125 +77261 -0.007965087890625 +77262 0.14410400390625 +77263 0.207489013671875 +77264 0.2725830078125 +77265 0.409210205078125 +77266 0.375701904296875 +77267 0.57208251953125 +77268 0.434417724609375 +77269 0.66595458984375 +77270 0.42852783203125 +77271 0.65875244140625 +77272 0.36883544921875 +77273 0.56744384765625 +77274 0.280364990234375 +77275 0.431396484375 +77276 0.190948486328125 +77277 0.29443359375 +77278 0.117156982421875 +77279 0.182464599609375 +77280 0.039031982421875 +77281 0.06365966796875 +77282 -0.052093505859375 +77283 -0.075958251953125 +77284 -0.126373291015625 +77285 -0.189422607421875 +77286 -0.180633544921875 +77287 -0.271942138671875 +77288 -0.226776123046875 +77289 -0.342529296875 +77290 -0.241363525390625 +77291 -0.364166259765625 +77292 -0.21832275390625 +77293 -0.327239990234375 +77294 -0.18621826171875 +77295 -0.2769775390625 +77296 -0.170562744140625 +77297 -0.253692626953125 +77298 -0.1627197265625 +77299 -0.24365234375 +77300 -0.132171630859375 +77301 -0.1983642578125 +77302 -0.078033447265625 +77303 -0.116241455078125 +77304 -0.025390625 +77305 -0.036834716796875 +77306 0.022430419921875 +77307 0.034881591796875 +77308 0.060455322265625 +77309 0.09124755859375 +77310 0.07379150390625 +77311 0.10888671875 +77312 0.086517333984375 +77313 0.125518798828125 +77314 0.109161376953125 +77315 0.15771484375 +77316 0.12396240234375 +77317 0.17828369140625 +77318 0.1199951171875 +77319 0.17108154296875 +77320 0.093109130859375 +77321 0.129974365234375 +77322 0.06146240234375 +77323 0.082427978515625 +77324 0.024566650390625 +77325 0.027679443359375 +77326 -0.03839111328125 +77327 -0.065643310546875 +77328 -0.101959228515625 +77329 -0.15936279296875 +77330 -0.13922119140625 +77331 -0.21307373046875 +77332 -0.155303955078125 +77333 -0.234649658203125 +77334 -0.13421630859375 +77335 -0.2001953125 +77336 -0.082122802734375 +77337 -0.119171142578125 +77338 -0.020965576171875 +77339 -0.024749755859375 +77340 0.0511474609375 +77341 0.085784912109375 +77342 0.11151123046875 +77343 0.178131103515625 +77344 0.135833740234375 +77345 0.215576171875 +77346 0.132965087890625 +77347 0.211456298828125 +77348 0.10919189453125 +77349 0.17523193359375 +77350 0.0789794921875 +77351 0.128753662109375 +77352 0.062164306640625 +77353 0.1019287109375 +77354 0.045135498046875 +77355 0.0743408203125 +77356 0.0260009765625 +77357 0.04327392578125 +77358 0.024200439453125 +77359 0.038177490234375 +77360 0.05108642578125 +77361 0.076263427734375 +77362 0.095611572265625 +77363 0.14105224609375 +77364 0.127105712890625 +77365 0.186431884765625 +77366 0.12982177734375 +77367 0.188812255859375 +77368 0.09765625 +77369 0.1390380859375 +77370 0.033660888671875 +77371 0.041778564453125 +77372 -0.04656982421875 +77373 -0.079437255859375 +77374 -0.13958740234375 +77375 -0.219390869140625 +77376 -0.238555908203125 +77377 -0.367828369140625 +77378 -0.3236083984375 +77379 -0.494873046875 +77380 -0.36529541015625 +77381 -0.556243896484375 +77382 -0.3348388671875 +77383 -0.508697509765625 +77384 -0.247711181640625 +77385 -0.3756103515625 +77386 -0.14495849609375 +77387 -0.218902587890625 +77388 -0.043212890625 +77389 -0.063751220703125 +77390 0.058685302734375 +77391 0.091552734375 +77392 0.153533935546875 +77393 0.23602294921875 +77394 0.223663330078125 +77395 0.342987060546875 +77396 0.2576904296875 +77397 0.39520263671875 +77398 0.25347900390625 +77399 0.389373779296875 +77400 0.210174560546875 +77401 0.324249267578125 +77402 0.143890380859375 +77403 0.224090576171875 +77404 0.078094482421875 +77405 0.124267578125 +77406 0.0208740234375 +77407 0.037078857421875 +77408 -0.00958251953125 +77409 -0.010101318359375 +77410 -0.014801025390625 +77411 -0.019439697265625 +77412 -0.01593017578125 +77413 -0.022796630859375 +77414 -0.000701904296875 +77415 -0.001556396484375 +77416 0.038787841796875 +77417 0.056304931640625 +77418 0.073211669921875 +77419 0.106719970703125 +77420 0.067474365234375 +77421 0.096893310546875 +77422 0.0321044921875 +77423 0.042694091796875 +77424 -0.0078125 +77425 -0.018035888671875 +77426 -0.046051025390625 +77427 -0.07586669921875 +77428 -0.075042724609375 +77429 -0.11944580078125 +77430 -0.102081298828125 +77431 -0.15972900390625 +77432 -0.13104248046875 +77433 -0.202606201171875 +77434 -0.162200927734375 +77435 -0.24859619140625 +77436 -0.20050048828125 +77437 -0.30517578125 +77438 -0.239105224609375 +77439 -0.36212158203125 +77440 -0.2593994140625 +77441 -0.39141845703125 +77442 -0.236236572265625 +77443 -0.35528564453125 +77444 -0.1671142578125 +77445 -0.249969482421875 +77446 -0.06353759765625 +77447 -0.092864990234375 +77448 0.056640625 +77449 0.08905029296875 +77450 0.15325927734375 +77451 0.2352294921875 +77452 0.20849609375 +77453 0.318817138671875 +77454 0.23486328125 +77455 0.358642578125 +77456 0.227752685546875 +77457 0.347747802734375 +77458 0.186798095703125 +77459 0.28564453125 +77460 0.145751953125 +77461 0.223175048828125 +77462 0.12872314453125 +77463 0.196746826171875 +77464 0.11810302734375 +77465 0.179840087890625 +77466 0.102630615234375 +77467 0.155548095703125 +77468 0.100433349609375 +77469 0.151214599609375 +77470 0.10491943359375 +77471 0.156951904296875 +77472 0.08880615234375 +77473 0.13177490234375 +77474 0.0687255859375 +77475 0.100799560546875 +77476 0.060028076171875 +77477 0.087127685546875 +77478 0.038848876953125 +77479 0.05487060546875 +77480 -0.003448486328125 +77481 -0.009002685546875 +77482 -0.0665283203125 +77483 -0.10400390625 +77484 -0.14990234375 +77485 -0.229400634765625 +77486 -0.23388671875 +77487 -0.35552978515625 +77488 -0.29156494140625 +77489 -0.441925048828125 +77490 -0.31317138671875 +77491 -0.473846435546875 +77492 -0.307647705078125 +77493 -0.464813232421875 +77494 -0.277801513671875 +77495 -0.419097900390625 +77496 -0.222015380859375 +77497 -0.334320068359375 +77498 -0.151824951171875 +77499 -0.227935791015625 +77500 -0.0828857421875 +77501 -0.12347412109375 +77502 -0.01959228515625 +77503 -0.02764892578125 +77504 0.050079345703125 +77505 0.077667236328125 +77506 0.13995361328125 +77507 0.2132568359375 +77508 0.256500244140625 +77509 0.38885498046875 +77510 0.38531494140625 +77511 0.582794189453125 +77512 0.485870361328125 +77513 0.734039306640625 +77514 0.529937744140625 +77515 0.800140380859375 +77516 0.51568603515625 +77517 0.7783203125 +77518 0.440826416015625 +77519 0.6651611328125 +77520 0.3046875 +77521 0.45965576171875 +77522 0.132080078125 +77523 0.199188232421875 +77524 -0.033477783203125 +77525 -0.050689697265625 +77526 -0.154144287109375 +77527 -0.23297119140625 +77528 -0.218353271484375 +77529 -0.33013916015625 +77530 -0.24346923828125 +77531 -0.368408203125 +77532 -0.250213623046875 +77533 -0.378936767578125 +77534 -0.248748779296875 +77535 -0.376983642578125 +77536 -0.250457763671875 +77537 -0.37969970703125 +77538 -0.258270263671875 +77539 -0.391510009765625 +77540 -0.254241943359375 +77541 -0.385345458984375 +77542 -0.225555419921875 +77543 -0.3419189453125 +77544 -0.18658447265625 +77545 -0.28289794921875 +77546 -0.166107177734375 +77547 -0.251617431640625 +77548 -0.176055908203125 +77549 -0.266143798828125 +77550 -0.18115234375 +77551 -0.273345947265625 +77552 -0.1439208984375 +77553 -0.216796875 +77554 -0.085418701171875 +77555 -0.128265380859375 +77556 -0.0457763671875 +77557 -0.068145751953125 +77558 -0.029327392578125 +77559 -0.0430908203125 +77560 -0.01708984375 +77561 -0.024444580078125 +77562 0.0128173828125 +77563 0.020721435546875 +77564 0.081695556640625 +77565 0.124481201171875 +77566 0.1702880859375 +77567 0.25787353515625 +77568 0.25140380859375 +77569 0.379119873046875 +77570 0.31939697265625 +77571 0.47991943359375 +77572 0.351531982421875 +77573 0.5281982421875 +77574 0.339080810546875 +77575 0.511138916015625 +77576 0.301239013671875 +77577 0.456207275390625 +77578 0.2686767578125 +77579 0.407470703125 +77580 0.25445556640625 +77581 0.383758544921875 +77582 0.23876953125 +77583 0.35687255859375 +77584 0.21099853515625 +77585 0.31182861328125 +77586 0.172454833984375 +77587 0.250885009765625 +77588 0.116912841796875 +77589 0.1654052734375 +77590 0.030120849609375 +77591 0.035247802734375 +77592 -0.08984375 +77593 -0.142059326171875 +77594 -0.2216796875 +77595 -0.33563232421875 +77596 -0.357940673828125 +77597 -0.5345458984375 +77598 -0.486907958984375 +77599 -0.72186279296875 +77600 -0.566253662109375 +77601 -0.836669921875 +77602 -0.56378173828125 +77603 -0.8326416015625 +77604 -0.4932861328125 +77605 -0.7296142578125 +77606 -0.39288330078125 +77607 -0.582550048828125 +77608 -0.29632568359375 +77609 -0.440093994140625 +77610 -0.21881103515625 +77611 -0.324310302734375 +77612 -0.13665771484375 +77613 -0.20147705078125 +77614 -0.030914306640625 +77615 -0.044647216796875 +77616 0.0692138671875 +77617 0.103973388671875 +77618 0.134674072265625 +77619 0.202392578125 +77620 0.17529296875 +77621 0.264495849609375 +77622 0.22503662109375 +77623 0.338897705078125 +77624 0.296661376953125 +77625 0.443817138671875 +77626 0.366424560546875 +77627 0.545074462890625 +77628 0.416717529296875 +77629 0.6173095703125 +77630 0.44189453125 +77631 0.6524658203125 +77632 0.450836181640625 +77633 0.66339111328125 +77634 0.447662353515625 +77635 0.6561279296875 +77636 0.415618896484375 +77637 0.606781005859375 +77638 0.3447265625 +77639 0.501190185546875 +77640 0.244171142578125 +77641 0.352783203125 +77642 0.124237060546875 +77643 0.176544189453125 +77644 -0.020294189453125 +77645 -0.034820556640625 +77646 -0.173431396484375 +77647 -0.258209228515625 +77648 -0.299713134765625 +77649 -0.44244384765625 +77650 -0.390716552734375 +77651 -0.5753173828125 +77652 -0.443206787109375 +77653 -0.65203857421875 +77654 -0.435638427734375 +77655 -0.641632080078125 +77656 -0.380615234375 +77657 -0.562164306640625 +77658 -0.30902099609375 +77659 -0.458038330078125 +77660 -0.235565185546875 +77661 -0.350555419921875 +77662 -0.1746826171875 +77663 -0.260528564453125 +77664 -0.129150390625 +77665 -0.192108154296875 +77666 -0.096527099609375 +77667 -0.141937255859375 +77668 -0.071197509765625 +77669 -0.1021728515625 +77670 -0.046142578125 +77671 -0.062896728515625 +77672 -0.012725830078125 +77673 -0.011932373046875 +77674 0.037567138671875 +77675 0.062835693359375 +77676 0.095977783203125 +77677 0.148712158203125 +77678 0.159820556640625 +77679 0.241729736328125 +77680 0.234130859375 +77681 0.34912109375 +77682 0.30950927734375 +77683 0.457305908203125 +77684 0.370330810546875 +77685 0.54388427734375 +77686 0.39154052734375 +77687 0.5728759765625 +77688 0.3468017578125 +77689 0.506591796875 +77690 0.240325927734375 +77691 0.351226806640625 +77692 0.099700927734375 +77693 0.146514892578125 +77694 -0.038787841796875 +77695 -0.05523681640625 +77696 -0.14892578125 +77697 -0.21624755859375 +77698 -0.229705810546875 +77699 -0.334930419921875 +77700 -0.275482177734375 +77701 -0.402984619140625 +77702 -0.300872802734375 +77703 -0.4412841796875 +77704 -0.337921142578125 +77705 -0.49578857421875 +77706 -0.382232666015625 +77707 -0.5601806640625 +77708 -0.410400390625 +77709 -0.600738525390625 +77710 -0.3992919921875 +77711 -0.584228515625 +77712 -0.3270263671875 +77713 -0.47930908203125 +77714 -0.18896484375 +77715 -0.27935791015625 +77716 -0.0020751953125 +77717 -0.0089111328125 +77718 0.189666748046875 +77719 0.268798828125 +77720 0.337005615234375 +77721 0.482818603515625 +77722 0.419525146484375 +77723 0.60369873046875 +77724 0.45050048828125 +77725 0.650421142578125 +77726 0.458587646484375 +77727 0.66400146484375 +77728 0.4417724609375 +77729 0.6414794921875 +77730 0.3929443359375 +77731 0.572540283203125 +77732 0.34063720703125 +77733 0.498138427734375 +77734 0.29962158203125 +77735 0.439453125 +77736 0.255279541015625 +77737 0.375518798828125 +77738 0.185455322265625 +77739 0.274505615234375 +77740 0.070892333984375 +77741 0.1087646484375 +77742 -0.072967529296875 +77743 -0.099395751953125 +77744 -0.22406005859375 +77745 -0.3182373046875 +77746 -0.38330078125 +77747 -0.5489501953125 +77748 -0.538421630859375 +77749 -0.7738037109375 +77750 -0.65264892578125 +77751 -0.86383056640625 +77752 -0.702911376953125 +77753 -0.870391845703125 +77754 -0.70159912109375 +77755 -0.86895751953125 +77756 -0.65789794921875 +77757 -0.861053466796875 +77758 -0.559783935546875 +77759 -0.765869140625 +77760 -0.399444580078125 +77761 -0.5301513671875 +77762 -0.18182373046875 +77763 -0.214691162109375 +77764 0.063079833984375 +77765 0.137359619140625 +77766 0.299591064453125 +77767 0.474822998046875 +77768 0.503021240234375 +77769 0.76239013671875 +77770 0.654632568359375 +77771 0.867462158203125 +77772 0.7547607421875 +77773 0.870361328125 +77774 0.79541015625 +77775 0.86480712890625 +77776 0.7803955078125 +77777 0.831817626953125 +77778 0.726715087890625 +77779 0.677581787109375 +77780 0.638458251953125 +77781 0.495880126953125 +77782 0.528594970703125 +77783 0.30767822265625 +77784 0.398681640625 +77785 0.116180419921875 +77786 0.2266845703125 +77787 -0.110748291015625 +77788 0.007781982421875 +77789 -0.381805419921875 +77790 -0.228179931640625 +77791 -0.6572265625 +77792 -0.43951416015625 +77793 -0.857421875 +77794 -0.59637451171875 +77795 -0.870391845703125 +77796 -0.693817138671875 +77797 -0.870391845703125 +77798 -0.750579833984375 +77799 -0.86444091796875 +77800 -0.79156494140625 +77801 -0.85723876953125 +77802 -0.804046630859375 +77803 -0.790008544921875 +77804 -0.75030517578125 +77805 -0.62847900390625 +77806 -0.628173828125 +77807 -0.3956298828125 +77808 -0.460540771484375 +77809 -0.126708984375 +77810 -0.26654052734375 +77811 0.150115966796875 +77812 -0.0543212890625 +77813 0.424041748046875 +77814 0.15728759765625 +77815 0.670623779296875 +77816 0.34130859375 +77817 0.854522705078125 +77818 0.48541259765625 +77819 0.866485595703125 +77820 0.578887939453125 +77821 0.86920166015625 +77822 0.634368896484375 +77823 0.8653564453125 +77824 0.66094970703125 +77825 0.857147216796875 +77826 0.656890869140625 +77827 0.766845703125 +77828 0.6260986328125 +77829 0.628509521484375 +77830 0.563629150390625 +77831 0.462127685546875 +77832 0.4881591796875 +77833 0.297210693359375 +77834 0.408477783203125 +77835 0.14862060546875 +77836 0.307708740234375 +77837 -0.00537109375 +77838 0.19097900390625 +77839 -0.15753173828125 +77840 0.055328369140625 +77841 -0.31304931640625 +77842 -0.109771728515625 +77843 -0.48876953125 +77844 -0.2705078125 +77845 -0.6416015625 +77846 -0.409149169921875 +77847 -0.751373291015625 +77848 -0.542724609375 +77849 -0.84619140625 +77850 -0.66064453125 +77851 -0.861297607421875 +77852 -0.738861083984375 +77853 -0.863250732421875 +77854 -0.754425048828125 +77855 -0.856597900390625 +77856 -0.71612548828125 +77857 -0.7498779296875 +77858 -0.665924072265625 +77859 -0.624542236328125 +77860 -0.587646484375 +77861 -0.47808837890625 +77862 -0.438507080078125 +77863 -0.253387451171875 +77864 -0.251495361328125 +77865 0.003692626953125 +77866 -0.07611083984375 +77867 0.2257080078125 +77868 0.09698486328125 +77869 0.427154541015625 +77870 0.2916259765625 +77871 0.643218994140625 +77872 0.501007080078125 +77873 0.855926513671875 +77874 0.68310546875 +77875 0.870361328125 +77876 0.8018798828125 +77877 0.870361328125 +77878 0.855377197265625 +77879 0.862762451171875 +77880 0.855438232421875 +77881 0.79669189453125 +77882 0.7967529296875 +77883 0.595794677734375 +77884 0.684356689453125 +77885 0.362152099609375 +77886 0.54632568359375 +77887 0.1270751953125 +77888 0.397918701171875 +77889 -0.086944580078125 +77890 0.240509033203125 +77891 -0.2784423828125 +77892 0.048614501953125 +77893 -0.484832763671875 +77894 -0.191925048828125 +77895 -0.729583740234375 +77896 -0.44439697265625 +77897 -0.86688232421875 +77898 -0.662811279296875 +77899 -0.870391845703125 +77900 -0.843658447265625 +77901 -0.86859130859375 +77902 -0.868804931640625 +77903 -0.86279296875 +77904 -0.870391845703125 +77905 -0.817962646484375 +77906 -0.86181640625 +77907 -0.6116943359375 +77908 -0.7474365234375 +77909 -0.3128662109375 +77910 -0.504974365234375 +77911 0.039398193359375 +77912 -0.210296630859375 +77913 0.422821044921875 +77914 0.111358642578125 +77915 0.805145263671875 +77916 0.410186767578125 +77917 0.870361328125 +77918 0.64520263671875 +77919 0.870361328125 +77920 0.809051513671875 +77921 0.860015869140625 +77922 0.859222412109375 +77923 0.727935791015625 +77924 0.860504150390625 +77925 0.48114013671875 +77926 0.855621337890625 +77927 0.2059326171875 +77928 0.78277587890625 +77929 -0.06103515625 +77930 0.673187255859375 +77931 -0.29913330078125 +77932 0.528472900390625 +77933 -0.516204833984375 +77934 0.3399658203125 +77935 -0.7252197265625 +77936 0.1279296875 +77937 -0.85980224609375 +77938 -0.080841064453125 +77939 -0.870391845703125 +77940 -0.26361083984375 +77941 -0.870391845703125 +77942 -0.384246826171875 +77943 -0.858062744140625 +77944 -0.439605712890625 +77945 -0.673004150390625 +77946 -0.4683837890625 +77947 -0.42694091796875 +77948 -0.503875732421875 +77949 -0.2100830078125 +77950 -0.545989990234375 +77951 -0.0362548828125 +77952 -0.575408935546875 +77953 0.10943603515625 +77954 -0.579742431640625 +77955 0.23516845703125 +77956 -0.53106689453125 +77957 0.373687744140625 +77958 -0.43304443359375 +77959 0.517791748046875 +77960 -0.33367919921875 +77961 0.602783203125 +77962 -0.23114013671875 +77963 0.635711669921875 +77964 -0.102813720703125 +77965 0.655181884765625 +77966 0.04278564453125 +77967 0.65948486328125 +77968 0.199005126953125 +77969 0.651275634765625 +77970 0.347625732421875 +77971 0.61846923828125 +77972 0.46185302734375 +77973 0.53753662109375 +77974 0.529083251953125 +77975 0.404144287109375 +77976 0.543182373046875 +77977 0.22186279296875 +77978 0.50634765625 +77979 0.003997802734375 +77980 0.433349609375 +77981 -0.22100830078125 +77982 0.34100341796875 +77983 -0.42449951171875 +77984 0.246673583984375 +77985 -0.579833984375 +77986 0.1832275390625 +77987 -0.641876220703125 +77988 0.14752197265625 +77989 -0.6177978515625 +77990 0.093994140625 +77991 -0.575531005859375 +77992 0.01995849609375 +77993 -0.526336669921875 +77994 -0.0360107421875 +77995 -0.42645263671875 +77996 -0.053436279296875 +77997 -0.2581787109375 +77998 -0.0587158203125 +77999 -0.068695068359375 +78000 -0.08013916015625 +78001 0.09222412109375 +78002 -0.10479736328125 +78003 0.232147216796875 +78004 -0.126251220703125 +78005 0.3509521484375 +78006 -0.167205810546875 +78007 0.410064697265625 +78008 -0.2503662109375 +78009 0.372955322265625 +78010 -0.3619384765625 +78011 0.2554931640625 +78012 -0.46539306640625 +78013 0.10711669921875 +78014 -0.547821044921875 +78015 -0.052886962890625 +78016 -0.58404541015625 +78017 -0.186279296875 +78018 -0.534423828125 +78019 -0.23291015625 +78020 -0.416290283203125 +78021 -0.209442138671875 +78022 -0.278076171875 +78023 -0.174163818359375 +78024 -0.126007080078125 +78025 -0.126739501953125 +78026 0.04718017578125 +78027 -0.048126220703125 +78028 0.22137451171875 +78029 0.0426025390625 +78030 0.36328125 +78031 0.10748291015625 +78032 0.464080810546875 +78033 0.1409912109375 +78034 0.559417724609375 +78035 0.19708251953125 +78036 0.645416259765625 +78037 0.273651123046875 +78038 0.68255615234375 +78039 0.31768798828125 +78040 0.679931640625 +78041 0.341094970703125 +78042 0.65692138671875 +78043 0.368011474609375 +78044 0.59759521484375 +78045 0.37249755859375 +78046 0.466766357421875 +78047 0.30072021484375 +78048 0.268463134765625 +78049 0.1517333984375 +78050 0.051361083984375 +78051 -0.01470947265625 +78052 -0.171600341796875 +78053 -0.1883544921875 +78054 -0.397705078125 +78055 -0.372711181640625 +78056 -0.582916259765625 +78057 -0.51397705078125 +78058 -0.693603515625 +78059 -0.57177734375 +78060 -0.72161865234375 +78061 -0.53948974609375 +78062 -0.677764892578125 +78063 -0.43511962890625 +78064 -0.588165283203125 +78065 -0.2962646484375 +78066 -0.480621337890625 +78067 -0.161102294921875 +78068 -0.366363525390625 +78069 -0.0435791015625 +78070 -0.244537353515625 +78071 0.060394287109375 +78072 -0.12847900390625 +78073 0.13665771484375 +78074 -0.0328369140625 +78075 0.170135498046875 +78076 0.041595458984375 +78077 0.16552734375 +78078 0.115447998046875 +78079 0.15728759765625 +78080 0.18804931640625 +78081 0.150787353515625 +78082 0.23773193359375 +78083 0.12200927734375 +78084 0.26776123046875 +78085 0.080108642578125 +78086 0.294586181640625 +78087 0.05126953125 +78088 0.336395263671875 +78089 0.062896728515625 +78090 0.375030517578125 +78091 0.09271240234375 +78092 0.374298095703125 +78093 0.092987060546875 +78094 0.3458251953125 +78095 0.07855224609375 +78096 0.302215576171875 +78097 0.06427001953125 +78098 0.23419189453125 +78099 0.0347900390625 +78100 0.14324951171875 +78101 -0.01171875 +78102 0.04718017578125 +78103 -0.056060791015625 +78104 -0.018341064453125 +78105 -0.055511474609375 +78106 -0.049896240234375 +78107 -0.010467529296875 +78108 -0.08441162109375 +78109 0.02508544921875 +78110 -0.13775634765625 +78111 0.025665283203125 +78112 -0.187652587890625 +78113 0.017333984375 +78114 -0.23065185546875 +78115 0.00189208984375 +78116 -0.27374267578125 +78117 -0.03173828125 +78118 -0.30731201171875 +78119 -0.071502685546875 +78120 -0.345062255859375 +78121 -0.13543701171875 +78122 -0.385284423828125 +78123 -0.219970703125 +78124 -0.411163330078125 +78125 -0.300506591796875 +78126 -0.42431640625 +78127 -0.376312255859375 +78128 -0.4039306640625 +78129 -0.416107177734375 +78130 -0.316375732421875 +78131 -0.371124267578125 +78132 -0.165374755859375 +78133 -0.242279052734375 +78134 0.01593017578125 +78135 -0.069732666015625 +78136 0.209136962890625 +78137 0.125640869140625 +78138 0.38848876953125 +78139 0.31268310546875 +78140 0.5247802734375 +78141 0.45501708984375 +78142 0.6182861328125 +78143 0.554779052734375 +78144 0.667327880859375 +78145 0.61065673828125 +78146 0.663055419921875 +78147 0.610931396484375 +78148 0.587982177734375 +78149 0.531463623046875 +78150 0.45526123046875 +78151 0.3883056640625 +78152 0.30645751953125 +78153 0.23468017578125 +78154 0.16217041015625 +78155 0.095245361328125 +78156 0.04425048828125 +78157 -0.00396728515625 +78158 -0.03399658203125 +78159 -0.04852294921875 +78160 -0.082611083984375 +78161 -0.055145263671875 +78162 -0.138275146484375 +78163 -0.0758056640625 +78164 -0.220001220703125 +78165 -0.138702392578125 +78166 -0.30010986328125 +78167 -0.209197998046875 +78168 -0.378631591796875 +78169 -0.289031982421875 +78170 -0.455291748046875 +78171 -0.37884521484375 +78172 -0.513092041015625 +78173 -0.456329345703125 +78174 -0.54852294921875 +78175 -0.51641845703125 +78176 -0.532501220703125 +78177 -0.519287109375 +78178 -0.46124267578125 +78179 -0.458251953125 +78180 -0.375 +78181 -0.384796142578125 +78182 -0.294189453125 +78183 -0.323699951171875 +78184 -0.216583251953125 +78185 -0.269287109375 +78186 -0.124481201171875 +78187 -0.1951904296875 +78188 -0.018768310546875 +78189 -0.100006103515625 +78190 0.078582763671875 +78191 -0.01055908203125 +78192 0.188690185546875 +78193 0.1033935546875 +78194 0.315826416015625 +78195 0.24908447265625 +78196 0.419219970703125 +78197 0.373199462890625 +78198 0.48529052734375 +78199 0.45806884765625 +78200 0.51995849609375 +78201 0.511474609375 +78202 0.547760009765625 +78203 0.565399169921875 +78204 0.563232421875 +78205 0.61138916015625 +78206 0.522796630859375 +78207 0.5897216796875 +78208 0.420562744140625 +78209 0.4906005859375 +78210 0.27130126953125 +78211 0.33148193359375 +78212 0.10321044921875 +78213 0.147796630859375 +78214 -0.05072021484375 +78215 -0.01873779296875 +78216 -0.1680908203125 +78217 -0.140289306640625 +78218 -0.2288818359375 +78219 -0.191986083984375 +78220 -0.2398681640625 +78221 -0.184295654296875 +78222 -0.2337646484375 +78223 -0.161834716796875 +78224 -0.241607666015625 +78225 -0.166595458984375 +78226 -0.2598876953125 +78227 -0.19390869140625 +78228 -0.274383544921875 +78229 -0.22442626953125 +78230 -0.301910400390625 +78231 -0.279754638671875 +78232 -0.327728271484375 +78233 -0.3389892578125 +78234 -0.31719970703125 +78235 -0.3543701171875 +78236 -0.288330078125 +78237 -0.348175048828125 +78238 -0.24664306640625 +78239 -0.32598876953125 +78240 -0.171356201171875 +78241 -0.2581787109375 +78242 -0.06005859375 +78243 -0.139801025390625 +78244 0.0751953125 +78245 0.014617919921875 +78246 0.1878662109375 +78247 0.144378662109375 +78248 0.255950927734375 +78249 0.221038818359375 +78250 0.298553466796875 +78251 0.27069091796875 +78252 0.316070556640625 +78253 0.294036865234375 +78254 0.324188232421875 +78255 0.311767578125 +78256 0.334808349609375 +78257 0.339141845703125 +78258 0.3367919921875 +78259 0.360260009765625 +78260 0.320037841796875 +78261 0.360504150390625 +78262 0.26153564453125 +78263 0.308380126953125 +78264 0.145477294921875 +78265 0.18170166015625 +78266 -0.008544921875 +78267 0.0047607421875 +78268 -0.163909912109375 +78269 -0.17559814453125 +78270 -0.28546142578125 +78271 -0.3143310546875 +78272 -0.3392333984375 +78273 -0.36785888671875 +78274 -0.3446044921875 +78275 -0.36248779296875 +78276 -0.33563232421875 +78277 -0.343536376953125 +78278 -0.305206298828125 +78279 -0.3018798828125 +78280 -0.24871826171875 +78281 -0.231414794921875 +78282 -0.155426025390625 +78283 -0.117645263671875 +78284 -0.0504150390625 +78285 0.007049560546875 +78286 0.024078369140625 +78287 0.087982177734375 +78288 0.078155517578125 +78289 0.13946533203125 +78290 0.12066650390625 +78291 0.17425537109375 +78292 0.14752197265625 +78293 0.188201904296875 +78294 0.150146484375 +78295 0.171234130859375 +78296 0.1240234375 +78297 0.118438720703125 +78298 0.089141845703125 +78299 0.05706787109375 +78300 0.0465087890625 +78301 -0.010711669921875 +78302 -0.00921630859375 +78303 -0.0914306640625 +78304 -0.0609130859375 +78305 -0.162322998046875 +78306 -0.086669921875 +78307 -0.194549560546875 +78308 -0.056854248046875 +78309 -0.1492919921875 +78310 0.032562255859375 +78311 -0.02166748046875 +78312 0.13330078125 +78313 0.124053955078125 +78314 0.1876220703125 +78315 0.211151123046875 +78316 0.1968994140625 +78317 0.240447998046875 +78318 0.184814453125 +78319 0.242218017578125 +78320 0.159210205078125 +78321 0.2257080078125 +78322 0.123382568359375 +78323 0.194366455078125 +78324 0.0531005859375 +78325 0.115509033203125 +78326 -0.033050537109375 +78327 0.0128173828125 +78328 -0.089202880859375 +78329 -0.053802490234375 +78330 -0.135101318359375 +78331 -0.110626220703125 +78332 -0.2025146484375 +78333 -0.199493408203125 +78334 -0.271728515625 +78335 -0.29437255859375 +78336 -0.294677734375 +78337 -0.33221435546875 +78338 -0.2457275390625 +78339 -0.27972412109375 +78340 -0.163177490234375 +78341 -0.185333251953125 +78342 -0.10986328125 +78343 -0.128204345703125 +78344 -0.091827392578125 +78345 -0.115692138671875 +78346 -0.084564208984375 +78347 -0.116455078125 +78348 -0.068939208984375 +78349 -0.105926513671875 +78350 -0.021392822265625 +78351 -0.053955078125 +78352 0.065185546875 +78353 0.048797607421875 +78354 0.1549072265625 +78355 0.157318115234375 +78356 0.20037841796875 +78357 0.212005615234375 +78358 0.205963134765625 +78359 0.218475341796875 +78360 0.2196044921875 +78361 0.23724365234375 +78362 0.270721435546875 +78363 0.30535888671875 +78364 0.32659912109375 +78365 0.38128662109375 +78366 0.3394775390625 +78367 0.404449462890625 +78368 0.3251953125 +78369 0.3944091796875 +78370 0.313720703125 +78371 0.3885498046875 +78372 0.286285400390625 +78373 0.362640380859375 +78374 0.2091064453125 +78375 0.27362060546875 +78376 0.079071044921875 +78377 0.11712646484375 +78378 -0.062347412109375 +78379 -0.054901123046875 +78380 -0.17401123046875 +78381 -0.19085693359375 +78382 -0.251739501953125 +78383 -0.28570556640625 +78384 -0.295318603515625 +78385 -0.339263916015625 +78386 -0.3253173828125 +78387 -0.3775634765625 +78388 -0.377532958984375 +78389 -0.445709228515625 +78390 -0.44525146484375 +78391 -0.535064697265625 +78392 -0.51556396484375 +78393 -0.629058837890625 +78394 -0.56488037109375 +78395 -0.697601318359375 +78396 -0.564361572265625 +78397 -0.70391845703125 +78398 -0.50994873046875 +78399 -0.6424560546875 +78400 -0.384552001953125 +78401 -0.491241455078125 +78402 -0.20068359375 +78403 -0.265716552734375 +78404 -0.004425048828125 +78405 -0.023712158203125 +78406 0.17779541015625 +78407 0.201751708984375 +78408 0.318206787109375 +78409 0.375823974609375 +78410 0.406097412109375 +78411 0.485076904296875 +78412 0.472564697265625 +78413 0.56884765625 +78414 0.523712158203125 +78415 0.634765625 +78416 0.5238037109375 +78417 0.63763427734375 +78418 0.46392822265625 +78419 0.5660400390625 +78420 0.385528564453125 +78421 0.4720458984375 +78422 0.3294677734375 +78423 0.40692138671875 +78424 0.301666259765625 +78425 0.3778076171875 +78426 0.2962646484375 +78427 0.376953125 +78428 0.287872314453125 +78429 0.371978759765625 +78430 0.237335205078125 +78431 0.313140869140625 +78432 0.132110595703125 +78433 0.184417724609375 +78434 -0.007476806640625 +78435 0.011199951171875 +78436 -0.153228759765625 +78437 -0.171051025390625 +78438 -0.285369873046875 +78439 -0.33740234375 +78440 -0.391326904296875 +78441 -0.47198486328125 +78442 -0.459808349609375 +78443 -0.560394287109375 +78444 -0.473419189453125 +78445 -0.58056640625 +78446 -0.4442138671875 +78447 -0.54754638671875 +78448 -0.409820556640625 +78449 -0.508575439453125 +78450 -0.36712646484375 +78451 -0.459503173828125 +78452 -0.311676025390625 +78453 -0.394378662109375 +78454 -0.27484130859375 +78455 -0.35260009765625 +78456 -0.239044189453125 +78457 -0.31170654296875 +78458 -0.1456298828125 +78459 -0.197418212890625 +78460 0.00665283203125 +78461 -0.007965087890625 +78462 0.17877197265625 +78463 0.207489013671875 +78464 0.33917236328125 +78465 0.409210205078125 +78466 0.46795654296875 +78467 0.57208251953125 +78468 0.541290283203125 +78469 0.66595458984375 +78470 0.533843994140625 +78471 0.65875244140625 +78472 0.45916748046875 +78473 0.56744384765625 +78474 0.34857177734375 +78475 0.431396484375 +78476 0.236968994140625 +78477 0.29443359375 +78478 0.145050048828125 +78479 0.182464599609375 +78480 0.04779052734375 +78481 0.06365966796875 +78482 -0.065704345703125 +78483 -0.075958251953125 +78484 -0.1580810546875 +78485 -0.189422607421875 +78486 -0.225433349609375 +78487 -0.271942138671875 +78488 -0.28271484375 +78489 -0.342529296875 +78490 -0.300567626953125 +78491 -0.364166259765625 +78492 -0.2713623046875 +78493 -0.327239990234375 +78494 -0.230926513671875 +78495 -0.2769775390625 +78496 -0.21124267578125 +78497 -0.253692626953125 +78498 -0.201507568359375 +78499 -0.24365234375 +78500 -0.1634521484375 +78501 -0.1983642578125 +78502 -0.095916748046875 +78503 -0.116241455078125 +78504 -0.030364990234375 +78505 -0.036834716796875 +78506 0.029083251953125 +78507 0.034881591796875 +78508 0.076202392578125 +78509 0.09124755859375 +78510 0.092376708984375 +78511 0.10888671875 +78512 0.10736083984375 +78513 0.125518798828125 +78514 0.134185791015625 +78515 0.15771484375 +78516 0.1512451171875 +78517 0.17828369140625 +78518 0.145721435546875 +78519 0.17108154296875 +78520 0.11279296875 +78521 0.129974365234375 +78522 0.07421875 +78523 0.082427978515625 +78524 0.029510498046875 +78525 0.027679443359375 +78526 -0.046112060546875 +78527 -0.065643310546875 +78528 -0.122283935546875 +78529 -0.15936279296875 +78530 -0.166900634765625 +78531 -0.21307373046875 +78532 -0.18609619140625 +78533 -0.234649658203125 +78534 -0.16082763671875 +78535 -0.2001953125 +78536 -0.0985107421875 +78537 -0.119171142578125 +78538 -0.02532958984375 +78539 -0.024749755859375 +78540 0.06097412109375 +78541 0.085784912109375 +78542 0.13330078125 +78543 0.178131103515625 +78544 0.16259765625 +78545 0.215576171875 +78546 0.159393310546875 +78547 0.211456298828125 +78548 0.131195068359375 +78549 0.17523193359375 +78550 0.095306396484375 +78551 0.128753662109375 +78552 0.075347900390625 +78553 0.1019287109375 +78554 0.0550537109375 +78555 0.0743408203125 +78556 0.03216552734375 +78557 0.04327392578125 +78558 0.0299072265625 +78559 0.038177490234375 +78560 0.06182861328125 +78561 0.076263427734375 +78562 0.114776611328125 +78563 0.14105224609375 +78564 0.152130126953125 +78565 0.186431884765625 +78566 0.1551513671875 +78567 0.188812255859375 +78568 0.11651611328125 +78569 0.1390380859375 +78570 0.0399169921875 +78571 0.041778564453125 +78572 -0.0560302734375 +78573 -0.079437255859375 +78574 -0.167205810546875 +78575 -0.219390869140625 +78576 -0.285430908203125 +78577 -0.367828369140625 +78578 -0.38702392578125 +78579 -0.494873046875 +78580 -0.43682861328125 +78581 -0.556243896484375 +78582 -0.400543212890625 +78583 -0.508697509765625 +78584 -0.296600341796875 +78585 -0.3756103515625 +78586 -0.1739501953125 +78587 -0.218902587890625 +78588 -0.05242919921875 +78589 -0.063751220703125 +78590 0.0693359375 +78591 0.091552734375 +78592 0.182769775390625 +78593 0.23602294921875 +78594 0.26678466796875 +78595 0.342987060546875 +78596 0.3074951171875 +78597 0.39520263671875 +78598 0.302001953125 +78599 0.389373779296875 +78600 0.249053955078125 +78601 0.324249267578125 +78602 0.168365478515625 +78603 0.224090576171875 +78604 0.0888671875 +78605 0.124267578125 +78606 0.0203857421875 +78607 0.037078857421875 +78608 -0.014739990234375 +78609 -0.010101318359375 +78610 -0.0185546875 +78611 -0.019439697265625 +78612 -0.01751708984375 +78613 -0.022796630859375 +78614 0.00347900390625 +78615 -0.001556396484375 +78616 0.054168701171875 +78617 0.056304931640625 +78618 0.09814453125 +78619 0.106719970703125 +78620 0.091796875 +78621 0.096893310546875 +78622 0.04815673828125 +78623 0.042694091796875 +78624 -0.001617431640625 +78625 -0.018035888671875 +78626 -0.04974365234375 +78627 -0.07586669921875 +78628 -0.0867919921875 +78629 -0.11944580078125 +78630 -0.12176513671875 +78631 -0.15972900390625 +78632 -0.15936279296875 +78633 -0.202606201171875 +78634 -0.199859619140625 +78635 -0.24859619140625 +78636 -0.249237060546875 +78637 -0.30517578125 +78638 -0.2989501953125 +78639 -0.36212158203125 +78640 -0.3258056640625 +78641 -0.39141845703125 +78642 -0.2984619140625 +78643 -0.35528564453125 +78644 -0.213714599609375 +78645 -0.249969482421875 +78646 -0.0858154296875 +78647 -0.092864990234375 +78648 0.063079833984375 +78649 0.08905029296875 +78650 0.18310546875 +78651 0.2352294921875 +78652 0.25213623046875 +78653 0.318817138671875 +78654 0.28564453125 +78655 0.358642578125 +78656 0.27789306640625 +78657 0.347747802734375 +78658 0.2283935546875 +78659 0.28564453125 +78660 0.178924560546875 +78661 0.223175048828125 +78662 0.15936279296875 +78663 0.196746826171875 +78664 0.147735595703125 +78665 0.179840087890625 +78666 0.1300048828125 +78667 0.155548095703125 +78668 0.1285400390625 +78669 0.151214599609375 +78670 0.135101318359375 +78671 0.156951904296875 +78672 0.115814208984375 +78673 0.13177490234375 +78674 0.09130859375 +78675 0.100799560546875 +78676 0.08056640625 +78677 0.087127685546875 +78678 0.05401611328125 +78679 0.05487060546875 +78680 0.00091552734375 +78681 -0.009002685546875 +78682 -0.0782470703125 +78683 -0.10400390625 +78684 -0.182830810546875 +78685 -0.229400634765625 +78686 -0.288330078125 +78687 -0.35552978515625 +78688 -0.36126708984375 +78689 -0.441925048828125 +78690 -0.389434814453125 +78691 -0.473846435546875 +78692 -0.38385009765625 +78693 -0.464813232421875 +78694 -0.347900390625 +78695 -0.419097900390625 +78696 -0.279571533203125 +78697 -0.334320068359375 +78698 -0.193145751953125 +78699 -0.227935791015625 +78700 -0.10797119140625 +78701 -0.12347412109375 +78702 -0.029510498046875 +78703 -0.02764892578125 +78704 0.05718994140625 +78705 0.077667236328125 +78706 0.169189453125 +78707 0.2132568359375 +78708 0.314483642578125 +78709 0.38885498046875 +78710 0.475189208984375 +78711 0.582794189453125 +78712 0.6009521484375 +78713 0.734039306640625 +78714 0.65673828125 +78715 0.800140380859375 +78716 0.640167236328125 +78717 0.7783203125 +78718 0.548370361328125 +78719 0.6651611328125 +78720 0.38043212890625 +78721 0.45965576171875 +78722 0.167083740234375 +78723 0.199188232421875 +78724 -0.0377197265625 +78725 -0.050689697265625 +78726 -0.18707275390625 +78727 -0.23297119140625 +78728 -0.2666015625 +78729 -0.33013916015625 +78730 -0.297882080078125 +78731 -0.368408203125 +78732 -0.306610107421875 +78733 -0.378936767578125 +78734 -0.30535888671875 +78735 -0.376983642578125 +78736 -0.3082275390625 +78737 -0.37969970703125 +78738 -0.318817138671875 +78739 -0.391510009765625 +78740 -0.314788818359375 +78741 -0.385345458984375 +78742 -0.280181884765625 +78743 -0.3419189453125 +78744 -0.2327880859375 +78745 -0.28289794921875 +78746 -0.208221435546875 +78747 -0.251617431640625 +78748 -0.2213134765625 +78749 -0.266143798828125 +78750 -0.228240966796875 +78751 -0.273345947265625 +78752 -0.182464599609375 +78753 -0.216796875 +78754 -0.110076904296875 +78755 -0.128265380859375 +78756 -0.06085205078125 +78757 -0.068145751953125 +78758 -0.04022216796875 +78759 -0.0430908203125 +78760 -0.02459716796875 +78761 -0.024444580078125 +78762 0.01312255859375 +78763 0.020721435546875 +78764 0.099334716796875 +78765 0.124481201171875 +78766 0.210113525390625 +78767 0.25787353515625 +78768 0.31097412109375 +78769 0.379119873046875 +78770 0.395050048828125 +78771 0.47991943359375 +78772 0.43585205078125 +78773 0.5281982421875 +78774 0.422760009765625 +78775 0.511138916015625 +78776 0.37835693359375 +78777 0.456207275390625 +78778 0.338897705078125 +78779 0.407470703125 +78780 0.319854736328125 +78781 0.383758544921875 +78782 0.2979736328125 +78783 0.35687255859375 +78784 0.26092529296875 +78785 0.31182861328125 +78786 0.210540771484375 +78787 0.250885009765625 +78788 0.139739990234375 +78789 0.1654052734375 +78790 0.031951904296875 +78791 0.035247802734375 +78792 -0.114837646484375 +78793 -0.142059326171875 +78794 -0.275115966796875 +78795 -0.33563232421875 +78796 -0.4398193359375 +78797 -0.5345458984375 +78798 -0.594940185546875 +78799 -0.72186279296875 +78800 -0.690277099609375 +78801 -0.836669921875 +78802 -0.687652587890625 +78803 -0.8326416015625 +78804 -0.603363037109375 +78805 -0.7296142578125 +78806 -0.482635498046875 +78807 -0.582550048828125 +78808 -0.36553955078125 +78809 -0.440093994140625 +78810 -0.270263671875 +78811 -0.324310302734375 +78812 -0.16900634765625 +78813 -0.20147705078125 +78814 -0.03955078125 +78815 -0.044647216796875 +78816 0.083282470703125 +78817 0.103973388671875 +78818 0.164886474609375 +78819 0.202392578125 +78820 0.216644287109375 +78821 0.264495849609375 +78822 0.278594970703125 +78823 0.338897705078125 +78824 0.365692138671875 +78825 0.443817138671875 +78826 0.44976806640625 +78827 0.545074462890625 +78828 0.509857177734375 +78829 0.6173095703125 +78830 0.539337158203125 +78831 0.6524658203125 +78832 0.548736572265625 +78833 0.66339111328125 +78834 0.54302978515625 +78835 0.6561279296875 +78836 0.50250244140625 +78837 0.606781005859375 +78838 0.41546630859375 +78839 0.501190185546875 +78840 0.292999267578125 +78841 0.352783203125 +78842 0.1474609375 +78843 0.176544189453125 +78844 -0.027130126953125 +78845 -0.034820556640625 +78846 -0.211700439453125 +78847 -0.258209228515625 +78848 -0.3638916015625 +78849 -0.44244384765625 +78850 -0.47369384765625 +78851 -0.5753173828125 +78852 -0.53704833984375 +78853 -0.65203857421875 +78854 -0.527374267578125 +78855 -0.641632080078125 +78856 -0.459991455078125 +78857 -0.562164306640625 +78858 -0.37274169921875 +78859 -0.458038330078125 +78860 -0.28363037109375 +78861 -0.350555419921875 +78862 -0.21026611328125 +78863 -0.260528564453125 +78864 -0.15594482421875 +78865 -0.192108154296875 +78866 -0.117523193359375 +78867 -0.141937255859375 +78868 -0.088043212890625 +78869 -0.1021728515625 +78870 -0.058746337890625 +78871 -0.062896728515625 +78872 -0.018951416015625 +78873 -0.011932373046875 +78874 0.041839599609375 +78875 0.062835693359375 +78876 0.1129150390625 +78877 0.148712158203125 +78878 0.19097900390625 +78879 0.241729736328125 +78880 0.28228759765625 +78881 0.34912109375 +78882 0.375213623046875 +78883 0.457305908203125 +78884 0.450531005859375 +78885 0.54388427734375 +78886 0.47735595703125 +78887 0.5728759765625 +78888 0.42327880859375 +78889 0.506591796875 +78890 0.29345703125 +78891 0.351226806640625 +78892 0.121673583984375 +78893 0.146514892578125 +78894 -0.047454833984375 +78895 -0.05523681640625 +78896 -0.181793212890625 +78897 -0.21624755859375 +78898 -0.280181884765625 +78899 -0.334930419921875 +78900 -0.335662841796875 +78901 -0.402984619140625 +78902 -0.366241455078125 +78903 -0.4412841796875 +78904 -0.411407470703125 +78905 -0.49578857421875 +78906 -0.465789794921875 +78907 -0.5601806640625 +78908 -0.50054931640625 +78909 -0.600738525390625 +78910 -0.487213134765625 +78911 -0.584228515625 +78912 -0.398834228515625 +78913 -0.47930908203125 +78914 -0.229705810546875 +78915 -0.27935791015625 +78916 -0.00067138671875 +78917 -0.0089111328125 +78918 0.2342529296875 +78919 0.268798828125 +78920 0.41455078125 +78921 0.482818603515625 +78922 0.515167236328125 +78923 0.60369873046875 +78924 0.552459716796875 +78925 0.650421142578125 +78926 0.561676025390625 +78927 0.66400146484375 +78928 0.5404052734375 +78929 0.6414794921875 +78930 0.479949951171875 +78931 0.572540283203125 +78932 0.4154052734375 +78933 0.498138427734375 +78934 0.36492919921875 +78935 0.439453125 +78936 0.310577392578125 +78937 0.375518798828125 +78938 0.225067138671875 +78939 0.274505615234375 +78940 0.08465576171875 +78941 0.1087646484375 +78942 -0.0916748046875 +78943 -0.099395751953125 +78944 -0.27679443359375 +78945 -0.3182373046875 +78946 -0.471923828125 +78947 -0.5489501953125 +78948 -0.6619873046875 +78949 -0.7738037109375 +78950 -0.801788330078125 +78951 -0.86383056640625 +78952 -0.855438232421875 +78953 -0.870391845703125 +78954 -0.855194091796875 +78955 -0.86895751953125 +78956 -0.80670166015625 +78957 -0.861053466796875 +78958 -0.685821533203125 +78959 -0.765869140625 +78960 -0.48858642578125 +78961 -0.5301513671875 +78962 -0.2210693359375 +78963 -0.214691162109375 +78964 0.07989501953125 +78965 0.137359619140625 +78966 0.37042236328125 +78967 0.474822998046875 +78968 0.620147705078125 +78969 0.76239013671875 +78970 0.806060791015625 +78971 0.867462158203125 +78972 0.862579345703125 +78973 0.870361328125 +78974 0.867950439453125 +78975 0.86480712890625 +78976 0.865875244140625 +78977 0.831817626953125 +78978 0.858642578125 +78979 0.677581787109375 +78980 0.783599853515625 +78981 0.495880126953125 +78982 0.648193359375 +78983 0.30767822265625 +78984 0.488250732421875 +78985 0.116180419921875 +78986 0.27667236328125 +78987 -0.110748291015625 +78988 0.007568359375 +78989 -0.381805419921875 +78990 -0.28240966796875 +78991 -0.6572265625 +78992 -0.54205322265625 +78993 -0.857421875 +78994 -0.734649658203125 +78995 -0.870391845703125 +78996 -0.854095458984375 +78997 -0.870391845703125 +78998 -0.862030029296875 +78999 -0.86444091796875 +79000 -0.86749267578125 +79001 -0.85723876953125 +79002 -0.869140625 +79003 -0.790008544921875 +79004 -0.86187744140625 +79005 -0.62847900390625 +79006 -0.771575927734375 +79007 -0.3956298828125 +79008 -0.565185546875 +79009 -0.126708984375 +79010 -0.326446533203125 +79011 0.150115966796875 +79012 -0.065399169921875 +79013 0.424041748046875 +79014 0.19482421875 +79015 0.670623779296875 +79016 0.421051025390625 +79017 0.854522705078125 +79018 0.59814453125 +79019 0.866485595703125 +79020 0.712890625 +79021 0.86920166015625 +79022 0.7808837890625 +79023 0.8653564453125 +79024 0.813629150390625 +79025 0.857147216796875 +79026 0.80865478515625 +79027 0.766845703125 +79028 0.7703857421875 +79029 0.628509521484375 +79030 0.693084716796875 +79031 0.462127685546875 +79032 0.59893798828125 +79033 0.297210693359375 +79034 0.498626708984375 +79035 0.14862060546875 +79036 0.372650146484375 +79037 -0.00537109375 +79038 0.22747802734375 +79039 -0.15753173828125 +79040 0.060089111328125 +79041 -0.31304931640625 +79042 -0.1414794921875 +79043 -0.48876953125 +79044 -0.337066650390625 +79045 -0.6416015625 +79046 -0.505462646484375 +79047 -0.751373291015625 +79048 -0.66644287109375 +79049 -0.84619140625 +79050 -0.807373046875 +79051 -0.861297607421875 +79052 -0.859466552734375 +79053 -0.863250732421875 +79054 -0.861328125 +79055 -0.856597900390625 +79056 -0.85614013671875 +79057 -0.7498779296875 +79058 -0.80621337890625 +79059 -0.624542236328125 +79060 -0.70892333984375 +79061 -0.47808837890625 +79062 -0.527496337890625 +79063 -0.253387451171875 +79064 -0.301055908203125 +79065 0.003692626953125 +79066 -0.08819580078125 +79067 0.2257080078125 +79068 0.12176513671875 +79069 0.427154541015625 +79070 0.356475830078125 +79071 0.643218994140625 +79072 0.60760498046875 +79073 0.855926513671875 +79074 0.82550048828125 +79075 0.870361328125 +79076 0.8668212890625 +79077 0.870361328125 +79078 0.870361328125 +79079 0.862762451171875 +79080 0.866363525390625 +79081 0.79669189453125 +79082 0.852020263671875 +79083 0.595794677734375 +79084 0.692138671875 +79085 0.362152099609375 +79086 0.509063720703125 +79087 0.1270751953125 +79088 0.3216552734375 +79089 -0.086944580078125 +79090 0.131988525390625 +79091 -0.2784423828125 +79092 -0.089874267578125 +79093 -0.484832763671875 +79094 -0.36102294921875 +79095 -0.729583740234375 +79096 -0.639129638671875 +79097 -0.86688232421875 +79098 -0.856353759765625 +79099 -0.870391845703125 +79100 -0.870391845703125 +79101 -0.86859130859375 +79102 -0.870391845703125 +79103 -0.86279296875 +79104 -0.863494873046875 +79105 -0.817962646484375 +79106 -0.77923583984375 +79107 -0.6116943359375 +79108 -0.52740478515625 +79109 -0.3128662109375 +79110 -0.21514892578125 +79111 0.039398193359375 +79112 0.1378173828125 +79113 0.422821044921875 +79114 0.5020751953125 +79115 0.805145263671875 +79116 0.81927490234375 +79117 0.870361328125 +79118 0.870361328125 +79119 0.870361328125 +79120 0.870361328125 +79121 0.860015869140625 +79122 0.860931396484375 +79123 0.727935791015625 +79124 0.74932861328125 +79125 0.48114013671875 +79126 0.540802001953125 +79127 0.2059326171875 +79128 0.319244384765625 +79129 -0.06103515625 +79130 0.10260009765625 +79131 -0.29913330078125 +79132 -0.115203857421875 +79133 -0.516204833984375 +79134 -0.343719482421875 +79135 -0.7252197265625 +79136 -0.55950927734375 +79137 -0.85980224609375 +79138 -0.7335205078125 +79139 -0.870391845703125 +79140 -0.843505859375 +79141 -0.870391845703125 +79142 -0.852508544921875 +79143 -0.858062744140625 +79144 -0.764923095703125 +79145 -0.673004150390625 +79146 -0.636871337890625 +79147 -0.42694091796875 +79148 -0.51812744140625 +79149 -0.2100830078125 +79150 -0.41741943359375 +79151 -0.0362548828125 +79152 -0.31915283203125 +79153 0.10943603515625 +79154 -0.214996337890625 +79155 0.23516845703125 +79156 -0.076141357421875 +79157 0.373687744140625 +79158 0.08941650390625 +79159 0.517791748046875 +79160 0.221588134765625 +79161 0.602783203125 +79162 0.323028564453125 +79163 0.635711669921875 +79164 0.423614501953125 +79165 0.655181884765625 +79166 0.516937255859375 +79167 0.65948486328125 +79168 0.600311279296875 +79169 0.651275634765625 +79170 0.657989501953125 +79171 0.61846923828125 +79172 0.66448974609375 +79173 0.53753662109375 +79174 0.6119384765625 +79175 0.404144287109375 +79176 0.500274658203125 +79177 0.22186279296875 +79178 0.33905029296875 +79179 0.003997802734375 +79180 0.152252197265625 +79181 -0.22100830078125 +79182 -0.034820556640625 +79183 -0.42449951171875 +79184 -0.19757080078125 +79185 -0.579833984375 +79186 -0.2940673828125 +79187 -0.641876220703125 +79188 -0.327911376953125 +79189 -0.6177978515625 +79190 -0.356048583984375 +79191 -0.575531005859375 +79192 -0.38458251953125 +79193 -0.526336669921875 +79194 -0.370574951171875 +79195 -0.42645263671875 +79196 -0.29412841796875 +79197 -0.2581787109375 +79198 -0.193206787109375 +79199 -0.068695068359375 +79200 -0.108489990234375 +79201 0.09222412109375 +79202 -0.030364990234375 +79203 0.232147216796875 +79204 0.043243408203125 +79205 0.3509521484375 +79206 0.079376220703125 +79207 0.410064697265625 +79208 0.046051025390625 +79209 0.372955322265625 +79210 -0.04302978515625 +79211 0.2554931640625 +79212 -0.145263671875 +79213 0.10711669921875 +79214 -0.245574951171875 +79215 -0.052886962890625 +79216 -0.312591552734375 +79217 -0.186279296875 +79218 -0.2960205078125 +79219 -0.23291015625 +79220 -0.214019775390625 +79221 -0.209442138671875 +79222 -0.12176513671875 +79223 -0.174163818359375 +79224 -0.022247314453125 +79225 -0.126739501953125 +79226 0.098358154296875 +79227 -0.048126220703125 +79228 0.2205810546875 +79229 0.0426025390625 +79230 0.308685302734375 +79231 0.10748291015625 +79232 0.3564453125 +79233 0.1409912109375 +79234 0.4111328125 +79235 0.19708251953125 +79236 0.47100830078125 +79237 0.273651123046875 +79238 0.48980712890625 +79239 0.31768798828125 +79240 0.479522705078125 +79241 0.341094970703125 +79242 0.463623046875 +79243 0.368011474609375 +79244 0.421478271484375 +79245 0.37249755859375 +79246 0.3079833984375 +79247 0.30072021484375 +79248 0.125091552734375 +79249 0.1517333984375 +79250 -0.071319580078125 +79251 -0.01470947265625 +79252 -0.26953125 +79253 -0.1883544921875 +79254 -0.47039794921875 +79255 -0.372711181640625 +79256 -0.62432861328125 +79257 -0.51397705078125 +79258 -0.69415283203125 +79259 -0.57177734375 +79260 -0.67327880859375 +79261 -0.53948974609375 +79262 -0.577606201171875 +79263 -0.43511962890625 +79264 -0.44097900390625 +79265 -0.2962646484375 +79266 -0.298309326171875 +79267 -0.161102294921875 +79268 -0.1634521484375 +79269 -0.0435791015625 +79270 -0.034698486328125 +79271 0.060394287109375 +79272 0.07318115234375 +79273 0.13665771484375 +79274 0.144561767578125 +79275 0.170135498046875 +79276 0.181304931640625 +79277 0.16552734375 +79278 0.211761474609375 +79279 0.15728759765625 +79280 0.23876953125 +79281 0.150787353515625 +79282 0.239349365234375 +79283 0.12200927734375 +79284 0.220367431640625 +79285 0.080108642578125 +79286 0.204345703125 +79287 0.05126953125 +79288 0.21533203125 +79289 0.062896728515625 +79290 0.2337646484375 +79291 0.09271240234375 +79292 0.21795654296875 +79293 0.092987060546875 +79294 0.182159423828125 +79295 0.07855224609375 +79296 0.14105224609375 +79297 0.06427001953125 +79298 0.082672119140625 +79299 0.0347900390625 +79300 0.007232666015625 +79301 -0.01171875 +79302 -0.066253662109375 +79303 -0.056060791015625 +79304 -0.097991943359375 +79305 -0.055511474609375 +79306 -0.08660888671875 +79307 -0.010467529296875 +79308 -0.078582763671875 +79309 0.02508544921875 +79310 -0.095367431640625 +79311 0.025665283203125 +79312 -0.11309814453125 +79313 0.017333984375 +79314 -0.12982177734375 +79315 0.00189208984375 +79316 -0.155426025390625 +79317 -0.03173828125 +79318 -0.1796875 +79319 -0.071502685546875 +79320 -0.219390869140625 +79321 -0.13543701171875 +79322 -0.272491455078125 +79323 -0.219970703125 +79324 -0.3184814453125 +79325 -0.300506591796875 +79326 -0.358184814453125 +79327 -0.376312255859375 +79328 -0.3653564453125 +79329 -0.416107177734375 +79330 -0.29827880859375 +79331 -0.371124267578125 +79332 -0.159210205078125 +79333 -0.242279052734375 +79334 0.014892578125 +79335 -0.069732666015625 +79336 0.2044677734375 +79337 0.125640869140625 +79338 0.381103515625 +79339 0.31268310546875 +79340 0.512115478515625 +79341 0.45501708984375 +79342 0.599273681640625 +79343 0.554779052734375 +79344 0.6417236328125 +79345 0.61065673828125 +79346 0.62957763671875 +79347 0.610931396484375 +79348 0.542266845703125 +79349 0.531463623046875 +79350 0.395050048828125 +79351 0.3883056640625 +79352 0.23638916015625 +79353 0.23468017578125 +79354 0.089447021484375 +79355 0.095245361328125 +79356 -0.0213623046875 +79357 -0.00396728515625 +79358 -0.08203125 +79359 -0.04852294921875 +79360 -0.1060791015625 +79361 -0.055145263671875 +79362 -0.138885498046875 +79363 -0.0758056640625 +79364 -0.205078125 +79365 -0.138702392578125 +79366 -0.273162841796875 +79367 -0.209197998046875 +79368 -0.3447265625 +79369 -0.289031982421875 +79370 -0.420562744140625 +79371 -0.37884521484375 +79372 -0.48101806640625 +79373 -0.456329345703125 +79374 -0.52227783203125 +79375 -0.51641845703125 +79376 -0.509307861328125 +79377 -0.519287109375 +79378 -0.43701171875 +79379 -0.458251953125 +79380 -0.35272216796875 +79381 -0.384796142578125 +79382 -0.27978515625 +79383 -0.323699951171875 +79384 -0.21405029296875 +79385 -0.269287109375 +79386 -0.132659912109375 +79387 -0.1951904296875 +79388 -0.035064697265625 +79389 -0.100006103515625 +79390 0.053985595703125 +79391 -0.01055908203125 +79392 0.16131591796875 +79393 0.1033935546875 +79394 0.2933349609375 +79395 0.24908447265625 +79396 0.402130126953125 +79397 0.373199462890625 +79398 0.472076416015625 +79399 0.45806884765625 +79400 0.5106201171875 +79401 0.511474609375 +79402 0.54718017578125 +79403 0.565399169921875 +79404 0.57489013671875 +79405 0.61138916015625 +79406 0.540740966796875 +79407 0.5897216796875 +79408 0.436737060546875 +79409 0.4906005859375 +79410 0.279449462890625 +79411 0.33148193359375 +79412 0.10150146484375 +79413 0.147796630859375 +79414 -0.058929443359375 +79415 -0.01873779296875 +79416 -0.176300048828125 +79417 -0.140289306640625 +79418 -0.227813720703125 +79419 -0.191986083984375 +79420 -0.222747802734375 +79421 -0.184295654296875 +79422 -0.20123291015625 +79423 -0.161834716796875 +79424 -0.20123291015625 +79425 -0.166595458984375 +79426 -0.2188720703125 +79427 -0.19390869140625 +79428 -0.237152099609375 +79429 -0.22442626953125 +79430 -0.276092529296875 +79431 -0.279754638671875 +79432 -0.317535400390625 +79433 -0.3389892578125 +79434 -0.319183349609375 +79435 -0.3543701171875 +79436 -0.3017578125 +79437 -0.348175048828125 +79438 -0.270904541015625 +79439 -0.32598876953125 +79440 -0.2005615234375 +79441 -0.2581787109375 +79442 -0.08673095703125 +79443 -0.139801025390625 +79444 0.057220458984375 +79445 0.014617919921875 +79446 0.176422119140625 +79447 0.144378662109375 +79448 0.245269775390625 +79449 0.221038818359375 +79450 0.28729248046875 +79451 0.27069091796875 +79452 0.3033447265625 +79453 0.294036865234375 +79454 0.312408447265625 +79455 0.311767578125 +79456 0.32867431640625 +79457 0.339141845703125 +79458 0.338592529296875 +79459 0.360260009765625 +79460 0.3294677734375 +79461 0.360504150390625 +79462 0.272705078125 +79463 0.308380126953125 +79464 0.1483154296875 +79465 0.18170166015625 +79466 -0.020965576171875 +79467 0.0047607421875 +79468 -0.1917724609375 +79469 -0.17559814453125 +79470 -0.322509765625 +79471 -0.3143310546875 +79472 -0.372955322265625 +79473 -0.36785888671875 +79474 -0.367340087890625 +79475 -0.36248779296875 +79476 -0.347442626953125 +79477 -0.343536376953125 +79478 -0.3050537109375 +79479 -0.3018798828125 +79480 -0.234832763671875 +79481 -0.231414794921875 +79482 -0.123748779296875 +79483 -0.117645263671875 +79484 -0.001922607421875 +79485 0.007049560546875 +79486 0.079864501953125 +79487 0.087982177734375 +79488 0.134429931640625 +79489 0.13946533203125 +79490 0.173095703125 +79491 0.17425537109375 +79492 0.191680908203125 +79493 0.188201904296875 +79494 0.180633544921875 +79495 0.171234130859375 +79496 0.135223388671875 +79497 0.118438720703125 +79498 0.08038330078125 +79499 0.05706787109375 +79500 0.01806640625 +79501 -0.010711669921875 +79502 -0.05767822265625 +79503 -0.0914306640625 +79504 -0.125762939453125 +79505 -0.162322998046875 +79506 -0.15948486328125 +79507 -0.194549560546875 +79508 -0.122894287109375 +79509 -0.1492919921875 +79510 -0.01116943359375 +79511 -0.02166748046875 +79512 0.116912841796875 +79513 0.124053955078125 +79514 0.19110107421875 +79515 0.211151123046875 +79516 0.21246337890625 +79517 0.240447998046875 +79518 0.2091064453125 +79519 0.242218017578125 +79520 0.189849853515625 +79521 0.2257080078125 +79522 0.158050537109375 +79523 0.194366455078125 +79524 0.083740234375 +79525 0.115509033203125 +79526 -0.011199951171875 +79527 0.0128173828125 +79528 -0.071685791015625 +79529 -0.053802490234375 +79530 -0.1219482421875 +79531 -0.110626220703125 +79532 -0.200653076171875 +79533 -0.199493408203125 +79534 -0.284027099609375 +79535 -0.29437255859375 +79536 -0.314300537109375 +79537 -0.33221435546875 +79538 -0.261138916015625 +79539 -0.27972412109375 +79540 -0.16937255859375 +79541 -0.185333251953125 +79542 -0.112091064453125 +79543 -0.128204345703125 +79544 -0.09625244140625 +79545 -0.115692138671875 +79546 -0.093292236328125 +79547 -0.116455078125 +79548 -0.080780029296875 +79549 -0.105926513671875 +79550 -0.031158447265625 +79551 -0.053955078125 +79552 0.064117431640625 +79553 0.048797607421875 +79554 0.16363525390625 +79555 0.157318115234375 +79556 0.212615966796875 +79557 0.212005615234375 +79558 0.21630859375 +79559 0.218475341796875 +79560 0.23052978515625 +79561 0.23724365234375 +79562 0.289581298828125 +79563 0.30535888671875 +79564 0.35540771484375 +79565 0.38128662109375 +79566 0.372528076171875 +79567 0.404449462890625 +79568 0.35919189453125 +79569 0.3944091796875 +79570 0.35003662109375 +79571 0.3885498046875 +79572 0.322967529296875 +79573 0.362640380859375 +79574 0.238525390625 +79575 0.27362060546875 +79576 0.0927734375 +79577 0.11712646484375 +79578 -0.06640625 +79579 -0.054901123046875 +79580 -0.19146728515625 +79581 -0.19085693359375 +79582 -0.27783203125 +79583 -0.28570556640625 +79584 -0.325439453125 +79585 -0.339263916015625 +79586 -0.35833740234375 +79587 -0.3775634765625 +79588 -0.41815185546875 +79589 -0.445709228515625 +79590 -0.49713134765625 +79591 -0.535064697265625 +79592 -0.5802001953125 +79593 -0.629058837890625 +79594 -0.639892578125 +79595 -0.697601318359375 +79596 -0.642547607421875 +79597 -0.70391845703125 +79598 -0.58319091796875 +79599 -0.6424560546875 +79600 -0.4417724609375 +79601 -0.491241455078125 +79602 -0.232574462890625 +79603 -0.265716552734375 +79604 -0.0089111328125 +79605 -0.023712158203125 +79606 0.19879150390625 +79607 0.201751708984375 +79608 0.358489990234375 +79609 0.375823974609375 +79610 0.457855224609375 +79611 0.485076904296875 +79612 0.533172607421875 +79613 0.56884765625 +79614 0.591583251953125 +79615 0.634765625 +79616 0.591156005859375 +79617 0.63763427734375 +79618 0.520782470703125 +79619 0.5660400390625 +79620 0.429595947265625 +79621 0.4720458984375 +79622 0.366668701171875 +79623 0.40692138671875 +79624 0.3389892578125 +79625 0.3778076171875 +79626 0.3392333984375 +79627 0.376953125 +79628 0.336578369140625 +79629 0.371978759765625 +79630 0.283599853515625 +79631 0.313140869140625 +79632 0.164825439453125 +79633 0.184417724609375 +79634 0.004241943359375 +79635 0.011199951171875 +79636 -0.164642333984375 +79637 -0.171051025390625 +79638 -0.318359375 +79639 -0.33740234375 +79640 -0.4420166015625 +79641 -0.47198486328125 +79642 -0.522186279296875 +79643 -0.560394287109375 +79644 -0.5380859375 +79645 -0.58056640625 +79646 -0.50421142578125 +79647 -0.54754638671875 +79648 -0.465667724609375 +79649 -0.508575439453125 +79650 -0.418548583984375 +79651 -0.459503173828125 +79652 -0.357177734375 +79653 -0.394378662109375 +79654 -0.319000244140625 +79655 -0.35260009765625 +79656 -0.282501220703125 +79657 -0.31170654296875 +79658 -0.17681884765625 +79659 -0.197418212890625 +79660 -9.1552734375e-05 +79661 -0.007965087890625 +79662 0.201080322265625 +79663 0.207489013671875 +79664 0.389068603515625 +79665 0.409210205078125 +79666 0.54022216796875 +79667 0.57208251953125 +79668 0.62603759765625 +79669 0.66595458984375 +79670 0.61614990234375 +79671 0.65875244140625 +79672 0.52685546875 +79673 0.56744384765625 +79674 0.395782470703125 +79675 0.431396484375 +79676 0.26470947265625 +79677 0.29443359375 +79678 0.158294677734375 +79679 0.182464599609375 +79680 0.046234130859375 +79681 0.06365966796875 +79682 -0.084869384765625 +79683 -0.075958251953125 +79684 -0.190460205078125 +79685 -0.189422607421875 +79686 -0.26611328125 +79687 -0.271942138671875 +79688 -0.330078125 +79689 -0.342529296875 +79690 -0.34735107421875 +79691 -0.364166259765625 +79692 -0.3089599609375 +79693 -0.327239990234375 +79694 -0.258087158203125 +79695 -0.2769775390625 +79696 -0.233306884765625 +79697 -0.253692626953125 +79698 -0.221649169921875 +79699 -0.24365234375 +79700 -0.177093505859375 +79701 -0.1983642578125 +79702 -0.09814453125 +79703 -0.116241455078125 +79704 -0.0224609375 +79705 -0.036834716796875 +79706 0.045196533203125 +79707 0.034881591796875 +79708 0.09759521484375 +79709 0.09124755859375 +79710 0.11260986328125 +79711 0.10888671875 +79712 0.126220703125 +79713 0.125518798828125 +79714 0.15435791015625 +79715 0.15771484375 +79716 0.1712646484375 +79717 0.17828369140625 +79718 0.161712646484375 +79719 0.17108154296875 +79720 0.120025634765625 +79721 0.129974365234375 +79722 0.072479248046875 +79723 0.082427978515625 +79724 0.01849365234375 +79725 0.027679443359375 +79726 -0.07171630859375 +79727 -0.065643310546875 +79728 -0.1617431640625 +79729 -0.15936279296875 +79730 -0.213104248046875 +79731 -0.21307373046875 +79732 -0.233306884765625 +79733 -0.234649658203125 +79734 -0.199615478515625 +79735 -0.2001953125 +79736 -0.121124267578125 +79737 -0.119171142578125 +79738 -0.029541015625 +79739 -0.024749755859375 +79740 0.077667236328125 +79741 0.085784912109375 +79742 0.167724609375 +79743 0.178131103515625 +79744 0.20556640625 +79745 0.215576171875 +79746 0.2037353515625 +79747 0.211456298828125 +79748 0.171142578125 +79749 0.17523193359375 +79750 0.128509521484375 +79751 0.128753662109375 +79752 0.104217529296875 +79753 0.1019287109375 +79754 0.07879638671875 +79755 0.0743408203125 +79756 0.049591064453125 +79757 0.04327392578125 +79758 0.044647216796875 +79759 0.038177490234375 +79760 0.080352783203125 +79761 0.076263427734375 +79762 0.141082763671875 +79763 0.14105224609375 +79764 0.183013916015625 +79765 0.186431884765625 +79766 0.183746337890625 +79767 0.188812255859375 +79768 0.1346435546875 +79769 0.1390380859375 +79770 0.040283203125 +79771 0.041778564453125 +79772 -0.07684326171875 +79773 -0.079437255859375 +79774 -0.21173095703125 +79775 -0.219390869140625 +79776 -0.3544921875 +79777 -0.367828369140625 +79778 -0.47662353515625 +79779 -0.494873046875 +79780 -0.535919189453125 +79781 -0.556243896484375 +79782 -0.49114990234375 +79783 -0.508697509765625 +79784 -0.36456298828125 +79785 -0.3756103515625 +79786 -0.215118408203125 +79787 -0.218902587890625 +79788 -0.0667724609375 +79789 -0.063751220703125 +79790 0.08203125 +79791 0.091552734375 +79792 0.22076416015625 +79793 0.23602294921875 +79794 0.323974609375 +79795 0.342987060546875 +79796 0.37518310546875 +79797 0.39520263671875 +79798 0.37115478515625 +79799 0.389373779296875 +79800 0.31060791015625 +79801 0.324249267578125 +79802 0.216552734375 +79803 0.224090576171875 +79804 0.122589111328125 +79805 0.124267578125 +79806 0.040374755859375 +79807 0.037078857421875 +79808 -0.004058837890625 +79809 -0.010101318359375 +79810 -0.012786865234375 +79811 -0.019439697265625 +79812 -0.01611328125 +79813 -0.022796630859375 +79814 0.003631591796875 +79815 -0.001556396484375 +79816 0.0579833984375 +79817 0.056304931640625 +79818 0.10504150390625 +79819 0.106719970703125 +79820 0.0946044921875 +79821 0.096893310546875 +79822 0.041839599609375 +79823 0.042694091796875 +79824 -0.017181396484375 +79825 -0.018035888671875 +79826 -0.073394775390625 +79827 -0.07586669921875 +79828 -0.115966796875 +79829 -0.11944580078125 +79830 -0.1552734375 +79831 -0.15972900390625 +79832 -0.19683837890625 +79833 -0.202606201171875 +79834 -0.241119384765625 +79835 -0.24859619140625 +79836 -0.295196533203125 +79837 -0.30517578125 +79838 -0.349365234375 +79839 -0.36212158203125 +79840 -0.376983642578125 +79841 -0.39141845703125 +79842 -0.342041015625 +79843 -0.35528564453125 +79844 -0.24102783203125 +79845 -0.249969482421875 +79846 -0.090576171875 +79847 -0.092864990234375 +79848 0.08355712890625 +79849 0.08905029296875 +79850 0.223724365234375 +79851 0.2352294921875 +79852 0.304290771484375 +79853 0.318817138671875 +79854 0.343109130859375 +79855 0.358642578125 +79856 0.333526611328125 +79857 0.347747802734375 +79858 0.275054931640625 +79859 0.28564453125 +79860 0.216033935546875 +79861 0.223175048828125 +79862 0.19110107421875 +79863 0.196746826171875 +79864 0.175018310546875 +79865 0.179840087890625 +79866 0.151702880859375 +79867 0.155548095703125 +79868 0.147186279296875 +79869 0.151214599609375 +79870 0.152099609375 +79871 0.156951904296875 +79872 0.127288818359375 +79873 0.13177490234375 +79874 0.097137451171875 +79875 0.100799560546875 +79876 0.0838623046875 +79877 0.087127685546875 +79878 0.05230712890625 +79879 0.05487060546875 +79880 -0.010223388671875 +79881 -0.009002685546875 +79882 -0.10321044921875 +79883 -0.10400390625 +79884 -0.2259521484375 +79885 -0.229400634765625 +79886 -0.349273681640625 +79887 -0.35552978515625 +79888 -0.433349609375 +79889 -0.441925048828125 +79890 -0.46380615234375 +79891 -0.473846435546875 +79892 -0.454010009765625 +79893 -0.464813232421875 +79894 -0.408233642578125 +79895 -0.419097900390625 +79896 -0.324188232421875 +79897 -0.334320068359375 +79898 -0.219085693359375 +79899 -0.227935791015625 +79900 -0.11614990234375 +79901 -0.12347412109375 +79902 -0.02197265625 +79903 -0.02764892578125 +79904 0.081298828125 +79905 0.077667236328125 +79906 0.214111328125 +79907 0.2132568359375 +79908 0.38604736328125 +79909 0.38885498046875 +79910 0.575836181640625 +79911 0.582794189453125 +79912 0.7235107421875 +79913 0.734039306640625 +79914 0.787384033203125 +79915 0.800140380859375 +79916 0.764739990234375 +79917 0.7783203125 +79918 0.65228271484375 +79919 0.6651611328125 +79920 0.4490966796875 +79921 0.45965576171875 +79922 0.192047119140625 +79923 0.199188232421875 +79924 -0.054351806640625 +79925 -0.050689697265625 +79926 -0.233978271484375 +79927 -0.23297119140625 +79928 -0.32958984375 +79929 -0.33013916015625 +79930 -0.366973876953125 +79931 -0.368408203125 +79932 -0.376800537109375 +79933 -0.378936767578125 +79934 -0.3741455078125 +79935 -0.376983642578125 +79936 -0.375946044921875 +79937 -0.37969970703125 +79938 -0.386566162109375 +79939 -0.391510009765625 +79940 -0.37945556640625 +79941 -0.385345458984375 +79942 -0.335693359375 +79943 -0.3419189453125 +79944 -0.27667236328125 +79945 -0.28289794921875 +79946 -0.24505615234375 +79947 -0.251617431640625 +79948 -0.2586669921875 +79949 -0.266143798828125 +79950 -0.265289306640625 +79951 -0.273345947265625 +79952 -0.20941162109375 +79953 -0.216796875 +79954 -0.12225341796875 +79955 -0.128265380859375 +79956 -0.06329345703125 +79957 -0.068145751953125 +79958 -0.03900146484375 +79959 -0.0430908203125 +79960 -0.021209716796875 +79961 -0.024444580078125 +79962 0.022552490234375 +79963 0.020721435546875 +79964 0.123870849609375 +79965 0.124481201171875 +79966 0.2542724609375 +79967 0.25787353515625 +79968 0.372711181640625 +79969 0.379119873046875 +79970 0.471099853515625 +79971 0.47991943359375 +79972 0.51788330078125 +79973 0.5281982421875 +79974 0.500518798828125 +79975 0.511138916015625 +79976 0.446044921875 +79977 0.456207275390625 +79978 0.3978271484375 +79979 0.407470703125 +79980 0.3743896484375 +79981 0.383758544921875 +79982 0.3480224609375 +79983 0.35687255859375 +79984 0.303985595703125 +79985 0.31182861328125 +79986 0.24444580078125 +79987 0.250885009765625 +79988 0.160858154296875 +79989 0.1654052734375 +79990 0.033416748046875 +79991 0.035247802734375 +79992 -0.140350341796875 +79993 -0.142059326171875 +79994 -0.33013916015625 +79995 -0.33563232421875 +79996 -0.52520751953125 +79997 -0.5345458984375 +79998 -0.70892333984375 +79999 -0.72186279296875 +80000 -0.821380615234375 +80001 -0.836669921875 +80002 -0.817047119140625 +80003 -0.8326416015625 +80004 -0.7154541015625 +80005 -0.7296142578125 +80006 -0.5706787109375 +80007 -0.582550048828125 +80008 -0.4305419921875 +80009 -0.440093994140625 +80010 -0.316802978515625 +80011 -0.324310302734375 +80012 -0.1962890625 +80013 -0.20147705078125 +80014 -0.04241943359375 +80015 -0.044647216796875 +80016 0.10333251953125 +80017 0.103973388671875 +80018 0.19964599609375 +80019 0.202392578125 +80020 0.260223388671875 +80021 0.264495849609375 +80022 0.33294677734375 +80023 0.338897705078125 +80024 0.43572998046875 +80025 0.443817138671875 +80026 0.53497314453125 +80027 0.545074462890625 +80028 0.605743408203125 +80029 0.6173095703125 +80030 0.64013671875 +80031 0.6524658203125 +80032 0.650787353515625 +80033 0.66339111328125 +80034 0.6436767578125 +80035 0.6561279296875 +80036 0.595245361328125 +80037 0.606781005859375 +80038 0.491546630859375 +80039 0.501190185546875 +80040 0.34576416015625 +80041 0.352783203125 +80042 0.17266845703125 +80043 0.176544189453125 +80044 -0.034942626953125 +80045 -0.034820556640625 +80046 -0.25433349609375 +80047 -0.258209228515625 +80048 -0.4351806640625 +80049 -0.44244384765625 +80050 -0.56549072265625 +80051 -0.5753173828125 +80052 -0.640625 +80053 -0.65203857421875 +80054 -0.630096435546875 +80055 -0.641632080078125 +80056 -0.551666259765625 +80057 -0.562164306640625 +80058 -0.449066162109375 +80059 -0.458038330078125 +80060 -0.343231201171875 +80061 -0.350555419921875 +80062 -0.254669189453125 +80063 -0.260528564453125 +80064 -0.187469482421875 +80065 -0.192108154296875 +80066 -0.138336181640625 +80067 -0.141937255859375 +80068 -0.099517822265625 +80069 -0.1021728515625 +80070 -0.06121826171875 +80071 -0.062896728515625 +80072 -0.011444091796875 +80073 -0.011932373046875 +80074 0.061767578125 +80075 0.062835693359375 +80076 0.145965576171875 +80077 0.148712158203125 +80078 0.2371826171875 +80079 0.241729736328125 +80080 0.34259033203125 +80081 0.34912109375 +80082 0.448822021484375 +80083 0.457305908203125 +80084 0.533843994140625 +80085 0.54388427734375 +80086 0.56231689453125 +80087 0.5728759765625 +80088 0.497100830078125 +80089 0.506591796875 +80090 0.344329833984375 +80091 0.351226806640625 +80092 0.14306640625 +80093 0.146514892578125 +80094 -0.05523681640625 +80095 -0.05523681640625 +80096 -0.213409423828125 +80097 -0.21624755859375 +80098 -0.32989501953125 +80099 -0.334930419921875 +80100 -0.39654541015625 +80101 -0.402984619140625 +80102 -0.43389892578125 +80103 -0.4412841796875 +80104 -0.487213134765625 +80105 -0.49578857421875 +80106 -0.55029296875 +80107 -0.5601806640625 +80108 -0.589996337890625 +80109 -0.600738525390625 +80110 -0.5736083984375 +80111 -0.584228515625 +80112 -0.47027587890625 +80113 -0.47930908203125 +80114 -0.273529052734375 +80115 -0.27935791015625 +80116 -0.007476806640625 +80117 -0.0089111328125 +80118 0.265625 +80119 0.268798828125 +80120 0.47601318359375 +80121 0.482818603515625 +80122 0.5947265625 +80123 0.60369873046875 +80124 0.640411376953125 +80125 0.650421142578125 +80126 0.653472900390625 +80127 0.66400146484375 +80128 0.630859375 +80129 0.6416015625 +80130 0.562530517578125 +80131 0.5728759765625 +80132 0.489349365234375 +80133 0.498199462890625 +80134 0.432342529296875 +80135 0.43853759765625 +80136 0.37042236328125 +80137 0.3734130859375 +80138 0.271636962890625 +80139 0.271636962890625 +80140 0.108184814453125 +80141 0.106170654296875 +80142 -0.097747802734375 +80143 -0.100921630859375 +80144 -0.314544677734375 +80145 -0.3182373046875 +80146 -0.54351806640625 +80147 -0.546875 +80148 -0.766998291015625 +80149 -0.769287109375 +80150 -0.86297607421875 +80151 -0.863128662109375 +80152 -0.870391845703125 +80153 -0.870391845703125 +80154 -0.869781494140625 +80155 -0.86968994140625 +80156 -0.862640380859375 +80157 -0.8624267578125 +80158 -0.786224365234375 +80159 -0.784149169921875 +80160 -0.55517578125 +80161 -0.553741455078125 +80162 -0.242889404296875 +80163 -0.24310302734375 +80164 0.10760498046875 +80165 0.105255126953125 +80166 0.445159912109375 +80167 0.4407958984375 +80168 0.73443603515625 +80169 0.72857666015625 +80170 0.86474609375 +80171 0.864044189453125 +80172 0.870361328125 +80173 0.870361328125 +80174 0.867431640625 +80175 0.8681640625 +80176 0.857025146484375 +80177 0.85845947265625 +80178 0.742645263671875 +80179 0.7611083984375 +80180 0.575775146484375 +80181 0.598388671875 +80182 0.397613525390625 +80183 0.42279052734375 +80184 0.210968017578125 +80185 0.237152099609375 +80186 -0.016387939453125 +80187 0.009857177734375 +80188 -0.292999267578125 +80189 -0.2672119140625 +80190 -0.578643798828125 +80191 -0.554168701171875 +80192 -0.81683349609375 +80193 -0.795074462890625 +80194 -0.866943359375 +80195 -0.86505126953125 +80196 -0.870391845703125 +80197 -0.870391845703125 +80198 -0.867767333984375 +80199 -0.869598388671875 +80200 -0.863616943359375 +80201 -0.8670654296875 +80202 -0.856475830078125 +80203 -0.861297607421875 +80204 -0.729736328125 +80205 -0.7840576171875 +80206 -0.509613037109375 +80207 -0.57147216796875 +80208 -0.246826171875 +80209 -0.312957763671875 +80210 0.03057861328125 +80211 -0.03619384765625 +80212 0.31158447265625 +80213 0.24761962890625 +80214 0.5711669921875 +80215 0.51336669921875 +80216 0.7735595703125 +80217 0.725189208984375 +80218 0.8599853515625 +80219 0.856048583984375 +80220 0.865386962890625 +80221 0.863006591796875 +80222 0.8643798828125 +80223 0.8636474609375 +80224 0.85894775390625 +80225 0.859832763671875 +80226 0.807159423828125 +80227 0.82916259765625 +80228 0.689849853515625 +80229 0.72393798828125 +80230 0.54052734375 +80231 0.584442138671875 +80232 0.387908935546875 +80233 0.438629150390625 +80234 0.246337890625 +80235 0.3004150390625 +80236 0.09381103515625 +80237 0.148223876953125 +80238 -0.06231689453125 +80239 -0.010498046875 +80240 -0.22686767578125 +80241 -0.180145263671875 +80242 -0.41607666015625 +80243 -0.376190185546875 +80244 -0.58599853515625 +80245 -0.55474853515625 +80246 -0.71539306640625 +80247 -0.694305419921875 +80248 -0.83123779296875 +80249 -0.820709228515625 +80250 -0.861968994140625 +80251 -0.861968994140625 +80252 -0.86614990234375 +80253 -0.86724853515625 +80254 -0.861480712890625 +80255 -0.8636474609375 +80256 -0.80999755859375 +80257 -0.8385009765625 +80258 -0.696258544921875 +80259 -0.731048583984375 +80260 -0.557159423828125 +80261 -0.59600830078125 +80262 -0.335296630859375 +80263 -0.376861572265625 +80264 -0.07647705078125 +80265 -0.118804931640625 +80266 0.151611328125 +80267 0.11126708984375 +80268 0.36297607421875 +80269 0.3267822265625 +80270 0.5921630859375 +80271 0.561309814453125 +80272 0.832244873046875 +80273 0.80743408203125 +80274 0.870361328125 +80275 0.870361328125 +80276 0.870361328125 +80277 0.870361328125 +80278 0.862762451171875 +80279 0.86279296875 +80280 0.79669189453125 +80281 0.797332763671875 +80282 0.595794677734375 +80283 0.597259521484375 +80284 0.362152099609375 +80285 0.36444091796875 +80286 0.1270751953125 +80287 0.1298828125 +80288 -0.086944580078125 +80289 -0.0841064453125 +80290 -0.2784423828125 +80291 -0.27593994140625 +80292 -0.484832763671875 +80293 -0.48223876953125 +80294 -0.729583740234375 +80295 -0.725921630859375 +80296 -0.86688232421875 +80297 -0.866302490234375 +80298 -0.870391845703125 +80299 -0.870391845703125 +80300 -0.86859130859375 +80301 -0.869110107421875 +80302 -0.86279296875 +80303 -0.86376953125 +80304 -0.817962646484375 +80305 -0.83087158203125 +80306 -0.6116943359375 +80307 -0.62841796875 +80308 -0.3128662109375 +80309 -0.33343505859375 +80310 0.039398193359375 +80311 0.0155029296875 +80312 0.422821044921875 +80313 0.39630126953125 +80314 0.805145263671875 +80315 0.7769775390625 +80316 0.870361328125 +80317 0.870361328125 +80318 0.870361328125 +80319 0.870361328125 +80320 0.860015869140625 +80321 0.860076904296875 +80322 0.727935791015625 +80323 0.729766845703125 +80324 0.48114013671875 +80325 0.484588623046875 +80326 0.2059326171875 +80327 0.21087646484375 +80328 -0.06103515625 +80329 -0.055084228515625 +80330 -0.29913330078125 +80331 -0.2928466796875 +80332 -0.516204833984375 +80333 -0.509918212890625 +80334 -0.7252197265625 +80335 -0.718841552734375 +80336 -0.85980224609375 +80337 -0.859100341796875 +80338 -0.870391845703125 +80339 -0.870391845703125 +80340 -0.870391845703125 +80341 -0.870391845703125 +80342 -0.858062744140625 +80343 -0.858184814453125 +80344 -0.673004150390625 +80345 -0.675689697265625 +80346 -0.42694091796875 +80347 -0.43121337890625 +80348 -0.2100830078125 +80349 -0.2149658203125 +80350 -0.0362548828125 +80351 -0.040679931640625 +80352 0.10943603515625 +80353 0.1060791015625 +80354 0.23516845703125 +80355 0.233184814453125 +80356 0.373687744140625 +80357 0.3726806640625 +80358 0.517791748046875 +80359 0.517303466796875 +80360 0.602783203125 +80361 0.603271484375 +80362 0.635711669921875 +80363 0.63739013671875 +80364 0.655181884765625 +80365 0.657562255859375 +80366 0.65948486328125 +80367 0.662078857421875 +80368 0.651275634765625 +80369 0.653533935546875 +80370 0.61846923828125 +80371 0.620086669921875 +80372 0.53753662109375 +80373 0.538665771484375 +80374 0.404144287109375 +80375 0.4051513671875 +80376 0.22186279296875 +80377 0.22320556640625 +80378 0.003997802734375 +80379 0.00604248046875 +80380 -0.22100830078125 +80381 -0.21820068359375 +80382 -0.42449951171875 +80383 -0.421173095703125 +80384 -0.579833984375 +80385 -0.576812744140625 +80386 -0.641876220703125 +80387 -0.641265869140625 +80388 -0.6177978515625 +80389 -0.620880126953125 +80390 -0.575531005859375 +80391 -0.58062744140625 +80392 -0.526336669921875 +80393 -0.5316162109375 +80394 -0.42645263671875 +80395 -0.432647705078125 +80396 -0.2581787109375 +80397 -0.2672119140625 +80398 -0.068695068359375 +80399 -0.080657958984375 +80400 0.09222412109375 +80401 0.079193115234375 +80402 0.232147216796875 +80403 0.219146728515625 +80404 0.3509521484375 +80405 0.3387451171875 +80406 0.410064697265625 +80407 0.40093994140625 +80408 0.372955322265625 +80409 0.370635986328125 +80410 0.2554931640625 +80411 0.262725830078125 +80412 0.10711669921875 +80413 0.1241455078125 +80414 -0.052886962890625 +80415 -0.02685546875 +80416 -0.186279296875 +80417 -0.15386962890625 +80418 -0.23291015625 +80419 -0.199615478515625 +80420 -0.209442138671875 +80421 -0.1798095703125 +80422 -0.174163818359375 +80423 -0.149749755859375 +80424 -0.126739501953125 +80425 -0.10888671875 +80426 -0.048126220703125 +80427 -0.038848876953125 +80428 0.0426025390625 +80429 0.04248046875 +80430 0.10748291015625 +80431 0.0992431640625 +80432 0.1409912109375 +80433 0.12646484375 +80434 0.19708251953125 +80435 0.17572021484375 +80436 0.273651123046875 +80437 0.2452392578125 +80438 0.31768798828125 +80439 0.28472900390625 +80440 0.341094970703125 +80441 0.30560302734375 +80442 0.368011474609375 +80443 0.3309326171875 +80444 0.37249755859375 +80445 0.335968017578125 +80446 0.30072021484375 +80447 0.269378662109375 +80448 0.1517333984375 +80449 0.130126953125 +80450 -0.01470947265625 +80451 -0.0250244140625 +80452 -0.1883544921875 +80453 -0.1865234375 +80454 -0.372711181640625 +80455 -0.35797119140625 +80456 -0.51397705078125 +80457 -0.48834228515625 +80458 -0.57177734375 +80459 -0.539398193359375 +80460 -0.53948974609375 +80461 -0.50506591796875 +80462 -0.43511962890625 +80463 -0.4027099609375 +80464 -0.2962646484375 +80465 -0.26824951171875 +80466 -0.161102294921875 +80467 -0.13812255859375 +80468 -0.0435791015625 +80469 -0.025634765625 +80470 0.060394287109375 +80471 0.07305908203125 +80472 0.13665771484375 +80473 0.14453125 +80474 0.170135498046875 +80475 0.174530029296875 +80476 0.16552734375 +80477 0.16766357421875 +80478 0.15728759765625 +80479 0.1568603515625 +80480 0.150787353515625 +80481 0.147430419921875 +80482 0.12200927734375 +80483 0.116668701171875 +80484 0.080108642578125 +80485 0.073486328125 +80486 0.05126953125 +80487 0.04296875 +80488 0.062896728515625 +80489 0.051422119140625 +80490 0.09271240234375 +80491 0.07769775390625 +80492 0.092987060546875 +80493 0.076507568359375 +80494 0.07855224609375 +80495 0.06201171875 +80496 0.06427001953125 +80497 0.04840087890625 +80498 0.0347900390625 +80499 0.02099609375 +80500 -0.01171875 +80501 -0.02197265625 +80502 -0.056060791015625 +80503 -0.062347412109375 +80504 -0.055511474609375 +80505 -0.059539794921875 +80506 -0.010467529296875 +80507 -0.014068603515625 +80508 0.02508544921875 +80509 0.02252197265625 +80510 0.025665283203125 +80511 0.02581787109375 +80512 0.017333984375 +80513 0.020477294921875 +80514 0.00189208984375 +80515 0.008087158203125 +80516 -0.03173828125 +80517 -0.022003173828125 +80518 -0.071502685546875 +80519 -0.0584716796875 +80520 -0.13543701171875 +80521 -0.118499755859375 +80522 -0.219970703125 +80523 -0.19873046875 +80524 -0.300506591796875 +80525 -0.2757568359375 +80526 -0.376312255859375 +80527 -0.34881591796875 +80528 -0.416107177734375 +80529 -0.3880615234375 +80530 -0.371124267578125 +80531 -0.34698486328125 +80532 -0.242279052734375 +80533 -0.226348876953125 +80534 -0.069732666015625 +80535 -0.06427001953125 +80536 0.125640869140625 +80537 0.119476318359375 +80538 0.31268310546875 +80539 0.29534912109375 +80540 0.45501708984375 +80541 0.428863525390625 +80542 0.554779052734375 +80543 0.52215576171875 +80544 0.61065673828125 +80545 0.574066162109375 +80546 0.610931396484375 +80547 0.573455810546875 +80548 0.531463623046875 +80549 0.497406005859375 +80550 0.3883056640625 +80551 0.3612060546875 +80552 0.23468017578125 +80553 0.215484619140625 +80554 0.095245361328125 +80555 0.083709716796875 +80556 -0.00396728515625 +80557 -0.009429931640625 +80558 -0.04852294921875 +80559 -0.05029296875 +80560 -0.055145263671875 +80561 -0.054840087890625 +80562 -0.0758056640625 +80563 -0.07269287109375 +80564 -0.138702392578125 +80565 -0.130767822265625 +80566 -0.209197998046875 +80567 -0.196197509765625 +80568 -0.289031982421875 +80569 -0.270751953125 +80570 -0.37884521484375 +80571 -0.3551025390625 +80572 -0.456329345703125 +80573 -0.42803955078125 +80574 -0.51641845703125 +80575 -0.484771728515625 +80576 -0.519287109375 +80577 -0.487396240234375 +80578 -0.458251953125 +80579 -0.4295654296875 +80580 -0.384796142578125 +80581 -0.360260009765625 +80582 -0.323699951171875 +80583 -0.30303955078125 +80584 -0.269287109375 +80585 -0.252410888671875 +80586 -0.1951904296875 +80587 -0.1832275390625 +80588 -0.100006103515625 +80589 -0.09405517578125 +80590 -0.01055908203125 +80591 -0.010345458984375 +80592 0.1033935546875 +80593 0.09674072265625 +80594 0.24908447265625 +80595 0.234161376953125 +80596 0.373199462890625 +80597 0.351226806640625 +80598 0.45806884765625 +80599 0.431182861328125 +80600 0.511474609375 +80601 0.4814453125 +80602 0.565399169921875 +80603 0.53253173828125 +80604 0.61138916015625 +80605 0.576385498046875 +80606 0.5897216796875 +80607 0.556121826171875 +80608 0.4906005859375 +80609 0.462371826171875 +80610 0.33148193359375 +80611 0.311767578125 +80612 0.147796630859375 +80613 0.137939453125 +80614 -0.01873779296875 +80615 -0.019439697265625 +80616 -0.140289306640625 +80617 -0.133941650390625 +80618 -0.191986083984375 +80619 -0.18194580078125 +80620 -0.184295654296875 +80621 -0.173492431640625 +80622 -0.161834716796875 +80623 -0.151123046875 +80624 -0.166595458984375 +80625 -0.15484619140625 +80626 -0.19390869140625 +80627 -0.18023681640625 +80628 -0.22442626953125 +80629 -0.20892333984375 +80630 -0.279754638671875 +80631 -0.261505126953125 +80632 -0.3389892578125 +80633 -0.318084716796875 +80634 -0.3543701171875 +80635 -0.333160400390625 +80636 -0.348175048828125 +80637 -0.327911376953125 +80638 -0.32598876953125 +80639 -0.3076171875 +80640 -0.2581787109375 +80641 -0.2440185546875 +80642 -0.139801025390625 +80643 -0.132354736328125 +80644 0.014617919921875 +80645 0.013580322265625 +80646 0.144378662109375 +80647 0.1361083984375 +80648 0.221038818359375 +80649 0.208282470703125 +80650 0.27069091796875 +80651 0.2548828125 +80652 0.294036865234375 +80653 0.276641845703125 +80654 0.311767578125 +80655 0.293212890625 +80656 0.339141845703125 +80657 0.31903076171875 +80658 0.360260009765625 +80659 0.338623046875 +80660 0.360504150390625 +80661 0.338226318359375 +80662 0.308380126953125 +80663 0.28900146484375 +80664 0.18170166015625 +80665 0.170745849609375 +80666 0.0047607421875 +80667 0.00604248046875 +80668 -0.17559814453125 +80669 -0.161865234375 +80670 -0.3143310546875 +80671 -0.291412353515625 +80672 -0.36785888671875 +80673 -0.342376708984375 +80674 -0.36248779296875 +80675 -0.338836669921875 +80676 -0.343536376953125 +80677 -0.322418212890625 +80678 -0.3018798828125 +80679 -0.284698486328125 +80680 -0.231414794921875 +80681 -0.22003173828125 +80682 -0.117645263671875 +80683 -0.11505126953125 +80684 0.007049560546875 +80685 0.0003662109375 +80686 0.087982177734375 +80687 0.07586669921875 +80688 0.13946533203125 +80689 0.12457275390625 +80690 0.17425537109375 +80691 0.158111572265625 +80692 0.188201904296875 +80693 0.17254638671875 +80694 0.171234130859375 +80695 0.15850830078125 +80696 0.118438720703125 +80697 0.111419677734375 +80698 0.05706787109375 +80699 0.0562744140625 +80700 -0.010711669921875 +80701 -0.0050048828125 +80702 -0.0914306640625 +80703 -0.078521728515625 +80704 -0.162322998046875 +80705 -0.143310546875 +80706 -0.194549560546875 +80707 -0.172882080078125 +80708 -0.1492919921875 +80709 -0.13153076171875 +80710 -0.02166748046875 +80711 -0.014678955078125 +80712 0.124053955078125 +80713 0.1185302734375 +80714 0.211151123046875 +80715 0.197601318359375 +80716 0.240447998046875 +80717 0.223358154296875 +80718 0.242218017578125 +80719 0.22369384765625 +80720 0.2257080078125 +80721 0.20721435546875 +80722 0.194366455078125 +80723 0.177154541015625 +80724 0.115509033203125 +80725 0.103515625 +80726 0.0128173828125 +80727 0.00811767578125 +80728 -0.053802490234375 +80729 -0.053863525390625 +80730 -0.110626220703125 +80731 -0.1065673828125 +80732 -0.199493408203125 +80733 -0.1884765625 +80734 -0.29437255859375 +80735 -0.275634765625 +80736 -0.33221435546875 +80737 -0.31005859375 +80738 -0.27972412109375 +80739 -0.261138916015625 +80740 -0.185333251953125 +80741 -0.173492431640625 +80742 -0.128204345703125 +80743 -0.1199951171875 +80744 -0.115692138671875 +80745 -0.107421875 +80746 -0.116455078125 +80747 -0.107025146484375 +80748 -0.105926513671875 +80749 -0.09625244140625 +80750 -0.053955078125 +80751 -0.047454833984375 +80752 0.048797607421875 +80753 0.04791259765625 +80754 0.157318115234375 +80755 0.148406982421875 +80756 0.212005615234375 +80757 0.19915771484375 +80758 0.218475341796875 +80759 0.205291748046875 +80760 0.23724365234375 +80761 0.222503662109375 +80762 0.30535888671875 +80763 0.284912109375 +80764 0.38128662109375 +80765 0.354278564453125 +80766 0.404449462890625 +80767 0.374908447265625 +80768 0.3944091796875 +80769 0.364837646484375 +80770 0.3885498046875 +80771 0.358551025390625 +80772 0.362640380859375 +80773 0.333831787109375 +80774 0.27362060546875 +80775 0.251068115234375 +80776 0.11712646484375 +80777 0.10626220703125 +80778 -0.054901123046875 +80779 -0.052734375 +80780 -0.19085693359375 +80781 -0.178375244140625 +80782 -0.28570556640625 +80783 -0.266021728515625 +80784 -0.339263916015625 +80785 -0.31549072265625 +80786 -0.3775634765625 +80787 -0.350738525390625 +80788 -0.445709228515625 +80789 -0.41326904296875 +80790 -0.535064697265625 +80791 -0.495147705078125 +80792 -0.629058837890625 +80793 -0.581146240234375 +80794 -0.697601318359375 +80795 -0.64361572265625 +80796 -0.70391845703125 +80797 -0.648773193359375 +80798 -0.6424560546875 +80799 -0.591522216796875 +80800 -0.491241455078125 +80801 -0.451690673828125 +80802 -0.265716552734375 +80803 -0.243499755859375 +80804 -0.023712158203125 +80805 -0.02020263671875 +80806 0.201751708984375 +80807 0.187744140625 +80808 0.375823974609375 +80809 0.3482666015625 +80810 0.485076904296875 +80811 0.449005126953125 +80812 0.56884765625 +80813 0.526153564453125 +80814 0.634765625 +80815 0.58673095703125 +80816 0.63763427734375 +80817 0.58917236328125 +80818 0.5660400390625 +80819 0.522979736328125 +80820 0.4720458984375 +80821 0.436065673828125 +80822 0.40692138671875 +80823 0.375579833984375 +80824 0.3778076171875 +80825 0.34820556640625 +80826 0.376953125 +80827 0.3468017578125 +80828 0.371978759765625 +80829 0.34161376953125 +80830 0.313140869140625 +80831 0.28692626953125 +80832 0.184417724609375 +80833 0.167999267578125 +80834 0.011199951171875 +80835 0.00823974609375 +80836 -0.171051025390625 +80837 -0.15972900390625 +80838 -0.33740234375 +80839 -0.31292724609375 +80840 -0.47198486328125 +80841 -0.436737060546875 +80842 -0.560394287109375 +80843 -0.5179443359375 +80844 -0.58056640625 +80845 -0.5362548828125 +80846 -0.54754638671875 +80847 -0.505523681640625 +80848 -0.508575439453125 +80849 -0.46923828125 +80850 -0.459503173828125 +80851 -0.423583984375 +80852 -0.394378662109375 +80853 -0.3631591796875 +80854 -0.35260009765625 +80855 -0.32421875 +80856 -0.31170654296875 +80857 -0.286102294921875 +80858 -0.197418212890625 +80859 -0.180511474609375 +80860 -0.007965087890625 +80861 -0.005828857421875 +80862 0.207489013671875 +80863 0.19268798828125 +80864 0.409210205078125 +80865 0.37847900390625 +80866 0.57208251953125 +80867 0.52838134765625 +80868 0.66595458984375 +80869 0.61468505859375 +80870 0.65875244140625 +80871 0.60791015625 +80872 0.56744384765625 +80873 0.523651123046875 +80874 0.431396484375 +80875 0.39813232421875 +80876 0.29443359375 +80877 0.271728515625 +80878 0.182464599609375 +80879 0.16827392578125 +80880 0.06365966796875 +80881 0.05853271484375 +80882 -0.075958251953125 +80883 -0.070343017578125 +80884 -0.189422607421875 +80885 -0.175140380859375 +80886 -0.271942138671875 +80887 -0.25140380859375 +80888 -0.342529296875 +80889 -0.316619873046875 +80890 -0.364166259765625 +80891 -0.336761474609375 +80892 -0.327239990234375 +80893 -0.302947998046875 +80894 -0.2769775390625 +80895 -0.25677490234375 +80896 -0.253692626953125 +80897 -0.235076904296875 +80898 -0.24365234375 +80899 -0.22540283203125 +80900 -0.1983642578125 +80901 -0.184295654296875 +80902 -0.116241455078125 +80903 -0.1102294921875 +80904 -0.036834716796875 +80905 -0.038238525390625 +80906 0.034881591796875 +80907 0.027191162109375 +80908 0.09124755859375 +80909 0.079193115234375 +80910 0.10888671875 +80911 0.096954345703125 +80912 0.125518798828125 +80913 0.11383056640625 +80914 0.15771484375 +80915 0.1444091796875 +80916 0.17828369140625 +80917 0.1644287109375 +80918 0.17108154296875 +80919 0.159454345703125 +80920 0.129974365234375 +80921 0.123992919921875 +80922 0.082427978515625 +80923 0.08233642578125 +80924 0.027679443359375 +80925 0.0338134765625 +80926 -0.065643310546875 +80927 -0.0494384765625 +80928 -0.15936279296875 +80929 -0.13348388671875 +80930 -0.21307373046875 +80931 -0.182373046875 +80932 -0.234649658203125 +80933 -0.20306396484375 +80934 -0.2001953125 +80935 -0.174224853515625 +80936 -0.119171142578125 +80937 -0.10418701171875 +80938 -0.024749755859375 +80939 -0.022308349609375 +80940 0.085784912109375 +80941 0.073944091796875 +80942 0.178131103515625 +80943 0.154205322265625 +80944 0.215576171875 +80945 0.186004638671875 +80946 0.211456298828125 +80947 0.18121337890625 +80948 0.17523193359375 +80949 0.148284912109375 +80950 0.128753662109375 +80951 0.106689453125 +80952 0.1019287109375 +80953 0.082977294921875 +80954 0.0743408203125 +80955 0.05902099609375 +80956 0.04327392578125 +80957 0.0323486328125 +80958 0.038177490234375 +80959 0.029022216796875 +80960 0.076263427734375 +80961 0.064300537109375 +80962 0.14105224609375 +80963 0.1234130859375 +80964 0.186431884765625 +80965 0.16534423828125 +80966 0.188812255859375 +80967 0.169036865234375 +80968 0.1390380859375 +80969 0.126251220703125 +80970 0.041778564453125 +80971 0.041107177734375 +80972 -0.079437255859375 +80973 -0.0655517578125 +80974 -0.219390869140625 +80975 -0.18914794921875 +80976 -0.367828369140625 +80977 -0.320587158203125 +80978 -0.494873046875 +80979 -0.433349609375 +80980 -0.556243896484375 +80981 -0.488128662109375 +80982 -0.508697509765625 +80983 -0.446502685546875 +80984 -0.3756103515625 +80985 -0.32916259765625 +80986 -0.218902587890625 +80987 -0.191070556640625 +80988 -0.063751220703125 +80989 -0.05450439453125 +80990 0.091552734375 +80991 0.08209228515625 +80992 0.23602294921875 +80993 0.209075927734375 +80994 0.342987060546875 +80995 0.30279541015625 +80996 0.39520263671875 +80997 0.3480224609375 +80998 0.389373779296875 +80999 0.3419189453125 +81000 0.324249267578125 +81001 0.28338623046875 +81002 0.224090576171875 +81003 0.194000244140625 +81004 0.124267578125 +81005 0.105224609375 +81006 0.037078857421875 +81007 0.027923583984375 +81008 -0.010101318359375 +81009 -0.013580322265625 +81010 -0.019439697265625 +81011 -0.021270751953125 +81012 -0.022796630859375 +81013 -0.0234375 +81014 -0.001556396484375 +81015 -0.003570556640625 +81016 0.056304931640625 +81017 0.048919677734375 +81018 0.106719970703125 +81019 0.09478759765625 +81020 0.096893310546875 +81021 0.087127685546875 +81022 0.042694091796875 +81023 0.040008544921875 +81024 -0.018035888671875 +81025 -0.0130615234375 +81026 -0.07586669921875 +81027 -0.063720703125 +81028 -0.11944580078125 +81029 -0.1019287109375 +81030 -0.15972900390625 +81031 -0.137451171875 +81032 -0.202606201171875 +81033 -0.175537109375 +81034 -0.24859619140625 +81035 -0.216644287109375 +81036 -0.30517578125 +81037 -0.267333984375 +81038 -0.36212158203125 +81039 -0.31854248046875 +81040 -0.39141845703125 +81041 -0.345367431640625 +81042 -0.35528564453125 +81043 -0.314178466796875 +81044 -0.249969482421875 +81045 -0.22161865234375 +81046 -0.092864990234375 +81047 -0.083099365234375 +81048 0.08905029296875 +81049 0.0775146484375 +81050 0.2352294921875 +81051 0.206512451171875 +81052 0.318817138671875 +81053 0.28009033203125 +81054 0.358642578125 +81055 0.31500244140625 +81056 0.347747802734375 +81057 0.305084228515625 +81058 0.28564453125 +81059 0.249908447265625 +81060 0.223175048828125 +81061 0.19464111328125 +81062 0.196746826171875 +81063 0.17156982421875 +81064 0.179840087890625 +81065 0.1571044921875 +81066 0.155548095703125 +81067 0.13623046875 +81068 0.151214599609375 +81069 0.133148193359375 +81070 0.156951904296875 +81071 0.139068603515625 +81072 0.13177490234375 +81073 0.117523193359375 +81074 0.100799560546875 +81075 0.09075927734375 +81076 0.087127685546875 +81077 0.079254150390625 +81078 0.05487060546875 +81079 0.051116943359375 +81080 -0.009002685546875 +81081 -0.0052490234375 +81082 -0.10400390625 +81083 -0.089385986328125 +81084 -0.229400634765625 +81085 -0.200653076171875 +81086 -0.35552978515625 +81087 -0.312713623046875 +81088 -0.441925048828125 +81089 -0.3896484375 +81090 -0.473846435546875 +81091 -0.41839599609375 +81092 -0.464813232421875 +81093 -0.410858154296875 +81094 -0.419097900390625 +81095 -0.370819091796875 +81096 -0.334320068359375 +81097 -0.296173095703125 +81098 -0.227935791015625 +81099 -0.20233154296875 +81100 -0.12347412109375 +81101 -0.11016845703125 +81102 -0.02764892578125 +81103 -0.025604248046875 +81104 0.077667236328125 +81105 0.06744384765625 +81106 0.2132568359375 +81107 0.187469482421875 +81108 0.38885498046875 +81109 0.3431396484375 +81110 0.582794189453125 +81111 0.51519775390625 +81112 0.734039306640625 +81113 0.649444580078125 +81114 0.800140380859375 +81115 0.708221435546875 +81116 0.7783203125 +81117 0.68902587890625 +81118 0.6651611328125 +81119 0.588836669921875 +81120 0.45965576171875 +81121 0.40673828125 +81122 0.199188232421875 +81123 0.1759033203125 +81124 -0.050689697265625 +81125 -0.04547119140625 +81126 -0.23297119140625 +81127 -0.206817626953125 +81128 -0.33013916015625 +81129 -0.292633056640625 +81130 -0.368408203125 +81131 -0.326171875 +81132 -0.378936767578125 +81133 -0.335113525390625 +81134 -0.376983642578125 +81135 -0.333038330078125 +81136 -0.37969970703125 +81137 -0.335205078125 +81138 -0.391510009765625 +81139 -0.345550537109375 +81140 -0.385345458984375 +81141 -0.340057373046875 +81142 -0.3419189453125 +81143 -0.301605224609375 +81144 -0.28289794921875 +81145 -0.249420166015625 +81146 -0.251617431640625 +81147 -0.221954345703125 +81148 -0.266143798828125 +81149 -0.235198974609375 +81150 -0.273345947265625 +81151 -0.24200439453125 +81152 -0.216796875 +81153 -0.192352294921875 +81154 -0.128265380859375 +81155 -0.114166259765625 +81156 -0.068145751953125 +81157 -0.060089111328125 +81158 -0.0430908203125 +81159 -0.03594970703125 +81160 -0.024444580078125 +81161 -0.01739501953125 +81162 0.020721435546875 +81163 0.023651123046875 +81164 0.124481201171875 +81165 0.114501953125 +81166 0.25787353515625 +81167 0.230224609375 +81168 0.379119873046875 +81169 0.334991455078125 +81170 0.47991943359375 +81171 0.421661376953125 +81172 0.5281982421875 +81173 0.4627685546875 +81174 0.511138916015625 +81175 0.447357177734375 +81176 0.456207275390625 +81177 0.399017333984375 +81178 0.407470703125 +81179 0.355560302734375 +81180 0.383758544921875 +81181 0.333221435546875 +81182 0.35687255859375 +81183 0.307952880859375 +81184 0.31182861328125 +81185 0.267059326171875 +81186 0.250885009765625 +81187 0.212615966796875 +81188 0.1654052734375 +81189 0.137359619140625 +81190 0.035247802734375 +81191 0.024139404296875 +81192 -0.142059326171875 +81193 -0.129058837890625 +81194 -0.33563232421875 +81195 -0.295745849609375 +81196 -0.5345458984375 +81197 -0.46649169921875 +81198 -0.72186279296875 +81199 -0.62677001953125 +81200 -0.836669921875 +81201 -0.7244873046875 +81202 -0.8326416015625 +81203 -0.72003173828125 +81204 -0.7296142578125 +81205 -0.6304931640625 +81206 -0.582550048828125 +81207 -0.502960205078125 +81208 -0.440093994140625 +81209 -0.379180908203125 +81210 -0.324310302734375 +81211 -0.278167724609375 +81212 -0.20147705078125 +81213 -0.171142578125 +81214 -0.044647216796875 +81215 -0.035125732421875 +81216 0.103973388671875 +81217 0.093658447265625 +81218 0.202392578125 +81219 0.179168701171875 +81220 0.264495849609375 +81221 0.233245849609375 +81222 0.338897705078125 +81223 0.2974853515625 +81224 0.443817138671875 +81225 0.387420654296875 +81226 0.545074462890625 +81227 0.47381591796875 +81228 0.6173095703125 +81229 0.53497314453125 +81230 0.6524658203125 +81231 0.564056396484375 +81232 0.66339111328125 +81233 0.572113037109375 +81234 0.6561279296875 +81235 0.56439208984375 +81236 0.606781005859375 +81237 0.520538330078125 +81238 0.501190185546875 +81239 0.42852783203125 +81240 0.352783203125 +81241 0.2999267578125 +81242 0.176544189453125 +81243 0.147674560546875 +81244 -0.034820556640625 +81245 -0.034423828125 +81246 -0.258209228515625 +81247 -0.226531982421875 +81248 -0.44244384765625 +81249 -0.384765625 +81250 -0.5753173828125 +81251 -0.4986572265625 +81252 -0.65203857421875 +81253 -0.56414794921875 +81254 -0.641632080078125 +81255 -0.55474853515625 +81256 -0.562164306640625 +81257 -0.485931396484375 +81258 -0.458038330078125 +81259 -0.395782470703125 +81260 -0.350555419921875 +81261 -0.302581787109375 +81262 -0.260528564453125 +81263 -0.224212646484375 +81264 -0.192108154296875 +81265 -0.164306640625 +81266 -0.141937255859375 +81267 -0.120086669921875 +81268 -0.1021728515625 +81269 -0.08489990234375 +81270 -0.062896728515625 +81271 -0.050323486328125 +81272 -0.011932373046875 +81273 -0.005950927734375 +81274 0.062835693359375 +81275 0.058563232421875 +81276 0.148712158203125 +81277 0.13232421875 +81278 0.241729736328125 +81279 0.2119140625 +81280 0.34912109375 +81281 0.30352783203125 +81282 0.457305908203125 +81283 0.395599365234375 +81284 0.54388427734375 +81285 0.46893310546875 +81286 0.5728759765625 +81287 0.492828369140625 +81288 0.506591796875 +81289 0.43505859375 +81290 0.351226806640625 +81291 0.300994873046875 +81292 0.146514892578125 +81293 0.12469482421875 +81294 -0.05523681640625 +81295 -0.048980712890625 +81296 -0.21624755859375 +81297 -0.18768310546875 +81298 -0.334930419921875 +81299 -0.289947509765625 +81300 -0.402984619140625 +81301 -0.348663330078125 +81302 -0.4412841796875 +81303 -0.381683349609375 +81304 -0.49578857421875 +81305 -0.428375244140625 +81306 -0.5601806640625 +81307 -0.483306884765625 +81308 -0.600738525390625 +81309 -0.51763916015625 +81310 -0.584228515625 +81311 -0.502960205078125 +81312 -0.47930908203125 +81313 -0.41241455078125 +81314 -0.27935791015625 +81315 -0.240447998046875 +81316 -0.0089111328125 +81317 -0.008087158203125 +81318 0.268798828125 +81319 0.23046875 +81320 0.482818603515625 +81321 0.41448974609375 +81322 0.60369873046875 +81323 0.518707275390625 +81324 0.650421142578125 +81325 0.559295654296875 +81326 0.66400146484375 +81327 0.57135009765625 +81328 0.6414794921875 +81329 0.55230712890625 +81330 0.572540283203125 +81331 0.49334716796875 +81332 0.498138427734375 +81333 0.429534912109375 +81334 0.439453125 +81335 0.378997802734375 +81336 0.375518798828125 +81337 0.323822021484375 +81338 0.274505615234375 +81339 0.236785888671875 +81340 0.1087646484375 +81341 0.09423828125 +81342 -0.099395751953125 +81343 -0.084686279296875 +81344 -0.3182373046875 +81345 -0.272735595703125 +81346 -0.5489501953125 +81347 -0.470916748046875 +81348 -0.7738037109375 +81349 -0.663970947265625 +81350 -0.86383056640625 +81351 -0.806549072265625 +81352 -0.870391845703125 +81353 -0.856231689453125 +81354 -0.86895751953125 +81355 -0.856201171875 +81356 -0.861053466796875 +81357 -0.81732177734375 +81358 -0.765869140625 +81359 -0.697235107421875 +81360 -0.5301513671875 +81361 -0.5001220703125 +81362 -0.214691162109375 +81363 -0.23211669921875 +81364 0.137359619140625 +81365 0.069915771484375 +81366 0.474822998046875 +81367 0.36199951171875 +81368 0.76239013671875 +81369 0.613677978515625 +81370 0.867462158203125 +81371 0.801849365234375 +81372 0.870361328125 +81373 0.86236572265625 +81374 0.86480712890625 +81375 0.8680419921875 +81376 0.831817626953125 +81377 0.8662109375 +81378 0.677581787109375 +81379 0.85919189453125 +81380 0.495880126953125 +81381 0.790435791015625 +81382 0.30767822265625 +81383 0.6563720703125 +81384 0.116180419921875 +81385 0.497283935546875 +81386 -0.110748291015625 +81387 0.286041259765625 +81388 -0.381805419921875 +81389 0.016754150390625 +81390 -0.6572265625 +81391 -0.27392578125 +81392 -0.857421875 +81393 -0.534698486328125 +81394 -0.870391845703125 +81395 -0.728790283203125 +81396 -0.870391845703125 +81397 -0.850006103515625 +81398 -0.86444091796875 +81399 -0.86181640625 +81400 -0.85723876953125 +81401 -0.86749267578125 +81402 -0.790008544921875 +81403 -0.86932373046875 +81404 -0.62847900390625 +81405 -0.862274169921875 +81406 -0.3956298828125 +81407 -0.776763916015625 +81408 -0.126708984375 +81409 -0.5716552734375 +81410 0.150115966796875 +81411 -0.333831787109375 +81412 0.424041748046875 +81413 -0.073638916015625 +81414 0.670623779296875 +81415 0.186065673828125 +81416 0.854522705078125 +81417 0.4127197265625 +81418 0.866485595703125 +81419 0.59124755859375 +81420 0.86920166015625 +81421 0.708526611328125 +81422 0.8653564453125 +81423 0.779205322265625 +81424 0.857147216796875 +81425 0.81414794921875 +81426 0.766845703125 +81427 0.81085205078125 +81428 0.628509521484375 +81429 0.773590087890625 +81430 0.462127685546875 +81431 0.696990966796875 +81432 0.297210693359375 +81433 0.602569580078125 +81434 0.14862060546875 +81435 0.5008544921875 +81436 -0.00537109375 +81437 0.373443603515625 +81438 -0.15753173828125 +81439 0.2269287109375 +81440 -0.31304931640625 +81441 0.05877685546875 +81442 -0.48876953125 +81443 -0.142120361328125 +81444 -0.6416015625 +81445 -0.33673095703125 +81446 -0.751373291015625 +81447 -0.50433349609375 +81448 -0.84619140625 +81449 -0.663665771484375 +81450 -0.861297607421875 +81451 -0.802398681640625 +81452 -0.863250732421875 +81453 -0.858734130859375 +81454 -0.856597900390625 +81455 -0.86053466796875 +81456 -0.7498779296875 +81457 -0.855377197265625 +81458 -0.624542236328125 +81459 -0.798858642578125 +81460 -0.47808837890625 +81461 -0.701324462890625 +81462 -0.253387451171875 +81463 -0.521881103515625 +81464 0.003692626953125 +81465 -0.2984619140625 +81466 0.2257080078125 +81467 -0.087799072265625 +81468 0.427154541015625 +81469 0.12005615234375 +81470 0.643218994140625 +81471 0.351409912109375 +81472 0.855926513671875 +81473 0.59796142578125 +81474 0.870361328125 +81475 0.8116455078125 +81476 0.870361328125 +81477 0.86505126953125 +81478 0.862762451171875 +81479 0.870361328125 +81480 0.79669189453125 +81481 0.868133544921875 +81482 0.595794677734375 +81483 0.857696533203125 +81484 0.362152099609375 +81485 0.737945556640625 +81486 0.1270751953125 +81487 0.56536865234375 +81488 -0.086944580078125 +81489 0.3843994140625 +81490 -0.2784423828125 +81491 0.197235107421875 +81492 -0.484832763671875 +81493 -0.024627685546875 +81494 -0.729583740234375 +81495 -0.297027587890625 +81496 -0.86688232421875 +81497 -0.578582763671875 +81498 -0.870391845703125 +81499 -0.817596435546875 +81500 -0.86859130859375 +81501 -0.870391845703125 +81502 -0.86279296875 +81503 -0.870391845703125 +81504 -0.817962646484375 +81505 -0.863525390625 +81506 -0.6116943359375 +81507 -0.78167724609375 +81508 -0.3128662109375 +81509 -0.534423828125 +81510 0.039398193359375 +81511 -0.228057861328125 +81512 0.422821044921875 +81513 0.11773681640625 +81514 0.805145263671875 +81515 0.47430419921875 +81516 0.870361328125 +81517 0.786285400390625 +81518 0.870361328125 +81519 0.870361328125 +81520 0.860015869140625 +81521 0.870361328125 +81522 0.727935791015625 +81523 0.861175537109375 +81524 0.48114013671875 +81525 0.755401611328125 +81526 0.2059326171875 +81527 0.55078125 +81528 -0.06103515625 +81529 0.33154296875 +81530 -0.29913330078125 +81531 0.115203857421875 +81532 -0.516204833984375 +81533 -0.10296630859375 +81534 -0.7252197265625 +81535 -0.3309326171875 +81536 -0.85980224609375 +81537 -0.546051025390625 +81538 -0.870391845703125 +81539 -0.72052001953125 +81540 -0.870391845703125 +81541 -0.833038330078125 +81542 -0.858062744140625 +81543 -0.848785400390625 +81544 -0.673004150390625 +81545 -0.77154541015625 +81546 -0.42694091796875 +81547 -0.653289794921875 +81548 -0.2100830078125 +81549 -0.540252685546875 +81550 -0.0362548828125 +81551 -0.440765380859375 +81552 0.10943603515625 +81553 -0.340789794921875 +81554 0.23516845703125 +81555 -0.233184814453125 +81556 0.373687744140625 +81557 -0.091888427734375 +81558 0.517791748046875 +81559 0.07501220703125 +81560 0.602783203125 +81561 0.21099853515625 +81562 0.635711669921875 +81563 0.317779541015625 +81564 0.655181884765625 +81565 0.42242431640625 +81566 0.65948486328125 +81567 0.5184326171875 +81568 0.651275634765625 +81569 0.602813720703125 +81570 0.61846923828125 +81571 0.66070556640625 +81572 0.53753662109375 +81573 0.668243408203125 +81574 0.404144287109375 +81575 0.618133544921875 +81576 0.22186279296875 +81577 0.510498046875 +81578 0.003997802734375 +81579 0.354461669921875 +81580 -0.22100830078125 +81581 0.172698974609375 +81582 -0.42449951171875 +81583 -0.010772705078125 +81584 -0.579833984375 +81585 -0.172576904296875 +81586 -0.641876220703125 +81587 -0.273193359375 +81588 -0.6177978515625 +81589 -0.315338134765625 +81590 -0.575531005859375 +81591 -0.35125732421875 +81592 -0.526336669921875 +81593 -0.386138916015625 +81594 -0.42645263671875 +81595 -0.37969970703125 +81596 -0.2581787109375 +81597 -0.31317138671875 +81598 -0.068695068359375 +81599 -0.22161865234375 +81600 0.09222412109375 +81601 -0.142730712890625 +81602 0.232147216796875 +81603 -0.067657470703125 +81604 0.3509521484375 +81605 0.005279541015625 +81606 0.410064697265625 +81607 0.045196533203125 +81608 0.372955322265625 +81609 0.02203369140625 +81610 0.2554931640625 +81611 -0.05194091796875 +81612 0.10711669921875 +81613 -0.1376953125 +81614 -0.052886962890625 +81615 -0.221771240234375 +81616 -0.186279296875 +81617 -0.27557373046875 +81618 -0.23291015625 +81619 -0.25286865234375 +81620 -0.209442138671875 +81621 -0.17083740234375 +81622 -0.174163818359375 +81623 -0.080963134765625 +81624 -0.126739501953125 +81625 0.01373291015625 +81626 -0.048126220703125 +81627 0.12603759765625 +81628 0.0426025390625 +81629 0.2379150390625 +81630 0.10748291015625 +81631 0.316375732421875 +81632 0.1409912109375 +81633 0.3558349609375 +81634 0.19708251953125 +81635 0.400482177734375 +81636 0.273651123046875 +81637 0.4490966796875 +81638 0.31768798828125 +81639 0.459136962890625 +81640 0.341094970703125 +81641 0.442169189453125 +81642 0.368011474609375 +81643 0.42034912109375 +81644 0.37249755859375 +81645 0.37493896484375 +81646 0.30072021484375 +81647 0.264373779296875 +81648 0.1517333984375 +81649 0.09075927734375 +81650 -0.01470947265625 +81651 -0.09393310546875 +81652 -0.1883544921875 +81653 -0.27874755859375 +81654 -0.372711181640625 +81655 -0.464447021484375 +81656 -0.51397705078125 +81657 -0.6051025390625 +81658 -0.57177734375 +81659 -0.666351318359375 +81660 -0.53948974609375 +81661 -0.642333984375 +81662 -0.43511962890625 +81663 -0.548065185546875 +81664 -0.2962646484375 +81665 -0.415557861328125 +81666 -0.161102294921875 +81667 -0.277679443359375 +81668 -0.0435791015625 +81669 -0.1474609375 +81670 0.060394287109375 +81671 -0.0235595703125 +81672 0.13665771484375 +81673 0.080596923828125 +81674 0.170135498046875 +81675 0.150726318359375 +81676 0.16552734375 +81677 0.188323974609375 +81678 0.15728759765625 +81679 0.218841552734375 +81680 0.150787353515625 +81681 0.244720458984375 +81682 0.12200927734375 +81683 0.2452392578125 +81684 0.080108642578125 +81685 0.226654052734375 +81686 0.05126953125 +81687 0.209320068359375 +81688 0.062896728515625 +81689 0.21514892578125 +81690 0.09271240234375 +81691 0.226715087890625 +81692 0.092987060546875 +81693 0.206756591796875 +81694 0.07855224609375 +81695 0.16845703125 +81696 0.06427001953125 +81697 0.125335693359375 +81698 0.0347900390625 +81699 0.06695556640625 +81700 -0.01171875 +81701 -0.006195068359375 +81702 -0.056060791015625 +81703 -0.07672119140625 +81704 -0.055511474609375 +81705 -0.108551025390625 +81706 -0.010467529296875 +81707 -0.100341796875 +81708 0.02508544921875 +81709 -0.0938720703125 +81710 0.025665283203125 +81711 -0.1085205078125 +81712 0.017333984375 +81713 -0.122802734375 +81714 0.00189208984375 +81715 -0.135101318359375 +81716 -0.03173828125 +81717 -0.15447998046875 +81718 -0.071502685546875 +81719 -0.171966552734375 +81720 -0.13543701171875 +81721 -0.20294189453125 +81722 -0.219970703125 +81723 -0.245819091796875 +81724 -0.300506591796875 +81725 -0.28240966796875 +81726 -0.376312255859375 +81727 -0.313720703125 +81728 -0.416107177734375 +81729 -0.31634521484375 +81730 -0.371124267578125 +81731 -0.25286865234375 +81732 -0.242279052734375 +81733 -0.125457763671875 +81734 -0.069732666015625 +81735 0.032470703125 +81736 0.125640869140625 +81737 0.2032470703125 +81738 0.31268310546875 +81739 0.361328125 +81740 0.45501708984375 +81741 0.47735595703125 +81742 0.554779052734375 +81743 0.553070068359375 +81744 0.61065673828125 +81745 0.58782958984375 +81746 0.610931396484375 +81747 0.572967529296875 +81748 0.531463623046875 +81749 0.49017333984375 +81750 0.3883056640625 +81751 0.353424072265625 +81752 0.23468017578125 +81753 0.206634521484375 +81754 0.095245361328125 +81755 0.07086181640625 +81756 -0.00396728515625 +81757 -0.03173828125 +81758 -0.04852294921875 +81759 -0.088409423828125 +81760 -0.055145263671875 +81761 -0.11138916015625 +81762 -0.0758056640625 +81763 -0.14141845703125 +81764 -0.138702392578125 +81765 -0.200439453125 +81766 -0.209197998046875 +81767 -0.260406494140625 +81768 -0.289031982421875 +81769 -0.322662353515625 +81770 -0.37884521484375 +81771 -0.387969970703125 +81772 -0.456329345703125 +81773 -0.43896484375 +81774 -0.51641845703125 +81775 -0.472320556640625 +81776 -0.519287109375 +81777 -0.45709228515625 +81778 -0.458251953125 +81779 -0.38897705078125 +81780 -0.384796142578125 +81781 -0.31024169921875 +81782 -0.323699951171875 +81783 -0.241851806640625 +81784 -0.269287109375 +81785 -0.180267333984375 +81786 -0.1951904296875 +81787 -0.105377197265625 +81788 -0.100006103515625 +81789 -0.016815185546875 +81790 -0.01055908203125 +81791 0.063323974609375 +81792 0.1033935546875 +81793 0.158905029296875 +81794 0.24908447265625 +81795 0.275604248046875 +81796 0.373199462890625 +81797 0.370880126953125 +81798 0.45806884765625 +81799 0.430938720703125 +81800 0.511474609375 +81801 0.4625244140625 +81802 0.565399169921875 +81803 0.491973876953125 +81804 0.61138916015625 +81805 0.5133056640625 +81806 0.5897216796875 +81807 0.479644775390625 +81808 0.4906005859375 +81809 0.384033203125 +81810 0.33148193359375 +81811 0.241363525390625 +81812 0.147796630859375 +81813 0.080780029296875 +81814 -0.01873779296875 +81815 -0.06365966796875 +81816 -0.140289306640625 +81817 -0.169158935546875 +81818 -0.191986083984375 +81819 -0.215423583984375 +81820 -0.184295654296875 +81821 -0.210662841796875 +81822 -0.161834716796875 +81823 -0.19061279296875 +81824 -0.166595458984375 +81825 -0.189056396484375 +81826 -0.19390869140625 +81827 -0.20263671875 +81828 -0.22442626953125 +81829 -0.216400146484375 +81830 -0.279754638671875 +81831 -0.248291015625 +81832 -0.3389892578125 +81833 -0.282318115234375 +81834 -0.3543701171875 +81835 -0.28106689453125 +81836 -0.348175048828125 +81837 -0.2630615234375 +81838 -0.32598876953125 +81839 -0.23345947265625 +81840 -0.2581787109375 +81841 -0.169189453125 +81842 -0.139801025390625 +81843 -0.066802978515625 +81844 0.014617919921875 +81845 0.061767578125 +81846 0.144378662109375 +81847 0.167694091796875 +81848 0.221038818359375 +81849 0.228240966796875 +81850 0.27069091796875 +81851 0.264404296875 +81852 0.294036865234375 +81853 0.277008056640625 +81854 0.311767578125 +81855 0.28302001953125 +81856 0.339141845703125 +81857 0.295135498046875 +81858 0.360260009765625 +81859 0.301116943359375 +81860 0.360504150390625 +81861 0.2899169921875 +81862 0.308380126953125 +81863 0.23724365234375 +81864 0.18170166015625 +81865 0.12615966796875 +81866 0.0047607421875 +81867 -0.0234375 +81868 -0.17559814453125 +81869 -0.173980712890625 +81870 -0.3143310546875 +81871 -0.289398193359375 +81872 -0.36785888671875 +81873 -0.3349609375 +81874 -0.36248779296875 +81875 -0.331390380859375 +81876 -0.343536376953125 +81877 -0.314605712890625 +81878 -0.3018798828125 +81879 -0.277557373046875 +81880 -0.231414794921875 +81881 -0.2156982421875 +81882 -0.117645263671875 +81883 -0.117919921875 +81884 0.007049560546875 +81885 -0.01031494140625 +81886 0.087982177734375 +81887 0.063262939453125 +81888 0.13946533203125 +81889 0.11358642578125 +81890 0.17425537109375 +81891 0.150238037109375 +81892 0.188201904296875 +81893 0.169464111328125 +81894 0.171234130859375 +81895 0.162841796875 +81896 0.118438720703125 +81897 0.126190185546875 +81898 0.05706787109375 +81899 0.080841064453125 +81900 -0.010711669921875 +81901 0.0283203125 +81902 -0.0914306640625 +81903 -0.036468505859375 +81904 -0.162322998046875 +81905 -0.09539794921875 +81906 -0.194549560546875 +81907 -0.125457763671875 +81908 -0.1492919921875 +81909 -0.095611572265625 +81910 -0.02166748046875 +81911 -0.0015869140625 +81912 0.124053955078125 +81913 0.106109619140625 +81914 0.211151123046875 +81915 0.16717529296875 +81916 0.240447998046875 +81917 0.182708740234375 +81918 0.242218017578125 +81919 0.17706298828125 +81920 0.2257080078125 +81921 0.157440185546875 +81922 0.194366455078125 +81923 0.12713623046875 +81924 0.115509033203125 +81925 0.062164306640625 +81926 0.0128173828125 +81927 -0.01922607421875 +81928 -0.053802490234375 +81929 -0.071380615234375 +81930 -0.110626220703125 +81931 -0.1142578125 +81932 -0.199493408203125 +81933 -0.179779052734375 +81934 -0.29437255859375 +81935 -0.248321533203125 +81936 -0.33221435546875 +81937 -0.272216796875 +81938 -0.27972412109375 +81939 -0.22650146484375 +81940 -0.185333251953125 +81941 -0.148345947265625 +81942 -0.128204345703125 +81943 -0.0982666015625 +81944 -0.115692138671875 +81945 -0.08221435546875 +81946 -0.116455078125 +81947 -0.07672119140625 +81948 -0.105926513671875 +81949 -0.0634765625 +81950 -0.053955078125 +81951 -0.01983642578125 +81952 0.048797607421875 +81953 0.06109619140625 +81954 0.157318115234375 +81955 0.145050048828125 +81956 0.212005615234375 +81957 0.1866455078125 +81958 0.218475341796875 +81959 0.190185546875 +81960 0.23724365234375 +81961 0.201812744140625 +81962 0.30535888671875 +81963 0.2498779296875 +81964 0.38128662109375 +81965 0.303009033203125 +81966 0.404449462890625 +81967 0.315399169921875 +81968 0.3944091796875 +81969 0.302276611328125 +81970 0.3885498046875 +81971 0.292327880859375 +81972 0.362640380859375 +81973 0.2674560546875 +81974 0.27362060546875 +81975 0.195220947265625 +81976 0.11712646484375 +81977 0.072540283203125 +81978 -0.054901123046875 +81979 -0.0609130859375 +81980 -0.19085693359375 +81981 -0.165802001953125 +81982 -0.28570556640625 +81983 -0.238250732421875 +81984 -0.339263916015625 +81985 -0.278167724609375 +81986 -0.3775634765625 +81987 -0.305389404296875 +81988 -0.445709228515625 +81989 -0.354339599609375 +81990 -0.535064697265625 +81991 -0.41864013671875 +81992 -0.629058837890625 +81993 -0.48590087890625 +81994 -0.697601318359375 +81995 -0.53350830078125 +81996 -0.70391845703125 +81997 -0.53375244140625 +81998 -0.6424560546875 +81999 -0.482666015625 +82000 -0.491241455078125 +82001 -0.36376953125 +82002 -0.265716552734375 +82003 -0.188995361328125 +82004 -0.023712158203125 +82005 -0.002471923828125 +82006 0.201751708984375 +82007 0.170562744140625 +82008 0.375823974609375 +82009 0.303558349609375 +82010 0.485076904296875 +82011 0.38629150390625 +82012 0.56884765625 +82013 0.448699951171875 +82014 0.634765625 +82015 0.496673583984375 +82016 0.63763427734375 +82017 0.49603271484375 +82018 0.5660400390625 +82019 0.438232421875 +82020 0.4720458984375 +82021 0.363037109375 +82022 0.40692138671875 +82023 0.30963134765625 +82024 0.3778076171875 +82025 0.28369140625 +82026 0.376953125 +82027 0.279510498046875 +82028 0.371978759765625 +82029 0.272674560546875 +82030 0.313140869140625 +82031 0.225555419921875 +82032 0.184417724609375 +82033 0.126068115234375 +82034 0.011199951171875 +82035 -0.006378173828125 +82036 -0.171051025390625 +82037 -0.14483642578125 +82038 -0.33740234375 +82039 -0.2703857421875 +82040 -0.47198486328125 +82041 -0.37103271484375 +82042 -0.560394287109375 +82043 -0.43597412109375 +82044 -0.58056640625 +82045 -0.448577880859375 +82046 -0.54754638671875 +82047 -0.420440673828125 +82048 -0.508575439453125 +82049 -0.38763427734375 +82050 -0.459503173828125 +82051 -0.34716796875 +82052 -0.394378662109375 +82053 -0.294708251953125 +82054 -0.35260009765625 +82055 -0.260345458984375 +82056 -0.31170654296875 +82057 -0.227142333984375 +82058 -0.197418212890625 +82059 -0.13873291015625 +82060 -0.007965087890625 +82061 0.006134033203125 +82062 0.207489013671875 +82063 0.1700439453125 +82064 0.409210205078125 +82065 0.32281494140625 +82066 0.57208251953125 +82067 0.4454345703125 +82068 0.66595458984375 +82069 0.51507568359375 +82070 0.65875244140625 +82071 0.5074462890625 +82072 0.56744384765625 +82073 0.435577392578125 +82074 0.431396484375 +82075 0.32952880859375 +82076 0.29443359375 +82077 0.2227783203125 +82078 0.182464599609375 +82079 0.135162353515625 +82080 0.06365966796875 +82081 0.0426025390625 +82082 -0.075958251953125 +82083 -0.06536865234375 +82084 -0.189422607421875 +82085 -0.152984619140625 +82086 -0.271942138671875 +82087 -0.216552734375 +82088 -0.342529296875 +82089 -0.270477294921875 +82090 -0.364166259765625 +82091 -0.286651611328125 +82092 -0.327239990234375 +82093 -0.257781982421875 +82094 -0.2769775390625 +82095 -0.218292236328125 +82096 -0.253692626953125 +82097 -0.19891357421875 +82098 -0.24365234375 +82099 -0.189300537109375 +82100 -0.1983642578125 +82101 -0.152740478515625 +82102 -0.116241455078125 +82103 -0.088134765625 +82104 -0.036834716796875 +82105 -0.025634765625 +82106 0.034881591796875 +82107 0.03082275390625 +82108 0.09124755859375 +82109 0.0753173828125 +82110 0.10888671875 +82111 0.089996337890625 +82112 0.125518798828125 +82113 0.10345458984375 +82114 0.15771484375 +82115 0.1282958984375 +82116 0.17828369140625 +82117 0.143829345703125 +82118 0.17108154296875 +82119 0.137786865234375 +82120 0.129974365234375 +82121 0.105560302734375 +82122 0.082427978515625 +82123 0.068084716796875 +82124 0.027679443359375 +82125 0.02490234375 +82126 -0.065643310546875 +82127 -0.0477294921875 +82128 -0.15936279296875 +82129 -0.1207275390625 +82130 -0.21307373046875 +82131 -0.16326904296875 +82132 -0.234649658203125 +82133 -0.1812744140625 +82134 -0.2001953125 +82135 -0.156463623046875 +82136 -0.119171142578125 +82137 -0.095977783203125 +82138 -0.024749755859375 +82139 -0.024993896484375 +82140 0.085784912109375 +82141 0.05859375 +82142 0.178131103515625 +82143 0.12872314453125 +82144 0.215576171875 +82145 0.157501220703125 +82146 0.211456298828125 +82147 0.154998779296875 +82148 0.17523193359375 +82149 0.128387451171875 +82150 0.128753662109375 +82151 0.094207763671875 +82152 0.1019287109375 +82153 0.07513427734375 +82154 0.0743408203125 +82155 0.05560302734375 +82156 0.04327392578125 +82157 0.033416748046875 +82158 0.038177490234375 +82159 0.030914306640625 +82160 0.076263427734375 +82161 0.06109619140625 +82162 0.14105224609375 +82163 0.11138916015625 +82164 0.186431884765625 +82165 0.14666748046875 +82166 0.188812255859375 +82167 0.148956298828125 +82168 0.1390380859375 +82169 0.111297607421875 +82170 0.041778564453125 +82171 0.0372314453125 +82172 -0.079437255859375 +82173 -0.0552978515625 +82174 -0.219390869140625 +82175 -0.162322998046875 +82176 -0.367828369140625 +82177 -0.275665283203125 +82178 -0.494873046875 +82179 -0.372161865234375 +82180 -0.556243896484375 +82181 -0.41900634765625 +82182 -0.508697509765625 +82183 -0.38494873046875 +82184 -0.3756103515625 +82185 -0.287261962890625 +82186 -0.218902587890625 +82187 -0.17132568359375 +82188 -0.063751220703125 +82189 -0.05572509765625 +82190 0.091552734375 +82191 0.060455322265625 +82192 0.23602294921875 +82193 0.168975830078125 +82194 0.342987060546875 +82195 0.25018310546875 +82196 0.39520263671875 +82197 0.29132080078125 +82198 0.389373779296875 +82199 0.289825439453125 +82200 0.324249267578125 +82201 0.244659423828125 +82202 0.224090576171875 +82203 0.173370361328125 +82204 0.124267578125 +82205 0.101654052734375 +82206 0.037078857421875 +82207 0.038421630859375 +82208 -0.010101318359375 +82209 0.003631591796875 +82210 -0.019439697265625 +82211 -0.00421142578125 +82212 -0.022796630859375 +82213 -0.008209228515625 +82214 -0.001556396484375 +82215 0.0052490234375 +82216 0.056304931640625 +82217 0.0450439453125 +82218 0.106719970703125 +82219 0.079254150390625 +82220 0.096893310546875 +82221 0.069610595703125 +82222 0.042694091796875 +82223 0.027801513671875 +82224 -0.018035888671875 +82225 -0.01849365234375 +82226 -0.07586669921875 +82227 -0.06231689453125 +82228 -0.11944580078125 +82229 -0.095306396484375 +82230 -0.15972900390625 +82231 -0.12542724609375 +82232 -0.202606201171875 +82233 -0.15692138671875 +82234 -0.24859619140625 +82235 -0.19012451171875 +82236 -0.30517578125 +82237 -0.23052978515625 +82238 -0.36212158203125 +82239 -0.270751953125 +82240 -0.39141845703125 +82241 -0.290496826171875 +82242 -0.35528564453125 +82243 -0.2623291015625 +82244 -0.249969482421875 +82245 -0.18365478515625 +82246 -0.092864990234375 +82247 -0.067230224609375 +82248 0.08905029296875 +82249 0.067169189453125 +82250 0.2352294921875 +82251 0.175384521484375 +82252 0.318817138671875 +82253 0.237762451171875 +82254 0.358642578125 +82255 0.267913818359375 +82256 0.347747802734375 +82257 0.2607421875 +82258 0.28564453125 +82259 0.215850830078125 +82260 0.223175048828125 +82261 0.170257568359375 +82262 0.196746826171875 +82263 0.15045166015625 +82264 0.179840087890625 +82265 0.137237548828125 +82266 0.155548095703125 +82267 0.118316650390625 +82268 0.151214599609375 +82269 0.11370849609375 +82270 0.156951904296875 +82271 0.116302490234375 +82272 0.13177490234375 +82273 0.0963134765625 +82274 0.100799560546875 +82275 0.0721435546875 +82276 0.087127685546875 +82277 0.060638427734375 +82278 0.05487060546875 +82279 0.035797119140625 +82280 -0.009002685546875 +82281 -0.01177978515625 +82282 -0.10400390625 +82283 -0.081695556640625 +82284 -0.229400634765625 +82285 -0.173370361328125 +82286 -0.35552978515625 +82287 -0.26519775390625 +82288 -0.441925048828125 +82289 -0.327728271484375 +82290 -0.473846435546875 +82291 -0.350311279296875 +82292 -0.464813232421875 +82293 -0.342803955078125 +82294 -0.419097900390625 +82295 -0.308349609375 +82296 -0.334320068359375 +82297 -0.245269775390625 +82298 -0.227935791015625 +82299 -0.1663818359375 +82300 -0.12347412109375 +82301 -0.088897705078125 +82302 -0.02764892578125 +82303 -0.01776123046875 +82304 0.077667236328125 +82305 0.060150146484375 +82306 0.2132568359375 +82307 0.159881591796875 +82308 0.38885498046875 +82309 0.2884521484375 +82310 0.582794189453125 +82311 0.4300537109375 +82312 0.734039306640625 +82313 0.54022216796875 +82314 0.800140380859375 +82315 0.58807373046875 +82316 0.7783203125 +82317 0.57159423828125 +82318 0.6651611328125 +82319 0.488372802734375 +82320 0.45965576171875 +82321 0.337738037109375 +82322 0.199188232421875 +82323 0.146942138671875 +82324 -0.050689697265625 +82325 -0.03619384765625 +82326 -0.23297119140625 +82327 -0.17010498046875 +82328 -0.33013916015625 +82329 -0.24200439453125 +82330 -0.368408203125 +82331 -0.2708740234375 +82332 -0.378936767578125 +82333 -0.279327392578125 +82334 -0.376983642578125 +82335 -0.278472900390625 +82336 -0.37969970703125 +82337 -0.280792236328125 +82338 -0.391510009765625 +82339 -0.28948974609375 +82340 -0.385345458984375 +82341 -0.28485107421875 +82342 -0.3419189453125 +82343 -0.252838134765625 +82344 -0.28289794921875 +82345 -0.209228515625 +82346 -0.251617431640625 +82347 -0.185638427734375 +82348 -0.266143798828125 +82349 -0.195281982421875 +82350 -0.273345947265625 +82351 -0.199554443359375 +82352 -0.216796875 +82353 -0.15740966796875 +82354 -0.128265380859375 +82355 -0.092010498046875 +82356 -0.068145751953125 +82357 -0.047393798828125 +82358 -0.0430908203125 +82359 -0.0284423828125 +82360 -0.024444580078125 +82361 -0.014312744140625 +82362 0.020721435546875 +82363 0.018951416015625 +82364 0.124481201171875 +82365 0.094635009765625 +82366 0.25787353515625 +82367 0.191650390625 +82368 0.379119873046875 +82369 0.27960205078125 +82370 0.47991943359375 +82371 0.35247802734375 +82372 0.5281982421875 +82373 0.386962890625 +82374 0.511138916015625 +82375 0.373779296875 +82376 0.456207275390625 +82377 0.332977294921875 +82378 0.407470703125 +82379 0.29669189453125 +82380 0.383758544921875 +82381 0.278656005859375 +82382 0.35687255859375 +82383 0.258392333984375 +82384 0.31182861328125 +82385 0.2249755859375 +82386 0.250885009765625 +82387 0.18011474609375 +82388 0.1654052734375 +82389 0.117523193359375 +82390 0.035247802734375 +82391 0.0225830078125 +82392 -0.142059326171875 +82393 -0.10650634765625 +82394 -0.33563232421875 +82395 -0.24725341796875 +82396 -0.5345458984375 +82397 -0.3917236328125 +82398 -0.72186279296875 +82399 -0.527587890625 +82400 -0.836669921875 +82401 -0.61053466796875 +82402 -0.8326416015625 +82403 -0.606903076171875 +82404 -0.7296142578125 +82405 -0.531158447265625 +82406 -0.582550048828125 +82407 -0.423370361328125 +82408 -0.440093994140625 +82409 -0.3189697265625 +82410 -0.324310302734375 +82411 -0.234100341796875 +82412 -0.20147705078125 +82413 -0.14422607421875 +82414 -0.044647216796875 +82415 -0.02972412109375 +82416 0.103973388671875 +82417 0.078643798828125 +82418 0.202392578125 +82419 0.150299072265625 +82420 0.264495849609375 +82421 0.195343017578125 +82422 0.338897705078125 +82423 0.249176025390625 +82424 0.443817138671875 +82425 0.3250732421875 +82426 0.545074462890625 +82427 0.398223876953125 +82428 0.6173095703125 +82429 0.4501953125 +82430 0.6524658203125 +82431 0.47515869140625 +82432 0.66339111328125 +82433 0.482147216796875 +82434 0.6561279296875 +82435 0.47540283203125 +82436 0.606781005859375 +82437 0.438232421875 +82438 0.501190185546875 +82439 0.3609619140625 +82440 0.352783203125 +82441 0.253143310546875 +82442 0.176544189453125 +82443 0.125518798828125 +82444 -0.034820556640625 +82445 -0.02667236328125 +82446 -0.258209228515625 +82447 -0.187042236328125 +82448 -0.44244384765625 +82449 -0.3197021484375 +82450 -0.5753173828125 +82451 -0.415863037109375 +82452 -0.65203857421875 +82453 -0.47198486328125 +82454 -0.641632080078125 +82455 -0.4664306640625 +82456 -0.562164306640625 +82457 -0.41168212890625 +82458 -0.458038330078125 +82459 -0.338653564453125 +82460 -0.350555419921875 +82461 -0.26220703125 +82462 -0.260528564453125 +82463 -0.19696044921875 +82464 -0.192108154296875 +82465 -0.145965576171875 +82466 -0.141937255859375 +82467 -0.107086181640625 +82468 -0.1021728515625 +82469 -0.075103759765625 +82470 -0.062896728515625 +82471 -0.0433349609375 +82472 -0.011932373046875 +82473 -0.003570556640625 +82474 0.062835693359375 +82475 0.052398681640625 +82476 0.148712158203125 +82477 0.11553955078125 +82478 0.241729736328125 +82479 0.182861328125 +82480 0.34912109375 +82481 0.259307861328125 +82482 0.457305908203125 +82483 0.33538818359375 +82484 0.54388427734375 +82485 0.395477294921875 +82486 0.5728759765625 +82487 0.41461181640625 +82488 0.506591796875 +82489 0.366607666015625 +82490 0.351226806640625 +82491 0.255889892578125 +82492 0.146514892578125 +82493 0.11029052734375 +82494 -0.05523681640625 +82495 -0.033599853515625 +82496 -0.21624755859375 +82497 -0.1492919921875 +82498 -0.334930419921875 +82499 -0.235443115234375 +82500 -0.402984619140625 +82501 -0.286102294921875 +82502 -0.4412841796875 +82503 -0.315643310546875 +82504 -0.49578857421875 +82505 -0.35589599609375 +82506 -0.5601806640625 +82507 -0.402374267578125 +82508 -0.600738525390625 +82509 -0.4315185546875 +82510 -0.584228515625 +82511 -0.420196533203125 +82512 -0.47930908203125 +82513 -0.3465576171875 +82514 -0.27935791015625 +82515 -0.206085205078125 +82516 -0.0089111328125 +82517 -0.01593017578125 +82518 0.268798828125 +82519 0.17974853515625 +82520 0.482818603515625 +82521 0.331451416015625 +82522 0.60369873046875 +82523 0.41851806640625 +82524 0.650421142578125 +82525 0.453948974609375 +82526 0.66400146484375 +82527 0.466156005859375 +82528 0.6414794921875 +82529 0.45294189453125 +82530 0.572540283203125 +82531 0.406982421875 +82532 0.498138427734375 +82533 0.356689453125 +82534 0.439453125 +82535 0.316741943359375 +82536 0.375518798828125 +82537 0.27252197265625 +82538 0.274505615234375 +82539 0.201873779296875 +82540 0.1087646484375 +82541 0.085601806640625 +82542 -0.099395751953125 +82543 -0.060699462890625 +82544 -0.3182373046875 +82545 -0.214813232421875 +82546 -0.5489501953125 +82547 -0.37750244140625 +82548 -0.7738037109375 +82549 -0.536285400390625 +82550 -0.86383056640625 +82551 -0.6541748046875 +82552 -0.870391845703125 +82553 -0.707916259765625 +82554 -0.86895751953125 +82555 -0.709716796875 +82556 -0.861053466796875 +82557 -0.6685791015625 +82558 -0.765869140625 +82559 -0.5723876953125 +82560 -0.5301513671875 +82561 -0.413238525390625 +82562 -0.214691162109375 +82563 -0.196014404296875 +82564 0.137359619140625 +82565 0.04925537109375 +82566 0.474822998046875 +82567 0.286865234375 +82568 0.76239013671875 +82569 0.492034912109375 +82570 0.867462158203125 +82571 0.64593505859375 +82572 0.870361328125 +82573 0.748748779296875 +82574 0.86480712890625 +82575 0.792327880859375 +82576 0.831817626953125 +82577 0.780303955078125 +82578 0.677581787109375 +82579 0.729522705078125 +82580 0.495880126953125 +82581 0.643951416015625 +82582 0.30767822265625 +82583 0.536376953125 +82584 0.116180419921875 +82585 0.40826416015625 +82586 -0.110748291015625 +82587 0.23748779296875 +82588 -0.381805419921875 +82589 0.019195556640625 +82590 -0.6572265625 +82591 -0.216796875 +82592 -0.857421875 +82593 -0.428802490234375 +82594 -0.870391845703125 +82595 -0.586883544921875 +82596 -0.870391845703125 +82597 -0.68603515625 +82598 -0.86444091796875 +82599 -0.744873046875 +82600 -0.85723876953125 +82601 -0.788177490234375 +82602 -0.790008544921875 +82603 -0.803070068359375 +82604 -0.62847900390625 +82605 -0.751708984375 +82606 -0.3956298828125 +82607 -0.631805419921875 +82608 -0.126708984375 +82609 -0.46612548828125 +82610 0.150115966796875 +82611 -0.273712158203125 +82612 0.424041748046875 +82613 -0.062652587890625 +82614 0.670623779296875 +82615 0.148284912109375 +82616 0.854522705078125 +82617 0.3321533203125 +82618 0.866485595703125 +82619 0.47662353515625 +82620 0.86920166015625 +82621 0.570953369140625 +82622 0.8653564453125 +82623 0.627685546875 +82624 0.857147216796875 +82625 0.65606689453125 +82626 0.766845703125 +82627 0.654022216796875 +82628 0.628509521484375 +82629 0.62506103515625 +82630 0.462127685546875 +82631 0.564422607421875 +82632 0.297210693359375 +82633 0.489990234375 +82634 0.14862060546875 +82635 0.41033935546875 +82636 -0.00537109375 +82637 0.309478759765625 +82638 -0.15753173828125 +82639 0.192626953125 +82640 -0.31304931640625 +82641 0.0572509765625 +82642 -0.48876953125 +82643 -0.10638427734375 +82644 -0.6416015625 +82645 -0.265625 +82646 -0.751373291015625 +82647 -0.4031982421875 +82648 -0.84619140625 +82649 -0.535125732421875 +82650 -0.861297607421875 +82651 -0.651092529296875 +82652 -0.863250732421875 +82653 -0.72796630859375 +82654 -0.856597900390625 +82655 -0.74371337890625 +82656 -0.7498779296875 +82657 -0.706695556640625 +82658 -0.624542236328125 +82659 -0.6571044921875 +82660 -0.47808837890625 +82661 -0.579620361328125 +82662 -0.253387451171875 +82663 -0.433502197265625 +82664 0.003692626953125 +82665 -0.250518798828125 +82666 0.2257080078125 +82667 -0.0782470703125 +82668 0.427154541015625 +82669 0.092041015625 +82670 0.643218994140625 +82671 0.2828369140625 +82672 0.855926513671875 +82673 0.487335205078125 +82674 0.870361328125 +82675 0.665191650390625 +82676 0.870361328125 +82677 0.78173828125 +82678 0.862762451171875 +82679 0.8419189453125 +82680 0.79669189453125 +82681 0.843597412109375 +82682 0.595794677734375 +82683 0.780120849609375 +82684 0.362152099609375 +82685 0.671722412109375 +82686 0.1270751953125 +82687 0.53790283203125 +82688 -0.086944580078125 +82689 0.392822265625 +82690 -0.2784423828125 +82691 0.237640380859375 +82692 -0.484832763671875 +82693 0.04962158203125 +82694 -0.729583740234375 +82695 -0.18304443359375 +82696 -0.86688232421875 +82697 -0.425933837890625 +82698 -0.870391845703125 +82699 -0.63629150390625 +82700 -0.86859130859375 +82701 -0.810211181640625 +82702 -0.86279296875 +82703 -0.864471435546875 +82704 -0.817962646484375 +82705 -0.870391845703125 +82706 -0.6116943359375 +82707 -0.866363525390625 +82708 -0.3128662109375 +82709 -0.83123779296875 +82710 0.039398193359375 +82711 -0.62786865234375 +82712 0.422821044921875 +82713 -0.367095947265625 +82714 0.805145263671875 +82715 -0.07183837890625 +82716 0.870361328125 +82717 0.21209716796875 +82718 0.870361328125 +82719 0.446380615234375 +82720 0.860015869140625 +82721 0.6229248046875 +82722 0.727935791015625 +82723 0.736541748046875 +82724 0.48114013671875 +82725 0.7835693359375 +82726 0.2059326171875 +82727 0.780364990234375 +82728 -0.06103515625 +82729 0.74237060546875 +82730 -0.29913330078125 +82731 0.676849365234375 +82732 -0.516204833984375 +82733 0.574859619140625 +82734 -0.7252197265625 +82735 0.427001953125 +82736 -0.85980224609375 +82737 0.250640869140625 +82738 -0.870391845703125 +82739 0.0694580078125 +82740 -0.870391845703125 +82741 -0.0960693359375 +82742 -0.858062744140625 +82743 -0.21282958984375 +82744 -0.673004150390625 +82745 -0.277374267578125 +82746 -0.42694091796875 +82747 -0.324005126953125 +82748 -0.2100830078125 +82749 -0.381805419921875 +82750 -0.0362548828125 +82751 -0.44915771484375 +82752 0.10943603515625 +82753 -0.50677490234375 +82754 0.23516845703125 +82755 -0.54156494140625 +82756 0.373687744140625 +82757 -0.526397705078125 +82758 0.517791748046875 +82759 -0.46307373046875 +82760 0.602783203125 +82761 -0.394073486328125 +82762 0.635711669921875 +82763 -0.316680908203125 +82764 0.655181884765625 +82765 -0.20953369140625 +82766 0.65948486328125 +82767 -0.079986572265625 +82768 0.651275634765625 +82769 0.065826416015625 +82770 0.61846923828125 +82771 0.210906982421875 +82772 0.53753662109375 +82773 0.330108642578125 +82774 0.404144287109375 +82775 0.41094970703125 +82776 0.22186279296875 +82777 0.446685791015625 +82778 0.003997802734375 +82779 0.43798828125 +82780 -0.22100830078125 +82781 0.39691162109375 +82782 -0.42449951171875 +82783 0.33734130859375 +82784 -0.579833984375 +82785 0.2738037109375 +82786 -0.641876220703125 +82787 0.235137939453125 +82788 -0.6177978515625 +82789 0.217529296875 +82790 -0.575531005859375 +82791 0.1787109375 +82792 -0.526336669921875 +82793 0.1158447265625 +82794 -0.42645263671875 +82795 0.063995361328125 +82796 -0.2581787109375 +82797 0.0419921875 +82798 -0.068695068359375 +82799 0.0262451171875 +82800 0.09222412109375 +82801 -0.008270263671875 +82802 0.232147216796875 +82803 -0.048858642578125 +82804 0.3509521484375 +82805 -0.088531494140625 +82806 0.410064697265625 +82807 -0.1468505859375 +82808 0.372955322265625 +82809 -0.243377685546875 +82810 0.2554931640625 +82811 -0.3643798828125 +82812 0.10711669921875 +82813 -0.47552490234375 +82814 -0.052886962890625 +82815 -0.564239501953125 +82816 -0.186279296875 +82817 -0.60693359375 +82818 -0.23291015625 +82819 -0.566986083984375 +82820 -0.209442138671875 +82821 -0.46002197265625 +82822 -0.174163818359375 +82823 -0.330352783203125 +82824 -0.126739501953125 +82825 -0.1839599609375 +82826 -0.048126220703125 +82827 -0.01470947265625 +82828 0.0426025390625 +82829 0.158294677734375 +82830 0.10748291015625 +82831 0.303802490234375 +82832 0.1409912109375 +82833 0.412841796875 +82834 0.19708251953125 +82835 0.5169677734375 +82836 0.273651123046875 +82837 0.611724853515625 +82838 0.31768798828125 +82839 0.660186767578125 +82840 0.341094970703125 +82841 0.669891357421875 +82842 0.368011474609375 +82843 0.657928466796875 +82844 0.37249755859375 +82845 0.609375 +82846 0.30072021484375 +82847 0.491912841796875 +82848 0.1517333984375 +82849 0.309234619140625 +82850 -0.01470947265625 +82851 0.105987548828125 +82852 -0.1883544921875 +82853 -0.10565185546875 +82854 -0.372711181640625 +82855 -0.32269287109375 +82856 -0.51397705078125 +82857 -0.504302978515625 +82858 -0.57177734375 +82859 -0.619049072265625 +82860 -0.53948974609375 +82861 -0.658721923828125 +82862 -0.43511962890625 +82863 -0.63238525390625 +82864 -0.2962646484375 +82865 -0.56317138671875 +82866 -0.161102294921875 +82867 -0.475799560546875 +82868 -0.0435791015625 +82869 -0.37994384765625 +82870 0.060394287109375 +82871 -0.274444580078125 +82872 0.13665771484375 +82873 -0.171234130859375 +82874 0.170135498046875 +82875 -0.0836181640625 +82876 0.16552734375 +82877 -0.012420654296875 +82878 0.15728759765625 +82879 0.0609130859375 +82880 0.150787353515625 +82881 0.135528564453125 +82882 0.12200927734375 +82883 0.191131591796875 +82884 0.080108642578125 +82885 0.2298583984375 +82886 0.05126953125 +82887 0.265716552734375 +82888 0.062896728515625 +82889 0.31427001953125 +82890 0.09271240234375 +82891 0.358856201171875 +82892 0.092987060546875 +82893 0.366943359375 +82894 0.07855224609375 +82895 0.348388671875 +82896 0.06427001953125 +82897 0.314056396484375 +82898 0.0347900390625 +82899 0.25555419921875 +82900 -0.01171875 +82901 0.174163818359375 +82902 -0.056060791015625 +82903 0.085723876953125 +82904 -0.055511474609375 +82905 0.0220947265625 +82906 -0.010467529296875 +82907 -0.01336669921875 +82908 0.02508544921875 +82909 -0.0528564453125 +82910 0.025665283203125 +82911 -0.109893798828125 +82912 0.017333984375 +82913 -0.164215087890625 +82914 0.00189208984375 +82915 -0.2122802734375 +82916 -0.03173828125 +82917 -0.259674072265625 +82918 -0.071502685546875 +82919 -0.29742431640625 +82920 -0.13543701171875 +82921 -0.3372802734375 +82922 -0.219970703125 +82923 -0.37738037109375 +82924 -0.300506591796875 +82925 -0.402679443359375 +82926 -0.376312255859375 +82927 -0.41455078125 +82928 -0.416107177734375 +82929 -0.394622802734375 +82930 -0.371124267578125 +82931 -0.313262939453125 +82932 -0.242279052734375 +82933 -0.174041748046875 +82934 -0.069732666015625 +82935 -0.006622314453125 +82936 0.125640869140625 +82937 0.1722412109375 +82938 0.31268310546875 +82939 0.33929443359375 +82940 0.45501708984375 +82941 0.46826171875 +82942 0.554779052734375 +82943 0.558929443359375 +82944 0.61065673828125 +82945 0.609161376953125 +82946 0.610931396484375 +82947 0.61090087890625 +82948 0.531463623046875 +82949 0.54901123046875 +82950 0.3883056640625 +82951 0.434844970703125 +82952 0.23468017578125 +82953 0.30450439453125 +82954 0.095245361328125 +82955 0.175994873046875 +82956 -0.00396728515625 +82957 0.0684814453125 +82958 -0.04852294921875 +82959 -0.006134033203125 +82960 -0.055145263671875 +82961 -0.056121826171875 +82962 -0.0758056640625 +82963 -0.11279296875 +82964 -0.138702392578125 +82965 -0.192169189453125 +82966 -0.209197998046875 +82967 -0.269775390625 +82968 -0.289031982421875 +82969 -0.345184326171875 +82970 -0.37884521484375 +82971 -0.41778564453125 +82972 -0.456329345703125 +82973 -0.47259521484375 +82974 -0.51641845703125 +82975 -0.50634765625 +82976 -0.519287109375 +82977 -0.493743896484375 +82978 -0.458251953125 +82979 -0.431488037109375 +82980 -0.384796142578125 +82981 -0.3544921875 +82982 -0.323699951171875 +82983 -0.280670166015625 +82984 -0.269287109375 +82985 -0.20831298828125 +82986 -0.1951904296875 +82987 -0.122406005859375 +82988 -0.100006103515625 +82989 -0.02410888671875 +82990 -0.01055908203125 +82991 0.067169189453125 +82992 0.1033935546875 +82993 0.16937255859375 +82994 0.24908447265625 +82995 0.28582763671875 +82996 0.373199462890625 +82997 0.380859375 +82998 0.45806884765625 +82999 0.44244384765625 +83000 0.511474609375 +83001 0.475494384765625 +83002 0.565399169921875 +83003 0.501129150390625 +83004 0.61138916015625 +83005 0.51458740234375 +83006 0.5897216796875 +83007 0.478179931640625 +83008 0.4906005859375 +83009 0.38690185546875 +83010 0.33148193359375 +83011 0.253692626953125 +83012 0.147796630859375 +83013 0.103271484375 +83014 -0.01873779296875 +83015 -0.0355224609375 +83016 -0.140289306640625 +83017 -0.1429443359375 +83018 -0.191986083984375 +83019 -0.2012939453125 +83020 -0.184295654296875 +83021 -0.216156005859375 +83022 -0.161834716796875 +83023 -0.215576171875 +83024 -0.166595458984375 +83025 -0.22625732421875 +83026 -0.19390869140625 +83027 -0.24493408203125 +83028 -0.22442626953125 +83029 -0.2591552734375 +83030 -0.279754638671875 +83031 -0.283447265625 +83032 -0.3389892578125 +83033 -0.3050537109375 +83034 -0.3543701171875 +83035 -0.294036865234375 +83036 -0.348175048828125 +83037 -0.26611328125 +83038 -0.32598876953125 +83039 -0.226287841796875 +83040 -0.2581787109375 +83041 -0.156768798828125 +83042 -0.139801025390625 +83043 -0.055694580078125 +83044 0.014617919921875 +83045 0.06622314453125 +83046 0.144378662109375 +83047 0.16839599609375 +83048 0.221038818359375 +83049 0.2314453125 +83050 0.27069091796875 +83051 0.271759033203125 +83052 0.294036865234375 +83053 0.28955078125 +83054 0.311767578125 +83055 0.298248291015625 +83056 0.339141845703125 +83057 0.30804443359375 +83058 0.360260009765625 +83059 0.3089599609375 +83060 0.360504150390625 +83061 0.292388916015625 +83062 0.308380126953125 +83063 0.239501953125 +83064 0.18170166015625 +83065 0.13751220703125 +83066 0.0047607421875 +83067 0.00311279296875 +83068 -0.17559814453125 +83069 -0.1328125 +83070 -0.3143310546875 +83071 -0.2406005859375 +83072 -0.36785888671875 +83073 -0.291656494140625 +83074 -0.36248779296875 +83075 -0.30169677734375 +83076 -0.343536376953125 +83077 -0.29876708984375 +83078 -0.3018798828125 +83079 -0.276763916015625 +83080 -0.231414794921875 +83081 -0.231689453125 +83082 -0.117645263671875 +83083 -0.154571533203125 +83084 0.007049560546875 +83085 -0.0662841796875 +83086 0.087982177734375 +83087 -0.00201416015625 +83088 0.13946533203125 +83089 0.046417236328125 +83090 0.17425537109375 +83091 0.08612060546875 +83092 0.188201904296875 +83093 0.113433837890625 +83094 0.171234130859375 +83095 0.1209716796875 +83096 0.118438720703125 +83097 0.104644775390625 +83098 0.05706787109375 +83099 0.080810546875 +83100 -0.010711669921875 +83101 0.050048828125 +83102 -0.0914306640625 +83103 0.00762939453125 +83104 -0.162322998046875 +83105 -0.0323486328125 +83106 -0.194549560546875 +83107 -0.051849365234375 +83108 -0.1492919921875 +83109 -0.026275634765625 +83110 -0.02166748046875 +83111 0.047698974609375 +83112 0.124053955078125 +83113 0.12994384765625 +83114 0.211151123046875 +83115 0.172607421875 +83116 0.240447998046875 +83117 0.176971435546875 +83118 0.242218017578125 +83119 0.1629638671875 +83120 0.2257080078125 +83121 0.1373291015625 +83122 0.194366455078125 +83123 0.103057861328125 +83124 0.115509033203125 +83125 0.040252685546875 +83126 0.0128173828125 +83127 -0.035430908203125 +83128 -0.053802490234375 +83129 -0.08563232421875 +83130 -0.110626220703125 +83131 -0.126556396484375 +83132 -0.199493408203125 +83133 -0.18450927734375 +83134 -0.29437255859375 +83135 -0.243011474609375 +83136 -0.33221435546875 +83137 -0.26239013671875 +83138 -0.27972412109375 +83139 -0.221954345703125 +83140 -0.185333251953125 +83141 -0.15277099609375 +83142 -0.128204345703125 +83143 -0.10546875 +83144 -0.115692138671875 +83145 -0.085296630859375 +83146 -0.116455078125 +83147 -0.07318115234375 +83148 -0.105926513671875 +83149 -0.0543212890625 +83150 -0.053955078125 +83151 -0.01031494140625 +83152 0.048797607421875 +83153 0.064178466796875 +83154 0.157318115234375 +83155 0.140228271484375 +83156 0.212005615234375 +83157 0.1798095703125 +83158 0.218475341796875 +83159 0.186279296875 +83160 0.23724365234375 +83161 0.197845458984375 +83162 0.30535888671875 +83163 0.238006591796875 +83164 0.38128662109375 +83165 0.28070068359375 +83166 0.404449462890625 +83167 0.287994384765625 +83168 0.3944091796875 +83169 0.272735595703125 +83170 0.3885498046875 +83171 0.25909423828125 +83172 0.362640380859375 +83173 0.232330322265625 +83174 0.27362060546875 +83175 0.165802001953125 +83176 0.11712646484375 +83177 0.05731201171875 +83178 -0.054901123046875 +83179 -0.059783935546875 +83180 -0.19085693359375 +83181 -0.152435302734375 +83182 -0.28570556640625 +83183 -0.2171630859375 +83184 -0.339263916015625 +83185 -0.253662109375 +83186 -0.3775634765625 +83187 -0.278289794921875 +83188 -0.445709228515625 +83189 -0.319610595703125 +83190 -0.535064697265625 +83191 -0.372314453125 +83192 -0.629058837890625 +83193 -0.42620849609375 +83194 -0.697601318359375 +83195 -0.46258544921875 +83196 -0.70391845703125 +83197 -0.458648681640625 +83198 -0.6424560546875 +83199 -0.411346435546875 +83200 -0.491241455078125 +83201 -0.3077392578125 +83202 -0.265716552734375 +83203 -0.158172607421875 +83204 -0.023712158203125 +83205 0.0010986328125 +83206 0.201751708984375 +83207 0.14935302734375 +83208 0.375823974609375 +83209 0.264892578125 +83210 0.485076904296875 +83211 0.339019775390625 +83212 0.56884765625 +83213 0.394866943359375 +83214 0.634765625 +83215 0.436798095703125 +83216 0.63763427734375 +83217 0.43768310546875 +83218 0.5660400390625 +83219 0.390777587890625 +83220 0.4720458984375 +83221 0.327667236328125 +83222 0.40692138671875 +83223 0.279541015625 +83224 0.3778076171875 +83225 0.25128173828125 +83226 0.376953125 +83227 0.2388916015625 +83228 0.371978759765625 +83229 0.2236328125 +83230 0.313140869140625 +83231 0.176361083984375 +83232 0.184417724609375 +83233 0.088104248046875 +83234 0.011199951171875 +83235 -0.025299072265625 +83236 -0.171051025390625 +83237 -0.142059326171875 +83238 -0.33740234375 +83239 -0.24688720703125 +83240 -0.47198486328125 +83241 -0.330047607421875 +83242 -0.560394287109375 +83243 -0.38287353515625 +83244 -0.58056640625 +83245 -0.3922119140625 +83246 -0.54754638671875 +83247 -0.367340087890625 +83248 -0.508575439453125 +83249 -0.3369140625 +83250 -0.459503173828125 +83251 -0.298919677734375 +83252 -0.394378662109375 +83253 -0.250274658203125 +83254 -0.35260009765625 +83255 -0.215118408203125 +83256 -0.31170654296875 +83257 -0.180572509765625 +83258 -0.197418212890625 +83259 -0.102630615234375 +83260 -0.007965087890625 +83261 0.019287109375 +83262 0.207489013671875 +83263 0.155242919921875 +83264 0.409210205078125 +83265 0.281097412109375 +83266 0.57208251953125 +83267 0.38153076171875 +83268 0.66595458984375 +83269 0.43841552734375 +83270 0.65875244140625 +83271 0.4324951171875 +83272 0.56744384765625 +83273 0.374114990234375 +83274 0.431396484375 +83275 0.28717041015625 +83276 0.29443359375 +83277 0.198272705078125 +83278 0.182464599609375 +83279 0.1234130859375 +83280 0.06365966796875 +83281 0.043914794921875 +83282 -0.075958251953125 +83283 -0.048126220703125 +83284 -0.189422607421875 +83285 -0.124114990234375 +83286 -0.271942138671875 +83287 -0.18072509765625 +83288 -0.342529296875 +83289 -0.22900390625 +83290 -0.364166259765625 +83291 -0.2464599609375 +83292 -0.327239990234375 +83293 -0.22711181640625 +83294 -0.2769775390625 +83295 -0.197998046875 +83296 -0.253692626953125 +83297 -0.183319091796875 +83298 -0.24365234375 +83299 -0.174896240234375 +83300 -0.1983642578125 +83301 -0.143829345703125 +83302 -0.116241455078125 +83303 -0.08941650390625 +83304 -0.036834716796875 +83305 -0.03570556640625 +83306 0.034881591796875 +83307 0.013946533203125 +83308 0.09124755859375 +83309 0.054595947265625 +83310 0.10888671875 +83311 0.071807861328125 +83312 0.125518798828125 +83313 0.087860107421875 +83314 0.15771484375 +83315 0.112396240234375 +83316 0.17828369140625 +83317 0.128814697265625 +83318 0.17108154296875 +83319 0.12725830078125 +83320 0.129974365234375 +83321 0.10394287109375 +83322 0.082427978515625 +83323 0.0753173828125 +83324 0.027679443359375 +83325 0.040985107421875 +83326 -0.065643310546875 +83327 -0.01776123046875 +83328 -0.15936279296875 +83329 -0.07781982421875 +83330 -0.21307373046875 +83331 -0.114715576171875 +83332 -0.234649658203125 +83333 -0.132904052734375 +83334 -0.2001953125 +83335 -0.11773681640625 +83336 -0.119171142578125 +83337 -0.074615478515625 +83338 -0.024749755859375 +83339 -0.023101806640625 +83340 0.085784912109375 +83341 0.038665771484375 +83342 0.178131103515625 +83343 0.090362548828125 +83344 0.215576171875 +83345 0.110137939453125 +83346 0.211456298828125 +83347 0.1060791015625 +83348 0.17523193359375 +83349 0.08392333984375 +83350 0.128753662109375 +83351 0.056793212890625 +83352 0.1019287109375 +83353 0.04254150390625 +83354 0.0743408203125 +83355 0.02880859375 +83356 0.04327392578125 +83357 0.0137939453125 +83358 0.038177490234375 +83359 0.014923095703125 +83360 0.076263427734375 +83361 0.04229736328125 +83362 0.14105224609375 +83363 0.08575439453125 +83364 0.186431884765625 +83365 0.117340087890625 +83366 0.188812255859375 +83367 0.1226806640625 +83368 0.1390380859375 +83369 0.0960693359375 +83370 0.041778564453125 +83371 0.040191650390625 +83372 -0.079437255859375 +83373 -0.030914306640625 +83374 -0.219390869140625 +83375 -0.114227294921875 +83376 -0.367828369140625 +83377 -0.20355224609375 +83378 -0.494873046875 +83379 -0.280975341796875 +83380 -0.556243896484375 +83381 -0.31982421875 +83382 -0.508697509765625 +83383 -0.29400634765625 +83384 -0.3756103515625 +83385 -0.217376708984375 +83386 -0.218902587890625 +83387 -0.126922607421875 +83388 -0.063751220703125 +83389 -0.03753662109375 +83390 0.091552734375 +83391 0.051971435546875 +83392 0.23602294921875 +83393 0.13525390625 +83394 0.342987060546875 +83395 0.19647216796875 +83396 0.39520263671875 +83397 0.225433349609375 +83398 0.389373779296875 +83399 0.22027587890625 +83400 0.324249267578125 +83401 0.180328369140625 +83402 0.224090576171875 +83403 0.120147705078125 +83404 0.124267578125 +83405 0.06097412109375 +83406 0.037078857421875 +83407 0.010101318359375 +83408 -0.010101318359375 +83409 -0.01611328125 +83410 -0.019439697265625 +83411 -0.019134521484375 +83412 -0.022796630859375 +83413 -0.018218994140625 +83414 -0.001556396484375 +83415 -0.002349853515625 +83416 0.056304931640625 +83417 0.03546142578125 +83418 0.106719970703125 +83419 0.068634033203125 +83420 0.096893310546875 +83421 0.0653076171875 +83422 0.042694091796875 +83423 0.034912109375 +83424 -0.018035888671875 +83425 0.0 +83426 -0.07586669921875 +83427 -0.033782958984375 +83428 -0.11944580078125 +83429 -0.059661865234375 +83430 -0.15972900390625 +83431 -0.084259033203125 +83432 -0.202606201171875 +83433 -0.11102294921875 +83434 -0.24859619140625 +83435 -0.140167236328125 +83436 -0.30517578125 +83437 -0.17608642578125 +83438 -0.36212158203125 +83439 -0.2125244140625 +83440 -0.39141845703125 +83441 -0.232574462890625 +83442 -0.35528564453125 +83443 -0.21337890625 +83444 -0.249969482421875 +83445 -0.152587890625 +83446 -0.092864990234375 +83447 -0.060516357421875 +83448 0.08905029296875 +83449 0.0467529296875 +83450 0.2352294921875 +83451 0.13299560546875 +83452 0.318817138671875 +83453 0.182159423828125 +83454 0.358642578125 +83455 0.20556640625 +83456 0.347747802734375 +83457 0.199676513671875 +83458 0.28564453125 +83459 0.164825439453125 +83460 0.223175048828125 +83461 0.130279541015625 +83462 0.196746826171875 +83463 0.116424560546875 +83464 0.179840087890625 +83465 0.107940673828125 +83466 0.155548095703125 +83467 0.095001220703125 +83468 0.151214599609375 +83469 0.093017578125 +83470 0.156951904296875 +83471 0.096282958984375 +83472 0.13177490234375 +83473 0.08148193359375 +83474 0.100799560546875 +83475 0.06292724609375 +83476 0.087127685546875 +83477 0.053802490234375 +83478 0.05487060546875 +83479 0.0338134765625 +83480 -0.009002685546875 +83481 -0.004302978515625 +83482 -0.10400390625 +83483 -0.06011962890625 +83484 -0.229400634765625 +83485 -0.133148193359375 +83486 -0.35552978515625 +83487 -0.2064208984375 +83488 -0.441925048828125 +83489 -0.2568359375 +83490 -0.473846435546875 +83491 -0.275970458984375 +83492 -0.464813232421875 +83493 -0.27142333984375 +83494 -0.419097900390625 +83495 -0.245574951171875 +83496 -0.334320068359375 +83497 -0.197113037109375 +83498 -0.227935791015625 +83499 -0.135955810546875 +83500 -0.12347412109375 +83501 -0.075531005859375 +83502 -0.02764892578125 +83503 -0.01971435546875 +83504 0.077667236328125 +83505 0.04168701171875 +83506 0.2132568359375 +83507 0.120361328125 +83508 0.38885498046875 +83509 0.22174072265625 +83510 0.582794189453125 +83511 0.333465576171875 +83512 0.734039306640625 +83513 0.420745849609375 +83514 0.800140380859375 +83515 0.45941162109375 +83516 0.7783203125 +83517 0.44781494140625 +83518 0.6651611328125 +83519 0.384002685546875 +83520 0.45965576171875 +83521 0.26739501953125 +83522 0.199188232421875 +83523 0.119232177734375 +83524 -0.050689697265625 +83525 -0.023223876953125 +83526 -0.23297119140625 +83527 -0.1275634765625 +83528 -0.33013916015625 +83529 -0.183807373046875 +83530 -0.368408203125 +83531 -0.20672607421875 +83532 -0.378936767578125 +83533 -0.2139892578125 +83534 -0.376983642578125 +83535 -0.21417236328125 +83536 -0.37969970703125 +83537 -0.21697998046875 +83538 -0.391510009765625 +83539 -0.224822998046875 +83540 -0.385345458984375 +83541 -0.2222900390625 +83542 -0.3419189453125 +83543 -0.1983642578125 +83544 -0.28289794921875 +83545 -0.165313720703125 +83546 -0.251617431640625 +83547 -0.147735595703125 +83548 -0.266143798828125 +83549 -0.1558837890625 +83550 -0.273345947265625 +83551 -0.15960693359375 +83552 -0.216796875 +83553 -0.12689208984375 +83554 -0.128265380859375 +83555 -0.0758056640625 +83556 -0.068145751953125 +83557 -0.04071044921875 +83558 -0.0430908203125 +83559 -0.025390625 +83560 -0.024444580078125 +83561 -0.013702392578125 +83562 0.020721435546875 +83563 0.013031005859375 +83564 0.124481201171875 +83565 0.07293701171875 +83566 0.25787353515625 +83567 0.149505615234375 +83568 0.379119873046875 +83569 0.218994140625 +83570 0.47991943359375 +83571 0.27667236328125 +83572 0.5281982421875 +83573 0.30426025390625 +83574 0.511138916015625 +83575 0.29449462890625 +83576 0.456207275390625 +83577 0.26300048828125 +83578 0.407470703125 +83579 0.234832763671875 +83580 0.383758544921875 +83581 0.220703125 +83582 0.35687255859375 +83583 0.204620361328125 +83584 0.31182861328125 +83585 0.178131103515625 +83586 0.250885009765625 +83587 0.142578125 +83588 0.1654052734375 +83589 0.093109130859375 +83590 0.035247802734375 +83591 0.018341064453125 +83592 -0.142059326171875 +83593 -0.08306884765625 +83594 -0.33563232421875 +83595 -0.193572998046875 +83596 -0.5345458984375 +83597 -0.306915283203125 +83598 -0.72186279296875 +83599 -0.413482666015625 +83600 -0.836669921875 +83601 -0.4786376953125 +83602 -0.8326416015625 +83603 -0.47607421875 +83604 -0.7296142578125 +83605 -0.4171142578125 +83606 -0.582550048828125 +83607 -0.332977294921875 +83608 -0.440093994140625 +83609 -0.2513427734375 +83610 -0.324310302734375 +83611 -0.184814453125 +83612 -0.20147705078125 +83613 -0.1142578125 +83614 -0.044647216796875 +83615 -0.0244140625 +83616 0.103973388671875 +83617 0.060699462890625 +83618 0.202392578125 +83619 0.1171875 +83620 0.264495849609375 +83621 0.152923583984375 +83622 0.338897705078125 +83623 0.195465087890625 +83624 0.443817138671875 +83625 0.25518798828125 +83626 0.545074462890625 +83627 0.312652587890625 +83628 0.6173095703125 +83629 0.35345458984375 +83630 0.6524658203125 +83631 0.373046875 +83632 0.66339111328125 +83633 0.378753662109375 +83634 0.6561279296875 +83635 0.3740234375 +83636 0.606781005859375 +83637 0.345306396484375 +83638 0.501190185546875 +83639 0.284637451171875 +83640 0.352783203125 +83641 0.199676513671875 +83642 0.176544189453125 +83643 0.09893798828125 +83644 -0.034820556640625 +83645 -0.0216064453125 +83646 -0.258209228515625 +83647 -0.148834228515625 +83648 -0.44244384765625 +83649 -0.253662109375 +83650 -0.5753173828125 +83651 -0.32916259765625 +83652 -0.65203857421875 +83653 -0.37261962890625 +83654 -0.641632080078125 +83655 -0.366455078125 +83656 -0.562164306640625 +83657 -0.320953369140625 +83658 -0.458038330078125 +83659 -0.261383056640625 +83660 -0.350555419921875 +83661 -0.1998291015625 +83662 -0.260528564453125 +83663 -0.14813232421875 +83664 -0.192108154296875 +83665 -0.10870361328125 +83666 -0.141937255859375 +83667 -0.079681396484375 +83668 -0.1021728515625 +83669 -0.056610107421875 +83670 -0.062896728515625 +83671 -0.033905029296875 +83672 -0.011932373046875 +83673 -0.004638671875 +83674 0.062835693359375 +83675 0.037994384765625 +83676 0.148712158203125 +83677 0.086822509765625 +83678 0.241729736328125 +83679 0.139556884765625 +83680 0.34912109375 +83681 0.200347900390625 +83682 0.457305908203125 +83683 0.261505126953125 +83684 0.54388427734375 +83685 0.310302734375 +83686 0.5728759765625 +83687 0.326324462890625 +83688 0.506591796875 +83689 0.2882080078125 +83690 0.351226806640625 +83691 0.199493408203125 +83692 0.146514892578125 +83693 0.082763671875 +83694 -0.05523681640625 +83695 -0.0322265625 +83696 -0.21624755859375 +83697 -0.123992919921875 +83698 -0.334930419921875 +83699 -0.191619873046875 +83700 -0.402984619140625 +83701 -0.23040771484375 +83702 -0.4412841796875 +83703 -0.252197265625 +83704 -0.49578857421875 +83705 -0.2830810546875 +83706 -0.5601806640625 +83707 -0.319488525390625 +83708 -0.600738525390625 +83709 -0.342254638671875 +83710 -0.584228515625 +83711 -0.33258056640625 +83712 -0.47930908203125 +83713 -0.27294921875 +83714 -0.27935791015625 +83715 -0.160308837890625 +83716 -0.0089111328125 +83717 -0.008758544921875 +83718 0.268798828125 +83719 0.14703369140625 +83720 0.482818603515625 +83721 0.268402099609375 +83722 0.60369873046875 +83723 0.339080810546875 +83724 0.650421142578125 +83725 0.368804931640625 +83726 0.66400146484375 +83727 0.37933349609375 +83728 0.6414794921875 +83729 0.368896484375 +83730 0.572540283203125 +83731 0.331939697265625 +83732 0.498138427734375 +83733 0.290496826171875 +83734 0.439453125 +83735 0.256072998046875 +83736 0.375518798828125 +83737 0.217681884765625 +83738 0.274505615234375 +83739 0.1585693359375 +83740 0.1087646484375 +83741 0.064208984375 +83742 -0.099395751953125 +83743 -0.0531005859375 +83744 -0.3182373046875 +83745 -0.175994873046875 +83746 -0.5489501953125 +83747 -0.3048095703125 +83748 -0.7738037109375 +83749 -0.429718017578125 +83750 -0.86383056640625 +83751 -0.52215576171875 +83752 -0.870391845703125 +83753 -0.5640869140625 +83754 -0.86895751953125 +83755 -0.56494140625 +83756 -0.861053466796875 +83757 -0.53173828125 +83758 -0.765869140625 +83759 -0.45526123046875 +83760 -0.5301513671875 +83761 -0.329559326171875 +83762 -0.214691162109375 +83763 -0.15863037109375 +83764 0.137359619140625 +83765 0.034210205078125 +83766 0.474822998046875 +83767 0.22125244140625 +83768 0.76239013671875 +83769 0.3831787109375 +83770 0.867462158203125 +83771 0.505279541015625 +83772 0.870361328125 +83773 0.5875244140625 +83774 0.86480712890625 +83775 0.62347412109375 +83776 0.831817626953125 +83777 0.615814208984375 +83778 0.677581787109375 +83779 0.57745361328125 +83780 0.495880126953125 +83781 0.51141357421875 +83782 0.30767822265625 +83783 0.4276123046875 +83784 0.116180419921875 +83785 0.327239990234375 +83786 -0.110748291015625 +83787 0.193389892578125 +83788 -0.381805419921875 +83789 0.022430419921875 +83790 -0.6572265625 +83791 -0.1624755859375 +83792 -0.857421875 +83793 -0.329071044921875 +83794 -0.870391845703125 +83795 -0.4541015625 +83796 -0.870391845703125 +83797 -0.53350830078125 +83798 -0.86444091796875 +83799 -0.581512451171875 +83800 -0.85723876953125 +83801 -0.6170654296875 +83802 -0.790008544921875 +83803 -0.630126953125 +83804 -0.62847900390625 +83805 -0.59149169921875 +83806 -0.3956298828125 +83807 -0.499359130859375 +83808 -0.126708984375 +83809 -0.37127685546875 +83810 0.150115966796875 +83811 -0.221923828125 +83812 0.424041748046875 +83813 -0.057647705078125 +83814 0.670623779296875 +83815 0.10699462890625 +83816 0.854522705078125 +83817 0.2510986328125 +83818 0.866485595703125 +83819 0.365020751953125 +83820 0.86920166015625 +83821 0.440338134765625 +83822 0.8653564453125 +83823 0.486572265625 +83824 0.857147216796875 +83825 0.5107421875 +83826 0.766845703125 +83827 0.511138916015625 +83828 0.628509521484375 +83829 0.490325927734375 +83830 0.462127685546875 +83831 0.444580078125 +83832 0.297210693359375 +83833 0.38763427734375 +83834 0.14862060546875 +83835 0.3260498046875 +83836 -0.00537109375 +83837 0.247589111328125 +83838 -0.15753173828125 +83839 0.15631103515625 +83840 -0.31304931640625 +83841 0.050384521484375 +83842 -0.48876953125 +83843 -0.077606201171875 +83844 -0.6416015625 +83845 -0.202362060546875 +83846 -0.751373291015625 +83847 -0.31048583984375 +83848 -0.84619140625 +83849 -0.4141845703125 +83850 -0.861297607421875 +83851 -0.50543212890625 +83852 -0.863250732421875 +83853 -0.566314697265625 +83854 -0.856597900390625 +83855 -0.5797119140625 +83856 -0.7498779296875 +83857 -0.55206298828125 +83858 -0.624542236328125 +83859 -0.5142822265625 +83860 -0.47808837890625 +83861 -0.45452880859375 +83862 -0.253387451171875 +83863 -0.341461181640625 +83864 0.003692626953125 +83865 -0.1995849609375 +83866 0.2257080078125 +83867 -0.06561279296875 +83868 0.427154541015625 +83869 0.06707763671875 +83870 0.643218994140625 +83871 0.2156982421875 +83872 0.855926513671875 +83873 0.374969482421875 +83874 0.870361328125 +83875 0.513641357421875 +83876 0.870361328125 +83877 0.60498046875 +83878 0.862762451171875 +83879 0.652679443359375 +83880 0.79669189453125 +83881 0.655029296875 +83882 0.595794677734375 +83883 0.606903076171875 +83884 0.362152099609375 +83885 0.523834228515625 +83886 0.1270751953125 +83887 0.42083740234375 +83888 -0.086944580078125 +83889 0.30926513671875 +83890 -0.2784423828125 +83891 0.19024658203125 +83892 -0.484832763671875 +83893 0.045196533203125 +83894 -0.729583740234375 +83895 -0.13604736328125 +83896 -0.86688232421875 +83897 -0.32623291015625 +83898 -0.870391845703125 +83899 -0.49127197265625 +83900 -0.86859130859375 +83901 -0.628326416015625 +83902 -0.86279296875 +83903 -0.736114501953125 +83904 -0.817962646484375 +83905 -0.795196533203125 +83906 -0.6116943359375 +83907 -0.781097412109375 +83908 -0.3128662109375 +83909 -0.689910888671875 +83910 0.039398193359375 +83911 -0.539581298828125 +83912 0.422821044921875 +83913 -0.340850830078125 +83914 0.805145263671875 +83915 -0.111572265625 +83916 0.870361328125 +83917 0.111663818359375 +83918 0.870361328125 +83919 0.298187255859375 +83920 0.860015869140625 +83921 0.441558837890625 +83922 0.727935791015625 +83923 0.53741455078125 +83924 0.48114013671875 +83925 0.58251953125 +83926 0.2059326171875 +83927 0.589599609375 +83928 -0.06103515625 +83929 0.570526123046875 +83930 -0.29913330078125 +83931 0.53045654296875 +83932 -0.516204833984375 +83933 0.461456298828125 +83934 -0.7252197265625 +83935 0.35516357421875 +83936 -0.85980224609375 +83937 0.22491455078125 +83938 -0.870391845703125 +83939 0.08917236328125 +83940 -0.870391845703125 +83941 -0.0360107421875 +83942 -0.858062744140625 +83943 -0.12432861328125 +83944 -0.673004150390625 +83945 -0.1732177734375 +83946 -0.42694091796875 +83947 -0.21051025390625 +83948 -0.2100830078125 +83949 -0.259613037109375 +83950 -0.0362548828125 +83951 -0.319000244140625 +83952 0.10943603515625 +83953 -0.37274169921875 +83954 0.23516845703125 +83955 -0.40985107421875 +83956 0.373687744140625 +83957 -0.407867431640625 +83958 0.517791748046875 +83959 -0.367645263671875 +83960 0.602783203125 +83961 -0.322845458984375 +83962 0.635711669921875 +83963 -0.27069091796875 +83964 0.655181884765625 +83965 -0.193389892578125 +83966 0.65948486328125 +83967 -0.096435546875 +83968 0.651275634765625 +83969 0.01531982421875 +83970 0.61846923828125 +83971 0.128448486328125 +83972 0.53753662109375 +83973 0.22332763671875 +83974 0.404144287109375 +83975 0.290252685546875 +83976 0.22186279296875 +83977 0.32379150390625 +83978 0.003997802734375 +83979 0.324127197265625 +83980 -0.22100830078125 +83981 0.300018310546875 +83982 -0.42449951171875 +83983 0.261688232421875 +83984 -0.579833984375 +83985 0.219818115234375 +83986 -0.641876220703125 +83987 0.19598388671875 +83988 -0.6177978515625 +83989 0.186981201171875 +83990 -0.575531005859375 +83991 0.16058349609375 +83992 -0.526336669921875 +83993 0.114471435546875 +83994 -0.42645263671875 +83995 0.075225830078125 +83996 -0.2581787109375 +83997 0.057220458984375 +83998 -0.068695068359375 +83999 0.042633056640625 +84000 0.09222412109375 +84001 0.012603759765625 +84002 0.232147216796875 +84003 -0.022918701171875 +84004 0.3509521484375 +84005 -0.058380126953125 +84006 0.410064697265625 +84007 -0.10833740234375 +84008 0.372955322265625 +84009 -0.187286376953125 +84010 0.2554931640625 +84011 -0.28448486328125 +84012 0.10711669921875 +84013 -0.37359619140625 +84014 -0.052886962890625 +84015 -0.44482421875 +84016 -0.186279296875 +84017 -0.4801025390625 +84018 -0.23291015625 +84019 -0.451507568359375 +84020 -0.209442138671875 +84021 -0.370849609375 +84022 -0.174163818359375 +84023 -0.271728515625 +84024 -0.126739501953125 +84025 -0.1588134765625 +84026 -0.048126220703125 +84027 -0.027557373046875 +84028 0.0426025390625 +84029 0.107330322265625 +84030 0.10748291015625 +84031 0.221954345703125 +84032 0.1409912109375 +84033 0.30926513671875 +84034 0.19708251953125 +84035 0.3929443359375 +84036 0.273651123046875 +84037 0.4693603515625 +84038 0.31768798828125 +84039 0.510223388671875 +84040 0.341094970703125 +84041 0.52105712890625 +84042 0.368011474609375 +84043 0.5146484375 +84044 0.37249755859375 +84045 0.47955322265625 +84046 0.30072021484375 +84047 0.39117431640625 +84048 0.1517333984375 +84049 0.252288818359375 +84050 -0.01470947265625 +84051 0.096832275390625 +84052 -0.1883544921875 +84053 -0.06585693359375 +84054 -0.372711181640625 +84055 -0.233367919921875 +84056 -0.51397705078125 +84057 -0.374542236328125 +84058 -0.57177734375 +84059 -0.46533203125 +84060 -0.53948974609375 +84061 -0.499267578125 +84062 -0.43511962890625 +84063 -0.483001708984375 +84064 -0.2962646484375 +84065 -0.433929443359375 +84066 -0.161102294921875 +84067 -0.37060546875 +84068 -0.0435791015625 +84069 -0.30023193359375 +84070 0.060394287109375 +84071 -0.2218017578125 +84072 0.13665771484375 +84073 -0.144317626953125 +84074 0.170135498046875 +84075 -0.077880859375 +84076 0.16552734375 +84077 -0.0230712890625 +84078 0.15728759765625 +84079 0.0340576171875 +84080 0.150787353515625 +84081 0.0927734375 +84082 0.12200927734375 +84083 0.1375732421875 +84084 0.080108642578125 +84085 0.169891357421875 +84086 0.05126953125 +84087 0.200164794921875 +84088 0.062896728515625 +84089 0.240081787109375 +84090 0.09271240234375 +84091 0.276824951171875 +84092 0.092987060546875 +84093 0.2855224609375 +84094 0.07855224609375 +84095 0.273529052734375 +84096 0.06427001953125 +84097 0.248992919921875 +84098 0.0347900390625 +84099 0.205474853515625 +84100 -0.01171875 +84101 0.143951416015625 +84102 -0.056060791015625 +84103 0.076446533203125 +84104 -0.055511474609375 +84105 0.02716064453125 +84106 -0.010467529296875 +84107 -0.00128173828125 +84108 0.02508544921875 +84109 -0.033233642578125 +84110 0.025665283203125 +84111 -0.078826904296875 +84112 0.017333984375 +84113 -0.12255859375 +84114 0.00189208984375 +84115 -0.16156005859375 +84116 -0.03173828125 +84117 -0.199951171875 +84118 -0.071502685546875 +84119 -0.230804443359375 +84120 -0.13543701171875 +84121 -0.26287841796875 +84122 -0.219970703125 +84123 -0.294708251953125 +84124 -0.300506591796875 +84125 -0.314788818359375 +84126 -0.376312255859375 +84127 -0.32415771484375 +84128 -0.416107177734375 +84129 -0.308837890625 +84130 -0.371124267578125 +84131 -0.24639892578125 +84132 -0.242279052734375 +84133 -0.139556884765625 +84134 -0.069732666015625 +84135 -0.01092529296875 +84136 0.125640869140625 +84137 0.126678466796875 +84138 0.31268310546875 +84139 0.2554931640625 +84140 0.45501708984375 +84141 0.355438232421875 +84142 0.554779052734375 +84143 0.426239013671875 +84144 0.61065673828125 +84145 0.466339111328125 +84146 0.610931396484375 +84147 0.46942138671875 +84148 0.531463623046875 +84149 0.423431396484375 +84150 0.3883056640625 +84151 0.3370361328125 +84152 0.23468017578125 +84153 0.238067626953125 +84154 0.095245361328125 +84155 0.140350341796875 +84156 -0.00396728515625 +84157 0.058685302734375 +84158 -0.04852294921875 +84159 0.00213623046875 +84160 -0.055145263671875 +84161 -0.035736083984375 +84162 -0.0758056640625 +84163 -0.079254150390625 +84164 -0.138702392578125 +84165 -0.140869140625 +84166 -0.209197998046875 +84167 -0.2015380859375 +84168 -0.289031982421875 +84169 -0.26092529296875 +84170 -0.37884521484375 +84171 -0.318511962890625 +84172 -0.456329345703125 +84173 -0.362548828125 +84174 -0.51641845703125 +84175 -0.39044189453125 +84176 -0.519287109375 +84177 -0.3824462890625 +84178 -0.458251953125 +84179 -0.335906982421875 +84180 -0.384796142578125 +84181 -0.27783203125 +84182 -0.323699951171875 +84183 -0.22198486328125 +84184 -0.269287109375 +84185 -0.166961669921875 +84186 -0.1951904296875 +84187 -0.101104736328125 +84188 -0.100006103515625 +84189 -0.0252685546875 +84190 -0.01055908203125 +84191 0.045501708984375 +84192 0.1033935546875 +84193 0.1251220703125 +84194 0.24908447265625 +84195 0.216094970703125 +84196 0.373199462890625 +84197 0.290740966796875 +84198 0.45806884765625 +84199 0.33966064453125 +84200 0.511474609375 +84201 0.366607666015625 +84202 0.565399169921875 +84203 0.387908935546875 +84204 0.61138916015625 +84205 0.3997802734375 +84206 0.5897216796875 +84207 0.372894287109375 +84208 0.4906005859375 +84209 0.30328369140625 +84210 0.33148193359375 +84211 0.200958251953125 +84212 0.147796630859375 +84213 0.08502197265625 +84214 -0.01873779296875 +84215 -0.02215576171875 +84216 -0.140289306640625 +84217 -0.10528564453125 +84218 -0.191986083984375 +84219 -0.150665283203125 +84220 -0.184295654296875 +84221 -0.162628173828125 +84222 -0.161834716796875 +84223 -0.16290283203125 +84224 -0.166595458984375 +84225 -0.172088623046875 +84226 -0.19390869140625 +84227 -0.187591552734375 +84228 -0.22442626953125 +84229 -0.199737548828125 +84230 -0.279754638671875 +84231 -0.219635009765625 +84232 -0.3389892578125 +84233 -0.23736572265625 +84234 -0.3543701171875 +84235 -0.22979736328125 +84236 -0.348175048828125 +84237 -0.208984375 +84238 -0.32598876953125 +84239 -0.17877197265625 +84240 -0.2581787109375 +84241 -0.125457763671875 +84242 -0.139801025390625 +84243 -0.047607421875 +84244 0.014617919921875 +84245 0.046539306640625 +84246 0.144378662109375 +84247 0.125701904296875 +84248 0.221038818359375 +84249 0.17498779296875 +84250 0.27069091796875 +84251 0.206939697265625 +84252 0.294036865234375 +84253 0.221649169921875 +84254 0.311767578125 +84255 0.229400634765625 +84256 0.339141845703125 +84257 0.2379150390625 +84258 0.360260009765625 +84259 0.239288330078125 +84260 0.360504150390625 +84261 0.226898193359375 +84262 0.308380126953125 +84263 0.186798095703125 +84264 0.18170166015625 +84265 0.10955810546875 +84266 0.0047607421875 +84267 0.00775146484375 +84268 -0.17559814453125 +84269 -0.095458984375 +84270 -0.3143310546875 +84271 -0.17779541015625 +84272 -0.36785888671875 +84273 -0.2177734375 +84274 -0.36248779296875 +84275 -0.227081298828125 +84276 -0.343536376953125 +84277 -0.226531982421875 +84278 -0.3018798828125 +84279 -0.211456298828125 +84280 -0.231414794921875 +84281 -0.178863525390625 +84282 -0.117645263671875 +84283 -0.1219482421875 +84284 0.007049560546875 +84285 -0.056304931640625 +84286 0.087982177734375 +84287 -0.00823974609375 +84288 0.13946533203125 +84289 0.028350830078125 +84290 0.17425537109375 +84291 0.05877685546875 +84292 0.188201904296875 +84293 0.08026123046875 +84294 0.171234130859375 +84295 0.087188720703125 +84296 0.118438720703125 +84297 0.076446533203125 +84298 0.05706787109375 +84299 0.06011962890625 +84300 -0.010711669921875 +84301 0.03857421875 +84302 -0.0914306640625 +84303 0.008209228515625 +84304 -0.162322998046875 +84305 -0.0205078125 +84306 -0.194549560546875 +84307 -0.0341796875 +84308 -0.1492919921875 +84309 -0.01446533203125 +84310 -0.02166748046875 +84311 0.041107177734375 +84312 0.124053955078125 +84313 0.102569580078125 +84314 0.211151123046875 +84315 0.1341552734375 +84316 0.240447998046875 +84317 0.1368408203125 +84318 0.242218017578125 +84319 0.12554931640625 +84320 0.2257080078125 +84321 0.10540771484375 +84322 0.194366455078125 +84323 0.07867431640625 +84324 0.115509033203125 +84325 0.030548095703125 +84326 0.0128173828125 +84327 -0.02716064453125 +84328 -0.053802490234375 +84329 -0.06573486328125 +84330 -0.110626220703125 +84331 -0.09722900390625 +84332 -0.199493408203125 +84333 -0.1412353515625 +84334 -0.29437255859375 +84335 -0.185455322265625 +84336 -0.33221435546875 +84337 -0.2001953125 +84338 -0.27972412109375 +84339 -0.170013427734375 +84340 -0.185333251953125 +84341 -0.118133544921875 +84342 -0.128204345703125 +84343 -0.082366943359375 +84344 -0.115692138671875 +84345 -0.066680908203125 +84346 -0.116455078125 +84347 -0.056854248046875 +84348 -0.105926513671875 +84349 -0.0418701171875 +84350 -0.053955078125 +84351 -0.008056640625 +84352 0.048797607421875 +84353 0.048492431640625 +84354 0.157318115234375 +84355 0.10614013671875 +84356 0.212005615234375 +84357 0.136474609375 +84358 0.218475341796875 +84359 0.14190673828125 +84360 0.23724365234375 +84361 0.150970458984375 +84362 0.30535888671875 +84363 0.18121337890625 +84364 0.38128662109375 +84365 0.213165283203125 +84366 0.404449462890625 +84367 0.218475341796875 +84368 0.3944091796875 +84369 0.206756591796875 +84370 0.3885498046875 +84371 0.196075439453125 +84372 0.362640380859375 +84373 0.175445556640625 +84374 0.27362060546875 +84375 0.12506103515625 +84376 0.11712646484375 +84377 0.043304443359375 +84378 -0.054901123046875 +84379 -0.04486083984375 +84380 -0.19085693359375 +84381 -0.114715576171875 +84382 -0.28570556640625 +84383 -0.16363525390625 +84384 -0.339263916015625 +84385 -0.191375732421875 +84386 -0.3775634765625 +84387 -0.210113525390625 +84388 -0.445709228515625 +84389 -0.24114990234375 +84390 -0.535064697265625 +84391 -0.280548095703125 +84392 -0.629058837890625 +84393 -0.3206787109375 +84394 -0.697601318359375 +84395 -0.34759521484375 +84396 -0.70391845703125 +84397 -0.344268798828125 +84398 -0.6424560546875 +84399 -0.3084716796875 +84400 -0.491241455078125 +84401 -0.230194091796875 +84402 -0.265716552734375 +84403 -0.11712646484375 +84404 -0.023712158203125 +84405 0.0030517578125 +84406 0.201751708984375 +84407 0.114471435546875 +84408 0.375823974609375 +84409 0.200439453125 +84410 0.485076904296875 +84411 0.25445556640625 +84412 0.56884765625 +84413 0.29498291015625 +84414 0.634765625 +84415 0.32562255859375 +84416 0.63763427734375 +84417 0.325103759765625 +84418 0.5660400390625 +84419 0.288177490234375 +84420 0.4720458984375 +84421 0.239593505859375 +84422 0.40692138671875 +84423 0.203826904296875 +84424 0.3778076171875 +84425 0.1845703125 +84426 0.376953125 +84427 0.178466796875 +84428 0.371978759765625 +84429 0.170562744140625 +84430 0.313140869140625 +84431 0.137664794921875 +84432 0.184417724609375 +84433 0.072479248046875 +84434 0.011199951171875 +84435 -0.01275634765625 +84436 -0.171051025390625 +84437 -0.10113525390625 +84438 -0.33740234375 +84439 -0.180816650390625 +84440 -0.47198486328125 +84441 -0.244293212890625 +84442 -0.560394287109375 +84443 -0.2847900390625 +84444 -0.58056640625 +84445 -0.2919921875 +84446 -0.54754638671875 +84447 -0.273162841796875 +84448 -0.508575439453125 +84449 -0.250823974609375 +84450 -0.459503173828125 +84451 -0.223236083984375 +84452 -0.394378662109375 +84453 -0.1878662109375 +84454 -0.35260009765625 +84455 -0.163543701171875 +84456 -0.31170654296875 +84457 -0.139892578125 +84458 -0.197418212890625 +84459 -0.08209228515625 +84460 -0.007965087890625 +84461 0.010467529296875 +84462 0.207489013671875 +84463 0.114410400390625 +84464 0.409210205078125 +84465 0.21087646484375 +84466 0.57208251953125 +84467 0.287994384765625 +84468 0.66595458984375 +84469 0.331573486328125 +84470 0.65875244140625 +84471 0.326507568359375 +84472 0.56744384765625 +84473 0.28094482421875 +84474 0.431396484375 +84475 0.213623046875 +84476 0.29443359375 +84477 0.1453857421875 +84478 0.182464599609375 +84479 0.088714599609375 +84480 0.06365966796875 +84481 0.029266357421875 +84482 -0.075958251953125 +84483 -0.039276123046875 +84484 -0.189422607421875 +84485 -0.095916748046875 +84486 -0.271942138671875 +84487 -0.138092041015625 +84488 -0.342529296875 +84489 -0.173797607421875 +84490 -0.364166259765625 +84491 -0.186553955078125 +84492 -0.327239990234375 +84493 -0.171966552734375 +84494 -0.2769775390625 +84495 -0.149871826171875 +84496 -0.253692626953125 +84497 -0.1380615234375 +84498 -0.24365234375 +84499 -0.130615234375 +84500 -0.1983642578125 +84501 -0.106414794921875 +84502 -0.116241455078125 +84503 -0.065032958984375 +84504 -0.036834716796875 +84505 -0.024169921875 +84506 0.034881591796875 +84507 0.013580322265625 +84508 0.09124755859375 +84509 0.044525146484375 +84510 0.10888671875 +84511 0.05804443359375 +84512 0.125518798828125 +84513 0.070404052734375 +84514 0.15771484375 +84515 0.088623046875 +84516 0.17828369140625 +84517 0.100555419921875 +84518 0.17108154296875 +84519 0.09893798828125 +84520 0.129974365234375 +84521 0.081085205078125 +84522 0.082427978515625 +84523 0.05908203125 +84524 0.027679443359375 +84525 0.03271484375 +84526 -0.065643310546875 +84527 -0.01165771484375 +84528 -0.15936279296875 +84529 -0.057037353515625 +84530 -0.21307373046875 +84531 -0.08538818359375 +84532 -0.234649658203125 +84533 -0.09991455078125 +84534 -0.2001953125 +84535 -0.08978271484375 +84536 -0.119171142578125 +84537 -0.05889892578125 +84538 -0.024749755859375 +84539 -0.021636962890625 +84540 0.085784912109375 +84541 0.023406982421875 +84542 0.178131103515625 +84543 0.061309814453125 +84544 0.215576171875 +84545 0.0760498046875 +84546 0.211456298828125 +84547 0.07354736328125 +84548 0.17523193359375 +84549 0.058013916015625 +84550 0.128753662109375 +84551 0.03900146484375 +84552 0.1019287109375 +84553 0.029571533203125 +84554 0.0743408203125 +84555 0.02056884765625 +84556 0.04327392578125 +84557 0.0106201171875 +84558 0.038177490234375 +84559 0.012451171875 +84560 0.076263427734375 +84561 0.03338623046875 +84562 0.14105224609375 +84563 0.065948486328125 +84564 0.186431884765625 +84565 0.08966064453125 +84566 0.188812255859375 +84567 0.09393310546875 +84568 0.1390380859375 +84569 0.074554443359375 +84570 0.041778564453125 +84571 0.033477783203125 +84572 -0.079437255859375 +84573 -0.01898193359375 +84574 -0.219390869140625 +84575 -0.08056640625 +84576 -0.367828369140625 +84577 -0.146728515625 +84578 -0.494873046875 +84579 -0.204254150390625 +84580 -0.556243896484375 +84581 -0.233551025390625 +84582 -0.508697509765625 +84583 -0.2154541015625 +84584 -0.3756103515625 +84585 -0.16009521484375 +84586 -0.218902587890625 +84587 -0.094512939453125 +84588 -0.063751220703125 +84589 -0.02960205078125 +84590 0.091552734375 +84591 0.0355224609375 +84592 0.23602294921875 +84593 0.096221923828125 +84594 0.342987060546875 +84595 0.140899658203125 +84596 0.39520263671875 +84597 0.162109375 +84598 0.389373779296875 +84599 0.158477783203125 +84600 0.324249267578125 +84601 0.129486083984375 +84602 0.224090576171875 +84603 0.0858154296875 +84604 0.124267578125 +84605 0.042999267578125 +84606 0.037078857421875 +84607 0.00634765625 +84608 -0.010101318359375 +84609 -0.012176513671875 +84610 -0.019439697265625 +84611 -0.013702392578125 +84612 -0.022796630859375 +84613 -0.012359619140625 +84614 -0.001556396484375 +84615 -0.0001220703125 +84616 0.056304931640625 +84617 0.028076171875 +84618 0.106719970703125 +84619 0.052703857421875 +84620 0.096893310546875 +84621 0.050445556640625 +84622 0.042694091796875 +84623 0.028167724609375 +84624 -0.018035888671875 +84625 0.00244140625 +84626 -0.07586669921875 +84627 -0.0225830078125 +84628 -0.11944580078125 +84629 -0.04193115234375 +84630 -0.15972900390625 +84631 -0.060394287109375 +84632 -0.202606201171875 +84633 -0.08050537109375 +84634 -0.24859619140625 +84635 -0.102386474609375 +84636 -0.30517578125 +84637 -0.12921142578125 +84638 -0.36212158203125 +84639 -0.1563720703125 +84640 -0.39141845703125 +84641 -0.171478271484375 +84642 -0.35528564453125 +84643 -0.157745361328125 +84644 -0.249969482421875 +84645 -0.1134033203125 +84646 -0.092864990234375 +84647 -0.0460205078125 +84648 0.08905029296875 +84649 0.0325927734375 +84650 0.2352294921875 +84651 0.095855712890625 +84652 0.318817138671875 +84653 0.13201904296875 +84654 0.358642578125 +84655 0.149383544921875 +84656 0.347747802734375 +84657 0.1448974609375 +84658 0.28564453125 +84659 0.118316650390625 +84660 0.223175048828125 +84661 0.091949462890625 +84662 0.196746826171875 +84663 0.08172607421875 +84664 0.179840087890625 +84665 0.075927734375 +84666 0.155548095703125 +84667 0.0670166015625 +84668 0.151214599609375 +84669 0.06689453125 +84670 0.156951904296875 +84671 0.071136474609375 +84672 0.13177490234375 +84673 0.06158447265625 +84674 0.100799560546875 +84675 0.04925537109375 +84676 0.087127685546875 +84677 0.04425048828125 +84678 0.05487060546875 +84679 0.030731201171875 +84680 -0.009002685546875 +84681 0.002899169921875 +84682 -0.10400390625 +84683 -0.03900146484375 +84684 -0.229400634765625 +84685 -0.094635009765625 +84686 -0.35552978515625 +84687 -0.15087890625 +84688 -0.441925048828125 +84689 -0.18988037109375 +84690 -0.473846435546875 +84691 -0.20513916015625 +84692 -0.464813232421875 +84693 -0.2025146484375 +84694 -0.419097900390625 +84695 -0.18377685546875 +84696 -0.334320068359375 +84697 -0.1478271484375 +84698 -0.227935791015625 +84699 -0.102264404296875 +84700 -0.12347412109375 +84701 -0.057373046875 +84702 -0.02764892578125 +84703 -0.01605224609375 +84704 0.077667236328125 +84705 0.0296630859375 +84706 0.2132568359375 +84707 0.0889892578125 +84708 0.38885498046875 +84709 0.166168212890625 +84710 0.582794189453125 +84711 0.251678466796875 +84712 0.734039306640625 +84713 0.31866455078125 +84714 0.800140380859375 +84715 0.348388671875 +84716 0.7783203125 +84717 0.339599609375 +84718 0.6651611328125 +84719 0.290740966796875 +84720 0.45965576171875 +84721 0.201324462890625 +84722 0.199188232421875 +84723 0.0877685546875 +84724 -0.050689697265625 +84725 -0.021148681640625 +84726 -0.23297119140625 +84727 -0.100372314453125 +84728 -0.33013916015625 +84729 -0.14227294921875 +84730 -0.368408203125 +84731 -0.158416748046875 +84732 -0.378936767578125 +84733 -0.162567138671875 +84734 -0.376983642578125 +84735 -0.161468505859375 +84736 -0.37969970703125 +84737 -0.16259765625 +84738 -0.391510009765625 +84739 -0.167877197265625 +84740 -0.385345458984375 +84741 -0.165985107421875 +84742 -0.3419189453125 +84743 -0.1488037109375 +84744 -0.28289794921875 +84745 -0.124969482421875 +84746 -0.251617431640625 +84747 -0.112030029296875 +84748 -0.266143798828125 +84749 -0.117279052734375 +84750 -0.273345947265625 +84751 -0.119049072265625 +84752 -0.216796875 +84753 -0.0943603515625 +84754 -0.128265380859375 +84755 -0.05621337890625 +84756 -0.068145751953125 +84757 -0.02935791015625 +84758 -0.0430908203125 +84759 -0.01666259765625 +84760 -0.024444580078125 +84761 -0.006591796875 +84762 0.020721435546875 +84763 0.01409912109375 +84764 0.124481201171875 +84765 0.058380126953125 +84766 0.25787353515625 +84767 0.11431884765625 +84768 0.379119873046875 +84769 0.164764404296875 +84770 0.47991943359375 +84771 0.206329345703125 +84772 0.5281982421875 +84773 0.225860595703125 +84774 0.511138916015625 +84775 0.218170166015625 +84776 0.456207275390625 +84777 0.19451904296875 +84778 0.407470703125 +84779 0.173004150390625 +84780 0.383758544921875 +84781 0.161376953125 +84782 0.35687255859375 +84783 0.148223876953125 +84784 0.31182861328125 +84785 0.1275634765625 +84786 0.250885009765625 +84787 0.1004638671875 +84788 0.1654052734375 +84789 0.063507080078125 +84790 0.035247802734375 +84791 0.00860595703125 +84792 -0.142059326171875 +84793 -0.065155029296875 +84794 -0.33563232421875 +84795 -0.14508056640625 +84796 -0.5345458984375 +84797 -0.2266845703125 +84798 -0.72186279296875 +84799 -0.30303955078125 +84800 -0.836669921875 +84801 -0.34930419921875 +84802 -0.8326416015625 +84803 -0.34661865234375 +84804 -0.7296142578125 +84805 -0.303192138671875 +84806 -0.582550048828125 +84807 -0.241546630859375 +84808 -0.440093994140625 +84809 -0.18157958984375 +84810 -0.324310302734375 +84811 -0.132415771484375 +84812 -0.20147705078125 +84813 -0.080413818359375 +84814 -0.044647216796875 +84815 -0.014678955078125 +84816 0.103973388671875 +84817 0.0474853515625 +84818 0.202392578125 +84819 0.088836669921875 +84820 0.264495849609375 +84821 0.114990234375 +84822 0.338897705078125 +84823 0.145751953125 +84824 0.443817138671875 +84825 0.18853759765625 +84826 0.545074462890625 +84827 0.22943115234375 +84828 0.6173095703125 +84829 0.258087158203125 +84830 0.6524658203125 +84831 0.27130126953125 +84832 0.66339111328125 +84833 0.274383544921875 +84834 0.6561279296875 +84835 0.269866943359375 +84836 0.606781005859375 +84837 0.24810791015625 +84838 0.501190185546875 +84839 0.203399658203125 +84840 0.352783203125 +84841 0.141326904296875 +84842 0.176544189453125 +84843 0.068084716796875 +84844 -0.034820556640625 +84845 -0.01922607421875 +84846 -0.258209228515625 +84847 -0.111114501953125 +84848 -0.44244384765625 +84849 -0.1866455078125 +84850 -0.5753173828125 +84851 -0.2408447265625 +84852 -0.65203857421875 +84853 -0.27178955078125 +84854 -0.641632080078125 +84855 -0.266845703125 +84856 -0.562164306640625 +84857 -0.23345947265625 +84858 -0.458038330078125 +84859 -0.1898193359375 +84860 -0.350555419921875 +84861 -0.1446533203125 +84862 -0.260528564453125 +84863 -0.106536865234375 +84864 -0.192108154296875 +84865 -0.0772705078125 +84866 -0.141937255859375 +84867 -0.055511474609375 +84868 -0.1021728515625 +84869 -0.03814697265625 +84870 -0.062896728515625 +84871 -0.02117919921875 +84872 -0.011932373046875 +84873 0.000274658203125 +84874 0.062835693359375 +84875 0.031158447265625 +84876 0.148712158203125 +84877 0.0662841796875 +84878 0.241729736328125 +84879 0.10400390625 +84880 0.34912109375 +84881 0.147308349609375 +84882 0.457305908203125 +84883 0.190673828125 +84884 0.54388427734375 +84885 0.22503662109375 +84886 0.5728759765625 +84887 0.235748291015625 +84888 0.506591796875 +84889 0.20751953125 +84890 0.351226806640625 +84891 0.1429443359375 +84892 0.146514892578125 +84893 0.05828857421875 +84894 -0.05523681640625 +84895 -0.0250244140625 +84896 -0.21624755859375 +84897 -0.091522216796875 +84898 -0.334930419921875 +84899 -0.140533447265625 +84900 -0.402984619140625 +84901 -0.16864013671875 +84902 -0.4412841796875 +84903 -0.184326171875 +84904 -0.49578857421875 +84905 -0.20635986328125 +84906 -0.5601806640625 +84907 -0.232208251953125 +84908 -0.600738525390625 +84909 -0.248138427734375 +84910 -0.584228515625 +84911 -0.240631103515625 +84912 -0.47930908203125 +84913 -0.196929931640625 +84914 -0.27935791015625 +84915 -0.1143798828125 +84916 -0.0089111328125 +84917 -0.0030517578125 +84918 0.268798828125 +84919 0.11114501953125 +84920 0.482818603515625 +84921 0.199249267578125 +84922 0.60369873046875 +84923 0.24920654296875 +84924 0.650421142578125 +84925 0.268707275390625 +84926 0.66400146484375 +84927 0.27447509765625 +84928 0.6414794921875 +84929 0.26531982421875 +84930 0.572540283203125 +84931 0.237030029296875 +84932 0.498138427734375 +84933 0.206329345703125 +84934 0.439453125 +84935 0.181884765625 +84936 0.375518798828125 +84937 0.155181884765625 +84938 0.274505615234375 +84939 0.113250732421875 +84940 0.1087646484375 +84941 0.04486083984375 +84942 -0.099395751953125 +84943 -0.04083251953125 +84944 -0.3182373046875 +84945 -0.130828857421875 +84946 -0.5489501953125 +84947 -0.2255859375 +84948 -0.7738037109375 +84949 -0.31781005859375 +84950 -0.86383056640625 +84951 -0.3858642578125 +84952 -0.870391845703125 +84953 -0.41619873046875 +84954 -0.86895751953125 +84955 -0.416015625 +84956 -0.861053466796875 +84957 -0.39068603515625 +84958 -0.765869140625 +84959 -0.33319091796875 +84960 -0.5301513671875 +84961 -0.23895263671875 +84962 -0.214691162109375 +84963 -0.110870361328125 +84964 0.137359619140625 +84965 0.033416748046875 +84966 0.474822998046875 +84967 0.172943115234375 +84968 0.76239013671875 +84969 0.293182373046875 +84970 0.867462158203125 +84971 0.383087158203125 +84972 0.870361328125 +84973 0.44281005859375 +84974 0.86480712890625 +84975 0.46759033203125 +84976 0.831817626953125 +84977 0.459625244140625 +84978 0.677581787109375 +84979 0.428863525390625 +84980 0.495880126953125 +84981 0.377655029296875 +84982 0.30767822265625 +84983 0.3135986328125 +84984 0.116180419921875 +84985 0.237579345703125 +84986 -0.110748291015625 +84987 0.136688232421875 +84988 -0.381805419921875 +84989 0.00811767578125 +84990 -0.6572265625 +84991 -0.130615234375 +84992 -0.857421875 +84993 -0.25518798828125 +84994 -0.870391845703125 +84995 -0.34820556640625 +84996 -0.870391845703125 +84997 -0.406585693359375 +84998 -0.86444091796875 +84999 -0.440460205078125 +85000 -0.85723876953125 +85001 -0.46337890625 +85002 -0.790008544921875 +85003 -0.46868896484375 +85004 -0.62847900390625 +85005 -0.436279296875 +85006 -0.3956298828125 +85007 -0.36529541015625 +85008 -0.126708984375 +85009 -0.26849365234375 +85010 0.150115966796875 +85011 -0.1566162109375 +85012 0.424041748046875 +85013 -0.03448486328125 +85014 0.670623779296875 +85015 0.0872802734375 +85016 0.854522705078125 +85017 0.193695068359375 +85018 0.866485595703125 +85019 0.27777099609375 +85020 0.86920166015625 +85021 0.333404541015625 +85022 0.8653564453125 +85023 0.3671875 +85024 0.857147216796875 +85025 0.384033203125 +85026 0.766845703125 +85027 0.38275146484375 +85028 0.628509521484375 +85029 0.36529541015625 +85030 0.462127685546875 +85031 0.3292236328125 +85032 0.297210693359375 +85033 0.284454345703125 +85034 0.14862060546875 +85035 0.23590087890625 +85036 -0.00537109375 +85037 0.175262451171875 +85038 -0.15753173828125 +85039 0.105712890625 +85040 -0.31304931640625 +85041 0.0262451171875 +85042 -0.48876953125 +85043 -0.068023681640625 +85044 -0.6416015625 +85045 -0.159149169921875 +85046 -0.751373291015625 +85047 -0.237548828125 +85048 -0.84619140625 +85049 -0.31170654296875 +85050 -0.861297607421875 +85051 -0.37591552734375 +85052 -0.863250732421875 +85053 -0.417633056640625 +85054 -0.856597900390625 +85055 -0.424957275390625 +85056 -0.7498779296875 +85057 -0.40252685546875 +85058 -0.624542236328125 +85059 -0.372222900390625 +85060 -0.47808837890625 +85061 -0.325958251953125 +85062 -0.253387451171875 +85063 -0.242034912109375 +85064 0.003692626953125 +85065 -0.137908935546875 +85066 0.2257080078125 +85067 -0.03955078125 +85068 0.427154541015625 +85069 0.05743408203125 +85070 0.643218994140625 +85071 0.164947509765625 +85072 0.855926513671875 +85073 0.279083251953125 +85074 0.870361328125 +85075 0.377838134765625 +85076 0.870361328125 +85077 0.4423828125 +85078 0.862762451171875 +85079 0.475311279296875 +85080 0.79669189453125 +85081 0.475494384765625 +85082 0.595794677734375 +85083 0.43939208984375 +85084 0.362152099609375 +85085 0.37811279296875 +85086 0.1270751953125 +85087 0.302337646484375 +85088 -0.086944580078125 +85089 0.220245361328125 +85090 -0.2784423828125 +85091 0.13287353515625 +85092 -0.484832763671875 +85093 0.027374267578125 +85094 -0.729583740234375 +85095 -0.103179931640625 +85096 -0.86688232421875 +85097 -0.239471435546875 +85098 -0.870391845703125 +85099 -0.357421875 +85100 -0.86859130859375 +85101 -0.4549560546875 +85102 -0.86279296875 +85103 -0.531158447265625 +85104 -0.817962646484375 +85105 -0.572357177734375 +85106 -0.6116943359375 +85107 -0.5614013671875 +85108 -0.3128662109375 +85109 -0.49566650390625 +85110 0.039398193359375 +85111 -0.38787841796875 +85112 0.422821044921875 +85113 -0.245697021484375 +85114 0.805145263671875 +85115 -0.081817626953125 +85116 0.870361328125 +85117 0.077911376953125 +85118 0.870361328125 +85119 0.2117919921875 +85120 0.860015869140625 +85121 0.315185546875 +85122 0.727935791015625 +85123 0.3848876953125 +85124 0.48114013671875 +85125 0.418487548828125 +85126 0.2059326171875 +85127 0.4248046875 +85128 -0.06103515625 +85129 0.412109375 +85130 -0.29913330078125 +85131 0.384033203125 +85132 -0.516204833984375 +85133 0.33502197265625 +85134 -0.7252197265625 +85135 0.25927734375 +85136 -0.85980224609375 +85137 0.16619873046875 +85138 -0.870391845703125 +85139 0.068878173828125 +85140 -0.870391845703125 +85141 -0.021331787109375 +85142 -0.858062744140625 +85143 -0.085845947265625 +85144 -0.673004150390625 +85145 -0.122711181640625 +85146 -0.42694091796875 +85147 -0.15130615234375 +85148 -0.2100830078125 +85149 -0.18792724609375 +85150 -0.0362548828125 +85151 -0.23138427734375 +85152 0.10943603515625 +85153 -0.2703857421875 +85154 0.23516845703125 +85155 -0.29718017578125 +85156 0.373687744140625 +85157 -0.29595947265625 +85158 0.517791748046875 +85159 -0.267364501953125 +85160 0.602783203125 +85161 -0.23504638671875 +85162 0.635711669921875 +85163 -0.197113037109375 +85164 0.655181884765625 +85165 -0.14117431640625 +85166 0.65948486328125 +85167 -0.071197509765625 +85168 0.651275634765625 +85169 0.009490966796875 +85170 0.61846923828125 +85171 0.091339111328125 +85172 0.53753662109375 +85173 0.160064697265625 +85174 0.404144287109375 +85175 0.208465576171875 +85176 0.22186279296875 +85177 0.232574462890625 +85178 0.003997802734375 +85179 0.232513427734375 +85180 -0.22100830078125 +85181 0.214813232421875 +85182 -0.42449951171875 +85183 0.187042236328125 +85184 -0.579833984375 +85185 0.157073974609375 +85186 -0.641876220703125 +85187 0.140899658203125 +85188 -0.6177978515625 +85189 0.13604736328125 +85190 -0.575531005859375 +85191 0.11834716796875 +85192 -0.526336669921875 +85193 0.085968017578125 +85194 -0.42645263671875 +85195 0.058624267578125 +85196 -0.2581787109375 +85197 0.046905517578125 +85198 -0.068695068359375 +85199 0.037445068359375 +85200 0.09222412109375 +85201 0.01611328125 +85202 0.232147216796875 +85203 -0.009735107421875 +85204 0.3509521484375 +85205 -0.03594970703125 +85206 0.410064697265625 +85207 -0.073394775390625 +85208 0.372955322265625 +85209 -0.132843017578125 +85210 0.2554931640625 +85211 -0.206268310546875 +85212 0.10711669921875 +85213 -0.273956298828125 +85214 -0.052886962890625 +85215 -0.3284912109375 +85216 -0.186279296875 +85217 -0.3563232421875 +85218 -0.23291015625 +85219 -0.3365478515625 +85220 -0.209442138671875 +85221 -0.277862548828125 +85222 -0.174163818359375 +85223 -0.205291748046875 +85224 -0.126739501953125 +85225 -0.122222900390625 +85226 -0.048126220703125 +85227 -0.025238037109375 +85228 0.0426025390625 +85229 0.07476806640625 +85230 0.10748291015625 +85231 0.15997314453125 +85232 0.1409912109375 +85233 0.22509765625 +85234 0.19708251953125 +85235 0.287811279296875 +85236 0.273651123046875 +85237 0.345367431640625 +85238 0.31768798828125 +85239 0.376617431640625 +85240 0.341094970703125 +85241 0.38568115234375 +85242 0.368011474609375 +85243 0.38201904296875 +85244 0.37249755859375 +85245 0.3570556640625 +85246 0.30072021484375 +85247 0.2923583984375 +85248 0.1517333984375 +85249 0.18975830078125 +85250 -0.01470947265625 +85251 0.074371337890625 +85252 -0.1883544921875 +85253 -0.046051025390625 +85254 -0.372711181640625 +85255 -0.169342041015625 +85256 -0.51397705078125 +85257 -0.2734375 +85258 -0.57177734375 +85259 -0.341339111328125 +85260 -0.53948974609375 +85261 -0.368377685546875 +85262 -0.43511962890625 +85263 -0.359039306640625 +85264 -0.2962646484375 +85265 -0.325347900390625 +85266 -0.161102294921875 +85267 -0.2802734375 +85268 -0.0435791015625 +85269 -0.228973388671875 +85270 0.060394287109375 +85271 -0.17095947265625 +85272 0.13665771484375 +85273 -0.112701416015625 +85274 0.170135498046875 +85275 -0.0615234375 +85276 0.16552734375 +85277 -0.018157958984375 +85278 0.15728759765625 +85279 0.02679443359375 +85280 0.150787353515625 +85281 0.072509765625 +85282 0.12200927734375 +85283 0.10797119140625 +85284 0.080108642578125 +85285 0.13397216796875 +85286 0.05126953125 +85287 0.1575927734375 +85288 0.062896728515625 +85289 0.186767578125 +85290 0.09271240234375 +85291 0.212615966796875 +85292 0.092987060546875 +85293 0.217864990234375 +85294 0.07855224609375 +85295 0.20770263671875 +85296 0.06427001953125 +85297 0.187896728515625 +85298 0.0347900390625 +85299 0.1541748046875 +85300 -0.01171875 +85301 0.107421875 +85302 -0.056060791015625 +85303 0.05621337890625 +85304 -0.055511474609375 +85305 0.017578125 +85306 -0.010467529296875 +85307 -0.006378173828125 +85308 0.02508544921875 +85309 -0.032318115234375 +85310 0.025665283203125 +85311 -0.067108154296875 +85312 0.017333984375 +85313 -0.099822998046875 +85314 0.00189208984375 +85315 -0.128387451171875 +85316 -0.03173828125 +85317 -0.155609130859375 +85318 -0.071502685546875 +85319 -0.176666259765625 +85320 -0.13543701171875 +85321 -0.19769287109375 +85322 -0.219970703125 +85323 -0.217742919921875 +85324 -0.300506591796875 +85325 -0.22894287109375 +85326 -0.376312255859375 +85327 -0.232208251953125 +85328 -0.416107177734375 +85329 -0.218048095703125 +85330 -0.371124267578125 +85331 -0.171051025390625 +85332 -0.242279052734375 +85333 -0.09332275390625 +85334 -0.069732666015625 +85335 -0.000762939453125 +85336 0.125640869140625 +85337 0.097564697265625 +85338 0.31268310546875 +85339 0.189178466796875 +85340 0.45501708984375 +85341 0.260009765625 +85342 0.554779052734375 +85343 0.309814453125 +85344 0.61065673828125 +85345 0.3375244140625 +85346 0.610931396484375 +85347 0.33880615234375 +85348 0.531463623046875 +85349 0.305328369140625 +85350 0.3883056640625 +85351 0.24322509765625 +85352 0.23468017578125 +85353 0.17193603515625 +85354 0.095245361328125 +85355 0.10125732421875 +85356 -0.00396728515625 +85357 0.041595458984375 +85358 -0.04852294921875 +85359 -0.00054931640625 +85360 -0.055145263671875 +85361 -0.029541015625 +85362 -0.0758056640625 +85363 -0.062103271484375 +85364 -0.138702392578125 +85365 -0.106781005859375 +85366 -0.209197998046875 +85367 -0.1502685546875 +85368 -0.289031982421875 +85369 -0.1922607421875 +85370 -0.37884521484375 +85371 -0.23236083984375 +85372 -0.456329345703125 +85373 -0.262451171875 +85374 -0.51641845703125 +85375 -0.28076171875 +85376 -0.519287109375 +85377 -0.27362060546875 +85378 -0.458251953125 +85379 -0.23931884765625 +85380 -0.384796142578125 +85381 -0.19671630859375 +85382 -0.323699951171875 +85383 -0.155517578125 +85384 -0.269287109375 +85385 -0.114898681640625 +85386 -0.1951904296875 +85387 -0.06683349609375 +85388 -0.100006103515625 +85389 -0.0120849609375 +85390 -0.01055908203125 +85391 0.038787841796875 +85392 0.1033935546875 +85393 0.0953369140625 +85394 0.24908447265625 +85395 0.1593017578125 +85396 0.373199462890625 +85397 0.21142578125 +85398 0.45806884765625 +85399 0.245147705078125 +85400 0.511474609375 +85401 0.26312255859375 +85402 0.565399169921875 +85403 0.276702880859375 +85404 0.61138916015625 +85405 0.283355712890625 +85406 0.5897216796875 +85407 0.2628173828125 +85408 0.4906005859375 +85409 0.212432861328125 +85410 0.33148193359375 +85411 0.1392822265625 +85412 0.147796630859375 +85413 0.0567626953125 +85414 -0.01873779296875 +85415 -0.01947021484375 +85416 -0.140289306640625 +85417 -0.078704833984375 +85418 -0.191986083984375 +85419 -0.11138916015625 +85420 -0.184295654296875 +85421 -0.120452880859375 +85422 -0.161834716796875 +85423 -0.120941162109375 +85424 -0.166595458984375 +85425 -0.127197265625 +85426 -0.19390869140625 +85427 -0.137420654296875 +85428 -0.22442626953125 +85429 -0.144927978515625 +85430 -0.279754638671875 +85431 -0.157562255859375 +85432 -0.3389892578125 +85433 -0.168487548828125 +85434 -0.3543701171875 +85435 -0.16162109375 +85436 -0.348175048828125 +85437 -0.145477294921875 +85438 -0.32598876953125 +85439 -0.122833251953125 +85440 -0.2581787109375 +85441 -0.08416748046875 +85442 -0.139801025390625 +85443 -0.028564453125 +85444 0.014617919921875 +85445 0.03814697265625 +85446 0.144378662109375 +85447 0.094024658203125 +85448 0.221038818359375 +85449 0.128631591796875 +85450 0.27069091796875 +85451 0.1507568359375 +85452 0.294036865234375 +85453 0.160491943359375 +85454 0.311767578125 +85455 0.16510009765625 +85456 0.339141845703125 +85457 0.170074462890625 +85458 0.360260009765625 +85459 0.17010498046875 +85460 0.360504150390625 +85461 0.16058349609375 +85462 0.308380126953125 +85463 0.13128662109375 +85464 0.18170166015625 +85465 0.07525634765625 +85466 0.0047607421875 +85467 0.001617431640625 +85468 -0.17559814453125 +85469 -0.07281494140625 +85470 -0.3143310546875 +85471 -0.13189697265625 +85472 -0.36785888671875 +85473 -0.1600341796875 +85474 -0.36248779296875 +85475 -0.165802001953125 +85476 -0.343536376953125 +85477 -0.164398193359375 +85478 -0.3018798828125 +85479 -0.152496337890625 +85480 -0.231414794921875 +85481 -0.1279296875 +85482 -0.117645263671875 +85483 -0.0858154296875 +85484 0.007049560546875 +85485 -0.037567138671875 +85486 0.087982177734375 +85487 -0.002288818359375 +85488 0.13946533203125 +85489 0.0244140625 +85490 0.17425537109375 +85491 0.046417236328125 +85492 0.188201904296875 +85493 0.06170654296875 +85494 0.171234130859375 +85495 0.06622314453125 +85496 0.118438720703125 +85497 0.057708740234375 +85498 0.05706787109375 +85499 0.045074462890625 +85500 -0.010711669921875 +85501 0.028594970703125 +85502 -0.0914306640625 +85503 0.005706787109375 +85504 -0.162322998046875 +85505 -0.0155029296875 +85506 -0.194549560546875 +85507 -0.025421142578125 +85508 -0.1492919921875 +85509 -0.012176513671875 +85510 -0.02166748046875 +85511 0.025482177734375 +85512 0.124053955078125 +85513 0.0673828125 +85514 0.211151123046875 +85515 0.089630126953125 +85516 0.240447998046875 +85517 0.0926513671875 +85518 0.242218017578125 +85519 0.086181640625 +85520 0.2257080078125 +85521 0.073516845703125 +85522 0.194366455078125 +85523 0.056121826171875 +85524 0.115509033203125 +85525 0.024200439453125 +85526 0.0128173828125 +85527 -0.014404296875 +85528 -0.053802490234375 +85529 -0.0406494140625 +85530 -0.110626220703125 +85531 -0.06243896484375 +85532 -0.199493408203125 +85533 -0.0926513671875 +85534 -0.29437255859375 +85535 -0.123046875 +85536 -0.33221435546875 +85537 -0.133941650390625 +85538 -0.27972412109375 +85539 -0.11505126953125 +85540 -0.185333251953125 +85541 -0.0816650390625 +85542 -0.128204345703125 +85543 -0.058685302734375 +85544 -0.115692138671875 +85545 -0.0487060546875 +85546 -0.116455078125 +85547 -0.042327880859375 +85548 -0.105926513671875 +85549 -0.032257080078125 +85550 -0.053955078125 +85551 -0.00946044921875 +85552 0.048797607421875 +85553 0.028564453125 +85554 0.157318115234375 +85555 0.0675048828125 +85556 0.212005615234375 +85557 0.0885009765625 +85558 0.218475341796875 +85559 0.0931396484375 +85560 0.23724365234375 +85561 0.100189208984375 +85562 0.30535888671875 +85563 0.121185302734375 +85564 0.38128662109375 +85565 0.1431884765625 +85566 0.404449462890625 +85567 0.147430419921875 +85568 0.3944091796875 +85569 0.140228271484375 +85570 0.3885498046875 +85571 0.133514404296875 +85572 0.362640380859375 +85573 0.120025634765625 +85574 0.27362060546875 +85575 0.08660888671875 +85576 0.11712646484375 +85577 0.032257080078125 +85578 -0.054901123046875 +85579 -0.0264892578125 +85580 -0.19085693359375 +85581 -0.07330322265625 +85582 -0.28570556640625 +85583 -0.10638427734375 +85584 -0.339263916015625 +85585 -0.12554931640625 +85586 -0.3775634765625 +85587 -0.138763427734375 +85588 -0.445709228515625 +85589 -0.16009521484375 +85590 -0.535064697265625 +85591 -0.1868896484375 +85592 -0.629058837890625 +85593 -0.21405029296875 +85594 -0.697601318359375 +85595 -0.232330322265625 +85596 -0.70391845703125 +85597 -0.230438232421875 +85598 -0.6424560546875 +85599 -0.2069091796875 +85600 -0.491241455078125 +85601 -0.155120849609375 +85602 -0.265716552734375 +85603 -0.08013916015625 +85604 -0.023712158203125 +85605 -0.000274658203125 +85606 0.201751708984375 +85607 0.073883056640625 +85608 0.375823974609375 +85609 0.13128662109375 +85610 0.485076904296875 +85611 0.1676025390625 +85612 0.56884765625 +85613 0.19500732421875 +85614 0.634765625 +85615 0.215850830078125 +85616 0.63763427734375 +85617 0.216064453125 +85618 0.5660400390625 +85619 0.192138671875 +85620 0.4720458984375 +85621 0.160430908203125 +85622 0.40692138671875 +85623 0.137054443359375 +85624 0.3778076171875 +85625 0.12445068359375 +85626 0.376953125 +85627 0.12042236328125 +85628 0.371978759765625 +85629 0.11505126953125 +85630 0.313140869140625 +85631 0.093048095703125 +85632 0.184417724609375 +85633 0.049591064453125 +85634 0.011199951171875 +85635 -0.007171630859375 +85636 -0.171051025390625 +85637 -0.066070556640625 +85638 -0.33740234375 +85639 -0.119232177734375 +85640 -0.47198486328125 +85641 -0.161651611328125 +85642 -0.560394287109375 +85643 -0.1888427734375 +85644 -0.58056640625 +85645 -0.1939697265625 +85646 -0.54754638671875 +85647 -0.18182373046875 +85648 -0.508575439453125 +85649 -0.167266845703125 +85650 -0.459503173828125 +85651 -0.149139404296875 +85652 -0.394378662109375 +85653 -0.125732421875 +85654 -0.35260009765625 +85655 -0.109527587890625 +85656 -0.31170654296875 +85657 -0.09368896484375 +85658 -0.197418212890625 +85659 -0.055206298828125 +85660 -0.007965087890625 +85661 0.00628662109375 +85662 0.207489013671875 +85663 0.075347900390625 +85664 0.409210205078125 +85665 0.13946533203125 +85666 0.57208251953125 +85667 0.190765380859375 +85668 0.66595458984375 +85669 0.2198486328125 +85670 0.65875244140625 +85671 0.21673583984375 +85672 0.56744384765625 +85673 0.186798095703125 +85674 0.431396484375 +85675 0.142425537109375 +85676 0.29443359375 +85677 0.097412109375 +85678 0.182464599609375 +85679 0.0599365234375 +85680 0.06365966796875 +85681 0.020233154296875 +85682 -0.075958251953125 +85683 -0.025909423828125 +85684 -0.189422607421875 +85685 -0.063690185546875 +85686 -0.271942138671875 +85687 -0.091461181640625 +85688 -0.342529296875 +85689 -0.11505126953125 +85690 -0.364166259765625 +85691 -0.122894287109375 +85692 -0.327239990234375 +85693 -0.111907958984375 +85694 -0.2769775390625 +85695 -0.09619140625 +85696 -0.253692626953125 +85697 -0.088348388671875 +85698 -0.24365234375 +85699 -0.0841064453125 +85700 -0.1983642578125 +85701 -0.06842041015625 +85702 -0.116241455078125 +85703 -0.040924072265625 +85704 -0.036834716796875 +85705 -0.014068603515625 +85706 0.034881591796875 +85707 0.010467529296875 +85708 0.09124755859375 +85709 0.0301513671875 +85710 0.10888671875 +85711 0.03759765625 +85712 0.125518798828125 +85713 0.044464111328125 +85714 0.15771484375 +85715 0.05584716796875 +85716 0.17828369140625 +85717 0.063201904296875 +85718 0.17108154296875 +85719 0.061431884765625 +85720 0.129974365234375 +85721 0.04864501953125 +85722 0.082427978515625 +85723 0.03338623046875 +85724 0.027679443359375 +85725 0.0155029296875 +85726 -0.065643310546875 +85727 -0.01470947265625 +85728 -0.15936279296875 +85729 -0.0452880859375 +85730 -0.21307373046875 +85731 -0.063568115234375 +85732 -0.234649658203125 +85733 -0.071929931640625 +85734 -0.2001953125 +85735 -0.06280517578125 +85736 -0.119171142578125 +85737 -0.0390625 +85738 -0.024749755859375 +85739 -0.010986328125 +85740 0.085784912109375 +85741 0.0223388671875 +85742 0.178131103515625 +85743 0.05023193359375 +85744 0.215576171875 +85745 0.061309814453125 +85746 0.211456298828125 +85747 0.059783935546875 +85748 0.17523193359375 +85749 0.048614501953125 +85750 0.128753662109375 +85751 0.034576416015625 +85752 0.1019287109375 +85753 0.0269775390625 +85754 0.0743408203125 +85755 0.019378662109375 +85756 0.04327392578125 +85757 0.010894775390625 +85758 0.038177490234375 +85759 0.010589599609375 +85760 0.076263427734375 +85761 0.02325439453125 +85762 0.14105224609375 +85763 0.043182373046875 +85764 0.186431884765625 +85765 0.05682373046875 +85766 0.188812255859375 +85767 0.05767822265625 +85768 0.1390380859375 +85769 0.0433349609375 +85770 0.041778564453125 +85771 0.0152587890625 +85772 -0.079437255859375 +85773 -0.019775390625 +85774 -0.219390869140625 +85775 -0.060211181640625 +85776 -0.367828369140625 +85777 -0.10302734375 +85778 -0.494873046875 +85779 -0.1397705078125 +85780 -0.556243896484375 +85781 -0.157989501953125 +85782 -0.508697509765625 +85783 -0.1455078125 +85784 -0.3756103515625 +85785 -0.10882568359375 +85786 -0.218902587890625 +85787 -0.06524658203125 +85788 -0.063751220703125 +85789 -0.021820068359375 +85790 0.091552734375 +85791 0.021881103515625 +85792 0.23602294921875 +85793 0.062744140625 +85794 0.342987060546875 +85795 0.093292236328125 +85796 0.39520263671875 +85797 0.108642578125 +85798 0.389373779296875 +85799 0.10784912109375 +85800 0.324249267578125 +85801 0.09051513671875 +85802 0.224090576171875 +85803 0.063385009765625 +85804 0.124267578125 +85805 0.03631591796875 +85806 0.037078857421875 +85807 0.012664794921875 +85808 -0.010101318359375 +85809 6.103515625e-05 +85810 -0.019439697265625 +85811 -0.002105712890625 +85812 -0.022796630859375 +85813 -0.00274658203125 +85814 -0.001556396484375 +85815 0.003265380859375 +85816 0.056304931640625 +85817 0.019287109375 +85818 0.106719970703125 +85819 0.03302001953125 +85820 0.096893310546875 +85821 0.02972412109375 +85822 0.042694091796875 +85823 0.01385498046875 +85824 -0.018035888671875 +85825 -0.00390625 +85826 -0.07586669921875 +85827 -0.0208740234375 +85828 -0.11944580078125 +85829 -0.0338134765625 +85830 -0.15972900390625 +85831 -0.045745849609375 +85832 -0.202606201171875 +85833 -0.058319091796875 +85834 -0.24859619140625 +85835 -0.071624755859375 +85836 -0.30517578125 +85837 -0.087738037109375 +85838 -0.36212158203125 +85839 -0.103790283203125 +85840 -0.39141845703125 +85841 -0.1119384765625 +85842 -0.35528564453125 +85843 -0.10162353515625 +85844 -0.249969482421875 +85845 -0.071807861328125 +85846 -0.092864990234375 +85847 -0.02740478515625 +85848 0.08905029296875 +85849 0.024017333984375 +85850 0.2352294921875 +85851 0.065460205078125 +85852 0.318817138671875 +85853 0.089385986328125 +85854 0.358642578125 +85855 0.10101318359375 +85856 0.347747802734375 +85857 0.098388671875 +85858 0.28564453125 +85859 0.08135986328125 +85860 0.223175048828125 +85861 0.064117431640625 +85862 0.196746826171875 +85863 0.056884765625 +85864 0.179840087890625 +85865 0.052215576171875 +85866 0.155548095703125 +85867 0.045379638671875 +85868 0.151214599609375 +85869 0.044036865234375 +85870 0.156951904296875 +85871 0.045440673828125 +85872 0.13177490234375 +85873 0.0380859375 +85874 0.100799560546875 +85875 0.029052734375 +85876 0.087127685546875 +85877 0.024810791015625 +85878 0.05487060546875 +85879 0.015350341796875 +85880 -0.009002685546875 +85881 -0.0029296875 +85882 -0.10400390625 +85883 -0.029876708984375 +85884 -0.229400634765625 +85885 -0.065277099609375 +85886 -0.35552978515625 +85887 -0.100799560546875 +85888 -0.441925048828125 +85889 -0.125091552734375 +85890 -0.473846435546875 +85891 -0.134033203125 +85892 -0.464813232421875 +85893 -0.13140869140625 +85894 -0.419097900390625 +85895 -0.118438720703125 +85896 -0.334320068359375 +85897 -0.094451904296875 +85898 -0.227935791015625 +85899 -0.0643310546875 +85900 -0.12347412109375 +85901 -0.034698486328125 +85902 -0.02764892578125 +85903 -0.007476806640625 +85904 0.077667236328125 +85905 0.022369384765625 +85906 0.2132568359375 +85907 0.060638427734375 +85908 0.38885498046875 +85909 0.11004638671875 +85910 0.582794189453125 +85911 0.164520263671875 +85912 0.734039306640625 +85913 0.206939697265625 +85914 0.800140380859375 +85915 0.22540283203125 +85916 0.7783203125 +85917 0.219146728515625 +85918 0.6651611328125 +85919 0.187286376953125 +85920 0.45965576171875 +85921 0.129547119140625 +85922 0.199188232421875 +85923 0.056365966796875 +85924 -0.050689697265625 +85925 -0.013824462890625 +85926 -0.23297119140625 +85927 -0.0650634765625 +85928 -0.33013916015625 +85929 -0.092437744140625 +85930 -0.368408203125 +85931 -0.103302001953125 +85932 -0.378936767578125 +85933 -0.106353759765625 +85934 -0.376983642578125 +85935 -0.10589599609375 +85936 -0.37969970703125 +85937 -0.10675048828125 +85938 -0.391510009765625 +85939 -0.110107421875 +85940 -0.385345458984375 +85941 -0.1083984375 +85942 -0.3419189453125 +85943 -0.09619140625 +85944 -0.28289794921875 +85945 -0.079559326171875 +85946 -0.251617431640625 +85947 -0.0706787109375 +85948 -0.266143798828125 +85949 -0.0745849609375 +85950 -0.273345947265625 +85951 -0.076416015625 +85952 -0.216796875 +85953 -0.060394287109375 +85954 -0.128265380859375 +85955 -0.035400390625 +85956 -0.068145751953125 +85957 -0.01837158203125 +85958 -0.0430908203125 +85959 -0.011138916015625 +85960 -0.024444580078125 +85961 -0.0057373046875 +85962 0.020721435546875 +85963 0.00701904296875 +85964 0.124481201171875 +85965 0.036102294921875 +85966 0.25787353515625 +85967 0.07342529296875 +85968 0.379119873046875 +85969 0.107269287109375 +85970 0.47991943359375 +85971 0.135345458984375 +85972 0.5281982421875 +85973 0.148651123046875 +85974 0.511138916015625 +85975 0.14361572265625 +85976 0.456207275390625 +85977 0.1279296875 +85978 0.407470703125 +85979 0.113983154296875 +85980 0.383758544921875 +85981 0.107025146484375 +85982 0.35687255859375 +85983 0.099212646484375 +85984 0.31182861328125 +85985 0.08636474609375 +85986 0.250885009765625 +85987 0.069122314453125 +85988 0.1654052734375 +85989 0.045074462890625 +85990 0.035247802734375 +85991 0.008575439453125 +85992 -0.142059326171875 +85993 -0.041046142578125 +85994 -0.33563232421875 +85995 -0.095123291015625 +85996 -0.5345458984375 +85997 -0.150604248046875 +85998 -0.72186279296875 +85999 -0.202789306640625 +86000 -0.836669921875 +86001 -0.234588623046875 +86002 -0.8326416015625 +86003 -0.23309326171875 +86004 -0.7296142578125 +86005 -0.203857421875 +86006 -0.582550048828125 +86007 -0.16229248046875 +86008 -0.440093994140625 +86009 -0.1220703125 +86010 -0.324310302734375 +86011 -0.089385986328125 +86012 -0.20147705078125 +86013 -0.054779052734375 +86014 -0.044647216796875 +86015 -0.010711669921875 +86016 0.103973388671875 +86017 0.03155517578125 +86018 0.202392578125 +86019 0.060882568359375 +86020 0.264495849609375 +86021 0.08050537109375 +86022 0.338897705078125 +86023 0.10223388671875 +86024 0.443817138671875 +86025 0.13043212890625 +86026 0.545074462890625 +86027 0.156524658203125 +86028 0.6173095703125 +86029 0.1741943359375 +86030 0.6524658203125 +86031 0.1815185546875 +86032 0.66339111328125 +86033 0.1817626953125 +86034 0.6561279296875 +86035 0.176605224609375 +86036 0.606781005859375 +86037 0.160308837890625 +86038 0.501190185546875 +86039 0.129638671875 +86040 0.352783203125 +86041 0.088165283203125 +86042 0.176544189453125 +86043 0.039886474609375 +86044 -0.034820556640625 +86045 -0.0167236328125 +86046 -0.258209228515625 +86047 -0.07568359375 +86048 -0.44244384765625 +86049 -0.124176025390625 +86050 -0.5753173828125 +86051 -0.159027099609375 +86052 -0.65203857421875 +86053 -0.178985595703125 +86054 -0.641632080078125 +86055 -0.176361083984375 +86056 -0.562164306640625 +86057 -0.155670166015625 +86058 -0.458038330078125 +86059 -0.128021240234375 +86060 -0.350555419921875 +86061 -0.098785400390625 +86062 -0.260528564453125 +86063 -0.073272705078125 +86064 -0.192108154296875 +86065 -0.052703857421875 +86066 -0.141937255859375 +86067 -0.036468505859375 +86068 -0.1021728515625 +86069 -0.0228271484375 +86070 -0.062896728515625 +86071 -0.009521484375 +86072 -0.011932373046875 +86073 0.006256103515625 +86074 0.062835693359375 +86075 0.02734375 +86076 0.148712158203125 +86077 0.05047607421875 +86078 0.241729736328125 +86079 0.0745849609375 +86080 0.34912109375 +86081 0.101409912109375 +86082 0.457305908203125 +86083 0.12762451171875 +86084 0.54388427734375 +86085 0.147735595703125 +86086 0.5728759765625 +86087 0.15289306640625 +86088 0.506591796875 +86089 0.1339111328125 +86090 0.351226806640625 +86091 0.092437744140625 +86092 0.146514892578125 +86093 0.03851318359375 +86094 -0.05523681640625 +86095 -0.014678955078125 +86096 -0.21624755859375 +86097 -0.057586669921875 +86098 -0.334930419921875 +86099 -0.08966064453125 +86100 -0.402984619140625 +86101 -0.10870361328125 +86102 -0.4412841796875 +86103 -0.119781494140625 +86104 -0.49578857421875 +86105 -0.134246826171875 +86106 -0.5601806640625 +86107 -0.1505126953125 +86108 -0.600738525390625 +86109 -0.160186767578125 +86110 -0.584228515625 +86111 -0.15509033203125 +86112 -0.47930908203125 +86113 -0.12750244140625 +86114 -0.27935791015625 +86115 -0.075897216796875 +86116 -0.0089111328125 +86117 -0.006500244140625 +86118 0.268798828125 +86119 0.064849853515625 +86120 0.482818603515625 +86121 0.12042236328125 +86122 0.60369873046875 +86123 0.152801513671875 +86124 0.650421142578125 +86125 0.166534423828125 +86126 0.66400146484375 +86127 0.17169189453125 +86128 0.6414794921875 +86129 0.167449951171875 +86130 0.572540283203125 +86131 0.151214599609375 +86132 0.498138427734375 +86133 0.13311767578125 +86134 0.439453125 +86135 0.118377685546875 +86136 0.375518798828125 +86137 0.101806640625 +86138 0.274505615234375 +86139 0.075592041015625 +86140 0.1087646484375 +86141 0.032958984375 +86142 -0.099395751953125 +86143 -0.02044677734375 +86144 -0.3182373046875 +86145 -0.076629638671875 +86146 -0.5489501953125 +86147 -0.13580322265625 +86148 -0.7738037109375 +86149 -0.193450927734375 +86150 -0.86383056640625 +86151 -0.236358642578125 +86152 -0.870391845703125 +86153 -0.256195068359375 +86154 -0.86895751953125 +86155 -0.25726318359375 +86156 -0.861053466796875 +86157 -0.242767333984375 +86158 -0.765869140625 +86159 -0.208404541015625 +86160 -0.5301513671875 +86161 -0.1513671875 +86162 -0.214691162109375 +86163 -0.07342529296875 +86164 0.137359619140625 +86165 0.014678955078125 +86166 0.474822998046875 +86167 0.100189208984375 +86168 0.76239013671875 +86169 0.174224853515625 +86170 0.867462158203125 +86171 0.230010986328125 +86172 0.870361328125 +86173 0.267578125 +86174 0.86480712890625 +86175 0.283966064453125 +86176 0.831817626953125 +86177 0.280426025390625 +86178 0.677581787109375 +86179 0.262908935546875 +86180 0.495880126953125 +86181 0.232818603515625 +86182 0.30767822265625 +86183 0.1947021484375 +86184 0.116180419921875 +86185 0.149078369140625 +86186 -0.110748291015625 +86187 0.08807373046875 +86188 -0.381805419921875 +86189 0.00994873046875 +86190 -0.6572265625 +86191 -0.074615478515625 +86192 -0.857421875 +86193 -0.150726318359375 +86194 -0.870391845703125 +86195 -0.207672119140625 +86196 -0.870391845703125 +86197 -0.24365234375 +86198 -0.86444091796875 +86199 -0.265289306640625 +86200 -0.85723876953125 +86201 -0.2813720703125 +86202 -0.790008544921875 +86203 -0.28729248046875 +86204 -0.62847900390625 +86205 -0.26953125 +86206 -0.3956298828125 +86207 -0.227203369140625 +86208 -0.126708984375 +86209 -0.168426513671875 +86210 0.150115966796875 +86211 -0.0999755859375 +86212 0.424041748046875 +86213 -0.024749755859375 +86214 0.670623779296875 +86215 0.050567626953125 +86216 0.854522705078125 +86217 0.116363525390625 +86218 0.866485595703125 +86219 0.168243408203125 +86220 0.86920166015625 +86221 0.202301025390625 +86222 0.8653564453125 +86223 0.2230224609375 +86224 0.857147216796875 +86225 0.233673095703125 +86226 0.766845703125 +86227 0.233489990234375 +86228 0.628509521484375 +86229 0.223663330078125 +86230 0.462127685546875 +86231 0.202484130859375 +86232 0.297210693359375 +86233 0.176300048828125 +86234 0.14862060546875 +86235 0.148101806640625 +86236 -0.00537109375 +86237 0.112213134765625 +86238 -0.15753173828125 +86239 0.070526123046875 +86240 -0.31304931640625 +86241 0.022125244140625 +86242 -0.48876953125 +86243 -0.036407470703125 +86244 -0.6416015625 +86245 -0.09344482421875 +86246 -0.751373291015625 +86247 -0.142791748046875 +86248 -0.84619140625 +86249 -0.190155029296875 +86250 -0.861297607421875 +86251 -0.2318115234375 +86252 -0.863250732421875 +86253 -0.259521484375 +86254 -0.856597900390625 +86255 -0.265380859375 +86256 -0.7498779296875 +86257 -0.25238037109375 +86258 -0.624542236328125 +86259 -0.234832763671875 +86260 -0.47808837890625 +86261 -0.207275390625 +86262 -0.253387451171875 +86263 -0.15521240234375 +86264 0.003692626953125 +86265 -0.0899658203125 +86266 0.2257080078125 +86267 -0.028472900390625 +86268 0.427154541015625 +86269 0.032318115234375 +86270 0.643218994140625 +86271 0.100433349609375 +86272 0.855926513671875 +86273 0.1729736328125 +86274 0.870361328125 +86275 0.2354736328125 +86276 0.870361328125 +86277 0.27630615234375 +86278 0.862762451171875 +86279 0.29705810546875 +86280 0.79669189453125 +86281 0.29718017578125 +86282 0.595794677734375 +86283 0.274871826171875 +86284 0.362152099609375 +86285 0.23675537109375 +86286 0.1270751953125 +86287 0.18927001953125 +86288 -0.086944580078125 +86289 0.13739013671875 +86290 -0.2784423828125 +86291 0.082061767578125 +86292 -0.484832763671875 +86293 0.0162353515625 +86294 -0.729583740234375 +86295 -0.06378173828125 +86296 -0.86688232421875 +86297 -0.146636962890625 +86298 -0.870391845703125 +86299 -0.21826171875 +86300 -0.86859130859375 +86301 -0.277252197265625 +86302 -0.86279296875 +86303 -0.322967529296875 +86304 -0.817962646484375 +86305 -0.347503662109375 +86306 -0.6116943359375 +86307 -0.34100341796875 +86308 -0.3128662109375 +86309 -0.302001953125 +86310 0.039398193359375 +86311 -0.237884521484375 +86312 0.422821044921875 +86313 -0.153228759765625 +86314 0.805145263671875 +86315 -0.055511474609375 +86316 0.870361328125 +86317 0.0401611328125 +86318 0.870361328125 +86319 0.121124267578125 +86320 0.860015869140625 +86321 0.184478759765625 +86322 0.727935791015625 +86323 0.228179931640625 +86324 0.48114013671875 +86325 0.250640869140625 +86326 0.2059326171875 +86327 0.25677490234375 +86328 -0.06103515625 +86329 0.251220703125 +86330 -0.29913330078125 +86331 0.235992431640625 +86332 -0.516204833984375 +86333 0.207855224609375 +86334 -0.7252197265625 +86335 0.163543701171875 +86336 -0.85980224609375 +86337 0.1085205078125 +86338 -0.870391845703125 +86339 0.0504150390625 +86340 -0.870391845703125 +86341 -0.004119873046875 +86342 -0.858062744140625 +86343 -0.044219970703125 +86344 -0.673004150390625 +86345 -0.068634033203125 +86346 -0.42694091796875 +86347 -0.08831787109375 +86348 -0.2100830078125 +86349 -0.1124267578125 +86350 -0.0362548828125 +86351 -0.14013671875 +86352 0.10943603515625 +86353 -0.164794921875 +86354 0.23516845703125 +86355 -0.181793212890625 +86356 0.373687744140625 +86357 -0.182037353515625 +86358 0.517791748046875 +86359 -0.165863037109375 +86360 0.602783203125 +86361 -0.1468505859375 +86362 0.635711669921875 +86363 -0.12396240234375 +86364 0.655181884765625 +86365 -0.090179443359375 +86366 0.65948486328125 +86367 -0.0478515625 +86368 0.651275634765625 +86369 0.000946044921875 +86370 0.61846923828125 +86371 0.050567626953125 +86372 0.53753662109375 +86373 0.0926513671875 +86374 0.404144287109375 +86375 0.122955322265625 +86376 0.22186279296875 +86377 0.1390380859375 +86378 0.003997802734375 +86379 0.140899658203125 +86380 -0.22100830078125 +86381 0.132171630859375 +86382 -0.42449951171875 +86383 0.117156982421875 +86384 -0.579833984375 +86385 0.100341796875 +86386 -0.641876220703125 +86387 0.090911865234375 +86388 -0.6177978515625 +86389 0.08746337890625 +86390 -0.575531005859375 +86391 0.076141357421875 +86392 -0.526336669921875 +86393 0.055938720703125 +86394 -0.42645263671875 +86395 0.038299560546875 +86396 -0.2581787109375 +86397 0.0294189453125 +86398 -0.068695068359375 +86399 0.021728515625 +86400 0.09222412109375 +86401 0.00726318359375 +86402 0.232147216796875 +86403 -0.009613037109375 +86404 0.3509521484375 +86405 -0.026397705078125 +86406 0.410064697265625 +86407 -0.04925537109375 +86408 0.372955322265625 +86409 -0.084320068359375 +86410 0.2554931640625 +86411 -0.126922607421875 +86412 0.10711669921875 +86413 -0.165740966796875 +86414 -0.052886962890625 +86415 -0.196533203125 +86416 -0.186279296875 +86417 -0.2115478515625 +86418 -0.23291015625 +86419 -0.1988525390625 +86420 -0.209442138671875 +86421 -0.163543701171875 +86422 -0.174163818359375 +86423 -0.120086669921875 +86424 -0.126739501953125 +86425 -0.070526123046875 +86426 -0.048126220703125 +86427 -0.01300048828125 +86428 0.0426025390625 +86429 0.046142578125 +86430 0.10748291015625 +86431 0.0965576171875 +86432 0.1409912109375 +86433 0.1351318359375 +86434 0.19708251953125 +86435 0.171966552734375 +86436 0.273651123046875 +86437 0.2054443359375 +86438 0.31768798828125 +86439 0.223419189453125 +86440 0.341094970703125 +86441 0.228240966796875 +86442 0.368011474609375 +86443 0.22540283203125 +86444 0.37249755859375 +86445 0.209991455078125 +86446 0.30072021484375 +86447 0.171539306640625 +86448 0.1517333984375 +86449 0.11126708984375 +86450 -0.01470947265625 +86451 0.04376220703125 +86452 -0.1883544921875 +86453 -0.02691650390625 +86454 -0.372711181640625 +86455 -0.09967041015625 +86456 -0.51397705078125 +86457 -0.161102294921875 +86458 -0.57177734375 +86459 -0.20086669921875 +86460 -0.53948974609375 +86461 -0.21612548828125 +86462 -0.43511962890625 +86463 -0.209747314453125 +86464 -0.2962646484375 +86465 -0.189117431640625 +86466 -0.161102294921875 +86467 -0.162139892578125 +86468 -0.0435791015625 +86469 -0.131927490234375 +86470 0.060394287109375 +86471 -0.09808349609375 +86472 0.13665771484375 +86473 -0.064453125 +86474 0.170135498046875 +86475 -0.035400390625 +86476 0.16552734375 +86477 -0.011260986328125 +86478 0.15728759765625 +86479 0.013916015625 +86480 0.150787353515625 +86481 0.039794921875 +86482 0.12200927734375 +86483 0.059661865234375 +86484 0.080108642578125 +86485 0.074127197265625 +86486 0.05126953125 +86487 0.087646484375 +86488 0.062896728515625 +86489 0.105194091796875 +86490 0.09271240234375 +86491 0.121246337890625 +86492 0.092987060546875 +86493 0.1251220703125 +86494 0.07855224609375 +86495 0.1199951171875 +86496 0.06427001953125 +86497 0.109344482421875 +86498 0.0347900390625 +86499 0.090423583984375 +86500 -0.01171875 +86501 0.06365966796875 +86502 -0.056060791015625 +86503 0.034210205078125 +86504 -0.055511474609375 +86505 0.012481689453125 +86506 -0.010467529296875 +86507 -0.00030517578125 +86508 0.02508544921875 +86509 -0.01458740234375 +86510 0.025665283203125 +86511 -0.03466796875 +86512 0.017333984375 +86513 -0.053863525390625 +86514 0.00189208984375 +86515 -0.0709228515625 +86516 -0.03173828125 +86517 -0.087615966796875 +86518 -0.071502685546875 +86519 -0.100921630859375 +86520 -0.13543701171875 +86521 -0.1146240234375 +86522 -0.219970703125 +86523 -0.128082275390625 +86524 -0.300506591796875 +86525 -0.1363525390625 +86526 -0.376312255859375 +86527 -0.13995361328125 +86528 -0.416107177734375 +86529 -0.13299560546875 +86530 -0.371124267578125 +86531 -0.106048583984375 +86532 -0.242279052734375 +86533 -0.060333251953125 +86534 -0.069732666015625 +86535 -0.005279541015625 +86536 0.125640869140625 +86537 0.0535888671875 +86538 0.31268310546875 +86539 0.108795166015625 +86540 0.45501708984375 +86541 0.15203857421875 +86542 0.554779052734375 +86543 0.182952880859375 +86544 0.61065673828125 +86545 0.20074462890625 +86546 0.610931396484375 +86547 0.20281982421875 +86548 0.531463623046875 +86549 0.18438720703125 +86550 0.3883056640625 +86551 0.14892578125 +86552 0.23468017578125 +86553 0.107574462890625 +86554 0.095245361328125 +86555 0.0660400390625 +86556 -0.00396728515625 +86557 0.03033447265625 +86558 -0.04852294921875 +86559 0.004241943359375 +86560 -0.055145263671875 +86561 -0.0145263671875 +86562 -0.0758056640625 +86563 -0.035400390625 +86564 -0.138702392578125 +86565 -0.063140869140625 +86566 -0.209197998046875 +86567 -0.09002685546875 +86568 -0.289031982421875 +86569 -0.115753173828125 +86570 -0.37884521484375 +86571 -0.1400146484375 +86572 -0.456329345703125 +86573 -0.1580810546875 +86574 -0.51641845703125 +86575 -0.1689453125 +86576 -0.519287109375 +86577 -0.164794921875 +86578 -0.458251953125 +86579 -0.144622802734375 +86580 -0.384796142578125 +86581 -0.119293212890625 +86582 -0.323699951171875 +86583 -0.09442138671875 +86584 -0.269287109375 +86585 -0.069580078125 +86586 -0.1951904296875 +86587 -0.040283203125 +86588 -0.100006103515625 +86589 -0.007080078125 +86590 -0.01055908203125 +86591 0.02386474609375 +86592 0.1033935546875 +86593 0.057891845703125 +86594 0.24908447265625 +86595 0.095916748046875 +86596 0.373199462890625 +86597 0.126861572265625 +86598 0.45806884765625 +86599 0.14691162109375 +86600 0.511474609375 +86601 0.157562255859375 +86602 0.565399169921875 +86603 0.165313720703125 +86604 0.61138916015625 +86605 0.168701171875 +86606 0.5897216796875 +86607 0.15618896484375 +86608 0.4906005859375 +86609 0.1263427734375 +86610 0.33148193359375 +86611 0.083251953125 +86612 0.147796630859375 +86613 0.03466796875 +86614 -0.01873779296875 +86615 -0.010406494140625 +86616 -0.140289306640625 +86617 -0.045745849609375 +86618 -0.191986083984375 +86619 -0.0657958984375 +86620 -0.184295654296875 +86621 -0.072174072265625 +86622 -0.161834716796875 +86623 -0.07342529296875 +86624 -0.166595458984375 +86625 -0.07769775390625 +86626 -0.19390869140625 +86627 -0.08392333984375 +86628 -0.22442626953125 +86629 -0.0882568359375 +86630 -0.279754638671875 +86631 -0.09521484375 +86632 -0.3389892578125 +86633 -0.10089111328125 +86634 -0.3543701171875 +86635 -0.096160888671875 +86636 -0.348175048828125 +86637 -0.0859375 +86638 -0.32598876953125 +86639 -0.071868896484375 +86640 -0.2581787109375 +86641 -0.048583984375 +86642 -0.139801025390625 +86643 -0.015594482421875 +86644 0.014617919921875 +86645 0.023681640625 +86646 0.144378662109375 +86647 0.056610107421875 +86648 0.221038818359375 +86649 0.07720947265625 +86650 0.27069091796875 +86651 0.0904541015625 +86652 0.294036865234375 +86653 0.09637451171875 +86654 0.311767578125 +86655 0.099090576171875 +86656 0.339141845703125 +86657 0.1016845703125 +86658 0.360260009765625 +86659 0.10101318359375 +86660 0.360504150390625 +86661 0.09454345703125 +86662 0.308380126953125 +86663 0.07696533203125 +86664 0.18170166015625 +86665 0.044708251953125 +86666 0.0047607421875 +86667 0.0028076171875 +86668 -0.17559814453125 +86669 -0.039520263671875 +86670 -0.3143310546875 +86671 -0.073516845703125 +86672 -0.36785888671875 +86673 -0.0906982421875 +86674 -0.36248779296875 +86675 -0.09552001953125 +86676 -0.343536376953125 +86677 -0.0960693359375 +86678 -0.3018798828125 +86679 -0.09051513671875 +86680 -0.231414794921875 +86681 -0.07763671875 +86682 -0.117645263671875 +86683 -0.054840087890625 +86684 0.007049560546875 +86685 -0.02825927734375 +86686 0.087982177734375 +86687 -0.008209228515625 +86688 0.13946533203125 +86689 0.00762939453125 +86690 0.17425537109375 +86691 0.021209716796875 +86692 0.188201904296875 +86693 0.031341552734375 +86694 0.171234130859375 +86695 0.035736083984375 +86696 0.118438720703125 +86697 0.033111572265625 +86698 0.05706787109375 +86699 0.028106689453125 +86700 -0.010711669921875 +86701 0.020782470703125 +86702 -0.0914306640625 +86703 0.009674072265625 +86704 -0.162322998046875 +86705 -0.001129150390625 +86706 -0.194549560546875 +86707 -0.006439208984375 +86708 -0.1492919921875 +86709 0.000885009765625 +86710 -0.02166748046875 +86711 0.021820068359375 +86712 0.124053955078125 +86713 0.04473876953125 +86714 0.211151123046875 +86715 0.055755615234375 +86716 0.240447998046875 +86717 0.05535888671875 +86718 0.242218017578125 +86719 0.049468994140625 +86720 0.2257080078125 +86721 0.040130615234375 +86722 0.194366455078125 +86723 0.0283203125 +86724 0.115509033203125 +86725 0.008331298828125 +86726 0.0128173828125 +86727 -0.01513671875 +86728 -0.053802490234375 +86729 -0.030853271484375 +86730 -0.110626220703125 +86731 -0.043487548828125 +86732 -0.199493408203125 +86733 -0.0606689453125 +86734 -0.29437255859375 +86735 -0.07757568359375 +86736 -0.33221435546875 +86737 -0.08270263671875 +86738 -0.27972412109375 +86739 -0.070068359375 +86740 -0.185333251953125 +86741 -0.048797607421875 +86742 -0.128204345703125 +86743 -0.033660888671875 +86744 -0.115692138671875 +86745 -0.026275634765625 +86746 -0.116455078125 +86747 -0.021209716796875 +86748 -0.105926513671875 +86749 -0.01422119140625 +86750 -0.053955078125 +86751 0.0 +86752 0.048797607421875 +86753 0.02288818359375 +86754 0.157318115234375 +86755 0.04595947265625 +86756 0.212005615234375 +86757 0.058135986328125 +86758 0.218475341796875 +86759 0.060333251953125 +86760 0.23724365234375 +86761 0.06365966796875 +86762 0.30535888671875 +86763 0.074981689453125 +86764 0.38128662109375 +86765 0.086761474609375 +86766 0.404449462890625 +86767 0.08795166015625 +86768 0.3944091796875 +86769 0.082366943359375 +86770 0.3885498046875 +86771 0.077117919921875 +86772 0.362640380859375 +86773 0.0679931640625 +86774 0.27362060546875 +86775 0.047332763671875 +86776 0.11712646484375 +86777 0.014556884765625 +86778 -0.054901123046875 +86779 -0.020538330078125 +86780 -0.19085693359375 +86781 -0.04827880859375 +86782 -0.28570556640625 +86783 -0.067626953125 +86784 -0.339263916015625 +86785 -0.079071044921875 +86786 -0.3775634765625 +86787 -0.087127685546875 +86788 -0.445709228515625 +86789 -0.098663330078125 +86790 -0.535064697265625 +86791 -0.112060546875 +86792 -0.629058837890625 +86793 -0.1246337890625 +86794 -0.697601318359375 +86795 -0.131805419921875 +86796 -0.70391845703125 +86797 -0.128082275390625 +86798 -0.6424560546875 +86799 -0.11285400390625 +86800 -0.491241455078125 +86801 -0.0831298828125 +86802 -0.265716552734375 +86803 -0.041656494140625 +86804 -0.023712158203125 +86805 0.0023193359375 +86806 0.201751708984375 +86807 0.043365478515625 +86808 0.375823974609375 +86809 0.075836181640625 +86810 0.485076904296875 +86811 0.09735107421875 +86812 0.56884765625 +86813 0.113616943359375 +86814 0.634765625 +86815 0.1256103515625 +86816 0.63763427734375 +86817 0.12640380859375 +86818 0.5660400390625 +86819 0.1142578125 +86820 0.4720458984375 +86821 0.097198486328125 +86822 0.40692138671875 +86823 0.083221435546875 +86824 0.3778076171875 +86825 0.07366943359375 +86826 0.376953125 +86827 0.06768798828125 +86828 0.371978759765625 +86829 0.060638427734375 +86830 0.313140869140625 +86831 0.045318603515625 +86832 0.184417724609375 +86833 0.0196533203125 +86834 0.011199951171875 +86835 -0.012115478515625 +86836 -0.171051025390625 +86837 -0.0443115234375 +86838 -0.33740234375 +86839 -0.07293701171875 +86840 -0.47198486328125 +86841 -0.095428466796875 +86842 -0.560394287109375 +86843 -0.109527587890625 +86844 -0.58056640625 +86845 -0.11187744140625 +86846 -0.54754638671875 +86847 -0.1048583984375 +86848 -0.508575439453125 +86849 -0.095794677734375 +86850 -0.459503173828125 +86851 -0.084259033203125 +86852 -0.394378662109375 +86853 -0.069580078125 +86854 -0.35260009765625 +86855 -0.058013916015625 +86856 -0.31170654296875 +86857 -0.046478271484375 +86858 -0.197418212890625 +86859 -0.023956298828125 +86860 -0.007965087890625 +86861 0.009521484375 +86862 0.207489013671875 +86863 0.04620361328125 +86864 0.409210205078125 +86865 0.079864501953125 +86866 0.57208251953125 +86867 0.1065673828125 +86868 0.66595458984375 +86869 0.12164306640625 +86870 0.65875244140625 +86871 0.120208740234375 +86872 0.56744384765625 +86873 0.10491943359375 +86874 0.431396484375 +86875 0.08184814453125 +86876 0.29443359375 +86877 0.057830810546875 +86878 0.182464599609375 +86879 0.0369873046875 +86880 0.06365966796875 +86881 0.014739990234375 +86882 -0.075958251953125 +86883 -0.010772705078125 +86884 -0.189422607421875 +86885 -0.032196044921875 +86886 -0.271942138671875 +86887 -0.048553466796875 +86888 -0.342529296875 +86889 -0.06256103515625 +86890 -0.364166259765625 +86891 -0.068450927734375 +86892 -0.327239990234375 +86893 -0.064666748046875 +86894 -0.2769775390625 +86895 -0.0579833984375 +86896 -0.253692626953125 +86897 -0.05450439453125 +86898 -0.24365234375 +86899 -0.0521240234375 +86900 -0.1983642578125 +86901 -0.043548583984375 +86902 -0.116241455078125 +86903 -0.028656005859375 +86904 -0.036834716796875 +86905 -0.013641357421875 +86906 0.034881591796875 +86907 0.00054931640625 +86908 0.09124755859375 +86909 0.0125732421875 +86910 0.10888671875 +86911 0.0186767578125 +86912 0.125518798828125 +86913 0.0244140625 +86914 0.15771484375 +86915 0.032135009765625 +86916 0.17828369140625 +86917 0.037567138671875 +86918 0.17108154296875 +86919 0.03814697265625 +86920 0.129974365234375 +86921 0.032867431640625 +86922 0.082427978515625 +86923 0.025848388671875 +86924 0.027679443359375 +86925 0.01702880859375 +86926 -0.065643310546875 +86927 0.001678466796875 +86928 -0.15936279296875 +86929 -0.014312744140625 +86930 -0.21307373046875 +86931 -0.024658203125 +86932 -0.234649658203125 +86933 -0.03045654296875 +86934 -0.2001953125 +86935 -0.027923583984375 +86936 -0.119171142578125 +86937 -0.01837158203125 +86938 -0.024749755859375 +86939 -0.00665283203125 +86940 0.085784912109375 +86941 0.007720947265625 +86942 0.178131103515625 +86943 0.0196533203125 +86944 0.215576171875 +86945 0.023712158203125 +86946 0.211456298828125 +86947 0.02197265625 +86948 0.17523193359375 +86949 0.015960693359375 +86950 0.128753662109375 +86951 0.009002685546875 +86952 0.1019287109375 +86953 0.005615234375 +86954 0.0743408203125 +86955 0.002655029296875 +86956 0.04327392578125 +86957 -0.0003662109375 +86958 0.038177490234375 +86959 0.000885009765625 +86960 0.076263427734375 +86961 0.0089111328125 +86962 0.14105224609375 +86963 0.02105712890625 +86964 0.186431884765625 +86965 0.030181884765625 +86966 0.188812255859375 +86967 0.0325927734375 +86968 0.1390380859375 +86969 0.02679443359375 +86970 0.041778564453125 +86971 0.013427734375 +86972 -0.079437255859375 +86973 -0.00396728515625 +86974 -0.219390869140625 +86975 -0.024658203125 +86976 -0.367828369140625 +86977 -0.047088623046875 +86978 -0.494873046875 +86979 -0.066680908203125 +86980 -0.556243896484375 +86981 -0.076690673828125 +86982 -0.508697509765625 +86983 -0.070556640625 +86984 -0.3756103515625 +86985 -0.051727294921875 +86986 -0.218902587890625 +86987 -0.029541015625 +86988 -0.063751220703125 +86989 -0.007720947265625 +86990 0.091552734375 +86991 0.0140380859375 +86992 0.23602294921875 +86993 0.0341796875 +86994 0.342987060546875 +86995 0.04876708984375 +86996 0.39520263671875 +86997 0.055267333984375 +86998 0.389373779296875 +86999 0.053253173828125 +87000 0.324249267578125 +87001 0.042572021484375 +87002 0.224090576171875 +87003 0.0269775390625 +87004 0.124267578125 +87005 0.0118408203125 +87006 0.037078857421875 +87007 -0.000946044921875 +87008 -0.010101318359375 +87009 -0.00726318359375 +87010 -0.019439697265625 +87011 -0.00750732421875 +87012 -0.022796630859375 +87013 -0.006622314453125 +87014 -0.001556396484375 +87015 -0.0018310546875 +87016 0.056304931640625 +87017 0.008514404296875 +87018 0.106719970703125 +87019 0.017669677734375 +87020 0.096893310546875 +87021 0.01751708984375 +87022 0.042694091796875 +87023 0.010406494140625 +87024 -0.018035888671875 +87025 0.002044677734375 +87026 -0.07586669921875 +87027 -0.006134033203125 +87028 -0.11944580078125 +87029 -0.012420654296875 +87030 -0.15972900390625 +87031 -0.01849365234375 +87032 -0.202606201171875 +87033 -0.025238037109375 +87034 -0.24859619140625 +87035 -0.032684326171875 +87036 -0.30517578125 +87037 -0.041961669921875 +87038 -0.36212158203125 +87039 -0.051483154296875 +87040 -0.39141845703125 +87041 -0.05706787109375 +87042 -0.35528564453125 +87043 -0.053070068359375 +87044 -0.249969482421875 +87045 -0.03875732421875 +87046 -0.092864990234375 +87047 -0.016876220703125 +87048 0.08905029296875 +87049 0.00872802734375 +87050 0.2352294921875 +87051 0.0302734375 +87052 0.318817138671875 +87053 0.04412841796875 +87054 0.358642578125 +87055 0.05218505859375 +87056 0.347747802734375 +87057 0.053375244140625 +87058 0.28564453125 +87059 0.0474853515625 +87060 0.223175048828125 +87061 0.040557861328125 +87062 0.196746826171875 +87063 0.0369873046875 +87064 0.179840087890625 +87065 0.033660888671875 +87066 0.155548095703125 +87067 0.028656005859375 +87068 0.151214599609375 +87069 0.02545166015625 +87070 0.156951904296875 +87071 0.0230712890625 +87072 0.13177490234375 +87073 0.01678466796875 +87074 0.100799560546875 +87075 0.009796142578125 +87076 0.087127685546875 +87077 0.005096435546875 +87078 0.05487060546875 +87079 -0.001434326171875 +87080 -0.009002685546875 +87081 -0.01123046875 +87082 -0.10400390625 +87083 -0.02410888671875 +87084 -0.229400634765625 +87085 -0.0399169921875 +87086 -0.35552978515625 +87087 -0.055084228515625 +87088 -0.441925048828125 +87089 -0.06475830078125 +87090 -0.473846435546875 +87091 -0.067230224609375 +87092 -0.464813232421875 +87093 -0.064239501953125 +87094 -0.419097900390625 +87095 -0.056396484375 +87096 -0.334320068359375 +87097 -0.0435791015625 +87098 -0.227935791015625 +87099 -0.02801513671875 +87100 -0.12347412109375 +87101 -0.0126953125 +87102 -0.02764892578125 +87103 0.00140380859375 +87104 0.077667236328125 +87105 0.016326904296875 +87106 0.2132568359375 +87107 0.034454345703125 +87108 0.38885498046875 +87109 0.05682373046875 +87110 0.582794189453125 +87111 0.080780029296875 +87112 0.734039306640625 +87113 0.0989990234375 +87114 0.800140380859375 +87115 0.106414794921875 +87116 0.7783203125 +87117 0.10272216796875 +87118 0.6651611328125 +87119 0.08758544921875 +87120 0.45965576171875 +87121 0.061004638671875 +87122 0.199188232421875 +87123 0.027587890625 +87124 -0.050689697265625 +87125 -0.004638671875 +87126 -0.23297119140625 +87127 -0.028717041015625 +87128 -0.33013916015625 +87129 -0.042449951171875 +87130 -0.368408203125 +87131 -0.04888916015625 +87132 -0.378936767578125 +87133 -0.051666259765625 +87134 -0.376983642578125 +87135 -0.05255126953125 +87136 -0.37969970703125 +87137 -0.053558349609375 +87138 -0.391510009765625 +87139 -0.05517578125 +87140 -0.385345458984375 +87141 -0.054168701171875 +87142 -0.3419189453125 +87143 -0.048248291015625 +87144 -0.28289794921875 +87145 -0.0400390625 +87146 -0.251617431640625 +87147 -0.03485107421875 +87148 -0.266143798828125 +87149 -0.034912109375 +87150 -0.273345947265625 +87151 -0.033966064453125 +87152 -0.216796875 +87153 -0.02532958984375 +87154 -0.128265380859375 +87155 -0.012908935546875 +87156 -0.068145751953125 +87157 -0.0040283203125 +87158 -0.0430908203125 +87159 0.000396728515625 +87160 -0.024444580078125 +87161 0.00372314453125 +87162 0.020721435546875 +87163 0.00982666015625 +87164 0.124481201171875 +87165 0.022552490234375 +87166 0.25787353515625 +87167 0.03839111328125 +87168 0.379119873046875 +87169 0.0523681640625 +87170 0.47991943359375 +87171 0.063507080078125 +87172 0.5281982421875 +87173 0.06805419921875 +87174 0.511138916015625 +87175 0.06451416015625 +87176 0.456207275390625 +87177 0.0562744140625 +87178 0.407470703125 +87179 0.048736572265625 +87180 0.383758544921875 +87181 0.044281005859375 +87182 0.35687255859375 +87183 0.03955078125 +87184 0.31182861328125 +87185 0.032867431640625 +87186 0.250885009765625 +87187 0.024566650390625 +87188 0.1654052734375 +87189 0.013641357421875 +87190 0.035247802734375 +87191 -0.00225830078125 +87192 -0.142059326171875 +87193 -0.023406982421875 +87194 -0.33563232421875 +87195 -0.046142578125 +87196 -0.5345458984375 +87197 -0.069183349609375 +87198 -0.72186279296875 +87199 -0.090545654296875 +87200 -0.836669921875 +87201 -0.102935791015625 +87202 -0.8326416015625 +87203 -0.100921630859375 +87204 -0.7296142578125 +87205 -0.08697509765625 +87206 -0.582550048828125 +87207 -0.067840576171875 +87208 -0.440093994140625 +87209 -0.04937744140625 +87210 -0.324310302734375 +87211 -0.034332275390625 +87212 -0.20147705078125 +87213 -0.0186767578125 +87214 -0.044647216796875 +87215 0.000762939453125 +87216 0.103973388671875 +87217 0.01885986328125 +87218 0.202392578125 +87219 0.03057861328125 +87220 0.264495849609375 +87221 0.03759765625 +87222 0.338897705078125 +87223 0.0457763671875 +87224 0.443817138671875 +87225 0.057373046875 +87226 0.545074462890625 +87227 0.068328857421875 +87228 0.6173095703125 +87229 0.075653076171875 +87230 0.6524658203125 +87231 0.078460693359375 +87232 0.66339111328125 +87233 0.078399658203125 +87234 0.6561279296875 +87235 0.076263427734375 +87236 0.606781005859375 +87237 0.069244384765625 +87238 0.501190185546875 +87239 0.055694580078125 +87240 0.352783203125 +87241 0.037261962890625 +87242 0.176544189453125 +87243 0.015777587890625 +87244 -0.034820556640625 +87245 -0.00958251953125 +87246 -0.258209228515625 +87247 -0.036041259765625 +87248 -0.44244384765625 +87249 -0.0574951171875 +87250 -0.5753173828125 +87251 -0.072540283203125 +87252 -0.65203857421875 +87253 -0.080657958984375 +87254 -0.641632080078125 +87255 -0.078216552734375 +87256 -0.562164306640625 +87257 -0.06744384765625 +87258 -0.458038330078125 +87259 -0.053741455078125 +87260 -0.350555419921875 +87261 -0.039703369140625 +87262 -0.260528564453125 +87263 -0.027923583984375 +87264 -0.192108154296875 +87265 -0.0189208984375 +87266 -0.141937255859375 +87267 -0.0123291015625 +87268 -0.1021728515625 +87269 -0.007232666015625 +87270 -0.062896728515625 +87271 -0.00244140625 +87272 -0.011932373046875 +87273 0.00347900390625 +87274 0.062835693359375 +87275 0.011993408203125 +87276 0.148712158203125 +87277 0.021636962890625 +87278 0.241729736328125 +87279 0.031951904296875 +87280 0.34912109375 +87281 0.043853759765625 +87282 0.457305908203125 +87283 0.0557861328125 +87284 0.54388427734375 +87285 0.065093994140625 +87286 0.5728759765625 +87287 0.067535400390625 +87288 0.506591796875 +87289 0.058624267578125 +87290 0.351226806640625 +87291 0.0391845703125 +87292 0.146514892578125 +87293 0.014007568359375 +87294 -0.05523681640625 +87295 -0.010589599609375 +87296 -0.21624755859375 +87297 -0.02972412109375 +87298 -0.334930419921875 +87299 -0.043426513671875 +87300 -0.402984619140625 +87301 -0.051513671875 +87302 -0.4412841796875 +87303 -0.0557861328125 +87304 -0.49578857421875 +87305 -0.060333251953125 +87306 -0.5601806640625 +87307 -0.064697265625 +87308 -0.600738525390625 +87309 -0.0660400390625 +87310 -0.584228515625 +87311 -0.061614990234375 +87312 -0.47930908203125 +87313 -0.04888916015625 +87314 -0.27935791015625 +87315 -0.027496337890625 +87316 -0.0089111328125 +87317 0.000152587890625 +87318 0.268798828125 +87319 0.02825927734375 +87320 0.482818603515625 +87321 0.050384521484375 +87322 0.60369873046875 +87323 0.063751220703125 +87324 0.650421142578125 +87325 0.069915771484375 +87326 0.66400146484375 +87327 0.0723876953125 +87328 0.6414794921875 +87329 0.07086181640625 +87330 0.572540283203125 +87331 0.064453125 +87332 0.498138427734375 +87333 0.05682373046875 +87334 0.439453125 +87335 0.049896240234375 +87336 0.375518798828125 +87337 0.041961669921875 +87338 0.274505615234375 +87339 0.03033447265625 +87340 0.1087646484375 +87341 0.01275634765625 +87342 -0.099395751953125 +87343 -0.00860595703125 +87344 -0.3182373046875 +87345 -0.030792236328125 +87346 -0.5489501953125 +87347 -0.05377197265625 +87348 -0.7738037109375 +87349 -0.0758056640625 +87350 -0.86383056640625 +87351 -0.0921630859375 +87352 -0.870391845703125 +87353 -0.099822998046875 +87354 -0.86895751953125 +87355 -0.100311279296875 +87356 -0.861053466796875 +87357 -0.094757080078125 +87358 -0.765869140625 +87359 -0.0816650390625 +87360 -0.5301513671875 +87361 -0.06011962890625 +87362 -0.214691162109375 +87363 -0.030853271484375 +87364 0.137359619140625 +87365 0.00225830078125 +87366 0.474822998046875 +87367 0.034576416015625 +87368 0.76239013671875 +87369 0.06280517578125 +87370 0.867462158203125 +87371 0.084442138671875 +87372 0.870361328125 +87373 0.099395751953125 +87374 0.86480712890625 +87375 0.10650634765625 +87376 0.831817626953125 +87377 0.106170654296875 +87378 0.677581787109375 +87379 0.1004638671875 +87380 0.495880126953125 +87381 0.08990478515625 +87382 0.30767822265625 +87383 0.076080322265625 +87384 0.116180419921875 +87385 0.0592041015625 +87386 -0.110748291015625 +87387 0.03656005859375 +87388 -0.381805419921875 +87389 0.007598876953125 +87390 -0.6572265625 +87391 -0.0238037109375 +87392 -0.857421875 +87393 -0.052276611328125 +87394 -0.870391845703125 +87395 -0.073944091796875 +87396 -0.870391845703125 +87397 -0.088104248046875 +87398 -0.86444091796875 +87399 -0.097015380859375 +87400 -0.85723876953125 +87401 -0.103729248046875 +87402 -0.790008544921875 +87403 -0.1065673828125 +87404 -0.62847900390625 +87405 -0.1007080078125 +87406 -0.3956298828125 +87407 -0.085845947265625 +87408 -0.126708984375 +87409 -0.0648193359375 +87410 0.150115966796875 +87411 -0.040069580078125 +87412 0.424041748046875 +87413 -0.012664794921875 +87414 0.670623779296875 +87415 0.014984130859375 +87416 0.854522705078125 +87417 0.039398193359375 +87418 0.866485595703125 +87419 0.058929443359375 +87420 0.86920166015625 +87421 0.0721435546875 +87422 0.8653564453125 +87423 0.08056640625 +87424 0.857147216796875 +87425 0.085296630859375 +87426 0.766845703125 +87427 0.08599853515625 +87428 0.628509521484375 +87429 0.083099365234375 +87430 0.462127685546875 +87431 0.075958251953125 +87432 0.297210693359375 +87433 0.066802978515625 +87434 0.14862060546875 +87435 0.056671142578125 +87436 -0.00537109375 +87437 0.0435791015625 +87438 -0.15753173828125 +87439 0.028228759765625 +87440 -0.31304931640625 +87441 0.010345458984375 +87442 -0.48876953125 +87443 -0.01123046875 +87444 -0.6416015625 +87445 -0.032318115234375 +87446 -0.751373291015625 +87447 -0.050689697265625 +87448 -0.84619140625 +87449 -0.06829833984375 +87450 -0.861297607421875 +87451 -0.083770751953125 +87452 -0.863250732421875 +87453 -0.09417724609375 +87454 -0.856597900390625 +87455 -0.096649169921875 +87456 -0.7498779296875 +87457 -0.09222412109375 +87458 -0.624542236328125 +87459 -0.08599853515625 +87460 -0.47808837890625 +87461 -0.0760498046875 +87462 -0.253387451171875 +87463 -0.0572509765625 +87464 0.003692626953125 +87465 -0.033660888671875 +87466 0.2257080078125 +87467 -0.011322021484375 +87468 0.427154541015625 +87469 0.01080322265625 +87470 0.643218994140625 +87471 0.0355224609375 +87472 0.855926513671875 +87473 0.06195068359375 +87474 0.870361328125 +87475 0.0849609375 +87476 0.870361328125 +87477 0.10015869140625 +87478 0.862762451171875 +87479 0.108123779296875 +87480 0.79669189453125 +87481 0.108612060546875 +87482 0.595794677734375 +87483 0.10076904296875 +87484 0.362152099609375 +87485 0.087127685546875 +87486 0.1270751953125 +87487 0.070159912109375 +87488 -0.086944580078125 +87489 0.051727294921875 +87490 -0.2784423828125 +87491 0.032012939453125 +87492 -0.484832763671875 +87493 0.00799560546875 +87494 -0.729583740234375 +87495 -0.02197265625 +87496 -0.86688232421875 +87497 -0.053375244140625 +87498 -0.870391845703125 +87499 -0.08062744140625 +87500 -0.86859130859375 +87501 -0.103240966796875 +87502 -0.86279296875 +87503 -0.121002197265625 +87504 -0.817962646484375 +87505 -0.130706787109375 +87506 -0.6116943359375 +87507 -0.128387451171875 +87508 -0.3128662109375 +87509 -0.113372802734375 +87510 0.039398193359375 +87511 -0.088623046875 +87512 0.422821044921875 +87513 -0.055908203125 +87514 0.805145263671875 +87515 -0.0181884765625 +87516 0.870361328125 +87517 0.018524169921875 +87518 0.870361328125 +87519 0.049163818359375 +87520 0.860015869140625 +87521 0.072723388671875 +87522 0.727935791015625 +87523 0.088470458984375 +87524 0.48114013671875 +87525 0.095855712890625 +87526 0.2059326171875 +87527 0.097015380859375 +87528 -0.06103515625 +87529 0.0938720703125 +87530 -0.29913330078125 +87531 0.0872802734375 +87532 -0.516204833984375 +87533 0.075927734375 +87534 -0.7252197265625 +87535 0.0584716796875 +87536 -0.85980224609375 +87537 0.037078857421875 +87538 -0.870391845703125 +87539 0.0147705078125 +87540 -0.870391845703125 +87541 -0.005767822265625 +87542 -0.858062744140625 +87543 -0.020233154296875 +87544 -0.673004150390625 +87545 -0.028228759765625 +87546 -0.42694091796875 +87547 -0.034332275390625 +87548 -0.2100830078125 +87549 -0.0423583984375 +87550 -0.0362548828125 +87551 -0.052093505859375 +87552 0.10943603515625 +87553 -0.060577392578125 +87554 0.23516845703125 +87555 -0.065826416015625 +87556 0.373687744140625 +87557 -0.065399169921875 +87558 0.517791748046875 +87559 -0.05950927734375 +87560 0.602783203125 +87561 -0.051849365234375 +87562 0.635711669921875 +87563 -0.042388916015625 +87564 0.655181884765625 +87565 -0.029541015625 +87566 0.65948486328125 +87567 -0.014190673828125 +87568 0.651275634765625 +87569 0.002838134765625 +87570 0.61846923828125 +87571 0.019805908203125 +87572 0.53753662109375 +87573 0.0343017578125 +87574 0.404144287109375 +87575 0.0450439453125 +87576 0.22186279296875 +87577 0.05126953125 +87578 0.003997802734375 +87579 0.05291748046875 +87580 -0.22100830078125 +87581 0.0509033203125 +87582 -0.42449951171875 +87583 0.04632568359375 +87584 -0.579833984375 +87585 0.040435791015625 +87586 -0.641876220703125 +87587 0.03570556640625 +87588 -0.6177978515625 +87589 0.03192138671875 +87590 -0.575531005859375 +87591 0.025665283203125 +87592 -0.526336669921875 +87593 0.016876220703125 +87594 -0.42645263671875 +87595 0.00872802734375 +87596 -0.2581787109375 +87597 0.00299072265625 +87598 -0.068695068359375 +87599 -0.0020751953125 +87600 0.09222412109375 +87601 -0.00836181640625 +87602 0.232147216796875 +87603 -0.014617919921875 +87604 0.3509521484375 +87605 -0.020111083984375 +87606 0.410064697265625 +87607 -0.026397705078125 +87608 0.372955322265625 +87609 -0.035064697265625 +87610 0.2554931640625 +87611 -0.044952392578125 +87612 0.10711669921875 +87613 -0.053192138671875 +87614 -0.052886962890625 +87615 -0.058807373046875 +87616 -0.186279296875 +87617 -0.059967041015625 +87618 -0.23291015625 +87619 -0.0537109375 +87620 -0.209442138671875 +87621 -0.041534423828125 +87622 -0.174163818359375 +87623 -0.02734375 +87624 -0.126739501953125 +87625 -0.011871337890625 +87626 -0.048126220703125 +87627 0.005218505859375 +87628 0.0426025390625 +87629 0.022186279296875 +87630 0.10748291015625 +87631 0.036285400390625 +87632 0.1409912109375 +87633 0.046661376953125 +87634 0.19708251953125 +87635 0.055908203125 +87636 0.273651123046875 +87637 0.063690185546875 +87638 0.31768798828125 +87639 0.066925048828125 +87640 0.341094970703125 +87641 0.066314697265625 +87642 0.368011474609375 +87643 0.063385009765625 +87644 0.37249755859375 +87645 0.0570068359375 +87646 0.30072021484375 +87647 0.044586181640625 +87648 0.1517333984375 +87649 0.026580810546875 +87650 -0.01470947265625 +87651 0.00689697265625 +87652 -0.1883544921875 +87653 -0.013275146484375 +87654 -0.372711181640625 +87655 -0.0335693359375 +87656 -0.51397705078125 +87657 -0.050445556640625 +87658 -0.57177734375 +87659 -0.061187744140625 +87660 -0.53948974609375 +87661 -0.0650634765625 +87662 -0.43511962890625 +87663 -0.06280517578125 +87664 -0.2962646484375 +87665 -0.056396484375 +87666 -0.161102294921875 +87667 -0.047943115234375 +87668 -0.0435791015625 +87669 -0.038360595703125 +87670 0.060394287109375 +87671 -0.02764892578125 +87672 0.13665771484375 +87673 -0.01690673828125 +87674 0.170135498046875 +87675 -0.00738525390625 +87676 0.16552734375 +87677 0.000732421875 +87678 0.15728759765625 +87679 0.008880615234375 +87680 0.150787353515625 +87681 0.016876220703125 +87682 0.12200927734375 +87683 0.022918701171875 +87684 0.080108642578125 +87685 0.027130126953125 +87686 0.05126953125 +87687 0.030670166015625 +87688 0.062896728515625 +87689 0.034820556640625 +87690 0.09271240234375 +87691 0.038177490234375 +87692 0.092987060546875 +87693 0.038055419921875 +87694 0.07855224609375 +87695 0.03533935546875 +87696 0.06427001953125 +87697 0.031005859375 +87698 0.0347900390625 +87699 0.0244140625 +87700 -0.01171875 +87701 0.015777587890625 +87702 -0.056060791015625 +87703 0.00653076171875 +87704 -0.055511474609375 +87705 -0.000518798828125 +87706 -0.010467529296875 +87707 -0.0050048828125 +87708 0.02508544921875 +87709 -0.009521484375 +87710 0.025665283203125 +87711 -0.01519775390625 +87712 0.017333984375 +87713 -0.020263671875 +87714 0.00189208984375 +87715 -0.0244140625 +87716 -0.03173828125 +87717 -0.02813720703125 +87718 -0.071502685546875 +87719 -0.03070068359375 +87720 -0.13543701171875 +87721 -0.033111572265625 +87722 -0.219970703125 +87723 -0.0352783203125 +87724 -0.300506591796875 +87725 -0.035980224609375 +87726 -0.376312255859375 +87727 -0.035430908203125 +87728 -0.416107177734375 +87729 -0.03216552734375 +87730 -0.371124267578125 +87731 -0.0238037109375 +87732 -0.242279052734375 +87733 -0.0107421875 +87734 -0.069732666015625 +87735 0.004425048828125 +87736 0.125640869140625 +87737 0.020263671875 +87738 0.31268310546875 +87739 0.0347900390625 +87740 0.45501708984375 +87741 0.04571533203125 +87742 0.554779052734375 +87743 0.05303955078125 +87744 0.61065673828125 +87745 0.056640625 +87746 0.610931396484375 +87747 0.055908203125 +87748 0.531463623046875 +87749 0.049560546875 +87750 0.3883056640625 +87751 0.038604736328125 +87752 0.23468017578125 +87753 0.0262451171875 +87754 0.095245361328125 +87755 0.014129638671875 +87756 -0.00396728515625 +87757 0.003936767578125 +87758 -0.04852294921875 +87759 -0.0032958984375 +87760 -0.055145263671875 +87761 -0.008209228515625 +87762 -0.0758056640625 +87763 -0.01348876953125 +87764 -0.138702392578125 +87765 -0.020477294921875 +87766 -0.209197998046875 +87767 -0.027069091796875 +87768 -0.289031982421875 +87769 -0.033233642578125 +87770 -0.37884521484375 +87771 -0.0389404296875 +87772 -0.456329345703125 +87773 -0.04296875 +87774 -0.51641845703125 +87775 -0.0450439453125 +87776 -0.519287109375 +87777 -0.04302978515625 +87778 -0.458251953125 +87779 -0.036712646484375 +87780 -0.384796142578125 +87781 -0.029144287109375 +87782 -0.323699951171875 +87783 -0.02191162109375 +87784 -0.269287109375 +87785 -0.014923095703125 +87786 -0.1951904296875 +87787 -0.00689697265625 +87788 -0.100006103515625 +87789 0.001983642578125 +87790 -0.01055908203125 +87791 0.010040283203125 +87792 0.1033935546875 +87793 0.018798828125 +87794 0.24908447265625 +87795 0.028533935546875 +87796 0.373199462890625 +87797 0.03619384765625 +87798 0.45806884765625 +87799 0.040802001953125 +87800 0.511474609375 +87801 0.042816162109375 +87802 0.565399169921875 +87803 0.044097900390625 +87804 0.61138916015625 +87805 0.0443115234375 +87806 0.5897216796875 +87807 0.040252685546875 +87808 0.4906005859375 +87809 0.031646728515625 +87810 0.33148193359375 +87811 0.019775390625 +87812 0.147796630859375 +87813 0.006683349609375 +87814 -0.01873779296875 +87815 -0.005340576171875 +87816 -0.140289306640625 +87817 -0.014739990234375 +87818 -0.191986083984375 +87819 -0.020111083984375 +87820 -0.184295654296875 +87821 -0.021820068359375 +87822 -0.161834716796875 +87823 -0.02203369140625 +87824 -0.166595458984375 +87825 -0.022796630859375 +87826 -0.19390869140625 +87827 -0.02386474609375 +87828 -0.22442626953125 +87829 -0.024322509765625 +87830 -0.279754638671875 +87831 -0.025299072265625 +87832 -0.3389892578125 +87833 -0.025909423828125 +87834 -0.3543701171875 +87835 -0.02386474609375 +87836 -0.348175048828125 +87837 -0.02044677734375 +87838 -0.32598876953125 +87839 -0.016143798828125 +87840 -0.2581787109375 +87841 -0.0096435546875 +87842 -0.139801025390625 +87843 -0.000885009765625 +87844 0.014617919921875 +87845 0.00927734375 +87846 0.144378662109375 +87847 0.01763916015625 +87848 0.221038818359375 +87849 0.022735595703125 +87850 0.27069091796875 +87851 0.025787353515625 +87852 0.294036865234375 +87853 0.02685546875 +87854 0.311767578125 +87855 0.0269775390625 +87856 0.339141845703125 +87857 0.026885986328125 +87858 0.360260009765625 +87859 0.02557373046875 +87860 0.360504150390625 +87861 0.022552490234375 +87862 0.308380126953125 +87863 0.01739501953125 +87864 0.18170166015625 +87865 0.009857177734375 +87866 0.0047607421875 +87867 0.000885009765625 +87868 -0.17559814453125 +87869 -0.008056640625 +87870 -0.3143310546875 +87871 -0.015625 +87872 -0.36785888671875 +87873 -0.0205078125 +87874 -0.36248779296875 +87875 -0.023162841796875 +87876 -0.343536376953125 +87877 -0.024566650390625 +87878 -0.3018798828125 +87879 -0.0244140625 +87880 -0.231414794921875 +87881 -0.022552490234375 +87882 -0.117645263671875 +87883 -0.0186767578125 +87884 0.007049560546875 +87885 -0.013671875 +87886 0.087982177734375 +87887 -0.00897216796875 +87888 0.13946533203125 +87889 -0.004425048828125 +87890 0.17425537109375 +87891 6.103515625e-05 +87892 0.188201904296875 +87893 0.004180908203125 +87894 0.171234130859375 +87895 0.007476806640625 +87896 0.118438720703125 +87897 0.0096435546875 +87898 0.05706787109375 +87899 0.01116943359375 +87900 -0.010711669921875 +87901 0.011962890625 +87902 -0.0914306640625 +87903 0.01171875 +87904 -0.162322998046875 +87905 0.010894775390625 +87906 -0.194549560546875 +87907 0.010162353515625 +87908 -0.1492919921875 +87909 0.010467529296875 +87910 -0.02166748046875 +87911 0.011993408203125 +87912 0.124053955078125 +87913 0.0133056640625 +87914 0.211151123046875 +87915 0.012664794921875 +87916 0.240447998046875 +87917 0.010284423828125 +87918 0.242218017578125 +87919 0.007049560546875 +87920 0.2257080078125 +87921 0.00341796875 +87922 0.194366455078125 +87923 -0.000335693359375 +87924 0.115509033203125 +87925 -0.00482177734375 +87926 0.0128173828125 +87927 -0.00933837890625 +87928 -0.053802490234375 +87929 -0.012359619140625 +87930 -0.110626220703125 +87931 -0.01446533203125 +87932 -0.199493408203125 +87933 -0.016632080078125 +87934 -0.29437255859375 +87935 -0.018280029296875 +87936 -0.33221435546875 +87937 -0.0179443359375 +87938 -0.27972412109375 +87939 -0.014923095703125 +87940 -0.185333251953125 +87941 -0.010467529296875 +87942 -0.128204345703125 +87943 -0.006591796875 +87944 -0.115692138671875 +87945 -0.003631591796875 +87946 -0.116455078125 +87947 -0.001007080078125 +87948 -0.105926513671875 +87949 0.001708984375 +87950 -0.053955078125 +87951 0.005126953125 +87952 0.048797607421875 +87953 0.009368896484375 +87954 0.157318115234375 +87955 0.01324462890625 +87956 0.212005615234375 +87957 0.015289306640625 +87958 0.218475341796875 +87959 0.015594482421875 +87960 0.23724365234375 +87961 0.015594482421875 +87962 0.30535888671875 +87963 0.016265869140625 +87964 0.38128662109375 +87965 0.016632080078125 +87966 0.404449462890625 +87967 0.015380859375 +87968 0.3944091796875 +87969 0.0130615234375 +87970 0.3885498046875 +87971 0.010711669921875 +87972 0.362640380859375 +87973 0.00787353515625 +87974 0.27362060546875 +87975 0.003662109375 +87976 0.11712646484375 +87977 -0.00189208984375 +87978 -0.054901123046875 +87979 -0.007476806640625 +87980 -0.19085693359375 +87981 -0.01177978515625 +87982 -0.28570556640625 +87983 -0.014678955078125 +87984 -0.339263916015625 +87985 -0.01611328125 +87986 -0.3775634765625 +87987 -0.0167236328125 +87988 -0.445709228515625 +87989 -0.017608642578125 +87990 -0.535064697265625 +87991 -0.01861572265625 +87992 -0.629058837890625 +87993 -0.0194091796875 +87994 -0.697601318359375 +87995 -0.019317626953125 +87996 -0.70391845703125 +87997 -0.017608642578125 +87998 -0.6424560546875 +87999 -0.014251708984375 +88000 -0.491241455078125 +88001 -0.008819580078125 +88002 -0.265716552734375 +88003 -0.001800537109375 +88004 -0.023712158203125 +88005 0.005279541015625 +88006 0.201751708984375 +88007 0.0115966796875 +88008 0.375823974609375 +88009 0.0162353515625 +88010 0.485076904296875 +88011 0.0189208984375 +88012 0.56884765625 +88013 0.0206298828125 +88014 0.634765625 +88015 0.02154541015625 +88016 0.63763427734375 +88017 0.020599365234375 +88018 0.5660400390625 +88019 0.017608642578125 +88020 0.4720458984375 +88021 0.013885498046875 +88022 0.40692138671875 +88023 0.010772705078125 +88024 0.3778076171875 +88025 0.008514404296875 +88026 0.376953125 +88027 0.00701904296875 +88028 0.371978759765625 +88029 0.005584716796875 +88030 0.313140869140625 +88031 0.0030517578125 +88032 0.184417724609375 +88033 -0.000885009765625 +88034 0.011199951171875 +88035 -0.00555419921875 +88036 -0.171051025390625 +88037 -0.010040283203125 +88038 -0.33740234375 +88039 -0.013763427734375 +88040 -0.47198486328125 +88041 -0.016387939453125 +88042 -0.560394287109375 +88043 -0.01763916015625 +88044 -0.58056640625 +88045 -0.01702880859375 +88046 -0.54754638671875 +88047 -0.014984130859375 +88048 -0.508575439453125 +88049 -0.012725830078125 +88050 -0.459503173828125 +88051 -0.010223388671875 +88052 -0.394378662109375 +88053 -0.00738525390625 +88054 -0.35260009765625 +88055 -0.005218505859375 +88056 -0.31170654296875 +88057 -0.00323486328125 +88058 -0.197418212890625 +88059 0.000274658203125 +88060 -0.007965087890625 +88061 0.00531005859375 +88062 0.207489013671875 +88063 0.0106201171875 +88064 0.409210205078125 +88065 0.0152587890625 +88066 0.57208251953125 +88067 0.018341064453125 +88068 0.66595458984375 +88069 0.0194091796875 +88070 0.65875244140625 +88071 0.0184326171875 +88072 0.56744384765625 +88073 0.015838623046875 +88074 0.431396484375 +88075 0.012176513671875 +88076 0.29443359375 +88077 0.008056640625 +88078 0.182464599609375 +88079 0.00390625 +88080 0.06365966796875 +88081 -0.000244140625 +88082 -0.075958251953125 +88083 -0.00433349609375 +88084 -0.189422607421875 +88085 -0.0078125 +88086 -0.271942138671875 +88087 -0.010528564453125 +88088 -0.342529296875 +88089 -0.012542724609375 +88090 -0.364166259765625 +88091 -0.01348876953125 +88092 -0.327239990234375 +88093 -0.013275146484375 +88094 -0.2769775390625 +88095 -0.012298583984375 +88096 -0.253692626953125 +88097 -0.010955810546875 +88098 -0.24365234375 +88099 -0.009246826171875 +88100 -0.1983642578125 +88101 -0.0068359375 +88102 -0.116241455078125 +88103 -0.003875732421875 +88104 -0.036834716796875 +88105 -0.000823974609375 +88106 0.034881591796875 +88107 0.00213623046875 +88108 0.09124755859375 +88109 0.004791259765625 +88110 0.10888671875 +88111 0.006866455078125 +88112 0.125518798828125 +88113 0.008544921875 +88114 0.15771484375 +88115 0.0098876953125 +88116 0.17828369140625 +88117 0.010650634765625 +88118 0.17108154296875 +88119 0.010650634765625 +88120 0.129974365234375 +88121 0.009857177734375 +88122 0.082427978515625 +88123 0.008544921875 +88124 0.027679443359375 +88125 0.00677490234375 +88126 -0.065643310546875 +88127 0.004425048828125 +88128 -0.15936279296875 +88129 0.001861572265625 +88130 -0.21307373046875 +88131 -0.000457763671875 +88132 -0.234649658203125 +88133 -0.00250244140625 +88134 -0.2001953125 +88135 -0.003997802734375 +88136 -0.119171142578125 +88137 -0.00494384765625 +88138 -0.024749755859375 +88139 -0.0054931640625 +88140 0.085784912109375 +88141 -0.005615234375 +88142 0.178131103515625 +88143 -0.0054931640625 +88144 0.215576171875 +88145 -0.005401611328125 +88146 0.211456298828125 +88147 -0.005218505859375 +88148 0.17523193359375 +88149 -0.004913330078125 +88150 0.128753662109375 +88151 -0.004302978515625 +88152 0.1019287109375 +88153 -0.003204345703125 +88154 0.0743408203125 +88155 -0.001861572265625 +88156 0.04327392578125 +88157 -0.00042724609375 +88158 0.038177490234375 +88159 0.001190185546875 +88160 0.076263427734375 +88161 0.003021240234375 +88162 0.14105224609375 +88163 0.0048828125 +88164 0.186431884765625 +88165 0.00634765625 +88166 0.188812255859375 +88167 0.007171630859375 +88168 0.1390380859375 +88169 0.00726318359375 +88170 0.041778564453125 +88171 0.006622314453125 +88172 -0.079437255859375 +88173 0.005462646484375 +88174 -0.219390869140625 +88175 0.00384521484375 +88176 -0.367828369140625 +88177 0.00189208984375 +88178 -0.494873046875 +88179 -9.1552734375e-05 +88180 -0.556243896484375 +88181 -0.001678466796875 +88182 -0.508697509765625 +88183 -0.002471923828125 +88184 -0.3756103515625 +88185 -0.002593994140625 +88186 -0.218902587890625 +88187 -0.002471923828125 +88188 -0.063751220703125 +88189 -0.0023193359375 +88190 0.091552734375 +88191 -0.002044677734375 +88192 0.23602294921875 +88193 -0.001678466796875 +88194 0.342987060546875 +88195 -0.001373291015625 +88196 0.39520263671875 +88197 -0.001251220703125 +88198 0.389373779296875 +88199 -0.001312255859375 +88200 0.324249267578125 +88201 -0.001556396484375 +88202 0.224090576171875 +88203 -0.001800537109375 +88204 0.124267578125 +88205 -0.001800537109375 +88206 0.037078857421875 +88207 -0.00152587890625 +88208 -0.010101318359375 +88209 -0.000823974609375 +88210 -0.019439697265625 +88211 0.00018310546875 +88212 -0.022796630859375 +88213 0.001190185546875 +88214 -0.001556396484375 +88215 0.002288818359375 +88216 0.056304931640625 +88217 0.003509521484375 +88218 0.106719970703125 +88219 0.004486083984375 +88220 0.096893310546875 +88221 0.004730224609375 +88222 0.042694091796875 +88223 0.00439453125 +88224 -0.018035888671875 +88225 0.0037841796875 +88226 -0.07586669921875 +88227 0.00299072265625 +88228 -0.11944580078125 +88229 0.002105712890625 +88230 -0.15972900390625 +88231 0.0010986328125 +88232 -0.202606201171875 +88233 0.0 +88234 -0.24859619140625 +88235 -0.001129150390625 +88236 -0.30517578125 +88237 -0.0023193359375 +88238 -0.36212158203125 +88239 -0.00347900390625 +88240 -0.39141845703125 +88241 -0.00433349609375 +88242 -0.35528564453125 +88243 -0.00457763671875 +88244 -0.249969482421875 +88245 -0.004119873046875 +88246 -0.092864990234375 +88247 -0.003082275390625 +88248 0.08905029296875 +88249 -0.001708984375 +88250 0.2352294921875 +88251 -0.000457763671875 +88252 0.318817138671875 +88253 0.00042724609375 +88254 0.358642578125 +88255 0.001068115234375 +88256 0.347747802734375 +88257 0.00140380859375 +88258 0.28564453125 +88259 0.001373291015625 +88260 0.223175048828125 +88261 0.0013427734375 +88262 0.196746826171875 +88263 0.0015869140625 +88264 0.179840087890625 +88265 0.001922607421875 +88266 0.155548095703125 +88267 0.002166748046875 +88268 0.151214599609375 +88269 0.00250244140625 +88270 0.156951904296875 +88271 0.002838134765625 +88272 0.13177490234375 +88273 0.002838134765625 +88274 0.100799560546875 +88275 0.002685546875 +88276 0.087127685546875 +88277 0.0025634765625 +88278 0.05487060546875 +88279 0.002197265625 +88280 -0.009002685546875 +88281 0.001495361328125 +88282 -0.10400390625 +88283 0.000457763671875 +88284 -0.229400634765625 +88285 -0.0008544921875 +88286 -0.35552978515625 +88287 -0.002197265625 +88288 -0.441925048828125 +88289 -0.003204345703125 +88290 -0.473846435546875 +88291 -0.0037841796875 +88292 -0.464813232421875 +88293 -0.003997802734375 +88294 -0.419097900390625 +88295 -0.003875732421875 +88296 -0.334320068359375 +88297 -0.00335693359375 +88298 -0.227935791015625 +88299 -0.002593994140625 +88300 -0.12347412109375 +88301 -0.00177001953125 +88302 -0.02764892578125 +88303 -0.000946044921875 +88304 0.077667236328125 +88305 0.0 +88306 0.2132568359375 +88307 0.001220703125 +88308 0.38885498046875 +88309 0.002777099609375 +88310 0.582794189453125 +88311 0.004486083984375 +88312 0.734039306640625 +88313 0.005828857421875 +88314 0.800140380859375 +88315 0.0064697265625 +88316 0.7783203125 +88317 0.006378173828125 +88318 0.6651611328125 +88319 0.00555419921875 +88320 0.45965576171875 +88321 0.003509521484375 +88322 0.199188232421875 +88323 0.0 +88324 -0.050689697265625 +88325 -0.00347900390625 +88326 -0.23297119140625 +88327 -0.00482177734375 +88328 -0.33013916015625 +88329 -0.003509521484375 +88330 -0.368408203125 +88331 -0.000732421875 +88332 -0.378936767578125 +88333 0.002105712890625 +88334 -0.376983642578125 +88335 0.00433349609375 +88336 -0.37969970703125 +88337 0.005218505859375 +88338 -0.391510009765625 +88339 0.004608154296875 +88340 -0.385345458984375 +88341 0.003662109375 +88342 -0.3419189453125 +88343 0.003265380859375 +88344 -0.28289794921875 +88345 0.002716064453125 +88346 -0.251617431640625 +88347 0.00042724609375 +88348 -0.266143798828125 +88349 -0.004058837890625 +88350 -0.273345947265625 +88351 -0.0084228515625 +88352 -0.216796875 +88353 -0.010223388671875 +88354 -0.128265380859375 +88355 -0.010498046875 +88356 -0.068145751953125 +88357 -0.011444091796875 +88358 -0.0430908203125 +88359 -0.013153076171875 +88360 -0.024444580078125 +88361 -0.014373779296875 +88362 0.020721435546875 +88363 -0.013702392578125 +88364 0.124481201171875 +88365 -0.00982666015625 +88366 0.25787353515625 +88367 -0.003936767578125 +88368 0.379119873046875 +88369 0.002197265625 +88370 0.47991943359375 +88371 0.0081787109375 +88372 0.5281982421875 +88373 0.012603759765625 +88374 0.511138916015625 +88375 0.01483154296875 +88376 0.456207275390625 +88377 0.0157470703125 +88378 0.407470703125 +88379 0.0169677734375 +88380 0.383758544921875 +88381 0.019073486328125 +88382 0.35687255859375 +88383 0.020721435546875 +88384 0.31182861328125 +88385 0.02117919921875 +88386 0.250885009765625 +88387 0.02044677734375 +88388 0.1654052734375 +88389 0.01812744140625 +88390 0.035247802734375 +88391 0.013336181640625 +88392 -0.142059326171875 +88393 0.006011962890625 +88394 -0.33563232421875 +88395 -0.0025634765625 +88396 -0.5345458984375 +88397 -0.011871337890625 +88398 -0.72186279296875 +88399 -0.021148681640625 +88400 -0.836669921875 +88401 -0.02783203125 +88402 -0.8326416015625 +88403 -0.02996826171875 +88404 -0.7296142578125 +88405 -0.028228759765625 +88406 -0.582550048828125 +88407 -0.024688720703125 +88408 -0.440093994140625 +88409 -0.02117919921875 +88410 -0.324310302734375 +88411 -0.018463134765625 +88412 -0.20147705078125 +88413 -0.01507568359375 +88414 -0.044647216796875 +88415 -0.009857177734375 +88416 0.103973388671875 +88417 -0.00445556640625 +88418 0.202392578125 +88419 -0.00054931640625 +88420 0.264495849609375 +88421 0.00238037109375 +88422 0.338897705078125 +88423 0.0062255859375 +88424 0.443817138671875 +88425 0.01165771484375 +88426 0.545074462890625 +88427 0.0172119140625 +88428 0.6173095703125 +88429 0.021820068359375 +88430 0.6524658203125 +88431 0.025054931640625 +88432 0.66339111328125 +88433 0.027313232421875 +88434 0.6561279296875 +88435 0.02874755859375 +88436 0.606781005859375 +88437 0.028289794921875 +88438 0.501190185546875 +88439 0.025299072265625 +88440 0.352783203125 +88441 0.020263671875 +88442 0.176544189453125 +88443 0.013763427734375 +88444 -0.034820556640625 +88445 0.0054931640625 +88446 -0.258209228515625 +88447 -0.003570556640625 +88448 -0.44244384765625 +88449 -0.011383056640625 +88450 -0.5753173828125 +88451 -0.017425537109375 +88452 -0.65203857421875 +88453 -0.021484375 +88454 -0.641632080078125 +88455 -0.022247314453125 +88456 -0.562164306640625 +88457 -0.020416259765625 +88458 -0.458038330078125 +88459 -0.017669677734375 +88460 -0.350555419921875 +88461 -0.014739990234375 +88462 -0.260528564453125 +88463 -0.01239013671875 +88464 -0.192108154296875 +88465 -0.0107421875 +88466 -0.141937255859375 +88467 -0.00958251953125 +88468 -0.1021728515625 +88469 -0.008544921875 +88470 -0.062896728515625 +88471 -0.00726318359375 +88472 -0.011932373046875 +88473 -0.005218505859375 +88474 0.062835693359375 +88475 -0.001953125 +88476 0.148712158203125 +88477 0.00201416015625 +88478 0.241729736328125 +88479 0.0064697265625 +88480 0.34912109375 +88481 0.01165771484375 +88482 0.457305908203125 +88483 0.0169677734375 +88484 0.54388427734375 +88485 0.02142333984375 +88486 0.5728759765625 +88487 0.0235595703125 +88488 0.506591796875 +88489 0.021820068359375 +88490 0.351226806640625 +88491 0.016387939453125 +88492 0.146514892578125 +88493 0.008819580078125 +88494 -0.05523681640625 +88495 0.001190185546875 +88496 -0.21624755859375 +88497 -0.004974365234375 +88498 -0.334930419921875 +88499 -0.009613037109375 +88500 -0.402984619140625 +88501 -0.01239013671875 +88502 -0.4412841796875 +88503 -0.014129638671875 +88504 -0.49578857421875 +88505 -0.016693115234375 +88506 -0.5601806640625 +88507 -0.019775390625 +88508 -0.600738525390625 +88509 -0.02197265625 +88510 -0.584228515625 +88511 -0.02197265625 +88512 -0.47930908203125 +88513 -0.018463134765625 +88514 -0.27935791015625 +88515 -0.01116943359375 +88516 -0.0089111328125 +88517 -0.001007080078125 +88518 0.268798828125 +88519 0.009490966796875 +88520 0.482818603515625 +88521 0.01751708984375 +88522 0.60369873046875 +88523 0.021881103515625 +88524 0.650421142578125 +88525 0.023406982421875 +88526 0.66400146484375 +88527 0.023773193359375 +88528 0.6414794921875 +88529 0.022857666015625 +88530 0.572540283203125 +88531 0.020233154296875 +88532 0.498138427734375 +88533 0.01751708984375 +88534 0.439453125 +88535 0.01556396484375 +88536 0.375518798828125 +88537 0.01348876953125 +88538 0.274505615234375 +88539 0.010009765625 +88540 0.1087646484375 +88541 0.00396728515625 +88542 -0.099395751953125 +88543 -0.00372314453125 +88544 -0.3182373046875 +88545 -0.0118408203125 +88546 -0.5489501953125 +88547 -0.020477294921875 +88548 -0.7738037109375 +88549 -0.028900146484375 +88550 -0.86383056640625 +88551 -0.035064697265625 +88552 -0.870391845703125 +88553 -0.03765869140625 +88554 -0.86895751953125 +88555 -0.03741455078125 +88556 -0.861053466796875 +88557 -0.034881591796875 +88558 -0.765869140625 +88559 -0.02935791015625 +88560 -0.5301513671875 +88561 -0.020416259765625 +88562 -0.214691162109375 +88563 -0.00830078125 +88564 0.137359619140625 +88565 0.005279541015625 +88566 0.474822998046875 +88567 0.018310546875 +88568 0.76239013671875 +88569 0.0294189453125 +88570 0.867462158203125 +88571 0.03753662109375 +88572 0.870361328125 +88573 0.042724609375 +88574 0.86480712890625 +88575 0.044525146484375 +88576 0.831817626953125 +88577 0.0433349609375 +88578 0.677581787109375 +88579 0.040252685546875 +88580 0.495880126953125 +88581 0.035491943359375 +88582 0.30767822265625 +88583 0.03009033203125 +88584 0.116180419921875 +88585 0.023834228515625 +88586 -0.110748291015625 +88587 0.014007568359375 +88588 -0.381805419921875 +88589 -0.000335693359375 +88590 -0.6572265625 +88591 -0.0166015625 +88592 -0.857421875 +88593 -0.030914306640625 +88594 -0.870391845703125 +88595 -0.04058837890625 +88596 -0.870391845703125 +88597 -0.045440673828125 +88598 -0.86444091796875 +88599 -0.047637939453125 +88600 -0.85723876953125 +88601 -0.0499267578125 +88602 -0.790008544921875 +88603 -0.051055908203125 +88604 -0.62847900390625 +88605 -0.04705810546875 +88606 -0.3956298828125 +88607 -0.03759765625 +88608 -0.126708984375 +88609 -0.024810791015625 +88610 0.150115966796875 +88611 -0.0103759765625 +88612 0.424041748046875 +88613 0.005157470703125 +88614 0.670623779296875 +88615 0.02020263671875 +88616 0.854522705078125 +88617 0.032379150390625 +88618 0.866485595703125 +88619 0.040771484375 +88620 0.86920166015625 +88621 0.04461669921875 +88622 0.8653564453125 +88623 0.0455322265625 +88624 0.857147216796875 +88625 0.044708251953125 +88626 0.766845703125 +88627 0.0421142578125 +88628 0.628509521484375 +88629 0.038177490234375 +88630 0.462127685546875 +88631 0.03240966796875 +88632 0.297210693359375 +88633 0.026611328125 +88634 0.14862060546875 +88635 0.021514892578125 +88636 -0.00537109375 +88637 0.0152587890625 +88638 -0.15753173828125 +88639 0.008148193359375 +88640 -0.31304931640625 +88641 -0.0003662109375 +88642 -0.48876953125 +88643 -0.0115966796875 +88644 -0.6416015625 +88645 -0.0224609375 +88646 -0.751373291015625 +88647 -0.031494140625 +88648 -0.84619140625 +88649 -0.040618896484375 +88650 -0.861297607421875 +88651 -0.048980712890625 +88652 -0.863250732421875 +88653 -0.05438232421875 +88654 -0.856597900390625 +88655 -0.05462646484375 +88656 -0.7498779296875 +88657 -0.050628662109375 +88658 -0.624542236328125 +88659 -0.046539306640625 +88660 -0.47808837890625 +88661 -0.0406494140625 +88662 -0.253387451171875 +88663 -0.02862548828125 +88664 0.003692626953125 +88665 -0.013580322265625 +88666 0.2257080078125 +88667 -0.00018310546875 +88668 0.427154541015625 +88669 0.0126953125 +88670 0.643218994140625 +88671 0.02764892578125 +88672 0.855926513671875 +88673 0.044219970703125 +88674 0.870361328125 +88675 0.058502197265625 +88676 0.870361328125 +88677 0.067108154296875 +88678 0.862762451171875 +88679 0.070709228515625 +88680 0.79669189453125 +88681 0.0692138671875 +88682 0.595794677734375 +88683 0.062042236328125 +88684 0.362152099609375 +88685 0.051239013671875 +88686 0.1270751953125 +88687 0.038818359375 +88688 -0.086944580078125 +88689 0.02618408203125 +88690 -0.2784423828125 +88691 0.0133056640625 +88692 -0.484832763671875 +88693 -0.00244140625 +88694 -0.729583740234375 +88695 -0.022674560546875 +88696 -0.86688232421875 +88697 -0.043975830078125 +88698 -0.870391845703125 +88699 -0.061981201171875 +88700 -0.86859130859375 +88701 -0.076507568359375 +88702 -0.86279296875 +88703 -0.087615966796875 +88704 -0.817962646484375 +88705 -0.092864990234375 +88706 -0.6116943359375 +88707 -0.089111328125 +88708 -0.3128662109375 +88709 -0.075897216796875 +88710 0.039398193359375 +88711 -0.0556640625 +88712 0.422821044921875 +88713 -0.02984619140625 +88714 0.805145263671875 +88715 -0.000762939453125 +88716 0.870361328125 +88717 0.026763916015625 +88718 0.870361328125 +88719 0.04876708984375 +88720 0.860015869140625 +88721 0.0645751953125 +88722 0.727935791015625 +88723 0.07379150390625 +88724 0.48114013671875 +88725 0.076202392578125 +88726 0.2059326171875 +88727 0.07373046875 +88728 -0.06103515625 +88729 0.068145751953125 +88730 -0.29913330078125 +88731 0.060302734375 +88732 -0.516204833984375 +88733 0.04925537109375 +88734 -0.7252197265625 +88735 0.033966064453125 +88736 -0.85980224609375 +88737 0.016265869140625 +88738 -0.870391845703125 +88739 -0.001373291015625 +88740 -0.870391845703125 +88741 -0.016845703125 +88742 -0.858062744140625 +88743 -0.026702880859375 +88744 -0.673004150390625 +88745 -0.03076171875 +88746 -0.42694091796875 +88747 -0.032928466796875 +88748 -0.2100830078125 +88749 -0.0364990234375 +88750 -0.0362548828125 +88751 -0.041412353515625 +88752 0.10943603515625 +88753 -0.04571533203125 +88754 0.23516845703125 +88755 -0.048065185546875 +88756 0.373687744140625 +88757 -0.04559326171875 +88758 0.517791748046875 +88759 -0.03851318359375 +88760 0.602783203125 +88761 -0.03143310546875 +88762 0.635711669921875 +88763 -0.02398681640625 +88764 0.655181884765625 +88765 -0.013824462890625 +88766 0.65948486328125 +88767 -0.00164794921875 +88768 0.651275634765625 +88769 0.011962890625 +88770 0.61846923828125 +88771 0.0252685546875 +88772 0.53753662109375 +88773 0.035675048828125 +88774 0.404144287109375 +88775 0.041961669921875 +88776 0.22186279296875 +88777 0.043548583984375 +88778 0.003997802734375 +88779 0.040679931640625 +88780 -0.22100830078125 +88781 0.034759521484375 +88782 -0.42449951171875 +88783 0.02734375 +88784 -0.579833984375 +88785 0.02001953125 +88786 -0.641876220703125 +88787 0.01593017578125 +88788 -0.6177978515625 +88789 0.0146484375 +88790 -0.575531005859375 +88791 0.01153564453125 +88792 -0.526336669921875 +88793 0.006195068359375 +88794 -0.42645263671875 +88795 0.002349853515625 +88796 -0.2581787109375 +88797 0.00189208984375 +88798 -0.068695068359375 +88799 0.002197265625 +88800 0.09222412109375 +88801 0.00042724609375 +88802 0.232147216796875 +88803 -0.0020751953125 +88804 0.3509521484375 +88805 -0.00469970703125 +88806 0.410064697265625 +88807 -0.0096435546875 +88808 0.372955322265625 +88809 -0.019073486328125 +88810 0.2554931640625 +88811 -0.03155517578125 +88812 0.10711669921875 +88813 -0.04339599609375 +88814 -0.052886962890625 +88815 -0.053192138671875 +88816 -0.186279296875 +88817 -0.058380126953125 +88818 -0.23291015625 +88819 -0.054962158203125 +88820 -0.209442138671875 +88821 -0.044586181640625 +88822 -0.174163818359375 +88823 -0.031982421875 +88824 -0.126739501953125 +88825 -0.0177001953125 +88826 -0.048126220703125 +88827 -0.001007080078125 +88828 0.0426025390625 +88829 0.016082763671875 +88830 0.10748291015625 +88831 0.030303955078125 +88832 0.1409912109375 +88833 0.04119873046875 +88834 0.19708251953125 +88835 0.05303955078125 +88836 0.273651123046875 +88837 0.0645751953125 +88838 0.31768798828125 +88839 0.070465087890625 +88840 0.341094970703125 +88841 0.071990966796875 +88842 0.368011474609375 +88843 0.071746826171875 +88844 0.37249755859375 +88845 0.0673828125 +88846 0.30072021484375 +88847 0.05389404296875 +88848 0.1517333984375 +88849 0.031585693359375 +88850 -0.01470947265625 +88851 0.006866455078125 +88852 -0.1883544921875 +88853 -0.01873779296875 +88854 -0.372711181640625 +88855 -0.04510498046875 +88856 -0.51397705078125 +88857 -0.066436767578125 +88858 -0.57177734375 +88859 -0.078338623046875 +88860 -0.53948974609375 +88861 -0.079833984375 +88862 -0.43511962890625 +88863 -0.072509765625 +88864 -0.2962646484375 +88865 -0.060028076171875 +88866 -0.161102294921875 +88867 -0.046173095703125 +88868 -0.0435791015625 +88869 -0.03240966796875 +88870 0.060394287109375 +88871 -0.01849365234375 +88872 0.13665771484375 +88873 -0.006103515625 +88874 0.170135498046875 +88875 0.0029296875 +88876 0.16552734375 +88877 0.008758544921875 +88878 0.15728759765625 +88879 0.01446533203125 +88880 0.150787353515625 +88881 0.020233154296875 +88882 0.12200927734375 +88883 0.0233154296875 +88884 0.080108642578125 +88885 0.0242919921875 +88886 0.05126953125 +88887 0.025543212890625 +88888 0.062896728515625 +88889 0.02960205078125 +88890 0.09271240234375 +88891 0.03411865234375 +88892 0.092987060546875 +88893 0.0343017578125 +88894 0.07855224609375 +88895 0.031646728515625 +88896 0.06427001953125 +88897 0.027740478515625 +88898 0.0347900390625 +88899 0.021209716796875 +88900 -0.01171875 +88901 0.012115478515625 +88902 -0.056060791015625 +88903 0.002655029296875 +88904 -0.055511474609375 +88905 -0.002593994140625 +88906 -0.010467529296875 +88907 -0.003387451171875 +88908 0.02508544921875 +88909 -0.00482177734375 +88910 0.025665283203125 +88911 -0.009185791015625 +88912 0.017333984375 +88913 -0.013641357421875 +88914 0.00189208984375 +88915 -0.017822265625 +88916 -0.03173828125 +88917 -0.022735595703125 +88918 -0.071502685546875 +88919 -0.027130126953125 +88920 -0.13543701171875 +88921 -0.0328369140625 +88922 -0.219970703125 +88923 -0.03955078125 +88924 -0.300506591796875 +88925 -0.044891357421875 +88926 -0.376312255859375 +88927 -0.048980712890625 +88928 -0.416107177734375 +88929 -0.048919677734375 +88930 -0.371124267578125 +88931 -0.0400390625 +88932 -0.242279052734375 +88933 -0.022705078125 +88934 -0.069732666015625 +88935 -0.001190185546875 +88936 0.125640869140625 +88937 0.02215576171875 +88938 0.31268310546875 +88939 0.044036865234375 +88940 0.45501708984375 +88941 0.060638427734375 +88942 0.554779052734375 +88943 0.072052001953125 +88944 0.61065673828125 +88945 0.078125 +88946 0.610931396484375 +88947 0.07769775390625 +88948 0.531463623046875 +88949 0.068389892578125 +88950 0.3883056640625 +88951 0.051910400390625 +88952 0.23468017578125 +88953 0.03375244140625 +88954 0.095245361328125 +88955 0.016571044921875 +88956 -0.00396728515625 +88957 0.003143310546875 +88958 -0.04852294921875 +88959 -0.0048828125 +88960 -0.055145263671875 +88961 -0.009002685546875 +88962 -0.0758056640625 +88963 -0.014190673828125 +88964 -0.138702392578125 +88965 -0.023101806640625 +88966 -0.209197998046875 +88967 -0.03216552734375 +88968 -0.289031982421875 +88969 -0.041473388671875 +88970 -0.37884521484375 +88971 -0.051055908203125 +88972 -0.456329345703125 +88973 -0.05865478515625 +88974 -0.51641845703125 +88975 -0.06378173828125 +88976 -0.519287109375 +88977 -0.062530517578125 +88978 -0.458251953125 +88979 -0.0543212890625 +88980 -0.384796142578125 +88981 -0.044464111328125 +88982 -0.323699951171875 +88983 -0.035552978515625 +88984 -0.269287109375 +88985 -0.02716064453125 +88986 -0.1951904296875 +88987 -0.016815185546875 +88988 -0.100006103515625 +88989 -0.00457763671875 +88990 -0.01055908203125 +88991 0.0067138671875 +88992 0.1033935546875 +88993 0.01995849609375 +88994 0.24908447265625 +88995 0.035797119140625 +88996 0.373199462890625 +88997 0.048858642578125 +88998 0.45806884765625 +88999 0.057342529296875 +89000 0.511474609375 +89001 0.062042236328125 +89002 0.565399169921875 +89003 0.066192626953125 +89004 0.61138916015625 +89005 0.069061279296875 +89006 0.5897216796875 +89007 0.064788818359375 +89008 0.4906005859375 +89009 0.052520751953125 +89010 0.33148193359375 +89011 0.03411865234375 +89012 0.147796630859375 +89013 0.013275146484375 +89014 -0.01873779296875 +89015 -0.00567626953125 +89016 -0.140289306640625 +89017 -0.01983642578125 +89018 -0.191986083984375 +89019 -0.026611328125 +89020 -0.184295654296875 +89021 -0.027008056640625 +89022 -0.161834716796875 +89023 -0.025421142578125 +89024 -0.166595458984375 +89025 -0.0260009765625 +89026 -0.19390869140625 +89027 -0.028289794921875 +89028 -0.22442626953125 +89029 -0.0303955078125 +89030 -0.279754638671875 +89031 -0.0345458984375 +89032 -0.3389892578125 +89033 -0.038726806640625 +89034 -0.3543701171875 +89035 -0.03826904296875 +89036 -0.348175048828125 +89037 -0.0355224609375 +89038 -0.32598876953125 +89039 -0.03118896484375 +89040 -0.2581787109375 +89041 -0.02239990234375 +89042 -0.139801025390625 +89043 -0.008758544921875 +89044 0.014617919921875 +89045 0.008148193359375 +89046 0.144378662109375 +89047 0.02215576171875 +89048 0.221038818359375 +89049 0.0303955078125 +89050 0.27069091796875 +89051 0.03546142578125 +89052 0.294036865234375 +89053 0.03741455078125 +89054 0.311767578125 +89055 0.038360595703125 +89056 0.339141845703125 +89057 0.0399169921875 +89058 0.360260009765625 +89059 0.040618896484375 +89060 0.360504150390625 +89061 0.039093017578125 +89062 0.308380126953125 +89063 0.032135009765625 +89064 0.18170166015625 +89065 0.01751708984375 +89066 0.0047607421875 +89067 -0.00213623046875 +89068 -0.17559814453125 +89069 -0.02191162109375 +89070 -0.3143310546875 +89071 -0.037109375 +89072 -0.36785888671875 +89073 -0.04315185546875 +89074 -0.36248779296875 +89075 -0.042755126953125 +89076 -0.343536376953125 +89077 -0.0406494140625 +89078 -0.3018798828125 +89079 -0.035919189453125 +89080 -0.231414794921875 +89081 -0.0279541015625 +89082 -0.117645263671875 +89083 -0.015289306640625 +89084 0.007049560546875 +89085 -0.0013427734375 +89086 0.087982177734375 +89087 0.00811767578125 +89088 0.13946533203125 +89089 0.014495849609375 +89090 0.17425537109375 +89091 0.01910400390625 +89092 0.188201904296875 +89093 0.021514892578125 +89094 0.171234130859375 +89095 0.020172119140625 +89096 0.118438720703125 +89097 0.014251708984375 +89098 0.05706787109375 +89099 0.00732421875 +89100 -0.010711669921875 +89101 -0.00048828125 +89102 -0.0914306640625 +89103 -0.010162353515625 +89104 -0.162322998046875 +89105 -0.018707275390625 +89106 -0.194549560546875 +89107 -0.022247314453125 +89108 -0.1492919921875 +89109 -0.01556396484375 +89110 -0.02166748046875 +89111 0.001983642578125 +89112 0.124053955078125 +89113 0.021636962890625 +89114 0.211151123046875 +89115 0.032989501953125 +89116 0.240447998046875 +89117 0.036224365234375 +89118 0.242218017578125 +89119 0.0355224609375 +89120 0.2257080078125 +89121 0.032196044921875 +89122 0.194366455078125 +89123 0.02679443359375 +89124 0.115509033203125 +89125 0.01495361328125 +89126 0.0128173828125 +89127 0.0 +89128 -0.053802490234375 +89129 -0.009857177734375 +89130 -0.110626220703125 +89131 -0.0181884765625 +89132 -0.199493408203125 +89133 -0.030670166015625 +89134 -0.29437255859375 +89135 -0.043731689453125 +89136 -0.33221435546875 +89137 -0.048797607421875 +89138 -0.27972412109375 +89139 -0.041351318359375 +89140 -0.185333251953125 +89141 -0.02801513671875 +89142 -0.128204345703125 +89143 -0.01959228515625 +89144 -0.115692138671875 +89145 -0.017120361328125 +89146 -0.116455078125 +89147 -0.016387939453125 +89148 -0.105926513671875 +89149 -0.01409912109375 +89150 -0.053955078125 +89151 -0.006195068359375 +89152 0.048797607421875 +89153 0.008514404296875 +89154 0.157318115234375 +89155 0.023895263671875 +89156 0.212005615234375 +89157 0.03179931640625 +89158 0.218475341796875 +89159 0.032958984375 +89160 0.23724365234375 +89161 0.035614013671875 +89162 0.30535888671875 +89163 0.0447998046875 +89164 0.38128662109375 +89165 0.05487060546875 +89166 0.404449462890625 +89167 0.05755615234375 +89168 0.3944091796875 +89169 0.055572509765625 +89170 0.3885498046875 +89171 0.054046630859375 +89172 0.362640380859375 +89173 0.049774169921875 +89174 0.27362060546875 +89175 0.03692626953125 +89176 0.11712646484375 +89177 0.01495361328125 +89178 -0.054901123046875 +89179 -0.009002685546875 +89180 -0.19085693359375 +89181 -0.027923583984375 +89182 -0.28570556640625 +89183 -0.041107177734375 +89184 -0.339263916015625 +89185 -0.04852294921875 +89186 -0.3775634765625 +89187 -0.0537109375 +89188 -0.445709228515625 +89189 -0.06280517578125 +89190 -0.535064697265625 +89191 -0.074615478515625 +89192 -0.629058837890625 +89193 -0.086944580078125 +89194 -0.697601318359375 +89195 -0.095703125 +89196 -0.70391845703125 +89197 -0.095947265625 +89198 -0.6424560546875 +89199 -0.086944580078125 +89200 -0.491241455078125 +89201 -0.06573486328125 +89202 -0.265716552734375 +89203 -0.03448486328125 +89204 -0.023712158203125 +89205 -0.001068115234375 +89206 0.201751708984375 +89207 0.02996826171875 +89208 0.375823974609375 +89209 0.053863525390625 +89210 0.485076904296875 +89211 0.06878662109375 +89212 0.56884765625 +89213 0.080078125 +89214 0.634765625 +89215 0.088775634765625 +89216 0.63763427734375 +89217 0.088775634765625 +89218 0.5660400390625 +89219 0.07855224609375 +89220 0.4720458984375 +89221 0.06524658203125 +89222 0.40692138671875 +89223 0.055816650390625 +89224 0.3778076171875 +89225 0.05126953125 +89226 0.376953125 +89227 0.05059814453125 +89228 0.371978759765625 +89229 0.049407958984375 +89230 0.313140869140625 +89231 0.04095458984375 +89232 0.184417724609375 +89233 0.0230712890625 +89234 0.011199951171875 +89235 -0.000701904296875 +89236 -0.171051025390625 +89237 -0.025543212890625 +89238 -0.33740234375 +89239 -0.04803466796875 +89240 -0.47198486328125 +89241 -0.0660400390625 +89242 -0.560394287109375 +89243 -0.07763671875 +89244 -0.58056640625 +89245 -0.079864501953125 +89246 -0.54754638671875 +89247 -0.074798583984375 +89248 -0.508575439453125 +89249 -0.06890869140625 +89250 -0.459503173828125 +89251 -0.061676025390625 +89252 -0.394378662109375 +89253 -0.05230712890625 +89254 -0.35260009765625 +89255 -0.046173095703125 +89256 -0.31170654296875 +89257 -0.04022216796875 +89258 -0.197418212890625 +89259 -0.024383544921875 +89260 -0.007965087890625 +89261 0.00152587890625 +89262 0.207489013671875 +89263 0.03082275390625 +89264 0.409210205078125 +89265 0.05810546875 +89266 0.57208251953125 +89267 0.0799560546875 +89268 0.66595458984375 +89269 0.092315673828125 +89270 0.65875244140625 +89271 0.090850830078125 +89272 0.56744384765625 +89273 0.077880859375 +89274 0.431396484375 +89275 0.058807373046875 +89276 0.29443359375 +89277 0.039642333984375 +89278 0.182464599609375 +89279 0.023895263671875 +89280 0.06365966796875 +89281 0.007293701171875 +89282 -0.075958251953125 +89283 -0.01202392578125 +89284 -0.189422607421875 +89285 -0.027679443359375 +89286 -0.271942138671875 +89287 -0.038970947265625 +89288 -0.342529296875 +89289 -0.048492431640625 +89290 -0.364166259765625 +89291 -0.051239013671875 +89292 -0.327239990234375 +89293 -0.045928955078125 +89294 -0.2769775390625 +89295 -0.038726806640625 +89296 -0.253692626953125 +89297 -0.035125732421875 +89298 -0.24365234375 +89299 -0.03326416015625 +89300 -0.1983642578125 +89301 -0.026580810546875 +89302 -0.116241455078125 +89303 -0.014892578125 +89304 -0.036834716796875 +89305 -0.003631591796875 +89306 0.034881591796875 +89307 0.006500244140625 +89308 0.09124755859375 +89309 0.014434814453125 +89310 0.10888671875 +89311 0.016998291015625 +89312 0.125518798828125 +89313 0.019287109375 +89314 0.15771484375 +89315 0.0235595703125 +89316 0.17828369140625 +89317 0.026123046875 +89318 0.17108154296875 +89319 0.024810791015625 +89320 0.129974365234375 +89321 0.018798828125 +89322 0.082427978515625 +89323 0.011871337890625 +89324 0.027679443359375 +89325 0.003936767578125 +89326 -0.065643310546875 +89327 -0.009185791015625 +89328 -0.15936279296875 +89329 -0.02227783203125 +89330 -0.21307373046875 +89331 -0.029876708984375 +89332 -0.234649658203125 +89333 -0.03302001953125 +89334 -0.2001953125 +89335 -0.028472900390625 +89336 -0.119171142578125 +89337 -0.017486572265625 +89338 -0.024749755859375 +89339 -0.00457763671875 +89340 0.085784912109375 +89341 0.010589599609375 +89342 0.178131103515625 +89343 0.0233154296875 +89344 0.215576171875 +89345 0.02838134765625 +89346 0.211456298828125 +89347 0.0274658203125 +89348 0.17523193359375 +89349 0.021759033203125 +89350 0.128753662109375 +89351 0.01483154296875 +89352 0.1019287109375 +89353 0.0115966796875 +89354 0.0743408203125 +89355 0.008544921875 +89356 0.04327392578125 +89357 0.005096435546875 +89358 0.038177490234375 +89359 0.006072998046875 +89360 0.076263427734375 +89361 0.014251708984375 +89362 0.14105224609375 +89363 0.0267333984375 +89364 0.186431884765625 +89365 0.035675048828125 +89366 0.188812255859375 +89367 0.037078857421875 +89368 0.1390380859375 +89369 0.029388427734375 +89370 0.041778564453125 +89371 0.013336181640625 +89372 -0.079437255859375 +89373 -0.007080078125 +89374 -0.219390869140625 +89375 -0.030975341796875 +89376 -0.367828369140625 +89377 -0.0565185546875 +89378 -0.494873046875 +89379 -0.078704833984375 +89380 -0.556243896484375 +89381 -0.090057373046875 +89382 -0.508697509765625 +89383 -0.083251953125 +89384 -0.3756103515625 +89385 -0.0621337890625 +89386 -0.218902587890625 +89387 -0.03704833984375 +89388 -0.063751220703125 +89389 -0.01214599609375 +89390 0.091552734375 +89391 0.01287841796875 +89392 0.23602294921875 +89393 0.0362548828125 +89394 0.342987060546875 +89395 0.053497314453125 +89396 0.39520263671875 +89397 0.061767578125 +89398 0.389373779296875 +89399 0.060546875 +89400 0.324249267578125 +89401 0.049652099609375 +89402 0.224090576171875 +89403 0.033172607421875 +89404 0.124267578125 +89405 0.016998291015625 +89406 0.037078857421875 +89407 0.003143310546875 +89408 -0.010101318359375 +89409 -0.003814697265625 +89410 -0.019439697265625 +89411 -0.004302978515625 +89412 -0.022796630859375 +89413 -0.003753662109375 +89414 -0.001556396484375 +89415 0.000885009765625 +89416 0.056304931640625 +89417 0.01153564453125 +89418 0.106719970703125 +89419 0.020782470703125 +89420 0.096893310546875 +89421 0.019744873046875 +89422 0.042694091796875 +89423 0.01104736328125 +89424 -0.018035888671875 +89425 0.001007080078125 +89426 -0.07586669921875 +89427 -0.00872802734375 +89428 -0.11944580078125 +89429 -0.016265869140625 +89430 -0.15972900390625 +89431 -0.023406982421875 +89432 -0.202606201171875 +89433 -0.0311279296875 +89434 -0.24859619140625 +89435 -0.039459228515625 +89436 -0.30517578125 +89437 -0.049652099609375 +89438 -0.36212158203125 +89439 -0.0599365234375 +89440 -0.39141845703125 +89441 -0.065582275390625 +89442 -0.35528564453125 +89443 -0.0601806640625 +89444 -0.249969482421875 +89445 -0.0430908203125 +89446 -0.092864990234375 +89447 -0.0172119140625 +89448 0.08905029296875 +89449 0.012939453125 +89450 0.2352294921875 +89451 0.037200927734375 +89452 0.318817138671875 +89453 0.05108642578125 +89454 0.358642578125 +89455 0.057769775390625 +89456 0.347747802734375 +89457 0.056060791015625 +89458 0.28564453125 +89459 0.045867919921875 +89460 0.223175048828125 +89461 0.035736083984375 +89462 0.196746826171875 +89463 0.03173828125 +89464 0.179840087890625 +89465 0.029388427734375 +89466 0.155548095703125 +89467 0.02581787109375 +89468 0.151214599609375 +89469 0.025604248046875 +89470 0.156951904296875 +89471 0.027069091796875 +89472 0.13177490234375 +89473 0.023284912109375 +89474 0.100799560546875 +89475 0.018463134765625 +89476 0.087127685546875 +89477 0.016448974609375 +89478 0.05487060546875 +89479 0.011199951171875 +89480 -0.009002685546875 +89481 0.00054931640625 +89482 -0.10400390625 +89483 -0.01544189453125 +89484 -0.229400634765625 +89485 -0.03662109375 +89486 -0.35552978515625 +89487 -0.0579833984375 +89488 -0.441925048828125 +89489 -0.072723388671875 +89490 -0.473846435546875 +89491 -0.078369140625 +89492 -0.464813232421875 +89493 -0.077178955078125 +89494 -0.419097900390625 +89495 -0.069854736328125 +89496 -0.334320068359375 +89497 -0.05596923828125 +89498 -0.227935791015625 +89499 -0.038421630859375 +89500 -0.12347412109375 +89501 -0.021148681640625 +89502 -0.02764892578125 +89503 -0.0052490234375 +89504 0.077667236328125 +89505 0.01226806640625 +89506 0.2132568359375 +89507 0.034912109375 +89508 0.38885498046875 +89509 0.0643310546875 +89510 0.582794189453125 +89511 0.096893310546875 +89512 0.734039306640625 +89513 0.122344970703125 +89514 0.800140380859375 +89515 0.133514404296875 +89516 0.7783203125 +89517 0.129974365234375 +89518 0.6651611328125 +89519 0.111114501953125 +89520 0.45965576171875 +89521 0.0767822265625 +89522 0.199188232421875 +89523 0.03326416015625 +89524 -0.050689697265625 +89525 -0.008453369140625 +89526 -0.23297119140625 +89527 -0.038787841796875 +89528 -0.33013916015625 +89529 -0.054840087890625 +89530 -0.368408203125 +89531 -0.061004638671875 +89532 -0.378936767578125 +89533 -0.062530517578125 +89534 -0.376983642578125 +89535 -0.062042236328125 +89536 -0.37969970703125 +89537 -0.062408447265625 +89538 -0.391510009765625 +89539 -0.064361572265625 +89540 -0.385345458984375 +89541 -0.0633544921875 +89542 -0.3419189453125 +89543 -0.056121826171875 +89544 -0.28289794921875 +89545 -0.046295166015625 +89546 -0.251617431640625 +89547 -0.041168212890625 +89548 -0.266143798828125 +89549 -0.04376220703125 +89550 -0.273345947265625 +89551 -0.045135498046875 +89552 -0.216796875 +89553 -0.03582763671875 +89554 -0.128265380859375 +89555 -0.0211181640625 +89556 -0.068145751953125 +89557 -0.011138916015625 +89558 -0.0430908203125 +89559 -0.007049560546875 +89560 -0.024444580078125 +89561 -0.003997802734375 +89562 0.020721435546875 +89563 0.003509521484375 +89564 0.124481201171875 +89565 0.020843505859375 +89566 0.25787353515625 +89567 0.04315185546875 +89568 0.379119873046875 +89569 0.06341552734375 +89570 0.47991943359375 +89571 0.08026123046875 +89572 0.5281982421875 +89573 0.08831787109375 +89574 0.511138916015625 +89575 0.08538818359375 +89576 0.456207275390625 +89577 0.07611083984375 +89578 0.407470703125 +89579 0.067901611328125 +89580 0.383758544921875 +89581 0.063934326171875 +89582 0.35687255859375 +89583 0.0594482421875 +89584 0.31182861328125 +89585 0.051910400390625 +89586 0.250885009765625 +89587 0.04168701171875 +89588 0.1654052734375 +89589 0.027374267578125 +89590 0.035247802734375 +89591 0.005584716796875 +89592 -0.142059326171875 +89593 -0.024078369140625 +89594 -0.33563232421875 +89595 -0.056427001953125 +89596 -0.5345458984375 +89597 -0.089630126953125 +89598 -0.72186279296875 +89599 -0.120849609375 +89600 -0.836669921875 +89601 -0.139404296875 +89602 -0.8326416015625 +89603 -0.13690185546875 +89604 -0.7296142578125 +89605 -0.117279052734375 +89606 -0.582550048828125 +89607 -0.09112548828125 +89608 -0.440093994140625 +89609 -0.067657470703125 +89610 -0.324310302734375 +89611 -0.050750732421875 +89612 -0.20147705078125 +89613 -0.033111572265625 +89614 -0.044647216796875 +89615 -0.00885009765625 +89616 0.103973388671875 +89617 0.0140380859375 +89618 0.202392578125 +89619 0.027557373046875 +89620 0.264495849609375 +89621 0.0347900390625 +89622 0.338897705078125 +89623 0.045745849609375 +89624 0.443817138671875 +89625 0.064208984375 +89626 0.545074462890625 +89627 0.08343505859375 +89628 0.6173095703125 +89629 0.09832763671875 +89630 0.6524658203125 +89631 0.10723876953125 +89632 0.66339111328125 +89633 0.112548828125 +89634 0.6561279296875 +89635 0.115264892578125 +89636 0.606781005859375 +89637 0.110321044921875 +89638 0.501190185546875 +89639 0.094573974609375 +89640 0.352783203125 +89641 0.070404052734375 +89642 0.176544189453125 +89643 0.04052734375 +89644 -0.034820556640625 +89645 0.003204345703125 +89646 -0.258209228515625 +89647 -0.03717041015625 +89648 -0.44244384765625 +89649 -0.070587158203125 +89650 -0.5753173828125 +89651 -0.09478759765625 +89652 -0.65203857421875 +89653 -0.108917236328125 +89654 -0.641632080078125 +89655 -0.106781005859375 +89656 -0.562164306640625 +89657 -0.092010498046875 +89658 -0.458038330078125 +89659 -0.073394775390625 +89660 -0.350555419921875 +89661 -0.055023193359375 +89662 -0.260528564453125 +89663 -0.040863037109375 +89664 -0.192108154296875 +89665 -0.031524658203125 +89666 -0.141937255859375 +89667 -0.02606201171875 +89668 -0.1021728515625 +89669 -0.02264404296875 +89670 -0.062896728515625 +89671 -0.01904296875 +89672 -0.011932373046875 +89673 -0.012603759765625 +89674 0.062835693359375 +89675 -0.000701904296875 +89676 0.148712158203125 +89677 0.014251708984375 +89678 0.241729736328125 +89679 0.031524658203125 +89680 0.34912109375 +89681 0.052642822265625 +89682 0.457305908203125 +89683 0.07489013671875 +89684 0.54388427734375 +89685 0.09368896484375 +89686 0.5728759765625 +89687 0.101776123046875 +89688 0.506591796875 +89689 0.0914306640625 +89690 0.351226806640625 +89691 0.063720703125 +89692 0.146514892578125 +89693 0.026397705078125 +89694 -0.05523681640625 +89695 -0.01025390625 +89696 -0.21624755859375 +89697 -0.03887939453125 +89698 -0.334930419921875 +89699 -0.059356689453125 +89700 -0.402984619140625 +89701 -0.070159912109375 +89702 -0.4412841796875 +89703 -0.07562255859375 +89704 -0.49578857421875 +89705 -0.085052490234375 +89706 -0.5601806640625 +89707 -0.097259521484375 +89708 -0.600738525390625 +89709 -0.105499267578125 +89710 -0.584228515625 +89711 -0.10308837890625 +89712 -0.47930908203125 +89713 -0.083709716796875 +89714 -0.27935791015625 +89715 -0.045928955078125 +89716 -0.0089111328125 +89717 0.005462646484375 +89718 0.268798828125 +89719 0.0579833984375 +89720 0.482818603515625 +89721 0.09759521484375 +89722 0.60369873046875 +89723 0.118621826171875 +89724 0.650421142578125 +89725 0.125 +89726 0.66400146484375 +89727 0.125091552734375 +89728 0.6414794921875 +89729 0.118438720703125 +89730 0.572540283203125 +89731 0.103118896484375 +89732 0.498138427734375 +89733 0.087371826171875 +89734 0.439453125 +89735 0.075469970703125 +89736 0.375518798828125 +89737 0.063201904296875 +89738 0.274505615234375 +89739 0.044158935546875 +89740 0.1087646484375 +89741 0.012725830078125 +89742 -0.099395751953125 +89743 -0.026702880859375 +89744 -0.3182373046875 +89745 -0.06793212890625 +89746 -0.5489501953125 +89747 -0.111358642578125 +89748 -0.7738037109375 +89749 -0.153533935546875 +89750 -0.86383056640625 +89751 -0.184051513671875 +89752 -0.870391845703125 +89753 -0.1964111328125 +89754 -0.86895751953125 +89755 -0.194305419921875 +89756 -0.861053466796875 +89757 -0.180450439453125 +89758 -0.765869140625 +89759 -0.151458740234375 +89760 -0.5301513671875 +89761 -0.1051025390625 +89762 -0.214691162109375 +89763 -0.042816162109375 +89764 0.137359619140625 +89765 0.02679443359375 +89766 0.474822998046875 +89767 0.093536376953125 +89768 0.76239013671875 +89769 0.150390625 +89770 0.867462158203125 +89771 0.19207763671875 +89772 0.870361328125 +89773 0.21881103515625 +89774 0.86480712890625 +89775 0.2283935546875 +89776 0.831817626953125 +89777 0.222015380859375 +89778 0.677581787109375 +89779 0.2047119140625 +89780 0.495880126953125 +89781 0.177764892578125 +89782 0.30767822265625 +89783 0.14495849609375 +89784 0.116180419921875 +89785 0.1068115234375 +89786 -0.110748291015625 +89787 0.057037353515625 +89788 -0.381805419921875 +89789 -0.005706787109375 +89790 -0.6572265625 +89791 -0.072906494140625 +89792 -0.857421875 +89793 -0.132598876953125 +89794 -0.870391845703125 +89795 -0.176300048828125 +89796 -0.870391845703125 +89797 -0.202667236328125 +89798 -0.86444091796875 +89799 -0.217193603515625 +89800 -0.85723876953125 +89801 -0.227142333984375 +89802 -0.790008544921875 +89803 -0.228973388671875 +89804 -0.62847900390625 +89805 -0.2119140625 +89806 -0.3956298828125 +89807 -0.1754150390625 +89808 -0.126708984375 +89809 -0.12615966796875 +89810 0.150115966796875 +89811 -0.069671630859375 +89812 0.424041748046875 +89813 -0.008331298828125 +89814 0.670623779296875 +89815 0.05242919921875 +89816 0.854522705078125 +89817 0.1048583984375 +89818 0.866485595703125 +89819 0.145477294921875 +89820 0.86920166015625 +89821 0.171234130859375 +89822 0.8653564453125 +89823 0.18585205078125 +89824 0.857147216796875 +89825 0.19207763671875 +89826 0.766845703125 +89827 0.18939208984375 +89828 0.628509521484375 +89829 0.178955078125 +89830 0.462127685546875 +89831 0.159515380859375 +89832 0.297210693359375 +89833 0.13629150390625 +89834 0.14862060546875 +89835 0.111846923828125 +89836 -0.00537109375 +89837 0.081695556640625 +89838 -0.15753173828125 +89839 0.04736328125 +89840 -0.31304931640625 +89841 0.0081787109375 +89842 -0.48876953125 +89843 -0.038665771484375 +89844 -0.6416015625 +89845 -0.083770751953125 +89846 -0.751373291015625 +89847 -0.12225341796875 +89848 -0.84619140625 +89849 -0.158782958984375 +89850 -0.861297607421875 +89851 -0.190460205078125 +89852 -0.863250732421875 +89853 -0.210723876953125 +89854 -0.856597900390625 +89855 -0.213348388671875 +89856 -0.7498779296875 +89857 -0.201446533203125 +89858 -0.624542236328125 +89859 -0.187469482421875 +89860 -0.47808837890625 +89861 -0.165618896484375 +89862 -0.253387451171875 +89863 -0.122100830078125 +89864 0.003692626953125 +89865 -0.067230224609375 +89866 0.2257080078125 +89867 -0.016571044921875 +89868 0.427154541015625 +89869 0.033111572265625 +89870 0.643218994140625 +89871 0.0897216796875 +89872 0.855926513671875 +89873 0.1513671875 +89874 0.870361328125 +89875 0.20489501953125 +89876 0.870361328125 +89877 0.239044189453125 +89878 0.862762451171875 +89879 0.25567626953125 +89880 0.79669189453125 +89881 0.254241943359375 +89882 0.595794677734375 +89883 0.232574462890625 +89884 0.362152099609375 +89885 0.19744873046875 +89886 0.1270751953125 +89887 0.1552734375 +89888 -0.086944580078125 +89889 0.11077880859375 +89890 -0.2784423828125 +89891 0.064178466796875 +89892 -0.484832763671875 +89893 0.007171630859375 +89894 -0.729583740234375 +89895 -0.06500244140625 +89896 -0.86688232421875 +89897 -0.140869140625 +89898 -0.870391845703125 +89899 -0.2060546875 +89900 -0.86859130859375 +89901 -0.259613037109375 +89902 -0.86279296875 +89903 -0.301300048828125 +89904 -0.817962646484375 +89905 -0.322967529296875 +89906 -0.6116943359375 +89907 -0.314208984375 +89908 -0.3128662109375 +89909 -0.2734375 +89910 0.039398193359375 +89911 -0.20849609375 +89912 0.422821044921875 +89913 -0.123931884765625 +89914 0.805145263671875 +89915 -0.027374267578125 +89916 0.870361328125 +89917 0.06549072265625 +89918 0.870361328125 +89919 0.1416015625 +89920 0.860015869140625 +89921 0.198486328125 +89922 0.727935791015625 +89923 0.23455810546875 +89924 0.48114013671875 +89925 0.24871826171875 +89926 0.2059326171875 +89927 0.24676513671875 +89928 -0.06103515625 +89929 0.234100341796875 +89930 -0.29913330078125 +89931 0.21319580078125 +89932 -0.516204833984375 +89933 0.180755615234375 +89934 -0.7252197265625 +89935 0.13330078125 +89936 -0.85980224609375 +89937 0.07666015625 +89938 -0.870391845703125 +89939 0.018768310546875 +89940 -0.870391845703125 +89941 -0.03350830078125 +89942 -0.858062744140625 +89943 -0.06890869140625 +89944 -0.673004150390625 +89945 -0.08648681640625 +89946 -0.42694091796875 +89947 -0.0985107421875 +89948 -0.2100830078125 +89949 -0.1153564453125 +89950 -0.0362548828125 +89951 -0.136627197265625 +89952 0.10943603515625 +89953 -0.155609130859375 +89954 0.23516845703125 +89955 -0.16778564453125 +89956 0.373687744140625 +89957 -0.16363525390625 +89958 0.517791748046875 +89959 -0.143707275390625 +89960 0.602783203125 +89961 -0.1226806640625 +89962 0.635711669921875 +89963 -0.09942626953125 +89964 0.655181884765625 +89965 -0.066253662109375 +89966 0.65948486328125 +89967 -0.0255126953125 +89968 0.651275634765625 +89969 0.020904541015625 +89970 0.61846923828125 +89971 0.06732177734375 +89972 0.53753662109375 +89973 0.105133056640625 +89974 0.404144287109375 +89975 0.13018798828125 +89976 0.22186279296875 +89977 0.14031982421875 +89978 0.003997802734375 +89979 0.1358642578125 +89980 -0.22100830078125 +89981 0.121063232421875 +89982 -0.42449951171875 +89983 0.10076904296875 +89984 -0.579833984375 +89985 0.08001708984375 +89986 -0.641876220703125 +89987 0.068756103515625 +89988 -0.6177978515625 +89989 0.065521240234375 +89990 -0.575531005859375 +89991 0.05535888671875 +89992 -0.526336669921875 +89993 0.037078857421875 +89994 -0.42645263671875 +89995 0.022735595703125 +89996 -0.2581787109375 +89997 0.0186767578125 +89998 -0.068695068359375 +89999 0.0164794921875 +90000 0.09222412109375 +90001 0.0072021484375 +90002 0.232147216796875 +90003 -0.00482177734375 +90004 0.3509521484375 +90005 -0.017242431640625 +90006 0.410064697265625 +90007 -0.036956787109375 +90008 0.372955322265625 +90009 -0.07080078125 +90010 0.2554931640625 +90011 -0.113922119140625 +90012 0.10711669921875 +90013 -0.154296875 +90014 -0.052886962890625 +90015 -0.1873779296875 +90016 -0.186279296875 +90017 -0.204803466796875 +90018 -0.23291015625 +90019 -0.19366455078125 +90020 -0.209442138671875 +90021 -0.159271240234375 +90022 -0.174163818359375 +90023 -0.116912841796875 +90024 -0.126739501953125 +90025 -0.068511962890625 +90026 -0.048126220703125 +90027 -0.011810302734375 +90028 0.0426025390625 +90029 0.046630859375 +90030 0.10748291015625 +90031 0.095977783203125 +90032 0.1409912109375 +90033 0.1331787109375 +90034 0.19708251953125 +90035 0.16925048828125 +90036 0.273651123046875 +90037 0.202667236328125 +90038 0.31768798828125 +90039 0.220489501953125 +90040 0.341094970703125 +90041 0.225311279296875 +90042 0.368011474609375 +90043 0.222991943359375 +90044 0.37249755859375 +90045 0.208221435546875 +90046 0.30072021484375 +90047 0.169586181640625 +90048 0.1517333984375 +90049 0.10821533203125 +90050 -0.01470947265625 +90051 0.039581298828125 +90052 -0.1883544921875 +90053 -0.03216552734375 +90054 -0.372711181640625 +90055 -0.1060791015625 +90056 -0.51397705078125 +90057 -0.16802978515625 +90058 -0.57177734375 +90059 -0.20709228515625 +90060 -0.53948974609375 +90061 -0.220428466796875 +90062 -0.43511962890625 +90063 -0.211212158203125 +90064 -0.2962646484375 +90065 -0.187530517578125 +90066 -0.161102294921875 +90067 -0.157958984375 +90068 -0.0435791015625 +90069 -0.125823974609375 +90070 0.060394287109375 +90071 -0.09063720703125 +90072 0.13665771484375 +90073 -0.056488037109375 +90074 0.170135498046875 +90075 -0.02789306640625 +90076 0.16552734375 +90077 -0.005035400390625 +90078 0.15728759765625 +90079 0.018646240234375 +90080 0.150787353515625 +90081 0.04296875 +90082 0.12200927734375 +90083 0.060943603515625 +90084 0.080108642578125 +90085 0.073394775390625 +90086 0.05126953125 +90087 0.08526611328125 +90088 0.062896728515625 +90089 0.10198974609375 +90090 0.09271240234375 +90091 0.11773681640625 +90092 0.092987060546875 +90093 0.121124267578125 +90094 0.07855224609375 +90095 0.1156005859375 +90096 0.06427001953125 +90097 0.104888916015625 +90098 0.0347900390625 +90099 0.0859375 +90100 -0.01171875 +90101 0.05914306640625 +90102 -0.056060791015625 +90103 0.029937744140625 +90104 -0.055511474609375 +90105 0.00933837890625 +90106 -0.010467529296875 +90107 -0.00152587890625 +90108 0.02508544921875 +90109 -0.01397705078125 +90110 0.025665283203125 +90111 -0.0328369140625 +90112 0.017333984375 +90113 -0.050872802734375 +90114 0.00189208984375 +90115 -0.066986083984375 +90116 -0.03173828125 +90117 -0.083404541015625 +90118 -0.071502685546875 +90119 -0.096923828125 +90120 -0.13543701171875 +90121 -0.112030029296875 +90122 -0.219970703125 +90123 -0.128082275390625 +90124 -0.300506591796875 +90125 -0.139312744140625 +90126 -0.376312255859375 +90127 -0.146148681640625 +90128 -0.416107177734375 +90129 -0.141571044921875 +90130 -0.371124267578125 +90131 -0.114227294921875 +90132 -0.242279052734375 +90133 -0.06524658203125 +90134 -0.069732666015625 +90135 -0.005615234375 +90136 0.125640869140625 +90137 0.05853271484375 +90138 0.31268310546875 +90139 0.118621826171875 +90140 0.45501708984375 +90141 0.1649169921875 +90142 0.554779052734375 +90143 0.197418212890625 +90144 0.61065673828125 +90145 0.21551513671875 +90146 0.610931396484375 +90147 0.216156005859375 +90148 0.531463623046875 +90149 0.193389892578125 +90150 0.3883056640625 +90151 0.1514892578125 +90152 0.23468017578125 +90153 0.10418701171875 +90154 0.095245361328125 +90155 0.0582275390625 +90156 -0.00396728515625 +90157 0.02081298828125 +90158 -0.04852294921875 +90159 -0.003753662109375 +90160 -0.055145263671875 +90161 -0.018890380859375 +90162 -0.0758056640625 +90163 -0.036865234375 +90164 -0.138702392578125 +90165 -0.06402587890625 +90166 -0.209197998046875 +90167 -0.09112548828125 +90168 -0.289031982421875 +90169 -0.118133544921875 +90170 -0.37884521484375 +90171 -0.1448974609375 +90172 -0.456329345703125 +90173 -0.165679931640625 +90174 -0.51641845703125 +90175 -0.179229736328125 +90176 -0.519287109375 +90177 -0.17578125 +90178 -0.458251953125 +90179 -0.153961181640625 +90180 -0.384796142578125 +90181 -0.127044677734375 +90182 -0.323699951171875 +90183 -0.10174560546875 +90184 -0.269287109375 +90185 -0.07720947265625 +90186 -0.1951904296875 +90187 -0.047515869140625 +90188 -0.100006103515625 +90189 -0.012908935546875 +90190 -0.01055908203125 +90191 0.019287109375 +90192 0.1033935546875 +90193 0.056121826171875 +90194 0.24908447265625 +90195 0.0989990234375 +90196 0.373199462890625 +90197 0.13427734375 +90198 0.45806884765625 +90199 0.15740966796875 +90200 0.511474609375 +90201 0.170257568359375 +90202 0.565399169921875 +90203 0.180938720703125 +90204 0.61138916015625 +90205 0.18756103515625 +90206 0.5897216796875 +90207 0.175537109375 +90208 0.4906005859375 +90209 0.142791748046875 +90210 0.33148193359375 +90211 0.09417724609375 +90212 0.147796630859375 +90213 0.0390625 +90214 -0.01873779296875 +90215 -0.0115966796875 +90216 -0.140289306640625 +90217 -0.05035400390625 +90218 -0.191986083984375 +90219 -0.070526123046875 +90220 -0.184295654296875 +90221 -0.07440185546875 +90222 -0.161834716796875 +90223 -0.0728759765625 +90224 -0.166595458984375 +90225 -0.07623291015625 +90226 -0.19390869140625 +90227 -0.083251953125 +90228 -0.22442626953125 +90229 -0.089141845703125 +90230 -0.279754638671875 +90231 -0.099456787109375 +90232 -0.3389892578125 +90233 -0.109222412109375 +90234 -0.3543701171875 +90235 -0.1068115234375 +90236 -0.348175048828125 +90237 -0.098175048828125 +90238 -0.32598876953125 +90239 -0.085113525390625 +90240 -0.2581787109375 +90241 -0.060638427734375 +90242 -0.139801025390625 +90243 -0.02392578125 +90244 0.014617919921875 +90245 0.02099609375 +90246 0.144378662109375 +90247 0.058624267578125 +90248 0.221038818359375 +90249 0.08160400390625 +90250 0.27069091796875 +90251 0.096282958984375 +90252 0.294036865234375 +90253 0.102783203125 +90254 0.311767578125 +90255 0.106292724609375 +90256 0.339141845703125 +90257 0.1107177734375 +90258 0.360260009765625 +90259 0.112457275390625 +90260 0.360504150390625 +90261 0.1080322265625 +90262 0.308380126953125 +90263 0.089324951171875 +90264 0.18170166015625 +90265 0.050750732421875 +90266 0.0047607421875 +90267 -0.0009765625 +90268 -0.17559814453125 +90269 -0.05328369140625 +90270 -0.3143310546875 +90271 -0.09405517578125 +90272 -0.36785888671875 +90273 -0.111602783203125 +90274 -0.36248779296875 +90275 -0.112701416015625 +90276 -0.343536376953125 +90277 -0.109222412109375 +90278 -0.3018798828125 +90279 -0.09869384765625 +90280 -0.231414794921875 +90281 -0.079498291015625 +90282 -0.117645263671875 +90283 -0.047882080078125 +90284 0.007049560546875 +90285 -0.01251220703125 +90286 0.087982177734375 +90287 0.011993408203125 +90288 0.13946533203125 +90289 0.02923583984375 +90290 0.17425537109375 +90291 0.0423583984375 +90292 0.188201904296875 +90293 0.050079345703125 +90294 0.171234130859375 +90295 0.04949951171875 +90296 0.118438720703125 +90297 0.03912353515625 +90298 0.05706787109375 +90299 0.025970458984375 +90300 -0.010711669921875 +90301 0.01043701171875 +90302 -0.0914306640625 +90303 -0.00927734375 +90304 -0.162322998046875 +90305 -0.0272216796875 +90306 -0.194549560546875 +90307 -0.035797119140625 +90308 -0.1492919921875 +90309 -0.02471923828125 +90310 -0.02166748046875 +90311 0.00732421875 +90312 0.124053955078125 +90313 0.043487548828125 +90314 0.211151123046875 +90315 0.063629150390625 +90316 0.240447998046875 +90317 0.068145751953125 +90318 0.242218017578125 +90319 0.065185546875 +90320 0.2257080078125 +90321 0.05743408203125 +90322 0.194366455078125 +90323 0.045989990234375 +90324 0.115509033203125 +90325 0.022369384765625 +90326 0.0128173828125 +90327 -0.0069580078125 +90328 -0.053802490234375 +90329 -0.026092529296875 +90330 -0.110626220703125 +90331 -0.04193115234375 +90332 -0.199493408203125 +90333 -0.065460205078125 +90334 -0.29437255859375 +90335 -0.08984375 +90336 -0.33221435546875 +90337 -0.0985107421875 +90338 -0.27972412109375 +90339 -0.082794189453125 +90340 -0.185333251953125 +90341 -0.055572509765625 +90342 -0.128204345703125 +90343 -0.037872314453125 +90344 -0.115692138671875 +90345 -0.031768798828125 +90346 -0.116455078125 +90347 -0.029144287109375 +90348 -0.105926513671875 +90349 -0.023712158203125 +90350 -0.053955078125 +90351 -0.00762939453125 +90352 0.048797607421875 +90353 0.02142333984375 +90354 0.157318115234375 +90355 0.051483154296875 +90356 0.212005615234375 +90357 0.066741943359375 +90358 0.218475341796875 +90359 0.068634033203125 +90360 0.23724365234375 +90361 0.07318115234375 +90362 0.30535888671875 +90363 0.090179443359375 +90364 0.38128662109375 +90365 0.108734130859375 +90366 0.404449462890625 +90367 0.112945556640625 +90368 0.3944091796875 +90369 0.10870361328125 +90370 0.3885498046875 +90371 0.10662841796875 +90372 0.362640380859375 +90373 0.0994873046875 +90374 0.27362060546875 +90375 0.0743408203125 +90376 0.11712646484375 +90377 0.029693603515625 +90378 -0.054901123046875 +90379 -0.01922607421875 +90380 -0.19085693359375 +90381 -0.05731201171875 +90382 -0.28570556640625 +90383 -0.083251953125 +90384 -0.339263916015625 +90385 -0.097137451171875 +90386 -0.3775634765625 +90387 -0.106781005859375 +90388 -0.445709228515625 +90389 -0.1256103515625 +90390 -0.535064697265625 +90391 -0.151153564453125 +90392 -0.629058837890625 +90393 -0.17852783203125 +90394 -0.697601318359375 +90395 -0.19879150390625 +90396 -0.70391845703125 +90397 -0.2010498046875 +90398 -0.6424560546875 +90399 -0.183624267578125 +90400 -0.491241455078125 +90401 -0.13995361328125 +90402 -0.265716552734375 +90403 -0.074554443359375 +90404 -0.023712158203125 +90405 -0.00445556640625 +90406 0.201751708984375 +90407 0.060638427734375 +90408 0.375823974609375 +90409 0.110504150390625 +90410 0.485076904296875 +90411 0.141265869140625 +90412 0.56884765625 +90413 0.1646728515625 +90414 0.634765625 +90415 0.18304443359375 +90416 0.63763427734375 +90417 0.18304443359375 +90418 0.5660400390625 +90419 0.161346435546875 +90420 0.4720458984375 +90421 0.133392333984375 +90422 0.40692138671875 +90423 0.11431884765625 +90424 0.3778076171875 +90425 0.106231689453125 +90426 0.376953125 +90427 0.1068115234375 +90428 0.371978759765625 +90429 0.106414794921875 +90430 0.313140869140625 +90431 0.090240478515625 +90432 0.184417724609375 +90433 0.053436279296875 +90434 0.011199951171875 +90435 0.00347900390625 +90436 -0.171051025390625 +90437 -0.04913330078125 +90438 -0.33740234375 +90439 -0.09710693359375 +90440 -0.47198486328125 +90441 -0.135833740234375 +90442 -0.560394287109375 +90443 -0.1611328125 +90444 -0.58056640625 +90445 -0.16650390625 +90446 -0.54754638671875 +90447 -0.156402587890625 +90448 -0.508575439453125 +90449 -0.144866943359375 +90450 -0.459503173828125 +90451 -0.130645751953125 +90452 -0.394378662109375 +90453 -0.1119384765625 +90454 -0.35260009765625 +90455 -0.100341796875 +90456 -0.31170654296875 +90457 -0.08917236328125 +90458 -0.197418212890625 +90459 -0.056365966796875 +90460 -0.007965087890625 +90461 -0.001373291015625 +90462 0.207489013671875 +90463 0.061279296875 +90464 0.409210205078125 +90465 0.119873046875 +90466 0.57208251953125 +90467 0.16705322265625 +90468 0.66595458984375 +90469 0.193939208984375 +90470 0.65875244140625 +90471 0.191131591796875 +90472 0.56744384765625 +90473 0.163665771484375 +90474 0.431396484375 +90475 0.123199462890625 +90476 0.29443359375 +90477 0.082733154296875 +90478 0.182464599609375 +90479 0.0499267578125 +90480 0.06365966796875 +90481 0.01531982421875 +90482 -0.075958251953125 +90483 -0.025238037109375 +90484 -0.189422607421875 +90485 -0.05792236328125 +90486 -0.271942138671875 +90487 -0.081329345703125 +90488 -0.342529296875 +90489 -0.101165771484375 +90490 -0.364166259765625 +90491 -0.1065673828125 +90492 -0.327239990234375 +90493 -0.0947265625 +90494 -0.2769775390625 +90495 -0.079071044921875 +90496 -0.253692626953125 +90497 -0.071563720703125 +90498 -0.24365234375 +90499 -0.068145751953125 +90500 -0.1983642578125 +90501 -0.05450439453125 +90502 -0.116241455078125 +90503 -0.030181884765625 +90504 -0.036834716796875 +90505 -0.006866455078125 +90506 0.034881591796875 +90507 0.013946533203125 +90508 0.09124755859375 +90509 0.030029296875 +90510 0.10888671875 +90511 0.034515380859375 +90512 0.125518798828125 +90513 0.038604736328125 +90514 0.15771484375 +90515 0.047271728515625 +90516 0.17828369140625 +90517 0.052490234375 +90518 0.17108154296875 +90519 0.04949951171875 +90520 0.129974365234375 +90521 0.03656005859375 +90522 0.082427978515625 +90523 0.021820068359375 +90524 0.027679443359375 +90525 0.005126953125 +90526 -0.065643310546875 +90527 -0.02276611328125 +90528 -0.15936279296875 +90529 -0.050537109375 +90530 -0.21307373046875 +90531 -0.0662841796875 +90532 -0.234649658203125 +90533 -0.07232666015625 +90534 -0.2001953125 +90535 -0.061614990234375 +90536 -0.119171142578125 +90537 -0.0369873046875 +90538 -0.024749755859375 +90539 -0.00830078125 +90540 0.085784912109375 +90541 0.025177001953125 +90542 0.178131103515625 +90543 0.05322265625 +90544 0.215576171875 +90545 0.06494140625 +90546 0.211456298828125 +90547 0.06427001953125 +90548 0.17523193359375 +90549 0.05401611328125 +90550 0.128753662109375 +90551 0.040618896484375 +90552 0.1019287109375 +90553 0.03289794921875 +90554 0.0743408203125 +90555 0.024810791015625 +90556 0.04327392578125 +90557 0.015533447265625 +90558 0.038177490234375 +90559 0.0137939453125 +90560 0.076263427734375 +90561 0.024688720703125 +90562 0.14105224609375 +90563 0.043365478515625 +90564 0.186431884765625 +90565 0.05621337890625 +90566 0.188812255859375 +90567 0.0562744140625 +90568 0.1390380859375 +90569 0.0408935546875 +90570 0.041778564453125 +90571 0.011505126953125 +90572 -0.079437255859375 +90573 -0.02490234375 +90574 -0.219390869140625 +90575 -0.066741943359375 +90576 -0.367828369140625 +90577 -0.1109619140625 +90578 -0.494873046875 +90579 -0.148681640625 +90580 -0.556243896484375 +90581 -0.16680908203125 +90582 -0.508697509765625 +90583 -0.152557373046875 +90584 -0.3756103515625 +90585 -0.11285400390625 +90586 -0.218902587890625 +90587 -0.066070556640625 +90588 -0.063751220703125 +90589 -0.019683837890625 +90590 0.091552734375 +90591 0.026763916015625 +90592 0.23602294921875 +90593 0.07000732421875 +90594 0.342987060546875 +90595 0.10211181640625 +90596 0.39520263671875 +90597 0.11798095703125 +90598 0.389373779296875 +90599 0.116607666015625 +90600 0.324249267578125 +90601 0.097625732421875 +90602 0.224090576171875 +90603 0.068206787109375 +90604 0.124267578125 +90605 0.038787841796875 +90606 0.037078857421875 +90607 0.01300048828125 +90608 -0.010101318359375 +90609 -0.00103759765625 +90610 -0.019439697265625 +90611 -0.00396728515625 +90612 -0.022796630859375 +90613 -0.00518798828125 +90614 -0.001556396484375 +90615 0.000762939453125 +90616 0.056304931640625 +90617 0.017486572265625 +90618 0.106719970703125 +90619 0.031951904296875 +90620 0.096893310546875 +90621 0.028564453125 +90622 0.042694091796875 +90623 0.012054443359375 +90624 -0.018035888671875 +90625 -0.006622314453125 +90626 -0.07586669921875 +90627 -0.02447509765625 +90628 -0.11944580078125 +90629 -0.037506103515625 +90630 -0.15972900390625 +90631 -0.049468994140625 +90632 -0.202606201171875 +90633 -0.062469482421875 +90634 -0.24859619140625 +90635 -0.076690673828125 +90636 -0.30517578125 +90637 -0.094696044921875 +90638 -0.36212158203125 +90639 -0.1131591796875 +90640 -0.39141845703125 +90641 -0.122894287109375 +90642 -0.35528564453125 +90643 -0.11151123046875 +90644 -0.249969482421875 +90645 -0.077728271484375 +90646 -0.092864990234375 +90647 -0.0272216796875 +90648 0.08905029296875 +90649 0.03125 +90650 0.2352294921875 +90651 0.077911376953125 +90652 0.318817138671875 +90653 0.104034423828125 +90654 0.358642578125 +90655 0.1158447265625 +90656 0.347747802734375 +90657 0.11114501953125 +90658 0.28564453125 +90659 0.08984375 +90660 0.223175048828125 +90661 0.06866455078125 +90662 0.196746826171875 +90663 0.0595703125 +90664 0.179840087890625 +90665 0.053863525390625 +90666 0.155548095703125 +90667 0.0460205078125 +90668 0.151214599609375 +90669 0.045013427734375 +90670 0.156951904296875 +90671 0.04754638671875 +90672 0.13177490234375 +90673 0.040130615234375 +90674 0.100799560546875 +90675 0.03094482421875 +90676 0.087127685546875 +90677 0.02752685546875 +90678 0.05487060546875 +90679 0.01806640625 +90680 -0.009002685546875 +90681 -0.00177001953125 +90682 -0.10400390625 +90683 -0.031890869140625 +90684 -0.229400634765625 +90685 -0.072113037109375 +90686 -0.35552978515625 +90687 -0.112762451171875 +90688 -0.441925048828125 +90689 -0.14056396484375 +90690 -0.473846435546875 +90691 -0.150726318359375 +90692 -0.464813232421875 +90693 -0.147674560546875 +90694 -0.419097900390625 +90695 -0.132843017578125 +90696 -0.334320068359375 +90697 -0.105438232421875 +90698 -0.227935791015625 +90699 -0.071136474609375 +90700 -0.12347412109375 +90701 -0.037628173828125 +90702 -0.02764892578125 +90703 -0.007049560546875 +90704 0.077667236328125 +90705 0.026580810546875 +90706 0.2132568359375 +90707 0.070098876953125 +90708 0.38885498046875 +90709 0.12677001953125 +90710 0.582794189453125 +90711 0.18951416015625 +90712 0.734039306640625 +90713 0.238372802734375 +90714 0.800140380859375 +90715 0.259429931640625 +90716 0.7783203125 +90717 0.2518310546875 +90718 0.6651611328125 +90719 0.2144775390625 +90720 0.45965576171875 +90721 0.14703369140625 +90722 0.199188232421875 +90723 0.061767578125 +90724 -0.050689697265625 +90725 -0.019805908203125 +90726 -0.23297119140625 +90727 -0.079010009765625 +90728 -0.33013916015625 +90729 -0.11016845703125 +90730 -0.368408203125 +90731 -0.121917724609375 +90732 -0.378936767578125 +90733 -0.124481201171875 +90734 -0.376983642578125 +90735 -0.12298583984375 +90736 -0.37969970703125 +90737 -0.123077392578125 +90738 -0.391510009765625 +90739 -0.126251220703125 +90740 -0.385345458984375 +90741 -0.123626708984375 +90742 -0.3419189453125 +90743 -0.10894775390625 +90744 -0.28289794921875 +90745 -0.089324951171875 +90746 -0.251617431640625 +90747 -0.078948974609375 +90748 -0.266143798828125 +90749 -0.083770751953125 +90750 -0.273345947265625 +90751 -0.086395263671875 +90752 -0.216796875 +90753 -0.0682373046875 +90754 -0.128265380859375 +90755 -0.039703369140625 +90756 -0.068145751953125 +90757 -0.02056884765625 +90758 -0.0430908203125 +90759 -0.01300048828125 +90760 -0.024444580078125 +90761 -0.007537841796875 +90762 0.020721435546875 +90763 0.006622314453125 +90764 0.124481201171875 +90765 0.040008544921875 +90766 0.25787353515625 +90767 0.083160400390625 +90768 0.379119873046875 +90769 0.122406005859375 +90770 0.47991943359375 +90771 0.155059814453125 +90772 0.5281982421875 +90773 0.170654296875 +90774 0.511138916015625 +90775 0.164947509765625 +90776 0.456207275390625 +90777 0.14697265625 +90778 0.407470703125 +90779 0.13116455078125 +90780 0.383758544921875 +90781 0.123687744140625 +90782 0.35687255859375 +90783 0.115264892578125 +90784 0.31182861328125 +90785 0.1009521484375 +90786 0.250885009765625 +90787 0.081451416015625 +90788 0.1654052734375 +90789 0.053924560546875 +90790 0.035247802734375 +90791 0.011749267578125 +90792 -0.142059326171875 +90793 -0.045867919921875 +90794 -0.33563232421875 +90795 -0.108856201171875 +90796 -0.5345458984375 +90797 -0.17364501953125 +90798 -0.72186279296875 +90799 -0.234710693359375 +90800 -0.836669921875 +90801 -0.272064208984375 +90802 -0.8326416015625 +90803 -0.27056884765625 +90804 -0.7296142578125 +90805 -0.236724853515625 +90806 -0.582550048828125 +90807 -0.188568115234375 +90808 -0.440093994140625 +90809 -0.142059326171875 +90810 -0.324310302734375 +90811 -0.10443115234375 +90812 -0.20147705078125 +90813 -0.0645751953125 +90814 -0.044647216796875 +90815 -0.013580322265625 +90816 0.103973388671875 +90817 0.034698486328125 +90818 0.202392578125 +90819 0.066497802734375 +90820 0.264495849609375 +90821 0.08636474609375 +90822 0.338897705078125 +90823 0.11029052734375 +90824 0.443817138671875 +90825 0.144287109375 +90826 0.545074462890625 +90827 0.177154541015625 +90828 0.6173095703125 +90829 0.20062255859375 +90830 0.6524658203125 +90831 0.2120361328125 +90832 0.66339111328125 +90833 0.215606689453125 +90834 0.6561279296875 +90835 0.21331787109375 +90836 0.606781005859375 +90837 0.197296142578125 +90838 0.501190185546875 +90839 0.16290283203125 +90840 0.352783203125 +90841 0.114532470703125 +90842 0.176544189453125 +90843 0.05706787109375 +90844 -0.034820556640625 +90845 -0.0118408203125 +90846 -0.258209228515625 +90847 -0.08465576171875 +90848 -0.44244384765625 +90849 -0.14459228515625 +90850 -0.5753173828125 +90851 -0.18768310546875 +90852 -0.65203857421875 +90853 -0.21240234375 +90854 -0.641632080078125 +90855 -0.2086181640625 +90856 -0.562164306640625 +90857 -0.18231201171875 +90858 -0.458038330078125 +90859 -0.148040771484375 +90860 -0.350555419921875 +90861 -0.112762451171875 +90862 -0.260528564453125 +90863 -0.083343505859375 +90864 -0.192108154296875 +90865 -0.061126708984375 +90866 -0.141937255859375 +90867 -0.04498291015625 +90868 -0.1021728515625 +90869 -0.032318115234375 +90870 -0.062896728515625 +90871 -0.019866943359375 +90872 -0.011932373046875 +90873 -0.003570556640625 +90874 0.062835693359375 +90875 0.020538330078125 +90876 0.148712158203125 +90877 0.048309326171875 +90878 0.241729736328125 +90879 0.078460693359375 +90880 0.34912109375 +90881 0.113677978515625 +90882 0.457305908203125 +90883 0.150299072265625 +90884 0.54388427734375 +90885 0.180877685546875 +90886 0.5728759765625 +90887 0.192138671875 +90888 0.506591796875 +90889 0.170196533203125 +90890 0.351226806640625 +90891 0.116943359375 +90892 0.146514892578125 +90893 0.04638671875 +90894 -0.05523681640625 +90895 -0.02288818359375 +90896 -0.21624755859375 +90897 -0.0775146484375 +90898 -0.334930419921875 +90899 -0.11712646484375 +90900 -0.402984619140625 +90901 -0.138885498046875 +90902 -0.4412841796875 +90903 -0.15045166015625 +90904 -0.49578857421875 +90905 -0.16845703125 +90906 -0.5601806640625 +90907 -0.190704345703125 +90908 -0.600738525390625 +90909 -0.205047607421875 +90910 -0.584228515625 +90911 -0.199493408203125 +90912 -0.47930908203125 +90913 -0.162689208984375 +90914 -0.27935791015625 +90915 -0.092193603515625 +90916 -0.0089111328125 +90917 0.00323486328125 +90918 0.268798828125 +90919 0.1009521484375 +90920 0.482818603515625 +90921 0.175567626953125 +90922 0.60369873046875 +90923 0.216644287109375 +90924 0.650421142578125 +90925 0.231109619140625 +90926 0.66400146484375 +90927 0.23388671875 +90928 0.6414794921875 +90929 0.2239990234375 +90930 0.572540283203125 +90931 0.19781494140625 +90932 0.498138427734375 +90933 0.170166015625 +90934 0.439453125 +90935 0.148712158203125 +90936 0.375518798828125 +90937 0.12591552734375 +90938 0.274505615234375 +90939 0.09027099609375 +90940 0.1087646484375 +90941 0.031768798828125 +90942 -0.099395751953125 +90943 -0.0416259765625 +90944 -0.3182373046875 +90945 -0.118560791015625 +90946 -0.5489501953125 +90947 -0.199615478515625 +90948 -0.7738037109375 +90949 -0.278472900390625 +90950 -0.86383056640625 +90951 -0.336212158203125 +90952 -0.870391845703125 +90953 -0.3609619140625 +90954 -0.86895751953125 +90955 -0.35919189453125 +90956 -0.861053466796875 +90957 -0.335723876953125 +90958 -0.765869140625 +90959 -0.284393310546875 +90960 -0.5301513671875 +90961 -0.201171875 +90962 -0.214691162109375 +90963 -0.088592529296875 +90964 0.137359619140625 +90965 0.037811279296875 +90966 0.474822998046875 +90967 0.15960693359375 +90968 0.76239013671875 +90969 0.2640380859375 +90970 0.867462158203125 +90971 0.341461181640625 +90972 0.870361328125 +90973 0.39215087890625 +90974 0.86480712890625 +90975 0.4119873046875 +90976 0.831817626953125 +90977 0.40301513671875 +90978 0.677581787109375 +90979 0.374114990234375 +90980 0.495880126953125 +90981 0.32745361328125 +90982 0.30767822265625 +90983 0.269805908203125 +90984 0.116180419921875 +90985 0.2020263671875 +90986 -0.110748291015625 +90987 0.11273193359375 +90988 -0.381805419921875 +90989 -0.000518798828125 +90990 -0.6572265625 +90991 -0.122314453125 +90992 -0.857421875 +90993 -0.231109619140625 +90994 -0.870391845703125 +90995 -0.3115234375 +90996 -0.870391845703125 +90997 -0.361053466796875 +90998 -0.86444091796875 +90999 -0.389434814453125 +91000 -0.85723876953125 +91001 -0.40960693359375 +91002 -0.790008544921875 +91003 -0.4150390625 +91004 -0.62847900390625 +91005 -0.38629150390625 +91006 -0.3956298828125 +91007 -0.322265625 +91008 -0.126708984375 +91009 -0.23486328125 +91010 0.150115966796875 +91011 -0.134002685546875 +91012 0.424041748046875 +91013 -0.023956298828125 +91014 0.670623779296875 +91015 0.085540771484375 +91016 0.854522705078125 +91017 0.180511474609375 +91018 0.866485595703125 +91019 0.254638671875 +91020 0.86920166015625 +91021 0.302398681640625 +91022 0.8653564453125 +91023 0.33038330078125 +91024 0.857147216796875 +91025 0.34344482421875 +91026 0.766845703125 +91027 0.340576171875 +91028 0.628509521484375 +91029 0.323699951171875 +91030 0.462127685546875 +91031 0.29046630859375 +91032 0.297210693359375 +91033 0.250213623046875 +91034 0.14862060546875 +91035 0.20745849609375 +91036 -0.00537109375 +91037 0.154022216796875 +91038 -0.15753173828125 +91039 0.092681884765625 +91040 -0.31304931640625 +91041 0.022186279296875 +91042 -0.48876953125 +91043 -0.0625 +91044 -0.6416015625 +91045 -0.144500732421875 +91046 -0.751373291015625 +91047 -0.21490478515625 +91048 -0.84619140625 +91049 -0.28204345703125 +91050 -0.861297607421875 +91051 -0.340667724609375 +91052 -0.863250732421875 +91053 -0.378875732421875 +91054 -0.856597900390625 +91055 -0.385345458984375 +91056 -0.7498779296875 +91057 -0.364501953125 +91058 -0.624542236328125 +91059 -0.33721923828125 +91060 -0.47808837890625 +91061 -0.295684814453125 +91062 -0.253387451171875 +91063 -0.218902587890625 +91064 0.003692626953125 +91065 -0.12335205078125 +91066 0.2257080078125 +91067 -0.03369140625 +91068 0.427154541015625 +91069 0.054534912109375 +91070 0.643218994140625 +91071 0.152984619140625 +91072 0.855926513671875 +91073 0.2581787109375 +91074 0.870361328125 +91075 0.3492431640625 +91076 0.870361328125 +91077 0.4083251953125 +91078 0.862762451171875 +91079 0.43804931640625 +91080 0.79669189453125 +91081 0.437408447265625 +91082 0.595794677734375 +91083 0.403076171875 +91084 0.362152099609375 +91085 0.3455810546875 +91086 0.1270751953125 +91087 0.27508544921875 +91088 -0.086944580078125 +91089 0.19927978515625 +91090 -0.2784423828125 +91091 0.118927001953125 +91092 -0.484832763671875 +91093 0.021575927734375 +91094 -0.729583740234375 +91095 -0.099609375 +91096 -0.86688232421875 +91097 -0.226348876953125 +91098 -0.870391845703125 +91099 -0.3358154296875 +91100 -0.86859130859375 +91101 -0.426177978515625 +91102 -0.86279296875 +91103 -0.496673583984375 +91104 -0.817962646484375 +91105 -0.534393310546875 +91106 -0.6116943359375 +91107 -0.52301025390625 +91108 -0.3128662109375 +91109 -0.459991455078125 +91110 0.039398193359375 +91111 -0.35748291015625 +91112 0.422821044921875 +91113 -0.2227783203125 +91114 0.805145263671875 +91115 -0.067901611328125 +91116 0.870361328125 +91117 0.082489013671875 +91118 0.870361328125 +91119 0.207794189453125 +91120 0.860015869140625 +91121 0.303680419921875 +91122 0.727935791015625 +91123 0.367279052734375 +91124 0.48114013671875 +91125 0.396453857421875 +91126 0.2059326171875 +91127 0.39984130859375 +91128 -0.06103515625 +91129 0.385498046875 +91130 -0.29913330078125 +91131 0.35699462890625 +91132 -0.516204833984375 +91133 0.30908203125 +91134 -0.7252197265625 +91135 0.236236572265625 +91136 -0.85980224609375 +91137 0.147674560546875 +91138 -0.870391845703125 +91139 0.055419921875 +91140 -0.870391845703125 +91141 -0.029754638671875 +91142 -0.858062744140625 +91143 -0.088653564453125 +91144 -0.673004150390625 +91145 -0.11944580078125 +91146 -0.42694091796875 +91147 -0.142547607421875 +91148 -0.2100830078125 +91149 -0.175140380859375 +91150 -0.0362548828125 +91151 -0.2161865234375 +91152 0.10943603515625 +91153 -0.254058837890625 +91154 0.23516845703125 +91155 -0.28070068359375 +91156 0.373687744140625 +91157 -0.2796630859375 +91158 0.517791748046875 +91159 -0.251556396484375 +91160 0.602783203125 +91161 -0.22088623046875 +91162 0.635711669921875 +91163 -0.18548583984375 +91164 0.655181884765625 +91165 -0.1322021484375 +91166 0.65948486328125 +91167 -0.06488037109375 +91168 0.651275634765625 +91169 0.0133056640625 +91170 0.61846923828125 +91171 0.092742919921875 +91172 0.53753662109375 +91173 0.1588134765625 +91174 0.404144287109375 +91175 0.204345703125 +91176 0.22186279296875 +91177 0.22540283203125 +91178 0.003997802734375 +91179 0.222320556640625 +91180 -0.22100830078125 +91181 0.202056884765625 +91182 -0.42449951171875 +91183 0.172515869140625 +91184 -0.579833984375 +91185 0.141937255859375 +91186 -0.641876220703125 +91187 0.12689208984375 +91188 -0.6177978515625 +91189 0.12469482421875 +91190 -0.575531005859375 +91191 0.109954833984375 +91192 -0.526336669921875 +91193 0.08050537109375 +91194 -0.42645263671875 +91195 0.056640625 +91196 -0.2581787109375 +91197 0.0491943359375 +91198 -0.068695068359375 +91199 0.043975830078125 +91200 0.09222412109375 +91201 0.025970458984375 +91202 0.232147216796875 +91203 0.00262451171875 +91204 0.3509521484375 +91205 -0.021881103515625 +91206 0.410064697265625 +91207 -0.05902099609375 +91208 0.372955322265625 +91209 -0.1201171875 +91210 0.2554931640625 +91211 -0.196807861328125 +91212 0.10711669921875 +91213 -0.268524169921875 +91214 -0.052886962890625 +91215 -0.32745361328125 +91216 -0.186279296875 +91217 -0.35931396484375 +91218 -0.23291015625 +91219 -0.34210205078125 +91220 -0.209442138671875 +91221 -0.284759521484375 +91222 -0.174163818359375 +91223 -0.213104248046875 +91224 -0.126739501953125 +91225 -0.13043212890625 +91226 -0.048126220703125 +91227 -0.032958984375 +91228 0.0426025390625 +91229 0.068115234375 +91230 0.10748291015625 +91231 0.15435791015625 +91232 0.1409912109375 +91233 0.220428466796875 +91234 0.19708251953125 +91235 0.284820556640625 +91236 0.273651123046875 +91237 0.344696044921875 +91238 0.31768798828125 +91239 0.3780517578125 +91240 0.341094970703125 +91241 0.3890380859375 +91242 0.368011474609375 +91243 0.387420654296875 +91244 0.37249755859375 +91245 0.364105224609375 +91246 0.30072021484375 +91247 0.299713134765625 +91248 0.1517333984375 +91249 0.1961669921875 +91250 -0.01470947265625 +91251 0.079620361328125 +91252 -0.1883544921875 +91253 -0.04290771484375 +91254 -0.372711181640625 +91255 -0.16973876953125 +91256 -0.51397705078125 +91257 -0.276824951171875 +91258 -0.57177734375 +91259 -0.3455810546875 +91260 -0.53948974609375 +91261 -0.37103271484375 +91262 -0.43511962890625 +91263 -0.358428955078125 +91264 -0.2962646484375 +91265 -0.32122802734375 +91266 -0.161102294921875 +91267 -0.2738037109375 +91268 -0.0435791015625 +91269 -0.22161865234375 +91270 0.060394287109375 +91271 -0.16375732421875 +91272 0.13665771484375 +91273 -0.10699462890625 +91274 0.170135498046875 +91275 -0.058990478515625 +91276 0.16552734375 +91277 -0.020050048828125 +91278 0.15728759765625 +91279 0.02093505859375 +91280 0.150787353515625 +91281 0.063568115234375 +91282 0.12200927734375 +91283 0.095916748046875 +91284 0.080108642578125 +91285 0.119232177734375 +91286 0.05126953125 +91287 0.1417236328125 +91288 0.062896728515625 +91289 0.1724853515625 +91290 0.09271240234375 +91291 0.201568603515625 +91292 0.092987060546875 +91293 0.209564208984375 +91294 0.07855224609375 +91295 0.2021484375 +91296 0.06427001953125 +91297 0.18548583984375 +91298 0.0347900390625 +91299 0.154449462890625 +91300 -0.01171875 +91301 0.109588623046875 +91302 -0.056060791015625 +91303 0.060089111328125 +91304 -0.055511474609375 +91305 0.024627685546875 +91306 -0.010467529296875 +91307 0.005096435546875 +91308 0.02508544921875 +91309 -0.017547607421875 +91310 0.025665283203125 +91311 -0.051300048828125 +91312 0.017333984375 +91313 -0.084197998046875 +91314 0.00189208984375 +91315 -0.114044189453125 +91316 -0.03173828125 +91317 -0.14404296875 +91318 -0.071502685546875 +91319 -0.16876220703125 +91320 -0.13543701171875 +91321 -0.195037841796875 +91322 -0.219970703125 +91323 -0.221588134765625 +91324 -0.300506591796875 +91325 -0.239349365234375 +91326 -0.376312255859375 +91327 -0.2490234375 +91328 -0.416107177734375 +91329 -0.239593505859375 +91330 -0.371124267578125 +91331 -0.193450927734375 +91332 -0.242279052734375 +91333 -0.11260986328125 +91334 -0.069732666015625 +91335 -0.0145263671875 +91336 0.125640869140625 +91337 0.0909423828125 +91338 0.31268310546875 +91339 0.190032958984375 +91340 0.45501708984375 +91341 0.267181396484375 +91342 0.554779052734375 +91343 0.322174072265625 +91344 0.61065673828125 +91345 0.353790283203125 +91346 0.610931396484375 +91347 0.357086181640625 +91348 0.531463623046875 +91349 0.3226318359375 +91350 0.3883056640625 +91351 0.257080078125 +91352 0.23468017578125 +91353 0.181976318359375 +91354 0.095245361328125 +91355 0.10797119140625 +91356 -0.00396728515625 +91357 0.04644775390625 +91358 -0.04852294921875 +91359 0.004364013671875 +91360 -0.055145263671875 +91361 -0.023406982421875 +91362 -0.0758056640625 +91363 -0.055877685546875 +91364 -0.138702392578125 +91365 -0.102752685546875 +91366 -0.209197998046875 +91367 -0.1492919921875 +91368 -0.289031982421875 +91369 -0.19525146484375 +91370 -0.37884521484375 +91371 -0.240234375 +91372 -0.456329345703125 +91373 -0.27508544921875 +91374 -0.51641845703125 +91375 -0.2977294921875 +91376 -0.519287109375 +91377 -0.292755126953125 +91378 -0.458251953125 +91379 -0.258026123046875 +91380 -0.384796142578125 +91381 -0.214447021484375 +91382 -0.323699951171875 +91383 -0.17266845703125 +91384 -0.269287109375 +91385 -0.131500244140625 +91386 -0.1951904296875 +91387 -0.08172607421875 +91388 -0.100006103515625 +91389 -0.02398681640625 +91390 -0.01055908203125 +91391 0.03009033203125 +91392 0.1033935546875 +91393 0.09149169921875 +91394 0.24908447265625 +91395 0.162200927734375 +91396 0.373199462890625 +91397 0.220306396484375 +91398 0.45806884765625 +91399 0.25848388671875 +91400 0.511474609375 +91401 0.27978515625 +91402 0.565399169921875 +91403 0.29718017578125 +91404 0.61138916015625 +91405 0.30767822265625 +91406 0.5897216796875 +91407 0.287933349609375 +91408 0.4906005859375 +91409 0.234710693359375 +91410 0.33148193359375 +91411 0.15582275390625 +91412 0.147796630859375 +91413 0.066314697265625 +91414 -0.01873779296875 +91415 -0.0162353515625 +91416 -0.140289306640625 +91417 -0.079833984375 +91418 -0.191986083984375 +91419 -0.113739013671875 +91420 -0.184295654296875 +91421 -0.1214599609375 +91422 -0.161834716796875 +91423 -0.120330810546875 +91424 -0.166595458984375 +91425 -0.126800537109375 +91426 -0.19390869140625 +91427 -0.13885498046875 +91428 -0.22442626953125 +91429 -0.1488037109375 +91430 -0.279754638671875 +91431 -0.16552734375 +91432 -0.3389892578125 +91433 -0.1810302734375 +91434 -0.3543701171875 +91435 -0.176727294921875 +91436 -0.348175048828125 +91437 -0.16217041015625 +91438 -0.32598876953125 +91439 -0.140289306640625 +91440 -0.2581787109375 +91441 -0.100006103515625 +91442 -0.139801025390625 +91443 -0.0400390625 +91444 0.014617919921875 +91445 0.033111572265625 +91446 0.144378662109375 +91447 0.09454345703125 +91448 0.221038818359375 +91449 0.132476806640625 +91450 0.27069091796875 +91451 0.156982421875 +91452 0.294036865234375 +91453 0.168182373046875 +91454 0.311767578125 +91455 0.17431640625 +91456 0.339141845703125 +91457 0.181732177734375 +91458 0.360260009765625 +91459 0.184600830078125 +91460 0.360504150390625 +91461 0.177398681640625 +91462 0.308380126953125 +91463 0.1470947265625 +91464 0.18170166015625 +91465 0.08465576171875 +91466 0.0047607421875 +91467 0.0008544921875 +91468 -0.17559814453125 +91469 -0.084014892578125 +91470 -0.3143310546875 +91471 -0.15045166015625 +91472 -0.36785888671875 +91473 -0.179595947265625 +91474 -0.36248779296875 +91475 -0.18231201171875 +91476 -0.343536376953125 +91477 -0.177581787109375 +91478 -0.3018798828125 +91479 -0.16143798828125 +91480 -0.231414794921875 +91481 -0.1312255859375 +91482 -0.117645263671875 +91483 -0.08087158203125 +91484 0.007049560546875 +91485 -0.024261474609375 +91486 0.087982177734375 +91487 0.01513671875 +91488 0.13946533203125 +91489 0.0430908203125 +91490 0.17425537109375 +91491 0.064666748046875 +91492 0.188201904296875 +91493 0.07769775390625 +91494 0.171234130859375 +91495 0.0775146484375 +91496 0.118438720703125 +91497 0.061676025390625 +91498 0.05706787109375 +91499 0.041412353515625 +91500 -0.010711669921875 +91501 0.017333984375 +91502 -0.0914306640625 +91503 -0.0135498046875 +91504 -0.162322998046875 +91505 -0.041717529296875 +91506 -0.194549560546875 +91507 -0.055023193359375 +91508 -0.1492919921875 +91509 -0.036956787109375 +91510 -0.02166748046875 +91511 0.014617919921875 +91512 0.124053955078125 +91513 0.0726318359375 +91514 0.211151123046875 +91515 0.10479736328125 +91516 0.240447998046875 +91517 0.11175537109375 +91518 0.242218017578125 +91519 0.10662841796875 +91520 0.2257080078125 +91521 0.093719482421875 +91522 0.194366455078125 +91523 0.074798583984375 +91524 0.115509033203125 +91525 0.036285400390625 +91526 0.0128173828125 +91527 -0.011444091796875 +91528 -0.053802490234375 +91529 -0.042816162109375 +91530 -0.110626220703125 +91531 -0.068817138671875 +91532 -0.199493408203125 +91533 -0.107147216796875 +91534 -0.29437255859375 +91535 -0.14678955078125 +91536 -0.33221435546875 +91537 -0.161041259765625 +91538 -0.27972412109375 +91539 -0.13592529296875 +91540 -0.185333251953125 +91541 -0.0921630859375 +91542 -0.128204345703125 +91543 -0.063568115234375 +91544 -0.115692138671875 +91545 -0.053466796875 +91546 -0.116455078125 +91547 -0.048858642578125 +91548 -0.105926513671875 +91549 -0.03961181640625 +91550 -0.053955078125 +91551 -0.013214111328125 +91552 0.048797607421875 +91553 0.0340576171875 +91554 0.157318115234375 +91555 0.082916259765625 +91556 0.212005615234375 +91557 0.108001708984375 +91558 0.218475341796875 +91559 0.111602783203125 +91560 0.23724365234375 +91561 0.119384765625 +91562 0.30535888671875 +91563 0.147064208984375 +91564 0.38128662109375 +91565 0.1771240234375 +91566 0.404449462890625 +91567 0.183990478515625 +91568 0.3944091796875 +91569 0.176177978515625 +91570 0.3885498046875 +91571 0.16973876953125 +91572 0.362640380859375 +91573 0.154632568359375 +91574 0.27362060546875 +91575 0.11285400390625 +91576 0.11712646484375 +91577 0.042755126953125 +91578 -0.054901123046875 +91579 -0.033416748046875 +91580 -0.19085693359375 +91581 -0.0936279296875 +91582 -0.28570556640625 +91583 -0.1356201171875 +91584 -0.339263916015625 +91585 -0.159271240234375 +91586 -0.3775634765625 +91587 -0.175537109375 +91588 -0.445709228515625 +91589 -0.20361328125 +91590 -0.535064697265625 +91591 -0.239898681640625 +91592 -0.629058837890625 +91593 -0.2774658203125 +91594 -0.697601318359375 +91595 -0.303680419921875 +91596 -0.70391845703125 +91597 -0.303131103515625 +91598 -0.6424560546875 +91599 -0.273651123046875 +91600 -0.491241455078125 +91601 -0.206146240234375 +91602 -0.265716552734375 +91603 -0.107330322265625 +91604 -0.023712158203125 +91605 -0.00189208984375 +91606 0.201751708984375 +91607 0.095977783203125 +91608 0.375823974609375 +91609 0.171417236328125 +91610 0.485076904296875 +91611 0.218658447265625 +91612 0.56884765625 +91613 0.254364013671875 +91614 0.634765625 +91615 0.281768798828125 +91616 0.63763427734375 +91617 0.281768798828125 +91618 0.5660400390625 +91619 0.2496337890625 +91620 0.4720458984375 +91621 0.20751953125 +91622 0.40692138671875 +91623 0.177276611328125 +91624 0.3778076171875 +91625 0.162109375 +91626 0.376953125 +91627 0.158905029296875 +91628 0.371978759765625 +91629 0.15411376953125 +91630 0.313140869140625 +91631 0.12677001953125 +91632 0.184417724609375 +91633 0.070159912109375 +91634 0.011199951171875 +91635 -0.004791259765625 +91636 -0.171051025390625 +91637 -0.082977294921875 +91638 -0.33740234375 +91639 -0.15380859375 +91640 -0.47198486328125 +91641 -0.210540771484375 +91642 -0.560394287109375 +91643 -0.247100830078125 +91644 -0.58056640625 +91645 -0.25421142578125 +91646 -0.54754638671875 +91647 -0.238372802734375 +91648 -0.508575439453125 +91649 -0.2198486328125 +91650 -0.459503173828125 +91651 -0.19677734375 +91652 -0.394378662109375 +91653 -0.166961669921875 +91654 -0.35260009765625 +91655 -0.14837646484375 +91656 -0.31170654296875 +91657 -0.1307373046875 +91658 -0.197418212890625 +91659 -0.080169677734375 +91660 -0.007965087890625 +91661 0.004180908203125 +91662 0.207489013671875 +91663 0.100006103515625 +91664 0.409210205078125 +91665 0.189300537109375 +91666 0.57208251953125 +91667 0.260772705078125 +91668 0.66595458984375 +91669 0.30084228515625 +91670 0.65875244140625 +91671 0.2950439453125 +91672 0.56744384765625 +91673 0.251251220703125 +91674 0.431396484375 +91675 0.1875 +91676 0.29443359375 +91677 0.123870849609375 +91678 0.182464599609375 +91679 0.072265625 +91680 0.06365966796875 +91681 0.018157958984375 +91682 -0.075958251953125 +91683 -0.044830322265625 +91684 -0.189422607421875 +91685 -0.0953369140625 +91686 -0.271942138671875 +91687 -0.131256103515625 +91688 -0.342529296875 +91689 -0.161346435546875 +91690 -0.364166259765625 +91691 -0.168914794921875 +91692 -0.327239990234375 +91693 -0.149688720703125 +91694 -0.2769775390625 +91695 -0.124420166015625 +91696 -0.253692626953125 +91697 -0.111602783203125 +91698 -0.24365234375 +91699 -0.105072021484375 +91700 -0.1983642578125 +91701 -0.082855224609375 +91702 -0.116241455078125 +91703 -0.0443115234375 +91704 -0.036834716796875 +91705 -0.007476806640625 +91706 0.034881591796875 +91707 0.02532958984375 +91708 0.09124755859375 +91709 0.050628662109375 +91710 0.10888671875 +91711 0.05780029296875 +91712 0.125518798828125 +91713 0.0640869140625 +91714 0.15771484375 +91715 0.0771484375 +91716 0.17828369140625 +91717 0.084686279296875 +91718 0.17108154296875 +91719 0.07940673828125 +91720 0.129974365234375 +91721 0.05865478515625 +91722 0.082427978515625 +91723 0.035064697265625 +91724 0.027679443359375 +91725 0.008392333984375 +91726 -0.065643310546875 +91727 -0.035552978515625 +91728 -0.15936279296875 +91729 -0.07928466796875 +91730 -0.21307373046875 +91731 -0.104339599609375 +91732 -0.234649658203125 +91733 -0.11431884765625 +91734 -0.2001953125 +91735 -0.098358154296875 +91736 -0.119171142578125 +91737 -0.060760498046875 +91738 -0.024749755859375 +91739 -0.0167236328125 +91740 0.085784912109375 +91741 0.034912109375 +91742 0.178131103515625 +91743 0.07843017578125 +91744 0.215576171875 +91745 0.097015380859375 +91746 0.211456298828125 +91747 0.0966796875 +91748 0.17523193359375 +91749 0.0816650390625 +91750 0.128753662109375 +91751 0.06182861328125 +91752 0.1019287109375 +91753 0.050750732421875 +91754 0.0743408203125 +91755 0.0390625 +91756 0.04327392578125 +91757 0.025482177734375 +91758 0.038177490234375 +91759 0.0234375 +91760 0.076263427734375 +91761 0.040740966796875 +91762 0.14105224609375 +91763 0.06988525390625 +91764 0.186431884765625 +91765 0.089874267578125 +91766 0.188812255859375 +91767 0.089996337890625 +91768 0.1390380859375 +91769 0.066131591796875 +91770 0.041778564453125 +91771 0.0205078125 +91772 -0.079437255859375 +91773 -0.036041259765625 +91774 -0.219390869140625 +91775 -0.101104736328125 +91776 -0.367828369140625 +91777 -0.169921875 +91778 -0.494873046875 +91779 -0.228790283203125 +91780 -0.556243896484375 +91781 -0.257476806640625 +91782 -0.508697509765625 +91783 -0.236236572265625 +91784 -0.3756103515625 +91785 -0.17572021484375 +91786 -0.218902587890625 +91787 -0.10418701171875 +91788 -0.063751220703125 +91789 -0.033111572265625 +91790 0.091552734375 +91791 0.038238525390625 +91792 0.23602294921875 +91793 0.10479736328125 +91794 0.342987060546875 +91795 0.154388427734375 +91796 0.39520263671875 +91797 0.179107666015625 +91798 0.389373779296875 +91799 0.177398681640625 +91800 0.324249267578125 +91801 0.148651123046875 +91802 0.224090576171875 +91803 0.1038818359375 +91804 0.124267578125 +91805 0.05914306640625 +91806 0.037078857421875 +91807 0.019989013671875 +91808 -0.010101318359375 +91809 -0.0010986328125 +91810 -0.019439697265625 +91811 -0.005157470703125 +91812 -0.022796630859375 +91813 -0.006683349609375 +91814 -0.001556396484375 +91815 0.002777099609375 +91816 0.056304931640625 +91817 0.02874755859375 +91818 0.106719970703125 +91819 0.0511474609375 +91820 0.096893310546875 +91821 0.045928955078125 +91822 0.042694091796875 +91823 0.020416259765625 +91824 -0.018035888671875 +91825 -0.008087158203125 +91826 -0.07586669921875 +91827 -0.035247802734375 +91828 -0.11944580078125 +91829 -0.055816650390625 +91830 -0.15972900390625 +91831 -0.07476806640625 +91832 -0.202606201171875 +91833 -0.094757080078125 +91834 -0.24859619140625 +91835 -0.115966796875 +91836 -0.30517578125 +91837 -0.141815185546875 +91838 -0.36212158203125 +91839 -0.16766357421875 +91840 -0.39141845703125 +91841 -0.1807861328125 +91842 -0.35528564453125 +91843 -0.1639404296875 +91844 -0.249969482421875 +91845 -0.115447998046875 +91846 -0.092864990234375 +91847 -0.04327392578125 +91848 0.08905029296875 +91849 0.040252685546875 +91850 0.2352294921875 +91851 0.107513427734375 +91852 0.318817138671875 +91853 0.146209716796875 +91854 0.358642578125 +91855 0.164886474609375 +91856 0.347747802734375 +91857 0.16033935546875 +91858 0.28564453125 +91859 0.13232421875 +91860 0.223175048828125 +91861 0.10400390625 +91862 0.196746826171875 +91863 0.09197998046875 +91864 0.179840087890625 +91865 0.084197998046875 +91866 0.155548095703125 +91867 0.07293701171875 +91868 0.151214599609375 +91869 0.0706787109375 +91870 0.156951904296875 +91871 0.07293701171875 +91872 0.13177490234375 +91873 0.061004638671875 +91874 0.100799560546875 +91875 0.04638671875 +91876 0.087127685546875 +91877 0.039642333984375 +91878 0.05487060546875 +91879 0.02447509765625 +91880 -0.009002685546875 +91881 -0.00506591796875 +91882 -0.10400390625 +91883 -0.0487060546875 +91884 -0.229400634765625 +91885 -0.106109619140625 +91886 -0.35552978515625 +91887 -0.16375732421875 +91888 -0.441925048828125 +91889 -0.203155517578125 +91890 -0.473846435546875 +91891 -0.217620849609375 +91892 -0.464813232421875 +91893 -0.21331787109375 +91894 -0.419097900390625 +91895 -0.19219970703125 +91896 -0.334320068359375 +91897 -0.1531982421875 +91898 -0.227935791015625 +91899 -0.104278564453125 +91900 -0.12347412109375 +91901 -0.05621337890625 +91902 -0.02764892578125 +91903 -0.0120849609375 +91904 0.077667236328125 +91905 0.036285400390625 +91906 0.2132568359375 +91907 0.098602294921875 +91908 0.38885498046875 +91909 0.18011474609375 +91910 0.582794189453125 +91911 0.2708740234375 +91912 0.734039306640625 +91913 0.341583251953125 +91914 0.800140380859375 +91915 0.371856689453125 +91916 0.7783203125 +91917 0.36053466796875 +91918 0.6651611328125 +91919 0.30596923828125 +91920 0.45965576171875 +91921 0.207611083984375 +91922 0.199188232421875 +91923 0.083587646484375 +91924 -0.050689697265625 +91925 -0.034332275390625 +91926 -0.23297119140625 +91927 -0.118621826171875 +91928 -0.33013916015625 +91929 -0.16107177734375 +91930 -0.368408203125 +91931 -0.174774169921875 +91932 -0.378936767578125 +91933 -0.17523193359375 +91934 -0.376983642578125 +91935 -0.17022705078125 +91936 -0.37969970703125 +91937 -0.1683349609375 +91938 -0.391510009765625 +91939 -0.171844482421875 +91940 -0.385345458984375 +91941 -0.167694091796875 +91942 -0.3419189453125 +91943 -0.146484375 +91944 -0.28289794921875 +91945 -0.118804931640625 +91946 -0.251617431640625 +91947 -0.105682373046875 +91948 -0.266143798828125 +91949 -0.11578369140625 +91950 -0.273345947265625 +91951 -0.12298583984375 +91952 -0.216796875 +91953 -0.099517822265625 +91954 -0.128265380859375 +91955 -0.060638427734375 +91956 -0.068145751953125 +91957 -0.03558349609375 +91958 -0.0430908203125 +91959 -0.027374267578125 +91960 -0.024444580078125 +91961 -0.021820068359375 +91962 0.020721435546875 +91963 -0.00262451171875 +91964 0.124481201171875 +91965 0.04595947265625 +91966 0.25787353515625 +91967 0.10986328125 +91968 0.379119873046875 +91969 0.168731689453125 +91970 0.47991943359375 +91971 0.218536376953125 +91972 0.5281982421875 +91973 0.2435302734375 +91974 0.511138916015625 +91975 0.23736572265625 +91976 0.456207275390625 +91977 0.21331787109375 +91978 0.407470703125 +91979 0.192718505859375 +91980 0.383758544921875 +91981 0.1845703125 +91982 0.35687255859375 +91983 0.1749267578125 +91984 0.31182861328125 +91985 0.156280517578125 +91986 0.250885009765625 +91987 0.1295166015625 +91988 0.1654052734375 +91989 0.090301513671875 +91990 0.035247802734375 +91991 0.0286865234375 +91992 -0.142059326171875 +91993 -0.056610107421875 +91994 -0.33563232421875 +91995 -0.150543212890625 +91996 -0.5345458984375 +91997 -0.247772216796875 +91998 -0.72186279296875 +91999 -0.34002685546875 +92000 -0.836669921875 +92001 -0.39752197265625 +92002 -0.8326416015625 +92003 -0.397552490234375 +92004 -0.7296142578125 +92005 -0.34967041015625 +92006 -0.582550048828125 +92007 -0.28057861328125 +92008 -0.440093994140625 +92009 -0.213836669921875 +92010 -0.324310302734375 +92011 -0.160064697265625 +92012 -0.20147705078125 +92013 -0.102630615234375 +92014 -0.044647216796875 +92015 -0.02825927734375 +92016 0.103973388671875 +92017 0.042510986328125 +92018 0.202392578125 +92019 0.089263916015625 +92020 0.264495849609375 +92021 0.118865966796875 +92022 0.338897705078125 +92023 0.155059814453125 +92024 0.443817138671875 +92025 0.206695556640625 +92026 0.545074462890625 +92027 0.257049560546875 +92028 0.6173095703125 +92029 0.293701171875 +92030 0.6524658203125 +92031 0.312652587890625 +92032 0.66339111328125 +92033 0.320037841796875 +92034 0.6561279296875 +92035 0.31866455078125 +92036 0.606781005859375 +92037 0.2967529296875 +92038 0.501190185546875 +92039 0.247283935546875 +92040 0.352783203125 +92041 0.17669677734375 +92042 0.176544189453125 +92043 0.09222412109375 +92044 -0.034820556640625 +92045 -0.009735107421875 +92046 -0.258209228515625 +92047 -0.117950439453125 +92048 -0.44244384765625 +92049 -0.207489013671875 +92050 -0.5753173828125 +92051 -0.27239990234375 +92052 -0.65203857421875 +92053 -0.310333251953125 +92054 -0.641632080078125 +92055 -0.30615234375 +92056 -0.562164306640625 +92057 -0.268646240234375 +92058 -0.458038330078125 +92059 -0.219390869140625 +92060 -0.350555419921875 +92061 -0.168670654296875 +92062 -0.260528564453125 +92063 -0.12652587890625 +92064 -0.192108154296875 +92065 -0.09490966796875 +92066 -0.141937255859375 +92067 -0.072052001953125 +92068 -0.1021728515625 +92069 -0.054046630859375 +92070 -0.062896728515625 +92071 -0.035980224609375 +92072 -0.011932373046875 +92073 -0.011871337890625 +92074 0.062835693359375 +92075 0.024200439453125 +92076 0.148712158203125 +92077 0.066070556640625 +92078 0.241729736328125 +92079 0.11175537109375 +92080 0.34912109375 +92081 0.164764404296875 +92082 0.457305908203125 +92083 0.21844482421875 +92084 0.54388427734375 +92085 0.261810302734375 +92086 0.5728759765625 +92087 0.277252197265625 +92088 0.506591796875 +92089 0.246307373046875 +92090 0.351226806640625 +92091 0.171905517578125 +92092 0.146514892578125 +92093 0.0733642578125 +92094 -0.05523681640625 +92095 -0.02386474609375 +92096 -0.21624755859375 +92097 -0.1014404296875 +92098 -0.334930419921875 +92099 -0.158599853515625 +92100 -0.402984619140625 +92101 -0.191314697265625 +92102 -0.4412841796875 +92103 -0.20977783203125 +92104 -0.49578857421875 +92105 -0.2364501953125 +92106 -0.5601806640625 +92107 -0.268218994140625 +92108 -0.600738525390625 +92109 -0.288604736328125 +92110 -0.584228515625 +92111 -0.2813720703125 +92112 -0.47930908203125 +92113 -0.23114013671875 +92114 -0.27935791015625 +92115 -0.1346435546875 +92116 -0.0089111328125 +92117 -0.0037841796875 +92118 0.268798828125 +92119 0.130615234375 +92120 0.482818603515625 +92121 0.2340087890625 +92122 0.60369873046875 +92123 0.292083740234375 +92124 0.650421142578125 +92125 0.314117431640625 +92126 0.66400146484375 +92127 0.3201904296875 +92128 0.6414794921875 +92129 0.308868408203125 +92130 0.572540283203125 +92131 0.275146484375 +92132 0.498138427734375 +92133 0.23895263671875 +92134 0.439453125 +92135 0.210662841796875 +92136 0.375518798828125 +92137 0.180023193359375 +92138 0.274505615234375 +92139 0.1314697265625 +92140 0.1087646484375 +92141 0.05145263671875 +92142 -0.099395751953125 +92143 -0.049224853515625 +92144 -0.3182373046875 +92145 -0.155059814453125 +92146 -0.5489501953125 +92147 -0.2667236328125 +92148 -0.7738037109375 +92149 -0.375579833984375 +92150 -0.86383056640625 +92151 -0.455841064453125 +92152 -0.870391845703125 +92153 -0.4913330078125 +92154 -0.86895751953125 +92155 -0.49072265625 +92156 -0.861053466796875 +92157 -0.46044921875 +92158 -0.765869140625 +92159 -0.392059326171875 +92160 -0.5301513671875 +92161 -0.27996826171875 +92162 -0.214691162109375 +92163 -0.127105712890625 +92164 0.137359619140625 +92165 0.045318603515625 +92166 0.474822998046875 +92167 0.211639404296875 +92168 0.76239013671875 +92169 0.354217529296875 +92170 0.867462158203125 +92171 0.459747314453125 +92172 0.870361328125 +92173 0.5289306640625 +92174 0.86480712890625 +92175 0.55609130859375 +92176 0.831817626953125 +92177 0.544158935546875 +92178 0.677581787109375 +92179 0.50579833984375 +92180 0.495880126953125 +92181 0.44384765625 +92182 0.30767822265625 +92183 0.36767578125 +92184 0.116180419921875 +92185 0.278045654296875 +92186 -0.110748291015625 +92187 0.157989501953125 +92188 -0.381805419921875 +92189 0.00335693359375 +92190 -0.6572265625 +92191 -0.164093017578125 +92192 -0.857421875 +92193 -0.313720703125 +92194 -0.870391845703125 +92195 -0.42364501953125 +92196 -0.870391845703125 +92197 -0.490570068359375 +92198 -0.86444091796875 +92199 -0.52880859375 +92200 -0.85723876953125 +92201 -0.55712890625 +92202 -0.790008544921875 +92203 -0.56610107421875 +92204 -0.62847900390625 +92205 -0.52752685546875 +92206 -0.3956298828125 +92207 -0.439605712890625 +92208 -0.126708984375 +92209 -0.3192138671875 +92210 0.150115966796875 +92211 -0.180328369140625 +92212 0.424041748046875 +92213 -0.0286865234375 +92214 0.670623779296875 +92215 0.1220703125 +92216 0.854522705078125 +92217 0.252166748046875 +92218 0.866485595703125 +92219 0.352783203125 +92220 0.86920166015625 +92221 0.41632080078125 +92222 0.8653564453125 +92223 0.4525146484375 +92224 0.857147216796875 +92225 0.468597412109375 +92226 0.766845703125 +92227 0.463287353515625 +92228 0.628509521484375 +92229 0.439361572265625 +92230 0.462127685546875 +92231 0.393341064453125 +92232 0.297210693359375 +92233 0.33856201171875 +92234 0.14862060546875 +92235 0.281341552734375 +92236 -0.00537109375 +92237 0.2095947265625 +92238 -0.15753173828125 +92239 0.126983642578125 +92240 -0.31304931640625 +92241 0.03131103515625 +92242 -0.48876953125 +92243 -0.084991455078125 +92244 -0.6416015625 +92245 -0.1978759765625 +92246 -0.751373291015625 +92247 -0.294769287109375 +92248 -0.84619140625 +92249 -0.387969970703125 +92250 -0.861297607421875 +92251 -0.47003173828125 +92252 -0.863250732421875 +92253 -0.523895263671875 +92254 -0.856597900390625 +92255 -0.533233642578125 +92256 -0.7498779296875 +92257 -0.504425048828125 +92258 -0.624542236328125 +92259 -0.467559814453125 +92260 -0.47808837890625 +92261 -0.411102294921875 +92262 -0.253387451171875 +92263 -0.304534912109375 +92264 0.003692626953125 +92265 -0.17138671875 +92266 0.2257080078125 +92267 -0.0469970703125 +92268 0.427154541015625 +92269 0.075408935546875 +92270 0.643218994140625 +92271 0.212921142578125 +92272 0.855926513671875 +92273 0.360748291015625 +92274 0.870361328125 +92275 0.48895263671875 +92276 0.870361328125 +92277 0.571929931640625 +92278 0.862762451171875 +92279 0.61358642578125 +92280 0.79669189453125 +92281 0.612457275390625 +92282 0.595794677734375 +92283 0.563690185546875 +92284 0.362152099609375 +92285 0.482452392578125 +92286 0.1270751953125 +92287 0.383270263671875 +92288 -0.086944580078125 +92289 0.277069091796875 +92290 -0.2784423828125 +92291 0.164825439453125 +92292 -0.484832763671875 +92293 0.0283203125 +92294 -0.729583740234375 +92295 -0.142547607421875 +92296 -0.86688232421875 +92297 -0.3216552734375 +92298 -0.870391845703125 +92299 -0.47625732421875 +92300 -0.86859130859375 +92301 -0.603912353515625 +92302 -0.86279296875 +92303 -0.70361328125 +92304 -0.817962646484375 +92305 -0.75677490234375 +92306 -0.6116943359375 +92307 -0.7398681640625 +92308 -0.3128662109375 +92309 -0.64923095703125 +92310 0.039398193359375 +92311 -0.502410888671875 +92312 0.422821044921875 +92313 -0.309783935546875 +92314 0.805145263671875 +92315 -0.088623046875 +92316 0.870361328125 +92317 0.125640869140625 +92318 0.870361328125 +92319 0.30340576171875 +92320 0.860015869140625 +92321 0.4385986328125 +92322 0.727935791015625 +92323 0.52728271484375 +92324 0.48114013671875 +92325 0.566558837890625 +92326 0.2059326171875 +92327 0.569000244140625 +92328 -0.06103515625 +92329 0.546356201171875 +92330 -0.29913330078125 +92331 0.503875732421875 +92332 -0.516204833984375 +92333 0.43402099609375 +92334 -0.7252197265625 +92335 0.328857421875 +92336 -0.85980224609375 +92337 0.201385498046875 +92338 -0.870391845703125 +92339 0.069549560546875 +92340 -0.870391845703125 +92341 -0.051116943359375 +92342 -0.858062744140625 +92343 -0.13519287109375 +92344 -0.673004150390625 +92345 -0.1802978515625 +92346 -0.42694091796875 +92347 -0.213531494140625 +92348 -0.2100830078125 +92349 -0.257781982421875 +92350 -0.0362548828125 +92351 -0.311767578125 +92352 0.10943603515625 +92353 -0.360260009765625 +92354 0.23516845703125 +92355 -0.392791748046875 +92356 0.373687744140625 +92357 -0.38775634765625 +92358 0.517791748046875 +92359 -0.34613037109375 +92360 0.602783203125 +92361 -0.30072021484375 +92362 0.635711669921875 +92363 -0.248870849609375 +92364 0.655181884765625 +92365 -0.17340087890625 +92366 0.65948486328125 +92367 -0.07965087890625 +92368 0.651275634765625 +92369 0.027984619140625 +92370 0.61846923828125 +92371 0.136505126953125 +92372 0.53753662109375 +92373 0.226470947265625 +92374 0.404144287109375 +92375 0.288238525390625 +92376 0.22186279296875 +92377 0.316558837890625 +92378 0.003997802734375 +92379 0.3118896484375 +92380 -0.22100830078125 +92381 0.28350830078125 +92382 -0.42449951171875 +92383 0.242034912109375 +92384 -0.579833984375 +92385 0.198516845703125 +92386 -0.641876220703125 +92387 0.1751708984375 +92388 -0.6177978515625 +92389 0.1685791015625 +92390 -0.575531005859375 +92391 0.145263671875 +92392 -0.526336669921875 +92393 0.10260009765625 +92394 -0.42645263671875 +92395 0.067718505859375 +92396 -0.2581787109375 +92397 0.055084228515625 +92398 -0.068695068359375 +92399 0.046051025390625 +92400 0.09222412109375 +92401 0.020782470703125 +92402 0.232147216796875 +92403 -0.010772705078125 +92404 0.3509521484375 +92405 -0.0430908203125 +92406 0.410064697265625 +92407 -0.0914306640625 +92408 0.372955322265625 +92409 -0.1708984375 +92410 0.2554931640625 +92411 -0.270477294921875 +92412 0.10711669921875 +92413 -0.363006591796875 +92414 -0.052886962890625 +92415 -0.43829345703125 +92416 -0.186279296875 +92417 -0.47711181640625 +92418 -0.23291015625 +92419 -0.450042724609375 +92420 -0.209442138671875 +92421 -0.369903564453125 +92422 -0.174163818359375 +92423 -0.27239990234375 +92424 -0.126739501953125 +92425 -0.1614990234375 +92426 -0.048126220703125 +92427 -0.031280517578125 +92428 0.0426025390625 +92429 0.103179931640625 +92430 0.10748291015625 +92431 0.21661376953125 +92432 0.1409912109375 +92433 0.302032470703125 +92434 0.19708251953125 +92435 0.3858642578125 +92436 0.273651123046875 +92437 0.464508056640625 +92438 0.31768798828125 +92439 0.50726318359375 +92440 0.341094970703125 +92441 0.520172119140625 +92442 0.368011474609375 +92443 0.51702880859375 +92444 0.37249755859375 +92445 0.48504638671875 +92446 0.30072021484375 +92447 0.396942138671875 +92448 0.1517333984375 +92449 0.25518798828125 +92450 -0.01470947265625 +92451 0.096221923828125 +92452 -0.1883544921875 +92453 -0.070404052734375 +92454 -0.372711181640625 +92455 -0.242645263671875 +92456 -0.51397705078125 +92457 -0.387115478515625 +92458 -0.57177734375 +92459 -0.47802734375 +92460 -0.53948974609375 +92461 -0.508758544921875 +92462 -0.43511962890625 +92463 -0.48687744140625 +92464 -0.2962646484375 +92465 -0.4315185546875 +92466 -0.161102294921875 +92467 -0.362945556640625 +92468 -0.0435791015625 +92469 -0.2889404296875 +92470 0.060394287109375 +92471 -0.20819091796875 +92472 0.13665771484375 +92473 -0.130157470703125 +92474 0.170135498046875 +92475 -0.065460205078125 +92476 0.16552734375 +92477 -0.01434326171875 +92478 0.15728759765625 +92479 0.038970947265625 +92480 0.150787353515625 +92481 0.09417724609375 +92482 0.12200927734375 +92483 0.13482666015625 +92484 0.080108642578125 +92485 0.1629638671875 +92486 0.05126953125 +92487 0.190338134765625 +92488 0.062896728515625 +92489 0.229888916015625 +92490 0.09271240234375 +92491 0.267852783203125 +92492 0.092987060546875 +92493 0.277130126953125 +92494 0.07855224609375 +92495 0.2657470703125 +92496 0.06427001953125 +92497 0.242431640625 +92498 0.0347900390625 +92499 0.19989013671875 +92500 -0.01171875 +92501 0.13885498046875 +92502 -0.056060791015625 +92503 0.07208251953125 +92504 -0.055511474609375 +92505 0.025604248046875 +92506 -0.010467529296875 +92507 0.001861572265625 +92508 0.02508544921875 +92509 -0.026092529296875 +92510 0.025665283203125 +92511 -0.0697021484375 +92512 0.017333984375 +92513 -0.11236572265625 +92514 0.00189208984375 +92515 -0.15118408203125 +92516 -0.03173828125 +92517 -0.190826416015625 +92518 -0.071502685546875 +92519 -0.223785400390625 +92520 -0.13543701171875 +92521 -0.2596435546875 +92522 -0.219970703125 +92523 -0.29669189453125 +92524 -0.300506591796875 +92525 -0.32220458984375 +92526 -0.376312255859375 +92527 -0.337066650390625 +92528 -0.416107177734375 +92529 -0.325775146484375 +92530 -0.371124267578125 +92531 -0.263519287109375 +92532 -0.242279052734375 +92533 -0.152984619140625 +92534 -0.069732666015625 +92535 -0.0184326171875 +92536 0.125640869140625 +92537 0.126434326171875 +92538 0.31268310546875 +92539 0.26251220703125 +92540 0.45501708984375 +92541 0.368133544921875 +92542 0.554779052734375 +92543 0.443115234375 +92544 0.61065673828125 +92545 0.485870361328125 +92546 0.610931396484375 +92547 0.489532470703125 +92548 0.531463623046875 +92549 0.44085693359375 +92550 0.3883056640625 +92551 0.349212646484375 +92552 0.23468017578125 +92553 0.244781494140625 +92554 0.095245361328125 +92555 0.142425537109375 +92556 -0.00396728515625 +92557 0.05804443359375 +92558 -0.04852294921875 +92559 0.00128173828125 +92560 -0.055145263671875 +92561 -0.035186767578125 +92562 -0.0758056640625 +92563 -0.07818603515625 +92564 -0.138702392578125 +92565 -0.141510009765625 +92566 -0.209197998046875 +92567 -0.204620361328125 +92568 -0.289031982421875 +92569 -0.26727294921875 +92570 -0.37884521484375 +92571 -0.328948974609375 +92572 -0.456329345703125 +92573 -0.37689208984375 +92574 -0.51641845703125 +92575 -0.40826416015625 +92576 -0.519287109375 +92577 -0.40142822265625 +92578 -0.458251953125 +92579 -0.353363037109375 +92580 -0.384796142578125 +92581 -0.293365478515625 +92582 -0.323699951171875 +92583 -0.236236572265625 +92584 -0.269287109375 +92585 -0.18023681640625 +92586 -0.1951904296875 +92587 -0.112396240234375 +92588 -0.100006103515625 +92589 -0.033447265625 +92590 -0.01055908203125 +92591 0.0404052734375 +92592 0.1033935546875 +92593 0.12451171875 +92594 0.24908447265625 +92595 0.22174072265625 +92596 0.373199462890625 +92597 0.301971435546875 +92598 0.45806884765625 +92599 0.35498046875 +92600 0.511474609375 +92601 0.384857177734375 +92602 0.565399169921875 +92603 0.40936279296875 +92604 0.61138916015625 +92605 0.424285888671875 +92606 0.5897216796875 +92607 0.397491455078125 +92608 0.4906005859375 +92609 0.32452392578125 +92610 0.33148193359375 +92611 0.21612548828125 +92612 0.147796630859375 +92613 0.09295654296875 +92614 -0.01873779296875 +92615 -0.020751953125 +92616 -0.140289306640625 +92617 -0.108489990234375 +92618 -0.191986083984375 +92619 -0.155487060546875 +92620 -0.184295654296875 +92621 -0.166534423828125 +92622 -0.161834716796875 +92623 -0.16546630859375 +92624 -0.166595458984375 +92625 -0.17486572265625 +92626 -0.19390869140625 +92627 -0.191925048828125 +92628 -0.22442626953125 +92629 -0.206024169921875 +92630 -0.279754638671875 +92631 -0.229339599609375 +92632 -0.3389892578125 +92633 -0.250885009765625 +92634 -0.3543701171875 +92635 -0.2451171875 +92636 -0.348175048828125 +92637 -0.22515869140625 +92638 -0.32598876953125 +92639 -0.19500732421875 +92640 -0.2581787109375 +92641 -0.139434814453125 +92642 -0.139801025390625 +92643 -0.05670166015625 +92644 0.014617919921875 +92645 0.04425048828125 +92646 0.144378662109375 +92647 0.129180908203125 +92648 0.221038818359375 +92649 0.18182373046875 +92650 0.27069091796875 +92651 0.21600341796875 +92652 0.294036865234375 +92653 0.23187255859375 +92654 0.311767578125 +92655 0.240753173828125 +92656 0.339141845703125 +92657 0.251220703125 +92658 0.360260009765625 +92659 0.2548828125 +92660 0.360504150390625 +92661 0.2442626953125 +92662 0.308380126953125 +92663 0.202606201171875 +92664 0.18170166015625 +92665 0.118408203125 +92666 0.0047607421875 +92667 0.00592041015625 +92668 -0.17559814453125 +92669 -0.108184814453125 +92670 -0.3143310546875 +92671 -0.198272705078125 +92672 -0.36785888671875 +92673 -0.23919677734375 +92674 -0.36248779296875 +92675 -0.245269775390625 +92676 -0.343536376953125 +92677 -0.24169921875 +92678 -0.3018798828125 +92679 -0.222625732421875 +92680 -0.231414794921875 +92681 -0.18408203125 +92682 -0.117645263671875 +92683 -0.117462158203125 +92684 0.007049560546875 +92685 -0.04168701171875 +92686 0.087982177734375 +92687 0.011077880859375 +92688 0.13946533203125 +92689 0.048858642578125 +92690 0.17425537109375 +92691 0.078582763671875 +92692 0.188201904296875 +92693 0.09722900390625 +92694 0.171234130859375 +92695 0.09832763671875 +92696 0.118438720703125 +92697 0.078369140625 +92698 0.05706787109375 +92699 0.05267333984375 +92700 -0.010711669921875 +92701 0.02191162109375 +92702 -0.0914306640625 +92703 -0.0181884765625 +92704 -0.162322998046875 +92705 -0.05462646484375 +92706 -0.194549560546875 +92707 -0.07080078125 +92708 -0.1492919921875 +92709 -0.04412841796875 +92710 -0.02166748046875 +92711 0.02825927734375 +92712 0.124053955078125 +92713 0.109039306640625 +92714 0.211151123046875 +92715 0.1536865234375 +92716 0.240447998046875 +92717 0.163116455078125 +92718 0.242218017578125 +92719 0.155426025390625 +92720 0.2257080078125 +92721 0.13653564453125 +92722 0.194366455078125 +92723 0.1090087890625 +92724 0.115509033203125 +92725 0.054229736328125 +92726 0.0128173828125 +92727 -0.013427734375 +92728 -0.053802490234375 +92729 -0.05865478515625 +92730 -0.110626220703125 +92731 -0.096466064453125 +92732 -0.199493408203125 +92733 -0.151092529296875 +92734 -0.29437255859375 +92735 -0.207275390625 +92736 -0.33221435546875 +92737 -0.228179931640625 +92738 -0.27972412109375 +92739 -0.194488525390625 +92740 -0.185333251953125 +92741 -0.134735107421875 +92742 -0.128204345703125 +92743 -0.095428466796875 +92744 -0.115692138671875 +92745 -0.0811767578125 +92746 -0.116455078125 +92747 -0.074127197265625 +92748 -0.105926513671875 +92749 -0.06036376953125 +92750 -0.053955078125 +92751 -0.022705078125 +92752 0.048797607421875 +92753 0.043914794921875 +92754 0.157318115234375 +92755 0.112884521484375 +92756 0.212005615234375 +92757 0.149139404296875 +92758 0.218475341796875 +92759 0.155731201171875 +92760 0.23724365234375 +92761 0.167877197265625 +92762 0.30535888671875 +92763 0.20721435546875 +92764 0.38128662109375 +92765 0.24951171875 +92766 0.404449462890625 +92767 0.25958251953125 +92768 0.3944091796875 +92769 0.24908447265625 +92770 0.3885498046875 +92771 0.240142822265625 +92772 0.362640380859375 +92773 0.21893310546875 +92774 0.27362060546875 +92775 0.16064453125 +92776 0.11712646484375 +92777 0.063079833984375 +92778 -0.054901123046875 +92779 -0.043060302734375 +92780 -0.19085693359375 +92781 -0.127349853515625 +92782 -0.28570556640625 +92783 -0.186614990234375 +92784 -0.339263916015625 +92785 -0.2205810546875 +92786 -0.3775634765625 +92787 -0.24432373046875 +92788 -0.445709228515625 +92789 -0.284149169921875 +92790 -0.535064697265625 +92791 -0.335052490234375 +92792 -0.629058837890625 +92793 -0.387451171875 +92794 -0.697601318359375 +92795 -0.423919677734375 +92796 -0.70391845703125 +92797 -0.423248291015625 +92798 -0.6424560546875 +92799 -0.3824462890625 +92800 -0.491241455078125 +92801 -0.288970947265625 +92802 -0.265716552734375 +92803 -0.152099609375 +92804 -0.023712158203125 +92805 -0.00592041015625 +92806 0.201751708984375 +92807 0.130035400390625 +92808 0.375823974609375 +92809 0.23516845703125 +92810 0.485076904296875 +92811 0.301513671875 +92812 0.56884765625 +92813 0.351898193359375 +92814 0.634765625 +92815 0.3907470703125 +92816 0.63763427734375 +92817 0.391693115234375 +92818 0.5660400390625 +92819 0.34808349609375 +92820 0.4720458984375 +92821 0.290496826171875 +92822 0.40692138671875 +92823 0.2490234375 +92824 0.3778076171875 +92825 0.228057861328125 +92826 0.376953125 +92827 0.223297119140625 +92828 0.371978759765625 +92829 0.216094970703125 +92830 0.313140869140625 +92831 0.1776123046875 +92832 0.184417724609375 +92833 0.09869384765625 +92834 0.011199951171875 +92835 -0.005584716796875 +92836 -0.171051025390625 +92837 -0.114349365234375 +92838 -0.33740234375 +92839 -0.21295166015625 +92840 -0.47198486328125 +92841 -0.29205322265625 +92842 -0.560394287109375 +92843 -0.34326171875 +92844 -0.58056640625 +92845 -0.353759765625 +92846 -0.54754638671875 +92847 -0.332427978515625 +92848 -0.508575439453125 +92849 -0.3070068359375 +92850 -0.459503173828125 +92851 -0.275238037109375 +92852 -0.394378662109375 +92853 -0.233795166015625 +92854 -0.35260009765625 +92855 -0.205902099609375 +92856 -0.31170654296875 +92857 -0.1785888671875 +92858 -0.197418212890625 +92859 -0.108673095703125 +92860 -0.007965087890625 +92861 0.00469970703125 +92862 0.207489013671875 +92863 0.132659912109375 +92864 0.409210205078125 +92865 0.25189208984375 +92866 0.57208251953125 +92867 0.347686767578125 +92868 0.66595458984375 +92869 0.402435302734375 +92870 0.65875244140625 +92871 0.39739990234375 +92872 0.56744384765625 +92873 0.34259033203125 +92874 0.431396484375 +92875 0.2611083984375 +92876 0.29443359375 +92877 0.17864990234375 +92878 0.182464599609375 +92879 0.1104736328125 +92880 0.06365966796875 +92881 0.038177490234375 +92882 -0.075958251953125 +92883 -0.046234130859375 +92884 -0.189422607421875 +92885 -0.11517333984375 +92886 -0.271942138671875 +92887 -0.165679931640625 +92888 -0.342529296875 +92889 -0.208770751953125 +92890 -0.364166259765625 +92891 -0.222747802734375 +92892 -0.327239990234375 +92893 -0.201934814453125 +92894 -0.2769775390625 +92895 -0.1727294921875 +92896 -0.253692626953125 +92897 -0.15869140625 +92898 -0.24365234375 +92899 -0.15179443359375 +92900 -0.1983642578125 +92901 -0.123809814453125 +92902 -0.116241455078125 +92903 -0.07391357421875 +92904 -0.036834716796875 +92905 -0.025299072265625 +92906 0.034881591796875 +92907 0.018951416015625 +92908 0.09124755859375 +92909 0.05426025390625 +92910 0.10888671875 +92911 0.06683349609375 +92912 0.125518798828125 +92913 0.078582763671875 +92914 0.15771484375 +92915 0.099090576171875 +92916 0.17828369140625 +92917 0.11236572265625 +92918 0.17108154296875 +92919 0.108917236328125 +92920 0.129974365234375 +92921 0.08514404296875 +92922 0.082427978515625 +92923 0.057098388671875 +92924 0.027679443359375 +92925 0.024383544921875 +92926 -0.065643310546875 +92927 -0.03125 +92928 -0.15936279296875 +92929 -0.0870361328125 +92930 -0.21307373046875 +92931 -0.1197509765625 +92932 -0.234649658203125 +92933 -0.134552001953125 +92934 -0.2001953125 +92935 -0.1162109375 +92936 -0.119171142578125 +92937 -0.070037841796875 +92938 -0.024749755859375 +92939 -0.016021728515625 +92940 0.085784912109375 +92941 0.047943115234375 +92942 0.178131103515625 +92943 0.101043701171875 +92944 0.215576171875 +92945 0.1209716796875 +92946 0.211456298828125 +92947 0.116119384765625 +92948 0.17523193359375 +92949 0.09246826171875 +92950 0.128753662109375 +92951 0.06353759765625 +92952 0.1019287109375 +92953 0.0477294921875 +92954 0.0743408203125 +92955 0.032379150390625 +92956 0.04327392578125 +92957 0.01568603515625 +92958 0.038177490234375 +92959 0.015594482421875 +92960 0.076263427734375 +92961 0.042510986328125 +92962 0.14105224609375 +92963 0.086029052734375 +92964 0.186431884765625 +92965 0.1175537109375 +92966 0.188812255859375 +92967 0.122344970703125 +92968 0.1390380859375 +92969 0.094573974609375 +92970 0.041778564453125 +92971 0.0369873046875 +92972 -0.079437255859375 +92973 -0.0360107421875 +92974 -0.219390869140625 +92975 -0.121307373046875 +92976 -0.367828369140625 +92977 -0.21258544921875 +92978 -0.494873046875 +92979 -0.291473388671875 +92980 -0.556243896484375 +92981 -0.330596923828125 +92982 -0.508697509765625 +92983 -0.30322265625 +92984 -0.3756103515625 +92985 -0.223663330078125 +92986 -0.218902587890625 +92987 -0.129913330078125 +92988 -0.063751220703125 +92989 -0.03729248046875 +92990 0.091552734375 +92991 0.055389404296875 +92992 0.23602294921875 +92993 0.14154052734375 +92994 0.342987060546875 +92995 0.204864501953125 +92996 0.39520263671875 +92997 0.234893798828125 +92998 0.389373779296875 +92999 0.229705810546875 +93000 0.324249267578125 +93001 0.1885986328125 +93002 0.224090576171875 +93003 0.126556396484375 +93004 0.124267578125 +93005 0.06536865234375 +93006 0.037078857421875 +93007 0.012542724609375 +93008 -0.010101318359375 +93009 -0.015106201171875 +93010 -0.019439697265625 +93011 -0.019012451171875 +93012 -0.022796630859375 +93013 -0.018890380859375 +93014 -0.001556396484375 +93015 -0.00341796875 +93016 0.056304931640625 +93017 0.03466796875 +93018 0.106719970703125 +93019 0.068115234375 +93020 0.096893310546875 +93021 0.06427001953125 +93022 0.042694091796875 +93023 0.032806396484375 +93024 -0.018035888671875 +93025 -0.00311279296875 +93026 -0.07586669921875 +93027 -0.0377197265625 +93028 -0.11944580078125 +93029 -0.064056396484375 +93030 -0.15972900390625 +93031 -0.088897705078125 +93032 -0.202606201171875 +93033 -0.1158447265625 +93034 -0.24859619140625 +93035 -0.145172119140625 +93036 -0.30517578125 +93037 -0.181365966796875 +93038 -0.36212158203125 +93039 -0.218109130859375 +93040 -0.39141845703125 +93041 -0.238037109375 +93042 -0.35528564453125 +93043 -0.217742919921875 +93044 -0.249969482421875 +93045 -0.15484619140625 +93046 -0.092864990234375 +93047 -0.0599365234375 +93048 0.08905029296875 +93049 0.05047607421875 +93050 0.2352294921875 +93051 0.13916015625 +93052 0.318817138671875 +93053 0.18963623046875 +93054 0.358642578125 +93055 0.21356201171875 +93056 0.347747802734375 +93057 0.2066650390625 +93058 0.28564453125 +93059 0.16864013671875 +93060 0.223175048828125 +93061 0.13079833984375 +93062 0.196746826171875 +93063 0.115478515625 +93064 0.179840087890625 +93065 0.1063232421875 +93066 0.155548095703125 +93067 0.09283447265625 +93068 0.151214599609375 +93069 0.091766357421875 +93070 0.156951904296875 +93071 0.096923828125 +93072 0.13177490234375 +93073 0.08294677734375 +93074 0.100799560546875 +93075 0.06524658203125 +93076 0.087127685546875 +93077 0.058013916015625 +93078 0.05487060546875 +93079 0.039093017578125 +93080 -0.009002685546875 +93081 0.0003662109375 +93082 -0.10400390625 +93083 -0.057861328125 +93084 -0.229400634765625 +93085 -0.135162353515625 +93086 -0.35552978515625 +93087 -0.2132568359375 +93088 -0.441925048828125 +93089 -0.26715087890625 +93090 -0.473846435546875 +93091 -0.287750244140625 +93092 -0.464813232421875 +93093 -0.283294677734375 +93094 -0.419097900390625 +93095 -0.25634765625 +93096 -0.334320068359375 +93097 -0.20538330078125 +93098 -0.227935791015625 +93099 -0.141082763671875 +93100 -0.12347412109375 +93101 -0.077880859375 +93102 -0.02764892578125 +93103 -0.01983642578125 +93104 0.077667236328125 +93105 0.04425048828125 +93106 0.2132568359375 +93107 0.127197265625 +93108 0.38885498046875 +93109 0.23504638671875 +93110 0.582794189453125 +93111 0.35443115234375 +93112 0.734039306640625 +93113 0.447784423828125 +93114 0.800140380859375 +93115 0.4888916015625 +93116 0.7783203125 +93117 0.476043701171875 +93118 0.6651611328125 +93119 0.4071044921875 +93120 0.45965576171875 +93121 0.281402587890625 +93122 0.199188232421875 +93123 0.1219482421875 +93124 -0.050689697265625 +93125 -0.030975341796875 +93126 -0.23297119140625 +93127 -0.14227294921875 +93128 -0.33013916015625 +93129 -0.20123291015625 +93130 -0.368408203125 +93131 -0.224029541015625 +93132 -0.378936767578125 +93133 -0.229888916015625 +93134 -0.376983642578125 +93135 -0.228271484375 +93136 -0.37969970703125 +93137 -0.229766845703125 +93138 -0.391510009765625 +93139 -0.237091064453125 +93140 -0.385345458984375 +93141 -0.23358154296875 +93142 -0.3419189453125 +93143 -0.20733642578125 +93144 -0.28289794921875 +93145 -0.171630859375 +93146 -0.251617431640625 +93147 -0.153106689453125 +93148 -0.266143798828125 +93149 -0.162841796875 +93150 -0.273345947265625 +93151 -0.168121337890625 +93152 -0.216796875 +93153 -0.13409423828125 +93154 -0.128265380859375 +93155 -0.080291748046875 +93156 -0.068145751953125 +93157 -0.04388427734375 +93158 -0.0430908203125 +93159 -0.028900146484375 +93160 -0.024444580078125 +93161 -0.0177001953125 +93162 0.020721435546875 +93163 0.009979248046875 +93164 0.124481201171875 +93165 0.07391357421875 +93166 0.25787353515625 +93167 0.15625 +93168 0.379119873046875 +93169 0.231201171875 +93170 0.47991943359375 +93171 0.293670654296875 +93172 0.5281982421875 +93173 0.3238525390625 +93174 0.511138916015625 +93175 0.313873291015625 +93176 0.456207275390625 +93177 0.280609130859375 +93178 0.407470703125 +93179 0.251190185546875 +93180 0.383758544921875 +93181 0.237152099609375 +93182 0.35687255859375 +93183 0.221099853515625 +93184 0.31182861328125 +93185 0.19427490234375 +93186 0.250885009765625 +93187 0.158355712890625 +93188 0.1654052734375 +93189 0.10736083984375 +93190 0.035247802734375 +93191 0.02777099609375 +93192 -0.142059326171875 +93193 -0.08245849609375 +93194 -0.33563232421875 +93195 -0.203704833984375 +93196 -0.5345458984375 +93197 -0.329193115234375 +93198 -0.72186279296875 +93199 -0.448211669921875 +93200 -0.836669921875 +93201 -0.52142333984375 +93202 -0.8326416015625 +93203 -0.51885986328125 +93204 -0.7296142578125 +93205 -0.453369140625 +93206 -0.582550048828125 +93207 -0.360443115234375 +93208 -0.440093994140625 +93209 -0.27142333984375 +93210 -0.324310302734375 +93211 -0.200439453125 +93212 -0.20147705078125 +93213 -0.125335693359375 +93214 -0.044647216796875 +93215 -0.02838134765625 +93216 0.103973388671875 +93217 0.063323974609375 +93218 0.202392578125 +93219 0.122833251953125 +93220 0.264495849609375 +93221 0.15936279296875 +93222 0.338897705078125 +93223 0.204620361328125 +93224 0.443817138671875 +93225 0.27056884765625 +93226 0.545074462890625 +93227 0.335113525390625 +93228 0.6173095703125 +93229 0.381866455078125 +93230 0.6524658203125 +93231 0.405609130859375 +93232 0.66339111328125 +93233 0.414581298828125 +93234 0.6561279296875 +93235 0.41253662109375 +93236 0.606781005859375 +93237 0.383819580078125 +93238 0.501190185546875 +93239 0.319061279296875 +93240 0.352783203125 +93241 0.22674560546875 +93242 0.176544189453125 +93243 0.11639404296875 +93244 -0.034820556640625 +93245 -0.01690673828125 +93246 -0.258209228515625 +93247 -0.15838623046875 +93248 -0.44244384765625 +93249 -0.275054931640625 +93250 -0.5753173828125 +93251 -0.359130859375 +93252 -0.65203857421875 +93253 -0.4075927734375 +93254 -0.641632080078125 +93255 -0.40045166015625 +93256 -0.562164306640625 +93257 -0.34942626953125 +93258 -0.458038330078125 +93259 -0.283233642578125 +93260 -0.350555419921875 +93261 -0.215545654296875 +93262 -0.260528564453125 +93263 -0.15972900390625 +93264 -0.192108154296875 +93265 -0.118316650390625 +93266 -0.141937255859375 +93267 -0.088958740234375 +93268 -0.1021728515625 +93269 -0.06640625 +93270 -0.062896728515625 +93271 -0.0440673828125 +93272 -0.011932373046875 +93273 -0.01385498046875 +93274 0.062835693359375 +93275 0.032196044921875 +93276 0.148712158203125 +93277 0.08599853515625 +93278 0.241729736328125 +93279 0.14501953125 +93280 0.34912109375 +93281 0.214019775390625 +93282 0.457305908203125 +93283 0.28424072265625 +93284 0.54388427734375 +93285 0.341094970703125 +93286 0.5728759765625 +93287 0.36126708984375 +93288 0.506591796875 +93289 0.3201904296875 +93290 0.351226806640625 +93291 0.221771240234375 +93292 0.146514892578125 +93293 0.091644287109375 +93294 -0.05523681640625 +93295 -0.03643798828125 +93296 -0.21624755859375 +93297 -0.138153076171875 +93298 -0.334930419921875 +93299 -0.21258544921875 +93300 -0.402984619140625 +93301 -0.2545166015625 +93302 -0.4412841796875 +93303 -0.277557373046875 +93304 -0.49578857421875 +93305 -0.31158447265625 +93306 -0.5601806640625 +93307 -0.352569580078125 +93308 -0.600738525390625 +93309 -0.378662109375 +93310 -0.584228515625 +93311 -0.36834716796875 +93312 -0.47930908203125 +93313 -0.301300048828125 +93314 -0.27935791015625 +93315 -0.17315673828125 +93316 -0.0089111328125 +93317 0.000244140625 +93318 0.268798828125 +93319 0.17803955078125 +93320 0.482818603515625 +93321 0.314422607421875 +93322 0.60369873046875 +93323 0.39044189453125 +93324 0.650421142578125 +93325 0.418487548828125 +93326 0.66400146484375 +93327 0.42529296875 +93328 0.6414794921875 +93329 0.409027099609375 +93330 0.572540283203125 +93331 0.36309814453125 +93332 0.498138427734375 +93333 0.3140869140625 +93334 0.439453125 +93335 0.2757568359375 +93336 0.375518798828125 +93337 0.234527587890625 +93338 0.274505615234375 +93339 0.16973876953125 +93340 0.1087646484375 +93341 0.06341552734375 +93342 -0.099395751953125 +93343 -0.070037841796875 +93344 -0.3182373046875 +93345 -0.210113525390625 +93346 -0.5489501953125 +93347 -0.35772705078125 +93348 -0.7738037109375 +93349 -0.50146484375 +93350 -0.86383056640625 +93351 -0.60711669921875 +93352 -0.870391845703125 +93353 -0.65325927734375 +93354 -0.86895751953125 +93355 -0.651458740234375 +93356 -0.861053466796875 +93357 -0.610321044921875 +93358 -0.765869140625 +93359 -0.5186767578125 +93360 -0.5301513671875 +93361 -0.369232177734375 +93362 -0.214691162109375 +93363 -0.1666259765625 +93364 0.137359619140625 +93365 0.061248779296875 +93366 0.474822998046875 +93367 0.281158447265625 +93368 0.76239013671875 +93369 0.47015380859375 +93370 0.867462158203125 +93371 0.610809326171875 +93372 0.870361328125 +93373 0.703460693359375 +93374 0.86480712890625 +93375 0.74072265625 +93376 0.831817626953125 +93377 0.726165771484375 +93378 0.677581787109375 +93379 0.6756591796875 +93380 0.495880126953125 +93381 0.593048095703125 +93382 0.30767822265625 +93383 0.490386962890625 +93384 0.116180419921875 +93385 0.36920166015625 +93386 -0.110748291015625 +93387 0.208953857421875 +93388 -0.381805419921875 +93389 0.005157470703125 +93390 -0.6572265625 +93391 -0.21441650390625 +93392 -0.857421875 +93393 -0.410980224609375 +93394 -0.870391845703125 +93395 -0.556732177734375 +93396 -0.870391845703125 +93397 -0.647064208984375 +93398 -0.86444091796875 +93399 -0.699493408203125 +93400 -0.85723876953125 +93401 -0.737213134765625 +93402 -0.790008544921875 +93403 -0.748382568359375 +93404 -0.62847900390625 +93405 -0.697906494140625 +93406 -0.3956298828125 +93407 -0.583770751953125 +93408 -0.126708984375 +93409 -0.4273681640625 +93410 0.150115966796875 +93411 -0.2464599609375 +93412 0.424041748046875 +93413 -0.0487060546875 +93414 0.670623779296875 +93415 0.14837646484375 +93416 0.854522705078125 +93417 0.319671630859375 +93418 0.866485595703125 +93419 0.453704833984375 +93420 0.86920166015625 +93421 0.54052734375 +93422 0.8653564453125 +93423 0.591888427734375 +93424 0.857147216796875 +93425 0.61651611328125 +93426 0.766845703125 +93427 0.612548828125 +93428 0.628509521484375 +93429 0.5833740234375 +93430 0.462127685546875 +93431 0.524658203125 +93432 0.297210693359375 +93433 0.45318603515625 +93434 0.14862060546875 +93435 0.377044677734375 +93436 -0.00537109375 +93437 0.281494140625 +93438 -0.15753173828125 +93439 0.171478271484375 +93440 -0.31304931640625 +93441 0.04425048828125 +93442 -0.48876953125 +93443 -0.10931396484375 +93444 -0.6416015625 +93445 -0.25750732421875 +93446 -0.751373291015625 +93447 -0.384246826171875 +93448 -0.84619140625 +93449 -0.505889892578125 +93450 -0.861297607421875 +93451 -0.6129150390625 +93452 -0.863250732421875 +93453 -0.683197021484375 +93454 -0.856597900390625 +93455 -0.69549560546875 +93456 -0.7498779296875 +93457 -0.658172607421875 +93458 -0.624542236328125 +93459 -0.61053466796875 +93460 -0.47808837890625 +93461 -0.5374755859375 +93462 -0.253387451171875 +93463 -0.39898681640625 +93464 0.003692626953125 +93465 -0.225799560546875 +93466 0.2257080078125 +93467 -0.064056396484375 +93468 0.427154541015625 +93469 0.09515380859375 +93470 0.643218994140625 +93471 0.27423095703125 +93472 0.855926513671875 +93473 0.467010498046875 +93474 0.870361328125 +93475 0.6343994140625 +93476 0.870361328125 +93477 0.742919921875 +93478 0.862762451171875 +93479 0.797637939453125 +93480 0.79669189453125 +93481 0.796661376953125 +93482 0.595794677734375 +93483 0.733612060546875 +93484 0.362152099609375 +93485 0.6282958984375 +93486 0.1270751953125 +93487 0.499664306640625 +93488 -0.086944580078125 +93489 0.361907958984375 +93490 -0.2784423828125 +93491 0.216278076171875 +93492 -0.484832763671875 +93493 0.038848876953125 +93494 -0.729583740234375 +93495 -0.183685302734375 +93496 -0.86688232421875 +93497 -0.41717529296875 +93498 -0.870391845703125 +93499 -0.618804931640625 +93500 -0.86859130859375 +93501 -0.785430908203125 +93502 -0.86279296875 +93503 -0.8612060546875 +93504 -0.817962646484375 +93505 -0.868804931640625 +93506 -0.6116943359375 +93507 -0.866455078125 +93508 -0.3128662109375 +93509 -0.84600830078125 +93510 0.039398193359375 +93511 -0.65478515625 +93512 0.422821044921875 +93513 -0.403778076171875 +93514 0.805145263671875 +93515 -0.11553955078125 +93516 0.870361328125 +93517 0.1636962890625 +93518 0.870361328125 +93519 0.395294189453125 +93520 0.860015869140625 +93521 0.57135009765625 +93522 0.727935791015625 +93523 0.68670654296875 +93524 0.48114013671875 +93525 0.737579345703125 +93526 0.2059326171875 +93527 0.740478515625 +93528 -0.06103515625 +93529 0.710784912109375 +93530 -0.29913330078125 +93531 0.65533447265625 +93532 -0.516204833984375 +93533 0.56427001953125 +93534 -0.7252197265625 +93535 0.42718505859375 +93536 -0.85980224609375 +93537 0.26104736328125 +93538 -0.870391845703125 +93539 0.08929443359375 +93540 -0.870391845703125 +93541 -0.06781005859375 +93542 -0.858062744140625 +93543 -0.176971435546875 +93544 -0.673004150390625 +93545 -0.23516845703125 +93546 -0.42694091796875 +93547 -0.27789306640625 +93548 -0.2100830078125 +93549 -0.33514404296875 +93550 -0.0362548828125 +93551 -0.405303955078125 +93552 0.10943603515625 +93553 -0.468414306640625 +93554 0.23516845703125 +93555 -0.51080322265625 +93556 0.373687744140625 +93557 -0.504241943359375 +93558 0.517791748046875 +93559 -0.45001220703125 +93560 0.602783203125 +93561 -0.390960693359375 +93562 0.635711669921875 +93563 -0.32366943359375 +93564 0.655181884765625 +93565 -0.2255859375 +93566 0.65948486328125 +93567 -0.103668212890625 +93568 0.651275634765625 +93569 0.036376953125 +93570 0.61846923828125 +93571 0.177642822265625 +93572 0.53753662109375 +93573 0.29473876953125 +93574 0.404144287109375 +93575 0.375091552734375 +93576 0.22186279296875 +93577 0.41180419921875 +93578 0.003997802734375 +93579 0.405487060546875 +93580 -0.22100830078125 +93581 0.368255615234375 +93582 -0.42449951171875 +93583 0.314056396484375 +93584 -0.579833984375 +93585 0.25732421875 +93586 -0.641876220703125 +93587 0.227081298828125 +93588 -0.6177978515625 +93589 0.2188720703125 +93590 -0.575531005859375 +93591 0.188873291015625 +93592 -0.526336669921875 +93593 0.13360595703125 +93594 -0.42645263671875 +93595 0.088531494140625 +93596 -0.2581787109375 +93597 0.07257080078125 +93598 -0.068695068359375 +93599 0.061248779296875 +93600 0.09222412109375 +93601 0.028656005859375 +93602 0.232147216796875 +93603 -0.012237548828125 +93604 0.3509521484375 +93605 -0.05426025390625 +93606 0.410064697265625 +93607 -0.117340087890625 +93608 0.372955322265625 +93609 -0.22125244140625 +93610 0.2554931640625 +93611 -0.35162353515625 +93612 0.10711669921875 +93613 -0.472900390625 +93614 -0.052886962890625 +93615 -0.571746826171875 +93616 -0.186279296875 +93617 -0.62353515625 +93618 -0.23291015625 +93619 -0.590362548828125 +93620 -0.209442138671875 +93621 -0.48785400390625 +93622 -0.174163818359375 +93623 -0.3609619140625 +93624 -0.126739501953125 +93625 -0.215545654296875 +93626 -0.048126220703125 +93627 -0.04510498046875 +93628 0.0426025390625 +93629 0.130889892578125 +93630 0.10748291015625 +93631 0.280487060546875 +93632 0.1409912109375 +93633 0.3944091796875 +93634 0.19708251953125 +93635 0.5047607421875 +93636 0.273651123046875 +93637 0.60675048828125 +93638 0.31768798828125 +93639 0.662261962890625 +93640 0.341094970703125 +93641 0.678680419921875 +93642 0.368011474609375 +93643 0.673126220703125 +93644 0.37249755859375 +93645 0.62994384765625 +93646 0.30072021484375 +93647 0.51568603515625 +93648 0.1517333984375 +93649 0.333831787109375 +93650 -0.01470947265625 +93651 0.12982177734375 +93652 -0.1883544921875 +93653 -0.0841064453125 +93654 -0.372711181640625 +93655 -0.304962158203125 +93656 -0.51397705078125 +93657 -0.490966796875 +93658 -0.57177734375 +93659 -0.609893798828125 +93660 -0.53948974609375 +93661 -0.6531982421875 +93662 -0.43511962890625 +93663 -0.6300048828125 +93664 -0.2962646484375 +93665 -0.56378173828125 +93666 -0.161102294921875 +93667 -0.4794921875 +93668 -0.0435791015625 +93669 -0.38677978515625 +93670 0.060394287109375 +93671 -0.2841796875 +93672 0.13665771484375 +93673 -0.18359375 +93674 0.170135498046875 +93675 -0.098388671875 +93676 0.16552734375 +93677 -0.0291748046875 +93678 0.15728759765625 +93679 0.043182373046875 +93680 0.150787353515625 +93681 0.11798095703125 +93682 0.12200927734375 +93683 0.17449951171875 +93684 0.080108642578125 +93685 0.214935302734375 +93686 0.05126953125 +93687 0.253509521484375 +93688 0.062896728515625 +93689 0.3060302734375 +93690 0.09271240234375 +93691 0.35528564453125 +93692 0.092987060546875 +93693 0.367706298828125 +93694 0.07855224609375 +93695 0.353179931640625 +93696 0.06427001953125 +93697 0.322418212890625 +93698 0.0347900390625 +93699 0.2666015625 +93700 -0.01171875 +93701 0.18695068359375 +93702 -0.056060791015625 +93703 0.099700927734375 +93704 -0.055511474609375 +93705 0.0379638671875 +93706 -0.010467529296875 +93707 0.004974365234375 +93708 0.02508544921875 +93709 -0.033477783203125 +93710 0.025665283203125 +93711 -0.09185791015625 +93712 0.017333984375 +93713 -0.148834228515625 +93714 0.00189208984375 +93715 -0.200592041015625 +93716 -0.03173828125 +93717 -0.252960205078125 +93718 -0.071502685546875 +93719 -0.296295166015625 +93720 -0.13543701171875 +93721 -0.34271240234375 +93722 -0.219970703125 +93723 -0.390045166015625 +93724 -0.300506591796875 +93725 -0.42205810546875 +93726 -0.376312255859375 +93727 -0.43994140625 +93728 -0.416107177734375 +93729 -0.423980712890625 +93730 -0.371124267578125 +93731 -0.342681884765625 +93732 -0.242279052734375 +93733 -0.199554443359375 +93734 -0.069732666015625 +93735 -0.025726318359375 +93736 0.125640869140625 +93737 0.161285400390625 +93738 0.31268310546875 +93739 0.337005615234375 +93740 0.45501708984375 +93741 0.47369384765625 +93742 0.554779052734375 +93743 0.571044921875 +93744 0.61065673828125 +93745 0.626922607421875 +93746 0.610931396484375 +93747 0.632537841796875 +93748 0.531463623046875 +93749 0.571044921875 +93750 0.3883056640625 +93751 0.45428466796875 +93752 0.23468017578125 +93753 0.320709228515625 +93754 0.095245361328125 +93755 0.189300537109375 +93756 -0.00396728515625 +93757 0.080322265625 +93758 -0.04852294921875 +93759 0.00616455078125 +93760 -0.055145263671875 +93761 -0.042388916015625 +93762 -0.0758056640625 +93763 -0.09930419921875 +93764 -0.138702392578125 +93765 -0.182037353515625 +93766 -0.209197998046875 +93767 -0.26434326171875 +93768 -0.289031982421875 +93769 -0.345794677734375 +93770 -0.37884521484375 +93771 -0.4256591796875 +93772 -0.456329345703125 +93773 -0.48760986328125 +93774 -0.51641845703125 +93775 -0.527984619140625 +93776 -0.519287109375 +93777 -0.519256591796875 +93778 -0.458251953125 +93779 -0.45758056640625 +93780 -0.384796142578125 +93781 -0.38031005859375 +93782 -0.323699951171875 +93783 -0.306365966796875 +93784 -0.269287109375 +93785 -0.233642578125 +93786 -0.1951904296875 +93787 -0.14569091796875 +93788 -0.100006103515625 +93789 -0.04351806640625 +93790 -0.01055908203125 +93791 0.052154541015625 +93792 0.1033935546875 +93793 0.1607666015625 +93794 0.24908447265625 +93795 0.28594970703125 +93796 0.373199462890625 +93797 0.3892822265625 +93798 0.45806884765625 +93799 0.45770263671875 +93800 0.511474609375 +93801 0.496337890625 +93802 0.565399169921875 +93803 0.527740478515625 +93804 0.61138916015625 +93805 0.546600341796875 +93806 0.5897216796875 +93807 0.51202392578125 +93808 0.4906005859375 +93809 0.41839599609375 +93810 0.33148193359375 +93811 0.279388427734375 +93812 0.147796630859375 +93813 0.121368408203125 +93814 -0.01873779296875 +93815 -0.0247802734375 +93816 -0.140289306640625 +93817 -0.137939453125 +93818 -0.191986083984375 +93819 -0.19921875 +93820 -0.184295654296875 +93821 -0.214691162109375 +93822 -0.161834716796875 +93823 -0.21453857421875 +93824 -0.166595458984375 +93825 -0.227447509765625 +93826 -0.19390869140625 +93827 -0.24981689453125 +93828 -0.22442626953125 +93829 -0.268096923828125 +93830 -0.279754638671875 +93831 -0.29779052734375 +93832 -0.3389892578125 +93833 -0.32489013671875 +93834 -0.3543701171875 +93835 -0.31695556640625 +93836 -0.348175048828125 +93837 -0.290679931640625 +93838 -0.32598876953125 +93839 -0.25128173828125 +93840 -0.2581787109375 +93841 -0.17938232421875 +93842 -0.139801025390625 +93843 -0.072845458984375 +93844 0.014617919921875 +93845 0.056915283203125 +93846 0.144378662109375 +93847 0.166229248046875 +93848 0.221038818359375 +93849 0.23431396484375 +93850 0.27069091796875 +93851 0.27874755859375 +93852 0.294036865234375 +93853 0.29962158203125 +93854 0.311767578125 +93855 0.31134033203125 +93856 0.339141845703125 +93857 0.324798583984375 +93858 0.360260009765625 +93859 0.329437255859375 +93860 0.360504150390625 +93861 0.315704345703125 +93862 0.308380126953125 +93863 0.261962890625 +93864 0.18170166015625 +93865 0.153350830078125 +93866 0.0047607421875 +93867 0.00823974609375 +93868 -0.17559814453125 +93869 -0.138946533203125 +93870 -0.3143310546875 +93871 -0.25518798828125 +93872 -0.36785888671875 +93873 -0.308563232421875 +93874 -0.36248779296875 +93875 -0.317047119140625 +93876 -0.343536376953125 +93877 -0.31231689453125 +93878 -0.3018798828125 +93879 -0.287506103515625 +93880 -0.231414794921875 +93881 -0.23809814453125 +93882 -0.117645263671875 +93883 -0.153839111328125 +93884 0.007049560546875 +93885 -0.058074951171875 +93886 0.087982177734375 +93887 0.009735107421875 +93888 0.13946533203125 +93889 0.059173583984375 +93890 0.17425537109375 +93891 0.09857177734375 +93892 0.188201904296875 +93893 0.12408447265625 +93894 0.171234130859375 +93895 0.127685546875 +93896 0.118438720703125 +93897 0.105010986328125 +93898 0.05706787109375 +93899 0.074676513671875 +93900 -0.010711669921875 +93901 0.03753662109375 +93902 -0.0914306640625 +93903 -0.0115966796875 +93904 -0.162322998046875 +93905 -0.056884765625 +93906 -0.194549560546875 +93907 -0.0780029296875 +93908 -0.1492919921875 +93909 -0.04730224609375 +93910 -0.02166748046875 +93911 0.038848876953125 +93912 0.124053955078125 +93913 0.13507080078125 +93914 0.211151123046875 +93915 0.18719482421875 +93916 0.240447998046875 +93917 0.196441650390625 +93918 0.242218017578125 +93919 0.18505859375 +93920 0.2257080078125 +93921 0.160369873046875 +93922 0.194366455078125 +93923 0.125518798828125 +93924 0.115509033203125 +93925 0.057891845703125 +93926 0.0128173828125 +93927 -0.024993896484375 +93928 -0.053802490234375 +93929 -0.080047607421875 +93930 -0.110626220703125 +93931 -0.1256103515625 +93932 -0.199493408203125 +93933 -0.1912841796875 +93934 -0.29437255859375 +93935 -0.258453369140625 +93936 -0.33221435546875 +93937 -0.2823486328125 +93938 -0.27972412109375 +93939 -0.239532470703125 +93940 -0.185333251953125 +93941 -0.164825439453125 +93942 -0.128204345703125 +93943 -0.115081787109375 +93944 -0.115692138671875 +93945 -0.096038818359375 +93946 -0.116455078125 +93947 -0.085968017578125 +93948 -0.105926513671875 +93949 -0.0679931640625 +93950 -0.053955078125 +93951 -0.021209716796875 +93952 0.048797607421875 +93953 0.06072998046875 +93954 0.157318115234375 +93955 0.145050048828125 +93956 0.212005615234375 +93957 0.1878662109375 +93958 0.218475341796875 +93959 0.193328857421875 +93960 0.23724365234375 +93961 0.206451416015625 +93962 0.30535888671875 +93963 0.254913330078125 +93964 0.38128662109375 +93965 0.30792236328125 +93966 0.404449462890625 +93967 0.320587158203125 +93968 0.3944091796875 +93969 0.3077392578125 +93970 0.3885498046875 +93971 0.297454833984375 +93972 0.362640380859375 +93973 0.272064208984375 +93974 0.27362060546875 +93975 0.1998291015625 +93976 0.11712646484375 +93977 0.07781982421875 +93978 -0.054901123046875 +93979 -0.0550537109375 +93980 -0.19085693359375 +93981 -0.160125732421875 +93982 -0.28570556640625 +93983 -0.2335205078125 +93984 -0.339263916015625 +93985 -0.274993896484375 +93986 -0.3775634765625 +93987 -0.3038330078125 +93988 -0.445709228515625 +93989 -0.353607177734375 +93990 -0.535064697265625 +93991 -0.417999267578125 +93992 -0.629058837890625 +93993 -0.48480224609375 +93994 -0.697601318359375 +93995 -0.531829833984375 +93996 -0.70391845703125 +93997 -0.531951904296875 +93998 -0.6424560546875 +93999 -0.4813232421875 +94000 -0.491241455078125 +94001 -0.3638916015625 +94002 -0.265716552734375 +94003 -0.19140625 +94004 -0.023712158203125 +94005 -0.007110595703125 +94006 0.201751708984375 +94007 0.1641845703125 +94008 0.375823974609375 +94009 0.296356201171875 +94010 0.485076904296875 +94011 0.37933349609375 +94012 0.56884765625 +94013 0.442291259765625 +94014 0.634765625 +94015 0.49090576171875 +94016 0.63763427734375 +94017 0.491607666015625 +94018 0.5660400390625 +94019 0.436004638671875 +94020 0.4720458984375 +94021 0.36297607421875 +94022 0.40692138671875 +94023 0.31085205078125 +94024 0.3778076171875 +94025 0.285186767578125 +94026 0.376953125 +94027 0.280426025390625 +94028 0.371978759765625 +94029 0.272705078125 +94030 0.313140869140625 +94031 0.225250244140625 +94032 0.184417724609375 +94033 0.1263427734375 +94034 0.011199951171875 +94035 -0.004974365234375 +94036 -0.171051025390625 +94037 -0.1422119140625 +94038 -0.33740234375 +94039 -0.266754150390625 +94040 -0.47198486328125 +94041 -0.36676025390625 +94042 -0.560394287109375 +94043 -0.431549072265625 +94044 -0.58056640625 +94045 -0.444793701171875 +94046 -0.54754638671875 +94047 -0.417816162109375 +94048 -0.508575439453125 +94049 -0.385894775390625 +94050 -0.459503173828125 +94051 -0.34613037109375 +94052 -0.394378662109375 +94053 -0.294281005859375 +94054 -0.35260009765625 +94055 -0.259857177734375 +94056 -0.31170654296875 +94057 -0.226287841796875 +94058 -0.197418212890625 +94059 -0.13848876953125 +94060 -0.007965087890625 +94061 0.004669189453125 +94062 0.207489013671875 +94063 0.16650390625 +94064 0.409210205078125 +94065 0.3173828125 +94066 0.57208251953125 +94067 0.4385986328125 +94068 0.66595458984375 +94069 0.507781982421875 +94070 0.65875244140625 +94071 0.5010986328125 +94072 0.56744384765625 +94073 0.4312744140625 +94074 0.431396484375 +94075 0.327728271484375 +94076 0.29443359375 +94077 0.22320556640625 +94078 0.182464599609375 +94079 0.137115478515625 +94080 0.06365966796875 +94081 0.045928955078125 +94082 -0.075958251953125 +94083 -0.060577392578125 +94084 -0.189422607421875 +94085 -0.147308349609375 +94086 -0.271942138671875 +94087 -0.2105712890625 +94088 -0.342529296875 +94089 -0.264434814453125 +94090 -0.364166259765625 +94091 -0.281341552734375 +94092 -0.327239990234375 +94093 -0.25408935546875 +94094 -0.2769775390625 +94095 -0.21630859375 +94096 -0.253692626953125 +94097 -0.19805908203125 +94098 -0.24365234375 +94099 -0.189178466796875 +94100 -0.1983642578125 +94101 -0.1536865234375 +94102 -0.116241455078125 +94103 -0.09051513671875 +94104 -0.036834716796875 +94105 -0.0291748046875 +94106 0.034881591796875 +94107 0.026458740234375 +94108 0.09124755859375 +94109 0.070587158203125 +94110 0.10888671875 +94111 0.085723876953125 +94112 0.125518798828125 +94113 0.09979248046875 +94114 0.15771484375 +94115 0.125030517578125 +94116 0.17828369140625 +94117 0.141143798828125 +94118 0.17108154296875 +94119 0.1361083984375 +94120 0.129974365234375 +94121 0.105377197265625 +94122 0.082427978515625 +94123 0.069366455078125 +94124 0.027679443359375 +94125 0.027587890625 +94126 -0.065643310546875 +94127 -0.043243408203125 +94128 -0.15936279296875 +94129 -0.114593505859375 +94130 -0.21307373046875 +94131 -0.15631103515625 +94132 -0.234649658203125 +94133 -0.1741943359375 +94134 -0.2001953125 +94135 -0.150360107421875 +94136 -0.119171142578125 +94137 -0.09173583984375 +94138 -0.024749755859375 +94139 -0.02294921875 +94140 0.085784912109375 +94141 0.058135986328125 +94142 0.178131103515625 +94143 0.12603759765625 +94144 0.215576171875 +94145 0.153472900390625 +94146 0.211456298828125 +94147 0.150360107421875 +94148 0.17523193359375 +94149 0.123748779296875 +94150 0.128753662109375 +94151 0.08984375 +94152 0.1019287109375 +94153 0.07086181640625 +94154 0.0743408203125 +94155 0.051605224609375 +94156 0.04327392578125 +94157 0.0299072265625 +94158 0.038177490234375 +94159 0.027618408203125 +94160 0.076263427734375 +94161 0.057464599609375 +94162 0.14105224609375 +94163 0.107086181640625 +94164 0.186431884765625 +94165 0.142120361328125 +94166 0.188812255859375 +94167 0.144927978515625 +94168 0.1390380859375 +94169 0.108642578125 +94170 0.041778564453125 +94171 0.0367431640625 +94172 -0.079437255859375 +94173 -0.05328369140625 +94174 -0.219390869140625 +94175 -0.157562255859375 +94176 -0.367828369140625 +94177 -0.2684326171875 +94178 -0.494873046875 +94179 -0.3636474609375 +94180 -0.556243896484375 +94181 -0.41021728515625 +94182 -0.508697509765625 +94183 -0.37591552734375 +94184 -0.3756103515625 +94185 -0.278045654296875 +94186 -0.218902587890625 +94187 -0.162628173828125 +94188 -0.063751220703125 +94189 -0.04833984375 +94190 0.091552734375 +94191 0.06610107421875 +94192 0.23602294921875 +94193 0.172607421875 +94194 0.342987060546875 +94195 0.25140380859375 +94196 0.39520263671875 +94197 0.289703369140625 +94198 0.389373779296875 +94199 0.28509521484375 +94200 0.324249267578125 +94201 0.23663330078125 +94202 0.224090576171875 +94203 0.162353515625 +94204 0.124267578125 +94205 0.088531494140625 +94206 0.037078857421875 +94207 0.0242919921875 +94208 -0.010101318359375 +94209 -0.00958251953125 +94210 -0.019439697265625 +94211 -0.01495361328125 +94212 -0.022796630859375 +94213 -0.0162353515625 +94214 -0.001556396484375 +94215 0.00115966796875 +94216 0.056304931640625 +94217 0.046661376953125 +94218 0.106719970703125 +94219 0.086181640625 +94220 0.096893310546875 +94221 0.078826904296875 +94222 0.042694091796875 +94223 0.036956787109375 +94224 -0.018035888671875 +94225 -0.01007080078125 +94226 -0.07586669921875 +94227 -0.054931640625 +94228 -0.11944580078125 +94229 -0.088836669921875 +94230 -0.15972900390625 +94231 -0.12030029296875 +94232 -0.202606201171875 +94233 -0.15386962890625 +94234 -0.24859619140625 +94235 -0.18994140625 +94236 -0.30517578125 +94237 -0.234283447265625 +94238 -0.36212158203125 +94239 -0.27899169921875 +94240 -0.39141845703125 +94241 -0.302337646484375 +94242 -0.35528564453125 +94243 -0.274932861328125 +94244 -0.249969482421875 +94245 -0.19384765625 +94246 -0.092864990234375 +94247 -0.07257080078125 +94248 0.08905029296875 +94249 0.0679931640625 +94250 0.2352294921875 +94251 0.180877685546875 +94252 0.318817138671875 +94253 0.24530029296875 +94254 0.358642578125 +94255 0.27587890625 +94256 0.347747802734375 +94257 0.267242431640625 +94258 0.28564453125 +94259 0.219024658203125 +94260 0.223175048828125 +94261 0.170684814453125 +94262 0.196746826171875 +94263 0.150421142578125 +94264 0.179840087890625 +94265 0.137664794921875 +94266 0.155548095703125 +94267 0.119293212890625 +94268 0.151214599609375 +94269 0.116485595703125 +94270 0.156951904296875 +94271 0.121551513671875 +94272 0.13177490234375 +94273 0.10260009765625 +94274 0.100799560546875 +94275 0.0791015625 +94276 0.087127685546875 +94277 0.068939208984375 +94278 0.05487060546875 +94279 0.044281005859375 +94280 -0.009002685546875 +94281 -0.0050048828125 +94282 -0.10400390625 +94283 -0.07855224609375 +94284 -0.229400634765625 +94285 -0.175811767578125 +94286 -0.35552978515625 +94287 -0.27374267578125 +94288 -0.441925048828125 +94289 -0.3409423828125 +94290 -0.473846435546875 +94291 -0.365997314453125 +94292 -0.464813232421875 +94293 -0.359344482421875 +94294 -0.419097900390625 +94295 -0.32427978515625 +94296 -0.334320068359375 +94297 -0.2589111328125 +94298 -0.227935791015625 +94299 -0.1767578125 +94300 -0.12347412109375 +94301 -0.0960693359375 +94302 -0.02764892578125 +94303 -0.022064208984375 +94304 0.077667236328125 +94305 0.059356689453125 +94306 0.2132568359375 +94307 0.164337158203125 +94308 0.38885498046875 +94309 0.3004150390625 +94310 0.582794189453125 +94311 0.4508056640625 +94312 0.734039306640625 +94313 0.568115234375 +94314 0.800140380859375 +94315 0.61944580078125 +94316 0.7783203125 +94317 0.60260009765625 +94318 0.6651611328125 +94319 0.51495361328125 +94320 0.45965576171875 +94321 0.355712890625 +94322 0.199188232421875 +94323 0.15386962890625 +94324 -0.050689697265625 +94325 -0.039703369140625 +94326 -0.23297119140625 +94327 -0.180816650390625 +94328 -0.33013916015625 +94329 -0.255889892578125 +94330 -0.368408203125 +94331 -0.2852783203125 +94332 -0.378936767578125 +94333 -0.293182373046875 +94334 -0.376983642578125 +94335 -0.291473388671875 +94336 -0.37969970703125 +94337 -0.29345703125 +94338 -0.391510009765625 +94339 -0.30255126953125 +94340 -0.385345458984375 +94341 -0.297760009765625 +94342 -0.3419189453125 +94343 -0.264129638671875 +94344 -0.28289794921875 +94345 -0.218475341796875 +94346 -0.251617431640625 +94347 -0.19439697265625 +94348 -0.266143798828125 +94349 -0.205902099609375 +94350 -0.273345947265625 +94351 -0.211761474609375 +94352 -0.216796875 +94353 -0.16815185546875 +94354 -0.128265380859375 +94355 -0.099700927734375 +94356 -0.068145751953125 +94357 -0.053253173828125 +94358 -0.0430908203125 +94359 -0.033966064453125 +94360 -0.024444580078125 +94361 -0.019622802734375 +94362 0.020721435546875 +94363 0.015350341796875 +94364 0.124481201171875 +94365 0.095855712890625 +94366 0.25787353515625 +94367 0.199371337890625 +94368 0.379119873046875 +94369 0.293487548828125 +94370 0.47991943359375 +94371 0.371795654296875 +94372 0.5281982421875 +94373 0.40936279296875 +94374 0.511138916015625 +94375 0.396240234375 +94376 0.456207275390625 +94377 0.353729248046875 +94378 0.407470703125 +94379 0.3160400390625 +94380 0.383758544921875 +94381 0.29779052734375 +94382 0.35687255859375 +94383 0.277069091796875 +94384 0.31182861328125 +94385 0.24224853515625 +94386 0.250885009765625 +94387 0.195037841796875 +94388 0.1654052734375 +94389 0.128753662109375 +94390 0.035247802734375 +94391 0.02777099609375 +94392 -0.142059326171875 +94393 -0.109832763671875 +94394 -0.33563232421875 +94395 -0.26007080078125 +94396 -0.5345458984375 +94397 -0.414459228515625 +94398 -0.72186279296875 +94399 -0.559814453125 +94400 -0.836669921875 +94401 -0.64892578125 +94402 -0.8326416015625 +94403 -0.64581298828125 +94404 -0.7296142578125 +94405 -0.56591796875 +94406 -0.582550048828125 +94407 -0.451873779296875 +94408 -0.440093994140625 +94409 -0.341400146484375 +94410 -0.324310302734375 +94411 -0.251617431640625 +94412 -0.20147705078125 +94413 -0.1563720703125 +94414 -0.044647216796875 +94415 -0.03472900390625 +94416 0.103973388671875 +94417 0.08056640625 +94418 0.202392578125 +94419 0.15692138671875 +94420 0.264495849609375 +94421 0.205078125 +94422 0.338897705078125 +94423 0.2628173828125 +94424 0.443817138671875 +94425 0.34423828125 +94426 0.545074462890625 +94427 0.422821044921875 +94428 0.6173095703125 +94429 0.478851318359375 +94430 0.6524658203125 +94431 0.506103515625 +94432 0.66339111328125 +94433 0.514556884765625 +94434 0.6561279296875 +94435 0.5089111328125 +94436 0.606781005859375 +94437 0.470611572265625 +94438 0.501190185546875 +94439 0.388671875 +94440 0.352783203125 +94441 0.273529052734375 +94442 0.176544189453125 +94443 0.13677978515625 +94444 -0.034820556640625 +94445 -0.027191162109375 +94446 -0.258209228515625 +94447 -0.200439453125 +94448 -0.44244384765625 +94449 -0.343292236328125 +94450 -0.5753173828125 +94451 -0.446258544921875 +94452 -0.65203857421875 +94453 -0.505645751953125 +94454 -0.641632080078125 +94455 -0.4974365234375 +94456 -0.562164306640625 +94457 -0.4356689453125 +94458 -0.458038330078125 +94459 -0.35479736328125 +94460 -0.350555419921875 +94461 -0.271331787109375 +94462 -0.260528564453125 +94463 -0.201446533203125 +94464 -0.192108154296875 +94465 -0.1485595703125 +94466 -0.141937255859375 +94467 -0.110107421875 +94468 -0.1021728515625 +94469 -0.0797119140625 +94470 -0.062896728515625 +94471 -0.049530029296875 +94472 -0.011932373046875 +94473 -0.00982666015625 +94474 0.062835693359375 +94475 0.049102783203125 +94476 0.148712158203125 +94477 0.11700439453125 +94478 0.241729736328125 +94479 0.190704345703125 +94480 0.34912109375 +94481 0.276123046875 +94482 0.457305908203125 +94483 0.362396240234375 +94484 0.54388427734375 +94485 0.431488037109375 +94486 0.5728759765625 +94487 0.45440673828125 +94488 0.506591796875 +94489 0.400726318359375 +94490 0.351226806640625 +94491 0.275482177734375 +94492 0.146514892578125 +94493 0.110748291015625 +94494 -0.05523681640625 +94495 -0.051239013671875 +94496 -0.21624755859375 +94497 -0.17999267578125 +94498 -0.334930419921875 +94499 -0.2742919921875 +94500 -0.402984619140625 +94501 -0.3275146484375 +94502 -0.4412841796875 +94503 -0.35662841796875 +94504 -0.49578857421875 +94505 -0.39886474609375 +94506 -0.5601806640625 +94507 -0.449188232421875 +94508 -0.600738525390625 +94509 -0.480499267578125 +94510 -0.584228515625 +94511 -0.46600341796875 +94512 -0.47930908203125 +94513 -0.380401611328125 +94514 -0.27935791015625 +94515 -0.218414306640625 +94516 -0.0089111328125 +94517 9.1552734375e-05 +94518 0.268798828125 +94519 0.22406005859375 +94520 0.482818603515625 +94521 0.396209716796875 +94522 0.60369873046875 +94523 0.4927978515625 +94524 0.650421142578125 +94525 0.529205322265625 +94526 0.66400146484375 +94527 0.5386962890625 +94528 0.6414794921875 +94529 0.5189208984375 +94530 0.572540283203125 +94531 0.461669921875 +94532 0.498138427734375 +94533 0.40008544921875 +94534 0.439453125 +94535 0.351348876953125 +94536 0.375518798828125 +94537 0.298614501953125 +94538 0.274505615234375 +94539 0.2161865234375 +94540 0.1087646484375 +94541 0.081787109375 +94542 -0.099395751953125 +94543 -0.0865478515625 +94544 -0.3182373046875 +94545 -0.26312255859375 +94546 -0.5489501953125 +94547 -0.448974609375 +94548 -0.7738037109375 +94549 -0.62982177734375 +94550 -0.86383056640625 +94551 -0.762908935546875 +94552 -0.870391845703125 +94553 -0.8214111328125 +94554 -0.86895751953125 +94555 -0.819732666015625 +94556 -0.861053466796875 +94557 -0.7685546875 +94558 -0.765869140625 +94559 -0.65399169921875 +94560 -0.5301513671875 +94561 -0.46697998046875 +94562 -0.214691162109375 +94563 -0.213348388671875 +94564 0.137359619140625 +94565 0.07208251953125 +94566 0.474822998046875 +94567 0.3477783203125 +94568 0.76239013671875 +94569 0.584991455078125 +94570 0.867462158203125 +94571 0.761932373046875 +94572 0.870361328125 +94573 0.857147216796875 +94574 0.86480712890625 +94575 0.86236572265625 +94576 0.831817626953125 +94577 0.860504150390625 +94578 0.677581787109375 +94579 0.847625732421875 +94580 0.495880126953125 +94581 0.745147705078125 +94582 0.30767822265625 +94583 0.61737060546875 +94584 0.116180419921875 +94585 0.466156005859375 +94586 -0.110748291015625 +94587 0.26593017578125 +94588 -0.381805419921875 +94589 0.011138916015625 +94590 -0.6572265625 +94591 -0.263580322265625 +94592 -0.857421875 +94593 -0.509765625 +94594 -0.870391845703125 +94595 -0.692718505859375 +94596 -0.870391845703125 +94597 -0.806640625 +94598 -0.86444091796875 +94599 -0.8565673828125 +94600 -0.85723876953125 +94601 -0.86181640625 +94602 -0.790008544921875 +94603 -0.863433837890625 +94604 -0.62847900390625 +94605 -0.856658935546875 +94606 -0.3956298828125 +94607 -0.732574462890625 +94608 -0.126708984375 +94609 -0.537872314453125 +94610 0.150115966796875 +94611 -0.312347412109375 +94612 0.424041748046875 +94613 -0.0655517578125 +94614 0.670623779296875 +94615 0.1806640625 +94616 0.854522705078125 +94617 0.394927978515625 +94618 0.866485595703125 +94619 0.562896728515625 +94620 0.86920166015625 +94621 0.672088623046875 +94622 0.8653564453125 +94623 0.737152099609375 +94624 0.857147216796875 +94625 0.7689208984375 +94626 0.766845703125 +94627 0.7650146484375 +94628 0.628509521484375 +94629 0.729583740234375 +94630 0.462127685546875 +94631 0.657196044921875 +94632 0.297210693359375 +94633 0.5687255859375 +94634 0.14862060546875 +94635 0.474212646484375 +94636 -0.00537109375 +94637 0.35528564453125 +94638 -0.15753173828125 +94639 0.218048095703125 +94640 -0.31304931640625 +94641 0.059661865234375 +94642 -0.48876953125 +94643 -0.13116455078125 +94644 -0.6416015625 +94645 -0.316436767578125 +94646 -0.751373291015625 +94647 -0.47613525390625 +94648 -0.84619140625 +94649 -0.62884521484375 +94650 -0.861297607421875 +94651 -0.76263427734375 +94652 -0.863250732421875 +94653 -0.850677490234375 +94654 -0.856597900390625 +94655 -0.855926513671875 +94656 -0.7498779296875 +94657 -0.8228759765625 +94658 -0.624542236328125 +94659 -0.76361083984375 +94660 -0.47808837890625 +94661 -0.671966552734375 +94662 -0.253387451171875 +94663 -0.500732421875 +94664 0.003692626953125 +94665 -0.286865234375 +94666 0.2257080078125 +94667 -0.085662841796875 +94668 0.427154541015625 +94669 0.112884521484375 +94670 0.643218994140625 +94671 0.334869384765625 +94672 0.855926513671875 +94673 0.572418212890625 +94674 0.870361328125 +94675 0.778656005859375 +94676 0.870361328125 +94677 0.86090087890625 +94678 0.862762451171875 +94679 0.868438720703125 +94680 0.79669189453125 +94681 0.8685302734375 +94682 0.595794677734375 +94683 0.860321044921875 +94684 0.362152099609375 +94685 0.780853271484375 +94686 0.1270751953125 +94687 0.624053955078125 +94688 -0.086944580078125 +94689 0.45489501953125 +94690 -0.2784423828125 +94691 0.275177001953125 +94692 -0.484832763671875 +94693 0.056854248046875 +94694 -0.729583740234375 +94695 -0.215423583984375 +94696 -0.86688232421875 +94697 -0.500640869140625 +94698 -0.870391845703125 +94699 -0.747528076171875 +94700 -0.86859130859375 +94701 -0.865142822265625 +94702 -0.86279296875 +94703 -0.870391845703125 +94704 -0.817962646484375 +94705 -0.868621826171875 +94706 -0.6116943359375 +94707 -0.8564453125 +94708 -0.3128662109375 +94709 -0.663543701171875 +94710 0.039398193359375 +94711 -0.38836669921875 +94712 0.422821044921875 +94713 -0.064788818359375 +94714 0.805145263671875 +94715 0.279632568359375 +94716 0.870361328125 +94717 0.590606689453125 +94718 0.870361328125 +94719 0.823974609375 +94720 0.860015869140625 +94721 0.867462158203125 +94722 0.727935791015625 +94723 0.870361328125 +94724 0.48114013671875 +94725 0.86407470703125 +94726 0.2059326171875 +94727 0.827606201171875 +94728 -0.06103515625 +94729 0.6807861328125 +94730 -0.29913330078125 +94731 0.516021728515625 +94732 -0.516204833984375 +94733 0.325958251953125 +94734 -0.7252197265625 +94735 0.10137939453125 +94736 -0.85980224609375 +94737 -0.134368896484375 +94738 -0.870391845703125 +94739 -0.351348876953125 +94740 -0.870391845703125 +94741 -0.525054931640625 +94742 -0.858062744140625 +94743 -0.6162109375 +94744 -0.673004150390625 +94745 -0.624114990234375 +94746 -0.42694091796875 +94747 -0.596649169921875 +94748 -0.2100830078125 +94749 -0.575653076171875 +94750 -0.0362548828125 +94751 -0.564422607421875 +94752 0.10943603515625 +94753 -0.54388427734375 +94754 0.23516845703125 +94755 -0.50250244140625 +94756 0.373687744140625 +94757 -0.410369873046875 +94758 0.517791748046875 +94759 -0.273345947265625 +94760 0.602783203125 +94761 -0.147796630859375 +94762 0.635711669921875 +94763 -0.031829833984375 +94764 0.655181884765625 +94765 0.10113525390625 +94766 0.65948486328125 +94767 0.242462158203125 +94768 0.651275634765625 +94769 0.38629150390625 +94770 0.61846923828125 +94771 0.51385498046875 +94772 0.53753662109375 +94773 0.596832275390625 +94774 0.404144287109375 +94775 0.623504638671875 +94776 0.22186279296875 +94777 0.58966064453125 +94778 0.003997802734375 +94779 0.500518798828125 +94780 -0.22100830078125 +94781 0.375579833984375 +94782 -0.42449951171875 +94783 0.23626708984375 +94784 -0.579833984375 +94785 0.104156494140625 +94786 -0.641876220703125 +94787 0.0181884765625 +94788 -0.6177978515625 +94789 -0.024810791015625 +94790 -0.575531005859375 +94791 -0.07763671875 +94792 -0.526336669921875 +94793 -0.14422607421875 +94794 -0.42645263671875 +94795 -0.181396484375 +94796 -0.2581787109375 +94797 -0.167266845703125 +94798 -0.068695068359375 +94799 -0.13433837890625 +94800 0.09222412109375 +94801 -0.1175537109375 +94802 0.232147216796875 +94803 -0.104339599609375 +94804 0.3509521484375 +94805 -0.089508056640625 +94806 0.410064697265625 +94807 -0.101409912109375 +94808 0.372955322265625 +94809 -0.16802978515625 +94810 0.2554931640625 +94811 -0.27484130859375 +94812 0.10711669921875 +94813 -0.380706787109375 +94814 -0.052886962890625 +94815 -0.471221923828125 +94816 -0.186279296875 +94817 -0.517333984375 +94818 -0.23291015625 +94819 -0.4727783203125 +94820 -0.209442138671875 +94821 -0.356658935546875 +94822 -0.174163818359375 +94823 -0.223541259765625 +94824 -0.126739501953125 +94825 -0.0789794921875 +94826 -0.048126220703125 +94827 0.087249755859375 +94828 0.0426025390625 +94829 0.253814697265625 +94830 0.10748291015625 +94831 0.384185791015625 +94832 0.1409912109375 +94833 0.470001220703125 +94834 0.19708251953125 +94835 0.553955078125 +94836 0.273651123046875 +94837 0.63287353515625 +94838 0.31768798828125 +94839 0.66204833984375 +94840 0.341094970703125 +94841 0.652587890625 +94842 0.368011474609375 +94843 0.626953125 +94844 0.37249755859375 +94845 0.5665283203125 +94846 0.30072021484375 +94847 0.4300537109375 +94848 0.1517333984375 +94849 0.221221923828125 +94850 -0.01470947265625 +94851 -0.004974365234375 +94852 -0.1883544921875 +94853 -0.235137939453125 +94854 -0.372711181640625 +94855 -0.467681884765625 +94856 -0.51397705078125 +94857 -0.65338134765625 +94858 -0.57177734375 +94859 -0.75494384765625 +94860 -0.53948974609375 +94861 -0.764312744140625 +94862 -0.43511962890625 +94863 -0.69512939453125 +94864 -0.2962646484375 +94865 -0.5784912109375 +94866 -0.161102294921875 +94867 -0.446990966796875 +94868 -0.0435791015625 +94869 -0.313812255859375 +94870 0.060394287109375 +94871 -0.177886962890625 +94872 0.13665771484375 +94873 -0.054168701171875 +94874 0.170135498046875 +94875 0.041107177734375 +94876 0.16552734375 +94877 0.108062744140625 +94878 0.15728759765625 +94879 0.171600341796875 +94880 0.150787353515625 +94881 0.232421875 +94882 0.12200927734375 +94883 0.266876220703125 +94884 0.080108642578125 +94885 0.2796630859375 +94886 0.05126953125 +94887 0.290435791015625 +94888 0.062896728515625 +94889 0.32073974609375 +94890 0.09271240234375 +94891 0.351104736328125 +94892 0.092987060546875 +94893 0.341644287109375 +94894 0.07855224609375 +94895 0.30572509765625 +94896 0.06427001953125 +94897 0.257537841796875 +94898 0.0347900390625 +94899 0.1865234375 +94900 -0.01171875 +94901 0.093902587890625 +94902 -0.056060791015625 +94903 -0.001007080078125 +94904 -0.055511474609375 +94905 -0.059051513671875 +94906 -0.010467529296875 +94907 -0.077362060546875 +94908 0.02508544921875 +94909 -0.0982666015625 +94910 0.025665283203125 +94911 -0.140533447265625 +94912 0.017333984375 +94913 -0.18017578125 +94914 0.00189208984375 +94915 -0.214202880859375 +94916 -0.03173828125 +94917 -0.251129150390625 +94918 -0.071502685546875 +94919 -0.280731201171875 +94920 -0.13543701171875 +94921 -0.3187255859375 +94922 -0.219970703125 +94923 -0.36328125 +94924 -0.300506591796875 +94925 -0.3955078125 +94926 -0.376312255859375 +94927 -0.416961669921875 +94928 -0.416107177734375 +94929 -0.40386962890625 +94930 -0.371124267578125 +94931 -0.31793212890625 +94932 -0.242279052734375 +94933 -0.162567138671875 +94934 -0.069732666015625 +94935 0.02587890625 +94936 0.125640869140625 +94937 0.22760009765625 +94938 0.31268310546875 +94939 0.41455078125 +94940 0.45501708984375 +94941 0.5548095703125 +94942 0.554779052734375 +94943 0.649322509765625 +94944 0.61065673828125 +94945 0.696685791015625 +94946 0.610931396484375 +94947 0.68731689453125 +94948 0.531463623046875 +94949 0.601776123046875 +94950 0.3883056640625 +94951 0.454803466796875 +94952 0.23468017578125 +94953 0.29278564453125 +94954 0.095245361328125 +94955 0.138458251953125 +94956 -0.00396728515625 +94957 0.015777587890625 +94958 -0.04852294921875 +94959 -0.060882568359375 +94960 -0.055145263671875 +94961 -0.103424072265625 +94962 -0.0758056640625 +94963 -0.15362548828125 +94964 -0.138702392578125 +94965 -0.23345947265625 +94966 -0.209197998046875 +94967 -0.312530517578125 +94968 -0.289031982421875 +94969 -0.391387939453125 +94970 -0.37884521484375 +94971 -0.47021484375 +94972 -0.456329345703125 +94973 -0.5302734375 +94974 -0.51641845703125 +94975 -0.56787109375 +94976 -0.519287109375 +94977 -0.55029296875 +94978 -0.458251953125 +94979 -0.47320556640625 +94980 -0.384796142578125 +94981 -0.381805419921875 +94982 -0.323699951171875 +94983 -0.298797607421875 +94984 -0.269287109375 +94985 -0.221099853515625 +94986 -0.1951904296875 +94987 -0.128021240234375 +94988 -0.100006103515625 +94989 -0.01995849609375 +94990 -0.01055908203125 +94991 0.078857421875 +94992 0.1033935546875 +94993 0.193023681640625 +94994 0.24908447265625 +94995 0.327911376953125 +94996 0.373199462890625 +94997 0.43780517578125 +94998 0.45806884765625 +94999 0.50762939453125 +95000 0.511474609375 +95001 0.5443115234375 +95002 0.565399169921875 +95003 0.575714111328125 +95004 0.61138916015625 +95005 0.59564208984375 +95006 0.5897216796875 +95007 0.554473876953125 +95008 0.4906005859375 +95009 0.4451904296875 +95010 0.33148193359375 +95011 0.28411865234375 +95012 0.147796630859375 +95013 0.102752685546875 +95014 -0.01873779296875 +95015 -0.062042236328125 +95016 -0.140289306640625 +95017 -0.1854248046875 +95018 -0.191986083984375 +95019 -0.2452392578125 +95020 -0.184295654296875 +95021 -0.2496337890625 +95022 -0.161834716796875 +95023 -0.236083984375 +95024 -0.166595458984375 +95025 -0.240142822265625 +95026 -0.19390869140625 +95027 -0.25799560546875 +95028 -0.22442626953125 +95029 -0.273651123046875 +95030 -0.279754638671875 +95031 -0.30615234375 +95032 -0.3389892578125 +95033 -0.338653564453125 +95034 -0.3543701171875 +95035 -0.331634521484375 +95036 -0.348175048828125 +95037 -0.305206298828125 +95038 -0.32598876953125 +95039 -0.2652587890625 +95040 -0.2581787109375 +95041 -0.18780517578125 +95042 -0.139801025390625 +95043 -0.06964111328125 +95044 0.014617919921875 +95045 0.07598876953125 +95046 0.144378662109375 +95047 0.19677734375 +95048 0.221038818359375 +95049 0.268096923828125 +95050 0.27069091796875 +95051 0.3118896484375 +95052 0.294036865234375 +95053 0.328826904296875 +95054 0.311767578125 +95055 0.3367919921875 +95056 0.339141845703125 +95057 0.349334716796875 +95058 0.360260009765625 +95059 0.3538818359375 +95060 0.360504150390625 +95061 0.338775634765625 +95062 0.308380126953125 +95063 0.277313232421875 +95064 0.18170166015625 +95065 0.15093994140625 +95066 0.0047607421875 +95067 -0.01824951171875 +95068 -0.17559814453125 +95069 -0.188720703125 +95070 -0.3143310546875 +95071 -0.320587158203125 +95072 -0.36785888671875 +95073 -0.375335693359375 +95074 -0.36248779296875 +95075 -0.37554931640625 +95076 -0.343536376953125 +95077 -0.360565185546875 +95078 -0.3018798828125 +95079 -0.322479248046875 +95080 -0.231414794921875 +95081 -0.256134033203125 +95082 -0.117645263671875 +95083 -0.149200439453125 +95084 0.007049560546875 +95085 -0.030426025390625 +95086 0.087982177734375 +95087 0.0518798828125 +95088 0.13946533203125 +95089 0.1094970703125 +95090 0.17425537109375 +95091 0.152862548828125 +95092 0.188201904296875 +95093 0.1776123046875 +95094 0.171234130859375 +95095 0.174285888671875 +95096 0.118438720703125 +95097 0.138031005859375 +95098 0.05706787109375 +95099 0.092132568359375 +95100 -0.010711669921875 +95101 0.0380859375 +95102 -0.0914306640625 +95103 -0.02996826171875 +95104 -0.162322998046875 +95105 -0.09222412109375 +95106 -0.194549560546875 +95107 -0.123443603515625 +95108 -0.1492919921875 +95109 -0.08953857421875 +95110 -0.02166748046875 +95111 0.01409912109375 +95112 0.124053955078125 +95113 0.131927490234375 +95114 0.211151123046875 +95115 0.1976318359375 +95116 0.240447998046875 +95117 0.2125244140625 +95118 0.242218017578125 +95119 0.20355224609375 +95120 0.2257080078125 +95121 0.17938232421875 +95122 0.194366455078125 +95123 0.143524169921875 +95124 0.115509033203125 +95125 0.067901611328125 +95126 0.0128173828125 +95127 -0.0264892578125 +95128 -0.053802490234375 +95129 -0.087249755859375 +95130 -0.110626220703125 +95131 -0.137176513671875 +95132 -0.199493408203125 +95133 -0.21282958984375 +95134 -0.29437255859375 +95135 -0.291656494140625 +95136 -0.33221435546875 +95137 -0.31890869140625 +95138 -0.27972412109375 +95139 -0.265960693359375 +95140 -0.185333251953125 +95141 -0.175506591796875 +95142 -0.128204345703125 +95143 -0.11700439453125 +95144 -0.115692138671875 +95145 -0.09735107421875 +95146 -0.116455078125 +95147 -0.0897216796875 +95148 -0.105926513671875 +95149 -0.0731201171875 +95150 -0.053955078125 +95151 -0.021636962890625 +95152 0.048797607421875 +95153 0.07257080078125 +95154 0.157318115234375 +95155 0.1700439453125 +95156 0.212005615234375 +95157 0.21868896484375 +95158 0.218475341796875 +95159 0.223419189453125 +95160 0.23724365234375 +95161 0.23712158203125 +95162 0.30535888671875 +95163 0.29229736328125 +95164 0.38128662109375 +95165 0.35296630859375 +95166 0.404449462890625 +95167 0.36663818359375 +95168 0.3944091796875 +95169 0.35076904296875 +95170 0.3885498046875 +95171 0.338348388671875 +95172 0.362640380859375 +95173 0.308685302734375 +95174 0.27362060546875 +95175 0.224609375 +95176 0.11712646484375 +95177 0.0826416015625 +95178 -0.054901123046875 +95179 -0.071624755859375 +95180 -0.19085693359375 +95181 -0.1929931640625 +95182 -0.28570556640625 +95183 -0.2769775390625 +95184 -0.339263916015625 +95185 -0.32342529296875 +95186 -0.3775634765625 +95187 -0.355072021484375 +95188 -0.445709228515625 +95189 -0.411376953125 +95190 -0.535064697265625 +95191 -0.485015869140625 +95192 -0.629058837890625 +95193 -0.56182861328125 +95194 -0.697601318359375 +95195 -0.615875244140625 +95196 -0.70391845703125 +95197 -0.615386962890625 +95198 -0.6424560546875 +95199 -0.555877685546875 +95200 -0.491241455078125 +95201 -0.41851806640625 +95202 -0.265716552734375 +95203 -0.217010498046875 +95204 -0.023712158203125 +95205 -0.0020751953125 +95206 0.201751708984375 +95207 0.197296142578125 +95208 0.375823974609375 +95209 0.350616455078125 +95210 0.485076904296875 +95211 0.446136474609375 +95212 0.56884765625 +95213 0.518157958984375 +95214 0.634765625 +95215 0.57342529296875 +95216 0.63763427734375 +95217 0.572723388671875 +95218 0.5660400390625 +95219 0.50628662109375 +95220 0.4720458984375 +95221 0.419708251953125 +95222 0.40692138671875 +95223 0.35797119140625 +95224 0.3778076171875 +95225 0.327606201171875 +95226 0.376953125 +95227 0.322113037109375 +95228 0.371978759765625 +95229 0.31353759765625 +95230 0.313140869140625 +95231 0.25872802734375 +95232 0.184417724609375 +95233 0.143646240234375 +95234 0.011199951171875 +95235 -0.009674072265625 +95236 -0.171051025390625 +95237 -0.1700439453125 +95238 -0.33740234375 +95239 -0.31524658203125 +95240 -0.47198486328125 +95241 -0.4312744140625 +95242 -0.560394287109375 +95243 -0.505462646484375 +95244 -0.58056640625 +95245 -0.518218994140625 +95246 -0.54754638671875 +95247 -0.483428955078125 +95248 -0.508575439453125 +95249 -0.444091796875 +95250 -0.459503173828125 +95251 -0.396636962890625 +95252 -0.394378662109375 +95253 -0.3358154296875 +95254 -0.35260009765625 +95255 -0.297332763671875 +95256 -0.31170654296875 +95257 -0.260833740234375 +95258 -0.197418212890625 +95259 -0.159149169921875 +95260 -0.007965087890625 +95261 0.00946044921875 +95262 0.207489013671875 +95263 0.20074462890625 +95264 0.409210205078125 +95265 0.37896728515625 +95266 0.57208251953125 +95267 0.52166748046875 +95268 0.66595458984375 +95269 0.60186767578125 +95270 0.65875244140625 +95271 0.5908203125 +95272 0.56744384765625 +95273 0.504119873046875 +95274 0.431396484375 +95275 0.3775634765625 +95276 0.29443359375 +95277 0.2509765625 +95278 0.182464599609375 +95279 0.14788818359375 +95280 0.06365966796875 +95281 0.03961181640625 +95282 -0.075958251953125 +95283 -0.086456298828125 +95284 -0.189422607421875 +95285 -0.18792724609375 +95286 -0.271942138671875 +95287 -0.26055908203125 +95288 -0.342529296875 +95289 -0.3216552734375 +95290 -0.364166259765625 +95291 -0.337921142578125 +95292 -0.327239990234375 +95293 -0.3009033203125 +95294 -0.2769775390625 +95295 -0.251678466796875 +95296 -0.253692626953125 +95297 -0.22686767578125 +95298 -0.24365234375 +95299 -0.214263916015625 +95300 -0.1983642578125 +95301 -0.17022705078125 +95302 -0.116241455078125 +95303 -0.093505859375 +95304 -0.036834716796875 +95305 -0.019927978515625 +95306 0.034881591796875 +95307 0.0458984375 +95308 0.09124755859375 +95309 0.0970458984375 +95310 0.10888671875 +95311 0.1124267578125 +95312 0.125518798828125 +95313 0.126129150390625 +95314 0.15771484375 +95315 0.15325927734375 +95316 0.17828369140625 +95317 0.1693115234375 +95318 0.17108154296875 +95319 0.15985107421875 +95320 0.129974365234375 +95321 0.11956787109375 +95322 0.082427978515625 +95323 0.073455810546875 +95324 0.027679443359375 +95325 0.02099609375 +95326 -0.065643310546875 +95327 -0.066009521484375 +95328 -0.15936279296875 +95329 -0.15289306640625 +95330 -0.21307373046875 +95331 -0.20306396484375 +95332 -0.234649658203125 +95333 -0.22357177734375 +95334 -0.2001953125 +95335 -0.192779541015625 +95336 -0.119171142578125 +95337 -0.119232177734375 +95338 -0.024749755859375 +95339 -0.032958984375 +95340 0.085784912109375 +95341 0.06842041015625 +95342 0.178131103515625 +95343 0.15380859375 +95344 0.215576171875 +95345 0.189910888671875 +95346 0.211456298828125 +95347 0.188629150390625 +95348 0.17523193359375 +95349 0.15838623046875 +95350 0.128753662109375 +95351 0.118804931640625 +95352 0.1019287109375 +95353 0.0968017578125 +95354 0.0743408203125 +95355 0.07379150390625 +95356 0.04327392578125 +95357 0.047210693359375 +95358 0.038177490234375 +95359 0.043609619140625 +95360 0.076263427734375 +95361 0.078521728515625 +95362 0.14105224609375 +95363 0.137054443359375 +95364 0.186431884765625 +95365 0.177520751953125 +95366 0.188812255859375 +95367 0.17864990234375 +95368 0.1390380859375 +95369 0.1322021484375 +95370 0.041778564453125 +95371 0.04254150390625 +95372 -0.079437255859375 +95373 -0.0689697265625 +95374 -0.219390869140625 +95375 -0.197509765625 +95376 -0.367828369140625 +95377 -0.33367919921875 +95378 -0.494873046875 +95379 -0.450408935546875 +95380 -0.556243896484375 +95381 -0.507537841796875 +95382 -0.508697509765625 +95383 -0.465911865234375 +95384 -0.3756103515625 +95385 -0.3465576171875 +95386 -0.218902587890625 +95387 -0.2054443359375 +95388 -0.063751220703125 +95389 -0.0653076171875 +95390 0.091552734375 +95391 0.07537841796875 +95392 0.23602294921875 +95393 0.2066650390625 +95394 0.342987060546875 +95395 0.30438232421875 +95396 0.39520263671875 +95397 0.352874755859375 +95398 0.389373779296875 +95399 0.34912109375 +95400 0.324249267578125 +95401 0.291900634765625 +95402 0.224090576171875 +95403 0.203033447265625 +95404 0.124267578125 +95405 0.114410400390625 +95406 0.037078857421875 +95407 0.037017822265625 +95408 -0.010101318359375 +95409 -0.00445556640625 +95410 -0.019439697265625 +95411 -0.011993408203125 +95412 -0.022796630859375 +95413 -0.014434814453125 +95414 -0.001556396484375 +95415 0.004974365234375 +95416 0.056304931640625 +95417 0.05712890625 +95418 0.106719970703125 +95419 0.102203369140625 +95420 0.096893310546875 +95421 0.092529296875 +95422 0.042694091796875 +95423 0.04248046875 +95424 -0.018035888671875 +95425 -0.013671875 +95426 -0.07586669921875 +95427 -0.067291259765625 +95428 -0.11944580078125 +95429 -0.108062744140625 +95430 -0.15972900390625 +95431 -0.145843505859375 +95432 -0.202606201171875 +95433 -0.18585205078125 +95434 -0.24859619140625 +95435 -0.228485107421875 +95436 -0.30517578125 +95437 -0.280426025390625 +95438 -0.36212158203125 +95439 -0.332427978515625 +95440 -0.39141845703125 +95441 -0.359130859375 +95442 -0.35528564453125 +95443 -0.32635498046875 +95444 -0.249969482421875 +95445 -0.230743408203125 +95446 -0.092864990234375 +95447 -0.088104248046875 +95448 0.08905029296875 +95449 0.077178955078125 +95450 0.2352294921875 +95451 0.2103271484375 +95452 0.318817138671875 +95453 0.287017822265625 +95454 0.358642578125 +95455 0.32415771484375 +95456 0.347747802734375 +95457 0.3154296875 +95458 0.28564453125 +95459 0.260345458984375 +95460 0.223175048828125 +95461 0.204803466796875 +95462 0.196746826171875 +95463 0.181640625 +95464 0.179840087890625 +95465 0.1668701171875 +95466 0.155548095703125 +95467 0.145172119140625 +95468 0.151214599609375 +95469 0.141265869140625 +95470 0.156951904296875 +95471 0.146209716796875 +95472 0.13177490234375 +95473 0.122955322265625 +95474 0.100799560546875 +95475 0.094268798828125 +95476 0.087127685546875 +95477 0.0810546875 +95478 0.05487060546875 +95479 0.050933837890625 +95480 -0.009002685546875 +95481 -0.007781982421875 +95482 -0.10400390625 +95483 -0.0946044921875 +95484 -0.229400634765625 +95485 -0.2088623046875 +95486 -0.35552978515625 +95487 -0.32366943359375 +95488 -0.441925048828125 +95489 -0.402587890625 +95490 -0.473846435546875 +95491 -0.4326171875 +95492 -0.464813232421875 +95493 -0.426055908203125 +95494 -0.419097900390625 +95495 -0.386260986328125 +95496 -0.334320068359375 +95497 -0.31048583984375 +95498 -0.227935791015625 +95499 -0.214569091796875 +95500 -0.12347412109375 +95501 -0.120208740234375 +95502 -0.02764892578125 +95503 -0.03338623046875 +95504 0.077667236328125 +95505 0.063079833984375 +95506 0.2132568359375 +95507 0.188720703125 +95508 0.38885498046875 +95509 0.352691650390625 +95510 0.582794189453125 +95511 0.53466796875 +95512 0.734039306640625 +95513 0.677398681640625 +95514 0.800140380859375 +95515 0.7410888671875 +95516 0.7783203125 +95517 0.72296142578125 +95518 0.6651611328125 +95519 0.619659423828125 +95520 0.45965576171875 +95521 0.4300537109375 +95522 0.199188232421875 +95523 0.18896484375 +95524 -0.050689697265625 +95525 -0.04241943359375 +95526 -0.23297119140625 +95527 -0.21087646484375 +95528 -0.33013916015625 +95529 -0.300140380859375 +95530 -0.368408203125 +95531 -0.33477783203125 +95532 -0.378936767578125 +95533 -0.344024658203125 +95534 -0.376983642578125 +95535 -0.342193603515625 +95536 -0.37969970703125 +95537 -0.345306396484375 +95538 -0.391510009765625 +95539 -0.357452392578125 +95540 -0.385345458984375 +95541 -0.353271484375 +95542 -0.3419189453125 +95543 -0.314605712890625 +95544 -0.28289794921875 +95545 -0.2615966796875 +95546 -0.251617431640625 +95547 -0.234649658203125 +95548 -0.266143798828125 +95549 -0.25054931640625 +95550 -0.273345947265625 +95551 -0.25946044921875 +95552 -0.216796875 +95553 -0.20843505859375 +95554 -0.128265380859375 +95555 -0.127105712890625 +95556 -0.068145751953125 +95557 -0.07196044921875 +95558 -0.0430908203125 +95559 -0.049163818359375 +95560 -0.024444580078125 +95561 -0.0318603515625 +95562 0.020721435546875 +95563 0.010772705078125 +95564 0.124481201171875 +95565 0.108734130859375 +95566 0.25787353515625 +95567 0.23480224609375 +95568 0.379119873046875 +95569 0.349822998046875 +95570 0.47991943359375 +95571 0.445953369140625 +95572 0.5281982421875 +95573 0.4930419921875 +95574 0.511138916015625 +95575 0.47900390625 +95576 0.456207275390625 +95577 0.429443359375 +95578 0.407470703125 +95579 0.385498046875 +95580 0.383758544921875 +95581 0.36468505859375 +95582 0.35687255859375 +95583 0.340576171875 +95584 0.31182861328125 +95585 0.299102783203125 +95586 0.250885009765625 +95587 0.2423095703125 +95588 0.1654052734375 +95589 0.162139892578125 +95590 0.035247802734375 +95591 0.03973388671875 +95592 -0.142059326171875 +95593 -0.127166748046875 +95594 -0.33563232421875 +95595 -0.3095703125 +95596 -0.5345458984375 +95597 -0.4971923828125 +95598 -0.72186279296875 +95599 -0.674072265625 +95600 -0.836669921875 +95601 -0.783111572265625 +95602 -0.8326416015625 +95603 -0.7808837890625 +95604 -0.7296142578125 +95605 -0.685882568359375 +95606 -0.582550048828125 +95607 -0.549468994140625 +95608 -0.440093994140625 +95609 -0.417083740234375 +95610 -0.324310302734375 +95611 -0.30938720703125 +95612 -0.20147705078125 +95613 -0.194732666015625 +95614 -0.044647216796875 +95615 -0.04791259765625 +95616 0.103973388671875 +95617 0.091583251953125 +95618 0.202392578125 +95619 0.18438720703125 +95620 0.264495849609375 +95621 0.243438720703125 +95622 0.338897705078125 +95623 0.314239501953125 +95624 0.443817138671875 +95625 0.413726806640625 +95626 0.545074462890625 +95627 0.509857177734375 +95628 0.6173095703125 +95629 0.57879638671875 +95630 0.6524658203125 +95631 0.612945556640625 +95632 0.66339111328125 +95633 0.624237060546875 +95634 0.6561279296875 +95635 0.6182861328125 +95636 0.606781005859375 +95637 0.572662353515625 +95638 0.501190185546875 +95639 0.47412109375 +95640 0.352783203125 +95641 0.335174560546875 +95642 0.176544189453125 +95643 0.169921875 +95644 -0.034820556640625 +95645 -0.0284423828125 +95646 -0.258209228515625 +95647 -0.23828125 +95648 -0.44244384765625 +95649 -0.411651611328125 +95650 -0.5753173828125 +95651 -0.53704833984375 +95652 -0.65203857421875 +95653 -0.60992431640625 +95654 -0.641632080078125 +95655 -0.601226806640625 +95656 -0.562164306640625 +95657 -0.52783203125 +95658 -0.458038330078125 +95659 -0.431243896484375 +95660 -0.350555419921875 +95661 -0.331329345703125 +95662 -0.260528564453125 +95663 -0.24755859375 +95664 -0.192108154296875 +95665 -0.183807373046875 +95666 -0.141937255859375 +95667 -0.13690185546875 +95668 -0.1021728515625 +95669 -0.099517822265625 +95670 -0.062896728515625 +95671 -0.0623779296875 +95672 -0.011932373046875 +95673 -0.01409912109375 +95674 0.062835693359375 +95675 0.056610107421875 +95676 0.148712158203125 +95677 0.137847900390625 +95678 0.241729736328125 +95679 0.225799560546875 +95680 0.34912109375 +95681 0.32720947265625 +95682 0.457305908203125 +95683 0.4293212890625 +95684 0.54388427734375 +95685 0.5111083984375 +95686 0.5728759765625 +95687 0.53887939453125 +95688 0.506591796875 +95689 0.477294921875 +95690 0.351226806640625 +95691 0.3321533203125 +95692 0.146514892578125 +95693 0.140625 +95694 -0.05523681640625 +95695 -0.048309326171875 +95696 -0.21624755859375 +95697 -0.19927978515625 +95698 -0.334930419921875 +95699 -0.310760498046875 +95700 -0.402984619140625 +95701 -0.375 +95702 -0.4412841796875 +95703 -0.4114990234375 +95704 -0.49578857421875 +95705 -0.463226318359375 +95706 -0.5601806640625 +95707 -0.52423095703125 +95708 -0.600738525390625 +95709 -0.56292724609375 +95710 -0.584228515625 +95711 -0.548126220703125 +95712 -0.47930908203125 +95713 -0.450469970703125 +95714 -0.27935791015625 +95715 -0.263763427734375 +95716 -0.0089111328125 +95717 -0.01092529296875 +95718 0.268798828125 +95719 0.24884033203125 +95720 0.482818603515625 +95721 0.44915771484375 +95722 0.60369873046875 +95723 0.562469482421875 +95724 0.650421142578125 +95725 0.60650634765625 +95726 0.66400146484375 +95727 0.61962890625 +95728 0.6414794921875 +95729 0.599029541015625 +95730 0.572540283203125 +95731 0.5350341796875 +95732 0.498138427734375 +95733 0.465972900390625 +95734 0.439453125 +95735 0.41162109375 +95736 0.375518798828125 +95737 0.352325439453125 +95738 0.274505615234375 +95739 0.258270263671875 +95740 0.1087646484375 +95741 0.103546142578125 +95742 -0.099395751953125 +95743 -0.09100341796875 +95744 -0.3182373046875 +95745 -0.296142578125 +95746 -0.5489501953125 +95747 -0.51385498046875 +95748 -0.7738037109375 +95749 -0.727325439453125 +95750 -0.86383056640625 +95751 -0.857879638671875 +95752 -0.870391845703125 +95753 -0.8656005859375 +95754 -0.86895751953125 +95755 -0.865631103515625 +95756 -0.861053466796875 +95757 -0.859344482421875 +95758 -0.765869140625 +95759 -0.7667236328125 +95760 -0.5301513671875 +95761 -0.548583984375 +95762 -0.214691162109375 +95763 -0.251129150390625 +95764 0.137359619140625 +95765 0.084320068359375 +95766 0.474822998046875 +95767 0.408416748046875 +95768 0.76239013671875 +95769 0.68707275390625 +95770 0.867462158203125 +95771 0.85882568359375 +95772 0.870361328125 +95773 0.870361328125 +95774 0.86480712890625 +95775 0.870361328125 +95776 0.831817626953125 +95777 0.862701416015625 +95778 0.677581787109375 +95779 0.816070556640625 +95780 0.495880126953125 +95781 0.665863037109375 +95782 0.30767822265625 +95783 0.498504638671875 +95784 0.116180419921875 +95785 0.316619873046875 +95786 -0.110748291015625 +95787 0.089202880859375 +95788 -0.381805419921875 +95789 -0.19140625 +95790 -0.6572265625 +95791 -0.485443115234375 +95792 -0.857421875 +95793 -0.737091064453125 +95794 -0.870391845703125 +95795 -0.860260009765625 +95796 -0.870391845703125 +95797 -0.869537353515625 +95798 -0.86444091796875 +95799 -0.870391845703125 +95800 -0.85723876953125 +95801 -0.86932373046875 +95802 -0.790008544921875 +95803 -0.864837646484375 +95804 -0.62847900390625 +95805 -0.826568603515625 +95806 -0.3956298828125 +95807 -0.622161865234375 +95808 -0.126708984375 +95809 -0.369171142578125 +95810 0.150115966796875 +95811 -0.0948486328125 +95812 0.424041748046875 +95813 0.1895751953125 +95814 0.670623779296875 +95815 0.459014892578125 +95816 0.854522705078125 +95817 0.677703857421875 +95818 0.866485595703125 +95819 0.830902099609375 +95820 0.86920166015625 +95821 0.86016845703125 +95822 0.8653564453125 +95823 0.862213134765625 +95824 0.857147216796875 +95825 0.85986328125 +95826 0.766845703125 +95827 0.84197998046875 +95828 0.628509521484375 +95829 0.748138427734375 +95830 0.462127685546875 +95831 0.61834716796875 +95832 0.297210693359375 +95833 0.479736328125 +95834 0.14862060546875 +95835 0.3458251953125 +95836 -0.00537109375 +95837 0.19537353515625 +95838 -0.15753173828125 +95839 0.0357666015625 +95840 -0.31304931640625 +95841 -0.136993408203125 +95842 -0.48876953125 +95843 -0.337738037109375 +95844 -0.6416015625 +95845 -0.5228271484375 +95846 -0.751373291015625 +95847 -0.67047119140625 +95848 -0.84619140625 +95849 -0.805572509765625 +95850 -0.861297607421875 +95851 -0.86126708984375 +95852 -0.863250732421875 +95853 -0.8675537109375 +95854 -0.856597900390625 +95855 -0.86492919921875 +95856 -0.7498779296875 +95857 -0.854949951171875 +95858 -0.624542236328125 +95859 -0.757598876953125 +95860 -0.47808837890625 +95861 -0.627227783203125 +95862 -0.253387451171875 +95863 -0.41180419921875 +95864 0.003692626953125 +95865 -0.155853271484375 +95866 0.2257080078125 +95867 0.07464599609375 +95868 0.427154541015625 +95869 0.2926025390625 +95870 0.643218994140625 +95871 0.5306396484375 +95872 0.855926513671875 +95873 0.78106689453125 +95874 0.870361328125 +95875 0.869232177734375 +95876 0.870361328125 +95877 0.870361328125 +95878 0.862762451171875 +95879 0.8638916015625 +95880 0.79669189453125 +95881 0.817047119140625 +95882 0.595794677734375 +95883 0.6256103515625 +95884 0.362152099609375 +95885 0.39971923828125 +95886 0.1270751953125 +95887 0.169769287109375 +95888 -0.086944580078125 +95889 -0.042266845703125 +95890 -0.2784423828125 +95891 -0.23468017578125 +95892 -0.484832763671875 +95893 -0.443206787109375 +95894 -0.729583740234375 +95895 -0.6900634765625 +95896 -0.86688232421875 +95897 -0.862884521484375 +95898 -0.870391845703125 +95899 -0.870391845703125 +95900 -0.86859130859375 +95901 -0.870391845703125 +95902 -0.86279296875 +95903 -0.8662109375 +95904 -0.817962646484375 +95905 -0.8553466796875 +95906 -0.6116943359375 +95907 -0.667633056640625 +95908 -0.3128662109375 +95909 -0.379302978515625 +95910 0.039398193359375 +95911 -0.0350341796875 +95912 0.422821044921875 +95913 0.34332275390625 +95914 0.805145263671875 +95915 0.723968505859375 +95916 0.870361328125 +95917 0.870361328125 +95918 0.870361328125 +95919 0.870361328125 +95920 0.860015869140625 +95921 0.86016845703125 +95922 0.727935791015625 +95923 0.7315673828125 +95924 0.48114013671875 +95925 0.48797607421875 +95926 0.2059326171875 +95927 0.215789794921875 +95928 -0.06103515625 +95929 -0.04913330078125 +95930 -0.29913330078125 +95931 -0.2864990234375 +95932 -0.516204833984375 +95933 -0.503509521484375 +95934 -0.7252197265625 +95935 -0.712310791015625 +95936 -0.85980224609375 +95937 -0.8583984375 +95938 -0.870391845703125 +95939 -0.870391845703125 +95940 -0.870391845703125 +95941 -0.870391845703125 +95942 -0.858062744140625 +95943 -0.8582763671875 +95944 -0.673004150390625 +95945 -0.6783447265625 +95946 -0.42694091796875 +95947 -0.435394287109375 +95948 -0.2100830078125 +95949 -0.219696044921875 +95950 -0.0362548828125 +95951 -0.044921875 +95952 0.10943603515625 +95953 0.10296630859375 +95954 0.23516845703125 +95955 0.23150634765625 +95956 0.373687744140625 +95957 0.37200927734375 +95958 0.517791748046875 +95959 0.51715087890625 +95960 0.602783203125 +95961 0.604034423828125 +95962 0.635711669921875 +95963 0.639312744140625 +95964 0.655181884765625 +95965 0.66015625 +95966 0.65948486328125 +95967 0.66485595703125 +95968 0.651275634765625 +95969 0.655975341796875 +95970 0.61846923828125 +95971 0.62188720703125 +95972 0.53753662109375 +95973 0.540008544921875 +95974 0.404144287109375 +95975 0.4063720703125 +95976 0.22186279296875 +95977 0.224700927734375 +95978 0.003997802734375 +95979 0.008209228515625 +95980 -0.22100830078125 +95981 -0.21527099609375 +95982 -0.42449951171875 +95983 -0.417724609375 +95984 -0.579833984375 +95985 -0.57305908203125 +95986 -0.641876220703125 +95987 -0.637298583984375 +95988 -0.6177978515625 +95989 -0.617156982421875 +95990 -0.575531005859375 +95991 -0.578277587890625 +95992 -0.526336669921875 +95993 -0.531463623046875 +95994 -0.42645263671875 +95995 -0.43438720703125 +95996 -0.2581787109375 +95997 -0.2698974609375 +95998 -0.068695068359375 +95999 -0.083831787109375 +96000 0.09222412109375 +96001 0.075958251953125 +96002 0.232147216796875 +96003 0.2171630859375 +96004 0.3509521484375 +96005 0.3388671875 +96006 0.410064697265625 +96007 0.401947021484375 +96008 0.372955322265625 +96009 0.369384765625 +96010 0.2554931640625 +96011 0.256622314453125 +96012 0.10711669921875 +96013 0.11273193359375 +96014 -0.052886962890625 +96015 -0.0433349609375 +96016 -0.186279296875 +96017 -0.173553466796875 +96018 -0.23291015625 +96019 -0.21795654296875 +96020 -0.209442138671875 +96021 -0.19329833984375 +96022 -0.174163818359375 +96023 -0.15789794921875 +96024 -0.126739501953125 +96025 -0.111358642578125 +96026 -0.048126220703125 +96027 -0.0345458984375 +96028 0.0426025390625 +96029 0.0535888671875 +96030 0.10748291015625 +96031 0.11529541015625 +96032 0.1409912109375 +96033 0.145233154296875 +96034 0.19708251953125 +96035 0.197601318359375 +96036 0.273651123046875 +96037 0.270538330078125 +96038 0.31768798828125 +96039 0.311248779296875 +96040 0.341094970703125 +96041 0.331787109375 +96042 0.368011474609375 +96043 0.356414794921875 +96044 0.37249755859375 +96045 0.359283447265625 +96046 0.30072021484375 +96047 0.286651611328125 +96048 0.1517333984375 +96049 0.1375732421875 +96050 -0.01470947265625 +96051 -0.0281982421875 +96052 -0.1883544921875 +96053 -0.200439453125 +96054 -0.372711181640625 +96055 -0.38275146484375 +96056 -0.51397705078125 +96057 -0.521484375 +96058 -0.57177734375 +96059 -0.576416015625 +96060 -0.53948974609375 +96061 -0.541107177734375 +96062 -0.43511962890625 +96063 -0.4337158203125 +96064 -0.2962646484375 +96065 -0.292022705078125 +96066 -0.161102294921875 +96067 -0.154327392578125 +96068 -0.0435791015625 +96069 -0.034698486328125 +96070 0.060394287109375 +96071 0.070831298828125 +96072 0.13665771484375 +96073 0.148040771484375 +96074 0.170135498046875 +96075 0.18182373046875 +96076 0.16552734375 +96077 0.1768798828125 +96078 0.15728759765625 +96079 0.16766357421875 +96080 0.150787353515625 +96081 0.15966796875 +96082 0.12200927734375 +96083 0.12896728515625 +96084 0.080108642578125 +96085 0.084808349609375 +96086 0.05126953125 +96087 0.05352783203125 +96088 0.062896728515625 +96089 0.06268310546875 +96090 0.09271240234375 +96091 0.090118408203125 +96092 0.092987060546875 +96093 0.088226318359375 +96094 0.07855224609375 +96095 0.071929931640625 +96096 0.06427001953125 +96097 0.05621337890625 +96098 0.0347900390625 +96099 0.025787353515625 +96100 -0.01171875 +96101 -0.021148681640625 +96102 -0.056060791015625 +96103 -0.06536865234375 +96104 -0.055511474609375 +96105 -0.064208984375 +96106 -0.010467529296875 +96107 -0.018096923828125 +96108 0.02508544921875 +96109 0.0189208984375 +96110 0.025665283203125 +96111 0.021270751953125 +96112 0.017333984375 +96113 0.014923095703125 +96114 0.00189208984375 +96115 0.00152587890625 +96116 -0.03173828125 +96117 -0.03009033203125 +96118 -0.071502685546875 +96119 -0.0679931640625 +96120 -0.13543701171875 +96121 -0.13031005859375 +96122 -0.219970703125 +96123 -0.21356201171875 +96124 -0.300506591796875 +96125 -0.293182373046875 +96126 -0.376312255859375 +96127 -0.368499755859375 +96128 -0.416107177734375 +96129 -0.408233642578125 +96130 -0.371124267578125 +96131 -0.363616943359375 +96132 -0.242279052734375 +96133 -0.23553466796875 +96134 -0.069732666015625 +96135 -0.0640869140625 +96136 0.125640869140625 +96137 0.129913330078125 +96138 0.31268310546875 +96139 0.31536865234375 +96140 0.45501708984375 +96141 0.456024169921875 +96142 0.554779052734375 +96143 0.554107666015625 +96144 0.61065673828125 +96145 0.6083984375 +96146 0.610931396484375 +96147 0.607269287109375 +96148 0.531463623046875 +96149 0.526641845703125 +96150 0.3883056640625 +96151 0.382598876953125 +96152 0.23468017578125 +96153 0.228424072265625 +96154 0.095245361328125 +96155 0.08880615234375 +96156 -0.00396728515625 +96157 -0.010223388671875 +96158 -0.04852294921875 +96159 -0.05426025390625 +96160 -0.055145263671875 +96161 -0.06005859375 +96162 -0.0758056640625 +96163 -0.07965087890625 +96164 -0.138702392578125 +96165 -0.14129638671875 +96166 -0.209197998046875 +96167 -0.21044921875 +96168 -0.289031982421875 +96169 -0.288909912109375 +96170 -0.37884521484375 +96171 -0.377410888671875 +96172 -0.456329345703125 +96173 -0.45367431640625 +96174 -0.51641845703125 +96175 -0.512725830078125 +96176 -0.519287109375 +96177 -0.514801025390625 +96178 -0.458251953125 +96179 -0.4532470703125 +96180 -0.384796142578125 +96181 -0.379547119140625 +96182 -0.323699951171875 +96183 -0.3184814453125 +96184 -0.269287109375 +96185 -0.264373779296875 +96186 -0.1951904296875 +96187 -0.19085693359375 +96188 -0.100006103515625 +96189 -0.096466064453125 +96190 -0.01055908203125 +96191 -0.007965087890625 +96192 0.1033935546875 +96193 0.10491943359375 +96194 0.24908447265625 +96195 0.249481201171875 +96196 0.373199462890625 +96197 0.372467041015625 +96198 0.45806884765625 +96199 0.456298828125 +96200 0.511474609375 +96201 0.5087890625 +96202 0.565399169921875 +96203 0.561981201171875 +96204 0.61138916015625 +96205 0.607452392578125 +96206 0.5897216796875 +96207 0.58551025390625 +96208 0.4906005859375 +96209 0.486328125 +96210 0.33148193359375 +96211 0.327392578125 +96212 0.147796630859375 +96213 0.14410400390625 +96214 -0.01873779296875 +96215 -0.0218505859375 +96216 -0.140289306640625 +96217 -0.142669677734375 +96218 -0.191986083984375 +96219 -0.193511962890625 +96220 -0.184295654296875 +96221 -0.184906005859375 +96222 -0.161834716796875 +96223 -0.1614990234375 +96224 -0.166595458984375 +96225 -0.16534423828125 +96226 -0.19390869140625 +96227 -0.19183349609375 +96228 -0.22442626953125 +96229 -0.2216796875 +96230 -0.279754638671875 +96231 -0.2764892578125 +96232 -0.3389892578125 +96233 -0.33538818359375 +96234 -0.3543701171875 +96235 -0.35064697265625 +96236 -0.348175048828125 +96237 -0.34454345703125 +96238 -0.32598876953125 +96239 -0.322662353515625 +96240 -0.2581787109375 +96241 -0.255340576171875 +96242 -0.139801025390625 +96243 -0.137603759765625 +96244 0.014617919921875 +96245 0.016082763671875 +96246 0.144378662109375 +96247 0.145050048828125 +96248 0.221038818359375 +96249 0.220916748046875 +96250 0.27069091796875 +96251 0.269805908203125 +96252 0.294036865234375 +96253 0.29248046875 +96254 0.311767578125 +96255 0.309661865234375 +96256 0.33905029296875 +96257 0.33660888671875 +96258 0.359588623046875 +96259 0.357452392578125 +96260 0.35888671875 +96261 0.357574462890625 +96262 0.306671142578125 +96263 0.30548095703125 +96264 0.18170166015625 +96265 0.178985595703125 +96266 0.00775146484375 +96267 0.00238037109375 +96268 -0.16961669921875 +96269 -0.177520751953125 +96270 -0.306640625 +96271 -0.315704345703125 +96272 -0.3609619140625 +96273 -0.368621826171875 +96274 -0.357879638671875 +96275 -0.36260986328125 +96276 -0.341156005859375 +96277 -0.343017578125 +96278 -0.3018798828125 +96279 -0.30078125 +96280 -0.234100341796875 +96281 -0.22979736328125 +96282 -0.123809814453125 +96283 -0.1156005859375 +96284 -0.002349853515625 +96285 0.0093994140625 +96286 0.0772705078125 +96287 0.09051513671875 +96288 0.1287841796875 +96289 0.14202880859375 +96290 0.164459228515625 +96291 0.176727294921875 +96292 0.18011474609375 +96293 0.1904296875 +96294 0.1658935546875 +96295 0.173095703125 +96296 0.116943359375 +96297 0.119842529296875 +96298 0.05950927734375 +96299 0.057952880859375 +96300 -0.004425048828125 +96301 -0.0103759765625 +96302 -0.081298828125 +96303 -0.091644287109375 +96304 -0.149078369140625 +96305 -0.163055419921875 +96306 -0.179901123046875 +96307 -0.19573974609375 +96308 -0.13623046875 +96309 -0.15087890625 +96310 -0.0133056640625 +96311 -0.0235595703125 +96312 0.126739501953125 +96313 0.121978759765625 +96314 0.209686279296875 +96315 0.209014892578125 +96316 0.2364501953125 +96317 0.238372802734375 +96318 0.23638916015625 +96319 0.24029541015625 +96320 0.218597412109375 +96321 0.22406005859375 +96322 0.186492919921875 +96323 0.193084716796875 +96324 0.108551025390625 +96325 0.114654541015625 +96326 0.00775146484375 +96327 0.012420654296875 +96328 -0.057830810546875 +96329 -0.053741455078125 +96330 -0.113555908203125 +96331 -0.110107421875 +96332 -0.199951171875 +96333 -0.198577880859375 +96334 -0.29180908203125 +96335 -0.293121337890625 +96336 -0.32806396484375 +96337 -0.3306884765625 +96338 -0.27655029296875 +96339 -0.27801513671875 +96340 -0.184173583984375 +96341 -0.18353271484375 +96342 -0.12762451171875 +96343 -0.12640380859375 +96344 -0.11407470703125 +96345 -0.113983154296875 +96346 -0.11328125 +96347 -0.11492919921875 +96348 -0.1015625 +96349 -0.104644775390625 +96350 -0.049835205078125 +96351 -0.052978515625 +96352 0.05084228515625 +96353 0.0494384765625 +96354 0.156890869140625 +96355 0.157623291015625 +96356 0.2105712890625 +96357 0.21197509765625 +96358 0.217254638671875 +96359 0.218109130859375 +96360 0.23553466796875 +96361 0.236572265625 +96362 0.30126953125 +96363 0.304443359375 +96364 0.374237060546875 +96365 0.380157470703125 +96366 0.395843505859375 +96367 0.403167724609375 +96368 0.38507080078125 +96369 0.393035888671875 +96370 0.378173828125 +96371 0.38714599609375 +96372 0.351806640625 +96373 0.361297607421875 +96374 0.264373779296875 +96375 0.27239990234375 +96376 0.1116943359375 +96377 0.1160888671875 +96378 -0.055877685546875 +96379 -0.055694580078125 +96380 -0.188323974609375 +96381 -0.19134521484375 +96382 -0.28076171875 +96383 -0.285858154296875 +96384 -0.3330078125 +96385 -0.339080810546875 +96386 -0.370208740234375 +96387 -0.3770751953125 +96388 -0.43603515625 +96389 -0.4449462890625 +96390 -0.52215576171875 +96391 -0.534088134765625 +96392 -0.612548828125 +96393 -0.6279296875 +96394 -0.678131103515625 +96395 -0.696380615234375 +96396 -0.683349609375 +96397 -0.70269775390625 +96398 -0.62286376953125 +96399 -0.64129638671875 +96400 -0.4754638671875 +96401 -0.490203857421875 +96402 -0.25616455078125 +96403 -0.264862060546875 +96404 -0.02099609375 +96405 -0.0230712890625 +96406 0.198028564453125 +96407 0.2021484375 +96408 0.36712646484375 +96409 0.3759765625 +96410 0.473297119140625 +96411 0.4849853515625 +96412 0.554595947265625 +96413 0.568511962890625 +96414 0.618408203125 +96415 0.63421630859375 +96416 0.6209716796875 +96417 0.636932373046875 +96418 0.551239013671875 +96419 0.565216064453125 +96420 0.45965576171875 +96421 0.47113037109375 +96422 0.3958740234375 +96423 0.40594482421875 +96424 0.36688232421875 +96425 0.376800537109375 +96426 0.36517333984375 +96427 0.375946044921875 +96428 0.3594970703125 +96429 0.37103271484375 +96430 0.3017578125 +96431 0.31231689453125 +96432 0.17645263671875 +96433 0.183746337890625 +96434 0.008209228515625 +96435 0.010711669921875 +96436 -0.168609619140625 +96437 -0.17132568359375 +96438 -0.329864501953125 +96439 -0.33746337890625 +96440 -0.460174560546875 +96441 -0.471832275390625 +96442 -0.54559326171875 +96443 -0.560028076171875 +96444 -0.5648193359375 +96445 -0.58001708984375 +96446 -0.53240966796875 +96447 -0.546844482421875 +96448 -0.494140625 +96449 -0.507781982421875 +96450 -0.44598388671875 +96451 -0.458648681640625 +96452 -0.38226318359375 +96453 -0.393524169921875 +96454 -0.34112548828125 +96455 -0.351806640625 +96456 -0.30084228515625 +96457 -0.311004638671875 +96458 -0.1895751953125 +96459 -0.19683837890625 +96460 -0.005645751953125 +96461 -0.007537841796875 +96462 0.203338623046875 +96463 0.207733154296875 +96464 0.398834228515625 +96465 0.409271240234375 +96466 0.556549072265625 +96467 0.57196044921875 +96468 0.647308349609375 +96469 0.6656494140625 +96470 0.64007568359375 +96471 0.65826416015625 +96472 0.551300048828125 +96473 0.566802978515625 +96474 0.41912841796875 +96475 0.430633544921875 +96476 0.2860107421875 +96477 0.2935791015625 +96478 0.17706298828125 +96479 0.18157958984375 +96480 0.061492919921875 +96481 0.062774658203125 +96482 -0.074188232421875 +96483 -0.076812744140625 +96484 -0.18450927734375 +96485 -0.190185546875 +96486 -0.2647705078125 +96487 -0.2725830078125 +96488 -0.3333740234375 +96489 -0.343017578125 +96490 -0.354522705078125 +96491 -0.364501953125 +96492 -0.31890869140625 +96493 -0.327423095703125 +96494 -0.270263671875 +96495 -0.277008056640625 +96496 -0.24761962890625 +96497 -0.253570556640625 +96498 -0.2376708984375 +96499 -0.243377685546875 +96500 -0.19354248046875 +96501 -0.197967529296875 +96502 -0.11370849609375 +96503 -0.115753173828125 +96504 -0.036407470703125 +96505 -0.036285400390625 +96506 0.033477783203125 +96507 0.03546142578125 +96508 0.0885009765625 +96509 0.091827392578125 +96510 0.10601806640625 +96511 0.10943603515625 +96512 0.12213134765625 +96513 0.126007080078125 +96514 0.152740478515625 +96515 0.15814208984375 +96516 0.1719970703125 +96517 0.178619384765625 +96518 0.1649169921875 +96519 0.171295166015625 +96520 0.12591552734375 +96521 0.13006591796875 +96522 0.080780029296875 +96523 0.0823974609375 +96524 0.02886962890625 +96525 0.02752685546875 +96526 -0.059173583984375 +96527 -0.06591796875 +96528 -0.147552490234375 +96529 -0.15972900390625 +96530 -0.198455810546875 +96531 -0.2135009765625 +96532 -0.219207763671875 +96533 -0.235107421875 +96534 -0.18743896484375 +96535 -0.200653076171875 +96536 -0.11199951171875 +96537 -0.119598388671875 +96538 -0.023956298828125 +96539 -0.025115966796875 +96540 0.0792236328125 +96541 0.085479736328125 +96542 0.16546630859375 +96543 0.17791748046875 +96544 0.200408935546875 +96545 0.2154541015625 +96546 0.196533203125 +96547 0.21142578125 +96548 0.16265869140625 +96549 0.17529296875 +96550 0.1192626953125 +96551 0.12890625 +96552 0.094329833984375 +96553 0.1021728515625 +96554 0.068756103515625 +96555 0.074676513671875 +96556 0.03997802734375 +96557 0.043701171875 +96558 0.0355224609375 +96559 0.038665771484375 +96560 0.071502685546875 +96561 0.0767822265625 +96562 0.1324462890625 +96563 0.141571044921875 +96564 0.175201416015625 +96565 0.186920166015625 +96566 0.17767333984375 +96567 0.189239501953125 +96568 0.131256103515625 +96569 0.139373779296875 +96570 0.04034423828125 +96571 0.042022705078125 +96572 -0.07305908203125 +96573 -0.07928466796875 +96574 -0.204071044921875 +96575 -0.219329833984375 +96576 -0.343109130859375 +96577 -0.36785888671875 +96578 -0.462188720703125 +96579 -0.4949951171875 +96580 -0.51983642578125 +96581 -0.55645751953125 +96582 -0.4755859375 +96583 -0.509002685546875 +96584 -0.351287841796875 +96585 -0.3759765625 +96586 -0.20489501953125 +96587 -0.21929931640625 +96588 -0.059967041015625 +96589 -0.06414794921875 +96590 0.085113525390625 +96591 0.091156005859375 +96592 0.2200927734375 +96593 0.23565673828125 +96594 0.32000732421875 +96595 0.3426513671875 +96596 0.368743896484375 +96597 0.3948974609375 +96598 0.36322021484375 +96599 0.38909912109375 +96600 0.302276611328125 +96601 0.324005126953125 +96602 0.208587646484375 +96603 0.223907470703125 +96604 0.115264892578125 +96605 0.1241455078125 +96606 0.0338134765625 +96607 0.037017822265625 +96608 -0.0101318359375 +96609 -0.010101318359375 +96610 -0.018646240234375 +96611 -0.019378662109375 +96612 -0.02154541015625 +96613 -0.022674560546875 +96614 -0.00140380859375 +96615 -0.001373291015625 +96616 0.053009033203125 +96617 0.0565185546875 +96618 0.10040283203125 +96619 0.10693359375 +96620 0.091400146484375 +96621 0.097076416015625 +96622 0.04083251953125 +96623 0.0428466796875 +96624 -0.015899658203125 +96625 -0.017913818359375 +96626 -0.069976806640625 +96627 -0.075775146484375 +96628 -0.11077880859375 +96629 -0.119384765625 +96630 -0.148590087890625 +96631 -0.159698486328125 +96632 -0.188873291015625 +96633 -0.202606201171875 +96634 -0.232086181640625 +96635 -0.248626708984375 +96636 -0.285186767578125 +96637 -0.305206298828125 +96638 -0.338653564453125 +96639 -0.362152099609375 +96640 -0.36627197265625 +96641 -0.391448974609375 +96642 -0.3326416015625 +96643 -0.355316162109375 +96644 -0.234222412109375 +96645 -0.25 +96646 -0.087310791015625 +96647 -0.0928955078125 +96648 0.08282470703125 +96649 0.089019775390625 +96650 0.219573974609375 +96651 0.235198974609375 +96652 0.297760009765625 +96653 0.31878662109375 +96654 0.33502197265625 +96655 0.358612060546875 +96656 0.3248291015625 +96657 0.34771728515625 +96658 0.2667236328125 +96659 0.285614013671875 +96660 0.20831298828125 +96661 0.22314453125 +96662 0.18365478515625 +96663 0.19671630859375 +96664 0.167938232421875 +96665 0.1798095703125 +96666 0.14532470703125 +96667 0.155517578125 +96668 0.141448974609375 +96669 0.15118408203125 +96670 0.147003173828125 +96671 0.15692138671875 +96672 0.12359619140625 +96673 0.131744384765625 +96674 0.0947265625 +96675 0.10076904296875 +96676 0.082000732421875 +96677 0.08709716796875 +96678 0.051849365234375 +96679 0.054840087890625 +96680 -0.007904052734375 +96681 -0.009033203125 +96682 -0.0968017578125 +96683 -0.104034423828125 +96684 -0.214202880859375 +96685 -0.22943115234375 +96686 -0.33233642578125 +96687 -0.355560302734375 +96688 -0.41326904296875 +96689 -0.44195556640625 +96690 -0.4432373046875 +96691 -0.473876953125 +96692 -0.43487548828125 +96693 -0.46484375 +96694 -0.392181396484375 +96695 -0.41912841796875 +96696 -0.31292724609375 +96697 -0.3343505859375 +96698 -0.213409423828125 +96699 -0.22796630859375 +96700 -0.115692138671875 +96701 -0.123504638671875 +96702 -0.026031494140625 +96703 -0.027679443359375 +96704 0.072540283203125 +96705 0.07763671875 +96706 0.199462890625 +96707 0.213226318359375 +96708 0.363861083984375 +96709 0.388824462890625 +96710 0.54541015625 +96711 0.582763671875 +96712 0.68701171875 +96713 0.7340087890625 +96714 0.748931884765625 +96715 0.80010986328125 +96716 0.72857666015625 +96717 0.778289794921875 +96718 0.622711181640625 +96719 0.665130615234375 +96720 0.430419921875 +96721 0.459625244140625 +96722 0.186676025390625 +96723 0.199188232421875 +96724 -0.04718017578125 +96725 -0.0506591796875 +96726 -0.2177734375 +96727 -0.23291015625 +96728 -0.3087158203125 +96729 -0.330078125 +96730 -0.344512939453125 +96731 -0.36834716796875 +96732 -0.3543701171875 +96733 -0.378875732421875 +96734 -0.3525390625 +96735 -0.376922607421875 +96736 -0.355133056640625 +96737 -0.379638671875 +96738 -0.366241455078125 +96739 -0.391448974609375 +96740 -0.36053466796875 +96741 -0.385284423828125 +96742 -0.3199462890625 +96743 -0.34185791015625 +96744 -0.2647705078125 +96745 -0.2828369140625 +96746 -0.235565185546875 +96747 -0.251556396484375 +96748 -0.24920654296875 +96749 -0.266082763671875 +96750 -0.2559814453125 +96751 -0.273284912109375 +96752 -0.20306396484375 +96753 -0.21673583984375 +96754 -0.12017822265625 +96755 -0.128204345703125 +96756 -0.063873291015625 +96757 -0.068084716796875 +96758 -0.040374755859375 +96759 -0.04302978515625 +96760 -0.02288818359375 +96761 -0.024383544921875 +96762 0.019439697265625 +96763 0.020782470703125 +96764 0.116607666015625 +96765 0.124542236328125 +96766 0.24151611328125 +96767 0.2579345703125 +96768 0.3544921875 +96769 0.379150390625 +96770 0.447967529296875 +96771 0.47991943359375 +96772 0.4932861328125 +96773 0.528167724609375 +96774 0.4786376953125 +96775 0.5111083984375 +96776 0.42877197265625 +96777 0.4561767578125 +96778 0.383544921875 +96779 0.407440185546875 +96780 0.36004638671875 +96781 0.38372802734375 +96782 0.332916259765625 +96783 0.356842041015625 +96784 0.288787841796875 +96785 0.311798095703125 +96786 0.229888916015625 +96787 0.2508544921875 +96788 0.148681640625 +96789 0.165374755859375 +96790 0.027191162109375 +96791 0.03521728515625 +96792 -0.1365966796875 +96793 -0.14208984375 +96794 -0.3145751953125 +96795 -0.335662841796875 +96796 -0.4967041015625 +96797 -0.534576416015625 +96798 -0.667572021484375 +96799 -0.721893310546875 +96800 -0.772003173828125 +96801 -0.836669921875 +96802 -0.76812744140625 +96803 -0.8326416015625 +96804 -0.6739501953125 +96805 -0.7296142578125 +96806 -0.5391845703125 +96807 -0.582550048828125 +96808 -0.407958984375 +96809 -0.440093994140625 +96810 -0.30035400390625 +96811 -0.324310302734375 +96812 -0.18609619140625 +96813 -0.20147705078125 +96814 -0.04095458984375 +96815 -0.044647216796875 +96816 0.096710205078125 +96817 0.103973388671875 +96818 0.188751220703125 +96819 0.202392578125 +96820 0.24755859375 +96821 0.264495849609375 +96822 0.31695556640625 +96823 0.338897705078125 +96824 0.41326904296875 +96825 0.443817138671875 +96826 0.505584716796875 +96827 0.545074462890625 +96828 0.5709228515625 +96829 0.6173095703125 +96830 0.60205078125 +96831 0.6524658203125 +96832 0.610626220703125 +96833 0.66339111328125 +96834 0.602203369140625 +96835 0.6561279296875 +96836 0.555267333984375 +96837 0.606781005859375 +96838 0.457183837890625 +96839 0.501190185546875 +96840 0.32025146484375 +96841 0.352783203125 +96842 0.15814208984375 +96843 0.176544189453125 +96844 -0.035552978515625 +96845 -0.034820556640625 +96846 -0.23980712890625 +96847 -0.258209228515625 +96848 -0.40826416015625 +96849 -0.44244384765625 +96850 -0.529754638671875 +96851 -0.5753173828125 +96852 -0.59991455078125 +96853 -0.65203857421875 +96854 -0.590728759765625 +96855 -0.641632080078125 +96856 -0.518524169921875 +96857 -0.562164306640625 +96858 -0.423492431640625 +96859 -0.458038330078125 +96860 -0.32489013671875 +96861 -0.350555419921875 +96862 -0.24163818359375 +96863 -0.260528564453125 +96864 -0.177642822265625 +96865 -0.192108154296875 +96866 -0.1300048828125 +96867 -0.141937255859375 +96868 -0.091766357421875 +96869 -0.1021728515625 +96870 -0.0540771484375 +96871 -0.062896728515625 +96872 -0.006011962890625 +96873 -0.011932373046875 +96874 0.063262939453125 +96875 0.062835693359375 +96876 0.142181396484375 +96877 0.148712158203125 +96878 0.227081298828125 +96879 0.241729736328125 +96880 0.324493408203125 +96881 0.34912109375 +96882 0.422119140625 +96883 0.457305908203125 +96884 0.499725341796875 +96885 0.54388427734375 +96886 0.524871826171875 +96887 0.5728759765625 +96888 0.463531494140625 +96889 0.506591796875 +96890 0.321441650390625 +96891 0.351226806640625 +96892 0.13458251953125 +96893 0.146514892578125 +96894 -0.0496826171875 +96895 -0.05523681640625 +96896 -0.19708251953125 +96897 -0.21624755859375 +96898 -0.3060302734375 +96899 -0.334930419921875 +96900 -0.368988037109375 +96901 -0.402984619140625 +96902 -0.404754638671875 +96903 -0.4412841796875 +96904 -0.454803466796875 +96905 -0.49578857421875 +96906 -0.513397216796875 +96907 -0.5601806640625 +96908 -0.550018310546875 +96909 -0.600738525390625 +96910 -0.53466796875 +96911 -0.584228515625 +96912 -0.43902587890625 +96913 -0.47930908203125 +96914 -0.2572021484375 +96915 -0.27935791015625 +96916 -0.011444091796875 +96917 -0.0089111328125 +96918 0.240997314453125 +96919 0.268798828125 +96920 0.435943603515625 +96921 0.482818603515625 +96922 0.54669189453125 +96923 0.60369873046875 +96924 0.59027099609375 +96925 0.650421142578125 +96926 0.603729248046875 +96927 0.66400146484375 +96928 0.584320068359375 +96929 0.6414794921875 +96930 0.522705078125 +96931 0.572540283203125 +96932 0.455841064453125 +96933 0.498138427734375 +96934 0.402862548828125 +96935 0.439453125 +96936 0.3448486328125 +96937 0.375518798828125 +96938 0.253021240234375 +96939 0.274505615234375 +96940 0.1024169921875 +96941 0.1087646484375 +96942 -0.086761474609375 +96943 -0.099395751953125 +96944 -0.28570556640625 +96945 -0.3182373046875 +96946 -0.495452880859375 +96947 -0.5489501953125 +96948 -0.69989013671875 +96949 -0.7738037109375 +96950 -0.851104736328125 +96951 -0.86383056640625 +96952 -0.861541748046875 +96953 -0.870391845703125 +96954 -0.861602783203125 +96955 -0.86895751953125 +96956 -0.8555908203125 +96957 -0.861053466796875 +96958 -0.738067626953125 +96959 -0.765869140625 +96960 -0.53033447265625 +96961 -0.5301513671875 +96962 -0.247589111328125 +96963 -0.214691162109375 +96964 0.071197509765625 +96965 0.137359619140625 +96966 0.379638671875 +96967 0.474822998046875 +96968 0.64556884765625 +96969 0.76239013671875 +96970 0.844512939453125 +96971 0.867462158203125 +96972 0.867828369140625 +96973 0.870361328125 +96974 0.870361328125 +96975 0.86480712890625 +96976 0.865264892578125 +96977 0.831817626953125 +96978 0.85516357421875 +96979 0.677581787109375 +96980 0.7283935546875 +96981 0.495880126953125 +96982 0.573974609375 +96983 0.30767822265625 +96984 0.4000244140625 +96985 0.116180419921875 +96986 0.177978515625 +96987 -0.110748291015625 +96988 -0.098602294921875 +96989 -0.381805419921875 +96990 -0.39166259765625 +96991 -0.6572265625 +96992 -0.647979736328125 +96993 -0.857421875 +96994 -0.829864501953125 +96995 -0.870391845703125 +96996 -0.86297607421875 +96997 -0.870391845703125 +96998 -0.8682861328125 +96999 -0.86444091796875 +97000 -0.870391845703125 +97001 -0.85723876953125 +97002 -0.86871337890625 +97003 -0.790008544921875 +97004 -0.858123779296875 +97005 -0.62847900390625 +97006 -0.7071533203125 +97007 -0.3956298828125 +97008 -0.474212646484375 +97009 -0.126708984375 +97010 -0.214202880859375 +97011 0.150115966796875 +97012 0.061981201171875 +97013 0.424041748046875 +97014 0.33013916015625 +97015 0.670623779296875 +97016 0.555816650390625 +97017 0.854522705078125 +97018 0.723907470703125 +97019 0.866485595703125 +97020 0.821685791015625 +97021 0.86920166015625 +97022 0.8558349609375 +97023 0.8653564453125 +97024 0.8565673828125 +97025 0.857147216796875 +97026 0.840728759765625 +97027 0.766845703125 +97028 0.77374267578125 +97029 0.628509521484375 +97030 0.66845703125 +97031 0.462127685546875 +97032 0.548797607421875 +97033 0.297210693359375 +97034 0.4268798828125 +97035 0.14862060546875 +97036 0.283782958984375 +97037 -0.00537109375 +97038 0.126739501953125 +97039 -0.15753173828125 +97040 -0.046966552734375 +97041 -0.31304931640625 +97042 -0.249542236328125 +97043 -0.48876953125 +97044 -0.440399169921875 +97045 -0.6416015625 +97046 -0.59857177734375 +97047 -0.751373291015625 +97048 -0.745025634765625 +97049 -0.84619140625 +97050 -0.855987548828125 +97051 -0.861297607421875 +97052 -0.863800048828125 +97053 -0.863250732421875 +97054 -0.863189697265625 +97055 -0.856597900390625 +97056 -0.855438232421875 +97057 -0.7498779296875 +97058 -0.778289794921875 +97059 -0.624542236328125 +97060 -0.661590576171875 +97061 -0.47808837890625 +97062 -0.462982177734375 +97063 -0.253387451171875 +97064 -0.222991943359375 +97065 0.003692626953125 +97066 -0.00164794921875 +97067 0.2257080078125 +97068 0.2117919921875 +97069 0.427154541015625 +97070 0.445648193359375 +97071 0.643218994140625 +97072 0.691864013671875 +97073 0.855926513671875 +97074 0.8594970703125 +97075 0.870361328125 +97076 0.870361328125 +97077 0.870361328125 +97078 0.870361328125 +97079 0.862762451171875 +97080 0.8629150390625 +97081 0.79669189453125 +97082 0.790863037109375 +97083 0.595794677734375 +97084 0.6055908203125 +97085 0.362152099609375 +97086 0.402740478515625 +97087 0.1270751953125 +97088 0.2022705078125 +97089 -0.086944580078125 +97090 0.006622314453125 +97091 -0.2784423828125 +97092 -0.214813232421875 +97093 -0.484832763671875 +97094 -0.4798583984375 +97095 -0.729583740234375 +97096 -0.7462158203125 +97097 -0.86688232421875 +97098 -0.86614990234375 +97099 -0.870391845703125 +97100 -0.870391845703125 +97101 -0.86859130859375 +97102 -0.870147705078125 +97103 -0.86279296875 +97104 -0.863006591796875 +97105 -0.817962646484375 +97106 -0.77215576171875 +97107 -0.6116943359375 +97108 -0.5177001953125 +97109 -0.3128662109375 +97110 -0.203094482421875 +97111 0.039398193359375 +97112 0.15142822265625 +97113 0.422821044921875 +97114 0.5162353515625 +97115 0.805145263671875 +97116 0.83343505859375 +97117 0.870361328125 +97118 0.870361328125 +97119 0.870361328125 +97120 0.870361328125 +97121 0.860015869140625 +97122 0.860992431640625 +97123 0.727935791015625 +97124 0.75042724609375 +97125 0.48114013671875 +97126 0.542449951171875 +97127 0.2059326171875 +97128 0.320953369140625 +97129 -0.06103515625 +97130 0.1038818359375 +97131 -0.29913330078125 +97132 -0.114471435546875 +97133 -0.516204833984375 +97134 -0.343231201171875 +97135 -0.7252197265625 +97136 -0.55914306640625 +97137 -0.85980224609375 +97138 -0.733428955078125 +97139 -0.870391845703125 +97140 -0.844024658203125 +97141 -0.870391845703125 +97142 -0.8544921875 +97143 -0.858062744140625 +97144 -0.769134521484375 +97145 -0.673004150390625 +97146 -0.64306640625 +97147 -0.42694091796875 +97148 -0.52520751953125 +97149 -0.2100830078125 +97150 -0.424163818359375 +97151 -0.0362548828125 +97152 -0.324798583984375 +97153 0.10943603515625 +97154 -0.219085693359375 +97155 0.23516845703125 +97156 -0.078948974609375 +97157 0.373687744140625 +97158 0.087554931640625 +97159 0.517791748046875 +97160 0.221160888671875 +97161 0.602783203125 +97162 0.32427978515625 +97163 0.635711669921875 +97164 0.42608642578125 +97165 0.655181884765625 +97166 0.5201416015625 +97167 0.65948486328125 +97168 0.603668212890625 +97169 0.651275634765625 +97170 0.661163330078125 +97171 0.61846923828125 +97172 0.667572021484375 +97173 0.53753662109375 +97174 0.615203857421875 +97175 0.404144287109375 +97176 0.5040283203125 +97177 0.22186279296875 +97178 0.343505859375 +97179 0.003997802734375 +97180 0.157379150390625 +97181 -0.22100830078125 +97182 -0.02935791015625 +97183 -0.42449951171875 +97184 -0.192413330078125 +97185 -0.579833984375 +97186 -0.2904052734375 +97187 -0.641876220703125 +97188 -0.326690673828125 +97189 -0.6177978515625 +97190 -0.357025146484375 +97191 -0.575531005859375 +97192 -0.387298583984375 +97193 -0.526336669921875 +97194 -0.37518310546875 +97195 -0.42645263671875 +97196 -0.30108642578125 +97197 -0.2581787109375 +97198 -0.202239990234375 +97199 -0.068695068359375 +97200 -0.11859130859375 +97201 0.09222412109375 +97202 -0.040740966796875 +97203 0.232147216796875 +97204 0.033233642578125 +97205 0.3509521484375 +97206 0.07086181640625 +97207 0.410064697265625 +97208 0.040618896484375 +97209 0.372955322265625 +97210 -0.044189453125 +97211 0.2554931640625 +97212 -0.14190673828125 +97213 0.10711669921875 +97214 -0.23785400390625 +97215 -0.052886962890625 +97216 -0.3013916015625 +97217 -0.186279296875 +97218 -0.283233642578125 +97219 -0.23291015625 +97220 -0.20123291015625 +97221 -0.209442138671875 +97222 -0.10968017578125 +97223 -0.174163818359375 +97224 -0.011566162109375 +97225 -0.126739501953125 +97226 0.106658935546875 +97227 -0.048126220703125 +97228 0.225921630859375 +97229 0.0426025390625 +97230 0.311187744140625 +97231 0.10748291015625 +97232 0.35638427734375 +97233 0.1409912109375 +97234 0.4080810546875 +97235 0.19708251953125 +97236 0.464691162109375 +97237 0.273651123046875 +97238 0.48089599609375 +97239 0.31768798828125 +97240 0.4686279296875 +97241 0.341094970703125 +97242 0.4510498046875 +97243 0.368011474609375 +97244 0.407989501953125 +97245 0.37249755859375 +97246 0.29522705078125 +97247 0.30072021484375 +97248 0.11474609375 +97249 0.1517333984375 +97250 -0.07855224609375 +97251 -0.01470947265625 +97252 -0.27313232421875 +97253 -0.1883544921875 +97254 -0.469879150390625 +97255 -0.372711181640625 +97256 -0.620147705078125 +97257 -0.51397705078125 +97258 -0.687469482421875 +97259 -0.57177734375 +97260 -0.66546630859375 +97261 -0.53948974609375 +97262 -0.569793701171875 +97263 -0.43511962890625 +97264 -0.433807373046875 +97265 -0.2962646484375 +97266 -0.2918701171875 +97267 -0.161102294921875 +97268 -0.15771484375 +97269 -0.0435791015625 +97270 -0.029754638671875 +97271 0.060394287109375 +97272 0.07745361328125 +97273 0.13665771484375 +97274 0.148468017578125 +97275 0.170135498046875 +97276 0.185089111328125 +97277 0.16552734375 +97278 0.21514892578125 +97279 0.15728759765625 +97280 0.241607666015625 +97281 0.150787353515625 +97282 0.241943359375 +97283 0.12200927734375 +97284 0.222625732421875 +97285 0.080108642578125 +97286 0.205413818359375 +97287 0.05126953125 +97288 0.213592529296875 +97289 0.062896728515625 +97290 0.2286376953125 +97291 0.09271240234375 +97292 0.2108154296875 +97293 0.092987060546875 +97294 0.1739501953125 +97295 0.07855224609375 +97296 0.132232666015625 +97297 0.06427001953125 +97298 0.0743408203125 +97299 0.0347900390625 +97300 0.000518798828125 +97301 -0.01171875 +97302 -0.070953369140625 +97303 -0.056060791015625 +97304 -0.10198974609375 +97305 -0.055511474609375 +97306 -0.09124755859375 +97307 -0.010467529296875 +97308 -0.083221435546875 +97309 0.02508544921875 +97310 -0.0985107421875 +97311 0.025665283203125 +97312 -0.11431884765625 +97313 0.017333984375 +97314 -0.128875732421875 +97315 0.00189208984375 +97316 -0.151702880859375 +97317 -0.03173828125 +97318 -0.17315673828125 +97319 -0.071502685546875 +97320 -0.209381103515625 +97321 -0.13543701171875 +97322 -0.25848388671875 +97323 -0.219970703125 +97324 -0.30096435546875 +97325 -0.300506591796875 +97326 -0.337677001953125 +97327 -0.376312255859375 +97328 -0.343597412109375 +97329 -0.416107177734375 +97330 -0.278778076171875 +97331 -0.371124267578125 +97332 -0.145416259765625 +97333 -0.242279052734375 +97334 0.021087646484375 +97335 -0.069732666015625 +97336 0.201995849609375 +97337 0.125640869140625 +97338 0.370208740234375 +97339 0.31268310546875 +97340 0.494476318359375 +97341 0.45501708984375 +97342 0.57659912109375 +97343 0.554779052734375 +97344 0.615753173828125 +97345 0.61065673828125 +97346 0.602630615234375 +97347 0.610931396484375 +97348 0.517578125 +97349 0.531463623046875 +97350 0.37530517578125 +97351 0.3883056640625 +97352 0.22222900390625 +97353 0.23468017578125 +97354 0.08062744140625 +97355 0.095245361328125 +97356 -0.026092529296875 +97357 -0.00396728515625 +97358 -0.08447265625 +97359 -0.04852294921875 +97360 -0.107635498046875 +97361 -0.055145263671875 +97362 -0.138916015625 +97363 -0.0758056640625 +97364 -0.20166015625 +97365 -0.138702392578125 +97366 -0.266021728515625 +97367 -0.209197998046875 +97368 -0.3333740234375 +97369 -0.289031982421875 +97370 -0.404449462890625 +97371 -0.37884521484375 +97372 -0.460662841796875 +97373 -0.456329345703125 +97374 -0.4984130859375 +97375 -0.51641845703125 +97376 -0.484649658203125 +97377 -0.519287109375 +97378 -0.4146728515625 +97379 -0.458251953125 +97380 -0.33331298828125 +97381 -0.384796142578125 +97382 -0.26263427734375 +97383 -0.323699951171875 +97384 -0.198822021484375 +97385 -0.269287109375 +97386 -0.12042236328125 +97387 -0.1951904296875 +97388 -0.027008056640625 +97389 -0.100006103515625 +97390 0.0579833984375 +97391 -0.01055908203125 +97392 0.159881591796875 +97393 0.1033935546875 +97394 0.28466796875 +97395 0.24908447265625 +97396 0.387115478515625 +97397 0.373199462890625 +97398 0.452484130859375 +97399 0.45806884765625 +97400 0.48785400390625 +97401 0.511474609375 +97402 0.52105712890625 +97403 0.565399169921875 +97404 0.545684814453125 +97405 0.61138916015625 +97406 0.511810302734375 +97407 0.5897216796875 +97408 0.411956787109375 +97409 0.4906005859375 +97410 0.2618408203125 +97411 0.33148193359375 +97412 0.09234619140625 +97413 0.147796630859375 +97414 -0.06036376953125 +97415 -0.01873779296875 +97416 -0.172088623046875 +97417 -0.140289306640625 +97418 -0.221282958984375 +97419 -0.191986083984375 +97420 -0.2166748046875 +97421 -0.184295654296875 +97422 -0.196197509765625 +97423 -0.161834716796875 +97424 -0.1956787109375 +97425 -0.166595458984375 +97426 -0.21148681640625 +97427 -0.19390869140625 +97428 -0.227691650390625 +97429 -0.22442626953125 +97430 -0.26324462890625 +97431 -0.279754638671875 +97432 -0.301055908203125 +97433 -0.3389892578125 +97434 -0.30126953125 +97435 -0.3543701171875 +97436 -0.28350830078125 +97437 -0.348175048828125 +97438 -0.253173828125 +97439 -0.32598876953125 +97440 -0.185699462890625 +97441 -0.2581787109375 +97442 -0.077362060546875 +97443 -0.139801025390625 +97444 0.05914306640625 +97445 0.014617919921875 +97446 0.171966552734375 +97447 0.144378662109375 +97448 0.236907958984375 +97449 0.221038818359375 +97450 0.276214599609375 +97451 0.27069091796875 +97452 0.290740966796875 +97453 0.294036865234375 +97454 0.298431396484375 +97455 0.311767578125 +97456 0.31268310546875 +97457 0.339141845703125 +97458 0.320404052734375 +97459 0.360260009765625 +97460 0.309783935546875 +97461 0.360504150390625 +97462 0.2550048828125 +97463 0.308380126953125 +97464 0.1380615234375 +97465 0.18170166015625 +97466 -0.019989013671875 +97467 0.0047607421875 +97468 -0.1793212890625 +97469 -0.17559814453125 +97470 -0.301727294921875 +97471 -0.3143310546875 +97472 -0.350311279296875 +97473 -0.36785888671875 +97474 -0.3470458984375 +97475 -0.36248779296875 +97476 -0.329986572265625 +97477 -0.343536376953125 +97478 -0.2916259765625 +97479 -0.3018798828125 +97480 -0.227081298828125 +97481 -0.231414794921875 +97482 -0.12451171875 +97483 -0.117645263671875 +97484 -0.011505126953125 +97485 0.007049560546875 +97486 0.06549072265625 +97487 0.087982177734375 +97488 0.117950439453125 +97489 0.13946533203125 +97490 0.156097412109375 +97491 0.17425537109375 +97492 0.175933837890625 +97493 0.188201904296875 +97494 0.1685791015625 +97495 0.171234130859375 +97496 0.12957763671875 +97497 0.118438720703125 +97498 0.081573486328125 +97499 0.05706787109375 +97500 0.026214599609375 +97501 -0.010711669921875 +97502 -0.041961669921875 +97503 -0.0914306640625 +97504 -0.103759765625 +97505 -0.162322998046875 +97506 -0.134796142578125 +97507 -0.194549560546875 +97508 -0.102203369140625 +97509 -0.1492919921875 +97510 -0.00152587890625 +97511 -0.02166748046875 +97512 0.1136474609375 +97513 0.124053955078125 +97514 0.17926025390625 +97515 0.211151123046875 +97516 0.196441650390625 +97517 0.240447998046875 +97518 0.191009521484375 +97519 0.242218017578125 +97520 0.171112060546875 +97521 0.2257080078125 +97522 0.139923095703125 +97523 0.194366455078125 +97524 0.070220947265625 +97525 0.115509033203125 +97526 -0.017913818359375 +97527 0.0128173828125 +97528 -0.074127197265625 +97529 -0.053802490234375 +97530 -0.12054443359375 +97531 -0.110626220703125 +97532 -0.192413330078125 +97533 -0.199493408203125 +97534 -0.26806640625 +97535 -0.29437255859375 +97536 -0.295135498046875 +97537 -0.33221435546875 +97538 -0.246734619140625 +97539 -0.27972412109375 +97540 -0.162811279296875 +97541 -0.185333251953125 +97542 -0.108062744140625 +97543 -0.128204345703125 +97544 -0.089111328125 +97545 -0.115692138671875 +97546 -0.081298828125 +97547 -0.116455078125 +97548 -0.06536865234375 +97549 -0.105926513671875 +97550 -0.017364501953125 +97551 -0.053955078125 +97552 0.06988525390625 +97553 0.048797607421875 +97554 0.159881591796875 +97555 0.157318115234375 +97556 0.204376220703125 +97557 0.212005615234375 +97558 0.207977294921875 +97559 0.218475341796875 +97560 0.219757080078125 +97561 0.23724365234375 +97562 0.2698974609375 +97563 0.30535888671875 +97564 0.32513427734375 +97565 0.38128662109375 +97566 0.3369140625 +97567 0.404449462890625 +97568 0.32147216796875 +97569 0.3944091796875 +97570 0.3094482421875 +97571 0.3885498046875 +97572 0.281707763671875 +97573 0.362640380859375 +97574 0.203765869140625 +97575 0.27362060546875 +97576 0.072418212890625 +97577 0.11712646484375 +97578 -0.070098876953125 +97579 -0.054901123046875 +97580 -0.181915283203125 +97581 -0.19085693359375 +97582 -0.258941650390625 +97583 -0.28570556640625 +97584 -0.30108642578125 +97585 -0.339263916015625 +97586 -0.329437255859375 +97587 -0.3775634765625 +97588 -0.380645751953125 +97589 -0.445709228515625 +97590 -0.447998046875 +97591 -0.535064697265625 +97592 -0.51837158203125 +97593 -0.629058837890625 +97594 -0.567779541015625 +97595 -0.697601318359375 +97596 -0.56683349609375 +97597 -0.70391845703125 +97598 -0.51141357421875 +97599 -0.6424560546875 +97600 -0.384063720703125 +97601 -0.491241455078125 +97602 -0.197479248046875 +97603 -0.265716552734375 +97604 0.0013427734375 +97605 -0.023712158203125 +97606 0.185577392578125 +97607 0.201751708984375 +97608 0.326995849609375 +97609 0.375823974609375 +97610 0.414764404296875 +97611 0.485076904296875 +97612 0.480712890625 +97613 0.56884765625 +97614 0.5311279296875 +97615 0.634765625 +97616 0.529693603515625 +97617 0.63763427734375 +97618 0.4674072265625 +97619 0.5660400390625 +97620 0.3865966796875 +97621 0.4720458984375 +97622 0.328948974609375 +97623 0.40692138671875 +97624 0.300537109375 +97625 0.3778076171875 +97626 0.29534912109375 +97627 0.376953125 +97628 0.287445068359375 +97629 0.371978759765625 +97630 0.236846923828125 +97631 0.313140869140625 +97632 0.1307373046875 +97633 0.184417724609375 +97634 -0.010223388671875 +97635 0.011199951171875 +97636 -0.157379150390625 +97637 -0.171051025390625 +97638 -0.290618896484375 +97639 -0.33740234375 +97640 -0.397216796875 +97641 -0.47198486328125 +97642 -0.465728759765625 +97643 -0.560394287109375 +97644 -0.478485107421875 +97645 -0.58056640625 +97646 -0.447845458984375 +97647 -0.54754638671875 +97648 -0.412200927734375 +97649 -0.508575439453125 +97650 -0.368438720703125 +97651 -0.459503173828125 +97652 -0.311981201171875 +97653 -0.394378662109375 +97654 -0.27484130859375 +97655 -0.35260009765625 +97656 -0.239044189453125 +97657 -0.31170654296875 +97658 -0.14471435546875 +97659 -0.197418212890625 +97660 0.00946044921875 +97661 -0.007965087890625 +97662 0.1837158203125 +97663 0.207489013671875 +97664 0.345977783203125 +97665 0.409210205078125 +97666 0.47601318359375 +97667 0.57208251953125 +97668 0.549560546875 +97669 0.66595458984375 +97670 0.540863037109375 +97671 0.65875244140625 +97672 0.463836669921875 +97673 0.56744384765625 +97674 0.3504638671875 +97675 0.431396484375 +97676 0.236358642578125 +97677 0.29443359375 +97678 0.14263916015625 +97679 0.182464599609375 +97680 0.04376220703125 +97681 0.06365966796875 +97682 -0.0714111328125 +97683 -0.075958251953125 +97684 -0.16485595703125 +97685 -0.189422607421875 +97686 -0.23260498046875 +97687 -0.271942138671875 +97688 -0.28997802734375 +97689 -0.342529296875 +97690 -0.307098388671875 +97691 -0.364166259765625 +97692 -0.276214599609375 +97693 -0.327239990234375 +97694 -0.233917236328125 +97695 -0.2769775390625 +97696 -0.212921142578125 +97697 -0.253692626953125 +97698 -0.20220947265625 +97699 -0.24365234375 +97700 -0.162811279296875 +97701 -0.1983642578125 +97702 -0.093597412109375 +97703 -0.116241455078125 +97704 -0.026641845703125 +97705 -0.036834716796875 +97706 0.033843994140625 +97707 0.034881591796875 +97708 0.08154296875 +97709 0.09124755859375 +97710 0.09747314453125 +97711 0.10888671875 +97712 0.112030029296875 +97713 0.125518798828125 +97714 0.1385498046875 +97715 0.15771484375 +97716 0.155029296875 +97717 0.17828369140625 +97718 0.148468017578125 +97719 0.17108154296875 +97720 0.113983154296875 +97721 0.129974365234375 +97722 0.073822021484375 +97723 0.082427978515625 +97724 0.02752685546875 +97725 0.027679443359375 +97726 -0.050140380859375 +97727 -0.065643310546875 +97728 -0.128173828125 +97729 -0.15936279296875 +97730 -0.173828125 +97731 -0.21307373046875 +97732 -0.193359375 +97733 -0.234649658203125 +97734 -0.1673583984375 +97735 -0.2001953125 +97736 -0.103363037109375 +97737 -0.119171142578125 +97738 -0.02813720703125 +97739 -0.024749755859375 +97740 0.060577392578125 +97741 0.085784912109375 +97742 0.135101318359375 +97743 0.178131103515625 +97744 0.165771484375 +97745 0.215576171875 +97746 0.163299560546875 +97747 0.211456298828125 +97748 0.13525390625 +97749 0.17523193359375 +97750 0.099212646484375 +97751 0.128753662109375 +97752 0.079254150390625 +97753 0.1019287109375 +97754 0.058807373046875 +97755 0.0743408203125 +97756 0.035552978515625 +97757 0.04327392578125 +97758 0.033203125 +97759 0.038177490234375 +97760 0.065582275390625 +97761 0.076263427734375 +97762 0.119293212890625 +97763 0.14105224609375 +97764 0.157012939453125 +97765 0.186431884765625 +97766 0.15960693359375 +97767 0.188812255859375 +97768 0.11962890625 +97769 0.1390380859375 +97770 0.040863037109375 +97771 0.041778564453125 +97772 -0.0576171875 +97773 -0.079437255859375 +97774 -0.17156982421875 +97775 -0.219390869140625 +97776 -0.29266357421875 +97777 -0.367828369140625 +97778 -0.396697998046875 +97779 -0.494873046875 +97780 -0.447784423828125 +97781 -0.556243896484375 +97782 -0.410919189453125 +97783 -0.508697509765625 +97784 -0.304901123046875 +97785 -0.3756103515625 +97786 -0.179656982421875 +97787 -0.218902587890625 +97788 -0.05548095703125 +97789 -0.063751220703125 +97790 0.06903076171875 +97791 0.091552734375 +97792 0.18499755859375 +97793 0.23602294921875 +97794 0.27093505859375 +97795 0.342987060546875 +97796 0.313232421875 +97797 0.39520263671875 +97798 0.309539794921875 +97799 0.389373779296875 +97800 0.259063720703125 +97801 0.324249267578125 +97802 0.180816650390625 +97803 0.224090576171875 +97804 0.1024169921875 +97805 0.124267578125 +97806 0.033538818359375 +97807 0.037078857421875 +97808 -0.004425048828125 +97809 -0.010101318359375 +97810 -0.013092041015625 +97811 -0.019439697265625 +97812 -0.017059326171875 +97813 -0.022796630859375 +97814 -0.0018310546875 +97815 -0.001556396484375 +97816 0.0419921875 +97817 0.056304931640625 +97818 0.080230712890625 +97819 0.106719970703125 +97820 0.07196044921875 +97821 0.096893310546875 +97822 0.029510498046875 +97823 0.042694091796875 +97824 -0.017791748046875 +97825 -0.018035888671875 +97826 -0.062591552734375 +97827 -0.07586669921875 +97828 -0.096099853515625 +97829 -0.11944580078125 +97830 -0.12689208984375 +97831 -0.15972900390625 +97832 -0.1595458984375 +97833 -0.202606201171875 +97834 -0.194488525390625 +97835 -0.24859619140625 +97836 -0.237548828125 +97837 -0.30517578125 +97838 -0.280853271484375 +97839 -0.36212158203125 +97840 -0.302734375 +97841 -0.39141845703125 +97842 -0.273895263671875 +97843 -0.35528564453125 +97844 -0.191497802734375 +97845 -0.249969482421875 +97846 -0.069091796875 +97847 -0.092864990234375 +97848 0.0723876953125 +97849 0.08905029296875 +97850 0.185943603515625 +97851 0.2352294921875 +97852 0.250732421875 +97853 0.318817138671875 +97854 0.2813720703125 +97855 0.358642578125 +97856 0.272491455078125 +97857 0.347747802734375 +97858 0.2237548828125 +97859 0.28564453125 +97860 0.174652099609375 +97861 0.223175048828125 +97862 0.1534423828125 +97863 0.196746826171875 +97864 0.139617919921875 +97865 0.179840087890625 +97866 0.120086669921875 +97867 0.155548095703125 +97868 0.116119384765625 +97869 0.151214599609375 +97870 0.12005615234375 +97871 0.156951904296875 +97872 0.10009765625 +97873 0.13177490234375 +97874 0.075775146484375 +97875 0.100799560546875 +97876 0.06500244140625 +97877 0.087127685546875 +97878 0.03997802734375 +97879 0.05487060546875 +97880 -0.009429931640625 +97881 -0.009002685546875 +97882 -0.08282470703125 +97883 -0.10400390625 +97884 -0.1796875 +97885 -0.229400634765625 +97886 -0.27703857421875 +97887 -0.35552978515625 +97888 -0.343505859375 +97889 -0.441925048828125 +97890 -0.367706298828125 +97891 -0.473846435546875 +97892 -0.360137939453125 +97893 -0.464813232421875 +97894 -0.324127197265625 +97895 -0.419097900390625 +97896 -0.25787353515625 +97897 -0.334320068359375 +97898 -0.1749267578125 +97899 -0.227935791015625 +97900 -0.093597412109375 +97901 -0.12347412109375 +97902 -0.019073486328125 +97903 -0.02764892578125 +97904 0.06268310546875 +97905 0.077667236328125 +97906 0.167816162109375 +97907 0.2132568359375 +97908 0.303863525390625 +97909 0.38885498046875 +97910 0.45404052734375 +97911 0.582794189453125 +97912 0.57098388671875 +97913 0.734039306640625 +97914 0.621795654296875 +97915 0.800140380859375 +97916 0.604339599609375 +97917 0.7783203125 +97918 0.5159912109375 +97919 0.6651611328125 +97920 0.35601806640625 +97921 0.45965576171875 +97922 0.1534423828125 +97923 0.199188232421875 +97924 -0.040802001953125 +97925 -0.050689697265625 +97926 -0.1824951171875 +97927 -0.23297119140625 +97928 -0.258056640625 +97929 -0.33013916015625 +97930 -0.287811279296875 +97931 -0.368408203125 +97932 -0.295928955078125 +97933 -0.378936767578125 +97934 -0.294281005859375 +97935 -0.376983642578125 +97936 -0.296173095703125 +97937 -0.37969970703125 +97938 -0.305023193359375 +97939 -0.391510009765625 +97940 -0.29986572265625 +97941 -0.385345458984375 +97942 -0.2657470703125 +97943 -0.3419189453125 +97944 -0.219512939453125 +97945 -0.28289794921875 +97946 -0.194793701171875 +97947 -0.251617431640625 +97948 -0.205657958984375 +97949 -0.266143798828125 +97950 -0.210906982421875 +97951 -0.273345947265625 +97952 -0.166748046875 +97953 -0.216796875 +97954 -0.09783935546875 +97955 -0.128265380859375 +97956 -0.051055908203125 +97957 -0.068145751953125 +97958 -0.031585693359375 +97959 -0.0430908203125 +97960 -0.017181396484375 +97961 -0.024444580078125 +97962 0.0177001953125 +97963 0.020721435546875 +97964 0.097991943359375 +97965 0.124481201171875 +97966 0.201202392578125 +97967 0.25787353515625 +97968 0.294921875 +97969 0.379119873046875 +97970 0.37274169921875 +97971 0.47991943359375 +97972 0.4097900390625 +97973 0.5281982421875 +97974 0.396148681640625 +97975 0.511138916015625 +97976 0.3531494140625 +97977 0.456207275390625 +97978 0.31500244140625 +97979 0.407470703125 +97980 0.296356201171875 +97981 0.383758544921875 +97982 0.27532958984375 +97983 0.35687255859375 +97984 0.240325927734375 +97985 0.31182861328125 +97986 0.19305419921875 +97987 0.250885009765625 +97988 0.1268310546875 +97989 0.1654052734375 +97990 0.026031494140625 +97991 0.035247802734375 +97992 -0.111297607421875 +97993 -0.142059326171875 +97994 -0.261199951171875 +97995 -0.33563232421875 +97996 -0.415191650390625 +97997 -0.5345458984375 +97998 -0.56011962890625 +97999 -0.72186279296875 +98000 -0.648773193359375 +98001 -0.836669921875 +98002 -0.645233154296875 +98003 -0.8326416015625 +98004 -0.56494140625 +98005 -0.7296142578125 +98006 -0.4505615234375 +98007 -0.582550048828125 +98008 -0.339813232421875 +98009 -0.440093994140625 +98010 -0.249847412109375 +98011 -0.324310302734375 +98012 -0.154510498046875 +98013 -0.20147705078125 +98014 -0.032867431640625 +98015 -0.044647216796875 +98016 0.08233642578125 +98017 0.103973388671875 +98018 0.15850830078125 +98019 0.202392578125 +98020 0.2064208984375 +98021 0.264495849609375 +98022 0.263824462890625 +98023 0.338897705078125 +98024 0.3448486328125 +98025 0.443817138671875 +98026 0.42303466796875 +98027 0.545074462890625 +98028 0.478668212890625 +98029 0.6173095703125 +98030 0.50555419921875 +98031 0.6524658203125 +98032 0.513702392578125 +98033 0.66339111328125 +98034 0.5078125 +98035 0.6561279296875 +98036 0.469329833984375 +98037 0.606781005859375 +98038 0.38726806640625 +98039 0.501190185546875 +98040 0.272064208984375 +98041 0.352783203125 +98042 0.135345458984375 +98043 0.176544189453125 +98044 -0.028533935546875 +98045 -0.034820556640625 +98046 -0.201629638671875 +98047 -0.258209228515625 +98048 -0.344451904296875 +98049 -0.44244384765625 +98050 -0.4473876953125 +98051 -0.5753173828125 +98052 -0.50689697265625 +98053 -0.65203857421875 +98054 -0.5 +98055 -0.641632080078125 +98056 -0.440277099609375 +98057 -0.562164306640625 +98058 -0.36090087890625 +98059 -0.458038330078125 +98060 -0.277923583984375 +98061 -0.350555419921875 +98062 -0.20709228515625 +98063 -0.260528564453125 +98064 -0.15179443359375 +98065 -0.192108154296875 +98066 -0.109771728515625 +98067 -0.141937255859375 +98068 -0.075469970703125 +98069 -0.1021728515625 +98070 -0.041748046875 +98071 -0.062896728515625 +98072 0.00018310546875 +98073 -0.011932373046875 +98074 0.059173583984375 +98075 0.062835693359375 +98076 0.125640869140625 +98077 0.148712158203125 +98078 0.19647216796875 +98079 0.241729736328125 +98080 0.277008056640625 +98081 0.34912109375 +98082 0.357177734375 +98083 0.457305908203125 +98084 0.42034912109375 +98085 0.54388427734375 +98086 0.439849853515625 +98087 0.5728759765625 +98088 0.387786865234375 +98089 0.506591796875 +98090 0.268951416015625 +98091 0.351226806640625 +98092 0.11309814453125 +98093 0.146514892578125 +98094 -0.040679931640625 +98095 -0.05523681640625 +98096 -0.1640625 +98097 -0.21624755859375 +98098 -0.255645751953125 +98099 -0.334930419921875 +98100 -0.30908203125 +98101 -0.402984619140625 +98102 -0.33978271484375 +98103 -0.4412841796875 +98104 -0.3818359375 +98105 -0.49578857421875 +98106 -0.43048095703125 +98107 -0.5601806640625 +98108 -0.460601806640625 +98109 -0.600738525390625 +98110 -0.447509765625 +98111 -0.584228515625 +98112 -0.367950439453125 +98113 -0.47930908203125 +98114 -0.21710205078125 +98115 -0.27935791015625 +98116 -0.01336669921875 +98117 -0.0089111328125 +98118 0.196044921875 +98119 0.268798828125 +98120 0.35821533203125 +98121 0.482818603515625 +98122 0.451080322265625 +98123 0.60369873046875 +98124 0.488555908203125 +98125 0.650421142578125 +98126 0.50103759765625 +98127 0.66400146484375 +98128 0.486175537109375 +98129 0.6414794921875 +98130 0.436248779296875 +98131 0.572540283203125 +98132 0.38165283203125 +98133 0.498138427734375 +98134 0.338104248046875 +98135 0.439453125 +98136 0.2900390625 +98137 0.375518798828125 +98138 0.21380615234375 +98139 0.274505615234375 +98140 0.08892822265625 +98141 0.1087646484375 +98142 -0.067901611328125 +98143 -0.099395751953125 +98144 -0.232940673828125 +98145 -0.3182373046875 +98146 -0.406982421875 +98147 -0.5489501953125 +98148 -0.57666015625 +98149 -0.7738037109375 +98150 -0.702423095703125 +98151 -0.86383056640625 +98152 -0.759429931640625 +98153 -0.870391845703125 +98154 -0.760772705078125 +98155 -0.86895751953125 +98156 -0.716156005859375 +98157 -0.861053466796875 +98158 -0.612640380859375 +98159 -0.765869140625 +98160 -0.441802978515625 +98161 -0.5301513671875 +98162 -0.208953857421875 +98163 -0.214691162109375 +98164 0.0538330078125 +98165 0.137359619140625 +98166 0.308349609375 +98167 0.474822998046875 +98168 0.528106689453125 +98169 0.76239013671875 +98170 0.692901611328125 +98171 0.867462158203125 +98172 0.802978515625 +98173 0.870361328125 +98174 0.849609375 +98175 0.86480712890625 +98176 0.836669921875 +98177 0.831817626953125 +98178 0.78216552734375 +98179 0.677581787109375 +98180 0.690338134765625 +98181 0.495880126953125 +98182 0.574920654296875 +98183 0.30767822265625 +98184 0.4375 +98185 0.116180419921875 +98186 0.254425048828125 +98187 -0.110748291015625 +98188 0.02056884765625 +98189 -0.381805419921875 +98190 -0.232208251953125 +98191 -0.6572265625 +98192 -0.459320068359375 +98193 -0.857421875 +98194 -0.62872314453125 +98195 -0.870391845703125 +98196 -0.73504638671875 +98197 -0.870391845703125 +98198 -0.7982177734375 +98199 -0.86444091796875 +98200 -0.84466552734375 +98201 -0.85723876953125 +98202 -0.855194091796875 +98203 -0.790008544921875 +98204 -0.80572509765625 +98205 -0.62847900390625 +98206 -0.677398681640625 +98207 -0.3956298828125 +98208 -0.50006103515625 +98209 -0.126708984375 +98210 -0.294036865234375 +98211 0.150115966796875 +98212 -0.068023681640625 +98213 0.424041748046875 +98214 0.15789794921875 +98215 0.670623779296875 +98216 0.354888916015625 +98217 0.854522705078125 +98218 0.509765625 +98219 0.866485595703125 +98220 0.610992431640625 +98221 0.86920166015625 +98222 0.6719970703125 +98223 0.8653564453125 +98224 0.702667236328125 +98225 0.857147216796875 +98226 0.700714111328125 +98227 0.766845703125 +98228 0.669891357421875 +98229 0.628509521484375 +98230 0.605072021484375 +98231 0.462127685546875 +98232 0.525390625 +98233 0.297210693359375 +98234 0.44000244140625 +98235 0.14862060546875 +98236 0.3319091796875 +98237 -0.00537109375 +98238 0.2066650390625 +98239 -0.15753173828125 +98240 0.06158447265625 +98241 -0.31304931640625 +98242 -0.11370849609375 +98243 -0.48876953125 +98244 -0.2843017578125 +98245 -0.6416015625 +98246 -0.431732177734375 +98247 -0.751373291015625 +98248 -0.573089599609375 +98249 -0.84619140625 +98250 -0.69732666015625 +98251 -0.861297607421875 +98252 -0.779693603515625 +98253 -0.863250732421875 +98254 -0.796600341796875 +98255 -0.856597900390625 +98256 -0.75701904296875 +98257 -0.7498779296875 +98258 -0.703948974609375 +98259 -0.624542236328125 +98260 -0.620941162109375 +98261 -0.47808837890625 +98262 -0.464508056640625 +98263 -0.253387451171875 +98264 -0.268585205078125 +98265 0.003692626953125 +98266 -0.08404541015625 +98267 0.2257080078125 +98268 0.098358154296875 +98269 0.427154541015625 +98270 0.30267333984375 +98271 0.643218994140625 +98272 0.5216064453125 +98273 0.855926513671875 +98274 0.71197509765625 +98275 0.870361328125 +98276 0.836761474609375 +98277 0.870361328125 +98278 0.859588623046875 +98279 0.862762451171875 +98280 0.859771728515625 +98281 0.79669189453125 +98282 0.835174560546875 +98283 0.595794677734375 +98284 0.719207763671875 +98285 0.362152099609375 +98286 0.57598876953125 +98287 0.1270751953125 +98288 0.4212646484375 +98289 -0.086944580078125 +98290 0.256622314453125 +98291 -0.2784423828125 +98292 0.056243896484375 +98293 -0.484832763671875 +98294 -0.19403076171875 +98295 -0.729583740234375 +98296 -0.45648193359375 +98297 -0.86688232421875 +98298 -0.68389892578125 +98299 -0.870391845703125 +98300 -0.856475830078125 +98301 -0.86859130859375 +98302 -0.870391845703125 +98303 -0.86279296875 +98304 -0.870391845703125 +98305 -0.817962646484375 +98306 -0.860198974609375 +98307 -0.6116943359375 +98308 -0.718719482421875 +98309 -0.3128662109375 +98310 -0.463897705078125 +98311 0.039398193359375 +98312 -0.159515380859375 +98313 0.422821044921875 +98314 0.1685791015625 +98315 0.805145263671875 +98316 0.470794677734375 +98317 0.870361328125 +98318 0.706451416015625 +98319 0.870361328125 +98320 0.85595703125 +98321 0.860015869140625 +98322 0.8651123046875 +98323 0.727935791015625 +98324 0.8656005859375 +98325 0.48114013671875 +98326 0.859619140625 +98327 0.2059326171875 +98328 0.8074951171875 +98329 -0.06103515625 +98330 0.684539794921875 +98331 -0.29913330078125 +98332 0.526153564453125 +98333 -0.516204833984375 +98334 0.324798583984375 +98335 -0.7252197265625 +98336 0.101287841796875 +98337 -0.85980224609375 +98338 -0.1173095703125 +98339 -0.870391845703125 +98340 -0.3079833984375 +98341 -0.870391845703125 +98342 -0.434814453125 +98343 -0.858062744140625 +98344 -0.494354248046875 +98345 -0.673004150390625 +98346 -0.52423095703125 +98347 -0.42694091796875 +98348 -0.5570068359375 +98349 -0.2100830078125 +98350 -0.592803955078125 +98351 -0.0362548828125 +98352 -0.613128662109375 +98353 0.10943603515625 +98354 -0.60638427734375 +98355 0.23516845703125 +98356 -0.54595947265625 +98357 0.373687744140625 +98358 -0.4361572265625 +98359 0.517791748046875 +98360 -0.324737548828125 +98361 0.602783203125 +98362 -0.210723876953125 +98363 0.635711669921875 +98364 -0.072723388671875 +98365 0.655181884765625 +98366 0.080322265625 +98367 0.65948486328125 +98368 0.241363525390625 +98369 0.651275634765625 +98370 0.3922119140625 +98371 0.61846923828125 +98372 0.50640869140625 +98373 0.53753662109375 +98374 0.571563720703125 +98375 0.404144287109375 +98376 0.581817626953125 +98377 0.22186279296875 +98378 0.53961181640625 +98379 0.003997802734375 +98380 0.459808349609375 +98381 -0.22100830078125 +98382 0.359344482421875 +98383 -0.42449951171875 +98384 0.255828857421875 +98385 -0.579833984375 +98386 0.18206787109375 +98387 -0.641876220703125 +98388 0.1356201171875 +98389 -0.6177978515625 +98390 0.07257080078125 +98391 -0.575531005859375 +98392 -0.0091552734375 +98393 -0.526336669921875 +98394 -0.071380615234375 +98395 -0.42645263671875 +98396 -0.093719482421875 +98397 -0.2581787109375 +98398 -0.101776123046875 +98399 -0.068695068359375 +98400 -0.123138427734375 +98401 0.09222412109375 +98402 -0.145233154296875 +98403 0.232147216796875 +98404 -0.161895751953125 +98405 0.3509521484375 +98406 -0.1956787109375 +98407 0.410064697265625 +98408 -0.2691650390625 +98409 0.372955322265625 +98410 -0.36932373046875 +98411 0.2554931640625 +98412 -0.4609375 +98413 0.10711669921875 +98414 -0.531951904296875 +98415 -0.052886962890625 +98416 -0.55828857421875 +98417 -0.186279296875 +98418 -0.501617431640625 +98419 -0.23291015625 +98420 -0.379302978515625 +98421 -0.209442138671875 +98422 -0.239044189453125 +98423 -0.174163818359375 +98424 -0.087188720703125 +98425 -0.126739501953125 +98426 0.083282470703125 +98427 -0.048126220703125 +98428 0.252685546875 +98429 0.0426025390625 +98430 0.3885498046875 +98431 0.10748291015625 +98432 0.48248291015625 +98433 0.1409912109375 +98434 0.56964111328125 +98435 0.19708251953125 +98436 0.646636962890625 +98437 0.273651123046875 +98438 0.675201416015625 +98439 0.31768798828125 +98440 0.6646728515625 +98441 0.341094970703125 +98442 0.634429931640625 +98443 0.368011474609375 +98444 0.569305419921875 +98445 0.37249755859375 +98446 0.435272216796875 +98447 0.30072021484375 +98448 0.236572265625 +98449 0.1517333984375 +98450 0.02105712890625 +98451 -0.01470947265625 +98452 -0.198486328125 +98453 -0.1883544921875 +98454 -0.41937255859375 +98455 -0.372711181640625 +98456 -0.598602294921875 +98457 -0.51397705078125 +98458 -0.703460693359375 +98459 -0.57177734375 +98460 -0.726165771484375 +98461 -0.53948974609375 +98462 -0.677581787109375 +98463 -0.43511962890625 +98464 -0.583648681640625 +98465 -0.2962646484375 +98466 -0.471893310546875 +98467 -0.161102294921875 +98468 -0.353668212890625 +98469 -0.0435791015625 +98470 -0.228515625 +98471 0.060394287109375 +98472 -0.1097412109375 +98473 0.13665771484375 +98474 -0.011962890625 +98475 0.170135498046875 +98476 0.0638427734375 +98477 0.16552734375 +98478 0.137725830078125 +98479 0.15728759765625 +98480 0.209136962890625 +98481 0.150787353515625 +98482 0.2569580078125 +98483 0.12200927734375 +98484 0.284210205078125 +98485 0.080108642578125 +98486 0.3067626953125 +98487 0.05126953125 +98488 0.3421630859375 +98489 0.062896728515625 +98490 0.37353515625 +98491 0.09271240234375 +98492 0.3668212890625 +98493 0.092987060546875 +98494 0.333465576171875 +98495 0.07855224609375 +98496 0.2857666015625 +98497 0.06427001953125 +98498 0.215240478515625 +98499 0.0347900390625 +98500 0.12359619140625 +98501 -0.01171875 +98502 0.0279541015625 +98503 -0.056060791015625 +98504 -0.037567138671875 +98505 -0.055511474609375 +98506 -0.069580078125 +98507 -0.010467529296875 +98508 -0.10308837890625 +98509 0.02508544921875 +98510 -0.153167724609375 +98511 0.025665283203125 +98512 -0.198760986328125 +98513 0.017333984375 +98514 -0.23675537109375 +98515 0.00189208984375 +98516 -0.27392578125 +98517 -0.03173828125 +98518 -0.3013916015625 +98519 -0.071502685546875 +98520 -0.332427978515625 +98521 -0.13543701171875 +98522 -0.36566162109375 +98523 -0.219970703125 +98524 -0.38543701171875 +98525 -0.300506591796875 +98526 -0.393585205078125 +98527 -0.376312255859375 +98528 -0.370513916015625 +98529 -0.416107177734375 +98530 -0.284515380859375 +98531 -0.371124267578125 +98532 -0.13922119140625 +98533 -0.242279052734375 +98534 0.033843994140625 +98535 -0.069732666015625 +98536 0.2171630859375 +98537 0.125640869140625 +98538 0.38629150390625 +98539 0.31268310546875 +98540 0.513641357421875 +98541 0.45501708984375 +98542 0.599578857421875 +98543 0.554779052734375 +98544 0.6427001953125 +98545 0.61065673828125 +98546 0.634796142578125 +98547 0.610931396484375 +98548 0.559478759765625 +98549 0.531463623046875 +98550 0.42950439453125 +98551 0.3883056640625 +98552 0.2845458984375 +98553 0.23468017578125 +98554 0.144317626953125 +98555 0.095245361328125 +98556 0.02972412109375 +98557 -0.00396728515625 +98558 -0.046478271484375 +98559 -0.04852294921875 +98560 -0.09393310546875 +98561 -0.055145263671875 +98562 -0.14727783203125 +98563 -0.0758056640625 +98564 -0.22430419921875 +98565 -0.138702392578125 +98566 -0.299041748046875 +98567 -0.209197998046875 +98568 -0.37139892578125 +98569 -0.289031982421875 +98570 -0.441131591796875 +98571 -0.37884521484375 +98572 -0.492462158203125 +98573 -0.456329345703125 +98574 -0.52227783203125 +98575 -0.51641845703125 +98576 -0.50360107421875 +98577 -0.519287109375 +98578 -0.43310546875 +98579 -0.458251953125 +98580 -0.348541259765625 +98581 -0.384796142578125 +98582 -0.269195556640625 +98583 -0.323699951171875 +98584 -0.19317626953125 +98585 -0.269287109375 +98586 -0.104156494140625 +98587 -0.1951904296875 +98588 -0.003173828125 +98589 -0.100006103515625 +98590 0.08917236328125 +98591 -0.01055908203125 +98592 0.192535400390625 +98593 0.1033935546875 +98594 0.310882568359375 +98595 0.24908447265625 +98596 0.406219482421875 +98597 0.373199462890625 +98598 0.4659423828125 +98599 0.45806884765625 +98600 0.495697021484375 +98601 0.511474609375 +98602 0.518524169921875 +98603 0.565399169921875 +98604 0.529541015625 +98605 0.61138916015625 +98606 0.48828125 +98607 0.5897216796875 +98608 0.389404296875 +98609 0.4906005859375 +98610 0.24688720703125 +98611 0.33148193359375 +98612 0.087249755859375 +98613 0.147796630859375 +98614 -0.05859375 +98615 -0.01873779296875 +98616 -0.16961669921875 +98617 -0.140289306640625 +98618 -0.227081298828125 +98619 -0.191986083984375 +98620 -0.2373046875 +98621 -0.184295654296875 +98622 -0.2308349609375 +98623 -0.161834716796875 +98624 -0.236724853515625 +98625 -0.166595458984375 +98626 -0.25177001953125 +98627 -0.19390869140625 +98628 -0.262847900390625 +98629 -0.22442626953125 +98630 -0.285797119140625 +98631 -0.279754638671875 +98632 -0.307037353515625 +98633 -0.3389892578125 +98634 -0.29437255859375 +98635 -0.3543701171875 +98636 -0.264739990234375 +98637 -0.348175048828125 +98638 -0.223480224609375 +98639 -0.32598876953125 +98640 -0.151275634765625 +98641 -0.2581787109375 +98642 -0.04595947265625 +98643 -0.139801025390625 +98644 0.081146240234375 +98645 0.014617919921875 +98646 0.186553955078125 +98647 0.144378662109375 +98648 0.249725341796875 +98649 0.221038818359375 +98650 0.288543701171875 +98651 0.27069091796875 +98652 0.303436279296875 +98653 0.294036865234375 +98654 0.30914306640625 +98655 0.311767578125 +98656 0.316802978515625 +98657 0.339141845703125 +98658 0.315765380859375 +98659 0.360260009765625 +98660 0.296875 +98661 0.360504150390625 +98662 0.239898681640625 +98663 0.308380126953125 +98664 0.131072998046875 +98665 0.18170166015625 +98666 -0.011688232421875 +98667 0.0047607421875 +98668 -0.155303955078125 +98669 -0.17559814453125 +98670 -0.268035888671875 +98671 -0.3143310546875 +98672 -0.319305419921875 +98673 -0.36785888671875 +98674 -0.326263427734375 +98675 -0.36248779296875 +98676 -0.319305419921875 +98677 -0.343536376953125 +98678 -0.29205322265625 +98679 -0.3018798828125 +98680 -0.24041748046875 +98681 -0.231414794921875 +98682 -0.154876708984375 +98683 -0.117645263671875 +98684 -0.058013916015625 +98685 0.007049560546875 +98686 0.012176513671875 +98687 0.087982177734375 +98688 0.06451416015625 +98689 0.13946533203125 +98690 0.106658935546875 +98691 0.17425537109375 +98692 0.134735107421875 +98693 0.188201904296875 +98694 0.140869140625 +98695 0.171234130859375 +98696 0.120819091796875 +98697 0.118438720703125 +98698 0.09228515625 +98699 0.05706787109375 +98700 0.056060791015625 +98701 -0.010711669921875 +98702 0.00726318359375 +98703 -0.0914306640625 +98704 -0.038787841796875 +98705 -0.162322998046875 +98706 -0.0625 +98707 -0.194549560546875 +98708 -0.03729248046875 +98709 -0.1492919921875 +98710 0.04058837890625 +98711 -0.02166748046875 +98712 0.128021240234375 +98713 0.124053955078125 +98714 0.173553466796875 +98715 0.211151123046875 +98716 0.17852783203125 +98717 0.240447998046875 +98718 0.16436767578125 +98719 0.242218017578125 +98720 0.13824462890625 +98721 0.2257080078125 +98722 0.103302001953125 +98723 0.194366455078125 +98724 0.03802490234375 +98725 0.115509033203125 +98726 -0.0408935546875 +98727 0.0128173828125 +98728 -0.09228515625 +98729 -0.053802490234375 +98730 -0.1337890625 +98731 -0.110626220703125 +98732 -0.19378662109375 +98733 -0.199493408203125 +98734 -0.254730224609375 +98735 -0.29437255859375 +98736 -0.27398681640625 +98737 -0.33221435546875 +98738 -0.229400634765625 +98739 -0.27972412109375 +98740 -0.154449462890625 +98741 -0.185333251953125 +98742 -0.10357666015625 +98743 -0.128204345703125 +98744 -0.08245849609375 +98745 -0.115692138671875 +98746 -0.07049560546875 +98747 -0.116455078125 +98748 -0.051666259765625 +98749 -0.105926513671875 +98750 -0.006072998046875 +98751 -0.053955078125 +98752 0.07208251953125 +98753 0.048797607421875 +98754 0.15179443359375 +98755 0.157318115234375 +98756 0.192291259765625 +98757 0.212005615234375 +98758 0.197265625 +98759 0.218475341796875 +98760 0.207916259765625 +98761 0.23724365234375 +98762 0.2496337890625 +98763 0.30535888671875 +98764 0.29449462890625 +98765 0.38128662109375 +98766 0.301727294921875 +98767 0.404449462890625 +98768 0.28515625 +98769 0.3944091796875 +98770 0.270782470703125 +98771 0.3885498046875 +98772 0.24273681640625 +98773 0.362640380859375 +98774 0.172271728515625 +98775 0.27362060546875 +98776 0.056976318359375 +98777 0.11712646484375 +98778 -0.0673828125 +98779 -0.054901123046875 +98780 -0.16534423828125 +98781 -0.19085693359375 +98782 -0.233245849609375 +98783 -0.28570556640625 +98784 -0.270843505859375 +98785 -0.339263916015625 +98786 -0.29583740234375 +98787 -0.3775634765625 +98788 -0.339019775390625 +98789 -0.445709228515625 +98790 -0.394775390625 +98791 -0.535064697265625 +98792 -0.452117919921875 +98793 -0.629058837890625 +98794 -0.490997314453125 +98795 -0.697601318359375 +98796 -0.48687744140625 +98797 -0.70391845703125 +98798 -0.43646240234375 +98799 -0.6424560546875 +98800 -0.32525634765625 +98801 -0.491241455078125 +98802 -0.164215087890625 +98803 -0.265716552734375 +98804 0.00689697265625 +98805 -0.023712158203125 +98806 0.165313720703125 +98807 0.201751708984375 +98808 0.287078857421875 +98809 0.375823974609375 +98810 0.362945556640625 +98811 0.485076904296875 +98812 0.419647216796875 +98813 0.56884765625 +98814 0.462432861328125 +98815 0.634765625 +98816 0.461212158203125 +98817 0.63763427734375 +98818 0.409210205078125 +98819 0.5660400390625 +98820 0.341064453125 +98821 0.4720458984375 +98822 0.290252685546875 +98823 0.40692138671875 +98824 0.26177978515625 +98825 0.3778076171875 +98826 0.251068115234375 +98827 0.376953125 +98828 0.237640380859375 +98829 0.371978759765625 +98830 0.18975830078125 +98831 0.313140869140625 +98832 0.0975341796875 +98833 0.184417724609375 +98834 -0.022125244140625 +98835 0.011199951171875 +98836 -0.1458740234375 +98837 -0.171051025390625 +98838 -0.257293701171875 +98839 -0.33740234375 +98840 -0.345977783203125 +98841 -0.47198486328125 +98842 -0.402557373046875 +98843 -0.560394287109375 +98844 -0.412841796875 +98845 -0.58056640625 +98846 -0.38677978515625 +98847 -0.54754638671875 +98848 -0.35528564453125 +98849 -0.508575439453125 +98850 -0.3160400390625 +98851 -0.459503173828125 +98852 -0.265625 +98853 -0.394378662109375 +98854 -0.230010986328125 +98855 -0.35260009765625 +98856 -0.195098876953125 +98857 -0.31170654296875 +98858 -0.113250732421875 +98859 -0.197418212890625 +98860 0.016265869140625 +98861 -0.007965087890625 +98862 0.1612548828125 +98863 0.207489013671875 +98864 0.29571533203125 +98865 0.409210205078125 +98866 0.403228759765625 +98867 0.57208251953125 +98868 0.4642333984375 +98869 0.66595458984375 +98870 0.45794677734375 +98871 0.65875244140625 +98872 0.3955078125 +98873 0.56744384765625 +98874 0.302642822265625 +98875 0.431396484375 +98876 0.208038330078125 +98877 0.29443359375 +98878 0.128875732421875 +98879 0.182464599609375 +98880 0.044891357421875 +98881 0.06365966796875 +98882 -0.05255126953125 +98883 -0.075958251953125 +98884 -0.132659912109375 +98885 -0.189422607421875 +98886 -0.19195556640625 +98887 -0.271942138671875 +98888 -0.242462158203125 +98889 -0.342529296875 +98890 -0.260009765625 +98891 -0.364166259765625 +98892 -0.238189697265625 +98893 -0.327239990234375 +98894 -0.20623779296875 +98895 -0.2769775390625 +98896 -0.1903076171875 +98897 -0.253692626953125 +98898 -0.181549072265625 +98899 -0.24365234375 +98900 -0.14874267578125 +98901 -0.1983642578125 +98902 -0.091064453125 +98903 -0.116241455078125 +98904 -0.034393310546875 +98905 -0.036834716796875 +98906 0.0177001953125 +98907 0.034881591796875 +98908 0.0599365234375 +98909 0.09124755859375 +98910 0.076904296875 +98911 0.10888671875 +98912 0.092681884765625 +98913 0.125518798828125 +98914 0.117767333984375 +98915 0.15771484375 +98916 0.13433837890625 +98917 0.17828369140625 +98918 0.13177490234375 +98919 0.17108154296875 +98920 0.106048583984375 +98921 0.129974365234375 +98922 0.074920654296875 +98923 0.082427978515625 +98924 0.037994384765625 +98925 0.027679443359375 +98926 -0.024932861328125 +98927 -0.065643310546875 +98928 -0.0889892578125 +98929 -0.15936279296875 +98930 -0.127777099609375 +98931 -0.21307373046875 +98932 -0.14617919921875 +98933 -0.234649658203125 +98934 -0.12847900390625 +98935 -0.2001953125 +98936 -0.08050537109375 +98937 -0.119171142578125 +98938 -0.0235595703125 +98939 -0.024749755859375 +98940 0.04437255859375 +98941 0.085784912109375 +98942 0.101226806640625 +98943 0.178131103515625 +98944 0.123382568359375 +98945 0.215576171875 +98946 0.119537353515625 +98947 0.211456298828125 +98948 0.09588623046875 +98949 0.17523193359375 +98950 0.066558837890625 +98951 0.128753662109375 +98952 0.05084228515625 +98953 0.1019287109375 +98954 0.035430908203125 +98955 0.0743408203125 +98956 0.01837158203125 +98957 0.04327392578125 +98958 0.01861572265625 +98959 0.038177490234375 +98960 0.047088623046875 +98961 0.076263427734375 +98962 0.0928955078125 +98963 0.14105224609375 +98964 0.12591552734375 +98965 0.186431884765625 +98966 0.13067626953125 +98967 0.188812255859375 +98968 0.101104736328125 +98969 0.1390380859375 +98970 0.040069580078125 +98971 0.041778564453125 +98972 -0.0372314453125 +98973 -0.079437255859375 +98974 -0.12750244140625 +98975 -0.219390869140625 +98976 -0.224029541015625 +98977 -0.367828369140625 +98978 -0.30743408203125 +98979 -0.494873046875 +98980 -0.348968505859375 +98981 -0.556243896484375 +98982 -0.32049560546875 +98983 -0.508697509765625 +98984 -0.23699951171875 +98985 -0.3756103515625 +98986 -0.13848876953125 +98987 -0.218902587890625 +98988 -0.04107666015625 +98989 -0.063751220703125 +98990 0.056488037109375 +98991 0.091552734375 +98992 0.14727783203125 +98993 0.23602294921875 +98994 0.214141845703125 +98995 0.342987060546875 +98996 0.246063232421875 +98997 0.39520263671875 +98998 0.240997314453125 +98999 0.389373779296875 +99000 0.19818115234375 +99001 0.324249267578125 +99002 0.133331298828125 +99003 0.224090576171875 +99004 0.0693359375 +99005 0.124267578125 +99006 0.01409912109375 +99007 0.037078857421875 +99008 -0.014678955078125 +99009 -0.010101318359375 +99010 -0.0185546875 +99011 -0.019439697265625 +99012 -0.018280029296875 +99013 -0.022796630859375 +99014 -0.001953125 +99015 -0.001556396484375 +99016 0.038055419921875 +99017 0.056304931640625 +99018 0.07305908203125 +99019 0.106719970703125 +99020 0.068756103515625 +99021 0.096893310546875 +99022 0.035308837890625 +99023 0.042694091796875 +99024 -0.002838134765625 +99025 -0.018035888671875 +99026 -0.03961181640625 +99027 -0.07586669921875 +99028 -0.06768798828125 +99029 -0.11944580078125 +99030 -0.094146728515625 +99031 -0.15972900390625 +99032 -0.122772216796875 +99033 -0.202606201171875 +99034 -0.15380859375 +99035 -0.24859619140625 +99036 -0.1920166015625 +99037 -0.30517578125 +99038 -0.230743408203125 +99039 -0.36212158203125 +99040 -0.251708984375 +99041 -0.39141845703125 +99042 -0.23028564453125 +99043 -0.35528564453125 +99044 -0.163970947265625 +99045 -0.249969482421875 +99046 -0.06396484375 +99047 -0.092864990234375 +99048 0.0523681640625 +99049 0.08905029296875 +99050 0.145904541015625 +99051 0.2352294921875 +99052 0.199249267578125 +99053 0.318817138671875 +99054 0.22467041015625 +99055 0.358642578125 +99056 0.2176513671875 +99057 0.347747802734375 +99058 0.1778564453125 +99059 0.28564453125 +99060 0.138214111328125 +99061 0.223175048828125 +99062 0.122222900390625 +99063 0.196746826171875 +99064 0.1126708984375 +99065 0.179840087890625 +99066 0.0985107421875 +99067 0.155548095703125 +99068 0.097381591796875 +99069 0.151214599609375 +99070 0.102783203125 +99071 0.156951904296875 +99072 0.08819580078125 +99073 0.13177490234375 +99074 0.069366455078125 +99075 0.100799560546875 +99076 0.06103515625 +99077 0.087127685546875 +99078 0.040924072265625 +99079 0.05487060546875 +99080 0.000885009765625 +99081 -0.009002685546875 +99082 -0.0587158203125 +99083 -0.10400390625 +99084 -0.137420654296875 +99085 -0.229400634765625 +99086 -0.216888427734375 +99087 -0.35552978515625 +99088 -0.272064208984375 +99089 -0.441925048828125 +99090 -0.293792724609375 +99091 -0.473846435546875 +99092 -0.29022216796875 +99093 -0.464813232421875 +99094 -0.26385498046875 +99095 -0.419097900390625 +99096 -0.213104248046875 +99097 -0.334320068359375 +99098 -0.14862060546875 +99099 -0.227935791015625 +99100 -0.084869384765625 +99101 -0.12347412109375 +99102 -0.02593994140625 +99103 -0.02764892578125 +99104 0.039337158203125 +99105 0.077667236328125 +99106 0.12371826171875 +99107 0.2132568359375 +99108 0.233154296875 +99109 0.38885498046875 +99110 0.354217529296875 +99111 0.582794189453125 +99112 0.44921875 +99113 0.734039306640625 +99114 0.49188232421875 +99115 0.800140380859375 +99116 0.480377197265625 +99117 0.7783203125 +99118 0.412506103515625 +99119 0.6651611328125 +99120 0.287567138671875 +99121 0.45965576171875 +99122 0.128509521484375 +99123 0.199188232421875 +99124 -0.024383544921875 +99125 -0.050689697265625 +99126 -0.13604736328125 +99127 -0.23297119140625 +99128 -0.195709228515625 +99129 -0.33013916015625 +99130 -0.219482421875 +99131 -0.368408203125 +99132 -0.226531982421875 +99133 -0.378936767578125 +99134 -0.22625732421875 +99135 -0.376983642578125 +99136 -0.229156494140625 +99137 -0.37969970703125 +99138 -0.237884521484375 +99139 -0.391510009765625 +99140 -0.235687255859375 +99141 -0.385345458984375 +99142 -0.2105712890625 +99143 -0.3419189453125 +99144 -0.175811767578125 +99145 -0.28289794921875 +99146 -0.15802001953125 +99147 -0.251617431640625 +99148 -0.168212890625 +99149 -0.266143798828125 +99150 -0.17364501953125 +99151 -0.273345947265625 +99152 -0.13946533203125 +99153 -0.216796875 +99154 -0.085205078125 +99155 -0.128265380859375 +99156 -0.048095703125 +99157 -0.068145751953125 +99158 -0.0322265625 +99159 -0.0430908203125 +99160 -0.02001953125 +99161 -0.024444580078125 +99162 0.0087890625 +99163 0.020721435546875 +99164 0.073883056640625 +99165 0.124481201171875 +99166 0.1573486328125 +99167 0.25787353515625 +99168 0.23333740234375 +99169 0.379119873046875 +99170 0.296722412109375 +99171 0.47991943359375 +99172 0.32763671875 +99173 0.5281982421875 +99174 0.318145751953125 +99175 0.511138916015625 +99176 0.285125732421875 +99177 0.456207275390625 +99178 0.255706787109375 +99179 0.407470703125 +99180 0.241424560546875 +99181 0.383758544921875 +99182 0.224884033203125 +99183 0.35687255859375 +99184 0.1968994140625 +99185 0.31182861328125 +99186 0.158843994140625 +99187 0.250885009765625 +99188 0.105438232421875 +99189 0.1654052734375 +99190 0.02435302734375 +99191 0.035247802734375 +99192 -0.085906982421875 +99193 -0.142059326171875 +99194 -0.20623779296875 +99195 -0.33563232421875 +99196 -0.329803466796875 +99197 -0.5345458984375 +99198 -0.446136474609375 +99199 -0.72186279296875 +99200 -0.5177001953125 +99201 -0.836669921875 +99202 -0.515899658203125 +99203 -0.8326416015625 +99204 -0.452911376953125 +99205 -0.7296142578125 +99206 -0.36260986328125 +99207 -0.582550048828125 +99208 -0.274932861328125 +99209 -0.440093994140625 +99210 -0.203460693359375 +99211 -0.324310302734375 +99212 -0.12744140625 +99213 -0.20147705078125 +99214 -0.0302734375 +99215 -0.044647216796875 +99216 0.061981201171875 +99217 0.103973388671875 +99218 0.1234130859375 +99219 0.202392578125 +99220 0.16253662109375 +99221 0.264495849609375 +99222 0.209228515625 +99223 0.338897705078125 +99224 0.274658203125 +99225 0.443817138671875 +99226 0.337738037109375 +99227 0.545074462890625 +99228 0.382781982421875 +99229 0.6173095703125 +99230 0.40484619140625 +99231 0.6524658203125 +99232 0.41180419921875 +99233 0.66339111328125 +99234 0.4073486328125 +99235 0.6561279296875 +99236 0.376800537109375 +99237 0.606781005859375 +99238 0.311431884765625 +99239 0.501190185546875 +99240 0.21954345703125 +99241 0.352783203125 +99242 0.110382080078125 +99243 0.176544189453125 +99244 -0.020477294921875 +99245 -0.034820556640625 +99246 -0.15875244140625 +99247 -0.258209228515625 +99248 -0.27288818359375 +99249 -0.44244384765625 +99250 -0.355316162109375 +99251 -0.5753173828125 +99252 -0.403076171875 +99253 -0.65203857421875 +99254 -0.397064208984375 +99255 -0.641632080078125 +99256 -0.348388671875 +99257 -0.562164306640625 +99258 -0.284393310546875 +99259 -0.458038330078125 +99260 -0.21820068359375 +99261 -0.350555419921875 +99262 -0.162628173828125 +99263 -0.260528564453125 +99264 -0.120269775390625 +99265 -0.192108154296875 +99266 -0.08905029296875 +99267 -0.141937255859375 +99268 -0.06414794921875 +99269 -0.1021728515625 +99270 -0.03948974609375 +99271 -0.062896728515625 +99272 -0.007568359375 +99273 -0.011932373046875 +99274 0.03900146484375 +99275 0.062835693359375 +99276 0.0924072265625 +99277 0.148712158203125 +99278 0.150146484375 +99279 0.241729736328125 +99280 0.2166748046875 +99281 0.34912109375 +99282 0.283599853515625 +99283 0.457305908203125 +99284 0.33709716796875 +99285 0.54388427734375 +99286 0.355010986328125 +99287 0.5728759765625 +99288 0.31414794921875 +99289 0.506591796875 +99290 0.218292236328125 +99291 0.351226806640625 +99292 0.0919189453125 +99293 0.146514892578125 +99294 -0.032684326171875 +99295 -0.05523681640625 +99296 -0.132232666015625 +99297 -0.21624755859375 +99298 -0.205718994140625 +99299 -0.334930419921875 +99300 -0.248016357421875 +99301 -0.402984619140625 +99302 -0.27197265625 +99303 -0.4412841796875 +99304 -0.305908203125 +99305 -0.49578857421875 +99306 -0.345855712890625 +99307 -0.5601806640625 +99308 -0.371063232421875 +99309 -0.600738525390625 +99310 -0.361053466796875 +99311 -0.584228515625 +99312 -0.2965087890625 +99313 -0.47930908203125 +99314 -0.173370361328125 +99315 -0.27935791015625 +99316 -0.006744384765625 +99317 -0.0089111328125 +99318 0.164398193359375 +99319 0.268798828125 +99320 0.29638671875 +99321 0.482818603515625 +99322 0.371063232421875 +99323 0.60369873046875 +99324 0.40008544921875 +99325 0.650421142578125 +99326 0.408721923828125 +99327 0.66400146484375 +99328 0.395355224609375 +99329 0.6414794921875 +99330 0.353546142578125 +99331 0.572540283203125 +99332 0.307373046875 +99333 0.498138427734375 +99334 0.26947021484375 +99335 0.439453125 +99336 0.227874755859375 +99337 0.375518798828125 +99338 0.164276123046875 +99339 0.274505615234375 +99340 0.06280517578125 +99341 0.1087646484375 +99342 -0.063201904296875 +99343 -0.099395751953125 +99344 -0.1949462890625 +99345 -0.3182373046875 +99346 -0.33294677734375 +99347 -0.5489501953125 +99348 -0.4666748046875 +99349 -0.7738037109375 +99350 -0.56512451171875 +99351 -0.86383056640625 +99352 -0.60882568359375 +99353 -0.870391845703125 +99354 -0.608154296875 +99355 -0.86895751953125 +99356 -0.570831298828125 +99357 -0.861053466796875 +99358 -0.486846923828125 +99359 -0.765869140625 +99360 -0.349761962890625 +99361 -0.5301513671875 +99362 -0.163909912109375 +99363 -0.214691162109375 +99364 0.045379638671875 +99365 0.137359619140625 +99366 0.2479248046875 +99367 0.474822998046875 +99368 0.422760009765625 +99369 0.76239013671875 +99370 0.553924560546875 +99371 0.867462158203125 +99372 0.641510009765625 +99373 0.870361328125 +99374 0.678619384765625 +99375 0.86480712890625 +99376 0.668304443359375 +99377 0.831817626953125 +99378 0.624725341796875 +99379 0.677581787109375 +99380 0.55126953125 +99381 0.495880126953125 +99382 0.458831787109375 +99383 0.30767822265625 +99384 0.3487548828125 +99385 0.116180419921875 +99386 0.20263671875 +99387 -0.110748291015625 +99388 0.01654052734375 +99389 -0.381805419921875 +99390 -0.184326171875 +99391 -0.6572265625 +99392 -0.364837646484375 +99393 -0.857421875 +99394 -0.499755859375 +99395 -0.870391845703125 +99396 -0.584747314453125 +99397 -0.870391845703125 +99398 -0.635406494140625 +99399 -0.86444091796875 +99400 -0.67242431640625 +99401 -0.85723876953125 +99402 -0.68499755859375 +99403 -0.790008544921875 +99404 -0.641387939453125 +99405 -0.62847900390625 +99406 -0.539703369140625 +99407 -0.3956298828125 +99408 -0.39910888671875 +99409 -0.126708984375 +99410 -0.23565673828125 +99411 0.150115966796875 +99412 -0.0562744140625 +99413 0.424041748046875 +99414 0.123138427734375 +99415 0.670623779296875 +99416 0.279815673828125 +99417 0.854522705078125 +99418 0.403289794921875 +99419 0.866485595703125 +99420 0.48443603515625 +99421 0.86920166015625 +99422 0.53369140625 +99423 0.8653564453125 +99424 0.558746337890625 +99425 0.857147216796875 +99426 0.55780029296875 +99427 0.766845703125 +99428 0.533721923828125 +99429 0.628509521484375 +99430 0.482513427734375 +99431 0.462127685546875 +99432 0.41925048828125 +99433 0.297210693359375 +99434 0.351165771484375 +99435 0.14862060546875 +99436 0.26495361328125 +99437 -0.00537109375 +99438 0.16510009765625 +99439 -0.15753173828125 +99440 0.049560546875 +99441 -0.31304931640625 +99442 -0.0897216796875 +99443 -0.48876953125 +99444 -0.2252197265625 +99445 -0.6416015625 +99446 -0.34234619140625 +99447 -0.751373291015625 +99448 -0.4544677734375 +99449 -0.84619140625 +99450 -0.5528564453125 +99451 -0.861297607421875 +99452 -0.6180419921875 +99453 -0.863250732421875 +99454 -0.631500244140625 +99455 -0.856597900390625 +99456 -0.60028076171875 +99457 -0.7498779296875 +99458 -0.558135986328125 +99459 -0.624542236328125 +99460 -0.492218017578125 +99461 -0.47808837890625 +99462 -0.368408203125 +99463 -0.253387451171875 +99464 -0.21343994140625 +99465 0.003692626953125 +99466 -0.06732177734375 +99467 0.2257080078125 +99468 0.077178955078125 +99469 0.427154541015625 +99470 0.23883056640625 +99471 0.643218994140625 +99472 0.411865234375 +99473 0.855926513671875 +99474 0.56231689453125 +99475 0.870361328125 +99476 0.66107177734375 +99477 0.870361328125 +99478 0.712188720703125 +99479 0.862762451171875 +99480 0.7138671875 +99481 0.79669189453125 +99482 0.6605224609375 +99483 0.595794677734375 +99484 0.5692138671875 +99485 0.362152099609375 +99486 0.456298828125 +99487 0.1270751953125 +99488 0.33416748046875 +99489 -0.086944580078125 +99490 0.2041015625 +99491 -0.2784423828125 +99492 0.04583740234375 +99493 -0.484832763671875 +99494 -0.15167236328125 +99495 -0.729583740234375 +99496 -0.358734130859375 +99497 -0.86688232421875 +99498 -0.538238525390625 +99499 -0.870391845703125 +99500 -0.687103271484375 +99501 -0.86859130859375 +99502 -0.803955078125 +99503 -0.86279296875 +99504 -0.85595703125 +99505 -0.817962646484375 +99506 -0.851593017578125 +99507 -0.6116943359375 +99508 -0.751495361328125 +99509 -0.3128662109375 +99510 -0.5870361328125 +99511 0.039398193359375 +99512 -0.369903564453125 +99513 0.422821044921875 +99514 -0.119598388671875 +99515 0.805145263671875 +99516 0.1240234375 +99517 0.870361328125 +99518 0.3275146484375 +99519 0.870361328125 +99520 0.48382568359375 +99521 0.860015869140625 +99522 0.588226318359375 +99523 0.727935791015625 +99524 0.637176513671875 +99525 0.48114013671875 +99526 0.644561767578125 +99527 0.2059326171875 +99528 0.62335205078125 +99529 -0.06103515625 +99530 0.579193115234375 +99531 -0.29913330078125 +99532 0.503448486328125 +99533 -0.516204833984375 +99534 0.3870849609375 +99535 -0.7252197265625 +99536 0.24462890625 +99537 -0.85980224609375 +99538 0.096221923828125 +99539 -0.870391845703125 +99540 -0.0406494140625 +99541 -0.870391845703125 +99542 -0.13726806640625 +99543 -0.858062744140625 +99544 -0.190826416015625 +99545 -0.673004150390625 +99546 -0.231597900390625 +99547 -0.42694091796875 +99548 -0.285125732421875 +99549 -0.2100830078125 +99550 -0.3497314453125 +99551 -0.0362548828125 +99552 -0.4080810546875 +99553 0.10943603515625 +99554 -0.448211669921875 +99555 0.23516845703125 +99556 -0.4456787109375 +99557 0.373687744140625 +99558 -0.40142822265625 +99559 0.517791748046875 +99560 -0.352142333984375 +99561 0.602783203125 +99562 -0.294830322265625 +99563 0.635711669921875 +99564 -0.21014404296875 +99565 0.655181884765625 +99566 -0.104095458984375 +99567 0.65948486328125 +99568 0.018341064453125 +99569 0.651275634765625 +99570 0.142486572265625 +99571 0.61846923828125 +99572 0.246307373046875 +99573 0.53753662109375 +99574 0.318817138671875 +99575 0.404144287109375 +99576 0.353912353515625 +99577 0.22186279296875 +99578 0.351959228515625 +99579 0.003997802734375 +99580 0.32318115234375 +99581 -0.22100830078125 +99582 0.279327392578125 +99583 -0.42449951171875 +99584 0.23236083984375 +99585 -0.579833984375 +99586 0.206451416015625 +99587 -0.641876220703125 +99588 0.19830322265625 +99589 -0.6177978515625 +99590 0.17205810546875 +99591 -0.575531005859375 +99592 0.124725341796875 +99593 -0.526336669921875 +99594 0.084991455078125 +99595 -0.42645263671875 +99596 0.068267822265625 +99597 -0.2581787109375 +99598 0.0548095703125 +99599 -0.068695068359375 +99600 0.023773193359375 +99601 0.09222412109375 +99602 -0.014068603515625 +99603 0.232147216796875 +99604 -0.052642822265625 +99605 0.3509521484375 +99606 -0.107879638671875 +99607 0.410064697265625 +99608 -0.19561767578125 +99609 0.372955322265625 +99610 -0.303955078125 +99611 0.2554931640625 +99612 -0.4039306640625 +99613 0.10711669921875 +99614 -0.484588623046875 +99615 -0.052886962890625 +99616 -0.52593994140625 +99617 -0.186279296875 +99618 -0.497314453125 +99619 -0.23291015625 +99620 -0.411468505859375 +99621 -0.209442138671875 +99622 -0.3050537109375 +99623 -0.174163818359375 +99624 -0.183013916015625 +99625 -0.126739501953125 +99626 -0.040313720703125 +99627 -0.048126220703125 +99628 0.106964111328125 +99629 0.0426025390625 +99630 0.232635498046875 +99631 0.10748291015625 +99632 0.32891845703125 +99633 0.1409912109375 +99634 0.4217529296875 +99635 0.19708251953125 +99636 0.507049560546875 +99637 0.273651123046875 +99638 0.553741455078125 +99639 0.31768798828125 +99640 0.567779541015625 +99641 0.341094970703125 +99642 0.56304931640625 +99643 0.368011474609375 +99644 0.526885986328125 +99645 0.37249755859375 +99646 0.432220458984375 +99647 0.30072021484375 +99648 0.282012939453125 +99649 0.1517333984375 +99650 0.113311767578125 +99651 -0.01470947265625 +99652 -0.063751220703125 +99653 -0.1883544921875 +99654 -0.24658203125 +99655 -0.372711181640625 +99656 -0.401092529296875 +99657 -0.51397705078125 +99658 -0.50091552734375 +99659 -0.57177734375 +99660 -0.5389404296875 +99661 -0.53948974609375 +99662 -0.52239990234375 +99663 -0.43511962890625 +99664 -0.470245361328125 +99665 -0.2962646484375 +99666 -0.4027099609375 +99667 -0.161102294921875 +99668 -0.32757568359375 +99669 -0.0435791015625 +99670 -0.24365234375 +99671 0.060394287109375 +99672 -0.16064453125 +99673 0.13665771484375 +99674 -0.089508056640625 +99675 0.170135498046875 +99676 -0.0308837890625 +99677 0.16552734375 +99678 0.0306396484375 +99679 0.15728759765625 +99680 0.09429931640625 +99681 0.150787353515625 +99682 0.14312744140625 +99683 0.12200927734375 +99684 0.1787109375 +99685 0.080108642578125 +99686 0.212493896484375 +99687 0.05126953125 +99688 0.25714111328125 +99689 0.062896728515625 +99690 0.298583984375 +99691 0.09271240234375 +99692 0.309539794921875 +99693 0.092987060546875 +99694 0.2979736328125 +99695 0.07855224609375 +99696 0.272735595703125 +99697 0.06427001953125 +99698 0.2266845703125 +99699 0.0347900390625 +99700 0.1607666015625 +99701 -0.01171875 +99702 0.08807373046875 +99703 -0.056060791015625 +99704 0.0350341796875 +99705 -0.055511474609375 +99706 0.0045166015625 +99707 -0.010467529296875 +99708 -0.030181884765625 +99709 0.02508544921875 +99710 -0.0802001953125 +99711 0.025665283203125 +99712 -0.128509521484375 +99713 0.017333984375 +99714 -0.17193603515625 +99715 0.00189208984375 +99716 -0.214935302734375 +99717 -0.03173828125 +99718 -0.249847412109375 +99719 -0.071502685546875 +99720 -0.2862548828125 +99721 -0.13543701171875 +99722 -0.322479248046875 +99723 -0.219970703125 +99724 -0.3458251953125 +99725 -0.300506591796875 +99726 -0.357330322265625 +99727 -0.376312255859375 +99728 -0.341644287109375 +99729 -0.416107177734375 +99730 -0.27410888671875 +99731 -0.371124267578125 +99732 -0.157745361328125 +99733 -0.242279052734375 +99734 -0.017242431640625 +99735 -0.069732666015625 +99736 0.133392333984375 +99737 0.125640869140625 +99738 0.274688720703125 +99739 0.31268310546875 +99740 0.3846435546875 +99741 0.45501708984375 +99742 0.462921142578125 +99743 0.554779052734375 +99744 0.507781982421875 +99745 0.61065673828125 +99746 0.512237548828125 +99747 0.610931396484375 +99748 0.4630126953125 +99749 0.531463623046875 +99750 0.36956787109375 +99751 0.3883056640625 +99752 0.262298583984375 +99753 0.23468017578125 +99754 0.15631103515625 +99755 0.095245361328125 +99756 0.06768798828125 +99757 -0.00396728515625 +99758 0.006378173828125 +99759 -0.04852294921875 +99760 -0.03472900390625 +99761 -0.055145263671875 +99762 -0.082275390625 +99763 -0.0758056640625 +99764 -0.149871826171875 +99765 -0.138702392578125 +99766 -0.216705322265625 +99767 -0.209197998046875 +99768 -0.2823486328125 +99769 -0.289031982421875 +99770 -0.346160888671875 +99771 -0.37884521484375 +99772 -0.395263671875 +99773 -0.456329345703125 +99774 -0.4267578125 +99775 -0.51641845703125 +99776 -0.418975830078125 +99777 -0.519287109375 +99778 -0.368988037109375 +99779 -0.458251953125 +99780 -0.3062744140625 +99781 -0.384796142578125 +99782 -0.245880126953125 +99783 -0.323699951171875 +99784 -0.186248779296875 +99785 -0.269287109375 +99786 -0.114532470703125 +99787 -0.1951904296875 +99788 -0.03167724609375 +99789 -0.100006103515625 +99790 0.04583740234375 +99791 -0.01055908203125 +99792 0.13323974609375 +99793 0.1033935546875 +99794 0.233306884765625 +99795 0.24908447265625 +99796 0.315673828125 +99797 0.373199462890625 +99798 0.370025634765625 +99799 0.45806884765625 +99800 0.400390625 +99801 0.511474609375 +99802 0.424591064453125 +99803 0.565399169921875 +99804 0.43841552734375 +99805 0.61138916015625 +99806 0.40972900390625 +99807 0.5897216796875 +99808 0.334136962890625 +99809 0.4906005859375 +99810 0.222564697265625 +99811 0.33148193359375 +99812 0.095947265625 +99813 0.147796630859375 +99814 -0.021240234375 +99815 -0.01873779296875 +99816 -0.112274169921875 +99817 -0.140289306640625 +99818 -0.162139892578125 +99819 -0.191986083984375 +99820 -0.175537109375 +99821 -0.184295654296875 +99822 -0.176239013671875 +99823 -0.161834716796875 +99824 -0.18682861328125 +99825 -0.166595458984375 +99826 -0.204437255859375 +99827 -0.19390869140625 +99828 -0.218414306640625 +99829 -0.22442626953125 +99830 -0.240997314453125 +99831 -0.279754638671875 +99832 -0.26123046875 +99833 -0.3389892578125 +99834 -0.253570556640625 +99835 -0.3543701171875 +99836 -0.231292724609375 +99837 -0.348175048828125 +99838 -0.198577880859375 +99839 -0.32598876953125 +99840 -0.1402587890625 +99841 -0.2581787109375 +99842 -0.054779052734375 +99843 -0.139801025390625 +99844 0.04876708984375 +99845 0.014617919921875 +99846 0.135955810546875 +99847 0.144378662109375 +99848 0.1904296875 +99849 0.221038818359375 +99850 0.225921630859375 +99851 0.27069091796875 +99852 0.24249267578125 +99853 0.294036865234375 +99854 0.25146484375 +99855 0.311767578125 +99856 0.261322021484375 +99857 0.339141845703125 +99858 0.263336181640625 +99859 0.360260009765625 +99860 0.250213623046875 +99861 0.360504150390625 +99862 0.20654296875 +99863 0.308380126953125 +99864 0.121856689453125 +99865 0.18170166015625 +99866 0.010009765625 +99867 0.0047607421875 +99868 -0.10345458984375 +99869 -0.17559814453125 +99870 -0.194000244140625 +99871 -0.3143310546875 +99872 -0.238006591796875 +99873 -0.36785888671875 +99874 -0.248321533203125 +99875 -0.36248779296875 +99876 -0.247894287109375 +99877 -0.343536376953125 +99878 -0.2315673828125 +99879 -0.3018798828125 +99880 -0.19598388671875 +99881 -0.231414794921875 +99882 -0.133697509765625 +99883 -0.117645263671875 +99884 -0.06182861328125 +99885 0.007049560546875 +99886 -0.009307861328125 +99887 0.087982177734375 +99888 0.030609130859375 +99889 0.13946533203125 +99890 0.06378173828125 +99891 0.17425537109375 +99892 0.087158203125 +99893 0.188201904296875 +99894 0.094573974609375 +99895 0.171234130859375 +99896 0.08258056640625 +99897 0.118438720703125 +99898 0.064544677734375 +99899 0.05706787109375 +99900 0.040863037109375 +99901 -0.010711669921875 +99902 0.007568359375 +99903 -0.0914306640625 +99904 -0.023834228515625 +99905 -0.162322998046875 +99906 -0.03857421875 +99907 -0.194549560546875 +99908 -0.0164794921875 +99909 -0.1492919921875 +99910 0.045135498046875 +99911 -0.02166748046875 +99912 0.11322021484375 +99913 0.124053955078125 +99914 0.14837646484375 +99915 0.211151123046875 +99916 0.151641845703125 +99917 0.240447998046875 +99918 0.13946533203125 +99919 0.242218017578125 +99920 0.117431640625 +99921 0.2257080078125 +99922 0.08807373046875 +99923 0.194366455078125 +99924 0.03509521484375 +99925 0.115509033203125 +99926 -0.028533935546875 +99927 0.0128173828125 +99928 -0.0711669921875 +99929 -0.053802490234375 +99930 -0.1060791015625 +99931 -0.110626220703125 +99932 -0.15484619140625 +99933 -0.199493408203125 +99934 -0.203887939453125 +99935 -0.29437255859375 +99936 -0.220458984375 +99937 -0.33221435546875 +99938 -0.187530517578125 +99939 -0.27972412109375 +99940 -0.13067626953125 +99941 -0.185333251953125 +99942 -0.091522216796875 +99943 -0.128204345703125 +99944 -0.074462890625 +99945 -0.115692138671875 +99946 -0.0638427734375 +99947 -0.116455078125 +99948 -0.047454833984375 +99949 -0.105926513671875 +99950 -0.01025390625 +99951 -0.053955078125 +99952 0.052093505859375 +99953 0.048797607421875 +99954 0.115753173828125 +99955 0.157318115234375 +99956 0.14935302734375 +99957 0.212005615234375 +99958 0.155609130859375 +99959 0.218475341796875 +99960 0.165863037109375 +99961 0.23724365234375 +99962 0.199432373046875 +99963 0.30535888671875 +99964 0.234893798828125 +99965 0.38128662109375 +99966 0.24102783203125 +99967 0.404449462890625 +99968 0.228363037109375 +99969 0.3944091796875 +99970 0.216827392578125 +99971 0.3885498046875 +99972 0.194305419921875 +99973 0.362640380859375 +99974 0.138916015625 +99975 0.27362060546875 +99976 0.04888916015625 +99977 0.11712646484375 +99978 -0.04827880859375 +99979 -0.054901123046875 +99980 -0.125335693359375 +99981 -0.19085693359375 +99982 -0.17938232421875 +99983 -0.28570556640625 +99984 -0.21014404296875 +99985 -0.339263916015625 +99986 -0.23101806640625 +99987 -0.3775634765625 +99988 -0.2655029296875 +99989 -0.445709228515625 +99990 -0.309173583984375 +99991 -0.535064697265625 +99992 -0.3536376953125 +99993 -0.629058837890625 +99994 -0.383514404296875 +99995 -0.697601318359375 +99996 -0.38006591796875 +99997 -0.70391845703125 +99998 -0.340789794921875 +99999 -0.6424560546875 +100000 -0.254669189453125 +100001 -0.491241455078125 +100002 -0.130157470703125 +100003 -0.265716552734375 +100004 0.00225830078125 +100005 -0.023712158203125 +100006 0.125091552734375 +100007 0.201751708984375 +100008 0.219940185546875 +100009 0.375823974609375 +100010 0.27960205078125 +100011 0.485076904296875 +100012 0.324432373046875 +100013 0.56884765625 +100014 0.3583984375 +100015 0.634765625 +100016 0.3580322265625 +100017 0.63763427734375 +100018 0.317535400390625 +100019 0.5660400390625 +100020 0.26422119140625 +100021 0.4720458984375 +100022 0.225006103515625 +100023 0.40692138671875 +100024 0.203948974609375 +100025 0.3778076171875 +100026 0.197357177734375 +100027 0.376953125 +100028 0.188720703125 +100029 0.371978759765625 +100030 0.15252685546875 +100031 0.313140869140625 +100032 0.0806884765625 +100033 0.184417724609375 +100034 -0.0133056640625 +100035 0.011199951171875 +100036 -0.110809326171875 +100037 -0.171051025390625 +100038 -0.198760986328125 +100039 -0.33740234375 +100040 -0.268829345703125 +100041 -0.47198486328125 +100042 -0.3135986328125 +100043 -0.560394287109375 +100044 -0.321685791015625 +100045 -0.58056640625 +100046 -0.30108642578125 +100047 -0.54754638671875 +100048 -0.276580810546875 +100049 -0.508575439453125 +100050 -0.24627685546875 +100051 -0.459503173828125 +100052 -0.207366943359375 +100053 -0.394378662109375 +100054 -0.18060302734375 +100055 -0.35260009765625 +100056 -0.154571533203125 +100057 -0.31170654296875 +100058 -0.090911865234375 +100059 -0.197418212890625 +100060 0.01104736328125 +100061 -0.007965087890625 +100062 0.125579833984375 +100063 0.207489013671875 +100064 0.23193359375 +100065 0.409210205078125 +100066 0.3170166015625 +100067 0.57208251953125 +100068 0.365142822265625 +100069 0.66595458984375 +100070 0.359710693359375 +100071 0.65875244140625 +100072 0.30963134765625 +100073 0.56744384765625 +100074 0.235565185546875 +100075 0.431396484375 +100076 0.1605224609375 +100077 0.29443359375 +100078 0.098175048828125 +100079 0.182464599609375 +100080 0.0322265625 +100081 0.06365966796875 +100082 -0.044342041015625 +100083 -0.075958251953125 +100084 -0.10693359375 +100085 -0.189422607421875 +100086 -0.152862548828125 +100087 -0.271942138671875 +100088 -0.19183349609375 +100089 -0.342529296875 +100090 -0.204559326171875 +100091 -0.364166259765625 +100092 -0.18597412109375 +100093 -0.327239990234375 +100094 -0.159576416015625 +100095 -0.2769775390625 +100096 -0.146087646484375 +100097 -0.253692626953125 +100098 -0.138702392578125 +100099 -0.24365234375 +100100 -0.1134033203125 +100101 -0.1983642578125 +100102 -0.069488525390625 +100103 -0.116241455078125 +100104 -0.026336669921875 +100105 -0.036834716796875 +100106 0.013427734375 +100107 0.034881591796875 +100108 0.04583740234375 +100109 0.09124755859375 +100110 0.059234619140625 +100111 0.10888671875 +100112 0.071746826171875 +100113 0.125518798828125 +100114 0.09124755859375 +100115 0.15771484375 +100116 0.104248046875 +100117 0.17828369140625 +100118 0.10272216796875 +100119 0.17108154296875 +100120 0.083587646484375 +100121 0.129974365234375 +100122 0.060211181640625 +100123 0.082427978515625 +100124 0.032257080078125 +100125 0.027679443359375 +100126 -0.015472412109375 +100127 -0.065643310546875 +100128 -0.064178466796875 +100129 -0.15936279296875 +100130 -0.093994140625 +100131 -0.21307373046875 +100132 -0.108551025390625 +100133 -0.234649658203125 +100134 -0.095947265625 +100135 -0.2001953125 +100136 -0.060577392578125 +100137 -0.119171142578125 +100138 -0.018402099609375 +100139 -0.024749755859375 +100140 0.032073974609375 +100141 0.085784912109375 +100142 0.074310302734375 +100143 0.178131103515625 +100144 0.09051513671875 +100145 0.215576171875 +100146 0.0872802734375 +100147 0.211456298828125 +100148 0.06927490234375 +100149 0.17523193359375 +100150 0.04718017578125 +100151 0.128753662109375 +100152 0.0355224609375 +100153 0.1019287109375 +100154 0.02423095703125 +100155 0.0743408203125 +100156 0.0118408203125 +100157 0.04327392578125 +100158 0.012542724609375 +100159 0.038177490234375 +100160 0.034576416015625 +100161 0.076263427734375 +100162 0.069671630859375 +100163 0.14105224609375 +100164 0.09515380859375 +100165 0.186431884765625 +100166 0.099334716796875 +100167 0.188812255859375 +100168 0.07757568359375 +100169 0.1390380859375 +100170 0.03204345703125 +100171 0.041778564453125 +100172 -0.025848388671875 +100173 -0.079437255859375 +100174 -0.093597412109375 +100175 -0.219390869140625 +100176 -0.16619873046875 +100177 -0.367828369140625 +100178 -0.229034423828125 +100179 -0.494873046875 +100180 -0.260467529296875 +100181 -0.556243896484375 +100182 -0.239288330078125 +100183 -0.508697509765625 +100184 -0.176788330078125 +100185 -0.3756103515625 +100186 -0.10302734375 +100187 -0.218902587890625 +100188 -0.030120849609375 +100189 -0.063751220703125 +100190 0.042877197265625 +100191 0.091552734375 +100192 0.110748291015625 +100193 0.23602294921875 +100194 0.160614013671875 +100195 0.342987060546875 +100196 0.1842041015625 +100197 0.39520263671875 +100198 0.17999267578125 +100199 0.389373779296875 +100200 0.147430419921875 +100201 0.324249267578125 +100202 0.098388671875 +100203 0.224090576171875 +100204 0.050140380859375 +100205 0.124267578125 +100206 0.00860595703125 +100207 0.037078857421875 +100208 -0.012908935546875 +100209 -0.010101318359375 +100210 -0.01556396484375 +100211 -0.019439697265625 +100212 -0.0150146484375 +100213 -0.022796630859375 +100214 -0.002288818359375 +100215 -0.001556396484375 +100216 0.0283203125 +100217 0.056304931640625 +100218 0.05517578125 +100219 0.106719970703125 +100220 0.05242919921875 +100221 0.096893310546875 +100222 0.027679443359375 +100223 0.042694091796875 +100224 -0.00067138671875 +100225 -0.018035888671875 +100226 -0.028076171875 +100227 -0.07586669921875 +100228 -0.04901123046875 +100229 -0.11944580078125 +100230 -0.06884765625 +100231 -0.15972900390625 +100232 -0.0904541015625 +100233 -0.202606201171875 +100234 -0.113983154296875 +100235 -0.24859619140625 +100236 -0.143035888671875 +100237 -0.30517578125 +100238 -0.17254638671875 +100239 -0.36212158203125 +100240 -0.188720703125 +100241 -0.39141845703125 +100242 -0.173004150390625 +100243 -0.35528564453125 +100244 -0.12347412109375 +100245 -0.249969482421875 +100246 -0.04852294921875 +100247 -0.092864990234375 +100248 0.03875732421875 +100249 0.08905029296875 +100250 0.10888671875 +100251 0.2352294921875 +100252 0.148834228515625 +100253 0.318817138671875 +100254 0.167816162109375 +100255 0.358642578125 +100256 0.162445068359375 +100257 0.347747802734375 +100258 0.132476806640625 +100259 0.28564453125 +100260 0.102691650390625 +100261 0.223175048828125 +100262 0.090789794921875 +100263 0.196746826171875 +100264 0.08380126953125 +100265 0.179840087890625 +100266 0.073394775390625 +100267 0.155548095703125 +100268 0.07281494140625 +100269 0.151214599609375 +100270 0.0771484375 +100271 0.156951904296875 +100272 0.066314697265625 +100273 0.13177490234375 +100274 0.052520751953125 +100275 0.100799560546875 +100276 0.04693603515625 +100277 0.087127685546875 +100278 0.032012939453125 +100279 0.05487060546875 +100280 0.0013427734375 +100281 -0.009002685546875 +100282 -0.044830322265625 +100283 -0.10400390625 +100284 -0.10614013671875 +100285 -0.229400634765625 +100286 -0.1680908203125 +100287 -0.35552978515625 +100288 -0.210906982421875 +100289 -0.441925048828125 +100290 -0.227386474609375 +100291 -0.473846435546875 +100292 -0.22406005859375 +100293 -0.464813232421875 +100294 -0.202911376953125 +100295 -0.419097900390625 +100296 -0.1627197265625 +100297 -0.334320068359375 +100298 -0.111968994140625 +100299 -0.227935791015625 +100300 -0.06207275390625 +100301 -0.12347412109375 +100302 -0.0162353515625 +100303 -0.02764892578125 +100304 0.034423828125 +100305 0.077667236328125 +100306 0.100067138671875 +100307 0.2132568359375 +100308 0.185455322265625 +100309 0.38885498046875 +100310 0.280029296875 +100311 0.582794189453125 +100312 0.35400390625 +100313 0.734039306640625 +100314 0.38665771484375 +100315 0.800140380859375 +100316 0.3765869140625 +100317 0.7783203125 +100318 0.322113037109375 +100319 0.6651611328125 +100320 0.222686767578125 +100321 0.45965576171875 +100322 0.09649658203125 +100323 0.199188232421875 +100324 -0.024505615234375 +100325 -0.050689697265625 +100326 -0.112548828125 +100327 -0.23297119140625 +100328 -0.159149169921875 +100329 -0.33013916015625 +100330 -0.177093505859375 +100331 -0.368408203125 +100332 -0.181640625 +100333 -0.378936767578125 +100334 -0.1802978515625 +100335 -0.376983642578125 +100336 -0.18145751953125 +100337 -0.37969970703125 +100338 -0.187255859375 +100339 -0.391510009765625 +100340 -0.1844482421875 +100341 -0.385345458984375 +100342 -0.16363525390625 +100343 -0.3419189453125 +100344 -0.1353759765625 +100345 -0.28289794921875 +100346 -0.12078857421875 +100347 -0.251617431640625 +100348 -0.12860107421875 +100349 -0.266143798828125 +100350 -0.13287353515625 +100351 -0.273345947265625 +100352 -0.106170654296875 +100353 -0.216796875 +100354 -0.06365966796875 +100355 -0.128265380859375 +100356 -0.0338134765625 +100357 -0.068145751953125 +100358 -0.019805908203125 +100359 -0.0430908203125 +100360 -0.008697509765625 +100361 -0.024444580078125 +100362 0.01434326171875 +100363 0.020721435546875 +100364 0.06378173828125 +100365 0.124481201171875 +100366 0.126312255859375 +100367 0.25787353515625 +100368 0.182769775390625 +100369 0.379119873046875 +100370 0.229339599609375 +100371 0.47991943359375 +100372 0.251373291015625 +100373 0.5281982421875 +100374 0.243011474609375 +100375 0.511138916015625 +100376 0.216827392578125 +100377 0.456207275390625 +100378 0.193023681640625 +100379 0.407470703125 +100380 0.1802978515625 +100381 0.383758544921875 +100382 0.1658935546875 +100383 0.35687255859375 +100384 0.143096923828125 +100385 0.31182861328125 +100386 0.113037109375 +100387 0.250885009765625 +100388 0.071929931640625 +100389 0.1654052734375 +100390 0.010711669921875 +100391 0.035247802734375 +100392 -0.071624755859375 +100393 -0.142059326171875 +100394 -0.160919189453125 +100395 -0.33563232421875 +100396 -0.252166748046875 +100397 -0.5345458984375 +100398 -0.337615966796875 +100399 -0.72186279296875 +100400 -0.389495849609375 +100401 -0.836669921875 +100402 -0.386749267578125 +100403 -0.8326416015625 +100404 -0.3385009765625 +100405 -0.7296142578125 +100406 -0.2698974609375 +100407 -0.582550048828125 +100408 -0.20318603515625 +100409 -0.440093994140625 +100410 -0.1485595703125 +100411 -0.324310302734375 +100412 -0.0906982421875 +100413 -0.20147705078125 +100414 -0.017425537109375 +100415 -0.044647216796875 +100416 0.051910400390625 +100417 0.103973388671875 +100418 0.098052978515625 +100419 0.202392578125 +100420 0.12725830078125 +100421 0.264495849609375 +100422 0.16168212890625 +100423 0.338897705078125 +100424 0.209625244140625 +100425 0.443817138671875 +100426 0.2554931640625 +100427 0.545074462890625 +100428 0.287750244140625 +100429 0.6173095703125 +100430 0.302764892578125 +100431 0.6524658203125 +100432 0.30645751953125 +100433 0.66339111328125 +100434 0.301666259765625 +100435 0.6561279296875 +100436 0.277587890625 +100437 0.606781005859375 +100438 0.22784423828125 +100439 0.501190185546875 +100440 0.158660888671875 +100441 0.352783203125 +100442 0.076934814453125 +100443 0.176544189453125 +100444 -0.020538330078125 +100445 -0.034820556640625 +100446 -0.1231689453125 +100447 -0.258209228515625 +100448 -0.20758056640625 +100449 -0.44244384765625 +100450 -0.268218994140625 +100451 -0.5753173828125 +100452 -0.30291748046875 +100453 -0.65203857421875 +100454 -0.297576904296875 +100455 -0.641632080078125 +100456 -0.260467529296875 +100457 -0.562164306640625 +100458 -0.2119140625 +100459 -0.458038330078125 +100460 -0.16168212890625 +100461 -0.350555419921875 +100462 -0.11932373046875 +100463 -0.260528564453125 +100464 -0.086822509765625 +100465 -0.192108154296875 +100466 -0.062713623046875 +100467 -0.141937255859375 +100468 -0.043487548828125 +100469 -0.1021728515625 +100470 -0.024658203125 +100471 -0.062896728515625 +100472 -0.000701904296875 +100473 -0.011932373046875 +100474 0.033843994140625 +100475 0.062835693359375 +100476 0.07318115234375 +100477 0.148712158203125 +100478 0.115478515625 +100479 0.241729736328125 +100480 0.164031982421875 +100481 0.34912109375 +100482 0.212677001953125 +100483 0.457305908203125 +100484 0.251251220703125 +100485 0.54388427734375 +100486 0.263427734375 +100487 0.5728759765625 +100488 0.232086181640625 +100489 0.506591796875 +100490 0.16009521484375 +100491 0.351226806640625 +100492 0.065643310546875 +100493 0.146514892578125 +100494 -0.02734375 +100495 -0.05523681640625 +100496 -0.101593017578125 +100497 -0.21624755859375 +100498 -0.156341552734375 +100499 -0.334930419921875 +100500 -0.187774658203125 +100501 -0.402984619140625 +100502 -0.20538330078125 +100503 -0.4412841796875 +100504 -0.230133056640625 +100505 -0.49578857421875 +100506 -0.2591552734375 +100507 -0.5601806640625 +100508 -0.277099609375 +100509 -0.600738525390625 +100510 -0.268829345703125 +100511 -0.584228515625 +100512 -0.220123291015625 +100513 -0.47930908203125 +100514 -0.128021240234375 +100515 -0.27935791015625 +100516 -0.003753662109375 +100517 -0.0089111328125 +100518 0.123748779296875 +100519 0.268798828125 +100520 0.222137451171875 +100521 0.482818603515625 +100522 0.277923583984375 +100523 0.60369873046875 +100524 0.299713134765625 +100525 0.650421142578125 +100526 0.30621337890625 +100527 0.66400146484375 +100528 0.296051025390625 +100529 0.6414794921875 +100530 0.2645263671875 +100531 0.572540283203125 +100532 0.230316162109375 +100533 0.498138427734375 +100534 0.203094482421875 +100535 0.439453125 +100536 0.173370361328125 +100537 0.375518798828125 +100538 0.12664794921875 +100539 0.274505615234375 +100540 0.05035400390625 +100541 0.1087646484375 +100542 -0.0452880859375 +100543 -0.099395751953125 +100544 -0.145782470703125 +100545 -0.3182373046875 +100546 -0.251617431640625 +100547 -0.5489501953125 +100548 -0.35467529296875 +100549 -0.7738037109375 +100550 -0.4307861328125 +100551 -0.86383056640625 +100552 -0.464752197265625 +100553 -0.870391845703125 +100554 -0.46466064453125 +100555 -0.86895751953125 +100556 -0.436492919921875 +100557 -0.861053466796875 +100558 -0.37237548828125 +100559 -0.765869140625 +100560 -0.26715087890625 +100561 -0.5301513671875 +100562 -0.124114990234375 +100563 -0.214691162109375 +100564 0.037078857421875 +100565 0.137359619140625 +100566 0.1929931640625 +100567 0.474822998046875 +100568 0.327362060546875 +100569 0.76239013671875 +100570 0.427825927734375 +100571 0.867462158203125 +100572 0.49456787109375 +100573 0.870361328125 +100574 0.522308349609375 +100575 0.86480712890625 +100576 0.513458251953125 +100577 0.831817626953125 +100578 0.4791259765625 +100579 0.677581787109375 +100580 0.42193603515625 +100581 0.495880126953125 +100582 0.35040283203125 +100583 0.30767822265625 +100584 0.2655029296875 +100585 0.116180419921875 +100586 0.152801513671875 +100587 -0.110748291015625 +100588 0.009185791015625 +100589 -0.381805419921875 +100590 -0.14581298828125 +100591 -0.6572265625 +100592 -0.28485107421875 +100593 -0.857421875 +100594 -0.388336181640625 +100595 -0.870391845703125 +100596 -0.4530029296875 +100597 -0.870391845703125 +100598 -0.4910888671875 +100599 -0.86444091796875 +100600 -0.518829345703125 +100601 -0.85723876953125 +100602 -0.52783203125 +100603 -0.790008544921875 +100604 -0.49334716796875 +100605 -0.62847900390625 +100606 -0.413909912109375 +100607 -0.3956298828125 +100608 -0.3045654296875 +100609 -0.126708984375 +100610 -0.17779541015625 +100611 0.150115966796875 +100612 -0.039276123046875 +100613 0.424041748046875 +100614 0.098876953125 +100615 0.670623779296875 +100616 0.21966552734375 +100617 0.854522705078125 +100618 0.315093994140625 +100619 0.866485595703125 +100620 0.37823486328125 +100621 0.86920166015625 +100622 0.41650390625 +100623 0.8653564453125 +100624 0.4354248046875 +100625 0.857147216796875 +100626 0.433685302734375 +100627 0.766845703125 +100628 0.413543701171875 +100629 0.628509521484375 +100630 0.372314453125 +100631 0.462127685546875 +100632 0.3211669921875 +100633 0.297210693359375 +100634 0.265716552734375 +100635 0.14862060546875 +100636 0.1966552734375 +100637 -0.00537109375 +100638 0.11761474609375 +100639 -0.15753173828125 +100640 0.027496337890625 +100641 -0.31304931640625 +100642 -0.079193115234375 +100643 -0.48876953125 +100644 -0.182220458984375 +100645 -0.6416015625 +100646 -0.270751953125 +100647 -0.751373291015625 +100648 -0.35430908203125 +100649 -0.84619140625 +100650 -0.426513671875 +100651 -0.861297607421875 +100652 -0.47320556640625 +100653 -0.863250732421875 +100654 -0.480987548828125 +100655 -0.856597900390625 +100656 -0.455108642578125 +100657 -0.7498779296875 +100658 -0.420318603515625 +100659 -0.624542236328125 +100660 -0.367523193359375 +100661 -0.47808837890625 +100662 -0.27227783203125 +100663 -0.253387451171875 +100664 -0.154266357421875 +100665 0.003692626953125 +100666 -0.042877197265625 +100667 0.2257080078125 +100668 0.066802978515625 +100669 0.427154541015625 +100670 0.188201904296875 +100671 0.643218994140625 +100672 0.31695556640625 +100673 0.855926513671875 +100674 0.42822265625 +100675 0.870361328125 +100676 0.500823974609375 +100677 0.870361328125 +100678 0.537689208984375 +100679 0.862762451171875 +100680 0.53753662109375 +100681 0.79669189453125 +100682 0.496429443359375 +100683 0.595794677734375 +100684 0.4268798828125 +100685 0.362152099609375 +100686 0.340972900390625 +100687 0.1270751953125 +100688 0.2479248046875 +100689 -0.086944580078125 +100690 0.148956298828125 +100691 -0.2784423828125 +100692 0.02960205078125 +100693 -0.484832763671875 +100694 -0.117889404296875 +100695 -0.729583740234375 +100696 -0.27178955078125 +100697 -0.86688232421875 +100698 -0.404937744140625 +100699 -0.870391845703125 +100700 -0.514984130859375 +100701 -0.86859130859375 +100702 -0.600830078125 +100703 -0.86279296875 +100704 -0.6470947265625 +100705 -0.817962646484375 +100706 -0.634490966796875 +100707 -0.6116943359375 +100708 -0.56005859375 +100709 -0.3128662109375 +100710 -0.43817138671875 +100711 0.039398193359375 +100712 -0.2774658203125 +100713 0.422821044921875 +100714 -0.092254638671875 +100715 0.805145263671875 +100716 0.0882568359375 +100717 0.870361328125 +100718 0.239593505859375 +100719 0.870361328125 +100720 0.356475830078125 +100721 0.860015869140625 +100722 0.435302734375 +100723 0.727935791015625 +100724 0.473358154296875 +100725 0.48114013671875 +100726 0.480560302734375 +100727 0.2059326171875 +100728 0.46624755859375 +100729 -0.06103515625 +100730 0.43450927734375 +100731 -0.29913330078125 +100732 0.37908935546875 +100733 -0.516204833984375 +100734 0.29345703125 +100735 -0.7252197265625 +100736 0.188262939453125 +100737 -0.85980224609375 +100738 0.0782470703125 +100739 -0.870391845703125 +100740 -0.023773193359375 +100741 -0.870391845703125 +100742 -0.0968017578125 +100743 -0.858062744140625 +100744 -0.138641357421875 +100745 -0.673004150390625 +100746 -0.171112060546875 +100747 -0.42694091796875 +100748 -0.212615966796875 +100749 -0.2100830078125 +100750 -0.26177978515625 +100751 -0.0362548828125 +100752 -0.305877685546875 +100753 0.10943603515625 +100754 -0.336151123046875 +100755 0.23516845703125 +100756 -0.334808349609375 +100757 0.373687744140625 +100758 -0.302520751953125 +100759 0.517791748046875 +100760 -0.2659912109375 +100761 0.602783203125 +100762 -0.22308349609375 +100763 0.635711669921875 +100764 -0.15985107421875 +100765 0.655181884765625 +100766 -0.080718994140625 +100767 0.65948486328125 +100768 0.010498046875 +100769 0.651275634765625 +100770 0.10302734375 +100771 0.61846923828125 +100772 0.180755615234375 +100773 0.53753662109375 +100774 0.235565185546875 +100775 0.404144287109375 +100776 0.262939453125 +100777 0.22186279296875 +100778 0.263031005859375 +100779 0.003997802734375 +100780 0.243194580078125 +100781 -0.22100830078125 +100782 0.2119140625 +100783 -0.42449951171875 +100784 0.1781005859375 +100785 -0.579833984375 +100786 0.159820556640625 +100787 -0.641876220703125 +100788 0.154266357421875 +100789 -0.6177978515625 +100790 0.134185791015625 +100791 -0.575531005859375 +100792 0.097503662109375 +100793 -0.526336669921875 +100794 0.06646728515625 +100795 -0.42645263671875 +100796 0.053009033203125 +100797 -0.2581787109375 +100798 0.0421142578125 +100799 -0.068695068359375 +100800 0.017852783203125 +100801 0.09222412109375 +100802 -0.011474609375 +100803 0.232147216796875 +100804 -0.041168212890625 +100805 0.3509521484375 +100806 -0.08349609375 +100807 0.410064697265625 +100808 -0.150604248046875 +100809 0.372955322265625 +100810 -0.23345947265625 +100811 0.2554931640625 +100812 -0.309814453125 +100813 0.10711669921875 +100814 -0.371337890625 +100815 -0.052886962890625 +100816 -0.4027099609375 +100817 -0.186279296875 +100818 -0.380340576171875 +100819 -0.23291015625 +100820 -0.3140869140625 +100821 -0.209442138671875 +100822 -0.232147216796875 +100823 -0.174163818359375 +100824 -0.138336181640625 +100825 -0.126739501953125 +100826 -0.02880859375 +100827 -0.048126220703125 +100828 0.084136962890625 +100829 0.0426025390625 +100830 0.180389404296875 +100831 0.10748291015625 +100832 0.2540283203125 +100833 0.1409912109375 +100834 0.32489013671875 +100835 0.19708251953125 +100836 0.389923095703125 +100837 0.273651123046875 +100838 0.42529296875 +100839 0.31768798828125 +100840 0.43560791015625 +100841 0.341094970703125 +100842 0.4315185546875 +100843 0.368011474609375 +100844 0.403350830078125 +100845 0.37249755859375 +100846 0.330322265625 +100847 0.30072021484375 +100848 0.2147216796875 +100849 0.1517333984375 +100850 0.08502197265625 +100851 -0.01470947265625 +100852 -0.05096435546875 +100853 -0.1883544921875 +100854 -0.191253662109375 +100855 -0.372711181640625 +100856 -0.309661865234375 +100857 -0.51397705078125 +100858 -0.385986328125 +100859 -0.57177734375 +100860 -0.414794921875 +100861 -0.53948974609375 +100862 -0.40167236328125 +100863 -0.43511962890625 +100864 -0.3614501953125 +100865 -0.2962646484375 +100866 -0.309814453125 +100867 -0.161102294921875 +100868 -0.252593994140625 +100869 -0.0435791015625 +100870 -0.188812255859375 +100871 0.060394287109375 +100872 -0.125457763671875 +100873 0.13665771484375 +100874 -0.070465087890625 +100875 0.170135498046875 +100876 -0.02435302734375 +100877 0.16552734375 +100878 0.023895263671875 +100879 0.15728759765625 +100880 0.0736083984375 +100881 0.150787353515625 +100882 0.1123046875 +100883 0.12200927734375 +100884 0.1409912109375 +100885 0.080108642578125 +100886 0.16778564453125 +100887 0.05126953125 +100888 0.201751708984375 +100889 0.062896728515625 +100890 0.23260498046875 +100891 0.09271240234375 +100892 0.240509033203125 +100893 0.092987060546875 +100894 0.231292724609375 +100895 0.07855224609375 +100896 0.21136474609375 +100897 0.06427001953125 +100898 0.1756591796875 +100899 0.0347900390625 +100900 0.125 +100901 -0.01171875 +100902 0.069061279296875 +100903 -0.056060791015625 +100904 0.027191162109375 +100905 -0.055511474609375 +100906 0.001617431640625 +100907 -0.010467529296875 +100908 -0.02679443359375 +100909 0.02508544921875 +100910 -0.06591796875 +100911 0.025665283203125 +100912 -0.103302001953125 +100913 0.017333984375 +100914 -0.13653564453125 +100915 0.00189208984375 +100916 -0.16876220703125 +100917 -0.03173828125 +100918 -0.19439697265625 +100919 -0.071502685546875 +100920 -0.220367431640625 +100921 -0.13543701171875 +100922 -0.245513916015625 +100923 -0.219970703125 +100924 -0.26068115234375 +100925 -0.300506591796875 +100926 -0.266754150390625 +100927 -0.376312255859375 +100928 -0.252777099609375 +100929 -0.416107177734375 +100930 -0.2010498046875 +100931 -0.371124267578125 +100932 -0.113861083984375 +100933 -0.242279052734375 +100934 -0.00927734375 +100935 -0.069732666015625 +100936 0.102386474609375 +100937 0.125640869140625 +100938 0.206878662109375 +100939 0.31268310546875 +100940 0.288177490234375 +100941 0.45501708984375 +100942 0.345947265625 +100943 0.554779052734375 +100944 0.37890625 +100945 0.61065673828125 +100946 0.381988525390625 +100947 0.610931396484375 +100948 0.3455810546875 +100949 0.531463623046875 +100950 0.276580810546875 +100951 0.3883056640625 +100952 0.1971435546875 +100953 0.23468017578125 +100954 0.1182861328125 +100955 0.095245361328125 +100956 0.05181884765625 +100957 -0.00396728515625 +100958 0.00506591796875 +100959 -0.04852294921875 +100960 -0.027008056640625 +100961 -0.055145263671875 +100962 -0.063568115234375 +100963 -0.0758056640625 +100964 -0.1143798828125 +100965 -0.138702392578125 +100966 -0.164276123046875 +100967 -0.209197998046875 +100968 -0.212860107421875 +100969 -0.289031982421875 +100970 -0.259674072265625 +100971 -0.37884521484375 +100972 -0.295318603515625 +100973 -0.456329345703125 +100974 -0.31768798828125 +100975 -0.51641845703125 +100976 -0.3111572265625 +100977 -0.519287109375 +100978 -0.27362060546875 +100979 -0.458251953125 +100980 -0.2265625 +100981 -0.384796142578125 +100982 -0.18096923828125 +100983 -0.323699951171875 +100984 -0.13580322265625 +100985 -0.269287109375 +100986 -0.081878662109375 +100987 -0.1951904296875 +100988 -0.019989013671875 +100989 -0.100006103515625 +100990 0.037841796875 +100991 -0.01055908203125 +100992 0.1025390625 +100993 0.1033935546875 +100994 0.176055908203125 +100995 0.24908447265625 +100996 0.236328125 +100997 0.373199462890625 +100998 0.275848388671875 +100999 0.45806884765625 +101000 0.297576904296875 +101001 0.511474609375 +101002 0.314422607421875 +101003 0.565399169921875 +101004 0.32342529296875 +101005 0.61138916015625 +101006 0.30133056640625 +101007 0.5897216796875 +101008 0.24505615234375 +101009 0.4906005859375 +101010 0.16259765625 +101011 0.33148193359375 +101012 0.0692138671875 +101013 0.147796630859375 +101014 -0.01727294921875 +101015 -0.01873779296875 +101016 -0.084625244140625 +101017 -0.140289306640625 +101018 -0.121917724609375 +101019 -0.191986083984375 +101020 -0.13250732421875 +101021 -0.184295654296875 +101022 -0.133575439453125 +101023 -0.161834716796875 +101024 -0.141448974609375 +101025 -0.166595458984375 +101026 -0.154083251953125 +101027 -0.19390869140625 +101028 -0.163726806640625 +101029 -0.22442626953125 +101030 -0.179290771484375 +101031 -0.279754638671875 +101032 -0.192901611328125 +101033 -0.3389892578125 +101034 -0.1861572265625 +101035 -0.3543701171875 +101036 -0.168731689453125 +101037 -0.348175048828125 +101038 -0.143707275390625 +101039 -0.32598876953125 +101040 -0.100189208984375 +101041 -0.2581787109375 +101042 -0.037078857421875 +101043 -0.139801025390625 +101044 0.038970947265625 +101045 0.014617919921875 +101046 0.1029052734375 +101047 0.144378662109375 +101048 0.142822265625 +101049 0.221038818359375 +101050 0.168701171875 +101051 0.27069091796875 +101052 0.18060302734375 +101053 0.294036865234375 +101054 0.186737060546875 +101055 0.311767578125 +101056 0.193328857421875 +101057 0.339141845703125 +101058 0.194305419921875 +101059 0.360260009765625 +101060 0.184295654296875 +101061 0.360504150390625 +101062 0.151611328125 +101063 0.308380126953125 +101064 0.088348388671875 +101065 0.18170166015625 +101066 0.004852294921875 +101067 0.0047607421875 +101068 -0.0797119140625 +101069 -0.17559814453125 +101070 -0.146942138671875 +101071 -0.3143310546875 +101072 -0.179107666015625 +101073 -0.36785888671875 +101074 -0.185943603515625 +101075 -0.36248779296875 +101076 -0.184783935546875 +101077 -0.343536376953125 +101078 -0.17181396484375 +101079 -0.3018798828125 +101080 -0.144500732421875 +101081 -0.231414794921875 +101082 -0.097259521484375 +101083 -0.117645263671875 +101084 -0.042999267578125 +101085 0.007049560546875 +101086 -0.0035400390625 +101087 0.087982177734375 +101088 0.026214599609375 +101089 0.13946533203125 +101090 0.05072021484375 +101091 0.17425537109375 +101092 0.06768798828125 +101093 0.188201904296875 +101094 0.072540283203125 +101095 0.171234130859375 +101096 0.062744140625 +101097 0.118438720703125 +101098 0.04840087890625 +101099 0.05706787109375 +101100 0.02984619140625 +101101 -0.010711669921875 +101102 0.004119873046875 +101103 -0.0914306640625 +101104 -0.02008056640625 +101105 -0.162322998046875 +101106 -0.031585693359375 +101107 -0.194549560546875 +101108 -0.015167236328125 +101109 -0.1492919921875 +101110 0.031219482421875 +101111 -0.02166748046875 +101112 0.0826416015625 +101113 0.124053955078125 +101114 0.109375 +101115 0.211151123046875 +101116 0.112213134765625 +101117 0.240447998046875 +101118 0.103515625 +101119 0.242218017578125 +101120 0.086944580078125 +101121 0.2257080078125 +101122 0.06463623046875 +101123 0.194366455078125 +101124 0.025970458984375 +101125 0.115509033203125 +101126 -0.019927978515625 +101127 0.0128173828125 +101128 -0.05108642578125 +101129 -0.053802490234375 +101130 -0.076629638671875 +101131 -0.110626220703125 +101132 -0.111480712890625 +101133 -0.199493408203125 +101134 -0.146148681640625 +101135 -0.29437255859375 +101136 -0.15802001953125 +101137 -0.33221435546875 +101138 -0.13531494140625 +101139 -0.27972412109375 +101140 -0.095703125 +101141 -0.185333251953125 +101142 -0.06805419921875 +101143 -0.128204345703125 +101144 -0.055450439453125 +101145 -0.115692138671875 +101146 -0.047088623046875 +101147 -0.116455078125 +101148 -0.03460693359375 +101149 -0.105926513671875 +101150 -0.00762939453125 +101151 -0.053955078125 +101152 0.0367431640625 +101153 0.048797607421875 +101154 0.081939697265625 +101155 0.157318115234375 +101156 0.106201171875 +101157 0.212005615234375 +101158 0.111328125 +101159 0.218475341796875 +101160 0.1190185546875 +101161 0.23724365234375 +101162 0.142608642578125 +101163 0.30535888671875 +101164 0.167236328125 +101165 0.38128662109375 +101166 0.1712646484375 +101167 0.404449462890625 +101168 0.16204833984375 +101169 0.3944091796875 +101170 0.153411865234375 +101171 0.3885498046875 +101172 0.13702392578125 +101173 0.362640380859375 +101174 0.0977783203125 +101175 0.27362060546875 +101176 0.034515380859375 +101177 0.11712646484375 +101178 -0.03369140625 +101179 -0.054901123046875 +101180 -0.087921142578125 +101181 -0.19085693359375 +101182 -0.126129150390625 +101183 -0.28570556640625 +101184 -0.148101806640625 +101185 -0.339263916015625 +101186 -0.163055419921875 +101187 -0.3775634765625 +101188 -0.187225341796875 +101189 -0.445709228515625 +101190 -0.217559814453125 +101191 -0.535064697265625 +101192 -0.248260498046875 +101193 -0.629058837890625 +101194 -0.2686767578125 +101195 -0.697601318359375 +101196 -0.26580810546875 +101197 -0.70391845703125 +101198 -0.23797607421875 +101199 -0.6424560546875 +101200 -0.1776123046875 +101201 -0.491241455078125 +101202 -0.090606689453125 +101203 -0.265716552734375 +101204 0.00189208984375 +101205 -0.023712158203125 +101206 0.08770751953125 +101207 0.201751708984375 +101208 0.154052734375 +101209 0.375823974609375 +101210 0.1959228515625 +101211 0.485076904296875 +101212 0.227386474609375 +101213 0.56884765625 +101214 0.25115966796875 +101215 0.634765625 +101216 0.2509765625 +101217 0.63763427734375 +101218 0.22283935546875 +101219 0.5660400390625 +101220 0.185638427734375 +101221 0.4720458984375 +101222 0.158050537109375 +101223 0.40692138671875 +101224 0.1429443359375 +101225 0.3778076171875 +101226 0.137786865234375 +101227 0.376953125 +101228 0.13116455078125 +101229 0.371978759765625 +101230 0.10540771484375 +101231 0.313140869140625 +101232 0.055023193359375 +101233 0.184417724609375 +101234 -0.0106201171875 +101235 0.011199951171875 +101236 -0.078582763671875 +101237 -0.171051025390625 +101238 -0.139801025390625 +101239 -0.33740234375 +101240 -0.18853759765625 +101241 -0.47198486328125 +101242 -0.2196044921875 +101243 -0.560394287109375 +101244 -0.225128173828125 +101245 -0.58056640625 +101246 -0.210662841796875 +101247 -0.54754638671875 +101248 -0.193389892578125 +101249 -0.508575439453125 +101250 -0.1719970703125 +101251 -0.459503173828125 +101252 -0.144561767578125 +101253 -0.394378662109375 +101254 -0.125457763671875 +101255 -0.35260009765625 +101256 -0.106842041015625 +101257 -0.31170654296875 +101258 -0.06219482421875 +101259 -0.197418212890625 +101260 0.0089111328125 +101261 -0.007965087890625 +101262 0.088653564453125 +101263 0.207489013671875 +101264 0.16259765625 +101265 0.409210205078125 +101266 0.2216796875 +101267 0.57208251953125 +101268 0.25506591796875 +101269 0.66595458984375 +101270 0.251251220703125 +101271 0.65875244140625 +101272 0.2164306640625 +101273 0.56744384765625 +101274 0.164886474609375 +101275 0.431396484375 +101276 0.112579345703125 +101277 0.29443359375 +101278 0.069000244140625 +101279 0.182464599609375 +101280 0.02288818359375 +101281 0.06365966796875 +101282 -0.03057861328125 +101283 -0.075958251953125 +101284 -0.0743408203125 +101285 -0.189422607421875 +101286 -0.10650634765625 +101287 -0.271942138671875 +101288 -0.1337890625 +101289 -0.342529296875 +101290 -0.142822265625 +101291 -0.364166259765625 +101292 -0.130096435546875 +101293 -0.327239990234375 +101294 -0.111846923828125 +101295 -0.2769775390625 +101296 -0.1026611328125 +101297 -0.253692626953125 +101298 -0.097625732421875 +101299 -0.24365234375 +101300 -0.079376220703125 +101301 -0.1983642578125 +101302 -0.0474853515625 +101303 -0.116241455078125 +101304 -0.01629638671875 +101305 -0.036834716796875 +101306 0.01220703125 +101307 0.034881591796875 +101308 0.035125732421875 +101309 0.09124755859375 +101310 0.043914794921875 +101311 0.10888671875 +101312 0.052001953125 +101313 0.125518798828125 +101314 0.065277099609375 +101315 0.15771484375 +101316 0.0738525390625 +101317 0.17828369140625 +101318 0.071868896484375 +101319 0.17108154296875 +101320 0.057098388671875 +101321 0.129974365234375 +101322 0.039459228515625 +101323 0.082427978515625 +101324 0.018707275390625 +101325 0.027679443359375 +101326 -0.016357421875 +101327 -0.065643310546875 +101328 -0.0518798828125 +101329 -0.15936279296875 +101330 -0.0732421875 +101331 -0.21307373046875 +101332 -0.0831298828125 +101333 -0.234649658203125 +101334 -0.072845458984375 +101335 -0.2001953125 +101336 -0.045684814453125 +101337 -0.119171142578125 +101338 -0.013458251953125 +101339 -0.024749755859375 +101340 0.024871826171875 +101341 0.085784912109375 +101342 0.0570068359375 +101343 0.178131103515625 +101344 0.06976318359375 +101345 0.215576171875 +101346 0.0679931640625 +101347 0.211456298828125 +101348 0.05511474609375 +101349 0.17523193359375 +101350 0.038970947265625 +101351 0.128753662109375 +101352 0.030303955078125 +101353 0.1019287109375 +101354 0.021697998046875 +101355 0.0743408203125 +101356 0.012054443359375 +101357 0.04327392578125 +101358 0.01190185546875 +101359 0.038177490234375 +101360 0.027374267578125 +101361 0.076263427734375 +101362 0.052398681640625 +101363 0.14105224609375 +101364 0.070281982421875 +101365 0.186431884765625 +101366 0.07244873046875 +101367 0.188812255859375 +101368 0.055572509765625 +101369 0.1390380859375 +101370 0.02130126953125 +101371 0.041778564453125 +101372 -0.021942138671875 +101373 -0.079437255859375 +101374 -0.072296142578125 +101375 -0.219390869140625 +101376 -0.125701904296875 +101377 -0.367828369140625 +101378 -0.170928955078125 +101379 -0.494873046875 +101380 -0.192962646484375 +101381 -0.556243896484375 +101382 -0.1778564453125 +101383 -0.508697509765625 +101384 -0.133514404296875 +101385 -0.3756103515625 +101386 -0.080535888671875 +101387 -0.218902587890625 +101388 -0.027435302734375 +101389 -0.063751220703125 +101390 0.02606201171875 +101391 0.091552734375 +101392 0.07611083984375 +101393 0.23602294921875 +101394 0.113800048828125 +101395 0.342987060546875 +101396 0.13330078125 +101397 0.39520263671875 +101398 0.133392333984375 +101399 0.389373779296875 +101400 0.11358642578125 +101401 0.324249267578125 +101402 0.081787109375 +101403 0.224090576171875 +101404 0.049560546875 +101405 0.124267578125 +101406 0.02093505859375 +101407 0.037078857421875 +101408 0.0048828125 +101409 -0.010101318359375 +101410 0.000732421875 +101411 -0.019439697265625 +101412 -0.0018310546875 +101413 -0.022796630859375 +101414 0.003387451171875 +101415 -0.001556396484375 +101416 0.02044677734375 +101417 0.056304931640625 +101418 0.035003662109375 +101419 0.106719970703125 +101420 0.02984619140625 +101421 0.096893310546875 +101422 0.01031494140625 +101423 0.042694091796875 +101424 -0.011077880859375 +101425 -0.018035888671875 +101426 -0.031158447265625 +101427 -0.07586669921875 +101428 -0.046173095703125 +101429 -0.11944580078125 +101430 -0.0596923828125 +101431 -0.15972900390625 +101432 -0.073638916015625 +101433 -0.202606201171875 +101434 -0.088165283203125 +101435 -0.24859619140625 +101436 -0.10577392578125 +101437 -0.30517578125 +101438 -0.123199462890625 +101439 -0.36212158203125 +101440 -0.131317138671875 +101441 -0.39141845703125 +101442 -0.117828369140625 +101443 -0.35528564453125 +101444 -0.08160400390625 +101445 -0.249969482421875 +101446 -0.028472900390625 +101447 -0.092864990234375 +101448 0.032623291015625 +101449 0.08905029296875 +101450 0.081756591796875 +101451 0.2352294921875 +101452 0.110076904296875 +101453 0.318817138671875 +101454 0.12371826171875 +101455 0.358642578125 +101456 0.120391845703125 +101457 0.347747802734375 +101458 0.09991455078125 +101459 0.28564453125 +101460 0.0789794921875 +101461 0.223175048828125 +101462 0.069549560546875 +101463 0.196746826171875 +101464 0.06298828125 +101465 0.179840087890625 +101466 0.053802490234375 +101467 0.155548095703125 +101468 0.051055908203125 +101469 0.151214599609375 +101470 0.05157470703125 +101471 0.156951904296875 +101472 0.041961669921875 +101473 0.13177490234375 +101474 0.030548095703125 +101475 0.100799560546875 +101476 0.02496337890625 +101477 0.087127685546875 +101478 0.013519287109375 +101479 0.05487060546875 +101480 -0.00799560546875 +101481 -0.009002685546875 +101482 -0.039398193359375 +101483 -0.10400390625 +101484 -0.0804443359375 +101485 -0.229400634765625 +101486 -0.121429443359375 +101487 -0.35552978515625 +101488 -0.14910888671875 +101489 -0.441925048828125 +101490 -0.15869140625 +101491 -0.473846435546875 +101492 -0.1546630859375 +101493 -0.464813232421875 +101494 -0.13848876953125 +101495 -0.419097900390625 +101496 -0.109466552734375 +101497 -0.334320068359375 +101498 -0.0733642578125 +101499 -0.227935791015625 +101500 -0.0379638671875 +101501 -0.12347412109375 +101502 -0.00555419921875 +101503 -0.02764892578125 +101504 0.029754638671875 +101505 0.077667236328125 +101506 0.074737548828125 +101507 0.2132568359375 +101508 0.132568359375 +101509 0.38885498046875 +101510 0.196136474609375 +101511 0.582794189453125 +101512 0.24542236328125 +101513 0.734039306640625 +101514 0.266510009765625 +101515 0.800140380859375 +101516 0.258544921875 +101517 0.7783203125 +101518 0.220458984375 +101519 0.6651611328125 +101520 0.1519775390625 +101521 0.45965576171875 +101522 0.0654296875 +101523 0.199188232421875 +101524 -0.017608642578125 +101525 -0.050689697265625 +101526 -0.078338623046875 +101527 -0.23297119140625 +101528 -0.11102294921875 +101529 -0.33013916015625 +101530 -0.12420654296875 +101531 -0.368408203125 +101532 -0.1280517578125 +101533 -0.378936767578125 +101534 -0.127593994140625 +101535 -0.376983642578125 +101536 -0.128448486328125 +101537 -0.37969970703125 +101538 -0.132080078125 +101539 -0.391510009765625 +101540 -0.129608154296875 +101541 -0.385345458984375 +101542 -0.11474609375 +101543 -0.3419189453125 +101544 -0.094635009765625 +101545 -0.28289794921875 +101546 -0.08349609375 +101547 -0.251617431640625 +101548 -0.087310791015625 +101549 -0.266143798828125 +101550 -0.0887451171875 +101551 -0.273345947265625 +101552 -0.069305419921875 +101553 -0.216796875 +101554 -0.039459228515625 +101555 -0.128265380859375 +101556 -0.01904296875 +101557 -0.068145751953125 +101558 -0.01031494140625 +101559 -0.0430908203125 +101560 -0.003875732421875 +101561 -0.024444580078125 +101562 0.01104736328125 +101563 0.020721435546875 +101564 0.044921875 +101565 0.124481201171875 +101566 0.088287353515625 +101567 0.25787353515625 +101568 0.127471923828125 +101569 0.379119873046875 +101570 0.1597900390625 +101571 0.47991943359375 +101572 0.174774169921875 +101573 0.5281982421875 +101574 0.16827392578125 +101575 0.511138916015625 +101576 0.14935302734375 +101577 0.456207275390625 +101578 0.13250732421875 +101579 0.407470703125 +101580 0.12396240234375 +101581 0.383758544921875 +101582 0.114471435546875 +101583 0.35687255859375 +101584 0.099151611328125 +101585 0.31182861328125 +101586 0.078765869140625 +101587 0.250885009765625 +101588 0.050506591796875 +101589 0.1654052734375 +101590 0.0078125 +101591 0.035247802734375 +101592 -0.05010986328125 +101593 -0.142059326171875 +101594 -0.1131591796875 +101595 -0.33563232421875 +101596 -0.17779541015625 +101597 -0.5345458984375 +101598 -0.23846435546875 +101599 -0.72186279296875 +101600 -0.275238037109375 +101601 -0.836669921875 +101602 -0.272979736328125 +101603 -0.8326416015625 +101604 -0.238250732421875 +101605 -0.7296142578125 +101606 -0.18914794921875 +101607 -0.582550048828125 +101608 -0.14166259765625 +101609 -0.440093994140625 +101610 -0.10308837890625 +101611 -0.324310302734375 +101612 -0.0623779296875 +101613 -0.20147705078125 +101614 -0.01068115234375 +101615 -0.044647216796875 +101616 0.038116455078125 +101617 0.103973388671875 +101618 0.070220947265625 +101619 0.202392578125 +101620 0.090179443359375 +101621 0.264495849609375 +101622 0.113983154296875 +101623 0.338897705078125 +101624 0.14764404296875 +101625 0.443817138671875 +101626 0.17999267578125 +101627 0.545074462890625 +101628 0.202789306640625 +101629 0.6173095703125 +101630 0.21343994140625 +101631 0.6524658203125 +101632 0.2158203125 +101633 0.66339111328125 +101634 0.211822509765625 +101635 0.6561279296875 +101636 0.194244384765625 +101637 0.606781005859375 +101638 0.15911865234375 +101639 0.501190185546875 +101640 0.11065673828125 +101641 0.352783203125 +101642 0.053619384765625 +101643 0.176544189453125 +101644 -0.013824462890625 +101645 -0.034820556640625 +101646 -0.08453369140625 +101647 -0.258209228515625 +101648 -0.14312744140625 +101649 -0.44244384765625 +101650 -0.18572998046875 +101651 -0.5753173828125 +101652 -0.210784912109375 +101653 -0.65203857421875 +101654 -0.209014892578125 +101655 -0.641632080078125 +101656 -0.18572998046875 +101657 -0.562164306640625 +101658 -0.154083251953125 +101659 -0.458038330078125 +101660 -0.12042236328125 +101661 -0.350555419921875 +101662 -0.091064453125 +101663 -0.260528564453125 +101664 -0.067413330078125 +101665 -0.192108154296875 +101666 -0.04864501953125 +101667 -0.141937255859375 +101668 -0.03265380859375 +101669 -0.1021728515625 +101670 -0.016754150390625 +101671 -0.062896728515625 +101672 0.00238037109375 +101673 -0.011932373046875 +101674 0.02813720703125 +101675 0.062835693359375 +101676 0.05657958984375 +101677 0.148712158203125 +101678 0.086334228515625 +101679 0.241729736328125 +101680 0.119476318359375 +101681 0.34912109375 +101682 0.151947021484375 +101683 0.457305908203125 +101684 0.177093505859375 +101685 0.54388427734375 +101686 0.184326171875 +101687 0.5728759765625 +101688 0.16259765625 +101689 0.506591796875 +101690 0.1138916015625 +101691 0.351226806640625 +101692 0.05010986328125 +101693 0.146514892578125 +101694 -0.013031005859375 +101695 -0.05523681640625 +101696 -0.064178466796875 +101697 -0.21624755859375 +101698 -0.102630615234375 +101699 -0.334930419921875 +101700 -0.12579345703125 +101701 -0.402984619140625 +101702 -0.1396484375 +101703 -0.4412841796875 +101704 -0.15771484375 +101705 -0.49578857421875 +101706 -0.17803955078125 +101707 -0.5601806640625 +101708 -0.190582275390625 +101709 -0.600738525390625 +101710 -0.18548583984375 +101711 -0.584228515625 +101712 -0.15350341796875 +101713 -0.47930908203125 +101714 -0.0927734375 +101715 -0.27935791015625 +101716 -0.010650634765625 +101717 -0.0089111328125 +101718 0.073974609375 +101719 0.268798828125 +101720 0.139984130859375 +101721 0.482818603515625 +101722 0.178497314453125 +101723 0.60369873046875 +101724 0.194976806640625 +101725 0.650421142578125 +101726 0.201416015625 +101727 0.66400146484375 +101728 0.19683837890625 +101729 0.6414794921875 +101730 0.178070068359375 +101731 0.572540283203125 +101732 0.15716552734375 +101733 0.498138427734375 +101734 0.140380859375 +101735 0.439453125 +101736 0.1214599609375 +101737 0.375518798828125 +101738 0.09100341796875 +101739 0.274505615234375 +101740 0.0408935546875 +101741 0.1087646484375 +101742 -0.022186279296875 +101743 -0.099395751953125 +101744 -0.0887451171875 +101745 -0.3182373046875 +101746 -0.1590576171875 +101747 -0.5489501953125 +101748 -0.22772216796875 +101749 -0.7738037109375 +101750 -0.2789306640625 +101751 -0.86383056640625 +101752 -0.302764892578125 +101753 -0.870391845703125 +101754 -0.304351806640625 +101755 -0.86895751953125 +101756 -0.287506103515625 +101757 -0.861053466796875 +101758 -0.247039794921875 +101759 -0.765869140625 +101760 -0.179595947265625 +101761 -0.5301513671875 +101762 -0.087249755859375 +101763 -0.214691162109375 +101764 0.017242431640625 +101765 0.137359619140625 +101766 0.118682861328125 +101767 0.474822998046875 +101768 0.206512451171875 +101769 0.76239013671875 +101770 0.27264404296875 +101771 0.867462158203125 +101772 0.317138671875 +101773 0.870361328125 +101774 0.33648681640625 +101775 0.86480712890625 +101776 0.3321533203125 +101777 0.831817626953125 +101778 0.311279296875 +101779 0.677581787109375 +101780 0.2755126953125 +101781 0.495880126953125 +101782 0.23028564453125 +101783 0.30767822265625 +101784 0.17620849609375 +101785 0.116180419921875 +101786 0.103851318359375 +101787 -0.110748291015625 +101788 0.0111083984375 +101789 -0.381805419921875 +101790 -0.08929443359375 +101791 -0.6572265625 +101792 -0.179595947265625 +101793 -0.857421875 +101794 -0.247100830078125 +101795 -0.870391845703125 +101796 -0.289642333984375 +101797 -0.870391845703125 +101798 -0.315155029296875 +101799 -0.86444091796875 +101800 -0.3341064453125 +101801 -0.85723876953125 +101802 -0.34100341796875 +101803 -0.790008544921875 +101804 -0.3197021484375 +101805 -0.62847900390625 +101806 -0.26922607421875 +101807 -0.3956298828125 +101808 -0.199249267578125 +101809 -0.126708984375 +101810 -0.1177978515625 +101811 0.150115966796875 +101812 -0.0283203125 +101813 0.424041748046875 +101814 0.061187744140625 +101815 0.670623779296875 +101816 0.1392822265625 +101817 0.854522705078125 +101818 0.200714111328125 +101819 0.866485595703125 +101820 0.240936279296875 +101821 0.86920166015625 +101822 0.2652587890625 +101823 0.8653564453125 +101824 0.277618408203125 +101825 0.857147216796875 +101826 0.277099609375 +101827 0.766845703125 +101828 0.265167236328125 +101829 0.628509521484375 +101830 0.239776611328125 +101831 0.462127685546875 +101832 0.208526611328125 +101833 0.297210693359375 +101834 0.175018310546875 +101835 0.14862060546875 +101836 0.1324462890625 +101837 -0.00537109375 +101838 0.0830078125 +101839 -0.15753173828125 +101840 0.025634765625 +101841 -0.31304931640625 +101842 -0.0438232421875 +101843 -0.48876953125 +101844 -0.111480712890625 +101845 -0.6416015625 +101846 -0.16998291015625 +101847 -0.751373291015625 +101848 -0.22613525390625 +101849 -0.84619140625 +101850 -0.275543212890625 +101851 -0.861297607421875 +101852 -0.308380126953125 +101853 -0.863250732421875 +101854 -0.31524658203125 +101855 -0.856597900390625 +101856 -0.2996826171875 +101857 -0.7498779296875 +101858 -0.278778076171875 +101859 -0.624542236328125 +101860 -0.246002197265625 +101861 -0.47808837890625 +101862 -0.184051513671875 +101863 -0.253387451171875 +101864 -0.106414794921875 +101865 0.003692626953125 +101866 -0.0333251953125 +101867 0.2257080078125 +101868 0.038909912109375 +101869 0.427154541015625 +101870 0.119873046875 +101871 0.643218994140625 +101872 0.206695556640625 +101873 0.855926513671875 +101874 0.282196044921875 +101875 0.870361328125 +101876 0.3316650390625 +101877 0.870361328125 +101878 0.357208251953125 +101879 0.862762451171875 +101880 0.35791015625 +101881 0.79669189453125 +101882 0.330963134765625 +101883 0.595794677734375 +101884 0.28497314453125 +101885 0.362152099609375 +101886 0.22821044921875 +101887 0.1270751953125 +101888 0.166351318359375 +101889 -0.086944580078125 +101890 0.0997314453125 +101891 -0.2784423828125 +101892 0.01947021484375 +101893 -0.484832763671875 +101894 -0.078582763671875 +101895 -0.729583740234375 +101896 -0.1802978515625 +101897 -0.86688232421875 +101898 -0.268310546875 +101899 -0.870391845703125 +101900 -0.3408203125 +101901 -0.86859130859375 +101902 -0.3968505859375 +101903 -0.86279296875 +101904 -0.426727294921875 +101905 -0.817962646484375 +101906 -0.418426513671875 +101907 -0.6116943359375 +101908 -0.37017822265625 +101909 -0.3128662109375 +101910 -0.291107177734375 +101911 0.039398193359375 +101912 -0.186798095703125 +101913 0.422821044921875 +101914 -0.066497802734375 +101915 0.805145263671875 +101916 0.051300048828125 +101917 0.870361328125 +101918 0.15106201171875 +101919 0.870361328125 +101920 0.2291259765625 +101921 0.860015869140625 +101922 0.282958984375 +101923 0.727935791015625 +101924 0.310638427734375 +101925 0.48114013671875 +101926 0.318145751953125 +101927 0.2059326171875 +101928 0.3111572265625 +101929 -0.06103515625 +101930 0.292083740234375 +101931 -0.29913330078125 +101932 0.257049560546875 +101933 -0.516204833984375 +101934 0.202056884765625 +101935 -0.7252197265625 +101936 0.13385009765625 +101937 -0.85980224609375 +101938 0.061798095703125 +101939 -0.870391845703125 +101940 -0.005889892578125 +101941 -0.870391845703125 +101942 -0.055877685546875 +101943 -0.858062744140625 +101944 -0.0865478515625 +101945 -0.673004150390625 +101946 -0.111236572265625 +101947 -0.42694091796875 +101948 -0.141143798828125 +101949 -0.2100830078125 +101950 -0.17523193359375 +101951 -0.0362548828125 +101952 -0.205413818359375 +101953 0.10943603515625 +101954 -0.226043701171875 +101955 0.23516845703125 +101956 -0.225982666015625 +101957 0.373687744140625 +101958 -0.2056884765625 +101959 0.517791748046875 +101960 -0.181793212890625 +101961 0.602783203125 +101962 -0.153076171875 +101963 0.635711669921875 +101964 -0.1109619140625 +101965 0.655181884765625 +101966 -0.05841064453125 +101967 0.65948486328125 +101968 0.00201416015625 +101969 0.651275634765625 +101970 0.06341552734375 +101971 0.61846923828125 +101972 0.115509033203125 +101973 0.53753662109375 +101974 0.153076171875 +101975 0.404144287109375 +101976 0.173095703125 +101977 0.22186279296875 +101978 0.175537109375 +101979 0.003997802734375 +101980 0.16485595703125 +101981 -0.22100830078125 +101982 0.14630126953125 +101983 -0.42449951171875 +101984 0.125335693359375 +101985 -0.579833984375 +101986 0.113250732421875 +101987 -0.641876220703125 +101988 0.108367919921875 +101989 -0.6177978515625 +101990 0.09381103515625 +101991 -0.575531005859375 +101992 0.06842041015625 +101993 -0.526336669921875 +101994 0.04620361328125 +101995 -0.42645263671875 +101996 0.03472900390625 +101997 -0.2581787109375 +101998 0.02484130859375 +101999 -0.068695068359375 +102000 0.006805419921875 +102001 0.09222412109375 +102002 -0.0140380859375 +102003 0.232147216796875 +102004 -0.034637451171875 +102005 0.3509521484375 +102006 -0.062530517578125 +102007 0.410064697265625 +102008 -0.105224609375 +102009 0.372955322265625 +102010 -0.157073974609375 +102011 0.2554931640625 +102012 -0.2042236328125 +102013 0.10711669921875 +102014 -0.241485595703125 +102015 -0.052886962890625 +102016 -0.2593994140625 +102017 -0.186279296875 +102018 -0.243438720703125 +102019 -0.23291015625 +102020 -0.1998291015625 +102021 -0.209442138671875 +102022 -0.146270751953125 +102023 -0.174163818359375 +102024 -0.085296630859375 +102025 -0.126739501953125 +102026 -0.014617919921875 +102027 -0.048126220703125 +102028 0.05792236328125 +102029 0.0426025390625 +102030 0.11968994140625 +102031 0.10748291015625 +102032 0.166900634765625 +102033 0.1409912109375 +102034 0.211883544921875 +102035 0.19708251953125 +102036 0.252685546875 +102037 0.273651123046875 +102038 0.27447509765625 +102039 0.31768798828125 +102040 0.2801513671875 +102041 0.341094970703125 +102042 0.27642822265625 +102043 0.368011474609375 +102044 0.25732421875 +102045 0.37249755859375 +102046 0.209991455078125 +102047 0.30072021484375 +102048 0.135955810546875 +102049 0.1517333984375 +102050 0.053070068359375 +102051 -0.01470947265625 +102052 -0.03369140625 +102053 -0.1883544921875 +102054 -0.122955322265625 +102055 -0.372711181640625 +102056 -0.198333740234375 +102057 -0.51397705078125 +102058 -0.24713134765625 +102059 -0.57177734375 +102060 -0.26593017578125 +102061 -0.53948974609375 +102062 -0.258148193359375 +102063 -0.43511962890625 +102064 -0.232879638671875 +102065 -0.2962646484375 +102066 -0.199798583984375 +102067 -0.161102294921875 +102068 -0.162689208984375 +102069 -0.0435791015625 +102070 -0.121063232421875 +102071 0.060394287109375 +102072 -0.079681396484375 +102073 0.13665771484375 +102074 -0.04388427734375 +102075 0.170135498046875 +102076 -0.0140380859375 +102077 0.16552734375 +102078 0.017120361328125 +102079 0.15728759765625 +102080 0.049102783203125 +102081 0.150787353515625 +102082 0.07373046875 +102083 0.12200927734375 +102084 0.091705322265625 +102085 0.080108642578125 +102086 0.108428955078125 +102087 0.05126953125 +102088 0.129974365234375 +102089 0.062896728515625 +102090 0.14959716796875 +102091 0.09271240234375 +102092 0.154266357421875 +102093 0.092987060546875 +102094 0.1478271484375 +102095 0.07855224609375 +102096 0.13458251953125 +102097 0.06427001953125 +102098 0.111175537109375 +102099 0.0347900390625 +102100 0.078125 +102101 -0.01171875 +102102 0.041839599609375 +102103 -0.056060791015625 +102104 0.0150146484375 +102105 -0.055511474609375 +102106 -0.000885009765625 +102107 -0.010467529296875 +102108 -0.0185546875 +102109 0.02508544921875 +102110 -0.04327392578125 +102111 0.025665283203125 +102112 -0.066864013671875 +102113 0.017333984375 +102114 -0.087799072265625 +102115 0.00189208984375 +102116 -0.10821533203125 +102117 -0.03173828125 +102118 -0.12445068359375 +102119 -0.071502685546875 +102120 -0.14111328125 +102121 -0.13543701171875 +102122 -0.157470703125 +102123 -0.219970703125 +102124 -0.16748046875 +102125 -0.300506591796875 +102126 -0.171722412109375 +102127 -0.376312255859375 +102128 -0.1629638671875 +102129 -0.416107177734375 +102130 -0.12945556640625 +102131 -0.371124267578125 +102132 -0.072662353515625 +102133 -0.242279052734375 +102134 -0.004486083984375 +102135 -0.069732666015625 +102136 0.06829833984375 +102137 0.125640869140625 +102138 0.136322021484375 +102139 0.31268310546875 +102140 0.189056396484375 +102141 0.45501708984375 +102142 0.226348876953125 +102143 0.554779052734375 +102144 0.247161865234375 +102145 0.61065673828125 +102146 0.24835205078125 +102147 0.610931396484375 +102148 0.224212646484375 +102149 0.531463623046875 +102150 0.179229736328125 +102151 0.3883056640625 +102152 0.12738037109375 +102153 0.23468017578125 +102154 0.07574462890625 +102155 0.095245361328125 +102156 0.0318603515625 +102157 -0.00396728515625 +102158 0.000396728515625 +102159 -0.04852294921875 +102160 -0.021636962890625 +102161 -0.055145263671875 +102162 -0.046112060546875 +102163 -0.0758056640625 +102164 -0.079071044921875 +102165 -0.138702392578125 +102166 -0.1109619140625 +102167 -0.209197998046875 +102168 -0.14154052734375 +102169 -0.289031982421875 +102170 -0.170501708984375 +102171 -0.37884521484375 +102172 -0.1920166015625 +102173 -0.456329345703125 +102174 -0.204864501953125 +102175 -0.51641845703125 +102176 -0.199310302734375 +102177 -0.519287109375 +102178 -0.174163818359375 +102179 -0.458251953125 +102180 -0.142913818359375 +102181 -0.384796142578125 +102182 -0.112548828125 +102183 -0.323699951171875 +102184 -0.082489013671875 +102185 -0.269287109375 +102186 -0.047149658203125 +102187 -0.1951904296875 +102188 -0.007080078125 +102189 -0.100006103515625 +102190 0.030120849609375 +102191 -0.01055908203125 +102192 0.07122802734375 +102193 0.1033935546875 +102194 0.117431640625 +102195 0.24908447265625 +102196 0.15496826171875 +102197 0.373199462890625 +102198 0.17913818359375 +102199 0.45806884765625 +102200 0.191802978515625 +102201 0.511474609375 +102202 0.20111083984375 +102203 0.565399169921875 +102204 0.205291748046875 +102205 0.61138916015625 +102206 0.189910888671875 +102207 0.5897216796875 +102208 0.153106689453125 +102209 0.4906005859375 +102210 0.100006103515625 +102211 0.33148193359375 +102212 0.04022216796875 +102213 0.147796630859375 +102214 -0.015045166015625 +102215 -0.01873779296875 +102216 -0.058074951171875 +102217 -0.140289306640625 +102218 -0.082000732421875 +102219 -0.191986083984375 +102220 -0.088897705078125 +102221 -0.184295654296875 +102222 -0.089508056640625 +102223 -0.161834716796875 +102224 -0.094024658203125 +102225 -0.166595458984375 +102226 -0.1011962890625 +102227 -0.19390869140625 +102228 -0.10626220703125 +102229 -0.22442626953125 +102230 -0.114837646484375 +102231 -0.279754638671875 +102232 -0.1220703125 +102233 -0.3389892578125 +102234 -0.11651611328125 +102235 -0.3543701171875 +102236 -0.10430908203125 +102237 -0.348175048828125 +102238 -0.087432861328125 +102239 -0.32598876953125 +102240 -0.059112548828125 +102241 -0.2581787109375 +102242 -0.01873779296875 +102243 -0.139801025390625 +102244 0.029449462890625 +102245 0.014617919921875 +102246 0.069793701171875 +102247 0.144378662109375 +102248 0.09478759765625 +102249 0.221038818359375 +102250 0.110687255859375 +102251 0.27069091796875 +102252 0.117584228515625 +102253 0.294036865234375 +102254 0.12066650390625 +102255 0.311767578125 +102256 0.123809814453125 +102257 0.339141845703125 +102258 0.123077392578125 +102259 0.360260009765625 +102260 0.115264892578125 +102261 0.360504150390625 +102262 0.093658447265625 +102263 0.308380126953125 +102264 0.0537109375 +102265 0.18170166015625 +102266 0.001739501953125 +102267 0.0047607421875 +102268 -0.05072021484375 +102269 -0.17559814453125 +102270 -0.0926513671875 +102271 -0.3143310546875 +102272 -0.113433837890625 +102273 -0.36785888671875 +102274 -0.118743896484375 +102275 -0.36248779296875 +102276 -0.1187744140625 +102277 -0.343536376953125 +102278 -0.111236572265625 +102279 -0.3018798828125 +102280 -0.09466552734375 +102281 -0.231414794921875 +102282 -0.0657958984375 +102283 -0.117645263671875 +102284 -0.032318115234375 +102285 0.007049560546875 +102286 -0.007232666015625 +102287 0.087982177734375 +102288 0.012359619140625 +102289 0.13946533203125 +102290 0.028961181640625 +102291 0.17425537109375 +102292 0.041107177734375 +102293 0.188201904296875 +102294 0.04595947265625 +102295 0.171234130859375 +102296 0.041900634765625 +102297 0.118438720703125 +102298 0.034881591796875 +102299 0.05706787109375 +102300 0.02496337890625 +102301 -0.010711669921875 +102302 0.0103759765625 +102303 -0.0914306640625 +102304 -0.00372314453125 +102305 -0.162322998046875 +102306 -0.0107421875 +102307 -0.194549560546875 +102308 -0.001678466796875 +102309 -0.1492919921875 +102310 0.02471923828125 +102311 -0.02166748046875 +102312 0.053802490234375 +102313 0.124053955078125 +102314 0.068023681640625 +102315 0.211151123046875 +102316 0.067962646484375 +102317 0.240447998046875 +102318 0.061065673828125 +102319 0.242218017578125 +102320 0.049896240234375 +102321 0.2257080078125 +102322 0.035614013671875 +102323 0.194366455078125 +102324 0.011016845703125 +102325 0.115509033203125 +102326 -0.01800537109375 +102327 0.0128173828125 +102328 -0.037322998046875 +102329 -0.053802490234375 +102330 -0.0528564453125 +102331 -0.110626220703125 +102332 -0.074249267578125 +102333 -0.199493408203125 +102334 -0.095458984375 +102335 -0.29437255859375 +102336 -0.101959228515625 +102337 -0.33221435546875 +102338 -0.086181640625 +102339 -0.27972412109375 +102340 -0.059600830078125 +102341 -0.185333251953125 +102342 -0.0408935546875 +102343 -0.128204345703125 +102344 -0.032073974609375 +102345 -0.115692138671875 +102346 -0.02618408203125 +102347 -0.116455078125 +102348 -0.01788330078125 +102349 -0.105926513671875 +102350 -0.00048828125 +102351 -0.053955078125 +102352 0.02789306640625 +102353 0.048797607421875 +102354 0.05657958984375 +102355 0.157318115234375 +102356 0.071563720703125 +102357 0.212005615234375 +102358 0.074066162109375 +102359 0.218475341796875 +102360 0.078125 +102361 0.23724365234375 +102362 0.092376708984375 +102363 0.30535888671875 +102364 0.1072998046875 +102365 0.38128662109375 +102366 0.1090087890625 +102367 0.404449462890625 +102368 0.102294921875 +102369 0.3944091796875 +102370 0.0960693359375 +102371 0.3885498046875 +102372 0.08502197265625 +102373 0.362640380859375 +102374 0.0594482421875 +102375 0.27362060546875 +102376 0.018585205078125 +102377 0.11712646484375 +102378 -0.0252685546875 +102379 -0.054901123046875 +102380 -0.0599365234375 +102381 -0.19085693359375 +102382 -0.084075927734375 +102383 -0.28570556640625 +102384 -0.097564697265625 +102385 -0.339263916015625 +102386 -0.106414794921875 +102387 -0.3775634765625 +102388 -0.121124267578125 +102389 -0.445709228515625 +102390 -0.139801025390625 +102391 -0.535064697265625 +102392 -0.15875244140625 +102393 -0.629058837890625 +102394 -0.171142578125 +102395 -0.697601318359375 +102396 -0.168670654296875 +102397 -0.70391845703125 +102398 -0.150238037109375 +102399 -0.6424560546875 diff --git a/tests/circuitpython/deque_subclass.py b/tests/circuitpython/deque_subclass.py new file mode 100644 index 00000000000..5708407a9b6 --- /dev/null +++ b/tests/circuitpython/deque_subclass.py @@ -0,0 +1,40 @@ +try: + from collections import deque +except ImportError: + print("SKIP") + raise SystemExit + + +class DequeSubclass(deque): + def __init__(self, values, maxlen): + super().__init__(values, maxlen) + + def pop(self): + print("pop") + return super().pop() + + def popleft(self): + print("popleft") + return super().popleft() + + def append(self, value): + print("append") + return super().append(value) + + def appendleft(self, value): + print("appendleft") + return super().appendleft(value) + + def extend(self, value): + print("extend") + return super().extend(value) + + +d = DequeSubclass([1, 2, 3], 10) +print(d.append(4)) +print(d.appendleft(0)) +print(d.pop()) +print(d.popleft()) +d.extend([6, 7]) +# calling list() tests iteration. +print(list(d)) diff --git a/tests/circuitpython/getenv.py b/tests/circuitpython/getenv.py index 941674d114a..3647b562eed 100644 --- a/tests/circuitpython/getenv.py +++ b/tests/circuitpython/getenv.py @@ -58,7 +58,7 @@ def ioctl(self, op, arg): b'key = """\n', b"key =\n", b'key="', - b'key = strings must be quoted\n', + b"key = this is an unquoted string\n", ] @@ -75,6 +75,7 @@ def run_test(key, content): run_test("key", b"") +# key12 does not exist for i in range(13): run_test(f"key{i}", content_good) @@ -82,11 +83,9 @@ def run_test(key, content): for i in range(13): run_test(f"key{i}", content_good) -run_test(f"K", b"K = 7\r\n") -print(getenv_int("K")) - # Test value without trailing newline run_test(f"noeol", b"noeol=3") +# These return None now for content in content_bad: run_test("key", content) diff --git a/tests/circuitpython/getenv.py.exp b/tests/circuitpython/getenv.py.exp index 67707eb67fd..89d654403dc 100644 --- a/tests/circuitpython/getenv.py.exp +++ b/tests/circuitpython/getenv.py.exp @@ -1,6 +1,6 @@ key None key0 'hello world' -key1 7 +key1 '7' key2 '\n' key3 'Áx' key4 'Áx' @@ -9,11 +9,11 @@ key6 '\t\r\x08' key7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' key8 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' key9 'hello comment' -key10 127 -key11 0 +key10 '0x7f' +key11 '0' key12 None key0 'hello world' -key1 7 +key1 '7' key2 '\n' key3 'Áx' key4 'Áx' @@ -22,14 +22,12 @@ key6 '\t\r\x08' key7 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' key8 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' key9 'hello comment' -key10 127 -key11 0 +key10 '0x7f' +key11 '0' key12 None -K 7 -7 -noeol 3 -key Invalid byte '\n' -key Invalid byte '"' -key invalid syntax for integer with base 10: '' -key Invalid byte 'EOF' -key invalid syntax for integer with base 10: 'strings must be quoted' +noeol '3' +key None +key None +key None +key None +key 'this is an unquoted string' diff --git a/tests/circuitpython/issue9705.py b/tests/circuitpython/issue9705.py new file mode 100644 index 00000000000..0c694cc1b9f --- /dev/null +++ b/tests/circuitpython/issue9705.py @@ -0,0 +1,30 @@ +import audiomp3, audiocore + +TEST_FILE = ( + __file__.rsplit("/", 1)[0] + + "/../circuitpython-manual/audiocore/jeplayer-splash-44100-stereo.mp3" +) + + +def loudness(values): + return sum(abs(a) for a in values) + + +def print_frame_loudness(decoder, n): + for i in range(n): + result, buf = audiocore.get_buffer(decoder) + print(f"{i} {result} {loudness(buf):5.0f}") + print() + + +# First frames +decoder = audiomp3.MP3Decoder(TEST_FILE) +print_frame_loudness(decoder, 8) + +# First frames (fresh decoder) +decoder = audiomp3.MP3Decoder(TEST_FILE) +print_frame_loudness(decoder, 2) + +# First frames (reopen) +decoder.open(TEST_FILE) +print_frame_loudness(decoder, 3) diff --git a/tests/circuitpython/issue9705.py.exp b/tests/circuitpython/issue9705.py.exp new file mode 100644 index 00000000000..b57f8e63395 --- /dev/null +++ b/tests/circuitpython/issue9705.py.exp @@ -0,0 +1,16 @@ +0 1 0 +1 1 25 +2 1 830 +3 1 880 +4 1 932 +5 1 892 +6 1 869 +7 1 839 + +0 1 0 +1 1 25 + +0 1 0 +1 1 25 +2 1 830 + diff --git a/tests/circuitpython/mfm.py b/tests/circuitpython/mfm.py index 9839b5c7560..fd2745bc11d 100644 --- a/tests/circuitpython/mfm.py +++ b/tests/circuitpython/mfm.py @@ -1,76 +1,76 @@ import floppyio mfm_content = ( - b'HHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHH' - b'H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0' - b'0HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00H' - b'HHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHH' - b'H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0' - b'0HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00H' - b'HHH00HHHH00HHHH00HHHH00HHHH00HHHH00H00000000000000000000000000' - b'00000000000000000000000000000000000000000000000000000000000000' - b'0000000H0H`H`0H`H`0H`H`00000H0HHH00HHHH00HHHH00HHHH00HHHH00HHH' - b'H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0' - b'0HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00H' - b'HHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHH' - b'H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0' - b'0HHHH00HHHH00HHHH00H000000000000000000000000000000000000000000' - b'00000000000000000000000000000000000000000000000000000H`H`H0`H`' - b'H0`H`H0000000H0000000000000000000000HH0000H`0HH`HH0`000`HH00HH' - b'HH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH' - b'00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00' - b'H0000000000000000000000000000000000000000000000000000000000000' - b'0000000000000000000000000000000000H`H`H0`H`H0`H`H00000`0`0H00H' - b'`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0' - b'HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH' - b'H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H' - b'H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0' - b'H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0' - b'0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H' - b'`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0' - b'HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH' - b'0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0' - b'H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0' - b'H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0' - b'0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H' - b'`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0' - b'HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH' - b'H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H' - b'H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0' - b'H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0' - b'0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H' - b'`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0' - b'HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH' - b'0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0' - b'H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0' - b'H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0' - b'0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H' - b'`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0' - b'HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH' - b'H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H' - b'H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0' - b'H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0' - b'0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H' - b'`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0' - b'HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH' - b'0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0' - b'H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0' - b'H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0' - b'0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H' - b'`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0' - b'HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH' - b'H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H' - b'H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0' - b'H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0' - b'0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H' - b'`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0' - b'HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH' - b'0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0' - b'H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0' - b'H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0' - b'0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H' - b'`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0' - b'HH0HH0H00H`0HHH0H0H00H`0HH0``HHHH0`0000hhhhhhhhhhhhhhhhhhhhhhh' + b"HHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHH" + b"H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0" + b"0HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00H" + b"HHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHH" + b"H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0" + b"0HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00H" + b"HHH00HHHH00HHHH00HHHH00HHHH00HHHH00H00000000000000000000000000" + b"00000000000000000000000000000000000000000000000000000000000000" + b"0000000H0H`H`0H`H`0H`H`00000H0HHH00HHHH00HHHH00HHHH00HHHH00HHH" + b"H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0" + b"0HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00H" + b"HHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHH" + b"H00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH0" + b"0HHHH00HHHH00HHHH00H000000000000000000000000000000000000000000" + b"00000000000000000000000000000000000000000000000000000H`H`H0`H`" + b"H0`H`H0000000H0000000000000000000000HH0000H`0HH`HH0`000`HH00HH" + b"HH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH" + b"00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00HHHH00" + b"H0000000000000000000000000000000000000000000000000000000000000" + b"0000000000000000000000000000000000H`H`H0`H`H0`H`H00000`0`0H00H" + b"`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0" + b"HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH" + b"H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H" + b"H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0" + b"H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0" + b"0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H" + b"`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0" + b"HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH" + b"0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0" + b"H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0" + b"H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0" + b"0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H" + b"`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0" + b"HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH" + b"H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H" + b"H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0" + b"H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0" + b"0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H" + b"`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0" + b"HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH" + b"0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0" + b"H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0" + b"H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0" + b"0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H" + b"`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0" + b"HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH" + b"H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H" + b"H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0" + b"H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0" + b"0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H" + b"`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0" + b"HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH" + b"0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0" + b"H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0" + b"H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0" + b"0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H" + b"`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0" + b"HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HH" + b"H0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0H" + b"H0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0" + b"H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H0" + b"0H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H" + b"`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0" + b"HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH" + b"0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0" + b"H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0" + b"H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H0" + b"0H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H" + b"`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0HH0HH0H00H`0HHH0H0H00H`0" + b"HH0HH0H00H`0HHH0H0H00H`0HH0``HHHH0`0000hhhhhhhhhhhhhhhhhhhhhhh" ) b = bytearray(512) diff --git a/tests/circuitpython/miditrack.py.exp b/tests/circuitpython/miditrack.py.exp index 5aedd79a6b3..22a78e54459 100644 --- a/tests/circuitpython/miditrack.py.exp +++ b/tests/circuitpython/miditrack.py.exp @@ -1,4 +1,4 @@ (0, 1, 512, 1) -1 [-16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, -16384, 16383, 16383] +1 [-16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383] (0, 1, 512, 1) -1 [0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16384, -16384, -16384, -16384, -16384, -16384, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0] +1 [0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0, 0, 0, 0, 0, -16383, -16383, -16383, -16383, -16383, -16383, 0, 0, 0, 0, 0, 0, 16383, 16383, 16383, 16383, 16383, 16383, 0, 0] diff --git a/tests/circuitpython/synth_note_amplitude.py.exp b/tests/circuitpython/synth_note_amplitude.py.exp index 7339e9aa7b5..c5531195b74 100644 --- a/tests/circuitpython/synth_note_amplitude.py.exp +++ b/tests/circuitpython/synth_note_amplitude.py.exp @@ -499,504 +499,504 @@ 0.06225000000000001 0.004058837890625 0.7762060546875 0.06237500000000001 0.0 0.7762060546875 0.0625 0.0 0.7762060546875 -0.06262499999999999 -0.00408935546875 0.7762060546875 -0.06274999999999999 -0.00408935546875 0.7762060546875 -0.06287500000000001 -0.008148193359375 0.7762060546875 -0.063 -0.01220703125 0.7762060546875 -0.063125 -0.01220703125 0.7762060546875 -0.06325000000000001 -0.016265869140625 0.7762060546875 -0.063375 -0.016265869140625 0.7762060546875 -0.0635 -0.02032470703125 0.7762060546875 -0.063625 -0.024383544921875 0.7762060546875 -0.06375 -0.024383544921875 0.7762060546875 -0.063875 -0.0284423828125 0.7762060546875 -0.064 -0.034698486328125 0.9474169921874999 -0.064125 -0.039642333984375 0.9474169921874999 -0.06425000000000001 -0.044586181640625 0.9474169921874999 -0.064375 -0.044586181640625 0.9474169921874999 -0.0645 -0.049530029296875 0.9474169921874999 -0.064625 -0.049530029296875 0.9474169921874999 -0.06475 -0.054443359375 0.9474169921874999 -0.06487500000000001 -0.059356689453125 0.9474169921874999 -0.065 -0.059356689453125 0.9474169921874999 -0.065125 -0.064300537109375 0.9474169921874999 -0.06525 -0.064300537109375 0.9474169921874999 -0.06537500000000001 -0.0692138671875 0.9474169921874999 -0.06550000000000001 -0.0740966796875 0.9474169921874999 -0.065625 -0.0740966796875 0.9474169921874999 -0.06574999999999999 -0.079010009765625 0.9474169921874999 -0.065875 -0.079010009765625 0.9474169921874999 -0.06600000000000001 -0.083892822265625 0.9474169921874999 -0.066125 -0.088775634765625 0.9474169921874999 -0.06625000000000001 -0.088775634765625 0.9474169921874999 -0.06637500000000001 -0.0936279296875 0.9474169921874999 -0.0665 -0.0936279296875 0.9474169921874999 -0.066625 -0.098480224609375 0.9474169921874999 -0.06675 -0.10333251953125 0.9474169921874999 -0.06687500000000001 -0.10333251953125 0.9474169921874999 -0.067 -0.108184814453125 0.9474169921874999 -0.067125 -0.108184814453125 0.9474169921874999 -0.06725000000000001 -0.113006591796875 0.9474169921874999 -0.06737500000000001 -0.1177978515625 0.9474169921874999 -0.0675 -0.1177978515625 0.9474169921874999 -0.067625 -0.122589111328125 0.9474169921874999 -0.06775 -0.122589111328125 0.9474169921874999 -0.06787500000000001 -0.12738037109375 0.9474169921874999 -0.06800000000000001 -0.132171630859375 0.9474169921874999 -0.068125 -0.132171630859375 0.9474169921874999 -0.06825000000000001 -0.13690185546875 0.9474169921874999 -0.068375 -0.13690185546875 0.9474169921874999 -0.06850000000000001 -0.14166259765625 0.9474169921874999 -0.06862500000000001 -0.146392822265625 0.9474169921874999 -0.06875 -0.146392822265625 0.9474169921874999 -0.06887500000000001 -0.151092529296875 0.9474169921874999 -0.069 -0.151092529296875 0.9474169921874999 -0.06912500000000001 -0.155792236328125 0.9474169921874999 -0.06925000000000001 -0.16046142578125 0.9474169921874999 -0.06937500000000001 -0.16046142578125 0.9474169921874999 -0.06950000000000001 -0.165130615234375 0.9474169921874999 -0.069625 -0.165130615234375 0.9474169921874999 -0.06975 -0.169769287109375 0.9474169921874999 -0.06987500000000001 -0.17437744140625 0.9474169921874999 -0.07000000000000001 -0.17437744140625 0.9474169921874999 -0.070125 -0.178985595703125 0.9474169921874999 -0.07025000000000001 -0.178985595703125 0.9474169921874999 -0.07037500000000001 -0.183563232421875 0.9474169921874999 -0.07050000000000001 -0.188140869140625 0.9474169921874999 -0.070625 -0.188140869140625 0.9474169921874999 -0.07075 -0.192657470703125 0.9474169921874999 -0.07087500000000001 -0.192657470703125 0.9474169921874999 -0.07100000000000001 -0.19720458984375 0.9474169921874999 -0.07112500000000001 -0.201690673828125 0.9474169921874999 -0.07125000000000002 -0.201690673828125 0.9474169921874999 -0.07137500000000001 -0.2061767578125 0.9474169921874999 -0.0715 -0.2061767578125 0.9474169921874999 -0.07162500000000001 -0.21063232421875 0.9474169921874999 -0.07175000000000001 -0.215057373046875 0.9474169921874999 -0.07187500000000001 -0.215057373046875 0.9474169921874999 -0.07200000000000001 -0.219451904296875 0.9474169921874999 -0.07212499999999999 -0.219451904296875 0.9474169921874999 -0.07225 -0.223846435546875 0.9474169921874999 -0.07237499999999999 -0.22821044921875 0.9474169921874999 -0.0725 -0.22821044921875 0.9474169921874999 -0.07262499999999999 -0.2325439453125 0.9474169921874999 -0.07274999999999999 -0.2325439453125 0.9474169921874999 -0.072875 -0.236846923828125 0.9474169921874999 -0.073 -0.241119384765625 0.9474169921874999 -0.073125 -0.241119384765625 0.9474169921874999 -0.07324999999999999 -0.245391845703125 0.9474169921874999 -0.07337499999999999 -0.245391845703125 0.9474169921874999 -0.0735 -0.249603271484375 0.9474169921874999 -0.073625 -0.253814697265625 0.9474169921874999 -0.07374999999999999 -0.253814697265625 0.9474169921874999 -0.073875 -0.25799560546875 0.9474169921874999 -0.074 -0.25799560546875 0.9474169921874999 -0.074125 -0.26214599609375 0.9474169921874999 -0.07424999999999999 -0.266265869140625 0.9474169921874999 -0.07437499999999999 -0.266265869140625 0.9474169921874999 -0.0745 -0.270355224609375 0.9474169921874999 -0.07462499999999999 -0.270355224609375 0.9474169921874999 -0.07475 -0.2744140625 0.9474169921874999 -0.07487500000000001 -0.278411865234375 0.9474169921874999 -0.075 -0.278411865234375 0.9474169921874999 -0.07512499999999999 -0.282440185546875 0.9474169921874999 -0.07524999999999999 -0.282440185546875 0.9474169921874999 -0.075375 -0.286376953125 0.9474169921874999 -0.0755 -0.29034423828125 0.9474169921874999 -0.075625 -0.29034423828125 0.9474169921874999 -0.07574999999999999 -0.29425048828125 0.9474169921874999 -0.075875 -0.29425048828125 0.9474169921874999 -0.076 -0.298095703125 0.9474169921874999 -0.076125 -0.30194091796875 0.9474169921874999 -0.07625 -0.30194091796875 0.9474169921874999 -0.07637499999999999 -0.305755615234375 0.9474169921874999 -0.0765 -0.305755615234375 0.9474169921874999 -0.076625 -0.30950927734375 0.9474169921874999 -0.07675 -0.313262939453125 0.9474169921874999 -0.076875 -0.313262939453125 0.9474169921874999 -0.077 -0.31695556640625 0.9474169921874999 -0.077125 -0.31695556640625 0.9474169921874999 -0.07725 -0.320648193359375 0.9474169921874999 -0.07737499999999999 -0.324249267578125 0.9474169921874999 -0.0775 -0.324249267578125 0.9474169921874999 -0.077625 -0.327850341796875 0.9474169921874999 -0.07774999999999999 -0.327850341796875 0.9474169921874999 -0.07787500000000001 -0.3314208984375 0.9474169921874999 -0.07800000000000001 -0.3349609375 0.9474169921874999 -0.078125 -0.3349609375 0.9474169921874999 -0.07824999999999999 -0.33843994140625 0.9474169921874999 -0.07837499999999999 -0.33843994140625 0.9474169921874999 -0.07850000000000001 -0.341888427734375 0.9474169921874999 -0.078625 -0.345306396484375 0.9474169921874999 -0.07875 -0.345306396484375 0.9474169921874999 -0.07887500000000001 -0.34869384765625 0.9474169921874999 -0.079 -0.34869384765625 0.9474169921874999 -0.079125 -0.352020263671875 0.9474169921874999 -0.07925 -0.355316162109375 0.9474169921874999 -0.079375 -0.355316162109375 0.9474169921874999 -0.0795 -0.35858154296875 0.9474169921874999 -0.079625 -0.35858154296875 0.9474169921874999 -0.07975 -0.36181640625 0.9474169921874999 -0.07987500000000001 -0.364990234375 0.9474169921874999 -0.08 -0.364990234375 0.9474169921874999 -0.08012499999999999 -0.368133544921875 0.9474169921874999 -0.08025 -0.368133544921875 0.9474169921874999 -0.080375 -0.3712158203125 0.9474169921874999 -0.08050000000000001 -0.374298095703125 0.9474169921874999 -0.080625 -0.374298095703125 0.9474169921874999 -0.08074999999999999 -0.377288818359375 0.9474169921874999 -0.080875 -0.377288818359375 0.9474169921874999 -0.08100000000000001 -0.380279541015625 0.9474169921874999 -0.08112500000000001 -0.38323974609375 0.9474169921874999 -0.08125 -0.38323974609375 0.9474169921874999 -0.08137499999999999 -0.3861083984375 0.9474169921874999 -0.0815 -0.3861083984375 0.9474169921874999 -0.081625 -0.38897705078125 0.9474169921874999 -0.08175000000000001 -0.39178466796875 0.9474169921874999 -0.081875 -0.39178466796875 0.9474169921874999 -0.08200000000000001 -0.394561767578125 0.9474169921874999 -0.082125 -0.394561767578125 0.9474169921874999 -0.08225 -0.39727783203125 0.9474169921874999 -0.08237500000000001 -0.39996337890625 0.9474169921874999 -0.0825 -0.39996337890625 0.9474169921874999 -0.08262500000000001 -0.402587890625 0.9474169921874999 -0.08275 -0.402587890625 0.9474169921874999 -0.08287500000000001 -0.405181884765625 0.9474169921874999 -0.08300000000000001 -0.40771484375 0.9474169921874999 -0.083125 -0.40771484375 0.9474169921874999 -0.08324999999999999 -0.410247802734375 0.9474169921874999 -0.083375 -0.410247802734375 0.9474169921874999 -0.08350000000000001 -0.412689208984375 0.9474169921874999 -0.08362500000000001 -0.41510009765625 0.9474169921874999 -0.08375 -0.41510009765625 0.9474169921874999 -0.08387500000000001 -0.417449951171875 0.9474169921874999 -0.084 -0.417449951171875 0.9474169921874999 -0.08412500000000001 -0.4197998046875 0.9474169921874999 -0.08425000000000001 -0.42205810546875 0.9474169921874999 -0.084375 -0.42205810546875 0.9474169921874999 -0.08450000000000001 -0.424285888671875 0.9474169921874999 -0.084625 -0.424285888671875 0.9474169921874999 -0.08475 -0.42645263671875 0.9474169921874999 -0.08487500000000001 -0.428619384765625 0.9474169921874999 -0.085 -0.428619384765625 0.9474169921874999 -0.08512500000000001 -0.430694580078125 0.9474169921874999 -0.08525 -0.430694580078125 0.9474169921874999 -0.085375 -0.4327392578125 0.9474169921874999 -0.08550000000000001 -0.434722900390625 0.9474169921874999 -0.085625 -0.434722900390625 0.9474169921874999 -0.08575000000000001 -0.436676025390625 0.9474169921874999 -0.08587500000000002 -0.436676025390625 0.9474169921874999 -0.08600000000000001 -0.438568115234375 0.9474169921874999 -0.08612500000000001 -0.4404296875 0.9474169921874999 -0.08625 -0.4404296875 0.9474169921874999 -0.08637499999999999 -0.442230224609375 0.9474169921874999 -0.0865 -0.442230224609375 0.9474169921874999 -0.08662500000000001 -0.4439697265625 0.9474169921874999 -0.08675000000000001 -0.4456787109375 0.9474169921874999 -0.08687500000000002 -0.4456787109375 0.9474169921874999 -0.08700000000000001 -0.44732666015625 0.9474169921874999 -0.087125 -0.44732666015625 0.9474169921874999 -0.08725000000000001 -0.448944091796875 0.9474169921874999 -0.08737500000000001 -0.45050048828125 0.9474169921874999 -0.08750000000000002 -0.45050048828125 0.9474169921874999 -0.08762500000000001 -0.451995849609375 0.9474169921874999 -0.08775 -0.451995849609375 0.9474169921874999 -0.08787500000000001 -0.453460693359375 0.9474169921874999 -0.08799999999999999 -0.454864501953125 0.9474169921874999 -0.088125 -0.454864501953125 0.9474169921874999 -0.08824999999999999 -0.45623779296875 0.9474169921874999 -0.08837499999999999 -0.45623779296875 0.9474169921874999 -0.0885 -0.457550048828125 0.9474169921874999 -0.08862500000000001 -0.45880126953125 0.9474169921874999 -0.08875 -0.45880126953125 0.9474169921874999 -0.08887499999999999 -0.46002197265625 0.9474169921874999 -0.08899999999999999 -0.46002197265625 0.9474169921874999 -0.089125 -0.461181640625 0.9474169921874999 -0.08924999999999999 -0.4622802734375 0.9474169921874999 -0.089375 -0.4622802734375 0.9474169921874999 -0.08949999999999999 -0.46331787109375 0.9474169921874999 -0.089625 -0.46331787109375 0.9474169921874999 -0.08975 -0.46435546875 0.9474169921874999 -0.08987499999999999 -0.465301513671875 0.9474169921874999 -0.09 -0.465301513671875 0.9474169921874999 -0.09012499999999999 -0.466217041015625 0.9474169921874999 -0.09025 -0.466217041015625 0.9474169921874999 -0.090375 -0.467071533203125 0.9474169921874999 -0.09050000000000001 -0.467864990234375 0.9474169921874999 -0.090625 -0.467864990234375 0.9474169921874999 -0.09074999999999999 -0.468597412109375 0.9474169921874999 -0.09087499999999999 -0.468597412109375 0.9474169921874999 -0.091 -0.46929931640625 0.9474169921874999 -0.09112500000000001 -0.469940185546875 0.9474169921874999 -0.09125 -0.469940185546875 0.9474169921874999 -0.09137499999999999 -0.470550537109375 0.9474169921874999 -0.0915 -0.470550537109375 0.9474169921874999 -0.091625 -0.471099853515625 0.9474169921874999 -0.09175000000000001 -0.471588134765625 0.9474169921874999 -0.091875 -0.471588134765625 0.9474169921874999 -0.09199999999999999 -0.4720458984375 0.9474169921874999 -0.092125 -0.4720458984375 0.9474169921874999 -0.09225 -0.472412109375 0.9474169921874999 -0.09237499999999999 -0.472747802734375 0.9474169921874999 -0.0925 -0.472747802734375 0.9474169921874999 -0.09262499999999999 -0.473052978515625 0.9474169921874999 -0.09275 -0.473052978515625 0.9474169921874999 -0.092875 -0.4732666015625 0.9474169921874999 -0.09299999999999999 -0.47344970703125 0.9474169921874999 -0.093125 -0.47344970703125 0.9474169921874999 -0.09324999999999999 -0.47357177734375 0.9474169921874999 -0.093375 -0.47357177734375 0.9474169921874999 -0.09350000000000001 -0.473663330078125 0.9474169921874999 -0.09362500000000001 -0.47369384765625 0.9474169921874999 -0.09375 -0.47369384765625 0.9474169921874999 -0.09387499999999999 -0.473663330078125 0.9474169921874999 -0.09399999999999999 -0.473663330078125 0.9474169921874999 -0.094125 -0.47357177734375 0.9474169921874999 -0.09425000000000001 -0.47344970703125 0.9474169921874999 -0.094375 -0.47344970703125 0.9474169921874999 -0.09450000000000001 -0.4732666015625 0.9474169921874999 -0.094625 -0.4732666015625 0.9474169921874999 -0.09475 -0.473052978515625 0.9474169921874999 -0.09487500000000001 -0.472747802734375 0.9474169921874999 -0.095 -0.472747802734375 0.9474169921874999 -0.09512500000000001 -0.472412109375 0.9474169921874999 -0.09525 -0.472412109375 0.9474169921874999 -0.095375 -0.4720458984375 0.9474169921874999 -0.09550000000000001 -0.471588134765625 0.9474169921874999 -0.095625 -0.471588134765625 0.9474169921874999 -0.09574999999999999 -0.471099853515625 0.9474169921874999 -0.095875 -0.471099853515625 0.9474169921874999 -0.096 -0.496368408203125 0.9993847656250001 -0.09612500000000001 -0.4957275390625 0.9993847656250001 -0.09625 -0.4957275390625 0.9993847656250001 -0.09637499999999999 -0.49505615234375 0.9993847656250001 -0.0965 -0.49505615234375 0.9993847656250001 -0.09662500000000001 -0.49432373046875 0.9993847656250001 -0.09675000000000001 -0.4935302734375 0.9993847656250001 -0.096875 -0.4935302734375 0.9993847656250001 -0.09699999999999999 -0.49267578125 0.9993847656250001 -0.097125 -0.49267578125 0.9993847656250001 -0.09725 -0.491790771484375 0.9993847656250001 -0.09737500000000001 -0.490814208984375 0.9993847656250001 -0.0975 -0.490814208984375 0.9993847656250001 -0.09762500000000001 -0.48980712890625 0.9993847656250001 -0.09775 -0.48980712890625 0.9993847656250001 -0.097875 -0.488739013671875 0.9993847656250001 -0.09800000000000001 -0.487640380859375 0.9993847656250001 -0.098125 -0.487640380859375 0.9993847656250001 -0.09825000000000001 -0.486480712890625 0.9993847656250001 -0.098375 -0.486480712890625 0.9993847656250001 -0.09850000000000001 -0.485260009765625 0.9993847656250001 -0.09862500000000001 -0.483978271484375 0.9993847656250001 -0.09875 -0.483978271484375 0.9993847656250001 -0.09887499999999999 -0.482635498046875 0.9993847656250001 -0.099 -0.482635498046875 0.9993847656250001 -0.09912500000000001 -0.48126220703125 0.9993847656250001 -0.09925000000000001 -0.479827880859375 0.9993847656250001 -0.099375 -0.479827880859375 0.9993847656250001 -0.09950000000000001 -0.47833251953125 0.9993847656250001 -0.099625 -0.47833251953125 0.9993847656250001 -0.09975000000000001 -0.476806640625 0.9993847656250001 -0.09987500000000001 -0.4752197265625 0.9993847656250001 -0.1 -0.4752197265625 0.9993847656250001 -0.100125 -0.47357177734375 0.9993847656250001 -0.10025 -0.47357177734375 0.9993847656250001 -0.100375 -0.471893310546875 0.9993847656250001 -0.1005 -0.470123291015625 0.9993847656250001 -0.100625 -0.470123291015625 0.9993847656250001 -0.10075 -0.46832275390625 0.9993847656250001 -0.100875 -0.46832275390625 0.9993847656250001 -0.101 -0.46649169921875 0.9993847656250001 -0.101125 -0.464569091796875 0.9993847656250001 -0.10125 -0.464569091796875 0.9993847656250001 -0.101375 -0.462646484375 0.9993847656250001 -0.1015 -0.462646484375 0.9993847656250001 -0.101625 -0.46063232421875 0.9993847656250001 -0.10175 -0.458587646484375 0.9993847656250001 -0.101875 -0.458587646484375 0.9993847656250001 -0.102 -0.45648193359375 0.9993847656250001 -0.102125 -0.45648193359375 0.9993847656250001 -0.10225 -0.454315185546875 0.9993847656250001 -0.102375 -0.452117919921875 0.9993847656250001 -0.1025 -0.452117919921875 0.9993847656250001 -0.102625 -0.449859619140625 0.9993847656250001 -0.10275 -0.449859619140625 0.9993847656250001 -0.102875 -0.44757080078125 0.9993847656250001 -0.103 -0.445220947265625 0.9993847656250001 -0.103125 -0.445220947265625 0.9993847656250001 -0.10325 -0.44281005859375 0.9993847656250001 -0.103375 -0.44281005859375 0.9993847656250001 -0.1035 -0.44036865234375 0.9993847656250001 -0.103625 -0.4378662109375 0.9993847656250001 -0.10375 -0.4378662109375 0.9993847656250001 -0.103875 -0.435333251953125 0.9993847656250001 -0.104 -0.435333251953125 0.9993847656250001 -0.104125 -0.4327392578125 0.9993847656250001 -0.10425 -0.430084228515625 0.9993847656250001 -0.104375 -0.430084228515625 0.9993847656250001 -0.1045 -0.427398681640625 0.9993847656250001 -0.104625 -0.427398681640625 0.9993847656250001 -0.10475 -0.4246826171875 0.9993847656250001 -0.104875 -0.421905517578125 0.9993847656250001 -0.105 -0.421905517578125 0.9993847656250001 -0.105125 -0.4190673828125 0.9993847656250001 -0.10525 -0.4190673828125 0.9993847656250001 -0.105375 -0.41619873046875 0.9993847656250001 -0.1055 -0.41326904296875 0.9993847656250001 -0.105625 -0.41326904296875 0.9993847656250001 -0.10575 -0.410308837890625 0.9993847656250001 -0.105875 -0.410308837890625 0.9993847656250001 -0.106 -0.40728759765625 0.9993847656250001 -0.106125 -0.404266357421875 0.9993847656250001 -0.10625 -0.404266357421875 0.9993847656250001 -0.106375 -0.401153564453125 0.9993847656250001 -0.1065 -0.401153564453125 0.9993847656250001 -0.106625 -0.39801025390625 0.9993847656250001 -0.10675 -0.39483642578125 0.9993847656250001 -0.106875 -0.39483642578125 0.9993847656250001 -0.107 -0.3916015625 0.9993847656250001 -0.107125 -0.3916015625 0.9993847656250001 -0.10725 -0.3883056640625 0.9993847656250001 -0.107375 -0.385009765625 0.9993847656250001 -0.1075 -0.385009765625 0.9993847656250001 -0.107625 -0.38165283203125 0.9993847656250001 -0.10775 -0.38165283203125 0.9993847656250001 -0.107875 -0.378265380859375 0.9993847656250001 -0.108 -0.37481689453125 0.9993847656250001 -0.108125 -0.37481689453125 0.9993847656250001 -0.10825 -0.371337890625 0.9993847656250001 -0.108375 -0.371337890625 0.9993847656250001 -0.1085 -0.3677978515625 0.9993847656250001 -0.108625 -0.3642578125 0.9993847656250001 -0.10875 -0.3642578125 0.9993847656250001 -0.108875 -0.360626220703125 0.9993847656250001 -0.109 -0.360626220703125 0.9993847656250001 -0.109125 -0.35699462890625 0.9993847656250001 -0.10925 -0.35333251953125 0.9993847656250001 -0.109375 -0.35333251953125 0.9993847656250001 -0.1095 -0.349609375 0.9993847656250001 -0.109625 -0.349609375 0.9993847656250001 -0.10975 -0.345855712890625 0.9993847656250001 -0.109875 -0.342041015625 0.9993847656250001 -0.11 -0.342041015625 0.9993847656250001 -0.110125 -0.338226318359375 0.9993847656250001 -0.11025 -0.338226318359375 0.9993847656250001 -0.110375 -0.3343505859375 0.9993847656250001 -0.1105 -0.3304443359375 0.9993847656250001 -0.110625 -0.3304443359375 0.9993847656250001 -0.11075 -0.326507568359375 0.9993847656250001 -0.110875 -0.326507568359375 0.9993847656250001 -0.111 -0.322509765625 0.9993847656250001 -0.111125 -0.318511962890625 0.9993847656250001 -0.11125 -0.318511962890625 0.9993847656250001 -0.111375 -0.314453125 0.9993847656250001 -0.1115 -0.314453125 0.9993847656250001 -0.111625 -0.31036376953125 0.9993847656250001 -0.11175 -0.3062744140625 0.9993847656250001 -0.111875 -0.3062744140625 0.9993847656250001 -0.112 -0.302093505859375 0.9993847656250001 -0.112125 -0.302093505859375 0.9993847656250001 -0.11225 -0.29791259765625 0.9993847656250001 -0.112375 -0.293701171875 0.9993847656250001 -0.1125 -0.293701171875 0.9993847656250001 -0.112625 -0.289459228515625 0.9993847656250001 -0.11275 -0.289459228515625 0.9993847656250001 -0.112875 -0.285186767578125 0.9993847656250001 -0.113 -0.280853271484375 0.9993847656250001 -0.113125 -0.280853271484375 0.9993847656250001 -0.11325 -0.276519775390625 0.9993847656250001 -0.113375 -0.276519775390625 0.9993847656250001 -0.1135 -0.27215576171875 0.9993847656250001 -0.113625 -0.267730712890625 0.9993847656250001 -0.11375 -0.267730712890625 0.9993847656250001 -0.113875 -0.2633056640625 0.9993847656250001 -0.114 -0.2633056640625 0.9993847656250001 -0.114125 -0.25885009765625 0.9993847656250001 -0.11425 -0.254364013671875 0.9993847656250001 -0.114375 -0.254364013671875 0.9993847656250001 -0.1145 -0.249847412109375 0.9993847656250001 -0.114625 -0.249847412109375 0.9993847656250001 -0.11475 -0.24530029296875 0.9993847656250001 -0.114875 -0.24072265625 0.9993847656250001 -0.115 -0.24072265625 0.9993847656250001 -0.115125 -0.23614501953125 0.9993847656250001 -0.11525 -0.23614501953125 0.9993847656250001 -0.115375 -0.23150634765625 0.9993847656250001 -0.1155 -0.226837158203125 0.9993847656250001 -0.115625 -0.226837158203125 0.9993847656250001 -0.11575 -0.22216796875 0.9993847656250001 -0.115875 -0.22216796875 0.9993847656250001 -0.116 -0.21746826171875 0.9993847656250001 -0.116125 -0.2127685546875 0.9993847656250001 -0.11625 -0.2127685546875 0.9993847656250001 -0.116375 -0.2080078125 0.9993847656250001 -0.1165 -0.2080078125 0.9993847656250001 -0.116625 -0.2032470703125 0.9993847656250001 -0.11675 -0.198455810546875 0.9993847656250001 -0.116875 -0.198455810546875 0.9993847656250001 -0.117 -0.193634033203125 0.9993847656250001 -0.117125 -0.193634033203125 0.9993847656250001 -0.11725 -0.188812255859375 0.9993847656250001 -0.117375 -0.1839599609375 0.9993847656250001 -0.1175 -0.1839599609375 0.9993847656250001 -0.117625 -0.1790771484375 0.9993847656250001 -0.11775 -0.1790771484375 0.9993847656250001 -0.117875 -0.174163818359375 0.9993847656250001 -0.118 -0.16925048828125 0.9993847656250001 -0.118125 -0.16925048828125 0.9993847656250001 -0.11825 -0.164337158203125 0.9993847656250001 -0.118375 -0.164337158203125 0.9993847656250001 -0.1185 -0.159393310546875 0.9993847656250001 -0.118625 -0.1544189453125 0.9993847656250001 -0.11875 -0.1544189453125 0.9993847656250001 -0.118875 -0.1494140625 0.9993847656250001 -0.119 -0.1494140625 0.9993847656250001 -0.119125 -0.1444091796875 0.9993847656250001 -0.11925 -0.139404296875 0.9993847656250001 -0.119375 -0.139404296875 0.9993847656250001 -0.1195 -0.134368896484375 0.9993847656250001 -0.119625 -0.134368896484375 0.9993847656250001 -0.11975 -0.12933349609375 0.9993847656250001 -0.119875 -0.124267578125 0.9993847656250001 -0.12 -0.124267578125 0.9993847656250001 -0.120125 -0.11920166015625 0.9993847656250001 -0.12025 -0.11920166015625 0.9993847656250001 -0.120375 -0.114105224609375 0.9993847656250001 -0.1205 -0.1090087890625 0.9993847656250001 -0.120625 -0.1090087890625 0.9993847656250001 -0.12075 -0.1038818359375 0.9993847656250001 -0.120875 -0.1038818359375 0.9993847656250001 -0.121 -0.0987548828125 0.9993847656250001 -0.121125 -0.0936279296875 0.9993847656250001 -0.12125 -0.0936279296875 0.9993847656250001 -0.121375 -0.0885009765625 0.9993847656250001 -0.1215 -0.0885009765625 0.9993847656250001 -0.121625 -0.083343505859375 0.9993847656250001 -0.12175 -0.078155517578125 0.9993847656250001 -0.121875 -0.078155517578125 0.9993847656250001 -0.122 -0.072998046875 0.9993847656250001 -0.122125 -0.072998046875 0.9993847656250001 -0.12225 -0.06781005859375 0.9993847656250001 -0.122375 -0.0626220703125 0.9993847656250001 -0.1225 -0.0626220703125 0.9993847656250001 -0.122625 -0.05743408203125 0.9993847656250001 -0.12275 -0.05743408203125 0.9993847656250001 -0.122875 -0.05224609375 0.9993847656250001 -0.123 -0.047027587890625 0.9993847656250001 -0.123125 -0.047027587890625 0.9993847656250001 -0.12325 -0.04180908203125 0.9993847656250001 -0.123375 -0.04180908203125 0.9993847656250001 -0.1235 -0.036590576171875 0.9993847656250001 -0.123625 -0.0313720703125 0.9993847656250001 -0.12375 -0.0313720703125 0.9993847656250001 -0.123875 -0.026153564453125 0.9993847656250001 -0.124 -0.026153564453125 0.9993847656250001 -0.124125 -0.02093505859375 0.9993847656250001 -0.12425 -0.015716552734375 0.9993847656250001 -0.124375 -0.015716552734375 0.9993847656250001 -0.1245 -0.010467529296875 0.9993847656250001 -0.124625 -0.010467529296875 0.9993847656250001 -0.12475 -0.0052490234375 0.9993847656250001 +0.06262499999999999 -0.004058837890625 0.7762060546875 +0.06274999999999999 -0.004058837890625 0.7762060546875 +0.06287500000000001 -0.00811767578125 0.7762060546875 +0.063 -0.012176513671875 0.7762060546875 +0.063125 -0.012176513671875 0.7762060546875 +0.06325000000000001 -0.0162353515625 0.7762060546875 +0.063375 -0.0162353515625 0.7762060546875 +0.0635 -0.020294189453125 0.7762060546875 +0.063625 -0.02435302734375 0.7762060546875 +0.06375 -0.02435302734375 0.7762060546875 +0.063875 -0.028411865234375 0.7762060546875 +0.064 -0.03466796875 0.9474169921874999 +0.064125 -0.03961181640625 0.9474169921874999 +0.06425000000000001 -0.0445556640625 0.9474169921874999 +0.064375 -0.0445556640625 0.9474169921874999 +0.0645 -0.04949951171875 0.9474169921874999 +0.064625 -0.04949951171875 0.9474169921874999 +0.06475 -0.054412841796875 0.9474169921874999 +0.06487500000000001 -0.059326171875 0.9474169921874999 +0.065 -0.059326171875 0.9474169921874999 +0.065125 -0.06427001953125 0.9474169921874999 +0.06525 -0.06427001953125 0.9474169921874999 +0.06537500000000001 -0.069183349609375 0.9474169921874999 +0.06550000000000001 -0.074066162109375 0.9474169921874999 +0.065625 -0.074066162109375 0.9474169921874999 +0.06574999999999999 -0.0789794921875 0.9474169921874999 +0.065875 -0.0789794921875 0.9474169921874999 +0.06600000000000001 -0.0838623046875 0.9474169921874999 +0.066125 -0.0887451171875 0.9474169921874999 +0.06625000000000001 -0.0887451171875 0.9474169921874999 +0.06637500000000001 -0.093597412109375 0.9474169921874999 +0.0665 -0.093597412109375 0.9474169921874999 +0.066625 -0.09844970703125 0.9474169921874999 +0.06675 -0.103302001953125 0.9474169921874999 +0.06687500000000001 -0.103302001953125 0.9474169921874999 +0.067 -0.108154296875 0.9474169921874999 +0.067125 -0.108154296875 0.9474169921874999 +0.06725000000000001 -0.11297607421875 0.9474169921874999 +0.06737500000000001 -0.117767333984375 0.9474169921874999 +0.0675 -0.117767333984375 0.9474169921874999 +0.067625 -0.12255859375 0.9474169921874999 +0.06775 -0.12255859375 0.9474169921874999 +0.06787500000000001 -0.127349853515625 0.9474169921874999 +0.06800000000000001 -0.13214111328125 0.9474169921874999 +0.068125 -0.13214111328125 0.9474169921874999 +0.06825000000000001 -0.136871337890625 0.9474169921874999 +0.068375 -0.136871337890625 0.9474169921874999 +0.06850000000000001 -0.141632080078125 0.9474169921874999 +0.06862500000000001 -0.1463623046875 0.9474169921874999 +0.06875 -0.1463623046875 0.9474169921874999 +0.06887500000000001 -0.15106201171875 0.9474169921874999 +0.069 -0.15106201171875 0.9474169921874999 +0.06912500000000001 -0.15576171875 0.9474169921874999 +0.06925000000000001 -0.160430908203125 0.9474169921874999 +0.06937500000000001 -0.160430908203125 0.9474169921874999 +0.06950000000000001 -0.16510009765625 0.9474169921874999 +0.069625 -0.16510009765625 0.9474169921874999 +0.06975 -0.16973876953125 0.9474169921874999 +0.06987500000000001 -0.174346923828125 0.9474169921874999 +0.07000000000000001 -0.174346923828125 0.9474169921874999 +0.070125 -0.178955078125 0.9474169921874999 +0.07025000000000001 -0.178955078125 0.9474169921874999 +0.07037500000000001 -0.18353271484375 0.9474169921874999 +0.07050000000000001 -0.1881103515625 0.9474169921874999 +0.070625 -0.1881103515625 0.9474169921874999 +0.07075 -0.192626953125 0.9474169921874999 +0.07087500000000001 -0.192626953125 0.9474169921874999 +0.07100000000000001 -0.197174072265625 0.9474169921874999 +0.07112500000000001 -0.20166015625 0.9474169921874999 +0.07125000000000002 -0.20166015625 0.9474169921874999 +0.07137500000000001 -0.206146240234375 0.9474169921874999 +0.0715 -0.206146240234375 0.9474169921874999 +0.07162500000000001 -0.210601806640625 0.9474169921874999 +0.07175000000000001 -0.21502685546875 0.9474169921874999 +0.07187500000000001 -0.21502685546875 0.9474169921874999 +0.07200000000000001 -0.21942138671875 0.9474169921874999 +0.07212499999999999 -0.21942138671875 0.9474169921874999 +0.07225 -0.22381591796875 0.9474169921874999 +0.07237499999999999 -0.228179931640625 0.9474169921874999 +0.0725 -0.228179931640625 0.9474169921874999 +0.07262499999999999 -0.232513427734375 0.9474169921874999 +0.07274999999999999 -0.232513427734375 0.9474169921874999 +0.072875 -0.23681640625 0.9474169921874999 +0.073 -0.2410888671875 0.9474169921874999 +0.073125 -0.2410888671875 0.9474169921874999 +0.07324999999999999 -0.245361328125 0.9474169921874999 +0.07337499999999999 -0.245361328125 0.9474169921874999 +0.0735 -0.24957275390625 0.9474169921874999 +0.073625 -0.2537841796875 0.9474169921874999 +0.07374999999999999 -0.2537841796875 0.9474169921874999 +0.073875 -0.257965087890625 0.9474169921874999 +0.074 -0.257965087890625 0.9474169921874999 +0.074125 -0.262115478515625 0.9474169921874999 +0.07424999999999999 -0.2662353515625 0.9474169921874999 +0.07437499999999999 -0.2662353515625 0.9474169921874999 +0.0745 -0.27032470703125 0.9474169921874999 +0.07462499999999999 -0.27032470703125 0.9474169921874999 +0.07475 -0.274383544921875 0.9474169921874999 +0.07487500000000001 -0.27838134765625 0.9474169921874999 +0.075 -0.27838134765625 0.9474169921874999 +0.07512499999999999 -0.28240966796875 0.9474169921874999 +0.07524999999999999 -0.28240966796875 0.9474169921874999 +0.075375 -0.286346435546875 0.9474169921874999 +0.0755 -0.290313720703125 0.9474169921874999 +0.075625 -0.290313720703125 0.9474169921874999 +0.07574999999999999 -0.294219970703125 0.9474169921874999 +0.075875 -0.294219970703125 0.9474169921874999 +0.076 -0.298065185546875 0.9474169921874999 +0.076125 -0.301910400390625 0.9474169921874999 +0.07625 -0.301910400390625 0.9474169921874999 +0.07637499999999999 -0.30572509765625 0.9474169921874999 +0.0765 -0.30572509765625 0.9474169921874999 +0.076625 -0.309478759765625 0.9474169921874999 +0.07675 -0.313232421875 0.9474169921874999 +0.076875 -0.313232421875 0.9474169921874999 +0.077 -0.316925048828125 0.9474169921874999 +0.077125 -0.316925048828125 0.9474169921874999 +0.07725 -0.32061767578125 0.9474169921874999 +0.07737499999999999 -0.32421875 0.9474169921874999 +0.0775 -0.32421875 0.9474169921874999 +0.077625 -0.32781982421875 0.9474169921874999 +0.07774999999999999 -0.32781982421875 0.9474169921874999 +0.07787500000000001 -0.331390380859375 0.9474169921874999 +0.07800000000000001 -0.334930419921875 0.9474169921874999 +0.078125 -0.334930419921875 0.9474169921874999 +0.07824999999999999 -0.338409423828125 0.9474169921874999 +0.07837499999999999 -0.338409423828125 0.9474169921874999 +0.07850000000000001 -0.34185791015625 0.9474169921874999 +0.078625 -0.34527587890625 0.9474169921874999 +0.07875 -0.34527587890625 0.9474169921874999 +0.07887500000000001 -0.348663330078125 0.9474169921874999 +0.079 -0.348663330078125 0.9474169921874999 +0.079125 -0.35198974609375 0.9474169921874999 +0.07925 -0.35528564453125 0.9474169921874999 +0.079375 -0.35528564453125 0.9474169921874999 +0.0795 -0.358551025390625 0.9474169921874999 +0.079625 -0.358551025390625 0.9474169921874999 +0.07975 -0.361785888671875 0.9474169921874999 +0.07987500000000001 -0.364959716796875 0.9474169921874999 +0.08 -0.364959716796875 0.9474169921874999 +0.08012499999999999 -0.36810302734375 0.9474169921874999 +0.08025 -0.36810302734375 0.9474169921874999 +0.080375 -0.371185302734375 0.9474169921874999 +0.08050000000000001 -0.374267578125 0.9474169921874999 +0.080625 -0.374267578125 0.9474169921874999 +0.08074999999999999 -0.37725830078125 0.9474169921874999 +0.080875 -0.37725830078125 0.9474169921874999 +0.08100000000000001 -0.3802490234375 0.9474169921874999 +0.08112500000000001 -0.383209228515625 0.9474169921874999 +0.08125 -0.383209228515625 0.9474169921874999 +0.08137499999999999 -0.386077880859375 0.9474169921874999 +0.0815 -0.386077880859375 0.9474169921874999 +0.081625 -0.388946533203125 0.9474169921874999 +0.08175000000000001 -0.391754150390625 0.9474169921874999 +0.081875 -0.391754150390625 0.9474169921874999 +0.08200000000000001 -0.39453125 0.9474169921874999 +0.082125 -0.39453125 0.9474169921874999 +0.08225 -0.397247314453125 0.9474169921874999 +0.08237500000000001 -0.399932861328125 0.9474169921874999 +0.0825 -0.399932861328125 0.9474169921874999 +0.08262500000000001 -0.402557373046875 0.9474169921874999 +0.08275 -0.402557373046875 0.9474169921874999 +0.08287500000000001 -0.4051513671875 0.9474169921874999 +0.08300000000000001 -0.407684326171875 0.9474169921874999 +0.083125 -0.407684326171875 0.9474169921874999 +0.08324999999999999 -0.41021728515625 0.9474169921874999 +0.083375 -0.41021728515625 0.9474169921874999 +0.08350000000000001 -0.41265869140625 0.9474169921874999 +0.08362500000000001 -0.415069580078125 0.9474169921874999 +0.08375 -0.415069580078125 0.9474169921874999 +0.08387500000000001 -0.41741943359375 0.9474169921874999 +0.084 -0.41741943359375 0.9474169921874999 +0.08412500000000001 -0.419769287109375 0.9474169921874999 +0.08425000000000001 -0.422027587890625 0.9474169921874999 +0.084375 -0.422027587890625 0.9474169921874999 +0.08450000000000001 -0.42425537109375 0.9474169921874999 +0.084625 -0.42425537109375 0.9474169921874999 +0.08475 -0.426422119140625 0.9474169921874999 +0.08487500000000001 -0.4285888671875 0.9474169921874999 +0.085 -0.4285888671875 0.9474169921874999 +0.08512500000000001 -0.4306640625 0.9474169921874999 +0.08525 -0.4306640625 0.9474169921874999 +0.085375 -0.432708740234375 0.9474169921874999 +0.08550000000000001 -0.4346923828125 0.9474169921874999 +0.085625 -0.4346923828125 0.9474169921874999 +0.08575000000000001 -0.4366455078125 0.9474169921874999 +0.08587500000000002 -0.4366455078125 0.9474169921874999 +0.08600000000000001 -0.43853759765625 0.9474169921874999 +0.08612500000000001 -0.440399169921875 0.9474169921874999 +0.08625 -0.440399169921875 0.9474169921874999 +0.08637499999999999 -0.44219970703125 0.9474169921874999 +0.0865 -0.44219970703125 0.9474169921874999 +0.08662500000000001 -0.443939208984375 0.9474169921874999 +0.08675000000000001 -0.445648193359375 0.9474169921874999 +0.08687500000000002 -0.445648193359375 0.9474169921874999 +0.08700000000000001 -0.447296142578125 0.9474169921874999 +0.087125 -0.447296142578125 0.9474169921874999 +0.08725000000000001 -0.44891357421875 0.9474169921874999 +0.08737500000000001 -0.450469970703125 0.9474169921874999 +0.08750000000000002 -0.450469970703125 0.9474169921874999 +0.08762500000000001 -0.45196533203125 0.9474169921874999 +0.08775 -0.45196533203125 0.9474169921874999 +0.08787500000000001 -0.45343017578125 0.9474169921874999 +0.08799999999999999 -0.454833984375 0.9474169921874999 +0.088125 -0.454833984375 0.9474169921874999 +0.08824999999999999 -0.456207275390625 0.9474169921874999 +0.08837499999999999 -0.456207275390625 0.9474169921874999 +0.0885 -0.45751953125 0.9474169921874999 +0.08862500000000001 -0.458770751953125 0.9474169921874999 +0.08875 -0.458770751953125 0.9474169921874999 +0.08887499999999999 -0.459991455078125 0.9474169921874999 +0.08899999999999999 -0.459991455078125 0.9474169921874999 +0.089125 -0.461151123046875 0.9474169921874999 +0.08924999999999999 -0.462249755859375 0.9474169921874999 +0.089375 -0.462249755859375 0.9474169921874999 +0.08949999999999999 -0.463287353515625 0.9474169921874999 +0.089625 -0.463287353515625 0.9474169921874999 +0.08975 -0.464324951171875 0.9474169921874999 +0.08987499999999999 -0.46527099609375 0.9474169921874999 +0.09 -0.46527099609375 0.9474169921874999 +0.09012499999999999 -0.4661865234375 0.9474169921874999 +0.09025 -0.4661865234375 0.9474169921874999 +0.090375 -0.467041015625 0.9474169921874999 +0.09050000000000001 -0.46783447265625 0.9474169921874999 +0.090625 -0.46783447265625 0.9474169921874999 +0.09074999999999999 -0.46856689453125 0.9474169921874999 +0.09087499999999999 -0.46856689453125 0.9474169921874999 +0.091 -0.469268798828125 0.9474169921874999 +0.09112500000000001 -0.46990966796875 0.9474169921874999 +0.09125 -0.46990966796875 0.9474169921874999 +0.09137499999999999 -0.47052001953125 0.9474169921874999 +0.0915 -0.47052001953125 0.9474169921874999 +0.091625 -0.4710693359375 0.9474169921874999 +0.09175000000000001 -0.4715576171875 0.9474169921874999 +0.091875 -0.4715576171875 0.9474169921874999 +0.09199999999999999 -0.472015380859375 0.9474169921874999 +0.092125 -0.472015380859375 0.9474169921874999 +0.09225 -0.472381591796875 0.9474169921874999 +0.09237499999999999 -0.47271728515625 0.9474169921874999 +0.0925 -0.47271728515625 0.9474169921874999 +0.09262499999999999 -0.4730224609375 0.9474169921874999 +0.09275 -0.4730224609375 0.9474169921874999 +0.092875 -0.473236083984375 0.9474169921874999 +0.09299999999999999 -0.473419189453125 0.9474169921874999 +0.093125 -0.473419189453125 0.9474169921874999 +0.09324999999999999 -0.473541259765625 0.9474169921874999 +0.093375 -0.473541259765625 0.9474169921874999 +0.09350000000000001 -0.4736328125 0.9474169921874999 +0.09362500000000001 -0.473663330078125 0.9474169921874999 +0.09375 -0.473663330078125 0.9474169921874999 +0.09387499999999999 -0.4736328125 0.9474169921874999 +0.09399999999999999 -0.4736328125 0.9474169921874999 +0.094125 -0.473541259765625 0.9474169921874999 +0.09425000000000001 -0.473419189453125 0.9474169921874999 +0.094375 -0.473419189453125 0.9474169921874999 +0.09450000000000001 -0.473236083984375 0.9474169921874999 +0.094625 -0.473236083984375 0.9474169921874999 +0.09475 -0.4730224609375 0.9474169921874999 +0.09487500000000001 -0.47271728515625 0.9474169921874999 +0.095 -0.47271728515625 0.9474169921874999 +0.09512500000000001 -0.472381591796875 0.9474169921874999 +0.09525 -0.472381591796875 0.9474169921874999 +0.095375 -0.472015380859375 0.9474169921874999 +0.09550000000000001 -0.4715576171875 0.9474169921874999 +0.095625 -0.4715576171875 0.9474169921874999 +0.09574999999999999 -0.4710693359375 0.9474169921874999 +0.095875 -0.4710693359375 0.9474169921874999 +0.096 -0.496337890625 0.9993847656250001 +0.09612500000000001 -0.495697021484375 0.9993847656250001 +0.09625 -0.495697021484375 0.9993847656250001 +0.09637499999999999 -0.495025634765625 0.9993847656250001 +0.0965 -0.495025634765625 0.9993847656250001 +0.09662500000000001 -0.494293212890625 0.9993847656250001 +0.09675000000000001 -0.493499755859375 0.9993847656250001 +0.096875 -0.493499755859375 0.9993847656250001 +0.09699999999999999 -0.492645263671875 0.9993847656250001 +0.097125 -0.492645263671875 0.9993847656250001 +0.09725 -0.49176025390625 0.9993847656250001 +0.09737500000000001 -0.49078369140625 0.9993847656250001 +0.0975 -0.49078369140625 0.9993847656250001 +0.09762500000000001 -0.489776611328125 0.9993847656250001 +0.09775 -0.489776611328125 0.9993847656250001 +0.097875 -0.48870849609375 0.9993847656250001 +0.09800000000000001 -0.48760986328125 0.9993847656250001 +0.098125 -0.48760986328125 0.9993847656250001 +0.09825000000000001 -0.4864501953125 0.9993847656250001 +0.098375 -0.4864501953125 0.9993847656250001 +0.09850000000000001 -0.4852294921875 0.9993847656250001 +0.09862500000000001 -0.48394775390625 0.9993847656250001 +0.09875 -0.48394775390625 0.9993847656250001 +0.09887499999999999 -0.48260498046875 0.9993847656250001 +0.099 -0.48260498046875 0.9993847656250001 +0.09912500000000001 -0.481231689453125 0.9993847656250001 +0.09925000000000001 -0.47979736328125 0.9993847656250001 +0.099375 -0.47979736328125 0.9993847656250001 +0.09950000000000001 -0.478302001953125 0.9993847656250001 +0.099625 -0.478302001953125 0.9993847656250001 +0.09975000000000001 -0.476776123046875 0.9993847656250001 +0.09987500000000001 -0.475189208984375 0.9993847656250001 +0.1 -0.475189208984375 0.9993847656250001 +0.100125 -0.473541259765625 0.9993847656250001 +0.10025 -0.473541259765625 0.9993847656250001 +0.100375 -0.47186279296875 0.9993847656250001 +0.1005 -0.4700927734375 0.9993847656250001 +0.100625 -0.4700927734375 0.9993847656250001 +0.10075 -0.468292236328125 0.9993847656250001 +0.100875 -0.468292236328125 0.9993847656250001 +0.101 -0.466461181640625 0.9993847656250001 +0.101125 -0.46453857421875 0.9993847656250001 +0.10125 -0.46453857421875 0.9993847656250001 +0.101375 -0.462615966796875 0.9993847656250001 +0.1015 -0.462615966796875 0.9993847656250001 +0.101625 -0.460601806640625 0.9993847656250001 +0.10175 -0.45855712890625 0.9993847656250001 +0.101875 -0.45855712890625 0.9993847656250001 +0.102 -0.456451416015625 0.9993847656250001 +0.102125 -0.456451416015625 0.9993847656250001 +0.10225 -0.45428466796875 0.9993847656250001 +0.102375 -0.45208740234375 0.9993847656250001 +0.1025 -0.45208740234375 0.9993847656250001 +0.102625 -0.4498291015625 0.9993847656250001 +0.10275 -0.4498291015625 0.9993847656250001 +0.102875 -0.447540283203125 0.9993847656250001 +0.103 -0.4451904296875 0.9993847656250001 +0.103125 -0.4451904296875 0.9993847656250001 +0.10325 -0.442779541015625 0.9993847656250001 +0.103375 -0.442779541015625 0.9993847656250001 +0.1035 -0.440338134765625 0.9993847656250001 +0.103625 -0.437835693359375 0.9993847656250001 +0.10375 -0.437835693359375 0.9993847656250001 +0.103875 -0.435302734375 0.9993847656250001 +0.104 -0.435302734375 0.9993847656250001 +0.104125 -0.432708740234375 0.9993847656250001 +0.10425 -0.4300537109375 0.9993847656250001 +0.104375 -0.4300537109375 0.9993847656250001 +0.1045 -0.4273681640625 0.9993847656250001 +0.104625 -0.4273681640625 0.9993847656250001 +0.10475 -0.424652099609375 0.9993847656250001 +0.104875 -0.421875 0.9993847656250001 +0.105 -0.421875 0.9993847656250001 +0.105125 -0.419036865234375 0.9993847656250001 +0.10525 -0.419036865234375 0.9993847656250001 +0.105375 -0.416168212890625 0.9993847656250001 +0.1055 -0.413238525390625 0.9993847656250001 +0.105625 -0.413238525390625 0.9993847656250001 +0.10575 -0.4102783203125 0.9993847656250001 +0.105875 -0.4102783203125 0.9993847656250001 +0.106 -0.407257080078125 0.9993847656250001 +0.106125 -0.40423583984375 0.9993847656250001 +0.10625 -0.40423583984375 0.9993847656250001 +0.106375 -0.401123046875 0.9993847656250001 +0.1065 -0.401123046875 0.9993847656250001 +0.106625 -0.397979736328125 0.9993847656250001 +0.10675 -0.394805908203125 0.9993847656250001 +0.106875 -0.394805908203125 0.9993847656250001 +0.107 -0.391571044921875 0.9993847656250001 +0.107125 -0.391571044921875 0.9993847656250001 +0.10725 -0.388275146484375 0.9993847656250001 +0.107375 -0.384979248046875 0.9993847656250001 +0.1075 -0.384979248046875 0.9993847656250001 +0.107625 -0.381622314453125 0.9993847656250001 +0.10775 -0.381622314453125 0.9993847656250001 +0.107875 -0.37823486328125 0.9993847656250001 +0.108 -0.374786376953125 0.9993847656250001 +0.108125 -0.374786376953125 0.9993847656250001 +0.10825 -0.371307373046875 0.9993847656250001 +0.108375 -0.371307373046875 0.9993847656250001 +0.1085 -0.367767333984375 0.9993847656250001 +0.108625 -0.364227294921875 0.9993847656250001 +0.10875 -0.364227294921875 0.9993847656250001 +0.108875 -0.360595703125 0.9993847656250001 +0.109 -0.360595703125 0.9993847656250001 +0.109125 -0.356964111328125 0.9993847656250001 +0.10925 -0.353302001953125 0.9993847656250001 +0.109375 -0.353302001953125 0.9993847656250001 +0.1095 -0.349578857421875 0.9993847656250001 +0.109625 -0.349578857421875 0.9993847656250001 +0.10975 -0.3458251953125 0.9993847656250001 +0.109875 -0.342010498046875 0.9993847656250001 +0.11 -0.342010498046875 0.9993847656250001 +0.110125 -0.33819580078125 0.9993847656250001 +0.11025 -0.33819580078125 0.9993847656250001 +0.110375 -0.334320068359375 0.9993847656250001 +0.1105 -0.330413818359375 0.9993847656250001 +0.110625 -0.330413818359375 0.9993847656250001 +0.11075 -0.32647705078125 0.9993847656250001 +0.110875 -0.32647705078125 0.9993847656250001 +0.111 -0.322479248046875 0.9993847656250001 +0.111125 -0.3184814453125 0.9993847656250001 +0.11125 -0.3184814453125 0.9993847656250001 +0.111375 -0.314422607421875 0.9993847656250001 +0.1115 -0.314422607421875 0.9993847656250001 +0.111625 -0.310333251953125 0.9993847656250001 +0.11175 -0.306243896484375 0.9993847656250001 +0.111875 -0.306243896484375 0.9993847656250001 +0.112 -0.30206298828125 0.9993847656250001 +0.112125 -0.30206298828125 0.9993847656250001 +0.11225 -0.297882080078125 0.9993847656250001 +0.112375 -0.293670654296875 0.9993847656250001 +0.1125 -0.293670654296875 0.9993847656250001 +0.112625 -0.2894287109375 0.9993847656250001 +0.11275 -0.2894287109375 0.9993847656250001 +0.112875 -0.28515625 0.9993847656250001 +0.113 -0.28082275390625 0.9993847656250001 +0.113125 -0.28082275390625 0.9993847656250001 +0.11325 -0.2764892578125 0.9993847656250001 +0.113375 -0.2764892578125 0.9993847656250001 +0.1135 -0.272125244140625 0.9993847656250001 +0.113625 -0.2677001953125 0.9993847656250001 +0.11375 -0.2677001953125 0.9993847656250001 +0.113875 -0.263275146484375 0.9993847656250001 +0.114 -0.263275146484375 0.9993847656250001 +0.114125 -0.258819580078125 0.9993847656250001 +0.11425 -0.25433349609375 0.9993847656250001 +0.114375 -0.25433349609375 0.9993847656250001 +0.1145 -0.24981689453125 0.9993847656250001 +0.114625 -0.24981689453125 0.9993847656250001 +0.11475 -0.245269775390625 0.9993847656250001 +0.114875 -0.240692138671875 0.9993847656250001 +0.115 -0.240692138671875 0.9993847656250001 +0.115125 -0.236114501953125 0.9993847656250001 +0.11525 -0.236114501953125 0.9993847656250001 +0.115375 -0.231475830078125 0.9993847656250001 +0.1155 -0.226806640625 0.9993847656250001 +0.115625 -0.226806640625 0.9993847656250001 +0.11575 -0.222137451171875 0.9993847656250001 +0.115875 -0.222137451171875 0.9993847656250001 +0.116 -0.217437744140625 0.9993847656250001 +0.116125 -0.212738037109375 0.9993847656250001 +0.11625 -0.212738037109375 0.9993847656250001 +0.116375 -0.207977294921875 0.9993847656250001 +0.1165 -0.207977294921875 0.9993847656250001 +0.116625 -0.203216552734375 0.9993847656250001 +0.11675 -0.19842529296875 0.9993847656250001 +0.116875 -0.19842529296875 0.9993847656250001 +0.117 -0.193603515625 0.9993847656250001 +0.117125 -0.193603515625 0.9993847656250001 +0.11725 -0.18878173828125 0.9993847656250001 +0.117375 -0.183929443359375 0.9993847656250001 +0.1175 -0.183929443359375 0.9993847656250001 +0.117625 -0.179046630859375 0.9993847656250001 +0.11775 -0.179046630859375 0.9993847656250001 +0.117875 -0.17413330078125 0.9993847656250001 +0.118 -0.169219970703125 0.9993847656250001 +0.118125 -0.169219970703125 0.9993847656250001 +0.11825 -0.164306640625 0.9993847656250001 +0.118375 -0.164306640625 0.9993847656250001 +0.1185 -0.15936279296875 0.9993847656250001 +0.118625 -0.154388427734375 0.9993847656250001 +0.11875 -0.154388427734375 0.9993847656250001 +0.118875 -0.149383544921875 0.9993847656250001 +0.119 -0.149383544921875 0.9993847656250001 +0.119125 -0.144378662109375 0.9993847656250001 +0.11925 -0.139373779296875 0.9993847656250001 +0.119375 -0.139373779296875 0.9993847656250001 +0.1195 -0.13433837890625 0.9993847656250001 +0.119625 -0.13433837890625 0.9993847656250001 +0.11975 -0.129302978515625 0.9993847656250001 +0.119875 -0.124237060546875 0.9993847656250001 +0.12 -0.124237060546875 0.9993847656250001 +0.120125 -0.119171142578125 0.9993847656250001 +0.12025 -0.119171142578125 0.9993847656250001 +0.120375 -0.11407470703125 0.9993847656250001 +0.1205 -0.108978271484375 0.9993847656250001 +0.120625 -0.108978271484375 0.9993847656250001 +0.12075 -0.103851318359375 0.9993847656250001 +0.120875 -0.103851318359375 0.9993847656250001 +0.121 -0.098724365234375 0.9993847656250001 +0.121125 -0.093597412109375 0.9993847656250001 +0.12125 -0.093597412109375 0.9993847656250001 +0.121375 -0.088470458984375 0.9993847656250001 +0.1215 -0.088470458984375 0.9993847656250001 +0.121625 -0.08331298828125 0.9993847656250001 +0.12175 -0.078125 0.9993847656250001 +0.121875 -0.078125 0.9993847656250001 +0.122 -0.072967529296875 0.9993847656250001 +0.122125 -0.072967529296875 0.9993847656250001 +0.12225 -0.067779541015625 0.9993847656250001 +0.122375 -0.062591552734375 0.9993847656250001 +0.1225 -0.062591552734375 0.9993847656250001 +0.122625 -0.057403564453125 0.9993847656250001 +0.12275 -0.057403564453125 0.9993847656250001 +0.122875 -0.052215576171875 0.9993847656250001 +0.123 -0.0469970703125 0.9993847656250001 +0.123125 -0.0469970703125 0.9993847656250001 +0.12325 -0.041778564453125 0.9993847656250001 +0.123375 -0.041778564453125 0.9993847656250001 +0.1235 -0.03656005859375 0.9993847656250001 +0.123625 -0.031341552734375 0.9993847656250001 +0.12375 -0.031341552734375 0.9993847656250001 +0.123875 -0.026123046875 0.9993847656250001 +0.124 -0.026123046875 0.9993847656250001 +0.124125 -0.020904541015625 0.9993847656250001 +0.12425 -0.01568603515625 0.9993847656250001 +0.124375 -0.01568603515625 0.9993847656250001 +0.1245 -0.01043701171875 0.9993847656250001 +0.124625 -0.01043701171875 0.9993847656250001 +0.12475 -0.005218505859375 0.9993847656250001 0.124875 0.0 0.9993847656250001 0.125 0.0 0.9993847656250001 0.125125 0.005218505859375 0.9993847656250001 @@ -1499,504 +1499,504 @@ 0.18725 0.003814697265625 0.7327783203125 0.187375 0.0 0.7327783203125 0.1875 0.0 0.7327783203125 -0.187625 -0.00384521484375 0.7327783203125 -0.18775 -0.00384521484375 0.7327783203125 -0.187875 -0.0076904296875 0.7327783203125 -0.188 -0.01153564453125 0.7327783203125 -0.188125 -0.01153564453125 0.7327783203125 -0.18825 -0.015350341796875 0.7327783203125 -0.188375 -0.015350341796875 0.7327783203125 -0.1885 -0.0191650390625 0.7327783203125 -0.188625 -0.02301025390625 0.7327783203125 -0.18875 -0.02301025390625 0.7327783203125 -0.188875 -0.026824951171875 0.7327783203125 -0.189 -0.026824951171875 0.7327783203125 -0.189125 -0.030670166015625 0.7327783203125 -0.18925 -0.03448486328125 0.7327783203125 -0.189375 -0.03448486328125 0.7327783203125 -0.1895 -0.038299560546875 0.7327783203125 -0.189625 -0.038299560546875 0.7327783203125 -0.18975 -0.0421142578125 0.7327783203125 -0.189875 -0.045928955078125 0.7327783203125 -0.19 -0.045928955078125 0.7327783203125 -0.190125 -0.049713134765625 0.7327783203125 -0.19025 -0.049713134765625 0.7327783203125 -0.190375 -0.05352783203125 0.7327783203125 -0.1905 -0.05731201171875 0.7327783203125 -0.190625 -0.05731201171875 0.7327783203125 -0.19075 -0.06109619140625 0.7327783203125 -0.190875 -0.06109619140625 0.7327783203125 -0.191 -0.06488037109375 0.7327783203125 -0.191125 -0.06866455078125 0.7327783203125 -0.19125 -0.06866455078125 0.7327783203125 -0.191375 -0.072418212890625 0.7327783203125 -0.1915 -0.072418212890625 0.7327783203125 -0.191625 -0.076171875 0.7327783203125 -0.19175 -0.079925537109375 0.7327783203125 -0.191875 -0.079925537109375 0.7327783203125 -0.192 -0.052154541015625 0.4567333984374999 -0.192125 -0.052154541015625 0.4567333984374999 -0.19225 -0.054473876953125 0.4567333984374999 -0.192375 -0.056793212890625 0.4567333984374999 -0.1925 -0.056793212890625 0.4567333984374999 -0.192625 -0.059112548828125 0.4567333984374999 -0.19275 -0.059112548828125 0.4567333984374999 -0.192875 -0.0614013671875 0.4567333984374999 -0.193 -0.063720703125 0.4567333984374999 -0.193125 -0.063720703125 0.4567333984374999 -0.19325 -0.066009521484375 0.4567333984374999 -0.193375 -0.066009521484375 0.4567333984374999 -0.1935 -0.06829833984375 0.4567333984374999 -0.193625 -0.070587158203125 0.4567333984374999 -0.19375 -0.070587158203125 0.4567333984374999 -0.193875 -0.072845458984375 0.4567333984374999 -0.194 -0.072845458984375 0.4567333984374999 -0.194125 -0.075103759765625 0.4567333984374999 -0.19425 -0.077362060546875 0.4567333984374999 -0.194375 -0.077362060546875 0.4567333984374999 -0.1945 -0.07958984375 0.4567333984374999 -0.194625 -0.07958984375 0.4567333984374999 -0.19475 -0.08184814453125 0.4567333984374999 -0.194875 -0.084075927734375 0.4567333984374999 -0.195 -0.084075927734375 0.4567333984374999 -0.195125 -0.086273193359375 0.4567333984374999 -0.19525 -0.086273193359375 0.4567333984374999 -0.195375 -0.0885009765625 0.4567333984374999 -0.1955 -0.0906982421875 0.4567333984374999 -0.195625 -0.0906982421875 0.4567333984374999 -0.19575 -0.0928955078125 0.4567333984374999 -0.195875 -0.0928955078125 0.4567333984374999 -0.196 -0.095062255859375 0.4567333984374999 -0.196125 -0.09722900390625 0.4567333984374999 -0.19625 -0.09722900390625 0.4567333984374999 -0.196375 -0.099395751953125 0.4567333984374999 -0.1965 -0.099395751953125 0.4567333984374999 -0.196625 -0.101531982421875 0.4567333984374999 -0.19675 -0.103668212890625 0.4567333984374999 -0.196875 -0.103668212890625 0.4567333984374999 -0.197 -0.105804443359375 0.4567333984374999 -0.197125 -0.105804443359375 0.4567333984374999 -0.19725 -0.10791015625 0.4567333984374999 -0.197375 -0.110015869140625 0.4567333984374999 -0.1975 -0.110015869140625 0.4567333984374999 -0.197625 -0.112091064453125 0.4567333984374999 -0.19775 -0.112091064453125 0.4567333984374999 -0.197875 -0.11419677734375 0.4567333984374999 -0.198 -0.116241455078125 0.4567333984374999 -0.198125 -0.116241455078125 0.4567333984374999 -0.19825 -0.1182861328125 0.4567333984374999 -0.198375 -0.1182861328125 0.4567333984374999 -0.1985 -0.120330810546875 0.4567333984374999 -0.198625 -0.12237548828125 0.4567333984374999 -0.19875 -0.12237548828125 0.4567333984374999 -0.198875 -0.1243896484375 0.4567333984374999 -0.199 -0.1243896484375 0.4567333984374999 -0.199125 -0.126373291015625 0.4567333984374999 -0.19925 -0.12835693359375 0.4567333984374999 -0.199375 -0.12835693359375 0.4567333984374999 -0.1995 -0.130340576171875 0.4567333984374999 -0.199625 -0.130340576171875 0.4567333984374999 -0.19975 -0.132293701171875 0.4567333984374999 -0.199875 -0.13421630859375 0.4567333984374999 -0.2 -0.13421630859375 0.4567333984374999 -0.200125 -0.13616943359375 0.4567333984374999 -0.20025 -0.13616943359375 0.4567333984374999 -0.200375 -0.1380615234375 0.4567333984374999 -0.2005 -0.13995361328125 0.4567333984374999 -0.200625 -0.13995361328125 0.4567333984374999 -0.20075 -0.141845703125 0.4567333984374999 -0.200875 -0.141845703125 0.4567333984374999 -0.201 -0.143707275390625 0.4567333984374999 -0.201125 -0.14556884765625 0.4567333984374999 -0.20125 -0.14556884765625 0.4567333984374999 -0.201375 -0.14739990234375 0.4567333984374999 -0.2015 -0.14739990234375 0.4567333984374999 -0.201625 -0.149200439453125 0.4567333984374999 -0.20175 -0.151031494140625 0.4567333984374999 -0.201875 -0.151031494140625 0.4567333984374999 -0.202 -0.152801513671875 0.4567333984374999 -0.202125 -0.152801513671875 0.4567333984374999 -0.20225 -0.154571533203125 0.4567333984374999 -0.202375 -0.15631103515625 0.4567333984374999 -0.2025 -0.15631103515625 0.4567333984374999 -0.202625 -0.158050537109375 0.4567333984374999 -0.20275 -0.158050537109375 0.4567333984374999 -0.202875 -0.159759521484375 0.4567333984374999 -0.203 -0.161468505859375 0.4567333984374999 -0.203125 -0.161468505859375 0.4567333984374999 -0.20325 -0.16314697265625 0.4567333984374999 -0.203375 -0.16314697265625 0.4567333984374999 -0.2035 -0.164825439453125 0.4567333984374999 -0.203625 -0.166473388671875 0.4567333984374999 -0.20375 -0.166473388671875 0.4567333984374999 -0.203875 -0.1680908203125 0.4567333984374999 -0.204 -0.1680908203125 0.4567333984374999 -0.204125 -0.169708251953125 0.4567333984374999 -0.20425 -0.171295166015625 0.4567333984374999 -0.204375 -0.171295166015625 0.4567333984374999 -0.2045 -0.1728515625 0.4567333984374999 -0.204625 -0.1728515625 0.4567333984374999 -0.20475 -0.174407958984375 0.4567333984374999 -0.204875 -0.17596435546875 0.4567333984374999 -0.205 -0.17596435546875 0.4567333984374999 -0.205125 -0.177459716796875 0.4567333984374999 -0.20525 -0.177459716796875 0.4567333984374999 -0.205375 -0.178955078125 0.4567333984374999 -0.2055 -0.180450439453125 0.4567333984374999 -0.205625 -0.180450439453125 0.4567333984374999 -0.20575 -0.181884765625 0.4567333984374999 -0.205875 -0.181884765625 0.4567333984374999 -0.206 -0.183319091796875 0.4567333984374999 -0.206125 -0.18475341796875 0.4567333984374999 -0.20625 -0.18475341796875 0.4567333984374999 -0.206375 -0.186126708984375 0.4567333984374999 -0.2065 -0.186126708984375 0.4567333984374999 -0.206625 -0.1875 0.4567333984374999 -0.20675 -0.188873291015625 0.4567333984374999 -0.206875 -0.188873291015625 0.4567333984374999 -0.207 -0.190216064453125 0.4567333984374999 -0.207125 -0.190216064453125 0.4567333984374999 -0.20725 -0.191497802734375 0.4567333984374999 -0.207375 -0.19281005859375 0.4567333984374999 -0.2075 -0.19281005859375 0.4567333984374999 -0.207625 -0.194091796875 0.4567333984374999 -0.20775 -0.194091796875 0.4567333984374999 -0.207875 -0.1953125 0.4567333984374999 -0.208 -0.196563720703125 0.4567333984374999 -0.208125 -0.196563720703125 0.4567333984374999 -0.20825 -0.19775390625 0.4567333984374999 -0.208375 -0.19775390625 0.4567333984374999 -0.2085 -0.198944091796875 0.4567333984374999 -0.208625 -0.200103759765625 0.4567333984374999 -0.20875 -0.200103759765625 0.4567333984374999 -0.208875 -0.20123291015625 0.4567333984374999 -0.209 -0.20123291015625 0.4567333984374999 -0.209125 -0.202362060546875 0.4567333984374999 -0.20925 -0.203460693359375 0.4567333984374999 -0.209375 -0.203460693359375 0.4567333984374999 -0.2095 -0.20452880859375 0.4567333984374999 -0.209625 -0.20452880859375 0.4567333984374999 -0.20975 -0.205596923828125 0.4567333984374999 -0.209875 -0.206634521484375 0.4567333984374999 -0.21 -0.206634521484375 0.4567333984374999 -0.210125 -0.207611083984375 0.4567333984374999 -0.21025 -0.207611083984375 0.4567333984374999 -0.210375 -0.2086181640625 0.4567333984374999 -0.2105 -0.209564208984375 0.4567333984374999 -0.210625 -0.209564208984375 0.4567333984374999 -0.21075 -0.21051025390625 0.4567333984374999 -0.210875 -0.21051025390625 0.4567333984374999 -0.211 -0.21142578125 0.4567333984374999 -0.211125 -0.212310791015625 0.4567333984374999 -0.21125 -0.212310791015625 0.4567333984374999 -0.211375 -0.21319580078125 0.4567333984374999 -0.2115 -0.21319580078125 0.4567333984374999 -0.211625 -0.214019775390625 0.4567333984374999 -0.21175 -0.21484375 0.4567333984374999 -0.211875 -0.21484375 0.4567333984374999 -0.212 -0.21563720703125 0.4567333984374999 -0.212125 -0.21563720703125 0.4567333984374999 -0.21225 -0.2164306640625 0.4567333984374999 -0.212375 -0.217193603515625 0.4567333984374999 -0.2125 -0.217193603515625 0.4567333984374999 -0.212625 -0.2178955078125 0.4567333984374999 -0.21275 -0.2178955078125 0.4567333984374999 -0.212875 -0.218597412109375 0.4567333984374999 -0.213 -0.219268798828125 0.4567333984374999 -0.213125 -0.219268798828125 0.4567333984374999 -0.21325 -0.219940185546875 0.4567333984374999 -0.213375 -0.219940185546875 0.4567333984374999 -0.2135 -0.2205810546875 0.4567333984374999 -0.213625 -0.22119140625 0.4567333984374999 -0.21375 -0.22119140625 0.4567333984374999 -0.213875 -0.221771240234375 0.4567333984374999 -0.214 -0.221771240234375 0.4567333984374999 -0.214125 -0.222320556640625 0.4567333984374999 -0.21425 -0.22283935546875 0.4567333984374999 -0.214375 -0.22283935546875 0.4567333984374999 -0.2145 -0.223358154296875 0.4567333984374999 -0.214625 -0.223358154296875 0.4567333984374999 -0.21475 -0.223846435546875 0.4567333984374999 -0.214875 -0.22430419921875 0.4567333984374999 -0.215 -0.22430419921875 0.4567333984374999 -0.215125 -0.2247314453125 0.4567333984374999 -0.21525 -0.2247314453125 0.4567333984374999 -0.215375 -0.22515869140625 0.4567333984374999 -0.2155 -0.225555419921875 0.4567333984374999 -0.215625 -0.225555419921875 0.4567333984374999 -0.21575 -0.22589111328125 0.4567333984374999 -0.215875 -0.22589111328125 0.4567333984374999 -0.216 -0.226226806640625 0.4567333984374999 -0.216125 -0.2265625 0.4567333984374999 -0.21625 -0.2265625 0.4567333984374999 -0.216375 -0.226837158203125 0.4567333984374999 -0.2165 -0.226837158203125 0.4567333984374999 -0.216625 -0.22711181640625 0.4567333984374999 -0.21675 -0.227325439453125 0.4567333984374999 -0.216875 -0.227325439453125 0.4567333984374999 -0.217 -0.227569580078125 0.4567333984374999 -0.217125 -0.227569580078125 0.4567333984374999 -0.21725 -0.227752685546875 0.4567333984374999 -0.217375 -0.2279052734375 0.4567333984374999 -0.2175 -0.2279052734375 0.4567333984374999 -0.217625 -0.22802734375 0.4567333984374999 -0.21775 -0.22802734375 0.4567333984374999 -0.217875 -0.2281494140625 0.4567333984374999 -0.218 -0.228240966796875 0.4567333984374999 -0.218125 -0.228240966796875 0.4567333984374999 -0.21825 -0.228302001953125 0.4567333984374999 -0.218375 -0.228302001953125 0.4567333984374999 -0.2185 -0.22833251953125 0.4567333984374999 -0.218625 -0.228363037109375 0.4567333984374999 -0.21875 -0.228363037109375 0.4567333984374999 -0.218875 -0.22833251953125 0.4567333984374999 -0.219 -0.22833251953125 0.4567333984374999 -0.219125 -0.228302001953125 0.4567333984374999 -0.21925 -0.228240966796875 0.4567333984374999 -0.219375 -0.228240966796875 0.4567333984374999 -0.2195 -0.2281494140625 0.4567333984374999 -0.219625 -0.2281494140625 0.4567333984374999 -0.21975 -0.22802734375 0.4567333984374999 -0.219875 -0.2279052734375 0.4567333984374999 -0.22 -0.2279052734375 0.4567333984374999 -0.220125 -0.227752685546875 0.4567333984374999 -0.22025 -0.227752685546875 0.4567333984374999 -0.220375 -0.227569580078125 0.4567333984374999 -0.2205 -0.227325439453125 0.4567333984374999 -0.220625 -0.227325439453125 0.4567333984374999 -0.22075 -0.22711181640625 0.4567333984374999 -0.220875 -0.22711181640625 0.4567333984374999 -0.221 -0.226837158203125 0.4567333984374999 -0.221125 -0.2265625 0.4567333984374999 -0.22125 -0.2265625 0.4567333984374999 -0.221375 -0.226226806640625 0.4567333984374999 -0.2215 -0.226226806640625 0.4567333984374999 -0.221625 -0.22589111328125 0.4567333984374999 -0.22175 -0.225555419921875 0.4567333984374999 -0.221875 -0.225555419921875 0.4567333984374999 -0.222 -0.22515869140625 0.4567333984374999 -0.222125 -0.22515869140625 0.4567333984374999 -0.22225 -0.2247314453125 0.4567333984374999 -0.222375 -0.22430419921875 0.4567333984374999 -0.2225 -0.22430419921875 0.4567333984374999 -0.222625 -0.223846435546875 0.4567333984374999 -0.22275 -0.223846435546875 0.4567333984374999 -0.222875 -0.223358154296875 0.4567333984374999 -0.223 -0.22283935546875 0.4567333984374999 -0.223125 -0.22283935546875 0.4567333984374999 -0.22325 -0.222320556640625 0.4567333984374999 -0.223375 -0.222320556640625 0.4567333984374999 -0.2235 -0.221771240234375 0.4567333984374999 -0.223625 -0.22119140625 0.4567333984374999 -0.22375 -0.22119140625 0.4567333984374999 -0.223875 -0.2205810546875 0.4567333984374999 -0.224 -0.0675048828125 0.1397607421875001 -0.224125 -0.06732177734375 0.1397607421875001 -0.22425 -0.067108154296875 0.1397607421875001 -0.224375 -0.067108154296875 0.1397607421875001 -0.2245 -0.06689453125 0.1397607421875001 -0.224625 -0.06689453125 0.1397607421875001 -0.22475 -0.066680908203125 0.1397607421875001 -0.224875 -0.06646728515625 0.1397607421875001 -0.225 -0.06646728515625 0.1397607421875001 -0.225125 -0.06622314453125 0.1397607421875001 -0.22525 -0.06622314453125 0.1397607421875001 -0.225375 -0.066009521484375 0.1397607421875001 -0.2255 -0.065765380859375 0.1397607421875001 -0.225625 -0.065765380859375 0.1397607421875001 -0.22575 -0.06549072265625 0.1397607421875001 -0.225875 -0.06549072265625 0.1397607421875001 -0.226 -0.06524658203125 0.1397607421875001 -0.226125 -0.064971923828125 0.1397607421875001 -0.22625 -0.064971923828125 0.1397607421875001 -0.226375 -0.064697265625 0.1397607421875001 -0.2265 -0.064697265625 0.1397607421875001 -0.226625 -0.064422607421875 0.1397607421875001 -0.22675 -0.06414794921875 0.1397607421875001 -0.226875 -0.06414794921875 0.1397607421875001 -0.227 -0.0638427734375 0.1397607421875001 -0.227125 -0.0638427734375 0.1397607421875001 -0.22725 -0.06353759765625 0.1397607421875001 -0.227375 -0.063232421875 0.1397607421875001 -0.2275 -0.063232421875 0.1397607421875001 -0.227625 -0.06292724609375 0.1397607421875001 -0.22775 -0.06292724609375 0.1397607421875001 -0.227875 -0.062591552734375 0.1397607421875001 -0.228 -0.062255859375 0.1397607421875001 -0.228125 -0.062255859375 0.1397607421875001 -0.22825 -0.061920166015625 0.1397607421875001 -0.228375 -0.061920166015625 0.1397607421875001 -0.2285 -0.06158447265625 0.1397607421875001 -0.228625 -0.061248779296875 0.1397607421875001 -0.22875 -0.061248779296875 0.1397607421875001 -0.228875 -0.060882568359375 0.1397607421875001 -0.229 -0.060882568359375 0.1397607421875001 -0.229125 -0.060516357421875 0.1397607421875001 -0.22925 -0.060150146484375 0.1397607421875001 -0.229375 -0.060150146484375 0.1397607421875001 -0.2295 -0.059783935546875 0.1397607421875001 -0.229625 -0.059783935546875 0.1397607421875001 -0.22975 -0.05938720703125 0.1397607421875001 -0.229875 -0.05902099609375 0.1397607421875001 -0.23 -0.05902099609375 0.1397607421875001 -0.230125 -0.058624267578125 0.1397607421875001 -0.23025 -0.058624267578125 0.1397607421875001 -0.230375 -0.058197021484375 0.1397607421875001 -0.2305 -0.05780029296875 0.1397607421875001 -0.230625 -0.05780029296875 0.1397607421875001 -0.23075 -0.057373046875 0.1397607421875001 -0.230875 -0.057373046875 0.1397607421875001 -0.231 -0.056976318359375 0.1397607421875001 -0.231125 -0.056549072265625 0.1397607421875001 -0.23125 -0.056549072265625 0.1397607421875001 -0.231375 -0.05609130859375 0.1397607421875001 -0.2315 -0.05609130859375 0.1397607421875001 -0.231625 -0.0556640625 0.1397607421875001 -0.23175 -0.05523681640625 0.1397607421875001 -0.231875 -0.05523681640625 0.1397607421875001 -0.232 -0.054779052734375 0.1397607421875001 -0.232125 -0.054779052734375 0.1397607421875001 -0.23225 -0.0543212890625 0.1397607421875001 -0.232375 -0.053863525390625 0.1397607421875001 -0.2325 -0.053863525390625 0.1397607421875001 -0.232625 -0.053375244140625 0.1397607421875001 -0.23275 -0.053375244140625 0.1397607421875001 -0.232875 -0.05291748046875 0.1397607421875001 -0.233 -0.05242919921875 0.1397607421875001 -0.233125 -0.05242919921875 0.1397607421875001 -0.23325 -0.05194091796875 0.1397607421875001 -0.233375 -0.05194091796875 0.1397607421875001 -0.2335 -0.05145263671875 0.1397607421875001 -0.233625 -0.050933837890625 0.1397607421875001 -0.23375 -0.050933837890625 0.1397607421875001 -0.233875 -0.050445556640625 0.1397607421875001 -0.234 -0.050445556640625 0.1397607421875001 -0.234125 -0.0499267578125 0.1397607421875001 -0.23425 -0.049407958984375 0.1397607421875001 -0.234375 -0.049407958984375 0.1397607421875001 -0.2345 -0.04888916015625 0.1397607421875001 -0.234625 -0.04888916015625 0.1397607421875001 -0.23475 -0.048370361328125 0.1397607421875001 -0.234875 -0.0478515625 0.1397607421875001 -0.235 -0.0478515625 0.1397607421875001 -0.235125 -0.04730224609375 0.1397607421875001 -0.23525 -0.04730224609375 0.1397607421875001 -0.235375 -0.0467529296875 0.1397607421875001 -0.2355 -0.046234130859375 0.1397607421875001 -0.235625 -0.046234130859375 0.1397607421875001 -0.23575 -0.045654296875 0.1397607421875001 -0.235875 -0.045654296875 0.1397607421875001 -0.236 -0.04510498046875 0.1397607421875001 -0.236125 -0.0445556640625 0.1397607421875001 -0.23625 -0.0445556640625 0.1397607421875001 -0.236375 -0.043975830078125 0.1397607421875001 -0.2365 -0.043975830078125 0.1397607421875001 -0.236625 -0.043426513671875 0.1397607421875001 -0.23675 -0.0428466796875 0.1397607421875001 -0.236875 -0.0428466796875 0.1397607421875001 -0.237 -0.042266845703125 0.1397607421875001 -0.237125 -0.042266845703125 0.1397607421875001 -0.23725 -0.041656494140625 0.1397607421875001 -0.237375 -0.04107666015625 0.1397607421875001 -0.2375 -0.04107666015625 0.1397607421875001 -0.237625 -0.040496826171875 0.1397607421875001 -0.23775 -0.040496826171875 0.1397607421875001 -0.237875 -0.039886474609375 0.1397607421875001 -0.238 -0.039276123046875 0.1397607421875001 -0.238125 -0.039276123046875 0.1397607421875001 -0.23825 -0.038665771484375 0.1397607421875001 -0.238375 -0.038665771484375 0.1397607421875001 -0.2385 -0.038055419921875 0.1397607421875001 -0.238625 -0.037445068359375 0.1397607421875001 -0.23875 -0.037445068359375 0.1397607421875001 -0.238875 -0.036834716796875 0.1397607421875001 -0.239 -0.036834716796875 0.1397607421875001 -0.239125 -0.03619384765625 0.1397607421875001 -0.23925 -0.03558349609375 0.1397607421875001 -0.239375 -0.03558349609375 0.1397607421875001 -0.2395 -0.034942626953125 0.1397607421875001 -0.239625 -0.034942626953125 0.1397607421875001 -0.23975 -0.0343017578125 0.1397607421875001 -0.239875 -0.033660888671875 0.1397607421875001 -0.24 -0.033660888671875 0.1397607421875001 -0.240125 -0.03302001953125 0.1397607421875001 -0.24025 -0.03302001953125 0.1397607421875001 -0.240375 -0.032379150390625 0.1397607421875001 -0.2405 -0.03173828125 0.1397607421875001 -0.240625 -0.03173828125 0.1397607421875001 -0.24075 -0.03106689453125 0.1397607421875001 -0.240875 -0.03106689453125 0.1397607421875001 -0.241 -0.030426025390625 0.1397607421875001 -0.241125 -0.029754638671875 0.1397607421875001 -0.24125 -0.029754638671875 0.1397607421875001 -0.241375 -0.02911376953125 0.1397607421875001 -0.2415 -0.02911376953125 0.1397607421875001 -0.241625 -0.0284423828125 0.1397607421875001 -0.24175 -0.02777099609375 0.1397607421875001 -0.241875 -0.02777099609375 0.1397607421875001 -0.242 -0.027099609375 0.1397607421875001 -0.242125 -0.027099609375 0.1397607421875001 -0.24225 -0.026397705078125 0.1397607421875001 -0.242375 -0.025726318359375 0.1397607421875001 -0.2425 -0.025726318359375 0.1397607421875001 -0.242625 -0.025054931640625 0.1397607421875001 -0.24275 -0.025054931640625 0.1397607421875001 -0.242875 -0.02435302734375 0.1397607421875001 -0.243 -0.023681640625 0.1397607421875001 -0.243125 -0.023681640625 0.1397607421875001 -0.24325 -0.022979736328125 0.1397607421875001 -0.243375 -0.022979736328125 0.1397607421875001 -0.2435 -0.022308349609375 0.1397607421875001 -0.243625 -0.0216064453125 0.1397607421875001 -0.24375 -0.0216064453125 0.1397607421875001 -0.243875 -0.020904541015625 0.1397607421875001 -0.244 -0.020904541015625 0.1397607421875001 -0.244125 -0.02020263671875 0.1397607421875001 -0.24425 -0.019500732421875 0.1397607421875001 -0.244375 -0.019500732421875 0.1397607421875001 -0.2445 -0.018798828125 0.1397607421875001 -0.244625 -0.018798828125 0.1397607421875001 -0.24475 -0.018096923828125 0.1397607421875001 -0.244875 -0.01739501953125 0.1397607421875001 -0.245 -0.01739501953125 0.1397607421875001 -0.245125 -0.016693115234375 0.1397607421875001 -0.24525 -0.016693115234375 0.1397607421875001 -0.245375 -0.015960693359375 0.1397607421875001 -0.2455 -0.0152587890625 0.1397607421875001 -0.245625 -0.0152587890625 0.1397607421875001 -0.24575 -0.0145263671875 0.1397607421875001 -0.245875 -0.0145263671875 0.1397607421875001 -0.246 -0.013824462890625 0.1397607421875001 -0.246125 -0.013092041015625 0.1397607421875001 -0.24625 -0.013092041015625 0.1397607421875001 -0.246375 -0.01239013671875 0.1397607421875001 -0.2465 -0.01239013671875 0.1397607421875001 -0.246625 -0.01165771484375 0.1397607421875001 -0.24675 -0.010955810546875 0.1397607421875001 -0.246875 -0.010955810546875 0.1397607421875001 -0.247 -0.010223388671875 0.1397607421875001 -0.247125 -0.010223388671875 0.1397607421875001 -0.24725 -0.009490966796875 0.1397607421875001 -0.247375 -0.008758544921875 0.1397607421875001 -0.2475 -0.008758544921875 0.1397607421875001 -0.247625 -0.008056640625 0.1397607421875001 -0.24775 -0.008056640625 0.1397607421875001 -0.247875 -0.00732421875 0.1397607421875001 -0.248 -0.006591796875 0.1397607421875001 -0.248125 -0.006591796875 0.1397607421875001 -0.24825 -0.005859375 0.1397607421875001 -0.248375 -0.005859375 0.1397607421875001 -0.2485 -0.005126953125 0.1397607421875001 -0.248625 -0.00439453125 0.1397607421875001 -0.24875 -0.00439453125 0.1397607421875001 -0.248875 -0.003662109375 0.1397607421875001 -0.249 -0.003662109375 0.1397607421875001 -0.249125 -0.0029296875 0.1397607421875001 -0.24925 -0.002197265625 0.1397607421875001 -0.249375 -0.002197265625 0.1397607421875001 -0.2495 -0.00146484375 0.1397607421875001 -0.249625 -0.00146484375 0.1397607421875001 -0.24975 -0.000732421875 0.1397607421875001 +0.187625 -0.003814697265625 0.7327783203125 +0.18775 -0.003814697265625 0.7327783203125 +0.187875 -0.007659912109375 0.7327783203125 +0.188 -0.011505126953125 0.7327783203125 +0.188125 -0.011505126953125 0.7327783203125 +0.18825 -0.01531982421875 0.7327783203125 +0.188375 -0.01531982421875 0.7327783203125 +0.1885 -0.019134521484375 0.7327783203125 +0.188625 -0.022979736328125 0.7327783203125 +0.18875 -0.022979736328125 0.7327783203125 +0.188875 -0.02679443359375 0.7327783203125 +0.189 -0.02679443359375 0.7327783203125 +0.189125 -0.0306396484375 0.7327783203125 +0.18925 -0.034454345703125 0.7327783203125 +0.189375 -0.034454345703125 0.7327783203125 +0.1895 -0.03826904296875 0.7327783203125 +0.189625 -0.03826904296875 0.7327783203125 +0.18975 -0.042083740234375 0.7327783203125 +0.189875 -0.0458984375 0.7327783203125 +0.19 -0.0458984375 0.7327783203125 +0.190125 -0.0496826171875 0.7327783203125 +0.19025 -0.0496826171875 0.7327783203125 +0.190375 -0.053497314453125 0.7327783203125 +0.1905 -0.057281494140625 0.7327783203125 +0.190625 -0.057281494140625 0.7327783203125 +0.19075 -0.061065673828125 0.7327783203125 +0.190875 -0.061065673828125 0.7327783203125 +0.191 -0.064849853515625 0.7327783203125 +0.191125 -0.068634033203125 0.7327783203125 +0.19125 -0.068634033203125 0.7327783203125 +0.191375 -0.0723876953125 0.7327783203125 +0.1915 -0.0723876953125 0.7327783203125 +0.191625 -0.076141357421875 0.7327783203125 +0.19175 -0.07989501953125 0.7327783203125 +0.191875 -0.07989501953125 0.7327783203125 +0.192 -0.0521240234375 0.4567333984374999 +0.192125 -0.0521240234375 0.4567333984374999 +0.19225 -0.054443359375 0.4567333984374999 +0.192375 -0.0567626953125 0.4567333984374999 +0.1925 -0.0567626953125 0.4567333984374999 +0.192625 -0.05908203125 0.4567333984374999 +0.19275 -0.05908203125 0.4567333984374999 +0.192875 -0.061370849609375 0.4567333984374999 +0.193 -0.063690185546875 0.4567333984374999 +0.193125 -0.063690185546875 0.4567333984374999 +0.19325 -0.06597900390625 0.4567333984374999 +0.193375 -0.06597900390625 0.4567333984374999 +0.1935 -0.068267822265625 0.4567333984374999 +0.193625 -0.070556640625 0.4567333984374999 +0.19375 -0.070556640625 0.4567333984374999 +0.193875 -0.07281494140625 0.4567333984374999 +0.194 -0.07281494140625 0.4567333984374999 +0.194125 -0.0750732421875 0.4567333984374999 +0.19425 -0.07733154296875 0.4567333984374999 +0.194375 -0.07733154296875 0.4567333984374999 +0.1945 -0.079559326171875 0.4567333984374999 +0.194625 -0.079559326171875 0.4567333984374999 +0.19475 -0.081817626953125 0.4567333984374999 +0.194875 -0.08404541015625 0.4567333984374999 +0.195 -0.08404541015625 0.4567333984374999 +0.195125 -0.08624267578125 0.4567333984374999 +0.19525 -0.08624267578125 0.4567333984374999 +0.195375 -0.088470458984375 0.4567333984374999 +0.1955 -0.090667724609375 0.4567333984374999 +0.195625 -0.090667724609375 0.4567333984374999 +0.19575 -0.092864990234375 0.4567333984374999 +0.195875 -0.092864990234375 0.4567333984374999 +0.196 -0.09503173828125 0.4567333984374999 +0.196125 -0.097198486328125 0.4567333984374999 +0.19625 -0.097198486328125 0.4567333984374999 +0.196375 -0.099365234375 0.4567333984374999 +0.1965 -0.099365234375 0.4567333984374999 +0.196625 -0.10150146484375 0.4567333984374999 +0.19675 -0.1036376953125 0.4567333984374999 +0.196875 -0.1036376953125 0.4567333984374999 +0.197 -0.10577392578125 0.4567333984374999 +0.197125 -0.10577392578125 0.4567333984374999 +0.19725 -0.107879638671875 0.4567333984374999 +0.197375 -0.1099853515625 0.4567333984374999 +0.1975 -0.1099853515625 0.4567333984374999 +0.197625 -0.112060546875 0.4567333984374999 +0.19775 -0.112060546875 0.4567333984374999 +0.197875 -0.114166259765625 0.4567333984374999 +0.198 -0.1162109375 0.4567333984374999 +0.198125 -0.1162109375 0.4567333984374999 +0.19825 -0.118255615234375 0.4567333984374999 +0.198375 -0.118255615234375 0.4567333984374999 +0.1985 -0.12030029296875 0.4567333984374999 +0.198625 -0.122344970703125 0.4567333984374999 +0.19875 -0.122344970703125 0.4567333984374999 +0.198875 -0.124359130859375 0.4567333984374999 +0.199 -0.124359130859375 0.4567333984374999 +0.199125 -0.1263427734375 0.4567333984374999 +0.19925 -0.128326416015625 0.4567333984374999 +0.199375 -0.128326416015625 0.4567333984374999 +0.1995 -0.13031005859375 0.4567333984374999 +0.199625 -0.13031005859375 0.4567333984374999 +0.19975 -0.13226318359375 0.4567333984374999 +0.199875 -0.134185791015625 0.4567333984374999 +0.2 -0.134185791015625 0.4567333984374999 +0.200125 -0.136138916015625 0.4567333984374999 +0.20025 -0.136138916015625 0.4567333984374999 +0.200375 -0.138031005859375 0.4567333984374999 +0.2005 -0.139923095703125 0.4567333984374999 +0.200625 -0.139923095703125 0.4567333984374999 +0.20075 -0.141815185546875 0.4567333984374999 +0.200875 -0.141815185546875 0.4567333984374999 +0.201 -0.1436767578125 0.4567333984374999 +0.201125 -0.145538330078125 0.4567333984374999 +0.20125 -0.145538330078125 0.4567333984374999 +0.201375 -0.147369384765625 0.4567333984374999 +0.2015 -0.147369384765625 0.4567333984374999 +0.201625 -0.149169921875 0.4567333984374999 +0.20175 -0.1510009765625 0.4567333984374999 +0.201875 -0.1510009765625 0.4567333984374999 +0.202 -0.15277099609375 0.4567333984374999 +0.202125 -0.15277099609375 0.4567333984374999 +0.20225 -0.154541015625 0.4567333984374999 +0.202375 -0.156280517578125 0.4567333984374999 +0.2025 -0.156280517578125 0.4567333984374999 +0.202625 -0.15802001953125 0.4567333984374999 +0.20275 -0.15802001953125 0.4567333984374999 +0.202875 -0.15972900390625 0.4567333984374999 +0.203 -0.16143798828125 0.4567333984374999 +0.203125 -0.16143798828125 0.4567333984374999 +0.20325 -0.163116455078125 0.4567333984374999 +0.203375 -0.163116455078125 0.4567333984374999 +0.2035 -0.164794921875 0.4567333984374999 +0.203625 -0.16644287109375 0.4567333984374999 +0.20375 -0.16644287109375 0.4567333984374999 +0.203875 -0.168060302734375 0.4567333984374999 +0.204 -0.168060302734375 0.4567333984374999 +0.204125 -0.169677734375 0.4567333984374999 +0.20425 -0.1712646484375 0.4567333984374999 +0.204375 -0.1712646484375 0.4567333984374999 +0.2045 -0.172821044921875 0.4567333984374999 +0.204625 -0.172821044921875 0.4567333984374999 +0.20475 -0.17437744140625 0.4567333984374999 +0.204875 -0.175933837890625 0.4567333984374999 +0.205 -0.175933837890625 0.4567333984374999 +0.205125 -0.17742919921875 0.4567333984374999 +0.20525 -0.17742919921875 0.4567333984374999 +0.205375 -0.178924560546875 0.4567333984374999 +0.2055 -0.180419921875 0.4567333984374999 +0.205625 -0.180419921875 0.4567333984374999 +0.20575 -0.181854248046875 0.4567333984374999 +0.205875 -0.181854248046875 0.4567333984374999 +0.206 -0.18328857421875 0.4567333984374999 +0.206125 -0.184722900390625 0.4567333984374999 +0.20625 -0.184722900390625 0.4567333984374999 +0.206375 -0.18609619140625 0.4567333984374999 +0.2065 -0.18609619140625 0.4567333984374999 +0.206625 -0.187469482421875 0.4567333984374999 +0.20675 -0.1888427734375 0.4567333984374999 +0.206875 -0.1888427734375 0.4567333984374999 +0.207 -0.190185546875 0.4567333984374999 +0.207125 -0.190185546875 0.4567333984374999 +0.20725 -0.19146728515625 0.4567333984374999 +0.207375 -0.192779541015625 0.4567333984374999 +0.2075 -0.192779541015625 0.4567333984374999 +0.207625 -0.194061279296875 0.4567333984374999 +0.20775 -0.194061279296875 0.4567333984374999 +0.207875 -0.195281982421875 0.4567333984374999 +0.208 -0.196533203125 0.4567333984374999 +0.208125 -0.196533203125 0.4567333984374999 +0.20825 -0.197723388671875 0.4567333984374999 +0.208375 -0.197723388671875 0.4567333984374999 +0.2085 -0.19891357421875 0.4567333984374999 +0.208625 -0.2000732421875 0.4567333984374999 +0.20875 -0.2000732421875 0.4567333984374999 +0.208875 -0.201202392578125 0.4567333984374999 +0.209 -0.201202392578125 0.4567333984374999 +0.209125 -0.20233154296875 0.4567333984374999 +0.20925 -0.20343017578125 0.4567333984374999 +0.209375 -0.20343017578125 0.4567333984374999 +0.2095 -0.204498291015625 0.4567333984374999 +0.209625 -0.204498291015625 0.4567333984374999 +0.20975 -0.20556640625 0.4567333984374999 +0.209875 -0.20660400390625 0.4567333984374999 +0.21 -0.20660400390625 0.4567333984374999 +0.210125 -0.20758056640625 0.4567333984374999 +0.21025 -0.20758056640625 0.4567333984374999 +0.210375 -0.208587646484375 0.4567333984374999 +0.2105 -0.20953369140625 0.4567333984374999 +0.210625 -0.20953369140625 0.4567333984374999 +0.21075 -0.210479736328125 0.4567333984374999 +0.210875 -0.210479736328125 0.4567333984374999 +0.211 -0.211395263671875 0.4567333984374999 +0.211125 -0.2122802734375 0.4567333984374999 +0.21125 -0.2122802734375 0.4567333984374999 +0.211375 -0.213165283203125 0.4567333984374999 +0.2115 -0.213165283203125 0.4567333984374999 +0.211625 -0.2139892578125 0.4567333984374999 +0.21175 -0.214813232421875 0.4567333984374999 +0.211875 -0.214813232421875 0.4567333984374999 +0.212 -0.215606689453125 0.4567333984374999 +0.212125 -0.215606689453125 0.4567333984374999 +0.21225 -0.216400146484375 0.4567333984374999 +0.212375 -0.2171630859375 0.4567333984374999 +0.2125 -0.2171630859375 0.4567333984374999 +0.212625 -0.217864990234375 0.4567333984374999 +0.21275 -0.217864990234375 0.4567333984374999 +0.212875 -0.21856689453125 0.4567333984374999 +0.213 -0.21923828125 0.4567333984374999 +0.213125 -0.21923828125 0.4567333984374999 +0.21325 -0.21990966796875 0.4567333984374999 +0.213375 -0.21990966796875 0.4567333984374999 +0.2135 -0.220550537109375 0.4567333984374999 +0.213625 -0.221160888671875 0.4567333984374999 +0.21375 -0.221160888671875 0.4567333984374999 +0.213875 -0.22174072265625 0.4567333984374999 +0.214 -0.22174072265625 0.4567333984374999 +0.214125 -0.2222900390625 0.4567333984374999 +0.21425 -0.222808837890625 0.4567333984374999 +0.214375 -0.222808837890625 0.4567333984374999 +0.2145 -0.22332763671875 0.4567333984374999 +0.214625 -0.22332763671875 0.4567333984374999 +0.21475 -0.22381591796875 0.4567333984374999 +0.214875 -0.224273681640625 0.4567333984374999 +0.215 -0.224273681640625 0.4567333984374999 +0.215125 -0.224700927734375 0.4567333984374999 +0.21525 -0.224700927734375 0.4567333984374999 +0.215375 -0.225128173828125 0.4567333984374999 +0.2155 -0.22552490234375 0.4567333984374999 +0.215625 -0.22552490234375 0.4567333984374999 +0.21575 -0.225860595703125 0.4567333984374999 +0.215875 -0.225860595703125 0.4567333984374999 +0.216 -0.2261962890625 0.4567333984374999 +0.216125 -0.226531982421875 0.4567333984374999 +0.21625 -0.226531982421875 0.4567333984374999 +0.216375 -0.226806640625 0.4567333984374999 +0.2165 -0.226806640625 0.4567333984374999 +0.216625 -0.227081298828125 0.4567333984374999 +0.21675 -0.227294921875 0.4567333984374999 +0.216875 -0.227294921875 0.4567333984374999 +0.217 -0.2275390625 0.4567333984374999 +0.217125 -0.2275390625 0.4567333984374999 +0.21725 -0.22772216796875 0.4567333984374999 +0.217375 -0.227874755859375 0.4567333984374999 +0.2175 -0.227874755859375 0.4567333984374999 +0.217625 -0.227996826171875 0.4567333984374999 +0.21775 -0.227996826171875 0.4567333984374999 +0.217875 -0.228118896484375 0.4567333984374999 +0.218 -0.22821044921875 0.4567333984374999 +0.218125 -0.22821044921875 0.4567333984374999 +0.21825 -0.228271484375 0.4567333984374999 +0.218375 -0.228271484375 0.4567333984374999 +0.2185 -0.228302001953125 0.4567333984374999 +0.218625 -0.22833251953125 0.4567333984374999 +0.21875 -0.22833251953125 0.4567333984374999 +0.218875 -0.228302001953125 0.4567333984374999 +0.219 -0.228302001953125 0.4567333984374999 +0.219125 -0.228271484375 0.4567333984374999 +0.21925 -0.22821044921875 0.4567333984374999 +0.219375 -0.22821044921875 0.4567333984374999 +0.2195 -0.228118896484375 0.4567333984374999 +0.219625 -0.228118896484375 0.4567333984374999 +0.21975 -0.227996826171875 0.4567333984374999 +0.219875 -0.227874755859375 0.4567333984374999 +0.22 -0.227874755859375 0.4567333984374999 +0.220125 -0.22772216796875 0.4567333984374999 +0.22025 -0.22772216796875 0.4567333984374999 +0.220375 -0.2275390625 0.4567333984374999 +0.2205 -0.227294921875 0.4567333984374999 +0.220625 -0.227294921875 0.4567333984374999 +0.22075 -0.227081298828125 0.4567333984374999 +0.220875 -0.227081298828125 0.4567333984374999 +0.221 -0.226806640625 0.4567333984374999 +0.221125 -0.226531982421875 0.4567333984374999 +0.22125 -0.226531982421875 0.4567333984374999 +0.221375 -0.2261962890625 0.4567333984374999 +0.2215 -0.2261962890625 0.4567333984374999 +0.221625 -0.225860595703125 0.4567333984374999 +0.22175 -0.22552490234375 0.4567333984374999 +0.221875 -0.22552490234375 0.4567333984374999 +0.222 -0.225128173828125 0.4567333984374999 +0.222125 -0.225128173828125 0.4567333984374999 +0.22225 -0.224700927734375 0.4567333984374999 +0.222375 -0.224273681640625 0.4567333984374999 +0.2225 -0.224273681640625 0.4567333984374999 +0.222625 -0.22381591796875 0.4567333984374999 +0.22275 -0.22381591796875 0.4567333984374999 +0.222875 -0.22332763671875 0.4567333984374999 +0.223 -0.222808837890625 0.4567333984374999 +0.223125 -0.222808837890625 0.4567333984374999 +0.22325 -0.2222900390625 0.4567333984374999 +0.223375 -0.2222900390625 0.4567333984374999 +0.2235 -0.22174072265625 0.4567333984374999 +0.223625 -0.221160888671875 0.4567333984374999 +0.22375 -0.221160888671875 0.4567333984374999 +0.223875 -0.220550537109375 0.4567333984374999 +0.224 -0.067474365234375 0.1397607421875001 +0.224125 -0.067291259765625 0.1397607421875001 +0.22425 -0.06707763671875 0.1397607421875001 +0.224375 -0.06707763671875 0.1397607421875001 +0.2245 -0.066864013671875 0.1397607421875001 +0.224625 -0.066864013671875 0.1397607421875001 +0.22475 -0.066650390625 0.1397607421875001 +0.224875 -0.066436767578125 0.1397607421875001 +0.225 -0.066436767578125 0.1397607421875001 +0.225125 -0.066192626953125 0.1397607421875001 +0.22525 -0.066192626953125 0.1397607421875001 +0.225375 -0.06597900390625 0.1397607421875001 +0.2255 -0.06573486328125 0.1397607421875001 +0.225625 -0.06573486328125 0.1397607421875001 +0.22575 -0.065460205078125 0.1397607421875001 +0.225875 -0.065460205078125 0.1397607421875001 +0.226 -0.065216064453125 0.1397607421875001 +0.226125 -0.06494140625 0.1397607421875001 +0.22625 -0.06494140625 0.1397607421875001 +0.226375 -0.064666748046875 0.1397607421875001 +0.2265 -0.064666748046875 0.1397607421875001 +0.226625 -0.06439208984375 0.1397607421875001 +0.22675 -0.064117431640625 0.1397607421875001 +0.226875 -0.064117431640625 0.1397607421875001 +0.227 -0.063812255859375 0.1397607421875001 +0.227125 -0.063812255859375 0.1397607421875001 +0.22725 -0.063507080078125 0.1397607421875001 +0.227375 -0.063201904296875 0.1397607421875001 +0.2275 -0.063201904296875 0.1397607421875001 +0.227625 -0.062896728515625 0.1397607421875001 +0.22775 -0.062896728515625 0.1397607421875001 +0.227875 -0.06256103515625 0.1397607421875001 +0.228 -0.062225341796875 0.1397607421875001 +0.228125 -0.062225341796875 0.1397607421875001 +0.22825 -0.0618896484375 0.1397607421875001 +0.228375 -0.0618896484375 0.1397607421875001 +0.2285 -0.061553955078125 0.1397607421875001 +0.228625 -0.06121826171875 0.1397607421875001 +0.22875 -0.06121826171875 0.1397607421875001 +0.228875 -0.06085205078125 0.1397607421875001 +0.229 -0.06085205078125 0.1397607421875001 +0.229125 -0.06048583984375 0.1397607421875001 +0.22925 -0.06011962890625 0.1397607421875001 +0.229375 -0.06011962890625 0.1397607421875001 +0.2295 -0.05975341796875 0.1397607421875001 +0.229625 -0.05975341796875 0.1397607421875001 +0.22975 -0.059356689453125 0.1397607421875001 +0.229875 -0.058990478515625 0.1397607421875001 +0.23 -0.058990478515625 0.1397607421875001 +0.230125 -0.05859375 0.1397607421875001 +0.23025 -0.05859375 0.1397607421875001 +0.230375 -0.05816650390625 0.1397607421875001 +0.2305 -0.057769775390625 0.1397607421875001 +0.230625 -0.057769775390625 0.1397607421875001 +0.23075 -0.057342529296875 0.1397607421875001 +0.230875 -0.057342529296875 0.1397607421875001 +0.231 -0.05694580078125 0.1397607421875001 +0.231125 -0.0565185546875 0.1397607421875001 +0.23125 -0.0565185546875 0.1397607421875001 +0.231375 -0.056060791015625 0.1397607421875001 +0.2315 -0.056060791015625 0.1397607421875001 +0.231625 -0.055633544921875 0.1397607421875001 +0.23175 -0.055206298828125 0.1397607421875001 +0.231875 -0.055206298828125 0.1397607421875001 +0.232 -0.05474853515625 0.1397607421875001 +0.232125 -0.05474853515625 0.1397607421875001 +0.23225 -0.054290771484375 0.1397607421875001 +0.232375 -0.0538330078125 0.1397607421875001 +0.2325 -0.0538330078125 0.1397607421875001 +0.232625 -0.0533447265625 0.1397607421875001 +0.23275 -0.0533447265625 0.1397607421875001 +0.232875 -0.052886962890625 0.1397607421875001 +0.233 -0.052398681640625 0.1397607421875001 +0.233125 -0.052398681640625 0.1397607421875001 +0.23325 -0.051910400390625 0.1397607421875001 +0.233375 -0.051910400390625 0.1397607421875001 +0.2335 -0.051422119140625 0.1397607421875001 +0.233625 -0.0509033203125 0.1397607421875001 +0.23375 -0.0509033203125 0.1397607421875001 +0.233875 -0.0504150390625 0.1397607421875001 +0.234 -0.0504150390625 0.1397607421875001 +0.234125 -0.049896240234375 0.1397607421875001 +0.23425 -0.04937744140625 0.1397607421875001 +0.234375 -0.04937744140625 0.1397607421875001 +0.2345 -0.048858642578125 0.1397607421875001 +0.234625 -0.048858642578125 0.1397607421875001 +0.23475 -0.04833984375 0.1397607421875001 +0.234875 -0.047821044921875 0.1397607421875001 +0.235 -0.047821044921875 0.1397607421875001 +0.235125 -0.047271728515625 0.1397607421875001 +0.23525 -0.047271728515625 0.1397607421875001 +0.235375 -0.046722412109375 0.1397607421875001 +0.2355 -0.04620361328125 0.1397607421875001 +0.235625 -0.04620361328125 0.1397607421875001 +0.23575 -0.045623779296875 0.1397607421875001 +0.235875 -0.045623779296875 0.1397607421875001 +0.236 -0.045074462890625 0.1397607421875001 +0.236125 -0.044525146484375 0.1397607421875001 +0.23625 -0.044525146484375 0.1397607421875001 +0.236375 -0.0439453125 0.1397607421875001 +0.2365 -0.0439453125 0.1397607421875001 +0.236625 -0.04339599609375 0.1397607421875001 +0.23675 -0.042816162109375 0.1397607421875001 +0.236875 -0.042816162109375 0.1397607421875001 +0.237 -0.042236328125 0.1397607421875001 +0.237125 -0.042236328125 0.1397607421875001 +0.23725 -0.0416259765625 0.1397607421875001 +0.237375 -0.041046142578125 0.1397607421875001 +0.2375 -0.041046142578125 0.1397607421875001 +0.237625 -0.04046630859375 0.1397607421875001 +0.23775 -0.04046630859375 0.1397607421875001 +0.237875 -0.03985595703125 0.1397607421875001 +0.238 -0.03924560546875 0.1397607421875001 +0.238125 -0.03924560546875 0.1397607421875001 +0.23825 -0.03863525390625 0.1397607421875001 +0.238375 -0.03863525390625 0.1397607421875001 +0.2385 -0.03802490234375 0.1397607421875001 +0.238625 -0.03741455078125 0.1397607421875001 +0.23875 -0.03741455078125 0.1397607421875001 +0.238875 -0.03680419921875 0.1397607421875001 +0.239 -0.03680419921875 0.1397607421875001 +0.239125 -0.036163330078125 0.1397607421875001 +0.23925 -0.035552978515625 0.1397607421875001 +0.239375 -0.035552978515625 0.1397607421875001 +0.2395 -0.034912109375 0.1397607421875001 +0.239625 -0.034912109375 0.1397607421875001 +0.23975 -0.034271240234375 0.1397607421875001 +0.239875 -0.03363037109375 0.1397607421875001 +0.24 -0.03363037109375 0.1397607421875001 +0.240125 -0.032989501953125 0.1397607421875001 +0.24025 -0.032989501953125 0.1397607421875001 +0.240375 -0.0323486328125 0.1397607421875001 +0.2405 -0.031707763671875 0.1397607421875001 +0.240625 -0.031707763671875 0.1397607421875001 +0.24075 -0.031036376953125 0.1397607421875001 +0.240875 -0.031036376953125 0.1397607421875001 +0.241 -0.0303955078125 0.1397607421875001 +0.241125 -0.02972412109375 0.1397607421875001 +0.24125 -0.02972412109375 0.1397607421875001 +0.241375 -0.029083251953125 0.1397607421875001 +0.2415 -0.029083251953125 0.1397607421875001 +0.241625 -0.028411865234375 0.1397607421875001 +0.24175 -0.027740478515625 0.1397607421875001 +0.241875 -0.027740478515625 0.1397607421875001 +0.242 -0.027069091796875 0.1397607421875001 +0.242125 -0.027069091796875 0.1397607421875001 +0.24225 -0.0263671875 0.1397607421875001 +0.242375 -0.02569580078125 0.1397607421875001 +0.2425 -0.02569580078125 0.1397607421875001 +0.242625 -0.0250244140625 0.1397607421875001 +0.24275 -0.0250244140625 0.1397607421875001 +0.242875 -0.024322509765625 0.1397607421875001 +0.243 -0.023651123046875 0.1397607421875001 +0.243125 -0.023651123046875 0.1397607421875001 +0.24325 -0.02294921875 0.1397607421875001 +0.243375 -0.02294921875 0.1397607421875001 +0.2435 -0.02227783203125 0.1397607421875001 +0.243625 -0.021575927734375 0.1397607421875001 +0.24375 -0.021575927734375 0.1397607421875001 +0.243875 -0.0208740234375 0.1397607421875001 +0.244 -0.0208740234375 0.1397607421875001 +0.244125 -0.020172119140625 0.1397607421875001 +0.24425 -0.01947021484375 0.1397607421875001 +0.244375 -0.01947021484375 0.1397607421875001 +0.2445 -0.018768310546875 0.1397607421875001 +0.244625 -0.018768310546875 0.1397607421875001 +0.24475 -0.01806640625 0.1397607421875001 +0.244875 -0.017364501953125 0.1397607421875001 +0.245 -0.017364501953125 0.1397607421875001 +0.245125 -0.01666259765625 0.1397607421875001 +0.24525 -0.01666259765625 0.1397607421875001 +0.245375 -0.01593017578125 0.1397607421875001 +0.2455 -0.015228271484375 0.1397607421875001 +0.245625 -0.015228271484375 0.1397607421875001 +0.24575 -0.014495849609375 0.1397607421875001 +0.245875 -0.014495849609375 0.1397607421875001 +0.246 -0.0137939453125 0.1397607421875001 +0.246125 -0.0130615234375 0.1397607421875001 +0.24625 -0.0130615234375 0.1397607421875001 +0.246375 -0.012359619140625 0.1397607421875001 +0.2465 -0.012359619140625 0.1397607421875001 +0.246625 -0.011627197265625 0.1397607421875001 +0.24675 -0.01092529296875 0.1397607421875001 +0.246875 -0.01092529296875 0.1397607421875001 +0.247 -0.01019287109375 0.1397607421875001 +0.247125 -0.01019287109375 0.1397607421875001 +0.24725 -0.00946044921875 0.1397607421875001 +0.247375 -0.00872802734375 0.1397607421875001 +0.2475 -0.00872802734375 0.1397607421875001 +0.247625 -0.008026123046875 0.1397607421875001 +0.24775 -0.008026123046875 0.1397607421875001 +0.247875 -0.007293701171875 0.1397607421875001 +0.248 -0.006561279296875 0.1397607421875001 +0.248125 -0.006561279296875 0.1397607421875001 +0.24825 -0.005828857421875 0.1397607421875001 +0.248375 -0.005828857421875 0.1397607421875001 +0.2485 -0.005096435546875 0.1397607421875001 +0.248625 -0.004364013671875 0.1397607421875001 +0.24875 -0.004364013671875 0.1397607421875001 +0.248875 -0.003631591796875 0.1397607421875001 +0.249 -0.003631591796875 0.1397607421875001 +0.249125 -0.002899169921875 0.1397607421875001 +0.24925 -0.002166748046875 0.1397607421875001 +0.249375 -0.002166748046875 0.1397607421875001 +0.2495 -0.001434326171875 0.1397607421875001 +0.249625 -0.001434326171875 0.1397607421875001 +0.24975 -0.000701904296875 0.1397607421875001 0.249875 0.0 0.1397607421875001 0.25 0.0 0.1397607421875001 0.250125 0.000701904296875 0.1397607421875001 @@ -2046,457 +2046,457 @@ 0.255625 0.01947021484375 0.1397607421875001 0.25575 0.020172119140625 0.1397607421875001 0.255875 0.020172119140625 0.1397607421875001 -0.256 -0.02508544921875 -0.1676269531250002 -0.256125 -0.025909423828125 -0.1676269531250002 -0.25625 -0.025909423828125 -0.1676269531250002 -0.256375 -0.0267333984375 -0.1676269531250002 -0.2565 -0.0267333984375 -0.1676269531250002 -0.256625 -0.027587890625 -0.1676269531250002 -0.25675 -0.028411865234375 -0.1676269531250002 -0.256875 -0.028411865234375 -0.1676269531250002 -0.257 -0.02923583984375 -0.1676269531250002 -0.257125 -0.02923583984375 -0.1676269531250002 -0.25725 -0.030059814453125 -0.1676269531250002 -0.257375 -0.030853271484375 -0.1676269531250002 -0.2575 -0.030853271484375 -0.1676269531250002 -0.257625 -0.03167724609375 -0.1676269531250002 -0.25775 -0.03167724609375 -0.1676269531250002 -0.257875 -0.032501220703125 -0.1676269531250002 -0.258 -0.033294677734375 -0.1676269531250002 -0.258125 -0.033294677734375 -0.1676269531250002 -0.25825 -0.03411865234375 -0.1676269531250002 -0.258375 -0.03411865234375 -0.1676269531250002 -0.2585 -0.034912109375 -0.1676269531250002 -0.258625 -0.03570556640625 -0.1676269531250002 -0.25875 -0.03570556640625 -0.1676269531250002 -0.258875 -0.0364990234375 -0.1676269531250002 -0.259 -0.0364990234375 -0.1676269531250002 -0.259125 -0.03729248046875 -0.1676269531250002 -0.25925 -0.038055419921875 -0.1676269531250002 -0.259375 -0.038055419921875 -0.1676269531250002 -0.2595 -0.038848876953125 -0.1676269531250002 -0.259625 -0.038848876953125 -0.1676269531250002 -0.25975 -0.03961181640625 -0.1676269531250002 -0.259875 -0.0404052734375 -0.1676269531250002 -0.26 -0.0404052734375 -0.1676269531250002 -0.260125 -0.041168212890625 -0.1676269531250002 -0.26025 -0.041168212890625 -0.1676269531250002 -0.260375 -0.04193115234375 -0.1676269531250002 -0.2605 -0.04266357421875 -0.1676269531250002 -0.260625 -0.04266357421875 -0.1676269531250002 -0.26075 -0.043426513671875 -0.1676269531250002 -0.260875 -0.043426513671875 -0.1676269531250002 -0.261 -0.044189453125 -0.1676269531250002 -0.261125 -0.044921875 -0.1676269531250002 -0.26125 -0.044921875 -0.1676269531250002 -0.261375 -0.045654296875 -0.1676269531250002 -0.2615 -0.045654296875 -0.1676269531250002 -0.261625 -0.04638671875 -0.1676269531250002 -0.26175 -0.047119140625 -0.1676269531250002 -0.261875 -0.047119140625 -0.1676269531250002 -0.262 -0.0478515625 -0.1676269531250002 -0.262125 -0.0478515625 -0.1676269531250002 -0.26225 -0.048553466796875 -0.1676269531250002 -0.262375 -0.049285888671875 -0.1676269531250002 -0.2625 -0.049285888671875 -0.1676269531250002 -0.262625 -0.04998779296875 -0.1676269531250002 -0.26275 -0.04998779296875 -0.1676269531250002 -0.262875 -0.050689697265625 -0.1676269531250002 -0.263 -0.0513916015625 -0.1676269531250002 -0.263125 -0.0513916015625 -0.1676269531250002 -0.26325 -0.05206298828125 -0.1676269531250002 -0.263375 -0.05206298828125 -0.1676269531250002 -0.2635 -0.052764892578125 -0.1676269531250002 -0.263625 -0.053436279296875 -0.1676269531250002 -0.26375 -0.053436279296875 -0.1676269531250002 -0.263875 -0.054107666015625 -0.1676269531250002 -0.264 -0.054107666015625 -0.1676269531250002 -0.264125 -0.054779052734375 -0.1676269531250002 -0.26425 -0.055450439453125 -0.1676269531250002 -0.264375 -0.055450439453125 -0.1676269531250002 -0.2645 -0.05609130859375 -0.1676269531250002 -0.264625 -0.05609130859375 -0.1676269531250002 -0.26475 -0.056732177734375 -0.1676269531250002 -0.264875 -0.057403564453125 -0.1676269531250002 -0.265 -0.057403564453125 -0.1676269531250002 -0.265125 -0.058013916015625 -0.1676269531250002 -0.26525 -0.058013916015625 -0.1676269531250002 -0.265375 -0.05865478515625 -0.1676269531250002 -0.2655 -0.05926513671875 -0.1676269531250002 -0.265625 -0.05926513671875 -0.1676269531250002 -0.26575 -0.059906005859375 -0.1676269531250002 -0.265875 -0.059906005859375 -0.1676269531250002 -0.266 -0.060516357421875 -0.1676269531250002 -0.266125 -0.061126708984375 -0.1676269531250002 -0.26625 -0.061126708984375 -0.1676269531250002 -0.266375 -0.06170654296875 -0.1676269531250002 -0.2665 -0.06170654296875 -0.1676269531250002 -0.266625 -0.062286376953125 -0.1676269531250002 -0.26675 -0.062896728515625 -0.1676269531250002 -0.266875 -0.062896728515625 -0.1676269531250002 -0.267 -0.063446044921875 -0.1676269531250002 -0.267125 -0.063446044921875 -0.1676269531250002 -0.26725 -0.06402587890625 -0.1676269531250002 -0.267375 -0.064605712890625 -0.1676269531250002 -0.2675 -0.064605712890625 -0.1676269531250002 -0.267625 -0.065155029296875 -0.1676269531250002 -0.26775 -0.065155029296875 -0.1676269531250002 -0.267875 -0.065704345703125 -0.1676269531250002 -0.268 -0.066253662109375 -0.1676269531250002 -0.268125 -0.066253662109375 -0.1676269531250002 -0.26825 -0.0667724609375 -0.1676269531250002 -0.268375 -0.0667724609375 -0.1676269531250002 -0.2685 -0.067291259765625 -0.1676269531250002 -0.268625 -0.06781005859375 -0.1676269531250002 -0.26875 -0.06781005859375 -0.1676269531250002 -0.268875 -0.068328857421875 -0.1676269531250002 -0.269 -0.068328857421875 -0.1676269531250002 -0.269125 -0.06884765625 -0.1676269531250002 -0.26925 -0.0693359375 -0.1676269531250002 -0.2693750000000001 -0.0693359375 -0.1676269531250002 -0.2695 -0.06982421875 -0.1676269531250002 -0.269625 -0.06982421875 -0.1676269531250002 -0.26975 -0.0703125 -0.1676269531250002 -0.269875 -0.070770263671875 -0.1676269531250002 -0.27 -0.070770263671875 -0.1676269531250002 -0.270125 -0.071258544921875 -0.1676269531250002 -0.27025 -0.071258544921875 -0.1676269531250002 -0.270375 -0.07171630859375 -0.1676269531250002 -0.2705 -0.0721435546875 -0.1676269531250002 -0.270625 -0.0721435546875 -0.1676269531250002 -0.27075 -0.072601318359375 -0.1676269531250002 -0.270875 -0.072601318359375 -0.1676269531250002 -0.271 -0.073028564453125 -0.1676269531250002 -0.271125 -0.073455810546875 -0.1676269531250002 -0.27125 -0.073455810546875 -0.1676269531250002 -0.271375 -0.073883056640625 -0.1676269531250002 -0.2715 -0.073883056640625 -0.1676269531250002 -0.271625 -0.07427978515625 -0.1676269531250002 -0.27175 -0.07470703125 -0.1676269531250002 -0.271875 -0.07470703125 -0.1676269531250002 -0.272 -0.0750732421875 -0.1676269531250002 -0.272125 -0.0750732421875 -0.1676269531250002 -0.27225 -0.075469970703125 -0.1676269531250002 -0.272375 -0.075836181640625 -0.1676269531250002 -0.2725 -0.075836181640625 -0.1676269531250002 -0.272625 -0.07623291015625 -0.1676269531250002 -0.27275 -0.07623291015625 -0.1676269531250002 -0.272875 -0.076568603515625 -0.1676269531250002 -0.273 -0.076934814453125 -0.1676269531250002 -0.273125 -0.076934814453125 -0.1676269531250002 -0.27325 -0.0772705078125 -0.1676269531250002 -0.273375 -0.0772705078125 -0.1676269531250002 -0.2735 -0.077606201171875 -0.1676269531250002 -0.273625 -0.07794189453125 -0.1676269531250002 -0.27375 -0.07794189453125 -0.1676269531250002 -0.273875 -0.0782470703125 -0.1676269531250002 -0.274 -0.0782470703125 -0.1676269531250002 -0.274125 -0.078582763671875 -0.1676269531250002 -0.27425 -0.078857421875 -0.1676269531250002 -0.274375 -0.078857421875 -0.1676269531250002 -0.2745 -0.07916259765625 -0.1676269531250002 -0.274625 -0.07916259765625 -0.1676269531250002 -0.27475 -0.079437255859375 -0.1676269531250002 -0.274875 -0.0797119140625 -0.1676269531250002 -0.275 -0.0797119140625 -0.1676269531250002 -0.275125 -0.079986572265625 -0.1676269531250002 -0.27525 -0.079986572265625 -0.1676269531250002 -0.275375 -0.08026123046875 -0.1676269531250002 -0.2755 -0.08050537109375 -0.1676269531250002 -0.275625 -0.08050537109375 -0.1676269531250002 -0.27575 -0.08074951171875 -0.1676269531250002 -0.275875 -0.08074951171875 -0.1676269531250002 -0.276 -0.080963134765625 -0.1676269531250002 -0.276125 -0.081207275390625 -0.1676269531250002 -0.27625 -0.081207275390625 -0.1676269531250002 -0.276375 -0.0814208984375 -0.1676269531250002 -0.2765 -0.0814208984375 -0.1676269531250002 -0.276625 -0.08160400390625 -0.1676269531250002 -0.27675 -0.081817626953125 -0.1676269531250002 -0.276875 -0.081817626953125 -0.1676269531250002 -0.277 -0.082000732421875 -0.1676269531250002 -0.277125 -0.082000732421875 -0.1676269531250002 -0.27725 -0.082183837890625 -0.1676269531250002 -0.277375 -0.08233642578125 -0.1676269531250002 -0.2775 -0.08233642578125 -0.1676269531250002 -0.277625 -0.082489013671875 -0.1676269531250002 -0.27775 -0.082489013671875 -0.1676269531250002 -0.277875 -0.0826416015625 -0.1676269531250002 -0.278 -0.082794189453125 -0.1676269531250002 -0.278125 -0.082794189453125 -0.1676269531250002 -0.27825 -0.082916259765625 -0.1676269531250002 -0.278375 -0.082916259765625 -0.1676269531250002 -0.2785 -0.083038330078125 -0.1676269531250002 -0.278625 -0.083160400390625 -0.1676269531250002 -0.27875 -0.083160400390625 -0.1676269531250002 -0.278875 -0.083282470703125 -0.1676269531250002 -0.279 -0.083282470703125 -0.1676269531250002 -0.279125 -0.0833740234375 -0.1676269531250002 -0.27925 -0.083465576171875 -0.1676269531250002 -0.279375 -0.083465576171875 -0.1676269531250002 -0.2795 -0.083526611328125 -0.1676269531250002 -0.279625 -0.083526611328125 -0.1676269531250002 -0.27975 -0.0836181640625 -0.1676269531250002 -0.279875 -0.083648681640625 -0.1676269531250002 -0.28 -0.083648681640625 -0.1676269531250002 -0.280125 -0.083709716796875 -0.1676269531250002 -0.28025 -0.083709716796875 -0.1676269531250002 -0.280375 -0.083740234375 -0.1676269531250002 -0.2805 -0.083770751953125 -0.1676269531250002 -0.280625 -0.083770751953125 -0.1676269531250002 -0.28075 -0.08380126953125 -0.1676269531250002 -0.280875 -0.08380126953125 -0.1676269531250002 -0.281 -0.083831787109375 -0.1676269531250002 -0.281125 -0.083831787109375 -0.1676269531250002 -0.28125 -0.083831787109375 -0.1676269531250002 -0.281375 -0.083831787109375 -0.1676269531250002 -0.2815 -0.083831787109375 -0.1676269531250002 -0.281625 -0.08380126953125 -0.1676269531250002 -0.28175 -0.083770751953125 -0.1676269531250002 -0.281875 -0.083770751953125 -0.1676269531250002 -0.282 -0.083740234375 -0.1676269531250002 -0.282125 -0.083740234375 -0.1676269531250002 -0.28225 -0.083709716796875 -0.1676269531250002 -0.282375 -0.083648681640625 -0.1676269531250002 -0.2825 -0.083648681640625 -0.1676269531250002 -0.282625 -0.0836181640625 -0.1676269531250002 -0.28275 -0.0836181640625 -0.1676269531250002 -0.282875 -0.083526611328125 -0.1676269531250002 -0.283 -0.083465576171875 -0.1676269531250002 -0.283125 -0.083465576171875 -0.1676269531250002 -0.28325 -0.0833740234375 -0.1676269531250002 -0.283375 -0.0833740234375 -0.1676269531250002 -0.2835 -0.083282470703125 -0.1676269531250002 -0.283625 -0.083160400390625 -0.1676269531250002 -0.28375 -0.083160400390625 -0.1676269531250002 -0.283875 -0.083038330078125 -0.1676269531250002 -0.284 -0.083038330078125 -0.1676269531250002 -0.284125 -0.082916259765625 -0.1676269531250002 -0.28425 -0.082794189453125 -0.1676269531250002 -0.284375 -0.082794189453125 -0.1676269531250002 -0.2845 -0.0826416015625 -0.1676269531250002 -0.284625 -0.0826416015625 -0.1676269531250002 -0.28475 -0.082489013671875 -0.1676269531250002 -0.284875 -0.08233642578125 -0.1676269531250002 -0.2850000000000001 -0.08233642578125 -0.1676269531250002 -0.285125 -0.082183837890625 -0.1676269531250002 -0.28525 -0.082183837890625 -0.1676269531250002 -0.285375 -0.082000732421875 -0.1676269531250002 -0.2855 -0.081817626953125 -0.1676269531250002 -0.285625 -0.081817626953125 -0.1676269531250002 -0.28575 -0.08160400390625 -0.1676269531250002 -0.285875 -0.08160400390625 -0.1676269531250002 -0.286 -0.0814208984375 -0.1676269531250002 -0.286125 -0.081207275390625 -0.1676269531250002 -0.28625 -0.081207275390625 -0.1676269531250002 -0.286375 -0.080963134765625 -0.1676269531250002 -0.2865 -0.080963134765625 -0.1676269531250002 -0.286625 -0.08074951171875 -0.1676269531250002 -0.28675 -0.08050537109375 -0.1676269531250002 -0.286875 -0.08050537109375 -0.1676269531250002 -0.287 -0.08026123046875 -0.1676269531250002 -0.287125 -0.08026123046875 -0.1676269531250002 -0.28725 -0.079986572265625 -0.1676269531250002 -0.287375 -0.0797119140625 -0.1676269531250002 -0.2875 -0.0797119140625 -0.1676269531250002 -0.287625 -0.079437255859375 -0.1676269531250002 -0.28775 -0.079437255859375 -0.1676269531250002 -0.287875 -0.07916259765625 -0.1676269531250002 -0.288 -0.195892333984375 -0.4163818359375004 -0.288125 -0.195892333984375 -0.4163818359375004 -0.28825 -0.19512939453125 -0.4163818359375004 -0.288375 -0.19512939453125 -0.4163818359375004 -0.2885 -0.194366455078125 -0.4163818359375004 -0.288625 -0.193572998046875 -0.4163818359375004 -0.28875 -0.193572998046875 -0.4163818359375004 -0.288875 -0.192779541015625 -0.4163818359375004 -0.289 -0.192779541015625 -0.4163818359375004 -0.289125 -0.191925048828125 -0.4163818359375004 -0.28925 -0.191070556640625 -0.4163818359375004 -0.289375 -0.191070556640625 -0.4163818359375004 -0.2895 -0.190185546875 -0.4163818359375004 -0.289625 -0.190185546875 -0.4163818359375004 -0.28975 -0.189300537109375 -0.4163818359375004 -0.289875 -0.188385009765625 -0.4163818359375004 -0.29 -0.188385009765625 -0.4163818359375004 -0.290125 -0.18743896484375 -0.4163818359375004 -0.29025 -0.18743896484375 -0.4163818359375004 -0.290375 -0.186492919921875 -0.4163818359375004 -0.2905 -0.185516357421875 -0.4163818359375004 -0.290625 -0.185516357421875 -0.4163818359375004 -0.29075 -0.18450927734375 -0.4163818359375004 -0.290875 -0.18450927734375 -0.4163818359375004 -0.291 -0.1834716796875 -0.4163818359375004 -0.291125 -0.18243408203125 -0.4163818359375004 -0.29125 -0.18243408203125 -0.4163818359375004 -0.291375 -0.181396484375 -0.4163818359375004 -0.2915 -0.181396484375 -0.4163818359375004 -0.291625 -0.1802978515625 -0.4163818359375004 -0.29175 -0.17919921875 -0.4163818359375004 -0.291875 -0.17919921875 -0.4163818359375004 -0.292 -0.178070068359375 -0.4163818359375004 -0.292125 -0.178070068359375 -0.4163818359375004 -0.29225 -0.17694091796875 -0.4163818359375004 -0.292375 -0.17578125 -0.4163818359375004 -0.2925 -0.17578125 -0.4163818359375004 -0.292625 -0.17462158203125 -0.4163818359375004 -0.29275 -0.17462158203125 -0.4163818359375004 -0.292875 -0.17340087890625 -0.4163818359375004 -0.293 -0.17218017578125 -0.4163818359375004 -0.293125 -0.17218017578125 -0.4163818359375004 -0.29325 -0.17095947265625 -0.4163818359375004 -0.293375 -0.17095947265625 -0.4163818359375004 -0.2935 -0.169708251953125 -0.4163818359375004 -0.293625 -0.168426513671875 -0.4163818359375004 -0.29375 -0.168426513671875 -0.4163818359375004 -0.293875 -0.167144775390625 -0.4163818359375004 -0.294 -0.167144775390625 -0.4163818359375004 -0.294125 -0.16583251953125 -0.4163818359375004 -0.29425 -0.164520263671875 -0.4163818359375004 -0.294375 -0.164520263671875 -0.4163818359375004 -0.2945 -0.163177490234375 -0.4163818359375004 -0.294625 -0.163177490234375 -0.4163818359375004 -0.29475 -0.16180419921875 -0.4163818359375004 -0.294875 -0.160430908203125 -0.4163818359375004 -0.295 -0.160430908203125 -0.4163818359375004 -0.295125 -0.159027099609375 -0.4163818359375004 -0.29525 -0.159027099609375 -0.4163818359375004 -0.295375 -0.1575927734375 -0.4163818359375004 -0.2955 -0.156158447265625 -0.4163818359375004 -0.295625 -0.156158447265625 -0.4163818359375004 -0.29575 -0.15472412109375 -0.4163818359375004 -0.295875 -0.15472412109375 -0.4163818359375004 -0.296 -0.15325927734375 -0.4163818359375004 -0.296125 -0.151763916015625 -0.4163818359375004 -0.29625 -0.151763916015625 -0.4163818359375004 -0.296375 -0.1502685546875 -0.4163818359375004 -0.2965 -0.1502685546875 -0.4163818359375004 -0.296625 -0.14874267578125 -0.4163818359375004 -0.29675 -0.147216796875 -0.4163818359375004 -0.296875 -0.147216796875 -0.4163818359375004 -0.297 -0.145660400390625 -0.4163818359375004 -0.297125 -0.145660400390625 -0.4163818359375004 -0.29725 -0.14410400390625 -0.4163818359375004 -0.297375 -0.14251708984375 -0.4163818359375004 -0.2975 -0.14251708984375 -0.4163818359375004 -0.297625 -0.14093017578125 -0.4163818359375004 -0.29775 -0.14093017578125 -0.4163818359375004 -0.297875 -0.139312744140625 -0.4163818359375004 -0.298 -0.1376953125 -0.4163818359375004 -0.298125 -0.1376953125 -0.4163818359375004 -0.29825 -0.13604736328125 -0.4163818359375004 -0.298375 -0.13604736328125 -0.4163818359375004 -0.2985 -0.1343994140625 -0.4163818359375004 -0.298625 -0.132720947265625 -0.4163818359375004 -0.29875 -0.132720947265625 -0.4163818359375004 -0.298875 -0.131011962890625 -0.4163818359375004 -0.299 -0.131011962890625 -0.4163818359375004 -0.299125 -0.12933349609375 -0.4163818359375004 -0.29925 -0.12762451171875 -0.4163818359375004 -0.299375 -0.12762451171875 -0.4163818359375004 -0.2995 -0.125885009765625 -0.4163818359375004 -0.299625 -0.125885009765625 -0.4163818359375004 -0.29975 -0.1241455078125 -0.4163818359375004 -0.299875 -0.12237548828125 -0.4163818359375004 -0.3 -0.12237548828125 -0.4163818359375004 -0.300125 -0.12060546875 -0.4163818359375004 -0.30025 -0.12060546875 -0.4163818359375004 -0.300375 -0.11883544921875 -0.4163818359375004 -0.3005 -0.117034912109375 -0.4163818359375004 -0.3006250000000001 -0.117034912109375 -0.4163818359375004 -0.30075 -0.115203857421875 -0.4163818359375004 -0.300875 -0.115203857421875 -0.4163818359375004 -0.301 -0.1134033203125 -0.4163818359375004 -0.301125 -0.111572265625 -0.4163818359375004 -0.30125 -0.111572265625 -0.4163818359375004 -0.301375 -0.109710693359375 -0.4163818359375004 -0.3015 -0.109710693359375 -0.4163818359375004 -0.301625 -0.10784912109375 -0.4163818359375004 -0.30175 -0.105987548828125 -0.4163818359375004 -0.301875 -0.105987548828125 -0.4163818359375004 -0.302 -0.104095458984375 -0.4163818359375004 -0.302125 -0.104095458984375 -0.4163818359375004 -0.30225 -0.102203369140625 -0.4163818359375004 -0.302375 -0.100311279296875 -0.4163818359375004 -0.3025 -0.100311279296875 -0.4163818359375004 -0.302625 -0.098388671875 -0.4163818359375004 -0.30275 -0.098388671875 -0.4163818359375004 -0.302875 -0.096466064453125 -0.4163818359375004 -0.303 -0.094512939453125 -0.4163818359375004 -0.303125 -0.094512939453125 -0.4163818359375004 -0.30325 -0.09259033203125 -0.4163818359375004 -0.303375 -0.09259033203125 -0.4163818359375004 -0.3035 -0.09063720703125 -0.4163818359375004 -0.303625 -0.088653564453125 -0.4163818359375004 -0.30375 -0.088653564453125 -0.4163818359375004 -0.303875 -0.086669921875 -0.4163818359375004 -0.304 -0.086669921875 -0.4163818359375004 -0.304125 -0.084686279296875 -0.4163818359375004 -0.30425 -0.08270263671875 -0.4163818359375004 -0.304375 -0.08270263671875 -0.4163818359375004 -0.3045 -0.0806884765625 -0.4163818359375004 -0.304625 -0.0806884765625 -0.4163818359375004 -0.30475 -0.07867431640625 -0.4163818359375004 -0.304875 -0.07666015625 -0.4163818359375004 -0.305 -0.07666015625 -0.4163818359375004 -0.305125 -0.074615478515625 -0.4163818359375004 -0.30525 -0.074615478515625 -0.4163818359375004 -0.305375 -0.07257080078125 -0.4163818359375004 -0.3055 -0.070526123046875 -0.4163818359375004 -0.305625 -0.070526123046875 -0.4163818359375004 -0.30575 -0.0684814453125 -0.4163818359375004 -0.305875 -0.0684814453125 -0.4163818359375004 -0.306 -0.06640625 -0.4163818359375004 -0.306125 -0.0643310546875 -0.4163818359375004 -0.30625 -0.0643310546875 -0.4163818359375004 -0.306375 -0.062255859375 -0.4163818359375004 -0.3065 -0.062255859375 -0.4163818359375004 -0.306625 -0.0601806640625 -0.4163818359375004 -0.30675 -0.05810546875 -0.4163818359375004 -0.306875 -0.05810546875 -0.4163818359375004 -0.307 -0.055999755859375 -0.4163818359375004 -0.307125 -0.055999755859375 -0.4163818359375004 -0.30725 -0.05389404296875 -0.4163818359375004 -0.307375 -0.051788330078125 -0.4163818359375004 -0.3075 -0.051788330078125 -0.4163818359375004 -0.307625 -0.0496826171875 -0.4163818359375004 -0.30775 -0.0496826171875 -0.4163818359375004 -0.307875 -0.04754638671875 -0.4163818359375004 -0.308 -0.04541015625 -0.4163818359375004 -0.308125 -0.04541015625 -0.4163818359375004 -0.30825 -0.043304443359375 -0.4163818359375004 -0.308375 -0.043304443359375 -0.4163818359375004 -0.3085 -0.041168212890625 -0.4163818359375004 -0.308625 -0.039031982421875 -0.4163818359375004 -0.30875 -0.039031982421875 -0.4163818359375004 -0.308875 -0.036865234375 -0.4163818359375004 -0.309 -0.036865234375 -0.4163818359375004 -0.309125 -0.03472900390625 -0.4163818359375004 -0.30925 -0.032562255859375 -0.4163818359375004 -0.309375 -0.032562255859375 -0.4163818359375004 -0.3095 -0.030426025390625 -0.4163818359375004 -0.309625 -0.030426025390625 -0.4163818359375004 -0.30975 -0.02825927734375 -0.4163818359375004 -0.309875 -0.026092529296875 -0.4163818359375004 -0.31 -0.026092529296875 -0.4163818359375004 -0.310125 -0.023956298828125 -0.4163818359375004 -0.31025 -0.023956298828125 -0.4163818359375004 -0.310375 -0.02178955078125 -0.4163818359375004 -0.3105 -0.01959228515625 -0.4163818359375004 -0.310625 -0.01959228515625 -0.4163818359375004 -0.31075 -0.017425537109375 -0.4163818359375004 -0.310875 -0.017425537109375 -0.4163818359375004 -0.311 -0.0152587890625 -0.4163818359375004 -0.311125 -0.013092041015625 -0.4163818359375004 -0.31125 -0.013092041015625 -0.4163818359375004 -0.311375 -0.010894775390625 -0.4163818359375004 -0.3115 -0.010894775390625 -0.4163818359375004 -0.311625 -0.00872802734375 -0.4163818359375004 -0.31175 -0.006561279296875 -0.4163818359375004 -0.311875 -0.006561279296875 -0.4163818359375004 -0.312 -0.004364013671875 -0.4163818359375004 -0.312125 -0.004364013671875 -0.4163818359375004 -0.31225 -0.002197265625 -0.4163818359375004 +0.256 -0.025054931640625 -0.1676269531250002 +0.256125 -0.02587890625 -0.1676269531250002 +0.25625 -0.02587890625 -0.1676269531250002 +0.256375 -0.026702880859375 -0.1676269531250002 +0.2565 -0.026702880859375 -0.1676269531250002 +0.256625 -0.027557373046875 -0.1676269531250002 +0.25675 -0.02838134765625 -0.1676269531250002 +0.256875 -0.02838134765625 -0.1676269531250002 +0.257 -0.029205322265625 -0.1676269531250002 +0.257125 -0.029205322265625 -0.1676269531250002 +0.25725 -0.030029296875 -0.1676269531250002 +0.257375 -0.03082275390625 -0.1676269531250002 +0.2575 -0.03082275390625 -0.1676269531250002 +0.257625 -0.031646728515625 -0.1676269531250002 +0.25775 -0.031646728515625 -0.1676269531250002 +0.257875 -0.032470703125 -0.1676269531250002 +0.258 -0.03326416015625 -0.1676269531250002 +0.258125 -0.03326416015625 -0.1676269531250002 +0.25825 -0.034088134765625 -0.1676269531250002 +0.258375 -0.034088134765625 -0.1676269531250002 +0.2585 -0.034881591796875 -0.1676269531250002 +0.258625 -0.035675048828125 -0.1676269531250002 +0.25875 -0.035675048828125 -0.1676269531250002 +0.258875 -0.036468505859375 -0.1676269531250002 +0.259 -0.036468505859375 -0.1676269531250002 +0.259125 -0.037261962890625 -0.1676269531250002 +0.25925 -0.03802490234375 -0.1676269531250002 +0.259375 -0.03802490234375 -0.1676269531250002 +0.2595 -0.038818359375 -0.1676269531250002 +0.259625 -0.038818359375 -0.1676269531250002 +0.25975 -0.039581298828125 -0.1676269531250002 +0.259875 -0.040374755859375 -0.1676269531250002 +0.26 -0.040374755859375 -0.1676269531250002 +0.260125 -0.0411376953125 -0.1676269531250002 +0.26025 -0.0411376953125 -0.1676269531250002 +0.260375 -0.041900634765625 -0.1676269531250002 +0.2605 -0.042633056640625 -0.1676269531250002 +0.260625 -0.042633056640625 -0.1676269531250002 +0.26075 -0.04339599609375 -0.1676269531250002 +0.260875 -0.04339599609375 -0.1676269531250002 +0.261 -0.044158935546875 -0.1676269531250002 +0.261125 -0.044891357421875 -0.1676269531250002 +0.26125 -0.044891357421875 -0.1676269531250002 +0.261375 -0.045623779296875 -0.1676269531250002 +0.2615 -0.045623779296875 -0.1676269531250002 +0.261625 -0.046356201171875 -0.1676269531250002 +0.26175 -0.047088623046875 -0.1676269531250002 +0.261875 -0.047088623046875 -0.1676269531250002 +0.262 -0.047821044921875 -0.1676269531250002 +0.262125 -0.047821044921875 -0.1676269531250002 +0.26225 -0.04852294921875 -0.1676269531250002 +0.262375 -0.04925537109375 -0.1676269531250002 +0.2625 -0.04925537109375 -0.1676269531250002 +0.262625 -0.049957275390625 -0.1676269531250002 +0.26275 -0.049957275390625 -0.1676269531250002 +0.262875 -0.0506591796875 -0.1676269531250002 +0.263 -0.051361083984375 -0.1676269531250002 +0.263125 -0.051361083984375 -0.1676269531250002 +0.26325 -0.052032470703125 -0.1676269531250002 +0.263375 -0.052032470703125 -0.1676269531250002 +0.2635 -0.052734375 -0.1676269531250002 +0.263625 -0.05340576171875 -0.1676269531250002 +0.26375 -0.05340576171875 -0.1676269531250002 +0.263875 -0.0540771484375 -0.1676269531250002 +0.264 -0.0540771484375 -0.1676269531250002 +0.264125 -0.05474853515625 -0.1676269531250002 +0.26425 -0.055419921875 -0.1676269531250002 +0.264375 -0.055419921875 -0.1676269531250002 +0.2645 -0.056060791015625 -0.1676269531250002 +0.264625 -0.056060791015625 -0.1676269531250002 +0.26475 -0.05670166015625 -0.1676269531250002 +0.264875 -0.057373046875 -0.1676269531250002 +0.265 -0.057373046875 -0.1676269531250002 +0.265125 -0.0579833984375 -0.1676269531250002 +0.26525 -0.0579833984375 -0.1676269531250002 +0.265375 -0.058624267578125 -0.1676269531250002 +0.2655 -0.059234619140625 -0.1676269531250002 +0.265625 -0.059234619140625 -0.1676269531250002 +0.26575 -0.05987548828125 -0.1676269531250002 +0.265875 -0.05987548828125 -0.1676269531250002 +0.266 -0.06048583984375 -0.1676269531250002 +0.266125 -0.06109619140625 -0.1676269531250002 +0.26625 -0.06109619140625 -0.1676269531250002 +0.266375 -0.061676025390625 -0.1676269531250002 +0.2665 -0.061676025390625 -0.1676269531250002 +0.266625 -0.062255859375 -0.1676269531250002 +0.26675 -0.0628662109375 -0.1676269531250002 +0.266875 -0.0628662109375 -0.1676269531250002 +0.267 -0.06341552734375 -0.1676269531250002 +0.267125 -0.06341552734375 -0.1676269531250002 +0.26725 -0.063995361328125 -0.1676269531250002 +0.267375 -0.0645751953125 -0.1676269531250002 +0.2675 -0.0645751953125 -0.1676269531250002 +0.267625 -0.06512451171875 -0.1676269531250002 +0.26775 -0.06512451171875 -0.1676269531250002 +0.267875 -0.065673828125 -0.1676269531250002 +0.268 -0.06622314453125 -0.1676269531250002 +0.268125 -0.06622314453125 -0.1676269531250002 +0.26825 -0.066741943359375 -0.1676269531250002 +0.268375 -0.066741943359375 -0.1676269531250002 +0.2685 -0.0672607421875 -0.1676269531250002 +0.268625 -0.067779541015625 -0.1676269531250002 +0.26875 -0.067779541015625 -0.1676269531250002 +0.268875 -0.06829833984375 -0.1676269531250002 +0.269 -0.06829833984375 -0.1676269531250002 +0.269125 -0.068817138671875 -0.1676269531250002 +0.26925 -0.069305419921875 -0.1676269531250002 +0.2693750000000001 -0.069305419921875 -0.1676269531250002 +0.2695 -0.069793701171875 -0.1676269531250002 +0.269625 -0.069793701171875 -0.1676269531250002 +0.26975 -0.070281982421875 -0.1676269531250002 +0.269875 -0.07073974609375 -0.1676269531250002 +0.27 -0.07073974609375 -0.1676269531250002 +0.270125 -0.07122802734375 -0.1676269531250002 +0.27025 -0.07122802734375 -0.1676269531250002 +0.270375 -0.071685791015625 -0.1676269531250002 +0.2705 -0.072113037109375 -0.1676269531250002 +0.270625 -0.072113037109375 -0.1676269531250002 +0.27075 -0.07257080078125 -0.1676269531250002 +0.270875 -0.07257080078125 -0.1676269531250002 +0.271 -0.072998046875 -0.1676269531250002 +0.271125 -0.07342529296875 -0.1676269531250002 +0.27125 -0.07342529296875 -0.1676269531250002 +0.271375 -0.0738525390625 -0.1676269531250002 +0.2715 -0.0738525390625 -0.1676269531250002 +0.271625 -0.074249267578125 -0.1676269531250002 +0.27175 -0.074676513671875 -0.1676269531250002 +0.271875 -0.074676513671875 -0.1676269531250002 +0.272 -0.075042724609375 -0.1676269531250002 +0.272125 -0.075042724609375 -0.1676269531250002 +0.27225 -0.075439453125 -0.1676269531250002 +0.272375 -0.0758056640625 -0.1676269531250002 +0.2725 -0.0758056640625 -0.1676269531250002 +0.272625 -0.076202392578125 -0.1676269531250002 +0.27275 -0.076202392578125 -0.1676269531250002 +0.272875 -0.0765380859375 -0.1676269531250002 +0.273 -0.076904296875 -0.1676269531250002 +0.273125 -0.076904296875 -0.1676269531250002 +0.27325 -0.077239990234375 -0.1676269531250002 +0.273375 -0.077239990234375 -0.1676269531250002 +0.2735 -0.07757568359375 -0.1676269531250002 +0.273625 -0.077911376953125 -0.1676269531250002 +0.27375 -0.077911376953125 -0.1676269531250002 +0.273875 -0.078216552734375 -0.1676269531250002 +0.274 -0.078216552734375 -0.1676269531250002 +0.274125 -0.07855224609375 -0.1676269531250002 +0.27425 -0.078826904296875 -0.1676269531250002 +0.274375 -0.078826904296875 -0.1676269531250002 +0.2745 -0.079132080078125 -0.1676269531250002 +0.274625 -0.079132080078125 -0.1676269531250002 +0.27475 -0.07940673828125 -0.1676269531250002 +0.274875 -0.079681396484375 -0.1676269531250002 +0.275 -0.079681396484375 -0.1676269531250002 +0.275125 -0.0799560546875 -0.1676269531250002 +0.27525 -0.0799560546875 -0.1676269531250002 +0.275375 -0.080230712890625 -0.1676269531250002 +0.2755 -0.080474853515625 -0.1676269531250002 +0.275625 -0.080474853515625 -0.1676269531250002 +0.27575 -0.080718994140625 -0.1676269531250002 +0.275875 -0.080718994140625 -0.1676269531250002 +0.276 -0.0809326171875 -0.1676269531250002 +0.276125 -0.0811767578125 -0.1676269531250002 +0.27625 -0.0811767578125 -0.1676269531250002 +0.276375 -0.081390380859375 -0.1676269531250002 +0.2765 -0.081390380859375 -0.1676269531250002 +0.276625 -0.081573486328125 -0.1676269531250002 +0.27675 -0.081787109375 -0.1676269531250002 +0.276875 -0.081787109375 -0.1676269531250002 +0.277 -0.08197021484375 -0.1676269531250002 +0.277125 -0.08197021484375 -0.1676269531250002 +0.27725 -0.0821533203125 -0.1676269531250002 +0.277375 -0.082305908203125 -0.1676269531250002 +0.2775 -0.082305908203125 -0.1676269531250002 +0.277625 -0.08245849609375 -0.1676269531250002 +0.27775 -0.08245849609375 -0.1676269531250002 +0.277875 -0.082611083984375 -0.1676269531250002 +0.278 -0.082763671875 -0.1676269531250002 +0.278125 -0.082763671875 -0.1676269531250002 +0.27825 -0.0828857421875 -0.1676269531250002 +0.278375 -0.0828857421875 -0.1676269531250002 +0.2785 -0.0830078125 -0.1676269531250002 +0.278625 -0.0831298828125 -0.1676269531250002 +0.27875 -0.0831298828125 -0.1676269531250002 +0.278875 -0.083251953125 -0.1676269531250002 +0.279 -0.083251953125 -0.1676269531250002 +0.279125 -0.083343505859375 -0.1676269531250002 +0.27925 -0.08343505859375 -0.1676269531250002 +0.279375 -0.08343505859375 -0.1676269531250002 +0.2795 -0.08349609375 -0.1676269531250002 +0.279625 -0.08349609375 -0.1676269531250002 +0.27975 -0.083587646484375 -0.1676269531250002 +0.279875 -0.0836181640625 -0.1676269531250002 +0.28 -0.0836181640625 -0.1676269531250002 +0.280125 -0.08367919921875 -0.1676269531250002 +0.28025 -0.08367919921875 -0.1676269531250002 +0.280375 -0.083709716796875 -0.1676269531250002 +0.2805 -0.083740234375 -0.1676269531250002 +0.280625 -0.083740234375 -0.1676269531250002 +0.28075 -0.083770751953125 -0.1676269531250002 +0.280875 -0.083770751953125 -0.1676269531250002 +0.281 -0.08380126953125 -0.1676269531250002 +0.281125 -0.08380126953125 -0.1676269531250002 +0.28125 -0.08380126953125 -0.1676269531250002 +0.281375 -0.08380126953125 -0.1676269531250002 +0.2815 -0.08380126953125 -0.1676269531250002 +0.281625 -0.083770751953125 -0.1676269531250002 +0.28175 -0.083740234375 -0.1676269531250002 +0.281875 -0.083740234375 -0.1676269531250002 +0.282 -0.083709716796875 -0.1676269531250002 +0.282125 -0.083709716796875 -0.1676269531250002 +0.28225 -0.08367919921875 -0.1676269531250002 +0.282375 -0.0836181640625 -0.1676269531250002 +0.2825 -0.0836181640625 -0.1676269531250002 +0.282625 -0.083587646484375 -0.1676269531250002 +0.28275 -0.083587646484375 -0.1676269531250002 +0.282875 -0.08349609375 -0.1676269531250002 +0.283 -0.08343505859375 -0.1676269531250002 +0.283125 -0.08343505859375 -0.1676269531250002 +0.28325 -0.083343505859375 -0.1676269531250002 +0.283375 -0.083343505859375 -0.1676269531250002 +0.2835 -0.083251953125 -0.1676269531250002 +0.283625 -0.0831298828125 -0.1676269531250002 +0.28375 -0.0831298828125 -0.1676269531250002 +0.283875 -0.0830078125 -0.1676269531250002 +0.284 -0.0830078125 -0.1676269531250002 +0.284125 -0.0828857421875 -0.1676269531250002 +0.28425 -0.082763671875 -0.1676269531250002 +0.284375 -0.082763671875 -0.1676269531250002 +0.2845 -0.082611083984375 -0.1676269531250002 +0.284625 -0.082611083984375 -0.1676269531250002 +0.28475 -0.08245849609375 -0.1676269531250002 +0.284875 -0.082305908203125 -0.1676269531250002 +0.2850000000000001 -0.082305908203125 -0.1676269531250002 +0.285125 -0.0821533203125 -0.1676269531250002 +0.28525 -0.0821533203125 -0.1676269531250002 +0.285375 -0.08197021484375 -0.1676269531250002 +0.2855 -0.081787109375 -0.1676269531250002 +0.285625 -0.081787109375 -0.1676269531250002 +0.28575 -0.081573486328125 -0.1676269531250002 +0.285875 -0.081573486328125 -0.1676269531250002 +0.286 -0.081390380859375 -0.1676269531250002 +0.286125 -0.0811767578125 -0.1676269531250002 +0.28625 -0.0811767578125 -0.1676269531250002 +0.286375 -0.0809326171875 -0.1676269531250002 +0.2865 -0.0809326171875 -0.1676269531250002 +0.286625 -0.080718994140625 -0.1676269531250002 +0.28675 -0.080474853515625 -0.1676269531250002 +0.286875 -0.080474853515625 -0.1676269531250002 +0.287 -0.080230712890625 -0.1676269531250002 +0.287125 -0.080230712890625 -0.1676269531250002 +0.28725 -0.0799560546875 -0.1676269531250002 +0.287375 -0.079681396484375 -0.1676269531250002 +0.2875 -0.079681396484375 -0.1676269531250002 +0.287625 -0.07940673828125 -0.1676269531250002 +0.28775 -0.07940673828125 -0.1676269531250002 +0.287875 -0.079132080078125 -0.1676269531250002 +0.288 -0.19586181640625 -0.4163818359375004 +0.288125 -0.19586181640625 -0.4163818359375004 +0.28825 -0.195098876953125 -0.4163818359375004 +0.288375 -0.195098876953125 -0.4163818359375004 +0.2885 -0.1943359375 -0.4163818359375004 +0.288625 -0.19354248046875 -0.4163818359375004 +0.28875 -0.19354248046875 -0.4163818359375004 +0.288875 -0.1927490234375 -0.4163818359375004 +0.289 -0.1927490234375 -0.4163818359375004 +0.289125 -0.19189453125 -0.4163818359375004 +0.28925 -0.1910400390625 -0.4163818359375004 +0.289375 -0.1910400390625 -0.4163818359375004 +0.2895 -0.190155029296875 -0.4163818359375004 +0.289625 -0.190155029296875 -0.4163818359375004 +0.28975 -0.18927001953125 -0.4163818359375004 +0.289875 -0.1883544921875 -0.4163818359375004 +0.29 -0.1883544921875 -0.4163818359375004 +0.290125 -0.187408447265625 -0.4163818359375004 +0.29025 -0.187408447265625 -0.4163818359375004 +0.290375 -0.18646240234375 -0.4163818359375004 +0.2905 -0.18548583984375 -0.4163818359375004 +0.290625 -0.18548583984375 -0.4163818359375004 +0.29075 -0.184478759765625 -0.4163818359375004 +0.290875 -0.184478759765625 -0.4163818359375004 +0.291 -0.183441162109375 -0.4163818359375004 +0.291125 -0.182403564453125 -0.4163818359375004 +0.29125 -0.182403564453125 -0.4163818359375004 +0.291375 -0.181365966796875 -0.4163818359375004 +0.2915 -0.181365966796875 -0.4163818359375004 +0.291625 -0.180267333984375 -0.4163818359375004 +0.29175 -0.179168701171875 -0.4163818359375004 +0.291875 -0.179168701171875 -0.4163818359375004 +0.292 -0.17803955078125 -0.4163818359375004 +0.292125 -0.17803955078125 -0.4163818359375004 +0.29225 -0.176910400390625 -0.4163818359375004 +0.292375 -0.175750732421875 -0.4163818359375004 +0.2925 -0.175750732421875 -0.4163818359375004 +0.292625 -0.174591064453125 -0.4163818359375004 +0.29275 -0.174591064453125 -0.4163818359375004 +0.292875 -0.173370361328125 -0.4163818359375004 +0.293 -0.172149658203125 -0.4163818359375004 +0.293125 -0.172149658203125 -0.4163818359375004 +0.29325 -0.170928955078125 -0.4163818359375004 +0.293375 -0.170928955078125 -0.4163818359375004 +0.2935 -0.169677734375 -0.4163818359375004 +0.293625 -0.16839599609375 -0.4163818359375004 +0.29375 -0.16839599609375 -0.4163818359375004 +0.293875 -0.1671142578125 -0.4163818359375004 +0.294 -0.1671142578125 -0.4163818359375004 +0.294125 -0.165802001953125 -0.4163818359375004 +0.29425 -0.16448974609375 -0.4163818359375004 +0.294375 -0.16448974609375 -0.4163818359375004 +0.2945 -0.16314697265625 -0.4163818359375004 +0.294625 -0.16314697265625 -0.4163818359375004 +0.29475 -0.161773681640625 -0.4163818359375004 +0.294875 -0.160400390625 -0.4163818359375004 +0.295 -0.160400390625 -0.4163818359375004 +0.295125 -0.15899658203125 -0.4163818359375004 +0.29525 -0.15899658203125 -0.4163818359375004 +0.295375 -0.157562255859375 -0.4163818359375004 +0.2955 -0.1561279296875 -0.4163818359375004 +0.295625 -0.1561279296875 -0.4163818359375004 +0.29575 -0.154693603515625 -0.4163818359375004 +0.295875 -0.154693603515625 -0.4163818359375004 +0.296 -0.153228759765625 -0.4163818359375004 +0.296125 -0.1517333984375 -0.4163818359375004 +0.29625 -0.1517333984375 -0.4163818359375004 +0.296375 -0.150238037109375 -0.4163818359375004 +0.2965 -0.150238037109375 -0.4163818359375004 +0.296625 -0.148712158203125 -0.4163818359375004 +0.29675 -0.147186279296875 -0.4163818359375004 +0.296875 -0.147186279296875 -0.4163818359375004 +0.297 -0.1456298828125 -0.4163818359375004 +0.297125 -0.1456298828125 -0.4163818359375004 +0.29725 -0.144073486328125 -0.4163818359375004 +0.297375 -0.142486572265625 -0.4163818359375004 +0.2975 -0.142486572265625 -0.4163818359375004 +0.297625 -0.140899658203125 -0.4163818359375004 +0.29775 -0.140899658203125 -0.4163818359375004 +0.297875 -0.1392822265625 -0.4163818359375004 +0.298 -0.137664794921875 -0.4163818359375004 +0.298125 -0.137664794921875 -0.4163818359375004 +0.29825 -0.136016845703125 -0.4163818359375004 +0.298375 -0.136016845703125 -0.4163818359375004 +0.2985 -0.134368896484375 -0.4163818359375004 +0.298625 -0.1326904296875 -0.4163818359375004 +0.29875 -0.1326904296875 -0.4163818359375004 +0.298875 -0.1309814453125 -0.4163818359375004 +0.299 -0.1309814453125 -0.4163818359375004 +0.299125 -0.129302978515625 -0.4163818359375004 +0.29925 -0.127593994140625 -0.4163818359375004 +0.299375 -0.127593994140625 -0.4163818359375004 +0.2995 -0.1258544921875 -0.4163818359375004 +0.299625 -0.1258544921875 -0.4163818359375004 +0.29975 -0.124114990234375 -0.4163818359375004 +0.299875 -0.122344970703125 -0.4163818359375004 +0.3 -0.122344970703125 -0.4163818359375004 +0.300125 -0.120574951171875 -0.4163818359375004 +0.30025 -0.120574951171875 -0.4163818359375004 +0.300375 -0.118804931640625 -0.4163818359375004 +0.3005 -0.11700439453125 -0.4163818359375004 +0.3006250000000001 -0.11700439453125 -0.4163818359375004 +0.30075 -0.11517333984375 -0.4163818359375004 +0.300875 -0.11517333984375 -0.4163818359375004 +0.301 -0.113372802734375 -0.4163818359375004 +0.301125 -0.111541748046875 -0.4163818359375004 +0.30125 -0.111541748046875 -0.4163818359375004 +0.301375 -0.10968017578125 -0.4163818359375004 +0.3015 -0.10968017578125 -0.4163818359375004 +0.301625 -0.107818603515625 -0.4163818359375004 +0.30175 -0.10595703125 -0.4163818359375004 +0.301875 -0.10595703125 -0.4163818359375004 +0.302 -0.10406494140625 -0.4163818359375004 +0.302125 -0.10406494140625 -0.4163818359375004 +0.30225 -0.1021728515625 -0.4163818359375004 +0.302375 -0.10028076171875 -0.4163818359375004 +0.3025 -0.10028076171875 -0.4163818359375004 +0.302625 -0.098358154296875 -0.4163818359375004 +0.30275 -0.098358154296875 -0.4163818359375004 +0.302875 -0.096435546875 -0.4163818359375004 +0.303 -0.094482421875 -0.4163818359375004 +0.303125 -0.094482421875 -0.4163818359375004 +0.30325 -0.092559814453125 -0.4163818359375004 +0.303375 -0.092559814453125 -0.4163818359375004 +0.3035 -0.090606689453125 -0.4163818359375004 +0.303625 -0.088623046875 -0.4163818359375004 +0.30375 -0.088623046875 -0.4163818359375004 +0.303875 -0.086639404296875 -0.4163818359375004 +0.304 -0.086639404296875 -0.4163818359375004 +0.304125 -0.08465576171875 -0.4163818359375004 +0.30425 -0.082672119140625 -0.4163818359375004 +0.304375 -0.082672119140625 -0.4163818359375004 +0.3045 -0.080657958984375 -0.4163818359375004 +0.304625 -0.080657958984375 -0.4163818359375004 +0.30475 -0.078643798828125 -0.4163818359375004 +0.304875 -0.076629638671875 -0.4163818359375004 +0.305 -0.076629638671875 -0.4163818359375004 +0.305125 -0.0745849609375 -0.4163818359375004 +0.30525 -0.0745849609375 -0.4163818359375004 +0.305375 -0.072540283203125 -0.4163818359375004 +0.3055 -0.07049560546875 -0.4163818359375004 +0.305625 -0.07049560546875 -0.4163818359375004 +0.30575 -0.068450927734375 -0.4163818359375004 +0.305875 -0.068450927734375 -0.4163818359375004 +0.306 -0.066375732421875 -0.4163818359375004 +0.306125 -0.064300537109375 -0.4163818359375004 +0.30625 -0.064300537109375 -0.4163818359375004 +0.306375 -0.062225341796875 -0.4163818359375004 +0.3065 -0.062225341796875 -0.4163818359375004 +0.306625 -0.060150146484375 -0.4163818359375004 +0.30675 -0.058074951171875 -0.4163818359375004 +0.306875 -0.058074951171875 -0.4163818359375004 +0.307 -0.05596923828125 -0.4163818359375004 +0.307125 -0.05596923828125 -0.4163818359375004 +0.30725 -0.053863525390625 -0.4163818359375004 +0.307375 -0.0517578125 -0.4163818359375004 +0.3075 -0.0517578125 -0.4163818359375004 +0.307625 -0.049652099609375 -0.4163818359375004 +0.30775 -0.049652099609375 -0.4163818359375004 +0.307875 -0.047515869140625 -0.4163818359375004 +0.308 -0.045379638671875 -0.4163818359375004 +0.308125 -0.045379638671875 -0.4163818359375004 +0.30825 -0.04327392578125 -0.4163818359375004 +0.308375 -0.04327392578125 -0.4163818359375004 +0.3085 -0.0411376953125 -0.4163818359375004 +0.308625 -0.03900146484375 -0.4163818359375004 +0.30875 -0.03900146484375 -0.4163818359375004 +0.308875 -0.036834716796875 -0.4163818359375004 +0.309 -0.036834716796875 -0.4163818359375004 +0.309125 -0.034698486328125 -0.4163818359375004 +0.30925 -0.03253173828125 -0.4163818359375004 +0.309375 -0.03253173828125 -0.4163818359375004 +0.3095 -0.0303955078125 -0.4163818359375004 +0.309625 -0.0303955078125 -0.4163818359375004 +0.30975 -0.028228759765625 -0.4163818359375004 +0.309875 -0.02606201171875 -0.4163818359375004 +0.31 -0.02606201171875 -0.4163818359375004 +0.310125 -0.02392578125 -0.4163818359375004 +0.31025 -0.02392578125 -0.4163818359375004 +0.310375 -0.021759033203125 -0.4163818359375004 +0.3105 -0.019561767578125 -0.4163818359375004 +0.310625 -0.019561767578125 -0.4163818359375004 +0.31075 -0.01739501953125 -0.4163818359375004 +0.310875 -0.01739501953125 -0.4163818359375004 +0.311 -0.015228271484375 -0.4163818359375004 +0.311125 -0.0130615234375 -0.4163818359375004 +0.31125 -0.0130615234375 -0.4163818359375004 +0.311375 -0.0108642578125 -0.4163818359375004 +0.3115 -0.0108642578125 -0.4163818359375004 +0.311625 -0.008697509765625 -0.4163818359375004 +0.31175 -0.00653076171875 -0.4163818359375004 +0.311875 -0.00653076171875 -0.4163818359375004 +0.312 -0.00433349609375 -0.4163818359375004 +0.312125 -0.00433349609375 -0.4163818359375004 +0.31225 -0.002166748046875 -0.4163818359375004 0.312375 0.0 -0.4163818359375004 0.3125 0.0 -0.4163818359375004 0.312625 0.002166748046875 -0.4163818359375004 @@ -2999,504 +2999,504 @@ 0.37475 0.00311279296875 -0.5948388671875 0.374875 0.0 -0.5948388671875 0.375 0.0 -0.5948388671875 -0.375125 -0.003143310546875 -0.5948388671875 -0.37525 -0.003143310546875 -0.5948388671875 -0.375375 -0.006256103515625 -0.5948388671875 -0.3755 -0.009368896484375 -0.5948388671875 -0.375625 -0.009368896484375 -0.5948388671875 -0.37575 -0.012481689453125 -0.5948388671875 -0.375875 -0.012481689453125 -0.5948388671875 -0.376 -0.01556396484375 -0.5948388671875 -0.376125 -0.0186767578125 -0.5948388671875 -0.37625 -0.0186767578125 -0.5948388671875 -0.376375 -0.02178955078125 -0.5948388671875 -0.3765 -0.02178955078125 -0.5948388671875 -0.376625 -0.02490234375 -0.5948388671875 -0.37675 -0.027984619140625 -0.5948388671875 -0.376875 -0.027984619140625 -0.5948388671875 -0.377 -0.031097412109375 -0.5948388671875 -0.377125 -0.031097412109375 -0.5948388671875 -0.37725 -0.034210205078125 -0.5948388671875 -0.377375 -0.03729248046875 -0.5948388671875 -0.3775 -0.03729248046875 -0.5948388671875 -0.377625 -0.040374755859375 -0.5948388671875 -0.37775 -0.040374755859375 -0.5948388671875 -0.377875 -0.04345703125 -0.5948388671875 -0.378 -0.046539306640625 -0.5948388671875 -0.378125 -0.046539306640625 -0.5948388671875 -0.37825 -0.04962158203125 -0.5948388671875 -0.378375 -0.04962158203125 -0.5948388671875 -0.3785 -0.05267333984375 -0.5948388671875 -0.378625 -0.05572509765625 -0.5948388671875 -0.3787500000000001 -0.05572509765625 -0.5948388671875 -0.378875 -0.058807373046875 -0.5948388671875 -0.379 -0.058807373046875 -0.5948388671875 -0.379125 -0.061859130859375 -0.5948388671875 -0.37925 -0.06488037109375 -0.5948388671875 -0.379375 -0.06488037109375 -0.5948388671875 -0.3795 -0.06793212890625 -0.5948388671875 -0.379625 -0.06793212890625 -0.5948388671875 -0.37975 -0.070953369140625 -0.5948388671875 -0.379875 -0.073974609375 -0.5948388671875 -0.38 -0.073974609375 -0.5948388671875 -0.380125 -0.076995849609375 -0.5948388671875 -0.38025 -0.076995849609375 -0.5948388671875 -0.380375 -0.079986572265625 -0.5948388671875 -0.3805 -0.082977294921875 -0.5948388671875 -0.380625 -0.082977294921875 -0.5948388671875 -0.38075 -0.085968017578125 -0.5948388671875 -0.380875 -0.085968017578125 -0.5948388671875 -0.381 -0.088958740234375 -0.5948388671875 -0.381125 -0.0919189453125 -0.5948388671875 -0.38125 -0.0919189453125 -0.5948388671875 -0.381375 -0.094879150390625 -0.5948388671875 -0.3815 -0.094879150390625 -0.5948388671875 -0.381625 -0.097808837890625 -0.5948388671875 -0.38175 -0.10076904296875 -0.5948388671875 -0.381875 -0.10076904296875 -0.5948388671875 -0.382 -0.103668212890625 -0.5948388671875 -0.382125 -0.103668212890625 -0.5948388671875 -0.38225 -0.106597900390625 -0.5948388671875 -0.382375 -0.1094970703125 -0.5948388671875 -0.3825 -0.1094970703125 -0.5948388671875 -0.382625 -0.112396240234375 -0.5948388671875 -0.3827500000000001 -0.112396240234375 -0.5948388671875 -0.382875 -0.115264892578125 -0.5948388671875 -0.383 -0.118133544921875 -0.5948388671875 -0.383125 -0.118133544921875 -0.5948388671875 -0.38325 -0.1209716796875 -0.5948388671875 -0.383375 -0.1209716796875 -0.5948388671875 -0.3835 -0.123809814453125 -0.5948388671875 -0.383625 -0.12664794921875 -0.5948388671875 -0.38375 -0.12664794921875 -0.5948388671875 -0.383875 -0.12945556640625 -0.5948388671875 -0.384 -0.10797119140625 -0.4961181640624994 -0.384125 -0.110321044921875 -0.4961181640624994 -0.38425 -0.11260986328125 -0.4961181640624994 -0.384375 -0.11260986328125 -0.4961181640624994 -0.3845 -0.11492919921875 -0.4961181640624994 -0.384625 -0.11492919921875 -0.4961181640624994 -0.38475 -0.117218017578125 -0.4961181640624994 -0.384875 -0.1195068359375 -0.4961181640624994 -0.385 -0.1195068359375 -0.4961181640624994 -0.385125 -0.121795654296875 -0.4961181640624994 -0.38525 -0.121795654296875 -0.4961181640624994 -0.385375 -0.124053955078125 -0.4961181640624994 -0.3855 -0.12628173828125 -0.4961181640624994 -0.385625 -0.12628173828125 -0.4961181640624994 -0.38575 -0.128509521484375 -0.4961181640624994 -0.385875 -0.128509521484375 -0.4961181640624994 -0.386 -0.1307373046875 -0.4961181640624994 -0.386125 -0.1329345703125 -0.4961181640624994 -0.38625 -0.1329345703125 -0.4961181640624994 -0.386375 -0.135101318359375 -0.4961181640624994 -0.3865 -0.135101318359375 -0.4961181640624994 -0.386625 -0.13726806640625 -0.4961181640624994 -0.38675 -0.139434814453125 -0.4961181640624994 -0.386875 -0.139434814453125 -0.4961181640624994 -0.387 -0.141571044921875 -0.4961181640624994 -0.387125 -0.141571044921875 -0.4961181640624994 -0.38725 -0.143707275390625 -0.4961181640624994 -0.387375 -0.14581298828125 -0.4961181640624994 -0.3875 -0.14581298828125 -0.4961181640624994 -0.387625 -0.147918701171875 -0.4961181640624994 -0.38775 -0.147918701171875 -0.4961181640624994 -0.387875 -0.149993896484375 -0.4961181640624994 -0.388 -0.15203857421875 -0.4961181640624994 -0.388125 -0.15203857421875 -0.4961181640624994 -0.38825 -0.154083251953125 -0.4961181640624994 -0.388375 -0.154083251953125 -0.4961181640624994 -0.3885 -0.1561279296875 -0.4961181640624994 -0.388625 -0.15814208984375 -0.4961181640624994 -0.38875 -0.15814208984375 -0.4961181640624994 -0.388875 -0.160125732421875 -0.4961181640624994 -0.389 -0.160125732421875 -0.4961181640624994 -0.389125 -0.162109375 -0.4961181640624994 -0.38925 -0.1640625 -0.4961181640624994 -0.389375 -0.1640625 -0.4961181640624994 -0.3895 -0.165985107421875 -0.4961181640624994 -0.389625 -0.165985107421875 -0.4961181640624994 -0.38975 -0.16790771484375 -0.4961181640624994 -0.389875 -0.169830322265625 -0.4961181640624994 -0.39 -0.169830322265625 -0.4961181640624994 -0.390125 -0.17169189453125 -0.4961181640624994 -0.39025 -0.17169189453125 -0.4961181640624994 -0.390375 -0.173553466796875 -0.4961181640624994 -0.3905 -0.1754150390625 -0.4961181640624994 -0.390625 -0.1754150390625 -0.4961181640624994 -0.39075 -0.17724609375 -0.4961181640624994 -0.390875 -0.17724609375 -0.4961181640624994 -0.391 -0.179046630859375 -0.4961181640624994 -0.391125 -0.18084716796875 -0.4961181640624994 -0.39125 -0.18084716796875 -0.4961181640624994 -0.391375 -0.1826171875 -0.4961181640624994 -0.3915 -0.1826171875 -0.4961181640624994 -0.391625 -0.184356689453125 -0.4961181640624994 -0.39175 -0.186065673828125 -0.4961181640624994 -0.391875 -0.186065673828125 -0.4961181640624994 -0.392 -0.187774658203125 -0.4961181640624994 -0.392125 -0.187774658203125 -0.4961181640624994 -0.39225 -0.189483642578125 -0.4961181640624994 -0.392375 -0.191131591796875 -0.4961181640624994 -0.3925 -0.191131591796875 -0.4961181640624994 -0.392625 -0.192779541015625 -0.4961181640624994 -0.39275 -0.192779541015625 -0.4961181640624994 -0.392875 -0.19439697265625 -0.4961181640624994 -0.393 -0.196014404296875 -0.4961181640624994 -0.393125 -0.196014404296875 -0.4961181640624994 -0.39325 -0.197601318359375 -0.4961181640624994 -0.393375 -0.197601318359375 -0.4961181640624994 -0.3935 -0.19915771484375 -0.4961181640624994 -0.393625 -0.20068359375 -0.4961181640624994 -0.39375 -0.20068359375 -0.4961181640624994 -0.393875 -0.20220947265625 -0.4961181640624994 -0.394 -0.20220947265625 -0.4961181640624994 -0.394125 -0.203704833984375 -0.4961181640624994 -0.39425 -0.205169677734375 -0.4961181640624994 -0.3943750000000001 -0.205169677734375 -0.4961181640624994 -0.3945 -0.206634521484375 -0.4961181640624994 -0.394625 -0.206634521484375 -0.4961181640624994 -0.39475 -0.208038330078125 -0.4961181640624994 -0.394875 -0.209442138671875 -0.4961181640624994 -0.395 -0.209442138671875 -0.4961181640624994 -0.395125 -0.210845947265625 -0.4961181640624994 -0.39525 -0.210845947265625 -0.4961181640624994 -0.395375 -0.212188720703125 -0.4961181640624994 -0.3955 -0.213531494140625 -0.4961181640624994 -0.395625 -0.213531494140625 -0.4961181640624994 -0.39575 -0.21484375 -0.4961181640624994 -0.395875 -0.21484375 -0.4961181640624994 -0.396 -0.21612548828125 -0.4961181640624994 -0.396125 -0.217376708984375 -0.4961181640624994 -0.39625 -0.217376708984375 -0.4961181640624994 -0.396375 -0.2186279296875 -0.4961181640624994 -0.3965 -0.2186279296875 -0.4961181640624994 -0.396625 -0.2198486328125 -0.4961181640624994 -0.39675 -0.221038818359375 -0.4961181640624994 -0.396875 -0.221038818359375 -0.4961181640624994 -0.397 -0.222198486328125 -0.4961181640624994 -0.397125 -0.222198486328125 -0.4961181640624994 -0.39725 -0.22332763671875 -0.4961181640624994 -0.397375 -0.224456787109375 -0.4961181640624994 -0.3975 -0.224456787109375 -0.4961181640624994 -0.397625 -0.225555419921875 -0.4961181640624994 -0.39775 -0.225555419921875 -0.4961181640624994 -0.397875 -0.22662353515625 -0.4961181640624994 -0.398 -0.2276611328125 -0.4961181640624994 -0.398125 -0.2276611328125 -0.4961181640624994 -0.39825 -0.228668212890625 -0.4961181640624994 -0.3983750000000001 -0.228668212890625 -0.4961181640624994 -0.3985 -0.22967529296875 -0.4961181640624994 -0.398625 -0.23065185546875 -0.4961181640624994 -0.39875 -0.23065185546875 -0.4961181640624994 -0.398875 -0.231597900390625 -0.4961181640624994 -0.399 -0.231597900390625 -0.4961181640624994 -0.399125 -0.232513427734375 -0.4961181640624994 -0.39925 -0.2333984375 -0.4961181640624994 -0.399375 -0.2333984375 -0.4961181640624994 -0.3995 -0.234283447265625 -0.4961181640624994 -0.399625 -0.234283447265625 -0.4961181640624994 -0.39975 -0.235107421875 -0.4961181640624994 -0.399875 -0.235931396484375 -0.4961181640624994 -0.4 -0.235931396484375 -0.4961181640624994 -0.400125 -0.236724853515625 -0.4961181640624994 -0.40025 -0.236724853515625 -0.4961181640624994 -0.400375 -0.23748779296875 -0.4961181640624994 -0.4005 -0.23822021484375 -0.4961181640624994 -0.400625 -0.23822021484375 -0.4961181640624994 -0.40075 -0.238922119140625 -0.4961181640624994 -0.400875 -0.238922119140625 -0.4961181640624994 -0.401 -0.2396240234375 -0.4961181640624994 -0.401125 -0.240264892578125 -0.4961181640624994 -0.40125 -0.240264892578125 -0.4961181640624994 -0.401375 -0.24090576171875 -0.4961181640624994 -0.4015000000000001 -0.24090576171875 -0.4961181640624994 -0.401625 -0.24151611328125 -0.4961181640624994 -0.40175 -0.242095947265625 -0.4961181640624994 -0.401875 -0.242095947265625 -0.4961181640624994 -0.402 -0.242645263671875 -0.4961181640624994 -0.402125 -0.242645263671875 -0.4961181640624994 -0.40225 -0.2431640625 -0.4961181640624994 -0.402375 -0.243682861328125 -0.4961181640624994 -0.4025 -0.243682861328125 -0.4961181640624994 -0.402625 -0.244140625 -0.4961181640624994 -0.40275 -0.244140625 -0.4961181640624994 -0.402875 -0.244598388671875 -0.4961181640624994 -0.403 -0.245025634765625 -0.4961181640624994 -0.403125 -0.245025634765625 -0.4961181640624994 -0.40325 -0.245391845703125 -0.4961181640624994 -0.403375 -0.245391845703125 -0.4961181640624994 -0.4035 -0.245758056640625 -0.4961181640624994 -0.403625 -0.246124267578125 -0.4961181640624994 -0.40375 -0.246124267578125 -0.4961181640624994 -0.403875 -0.246429443359375 -0.4961181640624994 -0.404 -0.246429443359375 -0.4961181640624994 -0.404125 -0.2467041015625 -0.4961181640624994 -0.40425 -0.246978759765625 -0.4961181640624994 -0.404375 -0.246978759765625 -0.4961181640624994 -0.4045 -0.2471923828125 -0.4961181640624994 -0.4046250000000001 -0.2471923828125 -0.4961181640624994 -0.40475 -0.247406005859375 -0.4961181640624994 -0.404875 -0.247589111328125 -0.4961181640624994 -0.4050000000000001 -0.247589111328125 -0.4961181640624994 -0.405125 -0.24774169921875 -0.4961181640624994 -0.40525 -0.24774169921875 -0.4961181640624994 -0.405375 -0.24786376953125 -0.4961181640624994 -0.4055000000000001 -0.247955322265625 -0.4961181640624994 -0.405625 -0.247955322265625 -0.4961181640624994 -0.40575 -0.248016357421875 -0.4961181640624994 -0.405875 -0.248016357421875 -0.4961181640624994 -0.406 -0.248046875 -0.4961181640624994 -0.406125 -0.248077392578125 -0.4961181640624994 -0.40625 -0.248077392578125 -0.4961181640624994 -0.406375 -0.248046875 -0.4961181640624994 -0.4065 -0.248046875 -0.4961181640624994 -0.406625 -0.248016357421875 -0.4961181640624994 -0.40675 -0.247955322265625 -0.4961181640624994 -0.406875 -0.247955322265625 -0.4961181640624994 -0.407 -0.24786376953125 -0.4961181640624994 -0.407125 -0.24786376953125 -0.4961181640624994 -0.40725 -0.24774169921875 -0.4961181640624994 -0.407375 -0.247589111328125 -0.4961181640624994 -0.4075 -0.247589111328125 -0.4961181640624994 -0.407625 -0.247406005859375 -0.4961181640624994 -0.40775 -0.247406005859375 -0.4961181640624994 -0.4078749999999999 -0.2471923828125 -0.4961181640624994 -0.408 -0.246978759765625 -0.4961181640624994 -0.408125 -0.246978759765625 -0.4961181640624994 -0.40825 -0.2467041015625 -0.4961181640624994 -0.408375 -0.2467041015625 -0.4961181640624994 -0.4085 -0.246429443359375 -0.4961181640624994 -0.408625 -0.246124267578125 -0.4961181640624994 -0.40875 -0.246124267578125 -0.4961181640624994 -0.408875 -0.245758056640625 -0.4961181640624994 -0.409 -0.245758056640625 -0.4961181640624994 -0.409125 -0.245391845703125 -0.4961181640624994 -0.40925 -0.245025634765625 -0.4961181640624994 -0.409375 -0.245025634765625 -0.4961181640624994 -0.4095000000000001 -0.244598388671875 -0.4961181640624994 -0.409625 -0.244598388671875 -0.4961181640624994 -0.40975 -0.244140625 -0.4961181640624994 -0.409875 -0.243682861328125 -0.4961181640624994 -0.4100000000000001 -0.243682861328125 -0.4961181640624994 -0.410125 -0.2431640625 -0.4961181640624994 -0.41025 -0.2431640625 -0.4961181640624994 -0.410375 -0.242645263671875 -0.4961181640624994 -0.4105 -0.242095947265625 -0.4961181640624994 -0.410625 -0.242095947265625 -0.4961181640624994 -0.41075 -0.24151611328125 -0.4961181640624994 -0.410875 -0.24151611328125 -0.4961181640624994 -0.411 -0.24090576171875 -0.4961181640624994 -0.411125 -0.240264892578125 -0.4961181640624994 -0.41125 -0.240264892578125 -0.4961181640624994 -0.411375 -0.2396240234375 -0.4961181640624994 -0.4115 -0.2396240234375 -0.4961181640624994 -0.411625 -0.238922119140625 -0.4961181640624994 -0.41175 -0.23822021484375 -0.4961181640624994 -0.411875 -0.23822021484375 -0.4961181640624994 -0.412 -0.23748779296875 -0.4961181640624994 -0.412125 -0.23748779296875 -0.4961181640624994 -0.41225 -0.236724853515625 -0.4961181640624994 -0.412375 -0.235931396484375 -0.4961181640624994 -0.4125 -0.235931396484375 -0.4961181640624994 -0.4126250000000001 -0.235107421875 -0.4961181640624994 -0.41275 -0.235107421875 -0.4961181640624994 -0.412875 -0.234283447265625 -0.4961181640624994 -0.4130000000000001 -0.2333984375 -0.4961181640624994 -0.4131250000000001 -0.2333984375 -0.4961181640624994 -0.41325 -0.232513427734375 -0.4961181640624994 -0.413375 -0.232513427734375 -0.4961181640624994 -0.4135000000000001 -0.231597900390625 -0.4961181640624994 -0.413625 -0.23065185546875 -0.4961181640624994 -0.41375 -0.23065185546875 -0.4961181640624994 -0.413875 -0.22967529296875 -0.4961181640624994 -0.4140000000000001 -0.22967529296875 -0.4961181640624994 -0.414125 -0.228668212890625 -0.4961181640624994 -0.41425 -0.2276611328125 -0.4961181640624994 -0.414375 -0.2276611328125 -0.4961181640624994 -0.4145 -0.22662353515625 -0.4961181640624994 -0.414625 -0.22662353515625 -0.4961181640624994 -0.41475 -0.225555419921875 -0.4961181640624994 -0.414875 -0.224456787109375 -0.4961181640624994 -0.415 -0.224456787109375 -0.4961181640624994 -0.415125 -0.22332763671875 -0.4961181640624994 -0.41525 -0.22332763671875 -0.4961181640624994 -0.415375 -0.222198486328125 -0.4961181640624994 -0.4155 -0.221038818359375 -0.4961181640624994 -0.415625 -0.221038818359375 -0.4961181640624994 -0.41575 -0.2198486328125 -0.4961181640624994 -0.415875 -0.2198486328125 -0.4961181640624994 -0.416 -0.12615966796875 -0.2863085937499983 -0.416125 -0.125457763671875 -0.2863085937499983 -0.41625 -0.125457763671875 -0.2863085937499983 -0.416375 -0.124725341796875 -0.2863085937499983 -0.4165 -0.124725341796875 -0.2863085937499983 -0.416625 -0.123992919921875 -0.2863085937499983 -0.41675 -0.12322998046875 -0.2863085937499983 -0.416875 -0.12322998046875 -0.2863085937499983 -0.417 -0.122467041015625 -0.2863085937499983 -0.4171250000000001 -0.122467041015625 -0.2863085937499983 -0.41725 -0.121673583984375 -0.2863085937499983 -0.417375 -0.120880126953125 -0.2863085937499983 -0.4175 -0.120880126953125 -0.2863085937499983 -0.417625 -0.12005615234375 -0.2863085937499983 -0.41775 -0.12005615234375 -0.2863085937499983 -0.417875 -0.1192626953125 -0.2863085937499983 -0.418 -0.118408203125 -0.2863085937499983 -0.418125 -0.118408203125 -0.2863085937499983 -0.41825 -0.1175537109375 -0.2863085937499983 -0.418375 -0.1175537109375 -0.2863085937499983 -0.4185 -0.11669921875 -0.2863085937499983 -0.418625 -0.115814208984375 -0.2863085937499983 -0.41875 -0.115814208984375 -0.2863085937499983 -0.418875 -0.11492919921875 -0.2863085937499983 -0.419 -0.11492919921875 -0.2863085937499983 -0.419125 -0.114044189453125 -0.2863085937499983 -0.41925 -0.113128662109375 -0.2863085937499983 -0.419375 -0.113128662109375 -0.2863085937499983 -0.4195 -0.112213134765625 -0.2863085937499983 -0.419625 -0.112213134765625 -0.2863085937499983 -0.41975 -0.11126708984375 -0.2863085937499983 -0.419875 -0.110321044921875 -0.2863085937499983 -0.42 -0.110321044921875 -0.2863085937499983 -0.420125 -0.109344482421875 -0.2863085937499983 -0.4202500000000001 -0.109344482421875 -0.2863085937499983 -0.420375 -0.108367919921875 -0.2863085937499983 -0.4205 -0.107391357421875 -0.2863085937499983 -0.4206250000000001 -0.107391357421875 -0.2863085937499983 -0.42075 -0.10638427734375 -0.2863085937499983 -0.420875 -0.10638427734375 -0.2863085937499983 -0.421 -0.105377197265625 -0.2863085937499983 -0.4211250000000001 -0.1043701171875 -0.2863085937499983 -0.42125 -0.1043701171875 -0.2863085937499983 -0.421375 -0.10333251953125 -0.2863085937499983 -0.4215 -0.10333251953125 -0.2863085937499983 -0.421625 -0.102294921875 -0.2863085937499983 -0.42175 -0.101226806640625 -0.2863085937499983 -0.421875 -0.101226806640625 -0.2863085937499983 -0.422 -0.10015869140625 -0.2863085937499983 -0.422125 -0.10015869140625 -0.2863085937499983 -0.42225 -0.099090576171875 -0.2863085937499983 -0.422375 -0.0980224609375 -0.2863085937499983 -0.4225 -0.0980224609375 -0.2863085937499983 -0.422625 -0.096923828125 -0.2863085937499983 -0.42275 -0.096923828125 -0.2863085937499983 -0.422875 -0.095794677734375 -0.2863085937499983 -0.423 -0.094696044921875 -0.2863085937499983 -0.423125 -0.094696044921875 -0.2863085937499983 -0.42325 -0.09356689453125 -0.2863085937499983 -0.423375 -0.09356689453125 -0.2863085937499983 -0.4234999999999999 -0.0924072265625 -0.2863085937499983 -0.423625 -0.09124755859375 -0.2863085937499983 -0.42375 -0.09124755859375 -0.2863085937499983 -0.423875 -0.090087890625 -0.2863085937499983 -0.424 -0.090087890625 -0.2863085937499983 -0.424125 -0.08892822265625 -0.2863085937499983 -0.42425 -0.0877685546875 -0.2863085937499983 -0.424375 -0.0877685546875 -0.2863085937499983 -0.4245 -0.0865478515625 -0.2863085937499983 -0.424625 -0.0865478515625 -0.2863085937499983 -0.42475 -0.085357666015625 -0.2863085937499983 -0.424875 -0.08416748046875 -0.2863085937499983 -0.425 -0.08416748046875 -0.2863085937499983 -0.4251250000000001 -0.08294677734375 -0.2863085937499983 -0.42525 -0.08294677734375 -0.2863085937499983 -0.425375 -0.08172607421875 -0.2863085937499983 -0.4255 -0.080474853515625 -0.2863085937499983 -0.4256250000000001 -0.080474853515625 -0.2863085937499983 -0.42575 -0.0792236328125 -0.2863085937499983 -0.425875 -0.0792236328125 -0.2863085937499983 -0.426 -0.077972412109375 -0.2863085937499983 -0.426125 -0.07672119140625 -0.2863085937499983 -0.42625 -0.07672119140625 -0.2863085937499983 -0.426375 -0.075439453125 -0.2863085937499983 -0.4265 -0.075439453125 -0.2863085937499983 -0.426625 -0.07415771484375 -0.2863085937499983 -0.42675 -0.0728759765625 -0.2863085937499983 -0.426875 -0.0728759765625 -0.2863085937499983 -0.427 -0.07159423828125 -0.2863085937499983 -0.427125 -0.07159423828125 -0.2863085937499983 -0.42725 -0.070281982421875 -0.2863085937499983 -0.427375 -0.0689697265625 -0.2863085937499983 -0.4275 -0.0689697265625 -0.2863085937499983 -0.427625 -0.067657470703125 -0.2863085937499983 -0.42775 -0.067657470703125 -0.2863085937499983 -0.427875 -0.06634521484375 -0.2863085937499983 -0.428 -0.06500244140625 -0.2863085937499983 -0.428125 -0.06500244140625 -0.2863085937499983 -0.4282500000000001 -0.06365966796875 -0.2863085937499983 -0.428375 -0.06365966796875 -0.2863085937499983 -0.4285 -0.06231689453125 -0.2863085937499983 -0.4286250000000001 -0.06097412109375 -0.2863085937499983 -0.4287500000000001 -0.06097412109375 -0.2863085937499983 -0.428875 -0.059600830078125 -0.2863085937499983 -0.429 -0.059600830078125 -0.2863085937499983 -0.4291250000000001 -0.0582275390625 -0.2863085937499983 -0.42925 -0.056854248046875 -0.2863085937499983 -0.429375 -0.056854248046875 -0.2863085937499983 -0.4295 -0.05548095703125 -0.2863085937499983 -0.4296250000000001 -0.05548095703125 -0.2863085937499983 -0.42975 -0.054107666015625 -0.2863085937499983 -0.429875 -0.052703857421875 -0.2863085937499983 -0.43 -0.052703857421875 -0.2863085937499983 -0.430125 -0.051300048828125 -0.2863085937499983 -0.43025 -0.051300048828125 -0.2863085937499983 -0.430375 -0.0499267578125 -0.2863085937499983 -0.4305 -0.048492431640625 -0.2863085937499983 -0.430625 -0.048492431640625 -0.2863085937499983 -0.43075 -0.047088623046875 -0.2863085937499983 -0.430875 -0.047088623046875 -0.2863085937499983 -0.431 -0.045684814453125 -0.2863085937499983 -0.431125 -0.04425048828125 -0.2863085937499983 -0.43125 -0.04425048828125 -0.2863085937499983 -0.431375 -0.042816162109375 -0.2863085937499983 -0.4315 -0.042816162109375 -0.2863085937499983 -0.431625 -0.0413818359375 -0.2863085937499983 -0.43175 -0.039947509765625 -0.2863085937499983 -0.431875 -0.039947509765625 -0.2863085937499983 -0.432 -0.03851318359375 -0.2863085937499983 -0.432125 -0.03851318359375 -0.2863085937499983 -0.43225 -0.03704833984375 -0.2863085937499983 -0.432375 -0.035614013671875 -0.2863085937499983 -0.4325 -0.035614013671875 -0.2863085937499983 -0.432625 -0.034149169921875 -0.2863085937499983 -0.4327500000000001 -0.034149169921875 -0.2863085937499983 -0.432875 -0.03271484375 -0.2863085937499983 -0.433 -0.03125 -0.2863085937499983 -0.433125 -0.03125 -0.2863085937499983 -0.43325 -0.02978515625 -0.2863085937499983 -0.433375 -0.02978515625 -0.2863085937499983 -0.4335 -0.0283203125 -0.2863085937499983 -0.433625 -0.026824951171875 -0.2863085937499983 -0.43375 -0.026824951171875 -0.2863085937499983 -0.433875 -0.025360107421875 -0.2863085937499983 -0.434 -0.025360107421875 -0.2863085937499983 -0.434125 -0.023895263671875 -0.2863085937499983 -0.43425 -0.02239990234375 -0.2863085937499983 -0.434375 -0.02239990234375 -0.2863085937499983 -0.4345 -0.02093505859375 -0.2863085937499983 -0.434625 -0.02093505859375 -0.2863085937499983 -0.43475 -0.019439697265625 -0.2863085937499983 -0.434875 -0.0179443359375 -0.2863085937499983 -0.435 -0.0179443359375 -0.2863085937499983 -0.435125 -0.0164794921875 -0.2863085937499983 -0.43525 -0.0164794921875 -0.2863085937499983 -0.435375 -0.014984130859375 -0.2863085937499983 -0.4355 -0.01348876953125 -0.2863085937499983 -0.435625 -0.01348876953125 -0.2863085937499983 -0.43575 -0.011993408203125 -0.2863085937499983 -0.4358750000000001 -0.011993408203125 -0.2863085937499983 -0.436 -0.010498046875 -0.2863085937499983 -0.436125 -0.009002685546875 -0.2863085937499983 -0.4362500000000001 -0.009002685546875 -0.2863085937499983 -0.436375 -0.00750732421875 -0.2863085937499983 -0.4365 -0.00750732421875 -0.2863085937499983 -0.436625 -0.006011962890625 -0.2863085937499983 -0.4367500000000001 -0.0045166015625 -0.2863085937499983 -0.436875 -0.0045166015625 -0.2863085937499983 -0.437 -0.003021240234375 -0.2863085937499983 -0.437125 -0.003021240234375 -0.2863085937499983 -0.43725 -0.00152587890625 -0.2863085937499983 +0.375125 -0.00311279296875 -0.5948388671875 +0.37525 -0.00311279296875 -0.5948388671875 +0.375375 -0.0062255859375 -0.5948388671875 +0.3755 -0.00933837890625 -0.5948388671875 +0.375625 -0.00933837890625 -0.5948388671875 +0.37575 -0.012451171875 -0.5948388671875 +0.375875 -0.012451171875 -0.5948388671875 +0.376 -0.015533447265625 -0.5948388671875 +0.376125 -0.018646240234375 -0.5948388671875 +0.37625 -0.018646240234375 -0.5948388671875 +0.376375 -0.021759033203125 -0.5948388671875 +0.3765 -0.021759033203125 -0.5948388671875 +0.376625 -0.024871826171875 -0.5948388671875 +0.37675 -0.0279541015625 -0.5948388671875 +0.376875 -0.0279541015625 -0.5948388671875 +0.377 -0.03106689453125 -0.5948388671875 +0.377125 -0.03106689453125 -0.5948388671875 +0.37725 -0.0341796875 -0.5948388671875 +0.377375 -0.037261962890625 -0.5948388671875 +0.3775 -0.037261962890625 -0.5948388671875 +0.377625 -0.04034423828125 -0.5948388671875 +0.37775 -0.04034423828125 -0.5948388671875 +0.377875 -0.043426513671875 -0.5948388671875 +0.378 -0.0465087890625 -0.5948388671875 +0.378125 -0.0465087890625 -0.5948388671875 +0.37825 -0.049591064453125 -0.5948388671875 +0.378375 -0.049591064453125 -0.5948388671875 +0.3785 -0.052642822265625 -0.5948388671875 +0.378625 -0.055694580078125 -0.5948388671875 +0.3787500000000001 -0.055694580078125 -0.5948388671875 +0.378875 -0.05877685546875 -0.5948388671875 +0.379 -0.05877685546875 -0.5948388671875 +0.379125 -0.06182861328125 -0.5948388671875 +0.37925 -0.064849853515625 -0.5948388671875 +0.379375 -0.064849853515625 -0.5948388671875 +0.3795 -0.067901611328125 -0.5948388671875 +0.379625 -0.067901611328125 -0.5948388671875 +0.37975 -0.0709228515625 -0.5948388671875 +0.379875 -0.073944091796875 -0.5948388671875 +0.38 -0.073944091796875 -0.5948388671875 +0.380125 -0.07696533203125 -0.5948388671875 +0.38025 -0.07696533203125 -0.5948388671875 +0.380375 -0.0799560546875 -0.5948388671875 +0.3805 -0.08294677734375 -0.5948388671875 +0.380625 -0.08294677734375 -0.5948388671875 +0.38075 -0.0859375 -0.5948388671875 +0.380875 -0.0859375 -0.5948388671875 +0.381 -0.08892822265625 -0.5948388671875 +0.381125 -0.091888427734375 -0.5948388671875 +0.38125 -0.091888427734375 -0.5948388671875 +0.381375 -0.0948486328125 -0.5948388671875 +0.3815 -0.0948486328125 -0.5948388671875 +0.381625 -0.0977783203125 -0.5948388671875 +0.38175 -0.100738525390625 -0.5948388671875 +0.381875 -0.100738525390625 -0.5948388671875 +0.382 -0.1036376953125 -0.5948388671875 +0.382125 -0.1036376953125 -0.5948388671875 +0.38225 -0.1065673828125 -0.5948388671875 +0.382375 -0.109466552734375 -0.5948388671875 +0.3825 -0.109466552734375 -0.5948388671875 +0.382625 -0.11236572265625 -0.5948388671875 +0.3827500000000001 -0.11236572265625 -0.5948388671875 +0.382875 -0.115234375 -0.5948388671875 +0.383 -0.11810302734375 -0.5948388671875 +0.383125 -0.11810302734375 -0.5948388671875 +0.38325 -0.120941162109375 -0.5948388671875 +0.383375 -0.120941162109375 -0.5948388671875 +0.3835 -0.123779296875 -0.5948388671875 +0.383625 -0.126617431640625 -0.5948388671875 +0.38375 -0.126617431640625 -0.5948388671875 +0.383875 -0.129425048828125 -0.5948388671875 +0.384 -0.107940673828125 -0.4961181640624994 +0.384125 -0.11029052734375 -0.4961181640624994 +0.38425 -0.112579345703125 -0.4961181640624994 +0.384375 -0.112579345703125 -0.4961181640624994 +0.3845 -0.114898681640625 -0.4961181640624994 +0.384625 -0.114898681640625 -0.4961181640624994 +0.38475 -0.1171875 -0.4961181640624994 +0.384875 -0.119476318359375 -0.4961181640624994 +0.385 -0.119476318359375 -0.4961181640624994 +0.385125 -0.12176513671875 -0.4961181640624994 +0.38525 -0.12176513671875 -0.4961181640624994 +0.385375 -0.1240234375 -0.4961181640624994 +0.3855 -0.126251220703125 -0.4961181640624994 +0.385625 -0.126251220703125 -0.4961181640624994 +0.38575 -0.12847900390625 -0.4961181640624994 +0.385875 -0.12847900390625 -0.4961181640624994 +0.386 -0.130706787109375 -0.4961181640624994 +0.386125 -0.132904052734375 -0.4961181640624994 +0.38625 -0.132904052734375 -0.4961181640624994 +0.386375 -0.13507080078125 -0.4961181640624994 +0.3865 -0.13507080078125 -0.4961181640624994 +0.386625 -0.137237548828125 -0.4961181640624994 +0.38675 -0.139404296875 -0.4961181640624994 +0.386875 -0.139404296875 -0.4961181640624994 +0.387 -0.14154052734375 -0.4961181640624994 +0.387125 -0.14154052734375 -0.4961181640624994 +0.38725 -0.1436767578125 -0.4961181640624994 +0.387375 -0.145782470703125 -0.4961181640624994 +0.3875 -0.145782470703125 -0.4961181640624994 +0.387625 -0.14788818359375 -0.4961181640624994 +0.38775 -0.14788818359375 -0.4961181640624994 +0.387875 -0.14996337890625 -0.4961181640624994 +0.388 -0.152008056640625 -0.4961181640624994 +0.388125 -0.152008056640625 -0.4961181640624994 +0.38825 -0.154052734375 -0.4961181640624994 +0.388375 -0.154052734375 -0.4961181640624994 +0.3885 -0.156097412109375 -0.4961181640624994 +0.388625 -0.158111572265625 -0.4961181640624994 +0.38875 -0.158111572265625 -0.4961181640624994 +0.388875 -0.16009521484375 -0.4961181640624994 +0.389 -0.16009521484375 -0.4961181640624994 +0.389125 -0.162078857421875 -0.4961181640624994 +0.38925 -0.164031982421875 -0.4961181640624994 +0.389375 -0.164031982421875 -0.4961181640624994 +0.3895 -0.16595458984375 -0.4961181640624994 +0.389625 -0.16595458984375 -0.4961181640624994 +0.38975 -0.167877197265625 -0.4961181640624994 +0.389875 -0.1697998046875 -0.4961181640624994 +0.39 -0.1697998046875 -0.4961181640624994 +0.390125 -0.171661376953125 -0.4961181640624994 +0.39025 -0.171661376953125 -0.4961181640624994 +0.390375 -0.17352294921875 -0.4961181640624994 +0.3905 -0.175384521484375 -0.4961181640624994 +0.390625 -0.175384521484375 -0.4961181640624994 +0.39075 -0.177215576171875 -0.4961181640624994 +0.390875 -0.177215576171875 -0.4961181640624994 +0.391 -0.17901611328125 -0.4961181640624994 +0.391125 -0.180816650390625 -0.4961181640624994 +0.39125 -0.180816650390625 -0.4961181640624994 +0.391375 -0.182586669921875 -0.4961181640624994 +0.3915 -0.182586669921875 -0.4961181640624994 +0.391625 -0.184326171875 -0.4961181640624994 +0.39175 -0.18603515625 -0.4961181640624994 +0.391875 -0.18603515625 -0.4961181640624994 +0.392 -0.187744140625 -0.4961181640624994 +0.392125 -0.187744140625 -0.4961181640624994 +0.39225 -0.189453125 -0.4961181640624994 +0.392375 -0.19110107421875 -0.4961181640624994 +0.3925 -0.19110107421875 -0.4961181640624994 +0.392625 -0.1927490234375 -0.4961181640624994 +0.39275 -0.1927490234375 -0.4961181640624994 +0.392875 -0.194366455078125 -0.4961181640624994 +0.393 -0.19598388671875 -0.4961181640624994 +0.393125 -0.19598388671875 -0.4961181640624994 +0.39325 -0.19757080078125 -0.4961181640624994 +0.393375 -0.19757080078125 -0.4961181640624994 +0.3935 -0.199127197265625 -0.4961181640624994 +0.393625 -0.200653076171875 -0.4961181640624994 +0.39375 -0.200653076171875 -0.4961181640624994 +0.393875 -0.202178955078125 -0.4961181640624994 +0.394 -0.202178955078125 -0.4961181640624994 +0.394125 -0.20367431640625 -0.4961181640624994 +0.39425 -0.20513916015625 -0.4961181640624994 +0.3943750000000001 -0.20513916015625 -0.4961181640624994 +0.3945 -0.20660400390625 -0.4961181640624994 +0.394625 -0.20660400390625 -0.4961181640624994 +0.39475 -0.2080078125 -0.4961181640624994 +0.394875 -0.20941162109375 -0.4961181640624994 +0.395 -0.20941162109375 -0.4961181640624994 +0.395125 -0.2108154296875 -0.4961181640624994 +0.39525 -0.2108154296875 -0.4961181640624994 +0.395375 -0.212158203125 -0.4961181640624994 +0.3955 -0.2135009765625 -0.4961181640624994 +0.395625 -0.2135009765625 -0.4961181640624994 +0.39575 -0.214813232421875 -0.4961181640624994 +0.395875 -0.214813232421875 -0.4961181640624994 +0.396 -0.216094970703125 -0.4961181640624994 +0.396125 -0.21734619140625 -0.4961181640624994 +0.39625 -0.21734619140625 -0.4961181640624994 +0.396375 -0.218597412109375 -0.4961181640624994 +0.3965 -0.218597412109375 -0.4961181640624994 +0.396625 -0.219818115234375 -0.4961181640624994 +0.39675 -0.22100830078125 -0.4961181640624994 +0.396875 -0.22100830078125 -0.4961181640624994 +0.397 -0.22216796875 -0.4961181640624994 +0.397125 -0.22216796875 -0.4961181640624994 +0.39725 -0.223297119140625 -0.4961181640624994 +0.397375 -0.22442626953125 -0.4961181640624994 +0.3975 -0.22442626953125 -0.4961181640624994 +0.397625 -0.22552490234375 -0.4961181640624994 +0.39775 -0.22552490234375 -0.4961181640624994 +0.397875 -0.226593017578125 -0.4961181640624994 +0.398 -0.227630615234375 -0.4961181640624994 +0.398125 -0.227630615234375 -0.4961181640624994 +0.39825 -0.2286376953125 -0.4961181640624994 +0.3983750000000001 -0.2286376953125 -0.4961181640624994 +0.3985 -0.229644775390625 -0.4961181640624994 +0.398625 -0.230621337890625 -0.4961181640624994 +0.39875 -0.230621337890625 -0.4961181640624994 +0.398875 -0.2315673828125 -0.4961181640624994 +0.399 -0.2315673828125 -0.4961181640624994 +0.399125 -0.23248291015625 -0.4961181640624994 +0.39925 -0.233367919921875 -0.4961181640624994 +0.399375 -0.233367919921875 -0.4961181640624994 +0.3995 -0.2342529296875 -0.4961181640624994 +0.399625 -0.2342529296875 -0.4961181640624994 +0.39975 -0.235076904296875 -0.4961181640624994 +0.399875 -0.23590087890625 -0.4961181640624994 +0.4 -0.23590087890625 -0.4961181640624994 +0.400125 -0.2366943359375 -0.4961181640624994 +0.40025 -0.2366943359375 -0.4961181640624994 +0.400375 -0.237457275390625 -0.4961181640624994 +0.4005 -0.238189697265625 -0.4961181640624994 +0.400625 -0.238189697265625 -0.4961181640624994 +0.40075 -0.2388916015625 -0.4961181640624994 +0.400875 -0.2388916015625 -0.4961181640624994 +0.401 -0.239593505859375 -0.4961181640624994 +0.401125 -0.240234375 -0.4961181640624994 +0.40125 -0.240234375 -0.4961181640624994 +0.401375 -0.240875244140625 -0.4961181640624994 +0.4015000000000001 -0.240875244140625 -0.4961181640624994 +0.401625 -0.241485595703125 -0.4961181640624994 +0.40175 -0.2420654296875 -0.4961181640624994 +0.401875 -0.2420654296875 -0.4961181640624994 +0.402 -0.24261474609375 -0.4961181640624994 +0.402125 -0.24261474609375 -0.4961181640624994 +0.40225 -0.243133544921875 -0.4961181640624994 +0.402375 -0.24365234375 -0.4961181640624994 +0.4025 -0.24365234375 -0.4961181640624994 +0.402625 -0.244110107421875 -0.4961181640624994 +0.40275 -0.244110107421875 -0.4961181640624994 +0.402875 -0.24456787109375 -0.4961181640624994 +0.403 -0.2449951171875 -0.4961181640624994 +0.403125 -0.2449951171875 -0.4961181640624994 +0.40325 -0.245361328125 -0.4961181640624994 +0.403375 -0.245361328125 -0.4961181640624994 +0.4035 -0.2457275390625 -0.4961181640624994 +0.403625 -0.24609375 -0.4961181640624994 +0.40375 -0.24609375 -0.4961181640624994 +0.403875 -0.24639892578125 -0.4961181640624994 +0.404 -0.24639892578125 -0.4961181640624994 +0.404125 -0.246673583984375 -0.4961181640624994 +0.40425 -0.2469482421875 -0.4961181640624994 +0.404375 -0.2469482421875 -0.4961181640624994 +0.4045 -0.247161865234375 -0.4961181640624994 +0.4046250000000001 -0.247161865234375 -0.4961181640624994 +0.40475 -0.24737548828125 -0.4961181640624994 +0.404875 -0.24755859375 -0.4961181640624994 +0.4050000000000001 -0.24755859375 -0.4961181640624994 +0.405125 -0.247711181640625 -0.4961181640624994 +0.40525 -0.247711181640625 -0.4961181640624994 +0.405375 -0.247833251953125 -0.4961181640624994 +0.4055000000000001 -0.2479248046875 -0.4961181640624994 +0.405625 -0.2479248046875 -0.4961181640624994 +0.40575 -0.24798583984375 -0.4961181640624994 +0.405875 -0.24798583984375 -0.4961181640624994 +0.406 -0.248016357421875 -0.4961181640624994 +0.406125 -0.248046875 -0.4961181640624994 +0.40625 -0.248046875 -0.4961181640624994 +0.406375 -0.248016357421875 -0.4961181640624994 +0.4065 -0.248016357421875 -0.4961181640624994 +0.406625 -0.24798583984375 -0.4961181640624994 +0.40675 -0.2479248046875 -0.4961181640624994 +0.406875 -0.2479248046875 -0.4961181640624994 +0.407 -0.247833251953125 -0.4961181640624994 +0.407125 -0.247833251953125 -0.4961181640624994 +0.40725 -0.247711181640625 -0.4961181640624994 +0.407375 -0.24755859375 -0.4961181640624994 +0.4075 -0.24755859375 -0.4961181640624994 +0.407625 -0.24737548828125 -0.4961181640624994 +0.40775 -0.24737548828125 -0.4961181640624994 +0.4078749999999999 -0.247161865234375 -0.4961181640624994 +0.408 -0.2469482421875 -0.4961181640624994 +0.408125 -0.2469482421875 -0.4961181640624994 +0.40825 -0.246673583984375 -0.4961181640624994 +0.408375 -0.246673583984375 -0.4961181640624994 +0.4085 -0.24639892578125 -0.4961181640624994 +0.408625 -0.24609375 -0.4961181640624994 +0.40875 -0.24609375 -0.4961181640624994 +0.408875 -0.2457275390625 -0.4961181640624994 +0.409 -0.2457275390625 -0.4961181640624994 +0.409125 -0.245361328125 -0.4961181640624994 +0.40925 -0.2449951171875 -0.4961181640624994 +0.409375 -0.2449951171875 -0.4961181640624994 +0.4095000000000001 -0.24456787109375 -0.4961181640624994 +0.409625 -0.24456787109375 -0.4961181640624994 +0.40975 -0.244110107421875 -0.4961181640624994 +0.409875 -0.24365234375 -0.4961181640624994 +0.4100000000000001 -0.24365234375 -0.4961181640624994 +0.410125 -0.243133544921875 -0.4961181640624994 +0.41025 -0.243133544921875 -0.4961181640624994 +0.410375 -0.24261474609375 -0.4961181640624994 +0.4105 -0.2420654296875 -0.4961181640624994 +0.410625 -0.2420654296875 -0.4961181640624994 +0.41075 -0.241485595703125 -0.4961181640624994 +0.410875 -0.241485595703125 -0.4961181640624994 +0.411 -0.240875244140625 -0.4961181640624994 +0.411125 -0.240234375 -0.4961181640624994 +0.41125 -0.240234375 -0.4961181640624994 +0.411375 -0.239593505859375 -0.4961181640624994 +0.4115 -0.239593505859375 -0.4961181640624994 +0.411625 -0.2388916015625 -0.4961181640624994 +0.41175 -0.238189697265625 -0.4961181640624994 +0.411875 -0.238189697265625 -0.4961181640624994 +0.412 -0.237457275390625 -0.4961181640624994 +0.412125 -0.237457275390625 -0.4961181640624994 +0.41225 -0.2366943359375 -0.4961181640624994 +0.412375 -0.23590087890625 -0.4961181640624994 +0.4125 -0.23590087890625 -0.4961181640624994 +0.4126250000000001 -0.235076904296875 -0.4961181640624994 +0.41275 -0.235076904296875 -0.4961181640624994 +0.412875 -0.2342529296875 -0.4961181640624994 +0.4130000000000001 -0.233367919921875 -0.4961181640624994 +0.4131250000000001 -0.233367919921875 -0.4961181640624994 +0.41325 -0.23248291015625 -0.4961181640624994 +0.413375 -0.23248291015625 -0.4961181640624994 +0.4135000000000001 -0.2315673828125 -0.4961181640624994 +0.413625 -0.230621337890625 -0.4961181640624994 +0.41375 -0.230621337890625 -0.4961181640624994 +0.413875 -0.229644775390625 -0.4961181640624994 +0.4140000000000001 -0.229644775390625 -0.4961181640624994 +0.414125 -0.2286376953125 -0.4961181640624994 +0.41425 -0.227630615234375 -0.4961181640624994 +0.414375 -0.227630615234375 -0.4961181640624994 +0.4145 -0.226593017578125 -0.4961181640624994 +0.414625 -0.226593017578125 -0.4961181640624994 +0.41475 -0.22552490234375 -0.4961181640624994 +0.414875 -0.22442626953125 -0.4961181640624994 +0.415 -0.22442626953125 -0.4961181640624994 +0.415125 -0.223297119140625 -0.4961181640624994 +0.41525 -0.223297119140625 -0.4961181640624994 +0.415375 -0.22216796875 -0.4961181640624994 +0.4155 -0.22100830078125 -0.4961181640624994 +0.415625 -0.22100830078125 -0.4961181640624994 +0.41575 -0.219818115234375 -0.4961181640624994 +0.415875 -0.219818115234375 -0.4961181640624994 +0.416 -0.126129150390625 -0.2863085937499983 +0.416125 -0.12542724609375 -0.2863085937499983 +0.41625 -0.12542724609375 -0.2863085937499983 +0.416375 -0.12469482421875 -0.2863085937499983 +0.4165 -0.12469482421875 -0.2863085937499983 +0.416625 -0.12396240234375 -0.2863085937499983 +0.41675 -0.123199462890625 -0.2863085937499983 +0.416875 -0.123199462890625 -0.2863085937499983 +0.417 -0.1224365234375 -0.2863085937499983 +0.4171250000000001 -0.1224365234375 -0.2863085937499983 +0.41725 -0.12164306640625 -0.2863085937499983 +0.417375 -0.120849609375 -0.2863085937499983 +0.4175 -0.120849609375 -0.2863085937499983 +0.417625 -0.120025634765625 -0.2863085937499983 +0.41775 -0.120025634765625 -0.2863085937499983 +0.417875 -0.119232177734375 -0.2863085937499983 +0.418 -0.118377685546875 -0.2863085937499983 +0.418125 -0.118377685546875 -0.2863085937499983 +0.41825 -0.117523193359375 -0.2863085937499983 +0.418375 -0.117523193359375 -0.2863085937499983 +0.4185 -0.116668701171875 -0.2863085937499983 +0.418625 -0.11578369140625 -0.2863085937499983 +0.41875 -0.11578369140625 -0.2863085937499983 +0.418875 -0.114898681640625 -0.2863085937499983 +0.419 -0.114898681640625 -0.2863085937499983 +0.419125 -0.114013671875 -0.2863085937499983 +0.41925 -0.11309814453125 -0.2863085937499983 +0.419375 -0.11309814453125 -0.2863085937499983 +0.4195 -0.1121826171875 -0.2863085937499983 +0.419625 -0.1121826171875 -0.2863085937499983 +0.41975 -0.111236572265625 -0.2863085937499983 +0.419875 -0.11029052734375 -0.2863085937499983 +0.42 -0.11029052734375 -0.2863085937499983 +0.420125 -0.10931396484375 -0.2863085937499983 +0.4202500000000001 -0.10931396484375 -0.2863085937499983 +0.420375 -0.10833740234375 -0.2863085937499983 +0.4205 -0.10736083984375 -0.2863085937499983 +0.4206250000000001 -0.10736083984375 -0.2863085937499983 +0.42075 -0.106353759765625 -0.2863085937499983 +0.420875 -0.106353759765625 -0.2863085937499983 +0.421 -0.1053466796875 -0.2863085937499983 +0.4211250000000001 -0.104339599609375 -0.2863085937499983 +0.42125 -0.104339599609375 -0.2863085937499983 +0.421375 -0.103302001953125 -0.2863085937499983 +0.4215 -0.103302001953125 -0.2863085937499983 +0.421625 -0.102264404296875 -0.2863085937499983 +0.42175 -0.1011962890625 -0.2863085937499983 +0.421875 -0.1011962890625 -0.2863085937499983 +0.422 -0.100128173828125 -0.2863085937499983 +0.422125 -0.100128173828125 -0.2863085937499983 +0.42225 -0.09906005859375 -0.2863085937499983 +0.422375 -0.097991943359375 -0.2863085937499983 +0.4225 -0.097991943359375 -0.2863085937499983 +0.422625 -0.096893310546875 -0.2863085937499983 +0.42275 -0.096893310546875 -0.2863085937499983 +0.422875 -0.09576416015625 -0.2863085937499983 +0.423 -0.09466552734375 -0.2863085937499983 +0.423125 -0.09466552734375 -0.2863085937499983 +0.42325 -0.093536376953125 -0.2863085937499983 +0.423375 -0.093536376953125 -0.2863085937499983 +0.4234999999999999 -0.092376708984375 -0.2863085937499983 +0.423625 -0.091217041015625 -0.2863085937499983 +0.42375 -0.091217041015625 -0.2863085937499983 +0.423875 -0.090057373046875 -0.2863085937499983 +0.424 -0.090057373046875 -0.2863085937499983 +0.424125 -0.088897705078125 -0.2863085937499983 +0.42425 -0.087738037109375 -0.2863085937499983 +0.424375 -0.087738037109375 -0.2863085937499983 +0.4245 -0.086517333984375 -0.2863085937499983 +0.424625 -0.086517333984375 -0.2863085937499983 +0.42475 -0.0853271484375 -0.2863085937499983 +0.424875 -0.084136962890625 -0.2863085937499983 +0.425 -0.084136962890625 -0.2863085937499983 +0.4251250000000001 -0.082916259765625 -0.2863085937499983 +0.42525 -0.082916259765625 -0.2863085937499983 +0.425375 -0.081695556640625 -0.2863085937499983 +0.4255 -0.0804443359375 -0.2863085937499983 +0.4256250000000001 -0.0804443359375 -0.2863085937499983 +0.42575 -0.079193115234375 -0.2863085937499983 +0.425875 -0.079193115234375 -0.2863085937499983 +0.426 -0.07794189453125 -0.2863085937499983 +0.426125 -0.076690673828125 -0.2863085937499983 +0.42625 -0.076690673828125 -0.2863085937499983 +0.426375 -0.075408935546875 -0.2863085937499983 +0.4265 -0.075408935546875 -0.2863085937499983 +0.426625 -0.074127197265625 -0.2863085937499983 +0.42675 -0.072845458984375 -0.2863085937499983 +0.426875 -0.072845458984375 -0.2863085937499983 +0.427 -0.071563720703125 -0.2863085937499983 +0.427125 -0.071563720703125 -0.2863085937499983 +0.42725 -0.07025146484375 -0.2863085937499983 +0.427375 -0.068939208984375 -0.2863085937499983 +0.4275 -0.068939208984375 -0.2863085937499983 +0.427625 -0.067626953125 -0.2863085937499983 +0.42775 -0.067626953125 -0.2863085937499983 +0.427875 -0.066314697265625 -0.2863085937499983 +0.428 -0.064971923828125 -0.2863085937499983 +0.428125 -0.064971923828125 -0.2863085937499983 +0.4282500000000001 -0.063629150390625 -0.2863085937499983 +0.428375 -0.063629150390625 -0.2863085937499983 +0.4285 -0.062286376953125 -0.2863085937499983 +0.4286250000000001 -0.060943603515625 -0.2863085937499983 +0.4287500000000001 -0.060943603515625 -0.2863085937499983 +0.428875 -0.0595703125 -0.2863085937499983 +0.429 -0.0595703125 -0.2863085937499983 +0.4291250000000001 -0.058197021484375 -0.2863085937499983 +0.42925 -0.05682373046875 -0.2863085937499983 +0.429375 -0.05682373046875 -0.2863085937499983 +0.4295 -0.055450439453125 -0.2863085937499983 +0.4296250000000001 -0.055450439453125 -0.2863085937499983 +0.42975 -0.0540771484375 -0.2863085937499983 +0.429875 -0.05267333984375 -0.2863085937499983 +0.43 -0.05267333984375 -0.2863085937499983 +0.430125 -0.05126953125 -0.2863085937499983 +0.43025 -0.05126953125 -0.2863085937499983 +0.430375 -0.049896240234375 -0.2863085937499983 +0.4305 -0.0484619140625 -0.2863085937499983 +0.430625 -0.0484619140625 -0.2863085937499983 +0.43075 -0.04705810546875 -0.2863085937499983 +0.430875 -0.04705810546875 -0.2863085937499983 +0.431 -0.045654296875 -0.2863085937499983 +0.431125 -0.044219970703125 -0.2863085937499983 +0.43125 -0.044219970703125 -0.2863085937499983 +0.431375 -0.04278564453125 -0.2863085937499983 +0.4315 -0.04278564453125 -0.2863085937499983 +0.431625 -0.041351318359375 -0.2863085937499983 +0.43175 -0.0399169921875 -0.2863085937499983 +0.431875 -0.0399169921875 -0.2863085937499983 +0.432 -0.038482666015625 -0.2863085937499983 +0.432125 -0.038482666015625 -0.2863085937499983 +0.43225 -0.037017822265625 -0.2863085937499983 +0.432375 -0.03558349609375 -0.2863085937499983 +0.4325 -0.03558349609375 -0.2863085937499983 +0.432625 -0.03411865234375 -0.2863085937499983 +0.4327500000000001 -0.03411865234375 -0.2863085937499983 +0.432875 -0.032684326171875 -0.2863085937499983 +0.433 -0.031219482421875 -0.2863085937499983 +0.433125 -0.031219482421875 -0.2863085937499983 +0.43325 -0.029754638671875 -0.2863085937499983 +0.433375 -0.029754638671875 -0.2863085937499983 +0.4335 -0.028289794921875 -0.2863085937499983 +0.433625 -0.02679443359375 -0.2863085937499983 +0.43375 -0.02679443359375 -0.2863085937499983 +0.433875 -0.02532958984375 -0.2863085937499983 +0.434 -0.02532958984375 -0.2863085937499983 +0.434125 -0.02386474609375 -0.2863085937499983 +0.43425 -0.022369384765625 -0.2863085937499983 +0.434375 -0.022369384765625 -0.2863085937499983 +0.4345 -0.020904541015625 -0.2863085937499983 +0.434625 -0.020904541015625 -0.2863085937499983 +0.43475 -0.0194091796875 -0.2863085937499983 +0.434875 -0.017913818359375 -0.2863085937499983 +0.435 -0.017913818359375 -0.2863085937499983 +0.435125 -0.016448974609375 -0.2863085937499983 +0.43525 -0.016448974609375 -0.2863085937499983 +0.435375 -0.01495361328125 -0.2863085937499983 +0.4355 -0.013458251953125 -0.2863085937499983 +0.435625 -0.013458251953125 -0.2863085937499983 +0.43575 -0.011962890625 -0.2863085937499983 +0.4358750000000001 -0.011962890625 -0.2863085937499983 +0.436 -0.010467529296875 -0.2863085937499983 +0.436125 -0.00897216796875 -0.2863085937499983 +0.4362500000000001 -0.00897216796875 -0.2863085937499983 +0.436375 -0.007476806640625 -0.2863085937499983 +0.4365 -0.007476806640625 -0.2863085937499983 +0.436625 -0.0059814453125 -0.2863085937499983 +0.4367500000000001 -0.004486083984375 -0.2863085937499983 +0.436875 -0.004486083984375 -0.2863085937499983 +0.437 -0.00299072265625 -0.2863085937499983 +0.437125 -0.00299072265625 -0.2863085937499983 +0.43725 -0.001495361328125 -0.2863085937499983 0.437375 0.0 -0.2863085937499983 0.4375 0.0 -0.2863085937499983 0.437625 0.001495361328125 -0.2863085937499983 @@ -3582,421 +3582,421 @@ 0.447625 0.07025146484375 -0.2863085937499983 0.44775 0.07025146484375 -0.2863085937499983 0.447875 0.071563720703125 -0.2863085937499983 -0.448 -0.000274658203125 0.001074218750001854 -0.448125 -0.000274658203125 0.001074218750001854 -0.44825 -0.000274658203125 0.001074218750001854 -0.4483750000000001 -0.000274658203125 0.001074218750001854 -0.4485 -0.000274658203125 0.001074218750001854 -0.448625 -0.00030517578125 0.001074218750001854 -0.44875 -0.00030517578125 0.001074218750001854 -0.448875 -0.00030517578125 0.001074218750001854 -0.449 -0.00030517578125 0.001074218750001854 -0.449125 -0.00030517578125 0.001074218750001854 -0.44925 -0.00030517578125 0.001074218750001854 -0.449375 -0.00030517578125 0.001074218750001854 -0.4495 -0.00030517578125 0.001074218750001854 -0.449625 -0.00030517578125 0.001074218750001854 -0.44975 -0.00030517578125 0.001074218750001854 -0.449875 -0.00030517578125 0.001074218750001854 -0.45 -0.00030517578125 0.001074218750001854 -0.450125 -0.000335693359375 0.001074218750001854 -0.45025 -0.000335693359375 0.001074218750001854 -0.450375 -0.000335693359375 0.001074218750001854 -0.4505 -0.000335693359375 0.001074218750001854 -0.450625 -0.000335693359375 0.001074218750001854 -0.45075 -0.000335693359375 0.001074218750001854 -0.450875 -0.000335693359375 0.001074218750001854 -0.451 -0.000335693359375 0.001074218750001854 -0.451125 -0.000335693359375 0.001074218750001854 -0.45125 -0.000335693359375 0.001074218750001854 -0.451375 -0.000335693359375 0.001074218750001854 -0.4515000000000001 -0.000335693359375 0.001074218750001854 -0.451625 -0.0003662109375 0.001074218750001854 -0.45175 -0.0003662109375 0.001074218750001854 -0.4518750000000001 -0.0003662109375 0.001074218750001854 -0.452 -0.0003662109375 0.001074218750001854 -0.452125 -0.0003662109375 0.001074218750001854 -0.45225 -0.0003662109375 0.001074218750001854 -0.4523750000000001 -0.0003662109375 0.001074218750001854 -0.4525 -0.0003662109375 0.001074218750001854 -0.452625 -0.0003662109375 0.001074218750001854 -0.45275 -0.0003662109375 0.001074218750001854 -0.452875 -0.0003662109375 0.001074218750001854 -0.453 -0.000396728515625 0.001074218750001854 -0.453125 -0.000396728515625 0.001074218750001854 -0.45325 -0.000396728515625 0.001074218750001854 -0.453375 -0.000396728515625 0.001074218750001854 -0.4535 -0.000396728515625 0.001074218750001854 -0.453625 -0.000396728515625 0.001074218750001854 -0.45375 -0.000396728515625 0.001074218750001854 -0.453875 -0.000396728515625 0.001074218750001854 -0.454 -0.000396728515625 0.001074218750001854 -0.454125 -0.000396728515625 0.001074218750001854 -0.45425 -0.000396728515625 0.001074218750001854 -0.454375 -0.000396728515625 0.001074218750001854 -0.4545 -0.000396728515625 0.001074218750001854 -0.454625 -0.000396728515625 0.001074218750001854 -0.4547499999999999 -0.000396728515625 0.001074218750001854 -0.454875 -0.00042724609375 0.001074218750001854 -0.455 -0.00042724609375 0.001074218750001854 -0.455125 -0.00042724609375 0.001074218750001854 -0.45525 -0.00042724609375 0.001074218750001854 -0.455375 -0.00042724609375 0.001074218750001854 -0.4555 -0.00042724609375 0.001074218750001854 -0.455625 -0.00042724609375 0.001074218750001854 -0.45575 -0.00042724609375 0.001074218750001854 -0.455875 -0.00042724609375 0.001074218750001854 -0.456 -0.00042724609375 0.001074218750001854 -0.456125 -0.00042724609375 0.001074218750001854 -0.45625 -0.00042724609375 0.001074218750001854 -0.4563750000000001 -0.00042724609375 0.001074218750001854 -0.4565 -0.00042724609375 0.001074218750001854 -0.456625 -0.00042724609375 0.001074218750001854 -0.45675 -0.000457763671875 0.001074218750001854 -0.4568750000000001 -0.000457763671875 0.001074218750001854 -0.457 -0.000457763671875 0.001074218750001854 -0.457125 -0.000457763671875 0.001074218750001854 -0.45725 -0.000457763671875 0.001074218750001854 -0.457375 -0.000457763671875 0.001074218750001854 -0.4575 -0.000457763671875 0.001074218750001854 -0.457625 -0.000457763671875 0.001074218750001854 -0.45775 -0.000457763671875 0.001074218750001854 -0.457875 -0.000457763671875 0.001074218750001854 -0.458 -0.000457763671875 0.001074218750001854 -0.458125 -0.000457763671875 0.001074218750001854 -0.45825 -0.000457763671875 0.001074218750001854 -0.458375 -0.000457763671875 0.001074218750001854 -0.4585 -0.000457763671875 0.001074218750001854 -0.458625 -0.000457763671875 0.001074218750001854 -0.45875 -0.000457763671875 0.001074218750001854 -0.458875 -0.000457763671875 0.001074218750001854 -0.459 -0.000457763671875 0.001074218750001854 -0.459125 -0.00048828125 0.001074218750001854 -0.45925 -0.00048828125 0.001074218750001854 -0.459375 -0.00048828125 0.001074218750001854 -0.4595000000000001 -0.00048828125 0.001074218750001854 -0.459625 -0.00048828125 0.001074218750001854 -0.45975 -0.00048828125 0.001074218750001854 -0.4598750000000001 -0.00048828125 0.001074218750001854 -0.4600000000000001 -0.00048828125 0.001074218750001854 -0.460125 -0.00048828125 0.001074218750001854 -0.46025 -0.00048828125 0.001074218750001854 -0.4603750000000001 -0.00048828125 0.001074218750001854 -0.4605 -0.00048828125 0.001074218750001854 -0.460625 -0.00048828125 0.001074218750001854 -0.46075 -0.00048828125 0.001074218750001854 -0.4608750000000001 -0.00048828125 0.001074218750001854 -0.461 -0.00048828125 0.001074218750001854 -0.461125 -0.00048828125 0.001074218750001854 -0.46125 -0.00048828125 0.001074218750001854 -0.461375 -0.00048828125 0.001074218750001854 -0.4615 -0.00048828125 0.001074218750001854 -0.461625 -0.00048828125 0.001074218750001854 -0.46175 -0.00048828125 0.001074218750001854 -0.461875 -0.00048828125 0.001074218750001854 -0.462 -0.000518798828125 0.001074218750001854 -0.462125 -0.000518798828125 0.001074218750001854 -0.46225 -0.000518798828125 0.001074218750001854 -0.462375 -0.000518798828125 0.001074218750001854 -0.4625 -0.000518798828125 0.001074218750001854 -0.462625 -0.000518798828125 0.001074218750001854 -0.46275 -0.000518798828125 0.001074218750001854 -0.462875 -0.000518798828125 0.001074218750001854 -0.463 -0.000518798828125 0.001074218750001854 -0.463125 -0.000518798828125 0.001074218750001854 -0.46325 -0.000518798828125 0.001074218750001854 -0.463375 -0.000518798828125 0.001074218750001854 -0.4635 -0.000518798828125 0.001074218750001854 -0.463625 -0.000518798828125 0.001074218750001854 -0.46375 -0.000518798828125 0.001074218750001854 -0.463875 -0.000518798828125 0.001074218750001854 -0.4640000000000001 -0.000518798828125 0.001074218750001854 -0.464125 -0.000518798828125 0.001074218750001854 -0.46425 -0.000518798828125 0.001074218750001854 -0.464375 -0.000518798828125 0.001074218750001854 -0.4645 -0.000518798828125 0.001074218750001854 -0.464625 -0.000518798828125 0.001074218750001854 -0.46475 -0.000518798828125 0.001074218750001854 -0.464875 -0.000518798828125 0.001074218750001854 -0.465 -0.000518798828125 0.001074218750001854 -0.465125 -0.000518798828125 0.001074218750001854 -0.46525 -0.000518798828125 0.001074218750001854 -0.465375 -0.000518798828125 0.001074218750001854 -0.4655 -0.000518798828125 0.001074218750001854 -0.465625 -0.000518798828125 0.001074218750001854 -0.46575 -0.000518798828125 0.001074218750001854 -0.465875 -0.000518798828125 0.001074218750001854 -0.466 -0.000518798828125 0.001074218750001854 -0.466125 -0.000518798828125 0.001074218750001854 -0.46625 -0.000518798828125 0.001074218750001854 -0.466375 -0.000518798828125 0.001074218750001854 -0.4665 -0.000518798828125 0.001074218750001854 -0.466625 -0.000518798828125 0.001074218750001854 -0.46675 -0.000518798828125 0.001074218750001854 -0.466875 -0.000518798828125 0.001074218750001854 -0.467 -0.000518798828125 0.001074218750001854 -0.4671250000000001 -0.000518798828125 0.001074218750001854 -0.46725 -0.000518798828125 0.001074218750001854 -0.467375 -0.000518798828125 0.001074218750001854 -0.4675000000000001 -0.000518798828125 0.001074218750001854 -0.467625 -0.000518798828125 0.001074218750001854 -0.46775 -0.000518798828125 0.001074218750001854 -0.467875 -0.000518798828125 0.001074218750001854 -0.4680000000000001 -0.000518798828125 0.001074218750001854 -0.468125 -0.000518798828125 0.001074218750001854 -0.46825 -0.000518798828125 0.001074218750001854 -0.468375 -0.000518798828125 0.001074218750001854 -0.4685 -0.000518798828125 0.001074218750001854 -0.468625 -0.000518798828125 0.001074218750001854 -0.46875 -0.000518798828125 0.001074218750001854 -0.468875 -0.000518798828125 0.001074218750001854 -0.469 -0.000518798828125 0.001074218750001854 -0.469125 -0.000518798828125 0.001074218750001854 -0.46925 -0.000518798828125 0.001074218750001854 -0.469375 -0.000518798828125 0.001074218750001854 -0.4695 -0.000518798828125 0.001074218750001854 -0.469625 -0.000518798828125 0.001074218750001854 -0.46975 -0.000518798828125 0.001074218750001854 -0.469875 -0.000518798828125 0.001074218750001854 -0.47 -0.000518798828125 0.001074218750001854 -0.470125 -0.000518798828125 0.001074218750001854 -0.47025 -0.000518798828125 0.001074218750001854 -0.4703749999999999 -0.000518798828125 0.001074218750001854 -0.4705 -0.000518798828125 0.001074218750001854 -0.470625 -0.000518798828125 0.001074218750001854 -0.47075 -0.000518798828125 0.001074218750001854 -0.470875 -0.000518798828125 0.001074218750001854 -0.471 -0.000518798828125 0.001074218750001854 -0.471125 -0.000518798828125 0.001074218750001854 -0.47125 -0.000518798828125 0.001074218750001854 -0.471375 -0.000518798828125 0.001074218750001854 -0.4715 -0.000518798828125 0.001074218750001854 -0.471625 -0.000518798828125 0.001074218750001854 -0.47175 -0.000518798828125 0.001074218750001854 -0.471875 -0.000518798828125 0.001074218750001854 -0.4720000000000001 -0.000518798828125 0.001074218750001854 -0.472125 -0.000518798828125 0.001074218750001854 -0.47225 -0.000518798828125 0.001074218750001854 -0.472375 -0.000518798828125 0.001074218750001854 -0.4725000000000001 -0.000518798828125 0.001074218750001854 -0.472625 -0.000518798828125 0.001074218750001854 -0.47275 -0.000518798828125 0.001074218750001854 -0.472875 -0.000518798828125 0.001074218750001854 -0.473 -0.000518798828125 0.001074218750001854 -0.473125 -0.000518798828125 0.001074218750001854 -0.47325 -0.000518798828125 0.001074218750001854 -0.473375 -0.000518798828125 0.001074218750001854 -0.4735 -0.000518798828125 0.001074218750001854 -0.473625 -0.000518798828125 0.001074218750001854 -0.47375 -0.000518798828125 0.001074218750001854 -0.473875 -0.000518798828125 0.001074218750001854 -0.474 -0.000518798828125 0.001074218750001854 -0.474125 -0.000518798828125 0.001074218750001854 -0.47425 -0.000518798828125 0.001074218750001854 -0.474375 -0.000518798828125 0.001074218750001854 -0.4745 -0.000518798828125 0.001074218750001854 -0.474625 -0.000518798828125 0.001074218750001854 -0.47475 -0.000518798828125 0.001074218750001854 -0.474875 -0.000518798828125 0.001074218750001854 -0.475 -0.000518798828125 0.001074218750001854 -0.4751250000000001 -0.000518798828125 0.001074218750001854 -0.47525 -0.000518798828125 0.001074218750001854 -0.475375 -0.000518798828125 0.001074218750001854 -0.4755000000000001 -0.00048828125 0.001074218750001854 -0.4756250000000001 -0.00048828125 0.001074218750001854 -0.47575 -0.00048828125 0.001074218750001854 -0.475875 -0.00048828125 0.001074218750001854 -0.4760000000000001 -0.00048828125 0.001074218750001854 -0.476125 -0.00048828125 0.001074218750001854 -0.47625 -0.00048828125 0.001074218750001854 -0.476375 -0.00048828125 0.001074218750001854 -0.4765000000000001 -0.00048828125 0.001074218750001854 -0.476625 -0.00048828125 0.001074218750001854 -0.47675 -0.00048828125 0.001074218750001854 -0.476875 -0.00048828125 0.001074218750001854 -0.477 -0.00048828125 0.001074218750001854 -0.477125 -0.00048828125 0.001074218750001854 -0.47725 -0.00048828125 0.001074218750001854 -0.477375 -0.00048828125 0.001074218750001854 -0.4775 -0.00048828125 0.001074218750001854 -0.477625 -0.00048828125 0.001074218750001854 -0.47775 -0.00048828125 0.001074218750001854 -0.477875 -0.00048828125 0.001074218750001854 -0.478 -0.00048828125 0.001074218750001854 -0.478125 -0.00048828125 0.001074218750001854 -0.47825 -0.00048828125 0.001074218750001854 -0.478375 -0.00048828125 0.001074218750001854 -0.4785 -0.000457763671875 0.001074218750001854 -0.478625 -0.000457763671875 0.001074218750001854 -0.47875 -0.000457763671875 0.001074218750001854 -0.478875 -0.000457763671875 0.001074218750001854 -0.479 -0.000457763671875 0.001074218750001854 -0.479125 -0.000457763671875 0.001074218750001854 -0.47925 -0.000457763671875 0.001074218750001854 -0.479375 -0.000457763671875 0.001074218750001854 -0.4795 -0.000457763671875 0.001074218750001854 -0.4796250000000001 -0.000457763671875 0.001074218750001854 -0.47975 -0.000457763671875 0.001074218750001854 -0.479875 -0.000457763671875 0.001074218750001854 -0.48 -0.135162353515625 0.3201562500000024 -0.480125 -0.134246826171875 0.3201562500000024 -0.48025 -0.134246826171875 0.3201562500000024 -0.480375 -0.133331298828125 0.3201562500000024 -0.4805 -0.13238525390625 0.3201562500000024 -0.480625 -0.13238525390625 0.3201562500000024 -0.48075 -0.131439208984375 0.3201562500000024 -0.480875 -0.131439208984375 0.3201562500000024 -0.481 -0.1304931640625 0.3201562500000024 -0.481125 -0.1295166015625 0.3201562500000024 -0.48125 -0.1295166015625 0.3201562500000024 -0.481375 -0.128509521484375 0.3201562500000024 -0.4815 -0.128509521484375 0.3201562500000024 -0.481625 -0.12750244140625 0.3201562500000024 -0.48175 -0.126495361328125 0.3201562500000024 -0.481875 -0.126495361328125 0.3201562500000024 -0.482 -0.125457763671875 0.3201562500000024 -0.482125 -0.125457763671875 0.3201562500000024 -0.48225 -0.1243896484375 0.3201562500000024 -0.482375 -0.12335205078125 0.3201562500000024 -0.4825 -0.12335205078125 0.3201562500000024 -0.482625 -0.12225341796875 0.3201562500000024 -0.4827500000000001 -0.12225341796875 0.3201562500000024 -0.482875 -0.121185302734375 0.3201562500000024 -0.483 -0.120086669921875 0.3201562500000024 -0.4831250000000001 -0.120086669921875 0.3201562500000024 -0.48325 -0.11895751953125 0.3201562500000024 -0.483375 -0.11895751953125 0.3201562500000024 -0.4835 -0.117828369140625 0.3201562500000024 -0.4836250000000001 -0.11669921875 0.3201562500000024 -0.48375 -0.11669921875 0.3201562500000024 -0.483875 -0.11553955078125 0.3201562500000024 -0.484 -0.11553955078125 0.3201562500000024 -0.484125 -0.1143798828125 0.3201562500000024 -0.48425 -0.113189697265625 0.3201562500000024 -0.484375 -0.113189697265625 0.3201562500000024 -0.4845 -0.11199951171875 0.3201562500000024 -0.484625 -0.11199951171875 0.3201562500000024 -0.48475 -0.110809326171875 0.3201562500000024 -0.484875 -0.109588623046875 0.3201562500000024 -0.485 -0.109588623046875 0.3201562500000024 -0.485125 -0.108367919921875 0.3201562500000024 -0.48525 -0.108367919921875 0.3201562500000024 -0.485375 -0.10711669921875 0.3201562500000024 -0.4855 -0.105865478515625 0.3201562500000024 -0.485625 -0.105865478515625 0.3201562500000024 -0.48575 -0.104583740234375 0.3201562500000024 -0.485875 -0.104583740234375 0.3201562500000024 -0.4859999999999999 -0.10333251953125 0.3201562500000024 -0.486125 -0.10205078125 0.3201562500000024 -0.48625 -0.10205078125 0.3201562500000024 -0.486375 -0.100738525390625 0.3201562500000024 -0.4865 -0.100738525390625 0.3201562500000024 -0.486625 -0.09942626953125 0.3201562500000024 -0.48675 -0.098114013671875 0.3201562500000024 -0.486875 -0.098114013671875 0.3201562500000024 -0.487 -0.096771240234375 0.3201562500000024 -0.487125 -0.096771240234375 0.3201562500000024 -0.48725 -0.095458984375 0.3201562500000024 -0.487375 -0.094085693359375 0.3201562500000024 -0.4875 -0.094085693359375 0.3201562500000024 -0.4876250000000001 -0.092742919921875 0.3201562500000024 -0.48775 -0.092742919921875 0.3201562500000024 -0.487875 -0.09136962890625 0.3201562500000024 -0.488 -0.0899658203125 0.3201562500000024 -0.4881250000000001 -0.0899658203125 0.3201562500000024 -0.48825 -0.088592529296875 0.3201562500000024 -0.488375 -0.088592529296875 0.3201562500000024 -0.4885 -0.087188720703125 0.3201562500000024 -0.488625 -0.085784912109375 0.3201562500000024 -0.48875 -0.085784912109375 0.3201562500000024 -0.488875 -0.0843505859375 0.3201562500000024 -0.489 -0.0843505859375 0.3201562500000024 -0.489125 -0.082916259765625 0.3201562500000024 -0.48925 -0.08148193359375 0.3201562500000024 -0.489375 -0.08148193359375 0.3201562500000024 -0.4895 -0.080047607421875 0.3201562500000024 -0.489625 -0.080047607421875 0.3201562500000024 -0.48975 -0.078582763671875 0.3201562500000024 -0.489875 -0.077117919921875 0.3201562500000024 -0.49 -0.077117919921875 0.3201562500000024 -0.490125 -0.075653076171875 0.3201562500000024 -0.49025 -0.075653076171875 0.3201562500000024 -0.490375 -0.07415771484375 0.3201562500000024 -0.4905 -0.072662353515625 0.3201562500000024 -0.490625 -0.072662353515625 0.3201562500000024 -0.4907500000000001 -0.0711669921875 0.3201562500000024 -0.490875 -0.0711669921875 0.3201562500000024 -0.491 -0.069671630859375 0.3201562500000024 -0.4911250000000001 -0.06817626953125 0.3201562500000024 -0.4912500000000001 -0.06817626953125 0.3201562500000024 -0.491375 -0.066650390625 0.3201562500000024 -0.4915 -0.066650390625 0.3201562500000024 -0.4916250000000001 -0.06512451171875 0.3201562500000024 -0.49175 -0.063568115234375 0.3201562500000024 -0.491875 -0.063568115234375 0.3201562500000024 -0.492 -0.062042236328125 0.3201562500000024 -0.4921250000000001 -0.062042236328125 0.3201562500000024 -0.49225 -0.06048583984375 0.3201562500000024 -0.492375 -0.058929443359375 0.3201562500000024 -0.4925 -0.058929443359375 0.3201562500000024 -0.492625 -0.057373046875 0.3201562500000024 -0.49275 -0.057373046875 0.3201562500000024 -0.492875 -0.055816650390625 0.3201562500000024 -0.493 -0.054229736328125 0.3201562500000024 -0.493125 -0.054229736328125 0.3201562500000024 -0.49325 -0.052642822265625 0.3201562500000024 -0.493375 -0.052642822265625 0.3201562500000024 -0.4935 -0.051055908203125 0.3201562500000024 -0.493625 -0.049468994140625 0.3201562500000024 -0.49375 -0.049468994140625 0.3201562500000024 -0.493875 -0.047882080078125 0.3201562500000024 -0.494 -0.047882080078125 0.3201562500000024 -0.494125 -0.0462646484375 0.3201562500000024 -0.49425 -0.044677734375 0.3201562500000024 -0.494375 -0.044677734375 0.3201562500000024 -0.4945 -0.043060302734375 0.3201562500000024 -0.494625 -0.043060302734375 0.3201562500000024 -0.49475 -0.04144287109375 0.3201562500000024 -0.494875 -0.039825439453125 0.3201562500000024 -0.495 -0.039825439453125 0.3201562500000024 -0.495125 -0.0382080078125 0.3201562500000024 -0.4952500000000001 -0.0382080078125 0.3201562500000024 -0.495375 -0.03656005859375 0.3201562500000024 -0.4955 -0.034912109375 0.3201562500000024 -0.4956250000000001 -0.034912109375 0.3201562500000024 -0.49575 -0.033294677734375 0.3201562500000024 -0.495875 -0.033294677734375 0.3201562500000024 -0.496 -0.031646728515625 0.3201562500000024 -0.496125 -0.029998779296875 0.3201562500000024 -0.49625 -0.029998779296875 0.3201562500000024 -0.496375 -0.028350830078125 0.3201562500000024 -0.4965 -0.028350830078125 0.3201562500000024 -0.496625 -0.026702880859375 0.3201562500000024 -0.49675 -0.025054931640625 0.3201562500000024 -0.496875 -0.025054931640625 0.3201562500000024 -0.497 -0.023406982421875 0.3201562500000024 -0.497125 -0.023406982421875 0.3201562500000024 -0.49725 -0.021728515625 0.3201562500000024 -0.497375 -0.02008056640625 0.3201562500000024 -0.4975 -0.02008056640625 0.3201562500000024 -0.497625 -0.018402099609375 0.3201562500000024 -0.49775 -0.018402099609375 0.3201562500000024 -0.497875 -0.016754150390625 0.3201562500000024 -0.498 -0.01507568359375 0.3201562500000024 -0.498125 -0.01507568359375 0.3201562500000024 -0.49825 -0.013397216796875 0.3201562500000024 -0.4983750000000001 -0.013397216796875 0.3201562500000024 -0.4985 -0.01171875 0.3201562500000024 -0.498625 -0.01007080078125 0.3201562500000024 -0.4987500000000001 -0.01007080078125 0.3201562500000024 -0.498875 -0.008392333984375 0.3201562500000024 -0.499 -0.008392333984375 0.3201562500000024 -0.499125 -0.0067138671875 0.3201562500000024 -0.4992500000000001 -0.005035400390625 0.3201562500000024 -0.499375 -0.005035400390625 0.3201562500000024 -0.4995 -0.00335693359375 0.3201562500000024 -0.499625 -0.00335693359375 0.3201562500000024 -0.49975 -0.001678466796875 0.3201562500000024 +0.448 -0.000244140625 0.001074218750001854 +0.448125 -0.000244140625 0.001074218750001854 +0.44825 -0.000244140625 0.001074218750001854 +0.4483750000000001 -0.000244140625 0.001074218750001854 +0.4485 -0.000244140625 0.001074218750001854 +0.448625 -0.000274658203125 0.001074218750001854 +0.44875 -0.000274658203125 0.001074218750001854 +0.448875 -0.000274658203125 0.001074218750001854 +0.449 -0.000274658203125 0.001074218750001854 +0.449125 -0.000274658203125 0.001074218750001854 +0.44925 -0.000274658203125 0.001074218750001854 +0.449375 -0.000274658203125 0.001074218750001854 +0.4495 -0.000274658203125 0.001074218750001854 +0.449625 -0.000274658203125 0.001074218750001854 +0.44975 -0.000274658203125 0.001074218750001854 +0.449875 -0.000274658203125 0.001074218750001854 +0.45 -0.000274658203125 0.001074218750001854 +0.450125 -0.00030517578125 0.001074218750001854 +0.45025 -0.00030517578125 0.001074218750001854 +0.450375 -0.00030517578125 0.001074218750001854 +0.4505 -0.00030517578125 0.001074218750001854 +0.450625 -0.00030517578125 0.001074218750001854 +0.45075 -0.00030517578125 0.001074218750001854 +0.450875 -0.00030517578125 0.001074218750001854 +0.451 -0.00030517578125 0.001074218750001854 +0.451125 -0.00030517578125 0.001074218750001854 +0.45125 -0.00030517578125 0.001074218750001854 +0.451375 -0.00030517578125 0.001074218750001854 +0.4515000000000001 -0.00030517578125 0.001074218750001854 +0.451625 -0.000335693359375 0.001074218750001854 +0.45175 -0.000335693359375 0.001074218750001854 +0.4518750000000001 -0.000335693359375 0.001074218750001854 +0.452 -0.000335693359375 0.001074218750001854 +0.452125 -0.000335693359375 0.001074218750001854 +0.45225 -0.000335693359375 0.001074218750001854 +0.4523750000000001 -0.000335693359375 0.001074218750001854 +0.4525 -0.000335693359375 0.001074218750001854 +0.452625 -0.000335693359375 0.001074218750001854 +0.45275 -0.000335693359375 0.001074218750001854 +0.452875 -0.000335693359375 0.001074218750001854 +0.453 -0.0003662109375 0.001074218750001854 +0.453125 -0.0003662109375 0.001074218750001854 +0.45325 -0.0003662109375 0.001074218750001854 +0.453375 -0.0003662109375 0.001074218750001854 +0.4535 -0.0003662109375 0.001074218750001854 +0.453625 -0.0003662109375 0.001074218750001854 +0.45375 -0.0003662109375 0.001074218750001854 +0.453875 -0.0003662109375 0.001074218750001854 +0.454 -0.0003662109375 0.001074218750001854 +0.454125 -0.0003662109375 0.001074218750001854 +0.45425 -0.0003662109375 0.001074218750001854 +0.454375 -0.0003662109375 0.001074218750001854 +0.4545 -0.0003662109375 0.001074218750001854 +0.454625 -0.0003662109375 0.001074218750001854 +0.4547499999999999 -0.0003662109375 0.001074218750001854 +0.454875 -0.000396728515625 0.001074218750001854 +0.455 -0.000396728515625 0.001074218750001854 +0.455125 -0.000396728515625 0.001074218750001854 +0.45525 -0.000396728515625 0.001074218750001854 +0.455375 -0.000396728515625 0.001074218750001854 +0.4555 -0.000396728515625 0.001074218750001854 +0.455625 -0.000396728515625 0.001074218750001854 +0.45575 -0.000396728515625 0.001074218750001854 +0.455875 -0.000396728515625 0.001074218750001854 +0.456 -0.000396728515625 0.001074218750001854 +0.456125 -0.000396728515625 0.001074218750001854 +0.45625 -0.000396728515625 0.001074218750001854 +0.4563750000000001 -0.000396728515625 0.001074218750001854 +0.4565 -0.000396728515625 0.001074218750001854 +0.456625 -0.000396728515625 0.001074218750001854 +0.45675 -0.00042724609375 0.001074218750001854 +0.4568750000000001 -0.00042724609375 0.001074218750001854 +0.457 -0.00042724609375 0.001074218750001854 +0.457125 -0.00042724609375 0.001074218750001854 +0.45725 -0.00042724609375 0.001074218750001854 +0.457375 -0.00042724609375 0.001074218750001854 +0.4575 -0.00042724609375 0.001074218750001854 +0.457625 -0.00042724609375 0.001074218750001854 +0.45775 -0.00042724609375 0.001074218750001854 +0.457875 -0.00042724609375 0.001074218750001854 +0.458 -0.00042724609375 0.001074218750001854 +0.458125 -0.00042724609375 0.001074218750001854 +0.45825 -0.00042724609375 0.001074218750001854 +0.458375 -0.00042724609375 0.001074218750001854 +0.4585 -0.00042724609375 0.001074218750001854 +0.458625 -0.00042724609375 0.001074218750001854 +0.45875 -0.00042724609375 0.001074218750001854 +0.458875 -0.00042724609375 0.001074218750001854 +0.459 -0.00042724609375 0.001074218750001854 +0.459125 -0.000457763671875 0.001074218750001854 +0.45925 -0.000457763671875 0.001074218750001854 +0.459375 -0.000457763671875 0.001074218750001854 +0.4595000000000001 -0.000457763671875 0.001074218750001854 +0.459625 -0.000457763671875 0.001074218750001854 +0.45975 -0.000457763671875 0.001074218750001854 +0.4598750000000001 -0.000457763671875 0.001074218750001854 +0.4600000000000001 -0.000457763671875 0.001074218750001854 +0.460125 -0.000457763671875 0.001074218750001854 +0.46025 -0.000457763671875 0.001074218750001854 +0.4603750000000001 -0.000457763671875 0.001074218750001854 +0.4605 -0.000457763671875 0.001074218750001854 +0.460625 -0.000457763671875 0.001074218750001854 +0.46075 -0.000457763671875 0.001074218750001854 +0.4608750000000001 -0.000457763671875 0.001074218750001854 +0.461 -0.000457763671875 0.001074218750001854 +0.461125 -0.000457763671875 0.001074218750001854 +0.46125 -0.000457763671875 0.001074218750001854 +0.461375 -0.000457763671875 0.001074218750001854 +0.4615 -0.000457763671875 0.001074218750001854 +0.461625 -0.000457763671875 0.001074218750001854 +0.46175 -0.000457763671875 0.001074218750001854 +0.461875 -0.000457763671875 0.001074218750001854 +0.462 -0.00048828125 0.001074218750001854 +0.462125 -0.00048828125 0.001074218750001854 +0.46225 -0.00048828125 0.001074218750001854 +0.462375 -0.00048828125 0.001074218750001854 +0.4625 -0.00048828125 0.001074218750001854 +0.462625 -0.00048828125 0.001074218750001854 +0.46275 -0.00048828125 0.001074218750001854 +0.462875 -0.00048828125 0.001074218750001854 +0.463 -0.00048828125 0.001074218750001854 +0.463125 -0.00048828125 0.001074218750001854 +0.46325 -0.00048828125 0.001074218750001854 +0.463375 -0.00048828125 0.001074218750001854 +0.4635 -0.00048828125 0.001074218750001854 +0.463625 -0.00048828125 0.001074218750001854 +0.46375 -0.00048828125 0.001074218750001854 +0.463875 -0.00048828125 0.001074218750001854 +0.4640000000000001 -0.00048828125 0.001074218750001854 +0.464125 -0.00048828125 0.001074218750001854 +0.46425 -0.00048828125 0.001074218750001854 +0.464375 -0.00048828125 0.001074218750001854 +0.4645 -0.00048828125 0.001074218750001854 +0.464625 -0.00048828125 0.001074218750001854 +0.46475 -0.00048828125 0.001074218750001854 +0.464875 -0.00048828125 0.001074218750001854 +0.465 -0.00048828125 0.001074218750001854 +0.465125 -0.00048828125 0.001074218750001854 +0.46525 -0.00048828125 0.001074218750001854 +0.465375 -0.00048828125 0.001074218750001854 +0.4655 -0.00048828125 0.001074218750001854 +0.465625 -0.00048828125 0.001074218750001854 +0.46575 -0.00048828125 0.001074218750001854 +0.465875 -0.00048828125 0.001074218750001854 +0.466 -0.00048828125 0.001074218750001854 +0.466125 -0.00048828125 0.001074218750001854 +0.46625 -0.00048828125 0.001074218750001854 +0.466375 -0.00048828125 0.001074218750001854 +0.4665 -0.00048828125 0.001074218750001854 +0.466625 -0.00048828125 0.001074218750001854 +0.46675 -0.00048828125 0.001074218750001854 +0.466875 -0.00048828125 0.001074218750001854 +0.467 -0.00048828125 0.001074218750001854 +0.4671250000000001 -0.00048828125 0.001074218750001854 +0.46725 -0.00048828125 0.001074218750001854 +0.467375 -0.00048828125 0.001074218750001854 +0.4675000000000001 -0.00048828125 0.001074218750001854 +0.467625 -0.00048828125 0.001074218750001854 +0.46775 -0.00048828125 0.001074218750001854 +0.467875 -0.00048828125 0.001074218750001854 +0.4680000000000001 -0.00048828125 0.001074218750001854 +0.468125 -0.00048828125 0.001074218750001854 +0.46825 -0.00048828125 0.001074218750001854 +0.468375 -0.00048828125 0.001074218750001854 +0.4685 -0.00048828125 0.001074218750001854 +0.468625 -0.00048828125 0.001074218750001854 +0.46875 -0.00048828125 0.001074218750001854 +0.468875 -0.00048828125 0.001074218750001854 +0.469 -0.00048828125 0.001074218750001854 +0.469125 -0.00048828125 0.001074218750001854 +0.46925 -0.00048828125 0.001074218750001854 +0.469375 -0.00048828125 0.001074218750001854 +0.4695 -0.00048828125 0.001074218750001854 +0.469625 -0.00048828125 0.001074218750001854 +0.46975 -0.00048828125 0.001074218750001854 +0.469875 -0.00048828125 0.001074218750001854 +0.47 -0.00048828125 0.001074218750001854 +0.470125 -0.00048828125 0.001074218750001854 +0.47025 -0.00048828125 0.001074218750001854 +0.4703749999999999 -0.00048828125 0.001074218750001854 +0.4705 -0.00048828125 0.001074218750001854 +0.470625 -0.00048828125 0.001074218750001854 +0.47075 -0.00048828125 0.001074218750001854 +0.470875 -0.00048828125 0.001074218750001854 +0.471 -0.00048828125 0.001074218750001854 +0.471125 -0.00048828125 0.001074218750001854 +0.47125 -0.00048828125 0.001074218750001854 +0.471375 -0.00048828125 0.001074218750001854 +0.4715 -0.00048828125 0.001074218750001854 +0.471625 -0.00048828125 0.001074218750001854 +0.47175 -0.00048828125 0.001074218750001854 +0.471875 -0.00048828125 0.001074218750001854 +0.4720000000000001 -0.00048828125 0.001074218750001854 +0.472125 -0.00048828125 0.001074218750001854 +0.47225 -0.00048828125 0.001074218750001854 +0.472375 -0.00048828125 0.001074218750001854 +0.4725000000000001 -0.00048828125 0.001074218750001854 +0.472625 -0.00048828125 0.001074218750001854 +0.47275 -0.00048828125 0.001074218750001854 +0.472875 -0.00048828125 0.001074218750001854 +0.473 -0.00048828125 0.001074218750001854 +0.473125 -0.00048828125 0.001074218750001854 +0.47325 -0.00048828125 0.001074218750001854 +0.473375 -0.00048828125 0.001074218750001854 +0.4735 -0.00048828125 0.001074218750001854 +0.473625 -0.00048828125 0.001074218750001854 +0.47375 -0.00048828125 0.001074218750001854 +0.473875 -0.00048828125 0.001074218750001854 +0.474 -0.00048828125 0.001074218750001854 +0.474125 -0.00048828125 0.001074218750001854 +0.47425 -0.00048828125 0.001074218750001854 +0.474375 -0.00048828125 0.001074218750001854 +0.4745 -0.00048828125 0.001074218750001854 +0.474625 -0.00048828125 0.001074218750001854 +0.47475 -0.00048828125 0.001074218750001854 +0.474875 -0.00048828125 0.001074218750001854 +0.475 -0.00048828125 0.001074218750001854 +0.4751250000000001 -0.00048828125 0.001074218750001854 +0.47525 -0.00048828125 0.001074218750001854 +0.475375 -0.00048828125 0.001074218750001854 +0.4755000000000001 -0.000457763671875 0.001074218750001854 +0.4756250000000001 -0.000457763671875 0.001074218750001854 +0.47575 -0.000457763671875 0.001074218750001854 +0.475875 -0.000457763671875 0.001074218750001854 +0.4760000000000001 -0.000457763671875 0.001074218750001854 +0.476125 -0.000457763671875 0.001074218750001854 +0.47625 -0.000457763671875 0.001074218750001854 +0.476375 -0.000457763671875 0.001074218750001854 +0.4765000000000001 -0.000457763671875 0.001074218750001854 +0.476625 -0.000457763671875 0.001074218750001854 +0.47675 -0.000457763671875 0.001074218750001854 +0.476875 -0.000457763671875 0.001074218750001854 +0.477 -0.000457763671875 0.001074218750001854 +0.477125 -0.000457763671875 0.001074218750001854 +0.47725 -0.000457763671875 0.001074218750001854 +0.477375 -0.000457763671875 0.001074218750001854 +0.4775 -0.000457763671875 0.001074218750001854 +0.477625 -0.000457763671875 0.001074218750001854 +0.47775 -0.000457763671875 0.001074218750001854 +0.477875 -0.000457763671875 0.001074218750001854 +0.478 -0.000457763671875 0.001074218750001854 +0.478125 -0.000457763671875 0.001074218750001854 +0.47825 -0.000457763671875 0.001074218750001854 +0.478375 -0.000457763671875 0.001074218750001854 +0.4785 -0.00042724609375 0.001074218750001854 +0.478625 -0.00042724609375 0.001074218750001854 +0.47875 -0.00042724609375 0.001074218750001854 +0.478875 -0.00042724609375 0.001074218750001854 +0.479 -0.00042724609375 0.001074218750001854 +0.479125 -0.00042724609375 0.001074218750001854 +0.47925 -0.00042724609375 0.001074218750001854 +0.479375 -0.00042724609375 0.001074218750001854 +0.4795 -0.00042724609375 0.001074218750001854 +0.4796250000000001 -0.00042724609375 0.001074218750001854 +0.47975 -0.00042724609375 0.001074218750001854 +0.479875 -0.00042724609375 0.001074218750001854 +0.48 -0.1351318359375 0.3201562500000024 +0.480125 -0.13421630859375 0.3201562500000024 +0.48025 -0.13421630859375 0.3201562500000024 +0.480375 -0.13330078125 0.3201562500000024 +0.4805 -0.132354736328125 0.3201562500000024 +0.480625 -0.132354736328125 0.3201562500000024 +0.48075 -0.13140869140625 0.3201562500000024 +0.480875 -0.13140869140625 0.3201562500000024 +0.481 -0.130462646484375 0.3201562500000024 +0.481125 -0.129486083984375 0.3201562500000024 +0.48125 -0.129486083984375 0.3201562500000024 +0.481375 -0.12847900390625 0.3201562500000024 +0.4815 -0.12847900390625 0.3201562500000024 +0.481625 -0.127471923828125 0.3201562500000024 +0.48175 -0.12646484375 0.3201562500000024 +0.481875 -0.12646484375 0.3201562500000024 +0.482 -0.12542724609375 0.3201562500000024 +0.482125 -0.12542724609375 0.3201562500000024 +0.48225 -0.124359130859375 0.3201562500000024 +0.482375 -0.123321533203125 0.3201562500000024 +0.4825 -0.123321533203125 0.3201562500000024 +0.482625 -0.122222900390625 0.3201562500000024 +0.4827500000000001 -0.122222900390625 0.3201562500000024 +0.482875 -0.12115478515625 0.3201562500000024 +0.483 -0.12005615234375 0.3201562500000024 +0.4831250000000001 -0.12005615234375 0.3201562500000024 +0.48325 -0.118927001953125 0.3201562500000024 +0.483375 -0.118927001953125 0.3201562500000024 +0.4835 -0.1177978515625 0.3201562500000024 +0.4836250000000001 -0.116668701171875 0.3201562500000024 +0.48375 -0.116668701171875 0.3201562500000024 +0.483875 -0.115509033203125 0.3201562500000024 +0.484 -0.115509033203125 0.3201562500000024 +0.484125 -0.114349365234375 0.3201562500000024 +0.48425 -0.1131591796875 0.3201562500000024 +0.484375 -0.1131591796875 0.3201562500000024 +0.4845 -0.111968994140625 0.3201562500000024 +0.484625 -0.111968994140625 0.3201562500000024 +0.48475 -0.11077880859375 0.3201562500000024 +0.484875 -0.10955810546875 0.3201562500000024 +0.485 -0.10955810546875 0.3201562500000024 +0.485125 -0.10833740234375 0.3201562500000024 +0.48525 -0.10833740234375 0.3201562500000024 +0.485375 -0.107086181640625 0.3201562500000024 +0.4855 -0.1058349609375 0.3201562500000024 +0.485625 -0.1058349609375 0.3201562500000024 +0.48575 -0.10455322265625 0.3201562500000024 +0.485875 -0.10455322265625 0.3201562500000024 +0.4859999999999999 -0.103302001953125 0.3201562500000024 +0.486125 -0.102020263671875 0.3201562500000024 +0.48625 -0.102020263671875 0.3201562500000024 +0.486375 -0.1007080078125 0.3201562500000024 +0.4865 -0.1007080078125 0.3201562500000024 +0.486625 -0.099395751953125 0.3201562500000024 +0.48675 -0.09808349609375 0.3201562500000024 +0.486875 -0.09808349609375 0.3201562500000024 +0.487 -0.09674072265625 0.3201562500000024 +0.487125 -0.09674072265625 0.3201562500000024 +0.48725 -0.095428466796875 0.3201562500000024 +0.487375 -0.09405517578125 0.3201562500000024 +0.4875 -0.09405517578125 0.3201562500000024 +0.4876250000000001 -0.09271240234375 0.3201562500000024 +0.48775 -0.09271240234375 0.3201562500000024 +0.487875 -0.091339111328125 0.3201562500000024 +0.488 -0.089935302734375 0.3201562500000024 +0.4881250000000001 -0.089935302734375 0.3201562500000024 +0.48825 -0.08856201171875 0.3201562500000024 +0.488375 -0.08856201171875 0.3201562500000024 +0.4885 -0.087158203125 0.3201562500000024 +0.488625 -0.08575439453125 0.3201562500000024 +0.48875 -0.08575439453125 0.3201562500000024 +0.488875 -0.084320068359375 0.3201562500000024 +0.489 -0.084320068359375 0.3201562500000024 +0.489125 -0.0828857421875 0.3201562500000024 +0.48925 -0.081451416015625 0.3201562500000024 +0.489375 -0.081451416015625 0.3201562500000024 +0.4895 -0.08001708984375 0.3201562500000024 +0.489625 -0.08001708984375 0.3201562500000024 +0.48975 -0.07855224609375 0.3201562500000024 +0.489875 -0.07708740234375 0.3201562500000024 +0.49 -0.07708740234375 0.3201562500000024 +0.490125 -0.07562255859375 0.3201562500000024 +0.49025 -0.07562255859375 0.3201562500000024 +0.490375 -0.074127197265625 0.3201562500000024 +0.4905 -0.0726318359375 0.3201562500000024 +0.490625 -0.0726318359375 0.3201562500000024 +0.4907500000000001 -0.071136474609375 0.3201562500000024 +0.490875 -0.071136474609375 0.3201562500000024 +0.491 -0.06964111328125 0.3201562500000024 +0.4911250000000001 -0.068145751953125 0.3201562500000024 +0.4912500000000001 -0.068145751953125 0.3201562500000024 +0.491375 -0.066619873046875 0.3201562500000024 +0.4915 -0.066619873046875 0.3201562500000024 +0.4916250000000001 -0.065093994140625 0.3201562500000024 +0.49175 -0.06353759765625 0.3201562500000024 +0.491875 -0.06353759765625 0.3201562500000024 +0.492 -0.06201171875 0.3201562500000024 +0.4921250000000001 -0.06201171875 0.3201562500000024 +0.49225 -0.060455322265625 0.3201562500000024 +0.492375 -0.05889892578125 0.3201562500000024 +0.4925 -0.05889892578125 0.3201562500000024 +0.492625 -0.057342529296875 0.3201562500000024 +0.49275 -0.057342529296875 0.3201562500000024 +0.492875 -0.0557861328125 0.3201562500000024 +0.493 -0.05419921875 0.3201562500000024 +0.493125 -0.05419921875 0.3201562500000024 +0.49325 -0.0526123046875 0.3201562500000024 +0.493375 -0.0526123046875 0.3201562500000024 +0.4935 -0.051025390625 0.3201562500000024 +0.493625 -0.0494384765625 0.3201562500000024 +0.49375 -0.0494384765625 0.3201562500000024 +0.493875 -0.0478515625 0.3201562500000024 +0.494 -0.0478515625 0.3201562500000024 +0.494125 -0.046234130859375 0.3201562500000024 +0.49425 -0.044647216796875 0.3201562500000024 +0.494375 -0.044647216796875 0.3201562500000024 +0.4945 -0.04302978515625 0.3201562500000024 +0.494625 -0.04302978515625 0.3201562500000024 +0.49475 -0.041412353515625 0.3201562500000024 +0.494875 -0.039794921875 0.3201562500000024 +0.495 -0.039794921875 0.3201562500000024 +0.495125 -0.038177490234375 0.3201562500000024 +0.4952500000000001 -0.038177490234375 0.3201562500000024 +0.495375 -0.036529541015625 0.3201562500000024 +0.4955 -0.034881591796875 0.3201562500000024 +0.4956250000000001 -0.034881591796875 0.3201562500000024 +0.49575 -0.03326416015625 0.3201562500000024 +0.495875 -0.03326416015625 0.3201562500000024 +0.496 -0.0316162109375 0.3201562500000024 +0.496125 -0.02996826171875 0.3201562500000024 +0.49625 -0.02996826171875 0.3201562500000024 +0.496375 -0.0283203125 0.3201562500000024 +0.4965 -0.0283203125 0.3201562500000024 +0.496625 -0.02667236328125 0.3201562500000024 +0.49675 -0.0250244140625 0.3201562500000024 +0.496875 -0.0250244140625 0.3201562500000024 +0.497 -0.02337646484375 0.3201562500000024 +0.497125 -0.02337646484375 0.3201562500000024 +0.49725 -0.021697998046875 0.3201562500000024 +0.497375 -0.020050048828125 0.3201562500000024 +0.4975 -0.020050048828125 0.3201562500000024 +0.497625 -0.01837158203125 0.3201562500000024 +0.49775 -0.01837158203125 0.3201562500000024 +0.497875 -0.0167236328125 0.3201562500000024 +0.498 -0.015045166015625 0.3201562500000024 +0.498125 -0.015045166015625 0.3201562500000024 +0.49825 -0.01336669921875 0.3201562500000024 +0.4983750000000001 -0.01336669921875 0.3201562500000024 +0.4985 -0.011688232421875 0.3201562500000024 +0.498625 -0.010040283203125 0.3201562500000024 +0.4987500000000001 -0.010040283203125 0.3201562500000024 +0.498875 -0.00836181640625 0.3201562500000024 +0.499 -0.00836181640625 0.3201562500000024 +0.499125 -0.006683349609375 0.3201562500000024 +0.4992500000000001 -0.0050048828125 0.3201562500000024 +0.499375 -0.0050048828125 0.3201562500000024 +0.4995 -0.003326416015625 0.3201562500000024 +0.499625 -0.003326416015625 0.3201562500000024 +0.49975 -0.00164794921875 0.3201562500000024 0.499875 0.0 0.3201562500000024 0.5 0.0 0.3201562500000024 0.5001250000000001 0.00164794921875 0.3201562500000024 @@ -4499,504 +4499,504 @@ 0.56225 0.00445556640625 0.8530371093750013 0.5623749999999999 0.0 0.8530371093750013 0.5625 0.0 0.8530371093750013 -0.5626250000000001 -0.004486083984375 0.8530371093750013 -0.56275 -0.004486083984375 0.8530371093750013 -0.562875 -0.008941650390625 0.8530371093750013 -0.5630000000000001 -0.013397216796875 0.8530371093750013 -0.563125 -0.013397216796875 0.8530371093750013 -0.56325 -0.01788330078125 0.8530371093750013 -0.5633749999999999 -0.01788330078125 0.8530371093750013 -0.5635 -0.0223388671875 0.8530371093750013 -0.563625 -0.02679443359375 0.8530371093750013 -0.5637499999999999 -0.02679443359375 0.8530371093750013 -0.563875 -0.03125 0.8530371093750013 -0.5640000000000001 -0.03125 0.8530371093750013 -0.5641249999999999 -0.03570556640625 0.8530371093750013 -0.56425 -0.040130615234375 0.8530371093750013 -0.564375 -0.040130615234375 0.8530371093750013 -0.5645 -0.044586181640625 0.8530371093750013 -0.564625 -0.044586181640625 0.8530371093750013 -0.56475 -0.049041748046875 0.8530371093750013 -0.564875 -0.053466796875 0.8530371093750013 -0.565 -0.053466796875 0.8530371093750013 -0.565125 -0.057891845703125 0.8530371093750013 -0.56525 -0.057891845703125 0.8530371093750013 -0.565375 -0.06231689453125 0.8530371093750013 -0.5655 -0.06671142578125 0.8530371093750013 -0.565625 -0.06671142578125 0.8530371093750013 -0.56575 -0.071136474609375 0.8530371093750013 -0.565875 -0.071136474609375 0.8530371093750013 -0.566 -0.075531005859375 0.8530371093750013 -0.566125 -0.079925537109375 0.8530371093750013 -0.5662500000000001 -0.079925537109375 0.8530371093750013 -0.5663749999999999 -0.084320068359375 0.8530371093750013 -0.5665 -0.084320068359375 0.8530371093750013 -0.5666250000000001 -0.08868408203125 0.8530371093750013 -0.56675 -0.093048095703125 0.8530371093750013 -0.566875 -0.093048095703125 0.8530371093750013 -0.5670000000000001 -0.097412109375 0.8530371093750013 -0.567125 -0.097412109375 0.8530371093750013 -0.56725 -0.10174560546875 0.8530371093750013 -0.567375 -0.1060791015625 0.8530371093750013 -0.5675 -0.1060791015625 0.8530371093750013 -0.567625 -0.110382080078125 0.8530371093750013 -0.56775 -0.110382080078125 0.8530371093750013 -0.567875 -0.11468505859375 0.8530371093750013 -0.5680000000000001 -0.118988037109375 0.8530371093750013 -0.568125 -0.118988037109375 0.8530371093750013 -0.56825 -0.123260498046875 0.8530371093750013 -0.568375 -0.123260498046875 0.8530371093750013 -0.5685 -0.127532958984375 0.8530371093750013 -0.568625 -0.131805419921875 0.8530371093750013 -0.56875 -0.131805419921875 0.8530371093750013 -0.5688750000000001 -0.13604736328125 0.8530371093750013 -0.569 -0.13604736328125 0.8530371093750013 -0.569125 -0.1402587890625 0.8530371093750013 -0.5692500000000001 -0.14447021484375 0.8530371093750013 -0.569375 -0.14447021484375 0.8530371093750013 -0.5695 -0.148681640625 0.8530371093750013 -0.5696250000000001 -0.148681640625 0.8530371093750013 -0.56975 -0.15283203125 0.8530371093750013 -0.569875 -0.157012939453125 0.8530371093750013 -0.5700000000000001 -0.157012939453125 0.8530371093750013 -0.570125 -0.161163330078125 0.8530371093750013 -0.5702500000000001 -0.161163330078125 0.8530371093750013 -0.5703749999999999 -0.165283203125 0.8530371093750013 -0.5705 -0.169403076171875 0.8530371093750013 -0.5706250000000001 -0.169403076171875 0.8530371093750013 -0.57075 -0.1734619140625 0.8530371093750013 -0.570875 -0.1734619140625 0.8530371093750013 -0.5710000000000001 -0.17755126953125 0.8530371093750013 -0.571125 -0.181610107421875 0.8530371093750013 -0.57125 -0.181610107421875 0.8530371093750013 -0.5713749999999999 -0.185638427734375 0.8530371093750013 -0.5715 -0.185638427734375 0.8530371093750013 -0.571625 -0.18963623046875 0.8530371093750013 -0.5717499999999999 -0.193634033203125 0.8530371093750013 -0.571875 -0.193634033203125 0.8530371093750013 -0.5720000000000001 -0.197601318359375 0.8530371093750013 -0.572125 -0.197601318359375 0.8530371093750013 -0.57225 -0.2015380859375 0.8530371093750013 -0.572375 -0.205474853515625 0.8530371093750013 -0.5725 -0.205474853515625 0.8530371093750013 -0.572625 -0.209381103515625 0.8530371093750013 -0.57275 -0.209381103515625 0.8530371093750013 -0.572875 -0.2132568359375 0.8530371093750013 -0.573 -0.21710205078125 0.8530371093750013 -0.573125 -0.21710205078125 0.8530371093750013 -0.57325 -0.220947265625 0.8530371093750013 -0.573375 -0.220947265625 0.8530371093750013 -0.5735 -0.2247314453125 0.8530371093750013 -0.573625 -0.228546142578125 0.8530371093750013 -0.57375 -0.228546142578125 0.8530371093750013 -0.573875 -0.2322998046875 0.8530371093750013 -0.574 -0.2322998046875 0.8530371093750013 -0.574125 -0.23602294921875 0.8530371093750013 -0.5742500000000001 -0.239715576171875 0.8530371093750013 -0.5743749999999999 -0.239715576171875 0.8530371093750013 -0.5745 -0.243408203125 0.8530371093750013 -0.5746250000000001 -0.243408203125 0.8530371093750013 -0.57475 -0.2470703125 0.8530371093750013 -0.574875 -0.25067138671875 0.8530371093750013 -0.5750000000000001 -0.25067138671875 0.8530371093750013 -0.575125 -0.254302978515625 0.8530371093750013 -0.57525 -0.254302978515625 0.8530371093750013 -0.575375 -0.257843017578125 0.8530371093750013 -0.5755 -0.26141357421875 0.8530371093750013 -0.5756250000000001 -0.26141357421875 0.8530371093750013 -0.57575 -0.264923095703125 0.8530371093750013 -0.575875 -0.264923095703125 0.8530371093750013 -0.5760000000000001 -0.30889892578125 0.9817578125000006 -0.576125 -0.312896728515625 0.9817578125000006 -0.57625 -0.312896728515625 0.9817578125000006 -0.576375 -0.31683349609375 0.9817578125000006 -0.5765000000000001 -0.31683349609375 0.9817578125000006 -0.576625 -0.32073974609375 0.9817578125000006 -0.57675 -0.324615478515625 0.9817578125000006 -0.5768750000000001 -0.324615478515625 0.9817578125000006 -0.577 -0.328460693359375 0.9817578125000006 -0.577125 -0.328460693359375 0.9817578125000006 -0.5772500000000001 -0.332244873046875 0.9817578125000006 -0.577375 -0.33599853515625 0.9817578125000006 -0.5775 -0.33599853515625 0.9817578125000006 -0.5776250000000001 -0.339752197265625 0.9817578125000006 -0.57775 -0.339752197265625 0.9817578125000006 -0.577875 -0.343414306640625 0.9817578125000006 -0.5779999999999999 -0.347076416015625 0.9817578125000006 -0.578125 -0.347076416015625 0.9817578125000006 -0.5782500000000001 -0.3507080078125 0.9817578125000006 -0.578375 -0.3507080078125 0.9817578125000006 -0.5785 -0.354278564453125 0.9817578125000006 -0.5786250000000001 -0.357818603515625 0.9817578125000006 -0.57875 -0.357818603515625 0.9817578125000006 -0.578875 -0.361328125 0.9817578125000006 -0.5789999999999999 -0.361328125 0.9817578125000006 -0.579125 -0.364776611328125 0.9817578125000006 -0.57925 -0.368194580078125 0.9817578125000006 -0.5793749999999999 -0.368194580078125 0.9817578125000006 -0.5795 -0.37158203125 0.9817578125000006 -0.5796250000000001 -0.37158203125 0.9817578125000006 -0.5797499999999999 -0.374908447265625 0.9817578125000006 -0.579875 -0.378204345703125 0.9817578125000006 -0.58 -0.378204345703125 0.9817578125000006 -0.580125 -0.3814697265625 0.9817578125000006 -0.58025 -0.3814697265625 0.9817578125000006 -0.580375 -0.384674072265625 0.9817578125000006 -0.5805 -0.387847900390625 0.9817578125000006 -0.580625 -0.387847900390625 0.9817578125000006 -0.58075 -0.390960693359375 0.9817578125000006 -0.580875 -0.390960693359375 0.9817578125000006 -0.581 -0.394073486328125 0.9817578125000006 -0.581125 -0.397125244140625 0.9817578125000006 -0.58125 -0.397125244140625 0.9817578125000006 -0.581375 -0.400115966796875 0.9817578125000006 -0.5815 -0.400115966796875 0.9817578125000006 -0.581625 -0.403076171875 0.9817578125000006 -0.58175 -0.405975341796875 0.9817578125000006 -0.5818750000000001 -0.405975341796875 0.9817578125000006 -0.5819999999999999 -0.408843994140625 0.9817578125000006 -0.582125 -0.408843994140625 0.9817578125000006 -0.5822500000000001 -0.411651611328125 0.9817578125000006 -0.582375 -0.414459228515625 0.9817578125000006 -0.5825 -0.414459228515625 0.9817578125000006 -0.5826250000000001 -0.41717529296875 0.9817578125000006 -0.58275 -0.41717529296875 0.9817578125000006 -0.582875 -0.41986083984375 0.9817578125000006 -0.583 -0.4224853515625 0.9817578125000006 -0.583125 -0.4224853515625 0.9817578125000006 -0.58325 -0.42510986328125 0.9817578125000006 -0.583375 -0.42510986328125 0.9817578125000006 -0.5835 -0.427642822265625 0.9817578125000006 -0.5836250000000001 -0.430145263671875 0.9817578125000006 -0.58375 -0.430145263671875 0.9817578125000006 -0.583875 -0.432586669921875 0.9817578125000006 -0.584 -0.432586669921875 0.9817578125000006 -0.584125 -0.43499755859375 0.9817578125000006 -0.58425 -0.437347412109375 0.9817578125000006 -0.584375 -0.437347412109375 0.9817578125000006 -0.5845000000000001 -0.439666748046875 0.9817578125000006 -0.584625 -0.439666748046875 0.9817578125000006 -0.58475 -0.441925048828125 0.9817578125000006 -0.5848750000000001 -0.44415283203125 0.9817578125000006 -0.585 -0.44415283203125 0.9817578125000006 -0.585125 -0.4462890625 0.9817578125000006 -0.5852500000000001 -0.4462890625 0.9817578125000006 -0.585375 -0.44842529296875 0.9817578125000006 -0.5855 -0.45050048828125 0.9817578125000006 -0.5856250000000001 -0.45050048828125 0.9817578125000006 -0.58575 -0.452484130859375 0.9817578125000006 -0.5858750000000001 -0.452484130859375 0.9817578125000006 -0.5859999999999999 -0.4544677734375 0.9817578125000006 -0.586125 -0.456390380859375 0.9817578125000006 -0.5862500000000001 -0.456390380859375 0.9817578125000006 -0.586375 -0.458251953125 0.9817578125000006 -0.5865 -0.458251953125 0.9817578125000006 -0.5866250000000001 -0.460052490234375 0.9817578125000006 -0.58675 -0.461822509765625 0.9817578125000006 -0.586875 -0.461822509765625 0.9817578125000006 -0.5869999999999999 -0.46356201171875 0.9817578125000006 -0.587125 -0.46356201171875 0.9817578125000006 -0.58725 -0.4652099609375 0.9817578125000006 -0.5873749999999999 -0.466827392578125 0.9817578125000006 -0.5875 -0.466827392578125 0.9817578125000006 -0.5876250000000001 -0.4683837890625 0.9817578125000006 -0.58775 -0.4683837890625 0.9817578125000006 -0.587875 -0.46990966796875 0.9817578125000006 -0.588 -0.471343994140625 0.9817578125000006 -0.588125 -0.471343994140625 0.9817578125000006 -0.58825 -0.4727783203125 0.9817578125000006 -0.588375 -0.4727783203125 0.9817578125000006 -0.5885 -0.47412109375 0.9817578125000006 -0.588625 -0.475433349609375 0.9817578125000006 -0.58875 -0.475433349609375 0.9817578125000006 -0.588875 -0.4766845703125 0.9817578125000006 -0.589 -0.4766845703125 0.9817578125000006 -0.589125 -0.477874755859375 0.9817578125000006 -0.58925 -0.479034423828125 0.9817578125000006 -0.589375 -0.479034423828125 0.9817578125000006 -0.5895 -0.480133056640625 0.9817578125000006 -0.589625 -0.480133056640625 0.9817578125000006 -0.58975 -0.481170654296875 0.9817578125000006 -0.5898750000000001 -0.482147216796875 0.9817578125000006 -0.5899999999999999 -0.482147216796875 0.9817578125000006 -0.590125 -0.48309326171875 0.9817578125000006 -0.5902500000000001 -0.48309326171875 0.9817578125000006 -0.590375 -0.483978271484375 0.9817578125000006 -0.5905 -0.48480224609375 0.9817578125000006 -0.5906250000000001 -0.48480224609375 0.9817578125000006 -0.59075 -0.485595703125 0.9817578125000006 -0.590875 -0.485595703125 0.9817578125000006 -0.591 -0.486297607421875 0.9817578125000006 -0.591125 -0.486968994140625 0.9817578125000006 -0.5912500000000001 -0.486968994140625 0.9817578125000006 -0.591375 -0.48760986328125 0.9817578125000006 -0.5915 -0.48760986328125 0.9817578125000006 -0.5916250000000001 -0.4881591796875 0.9817578125000006 -0.59175 -0.488677978515625 0.9817578125000006 -0.591875 -0.488677978515625 0.9817578125000006 -0.592 -0.4891357421875 0.9817578125000006 -0.5921250000000001 -0.4891357421875 0.9817578125000006 -0.59225 -0.489532470703125 0.9817578125000006 -0.592375 -0.489898681640625 0.9817578125000006 -0.5925000000000001 -0.489898681640625 0.9817578125000006 -0.592625 -0.49017333984375 0.9817578125000006 -0.59275 -0.49017333984375 0.9817578125000006 -0.5928750000000001 -0.49041748046875 0.9817578125000006 -0.593 -0.4906005859375 0.9817578125000006 -0.593125 -0.4906005859375 0.9817578125000006 -0.5932500000000001 -0.490753173828125 0.9817578125000006 -0.593375 -0.490753173828125 0.9817578125000006 -0.5935 -0.4908447265625 0.9817578125000006 -0.5936249999999999 -0.490875244140625 0.9817578125000006 -0.59375 -0.490875244140625 0.9817578125000006 -0.5938750000000001 -0.4908447265625 0.9817578125000006 -0.594 -0.4908447265625 0.9817578125000006 -0.594125 -0.490753173828125 0.9817578125000006 -0.5942500000000001 -0.4906005859375 0.9817578125000006 -0.594375 -0.4906005859375 0.9817578125000006 -0.5945 -0.49041748046875 0.9817578125000006 -0.5946249999999999 -0.49041748046875 0.9817578125000006 -0.59475 -0.49017333984375 0.9817578125000006 -0.594875 -0.489898681640625 0.9817578125000006 -0.5949999999999999 -0.489898681640625 0.9817578125000006 -0.595125 -0.489532470703125 0.9817578125000006 -0.5952500000000001 -0.489532470703125 0.9817578125000006 -0.5953749999999999 -0.4891357421875 0.9817578125000006 -0.5955 -0.488677978515625 0.9817578125000006 -0.595625 -0.488677978515625 0.9817578125000006 -0.59575 -0.4881591796875 0.9817578125000006 -0.595875 -0.4881591796875 0.9817578125000006 -0.596 -0.48760986328125 0.9817578125000006 -0.596125 -0.486968994140625 0.9817578125000006 -0.59625 -0.486968994140625 0.9817578125000006 -0.596375 -0.486297607421875 0.9817578125000006 -0.5965 -0.486297607421875 0.9817578125000006 -0.596625 -0.485595703125 0.9817578125000006 -0.59675 -0.48480224609375 0.9817578125000006 -0.596875 -0.48480224609375 0.9817578125000006 -0.597 -0.483978271484375 0.9817578125000006 -0.597125 -0.483978271484375 0.9817578125000006 -0.59725 -0.48309326171875 0.9817578125000006 -0.597375 -0.482147216796875 0.9817578125000006 -0.5975000000000001 -0.482147216796875 0.9817578125000006 -0.5976249999999999 -0.481170654296875 0.9817578125000006 -0.59775 -0.481170654296875 0.9817578125000006 -0.5978750000000001 -0.480133056640625 0.9817578125000006 -0.598 -0.479034423828125 0.9817578125000006 -0.598125 -0.479034423828125 0.9817578125000006 -0.5982500000000001 -0.477874755859375 0.9817578125000006 -0.598375 -0.477874755859375 0.9817578125000006 -0.5985 -0.4766845703125 0.9817578125000006 -0.598625 -0.475433349609375 0.9817578125000006 -0.59875 -0.475433349609375 0.9817578125000006 -0.598875 -0.47412109375 0.9817578125000006 -0.599 -0.47412109375 0.9817578125000006 -0.599125 -0.4727783203125 0.9817578125000006 -0.5992500000000001 -0.471343994140625 0.9817578125000006 -0.599375 -0.471343994140625 0.9817578125000006 -0.5995 -0.46990966796875 0.9817578125000006 -0.599625 -0.46990966796875 0.9817578125000006 -0.59975 -0.4683837890625 0.9817578125000006 -0.599875 -0.466827392578125 0.9817578125000006 -0.6 -0.466827392578125 0.9817578125000006 -0.6001250000000001 -0.4652099609375 0.9817578125000006 -0.60025 -0.4652099609375 0.9817578125000006 -0.600375 -0.46356201171875 0.9817578125000006 -0.6005000000000001 -0.461822509765625 0.9817578125000006 -0.600625 -0.461822509765625 0.9817578125000006 -0.60075 -0.460052490234375 0.9817578125000006 -0.6008750000000001 -0.460052490234375 0.9817578125000006 -0.601 -0.458251953125 0.9817578125000006 -0.601125 -0.456390380859375 0.9817578125000006 -0.6012500000000001 -0.456390380859375 0.9817578125000006 -0.601375 -0.4544677734375 0.9817578125000006 -0.6015000000000001 -0.4544677734375 0.9817578125000006 -0.6016249999999999 -0.452484130859375 0.9817578125000006 -0.60175 -0.45050048828125 0.9817578125000006 -0.6018750000000001 -0.45050048828125 0.9817578125000006 -0.602 -0.44842529296875 0.9817578125000006 -0.602125 -0.44842529296875 0.9817578125000006 -0.6022500000000001 -0.4462890625 0.9817578125000006 -0.602375 -0.44415283203125 0.9817578125000006 -0.6025 -0.44415283203125 0.9817578125000006 -0.6026249999999999 -0.441925048828125 0.9817578125000006 -0.60275 -0.441925048828125 0.9817578125000006 -0.602875 -0.439666748046875 0.9817578125000006 -0.6029999999999999 -0.437347412109375 0.9817578125000006 -0.603125 -0.437347412109375 0.9817578125000006 -0.6032500000000001 -0.43499755859375 0.9817578125000006 -0.603375 -0.43499755859375 0.9817578125000006 -0.6035 -0.432586669921875 0.9817578125000006 -0.603625 -0.430145263671875 0.9817578125000006 -0.60375 -0.430145263671875 0.9817578125000006 -0.603875 -0.427642822265625 0.9817578125000006 -0.604 -0.427642822265625 0.9817578125000006 -0.604125 -0.42510986328125 0.9817578125000006 -0.60425 -0.4224853515625 0.9817578125000006 -0.604375 -0.4224853515625 0.9817578125000006 -0.6045 -0.41986083984375 0.9817578125000006 -0.604625 -0.41986083984375 0.9817578125000006 -0.60475 -0.41717529296875 0.9817578125000006 -0.604875 -0.414459228515625 0.9817578125000006 -0.605 -0.414459228515625 0.9817578125000006 -0.605125 -0.411651611328125 0.9817578125000006 -0.60525 -0.411651611328125 0.9817578125000006 -0.605375 -0.408843994140625 0.9817578125000006 -0.6055000000000001 -0.405975341796875 0.9817578125000006 -0.6056249999999999 -0.405975341796875 0.9817578125000006 -0.60575 -0.403076171875 0.9817578125000006 -0.6058750000000001 -0.403076171875 0.9817578125000006 -0.606 -0.400115966796875 0.9817578125000006 -0.606125 -0.397125244140625 0.9817578125000006 -0.6062500000000001 -0.397125244140625 0.9817578125000006 -0.606375 -0.394073486328125 0.9817578125000006 -0.6065 -0.394073486328125 0.9817578125000006 -0.606625 -0.390960693359375 0.9817578125000006 -0.60675 -0.387847900390625 0.9817578125000006 -0.6068750000000001 -0.387847900390625 0.9817578125000006 -0.607 -0.384674072265625 0.9817578125000006 -0.607125 -0.384674072265625 0.9817578125000006 -0.6072500000000001 -0.3814697265625 0.9817578125000006 -0.607375 -0.378204345703125 0.9817578125000006 -0.6075 -0.378204345703125 0.9817578125000006 -0.607625 -0.374908447265625 0.9817578125000006 -0.6077500000000001 -0.374908447265625 0.9817578125000006 -0.607875 -0.37158203125 0.9817578125000006 -0.608 -0.36968994140625 0.9857910156249996 -0.6081250000000001 -0.36968994140625 0.9857910156249996 -0.60825 -0.36627197265625 0.9857910156249996 -0.608375 -0.36627197265625 0.9857910156249996 -0.6085000000000001 -0.36279296875 0.9857910156249996 -0.608625 -0.359283447265625 0.9857910156249996 -0.60875 -0.359283447265625 0.9857910156249996 -0.6088750000000001 -0.355712890625 0.9857910156249996 -0.609 -0.355712890625 0.9857910156249996 -0.609125 -0.352142333984375 0.9857910156249996 -0.6092499999999999 -0.3485107421875 0.9857910156249996 -0.609375 -0.3485107421875 0.9857910156249996 -0.6095000000000001 -0.3448486328125 0.9857910156249996 -0.609625 -0.3448486328125 0.9857910156249996 -0.60975 -0.34112548828125 0.9857910156249996 -0.6098750000000001 -0.33740234375 0.9857910156249996 -0.61 -0.33740234375 0.9857910156249996 -0.610125 -0.3336181640625 0.9857910156249996 -0.6102499999999999 -0.3336181640625 0.9857910156249996 -0.610375 -0.329803466796875 0.9857910156249996 -0.6105 -0.325958251953125 0.9857910156249996 -0.6106249999999999 -0.325958251953125 0.9857910156249996 -0.61075 -0.322052001953125 0.9857910156249996 -0.6108750000000001 -0.322052001953125 0.9857910156249996 -0.6109999999999999 -0.318115234375 0.9857910156249996 -0.611125 -0.314178466796875 0.9857910156249996 -0.61125 -0.314178466796875 0.9857910156249996 -0.611375 -0.3101806640625 0.9857910156249996 -0.6115 -0.3101806640625 0.9857910156249996 -0.611625 -0.30615234375 0.9857910156249996 -0.61175 -0.302093505859375 0.9857910156249996 -0.611875 -0.302093505859375 0.9857910156249996 -0.612 -0.2979736328125 0.9857910156249996 -0.612125 -0.2979736328125 0.9857910156249996 -0.61225 -0.293853759765625 0.9857910156249996 -0.612375 -0.289703369140625 0.9857910156249996 -0.6125 -0.289703369140625 0.9857910156249996 -0.612625 -0.2855224609375 0.9857910156249996 -0.61275 -0.2855224609375 0.9857910156249996 -0.612875 -0.281280517578125 0.9857910156249996 -0.613 -0.27703857421875 0.9857910156249996 -0.6131250000000001 -0.27703857421875 0.9857910156249996 -0.6132499999999999 -0.272735595703125 0.9857910156249996 -0.613375 -0.272735595703125 0.9857910156249996 -0.6135000000000001 -0.2684326171875 0.9857910156249996 -0.613625 -0.26409912109375 0.9857910156249996 -0.61375 -0.26409912109375 0.9857910156249996 -0.6138750000000001 -0.25970458984375 0.9857910156249996 -0.614 -0.25970458984375 0.9857910156249996 -0.614125 -0.255340576171875 0.9857910156249996 -0.61425 -0.250885009765625 0.9857910156249996 -0.614375 -0.250885009765625 0.9857910156249996 -0.6145 -0.246429443359375 0.9857910156249996 -0.614625 -0.246429443359375 0.9857910156249996 -0.61475 -0.241943359375 0.9857910156249996 -0.6148750000000001 -0.237457275390625 0.9857910156249996 -0.615 -0.237457275390625 0.9857910156249996 -0.615125 -0.23291015625 0.9857910156249996 -0.61525 -0.23291015625 0.9857910156249996 -0.615375 -0.22833251953125 0.9857910156249996 -0.6155 -0.2237548828125 0.9857910156249996 -0.615625 -0.2237548828125 0.9857910156249996 -0.6157500000000001 -0.219146728515625 0.9857910156249996 -0.615875 -0.219146728515625 0.9857910156249996 -0.616 -0.214508056640625 0.9857910156249996 -0.6161250000000001 -0.209869384765625 0.9857910156249996 -0.61625 -0.209869384765625 0.9857910156249996 -0.616375 -0.205169677734375 0.9857910156249996 -0.6165000000000001 -0.205169677734375 0.9857910156249996 -0.616625 -0.200469970703125 0.9857910156249996 -0.61675 -0.19573974609375 0.9857910156249996 -0.6168750000000001 -0.19573974609375 0.9857910156249996 -0.617 -0.191009521484375 0.9857910156249996 -0.6171250000000001 -0.191009521484375 0.9857910156249996 -0.6172499999999999 -0.18621826171875 0.9857910156249996 -0.617375 -0.18145751953125 0.9857910156249996 -0.6175000000000001 -0.18145751953125 0.9857910156249996 -0.617625 -0.1766357421875 0.9857910156249996 -0.61775 -0.1766357421875 0.9857910156249996 -0.6178750000000001 -0.17181396484375 0.9857910156249996 -0.618 -0.166961669921875 0.9857910156249996 -0.618125 -0.166961669921875 0.9857910156249996 -0.6182499999999999 -0.162078857421875 0.9857910156249996 -0.618375 -0.162078857421875 0.9857910156249996 -0.6185 -0.1572265625 0.9857910156249996 -0.6186249999999999 -0.152313232421875 0.9857910156249996 -0.61875 -0.152313232421875 0.9857910156249996 -0.6188750000000001 -0.14739990234375 0.9857910156249996 -0.619 -0.14739990234375 0.9857910156249996 -0.619125 -0.1424560546875 0.9857910156249996 -0.61925 -0.13751220703125 0.9857910156249996 -0.619375 -0.13751220703125 0.9857910156249996 -0.6195 -0.132537841796875 0.9857910156249996 -0.619625 -0.132537841796875 0.9857910156249996 -0.61975 -0.1275634765625 0.9857910156249996 -0.619875 -0.12255859375 0.9857910156249996 -0.62 -0.12255859375 0.9857910156249996 -0.620125 -0.117584228515625 0.9857910156249996 -0.62025 -0.117584228515625 0.9857910156249996 -0.620375 -0.112548828125 0.9857910156249996 -0.6205 -0.107513427734375 0.9857910156249996 -0.620625 -0.107513427734375 0.9857910156249996 -0.62075 -0.10247802734375 0.9857910156249996 -0.620875 -0.10247802734375 0.9857910156249996 -0.621 -0.097412109375 0.9857910156249996 -0.6211250000000001 -0.09234619140625 0.9857910156249996 -0.6212499999999999 -0.09234619140625 0.9857910156249996 -0.621375 -0.0872802734375 0.9857910156249996 -0.6215000000000001 -0.0872802734375 0.9857910156249996 -0.621625 -0.08221435546875 0.9857910156249996 -0.62175 -0.07708740234375 0.9857910156249996 -0.6218750000000001 -0.07708740234375 0.9857910156249996 -0.622 -0.071990966796875 0.9857910156249996 -0.622125 -0.071990966796875 0.9857910156249996 -0.62225 -0.06689453125 0.9857910156249996 -0.622375 -0.061767578125 0.9857910156249996 -0.6225000000000001 -0.061767578125 0.9857910156249996 -0.622625 -0.056671142578125 0.9857910156249996 -0.62275 -0.056671142578125 0.9857910156249996 -0.6228750000000001 -0.051544189453125 0.9857910156249996 -0.623 -0.04638671875 0.9857910156249996 -0.623125 -0.04638671875 0.9857910156249996 -0.62325 -0.041229248046875 0.9857910156249996 -0.6233750000000001 -0.041229248046875 0.9857910156249996 -0.6235 -0.036102294921875 0.9857910156249996 -0.623625 -0.03094482421875 0.9857910156249996 -0.6237500000000001 -0.03094482421875 0.9857910156249996 -0.623875 -0.025787353515625 0.9857910156249996 -0.624 -0.025787353515625 0.9857910156249996 -0.6241250000000001 -0.020660400390625 0.9857910156249996 -0.62425 -0.0155029296875 0.9857910156249996 -0.624375 -0.0155029296875 0.9857910156249996 -0.6245000000000001 -0.010345458984375 0.9857910156249996 -0.624625 -0.010345458984375 0.9857910156249996 -0.62475 -0.00518798828125 0.9857910156249996 +0.5626250000000001 -0.00445556640625 0.8530371093750013 +0.56275 -0.00445556640625 0.8530371093750013 +0.562875 -0.0089111328125 0.8530371093750013 +0.5630000000000001 -0.01336669921875 0.8530371093750013 +0.563125 -0.01336669921875 0.8530371093750013 +0.56325 -0.017852783203125 0.8530371093750013 +0.5633749999999999 -0.017852783203125 0.8530371093750013 +0.5635 -0.022308349609375 0.8530371093750013 +0.563625 -0.026763916015625 0.8530371093750013 +0.5637499999999999 -0.026763916015625 0.8530371093750013 +0.563875 -0.031219482421875 0.8530371093750013 +0.5640000000000001 -0.031219482421875 0.8530371093750013 +0.5641249999999999 -0.035675048828125 0.8530371093750013 +0.56425 -0.04010009765625 0.8530371093750013 +0.564375 -0.04010009765625 0.8530371093750013 +0.5645 -0.0445556640625 0.8530371093750013 +0.564625 -0.0445556640625 0.8530371093750013 +0.56475 -0.04901123046875 0.8530371093750013 +0.564875 -0.053436279296875 0.8530371093750013 +0.565 -0.053436279296875 0.8530371093750013 +0.565125 -0.057861328125 0.8530371093750013 +0.56525 -0.057861328125 0.8530371093750013 +0.565375 -0.062286376953125 0.8530371093750013 +0.5655 -0.066680908203125 0.8530371093750013 +0.565625 -0.066680908203125 0.8530371093750013 +0.56575 -0.07110595703125 0.8530371093750013 +0.565875 -0.07110595703125 0.8530371093750013 +0.566 -0.07550048828125 0.8530371093750013 +0.566125 -0.07989501953125 0.8530371093750013 +0.5662500000000001 -0.07989501953125 0.8530371093750013 +0.5663749999999999 -0.08428955078125 0.8530371093750013 +0.5665 -0.08428955078125 0.8530371093750013 +0.5666250000000001 -0.088653564453125 0.8530371093750013 +0.56675 -0.093017578125 0.8530371093750013 +0.566875 -0.093017578125 0.8530371093750013 +0.5670000000000001 -0.097381591796875 0.8530371093750013 +0.567125 -0.097381591796875 0.8530371093750013 +0.56725 -0.101715087890625 0.8530371093750013 +0.567375 -0.106048583984375 0.8530371093750013 +0.5675 -0.106048583984375 0.8530371093750013 +0.567625 -0.1103515625 0.8530371093750013 +0.56775 -0.1103515625 0.8530371093750013 +0.567875 -0.114654541015625 0.8530371093750013 +0.5680000000000001 -0.11895751953125 0.8530371093750013 +0.568125 -0.11895751953125 0.8530371093750013 +0.56825 -0.12322998046875 0.8530371093750013 +0.568375 -0.12322998046875 0.8530371093750013 +0.5685 -0.12750244140625 0.8530371093750013 +0.568625 -0.13177490234375 0.8530371093750013 +0.56875 -0.13177490234375 0.8530371093750013 +0.5688750000000001 -0.136016845703125 0.8530371093750013 +0.569 -0.136016845703125 0.8530371093750013 +0.569125 -0.140228271484375 0.8530371093750013 +0.5692500000000001 -0.144439697265625 0.8530371093750013 +0.569375 -0.144439697265625 0.8530371093750013 +0.5695 -0.148651123046875 0.8530371093750013 +0.5696250000000001 -0.148651123046875 0.8530371093750013 +0.56975 -0.152801513671875 0.8530371093750013 +0.569875 -0.156982421875 0.8530371093750013 +0.5700000000000001 -0.156982421875 0.8530371093750013 +0.570125 -0.1611328125 0.8530371093750013 +0.5702500000000001 -0.1611328125 0.8530371093750013 +0.5703749999999999 -0.165252685546875 0.8530371093750013 +0.5705 -0.16937255859375 0.8530371093750013 +0.5706250000000001 -0.16937255859375 0.8530371093750013 +0.57075 -0.173431396484375 0.8530371093750013 +0.570875 -0.173431396484375 0.8530371093750013 +0.5710000000000001 -0.177520751953125 0.8530371093750013 +0.571125 -0.18157958984375 0.8530371093750013 +0.57125 -0.18157958984375 0.8530371093750013 +0.5713749999999999 -0.18560791015625 0.8530371093750013 +0.5715 -0.18560791015625 0.8530371093750013 +0.571625 -0.189605712890625 0.8530371093750013 +0.5717499999999999 -0.193603515625 0.8530371093750013 +0.571875 -0.193603515625 0.8530371093750013 +0.5720000000000001 -0.19757080078125 0.8530371093750013 +0.572125 -0.19757080078125 0.8530371093750013 +0.57225 -0.201507568359375 0.8530371093750013 +0.572375 -0.2054443359375 0.8530371093750013 +0.5725 -0.2054443359375 0.8530371093750013 +0.572625 -0.2093505859375 0.8530371093750013 +0.57275 -0.2093505859375 0.8530371093750013 +0.572875 -0.213226318359375 0.8530371093750013 +0.573 -0.217071533203125 0.8530371093750013 +0.573125 -0.217071533203125 0.8530371093750013 +0.57325 -0.220916748046875 0.8530371093750013 +0.573375 -0.220916748046875 0.8530371093750013 +0.5735 -0.224700927734375 0.8530371093750013 +0.573625 -0.228515625 0.8530371093750013 +0.57375 -0.228515625 0.8530371093750013 +0.573875 -0.232269287109375 0.8530371093750013 +0.574 -0.232269287109375 0.8530371093750013 +0.574125 -0.235992431640625 0.8530371093750013 +0.5742500000000001 -0.23968505859375 0.8530371093750013 +0.5743749999999999 -0.23968505859375 0.8530371093750013 +0.5745 -0.243377685546875 0.8530371093750013 +0.5746250000000001 -0.243377685546875 0.8530371093750013 +0.57475 -0.247039794921875 0.8530371093750013 +0.574875 -0.250640869140625 0.8530371093750013 +0.5750000000000001 -0.250640869140625 0.8530371093750013 +0.575125 -0.2542724609375 0.8530371093750013 +0.57525 -0.2542724609375 0.8530371093750013 +0.575375 -0.2578125 0.8530371093750013 +0.5755 -0.261383056640625 0.8530371093750013 +0.5756250000000001 -0.261383056640625 0.8530371093750013 +0.57575 -0.264892578125 0.8530371093750013 +0.575875 -0.264892578125 0.8530371093750013 +0.5760000000000001 -0.308868408203125 0.9817578125000006 +0.576125 -0.3128662109375 0.9817578125000006 +0.57625 -0.3128662109375 0.9817578125000006 +0.576375 -0.316802978515625 0.9817578125000006 +0.5765000000000001 -0.316802978515625 0.9817578125000006 +0.576625 -0.320709228515625 0.9817578125000006 +0.57675 -0.3245849609375 0.9817578125000006 +0.5768750000000001 -0.3245849609375 0.9817578125000006 +0.577 -0.32843017578125 0.9817578125000006 +0.577125 -0.32843017578125 0.9817578125000006 +0.5772500000000001 -0.33221435546875 0.9817578125000006 +0.577375 -0.335968017578125 0.9817578125000006 +0.5775 -0.335968017578125 0.9817578125000006 +0.5776250000000001 -0.3397216796875 0.9817578125000006 +0.57775 -0.3397216796875 0.9817578125000006 +0.577875 -0.3433837890625 0.9817578125000006 +0.5779999999999999 -0.3470458984375 0.9817578125000006 +0.578125 -0.3470458984375 0.9817578125000006 +0.5782500000000001 -0.350677490234375 0.9817578125000006 +0.578375 -0.350677490234375 0.9817578125000006 +0.5785 -0.354248046875 0.9817578125000006 +0.5786250000000001 -0.3577880859375 0.9817578125000006 +0.57875 -0.3577880859375 0.9817578125000006 +0.578875 -0.361297607421875 0.9817578125000006 +0.5789999999999999 -0.361297607421875 0.9817578125000006 +0.579125 -0.36474609375 0.9817578125000006 +0.57925 -0.3681640625 0.9817578125000006 +0.5793749999999999 -0.3681640625 0.9817578125000006 +0.5795 -0.371551513671875 0.9817578125000006 +0.5796250000000001 -0.371551513671875 0.9817578125000006 +0.5797499999999999 -0.3748779296875 0.9817578125000006 +0.579875 -0.378173828125 0.9817578125000006 +0.58 -0.378173828125 0.9817578125000006 +0.580125 -0.381439208984375 0.9817578125000006 +0.58025 -0.381439208984375 0.9817578125000006 +0.580375 -0.3846435546875 0.9817578125000006 +0.5805 -0.3878173828125 0.9817578125000006 +0.580625 -0.3878173828125 0.9817578125000006 +0.58075 -0.39093017578125 0.9817578125000006 +0.580875 -0.39093017578125 0.9817578125000006 +0.581 -0.39404296875 0.9817578125000006 +0.581125 -0.3970947265625 0.9817578125000006 +0.58125 -0.3970947265625 0.9817578125000006 +0.581375 -0.40008544921875 0.9817578125000006 +0.5815 -0.40008544921875 0.9817578125000006 +0.581625 -0.403045654296875 0.9817578125000006 +0.58175 -0.40594482421875 0.9817578125000006 +0.5818750000000001 -0.40594482421875 0.9817578125000006 +0.5819999999999999 -0.4088134765625 0.9817578125000006 +0.582125 -0.4088134765625 0.9817578125000006 +0.5822500000000001 -0.41162109375 0.9817578125000006 +0.582375 -0.4144287109375 0.9817578125000006 +0.5825 -0.4144287109375 0.9817578125000006 +0.5826250000000001 -0.417144775390625 0.9817578125000006 +0.58275 -0.417144775390625 0.9817578125000006 +0.582875 -0.419830322265625 0.9817578125000006 +0.583 -0.422454833984375 0.9817578125000006 +0.583125 -0.422454833984375 0.9817578125000006 +0.58325 -0.425079345703125 0.9817578125000006 +0.583375 -0.425079345703125 0.9817578125000006 +0.5835 -0.4276123046875 0.9817578125000006 +0.5836250000000001 -0.43011474609375 0.9817578125000006 +0.58375 -0.43011474609375 0.9817578125000006 +0.583875 -0.43255615234375 0.9817578125000006 +0.584 -0.43255615234375 0.9817578125000006 +0.584125 -0.434967041015625 0.9817578125000006 +0.58425 -0.43731689453125 0.9817578125000006 +0.584375 -0.43731689453125 0.9817578125000006 +0.5845000000000001 -0.43963623046875 0.9817578125000006 +0.584625 -0.43963623046875 0.9817578125000006 +0.58475 -0.44189453125 0.9817578125000006 +0.5848750000000001 -0.444122314453125 0.9817578125000006 +0.585 -0.444122314453125 0.9817578125000006 +0.585125 -0.446258544921875 0.9817578125000006 +0.5852500000000001 -0.446258544921875 0.9817578125000006 +0.585375 -0.448394775390625 0.9817578125000006 +0.5855 -0.450469970703125 0.9817578125000006 +0.5856250000000001 -0.450469970703125 0.9817578125000006 +0.58575 -0.45245361328125 0.9817578125000006 +0.5858750000000001 -0.45245361328125 0.9817578125000006 +0.5859999999999999 -0.454437255859375 0.9817578125000006 +0.586125 -0.45635986328125 0.9817578125000006 +0.5862500000000001 -0.45635986328125 0.9817578125000006 +0.586375 -0.458221435546875 0.9817578125000006 +0.5865 -0.458221435546875 0.9817578125000006 +0.5866250000000001 -0.46002197265625 0.9817578125000006 +0.58675 -0.4617919921875 0.9817578125000006 +0.586875 -0.4617919921875 0.9817578125000006 +0.5869999999999999 -0.463531494140625 0.9817578125000006 +0.587125 -0.463531494140625 0.9817578125000006 +0.58725 -0.465179443359375 0.9817578125000006 +0.5873749999999999 -0.466796875 0.9817578125000006 +0.5875 -0.466796875 0.9817578125000006 +0.5876250000000001 -0.468353271484375 0.9817578125000006 +0.58775 -0.468353271484375 0.9817578125000006 +0.587875 -0.469879150390625 0.9817578125000006 +0.588 -0.4713134765625 0.9817578125000006 +0.588125 -0.4713134765625 0.9817578125000006 +0.58825 -0.472747802734375 0.9817578125000006 +0.588375 -0.472747802734375 0.9817578125000006 +0.5885 -0.474090576171875 0.9817578125000006 +0.588625 -0.47540283203125 0.9817578125000006 +0.58875 -0.47540283203125 0.9817578125000006 +0.588875 -0.476654052734375 0.9817578125000006 +0.589 -0.476654052734375 0.9817578125000006 +0.589125 -0.47784423828125 0.9817578125000006 +0.58925 -0.47900390625 0.9817578125000006 +0.589375 -0.47900390625 0.9817578125000006 +0.5895 -0.4801025390625 0.9817578125000006 +0.589625 -0.4801025390625 0.9817578125000006 +0.58975 -0.48114013671875 0.9817578125000006 +0.5898750000000001 -0.48211669921875 0.9817578125000006 +0.5899999999999999 -0.48211669921875 0.9817578125000006 +0.590125 -0.483062744140625 0.9817578125000006 +0.5902500000000001 -0.483062744140625 0.9817578125000006 +0.590375 -0.48394775390625 0.9817578125000006 +0.5905 -0.484771728515625 0.9817578125000006 +0.5906250000000001 -0.484771728515625 0.9817578125000006 +0.59075 -0.485565185546875 0.9817578125000006 +0.590875 -0.485565185546875 0.9817578125000006 +0.591 -0.48626708984375 0.9817578125000006 +0.591125 -0.4869384765625 0.9817578125000006 +0.5912500000000001 -0.4869384765625 0.9817578125000006 +0.591375 -0.487579345703125 0.9817578125000006 +0.5915 -0.487579345703125 0.9817578125000006 +0.5916250000000001 -0.488128662109375 0.9817578125000006 +0.59175 -0.4886474609375 0.9817578125000006 +0.591875 -0.4886474609375 0.9817578125000006 +0.592 -0.489105224609375 0.9817578125000006 +0.5921250000000001 -0.489105224609375 0.9817578125000006 +0.59225 -0.489501953125 0.9817578125000006 +0.592375 -0.4898681640625 0.9817578125000006 +0.5925000000000001 -0.4898681640625 0.9817578125000006 +0.592625 -0.490142822265625 0.9817578125000006 +0.59275 -0.490142822265625 0.9817578125000006 +0.5928750000000001 -0.490386962890625 0.9817578125000006 +0.593 -0.490570068359375 0.9817578125000006 +0.593125 -0.490570068359375 0.9817578125000006 +0.5932500000000001 -0.49072265625 0.9817578125000006 +0.593375 -0.49072265625 0.9817578125000006 +0.5935 -0.490814208984375 0.9817578125000006 +0.5936249999999999 -0.4908447265625 0.9817578125000006 +0.59375 -0.4908447265625 0.9817578125000006 +0.5938750000000001 -0.490814208984375 0.9817578125000006 +0.594 -0.490814208984375 0.9817578125000006 +0.594125 -0.49072265625 0.9817578125000006 +0.5942500000000001 -0.490570068359375 0.9817578125000006 +0.594375 -0.490570068359375 0.9817578125000006 +0.5945 -0.490386962890625 0.9817578125000006 +0.5946249999999999 -0.490386962890625 0.9817578125000006 +0.59475 -0.490142822265625 0.9817578125000006 +0.594875 -0.4898681640625 0.9817578125000006 +0.5949999999999999 -0.4898681640625 0.9817578125000006 +0.595125 -0.489501953125 0.9817578125000006 +0.5952500000000001 -0.489501953125 0.9817578125000006 +0.5953749999999999 -0.489105224609375 0.9817578125000006 +0.5955 -0.4886474609375 0.9817578125000006 +0.595625 -0.4886474609375 0.9817578125000006 +0.59575 -0.488128662109375 0.9817578125000006 +0.595875 -0.488128662109375 0.9817578125000006 +0.596 -0.487579345703125 0.9817578125000006 +0.596125 -0.4869384765625 0.9817578125000006 +0.59625 -0.4869384765625 0.9817578125000006 +0.596375 -0.48626708984375 0.9817578125000006 +0.5965 -0.48626708984375 0.9817578125000006 +0.596625 -0.485565185546875 0.9817578125000006 +0.59675 -0.484771728515625 0.9817578125000006 +0.596875 -0.484771728515625 0.9817578125000006 +0.597 -0.48394775390625 0.9817578125000006 +0.597125 -0.48394775390625 0.9817578125000006 +0.59725 -0.483062744140625 0.9817578125000006 +0.597375 -0.48211669921875 0.9817578125000006 +0.5975000000000001 -0.48211669921875 0.9817578125000006 +0.5976249999999999 -0.48114013671875 0.9817578125000006 +0.59775 -0.48114013671875 0.9817578125000006 +0.5978750000000001 -0.4801025390625 0.9817578125000006 +0.598 -0.47900390625 0.9817578125000006 +0.598125 -0.47900390625 0.9817578125000006 +0.5982500000000001 -0.47784423828125 0.9817578125000006 +0.598375 -0.47784423828125 0.9817578125000006 +0.5985 -0.476654052734375 0.9817578125000006 +0.598625 -0.47540283203125 0.9817578125000006 +0.59875 -0.47540283203125 0.9817578125000006 +0.598875 -0.474090576171875 0.9817578125000006 +0.599 -0.474090576171875 0.9817578125000006 +0.599125 -0.472747802734375 0.9817578125000006 +0.5992500000000001 -0.4713134765625 0.9817578125000006 +0.599375 -0.4713134765625 0.9817578125000006 +0.5995 -0.469879150390625 0.9817578125000006 +0.599625 -0.469879150390625 0.9817578125000006 +0.59975 -0.468353271484375 0.9817578125000006 +0.599875 -0.466796875 0.9817578125000006 +0.6 -0.466796875 0.9817578125000006 +0.6001250000000001 -0.465179443359375 0.9817578125000006 +0.60025 -0.465179443359375 0.9817578125000006 +0.600375 -0.463531494140625 0.9817578125000006 +0.6005000000000001 -0.4617919921875 0.9817578125000006 +0.600625 -0.4617919921875 0.9817578125000006 +0.60075 -0.46002197265625 0.9817578125000006 +0.6008750000000001 -0.46002197265625 0.9817578125000006 +0.601 -0.458221435546875 0.9817578125000006 +0.601125 -0.45635986328125 0.9817578125000006 +0.6012500000000001 -0.45635986328125 0.9817578125000006 +0.601375 -0.454437255859375 0.9817578125000006 +0.6015000000000001 -0.454437255859375 0.9817578125000006 +0.6016249999999999 -0.45245361328125 0.9817578125000006 +0.60175 -0.450469970703125 0.9817578125000006 +0.6018750000000001 -0.450469970703125 0.9817578125000006 +0.602 -0.448394775390625 0.9817578125000006 +0.602125 -0.448394775390625 0.9817578125000006 +0.6022500000000001 -0.446258544921875 0.9817578125000006 +0.602375 -0.444122314453125 0.9817578125000006 +0.6025 -0.444122314453125 0.9817578125000006 +0.6026249999999999 -0.44189453125 0.9817578125000006 +0.60275 -0.44189453125 0.9817578125000006 +0.602875 -0.43963623046875 0.9817578125000006 +0.6029999999999999 -0.43731689453125 0.9817578125000006 +0.603125 -0.43731689453125 0.9817578125000006 +0.6032500000000001 -0.434967041015625 0.9817578125000006 +0.603375 -0.434967041015625 0.9817578125000006 +0.6035 -0.43255615234375 0.9817578125000006 +0.603625 -0.43011474609375 0.9817578125000006 +0.60375 -0.43011474609375 0.9817578125000006 +0.603875 -0.4276123046875 0.9817578125000006 +0.604 -0.4276123046875 0.9817578125000006 +0.604125 -0.425079345703125 0.9817578125000006 +0.60425 -0.422454833984375 0.9817578125000006 +0.604375 -0.422454833984375 0.9817578125000006 +0.6045 -0.419830322265625 0.9817578125000006 +0.604625 -0.419830322265625 0.9817578125000006 +0.60475 -0.417144775390625 0.9817578125000006 +0.604875 -0.4144287109375 0.9817578125000006 +0.605 -0.4144287109375 0.9817578125000006 +0.605125 -0.41162109375 0.9817578125000006 +0.60525 -0.41162109375 0.9817578125000006 +0.605375 -0.4088134765625 0.9817578125000006 +0.6055000000000001 -0.40594482421875 0.9817578125000006 +0.6056249999999999 -0.40594482421875 0.9817578125000006 +0.60575 -0.403045654296875 0.9817578125000006 +0.6058750000000001 -0.403045654296875 0.9817578125000006 +0.606 -0.40008544921875 0.9817578125000006 +0.606125 -0.3970947265625 0.9817578125000006 +0.6062500000000001 -0.3970947265625 0.9817578125000006 +0.606375 -0.39404296875 0.9817578125000006 +0.6065 -0.39404296875 0.9817578125000006 +0.606625 -0.39093017578125 0.9817578125000006 +0.60675 -0.3878173828125 0.9817578125000006 +0.6068750000000001 -0.3878173828125 0.9817578125000006 +0.607 -0.3846435546875 0.9817578125000006 +0.607125 -0.3846435546875 0.9817578125000006 +0.6072500000000001 -0.381439208984375 0.9817578125000006 +0.607375 -0.378173828125 0.9817578125000006 +0.6075 -0.378173828125 0.9817578125000006 +0.607625 -0.3748779296875 0.9817578125000006 +0.6077500000000001 -0.3748779296875 0.9817578125000006 +0.607875 -0.371551513671875 0.9817578125000006 +0.608 -0.369659423828125 0.9857910156249996 +0.6081250000000001 -0.369659423828125 0.9857910156249996 +0.60825 -0.366241455078125 0.9857910156249996 +0.608375 -0.366241455078125 0.9857910156249996 +0.6085000000000001 -0.362762451171875 0.9857910156249996 +0.608625 -0.3592529296875 0.9857910156249996 +0.60875 -0.3592529296875 0.9857910156249996 +0.6088750000000001 -0.355682373046875 0.9857910156249996 +0.609 -0.355682373046875 0.9857910156249996 +0.609125 -0.35211181640625 0.9857910156249996 +0.6092499999999999 -0.348480224609375 0.9857910156249996 +0.609375 -0.348480224609375 0.9857910156249996 +0.6095000000000001 -0.344818115234375 0.9857910156249996 +0.609625 -0.344818115234375 0.9857910156249996 +0.60975 -0.341094970703125 0.9857910156249996 +0.6098750000000001 -0.337371826171875 0.9857910156249996 +0.61 -0.337371826171875 0.9857910156249996 +0.610125 -0.333587646484375 0.9857910156249996 +0.6102499999999999 -0.333587646484375 0.9857910156249996 +0.610375 -0.32977294921875 0.9857910156249996 +0.6105 -0.325927734375 0.9857910156249996 +0.6106249999999999 -0.325927734375 0.9857910156249996 +0.61075 -0.322021484375 0.9857910156249996 +0.6108750000000001 -0.322021484375 0.9857910156249996 +0.6109999999999999 -0.318084716796875 0.9857910156249996 +0.611125 -0.31414794921875 0.9857910156249996 +0.61125 -0.31414794921875 0.9857910156249996 +0.611375 -0.310150146484375 0.9857910156249996 +0.6115 -0.310150146484375 0.9857910156249996 +0.611625 -0.306121826171875 0.9857910156249996 +0.61175 -0.30206298828125 0.9857910156249996 +0.611875 -0.30206298828125 0.9857910156249996 +0.612 -0.297943115234375 0.9857910156249996 +0.612125 -0.297943115234375 0.9857910156249996 +0.61225 -0.2938232421875 0.9857910156249996 +0.612375 -0.2896728515625 0.9857910156249996 +0.6125 -0.2896728515625 0.9857910156249996 +0.612625 -0.285491943359375 0.9857910156249996 +0.61275 -0.285491943359375 0.9857910156249996 +0.612875 -0.28125 0.9857910156249996 +0.613 -0.277008056640625 0.9857910156249996 +0.6131250000000001 -0.277008056640625 0.9857910156249996 +0.6132499999999999 -0.272705078125 0.9857910156249996 +0.613375 -0.272705078125 0.9857910156249996 +0.6135000000000001 -0.268402099609375 0.9857910156249996 +0.613625 -0.264068603515625 0.9857910156249996 +0.61375 -0.264068603515625 0.9857910156249996 +0.6138750000000001 -0.259674072265625 0.9857910156249996 +0.614 -0.259674072265625 0.9857910156249996 +0.614125 -0.25531005859375 0.9857910156249996 +0.61425 -0.2508544921875 0.9857910156249996 +0.614375 -0.2508544921875 0.9857910156249996 +0.6145 -0.24639892578125 0.9857910156249996 +0.614625 -0.24639892578125 0.9857910156249996 +0.61475 -0.241912841796875 0.9857910156249996 +0.6148750000000001 -0.2374267578125 0.9857910156249996 +0.615 -0.2374267578125 0.9857910156249996 +0.615125 -0.232879638671875 0.9857910156249996 +0.61525 -0.232879638671875 0.9857910156249996 +0.615375 -0.228302001953125 0.9857910156249996 +0.6155 -0.223724365234375 0.9857910156249996 +0.615625 -0.223724365234375 0.9857910156249996 +0.6157500000000001 -0.2191162109375 0.9857910156249996 +0.615875 -0.2191162109375 0.9857910156249996 +0.616 -0.2144775390625 0.9857910156249996 +0.6161250000000001 -0.2098388671875 0.9857910156249996 +0.61625 -0.2098388671875 0.9857910156249996 +0.616375 -0.20513916015625 0.9857910156249996 +0.6165000000000001 -0.20513916015625 0.9857910156249996 +0.616625 -0.200439453125 0.9857910156249996 +0.61675 -0.195709228515625 0.9857910156249996 +0.6168750000000001 -0.195709228515625 0.9857910156249996 +0.617 -0.19097900390625 0.9857910156249996 +0.6171250000000001 -0.19097900390625 0.9857910156249996 +0.6172499999999999 -0.186187744140625 0.9857910156249996 +0.617375 -0.181427001953125 0.9857910156249996 +0.6175000000000001 -0.181427001953125 0.9857910156249996 +0.617625 -0.176605224609375 0.9857910156249996 +0.61775 -0.176605224609375 0.9857910156249996 +0.6178750000000001 -0.171783447265625 0.9857910156249996 +0.618 -0.16693115234375 0.9857910156249996 +0.618125 -0.16693115234375 0.9857910156249996 +0.6182499999999999 -0.16204833984375 0.9857910156249996 +0.618375 -0.16204833984375 0.9857910156249996 +0.6185 -0.157196044921875 0.9857910156249996 +0.6186249999999999 -0.15228271484375 0.9857910156249996 +0.61875 -0.15228271484375 0.9857910156249996 +0.6188750000000001 -0.147369384765625 0.9857910156249996 +0.619 -0.147369384765625 0.9857910156249996 +0.619125 -0.142425537109375 0.9857910156249996 +0.61925 -0.137481689453125 0.9857910156249996 +0.619375 -0.137481689453125 0.9857910156249996 +0.6195 -0.13250732421875 0.9857910156249996 +0.619625 -0.13250732421875 0.9857910156249996 +0.61975 -0.127532958984375 0.9857910156249996 +0.619875 -0.122528076171875 0.9857910156249996 +0.62 -0.122528076171875 0.9857910156249996 +0.620125 -0.1175537109375 0.9857910156249996 +0.62025 -0.1175537109375 0.9857910156249996 +0.620375 -0.112518310546875 0.9857910156249996 +0.6205 -0.10748291015625 0.9857910156249996 +0.620625 -0.10748291015625 0.9857910156249996 +0.62075 -0.102447509765625 0.9857910156249996 +0.620875 -0.102447509765625 0.9857910156249996 +0.621 -0.097381591796875 0.9857910156249996 +0.6211250000000001 -0.092315673828125 0.9857910156249996 +0.6212499999999999 -0.092315673828125 0.9857910156249996 +0.621375 -0.087249755859375 0.9857910156249996 +0.6215000000000001 -0.087249755859375 0.9857910156249996 +0.621625 -0.082183837890625 0.9857910156249996 +0.62175 -0.077056884765625 0.9857910156249996 +0.6218750000000001 -0.077056884765625 0.9857910156249996 +0.622 -0.07196044921875 0.9857910156249996 +0.622125 -0.07196044921875 0.9857910156249996 +0.62225 -0.066864013671875 0.9857910156249996 +0.622375 -0.061737060546875 0.9857910156249996 +0.6225000000000001 -0.061737060546875 0.9857910156249996 +0.622625 -0.056640625 0.9857910156249996 +0.62275 -0.056640625 0.9857910156249996 +0.6228750000000001 -0.051513671875 0.9857910156249996 +0.623 -0.046356201171875 0.9857910156249996 +0.623125 -0.046356201171875 0.9857910156249996 +0.62325 -0.04119873046875 0.9857910156249996 +0.6233750000000001 -0.04119873046875 0.9857910156249996 +0.6235 -0.03607177734375 0.9857910156249996 +0.623625 -0.030914306640625 0.9857910156249996 +0.6237500000000001 -0.030914306640625 0.9857910156249996 +0.623875 -0.0257568359375 0.9857910156249996 +0.624 -0.0257568359375 0.9857910156249996 +0.6241250000000001 -0.0206298828125 0.9857910156249996 +0.62425 -0.015472412109375 0.9857910156249996 +0.624375 -0.015472412109375 0.9857910156249996 +0.6245000000000001 -0.01031494140625 0.9857910156249996 +0.624625 -0.01031494140625 0.9857910156249996 +0.62475 -0.005157470703125 0.9857910156249996 0.6248749999999999 0.0 0.9857910156249996 0.625 0.0 0.9857910156249996 0.6251250000000001 0.005157470703125 0.9857910156249996 @@ -5499,504 +5499,504 @@ 0.68725 0.003326416015625 0.6370898437499979 0.6873750000000001 0.0 0.6370898437499979 0.6875 0.0 0.6370898437499979 -0.6876250000000001 -0.00335693359375 0.6370898437499979 -0.68775 -0.00335693359375 0.6370898437499979 -0.687875 -0.006683349609375 0.6370898437499979 -0.6880000000000001 -0.010009765625 0.6370898437499979 -0.688125 -0.010009765625 0.6370898437499979 -0.68825 -0.01336669921875 0.6370898437499979 -0.6883749999999999 -0.01336669921875 0.6370898437499979 -0.6885 -0.01666259765625 0.6370898437499979 -0.688625 -0.02001953125 0.6370898437499979 -0.6887499999999999 -0.02001953125 0.6370898437499979 -0.688875 -0.023345947265625 0.6370898437499979 -0.6890000000000001 -0.023345947265625 0.6370898437499979 -0.6891249999999999 -0.02667236328125 0.6370898437499979 -0.68925 -0.029998779296875 0.6370898437499979 -0.689375 -0.029998779296875 0.6370898437499979 -0.6895 -0.033294677734375 0.6370898437499979 -0.689625 -0.033294677734375 0.6370898437499979 -0.68975 -0.03662109375 0.6370898437499979 -0.689875 -0.0399169921875 0.6370898437499979 -0.69 -0.0399169921875 0.6370898437499979 -0.690125 -0.043243408203125 0.6370898437499979 -0.69025 -0.043243408203125 0.6370898437499979 -0.690375 -0.046539306640625 0.6370898437499979 -0.6905 -0.049835205078125 0.6370898437499979 -0.690625 -0.049835205078125 0.6370898437499979 -0.69075 -0.053131103515625 0.6370898437499979 -0.690875 -0.053131103515625 0.6370898437499979 -0.691 -0.056427001953125 0.6370898437499979 -0.691125 -0.0596923828125 0.6370898437499979 -0.6912500000000001 -0.0596923828125 0.6370898437499979 -0.6913749999999999 -0.062957763671875 0.6370898437499979 -0.6915 -0.062957763671875 0.6370898437499979 -0.6916250000000001 -0.06622314453125 0.6370898437499979 -0.69175 -0.069488525390625 0.6370898437499979 -0.691875 -0.069488525390625 0.6370898437499979 -0.6920000000000001 -0.07275390625 0.6370898437499979 -0.692125 -0.07275390625 0.6370898437499979 -0.69225 -0.07598876953125 0.6370898437499979 -0.692375 -0.0792236328125 0.6370898437499979 -0.6925 -0.0792236328125 0.6370898437499979 -0.692625 -0.08245849609375 0.6370898437499979 -0.69275 -0.08245849609375 0.6370898437499979 -0.692875 -0.085662841796875 0.6370898437499979 -0.6930000000000001 -0.0888671875 0.6370898437499979 -0.693125 -0.0888671875 0.6370898437499979 -0.69325 -0.092071533203125 0.6370898437499979 -0.693375 -0.092071533203125 0.6370898437499979 -0.6935 -0.095245361328125 0.6370898437499979 -0.693625 -0.09844970703125 0.6370898437499979 -0.69375 -0.09844970703125 0.6370898437499979 -0.6938750000000001 -0.101593017578125 0.6370898437499979 -0.694 -0.101593017578125 0.6370898437499979 -0.694125 -0.104766845703125 0.6370898437499979 -0.6942500000000001 -0.10791015625 0.6370898437499979 -0.694375 -0.10791015625 0.6370898437499979 -0.6945 -0.11102294921875 0.6370898437499979 -0.6946250000000001 -0.11102294921875 0.6370898437499979 -0.69475 -0.114166259765625 0.6370898437499979 -0.694875 -0.117279052734375 0.6370898437499979 -0.6950000000000001 -0.117279052734375 0.6370898437499979 -0.695125 -0.120361328125 0.6370898437499979 -0.6952500000000001 -0.120361328125 0.6370898437499979 -0.6953749999999999 -0.123443603515625 0.6370898437499979 -0.6955 -0.126495361328125 0.6370898437499979 -0.6956250000000001 -0.126495361328125 0.6370898437499979 -0.69575 -0.12957763671875 0.6370898437499979 -0.695875 -0.12957763671875 0.6370898437499979 -0.6960000000000001 -0.132598876953125 0.6370898437499979 -0.696125 -0.1356201171875 0.6370898437499979 -0.69625 -0.1356201171875 0.6370898437499979 -0.6963749999999999 -0.138641357421875 0.6370898437499979 -0.6965 -0.138641357421875 0.6370898437499979 -0.696625 -0.141632080078125 0.6370898437499979 -0.6967499999999999 -0.144622802734375 0.6370898437499979 -0.696875 -0.144622802734375 0.6370898437499979 -0.6970000000000001 -0.1475830078125 0.6370898437499979 -0.697125 -0.1475830078125 0.6370898437499979 -0.69725 -0.150543212890625 0.6370898437499979 -0.697375 -0.1534423828125 0.6370898437499979 -0.6975 -0.1534423828125 0.6370898437499979 -0.697625 -0.1563720703125 0.6370898437499979 -0.69775 -0.1563720703125 0.6370898437499979 -0.697875 -0.159271240234375 0.6370898437499979 -0.698 -0.162139892578125 0.6370898437499979 -0.698125 -0.162139892578125 0.6370898437499979 -0.69825 -0.165008544921875 0.6370898437499979 -0.698375 -0.165008544921875 0.6370898437499979 -0.6985 -0.1678466796875 0.6370898437499979 -0.698625 -0.170684814453125 0.6370898437499979 -0.69875 -0.170684814453125 0.6370898437499979 -0.698875 -0.173492431640625 0.6370898437499979 -0.699 -0.173492431640625 0.6370898437499979 -0.699125 -0.17626953125 0.6370898437499979 -0.6992500000000001 -0.179046630859375 0.6370898437499979 -0.6993749999999999 -0.179046630859375 0.6370898437499979 -0.6995 -0.181793212890625 0.6370898437499979 -0.6996250000000001 -0.181793212890625 0.6370898437499979 -0.69975 -0.18450927734375 0.6370898437499979 -0.699875 -0.187225341796875 0.6370898437499979 -0.7000000000000001 -0.187225341796875 0.6370898437499979 -0.700125 -0.189910888671875 0.6370898437499979 -0.70025 -0.189910888671875 0.6370898437499979 -0.700375 -0.192596435546875 0.6370898437499979 -0.7005 -0.195220947265625 0.6370898437499979 -0.7006250000000001 -0.195220947265625 0.6370898437499979 -0.70075 -0.197845458984375 0.6370898437499979 -0.700875 -0.197845458984375 0.6370898437499979 -0.7010000000000001 -0.200469970703125 0.6370898437499979 -0.701125 -0.203033447265625 0.6370898437499979 -0.70125 -0.203033447265625 0.6370898437499979 -0.701375 -0.205596923828125 0.6370898437499979 -0.7015000000000001 -0.205596923828125 0.6370898437499979 -0.701625 -0.2081298828125 0.6370898437499979 -0.70175 -0.210662841796875 0.6370898437499979 -0.7018750000000001 -0.210662841796875 0.6370898437499979 -0.702 -0.213134765625 0.6370898437499979 -0.702125 -0.213134765625 0.6370898437499979 -0.7022500000000001 -0.215606689453125 0.6370898437499979 -0.702375 -0.218048095703125 0.6370898437499979 -0.7025 -0.218048095703125 0.6370898437499979 -0.7026250000000001 -0.220458984375 0.6370898437499979 -0.70275 -0.220458984375 0.6370898437499979 -0.702875 -0.222869873046875 0.6370898437499979 -0.7030000000000001 -0.2252197265625 0.6370898437499979 -0.703125 -0.2252197265625 0.6370898437499979 -0.7032500000000001 -0.22760009765625 0.6370898437499979 -0.703375 -0.22760009765625 0.6370898437499979 -0.7035 -0.229888916015625 0.6370898437499979 -0.7036250000000001 -0.232208251953125 0.6370898437499979 -0.70375 -0.232208251953125 0.6370898437499979 -0.703875 -0.234466552734375 0.6370898437499979 -0.7039999999999999 -0.1251220703125 0.3399999999999977 -0.704125 -0.1263427734375 0.3399999999999977 -0.70425 -0.12750244140625 0.3399999999999977 -0.7043749999999999 -0.12750244140625 0.3399999999999977 -0.7045 -0.128692626953125 0.3399999999999977 -0.7046250000000001 -0.128692626953125 0.3399999999999977 -0.7047499999999999 -0.129852294921875 0.3399999999999977 -0.704875 -0.1309814453125 0.3399999999999977 -0.705 -0.1309814453125 0.3399999999999977 -0.705125 -0.132110595703125 0.3399999999999977 -0.70525 -0.132110595703125 0.3399999999999977 -0.705375 -0.133209228515625 0.3399999999999977 -0.7055 -0.13433837890625 0.3399999999999977 -0.705625 -0.13433837890625 0.3399999999999977 -0.70575 -0.135406494140625 0.3399999999999977 -0.705875 -0.135406494140625 0.3399999999999977 -0.706 -0.136474609375 0.3399999999999977 -0.706125 -0.137542724609375 0.3399999999999977 -0.70625 -0.137542724609375 0.3399999999999977 -0.706375 -0.138580322265625 0.3399999999999977 -0.7065 -0.138580322265625 0.3399999999999977 -0.706625 -0.13958740234375 0.3399999999999977 -0.70675 -0.140594482421875 0.3399999999999977 -0.7068750000000001 -0.140594482421875 0.3399999999999977 -0.7069999999999999 -0.1416015625 0.3399999999999977 -0.707125 -0.1416015625 0.3399999999999977 -0.7072500000000001 -0.142578125 0.3399999999999977 -0.707375 -0.143524169921875 0.3399999999999977 -0.7075 -0.143524169921875 0.3399999999999977 -0.7076250000000001 -0.14447021484375 0.3399999999999977 -0.70775 -0.14447021484375 0.3399999999999977 -0.707875 -0.145416259765625 0.3399999999999977 -0.708 -0.146331787109375 0.3399999999999977 -0.708125 -0.146331787109375 0.3399999999999977 -0.70825 -0.147216796875 0.3399999999999977 -0.708375 -0.147216796875 0.3399999999999977 -0.7085 -0.148101806640625 0.3399999999999977 -0.7086250000000001 -0.148956298828125 0.3399999999999977 -0.70875 -0.148956298828125 0.3399999999999977 -0.708875 -0.149810791015625 0.3399999999999977 -0.709 -0.149810791015625 0.3399999999999977 -0.709125 -0.150634765625 0.3399999999999977 -0.70925 -0.151458740234375 0.3399999999999977 -0.709375 -0.151458740234375 0.3399999999999977 -0.7095000000000001 -0.152252197265625 0.3399999999999977 -0.709625 -0.152252197265625 0.3399999999999977 -0.70975 -0.153045654296875 0.3399999999999977 -0.7098750000000001 -0.15380859375 0.3399999999999977 -0.71 -0.15380859375 0.3399999999999977 -0.710125 -0.154571533203125 0.3399999999999977 -0.7102500000000001 -0.154571533203125 0.3399999999999977 -0.710375 -0.155303955078125 0.3399999999999977 -0.7105 -0.156005859375 0.3399999999999977 -0.7106250000000001 -0.156005859375 0.3399999999999977 -0.71075 -0.156707763671875 0.3399999999999977 -0.7108750000000001 -0.156707763671875 0.3399999999999977 -0.7109999999999999 -0.157379150390625 0.3399999999999977 -0.711125 -0.158050537109375 0.3399999999999977 -0.7112500000000001 -0.158050537109375 0.3399999999999977 -0.711375 -0.15869140625 0.3399999999999977 -0.7115 -0.15869140625 0.3399999999999977 -0.7116250000000001 -0.159332275390625 0.3399999999999977 -0.71175 -0.159942626953125 0.3399999999999977 -0.711875 -0.159942626953125 0.3399999999999977 -0.7119999999999999 -0.1605224609375 0.3399999999999977 -0.712125 -0.1605224609375 0.3399999999999977 -0.71225 -0.161102294921875 0.3399999999999977 -0.7123749999999999 -0.16168212890625 0.3399999999999977 -0.7125 -0.16168212890625 0.3399999999999977 -0.7126250000000001 -0.162200927734375 0.3399999999999977 -0.71275 -0.162200927734375 0.3399999999999977 -0.712875 -0.162750244140625 0.3399999999999977 -0.713 -0.163238525390625 0.3399999999999977 -0.713125 -0.163238525390625 0.3399999999999977 -0.71325 -0.163726806640625 0.3399999999999977 -0.713375 -0.163726806640625 0.3399999999999977 -0.7135 -0.1641845703125 0.3399999999999977 -0.713625 -0.164642333984375 0.3399999999999977 -0.71375 -0.164642333984375 0.3399999999999977 -0.713875 -0.16510009765625 0.3399999999999977 -0.714 -0.16510009765625 0.3399999999999977 -0.714125 -0.165496826171875 0.3399999999999977 -0.71425 -0.1658935546875 0.3399999999999977 -0.714375 -0.1658935546875 0.3399999999999977 -0.7145 -0.166259765625 0.3399999999999977 -0.714625 -0.166259765625 0.3399999999999977 -0.71475 -0.1666259765625 0.3399999999999977 -0.7148750000000001 -0.1669921875 0.3399999999999977 -0.7149999999999999 -0.1669921875 0.3399999999999977 -0.715125 -0.16729736328125 0.3399999999999977 -0.7152500000000001 -0.16729736328125 0.3399999999999977 -0.715375 -0.1676025390625 0.3399999999999977 -0.7155 -0.16790771484375 0.3399999999999977 -0.7156250000000001 -0.16790771484375 0.3399999999999977 -0.71575 -0.16815185546875 0.3399999999999977 -0.715875 -0.16815185546875 0.3399999999999977 -0.716 -0.168426513671875 0.3399999999999977 -0.716125 -0.16864013671875 0.3399999999999977 -0.7162500000000001 -0.16864013671875 0.3399999999999977 -0.716375 -0.168853759765625 0.3399999999999977 -0.7165 -0.168853759765625 0.3399999999999977 -0.7166250000000001 -0.1690673828125 0.3399999999999977 -0.71675 -0.16925048828125 0.3399999999999977 -0.716875 -0.16925048828125 0.3399999999999977 -0.717 -0.169403076171875 0.3399999999999977 -0.7171250000000001 -0.169403076171875 0.3399999999999977 -0.71725 -0.169525146484375 0.3399999999999977 -0.717375 -0.169647216796875 0.3399999999999977 -0.7175000000000001 -0.169647216796875 0.3399999999999977 -0.717625 -0.169769287109375 0.3399999999999977 -0.71775 -0.169769287109375 0.3399999999999977 -0.7178750000000001 -0.169830322265625 0.3399999999999977 -0.718 -0.169891357421875 0.3399999999999977 -0.718125 -0.169891357421875 0.3399999999999977 -0.7182500000000001 -0.169952392578125 0.3399999999999977 -0.718375 -0.169952392578125 0.3399999999999977 -0.7185 -0.16998291015625 0.3399999999999977 -0.7186250000000001 -0.16998291015625 0.3399999999999977 -0.71875 -0.16998291015625 0.3399999999999977 -0.7188750000000001 -0.16998291015625 0.3399999999999977 -0.719 -0.16998291015625 0.3399999999999977 -0.719125 -0.169952392578125 0.3399999999999977 -0.7192500000000001 -0.169891357421875 0.3399999999999977 -0.719375 -0.169891357421875 0.3399999999999977 -0.7195 -0.169830322265625 0.3399999999999977 -0.7196250000000001 -0.169830322265625 0.3399999999999977 -0.71975 -0.169769287109375 0.3399999999999977 -0.719875 -0.169647216796875 0.3399999999999977 -0.7199999999999999 -0.169647216796875 0.3399999999999977 -0.720125 -0.169525146484375 0.3399999999999977 -0.7202500000000001 -0.169525146484375 0.3399999999999977 -0.7203749999999999 -0.169403076171875 0.3399999999999977 -0.7205 -0.16925048828125 0.3399999999999977 -0.720625 -0.16925048828125 0.3399999999999977 -0.72075 -0.1690673828125 0.3399999999999977 -0.720875 -0.1690673828125 0.3399999999999977 -0.721 -0.168853759765625 0.3399999999999977 -0.721125 -0.16864013671875 0.3399999999999977 -0.72125 -0.16864013671875 0.3399999999999977 -0.721375 -0.168426513671875 0.3399999999999977 -0.7215 -0.168426513671875 0.3399999999999977 -0.721625 -0.16815185546875 0.3399999999999977 -0.72175 -0.16790771484375 0.3399999999999977 -0.721875 -0.16790771484375 0.3399999999999977 -0.722 -0.1676025390625 0.3399999999999977 -0.722125 -0.1676025390625 0.3399999999999977 -0.72225 -0.16729736328125 0.3399999999999977 -0.722375 -0.1669921875 0.3399999999999977 -0.7225000000000001 -0.1669921875 0.3399999999999977 -0.7226249999999999 -0.1666259765625 0.3399999999999977 -0.72275 -0.1666259765625 0.3399999999999977 -0.7228750000000001 -0.166259765625 0.3399999999999977 -0.723 -0.1658935546875 0.3399999999999977 -0.723125 -0.1658935546875 0.3399999999999977 -0.7232500000000001 -0.165496826171875 0.3399999999999977 -0.723375 -0.165496826171875 0.3399999999999977 -0.7235 -0.16510009765625 0.3399999999999977 -0.723625 -0.164642333984375 0.3399999999999977 -0.72375 -0.164642333984375 0.3399999999999977 -0.723875 -0.1641845703125 0.3399999999999977 -0.724 -0.1641845703125 0.3399999999999977 -0.724125 -0.163726806640625 0.3399999999999977 -0.7242500000000001 -0.163238525390625 0.3399999999999977 -0.724375 -0.163238525390625 0.3399999999999977 -0.7245 -0.162750244140625 0.3399999999999977 -0.724625 -0.162750244140625 0.3399999999999977 -0.72475 -0.162200927734375 0.3399999999999977 -0.724875 -0.16168212890625 0.3399999999999977 -0.725 -0.16168212890625 0.3399999999999977 -0.7251250000000001 -0.161102294921875 0.3399999999999977 -0.72525 -0.161102294921875 0.3399999999999977 -0.725375 -0.1605224609375 0.3399999999999977 -0.7255000000000001 -0.159942626953125 0.3399999999999977 -0.725625 -0.159942626953125 0.3399999999999977 -0.72575 -0.159332275390625 0.3399999999999977 -0.7258750000000001 -0.159332275390625 0.3399999999999977 -0.726 -0.15869140625 0.3399999999999977 -0.726125 -0.158050537109375 0.3399999999999977 -0.7262500000000001 -0.158050537109375 0.3399999999999977 -0.726375 -0.157379150390625 0.3399999999999977 -0.7265000000000001 -0.157379150390625 0.3399999999999977 -0.7266249999999999 -0.156707763671875 0.3399999999999977 -0.72675 -0.156005859375 0.3399999999999977 -0.7268750000000001 -0.156005859375 0.3399999999999977 -0.727 -0.155303955078125 0.3399999999999977 -0.727125 -0.155303955078125 0.3399999999999977 -0.7272500000000001 -0.154571533203125 0.3399999999999977 -0.727375 -0.15380859375 0.3399999999999977 -0.7275 -0.15380859375 0.3399999999999977 -0.7276249999999999 -0.153045654296875 0.3399999999999977 -0.72775 -0.153045654296875 0.3399999999999977 -0.727875 -0.152252197265625 0.3399999999999977 -0.7279999999999999 -0.151458740234375 0.3399999999999977 -0.728125 -0.151458740234375 0.3399999999999977 -0.7282500000000001 -0.150634765625 0.3399999999999977 -0.728375 -0.150634765625 0.3399999999999977 -0.7285 -0.149810791015625 0.3399999999999977 -0.728625 -0.148956298828125 0.3399999999999977 -0.72875 -0.148956298828125 0.3399999999999977 -0.728875 -0.148101806640625 0.3399999999999977 -0.729 -0.148101806640625 0.3399999999999977 -0.729125 -0.147216796875 0.3399999999999977 -0.72925 -0.146331787109375 0.3399999999999977 -0.729375 -0.146331787109375 0.3399999999999977 -0.7295 -0.145416259765625 0.3399999999999977 -0.729625 -0.145416259765625 0.3399999999999977 -0.72975 -0.14447021484375 0.3399999999999977 -0.729875 -0.143524169921875 0.3399999999999977 -0.73 -0.143524169921875 0.3399999999999977 -0.730125 -0.142578125 0.3399999999999977 -0.73025 -0.142578125 0.3399999999999977 -0.730375 -0.1416015625 0.3399999999999977 -0.7305000000000001 -0.140594482421875 0.3399999999999977 -0.7306249999999999 -0.140594482421875 0.3399999999999977 -0.73075 -0.13958740234375 0.3399999999999977 -0.7308750000000001 -0.13958740234375 0.3399999999999977 -0.731 -0.138580322265625 0.3399999999999977 -0.731125 -0.137542724609375 0.3399999999999977 -0.7312500000000001 -0.137542724609375 0.3399999999999977 -0.731375 -0.136474609375 0.3399999999999977 -0.7315 -0.136474609375 0.3399999999999977 -0.731625 -0.135406494140625 0.3399999999999977 -0.73175 -0.13433837890625 0.3399999999999977 -0.7318750000000001 -0.13433837890625 0.3399999999999977 -0.732 -0.133209228515625 0.3399999999999977 -0.732125 -0.133209228515625 0.3399999999999977 -0.7322500000000001 -0.132110595703125 0.3399999999999977 -0.732375 -0.1309814453125 0.3399999999999977 -0.7325 -0.1309814453125 0.3399999999999977 -0.732625 -0.129852294921875 0.3399999999999977 -0.7327500000000001 -0.129852294921875 0.3399999999999977 -0.732875 -0.128692626953125 0.3399999999999977 -0.733 -0.12750244140625 0.3399999999999977 -0.7331250000000001 -0.12750244140625 0.3399999999999977 -0.73325 -0.1263427734375 0.3399999999999977 -0.733375 -0.1263427734375 0.3399999999999977 -0.7335000000000001 -0.1251220703125 0.3399999999999977 -0.733625 -0.123931884765625 0.3399999999999977 -0.73375 -0.123931884765625 0.3399999999999977 -0.7338750000000001 -0.1226806640625 0.3399999999999977 -0.734 -0.1226806640625 0.3399999999999977 -0.734125 -0.1214599609375 0.3399999999999977 -0.7342500000000001 -0.120208740234375 0.3399999999999977 -0.734375 -0.120208740234375 0.3399999999999977 -0.7345000000000001 -0.118927001953125 0.3399999999999977 -0.734625 -0.118927001953125 0.3399999999999977 -0.73475 -0.11767578125 0.3399999999999977 -0.7348750000000001 -0.116363525390625 0.3399999999999977 -0.735 -0.116363525390625 0.3399999999999977 -0.735125 -0.115081787109375 0.3399999999999977 -0.7352500000000001 -0.115081787109375 0.3399999999999977 -0.735375 -0.113739013671875 0.3399999999999977 -0.7355 -0.1124267578125 0.3399999999999977 -0.7356249999999999 -0.1124267578125 0.3399999999999977 -0.73575 -0.111083984375 0.3399999999999977 -0.7358750000000001 -0.111083984375 0.3399999999999977 -0.7359999999999999 -0.00665283203125 0.02060546874999752 -0.736125 -0.006561279296875 0.02060546874999752 -0.73625 -0.006561279296875 0.02060546874999752 -0.736375 -0.006500244140625 0.02060546874999752 -0.7365 -0.006500244140625 0.02060546874999752 -0.736625 -0.00640869140625 0.02060546874999752 -0.73675 -0.006317138671875 0.02060546874999752 -0.736875 -0.006317138671875 0.02060546874999752 -0.737 -0.0062255859375 0.02060546874999752 -0.737125 -0.0062255859375 0.02060546874999752 -0.73725 -0.006134033203125 0.02060546874999752 -0.737375 -0.006072998046875 0.02060546874999752 -0.7375 -0.006072998046875 0.02060546874999752 -0.737625 -0.0059814453125 0.02060546874999752 -0.73775 -0.0059814453125 0.02060546874999752 -0.737875 -0.005889892578125 0.02060546874999752 -0.738 -0.00579833984375 0.02060546874999752 -0.7381250000000001 -0.00579833984375 0.02060546874999752 -0.7382499999999999 -0.005706787109375 0.02060546874999752 -0.738375 -0.005706787109375 0.02060546874999752 -0.7385000000000001 -0.005615234375 0.02060546874999752 -0.738625 -0.005523681640625 0.02060546874999752 -0.73875 -0.005523681640625 0.02060546874999752 -0.7388750000000001 -0.00543212890625 0.02060546874999752 -0.739 -0.00543212890625 0.02060546874999752 -0.739125 -0.005340576171875 0.02060546874999752 -0.73925 -0.0052490234375 0.02060546874999752 -0.739375 -0.0052490234375 0.02060546874999752 -0.7395 -0.005157470703125 0.02060546874999752 -0.739625 -0.005157470703125 0.02060546874999752 -0.73975 -0.00506591796875 0.02060546874999752 -0.7398750000000001 -0.004974365234375 0.02060546874999752 -0.74 -0.004974365234375 0.02060546874999752 -0.740125 -0.0048828125 0.02060546874999752 -0.74025 -0.0048828125 0.02060546874999752 -0.740375 -0.004791259765625 0.02060546874999752 -0.7405 -0.004669189453125 0.02060546874999752 -0.740625 -0.004669189453125 0.02060546874999752 -0.7407500000000001 -0.00457763671875 0.02060546874999752 -0.740875 -0.00457763671875 0.02060546874999752 -0.741 -0.004486083984375 0.02060546874999752 -0.7411250000000001 -0.00439453125 0.02060546874999752 -0.74125 -0.00439453125 0.02060546874999752 -0.741375 -0.004302978515625 0.02060546874999752 -0.7415000000000001 -0.004302978515625 0.02060546874999752 -0.741625 -0.00421142578125 0.02060546874999752 -0.74175 -0.00408935546875 0.02060546874999752 -0.7418750000000001 -0.00408935546875 0.02060546874999752 -0.742 -0.003997802734375 0.02060546874999752 -0.7421250000000001 -0.003997802734375 0.02060546874999752 -0.7422499999999999 -0.00390625 0.02060546874999752 -0.742375 -0.003814697265625 0.02060546874999752 -0.7425000000000001 -0.003814697265625 0.02060546874999752 -0.742625 -0.003692626953125 0.02060546874999752 -0.74275 -0.003692626953125 0.02060546874999752 -0.7428750000000001 -0.00360107421875 0.02060546874999752 -0.743 -0.003509521484375 0.02060546874999752 -0.743125 -0.003509521484375 0.02060546874999752 -0.7432499999999999 -0.003387451171875 0.02060546874999752 -0.743375 -0.003387451171875 0.02060546874999752 -0.7435 -0.0032958984375 0.02060546874999752 -0.7436249999999999 -0.003204345703125 0.02060546874999752 -0.74375 -0.003204345703125 0.02060546874999752 -0.7438750000000001 -0.003082275390625 0.02060546874999752 -0.744 -0.003082275390625 0.02060546874999752 -0.744125 -0.00299072265625 0.02060546874999752 -0.74425 -0.002899169921875 0.02060546874999752 -0.744375 -0.002899169921875 0.02060546874999752 -0.7445 -0.002777099609375 0.02060546874999752 -0.744625 -0.002777099609375 0.02060546874999752 -0.74475 -0.002685546875 0.02060546874999752 -0.744875 -0.0025634765625 0.02060546874999752 -0.745 -0.0025634765625 0.02060546874999752 -0.745125 -0.002471923828125 0.02060546874999752 -0.74525 -0.002471923828125 0.02060546874999752 -0.745375 -0.002349853515625 0.02060546874999752 -0.7455 -0.00225830078125 0.02060546874999752 -0.745625 -0.00225830078125 0.02060546874999752 -0.74575 -0.002166748046875 0.02060546874999752 -0.745875 -0.002166748046875 0.02060546874999752 -0.746 -0.002044677734375 0.02060546874999752 -0.7461250000000001 -0.001953125 0.02060546874999752 -0.7462499999999999 -0.001953125 0.02060546874999752 -0.746375 -0.0018310546875 0.02060546874999752 -0.7465000000000001 -0.0018310546875 0.02060546874999752 -0.746625 -0.001739501953125 0.02060546874999752 -0.74675 -0.001617431640625 0.02060546874999752 -0.7468750000000001 -0.001617431640625 0.02060546874999752 -0.747 -0.00152587890625 0.02060546874999752 -0.747125 -0.00152587890625 0.02060546874999752 -0.74725 -0.00140380859375 0.02060546874999752 -0.747375 -0.001312255859375 0.02060546874999752 -0.7475000000000001 -0.001312255859375 0.02060546874999752 -0.747625 -0.001190185546875 0.02060546874999752 -0.74775 -0.001190185546875 0.02060546874999752 -0.7478750000000001 -0.0010986328125 0.02060546874999752 -0.748 -0.0009765625 0.02060546874999752 -0.748125 -0.0009765625 0.02060546874999752 -0.74825 -0.000885009765625 0.02060546874999752 -0.7483750000000001 -0.000885009765625 0.02060546874999752 -0.7485 -0.000762939453125 0.02060546874999752 -0.748625 -0.00067138671875 0.02060546874999752 -0.7487500000000001 -0.00067138671875 0.02060546874999752 -0.748875 -0.00054931640625 0.02060546874999752 -0.749 -0.00054931640625 0.02060546874999752 -0.7491250000000001 -0.000457763671875 0.02060546874999752 -0.74925 -0.000335693359375 0.02060546874999752 -0.749375 -0.000335693359375 0.02060546874999752 -0.7495000000000001 -0.000244140625 0.02060546874999752 -0.749625 -0.000244140625 0.02060546874999752 -0.74975 -0.0001220703125 0.02060546874999752 +0.6876250000000001 -0.003326416015625 0.6370898437499979 +0.68775 -0.003326416015625 0.6370898437499979 +0.687875 -0.00665283203125 0.6370898437499979 +0.6880000000000001 -0.009979248046875 0.6370898437499979 +0.688125 -0.009979248046875 0.6370898437499979 +0.68825 -0.013336181640625 0.6370898437499979 +0.6883749999999999 -0.013336181640625 0.6370898437499979 +0.6885 -0.016632080078125 0.6370898437499979 +0.688625 -0.019989013671875 0.6370898437499979 +0.6887499999999999 -0.019989013671875 0.6370898437499979 +0.688875 -0.0233154296875 0.6370898437499979 +0.6890000000000001 -0.0233154296875 0.6370898437499979 +0.6891249999999999 -0.026641845703125 0.6370898437499979 +0.68925 -0.02996826171875 0.6370898437499979 +0.689375 -0.02996826171875 0.6370898437499979 +0.6895 -0.03326416015625 0.6370898437499979 +0.689625 -0.03326416015625 0.6370898437499979 +0.68975 -0.036590576171875 0.6370898437499979 +0.689875 -0.039886474609375 0.6370898437499979 +0.69 -0.039886474609375 0.6370898437499979 +0.690125 -0.043212890625 0.6370898437499979 +0.69025 -0.043212890625 0.6370898437499979 +0.690375 -0.0465087890625 0.6370898437499979 +0.6905 -0.0498046875 0.6370898437499979 +0.690625 -0.0498046875 0.6370898437499979 +0.69075 -0.0531005859375 0.6370898437499979 +0.690875 -0.0531005859375 0.6370898437499979 +0.691 -0.056396484375 0.6370898437499979 +0.691125 -0.059661865234375 0.6370898437499979 +0.6912500000000001 -0.059661865234375 0.6370898437499979 +0.6913749999999999 -0.06292724609375 0.6370898437499979 +0.6915 -0.06292724609375 0.6370898437499979 +0.6916250000000001 -0.066192626953125 0.6370898437499979 +0.69175 -0.0694580078125 0.6370898437499979 +0.691875 -0.0694580078125 0.6370898437499979 +0.6920000000000001 -0.072723388671875 0.6370898437499979 +0.692125 -0.072723388671875 0.6370898437499979 +0.69225 -0.075958251953125 0.6370898437499979 +0.692375 -0.079193115234375 0.6370898437499979 +0.6925 -0.079193115234375 0.6370898437499979 +0.692625 -0.082427978515625 0.6370898437499979 +0.69275 -0.082427978515625 0.6370898437499979 +0.692875 -0.08563232421875 0.6370898437499979 +0.6930000000000001 -0.088836669921875 0.6370898437499979 +0.693125 -0.088836669921875 0.6370898437499979 +0.69325 -0.092041015625 0.6370898437499979 +0.693375 -0.092041015625 0.6370898437499979 +0.6935 -0.09521484375 0.6370898437499979 +0.693625 -0.098419189453125 0.6370898437499979 +0.69375 -0.098419189453125 0.6370898437499979 +0.6938750000000001 -0.1015625 0.6370898437499979 +0.694 -0.1015625 0.6370898437499979 +0.694125 -0.104736328125 0.6370898437499979 +0.6942500000000001 -0.107879638671875 0.6370898437499979 +0.694375 -0.107879638671875 0.6370898437499979 +0.6945 -0.110992431640625 0.6370898437499979 +0.6946250000000001 -0.110992431640625 0.6370898437499979 +0.69475 -0.1141357421875 0.6370898437499979 +0.694875 -0.11724853515625 0.6370898437499979 +0.6950000000000001 -0.11724853515625 0.6370898437499979 +0.695125 -0.120330810546875 0.6370898437499979 +0.6952500000000001 -0.120330810546875 0.6370898437499979 +0.6953749999999999 -0.1234130859375 0.6370898437499979 +0.6955 -0.12646484375 0.6370898437499979 +0.6956250000000001 -0.12646484375 0.6370898437499979 +0.69575 -0.129547119140625 0.6370898437499979 +0.695875 -0.129547119140625 0.6370898437499979 +0.6960000000000001 -0.132568359375 0.6370898437499979 +0.696125 -0.135589599609375 0.6370898437499979 +0.69625 -0.135589599609375 0.6370898437499979 +0.6963749999999999 -0.13861083984375 0.6370898437499979 +0.6965 -0.13861083984375 0.6370898437499979 +0.696625 -0.1416015625 0.6370898437499979 +0.6967499999999999 -0.14459228515625 0.6370898437499979 +0.696875 -0.14459228515625 0.6370898437499979 +0.6970000000000001 -0.147552490234375 0.6370898437499979 +0.697125 -0.147552490234375 0.6370898437499979 +0.69725 -0.1505126953125 0.6370898437499979 +0.697375 -0.153411865234375 0.6370898437499979 +0.6975 -0.153411865234375 0.6370898437499979 +0.697625 -0.156341552734375 0.6370898437499979 +0.69775 -0.156341552734375 0.6370898437499979 +0.697875 -0.15924072265625 0.6370898437499979 +0.698 -0.162109375 0.6370898437499979 +0.698125 -0.162109375 0.6370898437499979 +0.69825 -0.16497802734375 0.6370898437499979 +0.698375 -0.16497802734375 0.6370898437499979 +0.6985 -0.167816162109375 0.6370898437499979 +0.698625 -0.170654296875 0.6370898437499979 +0.69875 -0.170654296875 0.6370898437499979 +0.698875 -0.1734619140625 0.6370898437499979 +0.699 -0.1734619140625 0.6370898437499979 +0.699125 -0.176239013671875 0.6370898437499979 +0.6992500000000001 -0.17901611328125 0.6370898437499979 +0.6993749999999999 -0.17901611328125 0.6370898437499979 +0.6995 -0.1817626953125 0.6370898437499979 +0.6996250000000001 -0.1817626953125 0.6370898437499979 +0.69975 -0.184478759765625 0.6370898437499979 +0.699875 -0.18719482421875 0.6370898437499979 +0.7000000000000001 -0.18719482421875 0.6370898437499979 +0.700125 -0.18988037109375 0.6370898437499979 +0.70025 -0.18988037109375 0.6370898437499979 +0.700375 -0.19256591796875 0.6370898437499979 +0.7005 -0.1951904296875 0.6370898437499979 +0.7006250000000001 -0.1951904296875 0.6370898437499979 +0.70075 -0.19781494140625 0.6370898437499979 +0.700875 -0.19781494140625 0.6370898437499979 +0.7010000000000001 -0.200439453125 0.6370898437499979 +0.701125 -0.2030029296875 0.6370898437499979 +0.70125 -0.2030029296875 0.6370898437499979 +0.701375 -0.20556640625 0.6370898437499979 +0.7015000000000001 -0.20556640625 0.6370898437499979 +0.701625 -0.208099365234375 0.6370898437499979 +0.70175 -0.21063232421875 0.6370898437499979 +0.7018750000000001 -0.21063232421875 0.6370898437499979 +0.702 -0.213104248046875 0.6370898437499979 +0.702125 -0.213104248046875 0.6370898437499979 +0.7022500000000001 -0.215576171875 0.6370898437499979 +0.702375 -0.218017578125 0.6370898437499979 +0.7025 -0.218017578125 0.6370898437499979 +0.7026250000000001 -0.220428466796875 0.6370898437499979 +0.70275 -0.220428466796875 0.6370898437499979 +0.702875 -0.22283935546875 0.6370898437499979 +0.7030000000000001 -0.225189208984375 0.6370898437499979 +0.703125 -0.225189208984375 0.6370898437499979 +0.7032500000000001 -0.227569580078125 0.6370898437499979 +0.703375 -0.227569580078125 0.6370898437499979 +0.7035 -0.2298583984375 0.6370898437499979 +0.7036250000000001 -0.232177734375 0.6370898437499979 +0.70375 -0.232177734375 0.6370898437499979 +0.703875 -0.23443603515625 0.6370898437499979 +0.7039999999999999 -0.125091552734375 0.3399999999999977 +0.704125 -0.126312255859375 0.3399999999999977 +0.70425 -0.127471923828125 0.3399999999999977 +0.7043749999999999 -0.127471923828125 0.3399999999999977 +0.7045 -0.128662109375 0.3399999999999977 +0.7046250000000001 -0.128662109375 0.3399999999999977 +0.7047499999999999 -0.12982177734375 0.3399999999999977 +0.704875 -0.130950927734375 0.3399999999999977 +0.705 -0.130950927734375 0.3399999999999977 +0.705125 -0.132080078125 0.3399999999999977 +0.70525 -0.132080078125 0.3399999999999977 +0.705375 -0.1331787109375 0.3399999999999977 +0.7055 -0.134307861328125 0.3399999999999977 +0.705625 -0.134307861328125 0.3399999999999977 +0.70575 -0.1353759765625 0.3399999999999977 +0.705875 -0.1353759765625 0.3399999999999977 +0.706 -0.136444091796875 0.3399999999999977 +0.706125 -0.13751220703125 0.3399999999999977 +0.70625 -0.13751220703125 0.3399999999999977 +0.706375 -0.1385498046875 0.3399999999999977 +0.7065 -0.1385498046875 0.3399999999999977 +0.706625 -0.139556884765625 0.3399999999999977 +0.70675 -0.14056396484375 0.3399999999999977 +0.7068750000000001 -0.14056396484375 0.3399999999999977 +0.7069999999999999 -0.141571044921875 0.3399999999999977 +0.707125 -0.141571044921875 0.3399999999999977 +0.7072500000000001 -0.142547607421875 0.3399999999999977 +0.707375 -0.14349365234375 0.3399999999999977 +0.7075 -0.14349365234375 0.3399999999999977 +0.7076250000000001 -0.144439697265625 0.3399999999999977 +0.70775 -0.144439697265625 0.3399999999999977 +0.707875 -0.1453857421875 0.3399999999999977 +0.708 -0.14630126953125 0.3399999999999977 +0.708125 -0.14630126953125 0.3399999999999977 +0.70825 -0.147186279296875 0.3399999999999977 +0.708375 -0.147186279296875 0.3399999999999977 +0.7085 -0.1480712890625 0.3399999999999977 +0.7086250000000001 -0.14892578125 0.3399999999999977 +0.70875 -0.14892578125 0.3399999999999977 +0.708875 -0.1497802734375 0.3399999999999977 +0.709 -0.1497802734375 0.3399999999999977 +0.709125 -0.150604248046875 0.3399999999999977 +0.70925 -0.15142822265625 0.3399999999999977 +0.709375 -0.15142822265625 0.3399999999999977 +0.7095000000000001 -0.1522216796875 0.3399999999999977 +0.709625 -0.1522216796875 0.3399999999999977 +0.70975 -0.15301513671875 0.3399999999999977 +0.7098750000000001 -0.153778076171875 0.3399999999999977 +0.71 -0.153778076171875 0.3399999999999977 +0.710125 -0.154541015625 0.3399999999999977 +0.7102500000000001 -0.154541015625 0.3399999999999977 +0.710375 -0.1552734375 0.3399999999999977 +0.7105 -0.155975341796875 0.3399999999999977 +0.7106250000000001 -0.155975341796875 0.3399999999999977 +0.71075 -0.15667724609375 0.3399999999999977 +0.7108750000000001 -0.15667724609375 0.3399999999999977 +0.7109999999999999 -0.1573486328125 0.3399999999999977 +0.711125 -0.15802001953125 0.3399999999999977 +0.7112500000000001 -0.15802001953125 0.3399999999999977 +0.711375 -0.158660888671875 0.3399999999999977 +0.7115 -0.158660888671875 0.3399999999999977 +0.7116250000000001 -0.1593017578125 0.3399999999999977 +0.71175 -0.159912109375 0.3399999999999977 +0.711875 -0.159912109375 0.3399999999999977 +0.7119999999999999 -0.160491943359375 0.3399999999999977 +0.712125 -0.160491943359375 0.3399999999999977 +0.71225 -0.16107177734375 0.3399999999999977 +0.7123749999999999 -0.161651611328125 0.3399999999999977 +0.7125 -0.161651611328125 0.3399999999999977 +0.7126250000000001 -0.16217041015625 0.3399999999999977 +0.71275 -0.16217041015625 0.3399999999999977 +0.712875 -0.1627197265625 0.3399999999999977 +0.713 -0.1632080078125 0.3399999999999977 +0.713125 -0.1632080078125 0.3399999999999977 +0.71325 -0.1636962890625 0.3399999999999977 +0.713375 -0.1636962890625 0.3399999999999977 +0.7135 -0.164154052734375 0.3399999999999977 +0.713625 -0.16461181640625 0.3399999999999977 +0.71375 -0.16461181640625 0.3399999999999977 +0.713875 -0.165069580078125 0.3399999999999977 +0.714 -0.165069580078125 0.3399999999999977 +0.714125 -0.16546630859375 0.3399999999999977 +0.71425 -0.165863037109375 0.3399999999999977 +0.714375 -0.165863037109375 0.3399999999999977 +0.7145 -0.166229248046875 0.3399999999999977 +0.714625 -0.166229248046875 0.3399999999999977 +0.71475 -0.166595458984375 0.3399999999999977 +0.7148750000000001 -0.166961669921875 0.3399999999999977 +0.7149999999999999 -0.166961669921875 0.3399999999999977 +0.715125 -0.167266845703125 0.3399999999999977 +0.7152500000000001 -0.167266845703125 0.3399999999999977 +0.715375 -0.167572021484375 0.3399999999999977 +0.7155 -0.167877197265625 0.3399999999999977 +0.7156250000000001 -0.167877197265625 0.3399999999999977 +0.71575 -0.168121337890625 0.3399999999999977 +0.715875 -0.168121337890625 0.3399999999999977 +0.716 -0.16839599609375 0.3399999999999977 +0.716125 -0.168609619140625 0.3399999999999977 +0.7162500000000001 -0.168609619140625 0.3399999999999977 +0.716375 -0.1688232421875 0.3399999999999977 +0.7165 -0.1688232421875 0.3399999999999977 +0.7166250000000001 -0.169036865234375 0.3399999999999977 +0.71675 -0.169219970703125 0.3399999999999977 +0.716875 -0.169219970703125 0.3399999999999977 +0.717 -0.16937255859375 0.3399999999999977 +0.7171250000000001 -0.16937255859375 0.3399999999999977 +0.71725 -0.16949462890625 0.3399999999999977 +0.717375 -0.16961669921875 0.3399999999999977 +0.7175000000000001 -0.16961669921875 0.3399999999999977 +0.717625 -0.16973876953125 0.3399999999999977 +0.71775 -0.16973876953125 0.3399999999999977 +0.7178750000000001 -0.1697998046875 0.3399999999999977 +0.718 -0.16986083984375 0.3399999999999977 +0.718125 -0.16986083984375 0.3399999999999977 +0.7182500000000001 -0.169921875 0.3399999999999977 +0.718375 -0.169921875 0.3399999999999977 +0.7185 -0.169952392578125 0.3399999999999977 +0.7186250000000001 -0.169952392578125 0.3399999999999977 +0.71875 -0.169952392578125 0.3399999999999977 +0.7188750000000001 -0.169952392578125 0.3399999999999977 +0.719 -0.169952392578125 0.3399999999999977 +0.719125 -0.169921875 0.3399999999999977 +0.7192500000000001 -0.16986083984375 0.3399999999999977 +0.719375 -0.16986083984375 0.3399999999999977 +0.7195 -0.1697998046875 0.3399999999999977 +0.7196250000000001 -0.1697998046875 0.3399999999999977 +0.71975 -0.16973876953125 0.3399999999999977 +0.719875 -0.16961669921875 0.3399999999999977 +0.7199999999999999 -0.16961669921875 0.3399999999999977 +0.720125 -0.16949462890625 0.3399999999999977 +0.7202500000000001 -0.16949462890625 0.3399999999999977 +0.7203749999999999 -0.16937255859375 0.3399999999999977 +0.7205 -0.169219970703125 0.3399999999999977 +0.720625 -0.169219970703125 0.3399999999999977 +0.72075 -0.169036865234375 0.3399999999999977 +0.720875 -0.169036865234375 0.3399999999999977 +0.721 -0.1688232421875 0.3399999999999977 +0.721125 -0.168609619140625 0.3399999999999977 +0.72125 -0.168609619140625 0.3399999999999977 +0.721375 -0.16839599609375 0.3399999999999977 +0.7215 -0.16839599609375 0.3399999999999977 +0.721625 -0.168121337890625 0.3399999999999977 +0.72175 -0.167877197265625 0.3399999999999977 +0.721875 -0.167877197265625 0.3399999999999977 +0.722 -0.167572021484375 0.3399999999999977 +0.722125 -0.167572021484375 0.3399999999999977 +0.72225 -0.167266845703125 0.3399999999999977 +0.722375 -0.166961669921875 0.3399999999999977 +0.7225000000000001 -0.166961669921875 0.3399999999999977 +0.7226249999999999 -0.166595458984375 0.3399999999999977 +0.72275 -0.166595458984375 0.3399999999999977 +0.7228750000000001 -0.166229248046875 0.3399999999999977 +0.723 -0.165863037109375 0.3399999999999977 +0.723125 -0.165863037109375 0.3399999999999977 +0.7232500000000001 -0.16546630859375 0.3399999999999977 +0.723375 -0.16546630859375 0.3399999999999977 +0.7235 -0.165069580078125 0.3399999999999977 +0.723625 -0.16461181640625 0.3399999999999977 +0.72375 -0.16461181640625 0.3399999999999977 +0.723875 -0.164154052734375 0.3399999999999977 +0.724 -0.164154052734375 0.3399999999999977 +0.724125 -0.1636962890625 0.3399999999999977 +0.7242500000000001 -0.1632080078125 0.3399999999999977 +0.724375 -0.1632080078125 0.3399999999999977 +0.7245 -0.1627197265625 0.3399999999999977 +0.724625 -0.1627197265625 0.3399999999999977 +0.72475 -0.16217041015625 0.3399999999999977 +0.724875 -0.161651611328125 0.3399999999999977 +0.725 -0.161651611328125 0.3399999999999977 +0.7251250000000001 -0.16107177734375 0.3399999999999977 +0.72525 -0.16107177734375 0.3399999999999977 +0.725375 -0.160491943359375 0.3399999999999977 +0.7255000000000001 -0.159912109375 0.3399999999999977 +0.725625 -0.159912109375 0.3399999999999977 +0.72575 -0.1593017578125 0.3399999999999977 +0.7258750000000001 -0.1593017578125 0.3399999999999977 +0.726 -0.158660888671875 0.3399999999999977 +0.726125 -0.15802001953125 0.3399999999999977 +0.7262500000000001 -0.15802001953125 0.3399999999999977 +0.726375 -0.1573486328125 0.3399999999999977 +0.7265000000000001 -0.1573486328125 0.3399999999999977 +0.7266249999999999 -0.15667724609375 0.3399999999999977 +0.72675 -0.155975341796875 0.3399999999999977 +0.7268750000000001 -0.155975341796875 0.3399999999999977 +0.727 -0.1552734375 0.3399999999999977 +0.727125 -0.1552734375 0.3399999999999977 +0.7272500000000001 -0.154541015625 0.3399999999999977 +0.727375 -0.153778076171875 0.3399999999999977 +0.7275 -0.153778076171875 0.3399999999999977 +0.7276249999999999 -0.15301513671875 0.3399999999999977 +0.72775 -0.15301513671875 0.3399999999999977 +0.727875 -0.1522216796875 0.3399999999999977 +0.7279999999999999 -0.15142822265625 0.3399999999999977 +0.728125 -0.15142822265625 0.3399999999999977 +0.7282500000000001 -0.150604248046875 0.3399999999999977 +0.728375 -0.150604248046875 0.3399999999999977 +0.7285 -0.1497802734375 0.3399999999999977 +0.728625 -0.14892578125 0.3399999999999977 +0.72875 -0.14892578125 0.3399999999999977 +0.728875 -0.1480712890625 0.3399999999999977 +0.729 -0.1480712890625 0.3399999999999977 +0.729125 -0.147186279296875 0.3399999999999977 +0.72925 -0.14630126953125 0.3399999999999977 +0.729375 -0.14630126953125 0.3399999999999977 +0.7295 -0.1453857421875 0.3399999999999977 +0.729625 -0.1453857421875 0.3399999999999977 +0.72975 -0.144439697265625 0.3399999999999977 +0.729875 -0.14349365234375 0.3399999999999977 +0.73 -0.14349365234375 0.3399999999999977 +0.730125 -0.142547607421875 0.3399999999999977 +0.73025 -0.142547607421875 0.3399999999999977 +0.730375 -0.141571044921875 0.3399999999999977 +0.7305000000000001 -0.14056396484375 0.3399999999999977 +0.7306249999999999 -0.14056396484375 0.3399999999999977 +0.73075 -0.139556884765625 0.3399999999999977 +0.7308750000000001 -0.139556884765625 0.3399999999999977 +0.731 -0.1385498046875 0.3399999999999977 +0.731125 -0.13751220703125 0.3399999999999977 +0.7312500000000001 -0.13751220703125 0.3399999999999977 +0.731375 -0.136444091796875 0.3399999999999977 +0.7315 -0.136444091796875 0.3399999999999977 +0.731625 -0.1353759765625 0.3399999999999977 +0.73175 -0.134307861328125 0.3399999999999977 +0.7318750000000001 -0.134307861328125 0.3399999999999977 +0.732 -0.1331787109375 0.3399999999999977 +0.732125 -0.1331787109375 0.3399999999999977 +0.7322500000000001 -0.132080078125 0.3399999999999977 +0.732375 -0.130950927734375 0.3399999999999977 +0.7325 -0.130950927734375 0.3399999999999977 +0.732625 -0.12982177734375 0.3399999999999977 +0.7327500000000001 -0.12982177734375 0.3399999999999977 +0.732875 -0.128662109375 0.3399999999999977 +0.733 -0.127471923828125 0.3399999999999977 +0.7331250000000001 -0.127471923828125 0.3399999999999977 +0.73325 -0.126312255859375 0.3399999999999977 +0.733375 -0.126312255859375 0.3399999999999977 +0.7335000000000001 -0.125091552734375 0.3399999999999977 +0.733625 -0.1239013671875 0.3399999999999977 +0.73375 -0.1239013671875 0.3399999999999977 +0.7338750000000001 -0.122650146484375 0.3399999999999977 +0.734 -0.122650146484375 0.3399999999999977 +0.734125 -0.121429443359375 0.3399999999999977 +0.7342500000000001 -0.12017822265625 0.3399999999999977 +0.734375 -0.12017822265625 0.3399999999999977 +0.7345000000000001 -0.118896484375 0.3399999999999977 +0.734625 -0.118896484375 0.3399999999999977 +0.73475 -0.117645263671875 0.3399999999999977 +0.7348750000000001 -0.1163330078125 0.3399999999999977 +0.735 -0.1163330078125 0.3399999999999977 +0.735125 -0.11505126953125 0.3399999999999977 +0.7352500000000001 -0.11505126953125 0.3399999999999977 +0.735375 -0.11370849609375 0.3399999999999977 +0.7355 -0.112396240234375 0.3399999999999977 +0.7356249999999999 -0.112396240234375 0.3399999999999977 +0.73575 -0.111053466796875 0.3399999999999977 +0.7358750000000001 -0.111053466796875 0.3399999999999977 +0.7359999999999999 -0.006622314453125 0.02060546874999752 +0.736125 -0.00653076171875 0.02060546874999752 +0.73625 -0.00653076171875 0.02060546874999752 +0.736375 -0.0064697265625 0.02060546874999752 +0.7365 -0.0064697265625 0.02060546874999752 +0.736625 -0.006378173828125 0.02060546874999752 +0.73675 -0.00628662109375 0.02060546874999752 +0.736875 -0.00628662109375 0.02060546874999752 +0.737 -0.006195068359375 0.02060546874999752 +0.737125 -0.006195068359375 0.02060546874999752 +0.73725 -0.006103515625 0.02060546874999752 +0.737375 -0.00604248046875 0.02060546874999752 +0.7375 -0.00604248046875 0.02060546874999752 +0.737625 -0.005950927734375 0.02060546874999752 +0.73775 -0.005950927734375 0.02060546874999752 +0.737875 -0.005859375 0.02060546874999752 +0.738 -0.005767822265625 0.02060546874999752 +0.7381250000000001 -0.005767822265625 0.02060546874999752 +0.7382499999999999 -0.00567626953125 0.02060546874999752 +0.738375 -0.00567626953125 0.02060546874999752 +0.7385000000000001 -0.005584716796875 0.02060546874999752 +0.738625 -0.0054931640625 0.02060546874999752 +0.73875 -0.0054931640625 0.02060546874999752 +0.7388750000000001 -0.005401611328125 0.02060546874999752 +0.739 -0.005401611328125 0.02060546874999752 +0.739125 -0.00531005859375 0.02060546874999752 +0.73925 -0.005218505859375 0.02060546874999752 +0.739375 -0.005218505859375 0.02060546874999752 +0.7395 -0.005126953125 0.02060546874999752 +0.739625 -0.005126953125 0.02060546874999752 +0.73975 -0.005035400390625 0.02060546874999752 +0.7398750000000001 -0.00494384765625 0.02060546874999752 +0.74 -0.00494384765625 0.02060546874999752 +0.740125 -0.004852294921875 0.02060546874999752 +0.74025 -0.004852294921875 0.02060546874999752 +0.740375 -0.0047607421875 0.02060546874999752 +0.7405 -0.004638671875 0.02060546874999752 +0.740625 -0.004638671875 0.02060546874999752 +0.7407500000000001 -0.004547119140625 0.02060546874999752 +0.740875 -0.004547119140625 0.02060546874999752 +0.741 -0.00445556640625 0.02060546874999752 +0.7411250000000001 -0.004364013671875 0.02060546874999752 +0.74125 -0.004364013671875 0.02060546874999752 +0.741375 -0.0042724609375 0.02060546874999752 +0.7415000000000001 -0.0042724609375 0.02060546874999752 +0.741625 -0.004180908203125 0.02060546874999752 +0.74175 -0.004058837890625 0.02060546874999752 +0.7418750000000001 -0.004058837890625 0.02060546874999752 +0.742 -0.00396728515625 0.02060546874999752 +0.7421250000000001 -0.00396728515625 0.02060546874999752 +0.7422499999999999 -0.003875732421875 0.02060546874999752 +0.742375 -0.0037841796875 0.02060546874999752 +0.7425000000000001 -0.0037841796875 0.02060546874999752 +0.742625 -0.003662109375 0.02060546874999752 +0.74275 -0.003662109375 0.02060546874999752 +0.7428750000000001 -0.003570556640625 0.02060546874999752 +0.743 -0.00347900390625 0.02060546874999752 +0.743125 -0.00347900390625 0.02060546874999752 +0.7432499999999999 -0.00335693359375 0.02060546874999752 +0.743375 -0.00335693359375 0.02060546874999752 +0.7435 -0.003265380859375 0.02060546874999752 +0.7436249999999999 -0.003173828125 0.02060546874999752 +0.74375 -0.003173828125 0.02060546874999752 +0.7438750000000001 -0.0030517578125 0.02060546874999752 +0.744 -0.0030517578125 0.02060546874999752 +0.744125 -0.002960205078125 0.02060546874999752 +0.74425 -0.00286865234375 0.02060546874999752 +0.744375 -0.00286865234375 0.02060546874999752 +0.7445 -0.00274658203125 0.02060546874999752 +0.744625 -0.00274658203125 0.02060546874999752 +0.74475 -0.002655029296875 0.02060546874999752 +0.744875 -0.002532958984375 0.02060546874999752 +0.745 -0.002532958984375 0.02060546874999752 +0.745125 -0.00244140625 0.02060546874999752 +0.74525 -0.00244140625 0.02060546874999752 +0.745375 -0.0023193359375 0.02060546874999752 +0.7455 -0.002227783203125 0.02060546874999752 +0.745625 -0.002227783203125 0.02060546874999752 +0.74575 -0.00213623046875 0.02060546874999752 +0.745875 -0.00213623046875 0.02060546874999752 +0.746 -0.00201416015625 0.02060546874999752 +0.7461250000000001 -0.001922607421875 0.02060546874999752 +0.7462499999999999 -0.001922607421875 0.02060546874999752 +0.746375 -0.001800537109375 0.02060546874999752 +0.7465000000000001 -0.001800537109375 0.02060546874999752 +0.746625 -0.001708984375 0.02060546874999752 +0.74675 -0.0015869140625 0.02060546874999752 +0.7468750000000001 -0.0015869140625 0.02060546874999752 +0.747 -0.001495361328125 0.02060546874999752 +0.747125 -0.001495361328125 0.02060546874999752 +0.74725 -0.001373291015625 0.02060546874999752 +0.747375 -0.00128173828125 0.02060546874999752 +0.7475000000000001 -0.00128173828125 0.02060546874999752 +0.747625 -0.00115966796875 0.02060546874999752 +0.74775 -0.00115966796875 0.02060546874999752 +0.7478750000000001 -0.001068115234375 0.02060546874999752 +0.748 -0.000946044921875 0.02060546874999752 +0.748125 -0.000946044921875 0.02060546874999752 +0.74825 -0.0008544921875 0.02060546874999752 +0.7483750000000001 -0.0008544921875 0.02060546874999752 +0.7485 -0.000732421875 0.02060546874999752 +0.748625 -0.000640869140625 0.02060546874999752 +0.7487500000000001 -0.000640869140625 0.02060546874999752 +0.748875 -0.000518798828125 0.02060546874999752 +0.749 -0.000518798828125 0.02060546874999752 +0.7491250000000001 -0.00042724609375 0.02060546874999752 +0.74925 -0.00030517578125 0.02060546874999752 +0.749375 -0.00030517578125 0.02060546874999752 +0.7495000000000001 -0.000213623046875 0.02060546874999752 +0.749625 -0.000213623046875 0.02060546874999752 +0.74975 -9.1552734375e-05 0.02060546874999752 0.7498750000000001 0.0 0.02060546874999752 0.75 0.0 0.02060546874999752 0.7501250000000001 9.1552734375e-05 0.02060546874999752 @@ -6142,361 +6142,361 @@ 0.767625 0.007965087890625 0.02060546874999752 0.76775 0.007965087890625 0.02060546874999752 0.767875 0.008056640625 0.02060546874999752 -0.768 -0.10675048828125 -0.2701904296875024 -0.768125 -0.10675048828125 -0.2701904296875024 -0.76825 -0.107635498046875 -0.2701904296875024 -0.768375 -0.107635498046875 -0.2701904296875024 -0.7685 -0.10845947265625 -0.2701904296875024 -0.768625 -0.10931396484375 -0.2701904296875024 -0.76875 -0.10931396484375 -0.2701904296875024 -0.768875 -0.110137939453125 -0.2701904296875024 -0.769 -0.110137939453125 -0.2701904296875024 -0.769125 -0.1109619140625 -0.2701904296875024 -0.76925 -0.11175537109375 -0.2701904296875024 -0.7693750000000001 -0.11175537109375 -0.2701904296875024 -0.7694999999999999 -0.112548828125 -0.2701904296875024 -0.769625 -0.112548828125 -0.2701904296875024 -0.7697500000000001 -0.113311767578125 -0.2701904296875024 -0.769875 -0.11407470703125 -0.2701904296875024 -0.77 -0.11407470703125 -0.2701904296875024 -0.7701250000000001 -0.114837646484375 -0.2701904296875024 -0.77025 -0.114837646484375 -0.2701904296875024 -0.770375 -0.115570068359375 -0.2701904296875024 -0.7705 -0.116302490234375 -0.2701904296875024 -0.770625 -0.116302490234375 -0.2701904296875024 -0.77075 -0.11700439453125 -0.2701904296875024 -0.770875 -0.11700439453125 -0.2701904296875024 -0.771 -0.117706298828125 -0.2701904296875024 -0.7711250000000001 -0.118408203125 -0.2701904296875024 -0.77125 -0.118408203125 -0.2701904296875024 -0.771375 -0.11907958984375 -0.2701904296875024 -0.7715 -0.11907958984375 -0.2701904296875024 -0.771625 -0.1197509765625 -0.2701904296875024 -0.77175 -0.120391845703125 -0.2701904296875024 -0.771875 -0.120391845703125 -0.2701904296875024 -0.7720000000000001 -0.12103271484375 -0.2701904296875024 -0.772125 -0.12103271484375 -0.2701904296875024 -0.77225 -0.12164306640625 -0.2701904296875024 -0.7723750000000001 -0.12225341796875 -0.2701904296875024 -0.7725 -0.12225341796875 -0.2701904296875024 -0.772625 -0.122833251953125 -0.2701904296875024 -0.7727500000000001 -0.122833251953125 -0.2701904296875024 -0.772875 -0.123443603515625 -0.2701904296875024 -0.773 -0.123992919921875 -0.2701904296875024 -0.7731250000000001 -0.123992919921875 -0.2701904296875024 -0.77325 -0.124542236328125 -0.2701904296875024 -0.7733750000000001 -0.124542236328125 -0.2701904296875024 -0.7734999999999999 -0.125091552734375 -0.2701904296875024 -0.773625 -0.1256103515625 -0.2701904296875024 -0.7737500000000001 -0.1256103515625 -0.2701904296875024 -0.773875 -0.126129150390625 -0.2701904296875024 -0.774 -0.126129150390625 -0.2701904296875024 -0.7741250000000001 -0.12664794921875 -0.2701904296875024 -0.77425 -0.12713623046875 -0.2701904296875024 -0.774375 -0.12713623046875 -0.2701904296875024 -0.7744999999999999 -0.127593994140625 -0.2701904296875024 -0.774625 -0.127593994140625 -0.2701904296875024 -0.77475 -0.1280517578125 -0.2701904296875024 -0.7748749999999999 -0.128509521484375 -0.2701904296875024 -0.775 -0.128509521484375 -0.2701904296875024 -0.7751250000000001 -0.128936767578125 -0.2701904296875024 -0.77525 -0.128936767578125 -0.2701904296875024 -0.775375 -0.12933349609375 -0.2701904296875024 -0.7755 -0.129730224609375 -0.2701904296875024 -0.775625 -0.129730224609375 -0.2701904296875024 -0.77575 -0.130126953125 -0.2701904296875024 -0.775875 -0.130126953125 -0.2701904296875024 -0.776 -0.1304931640625 -0.2701904296875024 -0.776125 -0.130859375 -0.2701904296875024 -0.77625 -0.130859375 -0.2701904296875024 -0.776375 -0.1312255859375 -0.2701904296875024 -0.7765 -0.1312255859375 -0.2701904296875024 -0.776625 -0.13153076171875 -0.2701904296875024 -0.77675 -0.131866455078125 -0.2701904296875024 -0.776875 -0.131866455078125 -0.2701904296875024 -0.777 -0.13214111328125 -0.2701904296875024 -0.777125 -0.13214111328125 -0.2701904296875024 -0.77725 -0.1324462890625 -0.2701904296875024 -0.7773750000000001 -0.132720947265625 -0.2701904296875024 -0.7774999999999999 -0.132720947265625 -0.2701904296875024 -0.777625 -0.132965087890625 -0.2701904296875024 -0.7777500000000001 -0.132965087890625 -0.2701904296875024 -0.777875 -0.133209228515625 -0.2701904296875024 -0.778 -0.133453369140625 -0.2701904296875024 -0.7781250000000001 -0.133453369140625 -0.2701904296875024 -0.77825 -0.1336669921875 -0.2701904296875024 -0.778375 -0.1336669921875 -0.2701904296875024 -0.7785 -0.13385009765625 -0.2701904296875024 -0.778625 -0.134033203125 -0.2701904296875024 -0.7787500000000001 -0.134033203125 -0.2701904296875024 -0.778875 -0.13421630859375 -0.2701904296875024 -0.779 -0.13421630859375 -0.2701904296875024 -0.7791250000000001 -0.134368896484375 -0.2701904296875024 -0.77925 -0.134521484375 -0.2701904296875024 -0.779375 -0.134521484375 -0.2701904296875024 -0.7795 -0.1346435546875 -0.2701904296875024 -0.7796250000000001 -0.1346435546875 -0.2701904296875024 -0.77975 -0.134735107421875 -0.2701904296875024 -0.779875 -0.134857177734375 -0.2701904296875024 -0.7800000000000001 -0.134857177734375 -0.2701904296875024 -0.780125 -0.134918212890625 -0.2701904296875024 -0.78025 -0.134918212890625 -0.2701904296875024 -0.7803750000000001 -0.134979248046875 -0.2701904296875024 -0.7805 -0.135040283203125 -0.2701904296875024 -0.780625 -0.135040283203125 -0.2701904296875024 -0.7807500000000001 -0.13507080078125 -0.2701904296875024 -0.780875 -0.13507080078125 -0.2701904296875024 -0.781 -0.135101318359375 -0.2701904296875024 -0.7811250000000001 -0.135101318359375 -0.2701904296875024 -0.78125 -0.135101318359375 -0.2701904296875024 -0.7813750000000001 -0.135101318359375 -0.2701904296875024 -0.7815 -0.135101318359375 -0.2701904296875024 -0.781625 -0.13507080078125 -0.2701904296875024 -0.7817500000000001 -0.135040283203125 -0.2701904296875024 -0.781875 -0.135040283203125 -0.2701904296875024 -0.782 -0.134979248046875 -0.2701904296875024 -0.7821250000000001 -0.134979248046875 -0.2701904296875024 -0.78225 -0.134918212890625 -0.2701904296875024 -0.782375 -0.134857177734375 -0.2701904296875024 -0.7824999999999999 -0.134857177734375 -0.2701904296875024 -0.782625 -0.134735107421875 -0.2701904296875024 -0.7827500000000001 -0.134735107421875 -0.2701904296875024 -0.7828749999999999 -0.1346435546875 -0.2701904296875024 -0.783 -0.134521484375 -0.2701904296875024 -0.7831250000000001 -0.134521484375 -0.2701904296875024 -0.78325 -0.134368896484375 -0.2701904296875024 -0.783375 -0.134368896484375 -0.2701904296875024 -0.7835 -0.13421630859375 -0.2701904296875024 -0.783625 -0.134033203125 -0.2701904296875024 -0.78375 -0.134033203125 -0.2701904296875024 -0.783875 -0.13385009765625 -0.2701904296875024 -0.784 -0.13385009765625 -0.2701904296875024 -0.784125 -0.1336669921875 -0.2701904296875024 -0.78425 -0.133453369140625 -0.2701904296875024 -0.784375 -0.133453369140625 -0.2701904296875024 -0.7845 -0.133209228515625 -0.2701904296875024 -0.784625 -0.133209228515625 -0.2701904296875024 -0.78475 -0.132965087890625 -0.2701904296875024 -0.784875 -0.132720947265625 -0.2701904296875024 -0.7850000000000001 -0.132720947265625 -0.2701904296875024 -0.7851249999999999 -0.1324462890625 -0.2701904296875024 -0.78525 -0.1324462890625 -0.2701904296875024 -0.7853750000000001 -0.13214111328125 -0.2701904296875024 -0.7855 -0.131866455078125 -0.2701904296875024 -0.785625 -0.131866455078125 -0.2701904296875024 -0.7857500000000001 -0.13153076171875 -0.2701904296875024 -0.785875 -0.13153076171875 -0.2701904296875024 -0.786 -0.1312255859375 -0.2701904296875024 -0.786125 -0.130859375 -0.2701904296875024 -0.78625 -0.130859375 -0.2701904296875024 -0.786375 -0.1304931640625 -0.2701904296875024 -0.7865 -0.1304931640625 -0.2701904296875024 -0.786625 -0.130126953125 -0.2701904296875024 -0.7867500000000001 -0.129730224609375 -0.2701904296875024 -0.786875 -0.129730224609375 -0.2701904296875024 -0.787 -0.12933349609375 -0.2701904296875024 -0.787125 -0.12933349609375 -0.2701904296875024 -0.78725 -0.128936767578125 -0.2701904296875024 -0.787375 -0.128509521484375 -0.2701904296875024 -0.7875 -0.128509521484375 -0.2701904296875024 -0.7876250000000001 -0.1280517578125 -0.2701904296875024 -0.78775 -0.1280517578125 -0.2701904296875024 -0.787875 -0.127593994140625 -0.2701904296875024 -0.7880000000000001 -0.12713623046875 -0.2701904296875024 -0.788125 -0.12713623046875 -0.2701904296875024 -0.78825 -0.12664794921875 -0.2701904296875024 -0.7883750000000001 -0.12664794921875 -0.2701904296875024 -0.7885 -0.126129150390625 -0.2701904296875024 -0.788625 -0.1256103515625 -0.2701904296875024 -0.7887500000000001 -0.1256103515625 -0.2701904296875024 -0.788875 -0.125091552734375 -0.2701904296875024 -0.7890000000000001 -0.125091552734375 -0.2701904296875024 -0.7891249999999999 -0.124542236328125 -0.2701904296875024 -0.78925 -0.123992919921875 -0.2701904296875024 -0.7893750000000001 -0.123992919921875 -0.2701904296875024 -0.7895 -0.123443603515625 -0.2701904296875024 -0.789625 -0.123443603515625 -0.2701904296875024 -0.7897500000000001 -0.122833251953125 -0.2701904296875024 -0.789875 -0.12225341796875 -0.2701904296875024 -0.79 -0.12225341796875 -0.2701904296875024 -0.7901249999999999 -0.12164306640625 -0.2701904296875024 -0.79025 -0.12164306640625 -0.2701904296875024 -0.790375 -0.12103271484375 -0.2701904296875024 -0.7904999999999999 -0.120391845703125 -0.2701904296875024 -0.790625 -0.120391845703125 -0.2701904296875024 -0.7907500000000001 -0.1197509765625 -0.2701904296875024 -0.790875 -0.1197509765625 -0.2701904296875024 -0.791 -0.11907958984375 -0.2701904296875024 -0.791125 -0.118408203125 -0.2701904296875024 -0.79125 -0.118408203125 -0.2701904296875024 -0.791375 -0.117706298828125 -0.2701904296875024 -0.7915 -0.117706298828125 -0.2701904296875024 -0.791625 -0.11700439453125 -0.2701904296875024 -0.79175 -0.116302490234375 -0.2701904296875024 -0.791875 -0.116302490234375 -0.2701904296875024 -0.792 -0.115570068359375 -0.2701904296875024 -0.792125 -0.115570068359375 -0.2701904296875024 -0.79225 -0.114837646484375 -0.2701904296875024 -0.792375 -0.11407470703125 -0.2701904296875024 -0.7925 -0.11407470703125 -0.2701904296875024 -0.792625 -0.113311767578125 -0.2701904296875024 -0.79275 -0.113311767578125 -0.2701904296875024 -0.792875 -0.112548828125 -0.2701904296875024 -0.7930000000000001 -0.11175537109375 -0.2701904296875024 -0.7931249999999999 -0.11175537109375 -0.2701904296875024 -0.79325 -0.1109619140625 -0.2701904296875024 -0.7933750000000001 -0.1109619140625 -0.2701904296875024 -0.7935 -0.110137939453125 -0.2701904296875024 -0.793625 -0.10931396484375 -0.2701904296875024 -0.7937500000000001 -0.10931396484375 -0.2701904296875024 -0.793875 -0.10845947265625 -0.2701904296875024 -0.794 -0.10845947265625 -0.2701904296875024 -0.794125 -0.107635498046875 -0.2701904296875024 -0.79425 -0.10675048828125 -0.2701904296875024 -0.7943750000000001 -0.10675048828125 -0.2701904296875024 -0.7945 -0.10589599609375 -0.2701904296875024 -0.794625 -0.10589599609375 -0.2701904296875024 -0.7947500000000001 -0.105010986328125 -0.2701904296875024 -0.794875 -0.104095458984375 -0.2701904296875024 -0.795 -0.104095458984375 -0.2701904296875024 -0.795125 -0.10321044921875 -0.2701904296875024 -0.7952500000000001 -0.10321044921875 -0.2701904296875024 -0.795375 -0.102294921875 -0.2701904296875024 -0.7955 -0.101348876953125 -0.2701904296875024 -0.7956250000000001 -0.101348876953125 -0.2701904296875024 -0.79575 -0.10040283203125 -0.2701904296875024 -0.795875 -0.10040283203125 -0.2701904296875024 -0.7960000000000001 -0.099456787109375 -0.2701904296875024 -0.796125 -0.0985107421875 -0.2701904296875024 -0.79625 -0.0985107421875 -0.2701904296875024 -0.7963750000000001 -0.0975341796875 -0.2701904296875024 -0.7965 -0.0975341796875 -0.2701904296875024 -0.796625 -0.096527099609375 -0.2701904296875024 -0.7967500000000001 -0.095550537109375 -0.2701904296875024 -0.796875 -0.095550537109375 -0.2701904296875024 -0.7970000000000001 -0.09454345703125 -0.2701904296875024 -0.797125 -0.09454345703125 -0.2701904296875024 -0.79725 -0.093505859375 -0.2701904296875024 -0.7973750000000001 -0.092498779296875 -0.2701904296875024 -0.7975 -0.092498779296875 -0.2701904296875024 -0.797625 -0.091461181640625 -0.2701904296875024 -0.7977500000000001 -0.091461181640625 -0.2701904296875024 -0.797875 -0.090423583984375 -0.2701904296875024 -0.798 -0.08935546875 -0.2701904296875024 -0.7981249999999999 -0.08935546875 -0.2701904296875024 -0.79825 -0.088287353515625 -0.2701904296875024 -0.7983750000000001 -0.088287353515625 -0.2701904296875024 -0.7984999999999999 -0.08721923828125 -0.2701904296875024 -0.798625 -0.08612060546875 -0.2701904296875024 -0.7987500000000001 -0.08612060546875 -0.2701904296875024 -0.798875 -0.08502197265625 -0.2701904296875024 -0.799 -0.08502197265625 -0.2701904296875024 -0.799125 -0.08392333984375 -0.2701904296875024 -0.79925 -0.08282470703125 -0.2701904296875024 -0.799375 -0.08282470703125 -0.2701904296875024 -0.7995 -0.081695556640625 -0.2701904296875024 -0.799625 -0.081695556640625 -0.2701904296875024 -0.79975 -0.08056640625 -0.2701904296875024 -0.799875 -0.07940673828125 -0.2701904296875024 -0.8 -0.142822265625 -0.4859716796875017 -0.8001249999999999 -0.140777587890625 -0.4859716796875017 -0.80025 -0.140777587890625 -0.4859716796875017 -0.800375 -0.138671875 -0.4859716796875017 -0.8004999999999999 -0.136566162109375 -0.4859716796875017 -0.800625 -0.136566162109375 -0.4859716796875017 -0.80075 -0.13446044921875 -0.4859716796875017 -0.8008749999999999 -0.13446044921875 -0.4859716796875017 -0.801 -0.132354736328125 -0.4859716796875017 -0.801125 -0.130218505859375 -0.4859716796875017 -0.8012499999999999 -0.130218505859375 -0.4859716796875017 -0.801375 -0.1280517578125 -0.4859716796875017 -0.8015000000000001 -0.1280517578125 -0.4859716796875017 -0.8016249999999999 -0.125885009765625 -0.4859716796875017 -0.80175 -0.123687744140625 -0.4859716796875017 -0.8018750000000001 -0.123687744140625 -0.4859716796875017 -0.802 -0.121490478515625 -0.4859716796875017 -0.802125 -0.121490478515625 -0.4859716796875017 -0.8022500000000001 -0.119293212890625 -0.4859716796875017 -0.802375 -0.1170654296875 -0.4859716796875017 -0.8025 -0.1170654296875 -0.4859716796875017 -0.8026250000000001 -0.114837646484375 -0.4859716796875017 -0.80275 -0.114837646484375 -0.4859716796875017 -0.802875 -0.112579345703125 -0.4859716796875017 -0.8030000000000001 -0.110321044921875 -0.4859716796875017 -0.803125 -0.110321044921875 -0.4859716796875017 -0.8032500000000001 -0.1080322265625 -0.4859716796875017 -0.8033750000000001 -0.1080322265625 -0.4859716796875017 -0.8035 -0.10577392578125 -0.4859716796875017 -0.8036250000000001 -0.10345458984375 -0.4859716796875017 -0.80375 -0.10345458984375 -0.4859716796875017 -0.803875 -0.101165771484375 -0.4859716796875017 -0.8040000000000001 -0.101165771484375 -0.4859716796875017 -0.804125 -0.098846435546875 -0.4859716796875017 -0.80425 -0.09649658203125 -0.4859716796875017 -0.8043750000000001 -0.09649658203125 -0.4859716796875017 -0.8045 -0.09417724609375 -0.4859716796875017 -0.8046250000000001 -0.09417724609375 -0.4859716796875017 -0.8047499999999999 -0.091827392578125 -0.4859716796875017 -0.804875 -0.089447021484375 -0.4859716796875017 -0.8050000000000001 -0.089447021484375 -0.4859716796875017 -0.805125 -0.08709716796875 -0.4859716796875017 -0.80525 -0.08709716796875 -0.4859716796875017 -0.8053750000000001 -0.084716796875 -0.4859716796875017 -0.8055 -0.082305908203125 -0.4859716796875017 -0.805625 -0.082305908203125 -0.4859716796875017 -0.8057499999999999 -0.079925537109375 -0.4859716796875017 -0.805875 -0.079925537109375 -0.4859716796875017 -0.806 -0.0775146484375 -0.4859716796875017 -0.8061249999999999 -0.075103759765625 -0.4859716796875017 -0.80625 -0.075103759765625 -0.4859716796875017 -0.8063750000000001 -0.072662353515625 -0.4859716796875017 -0.8065 -0.072662353515625 -0.4859716796875017 -0.806625 -0.07025146484375 -0.4859716796875017 -0.8067499999999999 -0.06781005859375 -0.4859716796875017 -0.806875 -0.06781005859375 -0.4859716796875017 -0.807 -0.065338134765625 -0.4859716796875017 -0.8071249999999999 -0.065338134765625 -0.4859716796875017 -0.80725 -0.062896728515625 -0.4859716796875017 -0.807375 -0.0604248046875 -0.4859716796875017 -0.8074999999999999 -0.0604248046875 -0.4859716796875017 -0.807625 -0.0579833984375 -0.4859716796875017 -0.8077500000000001 -0.0579833984375 -0.4859716796875017 -0.8078749999999999 -0.05548095703125 -0.4859716796875017 -0.808 -0.053009033203125 -0.4859716796875017 -0.8081250000000001 -0.053009033203125 -0.4859716796875017 -0.80825 -0.050537109375 -0.4859716796875017 -0.808375 -0.050537109375 -0.4859716796875017 -0.8085000000000001 -0.04803466796875 -0.4859716796875017 -0.808625 -0.0455322265625 -0.4859716796875017 -0.80875 -0.0455322265625 -0.4859716796875017 -0.8088750000000001 -0.04302978515625 -0.4859716796875017 -0.809 -0.04302978515625 -0.4859716796875017 -0.809125 -0.04052734375 -0.4859716796875017 -0.8092500000000001 -0.03802490234375 -0.4859716796875017 -0.809375 -0.03802490234375 -0.4859716796875017 -0.8095000000000001 -0.035491943359375 -0.4859716796875017 -0.8096250000000001 -0.035491943359375 -0.4859716796875017 -0.80975 -0.032989501953125 -0.4859716796875017 -0.8098750000000001 -0.03045654296875 -0.4859716796875017 -0.8100000000000001 -0.03045654296875 -0.4859716796875017 -0.810125 -0.0279541015625 -0.4859716796875017 -0.8102500000000001 -0.0279541015625 -0.4859716796875017 -0.8103750000000002 -0.025421142578125 -0.4859716796875017 -0.8105 -0.02288818359375 -0.4859716796875017 -0.8106250000000001 -0.02288818359375 -0.4859716796875017 -0.81075 -0.020355224609375 -0.4859716796875017 -0.8108750000000001 -0.020355224609375 -0.4859716796875017 -0.8110000000000001 -0.017791748046875 -0.4859716796875017 -0.811125 -0.0152587890625 -0.4859716796875017 -0.8112500000000001 -0.0152587890625 -0.4859716796875017 -0.8113750000000001 -0.012725830078125 -0.4859716796875017 -0.8115 -0.012725830078125 -0.4859716796875017 -0.8116250000000001 -0.01019287109375 -0.4859716796875017 -0.81175 -0.007659912109375 -0.4859716796875017 -0.811875 -0.007659912109375 -0.4859716796875017 -0.8120000000000001 -0.005096435546875 -0.4859716796875017 -0.812125 -0.005096435546875 -0.4859716796875017 -0.81225 -0.0025634765625 -0.4859716796875017 +0.768 -0.106719970703125 -0.2701904296875024 +0.768125 -0.106719970703125 -0.2701904296875024 +0.76825 -0.10760498046875 -0.2701904296875024 +0.768375 -0.10760498046875 -0.2701904296875024 +0.7685 -0.108428955078125 -0.2701904296875024 +0.768625 -0.109283447265625 -0.2701904296875024 +0.76875 -0.109283447265625 -0.2701904296875024 +0.768875 -0.110107421875 -0.2701904296875024 +0.769 -0.110107421875 -0.2701904296875024 +0.769125 -0.110931396484375 -0.2701904296875024 +0.76925 -0.111724853515625 -0.2701904296875024 +0.7693750000000001 -0.111724853515625 -0.2701904296875024 +0.7694999999999999 -0.112518310546875 -0.2701904296875024 +0.769625 -0.112518310546875 -0.2701904296875024 +0.7697500000000001 -0.11328125 -0.2701904296875024 +0.769875 -0.114044189453125 -0.2701904296875024 +0.77 -0.114044189453125 -0.2701904296875024 +0.7701250000000001 -0.11480712890625 -0.2701904296875024 +0.77025 -0.11480712890625 -0.2701904296875024 +0.770375 -0.11553955078125 -0.2701904296875024 +0.7705 -0.11627197265625 -0.2701904296875024 +0.770625 -0.11627197265625 -0.2701904296875024 +0.77075 -0.116973876953125 -0.2701904296875024 +0.770875 -0.116973876953125 -0.2701904296875024 +0.771 -0.11767578125 -0.2701904296875024 +0.7711250000000001 -0.118377685546875 -0.2701904296875024 +0.77125 -0.118377685546875 -0.2701904296875024 +0.771375 -0.119049072265625 -0.2701904296875024 +0.7715 -0.119049072265625 -0.2701904296875024 +0.771625 -0.119720458984375 -0.2701904296875024 +0.77175 -0.120361328125 -0.2701904296875024 +0.771875 -0.120361328125 -0.2701904296875024 +0.7720000000000001 -0.121002197265625 -0.2701904296875024 +0.772125 -0.121002197265625 -0.2701904296875024 +0.77225 -0.121612548828125 -0.2701904296875024 +0.7723750000000001 -0.122222900390625 -0.2701904296875024 +0.7725 -0.122222900390625 -0.2701904296875024 +0.772625 -0.122802734375 -0.2701904296875024 +0.7727500000000001 -0.122802734375 -0.2701904296875024 +0.772875 -0.1234130859375 -0.2701904296875024 +0.773 -0.12396240234375 -0.2701904296875024 +0.7731250000000001 -0.12396240234375 -0.2701904296875024 +0.77325 -0.12451171875 -0.2701904296875024 +0.7733750000000001 -0.12451171875 -0.2701904296875024 +0.7734999999999999 -0.12506103515625 -0.2701904296875024 +0.773625 -0.125579833984375 -0.2701904296875024 +0.7737500000000001 -0.125579833984375 -0.2701904296875024 +0.773875 -0.1260986328125 -0.2701904296875024 +0.774 -0.1260986328125 -0.2701904296875024 +0.7741250000000001 -0.126617431640625 -0.2701904296875024 +0.77425 -0.127105712890625 -0.2701904296875024 +0.774375 -0.127105712890625 -0.2701904296875024 +0.7744999999999999 -0.1275634765625 -0.2701904296875024 +0.774625 -0.1275634765625 -0.2701904296875024 +0.77475 -0.128021240234375 -0.2701904296875024 +0.7748749999999999 -0.12847900390625 -0.2701904296875024 +0.775 -0.12847900390625 -0.2701904296875024 +0.7751250000000001 -0.12890625 -0.2701904296875024 +0.77525 -0.12890625 -0.2701904296875024 +0.775375 -0.129302978515625 -0.2701904296875024 +0.7755 -0.12969970703125 -0.2701904296875024 +0.775625 -0.12969970703125 -0.2701904296875024 +0.77575 -0.130096435546875 -0.2701904296875024 +0.775875 -0.130096435546875 -0.2701904296875024 +0.776 -0.130462646484375 -0.2701904296875024 +0.776125 -0.130828857421875 -0.2701904296875024 +0.77625 -0.130828857421875 -0.2701904296875024 +0.776375 -0.131195068359375 -0.2701904296875024 +0.7765 -0.131195068359375 -0.2701904296875024 +0.776625 -0.131500244140625 -0.2701904296875024 +0.77675 -0.1318359375 -0.2701904296875024 +0.776875 -0.1318359375 -0.2701904296875024 +0.777 -0.132110595703125 -0.2701904296875024 +0.777125 -0.132110595703125 -0.2701904296875024 +0.77725 -0.132415771484375 -0.2701904296875024 +0.7773750000000001 -0.1326904296875 -0.2701904296875024 +0.7774999999999999 -0.1326904296875 -0.2701904296875024 +0.777625 -0.1329345703125 -0.2701904296875024 +0.7777500000000001 -0.1329345703125 -0.2701904296875024 +0.777875 -0.1331787109375 -0.2701904296875024 +0.778 -0.1334228515625 -0.2701904296875024 +0.7781250000000001 -0.1334228515625 -0.2701904296875024 +0.77825 -0.133636474609375 -0.2701904296875024 +0.778375 -0.133636474609375 -0.2701904296875024 +0.7785 -0.133819580078125 -0.2701904296875024 +0.778625 -0.134002685546875 -0.2701904296875024 +0.7787500000000001 -0.134002685546875 -0.2701904296875024 +0.778875 -0.134185791015625 -0.2701904296875024 +0.779 -0.134185791015625 -0.2701904296875024 +0.7791250000000001 -0.13433837890625 -0.2701904296875024 +0.77925 -0.134490966796875 -0.2701904296875024 +0.779375 -0.134490966796875 -0.2701904296875024 +0.7795 -0.134613037109375 -0.2701904296875024 +0.7796250000000001 -0.134613037109375 -0.2701904296875024 +0.77975 -0.13470458984375 -0.2701904296875024 +0.779875 -0.13482666015625 -0.2701904296875024 +0.7800000000000001 -0.13482666015625 -0.2701904296875024 +0.780125 -0.1348876953125 -0.2701904296875024 +0.78025 -0.1348876953125 -0.2701904296875024 +0.7803750000000001 -0.13494873046875 -0.2701904296875024 +0.7805 -0.135009765625 -0.2701904296875024 +0.780625 -0.135009765625 -0.2701904296875024 +0.7807500000000001 -0.135040283203125 -0.2701904296875024 +0.780875 -0.135040283203125 -0.2701904296875024 +0.781 -0.13507080078125 -0.2701904296875024 +0.7811250000000001 -0.13507080078125 -0.2701904296875024 +0.78125 -0.13507080078125 -0.2701904296875024 +0.7813750000000001 -0.13507080078125 -0.2701904296875024 +0.7815 -0.13507080078125 -0.2701904296875024 +0.781625 -0.135040283203125 -0.2701904296875024 +0.7817500000000001 -0.135009765625 -0.2701904296875024 +0.781875 -0.135009765625 -0.2701904296875024 +0.782 -0.13494873046875 -0.2701904296875024 +0.7821250000000001 -0.13494873046875 -0.2701904296875024 +0.78225 -0.1348876953125 -0.2701904296875024 +0.782375 -0.13482666015625 -0.2701904296875024 +0.7824999999999999 -0.13482666015625 -0.2701904296875024 +0.782625 -0.13470458984375 -0.2701904296875024 +0.7827500000000001 -0.13470458984375 -0.2701904296875024 +0.7828749999999999 -0.134613037109375 -0.2701904296875024 +0.783 -0.134490966796875 -0.2701904296875024 +0.7831250000000001 -0.134490966796875 -0.2701904296875024 +0.78325 -0.13433837890625 -0.2701904296875024 +0.783375 -0.13433837890625 -0.2701904296875024 +0.7835 -0.134185791015625 -0.2701904296875024 +0.783625 -0.134002685546875 -0.2701904296875024 +0.78375 -0.134002685546875 -0.2701904296875024 +0.783875 -0.133819580078125 -0.2701904296875024 +0.784 -0.133819580078125 -0.2701904296875024 +0.784125 -0.133636474609375 -0.2701904296875024 +0.78425 -0.1334228515625 -0.2701904296875024 +0.784375 -0.1334228515625 -0.2701904296875024 +0.7845 -0.1331787109375 -0.2701904296875024 +0.784625 -0.1331787109375 -0.2701904296875024 +0.78475 -0.1329345703125 -0.2701904296875024 +0.784875 -0.1326904296875 -0.2701904296875024 +0.7850000000000001 -0.1326904296875 -0.2701904296875024 +0.7851249999999999 -0.132415771484375 -0.2701904296875024 +0.78525 -0.132415771484375 -0.2701904296875024 +0.7853750000000001 -0.132110595703125 -0.2701904296875024 +0.7855 -0.1318359375 -0.2701904296875024 +0.785625 -0.1318359375 -0.2701904296875024 +0.7857500000000001 -0.131500244140625 -0.2701904296875024 +0.785875 -0.131500244140625 -0.2701904296875024 +0.786 -0.131195068359375 -0.2701904296875024 +0.786125 -0.130828857421875 -0.2701904296875024 +0.78625 -0.130828857421875 -0.2701904296875024 +0.786375 -0.130462646484375 -0.2701904296875024 +0.7865 -0.130462646484375 -0.2701904296875024 +0.786625 -0.130096435546875 -0.2701904296875024 +0.7867500000000001 -0.12969970703125 -0.2701904296875024 +0.786875 -0.12969970703125 -0.2701904296875024 +0.787 -0.129302978515625 -0.2701904296875024 +0.787125 -0.129302978515625 -0.2701904296875024 +0.78725 -0.12890625 -0.2701904296875024 +0.787375 -0.12847900390625 -0.2701904296875024 +0.7875 -0.12847900390625 -0.2701904296875024 +0.7876250000000001 -0.128021240234375 -0.2701904296875024 +0.78775 -0.128021240234375 -0.2701904296875024 +0.787875 -0.1275634765625 -0.2701904296875024 +0.7880000000000001 -0.127105712890625 -0.2701904296875024 +0.788125 -0.127105712890625 -0.2701904296875024 +0.78825 -0.126617431640625 -0.2701904296875024 +0.7883750000000001 -0.126617431640625 -0.2701904296875024 +0.7885 -0.1260986328125 -0.2701904296875024 +0.788625 -0.125579833984375 -0.2701904296875024 +0.7887500000000001 -0.125579833984375 -0.2701904296875024 +0.788875 -0.12506103515625 -0.2701904296875024 +0.7890000000000001 -0.12506103515625 -0.2701904296875024 +0.7891249999999999 -0.12451171875 -0.2701904296875024 +0.78925 -0.12396240234375 -0.2701904296875024 +0.7893750000000001 -0.12396240234375 -0.2701904296875024 +0.7895 -0.1234130859375 -0.2701904296875024 +0.789625 -0.1234130859375 -0.2701904296875024 +0.7897500000000001 -0.122802734375 -0.2701904296875024 +0.789875 -0.122222900390625 -0.2701904296875024 +0.79 -0.122222900390625 -0.2701904296875024 +0.7901249999999999 -0.121612548828125 -0.2701904296875024 +0.79025 -0.121612548828125 -0.2701904296875024 +0.790375 -0.121002197265625 -0.2701904296875024 +0.7904999999999999 -0.120361328125 -0.2701904296875024 +0.790625 -0.120361328125 -0.2701904296875024 +0.7907500000000001 -0.119720458984375 -0.2701904296875024 +0.790875 -0.119720458984375 -0.2701904296875024 +0.791 -0.119049072265625 -0.2701904296875024 +0.791125 -0.118377685546875 -0.2701904296875024 +0.79125 -0.118377685546875 -0.2701904296875024 +0.791375 -0.11767578125 -0.2701904296875024 +0.7915 -0.11767578125 -0.2701904296875024 +0.791625 -0.116973876953125 -0.2701904296875024 +0.79175 -0.11627197265625 -0.2701904296875024 +0.791875 -0.11627197265625 -0.2701904296875024 +0.792 -0.11553955078125 -0.2701904296875024 +0.792125 -0.11553955078125 -0.2701904296875024 +0.79225 -0.11480712890625 -0.2701904296875024 +0.792375 -0.114044189453125 -0.2701904296875024 +0.7925 -0.114044189453125 -0.2701904296875024 +0.792625 -0.11328125 -0.2701904296875024 +0.79275 -0.11328125 -0.2701904296875024 +0.792875 -0.112518310546875 -0.2701904296875024 +0.7930000000000001 -0.111724853515625 -0.2701904296875024 +0.7931249999999999 -0.111724853515625 -0.2701904296875024 +0.79325 -0.110931396484375 -0.2701904296875024 +0.7933750000000001 -0.110931396484375 -0.2701904296875024 +0.7935 -0.110107421875 -0.2701904296875024 +0.793625 -0.109283447265625 -0.2701904296875024 +0.7937500000000001 -0.109283447265625 -0.2701904296875024 +0.793875 -0.108428955078125 -0.2701904296875024 +0.794 -0.108428955078125 -0.2701904296875024 +0.794125 -0.10760498046875 -0.2701904296875024 +0.79425 -0.106719970703125 -0.2701904296875024 +0.7943750000000001 -0.106719970703125 -0.2701904296875024 +0.7945 -0.105865478515625 -0.2701904296875024 +0.794625 -0.105865478515625 -0.2701904296875024 +0.7947500000000001 -0.10498046875 -0.2701904296875024 +0.794875 -0.10406494140625 -0.2701904296875024 +0.795 -0.10406494140625 -0.2701904296875024 +0.795125 -0.103179931640625 -0.2701904296875024 +0.7952500000000001 -0.103179931640625 -0.2701904296875024 +0.795375 -0.102264404296875 -0.2701904296875024 +0.7955 -0.101318359375 -0.2701904296875024 +0.7956250000000001 -0.101318359375 -0.2701904296875024 +0.79575 -0.100372314453125 -0.2701904296875024 +0.795875 -0.100372314453125 -0.2701904296875024 +0.7960000000000001 -0.09942626953125 -0.2701904296875024 +0.796125 -0.098480224609375 -0.2701904296875024 +0.79625 -0.098480224609375 -0.2701904296875024 +0.7963750000000001 -0.097503662109375 -0.2701904296875024 +0.7965 -0.097503662109375 -0.2701904296875024 +0.796625 -0.09649658203125 -0.2701904296875024 +0.7967500000000001 -0.09552001953125 -0.2701904296875024 +0.796875 -0.09552001953125 -0.2701904296875024 +0.7970000000000001 -0.094512939453125 -0.2701904296875024 +0.797125 -0.094512939453125 -0.2701904296875024 +0.79725 -0.093475341796875 -0.2701904296875024 +0.7973750000000001 -0.09246826171875 -0.2701904296875024 +0.7975 -0.09246826171875 -0.2701904296875024 +0.797625 -0.0914306640625 -0.2701904296875024 +0.7977500000000001 -0.0914306640625 -0.2701904296875024 +0.797875 -0.09039306640625 -0.2701904296875024 +0.798 -0.089324951171875 -0.2701904296875024 +0.7981249999999999 -0.089324951171875 -0.2701904296875024 +0.79825 -0.0882568359375 -0.2701904296875024 +0.7983750000000001 -0.0882568359375 -0.2701904296875024 +0.7984999999999999 -0.087188720703125 -0.2701904296875024 +0.798625 -0.086090087890625 -0.2701904296875024 +0.7987500000000001 -0.086090087890625 -0.2701904296875024 +0.798875 -0.084991455078125 -0.2701904296875024 +0.799 -0.084991455078125 -0.2701904296875024 +0.799125 -0.083892822265625 -0.2701904296875024 +0.79925 -0.082794189453125 -0.2701904296875024 +0.799375 -0.082794189453125 -0.2701904296875024 +0.7995 -0.0816650390625 -0.2701904296875024 +0.799625 -0.0816650390625 -0.2701904296875024 +0.79975 -0.080535888671875 -0.2701904296875024 +0.799875 -0.079376220703125 -0.2701904296875024 +0.8 -0.142791748046875 -0.4859716796875017 +0.8001249999999999 -0.1407470703125 -0.4859716796875017 +0.80025 -0.1407470703125 -0.4859716796875017 +0.800375 -0.138641357421875 -0.4859716796875017 +0.8004999999999999 -0.13653564453125 -0.4859716796875017 +0.800625 -0.13653564453125 -0.4859716796875017 +0.80075 -0.134429931640625 -0.4859716796875017 +0.8008749999999999 -0.134429931640625 -0.4859716796875017 +0.801 -0.13232421875 -0.4859716796875017 +0.801125 -0.13018798828125 -0.4859716796875017 +0.8012499999999999 -0.13018798828125 -0.4859716796875017 +0.801375 -0.128021240234375 -0.4859716796875017 +0.8015000000000001 -0.128021240234375 -0.4859716796875017 +0.8016249999999999 -0.1258544921875 -0.4859716796875017 +0.80175 -0.1236572265625 -0.4859716796875017 +0.8018750000000001 -0.1236572265625 -0.4859716796875017 +0.802 -0.1214599609375 -0.4859716796875017 +0.802125 -0.1214599609375 -0.4859716796875017 +0.8022500000000001 -0.1192626953125 -0.4859716796875017 +0.802375 -0.117034912109375 -0.4859716796875017 +0.8025 -0.117034912109375 -0.4859716796875017 +0.8026250000000001 -0.11480712890625 -0.4859716796875017 +0.80275 -0.11480712890625 -0.4859716796875017 +0.802875 -0.112548828125 -0.4859716796875017 +0.8030000000000001 -0.11029052734375 -0.4859716796875017 +0.803125 -0.11029052734375 -0.4859716796875017 +0.8032500000000001 -0.108001708984375 -0.4859716796875017 +0.8033750000000001 -0.108001708984375 -0.4859716796875017 +0.8035 -0.105743408203125 -0.4859716796875017 +0.8036250000000001 -0.103424072265625 -0.4859716796875017 +0.80375 -0.103424072265625 -0.4859716796875017 +0.803875 -0.10113525390625 -0.4859716796875017 +0.8040000000000001 -0.10113525390625 -0.4859716796875017 +0.804125 -0.09881591796875 -0.4859716796875017 +0.80425 -0.096466064453125 -0.4859716796875017 +0.8043750000000001 -0.096466064453125 -0.4859716796875017 +0.8045 -0.094146728515625 -0.4859716796875017 +0.8046250000000001 -0.094146728515625 -0.4859716796875017 +0.8047499999999999 -0.091796875 -0.4859716796875017 +0.804875 -0.08941650390625 -0.4859716796875017 +0.8050000000000001 -0.08941650390625 -0.4859716796875017 +0.805125 -0.087066650390625 -0.4859716796875017 +0.80525 -0.087066650390625 -0.4859716796875017 +0.8053750000000001 -0.084686279296875 -0.4859716796875017 +0.8055 -0.082275390625 -0.4859716796875017 +0.805625 -0.082275390625 -0.4859716796875017 +0.8057499999999999 -0.07989501953125 -0.4859716796875017 +0.805875 -0.07989501953125 -0.4859716796875017 +0.806 -0.077484130859375 -0.4859716796875017 +0.8061249999999999 -0.0750732421875 -0.4859716796875017 +0.80625 -0.0750732421875 -0.4859716796875017 +0.8063750000000001 -0.0726318359375 -0.4859716796875017 +0.8065 -0.0726318359375 -0.4859716796875017 +0.806625 -0.070220947265625 -0.4859716796875017 +0.8067499999999999 -0.067779541015625 -0.4859716796875017 +0.806875 -0.067779541015625 -0.4859716796875017 +0.807 -0.0653076171875 -0.4859716796875017 +0.8071249999999999 -0.0653076171875 -0.4859716796875017 +0.80725 -0.0628662109375 -0.4859716796875017 +0.807375 -0.060394287109375 -0.4859716796875017 +0.8074999999999999 -0.060394287109375 -0.4859716796875017 +0.807625 -0.057952880859375 -0.4859716796875017 +0.8077500000000001 -0.057952880859375 -0.4859716796875017 +0.8078749999999999 -0.055450439453125 -0.4859716796875017 +0.808 -0.052978515625 -0.4859716796875017 +0.8081250000000001 -0.052978515625 -0.4859716796875017 +0.80825 -0.050506591796875 -0.4859716796875017 +0.808375 -0.050506591796875 -0.4859716796875017 +0.8085000000000001 -0.048004150390625 -0.4859716796875017 +0.808625 -0.045501708984375 -0.4859716796875017 +0.80875 -0.045501708984375 -0.4859716796875017 +0.8088750000000001 -0.042999267578125 -0.4859716796875017 +0.809 -0.042999267578125 -0.4859716796875017 +0.809125 -0.040496826171875 -0.4859716796875017 +0.8092500000000001 -0.037994384765625 -0.4859716796875017 +0.809375 -0.037994384765625 -0.4859716796875017 +0.8095000000000001 -0.03546142578125 -0.4859716796875017 +0.8096250000000001 -0.03546142578125 -0.4859716796875017 +0.80975 -0.032958984375 -0.4859716796875017 +0.8098750000000001 -0.030426025390625 -0.4859716796875017 +0.8100000000000001 -0.030426025390625 -0.4859716796875017 +0.810125 -0.027923583984375 -0.4859716796875017 +0.8102500000000001 -0.027923583984375 -0.4859716796875017 +0.8103750000000002 -0.025390625 -0.4859716796875017 +0.8105 -0.022857666015625 -0.4859716796875017 +0.8106250000000001 -0.022857666015625 -0.4859716796875017 +0.81075 -0.02032470703125 -0.4859716796875017 +0.8108750000000001 -0.02032470703125 -0.4859716796875017 +0.8110000000000001 -0.01776123046875 -0.4859716796875017 +0.811125 -0.015228271484375 -0.4859716796875017 +0.8112500000000001 -0.015228271484375 -0.4859716796875017 +0.8113750000000001 -0.0126953125 -0.4859716796875017 +0.8115 -0.0126953125 -0.4859716796875017 +0.8116250000000001 -0.010162353515625 -0.4859716796875017 +0.81175 -0.00762939453125 -0.4859716796875017 +0.811875 -0.00762939453125 -0.4859716796875017 +0.8120000000000001 -0.00506591796875 -0.4859716796875017 +0.812125 -0.00506591796875 -0.4859716796875017 +0.81225 -0.002532958984375 -0.4859716796875017 0.8123750000000001 0.0 -0.4859716796875017 0.8125 0.0 -0.4859716796875017 0.8126250000000001 0.002532958984375 -0.4859716796875017 @@ -6999,504 +6999,504 @@ 0.87475 0.00299072265625 -0.572260742187499 0.8748750000000001 0.0 -0.572260742187499 0.875 0.0 -0.572260742187499 -0.8751250000000001 -0.003021240234375 -0.572260742187499 -0.87525 -0.003021240234375 -0.572260742187499 -0.875375 -0.006011962890625 -0.572260742187499 -0.8755000000000001 -0.009002685546875 -0.572260742187499 -0.875625 -0.009002685546875 -0.572260742187499 -0.87575 -0.011993408203125 -0.572260742187499 -0.8758750000000001 -0.011993408203125 -0.572260742187499 -0.876 -0.014984130859375 -0.572260742187499 -0.876125 -0.017974853515625 -0.572260742187499 -0.8762499999999999 -0.017974853515625 -0.572260742187499 -0.876375 -0.020965576171875 -0.572260742187499 -0.8765000000000001 -0.020965576171875 -0.572260742187499 -0.8766249999999999 -0.023956298828125 -0.572260742187499 -0.87675 -0.026947021484375 -0.572260742187499 -0.8768750000000001 -0.026947021484375 -0.572260742187499 -0.877 -0.029937744140625 -0.572260742187499 -0.877125 -0.029937744140625 -0.572260742187499 -0.8772499999999999 -0.03289794921875 -0.572260742187499 -0.877375 -0.035858154296875 -0.572260742187499 -0.8775 -0.035858154296875 -0.572260742187499 -0.8776249999999999 -0.038848876953125 -0.572260742187499 -0.87775 -0.038848876953125 -0.572260742187499 -0.877875 -0.04180908203125 -0.572260742187499 -0.8779999999999999 -0.044769287109375 -0.572260742187499 -0.878125 -0.044769287109375 -0.572260742187499 -0.8782499999999999 -0.0477294921875 -0.572260742187499 -0.878375 -0.0477294921875 -0.572260742187499 -0.8785 -0.050689697265625 -0.572260742187499 -0.8786249999999999 -0.053619384765625 -0.572260742187499 -0.87875 -0.053619384765625 -0.572260742187499 -0.878875 -0.056549072265625 -0.572260742187499 -0.8789999999999999 -0.056549072265625 -0.572260742187499 -0.879125 -0.05950927734375 -0.572260742187499 -0.87925 -0.062408447265625 -0.572260742187499 -0.8793749999999999 -0.062408447265625 -0.572260742187499 -0.8795 -0.065338134765625 -0.572260742187499 -0.8796250000000001 -0.065338134765625 -0.572260742187499 -0.8797499999999999 -0.068267822265625 -0.572260742187499 -0.879875 -0.0711669921875 -0.572260742187499 -0.8800000000000001 -0.0711669921875 -0.572260742187499 -0.880125 -0.074066162109375 -0.572260742187499 -0.88025 -0.074066162109375 -0.572260742187499 -0.8803750000000001 -0.07696533203125 -0.572260742187499 -0.8805 -0.079833984375 -0.572260742187499 -0.880625 -0.079833984375 -0.572260742187499 -0.8807500000000001 -0.08270263671875 -0.572260742187499 -0.880875 -0.08270263671875 -0.572260742187499 -0.881 -0.0855712890625 -0.572260742187499 -0.8811250000000001 -0.08843994140625 -0.572260742187499 -0.88125 -0.08843994140625 -0.572260742187499 -0.8813750000000001 -0.091278076171875 -0.572260742187499 -0.8815000000000001 -0.091278076171875 -0.572260742187499 -0.881625 -0.0941162109375 -0.572260742187499 -0.8817500000000001 -0.096923828125 -0.572260742187499 -0.881875 -0.096923828125 -0.572260742187499 -0.882 -0.0997314453125 -0.572260742187499 -0.8821250000000001 -0.0997314453125 -0.572260742187499 -0.88225 -0.1025390625 -0.572260742187499 -0.882375 -0.1053466796875 -0.572260742187499 -0.8825000000000001 -0.1053466796875 -0.572260742187499 -0.882625 -0.108123779296875 -0.572260742187499 -0.8827500000000001 -0.108123779296875 -0.572260742187499 -0.8828749999999999 -0.11090087890625 -0.572260742187499 -0.883 -0.1136474609375 -0.572260742187499 -0.8831250000000001 -0.1136474609375 -0.572260742187499 -0.88325 -0.11639404296875 -0.572260742187499 -0.883375 -0.11639404296875 -0.572260742187499 -0.8835000000000001 -0.119110107421875 -0.572260742187499 -0.883625 -0.121826171875 -0.572260742187499 -0.88375 -0.121826171875 -0.572260742187499 -0.8838749999999999 -0.124542236328125 -0.572260742187499 -0.884 -0.124542236328125 -0.572260742187499 -0.884125 -0.127227783203125 -0.572260742187499 -0.8842499999999999 -0.129913330078125 -0.572260742187499 -0.884375 -0.129913330078125 -0.572260742187499 -0.8845000000000001 -0.132568359375 -0.572260742187499 -0.884625 -0.132568359375 -0.572260742187499 -0.88475 -0.135223388671875 -0.572260742187499 -0.8848749999999999 -0.137847900390625 -0.572260742187499 -0.885 -0.137847900390625 -0.572260742187499 -0.885125 -0.140472412109375 -0.572260742187499 -0.8852499999999999 -0.140472412109375 -0.572260742187499 -0.885375 -0.14306640625 -0.572260742187499 -0.8855 -0.145660400390625 -0.572260742187499 -0.8856249999999999 -0.145660400390625 -0.572260742187499 -0.88575 -0.148223876953125 -0.572260742187499 -0.8858750000000001 -0.148223876953125 -0.572260742187499 -0.8859999999999999 -0.150787353515625 -0.572260742187499 -0.886125 -0.1533203125 -0.572260742187499 -0.8862500000000001 -0.1533203125 -0.572260742187499 -0.886375 -0.155853271484375 -0.572260742187499 -0.8865 -0.155853271484375 -0.572260742187499 -0.8866250000000001 -0.158355712890625 -0.572260742187499 -0.88675 -0.16082763671875 -0.572260742187499 -0.886875 -0.16082763671875 -0.572260742187499 -0.8870000000000001 -0.163299560546875 -0.572260742187499 -0.887125 -0.163299560546875 -0.572260742187499 -0.88725 -0.165771484375 -0.572260742187499 -0.8873750000000001 -0.168182373046875 -0.572260742187499 -0.8875 -0.168182373046875 -0.572260742187499 -0.8876250000000001 -0.17059326171875 -0.572260742187499 -0.8877500000000001 -0.17059326171875 -0.572260742187499 -0.887875 -0.173004150390625 -0.572260742187499 -0.8880000000000001 -0.175384521484375 -0.572260742187499 -0.8881250000000001 -0.175384521484375 -0.572260742187499 -0.88825 -0.177734375 -0.572260742187499 -0.8883750000000001 -0.177734375 -0.572260742187499 -0.8885000000000002 -0.180084228515625 -0.572260742187499 -0.888625 -0.182403564453125 -0.572260742187499 -0.8887500000000001 -0.182403564453125 -0.572260742187499 -0.888875 -0.1846923828125 -0.572260742187499 -0.8890000000000001 -0.1846923828125 -0.572260742187499 -0.8891250000000001 -0.186981201171875 -0.572260742187499 -0.88925 -0.189239501953125 -0.572260742187499 -0.8893750000000001 -0.189239501953125 -0.572260742187499 -0.8895000000000001 -0.19146728515625 -0.572260742187499 -0.889625 -0.19146728515625 -0.572260742187499 -0.8897500000000001 -0.193695068359375 -0.572260742187499 -0.889875 -0.19586181640625 -0.572260742187499 -0.89 -0.19586181640625 -0.572260742187499 -0.8901250000000001 -0.19805908203125 -0.572260742187499 -0.89025 -0.19805908203125 -0.572260742187499 -0.890375 -0.2001953125 -0.572260742187499 -0.8905000000000001 -0.20233154296875 -0.572260742187499 -0.890625 -0.20233154296875 -0.572260742187499 -0.8907500000000001 -0.204437255859375 -0.572260742187499 -0.890875 -0.204437255859375 -0.572260742187499 -0.891 -0.206512451171875 -0.572260742187499 -0.8911250000000001 -0.208587646484375 -0.572260742187499 -0.89125 -0.208587646484375 -0.572260742187499 -0.891375 -0.21063232421875 -0.572260742187499 -0.8915000000000001 -0.21063232421875 -0.572260742187499 -0.891625 -0.212646484375 -0.572260742187499 -0.89175 -0.214630126953125 -0.572260742187499 -0.8918749999999999 -0.214630126953125 -0.572260742187499 -0.892 -0.21661376953125 -0.572260742187499 -0.8921250000000001 -0.21661376953125 -0.572260742187499 -0.8922499999999999 -0.21856689453125 -0.572260742187499 -0.892375 -0.220458984375 -0.572260742187499 -0.8925000000000001 -0.220458984375 -0.572260742187499 -0.892625 -0.222381591796875 -0.572260742187499 -0.89275 -0.222381591796875 -0.572260742187499 -0.8928749999999999 -0.2242431640625 -0.572260742187499 -0.893 -0.226104736328125 -0.572260742187499 -0.893125 -0.226104736328125 -0.572260742187499 -0.8932499999999999 -0.2279052734375 -0.572260742187499 -0.893375 -0.2279052734375 -0.572260742187499 -0.8935 -0.229705810546875 -0.572260742187499 -0.8936249999999999 -0.23150634765625 -0.572260742187499 -0.89375 -0.23150634765625 -0.572260742187499 -0.8938749999999999 -0.233245849609375 -0.572260742187499 -0.894 -0.233245849609375 -0.572260742187499 -0.894125 -0.234954833984375 -0.572260742187499 -0.8942499999999999 -0.236663818359375 -0.572260742187499 -0.894375 -0.236663818359375 -0.572260742187499 -0.8945 -0.23834228515625 -0.572260742187499 -0.8946249999999999 -0.23834228515625 -0.572260742187499 -0.89475 -0.239959716796875 -0.572260742187499 -0.894875 -0.241607666015625 -0.572260742187499 -0.8949999999999999 -0.241607666015625 -0.572260742187499 -0.895125 -0.243194580078125 -0.572260742187499 -0.8952500000000001 -0.243194580078125 -0.572260742187499 -0.8953749999999999 -0.2447509765625 -0.572260742187499 -0.8955 -0.24627685546875 -0.572260742187499 -0.8956250000000001 -0.24627685546875 -0.572260742187499 -0.89575 -0.247802734375 -0.572260742187499 -0.895875 -0.247802734375 -0.572260742187499 -0.8960000000000001 -0.1868896484375 -0.4289990234374976 -0.896125 -0.187957763671875 -0.4289990234374976 -0.89625 -0.187957763671875 -0.4289990234374976 -0.8963750000000001 -0.18902587890625 -0.4289990234374976 -0.8965 -0.18902587890625 -0.4289990234374976 -0.896625 -0.190093994140625 -0.4289990234374976 -0.8967500000000001 -0.191131591796875 -0.4289990234374976 -0.896875 -0.191131591796875 -0.4289990234374976 -0.8970000000000001 -0.192138671875 -0.4289990234374976 -0.8971250000000001 -0.192138671875 -0.4289990234374976 -0.89725 -0.193115234375 -0.4289990234374976 -0.8973750000000001 -0.194091796875 -0.4289990234374976 -0.8975 -0.194091796875 -0.4289990234374976 -0.897625 -0.195037841796875 -0.4289990234374976 -0.8977500000000001 -0.195037841796875 -0.4289990234374976 -0.897875 -0.195953369140625 -0.4289990234374976 -0.898 -0.196868896484375 -0.4289990234374976 -0.8981250000000001 -0.196868896484375 -0.4289990234374976 -0.89825 -0.197723388671875 -0.4289990234374976 -0.8983750000000001 -0.197723388671875 -0.4289990234374976 -0.8984999999999999 -0.1986083984375 -0.4289990234374976 -0.898625 -0.199432373046875 -0.4289990234374976 -0.8987500000000001 -0.199432373046875 -0.4289990234374976 -0.898875 -0.20025634765625 -0.4289990234374976 -0.899 -0.20025634765625 -0.4289990234374976 -0.8991250000000001 -0.2010498046875 -0.4289990234374976 -0.89925 -0.201812744140625 -0.4289990234374976 -0.899375 -0.201812744140625 -0.4289990234374976 -0.8994999999999999 -0.20257568359375 -0.4289990234374976 -0.899625 -0.20257568359375 -0.4289990234374976 -0.89975 -0.20330810546875 -0.4289990234374976 -0.8998749999999999 -0.204010009765625 -0.4289990234374976 -0.9 -0.204010009765625 -0.4289990234374976 -0.9001250000000001 -0.204681396484375 -0.4289990234374976 -0.90025 -0.204681396484375 -0.4289990234374976 -0.900375 -0.205352783203125 -0.4289990234374976 -0.9004999999999999 -0.20599365234375 -0.4289990234374976 -0.900625 -0.20599365234375 -0.4289990234374976 -0.90075 -0.20660400390625 -0.4289990234374976 -0.9008749999999999 -0.20660400390625 -0.4289990234374976 -0.901 -0.207183837890625 -0.4289990234374976 -0.901125 -0.207763671875 -0.4289990234374976 -0.9012499999999999 -0.207763671875 -0.4289990234374976 -0.901375 -0.20831298828125 -0.4289990234374976 -0.9015000000000001 -0.20831298828125 -0.4289990234374976 -0.9016249999999999 -0.208831787109375 -0.4289990234374976 -0.90175 -0.209320068359375 -0.4289990234374976 -0.9018750000000001 -0.209320068359375 -0.4289990234374976 -0.902 -0.209808349609375 -0.4289990234374976 -0.902125 -0.209808349609375 -0.4289990234374976 -0.9022500000000001 -0.21026611328125 -0.4289990234374976 -0.902375 -0.210693359375 -0.4289990234374976 -0.9025 -0.210693359375 -0.4289990234374976 -0.9026250000000001 -0.21112060546875 -0.4289990234374976 -0.90275 -0.21112060546875 -0.4289990234374976 -0.902875 -0.21148681640625 -0.4289990234374976 -0.9030000000000001 -0.21185302734375 -0.4289990234374976 -0.903125 -0.21185302734375 -0.4289990234374976 -0.9032500000000001 -0.212188720703125 -0.4289990234374976 -0.9033750000000001 -0.212188720703125 -0.4289990234374976 -0.9035 -0.2125244140625 -0.4289990234374976 -0.9036250000000001 -0.212799072265625 -0.4289990234374976 -0.9037500000000001 -0.212799072265625 -0.4289990234374976 -0.903875 -0.21307373046875 -0.4289990234374976 -0.9040000000000001 -0.21307373046875 -0.4289990234374976 -0.9041250000000002 -0.21331787109375 -0.4289990234374976 -0.90425 -0.213531494140625 -0.4289990234374976 -0.9043750000000001 -0.213531494140625 -0.4289990234374976 -0.9045 -0.2137451171875 -0.4289990234374976 -0.9046250000000001 -0.2137451171875 -0.4289990234374976 -0.9047500000000001 -0.21392822265625 -0.4289990234374976 -0.904875 -0.214080810546875 -0.4289990234374976 -0.9050000000000001 -0.214080810546875 -0.4289990234374976 -0.9051250000000001 -0.214202880859375 -0.4289990234374976 -0.90525 -0.214202880859375 -0.4289990234374976 -0.9053750000000001 -0.214324951171875 -0.4289990234374976 -0.9055 -0.214385986328125 -0.4289990234374976 -0.905625 -0.214385986328125 -0.4289990234374976 -0.9057500000000001 -0.214447021484375 -0.4289990234374976 -0.905875 -0.214447021484375 -0.4289990234374976 -0.906 -0.2144775390625 -0.4289990234374976 -0.9061250000000001 -0.214508056640625 -0.4289990234374976 -0.90625 -0.214508056640625 -0.4289990234374976 -0.9063750000000001 -0.2144775390625 -0.4289990234374976 -0.9065 -0.2144775390625 -0.4289990234374976 -0.906625 -0.214447021484375 -0.4289990234374976 -0.9067500000000001 -0.214385986328125 -0.4289990234374976 -0.906875 -0.214385986328125 -0.4289990234374976 -0.907 -0.214324951171875 -0.4289990234374976 -0.9071250000000001 -0.214324951171875 -0.4289990234374976 -0.90725 -0.214202880859375 -0.4289990234374976 -0.907375 -0.214080810546875 -0.4289990234374976 -0.9074999999999999 -0.214080810546875 -0.4289990234374976 -0.907625 -0.21392822265625 -0.4289990234374976 -0.9077500000000001 -0.21392822265625 -0.4289990234374976 -0.9078749999999999 -0.2137451171875 -0.4289990234374976 -0.908 -0.213531494140625 -0.4289990234374976 -0.9081250000000001 -0.213531494140625 -0.4289990234374976 -0.90825 -0.21331787109375 -0.4289990234374976 -0.908375 -0.21331787109375 -0.4289990234374976 -0.9084999999999999 -0.21307373046875 -0.4289990234374976 -0.908625 -0.212799072265625 -0.4289990234374976 -0.90875 -0.212799072265625 -0.4289990234374976 -0.9088749999999999 -0.2125244140625 -0.4289990234374976 -0.909 -0.2125244140625 -0.4289990234374976 -0.909125 -0.212188720703125 -0.4289990234374976 -0.9092499999999999 -0.21185302734375 -0.4289990234374976 -0.909375 -0.21185302734375 -0.4289990234374976 -0.9094999999999999 -0.21148681640625 -0.4289990234374976 -0.909625 -0.21148681640625 -0.4289990234374976 -0.90975 -0.21112060546875 -0.4289990234374976 -0.9098749999999999 -0.210693359375 -0.4289990234374976 -0.91 -0.210693359375 -0.4289990234374976 -0.910125 -0.21026611328125 -0.4289990234374976 -0.9102499999999999 -0.21026611328125 -0.4289990234374976 -0.910375 -0.209808349609375 -0.4289990234374976 -0.9105 -0.209320068359375 -0.4289990234374976 -0.9106249999999999 -0.209320068359375 -0.4289990234374976 -0.91075 -0.208831787109375 -0.4289990234374976 -0.9108750000000001 -0.208831787109375 -0.4289990234374976 -0.9109999999999999 -0.20831298828125 -0.4289990234374976 -0.911125 -0.207763671875 -0.4289990234374976 -0.9112500000000001 -0.207763671875 -0.4289990234374976 -0.911375 -0.207183837890625 -0.4289990234374976 -0.9115 -0.207183837890625 -0.4289990234374976 -0.9116250000000001 -0.20660400390625 -0.4289990234374976 -0.91175 -0.20599365234375 -0.4289990234374976 -0.911875 -0.20599365234375 -0.4289990234374976 -0.9120000000000001 -0.205352783203125 -0.4289990234374976 -0.912125 -0.205352783203125 -0.4289990234374976 -0.91225 -0.204681396484375 -0.4289990234374976 -0.9123750000000001 -0.204010009765625 -0.4289990234374976 -0.9125 -0.204010009765625 -0.4289990234374976 -0.9126250000000001 -0.20330810546875 -0.4289990234374976 -0.9127500000000001 -0.20330810546875 -0.4289990234374976 -0.912875 -0.20257568359375 -0.4289990234374976 -0.9130000000000001 -0.201812744140625 -0.4289990234374976 -0.913125 -0.201812744140625 -0.4289990234374976 -0.91325 -0.2010498046875 -0.4289990234374976 -0.9133750000000001 -0.2010498046875 -0.4289990234374976 -0.9135 -0.20025634765625 -0.4289990234374976 -0.913625 -0.199432373046875 -0.4289990234374976 -0.9137500000000001 -0.199432373046875 -0.4289990234374976 -0.913875 -0.1986083984375 -0.4289990234374976 -0.9140000000000001 -0.1986083984375 -0.4289990234374976 -0.9141249999999999 -0.197723388671875 -0.4289990234374976 -0.91425 -0.196868896484375 -0.4289990234374976 -0.9143750000000001 -0.196868896484375 -0.4289990234374976 -0.9145 -0.195953369140625 -0.4289990234374976 -0.914625 -0.195953369140625 -0.4289990234374976 -0.9147500000000001 -0.195037841796875 -0.4289990234374976 -0.914875 -0.194091796875 -0.4289990234374976 -0.915 -0.194091796875 -0.4289990234374976 -0.9151249999999999 -0.193115234375 -0.4289990234374976 -0.91525 -0.193115234375 -0.4289990234374976 -0.915375 -0.192138671875 -0.4289990234374976 -0.9154999999999999 -0.191131591796875 -0.4289990234374976 -0.915625 -0.191131591796875 -0.4289990234374976 -0.9157500000000001 -0.190093994140625 -0.4289990234374976 -0.915875 -0.190093994140625 -0.4289990234374976 -0.916 -0.18902587890625 -0.4289990234374976 -0.9161249999999999 -0.187957763671875 -0.4289990234374976 -0.91625 -0.187957763671875 -0.4289990234374976 -0.916375 -0.1868896484375 -0.4289990234374976 -0.9164999999999999 -0.1868896484375 -0.4289990234374976 -0.916625 -0.185760498046875 -0.4289990234374976 -0.91675 -0.18463134765625 -0.4289990234374976 -0.9168749999999999 -0.18463134765625 -0.4289990234374976 -0.917 -0.1834716796875 -0.4289990234374976 -0.9171250000000001 -0.1834716796875 -0.4289990234374976 -0.9172499999999999 -0.18231201171875 -0.4289990234374976 -0.917375 -0.181121826171875 -0.4289990234374976 -0.9175000000000001 -0.181121826171875 -0.4289990234374976 -0.917625 -0.179901123046875 -0.4289990234374976 -0.91775 -0.179901123046875 -0.4289990234374976 -0.9178750000000001 -0.17864990234375 -0.4289990234374976 -0.918 -0.177398681640625 -0.4289990234374976 -0.918125 -0.177398681640625 -0.4289990234374976 -0.9182500000000001 -0.1761474609375 -0.4289990234374976 -0.918375 -0.1761474609375 -0.4289990234374976 -0.9185 -0.174835205078125 -0.4289990234374976 -0.9186250000000001 -0.17352294921875 -0.4289990234374976 -0.91875 -0.17352294921875 -0.4289990234374976 -0.9188750000000001 -0.172210693359375 -0.4289990234374976 -0.9190000000000001 -0.172210693359375 -0.4289990234374976 -0.919125 -0.170867919921875 -0.4289990234374976 -0.9192500000000001 -0.16949462890625 -0.4289990234374976 -0.9193750000000001 -0.16949462890625 -0.4289990234374976 -0.9195 -0.1680908203125 -0.4289990234374976 -0.9196250000000001 -0.1680908203125 -0.4289990234374976 -0.9197500000000002 -0.16668701171875 -0.4289990234374976 -0.919875 -0.165283203125 -0.4289990234374976 -0.9200000000000001 -0.165283203125 -0.4289990234374976 -0.920125 -0.163848876953125 -0.4289990234374976 -0.9202500000000001 -0.163848876953125 -0.4289990234374976 -0.9203750000000001 -0.162384033203125 -0.4289990234374976 -0.9205 -0.160888671875 -0.4289990234374976 -0.9206250000000001 -0.160888671875 -0.4289990234374976 -0.9207500000000001 -0.159393310546875 -0.4289990234374976 -0.920875 -0.159393310546875 -0.4289990234374976 -0.9210000000000001 -0.15789794921875 -0.4289990234374976 -0.921125 -0.1563720703125 -0.4289990234374976 -0.92125 -0.1563720703125 -0.4289990234374976 -0.9213750000000001 -0.154815673828125 -0.4289990234374976 -0.9215 -0.154815673828125 -0.4289990234374976 -0.921625 -0.15325927734375 -0.4289990234374976 -0.9217500000000001 -0.15167236328125 -0.4289990234374976 -0.921875 -0.15167236328125 -0.4289990234374976 -0.9220000000000001 -0.15008544921875 -0.4289990234374976 -0.922125 -0.15008544921875 -0.4289990234374976 -0.92225 -0.148468017578125 -0.4289990234374976 -0.9223750000000001 -0.1468505859375 -0.4289990234374976 -0.9225 -0.1468505859375 -0.4289990234374976 -0.922625 -0.14520263671875 -0.4289990234374976 -0.9227500000000001 -0.14520263671875 -0.4289990234374976 -0.922875 -0.143524169921875 -0.4289990234374976 -0.923 -0.141845703125 -0.4289990234374976 -0.9231249999999999 -0.141845703125 -0.4289990234374976 -0.92325 -0.140167236328125 -0.4289990234374976 -0.9233750000000001 -0.140167236328125 -0.4289990234374976 -0.9234999999999999 -0.138458251953125 -0.4289990234374976 -0.923625 -0.13671875 -0.4289990234374976 -0.9237500000000001 -0.13671875 -0.4289990234374976 -0.923875 -0.134979248046875 -0.4289990234374976 -0.924 -0.134979248046875 -0.4289990234374976 -0.9241249999999999 -0.13323974609375 -0.4289990234374976 -0.92425 -0.1314697265625 -0.4289990234374976 -0.924375 -0.1314697265625 -0.4289990234374976 -0.9244999999999999 -0.12969970703125 -0.4289990234374976 -0.924625 -0.12969970703125 -0.4289990234374976 -0.92475 -0.127899169921875 -0.4289990234374976 -0.9248749999999999 -0.126068115234375 -0.4289990234374976 -0.925 -0.126068115234375 -0.4289990234374976 -0.9251249999999999 -0.124267578125 -0.4289990234374976 -0.92525 -0.124267578125 -0.4289990234374976 -0.925375 -0.1224365234375 -0.4289990234374976 -0.9254999999999999 -0.120574951171875 -0.4289990234374976 -0.925625 -0.120574951171875 -0.4289990234374976 -0.92575 -0.11871337890625 -0.4289990234374976 -0.9258749999999999 -0.11871337890625 -0.4289990234374976 -0.926 -0.1168212890625 -0.4289990234374976 -0.926125 -0.11492919921875 -0.4289990234374976 -0.9262499999999999 -0.11492919921875 -0.4289990234374976 -0.926375 -0.113037109375 -0.4289990234374976 -0.9265000000000001 -0.113037109375 -0.4289990234374976 -0.9266249999999999 -0.111114501953125 -0.4289990234374976 -0.92675 -0.10919189453125 -0.4289990234374976 -0.9268750000000001 -0.10919189453125 -0.4289990234374976 -0.927 -0.107269287109375 -0.4289990234374976 -0.927125 -0.107269287109375 -0.4289990234374976 -0.9272500000000001 -0.105316162109375 -0.4289990234374976 -0.927375 -0.10333251953125 -0.4289990234374976 -0.9275 -0.10333251953125 -0.4289990234374976 -0.9276250000000001 -0.10137939453125 -0.4289990234374976 -0.92775 -0.10137939453125 -0.4289990234374976 -0.927875 -0.099395751953125 -0.4289990234374976 -0.9280000000000001 -0.042083740234375 -0.1853759765624967 -0.928125 -0.042083740234375 -0.1853759765624967 -0.9282500000000001 -0.041229248046875 -0.1853759765624967 -0.9283750000000001 -0.041229248046875 -0.1853759765624967 -0.9285 -0.04034423828125 -0.1853759765624967 -0.9286250000000001 -0.03948974609375 -0.1853759765624967 -0.92875 -0.03948974609375 -0.1853759765624967 -0.928875 -0.038604736328125 -0.1853759765624967 -0.9290000000000001 -0.038604736328125 -0.1853759765624967 -0.929125 -0.0377197265625 -0.1853759765624967 -0.92925 -0.036834716796875 -0.1853759765624967 -0.9293750000000001 -0.036834716796875 -0.1853759765624967 -0.9295 -0.035919189453125 -0.1853759765624967 -0.9296250000000001 -0.035919189453125 -0.1853759765624967 -0.9297499999999999 -0.0350341796875 -0.1853759765624967 -0.929875 -0.03411865234375 -0.1853759765624967 -0.9300000000000001 -0.03411865234375 -0.1853759765624967 -0.930125 -0.033233642578125 -0.1853759765624967 -0.93025 -0.033233642578125 -0.1853759765624967 -0.9303750000000001 -0.032318115234375 -0.1853759765624967 -0.9305 -0.031402587890625 -0.1853759765624967 -0.930625 -0.031402587890625 -0.1853759765624967 -0.9307499999999999 -0.030487060546875 -0.1853759765624967 -0.930875 -0.030487060546875 -0.1853759765624967 -0.931 -0.029571533203125 -0.1853759765624967 -0.9311249999999999 -0.028656005859375 -0.1853759765624967 -0.93125 -0.028656005859375 -0.1853759765624967 -0.9313750000000001 -0.027740478515625 -0.1853759765624967 -0.9315 -0.027740478515625 -0.1853759765624967 -0.931625 -0.02679443359375 -0.1853759765624967 -0.9317499999999999 -0.02587890625 -0.1853759765624967 -0.931875 -0.02587890625 -0.1853759765624967 -0.932 -0.024932861328125 -0.1853759765624967 -0.9321249999999999 -0.024932861328125 -0.1853759765624967 -0.93225 -0.02398681640625 -0.1853759765624967 -0.932375 -0.0230712890625 -0.1853759765624967 -0.9324999999999999 -0.0230712890625 -0.1853759765624967 -0.932625 -0.022125244140625 -0.1853759765624967 -0.9327500000000001 -0.022125244140625 -0.1853759765624967 -0.9328749999999999 -0.02117919921875 -0.1853759765624967 -0.933 -0.020233154296875 -0.1853759765624967 -0.9331250000000001 -0.020233154296875 -0.1853759765624967 -0.93325 -0.019287109375 -0.1853759765624967 -0.933375 -0.019287109375 -0.1853759765624967 -0.9335000000000001 -0.018341064453125 -0.1853759765624967 -0.933625 -0.017364501953125 -0.1853759765624967 -0.93375 -0.017364501953125 -0.1853759765624967 -0.9338750000000001 -0.01641845703125 -0.1853759765624967 -0.934 -0.01641845703125 -0.1853759765624967 -0.934125 -0.015472412109375 -0.1853759765624967 -0.9342500000000001 -0.014495849609375 -0.1853759765624967 -0.934375 -0.014495849609375 -0.1853759765624967 -0.9345000000000001 -0.0135498046875 -0.1853759765624967 -0.9346250000000001 -0.0135498046875 -0.1853759765624967 -0.93475 -0.012603759765625 -0.1853759765624967 -0.9348750000000001 -0.011627197265625 -0.1853759765624967 -0.9350000000000001 -0.011627197265625 -0.1853759765624967 -0.935125 -0.01068115234375 -0.1853759765624967 -0.9352500000000001 -0.01068115234375 -0.1853759765624967 -0.9353750000000002 -0.00970458984375 -0.1853759765624967 -0.9355 -0.00872802734375 -0.1853759765624967 -0.9356250000000001 -0.00872802734375 -0.1853759765624967 -0.93575 -0.007781982421875 -0.1853759765624967 -0.9358750000000001 -0.007781982421875 -0.1853759765624967 -0.9360000000000001 -0.006805419921875 -0.1853759765624967 -0.936125 -0.005828857421875 -0.1853759765624967 -0.9362500000000001 -0.005828857421875 -0.1853759765624967 -0.9363750000000001 -0.004852294921875 -0.1853759765624967 -0.9365 -0.004852294921875 -0.1853759765624967 -0.9366250000000001 -0.00390625 -0.1853759765624967 -0.93675 -0.0029296875 -0.1853759765624967 -0.936875 -0.0029296875 -0.1853759765624967 -0.9370000000000001 -0.001953125 -0.1853759765624967 -0.937125 -0.001953125 -0.1853759765624967 -0.93725 -0.0009765625 -0.1853759765624967 +0.8751250000000001 -0.00299072265625 -0.572260742187499 +0.87525 -0.00299072265625 -0.572260742187499 +0.875375 -0.0059814453125 -0.572260742187499 +0.8755000000000001 -0.00897216796875 -0.572260742187499 +0.875625 -0.00897216796875 -0.572260742187499 +0.87575 -0.011962890625 -0.572260742187499 +0.8758750000000001 -0.011962890625 -0.572260742187499 +0.876 -0.01495361328125 -0.572260742187499 +0.876125 -0.0179443359375 -0.572260742187499 +0.8762499999999999 -0.0179443359375 -0.572260742187499 +0.876375 -0.02093505859375 -0.572260742187499 +0.8765000000000001 -0.02093505859375 -0.572260742187499 +0.8766249999999999 -0.02392578125 -0.572260742187499 +0.87675 -0.02691650390625 -0.572260742187499 +0.8768750000000001 -0.02691650390625 -0.572260742187499 +0.877 -0.0299072265625 -0.572260742187499 +0.877125 -0.0299072265625 -0.572260742187499 +0.8772499999999999 -0.032867431640625 -0.572260742187499 +0.877375 -0.03582763671875 -0.572260742187499 +0.8775 -0.03582763671875 -0.572260742187499 +0.8776249999999999 -0.038818359375 -0.572260742187499 +0.87775 -0.038818359375 -0.572260742187499 +0.877875 -0.041778564453125 -0.572260742187499 +0.8779999999999999 -0.04473876953125 -0.572260742187499 +0.878125 -0.04473876953125 -0.572260742187499 +0.8782499999999999 -0.047698974609375 -0.572260742187499 +0.878375 -0.047698974609375 -0.572260742187499 +0.8785 -0.0506591796875 -0.572260742187499 +0.8786249999999999 -0.0535888671875 -0.572260742187499 +0.87875 -0.0535888671875 -0.572260742187499 +0.878875 -0.0565185546875 -0.572260742187499 +0.8789999999999999 -0.0565185546875 -0.572260742187499 +0.879125 -0.059478759765625 -0.572260742187499 +0.87925 -0.0623779296875 -0.572260742187499 +0.8793749999999999 -0.0623779296875 -0.572260742187499 +0.8795 -0.0653076171875 -0.572260742187499 +0.8796250000000001 -0.0653076171875 -0.572260742187499 +0.8797499999999999 -0.0682373046875 -0.572260742187499 +0.879875 -0.071136474609375 -0.572260742187499 +0.8800000000000001 -0.071136474609375 -0.572260742187499 +0.880125 -0.07403564453125 -0.572260742187499 +0.88025 -0.07403564453125 -0.572260742187499 +0.8803750000000001 -0.076934814453125 -0.572260742187499 +0.8805 -0.079803466796875 -0.572260742187499 +0.880625 -0.079803466796875 -0.572260742187499 +0.8807500000000001 -0.082672119140625 -0.572260742187499 +0.880875 -0.082672119140625 -0.572260742187499 +0.881 -0.085540771484375 -0.572260742187499 +0.8811250000000001 -0.088409423828125 -0.572260742187499 +0.88125 -0.088409423828125 -0.572260742187499 +0.8813750000000001 -0.09124755859375 -0.572260742187499 +0.8815000000000001 -0.09124755859375 -0.572260742187499 +0.881625 -0.094085693359375 -0.572260742187499 +0.8817500000000001 -0.096893310546875 -0.572260742187499 +0.881875 -0.096893310546875 -0.572260742187499 +0.882 -0.099700927734375 -0.572260742187499 +0.8821250000000001 -0.099700927734375 -0.572260742187499 +0.88225 -0.102508544921875 -0.572260742187499 +0.882375 -0.105316162109375 -0.572260742187499 +0.8825000000000001 -0.105316162109375 -0.572260742187499 +0.882625 -0.10809326171875 -0.572260742187499 +0.8827500000000001 -0.10809326171875 -0.572260742187499 +0.8828749999999999 -0.110870361328125 -0.572260742187499 +0.883 -0.113616943359375 -0.572260742187499 +0.8831250000000001 -0.113616943359375 -0.572260742187499 +0.88325 -0.116363525390625 -0.572260742187499 +0.883375 -0.116363525390625 -0.572260742187499 +0.8835000000000001 -0.11907958984375 -0.572260742187499 +0.883625 -0.121795654296875 -0.572260742187499 +0.88375 -0.121795654296875 -0.572260742187499 +0.8838749999999999 -0.12451171875 -0.572260742187499 +0.884 -0.12451171875 -0.572260742187499 +0.884125 -0.127197265625 -0.572260742187499 +0.8842499999999999 -0.1298828125 -0.572260742187499 +0.884375 -0.1298828125 -0.572260742187499 +0.8845000000000001 -0.132537841796875 -0.572260742187499 +0.884625 -0.132537841796875 -0.572260742187499 +0.88475 -0.13519287109375 -0.572260742187499 +0.8848749999999999 -0.1378173828125 -0.572260742187499 +0.885 -0.1378173828125 -0.572260742187499 +0.885125 -0.14044189453125 -0.572260742187499 +0.8852499999999999 -0.14044189453125 -0.572260742187499 +0.885375 -0.143035888671875 -0.572260742187499 +0.8855 -0.1456298828125 -0.572260742187499 +0.8856249999999999 -0.1456298828125 -0.572260742187499 +0.88575 -0.148193359375 -0.572260742187499 +0.8858750000000001 -0.148193359375 -0.572260742187499 +0.8859999999999999 -0.1507568359375 -0.572260742187499 +0.886125 -0.153289794921875 -0.572260742187499 +0.8862500000000001 -0.153289794921875 -0.572260742187499 +0.886375 -0.15582275390625 -0.572260742187499 +0.8865 -0.15582275390625 -0.572260742187499 +0.8866250000000001 -0.1583251953125 -0.572260742187499 +0.88675 -0.160797119140625 -0.572260742187499 +0.886875 -0.160797119140625 -0.572260742187499 +0.8870000000000001 -0.16326904296875 -0.572260742187499 +0.887125 -0.16326904296875 -0.572260742187499 +0.88725 -0.165740966796875 -0.572260742187499 +0.8873750000000001 -0.16815185546875 -0.572260742187499 +0.8875 -0.16815185546875 -0.572260742187499 +0.8876250000000001 -0.170562744140625 -0.572260742187499 +0.8877500000000001 -0.170562744140625 -0.572260742187499 +0.887875 -0.1729736328125 -0.572260742187499 +0.8880000000000001 -0.17535400390625 -0.572260742187499 +0.8881250000000001 -0.17535400390625 -0.572260742187499 +0.88825 -0.177703857421875 -0.572260742187499 +0.8883750000000001 -0.177703857421875 -0.572260742187499 +0.8885000000000002 -0.1800537109375 -0.572260742187499 +0.888625 -0.182373046875 -0.572260742187499 +0.8887500000000001 -0.182373046875 -0.572260742187499 +0.888875 -0.184661865234375 -0.572260742187499 +0.8890000000000001 -0.184661865234375 -0.572260742187499 +0.8891250000000001 -0.18695068359375 -0.572260742187499 +0.88925 -0.189208984375 -0.572260742187499 +0.8893750000000001 -0.189208984375 -0.572260742187499 +0.8895000000000001 -0.191436767578125 -0.572260742187499 +0.889625 -0.191436767578125 -0.572260742187499 +0.8897500000000001 -0.19366455078125 -0.572260742187499 +0.889875 -0.195831298828125 -0.572260742187499 +0.89 -0.195831298828125 -0.572260742187499 +0.8901250000000001 -0.198028564453125 -0.572260742187499 +0.89025 -0.198028564453125 -0.572260742187499 +0.890375 -0.200164794921875 -0.572260742187499 +0.8905000000000001 -0.202301025390625 -0.572260742187499 +0.890625 -0.202301025390625 -0.572260742187499 +0.8907500000000001 -0.20440673828125 -0.572260742187499 +0.890875 -0.20440673828125 -0.572260742187499 +0.891 -0.20648193359375 -0.572260742187499 +0.8911250000000001 -0.20855712890625 -0.572260742187499 +0.89125 -0.20855712890625 -0.572260742187499 +0.891375 -0.210601806640625 -0.572260742187499 +0.8915000000000001 -0.210601806640625 -0.572260742187499 +0.891625 -0.212615966796875 -0.572260742187499 +0.89175 -0.214599609375 -0.572260742187499 +0.8918749999999999 -0.214599609375 -0.572260742187499 +0.892 -0.216583251953125 -0.572260742187499 +0.8921250000000001 -0.216583251953125 -0.572260742187499 +0.8922499999999999 -0.218536376953125 -0.572260742187499 +0.892375 -0.220428466796875 -0.572260742187499 +0.8925000000000001 -0.220428466796875 -0.572260742187499 +0.892625 -0.22235107421875 -0.572260742187499 +0.89275 -0.22235107421875 -0.572260742187499 +0.8928749999999999 -0.224212646484375 -0.572260742187499 +0.893 -0.22607421875 -0.572260742187499 +0.893125 -0.22607421875 -0.572260742187499 +0.8932499999999999 -0.227874755859375 -0.572260742187499 +0.893375 -0.227874755859375 -0.572260742187499 +0.8935 -0.22967529296875 -0.572260742187499 +0.8936249999999999 -0.231475830078125 -0.572260742187499 +0.89375 -0.231475830078125 -0.572260742187499 +0.8938749999999999 -0.23321533203125 -0.572260742187499 +0.894 -0.23321533203125 -0.572260742187499 +0.894125 -0.23492431640625 -0.572260742187499 +0.8942499999999999 -0.23663330078125 -0.572260742187499 +0.894375 -0.23663330078125 -0.572260742187499 +0.8945 -0.238311767578125 -0.572260742187499 +0.8946249999999999 -0.238311767578125 -0.572260742187499 +0.89475 -0.23992919921875 -0.572260742187499 +0.894875 -0.2415771484375 -0.572260742187499 +0.8949999999999999 -0.2415771484375 -0.572260742187499 +0.895125 -0.2431640625 -0.572260742187499 +0.8952500000000001 -0.2431640625 -0.572260742187499 +0.8953749999999999 -0.244720458984375 -0.572260742187499 +0.8955 -0.246246337890625 -0.572260742187499 +0.8956250000000001 -0.246246337890625 -0.572260742187499 +0.89575 -0.247772216796875 -0.572260742187499 +0.895875 -0.247772216796875 -0.572260742187499 +0.8960000000000001 -0.186859130859375 -0.4289990234374976 +0.896125 -0.18792724609375 -0.4289990234374976 +0.89625 -0.18792724609375 -0.4289990234374976 +0.8963750000000001 -0.188995361328125 -0.4289990234374976 +0.8965 -0.188995361328125 -0.4289990234374976 +0.896625 -0.1900634765625 -0.4289990234374976 +0.8967500000000001 -0.19110107421875 -0.4289990234374976 +0.896875 -0.19110107421875 -0.4289990234374976 +0.8970000000000001 -0.192108154296875 -0.4289990234374976 +0.8971250000000001 -0.192108154296875 -0.4289990234374976 +0.89725 -0.193084716796875 -0.4289990234374976 +0.8973750000000001 -0.194061279296875 -0.4289990234374976 +0.8975 -0.194061279296875 -0.4289990234374976 +0.897625 -0.19500732421875 -0.4289990234374976 +0.8977500000000001 -0.19500732421875 -0.4289990234374976 +0.897875 -0.1959228515625 -0.4289990234374976 +0.898 -0.19683837890625 -0.4289990234374976 +0.8981250000000001 -0.19683837890625 -0.4289990234374976 +0.89825 -0.19769287109375 -0.4289990234374976 +0.8983750000000001 -0.19769287109375 -0.4289990234374976 +0.8984999999999999 -0.198577880859375 -0.4289990234374976 +0.898625 -0.19940185546875 -0.4289990234374976 +0.8987500000000001 -0.19940185546875 -0.4289990234374976 +0.898875 -0.200225830078125 -0.4289990234374976 +0.899 -0.200225830078125 -0.4289990234374976 +0.8991250000000001 -0.201019287109375 -0.4289990234374976 +0.89925 -0.2017822265625 -0.4289990234374976 +0.899375 -0.2017822265625 -0.4289990234374976 +0.8994999999999999 -0.202545166015625 -0.4289990234374976 +0.899625 -0.202545166015625 -0.4289990234374976 +0.89975 -0.203277587890625 -0.4289990234374976 +0.8998749999999999 -0.2039794921875 -0.4289990234374976 +0.9 -0.2039794921875 -0.4289990234374976 +0.9001250000000001 -0.20465087890625 -0.4289990234374976 +0.90025 -0.20465087890625 -0.4289990234374976 +0.900375 -0.205322265625 -0.4289990234374976 +0.9004999999999999 -0.205963134765625 -0.4289990234374976 +0.900625 -0.205963134765625 -0.4289990234374976 +0.90075 -0.206573486328125 -0.4289990234374976 +0.9008749999999999 -0.206573486328125 -0.4289990234374976 +0.901 -0.2071533203125 -0.4289990234374976 +0.901125 -0.207733154296875 -0.4289990234374976 +0.9012499999999999 -0.207733154296875 -0.4289990234374976 +0.901375 -0.208282470703125 -0.4289990234374976 +0.9015000000000001 -0.208282470703125 -0.4289990234374976 +0.9016249999999999 -0.20880126953125 -0.4289990234374976 +0.90175 -0.20928955078125 -0.4289990234374976 +0.9018750000000001 -0.20928955078125 -0.4289990234374976 +0.902 -0.20977783203125 -0.4289990234374976 +0.902125 -0.20977783203125 -0.4289990234374976 +0.9022500000000001 -0.210235595703125 -0.4289990234374976 +0.902375 -0.210662841796875 -0.4289990234374976 +0.9025 -0.210662841796875 -0.4289990234374976 +0.9026250000000001 -0.211090087890625 -0.4289990234374976 +0.90275 -0.211090087890625 -0.4289990234374976 +0.902875 -0.211456298828125 -0.4289990234374976 +0.9030000000000001 -0.211822509765625 -0.4289990234374976 +0.903125 -0.211822509765625 -0.4289990234374976 +0.9032500000000001 -0.212158203125 -0.4289990234374976 +0.9033750000000001 -0.212158203125 -0.4289990234374976 +0.9035 -0.212493896484375 -0.4289990234374976 +0.9036250000000001 -0.2127685546875 -0.4289990234374976 +0.9037500000000001 -0.2127685546875 -0.4289990234374976 +0.903875 -0.213043212890625 -0.4289990234374976 +0.9040000000000001 -0.213043212890625 -0.4289990234374976 +0.9041250000000002 -0.213287353515625 -0.4289990234374976 +0.90425 -0.2135009765625 -0.4289990234374976 +0.9043750000000001 -0.2135009765625 -0.4289990234374976 +0.9045 -0.213714599609375 -0.4289990234374976 +0.9046250000000001 -0.213714599609375 -0.4289990234374976 +0.9047500000000001 -0.213897705078125 -0.4289990234374976 +0.904875 -0.21405029296875 -0.4289990234374976 +0.9050000000000001 -0.21405029296875 -0.4289990234374976 +0.9051250000000001 -0.21417236328125 -0.4289990234374976 +0.90525 -0.21417236328125 -0.4289990234374976 +0.9053750000000001 -0.21429443359375 -0.4289990234374976 +0.9055 -0.21435546875 -0.4289990234374976 +0.905625 -0.21435546875 -0.4289990234374976 +0.9057500000000001 -0.21441650390625 -0.4289990234374976 +0.905875 -0.21441650390625 -0.4289990234374976 +0.906 -0.214447021484375 -0.4289990234374976 +0.9061250000000001 -0.2144775390625 -0.4289990234374976 +0.90625 -0.2144775390625 -0.4289990234374976 +0.9063750000000001 -0.214447021484375 -0.4289990234374976 +0.9065 -0.214447021484375 -0.4289990234374976 +0.906625 -0.21441650390625 -0.4289990234374976 +0.9067500000000001 -0.21435546875 -0.4289990234374976 +0.906875 -0.21435546875 -0.4289990234374976 +0.907 -0.21429443359375 -0.4289990234374976 +0.9071250000000001 -0.21429443359375 -0.4289990234374976 +0.90725 -0.21417236328125 -0.4289990234374976 +0.907375 -0.21405029296875 -0.4289990234374976 +0.9074999999999999 -0.21405029296875 -0.4289990234374976 +0.907625 -0.213897705078125 -0.4289990234374976 +0.9077500000000001 -0.213897705078125 -0.4289990234374976 +0.9078749999999999 -0.213714599609375 -0.4289990234374976 +0.908 -0.2135009765625 -0.4289990234374976 +0.9081250000000001 -0.2135009765625 -0.4289990234374976 +0.90825 -0.213287353515625 -0.4289990234374976 +0.908375 -0.213287353515625 -0.4289990234374976 +0.9084999999999999 -0.213043212890625 -0.4289990234374976 +0.908625 -0.2127685546875 -0.4289990234374976 +0.90875 -0.2127685546875 -0.4289990234374976 +0.9088749999999999 -0.212493896484375 -0.4289990234374976 +0.909 -0.212493896484375 -0.4289990234374976 +0.909125 -0.212158203125 -0.4289990234374976 +0.9092499999999999 -0.211822509765625 -0.4289990234374976 +0.909375 -0.211822509765625 -0.4289990234374976 +0.9094999999999999 -0.211456298828125 -0.4289990234374976 +0.909625 -0.211456298828125 -0.4289990234374976 +0.90975 -0.211090087890625 -0.4289990234374976 +0.9098749999999999 -0.210662841796875 -0.4289990234374976 +0.91 -0.210662841796875 -0.4289990234374976 +0.910125 -0.210235595703125 -0.4289990234374976 +0.9102499999999999 -0.210235595703125 -0.4289990234374976 +0.910375 -0.20977783203125 -0.4289990234374976 +0.9105 -0.20928955078125 -0.4289990234374976 +0.9106249999999999 -0.20928955078125 -0.4289990234374976 +0.91075 -0.20880126953125 -0.4289990234374976 +0.9108750000000001 -0.20880126953125 -0.4289990234374976 +0.9109999999999999 -0.208282470703125 -0.4289990234374976 +0.911125 -0.207733154296875 -0.4289990234374976 +0.9112500000000001 -0.207733154296875 -0.4289990234374976 +0.911375 -0.2071533203125 -0.4289990234374976 +0.9115 -0.2071533203125 -0.4289990234374976 +0.9116250000000001 -0.206573486328125 -0.4289990234374976 +0.91175 -0.205963134765625 -0.4289990234374976 +0.911875 -0.205963134765625 -0.4289990234374976 +0.9120000000000001 -0.205322265625 -0.4289990234374976 +0.912125 -0.205322265625 -0.4289990234374976 +0.91225 -0.20465087890625 -0.4289990234374976 +0.9123750000000001 -0.2039794921875 -0.4289990234374976 +0.9125 -0.2039794921875 -0.4289990234374976 +0.9126250000000001 -0.203277587890625 -0.4289990234374976 +0.9127500000000001 -0.203277587890625 -0.4289990234374976 +0.912875 -0.202545166015625 -0.4289990234374976 +0.9130000000000001 -0.2017822265625 -0.4289990234374976 +0.913125 -0.2017822265625 -0.4289990234374976 +0.91325 -0.201019287109375 -0.4289990234374976 +0.9133750000000001 -0.201019287109375 -0.4289990234374976 +0.9135 -0.200225830078125 -0.4289990234374976 +0.913625 -0.19940185546875 -0.4289990234374976 +0.9137500000000001 -0.19940185546875 -0.4289990234374976 +0.913875 -0.198577880859375 -0.4289990234374976 +0.9140000000000001 -0.198577880859375 -0.4289990234374976 +0.9141249999999999 -0.19769287109375 -0.4289990234374976 +0.91425 -0.19683837890625 -0.4289990234374976 +0.9143750000000001 -0.19683837890625 -0.4289990234374976 +0.9145 -0.1959228515625 -0.4289990234374976 +0.914625 -0.1959228515625 -0.4289990234374976 +0.9147500000000001 -0.19500732421875 -0.4289990234374976 +0.914875 -0.194061279296875 -0.4289990234374976 +0.915 -0.194061279296875 -0.4289990234374976 +0.9151249999999999 -0.193084716796875 -0.4289990234374976 +0.91525 -0.193084716796875 -0.4289990234374976 +0.915375 -0.192108154296875 -0.4289990234374976 +0.9154999999999999 -0.19110107421875 -0.4289990234374976 +0.915625 -0.19110107421875 -0.4289990234374976 +0.9157500000000001 -0.1900634765625 -0.4289990234374976 +0.915875 -0.1900634765625 -0.4289990234374976 +0.916 -0.188995361328125 -0.4289990234374976 +0.9161249999999999 -0.18792724609375 -0.4289990234374976 +0.91625 -0.18792724609375 -0.4289990234374976 +0.916375 -0.186859130859375 -0.4289990234374976 +0.9164999999999999 -0.186859130859375 -0.4289990234374976 +0.916625 -0.18572998046875 -0.4289990234374976 +0.91675 -0.184600830078125 -0.4289990234374976 +0.9168749999999999 -0.184600830078125 -0.4289990234374976 +0.917 -0.183441162109375 -0.4289990234374976 +0.9171250000000001 -0.183441162109375 -0.4289990234374976 +0.9172499999999999 -0.182281494140625 -0.4289990234374976 +0.917375 -0.18109130859375 -0.4289990234374976 +0.9175000000000001 -0.18109130859375 -0.4289990234374976 +0.917625 -0.17987060546875 -0.4289990234374976 +0.91775 -0.17987060546875 -0.4289990234374976 +0.9178750000000001 -0.178619384765625 -0.4289990234374976 +0.918 -0.1773681640625 -0.4289990234374976 +0.918125 -0.1773681640625 -0.4289990234374976 +0.9182500000000001 -0.176116943359375 -0.4289990234374976 +0.918375 -0.176116943359375 -0.4289990234374976 +0.9185 -0.1748046875 -0.4289990234374976 +0.9186250000000001 -0.173492431640625 -0.4289990234374976 +0.91875 -0.173492431640625 -0.4289990234374976 +0.9188750000000001 -0.17218017578125 -0.4289990234374976 +0.9190000000000001 -0.17218017578125 -0.4289990234374976 +0.919125 -0.17083740234375 -0.4289990234374976 +0.9192500000000001 -0.169464111328125 -0.4289990234374976 +0.9193750000000001 -0.169464111328125 -0.4289990234374976 +0.9195 -0.168060302734375 -0.4289990234374976 +0.9196250000000001 -0.168060302734375 -0.4289990234374976 +0.9197500000000002 -0.166656494140625 -0.4289990234374976 +0.919875 -0.165252685546875 -0.4289990234374976 +0.9200000000000001 -0.165252685546875 -0.4289990234374976 +0.920125 -0.163818359375 -0.4289990234374976 +0.9202500000000001 -0.163818359375 -0.4289990234374976 +0.9203750000000001 -0.162353515625 -0.4289990234374976 +0.9205 -0.160858154296875 -0.4289990234374976 +0.9206250000000001 -0.160858154296875 -0.4289990234374976 +0.9207500000000001 -0.15936279296875 -0.4289990234374976 +0.920875 -0.15936279296875 -0.4289990234374976 +0.9210000000000001 -0.157867431640625 -0.4289990234374976 +0.921125 -0.156341552734375 -0.4289990234374976 +0.92125 -0.156341552734375 -0.4289990234374976 +0.9213750000000001 -0.15478515625 -0.4289990234374976 +0.9215 -0.15478515625 -0.4289990234374976 +0.921625 -0.153228759765625 -0.4289990234374976 +0.9217500000000001 -0.151641845703125 -0.4289990234374976 +0.921875 -0.151641845703125 -0.4289990234374976 +0.9220000000000001 -0.150054931640625 -0.4289990234374976 +0.922125 -0.150054931640625 -0.4289990234374976 +0.92225 -0.1484375 -0.4289990234374976 +0.9223750000000001 -0.146820068359375 -0.4289990234374976 +0.9225 -0.146820068359375 -0.4289990234374976 +0.922625 -0.145172119140625 -0.4289990234374976 +0.9227500000000001 -0.145172119140625 -0.4289990234374976 +0.922875 -0.14349365234375 -0.4289990234374976 +0.923 -0.141815185546875 -0.4289990234374976 +0.9231249999999999 -0.141815185546875 -0.4289990234374976 +0.92325 -0.14013671875 -0.4289990234374976 +0.9233750000000001 -0.14013671875 -0.4289990234374976 +0.9234999999999999 -0.138427734375 -0.4289990234374976 +0.923625 -0.136688232421875 -0.4289990234374976 +0.9237500000000001 -0.136688232421875 -0.4289990234374976 +0.923875 -0.13494873046875 -0.4289990234374976 +0.924 -0.13494873046875 -0.4289990234374976 +0.9241249999999999 -0.133209228515625 -0.4289990234374976 +0.92425 -0.131439208984375 -0.4289990234374976 +0.924375 -0.131439208984375 -0.4289990234374976 +0.9244999999999999 -0.129669189453125 -0.4289990234374976 +0.924625 -0.129669189453125 -0.4289990234374976 +0.92475 -0.12786865234375 -0.4289990234374976 +0.9248749999999999 -0.12603759765625 -0.4289990234374976 +0.925 -0.12603759765625 -0.4289990234374976 +0.9251249999999999 -0.124237060546875 -0.4289990234374976 +0.92525 -0.124237060546875 -0.4289990234374976 +0.925375 -0.122406005859375 -0.4289990234374976 +0.9254999999999999 -0.12054443359375 -0.4289990234374976 +0.925625 -0.12054443359375 -0.4289990234374976 +0.92575 -0.118682861328125 -0.4289990234374976 +0.9258749999999999 -0.118682861328125 -0.4289990234374976 +0.926 -0.116790771484375 -0.4289990234374976 +0.926125 -0.114898681640625 -0.4289990234374976 +0.9262499999999999 -0.114898681640625 -0.4289990234374976 +0.926375 -0.113006591796875 -0.4289990234374976 +0.9265000000000001 -0.113006591796875 -0.4289990234374976 +0.9266249999999999 -0.111083984375 -0.4289990234374976 +0.92675 -0.109161376953125 -0.4289990234374976 +0.9268750000000001 -0.109161376953125 -0.4289990234374976 +0.927 -0.10723876953125 -0.4289990234374976 +0.927125 -0.10723876953125 -0.4289990234374976 +0.9272500000000001 -0.10528564453125 -0.4289990234374976 +0.927375 -0.103302001953125 -0.4289990234374976 +0.9275 -0.103302001953125 -0.4289990234374976 +0.9276250000000001 -0.101348876953125 -0.4289990234374976 +0.92775 -0.101348876953125 -0.4289990234374976 +0.927875 -0.099365234375 -0.4289990234374976 +0.9280000000000001 -0.04205322265625 -0.1853759765624967 +0.928125 -0.04205322265625 -0.1853759765624967 +0.9282500000000001 -0.04119873046875 -0.1853759765624967 +0.9283750000000001 -0.04119873046875 -0.1853759765624967 +0.9285 -0.040313720703125 -0.1853759765624967 +0.9286250000000001 -0.039459228515625 -0.1853759765624967 +0.92875 -0.039459228515625 -0.1853759765624967 +0.928875 -0.03857421875 -0.1853759765624967 +0.9290000000000001 -0.03857421875 -0.1853759765624967 +0.929125 -0.037689208984375 -0.1853759765624967 +0.92925 -0.03680419921875 -0.1853759765624967 +0.9293750000000001 -0.03680419921875 -0.1853759765624967 +0.9295 -0.035888671875 -0.1853759765624967 +0.9296250000000001 -0.035888671875 -0.1853759765624967 +0.9297499999999999 -0.035003662109375 -0.1853759765624967 +0.929875 -0.034088134765625 -0.1853759765624967 +0.9300000000000001 -0.034088134765625 -0.1853759765624967 +0.930125 -0.033203125 -0.1853759765624967 +0.93025 -0.033203125 -0.1853759765624967 +0.9303750000000001 -0.03228759765625 -0.1853759765624967 +0.9305 -0.0313720703125 -0.1853759765624967 +0.930625 -0.0313720703125 -0.1853759765624967 +0.9307499999999999 -0.03045654296875 -0.1853759765624967 +0.930875 -0.03045654296875 -0.1853759765624967 +0.931 -0.029541015625 -0.1853759765624967 +0.9311249999999999 -0.02862548828125 -0.1853759765624967 +0.93125 -0.02862548828125 -0.1853759765624967 +0.9313750000000001 -0.0277099609375 -0.1853759765624967 +0.9315 -0.0277099609375 -0.1853759765624967 +0.931625 -0.026763916015625 -0.1853759765624967 +0.9317499999999999 -0.025848388671875 -0.1853759765624967 +0.931875 -0.025848388671875 -0.1853759765624967 +0.932 -0.02490234375 -0.1853759765624967 +0.9321249999999999 -0.02490234375 -0.1853759765624967 +0.93225 -0.023956298828125 -0.1853759765624967 +0.932375 -0.023040771484375 -0.1853759765624967 +0.9324999999999999 -0.023040771484375 -0.1853759765624967 +0.932625 -0.0220947265625 -0.1853759765624967 +0.9327500000000001 -0.0220947265625 -0.1853759765624967 +0.9328749999999999 -0.021148681640625 -0.1853759765624967 +0.933 -0.02020263671875 -0.1853759765624967 +0.9331250000000001 -0.02020263671875 -0.1853759765624967 +0.93325 -0.019256591796875 -0.1853759765624967 +0.933375 -0.019256591796875 -0.1853759765624967 +0.9335000000000001 -0.018310546875 -0.1853759765624967 +0.933625 -0.017333984375 -0.1853759765624967 +0.93375 -0.017333984375 -0.1853759765624967 +0.9338750000000001 -0.016387939453125 -0.1853759765624967 +0.934 -0.016387939453125 -0.1853759765624967 +0.934125 -0.01544189453125 -0.1853759765624967 +0.9342500000000001 -0.01446533203125 -0.1853759765624967 +0.934375 -0.01446533203125 -0.1853759765624967 +0.9345000000000001 -0.013519287109375 -0.1853759765624967 +0.9346250000000001 -0.013519287109375 -0.1853759765624967 +0.93475 -0.0125732421875 -0.1853759765624967 +0.9348750000000001 -0.0115966796875 -0.1853759765624967 +0.9350000000000001 -0.0115966796875 -0.1853759765624967 +0.935125 -0.010650634765625 -0.1853759765624967 +0.9352500000000001 -0.010650634765625 -0.1853759765624967 +0.9353750000000002 -0.009674072265625 -0.1853759765624967 +0.9355 -0.008697509765625 -0.1853759765624967 +0.9356250000000001 -0.008697509765625 -0.1853759765624967 +0.93575 -0.00775146484375 -0.1853759765624967 +0.9358750000000001 -0.00775146484375 -0.1853759765624967 +0.9360000000000001 -0.00677490234375 -0.1853759765624967 +0.936125 -0.00579833984375 -0.1853759765624967 +0.9362500000000001 -0.00579833984375 -0.1853759765624967 +0.9363750000000001 -0.00482177734375 -0.1853759765624967 +0.9365 -0.00482177734375 -0.1853759765624967 +0.9366250000000001 -0.003875732421875 -0.1853759765624967 +0.93675 -0.002899169921875 -0.1853759765624967 +0.936875 -0.002899169921875 -0.1853759765624967 +0.9370000000000001 -0.001922607421875 -0.1853759765624967 +0.937125 -0.001922607421875 -0.1853759765624967 +0.93725 -0.000946044921875 -0.1853759765624967 0.9373750000000001 0.0 -0.1853759765624967 0.9375 0.0 -0.1853759765624967 0.9376250000000001 0.000946044921875 -0.1853759765624967 @@ -7678,325 +7678,325 @@ 0.9596250000000001 0.0830078125 -0.1853759765624967 0.95975 0.08343505859375 -0.1853759765624967 0.9598750000000001 0.083831787109375 -0.1853759765624967 -0.96 -0.054168701171875 0.1197216796875046 -0.960125 -0.054412841796875 0.1197216796875046 -0.9602500000000001 -0.054412841796875 0.1197216796875046 -0.960375 -0.0546875 0.1197216796875046 -0.9605 -0.054931640625 0.1197216796875046 -0.9606250000000001 -0.054931640625 0.1197216796875046 -0.96075 -0.05517578125 0.1197216796875046 -0.9608750000000001 -0.05517578125 0.1197216796875046 -0.9609999999999999 -0.055419921875 0.1197216796875046 -0.961125 -0.0556640625 0.1197216796875046 -0.9612500000000001 -0.0556640625 0.1197216796875046 -0.961375 -0.055877685546875 0.1197216796875046 -0.9615 -0.055877685546875 0.1197216796875046 -0.9616250000000001 -0.05609130859375 0.1197216796875046 -0.96175 -0.056304931640625 0.1197216796875046 -0.961875 -0.056304931640625 0.1197216796875046 -0.9619999999999999 -0.0565185546875 0.1197216796875046 -0.962125 -0.0565185546875 0.1197216796875046 -0.96225 -0.056732177734375 0.1197216796875046 -0.9623749999999999 -0.056915283203125 0.1197216796875046 -0.9625 -0.056915283203125 0.1197216796875046 -0.9626250000000001 -0.05712890625 0.1197216796875046 -0.96275 -0.05712890625 0.1197216796875046 -0.962875 -0.05731201171875 0.1197216796875046 -0.9629999999999999 -0.0574951171875 0.1197216796875046 -0.963125 -0.0574951171875 0.1197216796875046 -0.96325 -0.057647705078125 0.1197216796875046 -0.9633749999999999 -0.057647705078125 0.1197216796875046 -0.9635 -0.057830810546875 0.1197216796875046 -0.963625 -0.0579833984375 0.1197216796875046 -0.9637499999999999 -0.0579833984375 0.1197216796875046 -0.963875 -0.058135986328125 0.1197216796875046 -0.9640000000000001 -0.058135986328125 0.1197216796875046 -0.9641249999999999 -0.05828857421875 0.1197216796875046 -0.96425 -0.05841064453125 0.1197216796875046 -0.9643750000000001 -0.05841064453125 0.1197216796875046 -0.9645 -0.058563232421875 0.1197216796875046 -0.964625 -0.058563232421875 0.1197216796875046 -0.9647500000000001 -0.058685302734375 0.1197216796875046 -0.964875 -0.058807373046875 0.1197216796875046 -0.965 -0.058807373046875 0.1197216796875046 -0.9651250000000001 -0.05889892578125 0.1197216796875046 -0.96525 -0.05889892578125 0.1197216796875046 -0.965375 -0.05902099609375 0.1197216796875046 -0.9655000000000001 -0.059112548828125 0.1197216796875046 -0.965625 -0.059112548828125 0.1197216796875046 -0.9657500000000001 -0.0592041015625 0.1197216796875046 -0.9658750000000001 -0.0592041015625 0.1197216796875046 -0.966 -0.059295654296875 0.1197216796875046 -0.9661250000000001 -0.05938720703125 0.1197216796875046 -0.9662500000000001 -0.05938720703125 0.1197216796875046 -0.966375 -0.0594482421875 0.1197216796875046 -0.9665000000000001 -0.0594482421875 0.1197216796875046 -0.9666250000000002 -0.059539794921875 0.1197216796875046 -0.96675 -0.059600830078125 0.1197216796875046 -0.9668750000000001 -0.059600830078125 0.1197216796875046 -0.967 -0.059661865234375 0.1197216796875046 -0.9671250000000001 -0.059661865234375 0.1197216796875046 -0.9672500000000001 -0.0596923828125 0.1197216796875046 -0.967375 -0.05975341796875 0.1197216796875046 -0.9675000000000001 -0.05975341796875 0.1197216796875046 -0.9676250000000001 -0.059783935546875 0.1197216796875046 -0.96775 -0.059783935546875 0.1197216796875046 -0.9678750000000001 -0.059814453125 0.1197216796875046 -0.968 -0.059814453125 0.1197216796875046 -0.968125 -0.059814453125 0.1197216796875046 -0.9682500000000001 -0.059844970703125 0.1197216796875046 -0.968375 -0.059844970703125 0.1197216796875046 -0.9685 -0.059844970703125 0.1197216796875046 -0.9686250000000001 -0.059844970703125 0.1197216796875046 -0.96875 -0.059844970703125 0.1197216796875046 -0.9688750000000001 -0.059844970703125 0.1197216796875046 -0.969 -0.059844970703125 0.1197216796875046 -0.969125 -0.059844970703125 0.1197216796875046 -0.9692500000000001 -0.059814453125 0.1197216796875046 -0.969375 -0.059814453125 0.1197216796875046 -0.9695 -0.059814453125 0.1197216796875046 -0.9696250000000001 -0.059814453125 0.1197216796875046 -0.96975 -0.059783935546875 0.1197216796875046 -0.969875 -0.05975341796875 0.1197216796875046 -0.9699999999999999 -0.05975341796875 0.1197216796875046 -0.970125 -0.0596923828125 0.1197216796875046 -0.9702500000000001 -0.0596923828125 0.1197216796875046 -0.9703749999999999 -0.059661865234375 0.1197216796875046 -0.9705 -0.059600830078125 0.1197216796875046 -0.9706250000000001 -0.059600830078125 0.1197216796875046 -0.97075 -0.059539794921875 0.1197216796875046 -0.970875 -0.059539794921875 0.1197216796875046 -0.9709999999999999 -0.0594482421875 0.1197216796875046 -0.971125 -0.05938720703125 0.1197216796875046 -0.97125 -0.05938720703125 0.1197216796875046 -0.9713749999999999 -0.059295654296875 0.1197216796875046 -0.9715 -0.059295654296875 0.1197216796875046 -0.971625 -0.0592041015625 0.1197216796875046 -0.9717499999999999 -0.059112548828125 0.1197216796875046 -0.971875 -0.059112548828125 0.1197216796875046 -0.9719999999999999 -0.05902099609375 0.1197216796875046 -0.972125 -0.05902099609375 0.1197216796875046 -0.97225 -0.05889892578125 0.1197216796875046 -0.9723749999999999 -0.058807373046875 0.1197216796875046 -0.9725 -0.058807373046875 0.1197216796875046 -0.972625 -0.058685302734375 0.1197216796875046 -0.9727499999999999 -0.058685302734375 0.1197216796875046 -0.972875 -0.058563232421875 0.1197216796875046 -0.973 -0.05841064453125 0.1197216796875046 -0.9731249999999999 -0.05841064453125 0.1197216796875046 -0.97325 -0.05828857421875 0.1197216796875046 -0.9733750000000001 -0.05828857421875 0.1197216796875046 -0.9734999999999999 -0.058135986328125 0.1197216796875046 -0.973625 -0.0579833984375 0.1197216796875046 -0.9737500000000001 -0.0579833984375 0.1197216796875046 -0.973875 -0.057830810546875 0.1197216796875046 -0.974 -0.057830810546875 0.1197216796875046 -0.9741250000000001 -0.057647705078125 0.1197216796875046 -0.97425 -0.0574951171875 0.1197216796875046 -0.974375 -0.0574951171875 0.1197216796875046 -0.9745000000000001 -0.05731201171875 0.1197216796875046 -0.974625 -0.05731201171875 0.1197216796875046 -0.97475 -0.05712890625 0.1197216796875046 -0.9748750000000001 -0.056915283203125 0.1197216796875046 -0.975 -0.056915283203125 0.1197216796875046 -0.9751250000000001 -0.056732177734375 0.1197216796875046 -0.9752500000000001 -0.056732177734375 0.1197216796875046 -0.975375 -0.0565185546875 0.1197216796875046 -0.9755000000000001 -0.056304931640625 0.1197216796875046 -0.9756250000000001 -0.056304931640625 0.1197216796875046 -0.97575 -0.05609130859375 0.1197216796875046 -0.9758750000000001 -0.05609130859375 0.1197216796875046 -0.976 -0.055877685546875 0.1197216796875046 -0.976125 -0.0556640625 0.1197216796875046 -0.9762500000000001 -0.0556640625 0.1197216796875046 -0.976375 -0.055419921875 0.1197216796875046 -0.9765000000000001 -0.055419921875 0.1197216796875046 -0.9766249999999999 -0.05517578125 0.1197216796875046 -0.97675 -0.054931640625 0.1197216796875046 -0.9768750000000001 -0.054931640625 0.1197216796875046 -0.977 -0.0546875 0.1197216796875046 -0.977125 -0.0546875 0.1197216796875046 -0.9772500000000001 -0.054412841796875 0.1197216796875046 -0.977375 -0.054168701171875 0.1197216796875046 -0.9775 -0.054168701171875 0.1197216796875046 -0.9776249999999999 -0.05389404296875 0.1197216796875046 -0.97775 -0.05389404296875 0.1197216796875046 -0.977875 -0.053619384765625 0.1197216796875046 -0.9779999999999999 -0.0533447265625 0.1197216796875046 -0.978125 -0.0533447265625 0.1197216796875046 -0.9782500000000001 -0.05303955078125 0.1197216796875046 -0.978375 -0.05303955078125 0.1197216796875046 -0.9785 -0.052764892578125 0.1197216796875046 -0.9786249999999999 -0.052459716796875 0.1197216796875046 -0.97875 -0.052459716796875 0.1197216796875046 -0.978875 -0.052154541015625 0.1197216796875046 -0.9789999999999999 -0.052154541015625 0.1197216796875046 -0.979125 -0.051849365234375 0.1197216796875046 -0.97925 -0.051513671875 0.1197216796875046 -0.9793749999999999 -0.051513671875 0.1197216796875046 -0.9795 -0.05120849609375 0.1197216796875046 -0.9796250000000001 -0.05120849609375 0.1197216796875046 -0.9797499999999999 -0.050872802734375 0.1197216796875046 -0.979875 -0.050537109375 0.1197216796875046 -0.9800000000000001 -0.050537109375 0.1197216796875046 -0.980125 -0.050201416015625 0.1197216796875046 -0.98025 -0.050201416015625 0.1197216796875046 -0.9803750000000001 -0.04986572265625 0.1197216796875046 -0.9805 -0.04949951171875 0.1197216796875046 -0.980625 -0.04949951171875 0.1197216796875046 -0.9807500000000001 -0.049163818359375 0.1197216796875046 -0.980875 -0.049163818359375 0.1197216796875046 -0.981 -0.048797607421875 0.1197216796875046 -0.9811250000000001 -0.048431396484375 0.1197216796875046 -0.98125 -0.048431396484375 0.1197216796875046 -0.9813750000000001 -0.048065185546875 0.1197216796875046 -0.9815000000000001 -0.048065185546875 0.1197216796875046 -0.981625 -0.04766845703125 0.1197216796875046 -0.9817500000000001 -0.04730224609375 0.1197216796875046 -0.9818750000000001 -0.04730224609375 0.1197216796875046 -0.982 -0.046905517578125 0.1197216796875046 -0.9821250000000001 -0.046905517578125 0.1197216796875046 -0.9822500000000002 -0.0465087890625 0.1197216796875046 -0.982375 -0.046112060546875 0.1197216796875046 -0.9825000000000001 -0.046112060546875 0.1197216796875046 -0.982625 -0.04571533203125 0.1197216796875046 -0.9827500000000001 -0.04571533203125 0.1197216796875046 -0.9828750000000001 -0.045318603515625 0.1197216796875046 -0.983 -0.044891357421875 0.1197216796875046 -0.9831250000000001 -0.044891357421875 0.1197216796875046 -0.9832500000000001 -0.04449462890625 0.1197216796875046 -0.983375 -0.04449462890625 0.1197216796875046 -0.9835000000000001 -0.0440673828125 0.1197216796875046 -0.983625 -0.04364013671875 0.1197216796875046 -0.98375 -0.04364013671875 0.1197216796875046 -0.9838750000000001 -0.043212890625 0.1197216796875046 -0.984 -0.043212890625 0.1197216796875046 -0.984125 -0.04278564453125 0.1197216796875046 -0.9842500000000001 -0.042327880859375 0.1197216796875046 -0.984375 -0.042327880859375 0.1197216796875046 -0.9845000000000001 -0.0418701171875 0.1197216796875046 -0.984625 -0.0418701171875 0.1197216796875046 -0.98475 -0.04144287109375 0.1197216796875046 -0.9848750000000001 -0.040985107421875 0.1197216796875046 -0.985 -0.040985107421875 0.1197216796875046 -0.985125 -0.04052734375 0.1197216796875046 -0.9852500000000001 -0.04052734375 0.1197216796875046 -0.985375 -0.040069580078125 0.1197216796875046 -0.9855 -0.039581298828125 0.1197216796875046 -0.9856249999999999 -0.039581298828125 0.1197216796875046 -0.98575 -0.03912353515625 0.1197216796875046 -0.9858750000000001 -0.03912353515625 0.1197216796875046 -0.9859999999999999 -0.03863525390625 0.1197216796875046 -0.986125 -0.03814697265625 0.1197216796875046 -0.9862500000000001 -0.03814697265625 0.1197216796875046 -0.986375 -0.037689208984375 0.1197216796875046 -0.9865 -0.037689208984375 0.1197216796875046 -0.9866249999999999 -0.037200927734375 0.1197216796875046 -0.98675 -0.03668212890625 0.1197216796875046 -0.986875 -0.03668212890625 0.1197216796875046 -0.9869999999999999 -0.03619384765625 0.1197216796875046 -0.987125 -0.03619384765625 0.1197216796875046 -0.98725 -0.03570556640625 0.1197216796875046 -0.9873749999999999 -0.035186767578125 0.1197216796875046 -0.9875 -0.035186767578125 0.1197216796875046 -0.9876249999999999 -0.03466796875 0.1197216796875046 -0.98775 -0.03466796875 0.1197216796875046 -0.987875 -0.0341796875 0.1197216796875046 -0.9879999999999999 -0.033660888671875 0.1197216796875046 -0.988125 -0.033660888671875 0.1197216796875046 -0.98825 -0.03314208984375 0.1197216796875046 -0.9883749999999999 -0.03314208984375 0.1197216796875046 -0.9885 -0.0325927734375 0.1197216796875046 -0.988625 -0.032073974609375 0.1197216796875046 -0.9887499999999999 -0.032073974609375 0.1197216796875046 -0.988875 -0.03155517578125 0.1197216796875046 -0.9890000000000001 -0.03155517578125 0.1197216796875046 -0.9891249999999999 -0.031005859375 0.1197216796875046 -0.98925 -0.030487060546875 0.1197216796875046 -0.9893750000000001 -0.030487060546875 0.1197216796875046 -0.9895 -0.029937744140625 0.1197216796875046 -0.989625 -0.029937744140625 0.1197216796875046 -0.9897500000000001 -0.029388427734375 0.1197216796875046 -0.989875 -0.028839111328125 0.1197216796875046 -0.99 -0.028839111328125 0.1197216796875046 -0.9901250000000001 -0.028289794921875 0.1197216796875046 -0.99025 -0.028289794921875 0.1197216796875046 -0.990375 -0.027740478515625 0.1197216796875046 -0.9905000000000001 -0.027191162109375 0.1197216796875046 -0.990625 -0.027191162109375 0.1197216796875046 -0.9907500000000001 -0.026611328125 0.1197216796875046 -0.9908750000000001 -0.026611328125 0.1197216796875046 -0.991 -0.02606201171875 0.1197216796875046 -0.9911250000000001 -0.025482177734375 0.1197216796875046 -0.9912500000000001 -0.025482177734375 0.1197216796875046 -0.991375 -0.024932861328125 0.1197216796875046 -0.9915000000000001 -0.024932861328125 0.1197216796875046 -0.991625 -0.02435302734375 0.1197216796875046 -0.99175 -0.023773193359375 0.1197216796875046 -0.9918750000000001 -0.023773193359375 0.1197216796875046 -0.992 -0.084808349609375 0.4376074218750045 -0.9921250000000001 -0.084808349609375 0.4376074218750045 -0.9922499999999999 -0.082672119140625 0.4376074218750045 -0.992375 -0.08056640625 0.4376074218750045 -0.9925000000000001 -0.08056640625 0.4376074218750045 -0.992625 -0.07843017578125 0.4376074218750045 -0.99275 -0.07843017578125 0.4376074218750045 -0.9928750000000001 -0.076263427734375 0.4376074218750045 -0.993 -0.074127197265625 0.4376074218750045 -0.993125 -0.074127197265625 0.4376074218750045 -0.9932499999999999 -0.07196044921875 0.4376074218750045 -0.993375 -0.07196044921875 0.4376074218750045 -0.9935 -0.069793701171875 0.4376074218750045 -0.9936249999999999 -0.067626953125 0.4376074218750045 -0.99375 -0.067626953125 0.4376074218750045 -0.9938750000000001 -0.0654296875 0.4376074218750045 -0.994 -0.0654296875 0.4376074218750045 -0.994125 -0.063232421875 0.4376074218750045 -0.9942499999999999 -0.061065673828125 0.4376074218750045 -0.994375 -0.061065673828125 0.4376074218750045 -0.9945 -0.058837890625 0.4376074218750045 -0.9946249999999999 -0.058837890625 0.4376074218750045 -0.99475 -0.056640625 0.4376074218750045 -0.994875 -0.054412841796875 0.4376074218750045 -0.9949999999999999 -0.054412841796875 0.4376074218750045 -0.995125 -0.052215576171875 0.4376074218750045 -0.9952500000000001 -0.052215576171875 0.4376074218750045 -0.9953749999999999 -0.04998779296875 0.4376074218750045 -0.9955 -0.0477294921875 0.4376074218750045 -0.9956250000000001 -0.0477294921875 0.4376074218750045 -0.99575 -0.045501708984375 0.4376074218750045 -0.995875 -0.045501708984375 0.4376074218750045 -0.9960000000000001 -0.043243408203125 0.4376074218750045 -0.996125 -0.041015625 0.4376074218750045 -0.99625 -0.041015625 0.4376074218750045 -0.9963750000000001 -0.03875732421875 0.4376074218750045 -0.9965 -0.03875732421875 0.4376074218750045 -0.996625 -0.0364990234375 0.4376074218750045 -0.9967500000000001 -0.03424072265625 0.4376074218750045 -0.996875 -0.03424072265625 0.4376074218750045 -0.9970000000000001 -0.031982421875 0.4376074218750045 -0.9971250000000001 -0.031982421875 0.4376074218750045 -0.99725 -0.029693603515625 0.4376074218750045 -0.9973750000000001 -0.027435302734375 0.4376074218750045 -0.9975000000000001 -0.027435302734375 0.4376074218750045 -0.997625 -0.025146484375 0.4376074218750045 -0.9977500000000001 -0.025146484375 0.4376074218750045 -0.9978750000000002 -0.02288818359375 0.4376074218750045 -0.998 -0.020599365234375 0.4376074218750045 -0.9981250000000001 -0.020599365234375 0.4376074218750045 -0.99825 -0.018310546875 0.4376074218750045 -0.9983750000000001 -0.018310546875 0.4376074218750045 -0.9985000000000001 -0.016021728515625 0.4376074218750045 -0.998625 -0.013763427734375 0.4376074218750045 -0.9987500000000001 -0.013763427734375 0.4376074218750045 -0.9988750000000001 -0.011474609375 0.4376074218750045 -0.999 -0.011474609375 0.4376074218750045 -0.9991250000000001 -0.009185791015625 0.4376074218750045 -0.99925 -0.00689697265625 0.4376074218750045 -0.999375 -0.00689697265625 0.4376074218750045 -0.9995000000000001 -0.004608154296875 0.4376074218750045 -0.999625 -0.004608154296875 0.4376074218750045 -0.99975 -0.0023193359375 0.4376074218750045 +0.96 -0.05413818359375 0.1197216796875046 +0.960125 -0.05438232421875 0.1197216796875046 +0.9602500000000001 -0.05438232421875 0.1197216796875046 +0.960375 -0.054656982421875 0.1197216796875046 +0.9605 -0.054901123046875 0.1197216796875046 +0.9606250000000001 -0.054901123046875 0.1197216796875046 +0.96075 -0.055145263671875 0.1197216796875046 +0.9608750000000001 -0.055145263671875 0.1197216796875046 +0.9609999999999999 -0.055389404296875 0.1197216796875046 +0.961125 -0.055633544921875 0.1197216796875046 +0.9612500000000001 -0.055633544921875 0.1197216796875046 +0.961375 -0.05584716796875 0.1197216796875046 +0.9615 -0.05584716796875 0.1197216796875046 +0.9616250000000001 -0.056060791015625 0.1197216796875046 +0.96175 -0.0562744140625 0.1197216796875046 +0.961875 -0.0562744140625 0.1197216796875046 +0.9619999999999999 -0.056488037109375 0.1197216796875046 +0.962125 -0.056488037109375 0.1197216796875046 +0.96225 -0.05670166015625 0.1197216796875046 +0.9623749999999999 -0.056884765625 0.1197216796875046 +0.9625 -0.056884765625 0.1197216796875046 +0.9626250000000001 -0.057098388671875 0.1197216796875046 +0.96275 -0.057098388671875 0.1197216796875046 +0.962875 -0.057281494140625 0.1197216796875046 +0.9629999999999999 -0.057464599609375 0.1197216796875046 +0.963125 -0.057464599609375 0.1197216796875046 +0.96325 -0.0576171875 0.1197216796875046 +0.9633749999999999 -0.0576171875 0.1197216796875046 +0.9635 -0.05780029296875 0.1197216796875046 +0.963625 -0.057952880859375 0.1197216796875046 +0.9637499999999999 -0.057952880859375 0.1197216796875046 +0.963875 -0.05810546875 0.1197216796875046 +0.9640000000000001 -0.05810546875 0.1197216796875046 +0.9641249999999999 -0.058258056640625 0.1197216796875046 +0.96425 -0.058380126953125 0.1197216796875046 +0.9643750000000001 -0.058380126953125 0.1197216796875046 +0.9645 -0.05853271484375 0.1197216796875046 +0.964625 -0.05853271484375 0.1197216796875046 +0.9647500000000001 -0.05865478515625 0.1197216796875046 +0.964875 -0.05877685546875 0.1197216796875046 +0.965 -0.05877685546875 0.1197216796875046 +0.9651250000000001 -0.058868408203125 0.1197216796875046 +0.96525 -0.058868408203125 0.1197216796875046 +0.965375 -0.058990478515625 0.1197216796875046 +0.9655000000000001 -0.05908203125 0.1197216796875046 +0.965625 -0.05908203125 0.1197216796875046 +0.9657500000000001 -0.059173583984375 0.1197216796875046 +0.9658750000000001 -0.059173583984375 0.1197216796875046 +0.966 -0.05926513671875 0.1197216796875046 +0.9661250000000001 -0.059356689453125 0.1197216796875046 +0.9662500000000001 -0.059356689453125 0.1197216796875046 +0.966375 -0.059417724609375 0.1197216796875046 +0.9665000000000001 -0.059417724609375 0.1197216796875046 +0.9666250000000002 -0.05950927734375 0.1197216796875046 +0.96675 -0.0595703125 0.1197216796875046 +0.9668750000000001 -0.0595703125 0.1197216796875046 +0.967 -0.05963134765625 0.1197216796875046 +0.9671250000000001 -0.05963134765625 0.1197216796875046 +0.9672500000000001 -0.059661865234375 0.1197216796875046 +0.967375 -0.059722900390625 0.1197216796875046 +0.9675000000000001 -0.059722900390625 0.1197216796875046 +0.9676250000000001 -0.05975341796875 0.1197216796875046 +0.96775 -0.05975341796875 0.1197216796875046 +0.9678750000000001 -0.059783935546875 0.1197216796875046 +0.968 -0.059783935546875 0.1197216796875046 +0.968125 -0.059783935546875 0.1197216796875046 +0.9682500000000001 -0.059814453125 0.1197216796875046 +0.968375 -0.059814453125 0.1197216796875046 +0.9685 -0.059814453125 0.1197216796875046 +0.9686250000000001 -0.059814453125 0.1197216796875046 +0.96875 -0.059814453125 0.1197216796875046 +0.9688750000000001 -0.059814453125 0.1197216796875046 +0.969 -0.059814453125 0.1197216796875046 +0.969125 -0.059814453125 0.1197216796875046 +0.9692500000000001 -0.059783935546875 0.1197216796875046 +0.969375 -0.059783935546875 0.1197216796875046 +0.9695 -0.059783935546875 0.1197216796875046 +0.9696250000000001 -0.059783935546875 0.1197216796875046 +0.96975 -0.05975341796875 0.1197216796875046 +0.969875 -0.059722900390625 0.1197216796875046 +0.9699999999999999 -0.059722900390625 0.1197216796875046 +0.970125 -0.059661865234375 0.1197216796875046 +0.9702500000000001 -0.059661865234375 0.1197216796875046 +0.9703749999999999 -0.05963134765625 0.1197216796875046 +0.9705 -0.0595703125 0.1197216796875046 +0.9706250000000001 -0.0595703125 0.1197216796875046 +0.97075 -0.05950927734375 0.1197216796875046 +0.970875 -0.05950927734375 0.1197216796875046 +0.9709999999999999 -0.059417724609375 0.1197216796875046 +0.971125 -0.059356689453125 0.1197216796875046 +0.97125 -0.059356689453125 0.1197216796875046 +0.9713749999999999 -0.05926513671875 0.1197216796875046 +0.9715 -0.05926513671875 0.1197216796875046 +0.971625 -0.059173583984375 0.1197216796875046 +0.9717499999999999 -0.05908203125 0.1197216796875046 +0.971875 -0.05908203125 0.1197216796875046 +0.9719999999999999 -0.058990478515625 0.1197216796875046 +0.972125 -0.058990478515625 0.1197216796875046 +0.97225 -0.058868408203125 0.1197216796875046 +0.9723749999999999 -0.05877685546875 0.1197216796875046 +0.9725 -0.05877685546875 0.1197216796875046 +0.972625 -0.05865478515625 0.1197216796875046 +0.9727499999999999 -0.05865478515625 0.1197216796875046 +0.972875 -0.05853271484375 0.1197216796875046 +0.973 -0.058380126953125 0.1197216796875046 +0.9731249999999999 -0.058380126953125 0.1197216796875046 +0.97325 -0.058258056640625 0.1197216796875046 +0.9733750000000001 -0.058258056640625 0.1197216796875046 +0.9734999999999999 -0.05810546875 0.1197216796875046 +0.973625 -0.057952880859375 0.1197216796875046 +0.9737500000000001 -0.057952880859375 0.1197216796875046 +0.973875 -0.05780029296875 0.1197216796875046 +0.974 -0.05780029296875 0.1197216796875046 +0.9741250000000001 -0.0576171875 0.1197216796875046 +0.97425 -0.057464599609375 0.1197216796875046 +0.974375 -0.057464599609375 0.1197216796875046 +0.9745000000000001 -0.057281494140625 0.1197216796875046 +0.974625 -0.057281494140625 0.1197216796875046 +0.97475 -0.057098388671875 0.1197216796875046 +0.9748750000000001 -0.056884765625 0.1197216796875046 +0.975 -0.056884765625 0.1197216796875046 +0.9751250000000001 -0.05670166015625 0.1197216796875046 +0.9752500000000001 -0.05670166015625 0.1197216796875046 +0.975375 -0.056488037109375 0.1197216796875046 +0.9755000000000001 -0.0562744140625 0.1197216796875046 +0.9756250000000001 -0.0562744140625 0.1197216796875046 +0.97575 -0.056060791015625 0.1197216796875046 +0.9758750000000001 -0.056060791015625 0.1197216796875046 +0.976 -0.05584716796875 0.1197216796875046 +0.976125 -0.055633544921875 0.1197216796875046 +0.9762500000000001 -0.055633544921875 0.1197216796875046 +0.976375 -0.055389404296875 0.1197216796875046 +0.9765000000000001 -0.055389404296875 0.1197216796875046 +0.9766249999999999 -0.055145263671875 0.1197216796875046 +0.97675 -0.054901123046875 0.1197216796875046 +0.9768750000000001 -0.054901123046875 0.1197216796875046 +0.977 -0.054656982421875 0.1197216796875046 +0.977125 -0.054656982421875 0.1197216796875046 +0.9772500000000001 -0.05438232421875 0.1197216796875046 +0.977375 -0.05413818359375 0.1197216796875046 +0.9775 -0.05413818359375 0.1197216796875046 +0.9776249999999999 -0.053863525390625 0.1197216796875046 +0.97775 -0.053863525390625 0.1197216796875046 +0.977875 -0.0535888671875 0.1197216796875046 +0.9779999999999999 -0.053314208984375 0.1197216796875046 +0.978125 -0.053314208984375 0.1197216796875046 +0.9782500000000001 -0.053009033203125 0.1197216796875046 +0.978375 -0.053009033203125 0.1197216796875046 +0.9785 -0.052734375 0.1197216796875046 +0.9786249999999999 -0.05242919921875 0.1197216796875046 +0.97875 -0.05242919921875 0.1197216796875046 +0.978875 -0.0521240234375 0.1197216796875046 +0.9789999999999999 -0.0521240234375 0.1197216796875046 +0.979125 -0.05181884765625 0.1197216796875046 +0.97925 -0.051483154296875 0.1197216796875046 +0.9793749999999999 -0.051483154296875 0.1197216796875046 +0.9795 -0.051177978515625 0.1197216796875046 +0.9796250000000001 -0.051177978515625 0.1197216796875046 +0.9797499999999999 -0.05084228515625 0.1197216796875046 +0.979875 -0.050506591796875 0.1197216796875046 +0.9800000000000001 -0.050506591796875 0.1197216796875046 +0.980125 -0.0501708984375 0.1197216796875046 +0.98025 -0.0501708984375 0.1197216796875046 +0.9803750000000001 -0.049835205078125 0.1197216796875046 +0.9805 -0.049468994140625 0.1197216796875046 +0.980625 -0.049468994140625 0.1197216796875046 +0.9807500000000001 -0.04913330078125 0.1197216796875046 +0.980875 -0.04913330078125 0.1197216796875046 +0.981 -0.04876708984375 0.1197216796875046 +0.9811250000000001 -0.04840087890625 0.1197216796875046 +0.98125 -0.04840087890625 0.1197216796875046 +0.9813750000000001 -0.04803466796875 0.1197216796875046 +0.9815000000000001 -0.04803466796875 0.1197216796875046 +0.981625 -0.047637939453125 0.1197216796875046 +0.9817500000000001 -0.047271728515625 0.1197216796875046 +0.9818750000000001 -0.047271728515625 0.1197216796875046 +0.982 -0.046875 0.1197216796875046 +0.9821250000000001 -0.046875 0.1197216796875046 +0.9822500000000002 -0.046478271484375 0.1197216796875046 +0.982375 -0.04608154296875 0.1197216796875046 +0.9825000000000001 -0.04608154296875 0.1197216796875046 +0.982625 -0.045684814453125 0.1197216796875046 +0.9827500000000001 -0.045684814453125 0.1197216796875046 +0.9828750000000001 -0.0452880859375 0.1197216796875046 +0.983 -0.04486083984375 0.1197216796875046 +0.9831250000000001 -0.04486083984375 0.1197216796875046 +0.9832500000000001 -0.044464111328125 0.1197216796875046 +0.983375 -0.044464111328125 0.1197216796875046 +0.9835000000000001 -0.044036865234375 0.1197216796875046 +0.983625 -0.043609619140625 0.1197216796875046 +0.98375 -0.043609619140625 0.1197216796875046 +0.9838750000000001 -0.043182373046875 0.1197216796875046 +0.984 -0.043182373046875 0.1197216796875046 +0.984125 -0.042755126953125 0.1197216796875046 +0.9842500000000001 -0.04229736328125 0.1197216796875046 +0.984375 -0.04229736328125 0.1197216796875046 +0.9845000000000001 -0.041839599609375 0.1197216796875046 +0.984625 -0.041839599609375 0.1197216796875046 +0.98475 -0.041412353515625 0.1197216796875046 +0.9848750000000001 -0.04095458984375 0.1197216796875046 +0.985 -0.04095458984375 0.1197216796875046 +0.985125 -0.040496826171875 0.1197216796875046 +0.9852500000000001 -0.040496826171875 0.1197216796875046 +0.985375 -0.0400390625 0.1197216796875046 +0.9855 -0.03955078125 0.1197216796875046 +0.9856249999999999 -0.03955078125 0.1197216796875046 +0.98575 -0.039093017578125 0.1197216796875046 +0.9858750000000001 -0.039093017578125 0.1197216796875046 +0.9859999999999999 -0.038604736328125 0.1197216796875046 +0.986125 -0.038116455078125 0.1197216796875046 +0.9862500000000001 -0.038116455078125 0.1197216796875046 +0.986375 -0.03765869140625 0.1197216796875046 +0.9865 -0.03765869140625 0.1197216796875046 +0.9866249999999999 -0.03717041015625 0.1197216796875046 +0.98675 -0.036651611328125 0.1197216796875046 +0.986875 -0.036651611328125 0.1197216796875046 +0.9869999999999999 -0.036163330078125 0.1197216796875046 +0.987125 -0.036163330078125 0.1197216796875046 +0.98725 -0.035675048828125 0.1197216796875046 +0.9873749999999999 -0.03515625 0.1197216796875046 +0.9875 -0.03515625 0.1197216796875046 +0.9876249999999999 -0.034637451171875 0.1197216796875046 +0.98775 -0.034637451171875 0.1197216796875046 +0.987875 -0.034149169921875 0.1197216796875046 +0.9879999999999999 -0.03363037109375 0.1197216796875046 +0.988125 -0.03363037109375 0.1197216796875046 +0.98825 -0.033111572265625 0.1197216796875046 +0.9883749999999999 -0.033111572265625 0.1197216796875046 +0.9885 -0.032562255859375 0.1197216796875046 +0.988625 -0.03204345703125 0.1197216796875046 +0.9887499999999999 -0.03204345703125 0.1197216796875046 +0.988875 -0.031524658203125 0.1197216796875046 +0.9890000000000001 -0.031524658203125 0.1197216796875046 +0.9891249999999999 -0.030975341796875 0.1197216796875046 +0.98925 -0.03045654296875 0.1197216796875046 +0.9893750000000001 -0.03045654296875 0.1197216796875046 +0.9895 -0.0299072265625 0.1197216796875046 +0.989625 -0.0299072265625 0.1197216796875046 +0.9897500000000001 -0.02935791015625 0.1197216796875046 +0.989875 -0.02880859375 0.1197216796875046 +0.99 -0.02880859375 0.1197216796875046 +0.9901250000000001 -0.02825927734375 0.1197216796875046 +0.99025 -0.02825927734375 0.1197216796875046 +0.990375 -0.0277099609375 0.1197216796875046 +0.9905000000000001 -0.02716064453125 0.1197216796875046 +0.990625 -0.02716064453125 0.1197216796875046 +0.9907500000000001 -0.026580810546875 0.1197216796875046 +0.9908750000000001 -0.026580810546875 0.1197216796875046 +0.991 -0.026031494140625 0.1197216796875046 +0.9911250000000001 -0.02545166015625 0.1197216796875046 +0.9912500000000001 -0.02545166015625 0.1197216796875046 +0.991375 -0.02490234375 0.1197216796875046 +0.9915000000000001 -0.02490234375 0.1197216796875046 +0.991625 -0.024322509765625 0.1197216796875046 +0.99175 -0.02374267578125 0.1197216796875046 +0.9918750000000001 -0.02374267578125 0.1197216796875046 +0.992 -0.08477783203125 0.4376074218750045 +0.9921250000000001 -0.08477783203125 0.4376074218750045 +0.9922499999999999 -0.0826416015625 0.4376074218750045 +0.992375 -0.080535888671875 0.4376074218750045 +0.9925000000000001 -0.080535888671875 0.4376074218750045 +0.992625 -0.078399658203125 0.4376074218750045 +0.99275 -0.078399658203125 0.4376074218750045 +0.9928750000000001 -0.07623291015625 0.4376074218750045 +0.993 -0.0740966796875 0.4376074218750045 +0.993125 -0.0740966796875 0.4376074218750045 +0.9932499999999999 -0.071929931640625 0.4376074218750045 +0.993375 -0.071929931640625 0.4376074218750045 +0.9935 -0.06976318359375 0.4376074218750045 +0.9936249999999999 -0.067596435546875 0.4376074218750045 +0.99375 -0.067596435546875 0.4376074218750045 +0.9938750000000001 -0.065399169921875 0.4376074218750045 +0.994 -0.065399169921875 0.4376074218750045 +0.994125 -0.063201904296875 0.4376074218750045 +0.9942499999999999 -0.06103515625 0.4376074218750045 +0.994375 -0.06103515625 0.4376074218750045 +0.9945 -0.058807373046875 0.4376074218750045 +0.9946249999999999 -0.058807373046875 0.4376074218750045 +0.99475 -0.056610107421875 0.4376074218750045 +0.994875 -0.05438232421875 0.4376074218750045 +0.9949999999999999 -0.05438232421875 0.4376074218750045 +0.995125 -0.05218505859375 0.4376074218750045 +0.9952500000000001 -0.05218505859375 0.4376074218750045 +0.9953749999999999 -0.049957275390625 0.4376074218750045 +0.9955 -0.047698974609375 0.4376074218750045 +0.9956250000000001 -0.047698974609375 0.4376074218750045 +0.99575 -0.04547119140625 0.4376074218750045 +0.995875 -0.04547119140625 0.4376074218750045 +0.9960000000000001 -0.043212890625 0.4376074218750045 +0.996125 -0.040985107421875 0.4376074218750045 +0.99625 -0.040985107421875 0.4376074218750045 +0.9963750000000001 -0.038726806640625 0.4376074218750045 +0.9965 -0.038726806640625 0.4376074218750045 +0.996625 -0.036468505859375 0.4376074218750045 +0.9967500000000001 -0.034210205078125 0.4376074218750045 +0.996875 -0.034210205078125 0.4376074218750045 +0.9970000000000001 -0.031951904296875 0.4376074218750045 +0.9971250000000001 -0.031951904296875 0.4376074218750045 +0.99725 -0.0296630859375 0.4376074218750045 +0.9973750000000001 -0.02740478515625 0.4376074218750045 +0.9975000000000001 -0.02740478515625 0.4376074218750045 +0.997625 -0.025115966796875 0.4376074218750045 +0.9977500000000001 -0.025115966796875 0.4376074218750045 +0.9978750000000002 -0.022857666015625 0.4376074218750045 +0.998 -0.02056884765625 0.4376074218750045 +0.9981250000000001 -0.02056884765625 0.4376074218750045 +0.99825 -0.018280029296875 0.4376074218750045 +0.9983750000000001 -0.018280029296875 0.4376074218750045 +0.9985000000000001 -0.0159912109375 0.4376074218750045 +0.998625 -0.01373291015625 0.4376074218750045 +0.9987500000000001 -0.01373291015625 0.4376074218750045 +0.9988750000000001 -0.011444091796875 0.4376074218750045 +0.999 -0.011444091796875 0.4376074218750045 +0.9991250000000001 -0.0091552734375 0.4376074218750045 +0.99925 -0.006866455078125 0.4376074218750045 +0.999375 -0.006866455078125 0.4376074218750045 +0.9995000000000001 -0.00457763671875 0.4376074218750045 +0.999625 -0.00457763671875 0.4376074218750045 +0.99975 -0.002288818359375 0.4376074218750045 0.9998750000000001 0.0 0.4376074218750045 1.0 0.0 0.4376074218750045 1.000125 0.002288818359375 0.4376074218750045 @@ -8499,504 +8499,504 @@ 1.06225 0.0047607421875 0.9150244140625022 1.062375 0.0 0.9150244140625022 1.0625 0.0 0.9150244140625022 -1.062625 -0.004791259765625 0.9150244140625022 -1.06275 -0.004791259765625 0.9150244140625022 -1.062875 -0.00958251953125 0.9150244140625022 -1.063 -0.014373779296875 0.9150244140625022 -1.063125 -0.014373779296875 0.9150244140625022 -1.06325 -0.0191650390625 0.9150244140625022 -1.063375 -0.0191650390625 0.9150244140625022 -1.0635 -0.023956298828125 0.9150244140625022 -1.063625 -0.02874755859375 0.9150244140625022 -1.06375 -0.02874755859375 0.9150244140625022 -1.063875 -0.03350830078125 0.9150244140625022 -1.064 -0.03350830078125 0.9150244140625022 -1.064125 -0.038299560546875 0.9150244140625022 -1.06425 -0.043060302734375 0.9150244140625022 -1.064375 -0.043060302734375 0.9150244140625022 -1.0645 -0.047821044921875 0.9150244140625022 -1.064625 -0.047821044921875 0.9150244140625022 -1.06475 -0.052581787109375 0.9150244140625022 -1.064875 -0.057342529296875 0.9150244140625022 -1.065 -0.057342529296875 0.9150244140625022 -1.065125 -0.062103271484375 0.9150244140625022 -1.06525 -0.062103271484375 0.9150244140625022 -1.065375 -0.06683349609375 0.9150244140625022 -1.0655 -0.071563720703125 0.9150244140625022 -1.065625 -0.071563720703125 0.9150244140625022 -1.06575 -0.0762939453125 0.9150244140625022 -1.065875 -0.0762939453125 0.9150244140625022 -1.066 -0.081024169921875 0.9150244140625022 -1.066125 -0.085723876953125 0.9150244140625022 -1.06625 -0.085723876953125 0.9150244140625022 -1.066375 -0.090423583984375 0.9150244140625022 -1.0665 -0.090423583984375 0.9150244140625022 -1.066625 -0.095123291015625 0.9150244140625022 -1.06675 -0.09979248046875 0.9150244140625022 -1.066875 -0.09979248046875 0.9150244140625022 -1.067 -0.1044921875 0.9150244140625022 -1.067125 -0.1044921875 0.9150244140625022 -1.06725 -0.109130859375 0.9150244140625022 -1.067375 -0.11376953125 0.9150244140625022 -1.0675 -0.11376953125 0.9150244140625022 -1.067625 -0.118408203125 0.9150244140625022 -1.06775 -0.118408203125 0.9150244140625022 -1.067875 -0.123046875 0.9150244140625022 -1.068 -0.127655029296875 0.9150244140625022 -1.068125 -0.127655029296875 0.9150244140625022 -1.06825 -0.132232666015625 0.9150244140625022 -1.068375 -0.132232666015625 0.9150244140625022 -1.0685 -0.136810302734375 0.9150244140625022 -1.068625 -0.141387939453125 0.9150244140625022 -1.06875 -0.141387939453125 0.9150244140625022 -1.068875 -0.14593505859375 0.9150244140625022 -1.069 -0.14593505859375 0.9150244140625022 -1.069125 -0.15045166015625 0.9150244140625022 -1.06925 -0.15496826171875 0.9150244140625022 -1.069375 -0.15496826171875 0.9150244140625022 -1.0695 -0.15948486328125 0.9150244140625022 -1.069625 -0.15948486328125 0.9150244140625022 -1.06975 -0.163970947265625 0.9150244140625022 -1.069875 -0.168426513671875 0.9150244140625022 -1.07 -0.168426513671875 0.9150244140625022 -1.070125 -0.1728515625 0.9150244140625022 -1.07025 -0.1728515625 0.9150244140625022 -1.070375 -0.177276611328125 0.9150244140625022 -1.0705 -0.18170166015625 0.9150244140625022 -1.070625 -0.18170166015625 0.9150244140625022 -1.07075 -0.18609619140625 0.9150244140625022 -1.070875 -0.18609619140625 0.9150244140625022 -1.071 -0.190460205078125 0.9150244140625022 -1.071125 -0.194793701171875 0.9150244140625022 -1.07125 -0.194793701171875 0.9150244140625022 -1.071375 -0.199127197265625 0.9150244140625022 -1.0715 -0.199127197265625 0.9150244140625022 -1.071625 -0.20343017578125 0.9150244140625022 -1.07175 -0.20770263671875 0.9150244140625022 -1.071875 -0.20770263671875 0.9150244140625022 -1.072 -0.211944580078125 0.9150244140625022 -1.072125 -0.211944580078125 0.9150244140625022 -1.07225 -0.2161865234375 0.9150244140625022 -1.072375 -0.22039794921875 0.9150244140625022 -1.0725 -0.22039794921875 0.9150244140625022 -1.072625 -0.224578857421875 0.9150244140625022 -1.07275 -0.224578857421875 0.9150244140625022 -1.072875 -0.228759765625 0.9150244140625022 -1.073 -0.232879638671875 0.9150244140625022 -1.073125 -0.232879638671875 0.9150244140625022 -1.07325 -0.23699951171875 0.9150244140625022 -1.073375 -0.23699951171875 0.9150244140625022 -1.0735 -0.2410888671875 0.9150244140625022 -1.073625 -0.245147705078125 0.9150244140625022 -1.07375 -0.245147705078125 0.9150244140625022 -1.073875 -0.249176025390625 0.9150244140625022 -1.074 -0.249176025390625 0.9150244140625022 -1.074125 -0.253173828125 0.9150244140625022 -1.07425 -0.25714111328125 0.9150244140625022 -1.074375 -0.25714111328125 0.9150244140625022 -1.0745 -0.2611083984375 0.9150244140625022 -1.074625 -0.2611083984375 0.9150244140625022 -1.07475 -0.2650146484375 0.9150244140625022 -1.074875 -0.2689208984375 0.9150244140625022 -1.075 -0.2689208984375 0.9150244140625022 -1.075125 -0.27276611328125 0.9150244140625022 -1.07525 -0.27276611328125 0.9150244140625022 -1.075375 -0.276611328125 0.9150244140625022 -1.0755 -0.280426025390625 0.9150244140625022 -1.075625 -0.280426025390625 0.9150244140625022 -1.07575 -0.2841796875 0.9150244140625022 -1.075875 -0.2841796875 0.9150244140625022 -1.076 -0.28790283203125 0.9150244140625022 -1.076125 -0.2916259765625 0.9150244140625022 -1.07625 -0.2916259765625 0.9150244140625022 -1.076375 -0.2952880859375 0.9150244140625022 -1.0765 -0.2952880859375 0.9150244140625022 -1.076625 -0.2989501953125 0.9150244140625022 -1.07675 -0.30255126953125 0.9150244140625022 -1.076875 -0.30255126953125 0.9150244140625022 -1.077 -0.306121826171875 0.9150244140625022 -1.077125 -0.306121826171875 0.9150244140625022 -1.07725 -0.309661865234375 0.9150244140625022 -1.077375 -0.31317138671875 0.9150244140625022 -1.0775 -0.31317138671875 0.9150244140625022 -1.077625 -0.316650390625 0.9150244140625022 -1.07775 -0.316650390625 0.9150244140625022 -1.077875 -0.320098876953125 0.9150244140625022 -1.078 -0.323486328125 0.9150244140625022 -1.078125 -0.323486328125 0.9150244140625022 -1.07825 -0.326873779296875 0.9150244140625022 -1.078375 -0.326873779296875 0.9150244140625022 -1.0785 -0.3302001953125 0.9150244140625022 -1.078625 -0.33349609375 0.9150244140625022 -1.07875 -0.33349609375 0.9150244140625022 -1.078875 -0.336761474609375 0.9150244140625022 -1.079 -0.336761474609375 0.9150244140625022 -1.079125 -0.339996337890625 0.9150244140625022 -1.07925 -0.343170166015625 0.9150244140625022 -1.079375 -0.343170166015625 0.9150244140625022 -1.0795 -0.3463134765625 0.9150244140625022 -1.079625 -0.3463134765625 0.9150244140625022 -1.07975 -0.34942626953125 0.9150244140625022 -1.079875 -0.352508544921875 0.9150244140625022 -1.08 -0.352508544921875 0.9150244140625022 -1.080125 -0.35552978515625 0.9150244140625022 -1.08025 -0.35552978515625 0.9150244140625022 -1.080375 -0.358551025390625 0.9150244140625022 -1.0805 -0.36151123046875 0.9150244140625022 -1.080625 -0.36151123046875 0.9150244140625022 -1.08075 -0.364410400390625 0.9150244140625022 -1.080875 -0.364410400390625 0.9150244140625022 -1.081 -0.367279052734375 0.9150244140625022 -1.081125 -0.3701171875 0.9150244140625022 -1.08125 -0.3701171875 0.9150244140625022 -1.081375 -0.3729248046875 0.9150244140625022 -1.0815 -0.3729248046875 0.9150244140625022 -1.081625 -0.37567138671875 0.9150244140625022 -1.08175 -0.378387451171875 0.9150244140625022 -1.081875 -0.378387451171875 0.9150244140625022 -1.082 -0.381072998046875 0.9150244140625022 -1.082125 -0.381072998046875 0.9150244140625022 -1.08225 -0.383697509765625 0.9150244140625022 -1.082375 -0.38629150390625 0.9150244140625022 -1.0825 -0.38629150390625 0.9150244140625022 -1.082625 -0.388824462890625 0.9150244140625022 -1.08275 -0.388824462890625 0.9150244140625022 -1.082875 -0.391326904296875 0.9150244140625022 -1.083 -0.393768310546875 0.9150244140625022 -1.083125 -0.393768310546875 0.9150244140625022 -1.08325 -0.396209716796875 0.9150244140625022 -1.083375 -0.396209716796875 0.9150244140625022 -1.0835 -0.398590087890625 0.9150244140625022 -1.083625 -0.400909423828125 0.9150244140625022 -1.08375 -0.400909423828125 0.9150244140625022 -1.083875 -0.4031982421875 0.9150244140625022 -1.084 -0.4031982421875 0.9150244140625022 -1.084125 -0.40545654296875 0.9150244140625022 -1.08425 -0.407623291015625 0.9150244140625022 -1.084375 -0.407623291015625 0.9150244140625022 -1.0845 -0.4097900390625 0.9150244140625022 -1.084625 -0.4097900390625 0.9150244140625022 -1.08475 -0.411895751953125 0.9150244140625022 -1.084875 -0.413970947265625 0.9150244140625022 -1.085 -0.413970947265625 0.9150244140625022 -1.085125 -0.41595458984375 0.9150244140625022 -1.08525 -0.41595458984375 0.9150244140625022 -1.085375 -0.417938232421875 0.9150244140625022 -1.0855 -0.419891357421875 0.9150244140625022 -1.085625 -0.419891357421875 0.9150244140625022 -1.08575 -0.4217529296875 0.9150244140625022 -1.085875 -0.4217529296875 0.9150244140625022 -1.086 -0.423583984375 0.9150244140625022 -1.086125 -0.42535400390625 0.9150244140625022 -1.08625 -0.42535400390625 0.9150244140625022 -1.086375 -0.4271240234375 0.9150244140625022 -1.0865 -0.4271240234375 0.9150244140625022 -1.086625 -0.428802490234375 0.9150244140625022 -1.08675 -0.430450439453125 0.9150244140625022 -1.086875 -0.430450439453125 0.9150244140625022 -1.087 -0.43206787109375 0.9150244140625022 -1.087125 -0.43206787109375 0.9150244140625022 -1.08725 -0.43359375 0.9150244140625022 -1.087375 -0.43511962890625 0.9150244140625022 -1.0875 -0.43511962890625 0.9150244140625022 -1.087625 -0.436553955078125 0.9150244140625022 -1.08775 -0.436553955078125 0.9150244140625022 -1.087875 -0.437957763671875 0.9150244140625022 -1.088 -0.479339599609375 0.9983886718750004 -1.088125 -0.479339599609375 0.9983886718750004 -1.08825 -0.48077392578125 0.9983886718750004 -1.088375 -0.48077392578125 0.9983886718750004 -1.0885 -0.482147216796875 0.9983886718750004 -1.088625 -0.483489990234375 0.9983886718750004 -1.08875 -0.483489990234375 0.9983886718750004 -1.088875 -0.484771728515625 0.9983886718750004 -1.089 -0.484771728515625 0.9983886718750004 -1.089125 -0.485992431640625 0.9983886718750004 -1.08925 -0.487152099609375 0.9983886718750004 -1.089375 -0.487152099609375 0.9983886718750004 -1.0895 -0.488250732421875 0.9983886718750004 -1.089625 -0.488250732421875 0.9983886718750004 -1.08975 -0.48931884765625 0.9983886718750004 -1.089875 -0.490325927734375 0.9983886718750004 -1.09 -0.490325927734375 0.9983886718750004 -1.090125 -0.49127197265625 0.9983886718750004 -1.09025 -0.49127197265625 0.9983886718750004 -1.090375 -0.4921875 0.9983886718750004 -1.0905 -0.493011474609375 0.9983886718750004 -1.090625 -0.493011474609375 0.9983886718750004 -1.09075 -0.493804931640625 0.9983886718750004 -1.090875 -0.493804931640625 0.9983886718750004 -1.091 -0.494537353515625 0.9983886718750004 -1.091125 -0.4952392578125 0.9983886718750004 -1.09125 -0.4952392578125 0.9983886718750004 -1.091375 -0.495849609375 0.9983886718750004 -1.0915 -0.495849609375 0.9983886718750004 -1.091625 -0.496429443359375 0.9983886718750004 -1.09175 -0.4969482421875 0.9983886718750004 -1.091875 -0.4969482421875 0.9983886718750004 -1.092 -0.4974365234375 0.9983886718750004 -1.092125 -0.4974365234375 0.9983886718750004 -1.09225 -0.497833251953125 0.9983886718750004 -1.092375 -0.498199462890625 0.9983886718750004 -1.0925 -0.498199462890625 0.9983886718750004 -1.092625 -0.498504638671875 0.9983886718750004 -1.09275 -0.498504638671875 0.9983886718750004 -1.092875 -0.498748779296875 0.9983886718750004 -1.093 -0.498931884765625 0.9983886718750004 -1.093125 -0.498931884765625 0.9983886718750004 -1.09325 -0.499053955078125 0.9983886718750004 -1.093375 -0.499053955078125 0.9983886718750004 -1.0935 -0.4991455078125 0.9983886718750004 -1.093625 -0.499176025390625 0.9983886718750004 -1.09375 -0.499176025390625 0.9983886718750004 -1.093875 -0.4991455078125 0.9983886718750004 -1.094 -0.4991455078125 0.9983886718750004 -1.094125 -0.499053955078125 0.9983886718750004 -1.09425 -0.498931884765625 0.9983886718750004 -1.094375 -0.498931884765625 0.9983886718750004 -1.0945 -0.498748779296875 0.9983886718750004 -1.094625 -0.498748779296875 0.9983886718750004 -1.09475 -0.498504638671875 0.9983886718750004 -1.094875 -0.498199462890625 0.9983886718750004 -1.095 -0.498199462890625 0.9983886718750004 -1.095125 -0.497833251953125 0.9983886718750004 -1.09525 -0.497833251953125 0.9983886718750004 -1.095375 -0.4974365234375 0.9983886718750004 -1.0955 -0.4969482421875 0.9983886718750004 -1.095625 -0.4969482421875 0.9983886718750004 -1.09575 -0.496429443359375 0.9983886718750004 -1.095875 -0.496429443359375 0.9983886718750004 -1.096 -0.495849609375 0.9983886718750004 -1.096125 -0.4952392578125 0.9983886718750004 -1.09625 -0.4952392578125 0.9983886718750004 -1.096375 -0.494537353515625 0.9983886718750004 -1.0965 -0.494537353515625 0.9983886718750004 -1.096625 -0.493804931640625 0.9983886718750004 -1.09675 -0.493011474609375 0.9983886718750004 -1.096875 -0.493011474609375 0.9983886718750004 -1.097 -0.4921875 0.9983886718750004 -1.097125 -0.4921875 0.9983886718750004 -1.09725 -0.49127197265625 0.9983886718750004 -1.097375 -0.490325927734375 0.9983886718750004 -1.0975 -0.490325927734375 0.9983886718750004 -1.097625 -0.48931884765625 0.9983886718750004 -1.09775 -0.48931884765625 0.9983886718750004 -1.097875 -0.488250732421875 0.9983886718750004 -1.098 -0.487152099609375 0.9983886718750004 -1.098125 -0.487152099609375 0.9983886718750004 -1.09825 -0.485992431640625 0.9983886718750004 -1.098375 -0.485992431640625 0.9983886718750004 -1.0985 -0.484771728515625 0.9983886718750004 -1.098625 -0.483489990234375 0.9983886718750004 -1.09875 -0.483489990234375 0.9983886718750004 -1.098875 -0.482147216796875 0.9983886718750004 -1.099 -0.482147216796875 0.9983886718750004 -1.099125 -0.48077392578125 0.9983886718750004 -1.09925 -0.479339599609375 0.9983886718750004 -1.099375 -0.479339599609375 0.9983886718750004 -1.0995 -0.477874755859375 0.9983886718750004 -1.099625 -0.477874755859375 0.9983886718750004 -1.09975 -0.476318359375 0.9983886718750004 -1.099875 -0.4747314453125 0.9983886718750004 -1.1 -0.4747314453125 0.9983886718750004 -1.100125 -0.47308349609375 0.9983886718750004 -1.10025 -0.47308349609375 0.9983886718750004 -1.100375 -0.471405029296875 0.9983886718750004 -1.1005 -0.46966552734375 0.9983886718750004 -1.100625 -0.46966552734375 0.9983886718750004 -1.10075 -0.467864990234375 0.9983886718750004 -1.100875 -0.467864990234375 0.9983886718750004 -1.101 -0.46600341796875 0.9983886718750004 -1.101125 -0.464111328125 0.9983886718750004 -1.10125 -0.464111328125 0.9983886718750004 -1.101375 -0.462188720703125 0.9983886718750004 -1.1015 -0.462188720703125 0.9983886718750004 -1.101625 -0.460174560546875 0.9983886718750004 -1.10175 -0.4581298828125 0.9983886718750004 -1.101875 -0.4581298828125 0.9983886718750004 -1.102 -0.456024169921875 0.9983886718750004 -1.102125 -0.456024169921875 0.9983886718750004 -1.10225 -0.453857421875 0.9983886718750004 -1.102375 -0.45166015625 0.9983886718750004 -1.1025 -0.45166015625 0.9983886718750004 -1.102625 -0.44940185546875 0.9983886718750004 -1.10275 -0.44940185546875 0.9983886718750004 -1.102875 -0.447113037109375 0.9983886718750004 -1.103 -0.44476318359375 0.9983886718750004 -1.103125 -0.44476318359375 0.9983886718750004 -1.10325 -0.4423828125 0.9983886718750004 -1.103375 -0.4423828125 0.9983886718750004 -1.1035 -0.439910888671875 0.9983886718750004 -1.103625 -0.437408447265625 0.9983886718750004 -1.10375 -0.437408447265625 0.9983886718750004 -1.103875 -0.43487548828125 0.9983886718750004 -1.104 -0.43487548828125 0.9983886718750004 -1.104125 -0.43231201171875 0.9983886718750004 -1.10425 -0.429656982421875 0.9983886718750004 -1.104375 -0.429656982421875 0.9983886718750004 -1.1045 -0.426971435546875 0.9983886718750004 -1.104625 -0.426971435546875 0.9983886718750004 -1.10475 -0.42425537109375 0.9983886718750004 -1.104875 -0.421478271484375 0.9983886718750004 -1.105 -0.421478271484375 0.9983886718750004 -1.105125 -0.41864013671875 0.9983886718750004 -1.10525 -0.41864013671875 0.9983886718750004 -1.105375 -0.415771484375 0.9983886718750004 -1.1055 -0.412841796875 0.9983886718750004 -1.105625 -0.412841796875 0.9983886718750004 -1.10575 -0.409881591796875 0.9983886718750004 -1.105875 -0.409881591796875 0.9983886718750004 -1.106 -0.406890869140625 0.9983886718750004 -1.106125 -0.403839111328125 0.9983886718750004 -1.10625 -0.403839111328125 0.9983886718750004 -1.106375 -0.400726318359375 0.9983886718750004 -1.1065 -0.400726318359375 0.9983886718750004 -1.106625 -0.3975830078125 0.9983886718750004 -1.10675 -0.394439697265625 0.9983886718750004 -1.106875 -0.394439697265625 0.9983886718750004 -1.107 -0.391204833984375 0.9983886718750004 -1.107125 -0.391204833984375 0.9983886718750004 -1.10725 -0.387939453125 0.9983886718750004 -1.107375 -0.384613037109375 0.9983886718750004 -1.1075 -0.384613037109375 0.9983886718750004 -1.107625 -0.381256103515625 0.9983886718750004 -1.10775 -0.381256103515625 0.9983886718750004 -1.107875 -0.37786865234375 0.9983886718750004 -1.108 -0.374420166015625 0.9983886718750004 -1.108125 -0.374420166015625 0.9983886718750004 -1.10825 -0.370941162109375 0.9983886718750004 -1.108375 -0.370941162109375 0.9983886718750004 -1.1085 -0.367431640625 0.9983886718750004 -1.108625 -0.3638916015625 0.9983886718750004 -1.10875 -0.3638916015625 0.9983886718750004 -1.108875 -0.36029052734375 0.9983886718750004 -1.109 -0.36029052734375 0.9983886718750004 -1.109125 -0.356658935546875 0.9983886718750004 -1.10925 -0.35296630859375 0.9983886718750004 -1.109375 -0.35296630859375 0.9983886718750004 -1.1095 -0.3492431640625 0.9983886718750004 -1.109625 -0.3492431640625 0.9983886718750004 -1.10975 -0.345489501953125 0.9983886718750004 -1.109875 -0.341705322265625 0.9983886718750004 -1.11 -0.341705322265625 0.9983886718750004 -1.110125 -0.337890625 0.9983886718750004 -1.11025 -0.337890625 0.9983886718750004 -1.110375 -0.334014892578125 0.9983886718750004 -1.1105 -0.330108642578125 0.9983886718750004 -1.110625 -0.330108642578125 0.9983886718750004 -1.11075 -0.326171875 0.9983886718750004 -1.110875 -0.326171875 0.9983886718750004 -1.111 -0.32220458984375 0.9983886718750004 -1.111125 -0.31817626953125 0.9983886718750004 -1.11125 -0.31817626953125 0.9983886718750004 -1.111375 -0.31414794921875 0.9983886718750004 -1.1115 -0.31414794921875 0.9983886718750004 -1.111625 -0.31005859375 0.9983886718750004 -1.11175 -0.305938720703125 0.9983886718750004 -1.111875 -0.305938720703125 0.9983886718750004 -1.112 -0.301788330078125 0.9983886718750004 -1.112125 -0.301788330078125 0.9983886718750004 -1.11225 -0.297607421875 0.9983886718750004 -1.112375 -0.29339599609375 0.9983886718750004 -1.1125 -0.29339599609375 0.9983886718750004 -1.112625 -0.289154052734375 0.9983886718750004 -1.11275 -0.289154052734375 0.9983886718750004 -1.112875 -0.284881591796875 0.9983886718750004 -1.113 -0.28057861328125 0.9983886718750004 -1.113125 -0.28057861328125 0.9983886718750004 -1.11325 -0.2762451171875 0.9983886718750004 -1.113375 -0.2762451171875 0.9983886718750004 -1.1135 -0.271881103515625 0.9983886718750004 -1.113625 -0.267486572265625 0.9983886718750004 -1.11375 -0.267486572265625 0.9983886718750004 -1.113875 -0.263031005859375 0.9983886718750004 -1.114 -0.263031005859375 0.9983886718750004 -1.114125 -0.25860595703125 0.9983886718750004 -1.11425 -0.25408935546875 0.9983886718750004 -1.114375 -0.25408935546875 0.9983886718750004 -1.1145 -0.249603271484375 0.9983886718750004 -1.114625 -0.249603271484375 0.9983886718750004 -1.11475 -0.24505615234375 0.9983886718750004 -1.114875 -0.240478515625 0.9983886718750004 -1.115 -0.240478515625 0.9983886718750004 -1.115125 -0.23590087890625 0.9983886718750004 -1.11525 -0.23590087890625 0.9983886718750004 -1.115375 -0.23126220703125 0.9983886718750004 -1.1155 -0.22662353515625 0.9983886718750004 -1.115625 -0.22662353515625 0.9983886718750004 -1.11575 -0.221954345703125 0.9983886718750004 -1.115875 -0.221954345703125 0.9983886718750004 -1.116 -0.217254638671875 0.9983886718750004 -1.116125 -0.212554931640625 0.9983886718750004 -1.11625 -0.212554931640625 0.9983886718750004 -1.116375 -0.207794189453125 0.9983886718750004 -1.1165 -0.207794189453125 0.9983886718750004 -1.116625 -0.203033447265625 0.9983886718750004 -1.11675 -0.1982421875 0.9983886718750004 -1.116875 -0.1982421875 0.9983886718750004 -1.117 -0.193450927734375 0.9983886718750004 -1.117125 -0.193450927734375 0.9983886718750004 -1.11725 -0.1885986328125 0.9983886718750004 -1.117375 -0.18377685546875 0.9983886718750004 -1.1175 -0.18377685546875 0.9983886718750004 -1.117625 -0.17889404296875 0.9983886718750004 -1.11775 -0.17889404296875 0.9983886718750004 -1.117875 -0.17401123046875 0.9983886718750004 -1.118 -0.169097900390625 0.9983886718750004 -1.118125 -0.169097900390625 0.9983886718750004 -1.11825 -0.164154052734375 0.9983886718750004 -1.118375 -0.164154052734375 0.9983886718750004 -1.1185 -0.159210205078125 0.9983886718750004 -1.118625 -0.154266357421875 0.9983886718750004 -1.11875 -0.154266357421875 0.9983886718750004 -1.118875 -0.149261474609375 0.9983886718750004 -1.119 -0.149261474609375 0.9983886718750004 -1.119125 -0.144287109375 0.9983886718750004 -1.11925 -0.139251708984375 0.9983886718750004 -1.119375 -0.139251708984375 0.9983886718750004 -1.1195 -0.134246826171875 0.9983886718750004 -1.119625 -0.134246826171875 0.9983886718750004 -1.11975 -0.12921142578125 0.9983886718750004 -1.119875 -0.1241455078125 0.9983886718750004 -1.12 -0.11865234375 0.9543457031249984 -1.120125 -0.11383056640625 0.9543457031249984 -1.12025 -0.11383056640625 0.9543457031249984 -1.120375 -0.108978271484375 0.9543457031249984 -1.1205 -0.104095458984375 0.9543457031249984 -1.120625 -0.104095458984375 0.9543457031249984 -1.12075 -0.099212646484375 0.9543457031249984 -1.120875 -0.099212646484375 0.9543457031249984 -1.121 -0.094329833984375 0.9543457031249984 -1.121125 -0.08941650390625 0.9543457031249984 -1.12125 -0.08941650390625 0.9543457031249984 -1.121375 -0.084503173828125 0.9543457031249984 -1.1215 -0.084503173828125 0.9543457031249984 -1.121625 -0.07958984375 0.9543457031249984 -1.12175 -0.07464599609375 0.9543457031249984 -1.121875 -0.07464599609375 0.9543457031249984 -1.122 -0.0697021484375 0.9543457031249984 -1.122125 -0.0697021484375 0.9543457031249984 -1.12225 -0.06475830078125 0.9543457031249984 -1.122375 -0.059814453125 0.9543457031249984 -1.1225 -0.059814453125 0.9543457031249984 -1.122625 -0.054840087890625 0.9543457031249984 -1.12275 -0.054840087890625 0.9543457031249984 -1.122875 -0.049896240234375 0.9543457031249984 -1.123 -0.044921875 0.9543457031249984 -1.123125 -0.044921875 0.9543457031249984 -1.12325 -0.0399169921875 0.9543457031249984 -1.123375 -0.0399169921875 0.9543457031249984 -1.1235 -0.034942626953125 0.9543457031249984 -1.123625 -0.02996826171875 0.9543457031249984 -1.12375 -0.02996826171875 0.9543457031249984 -1.123875 -0.02496337890625 0.9543457031249984 -1.124 -0.02496337890625 0.9543457031249984 -1.124125 -0.019989013671875 0.9543457031249984 -1.12425 -0.014984130859375 0.9543457031249984 -1.124375 -0.014984130859375 0.9543457031249984 -1.1245 -0.010009765625 0.9543457031249984 -1.124625 -0.010009765625 0.9543457031249984 -1.12475 -0.0050048828125 0.9543457031249984 +1.062625 -0.0047607421875 0.9150244140625022 +1.06275 -0.0047607421875 0.9150244140625022 +1.062875 -0.009552001953125 0.9150244140625022 +1.063 -0.01434326171875 0.9150244140625022 +1.063125 -0.01434326171875 0.9150244140625022 +1.06325 -0.019134521484375 0.9150244140625022 +1.063375 -0.019134521484375 0.9150244140625022 +1.0635 -0.02392578125 0.9150244140625022 +1.063625 -0.028717041015625 0.9150244140625022 +1.06375 -0.028717041015625 0.9150244140625022 +1.063875 -0.033477783203125 0.9150244140625022 +1.064 -0.033477783203125 0.9150244140625022 +1.064125 -0.03826904296875 0.9150244140625022 +1.06425 -0.04302978515625 0.9150244140625022 +1.064375 -0.04302978515625 0.9150244140625022 +1.0645 -0.04779052734375 0.9150244140625022 +1.064625 -0.04779052734375 0.9150244140625022 +1.06475 -0.05255126953125 0.9150244140625022 +1.064875 -0.05731201171875 0.9150244140625022 +1.065 -0.05731201171875 0.9150244140625022 +1.065125 -0.06207275390625 0.9150244140625022 +1.06525 -0.06207275390625 0.9150244140625022 +1.065375 -0.066802978515625 0.9150244140625022 +1.0655 -0.071533203125 0.9150244140625022 +1.065625 -0.071533203125 0.9150244140625022 +1.06575 -0.076263427734375 0.9150244140625022 +1.065875 -0.076263427734375 0.9150244140625022 +1.066 -0.08099365234375 0.9150244140625022 +1.066125 -0.085693359375 0.9150244140625022 +1.06625 -0.085693359375 0.9150244140625022 +1.066375 -0.09039306640625 0.9150244140625022 +1.0665 -0.09039306640625 0.9150244140625022 +1.066625 -0.0950927734375 0.9150244140625022 +1.06675 -0.099761962890625 0.9150244140625022 +1.066875 -0.099761962890625 0.9150244140625022 +1.067 -0.104461669921875 0.9150244140625022 +1.067125 -0.104461669921875 0.9150244140625022 +1.06725 -0.109100341796875 0.9150244140625022 +1.067375 -0.113739013671875 0.9150244140625022 +1.0675 -0.113739013671875 0.9150244140625022 +1.067625 -0.118377685546875 0.9150244140625022 +1.06775 -0.118377685546875 0.9150244140625022 +1.067875 -0.123016357421875 0.9150244140625022 +1.068 -0.12762451171875 0.9150244140625022 +1.068125 -0.12762451171875 0.9150244140625022 +1.06825 -0.1322021484375 0.9150244140625022 +1.068375 -0.1322021484375 0.9150244140625022 +1.0685 -0.13677978515625 0.9150244140625022 +1.068625 -0.141357421875 0.9150244140625022 +1.06875 -0.141357421875 0.9150244140625022 +1.068875 -0.145904541015625 0.9150244140625022 +1.069 -0.145904541015625 0.9150244140625022 +1.069125 -0.150421142578125 0.9150244140625022 +1.06925 -0.154937744140625 0.9150244140625022 +1.069375 -0.154937744140625 0.9150244140625022 +1.0695 -0.159454345703125 0.9150244140625022 +1.069625 -0.159454345703125 0.9150244140625022 +1.06975 -0.1639404296875 0.9150244140625022 +1.069875 -0.16839599609375 0.9150244140625022 +1.07 -0.16839599609375 0.9150244140625022 +1.070125 -0.172821044921875 0.9150244140625022 +1.07025 -0.172821044921875 0.9150244140625022 +1.070375 -0.17724609375 0.9150244140625022 +1.0705 -0.181671142578125 0.9150244140625022 +1.070625 -0.181671142578125 0.9150244140625022 +1.07075 -0.186065673828125 0.9150244140625022 +1.070875 -0.186065673828125 0.9150244140625022 +1.071 -0.1904296875 0.9150244140625022 +1.071125 -0.19476318359375 0.9150244140625022 +1.07125 -0.19476318359375 0.9150244140625022 +1.071375 -0.1990966796875 0.9150244140625022 +1.0715 -0.1990966796875 0.9150244140625022 +1.071625 -0.203399658203125 0.9150244140625022 +1.07175 -0.207672119140625 0.9150244140625022 +1.071875 -0.207672119140625 0.9150244140625022 +1.072 -0.2119140625 0.9150244140625022 +1.072125 -0.2119140625 0.9150244140625022 +1.07225 -0.216156005859375 0.9150244140625022 +1.072375 -0.220367431640625 0.9150244140625022 +1.0725 -0.220367431640625 0.9150244140625022 +1.072625 -0.22454833984375 0.9150244140625022 +1.07275 -0.22454833984375 0.9150244140625022 +1.072875 -0.228729248046875 0.9150244140625022 +1.073 -0.23284912109375 0.9150244140625022 +1.073125 -0.23284912109375 0.9150244140625022 +1.07325 -0.236968994140625 0.9150244140625022 +1.073375 -0.236968994140625 0.9150244140625022 +1.0735 -0.241058349609375 0.9150244140625022 +1.073625 -0.2451171875 0.9150244140625022 +1.07375 -0.2451171875 0.9150244140625022 +1.073875 -0.2491455078125 0.9150244140625022 +1.074 -0.2491455078125 0.9150244140625022 +1.074125 -0.253143310546875 0.9150244140625022 +1.07425 -0.257110595703125 0.9150244140625022 +1.074375 -0.257110595703125 0.9150244140625022 +1.0745 -0.261077880859375 0.9150244140625022 +1.074625 -0.261077880859375 0.9150244140625022 +1.07475 -0.264984130859375 0.9150244140625022 +1.074875 -0.268890380859375 0.9150244140625022 +1.075 -0.268890380859375 0.9150244140625022 +1.075125 -0.272735595703125 0.9150244140625022 +1.07525 -0.272735595703125 0.9150244140625022 +1.075375 -0.276580810546875 0.9150244140625022 +1.0755 -0.2803955078125 0.9150244140625022 +1.075625 -0.2803955078125 0.9150244140625022 +1.07575 -0.284149169921875 0.9150244140625022 +1.075875 -0.284149169921875 0.9150244140625022 +1.076 -0.287872314453125 0.9150244140625022 +1.076125 -0.291595458984375 0.9150244140625022 +1.07625 -0.291595458984375 0.9150244140625022 +1.076375 -0.295257568359375 0.9150244140625022 +1.0765 -0.295257568359375 0.9150244140625022 +1.076625 -0.298919677734375 0.9150244140625022 +1.07675 -0.302520751953125 0.9150244140625022 +1.076875 -0.302520751953125 0.9150244140625022 +1.077 -0.30609130859375 0.9150244140625022 +1.077125 -0.30609130859375 0.9150244140625022 +1.07725 -0.30963134765625 0.9150244140625022 +1.077375 -0.313140869140625 0.9150244140625022 +1.0775 -0.313140869140625 0.9150244140625022 +1.077625 -0.316619873046875 0.9150244140625022 +1.07775 -0.316619873046875 0.9150244140625022 +1.077875 -0.320068359375 0.9150244140625022 +1.078 -0.323455810546875 0.9150244140625022 +1.078125 -0.323455810546875 0.9150244140625022 +1.07825 -0.32684326171875 0.9150244140625022 +1.078375 -0.32684326171875 0.9150244140625022 +1.0785 -0.330169677734375 0.9150244140625022 +1.078625 -0.333465576171875 0.9150244140625022 +1.07875 -0.333465576171875 0.9150244140625022 +1.078875 -0.33673095703125 0.9150244140625022 +1.079 -0.33673095703125 0.9150244140625022 +1.079125 -0.3399658203125 0.9150244140625022 +1.07925 -0.3431396484375 0.9150244140625022 +1.079375 -0.3431396484375 0.9150244140625022 +1.0795 -0.346282958984375 0.9150244140625022 +1.079625 -0.346282958984375 0.9150244140625022 +1.07975 -0.349395751953125 0.9150244140625022 +1.079875 -0.35247802734375 0.9150244140625022 +1.08 -0.35247802734375 0.9150244140625022 +1.080125 -0.355499267578125 0.9150244140625022 +1.08025 -0.355499267578125 0.9150244140625022 +1.080375 -0.3585205078125 0.9150244140625022 +1.0805 -0.361480712890625 0.9150244140625022 +1.080625 -0.361480712890625 0.9150244140625022 +1.08075 -0.3643798828125 0.9150244140625022 +1.080875 -0.3643798828125 0.9150244140625022 +1.081 -0.36724853515625 0.9150244140625022 +1.081125 -0.370086669921875 0.9150244140625022 +1.08125 -0.370086669921875 0.9150244140625022 +1.081375 -0.372894287109375 0.9150244140625022 +1.0815 -0.372894287109375 0.9150244140625022 +1.081625 -0.375640869140625 0.9150244140625022 +1.08175 -0.37835693359375 0.9150244140625022 +1.081875 -0.37835693359375 0.9150244140625022 +1.082 -0.38104248046875 0.9150244140625022 +1.082125 -0.38104248046875 0.9150244140625022 +1.08225 -0.3836669921875 0.9150244140625022 +1.082375 -0.386260986328125 0.9150244140625022 +1.0825 -0.386260986328125 0.9150244140625022 +1.082625 -0.3887939453125 0.9150244140625022 +1.08275 -0.3887939453125 0.9150244140625022 +1.082875 -0.39129638671875 0.9150244140625022 +1.083 -0.39373779296875 0.9150244140625022 +1.083125 -0.39373779296875 0.9150244140625022 +1.08325 -0.39617919921875 0.9150244140625022 +1.083375 -0.39617919921875 0.9150244140625022 +1.0835 -0.3985595703125 0.9150244140625022 +1.083625 -0.40087890625 0.9150244140625022 +1.08375 -0.40087890625 0.9150244140625022 +1.083875 -0.403167724609375 0.9150244140625022 +1.084 -0.403167724609375 0.9150244140625022 +1.084125 -0.405426025390625 0.9150244140625022 +1.08425 -0.4075927734375 0.9150244140625022 +1.084375 -0.4075927734375 0.9150244140625022 +1.0845 -0.409759521484375 0.9150244140625022 +1.084625 -0.409759521484375 0.9150244140625022 +1.08475 -0.411865234375 0.9150244140625022 +1.084875 -0.4139404296875 0.9150244140625022 +1.085 -0.4139404296875 0.9150244140625022 +1.085125 -0.415924072265625 0.9150244140625022 +1.08525 -0.415924072265625 0.9150244140625022 +1.085375 -0.41790771484375 0.9150244140625022 +1.0855 -0.41986083984375 0.9150244140625022 +1.085625 -0.41986083984375 0.9150244140625022 +1.08575 -0.421722412109375 0.9150244140625022 +1.085875 -0.421722412109375 0.9150244140625022 +1.086 -0.423553466796875 0.9150244140625022 +1.086125 -0.425323486328125 0.9150244140625022 +1.08625 -0.425323486328125 0.9150244140625022 +1.086375 -0.427093505859375 0.9150244140625022 +1.0865 -0.427093505859375 0.9150244140625022 +1.086625 -0.42877197265625 0.9150244140625022 +1.08675 -0.430419921875 0.9150244140625022 +1.086875 -0.430419921875 0.9150244140625022 +1.087 -0.432037353515625 0.9150244140625022 +1.087125 -0.432037353515625 0.9150244140625022 +1.08725 -0.433563232421875 0.9150244140625022 +1.087375 -0.435089111328125 0.9150244140625022 +1.0875 -0.435089111328125 0.9150244140625022 +1.087625 -0.4365234375 0.9150244140625022 +1.08775 -0.4365234375 0.9150244140625022 +1.087875 -0.43792724609375 0.9150244140625022 +1.088 -0.47930908203125 0.9983886718750004 +1.088125 -0.47930908203125 0.9983886718750004 +1.08825 -0.480743408203125 0.9983886718750004 +1.088375 -0.480743408203125 0.9983886718750004 +1.0885 -0.48211669921875 0.9983886718750004 +1.088625 -0.48345947265625 0.9983886718750004 +1.08875 -0.48345947265625 0.9983886718750004 +1.088875 -0.4847412109375 0.9983886718750004 +1.089 -0.4847412109375 0.9983886718750004 +1.089125 -0.4859619140625 0.9983886718750004 +1.08925 -0.48712158203125 0.9983886718750004 +1.089375 -0.48712158203125 0.9983886718750004 +1.0895 -0.48822021484375 0.9983886718750004 +1.089625 -0.48822021484375 0.9983886718750004 +1.08975 -0.489288330078125 0.9983886718750004 +1.089875 -0.49029541015625 0.9983886718750004 +1.09 -0.49029541015625 0.9983886718750004 +1.090125 -0.491241455078125 0.9983886718750004 +1.09025 -0.491241455078125 0.9983886718750004 +1.090375 -0.492156982421875 0.9983886718750004 +1.0905 -0.49298095703125 0.9983886718750004 +1.090625 -0.49298095703125 0.9983886718750004 +1.09075 -0.4937744140625 0.9983886718750004 +1.090875 -0.4937744140625 0.9983886718750004 +1.091 -0.4945068359375 0.9983886718750004 +1.091125 -0.495208740234375 0.9983886718750004 +1.09125 -0.495208740234375 0.9983886718750004 +1.091375 -0.495819091796875 0.9983886718750004 +1.0915 -0.495819091796875 0.9983886718750004 +1.091625 -0.49639892578125 0.9983886718750004 +1.09175 -0.496917724609375 0.9983886718750004 +1.091875 -0.496917724609375 0.9983886718750004 +1.092 -0.497406005859375 0.9983886718750004 +1.092125 -0.497406005859375 0.9983886718750004 +1.09225 -0.497802734375 0.9983886718750004 +1.092375 -0.4981689453125 0.9983886718750004 +1.0925 -0.4981689453125 0.9983886718750004 +1.092625 -0.49847412109375 0.9983886718750004 +1.09275 -0.49847412109375 0.9983886718750004 +1.092875 -0.49871826171875 0.9983886718750004 +1.093 -0.4989013671875 0.9983886718750004 +1.093125 -0.4989013671875 0.9983886718750004 +1.09325 -0.4990234375 0.9983886718750004 +1.093375 -0.4990234375 0.9983886718750004 +1.0935 -0.499114990234375 0.9983886718750004 +1.093625 -0.4991455078125 0.9983886718750004 +1.09375 -0.4991455078125 0.9983886718750004 +1.093875 -0.499114990234375 0.9983886718750004 +1.094 -0.499114990234375 0.9983886718750004 +1.094125 -0.4990234375 0.9983886718750004 +1.09425 -0.4989013671875 0.9983886718750004 +1.094375 -0.4989013671875 0.9983886718750004 +1.0945 -0.49871826171875 0.9983886718750004 +1.094625 -0.49871826171875 0.9983886718750004 +1.09475 -0.49847412109375 0.9983886718750004 +1.094875 -0.4981689453125 0.9983886718750004 +1.095 -0.4981689453125 0.9983886718750004 +1.095125 -0.497802734375 0.9983886718750004 +1.09525 -0.497802734375 0.9983886718750004 +1.095375 -0.497406005859375 0.9983886718750004 +1.0955 -0.496917724609375 0.9983886718750004 +1.095625 -0.496917724609375 0.9983886718750004 +1.09575 -0.49639892578125 0.9983886718750004 +1.095875 -0.49639892578125 0.9983886718750004 +1.096 -0.495819091796875 0.9983886718750004 +1.096125 -0.495208740234375 0.9983886718750004 +1.09625 -0.495208740234375 0.9983886718750004 +1.096375 -0.4945068359375 0.9983886718750004 +1.0965 -0.4945068359375 0.9983886718750004 +1.096625 -0.4937744140625 0.9983886718750004 +1.09675 -0.49298095703125 0.9983886718750004 +1.096875 -0.49298095703125 0.9983886718750004 +1.097 -0.492156982421875 0.9983886718750004 +1.097125 -0.492156982421875 0.9983886718750004 +1.09725 -0.491241455078125 0.9983886718750004 +1.097375 -0.49029541015625 0.9983886718750004 +1.0975 -0.49029541015625 0.9983886718750004 +1.097625 -0.489288330078125 0.9983886718750004 +1.09775 -0.489288330078125 0.9983886718750004 +1.097875 -0.48822021484375 0.9983886718750004 +1.098 -0.48712158203125 0.9983886718750004 +1.098125 -0.48712158203125 0.9983886718750004 +1.09825 -0.4859619140625 0.9983886718750004 +1.098375 -0.4859619140625 0.9983886718750004 +1.0985 -0.4847412109375 0.9983886718750004 +1.098625 -0.48345947265625 0.9983886718750004 +1.09875 -0.48345947265625 0.9983886718750004 +1.098875 -0.48211669921875 0.9983886718750004 +1.099 -0.48211669921875 0.9983886718750004 +1.099125 -0.480743408203125 0.9983886718750004 +1.09925 -0.47930908203125 0.9983886718750004 +1.099375 -0.47930908203125 0.9983886718750004 +1.0995 -0.47784423828125 0.9983886718750004 +1.099625 -0.47784423828125 0.9983886718750004 +1.09975 -0.476287841796875 0.9983886718750004 +1.099875 -0.474700927734375 0.9983886718750004 +1.1 -0.474700927734375 0.9983886718750004 +1.100125 -0.473052978515625 0.9983886718750004 +1.10025 -0.473052978515625 0.9983886718750004 +1.100375 -0.47137451171875 0.9983886718750004 +1.1005 -0.469635009765625 0.9983886718750004 +1.100625 -0.469635009765625 0.9983886718750004 +1.10075 -0.46783447265625 0.9983886718750004 +1.100875 -0.46783447265625 0.9983886718750004 +1.101 -0.465972900390625 0.9983886718750004 +1.101125 -0.464080810546875 0.9983886718750004 +1.10125 -0.464080810546875 0.9983886718750004 +1.101375 -0.462158203125 0.9983886718750004 +1.1015 -0.462158203125 0.9983886718750004 +1.101625 -0.46014404296875 0.9983886718750004 +1.10175 -0.458099365234375 0.9983886718750004 +1.101875 -0.458099365234375 0.9983886718750004 +1.102 -0.45599365234375 0.9983886718750004 +1.102125 -0.45599365234375 0.9983886718750004 +1.10225 -0.453826904296875 0.9983886718750004 +1.102375 -0.451629638671875 0.9983886718750004 +1.1025 -0.451629638671875 0.9983886718750004 +1.102625 -0.449371337890625 0.9983886718750004 +1.10275 -0.449371337890625 0.9983886718750004 +1.102875 -0.44708251953125 0.9983886718750004 +1.103 -0.444732666015625 0.9983886718750004 +1.103125 -0.444732666015625 0.9983886718750004 +1.10325 -0.442352294921875 0.9983886718750004 +1.103375 -0.442352294921875 0.9983886718750004 +1.1035 -0.43988037109375 0.9983886718750004 +1.103625 -0.4373779296875 0.9983886718750004 +1.10375 -0.4373779296875 0.9983886718750004 +1.103875 -0.434844970703125 0.9983886718750004 +1.104 -0.434844970703125 0.9983886718750004 +1.104125 -0.432281494140625 0.9983886718750004 +1.10425 -0.42962646484375 0.9983886718750004 +1.104375 -0.42962646484375 0.9983886718750004 +1.1045 -0.42694091796875 0.9983886718750004 +1.104625 -0.42694091796875 0.9983886718750004 +1.10475 -0.424224853515625 0.9983886718750004 +1.104875 -0.42144775390625 0.9983886718750004 +1.105 -0.42144775390625 0.9983886718750004 +1.105125 -0.418609619140625 0.9983886718750004 +1.10525 -0.418609619140625 0.9983886718750004 +1.105375 -0.415740966796875 0.9983886718750004 +1.1055 -0.412811279296875 0.9983886718750004 +1.105625 -0.412811279296875 0.9983886718750004 +1.10575 -0.40985107421875 0.9983886718750004 +1.105875 -0.40985107421875 0.9983886718750004 +1.106 -0.4068603515625 0.9983886718750004 +1.106125 -0.40380859375 0.9983886718750004 +1.10625 -0.40380859375 0.9983886718750004 +1.106375 -0.40069580078125 0.9983886718750004 +1.1065 -0.40069580078125 0.9983886718750004 +1.106625 -0.397552490234375 0.9983886718750004 +1.10675 -0.3944091796875 0.9983886718750004 +1.106875 -0.3944091796875 0.9983886718750004 +1.107 -0.39117431640625 0.9983886718750004 +1.107125 -0.39117431640625 0.9983886718750004 +1.10725 -0.387908935546875 0.9983886718750004 +1.107375 -0.38458251953125 0.9983886718750004 +1.1075 -0.38458251953125 0.9983886718750004 +1.107625 -0.3812255859375 0.9983886718750004 +1.10775 -0.3812255859375 0.9983886718750004 +1.107875 -0.377838134765625 0.9983886718750004 +1.108 -0.3743896484375 0.9983886718750004 +1.108125 -0.3743896484375 0.9983886718750004 +1.10825 -0.37091064453125 0.9983886718750004 +1.108375 -0.37091064453125 0.9983886718750004 +1.1085 -0.367401123046875 0.9983886718750004 +1.108625 -0.363861083984375 0.9983886718750004 +1.10875 -0.363861083984375 0.9983886718750004 +1.108875 -0.360260009765625 0.9983886718750004 +1.109 -0.360260009765625 0.9983886718750004 +1.109125 -0.35662841796875 0.9983886718750004 +1.10925 -0.352935791015625 0.9983886718750004 +1.109375 -0.352935791015625 0.9983886718750004 +1.1095 -0.349212646484375 0.9983886718750004 +1.109625 -0.349212646484375 0.9983886718750004 +1.10975 -0.345458984375 0.9983886718750004 +1.109875 -0.3416748046875 0.9983886718750004 +1.11 -0.3416748046875 0.9983886718750004 +1.110125 -0.337860107421875 0.9983886718750004 +1.11025 -0.337860107421875 0.9983886718750004 +1.110375 -0.333984375 0.9983886718750004 +1.1105 -0.330078125 0.9983886718750004 +1.110625 -0.330078125 0.9983886718750004 +1.11075 -0.326141357421875 0.9983886718750004 +1.110875 -0.326141357421875 0.9983886718750004 +1.111 -0.322174072265625 0.9983886718750004 +1.111125 -0.318145751953125 0.9983886718750004 +1.11125 -0.318145751953125 0.9983886718750004 +1.111375 -0.314117431640625 0.9983886718750004 +1.1115 -0.314117431640625 0.9983886718750004 +1.111625 -0.310028076171875 0.9983886718750004 +1.11175 -0.305908203125 0.9983886718750004 +1.111875 -0.305908203125 0.9983886718750004 +1.112 -0.3017578125 0.9983886718750004 +1.112125 -0.3017578125 0.9983886718750004 +1.11225 -0.297576904296875 0.9983886718750004 +1.112375 -0.293365478515625 0.9983886718750004 +1.1125 -0.293365478515625 0.9983886718750004 +1.112625 -0.28912353515625 0.9983886718750004 +1.11275 -0.28912353515625 0.9983886718750004 +1.112875 -0.28485107421875 0.9983886718750004 +1.113 -0.280548095703125 0.9983886718750004 +1.113125 -0.280548095703125 0.9983886718750004 +1.11325 -0.276214599609375 0.9983886718750004 +1.113375 -0.276214599609375 0.9983886718750004 +1.1135 -0.2718505859375 0.9983886718750004 +1.113625 -0.2674560546875 0.9983886718750004 +1.11375 -0.2674560546875 0.9983886718750004 +1.113875 -0.26300048828125 0.9983886718750004 +1.114 -0.26300048828125 0.9983886718750004 +1.114125 -0.258575439453125 0.9983886718750004 +1.11425 -0.254058837890625 0.9983886718750004 +1.114375 -0.254058837890625 0.9983886718750004 +1.1145 -0.24957275390625 0.9983886718750004 +1.114625 -0.24957275390625 0.9983886718750004 +1.11475 -0.245025634765625 0.9983886718750004 +1.114875 -0.240447998046875 0.9983886718750004 +1.115 -0.240447998046875 0.9983886718750004 +1.115125 -0.235870361328125 0.9983886718750004 +1.11525 -0.235870361328125 0.9983886718750004 +1.115375 -0.231231689453125 0.9983886718750004 +1.1155 -0.226593017578125 0.9983886718750004 +1.115625 -0.226593017578125 0.9983886718750004 +1.11575 -0.221923828125 0.9983886718750004 +1.115875 -0.221923828125 0.9983886718750004 +1.116 -0.21722412109375 0.9983886718750004 +1.116125 -0.2125244140625 0.9983886718750004 +1.11625 -0.2125244140625 0.9983886718750004 +1.116375 -0.207763671875 0.9983886718750004 +1.1165 -0.207763671875 0.9983886718750004 +1.116625 -0.2030029296875 0.9983886718750004 +1.11675 -0.198211669921875 0.9983886718750004 +1.116875 -0.198211669921875 0.9983886718750004 +1.117 -0.19342041015625 0.9983886718750004 +1.117125 -0.19342041015625 0.9983886718750004 +1.11725 -0.188568115234375 0.9983886718750004 +1.117375 -0.183746337890625 0.9983886718750004 +1.1175 -0.183746337890625 0.9983886718750004 +1.117625 -0.178863525390625 0.9983886718750004 +1.11775 -0.178863525390625 0.9983886718750004 +1.117875 -0.173980712890625 0.9983886718750004 +1.118 -0.1690673828125 0.9983886718750004 +1.118125 -0.1690673828125 0.9983886718750004 +1.11825 -0.16412353515625 0.9983886718750004 +1.118375 -0.16412353515625 0.9983886718750004 +1.1185 -0.1591796875 0.9983886718750004 +1.118625 -0.15423583984375 0.9983886718750004 +1.11875 -0.15423583984375 0.9983886718750004 +1.118875 -0.14923095703125 0.9983886718750004 +1.119 -0.14923095703125 0.9983886718750004 +1.119125 -0.144256591796875 0.9983886718750004 +1.11925 -0.13922119140625 0.9983886718750004 +1.119375 -0.13922119140625 0.9983886718750004 +1.1195 -0.13421630859375 0.9983886718750004 +1.119625 -0.13421630859375 0.9983886718750004 +1.11975 -0.129180908203125 0.9983886718750004 +1.119875 -0.124114990234375 0.9983886718750004 +1.12 -0.118621826171875 0.9543457031249984 +1.120125 -0.113800048828125 0.9543457031249984 +1.12025 -0.113800048828125 0.9543457031249984 +1.120375 -0.10894775390625 0.9543457031249984 +1.1205 -0.10406494140625 0.9543457031249984 +1.120625 -0.10406494140625 0.9543457031249984 +1.12075 -0.09918212890625 0.9543457031249984 +1.120875 -0.09918212890625 0.9543457031249984 +1.121 -0.09429931640625 0.9543457031249984 +1.121125 -0.089385986328125 0.9543457031249984 +1.12125 -0.089385986328125 0.9543457031249984 +1.121375 -0.08447265625 0.9543457031249984 +1.1215 -0.08447265625 0.9543457031249984 +1.121625 -0.079559326171875 0.9543457031249984 +1.12175 -0.074615478515625 0.9543457031249984 +1.121875 -0.074615478515625 0.9543457031249984 +1.122 -0.069671630859375 0.9543457031249984 +1.122125 -0.069671630859375 0.9543457031249984 +1.12225 -0.064727783203125 0.9543457031249984 +1.122375 -0.059783935546875 0.9543457031249984 +1.1225 -0.059783935546875 0.9543457031249984 +1.122625 -0.0548095703125 0.9543457031249984 +1.12275 -0.0548095703125 0.9543457031249984 +1.122875 -0.04986572265625 0.9543457031249984 +1.123 -0.044891357421875 0.9543457031249984 +1.123125 -0.044891357421875 0.9543457031249984 +1.12325 -0.039886474609375 0.9543457031249984 +1.123375 -0.039886474609375 0.9543457031249984 +1.1235 -0.034912109375 0.9543457031249984 +1.123625 -0.029937744140625 0.9543457031249984 +1.12375 -0.029937744140625 0.9543457031249984 +1.123875 -0.024932861328125 0.9543457031249984 +1.124 -0.024932861328125 0.9543457031249984 +1.124125 -0.01995849609375 0.9543457031249984 +1.12425 -0.01495361328125 0.9543457031249984 +1.124375 -0.01495361328125 0.9543457031249984 +1.1245 -0.009979248046875 0.9543457031249984 +1.124625 -0.009979248046875 0.9543457031249984 +1.12475 -0.004974365234375 0.9543457031249984 1.124875 0.0 0.9543457031249984 1.125 0.0 0.9543457031249984 1.125125 0.004974365234375 0.9543457031249984 @@ -9499,489 +9499,489 @@ 1.18725 0.002777099609375 0.5314794921874958 1.187375 0.0 0.5314794921874958 1.1875 0.0 0.5314794921874958 -1.187625 -0.0028076171875 0.5314794921874958 -1.18775 -0.0028076171875 0.5314794921874958 -1.187875 -0.005584716796875 0.5314794921874958 -1.188 -0.00836181640625 0.5314794921874958 -1.188125 -0.00836181640625 0.5314794921874958 -1.18825 -0.011138916015625 0.5314794921874958 -1.188375 -0.011138916015625 0.5314794921874958 -1.1885 -0.013916015625 0.5314794921874958 -1.188625 -0.016693115234375 0.5314794921874958 -1.18875 -0.016693115234375 0.5314794921874958 -1.188875 -0.01947021484375 0.5314794921874958 -1.189 -0.01947021484375 0.5314794921874958 -1.189125 -0.022247314453125 0.5314794921874958 -1.18925 -0.0250244140625 0.5314794921874958 -1.189375 -0.0250244140625 0.5314794921874958 -1.1895 -0.027801513671875 0.5314794921874958 -1.189625 -0.027801513671875 0.5314794921874958 -1.18975 -0.030548095703125 0.5314794921874958 -1.189875 -0.0333251953125 0.5314794921874958 -1.19 -0.0333251953125 0.5314794921874958 -1.190125 -0.03607177734375 0.5314794921874958 -1.19025 -0.03607177734375 0.5314794921874958 -1.190375 -0.038818359375 0.5314794921874958 -1.1905 -0.04156494140625 0.5314794921874958 -1.190625 -0.04156494140625 0.5314794921874958 -1.19075 -0.0443115234375 0.5314794921874958 -1.190875 -0.0443115234375 0.5314794921874958 -1.191 -0.04705810546875 0.5314794921874958 -1.191125 -0.0498046875 0.5314794921874958 -1.19125 -0.0498046875 0.5314794921874958 -1.191375 -0.052520751953125 0.5314794921874958 -1.1915 -0.052520751953125 0.5314794921874958 -1.191625 -0.055267333984375 0.5314794921874958 -1.19175 -0.0579833984375 0.5314794921874958 -1.191875 -0.0579833984375 0.5314794921874958 -1.192 -0.060699462890625 0.5314794921874958 -1.192125 -0.060699462890625 0.5314794921874958 -1.19225 -0.063385009765625 0.5314794921874958 -1.192375 -0.06610107421875 0.5314794921874958 -1.1925 -0.06610107421875 0.5314794921874958 -1.192625 -0.06878662109375 0.5314794921874958 -1.19275 -0.06878662109375 0.5314794921874958 -1.192875 -0.07147216796875 0.5314794921874958 -1.193 -0.07415771484375 0.5314794921874958 -1.193125 -0.07415771484375 0.5314794921874958 -1.19325 -0.076812744140625 0.5314794921874958 -1.193375 -0.076812744140625 0.5314794921874958 -1.1935 -0.0794677734375 0.5314794921874958 -1.193625 -0.082122802734375 0.5314794921874958 -1.19375 -0.082122802734375 0.5314794921874958 -1.193875 -0.08477783203125 0.5314794921874958 -1.194 -0.08477783203125 0.5314794921874958 -1.194125 -0.08740234375 0.5314794921874958 -1.19425 -0.09002685546875 0.5314794921874958 -1.194375 -0.09002685546875 0.5314794921874958 -1.1945 -0.092620849609375 0.5314794921874958 -1.194625 -0.092620849609375 0.5314794921874958 -1.19475 -0.095245361328125 0.5314794921874958 -1.194875 -0.09783935546875 0.5314794921874958 -1.195 -0.09783935546875 0.5314794921874958 -1.195125 -0.10040283203125 0.5314794921874958 -1.19525 -0.10040283203125 0.5314794921874958 -1.195375 -0.10296630859375 0.5314794921874958 -1.1955 -0.10552978515625 0.5314794921874958 -1.195625 -0.10552978515625 0.5314794921874958 -1.19575 -0.10809326171875 0.5314794921874958 -1.195875 -0.10809326171875 0.5314794921874958 -1.196 -0.110626220703125 0.5314794921874958 -1.196125 -0.1131591796875 0.5314794921874958 -1.19625 -0.1131591796875 0.5314794921874958 -1.196375 -0.11566162109375 0.5314794921874958 -1.1965 -0.11566162109375 0.5314794921874958 -1.196625 -0.1181640625 0.5314794921874958 -1.19675 -0.120635986328125 0.5314794921874958 -1.196875 -0.120635986328125 0.5314794921874958 -1.197 -0.12310791015625 0.5314794921874958 -1.197125 -0.12310791015625 0.5314794921874958 -1.19725 -0.125579833984375 0.5314794921874958 -1.197375 -0.128021240234375 0.5314794921874958 -1.1975 -0.128021240234375 0.5314794921874958 -1.197625 -0.130462646484375 0.5314794921874958 -1.19775 -0.130462646484375 0.5314794921874958 -1.197875 -0.13287353515625 0.5314794921874958 -1.198 -0.135284423828125 0.5314794921874958 -1.198125 -0.135284423828125 0.5314794921874958 -1.19825 -0.137664794921875 0.5314794921874958 -1.198375 -0.137664794921875 0.5314794921874958 -1.1985 -0.140045166015625 0.5314794921874958 -1.198625 -0.14239501953125 0.5314794921874958 -1.19875 -0.14239501953125 0.5314794921874958 -1.198875 -0.144744873046875 0.5314794921874958 -1.199 -0.144744873046875 0.5314794921874958 -1.199125 -0.147064208984375 0.5314794921874958 -1.19925 -0.14935302734375 0.5314794921874958 -1.199375 -0.14935302734375 0.5314794921874958 -1.1995 -0.15167236328125 0.5314794921874958 -1.199625 -0.15167236328125 0.5314794921874958 -1.19975 -0.1539306640625 0.5314794921874958 -1.199875 -0.15618896484375 0.5314794921874958 -1.2 -0.15618896484375 0.5314794921874958 -1.200125 -0.158447265625 0.5314794921874958 -1.20025 -0.158447265625 0.5314794921874958 -1.200375 -0.160675048828125 0.5314794921874958 -1.2005 -0.162872314453125 0.5314794921874958 -1.200625 -0.162872314453125 0.5314794921874958 -1.20075 -0.165069580078125 0.5314794921874958 -1.200875 -0.165069580078125 0.5314794921874958 -1.201 -0.167236328125 0.5314794921874958 -1.201125 -0.169403076171875 0.5314794921874958 -1.20125 -0.169403076171875 0.5314794921874958 -1.201375 -0.1715087890625 0.5314794921874958 -1.2015 -0.1715087890625 0.5314794921874958 -1.201625 -0.17364501953125 0.5314794921874958 -1.20175 -0.175750732421875 0.5314794921874958 -1.201875 -0.175750732421875 0.5314794921874958 -1.202 -0.177825927734375 0.5314794921874958 -1.202125 -0.177825927734375 0.5314794921874958 -1.20225 -0.17987060546875 0.5314794921874958 -1.202375 -0.181915283203125 0.5314794921874958 -1.2025 -0.181915283203125 0.5314794921874958 -1.202625 -0.183929443359375 0.5314794921874958 -1.20275 -0.183929443359375 0.5314794921874958 -1.202875 -0.1859130859375 0.5314794921874958 -1.203 -0.187896728515625 0.5314794921874958 -1.203125 -0.187896728515625 0.5314794921874958 -1.20325 -0.18988037109375 0.5314794921874958 -1.203375 -0.18988037109375 0.5314794921874958 -1.2035 -0.191802978515625 0.5314794921874958 -1.203625 -0.1937255859375 0.5314794921874958 -1.20375 -0.1937255859375 0.5314794921874958 -1.203875 -0.19561767578125 0.5314794921874958 -1.204 -0.19561767578125 0.5314794921874958 -1.204125 -0.197479248046875 0.5314794921874958 -1.20425 -0.1993408203125 0.5314794921874958 -1.204375 -0.1993408203125 0.5314794921874958 -1.2045 -0.201171875 0.5314794921874958 -1.204625 -0.201171875 0.5314794921874958 -1.20475 -0.202972412109375 0.5314794921874958 -1.204875 -0.204742431640625 0.5314794921874958 -1.205 -0.204742431640625 0.5314794921874958 -1.205125 -0.206512451171875 0.5314794921874958 -1.20525 -0.206512451171875 0.5314794921874958 -1.205375 -0.208251953125 0.5314794921874958 -1.2055 -0.209991455078125 0.5314794921874958 -1.205625 -0.209991455078125 0.5314794921874958 -1.20575 -0.211669921875 0.5314794921874958 -1.205875 -0.211669921875 0.5314794921874958 -1.206 -0.213348388671875 0.5314794921874958 -1.206125 -0.214996337890625 0.5314794921874958 -1.20625 -0.214996337890625 0.5314794921874958 -1.206375 -0.21661376953125 0.5314794921874958 -1.2065 -0.21661376953125 0.5314794921874958 -1.206625 -0.21820068359375 0.5314794921874958 -1.20675 -0.21978759765625 0.5314794921874958 -1.206875 -0.21978759765625 0.5314794921874958 -1.207 -0.221343994140625 0.5314794921874958 -1.207125 -0.221343994140625 0.5314794921874958 -1.20725 -0.222869873046875 0.5314794921874958 -1.207375 -0.224365234375 0.5314794921874958 -1.2075 -0.224365234375 0.5314794921874958 -1.207625 -0.225860595703125 0.5314794921874958 -1.20775 -0.225860595703125 0.5314794921874958 -1.207875 -0.227294921875 0.5314794921874958 -1.208 -0.228729248046875 0.5314794921874958 -1.208125 -0.228729248046875 0.5314794921874958 -1.20825 -0.230133056640625 0.5314794921874958 -1.208375 -0.230133056640625 0.5314794921874958 -1.2085 -0.23150634765625 0.5314794921874958 -1.208625 -0.23284912109375 0.5314794921874958 -1.20875 -0.23284912109375 0.5314794921874958 -1.208875 -0.23419189453125 0.5314794921874958 -1.209 -0.23419189453125 0.5314794921874958 -1.209125 -0.235504150390625 0.5314794921874958 -1.20925 -0.236785888671875 0.5314794921874958 -1.209375 -0.236785888671875 0.5314794921874958 -1.2095 -0.238006591796875 0.5314794921874958 -1.209625 -0.238006591796875 0.5314794921874958 -1.20975 -0.2392578125 0.5314794921874958 -1.209875 -0.240447998046875 0.5314794921874958 -1.21 -0.240447998046875 0.5314794921874958 -1.210125 -0.241607666015625 0.5314794921874958 -1.21025 -0.241607666015625 0.5314794921874958 -1.210375 -0.242767333984375 0.5314794921874958 -1.2105 -0.243896484375 0.5314794921874958 -1.210625 -0.243896484375 0.5314794921874958 -1.21075 -0.244964599609375 0.5314794921874958 -1.210875 -0.244964599609375 0.5314794921874958 -1.211 -0.24603271484375 0.5314794921874958 -1.211125 -0.2470703125 0.5314794921874958 -1.21125 -0.2470703125 0.5314794921874958 -1.211375 -0.248077392578125 0.5314794921874958 -1.2115 -0.248077392578125 0.5314794921874958 -1.211625 -0.249053955078125 0.5314794921874958 -1.21175 -0.250030517578125 0.5314794921874958 -1.211875 -0.250030517578125 0.5314794921874958 -1.212 -0.250946044921875 0.5314794921874958 -1.212125 -0.250946044921875 0.5314794921874958 -1.21225 -0.251861572265625 0.5314794921874958 -1.212375 -0.25274658203125 0.5314794921874958 -1.2125 -0.25274658203125 0.5314794921874958 -1.212625 -0.253570556640625 0.5314794921874958 -1.21275 -0.253570556640625 0.5314794921874958 -1.212875 -0.25439453125 0.5314794921874958 -1.213 -0.25518798828125 0.5314794921874958 -1.213125 -0.25518798828125 0.5314794921874958 -1.21325 -0.255950927734375 0.5314794921874958 -1.213375 -0.255950927734375 0.5314794921874958 -1.2135 -0.256683349609375 0.5314794921874958 -1.213625 -0.25738525390625 0.5314794921874958 -1.21375 -0.25738525390625 0.5314794921874958 -1.213875 -0.258056640625 0.5314794921874958 -1.214 -0.258056640625 0.5314794921874958 -1.214125 -0.25872802734375 0.5314794921874958 -1.21425 -0.25933837890625 0.5314794921874958 -1.214375 -0.25933837890625 0.5314794921874958 -1.2145 -0.259918212890625 0.5314794921874958 -1.214625 -0.259918212890625 0.5314794921874958 -1.21475 -0.260498046875 0.5314794921874958 -1.214875 -0.261016845703125 0.5314794921874958 -1.215 -0.261016845703125 0.5314794921874958 -1.215125 -0.26153564453125 0.5314794921874958 -1.21525 -0.26153564453125 0.5314794921874958 -1.215375 -0.26202392578125 0.5314794921874958 -1.2155 -0.262451171875 0.5314794921874958 -1.215625 -0.262451171875 0.5314794921874958 -1.21575 -0.26287841796875 0.5314794921874958 -1.215875 -0.26287841796875 0.5314794921874958 -1.216 -0.1090087890625 0.220097656249995 -1.216125 -0.109161376953125 0.220097656249995 -1.21625 -0.109161376953125 0.220097656249995 -1.216375 -0.10931396484375 0.220097656249995 -1.2165 -0.10931396484375 0.220097656249995 -1.216625 -0.10943603515625 0.220097656249995 -1.21675 -0.10955810546875 0.220097656249995 -1.216875 -0.10955810546875 0.220097656249995 -1.217 -0.109649658203125 0.220097656249995 -1.217125 -0.109649658203125 0.220097656249995 -1.21725 -0.1097412109375 0.220097656249995 -1.217375 -0.109832763671875 0.220097656249995 -1.2175 -0.109832763671875 0.220097656249995 -1.217625 -0.109893798828125 0.220097656249995 -1.21775 -0.109893798828125 0.220097656249995 -1.217875 -0.109954833984375 0.220097656249995 -1.218 -0.1099853515625 0.220097656249995 -1.218125 -0.1099853515625 0.220097656249995 -1.21825 -0.110015869140625 0.220097656249995 -1.218375 -0.110015869140625 0.220097656249995 -1.2185 -0.11004638671875 0.220097656249995 -1.218625 -0.11004638671875 0.220097656249995 -1.21875 -0.11004638671875 0.220097656249995 -1.218875 -0.11004638671875 0.220097656249995 -1.219 -0.11004638671875 0.220097656249995 -1.219125 -0.110015869140625 0.220097656249995 -1.21925 -0.1099853515625 0.220097656249995 -1.219375 -0.1099853515625 0.220097656249995 -1.2195 -0.109954833984375 0.220097656249995 -1.219625 -0.109954833984375 0.220097656249995 -1.21975 -0.109893798828125 0.220097656249995 -1.219875 -0.109832763671875 0.220097656249995 -1.22 -0.109832763671875 0.220097656249995 -1.220125 -0.1097412109375 0.220097656249995 -1.22025 -0.1097412109375 0.220097656249995 -1.220375 -0.109649658203125 0.220097656249995 -1.2205 -0.10955810546875 0.220097656249995 -1.220625 -0.10955810546875 0.220097656249995 -1.22075 -0.10943603515625 0.220097656249995 -1.220875 -0.10943603515625 0.220097656249995 -1.221 -0.10931396484375 0.220097656249995 -1.221125 -0.109161376953125 0.220097656249995 -1.22125 -0.109161376953125 0.220097656249995 -1.221375 -0.1090087890625 0.220097656249995 -1.2215 -0.1090087890625 0.220097656249995 -1.221625 -0.108856201171875 0.220097656249995 -1.22175 -0.108673095703125 0.220097656249995 -1.221875 -0.108673095703125 0.220097656249995 -1.222 -0.108489990234375 0.220097656249995 -1.222125 -0.108489990234375 0.220097656249995 -1.22225 -0.108306884765625 0.220097656249995 -1.222375 -0.10809326171875 0.220097656249995 -1.2225 -0.10809326171875 0.220097656249995 -1.222625 -0.107879638671875 0.220097656249995 -1.22275 -0.107879638671875 0.220097656249995 -1.222875 -0.107635498046875 0.220097656249995 -1.223 -0.107391357421875 0.220097656249995 -1.223125 -0.107391357421875 0.220097656249995 -1.22325 -0.107147216796875 0.220097656249995 -1.223375 -0.107147216796875 0.220097656249995 -1.2235 -0.10687255859375 0.220097656249995 -1.223625 -0.106597900390625 0.220097656249995 -1.22375 -0.106597900390625 0.220097656249995 -1.223875 -0.106292724609375 0.220097656249995 -1.224 -0.106292724609375 0.220097656249995 -1.224125 -0.105987548828125 0.220097656249995 -1.22425 -0.105682373046875 0.220097656249995 -1.224375 -0.105682373046875 0.220097656249995 -1.2245 -0.1053466796875 0.220097656249995 -1.224625 -0.1053466796875 0.220097656249995 -1.22475 -0.105010986328125 0.220097656249995 -1.224875 -0.104644775390625 0.220097656249995 -1.225 -0.104644775390625 0.220097656249995 -1.225125 -0.10430908203125 0.220097656249995 -1.22525 -0.10430908203125 0.220097656249995 -1.225375 -0.103912353515625 0.220097656249995 -1.2255 -0.103546142578125 0.220097656249995 -1.225625 -0.103546142578125 0.220097656249995 -1.22575 -0.1031494140625 0.220097656249995 -1.225875 -0.1031494140625 0.220097656249995 -1.226 -0.10272216796875 0.220097656249995 -1.226125 -0.102325439453125 0.220097656249995 -1.22625 -0.102325439453125 0.220097656249995 -1.226375 -0.101898193359375 0.220097656249995 -1.2265 -0.101898193359375 0.220097656249995 -1.226625 -0.1014404296875 0.220097656249995 -1.22675 -0.100982666015625 0.220097656249995 -1.226875 -0.100982666015625 0.220097656249995 -1.227 -0.10052490234375 0.220097656249995 -1.227125 -0.10052490234375 0.220097656249995 -1.22725 -0.100067138671875 0.220097656249995 -1.227375 -0.099578857421875 0.220097656249995 -1.2275 -0.099578857421875 0.220097656249995 -1.227625 -0.09906005859375 0.220097656249995 -1.22775 -0.09906005859375 0.220097656249995 -1.227875 -0.09857177734375 0.220097656249995 -1.228 -0.098052978515625 0.220097656249995 -1.228125 -0.098052978515625 0.220097656249995 -1.22825 -0.0975341796875 0.220097656249995 -1.228375 -0.0975341796875 0.220097656249995 -1.2285 -0.09698486328125 0.220097656249995 -1.228625 -0.096435546875 0.220097656249995 -1.22875 -0.096435546875 0.220097656249995 -1.228875 -0.09588623046875 0.220097656249995 -1.229 -0.09588623046875 0.220097656249995 -1.229125 -0.095306396484375 0.220097656249995 -1.22925 -0.0947265625 0.220097656249995 -1.229375 -0.0947265625 0.220097656249995 -1.2295 -0.0941162109375 0.220097656249995 -1.229625 -0.0941162109375 0.220097656249995 -1.22975 -0.093536376953125 0.220097656249995 -1.229875 -0.092926025390625 0.220097656249995 -1.23 -0.092926025390625 0.220097656249995 -1.230125 -0.09228515625 0.220097656249995 -1.23025 -0.09228515625 0.220097656249995 -1.230375 -0.091644287109375 0.220097656249995 -1.2305 -0.09100341796875 0.220097656249995 -1.230625 -0.09100341796875 0.220097656249995 -1.23075 -0.090362548828125 0.220097656249995 -1.230875 -0.090362548828125 0.220097656249995 -1.231 -0.089691162109375 0.220097656249995 -1.231125 -0.089019775390625 0.220097656249995 -1.23125 -0.089019775390625 0.220097656249995 -1.231375 -0.088348388671875 0.220097656249995 -1.2315 -0.088348388671875 0.220097656249995 -1.231625 -0.087646484375 0.220097656249995 -1.23175 -0.086944580078125 0.220097656249995 -1.231875 -0.086944580078125 0.220097656249995 -1.232 -0.08624267578125 0.220097656249995 -1.232125 -0.08624267578125 0.220097656249995 -1.23225 -0.08551025390625 0.220097656249995 -1.232375 -0.08477783203125 0.220097656249995 -1.2325 -0.08477783203125 0.220097656249995 -1.232625 -0.08404541015625 0.220097656249995 -1.23275 -0.08404541015625 0.220097656249995 -1.232875 -0.08331298828125 0.220097656249995 -1.233 -0.082550048828125 0.220097656249995 -1.233125 -0.082550048828125 0.220097656249995 -1.23325 -0.081787109375 0.220097656249995 -1.233375 -0.081787109375 0.220097656249995 -1.2335 -0.08099365234375 0.220097656249995 -1.233625 -0.080230712890625 0.220097656249995 -1.23375 -0.080230712890625 0.220097656249995 -1.233875 -0.079437255859375 0.220097656249995 -1.234 -0.079437255859375 0.220097656249995 -1.234125 -0.07861328125 0.220097656249995 -1.23425 -0.07781982421875 0.220097656249995 -1.234375 -0.07781982421875 0.220097656249995 -1.2345 -0.076995849609375 0.220097656249995 -1.234625 -0.076995849609375 0.220097656249995 -1.23475 -0.076171875 0.220097656249995 -1.234875 -0.0753173828125 0.220097656249995 -1.235 -0.0753173828125 0.220097656249995 -1.235125 -0.074493408203125 0.220097656249995 -1.23525 -0.074493408203125 0.220097656249995 -1.235375 -0.073638916015625 0.220097656249995 -1.2355 -0.072784423828125 0.220097656249995 -1.235625 -0.072784423828125 0.220097656249995 -1.23575 -0.0718994140625 0.220097656249995 -1.235875 -0.0718994140625 0.220097656249995 -1.236 -0.071044921875 0.220097656249995 -1.236125 -0.070159912109375 0.220097656249995 -1.23625 -0.070159912109375 0.220097656249995 -1.236375 -0.069244384765625 0.220097656249995 -1.2365 -0.069244384765625 0.220097656249995 -1.236625 -0.068359375 0.220097656249995 -1.23675 -0.06744384765625 0.220097656249995 -1.236875 -0.06744384765625 0.220097656249995 -1.237 -0.0665283203125 0.220097656249995 -1.237125 -0.0665283203125 0.220097656249995 -1.23725 -0.06561279296875 0.220097656249995 -1.237375 -0.064697265625 0.220097656249995 -1.2375 -0.064697265625 0.220097656249995 -1.237625 -0.063751220703125 0.220097656249995 -1.23775 -0.063751220703125 0.220097656249995 -1.237875 -0.06280517578125 0.220097656249995 -1.238 -0.061859130859375 0.220097656249995 -1.238125 -0.061859130859375 0.220097656249995 -1.23825 -0.0609130859375 0.220097656249995 -1.238375 -0.0609130859375 0.220097656249995 -1.2385 -0.0599365234375 0.220097656249995 -1.238625 -0.0589599609375 0.220097656249995 -1.23875 -0.0589599609375 0.220097656249995 -1.238875 -0.0579833984375 0.220097656249995 -1.239 -0.0579833984375 0.220097656249995 -1.239125 -0.0570068359375 0.220097656249995 -1.23925 -0.0560302734375 0.220097656249995 -1.239375 -0.0560302734375 0.220097656249995 -1.2395 -0.055023193359375 0.220097656249995 -1.239625 -0.055023193359375 0.220097656249995 -1.23975 -0.05401611328125 0.220097656249995 -1.239875 -0.053009033203125 0.220097656249995 -1.24 -0.053009033203125 0.220097656249995 -1.240125 -0.052001953125 0.220097656249995 -1.24025 -0.052001953125 0.220097656249995 -1.240375 -0.050994873046875 0.220097656249995 -1.2405 -0.049957275390625 0.220097656249995 -1.240625 -0.049957275390625 0.220097656249995 -1.24075 -0.0489501953125 0.220097656249995 -1.240875 -0.0489501953125 0.220097656249995 -1.241 -0.04791259765625 0.220097656249995 -1.241125 -0.046875 0.220097656249995 -1.24125 -0.046875 0.220097656249995 -1.241375 -0.045806884765625 0.220097656249995 -1.2415 -0.045806884765625 0.220097656249995 -1.241625 -0.044769287109375 0.220097656249995 -1.24175 -0.043701171875 0.220097656249995 -1.241875 -0.043701171875 0.220097656249995 -1.242 -0.04266357421875 0.220097656249995 -1.242125 -0.04266357421875 0.220097656249995 -1.24225 -0.041595458984375 0.220097656249995 -1.242375 -0.04052734375 0.220097656249995 -1.2425 -0.04052734375 0.220097656249995 -1.242625 -0.0394287109375 0.220097656249995 -1.24275 -0.0394287109375 0.220097656249995 -1.242875 -0.038360595703125 0.220097656249995 -1.243 -0.03729248046875 0.220097656249995 -1.243125 -0.03729248046875 0.220097656249995 -1.24325 -0.03619384765625 0.220097656249995 -1.243375 -0.03619384765625 0.220097656249995 -1.2435 -0.03509521484375 0.220097656249995 -1.243625 -0.034027099609375 0.220097656249995 -1.24375 -0.034027099609375 0.220097656249995 -1.243875 -0.032928466796875 0.220097656249995 -1.244 -0.032928466796875 0.220097656249995 -1.244125 -0.03179931640625 0.220097656249995 -1.24425 -0.03070068359375 0.220097656249995 -1.244375 -0.03070068359375 0.220097656249995 -1.2445 -0.02960205078125 0.220097656249995 -1.244625 -0.02960205078125 0.220097656249995 -1.24475 -0.02850341796875 0.220097656249995 -1.244875 -0.027374267578125 0.220097656249995 -1.245 -0.027374267578125 0.220097656249995 -1.245125 -0.026275634765625 0.220097656249995 -1.24525 -0.026275634765625 0.220097656249995 -1.245375 -0.025146484375 0.220097656249995 -1.2455 -0.024017333984375 0.220097656249995 -1.245625 -0.024017333984375 0.220097656249995 -1.24575 -0.02288818359375 0.220097656249995 -1.245875 -0.02288818359375 0.220097656249995 -1.246 -0.021759033203125 0.220097656249995 -1.246125 -0.0206298828125 0.220097656249995 -1.24625 -0.0206298828125 0.220097656249995 -1.246375 -0.019500732421875 0.220097656249995 -1.2465 -0.019500732421875 0.220097656249995 -1.246625 -0.01837158203125 0.220097656249995 -1.24675 -0.0172119140625 0.220097656249995 -1.246875 -0.0172119140625 0.220097656249995 -1.247 -0.016082763671875 0.220097656249995 -1.247125 -0.016082763671875 0.220097656249995 -1.24725 -0.01495361328125 0.220097656249995 -1.247375 -0.0137939453125 0.220097656249995 -1.2475 -0.0137939453125 0.220097656249995 -1.247625 -0.012664794921875 0.220097656249995 -1.24775 -0.012664794921875 0.220097656249995 -1.247875 -0.011505126953125 0.220097656249995 +1.187625 -0.002777099609375 0.5314794921874958 +1.18775 -0.002777099609375 0.5314794921874958 +1.187875 -0.00555419921875 0.5314794921874958 +1.188 -0.008331298828125 0.5314794921874958 +1.188125 -0.008331298828125 0.5314794921874958 +1.18825 -0.0111083984375 0.5314794921874958 +1.188375 -0.0111083984375 0.5314794921874958 +1.1885 -0.013885498046875 0.5314794921874958 +1.188625 -0.01666259765625 0.5314794921874958 +1.18875 -0.01666259765625 0.5314794921874958 +1.188875 -0.019439697265625 0.5314794921874958 +1.189 -0.019439697265625 0.5314794921874958 +1.189125 -0.022216796875 0.5314794921874958 +1.18925 -0.024993896484375 0.5314794921874958 +1.189375 -0.024993896484375 0.5314794921874958 +1.1895 -0.02777099609375 0.5314794921874958 +1.189625 -0.02777099609375 0.5314794921874958 +1.18975 -0.030517578125 0.5314794921874958 +1.189875 -0.033294677734375 0.5314794921874958 +1.19 -0.033294677734375 0.5314794921874958 +1.190125 -0.036041259765625 0.5314794921874958 +1.19025 -0.036041259765625 0.5314794921874958 +1.190375 -0.038787841796875 0.5314794921874958 +1.1905 -0.041534423828125 0.5314794921874958 +1.190625 -0.041534423828125 0.5314794921874958 +1.19075 -0.044281005859375 0.5314794921874958 +1.190875 -0.044281005859375 0.5314794921874958 +1.191 -0.047027587890625 0.5314794921874958 +1.191125 -0.049774169921875 0.5314794921874958 +1.19125 -0.049774169921875 0.5314794921874958 +1.191375 -0.052490234375 0.5314794921874958 +1.1915 -0.052490234375 0.5314794921874958 +1.191625 -0.05523681640625 0.5314794921874958 +1.19175 -0.057952880859375 0.5314794921874958 +1.191875 -0.057952880859375 0.5314794921874958 +1.192 -0.0606689453125 0.5314794921874958 +1.192125 -0.0606689453125 0.5314794921874958 +1.19225 -0.0633544921875 0.5314794921874958 +1.192375 -0.066070556640625 0.5314794921874958 +1.1925 -0.066070556640625 0.5314794921874958 +1.192625 -0.068756103515625 0.5314794921874958 +1.19275 -0.068756103515625 0.5314794921874958 +1.192875 -0.071441650390625 0.5314794921874958 +1.193 -0.074127197265625 0.5314794921874958 +1.193125 -0.074127197265625 0.5314794921874958 +1.19325 -0.0767822265625 0.5314794921874958 +1.193375 -0.0767822265625 0.5314794921874958 +1.1935 -0.079437255859375 0.5314794921874958 +1.193625 -0.08209228515625 0.5314794921874958 +1.19375 -0.08209228515625 0.5314794921874958 +1.193875 -0.084747314453125 0.5314794921874958 +1.194 -0.084747314453125 0.5314794921874958 +1.194125 -0.087371826171875 0.5314794921874958 +1.19425 -0.089996337890625 0.5314794921874958 +1.194375 -0.089996337890625 0.5314794921874958 +1.1945 -0.09259033203125 0.5314794921874958 +1.194625 -0.09259033203125 0.5314794921874958 +1.19475 -0.09521484375 0.5314794921874958 +1.194875 -0.097808837890625 0.5314794921874958 +1.195 -0.097808837890625 0.5314794921874958 +1.195125 -0.100372314453125 0.5314794921874958 +1.19525 -0.100372314453125 0.5314794921874958 +1.195375 -0.102935791015625 0.5314794921874958 +1.1955 -0.105499267578125 0.5314794921874958 +1.195625 -0.105499267578125 0.5314794921874958 +1.19575 -0.108062744140625 0.5314794921874958 +1.195875 -0.108062744140625 0.5314794921874958 +1.196 -0.110595703125 0.5314794921874958 +1.196125 -0.113128662109375 0.5314794921874958 +1.19625 -0.113128662109375 0.5314794921874958 +1.196375 -0.115631103515625 0.5314794921874958 +1.1965 -0.115631103515625 0.5314794921874958 +1.196625 -0.118133544921875 0.5314794921874958 +1.19675 -0.12060546875 0.5314794921874958 +1.196875 -0.12060546875 0.5314794921874958 +1.197 -0.123077392578125 0.5314794921874958 +1.197125 -0.123077392578125 0.5314794921874958 +1.19725 -0.12554931640625 0.5314794921874958 +1.197375 -0.12799072265625 0.5314794921874958 +1.1975 -0.12799072265625 0.5314794921874958 +1.197625 -0.13043212890625 0.5314794921874958 +1.19775 -0.13043212890625 0.5314794921874958 +1.197875 -0.132843017578125 0.5314794921874958 +1.198 -0.13525390625 0.5314794921874958 +1.198125 -0.13525390625 0.5314794921874958 +1.19825 -0.13763427734375 0.5314794921874958 +1.198375 -0.13763427734375 0.5314794921874958 +1.1985 -0.1400146484375 0.5314794921874958 +1.198625 -0.142364501953125 0.5314794921874958 +1.19875 -0.142364501953125 0.5314794921874958 +1.198875 -0.14471435546875 0.5314794921874958 +1.199 -0.14471435546875 0.5314794921874958 +1.199125 -0.14703369140625 0.5314794921874958 +1.19925 -0.149322509765625 0.5314794921874958 +1.199375 -0.149322509765625 0.5314794921874958 +1.1995 -0.151641845703125 0.5314794921874958 +1.199625 -0.151641845703125 0.5314794921874958 +1.19975 -0.153900146484375 0.5314794921874958 +1.199875 -0.156158447265625 0.5314794921874958 +1.2 -0.156158447265625 0.5314794921874958 +1.200125 -0.158416748046875 0.5314794921874958 +1.20025 -0.158416748046875 0.5314794921874958 +1.200375 -0.16064453125 0.5314794921874958 +1.2005 -0.162841796875 0.5314794921874958 +1.200625 -0.162841796875 0.5314794921874958 +1.20075 -0.1650390625 0.5314794921874958 +1.200875 -0.1650390625 0.5314794921874958 +1.201 -0.167205810546875 0.5314794921874958 +1.201125 -0.16937255859375 0.5314794921874958 +1.20125 -0.16937255859375 0.5314794921874958 +1.201375 -0.171478271484375 0.5314794921874958 +1.2015 -0.171478271484375 0.5314794921874958 +1.201625 -0.173614501953125 0.5314794921874958 +1.20175 -0.17572021484375 0.5314794921874958 +1.201875 -0.17572021484375 0.5314794921874958 +1.202 -0.17779541015625 0.5314794921874958 +1.202125 -0.17779541015625 0.5314794921874958 +1.20225 -0.179840087890625 0.5314794921874958 +1.202375 -0.181884765625 0.5314794921874958 +1.2025 -0.181884765625 0.5314794921874958 +1.202625 -0.18389892578125 0.5314794921874958 +1.20275 -0.18389892578125 0.5314794921874958 +1.202875 -0.185882568359375 0.5314794921874958 +1.203 -0.1878662109375 0.5314794921874958 +1.203125 -0.1878662109375 0.5314794921874958 +1.20325 -0.189849853515625 0.5314794921874958 +1.203375 -0.189849853515625 0.5314794921874958 +1.2035 -0.1917724609375 0.5314794921874958 +1.203625 -0.193695068359375 0.5314794921874958 +1.20375 -0.193695068359375 0.5314794921874958 +1.203875 -0.195587158203125 0.5314794921874958 +1.204 -0.195587158203125 0.5314794921874958 +1.204125 -0.19744873046875 0.5314794921874958 +1.20425 -0.199310302734375 0.5314794921874958 +1.204375 -0.199310302734375 0.5314794921874958 +1.2045 -0.201141357421875 0.5314794921874958 +1.204625 -0.201141357421875 0.5314794921874958 +1.20475 -0.20294189453125 0.5314794921874958 +1.204875 -0.2047119140625 0.5314794921874958 +1.205 -0.2047119140625 0.5314794921874958 +1.205125 -0.20648193359375 0.5314794921874958 +1.20525 -0.20648193359375 0.5314794921874958 +1.205375 -0.208221435546875 0.5314794921874958 +1.2055 -0.2099609375 0.5314794921874958 +1.205625 -0.2099609375 0.5314794921874958 +1.20575 -0.211639404296875 0.5314794921874958 +1.205875 -0.211639404296875 0.5314794921874958 +1.206 -0.21331787109375 0.5314794921874958 +1.206125 -0.2149658203125 0.5314794921874958 +1.20625 -0.2149658203125 0.5314794921874958 +1.206375 -0.216583251953125 0.5314794921874958 +1.2065 -0.216583251953125 0.5314794921874958 +1.206625 -0.218170166015625 0.5314794921874958 +1.20675 -0.219757080078125 0.5314794921874958 +1.206875 -0.219757080078125 0.5314794921874958 +1.207 -0.2213134765625 0.5314794921874958 +1.207125 -0.2213134765625 0.5314794921874958 +1.20725 -0.22283935546875 0.5314794921874958 +1.207375 -0.224334716796875 0.5314794921874958 +1.2075 -0.224334716796875 0.5314794921874958 +1.207625 -0.225830078125 0.5314794921874958 +1.20775 -0.225830078125 0.5314794921874958 +1.207875 -0.227264404296875 0.5314794921874958 +1.208 -0.22869873046875 0.5314794921874958 +1.208125 -0.22869873046875 0.5314794921874958 +1.20825 -0.2301025390625 0.5314794921874958 +1.208375 -0.2301025390625 0.5314794921874958 +1.2085 -0.231475830078125 0.5314794921874958 +1.208625 -0.232818603515625 0.5314794921874958 +1.20875 -0.232818603515625 0.5314794921874958 +1.208875 -0.234161376953125 0.5314794921874958 +1.209 -0.234161376953125 0.5314794921874958 +1.209125 -0.2354736328125 0.5314794921874958 +1.20925 -0.23675537109375 0.5314794921874958 +1.209375 -0.23675537109375 0.5314794921874958 +1.2095 -0.23797607421875 0.5314794921874958 +1.209625 -0.23797607421875 0.5314794921874958 +1.20975 -0.239227294921875 0.5314794921874958 +1.209875 -0.24041748046875 0.5314794921874958 +1.21 -0.24041748046875 0.5314794921874958 +1.210125 -0.2415771484375 0.5314794921874958 +1.21025 -0.2415771484375 0.5314794921874958 +1.210375 -0.24273681640625 0.5314794921874958 +1.2105 -0.243865966796875 0.5314794921874958 +1.210625 -0.243865966796875 0.5314794921874958 +1.21075 -0.24493408203125 0.5314794921874958 +1.210875 -0.24493408203125 0.5314794921874958 +1.211 -0.246002197265625 0.5314794921874958 +1.211125 -0.247039794921875 0.5314794921874958 +1.21125 -0.247039794921875 0.5314794921874958 +1.211375 -0.248046875 0.5314794921874958 +1.2115 -0.248046875 0.5314794921874958 +1.211625 -0.2490234375 0.5314794921874958 +1.21175 -0.25 0.5314794921874958 +1.211875 -0.25 0.5314794921874958 +1.212 -0.25091552734375 0.5314794921874958 +1.212125 -0.25091552734375 0.5314794921874958 +1.21225 -0.2518310546875 0.5314794921874958 +1.212375 -0.252716064453125 0.5314794921874958 +1.2125 -0.252716064453125 0.5314794921874958 +1.212625 -0.2535400390625 0.5314794921874958 +1.21275 -0.2535400390625 0.5314794921874958 +1.212875 -0.254364013671875 0.5314794921874958 +1.213 -0.255157470703125 0.5314794921874958 +1.213125 -0.255157470703125 0.5314794921874958 +1.21325 -0.25592041015625 0.5314794921874958 +1.213375 -0.25592041015625 0.5314794921874958 +1.2135 -0.25665283203125 0.5314794921874958 +1.213625 -0.257354736328125 0.5314794921874958 +1.21375 -0.257354736328125 0.5314794921874958 +1.213875 -0.258026123046875 0.5314794921874958 +1.214 -0.258026123046875 0.5314794921874958 +1.214125 -0.258697509765625 0.5314794921874958 +1.21425 -0.259307861328125 0.5314794921874958 +1.214375 -0.259307861328125 0.5314794921874958 +1.2145 -0.2598876953125 0.5314794921874958 +1.214625 -0.2598876953125 0.5314794921874958 +1.21475 -0.260467529296875 0.5314794921874958 +1.214875 -0.260986328125 0.5314794921874958 +1.215 -0.260986328125 0.5314794921874958 +1.215125 -0.261505126953125 0.5314794921874958 +1.21525 -0.261505126953125 0.5314794921874958 +1.215375 -0.261993408203125 0.5314794921874958 +1.2155 -0.262420654296875 0.5314794921874958 +1.215625 -0.262420654296875 0.5314794921874958 +1.21575 -0.262847900390625 0.5314794921874958 +1.215875 -0.262847900390625 0.5314794921874958 +1.216 -0.108978271484375 0.220097656249995 +1.216125 -0.109130859375 0.220097656249995 +1.21625 -0.109130859375 0.220097656249995 +1.216375 -0.109283447265625 0.220097656249995 +1.2165 -0.109283447265625 0.220097656249995 +1.216625 -0.109405517578125 0.220097656249995 +1.21675 -0.109527587890625 0.220097656249995 +1.216875 -0.109527587890625 0.220097656249995 +1.217 -0.109619140625 0.220097656249995 +1.217125 -0.109619140625 0.220097656249995 +1.21725 -0.109710693359375 0.220097656249995 +1.217375 -0.10980224609375 0.220097656249995 +1.2175 -0.10980224609375 0.220097656249995 +1.217625 -0.10986328125 0.220097656249995 +1.21775 -0.10986328125 0.220097656249995 +1.217875 -0.10992431640625 0.220097656249995 +1.218 -0.109954833984375 0.220097656249995 +1.218125 -0.109954833984375 0.220097656249995 +1.21825 -0.1099853515625 0.220097656249995 +1.218375 -0.1099853515625 0.220097656249995 +1.2185 -0.110015869140625 0.220097656249995 +1.218625 -0.110015869140625 0.220097656249995 +1.21875 -0.110015869140625 0.220097656249995 +1.218875 -0.110015869140625 0.220097656249995 +1.219 -0.110015869140625 0.220097656249995 +1.219125 -0.1099853515625 0.220097656249995 +1.21925 -0.109954833984375 0.220097656249995 +1.219375 -0.109954833984375 0.220097656249995 +1.2195 -0.10992431640625 0.220097656249995 +1.219625 -0.10992431640625 0.220097656249995 +1.21975 -0.10986328125 0.220097656249995 +1.219875 -0.10980224609375 0.220097656249995 +1.22 -0.10980224609375 0.220097656249995 +1.220125 -0.109710693359375 0.220097656249995 +1.22025 -0.109710693359375 0.220097656249995 +1.220375 -0.109619140625 0.220097656249995 +1.2205 -0.109527587890625 0.220097656249995 +1.220625 -0.109527587890625 0.220097656249995 +1.22075 -0.109405517578125 0.220097656249995 +1.220875 -0.109405517578125 0.220097656249995 +1.221 -0.109283447265625 0.220097656249995 +1.221125 -0.109130859375 0.220097656249995 +1.22125 -0.109130859375 0.220097656249995 +1.221375 -0.108978271484375 0.220097656249995 +1.2215 -0.108978271484375 0.220097656249995 +1.221625 -0.10882568359375 0.220097656249995 +1.22175 -0.108642578125 0.220097656249995 +1.221875 -0.108642578125 0.220097656249995 +1.222 -0.10845947265625 0.220097656249995 +1.222125 -0.10845947265625 0.220097656249995 +1.22225 -0.1082763671875 0.220097656249995 +1.222375 -0.108062744140625 0.220097656249995 +1.2225 -0.108062744140625 0.220097656249995 +1.222625 -0.10784912109375 0.220097656249995 +1.22275 -0.10784912109375 0.220097656249995 +1.222875 -0.10760498046875 0.220097656249995 +1.223 -0.10736083984375 0.220097656249995 +1.223125 -0.10736083984375 0.220097656249995 +1.22325 -0.10711669921875 0.220097656249995 +1.223375 -0.10711669921875 0.220097656249995 +1.2235 -0.106842041015625 0.220097656249995 +1.223625 -0.1065673828125 0.220097656249995 +1.22375 -0.1065673828125 0.220097656249995 +1.223875 -0.10626220703125 0.220097656249995 +1.224 -0.10626220703125 0.220097656249995 +1.224125 -0.10595703125 0.220097656249995 +1.22425 -0.10565185546875 0.220097656249995 +1.224375 -0.10565185546875 0.220097656249995 +1.2245 -0.105316162109375 0.220097656249995 +1.224625 -0.105316162109375 0.220097656249995 +1.22475 -0.10498046875 0.220097656249995 +1.224875 -0.1046142578125 0.220097656249995 +1.225 -0.1046142578125 0.220097656249995 +1.225125 -0.104278564453125 0.220097656249995 +1.22525 -0.104278564453125 0.220097656249995 +1.225375 -0.1038818359375 0.220097656249995 +1.2255 -0.103515625 0.220097656249995 +1.225625 -0.103515625 0.220097656249995 +1.22575 -0.103118896484375 0.220097656249995 +1.225875 -0.103118896484375 0.220097656249995 +1.226 -0.102691650390625 0.220097656249995 +1.226125 -0.102294921875 0.220097656249995 +1.22625 -0.102294921875 0.220097656249995 +1.226375 -0.10186767578125 0.220097656249995 +1.2265 -0.10186767578125 0.220097656249995 +1.226625 -0.101409912109375 0.220097656249995 +1.22675 -0.1009521484375 0.220097656249995 +1.226875 -0.1009521484375 0.220097656249995 +1.227 -0.100494384765625 0.220097656249995 +1.227125 -0.100494384765625 0.220097656249995 +1.22725 -0.10003662109375 0.220097656249995 +1.227375 -0.09954833984375 0.220097656249995 +1.2275 -0.09954833984375 0.220097656249995 +1.227625 -0.099029541015625 0.220097656249995 +1.22775 -0.099029541015625 0.220097656249995 +1.227875 -0.098541259765625 0.220097656249995 +1.228 -0.0980224609375 0.220097656249995 +1.228125 -0.0980224609375 0.220097656249995 +1.22825 -0.097503662109375 0.220097656249995 +1.228375 -0.097503662109375 0.220097656249995 +1.2285 -0.096954345703125 0.220097656249995 +1.228625 -0.096405029296875 0.220097656249995 +1.22875 -0.096405029296875 0.220097656249995 +1.228875 -0.095855712890625 0.220097656249995 +1.229 -0.095855712890625 0.220097656249995 +1.229125 -0.09527587890625 0.220097656249995 +1.22925 -0.094696044921875 0.220097656249995 +1.229375 -0.094696044921875 0.220097656249995 +1.2295 -0.094085693359375 0.220097656249995 +1.229625 -0.094085693359375 0.220097656249995 +1.22975 -0.093505859375 0.220097656249995 +1.229875 -0.0928955078125 0.220097656249995 +1.23 -0.0928955078125 0.220097656249995 +1.230125 -0.092254638671875 0.220097656249995 +1.23025 -0.092254638671875 0.220097656249995 +1.230375 -0.09161376953125 0.220097656249995 +1.2305 -0.090972900390625 0.220097656249995 +1.230625 -0.090972900390625 0.220097656249995 +1.23075 -0.09033203125 0.220097656249995 +1.230875 -0.09033203125 0.220097656249995 +1.231 -0.08966064453125 0.220097656249995 +1.231125 -0.0889892578125 0.220097656249995 +1.23125 -0.0889892578125 0.220097656249995 +1.231375 -0.08831787109375 0.220097656249995 +1.2315 -0.08831787109375 0.220097656249995 +1.231625 -0.087615966796875 0.220097656249995 +1.23175 -0.0869140625 0.220097656249995 +1.231875 -0.0869140625 0.220097656249995 +1.232 -0.086212158203125 0.220097656249995 +1.232125 -0.086212158203125 0.220097656249995 +1.23225 -0.085479736328125 0.220097656249995 +1.232375 -0.084747314453125 0.220097656249995 +1.2325 -0.084747314453125 0.220097656249995 +1.232625 -0.084014892578125 0.220097656249995 +1.23275 -0.084014892578125 0.220097656249995 +1.232875 -0.083282470703125 0.220097656249995 +1.233 -0.08251953125 0.220097656249995 +1.233125 -0.08251953125 0.220097656249995 +1.23325 -0.081756591796875 0.220097656249995 +1.233375 -0.081756591796875 0.220097656249995 +1.2335 -0.080963134765625 0.220097656249995 +1.233625 -0.0802001953125 0.220097656249995 +1.23375 -0.0802001953125 0.220097656249995 +1.233875 -0.07940673828125 0.220097656249995 +1.234 -0.07940673828125 0.220097656249995 +1.234125 -0.078582763671875 0.220097656249995 +1.23425 -0.077789306640625 0.220097656249995 +1.234375 -0.077789306640625 0.220097656249995 +1.2345 -0.07696533203125 0.220097656249995 +1.234625 -0.07696533203125 0.220097656249995 +1.23475 -0.076141357421875 0.220097656249995 +1.234875 -0.075286865234375 0.220097656249995 +1.235 -0.075286865234375 0.220097656249995 +1.235125 -0.074462890625 0.220097656249995 +1.23525 -0.074462890625 0.220097656249995 +1.235375 -0.0736083984375 0.220097656249995 +1.2355 -0.07275390625 0.220097656249995 +1.235625 -0.07275390625 0.220097656249995 +1.23575 -0.071868896484375 0.220097656249995 +1.235875 -0.071868896484375 0.220097656249995 +1.236 -0.071014404296875 0.220097656249995 +1.236125 -0.07012939453125 0.220097656249995 +1.23625 -0.07012939453125 0.220097656249995 +1.236375 -0.0692138671875 0.220097656249995 +1.2365 -0.0692138671875 0.220097656249995 +1.236625 -0.068328857421875 0.220097656249995 +1.23675 -0.067413330078125 0.220097656249995 +1.236875 -0.067413330078125 0.220097656249995 +1.237 -0.066497802734375 0.220097656249995 +1.237125 -0.066497802734375 0.220097656249995 +1.23725 -0.065582275390625 0.220097656249995 +1.237375 -0.064666748046875 0.220097656249995 +1.2375 -0.064666748046875 0.220097656249995 +1.237625 -0.063720703125 0.220097656249995 +1.23775 -0.063720703125 0.220097656249995 +1.237875 -0.062774658203125 0.220097656249995 +1.238 -0.06182861328125 0.220097656249995 +1.238125 -0.06182861328125 0.220097656249995 +1.23825 -0.060882568359375 0.220097656249995 +1.238375 -0.060882568359375 0.220097656249995 +1.2385 -0.059906005859375 0.220097656249995 +1.238625 -0.058929443359375 0.220097656249995 +1.23875 -0.058929443359375 0.220097656249995 +1.238875 -0.057952880859375 0.220097656249995 +1.239 -0.057952880859375 0.220097656249995 +1.239125 -0.056976318359375 0.220097656249995 +1.23925 -0.055999755859375 0.220097656249995 +1.239375 -0.055999755859375 0.220097656249995 +1.2395 -0.05499267578125 0.220097656249995 +1.239625 -0.05499267578125 0.220097656249995 +1.23975 -0.053985595703125 0.220097656249995 +1.239875 -0.052978515625 0.220097656249995 +1.24 -0.052978515625 0.220097656249995 +1.240125 -0.051971435546875 0.220097656249995 +1.24025 -0.051971435546875 0.220097656249995 +1.240375 -0.05096435546875 0.220097656249995 +1.2405 -0.0499267578125 0.220097656249995 +1.240625 -0.0499267578125 0.220097656249995 +1.24075 -0.048919677734375 0.220097656249995 +1.240875 -0.048919677734375 0.220097656249995 +1.241 -0.047882080078125 0.220097656249995 +1.241125 -0.046844482421875 0.220097656249995 +1.24125 -0.046844482421875 0.220097656249995 +1.241375 -0.0457763671875 0.220097656249995 +1.2415 -0.0457763671875 0.220097656249995 +1.241625 -0.04473876953125 0.220097656249995 +1.24175 -0.043670654296875 0.220097656249995 +1.241875 -0.043670654296875 0.220097656249995 +1.242 -0.042633056640625 0.220097656249995 +1.242125 -0.042633056640625 0.220097656249995 +1.24225 -0.04156494140625 0.220097656249995 +1.242375 -0.040496826171875 0.220097656249995 +1.2425 -0.040496826171875 0.220097656249995 +1.242625 -0.039398193359375 0.220097656249995 +1.24275 -0.039398193359375 0.220097656249995 +1.242875 -0.038330078125 0.220097656249995 +1.243 -0.037261962890625 0.220097656249995 +1.243125 -0.037261962890625 0.220097656249995 +1.24325 -0.036163330078125 0.220097656249995 +1.243375 -0.036163330078125 0.220097656249995 +1.2435 -0.035064697265625 0.220097656249995 +1.243625 -0.03399658203125 0.220097656249995 +1.24375 -0.03399658203125 0.220097656249995 +1.243875 -0.03289794921875 0.220097656249995 +1.244 -0.03289794921875 0.220097656249995 +1.244125 -0.031768798828125 0.220097656249995 +1.24425 -0.030670166015625 0.220097656249995 +1.244375 -0.030670166015625 0.220097656249995 +1.2445 -0.029571533203125 0.220097656249995 +1.244625 -0.029571533203125 0.220097656249995 +1.24475 -0.028472900390625 0.220097656249995 +1.244875 -0.02734375 0.220097656249995 +1.245 -0.02734375 0.220097656249995 +1.245125 -0.0262451171875 0.220097656249995 +1.24525 -0.0262451171875 0.220097656249995 +1.245375 -0.025115966796875 0.220097656249995 +1.2455 -0.02398681640625 0.220097656249995 +1.245625 -0.02398681640625 0.220097656249995 +1.24575 -0.022857666015625 0.220097656249995 +1.245875 -0.022857666015625 0.220097656249995 +1.246 -0.021728515625 0.220097656249995 +1.246125 -0.020599365234375 0.220097656249995 +1.24625 -0.020599365234375 0.220097656249995 +1.246375 -0.01947021484375 0.220097656249995 +1.2465 -0.01947021484375 0.220097656249995 +1.246625 -0.018341064453125 0.220097656249995 +1.24675 -0.017181396484375 0.220097656249995 +1.246875 -0.017181396484375 0.220097656249995 +1.247 -0.01605224609375 0.220097656249995 +1.247125 -0.01605224609375 0.220097656249995 +1.24725 -0.014923095703125 0.220097656249995 +1.247375 -0.013763427734375 0.220097656249995 +1.2475 -0.013763427734375 0.220097656249995 +1.247625 -0.01263427734375 0.220097656249995 +1.24775 -0.01263427734375 0.220097656249995 +1.247875 -0.011474609375 0.220097656249995 1.248 0.004425048828125 -0.09448242187500444 1.248125 0.004425048828125 -0.09448242187500444 1.24825 0.003936767578125 -0.09448242187500444 @@ -9999,504 +9999,504 @@ 1.24975 0.00048828125 -0.09448242187500444 1.249875 0.0 -0.09448242187500444 1.25 0.0 -0.09448242187500444 -1.250125 -0.000518798828125 -0.09448242187500444 -1.25025 -0.000518798828125 -0.09448242187500444 -1.250375 -0.001007080078125 -0.09448242187500444 -1.2505 -0.001495361328125 -0.09448242187500444 -1.250625 -0.001495361328125 -0.09448242187500444 -1.25075 -0.001983642578125 -0.09448242187500444 -1.250875 -0.001983642578125 -0.09448242187500444 -1.251 -0.002471923828125 -0.09448242187500444 -1.251125 -0.00299072265625 -0.09448242187500444 -1.25125 -0.00299072265625 -0.09448242187500444 -1.251375 -0.00347900390625 -0.09448242187500444 -1.2515 -0.00347900390625 -0.09448242187500444 -1.251625 -0.00396728515625 -0.09448242187500444 -1.25175 -0.00445556640625 -0.09448242187500444 -1.251875 -0.00445556640625 -0.09448242187500444 -1.252 -0.00494384765625 -0.09448242187500444 -1.252125 -0.00494384765625 -0.09448242187500444 -1.25225 -0.00543212890625 -0.09448242187500444 -1.252375 -0.00592041015625 -0.09448242187500444 -1.2525 -0.00592041015625 -0.09448242187500444 -1.252625 -0.006439208984375 -0.09448242187500444 -1.25275 -0.006439208984375 -0.09448242187500444 -1.252875 -0.006927490234375 -0.09448242187500444 -1.253 -0.007415771484375 -0.09448242187500444 -1.253125 -0.007415771484375 -0.09448242187500444 -1.25325 -0.007904052734375 -0.09448242187500444 -1.253375 -0.007904052734375 -0.09448242187500444 -1.2535 -0.008392333984375 -0.09448242187500444 -1.253625 -0.008880615234375 -0.09448242187500444 -1.25375 -0.008880615234375 -0.09448242187500444 -1.253875 -0.00933837890625 -0.09448242187500444 -1.254 -0.00933837890625 -0.09448242187500444 -1.254125 -0.00982666015625 -0.09448242187500444 -1.25425 -0.01031494140625 -0.09448242187500444 -1.254375 -0.01031494140625 -0.09448242187500444 -1.2545 -0.01080322265625 -0.09448242187500444 -1.254625 -0.01080322265625 -0.09448242187500444 -1.25475 -0.01129150390625 -0.09448242187500444 -1.254875 -0.011749267578125 -0.09448242187500444 -1.255 -0.011749267578125 -0.09448242187500444 -1.255125 -0.012237548828125 -0.09448242187500444 -1.25525 -0.012237548828125 -0.09448242187500444 -1.255375 -0.012725830078125 -0.09448242187500444 -1.2555 -0.01318359375 -0.09448242187500444 -1.255625 -0.01318359375 -0.09448242187500444 -1.25575 -0.013671875 -0.09448242187500444 -1.255875 -0.013671875 -0.09448242187500444 -1.256 -0.014129638671875 -0.09448242187500444 -1.256125 -0.014617919921875 -0.09448242187500444 -1.25625 -0.014617919921875 -0.09448242187500444 -1.256375 -0.01507568359375 -0.09448242187500444 -1.2565 -0.01507568359375 -0.09448242187500444 -1.256625 -0.01556396484375 -0.09448242187500444 -1.25675 -0.016021728515625 -0.09448242187500444 -1.256875 -0.016021728515625 -0.09448242187500444 -1.257 -0.0164794921875 -0.09448242187500444 -1.257125 -0.0164794921875 -0.09448242187500444 -1.25725 -0.016937255859375 -0.09448242187500444 -1.257375 -0.01739501953125 -0.09448242187500444 -1.2575 -0.01739501953125 -0.09448242187500444 -1.257625 -0.017852783203125 -0.09448242187500444 -1.25775 -0.017852783203125 -0.09448242187500444 -1.257875 -0.018310546875 -0.09448242187500444 -1.258 -0.018768310546875 -0.09448242187500444 -1.258125 -0.018768310546875 -0.09448242187500444 -1.25825 -0.01922607421875 -0.09448242187500444 -1.258375 -0.01922607421875 -0.09448242187500444 -1.2585 -0.019683837890625 -0.09448242187500444 -1.258625 -0.0201416015625 -0.09448242187500444 -1.25875 -0.0201416015625 -0.09448242187500444 -1.258875 -0.02056884765625 -0.09448242187500444 -1.259 -0.02056884765625 -0.09448242187500444 -1.259125 -0.021026611328125 -0.09448242187500444 -1.25925 -0.021453857421875 -0.09448242187500444 -1.259375 -0.021453857421875 -0.09448242187500444 -1.2595 -0.02191162109375 -0.09448242187500444 -1.259625 -0.02191162109375 -0.09448242187500444 -1.25975 -0.0223388671875 -0.09448242187500444 -1.259875 -0.02276611328125 -0.09448242187500444 -1.26 -0.02276611328125 -0.09448242187500444 -1.260125 -0.023193359375 -0.09448242187500444 -1.26025 -0.023193359375 -0.09448242187500444 -1.260375 -0.02362060546875 -0.09448242187500444 -1.2605 -0.0240478515625 -0.09448242187500444 -1.260625 -0.0240478515625 -0.09448242187500444 -1.26075 -0.02447509765625 -0.09448242187500444 -1.260875 -0.02447509765625 -0.09448242187500444 -1.261 -0.02490234375 -0.09448242187500444 -1.261125 -0.02532958984375 -0.09448242187500444 -1.26125 -0.02532958984375 -0.09448242187500444 -1.261375 -0.0257568359375 -0.09448242187500444 -1.2615 -0.0257568359375 -0.09448242187500444 -1.261625 -0.026153564453125 -0.09448242187500444 -1.26175 -0.026580810546875 -0.09448242187500444 -1.261875 -0.026580810546875 -0.09448242187500444 -1.262 -0.0269775390625 -0.09448242187500444 -1.262125 -0.0269775390625 -0.09448242187500444 -1.26225 -0.027374267578125 -0.09448242187500444 -1.262375 -0.02777099609375 -0.09448242187500444 -1.2625 -0.02777099609375 -0.09448242187500444 -1.262625 -0.028167724609375 -0.09448242187500444 -1.26275 -0.028167724609375 -0.09448242187500444 -1.262875 -0.028564453125 -0.09448242187500444 -1.263 -0.028961181640625 -0.09448242187500444 -1.263125 -0.028961181640625 -0.09448242187500444 -1.26325 -0.02935791015625 -0.09448242187500444 -1.263375 -0.02935791015625 -0.09448242187500444 -1.2635 -0.029754638671875 -0.09448242187500444 -1.263625 -0.030120849609375 -0.09448242187500444 -1.26375 -0.030120849609375 -0.09448242187500444 -1.263875 -0.030517578125 -0.09448242187500444 -1.264 -0.030517578125 -0.09448242187500444 -1.264125 -0.0308837890625 -0.09448242187500444 -1.26425 -0.03125 -0.09448242187500444 -1.264375 -0.03125 -0.09448242187500444 -1.2645 -0.0316162109375 -0.09448242187500444 -1.264625 -0.0316162109375 -0.09448242187500444 -1.26475 -0.031982421875 -0.09448242187500444 -1.264875 -0.0323486328125 -0.09448242187500444 -1.265 -0.0323486328125 -0.09448242187500444 -1.265125 -0.03271484375 -0.09448242187500444 -1.26525 -0.03271484375 -0.09448242187500444 -1.265375 -0.0330810546875 -0.09448242187500444 -1.2655 -0.033416748046875 -0.09448242187500444 -1.265625 -0.033416748046875 -0.09448242187500444 -1.26575 -0.03375244140625 -0.09448242187500444 -1.265875 -0.03375244140625 -0.09448242187500444 -1.266 -0.03411865234375 -0.09448242187500444 -1.266125 -0.034454345703125 -0.09448242187500444 -1.26625 -0.034454345703125 -0.09448242187500444 -1.266375 -0.0347900390625 -0.09448242187500444 -1.2665 -0.0347900390625 -0.09448242187500444 -1.266625 -0.035125732421875 -0.09448242187500444 -1.26675 -0.03546142578125 -0.09448242187500444 -1.266875 -0.03546142578125 -0.09448242187500444 -1.267 -0.0357666015625 -0.09448242187500444 -1.267125 -0.0357666015625 -0.09448242187500444 -1.26725 -0.036102294921875 -0.09448242187500444 -1.267375 -0.036407470703125 -0.09448242187500444 -1.2675 -0.036407470703125 -0.09448242187500444 -1.267625 -0.036712646484375 -0.09448242187500444 -1.26775 -0.036712646484375 -0.09448242187500444 -1.267875 -0.03704833984375 -0.09448242187500444 -1.268 -0.037353515625 -0.09448242187500444 -1.268125 -0.037353515625 -0.09448242187500444 -1.26825 -0.037628173828125 -0.09448242187500444 -1.268375 -0.037628173828125 -0.09448242187500444 -1.2685 -0.037933349609375 -0.09448242187500444 -1.268625 -0.038238525390625 -0.09448242187500444 -1.26875 -0.038238525390625 -0.09448242187500444 -1.268875 -0.03851318359375 -0.09448242187500444 -1.269 -0.03851318359375 -0.09448242187500444 -1.269125 -0.038818359375 -0.09448242187500444 -1.26925 -0.039093017578125 -0.09448242187500444 -1.269375 -0.039093017578125 -0.09448242187500444 -1.2695 -0.03936767578125 -0.09448242187500444 -1.269625 -0.03936767578125 -0.09448242187500444 -1.26975 -0.039642333984375 -0.09448242187500444 -1.269875 -0.039886474609375 -0.09448242187500444 -1.27 -0.039886474609375 -0.09448242187500444 -1.270125 -0.0401611328125 -0.09448242187500444 -1.27025 -0.0401611328125 -0.09448242187500444 -1.270375 -0.040435791015625 -0.09448242187500444 -1.2705 -0.040679931640625 -0.09448242187500444 -1.270625 -0.040679931640625 -0.09448242187500444 -1.27075 -0.040924072265625 -0.09448242187500444 -1.270875 -0.040924072265625 -0.09448242187500444 -1.271 -0.041168212890625 -0.09448242187500444 -1.271125 -0.041412353515625 -0.09448242187500444 -1.27125 -0.041412353515625 -0.09448242187500444 -1.271375 -0.041656494140625 -0.09448242187500444 -1.2715 -0.041656494140625 -0.09448242187500444 -1.271625 -0.0418701171875 -0.09448242187500444 -1.27175 -0.0421142578125 -0.09448242187500444 -1.271875 -0.0421142578125 -0.09448242187500444 -1.272 -0.042327880859375 -0.09448242187500444 -1.272125 -0.042327880859375 -0.09448242187500444 -1.27225 -0.04254150390625 -0.09448242187500444 -1.272375 -0.042755126953125 -0.09448242187500444 -1.2725 -0.042755126953125 -0.09448242187500444 -1.272625 -0.04296875 -0.09448242187500444 -1.27275 -0.04296875 -0.09448242187500444 -1.272875 -0.043182373046875 -0.09448242187500444 -1.273 -0.043365478515625 -0.09448242187500444 -1.273125 -0.043365478515625 -0.09448242187500444 -1.27325 -0.043548583984375 -0.09448242187500444 -1.273375 -0.043548583984375 -0.09448242187500444 -1.2735 -0.04376220703125 -0.09448242187500444 -1.273625 -0.0439453125 -0.09448242187500444 -1.27375 -0.0439453125 -0.09448242187500444 -1.273875 -0.04412841796875 -0.09448242187500444 -1.274 -0.04412841796875 -0.09448242187500444 -1.274125 -0.044281005859375 -0.09448242187500444 -1.27425 -0.044464111328125 -0.09448242187500444 -1.274375 -0.044464111328125 -0.09448242187500444 -1.2745 -0.04461669921875 -0.09448242187500444 -1.274625 -0.04461669921875 -0.09448242187500444 -1.27475 -0.0447998046875 -0.09448242187500444 -1.274875 -0.044952392578125 -0.09448242187500444 -1.275 -0.044952392578125 -0.09448242187500444 -1.275125 -0.04510498046875 -0.09448242187500444 -1.27525 -0.04510498046875 -0.09448242187500444 -1.275375 -0.04522705078125 -0.09448242187500444 -1.2755 -0.045379638671875 -0.09448242187500444 -1.275625 -0.045379638671875 -0.09448242187500444 -1.27575 -0.045501708984375 -0.09448242187500444 -1.275875 -0.045501708984375 -0.09448242187500444 -1.276 -0.045654296875 -0.09448242187500444 -1.276125 -0.0457763671875 -0.09448242187500444 -1.27625 -0.0457763671875 -0.09448242187500444 -1.276375 -0.0458984375 -0.09448242187500444 -1.2765 -0.0458984375 -0.09448242187500444 -1.276625 -0.0460205078125 -0.09448242187500444 -1.27675 -0.046112060546875 -0.09448242187500444 -1.276875 -0.046112060546875 -0.09448242187500444 -1.277 -0.046234130859375 -0.09448242187500444 -1.277125 -0.046234130859375 -0.09448242187500444 -1.27725 -0.04632568359375 -0.09448242187500444 -1.277375 -0.046417236328125 -0.09448242187500444 -1.2775 -0.046417236328125 -0.09448242187500444 -1.277625 -0.0465087890625 -0.09448242187500444 -1.27775 -0.0465087890625 -0.09448242187500444 -1.277875 -0.046600341796875 -0.09448242187500444 -1.278 -0.046661376953125 -0.09448242187500444 -1.278125 -0.046661376953125 -0.09448242187500444 -1.27825 -0.0467529296875 -0.09448242187500444 -1.278375 -0.0467529296875 -0.09448242187500444 -1.2785 -0.04681396484375 -0.09448242187500444 -1.278625 -0.046875 -0.09448242187500444 -1.27875 -0.046875 -0.09448242187500444 -1.278875 -0.04693603515625 -0.09448242187500444 -1.279 -0.04693603515625 -0.09448242187500444 -1.279125 -0.0469970703125 -0.09448242187500444 -1.27925 -0.04705810546875 -0.09448242187500444 -1.279375 -0.04705810546875 -0.09448242187500444 -1.2795 -0.047088623046875 -0.09448242187500444 -1.279625 -0.047088623046875 -0.09448242187500444 -1.27975 -0.047119140625 -0.09448242187500444 -1.279875 -0.047149658203125 -0.09448242187500444 -1.28 -0.180694580078125 -0.3620751953125036 -1.280125 -0.1807861328125 -0.3620751953125036 -1.28025 -0.1807861328125 -0.3620751953125036 -1.280375 -0.180877685546875 -0.3620751953125036 -1.2805 -0.180938720703125 -0.3620751953125036 -1.280625 -0.180938720703125 -0.3620751953125036 -1.28075 -0.180999755859375 -0.3620751953125036 -1.280875 -0.180999755859375 -0.3620751953125036 -1.281 -0.1810302734375 -0.3620751953125036 -1.281125 -0.1810302734375 -0.3620751953125036 -1.28125 -0.1810302734375 -0.3620751953125036 -1.281375 -0.1810302734375 -0.3620751953125036 -1.2815 -0.1810302734375 -0.3620751953125036 -1.281625 -0.180999755859375 -0.3620751953125036 -1.28175 -0.180938720703125 -0.3620751953125036 -1.281875 -0.180938720703125 -0.3620751953125036 -1.282 -0.180877685546875 -0.3620751953125036 -1.282125 -0.180877685546875 -0.3620751953125036 -1.28225 -0.1807861328125 -0.3620751953125036 -1.282375 -0.180694580078125 -0.3620751953125036 -1.2825 -0.180694580078125 -0.3620751953125036 -1.282625 -0.1805419921875 -0.3620751953125036 -1.28275 -0.1805419921875 -0.3620751953125036 -1.282875 -0.180419921875 -0.3620751953125036 -1.283 -0.18023681640625 -0.3620751953125036 -1.283125 -0.18023681640625 -0.3620751953125036 -1.28325 -0.1800537109375 -0.3620751953125036 -1.283375 -0.1800537109375 -0.3620751953125036 -1.2835 -0.179840087890625 -0.3620751953125036 -1.283625 -0.179595947265625 -0.3620751953125036 -1.28375 -0.179595947265625 -0.3620751953125036 -1.283875 -0.179351806640625 -0.3620751953125036 -1.284 -0.179351806640625 -0.3620751953125036 -1.284125 -0.179107666015625 -0.3620751953125036 -1.28425 -0.178802490234375 -0.3620751953125036 -1.284375 -0.178802490234375 -0.3620751953125036 -1.2845 -0.178497314453125 -0.3620751953125036 -1.284625 -0.178497314453125 -0.3620751953125036 -1.28475 -0.178192138671875 -0.3620751953125036 -1.284875 -0.177825927734375 -0.3620751953125036 -1.285 -0.177825927734375 -0.3620751953125036 -1.285125 -0.177459716796875 -0.3620751953125036 -1.28525 -0.177459716796875 -0.3620751953125036 -1.285375 -0.177093505859375 -0.3620751953125036 -1.2855 -0.176666259765625 -0.3620751953125036 -1.285625 -0.176666259765625 -0.3620751953125036 -1.28575 -0.17626953125 -0.3620751953125036 -1.285875 -0.17626953125 -0.3620751953125036 -1.286 -0.175811767578125 -0.3620751953125036 -1.286125 -0.17535400390625 -0.3620751953125036 -1.28625 -0.17535400390625 -0.3620751953125036 -1.286375 -0.17486572265625 -0.3620751953125036 -1.2865 -0.17486572265625 -0.3620751953125036 -1.286625 -0.17437744140625 -0.3620751953125036 -1.28675 -0.173858642578125 -0.3620751953125036 -1.286875 -0.173858642578125 -0.3620751953125036 -1.287 -0.173309326171875 -0.3620751953125036 -1.287125 -0.173309326171875 -0.3620751953125036 -1.28725 -0.172760009765625 -0.3620751953125036 -1.287375 -0.17218017578125 -0.3620751953125036 -1.2875 -0.17218017578125 -0.3620751953125036 -1.287625 -0.17156982421875 -0.3620751953125036 -1.28775 -0.17156982421875 -0.3620751953125036 -1.287875 -0.17095947265625 -0.3620751953125036 -1.288 -0.170318603515625 -0.3620751953125036 -1.288125 -0.170318603515625 -0.3620751953125036 -1.28825 -0.169677734375 -0.3620751953125036 -1.288375 -0.169677734375 -0.3620751953125036 -1.2885 -0.16900634765625 -0.3620751953125036 -1.288625 -0.1683349609375 -0.3620751953125036 -1.28875 -0.1683349609375 -0.3620751953125036 -1.288875 -0.167633056640625 -0.3620751953125036 -1.289 -0.167633056640625 -0.3620751953125036 -1.289125 -0.166900634765625 -0.3620751953125036 -1.28925 -0.1661376953125 -0.3620751953125036 -1.289375 -0.1661376953125 -0.3620751953125036 -1.2895 -0.165374755859375 -0.3620751953125036 -1.289625 -0.165374755859375 -0.3620751953125036 -1.28975 -0.16461181640625 -0.3620751953125036 -1.289875 -0.163818359375 -0.3620751953125036 -1.29 -0.163818359375 -0.3620751953125036 -1.290125 -0.162994384765625 -0.3620751953125036 -1.29025 -0.162994384765625 -0.3620751953125036 -1.290375 -0.16217041015625 -0.3620751953125036 -1.2905 -0.16131591796875 -0.3620751953125036 -1.290625 -0.16131591796875 -0.3620751953125036 -1.29075 -0.160430908203125 -0.3620751953125036 -1.290875 -0.160430908203125 -0.3620751953125036 -1.291 -0.1595458984375 -0.3620751953125036 -1.291125 -0.15863037109375 -0.3620751953125036 -1.29125 -0.15863037109375 -0.3620751953125036 -1.291375 -0.15771484375 -0.3620751953125036 -1.2915 -0.15771484375 -0.3620751953125036 -1.291625 -0.15679931640625 -0.3620751953125036 -1.29175 -0.15582275390625 -0.3620751953125036 -1.291875 -0.15582275390625 -0.3620751953125036 -1.292 -0.15484619140625 -0.3620751953125036 -1.292125 -0.15484619140625 -0.3620751953125036 -1.29225 -0.15386962890625 -0.3620751953125036 -1.292375 -0.152862548828125 -0.3620751953125036 -1.2925 -0.152862548828125 -0.3620751953125036 -1.292625 -0.151824951171875 -0.3620751953125036 -1.29275 -0.151824951171875 -0.3620751953125036 -1.292875 -0.150787353515625 -0.3620751953125036 -1.293 -0.14971923828125 -0.3620751953125036 -1.293125 -0.14971923828125 -0.3620751953125036 -1.29325 -0.148651123046875 -0.3620751953125036 -1.293375 -0.148651123046875 -0.3620751953125036 -1.2935 -0.1475830078125 -0.3620751953125036 -1.293625 -0.146453857421875 -0.3620751953125036 -1.29375 -0.146453857421875 -0.3620751953125036 -1.293875 -0.145355224609375 -0.3620751953125036 -1.294 -0.145355224609375 -0.3620751953125036 -1.294125 -0.144195556640625 -0.3620751953125036 -1.29425 -0.14306640625 -0.3620751953125036 -1.294375 -0.14306640625 -0.3620751953125036 -1.2945 -0.141876220703125 -0.3620751953125036 -1.294625 -0.141876220703125 -0.3620751953125036 -1.29475 -0.14068603515625 -0.3620751953125036 -1.294875 -0.139495849609375 -0.3620751953125036 -1.295 -0.139495849609375 -0.3620751953125036 -1.295125 -0.138275146484375 -0.3620751953125036 -1.29525 -0.138275146484375 -0.3620751953125036 -1.295375 -0.137054443359375 -0.3620751953125036 -1.2955 -0.13580322265625 -0.3620751953125036 -1.295625 -0.13580322265625 -0.3620751953125036 -1.29575 -0.134552001953125 -0.3620751953125036 -1.295875 -0.134552001953125 -0.3620751953125036 -1.296 -0.133270263671875 -0.3620751953125036 -1.296125 -0.131988525390625 -0.3620751953125036 -1.29625 -0.131988525390625 -0.3620751953125036 -1.296375 -0.13067626953125 -0.3620751953125036 -1.2965 -0.13067626953125 -0.3620751953125036 -1.296625 -0.129364013671875 -0.3620751953125036 -1.29675 -0.128021240234375 -0.3620751953125036 -1.296875 -0.128021240234375 -0.3620751953125036 -1.297 -0.126678466796875 -0.3620751953125036 -1.297125 -0.126678466796875 -0.3620751953125036 -1.29725 -0.12530517578125 -0.3620751953125036 -1.297375 -0.123931884765625 -0.3620751953125036 -1.2975 -0.123931884765625 -0.3620751953125036 -1.297625 -0.12255859375 -0.3620751953125036 -1.29775 -0.12255859375 -0.3620751953125036 -1.297875 -0.12115478515625 -0.3620751953125036 -1.298 -0.119720458984375 -0.3620751953125036 -1.298125 -0.119720458984375 -0.3620751953125036 -1.29825 -0.1182861328125 -0.3620751953125036 -1.298375 -0.1182861328125 -0.3620751953125036 -1.2985 -0.116851806640625 -0.3620751953125036 -1.298625 -0.115386962890625 -0.3620751953125036 -1.29875 -0.115386962890625 -0.3620751953125036 -1.298875 -0.113922119140625 -0.3620751953125036 -1.299 -0.113922119140625 -0.3620751953125036 -1.299125 -0.112457275390625 -0.3620751953125036 -1.29925 -0.1109619140625 -0.3620751953125036 -1.299375 -0.1109619140625 -0.3620751953125036 -1.2995 -0.109466552734375 -0.3620751953125036 -1.299625 -0.109466552734375 -0.3620751953125036 -1.29975 -0.107940673828125 -0.3620751953125036 -1.299875 -0.106414794921875 -0.3620751953125036 -1.3 -0.106414794921875 -0.3620751953125036 -1.300125 -0.104888916015625 -0.3620751953125036 -1.30025 -0.104888916015625 -0.3620751953125036 -1.300375 -0.10333251953125 -0.3620751953125036 -1.3005 -0.101776123046875 -0.3620751953125036 -1.300625 -0.101776123046875 -0.3620751953125036 -1.30075 -0.100189208984375 -0.3620751953125036 -1.300875 -0.100189208984375 -0.3620751953125036 -1.301 -0.098602294921875 -0.3620751953125036 -1.301125 -0.097015380859375 -0.3620751953125036 -1.30125 -0.097015380859375 -0.3620751953125036 -1.301375 -0.09539794921875 -0.3620751953125036 -1.3015 -0.09539794921875 -0.3620751953125036 -1.301625 -0.093780517578125 -0.3620751953125036 -1.30175 -0.0921630859375 -0.3620751953125036 -1.301875 -0.0921630859375 -0.3620751953125036 -1.302 -0.09051513671875 -0.3620751953125036 -1.302125 -0.09051513671875 -0.3620751953125036 -1.30225 -0.0888671875 -0.3620751953125036 -1.302375 -0.08721923828125 -0.3620751953125036 -1.3025 -0.08721923828125 -0.3620751953125036 -1.302625 -0.0855712890625 -0.3620751953125036 -1.30275 -0.0855712890625 -0.3620751953125036 -1.302875 -0.083892822265625 -0.3620751953125036 -1.303 -0.082183837890625 -0.3620751953125036 -1.303125 -0.082183837890625 -0.3620751953125036 -1.30325 -0.08050537109375 -0.3620751953125036 -1.303375 -0.08050537109375 -0.3620751953125036 -1.3035 -0.07879638671875 -0.3620751953125036 -1.303625 -0.07708740234375 -0.3620751953125036 -1.30375 -0.07708740234375 -0.3620751953125036 -1.303875 -0.07537841796875 -0.3620751953125036 -1.304 -0.07537841796875 -0.3620751953125036 -1.304125 -0.073638916015625 -0.3620751953125036 -1.30425 -0.0718994140625 -0.3620751953125036 -1.304375 -0.0718994140625 -0.3620751953125036 -1.3045 -0.070159912109375 -0.3620751953125036 -1.304625 -0.070159912109375 -0.3620751953125036 -1.30475 -0.06842041015625 -0.3620751953125036 -1.304875 -0.066650390625 -0.3620751953125036 -1.305 -0.066650390625 -0.3620751953125036 -1.305125 -0.06488037109375 -0.3620751953125036 -1.30525 -0.06488037109375 -0.3620751953125036 -1.305375 -0.0631103515625 -0.3620751953125036 -1.3055 -0.06134033203125 -0.3620751953125036 -1.305625 -0.06134033203125 -0.3620751953125036 -1.30575 -0.059539794921875 -0.3620751953125036 -1.305875 -0.059539794921875 -0.3620751953125036 -1.306 -0.0577392578125 -0.3620751953125036 -1.306125 -0.055938720703125 -0.3620751953125036 -1.30625 -0.055938720703125 -0.3620751953125036 -1.306375 -0.05413818359375 -0.3620751953125036 -1.3065 -0.05413818359375 -0.3620751953125036 -1.306625 -0.052337646484375 -0.3620751953125036 -1.30675 -0.050506591796875 -0.3620751953125036 -1.306875 -0.050506591796875 -0.3620751953125036 -1.307 -0.0487060546875 -0.3620751953125036 -1.307125 -0.0487060546875 -0.3620751953125036 -1.30725 -0.046875 -0.3620751953125036 -1.307375 -0.0450439453125 -0.3620751953125036 -1.3075 -0.0450439453125 -0.3620751953125036 -1.307625 -0.043182373046875 -0.3620751953125036 -1.30775 -0.043182373046875 -0.3620751953125036 -1.307875 -0.041351318359375 -0.3620751953125036 -1.308 -0.03948974609375 -0.3620751953125036 -1.308125 -0.03948974609375 -0.3620751953125036 -1.30825 -0.03765869140625 -0.3620751953125036 -1.308375 -0.03765869140625 -0.3620751953125036 -1.3085 -0.035797119140625 -0.3620751953125036 -1.308625 -0.033935546875 -0.3620751953125036 -1.30875 -0.033935546875 -0.3620751953125036 -1.308875 -0.032073974609375 -0.3620751953125036 -1.309 -0.032073974609375 -0.3620751953125036 -1.309125 -0.03021240234375 -0.3620751953125036 -1.30925 -0.0283203125 -0.3620751953125036 -1.309375 -0.0283203125 -0.3620751953125036 -1.3095 -0.026458740234375 -0.3620751953125036 -1.309625 -0.026458740234375 -0.3620751953125036 -1.30975 -0.024566650390625 -0.3620751953125036 -1.309875 -0.022705078125 -0.3620751953125036 -1.31 -0.022705078125 -0.3620751953125036 -1.310125 -0.02081298828125 -0.3620751953125036 -1.31025 -0.02081298828125 -0.3620751953125036 -1.310375 -0.018951416015625 -0.3620751953125036 -1.3105 -0.017059326171875 -0.3620751953125036 -1.310625 -0.017059326171875 -0.3620751953125036 -1.31075 -0.015167236328125 -0.3620751953125036 -1.310875 -0.015167236328125 -0.3620751953125036 -1.311 -0.013275146484375 -0.3620751953125036 -1.311125 -0.011383056640625 -0.3620751953125036 -1.31125 -0.011383056640625 -0.3620751953125036 -1.311375 -0.009490966796875 -0.3620751953125036 -1.3115 -0.009490966796875 -0.3620751953125036 -1.311625 -0.007598876953125 -0.3620751953125036 -1.31175 -0.005706787109375 -0.3620751953125036 -1.311875 -0.005706787109375 -0.3620751953125036 -1.312 -0.00567626953125 -0.5400292968750023 -1.312125 -0.00567626953125 -0.5400292968750023 -1.31225 -0.002838134765625 -0.5400292968750023 +1.250125 -0.00048828125 -0.09448242187500444 +1.25025 -0.00048828125 -0.09448242187500444 +1.250375 -0.0009765625 -0.09448242187500444 +1.2505 -0.00146484375 -0.09448242187500444 +1.250625 -0.00146484375 -0.09448242187500444 +1.25075 -0.001953125 -0.09448242187500444 +1.250875 -0.001953125 -0.09448242187500444 +1.251 -0.00244140625 -0.09448242187500444 +1.251125 -0.002960205078125 -0.09448242187500444 +1.25125 -0.002960205078125 -0.09448242187500444 +1.251375 -0.003448486328125 -0.09448242187500444 +1.2515 -0.003448486328125 -0.09448242187500444 +1.251625 -0.003936767578125 -0.09448242187500444 +1.25175 -0.004425048828125 -0.09448242187500444 +1.251875 -0.004425048828125 -0.09448242187500444 +1.252 -0.004913330078125 -0.09448242187500444 +1.252125 -0.004913330078125 -0.09448242187500444 +1.25225 -0.005401611328125 -0.09448242187500444 +1.252375 -0.005889892578125 -0.09448242187500444 +1.2525 -0.005889892578125 -0.09448242187500444 +1.252625 -0.00640869140625 -0.09448242187500444 +1.25275 -0.00640869140625 -0.09448242187500444 +1.252875 -0.00689697265625 -0.09448242187500444 +1.253 -0.00738525390625 -0.09448242187500444 +1.253125 -0.00738525390625 -0.09448242187500444 +1.25325 -0.00787353515625 -0.09448242187500444 +1.253375 -0.00787353515625 -0.09448242187500444 +1.2535 -0.00836181640625 -0.09448242187500444 +1.253625 -0.00885009765625 -0.09448242187500444 +1.25375 -0.00885009765625 -0.09448242187500444 +1.253875 -0.009307861328125 -0.09448242187500444 +1.254 -0.009307861328125 -0.09448242187500444 +1.254125 -0.009796142578125 -0.09448242187500444 +1.25425 -0.010284423828125 -0.09448242187500444 +1.254375 -0.010284423828125 -0.09448242187500444 +1.2545 -0.010772705078125 -0.09448242187500444 +1.254625 -0.010772705078125 -0.09448242187500444 +1.25475 -0.011260986328125 -0.09448242187500444 +1.254875 -0.01171875 -0.09448242187500444 +1.255 -0.01171875 -0.09448242187500444 +1.255125 -0.01220703125 -0.09448242187500444 +1.25525 -0.01220703125 -0.09448242187500444 +1.255375 -0.0126953125 -0.09448242187500444 +1.2555 -0.013153076171875 -0.09448242187500444 +1.255625 -0.013153076171875 -0.09448242187500444 +1.25575 -0.013641357421875 -0.09448242187500444 +1.255875 -0.013641357421875 -0.09448242187500444 +1.256 -0.01409912109375 -0.09448242187500444 +1.256125 -0.01458740234375 -0.09448242187500444 +1.25625 -0.01458740234375 -0.09448242187500444 +1.256375 -0.015045166015625 -0.09448242187500444 +1.2565 -0.015045166015625 -0.09448242187500444 +1.256625 -0.015533447265625 -0.09448242187500444 +1.25675 -0.0159912109375 -0.09448242187500444 +1.256875 -0.0159912109375 -0.09448242187500444 +1.257 -0.016448974609375 -0.09448242187500444 +1.257125 -0.016448974609375 -0.09448242187500444 +1.25725 -0.01690673828125 -0.09448242187500444 +1.257375 -0.017364501953125 -0.09448242187500444 +1.2575 -0.017364501953125 -0.09448242187500444 +1.257625 -0.017822265625 -0.09448242187500444 +1.25775 -0.017822265625 -0.09448242187500444 +1.257875 -0.018280029296875 -0.09448242187500444 +1.258 -0.01873779296875 -0.09448242187500444 +1.258125 -0.01873779296875 -0.09448242187500444 +1.25825 -0.019195556640625 -0.09448242187500444 +1.258375 -0.019195556640625 -0.09448242187500444 +1.2585 -0.0196533203125 -0.09448242187500444 +1.258625 -0.020111083984375 -0.09448242187500444 +1.25875 -0.020111083984375 -0.09448242187500444 +1.258875 -0.020538330078125 -0.09448242187500444 +1.259 -0.020538330078125 -0.09448242187500444 +1.259125 -0.02099609375 -0.09448242187500444 +1.25925 -0.02142333984375 -0.09448242187500444 +1.259375 -0.02142333984375 -0.09448242187500444 +1.2595 -0.021881103515625 -0.09448242187500444 +1.259625 -0.021881103515625 -0.09448242187500444 +1.25975 -0.022308349609375 -0.09448242187500444 +1.259875 -0.022735595703125 -0.09448242187500444 +1.26 -0.022735595703125 -0.09448242187500444 +1.260125 -0.023162841796875 -0.09448242187500444 +1.26025 -0.023162841796875 -0.09448242187500444 +1.260375 -0.023590087890625 -0.09448242187500444 +1.2605 -0.024017333984375 -0.09448242187500444 +1.260625 -0.024017333984375 -0.09448242187500444 +1.26075 -0.024444580078125 -0.09448242187500444 +1.260875 -0.024444580078125 -0.09448242187500444 +1.261 -0.024871826171875 -0.09448242187500444 +1.261125 -0.025299072265625 -0.09448242187500444 +1.26125 -0.025299072265625 -0.09448242187500444 +1.261375 -0.025726318359375 -0.09448242187500444 +1.2615 -0.025726318359375 -0.09448242187500444 +1.261625 -0.026123046875 -0.09448242187500444 +1.26175 -0.02655029296875 -0.09448242187500444 +1.261875 -0.02655029296875 -0.09448242187500444 +1.262 -0.026947021484375 -0.09448242187500444 +1.262125 -0.026947021484375 -0.09448242187500444 +1.26225 -0.02734375 -0.09448242187500444 +1.262375 -0.027740478515625 -0.09448242187500444 +1.2625 -0.027740478515625 -0.09448242187500444 +1.262625 -0.02813720703125 -0.09448242187500444 +1.26275 -0.02813720703125 -0.09448242187500444 +1.262875 -0.028533935546875 -0.09448242187500444 +1.263 -0.0289306640625 -0.09448242187500444 +1.263125 -0.0289306640625 -0.09448242187500444 +1.26325 -0.029327392578125 -0.09448242187500444 +1.263375 -0.029327392578125 -0.09448242187500444 +1.2635 -0.02972412109375 -0.09448242187500444 +1.263625 -0.03009033203125 -0.09448242187500444 +1.26375 -0.03009033203125 -0.09448242187500444 +1.263875 -0.030487060546875 -0.09448242187500444 +1.264 -0.030487060546875 -0.09448242187500444 +1.264125 -0.030853271484375 -0.09448242187500444 +1.26425 -0.031219482421875 -0.09448242187500444 +1.264375 -0.031219482421875 -0.09448242187500444 +1.2645 -0.031585693359375 -0.09448242187500444 +1.264625 -0.031585693359375 -0.09448242187500444 +1.26475 -0.031951904296875 -0.09448242187500444 +1.264875 -0.032318115234375 -0.09448242187500444 +1.265 -0.032318115234375 -0.09448242187500444 +1.265125 -0.032684326171875 -0.09448242187500444 +1.26525 -0.032684326171875 -0.09448242187500444 +1.265375 -0.033050537109375 -0.09448242187500444 +1.2655 -0.03338623046875 -0.09448242187500444 +1.265625 -0.03338623046875 -0.09448242187500444 +1.26575 -0.033721923828125 -0.09448242187500444 +1.265875 -0.033721923828125 -0.09448242187500444 +1.266 -0.034088134765625 -0.09448242187500444 +1.266125 -0.034423828125 -0.09448242187500444 +1.26625 -0.034423828125 -0.09448242187500444 +1.266375 -0.034759521484375 -0.09448242187500444 +1.2665 -0.034759521484375 -0.09448242187500444 +1.266625 -0.03509521484375 -0.09448242187500444 +1.26675 -0.035430908203125 -0.09448242187500444 +1.266875 -0.035430908203125 -0.09448242187500444 +1.267 -0.035736083984375 -0.09448242187500444 +1.267125 -0.035736083984375 -0.09448242187500444 +1.26725 -0.03607177734375 -0.09448242187500444 +1.267375 -0.036376953125 -0.09448242187500444 +1.2675 -0.036376953125 -0.09448242187500444 +1.267625 -0.03668212890625 -0.09448242187500444 +1.26775 -0.03668212890625 -0.09448242187500444 +1.267875 -0.037017822265625 -0.09448242187500444 +1.268 -0.037322998046875 -0.09448242187500444 +1.268125 -0.037322998046875 -0.09448242187500444 +1.26825 -0.03759765625 -0.09448242187500444 +1.268375 -0.03759765625 -0.09448242187500444 +1.2685 -0.03790283203125 -0.09448242187500444 +1.268625 -0.0382080078125 -0.09448242187500444 +1.26875 -0.0382080078125 -0.09448242187500444 +1.268875 -0.038482666015625 -0.09448242187500444 +1.269 -0.038482666015625 -0.09448242187500444 +1.269125 -0.038787841796875 -0.09448242187500444 +1.26925 -0.0390625 -0.09448242187500444 +1.269375 -0.0390625 -0.09448242187500444 +1.2695 -0.039337158203125 -0.09448242187500444 +1.269625 -0.039337158203125 -0.09448242187500444 +1.26975 -0.03961181640625 -0.09448242187500444 +1.269875 -0.03985595703125 -0.09448242187500444 +1.27 -0.03985595703125 -0.09448242187500444 +1.270125 -0.040130615234375 -0.09448242187500444 +1.27025 -0.040130615234375 -0.09448242187500444 +1.270375 -0.0404052734375 -0.09448242187500444 +1.2705 -0.0406494140625 -0.09448242187500444 +1.270625 -0.0406494140625 -0.09448242187500444 +1.27075 -0.0408935546875 -0.09448242187500444 +1.270875 -0.0408935546875 -0.09448242187500444 +1.271 -0.0411376953125 -0.09448242187500444 +1.271125 -0.0413818359375 -0.09448242187500444 +1.27125 -0.0413818359375 -0.09448242187500444 +1.271375 -0.0416259765625 -0.09448242187500444 +1.2715 -0.0416259765625 -0.09448242187500444 +1.271625 -0.041839599609375 -0.09448242187500444 +1.27175 -0.042083740234375 -0.09448242187500444 +1.271875 -0.042083740234375 -0.09448242187500444 +1.272 -0.04229736328125 -0.09448242187500444 +1.272125 -0.04229736328125 -0.09448242187500444 +1.27225 -0.042510986328125 -0.09448242187500444 +1.272375 -0.042724609375 -0.09448242187500444 +1.2725 -0.042724609375 -0.09448242187500444 +1.272625 -0.042938232421875 -0.09448242187500444 +1.27275 -0.042938232421875 -0.09448242187500444 +1.272875 -0.04315185546875 -0.09448242187500444 +1.273 -0.0433349609375 -0.09448242187500444 +1.273125 -0.0433349609375 -0.09448242187500444 +1.27325 -0.04351806640625 -0.09448242187500444 +1.273375 -0.04351806640625 -0.09448242187500444 +1.2735 -0.043731689453125 -0.09448242187500444 +1.273625 -0.043914794921875 -0.09448242187500444 +1.27375 -0.043914794921875 -0.09448242187500444 +1.273875 -0.044097900390625 -0.09448242187500444 +1.274 -0.044097900390625 -0.09448242187500444 +1.274125 -0.04425048828125 -0.09448242187500444 +1.27425 -0.04443359375 -0.09448242187500444 +1.274375 -0.04443359375 -0.09448242187500444 +1.2745 -0.044586181640625 -0.09448242187500444 +1.274625 -0.044586181640625 -0.09448242187500444 +1.27475 -0.044769287109375 -0.09448242187500444 +1.274875 -0.044921875 -0.09448242187500444 +1.275 -0.044921875 -0.09448242187500444 +1.275125 -0.045074462890625 -0.09448242187500444 +1.27525 -0.045074462890625 -0.09448242187500444 +1.275375 -0.045196533203125 -0.09448242187500444 +1.2755 -0.04534912109375 -0.09448242187500444 +1.275625 -0.04534912109375 -0.09448242187500444 +1.27575 -0.04547119140625 -0.09448242187500444 +1.275875 -0.04547119140625 -0.09448242187500444 +1.276 -0.045623779296875 -0.09448242187500444 +1.276125 -0.045745849609375 -0.09448242187500444 +1.27625 -0.045745849609375 -0.09448242187500444 +1.276375 -0.045867919921875 -0.09448242187500444 +1.2765 -0.045867919921875 -0.09448242187500444 +1.276625 -0.045989990234375 -0.09448242187500444 +1.27675 -0.04608154296875 -0.09448242187500444 +1.276875 -0.04608154296875 -0.09448242187500444 +1.277 -0.04620361328125 -0.09448242187500444 +1.277125 -0.04620361328125 -0.09448242187500444 +1.27725 -0.046295166015625 -0.09448242187500444 +1.277375 -0.04638671875 -0.09448242187500444 +1.2775 -0.04638671875 -0.09448242187500444 +1.277625 -0.046478271484375 -0.09448242187500444 +1.27775 -0.046478271484375 -0.09448242187500444 +1.277875 -0.04656982421875 -0.09448242187500444 +1.278 -0.046630859375 -0.09448242187500444 +1.278125 -0.046630859375 -0.09448242187500444 +1.27825 -0.046722412109375 -0.09448242187500444 +1.278375 -0.046722412109375 -0.09448242187500444 +1.2785 -0.046783447265625 -0.09448242187500444 +1.278625 -0.046844482421875 -0.09448242187500444 +1.27875 -0.046844482421875 -0.09448242187500444 +1.278875 -0.046905517578125 -0.09448242187500444 +1.279 -0.046905517578125 -0.09448242187500444 +1.279125 -0.046966552734375 -0.09448242187500444 +1.27925 -0.047027587890625 -0.09448242187500444 +1.279375 -0.047027587890625 -0.09448242187500444 +1.2795 -0.04705810546875 -0.09448242187500444 +1.279625 -0.04705810546875 -0.09448242187500444 +1.27975 -0.047088623046875 -0.09448242187500444 +1.279875 -0.047119140625 -0.09448242187500444 +1.28 -0.1806640625 -0.3620751953125036 +1.280125 -0.180755615234375 -0.3620751953125036 +1.28025 -0.180755615234375 -0.3620751953125036 +1.280375 -0.18084716796875 -0.3620751953125036 +1.2805 -0.180908203125 -0.3620751953125036 +1.280625 -0.180908203125 -0.3620751953125036 +1.28075 -0.18096923828125 -0.3620751953125036 +1.280875 -0.18096923828125 -0.3620751953125036 +1.281 -0.180999755859375 -0.3620751953125036 +1.281125 -0.180999755859375 -0.3620751953125036 +1.28125 -0.180999755859375 -0.3620751953125036 +1.281375 -0.180999755859375 -0.3620751953125036 +1.2815 -0.180999755859375 -0.3620751953125036 +1.281625 -0.18096923828125 -0.3620751953125036 +1.28175 -0.180908203125 -0.3620751953125036 +1.281875 -0.180908203125 -0.3620751953125036 +1.282 -0.18084716796875 -0.3620751953125036 +1.282125 -0.18084716796875 -0.3620751953125036 +1.28225 -0.180755615234375 -0.3620751953125036 +1.282375 -0.1806640625 -0.3620751953125036 +1.2825 -0.1806640625 -0.3620751953125036 +1.282625 -0.180511474609375 -0.3620751953125036 +1.28275 -0.180511474609375 -0.3620751953125036 +1.282875 -0.180389404296875 -0.3620751953125036 +1.283 -0.180206298828125 -0.3620751953125036 +1.283125 -0.180206298828125 -0.3620751953125036 +1.28325 -0.180023193359375 -0.3620751953125036 +1.283375 -0.180023193359375 -0.3620751953125036 +1.2835 -0.1798095703125 -0.3620751953125036 +1.283625 -0.1795654296875 -0.3620751953125036 +1.28375 -0.1795654296875 -0.3620751953125036 +1.283875 -0.1793212890625 -0.3620751953125036 +1.284 -0.1793212890625 -0.3620751953125036 +1.284125 -0.1790771484375 -0.3620751953125036 +1.28425 -0.17877197265625 -0.3620751953125036 +1.284375 -0.17877197265625 -0.3620751953125036 +1.2845 -0.178466796875 -0.3620751953125036 +1.284625 -0.178466796875 -0.3620751953125036 +1.28475 -0.17816162109375 -0.3620751953125036 +1.284875 -0.17779541015625 -0.3620751953125036 +1.285 -0.17779541015625 -0.3620751953125036 +1.285125 -0.17742919921875 -0.3620751953125036 +1.28525 -0.17742919921875 -0.3620751953125036 +1.285375 -0.17706298828125 -0.3620751953125036 +1.2855 -0.1766357421875 -0.3620751953125036 +1.285625 -0.1766357421875 -0.3620751953125036 +1.28575 -0.176239013671875 -0.3620751953125036 +1.285875 -0.176239013671875 -0.3620751953125036 +1.286 -0.17578125 -0.3620751953125036 +1.286125 -0.175323486328125 -0.3620751953125036 +1.28625 -0.175323486328125 -0.3620751953125036 +1.286375 -0.174835205078125 -0.3620751953125036 +1.2865 -0.174835205078125 -0.3620751953125036 +1.286625 -0.174346923828125 -0.3620751953125036 +1.28675 -0.173828125 -0.3620751953125036 +1.286875 -0.173828125 -0.3620751953125036 +1.287 -0.17327880859375 -0.3620751953125036 +1.287125 -0.17327880859375 -0.3620751953125036 +1.28725 -0.1727294921875 -0.3620751953125036 +1.287375 -0.172149658203125 -0.3620751953125036 +1.2875 -0.172149658203125 -0.3620751953125036 +1.287625 -0.171539306640625 -0.3620751953125036 +1.28775 -0.171539306640625 -0.3620751953125036 +1.287875 -0.170928955078125 -0.3620751953125036 +1.288 -0.1702880859375 -0.3620751953125036 +1.288125 -0.1702880859375 -0.3620751953125036 +1.28825 -0.169647216796875 -0.3620751953125036 +1.288375 -0.169647216796875 -0.3620751953125036 +1.2885 -0.168975830078125 -0.3620751953125036 +1.288625 -0.168304443359375 -0.3620751953125036 +1.28875 -0.168304443359375 -0.3620751953125036 +1.288875 -0.1676025390625 -0.3620751953125036 +1.289 -0.1676025390625 -0.3620751953125036 +1.289125 -0.1668701171875 -0.3620751953125036 +1.28925 -0.166107177734375 -0.3620751953125036 +1.289375 -0.166107177734375 -0.3620751953125036 +1.2895 -0.16534423828125 -0.3620751953125036 +1.289625 -0.16534423828125 -0.3620751953125036 +1.28975 -0.164581298828125 -0.3620751953125036 +1.289875 -0.163787841796875 -0.3620751953125036 +1.29 -0.163787841796875 -0.3620751953125036 +1.290125 -0.1629638671875 -0.3620751953125036 +1.29025 -0.1629638671875 -0.3620751953125036 +1.290375 -0.162139892578125 -0.3620751953125036 +1.2905 -0.161285400390625 -0.3620751953125036 +1.290625 -0.161285400390625 -0.3620751953125036 +1.29075 -0.160400390625 -0.3620751953125036 +1.290875 -0.160400390625 -0.3620751953125036 +1.291 -0.159515380859375 -0.3620751953125036 +1.291125 -0.158599853515625 -0.3620751953125036 +1.29125 -0.158599853515625 -0.3620751953125036 +1.291375 -0.157684326171875 -0.3620751953125036 +1.2915 -0.157684326171875 -0.3620751953125036 +1.291625 -0.156768798828125 -0.3620751953125036 +1.29175 -0.155792236328125 -0.3620751953125036 +1.291875 -0.155792236328125 -0.3620751953125036 +1.292 -0.154815673828125 -0.3620751953125036 +1.292125 -0.154815673828125 -0.3620751953125036 +1.29225 -0.153839111328125 -0.3620751953125036 +1.292375 -0.15283203125 -0.3620751953125036 +1.2925 -0.15283203125 -0.3620751953125036 +1.292625 -0.15179443359375 -0.3620751953125036 +1.29275 -0.15179443359375 -0.3620751953125036 +1.292875 -0.1507568359375 -0.3620751953125036 +1.293 -0.149688720703125 -0.3620751953125036 +1.293125 -0.149688720703125 -0.3620751953125036 +1.29325 -0.14862060546875 -0.3620751953125036 +1.293375 -0.14862060546875 -0.3620751953125036 +1.2935 -0.147552490234375 -0.3620751953125036 +1.293625 -0.14642333984375 -0.3620751953125036 +1.29375 -0.14642333984375 -0.3620751953125036 +1.293875 -0.14532470703125 -0.3620751953125036 +1.294 -0.14532470703125 -0.3620751953125036 +1.294125 -0.1441650390625 -0.3620751953125036 +1.29425 -0.143035888671875 -0.3620751953125036 +1.294375 -0.143035888671875 -0.3620751953125036 +1.2945 -0.141845703125 -0.3620751953125036 +1.294625 -0.141845703125 -0.3620751953125036 +1.29475 -0.140655517578125 -0.3620751953125036 +1.294875 -0.13946533203125 -0.3620751953125036 +1.295 -0.13946533203125 -0.3620751953125036 +1.295125 -0.13824462890625 -0.3620751953125036 +1.29525 -0.13824462890625 -0.3620751953125036 +1.295375 -0.13702392578125 -0.3620751953125036 +1.2955 -0.135772705078125 -0.3620751953125036 +1.295625 -0.135772705078125 -0.3620751953125036 +1.29575 -0.134521484375 -0.3620751953125036 +1.295875 -0.134521484375 -0.3620751953125036 +1.296 -0.13323974609375 -0.3620751953125036 +1.296125 -0.1319580078125 -0.3620751953125036 +1.29625 -0.1319580078125 -0.3620751953125036 +1.296375 -0.130645751953125 -0.3620751953125036 +1.2965 -0.130645751953125 -0.3620751953125036 +1.296625 -0.12933349609375 -0.3620751953125036 +1.29675 -0.12799072265625 -0.3620751953125036 +1.296875 -0.12799072265625 -0.3620751953125036 +1.297 -0.12664794921875 -0.3620751953125036 +1.297125 -0.12664794921875 -0.3620751953125036 +1.29725 -0.125274658203125 -0.3620751953125036 +1.297375 -0.1239013671875 -0.3620751953125036 +1.2975 -0.1239013671875 -0.3620751953125036 +1.297625 -0.122528076171875 -0.3620751953125036 +1.29775 -0.122528076171875 -0.3620751953125036 +1.297875 -0.121124267578125 -0.3620751953125036 +1.298 -0.11968994140625 -0.3620751953125036 +1.298125 -0.11968994140625 -0.3620751953125036 +1.29825 -0.118255615234375 -0.3620751953125036 +1.298375 -0.118255615234375 -0.3620751953125036 +1.2985 -0.1168212890625 -0.3620751953125036 +1.298625 -0.1153564453125 -0.3620751953125036 +1.29875 -0.1153564453125 -0.3620751953125036 +1.298875 -0.1138916015625 -0.3620751953125036 +1.299 -0.1138916015625 -0.3620751953125036 +1.299125 -0.1124267578125 -0.3620751953125036 +1.29925 -0.110931396484375 -0.3620751953125036 +1.299375 -0.110931396484375 -0.3620751953125036 +1.2995 -0.10943603515625 -0.3620751953125036 +1.299625 -0.10943603515625 -0.3620751953125036 +1.29975 -0.10791015625 -0.3620751953125036 +1.299875 -0.10638427734375 -0.3620751953125036 +1.3 -0.10638427734375 -0.3620751953125036 +1.300125 -0.1048583984375 -0.3620751953125036 +1.30025 -0.1048583984375 -0.3620751953125036 +1.300375 -0.103302001953125 -0.3620751953125036 +1.3005 -0.10174560546875 -0.3620751953125036 +1.300625 -0.10174560546875 -0.3620751953125036 +1.30075 -0.10015869140625 -0.3620751953125036 +1.300875 -0.10015869140625 -0.3620751953125036 +1.301 -0.09857177734375 -0.3620751953125036 +1.301125 -0.09698486328125 -0.3620751953125036 +1.30125 -0.09698486328125 -0.3620751953125036 +1.301375 -0.095367431640625 -0.3620751953125036 +1.3015 -0.095367431640625 -0.3620751953125036 +1.301625 -0.09375 -0.3620751953125036 +1.30175 -0.092132568359375 -0.3620751953125036 +1.301875 -0.092132568359375 -0.3620751953125036 +1.302 -0.090484619140625 -0.3620751953125036 +1.302125 -0.090484619140625 -0.3620751953125036 +1.30225 -0.088836669921875 -0.3620751953125036 +1.302375 -0.087188720703125 -0.3620751953125036 +1.3025 -0.087188720703125 -0.3620751953125036 +1.302625 -0.085540771484375 -0.3620751953125036 +1.30275 -0.085540771484375 -0.3620751953125036 +1.302875 -0.0838623046875 -0.3620751953125036 +1.303 -0.0821533203125 -0.3620751953125036 +1.303125 -0.0821533203125 -0.3620751953125036 +1.30325 -0.080474853515625 -0.3620751953125036 +1.303375 -0.080474853515625 -0.3620751953125036 +1.3035 -0.078765869140625 -0.3620751953125036 +1.303625 -0.077056884765625 -0.3620751953125036 +1.30375 -0.077056884765625 -0.3620751953125036 +1.303875 -0.075347900390625 -0.3620751953125036 +1.304 -0.075347900390625 -0.3620751953125036 +1.304125 -0.0736083984375 -0.3620751953125036 +1.30425 -0.071868896484375 -0.3620751953125036 +1.304375 -0.071868896484375 -0.3620751953125036 +1.3045 -0.07012939453125 -0.3620751953125036 +1.304625 -0.07012939453125 -0.3620751953125036 +1.30475 -0.068389892578125 -0.3620751953125036 +1.304875 -0.066619873046875 -0.3620751953125036 +1.305 -0.066619873046875 -0.3620751953125036 +1.305125 -0.064849853515625 -0.3620751953125036 +1.30525 -0.064849853515625 -0.3620751953125036 +1.305375 -0.063079833984375 -0.3620751953125036 +1.3055 -0.061309814453125 -0.3620751953125036 +1.305625 -0.061309814453125 -0.3620751953125036 +1.30575 -0.05950927734375 -0.3620751953125036 +1.305875 -0.05950927734375 -0.3620751953125036 +1.306 -0.057708740234375 -0.3620751953125036 +1.306125 -0.055908203125 -0.3620751953125036 +1.30625 -0.055908203125 -0.3620751953125036 +1.306375 -0.054107666015625 -0.3620751953125036 +1.3065 -0.054107666015625 -0.3620751953125036 +1.306625 -0.05230712890625 -0.3620751953125036 +1.30675 -0.05047607421875 -0.3620751953125036 +1.306875 -0.05047607421875 -0.3620751953125036 +1.307 -0.048675537109375 -0.3620751953125036 +1.307125 -0.048675537109375 -0.3620751953125036 +1.30725 -0.046844482421875 -0.3620751953125036 +1.307375 -0.045013427734375 -0.3620751953125036 +1.3075 -0.045013427734375 -0.3620751953125036 +1.307625 -0.04315185546875 -0.3620751953125036 +1.30775 -0.04315185546875 -0.3620751953125036 +1.307875 -0.04132080078125 -0.3620751953125036 +1.308 -0.039459228515625 -0.3620751953125036 +1.308125 -0.039459228515625 -0.3620751953125036 +1.30825 -0.037628173828125 -0.3620751953125036 +1.308375 -0.037628173828125 -0.3620751953125036 +1.3085 -0.0357666015625 -0.3620751953125036 +1.308625 -0.033905029296875 -0.3620751953125036 +1.30875 -0.033905029296875 -0.3620751953125036 +1.308875 -0.03204345703125 -0.3620751953125036 +1.309 -0.03204345703125 -0.3620751953125036 +1.309125 -0.030181884765625 -0.3620751953125036 +1.30925 -0.028289794921875 -0.3620751953125036 +1.309375 -0.028289794921875 -0.3620751953125036 +1.3095 -0.02642822265625 -0.3620751953125036 +1.309625 -0.02642822265625 -0.3620751953125036 +1.30975 -0.0245361328125 -0.3620751953125036 +1.309875 -0.022674560546875 -0.3620751953125036 +1.31 -0.022674560546875 -0.3620751953125036 +1.310125 -0.020782470703125 -0.3620751953125036 +1.31025 -0.020782470703125 -0.3620751953125036 +1.310375 -0.0189208984375 -0.3620751953125036 +1.3105 -0.01702880859375 -0.3620751953125036 +1.310625 -0.01702880859375 -0.3620751953125036 +1.31075 -0.01513671875 -0.3620751953125036 +1.310875 -0.01513671875 -0.3620751953125036 +1.311 -0.01324462890625 -0.3620751953125036 +1.311125 -0.0113525390625 -0.3620751953125036 +1.31125 -0.0113525390625 -0.3620751953125036 +1.311375 -0.00946044921875 -0.3620751953125036 +1.3115 -0.00946044921875 -0.3620751953125036 +1.311625 -0.007568359375 -0.3620751953125036 +1.31175 -0.00567626953125 -0.3620751953125036 +1.311875 -0.00567626953125 -0.3620751953125036 +1.312 -0.005645751953125 -0.5400292968750023 +1.312125 -0.005645751953125 -0.5400292968750023 +1.31225 -0.0028076171875 -0.5400292968750023 1.312375 0.0 -0.5400292968750023 1.3125 0.0 -0.5400292968750023 1.312625 0.0028076171875 -0.5400292968750023 @@ -10999,504 +10999,504 @@ 1.37475 0.00311279296875 -0.5998974609374999 1.374875 0.0 -0.5998974609374999 1.375 0.0 -0.5998974609374999 -1.375125 -0.003143310546875 -0.5998974609374999 -1.37525 -0.003143310546875 -0.5998974609374999 -1.375375 -0.00628662109375 -0.5998974609374999 -1.3755 -0.009429931640625 -0.5998974609374999 -1.375625 -0.009429931640625 -0.5998974609374999 -1.37575 -0.0125732421875 -0.5998974609374999 -1.375875 -0.0125732421875 -0.5998974609374999 -1.376 -0.013946533203125 -0.5321582031249976 -1.376125 -0.0167236328125 -0.5321582031249976 -1.37625 -0.0167236328125 -0.5321582031249976 -1.376375 -0.019500732421875 -0.5321582031249976 -1.3765 -0.019500732421875 -0.5321582031249976 -1.376625 -0.02227783203125 -0.5321582031249976 -1.37675 -0.025054931640625 -0.5321582031249976 -1.376875 -0.025054931640625 -0.5321582031249976 -1.377 -0.02783203125 -0.5321582031249976 -1.377125 -0.02783203125 -0.5321582031249976 -1.37725 -0.030609130859375 -0.5321582031249976 -1.377375 -0.033355712890625 -0.5321582031249976 -1.3775 -0.033355712890625 -0.5321582031249976 -1.377625 -0.0361328125 -0.5321582031249976 -1.37775 -0.0361328125 -0.5321582031249976 -1.377875 -0.03887939453125 -0.5321582031249976 -1.378 -0.0416259765625 -0.5321582031249976 -1.378125 -0.0416259765625 -0.5321582031249976 -1.37825 -0.04437255859375 -0.5321582031249976 -1.378375 -0.04437255859375 -0.5321582031249976 -1.3785 -0.047119140625 -0.5321582031249976 -1.378625 -0.04986572265625 -0.5321582031249976 -1.37875 -0.04986572265625 -0.5321582031249976 -1.378875 -0.0526123046875 -0.5321582031249976 -1.379 -0.0526123046875 -0.5321582031249976 -1.379125 -0.055328369140625 -0.5321582031249976 -1.37925 -0.05804443359375 -0.5321582031249976 -1.379375 -0.05804443359375 -0.5321582031249976 -1.3795 -0.060760498046875 -0.5321582031249976 -1.379625 -0.060760498046875 -0.5321582031249976 -1.37975 -0.0634765625 -0.5321582031249976 -1.379875 -0.066192626953125 -0.5321582031249976 -1.38 -0.066192626953125 -0.5321582031249976 -1.380125 -0.068878173828125 -0.5321582031249976 -1.38025 -0.068878173828125 -0.5321582031249976 -1.380375 -0.071563720703125 -0.5321582031249976 -1.3805 -0.074249267578125 -0.5321582031249976 -1.380625 -0.074249267578125 -0.5321582031249976 -1.38075 -0.076904296875 -0.5321582031249976 -1.380875 -0.076904296875 -0.5321582031249976 -1.381 -0.07958984375 -0.5321582031249976 -1.381125 -0.082244873046875 -0.5321582031249976 -1.38125 -0.082244873046875 -0.5321582031249976 -1.381375 -0.084869384765625 -0.5321582031249976 -1.3815 -0.084869384765625 -0.5321582031249976 -1.381625 -0.0875244140625 -0.5321582031249976 -1.38175 -0.09014892578125 -0.5321582031249976 -1.381875 -0.09014892578125 -0.5321582031249976 -1.382 -0.092742919921875 -0.5321582031249976 -1.382125 -0.092742919921875 -0.5321582031249976 -1.38225 -0.095367431640625 -0.5321582031249976 -1.382375 -0.09796142578125 -0.5321582031249976 -1.3825 -0.09796142578125 -0.5321582031249976 -1.382625 -0.100555419921875 -0.5321582031249976 -1.38275 -0.100555419921875 -0.5321582031249976 -1.382875 -0.103118896484375 -0.5321582031249976 -1.383 -0.105682373046875 -0.5321582031249976 -1.383125 -0.105682373046875 -0.5321582031249976 -1.38325 -0.108245849609375 -0.5321582031249976 -1.383375 -0.108245849609375 -0.5321582031249976 -1.3835 -0.11077880859375 -0.5321582031249976 -1.383625 -0.113311767578125 -0.5321582031249976 -1.38375 -0.113311767578125 -0.5321582031249976 -1.383875 -0.115814208984375 -0.5321582031249976 -1.384 -0.115814208984375 -0.5321582031249976 -1.384125 -0.118316650390625 -0.5321582031249976 -1.38425 -0.12078857421875 -0.5321582031249976 -1.384375 -0.12078857421875 -0.5321582031249976 -1.3845 -0.123291015625 -0.5321582031249976 -1.384625 -0.123291015625 -0.5321582031249976 -1.38475 -0.125762939453125 -0.5321582031249976 -1.384875 -0.128204345703125 -0.5321582031249976 -1.385 -0.128204345703125 -0.5321582031249976 -1.385125 -0.130615234375 -0.5321582031249976 -1.38525 -0.130615234375 -0.5321582031249976 -1.385375 -0.133056640625 -0.5321582031249976 -1.3855 -0.13543701171875 -0.5321582031249976 -1.385625 -0.13543701171875 -0.5321582031249976 -1.38575 -0.137847900390625 -0.5321582031249976 -1.385875 -0.137847900390625 -0.5321582031249976 -1.386 -0.140228271484375 -0.5321582031249976 -1.386125 -0.142578125 -0.5321582031249976 -1.38625 -0.142578125 -0.5321582031249976 -1.386375 -0.144927978515625 -0.5321582031249976 -1.3865 -0.144927978515625 -0.5321582031249976 -1.386625 -0.147247314453125 -0.5321582031249976 -1.38675 -0.149566650390625 -0.5321582031249976 -1.386875 -0.149566650390625 -0.5321582031249976 -1.387 -0.15185546875 -0.5321582031249976 -1.387125 -0.15185546875 -0.5321582031249976 -1.38725 -0.154144287109375 -0.5321582031249976 -1.387375 -0.156402587890625 -0.5321582031249976 -1.3875 -0.156402587890625 -0.5321582031249976 -1.387625 -0.158660888671875 -0.5321582031249976 -1.38775 -0.158660888671875 -0.5321582031249976 -1.387875 -0.160888671875 -0.5321582031249976 -1.388 -0.1630859375 -0.5321582031249976 -1.388125 -0.1630859375 -0.5321582031249976 -1.38825 -0.165283203125 -0.5321582031249976 -1.388375 -0.165283203125 -0.5321582031249976 -1.3885 -0.167449951171875 -0.5321582031249976 -1.388625 -0.16961669921875 -0.5321582031249976 -1.38875 -0.16961669921875 -0.5321582031249976 -1.388875 -0.1717529296875 -0.5321582031249976 -1.389 -0.1717529296875 -0.5321582031249976 -1.389125 -0.173858642578125 -0.5321582031249976 -1.38925 -0.17596435546875 -0.5321582031249976 -1.389375 -0.17596435546875 -0.5321582031249976 -1.3895 -0.17803955078125 -0.5321582031249976 -1.389625 -0.17803955078125 -0.5321582031249976 -1.38975 -0.18011474609375 -0.5321582031249976 -1.389875 -0.182159423828125 -0.5321582031249976 -1.39 -0.182159423828125 -0.5321582031249976 -1.390125 -0.184173583984375 -0.5321582031249976 -1.39025 -0.184173583984375 -0.5321582031249976 -1.390375 -0.1861572265625 -0.5321582031249976 -1.3905 -0.188140869140625 -0.5321582031249976 -1.390625 -0.188140869140625 -0.5321582031249976 -1.39075 -0.19012451171875 -0.5321582031249976 -1.390875 -0.19012451171875 -0.5321582031249976 -1.391 -0.192047119140625 -0.5321582031249976 -1.391125 -0.1939697265625 -0.5321582031249976 -1.39125 -0.1939697265625 -0.5321582031249976 -1.391375 -0.19586181640625 -0.5321582031249976 -1.3915 -0.19586181640625 -0.5321582031249976 -1.391625 -0.19775390625 -0.5321582031249976 -1.39175 -0.1995849609375 -0.5321582031249976 -1.391875 -0.1995849609375 -0.5321582031249976 -1.392 -0.201416015625 -0.5321582031249976 -1.392125 -0.201416015625 -0.5321582031249976 -1.39225 -0.2032470703125 -0.5321582031249976 -1.392375 -0.20501708984375 -0.5321582031249976 -1.3925 -0.20501708984375 -0.5321582031249976 -1.392625 -0.206787109375 -0.5321582031249976 -1.39275 -0.206787109375 -0.5321582031249976 -1.392875 -0.208526611328125 -0.5321582031249976 -1.393 -0.21026611328125 -0.5321582031249976 -1.393125 -0.21026611328125 -0.5321582031249976 -1.39325 -0.211944580078125 -0.5321582031249976 -1.393375 -0.211944580078125 -0.5321582031249976 -1.3935 -0.213623046875 -0.5321582031249976 -1.393625 -0.21527099609375 -0.5321582031249976 -1.39375 -0.21527099609375 -0.5321582031249976 -1.393875 -0.216888427734375 -0.5321582031249976 -1.394 -0.216888427734375 -0.5321582031249976 -1.394125 -0.218505859375 -0.5321582031249976 -1.39425 -0.220062255859375 -0.5321582031249976 -1.394375 -0.220062255859375 -0.5321582031249976 -1.3945 -0.22161865234375 -0.5321582031249976 -1.394625 -0.22161865234375 -0.5321582031249976 -1.39475 -0.22314453125 -0.5321582031249976 -1.394875 -0.22467041015625 -0.5321582031249976 -1.395 -0.22467041015625 -0.5321582031249976 -1.395125 -0.22613525390625 -0.5321582031249976 -1.39525 -0.22613525390625 -0.5321582031249976 -1.395375 -0.22760009765625 -0.5321582031249976 -1.3955 -0.229034423828125 -0.5321582031249976 -1.395625 -0.229034423828125 -0.5321582031249976 -1.39575 -0.230438232421875 -0.5321582031249976 -1.395875 -0.230438232421875 -0.5321582031249976 -1.396 -0.2318115234375 -0.5321582031249976 -1.396125 -0.233184814453125 -0.5321582031249976 -1.39625 -0.233184814453125 -0.5321582031249976 -1.396375 -0.2344970703125 -0.5321582031249976 -1.3965 -0.2344970703125 -0.5321582031249976 -1.396625 -0.235809326171875 -0.5321582031249976 -1.39675 -0.237091064453125 -0.5321582031249976 -1.396875 -0.237091064453125 -0.5321582031249976 -1.397 -0.23834228515625 -0.5321582031249976 -1.397125 -0.23834228515625 -0.5321582031249976 -1.39725 -0.23956298828125 -0.5321582031249976 -1.397375 -0.240753173828125 -0.5321582031249976 -1.3975 -0.240753173828125 -0.5321582031249976 -1.397625 -0.241943359375 -0.5321582031249976 -1.39775 -0.241943359375 -0.5321582031249976 -1.397875 -0.243072509765625 -0.5321582031249976 -1.398 -0.24420166015625 -0.5321582031249976 -1.398125 -0.24420166015625 -0.5321582031249976 -1.39825 -0.24530029296875 -0.5321582031249976 -1.398375 -0.24530029296875 -0.5321582031249976 -1.3985 -0.246368408203125 -0.5321582031249976 -1.398625 -0.247406005859375 -0.5321582031249976 -1.39875 -0.247406005859375 -0.5321582031249976 -1.398875 -0.2484130859375 -0.5321582031249976 -1.399 -0.2484130859375 -0.5321582031249976 -1.399125 -0.2493896484375 -0.5321582031249976 -1.39925 -0.2503662109375 -0.5321582031249976 -1.399375 -0.2503662109375 -0.5321582031249976 -1.3995 -0.25128173828125 -0.5321582031249976 -1.399625 -0.25128173828125 -0.5321582031249976 -1.39975 -0.252197265625 -0.5321582031249976 -1.399875 -0.2530517578125 -0.5321582031249976 -1.4 -0.2530517578125 -0.5321582031249976 -1.400125 -0.25390625 -0.5321582031249976 -1.40025 -0.25390625 -0.5321582031249976 -1.400375 -0.254730224609375 -0.5321582031249976 -1.4005 -0.255523681640625 -0.5321582031249976 -1.400625 -0.255523681640625 -0.5321582031249976 -1.40075 -0.25628662109375 -0.5321582031249976 -1.400875 -0.25628662109375 -0.5321582031249976 -1.401 -0.25701904296875 -0.5321582031249976 -1.401125 -0.257720947265625 -0.5321582031249976 -1.40125 -0.257720947265625 -0.5321582031249976 -1.401375 -0.2584228515625 -0.5321582031249976 -1.4015 -0.2584228515625 -0.5321582031249976 -1.401625 -0.259063720703125 -0.5321582031249976 -1.40175 -0.259674072265625 -0.5321582031249976 -1.401875 -0.259674072265625 -0.5321582031249976 -1.402 -0.26025390625 -0.5321582031249976 -1.402125 -0.26025390625 -0.5321582031249976 -1.40225 -0.260833740234375 -0.5321582031249976 -1.402375 -0.261383056640625 -0.5321582031249976 -1.4025 -0.261383056640625 -0.5321582031249976 -1.402625 -0.261871337890625 -0.5321582031249976 -1.40275 -0.261871337890625 -0.5321582031249976 -1.402875 -0.262359619140625 -0.5321582031249976 -1.403 -0.2628173828125 -0.5321582031249976 -1.403125 -0.2628173828125 -0.5321582031249976 -1.40325 -0.26324462890625 -0.5321582031249976 -1.403375 -0.26324462890625 -0.5321582031249976 -1.4035 -0.26361083984375 -0.5321582031249976 -1.403625 -0.26397705078125 -0.5321582031249976 -1.40375 -0.26397705078125 -0.5321582031249976 -1.403875 -0.264312744140625 -0.5321582031249976 -1.404 -0.264312744140625 -0.5321582031249976 -1.404125 -0.264617919921875 -0.5321582031249976 -1.40425 -0.264892578125 -0.5321582031249976 -1.404375 -0.264892578125 -0.5321582031249976 -1.4045 -0.265167236328125 -0.5321582031249976 -1.404625 -0.265167236328125 -0.5321582031249976 -1.40475 -0.265380859375 -0.5321582031249976 -1.404875 -0.26556396484375 -0.5321582031249976 -1.405 -0.26556396484375 -0.5321582031249976 -1.405125 -0.265716552734375 -0.5321582031249976 -1.40525 -0.265716552734375 -0.5321582031249976 -1.405375 -0.265869140625 -0.5321582031249976 -1.4055 -0.265960693359375 -0.5321582031249976 -1.405625 -0.265960693359375 -0.5321582031249976 -1.40575 -0.266021728515625 -0.5321582031249976 -1.405875 -0.266021728515625 -0.5321582031249976 -1.406 -0.266082763671875 -0.5321582031249976 -1.406125 -0.266082763671875 -0.5321582031249976 -1.40625 -0.266082763671875 -0.5321582031249976 -1.406375 -0.266082763671875 -0.5321582031249976 -1.4065 -0.266082763671875 -0.5321582031249976 -1.406625 -0.266021728515625 -0.5321582031249976 -1.40675 -0.265960693359375 -0.5321582031249976 -1.406875 -0.265960693359375 -0.5321582031249976 -1.407 -0.265869140625 -0.5321582031249976 -1.407125 -0.265869140625 -0.5321582031249976 -1.40725 -0.265716552734375 -0.5321582031249976 -1.407375 -0.26556396484375 -0.5321582031249976 -1.4075 -0.26556396484375 -0.5321582031249976 -1.407625 -0.265380859375 -0.5321582031249976 -1.40775 -0.265380859375 -0.5321582031249976 -1.407875 -0.265167236328125 -0.5321582031249976 -1.408 -0.17303466796875 -0.3476074218749959 -1.408125 -0.17303466796875 -0.3476074218749959 -1.40825 -0.1728515625 -0.3476074218749959 -1.408375 -0.1728515625 -0.3476074218749959 -1.4085 -0.172637939453125 -0.3476074218749959 -1.408625 -0.17242431640625 -0.3476074218749959 -1.40875 -0.17242431640625 -0.3476074218749959 -1.408875 -0.17218017578125 -0.3476074218749959 -1.409 -0.17218017578125 -0.3476074218749959 -1.409125 -0.17193603515625 -0.3476074218749959 -1.40925 -0.171661376953125 -0.3476074218749959 -1.409375 -0.171661376953125 -0.3476074218749959 -1.4095 -0.17138671875 -0.3476074218749959 -1.409625 -0.17138671875 -0.3476074218749959 -1.40975 -0.171051025390625 -0.3476074218749959 -1.409875 -0.17071533203125 -0.3476074218749959 -1.41 -0.17071533203125 -0.3476074218749959 -1.410125 -0.170379638671875 -0.3476074218749959 -1.41025 -0.170379638671875 -0.3476074218749959 -1.410375 -0.170013427734375 -0.3476074218749959 -1.4105 -0.16961669921875 -0.3476074218749959 -1.410625 -0.16961669921875 -0.3476074218749959 -1.41075 -0.169219970703125 -0.3476074218749959 -1.410875 -0.169219970703125 -0.3476074218749959 -1.411 -0.168792724609375 -0.3476074218749959 -1.411125 -0.1683349609375 -0.3476074218749959 -1.41125 -0.1683349609375 -0.3476074218749959 -1.411375 -0.167877197265625 -0.3476074218749959 -1.4115 -0.167877197265625 -0.3476074218749959 -1.411625 -0.167388916015625 -0.3476074218749959 -1.41175 -0.166900634765625 -0.3476074218749959 -1.411875 -0.166900634765625 -0.3476074218749959 -1.412 -0.1663818359375 -0.3476074218749959 -1.412125 -0.1663818359375 -0.3476074218749959 -1.41225 -0.165863037109375 -0.3476074218749959 -1.412375 -0.165313720703125 -0.3476074218749959 -1.4125 -0.165313720703125 -0.3476074218749959 -1.412625 -0.16473388671875 -0.3476074218749959 -1.41275 -0.16473388671875 -0.3476074218749959 -1.412875 -0.16412353515625 -0.3476074218749959 -1.413 -0.163543701171875 -0.3476074218749959 -1.413125 -0.163543701171875 -0.3476074218749959 -1.41325 -0.16290283203125 -0.3476074218749959 -1.413375 -0.16290283203125 -0.3476074218749959 -1.4135 -0.162261962890625 -0.3476074218749959 -1.413625 -0.161590576171875 -0.3476074218749959 -1.41375 -0.161590576171875 -0.3476074218749959 -1.413875 -0.160919189453125 -0.3476074218749959 -1.414 -0.160919189453125 -0.3476074218749959 -1.414125 -0.16021728515625 -0.3476074218749959 -1.41425 -0.159515380859375 -0.3476074218749959 -1.414375 -0.159515380859375 -0.3476074218749959 -1.4145 -0.158782958984375 -0.3476074218749959 -1.414625 -0.158782958984375 -0.3476074218749959 -1.41475 -0.15802001953125 -0.3476074218749959 -1.414875 -0.157257080078125 -0.3476074218749959 -1.415 -0.157257080078125 -0.3476074218749959 -1.415125 -0.156494140625 -0.3476074218749959 -1.41525 -0.156494140625 -0.3476074218749959 -1.415375 -0.155670166015625 -0.3476074218749959 -1.4155 -0.154876708984375 -0.3476074218749959 -1.415625 -0.154876708984375 -0.3476074218749959 -1.41575 -0.154022216796875 -0.3476074218749959 -1.415875 -0.154022216796875 -0.3476074218749959 -1.416 -0.153167724609375 -0.3476074218749959 -1.416125 -0.152313232421875 -0.3476074218749959 -1.41625 -0.152313232421875 -0.3476074218749959 -1.416375 -0.15142822265625 -0.3476074218749959 -1.4165 -0.15142822265625 -0.3476074218749959 -1.416625 -0.1505126953125 -0.3476074218749959 -1.41675 -0.14959716796875 -0.3476074218749959 -1.416875 -0.14959716796875 -0.3476074218749959 -1.417 -0.148681640625 -0.3476074218749959 -1.417125 -0.148681640625 -0.3476074218749959 -1.41725 -0.147705078125 -0.3476074218749959 -1.417375 -0.146759033203125 -0.3476074218749959 -1.4175 -0.146759033203125 -0.3476074218749959 -1.417625 -0.145751953125 -0.3476074218749959 -1.41775 -0.145751953125 -0.3476074218749959 -1.417875 -0.144775390625 -0.3476074218749959 -1.418 -0.14373779296875 -0.3476074218749959 -1.418125 -0.14373779296875 -0.3476074218749959 -1.41825 -0.142730712890625 -0.3476074218749959 -1.418375 -0.142730712890625 -0.3476074218749959 -1.4185 -0.14166259765625 -0.3476074218749959 -1.418625 -0.140625 -0.3476074218749959 -1.41875 -0.140625 -0.3476074218749959 -1.418875 -0.1395263671875 -0.3476074218749959 -1.419 -0.1395263671875 -0.3476074218749959 -1.419125 -0.138427734375 -0.3476074218749959 -1.41925 -0.1373291015625 -0.3476074218749959 -1.419375 -0.1373291015625 -0.3476074218749959 -1.4195 -0.136199951171875 -0.3476074218749959 -1.419625 -0.136199951171875 -0.3476074218749959 -1.41975 -0.13507080078125 -0.3476074218749959 -1.419875 -0.1339111328125 -0.3476074218749959 -1.42 -0.1339111328125 -0.3476074218749959 -1.420125 -0.13275146484375 -0.3476074218749959 -1.42025 -0.13275146484375 -0.3476074218749959 -1.420375 -0.131561279296875 -0.3476074218749959 -1.4205 -0.13037109375 -0.3476074218749959 -1.420625 -0.13037109375 -0.3476074218749959 -1.42075 -0.129150390625 -0.3476074218749959 -1.420875 -0.129150390625 -0.3476074218749959 -1.421 -0.1279296875 -0.3476074218749959 -1.421125 -0.126708984375 -0.3476074218749959 -1.42125 -0.126708984375 -0.3476074218749959 -1.421375 -0.125457763671875 -0.3476074218749959 -1.4215 -0.125457763671875 -0.3476074218749959 -1.421625 -0.124176025390625 -0.3476074218749959 -1.42175 -0.122894287109375 -0.3476074218749959 -1.421875 -0.122894287109375 -0.3476074218749959 -1.422 -0.121612548828125 -0.3476074218749959 -1.422125 -0.121612548828125 -0.3476074218749959 -1.42225 -0.12030029296875 -0.3476074218749959 -1.422375 -0.118988037109375 -0.3476074218749959 -1.4225 -0.118988037109375 -0.3476074218749959 -1.422625 -0.117645263671875 -0.3476074218749959 -1.42275 -0.117645263671875 -0.3476074218749959 -1.422875 -0.116302490234375 -0.3476074218749959 -1.423 -0.114959716796875 -0.3476074218749959 -1.423125 -0.114959716796875 -0.3476074218749959 -1.42325 -0.11358642578125 -0.3476074218749959 -1.423375 -0.11358642578125 -0.3476074218749959 -1.4235 -0.1121826171875 -0.3476074218749959 -1.423625 -0.11077880859375 -0.3476074218749959 -1.42375 -0.11077880859375 -0.3476074218749959 -1.423875 -0.109375 -0.3476074218749959 -1.424 -0.109375 -0.3476074218749959 -1.424125 -0.10797119140625 -0.3476074218749959 -1.42425 -0.106536865234375 -0.3476074218749959 -1.424375 -0.106536865234375 -0.3476074218749959 -1.4245 -0.105072021484375 -0.3476074218749959 -1.424625 -0.105072021484375 -0.3476074218749959 -1.42475 -0.1036376953125 -0.3476074218749959 -1.424875 -0.1021728515625 -0.3476074218749959 -1.425 -0.1021728515625 -0.3476074218749959 -1.425125 -0.100677490234375 -0.3476074218749959 -1.42525 -0.100677490234375 -0.3476074218749959 -1.425375 -0.099212646484375 -0.3476074218749959 -1.4255 -0.097686767578125 -0.3476074218749959 -1.425625 -0.097686767578125 -0.3476074218749959 -1.42575 -0.09619140625 -0.3476074218749959 -1.425875 -0.09619140625 -0.3476074218749959 -1.426 -0.09466552734375 -0.3476074218749959 -1.426125 -0.0931396484375 -0.3476074218749959 -1.42625 -0.0931396484375 -0.3476074218749959 -1.426375 -0.091583251953125 -0.3476074218749959 -1.4265 -0.091583251953125 -0.3476074218749959 -1.426625 -0.090057373046875 -0.3476074218749959 -1.42675 -0.088470458984375 -0.3476074218749959 -1.426875 -0.088470458984375 -0.3476074218749959 -1.427 -0.0869140625 -0.3476074218749959 -1.427125 -0.0869140625 -0.3476074218749959 -1.42725 -0.0853271484375 -0.3476074218749959 -1.427375 -0.083740234375 -0.3476074218749959 -1.4275 -0.083740234375 -0.3476074218749959 -1.427625 -0.0821533203125 -0.3476074218749959 -1.42775 -0.0821533203125 -0.3476074218749959 -1.427875 -0.080535888671875 -0.3476074218749959 -1.428 -0.07891845703125 -0.3476074218749959 -1.428125 -0.07891845703125 -0.3476074218749959 -1.42825 -0.077301025390625 -0.3476074218749959 -1.428375 -0.077301025390625 -0.3476074218749959 -1.4285 -0.075653076171875 -0.3476074218749959 -1.428625 -0.074005126953125 -0.3476074218749959 -1.42875 -0.074005126953125 -0.3476074218749959 -1.428875 -0.072357177734375 -0.3476074218749959 -1.429 -0.072357177734375 -0.3476074218749959 -1.429125 -0.070709228515625 -0.3476074218749959 -1.42925 -0.06903076171875 -0.3476074218749959 -1.429375 -0.06903076171875 -0.3476074218749959 -1.4295 -0.067352294921875 -0.3476074218749959 -1.429625 -0.067352294921875 -0.3476074218749959 -1.42975 -0.065673828125 -0.3476074218749959 -1.429875 -0.063995361328125 -0.3476074218749959 -1.43 -0.063995361328125 -0.3476074218749959 -1.430125 -0.062286376953125 -0.3476074218749959 -1.43025 -0.062286376953125 -0.3476074218749959 -1.430375 -0.060577392578125 -0.3476074218749959 -1.4305 -0.058868408203125 -0.3476074218749959 -1.430625 -0.058868408203125 -0.3476074218749959 -1.43075 -0.057159423828125 -0.3476074218749959 -1.430875 -0.057159423828125 -0.3476074218749959 -1.431 -0.055450439453125 -0.3476074218749959 -1.431125 -0.0537109375 -0.3476074218749959 -1.43125 -0.0537109375 -0.3476074218749959 -1.431375 -0.051971435546875 -0.3476074218749959 -1.4315 -0.051971435546875 -0.3476074218749959 -1.431625 -0.05023193359375 -0.3476074218749959 -1.43175 -0.048492431640625 -0.3476074218749959 -1.431875 -0.048492431640625 -0.3476074218749959 -1.432 -0.0467529296875 -0.3476074218749959 -1.432125 -0.0467529296875 -0.3476074218749959 -1.43225 -0.04498291015625 -0.3476074218749959 -1.432375 -0.043243408203125 -0.3476074218749959 -1.4325 -0.043243408203125 -0.3476074218749959 -1.432625 -0.041473388671875 -0.3476074218749959 -1.43275 -0.041473388671875 -0.3476074218749959 -1.432875 -0.039703369140625 -0.3476074218749959 -1.433 -0.037933349609375 -0.3476074218749959 -1.433125 -0.037933349609375 -0.3476074218749959 -1.43325 -0.0361328125 -0.3476074218749959 -1.433375 -0.0361328125 -0.3476074218749959 -1.4335 -0.03436279296875 -0.3476074218749959 -1.433625 -0.032562255859375 -0.3476074218749959 -1.43375 -0.032562255859375 -0.3476074218749959 -1.433875 -0.030792236328125 -0.3476074218749959 -1.434 -0.030792236328125 -0.3476074218749959 -1.434125 -0.02899169921875 -0.3476074218749959 -1.43425 -0.027191162109375 -0.3476074218749959 -1.434375 -0.027191162109375 -0.3476074218749959 -1.4345 -0.025390625 -0.3476074218749959 -1.434625 -0.025390625 -0.3476074218749959 -1.43475 -0.023590087890625 -0.3476074218749959 -1.434875 -0.02178955078125 -0.3476074218749959 -1.435 -0.02178955078125 -0.3476074218749959 -1.435125 -0.019989013671875 -0.3476074218749959 -1.43525 -0.019989013671875 -0.3476074218749959 -1.435375 -0.0181884765625 -0.3476074218749959 -1.4355 -0.016357421875 -0.3476074218749959 -1.435625 -0.016357421875 -0.3476074218749959 -1.43575 -0.014556884765625 -0.3476074218749959 -1.435875 -0.014556884765625 -0.3476074218749959 -1.436 -0.012725830078125 -0.3476074218749959 -1.436125 -0.01092529296875 -0.3476074218749959 -1.43625 -0.01092529296875 -0.3476074218749959 -1.436375 -0.00909423828125 -0.3476074218749959 -1.4365 -0.00909423828125 -0.3476074218749959 -1.436625 -0.007293701171875 -0.3476074218749959 -1.43675 -0.005462646484375 -0.3476074218749959 -1.436875 -0.005462646484375 -0.3476074218749959 -1.437 -0.003662109375 -0.3476074218749959 -1.437125 -0.003662109375 -0.3476074218749959 -1.43725 -0.0018310546875 -0.3476074218749959 +1.375125 -0.00311279296875 -0.5998974609374999 +1.37525 -0.00311279296875 -0.5998974609374999 +1.375375 -0.006256103515625 -0.5998974609374999 +1.3755 -0.0093994140625 -0.5998974609374999 +1.375625 -0.0093994140625 -0.5998974609374999 +1.37575 -0.012542724609375 -0.5998974609374999 +1.375875 -0.012542724609375 -0.5998974609374999 +1.376 -0.013916015625 -0.5321582031249976 +1.376125 -0.016693115234375 -0.5321582031249976 +1.37625 -0.016693115234375 -0.5321582031249976 +1.376375 -0.01947021484375 -0.5321582031249976 +1.3765 -0.01947021484375 -0.5321582031249976 +1.376625 -0.022247314453125 -0.5321582031249976 +1.37675 -0.0250244140625 -0.5321582031249976 +1.376875 -0.0250244140625 -0.5321582031249976 +1.377 -0.027801513671875 -0.5321582031249976 +1.377125 -0.027801513671875 -0.5321582031249976 +1.37725 -0.03057861328125 -0.5321582031249976 +1.377375 -0.0333251953125 -0.5321582031249976 +1.3775 -0.0333251953125 -0.5321582031249976 +1.377625 -0.036102294921875 -0.5321582031249976 +1.37775 -0.036102294921875 -0.5321582031249976 +1.377875 -0.038848876953125 -0.5321582031249976 +1.378 -0.041595458984375 -0.5321582031249976 +1.378125 -0.041595458984375 -0.5321582031249976 +1.37825 -0.044342041015625 -0.5321582031249976 +1.378375 -0.044342041015625 -0.5321582031249976 +1.3785 -0.047088623046875 -0.5321582031249976 +1.378625 -0.049835205078125 -0.5321582031249976 +1.37875 -0.049835205078125 -0.5321582031249976 +1.378875 -0.052581787109375 -0.5321582031249976 +1.379 -0.052581787109375 -0.5321582031249976 +1.379125 -0.0552978515625 -0.5321582031249976 +1.37925 -0.058013916015625 -0.5321582031249976 +1.379375 -0.058013916015625 -0.5321582031249976 +1.3795 -0.06072998046875 -0.5321582031249976 +1.379625 -0.06072998046875 -0.5321582031249976 +1.37975 -0.063446044921875 -0.5321582031249976 +1.379875 -0.066162109375 -0.5321582031249976 +1.38 -0.066162109375 -0.5321582031249976 +1.380125 -0.06884765625 -0.5321582031249976 +1.38025 -0.06884765625 -0.5321582031249976 +1.380375 -0.071533203125 -0.5321582031249976 +1.3805 -0.07421875 -0.5321582031249976 +1.380625 -0.07421875 -0.5321582031249976 +1.38075 -0.076873779296875 -0.5321582031249976 +1.380875 -0.076873779296875 -0.5321582031249976 +1.381 -0.079559326171875 -0.5321582031249976 +1.381125 -0.08221435546875 -0.5321582031249976 +1.38125 -0.08221435546875 -0.5321582031249976 +1.381375 -0.0848388671875 -0.5321582031249976 +1.3815 -0.0848388671875 -0.5321582031249976 +1.381625 -0.087493896484375 -0.5321582031249976 +1.38175 -0.090118408203125 -0.5321582031249976 +1.381875 -0.090118408203125 -0.5321582031249976 +1.382 -0.09271240234375 -0.5321582031249976 +1.382125 -0.09271240234375 -0.5321582031249976 +1.38225 -0.0953369140625 -0.5321582031249976 +1.382375 -0.097930908203125 -0.5321582031249976 +1.3825 -0.097930908203125 -0.5321582031249976 +1.382625 -0.10052490234375 -0.5321582031249976 +1.38275 -0.10052490234375 -0.5321582031249976 +1.382875 -0.10308837890625 -0.5321582031249976 +1.383 -0.10565185546875 -0.5321582031249976 +1.383125 -0.10565185546875 -0.5321582031249976 +1.38325 -0.10821533203125 -0.5321582031249976 +1.383375 -0.10821533203125 -0.5321582031249976 +1.3835 -0.110748291015625 -0.5321582031249976 +1.383625 -0.11328125 -0.5321582031249976 +1.38375 -0.11328125 -0.5321582031249976 +1.383875 -0.11578369140625 -0.5321582031249976 +1.384 -0.11578369140625 -0.5321582031249976 +1.384125 -0.1182861328125 -0.5321582031249976 +1.38425 -0.120758056640625 -0.5321582031249976 +1.384375 -0.120758056640625 -0.5321582031249976 +1.3845 -0.123260498046875 -0.5321582031249976 +1.384625 -0.123260498046875 -0.5321582031249976 +1.38475 -0.125732421875 -0.5321582031249976 +1.384875 -0.128173828125 -0.5321582031249976 +1.385 -0.128173828125 -0.5321582031249976 +1.385125 -0.130584716796875 -0.5321582031249976 +1.38525 -0.130584716796875 -0.5321582031249976 +1.385375 -0.133026123046875 -0.5321582031249976 +1.3855 -0.135406494140625 -0.5321582031249976 +1.385625 -0.135406494140625 -0.5321582031249976 +1.38575 -0.1378173828125 -0.5321582031249976 +1.385875 -0.1378173828125 -0.5321582031249976 +1.386 -0.14019775390625 -0.5321582031249976 +1.386125 -0.142547607421875 -0.5321582031249976 +1.38625 -0.142547607421875 -0.5321582031249976 +1.386375 -0.1448974609375 -0.5321582031249976 +1.3865 -0.1448974609375 -0.5321582031249976 +1.386625 -0.147216796875 -0.5321582031249976 +1.38675 -0.1495361328125 -0.5321582031249976 +1.386875 -0.1495361328125 -0.5321582031249976 +1.387 -0.151824951171875 -0.5321582031249976 +1.387125 -0.151824951171875 -0.5321582031249976 +1.38725 -0.15411376953125 -0.5321582031249976 +1.387375 -0.1563720703125 -0.5321582031249976 +1.3875 -0.1563720703125 -0.5321582031249976 +1.387625 -0.15863037109375 -0.5321582031249976 +1.38775 -0.15863037109375 -0.5321582031249976 +1.387875 -0.160858154296875 -0.5321582031249976 +1.388 -0.163055419921875 -0.5321582031249976 +1.388125 -0.163055419921875 -0.5321582031249976 +1.38825 -0.165252685546875 -0.5321582031249976 +1.388375 -0.165252685546875 -0.5321582031249976 +1.3885 -0.16741943359375 -0.5321582031249976 +1.388625 -0.169586181640625 -0.5321582031249976 +1.38875 -0.169586181640625 -0.5321582031249976 +1.388875 -0.171722412109375 -0.5321582031249976 +1.389 -0.171722412109375 -0.5321582031249976 +1.389125 -0.173828125 -0.5321582031249976 +1.38925 -0.175933837890625 -0.5321582031249976 +1.389375 -0.175933837890625 -0.5321582031249976 +1.3895 -0.178009033203125 -0.5321582031249976 +1.389625 -0.178009033203125 -0.5321582031249976 +1.38975 -0.180084228515625 -0.5321582031249976 +1.389875 -0.18212890625 -0.5321582031249976 +1.39 -0.18212890625 -0.5321582031249976 +1.390125 -0.18414306640625 -0.5321582031249976 +1.39025 -0.18414306640625 -0.5321582031249976 +1.390375 -0.186126708984375 -0.5321582031249976 +1.3905 -0.1881103515625 -0.5321582031249976 +1.390625 -0.1881103515625 -0.5321582031249976 +1.39075 -0.190093994140625 -0.5321582031249976 +1.390875 -0.190093994140625 -0.5321582031249976 +1.391 -0.1920166015625 -0.5321582031249976 +1.391125 -0.193939208984375 -0.5321582031249976 +1.39125 -0.193939208984375 -0.5321582031249976 +1.391375 -0.195831298828125 -0.5321582031249976 +1.3915 -0.195831298828125 -0.5321582031249976 +1.391625 -0.197723388671875 -0.5321582031249976 +1.39175 -0.199554443359375 -0.5321582031249976 +1.391875 -0.199554443359375 -0.5321582031249976 +1.392 -0.201385498046875 -0.5321582031249976 +1.392125 -0.201385498046875 -0.5321582031249976 +1.39225 -0.203216552734375 -0.5321582031249976 +1.392375 -0.204986572265625 -0.5321582031249976 +1.3925 -0.204986572265625 -0.5321582031249976 +1.392625 -0.206756591796875 -0.5321582031249976 +1.39275 -0.206756591796875 -0.5321582031249976 +1.392875 -0.20849609375 -0.5321582031249976 +1.393 -0.210235595703125 -0.5321582031249976 +1.393125 -0.210235595703125 -0.5321582031249976 +1.39325 -0.2119140625 -0.5321582031249976 +1.393375 -0.2119140625 -0.5321582031249976 +1.3935 -0.213592529296875 -0.5321582031249976 +1.393625 -0.215240478515625 -0.5321582031249976 +1.39375 -0.215240478515625 -0.5321582031249976 +1.393875 -0.21685791015625 -0.5321582031249976 +1.394 -0.21685791015625 -0.5321582031249976 +1.394125 -0.218475341796875 -0.5321582031249976 +1.39425 -0.22003173828125 -0.5321582031249976 +1.394375 -0.22003173828125 -0.5321582031249976 +1.3945 -0.221588134765625 -0.5321582031249976 +1.394625 -0.221588134765625 -0.5321582031249976 +1.39475 -0.223114013671875 -0.5321582031249976 +1.394875 -0.224639892578125 -0.5321582031249976 +1.395 -0.224639892578125 -0.5321582031249976 +1.395125 -0.226104736328125 -0.5321582031249976 +1.39525 -0.226104736328125 -0.5321582031249976 +1.395375 -0.227569580078125 -0.5321582031249976 +1.3955 -0.22900390625 -0.5321582031249976 +1.395625 -0.22900390625 -0.5321582031249976 +1.39575 -0.23040771484375 -0.5321582031249976 +1.395875 -0.23040771484375 -0.5321582031249976 +1.396 -0.231781005859375 -0.5321582031249976 +1.396125 -0.233154296875 -0.5321582031249976 +1.39625 -0.233154296875 -0.5321582031249976 +1.396375 -0.234466552734375 -0.5321582031249976 +1.3965 -0.234466552734375 -0.5321582031249976 +1.396625 -0.23577880859375 -0.5321582031249976 +1.39675 -0.237060546875 -0.5321582031249976 +1.396875 -0.237060546875 -0.5321582031249976 +1.397 -0.238311767578125 -0.5321582031249976 +1.397125 -0.238311767578125 -0.5321582031249976 +1.39725 -0.239532470703125 -0.5321582031249976 +1.397375 -0.24072265625 -0.5321582031249976 +1.3975 -0.24072265625 -0.5321582031249976 +1.397625 -0.241912841796875 -0.5321582031249976 +1.39775 -0.241912841796875 -0.5321582031249976 +1.397875 -0.2430419921875 -0.5321582031249976 +1.398 -0.244171142578125 -0.5321582031249976 +1.398125 -0.244171142578125 -0.5321582031249976 +1.39825 -0.245269775390625 -0.5321582031249976 +1.398375 -0.245269775390625 -0.5321582031249976 +1.3985 -0.246337890625 -0.5321582031249976 +1.398625 -0.24737548828125 -0.5321582031249976 +1.39875 -0.24737548828125 -0.5321582031249976 +1.398875 -0.248382568359375 -0.5321582031249976 +1.399 -0.248382568359375 -0.5321582031249976 +1.399125 -0.249359130859375 -0.5321582031249976 +1.39925 -0.250335693359375 -0.5321582031249976 +1.399375 -0.250335693359375 -0.5321582031249976 +1.3995 -0.251251220703125 -0.5321582031249976 +1.399625 -0.251251220703125 -0.5321582031249976 +1.39975 -0.252166748046875 -0.5321582031249976 +1.399875 -0.253021240234375 -0.5321582031249976 +1.4 -0.253021240234375 -0.5321582031249976 +1.400125 -0.253875732421875 -0.5321582031249976 +1.40025 -0.253875732421875 -0.5321582031249976 +1.400375 -0.25469970703125 -0.5321582031249976 +1.4005 -0.2554931640625 -0.5321582031249976 +1.400625 -0.2554931640625 -0.5321582031249976 +1.40075 -0.256256103515625 -0.5321582031249976 +1.400875 -0.256256103515625 -0.5321582031249976 +1.401 -0.256988525390625 -0.5321582031249976 +1.401125 -0.2576904296875 -0.5321582031249976 +1.40125 -0.2576904296875 -0.5321582031249976 +1.401375 -0.258392333984375 -0.5321582031249976 +1.4015 -0.258392333984375 -0.5321582031249976 +1.401625 -0.259033203125 -0.5321582031249976 +1.40175 -0.2596435546875 -0.5321582031249976 +1.401875 -0.2596435546875 -0.5321582031249976 +1.402 -0.260223388671875 -0.5321582031249976 +1.402125 -0.260223388671875 -0.5321582031249976 +1.40225 -0.26080322265625 -0.5321582031249976 +1.402375 -0.2613525390625 -0.5321582031249976 +1.4025 -0.2613525390625 -0.5321582031249976 +1.402625 -0.2618408203125 -0.5321582031249976 +1.40275 -0.2618408203125 -0.5321582031249976 +1.402875 -0.2623291015625 -0.5321582031249976 +1.403 -0.262786865234375 -0.5321582031249976 +1.403125 -0.262786865234375 -0.5321582031249976 +1.40325 -0.263214111328125 -0.5321582031249976 +1.403375 -0.263214111328125 -0.5321582031249976 +1.4035 -0.263580322265625 -0.5321582031249976 +1.403625 -0.263946533203125 -0.5321582031249976 +1.40375 -0.263946533203125 -0.5321582031249976 +1.403875 -0.2642822265625 -0.5321582031249976 +1.404 -0.2642822265625 -0.5321582031249976 +1.404125 -0.26458740234375 -0.5321582031249976 +1.40425 -0.264862060546875 -0.5321582031249976 +1.404375 -0.264862060546875 -0.5321582031249976 +1.4045 -0.26513671875 -0.5321582031249976 +1.404625 -0.26513671875 -0.5321582031249976 +1.40475 -0.265350341796875 -0.5321582031249976 +1.404875 -0.265533447265625 -0.5321582031249976 +1.405 -0.265533447265625 -0.5321582031249976 +1.405125 -0.26568603515625 -0.5321582031249976 +1.40525 -0.26568603515625 -0.5321582031249976 +1.405375 -0.265838623046875 -0.5321582031249976 +1.4055 -0.26593017578125 -0.5321582031249976 +1.405625 -0.26593017578125 -0.5321582031249976 +1.40575 -0.2659912109375 -0.5321582031249976 +1.405875 -0.2659912109375 -0.5321582031249976 +1.406 -0.26605224609375 -0.5321582031249976 +1.406125 -0.26605224609375 -0.5321582031249976 +1.40625 -0.26605224609375 -0.5321582031249976 +1.406375 -0.26605224609375 -0.5321582031249976 +1.4065 -0.26605224609375 -0.5321582031249976 +1.406625 -0.2659912109375 -0.5321582031249976 +1.40675 -0.26593017578125 -0.5321582031249976 +1.406875 -0.26593017578125 -0.5321582031249976 +1.407 -0.265838623046875 -0.5321582031249976 +1.407125 -0.265838623046875 -0.5321582031249976 +1.40725 -0.26568603515625 -0.5321582031249976 +1.407375 -0.265533447265625 -0.5321582031249976 +1.4075 -0.265533447265625 -0.5321582031249976 +1.407625 -0.265350341796875 -0.5321582031249976 +1.40775 -0.265350341796875 -0.5321582031249976 +1.407875 -0.26513671875 -0.5321582031249976 +1.408 -0.173004150390625 -0.3476074218749959 +1.408125 -0.173004150390625 -0.3476074218749959 +1.40825 -0.172821044921875 -0.3476074218749959 +1.408375 -0.172821044921875 -0.3476074218749959 +1.4085 -0.172607421875 -0.3476074218749959 +1.408625 -0.172393798828125 -0.3476074218749959 +1.40875 -0.172393798828125 -0.3476074218749959 +1.408875 -0.172149658203125 -0.3476074218749959 +1.409 -0.172149658203125 -0.3476074218749959 +1.409125 -0.171905517578125 -0.3476074218749959 +1.40925 -0.171630859375 -0.3476074218749959 +1.409375 -0.171630859375 -0.3476074218749959 +1.4095 -0.171356201171875 -0.3476074218749959 +1.409625 -0.171356201171875 -0.3476074218749959 +1.40975 -0.1710205078125 -0.3476074218749959 +1.409875 -0.170684814453125 -0.3476074218749959 +1.41 -0.170684814453125 -0.3476074218749959 +1.410125 -0.17034912109375 -0.3476074218749959 +1.41025 -0.17034912109375 -0.3476074218749959 +1.410375 -0.16998291015625 -0.3476074218749959 +1.4105 -0.169586181640625 -0.3476074218749959 +1.410625 -0.169586181640625 -0.3476074218749959 +1.41075 -0.169189453125 -0.3476074218749959 +1.410875 -0.169189453125 -0.3476074218749959 +1.411 -0.16876220703125 -0.3476074218749959 +1.411125 -0.168304443359375 -0.3476074218749959 +1.41125 -0.168304443359375 -0.3476074218749959 +1.411375 -0.1678466796875 -0.3476074218749959 +1.4115 -0.1678466796875 -0.3476074218749959 +1.411625 -0.1673583984375 -0.3476074218749959 +1.41175 -0.1668701171875 -0.3476074218749959 +1.411875 -0.1668701171875 -0.3476074218749959 +1.412 -0.166351318359375 -0.3476074218749959 +1.412125 -0.166351318359375 -0.3476074218749959 +1.41225 -0.16583251953125 -0.3476074218749959 +1.412375 -0.165283203125 -0.3476074218749959 +1.4125 -0.165283203125 -0.3476074218749959 +1.412625 -0.164703369140625 -0.3476074218749959 +1.41275 -0.164703369140625 -0.3476074218749959 +1.412875 -0.164093017578125 -0.3476074218749959 +1.413 -0.16351318359375 -0.3476074218749959 +1.413125 -0.16351318359375 -0.3476074218749959 +1.41325 -0.162872314453125 -0.3476074218749959 +1.413375 -0.162872314453125 -0.3476074218749959 +1.4135 -0.1622314453125 -0.3476074218749959 +1.413625 -0.16156005859375 -0.3476074218749959 +1.41375 -0.16156005859375 -0.3476074218749959 +1.413875 -0.160888671875 -0.3476074218749959 +1.414 -0.160888671875 -0.3476074218749959 +1.414125 -0.160186767578125 -0.3476074218749959 +1.41425 -0.15948486328125 -0.3476074218749959 +1.414375 -0.15948486328125 -0.3476074218749959 +1.4145 -0.15875244140625 -0.3476074218749959 +1.414625 -0.15875244140625 -0.3476074218749959 +1.41475 -0.157989501953125 -0.3476074218749959 +1.414875 -0.1572265625 -0.3476074218749959 +1.415 -0.1572265625 -0.3476074218749959 +1.415125 -0.156463623046875 -0.3476074218749959 +1.41525 -0.156463623046875 -0.3476074218749959 +1.415375 -0.1556396484375 -0.3476074218749959 +1.4155 -0.15484619140625 -0.3476074218749959 +1.415625 -0.15484619140625 -0.3476074218749959 +1.41575 -0.15399169921875 -0.3476074218749959 +1.415875 -0.15399169921875 -0.3476074218749959 +1.416 -0.15313720703125 -0.3476074218749959 +1.416125 -0.15228271484375 -0.3476074218749959 +1.41625 -0.15228271484375 -0.3476074218749959 +1.416375 -0.151397705078125 -0.3476074218749959 +1.4165 -0.151397705078125 -0.3476074218749959 +1.416625 -0.150482177734375 -0.3476074218749959 +1.41675 -0.149566650390625 -0.3476074218749959 +1.416875 -0.149566650390625 -0.3476074218749959 +1.417 -0.148651123046875 -0.3476074218749959 +1.417125 -0.148651123046875 -0.3476074218749959 +1.41725 -0.147674560546875 -0.3476074218749959 +1.417375 -0.146728515625 -0.3476074218749959 +1.4175 -0.146728515625 -0.3476074218749959 +1.417625 -0.145721435546875 -0.3476074218749959 +1.41775 -0.145721435546875 -0.3476074218749959 +1.417875 -0.144744873046875 -0.3476074218749959 +1.418 -0.143707275390625 -0.3476074218749959 +1.418125 -0.143707275390625 -0.3476074218749959 +1.41825 -0.1427001953125 -0.3476074218749959 +1.418375 -0.1427001953125 -0.3476074218749959 +1.4185 -0.141632080078125 -0.3476074218749959 +1.418625 -0.140594482421875 -0.3476074218749959 +1.41875 -0.140594482421875 -0.3476074218749959 +1.418875 -0.139495849609375 -0.3476074218749959 +1.419 -0.139495849609375 -0.3476074218749959 +1.419125 -0.138397216796875 -0.3476074218749959 +1.41925 -0.137298583984375 -0.3476074218749959 +1.419375 -0.137298583984375 -0.3476074218749959 +1.4195 -0.13616943359375 -0.3476074218749959 +1.419625 -0.13616943359375 -0.3476074218749959 +1.41975 -0.135040283203125 -0.3476074218749959 +1.419875 -0.133880615234375 -0.3476074218749959 +1.42 -0.133880615234375 -0.3476074218749959 +1.420125 -0.132720947265625 -0.3476074218749959 +1.42025 -0.132720947265625 -0.3476074218749959 +1.420375 -0.13153076171875 -0.3476074218749959 +1.4205 -0.130340576171875 -0.3476074218749959 +1.420625 -0.130340576171875 -0.3476074218749959 +1.42075 -0.129119873046875 -0.3476074218749959 +1.420875 -0.129119873046875 -0.3476074218749959 +1.421 -0.127899169921875 -0.3476074218749959 +1.421125 -0.126678466796875 -0.3476074218749959 +1.42125 -0.126678466796875 -0.3476074218749959 +1.421375 -0.12542724609375 -0.3476074218749959 +1.4215 -0.12542724609375 -0.3476074218749959 +1.421625 -0.1241455078125 -0.3476074218749959 +1.42175 -0.12286376953125 -0.3476074218749959 +1.421875 -0.12286376953125 -0.3476074218749959 +1.422 -0.12158203125 -0.3476074218749959 +1.422125 -0.12158203125 -0.3476074218749959 +1.42225 -0.120269775390625 -0.3476074218749959 +1.422375 -0.11895751953125 -0.3476074218749959 +1.4225 -0.11895751953125 -0.3476074218749959 +1.422625 -0.11761474609375 -0.3476074218749959 +1.42275 -0.11761474609375 -0.3476074218749959 +1.422875 -0.11627197265625 -0.3476074218749959 +1.423 -0.11492919921875 -0.3476074218749959 +1.423125 -0.11492919921875 -0.3476074218749959 +1.42325 -0.113555908203125 -0.3476074218749959 +1.423375 -0.113555908203125 -0.3476074218749959 +1.4235 -0.112152099609375 -0.3476074218749959 +1.423625 -0.110748291015625 -0.3476074218749959 +1.42375 -0.110748291015625 -0.3476074218749959 +1.423875 -0.109344482421875 -0.3476074218749959 +1.424 -0.109344482421875 -0.3476074218749959 +1.424125 -0.107940673828125 -0.3476074218749959 +1.42425 -0.10650634765625 -0.3476074218749959 +1.424375 -0.10650634765625 -0.3476074218749959 +1.4245 -0.10504150390625 -0.3476074218749959 +1.424625 -0.10504150390625 -0.3476074218749959 +1.42475 -0.103607177734375 -0.3476074218749959 +1.424875 -0.102142333984375 -0.3476074218749959 +1.425 -0.102142333984375 -0.3476074218749959 +1.425125 -0.10064697265625 -0.3476074218749959 +1.42525 -0.10064697265625 -0.3476074218749959 +1.425375 -0.09918212890625 -0.3476074218749959 +1.4255 -0.09765625 -0.3476074218749959 +1.425625 -0.09765625 -0.3476074218749959 +1.42575 -0.096160888671875 -0.3476074218749959 +1.425875 -0.096160888671875 -0.3476074218749959 +1.426 -0.094635009765625 -0.3476074218749959 +1.426125 -0.093109130859375 -0.3476074218749959 +1.42625 -0.093109130859375 -0.3476074218749959 +1.426375 -0.091552734375 -0.3476074218749959 +1.4265 -0.091552734375 -0.3476074218749959 +1.426625 -0.09002685546875 -0.3476074218749959 +1.42675 -0.08843994140625 -0.3476074218749959 +1.426875 -0.08843994140625 -0.3476074218749959 +1.427 -0.086883544921875 -0.3476074218749959 +1.427125 -0.086883544921875 -0.3476074218749959 +1.42725 -0.085296630859375 -0.3476074218749959 +1.427375 -0.083709716796875 -0.3476074218749959 +1.4275 -0.083709716796875 -0.3476074218749959 +1.427625 -0.082122802734375 -0.3476074218749959 +1.42775 -0.082122802734375 -0.3476074218749959 +1.427875 -0.08050537109375 -0.3476074218749959 +1.428 -0.078887939453125 -0.3476074218749959 +1.428125 -0.078887939453125 -0.3476074218749959 +1.42825 -0.0772705078125 -0.3476074218749959 +1.428375 -0.0772705078125 -0.3476074218749959 +1.4285 -0.07562255859375 -0.3476074218749959 +1.428625 -0.073974609375 -0.3476074218749959 +1.42875 -0.073974609375 -0.3476074218749959 +1.428875 -0.07232666015625 -0.3476074218749959 +1.429 -0.07232666015625 -0.3476074218749959 +1.429125 -0.0706787109375 -0.3476074218749959 +1.42925 -0.069000244140625 -0.3476074218749959 +1.429375 -0.069000244140625 -0.3476074218749959 +1.4295 -0.06732177734375 -0.3476074218749959 +1.429625 -0.06732177734375 -0.3476074218749959 +1.42975 -0.065643310546875 -0.3476074218749959 +1.429875 -0.06396484375 -0.3476074218749959 +1.43 -0.06396484375 -0.3476074218749959 +1.430125 -0.062255859375 -0.3476074218749959 +1.43025 -0.062255859375 -0.3476074218749959 +1.430375 -0.060546875 -0.3476074218749959 +1.4305 -0.058837890625 -0.3476074218749959 +1.430625 -0.058837890625 -0.3476074218749959 +1.43075 -0.05712890625 -0.3476074218749959 +1.430875 -0.05712890625 -0.3476074218749959 +1.431 -0.055419921875 -0.3476074218749959 +1.431125 -0.053680419921875 -0.3476074218749959 +1.43125 -0.053680419921875 -0.3476074218749959 +1.431375 -0.05194091796875 -0.3476074218749959 +1.4315 -0.05194091796875 -0.3476074218749959 +1.431625 -0.050201416015625 -0.3476074218749959 +1.43175 -0.0484619140625 -0.3476074218749959 +1.431875 -0.0484619140625 -0.3476074218749959 +1.432 -0.046722412109375 -0.3476074218749959 +1.432125 -0.046722412109375 -0.3476074218749959 +1.43225 -0.044952392578125 -0.3476074218749959 +1.432375 -0.043212890625 -0.3476074218749959 +1.4325 -0.043212890625 -0.3476074218749959 +1.432625 -0.04144287109375 -0.3476074218749959 +1.43275 -0.04144287109375 -0.3476074218749959 +1.432875 -0.0396728515625 -0.3476074218749959 +1.433 -0.03790283203125 -0.3476074218749959 +1.433125 -0.03790283203125 -0.3476074218749959 +1.43325 -0.036102294921875 -0.3476074218749959 +1.433375 -0.036102294921875 -0.3476074218749959 +1.4335 -0.034332275390625 -0.3476074218749959 +1.433625 -0.03253173828125 -0.3476074218749959 +1.43375 -0.03253173828125 -0.3476074218749959 +1.433875 -0.03076171875 -0.3476074218749959 +1.434 -0.03076171875 -0.3476074218749959 +1.434125 -0.028961181640625 -0.3476074218749959 +1.43425 -0.02716064453125 -0.3476074218749959 +1.434375 -0.02716064453125 -0.3476074218749959 +1.4345 -0.025360107421875 -0.3476074218749959 +1.434625 -0.025360107421875 -0.3476074218749959 +1.43475 -0.0235595703125 -0.3476074218749959 +1.434875 -0.021759033203125 -0.3476074218749959 +1.435 -0.021759033203125 -0.3476074218749959 +1.435125 -0.01995849609375 -0.3476074218749959 +1.43525 -0.01995849609375 -0.3476074218749959 +1.435375 -0.018157958984375 -0.3476074218749959 +1.4355 -0.016326904296875 -0.3476074218749959 +1.435625 -0.016326904296875 -0.3476074218749959 +1.43575 -0.0145263671875 -0.3476074218749959 +1.435875 -0.0145263671875 -0.3476074218749959 +1.436 -0.0126953125 -0.3476074218749959 +1.436125 -0.010894775390625 -0.3476074218749959 +1.43625 -0.010894775390625 -0.3476074218749959 +1.436375 -0.009063720703125 -0.3476074218749959 +1.4365 -0.009063720703125 -0.3476074218749959 +1.436625 -0.00726318359375 -0.3476074218749959 +1.43675 -0.00543212890625 -0.3476074218749959 +1.436875 -0.00543212890625 -0.3476074218749959 +1.437 -0.003631591796875 -0.3476074218749959 +1.437125 -0.003631591796875 -0.3476074218749959 +1.43725 -0.001800537109375 -0.3476074218749959 1.437375 0.0 -0.3476074218749959 1.4375 0.0 -0.3476074218749959 1.437625 0.001800537109375 -0.3476074218749959 @@ -11774,229 +11774,229 @@ 1.471625 0.03741455078125 -0.07568847656249394 1.47175 0.037353515625 -0.07568847656249394 1.471875 0.037353515625 -0.07568847656249394 -1.472 -0.118408203125 0.2401757812500067 -1.472125 -0.118408203125 0.2401757812500067 -1.47225 -0.118194580078125 0.2401757812500067 -1.472375 -0.117950439453125 0.2401757812500067 -1.4725 -0.117950439453125 0.2401757812500067 -1.472625 -0.117706298828125 0.2401757812500067 -1.47275 -0.117706298828125 0.2401757812500067 -1.472875 -0.117462158203125 0.2401757812500067 -1.473 -0.1171875 0.2401757812500067 -1.473125 -0.1171875 0.2401757812500067 -1.47325 -0.116912841796875 0.2401757812500067 -1.473375 -0.116912841796875 0.2401757812500067 -1.4735 -0.116607666015625 0.2401757812500067 -1.473625 -0.116302490234375 0.2401757812500067 -1.47375 -0.116302490234375 0.2401757812500067 -1.473875 -0.115997314453125 0.2401757812500067 -1.474 -0.115997314453125 0.2401757812500067 -1.474125 -0.11566162109375 0.2401757812500067 -1.47425 -0.115325927734375 0.2401757812500067 -1.474375 -0.115325927734375 0.2401757812500067 -1.4745 -0.114959716796875 0.2401757812500067 -1.474625 -0.114959716796875 0.2401757812500067 -1.47475 -0.114593505859375 0.2401757812500067 -1.474875 -0.11419677734375 0.2401757812500067 -1.475 -0.11419677734375 0.2401757812500067 -1.475125 -0.113800048828125 0.2401757812500067 -1.47525 -0.113800048828125 0.2401757812500067 -1.475375 -0.1134033203125 0.2401757812500067 -1.4755 -0.11297607421875 0.2401757812500067 -1.475625 -0.11297607421875 0.2401757812500067 -1.47575 -0.112548828125 0.2401757812500067 -1.475875 -0.112548828125 0.2401757812500067 -1.476 -0.112091064453125 0.2401757812500067 -1.476125 -0.11163330078125 0.2401757812500067 -1.47625 -0.11163330078125 0.2401757812500067 -1.476375 -0.111175537109375 0.2401757812500067 -1.4765 -0.111175537109375 0.2401757812500067 -1.476625 -0.110687255859375 0.2401757812500067 -1.47675 -0.110198974609375 0.2401757812500067 -1.476875 -0.110198974609375 0.2401757812500067 -1.477 -0.109710693359375 0.2401757812500067 -1.477125 -0.109710693359375 0.2401757812500067 -1.47725 -0.10919189453125 0.2401757812500067 -1.477375 -0.108642578125 0.2401757812500067 -1.4775 -0.108642578125 0.2401757812500067 -1.477625 -0.108123779296875 0.2401757812500067 -1.47775 -0.108123779296875 0.2401757812500067 -1.477875 -0.1075439453125 0.2401757812500067 -1.478 -0.10699462890625 0.2401757812500067 -1.478125 -0.10699462890625 0.2401757812500067 -1.47825 -0.106414794921875 0.2401757812500067 -1.478375 -0.106414794921875 0.2401757812500067 -1.4785 -0.1058349609375 0.2401757812500067 -1.478625 -0.105224609375 0.2401757812500067 -1.47875 -0.105224609375 0.2401757812500067 -1.478875 -0.1046142578125 0.2401757812500067 -1.479 -0.1046142578125 0.2401757812500067 -1.479125 -0.10400390625 0.2401757812500067 -1.47925 -0.103363037109375 0.2401757812500067 -1.479375 -0.103363037109375 0.2401757812500067 -1.4795 -0.10272216796875 0.2401757812500067 -1.479625 -0.10272216796875 0.2401757812500067 -1.47975 -0.10205078125 0.2401757812500067 -1.479875 -0.10137939453125 0.2401757812500067 -1.48 -0.10137939453125 0.2401757812500067 -1.480125 -0.1007080078125 0.2401757812500067 -1.48025 -0.1007080078125 0.2401757812500067 -1.480375 -0.100006103515625 0.2401757812500067 -1.4805 -0.09930419921875 0.2401757812500067 -1.480625 -0.09930419921875 0.2401757812500067 -1.48075 -0.098602294921875 0.2401757812500067 -1.480875 -0.098602294921875 0.2401757812500067 -1.481 -0.097869873046875 0.2401757812500067 -1.481125 -0.097137451171875 0.2401757812500067 -1.48125 -0.097137451171875 0.2401757812500067 -1.481375 -0.096405029296875 0.2401757812500067 -1.4815 -0.096405029296875 0.2401757812500067 -1.481625 -0.09564208984375 0.2401757812500067 -1.48175 -0.094879150390625 0.2401757812500067 -1.481875 -0.094879150390625 0.2401757812500067 -1.482 -0.0941162109375 0.2401757812500067 -1.482125 -0.0941162109375 0.2401757812500067 -1.48225 -0.09332275390625 0.2401757812500067 -1.482375 -0.092529296875 0.2401757812500067 -1.4825 -0.092529296875 0.2401757812500067 -1.482625 -0.09173583984375 0.2401757812500067 -1.48275 -0.09173583984375 0.2401757812500067 -1.482875 -0.090911865234375 0.2401757812500067 -1.483 -0.090087890625 0.2401757812500067 -1.483125 -0.090087890625 0.2401757812500067 -1.48325 -0.0892333984375 0.2401757812500067 -1.483375 -0.0892333984375 0.2401757812500067 -1.4835 -0.088409423828125 0.2401757812500067 -1.483625 -0.087554931640625 0.2401757812500067 -1.48375 -0.087554931640625 0.2401757812500067 -1.483875 -0.086669921875 0.2401757812500067 -1.484 -0.086669921875 0.2401757812500067 -1.484125 -0.085784912109375 0.2401757812500067 -1.48425 -0.08489990234375 0.2401757812500067 -1.484375 -0.08489990234375 0.2401757812500067 -1.4845 -0.084014892578125 0.2401757812500067 -1.484625 -0.084014892578125 0.2401757812500067 -1.48475 -0.0831298828125 0.2401757812500067 -1.484875 -0.08221435546875 0.2401757812500067 -1.485 -0.08221435546875 0.2401757812500067 -1.485125 -0.081298828125 0.2401757812500067 -1.48525 -0.081298828125 0.2401757812500067 -1.485375 -0.080352783203125 0.2401757812500067 -1.4855 -0.07940673828125 0.2401757812500067 -1.485625 -0.07940673828125 0.2401757812500067 -1.48575 -0.078460693359375 0.2401757812500067 -1.485875 -0.078460693359375 0.2401757812500067 -1.486 -0.0775146484375 0.2401757812500067 -1.486125 -0.0765380859375 0.2401757812500067 -1.48625 -0.0765380859375 0.2401757812500067 -1.486375 -0.0755615234375 0.2401757812500067 -1.4865 -0.0755615234375 0.2401757812500067 -1.486625 -0.0745849609375 0.2401757812500067 -1.48675 -0.0736083984375 0.2401757812500067 -1.486875 -0.0736083984375 0.2401757812500067 -1.487 -0.072601318359375 0.2401757812500067 -1.487125 -0.072601318359375 0.2401757812500067 -1.48725 -0.07159423828125 0.2401757812500067 -1.487375 -0.070587158203125 0.2401757812500067 -1.4875 -0.070587158203125 0.2401757812500067 -1.487625 -0.069580078125 0.2401757812500067 -1.48775 -0.069580078125 0.2401757812500067 -1.487875 -0.06854248046875 0.2401757812500067 -1.488 -0.0675048828125 0.2401757812500067 -1.488125 -0.0675048828125 0.2401757812500067 -1.48825 -0.06646728515625 0.2401757812500067 -1.488375 -0.06646728515625 0.2401757812500067 -1.4885 -0.065399169921875 0.2401757812500067 -1.488625 -0.064361572265625 0.2401757812500067 -1.48875 -0.064361572265625 0.2401757812500067 -1.488875 -0.06329345703125 0.2401757812500067 -1.489 -0.06329345703125 0.2401757812500067 -1.489125 -0.062225341796875 0.2401757812500067 -1.48925 -0.061126708984375 0.2401757812500067 -1.489375 -0.061126708984375 0.2401757812500067 -1.4895 -0.06005859375 0.2401757812500067 -1.489625 -0.06005859375 0.2401757812500067 -1.48975 -0.0589599609375 0.2401757812500067 -1.489875 -0.057861328125 0.2401757812500067 -1.49 -0.057861328125 0.2401757812500067 -1.490125 -0.0567626953125 0.2401757812500067 -1.49025 -0.0567626953125 0.2401757812500067 -1.490375 -0.055633544921875 0.2401757812500067 -1.4905 -0.054534912109375 0.2401757812500067 -1.490625 -0.054534912109375 0.2401757812500067 -1.49075 -0.05340576171875 0.2401757812500067 -1.490875 -0.05340576171875 0.2401757812500067 -1.491 -0.052276611328125 0.2401757812500067 -1.491125 -0.0511474609375 0.2401757812500067 -1.49125 -0.0511474609375 0.2401757812500067 -1.491375 -0.04998779296875 0.2401757812500067 -1.4915 -0.04998779296875 0.2401757812500067 -1.491625 -0.048858642578125 0.2401757812500067 -1.49175 -0.047698974609375 0.2401757812500067 -1.491875 -0.047698974609375 0.2401757812500067 -1.492 -0.046539306640625 0.2401757812500067 -1.492125 -0.046539306640625 0.2401757812500067 -1.49225 -0.045379638671875 0.2401757812500067 -1.492375 -0.044219970703125 0.2401757812500067 -1.4925 -0.044219970703125 0.2401757812500067 -1.492625 -0.04302978515625 0.2401757812500067 -1.49275 -0.04302978515625 0.2401757812500067 -1.492875 -0.0418701171875 0.2401757812500067 -1.493 -0.040679931640625 0.2401757812500067 -1.493125 -0.040679931640625 0.2401757812500067 -1.49325 -0.03948974609375 0.2401757812500067 -1.493375 -0.03948974609375 0.2401757812500067 -1.4935 -0.038299560546875 0.2401757812500067 -1.493625 -0.037109375 0.2401757812500067 -1.49375 -0.037109375 0.2401757812500067 -1.493875 -0.035919189453125 0.2401757812500067 -1.494 -0.035919189453125 0.2401757812500067 -1.494125 -0.03472900390625 0.2401757812500067 -1.49425 -0.03350830078125 0.2401757812500067 -1.494375 -0.03350830078125 0.2401757812500067 -1.4945 -0.03228759765625 0.2401757812500067 -1.494625 -0.03228759765625 0.2401757812500067 -1.49475 -0.031097412109375 0.2401757812500067 -1.494875 -0.029876708984375 0.2401757812500067 -1.495 -0.029876708984375 0.2401757812500067 -1.495125 -0.028656005859375 0.2401757812500067 -1.49525 -0.028656005859375 0.2401757812500067 -1.495375 -0.027435302734375 0.2401757812500067 -1.4955 -0.026214599609375 0.2401757812500067 -1.495625 -0.026214599609375 0.2401757812500067 -1.49575 -0.02496337890625 0.2401757812500067 -1.495875 -0.02496337890625 0.2401757812500067 -1.496 -0.02374267578125 0.2401757812500067 -1.496125 -0.02252197265625 0.2401757812500067 -1.49625 -0.02252197265625 0.2401757812500067 -1.496375 -0.021270751953125 0.2401757812500067 -1.4965 -0.021270751953125 0.2401757812500067 -1.496625 -0.020050048828125 0.2401757812500067 -1.49675 -0.018798828125 0.2401757812500067 -1.496875 -0.018798828125 0.2401757812500067 -1.497 -0.017547607421875 0.2401757812500067 -1.497125 -0.017547607421875 0.2401757812500067 -1.49725 -0.01629638671875 0.2401757812500067 -1.497375 -0.01507568359375 0.2401757812500067 -1.4975 -0.01507568359375 0.2401757812500067 -1.497625 -0.013824462890625 0.2401757812500067 -1.49775 -0.013824462890625 0.2401757812500067 -1.497875 -0.0125732421875 0.2401757812500067 -1.498 -0.011322021484375 0.2401757812500067 -1.498125 -0.011322021484375 0.2401757812500067 -1.49825 -0.01007080078125 0.2401757812500067 -1.498375 -0.01007080078125 0.2401757812500067 -1.4985 -0.008819580078125 0.2401757812500067 -1.498625 -0.007537841796875 0.2401757812500067 -1.49875 -0.007537841796875 0.2401757812500067 -1.498875 -0.00628662109375 0.2401757812500067 -1.499 -0.00628662109375 0.2401757812500067 -1.499125 -0.005035400390625 0.2401757812500067 -1.49925 -0.0037841796875 0.2401757812500067 -1.499375 -0.0037841796875 0.2401757812500067 -1.4995 -0.002532958984375 0.2401757812500067 -1.499625 -0.002532958984375 0.2401757812500067 -1.49975 -0.00128173828125 0.2401757812500067 +1.472 -0.118377685546875 0.2401757812500067 +1.472125 -0.118377685546875 0.2401757812500067 +1.47225 -0.1181640625 0.2401757812500067 +1.472375 -0.117919921875 0.2401757812500067 +1.4725 -0.117919921875 0.2401757812500067 +1.472625 -0.11767578125 0.2401757812500067 +1.47275 -0.11767578125 0.2401757812500067 +1.472875 -0.117431640625 0.2401757812500067 +1.473 -0.117156982421875 0.2401757812500067 +1.473125 -0.117156982421875 0.2401757812500067 +1.47325 -0.11688232421875 0.2401757812500067 +1.473375 -0.11688232421875 0.2401757812500067 +1.4735 -0.1165771484375 0.2401757812500067 +1.473625 -0.11627197265625 0.2401757812500067 +1.47375 -0.11627197265625 0.2401757812500067 +1.473875 -0.115966796875 0.2401757812500067 +1.474 -0.115966796875 0.2401757812500067 +1.474125 -0.115631103515625 0.2401757812500067 +1.47425 -0.11529541015625 0.2401757812500067 +1.474375 -0.11529541015625 0.2401757812500067 +1.4745 -0.11492919921875 0.2401757812500067 +1.474625 -0.11492919921875 0.2401757812500067 +1.47475 -0.11456298828125 0.2401757812500067 +1.474875 -0.114166259765625 0.2401757812500067 +1.475 -0.114166259765625 0.2401757812500067 +1.475125 -0.11376953125 0.2401757812500067 +1.47525 -0.11376953125 0.2401757812500067 +1.475375 -0.113372802734375 0.2401757812500067 +1.4755 -0.112945556640625 0.2401757812500067 +1.475625 -0.112945556640625 0.2401757812500067 +1.47575 -0.112518310546875 0.2401757812500067 +1.475875 -0.112518310546875 0.2401757812500067 +1.476 -0.112060546875 0.2401757812500067 +1.476125 -0.111602783203125 0.2401757812500067 +1.47625 -0.111602783203125 0.2401757812500067 +1.476375 -0.11114501953125 0.2401757812500067 +1.4765 -0.11114501953125 0.2401757812500067 +1.476625 -0.11065673828125 0.2401757812500067 +1.47675 -0.11016845703125 0.2401757812500067 +1.476875 -0.11016845703125 0.2401757812500067 +1.477 -0.10968017578125 0.2401757812500067 +1.477125 -0.10968017578125 0.2401757812500067 +1.47725 -0.109161376953125 0.2401757812500067 +1.477375 -0.108612060546875 0.2401757812500067 +1.4775 -0.108612060546875 0.2401757812500067 +1.477625 -0.10809326171875 0.2401757812500067 +1.47775 -0.10809326171875 0.2401757812500067 +1.477875 -0.107513427734375 0.2401757812500067 +1.478 -0.106964111328125 0.2401757812500067 +1.478125 -0.106964111328125 0.2401757812500067 +1.47825 -0.10638427734375 0.2401757812500067 +1.478375 -0.10638427734375 0.2401757812500067 +1.4785 -0.105804443359375 0.2401757812500067 +1.478625 -0.105194091796875 0.2401757812500067 +1.47875 -0.105194091796875 0.2401757812500067 +1.478875 -0.104583740234375 0.2401757812500067 +1.479 -0.104583740234375 0.2401757812500067 +1.479125 -0.103973388671875 0.2401757812500067 +1.47925 -0.10333251953125 0.2401757812500067 +1.479375 -0.10333251953125 0.2401757812500067 +1.4795 -0.102691650390625 0.2401757812500067 +1.479625 -0.102691650390625 0.2401757812500067 +1.47975 -0.102020263671875 0.2401757812500067 +1.479875 -0.101348876953125 0.2401757812500067 +1.48 -0.101348876953125 0.2401757812500067 +1.480125 -0.100677490234375 0.2401757812500067 +1.48025 -0.100677490234375 0.2401757812500067 +1.480375 -0.0999755859375 0.2401757812500067 +1.4805 -0.099273681640625 0.2401757812500067 +1.480625 -0.099273681640625 0.2401757812500067 +1.48075 -0.09857177734375 0.2401757812500067 +1.480875 -0.09857177734375 0.2401757812500067 +1.481 -0.09783935546875 0.2401757812500067 +1.481125 -0.09710693359375 0.2401757812500067 +1.48125 -0.09710693359375 0.2401757812500067 +1.481375 -0.09637451171875 0.2401757812500067 +1.4815 -0.09637451171875 0.2401757812500067 +1.481625 -0.095611572265625 0.2401757812500067 +1.48175 -0.0948486328125 0.2401757812500067 +1.481875 -0.0948486328125 0.2401757812500067 +1.482 -0.094085693359375 0.2401757812500067 +1.482125 -0.094085693359375 0.2401757812500067 +1.48225 -0.093292236328125 0.2401757812500067 +1.482375 -0.092498779296875 0.2401757812500067 +1.4825 -0.092498779296875 0.2401757812500067 +1.482625 -0.091705322265625 0.2401757812500067 +1.48275 -0.091705322265625 0.2401757812500067 +1.482875 -0.09088134765625 0.2401757812500067 +1.483 -0.090057373046875 0.2401757812500067 +1.483125 -0.090057373046875 0.2401757812500067 +1.48325 -0.089202880859375 0.2401757812500067 +1.483375 -0.089202880859375 0.2401757812500067 +1.4835 -0.08837890625 0.2401757812500067 +1.483625 -0.0875244140625 0.2401757812500067 +1.48375 -0.0875244140625 0.2401757812500067 +1.483875 -0.086639404296875 0.2401757812500067 +1.484 -0.086639404296875 0.2401757812500067 +1.484125 -0.08575439453125 0.2401757812500067 +1.48425 -0.084869384765625 0.2401757812500067 +1.484375 -0.084869384765625 0.2401757812500067 +1.4845 -0.083984375 0.2401757812500067 +1.484625 -0.083984375 0.2401757812500067 +1.48475 -0.083099365234375 0.2401757812500067 +1.484875 -0.082183837890625 0.2401757812500067 +1.485 -0.082183837890625 0.2401757812500067 +1.485125 -0.081268310546875 0.2401757812500067 +1.48525 -0.081268310546875 0.2401757812500067 +1.485375 -0.080322265625 0.2401757812500067 +1.4855 -0.079376220703125 0.2401757812500067 +1.485625 -0.079376220703125 0.2401757812500067 +1.48575 -0.07843017578125 0.2401757812500067 +1.485875 -0.07843017578125 0.2401757812500067 +1.486 -0.077484130859375 0.2401757812500067 +1.486125 -0.076507568359375 0.2401757812500067 +1.48625 -0.076507568359375 0.2401757812500067 +1.486375 -0.075531005859375 0.2401757812500067 +1.4865 -0.075531005859375 0.2401757812500067 +1.486625 -0.074554443359375 0.2401757812500067 +1.48675 -0.073577880859375 0.2401757812500067 +1.486875 -0.073577880859375 0.2401757812500067 +1.487 -0.07257080078125 0.2401757812500067 +1.487125 -0.07257080078125 0.2401757812500067 +1.48725 -0.071563720703125 0.2401757812500067 +1.487375 -0.070556640625 0.2401757812500067 +1.4875 -0.070556640625 0.2401757812500067 +1.487625 -0.069549560546875 0.2401757812500067 +1.48775 -0.069549560546875 0.2401757812500067 +1.487875 -0.068511962890625 0.2401757812500067 +1.488 -0.067474365234375 0.2401757812500067 +1.488125 -0.067474365234375 0.2401757812500067 +1.48825 -0.066436767578125 0.2401757812500067 +1.488375 -0.066436767578125 0.2401757812500067 +1.4885 -0.06536865234375 0.2401757812500067 +1.488625 -0.0643310546875 0.2401757812500067 +1.48875 -0.0643310546875 0.2401757812500067 +1.488875 -0.063262939453125 0.2401757812500067 +1.489 -0.063262939453125 0.2401757812500067 +1.489125 -0.06219482421875 0.2401757812500067 +1.48925 -0.06109619140625 0.2401757812500067 +1.489375 -0.06109619140625 0.2401757812500067 +1.4895 -0.060028076171875 0.2401757812500067 +1.489625 -0.060028076171875 0.2401757812500067 +1.48975 -0.058929443359375 0.2401757812500067 +1.489875 -0.057830810546875 0.2401757812500067 +1.49 -0.057830810546875 0.2401757812500067 +1.490125 -0.056732177734375 0.2401757812500067 +1.49025 -0.056732177734375 0.2401757812500067 +1.490375 -0.05560302734375 0.2401757812500067 +1.4905 -0.05450439453125 0.2401757812500067 +1.490625 -0.05450439453125 0.2401757812500067 +1.49075 -0.053375244140625 0.2401757812500067 +1.490875 -0.053375244140625 0.2401757812500067 +1.491 -0.05224609375 0.2401757812500067 +1.491125 -0.051116943359375 0.2401757812500067 +1.49125 -0.051116943359375 0.2401757812500067 +1.491375 -0.049957275390625 0.2401757812500067 +1.4915 -0.049957275390625 0.2401757812500067 +1.491625 -0.048828125 0.2401757812500067 +1.49175 -0.04766845703125 0.2401757812500067 +1.491875 -0.04766845703125 0.2401757812500067 +1.492 -0.0465087890625 0.2401757812500067 +1.492125 -0.0465087890625 0.2401757812500067 +1.49225 -0.04534912109375 0.2401757812500067 +1.492375 -0.044189453125 0.2401757812500067 +1.4925 -0.044189453125 0.2401757812500067 +1.492625 -0.042999267578125 0.2401757812500067 +1.49275 -0.042999267578125 0.2401757812500067 +1.492875 -0.041839599609375 0.2401757812500067 +1.493 -0.0406494140625 0.2401757812500067 +1.493125 -0.0406494140625 0.2401757812500067 +1.49325 -0.039459228515625 0.2401757812500067 +1.493375 -0.039459228515625 0.2401757812500067 +1.4935 -0.03826904296875 0.2401757812500067 +1.493625 -0.037078857421875 0.2401757812500067 +1.49375 -0.037078857421875 0.2401757812500067 +1.493875 -0.035888671875 0.2401757812500067 +1.494 -0.035888671875 0.2401757812500067 +1.494125 -0.034698486328125 0.2401757812500067 +1.49425 -0.033477783203125 0.2401757812500067 +1.494375 -0.033477783203125 0.2401757812500067 +1.4945 -0.032257080078125 0.2401757812500067 +1.494625 -0.032257080078125 0.2401757812500067 +1.49475 -0.03106689453125 0.2401757812500067 +1.494875 -0.02984619140625 0.2401757812500067 +1.495 -0.02984619140625 0.2401757812500067 +1.495125 -0.02862548828125 0.2401757812500067 +1.49525 -0.02862548828125 0.2401757812500067 +1.495375 -0.02740478515625 0.2401757812500067 +1.4955 -0.02618408203125 0.2401757812500067 +1.495625 -0.02618408203125 0.2401757812500067 +1.49575 -0.024932861328125 0.2401757812500067 +1.495875 -0.024932861328125 0.2401757812500067 +1.496 -0.023712158203125 0.2401757812500067 +1.496125 -0.022491455078125 0.2401757812500067 +1.49625 -0.022491455078125 0.2401757812500067 +1.496375 -0.021240234375 0.2401757812500067 +1.4965 -0.021240234375 0.2401757812500067 +1.496625 -0.02001953125 0.2401757812500067 +1.49675 -0.018768310546875 0.2401757812500067 +1.496875 -0.018768310546875 0.2401757812500067 +1.497 -0.01751708984375 0.2401757812500067 +1.497125 -0.01751708984375 0.2401757812500067 +1.49725 -0.016265869140625 0.2401757812500067 +1.497375 -0.015045166015625 0.2401757812500067 +1.4975 -0.015045166015625 0.2401757812500067 +1.497625 -0.0137939453125 0.2401757812500067 +1.49775 -0.0137939453125 0.2401757812500067 +1.497875 -0.012542724609375 0.2401757812500067 +1.498 -0.01129150390625 0.2401757812500067 +1.498125 -0.01129150390625 0.2401757812500067 +1.49825 -0.010040283203125 0.2401757812500067 +1.498375 -0.010040283203125 0.2401757812500067 +1.4985 -0.0087890625 0.2401757812500067 +1.498625 -0.00750732421875 0.2401757812500067 +1.49875 -0.00750732421875 0.2401757812500067 +1.498875 -0.006256103515625 0.2401757812500067 +1.499 -0.006256103515625 0.2401757812500067 +1.499125 -0.0050048828125 0.2401757812500067 +1.49925 -0.003753662109375 0.2401757812500067 +1.499375 -0.003753662109375 0.2401757812500067 +1.4995 -0.00250244140625 0.2401757812500067 +1.499625 -0.00250244140625 0.2401757812500067 +1.49975 -0.001251220703125 0.2401757812500067 1.499875 0.0 0.2401757812500067 1.5 0.0 0.2401757812500067 1.500125 0.001251220703125 0.2401757812500067 @@ -12499,504 +12499,504 @@ 1.56225 0.004180908203125 0.8033593750000046 1.562375 0.0 0.8033593750000046 1.5625 0.0 0.8033593750000046 -1.562625 -0.00421142578125 0.8033593750000046 -1.56275 -0.00421142578125 0.8033593750000046 -1.562875 -0.0084228515625 0.8033593750000046 -1.563 -0.01263427734375 0.8033593750000046 -1.563125 -0.01263427734375 0.8033593750000046 -1.56325 -0.016845703125 0.8033593750000046 -1.563375 -0.016845703125 0.8033593750000046 -1.5635 -0.021026611328125 0.8033593750000046 -1.563625 -0.025238037109375 0.8033593750000046 -1.56375 -0.025238037109375 0.8033593750000046 -1.563875 -0.0294189453125 0.8033593750000046 -1.564 -0.0294189453125 0.8033593750000046 -1.564125 -0.033599853515625 0.8033593750000046 -1.56425 -0.037811279296875 0.8033593750000046 -1.564375 -0.037811279296875 0.8033593750000046 -1.5645 -0.0419921875 0.8033593750000046 -1.564625 -0.0419921875 0.8033593750000046 -1.56475 -0.046173095703125 0.8033593750000046 -1.564875 -0.05035400390625 0.8033593750000046 -1.565 -0.05035400390625 0.8033593750000046 -1.565125 -0.05450439453125 0.8033593750000046 -1.56525 -0.05450439453125 0.8033593750000046 -1.565375 -0.058685302734375 0.8033593750000046 -1.5655 -0.062835693359375 0.8033593750000046 -1.565625 -0.062835693359375 0.8033593750000046 -1.56575 -0.066986083984375 0.8033593750000046 -1.565875 -0.066986083984375 0.8033593750000046 -1.566 -0.071136474609375 0.8033593750000046 -1.566125 -0.07525634765625 0.8033593750000046 -1.56625 -0.07525634765625 0.8033593750000046 -1.566375 -0.07940673828125 0.8033593750000046 -1.5665 -0.07940673828125 0.8033593750000046 -1.566625 -0.083526611328125 0.8033593750000046 -1.56675 -0.087615966796875 0.8033593750000046 -1.566875 -0.087615966796875 0.8033593750000046 -1.567 -0.09173583984375 0.8033593750000046 -1.567125 -0.09173583984375 0.8033593750000046 -1.56725 -0.0958251953125 0.8033593750000046 -1.567375 -0.099884033203125 0.8033593750000046 -1.5675 -0.099884033203125 0.8033593750000046 -1.567625 -0.103973388671875 0.8033593750000046 -1.56775 -0.103973388671875 0.8033593750000046 -1.567875 -0.1080322265625 0.8033593750000046 -1.568 -0.134033203125 0.960815429687502 -1.568125 -0.134033203125 0.960815429687502 -1.56825 -0.13885498046875 0.960815429687502 -1.568375 -0.13885498046875 0.960815429687502 -1.5685 -0.143646240234375 0.960815429687502 -1.568625 -0.1484375 0.960815429687502 -1.56875 -0.1484375 0.960815429687502 -1.568875 -0.153228759765625 0.960815429687502 -1.569 -0.153228759765625 0.960815429687502 -1.569125 -0.157989501953125 0.960815429687502 -1.56925 -0.1627197265625 0.960815429687502 -1.569375 -0.1627197265625 0.960815429687502 -1.5695 -0.167449951171875 0.960815429687502 -1.569625 -0.167449951171875 0.960815429687502 -1.56975 -0.172149658203125 0.960815429687502 -1.569875 -0.176849365234375 0.960815429687502 -1.57 -0.176849365234375 0.960815429687502 -1.570125 -0.1815185546875 0.960815429687502 -1.57025 -0.1815185546875 0.960815429687502 -1.570375 -0.1861572265625 0.960815429687502 -1.5705 -0.1907958984375 0.960815429687502 -1.570625 -0.1907958984375 0.960815429687502 -1.57075 -0.195404052734375 0.960815429687502 -1.570875 -0.195404052734375 0.960815429687502 -1.571 -0.199981689453125 0.960815429687502 -1.571125 -0.20452880859375 0.960815429687502 -1.57125 -0.20452880859375 0.960815429687502 -1.571375 -0.209075927734375 0.960815429687502 -1.5715 -0.209075927734375 0.960815429687502 -1.571625 -0.213592529296875 0.960815429687502 -1.57175 -0.21807861328125 0.960815429687502 -1.571875 -0.21807861328125 0.960815429687502 -1.572 -0.222564697265625 0.960815429687502 -1.572125 -0.222564697265625 0.960815429687502 -1.57225 -0.227020263671875 0.960815429687502 -1.572375 -0.231414794921875 0.960815429687502 -1.5725 -0.231414794921875 0.960815429687502 -1.572625 -0.23583984375 0.960815429687502 -1.57275 -0.23583984375 0.960815429687502 -1.572875 -0.240203857421875 0.960815429687502 -1.573 -0.244537353515625 0.960815429687502 -1.573125 -0.244537353515625 0.960815429687502 -1.57325 -0.248870849609375 0.960815429687502 -1.573375 -0.248870849609375 0.960815429687502 -1.5735 -0.253143310546875 0.960815429687502 -1.573625 -0.257415771484375 0.960815429687502 -1.57375 -0.257415771484375 0.960815429687502 -1.573875 -0.26165771484375 0.960815429687502 -1.574 -0.26165771484375 0.960815429687502 -1.574125 -0.265838623046875 0.960815429687502 -1.57425 -0.27001953125 0.960815429687502 -1.574375 -0.27001953125 0.960815429687502 -1.5745 -0.274169921875 0.960815429687502 -1.574625 -0.274169921875 0.960815429687502 -1.57475 -0.278289794921875 0.960815429687502 -1.574875 -0.2823486328125 0.960815429687502 -1.575 -0.2823486328125 0.960815429687502 -1.575125 -0.286407470703125 0.960815429687502 -1.57525 -0.286407470703125 0.960815429687502 -1.575375 -0.290435791015625 0.960815429687502 -1.5755 -0.29443359375 0.960815429687502 -1.575625 -0.29443359375 0.960815429687502 -1.57575 -0.29840087890625 0.960815429687502 -1.575875 -0.29840087890625 0.960815429687502 -1.576 -0.30230712890625 0.960815429687502 -1.576125 -0.30621337890625 0.960815429687502 -1.57625 -0.30621337890625 0.960815429687502 -1.576375 -0.31005859375 0.960815429687502 -1.5765 -0.31005859375 0.960815429687502 -1.576625 -0.31390380859375 0.960815429687502 -1.57675 -0.31768798828125 0.960815429687502 -1.576875 -0.31768798828125 0.960815429687502 -1.577 -0.321441650390625 0.960815429687502 -1.577125 -0.321441650390625 0.960815429687502 -1.57725 -0.325164794921875 0.960815429687502 -1.577375 -0.328857421875 0.960815429687502 -1.5775 -0.328857421875 0.960815429687502 -1.577625 -0.332489013671875 0.960815429687502 -1.57775 -0.332489013671875 0.960815429687502 -1.577875 -0.336090087890625 0.960815429687502 -1.578 -0.339691162109375 0.960815429687502 -1.578125 -0.339691162109375 0.960815429687502 -1.57825 -0.343231201171875 0.960815429687502 -1.578375 -0.343231201171875 0.960815429687502 -1.5785 -0.346710205078125 0.960815429687502 -1.578625 -0.350189208984375 0.960815429687502 -1.57875 -0.350189208984375 0.960815429687502 -1.578875 -0.353607177734375 0.960815429687502 -1.579 -0.353607177734375 0.960815429687502 -1.579125 -0.35699462890625 0.960815429687502 -1.57925 -0.3603515625 0.960815429687502 -1.579375 -0.3603515625 0.960815429687502 -1.5795 -0.3636474609375 0.960815429687502 -1.579625 -0.3636474609375 0.960815429687502 -1.57975 -0.366912841796875 0.960815429687502 -1.579875 -0.370147705078125 0.960815429687502 -1.58 -0.370147705078125 0.960815429687502 -1.580125 -0.373321533203125 0.960815429687502 -1.58025 -0.373321533203125 0.960815429687502 -1.580375 -0.37646484375 0.960815429687502 -1.5805 -0.37957763671875 0.960815429687502 -1.580625 -0.37957763671875 0.960815429687502 -1.58075 -0.38262939453125 0.960815429687502 -1.580875 -0.38262939453125 0.960815429687502 -1.581 -0.385650634765625 0.960815429687502 -1.581125 -0.388641357421875 0.960815429687502 -1.58125 -0.388641357421875 0.960815429687502 -1.581375 -0.391571044921875 0.960815429687502 -1.5815 -0.391571044921875 0.960815429687502 -1.581625 -0.39447021484375 0.960815429687502 -1.58175 -0.397308349609375 0.960815429687502 -1.581875 -0.397308349609375 0.960815429687502 -1.582 -0.400115966796875 0.960815429687502 -1.582125 -0.400115966796875 0.960815429687502 -1.58225 -0.40289306640625 0.960815429687502 -1.582375 -0.405609130859375 0.960815429687502 -1.5825 -0.405609130859375 0.960815429687502 -1.582625 -0.40826416015625 0.960815429687502 -1.58275 -0.40826416015625 0.960815429687502 -1.582875 -0.410888671875 0.960815429687502 -1.583 -0.413482666015625 0.960815429687502 -1.583125 -0.413482666015625 0.960815429687502 -1.58325 -0.416046142578125 0.960815429687502 -1.583375 -0.416046142578125 0.960815429687502 -1.5835 -0.41851806640625 0.960815429687502 -1.583625 -0.42095947265625 0.960815429687502 -1.58375 -0.42095947265625 0.960815429687502 -1.583875 -0.423370361328125 0.960815429687502 -1.584 -0.423370361328125 0.960815429687502 -1.584125 -0.42572021484375 0.960815429687502 -1.58425 -0.42803955078125 0.960815429687502 -1.584375 -0.42803955078125 0.960815429687502 -1.5845 -0.4302978515625 0.960815429687502 -1.584625 -0.4302978515625 0.960815429687502 -1.58475 -0.4324951171875 0.960815429687502 -1.584875 -0.434661865234375 0.960815429687502 -1.585 -0.434661865234375 0.960815429687502 -1.585125 -0.436767578125 0.960815429687502 -1.58525 -0.436767578125 0.960815429687502 -1.585375 -0.438873291015625 0.960815429687502 -1.5855 -0.440887451171875 0.960815429687502 -1.585625 -0.440887451171875 0.960815429687502 -1.58575 -0.442840576171875 0.960815429687502 -1.585875 -0.442840576171875 0.960815429687502 -1.586 -0.444793701171875 0.960815429687502 -1.586125 -0.4466552734375 0.960815429687502 -1.58625 -0.4466552734375 0.960815429687502 -1.586375 -0.448486328125 0.960815429687502 -1.5865 -0.448486328125 0.960815429687502 -1.586625 -0.45025634765625 0.960815429687502 -1.58675 -0.451995849609375 0.960815429687502 -1.586875 -0.451995849609375 0.960815429687502 -1.587 -0.45367431640625 0.960815429687502 -1.587125 -0.45367431640625 0.960815429687502 -1.58725 -0.455291748046875 0.960815429687502 -1.587375 -0.456878662109375 0.960815429687502 -1.5875 -0.456878662109375 0.960815429687502 -1.587625 -0.458404541015625 0.960815429687502 -1.58775 -0.458404541015625 0.960815429687502 -1.587875 -0.459869384765625 0.960815429687502 -1.588 -0.4613037109375 0.960815429687502 -1.588125 -0.4613037109375 0.960815429687502 -1.58825 -0.462677001953125 0.960815429687502 -1.588375 -0.462677001953125 0.960815429687502 -1.5885 -0.464019775390625 0.960815429687502 -1.588625 -0.465301513671875 0.960815429687502 -1.58875 -0.465301513671875 0.960815429687502 -1.588875 -0.466522216796875 0.960815429687502 -1.589 -0.466522216796875 0.960815429687502 -1.589125 -0.467681884765625 0.960815429687502 -1.58925 -0.46881103515625 0.960815429687502 -1.589375 -0.46881103515625 0.960815429687502 -1.5895 -0.469879150390625 0.960815429687502 -1.589625 -0.469879150390625 0.960815429687502 -1.58975 -0.470916748046875 0.960815429687502 -1.589875 -0.47186279296875 0.960815429687502 -1.59 -0.47186279296875 0.960815429687502 -1.590125 -0.472808837890625 0.960815429687502 -1.59025 -0.472808837890625 0.960815429687502 -1.590375 -0.473663330078125 0.960815429687502 -1.5905 -0.474456787109375 0.960815429687502 -1.590625 -0.474456787109375 0.960815429687502 -1.59075 -0.4752197265625 0.960815429687502 -1.590875 -0.4752197265625 0.960815429687502 -1.591 -0.475921630859375 0.960815429687502 -1.591125 -0.476593017578125 0.960815429687502 -1.59125 -0.476593017578125 0.960815429687502 -1.591375 -0.477203369140625 0.960815429687502 -1.5915 -0.477203369140625 0.960815429687502 -1.591625 -0.477752685546875 0.960815429687502 -1.59175 -0.478240966796875 0.960815429687502 -1.591875 -0.478240966796875 0.960815429687502 -1.592 -0.47869873046875 0.960815429687502 -1.592125 -0.47869873046875 0.960815429687502 -1.59225 -0.479095458984375 0.960815429687502 -1.592375 -0.47943115234375 0.960815429687502 -1.5925 -0.47943115234375 0.960815429687502 -1.592625 -0.479736328125 0.960815429687502 -1.59275 -0.479736328125 0.960815429687502 -1.592875 -0.47998046875 0.960815429687502 -1.593 -0.480133056640625 0.960815429687502 -1.593125 -0.480133056640625 0.960815429687502 -1.59325 -0.48028564453125 0.960815429687502 -1.593375 -0.48028564453125 0.960815429687502 -1.5935 -0.480377197265625 0.960815429687502 -1.593625 -0.48040771484375 0.960815429687502 -1.59375 -0.48040771484375 0.960815429687502 -1.593875 -0.480377197265625 0.960815429687502 -1.594 -0.480377197265625 0.960815429687502 -1.594125 -0.48028564453125 0.960815429687502 -1.59425 -0.480133056640625 0.960815429687502 -1.594375 -0.480133056640625 0.960815429687502 -1.5945 -0.47998046875 0.960815429687502 -1.594625 -0.47998046875 0.960815429687502 -1.59475 -0.479736328125 0.960815429687502 -1.594875 -0.47943115234375 0.960815429687502 -1.595 -0.47943115234375 0.960815429687502 -1.595125 -0.479095458984375 0.960815429687502 -1.59525 -0.479095458984375 0.960815429687502 -1.595375 -0.47869873046875 0.960815429687502 -1.5955 -0.478240966796875 0.960815429687502 -1.595625 -0.478240966796875 0.960815429687502 -1.59575 -0.477752685546875 0.960815429687502 -1.595875 -0.477752685546875 0.960815429687502 -1.596 -0.477203369140625 0.960815429687502 -1.596125 -0.476593017578125 0.960815429687502 -1.59625 -0.476593017578125 0.960815429687502 -1.596375 -0.475921630859375 0.960815429687502 -1.5965 -0.475921630859375 0.960815429687502 -1.596625 -0.4752197265625 0.960815429687502 -1.59675 -0.474456787109375 0.960815429687502 -1.596875 -0.474456787109375 0.960815429687502 -1.597 -0.473663330078125 0.960815429687502 -1.597125 -0.473663330078125 0.960815429687502 -1.59725 -0.472808837890625 0.960815429687502 -1.597375 -0.47186279296875 0.960815429687502 -1.5975 -0.47186279296875 0.960815429687502 -1.597625 -0.470916748046875 0.960815429687502 -1.59775 -0.470916748046875 0.960815429687502 -1.597875 -0.469879150390625 0.960815429687502 -1.598 -0.46881103515625 0.960815429687502 -1.598125 -0.46881103515625 0.960815429687502 -1.59825 -0.467681884765625 0.960815429687502 -1.598375 -0.467681884765625 0.960815429687502 -1.5985 -0.466522216796875 0.960815429687502 -1.598625 -0.465301513671875 0.960815429687502 -1.59875 -0.465301513671875 0.960815429687502 -1.598875 -0.464019775390625 0.960815429687502 -1.599 -0.464019775390625 0.960815429687502 -1.599125 -0.462677001953125 0.960815429687502 -1.59925 -0.4613037109375 0.960815429687502 -1.599375 -0.4613037109375 0.960815429687502 -1.5995 -0.459869384765625 0.960815429687502 -1.599625 -0.459869384765625 0.960815429687502 -1.59975 -0.458404541015625 0.960815429687502 -1.599875 -0.456878662109375 0.960815429687502 -1.6 -0.474029541015625 0.9968652343749994 -1.600125 -0.472381591796875 0.9968652343749994 -1.60025 -0.472381591796875 0.9968652343749994 -1.600375 -0.470672607421875 0.9968652343749994 -1.6005 -0.46893310546875 0.9968652343749994 -1.600625 -0.46893310546875 0.9968652343749994 -1.60075 -0.467132568359375 0.9968652343749994 -1.600875 -0.467132568359375 0.9968652343749994 -1.601 -0.465301513671875 0.9968652343749994 -1.601125 -0.463409423828125 0.9968652343749994 -1.60125 -0.463409423828125 0.9968652343749994 -1.601375 -0.461456298828125 0.9968652343749994 -1.6015 -0.461456298828125 0.9968652343749994 -1.601625 -0.45947265625 0.9968652343749994 -1.60175 -0.457427978515625 0.9968652343749994 -1.601875 -0.457427978515625 0.9968652343749994 -1.602 -0.455322265625 0.9968652343749994 -1.602125 -0.455322265625 0.9968652343749994 -1.60225 -0.453155517578125 0.9968652343749994 -1.602375 -0.450958251953125 0.9968652343749994 -1.6025 -0.450958251953125 0.9968652343749994 -1.602625 -0.44873046875 0.9968652343749994 -1.60275 -0.44873046875 0.9968652343749994 -1.602875 -0.4464111328125 0.9968652343749994 -1.603 -0.444091796875 0.9968652343749994 -1.603125 -0.444091796875 0.9968652343749994 -1.60325 -0.441680908203125 0.9968652343749994 -1.603375 -0.441680908203125 0.9968652343749994 -1.6035 -0.439239501953125 0.9968652343749994 -1.603625 -0.436737060546875 0.9968652343749994 -1.60375 -0.436737060546875 0.9968652343749994 -1.603875 -0.434234619140625 0.9968652343749994 -1.604 -0.434234619140625 0.9968652343749994 -1.604125 -0.431640625 0.9968652343749994 -1.60425 -0.428985595703125 0.9968652343749994 -1.604375 -0.428985595703125 0.9968652343749994 -1.6045 -0.42633056640625 0.9968652343749994 -1.604625 -0.42633056640625 0.9968652343749994 -1.60475 -0.423583984375 0.9968652343749994 -1.604875 -0.42083740234375 0.9968652343749994 -1.605 -0.42083740234375 0.9968652343749994 -1.605125 -0.417999267578125 0.9968652343749994 -1.60525 -0.417999267578125 0.9968652343749994 -1.605375 -0.415130615234375 0.9968652343749994 -1.6055 -0.412200927734375 0.9968652343749994 -1.605625 -0.412200927734375 0.9968652343749994 -1.60575 -0.409271240234375 0.9968652343749994 -1.605875 -0.409271240234375 0.9968652343749994 -1.606 -0.406280517578125 0.9968652343749994 -1.606125 -0.403228759765625 0.9968652343749994 -1.60625 -0.403228759765625 0.9968652343749994 -1.606375 -0.400115966796875 0.9968652343749994 -1.6065 -0.400115966796875 0.9968652343749994 -1.606625 -0.397003173828125 0.9968652343749994 -1.60675 -0.393829345703125 0.9968652343749994 -1.606875 -0.393829345703125 0.9968652343749994 -1.607 -0.390594482421875 0.9968652343749994 -1.607125 -0.390594482421875 0.9968652343749994 -1.60725 -0.3873291015625 0.9968652343749994 -1.607375 -0.384033203125 0.9968652343749994 -1.6075 -0.384033203125 0.9968652343749994 -1.607625 -0.38067626953125 0.9968652343749994 -1.60775 -0.38067626953125 0.9968652343749994 -1.607875 -0.377288818359375 0.9968652343749994 -1.608 -0.37384033203125 0.9968652343749994 -1.608125 -0.37384033203125 0.9968652343749994 -1.60825 -0.370391845703125 0.9968652343749994 -1.608375 -0.370391845703125 0.9968652343749994 -1.6085 -0.36688232421875 0.9968652343749994 -1.608625 -0.36334228515625 0.9968652343749994 -1.60875 -0.36334228515625 0.9968652343749994 -1.608875 -0.359710693359375 0.9968652343749994 -1.609 -0.359710693359375 0.9968652343749994 -1.609125 -0.356109619140625 0.9968652343749994 -1.60925 -0.3524169921875 0.9968652343749994 -1.609375 -0.3524169921875 0.9968652343749994 -1.6095 -0.348724365234375 0.9968652343749994 -1.609625 -0.348724365234375 0.9968652343749994 -1.60975 -0.344970703125 0.9968652343749994 -1.609875 -0.3411865234375 0.9968652343749994 -1.61 -0.3411865234375 0.9968652343749994 -1.610125 -0.337371826171875 0.9968652343749994 -1.61025 -0.337371826171875 0.9968652343749994 -1.610375 -0.33349609375 0.9968652343749994 -1.6105 -0.329620361328125 0.9968652343749994 -1.610625 -0.329620361328125 0.9968652343749994 -1.61075 -0.32568359375 0.9968652343749994 -1.610875 -0.32568359375 0.9968652343749994 -1.611 -0.321685791015625 0.9968652343749994 -1.611125 -0.31768798828125 0.9968652343749994 -1.61125 -0.31768798828125 0.9968652343749994 -1.611375 -0.31365966796875 0.9968652343749994 -1.6115 -0.31365966796875 0.9968652343749994 -1.611625 -0.309600830078125 0.9968652343749994 -1.61175 -0.30548095703125 0.9968652343749994 -1.611875 -0.30548095703125 0.9968652343749994 -1.612 -0.30133056640625 0.9968652343749994 -1.612125 -0.30133056640625 0.9968652343749994 -1.61225 -0.297149658203125 0.9968652343749994 -1.612375 -0.292938232421875 0.9968652343749994 -1.6125 -0.292938232421875 0.9968652343749994 -1.612625 -0.288726806640625 0.9968652343749994 -1.61275 -0.288726806640625 0.9968652343749994 -1.612875 -0.284454345703125 0.9968652343749994 -1.613 -0.2801513671875 0.9968652343749994 -1.613125 -0.2801513671875 0.9968652343749994 -1.61325 -0.27581787109375 0.9968652343749994 -1.613375 -0.27581787109375 0.9968652343749994 -1.6135 -0.271453857421875 0.9968652343749994 -1.613625 -0.267059326171875 0.9968652343749994 -1.61375 -0.267059326171875 0.9968652343749994 -1.613875 -0.26263427734375 0.9968652343749994 -1.614 -0.26263427734375 0.9968652343749994 -1.614125 -0.258209228515625 0.9968652343749994 -1.61425 -0.25372314453125 0.9968652343749994 -1.614375 -0.25372314453125 0.9968652343749994 -1.6145 -0.24920654296875 0.9968652343749994 -1.614625 -0.24920654296875 0.9968652343749994 -1.61475 -0.244659423828125 0.9968652343749994 -1.614875 -0.2401123046875 0.9968652343749994 -1.615 -0.2401123046875 0.9968652343749994 -1.615125 -0.23553466796875 0.9968652343749994 -1.61525 -0.23553466796875 0.9968652343749994 -1.615375 -0.23089599609375 0.9968652343749994 -1.6155 -0.22625732421875 0.9968652343749994 -1.615625 -0.22625732421875 0.9968652343749994 -1.61575 -0.22161865234375 0.9968652343749994 -1.615875 -0.22161865234375 0.9968652343749994 -1.616 -0.2169189453125 0.9968652343749994 -1.616125 -0.21221923828125 0.9968652343749994 -1.61625 -0.21221923828125 0.9968652343749994 -1.616375 -0.207489013671875 0.9968652343749994 -1.6165 -0.207489013671875 0.9968652343749994 -1.616625 -0.202728271484375 0.9968652343749994 -1.61675 -0.19793701171875 0.9968652343749994 -1.616875 -0.19793701171875 0.9968652343749994 -1.617 -0.193145751953125 0.9968652343749994 -1.617125 -0.193145751953125 0.9968652343749994 -1.61725 -0.188323974609375 0.9968652343749994 -1.617375 -0.1834716796875 0.9968652343749994 -1.6175 -0.1834716796875 0.9968652343749994 -1.617625 -0.178619384765625 0.9968652343749994 -1.61775 -0.178619384765625 0.9968652343749994 -1.617875 -0.173736572265625 0.9968652343749994 -1.618 -0.1688232421875 0.9968652343749994 -1.618125 -0.1688232421875 0.9968652343749994 -1.61825 -0.163909912109375 0.9968652343749994 -1.618375 -0.163909912109375 0.9968652343749994 -1.6185 -0.158966064453125 0.9968652343749994 -1.618625 -0.154022216796875 0.9968652343749994 -1.61875 -0.154022216796875 0.9968652343749994 -1.618875 -0.1490478515625 0.9968652343749994 -1.619 -0.1490478515625 0.9968652343749994 -1.619125 -0.14404296875 0.9968652343749994 -1.61925 -0.1390380859375 0.9968652343749994 -1.619375 -0.1390380859375 0.9968652343749994 -1.6195 -0.134033203125 0.9968652343749994 -1.619625 -0.134033203125 0.9968652343749994 -1.61975 -0.128997802734375 0.9968652343749994 -1.619875 -0.12396240234375 0.9968652343749994 -1.62 -0.12396240234375 0.9968652343749994 -1.620125 -0.118896484375 0.9968652343749994 -1.62025 -0.118896484375 0.9968652343749994 -1.620375 -0.11383056640625 0.9968652343749994 -1.6205 -0.108734130859375 0.9968652343749994 -1.620625 -0.108734130859375 0.9968652343749994 -1.62075 -0.1036376953125 0.9968652343749994 -1.620875 -0.1036376953125 0.9968652343749994 -1.621 -0.0985107421875 0.9968652343749994 -1.621125 -0.0933837890625 0.9968652343749994 -1.62125 -0.0933837890625 0.9968652343749994 -1.621375 -0.0882568359375 0.9968652343749994 -1.6215 -0.0882568359375 0.9968652343749994 -1.621625 -0.0831298828125 0.9968652343749994 -1.62175 -0.077972412109375 0.9968652343749994 -1.621875 -0.077972412109375 0.9968652343749994 -1.622 -0.07281494140625 0.9968652343749994 -1.622125 -0.07281494140625 0.9968652343749994 -1.62225 -0.067626953125 0.9968652343749994 -1.622375 -0.062469482421875 0.9968652343749994 -1.6225 -0.062469482421875 0.9968652343749994 -1.622625 -0.05731201171875 0.9968652343749994 -1.62275 -0.05731201171875 0.9968652343749994 -1.622875 -0.0521240234375 0.9968652343749994 -1.623 -0.046905517578125 0.9968652343749994 -1.623125 -0.046905517578125 0.9968652343749994 -1.62325 -0.041717529296875 0.9968652343749994 -1.623375 -0.041717529296875 0.9968652343749994 -1.6235 -0.0364990234375 0.9968652343749994 -1.623625 -0.03131103515625 0.9968652343749994 -1.62375 -0.03131103515625 0.9968652343749994 -1.623875 -0.026092529296875 0.9968652343749994 -1.624 -0.026092529296875 0.9968652343749994 -1.624125 -0.0208740234375 0.9968652343749994 -1.62425 -0.015655517578125 0.9968652343749994 -1.624375 -0.015655517578125 0.9968652343749994 -1.6245 -0.01043701171875 0.9968652343749994 -1.624625 -0.01043701171875 0.9968652343749994 -1.62475 -0.005218505859375 0.9968652343749994 +1.562625 -0.004180908203125 0.8033593750000046 +1.56275 -0.004180908203125 0.8033593750000046 +1.562875 -0.008392333984375 0.8033593750000046 +1.563 -0.012603759765625 0.8033593750000046 +1.563125 -0.012603759765625 0.8033593750000046 +1.56325 -0.016815185546875 0.8033593750000046 +1.563375 -0.016815185546875 0.8033593750000046 +1.5635 -0.02099609375 0.8033593750000046 +1.563625 -0.02520751953125 0.8033593750000046 +1.56375 -0.02520751953125 0.8033593750000046 +1.563875 -0.029388427734375 0.8033593750000046 +1.564 -0.029388427734375 0.8033593750000046 +1.564125 -0.0335693359375 0.8033593750000046 +1.56425 -0.03778076171875 0.8033593750000046 +1.564375 -0.03778076171875 0.8033593750000046 +1.5645 -0.041961669921875 0.8033593750000046 +1.564625 -0.041961669921875 0.8033593750000046 +1.56475 -0.046142578125 0.8033593750000046 +1.564875 -0.050323486328125 0.8033593750000046 +1.565 -0.050323486328125 0.8033593750000046 +1.565125 -0.054473876953125 0.8033593750000046 +1.56525 -0.054473876953125 0.8033593750000046 +1.565375 -0.05865478515625 0.8033593750000046 +1.5655 -0.06280517578125 0.8033593750000046 +1.565625 -0.06280517578125 0.8033593750000046 +1.56575 -0.06695556640625 0.8033593750000046 +1.565875 -0.06695556640625 0.8033593750000046 +1.566 -0.07110595703125 0.8033593750000046 +1.566125 -0.075225830078125 0.8033593750000046 +1.56625 -0.075225830078125 0.8033593750000046 +1.566375 -0.079376220703125 0.8033593750000046 +1.5665 -0.079376220703125 0.8033593750000046 +1.566625 -0.08349609375 0.8033593750000046 +1.56675 -0.08758544921875 0.8033593750000046 +1.566875 -0.08758544921875 0.8033593750000046 +1.567 -0.091705322265625 0.8033593750000046 +1.567125 -0.091705322265625 0.8033593750000046 +1.56725 -0.095794677734375 0.8033593750000046 +1.567375 -0.099853515625 0.8033593750000046 +1.5675 -0.099853515625 0.8033593750000046 +1.567625 -0.10394287109375 0.8033593750000046 +1.56775 -0.10394287109375 0.8033593750000046 +1.567875 -0.108001708984375 0.8033593750000046 +1.568 -0.134002685546875 0.960815429687502 +1.568125 -0.134002685546875 0.960815429687502 +1.56825 -0.138824462890625 0.960815429687502 +1.568375 -0.138824462890625 0.960815429687502 +1.5685 -0.14361572265625 0.960815429687502 +1.568625 -0.148406982421875 0.960815429687502 +1.56875 -0.148406982421875 0.960815429687502 +1.568875 -0.1531982421875 0.960815429687502 +1.569 -0.1531982421875 0.960815429687502 +1.569125 -0.157958984375 0.960815429687502 +1.56925 -0.162689208984375 0.960815429687502 +1.569375 -0.162689208984375 0.960815429687502 +1.5695 -0.16741943359375 0.960815429687502 +1.569625 -0.16741943359375 0.960815429687502 +1.56975 -0.172119140625 0.960815429687502 +1.569875 -0.17681884765625 0.960815429687502 +1.57 -0.17681884765625 0.960815429687502 +1.570125 -0.181488037109375 0.960815429687502 +1.57025 -0.181488037109375 0.960815429687502 +1.570375 -0.186126708984375 0.960815429687502 +1.5705 -0.190765380859375 0.960815429687502 +1.570625 -0.190765380859375 0.960815429687502 +1.57075 -0.19537353515625 0.960815429687502 +1.570875 -0.19537353515625 0.960815429687502 +1.571 -0.199951171875 0.960815429687502 +1.571125 -0.204498291015625 0.960815429687502 +1.57125 -0.204498291015625 0.960815429687502 +1.571375 -0.20904541015625 0.960815429687502 +1.5715 -0.20904541015625 0.960815429687502 +1.571625 -0.21356201171875 0.960815429687502 +1.57175 -0.218048095703125 0.960815429687502 +1.571875 -0.218048095703125 0.960815429687502 +1.572 -0.2225341796875 0.960815429687502 +1.572125 -0.2225341796875 0.960815429687502 +1.57225 -0.22698974609375 0.960815429687502 +1.572375 -0.23138427734375 0.960815429687502 +1.5725 -0.23138427734375 0.960815429687502 +1.572625 -0.235809326171875 0.960815429687502 +1.57275 -0.235809326171875 0.960815429687502 +1.572875 -0.24017333984375 0.960815429687502 +1.573 -0.2445068359375 0.960815429687502 +1.573125 -0.2445068359375 0.960815429687502 +1.57325 -0.24884033203125 0.960815429687502 +1.573375 -0.24884033203125 0.960815429687502 +1.5735 -0.25311279296875 0.960815429687502 +1.573625 -0.25738525390625 0.960815429687502 +1.57375 -0.25738525390625 0.960815429687502 +1.573875 -0.261627197265625 0.960815429687502 +1.574 -0.261627197265625 0.960815429687502 +1.574125 -0.26580810546875 0.960815429687502 +1.57425 -0.269989013671875 0.960815429687502 +1.574375 -0.269989013671875 0.960815429687502 +1.5745 -0.274139404296875 0.960815429687502 +1.574625 -0.274139404296875 0.960815429687502 +1.57475 -0.27825927734375 0.960815429687502 +1.574875 -0.282318115234375 0.960815429687502 +1.575 -0.282318115234375 0.960815429687502 +1.575125 -0.286376953125 0.960815429687502 +1.57525 -0.286376953125 0.960815429687502 +1.575375 -0.2904052734375 0.960815429687502 +1.5755 -0.294403076171875 0.960815429687502 +1.575625 -0.294403076171875 0.960815429687502 +1.57575 -0.298370361328125 0.960815429687502 +1.575875 -0.298370361328125 0.960815429687502 +1.576 -0.302276611328125 0.960815429687502 +1.576125 -0.306182861328125 0.960815429687502 +1.57625 -0.306182861328125 0.960815429687502 +1.576375 -0.310028076171875 0.960815429687502 +1.5765 -0.310028076171875 0.960815429687502 +1.576625 -0.313873291015625 0.960815429687502 +1.57675 -0.317657470703125 0.960815429687502 +1.576875 -0.317657470703125 0.960815429687502 +1.577 -0.3214111328125 0.960815429687502 +1.577125 -0.3214111328125 0.960815429687502 +1.57725 -0.32513427734375 0.960815429687502 +1.577375 -0.328826904296875 0.960815429687502 +1.5775 -0.328826904296875 0.960815429687502 +1.577625 -0.33245849609375 0.960815429687502 +1.57775 -0.33245849609375 0.960815429687502 +1.577875 -0.3360595703125 0.960815429687502 +1.578 -0.33966064453125 0.960815429687502 +1.578125 -0.33966064453125 0.960815429687502 +1.57825 -0.34320068359375 0.960815429687502 +1.578375 -0.34320068359375 0.960815429687502 +1.5785 -0.3466796875 0.960815429687502 +1.578625 -0.35015869140625 0.960815429687502 +1.57875 -0.35015869140625 0.960815429687502 +1.578875 -0.35357666015625 0.960815429687502 +1.579 -0.35357666015625 0.960815429687502 +1.579125 -0.356964111328125 0.960815429687502 +1.57925 -0.360321044921875 0.960815429687502 +1.579375 -0.360321044921875 0.960815429687502 +1.5795 -0.363616943359375 0.960815429687502 +1.579625 -0.363616943359375 0.960815429687502 +1.57975 -0.36688232421875 0.960815429687502 +1.579875 -0.3701171875 0.960815429687502 +1.58 -0.3701171875 0.960815429687502 +1.580125 -0.373291015625 0.960815429687502 +1.58025 -0.373291015625 0.960815429687502 +1.580375 -0.376434326171875 0.960815429687502 +1.5805 -0.379547119140625 0.960815429687502 +1.580625 -0.379547119140625 0.960815429687502 +1.58075 -0.382598876953125 0.960815429687502 +1.580875 -0.382598876953125 0.960815429687502 +1.581 -0.3856201171875 0.960815429687502 +1.581125 -0.38861083984375 0.960815429687502 +1.58125 -0.38861083984375 0.960815429687502 +1.581375 -0.39154052734375 0.960815429687502 +1.5815 -0.39154052734375 0.960815429687502 +1.581625 -0.394439697265625 0.960815429687502 +1.58175 -0.39727783203125 0.960815429687502 +1.581875 -0.39727783203125 0.960815429687502 +1.582 -0.40008544921875 0.960815429687502 +1.582125 -0.40008544921875 0.960815429687502 +1.58225 -0.402862548828125 0.960815429687502 +1.582375 -0.40557861328125 0.960815429687502 +1.5825 -0.40557861328125 0.960815429687502 +1.582625 -0.408233642578125 0.960815429687502 +1.58275 -0.408233642578125 0.960815429687502 +1.582875 -0.410858154296875 0.960815429687502 +1.583 -0.4134521484375 0.960815429687502 +1.583125 -0.4134521484375 0.960815429687502 +1.58325 -0.416015625 0.960815429687502 +1.583375 -0.416015625 0.960815429687502 +1.5835 -0.418487548828125 0.960815429687502 +1.583625 -0.420928955078125 0.960815429687502 +1.58375 -0.420928955078125 0.960815429687502 +1.583875 -0.42333984375 0.960815429687502 +1.584 -0.42333984375 0.960815429687502 +1.584125 -0.425689697265625 0.960815429687502 +1.58425 -0.428009033203125 0.960815429687502 +1.584375 -0.428009033203125 0.960815429687502 +1.5845 -0.430267333984375 0.960815429687502 +1.584625 -0.430267333984375 0.960815429687502 +1.58475 -0.432464599609375 0.960815429687502 +1.584875 -0.43463134765625 0.960815429687502 +1.585 -0.43463134765625 0.960815429687502 +1.585125 -0.436737060546875 0.960815429687502 +1.58525 -0.436737060546875 0.960815429687502 +1.585375 -0.4388427734375 0.960815429687502 +1.5855 -0.44085693359375 0.960815429687502 +1.585625 -0.44085693359375 0.960815429687502 +1.58575 -0.44281005859375 0.960815429687502 +1.585875 -0.44281005859375 0.960815429687502 +1.586 -0.44476318359375 0.960815429687502 +1.586125 -0.446624755859375 0.960815429687502 +1.58625 -0.446624755859375 0.960815429687502 +1.586375 -0.448455810546875 0.960815429687502 +1.5865 -0.448455810546875 0.960815429687502 +1.586625 -0.450225830078125 0.960815429687502 +1.58675 -0.45196533203125 0.960815429687502 +1.586875 -0.45196533203125 0.960815429687502 +1.587 -0.453643798828125 0.960815429687502 +1.587125 -0.453643798828125 0.960815429687502 +1.58725 -0.45526123046875 0.960815429687502 +1.587375 -0.45684814453125 0.960815429687502 +1.5875 -0.45684814453125 0.960815429687502 +1.587625 -0.4583740234375 0.960815429687502 +1.58775 -0.4583740234375 0.960815429687502 +1.587875 -0.4598388671875 0.960815429687502 +1.588 -0.461273193359375 0.960815429687502 +1.588125 -0.461273193359375 0.960815429687502 +1.58825 -0.462646484375 0.960815429687502 +1.588375 -0.462646484375 0.960815429687502 +1.5885 -0.4639892578125 0.960815429687502 +1.588625 -0.46527099609375 0.960815429687502 +1.58875 -0.46527099609375 0.960815429687502 +1.588875 -0.46649169921875 0.960815429687502 +1.589 -0.46649169921875 0.960815429687502 +1.589125 -0.4676513671875 0.960815429687502 +1.58925 -0.468780517578125 0.960815429687502 +1.589375 -0.468780517578125 0.960815429687502 +1.5895 -0.4698486328125 0.960815429687502 +1.589625 -0.4698486328125 0.960815429687502 +1.58975 -0.47088623046875 0.960815429687502 +1.589875 -0.471832275390625 0.960815429687502 +1.59 -0.471832275390625 0.960815429687502 +1.590125 -0.4727783203125 0.960815429687502 +1.59025 -0.4727783203125 0.960815429687502 +1.590375 -0.4736328125 0.960815429687502 +1.5905 -0.47442626953125 0.960815429687502 +1.590625 -0.47442626953125 0.960815429687502 +1.59075 -0.475189208984375 0.960815429687502 +1.590875 -0.475189208984375 0.960815429687502 +1.591 -0.47589111328125 0.960815429687502 +1.591125 -0.4765625 0.960815429687502 +1.59125 -0.4765625 0.960815429687502 +1.591375 -0.4771728515625 0.960815429687502 +1.5915 -0.4771728515625 0.960815429687502 +1.591625 -0.47772216796875 0.960815429687502 +1.59175 -0.47821044921875 0.960815429687502 +1.591875 -0.47821044921875 0.960815429687502 +1.592 -0.478668212890625 0.960815429687502 +1.592125 -0.478668212890625 0.960815429687502 +1.59225 -0.47906494140625 0.960815429687502 +1.592375 -0.479400634765625 0.960815429687502 +1.5925 -0.479400634765625 0.960815429687502 +1.592625 -0.479705810546875 0.960815429687502 +1.59275 -0.479705810546875 0.960815429687502 +1.592875 -0.479949951171875 0.960815429687502 +1.593 -0.4801025390625 0.960815429687502 +1.593125 -0.4801025390625 0.960815429687502 +1.59325 -0.480255126953125 0.960815429687502 +1.593375 -0.480255126953125 0.960815429687502 +1.5935 -0.4803466796875 0.960815429687502 +1.593625 -0.480377197265625 0.960815429687502 +1.59375 -0.480377197265625 0.960815429687502 +1.593875 -0.4803466796875 0.960815429687502 +1.594 -0.4803466796875 0.960815429687502 +1.594125 -0.480255126953125 0.960815429687502 +1.59425 -0.4801025390625 0.960815429687502 +1.594375 -0.4801025390625 0.960815429687502 +1.5945 -0.479949951171875 0.960815429687502 +1.594625 -0.479949951171875 0.960815429687502 +1.59475 -0.479705810546875 0.960815429687502 +1.594875 -0.479400634765625 0.960815429687502 +1.595 -0.479400634765625 0.960815429687502 +1.595125 -0.47906494140625 0.960815429687502 +1.59525 -0.47906494140625 0.960815429687502 +1.595375 -0.478668212890625 0.960815429687502 +1.5955 -0.47821044921875 0.960815429687502 +1.595625 -0.47821044921875 0.960815429687502 +1.59575 -0.47772216796875 0.960815429687502 +1.595875 -0.47772216796875 0.960815429687502 +1.596 -0.4771728515625 0.960815429687502 +1.596125 -0.4765625 0.960815429687502 +1.59625 -0.4765625 0.960815429687502 +1.596375 -0.47589111328125 0.960815429687502 +1.5965 -0.47589111328125 0.960815429687502 +1.596625 -0.475189208984375 0.960815429687502 +1.59675 -0.47442626953125 0.960815429687502 +1.596875 -0.47442626953125 0.960815429687502 +1.597 -0.4736328125 0.960815429687502 +1.597125 -0.4736328125 0.960815429687502 +1.59725 -0.4727783203125 0.960815429687502 +1.597375 -0.471832275390625 0.960815429687502 +1.5975 -0.471832275390625 0.960815429687502 +1.597625 -0.47088623046875 0.960815429687502 +1.59775 -0.47088623046875 0.960815429687502 +1.597875 -0.4698486328125 0.960815429687502 +1.598 -0.468780517578125 0.960815429687502 +1.598125 -0.468780517578125 0.960815429687502 +1.59825 -0.4676513671875 0.960815429687502 +1.598375 -0.4676513671875 0.960815429687502 +1.5985 -0.46649169921875 0.960815429687502 +1.598625 -0.46527099609375 0.960815429687502 +1.59875 -0.46527099609375 0.960815429687502 +1.598875 -0.4639892578125 0.960815429687502 +1.599 -0.4639892578125 0.960815429687502 +1.599125 -0.462646484375 0.960815429687502 +1.59925 -0.461273193359375 0.960815429687502 +1.599375 -0.461273193359375 0.960815429687502 +1.5995 -0.4598388671875 0.960815429687502 +1.599625 -0.4598388671875 0.960815429687502 +1.59975 -0.4583740234375 0.960815429687502 +1.599875 -0.45684814453125 0.960815429687502 +1.6 -0.4739990234375 0.9968652343749994 +1.600125 -0.47235107421875 0.9968652343749994 +1.60025 -0.47235107421875 0.9968652343749994 +1.600375 -0.47064208984375 0.9968652343749994 +1.6005 -0.468902587890625 0.9968652343749994 +1.600625 -0.468902587890625 0.9968652343749994 +1.60075 -0.46710205078125 0.9968652343749994 +1.600875 -0.46710205078125 0.9968652343749994 +1.601 -0.46527099609375 0.9968652343749994 +1.601125 -0.46337890625 0.9968652343749994 +1.60125 -0.46337890625 0.9968652343749994 +1.601375 -0.46142578125 0.9968652343749994 +1.6015 -0.46142578125 0.9968652343749994 +1.601625 -0.459442138671875 0.9968652343749994 +1.60175 -0.4573974609375 0.9968652343749994 +1.601875 -0.4573974609375 0.9968652343749994 +1.602 -0.455291748046875 0.9968652343749994 +1.602125 -0.455291748046875 0.9968652343749994 +1.60225 -0.453125 0.9968652343749994 +1.602375 -0.450927734375 0.9968652343749994 +1.6025 -0.450927734375 0.9968652343749994 +1.602625 -0.448699951171875 0.9968652343749994 +1.60275 -0.448699951171875 0.9968652343749994 +1.602875 -0.446380615234375 0.9968652343749994 +1.603 -0.444061279296875 0.9968652343749994 +1.603125 -0.444061279296875 0.9968652343749994 +1.60325 -0.441650390625 0.9968652343749994 +1.603375 -0.441650390625 0.9968652343749994 +1.6035 -0.439208984375 0.9968652343749994 +1.603625 -0.43670654296875 0.9968652343749994 +1.60375 -0.43670654296875 0.9968652343749994 +1.603875 -0.4342041015625 0.9968652343749994 +1.604 -0.4342041015625 0.9968652343749994 +1.604125 -0.431610107421875 0.9968652343749994 +1.60425 -0.428955078125 0.9968652343749994 +1.604375 -0.428955078125 0.9968652343749994 +1.6045 -0.426300048828125 0.9968652343749994 +1.604625 -0.426300048828125 0.9968652343749994 +1.60475 -0.423553466796875 0.9968652343749994 +1.604875 -0.420806884765625 0.9968652343749994 +1.605 -0.420806884765625 0.9968652343749994 +1.605125 -0.41796875 0.9968652343749994 +1.60525 -0.41796875 0.9968652343749994 +1.605375 -0.41510009765625 0.9968652343749994 +1.6055 -0.41217041015625 0.9968652343749994 +1.605625 -0.41217041015625 0.9968652343749994 +1.60575 -0.40924072265625 0.9968652343749994 +1.605875 -0.40924072265625 0.9968652343749994 +1.606 -0.40625 0.9968652343749994 +1.606125 -0.4031982421875 0.9968652343749994 +1.60625 -0.4031982421875 0.9968652343749994 +1.606375 -0.40008544921875 0.9968652343749994 +1.6065 -0.40008544921875 0.9968652343749994 +1.606625 -0.39697265625 0.9968652343749994 +1.60675 -0.393798828125 0.9968652343749994 +1.606875 -0.393798828125 0.9968652343749994 +1.607 -0.39056396484375 0.9968652343749994 +1.607125 -0.39056396484375 0.9968652343749994 +1.60725 -0.387298583984375 0.9968652343749994 +1.607375 -0.384002685546875 0.9968652343749994 +1.6075 -0.384002685546875 0.9968652343749994 +1.607625 -0.380645751953125 0.9968652343749994 +1.60775 -0.380645751953125 0.9968652343749994 +1.607875 -0.37725830078125 0.9968652343749994 +1.608 -0.373809814453125 0.9968652343749994 +1.608125 -0.373809814453125 0.9968652343749994 +1.60825 -0.370361328125 0.9968652343749994 +1.608375 -0.370361328125 0.9968652343749994 +1.6085 -0.366851806640625 0.9968652343749994 +1.608625 -0.363311767578125 0.9968652343749994 +1.60875 -0.363311767578125 0.9968652343749994 +1.608875 -0.35968017578125 0.9968652343749994 +1.609 -0.35968017578125 0.9968652343749994 +1.609125 -0.3560791015625 0.9968652343749994 +1.60925 -0.352386474609375 0.9968652343749994 +1.609375 -0.352386474609375 0.9968652343749994 +1.6095 -0.34869384765625 0.9968652343749994 +1.609625 -0.34869384765625 0.9968652343749994 +1.60975 -0.344940185546875 0.9968652343749994 +1.609875 -0.341156005859375 0.9968652343749994 +1.61 -0.341156005859375 0.9968652343749994 +1.610125 -0.33734130859375 0.9968652343749994 +1.61025 -0.33734130859375 0.9968652343749994 +1.610375 -0.333465576171875 0.9968652343749994 +1.6105 -0.32958984375 0.9968652343749994 +1.610625 -0.32958984375 0.9968652343749994 +1.61075 -0.325653076171875 0.9968652343749994 +1.610875 -0.325653076171875 0.9968652343749994 +1.611 -0.3216552734375 0.9968652343749994 +1.611125 -0.317657470703125 0.9968652343749994 +1.61125 -0.317657470703125 0.9968652343749994 +1.611375 -0.313629150390625 0.9968652343749994 +1.6115 -0.313629150390625 0.9968652343749994 +1.611625 -0.3095703125 0.9968652343749994 +1.61175 -0.305450439453125 0.9968652343749994 +1.611875 -0.305450439453125 0.9968652343749994 +1.612 -0.301300048828125 0.9968652343749994 +1.612125 -0.301300048828125 0.9968652343749994 +1.61225 -0.297119140625 0.9968652343749994 +1.612375 -0.29290771484375 0.9968652343749994 +1.6125 -0.29290771484375 0.9968652343749994 +1.612625 -0.2886962890625 0.9968652343749994 +1.61275 -0.2886962890625 0.9968652343749994 +1.612875 -0.284423828125 0.9968652343749994 +1.613 -0.280120849609375 0.9968652343749994 +1.613125 -0.280120849609375 0.9968652343749994 +1.61325 -0.275787353515625 0.9968652343749994 +1.613375 -0.275787353515625 0.9968652343749994 +1.6135 -0.27142333984375 0.9968652343749994 +1.613625 -0.26702880859375 0.9968652343749994 +1.61375 -0.26702880859375 0.9968652343749994 +1.613875 -0.262603759765625 0.9968652343749994 +1.614 -0.262603759765625 0.9968652343749994 +1.614125 -0.2581787109375 0.9968652343749994 +1.61425 -0.253692626953125 0.9968652343749994 +1.614375 -0.253692626953125 0.9968652343749994 +1.6145 -0.249176025390625 0.9968652343749994 +1.614625 -0.249176025390625 0.9968652343749994 +1.61475 -0.24462890625 0.9968652343749994 +1.614875 -0.240081787109375 0.9968652343749994 +1.615 -0.240081787109375 0.9968652343749994 +1.615125 -0.235504150390625 0.9968652343749994 +1.61525 -0.235504150390625 0.9968652343749994 +1.615375 -0.230865478515625 0.9968652343749994 +1.6155 -0.226226806640625 0.9968652343749994 +1.615625 -0.226226806640625 0.9968652343749994 +1.61575 -0.221588134765625 0.9968652343749994 +1.615875 -0.221588134765625 0.9968652343749994 +1.616 -0.216888427734375 0.9968652343749994 +1.616125 -0.212188720703125 0.9968652343749994 +1.61625 -0.212188720703125 0.9968652343749994 +1.616375 -0.20745849609375 0.9968652343749994 +1.6165 -0.20745849609375 0.9968652343749994 +1.616625 -0.20269775390625 0.9968652343749994 +1.61675 -0.197906494140625 0.9968652343749994 +1.616875 -0.197906494140625 0.9968652343749994 +1.617 -0.193115234375 0.9968652343749994 +1.617125 -0.193115234375 0.9968652343749994 +1.61725 -0.18829345703125 0.9968652343749994 +1.617375 -0.183441162109375 0.9968652343749994 +1.6175 -0.183441162109375 0.9968652343749994 +1.617625 -0.1785888671875 0.9968652343749994 +1.61775 -0.1785888671875 0.9968652343749994 +1.617875 -0.1737060546875 0.9968652343749994 +1.618 -0.168792724609375 0.9968652343749994 +1.618125 -0.168792724609375 0.9968652343749994 +1.61825 -0.16387939453125 0.9968652343749994 +1.618375 -0.16387939453125 0.9968652343749994 +1.6185 -0.158935546875 0.9968652343749994 +1.618625 -0.15399169921875 0.9968652343749994 +1.61875 -0.15399169921875 0.9968652343749994 +1.618875 -0.149017333984375 0.9968652343749994 +1.619 -0.149017333984375 0.9968652343749994 +1.619125 -0.144012451171875 0.9968652343749994 +1.61925 -0.139007568359375 0.9968652343749994 +1.619375 -0.139007568359375 0.9968652343749994 +1.6195 -0.134002685546875 0.9968652343749994 +1.619625 -0.134002685546875 0.9968652343749994 +1.61975 -0.12896728515625 0.9968652343749994 +1.619875 -0.123931884765625 0.9968652343749994 +1.62 -0.123931884765625 0.9968652343749994 +1.620125 -0.118865966796875 0.9968652343749994 +1.62025 -0.118865966796875 0.9968652343749994 +1.620375 -0.113800048828125 0.9968652343749994 +1.6205 -0.10870361328125 0.9968652343749994 +1.620625 -0.10870361328125 0.9968652343749994 +1.62075 -0.103607177734375 0.9968652343749994 +1.620875 -0.103607177734375 0.9968652343749994 +1.621 -0.098480224609375 0.9968652343749994 +1.621125 -0.093353271484375 0.9968652343749994 +1.62125 -0.093353271484375 0.9968652343749994 +1.621375 -0.088226318359375 0.9968652343749994 +1.6215 -0.088226318359375 0.9968652343749994 +1.621625 -0.083099365234375 0.9968652343749994 +1.62175 -0.07794189453125 0.9968652343749994 +1.621875 -0.07794189453125 0.9968652343749994 +1.622 -0.072784423828125 0.9968652343749994 +1.622125 -0.072784423828125 0.9968652343749994 +1.62225 -0.067596435546875 0.9968652343749994 +1.622375 -0.06243896484375 0.9968652343749994 +1.6225 -0.06243896484375 0.9968652343749994 +1.622625 -0.057281494140625 0.9968652343749994 +1.62275 -0.057281494140625 0.9968652343749994 +1.622875 -0.052093505859375 0.9968652343749994 +1.623 -0.046875 0.9968652343749994 +1.623125 -0.046875 0.9968652343749994 +1.62325 -0.04168701171875 0.9968652343749994 +1.623375 -0.04168701171875 0.9968652343749994 +1.6235 -0.036468505859375 0.9968652343749994 +1.623625 -0.031280517578125 0.9968652343749994 +1.62375 -0.031280517578125 0.9968652343749994 +1.623875 -0.02606201171875 0.9968652343749994 +1.624 -0.02606201171875 0.9968652343749994 +1.624125 -0.020843505859375 0.9968652343749994 +1.62425 -0.015625 0.9968652343749994 +1.624375 -0.015625 0.9968652343749994 +1.6245 -0.010406494140625 0.9968652343749994 +1.624625 -0.010406494140625 0.9968652343749994 +1.62475 -0.00518798828125 0.9968652343749994 1.624875 0.0 0.9968652343749994 1.625 0.0 0.9968652343749994 1.625125 0.00518798828125 0.9968652343749994 @@ -13499,504 +13499,504 @@ 1.68725 0.003662109375 0.7021142578124948 1.687375 0.0 0.7021142578124948 1.6875 0.0 0.7021142578124948 -1.687625 -0.003692626953125 0.7021142578124948 -1.68775 -0.003692626953125 0.7021142578124948 -1.687875 -0.007354736328125 0.7021142578124948 -1.688 -0.01104736328125 0.7021142578124948 -1.688125 -0.01104736328125 0.7021142578124948 -1.68825 -0.01470947265625 0.7021142578124948 -1.688375 -0.01470947265625 0.7021142578124948 -1.6885 -0.01837158203125 0.7021142578124948 -1.688625 -0.022064208984375 0.7021142578124948 -1.68875 -0.022064208984375 0.7021142578124948 -1.688875 -0.025726318359375 0.7021142578124948 -1.689 -0.025726318359375 0.7021142578124948 -1.689125 -0.029388427734375 0.7021142578124948 -1.68925 -0.033050537109375 0.7021142578124948 -1.689375 -0.033050537109375 0.7021142578124948 -1.6895 -0.036712646484375 0.7021142578124948 -1.689625 -0.036712646484375 0.7021142578124948 -1.68975 -0.040374755859375 0.7021142578124948 -1.689875 -0.04400634765625 0.7021142578124948 -1.69 -0.04400634765625 0.7021142578124948 -1.690125 -0.047637939453125 0.7021142578124948 -1.69025 -0.047637939453125 0.7021142578124948 -1.690375 -0.051300048828125 0.7021142578124948 -1.6905 -0.054931640625 0.7021142578124948 -1.690625 -0.054931640625 0.7021142578124948 -1.69075 -0.058563232421875 0.7021142578124948 -1.690875 -0.058563232421875 0.7021142578124948 -1.691 -0.062164306640625 0.7021142578124948 -1.691125 -0.0657958984375 0.7021142578124948 -1.69125 -0.0657958984375 0.7021142578124948 -1.691375 -0.06939697265625 0.7021142578124948 -1.6915 -0.06939697265625 0.7021142578124948 -1.691625 -0.072998046875 0.7021142578124948 -1.69175 -0.076568603515625 0.7021142578124948 -1.691875 -0.076568603515625 0.7021142578124948 -1.692 -0.080169677734375 0.7021142578124948 -1.692125 -0.080169677734375 0.7021142578124948 -1.69225 -0.083740234375 0.7021142578124948 -1.692375 -0.087310791015625 0.7021142578124948 -1.6925 -0.087310791015625 0.7021142578124948 -1.692625 -0.090850830078125 0.7021142578124948 -1.69275 -0.090850830078125 0.7021142578124948 -1.692875 -0.09442138671875 0.7021142578124948 -1.693 -0.097930908203125 0.7021142578124948 -1.693125 -0.097930908203125 0.7021142578124948 -1.69325 -0.101470947265625 0.7021142578124948 -1.693375 -0.101470947265625 0.7021142578124948 -1.6935 -0.10498046875 0.7021142578124948 -1.693625 -0.108489990234375 0.7021142578124948 -1.69375 -0.108489990234375 0.7021142578124948 -1.693875 -0.111968994140625 0.7021142578124948 -1.694 -0.111968994140625 0.7021142578124948 -1.694125 -0.115447998046875 0.7021142578124948 -1.69425 -0.118927001953125 0.7021142578124948 -1.694375 -0.118927001953125 0.7021142578124948 -1.6945 -0.12237548828125 0.7021142578124948 -1.694625 -0.12237548828125 0.7021142578124948 -1.69475 -0.12579345703125 0.7021142578124948 -1.694875 -0.129241943359375 0.7021142578124948 -1.695 -0.129241943359375 0.7021142578124948 -1.695125 -0.13262939453125 0.7021142578124948 -1.69525 -0.13262939453125 0.7021142578124948 -1.695375 -0.13604736328125 0.7021142578124948 -1.6955 -0.139434814453125 0.7021142578124948 -1.695625 -0.139434814453125 0.7021142578124948 -1.69575 -0.142791748046875 0.7021142578124948 -1.695875 -0.142791748046875 0.7021142578124948 -1.696 -0.087066650390625 0.4183349609374934 -1.696125 -0.08905029296875 0.4183349609374934 -1.69625 -0.08905029296875 0.4183349609374934 -1.696375 -0.091033935546875 0.4183349609374934 -1.6965 -0.091033935546875 0.4183349609374934 -1.696625 -0.093017578125 0.4183349609374934 -1.69675 -0.094970703125 0.4183349609374934 -1.696875 -0.094970703125 0.4183349609374934 -1.697 -0.096893310546875 0.4183349609374934 -1.697125 -0.096893310546875 0.4183349609374934 -1.69725 -0.098846435546875 0.4183349609374934 -1.697375 -0.10076904296875 0.4183349609374934 -1.6975 -0.10076904296875 0.4183349609374934 -1.697625 -0.102691650390625 0.4183349609374934 -1.69775 -0.102691650390625 0.4183349609374934 -1.697875 -0.104583740234375 0.4183349609374934 -1.698 -0.106475830078125 0.4183349609374934 -1.698125 -0.106475830078125 0.4183349609374934 -1.69825 -0.108367919921875 0.4183349609374934 -1.698375 -0.108367919921875 0.4183349609374934 -1.6985 -0.1102294921875 0.4183349609374934 -1.698625 -0.112091064453125 0.4183349609374934 -1.69875 -0.112091064453125 0.4183349609374934 -1.698875 -0.113922119140625 0.4183349609374934 -1.699 -0.113922119140625 0.4183349609374934 -1.699125 -0.115753173828125 0.4183349609374934 -1.69925 -0.1175537109375 0.4183349609374934 -1.699375 -0.1175537109375 0.4183349609374934 -1.6995 -0.119384765625 0.4183349609374934 -1.699625 -0.119384765625 0.4183349609374934 -1.69975 -0.12115478515625 0.4183349609374934 -1.699875 -0.122955322265625 0.4183349609374934 -1.7 -0.122955322265625 0.4183349609374934 -1.700125 -0.12469482421875 0.4183349609374934 -1.70025 -0.12469482421875 0.4183349609374934 -1.700375 -0.12646484375 0.4183349609374934 -1.7005 -0.128204345703125 0.4183349609374934 -1.700625 -0.128204345703125 0.4183349609374934 -1.70075 -0.129913330078125 0.4183349609374934 -1.700875 -0.129913330078125 0.4183349609374934 -1.701 -0.131622314453125 0.4183349609374934 -1.701125 -0.133331298828125 0.4183349609374934 -1.70125 -0.133331298828125 0.4183349609374934 -1.701375 -0.135009765625 0.4183349609374934 -1.7015 -0.135009765625 0.4183349609374934 -1.701625 -0.13665771484375 0.4183349609374934 -1.70175 -0.138336181640625 0.4183349609374934 -1.701875 -0.138336181640625 0.4183349609374934 -1.702 -0.13995361328125 0.4183349609374934 -1.702125 -0.13995361328125 0.4183349609374934 -1.70225 -0.141571044921875 0.4183349609374934 -1.702375 -0.1431884765625 0.4183349609374934 -1.7025 -0.1431884765625 0.4183349609374934 -1.702625 -0.144775390625 0.4183349609374934 -1.70275 -0.144775390625 0.4183349609374934 -1.702875 -0.146331787109375 0.4183349609374934 -1.703 -0.14788818359375 0.4183349609374934 -1.703125 -0.14788818359375 0.4183349609374934 -1.70325 -0.149444580078125 0.4183349609374934 -1.703375 -0.149444580078125 0.4183349609374934 -1.7035 -0.150970458984375 0.4183349609374934 -1.703625 -0.1524658203125 0.4183349609374934 -1.70375 -0.1524658203125 0.4183349609374934 -1.703875 -0.153961181640625 0.4183349609374934 -1.704 -0.153961181640625 0.4183349609374934 -1.704125 -0.155426025390625 0.4183349609374934 -1.70425 -0.156890869140625 0.4183349609374934 -1.704375 -0.156890869140625 0.4183349609374934 -1.7045 -0.1583251953125 0.4183349609374934 -1.704625 -0.1583251953125 0.4183349609374934 -1.70475 -0.159759521484375 0.4183349609374934 -1.704875 -0.161163330078125 0.4183349609374934 -1.705 -0.161163330078125 0.4183349609374934 -1.705125 -0.16253662109375 0.4183349609374934 -1.70525 -0.16253662109375 0.4183349609374934 -1.705375 -0.163909912109375 0.4183349609374934 -1.7055 -0.165283203125 0.4183349609374934 -1.705625 -0.165283203125 0.4183349609374934 -1.70575 -0.166595458984375 0.4183349609374934 -1.705875 -0.166595458984375 0.4183349609374934 -1.706 -0.16790771484375 0.4183349609374934 -1.706125 -0.169219970703125 0.4183349609374934 -1.70625 -0.169219970703125 0.4183349609374934 -1.706375 -0.170501708984375 0.4183349609374934 -1.7065 -0.170501708984375 0.4183349609374934 -1.706625 -0.1717529296875 0.4183349609374934 -1.70675 -0.173004150390625 0.4183349609374934 -1.706875 -0.173004150390625 0.4183349609374934 -1.707 -0.174224853515625 0.4183349609374934 -1.707125 -0.174224853515625 0.4183349609374934 -1.70725 -0.1754150390625 0.4183349609374934 -1.707375 -0.176605224609375 0.4183349609374934 -1.7075 -0.176605224609375 0.4183349609374934 -1.707625 -0.177764892578125 0.4183349609374934 -1.70775 -0.177764892578125 0.4183349609374934 -1.707875 -0.17889404296875 0.4183349609374934 -1.708 -0.180023193359375 0.4183349609374934 -1.708125 -0.180023193359375 0.4183349609374934 -1.70825 -0.18115234375 0.4183349609374934 -1.708375 -0.18115234375 0.4183349609374934 -1.7085 -0.182220458984375 0.4183349609374934 -1.708625 -0.18328857421875 0.4183349609374934 -1.70875 -0.18328857421875 0.4183349609374934 -1.708875 -0.184326171875 0.4183349609374934 -1.709 -0.184326171875 0.4183349609374934 -1.709125 -0.18536376953125 0.4183349609374934 -1.70925 -0.186370849609375 0.4183349609374934 -1.709375 -0.186370849609375 0.4183349609374934 -1.7095 -0.187347412109375 0.4183349609374934 -1.709625 -0.187347412109375 0.4183349609374934 -1.70975 -0.18829345703125 0.4183349609374934 -1.709875 -0.189239501953125 0.4183349609374934 -1.71 -0.189239501953125 0.4183349609374934 -1.710125 -0.190185546875 0.4183349609374934 -1.71025 -0.190185546875 0.4183349609374934 -1.710375 -0.191070556640625 0.4183349609374934 -1.7105 -0.19195556640625 0.4183349609374934 -1.710625 -0.19195556640625 0.4183349609374934 -1.71075 -0.19281005859375 0.4183349609374934 -1.710875 -0.19281005859375 0.4183349609374934 -1.711 -0.19366455078125 0.4183349609374934 -1.711125 -0.1944580078125 0.4183349609374934 -1.71125 -0.1944580078125 0.4183349609374934 -1.711375 -0.19525146484375 0.4183349609374934 -1.7115 -0.19525146484375 0.4183349609374934 -1.711625 -0.196044921875 0.4183349609374934 -1.71175 -0.19677734375 0.4183349609374934 -1.711875 -0.19677734375 0.4183349609374934 -1.712 -0.197540283203125 0.4183349609374934 -1.712125 -0.197540283203125 0.4183349609374934 -1.71225 -0.1982421875 0.4183349609374934 -1.712375 -0.19891357421875 0.4183349609374934 -1.7125 -0.19891357421875 0.4183349609374934 -1.712625 -0.1995849609375 0.4183349609374934 -1.71275 -0.1995849609375 0.4183349609374934 -1.712875 -0.200225830078125 0.4183349609374934 -1.713 -0.200836181640625 0.4183349609374934 -1.713125 -0.200836181640625 0.4183349609374934 -1.71325 -0.201446533203125 0.4183349609374934 -1.713375 -0.201446533203125 0.4183349609374934 -1.7135 -0.2020263671875 0.4183349609374934 -1.713625 -0.20257568359375 0.4183349609374934 -1.71375 -0.20257568359375 0.4183349609374934 -1.713875 -0.203125 0.4183349609374934 -1.714 -0.203125 0.4183349609374934 -1.714125 -0.203643798828125 0.4183349609374934 -1.71425 -0.204132080078125 0.4183349609374934 -1.714375 -0.204132080078125 0.4183349609374934 -1.7145 -0.20458984375 0.4183349609374934 -1.714625 -0.20458984375 0.4183349609374934 -1.71475 -0.20501708984375 0.4183349609374934 -1.714875 -0.2054443359375 0.4183349609374934 -1.715 -0.2054443359375 0.4183349609374934 -1.715125 -0.205841064453125 0.4183349609374934 -1.71525 -0.205841064453125 0.4183349609374934 -1.715375 -0.20623779296875 0.4183349609374934 -1.7155 -0.206573486328125 0.4183349609374934 -1.715625 -0.206573486328125 0.4183349609374934 -1.71575 -0.2069091796875 0.4183349609374934 -1.715875 -0.2069091796875 0.4183349609374934 -1.716 -0.20721435546875 0.4183349609374934 -1.716125 -0.20751953125 0.4183349609374934 -1.71625 -0.20751953125 0.4183349609374934 -1.716375 -0.207763671875 0.4183349609374934 -1.7165 -0.207763671875 0.4183349609374934 -1.716625 -0.2080078125 0.4183349609374934 -1.71675 -0.208221435546875 0.4183349609374934 -1.716875 -0.208221435546875 0.4183349609374934 -1.717 -0.20843505859375 0.4183349609374934 -1.717125 -0.20843505859375 0.4183349609374934 -1.71725 -0.208587646484375 0.4183349609374934 -1.717375 -0.208740234375 0.4183349609374934 -1.7175 -0.208740234375 0.4183349609374934 -1.717625 -0.2088623046875 0.4183349609374934 -1.71775 -0.2088623046875 0.4183349609374934 -1.717875 -0.208984375 0.4183349609374934 -1.718 -0.20904541015625 0.4183349609374934 -1.718125 -0.20904541015625 0.4183349609374934 -1.71825 -0.2091064453125 0.4183349609374934 -1.718375 -0.2091064453125 0.4183349609374934 -1.7185 -0.209136962890625 0.4183349609374934 -1.718625 -0.20916748046875 0.4183349609374934 -1.71875 -0.20916748046875 0.4183349609374934 -1.718875 -0.209136962890625 0.4183349609374934 -1.719 -0.209136962890625 0.4183349609374934 -1.719125 -0.2091064453125 0.4183349609374934 -1.71925 -0.20904541015625 0.4183349609374934 -1.719375 -0.20904541015625 0.4183349609374934 -1.7195 -0.208984375 0.4183349609374934 -1.719625 -0.208984375 0.4183349609374934 -1.71975 -0.2088623046875 0.4183349609374934 -1.719875 -0.208740234375 0.4183349609374934 -1.72 -0.208740234375 0.4183349609374934 -1.720125 -0.208587646484375 0.4183349609374934 -1.72025 -0.208587646484375 0.4183349609374934 -1.720375 -0.20843505859375 0.4183349609374934 -1.7205 -0.208221435546875 0.4183349609374934 -1.720625 -0.208221435546875 0.4183349609374934 -1.72075 -0.2080078125 0.4183349609374934 -1.720875 -0.2080078125 0.4183349609374934 -1.721 -0.207763671875 0.4183349609374934 -1.721125 -0.20751953125 0.4183349609374934 -1.72125 -0.20751953125 0.4183349609374934 -1.721375 -0.20721435546875 0.4183349609374934 -1.7215 -0.20721435546875 0.4183349609374934 -1.721625 -0.2069091796875 0.4183349609374934 -1.72175 -0.206573486328125 0.4183349609374934 -1.721875 -0.206573486328125 0.4183349609374934 -1.722 -0.20623779296875 0.4183349609374934 -1.722125 -0.20623779296875 0.4183349609374934 -1.72225 -0.205841064453125 0.4183349609374934 -1.722375 -0.2054443359375 0.4183349609374934 -1.7225 -0.2054443359375 0.4183349609374934 -1.722625 -0.20501708984375 0.4183349609374934 -1.72275 -0.20501708984375 0.4183349609374934 -1.722875 -0.20458984375 0.4183349609374934 -1.723 -0.204132080078125 0.4183349609374934 -1.723125 -0.204132080078125 0.4183349609374934 -1.72325 -0.203643798828125 0.4183349609374934 -1.723375 -0.203643798828125 0.4183349609374934 -1.7235 -0.203125 0.4183349609374934 -1.723625 -0.20257568359375 0.4183349609374934 -1.72375 -0.20257568359375 0.4183349609374934 -1.723875 -0.2020263671875 0.4183349609374934 -1.724 -0.2020263671875 0.4183349609374934 -1.724125 -0.201446533203125 0.4183349609374934 -1.72425 -0.200836181640625 0.4183349609374934 -1.724375 -0.200836181640625 0.4183349609374934 -1.7245 -0.200225830078125 0.4183349609374934 -1.724625 -0.200225830078125 0.4183349609374934 -1.72475 -0.1995849609375 0.4183349609374934 -1.724875 -0.19891357421875 0.4183349609374934 -1.725 -0.19891357421875 0.4183349609374934 -1.725125 -0.1982421875 0.4183349609374934 -1.72525 -0.1982421875 0.4183349609374934 -1.725375 -0.197540283203125 0.4183349609374934 -1.7255 -0.19677734375 0.4183349609374934 -1.725625 -0.19677734375 0.4183349609374934 -1.72575 -0.196044921875 0.4183349609374934 -1.725875 -0.196044921875 0.4183349609374934 -1.726 -0.19525146484375 0.4183349609374934 -1.726125 -0.1944580078125 0.4183349609374934 -1.72625 -0.1944580078125 0.4183349609374934 -1.726375 -0.19366455078125 0.4183349609374934 -1.7265 -0.19366455078125 0.4183349609374934 -1.726625 -0.19281005859375 0.4183349609374934 -1.72675 -0.19195556640625 0.4183349609374934 -1.726875 -0.19195556640625 0.4183349609374934 -1.727 -0.191070556640625 0.4183349609374934 -1.727125 -0.191070556640625 0.4183349609374934 -1.72725 -0.190185546875 0.4183349609374934 -1.727375 -0.189239501953125 0.4183349609374934 -1.7275 -0.189239501953125 0.4183349609374934 -1.727625 -0.18829345703125 0.4183349609374934 -1.72775 -0.18829345703125 0.4183349609374934 -1.727875 -0.187347412109375 0.4183349609374934 -1.728 -0.04443359375 0.09975585937499341 -1.728125 -0.04443359375 0.09975585937499341 -1.72825 -0.044219970703125 0.09975585937499341 -1.728375 -0.044219970703125 0.09975585937499341 -1.7285 -0.0439453125 0.09975585937499341 -1.728625 -0.043701171875 0.09975585937499341 -1.72875 -0.043701171875 0.09975585937499341 -1.728875 -0.04345703125 0.09975585937499341 -1.729 -0.04345703125 0.09975585937499341 -1.729125 -0.043212890625 0.09975585937499341 -1.72925 -0.042938232421875 0.09975585937499341 -1.729375 -0.042938232421875 0.09975585937499341 -1.7295 -0.04266357421875 0.09975585937499341 -1.729625 -0.04266357421875 0.09975585937499341 -1.72975 -0.042388916015625 0.09975585937499341 -1.729875 -0.0421142578125 0.09975585937499341 -1.73 -0.0421142578125 0.09975585937499341 -1.730125 -0.041839599609375 0.09975585937499341 -1.73025 -0.041839599609375 0.09975585937499341 -1.730375 -0.041534423828125 0.09975585937499341 -1.7305 -0.041259765625 0.09975585937499341 -1.730625 -0.041259765625 0.09975585937499341 -1.73075 -0.04095458984375 0.09975585937499341 -1.730875 -0.04095458984375 0.09975585937499341 -1.731 -0.0406494140625 0.09975585937499341 -1.731125 -0.04034423828125 0.09975585937499341 -1.73125 -0.04034423828125 0.09975585937499341 -1.731375 -0.0400390625 0.09975585937499341 -1.7315 -0.0400390625 0.09975585937499341 -1.731625 -0.03973388671875 0.09975585937499341 -1.73175 -0.0394287109375 0.09975585937499341 -1.731875 -0.0394287109375 0.09975585937499341 -1.732 -0.039093017578125 0.09975585937499341 -1.732125 -0.039093017578125 0.09975585937499341 -1.73225 -0.03875732421875 0.09975585937499341 -1.732375 -0.038421630859375 0.09975585937499341 -1.7325 -0.038421630859375 0.09975585937499341 -1.732625 -0.0380859375 0.09975585937499341 -1.73275 -0.0380859375 0.09975585937499341 -1.732875 -0.037750244140625 0.09975585937499341 -1.733 -0.03741455078125 0.09975585937499341 -1.733125 -0.03741455078125 0.09975585937499341 -1.73325 -0.037078857421875 0.09975585937499341 -1.733375 -0.037078857421875 0.09975585937499341 -1.7335 -0.036712646484375 0.09975585937499341 -1.733625 -0.036376953125 0.09975585937499341 -1.73375 -0.036376953125 0.09975585937499341 -1.733875 -0.0360107421875 0.09975585937499341 -1.734 -0.0360107421875 0.09975585937499341 -1.734125 -0.03564453125 0.09975585937499341 -1.73425 -0.0352783203125 0.09975585937499341 -1.734375 -0.0352783203125 0.09975585937499341 -1.7345 -0.034912109375 0.09975585937499341 -1.734625 -0.034912109375 0.09975585937499341 -1.73475 -0.034515380859375 0.09975585937499341 -1.734875 -0.034149169921875 0.09975585937499341 -1.735 -0.034149169921875 0.09975585937499341 -1.735125 -0.03375244140625 0.09975585937499341 -1.73525 -0.03375244140625 0.09975585937499341 -1.735375 -0.03338623046875 0.09975585937499341 -1.7355 -0.032989501953125 0.09975585937499341 -1.735625 -0.032989501953125 0.09975585937499341 -1.73575 -0.0325927734375 0.09975585937499341 -1.735875 -0.0325927734375 0.09975585937499341 -1.736 -0.032196044921875 0.09975585937499341 -1.736125 -0.03179931640625 0.09975585937499341 -1.73625 -0.03179931640625 0.09975585937499341 -1.736375 -0.031402587890625 0.09975585937499341 -1.7365 -0.031402587890625 0.09975585937499341 -1.736625 -0.030975341796875 0.09975585937499341 -1.73675 -0.03057861328125 0.09975585937499341 -1.736875 -0.03057861328125 0.09975585937499341 -1.737 -0.0301513671875 0.09975585937499341 -1.737125 -0.0301513671875 0.09975585937499341 -1.73725 -0.029754638671875 0.09975585937499341 -1.737375 -0.029327392578125 0.09975585937499341 -1.7375 -0.029327392578125 0.09975585937499341 -1.737625 -0.028900146484375 0.09975585937499341 -1.73775 -0.028900146484375 0.09975585937499341 -1.737875 -0.028472900390625 0.09975585937499341 -1.738 -0.028045654296875 0.09975585937499341 -1.738125 -0.028045654296875 0.09975585937499341 -1.73825 -0.027618408203125 0.09975585937499341 -1.738375 -0.027618408203125 0.09975585937499341 -1.7385 -0.02716064453125 0.09975585937499341 -1.738625 -0.0267333984375 0.09975585937499341 -1.73875 -0.0267333984375 0.09975585937499341 -1.738875 -0.026275634765625 0.09975585937499341 -1.739 -0.026275634765625 0.09975585937499341 -1.739125 -0.025848388671875 0.09975585937499341 -1.73925 -0.025390625 0.09975585937499341 -1.739375 -0.025390625 0.09975585937499341 -1.7395 -0.024932861328125 0.09975585937499341 -1.739625 -0.024932861328125 0.09975585937499341 -1.73975 -0.024505615234375 0.09975585937499341 -1.739875 -0.0240478515625 0.09975585937499341 -1.74 -0.0240478515625 0.09975585937499341 -1.740125 -0.023590087890625 0.09975585937499341 -1.74025 -0.023590087890625 0.09975585937499341 -1.740375 -0.023101806640625 0.09975585937499341 -1.7405 -0.02264404296875 0.09975585937499341 -1.740625 -0.02264404296875 0.09975585937499341 -1.74075 -0.022186279296875 0.09975585937499341 -1.740875 -0.022186279296875 0.09975585937499341 -1.741 -0.021728515625 0.09975585937499341 -1.741125 -0.021240234375 0.09975585937499341 -1.74125 -0.021240234375 0.09975585937499341 -1.741375 -0.020782470703125 0.09975585937499341 -1.7415 -0.020782470703125 0.09975585937499341 -1.741625 -0.020294189453125 0.09975585937499341 -1.74175 -0.019805908203125 0.09975585937499341 -1.741875 -0.019805908203125 0.09975585937499341 -1.742 -0.01934814453125 0.09975585937499341 -1.742125 -0.01934814453125 0.09975585937499341 -1.74225 -0.01885986328125 0.09975585937499341 -1.742375 -0.01837158203125 0.09975585937499341 -1.7425 -0.01837158203125 0.09975585937499341 -1.742625 -0.01788330078125 0.09975585937499341 -1.74275 -0.01788330078125 0.09975585937499341 -1.742875 -0.01739501953125 0.09975585937499341 -1.743 -0.01690673828125 0.09975585937499341 -1.743125 -0.01690673828125 0.09975585937499341 -1.74325 -0.01641845703125 0.09975585937499341 -1.743375 -0.01641845703125 0.09975585937499341 -1.7435 -0.01593017578125 0.09975585937499341 -1.743625 -0.015411376953125 0.09975585937499341 -1.74375 -0.015411376953125 0.09975585937499341 -1.743875 -0.014923095703125 0.09975585937499341 -1.744 -0.014923095703125 0.09975585937499341 -1.744125 -0.014434814453125 0.09975585937499341 -1.74425 -0.013916015625 0.09975585937499341 -1.744375 -0.013916015625 0.09975585937499341 -1.7445 -0.013427734375 0.09975585937499341 -1.744625 -0.013427734375 0.09975585937499341 -1.74475 -0.012908935546875 0.09975585937499341 -1.744875 -0.012420654296875 0.09975585937499341 -1.745 -0.012420654296875 0.09975585937499341 -1.745125 -0.01190185546875 0.09975585937499341 -1.74525 -0.01190185546875 0.09975585937499341 -1.745375 -0.01141357421875 0.09975585937499341 -1.7455 -0.010894775390625 0.09975585937499341 -1.745625 -0.010894775390625 0.09975585937499341 -1.74575 -0.0103759765625 0.09975585937499341 -1.745875 -0.0103759765625 0.09975585937499341 -1.746 -0.009857177734375 0.09975585937499341 -1.746125 -0.009368896484375 0.09975585937499341 -1.74625 -0.009368896484375 0.09975585937499341 -1.746375 -0.00885009765625 0.09975585937499341 -1.7465 -0.00885009765625 0.09975585937499341 -1.746625 -0.008331298828125 0.09975585937499341 -1.74675 -0.0078125 0.09975585937499341 -1.746875 -0.0078125 0.09975585937499341 -1.747 -0.007293701171875 0.09975585937499341 -1.747125 -0.007293701171875 0.09975585937499341 -1.74725 -0.00677490234375 0.09975585937499341 -1.747375 -0.006256103515625 0.09975585937499341 -1.7475 -0.006256103515625 0.09975585937499341 -1.747625 -0.0057373046875 0.09975585937499341 -1.74775 -0.0057373046875 0.09975585937499341 -1.747875 -0.005218505859375 0.09975585937499341 -1.748 -0.00469970703125 0.09975585937499341 -1.748125 -0.00469970703125 0.09975585937499341 -1.74825 -0.004180908203125 0.09975585937499341 -1.748375 -0.004180908203125 0.09975585937499341 -1.7485 -0.003662109375 0.09975585937499341 -1.748625 -0.003143310546875 0.09975585937499341 -1.74875 -0.003143310546875 0.09975585937499341 -1.748875 -0.00262451171875 0.09975585937499341 -1.749 -0.00262451171875 0.09975585937499341 -1.749125 -0.002105712890625 0.09975585937499341 -1.74925 -0.0015869140625 0.09975585937499341 -1.749375 -0.0015869140625 0.09975585937499341 -1.7495 -0.001068115234375 0.09975585937499341 -1.749625 -0.001068115234375 0.09975585937499341 -1.74975 -0.00054931640625 0.09975585937499341 +1.687625 -0.003662109375 0.7021142578124948 +1.68775 -0.003662109375 0.7021142578124948 +1.687875 -0.00732421875 0.7021142578124948 +1.688 -0.011016845703125 0.7021142578124948 +1.688125 -0.011016845703125 0.7021142578124948 +1.68825 -0.014678955078125 0.7021142578124948 +1.688375 -0.014678955078125 0.7021142578124948 +1.6885 -0.018341064453125 0.7021142578124948 +1.688625 -0.02203369140625 0.7021142578124948 +1.68875 -0.02203369140625 0.7021142578124948 +1.688875 -0.02569580078125 0.7021142578124948 +1.689 -0.02569580078125 0.7021142578124948 +1.689125 -0.02935791015625 0.7021142578124948 +1.68925 -0.03302001953125 0.7021142578124948 +1.689375 -0.03302001953125 0.7021142578124948 +1.6895 -0.03668212890625 0.7021142578124948 +1.689625 -0.03668212890625 0.7021142578124948 +1.68975 -0.04034423828125 0.7021142578124948 +1.689875 -0.043975830078125 0.7021142578124948 +1.69 -0.043975830078125 0.7021142578124948 +1.690125 -0.047607421875 0.7021142578124948 +1.69025 -0.047607421875 0.7021142578124948 +1.690375 -0.05126953125 0.7021142578124948 +1.6905 -0.054901123046875 0.7021142578124948 +1.690625 -0.054901123046875 0.7021142578124948 +1.69075 -0.05853271484375 0.7021142578124948 +1.690875 -0.05853271484375 0.7021142578124948 +1.691 -0.0621337890625 0.7021142578124948 +1.691125 -0.065765380859375 0.7021142578124948 +1.69125 -0.065765380859375 0.7021142578124948 +1.691375 -0.069366455078125 0.7021142578124948 +1.6915 -0.069366455078125 0.7021142578124948 +1.691625 -0.072967529296875 0.7021142578124948 +1.69175 -0.0765380859375 0.7021142578124948 +1.691875 -0.0765380859375 0.7021142578124948 +1.692 -0.08013916015625 0.7021142578124948 +1.692125 -0.08013916015625 0.7021142578124948 +1.69225 -0.083709716796875 0.7021142578124948 +1.692375 -0.0872802734375 0.7021142578124948 +1.6925 -0.0872802734375 0.7021142578124948 +1.692625 -0.0908203125 0.7021142578124948 +1.69275 -0.0908203125 0.7021142578124948 +1.692875 -0.094390869140625 0.7021142578124948 +1.693 -0.097900390625 0.7021142578124948 +1.693125 -0.097900390625 0.7021142578124948 +1.69325 -0.1014404296875 0.7021142578124948 +1.693375 -0.1014404296875 0.7021142578124948 +1.6935 -0.104949951171875 0.7021142578124948 +1.693625 -0.10845947265625 0.7021142578124948 +1.69375 -0.10845947265625 0.7021142578124948 +1.693875 -0.1119384765625 0.7021142578124948 +1.694 -0.1119384765625 0.7021142578124948 +1.694125 -0.11541748046875 0.7021142578124948 +1.69425 -0.118896484375 0.7021142578124948 +1.694375 -0.118896484375 0.7021142578124948 +1.6945 -0.122344970703125 0.7021142578124948 +1.694625 -0.122344970703125 0.7021142578124948 +1.69475 -0.125762939453125 0.7021142578124948 +1.694875 -0.12921142578125 0.7021142578124948 +1.695 -0.12921142578125 0.7021142578124948 +1.695125 -0.132598876953125 0.7021142578124948 +1.69525 -0.132598876953125 0.7021142578124948 +1.695375 -0.136016845703125 0.7021142578124948 +1.6955 -0.139404296875 0.7021142578124948 +1.695625 -0.139404296875 0.7021142578124948 +1.69575 -0.14276123046875 0.7021142578124948 +1.695875 -0.14276123046875 0.7021142578124948 +1.696 -0.0870361328125 0.4183349609374934 +1.696125 -0.089019775390625 0.4183349609374934 +1.69625 -0.089019775390625 0.4183349609374934 +1.696375 -0.09100341796875 0.4183349609374934 +1.6965 -0.09100341796875 0.4183349609374934 +1.696625 -0.092987060546875 0.4183349609374934 +1.69675 -0.094940185546875 0.4183349609374934 +1.696875 -0.094940185546875 0.4183349609374934 +1.697 -0.09686279296875 0.4183349609374934 +1.697125 -0.09686279296875 0.4183349609374934 +1.69725 -0.09881591796875 0.4183349609374934 +1.697375 -0.100738525390625 0.4183349609374934 +1.6975 -0.100738525390625 0.4183349609374934 +1.697625 -0.1026611328125 0.4183349609374934 +1.69775 -0.1026611328125 0.4183349609374934 +1.697875 -0.10455322265625 0.4183349609374934 +1.698 -0.1064453125 0.4183349609374934 +1.698125 -0.1064453125 0.4183349609374934 +1.69825 -0.10833740234375 0.4183349609374934 +1.698375 -0.10833740234375 0.4183349609374934 +1.6985 -0.110198974609375 0.4183349609374934 +1.698625 -0.112060546875 0.4183349609374934 +1.69875 -0.112060546875 0.4183349609374934 +1.698875 -0.1138916015625 0.4183349609374934 +1.699 -0.1138916015625 0.4183349609374934 +1.699125 -0.11572265625 0.4183349609374934 +1.69925 -0.117523193359375 0.4183349609374934 +1.699375 -0.117523193359375 0.4183349609374934 +1.6995 -0.119354248046875 0.4183349609374934 +1.699625 -0.119354248046875 0.4183349609374934 +1.69975 -0.121124267578125 0.4183349609374934 +1.699875 -0.1229248046875 0.4183349609374934 +1.7 -0.1229248046875 0.4183349609374934 +1.700125 -0.124664306640625 0.4183349609374934 +1.70025 -0.124664306640625 0.4183349609374934 +1.700375 -0.126434326171875 0.4183349609374934 +1.7005 -0.128173828125 0.4183349609374934 +1.700625 -0.128173828125 0.4183349609374934 +1.70075 -0.1298828125 0.4183349609374934 +1.700875 -0.1298828125 0.4183349609374934 +1.701 -0.131591796875 0.4183349609374934 +1.701125 -0.13330078125 0.4183349609374934 +1.70125 -0.13330078125 0.4183349609374934 +1.701375 -0.134979248046875 0.4183349609374934 +1.7015 -0.134979248046875 0.4183349609374934 +1.701625 -0.136627197265625 0.4183349609374934 +1.70175 -0.1383056640625 0.4183349609374934 +1.701875 -0.1383056640625 0.4183349609374934 +1.702 -0.139923095703125 0.4183349609374934 +1.702125 -0.139923095703125 0.4183349609374934 +1.70225 -0.14154052734375 0.4183349609374934 +1.702375 -0.143157958984375 0.4183349609374934 +1.7025 -0.143157958984375 0.4183349609374934 +1.702625 -0.144744873046875 0.4183349609374934 +1.70275 -0.144744873046875 0.4183349609374934 +1.702875 -0.14630126953125 0.4183349609374934 +1.703 -0.147857666015625 0.4183349609374934 +1.703125 -0.147857666015625 0.4183349609374934 +1.70325 -0.1494140625 0.4183349609374934 +1.703375 -0.1494140625 0.4183349609374934 +1.7035 -0.15093994140625 0.4183349609374934 +1.703625 -0.152435302734375 0.4183349609374934 +1.70375 -0.152435302734375 0.4183349609374934 +1.703875 -0.1539306640625 0.4183349609374934 +1.704 -0.1539306640625 0.4183349609374934 +1.704125 -0.1553955078125 0.4183349609374934 +1.70425 -0.1568603515625 0.4183349609374934 +1.704375 -0.1568603515625 0.4183349609374934 +1.7045 -0.158294677734375 0.4183349609374934 +1.704625 -0.158294677734375 0.4183349609374934 +1.70475 -0.15972900390625 0.4183349609374934 +1.704875 -0.1611328125 0.4183349609374934 +1.705 -0.1611328125 0.4183349609374934 +1.705125 -0.162506103515625 0.4183349609374934 +1.70525 -0.162506103515625 0.4183349609374934 +1.705375 -0.16387939453125 0.4183349609374934 +1.7055 -0.165252685546875 0.4183349609374934 +1.705625 -0.165252685546875 0.4183349609374934 +1.70575 -0.16656494140625 0.4183349609374934 +1.705875 -0.16656494140625 0.4183349609374934 +1.706 -0.167877197265625 0.4183349609374934 +1.706125 -0.169189453125 0.4183349609374934 +1.70625 -0.169189453125 0.4183349609374934 +1.706375 -0.17047119140625 0.4183349609374934 +1.7065 -0.17047119140625 0.4183349609374934 +1.706625 -0.171722412109375 0.4183349609374934 +1.70675 -0.1729736328125 0.4183349609374934 +1.706875 -0.1729736328125 0.4183349609374934 +1.707 -0.1741943359375 0.4183349609374934 +1.707125 -0.1741943359375 0.4183349609374934 +1.70725 -0.175384521484375 0.4183349609374934 +1.707375 -0.17657470703125 0.4183349609374934 +1.7075 -0.17657470703125 0.4183349609374934 +1.707625 -0.177734375 0.4183349609374934 +1.70775 -0.177734375 0.4183349609374934 +1.707875 -0.178863525390625 0.4183349609374934 +1.708 -0.17999267578125 0.4183349609374934 +1.708125 -0.17999267578125 0.4183349609374934 +1.70825 -0.181121826171875 0.4183349609374934 +1.708375 -0.181121826171875 0.4183349609374934 +1.7085 -0.18218994140625 0.4183349609374934 +1.708625 -0.183258056640625 0.4183349609374934 +1.70875 -0.183258056640625 0.4183349609374934 +1.708875 -0.184295654296875 0.4183349609374934 +1.709 -0.184295654296875 0.4183349609374934 +1.709125 -0.185333251953125 0.4183349609374934 +1.70925 -0.18634033203125 0.4183349609374934 +1.709375 -0.18634033203125 0.4183349609374934 +1.7095 -0.18731689453125 0.4183349609374934 +1.709625 -0.18731689453125 0.4183349609374934 +1.70975 -0.188262939453125 0.4183349609374934 +1.709875 -0.189208984375 0.4183349609374934 +1.71 -0.189208984375 0.4183349609374934 +1.710125 -0.190155029296875 0.4183349609374934 +1.71025 -0.190155029296875 0.4183349609374934 +1.710375 -0.1910400390625 0.4183349609374934 +1.7105 -0.191925048828125 0.4183349609374934 +1.710625 -0.191925048828125 0.4183349609374934 +1.71075 -0.192779541015625 0.4183349609374934 +1.710875 -0.192779541015625 0.4183349609374934 +1.711 -0.193634033203125 0.4183349609374934 +1.711125 -0.194427490234375 0.4183349609374934 +1.71125 -0.194427490234375 0.4183349609374934 +1.711375 -0.195220947265625 0.4183349609374934 +1.7115 -0.195220947265625 0.4183349609374934 +1.711625 -0.196014404296875 0.4183349609374934 +1.71175 -0.196746826171875 0.4183349609374934 +1.711875 -0.196746826171875 0.4183349609374934 +1.712 -0.197509765625 0.4183349609374934 +1.712125 -0.197509765625 0.4183349609374934 +1.71225 -0.198211669921875 0.4183349609374934 +1.712375 -0.198883056640625 0.4183349609374934 +1.7125 -0.198883056640625 0.4183349609374934 +1.712625 -0.199554443359375 0.4183349609374934 +1.71275 -0.199554443359375 0.4183349609374934 +1.712875 -0.2001953125 0.4183349609374934 +1.713 -0.2008056640625 0.4183349609374934 +1.713125 -0.2008056640625 0.4183349609374934 +1.71325 -0.201416015625 0.4183349609374934 +1.713375 -0.201416015625 0.4183349609374934 +1.7135 -0.201995849609375 0.4183349609374934 +1.713625 -0.202545166015625 0.4183349609374934 +1.71375 -0.202545166015625 0.4183349609374934 +1.713875 -0.203094482421875 0.4183349609374934 +1.714 -0.203094482421875 0.4183349609374934 +1.714125 -0.20361328125 0.4183349609374934 +1.71425 -0.2041015625 0.4183349609374934 +1.714375 -0.2041015625 0.4183349609374934 +1.7145 -0.204559326171875 0.4183349609374934 +1.714625 -0.204559326171875 0.4183349609374934 +1.71475 -0.204986572265625 0.4183349609374934 +1.714875 -0.205413818359375 0.4183349609374934 +1.715 -0.205413818359375 0.4183349609374934 +1.715125 -0.205810546875 0.4183349609374934 +1.71525 -0.205810546875 0.4183349609374934 +1.715375 -0.206207275390625 0.4183349609374934 +1.7155 -0.20654296875 0.4183349609374934 +1.715625 -0.20654296875 0.4183349609374934 +1.71575 -0.206878662109375 0.4183349609374934 +1.715875 -0.206878662109375 0.4183349609374934 +1.716 -0.207183837890625 0.4183349609374934 +1.716125 -0.207489013671875 0.4183349609374934 +1.71625 -0.207489013671875 0.4183349609374934 +1.716375 -0.207733154296875 0.4183349609374934 +1.7165 -0.207733154296875 0.4183349609374934 +1.716625 -0.207977294921875 0.4183349609374934 +1.71675 -0.20819091796875 0.4183349609374934 +1.716875 -0.20819091796875 0.4183349609374934 +1.717 -0.208404541015625 0.4183349609374934 +1.717125 -0.208404541015625 0.4183349609374934 +1.71725 -0.20855712890625 0.4183349609374934 +1.717375 -0.208709716796875 0.4183349609374934 +1.7175 -0.208709716796875 0.4183349609374934 +1.717625 -0.208831787109375 0.4183349609374934 +1.71775 -0.208831787109375 0.4183349609374934 +1.717875 -0.208953857421875 0.4183349609374934 +1.718 -0.209014892578125 0.4183349609374934 +1.718125 -0.209014892578125 0.4183349609374934 +1.71825 -0.209075927734375 0.4183349609374934 +1.718375 -0.209075927734375 0.4183349609374934 +1.7185 -0.2091064453125 0.4183349609374934 +1.718625 -0.209136962890625 0.4183349609374934 +1.71875 -0.209136962890625 0.4183349609374934 +1.718875 -0.2091064453125 0.4183349609374934 +1.719 -0.2091064453125 0.4183349609374934 +1.719125 -0.209075927734375 0.4183349609374934 +1.71925 -0.209014892578125 0.4183349609374934 +1.719375 -0.209014892578125 0.4183349609374934 +1.7195 -0.208953857421875 0.4183349609374934 +1.719625 -0.208953857421875 0.4183349609374934 +1.71975 -0.208831787109375 0.4183349609374934 +1.719875 -0.208709716796875 0.4183349609374934 +1.72 -0.208709716796875 0.4183349609374934 +1.720125 -0.20855712890625 0.4183349609374934 +1.72025 -0.20855712890625 0.4183349609374934 +1.720375 -0.208404541015625 0.4183349609374934 +1.7205 -0.20819091796875 0.4183349609374934 +1.720625 -0.20819091796875 0.4183349609374934 +1.72075 -0.207977294921875 0.4183349609374934 +1.720875 -0.207977294921875 0.4183349609374934 +1.721 -0.207733154296875 0.4183349609374934 +1.721125 -0.207489013671875 0.4183349609374934 +1.72125 -0.207489013671875 0.4183349609374934 +1.721375 -0.207183837890625 0.4183349609374934 +1.7215 -0.207183837890625 0.4183349609374934 +1.721625 -0.206878662109375 0.4183349609374934 +1.72175 -0.20654296875 0.4183349609374934 +1.721875 -0.20654296875 0.4183349609374934 +1.722 -0.206207275390625 0.4183349609374934 +1.722125 -0.206207275390625 0.4183349609374934 +1.72225 -0.205810546875 0.4183349609374934 +1.722375 -0.205413818359375 0.4183349609374934 +1.7225 -0.205413818359375 0.4183349609374934 +1.722625 -0.204986572265625 0.4183349609374934 +1.72275 -0.204986572265625 0.4183349609374934 +1.722875 -0.204559326171875 0.4183349609374934 +1.723 -0.2041015625 0.4183349609374934 +1.723125 -0.2041015625 0.4183349609374934 +1.72325 -0.20361328125 0.4183349609374934 +1.723375 -0.20361328125 0.4183349609374934 +1.7235 -0.203094482421875 0.4183349609374934 +1.723625 -0.202545166015625 0.4183349609374934 +1.72375 -0.202545166015625 0.4183349609374934 +1.723875 -0.201995849609375 0.4183349609374934 +1.724 -0.201995849609375 0.4183349609374934 +1.724125 -0.201416015625 0.4183349609374934 +1.72425 -0.2008056640625 0.4183349609374934 +1.724375 -0.2008056640625 0.4183349609374934 +1.7245 -0.2001953125 0.4183349609374934 +1.724625 -0.2001953125 0.4183349609374934 +1.72475 -0.199554443359375 0.4183349609374934 +1.724875 -0.198883056640625 0.4183349609374934 +1.725 -0.198883056640625 0.4183349609374934 +1.725125 -0.198211669921875 0.4183349609374934 +1.72525 -0.198211669921875 0.4183349609374934 +1.725375 -0.197509765625 0.4183349609374934 +1.7255 -0.196746826171875 0.4183349609374934 +1.725625 -0.196746826171875 0.4183349609374934 +1.72575 -0.196014404296875 0.4183349609374934 +1.725875 -0.196014404296875 0.4183349609374934 +1.726 -0.195220947265625 0.4183349609374934 +1.726125 -0.194427490234375 0.4183349609374934 +1.72625 -0.194427490234375 0.4183349609374934 +1.726375 -0.193634033203125 0.4183349609374934 +1.7265 -0.193634033203125 0.4183349609374934 +1.726625 -0.192779541015625 0.4183349609374934 +1.72675 -0.191925048828125 0.4183349609374934 +1.726875 -0.191925048828125 0.4183349609374934 +1.727 -0.1910400390625 0.4183349609374934 +1.727125 -0.1910400390625 0.4183349609374934 +1.72725 -0.190155029296875 0.4183349609374934 +1.727375 -0.189208984375 0.4183349609374934 +1.7275 -0.189208984375 0.4183349609374934 +1.727625 -0.188262939453125 0.4183349609374934 +1.72775 -0.188262939453125 0.4183349609374934 +1.727875 -0.18731689453125 0.4183349609374934 +1.728 -0.044403076171875 0.09975585937499341 +1.728125 -0.044403076171875 0.09975585937499341 +1.72825 -0.044189453125 0.09975585937499341 +1.728375 -0.044189453125 0.09975585937499341 +1.7285 -0.043914794921875 0.09975585937499341 +1.728625 -0.043670654296875 0.09975585937499341 +1.72875 -0.043670654296875 0.09975585937499341 +1.728875 -0.043426513671875 0.09975585937499341 +1.729 -0.043426513671875 0.09975585937499341 +1.729125 -0.043182373046875 0.09975585937499341 +1.72925 -0.04290771484375 0.09975585937499341 +1.729375 -0.04290771484375 0.09975585937499341 +1.7295 -0.042633056640625 0.09975585937499341 +1.729625 -0.042633056640625 0.09975585937499341 +1.72975 -0.0423583984375 0.09975585937499341 +1.729875 -0.042083740234375 0.09975585937499341 +1.73 -0.042083740234375 0.09975585937499341 +1.730125 -0.04180908203125 0.09975585937499341 +1.73025 -0.04180908203125 0.09975585937499341 +1.730375 -0.04150390625 0.09975585937499341 +1.7305 -0.041229248046875 0.09975585937499341 +1.730625 -0.041229248046875 0.09975585937499341 +1.73075 -0.040924072265625 0.09975585937499341 +1.730875 -0.040924072265625 0.09975585937499341 +1.731 -0.040618896484375 0.09975585937499341 +1.731125 -0.040313720703125 0.09975585937499341 +1.73125 -0.040313720703125 0.09975585937499341 +1.731375 -0.040008544921875 0.09975585937499341 +1.7315 -0.040008544921875 0.09975585937499341 +1.731625 -0.039703369140625 0.09975585937499341 +1.73175 -0.039398193359375 0.09975585937499341 +1.731875 -0.039398193359375 0.09975585937499341 +1.732 -0.0390625 0.09975585937499341 +1.732125 -0.0390625 0.09975585937499341 +1.73225 -0.038726806640625 0.09975585937499341 +1.732375 -0.03839111328125 0.09975585937499341 +1.7325 -0.03839111328125 0.09975585937499341 +1.732625 -0.038055419921875 0.09975585937499341 +1.73275 -0.038055419921875 0.09975585937499341 +1.732875 -0.0377197265625 0.09975585937499341 +1.733 -0.037384033203125 0.09975585937499341 +1.733125 -0.037384033203125 0.09975585937499341 +1.73325 -0.03704833984375 0.09975585937499341 +1.733375 -0.03704833984375 0.09975585937499341 +1.7335 -0.03668212890625 0.09975585937499341 +1.733625 -0.036346435546875 0.09975585937499341 +1.73375 -0.036346435546875 0.09975585937499341 +1.733875 -0.035980224609375 0.09975585937499341 +1.734 -0.035980224609375 0.09975585937499341 +1.734125 -0.035614013671875 0.09975585937499341 +1.73425 -0.035247802734375 0.09975585937499341 +1.734375 -0.035247802734375 0.09975585937499341 +1.7345 -0.034881591796875 0.09975585937499341 +1.734625 -0.034881591796875 0.09975585937499341 +1.73475 -0.03448486328125 0.09975585937499341 +1.734875 -0.03411865234375 0.09975585937499341 +1.735 -0.03411865234375 0.09975585937499341 +1.735125 -0.033721923828125 0.09975585937499341 +1.73525 -0.033721923828125 0.09975585937499341 +1.735375 -0.033355712890625 0.09975585937499341 +1.7355 -0.032958984375 0.09975585937499341 +1.735625 -0.032958984375 0.09975585937499341 +1.73575 -0.032562255859375 0.09975585937499341 +1.735875 -0.032562255859375 0.09975585937499341 +1.736 -0.03216552734375 0.09975585937499341 +1.736125 -0.031768798828125 0.09975585937499341 +1.73625 -0.031768798828125 0.09975585937499341 +1.736375 -0.0313720703125 0.09975585937499341 +1.7365 -0.0313720703125 0.09975585937499341 +1.736625 -0.03094482421875 0.09975585937499341 +1.73675 -0.030548095703125 0.09975585937499341 +1.736875 -0.030548095703125 0.09975585937499341 +1.737 -0.030120849609375 0.09975585937499341 +1.737125 -0.030120849609375 0.09975585937499341 +1.73725 -0.02972412109375 0.09975585937499341 +1.737375 -0.029296875 0.09975585937499341 +1.7375 -0.029296875 0.09975585937499341 +1.737625 -0.02886962890625 0.09975585937499341 +1.73775 -0.02886962890625 0.09975585937499341 +1.737875 -0.0284423828125 0.09975585937499341 +1.738 -0.02801513671875 0.09975585937499341 +1.738125 -0.02801513671875 0.09975585937499341 +1.73825 -0.027587890625 0.09975585937499341 +1.738375 -0.027587890625 0.09975585937499341 +1.7385 -0.027130126953125 0.09975585937499341 +1.738625 -0.026702880859375 0.09975585937499341 +1.73875 -0.026702880859375 0.09975585937499341 +1.738875 -0.0262451171875 0.09975585937499341 +1.739 -0.0262451171875 0.09975585937499341 +1.739125 -0.02581787109375 0.09975585937499341 +1.73925 -0.025360107421875 0.09975585937499341 +1.739375 -0.025360107421875 0.09975585937499341 +1.7395 -0.02490234375 0.09975585937499341 +1.739625 -0.02490234375 0.09975585937499341 +1.73975 -0.02447509765625 0.09975585937499341 +1.739875 -0.024017333984375 0.09975585937499341 +1.74 -0.024017333984375 0.09975585937499341 +1.740125 -0.0235595703125 0.09975585937499341 +1.74025 -0.0235595703125 0.09975585937499341 +1.740375 -0.0230712890625 0.09975585937499341 +1.7405 -0.022613525390625 0.09975585937499341 +1.740625 -0.022613525390625 0.09975585937499341 +1.74075 -0.02215576171875 0.09975585937499341 +1.740875 -0.02215576171875 0.09975585937499341 +1.741 -0.021697998046875 0.09975585937499341 +1.741125 -0.021209716796875 0.09975585937499341 +1.74125 -0.021209716796875 0.09975585937499341 +1.741375 -0.020751953125 0.09975585937499341 +1.7415 -0.020751953125 0.09975585937499341 +1.741625 -0.020263671875 0.09975585937499341 +1.74175 -0.019775390625 0.09975585937499341 +1.741875 -0.019775390625 0.09975585937499341 +1.742 -0.019317626953125 0.09975585937499341 +1.742125 -0.019317626953125 0.09975585937499341 +1.74225 -0.018829345703125 0.09975585937499341 +1.742375 -0.018341064453125 0.09975585937499341 +1.7425 -0.018341064453125 0.09975585937499341 +1.742625 -0.017852783203125 0.09975585937499341 +1.74275 -0.017852783203125 0.09975585937499341 +1.742875 -0.017364501953125 0.09975585937499341 +1.743 -0.016876220703125 0.09975585937499341 +1.743125 -0.016876220703125 0.09975585937499341 +1.74325 -0.016387939453125 0.09975585937499341 +1.743375 -0.016387939453125 0.09975585937499341 +1.7435 -0.015899658203125 0.09975585937499341 +1.743625 -0.015380859375 0.09975585937499341 +1.74375 -0.015380859375 0.09975585937499341 +1.743875 -0.014892578125 0.09975585937499341 +1.744 -0.014892578125 0.09975585937499341 +1.744125 -0.014404296875 0.09975585937499341 +1.74425 -0.013885498046875 0.09975585937499341 +1.744375 -0.013885498046875 0.09975585937499341 +1.7445 -0.013397216796875 0.09975585937499341 +1.744625 -0.013397216796875 0.09975585937499341 +1.74475 -0.01287841796875 0.09975585937499341 +1.744875 -0.01239013671875 0.09975585937499341 +1.745 -0.01239013671875 0.09975585937499341 +1.745125 -0.011871337890625 0.09975585937499341 +1.74525 -0.011871337890625 0.09975585937499341 +1.745375 -0.011383056640625 0.09975585937499341 +1.7455 -0.0108642578125 0.09975585937499341 +1.745625 -0.0108642578125 0.09975585937499341 +1.74575 -0.010345458984375 0.09975585937499341 +1.745875 -0.010345458984375 0.09975585937499341 +1.746 -0.00982666015625 0.09975585937499341 +1.746125 -0.00933837890625 0.09975585937499341 +1.74625 -0.00933837890625 0.09975585937499341 +1.746375 -0.008819580078125 0.09975585937499341 +1.7465 -0.008819580078125 0.09975585937499341 +1.746625 -0.00830078125 0.09975585937499341 +1.74675 -0.007781982421875 0.09975585937499341 +1.746875 -0.007781982421875 0.09975585937499341 +1.747 -0.00726318359375 0.09975585937499341 +1.747125 -0.00726318359375 0.09975585937499341 +1.74725 -0.006744384765625 0.09975585937499341 +1.747375 -0.0062255859375 0.09975585937499341 +1.7475 -0.0062255859375 0.09975585937499341 +1.747625 -0.005706787109375 0.09975585937499341 +1.74775 -0.005706787109375 0.09975585937499341 +1.747875 -0.00518798828125 0.09975585937499341 +1.748 -0.004669189453125 0.09975585937499341 +1.748125 -0.004669189453125 0.09975585937499341 +1.74825 -0.004150390625 0.09975585937499341 +1.748375 -0.004150390625 0.09975585937499341 +1.7485 -0.003631591796875 0.09975585937499341 +1.748625 -0.00311279296875 0.09975585937499341 +1.74875 -0.00311279296875 0.09975585937499341 +1.748875 -0.002593994140625 0.09975585937499341 +1.749 -0.002593994140625 0.09975585937499341 +1.749125 -0.0020751953125 0.09975585937499341 +1.74925 -0.001556396484375 0.09975585937499341 +1.749375 -0.001556396484375 0.09975585937499341 +1.7495 -0.00103759765625 0.09975585937499341 +1.749625 -0.00103759765625 0.09975585937499341 +1.74975 -0.000518798828125 0.09975585937499341 1.749875 0.0 0.09975585937499341 1.75 0.0 0.09975585937499341 1.750125 0.000518798828125 0.09975585937499341 @@ -14078,425 +14078,425 @@ 1.759625 0.0230712890625 0.09975585937499341 1.75975 0.0235595703125 0.09975585937499341 1.759875 0.024017333984375 0.09975585937499341 -1.76 -0.04888916015625 -0.202866210937506 -1.760125 -0.0498046875 -0.202866210937506 -1.76025 -0.0498046875 -0.202866210937506 -1.760375 -0.05072021484375 -0.202866210937506 -1.7605 -0.0516357421875 -0.202866210937506 -1.760625 -0.0516357421875 -0.202866210937506 -1.76075 -0.05255126953125 -0.202866210937506 -1.760875 -0.05255126953125 -0.202866210937506 -1.761 -0.053466796875 -0.202866210937506 -1.761125 -0.054351806640625 -0.202866210937506 -1.76125 -0.054351806640625 -0.202866210937506 -1.761375 -0.055267333984375 -0.202866210937506 -1.7615 -0.055267333984375 -0.202866210937506 -1.761625 -0.05615234375 -0.202866210937506 -1.76175 -0.057037353515625 -0.202866210937506 -1.761875 -0.057037353515625 -0.202866210937506 -1.762 -0.057891845703125 -0.202866210937506 -1.762125 -0.057891845703125 -0.202866210937506 -1.76225 -0.05877685546875 -0.202866210937506 -1.762375 -0.05963134765625 -0.202866210937506 -1.7625 -0.05963134765625 -0.202866210937506 -1.762625 -0.06048583984375 -0.202866210937506 -1.76275 -0.06048583984375 -0.202866210937506 -1.762875 -0.06134033203125 -0.202866210937506 -1.763 -0.06219482421875 -0.202866210937506 -1.763125 -0.06219482421875 -0.202866210937506 -1.76325 -0.063018798828125 -0.202866210937506 -1.763375 -0.063018798828125 -0.202866210937506 -1.7635 -0.0638427734375 -0.202866210937506 -1.763625 -0.064666748046875 -0.202866210937506 -1.76375 -0.064666748046875 -0.202866210937506 -1.763875 -0.06549072265625 -0.202866210937506 -1.764 -0.06549072265625 -0.202866210937506 -1.764125 -0.0662841796875 -0.202866210937506 -1.76425 -0.067108154296875 -0.202866210937506 -1.764375 -0.067108154296875 -0.202866210937506 -1.7645 -0.067901611328125 -0.202866210937506 -1.764625 -0.067901611328125 -0.202866210937506 -1.76475 -0.06866455078125 -0.202866210937506 -1.764875 -0.0694580078125 -0.202866210937506 -1.765 -0.0694580078125 -0.202866210937506 -1.765125 -0.070220947265625 -0.202866210937506 -1.76525 -0.070220947265625 -0.202866210937506 -1.765375 -0.07098388671875 -0.202866210937506 -1.7655 -0.071746826171875 -0.202866210937506 -1.765625 -0.071746826171875 -0.202866210937506 -1.76575 -0.072479248046875 -0.202866210937506 -1.765875 -0.072479248046875 -0.202866210937506 -1.766 -0.073211669921875 -0.202866210937506 -1.766125 -0.073974609375 -0.202866210937506 -1.76625 -0.073974609375 -0.202866210937506 -1.766375 -0.074676513671875 -0.202866210937506 -1.7665 -0.074676513671875 -0.202866210937506 -1.766625 -0.075408935546875 -0.202866210937506 -1.76675 -0.07611083984375 -0.202866210937506 -1.766875 -0.07611083984375 -0.202866210937506 -1.767 -0.076812744140625 -0.202866210937506 -1.767125 -0.076812744140625 -0.202866210937506 -1.76725 -0.077484130859375 -0.202866210937506 -1.767375 -0.07818603515625 -0.202866210937506 -1.7675 -0.07818603515625 -0.202866210937506 -1.767625 -0.078857421875 -0.202866210937506 -1.76775 -0.078857421875 -0.202866210937506 -1.767875 -0.079498291015625 -0.202866210937506 -1.768 -0.080169677734375 -0.202866210937506 -1.768125 -0.080169677734375 -0.202866210937506 -1.76825 -0.080810546875 -0.202866210937506 -1.768375 -0.080810546875 -0.202866210937506 -1.7685 -0.081451416015625 -0.202866210937506 -1.768625 -0.08209228515625 -0.202866210937506 -1.76875 -0.08209228515625 -0.202866210937506 -1.768875 -0.08270263671875 -0.202866210937506 -1.769 -0.08270263671875 -0.202866210937506 -1.769125 -0.08331298828125 -0.202866210937506 -1.76925 -0.08392333984375 -0.202866210937506 -1.769375 -0.08392333984375 -0.202866210937506 -1.7695 -0.084503173828125 -0.202866210937506 -1.769625 -0.084503173828125 -0.202866210937506 -1.76975 -0.0850830078125 -0.202866210937506 -1.769875 -0.085662841796875 -0.202866210937506 -1.77 -0.085662841796875 -0.202866210937506 -1.770125 -0.086212158203125 -0.202866210937506 -1.77025 -0.086212158203125 -0.202866210937506 -1.770375 -0.0867919921875 -0.202866210937506 -1.7705 -0.087310791015625 -0.202866210937506 -1.770625 -0.087310791015625 -0.202866210937506 -1.77075 -0.087860107421875 -0.202866210937506 -1.770875 -0.087860107421875 -0.202866210937506 -1.771 -0.08837890625 -0.202866210937506 -1.771125 -0.088897705078125 -0.202866210937506 -1.77125 -0.088897705078125 -0.202866210937506 -1.771375 -0.08941650390625 -0.202866210937506 -1.7715 -0.08941650390625 -0.202866210937506 -1.771625 -0.08990478515625 -0.202866210937506 -1.77175 -0.09039306640625 -0.202866210937506 -1.771875 -0.09039306640625 -0.202866210937506 -1.772 -0.09088134765625 -0.202866210937506 -1.772125 -0.09088134765625 -0.202866210937506 -1.77225 -0.091339111328125 -0.202866210937506 -1.772375 -0.091796875 -0.202866210937506 -1.7725 -0.091796875 -0.202866210937506 -1.772625 -0.092254638671875 -0.202866210937506 -1.77275 -0.092254638671875 -0.202866210937506 -1.772875 -0.092681884765625 -0.202866210937506 -1.773 -0.093109130859375 -0.202866210937506 -1.773125 -0.093109130859375 -0.202866210937506 -1.77325 -0.093536376953125 -0.202866210937506 -1.773375 -0.093536376953125 -0.202866210937506 -1.7735 -0.09393310546875 -0.202866210937506 -1.773625 -0.094329833984375 -0.202866210937506 -1.77375 -0.094329833984375 -0.202866210937506 -1.773875 -0.0947265625 -0.202866210937506 -1.774 -0.0947265625 -0.202866210937506 -1.774125 -0.0950927734375 -0.202866210937506 -1.77425 -0.095458984375 -0.202866210937506 -1.774375 -0.095458984375 -0.202866210937506 -1.7745 -0.095794677734375 -0.202866210937506 -1.774625 -0.095794677734375 -0.202866210937506 -1.77475 -0.096160888671875 -0.202866210937506 -1.774875 -0.09649658203125 -0.202866210937506 -1.775 -0.09649658203125 -0.202866210937506 -1.775125 -0.0968017578125 -0.202866210937506 -1.77525 -0.0968017578125 -0.202866210937506 -1.775375 -0.09710693359375 -0.202866210937506 -1.7755 -0.097412109375 -0.202866210937506 -1.775625 -0.097412109375 -0.202866210937506 -1.77575 -0.09771728515625 -0.202866210937506 -1.775875 -0.09771728515625 -0.202866210937506 -1.776 -0.097991943359375 -0.202866210937506 -1.776125 -0.0982666015625 -0.202866210937506 -1.77625 -0.0982666015625 -0.202866210937506 -1.776375 -0.0985107421875 -0.202866210937506 -1.7765 -0.0985107421875 -0.202866210937506 -1.776625 -0.098785400390625 -0.202866210937506 -1.77675 -0.0989990234375 -0.202866210937506 -1.776875 -0.0989990234375 -0.202866210937506 -1.777 -0.0992431640625 -0.202866210937506 -1.777125 -0.0992431640625 -0.202866210937506 -1.77725 -0.099456787109375 -0.202866210937506 -1.777375 -0.099639892578125 -0.202866210937506 -1.7775 -0.099639892578125 -0.202866210937506 -1.777625 -0.099853515625 -0.202866210937506 -1.77775 -0.099853515625 -0.202866210937506 -1.777875 -0.10003662109375 -0.202866210937506 -1.778 -0.100189208984375 -0.202866210937506 -1.778125 -0.100189208984375 -0.202866210937506 -1.77825 -0.100372314453125 -0.202866210937506 -1.778375 -0.100372314453125 -0.202866210937506 -1.7785 -0.10052490234375 -0.202866210937506 -1.778625 -0.10064697265625 -0.202866210937506 -1.77875 -0.10064697265625 -0.202866210937506 -1.778875 -0.10076904296875 -0.202866210937506 -1.779 -0.10076904296875 -0.202866210937506 -1.779125 -0.10089111328125 -0.202866210937506 -1.77925 -0.10101318359375 -0.202866210937506 -1.779375 -0.10101318359375 -0.202866210937506 -1.7795 -0.101104736328125 -0.202866210937506 -1.779625 -0.101104736328125 -0.202866210937506 -1.77975 -0.101165771484375 -0.202866210937506 -1.779875 -0.10125732421875 -0.202866210937506 -1.78 -0.10125732421875 -0.202866210937506 -1.780125 -0.101318359375 -0.202866210937506 -1.78025 -0.101318359375 -0.202866210937506 -1.780375 -0.101348876953125 -0.202866210937506 -1.7805 -0.101409912109375 -0.202866210937506 -1.780625 -0.101409912109375 -0.202866210937506 -1.78075 -0.1014404296875 -0.202866210937506 -1.780875 -0.1014404296875 -0.202866210937506 -1.781 -0.1014404296875 -0.202866210937506 -1.781125 -0.1014404296875 -0.202866210937506 -1.78125 -0.1014404296875 -0.202866210937506 -1.781375 -0.1014404296875 -0.202866210937506 -1.7815 -0.1014404296875 -0.202866210937506 -1.781625 -0.1014404296875 -0.202866210937506 -1.78175 -0.101409912109375 -0.202866210937506 -1.781875 -0.101409912109375 -0.202866210937506 -1.782 -0.101348876953125 -0.202866210937506 -1.782125 -0.101348876953125 -0.202866210937506 -1.78225 -0.101318359375 -0.202866210937506 -1.782375 -0.10125732421875 -0.202866210937506 -1.7825 -0.10125732421875 -0.202866210937506 -1.782625 -0.101165771484375 -0.202866210937506 -1.78275 -0.101165771484375 -0.202866210937506 -1.782875 -0.101104736328125 -0.202866210937506 -1.783 -0.10101318359375 -0.202866210937506 -1.783125 -0.10101318359375 -0.202866210937506 -1.78325 -0.10089111328125 -0.202866210937506 -1.783375 -0.10089111328125 -0.202866210937506 -1.7835 -0.10076904296875 -0.202866210937506 -1.783625 -0.10064697265625 -0.202866210937506 -1.78375 -0.10064697265625 -0.202866210937506 -1.783875 -0.10052490234375 -0.202866210937506 -1.784 -0.10052490234375 -0.202866210937506 -1.784125 -0.100372314453125 -0.202866210937506 -1.78425 -0.100189208984375 -0.202866210937506 -1.784375 -0.100189208984375 -0.202866210937506 -1.7845 -0.10003662109375 -0.202866210937506 -1.784625 -0.10003662109375 -0.202866210937506 -1.78475 -0.099853515625 -0.202866210937506 -1.784875 -0.099639892578125 -0.202866210937506 -1.785 -0.099639892578125 -0.202866210937506 -1.785125 -0.099456787109375 -0.202866210937506 -1.78525 -0.099456787109375 -0.202866210937506 -1.785375 -0.0992431640625 -0.202866210937506 -1.7855 -0.0989990234375 -0.202866210937506 -1.785625 -0.0989990234375 -0.202866210937506 -1.78575 -0.098785400390625 -0.202866210937506 -1.785875 -0.098785400390625 -0.202866210937506 -1.786 -0.0985107421875 -0.202866210937506 -1.786125 -0.0982666015625 -0.202866210937506 -1.78625 -0.0982666015625 -0.202866210937506 -1.786375 -0.097991943359375 -0.202866210937506 -1.7865 -0.097991943359375 -0.202866210937506 -1.786625 -0.09771728515625 -0.202866210937506 -1.78675 -0.097412109375 -0.202866210937506 -1.786875 -0.097412109375 -0.202866210937506 -1.787 -0.09710693359375 -0.202866210937506 -1.787125 -0.09710693359375 -0.202866210937506 -1.78725 -0.0968017578125 -0.202866210937506 -1.787375 -0.09649658203125 -0.202866210937506 -1.7875 -0.09649658203125 -0.202866210937506 -1.787625 -0.096160888671875 -0.202866210937506 -1.78775 -0.096160888671875 -0.202866210937506 -1.787875 -0.095794677734375 -0.202866210937506 -1.788 -0.095458984375 -0.202866210937506 -1.788125 -0.095458984375 -0.202866210937506 -1.78825 -0.0950927734375 -0.202866210937506 -1.788375 -0.0950927734375 -0.202866210937506 -1.7885 -0.0947265625 -0.202866210937506 -1.788625 -0.094329833984375 -0.202866210937506 -1.78875 -0.094329833984375 -0.202866210937506 -1.788875 -0.09393310546875 -0.202866210937506 -1.789 -0.09393310546875 -0.202866210937506 -1.789125 -0.093536376953125 -0.202866210937506 -1.78925 -0.093109130859375 -0.202866210937506 -1.789375 -0.093109130859375 -0.202866210937506 -1.7895 -0.092681884765625 -0.202866210937506 -1.789625 -0.092681884765625 -0.202866210937506 -1.78975 -0.092254638671875 -0.202866210937506 -1.789875 -0.091796875 -0.202866210937506 -1.79 -0.091796875 -0.202866210937506 -1.790125 -0.091339111328125 -0.202866210937506 -1.79025 -0.091339111328125 -0.202866210937506 -1.790375 -0.09088134765625 -0.202866210937506 -1.7905 -0.09039306640625 -0.202866210937506 -1.790625 -0.09039306640625 -0.202866210937506 -1.79075 -0.08990478515625 -0.202866210937506 -1.790875 -0.08990478515625 -0.202866210937506 -1.791 -0.08941650390625 -0.202866210937506 -1.791125 -0.088897705078125 -0.202866210937506 -1.79125 -0.088897705078125 -0.202866210937506 -1.791375 -0.08837890625 -0.202866210937506 -1.7915 -0.08837890625 -0.202866210937506 -1.791625 -0.087860107421875 -0.202866210937506 -1.79175 -0.087310791015625 -0.202866210937506 -1.791875 -0.087310791015625 -0.202866210937506 -1.792 -0.188690185546875 -0.4412060546875043 -1.792125 -0.188690185546875 -0.4412060546875043 -1.79225 -0.1875 -0.4412060546875043 -1.792375 -0.186279296875 -0.4412060546875043 -1.7925 -0.186279296875 -0.4412060546875043 -1.792625 -0.18499755859375 -0.4412060546875043 -1.79275 -0.18499755859375 -0.4412060546875043 -1.792875 -0.183746337890625 -0.4412060546875043 -1.793 -0.182464599609375 -0.4412060546875043 -1.793125 -0.182464599609375 -0.4412060546875043 -1.79325 -0.18115234375 -0.4412060546875043 -1.793375 -0.18115234375 -0.4412060546875043 -1.7935 -0.1798095703125 -0.4412060546875043 -1.793625 -0.178466796875 -0.4412060546875043 -1.79375 -0.178466796875 -0.4412060546875043 -1.793875 -0.177093505859375 -0.4412060546875043 -1.794 -0.177093505859375 -0.4412060546875043 -1.794125 -0.17572021484375 -0.4412060546875043 -1.79425 -0.17431640625 -0.4412060546875043 -1.794375 -0.17431640625 -0.4412060546875043 -1.7945 -0.172882080078125 -0.4412060546875043 -1.794625 -0.172882080078125 -0.4412060546875043 -1.79475 -0.17144775390625 -0.4412060546875043 -1.794875 -0.16998291015625 -0.4412060546875043 -1.795 -0.16998291015625 -0.4412060546875043 -1.795125 -0.168487548828125 -0.4412060546875043 -1.79525 -0.168487548828125 -0.4412060546875043 -1.795375 -0.1669921875 -0.4412060546875043 -1.7955 -0.16546630859375 -0.4412060546875043 -1.795625 -0.16546630859375 -0.4412060546875043 -1.79575 -0.1639404296875 -0.4412060546875043 -1.795875 -0.1639404296875 -0.4412060546875043 -1.796 -0.162384033203125 -0.4412060546875043 -1.796125 -0.16082763671875 -0.4412060546875043 -1.79625 -0.16082763671875 -0.4412060546875043 -1.796375 -0.159210205078125 -0.4412060546875043 -1.7965 -0.159210205078125 -0.4412060546875043 -1.796625 -0.157623291015625 -0.4412060546875043 -1.79675 -0.155975341796875 -0.4412060546875043 -1.796875 -0.155975341796875 -0.4412060546875043 -1.797 -0.15435791015625 -0.4412060546875043 -1.797125 -0.15435791015625 -0.4412060546875043 -1.79725 -0.152679443359375 -0.4412060546875043 -1.797375 -0.1510009765625 -0.4412060546875043 -1.7975 -0.1510009765625 -0.4412060546875043 -1.797625 -0.149322509765625 -0.4412060546875043 -1.79775 -0.149322509765625 -0.4412060546875043 -1.797875 -0.147613525390625 -0.4412060546875043 -1.798 -0.145904541015625 -0.4412060546875043 -1.798125 -0.145904541015625 -0.4412060546875043 -1.79825 -0.144134521484375 -0.4412060546875043 -1.798375 -0.144134521484375 -0.4412060546875043 -1.7985 -0.14239501953125 -0.4412060546875043 -1.798625 -0.140625 -0.4412060546875043 -1.79875 -0.140625 -0.4412060546875043 -1.798875 -0.138824462890625 -0.4412060546875043 -1.799 -0.138824462890625 -0.4412060546875043 -1.799125 -0.13702392578125 -0.4412060546875043 -1.79925 -0.135223388671875 -0.4412060546875043 -1.799375 -0.135223388671875 -0.4412060546875043 -1.7995 -0.133392333984375 -0.4412060546875043 -1.799625 -0.133392333984375 -0.4412060546875043 -1.79975 -0.13153076171875 -0.4412060546875043 -1.799875 -0.129669189453125 -0.4412060546875043 -1.8 -0.129669189453125 -0.4412060546875043 -1.800125 -0.1278076171875 -0.4412060546875043 -1.80025 -0.1278076171875 -0.4412060546875043 -1.800375 -0.12591552734375 -0.4412060546875043 -1.8005 -0.123992919921875 -0.4412060546875043 -1.800625 -0.123992919921875 -0.4412060546875043 -1.80075 -0.1220703125 -0.4412060546875043 -1.800875 -0.1220703125 -0.4412060546875043 -1.801 -0.120147705078125 -0.4412060546875043 -1.801125 -0.11822509765625 -0.4412060546875043 -1.80125 -0.11822509765625 -0.4412060546875043 -1.801375 -0.116241455078125 -0.4412060546875043 -1.8015 -0.116241455078125 -0.4412060546875043 -1.801625 -0.114288330078125 -0.4412060546875043 -1.80175 -0.1123046875 -0.4412060546875043 -1.801875 -0.1123046875 -0.4412060546875043 -1.802 -0.110321044921875 -0.4412060546875043 -1.802125 -0.110321044921875 -0.4412060546875043 -1.80225 -0.108306884765625 -0.4412060546875043 -1.802375 -0.106292724609375 -0.4412060546875043 -1.8025 -0.106292724609375 -0.4412060546875043 -1.802625 -0.104248046875 -0.4412060546875043 -1.80275 -0.104248046875 -0.4412060546875043 -1.802875 -0.102203369140625 -0.4412060546875043 -1.803 -0.10015869140625 -0.4412060546875043 -1.803125 -0.10015869140625 -0.4412060546875043 -1.80325 -0.09808349609375 -0.4412060546875043 -1.803375 -0.09808349609375 -0.4412060546875043 -1.8035 -0.09600830078125 -0.4412060546875043 -1.803625 -0.09393310546875 -0.4412060546875043 -1.80375 -0.09393310546875 -0.4412060546875043 -1.803875 -0.091827392578125 -0.4412060546875043 -1.804 -0.091827392578125 -0.4412060546875043 -1.804125 -0.0897216796875 -0.4412060546875043 -1.80425 -0.087615966796875 -0.4412060546875043 -1.804375 -0.087615966796875 -0.4412060546875043 -1.8045 -0.085479736328125 -0.4412060546875043 -1.804625 -0.085479736328125 -0.4412060546875043 -1.80475 -0.083343505859375 -0.4412060546875043 -1.804875 -0.081207275390625 -0.4412060546875043 -1.805 -0.081207275390625 -0.4412060546875043 -1.805125 -0.079071044921875 -0.4412060546875043 -1.80525 -0.079071044921875 -0.4412060546875043 -1.805375 -0.076904296875 -0.4412060546875043 -1.8055 -0.074737548828125 -0.4412060546875043 -1.805625 -0.074737548828125 -0.4412060546875043 -1.80575 -0.072540283203125 -0.4412060546875043 -1.805875 -0.072540283203125 -0.4412060546875043 -1.806 -0.07037353515625 -0.4412060546875043 -1.806125 -0.06817626953125 -0.4412060546875043 -1.80625 -0.06817626953125 -0.4412060546875043 -1.806375 -0.06597900390625 -0.4412060546875043 -1.8065 -0.06597900390625 -0.4412060546875043 -1.806625 -0.06378173828125 -0.4412060546875043 -1.80675 -0.061553955078125 -0.4412060546875043 -1.806875 -0.061553955078125 -0.4412060546875043 -1.807 -0.059326171875 -0.4412060546875043 -1.807125 -0.059326171875 -0.4412060546875043 -1.80725 -0.057098388671875 -0.4412060546875043 -1.807375 -0.05487060546875 -0.4412060546875043 -1.8075 -0.05487060546875 -0.4412060546875043 -1.807625 -0.052642822265625 -0.4412060546875043 -1.80775 -0.052642822265625 -0.4412060546875043 -1.807875 -0.050384521484375 -0.4412060546875043 -1.808 -0.048126220703125 -0.4412060546875043 -1.808125 -0.048126220703125 -0.4412060546875043 -1.80825 -0.045867919921875 -0.4412060546875043 -1.808375 -0.045867919921875 -0.4412060546875043 -1.8085 -0.043609619140625 -0.4412060546875043 -1.808625 -0.041351318359375 -0.4412060546875043 -1.80875 -0.041351318359375 -0.4412060546875043 -1.808875 -0.0390625 -0.4412060546875043 -1.809 -0.0390625 -0.4412060546875043 -1.809125 -0.03680419921875 -0.4412060546875043 -1.80925 -0.034515380859375 -0.4412060546875043 -1.809375 -0.034515380859375 -0.4412060546875043 -1.8095 -0.0322265625 -0.4412060546875043 -1.809625 -0.0322265625 -0.4412060546875043 -1.80975 -0.029937744140625 -0.4412060546875043 -1.809875 -0.02764892578125 -0.4412060546875043 -1.81 -0.02764892578125 -0.4412060546875043 -1.810125 -0.025360107421875 -0.4412060546875043 -1.81025 -0.025360107421875 -0.4412060546875043 -1.810375 -0.0230712890625 -0.4412060546875043 -1.8105 -0.020782470703125 -0.4412060546875043 -1.810625 -0.020782470703125 -0.4412060546875043 -1.81075 -0.018463134765625 -0.4412060546875043 -1.810875 -0.018463134765625 -0.4412060546875043 -1.811 -0.01617431640625 -0.4412060546875043 -1.811125 -0.01385498046875 -0.4412060546875043 -1.81125 -0.01385498046875 -0.4412060546875043 -1.811375 -0.011566162109375 -0.4412060546875043 -1.8115 -0.011566162109375 -0.4412060546875043 -1.811625 -0.009246826171875 -0.4412060546875043 -1.81175 -0.006927490234375 -0.4412060546875043 -1.811875 -0.006927490234375 -0.4412060546875043 -1.812 -0.004638671875 -0.4412060546875043 -1.812125 -0.004638671875 -0.4412060546875043 -1.81225 -0.0023193359375 -0.4412060546875043 +1.76 -0.048858642578125 -0.202866210937506 +1.760125 -0.049774169921875 -0.202866210937506 +1.76025 -0.049774169921875 -0.202866210937506 +1.760375 -0.050689697265625 -0.202866210937506 +1.7605 -0.051605224609375 -0.202866210937506 +1.760625 -0.051605224609375 -0.202866210937506 +1.76075 -0.052520751953125 -0.202866210937506 +1.760875 -0.052520751953125 -0.202866210937506 +1.761 -0.053436279296875 -0.202866210937506 +1.761125 -0.0543212890625 -0.202866210937506 +1.76125 -0.0543212890625 -0.202866210937506 +1.761375 -0.05523681640625 -0.202866210937506 +1.7615 -0.05523681640625 -0.202866210937506 +1.761625 -0.056121826171875 -0.202866210937506 +1.76175 -0.0570068359375 -0.202866210937506 +1.761875 -0.0570068359375 -0.202866210937506 +1.762 -0.057861328125 -0.202866210937506 +1.762125 -0.057861328125 -0.202866210937506 +1.76225 -0.058746337890625 -0.202866210937506 +1.762375 -0.059600830078125 -0.202866210937506 +1.7625 -0.059600830078125 -0.202866210937506 +1.762625 -0.060455322265625 -0.202866210937506 +1.76275 -0.060455322265625 -0.202866210937506 +1.762875 -0.061309814453125 -0.202866210937506 +1.763 -0.062164306640625 -0.202866210937506 +1.763125 -0.062164306640625 -0.202866210937506 +1.76325 -0.06298828125 -0.202866210937506 +1.763375 -0.06298828125 -0.202866210937506 +1.7635 -0.063812255859375 -0.202866210937506 +1.763625 -0.06463623046875 -0.202866210937506 +1.76375 -0.06463623046875 -0.202866210937506 +1.763875 -0.065460205078125 -0.202866210937506 +1.764 -0.065460205078125 -0.202866210937506 +1.764125 -0.066253662109375 -0.202866210937506 +1.76425 -0.06707763671875 -0.202866210937506 +1.764375 -0.06707763671875 -0.202866210937506 +1.7645 -0.06787109375 -0.202866210937506 +1.764625 -0.06787109375 -0.202866210937506 +1.76475 -0.068634033203125 -0.202866210937506 +1.764875 -0.069427490234375 -0.202866210937506 +1.765 -0.069427490234375 -0.202866210937506 +1.765125 -0.0701904296875 -0.202866210937506 +1.76525 -0.0701904296875 -0.202866210937506 +1.765375 -0.070953369140625 -0.202866210937506 +1.7655 -0.07171630859375 -0.202866210937506 +1.765625 -0.07171630859375 -0.202866210937506 +1.76575 -0.07244873046875 -0.202866210937506 +1.765875 -0.07244873046875 -0.202866210937506 +1.766 -0.07318115234375 -0.202866210937506 +1.766125 -0.073944091796875 -0.202866210937506 +1.76625 -0.073944091796875 -0.202866210937506 +1.766375 -0.07464599609375 -0.202866210937506 +1.7665 -0.07464599609375 -0.202866210937506 +1.766625 -0.07537841796875 -0.202866210937506 +1.76675 -0.076080322265625 -0.202866210937506 +1.766875 -0.076080322265625 -0.202866210937506 +1.767 -0.0767822265625 -0.202866210937506 +1.767125 -0.0767822265625 -0.202866210937506 +1.76725 -0.07745361328125 -0.202866210937506 +1.767375 -0.078155517578125 -0.202866210937506 +1.7675 -0.078155517578125 -0.202866210937506 +1.767625 -0.078826904296875 -0.202866210937506 +1.76775 -0.078826904296875 -0.202866210937506 +1.767875 -0.0794677734375 -0.202866210937506 +1.768 -0.08013916015625 -0.202866210937506 +1.768125 -0.08013916015625 -0.202866210937506 +1.76825 -0.080780029296875 -0.202866210937506 +1.768375 -0.080780029296875 -0.202866210937506 +1.7685 -0.0814208984375 -0.202866210937506 +1.768625 -0.082061767578125 -0.202866210937506 +1.76875 -0.082061767578125 -0.202866210937506 +1.768875 -0.082672119140625 -0.202866210937506 +1.769 -0.082672119140625 -0.202866210937506 +1.769125 -0.083282470703125 -0.202866210937506 +1.76925 -0.083892822265625 -0.202866210937506 +1.769375 -0.083892822265625 -0.202866210937506 +1.7695 -0.08447265625 -0.202866210937506 +1.769625 -0.08447265625 -0.202866210937506 +1.76975 -0.085052490234375 -0.202866210937506 +1.769875 -0.08563232421875 -0.202866210937506 +1.77 -0.08563232421875 -0.202866210937506 +1.770125 -0.086181640625 -0.202866210937506 +1.77025 -0.086181640625 -0.202866210937506 +1.770375 -0.086761474609375 -0.202866210937506 +1.7705 -0.0872802734375 -0.202866210937506 +1.770625 -0.0872802734375 -0.202866210937506 +1.77075 -0.08782958984375 -0.202866210937506 +1.770875 -0.08782958984375 -0.202866210937506 +1.771 -0.088348388671875 -0.202866210937506 +1.771125 -0.0888671875 -0.202866210937506 +1.77125 -0.0888671875 -0.202866210937506 +1.771375 -0.089385986328125 -0.202866210937506 +1.7715 -0.089385986328125 -0.202866210937506 +1.771625 -0.089874267578125 -0.202866210937506 +1.77175 -0.090362548828125 -0.202866210937506 +1.771875 -0.090362548828125 -0.202866210937506 +1.772 -0.090850830078125 -0.202866210937506 +1.772125 -0.090850830078125 -0.202866210937506 +1.77225 -0.09130859375 -0.202866210937506 +1.772375 -0.091766357421875 -0.202866210937506 +1.7725 -0.091766357421875 -0.202866210937506 +1.772625 -0.09222412109375 -0.202866210937506 +1.77275 -0.09222412109375 -0.202866210937506 +1.772875 -0.0926513671875 -0.202866210937506 +1.773 -0.09307861328125 -0.202866210937506 +1.773125 -0.09307861328125 -0.202866210937506 +1.77325 -0.093505859375 -0.202866210937506 +1.773375 -0.093505859375 -0.202866210937506 +1.7735 -0.093902587890625 -0.202866210937506 +1.773625 -0.09429931640625 -0.202866210937506 +1.77375 -0.09429931640625 -0.202866210937506 +1.773875 -0.094696044921875 -0.202866210937506 +1.774 -0.094696044921875 -0.202866210937506 +1.774125 -0.095062255859375 -0.202866210937506 +1.77425 -0.095428466796875 -0.202866210937506 +1.774375 -0.095428466796875 -0.202866210937506 +1.7745 -0.09576416015625 -0.202866210937506 +1.774625 -0.09576416015625 -0.202866210937506 +1.77475 -0.09613037109375 -0.202866210937506 +1.774875 -0.096466064453125 -0.202866210937506 +1.775 -0.096466064453125 -0.202866210937506 +1.775125 -0.096771240234375 -0.202866210937506 +1.77525 -0.096771240234375 -0.202866210937506 +1.775375 -0.097076416015625 -0.202866210937506 +1.7755 -0.097381591796875 -0.202866210937506 +1.775625 -0.097381591796875 -0.202866210937506 +1.77575 -0.097686767578125 -0.202866210937506 +1.775875 -0.097686767578125 -0.202866210937506 +1.776 -0.09796142578125 -0.202866210937506 +1.776125 -0.098236083984375 -0.202866210937506 +1.77625 -0.098236083984375 -0.202866210937506 +1.776375 -0.098480224609375 -0.202866210937506 +1.7765 -0.098480224609375 -0.202866210937506 +1.776625 -0.0987548828125 -0.202866210937506 +1.77675 -0.098968505859375 -0.202866210937506 +1.776875 -0.098968505859375 -0.202866210937506 +1.777 -0.099212646484375 -0.202866210937506 +1.777125 -0.099212646484375 -0.202866210937506 +1.77725 -0.09942626953125 -0.202866210937506 +1.777375 -0.099609375 -0.202866210937506 +1.7775 -0.099609375 -0.202866210937506 +1.777625 -0.099822998046875 -0.202866210937506 +1.77775 -0.099822998046875 -0.202866210937506 +1.777875 -0.100006103515625 -0.202866210937506 +1.778 -0.10015869140625 -0.202866210937506 +1.778125 -0.10015869140625 -0.202866210937506 +1.77825 -0.100341796875 -0.202866210937506 +1.778375 -0.100341796875 -0.202866210937506 +1.7785 -0.100494384765625 -0.202866210937506 +1.778625 -0.100616455078125 -0.202866210937506 +1.77875 -0.100616455078125 -0.202866210937506 +1.778875 -0.100738525390625 -0.202866210937506 +1.779 -0.100738525390625 -0.202866210937506 +1.779125 -0.100860595703125 -0.202866210937506 +1.77925 -0.100982666015625 -0.202866210937506 +1.779375 -0.100982666015625 -0.202866210937506 +1.7795 -0.10107421875 -0.202866210937506 +1.779625 -0.10107421875 -0.202866210937506 +1.77975 -0.10113525390625 -0.202866210937506 +1.779875 -0.101226806640625 -0.202866210937506 +1.78 -0.101226806640625 -0.202866210937506 +1.780125 -0.101287841796875 -0.202866210937506 +1.78025 -0.101287841796875 -0.202866210937506 +1.780375 -0.101318359375 -0.202866210937506 +1.7805 -0.10137939453125 -0.202866210937506 +1.780625 -0.10137939453125 -0.202866210937506 +1.78075 -0.101409912109375 -0.202866210937506 +1.780875 -0.101409912109375 -0.202866210937506 +1.781 -0.101409912109375 -0.202866210937506 +1.781125 -0.101409912109375 -0.202866210937506 +1.78125 -0.101409912109375 -0.202866210937506 +1.781375 -0.101409912109375 -0.202866210937506 +1.7815 -0.101409912109375 -0.202866210937506 +1.781625 -0.101409912109375 -0.202866210937506 +1.78175 -0.10137939453125 -0.202866210937506 +1.781875 -0.10137939453125 -0.202866210937506 +1.782 -0.101318359375 -0.202866210937506 +1.782125 -0.101318359375 -0.202866210937506 +1.78225 -0.101287841796875 -0.202866210937506 +1.782375 -0.101226806640625 -0.202866210937506 +1.7825 -0.101226806640625 -0.202866210937506 +1.782625 -0.10113525390625 -0.202866210937506 +1.78275 -0.10113525390625 -0.202866210937506 +1.782875 -0.10107421875 -0.202866210937506 +1.783 -0.100982666015625 -0.202866210937506 +1.783125 -0.100982666015625 -0.202866210937506 +1.78325 -0.100860595703125 -0.202866210937506 +1.783375 -0.100860595703125 -0.202866210937506 +1.7835 -0.100738525390625 -0.202866210937506 +1.783625 -0.100616455078125 -0.202866210937506 +1.78375 -0.100616455078125 -0.202866210937506 +1.783875 -0.100494384765625 -0.202866210937506 +1.784 -0.100494384765625 -0.202866210937506 +1.784125 -0.100341796875 -0.202866210937506 +1.78425 -0.10015869140625 -0.202866210937506 +1.784375 -0.10015869140625 -0.202866210937506 +1.7845 -0.100006103515625 -0.202866210937506 +1.784625 -0.100006103515625 -0.202866210937506 +1.78475 -0.099822998046875 -0.202866210937506 +1.784875 -0.099609375 -0.202866210937506 +1.785 -0.099609375 -0.202866210937506 +1.785125 -0.09942626953125 -0.202866210937506 +1.78525 -0.09942626953125 -0.202866210937506 +1.785375 -0.099212646484375 -0.202866210937506 +1.7855 -0.098968505859375 -0.202866210937506 +1.785625 -0.098968505859375 -0.202866210937506 +1.78575 -0.0987548828125 -0.202866210937506 +1.785875 -0.0987548828125 -0.202866210937506 +1.786 -0.098480224609375 -0.202866210937506 +1.786125 -0.098236083984375 -0.202866210937506 +1.78625 -0.098236083984375 -0.202866210937506 +1.786375 -0.09796142578125 -0.202866210937506 +1.7865 -0.09796142578125 -0.202866210937506 +1.786625 -0.097686767578125 -0.202866210937506 +1.78675 -0.097381591796875 -0.202866210937506 +1.786875 -0.097381591796875 -0.202866210937506 +1.787 -0.097076416015625 -0.202866210937506 +1.787125 -0.097076416015625 -0.202866210937506 +1.78725 -0.096771240234375 -0.202866210937506 +1.787375 -0.096466064453125 -0.202866210937506 +1.7875 -0.096466064453125 -0.202866210937506 +1.787625 -0.09613037109375 -0.202866210937506 +1.78775 -0.09613037109375 -0.202866210937506 +1.787875 -0.09576416015625 -0.202866210937506 +1.788 -0.095428466796875 -0.202866210937506 +1.788125 -0.095428466796875 -0.202866210937506 +1.78825 -0.095062255859375 -0.202866210937506 +1.788375 -0.095062255859375 -0.202866210937506 +1.7885 -0.094696044921875 -0.202866210937506 +1.788625 -0.09429931640625 -0.202866210937506 +1.78875 -0.09429931640625 -0.202866210937506 +1.788875 -0.093902587890625 -0.202866210937506 +1.789 -0.093902587890625 -0.202866210937506 +1.789125 -0.093505859375 -0.202866210937506 +1.78925 -0.09307861328125 -0.202866210937506 +1.789375 -0.09307861328125 -0.202866210937506 +1.7895 -0.0926513671875 -0.202866210937506 +1.789625 -0.0926513671875 -0.202866210937506 +1.78975 -0.09222412109375 -0.202866210937506 +1.789875 -0.091766357421875 -0.202866210937506 +1.79 -0.091766357421875 -0.202866210937506 +1.790125 -0.09130859375 -0.202866210937506 +1.79025 -0.09130859375 -0.202866210937506 +1.790375 -0.090850830078125 -0.202866210937506 +1.7905 -0.090362548828125 -0.202866210937506 +1.790625 -0.090362548828125 -0.202866210937506 +1.79075 -0.089874267578125 -0.202866210937506 +1.790875 -0.089874267578125 -0.202866210937506 +1.791 -0.089385986328125 -0.202866210937506 +1.791125 -0.0888671875 -0.202866210937506 +1.79125 -0.0888671875 -0.202866210937506 +1.791375 -0.088348388671875 -0.202866210937506 +1.7915 -0.088348388671875 -0.202866210937506 +1.791625 -0.08782958984375 -0.202866210937506 +1.79175 -0.0872802734375 -0.202866210937506 +1.791875 -0.0872802734375 -0.202866210937506 +1.792 -0.18865966796875 -0.4412060546875043 +1.792125 -0.18865966796875 -0.4412060546875043 +1.79225 -0.187469482421875 -0.4412060546875043 +1.792375 -0.186248779296875 -0.4412060546875043 +1.7925 -0.186248779296875 -0.4412060546875043 +1.792625 -0.184967041015625 -0.4412060546875043 +1.79275 -0.184967041015625 -0.4412060546875043 +1.792875 -0.1837158203125 -0.4412060546875043 +1.793 -0.18243408203125 -0.4412060546875043 +1.793125 -0.18243408203125 -0.4412060546875043 +1.79325 -0.181121826171875 -0.4412060546875043 +1.793375 -0.181121826171875 -0.4412060546875043 +1.7935 -0.179779052734375 -0.4412060546875043 +1.793625 -0.178436279296875 -0.4412060546875043 +1.79375 -0.178436279296875 -0.4412060546875043 +1.793875 -0.17706298828125 -0.4412060546875043 +1.794 -0.17706298828125 -0.4412060546875043 +1.794125 -0.175689697265625 -0.4412060546875043 +1.79425 -0.174285888671875 -0.4412060546875043 +1.794375 -0.174285888671875 -0.4412060546875043 +1.7945 -0.1728515625 -0.4412060546875043 +1.794625 -0.1728515625 -0.4412060546875043 +1.79475 -0.171417236328125 -0.4412060546875043 +1.794875 -0.169952392578125 -0.4412060546875043 +1.795 -0.169952392578125 -0.4412060546875043 +1.795125 -0.16845703125 -0.4412060546875043 +1.79525 -0.16845703125 -0.4412060546875043 +1.795375 -0.166961669921875 -0.4412060546875043 +1.7955 -0.165435791015625 -0.4412060546875043 +1.795625 -0.165435791015625 -0.4412060546875043 +1.79575 -0.163909912109375 -0.4412060546875043 +1.795875 -0.163909912109375 -0.4412060546875043 +1.796 -0.162353515625 -0.4412060546875043 +1.796125 -0.160797119140625 -0.4412060546875043 +1.79625 -0.160797119140625 -0.4412060546875043 +1.796375 -0.1591796875 -0.4412060546875043 +1.7965 -0.1591796875 -0.4412060546875043 +1.796625 -0.1575927734375 -0.4412060546875043 +1.79675 -0.15594482421875 -0.4412060546875043 +1.796875 -0.15594482421875 -0.4412060546875043 +1.797 -0.154327392578125 -0.4412060546875043 +1.797125 -0.154327392578125 -0.4412060546875043 +1.79725 -0.15264892578125 -0.4412060546875043 +1.797375 -0.150970458984375 -0.4412060546875043 +1.7975 -0.150970458984375 -0.4412060546875043 +1.797625 -0.1492919921875 -0.4412060546875043 +1.79775 -0.1492919921875 -0.4412060546875043 +1.797875 -0.1475830078125 -0.4412060546875043 +1.798 -0.1458740234375 -0.4412060546875043 +1.798125 -0.1458740234375 -0.4412060546875043 +1.79825 -0.14410400390625 -0.4412060546875043 +1.798375 -0.14410400390625 -0.4412060546875043 +1.7985 -0.142364501953125 -0.4412060546875043 +1.798625 -0.140594482421875 -0.4412060546875043 +1.79875 -0.140594482421875 -0.4412060546875043 +1.798875 -0.1387939453125 -0.4412060546875043 +1.799 -0.1387939453125 -0.4412060546875043 +1.799125 -0.136993408203125 -0.4412060546875043 +1.79925 -0.13519287109375 -0.4412060546875043 +1.799375 -0.13519287109375 -0.4412060546875043 +1.7995 -0.13336181640625 -0.4412060546875043 +1.799625 -0.13336181640625 -0.4412060546875043 +1.79975 -0.131500244140625 -0.4412060546875043 +1.799875 -0.129638671875 -0.4412060546875043 +1.8 -0.129638671875 -0.4412060546875043 +1.800125 -0.127777099609375 -0.4412060546875043 +1.80025 -0.127777099609375 -0.4412060546875043 +1.800375 -0.125885009765625 -0.4412060546875043 +1.8005 -0.12396240234375 -0.4412060546875043 +1.800625 -0.12396240234375 -0.4412060546875043 +1.80075 -0.122039794921875 -0.4412060546875043 +1.800875 -0.122039794921875 -0.4412060546875043 +1.801 -0.1201171875 -0.4412060546875043 +1.801125 -0.118194580078125 -0.4412060546875043 +1.80125 -0.118194580078125 -0.4412060546875043 +1.801375 -0.1162109375 -0.4412060546875043 +1.8015 -0.1162109375 -0.4412060546875043 +1.801625 -0.1142578125 -0.4412060546875043 +1.80175 -0.112274169921875 -0.4412060546875043 +1.801875 -0.112274169921875 -0.4412060546875043 +1.802 -0.11029052734375 -0.4412060546875043 +1.802125 -0.11029052734375 -0.4412060546875043 +1.80225 -0.1082763671875 -0.4412060546875043 +1.802375 -0.10626220703125 -0.4412060546875043 +1.8025 -0.10626220703125 -0.4412060546875043 +1.802625 -0.104217529296875 -0.4412060546875043 +1.80275 -0.104217529296875 -0.4412060546875043 +1.802875 -0.1021728515625 -0.4412060546875043 +1.803 -0.100128173828125 -0.4412060546875043 +1.803125 -0.100128173828125 -0.4412060546875043 +1.80325 -0.098052978515625 -0.4412060546875043 +1.803375 -0.098052978515625 -0.4412060546875043 +1.8035 -0.095977783203125 -0.4412060546875043 +1.803625 -0.093902587890625 -0.4412060546875043 +1.80375 -0.093902587890625 -0.4412060546875043 +1.803875 -0.091796875 -0.4412060546875043 +1.804 -0.091796875 -0.4412060546875043 +1.804125 -0.089691162109375 -0.4412060546875043 +1.80425 -0.08758544921875 -0.4412060546875043 +1.804375 -0.08758544921875 -0.4412060546875043 +1.8045 -0.08544921875 -0.4412060546875043 +1.804625 -0.08544921875 -0.4412060546875043 +1.80475 -0.08331298828125 -0.4412060546875043 +1.804875 -0.0811767578125 -0.4412060546875043 +1.805 -0.0811767578125 -0.4412060546875043 +1.805125 -0.07904052734375 -0.4412060546875043 +1.80525 -0.07904052734375 -0.4412060546875043 +1.805375 -0.076873779296875 -0.4412060546875043 +1.8055 -0.07470703125 -0.4412060546875043 +1.805625 -0.07470703125 -0.4412060546875043 +1.80575 -0.072509765625 -0.4412060546875043 +1.805875 -0.072509765625 -0.4412060546875043 +1.806 -0.070343017578125 -0.4412060546875043 +1.806125 -0.068145751953125 -0.4412060546875043 +1.80625 -0.068145751953125 -0.4412060546875043 +1.806375 -0.065948486328125 -0.4412060546875043 +1.8065 -0.065948486328125 -0.4412060546875043 +1.806625 -0.063751220703125 -0.4412060546875043 +1.80675 -0.0615234375 -0.4412060546875043 +1.806875 -0.0615234375 -0.4412060546875043 +1.807 -0.059295654296875 -0.4412060546875043 +1.807125 -0.059295654296875 -0.4412060546875043 +1.80725 -0.05706787109375 -0.4412060546875043 +1.807375 -0.054840087890625 -0.4412060546875043 +1.8075 -0.054840087890625 -0.4412060546875043 +1.807625 -0.0526123046875 -0.4412060546875043 +1.80775 -0.0526123046875 -0.4412060546875043 +1.807875 -0.05035400390625 -0.4412060546875043 +1.808 -0.048095703125 -0.4412060546875043 +1.808125 -0.048095703125 -0.4412060546875043 +1.80825 -0.04583740234375 -0.4412060546875043 +1.808375 -0.04583740234375 -0.4412060546875043 +1.8085 -0.0435791015625 -0.4412060546875043 +1.808625 -0.04132080078125 -0.4412060546875043 +1.80875 -0.04132080078125 -0.4412060546875043 +1.808875 -0.039031982421875 -0.4412060546875043 +1.809 -0.039031982421875 -0.4412060546875043 +1.809125 -0.036773681640625 -0.4412060546875043 +1.80925 -0.03448486328125 -0.4412060546875043 +1.809375 -0.03448486328125 -0.4412060546875043 +1.8095 -0.032196044921875 -0.4412060546875043 +1.809625 -0.032196044921875 -0.4412060546875043 +1.80975 -0.0299072265625 -0.4412060546875043 +1.809875 -0.027618408203125 -0.4412060546875043 +1.81 -0.027618408203125 -0.4412060546875043 +1.810125 -0.02532958984375 -0.4412060546875043 +1.81025 -0.02532958984375 -0.4412060546875043 +1.810375 -0.023040771484375 -0.4412060546875043 +1.8105 -0.020751953125 -0.4412060546875043 +1.810625 -0.020751953125 -0.4412060546875043 +1.81075 -0.0184326171875 -0.4412060546875043 +1.810875 -0.0184326171875 -0.4412060546875043 +1.811 -0.016143798828125 -0.4412060546875043 +1.811125 -0.013824462890625 -0.4412060546875043 +1.81125 -0.013824462890625 -0.4412060546875043 +1.811375 -0.01153564453125 -0.4412060546875043 +1.8115 -0.01153564453125 -0.4412060546875043 +1.811625 -0.00921630859375 -0.4412060546875043 +1.81175 -0.00689697265625 -0.4412060546875043 +1.811875 -0.00689697265625 -0.4412060546875043 +1.812 -0.004608154296875 -0.4412060546875043 +1.812125 -0.004608154296875 -0.4412060546875043 +1.81225 -0.002288818359375 -0.4412060546875043 1.812375 0.0 -0.4412060546875043 1.8125 0.0 -0.4412060546875043 1.812625 0.002288818359375 -0.4412060546875043 @@ -14999,504 +14999,504 @@ 1.87475 0.003082275390625 -0.5893066406249988 1.874875 0.0 -0.5893066406249988 1.875 0.0 -0.5893066406249988 -1.875125 -0.00311279296875 -0.5893066406249988 -1.87525 -0.00311279296875 -0.5893066406249988 -1.875375 -0.006195068359375 -0.5893066406249988 -1.8755 -0.00927734375 -0.5893066406249988 -1.875625 -0.00927734375 -0.5893066406249988 -1.87575 -0.012359619140625 -0.5893066406249988 -1.875875 -0.012359619140625 -0.5893066406249988 -1.876 -0.01544189453125 -0.5893066406249988 -1.876125 -0.018524169921875 -0.5893066406249988 -1.87625 -0.018524169921875 -0.5893066406249988 -1.876375 -0.021575927734375 -0.5893066406249988 -1.8765 -0.021575927734375 -0.5893066406249988 -1.876625 -0.024658203125 -0.5893066406249988 -1.87675 -0.027740478515625 -0.5893066406249988 -1.876875 -0.027740478515625 -0.5893066406249988 -1.877 -0.03082275390625 -0.5893066406249988 -1.877125 -0.03082275390625 -0.5893066406249988 -1.87725 -0.03387451171875 -0.5893066406249988 -1.877375 -0.03692626953125 -0.5893066406249988 -1.8775 -0.03692626953125 -0.5893066406249988 -1.877625 -0.040008544921875 -0.5893066406249988 -1.87775 -0.040008544921875 -0.5893066406249988 -1.877875 -0.043060302734375 -0.5893066406249988 -1.878 -0.046112060546875 -0.5893066406249988 -1.878125 -0.046112060546875 -0.5893066406249988 -1.87825 -0.04913330078125 -0.5893066406249988 -1.878375 -0.04913330078125 -0.5893066406249988 -1.8785 -0.05218505859375 -0.5893066406249988 -1.878625 -0.055206298828125 -0.5893066406249988 -1.87875 -0.055206298828125 -0.5893066406249988 -1.878875 -0.058258056640625 -0.5893066406249988 -1.879 -0.058258056640625 -0.5893066406249988 -1.879125 -0.061279296875 -0.5893066406249988 -1.87925 -0.06427001953125 -0.5893066406249988 -1.879375 -0.06427001953125 -0.5893066406249988 -1.8795 -0.067291259765625 -0.5893066406249988 -1.879625 -0.067291259765625 -0.5893066406249988 -1.87975 -0.070281982421875 -0.5893066406249988 -1.879875 -0.073272705078125 -0.5893066406249988 -1.88 -0.073272705078125 -0.5893066406249988 -1.880125 -0.076263427734375 -0.5893066406249988 -1.88025 -0.076263427734375 -0.5893066406249988 -1.880375 -0.079254150390625 -0.5893066406249988 -1.8805 -0.08221435546875 -0.5893066406249988 -1.880625 -0.08221435546875 -0.5893066406249988 -1.88075 -0.085174560546875 -0.5893066406249988 -1.880875 -0.085174560546875 -0.5893066406249988 -1.881 -0.088104248046875 -0.5893066406249988 -1.881125 -0.091064453125 -0.5893066406249988 -1.88125 -0.091064453125 -0.5893066406249988 -1.881375 -0.093994140625 -0.5893066406249988 -1.8815 -0.093994140625 -0.5893066406249988 -1.881625 -0.096893310546875 -0.5893066406249988 -1.88175 -0.099822998046875 -0.5893066406249988 -1.881875 -0.099822998046875 -0.5893066406249988 -1.882 -0.10272216796875 -0.5893066406249988 -1.882125 -0.10272216796875 -0.5893066406249988 -1.88225 -0.1055908203125 -0.5893066406249988 -1.882375 -0.108489990234375 -0.5893066406249988 -1.8825 -0.108489990234375 -0.5893066406249988 -1.882625 -0.111328125 -0.5893066406249988 -1.88275 -0.111328125 -0.5893066406249988 -1.882875 -0.11419677734375 -0.5893066406249988 -1.883 -0.117034912109375 -0.5893066406249988 -1.883125 -0.117034912109375 -0.5893066406249988 -1.88325 -0.119842529296875 -0.5893066406249988 -1.883375 -0.119842529296875 -0.5893066406249988 -1.8835 -0.122650146484375 -0.5893066406249988 -1.883625 -0.125457763671875 -0.5893066406249988 -1.88375 -0.125457763671875 -0.5893066406249988 -1.883875 -0.12823486328125 -0.5893066406249988 -1.884 -0.12823486328125 -0.5893066406249988 -1.884125 -0.131011962890625 -0.5893066406249988 -1.88425 -0.133758544921875 -0.5893066406249988 -1.884375 -0.133758544921875 -0.5893066406249988 -1.8845 -0.136505126953125 -0.5893066406249988 -1.884625 -0.136505126953125 -0.5893066406249988 -1.88475 -0.139251708984375 -0.5893066406249988 -1.884875 -0.1419677734375 -0.5893066406249988 -1.885 -0.1419677734375 -0.5893066406249988 -1.885125 -0.1446533203125 -0.5893066406249988 -1.88525 -0.1446533203125 -0.5893066406249988 -1.885375 -0.1473388671875 -0.5893066406249988 -1.8855 -0.149993896484375 -0.5893066406249988 -1.885625 -0.149993896484375 -0.5893066406249988 -1.88575 -0.15264892578125 -0.5893066406249988 -1.885875 -0.15264892578125 -0.5893066406249988 -1.886 -0.1552734375 -0.5893066406249988 -1.886125 -0.15789794921875 -0.5893066406249988 -1.88625 -0.15789794921875 -0.5893066406249988 -1.886375 -0.160491943359375 -0.5893066406249988 -1.8865 -0.160491943359375 -0.5893066406249988 -1.886625 -0.163055419921875 -0.5893066406249988 -1.88675 -0.165618896484375 -0.5893066406249988 -1.886875 -0.165618896484375 -0.5893066406249988 -1.887 -0.16815185546875 -0.5893066406249988 -1.887125 -0.16815185546875 -0.5893066406249988 -1.88725 -0.170684814453125 -0.5893066406249988 -1.887375 -0.173187255859375 -0.5893066406249988 -1.8875 -0.173187255859375 -0.5893066406249988 -1.887625 -0.175689697265625 -0.5893066406249988 -1.88775 -0.175689697265625 -0.5893066406249988 -1.887875 -0.178131103515625 -0.5893066406249988 -1.888 -0.145721435546875 -0.4754394531249956 -1.888125 -0.145721435546875 -0.4754394531249956 -1.88825 -0.147674560546875 -0.4754394531249956 -1.888375 -0.147674560546875 -0.4754394531249956 -1.8885 -0.14959716796875 -0.4754394531249956 -1.888625 -0.151519775390625 -0.4754394531249956 -1.88875 -0.151519775390625 -0.4754394531249956 -1.888875 -0.1534423828125 -0.4754394531249956 -1.889 -0.1534423828125 -0.4754394531249956 -1.889125 -0.15533447265625 -0.4754394531249956 -1.88925 -0.1572265625 -0.4754394531249956 -1.889375 -0.1572265625 -0.4754394531249956 -1.8895 -0.1590576171875 -0.4754394531249956 -1.889625 -0.1590576171875 -0.4754394531249956 -1.88975 -0.160919189453125 -0.4754394531249956 -1.889875 -0.1627197265625 -0.4754394531249956 -1.89 -0.1627197265625 -0.4754394531249956 -1.890125 -0.16455078125 -0.4754394531249956 -1.89025 -0.16455078125 -0.4754394531249956 -1.890375 -0.16632080078125 -0.4754394531249956 -1.8905 -0.1680908203125 -0.4754394531249956 -1.890625 -0.1680908203125 -0.4754394531249956 -1.89075 -0.16986083984375 -0.4754394531249956 -1.890875 -0.16986083984375 -0.4754394531249956 -1.891 -0.17156982421875 -0.4754394531249956 -1.891125 -0.173309326171875 -0.4754394531249956 -1.89125 -0.173309326171875 -0.4754394531249956 -1.891375 -0.17498779296875 -0.4754394531249956 -1.8915 -0.17498779296875 -0.4754394531249956 -1.891625 -0.176666259765625 -0.4754394531249956 -1.89175 -0.178314208984375 -0.4754394531249956 -1.891875 -0.178314208984375 -0.4754394531249956 -1.892 -0.179962158203125 -0.4754394531249956 -1.892125 -0.179962158203125 -0.4754394531249956 -1.89225 -0.18157958984375 -0.4754394531249956 -1.892375 -0.18316650390625 -0.4754394531249956 -1.8925 -0.18316650390625 -0.4754394531249956 -1.892625 -0.18475341796875 -0.4754394531249956 -1.89275 -0.18475341796875 -0.4754394531249956 -1.892875 -0.186309814453125 -0.4754394531249956 -1.893 -0.187835693359375 -0.4754394531249956 -1.893125 -0.187835693359375 -0.4754394531249956 -1.89325 -0.189361572265625 -0.4754394531249956 -1.893375 -0.189361572265625 -0.4754394531249956 -1.8935 -0.19085693359375 -0.4754394531249956 -1.893625 -0.19232177734375 -0.4754394531249956 -1.89375 -0.19232177734375 -0.4754394531249956 -1.893875 -0.19378662109375 -0.4754394531249956 -1.894 -0.19378662109375 -0.4754394531249956 -1.894125 -0.195220947265625 -0.4754394531249956 -1.89425 -0.196624755859375 -0.4754394531249956 -1.894375 -0.196624755859375 -0.4754394531249956 -1.8945 -0.197998046875 -0.4754394531249956 -1.894625 -0.197998046875 -0.4754394531249956 -1.89475 -0.199371337890625 -0.4754394531249956 -1.894875 -0.200714111328125 -0.4754394531249956 -1.895 -0.200714111328125 -0.4754394531249956 -1.895125 -0.2020263671875 -0.4754394531249956 -1.89525 -0.2020263671875 -0.4754394531249956 -1.895375 -0.203338623046875 -0.4754394531249956 -1.8955 -0.204620361328125 -0.4754394531249956 -1.895625 -0.204620361328125 -0.4754394531249956 -1.89575 -0.20587158203125 -0.4754394531249956 -1.895875 -0.20587158203125 -0.4754394531249956 -1.896 -0.207122802734375 -0.4754394531249956 -1.896125 -0.20831298828125 -0.4754394531249956 -1.89625 -0.20831298828125 -0.4754394531249956 -1.896375 -0.209503173828125 -0.4754394531249956 -1.8965 -0.209503173828125 -0.4754394531249956 -1.896625 -0.210662841796875 -0.4754394531249956 -1.89675 -0.211822509765625 -0.4754394531249956 -1.896875 -0.211822509765625 -0.4754394531249956 -1.897 -0.212921142578125 -0.4754394531249956 -1.897125 -0.212921142578125 -0.4754394531249956 -1.89725 -0.214019775390625 -0.4754394531249956 -1.897375 -0.215087890625 -0.4754394531249956 -1.8975 -0.215087890625 -0.4754394531249956 -1.897625 -0.216156005859375 -0.4754394531249956 -1.89775 -0.216156005859375 -0.4754394531249956 -1.897875 -0.2171630859375 -0.4754394531249956 -1.898 -0.218170166015625 -0.4754394531249956 -1.898125 -0.218170166015625 -0.4754394531249956 -1.89825 -0.219146728515625 -0.4754394531249956 -1.898375 -0.219146728515625 -0.4754394531249956 -1.8985 -0.2200927734375 -0.4754394531249956 -1.898625 -0.221038818359375 -0.4754394531249956 -1.89875 -0.221038818359375 -0.4754394531249956 -1.898875 -0.221923828125 -0.4754394531249956 -1.899 -0.221923828125 -0.4754394531249956 -1.899125 -0.222808837890625 -0.4754394531249956 -1.89925 -0.223663330078125 -0.4754394531249956 -1.899375 -0.223663330078125 -0.4754394531249956 -1.8995 -0.2244873046875 -0.4754394531249956 -1.899625 -0.2244873046875 -0.4754394531249956 -1.89975 -0.225311279296875 -0.4754394531249956 -1.899875 -0.22607421875 -0.4754394531249956 -1.9 -0.22607421875 -0.4754394531249956 -1.900125 -0.226837158203125 -0.4754394531249956 -1.90025 -0.226837158203125 -0.4754394531249956 -1.900375 -0.227569580078125 -0.4754394531249956 -1.9005 -0.228271484375 -0.4754394531249956 -1.900625 -0.228271484375 -0.4754394531249956 -1.90075 -0.228973388671875 -0.4754394531249956 -1.900875 -0.228973388671875 -0.4754394531249956 -1.901 -0.2296142578125 -0.4754394531249956 -1.901125 -0.230255126953125 -0.4754394531249956 -1.90125 -0.230255126953125 -0.4754394531249956 -1.901375 -0.230865478515625 -0.4754394531249956 -1.9015 -0.230865478515625 -0.4754394531249956 -1.901625 -0.2314453125 -0.4754394531249956 -1.90175 -0.23199462890625 -0.4754394531249956 -1.901875 -0.23199462890625 -0.4754394531249956 -1.902 -0.232513427734375 -0.4754394531249956 -1.902125 -0.232513427734375 -0.4754394531249956 -1.90225 -0.2330322265625 -0.4754394531249956 -1.902375 -0.2335205078125 -0.4754394531249956 -1.9025 -0.2335205078125 -0.4754394531249956 -1.902625 -0.233978271484375 -0.4754394531249956 -1.90275 -0.233978271484375 -0.4754394531249956 -1.902875 -0.234405517578125 -0.4754394531249956 -1.903 -0.23480224609375 -0.4754394531249956 -1.903125 -0.23480224609375 -0.4754394531249956 -1.90325 -0.23516845703125 -0.4754394531249956 -1.903375 -0.23516845703125 -0.4754394531249956 -1.9035 -0.235504150390625 -0.4754394531249956 -1.903625 -0.23583984375 -0.4754394531249956 -1.90375 -0.23583984375 -0.4754394531249956 -1.903875 -0.23614501953125 -0.4754394531249956 -1.904 -0.23614501953125 -0.4754394531249956 -1.904125 -0.236419677734375 -0.4754394531249956 -1.90425 -0.236663818359375 -0.4754394531249956 -1.904375 -0.236663818359375 -0.4754394531249956 -1.9045 -0.23687744140625 -0.4754394531249956 -1.904625 -0.23687744140625 -0.4754394531249956 -1.90475 -0.237091064453125 -0.4754394531249956 -1.904875 -0.23724365234375 -0.4754394531249956 -1.905 -0.23724365234375 -0.4754394531249956 -1.905125 -0.237396240234375 -0.4754394531249956 -1.90525 -0.237396240234375 -0.4754394531249956 -1.905375 -0.237518310546875 -0.4754394531249956 -1.9055 -0.23760986328125 -0.4754394531249956 -1.905625 -0.23760986328125 -0.4754394531249956 -1.90575 -0.2376708984375 -0.4754394531249956 -1.905875 -0.2376708984375 -0.4754394531249956 -1.906 -0.237701416015625 -0.4754394531249956 -1.906125 -0.23773193359375 -0.4754394531249956 -1.90625 -0.23773193359375 -0.4754394531249956 -1.906375 -0.237701416015625 -0.4754394531249956 -1.9065 -0.237701416015625 -0.4754394531249956 -1.906625 -0.2376708984375 -0.4754394531249956 -1.90675 -0.23760986328125 -0.4754394531249956 -1.906875 -0.23760986328125 -0.4754394531249956 -1.907 -0.237518310546875 -0.4754394531249956 -1.907125 -0.237518310546875 -0.4754394531249956 -1.90725 -0.237396240234375 -0.4754394531249956 -1.907375 -0.23724365234375 -0.4754394531249956 -1.9075 -0.23724365234375 -0.4754394531249956 -1.907625 -0.237091064453125 -0.4754394531249956 -1.90775 -0.237091064453125 -0.4754394531249956 -1.907875 -0.23687744140625 -0.4754394531249956 -1.908 -0.236663818359375 -0.4754394531249956 -1.908125 -0.236663818359375 -0.4754394531249956 -1.90825 -0.236419677734375 -0.4754394531249956 -1.908375 -0.236419677734375 -0.4754394531249956 -1.9085 -0.23614501953125 -0.4754394531249956 -1.908625 -0.23583984375 -0.4754394531249956 -1.90875 -0.23583984375 -0.4754394531249956 -1.908875 -0.235504150390625 -0.4754394531249956 -1.909 -0.235504150390625 -0.4754394531249956 -1.909125 -0.23516845703125 -0.4754394531249956 -1.90925 -0.23480224609375 -0.4754394531249956 -1.909375 -0.23480224609375 -0.4754394531249956 -1.9095 -0.234405517578125 -0.4754394531249956 -1.909625 -0.234405517578125 -0.4754394531249956 -1.90975 -0.233978271484375 -0.4754394531249956 -1.909875 -0.2335205078125 -0.4754394531249956 -1.91 -0.2335205078125 -0.4754394531249956 -1.910125 -0.2330322265625 -0.4754394531249956 -1.91025 -0.2330322265625 -0.4754394531249956 -1.910375 -0.232513427734375 -0.4754394531249956 -1.9105 -0.23199462890625 -0.4754394531249956 -1.910625 -0.23199462890625 -0.4754394531249956 -1.91075 -0.2314453125 -0.4754394531249956 -1.910875 -0.2314453125 -0.4754394531249956 -1.911 -0.230865478515625 -0.4754394531249956 -1.911125 -0.230255126953125 -0.4754394531249956 -1.91125 -0.230255126953125 -0.4754394531249956 -1.911375 -0.2296142578125 -0.4754394531249956 -1.9115 -0.2296142578125 -0.4754394531249956 -1.911625 -0.228973388671875 -0.4754394531249956 -1.91175 -0.228271484375 -0.4754394531249956 -1.911875 -0.228271484375 -0.4754394531249956 -1.912 -0.227569580078125 -0.4754394531249956 -1.912125 -0.227569580078125 -0.4754394531249956 -1.91225 -0.226837158203125 -0.4754394531249956 -1.912375 -0.22607421875 -0.4754394531249956 -1.9125 -0.22607421875 -0.4754394531249956 -1.912625 -0.225311279296875 -0.4754394531249956 -1.91275 -0.225311279296875 -0.4754394531249956 -1.912875 -0.2244873046875 -0.4754394531249956 -1.913 -0.223663330078125 -0.4754394531249956 -1.913125 -0.223663330078125 -0.4754394531249956 -1.91325 -0.222808837890625 -0.4754394531249956 -1.913375 -0.222808837890625 -0.4754394531249956 -1.9135 -0.221923828125 -0.4754394531249956 -1.913625 -0.221038818359375 -0.4754394531249956 -1.91375 -0.221038818359375 -0.4754394531249956 -1.913875 -0.2200927734375 -0.4754394531249956 -1.914 -0.2200927734375 -0.4754394531249956 -1.914125 -0.219146728515625 -0.4754394531249956 -1.91425 -0.218170166015625 -0.4754394531249956 -1.914375 -0.218170166015625 -0.4754394531249956 -1.9145 -0.2171630859375 -0.4754394531249956 -1.914625 -0.2171630859375 -0.4754394531249956 -1.91475 -0.216156005859375 -0.4754394531249956 -1.914875 -0.215087890625 -0.4754394531249956 -1.915 -0.215087890625 -0.4754394531249956 -1.915125 -0.214019775390625 -0.4754394531249956 -1.91525 -0.214019775390625 -0.4754394531249956 -1.915375 -0.212921142578125 -0.4754394531249956 -1.9155 -0.211822509765625 -0.4754394531249956 -1.915625 -0.211822509765625 -0.4754394531249956 -1.91575 -0.210662841796875 -0.4754394531249956 -1.915875 -0.210662841796875 -0.4754394531249956 -1.916 -0.209503173828125 -0.4754394531249956 -1.916125 -0.20831298828125 -0.4754394531249956 -1.91625 -0.20831298828125 -0.4754394531249956 -1.916375 -0.207122802734375 -0.4754394531249956 -1.9165 -0.207122802734375 -0.4754394531249956 -1.916625 -0.20587158203125 -0.4754394531249956 -1.91675 -0.204620361328125 -0.4754394531249956 -1.916875 -0.204620361328125 -0.4754394531249956 -1.917 -0.203338623046875 -0.4754394531249956 -1.917125 -0.203338623046875 -0.4754394531249956 -1.91725 -0.2020263671875 -0.4754394531249956 -1.917375 -0.200714111328125 -0.4754394531249956 -1.9175 -0.200714111328125 -0.4754394531249956 -1.917625 -0.199371337890625 -0.4754394531249956 -1.91775 -0.199371337890625 -0.4754394531249956 -1.917875 -0.197998046875 -0.4754394531249956 -1.918 -0.196624755859375 -0.4754394531249956 -1.918125 -0.196624755859375 -0.4754394531249956 -1.91825 -0.195220947265625 -0.4754394531249956 -1.918375 -0.195220947265625 -0.4754394531249956 -1.9185 -0.19378662109375 -0.4754394531249956 -1.918625 -0.19232177734375 -0.4754394531249956 -1.91875 -0.19232177734375 -0.4754394531249956 -1.918875 -0.19085693359375 -0.4754394531249956 -1.919 -0.19085693359375 -0.4754394531249956 -1.919125 -0.189361572265625 -0.4754394531249956 -1.91925 -0.187835693359375 -0.4754394531249956 -1.919375 -0.187835693359375 -0.4754394531249956 -1.9195 -0.186309814453125 -0.4754394531249956 -1.919625 -0.186309814453125 -0.4754394531249956 -1.91975 -0.18475341796875 -0.4754394531249956 -1.919875 -0.18316650390625 -0.4754394531249956 -1.92 -0.0977783203125 -0.2537792968749932 -1.920125 -0.096923828125 -0.2537792968749932 -1.92025 -0.096923828125 -0.2537792968749932 -1.920375 -0.0960693359375 -0.2537792968749932 -1.9205 -0.095184326171875 -0.2537792968749932 -1.920625 -0.095184326171875 -0.2537792968749932 -1.92075 -0.09429931640625 -0.2537792968749932 -1.920875 -0.09429931640625 -0.2537792968749932 -1.921 -0.093414306640625 -0.2537792968749932 -1.921125 -0.092498779296875 -0.2537792968749932 -1.92125 -0.092498779296875 -0.2537792968749932 -1.921375 -0.091583251953125 -0.2537792968749932 -1.9215 -0.091583251953125 -0.2537792968749932 -1.921625 -0.090667724609375 -0.2537792968749932 -1.92175 -0.0897216796875 -0.2537792968749932 -1.921875 -0.0897216796875 -0.2537792968749932 -1.922 -0.08880615234375 -0.2537792968749932 -1.922125 -0.08880615234375 -0.2537792968749932 -1.92225 -0.08782958984375 -0.2537792968749932 -1.922375 -0.086883544921875 -0.2537792968749932 -1.9225 -0.086883544921875 -0.2537792968749932 -1.922625 -0.085906982421875 -0.2537792968749932 -1.92275 -0.085906982421875 -0.2537792968749932 -1.922875 -0.084930419921875 -0.2537792968749932 -1.923 -0.08392333984375 -0.2537792968749932 -1.923125 -0.08392333984375 -0.2537792968749932 -1.92325 -0.082916259765625 -0.2537792968749932 -1.923375 -0.082916259765625 -0.2537792968749932 -1.9235 -0.0819091796875 -0.2537792968749932 -1.923625 -0.080902099609375 -0.2537792968749932 -1.92375 -0.080902099609375 -0.2537792968749932 -1.923875 -0.079864501953125 -0.2537792968749932 -1.924 -0.079864501953125 -0.2537792968749932 -1.924125 -0.078826904296875 -0.2537792968749932 -1.92425 -0.077789306640625 -0.2537792968749932 -1.924375 -0.077789306640625 -0.2537792968749932 -1.9245 -0.07672119140625 -0.2537792968749932 -1.924625 -0.07672119140625 -0.2537792968749932 -1.92475 -0.075653076171875 -0.2537792968749932 -1.924875 -0.0745849609375 -0.2537792968749932 -1.925 -0.0745849609375 -0.2537792968749932 -1.925125 -0.073516845703125 -0.2537792968749932 -1.92525 -0.073516845703125 -0.2537792968749932 -1.925375 -0.072418212890625 -0.2537792968749932 -1.9255 -0.071319580078125 -0.2537792968749932 -1.925625 -0.071319580078125 -0.2537792968749932 -1.92575 -0.070220947265625 -0.2537792968749932 -1.925875 -0.070220947265625 -0.2537792968749932 -1.926 -0.069122314453125 -0.2537792968749932 -1.926125 -0.0679931640625 -0.2537792968749932 -1.92625 -0.0679931640625 -0.2537792968749932 -1.926375 -0.066864013671875 -0.2537792968749932 -1.9265 -0.066864013671875 -0.2537792968749932 -1.926625 -0.06573486328125 -0.2537792968749932 -1.92675 -0.064605712890625 -0.2537792968749932 -1.926875 -0.064605712890625 -0.2537792968749932 -1.927 -0.063446044921875 -0.2537792968749932 -1.927125 -0.063446044921875 -0.2537792968749932 -1.92725 -0.06231689453125 -0.2537792968749932 -1.927375 -0.061126708984375 -0.2537792968749932 -1.9275 -0.061126708984375 -0.2537792968749932 -1.927625 -0.059967041015625 -0.2537792968749932 -1.92775 -0.059967041015625 -0.2537792968749932 -1.927875 -0.058807373046875 -0.2537792968749932 -1.928 -0.0576171875 -0.2537792968749932 -1.928125 -0.0576171875 -0.2537792968749932 -1.92825 -0.056427001953125 -0.2537792968749932 -1.928375 -0.056427001953125 -0.2537792968749932 -1.9285 -0.05523681640625 -0.2537792968749932 -1.928625 -0.054046630859375 -0.2537792968749932 -1.92875 -0.054046630859375 -0.2537792968749932 -1.928875 -0.052825927734375 -0.2537792968749932 -1.929 -0.052825927734375 -0.2537792968749932 -1.929125 -0.0516357421875 -0.2537792968749932 -1.92925 -0.0504150390625 -0.2537792968749932 -1.929375 -0.0504150390625 -0.2537792968749932 -1.9295 -0.0491943359375 -0.2537792968749932 -1.929625 -0.0491943359375 -0.2537792968749932 -1.92975 -0.047943115234375 -0.2537792968749932 -1.929875 -0.046722412109375 -0.2537792968749932 -1.93 -0.046722412109375 -0.2537792968749932 -1.930125 -0.04547119140625 -0.2537792968749932 -1.93025 -0.04547119140625 -0.2537792968749932 -1.930375 -0.04425048828125 -0.2537792968749932 -1.9305 -0.042999267578125 -0.2537792968749932 -1.930625 -0.042999267578125 -0.2537792968749932 -1.93075 -0.041748046875 -0.2537792968749932 -1.930875 -0.041748046875 -0.2537792968749932 -1.931 -0.040496826171875 -0.2537792968749932 -1.931125 -0.039215087890625 -0.2537792968749932 -1.93125 -0.039215087890625 -0.2537792968749932 -1.931375 -0.0379638671875 -0.2537792968749932 -1.9315 -0.0379638671875 -0.2537792968749932 -1.931625 -0.03668212890625 -0.2537792968749932 -1.93175 -0.035400390625 -0.2537792968749932 -1.931875 -0.035400390625 -0.2537792968749932 -1.932 -0.034149169921875 -0.2537792968749932 -1.932125 -0.034149169921875 -0.2537792968749932 -1.93225 -0.032867431640625 -0.2537792968749932 -1.932375 -0.03155517578125 -0.2537792968749932 -1.9325 -0.03155517578125 -0.2537792968749932 -1.932625 -0.0302734375 -0.2537792968749932 -1.93275 -0.0302734375 -0.2537792968749932 -1.932875 -0.02899169921875 -0.2537792968749932 -1.933 -0.027679443359375 -0.2537792968749932 -1.933125 -0.027679443359375 -0.2537792968749932 -1.93325 -0.026397705078125 -0.2537792968749932 -1.933375 -0.026397705078125 -0.2537792968749932 -1.9335 -0.02508544921875 -0.2537792968749932 -1.933625 -0.023773193359375 -0.2537792968749932 -1.93375 -0.023773193359375 -0.2537792968749932 -1.933875 -0.022491455078125 -0.2537792968749932 -1.934 -0.022491455078125 -0.2537792968749932 -1.934125 -0.02117919921875 -0.2537792968749932 -1.93425 -0.019866943359375 -0.2537792968749932 -1.934375 -0.019866943359375 -0.2537792968749932 -1.9345 -0.0185546875 -0.2537792968749932 -1.934625 -0.0185546875 -0.2537792968749932 -1.93475 -0.017242431640625 -0.2537792968749932 -1.934875 -0.01593017578125 -0.2537792968749932 -1.935 -0.01593017578125 -0.2537792968749932 -1.935125 -0.01458740234375 -0.2537792968749932 -1.93525 -0.01458740234375 -0.2537792968749932 -1.935375 -0.013275146484375 -0.2537792968749932 -1.9355 -0.011962890625 -0.2537792968749932 -1.935625 -0.011962890625 -0.2537792968749932 -1.93575 -0.0106201171875 -0.2537792968749932 -1.935875 -0.0106201171875 -0.2537792968749932 -1.936 -0.009307861328125 -0.2537792968749932 -1.936125 -0.00799560546875 -0.2537792968749932 -1.93625 -0.00799560546875 -0.2537792968749932 -1.936375 -0.00665283203125 -0.2537792968749932 -1.9365 -0.00665283203125 -0.2537792968749932 -1.936625 -0.005340576171875 -0.2537792968749932 -1.93675 -0.003997802734375 -0.2537792968749932 -1.936875 -0.003997802734375 -0.2537792968749932 -1.937 -0.002685546875 -0.2537792968749932 -1.937125 -0.002685546875 -0.2537792968749932 -1.93725 -0.0013427734375 -0.2537792968749932 +1.875125 -0.003082275390625 -0.5893066406249988 +1.87525 -0.003082275390625 -0.5893066406249988 +1.875375 -0.00616455078125 -0.5893066406249988 +1.8755 -0.009246826171875 -0.5893066406249988 +1.875625 -0.009246826171875 -0.5893066406249988 +1.87575 -0.0123291015625 -0.5893066406249988 +1.875875 -0.0123291015625 -0.5893066406249988 +1.876 -0.015411376953125 -0.5893066406249988 +1.876125 -0.01849365234375 -0.5893066406249988 +1.87625 -0.01849365234375 -0.5893066406249988 +1.876375 -0.02154541015625 -0.5893066406249988 +1.8765 -0.02154541015625 -0.5893066406249988 +1.876625 -0.024627685546875 -0.5893066406249988 +1.87675 -0.0277099609375 -0.5893066406249988 +1.876875 -0.0277099609375 -0.5893066406249988 +1.877 -0.030792236328125 -0.5893066406249988 +1.877125 -0.030792236328125 -0.5893066406249988 +1.87725 -0.033843994140625 -0.5893066406249988 +1.877375 -0.036895751953125 -0.5893066406249988 +1.8775 -0.036895751953125 -0.5893066406249988 +1.877625 -0.03997802734375 -0.5893066406249988 +1.87775 -0.03997802734375 -0.5893066406249988 +1.877875 -0.04302978515625 -0.5893066406249988 +1.878 -0.04608154296875 -0.5893066406249988 +1.878125 -0.04608154296875 -0.5893066406249988 +1.87825 -0.049102783203125 -0.5893066406249988 +1.878375 -0.049102783203125 -0.5893066406249988 +1.8785 -0.052154541015625 -0.5893066406249988 +1.878625 -0.05517578125 -0.5893066406249988 +1.87875 -0.05517578125 -0.5893066406249988 +1.878875 -0.0582275390625 -0.5893066406249988 +1.879 -0.0582275390625 -0.5893066406249988 +1.879125 -0.061248779296875 -0.5893066406249988 +1.87925 -0.064239501953125 -0.5893066406249988 +1.879375 -0.064239501953125 -0.5893066406249988 +1.8795 -0.0672607421875 -0.5893066406249988 +1.879625 -0.0672607421875 -0.5893066406249988 +1.87975 -0.07025146484375 -0.5893066406249988 +1.879875 -0.0732421875 -0.5893066406249988 +1.88 -0.0732421875 -0.5893066406249988 +1.880125 -0.07623291015625 -0.5893066406249988 +1.88025 -0.07623291015625 -0.5893066406249988 +1.880375 -0.0792236328125 -0.5893066406249988 +1.8805 -0.082183837890625 -0.5893066406249988 +1.880625 -0.082183837890625 -0.5893066406249988 +1.88075 -0.08514404296875 -0.5893066406249988 +1.880875 -0.08514404296875 -0.5893066406249988 +1.881 -0.08807373046875 -0.5893066406249988 +1.881125 -0.091033935546875 -0.5893066406249988 +1.88125 -0.091033935546875 -0.5893066406249988 +1.881375 -0.093963623046875 -0.5893066406249988 +1.8815 -0.093963623046875 -0.5893066406249988 +1.881625 -0.09686279296875 -0.5893066406249988 +1.88175 -0.09979248046875 -0.5893066406249988 +1.881875 -0.09979248046875 -0.5893066406249988 +1.882 -0.102691650390625 -0.5893066406249988 +1.882125 -0.102691650390625 -0.5893066406249988 +1.88225 -0.105560302734375 -0.5893066406249988 +1.882375 -0.10845947265625 -0.5893066406249988 +1.8825 -0.10845947265625 -0.5893066406249988 +1.882625 -0.111297607421875 -0.5893066406249988 +1.88275 -0.111297607421875 -0.5893066406249988 +1.882875 -0.114166259765625 -0.5893066406249988 +1.883 -0.11700439453125 -0.5893066406249988 +1.883125 -0.11700439453125 -0.5893066406249988 +1.88325 -0.11981201171875 -0.5893066406249988 +1.883375 -0.11981201171875 -0.5893066406249988 +1.8835 -0.12261962890625 -0.5893066406249988 +1.883625 -0.12542724609375 -0.5893066406249988 +1.88375 -0.12542724609375 -0.5893066406249988 +1.883875 -0.128204345703125 -0.5893066406249988 +1.884 -0.128204345703125 -0.5893066406249988 +1.884125 -0.1309814453125 -0.5893066406249988 +1.88425 -0.13372802734375 -0.5893066406249988 +1.884375 -0.13372802734375 -0.5893066406249988 +1.8845 -0.136474609375 -0.5893066406249988 +1.884625 -0.136474609375 -0.5893066406249988 +1.88475 -0.13922119140625 -0.5893066406249988 +1.884875 -0.141937255859375 -0.5893066406249988 +1.885 -0.141937255859375 -0.5893066406249988 +1.885125 -0.144622802734375 -0.5893066406249988 +1.88525 -0.144622802734375 -0.5893066406249988 +1.885375 -0.147308349609375 -0.5893066406249988 +1.8855 -0.14996337890625 -0.5893066406249988 +1.885625 -0.14996337890625 -0.5893066406249988 +1.88575 -0.152618408203125 -0.5893066406249988 +1.885875 -0.152618408203125 -0.5893066406249988 +1.886 -0.155242919921875 -0.5893066406249988 +1.886125 -0.157867431640625 -0.5893066406249988 +1.88625 -0.157867431640625 -0.5893066406249988 +1.886375 -0.16046142578125 -0.5893066406249988 +1.8865 -0.16046142578125 -0.5893066406249988 +1.886625 -0.16302490234375 -0.5893066406249988 +1.88675 -0.16558837890625 -0.5893066406249988 +1.886875 -0.16558837890625 -0.5893066406249988 +1.887 -0.168121337890625 -0.5893066406249988 +1.887125 -0.168121337890625 -0.5893066406249988 +1.88725 -0.170654296875 -0.5893066406249988 +1.887375 -0.17315673828125 -0.5893066406249988 +1.8875 -0.17315673828125 -0.5893066406249988 +1.887625 -0.1756591796875 -0.5893066406249988 +1.88775 -0.1756591796875 -0.5893066406249988 +1.887875 -0.1781005859375 -0.5893066406249988 +1.888 -0.14569091796875 -0.4754394531249956 +1.888125 -0.14569091796875 -0.4754394531249956 +1.88825 -0.14764404296875 -0.4754394531249956 +1.888375 -0.14764404296875 -0.4754394531249956 +1.8885 -0.149566650390625 -0.4754394531249956 +1.888625 -0.1514892578125 -0.4754394531249956 +1.88875 -0.1514892578125 -0.4754394531249956 +1.888875 -0.153411865234375 -0.4754394531249956 +1.889 -0.153411865234375 -0.4754394531249956 +1.889125 -0.155303955078125 -0.4754394531249956 +1.88925 -0.157196044921875 -0.4754394531249956 +1.889375 -0.157196044921875 -0.4754394531249956 +1.8895 -0.159027099609375 -0.4754394531249956 +1.889625 -0.159027099609375 -0.4754394531249956 +1.88975 -0.160888671875 -0.4754394531249956 +1.889875 -0.162689208984375 -0.4754394531249956 +1.89 -0.162689208984375 -0.4754394531249956 +1.890125 -0.164520263671875 -0.4754394531249956 +1.89025 -0.164520263671875 -0.4754394531249956 +1.890375 -0.166290283203125 -0.4754394531249956 +1.8905 -0.168060302734375 -0.4754394531249956 +1.890625 -0.168060302734375 -0.4754394531249956 +1.89075 -0.169830322265625 -0.4754394531249956 +1.890875 -0.169830322265625 -0.4754394531249956 +1.891 -0.171539306640625 -0.4754394531249956 +1.891125 -0.17327880859375 -0.4754394531249956 +1.89125 -0.17327880859375 -0.4754394531249956 +1.891375 -0.174957275390625 -0.4754394531249956 +1.8915 -0.174957275390625 -0.4754394531249956 +1.891625 -0.1766357421875 -0.4754394531249956 +1.89175 -0.17828369140625 -0.4754394531249956 +1.891875 -0.17828369140625 -0.4754394531249956 +1.892 -0.179931640625 -0.4754394531249956 +1.892125 -0.179931640625 -0.4754394531249956 +1.89225 -0.181549072265625 -0.4754394531249956 +1.892375 -0.183135986328125 -0.4754394531249956 +1.8925 -0.183135986328125 -0.4754394531249956 +1.892625 -0.184722900390625 -0.4754394531249956 +1.89275 -0.184722900390625 -0.4754394531249956 +1.892875 -0.186279296875 -0.4754394531249956 +1.893 -0.18780517578125 -0.4754394531249956 +1.893125 -0.18780517578125 -0.4754394531249956 +1.89325 -0.1893310546875 -0.4754394531249956 +1.893375 -0.1893310546875 -0.4754394531249956 +1.8935 -0.190826416015625 -0.4754394531249956 +1.893625 -0.192291259765625 -0.4754394531249956 +1.89375 -0.192291259765625 -0.4754394531249956 +1.893875 -0.193756103515625 -0.4754394531249956 +1.894 -0.193756103515625 -0.4754394531249956 +1.894125 -0.1951904296875 -0.4754394531249956 +1.89425 -0.19659423828125 -0.4754394531249956 +1.894375 -0.19659423828125 -0.4754394531249956 +1.8945 -0.197967529296875 -0.4754394531249956 +1.894625 -0.197967529296875 -0.4754394531249956 +1.89475 -0.1993408203125 -0.4754394531249956 +1.894875 -0.20068359375 -0.4754394531249956 +1.895 -0.20068359375 -0.4754394531249956 +1.895125 -0.201995849609375 -0.4754394531249956 +1.89525 -0.201995849609375 -0.4754394531249956 +1.895375 -0.20330810546875 -0.4754394531249956 +1.8955 -0.20458984375 -0.4754394531249956 +1.895625 -0.20458984375 -0.4754394531249956 +1.89575 -0.205841064453125 -0.4754394531249956 +1.895875 -0.205841064453125 -0.4754394531249956 +1.896 -0.20709228515625 -0.4754394531249956 +1.896125 -0.208282470703125 -0.4754394531249956 +1.89625 -0.208282470703125 -0.4754394531249956 +1.896375 -0.20947265625 -0.4754394531249956 +1.8965 -0.20947265625 -0.4754394531249956 +1.896625 -0.21063232421875 -0.4754394531249956 +1.89675 -0.2117919921875 -0.4754394531249956 +1.896875 -0.2117919921875 -0.4754394531249956 +1.897 -0.212890625 -0.4754394531249956 +1.897125 -0.212890625 -0.4754394531249956 +1.89725 -0.2139892578125 -0.4754394531249956 +1.897375 -0.215057373046875 -0.4754394531249956 +1.8975 -0.215057373046875 -0.4754394531249956 +1.897625 -0.21612548828125 -0.4754394531249956 +1.89775 -0.21612548828125 -0.4754394531249956 +1.897875 -0.217132568359375 -0.4754394531249956 +1.898 -0.2181396484375 -0.4754394531249956 +1.898125 -0.2181396484375 -0.4754394531249956 +1.89825 -0.2191162109375 -0.4754394531249956 +1.898375 -0.2191162109375 -0.4754394531249956 +1.8985 -0.220062255859375 -0.4754394531249956 +1.898625 -0.22100830078125 -0.4754394531249956 +1.89875 -0.22100830078125 -0.4754394531249956 +1.898875 -0.221893310546875 -0.4754394531249956 +1.899 -0.221893310546875 -0.4754394531249956 +1.899125 -0.2227783203125 -0.4754394531249956 +1.89925 -0.2236328125 -0.4754394531249956 +1.899375 -0.2236328125 -0.4754394531249956 +1.8995 -0.224456787109375 -0.4754394531249956 +1.899625 -0.224456787109375 -0.4754394531249956 +1.89975 -0.22528076171875 -0.4754394531249956 +1.899875 -0.226043701171875 -0.4754394531249956 +1.9 -0.226043701171875 -0.4754394531249956 +1.900125 -0.226806640625 -0.4754394531249956 +1.90025 -0.226806640625 -0.4754394531249956 +1.900375 -0.2275390625 -0.4754394531249956 +1.9005 -0.228240966796875 -0.4754394531249956 +1.900625 -0.228240966796875 -0.4754394531249956 +1.90075 -0.22894287109375 -0.4754394531249956 +1.900875 -0.22894287109375 -0.4754394531249956 +1.901 -0.229583740234375 -0.4754394531249956 +1.901125 -0.230224609375 -0.4754394531249956 +1.90125 -0.230224609375 -0.4754394531249956 +1.901375 -0.2308349609375 -0.4754394531249956 +1.9015 -0.2308349609375 -0.4754394531249956 +1.901625 -0.231414794921875 -0.4754394531249956 +1.90175 -0.231964111328125 -0.4754394531249956 +1.901875 -0.231964111328125 -0.4754394531249956 +1.902 -0.23248291015625 -0.4754394531249956 +1.902125 -0.23248291015625 -0.4754394531249956 +1.90225 -0.233001708984375 -0.4754394531249956 +1.902375 -0.233489990234375 -0.4754394531249956 +1.9025 -0.233489990234375 -0.4754394531249956 +1.902625 -0.23394775390625 -0.4754394531249956 +1.90275 -0.23394775390625 -0.4754394531249956 +1.902875 -0.234375 -0.4754394531249956 +1.903 -0.234771728515625 -0.4754394531249956 +1.903125 -0.234771728515625 -0.4754394531249956 +1.90325 -0.235137939453125 -0.4754394531249956 +1.903375 -0.235137939453125 -0.4754394531249956 +1.9035 -0.2354736328125 -0.4754394531249956 +1.903625 -0.235809326171875 -0.4754394531249956 +1.90375 -0.235809326171875 -0.4754394531249956 +1.903875 -0.236114501953125 -0.4754394531249956 +1.904 -0.236114501953125 -0.4754394531249956 +1.904125 -0.23638916015625 -0.4754394531249956 +1.90425 -0.23663330078125 -0.4754394531249956 +1.904375 -0.23663330078125 -0.4754394531249956 +1.9045 -0.236846923828125 -0.4754394531249956 +1.904625 -0.236846923828125 -0.4754394531249956 +1.90475 -0.237060546875 -0.4754394531249956 +1.904875 -0.237213134765625 -0.4754394531249956 +1.905 -0.237213134765625 -0.4754394531249956 +1.905125 -0.23736572265625 -0.4754394531249956 +1.90525 -0.23736572265625 -0.4754394531249956 +1.905375 -0.23748779296875 -0.4754394531249956 +1.9055 -0.237579345703125 -0.4754394531249956 +1.905625 -0.237579345703125 -0.4754394531249956 +1.90575 -0.237640380859375 -0.4754394531249956 +1.905875 -0.237640380859375 -0.4754394531249956 +1.906 -0.2376708984375 -0.4754394531249956 +1.906125 -0.237701416015625 -0.4754394531249956 +1.90625 -0.237701416015625 -0.4754394531249956 +1.906375 -0.2376708984375 -0.4754394531249956 +1.9065 -0.2376708984375 -0.4754394531249956 +1.906625 -0.237640380859375 -0.4754394531249956 +1.90675 -0.237579345703125 -0.4754394531249956 +1.906875 -0.237579345703125 -0.4754394531249956 +1.907 -0.23748779296875 -0.4754394531249956 +1.907125 -0.23748779296875 -0.4754394531249956 +1.90725 -0.23736572265625 -0.4754394531249956 +1.907375 -0.237213134765625 -0.4754394531249956 +1.9075 -0.237213134765625 -0.4754394531249956 +1.907625 -0.237060546875 -0.4754394531249956 +1.90775 -0.237060546875 -0.4754394531249956 +1.907875 -0.236846923828125 -0.4754394531249956 +1.908 -0.23663330078125 -0.4754394531249956 +1.908125 -0.23663330078125 -0.4754394531249956 +1.90825 -0.23638916015625 -0.4754394531249956 +1.908375 -0.23638916015625 -0.4754394531249956 +1.9085 -0.236114501953125 -0.4754394531249956 +1.908625 -0.235809326171875 -0.4754394531249956 +1.90875 -0.235809326171875 -0.4754394531249956 +1.908875 -0.2354736328125 -0.4754394531249956 +1.909 -0.2354736328125 -0.4754394531249956 +1.909125 -0.235137939453125 -0.4754394531249956 +1.90925 -0.234771728515625 -0.4754394531249956 +1.909375 -0.234771728515625 -0.4754394531249956 +1.9095 -0.234375 -0.4754394531249956 +1.909625 -0.234375 -0.4754394531249956 +1.90975 -0.23394775390625 -0.4754394531249956 +1.909875 -0.233489990234375 -0.4754394531249956 +1.91 -0.233489990234375 -0.4754394531249956 +1.910125 -0.233001708984375 -0.4754394531249956 +1.91025 -0.233001708984375 -0.4754394531249956 +1.910375 -0.23248291015625 -0.4754394531249956 +1.9105 -0.231964111328125 -0.4754394531249956 +1.910625 -0.231964111328125 -0.4754394531249956 +1.91075 -0.231414794921875 -0.4754394531249956 +1.910875 -0.231414794921875 -0.4754394531249956 +1.911 -0.2308349609375 -0.4754394531249956 +1.911125 -0.230224609375 -0.4754394531249956 +1.91125 -0.230224609375 -0.4754394531249956 +1.911375 -0.229583740234375 -0.4754394531249956 +1.9115 -0.229583740234375 -0.4754394531249956 +1.911625 -0.22894287109375 -0.4754394531249956 +1.91175 -0.228240966796875 -0.4754394531249956 +1.911875 -0.228240966796875 -0.4754394531249956 +1.912 -0.2275390625 -0.4754394531249956 +1.912125 -0.2275390625 -0.4754394531249956 +1.91225 -0.226806640625 -0.4754394531249956 +1.912375 -0.226043701171875 -0.4754394531249956 +1.9125 -0.226043701171875 -0.4754394531249956 +1.912625 -0.22528076171875 -0.4754394531249956 +1.91275 -0.22528076171875 -0.4754394531249956 +1.912875 -0.224456787109375 -0.4754394531249956 +1.913 -0.2236328125 -0.4754394531249956 +1.913125 -0.2236328125 -0.4754394531249956 +1.91325 -0.2227783203125 -0.4754394531249956 +1.913375 -0.2227783203125 -0.4754394531249956 +1.9135 -0.221893310546875 -0.4754394531249956 +1.913625 -0.22100830078125 -0.4754394531249956 +1.91375 -0.22100830078125 -0.4754394531249956 +1.913875 -0.220062255859375 -0.4754394531249956 +1.914 -0.220062255859375 -0.4754394531249956 +1.914125 -0.2191162109375 -0.4754394531249956 +1.91425 -0.2181396484375 -0.4754394531249956 +1.914375 -0.2181396484375 -0.4754394531249956 +1.9145 -0.217132568359375 -0.4754394531249956 +1.914625 -0.217132568359375 -0.4754394531249956 +1.91475 -0.21612548828125 -0.4754394531249956 +1.914875 -0.215057373046875 -0.4754394531249956 +1.915 -0.215057373046875 -0.4754394531249956 +1.915125 -0.2139892578125 -0.4754394531249956 +1.91525 -0.2139892578125 -0.4754394531249956 +1.915375 -0.212890625 -0.4754394531249956 +1.9155 -0.2117919921875 -0.4754394531249956 +1.915625 -0.2117919921875 -0.4754394531249956 +1.91575 -0.21063232421875 -0.4754394531249956 +1.915875 -0.21063232421875 -0.4754394531249956 +1.916 -0.20947265625 -0.4754394531249956 +1.916125 -0.208282470703125 -0.4754394531249956 +1.91625 -0.208282470703125 -0.4754394531249956 +1.916375 -0.20709228515625 -0.4754394531249956 +1.9165 -0.20709228515625 -0.4754394531249956 +1.916625 -0.205841064453125 -0.4754394531249956 +1.91675 -0.20458984375 -0.4754394531249956 +1.916875 -0.20458984375 -0.4754394531249956 +1.917 -0.20330810546875 -0.4754394531249956 +1.917125 -0.20330810546875 -0.4754394531249956 +1.91725 -0.201995849609375 -0.4754394531249956 +1.917375 -0.20068359375 -0.4754394531249956 +1.9175 -0.20068359375 -0.4754394531249956 +1.917625 -0.1993408203125 -0.4754394531249956 +1.91775 -0.1993408203125 -0.4754394531249956 +1.917875 -0.197967529296875 -0.4754394531249956 +1.918 -0.19659423828125 -0.4754394531249956 +1.918125 -0.19659423828125 -0.4754394531249956 +1.91825 -0.1951904296875 -0.4754394531249956 +1.918375 -0.1951904296875 -0.4754394531249956 +1.9185 -0.193756103515625 -0.4754394531249956 +1.918625 -0.192291259765625 -0.4754394531249956 +1.91875 -0.192291259765625 -0.4754394531249956 +1.918875 -0.190826416015625 -0.4754394531249956 +1.919 -0.190826416015625 -0.4754394531249956 +1.919125 -0.1893310546875 -0.4754394531249956 +1.91925 -0.18780517578125 -0.4754394531249956 +1.919375 -0.18780517578125 -0.4754394531249956 +1.9195 -0.186279296875 -0.4754394531249956 +1.919625 -0.186279296875 -0.4754394531249956 +1.91975 -0.184722900390625 -0.4754394531249956 +1.919875 -0.183135986328125 -0.4754394531249956 +1.92 -0.097747802734375 -0.2537792968749932 +1.920125 -0.096893310546875 -0.2537792968749932 +1.92025 -0.096893310546875 -0.2537792968749932 +1.920375 -0.096038818359375 -0.2537792968749932 +1.9205 -0.09515380859375 -0.2537792968749932 +1.920625 -0.09515380859375 -0.2537792968749932 +1.92075 -0.094268798828125 -0.2537792968749932 +1.920875 -0.094268798828125 -0.2537792968749932 +1.921 -0.0933837890625 -0.2537792968749932 +1.921125 -0.09246826171875 -0.2537792968749932 +1.92125 -0.09246826171875 -0.2537792968749932 +1.921375 -0.091552734375 -0.2537792968749932 +1.9215 -0.091552734375 -0.2537792968749932 +1.921625 -0.09063720703125 -0.2537792968749932 +1.92175 -0.089691162109375 -0.2537792968749932 +1.921875 -0.089691162109375 -0.2537792968749932 +1.922 -0.088775634765625 -0.2537792968749932 +1.922125 -0.088775634765625 -0.2537792968749932 +1.92225 -0.087799072265625 -0.2537792968749932 +1.922375 -0.08685302734375 -0.2537792968749932 +1.9225 -0.08685302734375 -0.2537792968749932 +1.922625 -0.08587646484375 -0.2537792968749932 +1.92275 -0.08587646484375 -0.2537792968749932 +1.922875 -0.08489990234375 -0.2537792968749932 +1.923 -0.083892822265625 -0.2537792968749932 +1.923125 -0.083892822265625 -0.2537792968749932 +1.92325 -0.0828857421875 -0.2537792968749932 +1.923375 -0.0828857421875 -0.2537792968749932 +1.9235 -0.081878662109375 -0.2537792968749932 +1.923625 -0.08087158203125 -0.2537792968749932 +1.92375 -0.08087158203125 -0.2537792968749932 +1.923875 -0.079833984375 -0.2537792968749932 +1.924 -0.079833984375 -0.2537792968749932 +1.924125 -0.07879638671875 -0.2537792968749932 +1.92425 -0.0777587890625 -0.2537792968749932 +1.924375 -0.0777587890625 -0.2537792968749932 +1.9245 -0.076690673828125 -0.2537792968749932 +1.924625 -0.076690673828125 -0.2537792968749932 +1.92475 -0.07562255859375 -0.2537792968749932 +1.924875 -0.074554443359375 -0.2537792968749932 +1.925 -0.074554443359375 -0.2537792968749932 +1.925125 -0.073486328125 -0.2537792968749932 +1.92525 -0.073486328125 -0.2537792968749932 +1.925375 -0.0723876953125 -0.2537792968749932 +1.9255 -0.0712890625 -0.2537792968749932 +1.925625 -0.0712890625 -0.2537792968749932 +1.92575 -0.0701904296875 -0.2537792968749932 +1.925875 -0.0701904296875 -0.2537792968749932 +1.926 -0.069091796875 -0.2537792968749932 +1.926125 -0.067962646484375 -0.2537792968749932 +1.92625 -0.067962646484375 -0.2537792968749932 +1.926375 -0.06683349609375 -0.2537792968749932 +1.9265 -0.06683349609375 -0.2537792968749932 +1.926625 -0.065704345703125 -0.2537792968749932 +1.92675 -0.0645751953125 -0.2537792968749932 +1.926875 -0.0645751953125 -0.2537792968749932 +1.927 -0.06341552734375 -0.2537792968749932 +1.927125 -0.06341552734375 -0.2537792968749932 +1.92725 -0.062286376953125 -0.2537792968749932 +1.927375 -0.06109619140625 -0.2537792968749932 +1.9275 -0.06109619140625 -0.2537792968749932 +1.927625 -0.0599365234375 -0.2537792968749932 +1.92775 -0.0599365234375 -0.2537792968749932 +1.927875 -0.05877685546875 -0.2537792968749932 +1.928 -0.057586669921875 -0.2537792968749932 +1.928125 -0.057586669921875 -0.2537792968749932 +1.92825 -0.056396484375 -0.2537792968749932 +1.928375 -0.056396484375 -0.2537792968749932 +1.9285 -0.055206298828125 -0.2537792968749932 +1.928625 -0.05401611328125 -0.2537792968749932 +1.92875 -0.05401611328125 -0.2537792968749932 +1.928875 -0.05279541015625 -0.2537792968749932 +1.929 -0.05279541015625 -0.2537792968749932 +1.929125 -0.051605224609375 -0.2537792968749932 +1.92925 -0.050384521484375 -0.2537792968749932 +1.929375 -0.050384521484375 -0.2537792968749932 +1.9295 -0.049163818359375 -0.2537792968749932 +1.929625 -0.049163818359375 -0.2537792968749932 +1.92975 -0.04791259765625 -0.2537792968749932 +1.929875 -0.04669189453125 -0.2537792968749932 +1.93 -0.04669189453125 -0.2537792968749932 +1.930125 -0.045440673828125 -0.2537792968749932 +1.93025 -0.045440673828125 -0.2537792968749932 +1.930375 -0.044219970703125 -0.2537792968749932 +1.9305 -0.04296875 -0.2537792968749932 +1.930625 -0.04296875 -0.2537792968749932 +1.93075 -0.041717529296875 -0.2537792968749932 +1.930875 -0.041717529296875 -0.2537792968749932 +1.931 -0.04046630859375 -0.2537792968749932 +1.931125 -0.0391845703125 -0.2537792968749932 +1.93125 -0.0391845703125 -0.2537792968749932 +1.931375 -0.037933349609375 -0.2537792968749932 +1.9315 -0.037933349609375 -0.2537792968749932 +1.931625 -0.036651611328125 -0.2537792968749932 +1.93175 -0.035369873046875 -0.2537792968749932 +1.931875 -0.035369873046875 -0.2537792968749932 +1.932 -0.03411865234375 -0.2537792968749932 +1.932125 -0.03411865234375 -0.2537792968749932 +1.93225 -0.0328369140625 -0.2537792968749932 +1.932375 -0.031524658203125 -0.2537792968749932 +1.9325 -0.031524658203125 -0.2537792968749932 +1.932625 -0.030242919921875 -0.2537792968749932 +1.93275 -0.030242919921875 -0.2537792968749932 +1.932875 -0.028961181640625 -0.2537792968749932 +1.933 -0.02764892578125 -0.2537792968749932 +1.933125 -0.02764892578125 -0.2537792968749932 +1.93325 -0.0263671875 -0.2537792968749932 +1.933375 -0.0263671875 -0.2537792968749932 +1.9335 -0.025054931640625 -0.2537792968749932 +1.933625 -0.02374267578125 -0.2537792968749932 +1.93375 -0.02374267578125 -0.2537792968749932 +1.933875 -0.0224609375 -0.2537792968749932 +1.934 -0.0224609375 -0.2537792968749932 +1.934125 -0.021148681640625 -0.2537792968749932 +1.93425 -0.01983642578125 -0.2537792968749932 +1.934375 -0.01983642578125 -0.2537792968749932 +1.9345 -0.018524169921875 -0.2537792968749932 +1.934625 -0.018524169921875 -0.2537792968749932 +1.93475 -0.0172119140625 -0.2537792968749932 +1.934875 -0.015899658203125 -0.2537792968749932 +1.935 -0.015899658203125 -0.2537792968749932 +1.935125 -0.014556884765625 -0.2537792968749932 +1.93525 -0.014556884765625 -0.2537792968749932 +1.935375 -0.01324462890625 -0.2537792968749932 +1.9355 -0.011932373046875 -0.2537792968749932 +1.935625 -0.011932373046875 -0.2537792968749932 +1.93575 -0.010589599609375 -0.2537792968749932 +1.935875 -0.010589599609375 -0.2537792968749932 +1.936 -0.00927734375 -0.2537792968749932 +1.936125 -0.007965087890625 -0.2537792968749932 +1.93625 -0.007965087890625 -0.2537792968749932 +1.936375 -0.006622314453125 -0.2537792968749932 +1.9365 -0.006622314453125 -0.2537792968749932 +1.936625 -0.00531005859375 -0.2537792968749932 +1.93675 -0.00396728515625 -0.2537792968749932 +1.936875 -0.00396728515625 -0.2537792968749932 +1.937 -0.002655029296875 -0.2537792968749932 +1.937125 -0.002655029296875 -0.2537792968749932 +1.93725 -0.001312255859375 -0.2537792968749932 1.937375 0.0 -0.2537792968749932 1.9375 0.0 -0.2537792968749932 1.937625 0.001312255859375 -0.2537792968749932 @@ -15614,389 +15614,389 @@ 1.951625 0.0828857421875 -0.2537792968749932 1.95175 0.083892822265625 -0.2537792968749932 1.951875 0.083892822265625 -0.2537792968749932 -1.952 -0.013458251953125 0.04025390625000896 -1.952125 -0.013458251953125 0.04025390625000896 -1.95225 -0.013641357421875 0.04025390625000896 -1.952375 -0.0137939453125 0.04025390625000896 -1.9525 -0.0137939453125 0.04025390625000896 -1.952625 -0.013946533203125 0.04025390625000896 -1.95275 -0.013946533203125 0.04025390625000896 -1.952875 -0.01409912109375 0.04025390625000896 -1.953 -0.01422119140625 0.04025390625000896 -1.953125 -0.01422119140625 0.04025390625000896 -1.95325 -0.014373779296875 0.04025390625000896 -1.953375 -0.014373779296875 0.04025390625000896 -1.9535 -0.0145263671875 0.04025390625000896 -1.953625 -0.014678955078125 0.04025390625000896 -1.95375 -0.014678955078125 0.04025390625000896 -1.953875 -0.01483154296875 0.04025390625000896 -1.954 -0.01483154296875 0.04025390625000896 -1.954125 -0.01495361328125 0.04025390625000896 -1.95425 -0.015106201171875 0.04025390625000896 -1.954375 -0.015106201171875 0.04025390625000896 -1.9545 -0.015228271484375 0.04025390625000896 -1.954625 -0.015228271484375 0.04025390625000896 -1.95475 -0.015380859375 0.04025390625000896 -1.954875 -0.0155029296875 0.04025390625000896 -1.955 -0.0155029296875 0.04025390625000896 -1.955125 -0.015655517578125 0.04025390625000896 -1.95525 -0.015655517578125 0.04025390625000896 -1.955375 -0.015777587890625 0.04025390625000896 -1.9555 -0.015899658203125 0.04025390625000896 -1.955625 -0.015899658203125 0.04025390625000896 -1.95575 -0.016021728515625 0.04025390625000896 -1.955875 -0.016021728515625 0.04025390625000896 -1.956 -0.01617431640625 0.04025390625000896 -1.956125 -0.01629638671875 0.04025390625000896 -1.95625 -0.01629638671875 0.04025390625000896 -1.956375 -0.01641845703125 0.04025390625000896 -1.9565 -0.01641845703125 0.04025390625000896 -1.956625 -0.01654052734375 0.04025390625000896 -1.95675 -0.01666259765625 0.04025390625000896 -1.956875 -0.01666259765625 0.04025390625000896 -1.957 -0.016754150390625 0.04025390625000896 -1.957125 -0.016754150390625 0.04025390625000896 -1.95725 -0.016876220703125 0.04025390625000896 -1.957375 -0.016998291015625 0.04025390625000896 -1.9575 -0.016998291015625 0.04025390625000896 -1.957625 -0.017120361328125 0.04025390625000896 -1.95775 -0.017120361328125 0.04025390625000896 -1.957875 -0.0172119140625 0.04025390625000896 -1.958 -0.017333984375 0.04025390625000896 -1.958125 -0.017333984375 0.04025390625000896 -1.95825 -0.017425537109375 0.04025390625000896 -1.958375 -0.017425537109375 0.04025390625000896 -1.9585 -0.017547607421875 0.04025390625000896 -1.958625 -0.01763916015625 0.04025390625000896 -1.95875 -0.01763916015625 0.04025390625000896 -1.958875 -0.017730712890625 0.04025390625000896 -1.959 -0.017730712890625 0.04025390625000896 -1.959125 -0.017822265625 0.04025390625000896 -1.95925 -0.0179443359375 0.04025390625000896 -1.959375 -0.0179443359375 0.04025390625000896 -1.9595 -0.018035888671875 0.04025390625000896 -1.959625 -0.018035888671875 0.04025390625000896 -1.95975 -0.01812744140625 0.04025390625000896 -1.959875 -0.018218994140625 0.04025390625000896 -1.96 -0.018218994140625 0.04025390625000896 -1.960125 -0.018310546875 0.04025390625000896 -1.96025 -0.018310546875 0.04025390625000896 -1.960375 -0.018402099609375 0.04025390625000896 -1.9605 -0.018463134765625 0.04025390625000896 -1.960625 -0.018463134765625 0.04025390625000896 -1.96075 -0.0185546875 0.04025390625000896 -1.960875 -0.0185546875 0.04025390625000896 -1.961 -0.018646240234375 0.04025390625000896 -1.961125 -0.018707275390625 0.04025390625000896 -1.96125 -0.018707275390625 0.04025390625000896 -1.961375 -0.018798828125 0.04025390625000896 -1.9615 -0.018798828125 0.04025390625000896 -1.961625 -0.01885986328125 0.04025390625000896 -1.96175 -0.018951416015625 0.04025390625000896 -1.961875 -0.018951416015625 0.04025390625000896 -1.962 -0.019012451171875 0.04025390625000896 -1.962125 -0.019012451171875 0.04025390625000896 -1.96225 -0.019073486328125 0.04025390625000896 -1.962375 -0.019134521484375 0.04025390625000896 -1.9625 -0.019134521484375 0.04025390625000896 -1.962625 -0.019195556640625 0.04025390625000896 -1.96275 -0.019195556640625 0.04025390625000896 -1.962875 -0.019256591796875 0.04025390625000896 -1.963 -0.019317626953125 0.04025390625000896 -1.963125 -0.019317626953125 0.04025390625000896 -1.96325 -0.019378662109375 0.04025390625000896 -1.963375 -0.019378662109375 0.04025390625000896 -1.9635 -0.019439697265625 0.04025390625000896 -1.963625 -0.019500732421875 0.04025390625000896 -1.96375 -0.019500732421875 0.04025390625000896 -1.963875 -0.01953125 0.04025390625000896 -1.964 -0.01953125 0.04025390625000896 -1.964125 -0.01959228515625 0.04025390625000896 -1.96425 -0.0196533203125 0.04025390625000896 -1.964375 -0.0196533203125 0.04025390625000896 -1.9645 -0.019683837890625 0.04025390625000896 -1.964625 -0.019683837890625 0.04025390625000896 -1.96475 -0.01971435546875 0.04025390625000896 -1.964875 -0.019775390625 0.04025390625000896 -1.965 -0.019775390625 0.04025390625000896 -1.965125 -0.019805908203125 0.04025390625000896 -1.96525 -0.019805908203125 0.04025390625000896 -1.965375 -0.01983642578125 0.04025390625000896 -1.9655 -0.019866943359375 0.04025390625000896 -1.965625 -0.019866943359375 0.04025390625000896 -1.96575 -0.0198974609375 0.04025390625000896 -1.965875 -0.0198974609375 0.04025390625000896 -1.966 -0.019927978515625 0.04025390625000896 -1.966125 -0.01995849609375 0.04025390625000896 -1.96625 -0.01995849609375 0.04025390625000896 -1.966375 -0.019989013671875 0.04025390625000896 -1.9665 -0.019989013671875 0.04025390625000896 -1.966625 -0.02001953125 0.04025390625000896 -1.96675 -0.020050048828125 0.04025390625000896 -1.966875 -0.020050048828125 0.04025390625000896 -1.967 -0.020050048828125 0.04025390625000896 -1.967125 -0.020050048828125 0.04025390625000896 -1.96725 -0.02008056640625 0.04025390625000896 -1.967375 -0.02008056640625 0.04025390625000896 -1.9675 -0.02008056640625 0.04025390625000896 -1.967625 -0.020111083984375 0.04025390625000896 -1.96775 -0.020111083984375 0.04025390625000896 -1.967875 -0.020111083984375 0.04025390625000896 -1.968 -0.020111083984375 0.04025390625000896 -1.968125 -0.020111083984375 0.04025390625000896 -1.96825 -0.020111083984375 0.04025390625000896 -1.968375 -0.020111083984375 0.04025390625000896 -1.9685 -0.020111083984375 0.04025390625000896 -1.968625 -0.020111083984375 0.04025390625000896 -1.96875 -0.020111083984375 0.04025390625000896 -1.968875 -0.020111083984375 0.04025390625000896 -1.969 -0.020111083984375 0.04025390625000896 -1.969125 -0.020111083984375 0.04025390625000896 -1.96925 -0.020111083984375 0.04025390625000896 -1.969375 -0.020111083984375 0.04025390625000896 -1.9695 -0.020111083984375 0.04025390625000896 -1.969625 -0.020111083984375 0.04025390625000896 -1.96975 -0.020111083984375 0.04025390625000896 -1.969875 -0.02008056640625 0.04025390625000896 -1.97 -0.02008056640625 0.04025390625000896 -1.970125 -0.02008056640625 0.04025390625000896 -1.97025 -0.02008056640625 0.04025390625000896 -1.970375 -0.020050048828125 0.04025390625000896 -1.9705 -0.020050048828125 0.04025390625000896 -1.970625 -0.020050048828125 0.04025390625000896 -1.97075 -0.02001953125 0.04025390625000896 -1.970875 -0.02001953125 0.04025390625000896 -1.971 -0.019989013671875 0.04025390625000896 -1.971125 -0.01995849609375 0.04025390625000896 -1.97125 -0.01995849609375 0.04025390625000896 -1.971375 -0.019927978515625 0.04025390625000896 -1.9715 -0.019927978515625 0.04025390625000896 -1.971625 -0.0198974609375 0.04025390625000896 -1.97175 -0.019866943359375 0.04025390625000896 -1.971875 -0.019866943359375 0.04025390625000896 -1.972 -0.01983642578125 0.04025390625000896 -1.972125 -0.01983642578125 0.04025390625000896 -1.97225 -0.019805908203125 0.04025390625000896 -1.972375 -0.019775390625 0.04025390625000896 -1.9725 -0.019775390625 0.04025390625000896 -1.972625 -0.01971435546875 0.04025390625000896 -1.97275 -0.01971435546875 0.04025390625000896 -1.972875 -0.019683837890625 0.04025390625000896 -1.973 -0.0196533203125 0.04025390625000896 -1.973125 -0.0196533203125 0.04025390625000896 -1.97325 -0.01959228515625 0.04025390625000896 -1.973375 -0.01959228515625 0.04025390625000896 -1.9735 -0.01953125 0.04025390625000896 -1.973625 -0.019500732421875 0.04025390625000896 -1.97375 -0.019500732421875 0.04025390625000896 -1.973875 -0.019439697265625 0.04025390625000896 -1.974 -0.019439697265625 0.04025390625000896 -1.974125 -0.019378662109375 0.04025390625000896 -1.97425 -0.019317626953125 0.04025390625000896 -1.974375 -0.019317626953125 0.04025390625000896 -1.9745 -0.019256591796875 0.04025390625000896 -1.974625 -0.019256591796875 0.04025390625000896 -1.97475 -0.019195556640625 0.04025390625000896 -1.974875 -0.019134521484375 0.04025390625000896 -1.975 -0.019134521484375 0.04025390625000896 -1.975125 -0.019073486328125 0.04025390625000896 -1.97525 -0.019073486328125 0.04025390625000896 -1.975375 -0.019012451171875 0.04025390625000896 -1.9755 -0.018951416015625 0.04025390625000896 -1.975625 -0.018951416015625 0.04025390625000896 -1.97575 -0.01885986328125 0.04025390625000896 -1.975875 -0.01885986328125 0.04025390625000896 -1.976 -0.018798828125 0.04025390625000896 -1.976125 -0.018707275390625 0.04025390625000896 -1.97625 -0.018707275390625 0.04025390625000896 -1.976375 -0.018646240234375 0.04025390625000896 -1.9765 -0.018646240234375 0.04025390625000896 -1.976625 -0.0185546875 0.04025390625000896 -1.97675 -0.018463134765625 0.04025390625000896 -1.976875 -0.018463134765625 0.04025390625000896 -1.977 -0.018402099609375 0.04025390625000896 -1.977125 -0.018402099609375 0.04025390625000896 -1.97725 -0.018310546875 0.04025390625000896 -1.977375 -0.018218994140625 0.04025390625000896 -1.9775 -0.018218994140625 0.04025390625000896 -1.977625 -0.01812744140625 0.04025390625000896 -1.97775 -0.01812744140625 0.04025390625000896 -1.977875 -0.018035888671875 0.04025390625000896 -1.978 -0.0179443359375 0.04025390625000896 -1.978125 -0.0179443359375 0.04025390625000896 -1.97825 -0.017822265625 0.04025390625000896 -1.978375 -0.017822265625 0.04025390625000896 -1.9785 -0.017730712890625 0.04025390625000896 -1.978625 -0.01763916015625 0.04025390625000896 -1.97875 -0.01763916015625 0.04025390625000896 -1.978875 -0.017547607421875 0.04025390625000896 -1.979 -0.017547607421875 0.04025390625000896 -1.979125 -0.017425537109375 0.04025390625000896 -1.97925 -0.017333984375 0.04025390625000896 -1.979375 -0.017333984375 0.04025390625000896 -1.9795 -0.0172119140625 0.04025390625000896 -1.979625 -0.0172119140625 0.04025390625000896 -1.97975 -0.017120361328125 0.04025390625000896 -1.979875 -0.016998291015625 0.04025390625000896 -1.98 -0.016998291015625 0.04025390625000896 -1.980125 -0.016876220703125 0.04025390625000896 -1.98025 -0.016876220703125 0.04025390625000896 -1.980375 -0.016754150390625 0.04025390625000896 -1.9805 -0.01666259765625 0.04025390625000896 -1.980625 -0.01666259765625 0.04025390625000896 -1.98075 -0.01654052734375 0.04025390625000896 -1.980875 -0.01654052734375 0.04025390625000896 -1.981 -0.01641845703125 0.04025390625000896 -1.981125 -0.01629638671875 0.04025390625000896 -1.98125 -0.01629638671875 0.04025390625000896 -1.981375 -0.01617431640625 0.04025390625000896 -1.9815 -0.01617431640625 0.04025390625000896 -1.981625 -0.016021728515625 0.04025390625000896 -1.98175 -0.015899658203125 0.04025390625000896 -1.981875 -0.015899658203125 0.04025390625000896 -1.982 -0.015777587890625 0.04025390625000896 -1.982125 -0.015777587890625 0.04025390625000896 -1.98225 -0.015655517578125 0.04025390625000896 -1.982375 -0.0155029296875 0.04025390625000896 -1.9825 -0.0155029296875 0.04025390625000896 -1.982625 -0.015380859375 0.04025390625000896 -1.98275 -0.015380859375 0.04025390625000896 -1.982875 -0.015228271484375 0.04025390625000896 -1.983 -0.015106201171875 0.04025390625000896 -1.983125 -0.015106201171875 0.04025390625000896 -1.98325 -0.01495361328125 0.04025390625000896 -1.983375 -0.01495361328125 0.04025390625000896 -1.9835 -0.01483154296875 0.04025390625000896 -1.983625 -0.014678955078125 0.04025390625000896 -1.98375 -0.014678955078125 0.04025390625000896 -1.983875 -0.0145263671875 0.04025390625000896 -1.984 -0.12982177734375 0.3597460937500089 -1.984125 -0.128509521484375 0.3597460937500089 -1.98425 -0.127197265625 0.3597460937500089 -1.984375 -0.127197265625 0.3597460937500089 -1.9845 -0.1258544921875 0.3597460937500089 -1.984625 -0.1258544921875 0.3597460937500089 -1.98475 -0.124481201171875 0.3597460937500089 -1.984875 -0.123138427734375 0.3597460937500089 -1.985 -0.123138427734375 0.3597460937500089 -1.985125 -0.12176513671875 0.3597460937500089 -1.98525 -0.12176513671875 0.3597460937500089 -1.985375 -0.120361328125 0.3597460937500089 -1.9855 -0.11895751953125 0.3597460937500089 -1.985625 -0.11895751953125 0.3597460937500089 -1.98575 -0.117523193359375 0.3597460937500089 -1.985875 -0.117523193359375 0.3597460937500089 -1.986 -0.1160888671875 0.3597460937500089 -1.986125 -0.114654541015625 0.3597460937500089 -1.98625 -0.114654541015625 0.3597460937500089 -1.986375 -0.113189697265625 0.3597460937500089 -1.9865 -0.113189697265625 0.3597460937500089 -1.986625 -0.111724853515625 0.3597460937500089 -1.98675 -0.110260009765625 0.3597460937500089 -1.986875 -0.110260009765625 0.3597460937500089 -1.987 -0.108734130859375 0.3597460937500089 -1.987125 -0.108734130859375 0.3597460937500089 -1.98725 -0.10723876953125 0.3597460937500089 -1.987375 -0.105712890625 0.3597460937500089 -1.9875 -0.105712890625 0.3597460937500089 -1.987625 -0.10418701171875 0.3597460937500089 -1.98775 -0.10418701171875 0.3597460937500089 -1.987875 -0.1026611328125 0.3597460937500089 -1.988 -0.101104736328125 0.3597460937500089 -1.988125 -0.101104736328125 0.3597460937500089 -1.98825 -0.09954833984375 0.3597460937500089 -1.988375 -0.09954833984375 0.3597460937500089 -1.9885 -0.09796142578125 0.3597460937500089 -1.988625 -0.09637451171875 0.3597460937500089 -1.98875 -0.09637451171875 0.3597460937500089 -1.988875 -0.09478759765625 0.3597460937500089 -1.989 -0.09478759765625 0.3597460937500089 -1.989125 -0.093170166015625 0.3597460937500089 -1.98925 -0.091552734375 0.3597460937500089 -1.989375 -0.091552734375 0.3597460937500089 -1.9895 -0.089935302734375 0.3597460937500089 -1.989625 -0.089935302734375 0.3597460937500089 -1.98975 -0.088287353515625 0.3597460937500089 -1.989875 -0.086669921875 0.3597460937500089 -1.99 -0.086669921875 0.3597460937500089 -1.990125 -0.084991455078125 0.3597460937500089 -1.99025 -0.084991455078125 0.3597460937500089 -1.990375 -0.083343505859375 0.3597460937500089 -1.9905 -0.0816650390625 0.3597460937500089 -1.990625 -0.0816650390625 0.3597460937500089 -1.99075 -0.079986572265625 0.3597460937500089 -1.990875 -0.079986572265625 0.3597460937500089 -1.991 -0.078277587890625 0.3597460937500089 -1.991125 -0.07659912109375 0.3597460937500089 -1.99125 -0.07659912109375 0.3597460937500089 -1.991375 -0.07489013671875 0.3597460937500089 -1.9915 -0.07489013671875 0.3597460937500089 -1.991625 -0.073150634765625 0.3597460937500089 -1.99175 -0.071441650390625 0.3597460937500089 -1.991875 -0.071441650390625 0.3597460937500089 -1.992 -0.0697021484375 0.3597460937500089 -1.992125 -0.0697021484375 0.3597460937500089 -1.99225 -0.067962646484375 0.3597460937500089 -1.992375 -0.06622314453125 0.3597460937500089 -1.9925 -0.06622314453125 0.3597460937500089 -1.992625 -0.064453125 0.3597460937500089 -1.99275 -0.064453125 0.3597460937500089 -1.992875 -0.062713623046875 0.3597460937500089 -1.993 -0.060943603515625 0.3597460937500089 -1.993125 -0.060943603515625 0.3597460937500089 -1.99325 -0.05914306640625 0.3597460937500089 -1.993375 -0.05914306640625 0.3597460937500089 -1.9935 -0.057373046875 0.3597460937500089 -1.993625 -0.05560302734375 0.3597460937500089 -1.99375 -0.05560302734375 0.3597460937500089 -1.993875 -0.053802490234375 0.3597460937500089 -1.994 -0.053802490234375 0.3597460937500089 -1.994125 -0.052001953125 0.3597460937500089 -1.99425 -0.050201416015625 0.3597460937500089 -1.994375 -0.050201416015625 0.3597460937500089 -1.9945 -0.048370361328125 0.3597460937500089 -1.994625 -0.048370361328125 0.3597460937500089 -1.99475 -0.04656982421875 0.3597460937500089 -1.994875 -0.04473876953125 0.3597460937500089 -1.995 -0.04473876953125 0.3597460937500089 -1.995125 -0.04290771484375 0.3597460937500089 -1.99525 -0.04290771484375 0.3597460937500089 -1.995375 -0.04107666015625 0.3597460937500089 -1.9955 -0.03924560546875 0.3597460937500089 -1.995625 -0.03924560546875 0.3597460937500089 -1.99575 -0.03741455078125 0.3597460937500089 -1.995875 -0.03741455078125 0.3597460937500089 -1.996 -0.035552978515625 0.3597460937500089 -1.996125 -0.033721923828125 0.3597460937500089 -1.99625 -0.033721923828125 0.3597460937500089 -1.996375 -0.0318603515625 0.3597460937500089 -1.9965 -0.0318603515625 0.3597460937500089 -1.996625 -0.029998779296875 0.3597460937500089 -1.99675 -0.02813720703125 0.3597460937500089 -1.996875 -0.02813720703125 0.3597460937500089 -1.997 -0.026275634765625 0.3597460937500089 -1.997125 -0.026275634765625 0.3597460937500089 -1.99725 -0.0244140625 0.3597460937500089 -1.997375 -0.022552490234375 0.3597460937500089 -1.9975 -0.022552490234375 0.3597460937500089 -1.997625 -0.02069091796875 0.3597460937500089 -1.99775 -0.02069091796875 0.3597460937500089 -1.997875 -0.018829345703125 0.3597460937500089 -1.998 -0.016937255859375 0.3597460937500089 -1.998125 -0.016937255859375 0.3597460937500089 -1.99825 -0.015045166015625 0.3597460937500089 -1.998375 -0.015045166015625 0.3597460937500089 -1.9985 -0.01318359375 0.3597460937500089 -1.998625 -0.01129150390625 0.3597460937500089 -1.99875 -0.01129150390625 0.3597460937500089 -1.998875 -0.009429931640625 0.3597460937500089 -1.999 -0.009429931640625 0.3597460937500089 -1.999125 -0.007537841796875 0.3597460937500089 -1.99925 -0.00567626953125 0.3597460937500089 -1.999375 -0.00567626953125 0.3597460937500089 -1.9995 -0.0037841796875 0.3597460937500089 -1.999625 -0.0037841796875 0.3597460937500089 -1.99975 -0.00189208984375 0.3597460937500089 +1.952 -0.013427734375 0.04025390625000896 +1.952125 -0.013427734375 0.04025390625000896 +1.95225 -0.01361083984375 0.04025390625000896 +1.952375 -0.013763427734375 0.04025390625000896 +1.9525 -0.013763427734375 0.04025390625000896 +1.952625 -0.013916015625 0.04025390625000896 +1.95275 -0.013916015625 0.04025390625000896 +1.952875 -0.014068603515625 0.04025390625000896 +1.953 -0.014190673828125 0.04025390625000896 +1.953125 -0.014190673828125 0.04025390625000896 +1.95325 -0.01434326171875 0.04025390625000896 +1.953375 -0.01434326171875 0.04025390625000896 +1.9535 -0.014495849609375 0.04025390625000896 +1.953625 -0.0146484375 0.04025390625000896 +1.95375 -0.0146484375 0.04025390625000896 +1.953875 -0.014801025390625 0.04025390625000896 +1.954 -0.014801025390625 0.04025390625000896 +1.954125 -0.014923095703125 0.04025390625000896 +1.95425 -0.01507568359375 0.04025390625000896 +1.954375 -0.01507568359375 0.04025390625000896 +1.9545 -0.01519775390625 0.04025390625000896 +1.954625 -0.01519775390625 0.04025390625000896 +1.95475 -0.015350341796875 0.04025390625000896 +1.954875 -0.015472412109375 0.04025390625000896 +1.955 -0.015472412109375 0.04025390625000896 +1.955125 -0.015625 0.04025390625000896 +1.95525 -0.015625 0.04025390625000896 +1.955375 -0.0157470703125 0.04025390625000896 +1.9555 -0.015869140625 0.04025390625000896 +1.955625 -0.015869140625 0.04025390625000896 +1.95575 -0.0159912109375 0.04025390625000896 +1.955875 -0.0159912109375 0.04025390625000896 +1.956 -0.016143798828125 0.04025390625000896 +1.956125 -0.016265869140625 0.04025390625000896 +1.95625 -0.016265869140625 0.04025390625000896 +1.956375 -0.016387939453125 0.04025390625000896 +1.9565 -0.016387939453125 0.04025390625000896 +1.956625 -0.016510009765625 0.04025390625000896 +1.95675 -0.016632080078125 0.04025390625000896 +1.956875 -0.016632080078125 0.04025390625000896 +1.957 -0.0167236328125 0.04025390625000896 +1.957125 -0.0167236328125 0.04025390625000896 +1.95725 -0.016845703125 0.04025390625000896 +1.957375 -0.0169677734375 0.04025390625000896 +1.9575 -0.0169677734375 0.04025390625000896 +1.957625 -0.01708984375 0.04025390625000896 +1.95775 -0.01708984375 0.04025390625000896 +1.957875 -0.017181396484375 0.04025390625000896 +1.958 -0.017303466796875 0.04025390625000896 +1.958125 -0.017303466796875 0.04025390625000896 +1.95825 -0.01739501953125 0.04025390625000896 +1.958375 -0.01739501953125 0.04025390625000896 +1.9585 -0.01751708984375 0.04025390625000896 +1.958625 -0.017608642578125 0.04025390625000896 +1.95875 -0.017608642578125 0.04025390625000896 +1.958875 -0.0177001953125 0.04025390625000896 +1.959 -0.0177001953125 0.04025390625000896 +1.959125 -0.017791748046875 0.04025390625000896 +1.95925 -0.017913818359375 0.04025390625000896 +1.959375 -0.017913818359375 0.04025390625000896 +1.9595 -0.01800537109375 0.04025390625000896 +1.959625 -0.01800537109375 0.04025390625000896 +1.95975 -0.018096923828125 0.04025390625000896 +1.959875 -0.0181884765625 0.04025390625000896 +1.96 -0.0181884765625 0.04025390625000896 +1.960125 -0.018280029296875 0.04025390625000896 +1.96025 -0.018280029296875 0.04025390625000896 +1.960375 -0.01837158203125 0.04025390625000896 +1.9605 -0.0184326171875 0.04025390625000896 +1.960625 -0.0184326171875 0.04025390625000896 +1.96075 -0.018524169921875 0.04025390625000896 +1.960875 -0.018524169921875 0.04025390625000896 +1.961 -0.01861572265625 0.04025390625000896 +1.961125 -0.0186767578125 0.04025390625000896 +1.96125 -0.0186767578125 0.04025390625000896 +1.961375 -0.018768310546875 0.04025390625000896 +1.9615 -0.018768310546875 0.04025390625000896 +1.961625 -0.018829345703125 0.04025390625000896 +1.96175 -0.0189208984375 0.04025390625000896 +1.961875 -0.0189208984375 0.04025390625000896 +1.962 -0.01898193359375 0.04025390625000896 +1.962125 -0.01898193359375 0.04025390625000896 +1.96225 -0.01904296875 0.04025390625000896 +1.962375 -0.01910400390625 0.04025390625000896 +1.9625 -0.01910400390625 0.04025390625000896 +1.962625 -0.0191650390625 0.04025390625000896 +1.96275 -0.0191650390625 0.04025390625000896 +1.962875 -0.01922607421875 0.04025390625000896 +1.963 -0.019287109375 0.04025390625000896 +1.963125 -0.019287109375 0.04025390625000896 +1.96325 -0.01934814453125 0.04025390625000896 +1.963375 -0.01934814453125 0.04025390625000896 +1.9635 -0.0194091796875 0.04025390625000896 +1.963625 -0.01947021484375 0.04025390625000896 +1.96375 -0.01947021484375 0.04025390625000896 +1.963875 -0.019500732421875 0.04025390625000896 +1.964 -0.019500732421875 0.04025390625000896 +1.964125 -0.019561767578125 0.04025390625000896 +1.96425 -0.019622802734375 0.04025390625000896 +1.964375 -0.019622802734375 0.04025390625000896 +1.9645 -0.0196533203125 0.04025390625000896 +1.964625 -0.0196533203125 0.04025390625000896 +1.96475 -0.019683837890625 0.04025390625000896 +1.964875 -0.019744873046875 0.04025390625000896 +1.965 -0.019744873046875 0.04025390625000896 +1.965125 -0.019775390625 0.04025390625000896 +1.96525 -0.019775390625 0.04025390625000896 +1.965375 -0.019805908203125 0.04025390625000896 +1.9655 -0.01983642578125 0.04025390625000896 +1.965625 -0.01983642578125 0.04025390625000896 +1.96575 -0.019866943359375 0.04025390625000896 +1.965875 -0.019866943359375 0.04025390625000896 +1.966 -0.0198974609375 0.04025390625000896 +1.966125 -0.019927978515625 0.04025390625000896 +1.96625 -0.019927978515625 0.04025390625000896 +1.966375 -0.01995849609375 0.04025390625000896 +1.9665 -0.01995849609375 0.04025390625000896 +1.966625 -0.019989013671875 0.04025390625000896 +1.96675 -0.02001953125 0.04025390625000896 +1.966875 -0.02001953125 0.04025390625000896 +1.967 -0.02001953125 0.04025390625000896 +1.967125 -0.02001953125 0.04025390625000896 +1.96725 -0.020050048828125 0.04025390625000896 +1.967375 -0.020050048828125 0.04025390625000896 +1.9675 -0.020050048828125 0.04025390625000896 +1.967625 -0.02008056640625 0.04025390625000896 +1.96775 -0.02008056640625 0.04025390625000896 +1.967875 -0.02008056640625 0.04025390625000896 +1.968 -0.02008056640625 0.04025390625000896 +1.968125 -0.02008056640625 0.04025390625000896 +1.96825 -0.02008056640625 0.04025390625000896 +1.968375 -0.02008056640625 0.04025390625000896 +1.9685 -0.02008056640625 0.04025390625000896 +1.968625 -0.02008056640625 0.04025390625000896 +1.96875 -0.02008056640625 0.04025390625000896 +1.968875 -0.02008056640625 0.04025390625000896 +1.969 -0.02008056640625 0.04025390625000896 +1.969125 -0.02008056640625 0.04025390625000896 +1.96925 -0.02008056640625 0.04025390625000896 +1.969375 -0.02008056640625 0.04025390625000896 +1.9695 -0.02008056640625 0.04025390625000896 +1.969625 -0.02008056640625 0.04025390625000896 +1.96975 -0.02008056640625 0.04025390625000896 +1.969875 -0.020050048828125 0.04025390625000896 +1.97 -0.020050048828125 0.04025390625000896 +1.970125 -0.020050048828125 0.04025390625000896 +1.97025 -0.020050048828125 0.04025390625000896 +1.970375 -0.02001953125 0.04025390625000896 +1.9705 -0.02001953125 0.04025390625000896 +1.970625 -0.02001953125 0.04025390625000896 +1.97075 -0.019989013671875 0.04025390625000896 +1.970875 -0.019989013671875 0.04025390625000896 +1.971 -0.01995849609375 0.04025390625000896 +1.971125 -0.019927978515625 0.04025390625000896 +1.97125 -0.019927978515625 0.04025390625000896 +1.971375 -0.0198974609375 0.04025390625000896 +1.9715 -0.0198974609375 0.04025390625000896 +1.971625 -0.019866943359375 0.04025390625000896 +1.97175 -0.01983642578125 0.04025390625000896 +1.971875 -0.01983642578125 0.04025390625000896 +1.972 -0.019805908203125 0.04025390625000896 +1.972125 -0.019805908203125 0.04025390625000896 +1.97225 -0.019775390625 0.04025390625000896 +1.972375 -0.019744873046875 0.04025390625000896 +1.9725 -0.019744873046875 0.04025390625000896 +1.972625 -0.019683837890625 0.04025390625000896 +1.97275 -0.019683837890625 0.04025390625000896 +1.972875 -0.0196533203125 0.04025390625000896 +1.973 -0.019622802734375 0.04025390625000896 +1.973125 -0.019622802734375 0.04025390625000896 +1.97325 -0.019561767578125 0.04025390625000896 +1.973375 -0.019561767578125 0.04025390625000896 +1.9735 -0.019500732421875 0.04025390625000896 +1.973625 -0.01947021484375 0.04025390625000896 +1.97375 -0.01947021484375 0.04025390625000896 +1.973875 -0.0194091796875 0.04025390625000896 +1.974 -0.0194091796875 0.04025390625000896 +1.974125 -0.01934814453125 0.04025390625000896 +1.97425 -0.019287109375 0.04025390625000896 +1.974375 -0.019287109375 0.04025390625000896 +1.9745 -0.01922607421875 0.04025390625000896 +1.974625 -0.01922607421875 0.04025390625000896 +1.97475 -0.0191650390625 0.04025390625000896 +1.974875 -0.01910400390625 0.04025390625000896 +1.975 -0.01910400390625 0.04025390625000896 +1.975125 -0.01904296875 0.04025390625000896 +1.97525 -0.01904296875 0.04025390625000896 +1.975375 -0.01898193359375 0.04025390625000896 +1.9755 -0.0189208984375 0.04025390625000896 +1.975625 -0.0189208984375 0.04025390625000896 +1.97575 -0.018829345703125 0.04025390625000896 +1.975875 -0.018829345703125 0.04025390625000896 +1.976 -0.018768310546875 0.04025390625000896 +1.976125 -0.0186767578125 0.04025390625000896 +1.97625 -0.0186767578125 0.04025390625000896 +1.976375 -0.01861572265625 0.04025390625000896 +1.9765 -0.01861572265625 0.04025390625000896 +1.976625 -0.018524169921875 0.04025390625000896 +1.97675 -0.0184326171875 0.04025390625000896 +1.976875 -0.0184326171875 0.04025390625000896 +1.977 -0.01837158203125 0.04025390625000896 +1.977125 -0.01837158203125 0.04025390625000896 +1.97725 -0.018280029296875 0.04025390625000896 +1.977375 -0.0181884765625 0.04025390625000896 +1.9775 -0.0181884765625 0.04025390625000896 +1.977625 -0.018096923828125 0.04025390625000896 +1.97775 -0.018096923828125 0.04025390625000896 +1.977875 -0.01800537109375 0.04025390625000896 +1.978 -0.017913818359375 0.04025390625000896 +1.978125 -0.017913818359375 0.04025390625000896 +1.97825 -0.017791748046875 0.04025390625000896 +1.978375 -0.017791748046875 0.04025390625000896 +1.9785 -0.0177001953125 0.04025390625000896 +1.978625 -0.017608642578125 0.04025390625000896 +1.97875 -0.017608642578125 0.04025390625000896 +1.978875 -0.01751708984375 0.04025390625000896 +1.979 -0.01751708984375 0.04025390625000896 +1.979125 -0.01739501953125 0.04025390625000896 +1.97925 -0.017303466796875 0.04025390625000896 +1.979375 -0.017303466796875 0.04025390625000896 +1.9795 -0.017181396484375 0.04025390625000896 +1.979625 -0.017181396484375 0.04025390625000896 +1.97975 -0.01708984375 0.04025390625000896 +1.979875 -0.0169677734375 0.04025390625000896 +1.98 -0.0169677734375 0.04025390625000896 +1.980125 -0.016845703125 0.04025390625000896 +1.98025 -0.016845703125 0.04025390625000896 +1.980375 -0.0167236328125 0.04025390625000896 +1.9805 -0.016632080078125 0.04025390625000896 +1.980625 -0.016632080078125 0.04025390625000896 +1.98075 -0.016510009765625 0.04025390625000896 +1.980875 -0.016510009765625 0.04025390625000896 +1.981 -0.016387939453125 0.04025390625000896 +1.981125 -0.016265869140625 0.04025390625000896 +1.98125 -0.016265869140625 0.04025390625000896 +1.981375 -0.016143798828125 0.04025390625000896 +1.9815 -0.016143798828125 0.04025390625000896 +1.981625 -0.0159912109375 0.04025390625000896 +1.98175 -0.015869140625 0.04025390625000896 +1.981875 -0.015869140625 0.04025390625000896 +1.982 -0.0157470703125 0.04025390625000896 +1.982125 -0.0157470703125 0.04025390625000896 +1.98225 -0.015625 0.04025390625000896 +1.982375 -0.015472412109375 0.04025390625000896 +1.9825 -0.015472412109375 0.04025390625000896 +1.982625 -0.015350341796875 0.04025390625000896 +1.98275 -0.015350341796875 0.04025390625000896 +1.982875 -0.01519775390625 0.04025390625000896 +1.983 -0.01507568359375 0.04025390625000896 +1.983125 -0.01507568359375 0.04025390625000896 +1.98325 -0.014923095703125 0.04025390625000896 +1.983375 -0.014923095703125 0.04025390625000896 +1.9835 -0.014801025390625 0.04025390625000896 +1.983625 -0.0146484375 0.04025390625000896 +1.98375 -0.0146484375 0.04025390625000896 +1.983875 -0.014495849609375 0.04025390625000896 +1.984 -0.129791259765625 0.3597460937500089 +1.984125 -0.12847900390625 0.3597460937500089 +1.98425 -0.127166748046875 0.3597460937500089 +1.984375 -0.127166748046875 0.3597460937500089 +1.9845 -0.125823974609375 0.3597460937500089 +1.984625 -0.125823974609375 0.3597460937500089 +1.98475 -0.12445068359375 0.3597460937500089 +1.984875 -0.12310791015625 0.3597460937500089 +1.985 -0.12310791015625 0.3597460937500089 +1.985125 -0.121734619140625 0.3597460937500089 +1.98525 -0.121734619140625 0.3597460937500089 +1.985375 -0.120330810546875 0.3597460937500089 +1.9855 -0.118927001953125 0.3597460937500089 +1.985625 -0.118927001953125 0.3597460937500089 +1.98575 -0.11749267578125 0.3597460937500089 +1.985875 -0.11749267578125 0.3597460937500089 +1.986 -0.116058349609375 0.3597460937500089 +1.986125 -0.1146240234375 0.3597460937500089 +1.98625 -0.1146240234375 0.3597460937500089 +1.986375 -0.1131591796875 0.3597460937500089 +1.9865 -0.1131591796875 0.3597460937500089 +1.986625 -0.1116943359375 0.3597460937500089 +1.98675 -0.1102294921875 0.3597460937500089 +1.986875 -0.1102294921875 0.3597460937500089 +1.987 -0.10870361328125 0.3597460937500089 +1.987125 -0.10870361328125 0.3597460937500089 +1.98725 -0.107208251953125 0.3597460937500089 +1.987375 -0.105682373046875 0.3597460937500089 +1.9875 -0.105682373046875 0.3597460937500089 +1.987625 -0.104156494140625 0.3597460937500089 +1.98775 -0.104156494140625 0.3597460937500089 +1.987875 -0.102630615234375 0.3597460937500089 +1.988 -0.10107421875 0.3597460937500089 +1.988125 -0.10107421875 0.3597460937500089 +1.98825 -0.099517822265625 0.3597460937500089 +1.988375 -0.099517822265625 0.3597460937500089 +1.9885 -0.097930908203125 0.3597460937500089 +1.988625 -0.096343994140625 0.3597460937500089 +1.98875 -0.096343994140625 0.3597460937500089 +1.988875 -0.094757080078125 0.3597460937500089 +1.989 -0.094757080078125 0.3597460937500089 +1.989125 -0.0931396484375 0.3597460937500089 +1.98925 -0.091522216796875 0.3597460937500089 +1.989375 -0.091522216796875 0.3597460937500089 +1.9895 -0.08990478515625 0.3597460937500089 +1.989625 -0.08990478515625 0.3597460937500089 +1.98975 -0.0882568359375 0.3597460937500089 +1.989875 -0.086639404296875 0.3597460937500089 +1.99 -0.086639404296875 0.3597460937500089 +1.990125 -0.0849609375 0.3597460937500089 +1.99025 -0.0849609375 0.3597460937500089 +1.990375 -0.08331298828125 0.3597460937500089 +1.9905 -0.081634521484375 0.3597460937500089 +1.990625 -0.081634521484375 0.3597460937500089 +1.99075 -0.0799560546875 0.3597460937500089 +1.990875 -0.0799560546875 0.3597460937500089 +1.991 -0.0782470703125 0.3597460937500089 +1.991125 -0.076568603515625 0.3597460937500089 +1.99125 -0.076568603515625 0.3597460937500089 +1.991375 -0.074859619140625 0.3597460937500089 +1.9915 -0.074859619140625 0.3597460937500089 +1.991625 -0.0731201171875 0.3597460937500089 +1.99175 -0.0714111328125 0.3597460937500089 +1.991875 -0.0714111328125 0.3597460937500089 +1.992 -0.069671630859375 0.3597460937500089 +1.992125 -0.069671630859375 0.3597460937500089 +1.99225 -0.06793212890625 0.3597460937500089 +1.992375 -0.066192626953125 0.3597460937500089 +1.9925 -0.066192626953125 0.3597460937500089 +1.992625 -0.064422607421875 0.3597460937500089 +1.99275 -0.064422607421875 0.3597460937500089 +1.992875 -0.06268310546875 0.3597460937500089 +1.993 -0.0609130859375 0.3597460937500089 +1.993125 -0.0609130859375 0.3597460937500089 +1.99325 -0.059112548828125 0.3597460937500089 +1.993375 -0.059112548828125 0.3597460937500089 +1.9935 -0.057342529296875 0.3597460937500089 +1.993625 -0.055572509765625 0.3597460937500089 +1.99375 -0.055572509765625 0.3597460937500089 +1.993875 -0.05377197265625 0.3597460937500089 +1.994 -0.05377197265625 0.3597460937500089 +1.994125 -0.051971435546875 0.3597460937500089 +1.99425 -0.0501708984375 0.3597460937500089 +1.994375 -0.0501708984375 0.3597460937500089 +1.9945 -0.04833984375 0.3597460937500089 +1.994625 -0.04833984375 0.3597460937500089 +1.99475 -0.046539306640625 0.3597460937500089 +1.994875 -0.044708251953125 0.3597460937500089 +1.995 -0.044708251953125 0.3597460937500089 +1.995125 -0.042877197265625 0.3597460937500089 +1.99525 -0.042877197265625 0.3597460937500089 +1.995375 -0.041046142578125 0.3597460937500089 +1.9955 -0.039215087890625 0.3597460937500089 +1.995625 -0.039215087890625 0.3597460937500089 +1.99575 -0.037384033203125 0.3597460937500089 +1.995875 -0.037384033203125 0.3597460937500089 +1.996 -0.0355224609375 0.3597460937500089 +1.996125 -0.03369140625 0.3597460937500089 +1.99625 -0.03369140625 0.3597460937500089 +1.996375 -0.031829833984375 0.3597460937500089 +1.9965 -0.031829833984375 0.3597460937500089 +1.996625 -0.02996826171875 0.3597460937500089 +1.99675 -0.028106689453125 0.3597460937500089 +1.996875 -0.028106689453125 0.3597460937500089 +1.997 -0.0262451171875 0.3597460937500089 +1.997125 -0.0262451171875 0.3597460937500089 +1.99725 -0.024383544921875 0.3597460937500089 +1.997375 -0.02252197265625 0.3597460937500089 +1.9975 -0.02252197265625 0.3597460937500089 +1.997625 -0.020660400390625 0.3597460937500089 +1.99775 -0.020660400390625 0.3597460937500089 +1.997875 -0.018798828125 0.3597460937500089 +1.998 -0.01690673828125 0.3597460937500089 +1.998125 -0.01690673828125 0.3597460937500089 +1.99825 -0.0150146484375 0.3597460937500089 +1.998375 -0.0150146484375 0.3597460937500089 +1.9985 -0.013153076171875 0.3597460937500089 +1.998625 -0.011260986328125 0.3597460937500089 +1.99875 -0.011260986328125 0.3597460937500089 +1.998875 -0.0093994140625 0.3597460937500089 +1.999 -0.0093994140625 0.3597460937500089 +1.999125 -0.00750732421875 0.3597460937500089 +1.99925 -0.005645751953125 0.3597460937500089 +1.999375 -0.005645751953125 0.3597460937500089 +1.9995 -0.003753662109375 0.3597460937500089 +1.999625 -0.003753662109375 0.3597460937500089 +1.99975 -0.001861572265625 0.3597460937500089 1.999875 0.0 0.3597460937500089 2.0 0.0 0.3597460937500089 2.000125 0.001861572265625 0.3597460937500089 diff --git a/tests/circuitpython/synth_note_bend.py.exp b/tests/circuitpython/synth_note_bend.py.exp index fda9787b38c..e79811509e0 100644 --- a/tests/circuitpython/synth_note_bend.py.exp +++ b/tests/circuitpython/synth_note_bend.py.exp @@ -208,188 +208,188 @@ 0.025875 0.01043701171875 -0.743977294921875 0.026 0.005218505859375 -0.743977294921875 0.026125 0.0 -0.743977294921875 -0.02625 -0.010467529296875 -0.743977294921875 -0.026375 -0.015716552734375 -0.743977294921875 -0.0265 -0.026153564453125 -0.743977294921875 -0.026625 -0.031402587890625 -0.743977294921875 -0.02675 -0.041839599609375 -0.743977294921875 -0.026875 -0.04705810546875 -0.743977294921875 -0.027 -0.052276611328125 -0.743977294921875 -0.027125 -0.062652587890625 -0.743977294921875 -0.02725 -0.067840576171875 -0.743977294921875 -0.027375 -0.078216552734375 -0.743977294921875 -0.0275 -0.0833740234375 -0.743977294921875 -0.027625 -0.09368896484375 -0.743977294921875 -0.02775 -0.09881591796875 -0.743977294921875 -0.027875 -0.10906982421875 -0.743977294921875 -0.028 -0.114166259765625 -0.743977294921875 -0.028125 -0.1192626953125 -0.743977294921875 -0.02825 -0.12939453125 -0.743977294921875 -0.028375 -0.13446044921875 -0.743977294921875 -0.02850000000000001 -0.144500732421875 -0.743977294921875 -0.028625 -0.149505615234375 -0.743977294921875 -0.02875 -0.15948486328125 -0.743977294921875 -0.028875 -0.1644287109375 -0.743977294921875 -0.029 -0.16937255859375 -0.743977294921875 -0.029125 -0.179168701171875 -0.743977294921875 -0.02925 -0.184051513671875 -0.743977294921875 -0.029375 -0.193756103515625 -0.743977294921875 -0.0295 -0.198577880859375 -0.743977294921875 -0.029625 -0.2081298828125 -0.743977294921875 -0.02975000000000001 -0.212890625 -0.743977294921875 -0.029875 -0.217620849609375 -0.743977294921875 -0.03 -0.22698974609375 -0.743977294921875 -0.030125 -0.23162841796875 -0.743977294921875 -0.03025 -0.240875244140625 -0.743977294921875 -0.030375 -0.245452880859375 -0.743977294921875 -0.0305 -0.254486083984375 -0.743977294921875 -0.030625 -0.259002685546875 -0.743977294921875 -0.03075 -0.263458251953125 -0.743977294921875 -0.03087499999999999 -0.272308349609375 -0.743977294921875 -0.031 -0.27667236328125 -0.743977294921875 -0.031125 -0.28533935546875 -0.743977294921875 -0.03125 -0.28961181640625 -0.743977294921875 -0.031375 -0.298095703125 -0.743977294921875 -0.0315 -0.302276611328125 -0.743977294921875 -0.03162500000000001 -0.310546875 -0.743977294921875 -0.03175 -0.31463623046875 -0.743977294921875 -0.031875 -0.318695068359375 -0.743977294921875 -0.032 -0.326690673828125 -0.487985107421875 -0.032125 -0.33453369140625 -0.487985107421875 -0.03225 -0.342254638671875 -0.487985107421875 -0.032375 -0.346038818359375 -0.487985107421875 -0.0325 -0.353515625 -0.487985107421875 -0.032625 -0.36083984375 -0.487985107421875 -0.03275 -0.364471435546875 -0.487985107421875 -0.032875 -0.371551513671875 -0.487985107421875 -0.033 -0.37847900390625 -0.487985107421875 -0.033125 -0.385223388671875 -0.487985107421875 -0.03325 -0.3885498046875 -0.487985107421875 -0.033375 -0.395050048828125 -0.487985107421875 -0.0335 -0.4013671875 -0.487985107421875 -0.03362500000000001 -0.40447998046875 -0.487985107421875 -0.03375 -0.410552978515625 -0.487985107421875 -0.033875 -0.41644287109375 -0.487985107421875 -0.034 -0.4193115234375 -0.487985107421875 -0.03412500000000001 -0.4249267578125 -0.487985107421875 -0.03425 -0.430328369140625 -0.487985107421875 -0.034375 -0.435577392578125 -0.487985107421875 -0.0345 -0.4381103515625 -0.487985107421875 -0.034625 -0.443084716796875 -0.487985107421875 -0.03475000000000001 -0.44781494140625 -0.487985107421875 -0.034875 -0.45013427734375 -0.487985107421875 -0.035 -0.45458984375 -0.487985107421875 -0.03512500000000001 -0.4588623046875 -0.487985107421875 -0.03525 -0.462921142578125 -0.487985107421875 -0.035375 -0.46484375 -0.487985107421875 -0.0355 -0.468597412109375 -0.487985107421875 -0.03562500000000001 -0.47216796875 -0.487985107421875 -0.03575 -0.473846435546875 -0.487985107421875 -0.035875 -0.477081298828125 -0.487985107421875 -0.03600000000000001 -0.4801025390625 -0.487985107421875 -0.036125 -0.482940673828125 -0.487985107421875 -0.03625 -0.4842529296875 -0.487985107421875 -0.036375 -0.48675537109375 -0.487985107421875 -0.0365 -0.489044189453125 -0.487985107421875 -0.036625 -0.4901123046875 -0.487985107421875 -0.03675 -0.4920654296875 -0.487985107421875 -0.036875 -0.493804931640625 -0.487985107421875 -0.037 -0.495330810546875 -0.487985107421875 -0.03712499999999999 -0.49603271484375 -0.487985107421875 -0.03725 -0.497222900390625 -0.487985107421875 -0.037375 -0.49822998046875 -0.487985107421875 -0.0375 -0.498626708984375 -0.487985107421875 -0.037625 -0.499298095703125 -0.487985107421875 -0.03775 -0.499725341796875 -0.487985107421875 -0.037875 -0.49993896484375 -0.487985107421875 -0.038 -0.499969482421875 -0.487985107421875 -0.038125 -0.499847412109375 -0.487985107421875 -0.03825 -0.499542236328125 -0.487985107421875 -0.038375 -0.499298095703125 -0.487985107421875 -0.0385 -0.498626708984375 -0.487985107421875 -0.038625 -0.49774169921875 -0.487985107421875 -0.03875 -0.49664306640625 -0.487985107421875 -0.038875 -0.49603271484375 -0.487985107421875 -0.039 -0.494598388671875 -0.487985107421875 -0.039125 -0.49298095703125 -0.487985107421875 -0.03925 -0.4920654296875 -0.487985107421875 -0.039375 -0.4901123046875 -0.487985107421875 -0.0395 -0.4879150390625 -0.487985107421875 -0.039625 -0.48553466796875 -0.487985107421875 -0.03975 -0.4842529296875 -0.487985107421875 -0.039875 -0.481536865234375 -0.487985107421875 -0.04 -0.4786376953125 -0.487985107421875 -0.040125 -0.477081298828125 -0.487985107421875 -0.04025 -0.473846435546875 -0.487985107421875 -0.040375 -0.47039794921875 -0.487985107421875 -0.04050000000000001 -0.468597412109375 -0.487985107421875 -0.040625 -0.46484375 -0.487985107421875 -0.04075 -0.460906982421875 -0.487985107421875 -0.040875 -0.456756591796875 -0.487985107421875 -0.04100000000000001 -0.45458984375 -0.487985107421875 -0.041125 -0.45013427734375 -0.487985107421875 -0.04125 -0.445465087890625 -0.487985107421875 -0.041375 -0.443084716796875 -0.487985107421875 -0.0415 -0.4381103515625 -0.487985107421875 -0.041625 -0.4329833984375 -0.487985107421875 -0.04175000000000001 -0.427642822265625 -0.487985107421875 -0.041875 -0.4249267578125 -0.487985107421875 -0.042 -0.4193115234375 -0.487985107421875 -0.042125 -0.41351318359375 -0.487985107421875 -0.04225000000000001 -0.410552978515625 -0.487985107421875 -0.042375 -0.40447998046875 -0.487985107421875 -0.0425 -0.398223876953125 -0.487985107421875 -0.042625 -0.391815185546875 -0.487985107421875 -0.04275 -0.3885498046875 -0.487985107421875 -0.04287500000000001 -0.381866455078125 -0.487985107421875 -0.04300000000000001 -0.375030517578125 -0.487985107421875 -0.043125 -0.371551513671875 -0.487985107421875 -0.04325 -0.364471435546875 -0.487985107421875 -0.043375 -0.357208251953125 -0.487985107421875 -0.04350000000000001 -0.34979248046875 -0.487985107421875 -0.04362500000000001 -0.346038818359375 -0.487985107421875 -0.04375000000000001 -0.338409423828125 -0.487985107421875 -0.043875 -0.33062744140625 -0.487985107421875 -0.04399999999999999 -0.326690673828125 -0.487985107421875 -0.044125 -0.318695068359375 -0.487985107421875 -0.04425 -0.310546875 -0.487985107421875 -0.044375 -0.302276611328125 -0.487985107421875 -0.04449999999999999 -0.298095703125 -0.487985107421875 -0.04462499999999999 -0.28961181640625 -0.487985107421875 -0.04475 -0.281005859375 -0.487985107421875 -0.044875 -0.27667236328125 -0.487985107421875 -0.045 -0.26788330078125 -0.487985107421875 -0.045125 -0.259002685546875 -0.487985107421875 -0.04525 -0.25 -0.487985107421875 -0.045375 -0.245452880859375 -0.487985107421875 -0.0455 -0.23626708984375 -0.487985107421875 -0.045625 -0.22698974609375 -0.487985107421875 -0.04575 -0.222320556640625 -0.487985107421875 -0.045875 -0.212890625 -0.487985107421875 -0.046 -0.203369140625 -0.487985107421875 -0.046125 -0.193756103515625 -0.487985107421875 -0.04625 -0.18890380859375 -0.487985107421875 -0.046375 -0.179168701171875 -0.487985107421875 -0.04649999999999999 -0.16937255859375 -0.487985107421875 -0.046625 -0.1644287109375 -0.487985107421875 -0.04675000000000001 -0.154510498046875 -0.487985107421875 -0.046875 -0.144500732421875 -0.487985107421875 -0.04699999999999999 -0.139495849609375 -0.487985107421875 -0.047125 -0.12939453125 -0.487985107421875 -0.04725000000000001 -0.1192626953125 -0.487985107421875 -0.047375 -0.10906982421875 -0.487985107421875 -0.0475 -0.10394287109375 -0.487985107421875 -0.047625 -0.09368896484375 -0.487985107421875 -0.04775 -0.0833740234375 -0.487985107421875 -0.047875 -0.078216552734375 -0.487985107421875 -0.048 -0.067840576171875 -0.487985107421875 -0.048125 -0.057464599609375 -0.487985107421875 -0.04825 -0.04705810546875 -0.487985107421875 -0.048375 -0.041839599609375 -0.487985107421875 -0.0485 -0.031402587890625 -0.487985107421875 -0.048625 -0.02093505859375 -0.487985107421875 -0.04875 -0.015716552734375 -0.487985107421875 -0.048875 -0.0052490234375 -0.487985107421875 +0.02625 -0.01043701171875 -0.743977294921875 +0.026375 -0.01568603515625 -0.743977294921875 +0.0265 -0.026123046875 -0.743977294921875 +0.026625 -0.0313720703125 -0.743977294921875 +0.02675 -0.04180908203125 -0.743977294921875 +0.026875 -0.047027587890625 -0.743977294921875 +0.027 -0.05224609375 -0.743977294921875 +0.027125 -0.0626220703125 -0.743977294921875 +0.02725 -0.06781005859375 -0.743977294921875 +0.027375 -0.07818603515625 -0.743977294921875 +0.0275 -0.083343505859375 -0.743977294921875 +0.027625 -0.093658447265625 -0.743977294921875 +0.02775 -0.098785400390625 -0.743977294921875 +0.027875 -0.109039306640625 -0.743977294921875 +0.028 -0.1141357421875 -0.743977294921875 +0.028125 -0.119232177734375 -0.743977294921875 +0.02825 -0.129364013671875 -0.743977294921875 +0.028375 -0.134429931640625 -0.743977294921875 +0.02850000000000001 -0.14447021484375 -0.743977294921875 +0.028625 -0.14947509765625 -0.743977294921875 +0.02875 -0.159454345703125 -0.743977294921875 +0.028875 -0.164398193359375 -0.743977294921875 +0.029 -0.169342041015625 -0.743977294921875 +0.029125 -0.17913818359375 -0.743977294921875 +0.02925 -0.18402099609375 -0.743977294921875 +0.029375 -0.1937255859375 -0.743977294921875 +0.0295 -0.19854736328125 -0.743977294921875 +0.029625 -0.208099365234375 -0.743977294921875 +0.02975000000000001 -0.212860107421875 -0.743977294921875 +0.029875 -0.21759033203125 -0.743977294921875 +0.03 -0.226959228515625 -0.743977294921875 +0.030125 -0.231597900390625 -0.743977294921875 +0.03025 -0.2408447265625 -0.743977294921875 +0.030375 -0.24542236328125 -0.743977294921875 +0.0305 -0.25445556640625 -0.743977294921875 +0.030625 -0.25897216796875 -0.743977294921875 +0.03075 -0.263427734375 -0.743977294921875 +0.03087499999999999 -0.27227783203125 -0.743977294921875 +0.031 -0.276641845703125 -0.743977294921875 +0.031125 -0.285308837890625 -0.743977294921875 +0.03125 -0.289581298828125 -0.743977294921875 +0.031375 -0.298065185546875 -0.743977294921875 +0.0315 -0.30224609375 -0.743977294921875 +0.03162500000000001 -0.310516357421875 -0.743977294921875 +0.03175 -0.314605712890625 -0.743977294921875 +0.031875 -0.31866455078125 -0.743977294921875 +0.032 -0.32666015625 -0.487985107421875 +0.032125 -0.334503173828125 -0.487985107421875 +0.03225 -0.34222412109375 -0.487985107421875 +0.032375 -0.34600830078125 -0.487985107421875 +0.0325 -0.353485107421875 -0.487985107421875 +0.032625 -0.360809326171875 -0.487985107421875 +0.03275 -0.36444091796875 -0.487985107421875 +0.032875 -0.37152099609375 -0.487985107421875 +0.033 -0.378448486328125 -0.487985107421875 +0.033125 -0.38519287109375 -0.487985107421875 +0.03325 -0.388519287109375 -0.487985107421875 +0.033375 -0.39501953125 -0.487985107421875 +0.0335 -0.401336669921875 -0.487985107421875 +0.03362500000000001 -0.404449462890625 -0.487985107421875 +0.03375 -0.4105224609375 -0.487985107421875 +0.033875 -0.416412353515625 -0.487985107421875 +0.034 -0.419281005859375 -0.487985107421875 +0.03412500000000001 -0.424896240234375 -0.487985107421875 +0.03425 -0.4302978515625 -0.487985107421875 +0.034375 -0.435546875 -0.487985107421875 +0.0345 -0.438079833984375 -0.487985107421875 +0.034625 -0.44305419921875 -0.487985107421875 +0.03475000000000001 -0.447784423828125 -0.487985107421875 +0.034875 -0.450103759765625 -0.487985107421875 +0.035 -0.454559326171875 -0.487985107421875 +0.03512500000000001 -0.458831787109375 -0.487985107421875 +0.03525 -0.462890625 -0.487985107421875 +0.035375 -0.464813232421875 -0.487985107421875 +0.0355 -0.46856689453125 -0.487985107421875 +0.03562500000000001 -0.472137451171875 -0.487985107421875 +0.03575 -0.47381591796875 -0.487985107421875 +0.035875 -0.47705078125 -0.487985107421875 +0.03600000000000001 -0.480072021484375 -0.487985107421875 +0.036125 -0.48291015625 -0.487985107421875 +0.03625 -0.484222412109375 -0.487985107421875 +0.036375 -0.486724853515625 -0.487985107421875 +0.0365 -0.489013671875 -0.487985107421875 +0.036625 -0.490081787109375 -0.487985107421875 +0.03675 -0.492034912109375 -0.487985107421875 +0.036875 -0.4937744140625 -0.487985107421875 +0.037 -0.49530029296875 -0.487985107421875 +0.03712499999999999 -0.496002197265625 -0.487985107421875 +0.03725 -0.4971923828125 -0.487985107421875 +0.037375 -0.498199462890625 -0.487985107421875 +0.0375 -0.49859619140625 -0.487985107421875 +0.037625 -0.499267578125 -0.487985107421875 +0.03775 -0.49969482421875 -0.487985107421875 +0.037875 -0.499908447265625 -0.487985107421875 +0.038 -0.49993896484375 -0.487985107421875 +0.038125 -0.49981689453125 -0.487985107421875 +0.03825 -0.49951171875 -0.487985107421875 +0.038375 -0.499267578125 -0.487985107421875 +0.0385 -0.49859619140625 -0.487985107421875 +0.038625 -0.497711181640625 -0.487985107421875 +0.03875 -0.496612548828125 -0.487985107421875 +0.038875 -0.496002197265625 -0.487985107421875 +0.039 -0.49456787109375 -0.487985107421875 +0.039125 -0.492950439453125 -0.487985107421875 +0.03925 -0.492034912109375 -0.487985107421875 +0.039375 -0.490081787109375 -0.487985107421875 +0.0395 -0.487884521484375 -0.487985107421875 +0.039625 -0.485504150390625 -0.487985107421875 +0.03975 -0.484222412109375 -0.487985107421875 +0.039875 -0.48150634765625 -0.487985107421875 +0.04 -0.478607177734375 -0.487985107421875 +0.040125 -0.47705078125 -0.487985107421875 +0.04025 -0.47381591796875 -0.487985107421875 +0.040375 -0.470367431640625 -0.487985107421875 +0.04050000000000001 -0.46856689453125 -0.487985107421875 +0.040625 -0.464813232421875 -0.487985107421875 +0.04075 -0.46087646484375 -0.487985107421875 +0.040875 -0.45672607421875 -0.487985107421875 +0.04100000000000001 -0.454559326171875 -0.487985107421875 +0.041125 -0.450103759765625 -0.487985107421875 +0.04125 -0.4454345703125 -0.487985107421875 +0.041375 -0.44305419921875 -0.487985107421875 +0.0415 -0.438079833984375 -0.487985107421875 +0.041625 -0.432952880859375 -0.487985107421875 +0.04175000000000001 -0.4276123046875 -0.487985107421875 +0.041875 -0.424896240234375 -0.487985107421875 +0.042 -0.419281005859375 -0.487985107421875 +0.042125 -0.413482666015625 -0.487985107421875 +0.04225000000000001 -0.4105224609375 -0.487985107421875 +0.042375 -0.404449462890625 -0.487985107421875 +0.0425 -0.398193359375 -0.487985107421875 +0.042625 -0.39178466796875 -0.487985107421875 +0.04275 -0.388519287109375 -0.487985107421875 +0.04287500000000001 -0.3818359375 -0.487985107421875 +0.04300000000000001 -0.375 -0.487985107421875 +0.043125 -0.37152099609375 -0.487985107421875 +0.04325 -0.36444091796875 -0.487985107421875 +0.043375 -0.357177734375 -0.487985107421875 +0.04350000000000001 -0.349761962890625 -0.487985107421875 +0.04362500000000001 -0.34600830078125 -0.487985107421875 +0.04375000000000001 -0.33837890625 -0.487985107421875 +0.043875 -0.330596923828125 -0.487985107421875 +0.04399999999999999 -0.32666015625 -0.487985107421875 +0.044125 -0.31866455078125 -0.487985107421875 +0.04425 -0.310516357421875 -0.487985107421875 +0.044375 -0.30224609375 -0.487985107421875 +0.04449999999999999 -0.298065185546875 -0.487985107421875 +0.04462499999999999 -0.289581298828125 -0.487985107421875 +0.04475 -0.280975341796875 -0.487985107421875 +0.044875 -0.276641845703125 -0.487985107421875 +0.045 -0.267852783203125 -0.487985107421875 +0.045125 -0.25897216796875 -0.487985107421875 +0.04525 -0.249969482421875 -0.487985107421875 +0.045375 -0.24542236328125 -0.487985107421875 +0.0455 -0.236236572265625 -0.487985107421875 +0.045625 -0.226959228515625 -0.487985107421875 +0.04575 -0.2222900390625 -0.487985107421875 +0.045875 -0.212860107421875 -0.487985107421875 +0.046 -0.203338623046875 -0.487985107421875 +0.046125 -0.1937255859375 -0.487985107421875 +0.04625 -0.188873291015625 -0.487985107421875 +0.046375 -0.17913818359375 -0.487985107421875 +0.04649999999999999 -0.169342041015625 -0.487985107421875 +0.046625 -0.164398193359375 -0.487985107421875 +0.04675000000000001 -0.15447998046875 -0.487985107421875 +0.046875 -0.14447021484375 -0.487985107421875 +0.04699999999999999 -0.13946533203125 -0.487985107421875 +0.047125 -0.129364013671875 -0.487985107421875 +0.04725000000000001 -0.119232177734375 -0.487985107421875 +0.047375 -0.109039306640625 -0.487985107421875 +0.0475 -0.103912353515625 -0.487985107421875 +0.047625 -0.093658447265625 -0.487985107421875 +0.04775 -0.083343505859375 -0.487985107421875 +0.047875 -0.07818603515625 -0.487985107421875 +0.048 -0.06781005859375 -0.487985107421875 +0.048125 -0.05743408203125 -0.487985107421875 +0.04825 -0.047027587890625 -0.487985107421875 +0.048375 -0.04180908203125 -0.487985107421875 +0.0485 -0.0313720703125 -0.487985107421875 +0.048625 -0.020904541015625 -0.487985107421875 +0.04875 -0.01568603515625 -0.487985107421875 +0.048875 -0.005218505859375 -0.487985107421875 0.049 0.005218505859375 -0.487985107421875 0.04912500000000001 0.01568603515625 -0.487985107421875 0.04925000000000001 0.020904541015625 -0.487985107421875 @@ -556,153 +556,153 @@ 0.06937500000000001 0.0313720703125 -0.2319929199218749 0.06950000000000001 0.01568603515625 -0.2319929199218749 0.069625 0.005218505859375 -0.2319929199218749 -0.06975 -0.0052490234375 -0.2319929199218749 -0.06987500000000001 -0.015716552734375 -0.2319929199218749 -0.07000000000000001 -0.026153564453125 -0.2319929199218749 -0.070125 -0.03662109375 -0.2319929199218749 -0.07025000000000001 -0.04705810546875 -0.2319929199218749 -0.07037500000000001 -0.057464599609375 -0.2319929199218749 -0.07050000000000001 -0.067840576171875 -0.2319929199218749 -0.070625 -0.078216552734375 -0.2319929199218749 -0.07075 -0.088531494140625 -0.2319929199218749 -0.07087500000000001 -0.09881591796875 -0.2319929199218749 -0.07100000000000001 -0.10906982421875 -0.2319929199218749 -0.07112500000000001 -0.1192626953125 -0.2319929199218749 -0.07125000000000002 -0.12939453125 -0.2319929199218749 -0.07137500000000001 -0.139495849609375 -0.2319929199218749 -0.0715 -0.149505615234375 -0.2319929199218749 -0.07162500000000001 -0.15948486328125 -0.2319929199218749 -0.07175000000000001 -0.16937255859375 -0.2319929199218749 -0.07187500000000001 -0.179168701171875 -0.2319929199218749 -0.07200000000000001 -0.18890380859375 -0.2319929199218749 -0.07212499999999999 -0.198577880859375 -0.2319929199218749 -0.07225 -0.212890625 -0.2319929199218749 -0.07237499999999999 -0.222320556640625 -0.2319929199218749 -0.0725 -0.23162841796875 -0.2319929199218749 -0.07262499999999999 -0.240875244140625 -0.2319929199218749 -0.07274999999999999 -0.25 -0.2319929199218749 -0.072875 -0.259002685546875 -0.2319929199218749 -0.073 -0.26788330078125 -0.2319929199218749 -0.073125 -0.27667236328125 -0.2319929199218749 -0.07324999999999999 -0.28533935546875 -0.2319929199218749 -0.07337499999999999 -0.293853759765625 -0.2319929199218749 -0.0735 -0.302276611328125 -0.2319929199218749 -0.073625 -0.310546875 -0.2319929199218749 -0.07374999999999999 -0.318695068359375 -0.2319929199218749 -0.073875 -0.326690673828125 -0.2319929199218749 -0.074 -0.33453369140625 -0.2319929199218749 -0.074125 -0.342254638671875 -0.2319929199218749 -0.07424999999999999 -0.34979248046875 -0.2319929199218749 -0.07437499999999999 -0.357208251953125 -0.2319929199218749 -0.0745 -0.364471435546875 -0.2319929199218749 -0.07462499999999999 -0.371551513671875 -0.2319929199218749 -0.07475 -0.37847900390625 -0.2319929199218749 -0.07487500000000001 -0.385223388671875 -0.2319929199218749 -0.075 -0.391815185546875 -0.2319929199218749 -0.07512499999999999 -0.4013671875 -0.2319929199218749 -0.07524999999999999 -0.40753173828125 -0.2319929199218749 -0.075375 -0.41351318359375 -0.2319929199218749 -0.0755 -0.4193115234375 -0.2319929199218749 -0.075625 -0.4249267578125 -0.2319929199218749 -0.07574999999999999 -0.430328369140625 -0.2319929199218749 -0.075875 -0.435577392578125 -0.2319929199218749 -0.076 -0.44061279296875 -0.2319929199218749 -0.076125 -0.445465087890625 -0.2319929199218749 -0.07625 -0.45013427734375 -0.2319929199218749 -0.07637499999999999 -0.45458984375 -0.2319929199218749 -0.0765 -0.4588623046875 -0.2319929199218749 -0.076625 -0.462921142578125 -0.2319929199218749 -0.07675 -0.466766357421875 -0.2319929199218749 -0.076875 -0.47039794921875 -0.2319929199218749 -0.077 -0.473846435546875 -0.2319929199218749 -0.077125 -0.477081298828125 -0.2319929199218749 -0.07725 -0.4801025390625 -0.2319929199218749 -0.07737499999999999 -0.482940673828125 -0.2319929199218749 -0.0775 -0.48553466796875 -0.2319929199218749 -0.077625 -0.4879150390625 -0.2319929199218749 -0.07774999999999999 -0.4901123046875 -0.2319929199218749 -0.07787500000000001 -0.4920654296875 -0.2319929199218749 -0.07800000000000001 -0.494598388671875 -0.2319929199218749 -0.078125 -0.49603271484375 -0.2319929199218749 -0.07824999999999999 -0.497222900390625 -0.2319929199218749 -0.07837499999999999 -0.49822998046875 -0.2319929199218749 -0.07850000000000001 -0.498992919921875 -0.2319929199218749 -0.078625 -0.499542236328125 -0.2319929199218749 -0.07875 -0.499847412109375 -0.2319929199218749 -0.07887500000000001 -0.499969482421875 -0.2319929199218749 -0.079 -0.499847412109375 -0.2319929199218749 -0.079125 -0.499542236328125 -0.2319929199218749 -0.07925 -0.498992919921875 -0.2319929199218749 -0.079375 -0.49822998046875 -0.2319929199218749 -0.0795 -0.497222900390625 -0.2319929199218749 -0.079625 -0.49603271484375 -0.2319929199218749 -0.07975 -0.494598388671875 -0.2319929199218749 -0.07987500000000001 -0.49298095703125 -0.2319929199218749 -0.08 -0.491119384765625 -0.2319929199218749 -0.08012499999999999 -0.489044189453125 -0.2319929199218749 -0.08025 -0.48675537109375 -0.2319929199218749 -0.080375 -0.4842529296875 -0.2319929199218749 -0.08050000000000001 -0.481536865234375 -0.2319929199218749 -0.080625 -0.4786376953125 -0.2319929199218749 -0.08074999999999999 -0.473846435546875 -0.2319929199218749 -0.080875 -0.47039794921875 -0.2319929199218749 -0.08100000000000001 -0.466766357421875 -0.2319929199218749 -0.08112500000000001 -0.462921142578125 -0.2319929199218749 -0.08125 -0.4588623046875 -0.2319929199218749 -0.08137499999999999 -0.45458984375 -0.2319929199218749 -0.0815 -0.45013427734375 -0.2319929199218749 -0.081625 -0.445465087890625 -0.2319929199218749 -0.08175000000000001 -0.44061279296875 -0.2319929199218749 -0.081875 -0.435577392578125 -0.2319929199218749 -0.08200000000000001 -0.430328369140625 -0.2319929199218749 -0.082125 -0.4249267578125 -0.2319929199218749 -0.08225 -0.4193115234375 -0.2319929199218749 -0.08237500000000001 -0.41351318359375 -0.2319929199218749 -0.0825 -0.40753173828125 -0.2319929199218749 -0.08262500000000001 -0.4013671875 -0.2319929199218749 -0.08275 -0.395050048828125 -0.2319929199218749 -0.08287500000000001 -0.3885498046875 -0.2319929199218749 -0.08300000000000001 -0.381866455078125 -0.2319929199218749 -0.083125 -0.375030517578125 -0.2319929199218749 -0.08324999999999999 -0.368011474609375 -0.2319929199218749 -0.083375 -0.36083984375 -0.2319929199218749 -0.08350000000000001 -0.353515625 -0.2319929199218749 -0.08362500000000001 -0.342254638671875 -0.2319929199218749 -0.08375 -0.33453369140625 -0.2319929199218749 -0.08387500000000001 -0.326690673828125 -0.2319929199218749 -0.084 -0.318695068359375 -0.2319929199218749 -0.08412500000000001 -0.310546875 -0.2319929199218749 -0.08425000000000001 -0.302276611328125 -0.2319929199218749 -0.084375 -0.293853759765625 -0.2319929199218749 -0.08450000000000001 -0.28533935546875 -0.2319929199218749 -0.084625 -0.27667236328125 -0.2319929199218749 -0.08475 -0.26788330078125 -0.2319929199218749 -0.08487500000000001 -0.259002685546875 -0.2319929199218749 -0.085 -0.25 -0.2319929199218749 -0.08512500000000001 -0.240875244140625 -0.2319929199218749 -0.08525 -0.23162841796875 -0.2319929199218749 -0.085375 -0.222320556640625 -0.2319929199218749 -0.08550000000000001 -0.212890625 -0.2319929199218749 -0.085625 -0.203369140625 -0.2319929199218749 -0.08575000000000001 -0.193756103515625 -0.2319929199218749 -0.08587500000000002 -0.184051513671875 -0.2319929199218749 -0.08600000000000001 -0.174285888671875 -0.2319929199218749 -0.08612500000000001 -0.1644287109375 -0.2319929199218749 -0.08625 -0.154510498046875 -0.2319929199218749 -0.08637499999999999 -0.144500732421875 -0.2319929199218749 -0.0865 -0.12939453125 -0.2319929199218749 -0.08662500000000001 -0.1192626953125 -0.2319929199218749 -0.08675000000000001 -0.10906982421875 -0.2319929199218749 -0.08687500000000002 -0.09881591796875 -0.2319929199218749 -0.08700000000000001 -0.088531494140625 -0.2319929199218749 -0.087125 -0.078216552734375 -0.2319929199218749 -0.08725000000000001 -0.067840576171875 -0.2319929199218749 -0.08737500000000001 -0.057464599609375 -0.2319929199218749 -0.08750000000000002 -0.04705810546875 -0.2319929199218749 -0.08762500000000001 -0.03662109375 -0.2319929199218749 -0.08775 -0.026153564453125 -0.2319929199218749 -0.08787500000000001 -0.015716552734375 -0.2319929199218749 -0.08799999999999999 -0.0052490234375 -0.2319929199218749 +0.06975 -0.005218505859375 -0.2319929199218749 +0.06987500000000001 -0.01568603515625 -0.2319929199218749 +0.07000000000000001 -0.026123046875 -0.2319929199218749 +0.070125 -0.036590576171875 -0.2319929199218749 +0.07025000000000001 -0.047027587890625 -0.2319929199218749 +0.07037500000000001 -0.05743408203125 -0.2319929199218749 +0.07050000000000001 -0.06781005859375 -0.2319929199218749 +0.070625 -0.07818603515625 -0.2319929199218749 +0.07075 -0.0885009765625 -0.2319929199218749 +0.07087500000000001 -0.098785400390625 -0.2319929199218749 +0.07100000000000001 -0.109039306640625 -0.2319929199218749 +0.07112500000000001 -0.119232177734375 -0.2319929199218749 +0.07125000000000002 -0.129364013671875 -0.2319929199218749 +0.07137500000000001 -0.13946533203125 -0.2319929199218749 +0.0715 -0.14947509765625 -0.2319929199218749 +0.07162500000000001 -0.159454345703125 -0.2319929199218749 +0.07175000000000001 -0.169342041015625 -0.2319929199218749 +0.07187500000000001 -0.17913818359375 -0.2319929199218749 +0.07200000000000001 -0.188873291015625 -0.2319929199218749 +0.07212499999999999 -0.19854736328125 -0.2319929199218749 +0.07225 -0.212860107421875 -0.2319929199218749 +0.07237499999999999 -0.2222900390625 -0.2319929199218749 +0.0725 -0.231597900390625 -0.2319929199218749 +0.07262499999999999 -0.2408447265625 -0.2319929199218749 +0.07274999999999999 -0.249969482421875 -0.2319929199218749 +0.072875 -0.25897216796875 -0.2319929199218749 +0.073 -0.267852783203125 -0.2319929199218749 +0.073125 -0.276641845703125 -0.2319929199218749 +0.07324999999999999 -0.285308837890625 -0.2319929199218749 +0.07337499999999999 -0.2938232421875 -0.2319929199218749 +0.0735 -0.30224609375 -0.2319929199218749 +0.073625 -0.310516357421875 -0.2319929199218749 +0.07374999999999999 -0.31866455078125 -0.2319929199218749 +0.073875 -0.32666015625 -0.2319929199218749 +0.074 -0.334503173828125 -0.2319929199218749 +0.074125 -0.34222412109375 -0.2319929199218749 +0.07424999999999999 -0.349761962890625 -0.2319929199218749 +0.07437499999999999 -0.357177734375 -0.2319929199218749 +0.0745 -0.36444091796875 -0.2319929199218749 +0.07462499999999999 -0.37152099609375 -0.2319929199218749 +0.07475 -0.378448486328125 -0.2319929199218749 +0.07487500000000001 -0.38519287109375 -0.2319929199218749 +0.075 -0.39178466796875 -0.2319929199218749 +0.07512499999999999 -0.401336669921875 -0.2319929199218749 +0.07524999999999999 -0.407501220703125 -0.2319929199218749 +0.075375 -0.413482666015625 -0.2319929199218749 +0.0755 -0.419281005859375 -0.2319929199218749 +0.075625 -0.424896240234375 -0.2319929199218749 +0.07574999999999999 -0.4302978515625 -0.2319929199218749 +0.075875 -0.435546875 -0.2319929199218749 +0.076 -0.440582275390625 -0.2319929199218749 +0.076125 -0.4454345703125 -0.2319929199218749 +0.07625 -0.450103759765625 -0.2319929199218749 +0.07637499999999999 -0.454559326171875 -0.2319929199218749 +0.0765 -0.458831787109375 -0.2319929199218749 +0.076625 -0.462890625 -0.2319929199218749 +0.07675 -0.46673583984375 -0.2319929199218749 +0.076875 -0.470367431640625 -0.2319929199218749 +0.077 -0.47381591796875 -0.2319929199218749 +0.077125 -0.47705078125 -0.2319929199218749 +0.07725 -0.480072021484375 -0.2319929199218749 +0.07737499999999999 -0.48291015625 -0.2319929199218749 +0.0775 -0.485504150390625 -0.2319929199218749 +0.077625 -0.487884521484375 -0.2319929199218749 +0.07774999999999999 -0.490081787109375 -0.2319929199218749 +0.07787500000000001 -0.492034912109375 -0.2319929199218749 +0.07800000000000001 -0.49456787109375 -0.2319929199218749 +0.078125 -0.496002197265625 -0.2319929199218749 +0.07824999999999999 -0.4971923828125 -0.2319929199218749 +0.07837499999999999 -0.498199462890625 -0.2319929199218749 +0.07850000000000001 -0.49896240234375 -0.2319929199218749 +0.078625 -0.49951171875 -0.2319929199218749 +0.07875 -0.49981689453125 -0.2319929199218749 +0.07887500000000001 -0.49993896484375 -0.2319929199218749 +0.079 -0.49981689453125 -0.2319929199218749 +0.079125 -0.49951171875 -0.2319929199218749 +0.07925 -0.49896240234375 -0.2319929199218749 +0.079375 -0.498199462890625 -0.2319929199218749 +0.0795 -0.4971923828125 -0.2319929199218749 +0.079625 -0.496002197265625 -0.2319929199218749 +0.07975 -0.49456787109375 -0.2319929199218749 +0.07987500000000001 -0.492950439453125 -0.2319929199218749 +0.08 -0.4910888671875 -0.2319929199218749 +0.08012499999999999 -0.489013671875 -0.2319929199218749 +0.08025 -0.486724853515625 -0.2319929199218749 +0.080375 -0.484222412109375 -0.2319929199218749 +0.08050000000000001 -0.48150634765625 -0.2319929199218749 +0.080625 -0.478607177734375 -0.2319929199218749 +0.08074999999999999 -0.47381591796875 -0.2319929199218749 +0.080875 -0.470367431640625 -0.2319929199218749 +0.08100000000000001 -0.46673583984375 -0.2319929199218749 +0.08112500000000001 -0.462890625 -0.2319929199218749 +0.08125 -0.458831787109375 -0.2319929199218749 +0.08137499999999999 -0.454559326171875 -0.2319929199218749 +0.0815 -0.450103759765625 -0.2319929199218749 +0.081625 -0.4454345703125 -0.2319929199218749 +0.08175000000000001 -0.440582275390625 -0.2319929199218749 +0.081875 -0.435546875 -0.2319929199218749 +0.08200000000000001 -0.4302978515625 -0.2319929199218749 +0.082125 -0.424896240234375 -0.2319929199218749 +0.08225 -0.419281005859375 -0.2319929199218749 +0.08237500000000001 -0.413482666015625 -0.2319929199218749 +0.0825 -0.407501220703125 -0.2319929199218749 +0.08262500000000001 -0.401336669921875 -0.2319929199218749 +0.08275 -0.39501953125 -0.2319929199218749 +0.08287500000000001 -0.388519287109375 -0.2319929199218749 +0.08300000000000001 -0.3818359375 -0.2319929199218749 +0.083125 -0.375 -0.2319929199218749 +0.08324999999999999 -0.36798095703125 -0.2319929199218749 +0.083375 -0.360809326171875 -0.2319929199218749 +0.08350000000000001 -0.353485107421875 -0.2319929199218749 +0.08362500000000001 -0.34222412109375 -0.2319929199218749 +0.08375 -0.334503173828125 -0.2319929199218749 +0.08387500000000001 -0.32666015625 -0.2319929199218749 +0.084 -0.31866455078125 -0.2319929199218749 +0.08412500000000001 -0.310516357421875 -0.2319929199218749 +0.08425000000000001 -0.30224609375 -0.2319929199218749 +0.084375 -0.2938232421875 -0.2319929199218749 +0.08450000000000001 -0.285308837890625 -0.2319929199218749 +0.084625 -0.276641845703125 -0.2319929199218749 +0.08475 -0.267852783203125 -0.2319929199218749 +0.08487500000000001 -0.25897216796875 -0.2319929199218749 +0.085 -0.249969482421875 -0.2319929199218749 +0.08512500000000001 -0.2408447265625 -0.2319929199218749 +0.08525 -0.231597900390625 -0.2319929199218749 +0.085375 -0.2222900390625 -0.2319929199218749 +0.08550000000000001 -0.212860107421875 -0.2319929199218749 +0.085625 -0.203338623046875 -0.2319929199218749 +0.08575000000000001 -0.1937255859375 -0.2319929199218749 +0.08587500000000002 -0.18402099609375 -0.2319929199218749 +0.08600000000000001 -0.17425537109375 -0.2319929199218749 +0.08612500000000001 -0.164398193359375 -0.2319929199218749 +0.08625 -0.15447998046875 -0.2319929199218749 +0.08637499999999999 -0.14447021484375 -0.2319929199218749 +0.0865 -0.129364013671875 -0.2319929199218749 +0.08662500000000001 -0.119232177734375 -0.2319929199218749 +0.08675000000000001 -0.109039306640625 -0.2319929199218749 +0.08687500000000002 -0.098785400390625 -0.2319929199218749 +0.08700000000000001 -0.0885009765625 -0.2319929199218749 +0.087125 -0.07818603515625 -0.2319929199218749 +0.08725000000000001 -0.06781005859375 -0.2319929199218749 +0.08737500000000001 -0.05743408203125 -0.2319929199218749 +0.08750000000000002 -0.047027587890625 -0.2319929199218749 +0.08762500000000001 -0.036590576171875 -0.2319929199218749 +0.08775 -0.026123046875 -0.2319929199218749 +0.08787500000000001 -0.01568603515625 -0.2319929199218749 +0.08799999999999999 -0.005218505859375 -0.2319929199218749 0.088125 0.005218505859375 -0.2319929199218749 0.08824999999999999 0.01568603515625 -0.2319929199218749 0.08837499999999999 0.026123046875 -0.2319929199218749 @@ -836,129 +836,129 @@ 0.104375 0.0313720703125 0.02399926757812504 0.1045 0.020904541015625 0.02399926757812504 0.104625 0.005218505859375 0.02399926757812504 -0.10475 -0.0052490234375 0.02399926757812504 -0.104875 -0.02093505859375 0.02399926757812504 -0.105 -0.031402587890625 0.02399926757812504 -0.105125 -0.041839599609375 0.02399926757812504 -0.10525 -0.057464599609375 0.02399926757812504 -0.105375 -0.067840576171875 0.02399926757812504 -0.1055 -0.0833740234375 0.02399926757812504 -0.105625 -0.09368896484375 0.02399926757812504 -0.10575 -0.10906982421875 0.02399926757812504 -0.105875 -0.1192626953125 0.02399926757812504 -0.106 -0.13446044921875 0.02399926757812504 -0.106125 -0.144500732421875 0.02399926757812504 -0.10625 -0.154510498046875 0.02399926757812504 -0.106375 -0.16937255859375 0.02399926757812504 -0.1065 -0.179168701171875 0.02399926757812504 -0.106625 -0.193756103515625 0.02399926757812504 -0.10675 -0.203369140625 0.02399926757812504 -0.106875 -0.217620849609375 0.02399926757812504 -0.107 -0.22698974609375 0.02399926757812504 -0.107125 -0.240875244140625 0.02399926757812504 -0.10725 -0.25 0.02399926757812504 -0.107375 -0.259002685546875 0.02399926757812504 -0.1075 -0.272308349609375 0.02399926757812504 -0.107625 -0.281005859375 0.02399926757812504 -0.10775 -0.293853759765625 0.02399926757812504 -0.107875 -0.302276611328125 0.02399926757812504 -0.108 -0.31463623046875 0.02399926757812504 -0.108125 -0.32269287109375 0.02399926757812504 -0.10825 -0.33062744140625 0.02399926757812504 -0.108375 -0.342254638671875 0.02399926757812504 -0.1085 -0.34979248046875 0.02399926757812504 -0.108625 -0.36083984375 0.02399926757812504 -0.10875 -0.368011474609375 0.02399926757812504 -0.108875 -0.37847900390625 0.02399926757812504 -0.109 -0.385223388671875 0.02399926757812504 -0.109125 -0.395050048828125 0.02399926757812504 -0.10925 -0.4013671875 0.02399926757812504 -0.109375 -0.40753173828125 0.02399926757812504 -0.1095 -0.41644287109375 0.02399926757812504 -0.109625 -0.422149658203125 0.02399926757812504 -0.10975 -0.430328369140625 0.02399926757812504 -0.109875 -0.435577392578125 0.02399926757812504 -0.11 -0.443084716796875 0.02399926757812504 -0.110125 -0.44781494140625 0.02399926757812504 -0.11025 -0.45458984375 0.02399926757812504 -0.110375 -0.4588623046875 0.02399926757812504 -0.1105 -0.462921142578125 0.02399926757812504 -0.110625 -0.468597412109375 0.02399926757812504 -0.11075 -0.47216796875 0.02399926757812504 -0.110875 -0.477081298828125 0.02399926757812504 -0.111 -0.4801025390625 0.02399926757812504 -0.111125 -0.4842529296875 0.02399926757812504 -0.11125 -0.48675537109375 0.02399926757812504 -0.111375 -0.4901123046875 0.02399926757812504 -0.1115 -0.4920654296875 0.02399926757812504 -0.111625 -0.493804931640625 0.02399926757812504 -0.11175 -0.49603271484375 0.02399926757812504 -0.111875 -0.497222900390625 0.02399926757812504 -0.112 -0.498626708984375 0.02399926757812504 -0.112125 -0.499298095703125 0.02399926757812504 -0.11225 -0.499847412109375 0.02399926757812504 -0.112375 -0.499969482421875 0.02399926757812504 -0.1125 -0.499847412109375 0.02399926757812504 -0.112625 -0.499298095703125 0.02399926757812504 -0.11275 -0.498626708984375 0.02399926757812504 -0.112875 -0.497222900390625 0.02399926757812504 -0.113 -0.49603271484375 0.02399926757812504 -0.113125 -0.493804931640625 0.02399926757812504 -0.11325 -0.4920654296875 0.02399926757812504 -0.113375 -0.489044189453125 0.02399926757812504 -0.1135 -0.48675537109375 0.02399926757812504 -0.113625 -0.4842529296875 0.02399926757812504 -0.11375 -0.4801025390625 0.02399926757812504 -0.113875 -0.477081298828125 0.02399926757812504 -0.114 -0.47216796875 0.02399926757812504 -0.114125 -0.468597412109375 0.02399926757812504 -0.11425 -0.462921142578125 0.02399926757812504 -0.114375 -0.4588623046875 0.02399926757812504 -0.1145 -0.452392578125 0.02399926757812504 -0.114625 -0.44781494140625 0.02399926757812504 -0.11475 -0.443084716796875 0.02399926757812504 -0.114875 -0.435577392578125 0.02399926757812504 -0.115 -0.430328369140625 0.02399926757812504 -0.115125 -0.422149658203125 0.02399926757812504 -0.11525 -0.41644287109375 0.02399926757812504 -0.115375 -0.40753173828125 0.02399926757812504 -0.1155 -0.4013671875 0.02399926757812504 -0.115625 -0.391815185546875 0.02399926757812504 -0.11575 -0.385223388671875 0.02399926757812504 -0.115875 -0.37847900390625 0.02399926757812504 -0.116 -0.368011474609375 0.02399926757812504 -0.116125 -0.36083984375 0.02399926757812504 -0.11625 -0.34979248046875 0.02399926757812504 -0.116375 -0.342254638671875 0.02399926757812504 -0.1165 -0.33062744140625 0.02399926757812504 -0.116625 -0.32269287109375 0.02399926757812504 -0.11675 -0.31463623046875 0.02399926757812504 -0.116875 -0.302276611328125 0.02399926757812504 -0.117 -0.293853759765625 0.02399926757812504 -0.117125 -0.281005859375 0.02399926757812504 -0.11725 -0.272308349609375 0.02399926757812504 -0.117375 -0.259002685546875 0.02399926757812504 -0.1175 -0.25 0.02399926757812504 -0.117625 -0.23626708984375 0.02399926757812504 -0.11775 -0.22698974609375 0.02399926757812504 -0.117875 -0.217620849609375 0.02399926757812504 -0.118 -0.203369140625 0.02399926757812504 -0.118125 -0.193756103515625 0.02399926757812504 -0.11825 -0.179168701171875 0.02399926757812504 -0.118375 -0.16937255859375 0.02399926757812504 -0.1185 -0.154510498046875 0.02399926757812504 -0.118625 -0.144500732421875 0.02399926757812504 -0.11875 -0.12939453125 0.02399926757812504 -0.118875 -0.1192626953125 0.02399926757812504 -0.119 -0.10906982421875 0.02399926757812504 -0.119125 -0.09368896484375 0.02399926757812504 -0.11925 -0.0833740234375 0.02399926757812504 -0.119375 -0.067840576171875 0.02399926757812504 -0.1195 -0.057464599609375 0.02399926757812504 -0.119625 -0.041839599609375 0.02399926757812504 -0.11975 -0.031402587890625 0.02399926757812504 -0.119875 -0.015716552734375 0.02399926757812504 -0.12 -0.0052490234375 0.02399926757812504 +0.10475 -0.005218505859375 0.02399926757812504 +0.104875 -0.020904541015625 0.02399926757812504 +0.105 -0.0313720703125 0.02399926757812504 +0.105125 -0.04180908203125 0.02399926757812504 +0.10525 -0.05743408203125 0.02399926757812504 +0.105375 -0.06781005859375 0.02399926757812504 +0.1055 -0.083343505859375 0.02399926757812504 +0.105625 -0.093658447265625 0.02399926757812504 +0.10575 -0.109039306640625 0.02399926757812504 +0.105875 -0.119232177734375 0.02399926757812504 +0.106 -0.134429931640625 0.02399926757812504 +0.106125 -0.14447021484375 0.02399926757812504 +0.10625 -0.15447998046875 0.02399926757812504 +0.106375 -0.169342041015625 0.02399926757812504 +0.1065 -0.17913818359375 0.02399926757812504 +0.106625 -0.1937255859375 0.02399926757812504 +0.10675 -0.203338623046875 0.02399926757812504 +0.106875 -0.21759033203125 0.02399926757812504 +0.107 -0.226959228515625 0.02399926757812504 +0.107125 -0.2408447265625 0.02399926757812504 +0.10725 -0.249969482421875 0.02399926757812504 +0.107375 -0.25897216796875 0.02399926757812504 +0.1075 -0.27227783203125 0.02399926757812504 +0.107625 -0.280975341796875 0.02399926757812504 +0.10775 -0.2938232421875 0.02399926757812504 +0.107875 -0.30224609375 0.02399926757812504 +0.108 -0.314605712890625 0.02399926757812504 +0.108125 -0.322662353515625 0.02399926757812504 +0.10825 -0.330596923828125 0.02399926757812504 +0.108375 -0.34222412109375 0.02399926757812504 +0.1085 -0.349761962890625 0.02399926757812504 +0.108625 -0.360809326171875 0.02399926757812504 +0.10875 -0.36798095703125 0.02399926757812504 +0.108875 -0.378448486328125 0.02399926757812504 +0.109 -0.38519287109375 0.02399926757812504 +0.109125 -0.39501953125 0.02399926757812504 +0.10925 -0.401336669921875 0.02399926757812504 +0.109375 -0.407501220703125 0.02399926757812504 +0.1095 -0.416412353515625 0.02399926757812504 +0.109625 -0.422119140625 0.02399926757812504 +0.10975 -0.4302978515625 0.02399926757812504 +0.109875 -0.435546875 0.02399926757812504 +0.11 -0.44305419921875 0.02399926757812504 +0.110125 -0.447784423828125 0.02399926757812504 +0.11025 -0.454559326171875 0.02399926757812504 +0.110375 -0.458831787109375 0.02399926757812504 +0.1105 -0.462890625 0.02399926757812504 +0.110625 -0.46856689453125 0.02399926757812504 +0.11075 -0.472137451171875 0.02399926757812504 +0.110875 -0.47705078125 0.02399926757812504 +0.111 -0.480072021484375 0.02399926757812504 +0.111125 -0.484222412109375 0.02399926757812504 +0.11125 -0.486724853515625 0.02399926757812504 +0.111375 -0.490081787109375 0.02399926757812504 +0.1115 -0.492034912109375 0.02399926757812504 +0.111625 -0.4937744140625 0.02399926757812504 +0.11175 -0.496002197265625 0.02399926757812504 +0.111875 -0.4971923828125 0.02399926757812504 +0.112 -0.49859619140625 0.02399926757812504 +0.112125 -0.499267578125 0.02399926757812504 +0.11225 -0.49981689453125 0.02399926757812504 +0.112375 -0.49993896484375 0.02399926757812504 +0.1125 -0.49981689453125 0.02399926757812504 +0.112625 -0.499267578125 0.02399926757812504 +0.11275 -0.49859619140625 0.02399926757812504 +0.112875 -0.4971923828125 0.02399926757812504 +0.113 -0.496002197265625 0.02399926757812504 +0.113125 -0.4937744140625 0.02399926757812504 +0.11325 -0.492034912109375 0.02399926757812504 +0.113375 -0.489013671875 0.02399926757812504 +0.1135 -0.486724853515625 0.02399926757812504 +0.113625 -0.484222412109375 0.02399926757812504 +0.11375 -0.480072021484375 0.02399926757812504 +0.113875 -0.47705078125 0.02399926757812504 +0.114 -0.472137451171875 0.02399926757812504 +0.114125 -0.46856689453125 0.02399926757812504 +0.11425 -0.462890625 0.02399926757812504 +0.114375 -0.458831787109375 0.02399926757812504 +0.1145 -0.452362060546875 0.02399926757812504 +0.114625 -0.447784423828125 0.02399926757812504 +0.11475 -0.44305419921875 0.02399926757812504 +0.114875 -0.435546875 0.02399926757812504 +0.115 -0.4302978515625 0.02399926757812504 +0.115125 -0.422119140625 0.02399926757812504 +0.11525 -0.416412353515625 0.02399926757812504 +0.115375 -0.407501220703125 0.02399926757812504 +0.1155 -0.401336669921875 0.02399926757812504 +0.115625 -0.39178466796875 0.02399926757812504 +0.11575 -0.38519287109375 0.02399926757812504 +0.115875 -0.378448486328125 0.02399926757812504 +0.116 -0.36798095703125 0.02399926757812504 +0.116125 -0.360809326171875 0.02399926757812504 +0.11625 -0.349761962890625 0.02399926757812504 +0.116375 -0.34222412109375 0.02399926757812504 +0.1165 -0.330596923828125 0.02399926757812504 +0.116625 -0.322662353515625 0.02399926757812504 +0.11675 -0.314605712890625 0.02399926757812504 +0.116875 -0.30224609375 0.02399926757812504 +0.117 -0.2938232421875 0.02399926757812504 +0.117125 -0.280975341796875 0.02399926757812504 +0.11725 -0.27227783203125 0.02399926757812504 +0.117375 -0.25897216796875 0.02399926757812504 +0.1175 -0.249969482421875 0.02399926757812504 +0.117625 -0.236236572265625 0.02399926757812504 +0.11775 -0.226959228515625 0.02399926757812504 +0.117875 -0.21759033203125 0.02399926757812504 +0.118 -0.203338623046875 0.02399926757812504 +0.118125 -0.1937255859375 0.02399926757812504 +0.11825 -0.17913818359375 0.02399926757812504 +0.118375 -0.169342041015625 0.02399926757812504 +0.1185 -0.15447998046875 0.02399926757812504 +0.118625 -0.14447021484375 0.02399926757812504 +0.11875 -0.129364013671875 0.02399926757812504 +0.118875 -0.119232177734375 0.02399926757812504 +0.119 -0.109039306640625 0.02399926757812504 +0.119125 -0.093658447265625 0.02399926757812504 +0.11925 -0.083343505859375 0.02399926757812504 +0.119375 -0.06781005859375 0.02399926757812504 +0.1195 -0.05743408203125 0.02399926757812504 +0.119625 -0.04180908203125 0.02399926757812504 +0.11975 -0.0313720703125 0.02399926757812504 +0.119875 -0.01568603515625 0.02399926757812504 +0.12 -0.005218505859375 0.02399926757812504 0.120125 0.005218505859375 0.02399926757812504 0.12025 0.020904541015625 0.02399926757812504 0.120375 0.0313720703125 0.02399926757812504 @@ -1072,109 +1072,109 @@ 0.133875 0.036590576171875 0.2799914550781251 0.134 0.020904541015625 0.2799914550781251 0.134125 0.01043701171875 0.2799914550781251 -0.13425 -0.0052490234375 0.2799914550781251 -0.134375 -0.02093505859375 0.2799914550781251 -0.1345 -0.03662109375 0.2799914550781251 -0.134625 -0.052276611328125 0.2799914550781251 -0.13475 -0.067840576171875 0.2799914550781251 -0.134875 -0.0833740234375 0.2799914550781251 -0.135 -0.09881591796875 0.2799914550781251 -0.135125 -0.114166259765625 0.2799914550781251 -0.13525 -0.12939453125 0.2799914550781251 -0.135375 -0.144500732421875 0.2799914550781251 -0.1355 -0.15948486328125 0.2799914550781251 -0.135625 -0.16937255859375 0.2799914550781251 -0.13575 -0.184051513671875 0.2799914550781251 -0.135875 -0.198577880859375 0.2799914550781251 -0.136 -0.212890625 0.2799914550781251 -0.136125 -0.22698974609375 0.2799914550781251 -0.13625 -0.240875244140625 0.2799914550781251 -0.136375 -0.254486083984375 0.2799914550781251 -0.1365 -0.26788330078125 0.2799914550781251 -0.136625 -0.281005859375 0.2799914550781251 -0.13675 -0.293853759765625 0.2799914550781251 -0.136875 -0.306427001953125 0.2799914550781251 -0.137 -0.318695068359375 0.2799914550781251 -0.137125 -0.326690673828125 0.2799914550781251 -0.13725 -0.338409423828125 0.2799914550781251 -0.137375 -0.34979248046875 0.2799914550781251 -0.1375 -0.36083984375 0.2799914550781251 -0.137625 -0.371551513671875 0.2799914550781251 -0.13775 -0.381866455078125 0.2799914550781251 -0.137875 -0.391815185546875 0.2799914550781251 -0.138 -0.4013671875 0.2799914550781251 -0.138125 -0.410552978515625 0.2799914550781251 -0.13825 -0.4193115234375 0.2799914550781251 -0.138375 -0.427642822265625 0.2799914550781251 -0.1385 -0.435577392578125 0.2799914550781251 -0.138625 -0.44061279296875 0.2799914550781251 -0.13875 -0.44781494140625 0.2799914550781251 -0.138875 -0.45458984375 0.2799914550781251 -0.139 -0.460906982421875 0.2799914550781251 -0.139125 -0.466766357421875 0.2799914550781251 -0.13925 -0.47216796875 0.2799914550781251 -0.139375 -0.477081298828125 0.2799914550781251 -0.1395 -0.481536865234375 0.2799914550781251 -0.139625 -0.48553466796875 0.2799914550781251 -0.13975 -0.489044189453125 0.2799914550781251 -0.139875 -0.4920654296875 0.2799914550781251 -0.14 -0.493804931640625 0.2799914550781251 -0.140125 -0.49603271484375 0.2799914550781251 -0.14025 -0.49774169921875 0.2799914550781251 -0.140375 -0.498992919921875 0.2799914550781251 -0.1405 -0.499725341796875 0.2799914550781251 -0.140625 -0.499969482421875 0.2799914550781251 -0.14075 -0.499725341796875 0.2799914550781251 -0.140875 -0.498992919921875 0.2799914550781251 -0.141 -0.49774169921875 0.2799914550781251 -0.141125 -0.49603271484375 0.2799914550781251 -0.14125 -0.493804931640625 0.2799914550781251 -0.141375 -0.491119384765625 0.2799914550781251 -0.1415 -0.489044189453125 0.2799914550781251 -0.141625 -0.48553466796875 0.2799914550781251 -0.14175 -0.481536865234375 0.2799914550781251 -0.141875 -0.477081298828125 0.2799914550781251 -0.142 -0.47216796875 0.2799914550781251 -0.142125 -0.466766357421875 0.2799914550781251 -0.14225 -0.460906982421875 0.2799914550781251 -0.142375 -0.45458984375 0.2799914550781251 -0.1425 -0.44781494140625 0.2799914550781251 -0.142625 -0.44061279296875 0.2799914550781251 -0.14275 -0.4329833984375 0.2799914550781251 -0.142875 -0.4249267578125 0.2799914550781251 -0.143 -0.4193115234375 0.2799914550781251 -0.143125 -0.410552978515625 0.2799914550781251 -0.14325 -0.4013671875 0.2799914550781251 -0.143375 -0.391815185546875 0.2799914550781251 -0.1435 -0.381866455078125 0.2799914550781251 -0.143625 -0.371551513671875 0.2799914550781251 -0.14375 -0.36083984375 0.2799914550781251 -0.143875 -0.34979248046875 0.2799914550781251 -0.144 -0.338409423828125 0.2799914550781251 -0.144125 -0.326690673828125 0.2799914550781251 -0.14425 -0.31463623046875 0.2799914550781251 -0.144375 -0.302276611328125 0.2799914550781251 -0.1445 -0.293853759765625 0.2799914550781251 -0.144625 -0.281005859375 0.2799914550781251 -0.14475 -0.26788330078125 0.2799914550781251 -0.144875 -0.254486083984375 0.2799914550781251 -0.145 -0.240875244140625 0.2799914550781251 -0.145125 -0.22698974609375 0.2799914550781251 -0.14525 -0.212890625 0.2799914550781251 -0.145375 -0.198577880859375 0.2799914550781251 -0.1455 -0.184051513671875 0.2799914550781251 -0.145625 -0.16937255859375 0.2799914550781251 -0.14575 -0.154510498046875 0.2799914550781251 -0.145875 -0.139495849609375 0.2799914550781251 -0.146 -0.12939453125 0.2799914550781251 -0.146125 -0.114166259765625 0.2799914550781251 -0.14625 -0.09881591796875 0.2799914550781251 -0.146375 -0.0833740234375 0.2799914550781251 -0.1465 -0.067840576171875 0.2799914550781251 -0.146625 -0.052276611328125 0.2799914550781251 -0.14675 -0.03662109375 0.2799914550781251 -0.146875 -0.02093505859375 0.2799914550781251 -0.147 -0.0052490234375 0.2799914550781251 +0.13425 -0.005218505859375 0.2799914550781251 +0.134375 -0.020904541015625 0.2799914550781251 +0.1345 -0.036590576171875 0.2799914550781251 +0.134625 -0.05224609375 0.2799914550781251 +0.13475 -0.06781005859375 0.2799914550781251 +0.134875 -0.083343505859375 0.2799914550781251 +0.135 -0.098785400390625 0.2799914550781251 +0.135125 -0.1141357421875 0.2799914550781251 +0.13525 -0.129364013671875 0.2799914550781251 +0.135375 -0.14447021484375 0.2799914550781251 +0.1355 -0.159454345703125 0.2799914550781251 +0.135625 -0.169342041015625 0.2799914550781251 +0.13575 -0.18402099609375 0.2799914550781251 +0.135875 -0.19854736328125 0.2799914550781251 +0.136 -0.212860107421875 0.2799914550781251 +0.136125 -0.226959228515625 0.2799914550781251 +0.13625 -0.2408447265625 0.2799914550781251 +0.136375 -0.25445556640625 0.2799914550781251 +0.1365 -0.267852783203125 0.2799914550781251 +0.136625 -0.280975341796875 0.2799914550781251 +0.13675 -0.2938232421875 0.2799914550781251 +0.136875 -0.306396484375 0.2799914550781251 +0.137 -0.31866455078125 0.2799914550781251 +0.137125 -0.32666015625 0.2799914550781251 +0.13725 -0.33837890625 0.2799914550781251 +0.137375 -0.349761962890625 0.2799914550781251 +0.1375 -0.360809326171875 0.2799914550781251 +0.137625 -0.37152099609375 0.2799914550781251 +0.13775 -0.3818359375 0.2799914550781251 +0.137875 -0.39178466796875 0.2799914550781251 +0.138 -0.401336669921875 0.2799914550781251 +0.138125 -0.4105224609375 0.2799914550781251 +0.13825 -0.419281005859375 0.2799914550781251 +0.138375 -0.4276123046875 0.2799914550781251 +0.1385 -0.435546875 0.2799914550781251 +0.138625 -0.440582275390625 0.2799914550781251 +0.13875 -0.447784423828125 0.2799914550781251 +0.138875 -0.454559326171875 0.2799914550781251 +0.139 -0.46087646484375 0.2799914550781251 +0.139125 -0.46673583984375 0.2799914550781251 +0.13925 -0.472137451171875 0.2799914550781251 +0.139375 -0.47705078125 0.2799914550781251 +0.1395 -0.48150634765625 0.2799914550781251 +0.139625 -0.485504150390625 0.2799914550781251 +0.13975 -0.489013671875 0.2799914550781251 +0.139875 -0.492034912109375 0.2799914550781251 +0.14 -0.4937744140625 0.2799914550781251 +0.140125 -0.496002197265625 0.2799914550781251 +0.14025 -0.497711181640625 0.2799914550781251 +0.140375 -0.49896240234375 0.2799914550781251 +0.1405 -0.49969482421875 0.2799914550781251 +0.140625 -0.49993896484375 0.2799914550781251 +0.14075 -0.49969482421875 0.2799914550781251 +0.140875 -0.49896240234375 0.2799914550781251 +0.141 -0.497711181640625 0.2799914550781251 +0.141125 -0.496002197265625 0.2799914550781251 +0.14125 -0.4937744140625 0.2799914550781251 +0.141375 -0.4910888671875 0.2799914550781251 +0.1415 -0.489013671875 0.2799914550781251 +0.141625 -0.485504150390625 0.2799914550781251 +0.14175 -0.48150634765625 0.2799914550781251 +0.141875 -0.47705078125 0.2799914550781251 +0.142 -0.472137451171875 0.2799914550781251 +0.142125 -0.46673583984375 0.2799914550781251 +0.14225 -0.46087646484375 0.2799914550781251 +0.142375 -0.454559326171875 0.2799914550781251 +0.1425 -0.447784423828125 0.2799914550781251 +0.142625 -0.440582275390625 0.2799914550781251 +0.14275 -0.432952880859375 0.2799914550781251 +0.142875 -0.424896240234375 0.2799914550781251 +0.143 -0.419281005859375 0.2799914550781251 +0.143125 -0.4105224609375 0.2799914550781251 +0.14325 -0.401336669921875 0.2799914550781251 +0.143375 -0.39178466796875 0.2799914550781251 +0.1435 -0.3818359375 0.2799914550781251 +0.143625 -0.37152099609375 0.2799914550781251 +0.14375 -0.360809326171875 0.2799914550781251 +0.143875 -0.349761962890625 0.2799914550781251 +0.144 -0.33837890625 0.2799914550781251 +0.144125 -0.32666015625 0.2799914550781251 +0.14425 -0.314605712890625 0.2799914550781251 +0.144375 -0.30224609375 0.2799914550781251 +0.1445 -0.2938232421875 0.2799914550781251 +0.144625 -0.280975341796875 0.2799914550781251 +0.14475 -0.267852783203125 0.2799914550781251 +0.144875 -0.25445556640625 0.2799914550781251 +0.145 -0.2408447265625 0.2799914550781251 +0.145125 -0.226959228515625 0.2799914550781251 +0.14525 -0.212860107421875 0.2799914550781251 +0.145375 -0.19854736328125 0.2799914550781251 +0.1455 -0.18402099609375 0.2799914550781251 +0.145625 -0.169342041015625 0.2799914550781251 +0.14575 -0.15447998046875 0.2799914550781251 +0.145875 -0.13946533203125 0.2799914550781251 +0.146 -0.129364013671875 0.2799914550781251 +0.146125 -0.1141357421875 0.2799914550781251 +0.14625 -0.098785400390625 0.2799914550781251 +0.146375 -0.083343505859375 0.2799914550781251 +0.1465 -0.06781005859375 0.2799914550781251 +0.146625 -0.05224609375 0.2799914550781251 +0.14675 -0.036590576171875 0.2799914550781251 +0.146875 -0.020904541015625 0.2799914550781251 +0.147 -0.005218505859375 0.2799914550781251 0.147125 0.01043701171875 0.2799914550781251 0.14725 0.026123046875 0.2799914550781251 0.147375 0.036590576171875 0.2799914550781251 @@ -1278,92 +1278,92 @@ 0.159625 0.036590576171875 0.2799914550781251 0.15975 0.020904541015625 0.2799914550781251 0.159875 0.005218505859375 0.2799914550781251 -0.16 -0.010467529296875 0.535983642578125 -0.160125 -0.031402587890625 0.535983642578125 -0.16025 -0.04705810546875 0.535983642578125 -0.160375 -0.067840576171875 0.535983642578125 -0.1605 -0.0833740234375 0.535983642578125 -0.160625 -0.10394287109375 0.535983642578125 -0.16075 -0.1192626953125 0.535983642578125 -0.160875 -0.139495849609375 0.535983642578125 -0.161 -0.154510498046875 0.535983642578125 -0.161125 -0.174285888671875 0.535983642578125 -0.16125 -0.18890380859375 0.535983642578125 -0.161375 -0.2081298828125 0.535983642578125 -0.1615 -0.222320556640625 0.535983642578125 -0.161625 -0.240875244140625 0.535983642578125 -0.16175 -0.254486083984375 0.535983642578125 -0.161875 -0.272308349609375 0.535983642578125 -0.162 -0.28533935546875 0.535983642578125 -0.162125 -0.302276611328125 0.535983642578125 -0.16225 -0.31463623046875 0.535983642578125 -0.162375 -0.33062744140625 0.535983642578125 -0.1625 -0.342254638671875 0.535983642578125 -0.162625 -0.357208251953125 0.535983642578125 -0.16275 -0.368011474609375 0.535983642578125 -0.162875 -0.381866455078125 0.535983642578125 -0.163 -0.391815185546875 0.535983642578125 -0.163125 -0.40447998046875 0.535983642578125 -0.16325 -0.41351318359375 0.535983642578125 -0.163375 -0.422149658203125 0.535983642578125 -0.1635 -0.4329833984375 0.535983642578125 -0.163625 -0.44061279296875 0.535983642578125 -0.16375 -0.45013427734375 0.535983642578125 -0.163875 -0.456756591796875 0.535983642578125 -0.164 -0.46484375 0.535983642578125 -0.164125 -0.47039794921875 0.535983642578125 -0.16425 -0.477081298828125 0.535983642578125 -0.164375 -0.481536865234375 0.535983642578125 -0.1645 -0.48675537109375 0.535983642578125 -0.164625 -0.4901123046875 0.535983642578125 -0.16475 -0.493804931640625 0.535983642578125 -0.164875 -0.49603271484375 0.535983642578125 -0.165 -0.49822998046875 0.535983642578125 -0.165125 -0.499298095703125 0.535983642578125 -0.16525 -0.49993896484375 0.535983642578125 -0.165375 -0.499847412109375 0.535983642578125 -0.1655 -0.498992919921875 0.535983642578125 -0.165625 -0.49774169921875 0.535983642578125 -0.16575 -0.495330810546875 0.535983642578125 -0.165875 -0.49298095703125 0.535983642578125 -0.166 -0.489044189453125 0.535983642578125 -0.166125 -0.48553466796875 0.535983642578125 -0.16625 -0.4801025390625 0.535983642578125 -0.166375 -0.475494384765625 0.535983642578125 -0.1665 -0.468597412109375 0.535983642578125 -0.166625 -0.462921142578125 0.535983642578125 -0.16675 -0.456756591796875 0.535983642578125 -0.166875 -0.44781494140625 0.535983642578125 -0.167 -0.44061279296875 0.535983642578125 -0.167125 -0.430328369140625 0.535983642578125 -0.16725 -0.422149658203125 0.535983642578125 -0.167375 -0.410552978515625 0.535983642578125 -0.1675 -0.4013671875 0.535983642578125 -0.167625 -0.3885498046875 0.535983642578125 -0.16775 -0.37847900390625 0.535983642578125 -0.167875 -0.364471435546875 0.535983642578125 -0.168 -0.353515625 0.535983642578125 -0.168125 -0.338409423828125 0.535983642578125 -0.16825 -0.326690673828125 0.535983642578125 -0.168375 -0.310546875 0.535983642578125 -0.1685 -0.298095703125 0.535983642578125 -0.168625 -0.281005859375 0.535983642578125 -0.16875 -0.26788330078125 0.535983642578125 -0.168875 -0.25 0.535983642578125 -0.169 -0.23626708984375 0.535983642578125 -0.169125 -0.217620849609375 0.535983642578125 -0.16925 -0.203369140625 0.535983642578125 -0.169375 -0.184051513671875 0.535983642578125 -0.1695 -0.16937255859375 0.535983642578125 -0.169625 -0.149505615234375 0.535983642578125 -0.16975 -0.13446044921875 0.535983642578125 -0.169875 -0.1192626953125 0.535983642578125 -0.17 -0.09881591796875 0.535983642578125 -0.170125 -0.0833740234375 0.535983642578125 -0.17025 -0.062652587890625 0.535983642578125 -0.170375 -0.04705810546875 0.535983642578125 -0.1705 -0.026153564453125 0.535983642578125 -0.170625 -0.010467529296875 0.535983642578125 +0.16 -0.01043701171875 0.535983642578125 +0.160125 -0.0313720703125 0.535983642578125 +0.16025 -0.047027587890625 0.535983642578125 +0.160375 -0.06781005859375 0.535983642578125 +0.1605 -0.083343505859375 0.535983642578125 +0.160625 -0.103912353515625 0.535983642578125 +0.16075 -0.119232177734375 0.535983642578125 +0.160875 -0.13946533203125 0.535983642578125 +0.161 -0.15447998046875 0.535983642578125 +0.161125 -0.17425537109375 0.535983642578125 +0.16125 -0.188873291015625 0.535983642578125 +0.161375 -0.208099365234375 0.535983642578125 +0.1615 -0.2222900390625 0.535983642578125 +0.161625 -0.2408447265625 0.535983642578125 +0.16175 -0.25445556640625 0.535983642578125 +0.161875 -0.27227783203125 0.535983642578125 +0.162 -0.285308837890625 0.535983642578125 +0.162125 -0.30224609375 0.535983642578125 +0.16225 -0.314605712890625 0.535983642578125 +0.162375 -0.330596923828125 0.535983642578125 +0.1625 -0.34222412109375 0.535983642578125 +0.162625 -0.357177734375 0.535983642578125 +0.16275 -0.36798095703125 0.535983642578125 +0.162875 -0.3818359375 0.535983642578125 +0.163 -0.39178466796875 0.535983642578125 +0.163125 -0.404449462890625 0.535983642578125 +0.16325 -0.413482666015625 0.535983642578125 +0.163375 -0.422119140625 0.535983642578125 +0.1635 -0.432952880859375 0.535983642578125 +0.163625 -0.440582275390625 0.535983642578125 +0.16375 -0.450103759765625 0.535983642578125 +0.163875 -0.45672607421875 0.535983642578125 +0.164 -0.464813232421875 0.535983642578125 +0.164125 -0.470367431640625 0.535983642578125 +0.16425 -0.47705078125 0.535983642578125 +0.164375 -0.48150634765625 0.535983642578125 +0.1645 -0.486724853515625 0.535983642578125 +0.164625 -0.490081787109375 0.535983642578125 +0.16475 -0.4937744140625 0.535983642578125 +0.164875 -0.496002197265625 0.535983642578125 +0.165 -0.498199462890625 0.535983642578125 +0.165125 -0.499267578125 0.535983642578125 +0.16525 -0.499908447265625 0.535983642578125 +0.165375 -0.49981689453125 0.535983642578125 +0.1655 -0.49896240234375 0.535983642578125 +0.165625 -0.497711181640625 0.535983642578125 +0.16575 -0.49530029296875 0.535983642578125 +0.165875 -0.492950439453125 0.535983642578125 +0.166 -0.489013671875 0.535983642578125 +0.166125 -0.485504150390625 0.535983642578125 +0.16625 -0.480072021484375 0.535983642578125 +0.166375 -0.4754638671875 0.535983642578125 +0.1665 -0.46856689453125 0.535983642578125 +0.166625 -0.462890625 0.535983642578125 +0.16675 -0.45672607421875 0.535983642578125 +0.166875 -0.447784423828125 0.535983642578125 +0.167 -0.440582275390625 0.535983642578125 +0.167125 -0.4302978515625 0.535983642578125 +0.16725 -0.422119140625 0.535983642578125 +0.167375 -0.4105224609375 0.535983642578125 +0.1675 -0.401336669921875 0.535983642578125 +0.167625 -0.388519287109375 0.535983642578125 +0.16775 -0.378448486328125 0.535983642578125 +0.167875 -0.36444091796875 0.535983642578125 +0.168 -0.353485107421875 0.535983642578125 +0.168125 -0.33837890625 0.535983642578125 +0.16825 -0.32666015625 0.535983642578125 +0.168375 -0.310516357421875 0.535983642578125 +0.1685 -0.298065185546875 0.535983642578125 +0.168625 -0.280975341796875 0.535983642578125 +0.16875 -0.267852783203125 0.535983642578125 +0.168875 -0.249969482421875 0.535983642578125 +0.169 -0.236236572265625 0.535983642578125 +0.169125 -0.21759033203125 0.535983642578125 +0.16925 -0.203338623046875 0.535983642578125 +0.169375 -0.18402099609375 0.535983642578125 +0.1695 -0.169342041015625 0.535983642578125 +0.169625 -0.14947509765625 0.535983642578125 +0.16975 -0.134429931640625 0.535983642578125 +0.169875 -0.119232177734375 0.535983642578125 +0.17 -0.098785400390625 0.535983642578125 +0.170125 -0.083343505859375 0.535983642578125 +0.17025 -0.0626220703125 0.535983642578125 +0.170375 -0.047027587890625 0.535983642578125 +0.1705 -0.026123046875 0.535983642578125 +0.170625 -0.01043701171875 0.535983642578125 0.17075 0.01043701171875 0.535983642578125 0.170875 0.026123046875 0.535983642578125 0.171 0.047027587890625 0.535983642578125 @@ -1450,92 +1450,92 @@ 0.181125 0.047027587890625 0.535983642578125 0.18125 0.0313720703125 0.535983642578125 0.181375 0.01043701171875 0.535983642578125 -0.1815 -0.0052490234375 0.535983642578125 -0.181625 -0.026153564453125 0.535983642578125 -0.18175 -0.041839599609375 0.535983642578125 -0.181875 -0.062652587890625 0.535983642578125 -0.182 -0.078216552734375 0.535983642578125 -0.182125 -0.09881591796875 0.535983642578125 -0.18225 -0.114166259765625 0.535983642578125 -0.182375 -0.13446044921875 0.535983642578125 -0.1825 -0.149505615234375 0.535983642578125 -0.182625 -0.16937255859375 0.535983642578125 -0.18275 -0.184051513671875 0.535983642578125 -0.182875 -0.203369140625 0.535983642578125 -0.183 -0.217620849609375 0.535983642578125 -0.183125 -0.23626708984375 0.535983642578125 -0.18325 -0.25 0.535983642578125 -0.183375 -0.263458251953125 0.535983642578125 -0.1835 -0.281005859375 0.535983642578125 -0.183625 -0.293853759765625 0.535983642578125 -0.18375 -0.310546875 0.535983642578125 -0.183875 -0.32269287109375 0.535983642578125 -0.184 -0.338409423828125 0.535983642578125 -0.184125 -0.34979248046875 0.535983642578125 -0.18425 -0.364471435546875 0.535983642578125 -0.184375 -0.375030517578125 0.535983642578125 -0.1845 -0.3885498046875 0.535983642578125 -0.184625 -0.398223876953125 0.535983642578125 -0.18475 -0.410552978515625 0.535983642578125 -0.184875 -0.4193115234375 0.535983642578125 -0.185 -0.430328369140625 0.535983642578125 -0.185125 -0.4381103515625 0.535983642578125 -0.18525 -0.44781494140625 0.535983642578125 -0.185375 -0.45458984375 0.535983642578125 -0.1855 -0.462921142578125 0.535983642578125 -0.185625 -0.468597412109375 0.535983642578125 -0.18575 -0.475494384765625 0.535983642578125 -0.185875 -0.4801025390625 0.535983642578125 -0.186 -0.48553466796875 0.535983642578125 -0.186125 -0.489044189453125 0.535983642578125 -0.18625 -0.49298095703125 0.535983642578125 -0.186375 -0.495330810546875 0.535983642578125 -0.1865 -0.497222900390625 0.535983642578125 -0.186625 -0.498992919921875 0.535983642578125 -0.18675 -0.499725341796875 0.535983642578125 -0.186875 -0.49993896484375 0.535983642578125 -0.187 -0.499542236328125 0.535983642578125 -0.187125 -0.49822998046875 0.535983642578125 -0.18725 -0.49664306640625 0.535983642578125 -0.187375 -0.493804931640625 0.535983642578125 -0.1875 -0.491119384765625 0.535983642578125 -0.187625 -0.48675537109375 0.535983642578125 -0.18775 -0.482940673828125 0.535983642578125 -0.187875 -0.477081298828125 0.535983642578125 -0.188 -0.47216796875 0.535983642578125 -0.188125 -0.46484375 0.535983642578125 -0.18825 -0.4588623046875 0.535983642578125 -0.188375 -0.45013427734375 0.535983642578125 -0.1885 -0.443084716796875 0.535983642578125 -0.188625 -0.4329833984375 0.535983642578125 -0.18875 -0.4249267578125 0.535983642578125 -0.188875 -0.41351318359375 0.535983642578125 -0.189 -0.40447998046875 0.535983642578125 -0.189125 -0.391815185546875 0.535983642578125 -0.18925 -0.381866455078125 0.535983642578125 -0.189375 -0.368011474609375 0.535983642578125 -0.1895 -0.357208251953125 0.535983642578125 -0.189625 -0.342254638671875 0.535983642578125 -0.18975 -0.33062744140625 0.535983642578125 -0.189875 -0.318695068359375 0.535983642578125 -0.19 -0.302276611328125 0.535983642578125 -0.190125 -0.28961181640625 0.535983642578125 -0.19025 -0.272308349609375 0.535983642578125 -0.190375 -0.259002685546875 0.535983642578125 -0.1905 -0.240875244140625 0.535983642578125 -0.190625 -0.22698974609375 0.535983642578125 -0.19075 -0.2081298828125 0.535983642578125 -0.190875 -0.193756103515625 0.535983642578125 -0.191 -0.174285888671875 0.535983642578125 -0.191125 -0.15948486328125 0.535983642578125 -0.19125 -0.139495849609375 0.535983642578125 -0.191375 -0.12432861328125 0.535983642578125 -0.1915 -0.10394287109375 0.535983642578125 -0.191625 -0.088531494140625 0.535983642578125 -0.19175 -0.067840576171875 0.535983642578125 -0.191875 -0.052276611328125 0.535983642578125 -0.192 -0.031402587890625 0.791975830078125 -0.192125 -0.0052490234375 0.791975830078125 +0.1815 -0.005218505859375 0.535983642578125 +0.181625 -0.026123046875 0.535983642578125 +0.18175 -0.04180908203125 0.535983642578125 +0.181875 -0.0626220703125 0.535983642578125 +0.182 -0.07818603515625 0.535983642578125 +0.182125 -0.098785400390625 0.535983642578125 +0.18225 -0.1141357421875 0.535983642578125 +0.182375 -0.134429931640625 0.535983642578125 +0.1825 -0.14947509765625 0.535983642578125 +0.182625 -0.169342041015625 0.535983642578125 +0.18275 -0.18402099609375 0.535983642578125 +0.182875 -0.203338623046875 0.535983642578125 +0.183 -0.21759033203125 0.535983642578125 +0.183125 -0.236236572265625 0.535983642578125 +0.18325 -0.249969482421875 0.535983642578125 +0.183375 -0.263427734375 0.535983642578125 +0.1835 -0.280975341796875 0.535983642578125 +0.183625 -0.2938232421875 0.535983642578125 +0.18375 -0.310516357421875 0.535983642578125 +0.183875 -0.322662353515625 0.535983642578125 +0.184 -0.33837890625 0.535983642578125 +0.184125 -0.349761962890625 0.535983642578125 +0.18425 -0.36444091796875 0.535983642578125 +0.184375 -0.375 0.535983642578125 +0.1845 -0.388519287109375 0.535983642578125 +0.184625 -0.398193359375 0.535983642578125 +0.18475 -0.4105224609375 0.535983642578125 +0.184875 -0.419281005859375 0.535983642578125 +0.185 -0.4302978515625 0.535983642578125 +0.185125 -0.438079833984375 0.535983642578125 +0.18525 -0.447784423828125 0.535983642578125 +0.185375 -0.454559326171875 0.535983642578125 +0.1855 -0.462890625 0.535983642578125 +0.185625 -0.46856689453125 0.535983642578125 +0.18575 -0.4754638671875 0.535983642578125 +0.185875 -0.480072021484375 0.535983642578125 +0.186 -0.485504150390625 0.535983642578125 +0.186125 -0.489013671875 0.535983642578125 +0.18625 -0.492950439453125 0.535983642578125 +0.186375 -0.49530029296875 0.535983642578125 +0.1865 -0.4971923828125 0.535983642578125 +0.186625 -0.49896240234375 0.535983642578125 +0.18675 -0.49969482421875 0.535983642578125 +0.186875 -0.499908447265625 0.535983642578125 +0.187 -0.49951171875 0.535983642578125 +0.187125 -0.498199462890625 0.535983642578125 +0.18725 -0.496612548828125 0.535983642578125 +0.187375 -0.4937744140625 0.535983642578125 +0.1875 -0.4910888671875 0.535983642578125 +0.187625 -0.486724853515625 0.535983642578125 +0.18775 -0.48291015625 0.535983642578125 +0.187875 -0.47705078125 0.535983642578125 +0.188 -0.472137451171875 0.535983642578125 +0.188125 -0.464813232421875 0.535983642578125 +0.18825 -0.458831787109375 0.535983642578125 +0.188375 -0.450103759765625 0.535983642578125 +0.1885 -0.44305419921875 0.535983642578125 +0.188625 -0.432952880859375 0.535983642578125 +0.18875 -0.424896240234375 0.535983642578125 +0.188875 -0.413482666015625 0.535983642578125 +0.189 -0.404449462890625 0.535983642578125 +0.189125 -0.39178466796875 0.535983642578125 +0.18925 -0.3818359375 0.535983642578125 +0.189375 -0.36798095703125 0.535983642578125 +0.1895 -0.357177734375 0.535983642578125 +0.189625 -0.34222412109375 0.535983642578125 +0.18975 -0.330596923828125 0.535983642578125 +0.189875 -0.31866455078125 0.535983642578125 +0.19 -0.30224609375 0.535983642578125 +0.190125 -0.289581298828125 0.535983642578125 +0.19025 -0.27227783203125 0.535983642578125 +0.190375 -0.25897216796875 0.535983642578125 +0.1905 -0.2408447265625 0.535983642578125 +0.190625 -0.226959228515625 0.535983642578125 +0.19075 -0.208099365234375 0.535983642578125 +0.190875 -0.1937255859375 0.535983642578125 +0.191 -0.17425537109375 0.535983642578125 +0.191125 -0.159454345703125 0.535983642578125 +0.19125 -0.13946533203125 0.535983642578125 +0.191375 -0.124298095703125 0.535983642578125 +0.1915 -0.103912353515625 0.535983642578125 +0.191625 -0.0885009765625 0.535983642578125 +0.19175 -0.06781005859375 0.535983642578125 +0.191875 -0.05224609375 0.535983642578125 +0.192 -0.0313720703125 0.791975830078125 +0.192125 -0.005218505859375 0.791975830078125 0.19225 0.01568603515625 0.791975830078125 0.192375 0.036590576171875 0.791975830078125 0.1925 0.05743408203125 0.791975830078125 @@ -1608,78 +1608,78 @@ 0.200875 0.05743408203125 0.791975830078125 0.201 0.0313720703125 0.791975830078125 0.201125 0.01043701171875 0.791975830078125 -0.20125 -0.010467529296875 0.791975830078125 -0.201375 -0.031402587890625 0.791975830078125 -0.2015 -0.052276611328125 0.791975830078125 -0.201625 -0.073028564453125 0.791975830078125 -0.20175 -0.09881591796875 0.791975830078125 -0.201875 -0.1192626953125 0.791975830078125 -0.202 -0.139495849609375 0.791975830078125 -0.202125 -0.15948486328125 0.791975830078125 -0.20225 -0.179168701171875 0.791975830078125 -0.202375 -0.198577880859375 0.791975830078125 -0.2025 -0.222320556640625 0.791975830078125 -0.202625 -0.240875244140625 0.791975830078125 -0.20275 -0.259002685546875 0.791975830078125 -0.202875 -0.27667236328125 0.791975830078125 -0.203 -0.293853759765625 0.791975830078125 -0.203125 -0.310546875 0.791975830078125 -0.20325 -0.326690673828125 0.791975830078125 -0.203375 -0.346038818359375 0.791975830078125 -0.2035 -0.36083984375 0.791975830078125 -0.203625 -0.375030517578125 0.791975830078125 -0.20375 -0.3885498046875 0.791975830078125 -0.203875 -0.4013671875 0.791975830078125 -0.204 -0.41351318359375 0.791975830078125 -0.204125 -0.427642822265625 0.791975830078125 -0.20425 -0.4381103515625 0.791975830078125 -0.204375 -0.44781494140625 0.791975830078125 -0.2045 -0.456756591796875 0.791975830078125 -0.204625 -0.46484375 0.791975830078125 -0.20475 -0.47216796875 0.791975830078125 -0.204875 -0.4801025390625 0.791975830078125 -0.205 -0.48553466796875 0.791975830078125 -0.205125 -0.4901123046875 0.791975830078125 -0.20525 -0.493804931640625 0.791975830078125 -0.205375 -0.49664306640625 0.791975830078125 -0.2055 -0.498626708984375 0.791975830078125 -0.205625 -0.499725341796875 0.791975830078125 -0.20575 -0.499847412109375 0.791975830078125 -0.205875 -0.498992919921875 0.791975830078125 -0.206 -0.497222900390625 0.791975830078125 -0.206125 -0.494598388671875 0.791975830078125 -0.20625 -0.491119384765625 0.791975830078125 -0.206375 -0.48675537109375 0.791975830078125 -0.2065 -0.4801025390625 0.791975830078125 -0.206625 -0.473846435546875 0.791975830078125 -0.20675 -0.466766357421875 0.791975830078125 -0.206875 -0.4588623046875 0.791975830078125 -0.207 -0.45013427734375 0.791975830078125 -0.207125 -0.44061279296875 0.791975830078125 -0.20725 -0.427642822265625 0.791975830078125 -0.207375 -0.41644287109375 0.791975830078125 -0.2075 -0.40447998046875 0.791975830078125 -0.207625 -0.391815185546875 0.791975830078125 -0.20775 -0.37847900390625 0.791975830078125 -0.207875 -0.364471435546875 0.791975830078125 -0.208 -0.34979248046875 0.791975830078125 -0.208125 -0.33062744140625 0.791975830078125 -0.20825 -0.31463623046875 0.791975830078125 -0.208375 -0.298095703125 0.791975830078125 -0.2085 -0.281005859375 0.791975830078125 -0.208625 -0.263458251953125 0.791975830078125 -0.20875 -0.245452880859375 0.791975830078125 -0.208875 -0.222320556640625 0.791975830078125 -0.209 -0.203369140625 0.791975830078125 -0.209125 -0.184051513671875 0.791975830078125 -0.20925 -0.1644287109375 0.791975830078125 -0.209375 -0.144500732421875 0.791975830078125 -0.2095 -0.12432861328125 0.791975830078125 -0.209625 -0.10394287109375 0.791975830078125 -0.20975 -0.078216552734375 0.791975830078125 -0.209875 -0.057464599609375 0.791975830078125 -0.21 -0.03662109375 0.791975830078125 -0.210125 -0.015716552734375 0.791975830078125 +0.20125 -0.01043701171875 0.791975830078125 +0.201375 -0.0313720703125 0.791975830078125 +0.2015 -0.05224609375 0.791975830078125 +0.201625 -0.072998046875 0.791975830078125 +0.20175 -0.098785400390625 0.791975830078125 +0.201875 -0.119232177734375 0.791975830078125 +0.202 -0.13946533203125 0.791975830078125 +0.202125 -0.159454345703125 0.791975830078125 +0.20225 -0.17913818359375 0.791975830078125 +0.202375 -0.19854736328125 0.791975830078125 +0.2025 -0.2222900390625 0.791975830078125 +0.202625 -0.2408447265625 0.791975830078125 +0.20275 -0.25897216796875 0.791975830078125 +0.202875 -0.276641845703125 0.791975830078125 +0.203 -0.2938232421875 0.791975830078125 +0.203125 -0.310516357421875 0.791975830078125 +0.20325 -0.32666015625 0.791975830078125 +0.203375 -0.34600830078125 0.791975830078125 +0.2035 -0.360809326171875 0.791975830078125 +0.203625 -0.375 0.791975830078125 +0.20375 -0.388519287109375 0.791975830078125 +0.203875 -0.401336669921875 0.791975830078125 +0.204 -0.413482666015625 0.791975830078125 +0.204125 -0.4276123046875 0.791975830078125 +0.20425 -0.438079833984375 0.791975830078125 +0.204375 -0.447784423828125 0.791975830078125 +0.2045 -0.45672607421875 0.791975830078125 +0.204625 -0.464813232421875 0.791975830078125 +0.20475 -0.472137451171875 0.791975830078125 +0.204875 -0.480072021484375 0.791975830078125 +0.205 -0.485504150390625 0.791975830078125 +0.205125 -0.490081787109375 0.791975830078125 +0.20525 -0.4937744140625 0.791975830078125 +0.205375 -0.496612548828125 0.791975830078125 +0.2055 -0.49859619140625 0.791975830078125 +0.205625 -0.49969482421875 0.791975830078125 +0.20575 -0.49981689453125 0.791975830078125 +0.205875 -0.49896240234375 0.791975830078125 +0.206 -0.4971923828125 0.791975830078125 +0.206125 -0.49456787109375 0.791975830078125 +0.20625 -0.4910888671875 0.791975830078125 +0.206375 -0.486724853515625 0.791975830078125 +0.2065 -0.480072021484375 0.791975830078125 +0.206625 -0.47381591796875 0.791975830078125 +0.20675 -0.46673583984375 0.791975830078125 +0.206875 -0.458831787109375 0.791975830078125 +0.207 -0.450103759765625 0.791975830078125 +0.207125 -0.440582275390625 0.791975830078125 +0.20725 -0.4276123046875 0.791975830078125 +0.207375 -0.416412353515625 0.791975830078125 +0.2075 -0.404449462890625 0.791975830078125 +0.207625 -0.39178466796875 0.791975830078125 +0.20775 -0.378448486328125 0.791975830078125 +0.207875 -0.36444091796875 0.791975830078125 +0.208 -0.349761962890625 0.791975830078125 +0.208125 -0.330596923828125 0.791975830078125 +0.20825 -0.314605712890625 0.791975830078125 +0.208375 -0.298065185546875 0.791975830078125 +0.2085 -0.280975341796875 0.791975830078125 +0.208625 -0.263427734375 0.791975830078125 +0.20875 -0.24542236328125 0.791975830078125 +0.208875 -0.2222900390625 0.791975830078125 +0.209 -0.203338623046875 0.791975830078125 +0.209125 -0.18402099609375 0.791975830078125 +0.20925 -0.164398193359375 0.791975830078125 +0.209375 -0.14447021484375 0.791975830078125 +0.2095 -0.124298095703125 0.791975830078125 +0.209625 -0.103912353515625 0.791975830078125 +0.20975 -0.07818603515625 0.791975830078125 +0.209875 -0.05743408203125 0.791975830078125 +0.21 -0.036590576171875 0.791975830078125 +0.210125 -0.01568603515625 0.791975830078125 0.21025 0.005218505859375 0.791975830078125 0.210375 0.026123046875 0.791975830078125 0.2105 0.05224609375 0.791975830078125 @@ -1752,74 +1752,74 @@ 0.218875 0.0626220703125 0.791975830078125 0.219 0.04180908203125 0.791975830078125 0.219125 0.020904541015625 0.791975830078125 -0.21925 -0.0052490234375 0.791975830078125 -0.219375 -0.026153564453125 0.791975830078125 -0.2195 -0.04705810546875 0.791975830078125 -0.219625 -0.067840576171875 0.791975830078125 -0.21975 -0.088531494140625 0.791975830078125 -0.219875 -0.10906982421875 0.791975830078125 -0.22 -0.13446044921875 0.791975830078125 -0.220125 -0.154510498046875 0.791975830078125 -0.22025 -0.174285888671875 0.791975830078125 -0.220375 -0.193756103515625 0.791975830078125 -0.2205 -0.212890625 0.791975830078125 -0.220625 -0.23162841796875 0.791975830078125 -0.22075 -0.25 0.791975830078125 -0.220875 -0.272308349609375 0.791975830078125 -0.221 -0.28961181640625 0.791975830078125 -0.221125 -0.306427001953125 0.791975830078125 -0.22125 -0.32269287109375 0.791975830078125 -0.221375 -0.338409423828125 0.791975830078125 -0.2215 -0.353515625 0.791975830078125 -0.221625 -0.371551513671875 0.791975830078125 -0.22175 -0.385223388671875 0.791975830078125 -0.221875 -0.398223876953125 0.791975830078125 -0.222 -0.410552978515625 0.791975830078125 -0.222125 -0.422149658203125 0.791975830078125 -0.22225 -0.4329833984375 0.791975830078125 -0.222375 -0.445465087890625 0.791975830078125 -0.2225 -0.45458984375 0.791975830078125 -0.222625 -0.462921142578125 0.791975830078125 -0.22275 -0.47039794921875 0.791975830078125 -0.222875 -0.477081298828125 0.791975830078125 -0.223 -0.482940673828125 0.791975830078125 -0.223125 -0.4879150390625 0.791975830078125 -0.22325 -0.49298095703125 0.791975830078125 -0.223375 -0.49603271484375 0.791975830078125 -0.2235 -0.49822998046875 0.791975830078125 -0.223625 -0.499542236328125 0.791975830078125 -0.22375 -0.499969482421875 0.791975830078125 -0.223875 -0.499542236328125 0.791975830078125 -0.224 -0.49774169921875 0.9999084491282701 -0.224125 -0.494598388671875 0.9999084491282701 -0.22425 -0.4901123046875 0.9999084491282701 -0.224375 -0.4842529296875 0.9999084491282701 -0.2245 -0.4786376953125 0.9999084491282701 -0.224625 -0.47039794921875 0.9999084491282701 -0.22475 -0.460906982421875 0.9999084491282701 -0.224875 -0.45013427734375 0.9999084491282701 -0.225 -0.4381103515625 0.9999084491282701 -0.225125 -0.427642822265625 0.9999084491282701 -0.22525 -0.41351318359375 0.9999084491282701 -0.225375 -0.398223876953125 0.9999084491282701 -0.2255 -0.381866455078125 0.9999084491282701 -0.225625 -0.364471435546875 0.9999084491282701 -0.22575 -0.34979248046875 0.9999084491282701 -0.225875 -0.33062744140625 0.9999084491282701 -0.226 -0.310546875 0.9999084491282701 -0.226125 -0.28961181640625 0.9999084491282701 -0.22625 -0.26788330078125 0.9999084491282701 -0.226375 -0.25 0.9999084491282701 -0.2265 -0.22698974609375 0.9999084491282701 -0.226625 -0.203369140625 0.9999084491282701 -0.22675 -0.179168701171875 0.9999084491282701 -0.226875 -0.154510498046875 0.9999084491282701 -0.227 -0.13446044921875 0.9999084491282701 -0.227125 -0.10906982421875 0.9999084491282701 -0.22725 -0.0833740234375 0.9999084491282701 -0.227375 -0.057464599609375 0.9999084491282701 -0.2275 -0.031402587890625 0.9999084491282701 -0.227625 -0.010467529296875 0.9999084491282701 +0.21925 -0.005218505859375 0.791975830078125 +0.219375 -0.026123046875 0.791975830078125 +0.2195 -0.047027587890625 0.791975830078125 +0.219625 -0.06781005859375 0.791975830078125 +0.21975 -0.0885009765625 0.791975830078125 +0.219875 -0.109039306640625 0.791975830078125 +0.22 -0.134429931640625 0.791975830078125 +0.220125 -0.15447998046875 0.791975830078125 +0.22025 -0.17425537109375 0.791975830078125 +0.220375 -0.1937255859375 0.791975830078125 +0.2205 -0.212860107421875 0.791975830078125 +0.220625 -0.231597900390625 0.791975830078125 +0.22075 -0.249969482421875 0.791975830078125 +0.220875 -0.27227783203125 0.791975830078125 +0.221 -0.289581298828125 0.791975830078125 +0.221125 -0.306396484375 0.791975830078125 +0.22125 -0.322662353515625 0.791975830078125 +0.221375 -0.33837890625 0.791975830078125 +0.2215 -0.353485107421875 0.791975830078125 +0.221625 -0.37152099609375 0.791975830078125 +0.22175 -0.38519287109375 0.791975830078125 +0.221875 -0.398193359375 0.791975830078125 +0.222 -0.4105224609375 0.791975830078125 +0.222125 -0.422119140625 0.791975830078125 +0.22225 -0.432952880859375 0.791975830078125 +0.222375 -0.4454345703125 0.791975830078125 +0.2225 -0.454559326171875 0.791975830078125 +0.222625 -0.462890625 0.791975830078125 +0.22275 -0.470367431640625 0.791975830078125 +0.222875 -0.47705078125 0.791975830078125 +0.223 -0.48291015625 0.791975830078125 +0.223125 -0.487884521484375 0.791975830078125 +0.22325 -0.492950439453125 0.791975830078125 +0.223375 -0.496002197265625 0.791975830078125 +0.2235 -0.498199462890625 0.791975830078125 +0.223625 -0.49951171875 0.791975830078125 +0.22375 -0.49993896484375 0.791975830078125 +0.223875 -0.49951171875 0.791975830078125 +0.224 -0.497711181640625 0.9999084491282701 +0.224125 -0.49456787109375 0.9999084491282701 +0.22425 -0.490081787109375 0.9999084491282701 +0.224375 -0.484222412109375 0.9999084491282701 +0.2245 -0.478607177734375 0.9999084491282701 +0.224625 -0.470367431640625 0.9999084491282701 +0.22475 -0.46087646484375 0.9999084491282701 +0.224875 -0.450103759765625 0.9999084491282701 +0.225 -0.438079833984375 0.9999084491282701 +0.225125 -0.4276123046875 0.9999084491282701 +0.22525 -0.413482666015625 0.9999084491282701 +0.225375 -0.398193359375 0.9999084491282701 +0.2255 -0.3818359375 0.9999084491282701 +0.225625 -0.36444091796875 0.9999084491282701 +0.22575 -0.349761962890625 0.9999084491282701 +0.225875 -0.330596923828125 0.9999084491282701 +0.226 -0.310516357421875 0.9999084491282701 +0.226125 -0.289581298828125 0.9999084491282701 +0.22625 -0.267852783203125 0.9999084491282701 +0.226375 -0.249969482421875 0.9999084491282701 +0.2265 -0.226959228515625 0.9999084491282701 +0.226625 -0.203338623046875 0.9999084491282701 +0.22675 -0.17913818359375 0.9999084491282701 +0.226875 -0.15447998046875 0.9999084491282701 +0.227 -0.134429931640625 0.9999084491282701 +0.227125 -0.109039306640625 0.9999084491282701 +0.22725 -0.083343505859375 0.9999084491282701 +0.227375 -0.05743408203125 0.9999084491282701 +0.2275 -0.0313720703125 0.9999084491282701 +0.227625 -0.01043701171875 0.9999084491282701 0.22775 0.01568603515625 0.9999084491282701 0.227875 0.04180908203125 0.9999084491282701 0.228 0.06781005859375 0.9999084491282701 @@ -1882,69 +1882,69 @@ 0.235125 0.072998046875 0.9999084491282701 0.23525 0.047027587890625 0.9999084491282701 0.235375 0.020904541015625 0.9999084491282701 -0.2355 -0.0052490234375 0.9999084491282701 -0.235625 -0.031402587890625 0.9999084491282701 -0.23575 -0.052276611328125 0.9999084491282701 -0.235875 -0.078216552734375 0.9999084491282701 -0.236 -0.10394287109375 0.9999084491282701 -0.236125 -0.12939453125 0.9999084491282701 -0.23625 -0.154510498046875 0.9999084491282701 -0.236375 -0.174285888671875 0.9999084491282701 -0.2365 -0.198577880859375 0.9999084491282701 -0.236625 -0.222320556640625 0.9999084491282701 -0.23675 -0.245452880859375 0.9999084491282701 -0.236875 -0.26788330078125 0.9999084491282701 -0.237 -0.28533935546875 0.9999084491282701 -0.237125 -0.306427001953125 0.9999084491282701 -0.23725 -0.326690673828125 0.9999084491282701 -0.237375 -0.346038818359375 0.9999084491282701 -0.2375 -0.364471435546875 0.9999084491282701 -0.237625 -0.37847900390625 0.9999084491282701 -0.23775 -0.395050048828125 0.9999084491282701 -0.237875 -0.410552978515625 0.9999084491282701 -0.238 -0.4249267578125 0.9999084491282701 -0.238125 -0.4381103515625 0.9999084491282701 -0.23825 -0.44781494140625 0.9999084491282701 -0.238375 -0.4588623046875 0.9999084491282701 -0.2385 -0.468597412109375 0.9999084491282701 -0.238625 -0.477081298828125 0.9999084491282701 -0.23875 -0.4842529296875 0.9999084491282701 -0.238875 -0.489044189453125 0.9999084491282701 -0.239 -0.493804931640625 0.9999084491282701 -0.239125 -0.497222900390625 0.9999084491282701 -0.23925 -0.499298095703125 0.9999084491282701 -0.239375 -0.499969482421875 0.9999084491282701 -0.2395 -0.499542236328125 0.9999084491282701 -0.239625 -0.49774169921875 0.9999084491282701 -0.23975 -0.494598388671875 0.9999084491282701 -0.239875 -0.4901123046875 0.9999084491282701 -0.24 -0.4842529296875 0.9999084491282701 -0.240125 -0.4786376953125 0.9999084491282701 -0.24025 -0.47039794921875 0.9999084491282701 -0.240375 -0.460906982421875 0.9999084491282701 -0.2405 -0.45013427734375 0.9999084491282701 -0.240625 -0.4381103515625 0.9999084491282701 -0.24075 -0.427642822265625 0.9999084491282701 -0.240875 -0.41351318359375 0.9999084491282701 -0.241 -0.398223876953125 0.9999084491282701 -0.241125 -0.381866455078125 0.9999084491282701 -0.24125 -0.364471435546875 0.9999084491282701 -0.241375 -0.34979248046875 0.9999084491282701 -0.2415 -0.33062744140625 0.9999084491282701 -0.241625 -0.310546875 0.9999084491282701 -0.24175 -0.28961181640625 0.9999084491282701 -0.241875 -0.26788330078125 0.9999084491282701 -0.242 -0.25 0.9999084491282701 -0.242125 -0.22698974609375 0.9999084491282701 -0.24225 -0.203369140625 0.9999084491282701 -0.242375 -0.179168701171875 0.9999084491282701 -0.2425 -0.154510498046875 0.9999084491282701 -0.242625 -0.13446044921875 0.9999084491282701 -0.24275 -0.10906982421875 0.9999084491282701 -0.242875 -0.0833740234375 0.9999084491282701 -0.243 -0.057464599609375 0.9999084491282701 -0.243125 -0.031402587890625 0.9999084491282701 -0.24325 -0.010467529296875 0.9999084491282701 +0.2355 -0.005218505859375 0.9999084491282701 +0.235625 -0.0313720703125 0.9999084491282701 +0.23575 -0.05224609375 0.9999084491282701 +0.235875 -0.07818603515625 0.9999084491282701 +0.236 -0.103912353515625 0.9999084491282701 +0.236125 -0.129364013671875 0.9999084491282701 +0.23625 -0.15447998046875 0.9999084491282701 +0.236375 -0.17425537109375 0.9999084491282701 +0.2365 -0.19854736328125 0.9999084491282701 +0.236625 -0.2222900390625 0.9999084491282701 +0.23675 -0.24542236328125 0.9999084491282701 +0.236875 -0.267852783203125 0.9999084491282701 +0.237 -0.285308837890625 0.9999084491282701 +0.237125 -0.306396484375 0.9999084491282701 +0.23725 -0.32666015625 0.9999084491282701 +0.237375 -0.34600830078125 0.9999084491282701 +0.2375 -0.36444091796875 0.9999084491282701 +0.237625 -0.378448486328125 0.9999084491282701 +0.23775 -0.39501953125 0.9999084491282701 +0.237875 -0.4105224609375 0.9999084491282701 +0.238 -0.424896240234375 0.9999084491282701 +0.238125 -0.438079833984375 0.9999084491282701 +0.23825 -0.447784423828125 0.9999084491282701 +0.238375 -0.458831787109375 0.9999084491282701 +0.2385 -0.46856689453125 0.9999084491282701 +0.238625 -0.47705078125 0.9999084491282701 +0.23875 -0.484222412109375 0.9999084491282701 +0.238875 -0.489013671875 0.9999084491282701 +0.239 -0.4937744140625 0.9999084491282701 +0.239125 -0.4971923828125 0.9999084491282701 +0.23925 -0.499267578125 0.9999084491282701 +0.239375 -0.49993896484375 0.9999084491282701 +0.2395 -0.49951171875 0.9999084491282701 +0.239625 -0.497711181640625 0.9999084491282701 +0.23975 -0.49456787109375 0.9999084491282701 +0.239875 -0.490081787109375 0.9999084491282701 +0.24 -0.484222412109375 0.9999084491282701 +0.240125 -0.478607177734375 0.9999084491282701 +0.24025 -0.470367431640625 0.9999084491282701 +0.240375 -0.46087646484375 0.9999084491282701 +0.2405 -0.450103759765625 0.9999084491282701 +0.240625 -0.438079833984375 0.9999084491282701 +0.24075 -0.4276123046875 0.9999084491282701 +0.240875 -0.413482666015625 0.9999084491282701 +0.241 -0.398193359375 0.9999084491282701 +0.241125 -0.3818359375 0.9999084491282701 +0.24125 -0.36444091796875 0.9999084491282701 +0.241375 -0.349761962890625 0.9999084491282701 +0.2415 -0.330596923828125 0.9999084491282701 +0.241625 -0.310516357421875 0.9999084491282701 +0.24175 -0.289581298828125 0.9999084491282701 +0.241875 -0.267852783203125 0.9999084491282701 +0.242 -0.249969482421875 0.9999084491282701 +0.242125 -0.226959228515625 0.9999084491282701 +0.24225 -0.203338623046875 0.9999084491282701 +0.242375 -0.17913818359375 0.9999084491282701 +0.2425 -0.15447998046875 0.9999084491282701 +0.242625 -0.134429931640625 0.9999084491282701 +0.24275 -0.109039306640625 0.9999084491282701 +0.242875 -0.083343505859375 0.9999084491282701 +0.243 -0.05743408203125 0.9999084491282701 +0.243125 -0.0313720703125 0.9999084491282701 +0.24325 -0.01043701171875 0.9999084491282701 0.243375 0.01568603515625 0.9999084491282701 0.2435 0.04180908203125 0.9999084491282701 0.243625 0.06781005859375 0.9999084491282701 @@ -2007,42 +2007,42 @@ 0.25075 0.072998046875 0.9999084491282701 0.250875 0.047027587890625 0.9999084491282701 0.251 0.020904541015625 0.9999084491282701 -0.251125 -0.0052490234375 0.9999084491282701 -0.25125 -0.031402587890625 0.9999084491282701 -0.251375 -0.052276611328125 0.9999084491282701 -0.2515 -0.078216552734375 0.9999084491282701 -0.251625 -0.10394287109375 0.9999084491282701 -0.25175 -0.12939453125 0.9999084491282701 -0.251875 -0.154510498046875 0.9999084491282701 -0.252 -0.174285888671875 0.9999084491282701 -0.252125 -0.198577880859375 0.9999084491282701 -0.25225 -0.222320556640625 0.9999084491282701 -0.252375 -0.245452880859375 0.9999084491282701 -0.2525 -0.26788330078125 0.9999084491282701 -0.252625 -0.28533935546875 0.9999084491282701 -0.25275 -0.306427001953125 0.9999084491282701 -0.252875 -0.326690673828125 0.9999084491282701 -0.253 -0.346038818359375 0.9999084491282701 -0.253125 -0.364471435546875 0.9999084491282701 -0.25325 -0.37847900390625 0.9999084491282701 -0.253375 -0.395050048828125 0.9999084491282701 -0.2535 -0.410552978515625 0.9999084491282701 -0.253625 -0.4249267578125 0.9999084491282701 -0.2537500000000001 -0.4381103515625 0.9999084491282701 -0.253875 -0.44781494140625 0.9999084491282701 -0.254 -0.4588623046875 0.9999084491282701 -0.254125 -0.468597412109375 0.9999084491282701 -0.25425 -0.477081298828125 0.9999084491282701 -0.254375 -0.4842529296875 0.9999084491282701 -0.2545 -0.489044189453125 0.9999084491282701 -0.254625 -0.493804931640625 0.9999084491282701 -0.25475 -0.497222900390625 0.9999084491282701 -0.254875 -0.499298095703125 0.9999084491282701 -0.255 -0.499969482421875 0.9999084491282701 -0.255125 -0.499542236328125 0.9999084491282701 -0.25525 -0.49774169921875 0.9999084491282701 -0.255375 -0.494598388671875 0.9999084491282701 -0.2555 -0.4901123046875 0.9999084491282701 -0.255625 -0.4842529296875 0.9999084491282701 -0.25575 -0.4786376953125 0.9999084491282701 -0.255875 -0.47039794921875 0.9999084491282701 +0.251125 -0.005218505859375 0.9999084491282701 +0.25125 -0.0313720703125 0.9999084491282701 +0.251375 -0.05224609375 0.9999084491282701 +0.2515 -0.07818603515625 0.9999084491282701 +0.251625 -0.103912353515625 0.9999084491282701 +0.25175 -0.129364013671875 0.9999084491282701 +0.251875 -0.15447998046875 0.9999084491282701 +0.252 -0.17425537109375 0.9999084491282701 +0.252125 -0.19854736328125 0.9999084491282701 +0.25225 -0.2222900390625 0.9999084491282701 +0.252375 -0.24542236328125 0.9999084491282701 +0.2525 -0.267852783203125 0.9999084491282701 +0.252625 -0.285308837890625 0.9999084491282701 +0.25275 -0.306396484375 0.9999084491282701 +0.252875 -0.32666015625 0.9999084491282701 +0.253 -0.34600830078125 0.9999084491282701 +0.253125 -0.36444091796875 0.9999084491282701 +0.25325 -0.378448486328125 0.9999084491282701 +0.253375 -0.39501953125 0.9999084491282701 +0.2535 -0.4105224609375 0.9999084491282701 +0.253625 -0.424896240234375 0.9999084491282701 +0.2537500000000001 -0.438079833984375 0.9999084491282701 +0.253875 -0.447784423828125 0.9999084491282701 +0.254 -0.458831787109375 0.9999084491282701 +0.254125 -0.46856689453125 0.9999084491282701 +0.25425 -0.47705078125 0.9999084491282701 +0.254375 -0.484222412109375 0.9999084491282701 +0.2545 -0.489013671875 0.9999084491282701 +0.254625 -0.4937744140625 0.9999084491282701 +0.25475 -0.4971923828125 0.9999084491282701 +0.254875 -0.499267578125 0.9999084491282701 +0.255 -0.49993896484375 0.9999084491282701 +0.255125 -0.49951171875 0.9999084491282701 +0.25525 -0.497711181640625 0.9999084491282701 +0.255375 -0.49456787109375 0.9999084491282701 +0.2555 -0.490081787109375 0.9999084491282701 +0.255625 -0.484222412109375 0.9999084491282701 +0.25575 -0.478607177734375 0.9999084491282701 +0.255875 -0.470367431640625 0.9999084491282701 diff --git a/tests/circuitpython/synth_note_envelope.py.exp b/tests/circuitpython/synth_note_envelope.py.exp index c490380cb31..d4c7d0adc24 100644 --- a/tests/circuitpython/synth_note_envelope.py.exp +++ b/tests/circuitpython/synth_note_envelope.py.exp @@ -29,37 +29,37 @@ 0.0035 0.034515380859375 0.302396875 0.003625 0.0189208984375 0.302396875 0.00375 0.004730224609375 0.302396875 -0.003875 -0.011077880859375 0.302396875 -0.004 -0.025238037109375 0.302396875 -0.004125 -0.040679931640625 0.302396875 -0.00425 -0.0556640625 0.302396875 -0.004375000000000001 -0.068634033203125 0.302396875 -0.004500000000000001 -0.082366943359375 0.302396875 -0.004625 -0.09393310546875 0.302396875 -0.00475 -0.10577392578125 0.302396875 -0.004875 -0.116485595703125 0.302396875 -0.005 -0.12506103515625 0.302396875 -0.005125000000000001 -0.13323974609375 0.302396875 -0.00525 -0.139373779296875 0.302396875 -0.005375000000000001 -0.144744873046875 0.302396875 -0.005499999999999999 -0.148529052734375 0.302396875 -0.005625 -0.1505126953125 0.302396875 -0.00575 -0.15118408203125 0.302396875 -0.005874999999999999 -0.150360107421875 0.302396875 -0.006 -0.14788818359375 0.302396875 -0.006125 -0.143798828125 0.302396875 -0.00625 -0.138763427734375 0.302396875 -0.006375 -0.1317138671875 0.302396875 -0.0065 -0.1241455078125 0.302396875 -0.006625000000000001 -0.11444091796875 0.302396875 -0.00675 -0.103515625 0.302396875 -0.006875 -0.092681884765625 0.302396875 -0.007000000000000001 -0.079681396484375 0.302396875 -0.007125000000000002 -0.067230224609375 0.302396875 -0.007250000000000001 -0.052703857421875 0.302396875 -0.007375 -0.03759765625 0.302396875 -0.0075 -0.023651123046875 0.302396875 -0.007625 -0.0079345703125 0.302396875 +0.003875 -0.01104736328125 0.302396875 +0.004 -0.02520751953125 0.302396875 +0.004125 -0.0406494140625 0.302396875 +0.00425 -0.055633544921875 0.302396875 +0.004375000000000001 -0.068603515625 0.302396875 +0.004500000000000001 -0.08233642578125 0.302396875 +0.004625 -0.093902587890625 0.302396875 +0.00475 -0.105743408203125 0.302396875 +0.004875 -0.116455078125 0.302396875 +0.005 -0.125030517578125 0.302396875 +0.005125000000000001 -0.133209228515625 0.302396875 +0.00525 -0.13934326171875 0.302396875 +0.005375000000000001 -0.14471435546875 0.302396875 +0.005499999999999999 -0.14849853515625 0.302396875 +0.005625 -0.150482177734375 0.302396875 +0.00575 -0.151153564453125 0.302396875 +0.005874999999999999 -0.15032958984375 0.302396875 +0.006 -0.147857666015625 0.302396875 +0.006125 -0.143768310546875 0.302396875 +0.00625 -0.13873291015625 0.302396875 +0.006375 -0.131683349609375 0.302396875 +0.0065 -0.124114990234375 0.302396875 +0.006625000000000001 -0.114410400390625 0.302396875 +0.00675 -0.103485107421875 0.302396875 +0.006875 -0.0926513671875 0.302396875 +0.007000000000000001 -0.07965087890625 0.302396875 +0.007125000000000002 -0.06719970703125 0.302396875 +0.007250000000000001 -0.05267333984375 0.302396875 +0.007375 -0.037567138671875 0.302396875 +0.0075 -0.02362060546875 0.302396875 +0.007625 -0.007904052734375 0.302396875 0.00775 0.006317138671875 0.302396875 0.007875 0.022064208984375 0.302396875 0.008 0.037567138671875 0.302396875 @@ -91,37 +91,37 @@ 0.01125 0.042144775390625 0.302396875 0.011375 0.026763916015625 0.302396875 0.0115 0.01263427734375 0.302396875 -0.011625 -0.003173828125 0.302396875 -0.01175 -0.018951416015625 0.302396875 -0.011875 -0.032989501953125 0.302396875 -0.012 -0.048248291015625 0.302396875 -0.012125 -0.061492919921875 0.302396875 -0.01225 -0.075592041015625 0.302396875 -0.012375 -0.0888671875 0.302396875 -0.0125 -0.100006103515625 0.302396875 -0.012625 -0.111297607421875 0.302396875 -0.01275 -0.12042236328125 0.302396875 -0.012875 -0.12933349609375 0.302396875 -0.013 -0.136810302734375 0.302396875 -0.013125 -0.142242431640625 0.302396875 -0.01325 -0.146820068359375 0.302396875 -0.013375 -0.149566650390625 0.302396875 -0.0135 -0.15106201171875 0.302396875 -0.013625 -0.150909423828125 0.302396875 -0.01375 -0.149322509765625 0.302396875 -0.013875 -0.146026611328125 0.302396875 -0.014 -0.1417236328125 0.302396875 -0.014125 -0.13543701171875 0.302396875 -0.01425 -0.127655029296875 0.302396875 -0.014375 -0.119476318359375 0.302396875 -0.0145 -0.109130859375 0.302396875 -0.014625 -0.098785400390625 0.302396875 -0.01475 -0.0863037109375 0.302396875 -0.014875 -0.072845458984375 0.302396875 -0.015 -0.06005859375 0.302396875 -0.015125 -0.04522705078125 0.302396875 -0.01525 -0.03143310546875 0.302396875 -0.015375 -0.01580810546875 0.302396875 +0.011625 -0.003143310546875 0.302396875 +0.01175 -0.0189208984375 0.302396875 +0.011875 -0.032958984375 0.302396875 +0.012 -0.0482177734375 0.302396875 +0.012125 -0.06146240234375 0.302396875 +0.01225 -0.0755615234375 0.302396875 +0.012375 -0.088836669921875 0.302396875 +0.0125 -0.0999755859375 0.302396875 +0.012625 -0.11126708984375 0.302396875 +0.01275 -0.120391845703125 0.302396875 +0.012875 -0.129302978515625 0.302396875 +0.013 -0.13677978515625 0.302396875 +0.013125 -0.1422119140625 0.302396875 +0.01325 -0.14678955078125 0.302396875 +0.013375 -0.1495361328125 0.302396875 +0.0135 -0.151031494140625 0.302396875 +0.013625 -0.15087890625 0.302396875 +0.01375 -0.1492919921875 0.302396875 +0.013875 -0.14599609375 0.302396875 +0.014 -0.141693115234375 0.302396875 +0.014125 -0.135406494140625 0.302396875 +0.01425 -0.12762451171875 0.302396875 +0.014375 -0.11944580078125 0.302396875 +0.0145 -0.109100341796875 0.302396875 +0.014625 -0.0987548828125 0.302396875 +0.01475 -0.086273193359375 0.302396875 +0.014875 -0.07281494140625 0.302396875 +0.015 -0.060028076171875 0.302396875 +0.015125 -0.045196533203125 0.302396875 +0.01525 -0.031402587890625 0.302396875 +0.015375 -0.015777587890625 0.302396875 0.0155 0.0 0.302396875 0.015625 0.01422119140625 0.302396875 0.01575 0.029876708984375 0.302396875 @@ -154,37 +154,37 @@ 0.019125 0.034515380859375 0.302396875 0.01925 0.0189208984375 0.302396875 0.019375 0.004730224609375 0.302396875 -0.0195 -0.011077880859375 0.302396875 -0.019625 -0.025238037109375 0.302396875 -0.01975 -0.040679931640625 0.302396875 -0.019875 -0.0556640625 0.302396875 -0.02 -0.068634033203125 0.302396875 -0.020125 -0.082366943359375 0.302396875 -0.02025 -0.09393310546875 0.302396875 -0.020375 -0.10577392578125 0.302396875 -0.0205 -0.116485595703125 0.302396875 -0.020625 -0.12506103515625 0.302396875 -0.02075 -0.13323974609375 0.302396875 -0.020875 -0.139373779296875 0.302396875 -0.021 -0.144744873046875 0.302396875 -0.021125 -0.148529052734375 0.302396875 -0.02125 -0.1505126953125 0.302396875 -0.021375 -0.15118408203125 0.302396875 -0.0215 -0.150360107421875 0.302396875 -0.021625 -0.14788818359375 0.302396875 -0.02175 -0.143798828125 0.302396875 -0.021875 -0.138763427734375 0.302396875 -0.022 -0.1317138671875 0.302396875 -0.022125 -0.1241455078125 0.302396875 -0.02225 -0.11444091796875 0.302396875 -0.022375 -0.103515625 0.302396875 -0.0225 -0.092681884765625 0.302396875 -0.022625 -0.079681396484375 0.302396875 -0.02275 -0.067230224609375 0.302396875 -0.022875 -0.052703857421875 0.302396875 -0.023 -0.03759765625 0.302396875 -0.023125 -0.023651123046875 0.302396875 -0.02325 -0.0079345703125 0.302396875 +0.0195 -0.01104736328125 0.302396875 +0.019625 -0.02520751953125 0.302396875 +0.01975 -0.0406494140625 0.302396875 +0.019875 -0.055633544921875 0.302396875 +0.02 -0.068603515625 0.302396875 +0.020125 -0.08233642578125 0.302396875 +0.02025 -0.093902587890625 0.302396875 +0.020375 -0.105743408203125 0.302396875 +0.0205 -0.116455078125 0.302396875 +0.020625 -0.125030517578125 0.302396875 +0.02075 -0.133209228515625 0.302396875 +0.020875 -0.13934326171875 0.302396875 +0.021 -0.14471435546875 0.302396875 +0.021125 -0.14849853515625 0.302396875 +0.02125 -0.150482177734375 0.302396875 +0.021375 -0.151153564453125 0.302396875 +0.0215 -0.15032958984375 0.302396875 +0.021625 -0.147857666015625 0.302396875 +0.02175 -0.143768310546875 0.302396875 +0.021875 -0.13873291015625 0.302396875 +0.022 -0.131683349609375 0.302396875 +0.022125 -0.124114990234375 0.302396875 +0.02225 -0.114410400390625 0.302396875 +0.022375 -0.103485107421875 0.302396875 +0.0225 -0.0926513671875 0.302396875 +0.022625 -0.07965087890625 0.302396875 +0.02275 -0.06719970703125 0.302396875 +0.022875 -0.05267333984375 0.302396875 +0.023 -0.037567138671875 0.302396875 +0.023125 -0.02362060546875 0.302396875 +0.02325 -0.007904052734375 0.302396875 0.023375 0.006317138671875 0.302396875 0.0235 0.022064208984375 0.302396875 0.023625 0.037567138671875 0.302396875 @@ -216,37 +216,37 @@ 0.026875 0.042144775390625 0.302396875 0.027 0.026763916015625 0.302396875 0.027125 0.01263427734375 0.302396875 -0.02725 -0.003173828125 0.302396875 -0.027375 -0.018951416015625 0.302396875 -0.0275 -0.032989501953125 0.302396875 -0.027625 -0.048248291015625 0.302396875 -0.02775 -0.061492919921875 0.302396875 -0.027875 -0.075592041015625 0.302396875 -0.028 -0.0888671875 0.302396875 -0.028125 -0.100006103515625 0.302396875 -0.02825 -0.111297607421875 0.302396875 -0.028375 -0.12042236328125 0.302396875 -0.02850000000000001 -0.12933349609375 0.302396875 -0.028625 -0.136810302734375 0.302396875 -0.02875 -0.142242431640625 0.302396875 -0.028875 -0.146820068359375 0.302396875 -0.029 -0.149566650390625 0.302396875 -0.029125 -0.15106201171875 0.302396875 -0.02925 -0.150909423828125 0.302396875 -0.029375 -0.149322509765625 0.302396875 -0.0295 -0.146026611328125 0.302396875 -0.029625 -0.1417236328125 0.302396875 -0.02975000000000001 -0.13543701171875 0.302396875 -0.029875 -0.127655029296875 0.302396875 -0.03 -0.119476318359375 0.302396875 -0.030125 -0.109130859375 0.302396875 -0.03025 -0.098785400390625 0.302396875 -0.030375 -0.0863037109375 0.302396875 -0.0305 -0.072845458984375 0.302396875 -0.030625 -0.06005859375 0.302396875 -0.03075 -0.04522705078125 0.302396875 -0.03087499999999999 -0.03143310546875 0.302396875 -0.031 -0.01580810546875 0.302396875 +0.02725 -0.003143310546875 0.302396875 +0.027375 -0.0189208984375 0.302396875 +0.0275 -0.032958984375 0.302396875 +0.027625 -0.0482177734375 0.302396875 +0.02775 -0.06146240234375 0.302396875 +0.027875 -0.0755615234375 0.302396875 +0.028 -0.088836669921875 0.302396875 +0.028125 -0.0999755859375 0.302396875 +0.02825 -0.11126708984375 0.302396875 +0.028375 -0.120391845703125 0.302396875 +0.02850000000000001 -0.129302978515625 0.302396875 +0.028625 -0.13677978515625 0.302396875 +0.02875 -0.1422119140625 0.302396875 +0.028875 -0.14678955078125 0.302396875 +0.029 -0.1495361328125 0.302396875 +0.029125 -0.151031494140625 0.302396875 +0.02925 -0.15087890625 0.302396875 +0.029375 -0.1492919921875 0.302396875 +0.0295 -0.14599609375 0.302396875 +0.029625 -0.141693115234375 0.302396875 +0.02975000000000001 -0.135406494140625 0.302396875 +0.029875 -0.12762451171875 0.302396875 +0.03 -0.11944580078125 0.302396875 +0.030125 -0.109100341796875 0.302396875 +0.03025 -0.0987548828125 0.302396875 +0.030375 -0.086273193359375 0.302396875 +0.0305 -0.07281494140625 0.302396875 +0.030625 -0.060028076171875 0.302396875 +0.03075 -0.045196533203125 0.302396875 +0.03087499999999999 -0.031402587890625 0.302396875 +0.031 -0.015777587890625 0.302396875 0.031125 0.0 0.302396875 0.03125 0.01422119140625 0.302396875 0.031375 0.029876708984375 0.302396875 @@ -279,37 +279,37 @@ 0.03475000000000001 0.04620361328125 0.4047937500000001 0.034875 0.02532958984375 0.4047937500000001 0.035 0.00634765625 0.4047937500000001 -0.03512500000000001 -0.01483154296875 0.4047937500000001 -0.03525 -0.03375244140625 0.4047937500000001 -0.035375 -0.054443359375 0.4047937500000001 -0.0355 -0.07452392578125 0.4047937500000001 -0.03562500000000001 -0.091888427734375 0.4047937500000001 -0.03575 -0.1102294921875 0.4047937500000001 -0.035875 -0.125701904296875 0.4047937500000001 -0.03600000000000001 -0.1416015625 0.4047937500000001 -0.036125 -0.15594482421875 0.4047937500000001 -0.03625 -0.167388916015625 0.4047937500000001 -0.036375 -0.178375244140625 0.4047937500000001 -0.0365 -0.18658447265625 0.4047937500000001 -0.036625 -0.193756103515625 0.4047937500000001 -0.03675 -0.19879150390625 0.4047937500000001 -0.036875 -0.20147705078125 0.4047937500000001 -0.037 -0.202362060546875 0.4047937500000001 -0.03712499999999999 -0.201263427734375 0.4047937500000001 -0.03725 -0.197967529296875 0.4047937500000001 -0.037375 -0.192474365234375 0.4047937500000001 -0.0375 -0.18572998046875 0.4047937500000001 -0.037625 -0.17633056640625 0.4047937500000001 -0.03775 -0.16619873046875 0.4047937500000001 -0.037875 -0.1531982421875 0.4047937500000001 -0.038 -0.1385498046875 0.4047937500000001 -0.038125 -0.124053955078125 0.4047937500000001 -0.03825 -0.106658935546875 0.4047937500000001 -0.038375 -0.089996337890625 0.4047937500000001 -0.0385 -0.070556640625 0.4047937500000001 -0.038625 -0.050323486328125 0.4047937500000001 -0.03875 -0.03167724609375 0.4047937500000001 -0.038875 -0.010589599609375 0.4047937500000001 +0.03512500000000001 -0.014801025390625 0.4047937500000001 +0.03525 -0.033721923828125 0.4047937500000001 +0.035375 -0.054412841796875 0.4047937500000001 +0.0355 -0.074493408203125 0.4047937500000001 +0.03562500000000001 -0.09185791015625 0.4047937500000001 +0.03575 -0.110198974609375 0.4047937500000001 +0.035875 -0.12567138671875 0.4047937500000001 +0.03600000000000001 -0.141571044921875 0.4047937500000001 +0.036125 -0.155914306640625 0.4047937500000001 +0.03625 -0.1673583984375 0.4047937500000001 +0.036375 -0.1783447265625 0.4047937500000001 +0.0365 -0.186553955078125 0.4047937500000001 +0.036625 -0.1937255859375 0.4047937500000001 +0.03675 -0.198760986328125 0.4047937500000001 +0.036875 -0.201446533203125 0.4047937500000001 +0.037 -0.20233154296875 0.4047937500000001 +0.03712499999999999 -0.20123291015625 0.4047937500000001 +0.03725 -0.19793701171875 0.4047937500000001 +0.037375 -0.19244384765625 0.4047937500000001 +0.0375 -0.185699462890625 0.4047937500000001 +0.037625 -0.176300048828125 0.4047937500000001 +0.03775 -0.166168212890625 0.4047937500000001 +0.037875 -0.153167724609375 0.4047937500000001 +0.038 -0.138519287109375 0.4047937500000001 +0.038125 -0.1240234375 0.4047937500000001 +0.03825 -0.10662841796875 0.4047937500000001 +0.038375 -0.0899658203125 0.4047937500000001 +0.0385 -0.070526123046875 0.4047937500000001 +0.038625 -0.05029296875 0.4047937500000001 +0.03875 -0.031646728515625 0.4047937500000001 +0.038875 -0.01055908203125 0.4047937500000001 0.039 0.008453369140625 0.4047937500000001 0.039125 0.029541015625 0.4047937500000001 0.03925 0.05029296875 0.4047937500000001 @@ -341,37 +341,37 @@ 0.0425 0.056427001953125 0.4047937500000001 0.042625 0.03582763671875 0.4047937500000001 0.04275 0.01690673828125 0.4047937500000001 -0.04287500000000001 -0.004241943359375 0.4047937500000001 -0.04300000000000001 -0.025360107421875 0.4047937500000001 -0.043125 -0.044158935546875 0.4047937500000001 -0.04325 -0.0645751953125 0.4047937500000001 -0.043375 -0.08233642578125 0.4047937500000001 -0.04350000000000001 -0.1011962890625 0.4047937500000001 -0.04362500000000001 -0.11895751953125 0.4047937500000001 -0.04375000000000001 -0.13385009765625 0.4047937500000001 -0.043875 -0.14898681640625 0.4047937500000001 -0.04399999999999999 -0.16119384765625 0.4047937500000001 -0.044125 -0.173126220703125 0.4047937500000001 -0.04425 -0.183135986328125 0.4047937500000001 -0.044375 -0.1904296875 0.4047937500000001 -0.04449999999999999 -0.196533203125 0.4047937500000001 -0.04462499999999999 -0.200225830078125 0.4047937500000001 -0.04475 -0.20220947265625 0.4047937500000001 -0.044875 -0.201995849609375 0.4047937500000001 -0.045 -0.19989013671875 0.4047937500000001 -0.045125 -0.19549560546875 0.4047937500000001 -0.04525 -0.189697265625 0.4047937500000001 -0.045375 -0.1812744140625 0.4047937500000001 -0.0455 -0.170867919921875 0.4047937500000001 -0.045625 -0.159912109375 0.4047937500000001 -0.04575 -0.146087646484375 0.4047937500000001 -0.045875 -0.132232666015625 0.4047937500000001 -0.046 -0.115509033203125 0.4047937500000001 -0.046125 -0.097503662109375 0.4047937500000001 -0.04625 -0.08038330078125 0.4047937500000001 -0.046375 -0.060516357421875 0.4047937500000001 -0.04649999999999999 -0.042083740234375 0.4047937500000001 -0.046625 -0.02117919921875 0.4047937500000001 +0.04287500000000001 -0.00421142578125 0.4047937500000001 +0.04300000000000001 -0.02532958984375 0.4047937500000001 +0.043125 -0.04412841796875 0.4047937500000001 +0.04325 -0.064544677734375 0.4047937500000001 +0.043375 -0.082305908203125 0.4047937500000001 +0.04350000000000001 -0.101165771484375 0.4047937500000001 +0.04362500000000001 -0.118927001953125 0.4047937500000001 +0.04375000000000001 -0.133819580078125 0.4047937500000001 +0.043875 -0.148956298828125 0.4047937500000001 +0.04399999999999999 -0.161163330078125 0.4047937500000001 +0.044125 -0.173095703125 0.4047937500000001 +0.04425 -0.18310546875 0.4047937500000001 +0.044375 -0.190399169921875 0.4047937500000001 +0.04449999999999999 -0.196502685546875 0.4047937500000001 +0.04462499999999999 -0.2001953125 0.4047937500000001 +0.04475 -0.202178955078125 0.4047937500000001 +0.044875 -0.20196533203125 0.4047937500000001 +0.045 -0.199859619140625 0.4047937500000001 +0.045125 -0.195465087890625 0.4047937500000001 +0.04525 -0.189666748046875 0.4047937500000001 +0.045375 -0.181243896484375 0.4047937500000001 +0.0455 -0.17083740234375 0.4047937500000001 +0.045625 -0.159881591796875 0.4047937500000001 +0.04575 -0.14605712890625 0.4047937500000001 +0.045875 -0.1322021484375 0.4047937500000001 +0.046 -0.115478515625 0.4047937500000001 +0.046125 -0.09747314453125 0.4047937500000001 +0.04625 -0.080352783203125 0.4047937500000001 +0.046375 -0.06048583984375 0.4047937500000001 +0.04649999999999999 -0.04205322265625 0.4047937500000001 +0.046625 -0.021148681640625 0.4047937500000001 0.04675000000000001 0.0 0.4047937500000001 0.046875 0.019012451171875 0.4047937500000001 0.04699999999999999 0.03997802734375 0.4047937500000001 @@ -404,37 +404,37 @@ 0.05037500000000001 0.04620361328125 0.4047937500000001 0.0505 0.02532958984375 0.4047937500000001 0.05062500000000001 0.00634765625 0.4047937500000001 -0.05075000000000001 -0.01483154296875 0.4047937500000001 -0.050875 -0.03375244140625 0.4047937500000001 -0.051 -0.054443359375 0.4047937500000001 -0.051125 -0.07452392578125 0.4047937500000001 -0.05125000000000001 -0.091888427734375 0.4047937500000001 -0.051375 -0.1102294921875 0.4047937500000001 -0.0515 -0.125701904296875 0.4047937500000001 -0.05162500000000001 -0.1416015625 0.4047937500000001 -0.05175000000000001 -0.15594482421875 0.4047937500000001 -0.051875 -0.167388916015625 0.4047937500000001 -0.052 -0.178375244140625 0.4047937500000001 -0.052125 -0.18658447265625 0.4047937500000001 -0.05225 -0.193756103515625 0.4047937500000001 -0.05237499999999999 -0.19879150390625 0.4047937500000001 -0.0525 -0.20147705078125 0.4047937500000001 -0.052625 -0.202362060546875 0.4047937500000001 -0.05274999999999999 -0.201263427734375 0.4047937500000001 -0.052875 -0.197967529296875 0.4047937500000001 -0.05300000000000001 -0.192474365234375 0.4047937500000001 -0.053125 -0.18572998046875 0.4047937500000001 -0.05324999999999999 -0.17633056640625 0.4047937500000001 -0.05337499999999999 -0.16619873046875 0.4047937500000001 -0.05350000000000001 -0.1531982421875 0.4047937500000001 -0.053625 -0.1385498046875 0.4047937500000001 -0.05375 -0.124053955078125 0.4047937500000001 -0.05387499999999999 -0.106658935546875 0.4047937500000001 -0.054 -0.089996337890625 0.4047937500000001 -0.054125 -0.070556640625 0.4047937500000001 -0.05425 -0.050323486328125 0.4047937500000001 -0.054375 -0.03167724609375 0.4047937500000001 -0.0545 -0.010589599609375 0.4047937500000001 +0.05075000000000001 -0.014801025390625 0.4047937500000001 +0.050875 -0.033721923828125 0.4047937500000001 +0.051 -0.054412841796875 0.4047937500000001 +0.051125 -0.074493408203125 0.4047937500000001 +0.05125000000000001 -0.09185791015625 0.4047937500000001 +0.051375 -0.110198974609375 0.4047937500000001 +0.0515 -0.12567138671875 0.4047937500000001 +0.05162500000000001 -0.141571044921875 0.4047937500000001 +0.05175000000000001 -0.155914306640625 0.4047937500000001 +0.051875 -0.1673583984375 0.4047937500000001 +0.052 -0.1783447265625 0.4047937500000001 +0.052125 -0.186553955078125 0.4047937500000001 +0.05225 -0.1937255859375 0.4047937500000001 +0.05237499999999999 -0.198760986328125 0.4047937500000001 +0.0525 -0.201446533203125 0.4047937500000001 +0.052625 -0.20233154296875 0.4047937500000001 +0.05274999999999999 -0.20123291015625 0.4047937500000001 +0.052875 -0.19793701171875 0.4047937500000001 +0.05300000000000001 -0.19244384765625 0.4047937500000001 +0.053125 -0.185699462890625 0.4047937500000001 +0.05324999999999999 -0.176300048828125 0.4047937500000001 +0.05337499999999999 -0.166168212890625 0.4047937500000001 +0.05350000000000001 -0.153167724609375 0.4047937500000001 +0.053625 -0.138519287109375 0.4047937500000001 +0.05375 -0.1240234375 0.4047937500000001 +0.05387499999999999 -0.10662841796875 0.4047937500000001 +0.054 -0.0899658203125 0.4047937500000001 +0.054125 -0.070526123046875 0.4047937500000001 +0.05425 -0.05029296875 0.4047937500000001 +0.054375 -0.031646728515625 0.4047937500000001 +0.0545 -0.01055908203125 0.4047937500000001 0.054625 0.008453369140625 0.4047937500000001 0.05475 0.029541015625 0.4047937500000001 0.054875 0.05029296875 0.4047937500000001 @@ -466,37 +466,37 @@ 0.058125 0.056427001953125 0.4047937500000001 0.05825 0.03582763671875 0.4047937500000001 0.058375 0.01690673828125 0.4047937500000001 -0.05850000000000001 -0.004241943359375 0.4047937500000001 -0.05862500000000001 -0.025360107421875 0.4047937500000001 -0.05875 -0.044158935546875 0.4047937500000001 -0.058875 -0.0645751953125 0.4047937500000001 -0.059 -0.08233642578125 0.4047937500000001 -0.05912500000000001 -0.1011962890625 0.4047937500000001 -0.05925000000000001 -0.11895751953125 0.4047937500000001 -0.059375 -0.13385009765625 0.4047937500000001 -0.05950000000000001 -0.14898681640625 0.4047937500000001 -0.059625 -0.16119384765625 0.4047937500000001 -0.05975000000000001 -0.173126220703125 0.4047937500000001 -0.059875 -0.183135986328125 0.4047937500000001 -0.06 -0.1904296875 0.4047937500000001 -0.06012499999999999 -0.196533203125 0.4047937500000001 -0.06025 -0.200225830078125 0.4047937500000001 -0.060375 -0.20220947265625 0.4047937500000001 -0.0605 -0.201995849609375 0.4047937500000001 -0.060625 -0.19989013671875 0.4047937500000001 -0.06074999999999999 -0.19549560546875 0.4047937500000001 -0.060875 -0.189697265625 0.4047937500000001 -0.061 -0.1812744140625 0.4047937500000001 -0.061125 -0.170867919921875 0.4047937500000001 -0.06125 -0.159912109375 0.4047937500000001 -0.061375 -0.146087646484375 0.4047937500000001 -0.0615 -0.132232666015625 0.4047937500000001 -0.061625 -0.115509033203125 0.4047937500000001 -0.06174999999999999 -0.097503662109375 0.4047937500000001 -0.061875 -0.08038330078125 0.4047937500000001 -0.062 -0.060516357421875 0.4047937500000001 -0.06212499999999999 -0.042083740234375 0.4047937500000001 -0.06225000000000001 -0.02117919921875 0.4047937500000001 +0.05850000000000001 -0.00421142578125 0.4047937500000001 +0.05862500000000001 -0.02532958984375 0.4047937500000001 +0.05875 -0.04412841796875 0.4047937500000001 +0.058875 -0.064544677734375 0.4047937500000001 +0.059 -0.082305908203125 0.4047937500000001 +0.05912500000000001 -0.101165771484375 0.4047937500000001 +0.05925000000000001 -0.118927001953125 0.4047937500000001 +0.059375 -0.133819580078125 0.4047937500000001 +0.05950000000000001 -0.148956298828125 0.4047937500000001 +0.059625 -0.161163330078125 0.4047937500000001 +0.05975000000000001 -0.173095703125 0.4047937500000001 +0.059875 -0.18310546875 0.4047937500000001 +0.06 -0.190399169921875 0.4047937500000001 +0.06012499999999999 -0.196502685546875 0.4047937500000001 +0.06025 -0.2001953125 0.4047937500000001 +0.060375 -0.202178955078125 0.4047937500000001 +0.0605 -0.20196533203125 0.4047937500000001 +0.060625 -0.199859619140625 0.4047937500000001 +0.06074999999999999 -0.195465087890625 0.4047937500000001 +0.060875 -0.189666748046875 0.4047937500000001 +0.061 -0.181243896484375 0.4047937500000001 +0.061125 -0.17083740234375 0.4047937500000001 +0.06125 -0.159881591796875 0.4047937500000001 +0.061375 -0.14605712890625 0.4047937500000001 +0.0615 -0.1322021484375 0.4047937500000001 +0.061625 -0.115478515625 0.4047937500000001 +0.06174999999999999 -0.09747314453125 0.4047937500000001 +0.061875 -0.080352783203125 0.4047937500000001 +0.062 -0.06048583984375 0.4047937500000001 +0.06212499999999999 -0.04205322265625 0.4047937500000001 +0.06225000000000001 -0.021148681640625 0.4047937500000001 0.06237500000000001 0.0 0.4047937500000001 0.0625 0.019012451171875 0.4047937500000001 0.06262499999999999 0.03997802734375 0.4047937500000001 @@ -529,37 +529,37 @@ 0.06600000000000001 0.057891845703125 0.507190625 0.066125 0.031768798828125 0.507190625 0.06625000000000001 0.0079345703125 0.507190625 -0.06637500000000001 -0.018585205078125 0.507190625 -0.0665 -0.04229736328125 0.507190625 -0.066625 -0.068206787109375 0.507190625 -0.06675 -0.093353271484375 0.507190625 -0.06687500000000001 -0.115142822265625 0.507190625 -0.067 -0.13812255859375 0.507190625 -0.067125 -0.15753173828125 0.507190625 -0.06725000000000001 -0.17742919921875 0.507190625 -0.06737500000000001 -0.195404052734375 0.507190625 -0.0675 -0.209747314453125 0.507190625 -0.067625 -0.223480224609375 0.507190625 -0.06775 -0.2337646484375 0.507190625 -0.06787500000000001 -0.242767333984375 0.507190625 -0.06800000000000001 -0.24908447265625 0.507190625 -0.068125 -0.252471923828125 0.507190625 -0.06825000000000001 -0.253570556640625 0.507190625 -0.068375 -0.252197265625 0.507190625 -0.06850000000000001 -0.248046875 0.507190625 -0.06862500000000001 -0.241180419921875 0.507190625 -0.06875 -0.23272705078125 0.507190625 -0.06887500000000001 -0.220947265625 0.507190625 -0.069 -0.208221435546875 0.507190625 -0.06912500000000001 -0.19195556640625 0.507190625 -0.06925000000000001 -0.173583984375 0.507190625 -0.06937500000000001 -0.155426025390625 0.507190625 -0.06950000000000001 -0.133636474609375 0.507190625 -0.069625 -0.112762451171875 0.507190625 -0.06975 -0.088409423828125 0.507190625 -0.06987500000000001 -0.063079833984375 0.507190625 -0.07000000000000001 -0.0396728515625 0.507190625 -0.070125 -0.013275146484375 0.507190625 +0.06637500000000001 -0.0185546875 0.507190625 +0.0665 -0.042266845703125 0.507190625 +0.066625 -0.06817626953125 0.507190625 +0.06675 -0.09332275390625 0.507190625 +0.06687500000000001 -0.1151123046875 0.507190625 +0.067 -0.138092041015625 0.507190625 +0.067125 -0.157501220703125 0.507190625 +0.06725000000000001 -0.177398681640625 0.507190625 +0.06737500000000001 -0.19537353515625 0.507190625 +0.0675 -0.209716796875 0.507190625 +0.067625 -0.22344970703125 0.507190625 +0.06775 -0.233734130859375 0.507190625 +0.06787500000000001 -0.24273681640625 0.507190625 +0.06800000000000001 -0.249053955078125 0.507190625 +0.068125 -0.25244140625 0.507190625 +0.06825000000000001 -0.2535400390625 0.507190625 +0.068375 -0.252166748046875 0.507190625 +0.06850000000000001 -0.248016357421875 0.507190625 +0.06862500000000001 -0.24114990234375 0.507190625 +0.06875 -0.232696533203125 0.507190625 +0.06887500000000001 -0.220916748046875 0.507190625 +0.069 -0.20819091796875 0.507190625 +0.06912500000000001 -0.191925048828125 0.507190625 +0.06925000000000001 -0.173553466796875 0.507190625 +0.06937500000000001 -0.1553955078125 0.507190625 +0.06950000000000001 -0.13360595703125 0.507190625 +0.069625 -0.11273193359375 0.507190625 +0.06975 -0.08837890625 0.507190625 +0.06987500000000001 -0.06304931640625 0.507190625 +0.07000000000000001 -0.039642333984375 0.507190625 +0.070125 -0.01324462890625 0.507190625 0.07025000000000001 0.010589599609375 0.507190625 0.07037500000000001 0.037017822265625 0.507190625 0.07050000000000001 0.06304931640625 0.507190625 @@ -591,37 +591,37 @@ 0.07374999999999999 0.07073974609375 0.507190625 0.073875 0.044891357421875 0.507190625 0.074 0.021209716796875 0.507190625 -0.074125 -0.00531005859375 0.507190625 -0.07424999999999999 -0.03179931640625 0.507190625 -0.07437499999999999 -0.055328369140625 0.507190625 -0.0745 -0.080902099609375 0.507190625 -0.07462499999999999 -0.1031494140625 0.507190625 -0.07475 -0.126800537109375 0.507190625 -0.07487500000000001 -0.1490478515625 0.507190625 -0.075 -0.167694091796875 0.507190625 -0.07512499999999999 -0.186676025390625 0.507190625 -0.07524999999999999 -0.201995849609375 0.507190625 -0.075375 -0.2169189453125 0.507190625 -0.0755 -0.229461669921875 0.507190625 -0.075625 -0.23858642578125 0.507190625 -0.07574999999999999 -0.24627685546875 0.507190625 -0.075875 -0.2508544921875 0.507190625 -0.076 -0.25335693359375 0.507190625 -0.076125 -0.253082275390625 0.507190625 -0.07625 -0.250457763671875 0.507190625 -0.07637499999999999 -0.24493408203125 0.507190625 -0.0765 -0.2376708984375 0.507190625 -0.076625 -0.227142333984375 0.507190625 -0.07675 -0.214111328125 0.507190625 -0.076875 -0.20037841796875 0.507190625 -0.077 -0.18304443359375 0.507190625 -0.077125 -0.16571044921875 0.507190625 -0.07725 -0.144744873046875 0.507190625 -0.07737499999999999 -0.122161865234375 0.507190625 -0.0775 -0.1007080078125 0.507190625 -0.077625 -0.075836181640625 0.507190625 -0.07774999999999999 -0.052734375 0.507190625 -0.07787500000000001 -0.026519775390625 0.507190625 +0.074125 -0.005279541015625 0.507190625 +0.07424999999999999 -0.031768798828125 0.507190625 +0.07437499999999999 -0.0552978515625 0.507190625 +0.0745 -0.08087158203125 0.507190625 +0.07462499999999999 -0.103118896484375 0.507190625 +0.07475 -0.12677001953125 0.507190625 +0.07487500000000001 -0.149017333984375 0.507190625 +0.075 -0.16766357421875 0.507190625 +0.07512499999999999 -0.1866455078125 0.507190625 +0.07524999999999999 -0.20196533203125 0.507190625 +0.075375 -0.216888427734375 0.507190625 +0.0755 -0.22943115234375 0.507190625 +0.075625 -0.238555908203125 0.507190625 +0.07574999999999999 -0.246246337890625 0.507190625 +0.075875 -0.250823974609375 0.507190625 +0.076 -0.253326416015625 0.507190625 +0.076125 -0.2530517578125 0.507190625 +0.07625 -0.25042724609375 0.507190625 +0.07637499999999999 -0.244903564453125 0.507190625 +0.0765 -0.237640380859375 0.507190625 +0.076625 -0.22711181640625 0.507190625 +0.07675 -0.214080810546875 0.507190625 +0.076875 -0.200347900390625 0.507190625 +0.077 -0.183013916015625 0.507190625 +0.077125 -0.165679931640625 0.507190625 +0.07725 -0.14471435546875 0.507190625 +0.07737499999999999 -0.12213134765625 0.507190625 +0.0775 -0.100677490234375 0.507190625 +0.077625 -0.0758056640625 0.507190625 +0.07774999999999999 -0.052703857421875 0.507190625 +0.07787500000000001 -0.0264892578125 0.507190625 0.07800000000000001 0.0 0.507190625 0.078125 0.023834228515625 0.507190625 0.07824999999999999 0.05010986328125 0.507190625 @@ -654,37 +654,37 @@ 0.081625 0.057891845703125 0.507190625 0.08175000000000001 0.031768798828125 0.507190625 0.081875 0.0079345703125 0.507190625 -0.08200000000000001 -0.018585205078125 0.507190625 -0.082125 -0.04229736328125 0.507190625 -0.08225 -0.068206787109375 0.507190625 -0.08237500000000001 -0.093353271484375 0.507190625 -0.0825 -0.115142822265625 0.507190625 -0.08262500000000001 -0.13812255859375 0.507190625 -0.08275 -0.15753173828125 0.507190625 -0.08287500000000001 -0.17742919921875 0.507190625 -0.08300000000000001 -0.195404052734375 0.507190625 -0.083125 -0.209747314453125 0.507190625 -0.08324999999999999 -0.223480224609375 0.507190625 -0.083375 -0.2337646484375 0.507190625 -0.08350000000000001 -0.242767333984375 0.507190625 -0.08362500000000001 -0.24908447265625 0.507190625 -0.08375 -0.252471923828125 0.507190625 -0.08387500000000001 -0.253570556640625 0.507190625 -0.084 -0.252197265625 0.507190625 -0.08412500000000001 -0.248046875 0.507190625 -0.08425000000000001 -0.241180419921875 0.507190625 -0.084375 -0.23272705078125 0.507190625 -0.08450000000000001 -0.220947265625 0.507190625 -0.084625 -0.208221435546875 0.507190625 -0.08475 -0.19195556640625 0.507190625 -0.08487500000000001 -0.173583984375 0.507190625 -0.085 -0.155426025390625 0.507190625 -0.08512500000000001 -0.133636474609375 0.507190625 -0.08525 -0.112762451171875 0.507190625 -0.085375 -0.088409423828125 0.507190625 -0.08550000000000001 -0.063079833984375 0.507190625 -0.085625 -0.0396728515625 0.507190625 -0.08575000000000001 -0.013275146484375 0.507190625 +0.08200000000000001 -0.0185546875 0.507190625 +0.082125 -0.042266845703125 0.507190625 +0.08225 -0.06817626953125 0.507190625 +0.08237500000000001 -0.09332275390625 0.507190625 +0.0825 -0.1151123046875 0.507190625 +0.08262500000000001 -0.138092041015625 0.507190625 +0.08275 -0.157501220703125 0.507190625 +0.08287500000000001 -0.177398681640625 0.507190625 +0.08300000000000001 -0.19537353515625 0.507190625 +0.083125 -0.209716796875 0.507190625 +0.08324999999999999 -0.22344970703125 0.507190625 +0.083375 -0.233734130859375 0.507190625 +0.08350000000000001 -0.24273681640625 0.507190625 +0.08362500000000001 -0.249053955078125 0.507190625 +0.08375 -0.25244140625 0.507190625 +0.08387500000000001 -0.2535400390625 0.507190625 +0.084 -0.252166748046875 0.507190625 +0.08412500000000001 -0.248016357421875 0.507190625 +0.08425000000000001 -0.24114990234375 0.507190625 +0.084375 -0.232696533203125 0.507190625 +0.08450000000000001 -0.220916748046875 0.507190625 +0.084625 -0.20819091796875 0.507190625 +0.08475 -0.191925048828125 0.507190625 +0.08487500000000001 -0.173553466796875 0.507190625 +0.085 -0.1553955078125 0.507190625 +0.08512500000000001 -0.13360595703125 0.507190625 +0.08525 -0.11273193359375 0.507190625 +0.085375 -0.08837890625 0.507190625 +0.08550000000000001 -0.06304931640625 0.507190625 +0.085625 -0.039642333984375 0.507190625 +0.08575000000000001 -0.01324462890625 0.507190625 0.08587500000000002 0.010589599609375 0.507190625 0.08600000000000001 0.037017822265625 0.507190625 0.08612500000000001 0.06304931640625 0.507190625 @@ -716,37 +716,37 @@ 0.089375 0.07073974609375 0.507190625 0.08949999999999999 0.044891357421875 0.507190625 0.089625 0.021209716796875 0.507190625 -0.08975 -0.00531005859375 0.507190625 -0.08987499999999999 -0.03179931640625 0.507190625 -0.09 -0.055328369140625 0.507190625 -0.09012499999999999 -0.080902099609375 0.507190625 -0.09025 -0.1031494140625 0.507190625 -0.090375 -0.126800537109375 0.507190625 -0.09050000000000001 -0.1490478515625 0.507190625 -0.090625 -0.167694091796875 0.507190625 -0.09074999999999999 -0.186676025390625 0.507190625 -0.09087499999999999 -0.201995849609375 0.507190625 -0.091 -0.2169189453125 0.507190625 -0.09112500000000001 -0.229461669921875 0.507190625 -0.09125 -0.23858642578125 0.507190625 -0.09137499999999999 -0.24627685546875 0.507190625 -0.0915 -0.2508544921875 0.507190625 -0.091625 -0.25335693359375 0.507190625 -0.09175000000000001 -0.253082275390625 0.507190625 -0.091875 -0.250457763671875 0.507190625 -0.09199999999999999 -0.24493408203125 0.507190625 -0.092125 -0.2376708984375 0.507190625 -0.09225 -0.227142333984375 0.507190625 -0.09237499999999999 -0.214111328125 0.507190625 -0.0925 -0.20037841796875 0.507190625 -0.09262499999999999 -0.18304443359375 0.507190625 -0.09275 -0.16571044921875 0.507190625 -0.092875 -0.144744873046875 0.507190625 -0.09299999999999999 -0.122161865234375 0.507190625 -0.093125 -0.1007080078125 0.507190625 -0.09324999999999999 -0.075836181640625 0.507190625 -0.093375 -0.052734375 0.507190625 -0.09350000000000001 -0.026519775390625 0.507190625 +0.08975 -0.005279541015625 0.507190625 +0.08987499999999999 -0.031768798828125 0.507190625 +0.09 -0.0552978515625 0.507190625 +0.09012499999999999 -0.08087158203125 0.507190625 +0.09025 -0.103118896484375 0.507190625 +0.090375 -0.12677001953125 0.507190625 +0.09050000000000001 -0.149017333984375 0.507190625 +0.090625 -0.16766357421875 0.507190625 +0.09074999999999999 -0.1866455078125 0.507190625 +0.09087499999999999 -0.20196533203125 0.507190625 +0.091 -0.216888427734375 0.507190625 +0.09112500000000001 -0.22943115234375 0.507190625 +0.09125 -0.238555908203125 0.507190625 +0.09137499999999999 -0.246246337890625 0.507190625 +0.0915 -0.250823974609375 0.507190625 +0.091625 -0.253326416015625 0.507190625 +0.09175000000000001 -0.2530517578125 0.507190625 +0.091875 -0.25042724609375 0.507190625 +0.09199999999999999 -0.244903564453125 0.507190625 +0.092125 -0.237640380859375 0.507190625 +0.09225 -0.22711181640625 0.507190625 +0.09237499999999999 -0.214080810546875 0.507190625 +0.0925 -0.200347900390625 0.507190625 +0.09262499999999999 -0.183013916015625 0.507190625 +0.09275 -0.165679931640625 0.507190625 +0.092875 -0.14471435546875 0.507190625 +0.09299999999999999 -0.12213134765625 0.507190625 +0.093125 -0.100677490234375 0.507190625 +0.09324999999999999 -0.0758056640625 0.507190625 +0.093375 -0.052703857421875 0.507190625 +0.09350000000000001 -0.0264892578125 0.507190625 0.09362500000000001 0.0 0.507190625 0.09375 0.023834228515625 0.507190625 0.09387499999999999 0.05010986328125 0.507190625 @@ -779,37 +779,37 @@ 0.09725 0.069580078125 0.6095875 0.09737500000000001 0.038177490234375 0.6095875 0.0975 0.009552001953125 0.6095875 -0.09762500000000001 -0.0223388671875 0.6095875 -0.09775 -0.05084228515625 0.6095875 -0.097875 -0.08197021484375 0.6095875 -0.09800000000000001 -0.112213134765625 0.6095875 -0.098125 -0.13836669921875 0.6095875 -0.09825000000000001 -0.166015625 0.6095875 -0.098375 -0.1893310546875 0.6095875 -0.09850000000000001 -0.2132568359375 0.6095875 -0.09862500000000001 -0.234832763671875 0.6095875 -0.09875 -0.2520751953125 0.6095875 -0.09887499999999999 -0.26861572265625 0.6095875 -0.099 -0.280975341796875 0.6095875 -0.09912500000000001 -0.291778564453125 0.6095875 -0.09925000000000001 -0.29937744140625 0.6095875 -0.099375 -0.303436279296875 0.6095875 -0.09950000000000001 -0.304779052734375 0.6095875 -0.099625 -0.3031005859375 0.6095875 -0.09975000000000001 -0.298126220703125 0.6095875 -0.09987500000000001 -0.28985595703125 0.6095875 -0.1 -0.27972412109375 0.6095875 -0.100125 -0.265533447265625 0.6095875 -0.10025 -0.250274658203125 0.6095875 -0.100375 -0.230712890625 0.6095875 -0.1005 -0.208648681640625 0.6095875 -0.100625 -0.186798095703125 0.6095875 -0.10075 -0.160614013671875 0.6095875 -0.100875 -0.135528564453125 0.6095875 -0.101 -0.106231689453125 0.6095875 -0.101125 -0.0758056640625 0.6095875 -0.10125 -0.04766845703125 0.6095875 -0.101375 -0.015960693359375 0.6095875 +0.09762500000000001 -0.022308349609375 0.6095875 +0.09775 -0.050811767578125 0.6095875 +0.097875 -0.081939697265625 0.6095875 +0.09800000000000001 -0.1121826171875 0.6095875 +0.098125 -0.138336181640625 0.6095875 +0.09825000000000001 -0.165985107421875 0.6095875 +0.098375 -0.189300537109375 0.6095875 +0.09850000000000001 -0.213226318359375 0.6095875 +0.09862500000000001 -0.23480224609375 0.6095875 +0.09875 -0.252044677734375 0.6095875 +0.09887499999999999 -0.268585205078125 0.6095875 +0.099 -0.28094482421875 0.6095875 +0.09912500000000001 -0.291748046875 0.6095875 +0.09925000000000001 -0.299346923828125 0.6095875 +0.099375 -0.30340576171875 0.6095875 +0.09950000000000001 -0.30474853515625 0.6095875 +0.099625 -0.303070068359375 0.6095875 +0.09975000000000001 -0.298095703125 0.6095875 +0.09987500000000001 -0.289825439453125 0.6095875 +0.1 -0.279693603515625 0.6095875 +0.100125 -0.2655029296875 0.6095875 +0.10025 -0.250244140625 0.6095875 +0.100375 -0.230682373046875 0.6095875 +0.1005 -0.2086181640625 0.6095875 +0.100625 -0.186767578125 0.6095875 +0.10075 -0.16058349609375 0.6095875 +0.100875 -0.135498046875 0.6095875 +0.101 -0.106201171875 0.6095875 +0.101125 -0.075775146484375 0.6095875 +0.10125 -0.047637939453125 0.6095875 +0.101375 -0.01593017578125 0.6095875 0.1015 0.01275634765625 0.6095875 0.101625 0.04449462890625 0.6095875 0.10175 0.075775146484375 0.6095875 @@ -841,37 +841,37 @@ 0.105 0.084991455078125 0.6095875 0.105125 0.053955078125 0.6095875 0.10525 0.025482177734375 0.6095875 -0.105375 -0.00640869140625 0.6095875 -0.1055 -0.0382080078125 0.6095875 -0.105625 -0.066497802734375 0.6095875 -0.10575 -0.09722900390625 0.6095875 -0.105875 -0.12396240234375 0.6095875 -0.106 -0.15240478515625 0.6095875 -0.106125 -0.17913818359375 0.6095875 -0.10625 -0.201568603515625 0.6095875 -0.106375 -0.224334716796875 0.6095875 -0.1065 -0.242767333984375 0.6095875 -0.106625 -0.260711669921875 0.6095875 -0.10675 -0.275787353515625 0.6095875 -0.106875 -0.286773681640625 0.6095875 -0.107 -0.295989990234375 0.6095875 -0.107125 -0.301513671875 0.6095875 -0.10725 -0.30450439453125 0.6095875 -0.107375 -0.304168701171875 0.6095875 -0.1075 -0.301025390625 0.6095875 -0.107625 -0.294403076171875 0.6095875 -0.10775 -0.285675048828125 0.6095875 -0.107875 -0.272979736328125 0.6095875 -0.108 -0.257354736328125 0.6095875 -0.108125 -0.2408447265625 0.6095875 -0.10825 -0.219970703125 0.6095875 -0.108375 -0.19915771484375 0.6095875 -0.1085 -0.1739501953125 0.6095875 -0.108625 -0.146820068359375 0.6095875 -0.10875 -0.121063232421875 0.6095875 -0.108875 -0.091156005859375 0.6095875 -0.109 -0.063385009765625 0.6095875 -0.109125 -0.0318603515625 0.6095875 +0.105375 -0.006378173828125 0.6095875 +0.1055 -0.038177490234375 0.6095875 +0.105625 -0.06646728515625 0.6095875 +0.10575 -0.097198486328125 0.6095875 +0.105875 -0.123931884765625 0.6095875 +0.106 -0.152374267578125 0.6095875 +0.106125 -0.179107666015625 0.6095875 +0.10625 -0.2015380859375 0.6095875 +0.106375 -0.22430419921875 0.6095875 +0.1065 -0.24273681640625 0.6095875 +0.106625 -0.26068115234375 0.6095875 +0.10675 -0.2757568359375 0.6095875 +0.106875 -0.2867431640625 0.6095875 +0.107 -0.29595947265625 0.6095875 +0.107125 -0.301483154296875 0.6095875 +0.10725 -0.304473876953125 0.6095875 +0.107375 -0.30413818359375 0.6095875 +0.1075 -0.300994873046875 0.6095875 +0.107625 -0.29437255859375 0.6095875 +0.10775 -0.28564453125 0.6095875 +0.107875 -0.27294921875 0.6095875 +0.108 -0.25732421875 0.6095875 +0.108125 -0.240814208984375 0.6095875 +0.10825 -0.219940185546875 0.6095875 +0.108375 -0.199127197265625 0.6095875 +0.1085 -0.173919677734375 0.6095875 +0.108625 -0.14678955078125 0.6095875 +0.10875 -0.12103271484375 0.6095875 +0.108875 -0.09112548828125 0.6095875 +0.109 -0.0633544921875 0.6095875 +0.109125 -0.031829833984375 0.6095875 0.10925 0.0 0.6095875 0.109375 0.028656005859375 0.6095875 0.1095 0.060211181640625 0.6095875 @@ -904,37 +904,37 @@ 0.112875 0.069580078125 0.6095875 0.113 0.038177490234375 0.6095875 0.113125 0.009552001953125 0.6095875 -0.11325 -0.0223388671875 0.6095875 -0.113375 -0.05084228515625 0.6095875 -0.1135 -0.08197021484375 0.6095875 -0.113625 -0.112213134765625 0.6095875 -0.11375 -0.13836669921875 0.6095875 -0.113875 -0.166015625 0.6095875 -0.114 -0.1893310546875 0.6095875 -0.114125 -0.2132568359375 0.6095875 -0.11425 -0.234832763671875 0.6095875 -0.114375 -0.2520751953125 0.6095875 -0.1145 -0.26861572265625 0.6095875 -0.114625 -0.280975341796875 0.6095875 -0.11475 -0.291778564453125 0.6095875 -0.114875 -0.29937744140625 0.6095875 -0.115 -0.303436279296875 0.6095875 -0.115125 -0.304779052734375 0.6095875 -0.11525 -0.3031005859375 0.6095875 -0.115375 -0.298126220703125 0.6095875 -0.1155 -0.28985595703125 0.6095875 -0.115625 -0.27972412109375 0.6095875 -0.11575 -0.265533447265625 0.6095875 -0.115875 -0.250274658203125 0.6095875 -0.116 -0.230712890625 0.6095875 -0.116125 -0.208648681640625 0.6095875 -0.11625 -0.186798095703125 0.6095875 -0.116375 -0.160614013671875 0.6095875 -0.1165 -0.135528564453125 0.6095875 -0.116625 -0.106231689453125 0.6095875 -0.11675 -0.0758056640625 0.6095875 -0.116875 -0.04766845703125 0.6095875 -0.117 -0.015960693359375 0.6095875 +0.11325 -0.022308349609375 0.6095875 +0.113375 -0.050811767578125 0.6095875 +0.1135 -0.081939697265625 0.6095875 +0.113625 -0.1121826171875 0.6095875 +0.11375 -0.138336181640625 0.6095875 +0.113875 -0.165985107421875 0.6095875 +0.114 -0.189300537109375 0.6095875 +0.114125 -0.213226318359375 0.6095875 +0.11425 -0.23480224609375 0.6095875 +0.114375 -0.252044677734375 0.6095875 +0.1145 -0.268585205078125 0.6095875 +0.114625 -0.28094482421875 0.6095875 +0.11475 -0.291748046875 0.6095875 +0.114875 -0.299346923828125 0.6095875 +0.115 -0.30340576171875 0.6095875 +0.115125 -0.30474853515625 0.6095875 +0.11525 -0.303070068359375 0.6095875 +0.115375 -0.298095703125 0.6095875 +0.1155 -0.289825439453125 0.6095875 +0.115625 -0.279693603515625 0.6095875 +0.11575 -0.2655029296875 0.6095875 +0.115875 -0.250244140625 0.6095875 +0.116 -0.230682373046875 0.6095875 +0.116125 -0.2086181640625 0.6095875 +0.11625 -0.186767578125 0.6095875 +0.116375 -0.16058349609375 0.6095875 +0.1165 -0.135498046875 0.6095875 +0.116625 -0.106201171875 0.6095875 +0.11675 -0.075775146484375 0.6095875 +0.116875 -0.047637939453125 0.6095875 +0.117 -0.01593017578125 0.6095875 0.117125 0.01275634765625 0.6095875 0.11725 0.04449462890625 0.6095875 0.117375 0.075775146484375 0.6095875 @@ -966,37 +966,37 @@ 0.120625 0.084991455078125 0.6095875 0.12075 0.053955078125 0.6095875 0.120875 0.025482177734375 0.6095875 -0.121 -0.00640869140625 0.6095875 -0.121125 -0.0382080078125 0.6095875 -0.12125 -0.066497802734375 0.6095875 -0.121375 -0.09722900390625 0.6095875 -0.1215 -0.12396240234375 0.6095875 -0.121625 -0.15240478515625 0.6095875 -0.12175 -0.17913818359375 0.6095875 -0.121875 -0.201568603515625 0.6095875 -0.122 -0.224334716796875 0.6095875 -0.122125 -0.242767333984375 0.6095875 -0.12225 -0.260711669921875 0.6095875 -0.122375 -0.275787353515625 0.6095875 -0.1225 -0.286773681640625 0.6095875 -0.122625 -0.295989990234375 0.6095875 -0.12275 -0.301513671875 0.6095875 -0.122875 -0.30450439453125 0.6095875 -0.123 -0.304168701171875 0.6095875 -0.123125 -0.301025390625 0.6095875 -0.12325 -0.294403076171875 0.6095875 -0.123375 -0.285675048828125 0.6095875 -0.1235 -0.272979736328125 0.6095875 -0.123625 -0.257354736328125 0.6095875 -0.12375 -0.2408447265625 0.6095875 -0.123875 -0.219970703125 0.6095875 -0.124 -0.19915771484375 0.6095875 -0.124125 -0.1739501953125 0.6095875 -0.12425 -0.146820068359375 0.6095875 -0.124375 -0.121063232421875 0.6095875 -0.1245 -0.091156005859375 0.6095875 -0.124625 -0.063385009765625 0.6095875 -0.12475 -0.0318603515625 0.6095875 +0.121 -0.006378173828125 0.6095875 +0.121125 -0.038177490234375 0.6095875 +0.12125 -0.06646728515625 0.6095875 +0.121375 -0.097198486328125 0.6095875 +0.1215 -0.123931884765625 0.6095875 +0.121625 -0.152374267578125 0.6095875 +0.12175 -0.179107666015625 0.6095875 +0.121875 -0.2015380859375 0.6095875 +0.122 -0.22430419921875 0.6095875 +0.122125 -0.24273681640625 0.6095875 +0.12225 -0.26068115234375 0.6095875 +0.122375 -0.2757568359375 0.6095875 +0.1225 -0.2867431640625 0.6095875 +0.122625 -0.29595947265625 0.6095875 +0.12275 -0.301483154296875 0.6095875 +0.122875 -0.304473876953125 0.6095875 +0.123 -0.30413818359375 0.6095875 +0.123125 -0.300994873046875 0.6095875 +0.12325 -0.29437255859375 0.6095875 +0.123375 -0.28564453125 0.6095875 +0.1235 -0.27294921875 0.6095875 +0.123625 -0.25732421875 0.6095875 +0.12375 -0.240814208984375 0.6095875 +0.123875 -0.219940185546875 0.6095875 +0.124 -0.199127197265625 0.6095875 +0.124125 -0.173919677734375 0.6095875 +0.12425 -0.14678955078125 0.6095875 +0.124375 -0.12103271484375 0.6095875 +0.1245 -0.09112548828125 0.6095875 +0.124625 -0.0633544921875 0.6095875 +0.12475 -0.031829833984375 0.6095875 0.124875 0.0 0.6095875 0.125 0.028656005859375 0.6095875 0.125125 0.060211181640625 0.6095875 @@ -1029,37 +1029,37 @@ 0.1285 0.081268310546875 0.7119843750000001 0.128625 0.044586181640625 0.7119843750000001 0.12875 0.01116943359375 0.7119843750000001 -0.128875 -0.02606201171875 0.7119843750000001 -0.129 -0.05938720703125 0.7119843750000001 -0.129125 -0.095733642578125 0.7119843750000001 -0.12925 -0.13104248046875 0.7119843750000001 -0.129375 -0.16162109375 0.7119843750000001 -0.1295 -0.193878173828125 0.7119843750000001 -0.129625 -0.22113037109375 0.7119843750000001 -0.12975 -0.249053955078125 0.7119843750000001 -0.129875 -0.2742919921875 0.7119843750000001 -0.13 -0.294403076171875 0.7119843750000001 -0.130125 -0.313720703125 0.7119843750000001 -0.13025 -0.328155517578125 0.7119843750000001 -0.130375 -0.340789794921875 0.7119843750000001 -0.1305 -0.34967041015625 0.7119843750000001 -0.130625 -0.354400634765625 0.7119843750000001 -0.13075 -0.35595703125 0.7119843750000001 -0.130875 -0.354034423828125 0.7119843750000001 -0.131 -0.348175048828125 0.7119843750000001 -0.131125 -0.33856201171875 0.7119843750000001 -0.13125 -0.326690673828125 0.7119843750000001 -0.131375 -0.31011962890625 0.7119843750000001 -0.1315 -0.29229736328125 0.7119843750000001 -0.131625 -0.26947021484375 0.7119843750000001 -0.13175 -0.243682861328125 0.7119843750000001 -0.131875 -0.218170166015625 0.7119843750000001 -0.132 -0.187591552734375 0.7119843750000001 -0.132125 -0.158294677734375 0.7119843750000001 -0.13225 -0.12408447265625 0.7119843750000001 -0.132375 -0.088531494140625 0.7119843750000001 -0.1325 -0.055694580078125 0.7119843750000001 -0.132625 -0.018646240234375 0.7119843750000001 +0.128875 -0.026031494140625 0.7119843750000001 +0.129 -0.059356689453125 0.7119843750000001 +0.129125 -0.095703125 0.7119843750000001 +0.12925 -0.131011962890625 0.7119843750000001 +0.129375 -0.161590576171875 0.7119843750000001 +0.1295 -0.19384765625 0.7119843750000001 +0.129625 -0.221099853515625 0.7119843750000001 +0.12975 -0.2490234375 0.7119843750000001 +0.129875 -0.274261474609375 0.7119843750000001 +0.13 -0.29437255859375 0.7119843750000001 +0.130125 -0.313690185546875 0.7119843750000001 +0.13025 -0.328125 0.7119843750000001 +0.130375 -0.34075927734375 0.7119843750000001 +0.1305 -0.349639892578125 0.7119843750000001 +0.130625 -0.3543701171875 0.7119843750000001 +0.13075 -0.355926513671875 0.7119843750000001 +0.130875 -0.35400390625 0.7119843750000001 +0.131 -0.34814453125 0.7119843750000001 +0.131125 -0.338531494140625 0.7119843750000001 +0.13125 -0.32666015625 0.7119843750000001 +0.131375 -0.310089111328125 0.7119843750000001 +0.1315 -0.292266845703125 0.7119843750000001 +0.131625 -0.269439697265625 0.7119843750000001 +0.13175 -0.24365234375 0.7119843750000001 +0.131875 -0.2181396484375 0.7119843750000001 +0.132 -0.18756103515625 0.7119843750000001 +0.132125 -0.15826416015625 0.7119843750000001 +0.13225 -0.124053955078125 0.7119843750000001 +0.132375 -0.0885009765625 0.7119843750000001 +0.1325 -0.0556640625 0.7119843750000001 +0.132625 -0.01861572265625 0.7119843750000001 0.13275 0.014892578125 0.7119843750000001 0.132875 0.051971435546875 0.7119843750000001 0.133 0.0885009765625 0.7119843750000001 @@ -1091,37 +1091,37 @@ 0.13625 0.099273681640625 0.7119843750000001 0.136375 0.063018798828125 0.7119843750000001 0.1365 0.029754638671875 0.7119843750000001 -0.136625 -0.007476806640625 0.7119843750000001 -0.13675 -0.04461669921875 0.7119843750000001 -0.136875 -0.077667236328125 0.7119843750000001 -0.137 -0.113555908203125 0.7119843750000001 -0.137125 -0.144805908203125 0.7119843750000001 -0.13725 -0.177978515625 0.7119843750000001 -0.137375 -0.209228515625 0.7119843750000001 -0.1375 -0.23541259765625 0.7119843750000001 -0.137625 -0.26202392578125 0.7119843750000001 -0.13775 -0.283538818359375 0.7119843750000001 -0.137875 -0.304473876953125 0.7119843750000001 -0.138 -0.32208251953125 0.7119843750000001 -0.138125 -0.334930419921875 0.7119843750000001 -0.13825 -0.345703125 0.7119843750000001 -0.138375 -0.352142333984375 0.7119843750000001 -0.1385 -0.35565185546875 0.7119843750000001 -0.138625 -0.35528564453125 0.7119843750000001 -0.13875 -0.351593017578125 0.7119843750000001 -0.138875 -0.343841552734375 0.7119843750000001 -0.139 -0.333648681640625 0.7119843750000001 -0.139125 -0.31884765625 0.7119843750000001 -0.13925 -0.300567626953125 0.7119843750000001 -0.139375 -0.281280517578125 0.7119843750000001 -0.1395 -0.256927490234375 0.7119843750000001 -0.139625 -0.23260498046875 0.7119843750000001 -0.13975 -0.203155517578125 0.7119843750000001 -0.139875 -0.1715087890625 0.7119843750000001 -0.14 -0.141387939453125 0.7119843750000001 -0.140125 -0.1064453125 0.7119843750000001 -0.14025 -0.074005126953125 0.7119843750000001 -0.140375 -0.0372314453125 0.7119843750000001 +0.136625 -0.0074462890625 0.7119843750000001 +0.13675 -0.044586181640625 0.7119843750000001 +0.136875 -0.07763671875 0.7119843750000001 +0.137 -0.113525390625 0.7119843750000001 +0.137125 -0.144775390625 0.7119843750000001 +0.13725 -0.177947998046875 0.7119843750000001 +0.137375 -0.209197998046875 0.7119843750000001 +0.1375 -0.235382080078125 0.7119843750000001 +0.137625 -0.261993408203125 0.7119843750000001 +0.13775 -0.28350830078125 0.7119843750000001 +0.137875 -0.304443359375 0.7119843750000001 +0.138 -0.322052001953125 0.7119843750000001 +0.138125 -0.33489990234375 0.7119843750000001 +0.13825 -0.345672607421875 0.7119843750000001 +0.138375 -0.35211181640625 0.7119843750000001 +0.1385 -0.355621337890625 0.7119843750000001 +0.138625 -0.355255126953125 0.7119843750000001 +0.13875 -0.3515625 0.7119843750000001 +0.138875 -0.34381103515625 0.7119843750000001 +0.139 -0.3336181640625 0.7119843750000001 +0.139125 -0.318817138671875 0.7119843750000001 +0.13925 -0.300537109375 0.7119843750000001 +0.139375 -0.28125 0.7119843750000001 +0.1395 -0.25689697265625 0.7119843750000001 +0.139625 -0.232574462890625 0.7119843750000001 +0.13975 -0.203125 0.7119843750000001 +0.139875 -0.171478271484375 0.7119843750000001 +0.14 -0.141357421875 0.7119843750000001 +0.140125 -0.106414794921875 0.7119843750000001 +0.14025 -0.073974609375 0.7119843750000001 +0.140375 -0.037200927734375 0.7119843750000001 0.1405 0.0 0.7119843750000001 0.140625 0.033477783203125 0.7119843750000001 0.14075 0.070343017578125 0.7119843750000001 @@ -1154,37 +1154,37 @@ 0.144125 0.081268310546875 0.7119843750000001 0.14425 0.044586181640625 0.7119843750000001 0.144375 0.01116943359375 0.7119843750000001 -0.1445 -0.02606201171875 0.7119843750000001 -0.144625 -0.05938720703125 0.7119843750000001 -0.14475 -0.095733642578125 0.7119843750000001 -0.144875 -0.13104248046875 0.7119843750000001 -0.145 -0.16162109375 0.7119843750000001 -0.145125 -0.193878173828125 0.7119843750000001 -0.14525 -0.22113037109375 0.7119843750000001 -0.145375 -0.249053955078125 0.7119843750000001 -0.1455 -0.2742919921875 0.7119843750000001 -0.145625 -0.294403076171875 0.7119843750000001 -0.14575 -0.313720703125 0.7119843750000001 -0.145875 -0.328155517578125 0.7119843750000001 -0.146 -0.340789794921875 0.7119843750000001 -0.146125 -0.34967041015625 0.7119843750000001 -0.14625 -0.354400634765625 0.7119843750000001 -0.146375 -0.35595703125 0.7119843750000001 -0.1465 -0.354034423828125 0.7119843750000001 -0.146625 -0.348175048828125 0.7119843750000001 -0.14675 -0.33856201171875 0.7119843750000001 -0.146875 -0.326690673828125 0.7119843750000001 -0.147 -0.31011962890625 0.7119843750000001 -0.147125 -0.29229736328125 0.7119843750000001 -0.14725 -0.26947021484375 0.7119843750000001 -0.147375 -0.243682861328125 0.7119843750000001 -0.1475 -0.218170166015625 0.7119843750000001 -0.147625 -0.187591552734375 0.7119843750000001 -0.14775 -0.158294677734375 0.7119843750000001 -0.147875 -0.12408447265625 0.7119843750000001 -0.148 -0.088531494140625 0.7119843750000001 -0.148125 -0.055694580078125 0.7119843750000001 -0.14825 -0.018646240234375 0.7119843750000001 +0.1445 -0.026031494140625 0.7119843750000001 +0.144625 -0.059356689453125 0.7119843750000001 +0.14475 -0.095703125 0.7119843750000001 +0.144875 -0.131011962890625 0.7119843750000001 +0.145 -0.161590576171875 0.7119843750000001 +0.145125 -0.19384765625 0.7119843750000001 +0.14525 -0.221099853515625 0.7119843750000001 +0.145375 -0.2490234375 0.7119843750000001 +0.1455 -0.274261474609375 0.7119843750000001 +0.145625 -0.29437255859375 0.7119843750000001 +0.14575 -0.313690185546875 0.7119843750000001 +0.145875 -0.328125 0.7119843750000001 +0.146 -0.34075927734375 0.7119843750000001 +0.146125 -0.349639892578125 0.7119843750000001 +0.14625 -0.3543701171875 0.7119843750000001 +0.146375 -0.355926513671875 0.7119843750000001 +0.1465 -0.35400390625 0.7119843750000001 +0.146625 -0.34814453125 0.7119843750000001 +0.14675 -0.338531494140625 0.7119843750000001 +0.146875 -0.32666015625 0.7119843750000001 +0.147 -0.310089111328125 0.7119843750000001 +0.147125 -0.292266845703125 0.7119843750000001 +0.14725 -0.269439697265625 0.7119843750000001 +0.147375 -0.24365234375 0.7119843750000001 +0.1475 -0.2181396484375 0.7119843750000001 +0.147625 -0.18756103515625 0.7119843750000001 +0.14775 -0.15826416015625 0.7119843750000001 +0.147875 -0.124053955078125 0.7119843750000001 +0.148 -0.0885009765625 0.7119843750000001 +0.148125 -0.0556640625 0.7119843750000001 +0.14825 -0.01861572265625 0.7119843750000001 0.148375 0.014892578125 0.7119843750000001 0.1485 0.051971435546875 0.7119843750000001 0.148625 0.0885009765625 0.7119843750000001 @@ -1216,37 +1216,37 @@ 0.151875 0.099273681640625 0.7119843750000001 0.152 0.063018798828125 0.7119843750000001 0.152125 0.029754638671875 0.7119843750000001 -0.15225 -0.007476806640625 0.7119843750000001 -0.152375 -0.04461669921875 0.7119843750000001 -0.1525 -0.077667236328125 0.7119843750000001 -0.152625 -0.113555908203125 0.7119843750000001 -0.15275 -0.144805908203125 0.7119843750000001 -0.152875 -0.177978515625 0.7119843750000001 -0.153 -0.209228515625 0.7119843750000001 -0.153125 -0.23541259765625 0.7119843750000001 -0.15325 -0.26202392578125 0.7119843750000001 -0.153375 -0.283538818359375 0.7119843750000001 -0.1535 -0.304473876953125 0.7119843750000001 -0.153625 -0.32208251953125 0.7119843750000001 -0.15375 -0.334930419921875 0.7119843750000001 -0.153875 -0.345703125 0.7119843750000001 -0.154 -0.352142333984375 0.7119843750000001 -0.154125 -0.35565185546875 0.7119843750000001 -0.15425 -0.35528564453125 0.7119843750000001 -0.154375 -0.351593017578125 0.7119843750000001 -0.1545 -0.343841552734375 0.7119843750000001 -0.154625 -0.333648681640625 0.7119843750000001 -0.15475 -0.31884765625 0.7119843750000001 -0.154875 -0.300567626953125 0.7119843750000001 -0.155 -0.281280517578125 0.7119843750000001 -0.155125 -0.256927490234375 0.7119843750000001 -0.15525 -0.23260498046875 0.7119843750000001 -0.155375 -0.203155517578125 0.7119843750000001 -0.1555 -0.1715087890625 0.7119843750000001 -0.155625 -0.141387939453125 0.7119843750000001 -0.15575 -0.1064453125 0.7119843750000001 -0.155875 -0.074005126953125 0.7119843750000001 -0.156 -0.0372314453125 0.7119843750000001 +0.15225 -0.0074462890625 0.7119843750000001 +0.152375 -0.044586181640625 0.7119843750000001 +0.1525 -0.07763671875 0.7119843750000001 +0.152625 -0.113525390625 0.7119843750000001 +0.15275 -0.144775390625 0.7119843750000001 +0.152875 -0.177947998046875 0.7119843750000001 +0.153 -0.209197998046875 0.7119843750000001 +0.153125 -0.235382080078125 0.7119843750000001 +0.15325 -0.261993408203125 0.7119843750000001 +0.153375 -0.28350830078125 0.7119843750000001 +0.1535 -0.304443359375 0.7119843750000001 +0.153625 -0.322052001953125 0.7119843750000001 +0.15375 -0.33489990234375 0.7119843750000001 +0.153875 -0.345672607421875 0.7119843750000001 +0.154 -0.35211181640625 0.7119843750000001 +0.154125 -0.355621337890625 0.7119843750000001 +0.15425 -0.355255126953125 0.7119843750000001 +0.154375 -0.3515625 0.7119843750000001 +0.1545 -0.34381103515625 0.7119843750000001 +0.154625 -0.3336181640625 0.7119843750000001 +0.15475 -0.318817138671875 0.7119843750000001 +0.154875 -0.300537109375 0.7119843750000001 +0.155 -0.28125 0.7119843750000001 +0.155125 -0.25689697265625 0.7119843750000001 +0.15525 -0.232574462890625 0.7119843750000001 +0.155375 -0.203125 0.7119843750000001 +0.1555 -0.171478271484375 0.7119843750000001 +0.155625 -0.141357421875 0.7119843750000001 +0.15575 -0.106414794921875 0.7119843750000001 +0.155875 -0.073974609375 0.7119843750000001 +0.156 -0.037200927734375 0.7119843750000001 0.156125 0.0 0.7119843750000001 0.15625 0.033477783203125 0.7119843750000001 0.156375 0.070343017578125 0.7119843750000001 @@ -1279,37 +1279,37 @@ 0.15975 0.081268310546875 0.7119843750000001 0.159875 0.044586181640625 0.7119843750000001 0.16 0.01275634765625 0.8143812500000001 -0.160125 -0.029815673828125 0.8143812500000001 -0.16025 -0.067901611328125 0.8143812500000001 -0.160375 -0.1094970703125 0.8143812500000001 -0.1605 -0.14990234375 0.8143812500000001 -0.160625 -0.184844970703125 0.8143812500000001 -0.16075 -0.221771240234375 0.8143812500000001 -0.160875 -0.2529296875 0.8143812500000001 -0.161 -0.284881591796875 0.8143812500000001 -0.161125 -0.313751220703125 0.8143812500000001 -0.16125 -0.336761474609375 0.8143812500000001 -0.161375 -0.358856201171875 0.8143812500000001 -0.1615 -0.3753662109375 0.8143812500000001 -0.161625 -0.389801025390625 0.8143812500000001 -0.16175 -0.39996337890625 0.8143812500000001 -0.161875 -0.405364990234375 0.8143812500000001 -0.162 -0.40716552734375 0.8143812500000001 -0.162125 -0.404937744140625 0.8143812500000001 -0.16225 -0.398284912109375 0.8143812500000001 -0.162375 -0.387237548828125 0.8143812500000001 -0.1625 -0.373687744140625 0.8143812500000001 -0.162625 -0.354736328125 0.8143812500000001 -0.16275 -0.3343505859375 0.8143812500000001 -0.162875 -0.3082275390625 0.8143812500000001 -0.163 -0.27874755859375 0.8143812500000001 -0.163125 -0.24957275390625 0.8143812500000001 -0.16325 -0.214569091796875 0.8143812500000001 -0.163375 -0.181060791015625 0.8143812500000001 -0.1635 -0.141937255859375 0.8143812500000001 -0.163625 -0.10125732421875 0.8143812500000001 -0.16375 -0.063690185546875 0.8143812500000001 -0.163875 -0.02130126953125 0.8143812500000001 +0.160125 -0.02978515625 0.8143812500000001 +0.16025 -0.06787109375 0.8143812500000001 +0.160375 -0.109466552734375 0.8143812500000001 +0.1605 -0.149871826171875 0.8143812500000001 +0.160625 -0.184814453125 0.8143812500000001 +0.16075 -0.22174072265625 0.8143812500000001 +0.160875 -0.252899169921875 0.8143812500000001 +0.161 -0.28485107421875 0.8143812500000001 +0.161125 -0.313720703125 0.8143812500000001 +0.16125 -0.33673095703125 0.8143812500000001 +0.161375 -0.35882568359375 0.8143812500000001 +0.1615 -0.375335693359375 0.8143812500000001 +0.161625 -0.3897705078125 0.8143812500000001 +0.16175 -0.399932861328125 0.8143812500000001 +0.161875 -0.40533447265625 0.8143812500000001 +0.162 -0.407135009765625 0.8143812500000001 +0.162125 -0.4049072265625 0.8143812500000001 +0.16225 -0.39825439453125 0.8143812500000001 +0.162375 -0.38720703125 0.8143812500000001 +0.1625 -0.3736572265625 0.8143812500000001 +0.162625 -0.354705810546875 0.8143812500000001 +0.16275 -0.334320068359375 0.8143812500000001 +0.162875 -0.308197021484375 0.8143812500000001 +0.163 -0.278717041015625 0.8143812500000001 +0.163125 -0.249542236328125 0.8143812500000001 +0.16325 -0.21453857421875 0.8143812500000001 +0.163375 -0.1810302734375 0.8143812500000001 +0.1635 -0.14190673828125 0.8143812500000001 +0.163625 -0.101226806640625 0.8143812500000001 +0.16375 -0.06365966796875 0.8143812500000001 +0.163875 -0.021270751953125 0.8143812500000001 0.164 0.01702880859375 0.8143812500000001 0.164125 0.0594482421875 0.8143812500000001 0.16425 0.101226806640625 0.8143812500000001 @@ -1341,37 +1341,37 @@ 0.1675 0.11358642578125 0.8143812500000001 0.167625 0.07208251953125 0.8143812500000001 0.16775 0.0340576171875 0.8143812500000001 -0.167875 -0.008544921875 0.8143812500000001 -0.168 -0.051025390625 0.8143812500000001 -0.168125 -0.088836669921875 0.8143812500000001 -0.16825 -0.1298828125 0.8143812500000001 -0.168375 -0.165618896484375 0.8143812500000001 -0.1685 -0.203582763671875 0.8143812500000001 -0.168625 -0.23931884765625 0.8143812500000001 -0.16875 -0.269287109375 0.8143812500000001 -0.168875 -0.299713134765625 0.8143812500000001 -0.169 -0.3243408203125 0.8143812500000001 -0.169125 -0.348297119140625 0.8143812500000001 -0.16925 -0.368438720703125 0.8143812500000001 -0.169375 -0.383087158203125 0.8143812500000001 -0.1695 -0.395416259765625 0.8143812500000001 -0.169625 -0.402801513671875 0.8143812500000001 -0.16975 -0.406829833984375 0.8143812500000001 -0.169875 -0.4063720703125 0.8143812500000001 -0.17 -0.40216064453125 0.8143812500000001 -0.170125 -0.393310546875 0.8143812500000001 -0.17025 -0.381622314453125 0.8143812500000001 -0.170375 -0.364715576171875 0.8143812500000001 -0.1705 -0.34381103515625 0.8143812500000001 -0.170625 -0.321746826171875 0.8143812500000001 -0.17075 -0.29388427734375 0.8143812500000001 -0.170875 -0.26605224609375 0.8143812500000001 -0.171 -0.232391357421875 0.8143812500000001 -0.171125 -0.1961669921875 0.8143812500000001 -0.17125 -0.161712646484375 0.8143812500000001 -0.171375 -0.12176513671875 0.8143812500000001 -0.1715 -0.08465576171875 0.8143812500000001 -0.171625 -0.042572021484375 0.8143812500000001 +0.167875 -0.008514404296875 0.8143812500000001 +0.168 -0.050994873046875 0.8143812500000001 +0.168125 -0.08880615234375 0.8143812500000001 +0.16825 -0.129852294921875 0.8143812500000001 +0.168375 -0.16558837890625 0.8143812500000001 +0.1685 -0.20355224609375 0.8143812500000001 +0.168625 -0.239288330078125 0.8143812500000001 +0.16875 -0.269256591796875 0.8143812500000001 +0.168875 -0.2996826171875 0.8143812500000001 +0.169 -0.324310302734375 0.8143812500000001 +0.169125 -0.3482666015625 0.8143812500000001 +0.16925 -0.368408203125 0.8143812500000001 +0.169375 -0.383056640625 0.8143812500000001 +0.1695 -0.3953857421875 0.8143812500000001 +0.169625 -0.40277099609375 0.8143812500000001 +0.16975 -0.40679931640625 0.8143812500000001 +0.169875 -0.406341552734375 0.8143812500000001 +0.17 -0.402130126953125 0.8143812500000001 +0.170125 -0.393280029296875 0.8143812500000001 +0.17025 -0.381591796875 0.8143812500000001 +0.170375 -0.36468505859375 0.8143812500000001 +0.1705 -0.343780517578125 0.8143812500000001 +0.170625 -0.32171630859375 0.8143812500000001 +0.17075 -0.293853759765625 0.8143812500000001 +0.170875 -0.266021728515625 0.8143812500000001 +0.171 -0.23236083984375 0.8143812500000001 +0.171125 -0.196136474609375 0.8143812500000001 +0.17125 -0.16168212890625 0.8143812500000001 +0.171375 -0.121734619140625 0.8143812500000001 +0.1715 -0.084625244140625 0.8143812500000001 +0.171625 -0.04254150390625 0.8143812500000001 0.17175 0.0 0.8143812500000001 0.171875 0.038299560546875 0.8143812500000001 0.172 0.0804443359375 0.8143812500000001 @@ -1404,37 +1404,37 @@ 0.175375 0.09295654296875 0.8143812500000001 0.1755 0.050994873046875 0.8143812500000001 0.175625 0.01275634765625 0.8143812500000001 -0.17575 -0.029815673828125 0.8143812500000001 -0.175875 -0.067901611328125 0.8143812500000001 -0.176 -0.1094970703125 0.8143812500000001 -0.176125 -0.14990234375 0.8143812500000001 -0.17625 -0.184844970703125 0.8143812500000001 -0.176375 -0.221771240234375 0.8143812500000001 -0.1765 -0.2529296875 0.8143812500000001 -0.176625 -0.284881591796875 0.8143812500000001 -0.17675 -0.313751220703125 0.8143812500000001 -0.176875 -0.336761474609375 0.8143812500000001 -0.177 -0.358856201171875 0.8143812500000001 -0.177125 -0.3753662109375 0.8143812500000001 -0.17725 -0.389801025390625 0.8143812500000001 -0.177375 -0.39996337890625 0.8143812500000001 -0.1775 -0.405364990234375 0.8143812500000001 -0.177625 -0.40716552734375 0.8143812500000001 -0.17775 -0.404937744140625 0.8143812500000001 -0.177875 -0.398284912109375 0.8143812500000001 -0.178 -0.387237548828125 0.8143812500000001 -0.178125 -0.373687744140625 0.8143812500000001 -0.17825 -0.354736328125 0.8143812500000001 -0.178375 -0.3343505859375 0.8143812500000001 -0.1785 -0.3082275390625 0.8143812500000001 -0.178625 -0.27874755859375 0.8143812500000001 -0.17875 -0.24957275390625 0.8143812500000001 -0.178875 -0.214569091796875 0.8143812500000001 -0.179 -0.181060791015625 0.8143812500000001 -0.179125 -0.141937255859375 0.8143812500000001 -0.17925 -0.10125732421875 0.8143812500000001 -0.179375 -0.063690185546875 0.8143812500000001 -0.1795 -0.02130126953125 0.8143812500000001 +0.17575 -0.02978515625 0.8143812500000001 +0.175875 -0.06787109375 0.8143812500000001 +0.176 -0.109466552734375 0.8143812500000001 +0.176125 -0.149871826171875 0.8143812500000001 +0.17625 -0.184814453125 0.8143812500000001 +0.176375 -0.22174072265625 0.8143812500000001 +0.1765 -0.252899169921875 0.8143812500000001 +0.176625 -0.28485107421875 0.8143812500000001 +0.17675 -0.313720703125 0.8143812500000001 +0.176875 -0.33673095703125 0.8143812500000001 +0.177 -0.35882568359375 0.8143812500000001 +0.177125 -0.375335693359375 0.8143812500000001 +0.17725 -0.3897705078125 0.8143812500000001 +0.177375 -0.399932861328125 0.8143812500000001 +0.1775 -0.40533447265625 0.8143812500000001 +0.177625 -0.407135009765625 0.8143812500000001 +0.17775 -0.4049072265625 0.8143812500000001 +0.177875 -0.39825439453125 0.8143812500000001 +0.178 -0.38720703125 0.8143812500000001 +0.178125 -0.3736572265625 0.8143812500000001 +0.17825 -0.354705810546875 0.8143812500000001 +0.178375 -0.334320068359375 0.8143812500000001 +0.1785 -0.308197021484375 0.8143812500000001 +0.178625 -0.278717041015625 0.8143812500000001 +0.17875 -0.249542236328125 0.8143812500000001 +0.178875 -0.21453857421875 0.8143812500000001 +0.179 -0.1810302734375 0.8143812500000001 +0.179125 -0.14190673828125 0.8143812500000001 +0.17925 -0.101226806640625 0.8143812500000001 +0.179375 -0.06365966796875 0.8143812500000001 +0.1795 -0.021270751953125 0.8143812500000001 0.179625 0.01702880859375 0.8143812500000001 0.17975 0.0594482421875 0.8143812500000001 0.179875 0.101226806640625 0.8143812500000001 @@ -1466,37 +1466,37 @@ 0.183125 0.11358642578125 0.8143812500000001 0.18325 0.07208251953125 0.8143812500000001 0.183375 0.0340576171875 0.8143812500000001 -0.1835 -0.008544921875 0.8143812500000001 -0.183625 -0.051025390625 0.8143812500000001 -0.18375 -0.088836669921875 0.8143812500000001 -0.183875 -0.1298828125 0.8143812500000001 -0.184 -0.165618896484375 0.8143812500000001 -0.184125 -0.203582763671875 0.8143812500000001 -0.18425 -0.23931884765625 0.8143812500000001 -0.184375 -0.269287109375 0.8143812500000001 -0.1845 -0.299713134765625 0.8143812500000001 -0.184625 -0.3243408203125 0.8143812500000001 -0.18475 -0.348297119140625 0.8143812500000001 -0.184875 -0.368438720703125 0.8143812500000001 -0.185 -0.383087158203125 0.8143812500000001 -0.185125 -0.395416259765625 0.8143812500000001 -0.18525 -0.402801513671875 0.8143812500000001 -0.185375 -0.406829833984375 0.8143812500000001 -0.1855 -0.4063720703125 0.8143812500000001 -0.185625 -0.40216064453125 0.8143812500000001 -0.18575 -0.393310546875 0.8143812500000001 -0.185875 -0.381622314453125 0.8143812500000001 -0.186 -0.364715576171875 0.8143812500000001 -0.186125 -0.34381103515625 0.8143812500000001 -0.18625 -0.321746826171875 0.8143812500000001 -0.186375 -0.29388427734375 0.8143812500000001 -0.1865 -0.26605224609375 0.8143812500000001 -0.186625 -0.232391357421875 0.8143812500000001 -0.18675 -0.1961669921875 0.8143812500000001 -0.186875 -0.161712646484375 0.8143812500000001 -0.187 -0.12176513671875 0.8143812500000001 -0.187125 -0.08465576171875 0.8143812500000001 -0.18725 -0.042572021484375 0.8143812500000001 +0.1835 -0.008514404296875 0.8143812500000001 +0.183625 -0.050994873046875 0.8143812500000001 +0.18375 -0.08880615234375 0.8143812500000001 +0.183875 -0.129852294921875 0.8143812500000001 +0.184 -0.16558837890625 0.8143812500000001 +0.184125 -0.20355224609375 0.8143812500000001 +0.18425 -0.239288330078125 0.8143812500000001 +0.184375 -0.269256591796875 0.8143812500000001 +0.1845 -0.2996826171875 0.8143812500000001 +0.184625 -0.324310302734375 0.8143812500000001 +0.18475 -0.3482666015625 0.8143812500000001 +0.184875 -0.368408203125 0.8143812500000001 +0.185 -0.383056640625 0.8143812500000001 +0.185125 -0.3953857421875 0.8143812500000001 +0.18525 -0.40277099609375 0.8143812500000001 +0.185375 -0.40679931640625 0.8143812500000001 +0.1855 -0.406341552734375 0.8143812500000001 +0.185625 -0.402130126953125 0.8143812500000001 +0.18575 -0.393280029296875 0.8143812500000001 +0.185875 -0.381591796875 0.8143812500000001 +0.186 -0.36468505859375 0.8143812500000001 +0.186125 -0.343780517578125 0.8143812500000001 +0.18625 -0.32171630859375 0.8143812500000001 +0.186375 -0.293853759765625 0.8143812500000001 +0.1865 -0.266021728515625 0.8143812500000001 +0.186625 -0.23236083984375 0.8143812500000001 +0.18675 -0.196136474609375 0.8143812500000001 +0.186875 -0.16168212890625 0.8143812500000001 +0.187 -0.121734619140625 0.8143812500000001 +0.187125 -0.084625244140625 0.8143812500000001 +0.18725 -0.04254150390625 0.8143812500000001 0.187375 0.0 0.8143812500000001 0.1875 0.038299560546875 0.8143812500000001 0.187625 0.0804443359375 0.8143812500000001 @@ -1529,37 +1529,37 @@ 0.191 0.09295654296875 0.8143812500000001 0.191125 0.050994873046875 0.8143812500000001 0.19125 0.01275634765625 0.8143812500000001 -0.191375 -0.029815673828125 0.8143812500000001 -0.1915 -0.067901611328125 0.8143812500000001 -0.191625 -0.1094970703125 0.8143812500000001 -0.19175 -0.14990234375 0.8143812500000001 -0.191875 -0.184844970703125 0.8143812500000001 -0.192 -0.249664306640625 0.9167781250000001 -0.192125 -0.28472900390625 0.9167781250000001 -0.19225 -0.320709228515625 0.9167781250000001 -0.192375 -0.353179931640625 0.9167781250000001 -0.1925 -0.37908935546875 0.9167781250000001 -0.192625 -0.403961181640625 0.9167781250000001 -0.19275 -0.42254638671875 0.9167781250000001 -0.192875 -0.438812255859375 0.9167781250000001 -0.193 -0.45025634765625 0.9167781250000001 -0.193125 -0.456329345703125 0.9167781250000001 -0.19325 -0.458343505859375 0.9167781250000001 -0.193375 -0.45587158203125 0.9167781250000001 -0.1935 -0.448333740234375 0.9167781250000001 -0.193625 -0.435943603515625 0.9167781250000001 -0.19375 -0.420684814453125 0.9167781250000001 -0.193875 -0.39935302734375 0.9167781250000001 -0.194 -0.37640380859375 0.9167781250000001 -0.194125 -0.34698486328125 0.9167781250000001 -0.19425 -0.31378173828125 0.9167781250000001 -0.194375 -0.28094482421875 0.9167781250000001 -0.1945 -0.241546630859375 0.9167781250000001 -0.194625 -0.203826904296875 0.9167781250000001 -0.19475 -0.1597900390625 0.9167781250000001 -0.194875 -0.113983154296875 0.9167781250000001 -0.195 -0.07171630859375 0.9167781250000001 -0.195125 -0.02398681640625 0.9167781250000001 +0.191375 -0.02978515625 0.8143812500000001 +0.1915 -0.06787109375 0.8143812500000001 +0.191625 -0.109466552734375 0.8143812500000001 +0.19175 -0.149871826171875 0.8143812500000001 +0.191875 -0.184814453125 0.8143812500000001 +0.192 -0.2496337890625 0.9167781250000001 +0.192125 -0.284698486328125 0.9167781250000001 +0.19225 -0.3206787109375 0.9167781250000001 +0.192375 -0.3531494140625 0.9167781250000001 +0.1925 -0.379058837890625 0.9167781250000001 +0.192625 -0.4039306640625 0.9167781250000001 +0.19275 -0.422515869140625 0.9167781250000001 +0.192875 -0.43878173828125 0.9167781250000001 +0.193 -0.450225830078125 0.9167781250000001 +0.193125 -0.456298828125 0.9167781250000001 +0.19325 -0.45831298828125 0.9167781250000001 +0.193375 -0.455841064453125 0.9167781250000001 +0.1935 -0.44830322265625 0.9167781250000001 +0.193625 -0.4359130859375 0.9167781250000001 +0.19375 -0.420654296875 0.9167781250000001 +0.193875 -0.399322509765625 0.9167781250000001 +0.194 -0.376373291015625 0.9167781250000001 +0.194125 -0.346954345703125 0.9167781250000001 +0.19425 -0.313751220703125 0.9167781250000001 +0.194375 -0.280914306640625 0.9167781250000001 +0.1945 -0.24151611328125 0.9167781250000001 +0.194625 -0.20379638671875 0.9167781250000001 +0.19475 -0.159759521484375 0.9167781250000001 +0.194875 -0.11395263671875 0.9167781250000001 +0.195 -0.071685791015625 0.9167781250000001 +0.195125 -0.023956298828125 0.9167781250000001 0.19525 0.0191650390625 0.9167781250000001 0.195375 0.066925048828125 0.9167781250000001 0.1955 0.11395263671875 0.9167781250000001 @@ -1591,37 +1591,37 @@ 0.19875 0.127838134765625 0.9167781250000001 0.198875 0.081146240234375 0.9167781250000001 0.199 0.038330078125 0.9167781250000001 -0.199125 -0.009613037109375 0.9167781250000001 -0.19925 -0.057464599609375 0.9167781250000001 -0.199375 -0.0999755859375 0.9167781250000001 -0.1995 -0.146209716796875 0.9167781250000001 -0.199625 -0.186431884765625 0.9167781250000001 -0.19975 -0.22918701171875 0.9167781250000001 -0.199875 -0.2694091796875 0.9167781250000001 -0.2 -0.303131103515625 0.9167781250000001 -0.200125 -0.33740234375 0.9167781250000001 -0.20025 -0.3651123046875 0.9167781250000001 -0.200375 -0.392059326171875 0.9167781250000001 -0.2005 -0.41473388671875 0.9167781250000001 -0.200625 -0.4312744140625 0.9167781250000001 -0.20075 -0.44512939453125 0.9167781250000001 -0.200875 -0.453460693359375 0.9167781250000001 -0.201 -0.457977294921875 0.9167781250000001 -0.201125 -0.45745849609375 0.9167781250000001 -0.20125 -0.452728271484375 0.9167781250000001 -0.201375 -0.4427490234375 0.9167781250000001 -0.2015 -0.42962646484375 0.9167781250000001 -0.201625 -0.410552978515625 0.9167781250000001 -0.20175 -0.38702392578125 0.9167781250000001 -0.201875 -0.3621826171875 0.9167781250000001 -0.202 -0.330841064453125 0.9167781250000001 -0.202125 -0.29949951171875 0.9167781250000001 -0.20225 -0.2615966796875 0.9167781250000001 -0.202375 -0.2208251953125 0.9167781250000001 -0.2025 -0.182037353515625 0.9167781250000001 -0.202625 -0.1370849609375 0.9167781250000001 -0.20275 -0.095306396484375 0.9167781250000001 -0.202875 -0.04791259765625 0.9167781250000001 +0.199125 -0.00958251953125 0.9167781250000001 +0.19925 -0.05743408203125 0.9167781250000001 +0.199375 -0.099945068359375 0.9167781250000001 +0.1995 -0.14617919921875 0.9167781250000001 +0.199625 -0.1864013671875 0.9167781250000001 +0.19975 -0.229156494140625 0.9167781250000001 +0.199875 -0.269378662109375 0.9167781250000001 +0.2 -0.3031005859375 0.9167781250000001 +0.200125 -0.337371826171875 0.9167781250000001 +0.20025 -0.365081787109375 0.9167781250000001 +0.200375 -0.39202880859375 0.9167781250000001 +0.2005 -0.414703369140625 0.9167781250000001 +0.200625 -0.431243896484375 0.9167781250000001 +0.20075 -0.445098876953125 0.9167781250000001 +0.200875 -0.45343017578125 0.9167781250000001 +0.201 -0.45794677734375 0.9167781250000001 +0.201125 -0.457427978515625 0.9167781250000001 +0.20125 -0.45269775390625 0.9167781250000001 +0.201375 -0.442718505859375 0.9167781250000001 +0.2015 -0.429595947265625 0.9167781250000001 +0.201625 -0.4105224609375 0.9167781250000001 +0.20175 -0.386993408203125 0.9167781250000001 +0.201875 -0.362152099609375 0.9167781250000001 +0.202 -0.330810546875 0.9167781250000001 +0.202125 -0.299468994140625 0.9167781250000001 +0.20225 -0.261566162109375 0.9167781250000001 +0.202375 -0.220794677734375 0.9167781250000001 +0.2025 -0.1820068359375 0.9167781250000001 +0.202625 -0.137054443359375 0.9167781250000001 +0.20275 -0.09527587890625 0.9167781250000001 +0.202875 -0.047882080078125 0.9167781250000001 0.203 0.0 0.9167781250000001 0.203125 0.043121337890625 0.9167781250000001 0.20325 0.090576171875 0.9167781250000001 @@ -1654,37 +1654,37 @@ 0.206625 0.104644775390625 0.9167781250000001 0.20675 0.05743408203125 0.9167781250000001 0.206875 0.014373779296875 0.9167781250000001 -0.207 -0.0335693359375 0.9167781250000001 -0.207125 -0.076446533203125 0.9167781250000001 -0.20725 -0.123260498046875 0.9167781250000001 -0.207375 -0.168731689453125 0.9167781250000001 -0.2075 -0.208099365234375 0.9167781250000001 -0.207625 -0.249664306640625 0.9167781250000001 -0.20775 -0.28472900390625 0.9167781250000001 -0.207875 -0.320709228515625 0.9167781250000001 -0.208 -0.353179931640625 0.9167781250000001 -0.208125 -0.37908935546875 0.9167781250000001 -0.20825 -0.403961181640625 0.9167781250000001 -0.208375 -0.42254638671875 0.9167781250000001 -0.2085 -0.438812255859375 0.9167781250000001 -0.208625 -0.45025634765625 0.9167781250000001 -0.20875 -0.456329345703125 0.9167781250000001 -0.208875 -0.458343505859375 0.9167781250000001 -0.209 -0.45587158203125 0.9167781250000001 -0.209125 -0.448333740234375 0.9167781250000001 -0.20925 -0.435943603515625 0.9167781250000001 -0.209375 -0.420684814453125 0.9167781250000001 -0.2095 -0.39935302734375 0.9167781250000001 -0.209625 -0.37640380859375 0.9167781250000001 -0.20975 -0.34698486328125 0.9167781250000001 -0.209875 -0.31378173828125 0.9167781250000001 -0.21 -0.28094482421875 0.9167781250000001 -0.210125 -0.241546630859375 0.9167781250000001 -0.21025 -0.203826904296875 0.9167781250000001 -0.210375 -0.1597900390625 0.9167781250000001 -0.2105 -0.113983154296875 0.9167781250000001 -0.210625 -0.07171630859375 0.9167781250000001 -0.21075 -0.02398681640625 0.9167781250000001 +0.207 -0.033538818359375 0.9167781250000001 +0.207125 -0.076416015625 0.9167781250000001 +0.20725 -0.12322998046875 0.9167781250000001 +0.207375 -0.168701171875 0.9167781250000001 +0.2075 -0.20806884765625 0.9167781250000001 +0.207625 -0.2496337890625 0.9167781250000001 +0.20775 -0.284698486328125 0.9167781250000001 +0.207875 -0.3206787109375 0.9167781250000001 +0.208 -0.3531494140625 0.9167781250000001 +0.208125 -0.379058837890625 0.9167781250000001 +0.20825 -0.4039306640625 0.9167781250000001 +0.208375 -0.422515869140625 0.9167781250000001 +0.2085 -0.43878173828125 0.9167781250000001 +0.208625 -0.450225830078125 0.9167781250000001 +0.20875 -0.456298828125 0.9167781250000001 +0.208875 -0.45831298828125 0.9167781250000001 +0.209 -0.455841064453125 0.9167781250000001 +0.209125 -0.44830322265625 0.9167781250000001 +0.20925 -0.4359130859375 0.9167781250000001 +0.209375 -0.420654296875 0.9167781250000001 +0.2095 -0.399322509765625 0.9167781250000001 +0.209625 -0.376373291015625 0.9167781250000001 +0.20975 -0.346954345703125 0.9167781250000001 +0.209875 -0.313751220703125 0.9167781250000001 +0.21 -0.280914306640625 0.9167781250000001 +0.210125 -0.24151611328125 0.9167781250000001 +0.21025 -0.20379638671875 0.9167781250000001 +0.210375 -0.159759521484375 0.9167781250000001 +0.2105 -0.11395263671875 0.9167781250000001 +0.210625 -0.071685791015625 0.9167781250000001 +0.21075 -0.023956298828125 0.9167781250000001 0.210875 0.0191650390625 0.9167781250000001 0.211 0.066925048828125 0.9167781250000001 0.211125 0.11395263671875 0.9167781250000001 @@ -1716,37 +1716,37 @@ 0.214375 0.127838134765625 0.9167781250000001 0.2145 0.081146240234375 0.9167781250000001 0.214625 0.038330078125 0.9167781250000001 -0.21475 -0.009613037109375 0.9167781250000001 -0.214875 -0.057464599609375 0.9167781250000001 -0.215 -0.0999755859375 0.9167781250000001 -0.215125 -0.146209716796875 0.9167781250000001 -0.21525 -0.186431884765625 0.9167781250000001 -0.215375 -0.22918701171875 0.9167781250000001 -0.2155 -0.2694091796875 0.9167781250000001 -0.215625 -0.303131103515625 0.9167781250000001 -0.21575 -0.33740234375 0.9167781250000001 -0.215875 -0.3651123046875 0.9167781250000001 -0.216 -0.392059326171875 0.9167781250000001 -0.216125 -0.41473388671875 0.9167781250000001 -0.21625 -0.4312744140625 0.9167781250000001 -0.216375 -0.44512939453125 0.9167781250000001 -0.2165 -0.453460693359375 0.9167781250000001 -0.216625 -0.457977294921875 0.9167781250000001 -0.21675 -0.45745849609375 0.9167781250000001 -0.216875 -0.452728271484375 0.9167781250000001 -0.217 -0.4427490234375 0.9167781250000001 -0.217125 -0.42962646484375 0.9167781250000001 -0.21725 -0.410552978515625 0.9167781250000001 -0.217375 -0.38702392578125 0.9167781250000001 -0.2175 -0.3621826171875 0.9167781250000001 -0.217625 -0.330841064453125 0.9167781250000001 -0.21775 -0.29949951171875 0.9167781250000001 -0.217875 -0.2615966796875 0.9167781250000001 -0.218 -0.2208251953125 0.9167781250000001 -0.218125 -0.182037353515625 0.9167781250000001 -0.21825 -0.1370849609375 0.9167781250000001 -0.218375 -0.095306396484375 0.9167781250000001 -0.2185 -0.04791259765625 0.9167781250000001 +0.21475 -0.00958251953125 0.9167781250000001 +0.214875 -0.05743408203125 0.9167781250000001 +0.215 -0.099945068359375 0.9167781250000001 +0.215125 -0.14617919921875 0.9167781250000001 +0.21525 -0.1864013671875 0.9167781250000001 +0.215375 -0.229156494140625 0.9167781250000001 +0.2155 -0.269378662109375 0.9167781250000001 +0.215625 -0.3031005859375 0.9167781250000001 +0.21575 -0.337371826171875 0.9167781250000001 +0.215875 -0.365081787109375 0.9167781250000001 +0.216 -0.39202880859375 0.9167781250000001 +0.216125 -0.414703369140625 0.9167781250000001 +0.21625 -0.431243896484375 0.9167781250000001 +0.216375 -0.445098876953125 0.9167781250000001 +0.2165 -0.45343017578125 0.9167781250000001 +0.216625 -0.45794677734375 0.9167781250000001 +0.21675 -0.457427978515625 0.9167781250000001 +0.216875 -0.45269775390625 0.9167781250000001 +0.217 -0.442718505859375 0.9167781250000001 +0.217125 -0.429595947265625 0.9167781250000001 +0.21725 -0.4105224609375 0.9167781250000001 +0.217375 -0.386993408203125 0.9167781250000001 +0.2175 -0.362152099609375 0.9167781250000001 +0.217625 -0.330810546875 0.9167781250000001 +0.21775 -0.299468994140625 0.9167781250000001 +0.217875 -0.261566162109375 0.9167781250000001 +0.218 -0.220794677734375 0.9167781250000001 +0.218125 -0.1820068359375 0.9167781250000001 +0.21825 -0.137054443359375 0.9167781250000001 +0.218375 -0.09527587890625 0.9167781250000001 +0.2185 -0.047882080078125 0.9167781250000001 0.218625 0.0 0.9167781250000001 0.21875 0.043121337890625 0.9167781250000001 0.218875 0.090576171875 0.9167781250000001 @@ -1779,37 +1779,37 @@ 0.22225 0.104644775390625 0.9167781250000001 0.222375 0.05743408203125 0.9167781250000001 0.2225 0.014373779296875 0.9167781250000001 -0.222625 -0.0335693359375 0.9167781250000001 -0.22275 -0.076446533203125 0.9167781250000001 -0.222875 -0.123260498046875 0.9167781250000001 -0.223 -0.168731689453125 0.9167781250000001 -0.223125 -0.208099365234375 0.9167781250000001 -0.22325 -0.249664306640625 0.9167781250000001 -0.223375 -0.28472900390625 0.9167781250000001 -0.2235 -0.320709228515625 0.9167781250000001 -0.223625 -0.353179931640625 0.9167781250000001 -0.22375 -0.37908935546875 0.9167781250000001 -0.223875 -0.403961181640625 0.9167781250000001 -0.224 -0.46087646484375 0.9999511726200581 -0.224125 -0.478607177734375 0.9999511726200581 -0.22425 -0.4910888671875 0.9999511726200581 -0.224375 -0.49774169921875 0.9999511726200581 -0.2245 -0.49993896484375 0.9999511726200581 -0.224625 -0.497222900390625 0.9999511726200581 -0.22475 -0.489013671875 0.9999511726200581 -0.224875 -0.475494384765625 0.9999511726200581 -0.225 -0.458831787109375 0.9999511726200581 -0.225125 -0.435577392578125 0.9999511726200581 -0.22525 -0.4105224609375 0.9999511726200581 -0.225375 -0.378448486328125 0.9999511726200581 -0.2255 -0.34222412109375 0.9999511726200581 -0.225625 -0.306427001953125 0.9999511726200581 -0.22575 -0.263458251953125 0.9999511726200581 -0.225875 -0.2222900390625 0.9999511726200581 -0.226 -0.17425537109375 0.9999511726200581 -0.226125 -0.12432861328125 0.9999511726200581 -0.22625 -0.078216552734375 0.9999511726200581 -0.226375 -0.026153564453125 0.9999511726200581 +0.222625 -0.033538818359375 0.9167781250000001 +0.22275 -0.076416015625 0.9167781250000001 +0.222875 -0.12322998046875 0.9167781250000001 +0.223 -0.168701171875 0.9167781250000001 +0.223125 -0.20806884765625 0.9167781250000001 +0.22325 -0.2496337890625 0.9167781250000001 +0.223375 -0.284698486328125 0.9167781250000001 +0.2235 -0.3206787109375 0.9167781250000001 +0.223625 -0.3531494140625 0.9167781250000001 +0.22375 -0.379058837890625 0.9167781250000001 +0.223875 -0.4039306640625 0.9167781250000001 +0.224 -0.460845947265625 0.9999511726200581 +0.224125 -0.47857666015625 0.9999511726200581 +0.22425 -0.491058349609375 0.9999511726200581 +0.224375 -0.497711181640625 0.9999511726200581 +0.2245 -0.499908447265625 0.9999511726200581 +0.224625 -0.4971923828125 0.9999511726200581 +0.22475 -0.488983154296875 0.9999511726200581 +0.224875 -0.4754638671875 0.9999511726200581 +0.225 -0.45880126953125 0.9999511726200581 +0.225125 -0.435546875 0.9999511726200581 +0.22525 -0.410491943359375 0.9999511726200581 +0.225375 -0.37841796875 0.9999511726200581 +0.2255 -0.342193603515625 0.9999511726200581 +0.225625 -0.306396484375 0.9999511726200581 +0.22575 -0.263427734375 0.9999511726200581 +0.225875 -0.222259521484375 0.9999511726200581 +0.226 -0.174224853515625 0.9999511726200581 +0.226125 -0.124298095703125 0.9999511726200581 +0.22625 -0.07818603515625 0.9999511726200581 +0.226375 -0.026123046875 0.9999511726200581 0.2265 0.020904541015625 0.9999511726200581 0.226625 0.072998046875 0.9999511726200581 0.22675 0.124298095703125 0.9999511726200581 @@ -1841,37 +1841,37 @@ 0.23 0.13946533203125 0.9999511726200581 0.230125 0.0885009765625 0.9999511726200581 0.23025 0.04180908203125 0.9999511726200581 -0.230375 -0.010467529296875 0.9999511726200581 -0.2305 -0.062652587890625 0.9999511726200581 -0.230625 -0.10906982421875 0.9999511726200581 -0.23075 -0.15948486328125 0.9999511726200581 -0.230875 -0.203338623046875 0.9999511726200581 -0.231 -0.249969482421875 0.9999511726200581 -0.231125 -0.293853759765625 0.9999511726200581 -0.23125 -0.33062744140625 0.9999511726200581 -0.231375 -0.368011474609375 0.9999511726200581 -0.2315 -0.398223876953125 0.9999511726200581 -0.231625 -0.427642822265625 0.9999511726200581 -0.23175 -0.452362060546875 0.9999511726200581 -0.231875 -0.47039794921875 0.9999511726200581 -0.232 -0.48553466796875 0.9999511726200581 -0.232125 -0.494598388671875 0.9999511726200581 -0.23225 -0.49951171875 0.9999511726200581 -0.232375 -0.49896240234375 0.9999511726200581 -0.2325 -0.493804931640625 0.9999511726200581 -0.232625 -0.48291015625 0.9999511726200581 -0.23275 -0.468597412109375 0.9999511726200581 -0.232875 -0.44781494140625 0.9999511726200581 -0.233 -0.422119140625 0.9999511726200581 -0.233125 -0.395050048828125 0.9999511726200581 -0.23325 -0.36083984375 0.9999511726200581 -0.233375 -0.326690673828125 0.9999511726200581 -0.2335 -0.28533935546875 0.9999511726200581 -0.233625 -0.2408447265625 0.9999511726200581 -0.23375 -0.19854736328125 0.9999511726200581 -0.233875 -0.149505615234375 0.9999511726200581 -0.234 -0.10394287109375 0.9999511726200581 -0.234125 -0.052276611328125 0.9999511726200581 +0.230375 -0.01043701171875 0.9999511726200581 +0.2305 -0.0626220703125 0.9999511726200581 +0.230625 -0.109039306640625 0.9999511726200581 +0.23075 -0.159454345703125 0.9999511726200581 +0.230875 -0.20330810546875 0.9999511726200581 +0.231 -0.24993896484375 0.9999511726200581 +0.231125 -0.2938232421875 0.9999511726200581 +0.23125 -0.330596923828125 0.9999511726200581 +0.231375 -0.36798095703125 0.9999511726200581 +0.2315 -0.398193359375 0.9999511726200581 +0.231625 -0.4276123046875 0.9999511726200581 +0.23175 -0.45233154296875 0.9999511726200581 +0.231875 -0.470367431640625 0.9999511726200581 +0.232 -0.485504150390625 0.9999511726200581 +0.232125 -0.49456787109375 0.9999511726200581 +0.23225 -0.499481201171875 0.9999511726200581 +0.232375 -0.498931884765625 0.9999511726200581 +0.2325 -0.4937744140625 0.9999511726200581 +0.232625 -0.482879638671875 0.9999511726200581 +0.23275 -0.46856689453125 0.9999511726200581 +0.232875 -0.447784423828125 0.9999511726200581 +0.233 -0.422088623046875 0.9999511726200581 +0.233125 -0.39501953125 0.9999511726200581 +0.23325 -0.360809326171875 0.9999511726200581 +0.233375 -0.32666015625 0.9999511726200581 +0.2335 -0.285308837890625 0.9999511726200581 +0.233625 -0.240814208984375 0.9999511726200581 +0.23375 -0.198516845703125 0.9999511726200581 +0.233875 -0.14947509765625 0.9999511726200581 +0.234 -0.103912353515625 0.9999511726200581 +0.234125 -0.05224609375 0.9999511726200581 0.23425 0.0 0.9999511726200581 0.234375 0.047027587890625 0.9999511726200581 0.2345 0.098785400390625 0.9999511726200581 @@ -1904,37 +1904,37 @@ 0.237875 0.1141357421875 0.9999511726200581 0.238 0.0626220703125 0.9999511726200581 0.238125 0.01568603515625 0.9999511726200581 -0.23825 -0.03662109375 0.9999511726200581 -0.238375 -0.0833740234375 0.9999511726200581 -0.2385 -0.13446044921875 0.9999511726200581 -0.238625 -0.184051513671875 0.9999511726200581 -0.23875 -0.226959228515625 0.9999511726200581 -0.238875 -0.272308349609375 0.9999511726200581 -0.239 -0.310546875 0.9999511726200581 -0.239125 -0.34979248046875 0.9999511726200581 -0.23925 -0.385223388671875 0.9999511726200581 -0.239375 -0.413482666015625 0.9999511726200581 -0.2395 -0.44061279296875 0.9999511726200581 -0.239625 -0.46087646484375 0.9999511726200581 -0.23975 -0.478607177734375 0.9999511726200581 -0.239875 -0.4910888671875 0.9999511726200581 -0.24 -0.49774169921875 0.9999511726200581 -0.240125 -0.49993896484375 0.9999511726200581 -0.24025 -0.497222900390625 0.9999511726200581 -0.240375 -0.489013671875 0.9999511726200581 -0.2405 -0.475494384765625 0.9999511726200581 -0.240625 -0.458831787109375 0.9999511726200581 -0.24075 -0.435577392578125 0.9999511726200581 -0.240875 -0.4105224609375 0.9999511726200581 -0.241 -0.378448486328125 0.9999511726200581 -0.241125 -0.34222412109375 0.9999511726200581 -0.24125 -0.306427001953125 0.9999511726200581 -0.241375 -0.263458251953125 0.9999511726200581 -0.2415 -0.2222900390625 0.9999511726200581 -0.241625 -0.17425537109375 0.9999511726200581 -0.24175 -0.12432861328125 0.9999511726200581 -0.241875 -0.078216552734375 0.9999511726200581 -0.242 -0.026153564453125 0.9999511726200581 +0.23825 -0.036590576171875 0.9999511726200581 +0.238375 -0.083343505859375 0.9999511726200581 +0.2385 -0.134429931640625 0.9999511726200581 +0.238625 -0.18402099609375 0.9999511726200581 +0.23875 -0.2269287109375 0.9999511726200581 +0.238875 -0.27227783203125 0.9999511726200581 +0.239 -0.310516357421875 0.9999511726200581 +0.239125 -0.349761962890625 0.9999511726200581 +0.23925 -0.38519287109375 0.9999511726200581 +0.239375 -0.4134521484375 0.9999511726200581 +0.2395 -0.440582275390625 0.9999511726200581 +0.239625 -0.460845947265625 0.9999511726200581 +0.23975 -0.47857666015625 0.9999511726200581 +0.239875 -0.491058349609375 0.9999511726200581 +0.24 -0.497711181640625 0.9999511726200581 +0.240125 -0.499908447265625 0.9999511726200581 +0.24025 -0.4971923828125 0.9999511726200581 +0.240375 -0.488983154296875 0.9999511726200581 +0.2405 -0.4754638671875 0.9999511726200581 +0.240625 -0.45880126953125 0.9999511726200581 +0.24075 -0.435546875 0.9999511726200581 +0.240875 -0.410491943359375 0.9999511726200581 +0.241 -0.37841796875 0.9999511726200581 +0.241125 -0.342193603515625 0.9999511726200581 +0.24125 -0.306396484375 0.9999511726200581 +0.241375 -0.263427734375 0.9999511726200581 +0.2415 -0.222259521484375 0.9999511726200581 +0.241625 -0.174224853515625 0.9999511726200581 +0.24175 -0.124298095703125 0.9999511726200581 +0.241875 -0.07818603515625 0.9999511726200581 +0.242 -0.026123046875 0.9999511726200581 0.242125 0.020904541015625 0.9999511726200581 0.24225 0.072998046875 0.9999511726200581 0.242375 0.124298095703125 0.9999511726200581 @@ -1966,37 +1966,37 @@ 0.245625 0.13946533203125 0.9999511726200581 0.24575 0.0885009765625 0.9999511726200581 0.245875 0.04180908203125 0.9999511726200581 -0.246 -0.010467529296875 0.9999511726200581 -0.246125 -0.062652587890625 0.9999511726200581 -0.24625 -0.10906982421875 0.9999511726200581 -0.246375 -0.15948486328125 0.9999511726200581 -0.2465 -0.203338623046875 0.9999511726200581 -0.246625 -0.249969482421875 0.9999511726200581 -0.24675 -0.293853759765625 0.9999511726200581 -0.246875 -0.33062744140625 0.9999511726200581 -0.247 -0.368011474609375 0.9999511726200581 -0.247125 -0.398223876953125 0.9999511726200581 -0.24725 -0.427642822265625 0.9999511726200581 -0.247375 -0.452362060546875 0.9999511726200581 -0.2475 -0.47039794921875 0.9999511726200581 -0.247625 -0.48553466796875 0.9999511726200581 -0.24775 -0.494598388671875 0.9999511726200581 -0.247875 -0.49951171875 0.9999511726200581 -0.248 -0.49896240234375 0.9999511726200581 -0.248125 -0.493804931640625 0.9999511726200581 -0.24825 -0.48291015625 0.9999511726200581 -0.248375 -0.468597412109375 0.9999511726200581 -0.2485 -0.44781494140625 0.9999511726200581 -0.248625 -0.422119140625 0.9999511726200581 -0.24875 -0.395050048828125 0.9999511726200581 -0.248875 -0.36083984375 0.9999511726200581 -0.249 -0.326690673828125 0.9999511726200581 -0.249125 -0.28533935546875 0.9999511726200581 -0.24925 -0.2408447265625 0.9999511726200581 -0.249375 -0.19854736328125 0.9999511726200581 -0.2495 -0.149505615234375 0.9999511726200581 -0.249625 -0.10394287109375 0.9999511726200581 -0.24975 -0.052276611328125 0.9999511726200581 +0.246 -0.01043701171875 0.9999511726200581 +0.246125 -0.0626220703125 0.9999511726200581 +0.24625 -0.109039306640625 0.9999511726200581 +0.246375 -0.159454345703125 0.9999511726200581 +0.2465 -0.20330810546875 0.9999511726200581 +0.246625 -0.24993896484375 0.9999511726200581 +0.24675 -0.2938232421875 0.9999511726200581 +0.246875 -0.330596923828125 0.9999511726200581 +0.247 -0.36798095703125 0.9999511726200581 +0.247125 -0.398193359375 0.9999511726200581 +0.24725 -0.4276123046875 0.9999511726200581 +0.247375 -0.45233154296875 0.9999511726200581 +0.2475 -0.470367431640625 0.9999511726200581 +0.247625 -0.485504150390625 0.9999511726200581 +0.24775 -0.49456787109375 0.9999511726200581 +0.247875 -0.499481201171875 0.9999511726200581 +0.248 -0.498931884765625 0.9999511726200581 +0.248125 -0.4937744140625 0.9999511726200581 +0.24825 -0.482879638671875 0.9999511726200581 +0.248375 -0.46856689453125 0.9999511726200581 +0.2485 -0.447784423828125 0.9999511726200581 +0.248625 -0.422088623046875 0.9999511726200581 +0.24875 -0.39501953125 0.9999511726200581 +0.248875 -0.360809326171875 0.9999511726200581 +0.249 -0.32666015625 0.9999511726200581 +0.249125 -0.285308837890625 0.9999511726200581 +0.24925 -0.240814208984375 0.9999511726200581 +0.249375 -0.198516845703125 0.9999511726200581 +0.2495 -0.14947509765625 0.9999511726200581 +0.249625 -0.103912353515625 0.9999511726200581 +0.24975 -0.05224609375 0.9999511726200581 0.249875 0.0 0.9999511726200581 0.25 0.047027587890625 0.9999511726200581 0.250125 0.098785400390625 0.9999511726200581 @@ -2029,20 +2029,20 @@ 0.2535 0.1141357421875 0.9999511726200581 0.253625 0.0626220703125 0.9999511726200581 0.2537500000000001 0.01568603515625 0.9999511726200581 -0.253875 -0.03662109375 0.9999511726200581 -0.254 -0.0833740234375 0.9999511726200581 -0.254125 -0.13446044921875 0.9999511726200581 -0.25425 -0.184051513671875 0.9999511726200581 -0.254375 -0.226959228515625 0.9999511726200581 -0.2545 -0.272308349609375 0.9999511726200581 -0.254625 -0.310546875 0.9999511726200581 -0.25475 -0.34979248046875 0.9999511726200581 -0.254875 -0.385223388671875 0.9999511726200581 -0.255 -0.413482666015625 0.9999511726200581 -0.255125 -0.44061279296875 0.9999511726200581 -0.25525 -0.46087646484375 0.9999511726200581 -0.255375 -0.478607177734375 0.9999511726200581 -0.2555 -0.4910888671875 0.9999511726200581 -0.255625 -0.49774169921875 0.9999511726200581 -0.25575 -0.49993896484375 0.9999511726200581 -0.255875 -0.497222900390625 0.9999511726200581 +0.253875 -0.036590576171875 0.9999511726200581 +0.254 -0.083343505859375 0.9999511726200581 +0.254125 -0.134429931640625 0.9999511726200581 +0.25425 -0.18402099609375 0.9999511726200581 +0.254375 -0.2269287109375 0.9999511726200581 +0.2545 -0.27227783203125 0.9999511726200581 +0.254625 -0.310516357421875 0.9999511726200581 +0.25475 -0.349761962890625 0.9999511726200581 +0.254875 -0.38519287109375 0.9999511726200581 +0.255 -0.4134521484375 0.9999511726200581 +0.255125 -0.440582275390625 0.9999511726200581 +0.25525 -0.460845947265625 0.9999511726200581 +0.255375 -0.47857666015625 0.9999511726200581 +0.2555 -0.491058349609375 0.9999511726200581 +0.255625 -0.497711181640625 0.9999511726200581 +0.25575 -0.499908447265625 0.9999511726200581 +0.255875 -0.4971923828125 0.9999511726200581 diff --git a/tests/circuitpython/synth_note_panning.py b/tests/circuitpython/synth_note_panning.py new file mode 100644 index 00000000000..3968f2dfddb --- /dev/null +++ b/tests/circuitpython/synth_note_panning.py @@ -0,0 +1,10 @@ +from synthnotehelper import * + + +@synth_test(channel_count=2) +def gen(synth): + l = LFO(sine, offset=0.0, scale=1.0, rate=2) + yield [l] + n = Note(8, panning=l) + synth.press(n) + yield 2 diff --git a/tests/circuitpython/synth_note_panning.py.exp b/tests/circuitpython/synth_note_panning.py.exp new file mode 100644 index 00000000000..7b6bd871424 --- /dev/null +++ b/tests/circuitpython/synth_note_panning.py.exp @@ -0,0 +1,16128 @@ +0.0 0.0 0.0 0.391339111328125 +0.000125 0.003173828125 0.005218505859375 0.391339111328125 +0.00025 0.003173828125 0.005218505859375 0.391339111328125 +0.000375 0.00634765625 0.01043701171875 0.391339111328125 +0.0005 0.009552001953125 0.01568603515625 0.391339111328125 +0.000625 0.009552001953125 0.01568603515625 0.391339111328125 +0.00075 0.012725830078125 0.020904541015625 0.391339111328125 +0.000875 0.012725830078125 0.020904541015625 0.391339111328125 +0.001 0.015899658203125 0.026123046875 0.391339111328125 +0.0011250000000000002 0.019073486328125 0.0313720703125 0.391339111328125 +0.00125 0.019073486328125 0.0313720703125 0.391339111328125 +0.001375 0.022247314453125 0.036590576171875 0.391339111328125 +0.0015 0.022247314453125 0.036590576171875 0.391339111328125 +0.0016250000000000002 0.02545166015625 0.04180908203125 0.391339111328125 +0.00175 0.02862548828125 0.047027587890625 0.391339111328125 +0.001875 0.02862548828125 0.047027587890625 0.391339111328125 +0.002 0.03179931640625 0.05224609375 0.391339111328125 +0.002125 0.03179931640625 0.05224609375 0.391339111328125 +0.0022500000000000004 0.034942626953125 0.05743408203125 0.391339111328125 +0.002375 0.038116455078125 0.0626220703125 0.391339111328125 +0.0025 0.038116455078125 0.0626220703125 0.391339111328125 +0.002625 0.041259765625 0.06781005859375 0.391339111328125 +0.00275 0.041259765625 0.06781005859375 0.391339111328125 +0.002875 0.04443359375 0.072998046875 0.391339111328125 +0.003 0.047576904296875 0.07818603515625 0.391339111328125 +0.003125 0.047576904296875 0.07818603515625 0.391339111328125 +0.0032500000000000004 0.05072021484375 0.083343505859375 0.391339111328125 +0.003375 0.05072021484375 0.083343505859375 0.391339111328125 +0.0035 0.053863525390625 0.0885009765625 0.391339111328125 +0.003625 0.0570068359375 0.093658447265625 0.391339111328125 +0.00375 0.0570068359375 0.093658447265625 0.391339111328125 +0.003875 0.06011962890625 0.098785400390625 0.391339111328125 +0.004 0.06011962890625 0.098785400390625 0.391339111328125 +0.004125 0.063232421875 0.103912353515625 0.391339111328125 +0.00425 0.06634521484375 0.109039306640625 0.391339111328125 +0.004375 0.06634521484375 0.109039306640625 0.391339111328125 +0.0045000000000000006 0.0694580078125 0.1141357421875 0.391339111328125 +0.004625 0.0694580078125 0.1141357421875 0.391339111328125 +0.00475 0.07257080078125 0.119232177734375 0.391339111328125 +0.004875 0.075653076171875 0.124298095703125 0.391339111328125 +0.005 0.075653076171875 0.124298095703125 0.391339111328125 +0.005125 0.0787353515625 0.129364013671875 0.391339111328125 +0.00525 0.0787353515625 0.129364013671875 0.391339111328125 +0.0053750000000000008 0.081817626953125 0.134429931640625 0.391339111328125 +0.0055 0.084869384765625 0.13946533203125 0.391339111328125 +0.005625 0.084869384765625 0.13946533203125 0.391339111328125 +0.00575 0.087921142578125 0.14447021484375 0.391339111328125 +0.005875 0.087921142578125 0.14447021484375 0.391339111328125 +0.006 0.090972900390625 0.14947509765625 0.391339111328125 +0.006125 0.093994140625 0.15447998046875 0.391339111328125 +0.00625 0.093994140625 0.15447998046875 0.391339111328125 +0.0063750000000000008 0.0970458984375 0.159454345703125 0.391339111328125 +0.006500000000000001 0.0970458984375 0.159454345703125 0.391339111328125 +0.006625 0.10003662109375 0.164398193359375 0.391339111328125 +0.00675 0.103057861328125 0.169342041015625 0.391339111328125 +0.006875 0.103057861328125 0.169342041015625 0.391339111328125 +0.007 0.106048583984375 0.17425537109375 0.391339111328125 +0.007125 0.106048583984375 0.17425537109375 0.391339111328125 +0.00725 0.1090087890625 0.17913818359375 0.391339111328125 +0.00737500000000000064 0.11199951171875 0.18402099609375 0.391339111328125 +0.0075 0.11199951171875 0.18402099609375 0.391339111328125 +0.007625 0.114959716796875 0.188873291015625 0.391339111328125 +0.00775 0.114959716796875 0.188873291015625 0.391339111328125 +0.007875 0.117889404296875 0.1937255859375 0.391339111328125 +0.008 0.120819091796875 0.19854736328125 0.391339111328125 +0.008125 0.120819091796875 0.19854736328125 0.391339111328125 +0.00825 0.123748779296875 0.203338623046875 0.391339111328125 +0.008375 0.123748779296875 0.203338623046875 0.391339111328125 +0.008500000000000001 0.12664794921875 0.208099365234375 0.391339111328125 +0.008625000000000001 0.129547119140625 0.212860107421875 0.391339111328125 +0.008750000000000001 0.129547119140625 0.212860107421875 0.391339111328125 +0.008875000000000001 0.132415771484375 0.21759033203125 0.391339111328125 +0.009000000000000001 0.132415771484375 0.21759033203125 0.391339111328125 +0.009125 0.135284423828125 0.2222900390625 0.391339111328125 +0.00925 0.13812255859375 0.226959228515625 0.391339111328125 +0.009375 0.13812255859375 0.226959228515625 0.391339111328125 +0.0095 0.140960693359375 0.231597900390625 0.391339111328125 +0.009625 0.140960693359375 0.231597900390625 0.391339111328125 +0.00975 0.143768310546875 0.236236572265625 0.391339111328125 +0.009875 0.146575927734375 0.2408447265625 0.391339111328125 +0.01 0.146575927734375 0.2408447265625 0.391339111328125 +0.010125 0.14935302734375 0.24542236328125 0.391339111328125 +0.01025 0.14935302734375 0.24542236328125 0.391339111328125 +0.010375 0.152130126953125 0.249969482421875 0.391339111328125 +0.0105 0.154876708984375 0.25445556640625 0.391339111328125 +0.010625 0.154876708984375 0.25445556640625 0.391339111328125 +0.0107500000000000016 0.157623291015625 0.25897216796875 0.391339111328125 +0.0108750000000000016 0.157623291015625 0.25897216796875 0.391339111328125 +0.011 0.160308837890625 0.263427734375 0.391339111328125 +0.011125 0.16302490234375 0.267852783203125 0.391339111328125 +0.01125 0.16302490234375 0.267852783203125 0.391339111328125 +0.011375 0.16571044921875 0.27227783203125 0.391339111328125 +0.0115 0.16571044921875 0.27227783203125 0.391339111328125 +0.011625 0.168365478515625 0.276641845703125 0.391339111328125 +0.01175 0.1710205078125 0.280975341796875 0.391339111328125 +0.011875 0.1710205078125 0.280975341796875 0.391339111328125 +0.012 0.17364501953125 0.285308837890625 0.391339111328125 +0.012125 0.17364501953125 0.285308837890625 0.391339111328125 +0.01225 0.176239013671875 0.289581298828125 0.391339111328125 +0.012375 0.1788330078125 0.2938232421875 0.391339111328125 +0.0125 0.1788330078125 0.2938232421875 0.391339111328125 +0.012625 0.181396484375 0.298065185546875 0.391339111328125 +0.0127500000000000016 0.181396484375 0.298065185546875 0.391339111328125 +0.0128750000000000016 0.1839599609375 0.30224609375 0.391339111328125 +0.013000000000000002 0.186492919921875 0.306396484375 0.391339111328125 +0.013125 0.186492919921875 0.306396484375 0.391339111328125 +0.01325 0.188995361328125 0.310516357421875 0.391339111328125 +0.013375 0.188995361328125 0.310516357421875 0.391339111328125 +0.0135 0.19146728515625 0.314605712890625 0.391339111328125 +0.013625 0.193939208984375 0.31866455078125 0.391339111328125 +0.01375 0.193939208984375 0.31866455078125 0.391339111328125 +0.013875 0.196380615234375 0.322662353515625 0.391339111328125 +0.014 0.196380615234375 0.322662353515625 0.391339111328125 +0.014125 0.19879150390625 0.32666015625 0.391339111328125 +0.01425 0.201202392578125 0.330596923828125 0.391339111328125 +0.014375 0.201202392578125 0.330596923828125 0.391339111328125 +0.0145 0.203582763671875 0.334503173828125 0.391339111328125 +0.014625 0.203582763671875 0.334503173828125 0.391339111328125 +0.0147500000000000016 0.2059326171875 0.33837890625 0.391339111328125 +0.0148750000000000013 0.208282470703125 0.34222412109375 0.391339111328125 +0.015 0.208282470703125 0.34222412109375 0.391339111328125 +0.015125 0.210601806640625 0.34600830078125 0.391339111328125 +0.01525 0.210601806640625 0.34600830078125 0.391339111328125 +0.015375 0.212860107421875 0.349761962890625 0.391339111328125 +0.0155 0.21514892578125 0.353485107421875 0.391339111328125 +0.015625 0.21514892578125 0.353485107421875 0.391339111328125 +0.01575 0.217376708984375 0.357177734375 0.391339111328125 +0.015875 0.217376708984375 0.357177734375 0.391339111328125 +0.016 0.2196044921875 0.360809326171875 0.391339111328125 +0.016125 0.2218017578125 0.36444091796875 0.391339111328125 +0.01625 0.2218017578125 0.36444091796875 0.391339111328125 +0.016375 0.223968505859375 0.36798095703125 0.391339111328125 +0.0165 0.223968505859375 0.36798095703125 0.391339111328125 +0.016625 0.226104736328125 0.37152099609375 0.391339111328125 +0.01675 0.22821044921875 0.375 0.391339111328125 +0.016875 0.22821044921875 0.375 0.391339111328125 +0.017 0.230316162109375 0.378448486328125 0.391339111328125 +0.017125 0.230316162109375 0.378448486328125 0.391339111328125 +0.01725 0.232391357421875 0.3818359375 0.391339111328125 +0.017375 0.23443603515625 0.38519287109375 0.391339111328125 +0.0175 0.23443603515625 0.38519287109375 0.391339111328125 +0.017625000000000002 0.2364501953125 0.388519287109375 0.391339111328125 +0.017750000000000002 0.2364501953125 0.388519287109375 0.391339111328125 +0.017875000000000002 0.238433837890625 0.39178466796875 0.391339111328125 +0.018000000000000002 0.24041748046875 0.39501953125 0.391339111328125 +0.018125 0.24041748046875 0.39501953125 0.391339111328125 +0.01825 0.242340087890625 0.398193359375 0.391339111328125 +0.018375 0.242340087890625 0.398193359375 0.391339111328125 +0.0185 0.2442626953125 0.401336669921875 0.391339111328125 +0.018625 0.24615478515625 0.404449462890625 0.391339111328125 +0.01875 0.24615478515625 0.404449462890625 0.391339111328125 +0.018875 0.248016357421875 0.407501220703125 0.391339111328125 +0.019 0.248016357421875 0.407501220703125 0.391339111328125 +0.019125 0.249847412109375 0.4105224609375 0.391339111328125 +0.01925 0.25164794921875 0.413482666015625 0.391339111328125 +0.019375 0.25164794921875 0.413482666015625 0.391339111328125 +0.0195 0.25341796875 0.416412353515625 0.391339111328125 +0.019625 0.25341796875 0.416412353515625 0.391339111328125 +0.01975 0.255157470703125 0.419281005859375 0.391339111328125 +0.019875 0.25689697265625 0.422119140625 0.391339111328125 +0.02 0.25689697265625 0.422119140625 0.391339111328125 +0.020125 0.258575439453125 0.424896240234375 0.391339111328125 +0.02025 0.258575439453125 0.424896240234375 0.391339111328125 +0.020375 0.26025390625 0.4276123046875 0.391339111328125 +0.0205 0.261871337890625 0.4302978515625 0.391339111328125 +0.020625 0.261871337890625 0.4302978515625 0.391339111328125 +0.02075 0.26348876953125 0.432952880859375 0.391339111328125 +0.020875 0.26348876953125 0.432952880859375 0.391339111328125 +0.021 0.26507568359375 0.435546875 0.391339111328125 +0.021125 0.266632080078125 0.438079833984375 0.391339111328125 +0.02125 0.266632080078125 0.438079833984375 0.391339111328125 +0.021375 0.268157958984375 0.440582275390625 0.391339111328125 +0.0215000000000000032 0.268157958984375 0.440582275390625 0.391339111328125 +0.0216250000000000032 0.269622802734375 0.44305419921875 0.391339111328125 +0.0217500000000000032 0.271087646484375 0.4454345703125 0.391339111328125 +0.0218750000000000032 0.271087646484375 0.4454345703125 0.391339111328125 +0.022 0.27252197265625 0.447784423828125 0.391339111328125 +0.022125 0.27252197265625 0.447784423828125 0.391339111328125 +0.02225 0.27392578125 0.450103759765625 0.391339111328125 +0.022375 0.275299072265625 0.452362060546875 0.391339111328125 +0.0225 0.275299072265625 0.452362060546875 0.391339111328125 +0.022625 0.276641845703125 0.454559326171875 0.391339111328125 +0.02275 0.276641845703125 0.454559326171875 0.391339111328125 +0.022875 0.2779541015625 0.45672607421875 0.391339111328125 +0.023 0.27923583984375 0.458831787109375 0.391339111328125 +0.023125 0.27923583984375 0.458831787109375 0.391339111328125 +0.02325 0.280487060546875 0.46087646484375 0.391339111328125 +0.023375 0.280487060546875 0.46087646484375 0.391339111328125 +0.0235 0.281707763671875 0.462890625 0.391339111328125 +0.023625 0.28289794921875 0.464813232421875 0.391339111328125 +0.02375 0.28289794921875 0.464813232421875 0.391339111328125 +0.023875 0.2840576171875 0.46673583984375 0.391339111328125 +0.024 0.2840576171875 0.46673583984375 0.391339111328125 +0.024125 0.285186767578125 0.46856689453125 0.391339111328125 +0.02425 0.2862548828125 0.470367431640625 0.391339111328125 +0.024375 0.2862548828125 0.470367431640625 0.391339111328125 +0.0245 0.287322998046875 0.472137451171875 0.391339111328125 +0.024625 0.287322998046875 0.472137451171875 0.391339111328125 +0.02475 0.288360595703125 0.47381591796875 0.391339111328125 +0.024875 0.28936767578125 0.4754638671875 0.391339111328125 +0.025 0.28936767578125 0.4754638671875 0.391339111328125 +0.025125 0.29034423828125 0.47705078125 0.391339111328125 +0.02525 0.29034423828125 0.47705078125 0.391339111328125 +0.025375 0.291259765625 0.478607177734375 0.391339111328125 +0.0255000000000000032 0.29217529296875 0.480072021484375 0.391339111328125 +0.0256250000000000032 0.29217529296875 0.480072021484375 0.391339111328125 +0.0257500000000000032 0.293060302734375 0.48150634765625 0.391339111328125 +0.0258750000000000032 0.293060302734375 0.48150634765625 0.391339111328125 +0.026000000000000004 0.29388427734375 0.48291015625 0.391339111328125 +0.026125 0.294708251953125 0.484222412109375 0.391339111328125 +0.02625 0.294708251953125 0.484222412109375 0.391339111328125 +0.026375 0.29547119140625 0.485504150390625 0.391339111328125 +0.0265 0.29547119140625 0.485504150390625 0.391339111328125 +0.026625 0.296234130859375 0.486724853515625 0.391339111328125 +0.02675 0.29693603515625 0.487884521484375 0.391339111328125 +0.026875 0.29693603515625 0.487884521484375 0.391339111328125 +0.027 0.297607421875 0.489013671875 0.391339111328125 +0.027125 0.297607421875 0.489013671875 0.391339111328125 +0.02725 0.298248291015625 0.490081787109375 0.391339111328125 +0.027375 0.298858642578125 0.4910888671875 0.391339111328125 +0.0275 0.298858642578125 0.4910888671875 0.391339111328125 +0.027625 0.299468994140625 0.492034912109375 0.391339111328125 +0.02775 0.299468994140625 0.492034912109375 0.391339111328125 +0.027875 0.300018310546875 0.492950439453125 0.391339111328125 +0.028 0.300506591796875 0.4937744140625 0.391339111328125 +0.028125 0.300506591796875 0.4937744140625 0.391339111328125 +0.02825 0.300994873046875 0.49456787109375 0.391339111328125 +0.028375 0.300994873046875 0.49456787109375 0.391339111328125 +0.0285 0.30145263671875 0.49530029296875 0.391339111328125 +0.028625 0.301849365234375 0.496002197265625 0.391339111328125 +0.02875 0.301849365234375 0.496002197265625 0.391339111328125 +0.028875 0.30224609375 0.496612548828125 0.391339111328125 +0.029 0.30224609375 0.496612548828125 0.391339111328125 +0.029125 0.302581787109375 0.4971923828125 0.391339111328125 +0.02925 0.30291748046875 0.497711181640625 0.391339111328125 +0.0293750000000000032 0.30291748046875 0.497711181640625 0.391339111328125 +0.0295000000000000032 0.303192138671875 0.498199462890625 0.391339111328125 +0.0296250000000000026 0.303192138671875 0.498199462890625 0.391339111328125 +0.0297500000000000026 0.303436279296875 0.49859619140625 0.391339111328125 +0.0298750000000000026 0.30364990234375 0.49896240234375 0.391339111328125 +0.03 0.30364990234375 0.49896240234375 0.391339111328125 +0.030125 0.303863525390625 0.499267578125 0.391339111328125 +0.03025 0.303863525390625 0.499267578125 0.391339111328125 +0.030375 0.303985595703125 0.49951171875 0.391339111328125 +0.0305 0.304107666015625 0.49969482421875 0.391339111328125 +0.030625 0.304107666015625 0.49969482421875 0.391339111328125 +0.03075 0.30419921875 0.49981689453125 0.391339111328125 +0.030875 0.30419921875 0.49981689453125 0.391339111328125 +0.031 0.30426025390625 0.499908447265625 0.391339111328125 +0.031125 0.30426025390625 0.49993896484375 0.391339111328125 +0.03125 0.30426025390625 0.49993896484375 0.391339111328125 +0.031375 0.30426025390625 0.499908447265625 0.391339111328125 +0.0315 0.30426025390625 0.499908447265625 0.391339111328125 +0.031625 0.30419921875 0.49981689453125 0.391339111328125 +0.03175 0.304107666015625 0.49969482421875 0.391339111328125 +0.031875 0.304107666015625 0.49969482421875 0.391339111328125 +0.032 0.139678955078125 0.49951171875 0.7202575683593749 +0.032125 0.139678955078125 0.49951171875 0.7202575683593749 +0.03225 0.139617919921875 0.499267578125 0.7202575683593749 +0.032375 0.1395263671875 0.49896240234375 0.7202575683593749 +0.0325 0.1395263671875 0.49896240234375 0.7202575683593749 +0.032625 0.139434814453125 0.49859619140625 0.7202575683593749 +0.03275 0.139434814453125 0.49859619140625 0.7202575683593749 +0.032875 0.139312744140625 0.498199462890625 0.7202575683593749 +0.033 0.139190673828125 0.497711181640625 0.7202575683593749 +0.033125 0.139190673828125 0.497711181640625 0.7202575683593749 +0.03325 0.1390380859375 0.4971923828125 0.7202575683593749 +0.033375 0.1390380859375 0.4971923828125 0.7202575683593749 +0.0335 0.138885498046875 0.496612548828125 0.7202575683593749 +0.033625 0.138702392578125 0.496002197265625 0.7202575683593749 +0.03375 0.138702392578125 0.496002197265625 0.7202575683593749 +0.033875 0.138519287109375 0.49530029296875 0.7202575683593749 +0.034 0.138519287109375 0.49530029296875 0.7202575683593749 +0.034125 0.1383056640625 0.49456787109375 0.7202575683593749 +0.03425 0.138092041015625 0.4937744140625 0.7202575683593749 +0.034375 0.138092041015625 0.4937744140625 0.7202575683593749 +0.0345 0.137847900390625 0.492950439453125 0.7202575683593749 +0.034625 0.137847900390625 0.492950439453125 0.7202575683593749 +0.03475 0.137603759765625 0.492034912109375 0.7202575683593749 +0.034875 0.1373291015625 0.4910888671875 0.7202575683593749 +0.035 0.1373291015625 0.4910888671875 0.7202575683593749 +0.035125 0.137054443359375 0.490081787109375 0.7202575683593749 +0.035250000000000004 0.137054443359375 0.490081787109375 0.7202575683593749 +0.035375000000000004 0.136749267578125 0.489013671875 0.7202575683593749 +0.035500000000000004 0.136444091796875 0.487884521484375 0.7202575683593749 +0.035625000000000004 0.136444091796875 0.487884521484375 0.7202575683593749 +0.035750000000000004 0.1361083984375 0.486724853515625 0.7202575683593749 +0.035875000000000004 0.1361083984375 0.486724853515625 0.7202575683593749 +0.036000000000000004 0.135772705078125 0.485504150390625 0.7202575683593749 +0.036125 0.135406494140625 0.484222412109375 0.7202575683593749 +0.03625 0.135406494140625 0.484222412109375 0.7202575683593749 +0.036375 0.135040283203125 0.48291015625 0.7202575683593749 +0.0365 0.135040283203125 0.48291015625 0.7202575683593749 +0.036625 0.1346435546875 0.48150634765625 0.7202575683593749 +0.03675 0.134246826171875 0.480072021484375 0.7202575683593749 +0.036875 0.134246826171875 0.480072021484375 0.7202575683593749 +0.037 0.13385009765625 0.478607177734375 0.7202575683593749 +0.037125 0.13385009765625 0.478607177734375 0.7202575683593749 +0.03725 0.1334228515625 0.47705078125 0.7202575683593749 +0.037375 0.132965087890625 0.4754638671875 0.7202575683593749 +0.0375 0.132965087890625 0.4754638671875 0.7202575683593749 +0.037625 0.13250732421875 0.47381591796875 0.7202575683593749 +0.03775 0.13250732421875 0.47381591796875 0.7202575683593749 +0.037875 0.13201904296875 0.472137451171875 0.7202575683593749 +0.038 0.13153076171875 0.470367431640625 0.7202575683593749 +0.038125 0.13153076171875 0.470367431640625 0.7202575683593749 +0.03825 0.13104248046875 0.46856689453125 0.7202575683593749 +0.038375 0.13104248046875 0.46856689453125 0.7202575683593749 +0.0385 0.130523681640625 0.46673583984375 0.7202575683593749 +0.038625 0.129974365234375 0.464813232421875 0.7202575683593749 +0.03875 0.129974365234375 0.464813232421875 0.7202575683593749 +0.038875 0.12945556640625 0.462890625 0.7202575683593749 +0.039 0.12945556640625 0.462890625 0.7202575683593749 +0.039125 0.128875732421875 0.46087646484375 0.7202575683593749 +0.03925 0.128326416015625 0.458831787109375 0.7202575683593749 +0.039375 0.128326416015625 0.458831787109375 0.7202575683593749 +0.0395 0.127716064453125 0.45672607421875 0.7202575683593749 +0.039625 0.127716064453125 0.45672607421875 0.7202575683593749 +0.03975 0.127105712890625 0.454559326171875 0.7202575683593749 +0.039875 0.126495361328125 0.452362060546875 0.7202575683593749 +0.04 0.126495361328125 0.452362060546875 0.7202575683593749 +0.040125 0.125885009765625 0.450103759765625 0.7202575683593749 +0.04025 0.125885009765625 0.450103759765625 0.7202575683593749 +0.040375 0.125213623046875 0.447784423828125 0.7202575683593749 +0.0405 0.12457275390625 0.4454345703125 0.7202575683593749 +0.040625 0.12457275390625 0.4454345703125 0.7202575683593749 +0.04075 0.1239013671875 0.44305419921875 0.7202575683593749 +0.040875 0.1239013671875 0.44305419921875 0.7202575683593749 +0.041 0.123199462890625 0.440582275390625 0.7202575683593749 +0.041125 0.12249755859375 0.438079833984375 0.7202575683593749 +0.04125 0.12249755859375 0.438079833984375 0.7202575683593749 +0.041375 0.121795654296875 0.435546875 0.7202575683593749 +0.0415 0.121795654296875 0.435546875 0.7202575683593749 +0.041625 0.121063232421875 0.432952880859375 0.7202575683593749 +0.04175 0.120330810546875 0.4302978515625 0.7202575683593749 +0.041875 0.120330810546875 0.4302978515625 0.7202575683593749 +0.042 0.119598388671875 0.4276123046875 0.7202575683593749 +0.042125 0.119598388671875 0.4276123046875 0.7202575683593749 +0.04225 0.11883544921875 0.424896240234375 0.7202575683593749 +0.042375 0.1180419921875 0.422119140625 0.7202575683593749 +0.0425 0.1180419921875 0.422119140625 0.7202575683593749 +0.042625 0.11724853515625 0.419281005859375 0.7202575683593749 +0.04275 0.11724853515625 0.419281005859375 0.7202575683593749 +0.042875 0.116455078125 0.416412353515625 0.7202575683593749 +0.0430000000000000036 0.115631103515625 0.413482666015625 0.7202575683593749 +0.0431250000000000036 0.115631103515625 0.413482666015625 0.7202575683593749 +0.0432500000000000036 0.11480712890625 0.4105224609375 0.7202575683593749 +0.0433750000000000036 0.11480712890625 0.4105224609375 0.7202575683593749 +0.0435000000000000036 0.11395263671875 0.407501220703125 0.7202575683593749 +0.0436250000000000036 0.11309814453125 0.404449462890625 0.7202575683593749 +0.0437500000000000036 0.11309814453125 0.404449462890625 0.7202575683593749 +0.0438750000000000036 0.11224365234375 0.401336669921875 0.7202575683593749 +0.044 0.11224365234375 0.401336669921875 0.7202575683593749 +0.044125 0.111358642578125 0.398193359375 0.7202575683593749 +0.04425 0.1104736328125 0.39501953125 0.7202575683593749 +0.044375 0.1104736328125 0.39501953125 0.7202575683593749 +0.0445 0.10955810546875 0.39178466796875 0.7202575683593749 +0.044625 0.10955810546875 0.39178466796875 0.7202575683593749 +0.04475 0.108642578125 0.388519287109375 0.7202575683593749 +0.044875 0.10772705078125 0.38519287109375 0.7202575683593749 +0.045 0.10772705078125 0.38519287109375 0.7202575683593749 +0.045125 0.106781005859375 0.3818359375 0.7202575683593749 +0.04525 0.106781005859375 0.3818359375 0.7202575683593749 +0.045375 0.1058349609375 0.378448486328125 0.7202575683593749 +0.0455 0.1048583984375 0.375 0.7202575683593749 +0.045625 0.1048583984375 0.375 0.7202575683593749 +0.04575 0.1038818359375 0.37152099609375 0.7202575683593749 +0.045875 0.1038818359375 0.37152099609375 0.7202575683593749 +0.046 0.1029052734375 0.36798095703125 0.7202575683593749 +0.046125 0.1019287109375 0.36444091796875 0.7202575683593749 +0.04625 0.1019287109375 0.36444091796875 0.7202575683593749 +0.046375 0.10089111328125 0.360809326171875 0.7202575683593749 +0.0465 0.10089111328125 0.360809326171875 0.7202575683593749 +0.046625 0.099884033203125 0.357177734375 0.7202575683593749 +0.04675 0.098846435546875 0.353485107421875 0.7202575683593749 +0.046875 0.098846435546875 0.353485107421875 0.7202575683593749 +0.047 0.097808837890625 0.349761962890625 0.7202575683593749 +0.047125 0.097808837890625 0.349761962890625 0.7202575683593749 +0.04725 0.096771240234375 0.34600830078125 0.7202575683593749 +0.047375 0.095703125 0.34222412109375 0.7202575683593749 +0.0475 0.095703125 0.34222412109375 0.7202575683593749 +0.047625 0.094635009765625 0.33837890625 0.7202575683593749 +0.04775 0.094635009765625 0.33837890625 0.7202575683593749 +0.047875 0.093536376953125 0.334503173828125 0.7202575683593749 +0.048 0.09246826171875 0.330596923828125 0.7202575683593749 +0.048125 0.09246826171875 0.330596923828125 0.7202575683593749 +0.04825 0.091339111328125 0.32666015625 0.7202575683593749 +0.048375 0.091339111328125 0.32666015625 0.7202575683593749 +0.0485 0.090240478515625 0.322662353515625 0.7202575683593749 +0.048625 0.089111328125 0.31866455078125 0.7202575683593749 +0.04875 0.089111328125 0.31866455078125 0.7202575683593749 +0.048875 0.087982177734375 0.314605712890625 0.7202575683593749 +0.049 0.087982177734375 0.314605712890625 0.7202575683593749 +0.049125 0.086822509765625 0.310516357421875 0.7202575683593749 +0.04925 0.085693359375 0.306396484375 0.7202575683593749 +0.049375 0.085693359375 0.306396484375 0.7202575683593749 +0.0495 0.08453369140625 0.30224609375 0.7202575683593749 +0.049625 0.08453369140625 0.30224609375 0.7202575683593749 +0.04975 0.083343505859375 0.298065185546875 0.7202575683593749 +0.049875 0.082183837890625 0.2938232421875 0.7202575683593749 +0.05 0.082183837890625 0.2938232421875 0.7202575683593749 +0.050125 0.08099365234375 0.289581298828125 0.7202575683593749 +0.05025 0.08099365234375 0.289581298828125 0.7202575683593749 +0.050375 0.07977294921875 0.285308837890625 0.7202575683593749 +0.0505 0.078582763671875 0.280975341796875 0.7202575683593749 +0.050625 0.078582763671875 0.280975341796875 0.7202575683593749 +0.05075 0.077362060546875 0.276641845703125 0.7202575683593749 +0.0508750000000000064 0.077362060546875 0.276641845703125 0.7202575683593749 +0.0510000000000000064 0.076141357421875 0.27227783203125 0.7202575683593749 +0.0511250000000000064 0.074920654296875 0.267852783203125 0.7202575683593749 +0.0512500000000000064 0.074920654296875 0.267852783203125 0.7202575683593749 +0.0513750000000000064 0.07366943359375 0.263427734375 0.7202575683593749 +0.0515000000000000064 0.07366943359375 0.263427734375 0.7202575683593749 +0.0516250000000000064 0.072418212890625 0.25897216796875 0.7202575683593749 +0.0517500000000000064 0.0711669921875 0.25445556640625 0.7202575683593749 +0.0518750000000000064 0.0711669921875 0.25445556640625 0.7202575683593749 +0.052000000000000008 0.06988525390625 0.249969482421875 0.7202575683593749 +0.052125 0.06988525390625 0.249969482421875 0.7202575683593749 +0.05225 0.068634033203125 0.24542236328125 0.7202575683593749 +0.052375 0.067352294921875 0.2408447265625 0.7202575683593749 +0.0525 0.067352294921875 0.2408447265625 0.7202575683593749 +0.052625 0.066070556640625 0.236236572265625 0.7202575683593749 +0.05275 0.066070556640625 0.236236572265625 0.7202575683593749 +0.052875 0.06475830078125 0.231597900390625 0.7202575683593749 +0.053 0.063446044921875 0.226959228515625 0.7202575683593749 +0.053125 0.063446044921875 0.226959228515625 0.7202575683593749 +0.05325 0.062164306640625 0.2222900390625 0.7202575683593749 +0.053375 0.062164306640625 0.2222900390625 0.7202575683593749 +0.0535 0.06085205078125 0.21759033203125 0.7202575683593749 +0.053625 0.05950927734375 0.212860107421875 0.7202575683593749 +0.05375 0.05950927734375 0.212860107421875 0.7202575683593749 +0.053875 0.058197021484375 0.208099365234375 0.7202575683593749 +0.054 0.058197021484375 0.208099365234375 0.7202575683593749 +0.054125 0.056854248046875 0.203338623046875 0.7202575683593749 +0.05425 0.055511474609375 0.19854736328125 0.7202575683593749 +0.054375 0.055511474609375 0.19854736328125 0.7202575683593749 +0.0545 0.054168701171875 0.1937255859375 0.7202575683593749 +0.054625 0.054168701171875 0.1937255859375 0.7202575683593749 +0.05475 0.052825927734375 0.188873291015625 0.7202575683593749 +0.054875 0.05145263671875 0.18402099609375 0.7202575683593749 +0.055 0.05145263671875 0.18402099609375 0.7202575683593749 +0.055125 0.050079345703125 0.17913818359375 0.7202575683593749 +0.05525 0.050079345703125 0.17913818359375 0.7202575683593749 +0.055375 0.048736572265625 0.17425537109375 0.7202575683593749 +0.0555 0.047332763671875 0.169342041015625 0.7202575683593749 +0.055625 0.047332763671875 0.169342041015625 0.7202575683593749 +0.05575 0.04595947265625 0.164398193359375 0.7202575683593749 +0.055875 0.04595947265625 0.164398193359375 0.7202575683593749 +0.056 0.044586181640625 0.159454345703125 0.7202575683593749 +0.056125 0.043182373046875 0.15447998046875 0.7202575683593749 +0.05625 0.043182373046875 0.15447998046875 0.7202575683593749 +0.056375 0.04180908203125 0.14947509765625 0.7202575683593749 +0.0565 0.04180908203125 0.14947509765625 0.7202575683593749 +0.056625 0.0404052734375 0.14447021484375 0.7202575683593749 +0.05675 0.03900146484375 0.13946533203125 0.7202575683593749 +0.056875 0.03900146484375 0.13946533203125 0.7202575683593749 +0.057 0.03759765625 0.134429931640625 0.7202575683593749 +0.057125 0.03759765625 0.134429931640625 0.7202575683593749 +0.05725 0.036163330078125 0.129364013671875 0.7202575683593749 +0.057375 0.034759521484375 0.124298095703125 0.7202575683593749 +0.0575 0.034759521484375 0.124298095703125 0.7202575683593749 +0.057625 0.0333251953125 0.119232177734375 0.7202575683593749 +0.05775 0.0333251953125 0.119232177734375 0.7202575683593749 +0.057875 0.03192138671875 0.1141357421875 0.7202575683593749 +0.058 0.030487060546875 0.109039306640625 0.7202575683593749 +0.058125 0.030487060546875 0.109039306640625 0.7202575683593749 +0.05825 0.029052734375 0.103912353515625 0.7202575683593749 +0.058375 0.029052734375 0.103912353515625 0.7202575683593749 +0.0585 0.027618408203125 0.098785400390625 0.7202575683593749 +0.0586250000000000064 0.02618408203125 0.093658447265625 0.7202575683593749 +0.0587500000000000064 0.02618408203125 0.093658447265625 0.7202575683593749 +0.0588750000000000064 0.024749755859375 0.0885009765625 0.7202575683593749 +0.0590000000000000064 0.024749755859375 0.0885009765625 0.7202575683593749 +0.0591250000000000064 0.0233154296875 0.083343505859375 0.7202575683593749 +0.0592500000000000052 0.0218505859375 0.07818603515625 0.7202575683593749 +0.0593750000000000052 0.0218505859375 0.07818603515625 0.7202575683593749 +0.0595000000000000052 0.020416259765625 0.072998046875 0.7202575683593749 +0.0596250000000000052 0.020416259765625 0.072998046875 0.7202575683593749 +0.0597500000000000052 0.018951416015625 0.06781005859375 0.7202575683593749 +0.059875000000000008 0.01751708984375 0.0626220703125 0.7202575683593749 +0.06 0.01751708984375 0.0626220703125 0.7202575683593749 +0.060125 0.01605224609375 0.05743408203125 0.7202575683593749 +0.06025 0.01605224609375 0.05743408203125 0.7202575683593749 +0.060375 0.01458740234375 0.05224609375 0.7202575683593749 +0.0605 0.013153076171875 0.047027587890625 0.7202575683593749 +0.060625 0.013153076171875 0.047027587890625 0.7202575683593749 +0.06075 0.011688232421875 0.04180908203125 0.7202575683593749 +0.060875 0.011688232421875 0.04180908203125 0.7202575683593749 +0.061 0.010223388671875 0.036590576171875 0.7202575683593749 +0.061125 0.008758544921875 0.0313720703125 0.7202575683593749 +0.06125 0.008758544921875 0.0313720703125 0.7202575683593749 +0.061375 0.007293701171875 0.026123046875 0.7202575683593749 +0.0615 0.007293701171875 0.026123046875 0.7202575683593749 +0.061625 0.005828857421875 0.020904541015625 0.7202575683593749 +0.06175 0.004364013671875 0.01568603515625 0.7202575683593749 +0.061875 0.004364013671875 0.01568603515625 0.7202575683593749 +0.062 0.002899169921875 0.01043701171875 0.7202575683593749 +0.062125 0.002899169921875 0.01043701171875 0.7202575683593749 +0.06225 0.001434326171875 0.005218505859375 0.7202575683593749 +0.062375 0.0 0.0 0.7202575683593749 +0.0625 0.0 0.0 0.7202575683593749 +0.062625 -0.001434326171875 -0.005218505859375 0.7202575683593749 +0.06275 -0.001434326171875 -0.005218505859375 0.7202575683593749 +0.062875 -0.002899169921875 -0.01043701171875 0.7202575683593749 +0.063 -0.004364013671875 -0.01568603515625 0.7202575683593749 +0.063125 -0.004364013671875 -0.01568603515625 0.7202575683593749 +0.06325 -0.005828857421875 -0.020904541015625 0.7202575683593749 +0.063375 -0.005828857421875 -0.020904541015625 0.7202575683593749 +0.0635 -0.007293701171875 -0.026123046875 0.7202575683593749 +0.063625 -0.008758544921875 -0.0313720703125 0.7202575683593749 +0.06375 -0.008758544921875 -0.0313720703125 0.7202575683593749 +0.063875 -0.010223388671875 -0.036590576171875 0.7202575683593749 +0.064 -0.00238037109375 -0.036590576171875 0.934271240234375 +0.064125 -0.002716064453125 -0.04180908203125 0.934271240234375 +0.06425 -0.003082275390625 -0.047027587890625 0.934271240234375 +0.064375 -0.003082275390625 -0.047027587890625 0.934271240234375 +0.0645 -0.00341796875 -0.05224609375 0.934271240234375 +0.064625 -0.00341796875 -0.05224609375 0.934271240234375 +0.06475 -0.003753662109375 -0.05743408203125 0.934271240234375 +0.064875 -0.00408935546875 -0.0626220703125 0.934271240234375 +0.065 -0.00408935546875 -0.0626220703125 0.934271240234375 +0.065125 -0.004425048828125 -0.06781005859375 0.934271240234375 +0.06525 -0.004425048828125 -0.06781005859375 0.934271240234375 +0.065375 -0.004791259765625 -0.072998046875 0.934271240234375 +0.0655 -0.005126953125 -0.07818603515625 0.934271240234375 +0.065625 -0.005126953125 -0.07818603515625 0.934271240234375 +0.06575 -0.005462646484375 -0.083343505859375 0.934271240234375 +0.065875 -0.005462646484375 -0.083343505859375 0.934271240234375 +0.066 -0.00579833984375 -0.0885009765625 0.934271240234375 +0.066125 -0.006134033203125 -0.093658447265625 0.934271240234375 +0.06625 -0.006134033203125 -0.093658447265625 0.934271240234375 +0.066375 -0.0064697265625 -0.098785400390625 0.934271240234375 +0.0665 -0.0064697265625 -0.098785400390625 0.934271240234375 +0.066625 -0.006805419921875 -0.103912353515625 0.934271240234375 +0.06675 -0.00714111328125 -0.109039306640625 0.934271240234375 +0.066875 -0.00714111328125 -0.109039306640625 0.934271240234375 +0.067 -0.007476806640625 -0.1141357421875 0.934271240234375 +0.067125 -0.007476806640625 -0.1141357421875 0.934271240234375 +0.06725 -0.0078125 -0.119232177734375 0.934271240234375 +0.067375 -0.008148193359375 -0.124298095703125 0.934271240234375 +0.0675 -0.008148193359375 -0.124298095703125 0.934271240234375 +0.067625 -0.00848388671875 -0.129364013671875 0.934271240234375 +0.06775 -0.00848388671875 -0.129364013671875 0.934271240234375 +0.067875 -0.008819580078125 -0.134429931640625 0.934271240234375 +0.068 -0.0091552734375 -0.13946533203125 0.934271240234375 +0.068125 -0.0091552734375 -0.13946533203125 0.934271240234375 +0.06825000000000001 -0.00946044921875 -0.14447021484375 0.934271240234375 +0.06837500000000001 -0.00946044921875 -0.14447021484375 0.934271240234375 +0.06850000000000001 -0.009796142578125 -0.14947509765625 0.934271240234375 +0.06862500000000001 -0.0101318359375 -0.15447998046875 0.934271240234375 +0.06875000000000001 -0.0101318359375 -0.15447998046875 0.934271240234375 +0.06887500000000001 -0.010467529296875 -0.159454345703125 0.934271240234375 +0.06900000000000001 -0.010467529296875 -0.159454345703125 0.934271240234375 +0.06912500000000001 -0.010772705078125 -0.164398193359375 0.934271240234375 +0.06925000000000001 -0.0111083984375 -0.169342041015625 0.934271240234375 +0.06937500000000001 -0.0111083984375 -0.169342041015625 0.934271240234375 +0.06950000000000001 -0.01141357421875 -0.17425537109375 0.934271240234375 +0.06962500000000001 -0.01141357421875 -0.17425537109375 0.934271240234375 +0.06975000000000001 -0.011749267578125 -0.17913818359375 0.934271240234375 +0.06987500000000001 -0.012054443359375 -0.18402099609375 0.934271240234375 +0.07000000000000001 -0.012054443359375 -0.18402099609375 0.934271240234375 +0.07012500000000001 -0.01239013671875 -0.188873291015625 0.934271240234375 +0.07025000000000001 -0.01239013671875 -0.188873291015625 0.934271240234375 +0.07037500000000001 -0.0126953125 -0.1937255859375 0.934271240234375 +0.07050000000000001 -0.013031005859375 -0.19854736328125 0.934271240234375 +0.07062500000000001 -0.013031005859375 -0.19854736328125 0.934271240234375 +0.07075000000000001 -0.013336181640625 -0.203338623046875 0.934271240234375 +0.07087500000000001 -0.013336181640625 -0.203338623046875 0.934271240234375 +0.07100000000000001 -0.013641357421875 -0.208099365234375 0.934271240234375 +0.07112500000000001 -0.013946533203125 -0.212860107421875 0.934271240234375 +0.07125000000000001 -0.013946533203125 -0.212860107421875 0.934271240234375 +0.07137500000000001 -0.0142822265625 -0.21759033203125 0.934271240234375 +0.07150000000000001 -0.0142822265625 -0.21759033203125 0.934271240234375 +0.07162500000000001 -0.01458740234375 -0.2222900390625 0.934271240234375 +0.07175000000000001 -0.014892578125 -0.226959228515625 0.934271240234375 +0.07187500000000001 -0.014892578125 -0.226959228515625 0.934271240234375 +0.07200000000000001 -0.01519775390625 -0.231597900390625 0.934271240234375 +0.072125 -0.01519775390625 -0.231597900390625 0.934271240234375 +0.07225 -0.0155029296875 -0.236236572265625 0.934271240234375 +0.072375 -0.01580810546875 -0.2408447265625 0.934271240234375 +0.0725 -0.01580810546875 -0.2408447265625 0.934271240234375 +0.072625 -0.016082763671875 -0.24542236328125 0.934271240234375 +0.07275 -0.016082763671875 -0.24542236328125 0.934271240234375 +0.072875 -0.016387939453125 -0.249969482421875 0.934271240234375 +0.073 -0.016693115234375 -0.25445556640625 0.934271240234375 +0.073125 -0.016693115234375 -0.25445556640625 0.934271240234375 +0.07325 -0.016998291015625 -0.25897216796875 0.934271240234375 +0.073375 -0.016998291015625 -0.25897216796875 0.934271240234375 +0.0735 -0.01727294921875 -0.263427734375 0.934271240234375 +0.073625 -0.017578125 -0.267852783203125 0.934271240234375 +0.07375 -0.017578125 -0.267852783203125 0.934271240234375 +0.073875 -0.017852783203125 -0.27227783203125 0.934271240234375 +0.074 -0.017852783203125 -0.27227783203125 0.934271240234375 +0.074125 -0.018157958984375 -0.276641845703125 0.934271240234375 +0.07425 -0.0184326171875 -0.280975341796875 0.934271240234375 +0.074375 -0.0184326171875 -0.280975341796875 0.934271240234375 +0.0745 -0.018707275390625 -0.285308837890625 0.934271240234375 +0.074625 -0.018707275390625 -0.285308837890625 0.934271240234375 +0.07475 -0.01898193359375 -0.289581298828125 0.934271240234375 +0.074875 -0.019287109375 -0.2938232421875 0.934271240234375 +0.075 -0.019287109375 -0.2938232421875 0.934271240234375 +0.075125 -0.019561767578125 -0.298065185546875 0.934271240234375 +0.07525 -0.019561767578125 -0.298065185546875 0.934271240234375 +0.075375 -0.01983642578125 -0.30224609375 0.934271240234375 +0.0755 -0.020111083984375 -0.306396484375 0.934271240234375 +0.075625 -0.020111083984375 -0.306396484375 0.934271240234375 +0.07575 -0.0203857421875 -0.310516357421875 0.934271240234375 +0.075875 -0.0203857421875 -0.310516357421875 0.934271240234375 +0.076 -0.0206298828125 -0.314605712890625 0.934271240234375 +0.076125 -0.020904541015625 -0.31866455078125 0.934271240234375 +0.07625 -0.020904541015625 -0.31866455078125 0.934271240234375 +0.076375 -0.02117919921875 -0.322662353515625 0.934271240234375 +0.0765 -0.02117919921875 -0.322662353515625 0.934271240234375 +0.076625 -0.02142333984375 -0.32666015625 0.934271240234375 +0.07675 -0.021697998046875 -0.330596923828125 0.934271240234375 +0.076875 -0.021697998046875 -0.330596923828125 0.934271240234375 +0.077 -0.021942138671875 -0.334503173828125 0.934271240234375 +0.077125 -0.021942138671875 -0.334503173828125 0.934271240234375 +0.07725 -0.022186279296875 -0.33837890625 0.934271240234375 +0.077375 -0.0224609375 -0.34222412109375 0.934271240234375 +0.0775 -0.0224609375 -0.34222412109375 0.934271240234375 +0.077625 -0.022705078125 -0.34600830078125 0.934271240234375 +0.07775 -0.022705078125 -0.34600830078125 0.934271240234375 +0.077875 -0.02294921875 -0.349761962890625 0.934271240234375 +0.078 -0.023193359375 -0.353485107421875 0.934271240234375 +0.078125 -0.023193359375 -0.353485107421875 0.934271240234375 +0.07825 -0.0234375 -0.357177734375 0.934271240234375 +0.078375 -0.0234375 -0.357177734375 0.934271240234375 +0.0785 -0.023681640625 -0.360809326171875 0.934271240234375 +0.078625 -0.023895263671875 -0.36444091796875 0.934271240234375 +0.07875 -0.023895263671875 -0.36444091796875 0.934271240234375 +0.078875 -0.024139404296875 -0.36798095703125 0.934271240234375 +0.079 -0.024139404296875 -0.36798095703125 0.934271240234375 +0.079125 -0.024383544921875 -0.37152099609375 0.934271240234375 +0.07925 -0.02459716796875 -0.375 0.934271240234375 +0.079375 -0.02459716796875 -0.375 0.934271240234375 +0.0795 -0.02484130859375 -0.378448486328125 0.934271240234375 +0.079625 -0.02484130859375 -0.378448486328125 0.934271240234375 +0.07975 -0.025054931640625 -0.3818359375 0.934271240234375 +0.079875 -0.0252685546875 -0.38519287109375 0.934271240234375 +0.08 -0.0252685546875 -0.38519287109375 0.934271240234375 +0.080125 -0.025482177734375 -0.388519287109375 0.934271240234375 +0.08025 -0.025482177734375 -0.388519287109375 0.934271240234375 +0.080375 -0.02569580078125 -0.39178466796875 0.934271240234375 +0.0805 -0.025909423828125 -0.39501953125 0.934271240234375 +0.080625 -0.025909423828125 -0.39501953125 0.934271240234375 +0.08075 -0.026123046875 -0.398193359375 0.934271240234375 +0.080875 -0.026123046875 -0.398193359375 0.934271240234375 +0.081 -0.026336669921875 -0.401336669921875 0.934271240234375 +0.081125 -0.02655029296875 -0.404449462890625 0.934271240234375 +0.08125 -0.02655029296875 -0.404449462890625 0.934271240234375 +0.081375 -0.0267333984375 -0.407501220703125 0.934271240234375 +0.0815 -0.0267333984375 -0.407501220703125 0.934271240234375 +0.081625 -0.026947021484375 -0.4105224609375 0.934271240234375 +0.08175 -0.027130126953125 -0.413482666015625 0.934271240234375 +0.081875 -0.027130126953125 -0.413482666015625 0.934271240234375 +0.082 -0.027313232421875 -0.416412353515625 0.934271240234375 +0.082125 -0.027313232421875 -0.416412353515625 0.934271240234375 +0.08225 -0.027496337890625 -0.419281005859375 0.934271240234375 +0.082375 -0.0277099609375 -0.422119140625 0.934271240234375 +0.0825 -0.0277099609375 -0.422119140625 0.934271240234375 +0.082625 -0.02789306640625 -0.424896240234375 0.934271240234375 +0.08275 -0.02789306640625 -0.424896240234375 0.934271240234375 +0.082875 -0.028045654296875 -0.4276123046875 0.934271240234375 +0.083 -0.028228759765625 -0.4302978515625 0.934271240234375 +0.083125 -0.028228759765625 -0.4302978515625 0.934271240234375 +0.08325 -0.028411865234375 -0.432952880859375 0.934271240234375 +0.083375 -0.028411865234375 -0.432952880859375 0.934271240234375 +0.0835 -0.028564453125 -0.435546875 0.934271240234375 +0.083625 -0.02874755859375 -0.438079833984375 0.934271240234375 +0.08375 -0.02874755859375 -0.438079833984375 0.934271240234375 +0.08387500000000001 -0.028900146484375 -0.440582275390625 0.934271240234375 +0.08400000000000001 -0.028900146484375 -0.440582275390625 0.934271240234375 +0.08412500000000001 -0.029083251953125 -0.44305419921875 0.934271240234375 +0.08425000000000001 -0.02923583984375 -0.4454345703125 0.934271240234375 +0.08437500000000001 -0.02923583984375 -0.4454345703125 0.934271240234375 +0.08450000000000001 -0.029388427734375 -0.447784423828125 0.934271240234375 +0.08462500000000001 -0.029388427734375 -0.447784423828125 0.934271240234375 +0.08475000000000001 -0.029541015625 -0.450103759765625 0.934271240234375 +0.08487500000000001 -0.029693603515625 -0.452362060546875 0.934271240234375 +0.08500000000000001 -0.029693603515625 -0.452362060546875 0.934271240234375 +0.08512500000000001 -0.029815673828125 -0.454559326171875 0.934271240234375 +0.08525000000000001 -0.029815673828125 -0.454559326171875 0.934271240234375 +0.08537500000000001 -0.02996826171875 -0.45672607421875 0.934271240234375 +0.08550000000000001 -0.030120849609375 -0.458831787109375 0.934271240234375 +0.08562500000000001 -0.030120849609375 -0.458831787109375 0.934271240234375 +0.08575000000000001 -0.030242919921875 -0.46087646484375 0.934271240234375 +0.08587500000000001 -0.030242919921875 -0.46087646484375 0.934271240234375 +0.08600000000000001 -0.030364990234375 -0.462890625 0.934271240234375 +0.08612500000000001 -0.030487060546875 -0.464813232421875 0.934271240234375 +0.08625000000000001 -0.030487060546875 -0.464813232421875 0.934271240234375 +0.08637500000000001 -0.0306396484375 -0.46673583984375 0.934271240234375 +0.08650000000000001 -0.0306396484375 -0.46673583984375 0.934271240234375 +0.08662500000000001 -0.030731201171875 -0.46856689453125 0.934271240234375 +0.08675000000000001 -0.030853271484375 -0.470367431640625 0.934271240234375 +0.08687500000000001 -0.030853271484375 -0.470367431640625 0.934271240234375 +0.08700000000000001 -0.030975341796875 -0.472137451171875 0.934271240234375 +0.08712500000000001 -0.030975341796875 -0.472137451171875 0.934271240234375 +0.08725000000000001 -0.031097412109375 -0.47381591796875 0.934271240234375 +0.08737500000000001 -0.03118896484375 -0.4754638671875 0.934271240234375 +0.08750000000000001 -0.03118896484375 -0.4754638671875 0.934271240234375 +0.08762500000000001 -0.03131103515625 -0.47705078125 0.934271240234375 +0.08775000000000001 -0.03131103515625 -0.47705078125 0.934271240234375 +0.08787500000000001 -0.031402587890625 -0.478607177734375 0.934271240234375 +0.088 -0.031494140625 -0.480072021484375 0.934271240234375 +0.088125 -0.031494140625 -0.480072021484375 0.934271240234375 +0.08825 -0.031585693359375 -0.48150634765625 0.934271240234375 +0.088375 -0.031585693359375 -0.48150634765625 0.934271240234375 +0.0885 -0.03167724609375 -0.48291015625 0.934271240234375 +0.088625 -0.031768798828125 -0.484222412109375 0.934271240234375 +0.08875 -0.031768798828125 -0.484222412109375 0.934271240234375 +0.088875 -0.0318603515625 -0.485504150390625 0.934271240234375 +0.089 -0.0318603515625 -0.485504150390625 0.934271240234375 +0.089125 -0.031951904296875 -0.486724853515625 0.934271240234375 +0.08925 -0.032012939453125 -0.487884521484375 0.934271240234375 +0.089375 -0.032012939453125 -0.487884521484375 0.934271240234375 +0.0895 -0.032073974609375 -0.489013671875 0.934271240234375 +0.089625 -0.032073974609375 -0.489013671875 0.934271240234375 +0.08975 -0.03216552734375 -0.490081787109375 0.934271240234375 +0.089875 -0.0322265625 -0.4910888671875 0.934271240234375 +0.09 -0.0322265625 -0.4910888671875 0.934271240234375 +0.090125 -0.03228759765625 -0.492034912109375 0.934271240234375 +0.09025 -0.03228759765625 -0.492034912109375 0.934271240234375 +0.090375 -0.0323486328125 -0.492950439453125 0.934271240234375 +0.0905 -0.03240966796875 -0.4937744140625 0.934271240234375 +0.090625 -0.03240966796875 -0.4937744140625 0.934271240234375 +0.09075 -0.032440185546875 -0.49456787109375 0.934271240234375 +0.090875 -0.032440185546875 -0.49456787109375 0.934271240234375 +0.091 -0.032501220703125 -0.49530029296875 0.934271240234375 +0.091125 -0.03253173828125 -0.496002197265625 0.934271240234375 +0.09125 -0.03253173828125 -0.496002197265625 0.934271240234375 +0.091375 -0.0325927734375 -0.496612548828125 0.934271240234375 +0.0915 -0.0325927734375 -0.496612548828125 0.934271240234375 +0.091625 -0.032623291015625 -0.4971923828125 0.934271240234375 +0.09175 -0.03265380859375 -0.497711181640625 0.934271240234375 +0.091875 -0.03265380859375 -0.497711181640625 0.934271240234375 +0.092 -0.032684326171875 -0.498199462890625 0.934271240234375 +0.092125 -0.032684326171875 -0.498199462890625 0.934271240234375 +0.09225 -0.03271484375 -0.49859619140625 0.934271240234375 +0.092375 -0.032745361328125 -0.49896240234375 0.934271240234375 +0.0925 -0.032745361328125 -0.49896240234375 0.934271240234375 +0.092625 -0.032745361328125 -0.499267578125 0.934271240234375 +0.09275 -0.032745361328125 -0.499267578125 0.934271240234375 +0.092875 -0.03277587890625 -0.49951171875 0.934271240234375 +0.093 -0.03277587890625 -0.49969482421875 0.934271240234375 +0.093125 -0.03277587890625 -0.49969482421875 0.934271240234375 +0.09325 -0.032806396484375 -0.49981689453125 0.934271240234375 +0.093375 -0.032806396484375 -0.49981689453125 0.934271240234375 +0.0935 -0.032806396484375 -0.499908447265625 0.934271240234375 +0.093625 -0.032806396484375 -0.49993896484375 0.934271240234375 +0.09375 -0.032806396484375 -0.49993896484375 0.934271240234375 +0.093875 -0.032806396484375 -0.499908447265625 0.934271240234375 +0.094 -0.032806396484375 -0.499908447265625 0.934271240234375 +0.094125 -0.032806396484375 -0.49981689453125 0.934271240234375 +0.09425 -0.03277587890625 -0.49969482421875 0.934271240234375 +0.094375 -0.03277587890625 -0.49969482421875 0.934271240234375 +0.0945 -0.03277587890625 -0.49951171875 0.934271240234375 +0.094625 -0.03277587890625 -0.49951171875 0.934271240234375 +0.09475 -0.032745361328125 -0.499267578125 0.934271240234375 +0.094875 -0.032745361328125 -0.49896240234375 0.934271240234375 +0.095 -0.032745361328125 -0.49896240234375 0.934271240234375 +0.095125 -0.03271484375 -0.49859619140625 0.934271240234375 +0.09525 -0.03271484375 -0.49859619140625 0.934271240234375 +0.095375 -0.032684326171875 -0.498199462890625 0.934271240234375 +0.0955 -0.03265380859375 -0.497711181640625 0.934271240234375 +0.095625 -0.03265380859375 -0.497711181640625 0.934271240234375 +0.09575 -0.032623291015625 -0.4971923828125 0.934271240234375 +0.095875 -0.032623291015625 -0.4971923828125 0.934271240234375 +0.096 -0.00030517578125 -0.496612548828125 0.99923095703125 +0.096125 -0.00030517578125 -0.496002197265625 0.99923095703125 +0.09625 -0.00030517578125 -0.496002197265625 0.99923095703125 +0.096375 -0.00030517578125 -0.49530029296875 0.99923095703125 +0.0965 -0.00030517578125 -0.49530029296875 0.99923095703125 +0.096625 -0.00030517578125 -0.49456787109375 0.99923095703125 +0.09675 -0.00030517578125 -0.4937744140625 0.99923095703125 +0.096875 -0.00030517578125 -0.4937744140625 0.99923095703125 +0.097 -0.00030517578125 -0.492950439453125 0.99923095703125 +0.097125 -0.00030517578125 -0.492950439453125 0.99923095703125 +0.09725 -0.00030517578125 -0.492034912109375 0.99923095703125 +0.097375 -0.00030517578125 -0.4910888671875 0.99923095703125 +0.0975 -0.00030517578125 -0.4910888671875 0.99923095703125 +0.097625 -0.00030517578125 -0.490081787109375 0.99923095703125 +0.09775 -0.00030517578125 -0.490081787109375 0.99923095703125 +0.097875 -0.00030517578125 -0.489013671875 0.99923095703125 +0.098 -0.00030517578125 -0.487884521484375 0.99923095703125 +0.098125 -0.00030517578125 -0.487884521484375 0.99923095703125 +0.09825 -0.00030517578125 -0.486724853515625 0.99923095703125 +0.098375 -0.00030517578125 -0.486724853515625 0.99923095703125 +0.0985 -0.00030517578125 -0.485504150390625 0.99923095703125 +0.098625 -0.00030517578125 -0.484222412109375 0.99923095703125 +0.09875 -0.00030517578125 -0.484222412109375 0.99923095703125 +0.098875 -0.00030517578125 -0.48291015625 0.99923095703125 +0.099 -0.00030517578125 -0.48291015625 0.99923095703125 +0.099125 -0.00030517578125 -0.48150634765625 0.99923095703125 +0.09925 -0.00030517578125 -0.480072021484375 0.99923095703125 +0.099375 -0.00030517578125 -0.480072021484375 0.99923095703125 +0.0995 -0.00030517578125 -0.478607177734375 0.99923095703125 +0.099625 -0.00030517578125 -0.478607177734375 0.99923095703125 +0.09975 -0.00030517578125 -0.47705078125 0.99923095703125 +0.099875 -0.00030517578125 -0.4754638671875 0.99923095703125 +0.1 -0.00030517578125 -0.4754638671875 0.99923095703125 +0.100125 -0.00030517578125 -0.47381591796875 0.99923095703125 +0.10025 -0.00030517578125 -0.47381591796875 0.99923095703125 +0.100375 -0.00030517578125 -0.472137451171875 0.99923095703125 +0.1005 -0.00030517578125 -0.470367431640625 0.99923095703125 +0.100625 -0.00030517578125 -0.470367431640625 0.99923095703125 +0.10075 -0.00030517578125 -0.46856689453125 0.99923095703125 +0.100875 -0.00030517578125 -0.46856689453125 0.99923095703125 +0.101 -0.00030517578125 -0.46673583984375 0.99923095703125 +0.101125 -0.00030517578125 -0.464813232421875 0.99923095703125 +0.10125 -0.00030517578125 -0.464813232421875 0.99923095703125 +0.101375 -0.00030517578125 -0.462890625 0.99923095703125 +0.1015 -0.00030517578125 -0.462890625 0.99923095703125 +0.1016250000000000128 -0.00030517578125 -0.46087646484375 0.99923095703125 +0.1017500000000000128 -0.00030517578125 -0.458831787109375 0.99923095703125 +0.1018750000000000128 -0.00030517578125 -0.458831787109375 0.99923095703125 +0.1020000000000000128 -0.00030517578125 -0.45672607421875 0.99923095703125 +0.1021250000000000128 -0.00030517578125 -0.45672607421875 0.99923095703125 +0.1022500000000000128 -0.00030517578125 -0.454559326171875 0.99923095703125 +0.1023750000000000128 -0.000274658203125 -0.452362060546875 0.99923095703125 +0.1025000000000000128 -0.000274658203125 -0.452362060546875 0.99923095703125 +0.1026250000000000128 -0.000274658203125 -0.450103759765625 0.99923095703125 +0.1027500000000000128 -0.000274658203125 -0.450103759765625 0.99923095703125 +0.1028750000000000128 -0.000274658203125 -0.447784423828125 0.99923095703125 +0.1030000000000000128 -0.000274658203125 -0.4454345703125 0.99923095703125 +0.1031250000000000128 -0.000274658203125 -0.4454345703125 0.99923095703125 +0.1032500000000000128 -0.000274658203125 -0.44305419921875 0.99923095703125 +0.1033750000000000128 -0.000274658203125 -0.44305419921875 0.99923095703125 +0.1035000000000000128 -0.000274658203125 -0.440582275390625 0.99923095703125 +0.1036250000000000128 -0.000274658203125 -0.438079833984375 0.99923095703125 +0.1037500000000000128 -0.000274658203125 -0.438079833984375 0.99923095703125 +0.1038750000000000128 -0.000274658203125 -0.435546875 0.99923095703125 +0.104000000000000016 -0.000274658203125 -0.435546875 0.99923095703125 +0.104125 -0.000274658203125 -0.432952880859375 0.99923095703125 +0.10425 -0.000274658203125 -0.4302978515625 0.99923095703125 +0.104375 -0.000274658203125 -0.4302978515625 0.99923095703125 +0.1045 -0.000274658203125 -0.4276123046875 0.99923095703125 +0.104625 -0.000274658203125 -0.4276123046875 0.99923095703125 +0.10475 -0.000274658203125 -0.424896240234375 0.99923095703125 +0.104875 -0.000274658203125 -0.422119140625 0.99923095703125 +0.105 -0.000274658203125 -0.422119140625 0.99923095703125 +0.105125 -0.000274658203125 -0.419281005859375 0.99923095703125 +0.10525 -0.000274658203125 -0.419281005859375 0.99923095703125 +0.105375 -0.000274658203125 -0.416412353515625 0.99923095703125 +0.1055 -0.000274658203125 -0.413482666015625 0.99923095703125 +0.105625 -0.000274658203125 -0.413482666015625 0.99923095703125 +0.10575 -0.000274658203125 -0.4105224609375 0.99923095703125 +0.105875 -0.000274658203125 -0.4105224609375 0.99923095703125 +0.106 -0.000244140625 -0.407501220703125 0.99923095703125 +0.106125 -0.000244140625 -0.404449462890625 0.99923095703125 +0.10625 -0.000244140625 -0.404449462890625 0.99923095703125 +0.106375 -0.000244140625 -0.401336669921875 0.99923095703125 +0.1065 -0.000244140625 -0.401336669921875 0.99923095703125 +0.106625 -0.000244140625 -0.398193359375 0.99923095703125 +0.10675 -0.000244140625 -0.39501953125 0.99923095703125 +0.106875 -0.000244140625 -0.39501953125 0.99923095703125 +0.107 -0.000244140625 -0.39178466796875 0.99923095703125 +0.107125 -0.000244140625 -0.39178466796875 0.99923095703125 +0.10725 -0.000244140625 -0.388519287109375 0.99923095703125 +0.107375 -0.000244140625 -0.38519287109375 0.99923095703125 +0.1075 -0.000244140625 -0.38519287109375 0.99923095703125 +0.107625 -0.000244140625 -0.3818359375 0.99923095703125 +0.10775 -0.000244140625 -0.3818359375 0.99923095703125 +0.107875 -0.000244140625 -0.378448486328125 0.99923095703125 +0.108 -0.000244140625 -0.375 0.99923095703125 +0.108125 -0.000244140625 -0.375 0.99923095703125 +0.10825 -0.000244140625 -0.37152099609375 0.99923095703125 +0.108375 -0.000244140625 -0.37152099609375 0.99923095703125 +0.1085 -0.000244140625 -0.36798095703125 0.99923095703125 +0.108625 -0.000244140625 -0.36444091796875 0.99923095703125 +0.10875 -0.000244140625 -0.36444091796875 0.99923095703125 +0.108875 -0.000213623046875 -0.360809326171875 0.99923095703125 +0.109 -0.000213623046875 -0.360809326171875 0.99923095703125 +0.109125 -0.000213623046875 -0.357177734375 0.99923095703125 +0.10925 -0.000213623046875 -0.353485107421875 0.99923095703125 +0.109375 -0.000213623046875 -0.353485107421875 0.99923095703125 +0.1095 -0.000213623046875 -0.349761962890625 0.99923095703125 +0.109625 -0.000213623046875 -0.349761962890625 0.99923095703125 +0.10975 -0.000213623046875 -0.34600830078125 0.99923095703125 +0.109875 -0.000213623046875 -0.34222412109375 0.99923095703125 +0.11 -0.000213623046875 -0.34222412109375 0.99923095703125 +0.110125 -0.000213623046875 -0.33837890625 0.99923095703125 +0.11025 -0.000213623046875 -0.33837890625 0.99923095703125 +0.110375 -0.000213623046875 -0.334503173828125 0.99923095703125 +0.1105 -0.000213623046875 -0.330596923828125 0.99923095703125 +0.110625 -0.000213623046875 -0.330596923828125 0.99923095703125 +0.11075 -0.000213623046875 -0.32666015625 0.99923095703125 +0.110875 -0.000213623046875 -0.32666015625 0.99923095703125 +0.111 -0.000213623046875 -0.322662353515625 0.99923095703125 +0.111125 -0.000213623046875 -0.31866455078125 0.99923095703125 +0.11125 -0.000213623046875 -0.31866455078125 0.99923095703125 +0.111375 -0.00018310546875 -0.314605712890625 0.99923095703125 +0.1115 -0.00018310546875 -0.314605712890625 0.99923095703125 +0.111625 -0.00018310546875 -0.310516357421875 0.99923095703125 +0.11175 -0.00018310546875 -0.306396484375 0.99923095703125 +0.111875 -0.00018310546875 -0.306396484375 0.99923095703125 +0.112 -0.00018310546875 -0.30224609375 0.99923095703125 +0.112125 -0.00018310546875 -0.30224609375 0.99923095703125 +0.11225 -0.00018310546875 -0.298065185546875 0.99923095703125 +0.112375 -0.00018310546875 -0.2938232421875 0.99923095703125 +0.1125 -0.00018310546875 -0.2938232421875 0.99923095703125 +0.112625 -0.00018310546875 -0.289581298828125 0.99923095703125 +0.11275 -0.00018310546875 -0.289581298828125 0.99923095703125 +0.112875 -0.00018310546875 -0.285308837890625 0.99923095703125 +0.113 -0.00018310546875 -0.280975341796875 0.99923095703125 +0.113125 -0.00018310546875 -0.280975341796875 0.99923095703125 +0.11325 -0.00018310546875 -0.276641845703125 0.99923095703125 +0.113375 -0.00018310546875 -0.276641845703125 0.99923095703125 +0.1135 -0.000152587890625 -0.27227783203125 0.99923095703125 +0.113625 -0.000152587890625 -0.267852783203125 0.99923095703125 +0.11375 -0.000152587890625 -0.267852783203125 0.99923095703125 +0.113875 -0.000152587890625 -0.263427734375 0.99923095703125 +0.114 -0.000152587890625 -0.263427734375 0.99923095703125 +0.114125 -0.000152587890625 -0.25897216796875 0.99923095703125 +0.11425 -0.000152587890625 -0.25445556640625 0.99923095703125 +0.114375 -0.000152587890625 -0.25445556640625 0.99923095703125 +0.1145 -0.000152587890625 -0.249969482421875 0.99923095703125 +0.114625 -0.000152587890625 -0.249969482421875 0.99923095703125 +0.11475 -0.000152587890625 -0.24542236328125 0.99923095703125 +0.114875 -0.000152587890625 -0.2408447265625 0.99923095703125 +0.115 -0.000152587890625 -0.2408447265625 0.99923095703125 +0.115125 -0.000152587890625 -0.236236572265625 0.99923095703125 +0.11525 -0.000152587890625 -0.236236572265625 0.99923095703125 +0.115375 -0.000152587890625 -0.231597900390625 0.99923095703125 +0.1155 -0.0001220703125 -0.226959228515625 0.99923095703125 +0.115625 -0.0001220703125 -0.226959228515625 0.99923095703125 +0.11575 -0.0001220703125 -0.2222900390625 0.99923095703125 +0.115875 -0.0001220703125 -0.2222900390625 0.99923095703125 +0.116 -0.0001220703125 -0.21759033203125 0.99923095703125 +0.116125 -0.0001220703125 -0.212860107421875 0.99923095703125 +0.11625 -0.0001220703125 -0.212860107421875 0.99923095703125 +0.116375 -0.0001220703125 -0.208099365234375 0.99923095703125 +0.1165 -0.0001220703125 -0.208099365234375 0.99923095703125 +0.116625 -0.0001220703125 -0.203338623046875 0.99923095703125 +0.11675 -0.0001220703125 -0.19854736328125 0.99923095703125 +0.116875 -0.0001220703125 -0.19854736328125 0.99923095703125 +0.117 -0.0001220703125 -0.1937255859375 0.99923095703125 +0.117125 -0.0001220703125 -0.1937255859375 0.99923095703125 +0.117250000000000013 -0.0001220703125 -0.188873291015625 0.99923095703125 +0.117375000000000013 -0.0001220703125 -0.18402099609375 0.99923095703125 +0.117500000000000013 -0.0001220703125 -0.18402099609375 0.99923095703125 +0.117625000000000013 -9.1552734375e-05 -0.17913818359375 0.99923095703125 +0.117750000000000013 -9.1552734375e-05 -0.17913818359375 0.99923095703125 +0.117875000000000013 -9.1552734375e-05 -0.17425537109375 0.99923095703125 +0.118000000000000013 -9.1552734375e-05 -0.169342041015625 0.99923095703125 +0.118125000000000013 -9.1552734375e-05 -0.169342041015625 0.99923095703125 +0.118250000000000013 -9.1552734375e-05 -0.164398193359375 0.99923095703125 +0.118375000000000013 -9.1552734375e-05 -0.164398193359375 0.99923095703125 +0.118500000000000013 -9.1552734375e-05 -0.159454345703125 0.99923095703125 +0.118625000000000013 -9.1552734375e-05 -0.15447998046875 0.99923095703125 +0.118750000000000013 -9.1552734375e-05 -0.15447998046875 0.99923095703125 +0.118875000000000013 -9.1552734375e-05 -0.14947509765625 0.99923095703125 +0.119000000000000013 -9.1552734375e-05 -0.14947509765625 0.99923095703125 +0.119125000000000013 -9.1552734375e-05 -0.14447021484375 0.99923095703125 +0.119250000000000013 -9.1552734375e-05 -0.13946533203125 0.99923095703125 +0.119375000000000013 -9.1552734375e-05 -0.13946533203125 0.99923095703125 +0.119500000000000013 -6.103515625e-05 -0.134429931640625 0.99923095703125 +0.119625000000000016 -6.103515625e-05 -0.134429931640625 0.99923095703125 +0.119750000000000016 -6.103515625e-05 -0.129364013671875 0.99923095703125 +0.119875000000000016 -6.103515625e-05 -0.124298095703125 0.99923095703125 +0.12 -6.103515625e-05 -0.124298095703125 0.99923095703125 +0.120125 -6.103515625e-05 -0.119232177734375 0.99923095703125 +0.12025 -6.103515625e-05 -0.119232177734375 0.99923095703125 +0.120375 -6.103515625e-05 -0.1141357421875 0.99923095703125 +0.1205 -6.103515625e-05 -0.109039306640625 0.99923095703125 +0.120625 -6.103515625e-05 -0.109039306640625 0.99923095703125 +0.12075 -6.103515625e-05 -0.103912353515625 0.99923095703125 +0.120875 -6.103515625e-05 -0.103912353515625 0.99923095703125 +0.121 -6.103515625e-05 -0.098785400390625 0.99923095703125 +0.121125 -6.103515625e-05 -0.093658447265625 0.99923095703125 +0.12125 -6.103515625e-05 -0.093658447265625 0.99923095703125 +0.121375 -3.0517578125e-05 -0.0885009765625 0.99923095703125 +0.1215 -3.0517578125e-05 -0.0885009765625 0.99923095703125 +0.121625 -3.0517578125e-05 -0.083343505859375 0.99923095703125 +0.12175 -3.0517578125e-05 -0.07818603515625 0.99923095703125 +0.121875 -3.0517578125e-05 -0.07818603515625 0.99923095703125 +0.122 -3.0517578125e-05 -0.072998046875 0.99923095703125 +0.122125 -3.0517578125e-05 -0.072998046875 0.99923095703125 +0.12225 -3.0517578125e-05 -0.06781005859375 0.99923095703125 +0.122375 -3.0517578125e-05 -0.0626220703125 0.99923095703125 +0.1225 -3.0517578125e-05 -0.0626220703125 0.99923095703125 +0.122625 -3.0517578125e-05 -0.05743408203125 0.99923095703125 +0.12275 -3.0517578125e-05 -0.05743408203125 0.99923095703125 +0.122875 -3.0517578125e-05 -0.05224609375 0.99923095703125 +0.123 -3.0517578125e-05 -0.047027587890625 0.99923095703125 +0.123125 -3.0517578125e-05 -0.047027587890625 0.99923095703125 +0.12325 0.0 -0.04180908203125 0.99923095703125 +0.123375 0.0 -0.04180908203125 0.99923095703125 +0.1235 0.0 -0.036590576171875 0.99923095703125 +0.123625 0.0 -0.0313720703125 0.99923095703125 +0.12375 0.0 -0.0313720703125 0.99923095703125 +0.123875 0.0 -0.026123046875 0.99923095703125 +0.124 0.0 -0.026123046875 0.99923095703125 +0.124125 0.0 -0.020904541015625 0.99923095703125 +0.12425 0.0 -0.01568603515625 0.99923095703125 +0.124375 0.0 -0.01568603515625 0.99923095703125 +0.1245 0.0 -0.01043701171875 0.99923095703125 +0.124625 0.0 -0.01043701171875 0.99923095703125 +0.12475 0.0 -0.005218505859375 0.99923095703125 +0.124875 0.0 0.0 0.99923095703125 +0.125 0.0 0.0 0.99923095703125 +0.12512500000000002 0.0 0.005218505859375 0.99923095703125 +0.12525 0.0 0.005218505859375 0.99923095703125 +0.12537500000000002 0.0 0.01043701171875 0.99923095703125 +0.1255 0.0 0.01568603515625 0.99923095703125 +0.12562500000000002 0.0 0.01568603515625 0.99923095703125 +0.12575 0.0 0.020904541015625 0.99923095703125 +0.12587500000000002 0.0 0.020904541015625 0.99923095703125 +0.126 0.0 0.026123046875 0.99923095703125 +0.12612500000000002 0.0 0.0313720703125 0.99923095703125 +0.12625 0.0 0.0313720703125 0.99923095703125 +0.12637500000000002 0.0 0.036590576171875 0.99923095703125 +0.1265 0.0 0.036590576171875 0.99923095703125 +0.12662500000000002 0.0 0.04180908203125 0.99923095703125 +0.12675 3.0517578125e-05 0.047027587890625 0.99923095703125 +0.12687500000000002 3.0517578125e-05 0.047027587890625 0.99923095703125 +0.127 3.0517578125e-05 0.05224609375 0.99923095703125 +0.12712500000000002 3.0517578125e-05 0.05224609375 0.99923095703125 +0.12725 3.0517578125e-05 0.05743408203125 0.99923095703125 +0.12737500000000002 3.0517578125e-05 0.0626220703125 0.99923095703125 +0.1275 3.0517578125e-05 0.0626220703125 0.99923095703125 +0.12762500000000002 3.0517578125e-05 0.06781005859375 0.99923095703125 +0.12775 3.0517578125e-05 0.06781005859375 0.99923095703125 +0.12787500000000002 3.0517578125e-05 0.072998046875 0.99923095703125 +0.128 0.007415771484375 0.07818603515625 0.90478515625 +0.128125 0.007415771484375 0.07818603515625 0.90478515625 +0.12825 0.007904052734375 0.083343505859375 0.90478515625 +0.128375 0.007904052734375 0.083343505859375 0.90478515625 +0.1285 0.008392333984375 0.0885009765625 0.90478515625 +0.128625 0.008880615234375 0.093658447265625 0.90478515625 +0.12875 0.008880615234375 0.093658447265625 0.90478515625 +0.128875 0.0093994140625 0.098785400390625 0.90478515625 +0.129 0.0093994140625 0.098785400390625 0.90478515625 +0.129125 0.009857177734375 0.103912353515625 0.90478515625 +0.12925 0.010345458984375 0.109039306640625 0.90478515625 +0.129375 0.010345458984375 0.109039306640625 0.90478515625 +0.1295 0.010833740234375 0.1141357421875 0.90478515625 +0.129625 0.010833740234375 0.1141357421875 0.90478515625 +0.12975 0.011322021484375 0.119232177734375 0.90478515625 +0.129875 0.011810302734375 0.124298095703125 0.90478515625 +0.13 0.011810302734375 0.124298095703125 0.90478515625 +0.130125 0.012298583984375 0.129364013671875 0.90478515625 +0.13025 0.012298583984375 0.129364013671875 0.90478515625 +0.130375 0.012786865234375 0.134429931640625 0.90478515625 +0.1305 0.01324462890625 0.13946533203125 0.90478515625 +0.130625 0.01324462890625 0.13946533203125 0.90478515625 +0.13075 0.01373291015625 0.14447021484375 0.90478515625 +0.130875 0.01373291015625 0.14447021484375 0.90478515625 +0.131 0.01422119140625 0.14947509765625 0.90478515625 +0.131125 0.014678955078125 0.15447998046875 0.90478515625 +0.13125 0.014678955078125 0.15447998046875 0.90478515625 +0.131375 0.015167236328125 0.159454345703125 0.90478515625 +0.1315 0.015167236328125 0.159454345703125 0.90478515625 +0.131625 0.015625 0.164398193359375 0.90478515625 +0.13175 0.016082763671875 0.169342041015625 0.90478515625 +0.131875 0.016082763671875 0.169342041015625 0.90478515625 +0.132 0.016571044921875 0.17425537109375 0.90478515625 +0.132125 0.016571044921875 0.17425537109375 0.90478515625 +0.13225 0.01702880859375 0.17913818359375 0.90478515625 +0.132375 0.017486572265625 0.18402099609375 0.90478515625 +0.1325 0.017486572265625 0.18402099609375 0.90478515625 +0.132625 0.0179443359375 0.188873291015625 0.90478515625 +0.13275 0.0179443359375 0.188873291015625 0.90478515625 +0.132875 0.018402099609375 0.1937255859375 0.90478515625 +0.133 0.01885986328125 0.19854736328125 0.90478515625 +0.133125 0.01885986328125 0.19854736328125 0.90478515625 +0.13325 0.019317626953125 0.203338623046875 0.90478515625 +0.133375 0.019317626953125 0.203338623046875 0.90478515625 +0.1335 0.019775390625 0.208099365234375 0.90478515625 +0.133625 0.020233154296875 0.212860107421875 0.90478515625 +0.13375 0.020233154296875 0.212860107421875 0.90478515625 +0.133875 0.02069091796875 0.21759033203125 0.90478515625 +0.134 0.02069091796875 0.21759033203125 0.90478515625 +0.134125 0.0211181640625 0.2222900390625 0.90478515625 +0.13425 0.021575927734375 0.226959228515625 0.90478515625 +0.134375 0.021575927734375 0.226959228515625 0.90478515625 +0.1345 0.022003173828125 0.231597900390625 0.90478515625 +0.134625 0.022003173828125 0.231597900390625 0.90478515625 +0.13475 0.0224609375 0.236236572265625 0.90478515625 +0.134875 0.02288818359375 0.2408447265625 0.90478515625 +0.135 0.02288818359375 0.2408447265625 0.90478515625 +0.135125 0.023345947265625 0.24542236328125 0.90478515625 +0.13525 0.023345947265625 0.24542236328125 0.90478515625 +0.135375 0.023773193359375 0.249969482421875 0.90478515625 +0.1355 0.024200439453125 0.25445556640625 0.90478515625 +0.135625 0.024200439453125 0.25445556640625 0.90478515625 +0.13575 0.024627685546875 0.25897216796875 0.90478515625 +0.135875 0.024627685546875 0.25897216796875 0.90478515625 +0.136 0.025054931640625 0.263427734375 0.90478515625 +0.136125 0.025482177734375 0.267852783203125 0.90478515625 +0.13625 0.025482177734375 0.267852783203125 0.90478515625 +0.136375 0.02587890625 0.27227783203125 0.90478515625 +0.1365 0.02587890625 0.27227783203125 0.90478515625 +0.136625 0.02630615234375 0.276641845703125 0.90478515625 +0.13675 0.026702880859375 0.280975341796875 0.90478515625 +0.136875 0.026702880859375 0.280975341796875 0.90478515625 +0.137 0.027130126953125 0.285308837890625 0.90478515625 +0.137125 0.027130126953125 0.285308837890625 0.90478515625 +0.13725 0.02752685546875 0.289581298828125 0.90478515625 +0.137375 0.027923583984375 0.2938232421875 0.90478515625 +0.1375 0.027923583984375 0.2938232421875 0.90478515625 +0.137625 0.028350830078125 0.298065185546875 0.90478515625 +0.13775 0.028350830078125 0.298065185546875 0.90478515625 +0.137875 0.02874755859375 0.30224609375 0.90478515625 +0.138 0.029144287109375 0.306396484375 0.90478515625 +0.138125 0.029144287109375 0.306396484375 0.90478515625 +0.13825 0.029541015625 0.310516357421875 0.90478515625 +0.138375 0.029541015625 0.310516357421875 0.90478515625 +0.1385 0.0299072265625 0.314605712890625 0.90478515625 +0.138625 0.030303955078125 0.31866455078125 0.90478515625 +0.13875 0.030303955078125 0.31866455078125 0.90478515625 +0.138875 0.030670166015625 0.322662353515625 0.90478515625 +0.139 0.030670166015625 0.322662353515625 0.90478515625 +0.139125 0.03106689453125 0.32666015625 0.90478515625 +0.13925 0.03143310546875 0.330596923828125 0.90478515625 +0.139375 0.03143310546875 0.330596923828125 0.90478515625 +0.1395 0.03179931640625 0.334503173828125 0.90478515625 +0.139625 0.03179931640625 0.334503173828125 0.90478515625 +0.13975 0.03216552734375 0.33837890625 0.90478515625 +0.139875 0.03253173828125 0.34222412109375 0.90478515625 +0.14 0.03253173828125 0.34222412109375 0.90478515625 +0.140125 0.03289794921875 0.34600830078125 0.90478515625 +0.14025 0.03289794921875 0.34600830078125 0.90478515625 +0.140375 0.03326416015625 0.349761962890625 0.90478515625 +0.1405 0.033599853515625 0.353485107421875 0.90478515625 +0.140625 0.033599853515625 0.353485107421875 0.90478515625 +0.14075000000000002 0.033966064453125 0.357177734375 0.90478515625 +0.140875 0.033966064453125 0.357177734375 0.90478515625 +0.14100000000000002 0.0343017578125 0.360809326171875 0.90478515625 +0.141125 0.03466796875 0.36444091796875 0.90478515625 +0.14125000000000002 0.03466796875 0.36444091796875 0.90478515625 +0.141375 0.035003662109375 0.36798095703125 0.90478515625 +0.14150000000000002 0.035003662109375 0.36798095703125 0.90478515625 +0.141625 0.03533935546875 0.37152099609375 0.90478515625 +0.14175000000000002 0.03564453125 0.375 0.90478515625 +0.141875 0.03564453125 0.375 0.90478515625 +0.14200000000000002 0.035980224609375 0.378448486328125 0.90478515625 +0.142125 0.035980224609375 0.378448486328125 0.90478515625 +0.14225000000000002 0.03631591796875 0.3818359375 0.90478515625 +0.142375 0.03662109375 0.38519287109375 0.90478515625 +0.14250000000000002 0.03662109375 0.38519287109375 0.90478515625 +0.142625 0.036956787109375 0.388519287109375 0.90478515625 +0.14275000000000002 0.036956787109375 0.388519287109375 0.90478515625 +0.142875 0.037261962890625 0.39178466796875 0.90478515625 +0.14300000000000002 0.037567138671875 0.39501953125 0.90478515625 +0.143125 0.037567138671875 0.39501953125 0.90478515625 +0.14325000000000002 0.037872314453125 0.398193359375 0.90478515625 +0.143375 0.037872314453125 0.398193359375 0.90478515625 +0.14350000000000002 0.038177490234375 0.401336669921875 0.90478515625 +0.143625 0.0384521484375 0.404449462890625 0.90478515625 +0.14375000000000002 0.0384521484375 0.404449462890625 0.90478515625 +0.143875 0.03875732421875 0.407501220703125 0.90478515625 +0.14400000000000002 0.03875732421875 0.407501220703125 0.90478515625 +0.144125 0.039031982421875 0.4105224609375 0.90478515625 +0.14425 0.039306640625 0.413482666015625 0.90478515625 +0.144375 0.039306640625 0.413482666015625 0.90478515625 +0.1445 0.03961181640625 0.416412353515625 0.90478515625 +0.144625 0.03961181640625 0.416412353515625 0.90478515625 +0.14475 0.03985595703125 0.419281005859375 0.90478515625 +0.144875 0.040130615234375 0.422119140625 0.90478515625 +0.145 0.040130615234375 0.422119140625 0.90478515625 +0.145125 0.0404052734375 0.424896240234375 0.90478515625 +0.14525 0.0404052734375 0.424896240234375 0.90478515625 +0.145375 0.040679931640625 0.4276123046875 0.90478515625 +0.1455 0.040924072265625 0.4302978515625 0.90478515625 +0.145625 0.040924072265625 0.4302978515625 0.90478515625 +0.14575 0.041168212890625 0.432952880859375 0.90478515625 +0.145875 0.041168212890625 0.432952880859375 0.90478515625 +0.146 0.041412353515625 0.435546875 0.90478515625 +0.146125 0.041656494140625 0.438079833984375 0.90478515625 +0.14625 0.041656494140625 0.438079833984375 0.90478515625 +0.146375 0.041900634765625 0.440582275390625 0.90478515625 +0.1465 0.041900634765625 0.440582275390625 0.90478515625 +0.146625 0.042144775390625 0.44305419921875 0.90478515625 +0.14675 0.0423583984375 0.4454345703125 0.90478515625 +0.146875 0.0423583984375 0.4454345703125 0.90478515625 +0.147 0.042572021484375 0.447784423828125 0.90478515625 +0.147125 0.042572021484375 0.447784423828125 0.90478515625 +0.14725 0.042816162109375 0.450103759765625 0.90478515625 +0.147375 0.04302978515625 0.452362060546875 0.90478515625 +0.1475 0.04302978515625 0.452362060546875 0.90478515625 +0.147625 0.043212890625 0.454559326171875 0.90478515625 +0.14775 0.043212890625 0.454559326171875 0.90478515625 +0.147875 0.043426513671875 0.45672607421875 0.90478515625 +0.148 0.04364013671875 0.458831787109375 0.90478515625 +0.148125 0.04364013671875 0.458831787109375 0.90478515625 +0.14825 0.0438232421875 0.46087646484375 0.90478515625 +0.148375 0.0438232421875 0.46087646484375 0.90478515625 +0.1485 0.04400634765625 0.462890625 0.90478515625 +0.148625 0.044189453125 0.464813232421875 0.90478515625 +0.14875 0.044189453125 0.464813232421875 0.90478515625 +0.148875 0.04437255859375 0.46673583984375 0.90478515625 +0.149 0.04437255859375 0.46673583984375 0.90478515625 +0.149125 0.0445556640625 0.46856689453125 0.90478515625 +0.14925 0.04473876953125 0.470367431640625 0.90478515625 +0.149375 0.04473876953125 0.470367431640625 0.90478515625 +0.1495 0.044891357421875 0.472137451171875 0.90478515625 +0.149625 0.044891357421875 0.472137451171875 0.90478515625 +0.14975 0.045074462890625 0.47381591796875 0.90478515625 +0.149875 0.04522705078125 0.4754638671875 0.90478515625 +0.15 0.04522705078125 0.4754638671875 0.90478515625 +0.150125 0.045379638671875 0.47705078125 0.90478515625 +0.15025 0.045379638671875 0.47705078125 0.90478515625 +0.150375 0.045501708984375 0.478607177734375 0.90478515625 +0.1505 0.045654296875 0.480072021484375 0.90478515625 +0.150625 0.045654296875 0.480072021484375 0.90478515625 +0.15075 0.0457763671875 0.48150634765625 0.90478515625 +0.150875 0.0457763671875 0.48150634765625 0.90478515625 +0.151 0.045928955078125 0.48291015625 0.90478515625 +0.151125 0.046051025390625 0.484222412109375 0.90478515625 +0.15125 0.046051025390625 0.484222412109375 0.90478515625 +0.151375 0.046173095703125 0.485504150390625 0.90478515625 +0.1515 0.046173095703125 0.485504150390625 0.90478515625 +0.151625 0.046295166015625 0.486724853515625 0.90478515625 +0.15175 0.04638671875 0.487884521484375 0.90478515625 +0.151875 0.04638671875 0.487884521484375 0.90478515625 +0.152 0.0465087890625 0.489013671875 0.90478515625 +0.152125 0.0465087890625 0.489013671875 0.90478515625 +0.15225 0.046600341796875 0.490081787109375 0.90478515625 +0.152375 0.04669189453125 0.4910888671875 0.90478515625 +0.1525 0.04669189453125 0.4910888671875 0.90478515625 +0.152625 0.046783447265625 0.492034912109375 0.90478515625 +0.15275 0.046783447265625 0.492034912109375 0.90478515625 +0.152875 0.046875 0.492950439453125 0.90478515625 +0.153 0.046966552734375 0.4937744140625 0.90478515625 +0.153125 0.046966552734375 0.4937744140625 0.90478515625 +0.15325 0.047027587890625 0.49456787109375 0.90478515625 +0.153375 0.047027587890625 0.49456787109375 0.90478515625 +0.1535 0.047088623046875 0.49530029296875 0.90478515625 +0.153625 0.04718017578125 0.496002197265625 0.90478515625 +0.15375 0.04718017578125 0.496002197265625 0.90478515625 +0.153875 0.0472412109375 0.496612548828125 0.90478515625 +0.154 0.0472412109375 0.496612548828125 0.90478515625 +0.154125 0.047271728515625 0.4971923828125 0.90478515625 +0.15425 0.047332763671875 0.497711181640625 0.90478515625 +0.154375 0.047332763671875 0.497711181640625 0.90478515625 +0.1545 0.04736328125 0.498199462890625 0.90478515625 +0.154625 0.04736328125 0.498199462890625 0.90478515625 +0.15475 0.04742431640625 0.49859619140625 0.90478515625 +0.154875 0.047454833984375 0.49896240234375 0.90478515625 +0.155 0.047454833984375 0.49896240234375 0.90478515625 +0.155125 0.0474853515625 0.499267578125 0.90478515625 +0.15525 0.0474853515625 0.499267578125 0.90478515625 +0.155375 0.047515869140625 0.49951171875 0.90478515625 +0.1555 0.047515869140625 0.49969482421875 0.90478515625 +0.155625 0.047515869140625 0.49969482421875 0.90478515625 +0.15575 0.04754638671875 0.49981689453125 0.90478515625 +0.155875 0.04754638671875 0.49981689453125 0.90478515625 +0.156 0.04754638671875 0.499908447265625 0.90478515625 +0.156125 0.04754638671875 0.49993896484375 0.90478515625 +0.15625 0.04754638671875 0.49993896484375 0.90478515625 +0.15637500000000002 0.04754638671875 0.499908447265625 0.90478515625 +0.1565 0.04754638671875 0.499908447265625 0.90478515625 +0.15662500000000002 0.04754638671875 0.49981689453125 0.90478515625 +0.15675 0.047515869140625 0.49969482421875 0.90478515625 +0.15687500000000002 0.047515869140625 0.49969482421875 0.90478515625 +0.157 0.047515869140625 0.49951171875 0.90478515625 +0.15712500000000002 0.047515869140625 0.49951171875 0.90478515625 +0.15725 0.0474853515625 0.499267578125 0.90478515625 +0.15737500000000002 0.047454833984375 0.49896240234375 0.90478515625 +0.1575 0.047454833984375 0.49896240234375 0.90478515625 +0.15762500000000002 0.04742431640625 0.49859619140625 0.90478515625 +0.15775 0.04742431640625 0.49859619140625 0.90478515625 +0.15787500000000002 0.04736328125 0.498199462890625 0.90478515625 +0.158 0.047332763671875 0.497711181640625 0.90478515625 +0.15812500000000002 0.047332763671875 0.497711181640625 0.90478515625 +0.15825 0.047271728515625 0.4971923828125 0.90478515625 +0.15837500000000002 0.047271728515625 0.4971923828125 0.90478515625 +0.1585 0.0472412109375 0.496612548828125 0.90478515625 +0.15862500000000002 0.04718017578125 0.496002197265625 0.90478515625 +0.15875 0.04718017578125 0.496002197265625 0.90478515625 +0.15887500000000002 0.047088623046875 0.49530029296875 0.90478515625 +0.159 0.047088623046875 0.49530029296875 0.90478515625 +0.15912500000000002 0.047027587890625 0.49456787109375 0.90478515625 +0.15925 0.046966552734375 0.4937744140625 0.90478515625 +0.15937500000000002 0.046966552734375 0.4937744140625 0.90478515625 +0.1595 0.046875 0.492950439453125 0.90478515625 +0.15962500000000002 0.046875 0.492950439453125 0.90478515625 +0.15975 0.046783447265625 0.492034912109375 0.90478515625 +0.15987500000000002 0.04669189453125 0.4910888671875 0.90478515625 +0.16 0.163970947265625 0.4910888671875 0.665972900390625 +0.160125 0.16363525390625 0.490081787109375 0.665972900390625 +0.16025 0.16363525390625 0.490081787109375 0.665972900390625 +0.160375 0.163299560546875 0.489013671875 0.665972900390625 +0.1605 0.16290283203125 0.487884521484375 0.665972900390625 +0.160625 0.16290283203125 0.487884521484375 0.665972900390625 +0.16075 0.16253662109375 0.486724853515625 0.665972900390625 +0.160875 0.16253662109375 0.486724853515625 0.665972900390625 +0.161 0.162109375 0.485504150390625 0.665972900390625 +0.161125 0.16168212890625 0.484222412109375 0.665972900390625 +0.16125 0.16168212890625 0.484222412109375 0.665972900390625 +0.161375 0.1612548828125 0.48291015625 0.665972900390625 +0.1615 0.1612548828125 0.48291015625 0.665972900390625 +0.161625 0.160797119140625 0.48150634765625 0.665972900390625 +0.16175 0.160308837890625 0.480072021484375 0.665972900390625 +0.161875 0.160308837890625 0.480072021484375 0.665972900390625 +0.162 0.159820556640625 0.478607177734375 0.665972900390625 +0.162125 0.159820556640625 0.478607177734375 0.665972900390625 +0.16225 0.1593017578125 0.47705078125 0.665972900390625 +0.162375 0.158782958984375 0.4754638671875 0.665972900390625 +0.1625 0.158782958984375 0.4754638671875 0.665972900390625 +0.162625 0.158203125 0.47381591796875 0.665972900390625 +0.16275 0.158203125 0.47381591796875 0.665972900390625 +0.162875 0.15765380859375 0.472137451171875 0.665972900390625 +0.163 0.157073974609375 0.470367431640625 0.665972900390625 +0.163125 0.157073974609375 0.470367431640625 0.665972900390625 +0.16325 0.156463623046875 0.46856689453125 0.665972900390625 +0.163375 0.156463623046875 0.46856689453125 0.665972900390625 +0.1635 0.155853271484375 0.46673583984375 0.665972900390625 +0.163625 0.15521240234375 0.464813232421875 0.665972900390625 +0.16375 0.15521240234375 0.464813232421875 0.665972900390625 +0.163875 0.154571533203125 0.462890625 0.665972900390625 +0.164 0.154571533203125 0.462890625 0.665972900390625 +0.164125 0.153900146484375 0.46087646484375 0.665972900390625 +0.16425 0.1531982421875 0.458831787109375 0.665972900390625 +0.164375 0.1531982421875 0.458831787109375 0.665972900390625 +0.1645 0.152496337890625 0.45672607421875 0.665972900390625 +0.164625 0.152496337890625 0.45672607421875 0.665972900390625 +0.16475 0.15179443359375 0.454559326171875 0.665972900390625 +0.164875 0.15106201171875 0.452362060546875 0.665972900390625 +0.165 0.15106201171875 0.452362060546875 0.665972900390625 +0.165125 0.150299072265625 0.450103759765625 0.665972900390625 +0.16525 0.150299072265625 0.450103759765625 0.665972900390625 +0.165375 0.1495361328125 0.447784423828125 0.665972900390625 +0.1655 0.14874267578125 0.4454345703125 0.665972900390625 +0.165625 0.14874267578125 0.4454345703125 0.665972900390625 +0.16575 0.14794921875 0.44305419921875 0.665972900390625 +0.165875 0.14794921875 0.44305419921875 0.665972900390625 +0.166 0.147125244140625 0.440582275390625 0.665972900390625 +0.166125 0.146270751953125 0.438079833984375 0.665972900390625 +0.16625 0.146270751953125 0.438079833984375 0.665972900390625 +0.166375 0.14544677734375 0.435546875 0.665972900390625 +0.1665 0.14544677734375 0.435546875 0.665972900390625 +0.166625 0.144561767578125 0.432952880859375 0.665972900390625 +0.16675 0.1436767578125 0.4302978515625 0.665972900390625 +0.166875 0.1436767578125 0.4302978515625 0.665972900390625 +0.167 0.142791748046875 0.4276123046875 0.665972900390625 +0.167125 0.142791748046875 0.4276123046875 0.665972900390625 +0.16725 0.141876220703125 0.424896240234375 0.665972900390625 +0.167375 0.140960693359375 0.422119140625 0.665972900390625 +0.1675 0.140960693359375 0.422119140625 0.665972900390625 +0.167625 0.1400146484375 0.419281005859375 0.665972900390625 +0.16775 0.1400146484375 0.419281005859375 0.665972900390625 +0.167875 0.1390380859375 0.416412353515625 0.665972900390625 +0.168 0.1380615234375 0.413482666015625 0.665972900390625 +0.168125 0.1380615234375 0.413482666015625 0.665972900390625 +0.16825 0.1370849609375 0.4105224609375 0.665972900390625 +0.168375 0.1370849609375 0.4105224609375 0.665972900390625 +0.1685 0.136077880859375 0.407501220703125 0.665972900390625 +0.168625 0.135040283203125 0.404449462890625 0.665972900390625 +0.16875 0.135040283203125 0.404449462890625 0.665972900390625 +0.168875 0.134002685546875 0.401336669921875 0.665972900390625 +0.169 0.134002685546875 0.401336669921875 0.665972900390625 +0.169125 0.132965087890625 0.398193359375 0.665972900390625 +0.16925 0.13189697265625 0.39501953125 0.665972900390625 +0.169375 0.13189697265625 0.39501953125 0.665972900390625 +0.1695 0.130828857421875 0.39178466796875 0.665972900390625 +0.169625 0.130828857421875 0.39178466796875 0.665972900390625 +0.16975 0.129730224609375 0.388519287109375 0.665972900390625 +0.169875 0.128631591796875 0.38519287109375 0.665972900390625 +0.17 0.128631591796875 0.38519287109375 0.665972900390625 +0.170125 0.12750244140625 0.3818359375 0.665972900390625 +0.17025 0.12750244140625 0.3818359375 0.665972900390625 +0.170375 0.126373291015625 0.378448486328125 0.665972900390625 +0.1705 0.125213623046875 0.375 0.665972900390625 +0.170625 0.125213623046875 0.375 0.665972900390625 +0.17075 0.124053955078125 0.37152099609375 0.665972900390625 +0.170875 0.124053955078125 0.37152099609375 0.665972900390625 +0.171 0.12286376953125 0.36798095703125 0.665972900390625 +0.171125 0.1217041015625 0.36444091796875 0.665972900390625 +0.17125 0.1217041015625 0.36444091796875 0.665972900390625 +0.171375 0.1204833984375 0.360809326171875 0.665972900390625 +0.1715 0.1204833984375 0.360809326171875 0.665972900390625 +0.171625 0.1192626953125 0.357177734375 0.665972900390625 +0.17175 0.1180419921875 0.353485107421875 0.665972900390625 +0.171875 0.1180419921875 0.353485107421875 0.665972900390625 +0.17200000000000002 0.116790771484375 0.349761962890625 0.665972900390625 +0.172125 0.116790771484375 0.349761962890625 0.665972900390625 +0.17225000000000002 0.11553955078125 0.34600830078125 0.665972900390625 +0.172375 0.1142578125 0.34222412109375 0.665972900390625 +0.17250000000000002 0.1142578125 0.34222412109375 0.665972900390625 +0.172625 0.113006591796875 0.33837890625 0.665972900390625 +0.17275000000000002 0.113006591796875 0.33837890625 0.665972900390625 +0.172875 0.1116943359375 0.334503173828125 0.665972900390625 +0.17300000000000002 0.110382080078125 0.330596923828125 0.665972900390625 +0.173125 0.110382080078125 0.330596923828125 0.665972900390625 +0.17325000000000002 0.10906982421875 0.32666015625 0.665972900390625 +0.173375 0.10906982421875 0.32666015625 0.665972900390625 +0.17350000000000002 0.107757568359375 0.322662353515625 0.665972900390625 +0.173625 0.106414794921875 0.31866455078125 0.665972900390625 +0.17375000000000002 0.106414794921875 0.31866455078125 0.665972900390625 +0.173875 0.10504150390625 0.314605712890625 0.665972900390625 +0.17400000000000002 0.10504150390625 0.314605712890625 0.665972900390625 +0.174125 0.10369873046875 0.310516357421875 0.665972900390625 +0.17425000000000002 0.102325439453125 0.306396484375 0.665972900390625 +0.174375 0.102325439453125 0.306396484375 0.665972900390625 +0.17450000000000002 0.100921630859375 0.30224609375 0.665972900390625 +0.174625 0.100921630859375 0.30224609375 0.665972900390625 +0.17475000000000002 0.099517822265625 0.298065185546875 0.665972900390625 +0.174875 0.098114013671875 0.2938232421875 0.665972900390625 +0.17500000000000002 0.098114013671875 0.2938232421875 0.665972900390625 +0.175125 0.096710205078125 0.289581298828125 0.665972900390625 +0.17525000000000002 0.096710205078125 0.289581298828125 0.665972900390625 +0.175375 0.09527587890625 0.285308837890625 0.665972900390625 +0.17550000000000002 0.09381103515625 0.280975341796875 0.665972900390625 +0.175625 0.09381103515625 0.280975341796875 0.665972900390625 +0.17575000000000002 0.092376708984375 0.276641845703125 0.665972900390625 +0.175875 0.092376708984375 0.276641845703125 0.665972900390625 +0.176 0.090911865234375 0.27227783203125 0.665972900390625 +0.176125 0.089447021484375 0.267852783203125 0.665972900390625 +0.17625 0.089447021484375 0.267852783203125 0.665972900390625 +0.176375 0.08795166015625 0.263427734375 0.665972900390625 +0.1765 0.08795166015625 0.263427734375 0.665972900390625 +0.176625 0.08648681640625 0.25897216796875 0.665972900390625 +0.17675 0.0849609375 0.25445556640625 0.665972900390625 +0.176875 0.0849609375 0.25445556640625 0.665972900390625 +0.177 0.083465576171875 0.249969482421875 0.665972900390625 +0.177125 0.083465576171875 0.249969482421875 0.665972900390625 +0.17725 0.081939697265625 0.24542236328125 0.665972900390625 +0.177375 0.080413818359375 0.2408447265625 0.665972900390625 +0.1775 0.080413818359375 0.2408447265625 0.665972900390625 +0.177625 0.078887939453125 0.236236572265625 0.665972900390625 +0.17775 0.078887939453125 0.236236572265625 0.665972900390625 +0.177875 0.07733154296875 0.231597900390625 0.665972900390625 +0.178 0.075775146484375 0.226959228515625 0.665972900390625 +0.178125 0.075775146484375 0.226959228515625 0.665972900390625 +0.17825 0.07421875 0.2222900390625 0.665972900390625 +0.178375 0.07421875 0.2222900390625 0.665972900390625 +0.1785 0.072662353515625 0.21759033203125 0.665972900390625 +0.178625 0.071075439453125 0.212860107421875 0.665972900390625 +0.17875 0.071075439453125 0.212860107421875 0.665972900390625 +0.178875 0.069488525390625 0.208099365234375 0.665972900390625 +0.179 0.069488525390625 0.208099365234375 0.665972900390625 +0.179125 0.067901611328125 0.203338623046875 0.665972900390625 +0.17925 0.0662841796875 0.19854736328125 0.665972900390625 +0.179375 0.0662841796875 0.19854736328125 0.665972900390625 +0.1795 0.064666748046875 0.1937255859375 0.665972900390625 +0.179625 0.064666748046875 0.1937255859375 0.665972900390625 +0.17975 0.06304931640625 0.188873291015625 0.665972900390625 +0.179875 0.061431884765625 0.18402099609375 0.665972900390625 +0.18 0.061431884765625 0.18402099609375 0.665972900390625 +0.180125 0.059814453125 0.17913818359375 0.665972900390625 +0.18025 0.059814453125 0.17913818359375 0.665972900390625 +0.180375 0.05816650390625 0.17425537109375 0.665972900390625 +0.1805 0.056549072265625 0.169342041015625 0.665972900390625 +0.180625 0.056549072265625 0.169342041015625 0.665972900390625 +0.18075 0.054901123046875 0.164398193359375 0.665972900390625 +0.180875 0.054901123046875 0.164398193359375 0.665972900390625 +0.181 0.05322265625 0.159454345703125 0.665972900390625 +0.181125 0.05157470703125 0.15447998046875 0.665972900390625 +0.18125 0.05157470703125 0.15447998046875 0.665972900390625 +0.181375 0.049896240234375 0.14947509765625 0.665972900390625 +0.1815 0.049896240234375 0.14947509765625 0.665972900390625 +0.181625 0.048248291015625 0.14447021484375 0.665972900390625 +0.18175 0.04656982421875 0.13946533203125 0.665972900390625 +0.181875 0.04656982421875 0.13946533203125 0.665972900390625 +0.182 0.044891357421875 0.134429931640625 0.665972900390625 +0.182125 0.044891357421875 0.134429931640625 0.665972900390625 +0.18225 0.043182373046875 0.129364013671875 0.665972900390625 +0.182375 0.04150390625 0.124298095703125 0.665972900390625 +0.1825 0.04150390625 0.124298095703125 0.665972900390625 +0.182625 0.039794921875 0.119232177734375 0.665972900390625 +0.18275 0.039794921875 0.119232177734375 0.665972900390625 +0.182875 0.038116455078125 0.1141357421875 0.665972900390625 +0.183 0.036407470703125 0.109039306640625 0.665972900390625 +0.183125 0.036407470703125 0.109039306640625 0.665972900390625 +0.18325 0.034698486328125 0.103912353515625 0.665972900390625 +0.183375 0.034698486328125 0.103912353515625 0.665972900390625 +0.1835 0.032989501953125 0.098785400390625 0.665972900390625 +0.183625 0.03125 0.093658447265625 0.665972900390625 +0.18375 0.03125 0.093658447265625 0.665972900390625 +0.183875 0.029541015625 0.0885009765625 0.665972900390625 +0.184 0.029541015625 0.0885009765625 0.665972900390625 +0.184125 0.02783203125 0.083343505859375 0.665972900390625 +0.18425 0.026092529296875 0.07818603515625 0.665972900390625 +0.184375 0.026092529296875 0.07818603515625 0.665972900390625 +0.1845 0.024383544921875 0.072998046875 0.665972900390625 +0.184625 0.024383544921875 0.072998046875 0.665972900390625 +0.18475 0.02264404296875 0.06781005859375 0.665972900390625 +0.184875 0.020904541015625 0.0626220703125 0.665972900390625 +0.185 0.020904541015625 0.0626220703125 0.665972900390625 +0.185125 0.0191650390625 0.05743408203125 0.665972900390625 +0.18525 0.0191650390625 0.05743408203125 0.665972900390625 +0.185375 0.017425537109375 0.05224609375 0.665972900390625 +0.1855 0.01568603515625 0.047027587890625 0.665972900390625 +0.185625 0.01568603515625 0.047027587890625 0.665972900390625 +0.18575 0.013946533203125 0.04180908203125 0.665972900390625 +0.185875 0.013946533203125 0.04180908203125 0.665972900390625 +0.186 0.01220703125 0.036590576171875 0.665972900390625 +0.186125 0.010467529296875 0.0313720703125 0.665972900390625 +0.18625 0.010467529296875 0.0313720703125 0.665972900390625 +0.186375 0.00872802734375 0.026123046875 0.665972900390625 +0.1865 0.00872802734375 0.026123046875 0.665972900390625 +0.186625 0.006988525390625 0.020904541015625 0.665972900390625 +0.18675 0.005218505859375 0.01568603515625 0.665972900390625 +0.186875 0.005218505859375 0.01568603515625 0.665972900390625 +0.187 0.00347900390625 0.01043701171875 0.665972900390625 +0.187125 0.00347900390625 0.01043701171875 0.665972900390625 +0.18725 0.001739501953125 0.005218505859375 0.665972900390625 +0.187375 0.0 0.0 0.665972900390625 +0.1875 0.0 0.0 0.665972900390625 +0.1876250000000000256 -0.001739501953125 -0.005218505859375 0.665972900390625 +0.18775 -0.001739501953125 -0.005218505859375 0.665972900390625 +0.1878750000000000256 -0.00347900390625 -0.01043701171875 0.665972900390625 +0.188 -0.005218505859375 -0.01568603515625 0.665972900390625 +0.1881250000000000256 -0.005218505859375 -0.01568603515625 0.665972900390625 +0.18825 -0.006988525390625 -0.020904541015625 0.665972900390625 +0.1883750000000000256 -0.006988525390625 -0.020904541015625 0.665972900390625 +0.1885 -0.00872802734375 -0.026123046875 0.665972900390625 +0.1886250000000000256 -0.010467529296875 -0.0313720703125 0.665972900390625 +0.18875 -0.010467529296875 -0.0313720703125 0.665972900390625 +0.1888750000000000256 -0.01220703125 -0.036590576171875 0.665972900390625 +0.189 -0.01220703125 -0.036590576171875 0.665972900390625 +0.1891250000000000256 -0.013946533203125 -0.04180908203125 0.665972900390625 +0.18925 -0.01568603515625 -0.047027587890625 0.665972900390625 +0.1893750000000000256 -0.01568603515625 -0.047027587890625 0.665972900390625 +0.1895 -0.017425537109375 -0.05224609375 0.665972900390625 +0.1896250000000000256 -0.017425537109375 -0.05224609375 0.665972900390625 +0.18975 -0.0191650390625 -0.05743408203125 0.665972900390625 +0.1898750000000000256 -0.020904541015625 -0.0626220703125 0.665972900390625 +0.19 -0.020904541015625 -0.0626220703125 0.665972900390625 +0.1901250000000000256 -0.02264404296875 -0.06781005859375 0.665972900390625 +0.19025 -0.02264404296875 -0.06781005859375 0.665972900390625 +0.1903750000000000256 -0.024383544921875 -0.072998046875 0.665972900390625 +0.1905 -0.026092529296875 -0.07818603515625 0.665972900390625 +0.1906250000000000256 -0.026092529296875 -0.07818603515625 0.665972900390625 +0.19075 -0.02783203125 -0.083343505859375 0.665972900390625 +0.1908750000000000256 -0.02783203125 -0.083343505859375 0.665972900390625 +0.191 -0.029541015625 -0.0885009765625 0.665972900390625 +0.1911250000000000256 -0.03125 -0.093658447265625 0.665972900390625 +0.19125 -0.03125 -0.093658447265625 0.665972900390625 +0.1913750000000000256 -0.032989501953125 -0.098785400390625 0.665972900390625 +0.1915 -0.032989501953125 -0.098785400390625 0.665972900390625 +0.1916250000000000256 -0.034698486328125 -0.103912353515625 0.665972900390625 +0.19175 -0.036407470703125 -0.109039306640625 0.665972900390625 +0.1918750000000000256 -0.036407470703125 -0.109039306640625 0.665972900390625 +0.192 -0.0775146484375 -0.1141357421875 0.3209167480468749 +0.192125 -0.0775146484375 -0.1141357421875 0.3209167480468749 +0.19225 -0.080963134765625 -0.119232177734375 0.3209167480468749 +0.192375 -0.08441162109375 -0.124298095703125 0.3209167480468749 +0.1925 -0.08441162109375 -0.124298095703125 0.3209167480468749 +0.192625 -0.08782958984375 -0.129364013671875 0.3209167480468749 +0.19275 -0.08782958984375 -0.129364013671875 0.3209167480468749 +0.192875 -0.091278076171875 -0.134429931640625 0.3209167480468749 +0.193 -0.094696044921875 -0.13946533203125 0.3209167480468749 +0.193125 -0.094696044921875 -0.13946533203125 0.3209167480468749 +0.19325 -0.09808349609375 -0.14447021484375 0.3209167480468749 +0.193375 -0.09808349609375 -0.14447021484375 0.3209167480468749 +0.1935 -0.10150146484375 -0.14947509765625 0.3209167480468749 +0.193625 -0.104888916015625 -0.15447998046875 0.3209167480468749 +0.19375 -0.104888916015625 -0.15447998046875 0.3209167480468749 +0.193875 -0.1082763671875 -0.159454345703125 0.3209167480468749 +0.194 -0.1082763671875 -0.159454345703125 0.3209167480468749 +0.194125 -0.11163330078125 -0.164398193359375 0.3209167480468749 +0.19425 -0.114990234375 -0.169342041015625 0.3209167480468749 +0.194375 -0.114990234375 -0.169342041015625 0.3209167480468749 +0.1945 -0.118316650390625 -0.17425537109375 0.3209167480468749 +0.194625 -0.118316650390625 -0.17425537109375 0.3209167480468749 +0.19475 -0.12164306640625 -0.17913818359375 0.3209167480468749 +0.194875 -0.12493896484375 -0.18402099609375 0.3209167480468749 +0.195 -0.12493896484375 -0.18402099609375 0.3209167480468749 +0.195125 -0.12823486328125 -0.188873291015625 0.3209167480468749 +0.19525 -0.12823486328125 -0.188873291015625 0.3209167480468749 +0.195375 -0.13153076171875 -0.1937255859375 0.3209167480468749 +0.1955 -0.134796142578125 -0.19854736328125 0.3209167480468749 +0.195625 -0.134796142578125 -0.19854736328125 0.3209167480468749 +0.19575 -0.1380615234375 -0.203338623046875 0.3209167480468749 +0.195875 -0.1380615234375 -0.203338623046875 0.3209167480468749 +0.196 -0.14129638671875 -0.208099365234375 0.3209167480468749 +0.196125 -0.14453125 -0.212860107421875 0.3209167480468749 +0.19625 -0.14453125 -0.212860107421875 0.3209167480468749 +0.196375 -0.147735595703125 -0.21759033203125 0.3209167480468749 +0.1965 -0.147735595703125 -0.21759033203125 0.3209167480468749 +0.196625 -0.15093994140625 -0.2222900390625 0.3209167480468749 +0.19675 -0.154083251953125 -0.226959228515625 0.3209167480468749 +0.196875 -0.154083251953125 -0.226959228515625 0.3209167480468749 +0.197 -0.157257080078125 -0.231597900390625 0.3209167480468749 +0.197125 -0.157257080078125 -0.231597900390625 0.3209167480468749 +0.19725 -0.160400390625 -0.236236572265625 0.3209167480468749 +0.197375 -0.16351318359375 -0.2408447265625 0.3209167480468749 +0.1975 -0.16351318359375 -0.2408447265625 0.3209167480468749 +0.197625 -0.1666259765625 -0.24542236328125 0.3209167480468749 +0.19775 -0.1666259765625 -0.24542236328125 0.3209167480468749 +0.197875 -0.169708251953125 -0.249969482421875 0.3209167480468749 +0.198 -0.17279052734375 -0.25445556640625 0.3209167480468749 +0.198125 -0.17279052734375 -0.25445556640625 0.3209167480468749 +0.19825 -0.17584228515625 -0.25897216796875 0.3209167480468749 +0.198375 -0.17584228515625 -0.25897216796875 0.3209167480468749 +0.1985 -0.178863525390625 -0.263427734375 0.3209167480468749 +0.198625 -0.181884765625 -0.267852783203125 0.3209167480468749 +0.19875 -0.181884765625 -0.267852783203125 0.3209167480468749 +0.198875 -0.18487548828125 -0.27227783203125 0.3209167480468749 +0.199 -0.18487548828125 -0.27227783203125 0.3209167480468749 +0.199125 -0.187835693359375 -0.276641845703125 0.3209167480468749 +0.19925 -0.1907958984375 -0.280975341796875 0.3209167480468749 +0.199375 -0.1907958984375 -0.280975341796875 0.3209167480468749 +0.1995 -0.1937255859375 -0.285308837890625 0.3209167480468749 +0.199625 -0.1937255859375 -0.285308837890625 0.3209167480468749 +0.19975 -0.196624755859375 -0.289581298828125 0.3209167480468749 +0.199875 -0.19952392578125 -0.2938232421875 0.3209167480468749 +0.2 -0.19952392578125 -0.2938232421875 0.3209167480468749 +0.200125 -0.202392578125 -0.298065185546875 0.3209167480468749 +0.20025 -0.202392578125 -0.298065185546875 0.3209167480468749 +0.200375 -0.205230712890625 -0.30224609375 0.3209167480468749 +0.2005 -0.20806884765625 -0.306396484375 0.3209167480468749 +0.200625 -0.20806884765625 -0.306396484375 0.3209167480468749 +0.20075 -0.210845947265625 -0.310516357421875 0.3209167480468749 +0.200875 -0.210845947265625 -0.310516357421875 0.3209167480468749 +0.201 -0.213623046875 -0.314605712890625 0.3209167480468749 +0.201125 -0.21636962890625 -0.31866455078125 0.3209167480468749 +0.20125 -0.21636962890625 -0.31866455078125 0.3209167480468749 +0.201375 -0.219085693359375 -0.322662353515625 0.3209167480468749 +0.2015 -0.219085693359375 -0.322662353515625 0.3209167480468749 +0.201625 -0.2218017578125 -0.32666015625 0.3209167480468749 +0.20175 -0.2244873046875 -0.330596923828125 0.3209167480468749 +0.201875 -0.2244873046875 -0.330596923828125 0.3209167480468749 +0.202 -0.227142333984375 -0.334503173828125 0.3209167480468749 +0.202125 -0.227142333984375 -0.334503173828125 0.3209167480468749 +0.20225 -0.229766845703125 -0.33837890625 0.3209167480468749 +0.202375 -0.23236083984375 -0.34222412109375 0.3209167480468749 +0.2025 -0.23236083984375 -0.34222412109375 0.3209167480468749 +0.202625 -0.234954833984375 -0.34600830078125 0.3209167480468749 +0.20275 -0.234954833984375 -0.34600830078125 0.3209167480468749 +0.202875 -0.23748779296875 -0.349761962890625 0.3209167480468749 +0.203 -0.240020751953125 -0.353485107421875 0.3209167480468749 +0.203125 -0.240020751953125 -0.353485107421875 0.3209167480468749 +0.2032500000000000256 -0.242523193359375 -0.357177734375 0.3209167480468749 +0.203375 -0.242523193359375 -0.357177734375 0.3209167480468749 +0.2035000000000000256 -0.2449951171875 -0.360809326171875 0.3209167480468749 +0.203625 -0.247467041015625 -0.36444091796875 0.3209167480468749 +0.2037500000000000256 -0.247467041015625 -0.36444091796875 0.3209167480468749 +0.203875 -0.2498779296875 -0.36798095703125 0.3209167480468749 +0.2040000000000000256 -0.2498779296875 -0.36798095703125 0.3209167480468749 +0.204125 -0.25225830078125 -0.37152099609375 0.3209167480468749 +0.2042500000000000256 -0.254638671875 -0.375 0.3209167480468749 +0.204375 -0.254638671875 -0.375 0.3209167480468749 +0.2045000000000000256 -0.2569580078125 -0.378448486328125 0.3209167480468749 +0.204625 -0.2569580078125 -0.378448486328125 0.3209167480468749 +0.2047500000000000256 -0.25927734375 -0.3818359375 0.3209167480468749 +0.204875 -0.261566162109375 -0.38519287109375 0.3209167480468749 +0.2050000000000000256 -0.261566162109375 -0.38519287109375 0.3209167480468749 +0.205125 -0.2637939453125 -0.388519287109375 0.3209167480468749 +0.2052500000000000256 -0.2637939453125 -0.388519287109375 0.3209167480468749 +0.205375 -0.266021728515625 -0.39178466796875 0.3209167480468749 +0.2055000000000000256 -0.268218994140625 -0.39501953125 0.3209167480468749 +0.205625 -0.268218994140625 -0.39501953125 0.3209167480468749 +0.2057500000000000256 -0.2703857421875 -0.398193359375 0.3209167480468749 +0.205875 -0.2703857421875 -0.398193359375 0.3209167480468749 +0.2060000000000000256 -0.27252197265625 -0.401336669921875 0.3209167480468749 +0.206125 -0.274627685546875 -0.404449462890625 0.3209167480468749 +0.2062500000000000256 -0.274627685546875 -0.404449462890625 0.3209167480468749 +0.206375 -0.276702880859375 -0.407501220703125 0.3209167480468749 +0.2065000000000000256 -0.276702880859375 -0.407501220703125 0.3209167480468749 +0.206625 -0.27874755859375 -0.4105224609375 0.3209167480468749 +0.2067500000000000256 -0.28076171875 -0.413482666015625 0.3209167480468749 +0.206875 -0.28076171875 -0.413482666015625 0.3209167480468749 +0.2070000000000000256 -0.282745361328125 -0.416412353515625 0.3209167480468749 +0.207125 -0.282745361328125 -0.416412353515625 0.3209167480468749 +0.2072500000000000256 -0.284698486328125 -0.419281005859375 0.3209167480468749 +0.207375 -0.28662109375 -0.422119140625 0.3209167480468749 +0.2075000000000000256 -0.28662109375 -0.422119140625 0.3209167480468749 +0.207625 -0.28851318359375 -0.424896240234375 0.3209167480468749 +0.2077500000000000256 -0.28851318359375 -0.424896240234375 0.3209167480468749 +0.207875 -0.29034423828125 -0.4276123046875 0.3209167480468749 +0.208000000000000032 -0.29217529296875 -0.4302978515625 0.3209167480468749 +0.208125 -0.29217529296875 -0.4302978515625 0.3209167480468749 +0.20825 -0.293975830078125 -0.432952880859375 0.3209167480468749 +0.208375 -0.293975830078125 -0.432952880859375 0.3209167480468749 +0.2085 -0.295745849609375 -0.435546875 0.3209167480468749 +0.208625 -0.297454833984375 -0.438079833984375 0.3209167480468749 +0.20875 -0.297454833984375 -0.438079833984375 0.3209167480468749 +0.208875 -0.299163818359375 -0.440582275390625 0.3209167480468749 +0.209 -0.299163818359375 -0.440582275390625 0.3209167480468749 +0.209125 -0.30084228515625 -0.44305419921875 0.3209167480468749 +0.20925 -0.302459716796875 -0.4454345703125 0.3209167480468749 +0.209375 -0.302459716796875 -0.4454345703125 0.3209167480468749 +0.2095 -0.304046630859375 -0.447784423828125 0.3209167480468749 +0.209625 -0.304046630859375 -0.447784423828125 0.3209167480468749 +0.20975 -0.305633544921875 -0.450103759765625 0.3209167480468749 +0.209875 -0.307159423828125 -0.452362060546875 0.3209167480468749 +0.21 -0.307159423828125 -0.452362060546875 0.3209167480468749 +0.210125 -0.30865478515625 -0.454559326171875 0.3209167480468749 +0.21025 -0.30865478515625 -0.454559326171875 0.3209167480468749 +0.210375 -0.31011962890625 -0.45672607421875 0.3209167480468749 +0.2105 -0.311553955078125 -0.458831787109375 0.3209167480468749 +0.210625 -0.311553955078125 -0.458831787109375 0.3209167480468749 +0.21075 -0.31292724609375 -0.46087646484375 0.3209167480468749 +0.210875 -0.31292724609375 -0.46087646484375 0.3209167480468749 +0.211 -0.314300537109375 -0.462890625 0.3209167480468749 +0.211125 -0.31561279296875 -0.464813232421875 0.3209167480468749 +0.21125 -0.31561279296875 -0.464813232421875 0.3209167480468749 +0.211375 -0.316925048828125 -0.46673583984375 0.3209167480468749 +0.2115 -0.316925048828125 -0.46673583984375 0.3209167480468749 +0.211625 -0.31817626953125 -0.46856689453125 0.3209167480468749 +0.21175 -0.31939697265625 -0.470367431640625 0.3209167480468749 +0.211875 -0.31939697265625 -0.470367431640625 0.3209167480468749 +0.212 -0.320587158203125 -0.472137451171875 0.3209167480468749 +0.212125 -0.320587158203125 -0.472137451171875 0.3209167480468749 +0.21225 -0.32171630859375 -0.47381591796875 0.3209167480468749 +0.212375 -0.322845458984375 -0.4754638671875 0.3209167480468749 +0.2125 -0.322845458984375 -0.4754638671875 0.3209167480468749 +0.212625 -0.32391357421875 -0.47705078125 0.3209167480468749 +0.21275 -0.32391357421875 -0.47705078125 0.3209167480468749 +0.212875 -0.324981689453125 -0.478607177734375 0.3209167480468749 +0.213 -0.32598876953125 -0.480072021484375 0.3209167480468749 +0.213125 -0.32598876953125 -0.480072021484375 0.3209167480468749 +0.21325 -0.32696533203125 -0.48150634765625 0.3209167480468749 +0.213375 -0.32696533203125 -0.48150634765625 0.3209167480468749 +0.2135 -0.327880859375 -0.48291015625 0.3209167480468749 +0.213625 -0.32879638671875 -0.484222412109375 0.3209167480468749 +0.21375 -0.32879638671875 -0.484222412109375 0.3209167480468749 +0.213875 -0.329681396484375 -0.485504150390625 0.3209167480468749 +0.214 -0.329681396484375 -0.485504150390625 0.3209167480468749 +0.214125 -0.33050537109375 -0.486724853515625 0.3209167480468749 +0.21425 -0.331268310546875 -0.487884521484375 0.3209167480468749 +0.214375 -0.331268310546875 -0.487884521484375 0.3209167480468749 +0.2145 -0.33203125 -0.489013671875 0.3209167480468749 +0.214625 -0.33203125 -0.489013671875 0.3209167480468749 +0.21475 -0.332763671875 -0.490081787109375 0.3209167480468749 +0.214875 -0.33343505859375 -0.4910888671875 0.3209167480468749 +0.215 -0.33343505859375 -0.4910888671875 0.3209167480468749 +0.215125 -0.3341064453125 -0.492034912109375 0.3209167480468749 +0.21525 -0.3341064453125 -0.492034912109375 0.3209167480468749 +0.215375 -0.334716796875 -0.492950439453125 0.3209167480468749 +0.2155 -0.335296630859375 -0.4937744140625 0.3209167480468749 +0.215625 -0.335296630859375 -0.4937744140625 0.3209167480468749 +0.21575 -0.3358154296875 -0.49456787109375 0.3209167480468749 +0.215875 -0.3358154296875 -0.49456787109375 0.3209167480468749 +0.216 -0.3363037109375 -0.49530029296875 0.3209167480468749 +0.216125 -0.3367919921875 -0.496002197265625 0.3209167480468749 +0.21625 -0.3367919921875 -0.496002197265625 0.3209167480468749 +0.216375 -0.33721923828125 -0.496612548828125 0.3209167480468749 +0.2165 -0.33721923828125 -0.496612548828125 0.3209167480468749 +0.216625 -0.337615966796875 -0.4971923828125 0.3209167480468749 +0.21675 -0.33795166015625 -0.497711181640625 0.3209167480468749 +0.216875 -0.33795166015625 -0.497711181640625 0.3209167480468749 +0.217 -0.338287353515625 -0.498199462890625 0.3209167480468749 +0.217125 -0.338287353515625 -0.498199462890625 0.3209167480468749 +0.21725 -0.33856201171875 -0.49859619140625 0.3209167480468749 +0.217375 -0.33880615234375 -0.49896240234375 0.3209167480468749 +0.2175 -0.33880615234375 -0.49896240234375 0.3209167480468749 +0.217625 -0.3389892578125 -0.499267578125 0.3209167480468749 +0.21775 -0.3389892578125 -0.499267578125 0.3209167480468749 +0.217875 -0.33917236328125 -0.49951171875 0.3209167480468749 +0.218 -0.33929443359375 -0.49969482421875 0.3209167480468749 +0.218125 -0.33929443359375 -0.49969482421875 0.3209167480468749 +0.21825 -0.339385986328125 -0.49981689453125 0.3209167480468749 +0.218375 -0.339385986328125 -0.49981689453125 0.3209167480468749 +0.2185 -0.339447021484375 -0.499908447265625 0.3209167480468749 +0.218625 -0.3394775390625 -0.49993896484375 0.3209167480468749 +0.21875 -0.3394775390625 -0.49993896484375 0.3209167480468749 +0.2188750000000000256 -0.339447021484375 -0.499908447265625 0.3209167480468749 +0.219 -0.339447021484375 -0.499908447265625 0.3209167480468749 +0.2191250000000000256 -0.339385986328125 -0.49981689453125 0.3209167480468749 +0.21925 -0.33929443359375 -0.49969482421875 0.3209167480468749 +0.2193750000000000256 -0.33929443359375 -0.49969482421875 0.3209167480468749 +0.2195 -0.33917236328125 -0.49951171875 0.3209167480468749 +0.2196250000000000256 -0.33917236328125 -0.49951171875 0.3209167480468749 +0.21975 -0.3389892578125 -0.499267578125 0.3209167480468749 +0.2198750000000000256 -0.33880615234375 -0.49896240234375 0.3209167480468749 +0.22 -0.33880615234375 -0.49896240234375 0.3209167480468749 +0.2201250000000000256 -0.33856201171875 -0.49859619140625 0.3209167480468749 +0.22025 -0.33856201171875 -0.49859619140625 0.3209167480468749 +0.2203750000000000256 -0.338287353515625 -0.498199462890625 0.3209167480468749 +0.2205 -0.33795166015625 -0.497711181640625 0.3209167480468749 +0.2206250000000000256 -0.33795166015625 -0.497711181640625 0.3209167480468749 +0.22075 -0.337615966796875 -0.4971923828125 0.3209167480468749 +0.2208750000000000256 -0.337615966796875 -0.4971923828125 0.3209167480468749 +0.221 -0.33721923828125 -0.496612548828125 0.3209167480468749 +0.2211250000000000256 -0.3367919921875 -0.496002197265625 0.3209167480468749 +0.22125 -0.3367919921875 -0.496002197265625 0.3209167480468749 +0.2213750000000000256 -0.3363037109375 -0.49530029296875 0.3209167480468749 +0.2215 -0.3363037109375 -0.49530029296875 0.3209167480468749 +0.2216250000000000256 -0.3358154296875 -0.49456787109375 0.3209167480468749 +0.22175 -0.335296630859375 -0.4937744140625 0.3209167480468749 +0.2218750000000000256 -0.335296630859375 -0.4937744140625 0.3209167480468749 +0.222 -0.334716796875 -0.492950439453125 0.3209167480468749 +0.2221250000000000256 -0.334716796875 -0.492950439453125 0.3209167480468749 +0.22225 -0.3341064453125 -0.492034912109375 0.3209167480468749 +0.2223750000000000256 -0.33343505859375 -0.4910888671875 0.3209167480468749 +0.2225 -0.33343505859375 -0.4910888671875 0.3209167480468749 +0.2226250000000000256 -0.332763671875 -0.490081787109375 0.3209167480468749 +0.22275 -0.332763671875 -0.490081787109375 0.3209167480468749 +0.2228750000000000256 -0.33203125 -0.489013671875 0.3209167480468749 +0.223 -0.331268310546875 -0.487884521484375 0.3209167480468749 +0.2231250000000000256 -0.331268310546875 -0.487884521484375 0.3209167480468749 +0.22325 -0.33050537109375 -0.486724853515625 0.3209167480468749 +0.2233750000000000256 -0.33050537109375 -0.486724853515625 0.3209167480468749 +0.2235 -0.329681396484375 -0.485504150390625 0.3209167480468749 +0.223625000000000032 -0.32879638671875 -0.484222412109375 0.3209167480468749 +0.22375 -0.32879638671875 -0.484222412109375 0.3209167480468749 +0.223875000000000032 -0.327880859375 -0.48291015625 0.3209167480468749 +0.224 -0.48291015625 -0.446533203125 -0.07529907226562488 +0.224125 -0.48150634765625 -0.44525146484375 -0.07529907226562488 +0.22425 -0.480072021484375 -0.44390869140625 -0.07529907226562488 +0.224375 -0.480072021484375 -0.44390869140625 -0.07529907226562488 +0.2245 -0.478607177734375 -0.442535400390625 -0.07529907226562488 +0.224625 -0.478607177734375 -0.442535400390625 -0.07529907226562488 +0.22475 -0.47705078125 -0.441131591796875 -0.07529907226562488 +0.224875 -0.4754638671875 -0.43963623046875 -0.07529907226562488 +0.225 -0.4754638671875 -0.43963623046875 -0.07529907226562488 +0.225125 -0.47381591796875 -0.438140869140625 -0.07529907226562488 +0.22525 -0.47381591796875 -0.438140869140625 -0.07529907226562488 +0.225375 -0.472137451171875 -0.436553955078125 -0.07529907226562488 +0.2255 -0.470367431640625 -0.4349365234375 -0.07529907226562488 +0.225625 -0.470367431640625 -0.4349365234375 -0.07529907226562488 +0.22575 -0.46856689453125 -0.43328857421875 -0.07529907226562488 +0.225875 -0.46856689453125 -0.43328857421875 -0.07529907226562488 +0.226 -0.46673583984375 -0.43157958984375 -0.07529907226562488 +0.226125 -0.464813232421875 -0.4298095703125 -0.07529907226562488 +0.22625 -0.464813232421875 -0.4298095703125 -0.07529907226562488 +0.226375 -0.462890625 -0.428009033203125 -0.07529907226562488 +0.2265 -0.462890625 -0.428009033203125 -0.07529907226562488 +0.226625 -0.46087646484375 -0.4261474609375 -0.07529907226562488 +0.22675 -0.458831787109375 -0.42425537109375 -0.07529907226562488 +0.226875 -0.458831787109375 -0.42425537109375 -0.07529907226562488 +0.227 -0.45672607421875 -0.42230224609375 -0.07529907226562488 +0.227125 -0.45672607421875 -0.42230224609375 -0.07529907226562488 +0.22725 -0.454559326171875 -0.420318603515625 -0.07529907226562488 +0.227375 -0.452362060546875 -0.41827392578125 -0.07529907226562488 +0.2275 -0.452362060546875 -0.41827392578125 -0.07529907226562488 +0.227625 -0.450103759765625 -0.41619873046875 -0.07529907226562488 +0.22775 -0.450103759765625 -0.41619873046875 -0.07529907226562488 +0.227875 -0.447784423828125 -0.4140625 -0.07529907226562488 +0.228 -0.4454345703125 -0.411895751953125 -0.07529907226562488 +0.228125 -0.4454345703125 -0.411895751953125 -0.07529907226562488 +0.22825 -0.44305419921875 -0.40966796875 -0.07529907226562488 +0.228375 -0.44305419921875 -0.40966796875 -0.07529907226562488 +0.2285 -0.440582275390625 -0.40740966796875 -0.07529907226562488 +0.228625 -0.438079833984375 -0.40509033203125 -0.07529907226562488 +0.22875 -0.438079833984375 -0.40509033203125 -0.07529907226562488 +0.228875 -0.435546875 -0.402740478515625 -0.07529907226562488 +0.229 -0.435546875 -0.402740478515625 -0.07529907226562488 +0.229125 -0.432952880859375 -0.40032958984375 -0.07529907226562488 +0.22925 -0.4302978515625 -0.39788818359375 -0.07529907226562488 +0.229375 -0.4302978515625 -0.39788818359375 -0.07529907226562488 +0.2295 -0.4276123046875 -0.395416259765625 -0.07529907226562488 +0.229625 -0.4276123046875 -0.395416259765625 -0.07529907226562488 +0.22975 -0.424896240234375 -0.39288330078125 -0.07529907226562488 +0.229875 -0.422119140625 -0.39031982421875 -0.07529907226562488 +0.23 -0.422119140625 -0.39031982421875 -0.07529907226562488 +0.230125 -0.419281005859375 -0.3876953125 -0.07529907226562488 +0.23025 -0.419281005859375 -0.3876953125 -0.07529907226562488 +0.230375 -0.416412353515625 -0.385040283203125 -0.07529907226562488 +0.2305 -0.413482666015625 -0.38232421875 -0.07529907226562488 +0.230625 -0.413482666015625 -0.38232421875 -0.07529907226562488 +0.23075 -0.4105224609375 -0.37957763671875 -0.07529907226562488 +0.230875 -0.4105224609375 -0.37957763671875 -0.07529907226562488 +0.231 -0.407501220703125 -0.376800537109375 -0.07529907226562488 +0.231125 -0.404449462890625 -0.373992919921875 -0.07529907226562488 +0.23125 -0.404449462890625 -0.373992919921875 -0.07529907226562488 +0.231375 -0.401336669921875 -0.371124267578125 -0.07529907226562488 +0.2315 -0.401336669921875 -0.371124267578125 -0.07529907226562488 +0.231625 -0.398193359375 -0.368194580078125 -0.07529907226562488 +0.23175 -0.39501953125 -0.365264892578125 -0.07529907226562488 +0.231875 -0.39501953125 -0.365264892578125 -0.07529907226562488 +0.232 -0.39178466796875 -0.362274169921875 -0.07529907226562488 +0.232125 -0.39178466796875 -0.362274169921875 -0.07529907226562488 +0.23225 -0.388519287109375 -0.3592529296875 -0.07529907226562488 +0.232375 -0.38519287109375 -0.356170654296875 -0.07529907226562488 +0.2325 -0.38519287109375 -0.356170654296875 -0.07529907226562488 +0.232625 -0.3818359375 -0.35308837890625 -0.07529907226562488 +0.23275 -0.3818359375 -0.35308837890625 -0.07529907226562488 +0.232875 -0.378448486328125 -0.349945068359375 -0.07529907226562488 +0.233 -0.375 -0.34674072265625 -0.07529907226562488 +0.233125 -0.375 -0.34674072265625 -0.07529907226562488 +0.23325 -0.37152099609375 -0.343536376953125 -0.07529907226562488 +0.233375 -0.37152099609375 -0.343536376953125 -0.07529907226562488 +0.2335 -0.36798095703125 -0.34027099609375 -0.07529907226562488 +0.233625 -0.36444091796875 -0.33697509765625 -0.07529907226562488 +0.23375 -0.36444091796875 -0.33697509765625 -0.07529907226562488 +0.233875 -0.360809326171875 -0.333648681640625 -0.07529907226562488 +0.234 -0.360809326171875 -0.333648681640625 -0.07529907226562488 +0.234125 -0.357177734375 -0.330291748046875 -0.07529907226562488 +0.23425 -0.353485107421875 -0.326873779296875 -0.07529907226562488 +0.234375 -0.353485107421875 -0.326873779296875 -0.07529907226562488 +0.234500000000000026 -0.349761962890625 -0.32342529296875 -0.07529907226562488 +0.234625 -0.349761962890625 -0.32342529296875 -0.07529907226562488 +0.234750000000000026 -0.34600830078125 -0.3199462890625 -0.07529907226562488 +0.234875 -0.34222412109375 -0.316436767578125 -0.07529907226562488 +0.235000000000000026 -0.34222412109375 -0.316436767578125 -0.07529907226562488 +0.235125 -0.33837890625 -0.312896728515625 -0.07529907226562488 +0.235250000000000026 -0.33837890625 -0.312896728515625 -0.07529907226562488 +0.235375 -0.334503173828125 -0.309326171875 -0.07529907226562488 +0.235500000000000026 -0.330596923828125 -0.305694580078125 -0.07529907226562488 +0.235625 -0.330596923828125 -0.305694580078125 -0.07529907226562488 +0.235750000000000026 -0.32666015625 -0.30206298828125 -0.07529907226562488 +0.235875 -0.32666015625 -0.30206298828125 -0.07529907226562488 +0.236000000000000026 -0.322662353515625 -0.298370361328125 -0.07529907226562488 +0.236125 -0.31866455078125 -0.294647216796875 -0.07529907226562488 +0.236250000000000026 -0.31866455078125 -0.294647216796875 -0.07529907226562488 +0.236375 -0.314605712890625 -0.2908935546875 -0.07529907226562488 +0.236500000000000026 -0.314605712890625 -0.2908935546875 -0.07529907226562488 +0.236625 -0.310516357421875 -0.287139892578125 -0.07529907226562488 +0.236750000000000026 -0.306396484375 -0.2833251953125 -0.07529907226562488 +0.236875 -0.306396484375 -0.2833251953125 -0.07529907226562488 +0.237000000000000026 -0.30224609375 -0.27947998046875 -0.07529907226562488 +0.237125 -0.30224609375 -0.27947998046875 -0.07529907226562488 +0.237250000000000026 -0.298065185546875 -0.275604248046875 -0.07529907226562488 +0.237375 -0.2938232421875 -0.271697998046875 -0.07529907226562488 +0.237500000000000026 -0.2938232421875 -0.271697998046875 -0.07529907226562488 +0.237625 -0.289581298828125 -0.267791748046875 -0.07529907226562488 +0.237750000000000026 -0.289581298828125 -0.267791748046875 -0.07529907226562488 +0.237875 -0.285308837890625 -0.263824462890625 -0.07529907226562488 +0.238000000000000026 -0.280975341796875 -0.25982666015625 -0.07529907226562488 +0.238125 -0.280975341796875 -0.25982666015625 -0.07529907226562488 +0.238250000000000026 -0.276641845703125 -0.25579833984375 -0.07529907226562488 +0.238375 -0.276641845703125 -0.25579833984375 -0.07529907226562488 +0.238500000000000026 -0.27227783203125 -0.25177001953125 -0.07529907226562488 +0.238625 -0.267852783203125 -0.2476806640625 -0.07529907226562488 +0.238750000000000026 -0.267852783203125 -0.2476806640625 -0.07529907226562488 +0.238875 -0.263427734375 -0.24359130859375 -0.07529907226562488 +0.239000000000000026 -0.263427734375 -0.24359130859375 -0.07529907226562488 +0.239125 -0.25897216796875 -0.239471435546875 -0.07529907226562488 +0.239250000000000032 -0.25445556640625 -0.23529052734375 -0.07529907226562488 +0.239375 -0.25445556640625 -0.23529052734375 -0.07529907226562488 +0.239500000000000032 -0.249969482421875 -0.23114013671875 -0.07529907226562488 +0.239625 -0.249969482421875 -0.23114013671875 -0.07529907226562488 +0.239750000000000032 -0.24542236328125 -0.2269287109375 -0.07529907226562488 +0.239875 -0.2408447265625 -0.222686767578125 -0.07529907226562488 +0.24 -0.2408447265625 -0.222686767578125 -0.07529907226562488 +0.240125 -0.236236572265625 -0.21844482421875 -0.07529907226562488 +0.24025 -0.236236572265625 -0.21844482421875 -0.07529907226562488 +0.240375 -0.231597900390625 -0.214141845703125 -0.07529907226562488 +0.2405 -0.226959228515625 -0.2098388671875 -0.07529907226562488 +0.240625 -0.226959228515625 -0.2098388671875 -0.07529907226562488 +0.24075 -0.2222900390625 -0.205535888671875 -0.07529907226562488 +0.240875 -0.2222900390625 -0.205535888671875 -0.07529907226562488 +0.241 -0.21759033203125 -0.201202392578125 -0.07529907226562488 +0.241125 -0.212860107421875 -0.196807861328125 -0.07529907226562488 +0.24125 -0.212860107421875 -0.196807861328125 -0.07529907226562488 +0.241375 -0.208099365234375 -0.192413330078125 -0.07529907226562488 +0.2415 -0.208099365234375 -0.192413330078125 -0.07529907226562488 +0.241625 -0.203338623046875 -0.188018798828125 -0.07529907226562488 +0.24175 -0.19854736328125 -0.18359375 -0.07529907226562488 +0.241875 -0.19854736328125 -0.18359375 -0.07529907226562488 +0.242 -0.1937255859375 -0.179107666015625 -0.07529907226562488 +0.242125 -0.1937255859375 -0.179107666015625 -0.07529907226562488 +0.24225 -0.188873291015625 -0.174652099609375 -0.07529907226562488 +0.242375 -0.18402099609375 -0.170166015625 -0.07529907226562488 +0.2425 -0.18402099609375 -0.170166015625 -0.07529907226562488 +0.242625 -0.17913818359375 -0.1656494140625 -0.07529907226562488 +0.24275 -0.17913818359375 -0.1656494140625 -0.07529907226562488 +0.242875 -0.17425537109375 -0.1611328125 -0.07529907226562488 +0.243 -0.169342041015625 -0.156585693359375 -0.07529907226562488 +0.243125 -0.169342041015625 -0.156585693359375 -0.07529907226562488 +0.24325 -0.164398193359375 -0.152008056640625 -0.07529907226562488 +0.243375 -0.164398193359375 -0.152008056640625 -0.07529907226562488 +0.2435 -0.159454345703125 -0.147430419921875 -0.07529907226562488 +0.243625 -0.15447998046875 -0.142822265625 -0.07529907226562488 +0.24375 -0.15447998046875 -0.142822265625 -0.07529907226562488 +0.243875 -0.14947509765625 -0.138214111328125 -0.07529907226562488 +0.244 -0.14947509765625 -0.138214111328125 -0.07529907226562488 +0.244125 -0.14447021484375 -0.13360595703125 -0.07529907226562488 +0.24425 -0.13946533203125 -0.128936767578125 -0.07529907226562488 +0.244375 -0.13946533203125 -0.128936767578125 -0.07529907226562488 +0.2445 -0.134429931640625 -0.124298095703125 -0.07529907226562488 +0.244625 -0.134429931640625 -0.124298095703125 -0.07529907226562488 +0.24475 -0.129364013671875 -0.11962890625 -0.07529907226562488 +0.244875 -0.124298095703125 -0.11492919921875 -0.07529907226562488 +0.245 -0.124298095703125 -0.11492919921875 -0.07529907226562488 +0.245125 -0.119232177734375 -0.110260009765625 -0.07529907226562488 +0.24525 -0.119232177734375 -0.110260009765625 -0.07529907226562488 +0.245375 -0.1141357421875 -0.105560302734375 -0.07529907226562488 +0.2455 -0.109039306640625 -0.100830078125 -0.07529907226562488 +0.245625 -0.109039306640625 -0.100830078125 -0.07529907226562488 +0.24575 -0.103912353515625 -0.096099853515625 -0.07529907226562488 +0.245875 -0.103912353515625 -0.096099853515625 -0.07529907226562488 +0.246 -0.098785400390625 -0.091339111328125 -0.07529907226562488 +0.246125 -0.093658447265625 -0.08660888671875 -0.07529907226562488 +0.24625 -0.093658447265625 -0.08660888671875 -0.07529907226562488 +0.246375 -0.0885009765625 -0.08184814453125 -0.07529907226562488 +0.2465 -0.0885009765625 -0.08184814453125 -0.07529907226562488 +0.246625 -0.083343505859375 -0.07708740234375 -0.07529907226562488 +0.24675 -0.07818603515625 -0.072296142578125 -0.07529907226562488 +0.246875 -0.07818603515625 -0.072296142578125 -0.07529907226562488 +0.247 -0.072998046875 -0.0675048828125 -0.07529907226562488 +0.247125 -0.072998046875 -0.0675048828125 -0.07529907226562488 +0.24725 -0.06781005859375 -0.062713623046875 -0.07529907226562488 +0.247375 -0.0626220703125 -0.05792236328125 -0.07529907226562488 +0.2475 -0.0626220703125 -0.05792236328125 -0.07529907226562488 +0.247625 -0.05743408203125 -0.053131103515625 -0.07529907226562488 +0.24775 -0.05743408203125 -0.053131103515625 -0.07529907226562488 +0.247875 -0.05224609375 -0.048309326171875 -0.07529907226562488 +0.248 -0.047027587890625 -0.043487548828125 -0.07529907226562488 +0.248125 -0.047027587890625 -0.043487548828125 -0.07529907226562488 +0.24825 -0.04180908203125 -0.038665771484375 -0.07529907226562488 +0.248375 -0.04180908203125 -0.038665771484375 -0.07529907226562488 +0.2485 -0.036590576171875 -0.033843994140625 -0.07529907226562488 +0.248625 -0.0313720703125 -0.02899169921875 -0.07529907226562488 +0.24875 -0.0313720703125 -0.02899169921875 -0.07529907226562488 +0.248875 -0.026123046875 -0.024169921875 -0.07529907226562488 +0.249 -0.026123046875 -0.024169921875 -0.07529907226562488 +0.249125 -0.020904541015625 -0.01934814453125 -0.07529907226562488 +0.24925 -0.01568603515625 -0.014495849609375 -0.07529907226562488 +0.249375 -0.01568603515625 -0.014495849609375 -0.07529907226562488 +0.2495 -0.01043701171875 -0.009674072265625 -0.07529907226562488 +0.249625 -0.01043701171875 -0.009674072265625 -0.07529907226562488 +0.24975 -0.005218505859375 -0.00482177734375 -0.07529907226562488 +0.249875 0.0 0.0 -0.07529907226562488 +0.25 0.0 0.0 -0.07529907226562488 +0.250125 0.005218505859375 0.00482177734375 -0.07529907226562488 +0.25025000000000004 0.005218505859375 0.00482177734375 -0.07529907226562488 +0.250375 0.01043701171875 0.009674072265625 -0.07529907226562488 +0.2505 0.01568603515625 0.014495849609375 -0.07529907226562488 +0.250625 0.01568603515625 0.014495849609375 -0.07529907226562488 +0.25075000000000004 0.020904541015625 0.01934814453125 -0.07529907226562488 +0.250875 0.020904541015625 0.01934814453125 -0.07529907226562488 +0.251 0.026123046875 0.024169921875 -0.07529907226562488 +0.251125 0.0313720703125 0.02899169921875 -0.07529907226562488 +0.25125000000000004 0.0313720703125 0.02899169921875 -0.07529907226562488 +0.251375 0.036590576171875 0.033843994140625 -0.07529907226562488 +0.2515 0.036590576171875 0.033843994140625 -0.07529907226562488 +0.251625 0.04180908203125 0.038665771484375 -0.07529907226562488 +0.25175000000000004 0.047027587890625 0.043487548828125 -0.07529907226562488 +0.251875 0.047027587890625 0.043487548828125 -0.07529907226562488 +0.252 0.05224609375 0.048309326171875 -0.07529907226562488 +0.252125 0.05224609375 0.048309326171875 -0.07529907226562488 +0.25225000000000004 0.05743408203125 0.053131103515625 -0.07529907226562488 +0.252375 0.0626220703125 0.05792236328125 -0.07529907226562488 +0.2525 0.0626220703125 0.05792236328125 -0.07529907226562488 +0.252625 0.06781005859375 0.062713623046875 -0.07529907226562488 +0.25275000000000004 0.06781005859375 0.062713623046875 -0.07529907226562488 +0.252875 0.072998046875 0.0675048828125 -0.07529907226562488 +0.253 0.07818603515625 0.072296142578125 -0.07529907226562488 +0.253125 0.07818603515625 0.072296142578125 -0.07529907226562488 +0.25325000000000004 0.083343505859375 0.07708740234375 -0.07529907226562488 +0.253375 0.083343505859375 0.07708740234375 -0.07529907226562488 +0.2535 0.0885009765625 0.08184814453125 -0.07529907226562488 +0.253625 0.093658447265625 0.08660888671875 -0.07529907226562488 +0.25375000000000004 0.093658447265625 0.08660888671875 -0.07529907226562488 +0.253875 0.098785400390625 0.091339111328125 -0.07529907226562488 +0.254 0.098785400390625 0.091339111328125 -0.07529907226562488 +0.254125 0.103912353515625 0.096099853515625 -0.07529907226562488 +0.25425000000000004 0.109039306640625 0.100830078125 -0.07529907226562488 +0.254375 0.109039306640625 0.100830078125 -0.07529907226562488 +0.2545 0.1141357421875 0.105560302734375 -0.07529907226562488 +0.254625 0.1141357421875 0.105560302734375 -0.07529907226562488 +0.25475000000000004 0.119232177734375 0.110260009765625 -0.07529907226562488 +0.254875 0.124298095703125 0.11492919921875 -0.07529907226562488 +0.255 0.124298095703125 0.11492919921875 -0.07529907226562488 +0.255125 0.129364013671875 0.11962890625 -0.07529907226562488 +0.25525000000000004 0.129364013671875 0.11962890625 -0.07529907226562488 +0.255375 0.134429931640625 0.124298095703125 -0.07529907226562488 +0.2555 0.13946533203125 0.128936767578125 -0.07529907226562488 +0.255625 0.13946533203125 0.128936767578125 -0.07529907226562488 +0.25575000000000004 0.14447021484375 0.13360595703125 -0.07529907226562488 +0.255875 0.14447021484375 0.13360595703125 -0.07529907226562488 +0.256 0.14947509765625 0.080780029296875 -0.4595336914062502 +0.256125 0.15447998046875 0.083465576171875 -0.4595336914062502 +0.25625 0.15447998046875 0.083465576171875 -0.4595336914062502 +0.256375 0.159454345703125 0.086151123046875 -0.4595336914062502 +0.2565 0.159454345703125 0.086151123046875 -0.4595336914062502 +0.256625 0.164398193359375 0.088836669921875 -0.4595336914062502 +0.25675 0.169342041015625 0.09149169921875 -0.4595336914062502 +0.256875 0.169342041015625 0.09149169921875 -0.4595336914062502 +0.257 0.17425537109375 0.094146728515625 -0.4595336914062502 +0.257125 0.17425537109375 0.094146728515625 -0.4595336914062502 +0.25725 0.17913818359375 0.0968017578125 -0.4595336914062502 +0.257375 0.18402099609375 0.099456787109375 -0.4595336914062502 +0.2575 0.18402099609375 0.099456787109375 -0.4595336914062502 +0.257625 0.188873291015625 0.10205078125 -0.4595336914062502 +0.25775 0.188873291015625 0.10205078125 -0.4595336914062502 +0.257875 0.1937255859375 0.10467529296875 -0.4595336914062502 +0.258 0.19854736328125 0.107269287109375 -0.4595336914062502 +0.258125 0.19854736328125 0.107269287109375 -0.4595336914062502 +0.25825 0.203338623046875 0.10986328125 -0.4595336914062502 +0.258375 0.203338623046875 0.10986328125 -0.4595336914062502 +0.2585 0.208099365234375 0.112457275390625 -0.4595336914062502 +0.258625 0.212860107421875 0.115020751953125 -0.4595336914062502 +0.25875 0.212860107421875 0.115020751953125 -0.4595336914062502 +0.258875 0.21759033203125 0.117584228515625 -0.4595336914062502 +0.259 0.21759033203125 0.117584228515625 -0.4595336914062502 +0.259125 0.2222900390625 0.1201171875 -0.4595336914062502 +0.25925 0.226959228515625 0.122650146484375 -0.4595336914062502 +0.259375 0.226959228515625 0.122650146484375 -0.4595336914062502 +0.2595 0.231597900390625 0.125152587890625 -0.4595336914062502 +0.259625 0.231597900390625 0.125152587890625 -0.4595336914062502 +0.25975 0.236236572265625 0.127655029296875 -0.4595336914062502 +0.259875 0.2408447265625 0.130126953125 -0.4595336914062502 +0.26 0.2408447265625 0.130126953125 -0.4595336914062502 +0.260125 0.24542236328125 0.132598876953125 -0.4595336914062502 +0.26025 0.24542236328125 0.132598876953125 -0.4595336914062502 +0.260375 0.249969482421875 0.13507080078125 -0.4595336914062502 +0.2605 0.25445556640625 0.13751220703125 -0.4595336914062502 +0.260625 0.25445556640625 0.13751220703125 -0.4595336914062502 +0.26075 0.25897216796875 0.13995361328125 -0.4595336914062502 +0.260875 0.25897216796875 0.13995361328125 -0.4595336914062502 +0.261 0.263427734375 0.142364501953125 -0.4595336914062502 +0.261125 0.267852783203125 0.144744873046875 -0.4595336914062502 +0.26125 0.267852783203125 0.144744873046875 -0.4595336914062502 +0.261375 0.27227783203125 0.147125244140625 -0.4595336914062502 +0.2615 0.27227783203125 0.147125244140625 -0.4595336914062502 +0.261625 0.276641845703125 0.149505615234375 -0.4595336914062502 +0.26175 0.280975341796875 0.15185546875 -0.4595336914062502 +0.261875 0.280975341796875 0.15185546875 -0.4595336914062502 +0.262 0.285308837890625 0.1541748046875 -0.4595336914062502 +0.262125 0.285308837890625 0.1541748046875 -0.4595336914062502 +0.26225 0.289581298828125 0.156494140625 -0.4595336914062502 +0.262375 0.2938232421875 0.158782958984375 -0.4595336914062502 +0.2625 0.2938232421875 0.158782958984375 -0.4595336914062502 +0.262625 0.298065185546875 0.16107177734375 -0.4595336914062502 +0.26275 0.298065185546875 0.16107177734375 -0.4595336914062502 +0.262875 0.30224609375 0.163330078125 -0.4595336914062502 +0.263 0.306396484375 0.16558837890625 -0.4595336914062502 +0.263125 0.306396484375 0.16558837890625 -0.4595336914062502 +0.26325 0.310516357421875 0.167816162109375 -0.4595336914062502 +0.263375 0.310516357421875 0.167816162109375 -0.4595336914062502 +0.2635 0.314605712890625 0.170013427734375 -0.4595336914062502 +0.263625 0.31866455078125 0.172210693359375 -0.4595336914062502 +0.26375 0.31866455078125 0.172210693359375 -0.4595336914062502 +0.263875 0.322662353515625 0.17437744140625 -0.4595336914062502 +0.264 0.322662353515625 0.17437744140625 -0.4595336914062502 +0.264125 0.32666015625 0.176513671875 -0.4595336914062502 +0.26425 0.330596923828125 0.17864990234375 -0.4595336914062502 +0.264375 0.330596923828125 0.17864990234375 -0.4595336914062502 +0.2645 0.334503173828125 0.180755615234375 -0.4595336914062502 +0.264625 0.334503173828125 0.180755615234375 -0.4595336914062502 +0.26475 0.33837890625 0.182861328125 -0.4595336914062502 +0.264875 0.34222412109375 0.1849365234375 -0.4595336914062502 +0.265 0.34222412109375 0.1849365234375 -0.4595336914062502 +0.265125 0.34600830078125 0.186981201171875 -0.4595336914062502 +0.26525 0.34600830078125 0.186981201171875 -0.4595336914062502 +0.265375 0.349761962890625 0.18902587890625 -0.4595336914062502 +0.2655 0.353485107421875 0.191009521484375 -0.4595336914062502 +0.265625 0.353485107421875 0.191009521484375 -0.4595336914062502 +0.26575 0.357177734375 0.193023681640625 -0.4595336914062502 +0.26587500000000004 0.357177734375 0.193023681640625 -0.4595336914062502 +0.266 0.360809326171875 0.194976806640625 -0.4595336914062502 +0.266125 0.36444091796875 0.196929931640625 -0.4595336914062502 +0.26625 0.36444091796875 0.196929931640625 -0.4595336914062502 +0.26637500000000004 0.36798095703125 0.1988525390625 -0.4595336914062502 +0.2665 0.36798095703125 0.1988525390625 -0.4595336914062502 +0.266625 0.37152099609375 0.200775146484375 -0.4595336914062502 +0.26675 0.375 0.20263671875 -0.4595336914062502 +0.26687500000000004 0.375 0.20263671875 -0.4595336914062502 +0.267 0.378448486328125 0.204498291015625 -0.4595336914062502 +0.267125 0.378448486328125 0.204498291015625 -0.4595336914062502 +0.26725 0.3818359375 0.206329345703125 -0.4595336914062502 +0.26737500000000004 0.38519287109375 0.208160400390625 -0.4595336914062502 +0.2675 0.38519287109375 0.208160400390625 -0.4595336914062502 +0.267625 0.388519287109375 0.2099609375 -0.4595336914062502 +0.26775 0.388519287109375 0.2099609375 -0.4595336914062502 +0.26787500000000004 0.39178466796875 0.21173095703125 -0.4595336914062502 +0.268 0.39501953125 0.213470458984375 -0.4595336914062502 +0.268125 0.39501953125 0.213470458984375 -0.4595336914062502 +0.26825 0.398193359375 0.215179443359375 -0.4595336914062502 +0.26837500000000004 0.398193359375 0.215179443359375 -0.4595336914062502 +0.2685 0.401336669921875 0.216888427734375 -0.4595336914062502 +0.268625 0.404449462890625 0.21856689453125 -0.4595336914062502 +0.26875 0.404449462890625 0.21856689453125 -0.4595336914062502 +0.26887500000000004 0.407501220703125 0.22021484375 -0.4595336914062502 +0.269 0.407501220703125 0.22021484375 -0.4595336914062502 +0.269125 0.4105224609375 0.221832275390625 -0.4595336914062502 +0.26925 0.413482666015625 0.22344970703125 -0.4595336914062502 +0.26937500000000004 0.413482666015625 0.22344970703125 -0.4595336914062502 +0.2695 0.416412353515625 0.225006103515625 -0.4595336914062502 +0.269625 0.416412353515625 0.225006103515625 -0.4595336914062502 +0.26975 0.419281005859375 0.2265625 -0.4595336914062502 +0.26987500000000004 0.422119140625 0.228118896484375 -0.4595336914062502 +0.27 0.422119140625 0.228118896484375 -0.4595336914062502 +0.270125 0.424896240234375 0.2296142578125 -0.4595336914062502 +0.27025 0.424896240234375 0.2296142578125 -0.4595336914062502 +0.27037500000000004 0.4276123046875 0.2310791015625 -0.4595336914062502 +0.2705 0.4302978515625 0.2325439453125 -0.4595336914062502 +0.270625 0.4302978515625 0.2325439453125 -0.4595336914062502 +0.27075 0.432952880859375 0.233978271484375 -0.4595336914062502 +0.27087500000000004 0.432952880859375 0.233978271484375 -0.4595336914062502 +0.271 0.435546875 0.235382080078125 -0.4595336914062502 +0.271125 0.438079833984375 0.236724853515625 -0.4595336914062502 +0.27125 0.438079833984375 0.236724853515625 -0.4595336914062502 +0.27137500000000004 0.440582275390625 0.23809814453125 -0.4595336914062502 +0.2715 0.440582275390625 0.23809814453125 -0.4595336914062502 +0.271625 0.44305419921875 0.239410400390625 -0.4595336914062502 +0.27175 0.4454345703125 0.24072265625 -0.4595336914062502 +0.27187500000000004 0.4454345703125 0.24072265625 -0.4595336914062502 +0.272 0.447784423828125 0.241973876953125 -0.4595336914062502 +0.272125 0.447784423828125 0.241973876953125 -0.4595336914062502 +0.27225 0.450103759765625 0.24322509765625 -0.4595336914062502 +0.272375 0.452362060546875 0.24444580078125 -0.4595336914062502 +0.2725 0.452362060546875 0.24444580078125 -0.4595336914062502 +0.272625 0.454559326171875 0.245635986328125 -0.4595336914062502 +0.27275 0.454559326171875 0.245635986328125 -0.4595336914062502 +0.272875 0.45672607421875 0.246795654296875 -0.4595336914062502 +0.273 0.458831787109375 0.247955322265625 -0.4595336914062502 +0.273125 0.458831787109375 0.247955322265625 -0.4595336914062502 +0.27325 0.46087646484375 0.249053955078125 -0.4595336914062502 +0.273375 0.46087646484375 0.249053955078125 -0.4595336914062502 +0.2735 0.462890625 0.2501220703125 -0.4595336914062502 +0.273625 0.464813232421875 0.251190185546875 -0.4595336914062502 +0.27375 0.464813232421875 0.251190185546875 -0.4595336914062502 +0.273875 0.46673583984375 0.252227783203125 -0.4595336914062502 +0.274 0.46673583984375 0.252227783203125 -0.4595336914062502 +0.274125 0.46856689453125 0.253204345703125 -0.4595336914062502 +0.27425 0.470367431640625 0.254180908203125 -0.4595336914062502 +0.274375 0.470367431640625 0.254180908203125 -0.4595336914062502 +0.2745 0.472137451171875 0.255126953125 -0.4595336914062502 +0.274625 0.472137451171875 0.255126953125 -0.4595336914062502 +0.27475 0.47381591796875 0.25604248046875 -0.4595336914062502 +0.274875 0.4754638671875 0.256927490234375 -0.4595336914062502 +0.275 0.4754638671875 0.256927490234375 -0.4595336914062502 +0.275125 0.47705078125 0.257781982421875 -0.4595336914062502 +0.27525 0.47705078125 0.257781982421875 -0.4595336914062502 +0.275375 0.478607177734375 0.258636474609375 -0.4595336914062502 +0.2755 0.480072021484375 0.259429931640625 -0.4595336914062502 +0.275625 0.480072021484375 0.259429931640625 -0.4595336914062502 +0.27575 0.48150634765625 0.26019287109375 -0.4595336914062502 +0.275875 0.48150634765625 0.26019287109375 -0.4595336914062502 +0.276 0.48291015625 0.260955810546875 -0.4595336914062502 +0.276125 0.484222412109375 0.26165771484375 -0.4595336914062502 +0.27625 0.484222412109375 0.26165771484375 -0.4595336914062502 +0.276375 0.485504150390625 0.262359619140625 -0.4595336914062502 +0.2765 0.485504150390625 0.262359619140625 -0.4595336914062502 +0.276625 0.486724853515625 0.263031005859375 -0.4595336914062502 +0.27675 0.487884521484375 0.263641357421875 -0.4595336914062502 +0.276875 0.487884521484375 0.263641357421875 -0.4595336914062502 +0.277 0.489013671875 0.264251708984375 -0.4595336914062502 +0.277125 0.489013671875 0.264251708984375 -0.4595336914062502 +0.27725 0.490081787109375 0.26483154296875 -0.4595336914062502 +0.277375 0.4910888671875 0.265380859375 -0.4595336914062502 +0.2775 0.4910888671875 0.265380859375 -0.4595336914062502 +0.277625 0.492034912109375 0.265899658203125 -0.4595336914062502 +0.27775 0.492034912109375 0.265899658203125 -0.4595336914062502 +0.277875 0.492950439453125 0.266387939453125 -0.4595336914062502 +0.278 0.4937744140625 0.266845703125 -0.4595336914062502 +0.278125 0.4937744140625 0.266845703125 -0.4595336914062502 +0.27825 0.49456787109375 0.26727294921875 -0.4595336914062502 +0.278375 0.49456787109375 0.26727294921875 -0.4595336914062502 +0.2785 0.49530029296875 0.267669677734375 -0.4595336914062502 +0.278625 0.496002197265625 0.268035888671875 -0.4595336914062502 +0.27875 0.496002197265625 0.268035888671875 -0.4595336914062502 +0.278875 0.496612548828125 0.26837158203125 -0.4595336914062502 +0.279 0.496612548828125 0.26837158203125 -0.4595336914062502 +0.279125 0.4971923828125 0.2686767578125 -0.4595336914062502 +0.27925 0.497711181640625 0.268951416015625 -0.4595336914062502 +0.279375 0.497711181640625 0.268951416015625 -0.4595336914062502 +0.2795 0.498199462890625 0.26922607421875 -0.4595336914062502 +0.279625 0.498199462890625 0.26922607421875 -0.4595336914062502 +0.27975 0.49859619140625 0.269439697265625 -0.4595336914062502 +0.279875 0.49896240234375 0.269622802734375 -0.4595336914062502 +0.28 0.49896240234375 0.269622802734375 -0.4595336914062502 +0.280125 0.499267578125 0.269805908203125 -0.4595336914062502 +0.28025 0.499267578125 0.269805908203125 -0.4595336914062502 +0.280375 0.49951171875 0.269927978515625 -0.4595336914062502 +0.2805 0.49969482421875 0.27001953125 -0.4595336914062502 +0.280625 0.49969482421875 0.27001953125 -0.4595336914062502 +0.28075 0.49981689453125 0.270111083984375 -0.4595336914062502 +0.280875 0.49981689453125 0.270111083984375 -0.4595336914062502 +0.281 0.499908447265625 0.2701416015625 -0.4595336914062502 +0.281125 0.49993896484375 0.270172119140625 -0.4595336914062502 +0.28125 0.49993896484375 0.270172119140625 -0.4595336914062502 +0.281375 0.499908447265625 0.2701416015625 -0.4595336914062502 +0.28150000000000004 0.499908447265625 0.2701416015625 -0.4595336914062502 +0.281625 0.49981689453125 0.270111083984375 -0.4595336914062502 +0.28175 0.49969482421875 0.27001953125 -0.4595336914062502 +0.281875 0.49969482421875 0.27001953125 -0.4595336914062502 +0.28200000000000004 0.49951171875 0.269927978515625 -0.4595336914062502 +0.282125 0.49951171875 0.269927978515625 -0.4595336914062502 +0.28225 0.499267578125 0.269805908203125 -0.4595336914062502 +0.282375 0.49896240234375 0.269622802734375 -0.4595336914062502 +0.28250000000000004 0.49896240234375 0.269622802734375 -0.4595336914062502 +0.282625 0.49859619140625 0.269439697265625 -0.4595336914062502 +0.28275 0.49859619140625 0.269439697265625 -0.4595336914062502 +0.282875 0.498199462890625 0.26922607421875 -0.4595336914062502 +0.28300000000000004 0.497711181640625 0.268951416015625 -0.4595336914062502 +0.283125 0.497711181640625 0.268951416015625 -0.4595336914062502 +0.28325 0.4971923828125 0.2686767578125 -0.4595336914062502 +0.283375 0.4971923828125 0.2686767578125 -0.4595336914062502 +0.28350000000000004 0.496612548828125 0.26837158203125 -0.4595336914062502 +0.283625 0.496002197265625 0.268035888671875 -0.4595336914062502 +0.28375 0.496002197265625 0.268035888671875 -0.4595336914062502 +0.283875 0.49530029296875 0.267669677734375 -0.4595336914062502 +0.28400000000000004 0.49530029296875 0.267669677734375 -0.4595336914062502 +0.284125 0.49456787109375 0.26727294921875 -0.4595336914062502 +0.28425 0.4937744140625 0.266845703125 -0.4595336914062502 +0.284375 0.4937744140625 0.266845703125 -0.4595336914062502 +0.28450000000000004 0.492950439453125 0.266387939453125 -0.4595336914062502 +0.284625 0.492950439453125 0.266387939453125 -0.4595336914062502 +0.28475 0.492034912109375 0.265899658203125 -0.4595336914062502 +0.284875 0.4910888671875 0.265380859375 -0.4595336914062502 +0.28500000000000004 0.4910888671875 0.265380859375 -0.4595336914062502 +0.285125 0.490081787109375 0.26483154296875 -0.4595336914062502 +0.28525 0.490081787109375 0.26483154296875 -0.4595336914062502 +0.285375 0.489013671875 0.264251708984375 -0.4595336914062502 +0.28550000000000004 0.487884521484375 0.263641357421875 -0.4595336914062502 +0.285625 0.487884521484375 0.263641357421875 -0.4595336914062502 +0.28575 0.486724853515625 0.263031005859375 -0.4595336914062502 +0.285875 0.486724853515625 0.263031005859375 -0.4595336914062502 +0.28600000000000004 0.485504150390625 0.262359619140625 -0.4595336914062502 +0.286125 0.484222412109375 0.26165771484375 -0.4595336914062502 +0.28625 0.484222412109375 0.26165771484375 -0.4595336914062502 +0.286375 0.48291015625 0.260955810546875 -0.4595336914062502 +0.28650000000000004 0.48291015625 0.260955810546875 -0.4595336914062502 +0.286625 0.48150634765625 0.26019287109375 -0.4595336914062502 +0.28675 0.480072021484375 0.259429931640625 -0.4595336914062502 +0.286875 0.480072021484375 0.259429931640625 -0.4595336914062502 +0.28700000000000004 0.478607177734375 0.258636474609375 -0.4595336914062502 +0.287125 0.478607177734375 0.258636474609375 -0.4595336914062502 +0.28725 0.47705078125 0.257781982421875 -0.4595336914062502 +0.287375 0.4754638671875 0.256927490234375 -0.4595336914062502 +0.28750000000000004 0.4754638671875 0.256927490234375 -0.4595336914062502 +0.287625 0.47381591796875 0.25604248046875 -0.4595336914062502 +0.28775 0.47381591796875 0.25604248046875 -0.4595336914062502 +0.287875 0.472137451171875 0.255126953125 -0.4595336914062502 +0.28800000000000004 0.470367431640625 0.10791015625 -0.7704772949218753 +0.288125 0.470367431640625 0.10791015625 -0.7704772949218753 +0.28825 0.46856689453125 0.107513427734375 -0.7704772949218753 +0.288375 0.46856689453125 0.107513427734375 -0.7704772949218753 +0.2885 0.46673583984375 0.107086181640625 -0.7704772949218753 +0.288625 0.464813232421875 0.10662841796875 -0.7704772949218753 +0.28875 0.464813232421875 0.10662841796875 -0.7704772949218753 +0.288875 0.462890625 0.106201171875 -0.7704772949218753 +0.289 0.462890625 0.106201171875 -0.7704772949218753 +0.289125 0.46087646484375 0.105743408203125 -0.7704772949218753 +0.28925 0.458831787109375 0.105255126953125 -0.7704772949218753 +0.289375 0.458831787109375 0.105255126953125 -0.7704772949218753 +0.2895 0.45672607421875 0.104766845703125 -0.7704772949218753 +0.289625 0.45672607421875 0.104766845703125 -0.7704772949218753 +0.28975 0.454559326171875 0.104278564453125 -0.7704772949218753 +0.289875 0.452362060546875 0.103790283203125 -0.7704772949218753 +0.29 0.452362060546875 0.103790283203125 -0.7704772949218753 +0.290125 0.450103759765625 0.103271484375 -0.7704772949218753 +0.29025 0.450103759765625 0.103271484375 -0.7704772949218753 +0.290375 0.447784423828125 0.10272216796875 -0.7704772949218753 +0.2905 0.4454345703125 0.102203369140625 -0.7704772949218753 +0.290625 0.4454345703125 0.102203369140625 -0.7704772949218753 +0.29075 0.44305419921875 0.101654052734375 -0.7704772949218753 +0.290875 0.44305419921875 0.101654052734375 -0.7704772949218753 +0.291 0.440582275390625 0.10107421875 -0.7704772949218753 +0.291125 0.438079833984375 0.100494384765625 -0.7704772949218753 +0.29125 0.438079833984375 0.100494384765625 -0.7704772949218753 +0.291375 0.435546875 0.09991455078125 -0.7704772949218753 +0.2915 0.435546875 0.09991455078125 -0.7704772949218753 +0.291625 0.432952880859375 0.099334716796875 -0.7704772949218753 +0.29175 0.4302978515625 0.098724365234375 -0.7704772949218753 +0.291875 0.4302978515625 0.098724365234375 -0.7704772949218753 +0.292 0.4276123046875 0.098114013671875 -0.7704772949218753 +0.292125 0.4276123046875 0.098114013671875 -0.7704772949218753 +0.29225 0.424896240234375 0.09747314453125 -0.7704772949218753 +0.292375 0.422119140625 0.096832275390625 -0.7704772949218753 +0.2925 0.422119140625 0.096832275390625 -0.7704772949218753 +0.292625 0.419281005859375 0.09619140625 -0.7704772949218753 +0.29275 0.419281005859375 0.09619140625 -0.7704772949218753 +0.292875 0.416412353515625 0.09552001953125 -0.7704772949218753 +0.293 0.413482666015625 0.0948486328125 -0.7704772949218753 +0.293125 0.413482666015625 0.0948486328125 -0.7704772949218753 +0.29325 0.4105224609375 0.09417724609375 -0.7704772949218753 +0.293375 0.4105224609375 0.09417724609375 -0.7704772949218753 +0.2935 0.407501220703125 0.093475341796875 -0.7704772949218753 +0.293625 0.404449462890625 0.0927734375 -0.7704772949218753 +0.29375 0.404449462890625 0.0927734375 -0.7704772949218753 +0.293875 0.401336669921875 0.092071533203125 -0.7704772949218753 +0.294 0.401336669921875 0.092071533203125 -0.7704772949218753 +0.294125 0.398193359375 0.091339111328125 -0.7704772949218753 +0.29425 0.39501953125 0.09063720703125 -0.7704772949218753 +0.294375 0.39501953125 0.09063720703125 -0.7704772949218753 +0.2945 0.39178466796875 0.089874267578125 -0.7704772949218753 +0.294625 0.39178466796875 0.089874267578125 -0.7704772949218753 +0.29475 0.388519287109375 0.089141845703125 -0.7704772949218753 +0.294875 0.38519287109375 0.08837890625 -0.7704772949218753 +0.295 0.38519287109375 0.08837890625 -0.7704772949218753 +0.295125 0.3818359375 0.08758544921875 -0.7704772949218753 +0.29525 0.3818359375 0.08758544921875 -0.7704772949218753 +0.295375 0.378448486328125 0.086822509765625 -0.7704772949218753 +0.2955 0.375 0.086029052734375 -0.7704772949218753 +0.295625 0.375 0.086029052734375 -0.7704772949218753 +0.29575 0.37152099609375 0.085235595703125 -0.7704772949218753 +0.295875 0.37152099609375 0.085235595703125 -0.7704772949218753 +0.296 0.36798095703125 0.08441162109375 -0.7704772949218753 +0.296125 0.36444091796875 0.0836181640625 -0.7704772949218753 +0.29625 0.36444091796875 0.0836181640625 -0.7704772949218753 +0.296375 0.360809326171875 0.082763671875 -0.7704772949218753 +0.2965 0.360809326171875 0.082763671875 -0.7704772949218753 +0.296625 0.357177734375 0.081939697265625 -0.7704772949218753 +0.29675 0.353485107421875 0.081085205078125 -0.7704772949218753 +0.296875 0.353485107421875 0.081085205078125 -0.7704772949218753 +0.297 0.349761962890625 0.080230712890625 -0.7704772949218753 +0.29712500000000004 0.349761962890625 0.080230712890625 -0.7704772949218753 +0.29725 0.34600830078125 0.079376220703125 -0.7704772949218753 +0.297375 0.34222412109375 0.078521728515625 -0.7704772949218753 +0.2975 0.34222412109375 0.078521728515625 -0.7704772949218753 +0.29762500000000004 0.33837890625 0.07763671875 -0.7704772949218753 +0.29775 0.33837890625 0.07763671875 -0.7704772949218753 +0.297875 0.334503173828125 0.076751708984375 -0.7704772949218753 +0.298 0.330596923828125 0.075836181640625 -0.7704772949218753 +0.29812500000000004 0.330596923828125 0.075836181640625 -0.7704772949218753 +0.29825 0.32666015625 0.074951171875 -0.7704772949218753 +0.298375 0.32666015625 0.074951171875 -0.7704772949218753 +0.2985 0.322662353515625 0.07403564453125 -0.7704772949218753 +0.29862500000000004 0.31866455078125 0.073089599609375 -0.7704772949218753 +0.29875 0.31866455078125 0.073089599609375 -0.7704772949218753 +0.298875 0.314605712890625 0.072174072265625 -0.7704772949218753 +0.299 0.314605712890625 0.072174072265625 -0.7704772949218753 +0.29912500000000004 0.310516357421875 0.07122802734375 -0.7704772949218753 +0.29925 0.306396484375 0.070281982421875 -0.7704772949218753 +0.299375 0.306396484375 0.070281982421875 -0.7704772949218753 +0.2995 0.30224609375 0.0693359375 -0.7704772949218753 +0.29962500000000004 0.30224609375 0.0693359375 -0.7704772949218753 +0.29975 0.298065185546875 0.068389892578125 -0.7704772949218753 +0.299875 0.2938232421875 0.067413330078125 -0.7704772949218753 +0.3 0.2938232421875 0.067413330078125 -0.7704772949218753 +0.30012500000000004 0.289581298828125 0.066436767578125 -0.7704772949218753 +0.30025 0.289581298828125 0.066436767578125 -0.7704772949218753 +0.300375 0.285308837890625 0.065460205078125 -0.7704772949218753 +0.3005 0.280975341796875 0.064453125 -0.7704772949218753 +0.30062500000000004 0.280975341796875 0.064453125 -0.7704772949218753 +0.30075 0.276641845703125 0.0634765625 -0.7704772949218753 +0.300875 0.276641845703125 0.0634765625 -0.7704772949218753 +0.301 0.27227783203125 0.062469482421875 -0.7704772949218753 +0.30112500000000004 0.267852783203125 0.06146240234375 -0.7704772949218753 +0.30125 0.267852783203125 0.06146240234375 -0.7704772949218753 +0.301375 0.263427734375 0.0604248046875 -0.7704772949218753 +0.3015 0.263427734375 0.0604248046875 -0.7704772949218753 +0.30162500000000004 0.25897216796875 0.059417724609375 -0.7704772949218753 +0.30175 0.25445556640625 0.058380126953125 -0.7704772949218753 +0.301875 0.25445556640625 0.058380126953125 -0.7704772949218753 +0.302 0.249969482421875 0.057342529296875 -0.7704772949218753 +0.30212500000000004 0.249969482421875 0.057342529296875 -0.7704772949218753 +0.30225 0.24542236328125 0.056304931640625 -0.7704772949218753 +0.302375 0.2408447265625 0.05523681640625 -0.7704772949218753 +0.3025 0.2408447265625 0.05523681640625 -0.7704772949218753 +0.30262500000000004 0.236236572265625 0.05419921875 -0.7704772949218753 +0.30275 0.236236572265625 0.05419921875 -0.7704772949218753 +0.302875 0.231597900390625 0.053131103515625 -0.7704772949218753 +0.303 0.226959228515625 0.05206298828125 -0.7704772949218753 +0.30312500000000004 0.226959228515625 0.05206298828125 -0.7704772949218753 +0.30325 0.2222900390625 0.050994873046875 -0.7704772949218753 +0.303375 0.2222900390625 0.050994873046875 -0.7704772949218753 +0.3035 0.21759033203125 0.049896240234375 -0.7704772949218753 +0.30362500000000004 0.212860107421875 0.048828125 -0.7704772949218753 +0.30375 0.212860107421875 0.048828125 -0.7704772949218753 +0.303875 0.208099365234375 0.0477294921875 -0.7704772949218753 +0.304 0.208099365234375 0.0477294921875 -0.7704772949218753 +0.304125 0.203338623046875 0.046630859375 -0.7704772949218753 +0.30425 0.19854736328125 0.0455322265625 -0.7704772949218753 +0.304375 0.19854736328125 0.0455322265625 -0.7704772949218753 +0.3045 0.1937255859375 0.04443359375 -0.7704772949218753 +0.304625 0.1937255859375 0.04443359375 -0.7704772949218753 +0.30475 0.188873291015625 0.0433349609375 -0.7704772949218753 +0.304875 0.18402099609375 0.042205810546875 -0.7704772949218753 +0.305 0.18402099609375 0.042205810546875 -0.7704772949218753 +0.305125 0.17913818359375 0.04107666015625 -0.7704772949218753 +0.30525 0.17913818359375 0.04107666015625 -0.7704772949218753 +0.305375 0.17425537109375 0.03997802734375 -0.7704772949218753 +0.3055 0.169342041015625 0.038848876953125 -0.7704772949218753 +0.305625 0.169342041015625 0.038848876953125 -0.7704772949218753 +0.30575 0.164398193359375 0.0377197265625 -0.7704772949218753 +0.305875 0.164398193359375 0.0377197265625 -0.7704772949218753 +0.306 0.159454345703125 0.03656005859375 -0.7704772949218753 +0.306125 0.15447998046875 0.035430908203125 -0.7704772949218753 +0.30625 0.15447998046875 0.035430908203125 -0.7704772949218753 +0.306375 0.14947509765625 0.034271240234375 -0.7704772949218753 +0.3065 0.14947509765625 0.034271240234375 -0.7704772949218753 +0.306625 0.14447021484375 0.03314208984375 -0.7704772949218753 +0.30675 0.13946533203125 0.031982421875 -0.7704772949218753 +0.306875 0.13946533203125 0.031982421875 -0.7704772949218753 +0.307 0.134429931640625 0.03082275390625 -0.7704772949218753 +0.307125 0.134429931640625 0.03082275390625 -0.7704772949218753 +0.30725 0.129364013671875 0.0296630859375 -0.7704772949218753 +0.307375 0.124298095703125 0.02850341796875 -0.7704772949218753 +0.3075 0.124298095703125 0.02850341796875 -0.7704772949218753 +0.307625 0.119232177734375 0.02734375 -0.7704772949218753 +0.30775 0.119232177734375 0.02734375 -0.7704772949218753 +0.307875 0.1141357421875 0.02618408203125 -0.7704772949218753 +0.308 0.109039306640625 0.024993896484375 -0.7704772949218753 +0.308125 0.109039306640625 0.024993896484375 -0.7704772949218753 +0.30825 0.103912353515625 0.023834228515625 -0.7704772949218753 +0.308375 0.103912353515625 0.023834228515625 -0.7704772949218753 +0.3085 0.098785400390625 0.02264404296875 -0.7704772949218753 +0.308625 0.093658447265625 0.021484375 -0.7704772949218753 +0.30875 0.093658447265625 0.021484375 -0.7704772949218753 +0.308875 0.0885009765625 0.020294189453125 -0.7704772949218753 +0.309 0.0885009765625 0.020294189453125 -0.7704772949218753 +0.309125 0.083343505859375 0.01910400390625 -0.7704772949218753 +0.30925 0.07818603515625 0.017913818359375 -0.7704772949218753 +0.309375 0.07818603515625 0.017913818359375 -0.7704772949218753 +0.3095 0.072998046875 0.016754150390625 -0.7704772949218753 +0.309625 0.072998046875 0.016754150390625 -0.7704772949218753 +0.30975 0.06781005859375 0.01556396484375 -0.7704772949218753 +0.309875 0.0626220703125 0.014373779296875 -0.7704772949218753 +0.31 0.0626220703125 0.014373779296875 -0.7704772949218753 +0.310125 0.05743408203125 0.01318359375 -0.7704772949218753 +0.31025 0.05743408203125 0.01318359375 -0.7704772949218753 +0.310375 0.05224609375 0.011962890625 -0.7704772949218753 +0.3105 0.047027587890625 0.010772705078125 -0.7704772949218753 +0.310625 0.047027587890625 0.010772705078125 -0.7704772949218753 +0.31075 0.04180908203125 0.00958251953125 -0.7704772949218753 +0.310875 0.04180908203125 0.00958251953125 -0.7704772949218753 +0.311 0.036590576171875 0.008392333984375 -0.7704772949218753 +0.311125 0.0313720703125 0.007171630859375 -0.7704772949218753 +0.31125 0.0313720703125 0.007171630859375 -0.7704772949218753 +0.311375 0.026123046875 0.0059814453125 -0.7704772949218753 +0.3115 0.026123046875 0.0059814453125 -0.7704772949218753 +0.311625 0.020904541015625 0.004791259765625 -0.7704772949218753 +0.31175 0.01568603515625 0.00360107421875 -0.7704772949218753 +0.311875 0.01568603515625 0.00360107421875 -0.7704772949218753 +0.312 0.01043701171875 0.00238037109375 -0.7704772949218753 +0.312125 0.01043701171875 0.00238037109375 -0.7704772949218753 +0.31225 0.005218505859375 0.001190185546875 -0.7704772949218753 +0.312375 0.0 0.0 -0.7704772949218753 +0.3125 0.0 0.0 -0.7704772949218753 +0.312625 -0.005218505859375 -0.001190185546875 -0.7704772949218753 +0.31275000000000004 -0.005218505859375 -0.001190185546875 -0.7704772949218753 +0.312875 -0.01043701171875 -0.00238037109375 -0.7704772949218753 +0.313 -0.01568603515625 -0.00360107421875 -0.7704772949218753 +0.313125 -0.01568603515625 -0.00360107421875 -0.7704772949218753 +0.31325000000000004 -0.020904541015625 -0.004791259765625 -0.7704772949218753 +0.313375 -0.020904541015625 -0.004791259765625 -0.7704772949218753 +0.3135 -0.026123046875 -0.0059814453125 -0.7704772949218753 +0.313625 -0.0313720703125 -0.007171630859375 -0.7704772949218753 +0.31375000000000004 -0.0313720703125 -0.007171630859375 -0.7704772949218753 +0.313875 -0.036590576171875 -0.008392333984375 -0.7704772949218753 +0.314 -0.036590576171875 -0.008392333984375 -0.7704772949218753 +0.314125 -0.04180908203125 -0.00958251953125 -0.7704772949218753 +0.31425000000000004 -0.047027587890625 -0.010772705078125 -0.7704772949218753 +0.314375 -0.047027587890625 -0.010772705078125 -0.7704772949218753 +0.3145 -0.05224609375 -0.011962890625 -0.7704772949218753 +0.314625 -0.05224609375 -0.011962890625 -0.7704772949218753 +0.31475000000000004 -0.05743408203125 -0.01318359375 -0.7704772949218753 +0.314875 -0.0626220703125 -0.014373779296875 -0.7704772949218753 +0.315 -0.0626220703125 -0.014373779296875 -0.7704772949218753 +0.315125 -0.06781005859375 -0.01556396484375 -0.7704772949218753 +0.31525000000000004 -0.06781005859375 -0.01556396484375 -0.7704772949218753 +0.315375 -0.072998046875 -0.016754150390625 -0.7704772949218753 +0.3155 -0.07818603515625 -0.017913818359375 -0.7704772949218753 +0.315625 -0.07818603515625 -0.017913818359375 -0.7704772949218753 +0.31575000000000004 -0.083343505859375 -0.01910400390625 -0.7704772949218753 +0.315875 -0.083343505859375 -0.01910400390625 -0.7704772949218753 +0.316 -0.0885009765625 -0.020294189453125 -0.7704772949218753 +0.316125 -0.093658447265625 -0.021484375 -0.7704772949218753 +0.31625000000000004 -0.093658447265625 -0.021484375 -0.7704772949218753 +0.316375 -0.098785400390625 -0.02264404296875 -0.7704772949218753 +0.3165 -0.098785400390625 -0.02264404296875 -0.7704772949218753 +0.316625 -0.103912353515625 -0.023834228515625 -0.7704772949218753 +0.31675000000000004 -0.109039306640625 -0.024993896484375 -0.7704772949218753 +0.316875 -0.109039306640625 -0.024993896484375 -0.7704772949218753 +0.317 -0.1141357421875 -0.02618408203125 -0.7704772949218753 +0.317125 -0.1141357421875 -0.02618408203125 -0.7704772949218753 +0.31725000000000004 -0.119232177734375 -0.02734375 -0.7704772949218753 +0.317375 -0.124298095703125 -0.02850341796875 -0.7704772949218753 +0.3175 -0.124298095703125 -0.02850341796875 -0.7704772949218753 +0.317625 -0.129364013671875 -0.0296630859375 -0.7704772949218753 +0.31775000000000004 -0.129364013671875 -0.0296630859375 -0.7704772949218753 +0.317875 -0.134429931640625 -0.03082275390625 -0.7704772949218753 +0.318 -0.13946533203125 -0.031982421875 -0.7704772949218753 +0.318125 -0.13946533203125 -0.031982421875 -0.7704772949218753 +0.31825000000000004 -0.14447021484375 -0.03314208984375 -0.7704772949218753 +0.318375 -0.14447021484375 -0.03314208984375 -0.7704772949218753 +0.3185 -0.14947509765625 -0.034271240234375 -0.7704772949218753 +0.318625 -0.15447998046875 -0.035430908203125 -0.7704772949218753 +0.31875000000000004 -0.15447998046875 -0.035430908203125 -0.7704772949218753 +0.318875 -0.159454345703125 -0.03656005859375 -0.7704772949218753 +0.319 -0.159454345703125 -0.03656005859375 -0.7704772949218753 +0.319125 -0.164398193359375 -0.0377197265625 -0.7704772949218753 +0.31925000000000004 -0.169342041015625 -0.038848876953125 -0.7704772949218753 +0.319375 -0.169342041015625 -0.038848876953125 -0.7704772949218753 +0.3195 -0.17425537109375 -0.03997802734375 -0.7704772949218753 +0.319625 -0.17425537109375 -0.03997802734375 -0.7704772949218753 +0.31975000000000004 -0.17913818359375 -0.04107666015625 -0.7704772949218753 +0.319875 -0.18402099609375 -0.042205810546875 -0.7704772949218753 +0.32 -0.18402099609375 -0.007598876953125 -0.9584594726562502912 +0.320125 -0.188873291015625 -0.0078125 -0.9584594726562502912 +0.32025 -0.188873291015625 -0.0078125 -0.9584594726562502912 +0.320375 -0.1937255859375 -0.008026123046875 -0.9584594726562502912 +0.3205 -0.19854736328125 -0.008209228515625 -0.9584594726562502912 +0.320625 -0.19854736328125 -0.008209228515625 -0.9584594726562502912 +0.32075 -0.203338623046875 -0.0084228515625 -0.9584594726562502912 +0.320875 -0.203338623046875 -0.0084228515625 -0.9584594726562502912 +0.321 -0.208099365234375 -0.00860595703125 -0.9584594726562502912 +0.321125 -0.212860107421875 -0.008819580078125 -0.9584594726562502912 +0.32125 -0.212860107421875 -0.008819580078125 -0.9584594726562502912 +0.321375 -0.21759033203125 -0.009002685546875 -0.9584594726562502912 +0.3215 -0.21759033203125 -0.009002685546875 -0.9584594726562502912 +0.321625 -0.2222900390625 -0.009185791015625 -0.9584594726562502912 +0.32175 -0.226959228515625 -0.0093994140625 -0.9584594726562502912 +0.321875 -0.226959228515625 -0.0093994140625 -0.9584594726562502912 +0.322 -0.231597900390625 -0.00958251953125 -0.9584594726562502912 +0.322125 -0.231597900390625 -0.00958251953125 -0.9584594726562502912 +0.32225 -0.236236572265625 -0.009765625 -0.9584594726562502912 +0.322375 -0.2408447265625 -0.009979248046875 -0.9584594726562502912 +0.3225 -0.2408447265625 -0.009979248046875 -0.9584594726562502912 +0.322625 -0.24542236328125 -0.010162353515625 -0.9584594726562502912 +0.32275 -0.24542236328125 -0.010162353515625 -0.9584594726562502912 +0.322875 -0.249969482421875 -0.010345458984375 -0.9584594726562502912 +0.323 -0.25445556640625 -0.010528564453125 -0.9584594726562502912 +0.323125 -0.25445556640625 -0.010528564453125 -0.9584594726562502912 +0.32325 -0.25897216796875 -0.010711669921875 -0.9584594726562502912 +0.323375 -0.25897216796875 -0.010711669921875 -0.9584594726562502912 +0.3235 -0.263427734375 -0.010894775390625 -0.9584594726562502912 +0.323625 -0.267852783203125 -0.011077880859375 -0.9584594726562502912 +0.32375 -0.267852783203125 -0.011077880859375 -0.9584594726562502912 +0.323875 -0.27227783203125 -0.011260986328125 -0.9584594726562502912 +0.324 -0.27227783203125 -0.011260986328125 -0.9584594726562502912 +0.324125 -0.276641845703125 -0.011444091796875 -0.9584594726562502912 +0.32425 -0.280975341796875 -0.011627197265625 -0.9584594726562502912 +0.324375 -0.280975341796875 -0.011627197265625 -0.9584594726562502912 +0.3245 -0.285308837890625 -0.011810302734375 -0.9584594726562502912 +0.324625 -0.285308837890625 -0.011810302734375 -0.9584594726562502912 +0.32475 -0.289581298828125 -0.011993408203125 -0.9584594726562502912 +0.324875 -0.2938232421875 -0.012176513671875 -0.9584594726562502912 +0.325 -0.2938232421875 -0.012176513671875 -0.9584594726562502912 +0.325125 -0.298065185546875 -0.0123291015625 -0.9584594726562502912 +0.32525 -0.298065185546875 -0.0123291015625 -0.9584594726562502912 +0.325375 -0.30224609375 -0.01251220703125 -0.9584594726562502912 +0.3255 -0.306396484375 -0.0126953125 -0.9584594726562502912 +0.325625 -0.306396484375 -0.0126953125 -0.9584594726562502912 +0.32575 -0.310516357421875 -0.012847900390625 -0.9584594726562502912 +0.325875 -0.310516357421875 -0.012847900390625 -0.9584594726562502912 +0.326 -0.314605712890625 -0.013031005859375 -0.9584594726562502912 +0.326125 -0.31866455078125 -0.01318359375 -0.9584594726562502912 +0.32625 -0.31866455078125 -0.01318359375 -0.9584594726562502912 +0.326375 -0.322662353515625 -0.01336669921875 -0.9584594726562502912 +0.3265 -0.322662353515625 -0.01336669921875 -0.9584594726562502912 +0.326625 -0.32666015625 -0.013519287109375 -0.9584594726562502912 +0.32675 -0.330596923828125 -0.013702392578125 -0.9584594726562502912 +0.326875 -0.330596923828125 -0.013702392578125 -0.9584594726562502912 +0.327 -0.334503173828125 -0.01385498046875 -0.9584594726562502912 +0.327125 -0.334503173828125 -0.01385498046875 -0.9584594726562502912 +0.32725 -0.33837890625 -0.014007568359375 -0.9584594726562502912 +0.327375 -0.34222412109375 -0.01416015625 -0.9584594726562502912 +0.3275 -0.34222412109375 -0.01416015625 -0.9584594726562502912 +0.327625 -0.34600830078125 -0.014312744140625 -0.9584594726562502912 +0.32775 -0.34600830078125 -0.014312744140625 -0.9584594726562502912 +0.327875 -0.349761962890625 -0.014495849609375 -0.9584594726562502912 +0.328 -0.353485107421875 -0.0146484375 -0.9584594726562502912 +0.328125 -0.353485107421875 -0.0146484375 -0.9584594726562502912 +0.32825 -0.357177734375 -0.014801025390625 -0.9584594726562502912 +0.32837500000000004 -0.357177734375 -0.014801025390625 -0.9584594726562502912 +0.3285 -0.360809326171875 -0.01495361328125 -0.9584594726562502912 +0.328625 -0.36444091796875 -0.01507568359375 -0.9584594726562502912 +0.32875 -0.36444091796875 -0.01507568359375 -0.9584594726562502912 +0.32887500000000004 -0.36798095703125 -0.015228271484375 -0.9584594726562502912 +0.329 -0.36798095703125 -0.015228271484375 -0.9584594726562502912 +0.329125 -0.37152099609375 -0.015380859375 -0.9584594726562502912 +0.32925 -0.375 -0.015533447265625 -0.9584594726562502912 +0.32937500000000004 -0.375 -0.015533447265625 -0.9584594726562502912 +0.3295 -0.378448486328125 -0.015655517578125 -0.9584594726562502912 +0.329625 -0.378448486328125 -0.015655517578125 -0.9584594726562502912 +0.32975 -0.3818359375 -0.01580810546875 -0.9584594726562502912 +0.32987500000000004 -0.38519287109375 -0.015960693359375 -0.9584594726562502912 +0.33 -0.38519287109375 -0.015960693359375 -0.9584594726562502912 +0.330125 -0.388519287109375 -0.016082763671875 -0.9584594726562502912 +0.33025 -0.388519287109375 -0.016082763671875 -0.9584594726562502912 +0.33037500000000004 -0.39178466796875 -0.0162353515625 -0.9584594726562502912 +0.3305 -0.39501953125 -0.016357421875 -0.9584594726562502912 +0.330625 -0.39501953125 -0.016357421875 -0.9584594726562502912 +0.33075 -0.398193359375 -0.0164794921875 -0.9584594726562502912 +0.33087500000000004 -0.398193359375 -0.0164794921875 -0.9584594726562502912 +0.331 -0.401336669921875 -0.016632080078125 -0.9584594726562502912 +0.331125 -0.404449462890625 -0.016754150390625 -0.9584594726562502912 +0.33125 -0.404449462890625 -0.016754150390625 -0.9584594726562502912 +0.33137500000000004 -0.407501220703125 -0.016876220703125 -0.9584594726562502912 +0.3315 -0.407501220703125 -0.016876220703125 -0.9584594726562502912 +0.331625 -0.4105224609375 -0.016998291015625 -0.9584594726562502912 +0.33175 -0.413482666015625 -0.017120361328125 -0.9584594726562502912 +0.33187500000000004 -0.413482666015625 -0.017120361328125 -0.9584594726562502912 +0.332 -0.416412353515625 -0.017242431640625 -0.9584594726562502912 +0.332125 -0.416412353515625 -0.017242431640625 -0.9584594726562502912 +0.33225 -0.419281005859375 -0.017364501953125 -0.9584594726562502912 +0.33237500000000004 -0.422119140625 -0.017486572265625 -0.9584594726562502912 +0.3325 -0.422119140625 -0.017486572265625 -0.9584594726562502912 +0.332625 -0.424896240234375 -0.017608642578125 -0.9584594726562502912 +0.33275 -0.424896240234375 -0.017608642578125 -0.9584594726562502912 +0.33287500000000004 -0.4276123046875 -0.0177001953125 -0.9584594726562502912 +0.333 -0.4302978515625 -0.017822265625 -0.9584594726562502912 +0.333125 -0.4302978515625 -0.017822265625 -0.9584594726562502912 +0.33325 -0.432952880859375 -0.0179443359375 -0.9584594726562502912 +0.33337500000000004 -0.432952880859375 -0.0179443359375 -0.9584594726562502912 +0.3335 -0.435546875 -0.018035888671875 -0.9584594726562502912 +0.333625 -0.438079833984375 -0.01812744140625 -0.9584594726562502912 +0.33375 -0.438079833984375 -0.01812744140625 -0.9584594726562502912 +0.33387500000000004 -0.440582275390625 -0.01824951171875 -0.9584594726562502912 +0.334 -0.440582275390625 -0.01824951171875 -0.9584594726562502912 +0.334125 -0.44305419921875 -0.018341064453125 -0.9584594726562502912 +0.33425 -0.4454345703125 -0.0184326171875 -0.9584594726562502912 +0.33437500000000004 -0.4454345703125 -0.0184326171875 -0.9584594726562502912 +0.3345 -0.447784423828125 -0.0185546875 -0.9584594726562502912 +0.334625 -0.447784423828125 -0.0185546875 -0.9584594726562502912 +0.33475 -0.450103759765625 -0.018646240234375 -0.9584594726562502912 +0.33487500000000004 -0.452362060546875 -0.01873779296875 -0.9584594726562502912 +0.335 -0.452362060546875 -0.01873779296875 -0.9584594726562502912 +0.335125 -0.454559326171875 -0.018829345703125 -0.9584594726562502912 +0.33525 -0.454559326171875 -0.018829345703125 -0.9584594726562502912 +0.33537500000000004 -0.45672607421875 -0.0189208984375 -0.9584594726562502912 +0.3355 -0.458831787109375 -0.019012451171875 -0.9584594726562502912 +0.335625 -0.458831787109375 -0.019012451171875 -0.9584594726562502912 +0.33575 -0.46087646484375 -0.019073486328125 -0.9584594726562502912 +0.33587500000000004 -0.46087646484375 -0.019073486328125 -0.9584594726562502912 +0.336 -0.462890625 -0.0191650390625 -0.9584594726562502912 +0.336125 -0.464813232421875 -0.019256591796875 -0.9584594726562502912 +0.33625 -0.464813232421875 -0.019256591796875 -0.9584594726562502912 +0.336375 -0.46673583984375 -0.019317626953125 -0.9584594726562502912 +0.3365 -0.46673583984375 -0.019317626953125 -0.9584594726562502912 +0.336625 -0.46856689453125 -0.0194091796875 -0.9584594726562502912 +0.33675 -0.470367431640625 -0.01947021484375 -0.9584594726562502912 +0.336875 -0.470367431640625 -0.01947021484375 -0.9584594726562502912 +0.337 -0.472137451171875 -0.019561767578125 -0.9584594726562502912 +0.337125 -0.472137451171875 -0.019561767578125 -0.9584594726562502912 +0.33725 -0.47381591796875 -0.019622802734375 -0.9584594726562502912 +0.337375 -0.4754638671875 -0.019683837890625 -0.9584594726562502912 +0.3375 -0.4754638671875 -0.019683837890625 -0.9584594726562502912 +0.337625 -0.47705078125 -0.019744873046875 -0.9584594726562502912 +0.33775 -0.47705078125 -0.019744873046875 -0.9584594726562502912 +0.337875 -0.478607177734375 -0.019805908203125 -0.9584594726562502912 +0.338 -0.480072021484375 -0.019866943359375 -0.9584594726562502912 +0.338125 -0.480072021484375 -0.019866943359375 -0.9584594726562502912 +0.33825 -0.48150634765625 -0.019927978515625 -0.9584594726562502912 +0.338375 -0.48150634765625 -0.019927978515625 -0.9584594726562502912 +0.3385 -0.48291015625 -0.019989013671875 -0.9584594726562502912 +0.338625 -0.484222412109375 -0.020050048828125 -0.9584594726562502912 +0.33875 -0.484222412109375 -0.020050048828125 -0.9584594726562502912 +0.338875 -0.485504150390625 -0.020111083984375 -0.9584594726562502912 +0.339 -0.485504150390625 -0.020111083984375 -0.9584594726562502912 +0.339125 -0.486724853515625 -0.020172119140625 -0.9584594726562502912 +0.33925 -0.487884521484375 -0.02020263671875 -0.9584594726562502912 +0.339375 -0.487884521484375 -0.02020263671875 -0.9584594726562502912 +0.3395 -0.489013671875 -0.020263671875 -0.9584594726562502912 +0.339625 -0.489013671875 -0.020263671875 -0.9584594726562502912 +0.33975 -0.490081787109375 -0.020294189453125 -0.9584594726562502912 +0.339875 -0.4910888671875 -0.02032470703125 -0.9584594726562502912 +0.34 -0.4910888671875 -0.02032470703125 -0.9584594726562502912 +0.340125 -0.492034912109375 -0.0203857421875 -0.9584594726562502912 +0.34025 -0.492034912109375 -0.0203857421875 -0.9584594726562502912 +0.340375 -0.492950439453125 -0.020416259765625 -0.9584594726562502912 +0.3405 -0.4937744140625 -0.02044677734375 -0.9584594726562502912 +0.340625 -0.4937744140625 -0.02044677734375 -0.9584594726562502912 +0.34075 -0.49456787109375 -0.020477294921875 -0.9584594726562502912 +0.340875 -0.49456787109375 -0.020477294921875 -0.9584594726562502912 +0.341 -0.49530029296875 -0.0205078125 -0.9584594726562502912 +0.341125 -0.496002197265625 -0.020538330078125 -0.9584594726562502912 +0.34125 -0.496002197265625 -0.020538330078125 -0.9584594726562502912 +0.341375 -0.496612548828125 -0.02056884765625 -0.9584594726562502912 +0.3415 -0.496612548828125 -0.02056884765625 -0.9584594726562502912 +0.341625 -0.4971923828125 -0.020599365234375 -0.9584594726562502912 +0.34175 -0.497711181640625 -0.020599365234375 -0.9584594726562502912 +0.341875 -0.497711181640625 -0.020599365234375 -0.9584594726562502912 +0.342 -0.498199462890625 -0.0206298828125 -0.9584594726562502912 +0.342125 -0.498199462890625 -0.0206298828125 -0.9584594726562502912 +0.34225 -0.49859619140625 -0.020660400390625 -0.9584594726562502912 +0.342375 -0.49896240234375 -0.020660400390625 -0.9584594726562502912 +0.3425 -0.49896240234375 -0.020660400390625 -0.9584594726562502912 +0.342625 -0.499267578125 -0.02069091796875 -0.9584594726562502912 +0.34275 -0.499267578125 -0.02069091796875 -0.9584594726562502912 +0.342875 -0.49951171875 -0.02069091796875 -0.9584594726562502912 +0.343 -0.49969482421875 -0.02069091796875 -0.9584594726562502912 +0.343125 -0.49969482421875 -0.02069091796875 -0.9584594726562502912 +0.34325 -0.49981689453125 -0.02069091796875 -0.9584594726562502912 +0.343375 -0.49981689453125 -0.02069091796875 -0.9584594726562502912 +0.3435 -0.499908447265625 -0.02069091796875 -0.9584594726562502912 +0.343625 -0.49993896484375 -0.02069091796875 -0.9584594726562502912 +0.34375 -0.49993896484375 -0.02069091796875 -0.9584594726562502912 +0.343875 -0.499908447265625 -0.02069091796875 -0.9584594726562502912 +0.34400000000000004 -0.499908447265625 -0.02069091796875 -0.9584594726562502912 +0.344125 -0.49981689453125 -0.02069091796875 -0.9584594726562502912 +0.34425 -0.49969482421875 -0.02069091796875 -0.9584594726562502912 +0.344375 -0.49969482421875 -0.02069091796875 -0.9584594726562502912 +0.34450000000000004 -0.49951171875 -0.02069091796875 -0.9584594726562502912 +0.344625 -0.49951171875 -0.02069091796875 -0.9584594726562502912 +0.34475 -0.499267578125 -0.02069091796875 -0.9584594726562502912 +0.344875 -0.49896240234375 -0.020660400390625 -0.9584594726562502912 +0.34500000000000004 -0.49896240234375 -0.020660400390625 -0.9584594726562502912 +0.345125 -0.49859619140625 -0.020660400390625 -0.9584594726562502912 +0.34525 -0.49859619140625 -0.020660400390625 -0.9584594726562502912 +0.345375 -0.498199462890625 -0.0206298828125 -0.9584594726562502912 +0.34550000000000004 -0.497711181640625 -0.020599365234375 -0.9584594726562502912 +0.345625 -0.497711181640625 -0.020599365234375 -0.9584594726562502912 +0.34575 -0.4971923828125 -0.020599365234375 -0.9584594726562502912 +0.345875 -0.4971923828125 -0.020599365234375 -0.9584594726562502912 +0.34600000000000004 -0.496612548828125 -0.02056884765625 -0.9584594726562502912 +0.346125 -0.496002197265625 -0.020538330078125 -0.9584594726562502912 +0.34625 -0.496002197265625 -0.020538330078125 -0.9584594726562502912 +0.346375 -0.49530029296875 -0.0205078125 -0.9584594726562502912 +0.34650000000000004 -0.49530029296875 -0.0205078125 -0.9584594726562502912 +0.346625 -0.49456787109375 -0.020477294921875 -0.9584594726562502912 +0.34675 -0.4937744140625 -0.02044677734375 -0.9584594726562502912 +0.346875 -0.4937744140625 -0.02044677734375 -0.9584594726562502912 +0.34700000000000004 -0.492950439453125 -0.020416259765625 -0.9584594726562502912 +0.347125 -0.492950439453125 -0.020416259765625 -0.9584594726562502912 +0.34725 -0.492034912109375 -0.0203857421875 -0.9584594726562502912 +0.347375 -0.4910888671875 -0.02032470703125 -0.9584594726562502912 +0.34750000000000004 -0.4910888671875 -0.02032470703125 -0.9584594726562502912 +0.347625 -0.490081787109375 -0.020294189453125 -0.9584594726562502912 +0.34775 -0.490081787109375 -0.020294189453125 -0.9584594726562502912 +0.347875 -0.489013671875 -0.020263671875 -0.9584594726562502912 +0.34800000000000004 -0.487884521484375 -0.02020263671875 -0.9584594726562502912 +0.348125 -0.487884521484375 -0.02020263671875 -0.9584594726562502912 +0.34825 -0.486724853515625 -0.020172119140625 -0.9584594726562502912 +0.348375 -0.486724853515625 -0.020172119140625 -0.9584594726562502912 +0.34850000000000004 -0.485504150390625 -0.020111083984375 -0.9584594726562502912 +0.348625 -0.484222412109375 -0.020050048828125 -0.9584594726562502912 +0.34875 -0.484222412109375 -0.020050048828125 -0.9584594726562502912 +0.348875 -0.48291015625 -0.019989013671875 -0.9584594726562502912 +0.34900000000000004 -0.48291015625 -0.019989013671875 -0.9584594726562502912 +0.349125 -0.48150634765625 -0.019927978515625 -0.9584594726562502912 +0.34925 -0.480072021484375 -0.019866943359375 -0.9584594726562502912 +0.349375 -0.480072021484375 -0.019866943359375 -0.9584594726562502912 +0.34950000000000004 -0.478607177734375 -0.019805908203125 -0.9584594726562502912 +0.349625 -0.478607177734375 -0.019805908203125 -0.9584594726562502912 +0.34975 -0.47705078125 -0.019744873046875 -0.9584594726562502912 +0.349875 -0.4754638671875 -0.019683837890625 -0.9584594726562502912 +0.35000000000000004 -0.4754638671875 -0.019683837890625 -0.9584594726562502912 +0.350125 -0.47381591796875 -0.019622802734375 -0.9584594726562502912 +0.35025 -0.47381591796875 -0.019622802734375 -0.9584594726562502912 +0.350375 -0.472137451171875 -0.019561767578125 -0.9584594726562502912 +0.35050000000000004 -0.470367431640625 -0.01947021484375 -0.9584594726562502912 +0.350625 -0.470367431640625 -0.01947021484375 -0.9584594726562502912 +0.35075 -0.46856689453125 -0.0194091796875 -0.9584594726562502912 +0.350875 -0.46856689453125 -0.0194091796875 -0.9584594726562502912 +0.35100000000000004 -0.46673583984375 -0.019317626953125 -0.9584594726562502912 +0.351125 -0.464813232421875 -0.019256591796875 -0.9584594726562502912 +0.35125 -0.464813232421875 -0.019256591796875 -0.9584594726562502912 +0.351375 -0.462890625 -0.0191650390625 -0.9584594726562502912 +0.35150000000000004 -0.462890625 -0.0191650390625 -0.9584594726562502912 +0.351625 -0.46087646484375 -0.019073486328125 -0.9584594726562502912 +0.35175 -0.458831787109375 -0.019012451171875 -0.9584594726562502912 +0.351875 -0.458831787109375 -0.019012451171875 -0.9584594726562502912 +0.352 -0.45672607421875 -0.002899169921875 -0.9935485839843748 +0.352125 -0.45672607421875 -0.002899169921875 -0.9935485839843748 +0.35225 -0.454559326171875 -0.00286865234375 -0.9935485839843748 +0.352375 -0.452362060546875 -0.00286865234375 -0.9935485839843748 +0.3525 -0.452362060546875 -0.00286865234375 -0.9935485839843748 +0.352625 -0.450103759765625 -0.002838134765625 -0.9935485839843748 +0.35275 -0.450103759765625 -0.002838134765625 -0.9935485839843748 +0.352875 -0.447784423828125 -0.002838134765625 -0.9935485839843748 +0.353 -0.4454345703125 -0.0028076171875 -0.9935485839843748 +0.353125 -0.4454345703125 -0.0028076171875 -0.9935485839843748 +0.35325 -0.44305419921875 -0.0028076171875 -0.9935485839843748 +0.353375 -0.44305419921875 -0.0028076171875 -0.9935485839843748 +0.3535 -0.440582275390625 -0.002777099609375 -0.9935485839843748 +0.353625 -0.438079833984375 -0.002777099609375 -0.9935485839843748 +0.35375 -0.438079833984375 -0.002777099609375 -0.9935485839843748 +0.353875 -0.435546875 -0.00274658203125 -0.9935485839843748 +0.354 -0.435546875 -0.00274658203125 -0.9935485839843748 +0.354125 -0.432952880859375 -0.00274658203125 -0.9935485839843748 +0.35425 -0.4302978515625 -0.002716064453125 -0.9935485839843748 +0.354375 -0.4302978515625 -0.002716064453125 -0.9935485839843748 +0.3545 -0.4276123046875 -0.002685546875 -0.9935485839843748 +0.354625 -0.4276123046875 -0.002685546875 -0.9935485839843748 +0.35475 -0.424896240234375 -0.002685546875 -0.9935485839843748 +0.354875 -0.422119140625 -0.002655029296875 -0.9935485839843748 +0.355 -0.422119140625 -0.002655029296875 -0.9935485839843748 +0.355125 -0.419281005859375 -0.002655029296875 -0.9935485839843748 +0.35525 -0.419281005859375 -0.002655029296875 -0.9935485839843748 +0.355375 -0.416412353515625 -0.00262451171875 -0.9935485839843748 +0.3555 -0.413482666015625 -0.00262451171875 -0.9935485839843748 +0.355625 -0.413482666015625 -0.00262451171875 -0.9935485839843748 +0.35575 -0.4105224609375 -0.002593994140625 -0.9935485839843748 +0.355875 -0.4105224609375 -0.002593994140625 -0.9935485839843748 +0.356 -0.407501220703125 -0.0025634765625 -0.9935485839843748 +0.356125 -0.404449462890625 -0.0025634765625 -0.9935485839843748 +0.35625 -0.404449462890625 -0.0025634765625 -0.9935485839843748 +0.356375 -0.401336669921875 -0.002532958984375 -0.9935485839843748 +0.3565 -0.401336669921875 -0.002532958984375 -0.9935485839843748 +0.356625 -0.398193359375 -0.00250244140625 -0.9935485839843748 +0.35675 -0.39501953125 -0.00250244140625 -0.9935485839843748 +0.356875 -0.39501953125 -0.00250244140625 -0.9935485839843748 +0.357 -0.39178466796875 -0.002471923828125 -0.9935485839843748 +0.357125 -0.39178466796875 -0.002471923828125 -0.9935485839843748 +0.35725 -0.388519287109375 -0.00244140625 -0.9935485839843748 +0.357375 -0.38519287109375 -0.00244140625 -0.9935485839843748 +0.3575 -0.38519287109375 -0.00244140625 -0.9935485839843748 +0.357625 -0.3818359375 -0.002410888671875 -0.9935485839843748 +0.35775 -0.3818359375 -0.002410888671875 -0.9935485839843748 +0.357875 -0.378448486328125 -0.00238037109375 -0.9935485839843748 +0.358 -0.375 -0.00238037109375 -0.9935485839843748 +0.358125 -0.375 -0.00238037109375 -0.9935485839843748 +0.35825 -0.37152099609375 -0.002349853515625 -0.9935485839843748 +0.358375 -0.37152099609375 -0.002349853515625 -0.9935485839843748 +0.3585 -0.36798095703125 -0.0023193359375 -0.9935485839843748 +0.358625 -0.36444091796875 -0.002288818359375 -0.9935485839843748 +0.35875 -0.36444091796875 -0.002288818359375 -0.9935485839843748 +0.358875 -0.360809326171875 -0.002288818359375 -0.9935485839843748 +0.359 -0.360809326171875 -0.002288818359375 -0.9935485839843748 +0.359125 -0.357177734375 -0.00225830078125 -0.9935485839843748 +0.35925 -0.353485107421875 -0.002227783203125 -0.9935485839843748 +0.359375 -0.353485107421875 -0.002227783203125 -0.9935485839843748 +0.3595 -0.349761962890625 -0.002197265625 -0.9935485839843748 +0.35962500000000004 -0.349761962890625 -0.002197265625 -0.9935485839843748 +0.35975 -0.34600830078125 -0.002166748046875 -0.9935485839843748 +0.359875 -0.34222412109375 -0.002166748046875 -0.9935485839843748 +0.36 -0.34222412109375 -0.002166748046875 -0.9935485839843748 +0.36012500000000004 -0.33837890625 -0.00213623046875 -0.9935485839843748 +0.36025 -0.33837890625 -0.00213623046875 -0.9935485839843748 +0.360375 -0.334503173828125 -0.002105712890625 -0.9935485839843748 +0.3605 -0.330596923828125 -0.0020751953125 -0.9935485839843748 +0.3606250000000000512 -0.330596923828125 -0.0020751953125 -0.9935485839843748 +0.36075 -0.32666015625 -0.002044677734375 -0.9935485839843748 +0.360875 -0.32666015625 -0.002044677734375 -0.9935485839843748 +0.361 -0.322662353515625 -0.002044677734375 -0.9935485839843748 +0.3611250000000000512 -0.31866455078125 -0.00201416015625 -0.9935485839843748 +0.36125 -0.31866455078125 -0.00201416015625 -0.9935485839843748 +0.361375 -0.314605712890625 -0.001983642578125 -0.9935485839843748 +0.3615 -0.314605712890625 -0.001983642578125 -0.9935485839843748 +0.3616250000000000512 -0.310516357421875 -0.001953125 -0.9935485839843748 +0.36175 -0.306396484375 -0.001922607421875 -0.9935485839843748 +0.361875 -0.306396484375 -0.001922607421875 -0.9935485839843748 +0.362 -0.30224609375 -0.00189208984375 -0.9935485839843748 +0.3621250000000000512 -0.30224609375 -0.00189208984375 -0.9935485839843748 +0.36225 -0.298065185546875 -0.00189208984375 -0.9935485839843748 +0.362375 -0.2938232421875 -0.001861572265625 -0.9935485839843748 +0.3625 -0.2938232421875 -0.001861572265625 -0.9935485839843748 +0.3626250000000000512 -0.289581298828125 -0.0018310546875 -0.9935485839843748 +0.36275 -0.289581298828125 -0.0018310546875 -0.9935485839843748 +0.362875 -0.285308837890625 -0.001800537109375 -0.9935485839843748 +0.363 -0.280975341796875 -0.00177001953125 -0.9935485839843748 +0.3631250000000000512 -0.280975341796875 -0.00177001953125 -0.9935485839843748 +0.36325 -0.276641845703125 -0.001739501953125 -0.9935485839843748 +0.363375 -0.276641845703125 -0.001739501953125 -0.9935485839843748 +0.3635 -0.27227783203125 -0.001708984375 -0.9935485839843748 +0.3636250000000000512 -0.267852783203125 -0.001678466796875 -0.9935485839843748 +0.36375 -0.267852783203125 -0.001678466796875 -0.9935485839843748 +0.363875 -0.263427734375 -0.00164794921875 -0.9935485839843748 +0.364 -0.263427734375 -0.00164794921875 -0.9935485839843748 +0.3641250000000000512 -0.25897216796875 -0.001617431640625 -0.9935485839843748 +0.36425 -0.25445556640625 -0.0015869140625 -0.9935485839843748 +0.364375 -0.25445556640625 -0.0015869140625 -0.9935485839843748 +0.3645 -0.249969482421875 -0.001556396484375 -0.9935485839843748 +0.3646250000000000512 -0.249969482421875 -0.001556396484375 -0.9935485839843748 +0.36475 -0.24542236328125 -0.001556396484375 -0.9935485839843748 +0.364875 -0.2408447265625 -0.00152587890625 -0.9935485839843748 +0.365 -0.2408447265625 -0.00152587890625 -0.9935485839843748 +0.3651250000000000512 -0.236236572265625 -0.001495361328125 -0.9935485839843748 +0.36525 -0.236236572265625 -0.001495361328125 -0.9935485839843748 +0.365375 -0.231597900390625 -0.00146484375 -0.9935485839843748 +0.3655 -0.226959228515625 -0.001434326171875 -0.9935485839843748 +0.3656250000000000512 -0.226959228515625 -0.001434326171875 -0.9935485839843748 +0.36575 -0.2222900390625 -0.00140380859375 -0.9935485839843748 +0.365875 -0.2222900390625 -0.00140380859375 -0.9935485839843748 +0.366 -0.21759033203125 -0.001373291015625 -0.9935485839843748 +0.3661250000000000512 -0.212860107421875 -0.0013427734375 -0.9935485839843748 +0.36625 -0.212860107421875 -0.0013427734375 -0.9935485839843748 +0.366375 -0.208099365234375 -0.001312255859375 -0.9935485839843748 +0.3665 -0.208099365234375 -0.001312255859375 -0.9935485839843748 +0.3666250000000000512 -0.203338623046875 -0.00128173828125 -0.9935485839843748 +0.36675 -0.19854736328125 -0.001251220703125 -0.9935485839843748 +0.366875 -0.19854736328125 -0.001251220703125 -0.9935485839843748 +0.367 -0.1937255859375 -0.001220703125 -0.9935485839843748 +0.3671250000000000512 -0.1937255859375 -0.001220703125 -0.9935485839843748 +0.36725 -0.188873291015625 -0.001190185546875 -0.9935485839843748 +0.367375 -0.18402099609375 -0.00115966796875 -0.9935485839843748 +0.3675 -0.18402099609375 -0.00115966796875 -0.9935485839843748 +0.3676250000000000512 -0.17913818359375 -0.001129150390625 -0.9935485839843748 +0.36775 -0.17913818359375 -0.001129150390625 -0.9935485839843748 +0.367875 -0.17425537109375 -0.0010986328125 -0.9935485839843748 +0.368 -0.169342041015625 -0.001068115234375 -0.9935485839843748 +0.368125 -0.169342041015625 -0.001068115234375 -0.9935485839843748 +0.36825 -0.164398193359375 -0.00103759765625 -0.9935485839843748 +0.368375 -0.164398193359375 -0.00103759765625 -0.9935485839843748 +0.3685 -0.159454345703125 -0.001007080078125 -0.9935485839843748 +0.368625 -0.15447998046875 -0.0009765625 -0.9935485839843748 +0.36875 -0.15447998046875 -0.0009765625 -0.9935485839843748 +0.368875 -0.14947509765625 -0.000946044921875 -0.9935485839843748 +0.369 -0.14947509765625 -0.000946044921875 -0.9935485839843748 +0.369125 -0.14447021484375 -0.00091552734375 -0.9935485839843748 +0.36925 -0.13946533203125 -0.000885009765625 -0.9935485839843748 +0.369375 -0.13946533203125 -0.000885009765625 -0.9935485839843748 +0.3695 -0.134429931640625 -0.000823974609375 -0.9935485839843748 +0.369625 -0.134429931640625 -0.000823974609375 -0.9935485839843748 +0.36975 -0.129364013671875 -0.00079345703125 -0.9935485839843748 +0.369875 -0.124298095703125 -0.000762939453125 -0.9935485839843748 +0.37 -0.124298095703125 -0.000762939453125 -0.9935485839843748 +0.370125 -0.119232177734375 -0.000732421875 -0.9935485839843748 +0.37025 -0.119232177734375 -0.000732421875 -0.9935485839843748 +0.370375 -0.1141357421875 -0.000701904296875 -0.9935485839843748 +0.3705 -0.109039306640625 -0.00067138671875 -0.9935485839843748 +0.370625 -0.109039306640625 -0.00067138671875 -0.9935485839843748 +0.37075 -0.103912353515625 -0.000640869140625 -0.9935485839843748 +0.370875 -0.103912353515625 -0.000640869140625 -0.9935485839843748 +0.371 -0.098785400390625 -0.0006103515625 -0.9935485839843748 +0.371125 -0.093658447265625 -0.000579833984375 -0.9935485839843748 +0.37125 -0.093658447265625 -0.000579833984375 -0.9935485839843748 +0.371375 -0.0885009765625 -0.00054931640625 -0.9935485839843748 +0.3715 -0.0885009765625 -0.00054931640625 -0.9935485839843748 +0.371625 -0.083343505859375 -0.000518798828125 -0.9935485839843748 +0.37175 -0.07818603515625 -0.00048828125 -0.9935485839843748 +0.371875 -0.07818603515625 -0.00048828125 -0.9935485839843748 +0.372 -0.072998046875 -0.000457763671875 -0.9935485839843748 +0.372125 -0.072998046875 -0.000457763671875 -0.9935485839843748 +0.37225 -0.06781005859375 -0.00042724609375 -0.9935485839843748 +0.372375 -0.0626220703125 -0.000396728515625 -0.9935485839843748 +0.3725 -0.0626220703125 -0.000396728515625 -0.9935485839843748 +0.372625 -0.05743408203125 -0.000335693359375 -0.9935485839843748 +0.37275 -0.05743408203125 -0.000335693359375 -0.9935485839843748 +0.372875 -0.05224609375 -0.00030517578125 -0.9935485839843748 +0.373 -0.047027587890625 -0.000274658203125 -0.9935485839843748 +0.373125 -0.047027587890625 -0.000274658203125 -0.9935485839843748 +0.37325 -0.04180908203125 -0.000244140625 -0.9935485839843748 +0.373375 -0.04180908203125 -0.000244140625 -0.9935485839843748 +0.3735 -0.036590576171875 -0.000213623046875 -0.9935485839843748 +0.373625 -0.0313720703125 -0.00018310546875 -0.9935485839843748 +0.37375 -0.0313720703125 -0.00018310546875 -0.9935485839843748 +0.373875 -0.026123046875 -0.000152587890625 -0.9935485839843748 +0.374 -0.026123046875 -0.000152587890625 -0.9935485839843748 +0.374125 -0.020904541015625 -0.0001220703125 -0.9935485839843748 +0.37425 -0.01568603515625 -9.1552734375e-05 -0.9935485839843748 +0.374375 -0.01568603515625 -9.1552734375e-05 -0.9935485839843748 +0.3745 -0.01043701171875 -6.103515625e-05 -0.9935485839843748 +0.374625 -0.01043701171875 -6.103515625e-05 -0.9935485839843748 +0.37475 -0.005218505859375 -3.0517578125e-05 -0.9935485839843748 +0.374875 0.0 0.0 -0.9935485839843748 +0.375 0.0 0.0 -0.9935485839843748 +0.375125 0.005218505859375 3.0517578125e-05 -0.9935485839843748 +0.3752500000000000512 0.005218505859375 3.0517578125e-05 -0.9935485839843748 +0.375375 0.01043701171875 6.103515625e-05 -0.9935485839843748 +0.3755 0.01568603515625 9.1552734375e-05 -0.9935485839843748 +0.375625 0.01568603515625 9.1552734375e-05 -0.9935485839843748 +0.3757500000000000512 0.020904541015625 0.0001220703125 -0.9935485839843748 +0.375875 0.020904541015625 0.0001220703125 -0.9935485839843748 +0.376 0.026123046875 0.000152587890625 -0.9935485839843748 +0.376125 0.0313720703125 0.00018310546875 -0.9935485839843748 +0.3762500000000000512 0.0313720703125 0.00018310546875 -0.9935485839843748 +0.376375 0.036590576171875 0.000213623046875 -0.9935485839843748 +0.3765 0.036590576171875 0.000213623046875 -0.9935485839843748 +0.376625 0.04180908203125 0.000244140625 -0.9935485839843748 +0.3767500000000000512 0.047027587890625 0.000274658203125 -0.9935485839843748 +0.376875 0.047027587890625 0.000274658203125 -0.9935485839843748 +0.377 0.05224609375 0.00030517578125 -0.9935485839843748 +0.377125 0.05224609375 0.00030517578125 -0.9935485839843748 +0.3772500000000000512 0.05743408203125 0.000335693359375 -0.9935485839843748 +0.377375 0.0626220703125 0.000396728515625 -0.9935485839843748 +0.3775 0.0626220703125 0.000396728515625 -0.9935485839843748 +0.377625 0.06781005859375 0.00042724609375 -0.9935485839843748 +0.3777500000000000512 0.06781005859375 0.00042724609375 -0.9935485839843748 +0.377875 0.072998046875 0.000457763671875 -0.9935485839843748 +0.378 0.07818603515625 0.00048828125 -0.9935485839843748 +0.378125 0.07818603515625 0.00048828125 -0.9935485839843748 +0.3782500000000000512 0.083343505859375 0.000518798828125 -0.9935485839843748 +0.378375 0.083343505859375 0.000518798828125 -0.9935485839843748 +0.3785 0.0885009765625 0.00054931640625 -0.9935485839843748 +0.378625 0.093658447265625 0.000579833984375 -0.9935485839843748 +0.3787500000000000512 0.093658447265625 0.000579833984375 -0.9935485839843748 +0.378875 0.098785400390625 0.0006103515625 -0.9935485839843748 +0.379 0.098785400390625 0.0006103515625 -0.9935485839843748 +0.379125 0.103912353515625 0.000640869140625 -0.9935485839843748 +0.3792500000000000512 0.109039306640625 0.00067138671875 -0.9935485839843748 +0.379375 0.109039306640625 0.00067138671875 -0.9935485839843748 +0.3795 0.1141357421875 0.000701904296875 -0.9935485839843748 +0.379625 0.1141357421875 0.000701904296875 -0.9935485839843748 +0.3797500000000000512 0.119232177734375 0.000732421875 -0.9935485839843748 +0.379875 0.124298095703125 0.000762939453125 -0.9935485839843748 +0.38 0.124298095703125 0.000762939453125 -0.9935485839843748 +0.380125 0.129364013671875 0.00079345703125 -0.9935485839843748 +0.3802500000000000512 0.129364013671875 0.00079345703125 -0.9935485839843748 +0.380375 0.134429931640625 0.000823974609375 -0.9935485839843748 +0.3805 0.13946533203125 0.000885009765625 -0.9935485839843748 +0.380625 0.13946533203125 0.000885009765625 -0.9935485839843748 +0.3807500000000000512 0.14447021484375 0.00091552734375 -0.9935485839843748 +0.380875 0.14447021484375 0.00091552734375 -0.9935485839843748 +0.381 0.14947509765625 0.000946044921875 -0.9935485839843748 +0.381125 0.15447998046875 0.0009765625 -0.9935485839843748 +0.3812500000000000512 0.15447998046875 0.0009765625 -0.9935485839843748 +0.381375 0.159454345703125 0.001007080078125 -0.9935485839843748 +0.3815 0.159454345703125 0.001007080078125 -0.9935485839843748 +0.381625 0.164398193359375 0.00103759765625 -0.9935485839843748 +0.3817500000000000512 0.169342041015625 0.001068115234375 -0.9935485839843748 +0.381875 0.169342041015625 0.001068115234375 -0.9935485839843748 +0.382 0.17425537109375 0.0010986328125 -0.9935485839843748 +0.382125 0.17425537109375 0.0010986328125 -0.9935485839843748 +0.3822500000000000512 0.17913818359375 0.001129150390625 -0.9935485839843748 +0.382375 0.18402099609375 0.00115966796875 -0.9935485839843748 +0.3825 0.18402099609375 0.00115966796875 -0.9935485839843748 +0.382625 0.188873291015625 0.001190185546875 -0.9935485839843748 +0.3827500000000000512 0.188873291015625 0.001190185546875 -0.9935485839843748 +0.382875 0.1937255859375 0.001220703125 -0.9935485839843748 +0.383 0.19854736328125 0.001251220703125 -0.9935485839843748 +0.383125 0.19854736328125 0.001251220703125 -0.9935485839843748 +0.3832500000000000512 0.203338623046875 0.00128173828125 -0.9935485839843748 +0.383375 0.203338623046875 0.00128173828125 -0.9935485839843748 +0.3835 0.208099365234375 0.001312255859375 -0.9935485839843748 +0.383625 0.212860107421875 0.0013427734375 -0.9935485839843748 +0.3837500000000000512 0.212860107421875 0.0013427734375 -0.9935485839843748 +0.383875 0.21759033203125 0.001373291015625 -0.9935485839843748 +0.384 0.21759033203125 0.028228759765625 -0.8701477050781241 +0.384125 0.2222900390625 0.028839111328125 -0.8701477050781241 +0.38425 0.226959228515625 0.029449462890625 -0.8701477050781241 +0.384375 0.226959228515625 0.029449462890625 -0.8701477050781241 +0.3845 0.231597900390625 0.030029296875 -0.8701477050781241 +0.384625 0.231597900390625 0.030029296875 -0.8701477050781241 +0.38475 0.236236572265625 0.0306396484375 -0.8701477050781241 +0.384875 0.2408447265625 0.03125 -0.8701477050781241 +0.385 0.2408447265625 0.03125 -0.8701477050781241 +0.385125 0.24542236328125 0.031829833984375 -0.8701477050781241 +0.38525 0.24542236328125 0.031829833984375 -0.8701477050781241 +0.385375 0.249969482421875 0.03240966796875 -0.8701477050781241 +0.3855 0.25445556640625 0.03302001953125 -0.8701477050781241 +0.385625 0.25445556640625 0.03302001953125 -0.8701477050781241 +0.38575 0.25897216796875 0.033599853515625 -0.8701477050781241 +0.385875 0.25897216796875 0.033599853515625 -0.8701477050781241 +0.386 0.263427734375 0.0341796875 -0.8701477050781241 +0.386125 0.267852783203125 0.034759521484375 -0.8701477050781241 +0.38625 0.267852783203125 0.034759521484375 -0.8701477050781241 +0.386375 0.27227783203125 0.035308837890625 -0.8701477050781241 +0.3865 0.27227783203125 0.035308837890625 -0.8701477050781241 +0.386625 0.276641845703125 0.035888671875 -0.8701477050781241 +0.38675 0.280975341796875 0.03643798828125 -0.8701477050781241 +0.386875 0.280975341796875 0.03643798828125 -0.8701477050781241 +0.387 0.285308837890625 0.037017822265625 -0.8701477050781241 +0.387125 0.285308837890625 0.037017822265625 -0.8701477050781241 +0.38725 0.289581298828125 0.037567138671875 -0.8701477050781241 +0.387375 0.2938232421875 0.038116455078125 -0.8701477050781241 +0.3875 0.2938232421875 0.038116455078125 -0.8701477050781241 +0.387625 0.298065185546875 0.038665771484375 -0.8701477050781241 +0.38775 0.298065185546875 0.038665771484375 -0.8701477050781241 +0.387875 0.30224609375 0.039215087890625 -0.8701477050781241 +0.388 0.306396484375 0.03973388671875 -0.8701477050781241 +0.388125 0.306396484375 0.03973388671875 -0.8701477050781241 +0.38825 0.310516357421875 0.040283203125 -0.8701477050781241 +0.388375 0.310516357421875 0.040283203125 -0.8701477050781241 +0.3885 0.314605712890625 0.040802001953125 -0.8701477050781241 +0.388625 0.31866455078125 0.041351318359375 -0.8701477050781241 +0.38875 0.31866455078125 0.041351318359375 -0.8701477050781241 +0.388875 0.322662353515625 0.0418701171875 -0.8701477050781241 +0.389 0.322662353515625 0.0418701171875 -0.8701477050781241 +0.389125 0.32666015625 0.042388916015625 -0.8701477050781241 +0.38925 0.330596923828125 0.042877197265625 -0.8701477050781241 +0.389375 0.330596923828125 0.042877197265625 -0.8701477050781241 +0.3895 0.334503173828125 0.04339599609375 -0.8701477050781241 +0.389625 0.334503173828125 0.04339599609375 -0.8701477050781241 +0.38975 0.33837890625 0.04388427734375 -0.8701477050781241 +0.389875 0.34222412109375 0.044403076171875 -0.8701477050781241 +0.39 0.34222412109375 0.044403076171875 -0.8701477050781241 +0.390125 0.34600830078125 0.044891357421875 -0.8701477050781241 +0.39025 0.34600830078125 0.044891357421875 -0.8701477050781241 +0.390375 0.349761962890625 0.045379638671875 -0.8701477050781241 +0.3905 0.353485107421875 0.045867919921875 -0.8701477050781241 +0.390625 0.353485107421875 0.045867919921875 -0.8701477050781241 +0.39075 0.357177734375 0.04632568359375 -0.8701477050781241 +0.3908750000000000512 0.357177734375 0.04632568359375 -0.8701477050781241 +0.391 0.360809326171875 0.04681396484375 -0.8701477050781241 +0.391125 0.36444091796875 0.047271728515625 -0.8701477050781241 +0.39125 0.36444091796875 0.047271728515625 -0.8701477050781241 +0.3913750000000000512 0.36798095703125 0.0477294921875 -0.8701477050781241 +0.3915 0.36798095703125 0.0477294921875 -0.8701477050781241 +0.391625 0.37152099609375 0.048187255859375 -0.8701477050781241 +0.39175 0.375 0.04864501953125 -0.8701477050781241 +0.3918750000000000512 0.375 0.04864501953125 -0.8701477050781241 +0.392 0.378448486328125 0.049102783203125 -0.8701477050781241 +0.392125 0.378448486328125 0.049102783203125 -0.8701477050781241 +0.39225 0.3818359375 0.049530029296875 -0.8701477050781241 +0.3923750000000000512 0.38519287109375 0.04998779296875 -0.8701477050781241 +0.3925 0.38519287109375 0.04998779296875 -0.8701477050781241 +0.392625 0.388519287109375 0.0504150390625 -0.8701477050781241 +0.39275 0.388519287109375 0.0504150390625 -0.8701477050781241 +0.3928750000000000512 0.39178466796875 0.05084228515625 -0.8701477050781241 +0.393 0.39501953125 0.051239013671875 -0.8701477050781241 +0.393125 0.39501953125 0.051239013671875 -0.8701477050781241 +0.39325 0.398193359375 0.051666259765625 -0.8701477050781241 +0.3933750000000000512 0.398193359375 0.051666259765625 -0.8701477050781241 +0.3935 0.401336669921875 0.05206298828125 -0.8701477050781241 +0.393625 0.404449462890625 0.052459716796875 -0.8701477050781241 +0.39375 0.404449462890625 0.052459716796875 -0.8701477050781241 +0.3938750000000000512 0.407501220703125 0.0528564453125 -0.8701477050781241 +0.394 0.407501220703125 0.0528564453125 -0.8701477050781241 +0.394125 0.4105224609375 0.053253173828125 -0.8701477050781241 +0.39425 0.413482666015625 0.05364990234375 -0.8701477050781241 +0.3943750000000000512 0.413482666015625 0.05364990234375 -0.8701477050781241 +0.3945 0.416412353515625 0.05401611328125 -0.8701477050781241 +0.394625 0.416412353515625 0.05401611328125 -0.8701477050781241 +0.39475 0.419281005859375 0.05438232421875 -0.8701477050781241 +0.3948750000000000512 0.422119140625 0.05474853515625 -0.8701477050781241 +0.395 0.422119140625 0.05474853515625 -0.8701477050781241 +0.395125 0.424896240234375 0.05511474609375 -0.8701477050781241 +0.39525 0.424896240234375 0.05511474609375 -0.8701477050781241 +0.3953750000000000512 0.4276123046875 0.05548095703125 -0.8701477050781241 +0.3955 0.4302978515625 0.055816650390625 -0.8701477050781241 +0.395625 0.4302978515625 0.055816650390625 -0.8701477050781241 +0.39575 0.432952880859375 0.056182861328125 -0.8701477050781241 +0.3958750000000000512 0.432952880859375 0.056182861328125 -0.8701477050781241 +0.396 0.435546875 0.0565185546875 -0.8701477050781241 +0.396125 0.438079833984375 0.05682373046875 -0.8701477050781241 +0.39625 0.438079833984375 0.05682373046875 -0.8701477050781241 +0.3963750000000000512 0.440582275390625 0.057159423828125 -0.8701477050781241 +0.3965 0.440582275390625 0.057159423828125 -0.8701477050781241 +0.396625 0.44305419921875 0.057464599609375 -0.8701477050781241 +0.39675 0.4454345703125 0.05780029296875 -0.8701477050781241 +0.3968750000000000512 0.4454345703125 0.05780029296875 -0.8701477050781241 +0.397 0.447784423828125 0.05810546875 -0.8701477050781241 +0.397125 0.447784423828125 0.05810546875 -0.8701477050781241 +0.39725 0.450103759765625 0.058380126953125 -0.8701477050781241 +0.3973750000000000512 0.452362060546875 0.058685302734375 -0.8701477050781241 +0.3975 0.452362060546875 0.058685302734375 -0.8701477050781241 +0.397625 0.454559326171875 0.0589599609375 -0.8701477050781241 +0.39775 0.454559326171875 0.0589599609375 -0.8701477050781241 +0.3978750000000000512 0.45672607421875 0.05926513671875 -0.8701477050781241 +0.398 0.458831787109375 0.059539794921875 -0.8701477050781241 +0.398125 0.458831787109375 0.059539794921875 -0.8701477050781241 +0.39825 0.46087646484375 0.059783935546875 -0.8701477050781241 +0.3983750000000000512 0.46087646484375 0.059783935546875 -0.8701477050781241 +0.3985 0.462890625 0.06005859375 -0.8701477050781241 +0.398625 0.464813232421875 0.060302734375 -0.8701477050781241 +0.39875 0.464813232421875 0.060302734375 -0.8701477050781241 +0.3988750000000000512 0.46673583984375 0.060546875 -0.8701477050781241 +0.399 0.46673583984375 0.060546875 -0.8701477050781241 +0.399125 0.46856689453125 0.060791015625 -0.8701477050781241 +0.39925 0.470367431640625 0.06103515625 -0.8701477050781241 +0.3993750000000000512 0.470367431640625 0.06103515625 -0.8701477050781241 +0.3995 0.472137451171875 0.061248779296875 -0.8701477050781241 +0.399625 0.472137451171875 0.061248779296875 -0.8701477050781241 +0.39975 0.47381591796875 0.06146240234375 -0.8701477050781241 +0.3998750000000000512 0.4754638671875 0.061676025390625 -0.8701477050781241 +0.4 0.4754638671875 0.061676025390625 -0.8701477050781241 +0.400125 0.47705078125 0.0618896484375 -0.8701477050781241 +0.40025 0.47705078125 0.0618896484375 -0.8701477050781241 +0.400375 0.478607177734375 0.062103271484375 -0.8701477050781241 +0.4005 0.480072021484375 0.062286376953125 -0.8701477050781241 +0.400625 0.480072021484375 0.062286376953125 -0.8701477050781241 +0.40075 0.48150634765625 0.062469482421875 -0.8701477050781241 +0.400875 0.48150634765625 0.062469482421875 -0.8701477050781241 +0.401 0.48291015625 0.062652587890625 -0.8701477050781241 +0.401125 0.484222412109375 0.062835693359375 -0.8701477050781241 +0.40125 0.484222412109375 0.062835693359375 -0.8701477050781241 +0.401375 0.485504150390625 0.06298828125 -0.8701477050781241 +0.4015 0.485504150390625 0.06298828125 -0.8701477050781241 +0.401625 0.486724853515625 0.063140869140625 -0.8701477050781241 +0.40175 0.487884521484375 0.06329345703125 -0.8701477050781241 +0.401875 0.487884521484375 0.06329345703125 -0.8701477050781241 +0.402 0.489013671875 0.063446044921875 -0.8701477050781241 +0.402125 0.489013671875 0.063446044921875 -0.8701477050781241 +0.40225 0.490081787109375 0.063568115234375 -0.8701477050781241 +0.402375 0.4910888671875 0.063720703125 -0.8701477050781241 +0.4025 0.4910888671875 0.063720703125 -0.8701477050781241 +0.402625 0.492034912109375 0.0638427734375 -0.8701477050781241 +0.40275 0.492034912109375 0.0638427734375 -0.8701477050781241 +0.402875 0.492950439453125 0.06396484375 -0.8701477050781241 +0.403 0.4937744140625 0.064056396484375 -0.8701477050781241 +0.403125 0.4937744140625 0.064056396484375 -0.8701477050781241 +0.40325 0.49456787109375 0.064178466796875 -0.8701477050781241 +0.403375 0.49456787109375 0.064178466796875 -0.8701477050781241 +0.4035 0.49530029296875 0.06427001953125 -0.8701477050781241 +0.403625 0.496002197265625 0.064361572265625 -0.8701477050781241 +0.40375 0.496002197265625 0.064361572265625 -0.8701477050781241 +0.403875 0.496612548828125 0.064422607421875 -0.8701477050781241 +0.404 0.496612548828125 0.064422607421875 -0.8701477050781241 +0.404125 0.4971923828125 0.06451416015625 -0.8701477050781241 +0.40425 0.497711181640625 0.0645751953125 -0.8701477050781241 +0.404375 0.497711181640625 0.0645751953125 -0.8701477050781241 +0.4045 0.498199462890625 0.06463623046875 -0.8701477050781241 +0.404625 0.498199462890625 0.06463623046875 -0.8701477050781241 +0.40475 0.49859619140625 0.064697265625 -0.8701477050781241 +0.404875 0.49896240234375 0.064727783203125 -0.8701477050781241 +0.405 0.49896240234375 0.064727783203125 -0.8701477050781241 +0.405125 0.499267578125 0.064788818359375 -0.8701477050781241 +0.40525 0.499267578125 0.064788818359375 -0.8701477050781241 +0.405375 0.49951171875 0.0648193359375 -0.8701477050781241 +0.4055 0.49969482421875 0.0648193359375 -0.8701477050781241 +0.405625 0.49969482421875 0.0648193359375 -0.8701477050781241 +0.40575 0.49981689453125 0.064849853515625 -0.8701477050781241 +0.405875 0.49981689453125 0.064849853515625 -0.8701477050781241 +0.406 0.499908447265625 0.064849853515625 -0.8701477050781241 +0.406125 0.49993896484375 0.064849853515625 -0.8701477050781241 +0.40625 0.49993896484375 0.064849853515625 -0.8701477050781241 +0.406375 0.499908447265625 0.064849853515625 -0.8701477050781241 +0.4065000000000000512 0.499908447265625 0.064849853515625 -0.8701477050781241 +0.406625 0.49981689453125 0.064849853515625 -0.8701477050781241 +0.40675 0.49969482421875 0.0648193359375 -0.8701477050781241 +0.406875 0.49969482421875 0.0648193359375 -0.8701477050781241 +0.4070000000000000512 0.49951171875 0.0648193359375 -0.8701477050781241 +0.407125 0.49951171875 0.0648193359375 -0.8701477050781241 +0.40725 0.499267578125 0.064788818359375 -0.8701477050781241 +0.407375 0.49896240234375 0.064727783203125 -0.8701477050781241 +0.4075000000000000512 0.49896240234375 0.064727783203125 -0.8701477050781241 +0.407625 0.49859619140625 0.064697265625 -0.8701477050781241 +0.40775 0.49859619140625 0.064697265625 -0.8701477050781241 +0.407875 0.498199462890625 0.06463623046875 -0.8701477050781241 +0.4080000000000000512 0.497711181640625 0.0645751953125 -0.8701477050781241 +0.408125 0.497711181640625 0.0645751953125 -0.8701477050781241 +0.40825 0.4971923828125 0.06451416015625 -0.8701477050781241 +0.408375 0.4971923828125 0.06451416015625 -0.8701477050781241 +0.4085000000000000512 0.496612548828125 0.064422607421875 -0.8701477050781241 +0.408625 0.496002197265625 0.064361572265625 -0.8701477050781241 +0.40875 0.496002197265625 0.064361572265625 -0.8701477050781241 +0.408875 0.49530029296875 0.06427001953125 -0.8701477050781241 +0.4090000000000000512 0.49530029296875 0.06427001953125 -0.8701477050781241 +0.409125 0.49456787109375 0.064178466796875 -0.8701477050781241 +0.40925 0.4937744140625 0.064056396484375 -0.8701477050781241 +0.409375 0.4937744140625 0.064056396484375 -0.8701477050781241 +0.4095000000000000512 0.492950439453125 0.06396484375 -0.8701477050781241 +0.409625 0.492950439453125 0.06396484375 -0.8701477050781241 +0.40975 0.492034912109375 0.0638427734375 -0.8701477050781241 +0.409875 0.4910888671875 0.063720703125 -0.8701477050781241 +0.4100000000000000512 0.4910888671875 0.063720703125 -0.8701477050781241 +0.410125 0.490081787109375 0.063568115234375 -0.8701477050781241 +0.41025 0.490081787109375 0.063568115234375 -0.8701477050781241 +0.410375 0.489013671875 0.063446044921875 -0.8701477050781241 +0.4105000000000000512 0.487884521484375 0.06329345703125 -0.8701477050781241 +0.410625 0.487884521484375 0.06329345703125 -0.8701477050781241 +0.41075 0.486724853515625 0.063140869140625 -0.8701477050781241 +0.410875 0.486724853515625 0.063140869140625 -0.8701477050781241 +0.4110000000000000512 0.485504150390625 0.06298828125 -0.8701477050781241 +0.411125 0.484222412109375 0.062835693359375 -0.8701477050781241 +0.41125 0.484222412109375 0.062835693359375 -0.8701477050781241 +0.411375 0.48291015625 0.062652587890625 -0.8701477050781241 +0.4115000000000000512 0.48291015625 0.062652587890625 -0.8701477050781241 +0.411625 0.48150634765625 0.062469482421875 -0.8701477050781241 +0.41175 0.480072021484375 0.062286376953125 -0.8701477050781241 +0.411875 0.480072021484375 0.062286376953125 -0.8701477050781241 +0.4120000000000000512 0.478607177734375 0.062103271484375 -0.8701477050781241 +0.412125 0.478607177734375 0.062103271484375 -0.8701477050781241 +0.41225 0.47705078125 0.0618896484375 -0.8701477050781241 +0.412375 0.4754638671875 0.061676025390625 -0.8701477050781241 +0.4125000000000000512 0.4754638671875 0.061676025390625 -0.8701477050781241 +0.412625 0.47381591796875 0.06146240234375 -0.8701477050781241 +0.41275 0.47381591796875 0.06146240234375 -0.8701477050781241 +0.412875 0.472137451171875 0.061248779296875 -0.8701477050781241 +0.4130000000000000512 0.470367431640625 0.06103515625 -0.8701477050781241 +0.413125 0.470367431640625 0.06103515625 -0.8701477050781241 +0.41325 0.46856689453125 0.060791015625 -0.8701477050781241 +0.413375 0.46856689453125 0.060791015625 -0.8701477050781241 +0.4135000000000000512 0.46673583984375 0.060546875 -0.8701477050781241 +0.413625 0.464813232421875 0.060302734375 -0.8701477050781241 +0.41375 0.464813232421875 0.060302734375 -0.8701477050781241 +0.413875 0.462890625 0.06005859375 -0.8701477050781241 +0.4140000000000000512 0.462890625 0.06005859375 -0.8701477050781241 +0.414125 0.46087646484375 0.059783935546875 -0.8701477050781241 +0.41425 0.458831787109375 0.059539794921875 -0.8701477050781241 +0.414375 0.458831787109375 0.059539794921875 -0.8701477050781241 +0.4145000000000000512 0.45672607421875 0.05926513671875 -0.8701477050781241 +0.414625 0.45672607421875 0.05926513671875 -0.8701477050781241 +0.41475 0.454559326171875 0.0589599609375 -0.8701477050781241 +0.414875 0.452362060546875 0.058685302734375 -0.8701477050781241 +0.4150000000000000512 0.452362060546875 0.058685302734375 -0.8701477050781241 +0.415125 0.450103759765625 0.058380126953125 -0.8701477050781241 +0.41525 0.450103759765625 0.058380126953125 -0.8701477050781241 +0.415375 0.447784423828125 0.05810546875 -0.8701477050781241 +0.4155000000000000512 0.4454345703125 0.05780029296875 -0.8701477050781241 +0.415625 0.4454345703125 0.05780029296875 -0.8701477050781241 +0.41575 0.44305419921875 0.057464599609375 -0.8701477050781241 +0.415875 0.44305419921875 0.057464599609375 -0.8701477050781241 +0.416000000000000036 0.440582275390625 0.1727294921875 -0.6078857421874979 +0.416125 0.438079833984375 0.1717529296875 -0.6078857421874979 +0.41625 0.438079833984375 0.1717529296875 -0.6078857421874979 +0.416375 0.435546875 0.170745849609375 -0.6078857421874979 +0.4165 0.435546875 0.170745849609375 -0.6078857421874979 +0.416625 0.432952880859375 0.16973876953125 -0.6078857421874979 +0.41675 0.4302978515625 0.168701171875 -0.6078857421874979 +0.416875 0.4302978515625 0.168701171875 -0.6078857421874979 +0.417 0.4276123046875 0.167633056640625 -0.6078857421874979 +0.417125 0.4276123046875 0.167633056640625 -0.6078857421874979 +0.41725 0.424896240234375 0.16656494140625 -0.6078857421874979 +0.417375 0.422119140625 0.16546630859375 -0.6078857421874979 +0.4175 0.422119140625 0.16546630859375 -0.6078857421874979 +0.417625 0.419281005859375 0.16436767578125 -0.6078857421874979 +0.41775 0.419281005859375 0.16436767578125 -0.6078857421874979 +0.417875 0.416412353515625 0.163238525390625 -0.6078857421874979 +0.418 0.413482666015625 0.162078857421875 -0.6078857421874979 +0.418125 0.413482666015625 0.162078857421875 -0.6078857421874979 +0.41825 0.4105224609375 0.160919189453125 -0.6078857421874979 +0.418375 0.4105224609375 0.160919189453125 -0.6078857421874979 +0.4185 0.407501220703125 0.159759521484375 -0.6078857421874979 +0.418625 0.404449462890625 0.1585693359375 -0.6078857421874979 +0.41875 0.404449462890625 0.1585693359375 -0.6078857421874979 +0.418875 0.401336669921875 0.1573486328125 -0.6078857421874979 +0.419 0.401336669921875 0.1573486328125 -0.6078857421874979 +0.419125 0.398193359375 0.156097412109375 -0.6078857421874979 +0.41925 0.39501953125 0.154876708984375 -0.6078857421874979 +0.419375 0.39501953125 0.154876708984375 -0.6078857421874979 +0.4195 0.39178466796875 0.153594970703125 -0.6078857421874979 +0.419625 0.39178466796875 0.153594970703125 -0.6078857421874979 +0.41975 0.388519287109375 0.152313232421875 -0.6078857421874979 +0.419875 0.38519287109375 0.1510009765625 -0.6078857421874979 +0.42 0.38519287109375 0.1510009765625 -0.6078857421874979 +0.420125 0.3818359375 0.149688720703125 -0.6078857421874979 +0.42025 0.3818359375 0.149688720703125 -0.6078857421874979 +0.420375 0.378448486328125 0.148345947265625 -0.6078857421874979 +0.4205 0.375 0.147003173828125 -0.6078857421874979 +0.420625 0.375 0.147003173828125 -0.6078857421874979 +0.42075 0.37152099609375 0.1456298828125 -0.6078857421874979 +0.420875 0.37152099609375 0.1456298828125 -0.6078857421874979 +0.421 0.36798095703125 0.144256591796875 -0.6078857421874979 +0.421125 0.36444091796875 0.14288330078125 -0.6078857421874979 +0.42125 0.36444091796875 0.14288330078125 -0.6078857421874979 +0.421375 0.360809326171875 0.141448974609375 -0.6078857421874979 +0.4215 0.360809326171875 0.141448974609375 -0.6078857421874979 +0.421625 0.357177734375 0.1400146484375 -0.6078857421874979 +0.42175 0.353485107421875 0.138580322265625 -0.6078857421874979 +0.421875 0.353485107421875 0.138580322265625 -0.6078857421874979 +0.422 0.349761962890625 0.137115478515625 -0.6078857421874979 +0.4221250000000000512 0.349761962890625 0.137115478515625 -0.6078857421874979 +0.42225 0.34600830078125 0.135650634765625 -0.6078857421874979 +0.422375 0.34222412109375 0.1341552734375 -0.6078857421874979 +0.4225 0.34222412109375 0.1341552734375 -0.6078857421874979 +0.4226250000000000512 0.33837890625 0.132659912109375 -0.6078857421874979 +0.42275 0.33837890625 0.132659912109375 -0.6078857421874979 +0.422875 0.334503173828125 0.131134033203125 -0.6078857421874979 +0.423 0.330596923828125 0.129608154296875 -0.6078857421874979 +0.4231250000000000512 0.330596923828125 0.129608154296875 -0.6078857421874979 +0.42325 0.32666015625 0.1280517578125 -0.6078857421874979 +0.423375 0.32666015625 0.1280517578125 -0.6078857421874979 +0.4235 0.322662353515625 0.126495361328125 -0.6078857421874979 +0.4236250000000000512 0.31866455078125 0.124908447265625 -0.6078857421874979 +0.42375 0.31866455078125 0.124908447265625 -0.6078857421874979 +0.423875 0.314605712890625 0.123321533203125 -0.6078857421874979 +0.424 0.314605712890625 0.123321533203125 -0.6078857421874979 +0.4241250000000000512 0.310516357421875 0.121734619140625 -0.6078857421874979 +0.42425 0.306396484375 0.1201171875 -0.6078857421874979 +0.424375 0.306396484375 0.1201171875 -0.6078857421874979 +0.4245 0.30224609375 0.118499755859375 -0.6078857421874979 +0.4246250000000000512 0.30224609375 0.118499755859375 -0.6078857421874979 +0.42475 0.298065185546875 0.116851806640625 -0.6078857421874979 +0.424875 0.2938232421875 0.115203857421875 -0.6078857421874979 +0.425 0.2938232421875 0.115203857421875 -0.6078857421874979 +0.4251250000000000512 0.289581298828125 0.113525390625 -0.6078857421874979 +0.42525 0.289581298828125 0.113525390625 -0.6078857421874979 +0.425375 0.285308837890625 0.111846923828125 -0.6078857421874979 +0.4255 0.280975341796875 0.110137939453125 -0.6078857421874979 +0.4256250000000000512 0.280975341796875 0.110137939453125 -0.6078857421874979 +0.42575 0.276641845703125 0.10845947265625 -0.6078857421874979 +0.425875 0.276641845703125 0.10845947265625 -0.6078857421874979 +0.426 0.27227783203125 0.10675048828125 -0.6078857421874979 +0.4261250000000000512 0.267852783203125 0.105010986328125 -0.6078857421874979 +0.42625 0.267852783203125 0.105010986328125 -0.6078857421874979 +0.426375 0.263427734375 0.103271484375 -0.6078857421874979 +0.4265 0.263427734375 0.103271484375 -0.6078857421874979 +0.4266250000000000512 0.25897216796875 0.101531982421875 -0.6078857421874979 +0.42675 0.25445556640625 0.099761962890625 -0.6078857421874979 +0.426875 0.25445556640625 0.099761962890625 -0.6078857421874979 +0.427 0.249969482421875 0.097991943359375 -0.6078857421874979 +0.4271250000000000512 0.249969482421875 0.097991943359375 -0.6078857421874979 +0.42725 0.24542236328125 0.09619140625 -0.6078857421874979 +0.427375 0.2408447265625 0.09442138671875 -0.6078857421874979 +0.4275 0.2408447265625 0.09442138671875 -0.6078857421874979 +0.4276250000000000512 0.236236572265625 0.092620849609375 -0.6078857421874979 +0.42775 0.236236572265625 0.092620849609375 -0.6078857421874979 +0.427875 0.231597900390625 0.090789794921875 -0.6078857421874979 +0.428 0.226959228515625 0.088958740234375 -0.6078857421874979 +0.4281250000000000512 0.226959228515625 0.088958740234375 -0.6078857421874979 +0.42825 0.2222900390625 0.087127685546875 -0.6078857421874979 +0.428375 0.2222900390625 0.087127685546875 -0.6078857421874979 +0.4285 0.21759033203125 0.085296630859375 -0.6078857421874979 +0.4286250000000000512 0.212860107421875 0.08343505859375 -0.6078857421874979 +0.42875 0.212860107421875 0.08343505859375 -0.6078857421874979 +0.428875 0.208099365234375 0.081573486328125 -0.6078857421874979 +0.429 0.208099365234375 0.081573486328125 -0.6078857421874979 +0.4291250000000000512 0.203338623046875 0.0797119140625 -0.6078857421874979 +0.42925 0.19854736328125 0.07781982421875 -0.6078857421874979 +0.429375 0.19854736328125 0.07781982421875 -0.6078857421874979 +0.4295 0.1937255859375 0.075927734375 -0.6078857421874979 +0.4296250000000000512 0.1937255859375 0.075927734375 -0.6078857421874979 +0.42975 0.188873291015625 0.07403564453125 -0.6078857421874979 +0.429875 0.18402099609375 0.0721435546875 -0.6078857421874979 +0.43 0.18402099609375 0.0721435546875 -0.6078857421874979 +0.4301250000000000512 0.17913818359375 0.070220947265625 -0.6078857421874979 +0.43025 0.17913818359375 0.070220947265625 -0.6078857421874979 +0.430375 0.17425537109375 0.06829833984375 -0.6078857421874979 +0.4305 0.169342041015625 0.066375732421875 -0.6078857421874979 +0.4306250000000000512 0.169342041015625 0.066375732421875 -0.6078857421874979 +0.43075 0.164398193359375 0.064453125 -0.6078857421874979 +0.430875 0.164398193359375 0.064453125 -0.6078857421874979 +0.431 0.159454345703125 0.0625 -0.6078857421874979 +0.4311250000000000512 0.15447998046875 0.060546875 -0.6078857421874979 +0.43125 0.15447998046875 0.060546875 -0.6078857421874979 +0.431375 0.14947509765625 0.05859375 -0.6078857421874979 +0.4315 0.14947509765625 0.05859375 -0.6078857421874979 +0.431625000000000036 0.14447021484375 0.056640625 -0.6078857421874979 +0.43175 0.13946533203125 0.054656982421875 -0.6078857421874979 +0.431875 0.13946533203125 0.054656982421875 -0.6078857421874979 +0.432 0.134429931640625 0.052703857421875 -0.6078857421874979 +0.432125 0.134429931640625 0.052703857421875 -0.6078857421874979 +0.43225 0.129364013671875 0.05072021484375 -0.6078857421874979 +0.432375 0.124298095703125 0.048736572265625 -0.6078857421874979 +0.4325 0.124298095703125 0.048736572265625 -0.6078857421874979 +0.432625 0.119232177734375 0.0467529296875 -0.6078857421874979 +0.43275 0.119232177734375 0.0467529296875 -0.6078857421874979 +0.432875 0.1141357421875 0.04473876953125 -0.6078857421874979 +0.433 0.109039306640625 0.042724609375 -0.6078857421874979 +0.433125 0.109039306640625 0.042724609375 -0.6078857421874979 +0.43325 0.103912353515625 0.040740966796875 -0.6078857421874979 +0.433375 0.103912353515625 0.040740966796875 -0.6078857421874979 +0.4335 0.098785400390625 0.038726806640625 -0.6078857421874979 +0.433625 0.093658447265625 0.036712646484375 -0.6078857421874979 +0.43375 0.093658447265625 0.036712646484375 -0.6078857421874979 +0.433875 0.0885009765625 0.034698486328125 -0.6078857421874979 +0.434 0.0885009765625 0.034698486328125 -0.6078857421874979 +0.434125 0.083343505859375 0.032684326171875 -0.6078857421874979 +0.43425 0.07818603515625 0.0306396484375 -0.6078857421874979 +0.434375 0.07818603515625 0.0306396484375 -0.6078857421874979 +0.4345 0.072998046875 0.02862548828125 -0.6078857421874979 +0.434625 0.072998046875 0.02862548828125 -0.6078857421874979 +0.43475 0.06781005859375 0.026580810546875 -0.6078857421874979 +0.434875 0.0626220703125 0.0245361328125 -0.6078857421874979 +0.435 0.0626220703125 0.0245361328125 -0.6078857421874979 +0.435125 0.05743408203125 0.02252197265625 -0.6078857421874979 +0.43525 0.05743408203125 0.02252197265625 -0.6078857421874979 +0.435375 0.05224609375 0.020477294921875 -0.6078857421874979 +0.4355 0.047027587890625 0.0184326171875 -0.6078857421874979 +0.435625 0.047027587890625 0.0184326171875 -0.6078857421874979 +0.43575 0.04180908203125 0.016387939453125 -0.6078857421874979 +0.435875 0.04180908203125 0.016387939453125 -0.6078857421874979 +0.436 0.036590576171875 0.01434326171875 -0.6078857421874979 +0.436125 0.0313720703125 0.012298583984375 -0.6078857421874979 +0.43625 0.0313720703125 0.012298583984375 -0.6078857421874979 +0.436375 0.026123046875 0.010223388671875 -0.6078857421874979 +0.4365 0.026123046875 0.010223388671875 -0.6078857421874979 +0.436625 0.020904541015625 0.0081787109375 -0.6078857421874979 +0.43675 0.01568603515625 0.006134033203125 -0.6078857421874979 +0.436875 0.01568603515625 0.006134033203125 -0.6078857421874979 +0.437 0.01043701171875 0.00408935546875 -0.6078857421874979 +0.437125 0.01043701171875 0.00408935546875 -0.6078857421874979 +0.43725 0.005218505859375 0.002044677734375 -0.6078857421874979 +0.437375 0.0 0.0 -0.6078857421874979 +0.4375 0.0 0.0 -0.6078857421874979 +0.437625 -0.005218505859375 -0.002044677734375 -0.6078857421874979 +0.4377500000000000512 -0.005218505859375 -0.002044677734375 -0.6078857421874979 +0.437875 -0.01043701171875 -0.00408935546875 -0.6078857421874979 +0.438 -0.01568603515625 -0.006134033203125 -0.6078857421874979 +0.438125 -0.01568603515625 -0.006134033203125 -0.6078857421874979 +0.4382500000000000512 -0.020904541015625 -0.0081787109375 -0.6078857421874979 +0.438375 -0.020904541015625 -0.0081787109375 -0.6078857421874979 +0.4385 -0.026123046875 -0.010223388671875 -0.6078857421874979 +0.438625 -0.0313720703125 -0.012298583984375 -0.6078857421874979 +0.4387500000000000512 -0.0313720703125 -0.012298583984375 -0.6078857421874979 +0.438875 -0.036590576171875 -0.01434326171875 -0.6078857421874979 +0.439 -0.036590576171875 -0.01434326171875 -0.6078857421874979 +0.439125 -0.04180908203125 -0.016387939453125 -0.6078857421874979 +0.4392500000000000512 -0.047027587890625 -0.0184326171875 -0.6078857421874979 +0.439375 -0.047027587890625 -0.0184326171875 -0.6078857421874979 +0.4395 -0.05224609375 -0.020477294921875 -0.6078857421874979 +0.439625 -0.05224609375 -0.020477294921875 -0.6078857421874979 +0.4397500000000000512 -0.05743408203125 -0.02252197265625 -0.6078857421874979 +0.439875 -0.0626220703125 -0.0245361328125 -0.6078857421874979 +0.44 -0.0626220703125 -0.0245361328125 -0.6078857421874979 +0.440125 -0.06781005859375 -0.026580810546875 -0.6078857421874979 +0.4402500000000000512 -0.06781005859375 -0.026580810546875 -0.6078857421874979 +0.440375 -0.072998046875 -0.02862548828125 -0.6078857421874979 +0.4405 -0.07818603515625 -0.0306396484375 -0.6078857421874979 +0.440625 -0.07818603515625 -0.0306396484375 -0.6078857421874979 +0.4407500000000000512 -0.083343505859375 -0.032684326171875 -0.6078857421874979 +0.440875 -0.083343505859375 -0.032684326171875 -0.6078857421874979 +0.441 -0.0885009765625 -0.034698486328125 -0.6078857421874979 +0.441125 -0.093658447265625 -0.036712646484375 -0.6078857421874979 +0.4412500000000000512 -0.093658447265625 -0.036712646484375 -0.6078857421874979 +0.441375 -0.098785400390625 -0.038726806640625 -0.6078857421874979 +0.4415 -0.098785400390625 -0.038726806640625 -0.6078857421874979 +0.441625 -0.103912353515625 -0.040740966796875 -0.6078857421874979 +0.4417500000000000512 -0.109039306640625 -0.042724609375 -0.6078857421874979 +0.441875 -0.109039306640625 -0.042724609375 -0.6078857421874979 +0.442 -0.1141357421875 -0.04473876953125 -0.6078857421874979 +0.442125 -0.1141357421875 -0.04473876953125 -0.6078857421874979 +0.4422500000000000512 -0.119232177734375 -0.0467529296875 -0.6078857421874979 +0.442375 -0.124298095703125 -0.048736572265625 -0.6078857421874979 +0.4425 -0.124298095703125 -0.048736572265625 -0.6078857421874979 +0.442625 -0.129364013671875 -0.05072021484375 -0.6078857421874979 +0.4427500000000000512 -0.129364013671875 -0.05072021484375 -0.6078857421874979 +0.442875 -0.134429931640625 -0.052703857421875 -0.6078857421874979 +0.443 -0.13946533203125 -0.054656982421875 -0.6078857421874979 +0.443125 -0.13946533203125 -0.054656982421875 -0.6078857421874979 +0.4432500000000000512 -0.14447021484375 -0.056640625 -0.6078857421874979 +0.443375 -0.14447021484375 -0.056640625 -0.6078857421874979 +0.4435 -0.14947509765625 -0.05859375 -0.6078857421874979 +0.443625 -0.15447998046875 -0.060546875 -0.6078857421874979 +0.4437500000000000512 -0.15447998046875 -0.060546875 -0.6078857421874979 +0.443875 -0.159454345703125 -0.0625 -0.6078857421874979 +0.444 -0.159454345703125 -0.0625 -0.6078857421874979 +0.444125 -0.164398193359375 -0.064453125 -0.6078857421874979 +0.4442500000000000512 -0.169342041015625 -0.066375732421875 -0.6078857421874979 +0.444375 -0.169342041015625 -0.066375732421875 -0.6078857421874979 +0.4445 -0.17425537109375 -0.06829833984375 -0.6078857421874979 +0.444625 -0.17425537109375 -0.06829833984375 -0.6078857421874979 +0.4447500000000000512 -0.17913818359375 -0.070220947265625 -0.6078857421874979 +0.444875 -0.18402099609375 -0.0721435546875 -0.6078857421874979 +0.445 -0.18402099609375 -0.0721435546875 -0.6078857421874979 +0.445125 -0.188873291015625 -0.07403564453125 -0.6078857421874979 +0.4452500000000000512 -0.188873291015625 -0.07403564453125 -0.6078857421874979 +0.445375 -0.1937255859375 -0.075927734375 -0.6078857421874979 +0.4455 -0.19854736328125 -0.07781982421875 -0.6078857421874979 +0.445625 -0.19854736328125 -0.07781982421875 -0.6078857421874979 +0.4457500000000000512 -0.203338623046875 -0.0797119140625 -0.6078857421874979 +0.445875 -0.203338623046875 -0.0797119140625 -0.6078857421874979 +0.446 -0.208099365234375 -0.081573486328125 -0.6078857421874979 +0.446125 -0.212860107421875 -0.08343505859375 -0.6078857421874979 +0.4462500000000000512 -0.212860107421875 -0.08343505859375 -0.6078857421874979 +0.446375 -0.21759033203125 -0.085296630859375 -0.6078857421874979 +0.4465 -0.21759033203125 -0.085296630859375 -0.6078857421874979 +0.446625 -0.2222900390625 -0.087127685546875 -0.6078857421874979 +0.4467500000000000512 -0.226959228515625 -0.088958740234375 -0.6078857421874979 +0.446875 -0.226959228515625 -0.088958740234375 -0.6078857421874979 +0.447 -0.231597900390625 -0.090789794921875 -0.6078857421874979 +0.447125 -0.231597900390625 -0.090789794921875 -0.6078857421874979 +0.447250000000000036 -0.236236572265625 -0.092620849609375 -0.6078857421874979 +0.447375 -0.2408447265625 -0.09442138671875 -0.6078857421874979 +0.4475 -0.2408447265625 -0.09442138671875 -0.6078857421874979 +0.447625 -0.24542236328125 -0.09619140625 -0.6078857421874979 +0.447750000000000036 -0.24542236328125 -0.09619140625 -0.6078857421874979 +0.447875 -0.249969482421875 -0.097991943359375 -0.6078857421874979 +0.448 -0.25445556640625 -0.191192626953125 -0.2486572265624977 +0.448125 -0.25445556640625 -0.191192626953125 -0.2486572265624977 +0.44825 -0.25897216796875 -0.194549560546875 -0.2486572265624977 +0.448375 -0.25897216796875 -0.194549560546875 -0.2486572265624977 +0.4485 -0.263427734375 -0.197906494140625 -0.2486572265624977 +0.448625 -0.267852783203125 -0.20123291015625 -0.2486572265624977 +0.44875 -0.267852783203125 -0.20123291015625 -0.2486572265624977 +0.448875 -0.27227783203125 -0.204559326171875 -0.2486572265624977 +0.449 -0.27227783203125 -0.204559326171875 -0.2486572265624977 +0.449125 -0.276641845703125 -0.20782470703125 -0.2486572265624977 +0.44925 -0.280975341796875 -0.211090087890625 -0.2486572265624977 +0.449375 -0.280975341796875 -0.211090087890625 -0.2486572265624977 +0.4495 -0.285308837890625 -0.21435546875 -0.2486572265624977 +0.449625 -0.285308837890625 -0.21435546875 -0.2486572265624977 +0.44975 -0.289581298828125 -0.217559814453125 -0.2486572265624977 +0.449875 -0.2938232421875 -0.22076416015625 -0.2486572265624977 +0.45 -0.2938232421875 -0.22076416015625 -0.2486572265624977 +0.450125 -0.298065185546875 -0.22393798828125 -0.2486572265624977 +0.45025 -0.298065185546875 -0.22393798828125 -0.2486572265624977 +0.450375 -0.30224609375 -0.227081298828125 -0.2486572265624977 +0.4505 -0.306396484375 -0.230194091796875 -0.2486572265624977 +0.450625 -0.306396484375 -0.230194091796875 -0.2486572265624977 +0.45075 -0.310516357421875 -0.233306884765625 -0.2486572265624977 +0.450875 -0.310516357421875 -0.233306884765625 -0.2486572265624977 +0.451 -0.314605712890625 -0.236358642578125 -0.2486572265624977 +0.451125 -0.31866455078125 -0.239410400390625 -0.2486572265624977 +0.45125 -0.31866455078125 -0.239410400390625 -0.2486572265624977 +0.451375 -0.322662353515625 -0.242431640625 -0.2486572265624977 +0.4515 -0.322662353515625 -0.242431640625 -0.2486572265624977 +0.451625 -0.32666015625 -0.24542236328125 -0.2486572265624977 +0.45175 -0.330596923828125 -0.248382568359375 -0.2486572265624977 +0.451875 -0.330596923828125 -0.248382568359375 -0.2486572265624977 +0.452 -0.334503173828125 -0.251312255859375 -0.2486572265624977 +0.452125 -0.334503173828125 -0.251312255859375 -0.2486572265624977 +0.45225 -0.33837890625 -0.254241943359375 -0.2486572265624977 +0.452375 -0.34222412109375 -0.257110595703125 -0.2486572265624977 +0.4525 -0.34222412109375 -0.257110595703125 -0.2486572265624977 +0.452625 -0.34600830078125 -0.25994873046875 -0.2486572265624977 +0.45275 -0.34600830078125 -0.25994873046875 -0.2486572265624977 +0.452875 -0.349761962890625 -0.262786865234375 -0.2486572265624977 +0.453 -0.353485107421875 -0.26556396484375 -0.2486572265624977 +0.453125 -0.353485107421875 -0.26556396484375 -0.2486572265624977 +0.45325 -0.357177734375 -0.268341064453125 -0.2486572265624977 +0.4533750000000000512 -0.357177734375 -0.268341064453125 -0.2486572265624977 +0.4535 -0.360809326171875 -0.271087646484375 -0.2486572265624977 +0.453625 -0.36444091796875 -0.2738037109375 -0.2486572265624977 +0.45375 -0.36444091796875 -0.2738037109375 -0.2486572265624977 +0.4538750000000000512 -0.36798095703125 -0.276458740234375 -0.2486572265624977 +0.454 -0.36798095703125 -0.276458740234375 -0.2486572265624977 +0.454125 -0.37152099609375 -0.27911376953125 -0.2486572265624977 +0.45425 -0.375 -0.28173828125 -0.2486572265624977 +0.4543750000000000512 -0.375 -0.28173828125 -0.2486572265624977 +0.4545 -0.378448486328125 -0.284332275390625 -0.2486572265624977 +0.454625 -0.378448486328125 -0.284332275390625 -0.2486572265624977 +0.45475 -0.3818359375 -0.286865234375 -0.2486572265624977 +0.4548750000000000512 -0.38519287109375 -0.289398193359375 -0.2486572265624977 +0.455 -0.38519287109375 -0.289398193359375 -0.2486572265624977 +0.455125 -0.388519287109375 -0.2918701171875 -0.2486572265624977 +0.45525 -0.388519287109375 -0.2918701171875 -0.2486572265624977 +0.4553750000000000512 -0.39178466796875 -0.294342041015625 -0.2486572265624977 +0.4555 -0.39501953125 -0.296783447265625 -0.2486572265624977 +0.455625 -0.39501953125 -0.296783447265625 -0.2486572265624977 +0.45575 -0.398193359375 -0.299163818359375 -0.2486572265624977 +0.4558750000000000512 -0.398193359375 -0.299163818359375 -0.2486572265624977 +0.456 -0.401336669921875 -0.301513671875 -0.2486572265624977 +0.456125 -0.404449462890625 -0.303863525390625 -0.2486572265624977 +0.45625 -0.404449462890625 -0.303863525390625 -0.2486572265624977 +0.4563750000000000512 -0.407501220703125 -0.30615234375 -0.2486572265624977 +0.4565 -0.407501220703125 -0.30615234375 -0.2486572265624977 +0.456625 -0.4105224609375 -0.30841064453125 -0.2486572265624977 +0.45675 -0.413482666015625 -0.310638427734375 -0.2486572265624977 +0.4568750000000000512 -0.413482666015625 -0.310638427734375 -0.2486572265624977 +0.457 -0.416412353515625 -0.312835693359375 -0.2486572265624977 +0.457125 -0.416412353515625 -0.312835693359375 -0.2486572265624977 +0.45725 -0.419281005859375 -0.31500244140625 -0.2486572265624977 +0.4573750000000000512 -0.422119140625 -0.317138671875 -0.2486572265624977 +0.4575 -0.422119140625 -0.317138671875 -0.2486572265624977 +0.457625 -0.424896240234375 -0.3192138671875 -0.2486572265624977 +0.45775 -0.424896240234375 -0.3192138671875 -0.2486572265624977 +0.4578750000000000512 -0.4276123046875 -0.321258544921875 -0.2486572265624977 +0.458 -0.4302978515625 -0.323272705078125 -0.2486572265624977 +0.458125 -0.4302978515625 -0.323272705078125 -0.2486572265624977 +0.45825 -0.432952880859375 -0.325286865234375 -0.2486572265624977 +0.4583750000000000512 -0.432952880859375 -0.325286865234375 -0.2486572265624977 +0.4585 -0.435546875 -0.32720947265625 -0.2486572265624977 +0.458625 -0.438079833984375 -0.329132080078125 -0.2486572265624977 +0.45875 -0.438079833984375 -0.329132080078125 -0.2486572265624977 +0.4588750000000000512 -0.440582275390625 -0.33099365234375 -0.2486572265624977 +0.459 -0.440582275390625 -0.33099365234375 -0.2486572265624977 +0.459125 -0.44305419921875 -0.332855224609375 -0.2486572265624977 +0.45925 -0.4454345703125 -0.33465576171875 -0.2486572265624977 +0.4593750000000000512 -0.4454345703125 -0.33465576171875 -0.2486572265624977 +0.4595 -0.447784423828125 -0.33642578125 -0.2486572265624977 +0.459625 -0.447784423828125 -0.33642578125 -0.2486572265624977 +0.45975 -0.450103759765625 -0.338134765625 -0.2486572265624977 +0.4598750000000000512 -0.452362060546875 -0.33984375 -0.2486572265624977 +0.46 -0.452362060546875 -0.33984375 -0.2486572265624977 +0.460125 -0.454559326171875 -0.34149169921875 -0.2486572265624977 +0.46025 -0.454559326171875 -0.34149169921875 -0.2486572265624977 +0.4603750000000000512 -0.45672607421875 -0.343109130859375 -0.2486572265624977 +0.4605 -0.458831787109375 -0.344696044921875 -0.2486572265624977 +0.460625 -0.458831787109375 -0.344696044921875 -0.2486572265624977 +0.46075 -0.46087646484375 -0.34625244140625 -0.2486572265624977 +0.4608750000000000512 -0.46087646484375 -0.34625244140625 -0.2486572265624977 +0.461 -0.462890625 -0.347747802734375 -0.2486572265624977 +0.461125 -0.464813232421875 -0.349212646484375 -0.2486572265624977 +0.46125 -0.464813232421875 -0.349212646484375 -0.2486572265624977 +0.461375000000000052 -0.46673583984375 -0.35064697265625 -0.2486572265624977 +0.4615 -0.46673583984375 -0.35064697265625 -0.2486572265624977 +0.461625 -0.46856689453125 -0.352020263671875 -0.2486572265624977 +0.46175 -0.470367431640625 -0.3533935546875 -0.2486572265624977 +0.461875000000000052 -0.470367431640625 -0.3533935546875 -0.2486572265624977 +0.462 -0.472137451171875 -0.354705810546875 -0.2486572265624977 +0.462125 -0.472137451171875 -0.354705810546875 -0.2486572265624977 +0.46225 -0.47381591796875 -0.355987548828125 -0.2486572265624977 +0.462375000000000052 -0.4754638671875 -0.357208251953125 -0.2486572265624977 +0.4625 -0.4754638671875 -0.357208251953125 -0.2486572265624977 +0.462625 -0.47705078125 -0.3583984375 -0.2486572265624977 +0.46275 -0.47705078125 -0.3583984375 -0.2486572265624977 +0.462875000000000064 -0.478607177734375 -0.35955810546875 -0.2486572265624977 +0.463 -0.480072021484375 -0.360687255859375 -0.2486572265624977 +0.463125 -0.480072021484375 -0.360687255859375 -0.2486572265624977 +0.46325 -0.48150634765625 -0.36175537109375 -0.2486572265624977 +0.463375000000000064 -0.48150634765625 -0.36175537109375 -0.2486572265624977 +0.4635 -0.48291015625 -0.36279296875 -0.2486572265624977 +0.463625 -0.484222412109375 -0.363800048828125 -0.2486572265624977 +0.46375 -0.484222412109375 -0.363800048828125 -0.2486572265624977 +0.463875000000000064 -0.485504150390625 -0.36474609375 -0.2486572265624977 +0.464 -0.485504150390625 -0.36474609375 -0.2486572265624977 +0.464125 -0.486724853515625 -0.36566162109375 -0.2486572265624977 +0.46425 -0.487884521484375 -0.366546630859375 -0.2486572265624977 +0.464375 -0.487884521484375 -0.366546630859375 -0.2486572265624977 +0.4645 -0.489013671875 -0.36737060546875 -0.2486572265624977 +0.464625 -0.489013671875 -0.36737060546875 -0.2486572265624977 +0.46475 -0.490081787109375 -0.368194580078125 -0.2486572265624977 +0.464875 -0.4910888671875 -0.368927001953125 -0.2486572265624977 +0.465 -0.4910888671875 -0.368927001953125 -0.2486572265624977 +0.465125 -0.492034912109375 -0.369659423828125 -0.2486572265624977 +0.46525 -0.492034912109375 -0.369659423828125 -0.2486572265624977 +0.465375 -0.492950439453125 -0.370330810546875 -0.2486572265624977 +0.4655 -0.4937744140625 -0.3709716796875 -0.2486572265624977 +0.465625 -0.4937744140625 -0.3709716796875 -0.2486572265624977 +0.46575 -0.49456787109375 -0.371551513671875 -0.2486572265624977 +0.465875 -0.49456787109375 -0.371551513671875 -0.2486572265624977 +0.466 -0.49530029296875 -0.372100830078125 -0.2486572265624977 +0.466125 -0.496002197265625 -0.37261962890625 -0.2486572265624977 +0.46625 -0.496002197265625 -0.37261962890625 -0.2486572265624977 +0.466375 -0.496612548828125 -0.37310791015625 -0.2486572265624977 +0.4665 -0.496612548828125 -0.37310791015625 -0.2486572265624977 +0.466625 -0.4971923828125 -0.37353515625 -0.2486572265624977 +0.46675 -0.497711181640625 -0.373931884765625 -0.2486572265624977 +0.466875 -0.497711181640625 -0.373931884765625 -0.2486572265624977 +0.467 -0.498199462890625 -0.374267578125 -0.2486572265624977 +0.467125 -0.498199462890625 -0.374267578125 -0.2486572265624977 +0.46725 -0.49859619140625 -0.374603271484375 -0.2486572265624977 +0.467375 -0.49896240234375 -0.374847412109375 -0.2486572265624977 +0.4675 -0.49896240234375 -0.374847412109375 -0.2486572265624977 +0.467625 -0.499267578125 -0.375091552734375 -0.2486572265624977 +0.46775 -0.499267578125 -0.375091552734375 -0.2486572265624977 +0.467875 -0.49951171875 -0.375274658203125 -0.2486572265624977 +0.468 -0.49969482421875 -0.375396728515625 -0.2486572265624977 +0.468125 -0.49969482421875 -0.375396728515625 -0.2486572265624977 +0.46825 -0.49981689453125 -0.375518798828125 -0.2486572265624977 +0.468375 -0.49981689453125 -0.375518798828125 -0.2486572265624977 +0.4685 -0.499908447265625 -0.375579833984375 -0.2486572265624977 +0.468625 -0.49993896484375 -0.3756103515625 -0.2486572265624977 +0.46875 -0.49993896484375 -0.3756103515625 -0.2486572265624977 +0.468875 -0.499908447265625 -0.375579833984375 -0.2486572265624977 +0.469000000000000052 -0.499908447265625 -0.375579833984375 -0.2486572265624977 +0.469125 -0.49981689453125 -0.375518798828125 -0.2486572265624977 +0.46925 -0.49969482421875 -0.375396728515625 -0.2486572265624977 +0.469375 -0.49969482421875 -0.375396728515625 -0.2486572265624977 +0.469500000000000052 -0.49951171875 -0.375274658203125 -0.2486572265624977 +0.469625 -0.49951171875 -0.375274658203125 -0.2486572265624977 +0.46975 -0.499267578125 -0.375091552734375 -0.2486572265624977 +0.469875 -0.49896240234375 -0.374847412109375 -0.2486572265624977 +0.470000000000000052 -0.49896240234375 -0.374847412109375 -0.2486572265624977 +0.470125 -0.49859619140625 -0.374603271484375 -0.2486572265624977 +0.47025 -0.49859619140625 -0.374603271484375 -0.2486572265624977 +0.470375 -0.498199462890625 -0.374267578125 -0.2486572265624977 +0.470500000000000052 -0.497711181640625 -0.373931884765625 -0.2486572265624977 +0.470625 -0.497711181640625 -0.373931884765625 -0.2486572265624977 +0.47075 -0.4971923828125 -0.37353515625 -0.2486572265624977 +0.470875 -0.4971923828125 -0.37353515625 -0.2486572265624977 +0.471000000000000052 -0.496612548828125 -0.37310791015625 -0.2486572265624977 +0.471125 -0.496002197265625 -0.37261962890625 -0.2486572265624977 +0.47125 -0.496002197265625 -0.37261962890625 -0.2486572265624977 +0.471375 -0.49530029296875 -0.372100830078125 -0.2486572265624977 +0.471500000000000052 -0.49530029296875 -0.372100830078125 -0.2486572265624977 +0.471625 -0.49456787109375 -0.371551513671875 -0.2486572265624977 +0.47175 -0.4937744140625 -0.3709716796875 -0.2486572265624977 +0.471875 -0.4937744140625 -0.3709716796875 -0.2486572265624977 +0.472000000000000052 -0.492950439453125 -0.370330810546875 -0.2486572265624977 +0.472125 -0.492950439453125 -0.370330810546875 -0.2486572265624977 +0.47225 -0.492034912109375 -0.369659423828125 -0.2486572265624977 +0.472375 -0.4910888671875 -0.368927001953125 -0.2486572265624977 +0.472500000000000052 -0.4910888671875 -0.368927001953125 -0.2486572265624977 +0.472625 -0.490081787109375 -0.368194580078125 -0.2486572265624977 +0.47275 -0.490081787109375 -0.368194580078125 -0.2486572265624977 +0.472875 -0.489013671875 -0.36737060546875 -0.2486572265624977 +0.473000000000000052 -0.487884521484375 -0.366546630859375 -0.2486572265624977 +0.473125 -0.487884521484375 -0.366546630859375 -0.2486572265624977 +0.47325 -0.486724853515625 -0.36566162109375 -0.2486572265624977 +0.473375 -0.486724853515625 -0.36566162109375 -0.2486572265624977 +0.473500000000000052 -0.485504150390625 -0.36474609375 -0.2486572265624977 +0.473625 -0.484222412109375 -0.363800048828125 -0.2486572265624977 +0.47375 -0.484222412109375 -0.363800048828125 -0.2486572265624977 +0.473875 -0.48291015625 -0.36279296875 -0.2486572265624977 +0.474000000000000052 -0.48291015625 -0.36279296875 -0.2486572265624977 +0.474125 -0.48150634765625 -0.36175537109375 -0.2486572265624977 +0.47425 -0.480072021484375 -0.360687255859375 -0.2486572265624977 +0.474375 -0.480072021484375 -0.360687255859375 -0.2486572265624977 +0.474500000000000052 -0.478607177734375 -0.35955810546875 -0.2486572265624977 +0.474625 -0.478607177734375 -0.35955810546875 -0.2486572265624977 +0.47475 -0.47705078125 -0.3583984375 -0.2486572265624977 +0.474875 -0.4754638671875 -0.357208251953125 -0.2486572265624977 +0.475000000000000052 -0.4754638671875 -0.357208251953125 -0.2486572265624977 +0.475125 -0.47381591796875 -0.355987548828125 -0.2486572265624977 +0.47525 -0.47381591796875 -0.355987548828125 -0.2486572265624977 +0.475375 -0.472137451171875 -0.354705810546875 -0.2486572265624977 +0.475500000000000052 -0.470367431640625 -0.3533935546875 -0.2486572265624977 +0.475625 -0.470367431640625 -0.3533935546875 -0.2486572265624977 +0.47575 -0.46856689453125 -0.352020263671875 -0.2486572265624977 +0.475875 -0.46856689453125 -0.352020263671875 -0.2486572265624977 +0.476000000000000052 -0.46673583984375 -0.35064697265625 -0.2486572265624977 +0.476125 -0.464813232421875 -0.349212646484375 -0.2486572265624977 +0.47625 -0.464813232421875 -0.349212646484375 -0.2486572265624977 +0.476375 -0.462890625 -0.347747802734375 -0.2486572265624977 +0.476500000000000052 -0.462890625 -0.347747802734375 -0.2486572265624977 +0.476625 -0.46087646484375 -0.34625244140625 -0.2486572265624977 +0.47675 -0.458831787109375 -0.344696044921875 -0.2486572265624977 +0.476875 -0.458831787109375 -0.344696044921875 -0.2486572265624977 +0.477000000000000052 -0.45672607421875 -0.343109130859375 -0.2486572265624977 +0.477125 -0.45672607421875 -0.343109130859375 -0.2486572265624977 +0.47725 -0.454559326171875 -0.34149169921875 -0.2486572265624977 +0.477375 -0.452362060546875 -0.33984375 -0.2486572265624977 +0.477500000000000052 -0.452362060546875 -0.33984375 -0.2486572265624977 +0.477625 -0.450103759765625 -0.338134765625 -0.2486572265624977 +0.47775 -0.450103759765625 -0.338134765625 -0.2486572265624977 +0.477875 -0.447784423828125 -0.33642578125 -0.2486572265624977 +0.478000000000000052 -0.4454345703125 -0.33465576171875 -0.2486572265624977 +0.478125 -0.4454345703125 -0.33465576171875 -0.2486572265624977 +0.47825 -0.44305419921875 -0.332855224609375 -0.2486572265624977 +0.478375 -0.44305419921875 -0.332855224609375 -0.2486572265624977 +0.478500000000000064 -0.440582275390625 -0.33099365234375 -0.2486572265624977 +0.478625 -0.438079833984375 -0.329132080078125 -0.2486572265624977 +0.47875 -0.438079833984375 -0.329132080078125 -0.2486572265624977 +0.478875 -0.435546875 -0.32720947265625 -0.2486572265624977 +0.479000000000000064 -0.435546875 -0.32720947265625 -0.2486572265624977 +0.479125 -0.432952880859375 -0.325286865234375 -0.2486572265624977 +0.47925 -0.4302978515625 -0.323272705078125 -0.2486572265624977 +0.479375 -0.4302978515625 -0.323272705078125 -0.2486572265624977 +0.479500000000000064 -0.4276123046875 -0.321258544921875 -0.2486572265624977 +0.479625 -0.4276123046875 -0.321258544921875 -0.2486572265624977 +0.47975 -0.424896240234375 -0.3192138671875 -0.2486572265624977 +0.479875 -0.422119140625 -0.317138671875 -0.2486572265624977 +0.48 -0.358673095703125 -0.422119140625 0.1501953125000029 +0.480125 -0.35626220703125 -0.419281005859375 0.1501953125000029 +0.48025 -0.35626220703125 -0.419281005859375 0.1501953125000029 +0.480375 -0.353851318359375 -0.416412353515625 0.1501953125000029 +0.4805 -0.351348876953125 -0.413482666015625 0.1501953125000029 +0.480625 -0.351348876953125 -0.413482666015625 0.1501953125000029 +0.48075 -0.348846435546875 -0.4105224609375 0.1501953125000029 +0.480875 -0.348846435546875 -0.4105224609375 0.1501953125000029 +0.481 -0.346282958984375 -0.407501220703125 0.1501953125000029 +0.481125 -0.34368896484375 -0.404449462890625 0.1501953125000029 +0.48125 -0.34368896484375 -0.404449462890625 0.1501953125000029 +0.481375 -0.341033935546875 -0.401336669921875 0.1501953125000029 +0.4815 -0.341033935546875 -0.401336669921875 0.1501953125000029 +0.481625 -0.33837890625 -0.398193359375 0.1501953125000029 +0.48175 -0.335662841796875 -0.39501953125 0.1501953125000029 +0.481875 -0.335662841796875 -0.39501953125 0.1501953125000029 +0.482 -0.332916259765625 -0.39178466796875 0.1501953125000029 +0.482125 -0.332916259765625 -0.39178466796875 0.1501953125000029 +0.48225 -0.33013916015625 -0.388519287109375 0.1501953125000029 +0.482375 -0.32733154296875 -0.38519287109375 0.1501953125000029 +0.4825 -0.32733154296875 -0.38519287109375 0.1501953125000029 +0.482625 -0.324462890625 -0.3818359375 0.1501953125000029 +0.48275 -0.324462890625 -0.3818359375 0.1501953125000029 +0.482875 -0.321563720703125 -0.378448486328125 0.1501953125000029 +0.483 -0.318634033203125 -0.375 0.1501953125000029 +0.483125 -0.318634033203125 -0.375 0.1501953125000029 +0.48325 -0.315704345703125 -0.37152099609375 0.1501953125000029 +0.483375 -0.315704345703125 -0.37152099609375 0.1501953125000029 +0.4835 -0.31268310546875 -0.36798095703125 0.1501953125000029 +0.483625 -0.309661865234375 -0.36444091796875 0.1501953125000029 +0.48375 -0.309661865234375 -0.36444091796875 0.1501953125000029 +0.483875 -0.306610107421875 -0.360809326171875 0.1501953125000029 +0.484 -0.306610107421875 -0.360809326171875 0.1501953125000029 +0.484125 -0.30352783203125 -0.357177734375 0.1501953125000029 +0.48425 -0.300384521484375 -0.353485107421875 0.1501953125000029 +0.484375 -0.300384521484375 -0.353485107421875 0.1501953125000029 +0.4845 -0.297210693359375 -0.349761962890625 0.1501953125000029 +0.484625000000000052 -0.297210693359375 -0.349761962890625 0.1501953125000029 +0.48475 -0.294036865234375 -0.34600830078125 0.1501953125000029 +0.484875 -0.290802001953125 -0.34222412109375 0.1501953125000029 +0.485 -0.290802001953125 -0.34222412109375 0.1501953125000029 +0.485125000000000052 -0.28753662109375 -0.33837890625 0.1501953125000029 +0.48525 -0.28753662109375 -0.33837890625 0.1501953125000029 +0.485375 -0.28424072265625 -0.334503173828125 0.1501953125000029 +0.4855 -0.28094482421875 -0.330596923828125 0.1501953125000029 +0.485625000000000052 -0.28094482421875 -0.330596923828125 0.1501953125000029 +0.48575 -0.277587890625 -0.32666015625 0.1501953125000029 +0.485875 -0.277587890625 -0.32666015625 0.1501953125000029 +0.486 -0.274200439453125 -0.322662353515625 0.1501953125000029 +0.486125000000000052 -0.270782470703125 -0.31866455078125 0.1501953125000029 +0.48625 -0.270782470703125 -0.31866455078125 0.1501953125000029 +0.486375 -0.267333984375 -0.314605712890625 0.1501953125000029 +0.4865 -0.267333984375 -0.314605712890625 0.1501953125000029 +0.486625000000000052 -0.26385498046875 -0.310516357421875 0.1501953125000029 +0.48675 -0.2603759765625 -0.306396484375 0.1501953125000029 +0.486875 -0.2603759765625 -0.306396484375 0.1501953125000029 +0.487 -0.2568359375 -0.30224609375 0.1501953125000029 +0.487125000000000052 -0.2568359375 -0.30224609375 0.1501953125000029 +0.48725 -0.253265380859375 -0.298065185546875 0.1501953125000029 +0.487375 -0.24969482421875 -0.2938232421875 0.1501953125000029 +0.4875 -0.24969482421875 -0.2938232421875 0.1501953125000029 +0.487625000000000052 -0.24609375 -0.289581298828125 0.1501953125000029 +0.48775 -0.24609375 -0.289581298828125 0.1501953125000029 +0.487875 -0.242431640625 -0.285308837890625 0.1501953125000029 +0.488 -0.23876953125 -0.280975341796875 0.1501953125000029 +0.488125000000000052 -0.23876953125 -0.280975341796875 0.1501953125000029 +0.48825 -0.235076904296875 -0.276641845703125 0.1501953125000029 +0.488375 -0.235076904296875 -0.276641845703125 0.1501953125000029 +0.4885 -0.231353759765625 -0.27227783203125 0.1501953125000029 +0.488625000000000052 -0.227630615234375 -0.267852783203125 0.1501953125000029 +0.48875 -0.227630615234375 -0.267852783203125 0.1501953125000029 +0.488875 -0.223846435546875 -0.263427734375 0.1501953125000029 +0.489 -0.223846435546875 -0.263427734375 0.1501953125000029 +0.489125000000000052 -0.220062255859375 -0.25897216796875 0.1501953125000029 +0.48925 -0.21624755859375 -0.25445556640625 0.1501953125000029 +0.489375 -0.21624755859375 -0.25445556640625 0.1501953125000029 +0.4895 -0.21240234375 -0.249969482421875 0.1501953125000029 +0.489625000000000052 -0.21240234375 -0.249969482421875 0.1501953125000029 +0.48975 -0.208526611328125 -0.24542236328125 0.1501953125000029 +0.489875 -0.20465087890625 -0.2408447265625 0.1501953125000029 +0.49 -0.20465087890625 -0.2408447265625 0.1501953125000029 +0.490125000000000052 -0.20074462890625 -0.236236572265625 0.1501953125000029 +0.49025 -0.20074462890625 -0.236236572265625 0.1501953125000029 +0.490375 -0.196807861328125 -0.231597900390625 0.1501953125000029 +0.4905 -0.192840576171875 -0.226959228515625 0.1501953125000029 +0.490625000000000052 -0.192840576171875 -0.226959228515625 0.1501953125000029 +0.49075 -0.188873291015625 -0.2222900390625 0.1501953125000029 +0.490875 -0.188873291015625 -0.2222900390625 0.1501953125000029 +0.491 -0.18487548828125 -0.21759033203125 0.1501953125000029 +0.491125000000000052 -0.180877685546875 -0.212860107421875 0.1501953125000029 +0.49125 -0.180877685546875 -0.212860107421875 0.1501953125000029 +0.491375 -0.17681884765625 -0.208099365234375 0.1501953125000029 +0.4915 -0.17681884765625 -0.208099365234375 0.1501953125000029 +0.491625000000000052 -0.172760009765625 -0.203338623046875 0.1501953125000029 +0.49175 -0.168701171875 -0.19854736328125 0.1501953125000029 +0.491875 -0.168701171875 -0.19854736328125 0.1501953125000029 +0.492 -0.16461181640625 -0.1937255859375 0.1501953125000029 +0.492125000000000052 -0.16461181640625 -0.1937255859375 0.1501953125000029 +0.49225 -0.160491943359375 -0.188873291015625 0.1501953125000029 +0.492375 -0.1563720703125 -0.18402099609375 0.1501953125000029 +0.4925 -0.1563720703125 -0.18402099609375 0.1501953125000029 +0.492625000000000052 -0.1522216796875 -0.17913818359375 0.1501953125000029 +0.49275 -0.1522216796875 -0.17913818359375 0.1501953125000029 +0.492875 -0.1480712890625 -0.17425537109375 0.1501953125000029 +0.493 -0.143890380859375 -0.169342041015625 0.1501953125000029 +0.493125000000000052 -0.143890380859375 -0.169342041015625 0.1501953125000029 +0.49325 -0.139678955078125 -0.164398193359375 0.1501953125000029 +0.493375 -0.139678955078125 -0.164398193359375 0.1501953125000029 +0.4935 -0.135498046875 -0.159454345703125 0.1501953125000029 +0.493625000000000052 -0.131256103515625 -0.15447998046875 0.1501953125000029 +0.49375 -0.131256103515625 -0.15447998046875 0.1501953125000029 +0.493875 -0.12701416015625 -0.14947509765625 0.1501953125000029 +0.494 -0.12701416015625 -0.14947509765625 0.1501953125000029 +0.494125000000000064 -0.122772216796875 -0.14447021484375 0.1501953125000029 +0.49425 -0.118499755859375 -0.13946533203125 0.1501953125000029 +0.494375 -0.118499755859375 -0.13946533203125 0.1501953125000029 +0.4945 -0.114227294921875 -0.134429931640625 0.1501953125000029 +0.494625000000000064 -0.114227294921875 -0.134429931640625 0.1501953125000029 +0.49475 -0.10992431640625 -0.129364013671875 0.1501953125000029 +0.494875 -0.105621337890625 -0.124298095703125 0.1501953125000029 +0.495 -0.105621337890625 -0.124298095703125 0.1501953125000029 +0.495125000000000064 -0.101318359375 -0.119232177734375 0.1501953125000029 +0.49525 -0.101318359375 -0.119232177734375 0.1501953125000029 +0.495375 -0.09698486328125 -0.1141357421875 0.1501953125000029 +0.4955 -0.0926513671875 -0.109039306640625 0.1501953125000029 +0.495625000000000064 -0.0926513671875 -0.109039306640625 0.1501953125000029 +0.49575 -0.08831787109375 -0.103912353515625 0.1501953125000029 +0.495875 -0.08831787109375 -0.103912353515625 0.1501953125000029 +0.496 -0.083953857421875 -0.098785400390625 0.1501953125000029 +0.496125 -0.07958984375 -0.093658447265625 0.1501953125000029 +0.49625 -0.07958984375 -0.093658447265625 0.1501953125000029 +0.496375 -0.0751953125 -0.0885009765625 0.1501953125000029 +0.4965 -0.0751953125 -0.0885009765625 0.1501953125000029 +0.496625 -0.070831298828125 -0.083343505859375 0.1501953125000029 +0.49675 -0.066436767578125 -0.07818603515625 0.1501953125000029 +0.496875 -0.066436767578125 -0.07818603515625 0.1501953125000029 +0.497 -0.062042236328125 -0.072998046875 0.1501953125000029 +0.497125 -0.062042236328125 -0.072998046875 0.1501953125000029 +0.49725 -0.0576171875 -0.06781005859375 0.1501953125000029 +0.497375 -0.05322265625 -0.0626220703125 0.1501953125000029 +0.4975 -0.05322265625 -0.0626220703125 0.1501953125000029 +0.497625 -0.048797607421875 -0.05743408203125 0.1501953125000029 +0.49775 -0.048797607421875 -0.05743408203125 0.1501953125000029 +0.497875 -0.044403076171875 -0.05224609375 0.1501953125000029 +0.498 -0.039947509765625 -0.047027587890625 0.1501953125000029 +0.498125 -0.039947509765625 -0.047027587890625 0.1501953125000029 +0.49825 -0.0355224609375 -0.04180908203125 0.1501953125000029 +0.498375 -0.0355224609375 -0.04180908203125 0.1501953125000029 +0.4985 -0.031097412109375 -0.036590576171875 0.1501953125000029 +0.498625 -0.026641845703125 -0.0313720703125 0.1501953125000029 +0.49875 -0.026641845703125 -0.0313720703125 0.1501953125000029 +0.498875 -0.022216796875 -0.026123046875 0.1501953125000029 +0.499 -0.022216796875 -0.026123046875 0.1501953125000029 +0.499125 -0.01776123046875 -0.020904541015625 0.1501953125000029 +0.49925 -0.013336181640625 -0.01568603515625 0.1501953125000029 +0.499375 -0.013336181640625 -0.01568603515625 0.1501953125000029 +0.4995 -0.008880615234375 -0.01043701171875 0.1501953125000029 +0.499625 -0.008880615234375 -0.01043701171875 0.1501953125000029 +0.49975 -0.004425048828125 -0.005218505859375 0.1501953125000029 +0.499875 0.0 0.0 0.1501953125000029 +0.5 0.0 0.0 0.1501953125000029 +0.500125 0.004425048828125 0.005218505859375 0.1501953125000029 +0.50025 0.004425048828125 0.005218505859375 0.1501953125000029 +0.500375 0.008880615234375 0.01043701171875 0.1501953125000029 +0.5005000000000001 0.013336181640625 0.01568603515625 0.1501953125000029 +0.500625 0.013336181640625 0.01568603515625 0.1501953125000029 +0.50075 0.01776123046875 0.020904541015625 0.1501953125000029 +0.500875 0.01776123046875 0.020904541015625 0.1501953125000029 +0.501 0.022216796875 0.026123046875 0.1501953125000029 +0.501125 0.026641845703125 0.0313720703125 0.1501953125000029 +0.50125 0.026641845703125 0.0313720703125 0.1501953125000029 +0.501375 0.031097412109375 0.036590576171875 0.1501953125000029 +0.5015000000000001 0.031097412109375 0.036590576171875 0.1501953125000029 +0.501625 0.0355224609375 0.04180908203125 0.1501953125000029 +0.50175 0.039947509765625 0.047027587890625 0.1501953125000029 +0.501875 0.039947509765625 0.047027587890625 0.1501953125000029 +0.502 0.044403076171875 0.05224609375 0.1501953125000029 +0.502125 0.044403076171875 0.05224609375 0.1501953125000029 +0.50225 0.048797607421875 0.05743408203125 0.1501953125000029 +0.502375 0.05322265625 0.0626220703125 0.1501953125000029 +0.5025000000000001 0.05322265625 0.0626220703125 0.1501953125000029 +0.502625 0.0576171875 0.06781005859375 0.1501953125000029 +0.50275 0.0576171875 0.06781005859375 0.1501953125000029 +0.502875 0.062042236328125 0.072998046875 0.1501953125000029 +0.503 0.066436767578125 0.07818603515625 0.1501953125000029 +0.503125 0.066436767578125 0.07818603515625 0.1501953125000029 +0.50325 0.070831298828125 0.083343505859375 0.1501953125000029 +0.503375 0.070831298828125 0.083343505859375 0.1501953125000029 +0.5035000000000001 0.0751953125 0.0885009765625 0.1501953125000029 +0.503625 0.07958984375 0.093658447265625 0.1501953125000029 +0.50375 0.07958984375 0.093658447265625 0.1501953125000029 +0.503875 0.083953857421875 0.098785400390625 0.1501953125000029 +0.504 0.083953857421875 0.098785400390625 0.1501953125000029 +0.504125 0.08831787109375 0.103912353515625 0.1501953125000029 +0.50425 0.0926513671875 0.109039306640625 0.1501953125000029 +0.504375 0.0926513671875 0.109039306640625 0.1501953125000029 +0.5045000000000001 0.09698486328125 0.1141357421875 0.1501953125000029 +0.504625 0.09698486328125 0.1141357421875 0.1501953125000029 +0.50475 0.101318359375 0.119232177734375 0.1501953125000029 +0.504875 0.105621337890625 0.124298095703125 0.1501953125000029 +0.505 0.105621337890625 0.124298095703125 0.1501953125000029 +0.505125 0.10992431640625 0.129364013671875 0.1501953125000029 +0.50525 0.10992431640625 0.129364013671875 0.1501953125000029 +0.505375 0.114227294921875 0.134429931640625 0.1501953125000029 +0.5055000000000001 0.118499755859375 0.13946533203125 0.1501953125000029 +0.505625 0.118499755859375 0.13946533203125 0.1501953125000029 +0.50575 0.122772216796875 0.14447021484375 0.1501953125000029 +0.505875 0.122772216796875 0.14447021484375 0.1501953125000029 +0.506 0.12701416015625 0.14947509765625 0.1501953125000029 +0.506125 0.131256103515625 0.15447998046875 0.1501953125000029 +0.50625 0.131256103515625 0.15447998046875 0.1501953125000029 +0.506375 0.135498046875 0.159454345703125 0.1501953125000029 +0.5065000000000001 0.135498046875 0.159454345703125 0.1501953125000029 +0.506625 0.139678955078125 0.164398193359375 0.1501953125000029 +0.50675 0.143890380859375 0.169342041015625 0.1501953125000029 +0.506875 0.143890380859375 0.169342041015625 0.1501953125000029 +0.507 0.1480712890625 0.17425537109375 0.1501953125000029 +0.507125 0.1480712890625 0.17425537109375 0.1501953125000029 +0.50725 0.1522216796875 0.17913818359375 0.1501953125000029 +0.507375 0.1563720703125 0.18402099609375 0.1501953125000029 +0.5075000000000001 0.1563720703125 0.18402099609375 0.1501953125000029 +0.507625 0.160491943359375 0.188873291015625 0.1501953125000029 +0.50775 0.160491943359375 0.188873291015625 0.1501953125000029 +0.507875 0.16461181640625 0.1937255859375 0.1501953125000029 +0.508 0.168701171875 0.19854736328125 0.1501953125000029 +0.508125 0.168701171875 0.19854736328125 0.1501953125000029 +0.50825 0.172760009765625 0.203338623046875 0.1501953125000029 +0.508375 0.172760009765625 0.203338623046875 0.1501953125000029 +0.5085000000000001 0.17681884765625 0.208099365234375 0.1501953125000029 +0.508625 0.180877685546875 0.212860107421875 0.1501953125000029 +0.50875 0.180877685546875 0.212860107421875 0.1501953125000029 +0.508875 0.18487548828125 0.21759033203125 0.1501953125000029 +0.509 0.18487548828125 0.21759033203125 0.1501953125000029 +0.509125 0.188873291015625 0.2222900390625 0.1501953125000029 +0.50925 0.192840576171875 0.226959228515625 0.1501953125000029 +0.509375 0.192840576171875 0.226959228515625 0.1501953125000029 +0.5095000000000001 0.196807861328125 0.231597900390625 0.1501953125000029 +0.509625 0.196807861328125 0.231597900390625 0.1501953125000029 +0.50975 0.20074462890625 0.236236572265625 0.1501953125000029 +0.509875 0.20465087890625 0.2408447265625 0.1501953125000029 +0.51 0.20465087890625 0.2408447265625 0.1501953125000029 +0.5101250000000001 0.208526611328125 0.24542236328125 0.1501953125000029 +0.51025 0.208526611328125 0.24542236328125 0.1501953125000029 +0.510375 0.21240234375 0.249969482421875 0.1501953125000029 +0.5105000000000001 0.21624755859375 0.25445556640625 0.1501953125000029 +0.510625 0.21624755859375 0.25445556640625 0.1501953125000029 +0.51075 0.220062255859375 0.25897216796875 0.1501953125000029 +0.510875 0.220062255859375 0.25897216796875 0.1501953125000029 +0.511 0.223846435546875 0.263427734375 0.1501953125000029 +0.5111250000000001 0.227630615234375 0.267852783203125 0.1501953125000029 +0.51125 0.227630615234375 0.267852783203125 0.1501953125000029 +0.511375 0.231353759765625 0.27227783203125 0.1501953125000029 +0.5115000000000001 0.231353759765625 0.27227783203125 0.1501953125000029 +0.511625 0.235076904296875 0.276641845703125 0.1501953125000029 +0.51175 0.23876953125 0.280975341796875 0.1501953125000029 +0.511875 0.23876953125 0.280975341796875 0.1501953125000029 +0.512 0.135467529296875 0.285308837890625 0.5251342773437525 +0.5121250000000001 0.135467529296875 0.285308837890625 0.5251342773437525 +0.51225 0.137481689453125 0.289581298828125 0.5251342773437525 +0.512375 0.139495849609375 0.2938232421875 0.5251342773437525 +0.5125 0.139495849609375 0.2938232421875 0.5251342773437525 +0.512625 0.141510009765625 0.298065185546875 0.5251342773437525 +0.51275 0.141510009765625 0.298065185546875 0.5251342773437525 +0.512875 0.14349365234375 0.30224609375 0.5251342773437525 +0.513 0.145477294921875 0.306396484375 0.5251342773437525 +0.5131250000000001 0.145477294921875 0.306396484375 0.5251342773437525 +0.51325 0.147430419921875 0.310516357421875 0.5251342773437525 +0.513375 0.147430419921875 0.310516357421875 0.5251342773437525 +0.5135 0.14935302734375 0.314605712890625 0.5251342773437525 +0.513625 0.151275634765625 0.31866455078125 0.5251342773437525 +0.51375 0.151275634765625 0.31866455078125 0.5251342773437525 +0.513875 0.1531982421875 0.322662353515625 0.5251342773437525 +0.514 0.1531982421875 0.322662353515625 0.5251342773437525 +0.5141250000000001 0.15509033203125 0.32666015625 0.5251342773437525 +0.51425 0.156951904296875 0.330596923828125 0.5251342773437525 +0.514375 0.156951904296875 0.330596923828125 0.5251342773437525 +0.5145 0.1588134765625 0.334503173828125 0.5251342773437525 +0.514625 0.1588134765625 0.334503173828125 0.5251342773437525 +0.51475 0.16064453125 0.33837890625 0.5251342773437525 +0.514875 0.1624755859375 0.34222412109375 0.5251342773437525 +0.515 0.1624755859375 0.34222412109375 0.5251342773437525 +0.5151250000000001 0.164276123046875 0.34600830078125 0.5251342773437525 +0.51525 0.164276123046875 0.34600830078125 0.5251342773437525 +0.515375 0.166046142578125 0.349761962890625 0.5251342773437525 +0.5155 0.167816162109375 0.353485107421875 0.5251342773437525 +0.515625 0.167816162109375 0.353485107421875 0.5251342773437525 +0.51575 0.169586181640625 0.357177734375 0.5251342773437525 +0.515875 0.169586181640625 0.357177734375 0.5251342773437525 +0.516 0.171295166015625 0.360809326171875 0.5251342773437525 +0.5161250000000001 0.17303466796875 0.36444091796875 0.5251342773437525 +0.51625 0.17303466796875 0.36444091796875 0.5251342773437525 +0.516375 0.174713134765625 0.36798095703125 0.5251342773437525 +0.5165 0.174713134765625 0.36798095703125 0.5251342773437525 +0.516625 0.1763916015625 0.37152099609375 0.5251342773437525 +0.51675 0.17803955078125 0.375 0.5251342773437525 +0.516875 0.17803955078125 0.375 0.5251342773437525 +0.517 0.179656982421875 0.378448486328125 0.5251342773437525 +0.5171250000000001 0.179656982421875 0.378448486328125 0.5251342773437525 +0.51725 0.1812744140625 0.3818359375 0.5251342773437525 +0.517375 0.182891845703125 0.38519287109375 0.5251342773437525 +0.5175 0.182891845703125 0.38519287109375 0.5251342773437525 +0.517625 0.1844482421875 0.388519287109375 0.5251342773437525 +0.51775 0.1844482421875 0.388519287109375 0.5251342773437525 +0.517875 0.186004638671875 0.39178466796875 0.5251342773437525 +0.518 0.18756103515625 0.39501953125 0.5251342773437525 +0.5181250000000001 0.18756103515625 0.39501953125 0.5251342773437525 +0.51825 0.189056396484375 0.398193359375 0.5251342773437525 +0.518375 0.189056396484375 0.398193359375 0.5251342773437525 +0.5185 0.1905517578125 0.401336669921875 0.5251342773437525 +0.518625 0.1920166015625 0.404449462890625 0.5251342773437525 +0.51875 0.1920166015625 0.404449462890625 0.5251342773437525 +0.518875 0.1934814453125 0.407501220703125 0.5251342773437525 +0.519 0.1934814453125 0.407501220703125 0.5251342773437525 +0.5191250000000001 0.19488525390625 0.4105224609375 0.5251342773437525 +0.51925 0.196319580078125 0.413482666015625 0.5251342773437525 +0.519375 0.196319580078125 0.413482666015625 0.5251342773437525 +0.5195 0.19769287109375 0.416412353515625 0.5251342773437525 +0.519625 0.19769287109375 0.416412353515625 0.5251342773437525 +0.51975 0.199066162109375 0.419281005859375 0.5251342773437525 +0.519875 0.200408935546875 0.422119140625 0.5251342773437525 +0.52 0.200408935546875 0.422119140625 0.5251342773437525 +0.5201250000000001 0.20172119140625 0.424896240234375 0.5251342773437525 +0.52025 0.20172119140625 0.424896240234375 0.5251342773437525 +0.520375 0.203033447265625 0.4276123046875 0.5251342773437525 +0.5205 0.20428466796875 0.4302978515625 0.5251342773437525 +0.520625 0.20428466796875 0.4302978515625 0.5251342773437525 +0.52075 0.20556640625 0.432952880859375 0.5251342773437525 +0.520875 0.20556640625 0.432952880859375 0.5251342773437525 +0.521 0.206787109375 0.435546875 0.5251342773437525 +0.5211250000000001 0.207977294921875 0.438079833984375 0.5251342773437525 +0.52125 0.207977294921875 0.438079833984375 0.5251342773437525 +0.521375 0.20916748046875 0.440582275390625 0.5251342773437525 +0.5215 0.20916748046875 0.440582275390625 0.5251342773437525 +0.521625 0.210357666015625 0.44305419921875 0.5251342773437525 +0.52175 0.21148681640625 0.4454345703125 0.5251342773437525 +0.521875 0.21148681640625 0.4454345703125 0.5251342773437525 +0.522 0.21258544921875 0.447784423828125 0.5251342773437525 +0.5221250000000001 0.21258544921875 0.447784423828125 0.5251342773437525 +0.52225 0.21368408203125 0.450103759765625 0.5251342773437525 +0.522375 0.214752197265625 0.452362060546875 0.5251342773437525 +0.5225 0.214752197265625 0.452362060546875 0.5251342773437525 +0.522625 0.2158203125 0.454559326171875 0.5251342773437525 +0.52275 0.2158203125 0.454559326171875 0.5251342773437525 +0.522875 0.216827392578125 0.45672607421875 0.5251342773437525 +0.523 0.21783447265625 0.458831787109375 0.5251342773437525 +0.5231250000000001 0.21783447265625 0.458831787109375 0.5251342773437525 +0.52325 0.21881103515625 0.46087646484375 0.5251342773437525 +0.523375 0.21881103515625 0.46087646484375 0.5251342773437525 +0.5235 0.219757080078125 0.462890625 0.5251342773437525 +0.523625 0.220672607421875 0.464813232421875 0.5251342773437525 +0.52375 0.220672607421875 0.464813232421875 0.5251342773437525 +0.523875 0.221588134765625 0.46673583984375 0.5251342773437525 +0.524 0.221588134765625 0.46673583984375 0.5251342773437525 +0.5241250000000001 0.22247314453125 0.46856689453125 0.5251342773437525 +0.52425 0.22332763671875 0.470367431640625 0.5251342773437525 +0.524375 0.22332763671875 0.470367431640625 0.5251342773437525 +0.5245 0.224151611328125 0.472137451171875 0.5251342773437525 +0.524625 0.224151611328125 0.472137451171875 0.5251342773437525 +0.52475 0.224945068359375 0.47381591796875 0.5251342773437525 +0.524875 0.225738525390625 0.4754638671875 0.5251342773437525 +0.525 0.225738525390625 0.4754638671875 0.5251342773437525 +0.5251250000000001 0.22650146484375 0.47705078125 0.5251342773437525 +0.52525 0.22650146484375 0.47705078125 0.5251342773437525 +0.525375 0.22723388671875 0.478607177734375 0.5251342773437525 +0.5255 0.227935791015625 0.480072021484375 0.5251342773437525 +0.525625 0.227935791015625 0.480072021484375 0.5251342773437525 +0.5257500000000001 0.228607177734375 0.48150634765625 0.5251342773437525 +0.525875 0.228607177734375 0.48150634765625 0.5251342773437525 +0.526 0.229278564453125 0.48291015625 0.5251342773437525 +0.5261250000000001 0.229888916015625 0.484222412109375 0.5251342773437525 +0.52625 0.229888916015625 0.484222412109375 0.5251342773437525 +0.526375 0.230499267578125 0.485504150390625 0.5251342773437525 +0.5265 0.230499267578125 0.485504150390625 0.5251342773437525 +0.526625 0.2310791015625 0.486724853515625 0.5251342773437525 +0.5267500000000001 0.23162841796875 0.487884521484375 0.5251342773437525 +0.526875 0.23162841796875 0.487884521484375 0.5251342773437525 +0.527 0.232177734375 0.489013671875 0.5251342773437525 +0.5271250000000001 0.232177734375 0.489013671875 0.5251342773437525 +0.52725 0.232666015625 0.490081787109375 0.5251342773437525 +0.527375 0.233154296875 0.4910888671875 0.5251342773437525 +0.5275 0.233154296875 0.4910888671875 0.5251342773437525 +0.527625 0.233612060546875 0.492034912109375 0.5251342773437525 +0.5277500000000001 0.233612060546875 0.492034912109375 0.5251342773437525 +0.527875 0.234039306640625 0.492950439453125 0.5251342773437525 +0.528 0.23443603515625 0.4937744140625 0.5251342773437525 +0.528125 0.23443603515625 0.4937744140625 0.5251342773437525 +0.52825 0.23480224609375 0.49456787109375 0.5251342773437525 +0.528375 0.23480224609375 0.49456787109375 0.5251342773437525 +0.5285 0.23516845703125 0.49530029296875 0.5251342773437525 +0.528625 0.2354736328125 0.496002197265625 0.5251342773437525 +0.5287500000000001 0.2354736328125 0.496002197265625 0.5251342773437525 +0.528875 0.23577880859375 0.496612548828125 0.5251342773437525 +0.529 0.23577880859375 0.496612548828125 0.5251342773437525 +0.529125 0.236053466796875 0.4971923828125 0.5251342773437525 +0.52925 0.236297607421875 0.497711181640625 0.5251342773437525 +0.529375 0.236297607421875 0.497711181640625 0.5251342773437525 +0.5295 0.23651123046875 0.498199462890625 0.5251342773437525 +0.529625 0.23651123046875 0.498199462890625 0.5251342773437525 +0.5297500000000001 0.236724853515625 0.49859619140625 0.5251342773437525 +0.529875 0.23687744140625 0.49896240234375 0.5251342773437525 +0.53 0.23687744140625 0.49896240234375 0.5251342773437525 +0.530125 0.237030029296875 0.499267578125 0.5251342773437525 +0.53025 0.237030029296875 0.499267578125 0.5251342773437525 +0.530375 0.237152099609375 0.49951171875 0.5251342773437525 +0.5305 0.23724365234375 0.49969482421875 0.5251342773437525 +0.530625 0.23724365234375 0.49969482421875 0.5251342773437525 +0.5307500000000001 0.2373046875 0.49981689453125 0.5251342773437525 +0.530875 0.2373046875 0.49981689453125 0.5251342773437525 +0.531 0.237335205078125 0.499908447265625 0.5251342773437525 +0.531125 0.23736572265625 0.49993896484375 0.5251342773437525 +0.53125 0.23736572265625 0.49993896484375 0.5251342773437525 +0.531375 0.237335205078125 0.499908447265625 0.5251342773437525 +0.5315 0.237335205078125 0.499908447265625 0.5251342773437525 +0.531625 0.2373046875 0.49981689453125 0.5251342773437525 +0.5317500000000001 0.23724365234375 0.49969482421875 0.5251342773437525 +0.531875 0.23724365234375 0.49969482421875 0.5251342773437525 +0.532 0.237152099609375 0.49951171875 0.5251342773437525 +0.532125 0.237152099609375 0.49951171875 0.5251342773437525 +0.53225 0.237030029296875 0.499267578125 0.5251342773437525 +0.532375 0.23687744140625 0.49896240234375 0.5251342773437525 +0.5325 0.23687744140625 0.49896240234375 0.5251342773437525 +0.532625 0.236724853515625 0.49859619140625 0.5251342773437525 +0.5327500000000001 0.236724853515625 0.49859619140625 0.5251342773437525 +0.532875 0.23651123046875 0.498199462890625 0.5251342773437525 +0.533 0.236297607421875 0.497711181640625 0.5251342773437525 +0.533125 0.236297607421875 0.497711181640625 0.5251342773437525 +0.53325 0.236053466796875 0.4971923828125 0.5251342773437525 +0.533375 0.236053466796875 0.4971923828125 0.5251342773437525 +0.5335 0.23577880859375 0.496612548828125 0.5251342773437525 +0.533625 0.2354736328125 0.496002197265625 0.5251342773437525 +0.5337500000000001 0.2354736328125 0.496002197265625 0.5251342773437525 +0.533875 0.23516845703125 0.49530029296875 0.5251342773437525 +0.534 0.23516845703125 0.49530029296875 0.5251342773437525 +0.534125 0.23480224609375 0.49456787109375 0.5251342773437525 +0.53425 0.23443603515625 0.4937744140625 0.5251342773437525 +0.534375 0.23443603515625 0.4937744140625 0.5251342773437525 +0.5345 0.234039306640625 0.492950439453125 0.5251342773437525 +0.534625 0.234039306640625 0.492950439453125 0.5251342773437525 +0.5347500000000001 0.233612060546875 0.492034912109375 0.5251342773437525 +0.534875 0.233154296875 0.4910888671875 0.5251342773437525 +0.535 0.233154296875 0.4910888671875 0.5251342773437525 +0.535125 0.232666015625 0.490081787109375 0.5251342773437525 +0.53525 0.232666015625 0.490081787109375 0.5251342773437525 +0.535375 0.232177734375 0.489013671875 0.5251342773437525 +0.5355 0.23162841796875 0.487884521484375 0.5251342773437525 +0.535625 0.23162841796875 0.487884521484375 0.5251342773437525 +0.5357500000000001 0.2310791015625 0.486724853515625 0.5251342773437525 +0.535875 0.2310791015625 0.486724853515625 0.5251342773437525 +0.536 0.230499267578125 0.485504150390625 0.5251342773437525 +0.536125 0.229888916015625 0.484222412109375 0.5251342773437525 +0.53625 0.229888916015625 0.484222412109375 0.5251342773437525 +0.536375 0.229278564453125 0.48291015625 0.5251342773437525 +0.5365 0.229278564453125 0.48291015625 0.5251342773437525 +0.536625 0.228607177734375 0.48150634765625 0.5251342773437525 +0.5367500000000001 0.227935791015625 0.480072021484375 0.5251342773437525 +0.536875 0.227935791015625 0.480072021484375 0.5251342773437525 +0.537 0.22723388671875 0.478607177734375 0.5251342773437525 +0.537125 0.22723388671875 0.478607177734375 0.5251342773437525 +0.53725 0.22650146484375 0.47705078125 0.5251342773437525 +0.537375 0.225738525390625 0.4754638671875 0.5251342773437525 +0.5375 0.225738525390625 0.4754638671875 0.5251342773437525 +0.537625 0.224945068359375 0.47381591796875 0.5251342773437525 +0.5377500000000001 0.224945068359375 0.47381591796875 0.5251342773437525 +0.537875 0.224151611328125 0.472137451171875 0.5251342773437525 +0.538 0.22332763671875 0.470367431640625 0.5251342773437525 +0.538125 0.22332763671875 0.470367431640625 0.5251342773437525 +0.53825 0.22247314453125 0.46856689453125 0.5251342773437525 +0.538375 0.22247314453125 0.46856689453125 0.5251342773437525 +0.5385 0.221588134765625 0.46673583984375 0.5251342773437525 +0.538625 0.220672607421875 0.464813232421875 0.5251342773437525 +0.5387500000000001 0.220672607421875 0.464813232421875 0.5251342773437525 +0.538875 0.219757080078125 0.462890625 0.5251342773437525 +0.539 0.219757080078125 0.462890625 0.5251342773437525 +0.539125 0.21881103515625 0.46087646484375 0.5251342773437525 +0.53925 0.21783447265625 0.458831787109375 0.5251342773437525 +0.539375 0.21783447265625 0.458831787109375 0.5251342773437525 +0.5395 0.216827392578125 0.45672607421875 0.5251342773437525 +0.539625 0.216827392578125 0.45672607421875 0.5251342773437525 +0.5397500000000001 0.2158203125 0.454559326171875 0.5251342773437525 +0.539875 0.214752197265625 0.452362060546875 0.5251342773437525 +0.54 0.214752197265625 0.452362060546875 0.5251342773437525 +0.540125 0.21368408203125 0.450103759765625 0.5251342773437525 +0.54025 0.21368408203125 0.450103759765625 0.5251342773437525 +0.540375 0.21258544921875 0.447784423828125 0.5251342773437525 +0.5405 0.21148681640625 0.4454345703125 0.5251342773437525 +0.540625 0.21148681640625 0.4454345703125 0.5251342773437525 +0.5407500000000001 0.210357666015625 0.44305419921875 0.5251342773437525 +0.540875 0.210357666015625 0.44305419921875 0.5251342773437525 +0.541 0.20916748046875 0.440582275390625 0.5251342773437525 +0.541125 0.207977294921875 0.438079833984375 0.5251342773437525 +0.54125 0.207977294921875 0.438079833984375 0.5251342773437525 +0.5413750000000001 0.206787109375 0.435546875 0.5251342773437525 +0.5415 0.206787109375 0.435546875 0.5251342773437525 +0.541625 0.20556640625 0.432952880859375 0.5251342773437525 +0.5417500000000001 0.20428466796875 0.4302978515625 0.5251342773437525 +0.541875 0.20428466796875 0.4302978515625 0.5251342773437525 +0.542 0.203033447265625 0.4276123046875 0.5251342773437525 +0.542125 0.203033447265625 0.4276123046875 0.5251342773437525 +0.54225 0.20172119140625 0.424896240234375 0.5251342773437525 +0.5423750000000001 0.200408935546875 0.422119140625 0.5251342773437525 +0.5425 0.200408935546875 0.422119140625 0.5251342773437525 +0.542625 0.199066162109375 0.419281005859375 0.5251342773437525 +0.5427500000000001 0.199066162109375 0.419281005859375 0.5251342773437525 +0.542875 0.19769287109375 0.416412353515625 0.5251342773437525 +0.543 0.196319580078125 0.413482666015625 0.5251342773437525 +0.543125 0.196319580078125 0.413482666015625 0.5251342773437525 +0.54325 0.19488525390625 0.4105224609375 0.5251342773437525 +0.5433750000000001 0.19488525390625 0.4105224609375 0.5251342773437525 +0.5435 0.1934814453125 0.407501220703125 0.5251342773437525 +0.543625 0.1920166015625 0.404449462890625 0.5251342773437525 +0.5437500000000001 0.1920166015625 0.404449462890625 0.5251342773437525 +0.543875 0.1905517578125 0.401336669921875 0.5251342773437525 +0.544 0.073699951171875 0.401336669921875 0.8162963867187517 +0.544125 0.0731201171875 0.398193359375 0.8162963867187517 +0.54425 0.072540283203125 0.39501953125 0.8162963867187517 +0.5443750000000001 0.072540283203125 0.39501953125 0.8162963867187517 +0.5445 0.071929931640625 0.39178466796875 0.8162963867187517 +0.544625 0.071929931640625 0.39178466796875 0.8162963867187517 +0.54475 0.071319580078125 0.388519287109375 0.8162963867187517 +0.544875 0.070709228515625 0.38519287109375 0.8162963867187517 +0.545 0.070709228515625 0.38519287109375 0.8162963867187517 +0.545125 0.070098876953125 0.3818359375 0.8162963867187517 +0.54525 0.070098876953125 0.3818359375 0.8162963867187517 +0.5453750000000001 0.069488525390625 0.378448486328125 0.8162963867187517 +0.5455 0.06884765625 0.375 0.8162963867187517 +0.545625 0.06884765625 0.375 0.8162963867187517 +0.54575 0.068206787109375 0.37152099609375 0.8162963867187517 +0.545875 0.068206787109375 0.37152099609375 0.8162963867187517 +0.546 0.06756591796875 0.36798095703125 0.8162963867187517 +0.546125 0.066925048828125 0.36444091796875 0.8162963867187517 +0.54625 0.066925048828125 0.36444091796875 0.8162963867187517 +0.5463750000000001 0.066253662109375 0.360809326171875 0.8162963867187517 +0.5465 0.066253662109375 0.360809326171875 0.8162963867187517 +0.546625 0.065582275390625 0.357177734375 0.8162963867187517 +0.54675 0.064910888671875 0.353485107421875 0.8162963867187517 +0.546875 0.064910888671875 0.353485107421875 0.8162963867187517 +0.547 0.064208984375 0.349761962890625 0.8162963867187517 +0.547125 0.064208984375 0.349761962890625 0.8162963867187517 +0.54725 0.06353759765625 0.34600830078125 0.8162963867187517 +0.5473750000000001 0.062835693359375 0.34222412109375 0.8162963867187517 +0.5475 0.062835693359375 0.34222412109375 0.8162963867187517 +0.547625 0.0621337890625 0.33837890625 0.8162963867187517 +0.54775 0.0621337890625 0.33837890625 0.8162963867187517 +0.547875 0.0614013671875 0.334503173828125 0.8162963867187517 +0.548 0.060699462890625 0.330596923828125 0.8162963867187517 +0.548125 0.060699462890625 0.330596923828125 0.8162963867187517 +0.54825 0.059967041015625 0.32666015625 0.8162963867187517 +0.5483750000000001 0.059967041015625 0.32666015625 0.8162963867187517 +0.5485 0.059234619140625 0.322662353515625 0.8162963867187517 +0.548625 0.058502197265625 0.31866455078125 0.8162963867187517 +0.54875 0.058502197265625 0.31866455078125 0.8162963867187517 +0.548875 0.057769775390625 0.314605712890625 0.8162963867187517 +0.549 0.057769775390625 0.314605712890625 0.8162963867187517 +0.549125 0.0570068359375 0.310516357421875 0.8162963867187517 +0.54925 0.056243896484375 0.306396484375 0.8162963867187517 +0.5493750000000001 0.056243896484375 0.306396484375 0.8162963867187517 +0.5495 0.05548095703125 0.30224609375 0.8162963867187517 +0.549625 0.05548095703125 0.30224609375 0.8162963867187517 +0.54975 0.054718017578125 0.298065185546875 0.8162963867187517 +0.549875 0.053955078125 0.2938232421875 0.8162963867187517 +0.55 0.053955078125 0.2938232421875 0.8162963867187517 +0.550125 0.05316162109375 0.289581298828125 0.8162963867187517 +0.55025 0.05316162109375 0.289581298828125 0.8162963867187517 +0.5503750000000001 0.0523681640625 0.285308837890625 0.8162963867187517 +0.5505 0.05157470703125 0.280975341796875 0.8162963867187517 +0.550625 0.05157470703125 0.280975341796875 0.8162963867187517 +0.55075 0.05078125 0.276641845703125 0.8162963867187517 +0.550875 0.05078125 0.276641845703125 0.8162963867187517 +0.551 0.04998779296875 0.27227783203125 0.8162963867187517 +0.551125 0.049163818359375 0.267852783203125 0.8162963867187517 +0.55125 0.049163818359375 0.267852783203125 0.8162963867187517 +0.5513750000000001 0.048370361328125 0.263427734375 0.8162963867187517 +0.5515 0.048370361328125 0.263427734375 0.8162963867187517 +0.551625 0.04754638671875 0.25897216796875 0.8162963867187517 +0.55175 0.046722412109375 0.25445556640625 0.8162963867187517 +0.551875 0.046722412109375 0.25445556640625 0.8162963867187517 +0.552 0.0458984375 0.249969482421875 0.8162963867187517 +0.552125 0.0458984375 0.249969482421875 0.8162963867187517 +0.55225 0.0450439453125 0.24542236328125 0.8162963867187517 +0.5523750000000001 0.044219970703125 0.2408447265625 0.8162963867187517 +0.5525 0.044219970703125 0.2408447265625 0.8162963867187517 +0.552625 0.043365478515625 0.236236572265625 0.8162963867187517 +0.55275 0.043365478515625 0.236236572265625 0.8162963867187517 +0.552875 0.042510986328125 0.231597900390625 0.8162963867187517 +0.553 0.041656494140625 0.226959228515625 0.8162963867187517 +0.553125 0.041656494140625 0.226959228515625 0.8162963867187517 +0.55325 0.040802001953125 0.2222900390625 0.8162963867187517 +0.5533750000000001 0.040802001953125 0.2222900390625 0.8162963867187517 +0.5535 0.039947509765625 0.21759033203125 0.8162963867187517 +0.553625 0.0390625 0.212860107421875 0.8162963867187517 +0.55375 0.0390625 0.212860107421875 0.8162963867187517 +0.553875 0.0382080078125 0.208099365234375 0.8162963867187517 +0.554 0.0382080078125 0.208099365234375 0.8162963867187517 +0.554125 0.037322998046875 0.203338623046875 0.8162963867187517 +0.55425 0.03643798828125 0.19854736328125 0.8162963867187517 +0.5543750000000001 0.03643798828125 0.19854736328125 0.8162963867187517 +0.5545 0.035552978515625 0.1937255859375 0.8162963867187517 +0.554625 0.035552978515625 0.1937255859375 0.8162963867187517 +0.55475 0.03466796875 0.188873291015625 0.8162963867187517 +0.554875 0.033782958984375 0.18402099609375 0.8162963867187517 +0.555 0.033782958984375 0.18402099609375 0.8162963867187517 +0.555125 0.03289794921875 0.17913818359375 0.8162963867187517 +0.55525 0.03289794921875 0.17913818359375 0.8162963867187517 +0.5553750000000001 0.031982421875 0.17425537109375 0.8162963867187517 +0.5555 0.031097412109375 0.169342041015625 0.8162963867187517 +0.555625 0.031097412109375 0.169342041015625 0.8162963867187517 +0.55575 0.030181884765625 0.164398193359375 0.8162963867187517 +0.555875 0.030181884765625 0.164398193359375 0.8162963867187517 +0.556 0.029266357421875 0.159454345703125 0.8162963867187517 +0.556125 0.028350830078125 0.15447998046875 0.8162963867187517 +0.55625 0.028350830078125 0.15447998046875 0.8162963867187517 +0.5563750000000001 0.027435302734375 0.14947509765625 0.8162963867187517 +0.5565 0.027435302734375 0.14947509765625 0.8162963867187517 +0.556625 0.026519775390625 0.14447021484375 0.8162963867187517 +0.55675 0.025604248046875 0.13946533203125 0.8162963867187517 +0.556875 0.025604248046875 0.13946533203125 0.8162963867187517 +0.5570000000000001 0.024658203125 0.134429931640625 0.8162963867187517 +0.557125 0.024658203125 0.134429931640625 0.8162963867187517 +0.55725 0.02374267578125 0.129364013671875 0.8162963867187517 +0.5573750000000001 0.0228271484375 0.124298095703125 0.8162963867187517 +0.5575 0.0228271484375 0.124298095703125 0.8162963867187517 +0.557625 0.021881103515625 0.119232177734375 0.8162963867187517 +0.55775 0.021881103515625 0.119232177734375 0.8162963867187517 +0.557875 0.02093505859375 0.1141357421875 0.8162963867187517 +0.5580000000000001 0.02001953125 0.109039306640625 0.8162963867187517 +0.558125 0.02001953125 0.109039306640625 0.8162963867187517 +0.55825 0.019073486328125 0.103912353515625 0.8162963867187517 +0.5583750000000001 0.019073486328125 0.103912353515625 0.8162963867187517 +0.5585 0.01812744140625 0.098785400390625 0.8162963867187517 +0.558625 0.017181396484375 0.093658447265625 0.8162963867187517 +0.55875 0.017181396484375 0.093658447265625 0.8162963867187517 +0.558875 0.0162353515625 0.0885009765625 0.8162963867187517 +0.5590000000000001 0.0162353515625 0.0885009765625 0.8162963867187517 +0.559125 0.015289306640625 0.083343505859375 0.8162963867187517 +0.55925 0.01434326171875 0.07818603515625 0.8162963867187517 +0.5593750000000001 0.01434326171875 0.07818603515625 0.8162963867187517 +0.5595 0.013397216796875 0.072998046875 0.8162963867187517 +0.559625 0.013397216796875 0.072998046875 0.8162963867187517 +0.55975 0.012451171875 0.06781005859375 0.8162963867187517 +0.559875 0.011474609375 0.0626220703125 0.8162963867187517 +0.5600000000000001 0.011474609375 0.0626220703125 0.8162963867187517 +0.560125 0.010528564453125 0.05743408203125 0.8162963867187517 +0.56025 0.010528564453125 0.05743408203125 0.8162963867187517 +0.560375 0.00958251953125 0.05224609375 0.8162963867187517 +0.5605 0.008636474609375 0.047027587890625 0.8162963867187517 +0.560625 0.008636474609375 0.047027587890625 0.8162963867187517 +0.56075 0.007659912109375 0.04180908203125 0.8162963867187517 +0.560875 0.007659912109375 0.04180908203125 0.8162963867187517 +0.5610000000000001 0.0067138671875 0.036590576171875 0.8162963867187517 +0.561125 0.0057373046875 0.0313720703125 0.8162963867187517 +0.56125 0.0057373046875 0.0313720703125 0.8162963867187517 +0.561375 0.004791259765625 0.026123046875 0.8162963867187517 +0.5615 0.004791259765625 0.026123046875 0.8162963867187517 +0.561625 0.003814697265625 0.020904541015625 0.8162963867187517 +0.56175 0.00286865234375 0.01568603515625 0.8162963867187517 +0.561875 0.00286865234375 0.01568603515625 0.8162963867187517 +0.5620000000000001 0.00189208984375 0.01043701171875 0.8162963867187517 +0.562125 0.00189208984375 0.01043701171875 0.8162963867187517 +0.56225 0.000946044921875 0.005218505859375 0.8162963867187517 +0.562375 0.0 0.0 0.8162963867187517 +0.5625 0.0 0.0 0.8162963867187517 +0.562625 -0.000946044921875 -0.005218505859375 0.8162963867187517 +0.56275 -0.000946044921875 -0.005218505859375 0.8162963867187517 +0.562875 -0.00189208984375 -0.01043701171875 0.8162963867187517 +0.5630000000000001 -0.00286865234375 -0.01568603515625 0.8162963867187517 +0.563125 -0.00286865234375 -0.01568603515625 0.8162963867187517 +0.56325 -0.003814697265625 -0.020904541015625 0.8162963867187517 +0.563375 -0.003814697265625 -0.020904541015625 0.8162963867187517 +0.5635 -0.004791259765625 -0.026123046875 0.8162963867187517 +0.563625 -0.0057373046875 -0.0313720703125 0.8162963867187517 +0.56375 -0.0057373046875 -0.0313720703125 0.8162963867187517 +0.563875 -0.0067138671875 -0.036590576171875 0.8162963867187517 +0.5640000000000001 -0.0067138671875 -0.036590576171875 0.8162963867187517 +0.564125 -0.007659912109375 -0.04180908203125 0.8162963867187517 +0.56425 -0.008636474609375 -0.047027587890625 0.8162963867187517 +0.564375 -0.008636474609375 -0.047027587890625 0.8162963867187517 +0.5645 -0.00958251953125 -0.05224609375 0.8162963867187517 +0.564625 -0.00958251953125 -0.05224609375 0.8162963867187517 +0.56475 -0.010528564453125 -0.05743408203125 0.8162963867187517 +0.564875 -0.011474609375 -0.0626220703125 0.8162963867187517 +0.5650000000000001 -0.011474609375 -0.0626220703125 0.8162963867187517 +0.565125 -0.012451171875 -0.06781005859375 0.8162963867187517 +0.56525 -0.012451171875 -0.06781005859375 0.8162963867187517 +0.565375 -0.013397216796875 -0.072998046875 0.8162963867187517 +0.5655 -0.01434326171875 -0.07818603515625 0.8162963867187517 +0.565625 -0.01434326171875 -0.07818603515625 0.8162963867187517 +0.56575 -0.015289306640625 -0.083343505859375 0.8162963867187517 +0.565875 -0.015289306640625 -0.083343505859375 0.8162963867187517 +0.5660000000000001 -0.0162353515625 -0.0885009765625 0.8162963867187517 +0.566125 -0.017181396484375 -0.093658447265625 0.8162963867187517 +0.56625 -0.017181396484375 -0.093658447265625 0.8162963867187517 +0.566375 -0.01812744140625 -0.098785400390625 0.8162963867187517 +0.5665 -0.01812744140625 -0.098785400390625 0.8162963867187517 +0.566625 -0.019073486328125 -0.103912353515625 0.8162963867187517 +0.56675 -0.02001953125 -0.109039306640625 0.8162963867187517 +0.566875 -0.02001953125 -0.109039306640625 0.8162963867187517 +0.5670000000000001 -0.02093505859375 -0.1141357421875 0.8162963867187517 +0.567125 -0.02093505859375 -0.1141357421875 0.8162963867187517 +0.56725 -0.021881103515625 -0.119232177734375 0.8162963867187517 +0.567375 -0.0228271484375 -0.124298095703125 0.8162963867187517 +0.5675 -0.0228271484375 -0.124298095703125 0.8162963867187517 +0.567625 -0.02374267578125 -0.129364013671875 0.8162963867187517 +0.56775 -0.02374267578125 -0.129364013671875 0.8162963867187517 +0.567875 -0.024658203125 -0.134429931640625 0.8162963867187517 +0.5680000000000001 -0.025604248046875 -0.13946533203125 0.8162963867187517 +0.568125 -0.025604248046875 -0.13946533203125 0.8162963867187517 +0.56825 -0.026519775390625 -0.14447021484375 0.8162963867187517 +0.568375 -0.026519775390625 -0.14447021484375 0.8162963867187517 +0.5685 -0.027435302734375 -0.14947509765625 0.8162963867187517 +0.568625 -0.028350830078125 -0.15447998046875 0.8162963867187517 +0.56875 -0.028350830078125 -0.15447998046875 0.8162963867187517 +0.568875 -0.029266357421875 -0.159454345703125 0.8162963867187517 +0.5690000000000001 -0.029266357421875 -0.159454345703125 0.8162963867187517 +0.569125 -0.030181884765625 -0.164398193359375 0.8162963867187517 +0.56925 -0.031097412109375 -0.169342041015625 0.8162963867187517 +0.569375 -0.031097412109375 -0.169342041015625 0.8162963867187517 +0.5695 -0.031982421875 -0.17425537109375 0.8162963867187517 +0.569625 -0.031982421875 -0.17425537109375 0.8162963867187517 +0.56975 -0.03289794921875 -0.17913818359375 0.8162963867187517 +0.569875 -0.033782958984375 -0.18402099609375 0.8162963867187517 +0.5700000000000001 -0.033782958984375 -0.18402099609375 0.8162963867187517 +0.570125 -0.03466796875 -0.188873291015625 0.8162963867187517 +0.57025 -0.03466796875 -0.188873291015625 0.8162963867187517 +0.570375 -0.035552978515625 -0.1937255859375 0.8162963867187517 +0.5705 -0.03643798828125 -0.19854736328125 0.8162963867187517 +0.570625 -0.03643798828125 -0.19854736328125 0.8162963867187517 +0.57075 -0.037322998046875 -0.203338623046875 0.8162963867187517 +0.570875 -0.037322998046875 -0.203338623046875 0.8162963867187517 +0.5710000000000001 -0.0382080078125 -0.208099365234375 0.8162963867187517 +0.571125 -0.0390625 -0.212860107421875 0.8162963867187517 +0.57125 -0.0390625 -0.212860107421875 0.8162963867187517 +0.571375 -0.039947509765625 -0.21759033203125 0.8162963867187517 +0.5715 -0.039947509765625 -0.21759033203125 0.8162963867187517 +0.571625 -0.040802001953125 -0.2222900390625 0.8162963867187517 +0.57175 -0.041656494140625 -0.226959228515625 0.8162963867187517 +0.571875 -0.041656494140625 -0.226959228515625 0.8162963867187517 +0.5720000000000001 -0.042510986328125 -0.231597900390625 0.8162963867187517 +0.572125 -0.042510986328125 -0.231597900390625 0.8162963867187517 +0.57225 -0.043365478515625 -0.236236572265625 0.8162963867187517 +0.572375 -0.044219970703125 -0.2408447265625 0.8162963867187517 +0.5725 -0.044219970703125 -0.2408447265625 0.8162963867187517 +0.5726250000000001 -0.0450439453125 -0.24542236328125 0.8162963867187517 +0.57275 -0.0450439453125 -0.24542236328125 0.8162963867187517 +0.572875 -0.0458984375 -0.249969482421875 0.8162963867187517 +0.5730000000000001 -0.046722412109375 -0.25445556640625 0.8162963867187517 +0.573125 -0.046722412109375 -0.25445556640625 0.8162963867187517 +0.57325 -0.04754638671875 -0.25897216796875 0.8162963867187517 +0.573375 -0.04754638671875 -0.25897216796875 0.8162963867187517 +0.5735 -0.048370361328125 -0.263427734375 0.8162963867187517 +0.5736250000000001 -0.049163818359375 -0.267852783203125 0.8162963867187517 +0.57375 -0.049163818359375 -0.267852783203125 0.8162963867187517 +0.573875 -0.04998779296875 -0.27227783203125 0.8162963867187517 +0.5740000000000001 -0.04998779296875 -0.27227783203125 0.8162963867187517 +0.574125 -0.05078125 -0.276641845703125 0.8162963867187517 +0.57425 -0.05157470703125 -0.280975341796875 0.8162963867187517 +0.574375 -0.05157470703125 -0.280975341796875 0.8162963867187517 +0.5745 -0.0523681640625 -0.285308837890625 0.8162963867187517 +0.5746250000000001 -0.0523681640625 -0.285308837890625 0.8162963867187517 +0.57475 -0.05316162109375 -0.289581298828125 0.8162963867187517 +0.574875 -0.053955078125 -0.2938232421875 0.8162963867187517 +0.5750000000000001 -0.053955078125 -0.2938232421875 0.8162963867187517 +0.575125 -0.054718017578125 -0.298065185546875 0.8162963867187517 +0.57525 -0.054718017578125 -0.298065185546875 0.8162963867187517 +0.575375 -0.05548095703125 -0.30224609375 0.8162963867187517 +0.5755 -0.056243896484375 -0.306396484375 0.8162963867187517 +0.5756250000000001 -0.056243896484375 -0.306396484375 0.8162963867187517 +0.57575 -0.0570068359375 -0.310516357421875 0.8162963867187517 +0.575875 -0.0570068359375 -0.310516357421875 0.8162963867187517 +0.5760000000000001 -0.00714111328125 -0.314605712890625 0.9771972656250006 +0.576125 -0.007232666015625 -0.31866455078125 0.9771972656250006 +0.57625 -0.007232666015625 -0.31866455078125 0.9771972656250006 +0.576375 -0.00732421875 -0.322662353515625 0.9771972656250006 +0.5765 -0.00732421875 -0.322662353515625 0.9771972656250006 +0.5766250000000001 -0.007415771484375 -0.32666015625 0.9771972656250006 +0.57675 -0.007476806640625 -0.330596923828125 0.9771972656250006 +0.576875 -0.007476806640625 -0.330596923828125 0.9771972656250006 +0.577 -0.007568359375 -0.334503173828125 0.9771972656250006 +0.577125 -0.007568359375 -0.334503173828125 0.9771972656250006 +0.57725 -0.007659912109375 -0.33837890625 0.9771972656250006 +0.577375 -0.00775146484375 -0.34222412109375 0.9771972656250006 +0.5775 -0.00775146484375 -0.34222412109375 0.9771972656250006 +0.5776250000000001 -0.007843017578125 -0.34600830078125 0.9771972656250006 +0.57775 -0.007843017578125 -0.34600830078125 0.9771972656250006 +0.577875 -0.0079345703125 -0.349761962890625 0.9771972656250006 +0.578 -0.008026123046875 -0.353485107421875 0.9771972656250006 +0.578125 -0.008026123046875 -0.353485107421875 0.9771972656250006 +0.57825 -0.008087158203125 -0.357177734375 0.9771972656250006 +0.578375 -0.008087158203125 -0.357177734375 0.9771972656250006 +0.5785 -0.0081787109375 -0.360809326171875 0.9771972656250006 +0.5786250000000001 -0.008270263671875 -0.36444091796875 0.9771972656250006 +0.57875 -0.008270263671875 -0.36444091796875 0.9771972656250006 +0.578875 -0.008331298828125 -0.36798095703125 0.9771972656250006 +0.579 -0.008331298828125 -0.36798095703125 0.9771972656250006 +0.579125 -0.0084228515625 -0.37152099609375 0.9771972656250006 +0.57925 -0.008514404296875 -0.375 0.9771972656250006 +0.579375 -0.008514404296875 -0.375 0.9771972656250006 +0.5795 -0.008575439453125 -0.378448486328125 0.9771972656250006 +0.5796250000000001 -0.008575439453125 -0.378448486328125 0.9771972656250006 +0.57975 -0.0086669921875 -0.3818359375 0.9771972656250006 +0.579875 -0.00872802734375 -0.38519287109375 0.9771972656250006 +0.58 -0.00872802734375 -0.38519287109375 0.9771972656250006 +0.580125 -0.008819580078125 -0.388519287109375 0.9771972656250006 +0.58025 -0.008819580078125 -0.388519287109375 0.9771972656250006 +0.580375 -0.008880615234375 -0.39178466796875 0.9771972656250006 +0.5805 -0.008941650390625 -0.39501953125 0.9771972656250006 +0.5806250000000001 -0.008941650390625 -0.39501953125 0.9771972656250006 +0.58075 -0.009033203125 -0.398193359375 0.9771972656250006 +0.580875 -0.009033203125 -0.398193359375 0.9771972656250006 +0.581 -0.00909423828125 -0.401336669921875 0.9771972656250006 +0.581125 -0.0091552734375 -0.404449462890625 0.9771972656250006 +0.58125 -0.0091552734375 -0.404449462890625 0.9771972656250006 +0.581375 -0.009246826171875 -0.407501220703125 0.9771972656250006 +0.5815 -0.009246826171875 -0.407501220703125 0.9771972656250006 +0.5816250000000001 -0.009307861328125 -0.4105224609375 0.9771972656250006 +0.58175 -0.009368896484375 -0.413482666015625 0.9771972656250006 +0.581875 -0.009368896484375 -0.413482666015625 0.9771972656250006 +0.582 -0.009429931640625 -0.416412353515625 0.9771972656250006 +0.582125 -0.009429931640625 -0.416412353515625 0.9771972656250006 +0.58225 -0.009490966796875 -0.419281005859375 0.9771972656250006 +0.582375 -0.00958251953125 -0.422119140625 0.9771972656250006 +0.5825 -0.00958251953125 -0.422119140625 0.9771972656250006 +0.5826250000000001 -0.0096435546875 -0.424896240234375 0.9771972656250006 +0.58275 -0.0096435546875 -0.424896240234375 0.9771972656250006 +0.582875 -0.00970458984375 -0.4276123046875 0.9771972656250006 +0.583 -0.009765625 -0.4302978515625 0.9771972656250006 +0.583125 -0.009765625 -0.4302978515625 0.9771972656250006 +0.58325 -0.00982666015625 -0.432952880859375 0.9771972656250006 +0.583375 -0.00982666015625 -0.432952880859375 0.9771972656250006 +0.5835 -0.0098876953125 -0.435546875 0.9771972656250006 +0.5836250000000001 -0.009918212890625 -0.438079833984375 0.9771972656250006 +0.58375 -0.009918212890625 -0.438079833984375 0.9771972656250006 +0.583875 -0.009979248046875 -0.440582275390625 0.9771972656250006 +0.584 -0.009979248046875 -0.440582275390625 0.9771972656250006 +0.584125 -0.010040283203125 -0.44305419921875 0.9771972656250006 +0.58425 -0.010101318359375 -0.4454345703125 0.9771972656250006 +0.584375 -0.010101318359375 -0.4454345703125 0.9771972656250006 +0.5845 -0.010162353515625 -0.447784423828125 0.9771972656250006 +0.5846250000000001 -0.010162353515625 -0.447784423828125 0.9771972656250006 +0.58475 -0.01019287109375 -0.450103759765625 0.9771972656250006 +0.584875 -0.01025390625 -0.452362060546875 0.9771972656250006 +0.585 -0.01025390625 -0.452362060546875 0.9771972656250006 +0.585125 -0.01031494140625 -0.454559326171875 0.9771972656250006 +0.58525 -0.01031494140625 -0.454559326171875 0.9771972656250006 +0.585375 -0.010345458984375 -0.45672607421875 0.9771972656250006 +0.5855 -0.010406494140625 -0.458831787109375 0.9771972656250006 +0.5856250000000001 -0.010406494140625 -0.458831787109375 0.9771972656250006 +0.58575 -0.01043701171875 -0.46087646484375 0.9771972656250006 +0.585875 -0.01043701171875 -0.46087646484375 0.9771972656250006 +0.586 -0.010498046875 -0.462890625 0.9771972656250006 +0.586125 -0.010528564453125 -0.464813232421875 0.9771972656250006 +0.58625 -0.010528564453125 -0.464813232421875 0.9771972656250006 +0.586375 -0.010589599609375 -0.46673583984375 0.9771972656250006 +0.5865 -0.010589599609375 -0.46673583984375 0.9771972656250006 +0.5866250000000001 -0.0106201171875 -0.46856689453125 0.9771972656250006 +0.58675 -0.010650634765625 -0.470367431640625 0.9771972656250006 +0.586875 -0.010650634765625 -0.470367431640625 0.9771972656250006 +0.587 -0.010711669921875 -0.472137451171875 0.9771972656250006 +0.587125 -0.010711669921875 -0.472137451171875 0.9771972656250006 +0.58725 -0.0107421875 -0.47381591796875 0.9771972656250006 +0.587375 -0.010772705078125 -0.4754638671875 0.9771972656250006 +0.5875 -0.010772705078125 -0.4754638671875 0.9771972656250006 +0.5876250000000001 -0.01080322265625 -0.47705078125 0.9771972656250006 +0.58775 -0.01080322265625 -0.47705078125 0.9771972656250006 +0.587875 -0.0108642578125 -0.478607177734375 0.9771972656250006 +0.588 -0.010894775390625 -0.480072021484375 0.9771972656250006 +0.588125 -0.010894775390625 -0.480072021484375 0.9771972656250006 +0.5882500000000001 -0.01092529296875 -0.48150634765625 0.9771972656250006 +0.588375 -0.01092529296875 -0.48150634765625 0.9771972656250006 +0.5885 -0.010955810546875 -0.48291015625 0.9771972656250006 +0.5886250000000001 -0.010986328125 -0.484222412109375 0.9771972656250006 +0.58875 -0.010986328125 -0.484222412109375 0.9771972656250006 +0.588875 -0.011016845703125 -0.485504150390625 0.9771972656250006 +0.589 -0.011016845703125 -0.485504150390625 0.9771972656250006 +0.589125 -0.01104736328125 -0.486724853515625 0.9771972656250006 +0.5892500000000001 -0.011077880859375 -0.487884521484375 0.9771972656250006 +0.589375 -0.011077880859375 -0.487884521484375 0.9771972656250006 +0.5895 -0.011077880859375 -0.489013671875 0.9771972656250006 +0.5896250000000001 -0.011077880859375 -0.489013671875 0.9771972656250006 +0.58975 -0.0111083984375 -0.490081787109375 0.9771972656250006 +0.589875 -0.011138916015625 -0.4910888671875 0.9771972656250006 +0.59 -0.011138916015625 -0.4910888671875 0.9771972656250006 +0.590125 -0.01116943359375 -0.492034912109375 0.9771972656250006 +0.5902500000000001 -0.01116943359375 -0.492034912109375 0.9771972656250006 +0.590375 -0.01116943359375 -0.492950439453125 0.9771972656250006 +0.5905 -0.011199951171875 -0.4937744140625 0.9771972656250006 +0.5906250000000001 -0.011199951171875 -0.4937744140625 0.9771972656250006 +0.59075 -0.011199951171875 -0.49456787109375 0.9771972656250006 +0.590875 -0.011199951171875 -0.49456787109375 0.9771972656250006 +0.591 -0.01123046875 -0.49530029296875 0.9771972656250006 +0.591125 -0.011260986328125 -0.496002197265625 0.9771972656250006 +0.5912500000000001 -0.011260986328125 -0.496002197265625 0.9771972656250006 +0.591375 -0.011260986328125 -0.496612548828125 0.9771972656250006 +0.5915 -0.011260986328125 -0.496612548828125 0.9771972656250006 +0.5916250000000001 -0.011260986328125 -0.4971923828125 0.9771972656250006 +0.59175 -0.01129150390625 -0.497711181640625 0.9771972656250006 +0.591875 -0.01129150390625 -0.497711181640625 0.9771972656250006 +0.592 -0.01129150390625 -0.498199462890625 0.9771972656250006 +0.592125 -0.01129150390625 -0.498199462890625 0.9771972656250006 +0.5922500000000001 -0.01129150390625 -0.49859619140625 0.9771972656250006 +0.592375 -0.011322021484375 -0.49896240234375 0.9771972656250006 +0.5925 -0.011322021484375 -0.49896240234375 0.9771972656250006 +0.592625 -0.011322021484375 -0.499267578125 0.9771972656250006 +0.59275 -0.011322021484375 -0.499267578125 0.9771972656250006 +0.592875 -0.011322021484375 -0.49951171875 0.9771972656250006 +0.593 -0.011322021484375 -0.49969482421875 0.9771972656250006 +0.593125 -0.011322021484375 -0.49969482421875 0.9771972656250006 +0.5932500000000001 -0.011322021484375 -0.49981689453125 0.9771972656250006 +0.593375 -0.011322021484375 -0.49981689453125 0.9771972656250006 +0.5935 -0.011322021484375 -0.499908447265625 0.9771972656250006 +0.593625 -0.011322021484375 -0.49993896484375 0.9771972656250006 +0.59375 -0.011322021484375 -0.49993896484375 0.9771972656250006 +0.593875 -0.011322021484375 -0.499908447265625 0.9771972656250006 +0.594 -0.011322021484375 -0.499908447265625 0.9771972656250006 +0.594125 -0.011322021484375 -0.49981689453125 0.9771972656250006 +0.5942500000000001 -0.011322021484375 -0.49969482421875 0.9771972656250006 +0.594375 -0.011322021484375 -0.49969482421875 0.9771972656250006 +0.5945 -0.011322021484375 -0.49951171875 0.9771972656250006 +0.594625 -0.011322021484375 -0.49951171875 0.9771972656250006 +0.59475 -0.011322021484375 -0.499267578125 0.9771972656250006 +0.594875 -0.011322021484375 -0.49896240234375 0.9771972656250006 +0.595 -0.011322021484375 -0.49896240234375 0.9771972656250006 +0.595125 -0.01129150390625 -0.49859619140625 0.9771972656250006 +0.5952500000000001 -0.01129150390625 -0.49859619140625 0.9771972656250006 +0.595375 -0.01129150390625 -0.498199462890625 0.9771972656250006 +0.5955 -0.01129150390625 -0.497711181640625 0.9771972656250006 +0.595625 -0.01129150390625 -0.497711181640625 0.9771972656250006 +0.59575 -0.011260986328125 -0.4971923828125 0.9771972656250006 +0.595875 -0.011260986328125 -0.4971923828125 0.9771972656250006 +0.596 -0.011260986328125 -0.496612548828125 0.9771972656250006 +0.596125 -0.011260986328125 -0.496002197265625 0.9771972656250006 +0.5962500000000001 -0.011260986328125 -0.496002197265625 0.9771972656250006 +0.596375 -0.01123046875 -0.49530029296875 0.9771972656250006 +0.5965 -0.01123046875 -0.49530029296875 0.9771972656250006 +0.596625 -0.011199951171875 -0.49456787109375 0.9771972656250006 +0.59675 -0.011199951171875 -0.4937744140625 0.9771972656250006 +0.596875 -0.011199951171875 -0.4937744140625 0.9771972656250006 +0.597 -0.01116943359375 -0.492950439453125 0.9771972656250006 +0.597125 -0.01116943359375 -0.492950439453125 0.9771972656250006 +0.5972500000000001 -0.01116943359375 -0.492034912109375 0.9771972656250006 +0.597375 -0.011138916015625 -0.4910888671875 0.9771972656250006 +0.5975 -0.011138916015625 -0.4910888671875 0.9771972656250006 +0.597625 -0.0111083984375 -0.490081787109375 0.9771972656250006 +0.59775 -0.0111083984375 -0.490081787109375 0.9771972656250006 +0.597875 -0.011077880859375 -0.489013671875 0.9771972656250006 +0.598 -0.011077880859375 -0.487884521484375 0.9771972656250006 +0.598125 -0.011077880859375 -0.487884521484375 0.9771972656250006 +0.5982500000000001 -0.01104736328125 -0.486724853515625 0.9771972656250006 +0.598375 -0.01104736328125 -0.486724853515625 0.9771972656250006 +0.5985 -0.011016845703125 -0.485504150390625 0.9771972656250006 +0.598625 -0.010986328125 -0.484222412109375 0.9771972656250006 +0.59875 -0.010986328125 -0.484222412109375 0.9771972656250006 +0.598875 -0.010955810546875 -0.48291015625 0.9771972656250006 +0.599 -0.010955810546875 -0.48291015625 0.9771972656250006 +0.599125 -0.01092529296875 -0.48150634765625 0.9771972656250006 +0.5992500000000001 -0.010894775390625 -0.480072021484375 0.9771972656250006 +0.599375 -0.010894775390625 -0.480072021484375 0.9771972656250006 +0.5995 -0.0108642578125 -0.478607177734375 0.9771972656250006 +0.599625 -0.0108642578125 -0.478607177734375 0.9771972656250006 +0.59975 -0.01080322265625 -0.47705078125 0.9771972656250006 +0.599875 -0.010772705078125 -0.4754638671875 0.9771972656250006 +0.6 -0.010772705078125 -0.4754638671875 0.9771972656250006 +0.600125 -0.0107421875 -0.47381591796875 0.9771972656250006 +0.6002500000000001 -0.0107421875 -0.47381591796875 0.9771972656250006 +0.600375 -0.010711669921875 -0.472137451171875 0.9771972656250006 +0.6005 -0.010650634765625 -0.470367431640625 0.9771972656250006 +0.600625 -0.010650634765625 -0.470367431640625 0.9771972656250006 +0.60075 -0.0106201171875 -0.46856689453125 0.9771972656250006 +0.600875 -0.0106201171875 -0.46856689453125 0.9771972656250006 +0.601 -0.010589599609375 -0.46673583984375 0.9771972656250006 +0.601125 -0.010528564453125 -0.464813232421875 0.9771972656250006 +0.6012500000000001 -0.010528564453125 -0.464813232421875 0.9771972656250006 +0.601375 -0.010498046875 -0.462890625 0.9771972656250006 +0.6015 -0.010498046875 -0.462890625 0.9771972656250006 +0.601625 -0.01043701171875 -0.46087646484375 0.9771972656250006 +0.60175 -0.010406494140625 -0.458831787109375 0.9771972656250006 +0.601875 -0.010406494140625 -0.458831787109375 0.9771972656250006 +0.602 -0.010345458984375 -0.45672607421875 0.9771972656250006 +0.602125 -0.010345458984375 -0.45672607421875 0.9771972656250006 +0.6022500000000001 -0.01031494140625 -0.454559326171875 0.9771972656250006 +0.602375 -0.01025390625 -0.452362060546875 0.9771972656250006 +0.6025 -0.01025390625 -0.452362060546875 0.9771972656250006 +0.602625 -0.01019287109375 -0.450103759765625 0.9771972656250006 +0.60275 -0.01019287109375 -0.450103759765625 0.9771972656250006 +0.602875 -0.010162353515625 -0.447784423828125 0.9771972656250006 +0.603 -0.010101318359375 -0.4454345703125 0.9771972656250006 +0.603125 -0.010101318359375 -0.4454345703125 0.9771972656250006 +0.6032500000000001 -0.010040283203125 -0.44305419921875 0.9771972656250006 +0.603375 -0.010040283203125 -0.44305419921875 0.9771972656250006 +0.6035 -0.009979248046875 -0.440582275390625 0.9771972656250006 +0.603625 -0.009918212890625 -0.438079833984375 0.9771972656250006 +0.60375 -0.009918212890625 -0.438079833984375 0.9771972656250006 +0.6038750000000001 -0.0098876953125 -0.435546875 0.9771972656250006 +0.604 -0.0098876953125 -0.435546875 0.9771972656250006 +0.604125 -0.00982666015625 -0.432952880859375 0.9771972656250006 +0.6042500000000001 -0.009765625 -0.4302978515625 0.9771972656250006 +0.604375 -0.009765625 -0.4302978515625 0.9771972656250006 +0.6045 -0.00970458984375 -0.4276123046875 0.9771972656250006 +0.604625 -0.00970458984375 -0.4276123046875 0.9771972656250006 +0.60475 -0.0096435546875 -0.424896240234375 0.9771972656250006 +0.6048750000000001 -0.00958251953125 -0.422119140625 0.9771972656250006 +0.605 -0.00958251953125 -0.422119140625 0.9771972656250006 +0.605125 -0.009490966796875 -0.419281005859375 0.9771972656250006 +0.6052500000000001 -0.009490966796875 -0.419281005859375 0.9771972656250006 +0.605375 -0.009429931640625 -0.416412353515625 0.9771972656250006 +0.6055 -0.009368896484375 -0.413482666015625 0.9771972656250006 +0.605625 -0.009368896484375 -0.413482666015625 0.9771972656250006 +0.60575 -0.009307861328125 -0.4105224609375 0.9771972656250006 +0.6058750000000001 -0.009307861328125 -0.4105224609375 0.9771972656250006 +0.606 -0.009246826171875 -0.407501220703125 0.9771972656250006 +0.606125 -0.0091552734375 -0.404449462890625 0.9771972656250006 +0.6062500000000001 -0.0091552734375 -0.404449462890625 0.9771972656250006 +0.606375 -0.00909423828125 -0.401336669921875 0.9771972656250006 +0.6065 -0.00909423828125 -0.401336669921875 0.9771972656250006 +0.606625 -0.009033203125 -0.398193359375 0.9771972656250006 +0.60675 -0.008941650390625 -0.39501953125 0.9771972656250006 +0.6068750000000001 -0.008941650390625 -0.39501953125 0.9771972656250006 +0.607 -0.008880615234375 -0.39178466796875 0.9771972656250006 +0.607125 -0.008880615234375 -0.39178466796875 0.9771972656250006 +0.6072500000000001 -0.008819580078125 -0.388519287109375 0.9771972656250006 +0.607375 -0.00872802734375 -0.38519287109375 0.9771972656250006 +0.6075 -0.00872802734375 -0.38519287109375 0.9771972656250006 +0.607625 -0.0086669921875 -0.3818359375 0.9771972656250006 +0.60775 -0.0086669921875 -0.3818359375 0.9771972656250006 +0.6078750000000001 -0.008575439453125 -0.378448486328125 0.9771972656250006 +0.608 -0.006622314453125 -0.375 0.9822387695312494 +0.608125 -0.006622314453125 -0.375 0.9822387695312494 +0.60825 -0.006561279296875 -0.37152099609375 0.9822387695312494 +0.608375 -0.006561279296875 -0.37152099609375 0.9822387695312494 +0.6085 -0.006500244140625 -0.36798095703125 0.9822387695312494 +0.608625 -0.006439208984375 -0.36444091796875 0.9822387695312494 +0.60875 -0.006439208984375 -0.36444091796875 0.9822387695312494 +0.6088750000000001 -0.00634765625 -0.360809326171875 0.9822387695312494 +0.609 -0.00634765625 -0.360809326171875 0.9822387695312494 +0.609125 -0.00628662109375 -0.357177734375 0.9822387695312494 +0.60925 -0.0062255859375 -0.353485107421875 0.9822387695312494 +0.609375 -0.0062255859375 -0.353485107421875 0.9822387695312494 +0.6095 -0.00616455078125 -0.349761962890625 0.9822387695312494 +0.609625 -0.00616455078125 -0.349761962890625 0.9822387695312494 +0.60975 -0.006103515625 -0.34600830078125 0.9822387695312494 +0.6098750000000001 -0.00604248046875 -0.34222412109375 0.9822387695312494 +0.61 -0.00604248046875 -0.34222412109375 0.9822387695312494 +0.610125 -0.005950927734375 -0.33837890625 0.9822387695312494 +0.61025 -0.005950927734375 -0.33837890625 0.9822387695312494 +0.610375 -0.005889892578125 -0.334503173828125 0.9822387695312494 +0.6105 -0.005828857421875 -0.330596923828125 0.9822387695312494 +0.610625 -0.005828857421875 -0.330596923828125 0.9822387695312494 +0.61075 -0.005767822265625 -0.32666015625 0.9822387695312494 +0.6108750000000001 -0.005767822265625 -0.32666015625 0.9822387695312494 +0.611 -0.00567626953125 -0.322662353515625 0.9822387695312494 +0.611125 -0.005615234375 -0.31866455078125 0.9822387695312494 +0.61125 -0.005615234375 -0.31866455078125 0.9822387695312494 +0.611375 -0.00555419921875 -0.314605712890625 0.9822387695312494 +0.6115 -0.00555419921875 -0.314605712890625 0.9822387695312494 +0.611625 -0.005462646484375 -0.310516357421875 0.9822387695312494 +0.61175 -0.005401611328125 -0.306396484375 0.9822387695312494 +0.6118750000000001 -0.005401611328125 -0.306396484375 0.9822387695312494 +0.612 -0.005340576171875 -0.30224609375 0.9822387695312494 +0.612125 -0.005340576171875 -0.30224609375 0.9822387695312494 +0.61225 -0.0052490234375 -0.298065185546875 0.9822387695312494 +0.612375 -0.00518798828125 -0.2938232421875 0.9822387695312494 +0.6125 -0.00518798828125 -0.2938232421875 0.9822387695312494 +0.612625 -0.005096435546875 -0.289581298828125 0.9822387695312494 +0.61275 -0.005096435546875 -0.289581298828125 0.9822387695312494 +0.6128750000000001 -0.005035400390625 -0.285308837890625 0.9822387695312494 +0.613 -0.00494384765625 -0.280975341796875 0.9822387695312494 +0.613125 -0.00494384765625 -0.280975341796875 0.9822387695312494 +0.61325 -0.0048828125 -0.276641845703125 0.9822387695312494 +0.613375 -0.0048828125 -0.276641845703125 0.9822387695312494 +0.6135 -0.004791259765625 -0.27227783203125 0.9822387695312494 +0.613625 -0.004730224609375 -0.267852783203125 0.9822387695312494 +0.61375 -0.004730224609375 -0.267852783203125 0.9822387695312494 +0.6138750000000001 -0.004638671875 -0.263427734375 0.9822387695312494 +0.614 -0.004638671875 -0.263427734375 0.9822387695312494 +0.614125 -0.004547119140625 -0.25897216796875 0.9822387695312494 +0.61425 -0.004486083984375 -0.25445556640625 0.9822387695312494 +0.614375 -0.004486083984375 -0.25445556640625 0.9822387695312494 +0.6145 -0.00439453125 -0.249969482421875 0.9822387695312494 +0.614625 -0.00439453125 -0.249969482421875 0.9822387695312494 +0.61475 -0.00433349609375 -0.24542236328125 0.9822387695312494 +0.6148750000000001 -0.004241943359375 -0.2408447265625 0.9822387695312494 +0.615 -0.004241943359375 -0.2408447265625 0.9822387695312494 +0.615125 -0.004150390625 -0.236236572265625 0.9822387695312494 +0.61525 -0.004150390625 -0.236236572265625 0.9822387695312494 +0.615375 -0.00408935546875 -0.231597900390625 0.9822387695312494 +0.6155 -0.003997802734375 -0.226959228515625 0.9822387695312494 +0.615625 -0.003997802734375 -0.226959228515625 0.9822387695312494 +0.61575 -0.00390625 -0.2222900390625 0.9822387695312494 +0.6158750000000001 -0.00390625 -0.2222900390625 0.9822387695312494 +0.616 -0.003814697265625 -0.21759033203125 0.9822387695312494 +0.616125 -0.003753662109375 -0.212860107421875 0.9822387695312494 +0.61625 -0.003753662109375 -0.212860107421875 0.9822387695312494 +0.616375 -0.003662109375 -0.208099365234375 0.9822387695312494 +0.6165 -0.003662109375 -0.208099365234375 0.9822387695312494 +0.616625 -0.003570556640625 -0.203338623046875 0.9822387695312494 +0.61675 -0.00347900390625 -0.19854736328125 0.9822387695312494 +0.6168750000000001 -0.00347900390625 -0.19854736328125 0.9822387695312494 +0.617 -0.00341796875 -0.1937255859375 0.9822387695312494 +0.617125 -0.00341796875 -0.1937255859375 0.9822387695312494 +0.61725 -0.003326416015625 -0.188873291015625 0.9822387695312494 +0.617375 -0.00323486328125 -0.18402099609375 0.9822387695312494 +0.6175 -0.00323486328125 -0.18402099609375 0.9822387695312494 +0.617625 -0.003143310546875 -0.17913818359375 0.9822387695312494 +0.61775 -0.003143310546875 -0.17913818359375 0.9822387695312494 +0.6178750000000001 -0.0030517578125 -0.17425537109375 0.9822387695312494 +0.618 -0.00299072265625 -0.169342041015625 0.9822387695312494 +0.618125 -0.00299072265625 -0.169342041015625 0.9822387695312494 +0.61825 -0.002899169921875 -0.164398193359375 0.9822387695312494 +0.618375 -0.002899169921875 -0.164398193359375 0.9822387695312494 +0.6185 -0.0028076171875 -0.159454345703125 0.9822387695312494 +0.618625 -0.002716064453125 -0.15447998046875 0.9822387695312494 +0.61875 -0.002716064453125 -0.15447998046875 0.9822387695312494 +0.6188750000000001 -0.00262451171875 -0.14947509765625 0.9822387695312494 +0.619 -0.00262451171875 -0.14947509765625 0.9822387695312494 +0.619125 -0.002532958984375 -0.14447021484375 0.9822387695312494 +0.61925 -0.00244140625 -0.13946533203125 0.9822387695312494 +0.619375 -0.00244140625 -0.13946533203125 0.9822387695312494 +0.6195000000000001 -0.002349853515625 -0.134429931640625 0.9822387695312494 +0.619625 -0.002349853515625 -0.134429931640625 0.9822387695312494 +0.61975 -0.00225830078125 -0.129364013671875 0.9822387695312494 +0.6198750000000001 -0.002166748046875 -0.124298095703125 0.9822387695312494 +0.62 -0.002166748046875 -0.124298095703125 0.9822387695312494 +0.620125 -0.002105712890625 -0.119232177734375 0.9822387695312494 +0.62025 -0.002105712890625 -0.119232177734375 0.9822387695312494 +0.620375 -0.00201416015625 -0.1141357421875 0.9822387695312494 +0.6205000000000001 -0.001922607421875 -0.109039306640625 0.9822387695312494 +0.620625 -0.001922607421875 -0.109039306640625 0.9822387695312494 +0.62075 -0.0018310546875 -0.103912353515625 0.9822387695312494 +0.6208750000000001 -0.0018310546875 -0.103912353515625 0.9822387695312494 +0.621 -0.001739501953125 -0.098785400390625 0.9822387695312494 +0.621125 -0.00164794921875 -0.093658447265625 0.9822387695312494 +0.62125 -0.00164794921875 -0.093658447265625 0.9822387695312494 +0.621375 -0.001556396484375 -0.0885009765625 0.9822387695312494 +0.6215000000000001 -0.001556396484375 -0.0885009765625 0.9822387695312494 +0.621625 -0.00146484375 -0.083343505859375 0.9822387695312494 +0.62175 -0.001373291015625 -0.07818603515625 0.9822387695312494 +0.6218750000000001 -0.001373291015625 -0.07818603515625 0.9822387695312494 +0.622 -0.00128173828125 -0.072998046875 0.9822387695312494 +0.622125 -0.00128173828125 -0.072998046875 0.9822387695312494 +0.62225 -0.001190185546875 -0.06781005859375 0.9822387695312494 +0.622375 -0.0010986328125 -0.0626220703125 0.9822387695312494 +0.6225000000000001 -0.0010986328125 -0.0626220703125 0.9822387695312494 +0.622625 -0.001007080078125 -0.05743408203125 0.9822387695312494 +0.62275 -0.001007080078125 -0.05743408203125 0.9822387695312494 +0.6228750000000001 -0.00091552734375 -0.05224609375 0.9822387695312494 +0.623 -0.000823974609375 -0.047027587890625 0.9822387695312494 +0.623125 -0.000823974609375 -0.047027587890625 0.9822387695312494 +0.62325 -0.000732421875 -0.04180908203125 0.9822387695312494 +0.623375 -0.000732421875 -0.04180908203125 0.9822387695312494 +0.6235000000000001 -0.000640869140625 -0.036590576171875 0.9822387695312494 +0.623625 -0.00054931640625 -0.0313720703125 0.9822387695312494 +0.62375 -0.00054931640625 -0.0313720703125 0.9822387695312494 +0.6238750000000001 -0.000457763671875 -0.026123046875 0.9822387695312494 +0.624 -0.000457763671875 -0.026123046875 0.9822387695312494 +0.624125 -0.0003662109375 -0.020904541015625 0.9822387695312494 +0.62425 -0.000274658203125 -0.01568603515625 0.9822387695312494 +0.624375 -0.000274658203125 -0.01568603515625 0.9822387695312494 +0.6245000000000001 -0.00018310546875 -0.01043701171875 0.9822387695312494 +0.624625 -0.00018310546875 -0.01043701171875 0.9822387695312494 +0.62475 -9.1552734375e-05 -0.005218505859375 0.9822387695312494 +0.624875 0.0 0.0 0.9822387695312494 +0.625 0.0 0.0 0.9822387695312494 +0.625125 9.1552734375e-05 0.005218505859375 0.9822387695312494 +0.62525 9.1552734375e-05 0.005218505859375 0.9822387695312494 +0.625375 0.00018310546875 0.01043701171875 0.9822387695312494 +0.6255000000000001 0.000274658203125 0.01568603515625 0.9822387695312494 +0.625625 0.000274658203125 0.01568603515625 0.9822387695312494 +0.62575 0.0003662109375 0.020904541015625 0.9822387695312494 +0.625875 0.0003662109375 0.020904541015625 0.9822387695312494 +0.626 0.000457763671875 0.026123046875 0.9822387695312494 +0.626125 0.00054931640625 0.0313720703125 0.9822387695312494 +0.62625 0.00054931640625 0.0313720703125 0.9822387695312494 +0.626375 0.000640869140625 0.036590576171875 0.9822387695312494 +0.6265000000000001 0.000640869140625 0.036590576171875 0.9822387695312494 +0.626625 0.000732421875 0.04180908203125 0.9822387695312494 +0.62675 0.000823974609375 0.047027587890625 0.9822387695312494 +0.626875 0.000823974609375 0.047027587890625 0.9822387695312494 +0.627 0.00091552734375 0.05224609375 0.9822387695312494 +0.627125 0.00091552734375 0.05224609375 0.9822387695312494 +0.62725 0.001007080078125 0.05743408203125 0.9822387695312494 +0.627375 0.0010986328125 0.0626220703125 0.9822387695312494 +0.6275000000000001 0.0010986328125 0.0626220703125 0.9822387695312494 +0.627625 0.001190185546875 0.06781005859375 0.9822387695312494 +0.62775 0.001190185546875 0.06781005859375 0.9822387695312494 +0.627875 0.00128173828125 0.072998046875 0.9822387695312494 +0.628 0.001373291015625 0.07818603515625 0.9822387695312494 +0.628125 0.001373291015625 0.07818603515625 0.9822387695312494 +0.62825 0.00146484375 0.083343505859375 0.9822387695312494 +0.628375 0.00146484375 0.083343505859375 0.9822387695312494 +0.6285000000000001 0.001556396484375 0.0885009765625 0.9822387695312494 +0.628625 0.00164794921875 0.093658447265625 0.9822387695312494 +0.62875 0.00164794921875 0.093658447265625 0.9822387695312494 +0.628875 0.001739501953125 0.098785400390625 0.9822387695312494 +0.629 0.001739501953125 0.098785400390625 0.9822387695312494 +0.629125 0.0018310546875 0.103912353515625 0.9822387695312494 +0.62925 0.001922607421875 0.109039306640625 0.9822387695312494 +0.629375 0.001922607421875 0.109039306640625 0.9822387695312494 +0.6295000000000001 0.00201416015625 0.1141357421875 0.9822387695312494 +0.629625 0.00201416015625 0.1141357421875 0.9822387695312494 +0.62975 0.002105712890625 0.119232177734375 0.9822387695312494 +0.629875 0.002166748046875 0.124298095703125 0.9822387695312494 +0.63 0.002166748046875 0.124298095703125 0.9822387695312494 +0.630125 0.00225830078125 0.129364013671875 0.9822387695312494 +0.63025 0.00225830078125 0.129364013671875 0.9822387695312494 +0.630375 0.002349853515625 0.134429931640625 0.9822387695312494 +0.6305000000000001 0.00244140625 0.13946533203125 0.9822387695312494 +0.630625 0.00244140625 0.13946533203125 0.9822387695312494 +0.63075 0.002532958984375 0.14447021484375 0.9822387695312494 +0.630875 0.002532958984375 0.14447021484375 0.9822387695312494 +0.631 0.00262451171875 0.14947509765625 0.9822387695312494 +0.631125 0.002716064453125 0.15447998046875 0.9822387695312494 +0.63125 0.002716064453125 0.15447998046875 0.9822387695312494 +0.631375 0.0028076171875 0.159454345703125 0.9822387695312494 +0.6315000000000001 0.0028076171875 0.159454345703125 0.9822387695312494 +0.631625 0.002899169921875 0.164398193359375 0.9822387695312494 +0.63175 0.00299072265625 0.169342041015625 0.9822387695312494 +0.631875 0.00299072265625 0.169342041015625 0.9822387695312494 +0.632 0.0030517578125 0.17425537109375 0.9822387695312494 +0.632125 0.0030517578125 0.17425537109375 0.9822387695312494 +0.63225 0.003143310546875 0.17913818359375 0.9822387695312494 +0.632375 0.00323486328125 0.18402099609375 0.9822387695312494 +0.6325000000000001 0.00323486328125 0.18402099609375 0.9822387695312494 +0.632625 0.003326416015625 0.188873291015625 0.9822387695312494 +0.63275 0.003326416015625 0.188873291015625 0.9822387695312494 +0.632875 0.00341796875 0.1937255859375 0.9822387695312494 +0.633 0.00347900390625 0.19854736328125 0.9822387695312494 +0.633125 0.00347900390625 0.19854736328125 0.9822387695312494 +0.63325 0.003570556640625 0.203338623046875 0.9822387695312494 +0.633375 0.003570556640625 0.203338623046875 0.9822387695312494 +0.6335000000000001 0.003662109375 0.208099365234375 0.9822387695312494 +0.633625 0.003753662109375 0.212860107421875 0.9822387695312494 +0.63375 0.003753662109375 0.212860107421875 0.9822387695312494 +0.633875 0.003814697265625 0.21759033203125 0.9822387695312494 +0.634 0.003814697265625 0.21759033203125 0.9822387695312494 +0.634125 0.00390625 0.2222900390625 0.9822387695312494 +0.63425 0.003997802734375 0.226959228515625 0.9822387695312494 +0.634375 0.003997802734375 0.226959228515625 0.9822387695312494 +0.6345000000000001 0.00408935546875 0.231597900390625 0.9822387695312494 +0.634625 0.00408935546875 0.231597900390625 0.9822387695312494 +0.63475 0.004150390625 0.236236572265625 0.9822387695312494 +0.634875 0.004241943359375 0.2408447265625 0.9822387695312494 +0.635 0.004241943359375 0.2408447265625 0.9822387695312494 +0.6351250000000001 0.00433349609375 0.24542236328125 0.9822387695312494 +0.63525 0.00433349609375 0.24542236328125 0.9822387695312494 +0.635375 0.00439453125 0.249969482421875 0.9822387695312494 +0.6355000000000001 0.004486083984375 0.25445556640625 0.9822387695312494 +0.635625 0.004486083984375 0.25445556640625 0.9822387695312494 +0.63575 0.004547119140625 0.25897216796875 0.9822387695312494 +0.635875 0.004547119140625 0.25897216796875 0.9822387695312494 +0.636 0.004638671875 0.263427734375 0.9822387695312494 +0.6361250000000001 0.004730224609375 0.267852783203125 0.9822387695312494 +0.63625 0.004730224609375 0.267852783203125 0.9822387695312494 +0.636375 0.004791259765625 0.27227783203125 0.9822387695312494 +0.6365000000000001 0.004791259765625 0.27227783203125 0.9822387695312494 +0.636625 0.0048828125 0.276641845703125 0.9822387695312494 +0.63675 0.00494384765625 0.280975341796875 0.9822387695312494 +0.636875 0.00494384765625 0.280975341796875 0.9822387695312494 +0.637 0.005035400390625 0.285308837890625 0.9822387695312494 +0.6371250000000001 0.005035400390625 0.285308837890625 0.9822387695312494 +0.63725 0.005096435546875 0.289581298828125 0.9822387695312494 +0.637375 0.00518798828125 0.2938232421875 0.9822387695312494 +0.6375000000000001 0.00518798828125 0.2938232421875 0.9822387695312494 +0.637625 0.0052490234375 0.298065185546875 0.9822387695312494 +0.63775 0.0052490234375 0.298065185546875 0.9822387695312494 +0.637875 0.005340576171875 0.30224609375 0.9822387695312494 +0.638 0.005401611328125 0.306396484375 0.9822387695312494 +0.6381250000000001 0.005401611328125 0.306396484375 0.9822387695312494 +0.63825 0.005462646484375 0.310516357421875 0.9822387695312494 +0.638375 0.005462646484375 0.310516357421875 0.9822387695312494 +0.6385000000000001 0.00555419921875 0.314605712890625 0.9822387695312494 +0.638625 0.005615234375 0.31866455078125 0.9822387695312494 +0.63875 0.005615234375 0.31866455078125 0.9822387695312494 +0.638875 0.00567626953125 0.322662353515625 0.9822387695312494 +0.639 0.00567626953125 0.322662353515625 0.9822387695312494 +0.6391250000000001 0.005767822265625 0.32666015625 0.9822387695312494 +0.63925 0.005828857421875 0.330596923828125 0.9822387695312494 +0.639375 0.005828857421875 0.330596923828125 0.9822387695312494 +0.6395000000000001 0.005889892578125 0.334503173828125 0.9822387695312494 +0.639625 0.005889892578125 0.334503173828125 0.9822387695312494 +0.63975 0.005950927734375 0.33837890625 0.9822387695312494 +0.639875 0.00604248046875 0.34222412109375 0.9822387695312494 +0.64 0.057952880859375 0.34222412109375 0.8305419921874982 +0.6401250000000001 0.05859375 0.34600830078125 0.8305419921874982 +0.64025 0.05859375 0.34600830078125 0.8305419921874982 +0.640375 0.059234619140625 0.349761962890625 0.8305419921874982 +0.6405 0.05987548828125 0.353485107421875 0.8305419921874982 +0.640625 0.05987548828125 0.353485107421875 0.8305419921874982 +0.64075 0.06048583984375 0.357177734375 0.8305419921874982 +0.640875 0.06048583984375 0.357177734375 0.8305419921874982 +0.641 0.06109619140625 0.360809326171875 0.8305419921874982 +0.6411250000000001 0.06170654296875 0.36444091796875 0.8305419921874982 +0.64125 0.06170654296875 0.36444091796875 0.8305419921874982 +0.641375 0.06231689453125 0.36798095703125 0.8305419921874982 +0.6415 0.06231689453125 0.36798095703125 0.8305419921874982 +0.641625 0.06292724609375 0.37152099609375 0.8305419921874982 +0.64175 0.063507080078125 0.375 0.8305419921874982 +0.641875 0.063507080078125 0.375 0.8305419921874982 +0.642 0.0640869140625 0.378448486328125 0.8305419921874982 +0.6421250000000001 0.0640869140625 0.378448486328125 0.8305419921874982 +0.64225 0.064666748046875 0.3818359375 0.8305419921874982 +0.642375 0.06524658203125 0.38519287109375 0.8305419921874982 +0.6425 0.06524658203125 0.38519287109375 0.8305419921874982 +0.642625 0.0657958984375 0.388519287109375 0.8305419921874982 +0.64275 0.0657958984375 0.388519287109375 0.8305419921874982 +0.642875 0.06634521484375 0.39178466796875 0.8305419921874982 +0.643 0.06689453125 0.39501953125 0.8305419921874982 +0.6431250000000001 0.06689453125 0.39501953125 0.8305419921874982 +0.64325 0.06744384765625 0.398193359375 0.8305419921874982 +0.643375 0.06744384765625 0.398193359375 0.8305419921874982 +0.6435 0.067962646484375 0.401336669921875 0.8305419921874982 +0.643625 0.0684814453125 0.404449462890625 0.8305419921874982 +0.64375 0.0684814453125 0.404449462890625 0.8305419921874982 +0.643875 0.069000244140625 0.407501220703125 0.8305419921874982 +0.644 0.069000244140625 0.407501220703125 0.8305419921874982 +0.6441250000000001 0.06951904296875 0.4105224609375 0.8305419921874982 +0.64425 0.07000732421875 0.413482666015625 0.8305419921874982 +0.644375 0.07000732421875 0.413482666015625 0.8305419921874982 +0.6445 0.070526123046875 0.416412353515625 0.8305419921874982 +0.644625 0.070526123046875 0.416412353515625 0.8305419921874982 +0.64475 0.071014404296875 0.419281005859375 0.8305419921874982 +0.644875 0.07147216796875 0.422119140625 0.8305419921874982 +0.645 0.07147216796875 0.422119140625 0.8305419921874982 +0.6451250000000001 0.07196044921875 0.424896240234375 0.8305419921874982 +0.64525 0.07196044921875 0.424896240234375 0.8305419921874982 +0.645375 0.072418212890625 0.4276123046875 0.8305419921874982 +0.6455 0.0728759765625 0.4302978515625 0.8305419921874982 +0.645625 0.0728759765625 0.4302978515625 0.8305419921874982 +0.64575 0.073333740234375 0.432952880859375 0.8305419921874982 +0.645875 0.073333740234375 0.432952880859375 0.8305419921874982 +0.646 0.073760986328125 0.435546875 0.8305419921874982 +0.6461250000000001 0.074188232421875 0.438079833984375 0.8305419921874982 +0.64625 0.074188232421875 0.438079833984375 0.8305419921874982 +0.646375 0.074615478515625 0.440582275390625 0.8305419921874982 +0.6465 0.074615478515625 0.440582275390625 0.8305419921874982 +0.646625 0.075042724609375 0.44305419921875 0.8305419921874982 +0.64675 0.075439453125 0.4454345703125 0.8305419921874982 +0.646875 0.075439453125 0.4454345703125 0.8305419921874982 +0.647 0.075836181640625 0.447784423828125 0.8305419921874982 +0.6471250000000001 0.075836181640625 0.447784423828125 0.8305419921874982 +0.64725 0.07623291015625 0.450103759765625 0.8305419921874982 +0.647375 0.07659912109375 0.452362060546875 0.8305419921874982 +0.6475 0.07659912109375 0.452362060546875 0.8305419921874982 +0.647625 0.07696533203125 0.454559326171875 0.8305419921874982 +0.64775 0.07696533203125 0.454559326171875 0.8305419921874982 +0.647875 0.07733154296875 0.45672607421875 0.8305419921874982 +0.648 0.07769775390625 0.458831787109375 0.8305419921874982 +0.6481250000000001 0.07769775390625 0.458831787109375 0.8305419921874982 +0.64825 0.07806396484375 0.46087646484375 0.8305419921874982 +0.648375 0.07806396484375 0.46087646484375 0.8305419921874982 +0.6485 0.078399658203125 0.462890625 0.8305419921874982 +0.648625 0.078704833984375 0.464813232421875 0.8305419921874982 +0.64875 0.078704833984375 0.464813232421875 0.8305419921874982 +0.648875 0.07904052734375 0.46673583984375 0.8305419921874982 +0.649 0.07904052734375 0.46673583984375 0.8305419921874982 +0.6491250000000001 0.079345703125 0.46856689453125 0.8305419921874982 +0.64925 0.07965087890625 0.470367431640625 0.8305419921874982 +0.649375 0.07965087890625 0.470367431640625 0.8305419921874982 +0.6495 0.0799560546875 0.472137451171875 0.8305419921874982 +0.649625 0.0799560546875 0.472137451171875 0.8305419921874982 +0.64975 0.080230712890625 0.47381591796875 0.8305419921874982 +0.649875 0.080535888671875 0.4754638671875 0.8305419921874982 +0.65 0.080535888671875 0.4754638671875 0.8305419921874982 +0.6501250000000001 0.080780029296875 0.47705078125 0.8305419921874982 +0.65025 0.080780029296875 0.47705078125 0.8305419921874982 +0.650375 0.0810546875 0.478607177734375 0.8305419921874982 +0.6505 0.081298828125 0.480072021484375 0.8305419921874982 +0.650625 0.081298828125 0.480072021484375 0.8305419921874982 +0.6507500000000001 0.08154296875 0.48150634765625 0.8305419921874982 +0.650875 0.08154296875 0.48150634765625 0.8305419921874982 +0.651 0.081787109375 0.48291015625 0.8305419921874982 +0.6511250000000001 0.082000732421875 0.484222412109375 0.8305419921874982 +0.65125 0.082000732421875 0.484222412109375 0.8305419921874982 +0.651375 0.08221435546875 0.485504150390625 0.8305419921874982 +0.6515 0.08221435546875 0.485504150390625 0.8305419921874982 +0.651625 0.082427978515625 0.486724853515625 0.8305419921874982 +0.6517500000000001 0.0826416015625 0.487884521484375 0.8305419921874982 +0.651875 0.0826416015625 0.487884521484375 0.8305419921874982 +0.652 0.08282470703125 0.489013671875 0.8305419921874982 +0.6521250000000001 0.08282470703125 0.489013671875 0.8305419921874982 +0.65225 0.0830078125 0.490081787109375 0.8305419921874982 +0.652375 0.083160400390625 0.4910888671875 0.8305419921874982 +0.6525 0.083160400390625 0.4910888671875 0.8305419921874982 +0.652625 0.083343505859375 0.492034912109375 0.8305419921874982 +0.6527500000000001 0.083343505859375 0.492034912109375 0.8305419921874982 +0.652875 0.08349609375 0.492950439453125 0.8305419921874982 +0.653 0.0836181640625 0.4937744140625 0.8305419921874982 +0.6531250000000001 0.0836181640625 0.4937744140625 0.8305419921874982 +0.65325 0.083770751953125 0.49456787109375 0.8305419921874982 +0.653375 0.083770751953125 0.49456787109375 0.8305419921874982 +0.6535 0.083892822265625 0.49530029296875 0.8305419921874982 +0.653625 0.083984375 0.496002197265625 0.8305419921874982 +0.6537500000000001 0.083984375 0.496002197265625 0.8305419921874982 +0.653875 0.0841064453125 0.496612548828125 0.8305419921874982 +0.654 0.0841064453125 0.496612548828125 0.8305419921874982 +0.6541250000000001 0.084197998046875 0.4971923828125 0.8305419921874982 +0.65425 0.08428955078125 0.497711181640625 0.8305419921874982 +0.654375 0.08428955078125 0.497711181640625 0.8305419921874982 +0.6545 0.084381103515625 0.498199462890625 0.8305419921874982 +0.654625 0.084381103515625 0.498199462890625 0.8305419921874982 +0.6547500000000001 0.084442138671875 0.49859619140625 0.8305419921874982 +0.654875 0.084503173828125 0.49896240234375 0.8305419921874982 +0.655 0.084503173828125 0.49896240234375 0.8305419921874982 +0.6551250000000001 0.084564208984375 0.499267578125 0.8305419921874982 +0.65525 0.084564208984375 0.499267578125 0.8305419921874982 +0.655375 0.0845947265625 0.49951171875 0.8305419921874982 +0.6555 0.084625244140625 0.49969482421875 0.8305419921874982 +0.655625 0.084625244140625 0.49969482421875 0.8305419921874982 +0.6557500000000001 0.08465576171875 0.49981689453125 0.8305419921874982 +0.655875 0.08465576171875 0.49981689453125 0.8305419921874982 +0.656 0.08465576171875 0.499908447265625 0.8305419921874982 +0.656125 0.08465576171875 0.49993896484375 0.8305419921874982 +0.65625 0.08465576171875 0.49993896484375 0.8305419921874982 +0.656375 0.08465576171875 0.499908447265625 0.8305419921874982 +0.6565 0.08465576171875 0.499908447265625 0.8305419921874982 +0.656625 0.08465576171875 0.49981689453125 0.8305419921874982 +0.6567500000000001 0.084625244140625 0.49969482421875 0.8305419921874982 +0.656875 0.084625244140625 0.49969482421875 0.8305419921874982 +0.657 0.0845947265625 0.49951171875 0.8305419921874982 +0.657125 0.0845947265625 0.49951171875 0.8305419921874982 +0.65725 0.084564208984375 0.499267578125 0.8305419921874982 +0.657375 0.084503173828125 0.49896240234375 0.8305419921874982 +0.6575 0.084503173828125 0.49896240234375 0.8305419921874982 +0.657625 0.084442138671875 0.49859619140625 0.8305419921874982 +0.6577500000000001 0.084442138671875 0.49859619140625 0.8305419921874982 +0.657875 0.084381103515625 0.498199462890625 0.8305419921874982 +0.658 0.08428955078125 0.497711181640625 0.8305419921874982 +0.658125 0.08428955078125 0.497711181640625 0.8305419921874982 +0.65825 0.084197998046875 0.4971923828125 0.8305419921874982 +0.658375 0.084197998046875 0.4971923828125 0.8305419921874982 +0.6585 0.0841064453125 0.496612548828125 0.8305419921874982 +0.658625 0.083984375 0.496002197265625 0.8305419921874982 +0.6587500000000001 0.083984375 0.496002197265625 0.8305419921874982 +0.658875 0.083892822265625 0.49530029296875 0.8305419921874982 +0.659 0.083892822265625 0.49530029296875 0.8305419921874982 +0.659125 0.083770751953125 0.49456787109375 0.8305419921874982 +0.65925 0.0836181640625 0.4937744140625 0.8305419921874982 +0.659375 0.0836181640625 0.4937744140625 0.8305419921874982 +0.6595 0.08349609375 0.492950439453125 0.8305419921874982 +0.659625 0.08349609375 0.492950439453125 0.8305419921874982 +0.6597500000000001 0.083343505859375 0.492034912109375 0.8305419921874982 +0.659875 0.083160400390625 0.4910888671875 0.8305419921874982 +0.66 0.083160400390625 0.4910888671875 0.8305419921874982 +0.660125 0.0830078125 0.490081787109375 0.8305419921874982 +0.66025 0.0830078125 0.490081787109375 0.8305419921874982 +0.660375 0.08282470703125 0.489013671875 0.8305419921874982 +0.6605 0.0826416015625 0.487884521484375 0.8305419921874982 +0.660625 0.0826416015625 0.487884521484375 0.8305419921874982 +0.6607500000000001 0.082427978515625 0.486724853515625 0.8305419921874982 +0.660875 0.082427978515625 0.486724853515625 0.8305419921874982 +0.661 0.08221435546875 0.485504150390625 0.8305419921874982 +0.661125 0.082000732421875 0.484222412109375 0.8305419921874982 +0.66125 0.082000732421875 0.484222412109375 0.8305419921874982 +0.661375 0.081787109375 0.48291015625 0.8305419921874982 +0.6615 0.081787109375 0.48291015625 0.8305419921874982 +0.661625 0.08154296875 0.48150634765625 0.8305419921874982 +0.6617500000000001 0.081298828125 0.480072021484375 0.8305419921874982 +0.661875 0.081298828125 0.480072021484375 0.8305419921874982 +0.662 0.0810546875 0.478607177734375 0.8305419921874982 +0.662125 0.0810546875 0.478607177734375 0.8305419921874982 +0.66225 0.080780029296875 0.47705078125 0.8305419921874982 +0.662375 0.080535888671875 0.4754638671875 0.8305419921874982 +0.6625 0.080535888671875 0.4754638671875 0.8305419921874982 +0.662625 0.080230712890625 0.47381591796875 0.8305419921874982 +0.6627500000000001 0.080230712890625 0.47381591796875 0.8305419921874982 +0.662875 0.0799560546875 0.472137451171875 0.8305419921874982 +0.663 0.07965087890625 0.470367431640625 0.8305419921874982 +0.663125 0.07965087890625 0.470367431640625 0.8305419921874982 +0.66325 0.079345703125 0.46856689453125 0.8305419921874982 +0.663375 0.079345703125 0.46856689453125 0.8305419921874982 +0.6635 0.07904052734375 0.46673583984375 0.8305419921874982 +0.663625 0.078704833984375 0.464813232421875 0.8305419921874982 +0.6637500000000001 0.078704833984375 0.464813232421875 0.8305419921874982 +0.663875 0.078399658203125 0.462890625 0.8305419921874982 +0.664 0.078399658203125 0.462890625 0.8305419921874982 +0.664125 0.07806396484375 0.46087646484375 0.8305419921874982 +0.66425 0.07769775390625 0.458831787109375 0.8305419921874982 +0.664375 0.07769775390625 0.458831787109375 0.8305419921874982 +0.6645 0.07733154296875 0.45672607421875 0.8305419921874982 +0.664625 0.07733154296875 0.45672607421875 0.8305419921874982 +0.6647500000000001 0.07696533203125 0.454559326171875 0.8305419921874982 +0.664875 0.07659912109375 0.452362060546875 0.8305419921874982 +0.665 0.07659912109375 0.452362060546875 0.8305419921874982 +0.665125 0.07623291015625 0.450103759765625 0.8305419921874982 +0.66525 0.07623291015625 0.450103759765625 0.8305419921874982 +0.665375 0.075836181640625 0.447784423828125 0.8305419921874982 +0.6655 0.075439453125 0.4454345703125 0.8305419921874982 +0.665625 0.075439453125 0.4454345703125 0.8305419921874982 +0.6657500000000001 0.075042724609375 0.44305419921875 0.8305419921874982 +0.665875 0.075042724609375 0.44305419921875 0.8305419921874982 +0.666 0.074615478515625 0.440582275390625 0.8305419921874982 +0.666125 0.074188232421875 0.438079833984375 0.8305419921874982 +0.66625 0.074188232421875 0.438079833984375 0.8305419921874982 +0.6663750000000001 0.073760986328125 0.435546875 0.8305419921874982 +0.6665 0.073760986328125 0.435546875 0.8305419921874982 +0.666625 0.073333740234375 0.432952880859375 0.8305419921874982 +0.6667500000000001 0.0728759765625 0.4302978515625 0.8305419921874982 +0.666875 0.0728759765625 0.4302978515625 0.8305419921874982 +0.667 0.072418212890625 0.4276123046875 0.8305419921874982 +0.667125 0.072418212890625 0.4276123046875 0.8305419921874982 +0.66725 0.07196044921875 0.424896240234375 0.8305419921874982 +0.6673750000000001 0.07147216796875 0.422119140625 0.8305419921874982 +0.6675 0.07147216796875 0.422119140625 0.8305419921874982 +0.667625 0.071014404296875 0.419281005859375 0.8305419921874982 +0.6677500000000001 0.071014404296875 0.419281005859375 0.8305419921874982 +0.667875 0.070526123046875 0.416412353515625 0.8305419921874982 +0.668 0.07000732421875 0.413482666015625 0.8305419921874982 +0.668125 0.07000732421875 0.413482666015625 0.8305419921874982 +0.66825 0.06951904296875 0.4105224609375 0.8305419921874982 +0.6683750000000001 0.06951904296875 0.4105224609375 0.8305419921874982 +0.6685 0.069000244140625 0.407501220703125 0.8305419921874982 +0.668625 0.0684814453125 0.404449462890625 0.8305419921874982 +0.6687500000000001 0.0684814453125 0.404449462890625 0.8305419921874982 +0.668875 0.067962646484375 0.401336669921875 0.8305419921874982 +0.669 0.067962646484375 0.401336669921875 0.8305419921874982 +0.669125 0.06744384765625 0.398193359375 0.8305419921874982 +0.66925 0.06689453125 0.39501953125 0.8305419921874982 +0.6693750000000001 0.06689453125 0.39501953125 0.8305419921874982 +0.6695 0.06634521484375 0.39178466796875 0.8305419921874982 +0.669625 0.06634521484375 0.39178466796875 0.8305419921874982 +0.6697500000000001 0.0657958984375 0.388519287109375 0.8305419921874982 +0.669875 0.06524658203125 0.38519287109375 0.8305419921874982 +0.67 0.06524658203125 0.38519287109375 0.8305419921874982 +0.670125 0.064666748046875 0.3818359375 0.8305419921874982 +0.67025 0.064666748046875 0.3818359375 0.8305419921874982 +0.6703750000000001 0.0640869140625 0.378448486328125 0.8305419921874982 +0.6705 0.063507080078125 0.375 0.8305419921874982 +0.670625 0.063507080078125 0.375 0.8305419921874982 +0.6707500000000001 0.06292724609375 0.37152099609375 0.8305419921874982 +0.670875 0.06292724609375 0.37152099609375 0.8305419921874982 +0.671 0.06231689453125 0.36798095703125 0.8305419921874982 +0.671125 0.06170654296875 0.36444091796875 0.8305419921874982 +0.67125 0.06170654296875 0.36444091796875 0.8305419921874982 +0.6713750000000001 0.06109619140625 0.360809326171875 0.8305419921874982 +0.6715 0.06109619140625 0.360809326171875 0.8305419921874982 +0.671625 0.06048583984375 0.357177734375 0.8305419921874982 +0.6717500000000001 0.05987548828125 0.353485107421875 0.8305419921874982 +0.671875 0.05987548828125 0.353485107421875 0.8305419921874982 +0.672 0.15863037109375 0.349761962890625 0.5463623046874974 +0.672125 0.15863037109375 0.349761962890625 0.5463623046874974 +0.67225 0.156951904296875 0.34600830078125 0.5463623046874974 +0.6723750000000001 0.15521240234375 0.34222412109375 0.5463623046874974 +0.6725 0.15521240234375 0.34222412109375 0.5463623046874974 +0.672625 0.153472900390625 0.33837890625 0.5463623046874974 +0.67275 0.153472900390625 0.33837890625 0.5463623046874974 +0.672875 0.1517333984375 0.334503173828125 0.5463623046874974 +0.673 0.14996337890625 0.330596923828125 0.5463623046874974 +0.673125 0.14996337890625 0.330596923828125 0.5463623046874974 +0.67325 0.148162841796875 0.32666015625 0.5463623046874974 +0.6733750000000001 0.148162841796875 0.32666015625 0.5463623046874974 +0.6735 0.1463623046875 0.322662353515625 0.5463623046874974 +0.673625 0.14453125 0.31866455078125 0.5463623046874974 +0.67375 0.14453125 0.31866455078125 0.5463623046874974 +0.673875 0.1427001953125 0.314605712890625 0.5463623046874974 +0.674 0.1427001953125 0.314605712890625 0.5463623046874974 +0.674125 0.140838623046875 0.310516357421875 0.5463623046874974 +0.67425 0.13897705078125 0.306396484375 0.5463623046874974 +0.6743750000000001 0.13897705078125 0.306396484375 0.5463623046874974 +0.6745 0.1370849609375 0.30224609375 0.5463623046874974 +0.674625 0.1370849609375 0.30224609375 0.5463623046874974 +0.67475 0.13519287109375 0.298065185546875 0.5463623046874974 +0.674875 0.133270263671875 0.2938232421875 0.5463623046874974 +0.675 0.133270263671875 0.2938232421875 0.5463623046874974 +0.675125 0.13134765625 0.289581298828125 0.5463623046874974 +0.67525 0.13134765625 0.289581298828125 0.5463623046874974 +0.6753750000000001 0.12939453125 0.285308837890625 0.5463623046874974 +0.6755 0.12744140625 0.280975341796875 0.5463623046874974 +0.675625 0.12744140625 0.280975341796875 0.5463623046874974 +0.67575 0.125457763671875 0.276641845703125 0.5463623046874974 +0.675875 0.125457763671875 0.276641845703125 0.5463623046874974 +0.676 0.123504638671875 0.27227783203125 0.5463623046874974 +0.676125 0.121490478515625 0.267852783203125 0.5463623046874974 +0.67625 0.121490478515625 0.267852783203125 0.5463623046874974 +0.6763750000000001 0.119476318359375 0.263427734375 0.5463623046874974 +0.6765 0.119476318359375 0.263427734375 0.5463623046874974 +0.676625 0.117462158203125 0.25897216796875 0.5463623046874974 +0.67675 0.11541748046875 0.25445556640625 0.5463623046874974 +0.676875 0.11541748046875 0.25445556640625 0.5463623046874974 +0.677 0.113372802734375 0.249969482421875 0.5463623046874974 +0.677125 0.113372802734375 0.249969482421875 0.5463623046874974 +0.67725 0.111297607421875 0.24542236328125 0.5463623046874974 +0.6773750000000001 0.109222412109375 0.2408447265625 0.5463623046874974 +0.6775 0.109222412109375 0.2408447265625 0.5463623046874974 +0.677625 0.107147216796875 0.236236572265625 0.5463623046874974 +0.67775 0.107147216796875 0.236236572265625 0.5463623046874974 +0.677875 0.10504150390625 0.231597900390625 0.5463623046874974 +0.678 0.102935791015625 0.226959228515625 0.5463623046874974 +0.678125 0.102935791015625 0.226959228515625 0.5463623046874974 +0.67825 0.100799560546875 0.2222900390625 0.5463623046874974 +0.6783750000000001 0.100799560546875 0.2222900390625 0.5463623046874974 +0.6785 0.09869384765625 0.21759033203125 0.5463623046874974 +0.678625 0.096527099609375 0.212860107421875 0.5463623046874974 +0.67875 0.096527099609375 0.212860107421875 0.5463623046874974 +0.678875 0.094390869140625 0.208099365234375 0.5463623046874974 +0.679 0.094390869140625 0.208099365234375 0.5463623046874974 +0.679125 0.09222412109375 0.203338623046875 0.5463623046874974 +0.67925 0.090057373046875 0.19854736328125 0.5463623046874974 +0.6793750000000001 0.090057373046875 0.19854736328125 0.5463623046874974 +0.6795 0.087860107421875 0.1937255859375 0.5463623046874974 +0.679625 0.087860107421875 0.1937255859375 0.5463623046874974 +0.67975 0.085662841796875 0.188873291015625 0.5463623046874974 +0.679875 0.083465576171875 0.18402099609375 0.5463623046874974 +0.68 0.083465576171875 0.18402099609375 0.5463623046874974 +0.680125 0.08123779296875 0.17913818359375 0.5463623046874974 +0.68025 0.08123779296875 0.17913818359375 0.5463623046874974 +0.6803750000000001 0.07904052734375 0.17425537109375 0.5463623046874974 +0.6805 0.0767822265625 0.169342041015625 0.5463623046874974 +0.680625 0.0767822265625 0.169342041015625 0.5463623046874974 +0.68075 0.074554443359375 0.164398193359375 0.5463623046874974 +0.680875 0.074554443359375 0.164398193359375 0.5463623046874974 +0.681 0.07232666015625 0.159454345703125 0.5463623046874974 +0.681125 0.070068359375 0.15447998046875 0.5463623046874974 +0.68125 0.070068359375 0.15447998046875 0.5463623046874974 +0.6813750000000001 0.067779541015625 0.14947509765625 0.5463623046874974 +0.6815 0.067779541015625 0.14947509765625 0.5463623046874974 +0.681625 0.065521240234375 0.14447021484375 0.5463623046874974 +0.68175 0.063232421875 0.13946533203125 0.5463623046874974 +0.681875 0.063232421875 0.13946533203125 0.5463623046874974 +0.6820000000000001 0.06097412109375 0.134429931640625 0.5463623046874974 +0.682125 0.06097412109375 0.134429931640625 0.5463623046874974 +0.68225 0.058685302734375 0.129364013671875 0.5463623046874974 +0.6823750000000001 0.056365966796875 0.124298095703125 0.5463623046874974 +0.6825 0.056365966796875 0.124298095703125 0.5463623046874974 +0.682625 0.0540771484375 0.119232177734375 0.5463623046874974 +0.68275 0.0540771484375 0.119232177734375 0.5463623046874974 +0.682875 0.0517578125 0.1141357421875 0.5463623046874974 +0.6830000000000001 0.0494384765625 0.109039306640625 0.5463623046874974 +0.683125 0.0494384765625 0.109039306640625 0.5463623046874974 +0.68325 0.047119140625 0.103912353515625 0.5463623046874974 +0.6833750000000001 0.047119140625 0.103912353515625 0.5463623046874974 +0.6835 0.0447998046875 0.098785400390625 0.5463623046874974 +0.683625 0.04248046875 0.093658447265625 0.5463623046874974 +0.68375 0.04248046875 0.093658447265625 0.5463623046874974 +0.683875 0.040130615234375 0.0885009765625 0.5463623046874974 +0.6840000000000001 0.040130615234375 0.0885009765625 0.5463623046874974 +0.684125 0.037811279296875 0.083343505859375 0.5463623046874974 +0.68425 0.03546142578125 0.07818603515625 0.5463623046874974 +0.6843750000000001 0.03546142578125 0.07818603515625 0.5463623046874974 +0.6845 0.033111572265625 0.072998046875 0.5463623046874974 +0.684625 0.033111572265625 0.072998046875 0.5463623046874974 +0.68475 0.03076171875 0.06781005859375 0.5463623046874974 +0.684875 0.028411865234375 0.0626220703125 0.5463623046874974 +0.6850000000000001 0.028411865234375 0.0626220703125 0.5463623046874974 +0.685125 0.02606201171875 0.05743408203125 0.5463623046874974 +0.68525 0.02606201171875 0.05743408203125 0.5463623046874974 +0.6853750000000001 0.023681640625 0.05224609375 0.5463623046874974 +0.6855 0.021331787109375 0.047027587890625 0.5463623046874974 +0.685625 0.021331787109375 0.047027587890625 0.5463623046874974 +0.68575 0.018951416015625 0.04180908203125 0.5463623046874974 +0.685875 0.018951416015625 0.04180908203125 0.5463623046874974 +0.6860000000000001 0.0166015625 0.036590576171875 0.5463623046874974 +0.686125 0.01422119140625 0.0313720703125 0.5463623046874974 +0.68625 0.01422119140625 0.0313720703125 0.5463623046874974 +0.6863750000000001 0.0118408203125 0.026123046875 0.5463623046874974 +0.6865 0.0118408203125 0.026123046875 0.5463623046874974 +0.686625 0.009490966796875 0.020904541015625 0.5463623046874974 +0.68675 0.007110595703125 0.01568603515625 0.5463623046874974 +0.686875 0.007110595703125 0.01568603515625 0.5463623046874974 +0.6870000000000001 0.004730224609375 0.01043701171875 0.5463623046874974 +0.687125 0.004730224609375 0.01043701171875 0.5463623046874974 +0.68725 0.002349853515625 0.005218505859375 0.5463623046874974 +0.6873750000000001 0.0 0.0 0.5463623046874974 +0.6875 0.0 0.0 0.5463623046874974 +0.687625 -0.002349853515625 -0.005218505859375 0.5463623046874974 +0.68775 -0.002349853515625 -0.005218505859375 0.5463623046874974 +0.687875 -0.004730224609375 -0.01043701171875 0.5463623046874974 +0.6880000000000001 -0.007110595703125 -0.01568603515625 0.5463623046874974 +0.688125 -0.007110595703125 -0.01568603515625 0.5463623046874974 +0.68825 -0.009490966796875 -0.020904541015625 0.5463623046874974 +0.688375 -0.009490966796875 -0.020904541015625 0.5463623046874974 +0.6885 -0.0118408203125 -0.026123046875 0.5463623046874974 +0.688625 -0.01422119140625 -0.0313720703125 0.5463623046874974 +0.68875 -0.01422119140625 -0.0313720703125 0.5463623046874974 +0.688875 -0.0166015625 -0.036590576171875 0.5463623046874974 +0.6890000000000001 -0.0166015625 -0.036590576171875 0.5463623046874974 +0.689125 -0.018951416015625 -0.04180908203125 0.5463623046874974 +0.68925 -0.021331787109375 -0.047027587890625 0.5463623046874974 +0.689375 -0.021331787109375 -0.047027587890625 0.5463623046874974 +0.6895 -0.023681640625 -0.05224609375 0.5463623046874974 +0.689625 -0.023681640625 -0.05224609375 0.5463623046874974 +0.68975 -0.02606201171875 -0.05743408203125 0.5463623046874974 +0.689875 -0.028411865234375 -0.0626220703125 0.5463623046874974 +0.6900000000000001 -0.028411865234375 -0.0626220703125 0.5463623046874974 +0.690125 -0.03076171875 -0.06781005859375 0.5463623046874974 +0.69025 -0.03076171875 -0.06781005859375 0.5463623046874974 +0.690375 -0.033111572265625 -0.072998046875 0.5463623046874974 +0.6905 -0.03546142578125 -0.07818603515625 0.5463623046874974 +0.690625 -0.03546142578125 -0.07818603515625 0.5463623046874974 +0.69075 -0.037811279296875 -0.083343505859375 0.5463623046874974 +0.690875 -0.037811279296875 -0.083343505859375 0.5463623046874974 +0.6910000000000001 -0.040130615234375 -0.0885009765625 0.5463623046874974 +0.691125 -0.04248046875 -0.093658447265625 0.5463623046874974 +0.69125 -0.04248046875 -0.093658447265625 0.5463623046874974 +0.691375 -0.0447998046875 -0.098785400390625 0.5463623046874974 +0.6915 -0.0447998046875 -0.098785400390625 0.5463623046874974 +0.691625 -0.047119140625 -0.103912353515625 0.5463623046874974 +0.69175 -0.0494384765625 -0.109039306640625 0.5463623046874974 +0.691875 -0.0494384765625 -0.109039306640625 0.5463623046874974 +0.6920000000000001 -0.0517578125 -0.1141357421875 0.5463623046874974 +0.692125 -0.0517578125 -0.1141357421875 0.5463623046874974 +0.69225 -0.0540771484375 -0.119232177734375 0.5463623046874974 +0.692375 -0.056365966796875 -0.124298095703125 0.5463623046874974 +0.6925 -0.056365966796875 -0.124298095703125 0.5463623046874974 +0.692625 -0.058685302734375 -0.129364013671875 0.5463623046874974 +0.69275 -0.058685302734375 -0.129364013671875 0.5463623046874974 +0.692875 -0.06097412109375 -0.134429931640625 0.5463623046874974 +0.6930000000000001 -0.063232421875 -0.13946533203125 0.5463623046874974 +0.693125 -0.063232421875 -0.13946533203125 0.5463623046874974 +0.69325 -0.065521240234375 -0.14447021484375 0.5463623046874974 +0.693375 -0.065521240234375 -0.14447021484375 0.5463623046874974 +0.6935 -0.067779541015625 -0.14947509765625 0.5463623046874974 +0.693625 -0.070068359375 -0.15447998046875 0.5463623046874974 +0.69375 -0.070068359375 -0.15447998046875 0.5463623046874974 +0.693875 -0.07232666015625 -0.159454345703125 0.5463623046874974 +0.6940000000000001 -0.07232666015625 -0.159454345703125 0.5463623046874974 +0.694125 -0.074554443359375 -0.164398193359375 0.5463623046874974 +0.69425 -0.0767822265625 -0.169342041015625 0.5463623046874974 +0.694375 -0.0767822265625 -0.169342041015625 0.5463623046874974 +0.6945 -0.07904052734375 -0.17425537109375 0.5463623046874974 +0.694625 -0.07904052734375 -0.17425537109375 0.5463623046874974 +0.69475 -0.08123779296875 -0.17913818359375 0.5463623046874974 +0.694875 -0.083465576171875 -0.18402099609375 0.5463623046874974 +0.6950000000000001 -0.083465576171875 -0.18402099609375 0.5463623046874974 +0.695125 -0.085662841796875 -0.188873291015625 0.5463623046874974 +0.69525 -0.085662841796875 -0.188873291015625 0.5463623046874974 +0.695375 -0.087860107421875 -0.1937255859375 0.5463623046874974 +0.6955 -0.090057373046875 -0.19854736328125 0.5463623046874974 +0.695625 -0.090057373046875 -0.19854736328125 0.5463623046874974 +0.69575 -0.09222412109375 -0.203338623046875 0.5463623046874974 +0.695875 -0.09222412109375 -0.203338623046875 0.5463623046874974 +0.6960000000000001 -0.094390869140625 -0.208099365234375 0.5463623046874974 +0.696125 -0.096527099609375 -0.212860107421875 0.5463623046874974 +0.69625 -0.096527099609375 -0.212860107421875 0.5463623046874974 +0.696375 -0.09869384765625 -0.21759033203125 0.5463623046874974 +0.6965 -0.09869384765625 -0.21759033203125 0.5463623046874974 +0.696625 -0.100799560546875 -0.2222900390625 0.5463623046874974 +0.69675 -0.102935791015625 -0.226959228515625 0.5463623046874974 +0.696875 -0.102935791015625 -0.226959228515625 0.5463623046874974 +0.6970000000000001 -0.10504150390625 -0.231597900390625 0.5463623046874974 +0.697125 -0.10504150390625 -0.231597900390625 0.5463623046874974 +0.69725 -0.107147216796875 -0.236236572265625 0.5463623046874974 +0.697375 -0.109222412109375 -0.2408447265625 0.5463623046874974 +0.6975 -0.109222412109375 -0.2408447265625 0.5463623046874974 +0.6976250000000001 -0.111297607421875 -0.24542236328125 0.5463623046874974 +0.69775 -0.111297607421875 -0.24542236328125 0.5463623046874974 +0.697875 -0.113372802734375 -0.249969482421875 0.5463623046874974 +0.6980000000000001 -0.11541748046875 -0.25445556640625 0.5463623046874974 +0.698125 -0.11541748046875 -0.25445556640625 0.5463623046874974 +0.69825 -0.117462158203125 -0.25897216796875 0.5463623046874974 +0.698375 -0.117462158203125 -0.25897216796875 0.5463623046874974 +0.6985 -0.119476318359375 -0.263427734375 0.5463623046874974 +0.6986250000000001 -0.121490478515625 -0.267852783203125 0.5463623046874974 +0.69875 -0.121490478515625 -0.267852783203125 0.5463623046874974 +0.698875 -0.123504638671875 -0.27227783203125 0.5463623046874974 +0.6990000000000001 -0.123504638671875 -0.27227783203125 0.5463623046874974 +0.699125 -0.125457763671875 -0.276641845703125 0.5463623046874974 +0.69925 -0.12744140625 -0.280975341796875 0.5463623046874974 +0.699375 -0.12744140625 -0.280975341796875 0.5463623046874974 +0.6995 -0.12939453125 -0.285308837890625 0.5463623046874974 +0.6996250000000001 -0.12939453125 -0.285308837890625 0.5463623046874974 +0.69975 -0.13134765625 -0.289581298828125 0.5463623046874974 +0.699875 -0.133270263671875 -0.2938232421875 0.5463623046874974 +0.7000000000000001 -0.133270263671875 -0.2938232421875 0.5463623046874974 +0.700125 -0.13519287109375 -0.298065185546875 0.5463623046874974 +0.70025 -0.13519287109375 -0.298065185546875 0.5463623046874974 +0.700375 -0.1370849609375 -0.30224609375 0.5463623046874974 +0.7005 -0.13897705078125 -0.306396484375 0.5463623046874974 +0.7006250000000001 -0.13897705078125 -0.306396484375 0.5463623046874974 +0.70075 -0.140838623046875 -0.310516357421875 0.5463623046874974 +0.700875 -0.140838623046875 -0.310516357421875 0.5463623046874974 +0.7010000000000001 -0.1427001953125 -0.314605712890625 0.5463623046874974 +0.701125 -0.14453125 -0.31866455078125 0.5463623046874974 +0.70125 -0.14453125 -0.31866455078125 0.5463623046874974 +0.701375 -0.1463623046875 -0.322662353515625 0.5463623046874974 +0.7015 -0.1463623046875 -0.322662353515625 0.5463623046874974 +0.7016250000000001 -0.148162841796875 -0.32666015625 0.5463623046874974 +0.70175 -0.14996337890625 -0.330596923828125 0.5463623046874974 +0.701875 -0.14996337890625 -0.330596923828125 0.5463623046874974 +0.7020000000000001 -0.1517333984375 -0.334503173828125 0.5463623046874974 +0.702125 -0.1517333984375 -0.334503173828125 0.5463623046874974 +0.70225 -0.153472900390625 -0.33837890625 0.5463623046874974 +0.702375 -0.15521240234375 -0.34222412109375 0.5463623046874974 +0.7025 -0.15521240234375 -0.34222412109375 0.5463623046874974 +0.7026250000000001 -0.156951904296875 -0.34600830078125 0.5463623046874974 +0.70275 -0.156951904296875 -0.34600830078125 0.5463623046874974 +0.702875 -0.15863037109375 -0.349761962890625 0.5463623046874974 +0.7030000000000001 -0.16033935546875 -0.353485107421875 0.5463623046874974 +0.703125 -0.16033935546875 -0.353485107421875 0.5463623046874974 +0.70325 -0.162017822265625 -0.357177734375 0.5463623046874974 +0.703375 -0.162017822265625 -0.357177734375 0.5463623046874974 +0.7035 -0.163665771484375 -0.360809326171875 0.5463623046874974 +0.7036250000000001 -0.165283203125 -0.36444091796875 0.5463623046874974 +0.70375 -0.165283203125 -0.36444091796875 0.5463623046874974 +0.703875 -0.166900634765625 -0.36798095703125 0.5463623046874974 +0.704 -0.3035888671875 -0.36798095703125 0.17499999999999718 +0.704125 -0.306488037109375 -0.37152099609375 0.17499999999999718 +0.70425 -0.309356689453125 -0.375 0.17499999999999718 +0.704375 -0.309356689453125 -0.375 0.17499999999999718 +0.7045 -0.31219482421875 -0.378448486328125 0.17499999999999718 +0.7046250000000001 -0.31219482421875 -0.378448486328125 0.17499999999999718 +0.70475 -0.31500244140625 -0.3818359375 0.17499999999999718 +0.704875 -0.317779541015625 -0.38519287109375 0.17499999999999718 +0.705 -0.317779541015625 -0.38519287109375 0.17499999999999718 +0.705125 -0.32049560546875 -0.388519287109375 0.17499999999999718 +0.70525 -0.32049560546875 -0.388519287109375 0.17499999999999718 +0.705375 -0.323211669921875 -0.39178466796875 0.17499999999999718 +0.7055 -0.325897216796875 -0.39501953125 0.17499999999999718 +0.7056250000000001 -0.325897216796875 -0.39501953125 0.17499999999999718 +0.70575 -0.3284912109375 -0.398193359375 0.17499999999999718 +0.705875 -0.3284912109375 -0.398193359375 0.17499999999999718 +0.706 -0.331085205078125 -0.401336669921875 0.17499999999999718 +0.706125 -0.333648681640625 -0.404449462890625 0.17499999999999718 +0.70625 -0.333648681640625 -0.404449462890625 0.17499999999999718 +0.706375 -0.336181640625 -0.407501220703125 0.17499999999999718 +0.7065 -0.336181640625 -0.407501220703125 0.17499999999999718 +0.7066250000000001 -0.338653564453125 -0.4105224609375 0.17499999999999718 +0.70675 -0.341094970703125 -0.413482666015625 0.17499999999999718 +0.706875 -0.341094970703125 -0.413482666015625 0.17499999999999718 +0.707 -0.343505859375 -0.416412353515625 0.17499999999999718 +0.707125 -0.343505859375 -0.416412353515625 0.17499999999999718 +0.70725 -0.34588623046875 -0.419281005859375 0.17499999999999718 +0.707375 -0.348236083984375 -0.422119140625 0.17499999999999718 +0.7075 -0.348236083984375 -0.422119140625 0.17499999999999718 +0.7076250000000001 -0.35052490234375 -0.424896240234375 0.17499999999999718 +0.70775 -0.35052490234375 -0.424896240234375 0.17499999999999718 +0.707875 -0.352783203125 -0.4276123046875 0.17499999999999718 +0.708 -0.35498046875 -0.4302978515625 0.17499999999999718 +0.708125 -0.35498046875 -0.4302978515625 0.17499999999999718 +0.70825 -0.357177734375 -0.432952880859375 0.17499999999999718 +0.708375 -0.357177734375 -0.432952880859375 0.17499999999999718 +0.7085 -0.35931396484375 -0.435546875 0.17499999999999718 +0.7086250000000001 -0.36138916015625 -0.438079833984375 0.17499999999999718 +0.70875 -0.36138916015625 -0.438079833984375 0.17499999999999718 +0.708875 -0.36346435546875 -0.440582275390625 0.17499999999999718 +0.709 -0.36346435546875 -0.440582275390625 0.17499999999999718 +0.709125 -0.365509033203125 -0.44305419921875 0.17499999999999718 +0.70925 -0.367462158203125 -0.4454345703125 0.17499999999999718 +0.709375 -0.367462158203125 -0.4454345703125 0.17499999999999718 +0.7095 -0.369415283203125 -0.447784423828125 0.17499999999999718 +0.7096250000000001 -0.369415283203125 -0.447784423828125 0.17499999999999718 +0.70975 -0.371307373046875 -0.450103759765625 0.17499999999999718 +0.709875 -0.3731689453125 -0.452362060546875 0.17499999999999718 +0.71 -0.3731689453125 -0.452362060546875 0.17499999999999718 +0.710125 -0.375 -0.454559326171875 0.17499999999999718 +0.71025 -0.375 -0.454559326171875 0.17499999999999718 +0.710375 -0.37677001953125 -0.45672607421875 0.17499999999999718 +0.7105 -0.378509521484375 -0.458831787109375 0.17499999999999718 +0.7106250000000001 -0.378509521484375 -0.458831787109375 0.17499999999999718 +0.71075 -0.38018798828125 -0.46087646484375 0.17499999999999718 +0.710875 -0.38018798828125 -0.46087646484375 0.17499999999999718 +0.711 -0.381866455078125 -0.462890625 0.17499999999999718 +0.711125 -0.383453369140625 -0.464813232421875 0.17499999999999718 +0.71125 -0.383453369140625 -0.464813232421875 0.17499999999999718 +0.711375 -0.385040283203125 -0.46673583984375 0.17499999999999718 +0.7115 -0.385040283203125 -0.46673583984375 0.17499999999999718 +0.7116250000000001 -0.386566162109375 -0.46856689453125 0.17499999999999718 +0.71175 -0.388031005859375 -0.470367431640625 0.17499999999999718 +0.711875 -0.388031005859375 -0.470367431640625 0.17499999999999718 +0.712 -0.389495849609375 -0.472137451171875 0.17499999999999718 +0.712125 -0.389495849609375 -0.472137451171875 0.17499999999999718 +0.71225 -0.390869140625 -0.47381591796875 0.17499999999999718 +0.712375 -0.392242431640625 -0.4754638671875 0.17499999999999718 +0.7125 -0.392242431640625 -0.4754638671875 0.17499999999999718 +0.7126250000000001 -0.3935546875 -0.47705078125 0.17499999999999718 +0.71275 -0.3935546875 -0.47705078125 0.17499999999999718 +0.712875 -0.39483642578125 -0.478607177734375 0.17499999999999718 +0.713 -0.39605712890625 -0.480072021484375 0.17499999999999718 +0.713125 -0.39605712890625 -0.480072021484375 0.17499999999999718 +0.7132500000000001 -0.397216796875 -0.48150634765625 0.17499999999999718 +0.713375 -0.397216796875 -0.48150634765625 0.17499999999999718 +0.7135 -0.39837646484375 -0.48291015625 0.17499999999999718 +0.7136250000000001 -0.39947509765625 -0.484222412109375 0.17499999999999718 +0.71375 -0.39947509765625 -0.484222412109375 0.17499999999999718 +0.713875 -0.4005126953125 -0.485504150390625 0.17499999999999718 +0.714 -0.4005126953125 -0.485504150390625 0.17499999999999718 +0.714125 -0.401519775390625 -0.486724853515625 0.17499999999999718 +0.7142500000000001 -0.402496337890625 -0.487884521484375 0.17499999999999718 +0.714375 -0.402496337890625 -0.487884521484375 0.17499999999999718 +0.7145 -0.403411865234375 -0.489013671875 0.17499999999999718 +0.7146250000000001 -0.403411865234375 -0.489013671875 0.17499999999999718 +0.71475 -0.404296875 -0.490081787109375 0.17499999999999718 +0.714875 -0.405120849609375 -0.4910888671875 0.17499999999999718 +0.715 -0.405120849609375 -0.4910888671875 0.17499999999999718 +0.715125 -0.405914306640625 -0.492034912109375 0.17499999999999718 +0.7152500000000001 -0.405914306640625 -0.492034912109375 0.17499999999999718 +0.715375 -0.406646728515625 -0.492950439453125 0.17499999999999718 +0.7155 -0.4073486328125 -0.4937744140625 0.17499999999999718 +0.7156250000000001 -0.4073486328125 -0.4937744140625 0.17499999999999718 +0.71575 -0.407989501953125 -0.49456787109375 0.17499999999999718 +0.715875 -0.407989501953125 -0.49456787109375 0.17499999999999718 +0.716 -0.408599853515625 -0.49530029296875 0.17499999999999718 +0.716125 -0.4091796875 -0.496002197265625 0.17499999999999718 +0.7162500000000001 -0.4091796875 -0.496002197265625 0.17499999999999718 +0.716375 -0.409698486328125 -0.496612548828125 0.17499999999999718 +0.7165 -0.409698486328125 -0.496612548828125 0.17499999999999718 +0.7166250000000001 -0.41015625 -0.4971923828125 0.17499999999999718 +0.71675 -0.41058349609375 -0.497711181640625 0.17499999999999718 +0.716875 -0.41058349609375 -0.497711181640625 0.17499999999999718 +0.717 -0.410980224609375 -0.498199462890625 0.17499999999999718 +0.717125 -0.410980224609375 -0.498199462890625 0.17499999999999718 +0.7172500000000001 -0.41131591796875 -0.49859619140625 0.17499999999999718 +0.717375 -0.41162109375 -0.49896240234375 0.17499999999999718 +0.7175 -0.41162109375 -0.49896240234375 0.17499999999999718 +0.7176250000000001 -0.411865234375 -0.499267578125 0.17499999999999718 +0.71775 -0.411865234375 -0.499267578125 0.17499999999999718 +0.717875 -0.412078857421875 -0.49951171875 0.17499999999999718 +0.718 -0.4122314453125 -0.49969482421875 0.17499999999999718 +0.718125 -0.4122314453125 -0.49969482421875 0.17499999999999718 +0.7182500000000001 -0.412322998046875 -0.49981689453125 0.17499999999999718 +0.718375 -0.412322998046875 -0.49981689453125 0.17499999999999718 +0.7185 -0.41241455078125 -0.499908447265625 0.17499999999999718 +0.7186250000000001 -0.412445068359375 -0.49993896484375 0.17499999999999718 +0.71875 -0.412445068359375 -0.49993896484375 0.17499999999999718 +0.718875 -0.41241455078125 -0.499908447265625 0.17499999999999718 +0.719 -0.41241455078125 -0.499908447265625 0.17499999999999718 +0.719125 -0.412322998046875 -0.49981689453125 0.17499999999999718 +0.7192500000000001 -0.4122314453125 -0.49969482421875 0.17499999999999718 +0.719375 -0.4122314453125 -0.49969482421875 0.17499999999999718 +0.7195 -0.412078857421875 -0.49951171875 0.17499999999999718 +0.7196250000000001 -0.412078857421875 -0.49951171875 0.17499999999999718 +0.71975 -0.411865234375 -0.499267578125 0.17499999999999718 +0.719875 -0.41162109375 -0.49896240234375 0.17499999999999718 +0.72 -0.41162109375 -0.49896240234375 0.17499999999999718 +0.720125 -0.41131591796875 -0.49859619140625 0.17499999999999718 +0.7202500000000001 -0.41131591796875 -0.49859619140625 0.17499999999999718 +0.720375 -0.410980224609375 -0.498199462890625 0.17499999999999718 +0.7205 -0.41058349609375 -0.497711181640625 0.17499999999999718 +0.720625 -0.41058349609375 -0.497711181640625 0.17499999999999718 +0.72075 -0.41015625 -0.4971923828125 0.17499999999999718 +0.720875 -0.41015625 -0.4971923828125 0.17499999999999718 +0.721 -0.409698486328125 -0.496612548828125 0.17499999999999718 +0.721125 -0.4091796875 -0.496002197265625 0.17499999999999718 +0.7212500000000001 -0.4091796875 -0.496002197265625 0.17499999999999718 +0.721375 -0.408599853515625 -0.49530029296875 0.17499999999999718 +0.7215 -0.408599853515625 -0.49530029296875 0.17499999999999718 +0.721625 -0.407989501953125 -0.49456787109375 0.17499999999999718 +0.72175 -0.4073486328125 -0.4937744140625 0.17499999999999718 +0.721875 -0.4073486328125 -0.4937744140625 0.17499999999999718 +0.722 -0.406646728515625 -0.492950439453125 0.17499999999999718 +0.722125 -0.406646728515625 -0.492950439453125 0.17499999999999718 +0.7222500000000001 -0.405914306640625 -0.492034912109375 0.17499999999999718 +0.722375 -0.405120849609375 -0.4910888671875 0.17499999999999718 +0.7225 -0.405120849609375 -0.4910888671875 0.17499999999999718 +0.722625 -0.404296875 -0.490081787109375 0.17499999999999718 +0.72275 -0.404296875 -0.490081787109375 0.17499999999999718 +0.722875 -0.403411865234375 -0.489013671875 0.17499999999999718 +0.723 -0.402496337890625 -0.487884521484375 0.17499999999999718 +0.723125 -0.402496337890625 -0.487884521484375 0.17499999999999718 +0.7232500000000001 -0.401519775390625 -0.486724853515625 0.17499999999999718 +0.723375 -0.401519775390625 -0.486724853515625 0.17499999999999718 +0.7235 -0.4005126953125 -0.485504150390625 0.17499999999999718 +0.723625 -0.39947509765625 -0.484222412109375 0.17499999999999718 +0.72375 -0.39947509765625 -0.484222412109375 0.17499999999999718 +0.723875 -0.39837646484375 -0.48291015625 0.17499999999999718 +0.724 -0.39837646484375 -0.48291015625 0.17499999999999718 +0.724125 -0.397216796875 -0.48150634765625 0.17499999999999718 +0.7242500000000001 -0.39605712890625 -0.480072021484375 0.17499999999999718 +0.724375 -0.39605712890625 -0.480072021484375 0.17499999999999718 +0.7245 -0.39483642578125 -0.478607177734375 0.17499999999999718 +0.724625 -0.39483642578125 -0.478607177734375 0.17499999999999718 +0.72475 -0.3935546875 -0.47705078125 0.17499999999999718 +0.724875 -0.392242431640625 -0.4754638671875 0.17499999999999718 +0.725 -0.392242431640625 -0.4754638671875 0.17499999999999718 +0.725125 -0.390869140625 -0.47381591796875 0.17499999999999718 +0.7252500000000001 -0.390869140625 -0.47381591796875 0.17499999999999718 +0.725375 -0.389495849609375 -0.472137451171875 0.17499999999999718 +0.7255 -0.388031005859375 -0.470367431640625 0.17499999999999718 +0.725625 -0.388031005859375 -0.470367431640625 0.17499999999999718 +0.72575 -0.386566162109375 -0.46856689453125 0.17499999999999718 +0.725875 -0.386566162109375 -0.46856689453125 0.17499999999999718 +0.726 -0.385040283203125 -0.46673583984375 0.17499999999999718 +0.726125 -0.383453369140625 -0.464813232421875 0.17499999999999718 +0.7262500000000001 -0.383453369140625 -0.464813232421875 0.17499999999999718 +0.726375 -0.381866455078125 -0.462890625 0.17499999999999718 +0.7265 -0.381866455078125 -0.462890625 0.17499999999999718 +0.726625 -0.38018798828125 -0.46087646484375 0.17499999999999718 +0.72675 -0.378509521484375 -0.458831787109375 0.17499999999999718 +0.726875 -0.378509521484375 -0.458831787109375 0.17499999999999718 +0.727 -0.37677001953125 -0.45672607421875 0.17499999999999718 +0.727125 -0.37677001953125 -0.45672607421875 0.17499999999999718 +0.7272500000000001 -0.375 -0.454559326171875 0.17499999999999718 +0.727375 -0.3731689453125 -0.452362060546875 0.17499999999999718 +0.7275 -0.3731689453125 -0.452362060546875 0.17499999999999718 +0.727625 -0.371307373046875 -0.450103759765625 0.17499999999999718 +0.72775 -0.371307373046875 -0.450103759765625 0.17499999999999718 +0.727875 -0.369415283203125 -0.447784423828125 0.17499999999999718 +0.728 -0.367462158203125 -0.4454345703125 0.17499999999999718 +0.728125 -0.367462158203125 -0.4454345703125 0.17499999999999718 +0.7282500000000001 -0.365509033203125 -0.44305419921875 0.17499999999999718 +0.728375 -0.365509033203125 -0.44305419921875 0.17499999999999718 +0.7285 -0.36346435546875 -0.440582275390625 0.17499999999999718 +0.728625 -0.36138916015625 -0.438079833984375 0.17499999999999718 +0.72875 -0.36138916015625 -0.438079833984375 0.17499999999999718 +0.7288750000000001 -0.35931396484375 -0.435546875 0.17499999999999718 +0.729 -0.35931396484375 -0.435546875 0.17499999999999718 +0.729125 -0.357177734375 -0.432952880859375 0.17499999999999718 +0.7292500000000001 -0.35498046875 -0.4302978515625 0.17499999999999718 +0.729375 -0.35498046875 -0.4302978515625 0.17499999999999718 +0.7295 -0.352783203125 -0.4276123046875 0.17499999999999718 +0.729625 -0.352783203125 -0.4276123046875 0.17499999999999718 +0.72975 -0.35052490234375 -0.424896240234375 0.17499999999999718 +0.7298750000000001 -0.348236083984375 -0.422119140625 0.17499999999999718 +0.73 -0.348236083984375 -0.422119140625 0.17499999999999718 +0.730125 -0.34588623046875 -0.419281005859375 0.17499999999999718 +0.7302500000000001 -0.34588623046875 -0.419281005859375 0.17499999999999718 +0.730375 -0.343505859375 -0.416412353515625 0.17499999999999718 +0.7305 -0.341094970703125 -0.413482666015625 0.17499999999999718 +0.730625 -0.341094970703125 -0.413482666015625 0.17499999999999718 +0.73075 -0.338653564453125 -0.4105224609375 0.17499999999999718 +0.7308750000000001 -0.338653564453125 -0.4105224609375 0.17499999999999718 +0.731 -0.336181640625 -0.407501220703125 0.17499999999999718 +0.731125 -0.333648681640625 -0.404449462890625 0.17499999999999718 +0.7312500000000001 -0.333648681640625 -0.404449462890625 0.17499999999999718 +0.731375 -0.331085205078125 -0.401336669921875 0.17499999999999718 +0.7315 -0.331085205078125 -0.401336669921875 0.17499999999999718 +0.731625 -0.3284912109375 -0.398193359375 0.17499999999999718 +0.73175 -0.325897216796875 -0.39501953125 0.17499999999999718 +0.7318750000000001 -0.325897216796875 -0.39501953125 0.17499999999999718 +0.732 -0.323211669921875 -0.39178466796875 0.17499999999999718 +0.732125 -0.323211669921875 -0.39178466796875 0.17499999999999718 +0.7322500000000001 -0.32049560546875 -0.388519287109375 0.17499999999999718 +0.732375 -0.317779541015625 -0.38519287109375 0.17499999999999718 +0.7325 -0.317779541015625 -0.38519287109375 0.17499999999999718 +0.732625 -0.31500244140625 -0.3818359375 0.17499999999999718 +0.73275 -0.31500244140625 -0.3818359375 0.17499999999999718 +0.7328750000000001 -0.31219482421875 -0.378448486328125 0.17499999999999718 +0.733 -0.309356689453125 -0.375 0.17499999999999718 +0.733125 -0.309356689453125 -0.375 0.17499999999999718 +0.7332500000000001 -0.306488037109375 -0.37152099609375 0.17499999999999718 +0.733375 -0.306488037109375 -0.37152099609375 0.17499999999999718 +0.7335 -0.3035888671875 -0.36798095703125 0.17499999999999718 +0.733625 -0.3006591796875 -0.36444091796875 0.17499999999999718 +0.73375 -0.3006591796875 -0.36444091796875 0.17499999999999718 +0.7338750000000001 -0.29766845703125 -0.360809326171875 0.17499999999999718 +0.734 -0.29766845703125 -0.360809326171875 0.17499999999999718 +0.734125 -0.294677734375 -0.357177734375 0.17499999999999718 +0.7342500000000001 -0.2916259765625 -0.353485107421875 0.17499999999999718 +0.734375 -0.2916259765625 -0.353485107421875 0.17499999999999718 +0.7345 -0.288543701171875 -0.349761962890625 0.17499999999999718 +0.734625 -0.288543701171875 -0.349761962890625 0.17499999999999718 +0.73475 -0.28546142578125 -0.34600830078125 0.17499999999999718 +0.7348750000000001 -0.282318115234375 -0.34222412109375 0.17499999999999718 +0.735 -0.282318115234375 -0.34222412109375 0.17499999999999718 +0.735125 -0.279144287109375 -0.33837890625 0.17499999999999718 +0.7352500000000001 -0.279144287109375 -0.33837890625 0.17499999999999718 +0.735375 -0.275970458984375 -0.334503173828125 0.17499999999999718 +0.7355 -0.272735595703125 -0.330596923828125 0.17499999999999718 +0.735625 -0.272735595703125 -0.330596923828125 0.17499999999999718 +0.73575 -0.26947021484375 -0.32666015625 0.17499999999999718 +0.7358750000000001 -0.26947021484375 -0.32666015625 0.17499999999999718 +0.736 -0.322662353515625 -0.25030517578125 -0.224243164062503132 +0.736125 -0.31866455078125 -0.2471923828125 -0.224243164062503132 +0.73625 -0.31866455078125 -0.2471923828125 -0.224243164062503132 +0.736375 -0.314605712890625 -0.244049072265625 -0.224243164062503132 +0.7365 -0.314605712890625 -0.244049072265625 -0.224243164062503132 +0.736625 -0.310516357421875 -0.240875244140625 -0.224243164062503132 +0.73675 -0.306396484375 -0.2376708984375 -0.224243164062503132 +0.7368750000000001 -0.306396484375 -0.2376708984375 -0.224243164062503132 +0.737 -0.30224609375 -0.23443603515625 -0.224243164062503132 +0.737125 -0.30224609375 -0.23443603515625 -0.224243164062503132 +0.73725 -0.298065185546875 -0.231201171875 -0.224243164062503132 +0.737375 -0.2938232421875 -0.227935791015625 -0.224243164062503132 +0.7375 -0.2938232421875 -0.227935791015625 -0.224243164062503132 +0.737625 -0.289581298828125 -0.224639892578125 -0.224243164062503132 +0.73775 -0.289581298828125 -0.224639892578125 -0.224243164062503132 +0.7378750000000001 -0.285308837890625 -0.2213134765625 -0.224243164062503132 +0.738 -0.280975341796875 -0.21795654296875 -0.224243164062503132 +0.738125 -0.280975341796875 -0.21795654296875 -0.224243164062503132 +0.73825 -0.276641845703125 -0.214599609375 -0.224243164062503132 +0.738375 -0.276641845703125 -0.214599609375 -0.224243164062503132 +0.7385 -0.27227783203125 -0.211212158203125 -0.224243164062503132 +0.738625 -0.267852783203125 -0.207794189453125 -0.224243164062503132 +0.73875 -0.267852783203125 -0.207794189453125 -0.224243164062503132 +0.7388750000000001 -0.263427734375 -0.204345703125 -0.224243164062503132 +0.739 -0.263427734375 -0.204345703125 -0.224243164062503132 +0.739125 -0.25897216796875 -0.200897216796875 -0.224243164062503132 +0.73925 -0.25445556640625 -0.1973876953125 -0.224243164062503132 +0.739375 -0.25445556640625 -0.1973876953125 -0.224243164062503132 +0.7395 -0.249969482421875 -0.193878173828125 -0.224243164062503132 +0.739625 -0.249969482421875 -0.193878173828125 -0.224243164062503132 +0.73975 -0.24542236328125 -0.19036865234375 -0.224243164062503132 +0.7398750000000001 -0.2408447265625 -0.186798095703125 -0.224243164062503132 +0.74 -0.2408447265625 -0.186798095703125 -0.224243164062503132 +0.740125 -0.236236572265625 -0.183258056640625 -0.224243164062503132 +0.74025 -0.236236572265625 -0.183258056640625 -0.224243164062503132 +0.740375 -0.231597900390625 -0.179656982421875 -0.224243164062503132 +0.7405 -0.226959228515625 -0.176055908203125 -0.224243164062503132 +0.740625 -0.226959228515625 -0.176055908203125 -0.224243164062503132 +0.74075 -0.2222900390625 -0.17242431640625 -0.224243164062503132 +0.7408750000000001 -0.2222900390625 -0.17242431640625 -0.224243164062503132 +0.741 -0.21759033203125 -0.16876220703125 -0.224243164062503132 +0.741125 -0.212860107421875 -0.16510009765625 -0.224243164062503132 +0.74125 -0.212860107421875 -0.16510009765625 -0.224243164062503132 +0.741375 -0.208099365234375 -0.16143798828125 -0.224243164062503132 +0.7415 -0.208099365234375 -0.16143798828125 -0.224243164062503132 +0.741625 -0.203338623046875 -0.15771484375 -0.224243164062503132 +0.74175 -0.19854736328125 -0.15399169921875 -0.224243164062503132 +0.7418750000000001 -0.19854736328125 -0.15399169921875 -0.224243164062503132 +0.742 -0.1937255859375 -0.1502685546875 -0.224243164062503132 +0.742125 -0.1937255859375 -0.1502685546875 -0.224243164062503132 +0.74225 -0.188873291015625 -0.146514892578125 -0.224243164062503132 +0.742375 -0.18402099609375 -0.14276123046875 -0.224243164062503132 +0.7425 -0.18402099609375 -0.14276123046875 -0.224243164062503132 +0.742625 -0.17913818359375 -0.138946533203125 -0.224243164062503132 +0.74275 -0.17913818359375 -0.138946533203125 -0.224243164062503132 +0.7428750000000001 -0.17425537109375 -0.135162353515625 -0.224243164062503132 +0.743 -0.169342041015625 -0.13134765625 -0.224243164062503132 +0.743125 -0.169342041015625 -0.13134765625 -0.224243164062503132 +0.74325 -0.164398193359375 -0.12750244140625 -0.224243164062503132 +0.743375 -0.164398193359375 -0.12750244140625 -0.224243164062503132 +0.7435 -0.159454345703125 -0.123687744140625 -0.224243164062503132 +0.743625 -0.15447998046875 -0.11981201171875 -0.224243164062503132 +0.74375 -0.15447998046875 -0.11981201171875 -0.224243164062503132 +0.7438750000000001 -0.14947509765625 -0.115936279296875 -0.224243164062503132 +0.744 -0.14947509765625 -0.115936279296875 -0.224243164062503132 +0.744125 -0.14447021484375 -0.112060546875 -0.224243164062503132 +0.74425 -0.13946533203125 -0.108184814453125 -0.224243164062503132 +0.744375 -0.13946533203125 -0.108184814453125 -0.224243164062503132 +0.7445000000000001 -0.134429931640625 -0.104278564453125 -0.224243164062503132 +0.744625 -0.134429931640625 -0.104278564453125 -0.224243164062503132 +0.74475 -0.129364013671875 -0.100341796875 -0.224243164062503132 +0.7448750000000001 -0.124298095703125 -0.096435546875 -0.224243164062503132 +0.745 -0.124298095703125 -0.096435546875 -0.224243164062503132 +0.745125 -0.119232177734375 -0.092498779296875 -0.224243164062503132 +0.74525 -0.119232177734375 -0.092498779296875 -0.224243164062503132 +0.745375 -0.1141357421875 -0.088531494140625 -0.224243164062503132 +0.7455000000000001 -0.109039306640625 -0.084564208984375 -0.224243164062503132 +0.745625 -0.109039306640625 -0.084564208984375 -0.224243164062503132 +0.74575 -0.103912353515625 -0.080596923828125 -0.224243164062503132 +0.7458750000000001 -0.103912353515625 -0.080596923828125 -0.224243164062503132 +0.746 -0.098785400390625 -0.076629638671875 -0.224243164062503132 +0.746125 -0.093658447265625 -0.0726318359375 -0.224243164062503132 +0.74625 -0.093658447265625 -0.0726318359375 -0.224243164062503132 +0.746375 -0.0885009765625 -0.06866455078125 -0.224243164062503132 +0.7465000000000001 -0.0885009765625 -0.06866455078125 -0.224243164062503132 +0.746625 -0.083343505859375 -0.064666748046875 -0.224243164062503132 +0.74675 -0.07818603515625 -0.060638427734375 -0.224243164062503132 +0.7468750000000001 -0.07818603515625 -0.060638427734375 -0.224243164062503132 +0.747 -0.072998046875 -0.056640625 -0.224243164062503132 +0.747125 -0.072998046875 -0.056640625 -0.224243164062503132 +0.74725 -0.06781005859375 -0.0526123046875 -0.224243164062503132 +0.747375 -0.0626220703125 -0.048583984375 -0.224243164062503132 +0.7475000000000001 -0.0626220703125 -0.048583984375 -0.224243164062503132 +0.747625 -0.05743408203125 -0.0445556640625 -0.224243164062503132 +0.74775 -0.05743408203125 -0.0445556640625 -0.224243164062503132 +0.7478750000000001 -0.05224609375 -0.04052734375 -0.224243164062503132 +0.748 -0.047027587890625 -0.036468505859375 -0.224243164062503132 +0.748125 -0.047027587890625 -0.036468505859375 -0.224243164062503132 +0.74825 -0.04180908203125 -0.032440185546875 -0.224243164062503132 +0.748375 -0.04180908203125 -0.032440185546875 -0.224243164062503132 +0.7485000000000001 -0.036590576171875 -0.02838134765625 -0.224243164062503132 +0.748625 -0.0313720703125 -0.024322509765625 -0.224243164062503132 +0.74875 -0.0313720703125 -0.024322509765625 -0.224243164062503132 +0.7488750000000001 -0.026123046875 -0.020263671875 -0.224243164062503132 +0.749 -0.026123046875 -0.020263671875 -0.224243164062503132 +0.749125 -0.020904541015625 -0.0162353515625 -0.224243164062503132 +0.74925 -0.01568603515625 -0.012176513671875 -0.224243164062503132 +0.749375 -0.01568603515625 -0.012176513671875 -0.224243164062503132 +0.7495000000000001 -0.01043701171875 -0.00811767578125 -0.224243164062503132 +0.749625 -0.01043701171875 -0.00811767578125 -0.224243164062503132 +0.74975 -0.005218505859375 -0.004058837890625 -0.224243164062503132 +0.7498750000000001 0.0 0.0 -0.224243164062503132 +0.75 0.0 0.0 -0.224243164062503132 +0.750125 0.005218505859375 0.004058837890625 -0.224243164062503132 +0.75025 0.005218505859375 0.004058837890625 -0.224243164062503132 +0.750375 0.01043701171875 0.00811767578125 -0.224243164062503132 +0.7505000000000001 0.01568603515625 0.012176513671875 -0.224243164062503132 +0.750625 0.01568603515625 0.012176513671875 -0.224243164062503132 +0.75075 0.020904541015625 0.0162353515625 -0.224243164062503132 +0.7508750000000001 0.020904541015625 0.0162353515625 -0.224243164062503132 +0.751 0.026123046875 0.020263671875 -0.224243164062503132 +0.751125 0.0313720703125 0.024322509765625 -0.224243164062503132 +0.75125 0.0313720703125 0.024322509765625 -0.224243164062503132 +0.751375 0.036590576171875 0.02838134765625 -0.224243164062503132 +0.7515000000000001 0.036590576171875 0.02838134765625 -0.224243164062503132 +0.751625 0.04180908203125 0.032440185546875 -0.224243164062503132 +0.75175 0.047027587890625 0.036468505859375 -0.224243164062503132 +0.7518750000000001 0.047027587890625 0.036468505859375 -0.224243164062503132 +0.752 0.05224609375 0.04052734375 -0.224243164062503132 +0.752125 0.05224609375 0.04052734375 -0.224243164062503132 +0.75225 0.05743408203125 0.0445556640625 -0.224243164062503132 +0.752375 0.0626220703125 0.048583984375 -0.224243164062503132 +0.7525000000000001 0.0626220703125 0.048583984375 -0.224243164062503132 +0.752625 0.06781005859375 0.0526123046875 -0.224243164062503132 +0.75275 0.06781005859375 0.0526123046875 -0.224243164062503132 +0.752875 0.072998046875 0.056640625 -0.224243164062503132 +0.753 0.07818603515625 0.060638427734375 -0.224243164062503132 +0.753125 0.07818603515625 0.060638427734375 -0.224243164062503132 +0.75325 0.083343505859375 0.064666748046875 -0.224243164062503132 +0.753375 0.083343505859375 0.064666748046875 -0.224243164062503132 +0.7535000000000001 0.0885009765625 0.06866455078125 -0.224243164062503132 +0.753625 0.093658447265625 0.0726318359375 -0.224243164062503132 +0.75375 0.093658447265625 0.0726318359375 -0.224243164062503132 +0.753875 0.098785400390625 0.076629638671875 -0.224243164062503132 +0.754 0.098785400390625 0.076629638671875 -0.224243164062503132 +0.754125 0.103912353515625 0.080596923828125 -0.224243164062503132 +0.75425 0.109039306640625 0.084564208984375 -0.224243164062503132 +0.754375 0.109039306640625 0.084564208984375 -0.224243164062503132 +0.7545000000000001 0.1141357421875 0.088531494140625 -0.224243164062503132 +0.754625 0.1141357421875 0.088531494140625 -0.224243164062503132 +0.75475 0.119232177734375 0.092498779296875 -0.224243164062503132 +0.754875 0.124298095703125 0.096435546875 -0.224243164062503132 +0.755 0.124298095703125 0.096435546875 -0.224243164062503132 +0.755125 0.129364013671875 0.100341796875 -0.224243164062503132 +0.75525 0.129364013671875 0.100341796875 -0.224243164062503132 +0.755375 0.134429931640625 0.104278564453125 -0.224243164062503132 +0.7555000000000001 0.13946533203125 0.108184814453125 -0.224243164062503132 +0.755625 0.13946533203125 0.108184814453125 -0.224243164062503132 +0.75575 0.14447021484375 0.112060546875 -0.224243164062503132 +0.755875 0.14447021484375 0.112060546875 -0.224243164062503132 +0.756 0.14947509765625 0.115936279296875 -0.224243164062503132 +0.756125 0.15447998046875 0.11981201171875 -0.224243164062503132 +0.75625 0.15447998046875 0.11981201171875 -0.224243164062503132 +0.756375 0.159454345703125 0.123687744140625 -0.224243164062503132 +0.7565000000000001 0.159454345703125 0.123687744140625 -0.224243164062503132 +0.756625 0.164398193359375 0.12750244140625 -0.224243164062503132 +0.75675 0.169342041015625 0.13134765625 -0.224243164062503132 +0.756875 0.169342041015625 0.13134765625 -0.224243164062503132 +0.757 0.17425537109375 0.135162353515625 -0.224243164062503132 +0.757125 0.17425537109375 0.135162353515625 -0.224243164062503132 +0.75725 0.17913818359375 0.138946533203125 -0.224243164062503132 +0.757375 0.18402099609375 0.14276123046875 -0.224243164062503132 +0.7575000000000001 0.18402099609375 0.14276123046875 -0.224243164062503132 +0.757625 0.188873291015625 0.146514892578125 -0.224243164062503132 +0.75775 0.188873291015625 0.146514892578125 -0.224243164062503132 +0.757875 0.1937255859375 0.1502685546875 -0.224243164062503132 +0.758 0.19854736328125 0.15399169921875 -0.224243164062503132 +0.758125 0.19854736328125 0.15399169921875 -0.224243164062503132 +0.75825 0.203338623046875 0.15771484375 -0.224243164062503132 +0.758375 0.203338623046875 0.15771484375 -0.224243164062503132 +0.7585000000000001 0.208099365234375 0.16143798828125 -0.224243164062503132 +0.758625 0.212860107421875 0.16510009765625 -0.224243164062503132 +0.75875 0.212860107421875 0.16510009765625 -0.224243164062503132 +0.758875 0.21759033203125 0.16876220703125 -0.224243164062503132 +0.759 0.21759033203125 0.16876220703125 -0.224243164062503132 +0.759125 0.2222900390625 0.17242431640625 -0.224243164062503132 +0.75925 0.226959228515625 0.176055908203125 -0.224243164062503132 +0.759375 0.226959228515625 0.176055908203125 -0.224243164062503132 +0.7595000000000001 0.231597900390625 0.179656982421875 -0.224243164062503132 +0.759625 0.231597900390625 0.179656982421875 -0.224243164062503132 +0.75975 0.236236572265625 0.183258056640625 -0.224243164062503132 +0.759875 0.2408447265625 0.186798095703125 -0.224243164062503132 +0.76 0.2408447265625 0.186798095703125 -0.224243164062503132 +0.7601250000000001 0.24542236328125 0.19036865234375 -0.224243164062503132 +0.76025 0.24542236328125 0.19036865234375 -0.224243164062503132 +0.760375 0.249969482421875 0.193878173828125 -0.224243164062503132 +0.7605000000000001 0.25445556640625 0.1973876953125 -0.224243164062503132 +0.760625 0.25445556640625 0.1973876953125 -0.224243164062503132 +0.76075 0.25897216796875 0.200897216796875 -0.224243164062503132 +0.760875 0.25897216796875 0.200897216796875 -0.224243164062503132 +0.761 0.263427734375 0.204345703125 -0.224243164062503132 +0.7611250000000001 0.267852783203125 0.207794189453125 -0.224243164062503132 +0.76125 0.267852783203125 0.207794189453125 -0.224243164062503132 +0.761375 0.27227783203125 0.211212158203125 -0.224243164062503132 +0.7615000000000001 0.27227783203125 0.211212158203125 -0.224243164062503132 +0.761625 0.276641845703125 0.214599609375 -0.224243164062503132 +0.76175 0.280975341796875 0.21795654296875 -0.224243164062503132 +0.761875 0.280975341796875 0.21795654296875 -0.224243164062503132 +0.762 0.285308837890625 0.2213134765625 -0.224243164062503132 +0.7621250000000001 0.285308837890625 0.2213134765625 -0.224243164062503132 +0.76225 0.289581298828125 0.224639892578125 -0.224243164062503132 +0.762375 0.2938232421875 0.227935791015625 -0.224243164062503132 +0.7625000000000001 0.2938232421875 0.227935791015625 -0.224243164062503132 +0.762625 0.298065185546875 0.231201171875 -0.224243164062503132 +0.76275 0.298065185546875 0.231201171875 -0.224243164062503132 +0.762875 0.30224609375 0.23443603515625 -0.224243164062503132 +0.763 0.306396484375 0.2376708984375 -0.224243164062503132 +0.7631250000000001 0.306396484375 0.2376708984375 -0.224243164062503132 +0.76325 0.310516357421875 0.240875244140625 -0.224243164062503132 +0.763375 0.310516357421875 0.240875244140625 -0.224243164062503132 +0.7635000000000001 0.314605712890625 0.244049072265625 -0.224243164062503132 +0.763625 0.31866455078125 0.2471923828125 -0.224243164062503132 +0.76375 0.31866455078125 0.2471923828125 -0.224243164062503132 +0.763875 0.322662353515625 0.25030517578125 -0.224243164062503132 +0.764 0.322662353515625 0.25030517578125 -0.224243164062503132 +0.7641250000000001 0.32666015625 0.253387451171875 -0.224243164062503132 +0.76425 0.330596923828125 0.256439208984375 -0.224243164062503132 +0.764375 0.330596923828125 0.256439208984375 -0.224243164062503132 +0.7645000000000001 0.334503173828125 0.259490966796875 -0.224243164062503132 +0.764625 0.334503173828125 0.259490966796875 -0.224243164062503132 +0.76475 0.33837890625 0.262481689453125 -0.224243164062503132 +0.764875 0.34222412109375 0.265472412109375 -0.224243164062503132 +0.765 0.34222412109375 0.265472412109375 -0.224243164062503132 +0.7651250000000001 0.34600830078125 0.268402099609375 -0.224243164062503132 +0.76525 0.34600830078125 0.268402099609375 -0.224243164062503132 +0.765375 0.349761962890625 0.271331787109375 -0.224243164062503132 +0.7655000000000001 0.353485107421875 0.274200439453125 -0.224243164062503132 +0.765625 0.353485107421875 0.274200439453125 -0.224243164062503132 +0.76575 0.357177734375 0.277069091796875 -0.224243164062503132 +0.765875 0.357177734375 0.277069091796875 -0.224243164062503132 +0.766 0.360809326171875 0.279876708984375 -0.224243164062503132 +0.7661250000000001 0.36444091796875 0.282684326171875 -0.224243164062503132 +0.76625 0.36444091796875 0.282684326171875 -0.224243164062503132 +0.766375 0.36798095703125 0.28546142578125 -0.224243164062503132 +0.7665000000000001 0.36798095703125 0.28546142578125 -0.224243164062503132 +0.766625 0.37152099609375 0.288177490234375 -0.224243164062503132 +0.76675 0.375 0.2908935546875 -0.224243164062503132 +0.766875 0.375 0.2908935546875 -0.224243164062503132 +0.767 0.378448486328125 0.293548583984375 -0.224243164062503132 +0.7671250000000001 0.378448486328125 0.293548583984375 -0.224243164062503132 +0.76725 0.3818359375 0.29620361328125 -0.224243164062503132 +0.767375 0.38519287109375 0.298797607421875 -0.224243164062503132 +0.7675000000000001 0.38519287109375 0.298797607421875 -0.224243164062503132 +0.767625 0.388519287109375 0.301361083984375 -0.224243164062503132 +0.76775 0.388519287109375 0.301361083984375 -0.224243164062503132 +0.767875 0.39178466796875 0.303924560546875 -0.224243164062503132 +0.768 0.39501953125 0.162811279296875 -0.5877380371093779 +0.7681250000000001 0.39501953125 0.162811279296875 -0.5877380371093779 +0.76825 0.398193359375 0.16412353515625 -0.5877380371093779 +0.768375 0.398193359375 0.16412353515625 -0.5877380371093779 +0.7685 0.401336669921875 0.165435791015625 -0.5877380371093779 +0.768625 0.404449462890625 0.166717529296875 -0.5877380371093779 +0.76875 0.404449462890625 0.166717529296875 -0.5877380371093779 +0.768875 0.407501220703125 0.16796875 -0.5877380371093779 +0.769 0.407501220703125 0.16796875 -0.5877380371093779 +0.7691250000000001 0.4105224609375 0.169189453125 -0.5877380371093779 +0.76925 0.413482666015625 0.17041015625 -0.5877380371093779 +0.769375 0.413482666015625 0.17041015625 -0.5877380371093779 +0.7695 0.416412353515625 0.171630859375 -0.5877380371093779 +0.769625 0.416412353515625 0.171630859375 -0.5877380371093779 +0.76975 0.419281005859375 0.172821044921875 -0.5877380371093779 +0.769875 0.422119140625 0.173980712890625 -0.5877380371093779 +0.77 0.422119140625 0.173980712890625 -0.5877380371093779 +0.7701250000000001 0.424896240234375 0.175140380859375 -0.5877380371093779 +0.77025 0.424896240234375 0.175140380859375 -0.5877380371093779 +0.770375 0.4276123046875 0.176239013671875 -0.5877380371093779 +0.7705 0.4302978515625 0.1773681640625 -0.5877380371093779 +0.770625 0.4302978515625 0.1773681640625 -0.5877380371093779 +0.77075 0.432952880859375 0.178466796875 -0.5877380371093779 +0.770875 0.432952880859375 0.178466796875 -0.5877380371093779 +0.771 0.435546875 0.179534912109375 -0.5877380371093779 +0.7711250000000001 0.438079833984375 0.180572509765625 -0.5877380371093779 +0.77125 0.438079833984375 0.180572509765625 -0.5877380371093779 +0.771375 0.440582275390625 0.181610107421875 -0.5877380371093779 +0.7715 0.440582275390625 0.181610107421875 -0.5877380371093779 +0.771625 0.44305419921875 0.1826171875 -0.5877380371093779 +0.77175 0.4454345703125 0.18359375 -0.5877380371093779 +0.771875 0.4454345703125 0.18359375 -0.5877380371093779 +0.772 0.447784423828125 0.1845703125 -0.5877380371093779 +0.7721250000000001 0.447784423828125 0.1845703125 -0.5877380371093779 +0.77225 0.450103759765625 0.185516357421875 -0.5877380371093779 +0.772375 0.452362060546875 0.18646240234375 -0.5877380371093779 +0.7725 0.452362060546875 0.18646240234375 -0.5877380371093779 +0.772625 0.454559326171875 0.187347412109375 -0.5877380371093779 +0.77275 0.454559326171875 0.187347412109375 -0.5877380371093779 +0.772875 0.45672607421875 0.188232421875 -0.5877380371093779 +0.773 0.458831787109375 0.189117431640625 -0.5877380371093779 +0.7731250000000001 0.458831787109375 0.189117431640625 -0.5877380371093779 +0.77325 0.46087646484375 0.189971923828125 -0.5877380371093779 +0.773375 0.46087646484375 0.189971923828125 -0.5877380371093779 +0.7735 0.462890625 0.1907958984375 -0.5877380371093779 +0.773625 0.464813232421875 0.19158935546875 -0.5877380371093779 +0.77375 0.464813232421875 0.19158935546875 -0.5877380371093779 +0.773875 0.46673583984375 0.1923828125 -0.5877380371093779 +0.774 0.46673583984375 0.1923828125 -0.5877380371093779 +0.7741250000000001 0.46856689453125 0.193145751953125 -0.5877380371093779 +0.77425 0.470367431640625 0.193878173828125 -0.5877380371093779 +0.774375 0.470367431640625 0.193878173828125 -0.5877380371093779 +0.7745 0.472137451171875 0.194610595703125 -0.5877380371093779 +0.774625 0.472137451171875 0.194610595703125 -0.5877380371093779 +0.77475 0.47381591796875 0.195281982421875 -0.5877380371093779 +0.774875 0.4754638671875 0.19598388671875 -0.5877380371093779 +0.775 0.4754638671875 0.19598388671875 -0.5877380371093779 +0.7751250000000001 0.47705078125 0.196624755859375 -0.5877380371093779 +0.77525 0.47705078125 0.196624755859375 -0.5877380371093779 +0.775375 0.478607177734375 0.197265625 -0.5877380371093779 +0.7755 0.480072021484375 0.1978759765625 -0.5877380371093779 +0.775625 0.480072021484375 0.1978759765625 -0.5877380371093779 +0.7757500000000001 0.48150634765625 0.198455810546875 -0.5877380371093779 +0.775875 0.48150634765625 0.198455810546875 -0.5877380371093779 +0.776 0.48291015625 0.19903564453125 -0.5877380371093779 +0.7761250000000001 0.484222412109375 0.1995849609375 -0.5877380371093779 +0.77625 0.484222412109375 0.1995849609375 -0.5877380371093779 +0.776375 0.485504150390625 0.200103759765625 -0.5877380371093779 +0.7765 0.485504150390625 0.200103759765625 -0.5877380371093779 +0.776625 0.486724853515625 0.20062255859375 -0.5877380371093779 +0.7767500000000001 0.487884521484375 0.201080322265625 -0.5877380371093779 +0.776875 0.487884521484375 0.201080322265625 -0.5877380371093779 +0.777 0.489013671875 0.201568603515625 -0.5877380371093779 +0.7771250000000001 0.489013671875 0.201568603515625 -0.5877380371093779 +0.77725 0.490081787109375 0.201995849609375 -0.5877380371093779 +0.777375 0.4910888671875 0.202423095703125 -0.5877380371093779 +0.7775 0.4910888671875 0.202423095703125 -0.5877380371093779 +0.777625 0.492034912109375 0.20281982421875 -0.5877380371093779 +0.7777500000000001 0.492034912109375 0.20281982421875 -0.5877380371093779 +0.777875 0.492950439453125 0.20318603515625 -0.5877380371093779 +0.778 0.4937744140625 0.203521728515625 -0.5877380371093779 +0.7781250000000001 0.4937744140625 0.203521728515625 -0.5877380371093779 +0.77825 0.49456787109375 0.203857421875 -0.5877380371093779 +0.778375 0.49456787109375 0.203857421875 -0.5877380371093779 +0.7785 0.49530029296875 0.20416259765625 -0.5877380371093779 +0.778625 0.496002197265625 0.204437255859375 -0.5877380371093779 +0.7787500000000001 0.496002197265625 0.204437255859375 -0.5877380371093779 +0.778875 0.496612548828125 0.204681396484375 -0.5877380371093779 +0.779 0.496612548828125 0.204681396484375 -0.5877380371093779 +0.7791250000000001 0.4971923828125 0.204925537109375 -0.5877380371093779 +0.77925 0.497711181640625 0.20513916015625 -0.5877380371093779 +0.779375 0.497711181640625 0.20513916015625 -0.5877380371093779 +0.7795 0.498199462890625 0.205352783203125 -0.5877380371093779 +0.779625 0.498199462890625 0.205352783203125 -0.5877380371093779 +0.7797500000000001 0.49859619140625 0.20550537109375 -0.5877380371093779 +0.779875 0.49896240234375 0.205657958984375 -0.5877380371093779 +0.78 0.49896240234375 0.205657958984375 -0.5877380371093779 +0.7801250000000001 0.499267578125 0.205780029296875 -0.5877380371093779 +0.78025 0.499267578125 0.205780029296875 -0.5877380371093779 +0.780375 0.49951171875 0.20587158203125 -0.5877380371093779 +0.7805 0.49969482421875 0.205963134765625 -0.5877380371093779 +0.780625 0.49969482421875 0.205963134765625 -0.5877380371093779 +0.7807500000000001 0.49981689453125 0.206024169921875 -0.5877380371093779 +0.780875 0.49981689453125 0.206024169921875 -0.5877380371093779 +0.781 0.499908447265625 0.2060546875 -0.5877380371093779 +0.7811250000000001 0.49993896484375 0.2060546875 -0.5877380371093779 +0.78125 0.49993896484375 0.2060546875 -0.5877380371093779 +0.781375 0.499908447265625 0.2060546875 -0.5877380371093779 +0.7815 0.499908447265625 0.2060546875 -0.5877380371093779 +0.781625 0.49981689453125 0.206024169921875 -0.5877380371093779 +0.7817500000000001 0.49969482421875 0.205963134765625 -0.5877380371093779 +0.781875 0.49969482421875 0.205963134765625 -0.5877380371093779 +0.782 0.49951171875 0.20587158203125 -0.5877380371093779 +0.7821250000000001 0.49951171875 0.20587158203125 -0.5877380371093779 +0.78225 0.499267578125 0.205780029296875 -0.5877380371093779 +0.782375 0.49896240234375 0.205657958984375 -0.5877380371093779 +0.7825 0.49896240234375 0.205657958984375 -0.5877380371093779 +0.782625 0.49859619140625 0.20550537109375 -0.5877380371093779 +0.7827500000000001 0.49859619140625 0.20550537109375 -0.5877380371093779 +0.782875 0.498199462890625 0.205352783203125 -0.5877380371093779 +0.783 0.497711181640625 0.20513916015625 -0.5877380371093779 +0.7831250000000001 0.497711181640625 0.20513916015625 -0.5877380371093779 +0.78325 0.4971923828125 0.204925537109375 -0.5877380371093779 +0.783375 0.4971923828125 0.204925537109375 -0.5877380371093779 +0.7835 0.496612548828125 0.204681396484375 -0.5877380371093779 +0.783625 0.496002197265625 0.204437255859375 -0.5877380371093779 +0.7837500000000001 0.496002197265625 0.204437255859375 -0.5877380371093779 +0.783875 0.49530029296875 0.20416259765625 -0.5877380371093779 +0.784 0.49530029296875 0.20416259765625 -0.5877380371093779 +0.784125 0.49456787109375 0.203857421875 -0.5877380371093779 +0.78425 0.4937744140625 0.203521728515625 -0.5877380371093779 +0.784375 0.4937744140625 0.203521728515625 -0.5877380371093779 +0.7845 0.492950439453125 0.20318603515625 -0.5877380371093779 +0.784625 0.492950439453125 0.20318603515625 -0.5877380371093779 +0.7847500000000001 0.492034912109375 0.20281982421875 -0.5877380371093779 +0.784875 0.4910888671875 0.202423095703125 -0.5877380371093779 +0.785 0.4910888671875 0.202423095703125 -0.5877380371093779 +0.785125 0.490081787109375 0.201995849609375 -0.5877380371093779 +0.78525 0.490081787109375 0.201995849609375 -0.5877380371093779 +0.785375 0.489013671875 0.201568603515625 -0.5877380371093779 +0.7855 0.487884521484375 0.201080322265625 -0.5877380371093779 +0.785625 0.487884521484375 0.201080322265625 -0.5877380371093779 +0.7857500000000001 0.486724853515625 0.20062255859375 -0.5877380371093779 +0.785875 0.486724853515625 0.20062255859375 -0.5877380371093779 +0.786 0.485504150390625 0.200103759765625 -0.5877380371093779 +0.786125 0.484222412109375 0.1995849609375 -0.5877380371093779 +0.78625 0.484222412109375 0.1995849609375 -0.5877380371093779 +0.786375 0.48291015625 0.19903564453125 -0.5877380371093779 +0.7865 0.48291015625 0.19903564453125 -0.5877380371093779 +0.786625 0.48150634765625 0.198455810546875 -0.5877380371093779 +0.7867500000000001 0.480072021484375 0.1978759765625 -0.5877380371093779 +0.786875 0.480072021484375 0.1978759765625 -0.5877380371093779 +0.787 0.478607177734375 0.197265625 -0.5877380371093779 +0.787125 0.478607177734375 0.197265625 -0.5877380371093779 +0.78725 0.47705078125 0.196624755859375 -0.5877380371093779 +0.787375 0.4754638671875 0.19598388671875 -0.5877380371093779 +0.7875 0.4754638671875 0.19598388671875 -0.5877380371093779 +0.787625 0.47381591796875 0.195281982421875 -0.5877380371093779 +0.7877500000000001 0.47381591796875 0.195281982421875 -0.5877380371093779 +0.787875 0.472137451171875 0.194610595703125 -0.5877380371093779 +0.788 0.470367431640625 0.193878173828125 -0.5877380371093779 +0.788125 0.470367431640625 0.193878173828125 -0.5877380371093779 +0.78825 0.46856689453125 0.193145751953125 -0.5877380371093779 +0.788375 0.46856689453125 0.193145751953125 -0.5877380371093779 +0.7885 0.46673583984375 0.1923828125 -0.5877380371093779 +0.788625 0.464813232421875 0.19158935546875 -0.5877380371093779 +0.7887500000000001 0.464813232421875 0.19158935546875 -0.5877380371093779 +0.788875 0.462890625 0.1907958984375 -0.5877380371093779 +0.789 0.462890625 0.1907958984375 -0.5877380371093779 +0.789125 0.46087646484375 0.189971923828125 -0.5877380371093779 +0.78925 0.458831787109375 0.189117431640625 -0.5877380371093779 +0.789375 0.458831787109375 0.189117431640625 -0.5877380371093779 +0.7895 0.45672607421875 0.188232421875 -0.5877380371093779 +0.789625 0.45672607421875 0.188232421875 -0.5877380371093779 +0.7897500000000001 0.454559326171875 0.187347412109375 -0.5877380371093779 +0.789875 0.452362060546875 0.18646240234375 -0.5877380371093779 +0.79 0.452362060546875 0.18646240234375 -0.5877380371093779 +0.790125 0.450103759765625 0.185516357421875 -0.5877380371093779 +0.79025 0.450103759765625 0.185516357421875 -0.5877380371093779 +0.790375 0.447784423828125 0.1845703125 -0.5877380371093779 +0.7905 0.4454345703125 0.18359375 -0.5877380371093779 +0.790625 0.4454345703125 0.18359375 -0.5877380371093779 +0.7907500000000001 0.44305419921875 0.1826171875 -0.5877380371093779 +0.790875 0.44305419921875 0.1826171875 -0.5877380371093779 +0.791 0.440582275390625 0.181610107421875 -0.5877380371093779 +0.791125 0.438079833984375 0.180572509765625 -0.5877380371093779 +0.79125 0.438079833984375 0.180572509765625 -0.5877380371093779 +0.7913750000000001 0.435546875 0.179534912109375 -0.5877380371093779 +0.7915 0.435546875 0.179534912109375 -0.5877380371093779 +0.791625 0.432952880859375 0.178466796875 -0.5877380371093779 +0.7917500000000001 0.4302978515625 0.1773681640625 -0.5877380371093779 +0.791875 0.4302978515625 0.1773681640625 -0.5877380371093779 +0.792 0.4276123046875 0.176239013671875 -0.5877380371093779 +0.792125 0.4276123046875 0.176239013671875 -0.5877380371093779 +0.79225 0.424896240234375 0.175140380859375 -0.5877380371093779 +0.7923750000000001 0.422119140625 0.173980712890625 -0.5877380371093779 +0.7925 0.422119140625 0.173980712890625 -0.5877380371093779 +0.792625 0.419281005859375 0.172821044921875 -0.5877380371093779 +0.7927500000000001 0.419281005859375 0.172821044921875 -0.5877380371093779 +0.792875 0.416412353515625 0.171630859375 -0.5877380371093779 +0.793 0.413482666015625 0.17041015625 -0.5877380371093779 +0.793125 0.413482666015625 0.17041015625 -0.5877380371093779 +0.79325 0.4105224609375 0.169189453125 -0.5877380371093779 +0.7933750000000001 0.4105224609375 0.169189453125 -0.5877380371093779 +0.7935 0.407501220703125 0.16796875 -0.5877380371093779 +0.793625 0.404449462890625 0.166717529296875 -0.5877380371093779 +0.7937500000000001 0.404449462890625 0.166717529296875 -0.5877380371093779 +0.793875 0.401336669921875 0.165435791015625 -0.5877380371093779 +0.794 0.401336669921875 0.165435791015625 -0.5877380371093779 +0.794125 0.398193359375 0.16412353515625 -0.5877380371093779 +0.79425 0.39501953125 0.162811279296875 -0.5877380371093779 +0.7943750000000001 0.39501953125 0.162811279296875 -0.5877380371093779 +0.7945 0.39178466796875 0.1614990234375 -0.5877380371093779 +0.794625 0.39178466796875 0.1614990234375 -0.5877380371093779 +0.7947500000000001 0.388519287109375 0.160125732421875 -0.5877380371093779 +0.794875 0.38519287109375 0.158782958984375 -0.5877380371093779 +0.795 0.38519287109375 0.158782958984375 -0.5877380371093779 +0.795125 0.3818359375 0.157379150390625 -0.5877380371093779 +0.79525 0.3818359375 0.157379150390625 -0.5877380371093779 +0.7953750000000001 0.378448486328125 0.155975341796875 -0.5877380371093779 +0.7955 0.375 0.154571533203125 -0.5877380371093779 +0.795625 0.375 0.154571533203125 -0.5877380371093779 +0.7957500000000001 0.37152099609375 0.15313720703125 -0.5877380371093779 +0.795875 0.37152099609375 0.15313720703125 -0.5877380371093779 +0.796 0.36798095703125 0.15167236328125 -0.5877380371093779 +0.796125 0.36444091796875 0.15020751953125 -0.5877380371093779 +0.79625 0.36444091796875 0.15020751953125 -0.5877380371093779 +0.7963750000000001 0.360809326171875 0.148712158203125 -0.5877380371093779 +0.7965 0.360809326171875 0.148712158203125 -0.5877380371093779 +0.796625 0.357177734375 0.147216796875 -0.5877380371093779 +0.7967500000000001 0.353485107421875 0.14569091796875 -0.5877380371093779 +0.796875 0.353485107421875 0.14569091796875 -0.5877380371093779 +0.797 0.349761962890625 0.1441650390625 -0.5877380371093779 +0.797125 0.349761962890625 0.1441650390625 -0.5877380371093779 +0.79725 0.34600830078125 0.142608642578125 -0.5877380371093779 +0.7973750000000001 0.34222412109375 0.14105224609375 -0.5877380371093779 +0.7975 0.34222412109375 0.14105224609375 -0.5877380371093779 +0.797625 0.33837890625 0.13946533203125 -0.5877380371093779 +0.7977500000000001 0.33837890625 0.13946533203125 -0.5877380371093779 +0.797875 0.334503173828125 0.13787841796875 -0.5877380371093779 +0.798 0.330596923828125 0.136260986328125 -0.5877380371093779 +0.798125 0.330596923828125 0.136260986328125 -0.5877380371093779 +0.79825 0.32666015625 0.1346435546875 -0.5877380371093779 +0.7983750000000001 0.32666015625 0.1346435546875 -0.5877380371093779 +0.7985 0.322662353515625 0.13299560546875 -0.5877380371093779 +0.798625 0.31866455078125 0.13134765625 -0.5877380371093779 +0.7987500000000001 0.31866455078125 0.13134765625 -0.5877380371093779 +0.798875 0.314605712890625 0.129669189453125 -0.5877380371093779 +0.799 0.314605712890625 0.129669189453125 -0.5877380371093779 +0.799125 0.310516357421875 0.12799072265625 -0.5877380371093779 +0.79925 0.306396484375 0.12628173828125 -0.5877380371093779 +0.7993750000000001 0.306396484375 0.12628173828125 -0.5877380371093779 +0.7995 0.30224609375 0.12457275390625 -0.5877380371093779 +0.799625 0.30224609375 0.12457275390625 -0.5877380371093779 +0.7997500000000001 0.298065185546875 0.12286376953125 -0.5877380371093779 +0.799875 0.2938232421875 0.12109375 -0.5877380371093779 +0.8 0.2938232421875 0.041839599609375 -0.857464599609377 +0.800125 0.289581298828125 0.041229248046875 -0.857464599609377 +0.80025 0.289581298828125 0.041229248046875 -0.857464599609377 +0.8003750000000001 0.285308837890625 0.040618896484375 -0.857464599609377 +0.8005 0.280975341796875 0.040008544921875 -0.857464599609377 +0.800625 0.280975341796875 0.040008544921875 -0.857464599609377 +0.80075 0.276641845703125 0.039398193359375 -0.857464599609377 +0.800875 0.276641845703125 0.039398193359375 -0.857464599609377 +0.801 0.27227783203125 0.038787841796875 -0.857464599609377 +0.801125 0.267852783203125 0.03814697265625 -0.857464599609377 +0.80125 0.267852783203125 0.03814697265625 -0.857464599609377 +0.8013750000000001 0.263427734375 0.037506103515625 -0.857464599609377 +0.8015 0.263427734375 0.037506103515625 -0.857464599609377 +0.801625 0.25897216796875 0.036895751953125 -0.857464599609377 +0.80175 0.25445556640625 0.0362548828125 -0.857464599609377 +0.801875 0.25445556640625 0.0362548828125 -0.857464599609377 +0.802 0.249969482421875 0.03558349609375 -0.857464599609377 +0.802125 0.249969482421875 0.03558349609375 -0.857464599609377 +0.80225 0.24542236328125 0.034942626953125 -0.857464599609377 +0.8023750000000001 0.2408447265625 0.0343017578125 -0.857464599609377 +0.8025 0.2408447265625 0.0343017578125 -0.857464599609377 +0.802625 0.236236572265625 0.03363037109375 -0.857464599609377 +0.80275 0.236236572265625 0.03363037109375 -0.857464599609377 +0.802875 0.231597900390625 0.032989501953125 -0.857464599609377 +0.803 0.226959228515625 0.032318115234375 -0.857464599609377 +0.803125 0.226959228515625 0.032318115234375 -0.857464599609377 +0.80325 0.2222900390625 0.031646728515625 -0.857464599609377 +0.8033750000000001 0.2222900390625 0.031646728515625 -0.857464599609377 +0.8035 0.21759033203125 0.030975341796875 -0.857464599609377 +0.803625 0.212860107421875 0.030303955078125 -0.857464599609377 +0.80375 0.212860107421875 0.030303955078125 -0.857464599609377 +0.803875 0.208099365234375 0.029632568359375 -0.857464599609377 +0.804 0.208099365234375 0.029632568359375 -0.857464599609377 +0.804125 0.203338623046875 0.028961181640625 -0.857464599609377 +0.80425 0.19854736328125 0.02825927734375 -0.857464599609377 +0.8043750000000001 0.19854736328125 0.02825927734375 -0.857464599609377 +0.8045 0.1937255859375 0.027587890625 -0.857464599609377 +0.804625 0.1937255859375 0.027587890625 -0.857464599609377 +0.80475 0.188873291015625 0.026885986328125 -0.857464599609377 +0.804875 0.18402099609375 0.026214599609375 -0.857464599609377 +0.805 0.18402099609375 0.026214599609375 -0.857464599609377 +0.805125 0.17913818359375 0.0255126953125 -0.857464599609377 +0.80525 0.17913818359375 0.0255126953125 -0.857464599609377 +0.8053750000000001 0.17425537109375 0.024810791015625 -0.857464599609377 +0.8055 0.169342041015625 0.02410888671875 -0.857464599609377 +0.805625 0.169342041015625 0.02410888671875 -0.857464599609377 +0.80575 0.164398193359375 0.023406982421875 -0.857464599609377 +0.805875 0.164398193359375 0.023406982421875 -0.857464599609377 +0.806 0.159454345703125 0.022705078125 -0.857464599609377 +0.806125 0.15447998046875 0.022003173828125 -0.857464599609377 +0.80625 0.15447998046875 0.022003173828125 -0.857464599609377 +0.8063750000000001 0.14947509765625 0.021270751953125 -0.857464599609377 +0.8065 0.14947509765625 0.021270751953125 -0.857464599609377 +0.806625 0.14447021484375 0.02056884765625 -0.857464599609377 +0.80675 0.13946533203125 0.019866943359375 -0.857464599609377 +0.806875 0.13946533203125 0.019866943359375 -0.857464599609377 +0.8070000000000001 0.134429931640625 0.019134521484375 -0.857464599609377 +0.807125 0.134429931640625 0.019134521484375 -0.857464599609377 +0.80725 0.129364013671875 0.0184326171875 -0.857464599609377 +0.8073750000000001 0.124298095703125 0.0177001953125 -0.857464599609377 +0.8075 0.124298095703125 0.0177001953125 -0.857464599609377 +0.807625 0.119232177734375 0.0169677734375 -0.857464599609377 +0.80775 0.119232177734375 0.0169677734375 -0.857464599609377 +0.807875 0.1141357421875 0.0162353515625 -0.857464599609377 +0.8080000000000001 0.109039306640625 0.015533447265625 -0.857464599609377 +0.808125 0.109039306640625 0.015533447265625 -0.857464599609377 +0.80825 0.103912353515625 0.014801025390625 -0.857464599609377 +0.8083750000000001 0.103912353515625 0.014801025390625 -0.857464599609377 +0.8085 0.098785400390625 0.014068603515625 -0.857464599609377 +0.808625 0.093658447265625 0.013336181640625 -0.857464599609377 +0.80875 0.093658447265625 0.013336181640625 -0.857464599609377 +0.808875 0.0885009765625 0.012603759765625 -0.857464599609377 +0.8090000000000001 0.0885009765625 0.012603759765625 -0.857464599609377 +0.809125 0.083343505859375 0.011871337890625 -0.857464599609377 +0.80925 0.07818603515625 0.011138916015625 -0.857464599609377 +0.8093750000000001 0.07818603515625 0.011138916015625 -0.857464599609377 +0.8095 0.072998046875 0.0103759765625 -0.857464599609377 +0.809625 0.072998046875 0.0103759765625 -0.857464599609377 +0.80975 0.06781005859375 0.0096435546875 -0.857464599609377 +0.809875 0.0626220703125 0.0089111328125 -0.857464599609377 +0.8100000000000001 0.0626220703125 0.0089111328125 -0.857464599609377 +0.810125 0.05743408203125 0.0081787109375 -0.857464599609377 +0.81025 0.05743408203125 0.0081787109375 -0.857464599609377 +0.8103750000000001 0.05224609375 0.007415771484375 -0.857464599609377 +0.8105 0.047027587890625 0.006683349609375 -0.857464599609377 +0.810625 0.047027587890625 0.006683349609375 -0.857464599609377 +0.81075 0.04180908203125 0.005950927734375 -0.857464599609377 +0.810875 0.04180908203125 0.005950927734375 -0.857464599609377 +0.8110000000000001 0.036590576171875 0.00518798828125 -0.857464599609377 +0.811125 0.0313720703125 0.00445556640625 -0.857464599609377 +0.81125 0.0313720703125 0.00445556640625 -0.857464599609377 +0.8113750000000001 0.026123046875 0.00372314453125 -0.857464599609377 +0.8115 0.026123046875 0.00372314453125 -0.857464599609377 +0.811625 0.020904541015625 0.002960205078125 -0.857464599609377 +0.81175 0.01568603515625 0.002227783203125 -0.857464599609377 +0.811875 0.01568603515625 0.002227783203125 -0.857464599609377 +0.8120000000000001 0.01043701171875 0.00146484375 -0.857464599609377 +0.812125 0.01043701171875 0.00146484375 -0.857464599609377 +0.81225 0.005218505859375 0.000732421875 -0.857464599609377 +0.8123750000000001 0.0 0.0 -0.857464599609377 +0.8125 0.0 0.0 -0.857464599609377 +0.812625 -0.005218505859375 -0.000732421875 -0.857464599609377 +0.81275 -0.005218505859375 -0.000732421875 -0.857464599609377 +0.812875 -0.01043701171875 -0.00146484375 -0.857464599609377 +0.8130000000000001 -0.01568603515625 -0.002227783203125 -0.857464599609377 +0.813125 -0.01568603515625 -0.002227783203125 -0.857464599609377 +0.81325 -0.020904541015625 -0.002960205078125 -0.857464599609377 +0.8133750000000001 -0.020904541015625 -0.002960205078125 -0.857464599609377 +0.8135 -0.026123046875 -0.00372314453125 -0.857464599609377 +0.813625 -0.0313720703125 -0.00445556640625 -0.857464599609377 +0.81375 -0.0313720703125 -0.00445556640625 -0.857464599609377 +0.813875 -0.036590576171875 -0.00518798828125 -0.857464599609377 +0.8140000000000001 -0.036590576171875 -0.00518798828125 -0.857464599609377 +0.814125 -0.04180908203125 -0.005950927734375 -0.857464599609377 +0.81425 -0.047027587890625 -0.006683349609375 -0.857464599609377 +0.8143750000000001 -0.047027587890625 -0.006683349609375 -0.857464599609377 +0.8145 -0.05224609375 -0.007415771484375 -0.857464599609377 +0.814625 -0.05224609375 -0.007415771484375 -0.857464599609377 +0.81475 -0.05743408203125 -0.0081787109375 -0.857464599609377 +0.814875 -0.0626220703125 -0.0089111328125 -0.857464599609377 +0.8150000000000001 -0.0626220703125 -0.0089111328125 -0.857464599609377 +0.815125 -0.06781005859375 -0.0096435546875 -0.857464599609377 +0.81525 -0.06781005859375 -0.0096435546875 -0.857464599609377 +0.8153750000000001 -0.072998046875 -0.0103759765625 -0.857464599609377 +0.8155 -0.07818603515625 -0.011138916015625 -0.857464599609377 +0.815625 -0.07818603515625 -0.011138916015625 -0.857464599609377 +0.81575 -0.083343505859375 -0.011871337890625 -0.857464599609377 +0.815875 -0.083343505859375 -0.011871337890625 -0.857464599609377 +0.8160000000000001 -0.0885009765625 -0.012603759765625 -0.857464599609377 +0.816125 -0.093658447265625 -0.013336181640625 -0.857464599609377 +0.81625 -0.093658447265625 -0.013336181640625 -0.857464599609377 +0.816375 -0.098785400390625 -0.014068603515625 -0.857464599609377 +0.8165 -0.098785400390625 -0.014068603515625 -0.857464599609377 +0.816625 -0.103912353515625 -0.014801025390625 -0.857464599609377 +0.81675 -0.109039306640625 -0.015533447265625 -0.857464599609377 +0.816875 -0.109039306640625 -0.015533447265625 -0.857464599609377 +0.8170000000000001 -0.1141357421875 -0.0162353515625 -0.857464599609377 +0.817125 -0.1141357421875 -0.0162353515625 -0.857464599609377 +0.81725 -0.119232177734375 -0.0169677734375 -0.857464599609377 +0.817375 -0.124298095703125 -0.0177001953125 -0.857464599609377 +0.8175 -0.124298095703125 -0.0177001953125 -0.857464599609377 +0.817625 -0.129364013671875 -0.0184326171875 -0.857464599609377 +0.81775 -0.129364013671875 -0.0184326171875 -0.857464599609377 +0.817875 -0.134429931640625 -0.019134521484375 -0.857464599609377 +0.8180000000000001 -0.13946533203125 -0.019866943359375 -0.857464599609377 +0.818125 -0.13946533203125 -0.019866943359375 -0.857464599609377 +0.81825 -0.14447021484375 -0.02056884765625 -0.857464599609377 +0.818375 -0.14447021484375 -0.02056884765625 -0.857464599609377 +0.8185 -0.14947509765625 -0.021270751953125 -0.857464599609377 +0.818625 -0.15447998046875 -0.022003173828125 -0.857464599609377 +0.81875 -0.15447998046875 -0.022003173828125 -0.857464599609377 +0.818875 -0.159454345703125 -0.022705078125 -0.857464599609377 +0.8190000000000001 -0.159454345703125 -0.022705078125 -0.857464599609377 +0.819125 -0.164398193359375 -0.023406982421875 -0.857464599609377 +0.81925 -0.169342041015625 -0.02410888671875 -0.857464599609377 +0.819375 -0.169342041015625 -0.02410888671875 -0.857464599609377 +0.8195 -0.17425537109375 -0.024810791015625 -0.857464599609377 +0.819625 -0.17425537109375 -0.024810791015625 -0.857464599609377 +0.81975 -0.17913818359375 -0.0255126953125 -0.857464599609377 +0.819875 -0.18402099609375 -0.026214599609375 -0.857464599609377 +0.8200000000000001 -0.18402099609375 -0.026214599609375 -0.857464599609377 +0.820125 -0.188873291015625 -0.026885986328125 -0.857464599609377 +0.82025 -0.188873291015625 -0.026885986328125 -0.857464599609377 +0.820375 -0.1937255859375 -0.027587890625 -0.857464599609377 +0.8205 -0.19854736328125 -0.02825927734375 -0.857464599609377 +0.820625 -0.19854736328125 -0.02825927734375 -0.857464599609377 +0.82075 -0.203338623046875 -0.028961181640625 -0.857464599609377 +0.820875 -0.203338623046875 -0.028961181640625 -0.857464599609377 +0.8210000000000001 -0.208099365234375 -0.029632568359375 -0.857464599609377 +0.821125 -0.212860107421875 -0.030303955078125 -0.857464599609377 +0.82125 -0.212860107421875 -0.030303955078125 -0.857464599609377 +0.821375 -0.21759033203125 -0.030975341796875 -0.857464599609377 +0.8215 -0.21759033203125 -0.030975341796875 -0.857464599609377 +0.821625 -0.2222900390625 -0.031646728515625 -0.857464599609377 +0.82175 -0.226959228515625 -0.032318115234375 -0.857464599609377 +0.821875 -0.226959228515625 -0.032318115234375 -0.857464599609377 +0.8220000000000001 -0.231597900390625 -0.032989501953125 -0.857464599609377 +0.822125 -0.231597900390625 -0.032989501953125 -0.857464599609377 +0.82225 -0.236236572265625 -0.03363037109375 -0.857464599609377 +0.822375 -0.2408447265625 -0.0343017578125 -0.857464599609377 +0.8225 -0.2408447265625 -0.0343017578125 -0.857464599609377 +0.8226250000000001 -0.24542236328125 -0.034942626953125 -0.857464599609377 +0.82275 -0.24542236328125 -0.034942626953125 -0.857464599609377 +0.822875 -0.249969482421875 -0.03558349609375 -0.857464599609377 +0.8230000000000001 -0.25445556640625 -0.0362548828125 -0.857464599609377 +0.823125 -0.25445556640625 -0.0362548828125 -0.857464599609377 +0.82325 -0.25897216796875 -0.036895751953125 -0.857464599609377 +0.823375 -0.25897216796875 -0.036895751953125 -0.857464599609377 +0.8235 -0.263427734375 -0.037506103515625 -0.857464599609377 +0.8236250000000001 -0.267852783203125 -0.03814697265625 -0.857464599609377 +0.82375 -0.267852783203125 -0.03814697265625 -0.857464599609377 +0.823875 -0.27227783203125 -0.038787841796875 -0.857464599609377 +0.8240000000000001 -0.27227783203125 -0.038787841796875 -0.857464599609377 +0.824125 -0.276641845703125 -0.039398193359375 -0.857464599609377 +0.82425 -0.280975341796875 -0.040008544921875 -0.857464599609377 +0.824375 -0.280975341796875 -0.040008544921875 -0.857464599609377 +0.8245 -0.285308837890625 -0.040618896484375 -0.857464599609377 +0.8246250000000001 -0.285308837890625 -0.040618896484375 -0.857464599609377 +0.82475 -0.289581298828125 -0.041229248046875 -0.857464599609377 +0.824875 -0.2938232421875 -0.041839599609375 -0.857464599609377 +0.8250000000000001 -0.2938232421875 -0.041839599609375 -0.857464599609377 +0.825125 -0.298065185546875 -0.042449951171875 -0.857464599609377 +0.82525 -0.298065185546875 -0.042449951171875 -0.857464599609377 +0.825375 -0.30224609375 -0.043060302734375 -0.857464599609377 +0.8255 -0.306396484375 -0.04364013671875 -0.857464599609377 +0.8256250000000001 -0.306396484375 -0.04364013671875 -0.857464599609377 +0.82575 -0.310516357421875 -0.044219970703125 -0.857464599609377 +0.825875 -0.310516357421875 -0.044219970703125 -0.857464599609377 +0.8260000000000001 -0.314605712890625 -0.0447998046875 -0.857464599609377 +0.826125 -0.31866455078125 -0.045379638671875 -0.857464599609377 +0.82625 -0.31866455078125 -0.045379638671875 -0.857464599609377 +0.826375 -0.322662353515625 -0.04595947265625 -0.857464599609377 +0.8265 -0.322662353515625 -0.04595947265625 -0.857464599609377 +0.8266250000000001 -0.32666015625 -0.0465087890625 -0.857464599609377 +0.82675 -0.330596923828125 -0.047088623046875 -0.857464599609377 +0.826875 -0.330596923828125 -0.047088623046875 -0.857464599609377 +0.8270000000000001 -0.334503173828125 -0.047637939453125 -0.857464599609377 +0.827125 -0.334503173828125 -0.047637939453125 -0.857464599609377 +0.82725 -0.33837890625 -0.048187255859375 -0.857464599609377 +0.827375 -0.34222412109375 -0.048736572265625 -0.857464599609377 +0.8275 -0.34222412109375 -0.048736572265625 -0.857464599609377 +0.8276250000000001 -0.34600830078125 -0.049285888671875 -0.857464599609377 +0.82775 -0.34600830078125 -0.049285888671875 -0.857464599609377 +0.827875 -0.349761962890625 -0.0498046875 -0.857464599609377 +0.8280000000000001 -0.353485107421875 -0.05035400390625 -0.857464599609377 +0.828125 -0.353485107421875 -0.05035400390625 -0.857464599609377 +0.82825 -0.357177734375 -0.050872802734375 -0.857464599609377 +0.828375 -0.357177734375 -0.050872802734375 -0.857464599609377 +0.8285 -0.360809326171875 -0.0513916015625 -0.857464599609377 +0.8286250000000001 -0.36444091796875 -0.051910400390625 -0.857464599609377 +0.82875 -0.36444091796875 -0.051910400390625 -0.857464599609377 +0.828875 -0.36798095703125 -0.052398681640625 -0.857464599609377 +0.8290000000000001 -0.36798095703125 -0.052398681640625 -0.857464599609377 +0.829125 -0.37152099609375 -0.05291748046875 -0.857464599609377 +0.82925 -0.375 -0.05340576171875 -0.857464599609377 +0.829375 -0.375 -0.05340576171875 -0.857464599609377 +0.8295 -0.378448486328125 -0.05389404296875 -0.857464599609377 +0.8296250000000001 -0.378448486328125 -0.05389404296875 -0.857464599609377 +0.82975 -0.3818359375 -0.05438232421875 -0.857464599609377 +0.829875 -0.38519287109375 -0.05487060546875 -0.857464599609377 +0.8300000000000001 -0.38519287109375 -0.05487060546875 -0.857464599609377 +0.830125 -0.388519287109375 -0.055328369140625 -0.857464599609377 +0.83025 -0.388519287109375 -0.055328369140625 -0.857464599609377 +0.830375 -0.39178466796875 -0.055816650390625 -0.857464599609377 +0.8305 -0.39501953125 -0.0562744140625 -0.857464599609377 +0.8306250000000001 -0.39501953125 -0.0562744140625 -0.857464599609377 +0.83075 -0.398193359375 -0.05670166015625 -0.857464599609377 +0.830875 -0.398193359375 -0.05670166015625 -0.857464599609377 +0.8310000000000001 -0.401336669921875 -0.057159423828125 -0.857464599609377 +0.831125 -0.404449462890625 -0.0576171875 -0.857464599609377 +0.83125 -0.404449462890625 -0.0576171875 -0.857464599609377 +0.831375 -0.407501220703125 -0.05804443359375 -0.857464599609377 +0.8315 -0.407501220703125 -0.05804443359375 -0.857464599609377 +0.8316250000000001 -0.4105224609375 -0.0584716796875 -0.857464599609377 +0.83175 -0.413482666015625 -0.05889892578125 -0.857464599609377 +0.831875 -0.413482666015625 -0.05889892578125 -0.857464599609377 +0.8320000000000001 -0.416412353515625 -0.003936767578125 -0.9903991699218756 +0.832125 -0.416412353515625 -0.003936767578125 -0.9903991699218756 +0.83225 -0.419281005859375 -0.00396728515625 -0.9903991699218756 +0.832375 -0.422119140625 -0.003997802734375 -0.9903991699218756 +0.8325 -0.422119140625 -0.003997802734375 -0.9903991699218756 +0.8326250000000001 -0.424896240234375 -0.0040283203125 -0.9903991699218756 +0.83275 -0.424896240234375 -0.0040283203125 -0.9903991699218756 +0.832875 -0.4276123046875 -0.004058837890625 -0.9903991699218756 +0.833 -0.4302978515625 -0.00408935546875 -0.9903991699218756 +0.833125 -0.4302978515625 -0.00408935546875 -0.9903991699218756 +0.83325 -0.432952880859375 -0.004119873046875 -0.9903991699218756 +0.833375 -0.432952880859375 -0.004119873046875 -0.9903991699218756 +0.8335 -0.435546875 -0.004119873046875 -0.9903991699218756 +0.8336250000000001 -0.438079833984375 -0.004150390625 -0.9903991699218756 +0.83375 -0.438079833984375 -0.004150390625 -0.9903991699218756 +0.833875 -0.440582275390625 -0.004180908203125 -0.9903991699218756 +0.834 -0.440582275390625 -0.004180908203125 -0.9903991699218756 +0.834125 -0.44305419921875 -0.00421142578125 -0.9903991699218756 +0.83425 -0.4454345703125 -0.00421142578125 -0.9903991699218756 +0.834375 -0.4454345703125 -0.00421142578125 -0.9903991699218756 +0.8345 -0.447784423828125 -0.004241943359375 -0.9903991699218756 +0.8346250000000001 -0.447784423828125 -0.004241943359375 -0.9903991699218756 +0.83475 -0.450103759765625 -0.0042724609375 -0.9903991699218756 +0.834875 -0.452362060546875 -0.004302978515625 -0.9903991699218756 +0.835 -0.452362060546875 -0.004302978515625 -0.9903991699218756 +0.835125 -0.454559326171875 -0.004302978515625 -0.9903991699218756 +0.83525 -0.454559326171875 -0.004302978515625 -0.9903991699218756 +0.835375 -0.45672607421875 -0.00433349609375 -0.9903991699218756 +0.8355 -0.458831787109375 -0.004364013671875 -0.9903991699218756 +0.8356250000000001 -0.458831787109375 -0.004364013671875 -0.9903991699218756 +0.83575 -0.46087646484375 -0.004364013671875 -0.9903991699218756 +0.835875 -0.46087646484375 -0.004364013671875 -0.9903991699218756 +0.836 -0.462890625 -0.00439453125 -0.9903991699218756 +0.836125 -0.464813232421875 -0.004425048828125 -0.9903991699218756 +0.83625 -0.464813232421875 -0.004425048828125 -0.9903991699218756 +0.836375 -0.46673583984375 -0.004425048828125 -0.9903991699218756 +0.8365 -0.46673583984375 -0.004425048828125 -0.9903991699218756 +0.8366250000000001 -0.46856689453125 -0.00445556640625 -0.9903991699218756 +0.83675 -0.470367431640625 -0.00445556640625 -0.9903991699218756 +0.836875 -0.470367431640625 -0.00445556640625 -0.9903991699218756 +0.837 -0.472137451171875 -0.004486083984375 -0.9903991699218756 +0.837125 -0.472137451171875 -0.004486083984375 -0.9903991699218756 +0.83725 -0.47381591796875 -0.004486083984375 -0.9903991699218756 +0.837375 -0.4754638671875 -0.0045166015625 -0.9903991699218756 +0.8375 -0.4754638671875 -0.0045166015625 -0.9903991699218756 +0.8376250000000001 -0.47705078125 -0.0045166015625 -0.9903991699218756 +0.83775 -0.47705078125 -0.0045166015625 -0.9903991699218756 +0.837875 -0.478607177734375 -0.004547119140625 -0.9903991699218756 +0.838 -0.480072021484375 -0.004547119140625 -0.9903991699218756 +0.838125 -0.480072021484375 -0.004547119140625 -0.9903991699218756 +0.8382500000000001 -0.48150634765625 -0.00457763671875 -0.9903991699218756 +0.838375 -0.48150634765625 -0.00457763671875 -0.9903991699218756 +0.8385 -0.48291015625 -0.00457763671875 -0.9903991699218756 +0.8386250000000001 -0.484222412109375 -0.004608154296875 -0.9903991699218756 +0.83875 -0.484222412109375 -0.004608154296875 -0.9903991699218756 +0.838875 -0.485504150390625 -0.004608154296875 -0.9903991699218756 +0.839 -0.485504150390625 -0.004608154296875 -0.9903991699218756 +0.839125 -0.486724853515625 -0.004608154296875 -0.9903991699218756 +0.8392500000000001 -0.487884521484375 -0.004638671875 -0.9903991699218756 +0.839375 -0.487884521484375 -0.004638671875 -0.9903991699218756 +0.8395 -0.489013671875 -0.004638671875 -0.9903991699218756 +0.8396250000000001 -0.489013671875 -0.004638671875 -0.9903991699218756 +0.83975 -0.490081787109375 -0.004638671875 -0.9903991699218756 +0.839875 -0.4910888671875 -0.004669189453125 -0.9903991699218756 +0.84 -0.4910888671875 -0.004669189453125 -0.9903991699218756 +0.840125 -0.492034912109375 -0.004669189453125 -0.9903991699218756 +0.8402500000000001 -0.492034912109375 -0.004669189453125 -0.9903991699218756 +0.840375 -0.492950439453125 -0.004669189453125 -0.9903991699218756 +0.8405 -0.4937744140625 -0.00469970703125 -0.9903991699218756 +0.8406250000000001 -0.4937744140625 -0.00469970703125 -0.9903991699218756 +0.84075 -0.49456787109375 -0.00469970703125 -0.9903991699218756 +0.840875 -0.49456787109375 -0.00469970703125 -0.9903991699218756 +0.841 -0.49530029296875 -0.00469970703125 -0.9903991699218756 +0.841125 -0.496002197265625 -0.00469970703125 -0.9903991699218756 +0.8412500000000001 -0.496002197265625 -0.00469970703125 -0.9903991699218756 +0.841375 -0.496612548828125 -0.00469970703125 -0.9903991699218756 +0.8415 -0.496612548828125 -0.00469970703125 -0.9903991699218756 +0.8416250000000001 -0.4971923828125 -0.004730224609375 -0.9903991699218756 +0.84175 -0.497711181640625 -0.004730224609375 -0.9903991699218756 +0.841875 -0.497711181640625 -0.004730224609375 -0.9903991699218756 +0.842 -0.498199462890625 -0.004730224609375 -0.9903991699218756 +0.842125 -0.498199462890625 -0.004730224609375 -0.9903991699218756 +0.8422500000000001 -0.49859619140625 -0.004730224609375 -0.9903991699218756 +0.842375 -0.49896240234375 -0.004730224609375 -0.9903991699218756 +0.8425 -0.49896240234375 -0.004730224609375 -0.9903991699218756 +0.8426250000000001 -0.499267578125 -0.004730224609375 -0.9903991699218756 +0.84275 -0.499267578125 -0.004730224609375 -0.9903991699218756 +0.842875 -0.49951171875 -0.004730224609375 -0.9903991699218756 +0.843 -0.49969482421875 -0.004730224609375 -0.9903991699218756 +0.843125 -0.49969482421875 -0.004730224609375 -0.9903991699218756 +0.8432500000000001 -0.49981689453125 -0.004730224609375 -0.9903991699218756 +0.843375 -0.49981689453125 -0.004730224609375 -0.9903991699218756 +0.8435 -0.499908447265625 -0.004730224609375 -0.9903991699218756 +0.8436250000000001 -0.49993896484375 -0.004730224609375 -0.9903991699218756 +0.84375 -0.49993896484375 -0.004730224609375 -0.9903991699218756 +0.843875 -0.499908447265625 -0.004730224609375 -0.9903991699218756 +0.844 -0.499908447265625 -0.004730224609375 -0.9903991699218756 +0.844125 -0.49981689453125 -0.004730224609375 -0.9903991699218756 +0.8442500000000001 -0.49969482421875 -0.004730224609375 -0.9903991699218756 +0.844375 -0.49969482421875 -0.004730224609375 -0.9903991699218756 +0.8445 -0.49951171875 -0.004730224609375 -0.9903991699218756 +0.8446250000000001 -0.49951171875 -0.004730224609375 -0.9903991699218756 +0.84475 -0.499267578125 -0.004730224609375 -0.9903991699218756 +0.844875 -0.49896240234375 -0.004730224609375 -0.9903991699218756 +0.845 -0.49896240234375 -0.004730224609375 -0.9903991699218756 +0.845125 -0.49859619140625 -0.004730224609375 -0.9903991699218756 +0.8452500000000001 -0.49859619140625 -0.004730224609375 -0.9903991699218756 +0.845375 -0.498199462890625 -0.004730224609375 -0.9903991699218756 +0.8455 -0.497711181640625 -0.004730224609375 -0.9903991699218756 +0.8456250000000001 -0.497711181640625 -0.004730224609375 -0.9903991699218756 +0.84575 -0.4971923828125 -0.004730224609375 -0.9903991699218756 +0.845875 -0.4971923828125 -0.004730224609375 -0.9903991699218756 +0.846 -0.496612548828125 -0.00469970703125 -0.9903991699218756 +0.846125 -0.496002197265625 -0.00469970703125 -0.9903991699218756 +0.8462500000000001 -0.496002197265625 -0.00469970703125 -0.9903991699218756 +0.846375 -0.49530029296875 -0.00469970703125 -0.9903991699218756 +0.8465 -0.49530029296875 -0.00469970703125 -0.9903991699218756 +0.8466250000000001 -0.49456787109375 -0.00469970703125 -0.9903991699218756 +0.84675 -0.4937744140625 -0.00469970703125 -0.9903991699218756 +0.846875 -0.4937744140625 -0.00469970703125 -0.9903991699218756 +0.847 -0.492950439453125 -0.004669189453125 -0.9903991699218756 +0.847125 -0.492950439453125 -0.004669189453125 -0.9903991699218756 +0.8472500000000001 -0.492034912109375 -0.004669189453125 -0.9903991699218756 +0.847375 -0.4910888671875 -0.004669189453125 -0.9903991699218756 +0.8475 -0.4910888671875 -0.004669189453125 -0.9903991699218756 +0.8476250000000001 -0.490081787109375 -0.004638671875 -0.9903991699218756 +0.84775 -0.490081787109375 -0.004638671875 -0.9903991699218756 +0.847875 -0.489013671875 -0.004638671875 -0.9903991699218756 +0.848 -0.487884521484375 -0.004638671875 -0.9903991699218756 +0.848125 -0.487884521484375 -0.004638671875 -0.9903991699218756 +0.8482500000000001 -0.486724853515625 -0.004608154296875 -0.9903991699218756 +0.848375 -0.486724853515625 -0.004608154296875 -0.9903991699218756 +0.8485 -0.485504150390625 -0.004608154296875 -0.9903991699218756 +0.848625 -0.484222412109375 -0.004608154296875 -0.9903991699218756 +0.84875 -0.484222412109375 -0.004608154296875 -0.9903991699218756 +0.848875 -0.48291015625 -0.00457763671875 -0.9903991699218756 +0.849 -0.48291015625 -0.00457763671875 -0.9903991699218756 +0.849125 -0.48150634765625 -0.00457763671875 -0.9903991699218756 +0.8492500000000001 -0.480072021484375 -0.004547119140625 -0.9903991699218756 +0.849375 -0.480072021484375 -0.004547119140625 -0.9903991699218756 +0.8495 -0.478607177734375 -0.004547119140625 -0.9903991699218756 +0.849625 -0.478607177734375 -0.004547119140625 -0.9903991699218756 +0.84975 -0.47705078125 -0.0045166015625 -0.9903991699218756 +0.849875 -0.4754638671875 -0.0045166015625 -0.9903991699218756 +0.85 -0.4754638671875 -0.0045166015625 -0.9903991699218756 +0.850125 -0.47381591796875 -0.004486083984375 -0.9903991699218756 +0.8502500000000001 -0.47381591796875 -0.004486083984375 -0.9903991699218756 +0.850375 -0.472137451171875 -0.004486083984375 -0.9903991699218756 +0.8505 -0.470367431640625 -0.00445556640625 -0.9903991699218756 +0.850625 -0.470367431640625 -0.00445556640625 -0.9903991699218756 +0.85075 -0.46856689453125 -0.00445556640625 -0.9903991699218756 +0.850875 -0.46856689453125 -0.00445556640625 -0.9903991699218756 +0.851 -0.46673583984375 -0.004425048828125 -0.9903991699218756 +0.851125 -0.464813232421875 -0.004425048828125 -0.9903991699218756 +0.8512500000000001 -0.464813232421875 -0.004425048828125 -0.9903991699218756 +0.851375 -0.462890625 -0.00439453125 -0.9903991699218756 +0.8515 -0.462890625 -0.00439453125 -0.9903991699218756 +0.851625 -0.46087646484375 -0.004364013671875 -0.9903991699218756 +0.85175 -0.458831787109375 -0.004364013671875 -0.9903991699218756 +0.851875 -0.458831787109375 -0.004364013671875 -0.9903991699218756 +0.852 -0.45672607421875 -0.00433349609375 -0.9903991699218756 +0.852125 -0.45672607421875 -0.00433349609375 -0.9903991699218756 +0.8522500000000001 -0.454559326171875 -0.004302978515625 -0.9903991699218756 +0.852375 -0.452362060546875 -0.004302978515625 -0.9903991699218756 +0.8525 -0.452362060546875 -0.004302978515625 -0.9903991699218756 +0.852625 -0.450103759765625 -0.0042724609375 -0.9903991699218756 +0.85275 -0.450103759765625 -0.0042724609375 -0.9903991699218756 +0.852875 -0.447784423828125 -0.004241943359375 -0.9903991699218756 +0.853 -0.4454345703125 -0.00421142578125 -0.9903991699218756 +0.853125 -0.4454345703125 -0.00421142578125 -0.9903991699218756 +0.8532500000000001 -0.44305419921875 -0.00421142578125 -0.9903991699218756 +0.853375 -0.44305419921875 -0.00421142578125 -0.9903991699218756 +0.8535 -0.440582275390625 -0.004180908203125 -0.9903991699218756 +0.853625 -0.438079833984375 -0.004150390625 -0.9903991699218756 +0.85375 -0.438079833984375 -0.004150390625 -0.9903991699218756 +0.8538750000000001 -0.435546875 -0.004119873046875 -0.9903991699218756 +0.854 -0.435546875 -0.004119873046875 -0.9903991699218756 +0.854125 -0.432952880859375 -0.004119873046875 -0.9903991699218756 +0.8542500000000001 -0.4302978515625 -0.00408935546875 -0.9903991699218756 +0.854375 -0.4302978515625 -0.00408935546875 -0.9903991699218756 +0.8545 -0.4276123046875 -0.004058837890625 -0.9903991699218756 +0.854625 -0.4276123046875 -0.004058837890625 -0.9903991699218756 +0.85475 -0.424896240234375 -0.0040283203125 -0.9903991699218756 +0.8548750000000001 -0.422119140625 -0.003997802734375 -0.9903991699218756 +0.855 -0.422119140625 -0.003997802734375 -0.9903991699218756 +0.855125 -0.419281005859375 -0.00396728515625 -0.9903991699218756 +0.8552500000000001 -0.419281005859375 -0.00396728515625 -0.9903991699218756 +0.855375 -0.416412353515625 -0.003936767578125 -0.9903991699218756 +0.8555 -0.413482666015625 -0.003936767578125 -0.9903991699218756 +0.855625 -0.413482666015625 -0.003936767578125 -0.9903991699218756 +0.85575 -0.4105224609375 -0.00390625 -0.9903991699218756 +0.8558750000000001 -0.4105224609375 -0.00390625 -0.9903991699218756 +0.856 -0.407501220703125 -0.003875732421875 -0.9903991699218756 +0.856125 -0.404449462890625 -0.00384521484375 -0.9903991699218756 +0.8562500000000001 -0.404449462890625 -0.00384521484375 -0.9903991699218756 +0.856375 -0.401336669921875 -0.003814697265625 -0.9903991699218756 +0.8565 -0.401336669921875 -0.003814697265625 -0.9903991699218756 +0.856625 -0.398193359375 -0.0037841796875 -0.9903991699218756 +0.85675 -0.39501953125 -0.003753662109375 -0.9903991699218756 +0.8568750000000001 -0.39501953125 -0.003753662109375 -0.9903991699218756 +0.857 -0.39178466796875 -0.00372314453125 -0.9903991699218756 +0.857125 -0.39178466796875 -0.00372314453125 -0.9903991699218756 +0.8572500000000001 -0.388519287109375 -0.003692626953125 -0.9903991699218756 +0.857375 -0.38519287109375 -0.003662109375 -0.9903991699218756 +0.8575 -0.38519287109375 -0.003662109375 -0.9903991699218756 +0.857625 -0.3818359375 -0.003631591796875 -0.9903991699218756 +0.85775 -0.3818359375 -0.003631591796875 -0.9903991699218756 +0.8578750000000001 -0.378448486328125 -0.00360107421875 -0.9903991699218756 +0.858 -0.375 -0.003570556640625 -0.9903991699218756 +0.858125 -0.375 -0.003570556640625 -0.9903991699218756 +0.8582500000000001 -0.37152099609375 -0.003509521484375 -0.9903991699218756 +0.858375 -0.37152099609375 -0.003509521484375 -0.9903991699218756 +0.8585 -0.36798095703125 -0.00347900390625 -0.9903991699218756 +0.858625 -0.36444091796875 -0.003448486328125 -0.9903991699218756 +0.85875 -0.36444091796875 -0.003448486328125 -0.9903991699218756 +0.8588750000000001 -0.360809326171875 -0.00341796875 -0.9903991699218756 +0.859 -0.360809326171875 -0.00341796875 -0.9903991699218756 +0.859125 -0.357177734375 -0.003387451171875 -0.9903991699218756 +0.8592500000000001 -0.353485107421875 -0.00335693359375 -0.9903991699218756 +0.859375 -0.353485107421875 -0.00335693359375 -0.9903991699218756 +0.8595 -0.349761962890625 -0.003326416015625 -0.9903991699218756 +0.859625 -0.349761962890625 -0.003326416015625 -0.9903991699218756 +0.85975 -0.34600830078125 -0.003265380859375 -0.9903991699218756 +0.8598750000000001 -0.34222412109375 -0.00323486328125 -0.9903991699218756 +0.86 -0.34222412109375 -0.00323486328125 -0.9903991699218756 +0.860125 -0.33837890625 -0.003204345703125 -0.9903991699218756 +0.8602500000000001 -0.33837890625 -0.003204345703125 -0.9903991699218756 +0.860375 -0.334503173828125 -0.003173828125 -0.9903991699218756 +0.8605 -0.330596923828125 -0.003143310546875 -0.9903991699218756 +0.860625 -0.330596923828125 -0.003143310546875 -0.9903991699218756 +0.86075 -0.32666015625 -0.003082275390625 -0.9903991699218756 +0.8608750000000001 -0.32666015625 -0.003082275390625 -0.9903991699218756 +0.861 -0.322662353515625 -0.0030517578125 -0.9903991699218756 +0.861125 -0.31866455078125 -0.003021240234375 -0.9903991699218756 +0.8612500000000001 -0.31866455078125 -0.003021240234375 -0.9903991699218756 +0.861375 -0.314605712890625 -0.00299072265625 -0.9903991699218756 +0.8615 -0.314605712890625 -0.00299072265625 -0.9903991699218756 +0.861625 -0.310516357421875 -0.0029296875 -0.9903991699218756 +0.86175 -0.306396484375 -0.002899169921875 -0.9903991699218756 +0.8618750000000001 -0.306396484375 -0.002899169921875 -0.9903991699218756 +0.862 -0.30224609375 -0.00286865234375 -0.9903991699218756 +0.862125 -0.30224609375 -0.00286865234375 -0.9903991699218756 +0.8622500000000001 -0.298065185546875 -0.002838134765625 -0.9903991699218756 +0.862375 -0.2938232421875 -0.002777099609375 -0.9903991699218756 +0.8625 -0.2938232421875 -0.002777099609375 -0.9903991699218756 +0.862625 -0.289581298828125 -0.00274658203125 -0.9903991699218756 +0.86275 -0.289581298828125 -0.00274658203125 -0.9903991699218756 +0.8628750000000001 -0.285308837890625 -0.002716064453125 -0.9903991699218756 +0.863 -0.280975341796875 -0.002655029296875 -0.9903991699218756 +0.863125 -0.280975341796875 -0.002655029296875 -0.9903991699218756 +0.8632500000000001 -0.276641845703125 -0.00262451171875 -0.9903991699218756 +0.863375 -0.276641845703125 -0.00262451171875 -0.9903991699218756 +0.8635 -0.27227783203125 -0.0025634765625 -0.9903991699218756 +0.863625 -0.267852783203125 -0.002532958984375 -0.9903991699218756 +0.86375 -0.267852783203125 -0.002532958984375 -0.9903991699218756 +0.8638750000000001 -0.263427734375 -0.00250244140625 -0.9903991699218756 +0.864 -0.263427734375 -0.00909423828125 -0.9653259277343738 +0.864125 -0.25897216796875 -0.008941650390625 -0.9653259277343738 +0.86425 -0.25445556640625 -0.0087890625 -0.9653259277343738 +0.864375 -0.25445556640625 -0.0087890625 -0.9653259277343738 +0.8645 -0.249969482421875 -0.008636474609375 -0.9653259277343738 +0.864625 -0.249969482421875 -0.008636474609375 -0.9653259277343738 +0.86475 -0.24542236328125 -0.00848388671875 -0.9653259277343738 +0.8648750000000001 -0.2408447265625 -0.00830078125 -0.9653259277343738 +0.865 -0.2408447265625 -0.00830078125 -0.9653259277343738 +0.865125 -0.236236572265625 -0.008148193359375 -0.9653259277343738 +0.86525 -0.236236572265625 -0.008148193359375 -0.9653259277343738 +0.865375 -0.231597900390625 -0.00799560546875 -0.9653259277343738 +0.8655 -0.226959228515625 -0.007843017578125 -0.9653259277343738 +0.865625 -0.226959228515625 -0.007843017578125 -0.9653259277343738 +0.86575 -0.2222900390625 -0.007659912109375 -0.9653259277343738 +0.8658750000000001 -0.2222900390625 -0.007659912109375 -0.9653259277343738 +0.866 -0.21759033203125 -0.00750732421875 -0.9653259277343738 +0.866125 -0.212860107421875 -0.007354736328125 -0.9653259277343738 +0.86625 -0.212860107421875 -0.007354736328125 -0.9653259277343738 +0.866375 -0.208099365234375 -0.007171630859375 -0.9653259277343738 +0.8665 -0.208099365234375 -0.007171630859375 -0.9653259277343738 +0.866625 -0.203338623046875 -0.00701904296875 -0.9653259277343738 +0.86675 -0.19854736328125 -0.0068359375 -0.9653259277343738 +0.8668750000000001 -0.19854736328125 -0.0068359375 -0.9653259277343738 +0.867 -0.1937255859375 -0.006683349609375 -0.9653259277343738 +0.867125 -0.1937255859375 -0.006683349609375 -0.9653259277343738 +0.86725 -0.188873291015625 -0.00653076171875 -0.9653259277343738 +0.867375 -0.18402099609375 -0.00634765625 -0.9653259277343738 +0.8675 -0.18402099609375 -0.00634765625 -0.9653259277343738 +0.867625 -0.17913818359375 -0.00616455078125 -0.9653259277343738 +0.86775 -0.17913818359375 -0.00616455078125 -0.9653259277343738 +0.8678750000000001 -0.17425537109375 -0.006011962890625 -0.9653259277343738 +0.868 -0.169342041015625 -0.005828857421875 -0.9653259277343738 +0.868125 -0.169342041015625 -0.005828857421875 -0.9653259277343738 +0.86825 -0.164398193359375 -0.00567626953125 -0.9653259277343738 +0.868375 -0.164398193359375 -0.00567626953125 -0.9653259277343738 +0.8685 -0.159454345703125 -0.0054931640625 -0.9653259277343738 +0.868625 -0.15447998046875 -0.005340576171875 -0.9653259277343738 +0.86875 -0.15447998046875 -0.005340576171875 -0.9653259277343738 +0.8688750000000001 -0.14947509765625 -0.005157470703125 -0.9653259277343738 +0.869 -0.14947509765625 -0.005157470703125 -0.9653259277343738 +0.869125 -0.14447021484375 -0.004974365234375 -0.9653259277343738 +0.86925 -0.13946533203125 -0.00482177734375 -0.9653259277343738 +0.869375 -0.13946533203125 -0.00482177734375 -0.9653259277343738 +0.8695000000000001 -0.134429931640625 -0.004638671875 -0.9653259277343738 +0.869625 -0.134429931640625 -0.004638671875 -0.9653259277343738 +0.86975 -0.129364013671875 -0.00445556640625 -0.9653259277343738 +0.8698750000000001 -0.124298095703125 -0.0042724609375 -0.9653259277343738 +0.87 -0.124298095703125 -0.0042724609375 -0.9653259277343738 +0.870125 -0.119232177734375 -0.004119873046875 -0.9653259277343738 +0.87025 -0.119232177734375 -0.004119873046875 -0.9653259277343738 +0.870375 -0.1141357421875 -0.003936767578125 -0.9653259277343738 +0.8705000000000001 -0.109039306640625 -0.003753662109375 -0.9653259277343738 +0.870625 -0.109039306640625 -0.003753662109375 -0.9653259277343738 +0.87075 -0.103912353515625 -0.003570556640625 -0.9653259277343738 +0.8708750000000001 -0.103912353515625 -0.003570556640625 -0.9653259277343738 +0.871 -0.098785400390625 -0.003387451171875 -0.9653259277343738 +0.871125 -0.093658447265625 -0.00323486328125 -0.9653259277343738 +0.87125 -0.093658447265625 -0.00323486328125 -0.9653259277343738 +0.871375 -0.0885009765625 -0.0030517578125 -0.9653259277343738 +0.8715000000000001 -0.0885009765625 -0.0030517578125 -0.9653259277343738 +0.871625 -0.083343505859375 -0.00286865234375 -0.9653259277343738 +0.87175 -0.07818603515625 -0.002685546875 -0.9653259277343738 +0.8718750000000001 -0.07818603515625 -0.002685546875 -0.9653259277343738 +0.872 -0.072998046875 -0.00250244140625 -0.9653259277343738 +0.872125 -0.072998046875 -0.00250244140625 -0.9653259277343738 +0.87225 -0.06781005859375 -0.0023193359375 -0.9653259277343738 +0.872375 -0.0626220703125 -0.00213623046875 -0.9653259277343738 +0.8725000000000001 -0.0626220703125 -0.00213623046875 -0.9653259277343738 +0.872625 -0.05743408203125 -0.001983642578125 -0.9653259277343738 +0.87275 -0.05743408203125 -0.001983642578125 -0.9653259277343738 +0.8728750000000001 -0.05224609375 -0.001800537109375 -0.9653259277343738 +0.873 -0.047027587890625 -0.001617431640625 -0.9653259277343738 +0.873125 -0.047027587890625 -0.001617431640625 -0.9653259277343738 +0.87325 -0.04180908203125 -0.001434326171875 -0.9653259277343738 +0.873375 -0.04180908203125 -0.001434326171875 -0.9653259277343738 +0.8735000000000001 -0.036590576171875 -0.001251220703125 -0.9653259277343738 +0.873625 -0.0313720703125 -0.001068115234375 -0.9653259277343738 +0.87375 -0.0313720703125 -0.001068115234375 -0.9653259277343738 +0.8738750000000001 -0.026123046875 -0.000885009765625 -0.9653259277343738 +0.874 -0.026123046875 -0.000885009765625 -0.9653259277343738 +0.874125 -0.020904541015625 -0.000701904296875 -0.9653259277343738 +0.87425 -0.01568603515625 -0.000518798828125 -0.9653259277343738 +0.874375 -0.01568603515625 -0.000518798828125 -0.9653259277343738 +0.8745000000000001 -0.01043701171875 -0.000335693359375 -0.9653259277343738 +0.874625 -0.01043701171875 -0.000335693359375 -0.9653259277343738 +0.87475 -0.005218505859375 -0.000152587890625 -0.9653259277343738 +0.8748750000000001 0.0 0.0 -0.9653259277343738 +0.875 0.0 0.0 -0.9653259277343738 +0.875125 0.005218505859375 0.000152587890625 -0.9653259277343738 +0.87525 0.005218505859375 0.000152587890625 -0.9653259277343738 +0.875375 0.01043701171875 0.000335693359375 -0.9653259277343738 +0.8755000000000001 0.01568603515625 0.000518798828125 -0.9653259277343738 +0.875625 0.01568603515625 0.000518798828125 -0.9653259277343738 +0.87575 0.020904541015625 0.000701904296875 -0.9653259277343738 +0.8758750000000001 0.020904541015625 0.000701904296875 -0.9653259277343738 +0.876 0.026123046875 0.000885009765625 -0.9653259277343738 +0.876125 0.0313720703125 0.001068115234375 -0.9653259277343738 +0.87625 0.0313720703125 0.001068115234375 -0.9653259277343738 +0.876375 0.036590576171875 0.001251220703125 -0.9653259277343738 +0.8765000000000001 0.036590576171875 0.001251220703125 -0.9653259277343738 +0.876625 0.04180908203125 0.001434326171875 -0.9653259277343738 +0.87675 0.047027587890625 0.001617431640625 -0.9653259277343738 +0.8768750000000001 0.047027587890625 0.001617431640625 -0.9653259277343738 +0.877 0.05224609375 0.001800537109375 -0.9653259277343738 +0.877125 0.05224609375 0.001800537109375 -0.9653259277343738 +0.87725 0.05743408203125 0.001983642578125 -0.9653259277343738 +0.877375 0.0626220703125 0.00213623046875 -0.9653259277343738 +0.8775000000000001 0.0626220703125 0.00213623046875 -0.9653259277343738 +0.877625 0.06781005859375 0.0023193359375 -0.9653259277343738 +0.87775 0.06781005859375 0.0023193359375 -0.9653259277343738 +0.8778750000000001 0.072998046875 0.00250244140625 -0.9653259277343738 +0.878 0.07818603515625 0.002685546875 -0.9653259277343738 +0.878125 0.07818603515625 0.002685546875 -0.9653259277343738 +0.87825 0.083343505859375 0.00286865234375 -0.9653259277343738 +0.878375 0.083343505859375 0.00286865234375 -0.9653259277343738 +0.8785000000000001 0.0885009765625 0.0030517578125 -0.9653259277343738 +0.878625 0.093658447265625 0.00323486328125 -0.9653259277343738 +0.87875 0.093658447265625 0.00323486328125 -0.9653259277343738 +0.8788750000000001 0.098785400390625 0.003387451171875 -0.9653259277343738 +0.879 0.098785400390625 0.003387451171875 -0.9653259277343738 +0.879125 0.103912353515625 0.003570556640625 -0.9653259277343738 +0.87925 0.109039306640625 0.003753662109375 -0.9653259277343738 +0.879375 0.109039306640625 0.003753662109375 -0.9653259277343738 +0.8795000000000001 0.1141357421875 0.003936767578125 -0.9653259277343738 +0.879625 0.1141357421875 0.003936767578125 -0.9653259277343738 +0.87975 0.119232177734375 0.004119873046875 -0.9653259277343738 +0.8798750000000001 0.124298095703125 0.0042724609375 -0.9653259277343738 +0.88 0.124298095703125 0.0042724609375 -0.9653259277343738 +0.880125 0.129364013671875 0.00445556640625 -0.9653259277343738 +0.88025 0.129364013671875 0.00445556640625 -0.9653259277343738 +0.880375 0.134429931640625 0.004638671875 -0.9653259277343738 +0.8805000000000001 0.13946533203125 0.00482177734375 -0.9653259277343738 +0.880625 0.13946533203125 0.00482177734375 -0.9653259277343738 +0.88075 0.14447021484375 0.004974365234375 -0.9653259277343738 +0.880875 0.14447021484375 0.004974365234375 -0.9653259277343738 +0.881 0.14947509765625 0.005157470703125 -0.9653259277343738 +0.881125 0.15447998046875 0.005340576171875 -0.9653259277343738 +0.88125 0.15447998046875 0.005340576171875 -0.9653259277343738 +0.881375 0.159454345703125 0.0054931640625 -0.9653259277343738 +0.8815000000000001 0.159454345703125 0.0054931640625 -0.9653259277343738 +0.881625 0.164398193359375 0.00567626953125 -0.9653259277343738 +0.88175 0.169342041015625 0.005828857421875 -0.9653259277343738 +0.881875 0.169342041015625 0.005828857421875 -0.9653259277343738 +0.882 0.17425537109375 0.006011962890625 -0.9653259277343738 +0.882125 0.17425537109375 0.006011962890625 -0.9653259277343738 +0.88225 0.17913818359375 0.00616455078125 -0.9653259277343738 +0.882375 0.18402099609375 0.00634765625 -0.9653259277343738 +0.8825000000000001 0.18402099609375 0.00634765625 -0.9653259277343738 +0.882625 0.188873291015625 0.00653076171875 -0.9653259277343738 +0.88275 0.188873291015625 0.00653076171875 -0.9653259277343738 +0.882875 0.1937255859375 0.006683349609375 -0.9653259277343738 +0.883 0.19854736328125 0.0068359375 -0.9653259277343738 +0.883125 0.19854736328125 0.0068359375 -0.9653259277343738 +0.88325 0.203338623046875 0.00701904296875 -0.9653259277343738 +0.883375 0.203338623046875 0.00701904296875 -0.9653259277343738 +0.8835000000000001 0.208099365234375 0.007171630859375 -0.9653259277343738 +0.883625 0.212860107421875 0.007354736328125 -0.9653259277343738 +0.88375 0.212860107421875 0.007354736328125 -0.9653259277343738 +0.883875 0.21759033203125 0.00750732421875 -0.9653259277343738 +0.884 0.21759033203125 0.00750732421875 -0.9653259277343738 +0.884125 0.2222900390625 0.007659912109375 -0.9653259277343738 +0.88425 0.226959228515625 0.007843017578125 -0.9653259277343738 +0.884375 0.226959228515625 0.007843017578125 -0.9653259277343738 +0.8845000000000001 0.231597900390625 0.00799560546875 -0.9653259277343738 +0.884625 0.231597900390625 0.00799560546875 -0.9653259277343738 +0.88475 0.236236572265625 0.008148193359375 -0.9653259277343738 +0.884875 0.2408447265625 0.00830078125 -0.9653259277343738 +0.885 0.2408447265625 0.00830078125 -0.9653259277343738 +0.8851250000000001 0.24542236328125 0.00848388671875 -0.9653259277343738 +0.88525 0.24542236328125 0.00848388671875 -0.9653259277343738 +0.885375 0.249969482421875 0.008636474609375 -0.9653259277343738 +0.8855000000000001 0.25445556640625 0.0087890625 -0.9653259277343738 +0.885625 0.25445556640625 0.0087890625 -0.9653259277343738 +0.88575 0.25897216796875 0.008941650390625 -0.9653259277343738 +0.885875 0.25897216796875 0.008941650390625 -0.9653259277343738 +0.886 0.263427734375 0.00909423828125 -0.9653259277343738 +0.8861250000000001 0.267852783203125 0.009246826171875 -0.9653259277343738 +0.88625 0.267852783203125 0.009246826171875 -0.9653259277343738 +0.886375 0.27227783203125 0.0093994140625 -0.9653259277343738 +0.8865000000000001 0.27227783203125 0.0093994140625 -0.9653259277343738 +0.886625 0.276641845703125 0.009552001953125 -0.9653259277343738 +0.88675 0.280975341796875 0.00970458984375 -0.9653259277343738 +0.886875 0.280975341796875 0.00970458984375 -0.9653259277343738 +0.887 0.285308837890625 0.009857177734375 -0.9653259277343738 +0.8871250000000001 0.285308837890625 0.009857177734375 -0.9653259277343738 +0.88725 0.289581298828125 0.010009765625 -0.9653259277343738 +0.887375 0.2938232421875 0.0101318359375 -0.9653259277343738 +0.8875000000000001 0.2938232421875 0.0101318359375 -0.9653259277343738 +0.887625 0.298065185546875 0.010284423828125 -0.9653259277343738 +0.88775 0.298065185546875 0.010284423828125 -0.9653259277343738 +0.887875 0.30224609375 0.01043701171875 -0.9653259277343738 +0.888 0.306396484375 0.010589599609375 -0.9653259277343738 +0.8881250000000001 0.306396484375 0.010589599609375 -0.9653259277343738 +0.88825 0.310516357421875 0.010711669921875 -0.9653259277343738 +0.888375 0.310516357421875 0.010711669921875 -0.9653259277343738 +0.8885000000000001 0.314605712890625 0.0108642578125 -0.9653259277343738 +0.888625 0.31866455078125 0.011016845703125 -0.9653259277343738 +0.88875 0.31866455078125 0.011016845703125 -0.9653259277343738 +0.888875 0.322662353515625 0.011138916015625 -0.9653259277343738 +0.889 0.322662353515625 0.011138916015625 -0.9653259277343738 +0.8891250000000001 0.32666015625 0.01129150390625 -0.9653259277343738 +0.88925 0.330596923828125 0.01141357421875 -0.9653259277343738 +0.889375 0.330596923828125 0.01141357421875 -0.9653259277343738 +0.8895000000000001 0.334503173828125 0.011566162109375 -0.9653259277343738 +0.889625 0.334503173828125 0.011566162109375 -0.9653259277343738 +0.88975 0.33837890625 0.011688232421875 -0.9653259277343738 +0.889875 0.34222412109375 0.011810302734375 -0.9653259277343738 +0.89 0.34222412109375 0.011810302734375 -0.9653259277343738 +0.8901250000000001 0.34600830078125 0.011962890625 -0.9653259277343738 +0.89025 0.34600830078125 0.011962890625 -0.9653259277343738 +0.890375 0.349761962890625 0.0120849609375 -0.9653259277343738 +0.8905000000000001 0.353485107421875 0.01220703125 -0.9653259277343738 +0.890625 0.353485107421875 0.01220703125 -0.9653259277343738 +0.89075 0.357177734375 0.0123291015625 -0.9653259277343738 +0.890875 0.357177734375 0.0123291015625 -0.9653259277343738 +0.891 0.360809326171875 0.012451171875 -0.9653259277343738 +0.8911250000000001 0.36444091796875 0.0125732421875 -0.9653259277343738 +0.89125 0.36444091796875 0.0125732421875 -0.9653259277343738 +0.891375 0.36798095703125 0.0126953125 -0.9653259277343738 +0.8915000000000001 0.36798095703125 0.0126953125 -0.9653259277343738 +0.891625 0.37152099609375 0.0128173828125 -0.9653259277343738 +0.89175 0.375 0.012939453125 -0.9653259277343738 +0.891875 0.375 0.012939453125 -0.9653259277343738 +0.892 0.378448486328125 0.0130615234375 -0.9653259277343738 +0.8921250000000001 0.378448486328125 0.0130615234375 -0.9653259277343738 +0.89225 0.3818359375 0.01318359375 -0.9653259277343738 +0.892375 0.38519287109375 0.0133056640625 -0.9653259277343738 +0.8925000000000001 0.38519287109375 0.0133056640625 -0.9653259277343738 +0.892625 0.388519287109375 0.013427734375 -0.9653259277343738 +0.89275 0.388519287109375 0.013427734375 -0.9653259277343738 +0.892875 0.39178466796875 0.013519287109375 -0.9653259277343738 +0.893 0.39501953125 0.013641357421875 -0.9653259277343738 +0.8931250000000001 0.39501953125 0.013641357421875 -0.9653259277343738 +0.89325 0.398193359375 0.013763427734375 -0.9653259277343738 +0.893375 0.398193359375 0.013763427734375 -0.9653259277343738 +0.8935000000000001 0.401336669921875 0.01385498046875 -0.9653259277343738 +0.893625 0.404449462890625 0.01397705078125 -0.9653259277343738 +0.89375 0.404449462890625 0.01397705078125 -0.9653259277343738 +0.893875 0.407501220703125 0.014068603515625 -0.9653259277343738 +0.894 0.407501220703125 0.014068603515625 -0.9653259277343738 +0.8941250000000001 0.4105224609375 0.014190673828125 -0.9653259277343738 +0.89425 0.413482666015625 0.0142822265625 -0.9653259277343738 +0.894375 0.413482666015625 0.0142822265625 -0.9653259277343738 +0.8945000000000001 0.416412353515625 0.014373779296875 -0.9653259277343738 +0.894625 0.416412353515625 0.014373779296875 -0.9653259277343738 +0.89475 0.419281005859375 0.014495849609375 -0.9653259277343738 +0.894875 0.422119140625 0.01458740234375 -0.9653259277343738 +0.895 0.422119140625 0.01458740234375 -0.9653259277343738 +0.8951250000000001 0.424896240234375 0.014678955078125 -0.9653259277343738 +0.89525 0.424896240234375 0.014678955078125 -0.9653259277343738 +0.895375 0.4276123046875 0.0147705078125 -0.9653259277343738 +0.8955000000000001 0.4302978515625 0.014862060546875 -0.9653259277343738 +0.895625 0.4302978515625 0.014862060546875 -0.9653259277343738 +0.89575 0.432952880859375 0.01495361328125 -0.9653259277343738 +0.895875 0.432952880859375 0.01495361328125 -0.9653259277343738 +0.896 0.435546875 0.093048095703125 -0.7862487792968719 +0.8961250000000001 0.438079833984375 0.093597412109375 -0.7862487792968719 +0.89625 0.438079833984375 0.093597412109375 -0.7862487792968719 +0.896375 0.440582275390625 0.0941162109375 -0.7862487792968719 +0.8965 0.440582275390625 0.0941162109375 -0.7862487792968719 +0.896625 0.44305419921875 0.09466552734375 -0.7862487792968719 +0.89675 0.4454345703125 0.09515380859375 -0.7862487792968719 +0.896875 0.4454345703125 0.09515380859375 -0.7862487792968719 +0.897 0.447784423828125 0.095672607421875 -0.7862487792968719 +0.8971250000000001 0.447784423828125 0.095672607421875 -0.7862487792968719 +0.89725 0.450103759765625 0.096160888671875 -0.7862487792968719 +0.897375 0.452362060546875 0.096649169921875 -0.7862487792968719 +0.8975 0.452362060546875 0.096649169921875 -0.7862487792968719 +0.897625 0.454559326171875 0.09710693359375 -0.7862487792968719 +0.89775 0.454559326171875 0.09710693359375 -0.7862487792968719 +0.897875 0.45672607421875 0.097564697265625 -0.7862487792968719 +0.898 0.458831787109375 0.0980224609375 -0.7862487792968719 +0.8981250000000001 0.458831787109375 0.0980224609375 -0.7862487792968719 +0.89825 0.46087646484375 0.09844970703125 -0.7862487792968719 +0.898375 0.46087646484375 0.09844970703125 -0.7862487792968719 +0.8985 0.462890625 0.098876953125 -0.7862487792968719 +0.898625 0.464813232421875 0.09930419921875 -0.7862487792968719 +0.89875 0.464813232421875 0.09930419921875 -0.7862487792968719 +0.898875 0.46673583984375 0.099700927734375 -0.7862487792968719 +0.899 0.46673583984375 0.099700927734375 -0.7862487792968719 +0.8991250000000001 0.46856689453125 0.10009765625 -0.7862487792968719 +0.89925 0.470367431640625 0.100494384765625 -0.7862487792968719 +0.899375 0.470367431640625 0.100494384765625 -0.7862487792968719 +0.8995 0.472137451171875 0.100860595703125 -0.7862487792968719 +0.899625 0.472137451171875 0.100860595703125 -0.7862487792968719 +0.89975 0.47381591796875 0.101226806640625 -0.7862487792968719 +0.899875 0.4754638671875 0.101593017578125 -0.7862487792968719 +0.9 0.4754638671875 0.101593017578125 -0.7862487792968719 +0.9001250000000001 0.47705078125 0.1019287109375 -0.7862487792968719 +0.90025 0.47705078125 0.1019287109375 -0.7862487792968719 +0.900375 0.478607177734375 0.10223388671875 -0.7862487792968719 +0.9005 0.480072021484375 0.102569580078125 -0.7862487792968719 +0.900625 0.480072021484375 0.102569580078125 -0.7862487792968719 +0.90075 0.48150634765625 0.102874755859375 -0.7862487792968719 +0.900875 0.48150634765625 0.102874755859375 -0.7862487792968719 +0.901 0.48291015625 0.103179931640625 -0.7862487792968719 +0.9011250000000000768 0.484222412109375 0.10345458984375 -0.7862487792968719 +0.90125 0.484222412109375 0.10345458984375 -0.7862487792968719 +0.901375 0.485504150390625 0.103729248046875 -0.7862487792968719 +0.9015 0.485504150390625 0.103729248046875 -0.7862487792968719 +0.901625 0.486724853515625 0.103973388671875 -0.7862487792968719 +0.90175 0.487884521484375 0.104248046875 -0.7862487792968719 +0.901875 0.487884521484375 0.104248046875 -0.7862487792968719 +0.902 0.489013671875 0.104461669921875 -0.7862487792968719 +0.9021250000000000768 0.489013671875 0.104461669921875 -0.7862487792968719 +0.90225 0.490081787109375 0.104705810546875 -0.7862487792968719 +0.902375 0.4910888671875 0.10491943359375 -0.7862487792968719 +0.9025 0.4910888671875 0.10491943359375 -0.7862487792968719 +0.902625 0.492034912109375 0.105133056640625 -0.7862487792968719 +0.90275 0.492034912109375 0.105133056640625 -0.7862487792968719 +0.902875 0.492950439453125 0.105316162109375 -0.7862487792968719 +0.903 0.4937744140625 0.105499267578125 -0.7862487792968719 +0.9031250000000000768 0.4937744140625 0.105499267578125 -0.7862487792968719 +0.90325 0.49456787109375 0.10565185546875 -0.7862487792968719 +0.903375 0.49456787109375 0.10565185546875 -0.7862487792968719 +0.9035 0.49530029296875 0.105804443359375 -0.7862487792968719 +0.903625 0.496002197265625 0.10595703125 -0.7862487792968719 +0.90375 0.496002197265625 0.10595703125 -0.7862487792968719 +0.903875 0.496612548828125 0.106109619140625 -0.7862487792968719 +0.904 0.496612548828125 0.106109619140625 -0.7862487792968719 +0.9041250000000000768 0.4971923828125 0.106231689453125 -0.7862487792968719 +0.90425 0.497711181640625 0.1063232421875 -0.7862487792968719 +0.904375 0.497711181640625 0.1063232421875 -0.7862487792968719 +0.9045 0.498199462890625 0.1064453125 -0.7862487792968719 +0.904625 0.498199462890625 0.1064453125 -0.7862487792968719 +0.90475 0.49859619140625 0.10650634765625 -0.7862487792968719 +0.904875 0.49896240234375 0.106597900390625 -0.7862487792968719 +0.905 0.49896240234375 0.106597900390625 -0.7862487792968719 +0.9051250000000000768 0.499267578125 0.106658935546875 -0.7862487792968719 +0.90525 0.499267578125 0.106658935546875 -0.7862487792968719 +0.905375 0.49951171875 0.106719970703125 -0.7862487792968719 +0.9055 0.49969482421875 0.10675048828125 -0.7862487792968719 +0.905625 0.49969482421875 0.10675048828125 -0.7862487792968719 +0.90575 0.49981689453125 0.106781005859375 -0.7862487792968719 +0.905875 0.49981689453125 0.106781005859375 -0.7862487792968719 +0.906 0.499908447265625 0.1068115234375 -0.7862487792968719 +0.9061250000000000768 0.49993896484375 0.1068115234375 -0.7862487792968719 +0.90625 0.49993896484375 0.1068115234375 -0.7862487792968719 +0.906375 0.499908447265625 0.1068115234375 -0.7862487792968719 +0.9065 0.499908447265625 0.1068115234375 -0.7862487792968719 +0.906625 0.49981689453125 0.106781005859375 -0.7862487792968719 +0.9067500000000000768 0.49969482421875 0.10675048828125 -0.7862487792968719 +0.906875 0.49969482421875 0.10675048828125 -0.7862487792968719 +0.907 0.49951171875 0.106719970703125 -0.7862487792968719 +0.9071250000000000768 0.49951171875 0.106719970703125 -0.7862487792968719 +0.90725 0.499267578125 0.106658935546875 -0.7862487792968719 +0.907375 0.49896240234375 0.106597900390625 -0.7862487792968719 +0.9075 0.49896240234375 0.106597900390625 -0.7862487792968719 +0.907625 0.49859619140625 0.10650634765625 -0.7862487792968719 +0.9077500000000000768 0.49859619140625 0.10650634765625 -0.7862487792968719 +0.907875 0.498199462890625 0.1064453125 -0.7862487792968719 +0.908 0.497711181640625 0.1063232421875 -0.7862487792968719 +0.9081250000000000768 0.497711181640625 0.1063232421875 -0.7862487792968719 +0.90825 0.4971923828125 0.106231689453125 -0.7862487792968719 +0.908375 0.4971923828125 0.106231689453125 -0.7862487792968719 +0.9085 0.496612548828125 0.106109619140625 -0.7862487792968719 +0.908625 0.496002197265625 0.10595703125 -0.7862487792968719 +0.9087500000000000768 0.496002197265625 0.10595703125 -0.7862487792968719 +0.908875 0.49530029296875 0.105804443359375 -0.7862487792968719 +0.909 0.49530029296875 0.105804443359375 -0.7862487792968719 +0.9091250000000000768 0.49456787109375 0.10565185546875 -0.7862487792968719 +0.90925 0.4937744140625 0.105499267578125 -0.7862487792968719 +0.909375 0.4937744140625 0.105499267578125 -0.7862487792968719 +0.9095 0.492950439453125 0.105316162109375 -0.7862487792968719 +0.909625 0.492950439453125 0.105316162109375 -0.7862487792968719 +0.9097500000000000768 0.492034912109375 0.105133056640625 -0.7862487792968719 +0.909875 0.4910888671875 0.10491943359375 -0.7862487792968719 +0.91 0.4910888671875 0.10491943359375 -0.7862487792968719 +0.910125000000000096 0.490081787109375 0.104705810546875 -0.7862487792968719 +0.91025 0.490081787109375 0.104705810546875 -0.7862487792968719 +0.910375 0.489013671875 0.104461669921875 -0.7862487792968719 +0.9105 0.487884521484375 0.104248046875 -0.7862487792968719 +0.910625 0.487884521484375 0.104248046875 -0.7862487792968719 +0.9107500000000000768 0.486724853515625 0.103973388671875 -0.7862487792968719 +0.910875 0.486724853515625 0.103973388671875 -0.7862487792968719 +0.911 0.485504150390625 0.103729248046875 -0.7862487792968719 +0.911125000000000096 0.484222412109375 0.10345458984375 -0.7862487792968719 +0.91125 0.484222412109375 0.10345458984375 -0.7862487792968719 +0.911375 0.48291015625 0.103179931640625 -0.7862487792968719 +0.9115 0.48291015625 0.103179931640625 -0.7862487792968719 +0.911625 0.48150634765625 0.102874755859375 -0.7862487792968719 +0.9117500000000000768 0.480072021484375 0.102569580078125 -0.7862487792968719 +0.911875 0.480072021484375 0.102569580078125 -0.7862487792968719 +0.912 0.478607177734375 0.10223388671875 -0.7862487792968719 +0.912125 0.478607177734375 0.10223388671875 -0.7862487792968719 +0.91225 0.47705078125 0.1019287109375 -0.7862487792968719 +0.912375 0.4754638671875 0.101593017578125 -0.7862487792968719 +0.9125 0.4754638671875 0.101593017578125 -0.7862487792968719 +0.912625 0.47381591796875 0.101226806640625 -0.7862487792968719 +0.9127500000000000768 0.47381591796875 0.101226806640625 -0.7862487792968719 +0.912875 0.472137451171875 0.100860595703125 -0.7862487792968719 +0.913 0.470367431640625 0.100494384765625 -0.7862487792968719 +0.913125 0.470367431640625 0.100494384765625 -0.7862487792968719 +0.91325 0.46856689453125 0.10009765625 -0.7862487792968719 +0.913375 0.46856689453125 0.10009765625 -0.7862487792968719 +0.9135 0.46673583984375 0.099700927734375 -0.7862487792968719 +0.913625 0.464813232421875 0.09930419921875 -0.7862487792968719 +0.9137500000000000768 0.464813232421875 0.09930419921875 -0.7862487792968719 +0.913875 0.462890625 0.098876953125 -0.7862487792968719 +0.914 0.462890625 0.098876953125 -0.7862487792968719 +0.914125 0.46087646484375 0.09844970703125 -0.7862487792968719 +0.91425 0.458831787109375 0.0980224609375 -0.7862487792968719 +0.914375 0.458831787109375 0.0980224609375 -0.7862487792968719 +0.9145 0.45672607421875 0.097564697265625 -0.7862487792968719 +0.914625 0.45672607421875 0.097564697265625 -0.7862487792968719 +0.9147500000000000768 0.454559326171875 0.09710693359375 -0.7862487792968719 +0.914875 0.452362060546875 0.096649169921875 -0.7862487792968719 +0.915 0.452362060546875 0.096649169921875 -0.7862487792968719 +0.915125 0.450103759765625 0.096160888671875 -0.7862487792968719 +0.91525 0.450103759765625 0.096160888671875 -0.7862487792968719 +0.915375 0.447784423828125 0.095672607421875 -0.7862487792968719 +0.9155 0.4454345703125 0.09515380859375 -0.7862487792968719 +0.915625 0.4454345703125 0.09515380859375 -0.7862487792968719 +0.9157500000000000768 0.44305419921875 0.09466552734375 -0.7862487792968719 +0.915875 0.44305419921875 0.09466552734375 -0.7862487792968719 +0.916 0.440582275390625 0.0941162109375 -0.7862487792968719 +0.916125 0.438079833984375 0.093597412109375 -0.7862487792968719 +0.91625 0.438079833984375 0.093597412109375 -0.7862487792968719 +0.916375 0.435546875 0.093048095703125 -0.7862487792968719 +0.9165 0.435546875 0.093048095703125 -0.7862487792968719 +0.916625 0.432952880859375 0.092498779296875 -0.7862487792968719 +0.9167500000000000768 0.4302978515625 0.0919189453125 -0.7862487792968719 +0.916875 0.4302978515625 0.0919189453125 -0.7862487792968719 +0.917 0.4276123046875 0.09136962890625 -0.7862487792968719 +0.917125 0.4276123046875 0.09136962890625 -0.7862487792968719 +0.91725 0.424896240234375 0.09075927734375 -0.7862487792968719 +0.917375 0.422119140625 0.090179443359375 -0.7862487792968719 +0.9175 0.422119140625 0.090179443359375 -0.7862487792968719 +0.917625 0.419281005859375 0.089569091796875 -0.7862487792968719 +0.9177500000000000768 0.419281005859375 0.089569091796875 -0.7862487792968719 +0.917875 0.416412353515625 0.088958740234375 -0.7862487792968719 +0.918 0.413482666015625 0.088348388671875 -0.7862487792968719 +0.918125 0.413482666015625 0.088348388671875 -0.7862487792968719 +0.91825 0.4105224609375 0.08770751953125 -0.7862487792968719 +0.918375 0.4105224609375 0.08770751953125 -0.7862487792968719 +0.9185 0.407501220703125 0.087066650390625 -0.7862487792968719 +0.918625 0.404449462890625 0.086395263671875 -0.7862487792968719 +0.9187500000000000768 0.404449462890625 0.086395263671875 -0.7862487792968719 +0.918875 0.401336669921875 0.08575439453125 -0.7862487792968719 +0.919 0.401336669921875 0.08575439453125 -0.7862487792968719 +0.919125 0.398193359375 0.0850830078125 -0.7862487792968719 +0.91925 0.39501953125 0.084381103515625 -0.7862487792968719 +0.919375 0.39501953125 0.084381103515625 -0.7862487792968719 +0.9195 0.39178466796875 0.083709716796875 -0.7862487792968719 +0.919625 0.39178466796875 0.083709716796875 -0.7862487792968719 +0.9197500000000000768 0.388519287109375 0.0830078125 -0.7862487792968719 +0.919875 0.38519287109375 0.082305908203125 -0.7862487792968719 +0.92 0.38519287109375 0.082305908203125 -0.7862487792968719 +0.920125 0.3818359375 0.081573486328125 -0.7862487792968719 +0.92025 0.3818359375 0.081573486328125 -0.7862487792968719 +0.920375 0.378448486328125 0.080841064453125 -0.7862487792968719 +0.9205 0.375 0.080108642578125 -0.7862487792968719 +0.920625 0.375 0.080108642578125 -0.7862487792968719 +0.9207500000000000768 0.37152099609375 0.079376220703125 -0.7862487792968719 +0.920875 0.37152099609375 0.079376220703125 -0.7862487792968719 +0.921 0.36798095703125 0.07861328125 -0.7862487792968719 +0.921125 0.36444091796875 0.077850341796875 -0.7862487792968719 +0.92125 0.36444091796875 0.077850341796875 -0.7862487792968719 +0.921375 0.360809326171875 0.07708740234375 -0.7862487792968719 +0.9215 0.360809326171875 0.07708740234375 -0.7862487792968719 +0.921625 0.357177734375 0.0762939453125 -0.7862487792968719 +0.9217500000000000768 0.353485107421875 0.075531005859375 -0.7862487792968719 +0.921875 0.353485107421875 0.075531005859375 -0.7862487792968719 +0.922 0.349761962890625 0.074737548828125 -0.7862487792968719 +0.922125 0.349761962890625 0.074737548828125 -0.7862487792968719 +0.92225 0.34600830078125 0.07391357421875 -0.7862487792968719 +0.922375000000000096 0.34222412109375 0.0731201171875 -0.7862487792968719 +0.9225 0.34222412109375 0.0731201171875 -0.7862487792968719 +0.922625 0.33837890625 0.072296142578125 -0.7862487792968719 +0.922750000000000096 0.33837890625 0.072296142578125 -0.7862487792968719 +0.922875 0.334503173828125 0.07147216796875 -0.7862487792968719 +0.923 0.330596923828125 0.07061767578125 -0.7862487792968719 +0.923125 0.330596923828125 0.07061767578125 -0.7862487792968719 +0.92325 0.32666015625 0.069793701171875 -0.7862487792968719 +0.923375000000000096 0.32666015625 0.069793701171875 -0.7862487792968719 +0.9235 0.322662353515625 0.068939208984375 -0.7862487792968719 +0.923625 0.31866455078125 0.068084716796875 -0.7862487792968719 +0.923750000000000096 0.31866455078125 0.068084716796875 -0.7862487792968719 +0.923875 0.314605712890625 0.06719970703125 -0.7862487792968719 +0.924 0.314605712890625 0.06719970703125 -0.7862487792968719 +0.924125 0.310516357421875 0.06634521484375 -0.7862487792968719 +0.92425 0.306396484375 0.065460205078125 -0.7862487792968719 +0.924375000000000096 0.306396484375 0.065460205078125 -0.7862487792968719 +0.9245 0.30224609375 0.0645751953125 -0.7862487792968719 +0.924625 0.30224609375 0.0645751953125 -0.7862487792968719 +0.924750000000000096 0.298065185546875 0.06365966796875 -0.7862487792968719 +0.924875 0.2938232421875 0.062774658203125 -0.7862487792968719 +0.925 0.2938232421875 0.062774658203125 -0.7862487792968719 +0.925125 0.289581298828125 0.061859130859375 -0.7862487792968719 +0.92525 0.289581298828125 0.061859130859375 -0.7862487792968719 +0.925375000000000096 0.285308837890625 0.060943603515625 -0.7862487792968719 +0.9255 0.280975341796875 0.060028076171875 -0.7862487792968719 +0.925625 0.280975341796875 0.060028076171875 -0.7862487792968719 +0.925750000000000096 0.276641845703125 0.05908203125 -0.7862487792968719 +0.925875 0.276641845703125 0.05908203125 -0.7862487792968719 +0.926 0.27227783203125 0.05816650390625 -0.7862487792968719 +0.926125 0.267852783203125 0.057220458984375 -0.7862487792968719 +0.92625 0.267852783203125 0.057220458984375 -0.7862487792968719 +0.926375000000000096 0.263427734375 0.0562744140625 -0.7862487792968719 +0.9265 0.263427734375 0.0562744140625 -0.7862487792968719 +0.926625 0.25897216796875 0.055328369140625 -0.7862487792968719 +0.926750000000000096 0.25445556640625 0.054351806640625 -0.7862487792968719 +0.926875 0.25445556640625 0.054351806640625 -0.7862487792968719 +0.927 0.249969482421875 0.05340576171875 -0.7862487792968719 +0.927125 0.249969482421875 0.05340576171875 -0.7862487792968719 +0.92725 0.24542236328125 0.05242919921875 -0.7862487792968719 +0.927375000000000096 0.2408447265625 0.05145263671875 -0.7862487792968719 +0.9275 0.2408447265625 0.05145263671875 -0.7862487792968719 +0.927625 0.236236572265625 0.05047607421875 -0.7862487792968719 +0.927750000000000096 0.236236572265625 0.05047607421875 -0.7862487792968719 +0.927875 0.231597900390625 0.049468994140625 -0.7862487792968719 +0.928 0.226959228515625 0.11761474609375 -0.481719970703120832 +0.928125 0.226959228515625 0.11761474609375 -0.481719970703120832 +0.92825 0.2222900390625 0.11517333984375 -0.481719970703120832 +0.928375000000000096 0.2222900390625 0.11517333984375 -0.481719970703120832 +0.9285 0.21759033203125 0.11273193359375 -0.481719970703120832 +0.928625 0.212860107421875 0.11029052734375 -0.481719970703120832 +0.92875 0.212860107421875 0.11029052734375 -0.481719970703120832 +0.928875 0.208099365234375 0.10784912109375 -0.481719970703120832 +0.929 0.208099365234375 0.10784912109375 -0.481719970703120832 +0.929125 0.203338623046875 0.1053466796875 -0.481719970703120832 +0.92925 0.19854736328125 0.102874755859375 -0.481719970703120832 +0.929375000000000096 0.19854736328125 0.102874755859375 -0.481719970703120832 +0.9295 0.1937255859375 0.100372314453125 -0.481719970703120832 +0.929625 0.1937255859375 0.100372314453125 -0.481719970703120832 +0.92975 0.188873291015625 0.097869873046875 -0.481719970703120832 +0.929875 0.18402099609375 0.095367431640625 -0.481719970703120832 +0.93 0.18402099609375 0.095367431640625 -0.481719970703120832 +0.930125 0.17913818359375 0.09283447265625 -0.481719970703120832 +0.93025 0.17913818359375 0.09283447265625 -0.481719970703120832 +0.930375000000000096 0.17425537109375 0.090301513671875 -0.481719970703120832 +0.9305 0.169342041015625 0.087738037109375 -0.481719970703120832 +0.930625 0.169342041015625 0.087738037109375 -0.481719970703120832 +0.93075 0.164398193359375 0.085174560546875 -0.481719970703120832 +0.930875 0.164398193359375 0.085174560546875 -0.481719970703120832 +0.931 0.159454345703125 0.082611083984375 -0.481719970703120832 +0.931125 0.15447998046875 0.080047607421875 -0.481719970703120832 +0.93125 0.15447998046875 0.080047607421875 -0.481719970703120832 +0.931375000000000096 0.14947509765625 0.07745361328125 -0.481719970703120832 +0.9315 0.14947509765625 0.07745361328125 -0.481719970703120832 +0.931625 0.14447021484375 0.074859619140625 -0.481719970703120832 +0.93175 0.13946533203125 0.072265625 -0.481719970703120832 +0.931875 0.13946533203125 0.072265625 -0.481719970703120832 +0.932 0.134429931640625 0.06964111328125 -0.481719970703120832 +0.932125 0.134429931640625 0.06964111328125 -0.481719970703120832 +0.93225 0.129364013671875 0.067047119140625 -0.481719970703120832 +0.932375000000000096 0.124298095703125 0.064422607421875 -0.481719970703120832 +0.9325 0.124298095703125 0.064422607421875 -0.481719970703120832 +0.932625 0.119232177734375 0.061798095703125 -0.481719970703120832 +0.93275 0.119232177734375 0.061798095703125 -0.481719970703120832 +0.932875 0.1141357421875 0.05914306640625 -0.481719970703120832 +0.933 0.109039306640625 0.056488037109375 -0.481719970703120832 +0.933125 0.109039306640625 0.056488037109375 -0.481719970703120832 +0.93325 0.103912353515625 0.0538330078125 -0.481719970703120832 +0.933375000000000096 0.103912353515625 0.0538330078125 -0.481719970703120832 +0.9335 0.098785400390625 0.051177978515625 -0.481719970703120832 +0.933625 0.093658447265625 0.04852294921875 -0.481719970703120832 +0.93375 0.093658447265625 0.04852294921875 -0.481719970703120832 +0.933875 0.0885009765625 0.045867919921875 -0.481719970703120832 +0.934 0.0885009765625 0.045867919921875 -0.481719970703120832 +0.934125 0.083343505859375 0.043182373046875 -0.481719970703120832 +0.93425 0.07818603515625 0.040496826171875 -0.481719970703120832 +0.934375000000000096 0.07818603515625 0.040496826171875 -0.481719970703120832 +0.9345 0.072998046875 0.037841796875 -0.481719970703120832 +0.934625 0.072998046875 0.037841796875 -0.481719970703120832 +0.93475 0.06781005859375 0.035125732421875 -0.481719970703120832 +0.934875 0.0626220703125 0.032440185546875 -0.481719970703120832 +0.935 0.0626220703125 0.032440185546875 -0.481719970703120832 +0.935125 0.05743408203125 0.029754638671875 -0.481719970703120832 +0.93525 0.05743408203125 0.029754638671875 -0.481719970703120832 +0.935375000000000096 0.05224609375 0.027069091796875 -0.481719970703120832 +0.9355 0.047027587890625 0.02435302734375 -0.481719970703120832 +0.935625 0.047027587890625 0.02435302734375 -0.481719970703120832 +0.93575 0.04180908203125 0.02166748046875 -0.481719970703120832 +0.935875 0.04180908203125 0.02166748046875 -0.481719970703120832 +0.936 0.036590576171875 0.018951416015625 -0.481719970703120832 +0.936125 0.0313720703125 0.0162353515625 -0.481719970703120832 +0.93625 0.0313720703125 0.0162353515625 -0.481719970703120832 +0.936375000000000096 0.026123046875 0.0135498046875 -0.481719970703120832 +0.9365 0.026123046875 0.0135498046875 -0.481719970703120832 +0.936625 0.020904541015625 0.010833740234375 -0.481719970703120832 +0.93675 0.01568603515625 0.00811767578125 -0.481719970703120832 +0.936875 0.01568603515625 0.00811767578125 -0.481719970703120832 +0.937 0.01043701171875 0.005401611328125 -0.481719970703120832 +0.937125 0.01043701171875 0.005401611328125 -0.481719970703120832 +0.93725 0.005218505859375 0.002685546875 -0.481719970703120832 +0.937375000000000096 0.0 0.0 -0.481719970703120832 +0.9375 0.0 0.0 -0.481719970703120832 +0.937625 -0.005218505859375 -0.002685546875 -0.481719970703120832 +0.93775 -0.005218505859375 -0.002685546875 -0.481719970703120832 +0.937875 -0.01043701171875 -0.005401611328125 -0.481719970703120832 +0.938000000000000096 -0.01568603515625 -0.00811767578125 -0.481719970703120832 +0.938125 -0.01568603515625 -0.00811767578125 -0.481719970703120832 +0.93825 -0.020904541015625 -0.010833740234375 -0.481719970703120832 +0.938375000000000096 -0.020904541015625 -0.010833740234375 -0.481719970703120832 +0.9385 -0.026123046875 -0.0135498046875 -0.481719970703120832 +0.938625 -0.0313720703125 -0.0162353515625 -0.481719970703120832 +0.93875 -0.0313720703125 -0.0162353515625 -0.481719970703120832 +0.938875 -0.036590576171875 -0.018951416015625 -0.481719970703120832 +0.939000000000000096 -0.036590576171875 -0.018951416015625 -0.481719970703120832 +0.939125 -0.04180908203125 -0.02166748046875 -0.481719970703120832 +0.93925 -0.047027587890625 -0.02435302734375 -0.481719970703120832 +0.939375000000000096 -0.047027587890625 -0.02435302734375 -0.481719970703120832 +0.9395 -0.05224609375 -0.027069091796875 -0.481719970703120832 +0.939625 -0.05224609375 -0.027069091796875 -0.481719970703120832 +0.93975 -0.05743408203125 -0.029754638671875 -0.481719970703120832 +0.939875 -0.0626220703125 -0.032440185546875 -0.481719970703120832 +0.940000000000000096 -0.0626220703125 -0.032440185546875 -0.481719970703120832 +0.940125 -0.06781005859375 -0.035125732421875 -0.481719970703120832 +0.94025 -0.06781005859375 -0.035125732421875 -0.481719970703120832 +0.940375000000000096 -0.072998046875 -0.037841796875 -0.481719970703120832 +0.9405 -0.07818603515625 -0.040496826171875 -0.481719970703120832 +0.940625 -0.07818603515625 -0.040496826171875 -0.481719970703120832 +0.94075 -0.083343505859375 -0.043182373046875 -0.481719970703120832 +0.940875 -0.083343505859375 -0.043182373046875 -0.481719970703120832 +0.941000000000000096 -0.0885009765625 -0.045867919921875 -0.481719970703120832 +0.941125 -0.093658447265625 -0.04852294921875 -0.481719970703120832 +0.94125 -0.093658447265625 -0.04852294921875 -0.481719970703120832 +0.941375000000000096 -0.098785400390625 -0.051177978515625 -0.481719970703120832 +0.9415 -0.098785400390625 -0.051177978515625 -0.481719970703120832 +0.941625 -0.103912353515625 -0.0538330078125 -0.481719970703120832 +0.94175 -0.109039306640625 -0.056488037109375 -0.481719970703120832 +0.941875 -0.109039306640625 -0.056488037109375 -0.481719970703120832 +0.942000000000000096 -0.1141357421875 -0.05914306640625 -0.481719970703120832 +0.942125 -0.1141357421875 -0.05914306640625 -0.481719970703120832 +0.94225 -0.119232177734375 -0.061798095703125 -0.481719970703120832 +0.942375000000000096 -0.124298095703125 -0.064422607421875 -0.481719970703120832 +0.9425 -0.124298095703125 -0.064422607421875 -0.481719970703120832 +0.942625 -0.129364013671875 -0.067047119140625 -0.481719970703120832 +0.94275 -0.129364013671875 -0.067047119140625 -0.481719970703120832 +0.942875 -0.134429931640625 -0.06964111328125 -0.481719970703120832 +0.943000000000000096 -0.13946533203125 -0.072265625 -0.481719970703120832 +0.943125 -0.13946533203125 -0.072265625 -0.481719970703120832 +0.94325 -0.14447021484375 -0.074859619140625 -0.481719970703120832 +0.943375000000000096 -0.14447021484375 -0.074859619140625 -0.481719970703120832 +0.9435 -0.14947509765625 -0.07745361328125 -0.481719970703120832 +0.943625 -0.15447998046875 -0.080047607421875 -0.481719970703120832 +0.94375 -0.15447998046875 -0.080047607421875 -0.481719970703120832 +0.943875 -0.159454345703125 -0.082611083984375 -0.481719970703120832 +0.944000000000000096 -0.159454345703125 -0.082611083984375 -0.481719970703120832 +0.944125 -0.164398193359375 -0.085174560546875 -0.481719970703120832 +0.94425 -0.169342041015625 -0.087738037109375 -0.481719970703120832 +0.944375 -0.169342041015625 -0.087738037109375 -0.481719970703120832 +0.9445 -0.17425537109375 -0.090301513671875 -0.481719970703120832 +0.944625 -0.17425537109375 -0.090301513671875 -0.481719970703120832 +0.94475 -0.17913818359375 -0.09283447265625 -0.481719970703120832 +0.944875 -0.18402099609375 -0.095367431640625 -0.481719970703120832 +0.945000000000000096 -0.18402099609375 -0.095367431640625 -0.481719970703120832 +0.945125 -0.188873291015625 -0.097869873046875 -0.481719970703120832 +0.94525 -0.188873291015625 -0.097869873046875 -0.481719970703120832 +0.945375 -0.1937255859375 -0.100372314453125 -0.481719970703120832 +0.9455 -0.19854736328125 -0.102874755859375 -0.481719970703120832 +0.945625 -0.19854736328125 -0.102874755859375 -0.481719970703120832 +0.94575 -0.203338623046875 -0.1053466796875 -0.481719970703120832 +0.945875 -0.203338623046875 -0.1053466796875 -0.481719970703120832 +0.946000000000000096 -0.208099365234375 -0.10784912109375 -0.481719970703120832 +0.946125 -0.212860107421875 -0.11029052734375 -0.481719970703120832 +0.94625 -0.212860107421875 -0.11029052734375 -0.481719970703120832 +0.946375 -0.21759033203125 -0.11273193359375 -0.481719970703120832 +0.9465 -0.21759033203125 -0.11273193359375 -0.481719970703120832 +0.946625 -0.2222900390625 -0.11517333984375 -0.481719970703120832 +0.94675 -0.226959228515625 -0.11761474609375 -0.481719970703120832 +0.946875 -0.226959228515625 -0.11761474609375 -0.481719970703120832 +0.947000000000000096 -0.231597900390625 -0.120025634765625 -0.481719970703120832 +0.947125 -0.231597900390625 -0.120025634765625 -0.481719970703120832 +0.94725 -0.236236572265625 -0.122406005859375 -0.481719970703120832 +0.947375 -0.2408447265625 -0.124786376953125 -0.481719970703120832 +0.9475 -0.2408447265625 -0.124786376953125 -0.481719970703120832 +0.947625 -0.24542236328125 -0.127166748046875 -0.481719970703120832 +0.94775 -0.24542236328125 -0.127166748046875 -0.481719970703120832 +0.947875 -0.249969482421875 -0.1295166015625 -0.481719970703120832 +0.948000000000000096 -0.25445556640625 -0.131866455078125 -0.481719970703120832 +0.948125 -0.25445556640625 -0.131866455078125 -0.481719970703120832 +0.94825 -0.25897216796875 -0.134185791015625 -0.481719970703120832 +0.948375 -0.25897216796875 -0.134185791015625 -0.481719970703120832 +0.9485 -0.263427734375 -0.136505126953125 -0.481719970703120832 +0.948625 -0.267852783203125 -0.1387939453125 -0.481719970703120832 +0.94875 -0.267852783203125 -0.1387939453125 -0.481719970703120832 +0.948875 -0.27227783203125 -0.141082763671875 -0.481719970703120832 +0.949000000000000096 -0.27227783203125 -0.141082763671875 -0.481719970703120832 +0.949125 -0.276641845703125 -0.143341064453125 -0.481719970703120832 +0.94925 -0.280975341796875 -0.145599365234375 -0.481719970703120832 +0.949375 -0.280975341796875 -0.145599365234375 -0.481719970703120832 +0.9495 -0.285308837890625 -0.147857666015625 -0.481719970703120832 +0.949625 -0.285308837890625 -0.147857666015625 -0.481719970703120832 +0.94975 -0.289581298828125 -0.150054931640625 -0.481719970703120832 +0.949875 -0.2938232421875 -0.152252197265625 -0.481719970703120832 +0.950000000000000096 -0.2938232421875 -0.152252197265625 -0.481719970703120832 +0.950125 -0.298065185546875 -0.154449462890625 -0.481719970703120832 +0.95025 -0.298065185546875 -0.154449462890625 -0.481719970703120832 +0.950375 -0.30224609375 -0.1566162109375 -0.481719970703120832 +0.9505 -0.306396484375 -0.158782958984375 -0.481719970703120832 +0.950625 -0.306396484375 -0.158782958984375 -0.481719970703120832 +0.95075 -0.310516357421875 -0.160919189453125 -0.481719970703120832 +0.950875 -0.310516357421875 -0.160919189453125 -0.481719970703120832 +0.951000000000000096 -0.314605712890625 -0.16302490234375 -0.481719970703120832 +0.951125 -0.31866455078125 -0.165130615234375 -0.481719970703120832 +0.95125 -0.31866455078125 -0.165130615234375 -0.481719970703120832 +0.951375 -0.322662353515625 -0.167205810546875 -0.481719970703120832 +0.9515 -0.322662353515625 -0.167205810546875 -0.481719970703120832 +0.951625 -0.32666015625 -0.169281005859375 -0.481719970703120832 +0.95175 -0.330596923828125 -0.17132568359375 -0.481719970703120832 +0.951875 -0.330596923828125 -0.17132568359375 -0.481719970703120832 +0.952000000000000096 -0.334503173828125 -0.17333984375 -0.481719970703120832 +0.952125 -0.334503173828125 -0.17333984375 -0.481719970703120832 +0.95225 -0.33837890625 -0.17535400390625 -0.481719970703120832 +0.952375 -0.34222412109375 -0.177337646484375 -0.481719970703120832 +0.9525 -0.34222412109375 -0.177337646484375 -0.481719970703120832 +0.952625 -0.34600830078125 -0.179290771484375 -0.481719970703120832 +0.95275 -0.34600830078125 -0.179290771484375 -0.481719970703120832 +0.952875 -0.349761962890625 -0.181243896484375 -0.481719970703120832 +0.953000000000000096 -0.353485107421875 -0.18316650390625 -0.481719970703120832 +0.953125 -0.353485107421875 -0.18316650390625 -0.481719970703120832 +0.95325 -0.357177734375 -0.185089111328125 -0.481719970703120832 +0.953375 -0.357177734375 -0.185089111328125 -0.481719970703120832 +0.9535 -0.360809326171875 -0.186981201171875 -0.481719970703120832 +0.953625000000000096 -0.36444091796875 -0.1888427734375 -0.481719970703120832 +0.95375 -0.36444091796875 -0.1888427734375 -0.481719970703120832 +0.953875 -0.36798095703125 -0.190704345703125 -0.481719970703120832 +0.954000000000000096 -0.36798095703125 -0.190704345703125 -0.481719970703120832 +0.954125 -0.37152099609375 -0.1925048828125 -0.481719970703120832 +0.95425 -0.375 -0.1943359375 -0.481719970703120832 +0.954375 -0.375 -0.1943359375 -0.481719970703120832 +0.9545 -0.378448486328125 -0.19610595703125 -0.481719970703120832 +0.954625000000000096 -0.378448486328125 -0.19610595703125 -0.481719970703120832 +0.95475 -0.3818359375 -0.1978759765625 -0.481719970703120832 +0.954875 -0.38519287109375 -0.199615478515625 -0.481719970703120832 +0.955000000000000096 -0.38519287109375 -0.199615478515625 -0.481719970703120832 +0.955125 -0.388519287109375 -0.201324462890625 -0.481719970703120832 +0.95525 -0.388519287109375 -0.201324462890625 -0.481719970703120832 +0.955375 -0.39178466796875 -0.203033447265625 -0.481719970703120832 +0.9555 -0.39501953125 -0.2047119140625 -0.481719970703120832 +0.955625000000000096 -0.39501953125 -0.2047119140625 -0.481719970703120832 +0.95575 -0.398193359375 -0.20635986328125 -0.481719970703120832 +0.955875 -0.398193359375 -0.20635986328125 -0.481719970703120832 +0.956000000000000096 -0.401336669921875 -0.207977294921875 -0.481719970703120832 +0.956125 -0.404449462890625 -0.2095947265625 -0.481719970703120832 +0.95625 -0.404449462890625 -0.2095947265625 -0.481719970703120832 +0.956375 -0.407501220703125 -0.211181640625 -0.481719970703120832 +0.9565 -0.407501220703125 -0.211181640625 -0.481719970703120832 +0.956625000000000096 -0.4105224609375 -0.212738037109375 -0.481719970703120832 +0.95675 -0.413482666015625 -0.214263916015625 -0.481719970703120832 +0.956875 -0.413482666015625 -0.214263916015625 -0.481719970703120832 +0.957000000000000096 -0.416412353515625 -0.215789794921875 -0.481719970703120832 +0.957125 -0.416412353515625 -0.215789794921875 -0.481719970703120832 +0.95725 -0.419281005859375 -0.217254638671875 -0.481719970703120832 +0.957375 -0.422119140625 -0.21875 -0.481719970703120832 +0.9575 -0.422119140625 -0.21875 -0.481719970703120832 +0.957625000000000096 -0.424896240234375 -0.220184326171875 -0.481719970703120832 +0.95775 -0.424896240234375 -0.220184326171875 -0.481719970703120832 +0.957875 -0.4276123046875 -0.221588134765625 -0.481719970703120832 +0.958000000000000096 -0.4302978515625 -0.222991943359375 -0.481719970703120832 +0.958125 -0.4302978515625 -0.222991943359375 -0.481719970703120832 +0.95825 -0.432952880859375 -0.224365234375 -0.481719970703120832 +0.958375 -0.432952880859375 -0.224365234375 -0.481719970703120832 +0.9585 -0.435546875 -0.2257080078125 -0.481719970703120832 +0.958625000000000096 -0.438079833984375 -0.227020263671875 -0.481719970703120832 +0.95875 -0.438079833984375 -0.227020263671875 -0.481719970703120832 +0.958875 -0.440582275390625 -0.228302001953125 -0.481719970703120832 +0.959000000000000096 -0.440582275390625 -0.228302001953125 -0.481719970703120832 +0.959125 -0.44305419921875 -0.229583740234375 -0.481719970703120832 +0.95925 -0.4454345703125 -0.2308349609375 -0.481719970703120832 +0.959375 -0.4454345703125 -0.2308349609375 -0.481719970703120832 +0.9595 -0.447784423828125 -0.2320556640625 -0.481719970703120832 +0.959625000000000096 -0.447784423828125 -0.2320556640625 -0.481719970703120832 +0.95975 -0.450103759765625 -0.233245849609375 -0.481719970703120832 +0.959875 -0.452362060546875 -0.234405517578125 -0.481719970703120832 +0.96 -0.452362060546875 -0.406951904296875 -0.1003479003906193 +0.960125 -0.454559326171875 -0.408905029296875 -0.1003479003906193 +0.96025 -0.454559326171875 -0.408905029296875 -0.1003479003906193 +0.960375 -0.45672607421875 -0.410858154296875 -0.1003479003906193 +0.9605 -0.458831787109375 -0.412750244140625 -0.1003479003906193 +0.960625000000000096 -0.458831787109375 -0.412750244140625 -0.1003479003906193 +0.96075 -0.46087646484375 -0.41461181640625 -0.1003479003906193 +0.960875 -0.46087646484375 -0.41461181640625 -0.1003479003906193 +0.961 -0.462890625 -0.416412353515625 -0.1003479003906193 +0.961125 -0.464813232421875 -0.41815185546875 -0.1003479003906193 +0.96125 -0.464813232421875 -0.41815185546875 -0.1003479003906193 +0.961375 -0.46673583984375 -0.41986083984375 -0.1003479003906193 +0.9615 -0.46673583984375 -0.41986083984375 -0.1003479003906193 +0.961625000000000096 -0.46856689453125 -0.421539306640625 -0.1003479003906193 +0.96175 -0.470367431640625 -0.42315673828125 -0.1003479003906193 +0.961875 -0.470367431640625 -0.42315673828125 -0.1003479003906193 +0.962 -0.472137451171875 -0.42474365234375 -0.1003479003906193 +0.962125 -0.472137451171875 -0.42474365234375 -0.1003479003906193 +0.96225 -0.47381591796875 -0.42626953125 -0.1003479003906193 +0.962375 -0.4754638671875 -0.427734375 -0.1003479003906193 +0.9625 -0.4754638671875 -0.427734375 -0.1003479003906193 +0.962625000000000096 -0.47705078125 -0.429168701171875 -0.1003479003906193 +0.96275 -0.47705078125 -0.429168701171875 -0.1003479003906193 +0.962875 -0.478607177734375 -0.4305419921875 -0.1003479003906193 +0.963 -0.480072021484375 -0.431884765625 -0.1003479003906193 +0.963125 -0.480072021484375 -0.431884765625 -0.1003479003906193 +0.96325 -0.48150634765625 -0.43316650390625 -0.1003479003906193 +0.963375 -0.48150634765625 -0.43316650390625 -0.1003479003906193 +0.9635 -0.48291015625 -0.434417724609375 -0.1003479003906193 +0.963625000000000096 -0.484222412109375 -0.43560791015625 -0.1003479003906193 +0.96375 -0.484222412109375 -0.43560791015625 -0.1003479003906193 +0.963875 -0.485504150390625 -0.436767578125 -0.1003479003906193 +0.964 -0.485504150390625 -0.436767578125 -0.1003479003906193 +0.964125 -0.486724853515625 -0.4378662109375 -0.1003479003906193 +0.96425 -0.487884521484375 -0.43890380859375 -0.1003479003906193 +0.964375 -0.487884521484375 -0.43890380859375 -0.1003479003906193 +0.9645 -0.489013671875 -0.439910888671875 -0.1003479003906193 +0.964625000000000096 -0.489013671875 -0.439910888671875 -0.1003479003906193 +0.96475 -0.490081787109375 -0.440887451171875 -0.1003479003906193 +0.964875 -0.4910888671875 -0.4417724609375 -0.1003479003906193 +0.965 -0.4910888671875 -0.4417724609375 -0.1003479003906193 +0.965125 -0.492034912109375 -0.442657470703125 -0.1003479003906193 +0.96525 -0.492034912109375 -0.442657470703125 -0.1003479003906193 +0.965375 -0.492950439453125 -0.443450927734375 -0.1003479003906193 +0.9655 -0.4937744140625 -0.4442138671875 -0.1003479003906193 +0.965625000000000096 -0.4937744140625 -0.4442138671875 -0.1003479003906193 +0.96575 -0.49456787109375 -0.444915771484375 -0.1003479003906193 +0.965875 -0.49456787109375 -0.444915771484375 -0.1003479003906193 +0.966 -0.49530029296875 -0.445587158203125 -0.1003479003906193 +0.966125 -0.496002197265625 -0.446197509765625 -0.1003479003906193 +0.96625 -0.496002197265625 -0.446197509765625 -0.1003479003906193 +0.966375 -0.496612548828125 -0.446746826171875 -0.1003479003906193 +0.9665 -0.496612548828125 -0.446746826171875 -0.1003479003906193 +0.966625000000000096 -0.4971923828125 -0.447296142578125 -0.1003479003906193 +0.96675 -0.497711181640625 -0.44775390625 -0.1003479003906193 +0.966875 -0.497711181640625 -0.44775390625 -0.1003479003906193 +0.967 -0.498199462890625 -0.44818115234375 -0.1003479003906193 +0.967125 -0.498199462890625 -0.44818115234375 -0.1003479003906193 +0.96725 -0.49859619140625 -0.44854736328125 -0.1003479003906193 +0.967375 -0.49896240234375 -0.4488525390625 -0.1003479003906193 +0.9675 -0.49896240234375 -0.4488525390625 -0.1003479003906193 +0.967625000000000096 -0.499267578125 -0.449127197265625 -0.1003479003906193 +0.96775 -0.499267578125 -0.449127197265625 -0.1003479003906193 +0.967875 -0.49951171875 -0.449371337890625 -0.1003479003906193 +0.968 -0.49969482421875 -0.44952392578125 -0.1003479003906193 +0.968125 -0.49969482421875 -0.44952392578125 -0.1003479003906193 +0.96825 -0.49981689453125 -0.44964599609375 -0.1003479003906193 +0.968375 -0.49981689453125 -0.44964599609375 -0.1003479003906193 +0.9685 -0.499908447265625 -0.449737548828125 -0.1003479003906193 +0.968625000000000096 -0.49993896484375 -0.44976806640625 -0.1003479003906193 +0.96875 -0.49993896484375 -0.44976806640625 -0.1003479003906193 +0.968875 -0.499908447265625 -0.449737548828125 -0.1003479003906193 +0.969 -0.499908447265625 -0.449737548828125 -0.1003479003906193 +0.969125 -0.49981689453125 -0.44964599609375 -0.1003479003906193 +0.969250000000000096 -0.49969482421875 -0.44952392578125 -0.1003479003906193 +0.969375 -0.49969482421875 -0.44952392578125 -0.1003479003906193 +0.9695 -0.49951171875 -0.449371337890625 -0.1003479003906193 +0.969625000000000096 -0.49951171875 -0.449371337890625 -0.1003479003906193 +0.96975 -0.499267578125 -0.449127197265625 -0.1003479003906193 +0.969875 -0.49896240234375 -0.4488525390625 -0.1003479003906193 +0.97 -0.49896240234375 -0.4488525390625 -0.1003479003906193 +0.970125 -0.49859619140625 -0.44854736328125 -0.1003479003906193 +0.970250000000000096 -0.49859619140625 -0.44854736328125 -0.1003479003906193 +0.970375 -0.498199462890625 -0.44818115234375 -0.1003479003906193 +0.9705 -0.497711181640625 -0.44775390625 -0.1003479003906193 +0.970625000000000096 -0.497711181640625 -0.44775390625 -0.1003479003906193 +0.97075 -0.4971923828125 -0.447296142578125 -0.1003479003906193 +0.970875 -0.4971923828125 -0.447296142578125 -0.1003479003906193 +0.971 -0.496612548828125 -0.446746826171875 -0.1003479003906193 +0.971125 -0.496002197265625 -0.446197509765625 -0.1003479003906193 +0.971250000000000096 -0.496002197265625 -0.446197509765625 -0.1003479003906193 +0.971375 -0.49530029296875 -0.445587158203125 -0.1003479003906193 +0.9715 -0.49530029296875 -0.445587158203125 -0.1003479003906193 +0.971625000000000096 -0.49456787109375 -0.444915771484375 -0.1003479003906193 +0.97175 -0.4937744140625 -0.4442138671875 -0.1003479003906193 +0.971875 -0.4937744140625 -0.4442138671875 -0.1003479003906193 +0.972 -0.492950439453125 -0.443450927734375 -0.1003479003906193 +0.972125 -0.492950439453125 -0.443450927734375 -0.1003479003906193 +0.972250000000000096 -0.492034912109375 -0.442657470703125 -0.1003479003906193 +0.972375 -0.4910888671875 -0.4417724609375 -0.1003479003906193 +0.9725 -0.4910888671875 -0.4417724609375 -0.1003479003906193 +0.972625000000000096 -0.490081787109375 -0.440887451171875 -0.1003479003906193 +0.97275 -0.490081787109375 -0.440887451171875 -0.1003479003906193 +0.972875 -0.489013671875 -0.439910888671875 -0.1003479003906193 +0.973 -0.487884521484375 -0.43890380859375 -0.1003479003906193 +0.973125 -0.487884521484375 -0.43890380859375 -0.1003479003906193 +0.973250000000000096 -0.486724853515625 -0.4378662109375 -0.1003479003906193 +0.973375 -0.486724853515625 -0.4378662109375 -0.1003479003906193 +0.9735 -0.485504150390625 -0.436767578125 -0.1003479003906193 +0.973625000000000096 -0.484222412109375 -0.43560791015625 -0.1003479003906193 +0.97375 -0.484222412109375 -0.43560791015625 -0.1003479003906193 +0.973875 -0.48291015625 -0.434417724609375 -0.1003479003906193 +0.974 -0.48291015625 -0.434417724609375 -0.1003479003906193 +0.974125 -0.48150634765625 -0.43316650390625 -0.1003479003906193 +0.974250000000000096 -0.480072021484375 -0.431884765625 -0.1003479003906193 +0.974375 -0.480072021484375 -0.431884765625 -0.1003479003906193 +0.9745 -0.478607177734375 -0.4305419921875 -0.1003479003906193 +0.974625000000000096 -0.478607177734375 -0.4305419921875 -0.1003479003906193 +0.97475 -0.47705078125 -0.429168701171875 -0.1003479003906193 +0.974875 -0.4754638671875 -0.427734375 -0.1003479003906193 +0.975 -0.4754638671875 -0.427734375 -0.1003479003906193 +0.975125 -0.47381591796875 -0.42626953125 -0.1003479003906193 +0.975250000000000096 -0.47381591796875 -0.42626953125 -0.1003479003906193 +0.975375 -0.472137451171875 -0.42474365234375 -0.1003479003906193 +0.9755 -0.470367431640625 -0.42315673828125 -0.1003479003906193 +0.975625000000000096 -0.470367431640625 -0.42315673828125 -0.1003479003906193 +0.97575 -0.46856689453125 -0.421539306640625 -0.1003479003906193 +0.975875 -0.46856689453125 -0.421539306640625 -0.1003479003906193 +0.976 -0.46673583984375 -0.41986083984375 -0.1003479003906193 +0.976125 -0.464813232421875 -0.41815185546875 -0.1003479003906193 +0.976250000000000096 -0.464813232421875 -0.41815185546875 -0.1003479003906193 +0.976375 -0.462890625 -0.416412353515625 -0.1003479003906193 +0.9765 -0.462890625 -0.416412353515625 -0.1003479003906193 +0.976625 -0.46087646484375 -0.41461181640625 -0.1003479003906193 +0.97675 -0.458831787109375 -0.412750244140625 -0.1003479003906193 +0.976875 -0.458831787109375 -0.412750244140625 -0.1003479003906193 +0.977 -0.45672607421875 -0.410858154296875 -0.1003479003906193 +0.977125 -0.45672607421875 -0.410858154296875 -0.1003479003906193 +0.977250000000000096 -0.454559326171875 -0.408905029296875 -0.1003479003906193 +0.977375 -0.452362060546875 -0.406951904296875 -0.1003479003906193 +0.9775 -0.452362060546875 -0.406951904296875 -0.1003479003906193 +0.977625 -0.450103759765625 -0.4049072265625 -0.1003479003906193 +0.97775 -0.450103759765625 -0.4049072265625 -0.1003479003906193 +0.977875 -0.447784423828125 -0.40283203125 -0.1003479003906193 +0.978 -0.4454345703125 -0.400726318359375 -0.1003479003906193 +0.978125 -0.4454345703125 -0.400726318359375 -0.1003479003906193 +0.978250000000000096 -0.44305419921875 -0.3985595703125 -0.1003479003906193 +0.978375 -0.44305419921875 -0.3985595703125 -0.1003479003906193 +0.9785 -0.440582275390625 -0.3963623046875 -0.1003479003906193 +0.978625 -0.438079833984375 -0.39410400390625 -0.1003479003906193 +0.97875 -0.438079833984375 -0.39410400390625 -0.1003479003906193 +0.978875 -0.435546875 -0.391815185546875 -0.1003479003906193 +0.979 -0.435546875 -0.391815185546875 -0.1003479003906193 +0.979125 -0.432952880859375 -0.389495849609375 -0.1003479003906193 +0.979250000000000096 -0.4302978515625 -0.387115478515625 -0.1003479003906193 +0.979375 -0.4302978515625 -0.387115478515625 -0.1003479003906193 +0.9795 -0.4276123046875 -0.38470458984375 -0.1003479003906193 +0.979625 -0.4276123046875 -0.38470458984375 -0.1003479003906193 +0.97975 -0.424896240234375 -0.382232666015625 -0.1003479003906193 +0.979875 -0.422119140625 -0.379730224609375 -0.1003479003906193 +0.98 -0.422119140625 -0.379730224609375 -0.1003479003906193 +0.980125 -0.419281005859375 -0.377197265625 -0.1003479003906193 +0.980250000000000096 -0.419281005859375 -0.377197265625 -0.1003479003906193 +0.980375 -0.416412353515625 -0.374603271484375 -0.1003479003906193 +0.9805 -0.413482666015625 -0.371978759765625 -0.1003479003906193 +0.980625 -0.413482666015625 -0.371978759765625 -0.1003479003906193 +0.98075 -0.4105224609375 -0.369293212890625 -0.1003479003906193 +0.980875 -0.4105224609375 -0.369293212890625 -0.1003479003906193 +0.981 -0.407501220703125 -0.366607666015625 -0.1003479003906193 +0.981125 -0.404449462890625 -0.363861083984375 -0.1003479003906193 +0.981250000000000096 -0.404449462890625 -0.363861083984375 -0.1003479003906193 +0.981375 -0.401336669921875 -0.361053466796875 -0.1003479003906193 +0.9815 -0.401336669921875 -0.361053466796875 -0.1003479003906193 +0.981625 -0.398193359375 -0.35821533203125 -0.1003479003906193 +0.98175 -0.39501953125 -0.355377197265625 -0.1003479003906193 +0.981875 -0.39501953125 -0.355377197265625 -0.1003479003906193 +0.982 -0.39178466796875 -0.352447509765625 -0.1003479003906193 +0.982125 -0.39178466796875 -0.352447509765625 -0.1003479003906193 +0.982250000000000096 -0.388519287109375 -0.349517822265625 -0.1003479003906193 +0.982375 -0.38519287109375 -0.346527099609375 -0.1003479003906193 +0.9825 -0.38519287109375 -0.346527099609375 -0.1003479003906193 +0.982625 -0.3818359375 -0.343505859375 -0.1003479003906193 +0.98275 -0.3818359375 -0.343505859375 -0.1003479003906193 +0.982875 -0.378448486328125 -0.3404541015625 -0.1003479003906193 +0.983 -0.375 -0.33734130859375 -0.1003479003906193 +0.983125 -0.375 -0.33734130859375 -0.1003479003906193 +0.983250000000000096 -0.37152099609375 -0.334228515625 -0.1003479003906193 +0.983375 -0.37152099609375 -0.334228515625 -0.1003479003906193 +0.9835 -0.36798095703125 -0.3310546875 -0.1003479003906193 +0.983625 -0.36444091796875 -0.327850341796875 -0.1003479003906193 +0.98375 -0.36444091796875 -0.327850341796875 -0.1003479003906193 +0.983875 -0.360809326171875 -0.3245849609375 -0.1003479003906193 +0.984 -0.360809326171875 -0.3245849609375 -0.1003479003906193 +0.984125 -0.357177734375 -0.321319580078125 -0.1003479003906193 +0.984250000000000096 -0.353485107421875 -0.318023681640625 -0.1003479003906193 +0.984375 -0.353485107421875 -0.318023681640625 -0.1003479003906193 +0.9845 -0.349761962890625 -0.314666748046875 -0.1003479003906193 +0.984625 -0.349761962890625 -0.314666748046875 -0.1003479003906193 +0.98475 -0.34600830078125 -0.311279296875 -0.1003479003906193 +0.984875000000000096 -0.34222412109375 -0.307861328125 -0.1003479003906193 +0.985 -0.34222412109375 -0.307861328125 -0.1003479003906193 +0.985125 -0.33837890625 -0.304412841796875 -0.1003479003906193 +0.985250000000000096 -0.33837890625 -0.304412841796875 -0.1003479003906193 +0.985375 -0.334503173828125 -0.300933837890625 -0.1003479003906193 +0.9855 -0.330596923828125 -0.29742431640625 -0.1003479003906193 +0.985625 -0.330596923828125 -0.29742431640625 -0.1003479003906193 +0.98575 -0.32666015625 -0.293853759765625 -0.1003479003906193 +0.985875000000000096 -0.32666015625 -0.293853759765625 -0.1003479003906193 +0.986 -0.322662353515625 -0.290283203125 -0.1003479003906193 +0.986125 -0.31866455078125 -0.28668212890625 -0.1003479003906193 +0.986250000000000096 -0.31866455078125 -0.28668212890625 -0.1003479003906193 +0.986375 -0.314605712890625 -0.28302001953125 -0.1003479003906193 +0.9865 -0.314605712890625 -0.28302001953125 -0.1003479003906193 +0.986625 -0.310516357421875 -0.27935791015625 -0.1003479003906193 +0.98675 -0.306396484375 -0.275634765625 -0.1003479003906193 +0.986875000000000096 -0.306396484375 -0.275634765625 -0.1003479003906193 +0.987 -0.30224609375 -0.27191162109375 -0.1003479003906193 +0.987125 -0.30224609375 -0.27191162109375 -0.1003479003906193 +0.987250000000000096 -0.298065185546875 -0.26812744140625 -0.1003479003906193 +0.987375 -0.2938232421875 -0.26434326171875 -0.1003479003906193 +0.9875 -0.2938232421875 -0.26434326171875 -0.1003479003906193 +0.987625 -0.289581298828125 -0.260528564453125 -0.1003479003906193 +0.98775 -0.289581298828125 -0.260528564453125 -0.1003479003906193 +0.987875000000000096 -0.285308837890625 -0.25665283203125 -0.1003479003906193 +0.988 -0.280975341796875 -0.252777099609375 -0.1003479003906193 +0.988125 -0.280975341796875 -0.252777099609375 -0.1003479003906193 +0.988250000000000096 -0.276641845703125 -0.248870849609375 -0.1003479003906193 +0.988375 -0.276641845703125 -0.248870849609375 -0.1003479003906193 +0.9885 -0.27227783203125 -0.24493408203125 -0.1003479003906193 +0.988625 -0.267852783203125 -0.240966796875 -0.1003479003906193 +0.98875 -0.267852783203125 -0.240966796875 -0.1003479003906193 +0.988875000000000096 -0.263427734375 -0.236968994140625 -0.1003479003906193 +0.989 -0.263427734375 -0.236968994140625 -0.1003479003906193 +0.989125 -0.25897216796875 -0.23297119140625 -0.1003479003906193 +0.989250000000000096 -0.25445556640625 -0.228912353515625 -0.1003479003906193 +0.989375 -0.25445556640625 -0.228912353515625 -0.1003479003906193 +0.9895 -0.249969482421875 -0.224853515625 -0.1003479003906193 +0.989625 -0.249969482421875 -0.224853515625 -0.1003479003906193 +0.98975 -0.24542236328125 -0.22076416015625 -0.1003479003906193 +0.989875000000000096 -0.2408447265625 -0.216644287109375 -0.1003479003906193 +0.99 -0.2408447265625 -0.216644287109375 -0.1003479003906193 +0.990125 -0.236236572265625 -0.2125244140625 -0.1003479003906193 +0.990250000000000096 -0.236236572265625 -0.2125244140625 -0.1003479003906193 +0.990375 -0.231597900390625 -0.208343505859375 -0.1003479003906193 +0.9905 -0.226959228515625 -0.20416259765625 -0.1003479003906193 +0.990625 -0.226959228515625 -0.20416259765625 -0.1003479003906193 +0.99075 -0.2222900390625 -0.199951171875 -0.1003479003906193 +0.990875000000000096 -0.2222900390625 -0.199951171875 -0.1003479003906193 +0.991 -0.21759033203125 -0.19573974609375 -0.1003479003906193 +0.991125 -0.212860107421875 -0.19146728515625 -0.1003479003906193 +0.991250000000000096 -0.212860107421875 -0.19146728515625 -0.1003479003906193 +0.991375 -0.208099365234375 -0.187225341796875 -0.1003479003906193 +0.9915 -0.208099365234375 -0.187225341796875 -0.1003479003906193 +0.991625 -0.203338623046875 -0.18292236328125 -0.1003479003906193 +0.99175 -0.19854736328125 -0.178619384765625 -0.1003479003906193 +0.991875000000000096 -0.19854736328125 -0.178619384765625 -0.1003479003906193 +0.992 -0.13616943359375 -0.1937255859375 0.2970092773437556 +0.992125 -0.13616943359375 -0.1937255859375 0.2970092773437556 +0.99225 -0.132781982421875 -0.188873291015625 0.2970092773437556 +0.992375 -0.129364013671875 -0.18402099609375 0.2970092773437556 +0.9925 -0.129364013671875 -0.18402099609375 0.2970092773437556 +0.992625 -0.12591552734375 -0.17913818359375 0.2970092773437556 +0.99275 -0.12591552734375 -0.17913818359375 0.2970092773437556 +0.992875000000000096 -0.122467041015625 -0.17425537109375 0.2970092773437556 +0.993 -0.1190185546875 -0.169342041015625 0.2970092773437556 +0.993125 -0.1190185546875 -0.169342041015625 0.2970092773437556 +0.99325 -0.11553955078125 -0.164398193359375 0.2970092773437556 +0.993375 -0.11553955078125 -0.164398193359375 0.2970092773437556 +0.9935 -0.112091064453125 -0.159454345703125 0.2970092773437556 +0.993625 -0.10858154296875 -0.15447998046875 0.2970092773437556 +0.99375 -0.10858154296875 -0.15447998046875 0.2970092773437556 +0.993875000000000096 -0.105072021484375 -0.14947509765625 0.2970092773437556 +0.994 -0.105072021484375 -0.14947509765625 0.2970092773437556 +0.994125 -0.1015625 -0.14447021484375 0.2970092773437556 +0.99425 -0.0980224609375 -0.13946533203125 0.2970092773437556 +0.994375 -0.0980224609375 -0.13946533203125 0.2970092773437556 +0.9945 -0.094482421875 -0.134429931640625 0.2970092773437556 +0.994625 -0.094482421875 -0.134429931640625 0.2970092773437556 +0.99475 -0.0909423828125 -0.129364013671875 0.2970092773437556 +0.994875000000000096 -0.087371826171875 -0.124298095703125 0.2970092773437556 +0.995 -0.087371826171875 -0.124298095703125 0.2970092773437556 +0.995125 -0.08380126953125 -0.119232177734375 0.2970092773437556 +0.99525 -0.08380126953125 -0.119232177734375 0.2970092773437556 +0.995375 -0.080230712890625 -0.1141357421875 0.2970092773437556 +0.9955 -0.076629638671875 -0.109039306640625 0.2970092773437556 +0.995625 -0.076629638671875 -0.109039306640625 0.2970092773437556 +0.99575 -0.07305908203125 -0.103912353515625 0.2970092773437556 +0.995875000000000096 -0.07305908203125 -0.103912353515625 0.2970092773437556 +0.996 -0.0694580078125 -0.098785400390625 0.2970092773437556 +0.996125 -0.065826416015625 -0.093658447265625 0.2970092773437556 +0.99625 -0.065826416015625 -0.093658447265625 0.2970092773437556 +0.996375 -0.062225341796875 -0.0885009765625 0.2970092773437556 +0.9965 -0.062225341796875 -0.0885009765625 0.2970092773437556 +0.996625 -0.05859375 -0.083343505859375 0.2970092773437556 +0.99675 -0.054962158203125 -0.07818603515625 0.2970092773437556 +0.996875000000000096 -0.054962158203125 -0.07818603515625 0.2970092773437556 +0.997 -0.05133056640625 -0.072998046875 0.2970092773437556 +0.997125 -0.05133056640625 -0.072998046875 0.2970092773437556 +0.99725 -0.04766845703125 -0.06781005859375 0.2970092773437556 +0.997375 -0.044036865234375 -0.0626220703125 0.2970092773437556 +0.9975 -0.044036865234375 -0.0626220703125 0.2970092773437556 +0.997625 -0.040374755859375 -0.05743408203125 0.2970092773437556 +0.99775 -0.040374755859375 -0.05743408203125 0.2970092773437556 +0.997875000000000096 -0.036712646484375 -0.05224609375 0.2970092773437556 +0.998 -0.033050537109375 -0.047027587890625 0.2970092773437556 +0.998125 -0.033050537109375 -0.047027587890625 0.2970092773437556 +0.99825 -0.029388427734375 -0.04180908203125 0.2970092773437556 +0.998375 -0.029388427734375 -0.04180908203125 0.2970092773437556 +0.9985 -0.025726318359375 -0.036590576171875 0.2970092773437556 +0.998625 -0.02203369140625 -0.0313720703125 0.2970092773437556 +0.99875 -0.02203369140625 -0.0313720703125 0.2970092773437556 +0.998875000000000096 -0.01837158203125 -0.026123046875 0.2970092773437556 +0.999 -0.01837158203125 -0.026123046875 0.2970092773437556 +0.999125 -0.01470947265625 -0.020904541015625 0.2970092773437556 +0.99925 -0.011016845703125 -0.01568603515625 0.2970092773437556 +0.999375 -0.011016845703125 -0.01568603515625 0.2970092773437556 +0.9995 -0.007354736328125 -0.01043701171875 0.2970092773437556 +0.999625 -0.007354736328125 -0.01043701171875 0.2970092773437556 +0.99975 -0.003662109375 -0.005218505859375 0.2970092773437556 +0.999875000000000096 0.0 0.0 0.2970092773437556 +1.0 0.0 0.0 0.2970092773437556 +1.000125 0.003662109375 0.005218505859375 0.2970092773437556 +1.00025 0.003662109375 0.005218505859375 0.2970092773437556 +1.000375 0.007354736328125 0.01043701171875 0.2970092773437556 +1.0005 0.011016845703125 0.01568603515625 0.2970092773437556 +1.000625 0.011016845703125 0.01568603515625 0.2970092773437556 +1.00075 0.01470947265625 0.020904541015625 0.2970092773437556 +1.000875 0.01470947265625 0.020904541015625 0.2970092773437556 +1.0010000000000002 0.01837158203125 0.026123046875 0.2970092773437556 +1.001125 0.02203369140625 0.0313720703125 0.2970092773437556 +1.00125 0.02203369140625 0.0313720703125 0.2970092773437556 +1.0013750000000002 0.025726318359375 0.036590576171875 0.2970092773437556 +1.0015 0.025726318359375 0.036590576171875 0.2970092773437556 +1.001625 0.029388427734375 0.04180908203125 0.2970092773437556 +1.00175 0.033050537109375 0.047027587890625 0.2970092773437556 +1.001875 0.033050537109375 0.047027587890625 0.2970092773437556 +1.002 0.036712646484375 0.05224609375 0.2970092773437556 +1.002125 0.036712646484375 0.05224609375 0.2970092773437556 +1.00225 0.040374755859375 0.05743408203125 0.2970092773437556 +1.002375 0.044036865234375 0.0626220703125 0.2970092773437556 +1.0025 0.044036865234375 0.0626220703125 0.2970092773437556 +1.002625 0.04766845703125 0.06781005859375 0.2970092773437556 +1.00275 0.04766845703125 0.06781005859375 0.2970092773437556 +1.002875 0.05133056640625 0.072998046875 0.2970092773437556 +1.0030000000000002 0.054962158203125 0.07818603515625 0.2970092773437556 +1.003125 0.054962158203125 0.07818603515625 0.2970092773437556 +1.00325 0.05859375 0.083343505859375 0.2970092773437556 +1.0033750000000002 0.05859375 0.083343505859375 0.2970092773437556 +1.0035 0.062225341796875 0.0885009765625 0.2970092773437556 +1.003625 0.065826416015625 0.093658447265625 0.2970092773437556 +1.00375 0.065826416015625 0.093658447265625 0.2970092773437556 +1.003875 0.0694580078125 0.098785400390625 0.2970092773437556 +1.004 0.0694580078125 0.098785400390625 0.2970092773437556 +1.004125 0.07305908203125 0.103912353515625 0.2970092773437556 +1.00425 0.076629638671875 0.109039306640625 0.2970092773437556 +1.004375 0.076629638671875 0.109039306640625 0.2970092773437556 +1.0045 0.080230712890625 0.1141357421875 0.2970092773437556 +1.004625 0.080230712890625 0.1141357421875 0.2970092773437556 +1.00475 0.08380126953125 0.119232177734375 0.2970092773437556 +1.004875 0.087371826171875 0.124298095703125 0.2970092773437556 +1.0050000000000002 0.087371826171875 0.124298095703125 0.2970092773437556 +1.005125 0.0909423828125 0.129364013671875 0.2970092773437556 +1.00525 0.0909423828125 0.129364013671875 0.2970092773437556 +1.0053750000000002 0.094482421875 0.134429931640625 0.2970092773437556 +1.0055 0.0980224609375 0.13946533203125 0.2970092773437556 +1.005625 0.0980224609375 0.13946533203125 0.2970092773437556 +1.00575 0.1015625 0.14447021484375 0.2970092773437556 +1.005875 0.1015625 0.14447021484375 0.2970092773437556 +1.006 0.105072021484375 0.14947509765625 0.2970092773437556 +1.006125 0.10858154296875 0.15447998046875 0.2970092773437556 +1.00625 0.10858154296875 0.15447998046875 0.2970092773437556 +1.006375 0.112091064453125 0.159454345703125 0.2970092773437556 +1.0065 0.112091064453125 0.159454345703125 0.2970092773437556 +1.006625 0.11553955078125 0.164398193359375 0.2970092773437556 +1.00675 0.1190185546875 0.169342041015625 0.2970092773437556 +1.006875 0.1190185546875 0.169342041015625 0.2970092773437556 +1.0070000000000002 0.122467041015625 0.17425537109375 0.2970092773437556 +1.007125 0.122467041015625 0.17425537109375 0.2970092773437556 +1.00725 0.12591552734375 0.17913818359375 0.2970092773437556 +1.0073750000000002 0.129364013671875 0.18402099609375 0.2970092773437556 +1.0075 0.129364013671875 0.18402099609375 0.2970092773437556 +1.007625 0.132781982421875 0.188873291015625 0.2970092773437556 +1.00775 0.132781982421875 0.188873291015625 0.2970092773437556 +1.007875 0.13616943359375 0.1937255859375 0.2970092773437556 +1.008 0.139556884765625 0.19854736328125 0.2970092773437556 +1.008125 0.139556884765625 0.19854736328125 0.2970092773437556 +1.00825 0.142913818359375 0.203338623046875 0.2970092773437556 +1.008375 0.142913818359375 0.203338623046875 0.2970092773437556 +1.0085 0.146270751953125 0.208099365234375 0.2970092773437556 +1.008625 0.149627685546875 0.212860107421875 0.2970092773437556 +1.00875 0.149627685546875 0.212860107421875 0.2970092773437556 +1.008875 0.1529541015625 0.21759033203125 0.2970092773437556 +1.0090000000000002 0.1529541015625 0.21759033203125 0.2970092773437556 +1.009125 0.15625 0.2222900390625 0.2970092773437556 +1.00925 0.159515380859375 0.226959228515625 0.2970092773437556 +1.009375 0.159515380859375 0.226959228515625 0.2970092773437556 +1.0095 0.162811279296875 0.231597900390625 0.2970092773437556 +1.009625 0.162811279296875 0.231597900390625 0.2970092773437556 +1.00975 0.166046142578125 0.236236572265625 0.2970092773437556 +1.009875 0.169281005859375 0.2408447265625 0.2970092773437556 +1.01 0.169281005859375 0.2408447265625 0.2970092773437556 +1.010125 0.172515869140625 0.24542236328125 0.2970092773437556 +1.01025 0.172515869140625 0.24542236328125 0.2970092773437556 +1.010375 0.175689697265625 0.249969482421875 0.2970092773437556 +1.0105 0.178863525390625 0.25445556640625 0.2970092773437556 +1.010625 0.178863525390625 0.25445556640625 0.2970092773437556 +1.01075 0.182037353515625 0.25897216796875 0.2970092773437556 +1.010875 0.182037353515625 0.25897216796875 0.2970092773437556 +1.0110000000000002 0.1851806640625 0.263427734375 0.2970092773437556 +1.011125 0.18829345703125 0.267852783203125 0.2970092773437556 +1.01125 0.18829345703125 0.267852783203125 0.2970092773437556 +1.011375 0.19140625 0.27227783203125 0.2970092773437556 +1.0115 0.19140625 0.27227783203125 0.2970092773437556 +1.011625 0.1944580078125 0.276641845703125 0.2970092773437556 +1.01175 0.197509765625 0.280975341796875 0.2970092773437556 +1.011875 0.197509765625 0.280975341796875 0.2970092773437556 +1.012 0.2005615234375 0.285308837890625 0.2970092773437556 +1.012125 0.2005615234375 0.285308837890625 0.2970092773437556 +1.01225 0.20355224609375 0.289581298828125 0.2970092773437556 +1.012375 0.20654296875 0.2938232421875 0.2970092773437556 +1.0125 0.20654296875 0.2938232421875 0.2970092773437556 +1.012625 0.20953369140625 0.298065185546875 0.2970092773437556 +1.01275 0.20953369140625 0.298065185546875 0.2970092773437556 +1.012875 0.21246337890625 0.30224609375 0.2970092773437556 +1.0130000000000002 0.21539306640625 0.306396484375 0.2970092773437556 +1.013125 0.21539306640625 0.306396484375 0.2970092773437556 +1.01325 0.218292236328125 0.310516357421875 0.2970092773437556 +1.013375 0.218292236328125 0.310516357421875 0.2970092773437556 +1.0135 0.221160888671875 0.314605712890625 0.2970092773437556 +1.013625 0.2239990234375 0.31866455078125 0.2970092773437556 +1.01375 0.2239990234375 0.31866455078125 0.2970092773437556 +1.013875 0.226806640625 0.322662353515625 0.2970092773437556 +1.014 0.226806640625 0.322662353515625 0.2970092773437556 +1.014125 0.2296142578125 0.32666015625 0.2970092773437556 +1.01425 0.232391357421875 0.330596923828125 0.2970092773437556 +1.014375 0.232391357421875 0.330596923828125 0.2970092773437556 +1.0145 0.235137939453125 0.334503173828125 0.2970092773437556 +1.014625 0.235137939453125 0.334503173828125 0.2970092773437556 +1.01475 0.23785400390625 0.33837890625 0.2970092773437556 +1.014875 0.240570068359375 0.34222412109375 0.2970092773437556 +1.0150000000000002 0.240570068359375 0.34222412109375 0.2970092773437556 +1.015125 0.24322509765625 0.34600830078125 0.2970092773437556 +1.01525 0.24322509765625 0.34600830078125 0.2970092773437556 +1.015375 0.245880126953125 0.349761962890625 0.2970092773437556 +1.0155 0.24847412109375 0.353485107421875 0.2970092773437556 +1.015625 0.24847412109375 0.353485107421875 0.2970092773437556 +1.01575 0.251068115234375 0.357177734375 0.2970092773437556 +1.015875 0.251068115234375 0.357177734375 0.2970092773437556 +1.016 0.253631591796875 0.360809326171875 0.2970092773437556 +1.016125 0.25616455078125 0.36444091796875 0.2970092773437556 +1.01625 0.25616455078125 0.36444091796875 0.2970092773437556 +1.016375 0.2586669921875 0.36798095703125 0.2970092773437556 +1.0165 0.2586669921875 0.36798095703125 0.2970092773437556 +1.0166250000000002 0.261138916015625 0.37152099609375 0.2970092773437556 +1.01675 0.26361083984375 0.375 0.2970092773437556 +1.016875 0.26361083984375 0.375 0.2970092773437556 +1.0170000000000002 0.266021728515625 0.378448486328125 0.2970092773437556 +1.017125 0.266021728515625 0.378448486328125 0.2970092773437556 +1.01725 0.268402099609375 0.3818359375 0.2970092773437556 +1.017375 0.270782470703125 0.38519287109375 0.2970092773437556 +1.0175 0.270782470703125 0.38519287109375 0.2970092773437556 +1.017625 0.273101806640625 0.388519287109375 0.2970092773437556 +1.01775 0.273101806640625 0.388519287109375 0.2970092773437556 +1.017875 0.275421142578125 0.39178466796875 0.2970092773437556 +1.018 0.277679443359375 0.39501953125 0.2970092773437556 +1.018125 0.277679443359375 0.39501953125 0.2970092773437556 +1.01825 0.2799072265625 0.398193359375 0.2970092773437556 +1.018375 0.2799072265625 0.398193359375 0.2970092773437556 +1.0185 0.282135009765625 0.401336669921875 0.2970092773437556 +1.0186250000000002 0.2843017578125 0.404449462890625 0.2970092773437556 +1.01875 0.2843017578125 0.404449462890625 0.2970092773437556 +1.018875 0.286468505859375 0.407501220703125 0.2970092773437556 +1.0190000000000002 0.286468505859375 0.407501220703125 0.2970092773437556 +1.019125 0.28857421875 0.4105224609375 0.2970092773437556 +1.01925 0.2906494140625 0.413482666015625 0.2970092773437556 +1.019375 0.2906494140625 0.413482666015625 0.2970092773437556 +1.0195 0.292694091796875 0.416412353515625 0.2970092773437556 +1.019625 0.292694091796875 0.416412353515625 0.2970092773437556 +1.01975 0.29473876953125 0.419281005859375 0.2970092773437556 +1.019875 0.296722412109375 0.422119140625 0.2970092773437556 +1.02 0.296722412109375 0.422119140625 0.2970092773437556 +1.020125 0.298675537109375 0.424896240234375 0.2970092773437556 +1.02025 0.298675537109375 0.424896240234375 0.2970092773437556 +1.020375 0.30059814453125 0.4276123046875 0.2970092773437556 +1.0205 0.302490234375 0.4302978515625 0.2970092773437556 +1.0206250000000002 0.302490234375 0.4302978515625 0.2970092773437556 +1.02075 0.304351806640625 0.432952880859375 0.2970092773437556 +1.020875 0.304351806640625 0.432952880859375 0.2970092773437556 +1.0210000000000002 0.306182861328125 0.435546875 0.2970092773437556 +1.021125 0.307952880859375 0.438079833984375 0.2970092773437556 +1.02125 0.307952880859375 0.438079833984375 0.2970092773437556 +1.021375 0.3096923828125 0.440582275390625 0.2970092773437556 +1.0215 0.3096923828125 0.440582275390625 0.2970092773437556 +1.021625 0.311431884765625 0.44305419921875 0.2970092773437556 +1.02175 0.3131103515625 0.4454345703125 0.2970092773437556 +1.021875 0.3131103515625 0.4454345703125 0.2970092773437556 +1.022 0.31475830078125 0.447784423828125 0.2970092773437556 +1.022125 0.31475830078125 0.447784423828125 0.2970092773437556 +1.02225 0.316375732421875 0.450103759765625 0.2970092773437556 +1.022375 0.317962646484375 0.452362060546875 0.2970092773437556 +1.0225 0.317962646484375 0.452362060546875 0.2970092773437556 +1.0226250000000002 0.31951904296875 0.454559326171875 0.2970092773437556 +1.02275 0.31951904296875 0.454559326171875 0.2970092773437556 +1.022875 0.321044921875 0.45672607421875 0.2970092773437556 +1.0230000000000002 0.322509765625 0.458831787109375 0.2970092773437556 +1.023125 0.322509765625 0.458831787109375 0.2970092773437556 +1.02325 0.323974609375 0.46087646484375 0.2970092773437556 +1.023375 0.323974609375 0.46087646484375 0.2970092773437556 +1.0235 0.32537841796875 0.462890625 0.2970092773437556 +1.023625 0.326751708984375 0.464813232421875 0.2970092773437556 +1.02375 0.326751708984375 0.464813232421875 0.2970092773437556 +1.023875 0.328094482421875 0.46673583984375 0.2970092773437556 +1.024 0.164703369140625 0.46673583984375 0.6470092773437545 +1.024125 0.165374755859375 0.46856689453125 0.6470092773437545 +1.02425 0.165985107421875 0.470367431640625 0.6470092773437545 +1.024375 0.165985107421875 0.470367431640625 0.6470092773437545 +1.0245 0.1666259765625 0.472137451171875 0.6470092773437545 +1.0246250000000002 0.1666259765625 0.472137451171875 0.6470092773437545 +1.02475 0.167205810546875 0.47381591796875 0.6470092773437545 +1.024875 0.16778564453125 0.4754638671875 0.6470092773437545 +1.025 0.16778564453125 0.4754638671875 0.6470092773437545 +1.025125 0.168365478515625 0.47705078125 0.6470092773437545 +1.02525 0.168365478515625 0.47705078125 0.6470092773437545 +1.025375 0.16888427734375 0.478607177734375 0.6470092773437545 +1.0255 0.16943359375 0.480072021484375 0.6470092773437545 +1.025625 0.16943359375 0.480072021484375 0.6470092773437545 +1.02575 0.169921875 0.48150634765625 0.6470092773437545 +1.025875 0.169921875 0.48150634765625 0.6470092773437545 +1.026 0.17041015625 0.48291015625 0.6470092773437545 +1.026125 0.1708984375 0.484222412109375 0.6470092773437545 +1.02625 0.1708984375 0.484222412109375 0.6470092773437545 +1.026375 0.17132568359375 0.485504150390625 0.6470092773437545 +1.0265 0.17132568359375 0.485504150390625 0.6470092773437545 +1.0266250000000002 0.171783447265625 0.486724853515625 0.6470092773437545 +1.02675 0.17218017578125 0.487884521484375 0.6470092773437545 +1.026875 0.17218017578125 0.487884521484375 0.6470092773437545 +1.027 0.172576904296875 0.489013671875 0.6470092773437545 +1.027125 0.172576904296875 0.489013671875 0.6470092773437545 +1.02725 0.172943115234375 0.490081787109375 0.6470092773437545 +1.027375 0.173309326171875 0.4910888671875 0.6470092773437545 +1.0275 0.173309326171875 0.4910888671875 0.6470092773437545 +1.027625 0.17364501953125 0.492034912109375 0.6470092773437545 +1.02775 0.17364501953125 0.492034912109375 0.6470092773437545 +1.027875 0.1739501953125 0.492950439453125 0.6470092773437545 +1.028 0.17425537109375 0.4937744140625 0.6470092773437545 +1.028125 0.17425537109375 0.4937744140625 0.6470092773437545 +1.02825 0.174530029296875 0.49456787109375 0.6470092773437545 +1.028375 0.174530029296875 0.49456787109375 0.6470092773437545 +1.0285 0.1748046875 0.49530029296875 0.6470092773437545 +1.0286250000000002 0.175048828125 0.496002197265625 0.6470092773437545 +1.02875 0.175048828125 0.496002197265625 0.6470092773437545 +1.028875 0.175262451171875 0.496612548828125 0.6470092773437545 +1.029 0.175262451171875 0.496612548828125 0.6470092773437545 +1.029125 0.17547607421875 0.4971923828125 0.6470092773437545 +1.02925 0.1756591796875 0.497711181640625 0.6470092773437545 +1.029375 0.1756591796875 0.497711181640625 0.6470092773437545 +1.0295 0.175811767578125 0.498199462890625 0.6470092773437545 +1.029625 0.175811767578125 0.498199462890625 0.6470092773437545 +1.02975 0.17596435546875 0.49859619140625 0.6470092773437545 +1.029875 0.17608642578125 0.49896240234375 0.6470092773437545 +1.03 0.17608642578125 0.49896240234375 0.6470092773437545 +1.030125 0.176177978515625 0.499267578125 0.6470092773437545 +1.03025 0.176177978515625 0.499267578125 0.6470092773437545 +1.030375 0.17626953125 0.49951171875 0.6470092773437545 +1.0305 0.17633056640625 0.49969482421875 0.6470092773437545 +1.0306250000000002 0.17633056640625 0.49969482421875 0.6470092773437545 +1.03075 0.1763916015625 0.49981689453125 0.6470092773437545 +1.030875 0.1763916015625 0.49981689453125 0.6470092773437545 +1.031 0.176422119140625 0.499908447265625 0.6470092773437545 +1.031125 0.176422119140625 0.49993896484375 0.6470092773437545 +1.03125 0.176422119140625 0.49993896484375 0.6470092773437545 +1.031375 0.176422119140625 0.499908447265625 0.6470092773437545 +1.0315 0.176422119140625 0.499908447265625 0.6470092773437545 +1.031625 0.1763916015625 0.49981689453125 0.6470092773437545 +1.03175 0.17633056640625 0.49969482421875 0.6470092773437545 +1.031875 0.17633056640625 0.49969482421875 0.6470092773437545 +1.032 0.17626953125 0.49951171875 0.6470092773437545 +1.032125 0.17626953125 0.49951171875 0.6470092773437545 +1.0322500000000002 0.176177978515625 0.499267578125 0.6470092773437545 +1.032375 0.17608642578125 0.49896240234375 0.6470092773437545 +1.0325 0.17608642578125 0.49896240234375 0.6470092773437545 +1.0326250000000002 0.17596435546875 0.49859619140625 0.6470092773437545 +1.03275 0.17596435546875 0.49859619140625 0.6470092773437545 +1.032875 0.175811767578125 0.498199462890625 0.6470092773437545 +1.033 0.1756591796875 0.497711181640625 0.6470092773437545 +1.033125 0.1756591796875 0.497711181640625 0.6470092773437545 +1.03325 0.17547607421875 0.4971923828125 0.6470092773437545 +1.033375 0.17547607421875 0.4971923828125 0.6470092773437545 +1.0335 0.175262451171875 0.496612548828125 0.6470092773437545 +1.033625 0.175048828125 0.496002197265625 0.6470092773437545 +1.03375 0.175048828125 0.496002197265625 0.6470092773437545 +1.033875 0.1748046875 0.49530029296875 0.6470092773437545 +1.034 0.1748046875 0.49530029296875 0.6470092773437545 +1.034125 0.174530029296875 0.49456787109375 0.6470092773437545 +1.0342500000000002 0.17425537109375 0.4937744140625 0.6470092773437545 +1.034375 0.17425537109375 0.4937744140625 0.6470092773437545 +1.0345 0.1739501953125 0.492950439453125 0.6470092773437545 +1.0346250000000002 0.1739501953125 0.492950439453125 0.6470092773437545 +1.03475 0.17364501953125 0.492034912109375 0.6470092773437545 +1.034875 0.173309326171875 0.4910888671875 0.6470092773437545 +1.035 0.173309326171875 0.4910888671875 0.6470092773437545 +1.035125 0.172943115234375 0.490081787109375 0.6470092773437545 +1.03525 0.172943115234375 0.490081787109375 0.6470092773437545 +1.035375 0.172576904296875 0.489013671875 0.6470092773437545 +1.0355 0.17218017578125 0.487884521484375 0.6470092773437545 +1.035625 0.17218017578125 0.487884521484375 0.6470092773437545 +1.03575 0.171783447265625 0.486724853515625 0.6470092773437545 +1.035875 0.171783447265625 0.486724853515625 0.6470092773437545 +1.036 0.17132568359375 0.485504150390625 0.6470092773437545 +1.036125 0.1708984375 0.484222412109375 0.6470092773437545 +1.0362500000000002 0.1708984375 0.484222412109375 0.6470092773437545 +1.036375 0.17041015625 0.48291015625 0.6470092773437545 +1.0365 0.17041015625 0.48291015625 0.6470092773437545 +1.0366250000000002 0.169921875 0.48150634765625 0.6470092773437545 +1.03675 0.16943359375 0.480072021484375 0.6470092773437545 +1.036875 0.16943359375 0.480072021484375 0.6470092773437545 +1.037 0.16888427734375 0.478607177734375 0.6470092773437545 +1.037125 0.16888427734375 0.478607177734375 0.6470092773437545 +1.03725 0.168365478515625 0.47705078125 0.6470092773437545 +1.037375 0.16778564453125 0.4754638671875 0.6470092773437545 +1.0375 0.16778564453125 0.4754638671875 0.6470092773437545 +1.037625 0.167205810546875 0.47381591796875 0.6470092773437545 +1.03775 0.167205810546875 0.47381591796875 0.6470092773437545 +1.037875 0.1666259765625 0.472137451171875 0.6470092773437545 +1.038 0.165985107421875 0.470367431640625 0.6470092773437545 +1.038125 0.165985107421875 0.470367431640625 0.6470092773437545 +1.0382500000000002 0.165374755859375 0.46856689453125 0.6470092773437545 +1.038375 0.165374755859375 0.46856689453125 0.6470092773437545 +1.0385 0.164703369140625 0.46673583984375 0.6470092773437545 +1.0386250000000002 0.164031982421875 0.464813232421875 0.6470092773437545 +1.03875 0.164031982421875 0.464813232421875 0.6470092773437545 +1.038875 0.163360595703125 0.462890625 0.6470092773437545 +1.039 0.163360595703125 0.462890625 0.6470092773437545 +1.039125 0.162628173828125 0.46087646484375 0.6470092773437545 +1.03925 0.16192626953125 0.458831787109375 0.6470092773437545 +1.039375 0.16192626953125 0.458831787109375 0.6470092773437545 +1.0395 0.161163330078125 0.45672607421875 0.6470092773437545 +1.039625 0.161163330078125 0.45672607421875 0.6470092773437545 +1.03975 0.160400390625 0.454559326171875 0.6470092773437545 +1.039875 0.159637451171875 0.452362060546875 0.6470092773437545 +1.04 0.159637451171875 0.452362060546875 0.6470092773437545 +1.040125 0.158843994140625 0.450103759765625 0.6470092773437545 +1.0402500000000002 0.158843994140625 0.450103759765625 0.6470092773437545 +1.040375 0.15802001953125 0.447784423828125 0.6470092773437545 +1.0405 0.157196044921875 0.4454345703125 0.6470092773437545 +1.040625 0.157196044921875 0.4454345703125 0.6470092773437545 +1.04075 0.156341552734375 0.44305419921875 0.6470092773437545 +1.040875 0.156341552734375 0.44305419921875 0.6470092773437545 +1.041 0.155487060546875 0.440582275390625 0.6470092773437545 +1.041125 0.15460205078125 0.438079833984375 0.6470092773437545 +1.04125 0.15460205078125 0.438079833984375 0.6470092773437545 +1.041375 0.153717041015625 0.435546875 0.6470092773437545 +1.0415 0.153717041015625 0.435546875 0.6470092773437545 +1.041625 0.152801513671875 0.432952880859375 0.6470092773437545 +1.04175 0.15185546875 0.4302978515625 0.6470092773437545 +1.041875 0.15185546875 0.4302978515625 0.6470092773437545 +1.042 0.150909423828125 0.4276123046875 0.6470092773437545 +1.042125 0.150909423828125 0.4276123046875 0.6470092773437545 +1.0422500000000002 0.149932861328125 0.424896240234375 0.6470092773437545 +1.042375 0.148956298828125 0.422119140625 0.6470092773437545 +1.0425 0.148956298828125 0.422119140625 0.6470092773437545 +1.042625 0.14794921875 0.419281005859375 0.6470092773437545 +1.04275 0.14794921875 0.419281005859375 0.6470092773437545 +1.042875 0.146942138671875 0.416412353515625 0.6470092773437545 +1.043 0.145904541015625 0.413482666015625 0.6470092773437545 +1.043125 0.145904541015625 0.413482666015625 0.6470092773437545 +1.04325 0.144866943359375 0.4105224609375 0.6470092773437545 +1.043375 0.144866943359375 0.4105224609375 0.6470092773437545 +1.0435 0.143798828125 0.407501220703125 0.6470092773437545 +1.043625 0.142730712890625 0.404449462890625 0.6470092773437545 +1.04375 0.142730712890625 0.404449462890625 0.6470092773437545 +1.043875 0.141632080078125 0.401336669921875 0.6470092773437545 +1.044 0.141632080078125 0.401336669921875 0.6470092773437545 +1.044125 0.140533447265625 0.398193359375 0.6470092773437545 +1.0442500000000002 0.139404296875 0.39501953125 0.6470092773437545 +1.044375 0.139404296875 0.39501953125 0.6470092773437545 +1.0445 0.138275146484375 0.39178466796875 0.6470092773437545 +1.044625 0.138275146484375 0.39178466796875 0.6470092773437545 +1.04475 0.137115478515625 0.388519287109375 0.6470092773437545 +1.044875 0.13592529296875 0.38519287109375 0.6470092773437545 +1.045 0.13592529296875 0.38519287109375 0.6470092773437545 +1.045125 0.134765625 0.3818359375 0.6470092773437545 +1.04525 0.134765625 0.3818359375 0.6470092773437545 +1.045375 0.133544921875 0.378448486328125 0.6470092773437545 +1.0455 0.13232421875 0.375 0.6470092773437545 +1.045625 0.13232421875 0.375 0.6470092773437545 +1.04575 0.131103515625 0.37152099609375 0.6470092773437545 +1.045875 0.131103515625 0.37152099609375 0.6470092773437545 +1.046 0.129852294921875 0.36798095703125 0.6470092773437545 +1.046125 0.12860107421875 0.36444091796875 0.6470092773437545 +1.0462500000000002 0.12860107421875 0.36444091796875 0.6470092773437545 +1.046375 0.1273193359375 0.360809326171875 0.6470092773437545 +1.0465 0.1273193359375 0.360809326171875 0.6470092773437545 +1.046625 0.12603759765625 0.357177734375 0.6470092773437545 +1.04675 0.124755859375 0.353485107421875 0.6470092773437545 +1.046875 0.124755859375 0.353485107421875 0.6470092773437545 +1.047 0.123443603515625 0.349761962890625 0.6470092773437545 +1.047125 0.123443603515625 0.349761962890625 0.6470092773437545 +1.04725 0.122100830078125 0.34600830078125 0.6470092773437545 +1.047375 0.120758056640625 0.34222412109375 0.6470092773437545 +1.0475 0.120758056640625 0.34222412109375 0.6470092773437545 +1.047625 0.119415283203125 0.33837890625 0.6470092773437545 +1.04775 0.119415283203125 0.33837890625 0.6470092773437545 +1.0478750000000002 0.1180419921875 0.334503173828125 0.6470092773437545 +1.048 0.116668701171875 0.330596923828125 0.6470092773437545 +1.048125 0.116668701171875 0.330596923828125 0.6470092773437545 +1.0482500000000002 0.115264892578125 0.32666015625 0.6470092773437545 +1.048375 0.115264892578125 0.32666015625 0.6470092773437545 +1.0485 0.113861083984375 0.322662353515625 0.6470092773437545 +1.048625 0.112457275390625 0.31866455078125 0.6470092773437545 +1.04875 0.112457275390625 0.31866455078125 0.6470092773437545 +1.048875 0.11102294921875 0.314605712890625 0.6470092773437545 +1.049 0.11102294921875 0.314605712890625 0.6470092773437545 +1.049125 0.109588623046875 0.310516357421875 0.6470092773437545 +1.04925 0.108123779296875 0.306396484375 0.6470092773437545 +1.049375 0.108123779296875 0.306396484375 0.6470092773437545 +1.0495 0.106658935546875 0.30224609375 0.6470092773437545 +1.049625 0.106658935546875 0.30224609375 0.6470092773437545 +1.04975 0.105194091796875 0.298065185546875 0.6470092773437545 +1.0498750000000002 0.10369873046875 0.2938232421875 0.6470092773437545 +1.05 0.10369873046875 0.2938232421875 0.6470092773437545 +1.050125 0.102203369140625 0.289581298828125 0.6470092773437545 +1.0502500000000002 0.102203369140625 0.289581298828125 0.6470092773437545 +1.050375 0.100677490234375 0.285308837890625 0.6470092773437545 +1.0505 0.099151611328125 0.280975341796875 0.6470092773437545 +1.050625 0.099151611328125 0.280975341796875 0.6470092773437545 +1.05075 0.097625732421875 0.276641845703125 0.6470092773437545 +1.050875 0.097625732421875 0.276641845703125 0.6470092773437545 +1.051 0.0960693359375 0.27227783203125 0.6470092773437545 +1.051125 0.094512939453125 0.267852783203125 0.6470092773437545 +1.05125 0.094512939453125 0.267852783203125 0.6470092773437545 +1.051375 0.09295654296875 0.263427734375 0.6470092773437545 +1.0515 0.09295654296875 0.263427734375 0.6470092773437545 +1.051625 0.091400146484375 0.25897216796875 0.6470092773437545 +1.05175 0.089813232421875 0.25445556640625 0.6470092773437545 +1.0518750000000002 0.089813232421875 0.25445556640625 0.6470092773437545 +1.052 0.08819580078125 0.249969482421875 0.6470092773437545 +1.052125 0.08819580078125 0.249969482421875 0.6470092773437545 +1.0522500000000002 0.08660888671875 0.24542236328125 0.6470092773437545 +1.052375 0.084991455078125 0.2408447265625 0.6470092773437545 +1.0525 0.084991455078125 0.2408447265625 0.6470092773437545 +1.052625 0.0833740234375 0.236236572265625 0.6470092773437545 +1.05275 0.0833740234375 0.236236572265625 0.6470092773437545 +1.052875 0.08172607421875 0.231597900390625 0.6470092773437545 +1.053 0.080078125 0.226959228515625 0.6470092773437545 +1.053125 0.080078125 0.226959228515625 0.6470092773437545 +1.05325 0.07843017578125 0.2222900390625 0.6470092773437545 +1.053375 0.07843017578125 0.2222900390625 0.6470092773437545 +1.0535 0.0767822265625 0.21759033203125 0.6470092773437545 +1.053625 0.075103759765625 0.212860107421875 0.6470092773437545 +1.05375 0.075103759765625 0.212860107421875 0.6470092773437545 +1.0538750000000002 0.07342529296875 0.208099365234375 0.6470092773437545 +1.054 0.07342529296875 0.208099365234375 0.6470092773437545 +1.054125 0.071746826171875 0.203338623046875 0.6470092773437545 +1.0542500000000002 0.070068359375 0.19854736328125 0.6470092773437545 +1.054375 0.070068359375 0.19854736328125 0.6470092773437545 +1.0545 0.068359375 0.1937255859375 0.6470092773437545 +1.054625 0.068359375 0.1937255859375 0.6470092773437545 +1.05475 0.066650390625 0.188873291015625 0.6470092773437545 +1.054875 0.06494140625 0.18402099609375 0.6470092773437545 +1.055 0.06494140625 0.18402099609375 0.6470092773437545 +1.055125 0.063201904296875 0.17913818359375 0.6470092773437545 +1.05525 0.063201904296875 0.17913818359375 0.6470092773437545 +1.055375 0.061492919921875 0.17425537109375 0.6470092773437545 +1.0555 0.05975341796875 0.169342041015625 0.6470092773437545 +1.055625 0.05975341796875 0.169342041015625 0.6470092773437545 +1.05575 0.058013916015625 0.164398193359375 0.6470092773437545 +1.0558750000000002 0.058013916015625 0.164398193359375 0.6470092773437545 +1.056 0.01690673828125 0.159454345703125 0.8937805175781277 +1.056125 0.016387939453125 0.15447998046875 0.8937805175781277 +1.05625 0.016387939453125 0.15447998046875 0.8937805175781277 +1.056375 0.015838623046875 0.14947509765625 0.8937805175781277 +1.0565 0.015838623046875 0.14947509765625 0.8937805175781277 +1.056625 0.01531982421875 0.14447021484375 0.8937805175781277 +1.05675 0.014801025390625 0.13946533203125 0.8937805175781277 +1.056875 0.014801025390625 0.13946533203125 0.8937805175781277 +1.057 0.014251708984375 0.134429931640625 0.8937805175781277 +1.057125 0.014251708984375 0.134429931640625 0.8937805175781277 +1.05725 0.01373291015625 0.129364013671875 0.8937805175781277 +1.057375 0.01318359375 0.124298095703125 0.8937805175781277 +1.0575 0.01318359375 0.124298095703125 0.8937805175781277 +1.057625 0.01263427734375 0.119232177734375 0.8937805175781277 +1.05775 0.01263427734375 0.119232177734375 0.8937805175781277 +1.0578750000000002 0.012115478515625 0.1141357421875 0.8937805175781277 +1.058 0.011566162109375 0.109039306640625 0.8937805175781277 +1.058125 0.011566162109375 0.109039306640625 0.8937805175781277 +1.05825 0.011016845703125 0.103912353515625 0.8937805175781277 +1.058375 0.011016845703125 0.103912353515625 0.8937805175781277 +1.0585 0.010467529296875 0.098785400390625 0.8937805175781277 +1.058625 0.009918212890625 0.093658447265625 0.8937805175781277 +1.05875 0.009918212890625 0.093658447265625 0.8937805175781277 +1.058875 0.009368896484375 0.0885009765625 0.8937805175781277 +1.059 0.009368896484375 0.0885009765625 0.8937805175781277 +1.059125 0.008819580078125 0.083343505859375 0.8937805175781277 +1.05925 0.008270263671875 0.07818603515625 0.8937805175781277 +1.059375 0.008270263671875 0.07818603515625 0.8937805175781277 +1.0595 0.007720947265625 0.072998046875 0.8937805175781277 +1.059625 0.007720947265625 0.072998046875 0.8937805175781277 +1.05975 0.007171630859375 0.06781005859375 0.8937805175781277 +1.0598750000000002 0.006622314453125 0.0626220703125 0.8937805175781277 +1.06 0.006622314453125 0.0626220703125 0.8937805175781277 +1.060125 0.006072998046875 0.05743408203125 0.8937805175781277 +1.06025 0.006072998046875 0.05743408203125 0.8937805175781277 +1.060375 0.005523681640625 0.05224609375 0.8937805175781277 +1.0605 0.004974365234375 0.047027587890625 0.8937805175781277 +1.060625 0.004974365234375 0.047027587890625 0.8937805175781277 +1.06075 0.004425048828125 0.04180908203125 0.8937805175781277 +1.060875 0.004425048828125 0.04180908203125 0.8937805175781277 +1.061 0.003875732421875 0.036590576171875 0.8937805175781277 +1.061125 0.003326416015625 0.0313720703125 0.8937805175781277 +1.06125 0.003326416015625 0.0313720703125 0.8937805175781277 +1.061375 0.00274658203125 0.026123046875 0.8937805175781277 +1.0615 0.00274658203125 0.026123046875 0.8937805175781277 +1.061625 0.002197265625 0.020904541015625 0.8937805175781277 +1.06175 0.00164794921875 0.01568603515625 0.8937805175781277 +1.0618750000000002 0.00164794921875 0.01568603515625 0.8937805175781277 +1.062 0.0010986328125 0.01043701171875 0.8937805175781277 +1.062125 0.0010986328125 0.01043701171875 0.8937805175781277 +1.06225 0.00054931640625 0.005218505859375 0.8937805175781277 +1.062375 0.0 0.0 0.8937805175781277 +1.0625 0.0 0.0 0.8937805175781277 +1.062625 -0.00054931640625 -0.005218505859375 0.8937805175781277 +1.06275 -0.00054931640625 -0.005218505859375 0.8937805175781277 +1.062875 -0.0010986328125 -0.01043701171875 0.8937805175781277 +1.063 -0.00164794921875 -0.01568603515625 0.8937805175781277 +1.063125 -0.00164794921875 -0.01568603515625 0.8937805175781277 +1.06325 -0.002197265625 -0.020904541015625 0.8937805175781277 +1.063375 -0.002197265625 -0.020904541015625 0.8937805175781277 +1.0635000000000002 -0.00274658203125 -0.026123046875 0.8937805175781277 +1.063625 -0.003326416015625 -0.0313720703125 0.8937805175781277 +1.06375 -0.003326416015625 -0.0313720703125 0.8937805175781277 +1.0638750000000002 -0.003875732421875 -0.036590576171875 0.8937805175781277 +1.064 -0.003875732421875 -0.036590576171875 0.8937805175781277 +1.064125 -0.004425048828125 -0.04180908203125 0.8937805175781277 +1.06425 -0.004974365234375 -0.047027587890625 0.8937805175781277 +1.064375 -0.004974365234375 -0.047027587890625 0.8937805175781277 +1.0645 -0.005523681640625 -0.05224609375 0.8937805175781277 +1.064625 -0.005523681640625 -0.05224609375 0.8937805175781277 +1.06475 -0.006072998046875 -0.05743408203125 0.8937805175781277 +1.064875 -0.006622314453125 -0.0626220703125 0.8937805175781277 +1.065 -0.006622314453125 -0.0626220703125 0.8937805175781277 +1.065125 -0.007171630859375 -0.06781005859375 0.8937805175781277 +1.06525 -0.007171630859375 -0.06781005859375 0.8937805175781277 +1.065375 -0.007720947265625 -0.072998046875 0.8937805175781277 +1.0655000000000002 -0.008270263671875 -0.07818603515625 0.8937805175781277 +1.065625 -0.008270263671875 -0.07818603515625 0.8937805175781277 +1.06575 -0.008819580078125 -0.083343505859375 0.8937805175781277 +1.0658750000000002 -0.008819580078125 -0.083343505859375 0.8937805175781277 +1.066 -0.009368896484375 -0.0885009765625 0.8937805175781277 +1.066125 -0.009918212890625 -0.093658447265625 0.8937805175781277 +1.06625 -0.009918212890625 -0.093658447265625 0.8937805175781277 +1.066375 -0.010467529296875 -0.098785400390625 0.8937805175781277 +1.0665 -0.010467529296875 -0.098785400390625 0.8937805175781277 +1.066625 -0.011016845703125 -0.103912353515625 0.8937805175781277 +1.06675 -0.011566162109375 -0.109039306640625 0.8937805175781277 +1.066875 -0.011566162109375 -0.109039306640625 0.8937805175781277 +1.067 -0.012115478515625 -0.1141357421875 0.8937805175781277 +1.067125 -0.012115478515625 -0.1141357421875 0.8937805175781277 +1.06725 -0.01263427734375 -0.119232177734375 0.8937805175781277 +1.067375 -0.01318359375 -0.124298095703125 0.8937805175781277 +1.0675000000000002 -0.01318359375 -0.124298095703125 0.8937805175781277 +1.067625 -0.01373291015625 -0.129364013671875 0.8937805175781277 +1.06775 -0.01373291015625 -0.129364013671875 0.8937805175781277 +1.0678750000000002 -0.014251708984375 -0.134429931640625 0.8937805175781277 +1.068 -0.014801025390625 -0.13946533203125 0.8937805175781277 +1.068125 -0.014801025390625 -0.13946533203125 0.8937805175781277 +1.06825 -0.01531982421875 -0.14447021484375 0.8937805175781277 +1.068375 -0.01531982421875 -0.14447021484375 0.8937805175781277 +1.0685 -0.015838623046875 -0.14947509765625 0.8937805175781277 +1.068625 -0.016387939453125 -0.15447998046875 0.8937805175781277 +1.06875 -0.016387939453125 -0.15447998046875 0.8937805175781277 +1.068875 -0.01690673828125 -0.159454345703125 0.8937805175781277 +1.069 -0.01690673828125 -0.159454345703125 0.8937805175781277 +1.069125 -0.017425537109375 -0.164398193359375 0.8937805175781277 +1.06925 -0.017974853515625 -0.169342041015625 0.8937805175781277 +1.069375 -0.017974853515625 -0.169342041015625 0.8937805175781277 +1.0695000000000002 -0.01849365234375 -0.17425537109375 0.8937805175781277 +1.069625 -0.01849365234375 -0.17425537109375 0.8937805175781277 +1.06975 -0.019012451171875 -0.17913818359375 0.8937805175781277 +1.0698750000000002 -0.01953125 -0.18402099609375 0.8937805175781277 +1.07 -0.01953125 -0.18402099609375 0.8937805175781277 +1.070125 -0.020050048828125 -0.188873291015625 0.8937805175781277 +1.07025 -0.020050048828125 -0.188873291015625 0.8937805175781277 +1.070375 -0.020538330078125 -0.1937255859375 0.8937805175781277 +1.0705 -0.02105712890625 -0.19854736328125 0.8937805175781277 +1.070625 -0.02105712890625 -0.19854736328125 0.8937805175781277 +1.07075 -0.021575927734375 -0.203338623046875 0.8937805175781277 +1.070875 -0.021575927734375 -0.203338623046875 0.8937805175781277 +1.071 -0.022064208984375 -0.208099365234375 0.8937805175781277 +1.071125 -0.0225830078125 -0.212860107421875 0.8937805175781277 +1.07125 -0.0225830078125 -0.212860107421875 0.8937805175781277 +1.071375 -0.0230712890625 -0.21759033203125 0.8937805175781277 +1.0715000000000002 -0.0230712890625 -0.21759033203125 0.8937805175781277 +1.071625 -0.023590087890625 -0.2222900390625 0.8937805175781277 +1.07175 -0.024078369140625 -0.226959228515625 0.8937805175781277 +1.0718750000000002 -0.024078369140625 -0.226959228515625 0.8937805175781277 +1.072 -0.024566650390625 -0.231597900390625 0.8937805175781277 +1.072125 -0.024566650390625 -0.231597900390625 0.8937805175781277 +1.07225 -0.025054931640625 -0.236236572265625 0.8937805175781277 +1.072375 -0.025543212890625 -0.2408447265625 0.8937805175781277 +1.0725 -0.025543212890625 -0.2408447265625 0.8937805175781277 +1.072625 -0.026031494140625 -0.24542236328125 0.8937805175781277 +1.07275 -0.026031494140625 -0.24542236328125 0.8937805175781277 +1.072875 -0.026519775390625 -0.249969482421875 0.8937805175781277 +1.073 -0.027008056640625 -0.25445556640625 0.8937805175781277 +1.073125 -0.027008056640625 -0.25445556640625 0.8937805175781277 +1.07325 -0.0274658203125 -0.25897216796875 0.8937805175781277 +1.073375 -0.0274658203125 -0.25897216796875 0.8937805175781277 +1.0735000000000002 -0.0279541015625 -0.263427734375 0.8937805175781277 +1.073625 -0.028411865234375 -0.267852783203125 0.8937805175781277 +1.07375 -0.028411865234375 -0.267852783203125 0.8937805175781277 +1.073875 -0.028900146484375 -0.27227783203125 0.8937805175781277 +1.074 -0.028900146484375 -0.27227783203125 0.8937805175781277 +1.074125 -0.02935791015625 -0.276641845703125 0.8937805175781277 +1.07425 -0.029815673828125 -0.280975341796875 0.8937805175781277 +1.074375 -0.029815673828125 -0.280975341796875 0.8937805175781277 +1.0745 -0.0302734375 -0.285308837890625 0.8937805175781277 +1.074625 -0.0302734375 -0.285308837890625 0.8937805175781277 +1.07475 -0.030731201171875 -0.289581298828125 0.8937805175781277 +1.074875 -0.03118896484375 -0.2938232421875 0.8937805175781277 +1.075 -0.03118896484375 -0.2938232421875 0.8937805175781277 +1.075125 -0.0316162109375 -0.298065185546875 0.8937805175781277 +1.07525 -0.0316162109375 -0.298065185546875 0.8937805175781277 +1.075375 -0.032073974609375 -0.30224609375 0.8937805175781277 +1.0755000000000002 -0.032501220703125 -0.306396484375 0.8937805175781277 +1.075625 -0.032501220703125 -0.306396484375 0.8937805175781277 +1.07575 -0.032958984375 -0.310516357421875 0.8937805175781277 +1.075875 -0.032958984375 -0.310516357421875 0.8937805175781277 +1.076 -0.03338623046875 -0.314605712890625 0.8937805175781277 +1.076125 -0.0338134765625 -0.31866455078125 0.8937805175781277 +1.07625 -0.0338134765625 -0.31866455078125 0.8937805175781277 +1.076375 -0.03424072265625 -0.322662353515625 0.8937805175781277 +1.0765 -0.03424072265625 -0.322662353515625 0.8937805175781277 +1.076625 -0.03466796875 -0.32666015625 0.8937805175781277 +1.07675 -0.035064697265625 -0.330596923828125 0.8937805175781277 +1.076875 -0.035064697265625 -0.330596923828125 0.8937805175781277 +1.077 -0.035491943359375 -0.334503173828125 0.8937805175781277 +1.077125 -0.035491943359375 -0.334503173828125 0.8937805175781277 +1.07725 -0.035919189453125 -0.33837890625 0.8937805175781277 +1.077375 -0.03631591796875 -0.34222412109375 0.8937805175781277 +1.0775000000000002 -0.03631591796875 -0.34222412109375 0.8937805175781277 +1.077625 -0.036712646484375 -0.34600830078125 0.8937805175781277 +1.07775 -0.036712646484375 -0.34600830078125 0.8937805175781277 +1.077875 -0.037109375 -0.349761962890625 0.8937805175781277 +1.078 -0.037506103515625 -0.353485107421875 0.8937805175781277 +1.078125 -0.037506103515625 -0.353485107421875 0.8937805175781277 +1.07825 -0.03790283203125 -0.357177734375 0.8937805175781277 +1.078375 -0.03790283203125 -0.357177734375 0.8937805175781277 +1.0785 -0.038299560546875 -0.360809326171875 0.8937805175781277 +1.078625 -0.038665771484375 -0.36444091796875 0.8937805175781277 +1.07875 -0.038665771484375 -0.36444091796875 0.8937805175781277 +1.078875 -0.039031982421875 -0.36798095703125 0.8937805175781277 +1.079 -0.039031982421875 -0.36798095703125 0.8937805175781277 +1.0791250000000002 -0.0394287109375 -0.37152099609375 0.8937805175781277 +1.07925 -0.039794921875 -0.375 0.8937805175781277 +1.079375 -0.039794921875 -0.375 0.8937805175781277 +1.0795000000000002 -0.0401611328125 -0.378448486328125 0.8937805175781277 +1.079625 -0.0401611328125 -0.378448486328125 0.8937805175781277 +1.07975 -0.04052734375 -0.3818359375 0.8937805175781277 +1.079875 -0.040863037109375 -0.38519287109375 0.8937805175781277 +1.08 -0.040863037109375 -0.38519287109375 0.8937805175781277 +1.080125 -0.041229248046875 -0.388519287109375 0.8937805175781277 +1.08025 -0.041229248046875 -0.388519287109375 0.8937805175781277 +1.080375 -0.04156494140625 -0.39178466796875 0.8937805175781277 +1.0805 -0.04193115234375 -0.39501953125 0.8937805175781277 +1.080625 -0.04193115234375 -0.39501953125 0.8937805175781277 +1.08075 -0.042266845703125 -0.398193359375 0.8937805175781277 +1.080875 -0.042266845703125 -0.398193359375 0.8937805175781277 +1.081 -0.0426025390625 -0.401336669921875 0.8937805175781277 +1.0811250000000002 -0.04290771484375 -0.404449462890625 0.8937805175781277 +1.08125 -0.04290771484375 -0.404449462890625 0.8937805175781277 +1.081375 -0.043243408203125 -0.407501220703125 0.8937805175781277 +1.0815000000000002 -0.043243408203125 -0.407501220703125 0.8937805175781277 +1.081625 -0.043548583984375 -0.4105224609375 0.8937805175781277 +1.08175 -0.04388427734375 -0.413482666015625 0.8937805175781277 +1.081875 -0.04388427734375 -0.413482666015625 0.8937805175781277 +1.082 -0.044189453125 -0.416412353515625 0.8937805175781277 +1.082125 -0.044189453125 -0.416412353515625 0.8937805175781277 +1.08225 -0.04449462890625 -0.419281005859375 0.8937805175781277 +1.082375 -0.0447998046875 -0.422119140625 0.8937805175781277 +1.0825 -0.0447998046875 -0.422119140625 0.8937805175781277 +1.082625 -0.045074462890625 -0.424896240234375 0.8937805175781277 +1.08275 -0.045074462890625 -0.424896240234375 0.8937805175781277 +1.082875 -0.045379638671875 -0.4276123046875 0.8937805175781277 +1.083 -0.045654296875 -0.4302978515625 0.8937805175781277 +1.0831250000000002 -0.045654296875 -0.4302978515625 0.8937805175781277 +1.08325 -0.045928955078125 -0.432952880859375 0.8937805175781277 +1.083375 -0.045928955078125 -0.432952880859375 0.8937805175781277 +1.0835000000000002 -0.04620361328125 -0.435546875 0.8937805175781277 +1.083625 -0.046478271484375 -0.438079833984375 0.8937805175781277 +1.08375 -0.046478271484375 -0.438079833984375 0.8937805175781277 +1.083875 -0.0467529296875 -0.440582275390625 0.8937805175781277 +1.084 -0.0467529296875 -0.440582275390625 0.8937805175781277 +1.084125 -0.047027587890625 -0.44305419921875 0.8937805175781277 +1.08425 -0.047271728515625 -0.4454345703125 0.8937805175781277 +1.084375 -0.047271728515625 -0.4454345703125 0.8937805175781277 +1.0845 -0.047515869140625 -0.447784423828125 0.8937805175781277 +1.084625 -0.047515869140625 -0.447784423828125 0.8937805175781277 +1.08475 -0.047760009765625 -0.450103759765625 0.8937805175781277 +1.084875 -0.048004150390625 -0.452362060546875 0.8937805175781277 +1.085 -0.048004150390625 -0.452362060546875 0.8937805175781277 +1.0851250000000002 -0.048248291015625 -0.454559326171875 0.8937805175781277 +1.08525 -0.048248291015625 -0.454559326171875 0.8937805175781277 +1.085375 -0.0484619140625 -0.45672607421875 0.8937805175781277 +1.0855000000000002 -0.048675537109375 -0.458831787109375 0.8937805175781277 +1.085625 -0.048675537109375 -0.458831787109375 0.8937805175781277 +1.08575 -0.048919677734375 -0.46087646484375 0.8937805175781277 +1.085875 -0.048919677734375 -0.46087646484375 0.8937805175781277 +1.086 -0.04913330078125 -0.462890625 0.8937805175781277 +1.086125 -0.04931640625 -0.464813232421875 0.8937805175781277 +1.08625 -0.04931640625 -0.464813232421875 0.8937805175781277 +1.086375 -0.049530029296875 -0.46673583984375 0.8937805175781277 +1.0865 -0.049530029296875 -0.46673583984375 0.8937805175781277 +1.086625 -0.049713134765625 -0.46856689453125 0.8937805175781277 +1.08675 -0.0499267578125 -0.470367431640625 0.8937805175781277 +1.086875 -0.0499267578125 -0.470367431640625 0.8937805175781277 +1.087 -0.05010986328125 -0.472137451171875 0.8937805175781277 +1.0871250000000002 -0.05010986328125 -0.472137451171875 0.8937805175781277 +1.08725 -0.05029296875 -0.47381591796875 0.8937805175781277 +1.087375 -0.050445556640625 -0.4754638671875 0.8937805175781277 +1.0875000000000002 -0.050445556640625 -0.4754638671875 0.8937805175781277 +1.087625 -0.050628662109375 -0.47705078125 0.8937805175781277 +1.08775 -0.050628662109375 -0.47705078125 0.8937805175781277 +1.087875 -0.05078125 -0.478607177734375 0.8937805175781277 +1.088 -0.00091552734375 -0.480072021484375 0.9979858398437503488 +1.088125 -0.00091552734375 -0.480072021484375 0.9979858398437503488 +1.08825 -0.00091552734375 -0.48150634765625 0.9979858398437503488 +1.088375 -0.00091552734375 -0.48150634765625 0.9979858398437503488 +1.0885 -0.00091552734375 -0.48291015625 0.9979858398437503488 +1.088625 -0.00091552734375 -0.484222412109375 0.9979858398437503488 +1.08875 -0.00091552734375 -0.484222412109375 0.9979858398437503488 +1.088875 -0.00091552734375 -0.485504150390625 0.9979858398437503488 +1.089 -0.00091552734375 -0.485504150390625 0.9979858398437503488 +1.0891250000000002 -0.00091552734375 -0.486724853515625 0.9979858398437503488 +1.08925 -0.00091552734375 -0.487884521484375 0.9979858398437503488 +1.089375 -0.00091552734375 -0.487884521484375 0.9979858398437503488 +1.0895 -0.00091552734375 -0.489013671875 0.9979858398437503488 +1.089625 -0.00091552734375 -0.489013671875 0.9979858398437503488 +1.08975 -0.00091552734375 -0.490081787109375 0.9979858398437503488 +1.089875 -0.00091552734375 -0.4910888671875 0.9979858398437503488 +1.09 -0.00091552734375 -0.4910888671875 0.9979858398437503488 +1.090125 -0.000946044921875 -0.492034912109375 0.9979858398437503488 +1.09025 -0.000946044921875 -0.492034912109375 0.9979858398437503488 +1.090375 -0.000946044921875 -0.492950439453125 0.9979858398437503488 +1.0905 -0.000946044921875 -0.4937744140625 0.9979858398437503488 +1.090625 -0.000946044921875 -0.4937744140625 0.9979858398437503488 +1.09075 -0.000946044921875 -0.49456787109375 0.9979858398437503488 +1.090875 -0.000946044921875 -0.49456787109375 0.9979858398437503488 +1.091 -0.000946044921875 -0.49530029296875 0.9979858398437503488 +1.0911250000000002 -0.000946044921875 -0.496002197265625 0.9979858398437503488 +1.09125 -0.000946044921875 -0.496002197265625 0.9979858398437503488 +1.091375 -0.000946044921875 -0.496612548828125 0.9979858398437503488 +1.0915 -0.000946044921875 -0.496612548828125 0.9979858398437503488 +1.091625 -0.000946044921875 -0.4971923828125 0.9979858398437503488 +1.09175 -0.000946044921875 -0.497711181640625 0.9979858398437503488 +1.091875 -0.000946044921875 -0.497711181640625 0.9979858398437503488 +1.092 -0.000946044921875 -0.498199462890625 0.9979858398437503488 +1.092125 -0.000946044921875 -0.498199462890625 0.9979858398437503488 +1.09225 -0.000946044921875 -0.49859619140625 0.9979858398437503488 +1.092375 -0.000946044921875 -0.49896240234375 0.9979858398437503488 +1.0925 -0.000946044921875 -0.49896240234375 0.9979858398437503488 +1.092625 -0.000946044921875 -0.499267578125 0.9979858398437503488 +1.09275 -0.000946044921875 -0.499267578125 0.9979858398437503488 +1.092875 -0.000946044921875 -0.49951171875 0.9979858398437503488 +1.093 -0.000946044921875 -0.49969482421875 0.9979858398437503488 +1.0931250000000002 -0.000946044921875 -0.49969482421875 0.9979858398437503488 +1.09325 -0.000946044921875 -0.49981689453125 0.9979858398437503488 +1.093375 -0.000946044921875 -0.49981689453125 0.9979858398437503488 +1.0935 -0.000946044921875 -0.499908447265625 0.9979858398437503488 +1.093625 -0.000946044921875 -0.49993896484375 0.9979858398437503488 +1.09375 -0.000946044921875 -0.49993896484375 0.9979858398437503488 +1.093875 -0.000946044921875 -0.499908447265625 0.9979858398437503488 +1.094 -0.000946044921875 -0.499908447265625 0.9979858398437503488 +1.094125 -0.000946044921875 -0.49981689453125 0.9979858398437503488 +1.09425 -0.000946044921875 -0.49969482421875 0.9979858398437503488 +1.094375 -0.000946044921875 -0.49969482421875 0.9979858398437503488 +1.0945 -0.000946044921875 -0.49951171875 0.9979858398437503488 +1.094625 -0.000946044921875 -0.49951171875 0.9979858398437503488 +1.0947500000000002 -0.000946044921875 -0.499267578125 0.9979858398437503488 +1.094875 -0.000946044921875 -0.49896240234375 0.9979858398437503488 +1.095 -0.000946044921875 -0.49896240234375 0.9979858398437503488 +1.0951250000000002 -0.000946044921875 -0.49859619140625 0.9979858398437503488 +1.09525 -0.000946044921875 -0.49859619140625 0.9979858398437503488 +1.095375 -0.000946044921875 -0.498199462890625 0.9979858398437503488 +1.0955 -0.000946044921875 -0.497711181640625 0.9979858398437503488 +1.095625 -0.000946044921875 -0.497711181640625 0.9979858398437503488 +1.09575 -0.000946044921875 -0.4971923828125 0.9979858398437503488 +1.095875 -0.000946044921875 -0.4971923828125 0.9979858398437503488 +1.096 -0.000946044921875 -0.496612548828125 0.9979858398437503488 +1.096125 -0.000946044921875 -0.496002197265625 0.9979858398437503488 +1.09625 -0.000946044921875 -0.496002197265625 0.9979858398437503488 +1.096375 -0.000946044921875 -0.49530029296875 0.9979858398437503488 +1.0965 -0.000946044921875 -0.49530029296875 0.9979858398437503488 +1.096625 -0.000946044921875 -0.49456787109375 0.9979858398437503488 +1.0967500000000002 -0.000946044921875 -0.4937744140625 0.9979858398437503488 +1.096875 -0.000946044921875 -0.4937744140625 0.9979858398437503488 +1.097 -0.000946044921875 -0.492950439453125 0.9979858398437503488 +1.0971250000000002 -0.000946044921875 -0.492950439453125 0.9979858398437503488 +1.09725 -0.000946044921875 -0.492034912109375 0.9979858398437503488 +1.097375 -0.00091552734375 -0.4910888671875 0.9979858398437503488 +1.0975 -0.00091552734375 -0.4910888671875 0.9979858398437503488 +1.097625 -0.00091552734375 -0.490081787109375 0.9979858398437503488 +1.09775 -0.00091552734375 -0.490081787109375 0.9979858398437503488 +1.097875 -0.00091552734375 -0.489013671875 0.9979858398437503488 +1.098 -0.00091552734375 -0.487884521484375 0.9979858398437503488 +1.098125 -0.00091552734375 -0.487884521484375 0.9979858398437503488 +1.09825 -0.00091552734375 -0.486724853515625 0.9979858398437503488 +1.098375 -0.00091552734375 -0.486724853515625 0.9979858398437503488 +1.0985 -0.00091552734375 -0.485504150390625 0.9979858398437503488 +1.098625 -0.00091552734375 -0.484222412109375 0.9979858398437503488 +1.0987500000000002 -0.00091552734375 -0.484222412109375 0.9979858398437503488 +1.098875 -0.00091552734375 -0.48291015625 0.9979858398437503488 +1.099 -0.00091552734375 -0.48291015625 0.9979858398437503488 +1.0991250000000002 -0.00091552734375 -0.48150634765625 0.9979858398437503488 +1.09925 -0.00091552734375 -0.480072021484375 0.9979858398437503488 +1.099375 -0.00091552734375 -0.480072021484375 0.9979858398437503488 +1.0995 -0.00091552734375 -0.478607177734375 0.9979858398437503488 +1.099625 -0.00091552734375 -0.478607177734375 0.9979858398437503488 +1.09975 -0.00091552734375 -0.47705078125 0.9979858398437503488 +1.099875 -0.000885009765625 -0.4754638671875 0.9979858398437503488 +1.1 -0.000885009765625 -0.4754638671875 0.9979858398437503488 +1.100125 -0.000885009765625 -0.47381591796875 0.9979858398437503488 +1.10025 -0.000885009765625 -0.47381591796875 0.9979858398437503488 +1.100375 -0.000885009765625 -0.472137451171875 0.9979858398437503488 +1.1005 -0.000885009765625 -0.470367431640625 0.9979858398437503488 +1.100625 -0.000885009765625 -0.470367431640625 0.9979858398437503488 +1.1007500000000002 -0.000885009765625 -0.46856689453125 0.9979858398437503488 +1.100875 -0.000885009765625 -0.46856689453125 0.9979858398437503488 +1.101 -0.000885009765625 -0.46673583984375 0.9979858398437503488 +1.1011250000000002 -0.000885009765625 -0.464813232421875 0.9979858398437503488 +1.10125 -0.000885009765625 -0.464813232421875 0.9979858398437503488 +1.101375 -0.000885009765625 -0.462890625 0.9979858398437503488 +1.1015 -0.000885009765625 -0.462890625 0.9979858398437503488 +1.101625 -0.000885009765625 -0.46087646484375 0.9979858398437503488 +1.10175 -0.0008544921875 -0.458831787109375 0.9979858398437503488 +1.101875 -0.0008544921875 -0.458831787109375 0.9979858398437503488 +1.102 -0.0008544921875 -0.45672607421875 0.9979858398437503488 +1.102125 -0.0008544921875 -0.45672607421875 0.9979858398437503488 +1.10225 -0.0008544921875 -0.454559326171875 0.9979858398437503488 +1.102375 -0.0008544921875 -0.452362060546875 0.9979858398437503488 +1.1025 -0.0008544921875 -0.452362060546875 0.9979858398437503488 +1.102625 -0.0008544921875 -0.450103759765625 0.9979858398437503488 +1.1027500000000002 -0.0008544921875 -0.450103759765625 0.9979858398437503488 +1.102875 -0.0008544921875 -0.447784423828125 0.9979858398437503488 +1.103 -0.0008544921875 -0.4454345703125 0.9979858398437503488 +1.1031250000000002 -0.0008544921875 -0.4454345703125 0.9979858398437503488 +1.10325 -0.000823974609375 -0.44305419921875 0.9979858398437503488 +1.103375 -0.000823974609375 -0.44305419921875 0.9979858398437503488 +1.1035 -0.000823974609375 -0.440582275390625 0.9979858398437503488 +1.103625 -0.000823974609375 -0.438079833984375 0.9979858398437503488 +1.10375 -0.000823974609375 -0.438079833984375 0.9979858398437503488 +1.103875 -0.000823974609375 -0.435546875 0.9979858398437503488 +1.104 -0.000823974609375 -0.435546875 0.9979858398437503488 +1.104125 -0.000823974609375 -0.432952880859375 0.9979858398437503488 +1.10425 -0.000823974609375 -0.4302978515625 0.9979858398437503488 +1.104375 -0.000823974609375 -0.4302978515625 0.9979858398437503488 +1.1045 -0.00079345703125 -0.4276123046875 0.9979858398437503488 +1.104625 -0.00079345703125 -0.4276123046875 0.9979858398437503488 +1.1047500000000002 -0.00079345703125 -0.424896240234375 0.9979858398437503488 +1.104875 -0.00079345703125 -0.422119140625 0.9979858398437503488 +1.105 -0.00079345703125 -0.422119140625 0.9979858398437503488 +1.105125 -0.00079345703125 -0.419281005859375 0.9979858398437503488 +1.10525 -0.00079345703125 -0.419281005859375 0.9979858398437503488 +1.105375 -0.00079345703125 -0.416412353515625 0.9979858398437503488 +1.1055 -0.00079345703125 -0.413482666015625 0.9979858398437503488 +1.105625 -0.00079345703125 -0.413482666015625 0.9979858398437503488 +1.10575 -0.000762939453125 -0.4105224609375 0.9979858398437503488 +1.105875 -0.000762939453125 -0.4105224609375 0.9979858398437503488 +1.106 -0.000762939453125 -0.407501220703125 0.9979858398437503488 +1.106125 -0.000762939453125 -0.404449462890625 0.9979858398437503488 +1.10625 -0.000762939453125 -0.404449462890625 0.9979858398437503488 +1.106375 -0.000762939453125 -0.401336669921875 0.9979858398437503488 +1.1065 -0.000762939453125 -0.401336669921875 0.9979858398437503488 +1.106625 -0.000762939453125 -0.398193359375 0.9979858398437503488 +1.1067500000000002 -0.000732421875 -0.39501953125 0.9979858398437503488 +1.106875 -0.000732421875 -0.39501953125 0.9979858398437503488 +1.107 -0.000732421875 -0.39178466796875 0.9979858398437503488 +1.107125 -0.000732421875 -0.39178466796875 0.9979858398437503488 +1.10725 -0.000732421875 -0.388519287109375 0.9979858398437503488 +1.107375 -0.000732421875 -0.38519287109375 0.9979858398437503488 +1.1075 -0.000732421875 -0.38519287109375 0.9979858398437503488 +1.107625 -0.000732421875 -0.3818359375 0.9979858398437503488 +1.10775 -0.000732421875 -0.3818359375 0.9979858398437503488 +1.107875 -0.000701904296875 -0.378448486328125 0.9979858398437503488 +1.108 -0.000701904296875 -0.375 0.9979858398437503488 +1.108125 -0.000701904296875 -0.375 0.9979858398437503488 +1.10825 -0.000701904296875 -0.37152099609375 0.9979858398437503488 +1.108375 -0.000701904296875 -0.37152099609375 0.9979858398437503488 +1.1085 -0.000701904296875 -0.36798095703125 0.9979858398437503488 +1.108625 -0.00067138671875 -0.36444091796875 0.9979858398437503488 +1.1087500000000002 -0.00067138671875 -0.36444091796875 0.9979858398437503488 +1.108875 -0.00067138671875 -0.360809326171875 0.9979858398437503488 +1.109 -0.00067138671875 -0.360809326171875 0.9979858398437503488 +1.109125 -0.00067138671875 -0.357177734375 0.9979858398437503488 +1.10925 -0.00067138671875 -0.353485107421875 0.9979858398437503488 +1.109375 -0.00067138671875 -0.353485107421875 0.9979858398437503488 +1.1095 -0.00067138671875 -0.349761962890625 0.9979858398437503488 +1.109625 -0.00067138671875 -0.349761962890625 0.9979858398437503488 +1.10975 -0.000640869140625 -0.34600830078125 0.9979858398437503488 +1.109875 -0.000640869140625 -0.34222412109375 0.9979858398437503488 +1.11 -0.000640869140625 -0.34222412109375 0.9979858398437503488 +1.110125 -0.000640869140625 -0.33837890625 0.9979858398437503488 +1.11025 -0.000640869140625 -0.33837890625 0.9979858398437503488 +1.1103750000000002 -0.000640869140625 -0.334503173828125 0.9979858398437503488 +1.1105 -0.0006103515625 -0.330596923828125 0.9979858398437503488 +1.110625 -0.0006103515625 -0.330596923828125 0.9979858398437503488 +1.1107500000000002 -0.0006103515625 -0.32666015625 0.9979858398437503488 +1.110875 -0.0006103515625 -0.32666015625 0.9979858398437503488 +1.111 -0.0006103515625 -0.322662353515625 0.9979858398437503488 +1.111125 -0.0006103515625 -0.31866455078125 0.9979858398437503488 +1.11125 -0.0006103515625 -0.31866455078125 0.9979858398437503488 +1.111375 -0.000579833984375 -0.314605712890625 0.9979858398437503488 +1.1115 -0.000579833984375 -0.314605712890625 0.9979858398437503488 +1.111625 -0.000579833984375 -0.310516357421875 0.9979858398437503488 +1.11175 -0.000579833984375 -0.306396484375 0.9979858398437503488 +1.111875 -0.000579833984375 -0.306396484375 0.9979858398437503488 +1.112 -0.000579833984375 -0.30224609375 0.9979858398437503488 +1.112125 -0.000579833984375 -0.30224609375 0.9979858398437503488 +1.11225 -0.00054931640625 -0.298065185546875 0.9979858398437503488 +1.1123750000000002 -0.00054931640625 -0.2938232421875 0.9979858398437503488 +1.1125 -0.00054931640625 -0.2938232421875 0.9979858398437503488 +1.112625 -0.00054931640625 -0.289581298828125 0.9979858398437503488 +1.1127500000000002 -0.00054931640625 -0.289581298828125 0.9979858398437503488 +1.112875 -0.000518798828125 -0.285308837890625 0.9979858398437503488 +1.113 -0.000518798828125 -0.280975341796875 0.9979858398437503488 +1.113125 -0.000518798828125 -0.280975341796875 0.9979858398437503488 +1.11325 -0.000518798828125 -0.276641845703125 0.9979858398437503488 +1.113375 -0.000518798828125 -0.276641845703125 0.9979858398437503488 +1.1135 -0.000518798828125 -0.27227783203125 0.9979858398437503488 +1.113625 -0.00048828125 -0.267852783203125 0.9979858398437503488 +1.11375 -0.00048828125 -0.267852783203125 0.9979858398437503488 +1.113875 -0.00048828125 -0.263427734375 0.9979858398437503488 +1.114 -0.00048828125 -0.263427734375 0.9979858398437503488 +1.114125 -0.00048828125 -0.25897216796875 0.9979858398437503488 +1.11425 -0.00048828125 -0.25445556640625 0.9979858398437503488 +1.1143750000000002 -0.00048828125 -0.25445556640625 0.9979858398437503488 +1.1145 -0.000457763671875 -0.249969482421875 0.9979858398437503488 +1.114625 -0.000457763671875 -0.249969482421875 0.9979858398437503488 +1.1147500000000002 -0.000457763671875 -0.24542236328125 0.9979858398437503488 +1.114875 -0.000457763671875 -0.2408447265625 0.9979858398437503488 +1.115 -0.000457763671875 -0.2408447265625 0.9979858398437503488 +1.115125 -0.00042724609375 -0.236236572265625 0.9979858398437503488 +1.11525 -0.00042724609375 -0.236236572265625 0.9979858398437503488 +1.115375 -0.00042724609375 -0.231597900390625 0.9979858398437503488 +1.1155 -0.00042724609375 -0.226959228515625 0.9979858398437503488 +1.115625 -0.00042724609375 -0.226959228515625 0.9979858398437503488 +1.11575 -0.00042724609375 -0.2222900390625 0.9979858398437503488 +1.115875 -0.00042724609375 -0.2222900390625 0.9979858398437503488 +1.116 -0.000396728515625 -0.21759033203125 0.9979858398437503488 +1.116125 -0.000396728515625 -0.212860107421875 0.9979858398437503488 +1.11625 -0.000396728515625 -0.212860107421875 0.9979858398437503488 +1.1163750000000002 -0.000396728515625 -0.208099365234375 0.9979858398437503488 +1.1165 -0.000396728515625 -0.208099365234375 0.9979858398437503488 +1.116625 -0.0003662109375 -0.203338623046875 0.9979858398437503488 +1.1167500000000002 -0.0003662109375 -0.19854736328125 0.9979858398437503488 +1.116875 -0.0003662109375 -0.19854736328125 0.9979858398437503488 +1.117 -0.0003662109375 -0.1937255859375 0.9979858398437503488 +1.117125 -0.0003662109375 -0.1937255859375 0.9979858398437503488 +1.11725 -0.000335693359375 -0.188873291015625 0.9979858398437503488 +1.117375 -0.000335693359375 -0.18402099609375 0.9979858398437503488 +1.1175 -0.000335693359375 -0.18402099609375 0.9979858398437503488 +1.117625 -0.000335693359375 -0.17913818359375 0.9979858398437503488 +1.11775 -0.000335693359375 -0.17913818359375 0.9979858398437503488 +1.117875 -0.00030517578125 -0.17425537109375 0.9979858398437503488 +1.118 -0.00030517578125 -0.169342041015625 0.9979858398437503488 +1.118125 -0.00030517578125 -0.169342041015625 0.9979858398437503488 +1.11825 -0.00030517578125 -0.164398193359375 0.9979858398437503488 +1.1183750000000002 -0.00030517578125 -0.164398193359375 0.9979858398437503488 +1.1185 -0.00030517578125 -0.159454345703125 0.9979858398437503488 +1.118625 -0.000274658203125 -0.15447998046875 0.9979858398437503488 +1.1187500000000002 -0.000274658203125 -0.15447998046875 0.9979858398437503488 +1.118875 -0.000274658203125 -0.14947509765625 0.9979858398437503488 +1.119 -0.000274658203125 -0.14947509765625 0.9979858398437503488 +1.119125 -0.000274658203125 -0.14447021484375 0.9979858398437503488 +1.11925 -0.000244140625 -0.13946533203125 0.9979858398437503488 +1.119375 -0.000244140625 -0.13946533203125 0.9979858398437503488 +1.1195 -0.000244140625 -0.134429931640625 0.9979858398437503488 +1.119625 -0.000244140625 -0.134429931640625 0.9979858398437503488 +1.11975 -0.000244140625 -0.129364013671875 0.9979858398437503488 +1.119875 -0.000213623046875 -0.124298095703125 0.9979858398437503488 +1.12 -0.007080078125 -0.124298095703125 0.942932128906248 +1.120125 -0.00677490234375 -0.119232177734375 0.942932128906248 +1.12025 -0.00677490234375 -0.119232177734375 0.942932128906248 +1.1203750000000002 -0.006500244140625 -0.1141357421875 0.942932128906248 +1.1205 -0.006195068359375 -0.109039306640625 0.942932128906248 +1.120625 -0.006195068359375 -0.109039306640625 0.942932128906248 +1.12075 -0.00592041015625 -0.103912353515625 0.942932128906248 +1.120875 -0.00592041015625 -0.103912353515625 0.942932128906248 +1.121 -0.005615234375 -0.098785400390625 0.942932128906248 +1.121125 -0.00531005859375 -0.093658447265625 0.942932128906248 +1.12125 -0.00531005859375 -0.093658447265625 0.942932128906248 +1.121375 -0.005035400390625 -0.0885009765625 0.942932128906248 +1.1215 -0.005035400390625 -0.0885009765625 0.942932128906248 +1.121625 -0.004730224609375 -0.083343505859375 0.942932128906248 +1.12175 -0.00445556640625 -0.07818603515625 0.942932128906248 +1.121875 -0.00445556640625 -0.07818603515625 0.942932128906248 +1.122 -0.004150390625 -0.072998046875 0.942932128906248 +1.122125 -0.004150390625 -0.072998046875 0.942932128906248 +1.12225 -0.00384521484375 -0.06781005859375 0.942932128906248 +1.1223750000000002 -0.0035400390625 -0.0626220703125 0.942932128906248 +1.1225 -0.0035400390625 -0.0626220703125 0.942932128906248 +1.122625 -0.003265380859375 -0.05743408203125 0.942932128906248 +1.12275 -0.003265380859375 -0.05743408203125 0.942932128906248 +1.122875 -0.002960205078125 -0.05224609375 0.942932128906248 +1.123 -0.002655029296875 -0.047027587890625 0.942932128906248 +1.123125 -0.002655029296875 -0.047027587890625 0.942932128906248 +1.12325 -0.00238037109375 -0.04180908203125 0.942932128906248 +1.123375 -0.00238037109375 -0.04180908203125 0.942932128906248 +1.1235 -0.0020751953125 -0.036590576171875 0.942932128906248 +1.123625 -0.00177001953125 -0.0313720703125 0.942932128906248 +1.12375 -0.00177001953125 -0.0313720703125 0.942932128906248 +1.123875 -0.00146484375 -0.026123046875 0.942932128906248 +1.124 -0.00146484375 -0.026123046875 0.942932128906248 +1.124125 -0.001190185546875 -0.020904541015625 0.942932128906248 +1.12425 -0.000885009765625 -0.01568603515625 0.942932128906248 +1.1243750000000002 -0.000885009765625 -0.01568603515625 0.942932128906248 +1.1245 -0.000579833984375 -0.01043701171875 0.942932128906248 +1.124625 -0.000579833984375 -0.01043701171875 0.942932128906248 +1.12475 -0.000274658203125 -0.005218505859375 0.942932128906248 +1.124875 0.0 0.0 0.942932128906248 +1.125 0.0 0.0 0.942932128906248 +1.125125 0.000274658203125 0.005218505859375 0.942932128906248 +1.12525 0.000274658203125 0.005218505859375 0.942932128906248 +1.125375 0.000579833984375 0.01043701171875 0.942932128906248 +1.1255 0.000885009765625 0.01568603515625 0.942932128906248 +1.125625 0.000885009765625 0.01568603515625 0.942932128906248 +1.12575 0.001190185546875 0.020904541015625 0.942932128906248 +1.125875 0.001190185546875 0.020904541015625 0.942932128906248 +1.1260000000000002 0.00146484375 0.026123046875 0.942932128906248 +1.126125 0.00177001953125 0.0313720703125 0.942932128906248 +1.12625 0.00177001953125 0.0313720703125 0.942932128906248 +1.1263750000000002 0.0020751953125 0.036590576171875 0.942932128906248 +1.1265 0.0020751953125 0.036590576171875 0.942932128906248 +1.126625 0.00238037109375 0.04180908203125 0.942932128906248 +1.12675 0.002655029296875 0.047027587890625 0.942932128906248 +1.126875 0.002655029296875 0.047027587890625 0.942932128906248 +1.127 0.002960205078125 0.05224609375 0.942932128906248 +1.127125 0.002960205078125 0.05224609375 0.942932128906248 +1.12725 0.003265380859375 0.05743408203125 0.942932128906248 +1.127375 0.0035400390625 0.0626220703125 0.942932128906248 +1.1275 0.0035400390625 0.0626220703125 0.942932128906248 +1.127625 0.00384521484375 0.06781005859375 0.942932128906248 +1.12775 0.00384521484375 0.06781005859375 0.942932128906248 +1.127875 0.004150390625 0.072998046875 0.942932128906248 +1.1280000000000002 0.00445556640625 0.07818603515625 0.942932128906248 +1.128125 0.00445556640625 0.07818603515625 0.942932128906248 +1.12825 0.004730224609375 0.083343505859375 0.942932128906248 +1.1283750000000002 0.004730224609375 0.083343505859375 0.942932128906248 +1.1285 0.005035400390625 0.0885009765625 0.942932128906248 +1.128625 0.00531005859375 0.093658447265625 0.942932128906248 +1.12875 0.00531005859375 0.093658447265625 0.942932128906248 +1.128875 0.005615234375 0.098785400390625 0.942932128906248 +1.129 0.005615234375 0.098785400390625 0.942932128906248 +1.129125 0.00592041015625 0.103912353515625 0.942932128906248 +1.12925 0.006195068359375 0.109039306640625 0.942932128906248 +1.129375 0.006195068359375 0.109039306640625 0.942932128906248 +1.1295 0.006500244140625 0.1141357421875 0.942932128906248 +1.129625 0.006500244140625 0.1141357421875 0.942932128906248 +1.12975 0.00677490234375 0.119232177734375 0.942932128906248 +1.129875 0.007080078125 0.124298095703125 0.942932128906248 +1.1300000000000002 0.007080078125 0.124298095703125 0.942932128906248 +1.130125 0.007354736328125 0.129364013671875 0.942932128906248 +1.13025 0.007354736328125 0.129364013671875 0.942932128906248 +1.1303750000000002 0.007659912109375 0.134429931640625 0.942932128906248 +1.1305 0.0079345703125 0.13946533203125 0.942932128906248 +1.130625 0.0079345703125 0.13946533203125 0.942932128906248 +1.13075 0.008209228515625 0.14447021484375 0.942932128906248 +1.130875 0.008209228515625 0.14447021484375 0.942932128906248 +1.131 0.008514404296875 0.14947509765625 0.942932128906248 +1.131125 0.0087890625 0.15447998046875 0.942932128906248 +1.13125 0.0087890625 0.15447998046875 0.942932128906248 +1.131375 0.009063720703125 0.159454345703125 0.942932128906248 +1.1315 0.009063720703125 0.159454345703125 0.942932128906248 +1.131625 0.00933837890625 0.164398193359375 0.942932128906248 +1.13175 0.0096435546875 0.169342041015625 0.942932128906248 +1.131875 0.0096435546875 0.169342041015625 0.942932128906248 +1.1320000000000002 0.009918212890625 0.17425537109375 0.942932128906248 +1.132125 0.009918212890625 0.17425537109375 0.942932128906248 +1.13225 0.01019287109375 0.17913818359375 0.942932128906248 +1.1323750000000002 0.010467529296875 0.18402099609375 0.942932128906248 +1.1325 0.010467529296875 0.18402099609375 0.942932128906248 +1.132625 0.0107421875 0.188873291015625 0.942932128906248 +1.13275 0.0107421875 0.188873291015625 0.942932128906248 +1.132875 0.011016845703125 0.1937255859375 0.942932128906248 +1.133 0.01129150390625 0.19854736328125 0.942932128906248 +1.133125 0.01129150390625 0.19854736328125 0.942932128906248 +1.13325 0.011566162109375 0.203338623046875 0.942932128906248 +1.133375 0.011566162109375 0.203338623046875 0.942932128906248 +1.1335 0.0118408203125 0.208099365234375 0.942932128906248 +1.133625 0.012115478515625 0.212860107421875 0.942932128906248 +1.13375 0.012115478515625 0.212860107421875 0.942932128906248 +1.133875 0.01239013671875 0.21759033203125 0.942932128906248 +1.1340000000000002 0.01239013671875 0.21759033203125 0.942932128906248 +1.134125 0.012664794921875 0.2222900390625 0.942932128906248 +1.13425 0.012908935546875 0.226959228515625 0.942932128906248 +1.1343750000000002 0.012908935546875 0.226959228515625 0.942932128906248 +1.1345 0.01318359375 0.231597900390625 0.942932128906248 +1.134625 0.01318359375 0.231597900390625 0.942932128906248 +1.13475 0.013458251953125 0.236236572265625 0.942932128906248 +1.134875 0.013702392578125 0.2408447265625 0.942932128906248 +1.135 0.013702392578125 0.2408447265625 0.942932128906248 +1.135125 0.01397705078125 0.24542236328125 0.942932128906248 +1.13525 0.01397705078125 0.24542236328125 0.942932128906248 +1.135375 0.01422119140625 0.249969482421875 0.942932128906248 +1.1355 0.014495849609375 0.25445556640625 0.942932128906248 +1.135625 0.014495849609375 0.25445556640625 0.942932128906248 +1.13575 0.014739990234375 0.25897216796875 0.942932128906248 +1.135875 0.014739990234375 0.25897216796875 0.942932128906248 +1.1360000000000002 0.014984130859375 0.263427734375 0.942932128906248 +1.136125 0.0152587890625 0.267852783203125 0.942932128906248 +1.13625 0.0152587890625 0.267852783203125 0.942932128906248 +1.136375 0.0155029296875 0.27227783203125 0.942932128906248 +1.1365 0.0155029296875 0.27227783203125 0.942932128906248 +1.136625 0.0157470703125 0.276641845703125 0.942932128906248 +1.13675 0.0159912109375 0.280975341796875 0.942932128906248 +1.136875 0.0159912109375 0.280975341796875 0.942932128906248 +1.137 0.0162353515625 0.285308837890625 0.942932128906248 +1.137125 0.0162353515625 0.285308837890625 0.942932128906248 +1.13725 0.0164794921875 0.289581298828125 0.942932128906248 +1.137375 0.0167236328125 0.2938232421875 0.942932128906248 +1.1375 0.0167236328125 0.2938232421875 0.942932128906248 +1.137625 0.0169677734375 0.298065185546875 0.942932128906248 +1.13775 0.0169677734375 0.298065185546875 0.942932128906248 +1.137875 0.0172119140625 0.30224609375 0.942932128906248 +1.1380000000000002 0.0174560546875 0.306396484375 0.942932128906248 +1.138125 0.0174560546875 0.306396484375 0.942932128906248 +1.13825 0.017669677734375 0.310516357421875 0.942932128906248 +1.138375 0.017669677734375 0.310516357421875 0.942932128906248 +1.1385 0.017913818359375 0.314605712890625 0.942932128906248 +1.138625 0.018157958984375 0.31866455078125 0.942932128906248 +1.13875 0.018157958984375 0.31866455078125 0.942932128906248 +1.138875 0.01837158203125 0.322662353515625 0.942932128906248 +1.139 0.01837158203125 0.322662353515625 0.942932128906248 +1.139125 0.018585205078125 0.32666015625 0.942932128906248 +1.13925 0.018829345703125 0.330596923828125 0.942932128906248 +1.139375 0.018829345703125 0.330596923828125 0.942932128906248 +1.1395 0.01904296875 0.334503173828125 0.942932128906248 +1.139625 0.01904296875 0.334503173828125 0.942932128906248 +1.13975 0.019256591796875 0.33837890625 0.942932128906248 +1.139875 0.01947021484375 0.34222412109375 0.942932128906248 +1.1400000000000002 0.01947021484375 0.34222412109375 0.942932128906248 +1.140125 0.01971435546875 0.34600830078125 0.942932128906248 +1.14025 0.01971435546875 0.34600830078125 0.942932128906248 +1.140375 0.019927978515625 0.349761962890625 0.942932128906248 +1.1405 0.0201416015625 0.353485107421875 0.942932128906248 +1.140625 0.0201416015625 0.353485107421875 0.942932128906248 +1.14075 0.02032470703125 0.357177734375 0.942932128906248 +1.140875 0.02032470703125 0.357177734375 0.942932128906248 +1.141 0.020538330078125 0.360809326171875 0.942932128906248 +1.141125 0.020751953125 0.36444091796875 0.942932128906248 +1.14125 0.020751953125 0.36444091796875 0.942932128906248 +1.141375 0.020965576171875 0.36798095703125 0.942932128906248 +1.1415 0.020965576171875 0.36798095703125 0.942932128906248 +1.1416250000000002 0.021148681640625 0.37152099609375 0.942932128906248 +1.14175 0.0213623046875 0.375 0.942932128906248 +1.141875 0.0213623046875 0.375 0.942932128906248 +1.1420000000000002 0.02154541015625 0.378448486328125 0.942932128906248 +1.142125 0.02154541015625 0.378448486328125 0.942932128906248 +1.14225 0.021728515625 0.3818359375 0.942932128906248 +1.142375 0.021942138671875 0.38519287109375 0.942932128906248 +1.1425 0.021942138671875 0.38519287109375 0.942932128906248 +1.142625 0.022125244140625 0.388519287109375 0.942932128906248 +1.14275 0.022125244140625 0.388519287109375 0.942932128906248 +1.142875 0.022308349609375 0.39178466796875 0.942932128906248 +1.143 0.022491455078125 0.39501953125 0.942932128906248 +1.143125 0.022491455078125 0.39501953125 0.942932128906248 +1.14325 0.022674560546875 0.398193359375 0.942932128906248 +1.143375 0.022674560546875 0.398193359375 0.942932128906248 +1.1435 0.022857666015625 0.401336669921875 0.942932128906248 +1.1436250000000002 0.023040771484375 0.404449462890625 0.942932128906248 +1.14375 0.023040771484375 0.404449462890625 0.942932128906248 +1.143875 0.023193359375 0.407501220703125 0.942932128906248 +1.1440000000000002 0.023193359375 0.407501220703125 0.942932128906248 +1.144125 0.02337646484375 0.4105224609375 0.942932128906248 +1.14425 0.0235595703125 0.413482666015625 0.942932128906248 +1.144375 0.0235595703125 0.413482666015625 0.942932128906248 +1.1445 0.023712158203125 0.416412353515625 0.942932128906248 +1.144625 0.023712158203125 0.416412353515625 0.942932128906248 +1.14475 0.02386474609375 0.419281005859375 0.942932128906248 +1.144875 0.0240478515625 0.422119140625 0.942932128906248 +1.145 0.0240478515625 0.422119140625 0.942932128906248 +1.145125 0.024200439453125 0.424896240234375 0.942932128906248 +1.14525 0.024200439453125 0.424896240234375 0.942932128906248 +1.145375 0.02435302734375 0.4276123046875 0.942932128906248 +1.1455 0.024505615234375 0.4302978515625 0.942932128906248 +1.1456250000000002 0.024505615234375 0.4302978515625 0.942932128906248 +1.14575 0.024658203125 0.432952880859375 0.942932128906248 +1.145875 0.024658203125 0.432952880859375 0.942932128906248 +1.1460000000000002 0.024810791015625 0.435546875 0.942932128906248 +1.146125 0.024932861328125 0.438079833984375 0.942932128906248 +1.14625 0.024932861328125 0.438079833984375 0.942932128906248 +1.146375 0.02508544921875 0.440582275390625 0.942932128906248 +1.1465 0.02508544921875 0.440582275390625 0.942932128906248 +1.146625 0.025238037109375 0.44305419921875 0.942932128906248 +1.14675 0.025360107421875 0.4454345703125 0.942932128906248 +1.146875 0.025360107421875 0.4454345703125 0.942932128906248 +1.147 0.0255126953125 0.447784423828125 0.942932128906248 +1.147125 0.0255126953125 0.447784423828125 0.942932128906248 +1.14725 0.025634765625 0.450103759765625 0.942932128906248 +1.147375 0.0257568359375 0.452362060546875 0.942932128906248 +1.1475 0.0257568359375 0.452362060546875 0.942932128906248 +1.1476250000000002 0.02587890625 0.454559326171875 0.942932128906248 +1.14775 0.02587890625 0.454559326171875 0.942932128906248 +1.147875 0.0260009765625 0.45672607421875 0.942932128906248 +1.1480000000000002 0.026123046875 0.458831787109375 0.942932128906248 +1.148125 0.026123046875 0.458831787109375 0.942932128906248 +1.14825 0.0262451171875 0.46087646484375 0.942932128906248 +1.148375 0.0262451171875 0.46087646484375 0.942932128906248 +1.1485 0.0263671875 0.462890625 0.942932128906248 +1.148625 0.026458740234375 0.464813232421875 0.942932128906248 +1.14875 0.026458740234375 0.464813232421875 0.942932128906248 +1.148875 0.026580810546875 0.46673583984375 0.942932128906248 +1.149 0.026580810546875 0.46673583984375 0.942932128906248 +1.149125 0.02667236328125 0.46856689453125 0.942932128906248 +1.14925 0.02679443359375 0.470367431640625 0.942932128906248 +1.149375 0.02679443359375 0.470367431640625 0.942932128906248 +1.1495 0.026885986328125 0.472137451171875 0.942932128906248 +1.1496250000000002 0.026885986328125 0.472137451171875 0.942932128906248 +1.14975 0.0269775390625 0.47381591796875 0.942932128906248 +1.149875 0.027069091796875 0.4754638671875 0.942932128906248 +1.1500000000000002 0.027069091796875 0.4754638671875 0.942932128906248 +1.150125 0.02716064453125 0.47705078125 0.942932128906248 +1.15025 0.02716064453125 0.47705078125 0.942932128906248 +1.150375 0.027252197265625 0.478607177734375 0.942932128906248 +1.1505 0.02734375 0.480072021484375 0.942932128906248 +1.150625 0.02734375 0.480072021484375 0.942932128906248 +1.15075 0.027435302734375 0.48150634765625 0.942932128906248 +1.150875 0.027435302734375 0.48150634765625 0.942932128906248 +1.151 0.027496337890625 0.48291015625 0.942932128906248 +1.151125 0.027587890625 0.484222412109375 0.942932128906248 +1.15125 0.027587890625 0.484222412109375 0.942932128906248 +1.151375 0.02764892578125 0.485504150390625 0.942932128906248 +1.1515 0.02764892578125 0.485504150390625 0.942932128906248 +1.1516250000000002 0.0277099609375 0.486724853515625 0.942932128906248 +1.15175 0.02777099609375 0.487884521484375 0.942932128906248 +1.151875 0.02777099609375 0.487884521484375 0.942932128906248 +1.1520000000000002 0.128326416015625 0.489013671875 0.737463378906246 +1.152125 0.128326416015625 0.489013671875 0.737463378906246 +1.15225 0.12860107421875 0.490081787109375 0.737463378906246 +1.152375 0.128875732421875 0.4910888671875 0.737463378906246 +1.1525 0.128875732421875 0.4910888671875 0.737463378906246 +1.152625 0.129119873046875 0.492034912109375 0.737463378906246 +1.15275 0.129119873046875 0.492034912109375 0.737463378906246 +1.152875 0.129364013671875 0.492950439453125 0.737463378906246 +1.153 0.12957763671875 0.4937744140625 0.737463378906246 +1.153125 0.12957763671875 0.4937744140625 0.737463378906246 +1.15325 0.129791259765625 0.49456787109375 0.737463378906246 +1.153375 0.129791259765625 0.49456787109375 0.737463378906246 +1.1535 0.129974365234375 0.49530029296875 0.737463378906246 +1.1536250000000002 0.130157470703125 0.496002197265625 0.737463378906246 +1.15375 0.130157470703125 0.496002197265625 0.737463378906246 +1.153875 0.130340576171875 0.496612548828125 0.737463378906246 +1.154 0.130340576171875 0.496612548828125 0.737463378906246 +1.154125 0.1304931640625 0.4971923828125 0.737463378906246 +1.15425 0.130615234375 0.497711181640625 0.737463378906246 +1.154375 0.130615234375 0.497711181640625 0.737463378906246 +1.1545 0.1307373046875 0.498199462890625 0.737463378906246 +1.154625 0.1307373046875 0.498199462890625 0.737463378906246 +1.15475 0.130859375 0.49859619140625 0.737463378906246 +1.154875 0.130950927734375 0.49896240234375 0.737463378906246 +1.155 0.130950927734375 0.49896240234375 0.737463378906246 +1.155125 0.131011962890625 0.499267578125 0.737463378906246 +1.15525 0.131011962890625 0.499267578125 0.737463378906246 +1.155375 0.131103515625 0.49951171875 0.737463378906246 +1.1555 0.131134033203125 0.49969482421875 0.737463378906246 +1.1556250000000002 0.131134033203125 0.49969482421875 0.737463378906246 +1.15575 0.13116455078125 0.49981689453125 0.737463378906246 +1.155875 0.13116455078125 0.49981689453125 0.737463378906246 +1.156 0.131195068359375 0.499908447265625 0.737463378906246 +1.156125 0.131195068359375 0.49993896484375 0.737463378906246 +1.15625 0.131195068359375 0.49993896484375 0.737463378906246 +1.156375 0.131195068359375 0.499908447265625 0.737463378906246 +1.1565 0.131195068359375 0.499908447265625 0.737463378906246 +1.156625 0.13116455078125 0.49981689453125 0.737463378906246 +1.15675 0.131134033203125 0.49969482421875 0.737463378906246 +1.156875 0.131134033203125 0.49969482421875 0.737463378906246 +1.157 0.131103515625 0.49951171875 0.737463378906246 +1.157125 0.131103515625 0.49951171875 0.737463378906246 +1.1572500000000002 0.131011962890625 0.499267578125 0.737463378906246 +1.157375 0.130950927734375 0.49896240234375 0.737463378906246 +1.1575 0.130950927734375 0.49896240234375 0.737463378906246 +1.1576250000000002 0.130859375 0.49859619140625 0.737463378906246 +1.15775 0.130859375 0.49859619140625 0.737463378906246 +1.157875 0.1307373046875 0.498199462890625 0.737463378906246 +1.158 0.130615234375 0.497711181640625 0.737463378906246 +1.158125 0.130615234375 0.497711181640625 0.737463378906246 +1.15825 0.1304931640625 0.4971923828125 0.737463378906246 +1.158375 0.1304931640625 0.4971923828125 0.737463378906246 +1.1585 0.130340576171875 0.496612548828125 0.737463378906246 +1.158625 0.130157470703125 0.496002197265625 0.737463378906246 +1.15875 0.130157470703125 0.496002197265625 0.737463378906246 +1.158875 0.129974365234375 0.49530029296875 0.737463378906246 +1.159 0.129974365234375 0.49530029296875 0.737463378906246 +1.159125 0.129791259765625 0.49456787109375 0.737463378906246 +1.1592500000000002 0.12957763671875 0.4937744140625 0.737463378906246 +1.159375 0.12957763671875 0.4937744140625 0.737463378906246 +1.1595 0.129364013671875 0.492950439453125 0.737463378906246 +1.1596250000000002 0.129364013671875 0.492950439453125 0.737463378906246 +1.15975 0.129119873046875 0.492034912109375 0.737463378906246 +1.159875 0.128875732421875 0.4910888671875 0.737463378906246 +1.16 0.128875732421875 0.4910888671875 0.737463378906246 +1.160125 0.12860107421875 0.490081787109375 0.737463378906246 +1.16025 0.12860107421875 0.490081787109375 0.737463378906246 +1.160375 0.128326416015625 0.489013671875 0.737463378906246 +1.1605 0.1280517578125 0.487884521484375 0.737463378906246 +1.160625 0.1280517578125 0.487884521484375 0.737463378906246 +1.16075 0.12774658203125 0.486724853515625 0.737463378906246 +1.160875 0.12774658203125 0.486724853515625 0.737463378906246 +1.161 0.127410888671875 0.485504150390625 0.737463378906246 +1.161125 0.1270751953125 0.484222412109375 0.737463378906246 +1.1612500000000002 0.1270751953125 0.484222412109375 0.737463378906246 +1.161375 0.126739501953125 0.48291015625 0.737463378906246 +1.1615 0.126739501953125 0.48291015625 0.737463378906246 +1.1616250000000002 0.126373291015625 0.48150634765625 0.737463378906246 +1.16175 0.126007080078125 0.480072021484375 0.737463378906246 +1.161875 0.126007080078125 0.480072021484375 0.737463378906246 +1.162 0.1256103515625 0.478607177734375 0.737463378906246 +1.162125 0.1256103515625 0.478607177734375 0.737463378906246 +1.16225 0.125213623046875 0.47705078125 0.737463378906246 +1.162375 0.124786376953125 0.4754638671875 0.737463378906246 +1.1625 0.124786376953125 0.4754638671875 0.737463378906246 +1.162625 0.124359130859375 0.47381591796875 0.737463378906246 +1.16275 0.124359130859375 0.47381591796875 0.737463378906246 +1.162875 0.1239013671875 0.472137451171875 0.737463378906246 +1.163 0.123443603515625 0.470367431640625 0.737463378906246 +1.163125 0.123443603515625 0.470367431640625 0.737463378906246 +1.1632500000000002 0.12298583984375 0.46856689453125 0.737463378906246 +1.163375 0.12298583984375 0.46856689453125 0.737463378906246 +1.1635 0.12249755859375 0.46673583984375 0.737463378906246 +1.1636250000000002 0.121978759765625 0.464813232421875 0.737463378906246 +1.16375 0.121978759765625 0.464813232421875 0.737463378906246 +1.163875 0.121490478515625 0.462890625 0.737463378906246 +1.164 0.121490478515625 0.462890625 0.737463378906246 +1.164125 0.120941162109375 0.46087646484375 0.737463378906246 +1.16425 0.12042236328125 0.458831787109375 0.737463378906246 +1.164375 0.12042236328125 0.458831787109375 0.737463378906246 +1.1645 0.119873046875 0.45672607421875 0.737463378906246 +1.164625 0.119873046875 0.45672607421875 0.737463378906246 +1.16475 0.119293212890625 0.454559326171875 0.737463378906246 +1.164875 0.11871337890625 0.452362060546875 0.737463378906246 +1.165 0.11871337890625 0.452362060546875 0.737463378906246 +1.165125 0.118133544921875 0.450103759765625 0.737463378906246 +1.1652500000000002 0.118133544921875 0.450103759765625 0.737463378906246 +1.165375 0.117523193359375 0.447784423828125 0.737463378906246 +1.1655 0.116912841796875 0.4454345703125 0.737463378906246 +1.1656250000000002 0.116912841796875 0.4454345703125 0.737463378906246 +1.16575 0.11627197265625 0.44305419921875 0.737463378906246 +1.165875 0.11627197265625 0.44305419921875 0.737463378906246 +1.166 0.115631103515625 0.440582275390625 0.737463378906246 +1.166125 0.114959716796875 0.438079833984375 0.737463378906246 +1.16625 0.114959716796875 0.438079833984375 0.737463378906246 +1.166375 0.11431884765625 0.435546875 0.737463378906246 +1.1665 0.11431884765625 0.435546875 0.737463378906246 +1.166625 0.113616943359375 0.432952880859375 0.737463378906246 +1.16675 0.1129150390625 0.4302978515625 0.737463378906246 +1.166875 0.1129150390625 0.4302978515625 0.737463378906246 +1.167 0.112213134765625 0.4276123046875 0.737463378906246 +1.167125 0.112213134765625 0.4276123046875 0.737463378906246 +1.1672500000000002 0.11151123046875 0.424896240234375 0.737463378906246 +1.167375 0.11077880859375 0.422119140625 0.737463378906246 +1.1675 0.11077880859375 0.422119140625 0.737463378906246 +1.1676250000000002 0.11004638671875 0.419281005859375 0.737463378906246 +1.16775 0.11004638671875 0.419281005859375 0.737463378906246 +1.167875 0.109283447265625 0.416412353515625 0.737463378906246 +1.168 0.1085205078125 0.413482666015625 0.737463378906246 +1.168125 0.1085205078125 0.413482666015625 0.737463378906246 +1.16825 0.10772705078125 0.4105224609375 0.737463378906246 +1.168375 0.10772705078125 0.4105224609375 0.737463378906246 +1.1685 0.10693359375 0.407501220703125 0.737463378906246 +1.168625 0.10614013671875 0.404449462890625 0.737463378906246 +1.16875 0.10614013671875 0.404449462890625 0.737463378906246 +1.168875 0.105316162109375 0.401336669921875 0.737463378906246 +1.169 0.105316162109375 0.401336669921875 0.737463378906246 +1.169125 0.1044921875 0.398193359375 0.737463378906246 +1.1692500000000002 0.103668212890625 0.39501953125 0.737463378906246 +1.169375 0.103668212890625 0.39501953125 0.737463378906246 +1.1695 0.102813720703125 0.39178466796875 0.737463378906246 +1.169625 0.102813720703125 0.39178466796875 0.737463378906246 +1.16975 0.101959228515625 0.388519287109375 0.737463378906246 +1.169875 0.101104736328125 0.38519287109375 0.737463378906246 +1.17 0.101104736328125 0.38519287109375 0.737463378906246 +1.170125 0.1002197265625 0.3818359375 0.737463378906246 +1.17025 0.1002197265625 0.3818359375 0.737463378906246 +1.170375 0.09930419921875 0.378448486328125 0.737463378906246 +1.1705 0.098419189453125 0.375 0.737463378906246 +1.170625 0.098419189453125 0.375 0.737463378906246 +1.17075 0.097503662109375 0.37152099609375 0.737463378906246 +1.170875 0.097503662109375 0.37152099609375 0.737463378906246 +1.171 0.096588134765625 0.36798095703125 0.737463378906246 +1.171125 0.09564208984375 0.36444091796875 0.737463378906246 +1.1712500000000002 0.09564208984375 0.36444091796875 0.737463378906246 +1.171375 0.094696044921875 0.360809326171875 0.737463378906246 +1.1715 0.094696044921875 0.360809326171875 0.737463378906246 +1.171625 0.09375 0.357177734375 0.737463378906246 +1.17175 0.0927734375 0.353485107421875 0.737463378906246 +1.171875 0.0927734375 0.353485107421875 0.737463378906246 +1.172 0.091796875 0.349761962890625 0.737463378906246 +1.172125 0.091796875 0.349761962890625 0.737463378906246 +1.17225 0.0908203125 0.34600830078125 0.737463378906246 +1.172375 0.089813232421875 0.34222412109375 0.737463378906246 +1.1725 0.089813232421875 0.34222412109375 0.737463378906246 +1.172625 0.08880615234375 0.33837890625 0.737463378906246 +1.17275 0.08880615234375 0.33837890625 0.737463378906246 +1.1728750000000002 0.087799072265625 0.334503173828125 0.737463378906246 +1.173 0.086761474609375 0.330596923828125 0.737463378906246 +1.173125 0.086761474609375 0.330596923828125 0.737463378906246 +1.1732500000000002 0.085723876953125 0.32666015625 0.737463378906246 +1.173375 0.085723876953125 0.32666015625 0.737463378906246 +1.1735 0.084686279296875 0.322662353515625 0.737463378906246 +1.173625 0.0836181640625 0.31866455078125 0.737463378906246 +1.17375 0.0836181640625 0.31866455078125 0.737463378906246 +1.173875 0.082550048828125 0.314605712890625 0.737463378906246 +1.174 0.082550048828125 0.314605712890625 0.737463378906246 +1.174125 0.08148193359375 0.310516357421875 0.737463378906246 +1.17425 0.080413818359375 0.306396484375 0.737463378906246 +1.174375 0.080413818359375 0.306396484375 0.737463378906246 +1.1745 0.079315185546875 0.30224609375 0.737463378906246 +1.174625 0.079315185546875 0.30224609375 0.737463378906246 +1.17475 0.078216552734375 0.298065185546875 0.737463378906246 +1.1748750000000002 0.077117919921875 0.2938232421875 0.737463378906246 +1.175 0.077117919921875 0.2938232421875 0.737463378906246 +1.175125 0.07598876953125 0.289581298828125 0.737463378906246 +1.1752500000000002 0.07598876953125 0.289581298828125 0.737463378906246 +1.175375 0.074859619140625 0.285308837890625 0.737463378906246 +1.1755 0.07373046875 0.280975341796875 0.737463378906246 +1.175625 0.07373046875 0.280975341796875 0.737463378906246 +1.17575 0.072601318359375 0.276641845703125 0.737463378906246 +1.175875 0.072601318359375 0.276641845703125 0.737463378906246 +1.176 0.071441650390625 0.27227783203125 0.737463378906246 +1.176125 0.070281982421875 0.267852783203125 0.737463378906246 +1.17625 0.070281982421875 0.267852783203125 0.737463378906246 +1.176375 0.069122314453125 0.263427734375 0.737463378906246 +1.1765 0.069122314453125 0.263427734375 0.737463378906246 +1.176625 0.067962646484375 0.25897216796875 0.737463378906246 +1.17675 0.0667724609375 0.25445556640625 0.737463378906246 +1.1768750000000002 0.0667724609375 0.25445556640625 0.737463378906246 +1.177 0.065582275390625 0.249969482421875 0.737463378906246 +1.177125 0.065582275390625 0.249969482421875 0.737463378906246 +1.1772500000000002 0.06439208984375 0.24542236328125 0.737463378906246 +1.177375 0.063201904296875 0.2408447265625 0.737463378906246 +1.1775 0.063201904296875 0.2408447265625 0.737463378906246 +1.177625 0.061981201171875 0.236236572265625 0.737463378906246 +1.17775 0.061981201171875 0.236236572265625 0.737463378906246 +1.177875 0.060791015625 0.231597900390625 0.737463378906246 +1.178 0.059539794921875 0.226959228515625 0.737463378906246 +1.178125 0.059539794921875 0.226959228515625 0.737463378906246 +1.17825 0.058319091796875 0.2222900390625 0.737463378906246 +1.178375 0.058319091796875 0.2222900390625 0.737463378906246 +1.1785 0.057098388671875 0.21759033203125 0.737463378906246 +1.178625 0.05584716796875 0.212860107421875 0.737463378906246 +1.17875 0.05584716796875 0.212860107421875 0.737463378906246 +1.1788750000000002 0.054595947265625 0.208099365234375 0.737463378906246 +1.179 0.054595947265625 0.208099365234375 0.737463378906246 +1.179125 0.0533447265625 0.203338623046875 0.737463378906246 +1.1792500000000002 0.052093505859375 0.19854736328125 0.737463378906246 +1.179375 0.052093505859375 0.19854736328125 0.737463378906246 +1.1795 0.05084228515625 0.1937255859375 0.737463378906246 +1.179625 0.05084228515625 0.1937255859375 0.737463378906246 +1.17975 0.049560546875 0.188873291015625 0.737463378906246 +1.179875 0.04827880859375 0.18402099609375 0.737463378906246 +1.18 0.04827880859375 0.18402099609375 0.737463378906246 +1.180125 0.0469970703125 0.17913818359375 0.737463378906246 +1.18025 0.0469970703125 0.17913818359375 0.737463378906246 +1.180375 0.04571533203125 0.17425537109375 0.737463378906246 +1.1805 0.04443359375 0.169342041015625 0.737463378906246 +1.180625 0.04443359375 0.169342041015625 0.737463378906246 +1.18075 0.043121337890625 0.164398193359375 0.737463378906246 +1.1808750000000002 0.043121337890625 0.164398193359375 0.737463378906246 +1.181 0.041839599609375 0.159454345703125 0.737463378906246 +1.181125 0.04052734375 0.15447998046875 0.737463378906246 +1.1812500000000002 0.04052734375 0.15447998046875 0.737463378906246 +1.181375 0.039215087890625 0.14947509765625 0.737463378906246 +1.1815 0.039215087890625 0.14947509765625 0.737463378906246 +1.181625 0.03790283203125 0.14447021484375 0.737463378906246 +1.18175 0.036590576171875 0.13946533203125 0.737463378906246 +1.181875 0.036590576171875 0.13946533203125 0.737463378906246 +1.182 0.0352783203125 0.134429931640625 0.737463378906246 +1.182125 0.0352783203125 0.134429931640625 0.737463378906246 +1.18225 0.033935546875 0.129364013671875 0.737463378906246 +1.182375 0.032623291015625 0.124298095703125 0.737463378906246 +1.1825 0.032623291015625 0.124298095703125 0.737463378906246 +1.182625 0.031280517578125 0.119232177734375 0.737463378906246 +1.18275 0.031280517578125 0.119232177734375 0.737463378906246 +1.1828750000000002 0.029937744140625 0.1141357421875 0.737463378906246 +1.183 0.028594970703125 0.109039306640625 0.737463378906246 +1.183125 0.028594970703125 0.109039306640625 0.737463378906246 +1.1832500000000002 0.027252197265625 0.103912353515625 0.737463378906246 +1.183375 0.027252197265625 0.103912353515625 0.737463378906246 +1.1835 0.025909423828125 0.098785400390625 0.737463378906246 +1.183625 0.024566650390625 0.093658447265625 0.737463378906246 +1.18375 0.024566650390625 0.093658447265625 0.737463378906246 +1.183875 0.023223876953125 0.0885009765625 0.737463378906246 +1.184 0.05181884765625 0.0885009765625 0.41434936523436966 +1.184125 0.048797607421875 0.083343505859375 0.41434936523436966 +1.18425 0.0457763671875 0.07818603515625 0.41434936523436966 +1.184375 0.0457763671875 0.07818603515625 0.41434936523436966 +1.1845 0.042755126953125 0.072998046875 0.41434936523436966 +1.184625 0.042755126953125 0.072998046875 0.41434936523436966 +1.18475 0.039703369140625 0.06781005859375 0.41434936523436966 +1.1848750000000002 0.03668212890625 0.0626220703125 0.41434936523436966 +1.185 0.03668212890625 0.0626220703125 0.41434936523436966 +1.185125 0.03363037109375 0.05743408203125 0.41434936523436966 +1.18525 0.03363037109375 0.05743408203125 0.41434936523436966 +1.185375 0.03057861328125 0.05224609375 0.41434936523436966 +1.1855 0.02752685546875 0.047027587890625 0.41434936523436966 +1.185625 0.02752685546875 0.047027587890625 0.41434936523436966 +1.18575 0.02447509765625 0.04180908203125 0.41434936523436966 +1.185875 0.02447509765625 0.04180908203125 0.41434936523436966 +1.186 0.02142333984375 0.036590576171875 0.41434936523436966 +1.186125 0.01837158203125 0.0313720703125 0.41434936523436966 +1.18625 0.01837158203125 0.0313720703125 0.41434936523436966 +1.186375 0.015289306640625 0.026123046875 0.41434936523436966 +1.1865 0.015289306640625 0.026123046875 0.41434936523436966 +1.186625 0.012237548828125 0.020904541015625 0.41434936523436966 +1.18675 0.009185791015625 0.01568603515625 0.41434936523436966 +1.1868750000000002 0.009185791015625 0.01568603515625 0.41434936523436966 +1.187 0.006103515625 0.01043701171875 0.41434936523436966 +1.187125 0.006103515625 0.01043701171875 0.41434936523436966 +1.18725 0.0030517578125 0.005218505859375 0.41434936523436966 +1.187375 0.0 0.0 0.41434936523436966 +1.1875 0.0 0.0 0.41434936523436966 +1.187625 -0.0030517578125 -0.005218505859375 0.41434936523436966 +1.18775 -0.0030517578125 -0.005218505859375 0.41434936523436966 +1.187875 -0.006103515625 -0.01043701171875 0.41434936523436966 +1.188 -0.009185791015625 -0.01568603515625 0.41434936523436966 +1.188125 -0.009185791015625 -0.01568603515625 0.41434936523436966 +1.18825 -0.012237548828125 -0.020904541015625 0.41434936523436966 +1.188375 -0.012237548828125 -0.020904541015625 0.41434936523436966 +1.1885000000000002 -0.015289306640625 -0.026123046875 0.41434936523436966 +1.188625 -0.01837158203125 -0.0313720703125 0.41434936523436966 +1.18875 -0.01837158203125 -0.0313720703125 0.41434936523436966 +1.1888750000000002 -0.02142333984375 -0.036590576171875 0.41434936523436966 +1.189 -0.02142333984375 -0.036590576171875 0.41434936523436966 +1.189125 -0.02447509765625 -0.04180908203125 0.41434936523436966 +1.18925 -0.02752685546875 -0.047027587890625 0.41434936523436966 +1.189375 -0.02752685546875 -0.047027587890625 0.41434936523436966 +1.1895 -0.03057861328125 -0.05224609375 0.41434936523436966 +1.189625 -0.03057861328125 -0.05224609375 0.41434936523436966 +1.18975 -0.03363037109375 -0.05743408203125 0.41434936523436966 +1.189875 -0.03668212890625 -0.0626220703125 0.41434936523436966 +1.19 -0.03668212890625 -0.0626220703125 0.41434936523436966 +1.190125 -0.039703369140625 -0.06781005859375 0.41434936523436966 +1.19025 -0.039703369140625 -0.06781005859375 0.41434936523436966 +1.190375 -0.042755126953125 -0.072998046875 0.41434936523436966 +1.1905000000000002 -0.0457763671875 -0.07818603515625 0.41434936523436966 +1.190625 -0.0457763671875 -0.07818603515625 0.41434936523436966 +1.19075 -0.048797607421875 -0.083343505859375 0.41434936523436966 +1.1908750000000002 -0.048797607421875 -0.083343505859375 0.41434936523436966 +1.191 -0.05181884765625 -0.0885009765625 0.41434936523436966 +1.191125 -0.054840087890625 -0.093658447265625 0.41434936523436966 +1.19125 -0.054840087890625 -0.093658447265625 0.41434936523436966 +1.191375 -0.057861328125 -0.098785400390625 0.41434936523436966 +1.1915 -0.057861328125 -0.098785400390625 0.41434936523436966 +1.191625 -0.06085205078125 -0.103912353515625 0.41434936523436966 +1.19175 -0.0638427734375 -0.109039306640625 0.41434936523436966 +1.191875 -0.0638427734375 -0.109039306640625 0.41434936523436966 +1.192 -0.06683349609375 -0.1141357421875 0.41434936523436966 +1.192125 -0.06683349609375 -0.1141357421875 0.41434936523436966 +1.19225 -0.06982421875 -0.119232177734375 0.41434936523436966 +1.192375 -0.072784423828125 -0.124298095703125 0.41434936523436966 +1.1925000000000002 -0.072784423828125 -0.124298095703125 0.41434936523436966 +1.192625 -0.07574462890625 -0.129364013671875 0.41434936523436966 +1.19275 -0.07574462890625 -0.129364013671875 0.41434936523436966 +1.1928750000000002 -0.078704833984375 -0.134429931640625 0.41434936523436966 +1.193 -0.0816650390625 -0.13946533203125 0.41434936523436966 +1.193125 -0.0816650390625 -0.13946533203125 0.41434936523436966 +1.19325 -0.0845947265625 -0.14447021484375 0.41434936523436966 +1.193375 -0.0845947265625 -0.14447021484375 0.41434936523436966 +1.1935 -0.0875244140625 -0.14947509765625 0.41434936523436966 +1.193625 -0.0904541015625 -0.15447998046875 0.41434936523436966 +1.19375 -0.0904541015625 -0.15447998046875 0.41434936523436966 +1.193875 -0.093353271484375 -0.159454345703125 0.41434936523436966 +1.194 -0.093353271484375 -0.159454345703125 0.41434936523436966 +1.194125 -0.09625244140625 -0.164398193359375 0.41434936523436966 +1.19425 -0.099151611328125 -0.169342041015625 0.41434936523436966 +1.194375 -0.099151611328125 -0.169342041015625 0.41434936523436966 +1.1945000000000002 -0.102020263671875 -0.17425537109375 0.41434936523436966 +1.194625 -0.102020263671875 -0.17425537109375 0.41434936523436966 +1.19475 -0.104888916015625 -0.17913818359375 0.41434936523436966 +1.1948750000000002 -0.107757568359375 -0.18402099609375 0.41434936523436966 +1.195 -0.107757568359375 -0.18402099609375 0.41434936523436966 +1.195125 -0.110595703125 -0.188873291015625 0.41434936523436966 +1.19525 -0.110595703125 -0.188873291015625 0.41434936523436966 +1.195375 -0.113433837890625 -0.1937255859375 0.41434936523436966 +1.1955 -0.11627197265625 -0.19854736328125 0.41434936523436966 +1.195625 -0.11627197265625 -0.19854736328125 0.41434936523436966 +1.19575 -0.119049072265625 -0.203338623046875 0.41434936523436966 +1.195875 -0.119049072265625 -0.203338623046875 0.41434936523436966 +1.196 -0.121856689453125 -0.208099365234375 0.41434936523436966 +1.196125 -0.1246337890625 -0.212860107421875 0.41434936523436966 +1.19625 -0.1246337890625 -0.212860107421875 0.41434936523436966 +1.196375 -0.127410888671875 -0.21759033203125 0.41434936523436966 +1.1965000000000002 -0.127410888671875 -0.21759033203125 0.41434936523436966 +1.196625 -0.130157470703125 -0.2222900390625 0.41434936523436966 +1.19675 -0.132904052734375 -0.226959228515625 0.41434936523436966 +1.1968750000000002 -0.132904052734375 -0.226959228515625 0.41434936523436966 +1.197 -0.1356201171875 -0.231597900390625 0.41434936523436966 +1.197125 -0.1356201171875 -0.231597900390625 0.41434936523436966 +1.19725 -0.138336181640625 -0.236236572265625 0.41434936523436966 +1.197375 -0.141021728515625 -0.2408447265625 0.41434936523436966 +1.1975 -0.141021728515625 -0.2408447265625 0.41434936523436966 +1.197625 -0.143707275390625 -0.24542236328125 0.41434936523436966 +1.19775 -0.143707275390625 -0.24542236328125 0.41434936523436966 +1.197875 -0.1463623046875 -0.249969482421875 0.41434936523436966 +1.198 -0.149017333984375 -0.25445556640625 0.41434936523436966 +1.198125 -0.149017333984375 -0.25445556640625 0.41434936523436966 +1.19825 -0.151641845703125 -0.25897216796875 0.41434936523436966 +1.198375 -0.151641845703125 -0.25897216796875 0.41434936523436966 +1.1985000000000002 -0.154266357421875 -0.263427734375 0.41434936523436966 +1.198625 -0.1568603515625 -0.267852783203125 0.41434936523436966 +1.19875 -0.1568603515625 -0.267852783203125 0.41434936523436966 +1.1988750000000002 -0.159454345703125 -0.27227783203125 0.41434936523436966 +1.199 -0.159454345703125 -0.27227783203125 0.41434936523436966 +1.199125 -0.1619873046875 -0.276641845703125 0.41434936523436966 +1.19925 -0.16455078125 -0.280975341796875 0.41434936523436966 +1.199375 -0.16455078125 -0.280975341796875 0.41434936523436966 +1.1995 -0.167083740234375 -0.285308837890625 0.41434936523436966 +1.199625 -0.167083740234375 -0.285308837890625 0.41434936523436966 +1.19975 -0.169586181640625 -0.289581298828125 0.41434936523436966 +1.199875 -0.17205810546875 -0.2938232421875 0.41434936523436966 +1.2 -0.17205810546875 -0.2938232421875 0.41434936523436966 +1.200125 -0.174530029296875 -0.298065185546875 0.41434936523436966 +1.20025 -0.174530029296875 -0.298065185546875 0.41434936523436966 +1.200375 -0.177001953125 -0.30224609375 0.41434936523436966 +1.2005000000000002 -0.179443359375 -0.306396484375 0.41434936523436966 +1.200625 -0.179443359375 -0.306396484375 0.41434936523436966 +1.20075 -0.181854248046875 -0.310516357421875 0.41434936523436966 +1.200875 -0.181854248046875 -0.310516357421875 0.41434936523436966 +1.201 -0.184234619140625 -0.314605712890625 0.41434936523436966 +1.201125 -0.186614990234375 -0.31866455078125 0.41434936523436966 +1.20125 -0.186614990234375 -0.31866455078125 0.41434936523436966 +1.201375 -0.18896484375 -0.322662353515625 0.41434936523436966 +1.2015 -0.18896484375 -0.322662353515625 0.41434936523436966 +1.201625 -0.1912841796875 -0.32666015625 0.41434936523436966 +1.20175 -0.193603515625 -0.330596923828125 0.41434936523436966 +1.201875 -0.193603515625 -0.330596923828125 0.41434936523436966 +1.202 -0.195892333984375 -0.334503173828125 0.41434936523436966 +1.202125 -0.195892333984375 -0.334503173828125 0.41434936523436966 +1.20225 -0.198150634765625 -0.33837890625 0.41434936523436966 +1.202375 -0.200408935546875 -0.34222412109375 0.41434936523436966 +1.2025000000000002 -0.200408935546875 -0.34222412109375 0.41434936523436966 +1.202625 -0.20263671875 -0.34600830078125 0.41434936523436966 +1.20275 -0.20263671875 -0.34600830078125 0.41434936523436966 +1.202875 -0.204833984375 -0.349761962890625 0.41434936523436966 +1.203 -0.207000732421875 -0.353485107421875 0.41434936523436966 +1.203125 -0.207000732421875 -0.353485107421875 0.41434936523436966 +1.20325 -0.20916748046875 -0.357177734375 0.41434936523436966 +1.203375 -0.20916748046875 -0.357177734375 0.41434936523436966 +1.2035 -0.2113037109375 -0.360809326171875 0.41434936523436966 +1.203625 -0.213409423828125 -0.36444091796875 0.41434936523436966 +1.20375 -0.213409423828125 -0.36444091796875 0.41434936523436966 +1.203875 -0.215484619140625 -0.36798095703125 0.41434936523436966 +1.204 -0.215484619140625 -0.36798095703125 0.41434936523436966 +1.2041250000000002 -0.217559814453125 -0.37152099609375 0.41434936523436966 +1.20425 -0.2196044921875 -0.375 0.41434936523436966 +1.204375 -0.2196044921875 -0.375 0.41434936523436966 +1.2045000000000002 -0.22161865234375 -0.378448486328125 0.41434936523436966 +1.204625 -0.22161865234375 -0.378448486328125 0.41434936523436966 +1.20475 -0.223602294921875 -0.3818359375 0.41434936523436966 +1.204875 -0.225555419921875 -0.38519287109375 0.41434936523436966 +1.205 -0.225555419921875 -0.38519287109375 0.41434936523436966 +1.205125 -0.227508544921875 -0.388519287109375 0.41434936523436966 +1.20525 -0.227508544921875 -0.388519287109375 0.41434936523436966 +1.205375 -0.22943115234375 -0.39178466796875 0.41434936523436966 +1.2055 -0.2313232421875 -0.39501953125 0.41434936523436966 +1.205625 -0.2313232421875 -0.39501953125 0.41434936523436966 +1.20575 -0.233184814453125 -0.398193359375 0.41434936523436966 +1.205875 -0.233184814453125 -0.398193359375 0.41434936523436966 +1.206 -0.235015869140625 -0.401336669921875 0.41434936523436966 +1.2061250000000002 -0.236846923828125 -0.404449462890625 0.41434936523436966 +1.20625 -0.236846923828125 -0.404449462890625 0.41434936523436966 +1.206375 -0.2386474609375 -0.407501220703125 0.41434936523436966 +1.2065000000000002 -0.2386474609375 -0.407501220703125 0.41434936523436966 +1.206625 -0.240386962890625 -0.4105224609375 0.41434936523436966 +1.20675 -0.24212646484375 -0.413482666015625 0.41434936523436966 +1.206875 -0.24212646484375 -0.413482666015625 0.41434936523436966 +1.207 -0.24383544921875 -0.416412353515625 0.41434936523436966 +1.207125 -0.24383544921875 -0.416412353515625 0.41434936523436966 +1.20725 -0.245513916015625 -0.419281005859375 0.41434936523436966 +1.207375 -0.2471923828125 -0.422119140625 0.41434936523436966 +1.2075 -0.2471923828125 -0.422119140625 0.41434936523436966 +1.207625 -0.248809814453125 -0.424896240234375 0.41434936523436966 +1.20775 -0.248809814453125 -0.424896240234375 0.41434936523436966 +1.207875 -0.250396728515625 -0.4276123046875 0.41434936523436966 +1.208 -0.251983642578125 -0.4302978515625 0.41434936523436966 +1.2081250000000002 -0.251983642578125 -0.4302978515625 0.41434936523436966 +1.20825 -0.2535400390625 -0.432952880859375 0.41434936523436966 +1.208375 -0.2535400390625 -0.432952880859375 0.41434936523436966 +1.2085000000000002 -0.25506591796875 -0.435546875 0.41434936523436966 +1.208625 -0.25653076171875 -0.438079833984375 0.41434936523436966 +1.20875 -0.25653076171875 -0.438079833984375 0.41434936523436966 +1.208875 -0.25799560546875 -0.440582275390625 0.41434936523436966 +1.209 -0.25799560546875 -0.440582275390625 0.41434936523436966 +1.209125 -0.259429931640625 -0.44305419921875 0.41434936523436966 +1.20925 -0.260833740234375 -0.4454345703125 0.41434936523436966 +1.209375 -0.260833740234375 -0.4454345703125 0.41434936523436966 +1.2095 -0.26220703125 -0.447784423828125 0.41434936523436966 +1.209625 -0.26220703125 -0.447784423828125 0.41434936523436966 +1.20975 -0.263580322265625 -0.450103759765625 0.41434936523436966 +1.209875 -0.264892578125 -0.452362060546875 0.41434936523436966 +1.21 -0.264892578125 -0.452362060546875 0.41434936523436966 +1.2101250000000002 -0.26617431640625 -0.454559326171875 0.41434936523436966 +1.21025 -0.26617431640625 -0.454559326171875 0.41434936523436966 +1.210375 -0.2674560546875 -0.45672607421875 0.41434936523436966 +1.2105000000000002 -0.2686767578125 -0.458831787109375 0.41434936523436966 +1.210625 -0.2686767578125 -0.458831787109375 0.41434936523436966 +1.21075 -0.269866943359375 -0.46087646484375 0.41434936523436966 +1.210875 -0.269866943359375 -0.46087646484375 0.41434936523436966 +1.211 -0.27105712890625 -0.462890625 0.41434936523436966 +1.211125 -0.272186279296875 -0.464813232421875 0.41434936523436966 +1.21125 -0.272186279296875 -0.464813232421875 0.41434936523436966 +1.211375 -0.2733154296875 -0.46673583984375 0.41434936523436966 +1.2115 -0.2733154296875 -0.46673583984375 0.41434936523436966 +1.211625 -0.274383544921875 -0.46856689453125 0.41434936523436966 +1.21175 -0.27545166015625 -0.470367431640625 0.41434936523436966 +1.211875 -0.27545166015625 -0.470367431640625 0.41434936523436966 +1.212 -0.276458740234375 -0.472137451171875 0.41434936523436966 +1.2121250000000002 -0.276458740234375 -0.472137451171875 0.41434936523436966 +1.21225 -0.2774658203125 -0.47381591796875 0.41434936523436966 +1.212375 -0.2784423828125 -0.4754638671875 0.41434936523436966 +1.2125000000000002 -0.2784423828125 -0.4754638671875 0.41434936523436966 +1.212625 -0.27935791015625 -0.47705078125 0.41434936523436966 +1.21275 -0.27935791015625 -0.47705078125 0.41434936523436966 +1.212875 -0.2802734375 -0.478607177734375 0.41434936523436966 +1.213 -0.2811279296875 -0.480072021484375 0.41434936523436966 +1.213125 -0.2811279296875 -0.480072021484375 0.41434936523436966 +1.21325 -0.281982421875 -0.48150634765625 0.41434936523436966 +1.213375 -0.281982421875 -0.48150634765625 0.41434936523436966 +1.2135 -0.28277587890625 -0.48291015625 0.41434936523436966 +1.213625 -0.2835693359375 -0.484222412109375 0.41434936523436966 +1.21375 -0.2835693359375 -0.484222412109375 0.41434936523436966 +1.213875 -0.2843017578125 -0.485504150390625 0.41434936523436966 +1.214 -0.2843017578125 -0.485504150390625 0.41434936523436966 +1.2141250000000002 -0.2850341796875 -0.486724853515625 0.41434936523436966 +1.21425 -0.28570556640625 -0.487884521484375 0.41434936523436966 +1.214375 -0.28570556640625 -0.487884521484375 0.41434936523436966 +1.2145000000000002 -0.286346435546875 -0.489013671875 0.41434936523436966 +1.214625 -0.286346435546875 -0.489013671875 0.41434936523436966 +1.21475 -0.2869873046875 -0.490081787109375 0.41434936523436966 +1.214875 -0.287567138671875 -0.4910888671875 0.41434936523436966 +1.215 -0.287567138671875 -0.4910888671875 0.41434936523436966 +1.215125 -0.28814697265625 -0.492034912109375 0.41434936523436966 +1.21525 -0.28814697265625 -0.492034912109375 0.41434936523436966 +1.215375 -0.288665771484375 -0.492950439453125 0.41434936523436966 +1.2155 -0.289154052734375 -0.4937744140625 0.41434936523436966 +1.215625 -0.289154052734375 -0.4937744140625 0.41434936523436966 +1.21575 -0.28961181640625 -0.49456787109375 0.41434936523436966 +1.215875 -0.28961181640625 -0.49456787109375 0.41434936523436966 +1.216 -0.48284912109375 -0.49530029296875 0.025122070312493812 +1.2161250000000002 -0.4835205078125 -0.496002197265625 0.025122070312493812 +1.21625 -0.4835205078125 -0.496002197265625 0.025122070312493812 +1.216375 -0.484130859375 -0.496612548828125 0.025122070312493812 +1.2165 -0.484130859375 -0.496612548828125 0.025122070312493812 +1.216625 -0.48468017578125 -0.4971923828125 0.025122070312493812 +1.21675 -0.485198974609375 -0.497711181640625 0.025122070312493812 +1.216875 -0.485198974609375 -0.497711181640625 0.025122070312493812 +1.217 -0.48565673828125 -0.498199462890625 0.025122070312493812 +1.217125 -0.48565673828125 -0.498199462890625 0.025122070312493812 +1.21725 -0.486053466796875 -0.49859619140625 0.025122070312493812 +1.217375 -0.48638916015625 -0.49896240234375 0.025122070312493812 +1.2175 -0.48638916015625 -0.49896240234375 0.025122070312493812 +1.217625 -0.4866943359375 -0.499267578125 0.025122070312493812 +1.21775 -0.4866943359375 -0.499267578125 0.025122070312493812 +1.217875 -0.4869384765625 -0.49951171875 0.025122070312493812 +1.218 -0.48712158203125 -0.49969482421875 0.025122070312493812 +1.2181250000000002 -0.48712158203125 -0.49969482421875 0.025122070312493812 +1.21825 -0.48724365234375 -0.49981689453125 0.025122070312493812 +1.218375 -0.48724365234375 -0.49981689453125 0.025122070312493812 +1.2185 -0.487335205078125 -0.499908447265625 0.025122070312493812 +1.218625 -0.48736572265625 -0.49993896484375 0.025122070312493812 +1.21875 -0.48736572265625 -0.49993896484375 0.025122070312493812 +1.218875 -0.487335205078125 -0.499908447265625 0.025122070312493812 +1.219 -0.487335205078125 -0.499908447265625 0.025122070312493812 +1.219125 -0.48724365234375 -0.49981689453125 0.025122070312493812 +1.21925 -0.48712158203125 -0.49969482421875 0.025122070312493812 +1.219375 -0.48712158203125 -0.49969482421875 0.025122070312493812 +1.2195 -0.4869384765625 -0.49951171875 0.025122070312493812 +1.219625 -0.4869384765625 -0.49951171875 0.025122070312493812 +1.2197500000000002 -0.4866943359375 -0.499267578125 0.025122070312493812 +1.219875 -0.48638916015625 -0.49896240234375 0.025122070312493812 +1.22 -0.48638916015625 -0.49896240234375 0.025122070312493812 +1.2201250000000002 -0.486053466796875 -0.49859619140625 0.025122070312493812 +1.22025 -0.486053466796875 -0.49859619140625 0.025122070312493812 +1.220375 -0.48565673828125 -0.498199462890625 0.025122070312493812 +1.2205 -0.485198974609375 -0.497711181640625 0.025122070312493812 +1.220625 -0.485198974609375 -0.497711181640625 0.025122070312493812 +1.22075 -0.48468017578125 -0.4971923828125 0.025122070312493812 +1.220875 -0.48468017578125 -0.4971923828125 0.025122070312493812 +1.221 -0.484130859375 -0.496612548828125 0.025122070312493812 +1.221125 -0.4835205078125 -0.496002197265625 0.025122070312493812 +1.22125 -0.4835205078125 -0.496002197265625 0.025122070312493812 +1.221375 -0.48284912109375 -0.49530029296875 0.025122070312493812 +1.2215 -0.48284912109375 -0.49530029296875 0.025122070312493812 +1.221625 -0.48211669921875 -0.49456787109375 0.025122070312493812 +1.2217500000000002 -0.481353759765625 -0.4937744140625 0.025122070312493812 +1.221875 -0.481353759765625 -0.4937744140625 0.025122070312493812 +1.222 -0.48052978515625 -0.492950439453125 0.025122070312493812 +1.2221250000000002 -0.48052978515625 -0.492950439453125 0.025122070312493812 +1.22225 -0.47967529296875 -0.492034912109375 0.025122070312493812 +1.222375 -0.478729248046875 -0.4910888671875 0.025122070312493812 +1.2225 -0.478729248046875 -0.4910888671875 0.025122070312493812 +1.222625 -0.477752685546875 -0.490081787109375 0.025122070312493812 +1.22275 -0.477752685546875 -0.490081787109375 0.025122070312493812 +1.222875 -0.476715087890625 -0.489013671875 0.025122070312493812 +1.223 -0.475616455078125 -0.487884521484375 0.025122070312493812 +1.223125 -0.475616455078125 -0.487884521484375 0.025122070312493812 +1.22325 -0.4744873046875 -0.486724853515625 0.025122070312493812 +1.223375 -0.4744873046875 -0.486724853515625 0.025122070312493812 +1.2235 -0.473297119140625 -0.485504150390625 0.025122070312493812 +1.223625 -0.4720458984375 -0.484222412109375 0.025122070312493812 +1.2237500000000002 -0.4720458984375 -0.484222412109375 0.025122070312493812 +1.223875 -0.47076416015625 -0.48291015625 0.025122070312493812 +1.224 -0.47076416015625 -0.48291015625 0.025122070312493812 +1.2241250000000002 -0.469390869140625 -0.48150634765625 0.025122070312493812 +1.22425 -0.467987060546875 -0.480072021484375 0.025122070312493812 +1.224375 -0.467987060546875 -0.480072021484375 0.025122070312493812 +1.2245 -0.466552734375 -0.478607177734375 0.025122070312493812 +1.224625 -0.466552734375 -0.478607177734375 0.025122070312493812 +1.22475 -0.465057373046875 -0.47705078125 0.025122070312493812 +1.224875 -0.4635009765625 -0.4754638671875 0.025122070312493812 +1.225 -0.4635009765625 -0.4754638671875 0.025122070312493812 +1.225125 -0.4619140625 -0.47381591796875 0.025122070312493812 +1.22525 -0.4619140625 -0.47381591796875 0.025122070312493812 +1.225375 -0.460235595703125 -0.472137451171875 0.025122070312493812 +1.2255 -0.458526611328125 -0.470367431640625 0.025122070312493812 +1.225625 -0.458526611328125 -0.470367431640625 0.025122070312493812 +1.2257500000000002 -0.456787109375 -0.46856689453125 0.025122070312493812 +1.225875 -0.456787109375 -0.46856689453125 0.025122070312493812 +1.226 -0.454986572265625 -0.46673583984375 0.025122070312493812 +1.2261250000000002 -0.453125 -0.464813232421875 0.025122070312493812 +1.22625 -0.453125 -0.464813232421875 0.025122070312493812 +1.226375 -0.45123291015625 -0.462890625 0.025122070312493812 +1.2265 -0.45123291015625 -0.462890625 0.025122070312493812 +1.226625 -0.44927978515625 -0.46087646484375 0.025122070312493812 +1.22675 -0.447265625 -0.458831787109375 0.025122070312493812 +1.226875 -0.447265625 -0.458831787109375 0.025122070312493812 +1.227 -0.445220947265625 -0.45672607421875 0.025122070312493812 +1.227125 -0.445220947265625 -0.45672607421875 0.025122070312493812 +1.22725 -0.443115234375 -0.454559326171875 0.025122070312493812 +1.227375 -0.44097900390625 -0.452362060546875 0.025122070312493812 +1.2275 -0.44097900390625 -0.452362060546875 0.025122070312493812 +1.227625 -0.43878173828125 -0.450103759765625 0.025122070312493812 +1.2277500000000002 -0.43878173828125 -0.450103759765625 0.025122070312493812 +1.227875 -0.4365234375 -0.447784423828125 0.025122070312493812 +1.228 -0.434234619140625 -0.4454345703125 0.025122070312493812 +1.2281250000000002 -0.434234619140625 -0.4454345703125 0.025122070312493812 +1.22825 -0.431915283203125 -0.44305419921875 0.025122070312493812 +1.228375 -0.431915283203125 -0.44305419921875 0.025122070312493812 +1.2285 -0.42950439453125 -0.440582275390625 0.025122070312493812 +1.228625 -0.42706298828125 -0.438079833984375 0.025122070312493812 +1.22875 -0.42706298828125 -0.438079833984375 0.025122070312493812 +1.228875 -0.424591064453125 -0.435546875 0.025122070312493812 +1.229 -0.424591064453125 -0.435546875 0.025122070312493812 +1.229125 -0.42205810546875 -0.432952880859375 0.025122070312493812 +1.22925 -0.41949462890625 -0.4302978515625 0.025122070312493812 +1.229375 -0.41949462890625 -0.4302978515625 0.025122070312493812 +1.2295 -0.4168701171875 -0.4276123046875 0.025122070312493812 +1.229625 -0.4168701171875 -0.4276123046875 0.025122070312493812 +1.2297500000000002 -0.414215087890625 -0.424896240234375 0.025122070312493812 +1.229875 -0.4114990234375 -0.422119140625 0.025122070312493812 +1.23 -0.4114990234375 -0.422119140625 0.025122070312493812 +1.2301250000000002 -0.408721923828125 -0.419281005859375 0.025122070312493812 +1.23025 -0.408721923828125 -0.419281005859375 0.025122070312493812 +1.230375 -0.40594482421875 -0.416412353515625 0.025122070312493812 +1.2305 -0.403076171875 -0.413482666015625 0.025122070312493812 +1.230625 -0.403076171875 -0.413482666015625 0.025122070312493812 +1.23075 -0.400177001953125 -0.4105224609375 0.025122070312493812 +1.230875 -0.400177001953125 -0.4105224609375 0.025122070312493812 +1.231 -0.397247314453125 -0.407501220703125 0.025122070312493812 +1.231125 -0.394287109375 -0.404449462890625 0.025122070312493812 +1.23125 -0.394287109375 -0.404449462890625 0.025122070312493812 +1.231375 -0.3912353515625 -0.401336669921875 0.025122070312493812 +1.2315 -0.3912353515625 -0.401336669921875 0.025122070312493812 +1.231625 -0.38818359375 -0.398193359375 0.025122070312493812 +1.2317500000000002 -0.385101318359375 -0.39501953125 0.025122070312493812 +1.231875 -0.385101318359375 -0.39501953125 0.025122070312493812 +1.232 -0.381927490234375 -0.39178466796875 0.025122070312493812 +1.232125 -0.381927490234375 -0.39178466796875 0.025122070312493812 +1.23225 -0.378753662109375 -0.388519287109375 0.025122070312493812 +1.232375 -0.375518798828125 -0.38519287109375 0.025122070312493812 +1.2325 -0.375518798828125 -0.38519287109375 0.025122070312493812 +1.232625 -0.37225341796875 -0.3818359375 0.025122070312493812 +1.23275 -0.37225341796875 -0.3818359375 0.025122070312493812 +1.232875 -0.368927001953125 -0.378448486328125 0.025122070312493812 +1.233 -0.365570068359375 -0.375 0.025122070312493812 +1.233125 -0.365570068359375 -0.375 0.025122070312493812 +1.23325 -0.3621826171875 -0.37152099609375 0.025122070312493812 +1.233375 -0.3621826171875 -0.37152099609375 0.025122070312493812 +1.2335 -0.358734130859375 -0.36798095703125 0.025122070312493812 +1.233625 -0.355255126953125 -0.36444091796875 0.025122070312493812 +1.2337500000000002 -0.355255126953125 -0.36444091796875 0.025122070312493812 +1.233875 -0.35174560546875 -0.360809326171875 0.025122070312493812 +1.234 -0.35174560546875 -0.360809326171875 0.025122070312493812 +1.234125 -0.34820556640625 -0.357177734375 0.025122070312493812 +1.23425 -0.3446044921875 -0.353485107421875 0.025122070312493812 +1.234375 -0.3446044921875 -0.353485107421875 0.025122070312493812 +1.2345 -0.340972900390625 -0.349761962890625 0.025122070312493812 +1.234625 -0.340972900390625 -0.349761962890625 0.025122070312493812 +1.23475 -0.337310791015625 -0.34600830078125 0.025122070312493812 +1.234875 -0.3336181640625 -0.34222412109375 0.025122070312493812 +1.235 -0.3336181640625 -0.34222412109375 0.025122070312493812 +1.235125 -0.329864501953125 -0.33837890625 0.025122070312493812 +1.23525 -0.329864501953125 -0.33837890625 0.025122070312493812 +1.2353750000000002 -0.32611083984375 -0.334503173828125 0.025122070312493812 +1.2355 -0.322296142578125 -0.330596923828125 0.025122070312493812 +1.235625 -0.322296142578125 -0.330596923828125 0.025122070312493812 +1.2357500000000002 -0.318450927734375 -0.32666015625 0.025122070312493812 +1.235875 -0.318450927734375 -0.32666015625 0.025122070312493812 +1.236 -0.314544677734375 -0.322662353515625 0.025122070312493812 +1.236125 -0.310638427734375 -0.31866455078125 0.025122070312493812 +1.23625 -0.310638427734375 -0.31866455078125 0.025122070312493812 +1.236375 -0.30670166015625 -0.314605712890625 0.025122070312493812 +1.2365 -0.30670166015625 -0.314605712890625 0.025122070312493812 +1.236625 -0.302703857421875 -0.310516357421875 0.025122070312493812 +1.23675 -0.2987060546875 -0.306396484375 0.025122070312493812 +1.236875 -0.2987060546875 -0.306396484375 0.025122070312493812 +1.237 -0.294647216796875 -0.30224609375 0.025122070312493812 +1.237125 -0.294647216796875 -0.30224609375 0.025122070312493812 +1.23725 -0.290557861328125 -0.298065185546875 0.025122070312493812 +1.2373750000000002 -0.28643798828125 -0.2938232421875 0.025122070312493812 +1.2375 -0.28643798828125 -0.2938232421875 0.025122070312493812 +1.237625 -0.282318115234375 -0.289581298828125 0.025122070312493812 +1.2377500000000002 -0.282318115234375 -0.289581298828125 0.025122070312493812 +1.237875 -0.27813720703125 -0.285308837890625 0.025122070312493812 +1.238 -0.27392578125 -0.280975341796875 0.025122070312493812 +1.238125 -0.27392578125 -0.280975341796875 0.025122070312493812 +1.23825 -0.269683837890625 -0.276641845703125 0.025122070312493812 +1.238375 -0.269683837890625 -0.276641845703125 0.025122070312493812 +1.2385 -0.26544189453125 -0.27227783203125 0.025122070312493812 +1.238625 -0.261138916015625 -0.267852783203125 0.025122070312493812 +1.23875 -0.261138916015625 -0.267852783203125 0.025122070312493812 +1.238875 -0.256805419921875 -0.263427734375 0.025122070312493812 +1.239 -0.256805419921875 -0.263427734375 0.025122070312493812 +1.239125 -0.252471923828125 -0.25897216796875 0.025122070312493812 +1.23925 -0.248077392578125 -0.25445556640625 0.025122070312493812 +1.2393750000000002 -0.248077392578125 -0.25445556640625 0.025122070312493812 +1.2395 -0.243682861328125 -0.249969482421875 0.025122070312493812 +1.239625 -0.243682861328125 -0.249969482421875 0.025122070312493812 +1.2397500000000002 -0.239227294921875 -0.24542236328125 0.025122070312493812 +1.239875 -0.234771728515625 -0.2408447265625 0.025122070312493812 +1.24 -0.234771728515625 -0.2408447265625 0.025122070312493812 +1.240125 -0.23028564453125 -0.236236572265625 0.025122070312493812 +1.24025 -0.23028564453125 -0.236236572265625 0.025122070312493812 +1.240375 -0.22576904296875 -0.231597900390625 0.025122070312493812 +1.2405 -0.22125244140625 -0.226959228515625 0.025122070312493812 +1.240625 -0.22125244140625 -0.226959228515625 0.025122070312493812 +1.24075 -0.2166748046875 -0.2222900390625 0.025122070312493812 +1.240875 -0.2166748046875 -0.2222900390625 0.025122070312493812 +1.241 -0.21209716796875 -0.21759033203125 0.025122070312493812 +1.241125 -0.207489013671875 -0.212860107421875 0.025122070312493812 +1.24125 -0.207489013671875 -0.212860107421875 0.025122070312493812 +1.2413750000000002 -0.202880859375 -0.208099365234375 0.025122070312493812 +1.2415 -0.202880859375 -0.208099365234375 0.025122070312493812 +1.241625 -0.198211669921875 -0.203338623046875 0.025122070312493812 +1.2417500000000002 -0.19354248046875 -0.19854736328125 0.025122070312493812 +1.241875 -0.19354248046875 -0.19854736328125 0.025122070312493812 +1.242 -0.1888427734375 -0.1937255859375 0.025122070312493812 +1.242125 -0.1888427734375 -0.1937255859375 0.025122070312493812 +1.24225 -0.184112548828125 -0.188873291015625 0.025122070312493812 +1.242375 -0.17938232421875 -0.18402099609375 0.025122070312493812 +1.2425 -0.17938232421875 -0.18402099609375 0.025122070312493812 +1.242625 -0.174652099609375 -0.17913818359375 0.025122070312493812 +1.24275 -0.174652099609375 -0.17913818359375 0.025122070312493812 +1.242875 -0.16986083984375 -0.17425537109375 0.025122070312493812 +1.243 -0.165069580078125 -0.169342041015625 0.025122070312493812 +1.243125 -0.165069580078125 -0.169342041015625 0.025122070312493812 +1.24325 -0.160247802734375 -0.164398193359375 0.025122070312493812 +1.2433750000000002 -0.160247802734375 -0.164398193359375 0.025122070312493812 +1.2435 -0.155426025390625 -0.159454345703125 0.025122070312493812 +1.243625 -0.15057373046875 -0.15447998046875 0.025122070312493812 +1.2437500000000002 -0.15057373046875 -0.15447998046875 0.025122070312493812 +1.243875 -0.145721435546875 -0.14947509765625 0.025122070312493812 +1.244 -0.145721435546875 -0.14947509765625 0.025122070312493812 +1.244125 -0.140838623046875 -0.14447021484375 0.025122070312493812 +1.24425 -0.135955810546875 -0.13946533203125 0.025122070312493812 +1.244375 -0.135955810546875 -0.13946533203125 0.025122070312493812 +1.2445 -0.13104248046875 -0.134429931640625 0.025122070312493812 +1.244625 -0.13104248046875 -0.134429931640625 0.025122070312493812 +1.24475 -0.126129150390625 -0.129364013671875 0.025122070312493812 +1.244875 -0.121185302734375 -0.124298095703125 0.025122070312493812 +1.245 -0.121185302734375 -0.124298095703125 0.025122070312493812 +1.245125 -0.116241455078125 -0.119232177734375 0.025122070312493812 +1.24525 -0.116241455078125 -0.119232177734375 0.025122070312493812 +1.2453750000000002 -0.11126708984375 -0.1141357421875 0.025122070312493812 +1.2455 -0.106292724609375 -0.109039306640625 0.025122070312493812 +1.245625 -0.106292724609375 -0.109039306640625 0.025122070312493812 +1.2457500000000002 -0.101318359375 -0.103912353515625 0.025122070312493812 +1.245875 -0.101318359375 -0.103912353515625 0.025122070312493812 +1.246 -0.0963134765625 -0.098785400390625 0.025122070312493812 +1.246125 -0.09130859375 -0.093658447265625 0.025122070312493812 +1.24625 -0.09130859375 -0.093658447265625 0.025122070312493812 +1.246375 -0.086273193359375 -0.0885009765625 0.025122070312493812 +1.2465 -0.086273193359375 -0.0885009765625 0.025122070312493812 +1.246625 -0.081268310546875 -0.083343505859375 0.025122070312493812 +1.24675 -0.076202392578125 -0.07818603515625 0.025122070312493812 +1.246875 -0.076202392578125 -0.07818603515625 0.025122070312493812 +1.247 -0.0711669921875 -0.072998046875 0.025122070312493812 +1.247125 -0.0711669921875 -0.072998046875 0.025122070312493812 +1.24725 -0.06610107421875 -0.06781005859375 0.025122070312493812 +1.2473750000000002 -0.061065673828125 -0.0626220703125 0.025122070312493812 +1.2475 -0.061065673828125 -0.0626220703125 0.025122070312493812 +1.247625 -0.055999755859375 -0.05743408203125 0.025122070312493812 +1.2477500000000002 -0.055999755859375 -0.05743408203125 0.025122070312493812 +1.247875 -0.050933837890625 -0.05224609375 0.025122070312493812 +1.248 -0.047027587890625 -0.029693603515625 -0.3681030273437555 +1.248125 -0.047027587890625 -0.029693603515625 -0.3681030273437555 +1.24825 -0.04180908203125 -0.026397705078125 -0.3681030273437555 +1.248375 -0.04180908203125 -0.026397705078125 -0.3681030273437555 +1.2485 -0.036590576171875 -0.023101806640625 -0.3681030273437555 +1.248625 -0.0313720703125 -0.019805908203125 -0.3681030273437555 +1.24875 -0.0313720703125 -0.019805908203125 -0.3681030273437555 +1.248875 -0.026123046875 -0.016510009765625 -0.3681030273437555 +1.249 -0.026123046875 -0.016510009765625 -0.3681030273437555 +1.249125 -0.020904541015625 -0.013214111328125 -0.3681030273437555 +1.24925 -0.01568603515625 -0.009918212890625 -0.3681030273437555 +1.2493750000000002 -0.01568603515625 -0.009918212890625 -0.3681030273437555 +1.2495 -0.01043701171875 -0.006591796875 -0.3681030273437555 +1.249625 -0.01043701171875 -0.006591796875 -0.3681030273437555 +1.24975 -0.005218505859375 -0.0032958984375 -0.3681030273437555 +1.249875 0.0 0.0 -0.3681030273437555 +1.25 0.0 0.0 -0.3681030273437555 +1.250125 0.005218505859375 0.0032958984375 -0.3681030273437555 +1.25025 0.005218505859375 0.0032958984375 -0.3681030273437555 +1.250375 0.01043701171875 0.006591796875 -0.3681030273437555 +1.2505 0.01568603515625 0.009918212890625 -0.3681030273437555 +1.250625 0.01568603515625 0.009918212890625 -0.3681030273437555 +1.25075 0.020904541015625 0.013214111328125 -0.3681030273437555 +1.250875 0.020904541015625 0.013214111328125 -0.3681030273437555 +1.2510000000000002 0.026123046875 0.016510009765625 -0.3681030273437555 +1.251125 0.0313720703125 0.019805908203125 -0.3681030273437555 +1.25125 0.0313720703125 0.019805908203125 -0.3681030273437555 +1.2513750000000002 0.036590576171875 0.023101806640625 -0.3681030273437555 +1.2515 0.036590576171875 0.023101806640625 -0.3681030273437555 +1.251625 0.04180908203125 0.026397705078125 -0.3681030273437555 +1.25175 0.047027587890625 0.029693603515625 -0.3681030273437555 +1.251875 0.047027587890625 0.029693603515625 -0.3681030273437555 +1.252 0.05224609375 0.032989501953125 -0.3681030273437555 +1.252125 0.05224609375 0.032989501953125 -0.3681030273437555 +1.25225 0.05743408203125 0.036285400390625 -0.3681030273437555 +1.252375 0.0626220703125 0.039581298828125 -0.3681030273437555 +1.2525 0.0626220703125 0.039581298828125 -0.3681030273437555 +1.252625 0.06781005859375 0.0428466796875 -0.3681030273437555 +1.25275 0.06781005859375 0.0428466796875 -0.3681030273437555 +1.252875 0.072998046875 0.046112060546875 -0.3681030273437555 +1.2530000000000002 0.07818603515625 0.049407958984375 -0.3681030273437555 +1.253125 0.07818603515625 0.049407958984375 -0.3681030273437555 +1.25325 0.083343505859375 0.05267333984375 -0.3681030273437555 +1.2533750000000002 0.083343505859375 0.05267333984375 -0.3681030273437555 +1.2535 0.0885009765625 0.055908203125 -0.3681030273437555 +1.253625 0.093658447265625 0.059173583984375 -0.3681030273437555 +1.25375 0.093658447265625 0.059173583984375 -0.3681030273437555 +1.253875 0.098785400390625 0.062408447265625 -0.3681030273437555 +1.254 0.098785400390625 0.062408447265625 -0.3681030273437555 +1.254125 0.103912353515625 0.065643310546875 -0.3681030273437555 +1.25425 0.109039306640625 0.068878173828125 -0.3681030273437555 +1.254375 0.109039306640625 0.068878173828125 -0.3681030273437555 +1.2545 0.1141357421875 0.072113037109375 -0.3681030273437555 +1.254625 0.1141357421875 0.072113037109375 -0.3681030273437555 +1.25475 0.119232177734375 0.075347900390625 -0.3681030273437555 +1.254875 0.124298095703125 0.078521728515625 -0.3681030273437555 +1.2550000000000002 0.124298095703125 0.078521728515625 -0.3681030273437555 +1.255125 0.129364013671875 0.08172607421875 -0.3681030273437555 +1.25525 0.129364013671875 0.08172607421875 -0.3681030273437555 +1.2553750000000002 0.134429931640625 0.084930419921875 -0.3681030273437555 +1.2555 0.13946533203125 0.088104248046875 -0.3681030273437555 +1.255625 0.13946533203125 0.088104248046875 -0.3681030273437555 +1.25575 0.14447021484375 0.091278076171875 -0.3681030273437555 +1.255875 0.14447021484375 0.091278076171875 -0.3681030273437555 +1.256 0.14947509765625 0.094451904296875 -0.3681030273437555 +1.256125 0.15447998046875 0.09759521484375 -0.3681030273437555 +1.25625 0.15447998046875 0.09759521484375 -0.3681030273437555 +1.256375 0.159454345703125 0.100738525390625 -0.3681030273437555 +1.2565 0.159454345703125 0.100738525390625 -0.3681030273437555 +1.256625 0.164398193359375 0.103851318359375 -0.3681030273437555 +1.25675 0.169342041015625 0.10699462890625 -0.3681030273437555 +1.256875 0.169342041015625 0.10699462890625 -0.3681030273437555 +1.2570000000000002 0.17425537109375 0.110076904296875 -0.3681030273437555 +1.257125 0.17425537109375 0.110076904296875 -0.3681030273437555 +1.25725 0.17913818359375 0.113189697265625 -0.3681030273437555 +1.2573750000000002 0.18402099609375 0.11627197265625 -0.3681030273437555 +1.2575 0.18402099609375 0.11627197265625 -0.3681030273437555 +1.257625 0.188873291015625 0.11932373046875 -0.3681030273437555 +1.25775 0.188873291015625 0.11932373046875 -0.3681030273437555 +1.257875 0.1937255859375 0.122406005859375 -0.3681030273437555 +1.258 0.19854736328125 0.12542724609375 -0.3681030273437555 +1.258125 0.19854736328125 0.12542724609375 -0.3681030273437555 +1.25825 0.203338623046875 0.12847900390625 -0.3681030273437555 +1.258375 0.203338623046875 0.12847900390625 -0.3681030273437555 +1.2585 0.208099365234375 0.1314697265625 -0.3681030273437555 +1.258625 0.212860107421875 0.134490966796875 -0.3681030273437555 +1.25875 0.212860107421875 0.134490966796875 -0.3681030273437555 +1.258875 0.21759033203125 0.137481689453125 -0.3681030273437555 +1.2590000000000002 0.21759033203125 0.137481689453125 -0.3681030273437555 +1.259125 0.2222900390625 0.14044189453125 -0.3681030273437555 +1.25925 0.226959228515625 0.143402099609375 -0.3681030273437555 +1.2593750000000002 0.226959228515625 0.143402099609375 -0.3681030273437555 +1.2595 0.231597900390625 0.146331787109375 -0.3681030273437555 +1.259625 0.231597900390625 0.146331787109375 -0.3681030273437555 +1.25975 0.236236572265625 0.149261474609375 -0.3681030273437555 +1.259875 0.2408447265625 0.15216064453125 -0.3681030273437555 +1.26 0.2408447265625 0.15216064453125 -0.3681030273437555 +1.260125 0.24542236328125 0.155059814453125 -0.3681030273437555 +1.26025 0.24542236328125 0.155059814453125 -0.3681030273437555 +1.260375 0.249969482421875 0.157928466796875 -0.3681030273437555 +1.2605 0.25445556640625 0.1607666015625 -0.3681030273437555 +1.260625 0.25445556640625 0.1607666015625 -0.3681030273437555 +1.26075 0.25897216796875 0.16363525390625 -0.3681030273437555 +1.260875 0.25897216796875 0.16363525390625 -0.3681030273437555 +1.2610000000000002 0.263427734375 0.16644287109375 -0.3681030273437555 +1.261125 0.267852783203125 0.16925048828125 -0.3681030273437555 +1.26125 0.267852783203125 0.16925048828125 -0.3681030273437555 +1.2613750000000002 0.27227783203125 0.172027587890625 -0.3681030273437555 +1.2615 0.27227783203125 0.172027587890625 -0.3681030273437555 +1.261625 0.276641845703125 0.174774169921875 -0.3681030273437555 +1.26175 0.280975341796875 0.177520751953125 -0.3681030273437555 +1.261875 0.280975341796875 0.177520751953125 -0.3681030273437555 +1.262 0.285308837890625 0.180267333984375 -0.3681030273437555 +1.262125 0.285308837890625 0.180267333984375 -0.3681030273437555 +1.26225 0.289581298828125 0.1829833984375 -0.3681030273437555 +1.262375 0.2938232421875 0.185638427734375 -0.3681030273437555 +1.2625 0.2938232421875 0.185638427734375 -0.3681030273437555 +1.262625 0.298065185546875 0.188323974609375 -0.3681030273437555 +1.26275 0.298065185546875 0.188323974609375 -0.3681030273437555 +1.262875 0.30224609375 0.19097900390625 -0.3681030273437555 +1.2630000000000002 0.306396484375 0.193603515625 -0.3681030273437555 +1.263125 0.306396484375 0.193603515625 -0.3681030273437555 +1.26325 0.310516357421875 0.196197509765625 -0.3681030273437555 +1.2633750000000002 0.310516357421875 0.196197509765625 -0.3681030273437555 +1.2635 0.314605712890625 0.198760986328125 -0.3681030273437555 +1.263625 0.31866455078125 0.201324462890625 -0.3681030273437555 +1.26375 0.31866455078125 0.201324462890625 -0.3681030273437555 +1.263875 0.322662353515625 0.203887939453125 -0.3681030273437555 +1.264 0.322662353515625 0.203887939453125 -0.3681030273437555 +1.264125 0.32666015625 0.206390380859375 -0.3681030273437555 +1.26425 0.330596923828125 0.208892822265625 -0.3681030273437555 +1.264375 0.330596923828125 0.208892822265625 -0.3681030273437555 +1.2645 0.334503173828125 0.21136474609375 -0.3681030273437555 +1.264625 0.334503173828125 0.21136474609375 -0.3681030273437555 +1.26475 0.33837890625 0.21380615234375 -0.3681030273437555 +1.264875 0.34222412109375 0.216217041015625 -0.3681030273437555 +1.2650000000000002 0.34222412109375 0.216217041015625 -0.3681030273437555 +1.265125 0.34600830078125 0.2186279296875 -0.3681030273437555 +1.26525 0.34600830078125 0.2186279296875 -0.3681030273437555 +1.265375 0.349761962890625 0.22100830078125 -0.3681030273437555 +1.2655 0.353485107421875 0.223358154296875 -0.3681030273437555 +1.265625 0.353485107421875 0.223358154296875 -0.3681030273437555 +1.26575 0.357177734375 0.225677490234375 -0.3681030273437555 +1.265875 0.357177734375 0.225677490234375 -0.3681030273437555 +1.266 0.360809326171875 0.22796630859375 -0.3681030273437555 +1.266125 0.36444091796875 0.230255126953125 -0.3681030273437555 +1.26625 0.36444091796875 0.230255126953125 -0.3681030273437555 +1.266375 0.36798095703125 0.232513427734375 -0.3681030273437555 +1.2665 0.36798095703125 0.232513427734375 -0.3681030273437555 +1.2666250000000002 0.37152099609375 0.2347412109375 -0.3681030273437555 +1.26675 0.375 0.2369384765625 -0.3681030273437555 +1.266875 0.375 0.2369384765625 -0.3681030273437555 +1.2670000000000002 0.378448486328125 0.239105224609375 -0.3681030273437555 +1.267125 0.378448486328125 0.239105224609375 -0.3681030273437555 +1.26725 0.3818359375 0.24127197265625 -0.3681030273437555 +1.267375 0.38519287109375 0.243377685546875 -0.3681030273437555 +1.2675 0.38519287109375 0.243377685546875 -0.3681030273437555 +1.267625 0.388519287109375 0.2454833984375 -0.3681030273437555 +1.26775 0.388519287109375 0.2454833984375 -0.3681030273437555 +1.267875 0.39178466796875 0.24755859375 -0.3681030273437555 +1.268 0.39501953125 0.249603271484375 -0.3681030273437555 +1.268125 0.39501953125 0.249603271484375 -0.3681030273437555 +1.26825 0.398193359375 0.2515869140625 -0.3681030273437555 +1.268375 0.398193359375 0.2515869140625 -0.3681030273437555 +1.2685 0.401336669921875 0.253570556640625 -0.3681030273437555 +1.2686250000000002 0.404449462890625 0.25555419921875 -0.3681030273437555 +1.26875 0.404449462890625 0.25555419921875 -0.3681030273437555 +1.268875 0.407501220703125 0.257476806640625 -0.3681030273437555 +1.2690000000000002 0.407501220703125 0.257476806640625 -0.3681030273437555 +1.269125 0.4105224609375 0.259368896484375 -0.3681030273437555 +1.26925 0.413482666015625 0.26123046875 -0.3681030273437555 +1.269375 0.413482666015625 0.26123046875 -0.3681030273437555 +1.2695 0.416412353515625 0.263092041015625 -0.3681030273437555 +1.269625 0.416412353515625 0.263092041015625 -0.3681030273437555 +1.26975 0.419281005859375 0.264923095703125 -0.3681030273437555 +1.269875 0.422119140625 0.266693115234375 -0.3681030273437555 +1.27 0.422119140625 0.266693115234375 -0.3681030273437555 +1.270125 0.424896240234375 0.268463134765625 -0.3681030273437555 +1.27025 0.424896240234375 0.268463134765625 -0.3681030273437555 +1.270375 0.4276123046875 0.270172119140625 -0.3681030273437555 +1.2705 0.4302978515625 0.271881103515625 -0.3681030273437555 +1.2706250000000002 0.4302978515625 0.271881103515625 -0.3681030273437555 +1.27075 0.432952880859375 0.2735595703125 -0.3681030273437555 +1.270875 0.432952880859375 0.2735595703125 -0.3681030273437555 +1.2710000000000002 0.435546875 0.27520751953125 -0.3681030273437555 +1.271125 0.438079833984375 0.27679443359375 -0.3681030273437555 +1.27125 0.438079833984375 0.27679443359375 -0.3681030273437555 +1.271375 0.440582275390625 0.27838134765625 -0.3681030273437555 +1.2715 0.440582275390625 0.27838134765625 -0.3681030273437555 +1.271625 0.44305419921875 0.279937744140625 -0.3681030273437555 +1.27175 0.4454345703125 0.28143310546875 -0.3681030273437555 +1.271875 0.4454345703125 0.28143310546875 -0.3681030273437555 +1.272 0.447784423828125 0.282928466796875 -0.3681030273437555 +1.272125 0.447784423828125 0.282928466796875 -0.3681030273437555 +1.27225 0.450103759765625 0.284393310546875 -0.3681030273437555 +1.272375 0.452362060546875 0.285797119140625 -0.3681030273437555 +1.2725 0.452362060546875 0.285797119140625 -0.3681030273437555 +1.2726250000000002 0.454559326171875 0.287200927734375 -0.3681030273437555 +1.27275 0.454559326171875 0.287200927734375 -0.3681030273437555 +1.272875 0.45672607421875 0.28857421875 -0.3681030273437555 +1.2730000000000002 0.458831787109375 0.289886474609375 -0.3681030273437555 +1.273125 0.458831787109375 0.289886474609375 -0.3681030273437555 +1.27325 0.46087646484375 0.29119873046875 -0.3681030273437555 +1.273375 0.46087646484375 0.29119873046875 -0.3681030273437555 +1.2735 0.462890625 0.292449951171875 -0.3681030273437555 +1.273625 0.464813232421875 0.293670654296875 -0.3681030273437555 +1.27375 0.464813232421875 0.293670654296875 -0.3681030273437555 +1.273875 0.46673583984375 0.294891357421875 -0.3681030273437555 +1.274 0.46673583984375 0.294891357421875 -0.3681030273437555 +1.274125 0.46856689453125 0.296051025390625 -0.3681030273437555 +1.27425 0.470367431640625 0.29718017578125 -0.3681030273437555 +1.274375 0.470367431640625 0.29718017578125 -0.3681030273437555 +1.2745 0.472137451171875 0.298309326171875 -0.3681030273437555 +1.2746250000000002 0.472137451171875 0.298309326171875 -0.3681030273437555 +1.27475 0.47381591796875 0.29937744140625 -0.3681030273437555 +1.274875 0.4754638671875 0.3004150390625 -0.3681030273437555 +1.2750000000000002 0.4754638671875 0.3004150390625 -0.3681030273437555 +1.275125 0.47705078125 0.301422119140625 -0.3681030273437555 +1.27525 0.47705078125 0.301422119140625 -0.3681030273437555 +1.275375 0.478607177734375 0.302398681640625 -0.3681030273437555 +1.2755 0.480072021484375 0.303314208984375 -0.3681030273437555 +1.275625 0.480072021484375 0.303314208984375 -0.3681030273437555 +1.27575 0.48150634765625 0.304229736328125 -0.3681030273437555 +1.275875 0.48150634765625 0.304229736328125 -0.3681030273437555 +1.276 0.48291015625 0.30511474609375 -0.3681030273437555 +1.276125 0.484222412109375 0.305938720703125 -0.3681030273437555 +1.27625 0.484222412109375 0.305938720703125 -0.3681030273437555 +1.276375 0.485504150390625 0.3067626953125 -0.3681030273437555 +1.2765 0.485504150390625 0.3067626953125 -0.3681030273437555 +1.2766250000000002 0.486724853515625 0.307525634765625 -0.3681030273437555 +1.27675 0.487884521484375 0.308258056640625 -0.3681030273437555 +1.276875 0.487884521484375 0.308258056640625 -0.3681030273437555 +1.2770000000000002 0.489013671875 0.3089599609375 -0.3681030273437555 +1.277125 0.489013671875 0.3089599609375 -0.3681030273437555 +1.27725 0.490081787109375 0.30963134765625 -0.3681030273437555 +1.277375 0.4910888671875 0.310272216796875 -0.3681030273437555 +1.2775 0.4910888671875 0.310272216796875 -0.3681030273437555 +1.277625 0.492034912109375 0.310882568359375 -0.3681030273437555 +1.27775 0.492034912109375 0.310882568359375 -0.3681030273437555 +1.277875 0.492950439453125 0.31146240234375 -0.3681030273437555 +1.278 0.4937744140625 0.311981201171875 -0.3681030273437555 +1.278125 0.4937744140625 0.311981201171875 -0.3681030273437555 +1.27825 0.49456787109375 0.312469482421875 -0.3681030273437555 +1.278375 0.49456787109375 0.312469482421875 -0.3681030273437555 +1.2785 0.49530029296875 0.312957763671875 -0.3681030273437555 +1.2786250000000002 0.496002197265625 0.313385009765625 -0.3681030273437555 +1.27875 0.496002197265625 0.313385009765625 -0.3681030273437555 +1.278875 0.496612548828125 0.31378173828125 -0.3681030273437555 +1.2790000000000002 0.496612548828125 0.31378173828125 -0.3681030273437555 +1.279125 0.4971923828125 0.31414794921875 -0.3681030273437555 +1.27925 0.497711181640625 0.314483642578125 -0.3681030273437555 +1.279375 0.497711181640625 0.314483642578125 -0.3681030273437555 +1.2795 0.498199462890625 0.31475830078125 -0.3681030273437555 +1.279625 0.498199462890625 0.31475830078125 -0.3681030273437555 +1.27975 0.49859619140625 0.315032958984375 -0.3681030273437555 +1.279875 0.49896240234375 0.31524658203125 -0.3681030273437555 +1.28 0.49896240234375 0.148345947265625 -0.7025939941406295 +1.280125 0.499267578125 0.1484375 -0.7025939941406295 +1.28025 0.499267578125 0.1484375 -0.7025939941406295 +1.280375 0.49951171875 0.14849853515625 -0.7025939941406295 +1.2805 0.49969482421875 0.1485595703125 -0.7025939941406295 +1.2806250000000002 0.49969482421875 0.1485595703125 -0.7025939941406295 +1.28075 0.49981689453125 0.148590087890625 -0.7025939941406295 +1.280875 0.49981689453125 0.148590087890625 -0.7025939941406295 +1.281 0.499908447265625 0.14862060546875 -0.7025939941406295 +1.281125 0.49993896484375 0.14862060546875 -0.7025939941406295 +1.28125 0.49993896484375 0.14862060546875 -0.7025939941406295 +1.281375 0.499908447265625 0.14862060546875 -0.7025939941406295 +1.2815 0.499908447265625 0.14862060546875 -0.7025939941406295 +1.281625 0.49981689453125 0.148590087890625 -0.7025939941406295 +1.28175 0.49969482421875 0.1485595703125 -0.7025939941406295 +1.281875 0.49969482421875 0.1485595703125 -0.7025939941406295 +1.282 0.49951171875 0.14849853515625 -0.7025939941406295 +1.282125 0.49951171875 0.14849853515625 -0.7025939941406295 +1.2822500000000002 0.499267578125 0.1484375 -0.7025939941406295 +1.282375 0.49896240234375 0.148345947265625 -0.7025939941406295 +1.2825 0.49896240234375 0.148345947265625 -0.7025939941406295 +1.2826250000000002 0.49859619140625 0.148223876953125 -0.7025939941406295 +1.28275 0.49859619140625 0.148223876953125 -0.7025939941406295 +1.282875 0.498199462890625 0.148101806640625 -0.7025939941406295 +1.283 0.497711181640625 0.147979736328125 -0.7025939941406295 +1.283125 0.497711181640625 0.147979736328125 -0.7025939941406295 +1.28325 0.4971923828125 0.1478271484375 -0.7025939941406295 +1.283375 0.4971923828125 0.1478271484375 -0.7025939941406295 +1.2835 0.496612548828125 0.14764404296875 -0.7025939941406295 +1.283625 0.496002197265625 0.1474609375 -0.7025939941406295 +1.28375 0.496002197265625 0.1474609375 -0.7025939941406295 +1.283875 0.49530029296875 0.147247314453125 -0.7025939941406295 +1.284 0.49530029296875 0.147247314453125 -0.7025939941406295 +1.284125 0.49456787109375 0.14703369140625 -0.7025939941406295 +1.2842500000000002 0.4937744140625 0.14678955078125 -0.7025939941406295 +1.284375 0.4937744140625 0.14678955078125 -0.7025939941406295 +1.2845 0.492950439453125 0.14654541015625 -0.7025939941406295 +1.2846250000000002 0.492950439453125 0.14654541015625 -0.7025939941406295 +1.28475 0.492034912109375 0.146270751953125 -0.7025939941406295 +1.284875 0.4910888671875 0.14599609375 -0.7025939941406295 +1.285 0.4910888671875 0.14599609375 -0.7025939941406295 +1.285125 0.490081787109375 0.14569091796875 -0.7025939941406295 +1.28525 0.490081787109375 0.14569091796875 -0.7025939941406295 +1.285375 0.489013671875 0.1453857421875 -0.7025939941406295 +1.2855 0.487884521484375 0.145050048828125 -0.7025939941406295 +1.285625 0.487884521484375 0.145050048828125 -0.7025939941406295 +1.28575 0.486724853515625 0.14471435546875 -0.7025939941406295 +1.285875 0.486724853515625 0.14471435546875 -0.7025939941406295 +1.286 0.485504150390625 0.14434814453125 -0.7025939941406295 +1.286125 0.484222412109375 0.143951416015625 -0.7025939941406295 +1.2862500000000002 0.484222412109375 0.143951416015625 -0.7025939941406295 +1.286375 0.48291015625 0.1435546875 -0.7025939941406295 +1.2865 0.48291015625 0.1435546875 -0.7025939941406295 +1.2866250000000002 0.48150634765625 0.143157958984375 -0.7025939941406295 +1.28675 0.480072021484375 0.142730712890625 -0.7025939941406295 +1.286875 0.480072021484375 0.142730712890625 -0.7025939941406295 +1.287 0.478607177734375 0.14227294921875 -0.7025939941406295 +1.287125 0.478607177734375 0.14227294921875 -0.7025939941406295 +1.28725 0.47705078125 0.141815185546875 -0.7025939941406295 +1.287375 0.4754638671875 0.141357421875 -0.7025939941406295 +1.2875 0.4754638671875 0.141357421875 -0.7025939941406295 +1.287625 0.47381591796875 0.140869140625 -0.7025939941406295 +1.28775 0.47381591796875 0.140869140625 -0.7025939941406295 +1.287875 0.472137451171875 0.140350341796875 -0.7025939941406295 +1.288 0.470367431640625 0.13983154296875 -0.7025939941406295 +1.288125 0.470367431640625 0.13983154296875 -0.7025939941406295 +1.2882500000000002 0.46856689453125 0.139312744140625 -0.7025939941406295 +1.288375 0.46856689453125 0.139312744140625 -0.7025939941406295 +1.2885 0.46673583984375 0.138763427734375 -0.7025939941406295 +1.2886250000000002 0.464813232421875 0.13818359375 -0.7025939941406295 +1.28875 0.464813232421875 0.13818359375 -0.7025939941406295 +1.288875 0.462890625 0.137603759765625 -0.7025939941406295 +1.289 0.462890625 0.137603759765625 -0.7025939941406295 +1.289125 0.46087646484375 0.13702392578125 -0.7025939941406295 +1.28925 0.458831787109375 0.13641357421875 -0.7025939941406295 +1.289375 0.458831787109375 0.13641357421875 -0.7025939941406295 +1.2895 0.45672607421875 0.135772705078125 -0.7025939941406295 +1.289625 0.45672607421875 0.135772705078125 -0.7025939941406295 +1.28975 0.454559326171875 0.1351318359375 -0.7025939941406295 +1.289875 0.452362060546875 0.134490966796875 -0.7025939941406295 +1.29 0.452362060546875 0.134490966796875 -0.7025939941406295 +1.290125 0.450103759765625 0.133819580078125 -0.7025939941406295 +1.2902500000000002 0.450103759765625 0.133819580078125 -0.7025939941406295 +1.290375 0.447784423828125 0.13311767578125 -0.7025939941406295 +1.2905 0.4454345703125 0.132415771484375 -0.7025939941406295 +1.2906250000000002 0.4454345703125 0.132415771484375 -0.7025939941406295 +1.29075 0.44305419921875 0.1317138671875 -0.7025939941406295 +1.290875 0.44305419921875 0.1317138671875 -0.7025939941406295 +1.291 0.440582275390625 0.1309814453125 -0.7025939941406295 +1.291125 0.438079833984375 0.1302490234375 -0.7025939941406295 +1.29125 0.438079833984375 0.1302490234375 -0.7025939941406295 +1.291375 0.435546875 0.129486083984375 -0.7025939941406295 +1.2915 0.435546875 0.129486083984375 -0.7025939941406295 +1.291625 0.432952880859375 0.12872314453125 -0.7025939941406295 +1.29175 0.4302978515625 0.1279296875 -0.7025939941406295 +1.291875 0.4302978515625 0.1279296875 -0.7025939941406295 +1.292 0.4276123046875 0.12713623046875 -0.7025939941406295 +1.292125 0.4276123046875 0.12713623046875 -0.7025939941406295 +1.2922500000000002 0.424896240234375 0.126312255859375 -0.7025939941406295 +1.292375 0.422119140625 0.12548828125 -0.7025939941406295 +1.2925 0.422119140625 0.12548828125 -0.7025939941406295 +1.2926250000000002 0.419281005859375 0.1246337890625 -0.7025939941406295 +1.29275 0.419281005859375 0.1246337890625 -0.7025939941406295 +1.292875 0.416412353515625 0.123779296875 -0.7025939941406295 +1.293 0.413482666015625 0.1229248046875 -0.7025939941406295 +1.293125 0.413482666015625 0.1229248046875 -0.7025939941406295 +1.29325 0.4105224609375 0.122039794921875 -0.7025939941406295 +1.293375 0.4105224609375 0.122039794921875 -0.7025939941406295 +1.2935 0.407501220703125 0.12115478515625 -0.7025939941406295 +1.293625 0.404449462890625 0.1202392578125 -0.7025939941406295 +1.29375 0.404449462890625 0.1202392578125 -0.7025939941406295 +1.293875 0.401336669921875 0.11932373046875 -0.7025939941406295 +1.294 0.401336669921875 0.11932373046875 -0.7025939941406295 +1.294125 0.398193359375 0.118377685546875 -0.7025939941406295 +1.2942500000000002 0.39501953125 0.117431640625 -0.7025939941406295 +1.294375 0.39501953125 0.117431640625 -0.7025939941406295 +1.2945 0.39178466796875 0.116485595703125 -0.7025939941406295 +1.2946250000000002 0.39178466796875 0.116485595703125 -0.7025939941406295 +1.29475 0.388519287109375 0.115509033203125 -0.7025939941406295 +1.294875 0.38519287109375 0.114501953125 -0.7025939941406295 +1.295 0.38519287109375 0.114501953125 -0.7025939941406295 +1.295125 0.3818359375 0.113525390625 -0.7025939941406295 +1.29525 0.3818359375 0.113525390625 -0.7025939941406295 +1.295375 0.378448486328125 0.112518310546875 -0.7025939941406295 +1.2955 0.375 0.111480712890625 -0.7025939941406295 +1.295625 0.375 0.111480712890625 -0.7025939941406295 +1.29575 0.37152099609375 0.110443115234375 -0.7025939941406295 +1.295875 0.37152099609375 0.110443115234375 -0.7025939941406295 +1.296 0.36798095703125 0.109405517578125 -0.7025939941406295 +1.296125 0.36444091796875 0.10833740234375 -0.7025939941406295 +1.2962500000000002 0.36444091796875 0.10833740234375 -0.7025939941406295 +1.296375 0.360809326171875 0.107269287109375 -0.7025939941406295 +1.2965 0.360809326171875 0.107269287109375 -0.7025939941406295 +1.296625 0.357177734375 0.106201171875 -0.7025939941406295 +1.29675 0.353485107421875 0.1051025390625 -0.7025939941406295 +1.296875 0.353485107421875 0.1051025390625 -0.7025939941406295 +1.297 0.349761962890625 0.103973388671875 -0.7025939941406295 +1.297125 0.349761962890625 0.103973388671875 -0.7025939941406295 +1.29725 0.34600830078125 0.102874755859375 -0.7025939941406295 +1.297375 0.34222412109375 0.10174560546875 -0.7025939941406295 +1.2975 0.34222412109375 0.10174560546875 -0.7025939941406295 +1.297625 0.33837890625 0.1005859375 -0.7025939941406295 +1.29775 0.33837890625 0.1005859375 -0.7025939941406295 +1.2978750000000002 0.334503173828125 0.099456787109375 -0.7025939941406295 +1.298 0.330596923828125 0.098297119140625 -0.7025939941406295 +1.298125 0.330596923828125 0.098297119140625 -0.7025939941406295 +1.2982500000000002 0.32666015625 0.09710693359375 -0.7025939941406295 +1.298375 0.32666015625 0.09710693359375 -0.7025939941406295 +1.2985 0.322662353515625 0.095916748046875 -0.7025939941406295 +1.298625 0.31866455078125 0.0947265625 -0.7025939941406295 +1.29875 0.31866455078125 0.0947265625 -0.7025939941406295 +1.298875 0.314605712890625 0.093536376953125 -0.7025939941406295 +1.299 0.314605712890625 0.093536376953125 -0.7025939941406295 +1.299125 0.310516357421875 0.092315673828125 -0.7025939941406295 +1.29925 0.306396484375 0.091094970703125 -0.7025939941406295 +1.299375 0.306396484375 0.091094970703125 -0.7025939941406295 +1.2995 0.30224609375 0.08984375 -0.7025939941406295 +1.299625 0.30224609375 0.08984375 -0.7025939941406295 +1.29975 0.298065185546875 0.088623046875 -0.7025939941406295 +1.2998750000000002 0.2938232421875 0.08734130859375 -0.7025939941406295 +1.3 0.2938232421875 0.08734130859375 -0.7025939941406295 +1.300125 0.289581298828125 0.086090087890625 -0.7025939941406295 +1.3002500000000002 0.289581298828125 0.086090087890625 -0.7025939941406295 +1.300375 0.285308837890625 0.084808349609375 -0.7025939941406295 +1.3005 0.280975341796875 0.083526611328125 -0.7025939941406295 +1.300625 0.280975341796875 0.083526611328125 -0.7025939941406295 +1.30075 0.276641845703125 0.082244873046875 -0.7025939941406295 +1.300875 0.276641845703125 0.082244873046875 -0.7025939941406295 +1.301 0.27227783203125 0.0809326171875 -0.7025939941406295 +1.301125 0.267852783203125 0.079620361328125 -0.7025939941406295 +1.30125 0.267852783203125 0.079620361328125 -0.7025939941406295 +1.301375 0.263427734375 0.07830810546875 -0.7025939941406295 +1.3015 0.263427734375 0.07830810546875 -0.7025939941406295 +1.301625 0.25897216796875 0.076995849609375 -0.7025939941406295 +1.30175 0.25445556640625 0.075653076171875 -0.7025939941406295 +1.3018750000000002 0.25445556640625 0.075653076171875 -0.7025939941406295 +1.302 0.249969482421875 0.074310302734375 -0.7025939941406295 +1.302125 0.249969482421875 0.074310302734375 -0.7025939941406295 +1.3022500000000002 0.24542236328125 0.072967529296875 -0.7025939941406295 +1.302375 0.2408447265625 0.07159423828125 -0.7025939941406295 +1.3025 0.2408447265625 0.07159423828125 -0.7025939941406295 +1.302625 0.236236572265625 0.070220947265625 -0.7025939941406295 +1.30275 0.236236572265625 0.070220947265625 -0.7025939941406295 +1.302875 0.231597900390625 0.06884765625 -0.7025939941406295 +1.303 0.226959228515625 0.067474365234375 -0.7025939941406295 +1.303125 0.226959228515625 0.067474365234375 -0.7025939941406295 +1.30325 0.2222900390625 0.066070556640625 -0.7025939941406295 +1.303375 0.2222900390625 0.066070556640625 -0.7025939941406295 +1.3035 0.21759033203125 0.064666748046875 -0.7025939941406295 +1.303625 0.212860107421875 0.063262939453125 -0.7025939941406295 +1.30375 0.212860107421875 0.063262939453125 -0.7025939941406295 +1.3038750000000002 0.208099365234375 0.061859130859375 -0.7025939941406295 +1.304 0.208099365234375 0.061859130859375 -0.7025939941406295 +1.304125 0.203338623046875 0.060455322265625 -0.7025939941406295 +1.3042500000000002 0.19854736328125 0.05902099609375 -0.7025939941406295 +1.304375 0.19854736328125 0.05902099609375 -0.7025939941406295 +1.3045 0.1937255859375 0.057586669921875 -0.7025939941406295 +1.304625 0.1937255859375 0.057586669921875 -0.7025939941406295 +1.30475 0.188873291015625 0.05615234375 -0.7025939941406295 +1.304875 0.18402099609375 0.054718017578125 -0.7025939941406295 +1.305 0.18402099609375 0.054718017578125 -0.7025939941406295 +1.305125 0.17913818359375 0.053253173828125 -0.7025939941406295 +1.30525 0.17913818359375 0.053253173828125 -0.7025939941406295 +1.305375 0.17425537109375 0.051788330078125 -0.7025939941406295 +1.3055 0.169342041015625 0.050323486328125 -0.7025939941406295 +1.305625 0.169342041015625 0.050323486328125 -0.7025939941406295 +1.30575 0.164398193359375 0.048858642578125 -0.7025939941406295 +1.3058750000000002 0.164398193359375 0.048858642578125 -0.7025939941406295 +1.306 0.159454345703125 0.047393798828125 -0.7025939941406295 +1.306125 0.15447998046875 0.045928955078125 -0.7025939941406295 +1.3062500000000002 0.15447998046875 0.045928955078125 -0.7025939941406295 +1.306375 0.14947509765625 0.04443359375 -0.7025939941406295 +1.3065 0.14947509765625 0.04443359375 -0.7025939941406295 +1.306625 0.14447021484375 0.042938232421875 -0.7025939941406295 +1.30675 0.13946533203125 0.04144287109375 -0.7025939941406295 +1.306875 0.13946533203125 0.04144287109375 -0.7025939941406295 +1.307 0.134429931640625 0.039947509765625 -0.7025939941406295 +1.307125 0.134429931640625 0.039947509765625 -0.7025939941406295 +1.30725 0.129364013671875 0.0384521484375 -0.7025939941406295 +1.307375 0.124298095703125 0.036956787109375 -0.7025939941406295 +1.3075 0.124298095703125 0.036956787109375 -0.7025939941406295 +1.307625 0.119232177734375 0.035430908203125 -0.7025939941406295 +1.30775 0.119232177734375 0.035430908203125 -0.7025939941406295 +1.3078750000000002 0.1141357421875 0.033935546875 -0.7025939941406295 +1.308 0.109039306640625 0.03240966796875 -0.7025939941406295 +1.308125 0.109039306640625 0.03240966796875 -0.7025939941406295 +1.3082500000000002 0.103912353515625 0.0308837890625 -0.7025939941406295 +1.308375 0.103912353515625 0.0308837890625 -0.7025939941406295 +1.3085 0.098785400390625 0.02935791015625 -0.7025939941406295 +1.308625 0.093658447265625 0.02783203125 -0.7025939941406295 +1.30875 0.093658447265625 0.02783203125 -0.7025939941406295 +1.308875 0.0885009765625 0.02630615234375 -0.7025939941406295 +1.309 0.0885009765625 0.02630615234375 -0.7025939941406295 +1.309125 0.083343505859375 0.0247802734375 -0.7025939941406295 +1.30925 0.07818603515625 0.023223876953125 -0.7025939941406295 +1.309375 0.07818603515625 0.023223876953125 -0.7025939941406295 +1.3095 0.072998046875 0.021697998046875 -0.7025939941406295 +1.309625 0.072998046875 0.021697998046875 -0.7025939941406295 +1.30975 0.06781005859375 0.0201416015625 -0.7025939941406295 +1.3098750000000002 0.0626220703125 0.01861572265625 -0.7025939941406295 +1.31 0.0626220703125 0.01861572265625 -0.7025939941406295 +1.310125 0.05743408203125 0.017059326171875 -0.7025939941406295 +1.3102500000000002 0.05743408203125 0.017059326171875 -0.7025939941406295 +1.310375 0.05224609375 0.015533447265625 -0.7025939941406295 +1.3105 0.047027587890625 0.01397705078125 -0.7025939941406295 +1.310625 0.047027587890625 0.01397705078125 -0.7025939941406295 +1.31075 0.04180908203125 0.012420654296875 -0.7025939941406295 +1.310875 0.04180908203125 0.012420654296875 -0.7025939941406295 +1.311 0.036590576171875 0.0108642578125 -0.7025939941406295 +1.311125 0.0313720703125 0.009307861328125 -0.7025939941406295 +1.31125 0.0313720703125 0.009307861328125 -0.7025939941406295 +1.311375 0.026123046875 0.00775146484375 -0.7025939941406295 +1.3115 0.026123046875 0.00775146484375 -0.7025939941406295 +1.311625 0.020904541015625 0.006195068359375 -0.7025939941406295 +1.31175 0.01568603515625 0.004638671875 -0.7025939941406295 +1.3118750000000002 0.01568603515625 0.004638671875 -0.7025939941406295 +1.312 0.01043701171875 0.000762939453125 -0.9250366210937526 +1.312125 0.01043701171875 0.000762939453125 -0.9250366210937526 +1.31225 0.005218505859375 0.0003662109375 -0.9250366210937526 +1.312375 0.0 0.0 -0.9250366210937526 +1.3125 0.0 0.0 -0.9250366210937526 +1.312625 -0.005218505859375 -0.0003662109375 -0.9250366210937526 +1.31275 -0.005218505859375 -0.0003662109375 -0.9250366210937526 +1.312875 -0.01043701171875 -0.000762939453125 -0.9250366210937526 +1.313 -0.01568603515625 -0.00115966796875 -0.9250366210937526 +1.313125 -0.01568603515625 -0.00115966796875 -0.9250366210937526 +1.31325 -0.020904541015625 -0.001556396484375 -0.9250366210937526 +1.313375 -0.020904541015625 -0.001556396484375 -0.9250366210937526 +1.3135000000000002 -0.026123046875 -0.001953125 -0.9250366210937526 +1.313625 -0.0313720703125 -0.0023193359375 -0.9250366210937526 +1.31375 -0.0313720703125 -0.0023193359375 -0.9250366210937526 +1.3138750000000002 -0.036590576171875 -0.002716064453125 -0.9250366210937526 +1.314 -0.036590576171875 -0.002716064453125 -0.9250366210937526 +1.314125 -0.04180908203125 -0.00311279296875 -0.9250366210937526 +1.31425 -0.047027587890625 -0.003509521484375 -0.9250366210937526 +1.314375 -0.047027587890625 -0.003509521484375 -0.9250366210937526 +1.3145 -0.05224609375 -0.00390625 -0.9250366210937526 +1.314625 -0.05224609375 -0.00390625 -0.9250366210937526 +1.31475 -0.05743408203125 -0.0042724609375 -0.9250366210937526 +1.314875 -0.0626220703125 -0.004669189453125 -0.9250366210937526 +1.315 -0.0626220703125 -0.004669189453125 -0.9250366210937526 +1.315125 -0.06781005859375 -0.00506591796875 -0.9250366210937526 +1.31525 -0.06781005859375 -0.00506591796875 -0.9250366210937526 +1.315375 -0.072998046875 -0.005462646484375 -0.9250366210937526 +1.3155000000000002 -0.07818603515625 -0.005828857421875 -0.9250366210937526 +1.315625 -0.07818603515625 -0.005828857421875 -0.9250366210937526 +1.31575 -0.083343505859375 -0.0062255859375 -0.9250366210937526 +1.3158750000000002 -0.083343505859375 -0.0062255859375 -0.9250366210937526 +1.316 -0.0885009765625 -0.006622314453125 -0.9250366210937526 +1.316125 -0.093658447265625 -0.006988525390625 -0.9250366210937526 +1.31625 -0.093658447265625 -0.006988525390625 -0.9250366210937526 +1.316375 -0.098785400390625 -0.00738525390625 -0.9250366210937526 +1.3165 -0.098785400390625 -0.00738525390625 -0.9250366210937526 +1.316625 -0.103912353515625 -0.00775146484375 -0.9250366210937526 +1.31675 -0.109039306640625 -0.008148193359375 -0.9250366210937526 +1.316875 -0.109039306640625 -0.008148193359375 -0.9250366210937526 +1.317 -0.1141357421875 -0.008544921875 -0.9250366210937526 +1.317125 -0.1141357421875 -0.008544921875 -0.9250366210937526 +1.31725 -0.119232177734375 -0.0089111328125 -0.9250366210937526 +1.317375 -0.124298095703125 -0.00927734375 -0.9250366210937526 +1.3175000000000002 -0.124298095703125 -0.00927734375 -0.9250366210937526 +1.317625 -0.129364013671875 -0.009674072265625 -0.9250366210937526 +1.31775 -0.129364013671875 -0.009674072265625 -0.9250366210937526 +1.3178750000000002 -0.134429931640625 -0.010040283203125 -0.9250366210937526 +1.318 -0.13946533203125 -0.01043701171875 -0.9250366210937526 +1.318125 -0.13946533203125 -0.01043701171875 -0.9250366210937526 +1.31825 -0.14447021484375 -0.01080322265625 -0.9250366210937526 +1.318375 -0.14447021484375 -0.01080322265625 -0.9250366210937526 +1.3185 -0.14947509765625 -0.01116943359375 -0.9250366210937526 +1.318625 -0.15447998046875 -0.01153564453125 -0.9250366210937526 +1.31875 -0.15447998046875 -0.01153564453125 -0.9250366210937526 +1.318875 -0.159454345703125 -0.011932373046875 -0.9250366210937526 +1.319 -0.159454345703125 -0.011932373046875 -0.9250366210937526 +1.319125 -0.164398193359375 -0.012298583984375 -0.9250366210937526 +1.31925 -0.169342041015625 -0.012664794921875 -0.9250366210937526 +1.319375 -0.169342041015625 -0.012664794921875 -0.9250366210937526 +1.3195000000000002 -0.17425537109375 -0.013031005859375 -0.9250366210937526 +1.319625 -0.17425537109375 -0.013031005859375 -0.9250366210937526 +1.31975 -0.17913818359375 -0.013397216796875 -0.9250366210937526 +1.3198750000000002 -0.18402099609375 -0.013763427734375 -0.9250366210937526 +1.32 -0.18402099609375 -0.013763427734375 -0.9250366210937526 +1.320125 -0.188873291015625 -0.014129638671875 -0.9250366210937526 +1.32025 -0.188873291015625 -0.014129638671875 -0.9250366210937526 +1.320375 -0.1937255859375 -0.014495849609375 -0.9250366210937526 +1.3205 -0.19854736328125 -0.014862060546875 -0.9250366210937526 +1.320625 -0.19854736328125 -0.014862060546875 -0.9250366210937526 +1.32075 -0.203338623046875 -0.01519775390625 -0.9250366210937526 +1.320875 -0.203338623046875 -0.01519775390625 -0.9250366210937526 +1.321 -0.208099365234375 -0.01556396484375 -0.9250366210937526 +1.321125 -0.212860107421875 -0.01593017578125 -0.9250366210937526 +1.32125 -0.212860107421875 -0.01593017578125 -0.9250366210937526 +1.321375 -0.21759033203125 -0.016265869140625 -0.9250366210937526 +1.3215000000000002 -0.21759033203125 -0.016265869140625 -0.9250366210937526 +1.321625 -0.2222900390625 -0.016632080078125 -0.9250366210937526 +1.32175 -0.226959228515625 -0.0169677734375 -0.9250366210937526 +1.3218750000000002 -0.226959228515625 -0.0169677734375 -0.9250366210937526 +1.322 -0.231597900390625 -0.017333984375 -0.9250366210937526 +1.322125 -0.231597900390625 -0.017333984375 -0.9250366210937526 +1.32225 -0.236236572265625 -0.017669677734375 -0.9250366210937526 +1.322375 -0.2408447265625 -0.01800537109375 -0.9250366210937526 +1.3225 -0.2408447265625 -0.01800537109375 -0.9250366210937526 +1.322625 -0.24542236328125 -0.01837158203125 -0.9250366210937526 +1.32275 -0.24542236328125 -0.01837158203125 -0.9250366210937526 +1.322875 -0.249969482421875 -0.018707275390625 -0.9250366210937526 +1.323 -0.25445556640625 -0.01904296875 -0.9250366210937526 +1.323125 -0.25445556640625 -0.01904296875 -0.9250366210937526 +1.32325 -0.25897216796875 -0.019378662109375 -0.9250366210937526 +1.323375 -0.25897216796875 -0.019378662109375 -0.9250366210937526 +1.3235000000000002 -0.263427734375 -0.01971435546875 -0.9250366210937526 +1.323625 -0.267852783203125 -0.020050048828125 -0.9250366210937526 +1.32375 -0.267852783203125 -0.020050048828125 -0.9250366210937526 +1.3238750000000002 -0.27227783203125 -0.020355224609375 -0.9250366210937526 +1.324 -0.27227783203125 -0.020355224609375 -0.9250366210937526 +1.324125 -0.276641845703125 -0.02069091796875 -0.9250366210937526 +1.32425 -0.280975341796875 -0.021026611328125 -0.9250366210937526 +1.324375 -0.280975341796875 -0.021026611328125 -0.9250366210937526 +1.3245 -0.285308837890625 -0.021331787109375 -0.9250366210937526 +1.324625 -0.285308837890625 -0.021331787109375 -0.9250366210937526 +1.32475 -0.289581298828125 -0.02166748046875 -0.9250366210937526 +1.324875 -0.2938232421875 -0.02197265625 -0.9250366210937526 +1.325 -0.2938232421875 -0.02197265625 -0.9250366210937526 +1.325125 -0.298065185546875 -0.022308349609375 -0.9250366210937526 +1.32525 -0.298065185546875 -0.022308349609375 -0.9250366210937526 +1.325375 -0.30224609375 -0.022613525390625 -0.9250366210937526 +1.3255000000000002 -0.306396484375 -0.022918701171875 -0.9250366210937526 +1.325625 -0.306396484375 -0.022918701171875 -0.9250366210937526 +1.32575 -0.310516357421875 -0.023223876953125 -0.9250366210937526 +1.3258750000000002 -0.310516357421875 -0.023223876953125 -0.9250366210937526 +1.326 -0.314605712890625 -0.023529052734375 -0.9250366210937526 +1.326125 -0.31866455078125 -0.023834228515625 -0.9250366210937526 +1.32625 -0.31866455078125 -0.023834228515625 -0.9250366210937526 +1.326375 -0.322662353515625 -0.024139404296875 -0.9250366210937526 +1.3265 -0.322662353515625 -0.024139404296875 -0.9250366210937526 +1.326625 -0.32666015625 -0.024444580078125 -0.9250366210937526 +1.32675 -0.330596923828125 -0.024749755859375 -0.9250366210937526 +1.326875 -0.330596923828125 -0.024749755859375 -0.9250366210937526 +1.327 -0.334503173828125 -0.0250244140625 -0.9250366210937526 +1.327125 -0.334503173828125 -0.0250244140625 -0.9250366210937526 +1.32725 -0.33837890625 -0.02532958984375 -0.9250366210937526 +1.327375 -0.34222412109375 -0.025604248046875 -0.9250366210937526 +1.3275000000000002 -0.34222412109375 -0.025604248046875 -0.9250366210937526 +1.327625 -0.34600830078125 -0.02587890625 -0.9250366210937526 +1.32775 -0.34600830078125 -0.02587890625 -0.9250366210937526 +1.3278750000000002 -0.349761962890625 -0.02618408203125 -0.9250366210937526 +1.328 -0.353485107421875 -0.026458740234375 -0.9250366210937526 +1.328125 -0.353485107421875 -0.026458740234375 -0.9250366210937526 +1.32825 -0.357177734375 -0.0267333984375 -0.9250366210937526 +1.328375 -0.357177734375 -0.0267333984375 -0.9250366210937526 +1.3285 -0.360809326171875 -0.027008056640625 -0.9250366210937526 +1.328625 -0.36444091796875 -0.02728271484375 -0.9250366210937526 +1.32875 -0.36444091796875 -0.02728271484375 -0.9250366210937526 +1.328875 -0.36798095703125 -0.02752685546875 -0.9250366210937526 +1.329 -0.36798095703125 -0.02752685546875 -0.9250366210937526 +1.3291250000000002 -0.37152099609375 -0.027801513671875 -0.9250366210937526 +1.32925 -0.375 -0.028045654296875 -0.9250366210937526 +1.329375 -0.375 -0.028045654296875 -0.9250366210937526 +1.3295000000000002 -0.378448486328125 -0.0283203125 -0.9250366210937526 +1.329625 -0.378448486328125 -0.0283203125 -0.9250366210937526 +1.32975 -0.3818359375 -0.028564453125 -0.9250366210937526 +1.329875 -0.38519287109375 -0.02880859375 -0.9250366210937526 +1.33 -0.38519287109375 -0.02880859375 -0.9250366210937526 +1.330125 -0.388519287109375 -0.029083251953125 -0.9250366210937526 +1.33025 -0.388519287109375 -0.029083251953125 -0.9250366210937526 +1.330375 -0.39178466796875 -0.029327392578125 -0.9250366210937526 +1.3305 -0.39501953125 -0.029571533203125 -0.9250366210937526 +1.330625 -0.39501953125 -0.029571533203125 -0.9250366210937526 +1.33075 -0.398193359375 -0.02978515625 -0.9250366210937526 +1.330875 -0.398193359375 -0.02978515625 -0.9250366210937526 +1.331 -0.401336669921875 -0.030029296875 -0.9250366210937526 +1.3311250000000002 -0.404449462890625 -0.0302734375 -0.9250366210937526 +1.33125 -0.404449462890625 -0.0302734375 -0.9250366210937526 +1.331375 -0.407501220703125 -0.030487060546875 -0.9250366210937526 +1.3315000000000002 -0.407501220703125 -0.030487060546875 -0.9250366210937526 +1.331625 -0.4105224609375 -0.030731201171875 -0.9250366210937526 +1.33175 -0.413482666015625 -0.03094482421875 -0.9250366210937526 +1.331875 -0.413482666015625 -0.03094482421875 -0.9250366210937526 +1.332 -0.416412353515625 -0.031158447265625 -0.9250366210937526 +1.332125 -0.416412353515625 -0.031158447265625 -0.9250366210937526 +1.33225 -0.419281005859375 -0.0313720703125 -0.9250366210937526 +1.332375 -0.422119140625 -0.031585693359375 -0.9250366210937526 +1.3325 -0.422119140625 -0.031585693359375 -0.9250366210937526 +1.332625 -0.424896240234375 -0.03179931640625 -0.9250366210937526 +1.33275 -0.424896240234375 -0.03179931640625 -0.9250366210937526 +1.332875 -0.4276123046875 -0.032012939453125 -0.9250366210937526 +1.333 -0.4302978515625 -0.032196044921875 -0.9250366210937526 +1.3331250000000002 -0.4302978515625 -0.032196044921875 -0.9250366210937526 +1.33325 -0.432952880859375 -0.03240966796875 -0.9250366210937526 +1.333375 -0.432952880859375 -0.03240966796875 -0.9250366210937526 +1.3335000000000002 -0.435546875 -0.0325927734375 -0.9250366210937526 +1.333625 -0.438079833984375 -0.03277587890625 -0.9250366210937526 +1.33375 -0.438079833984375 -0.03277587890625 -0.9250366210937526 +1.333875 -0.440582275390625 -0.032958984375 -0.9250366210937526 +1.334 -0.440582275390625 -0.032958984375 -0.9250366210937526 +1.334125 -0.44305419921875 -0.03314208984375 -0.9250366210937526 +1.33425 -0.4454345703125 -0.0333251953125 -0.9250366210937526 +1.334375 -0.4454345703125 -0.0333251953125 -0.9250366210937526 +1.3345 -0.447784423828125 -0.03350830078125 -0.9250366210937526 +1.334625 -0.447784423828125 -0.03350830078125 -0.9250366210937526 +1.33475 -0.450103759765625 -0.03369140625 -0.9250366210937526 +1.334875 -0.452362060546875 -0.033843994140625 -0.9250366210937526 +1.335 -0.452362060546875 -0.033843994140625 -0.9250366210937526 +1.3351250000000002 -0.454559326171875 -0.034027099609375 -0.9250366210937526 +1.33525 -0.454559326171875 -0.034027099609375 -0.9250366210937526 +1.335375 -0.45672607421875 -0.0341796875 -0.9250366210937526 +1.3355000000000002 -0.458831787109375 -0.034332275390625 -0.9250366210937526 +1.335625 -0.458831787109375 -0.034332275390625 -0.9250366210937526 +1.33575 -0.46087646484375 -0.03448486328125 -0.9250366210937526 +1.335875 -0.46087646484375 -0.03448486328125 -0.9250366210937526 +1.336 -0.462890625 -0.034637451171875 -0.9250366210937526 +1.336125 -0.464813232421875 -0.0347900390625 -0.9250366210937526 +1.33625 -0.464813232421875 -0.0347900390625 -0.9250366210937526 +1.336375 -0.46673583984375 -0.034912109375 -0.9250366210937526 +1.3365 -0.46673583984375 -0.034912109375 -0.9250366210937526 +1.336625 -0.46856689453125 -0.035064697265625 -0.9250366210937526 +1.33675 -0.470367431640625 -0.035186767578125 -0.9250366210937526 +1.336875 -0.470367431640625 -0.035186767578125 -0.9250366210937526 +1.337 -0.472137451171875 -0.03533935546875 -0.9250366210937526 +1.3371250000000002 -0.472137451171875 -0.03533935546875 -0.9250366210937526 +1.33725 -0.47381591796875 -0.03546142578125 -0.9250366210937526 +1.337375 -0.4754638671875 -0.03558349609375 -0.9250366210937526 +1.3375000000000002 -0.4754638671875 -0.03558349609375 -0.9250366210937526 +1.337625 -0.47705078125 -0.03570556640625 -0.9250366210937526 +1.33775 -0.47705078125 -0.03570556640625 -0.9250366210937526 +1.337875 -0.478607177734375 -0.03582763671875 -0.9250366210937526 +1.338 -0.480072021484375 -0.035919189453125 -0.9250366210937526 +1.338125 -0.480072021484375 -0.035919189453125 -0.9250366210937526 +1.33825 -0.48150634765625 -0.036041259765625 -0.9250366210937526 +1.338375 -0.48150634765625 -0.036041259765625 -0.9250366210937526 +1.3385 -0.48291015625 -0.0361328125 -0.9250366210937526 +1.338625 -0.484222412109375 -0.036224365234375 -0.9250366210937526 +1.33875 -0.484222412109375 -0.036224365234375 -0.9250366210937526 +1.338875 -0.485504150390625 -0.036346435546875 -0.9250366210937526 +1.339 -0.485504150390625 -0.036346435546875 -0.9250366210937526 +1.3391250000000002 -0.486724853515625 -0.03643798828125 -0.9250366210937526 +1.33925 -0.487884521484375 -0.0364990234375 -0.9250366210937526 +1.339375 -0.487884521484375 -0.0364990234375 -0.9250366210937526 +1.3395000000000002 -0.489013671875 -0.036590576171875 -0.9250366210937526 +1.339625 -0.489013671875 -0.036590576171875 -0.9250366210937526 +1.33975 -0.490081787109375 -0.03668212890625 -0.9250366210937526 +1.339875 -0.4910888671875 -0.0367431640625 -0.9250366210937526 +1.34 -0.4910888671875 -0.0367431640625 -0.9250366210937526 +1.340125 -0.492034912109375 -0.036834716796875 -0.9250366210937526 +1.34025 -0.492034912109375 -0.036834716796875 -0.9250366210937526 +1.340375 -0.492950439453125 -0.036895751953125 -0.9250366210937526 +1.3405 -0.4937744140625 -0.036956787109375 -0.9250366210937526 +1.340625 -0.4937744140625 -0.036956787109375 -0.9250366210937526 +1.34075 -0.49456787109375 -0.037017822265625 -0.9250366210937526 +1.340875 -0.49456787109375 -0.037017822265625 -0.9250366210937526 +1.341 -0.49530029296875 -0.037078857421875 -0.9250366210937526 +1.3411250000000002 -0.496002197265625 -0.037109375 -0.9250366210937526 +1.34125 -0.496002197265625 -0.037109375 -0.9250366210937526 +1.341375 -0.496612548828125 -0.03717041015625 -0.9250366210937526 +1.3415000000000002 -0.496612548828125 -0.03717041015625 -0.9250366210937526 +1.341625 -0.4971923828125 -0.037200927734375 -0.9250366210937526 +1.34175 -0.497711181640625 -0.0372314453125 -0.9250366210937526 +1.341875 -0.497711181640625 -0.0372314453125 -0.9250366210937526 +1.342 -0.498199462890625 -0.03729248046875 -0.9250366210937526 +1.342125 -0.498199462890625 -0.03729248046875 -0.9250366210937526 +1.34225 -0.49859619140625 -0.037322998046875 -0.9250366210937526 +1.342375 -0.49896240234375 -0.037353515625 -0.9250366210937526 +1.3425 -0.49896240234375 -0.037353515625 -0.9250366210937526 +1.342625 -0.499267578125 -0.037353515625 -0.9250366210937526 +1.34275 -0.499267578125 -0.037353515625 -0.9250366210937526 +1.342875 -0.49951171875 -0.037384033203125 -0.9250366210937526 +1.343 -0.49969482421875 -0.037384033203125 -0.9250366210937526 +1.3431250000000002 -0.49969482421875 -0.037384033203125 -0.9250366210937526 +1.34325 -0.49981689453125 -0.03741455078125 -0.9250366210937526 +1.343375 -0.49981689453125 -0.03741455078125 -0.9250366210937526 +1.3435000000000002 -0.499908447265625 -0.03741455078125 -0.9250366210937526 +1.343625 -0.49993896484375 -0.03741455078125 -0.9250366210937526 +1.34375 -0.49993896484375 -0.03741455078125 -0.9250366210937526 +1.343875 -0.499908447265625 -0.03741455078125 -0.9250366210937526 +1.344 -0.499908447265625 0.0 -0.99987182617187488 +1.344125 -0.49981689453125 0.0 -0.99987182617187488 +1.34425 -0.49969482421875 0.0 -0.99987182617187488 +1.344375 -0.49969482421875 0.0 -0.99987182617187488 +1.3445 -0.49951171875 0.0 -0.99987182617187488 +1.344625 -0.49951171875 0.0 -0.99987182617187488 +1.3447500000000002 -0.499267578125 0.0 -0.99987182617187488 +1.344875 -0.49896240234375 0.0 -0.99987182617187488 +1.345 -0.49896240234375 0.0 -0.99987182617187488 +1.3451250000000002 -0.49859619140625 0.0 -0.99987182617187488 +1.34525 -0.49859619140625 0.0 -0.99987182617187488 +1.345375 -0.498199462890625 0.0 -0.99987182617187488 +1.3455 -0.497711181640625 0.0 -0.99987182617187488 +1.345625 -0.497711181640625 0.0 -0.99987182617187488 +1.34575 -0.4971923828125 0.0 -0.99987182617187488 +1.345875 -0.4971923828125 0.0 -0.99987182617187488 +1.346 -0.496612548828125 0.0 -0.99987182617187488 +1.346125 -0.496002197265625 0.0 -0.99987182617187488 +1.34625 -0.496002197265625 0.0 -0.99987182617187488 +1.346375 -0.49530029296875 0.0 -0.99987182617187488 +1.3465 -0.49530029296875 0.0 -0.99987182617187488 +1.346625 -0.49456787109375 0.0 -0.99987182617187488 +1.3467500000000002 -0.4937744140625 0.0 -0.99987182617187488 +1.346875 -0.4937744140625 0.0 -0.99987182617187488 +1.347 -0.492950439453125 0.0 -0.99987182617187488 +1.3471250000000002 -0.492950439453125 0.0 -0.99987182617187488 +1.34725 -0.492034912109375 0.0 -0.99987182617187488 +1.347375 -0.4910888671875 0.0 -0.99987182617187488 +1.3475 -0.4910888671875 0.0 -0.99987182617187488 +1.347625 -0.490081787109375 0.0 -0.99987182617187488 +1.34775 -0.490081787109375 0.0 -0.99987182617187488 +1.347875 -0.489013671875 0.0 -0.99987182617187488 +1.348 -0.487884521484375 0.0 -0.99987182617187488 +1.348125 -0.487884521484375 0.0 -0.99987182617187488 +1.34825 -0.486724853515625 0.0 -0.99987182617187488 +1.348375 -0.486724853515625 0.0 -0.99987182617187488 +1.3485 -0.485504150390625 0.0 -0.99987182617187488 +1.348625 -0.484222412109375 0.0 -0.99987182617187488 +1.3487500000000002 -0.484222412109375 0.0 -0.99987182617187488 +1.348875 -0.48291015625 0.0 -0.99987182617187488 +1.349 -0.48291015625 0.0 -0.99987182617187488 +1.3491250000000002 -0.48150634765625 0.0 -0.99987182617187488 +1.34925 -0.480072021484375 0.0 -0.99987182617187488 +1.349375 -0.480072021484375 0.0 -0.99987182617187488 +1.3495 -0.478607177734375 0.0 -0.99987182617187488 +1.349625 -0.478607177734375 0.0 -0.99987182617187488 +1.34975 -0.47705078125 0.0 -0.99987182617187488 +1.349875 -0.4754638671875 0.0 -0.99987182617187488 +1.35 -0.4754638671875 0.0 -0.99987182617187488 +1.350125 -0.47381591796875 0.0 -0.99987182617187488 +1.35025 -0.47381591796875 0.0 -0.99987182617187488 +1.350375 -0.472137451171875 0.0 -0.99987182617187488 +1.3505 -0.470367431640625 0.0 -0.99987182617187488 +1.350625 -0.470367431640625 0.0 -0.99987182617187488 +1.3507500000000002 -0.46856689453125 0.0 -0.99987182617187488 +1.350875 -0.46856689453125 0.0 -0.99987182617187488 +1.351 -0.46673583984375 0.0 -0.99987182617187488 +1.3511250000000002 -0.464813232421875 0.0 -0.99987182617187488 +1.35125 -0.464813232421875 0.0 -0.99987182617187488 +1.351375 -0.462890625 0.0 -0.99987182617187488 +1.3515 -0.462890625 0.0 -0.99987182617187488 +1.351625 -0.46087646484375 0.0 -0.99987182617187488 +1.35175 -0.458831787109375 0.0 -0.99987182617187488 +1.351875 -0.458831787109375 0.0 -0.99987182617187488 +1.352 -0.45672607421875 0.0 -0.99987182617187488 +1.352125 -0.45672607421875 0.0 -0.99987182617187488 +1.35225 -0.454559326171875 0.0 -0.99987182617187488 +1.352375 -0.452362060546875 0.0 -0.99987182617187488 +1.3525 -0.452362060546875 0.0 -0.99987182617187488 +1.352625 -0.450103759765625 0.0 -0.99987182617187488 +1.3527500000000002 -0.450103759765625 0.0 -0.99987182617187488 +1.352875 -0.447784423828125 0.0 -0.99987182617187488 +1.353 -0.4454345703125 0.0 -0.99987182617187488 +1.3531250000000002 -0.4454345703125 0.0 -0.99987182617187488 +1.35325 -0.44305419921875 0.0 -0.99987182617187488 +1.353375 -0.44305419921875 0.0 -0.99987182617187488 +1.3535 -0.440582275390625 0.0 -0.99987182617187488 +1.353625 -0.438079833984375 0.0 -0.99987182617187488 +1.35375 -0.438079833984375 0.0 -0.99987182617187488 +1.353875 -0.435546875 0.0 -0.99987182617187488 +1.354 -0.435546875 0.0 -0.99987182617187488 +1.354125 -0.432952880859375 0.0 -0.99987182617187488 +1.35425 -0.4302978515625 0.0 -0.99987182617187488 +1.354375 -0.4302978515625 0.0 -0.99987182617187488 +1.3545 -0.4276123046875 0.0 -0.99987182617187488 +1.354625 -0.4276123046875 0.0 -0.99987182617187488 +1.3547500000000002 -0.424896240234375 0.0 -0.99987182617187488 +1.354875 -0.422119140625 0.0 -0.99987182617187488 +1.355 -0.422119140625 0.0 -0.99987182617187488 +1.3551250000000002 -0.419281005859375 0.0 -0.99987182617187488 +1.35525 -0.419281005859375 0.0 -0.99987182617187488 +1.355375 -0.416412353515625 0.0 -0.99987182617187488 +1.3555 -0.413482666015625 0.0 -0.99987182617187488 +1.355625 -0.413482666015625 0.0 -0.99987182617187488 +1.35575 -0.4105224609375 0.0 -0.99987182617187488 +1.355875 -0.4105224609375 0.0 -0.99987182617187488 +1.356 -0.407501220703125 0.0 -0.99987182617187488 +1.356125 -0.404449462890625 0.0 -0.99987182617187488 +1.35625 -0.404449462890625 0.0 -0.99987182617187488 +1.356375 -0.401336669921875 0.0 -0.99987182617187488 +1.3565 -0.401336669921875 0.0 -0.99987182617187488 +1.356625 -0.398193359375 0.0 -0.99987182617187488 +1.3567500000000002 -0.39501953125 0.0 -0.99987182617187488 +1.356875 -0.39501953125 0.0 -0.99987182617187488 +1.357 -0.39178466796875 0.0 -0.99987182617187488 +1.3571250000000002 -0.39178466796875 0.0 -0.99987182617187488 +1.35725 -0.388519287109375 0.0 -0.99987182617187488 +1.357375 -0.38519287109375 0.0 -0.99987182617187488 +1.3575 -0.38519287109375 0.0 -0.99987182617187488 +1.357625 -0.3818359375 0.0 -0.99987182617187488 +1.35775 -0.3818359375 0.0 -0.99987182617187488 +1.357875 -0.378448486328125 0.0 -0.99987182617187488 +1.358 -0.375 0.0 -0.99987182617187488 +1.358125 -0.375 0.0 -0.99987182617187488 +1.35825 -0.37152099609375 0.0 -0.99987182617187488 +1.358375 -0.37152099609375 0.0 -0.99987182617187488 +1.3585 -0.36798095703125 0.0 -0.99987182617187488 +1.358625 -0.36444091796875 0.0 -0.99987182617187488 +1.3587500000000002 -0.36444091796875 0.0 -0.99987182617187488 +1.358875 -0.360809326171875 0.0 -0.99987182617187488 +1.359 -0.360809326171875 0.0 -0.99987182617187488 +1.3591250000000002 -0.357177734375 0.0 -0.99987182617187488 +1.35925 -0.353485107421875 0.0 -0.99987182617187488 +1.359375 -0.353485107421875 0.0 -0.99987182617187488 +1.3595 -0.349761962890625 0.0 -0.99987182617187488 +1.359625 -0.349761962890625 0.0 -0.99987182617187488 +1.35975 -0.34600830078125 0.0 -0.99987182617187488 +1.359875 -0.34222412109375 0.0 -0.99987182617187488 +1.36 -0.34222412109375 0.0 -0.99987182617187488 +1.360125 -0.33837890625 0.0 -0.99987182617187488 +1.36025 -0.33837890625 0.0 -0.99987182617187488 +1.3603750000000002 -0.334503173828125 0.0 -0.99987182617187488 +1.3605 -0.330596923828125 0.0 -0.99987182617187488 +1.360625 -0.330596923828125 0.0 -0.99987182617187488 +1.3607500000000002 -0.32666015625 0.0 -0.99987182617187488 +1.360875 -0.32666015625 0.0 -0.99987182617187488 +1.361 -0.322662353515625 0.0 -0.99987182617187488 +1.361125 -0.31866455078125 0.0 -0.99987182617187488 +1.36125 -0.31866455078125 0.0 -0.99987182617187488 +1.361375 -0.314605712890625 0.0 -0.99987182617187488 +1.3615 -0.314605712890625 0.0 -0.99987182617187488 +1.361625 -0.310516357421875 0.0 -0.99987182617187488 +1.36175 -0.306396484375 0.0 -0.99987182617187488 +1.361875 -0.306396484375 0.0 -0.99987182617187488 +1.362 -0.30224609375 0.0 -0.99987182617187488 +1.362125 -0.30224609375 0.0 -0.99987182617187488 +1.36225 -0.298065185546875 0.0 -0.99987182617187488 +1.3623750000000002 -0.2938232421875 0.0 -0.99987182617187488 +1.3625 -0.2938232421875 0.0 -0.99987182617187488 +1.362625 -0.289581298828125 0.0 -0.99987182617187488 +1.3627500000000002 -0.289581298828125 0.0 -0.99987182617187488 +1.362875 -0.285308837890625 0.0 -0.99987182617187488 +1.363 -0.280975341796875 0.0 -0.99987182617187488 +1.363125 -0.280975341796875 0.0 -0.99987182617187488 +1.36325 -0.276641845703125 0.0 -0.99987182617187488 +1.363375 -0.276641845703125 0.0 -0.99987182617187488 +1.3635 -0.27227783203125 0.0 -0.99987182617187488 +1.363625 -0.267852783203125 0.0 -0.99987182617187488 +1.36375 -0.267852783203125 0.0 -0.99987182617187488 +1.363875 -0.263427734375 0.0 -0.99987182617187488 +1.364 -0.263427734375 0.0 -0.99987182617187488 +1.364125 -0.25897216796875 0.0 -0.99987182617187488 +1.36425 -0.25445556640625 0.0 -0.99987182617187488 +1.3643750000000002 -0.25445556640625 0.0 -0.99987182617187488 +1.3645 -0.249969482421875 0.0 -0.99987182617187488 +1.364625 -0.249969482421875 0.0 -0.99987182617187488 +1.3647500000000002 -0.24542236328125 0.0 -0.99987182617187488 +1.364875 -0.2408447265625 0.0 -0.99987182617187488 +1.365 -0.2408447265625 0.0 -0.99987182617187488 +1.365125 -0.236236572265625 0.0 -0.99987182617187488 +1.36525 -0.236236572265625 0.0 -0.99987182617187488 +1.365375 -0.231597900390625 0.0 -0.99987182617187488 +1.3655 -0.226959228515625 0.0 -0.99987182617187488 +1.365625 -0.226959228515625 0.0 -0.99987182617187488 +1.36575 -0.2222900390625 0.0 -0.99987182617187488 +1.365875 -0.2222900390625 0.0 -0.99987182617187488 +1.366 -0.21759033203125 0.0 -0.99987182617187488 +1.366125 -0.212860107421875 0.0 -0.99987182617187488 +1.36625 -0.212860107421875 0.0 -0.99987182617187488 +1.3663750000000002 -0.208099365234375 0.0 -0.99987182617187488 +1.3665 -0.208099365234375 0.0 -0.99987182617187488 +1.366625 -0.203338623046875 0.0 -0.99987182617187488 +1.3667500000000002 -0.19854736328125 0.0 -0.99987182617187488 +1.366875 -0.19854736328125 0.0 -0.99987182617187488 +1.367 -0.1937255859375 0.0 -0.99987182617187488 +1.367125 -0.1937255859375 0.0 -0.99987182617187488 +1.36725 -0.188873291015625 0.0 -0.99987182617187488 +1.367375 -0.18402099609375 0.0 -0.99987182617187488 +1.3675 -0.18402099609375 0.0 -0.99987182617187488 +1.367625 -0.17913818359375 0.0 -0.99987182617187488 +1.36775 -0.17913818359375 0.0 -0.99987182617187488 +1.367875 -0.17425537109375 0.0 -0.99987182617187488 +1.368 -0.169342041015625 0.0 -0.99987182617187488 +1.368125 -0.169342041015625 0.0 -0.99987182617187488 +1.36825 -0.164398193359375 0.0 -0.99987182617187488 +1.3683750000000002 -0.164398193359375 0.0 -0.99987182617187488 +1.3685 -0.159454345703125 0.0 -0.99987182617187488 +1.368625 -0.15447998046875 0.0 -0.99987182617187488 +1.3687500000000002 -0.15447998046875 0.0 -0.99987182617187488 +1.368875 -0.14947509765625 0.0 -0.99987182617187488 +1.369 -0.14947509765625 0.0 -0.99987182617187488 +1.369125 -0.14447021484375 0.0 -0.99987182617187488 +1.36925 -0.13946533203125 0.0 -0.99987182617187488 +1.369375 -0.13946533203125 0.0 -0.99987182617187488 +1.3695 -0.134429931640625 0.0 -0.99987182617187488 +1.369625 -0.134429931640625 0.0 -0.99987182617187488 +1.36975 -0.129364013671875 0.0 -0.99987182617187488 +1.369875 -0.124298095703125 0.0 -0.99987182617187488 +1.37 -0.124298095703125 0.0 -0.99987182617187488 +1.370125 -0.119232177734375 0.0 -0.99987182617187488 +1.37025 -0.119232177734375 0.0 -0.99987182617187488 +1.3703750000000002 -0.1141357421875 0.0 -0.99987182617187488 +1.3705 -0.109039306640625 0.0 -0.99987182617187488 +1.370625 -0.109039306640625 0.0 -0.99987182617187488 +1.3707500000000002 -0.103912353515625 0.0 -0.99987182617187488 +1.370875 -0.103912353515625 0.0 -0.99987182617187488 +1.371 -0.098785400390625 0.0 -0.99987182617187488 +1.371125 -0.093658447265625 0.0 -0.99987182617187488 +1.37125 -0.093658447265625 0.0 -0.99987182617187488 +1.371375 -0.0885009765625 0.0 -0.99987182617187488 +1.3715 -0.0885009765625 0.0 -0.99987182617187488 +1.371625 -0.083343505859375 0.0 -0.99987182617187488 +1.37175 -0.07818603515625 0.0 -0.99987182617187488 +1.371875 -0.07818603515625 0.0 -0.99987182617187488 +1.372 -0.072998046875 0.0 -0.99987182617187488 +1.372125 -0.072998046875 0.0 -0.99987182617187488 +1.37225 -0.06781005859375 0.0 -0.99987182617187488 +1.3723750000000002 -0.0626220703125 0.0 -0.99987182617187488 +1.3725 -0.0626220703125 0.0 -0.99987182617187488 +1.372625 -0.05743408203125 0.0 -0.99987182617187488 +1.3727500000000002 -0.05743408203125 0.0 -0.99987182617187488 +1.372875 -0.05224609375 0.0 -0.99987182617187488 +1.373 -0.047027587890625 0.0 -0.99987182617187488 +1.373125 -0.047027587890625 0.0 -0.99987182617187488 +1.37325 -0.04180908203125 0.0 -0.99987182617187488 +1.373375 -0.04180908203125 0.0 -0.99987182617187488 +1.3735 -0.036590576171875 0.0 -0.99987182617187488 +1.373625 -0.0313720703125 0.0 -0.99987182617187488 +1.37375 -0.0313720703125 0.0 -0.99987182617187488 +1.373875 -0.026123046875 0.0 -0.99987182617187488 +1.374 -0.026123046875 0.0 -0.99987182617187488 +1.374125 -0.020904541015625 0.0 -0.99987182617187488 +1.37425 -0.01568603515625 0.0 -0.99987182617187488 +1.3743750000000002 -0.01568603515625 0.0 -0.99987182617187488 +1.3745 -0.01043701171875 0.0 -0.99987182617187488 +1.374625 -0.01043701171875 0.0 -0.99987182617187488 +1.3747500000000002 -0.005218505859375 0.0 -0.99987182617187488 +1.374875 0.0 0.0 -0.99987182617187488 +1.375 0.0 0.0 -0.99987182617187488 +1.375125 0.005218505859375 0.0 -0.99987182617187488 +1.37525 0.005218505859375 0.0 -0.99987182617187488 +1.375375 0.01043701171875 0.0 -0.99987182617187488 +1.3755 0.01568603515625 0.0 -0.99987182617187488 +1.375625 0.01568603515625 0.0 -0.99987182617187488 +1.37575 0.020904541015625 0.0 -0.99987182617187488 +1.375875 0.020904541015625 0.0 -0.99987182617187488 +1.3760000000000002 0.026123046875 0.002197265625 -0.915197753906247 +1.376125 0.0313720703125 0.002655029296875 -0.915197753906247 +1.37625 0.0313720703125 0.002655029296875 -0.915197753906247 +1.3763750000000002 0.036590576171875 0.003082275390625 -0.915197753906247 +1.3765 0.036590576171875 0.003082275390625 -0.915197753906247 +1.376625 0.04180908203125 0.0035400390625 -0.915197753906247 +1.37675 0.047027587890625 0.00396728515625 -0.915197753906247 +1.376875 0.047027587890625 0.00396728515625 -0.915197753906247 +1.377 0.05224609375 0.004425048828125 -0.915197753906247 +1.377125 0.05224609375 0.004425048828125 -0.915197753906247 +1.37725 0.05743408203125 0.004852294921875 -0.915197753906247 +1.377375 0.0626220703125 0.005279541015625 -0.915197753906247 +1.3775 0.0626220703125 0.005279541015625 -0.915197753906247 +1.377625 0.06781005859375 0.0057373046875 -0.915197753906247 +1.37775 0.06781005859375 0.0057373046875 -0.915197753906247 +1.377875 0.072998046875 0.00616455078125 -0.915197753906247 +1.3780000000000002 0.07818603515625 0.006622314453125 -0.915197753906247 +1.378125 0.07818603515625 0.006622314453125 -0.915197753906247 +1.37825 0.083343505859375 0.007049560546875 -0.915197753906247 +1.3783750000000002 0.083343505859375 0.007049560546875 -0.915197753906247 +1.3785 0.0885009765625 0.007476806640625 -0.915197753906247 +1.378625 0.093658447265625 0.0079345703125 -0.915197753906247 +1.37875 0.093658447265625 0.0079345703125 -0.915197753906247 +1.378875 0.098785400390625 0.00836181640625 -0.915197753906247 +1.379 0.098785400390625 0.00836181640625 -0.915197753906247 +1.379125 0.103912353515625 0.0087890625 -0.915197753906247 +1.37925 0.109039306640625 0.00921630859375 -0.915197753906247 +1.379375 0.109039306640625 0.00921630859375 -0.915197753906247 +1.3795 0.1141357421875 0.0096435546875 -0.915197753906247 +1.379625 0.1141357421875 0.0096435546875 -0.915197753906247 +1.37975 0.119232177734375 0.010101318359375 -0.915197753906247 +1.379875 0.124298095703125 0.010528564453125 -0.915197753906247 +1.3800000000000002 0.124298095703125 0.010528564453125 -0.915197753906247 +1.380125 0.129364013671875 0.010955810546875 -0.915197753906247 +1.38025 0.129364013671875 0.010955810546875 -0.915197753906247 +1.3803750000000002 0.134429931640625 0.011383056640625 -0.915197753906247 +1.3805 0.13946533203125 0.011810302734375 -0.915197753906247 +1.380625 0.13946533203125 0.011810302734375 -0.915197753906247 +1.38075 0.14447021484375 0.012237548828125 -0.915197753906247 +1.380875 0.14447021484375 0.012237548828125 -0.915197753906247 +1.381 0.14947509765625 0.012664794921875 -0.915197753906247 +1.381125 0.15447998046875 0.0130615234375 -0.915197753906247 +1.38125 0.15447998046875 0.0130615234375 -0.915197753906247 +1.381375 0.159454345703125 0.01348876953125 -0.915197753906247 +1.3815 0.159454345703125 0.01348876953125 -0.915197753906247 +1.381625 0.164398193359375 0.013916015625 -0.915197753906247 +1.38175 0.169342041015625 0.01434326171875 -0.915197753906247 +1.381875 0.169342041015625 0.01434326171875 -0.915197753906247 +1.3820000000000002 0.17425537109375 0.014739990234375 -0.915197753906247 +1.382125 0.17425537109375 0.014739990234375 -0.915197753906247 +1.38225 0.17913818359375 0.015167236328125 -0.915197753906247 +1.3823750000000002 0.18402099609375 0.01556396484375 -0.915197753906247 +1.3825 0.18402099609375 0.01556396484375 -0.915197753906247 +1.382625 0.188873291015625 0.0159912109375 -0.915197753906247 +1.38275 0.188873291015625 0.0159912109375 -0.915197753906247 +1.382875 0.1937255859375 0.016387939453125 -0.915197753906247 +1.383 0.19854736328125 0.016815185546875 -0.915197753906247 +1.383125 0.19854736328125 0.016815185546875 -0.915197753906247 +1.38325 0.203338623046875 0.0172119140625 -0.915197753906247 +1.383375 0.203338623046875 0.0172119140625 -0.915197753906247 +1.3835 0.208099365234375 0.017608642578125 -0.915197753906247 +1.383625 0.212860107421875 0.01800537109375 -0.915197753906247 +1.38375 0.212860107421875 0.01800537109375 -0.915197753906247 +1.383875 0.21759033203125 0.0184326171875 -0.915197753906247 +1.3840000000000002 0.21759033203125 0.0184326171875 -0.915197753906247 +1.384125 0.2222900390625 0.018829345703125 -0.915197753906247 +1.38425 0.226959228515625 0.01922607421875 -0.915197753906247 +1.3843750000000002 0.226959228515625 0.01922607421875 -0.915197753906247 +1.3845 0.231597900390625 0.019622802734375 -0.915197753906247 +1.384625 0.231597900390625 0.019622802734375 -0.915197753906247 +1.38475 0.236236572265625 0.019989013671875 -0.915197753906247 +1.384875 0.2408447265625 0.0203857421875 -0.915197753906247 +1.385 0.2408447265625 0.0203857421875 -0.915197753906247 +1.385125 0.24542236328125 0.020782470703125 -0.915197753906247 +1.38525 0.24542236328125 0.020782470703125 -0.915197753906247 +1.385375 0.249969482421875 0.021148681640625 -0.915197753906247 +1.3855 0.25445556640625 0.02154541015625 -0.915197753906247 +1.385625 0.25445556640625 0.02154541015625 -0.915197753906247 +1.38575 0.25897216796875 0.02191162109375 -0.915197753906247 +1.385875 0.25897216796875 0.02191162109375 -0.915197753906247 +1.3860000000000002 0.263427734375 0.022308349609375 -0.915197753906247 +1.386125 0.267852783203125 0.022674560546875 -0.915197753906247 +1.38625 0.267852783203125 0.022674560546875 -0.915197753906247 +1.3863750000000002 0.27227783203125 0.023040771484375 -0.915197753906247 +1.3865 0.27227783203125 0.023040771484375 -0.915197753906247 +1.386625 0.276641845703125 0.0234375 -0.915197753906247 +1.38675 0.280975341796875 0.0238037109375 -0.915197753906247 +1.386875 0.280975341796875 0.0238037109375 -0.915197753906247 +1.387 0.285308837890625 0.024169921875 -0.915197753906247 +1.387125 0.285308837890625 0.024169921875 -0.915197753906247 +1.38725 0.289581298828125 0.0245361328125 -0.915197753906247 +1.387375 0.2938232421875 0.024871826171875 -0.915197753906247 +1.3875 0.2938232421875 0.024871826171875 -0.915197753906247 +1.387625 0.298065185546875 0.025238037109375 -0.915197753906247 +1.38775 0.298065185546875 0.025238037109375 -0.915197753906247 +1.387875 0.30224609375 0.025604248046875 -0.915197753906247 +1.3880000000000002 0.306396484375 0.02593994140625 -0.915197753906247 +1.388125 0.306396484375 0.02593994140625 -0.915197753906247 +1.38825 0.310516357421875 0.02630615234375 -0.915197753906247 +1.3883750000000002 0.310516357421875 0.02630615234375 -0.915197753906247 +1.3885 0.314605712890625 0.026641845703125 -0.915197753906247 +1.388625 0.31866455078125 0.0269775390625 -0.915197753906247 +1.38875 0.31866455078125 0.0269775390625 -0.915197753906247 +1.388875 0.322662353515625 0.027313232421875 -0.915197753906247 +1.389 0.322662353515625 0.027313232421875 -0.915197753906247 +1.389125 0.32666015625 0.02764892578125 -0.915197753906247 +1.38925 0.330596923828125 0.027984619140625 -0.915197753906247 +1.389375 0.330596923828125 0.027984619140625 -0.915197753906247 +1.3895 0.334503173828125 0.0283203125 -0.915197753906247 +1.389625 0.334503173828125 0.0283203125 -0.915197753906247 +1.38975 0.33837890625 0.028656005859375 -0.915197753906247 +1.389875 0.34222412109375 0.02899169921875 -0.915197753906247 +1.3900000000000002 0.34222412109375 0.02899169921875 -0.915197753906247 +1.390125 0.34600830078125 0.029296875 -0.915197753906247 +1.39025 0.34600830078125 0.029296875 -0.915197753906247 +1.3903750000000002 0.349761962890625 0.029632568359375 -0.915197753906247 +1.3905 0.353485107421875 0.029937744140625 -0.915197753906247 +1.390625 0.353485107421875 0.029937744140625 -0.915197753906247 +1.39075 0.357177734375 0.030242919921875 -0.915197753906247 +1.390875 0.357177734375 0.030242919921875 -0.915197753906247 +1.391 0.360809326171875 0.030548095703125 -0.915197753906247 +1.391125 0.36444091796875 0.030853271484375 -0.915197753906247 +1.39125 0.36444091796875 0.030853271484375 -0.915197753906247 +1.391375 0.36798095703125 0.031158447265625 -0.915197753906247 +1.3915 0.36798095703125 0.031158447265625 -0.915197753906247 +1.3916250000000002 0.37152099609375 0.031463623046875 -0.915197753906247 +1.39175 0.375 0.031768798828125 -0.915197753906247 +1.391875 0.375 0.031768798828125 -0.915197753906247 +1.3920000000000002 0.378448486328125 0.03204345703125 -0.915197753906247 +1.392125 0.378448486328125 0.03204345703125 -0.915197753906247 +1.39225 0.3818359375 0.0323486328125 -0.915197753906247 +1.392375 0.38519287109375 0.032623291015625 -0.915197753906247 +1.3925 0.38519287109375 0.032623291015625 -0.915197753906247 +1.392625 0.388519287109375 0.03289794921875 -0.915197753906247 +1.39275 0.388519287109375 0.03289794921875 -0.915197753906247 +1.392875 0.39178466796875 0.033172607421875 -0.915197753906247 +1.393 0.39501953125 0.033447265625 -0.915197753906247 +1.393125 0.39501953125 0.033447265625 -0.915197753906247 +1.39325 0.398193359375 0.033721923828125 -0.915197753906247 +1.393375 0.398193359375 0.033721923828125 -0.915197753906247 +1.3935 0.401336669921875 0.03399658203125 -0.915197753906247 +1.3936250000000002 0.404449462890625 0.03424072265625 -0.915197753906247 +1.39375 0.404449462890625 0.03424072265625 -0.915197753906247 +1.393875 0.407501220703125 0.034515380859375 -0.915197753906247 +1.3940000000000002 0.407501220703125 0.034515380859375 -0.915197753906247 +1.394125 0.4105224609375 0.034759521484375 -0.915197753906247 +1.39425 0.413482666015625 0.035003662109375 -0.915197753906247 +1.394375 0.413482666015625 0.035003662109375 -0.915197753906247 +1.3945 0.416412353515625 0.0352783203125 -0.915197753906247 +1.394625 0.416412353515625 0.0352783203125 -0.915197753906247 +1.39475 0.419281005859375 0.0355224609375 -0.915197753906247 +1.394875 0.422119140625 0.035736083984375 -0.915197753906247 +1.395 0.422119140625 0.035736083984375 -0.915197753906247 +1.395125 0.424896240234375 0.035980224609375 -0.915197753906247 +1.39525 0.424896240234375 0.035980224609375 -0.915197753906247 +1.395375 0.4276123046875 0.036224365234375 -0.915197753906247 +1.3955 0.4302978515625 0.03643798828125 -0.915197753906247 +1.3956250000000002 0.4302978515625 0.03643798828125 -0.915197753906247 +1.39575 0.432952880859375 0.03668212890625 -0.915197753906247 +1.395875 0.432952880859375 0.03668212890625 -0.915197753906247 +1.3960000000000002 0.435546875 0.036895751953125 -0.915197753906247 +1.396125 0.438079833984375 0.037109375 -0.915197753906247 +1.39625 0.438079833984375 0.037109375 -0.915197753906247 +1.396375 0.440582275390625 0.037322998046875 -0.915197753906247 +1.3965 0.440582275390625 0.037322998046875 -0.915197753906247 +1.396625 0.44305419921875 0.03753662109375 -0.915197753906247 +1.39675 0.4454345703125 0.0377197265625 -0.915197753906247 +1.396875 0.4454345703125 0.0377197265625 -0.915197753906247 +1.397 0.447784423828125 0.037933349609375 -0.915197753906247 +1.397125 0.447784423828125 0.037933349609375 -0.915197753906247 +1.39725 0.450103759765625 0.038116455078125 -0.915197753906247 +1.397375 0.452362060546875 0.038299560546875 -0.915197753906247 +1.3975 0.452362060546875 0.038299560546875 -0.915197753906247 +1.3976250000000002 0.454559326171875 0.038482666015625 -0.915197753906247 +1.39775 0.454559326171875 0.038482666015625 -0.915197753906247 +1.397875 0.45672607421875 0.038665771484375 -0.915197753906247 +1.3980000000000002 0.458831787109375 0.038848876953125 -0.915197753906247 +1.398125 0.458831787109375 0.038848876953125 -0.915197753906247 +1.39825 0.46087646484375 0.039031982421875 -0.915197753906247 +1.398375 0.46087646484375 0.039031982421875 -0.915197753906247 +1.3985 0.462890625 0.039215087890625 -0.915197753906247 +1.398625 0.464813232421875 0.03936767578125 -0.915197753906247 +1.39875 0.464813232421875 0.03936767578125 -0.915197753906247 +1.398875 0.46673583984375 0.039520263671875 -0.915197753906247 +1.399 0.46673583984375 0.039520263671875 -0.915197753906247 +1.399125 0.46856689453125 0.0396728515625 -0.915197753906247 +1.39925 0.470367431640625 0.039825439453125 -0.915197753906247 +1.399375 0.470367431640625 0.039825439453125 -0.915197753906247 +1.3995 0.472137451171875 0.03997802734375 -0.915197753906247 +1.3996250000000002 0.472137451171875 0.03997802734375 -0.915197753906247 +1.39975 0.47381591796875 0.040130615234375 -0.915197753906247 +1.399875 0.4754638671875 0.040283203125 -0.915197753906247 +1.4000000000000002 0.4754638671875 0.040283203125 -0.915197753906247 +1.400125 0.47705078125 0.0404052734375 -0.915197753906247 +1.40025 0.47705078125 0.0404052734375 -0.915197753906247 +1.400375 0.478607177734375 0.04052734375 -0.915197753906247 +1.4005 0.480072021484375 0.0406494140625 -0.915197753906247 +1.400625 0.480072021484375 0.0406494140625 -0.915197753906247 +1.40075 0.48150634765625 0.040771484375 -0.915197753906247 +1.400875 0.48150634765625 0.040771484375 -0.915197753906247 +1.401 0.48291015625 0.0408935546875 -0.915197753906247 +1.401125 0.484222412109375 0.041015625 -0.915197753906247 +1.40125 0.484222412109375 0.041015625 -0.915197753906247 +1.401375 0.485504150390625 0.041107177734375 -0.915197753906247 +1.4015 0.485504150390625 0.041107177734375 -0.915197753906247 +1.4016250000000002 0.486724853515625 0.041229248046875 -0.915197753906247 +1.40175 0.487884521484375 0.04132080078125 -0.915197753906247 +1.401875 0.487884521484375 0.04132080078125 -0.915197753906247 +1.4020000000000002 0.489013671875 0.041412353515625 -0.915197753906247 +1.402125 0.489013671875 0.041412353515625 -0.915197753906247 +1.40225 0.490081787109375 0.04150390625 -0.915197753906247 +1.402375 0.4910888671875 0.041595458984375 -0.915197753906247 +1.4025 0.4910888671875 0.041595458984375 -0.915197753906247 +1.402625 0.492034912109375 0.04168701171875 -0.915197753906247 +1.40275 0.492034912109375 0.04168701171875 -0.915197753906247 +1.402875 0.492950439453125 0.041748046875 -0.915197753906247 +1.403 0.4937744140625 0.04180908203125 -0.915197753906247 +1.403125 0.4937744140625 0.04180908203125 -0.915197753906247 +1.40325 0.49456787109375 0.041900634765625 -0.915197753906247 +1.403375 0.49456787109375 0.041900634765625 -0.915197753906247 +1.4035 0.49530029296875 0.041961669921875 -0.915197753906247 +1.4036250000000002 0.496002197265625 0.0419921875 -0.915197753906247 +1.40375 0.496002197265625 0.0419921875 -0.915197753906247 +1.403875 0.496612548828125 0.04205322265625 -0.915197753906247 +1.4040000000000002 0.496612548828125 0.04205322265625 -0.915197753906247 +1.404125 0.4971923828125 0.0421142578125 -0.915197753906247 +1.40425 0.497711181640625 0.042144775390625 -0.915197753906247 +1.404375 0.497711181640625 0.042144775390625 -0.915197753906247 +1.4045 0.498199462890625 0.042205810546875 -0.915197753906247 +1.404625 0.498199462890625 0.042205810546875 -0.915197753906247 +1.40475 0.49859619140625 0.042236328125 -0.915197753906247 +1.404875 0.49896240234375 0.042266845703125 -0.915197753906247 +1.405 0.49896240234375 0.042266845703125 -0.915197753906247 +1.405125 0.499267578125 0.04229736328125 -0.915197753906247 +1.40525 0.499267578125 0.04229736328125 -0.915197753906247 +1.405375 0.49951171875 0.04229736328125 -0.915197753906247 +1.4055 0.49969482421875 0.042327880859375 -0.915197753906247 +1.4056250000000002 0.49969482421875 0.042327880859375 -0.915197753906247 +1.40575 0.49981689453125 0.042327880859375 -0.915197753906247 +1.405875 0.49981689453125 0.042327880859375 -0.915197753906247 +1.4060000000000002 0.499908447265625 0.042327880859375 -0.915197753906247 +1.406125 0.49993896484375 0.042327880859375 -0.915197753906247 +1.40625 0.49993896484375 0.042327880859375 -0.915197753906247 +1.406375 0.499908447265625 0.042327880859375 -0.915197753906247 +1.4065 0.499908447265625 0.042327880859375 -0.915197753906247 +1.406625 0.49981689453125 0.042327880859375 -0.915197753906247 +1.40675 0.49969482421875 0.042327880859375 -0.915197753906247 +1.406875 0.49969482421875 0.042327880859375 -0.915197753906247 +1.407 0.49951171875 0.04229736328125 -0.915197753906247 +1.407125 0.49951171875 0.04229736328125 -0.915197753906247 +1.4072500000000002 0.499267578125 0.04229736328125 -0.915197753906247 +1.407375 0.49896240234375 0.042266845703125 -0.915197753906247 +1.4075 0.49896240234375 0.042266845703125 -0.915197753906247 +1.4076250000000002 0.49859619140625 0.042236328125 -0.915197753906247 +1.40775 0.49859619140625 0.042236328125 -0.915197753906247 +1.407875 0.498199462890625 0.042205810546875 -0.915197753906247 +1.408 0.497711181640625 0.156982421875 -0.6845092773437448 +1.408125 0.497711181640625 0.156982421875 -0.6845092773437448 +1.40825 0.4971923828125 0.15679931640625 -0.6845092773437448 +1.408375 0.4971923828125 0.15679931640625 -0.6845092773437448 +1.4085 0.496612548828125 0.1566162109375 -0.6845092773437448 +1.408625 0.496002197265625 0.15643310546875 -0.6845092773437448 +1.40875 0.496002197265625 0.15643310546875 -0.6845092773437448 +1.408875 0.49530029296875 0.156219482421875 -0.6845092773437448 +1.409 0.49530029296875 0.156219482421875 -0.6845092773437448 +1.409125 0.49456787109375 0.155975341796875 -0.6845092773437448 +1.4092500000000002 0.4937744140625 0.155731201171875 -0.6845092773437448 +1.409375 0.4937744140625 0.155731201171875 -0.6845092773437448 +1.4095 0.492950439453125 0.15545654296875 -0.6845092773437448 +1.4096250000000002 0.492950439453125 0.15545654296875 -0.6845092773437448 +1.40975 0.492034912109375 0.155181884765625 -0.6845092773437448 +1.409875 0.4910888671875 0.154876708984375 -0.6845092773437448 +1.41 0.4910888671875 0.154876708984375 -0.6845092773437448 +1.410125 0.490081787109375 0.154571533203125 -0.6845092773437448 +1.41025 0.490081787109375 0.154571533203125 -0.6845092773437448 +1.410375 0.489013671875 0.15423583984375 -0.6845092773437448 +1.4105 0.487884521484375 0.15386962890625 -0.6845092773437448 +1.410625 0.487884521484375 0.15386962890625 -0.6845092773437448 +1.41075 0.486724853515625 0.15350341796875 -0.6845092773437448 +1.410875 0.486724853515625 0.15350341796875 -0.6845092773437448 +1.411 0.485504150390625 0.15313720703125 -0.6845092773437448 +1.411125 0.484222412109375 0.1527099609375 -0.6845092773437448 +1.4112500000000002 0.484222412109375 0.1527099609375 -0.6845092773437448 +1.411375 0.48291015625 0.152313232421875 -0.6845092773437448 +1.4115 0.48291015625 0.152313232421875 -0.6845092773437448 +1.4116250000000002 0.48150634765625 0.15185546875 -0.6845092773437448 +1.41175 0.480072021484375 0.15142822265625 -0.6845092773437448 +1.411875 0.480072021484375 0.15142822265625 -0.6845092773437448 +1.412 0.478607177734375 0.15093994140625 -0.6845092773437448 +1.412125 0.478607177734375 0.15093994140625 -0.6845092773437448 +1.41225 0.47705078125 0.15045166015625 -0.6845092773437448 +1.412375 0.4754638671875 0.14996337890625 -0.6845092773437448 +1.4125 0.4754638671875 0.14996337890625 -0.6845092773437448 +1.412625 0.47381591796875 0.149444580078125 -0.6845092773437448 +1.41275 0.47381591796875 0.149444580078125 -0.6845092773437448 +1.412875 0.472137451171875 0.148895263671875 -0.6845092773437448 +1.413 0.470367431640625 0.148345947265625 -0.6845092773437448 +1.413125 0.470367431640625 0.148345947265625 -0.6845092773437448 +1.4132500000000002 0.46856689453125 0.147796630859375 -0.6845092773437448 +1.413375 0.46856689453125 0.147796630859375 -0.6845092773437448 +1.4135 0.46673583984375 0.147216796875 -0.6845092773437448 +1.4136250000000002 0.464813232421875 0.1466064453125 -0.6845092773437448 +1.41375 0.464813232421875 0.1466064453125 -0.6845092773437448 +1.413875 0.462890625 0.14599609375 -0.6845092773437448 +1.414 0.462890625 0.14599609375 -0.6845092773437448 +1.414125 0.46087646484375 0.145355224609375 -0.6845092773437448 +1.41425 0.458831787109375 0.14471435546875 -0.6845092773437448 +1.414375 0.458831787109375 0.14471435546875 -0.6845092773437448 +1.4145 0.45672607421875 0.14404296875 -0.6845092773437448 +1.414625 0.45672607421875 0.14404296875 -0.6845092773437448 +1.41475 0.454559326171875 0.14337158203125 -0.6845092773437448 +1.414875 0.452362060546875 0.142669677734375 -0.6845092773437448 +1.415 0.452362060546875 0.142669677734375 -0.6845092773437448 +1.415125 0.450103759765625 0.1419677734375 -0.6845092773437448 +1.4152500000000002 0.450103759765625 0.1419677734375 -0.6845092773437448 +1.415375 0.447784423828125 0.1412353515625 -0.6845092773437448 +1.4155 0.4454345703125 0.1405029296875 -0.6845092773437448 +1.4156250000000002 0.4454345703125 0.1405029296875 -0.6845092773437448 +1.41575 0.44305419921875 0.139739990234375 -0.6845092773437448 +1.415875 0.44305419921875 0.139739990234375 -0.6845092773437448 +1.416 0.440582275390625 0.138946533203125 -0.6845092773437448 +1.416125 0.438079833984375 0.13818359375 -0.6845092773437448 +1.41625 0.438079833984375 0.13818359375 -0.6845092773437448 +1.416375 0.435546875 0.137359619140625 -0.6845092773437448 +1.4165 0.435546875 0.137359619140625 -0.6845092773437448 +1.416625 0.432952880859375 0.136566162109375 -0.6845092773437448 +1.41675 0.4302978515625 0.135711669921875 -0.6845092773437448 +1.416875 0.4302978515625 0.135711669921875 -0.6845092773437448 +1.417 0.4276123046875 0.134857177734375 -0.6845092773437448 +1.417125 0.4276123046875 0.134857177734375 -0.6845092773437448 +1.4172500000000002 0.424896240234375 0.134002685546875 -0.6845092773437448 +1.417375 0.422119140625 0.13311767578125 -0.6845092773437448 +1.4175 0.422119140625 0.13311767578125 -0.6845092773437448 +1.4176250000000002 0.419281005859375 0.132232666015625 -0.6845092773437448 +1.41775 0.419281005859375 0.132232666015625 -0.6845092773437448 +1.417875 0.416412353515625 0.131317138671875 -0.6845092773437448 +1.418 0.413482666015625 0.130401611328125 -0.6845092773437448 +1.418125 0.413482666015625 0.130401611328125 -0.6845092773437448 +1.41825 0.4105224609375 0.129486083984375 -0.6845092773437448 +1.418375 0.4105224609375 0.129486083984375 -0.6845092773437448 +1.4185 0.407501220703125 0.128509521484375 -0.6845092773437448 +1.418625 0.404449462890625 0.1275634765625 -0.6845092773437448 +1.41875 0.404449462890625 0.1275634765625 -0.6845092773437448 +1.418875 0.401336669921875 0.1265869140625 -0.6845092773437448 +1.419 0.401336669921875 0.1265869140625 -0.6845092773437448 +1.419125 0.398193359375 0.125579833984375 -0.6845092773437448 +1.4192500000000002 0.39501953125 0.12457275390625 -0.6845092773437448 +1.419375 0.39501953125 0.12457275390625 -0.6845092773437448 +1.4195 0.39178466796875 0.123565673828125 -0.6845092773437448 +1.4196250000000002 0.39178466796875 0.123565673828125 -0.6845092773437448 +1.41975 0.388519287109375 0.122528076171875 -0.6845092773437448 +1.419875 0.38519287109375 0.121490478515625 -0.6845092773437448 +1.42 0.38519287109375 0.121490478515625 -0.6845092773437448 +1.420125 0.3818359375 0.12042236328125 -0.6845092773437448 +1.42025 0.3818359375 0.12042236328125 -0.6845092773437448 +1.420375 0.378448486328125 0.119354248046875 -0.6845092773437448 +1.4205 0.375 0.118255615234375 -0.6845092773437448 +1.420625 0.375 0.118255615234375 -0.6845092773437448 +1.42075 0.37152099609375 0.117156982421875 -0.6845092773437448 +1.420875 0.37152099609375 0.117156982421875 -0.6845092773437448 +1.421 0.36798095703125 0.116058349609375 -0.6845092773437448 +1.421125 0.36444091796875 0.11492919921875 -0.6845092773437448 +1.4212500000000002 0.36444091796875 0.11492919921875 -0.6845092773437448 +1.421375 0.360809326171875 0.113800048828125 -0.6845092773437448 +1.4215 0.360809326171875 0.113800048828125 -0.6845092773437448 +1.4216250000000002 0.357177734375 0.112640380859375 -0.6845092773437448 +1.42175 0.353485107421875 0.111480712890625 -0.6845092773437448 +1.421875 0.353485107421875 0.111480712890625 -0.6845092773437448 +1.422 0.349761962890625 0.110321044921875 -0.6845092773437448 +1.422125 0.349761962890625 0.110321044921875 -0.6845092773437448 +1.42225 0.34600830078125 0.109130859375 -0.6845092773437448 +1.422375 0.34222412109375 0.107940673828125 -0.6845092773437448 +1.4225 0.34222412109375 0.107940673828125 -0.6845092773437448 +1.422625 0.33837890625 0.106719970703125 -0.6845092773437448 +1.42275 0.33837890625 0.106719970703125 -0.6845092773437448 +1.4228750000000002 0.334503173828125 0.105499267578125 -0.6845092773437448 +1.423 0.330596923828125 0.104278564453125 -0.6845092773437448 +1.423125 0.330596923828125 0.104278564453125 -0.6845092773437448 +1.4232500000000002 0.32666015625 0.10302734375 -0.6845092773437448 +1.423375 0.32666015625 0.10302734375 -0.6845092773437448 +1.4235 0.322662353515625 0.101776123046875 -0.6845092773437448 +1.4236250000000002 0.31866455078125 0.100494384765625 -0.6845092773437448 +1.42375 0.31866455078125 0.100494384765625 -0.6845092773437448 +1.423875 0.314605712890625 0.099212646484375 -0.6845092773437448 +1.424 0.314605712890625 0.099212646484375 -0.6845092773437448 +1.424125 0.310516357421875 0.097930908203125 -0.6845092773437448 +1.42425 0.306396484375 0.096649169921875 -0.6845092773437448 +1.424375 0.306396484375 0.096649169921875 -0.6845092773437448 +1.4245 0.30224609375 0.0953369140625 -0.6845092773437448 +1.424625 0.30224609375 0.0953369140625 -0.6845092773437448 +1.42475 0.298065185546875 0.093994140625 -0.6845092773437448 +1.4248750000000002 0.2938232421875 0.092681884765625 -0.6845092773437448 +1.425 0.2938232421875 0.092681884765625 -0.6845092773437448 +1.425125 0.289581298828125 0.091339111328125 -0.6845092773437448 +1.4252500000000002 0.289581298828125 0.091339111328125 -0.6845092773437448 +1.425375 0.285308837890625 0.0899658203125 -0.6845092773437448 +1.4255 0.280975341796875 0.088623046875 -0.6845092773437448 +1.425625 0.280975341796875 0.088623046875 -0.6845092773437448 +1.42575 0.276641845703125 0.087249755859375 -0.6845092773437448 +1.425875 0.276641845703125 0.087249755859375 -0.6845092773437448 +1.426 0.27227783203125 0.08587646484375 -0.6845092773437448 +1.426125 0.267852783203125 0.08447265625 -0.6845092773437448 +1.42625 0.267852783203125 0.08447265625 -0.6845092773437448 +1.426375 0.263427734375 0.08306884765625 -0.6845092773437448 +1.4265 0.263427734375 0.08306884765625 -0.6845092773437448 +1.426625 0.25897216796875 0.0816650390625 -0.6845092773437448 +1.42675 0.25445556640625 0.08026123046875 -0.6845092773437448 +1.4268750000000002 0.25445556640625 0.08026123046875 -0.6845092773437448 +1.427 0.249969482421875 0.078826904296875 -0.6845092773437448 +1.427125 0.249969482421875 0.078826904296875 -0.6845092773437448 +1.4272500000000002 0.24542236328125 0.077392578125 -0.6845092773437448 +1.427375 0.2408447265625 0.075958251953125 -0.6845092773437448 +1.4275 0.2408447265625 0.075958251953125 -0.6845092773437448 +1.427625 0.236236572265625 0.074493408203125 -0.6845092773437448 +1.42775 0.236236572265625 0.074493408203125 -0.6845092773437448 +1.427875 0.231597900390625 0.073028564453125 -0.6845092773437448 +1.428 0.226959228515625 0.071563720703125 -0.6845092773437448 +1.428125 0.226959228515625 0.071563720703125 -0.6845092773437448 +1.42825 0.2222900390625 0.070098876953125 -0.6845092773437448 +1.428375 0.2222900390625 0.070098876953125 -0.6845092773437448 +1.4285 0.21759033203125 0.068603515625 -0.6845092773437448 +1.428625 0.212860107421875 0.067138671875 -0.6845092773437448 +1.42875 0.212860107421875 0.067138671875 -0.6845092773437448 +1.4288750000000002 0.208099365234375 0.065643310546875 -0.6845092773437448 +1.429 0.208099365234375 0.065643310546875 -0.6845092773437448 +1.429125 0.203338623046875 0.064117431640625 -0.6845092773437448 +1.4292500000000002 0.19854736328125 0.0626220703125 -0.6845092773437448 +1.429375 0.19854736328125 0.0626220703125 -0.6845092773437448 +1.4295 0.1937255859375 0.06109619140625 -0.6845092773437448 +1.429625 0.1937255859375 0.06109619140625 -0.6845092773437448 +1.42975 0.188873291015625 0.0595703125 -0.6845092773437448 +1.429875 0.18402099609375 0.05804443359375 -0.6845092773437448 +1.43 0.18402099609375 0.05804443359375 -0.6845092773437448 +1.430125 0.17913818359375 0.056488037109375 -0.6845092773437448 +1.43025 0.17913818359375 0.056488037109375 -0.6845092773437448 +1.430375 0.17425537109375 0.054962158203125 -0.6845092773437448 +1.4305 0.169342041015625 0.05340576171875 -0.6845092773437448 +1.430625 0.169342041015625 0.05340576171875 -0.6845092773437448 +1.43075 0.164398193359375 0.051849365234375 -0.6845092773437448 +1.4308750000000002 0.164398193359375 0.051849365234375 -0.6845092773437448 +1.431 0.159454345703125 0.05029296875 -0.6845092773437448 +1.431125 0.15447998046875 0.0487060546875 -0.6845092773437448 +1.4312500000000002 0.15447998046875 0.0487060546875 -0.6845092773437448 +1.431375 0.14947509765625 0.047149658203125 -0.6845092773437448 +1.4315 0.14947509765625 0.047149658203125 -0.6845092773437448 +1.431625 0.14447021484375 0.045562744140625 -0.6845092773437448 +1.43175 0.13946533203125 0.043975830078125 -0.6845092773437448 +1.431875 0.13946533203125 0.043975830078125 -0.6845092773437448 +1.432 0.134429931640625 0.042388916015625 -0.6845092773437448 +1.432125 0.134429931640625 0.042388916015625 -0.6845092773437448 +1.43225 0.129364013671875 0.040802001953125 -0.6845092773437448 +1.432375 0.124298095703125 0.0391845703125 -0.6845092773437448 +1.4325 0.124298095703125 0.0391845703125 -0.6845092773437448 +1.432625 0.119232177734375 0.03759765625 -0.6845092773437448 +1.43275 0.119232177734375 0.03759765625 -0.6845092773437448 +1.4328750000000002 0.1141357421875 0.035980224609375 -0.6845092773437448 +1.433 0.109039306640625 0.034393310546875 -0.6845092773437448 +1.433125 0.109039306640625 0.034393310546875 -0.6845092773437448 +1.4332500000000002 0.103912353515625 0.03277587890625 -0.6845092773437448 +1.433375 0.103912353515625 0.03277587890625 -0.6845092773437448 +1.4335 0.098785400390625 0.031158447265625 -0.6845092773437448 +1.433625 0.093658447265625 0.029541015625 -0.6845092773437448 +1.43375 0.093658447265625 0.029541015625 -0.6845092773437448 +1.433875 0.0885009765625 0.02789306640625 -0.6845092773437448 +1.434 0.0885009765625 0.02789306640625 -0.6845092773437448 +1.434125 0.083343505859375 0.026275634765625 -0.6845092773437448 +1.43425 0.07818603515625 0.024658203125 -0.6845092773437448 +1.434375 0.07818603515625 0.024658203125 -0.6845092773437448 +1.4345 0.072998046875 0.02301025390625 -0.6845092773437448 +1.434625 0.072998046875 0.02301025390625 -0.6845092773437448 +1.43475 0.06781005859375 0.021392822265625 -0.6845092773437448 +1.4348750000000002 0.0626220703125 0.019744873046875 -0.6845092773437448 +1.435 0.0626220703125 0.019744873046875 -0.6845092773437448 +1.435125 0.05743408203125 0.018096923828125 -0.6845092773437448 +1.4352500000000002 0.05743408203125 0.018096923828125 -0.6845092773437448 +1.435375 0.05224609375 0.0164794921875 -0.6845092773437448 +1.4355 0.047027587890625 0.01483154296875 -0.6845092773437448 +1.435625 0.047027587890625 0.01483154296875 -0.6845092773437448 +1.43575 0.04180908203125 0.01318359375 -0.6845092773437448 +1.435875 0.04180908203125 0.01318359375 -0.6845092773437448 +1.436 0.036590576171875 0.01153564453125 -0.6845092773437448 +1.436125 0.0313720703125 0.0098876953125 -0.6845092773437448 +1.43625 0.0313720703125 0.0098876953125 -0.6845092773437448 +1.436375 0.026123046875 0.00823974609375 -0.6845092773437448 +1.4365 0.026123046875 0.00823974609375 -0.6845092773437448 +1.436625 0.020904541015625 0.006591796875 -0.6845092773437448 +1.43675 0.01568603515625 0.00494384765625 -0.6845092773437448 +1.4368750000000002 0.01568603515625 0.00494384765625 -0.6845092773437448 +1.437 0.01043701171875 0.0032958984375 -0.6845092773437448 +1.437125 0.01043701171875 0.0032958984375 -0.6845092773437448 +1.4372500000000002 0.005218505859375 0.00164794921875 -0.6845092773437448 +1.437375 0.0 0.0 -0.6845092773437448 +1.4375 0.0 0.0 -0.6845092773437448 +1.437625 -0.005218505859375 -0.00164794921875 -0.6845092773437448 +1.43775 -0.005218505859375 -0.00164794921875 -0.6845092773437448 +1.437875 -0.01043701171875 -0.0032958984375 -0.6845092773437448 +1.438 -0.01568603515625 -0.00494384765625 -0.6845092773437448 +1.438125 -0.01568603515625 -0.00494384765625 -0.6845092773437448 +1.43825 -0.020904541015625 -0.006591796875 -0.6845092773437448 +1.438375 -0.020904541015625 -0.006591796875 -0.6845092773437448 +1.4385000000000002 -0.026123046875 -0.00823974609375 -0.6845092773437448 +1.438625 -0.0313720703125 -0.0098876953125 -0.6845092773437448 +1.43875 -0.0313720703125 -0.0098876953125 -0.6845092773437448 +1.4388750000000002 -0.036590576171875 -0.01153564453125 -0.6845092773437448 +1.439 -0.036590576171875 -0.01153564453125 -0.6845092773437448 +1.439125 -0.04180908203125 -0.01318359375 -0.6845092773437448 +1.4392500000000002 -0.047027587890625 -0.01483154296875 -0.6845092773437448 +1.439375 -0.047027587890625 -0.01483154296875 -0.6845092773437448 +1.4395 -0.05224609375 -0.0164794921875 -0.6845092773437448 +1.439625 -0.05224609375 -0.0164794921875 -0.6845092773437448 +1.43975 -0.05743408203125 -0.018096923828125 -0.6845092773437448 +1.439875 -0.0626220703125 -0.019744873046875 -0.6845092773437448 +1.44 -0.0626220703125 -0.041046142578125 -0.3446105957031174 +1.440125 -0.06781005859375 -0.04443359375 -0.3446105957031174 +1.44025 -0.06781005859375 -0.04443359375 -0.3446105957031174 +1.440375 -0.072998046875 -0.0478515625 -0.3446105957031174 +1.4405000000000002 -0.07818603515625 -0.051239013671875 -0.3446105957031174 +1.440625 -0.07818603515625 -0.051239013671875 -0.3446105957031174 +1.44075 -0.083343505859375 -0.05462646484375 -0.3446105957031174 +1.4408750000000002 -0.083343505859375 -0.05462646484375 -0.3446105957031174 +1.441 -0.0885009765625 -0.058013916015625 -0.3446105957031174 +1.441125 -0.093658447265625 -0.061370849609375 -0.3446105957031174 +1.44125 -0.093658447265625 -0.061370849609375 -0.3446105957031174 +1.441375 -0.098785400390625 -0.064727783203125 -0.3446105957031174 +1.4415 -0.098785400390625 -0.064727783203125 -0.3446105957031174 +1.441625 -0.103912353515625 -0.068084716796875 -0.3446105957031174 +1.44175 -0.109039306640625 -0.071441650390625 -0.3446105957031174 +1.441875 -0.109039306640625 -0.071441650390625 -0.3446105957031174 +1.442 -0.1141357421875 -0.074798583984375 -0.3446105957031174 +1.442125 -0.1141357421875 -0.074798583984375 -0.3446105957031174 +1.44225 -0.119232177734375 -0.078125 -0.3446105957031174 +1.442375 -0.124298095703125 -0.081451416015625 -0.3446105957031174 +1.4425000000000002 -0.124298095703125 -0.081451416015625 -0.3446105957031174 +1.442625 -0.129364013671875 -0.08477783203125 -0.3446105957031174 +1.44275 -0.129364013671875 -0.08477783203125 -0.3446105957031174 +1.4428750000000002 -0.134429931640625 -0.08807373046875 -0.3446105957031174 +1.443 -0.13946533203125 -0.091400146484375 -0.3446105957031174 +1.443125 -0.13946533203125 -0.091400146484375 -0.3446105957031174 +1.44325 -0.14447021484375 -0.09466552734375 -0.3446105957031174 +1.443375 -0.14447021484375 -0.09466552734375 -0.3446105957031174 +1.4435 -0.14947509765625 -0.09796142578125 -0.3446105957031174 +1.443625 -0.15447998046875 -0.101226806640625 -0.3446105957031174 +1.44375 -0.15447998046875 -0.101226806640625 -0.3446105957031174 +1.443875 -0.159454345703125 -0.1044921875 -0.3446105957031174 +1.444 -0.159454345703125 -0.1044921875 -0.3446105957031174 +1.444125 -0.164398193359375 -0.10772705078125 -0.3446105957031174 +1.44425 -0.169342041015625 -0.1109619140625 -0.3446105957031174 +1.444375 -0.169342041015625 -0.1109619140625 -0.3446105957031174 +1.4445000000000002 -0.17425537109375 -0.11419677734375 -0.3446105957031174 +1.444625 -0.17425537109375 -0.11419677734375 -0.3446105957031174 +1.44475 -0.17913818359375 -0.117401123046875 -0.3446105957031174 +1.4448750000000002 -0.18402099609375 -0.12060546875 -0.3446105957031174 +1.445 -0.18402099609375 -0.12060546875 -0.3446105957031174 +1.445125 -0.188873291015625 -0.123779296875 -0.3446105957031174 +1.44525 -0.188873291015625 -0.123779296875 -0.3446105957031174 +1.445375 -0.1937255859375 -0.126953125 -0.3446105957031174 +1.4455 -0.19854736328125 -0.130096435546875 -0.3446105957031174 +1.445625 -0.19854736328125 -0.130096435546875 -0.3446105957031174 +1.44575 -0.203338623046875 -0.13323974609375 -0.3446105957031174 +1.445875 -0.203338623046875 -0.13323974609375 -0.3446105957031174 +1.446 -0.208099365234375 -0.136383056640625 -0.3446105957031174 +1.446125 -0.212860107421875 -0.139495849609375 -0.3446105957031174 +1.44625 -0.212860107421875 -0.139495849609375 -0.3446105957031174 +1.446375 -0.21759033203125 -0.142578125 -0.3446105957031174 +1.4465000000000002 -0.21759033203125 -0.142578125 -0.3446105957031174 +1.446625 -0.2222900390625 -0.145660400390625 -0.3446105957031174 +1.44675 -0.226959228515625 -0.148712158203125 -0.3446105957031174 +1.4468750000000002 -0.226959228515625 -0.148712158203125 -0.3446105957031174 +1.447 -0.231597900390625 -0.151763916015625 -0.3446105957031174 +1.447125 -0.231597900390625 -0.151763916015625 -0.3446105957031174 +1.44725 -0.236236572265625 -0.154815673828125 -0.3446105957031174 +1.447375 -0.2408447265625 -0.157806396484375 -0.3446105957031174 +1.4475 -0.2408447265625 -0.157806396484375 -0.3446105957031174 +1.447625 -0.24542236328125 -0.16082763671875 -0.3446105957031174 +1.44775 -0.24542236328125 -0.16082763671875 -0.3446105957031174 +1.447875 -0.249969482421875 -0.163787841796875 -0.3446105957031174 +1.448 -0.25445556640625 -0.166748046875 -0.3446105957031174 +1.448125 -0.25445556640625 -0.166748046875 -0.3446105957031174 +1.44825 -0.25897216796875 -0.169708251953125 -0.3446105957031174 +1.448375 -0.25897216796875 -0.169708251953125 -0.3446105957031174 +1.4485000000000002 -0.263427734375 -0.172637939453125 -0.3446105957031174 +1.448625 -0.267852783203125 -0.175537109375 -0.3446105957031174 +1.44875 -0.267852783203125 -0.175537109375 -0.3446105957031174 +1.4488750000000002 -0.27227783203125 -0.178436279296875 -0.3446105957031174 +1.449 -0.27227783203125 -0.178436279296875 -0.3446105957031174 +1.449125 -0.276641845703125 -0.1812744140625 -0.3446105957031174 +1.44925 -0.280975341796875 -0.18414306640625 -0.3446105957031174 +1.449375 -0.280975341796875 -0.18414306640625 -0.3446105957031174 +1.4495 -0.285308837890625 -0.186981201171875 -0.3446105957031174 +1.449625 -0.285308837890625 -0.186981201171875 -0.3446105957031174 +1.44975 -0.289581298828125 -0.189788818359375 -0.3446105957031174 +1.449875 -0.2938232421875 -0.19256591796875 -0.3446105957031174 +1.45 -0.2938232421875 -0.19256591796875 -0.3446105957031174 +1.450125 -0.298065185546875 -0.195343017578125 -0.3446105957031174 +1.45025 -0.298065185546875 -0.195343017578125 -0.3446105957031174 +1.450375 -0.30224609375 -0.19805908203125 -0.3446105957031174 +1.4505000000000002 -0.306396484375 -0.2008056640625 -0.3446105957031174 +1.450625 -0.306396484375 -0.2008056640625 -0.3446105957031174 +1.45075 -0.310516357421875 -0.2034912109375 -0.3446105957031174 +1.4508750000000002 -0.310516357421875 -0.2034912109375 -0.3446105957031174 +1.451 -0.314605712890625 -0.2061767578125 -0.3446105957031174 +1.451125 -0.31866455078125 -0.208831787109375 -0.3446105957031174 +1.45125 -0.31866455078125 -0.208831787109375 -0.3446105957031174 +1.451375 -0.322662353515625 -0.211456298828125 -0.3446105957031174 +1.4515 -0.322662353515625 -0.211456298828125 -0.3446105957031174 +1.451625 -0.32666015625 -0.214080810546875 -0.3446105957031174 +1.45175 -0.330596923828125 -0.216644287109375 -0.3446105957031174 +1.451875 -0.330596923828125 -0.216644287109375 -0.3446105957031174 +1.452 -0.334503173828125 -0.219207763671875 -0.3446105957031174 +1.452125 -0.334503173828125 -0.219207763671875 -0.3446105957031174 +1.45225 -0.33837890625 -0.22174072265625 -0.3446105957031174 +1.452375 -0.34222412109375 -0.224273681640625 -0.3446105957031174 +1.4525000000000002 -0.34222412109375 -0.224273681640625 -0.3446105957031174 +1.452625 -0.34600830078125 -0.22674560546875 -0.3446105957031174 +1.45275 -0.34600830078125 -0.22674560546875 -0.3446105957031174 +1.4528750000000002 -0.349761962890625 -0.229217529296875 -0.3446105957031174 +1.453 -0.353485107421875 -0.231658935546875 -0.3446105957031174 +1.453125 -0.353485107421875 -0.231658935546875 -0.3446105957031174 +1.45325 -0.357177734375 -0.23406982421875 -0.3446105957031174 +1.453375 -0.357177734375 -0.23406982421875 -0.3446105957031174 +1.4535 -0.360809326171875 -0.2364501953125 -0.3446105957031174 +1.453625 -0.36444091796875 -0.23883056640625 -0.3446105957031174 +1.45375 -0.36444091796875 -0.23883056640625 -0.3446105957031174 +1.453875 -0.36798095703125 -0.24114990234375 -0.3446105957031174 +1.454 -0.36798095703125 -0.24114990234375 -0.3446105957031174 +1.4541250000000002 -0.37152099609375 -0.24346923828125 -0.3446105957031174 +1.45425 -0.375 -0.245758056640625 -0.3446105957031174 +1.454375 -0.375 -0.245758056640625 -0.3446105957031174 +1.4545000000000002 -0.378448486328125 -0.248016357421875 -0.3446105957031174 +1.454625 -0.378448486328125 -0.248016357421875 -0.3446105957031174 +1.45475 -0.3818359375 -0.250244140625 -0.3446105957031174 +1.4548750000000002 -0.38519287109375 -0.25244140625 -0.3446105957031174 +1.455 -0.38519287109375 -0.25244140625 -0.3446105957031174 +1.455125 -0.388519287109375 -0.254608154296875 -0.3446105957031174 +1.45525 -0.388519287109375 -0.254608154296875 -0.3446105957031174 +1.455375 -0.39178466796875 -0.256744384765625 -0.3446105957031174 +1.4555 -0.39501953125 -0.258880615234375 -0.3446105957031174 +1.455625 -0.39501953125 -0.258880615234375 -0.3446105957031174 +1.45575 -0.398193359375 -0.260955810546875 -0.3446105957031174 +1.455875 -0.398193359375 -0.260955810546875 -0.3446105957031174 +1.456 -0.401336669921875 -0.26300048828125 -0.3446105957031174 +1.4561250000000002 -0.404449462890625 -0.265045166015625 -0.3446105957031174 +1.45625 -0.404449462890625 -0.265045166015625 -0.3446105957031174 +1.456375 -0.407501220703125 -0.267059326171875 -0.3446105957031174 +1.4565000000000002 -0.407501220703125 -0.267059326171875 -0.3446105957031174 +1.456625 -0.4105224609375 -0.269012451171875 -0.3446105957031174 +1.45675 -0.413482666015625 -0.270965576171875 -0.3446105957031174 +1.456875 -0.413482666015625 -0.270965576171875 -0.3446105957031174 +1.457 -0.416412353515625 -0.27288818359375 -0.3446105957031174 +1.457125 -0.416412353515625 -0.27288818359375 -0.3446105957031174 +1.45725 -0.419281005859375 -0.274749755859375 -0.3446105957031174 +1.457375 -0.422119140625 -0.276611328125 -0.3446105957031174 +1.4575 -0.422119140625 -0.276611328125 -0.3446105957031174 +1.457625 -0.424896240234375 -0.2784423828125 -0.3446105957031174 +1.45775 -0.424896240234375 -0.2784423828125 -0.3446105957031174 +1.457875 -0.4276123046875 -0.280242919921875 -0.3446105957031174 +1.458 -0.4302978515625 -0.281982421875 -0.3446105957031174 +1.4581250000000002 -0.4302978515625 -0.281982421875 -0.3446105957031174 +1.45825 -0.432952880859375 -0.283721923828125 -0.3446105957031174 +1.458375 -0.432952880859375 -0.283721923828125 -0.3446105957031174 +1.4585000000000002 -0.435546875 -0.285430908203125 -0.3446105957031174 +1.458625 -0.438079833984375 -0.287078857421875 -0.3446105957031174 +1.45875 -0.438079833984375 -0.287078857421875 -0.3446105957031174 +1.458875 -0.440582275390625 -0.288726806640625 -0.3446105957031174 +1.459 -0.440582275390625 -0.288726806640625 -0.3446105957031174 +1.459125 -0.44305419921875 -0.29034423828125 -0.3446105957031174 +1.45925 -0.4454345703125 -0.291900634765625 -0.3446105957031174 +1.459375 -0.4454345703125 -0.291900634765625 -0.3446105957031174 +1.4595 -0.447784423828125 -0.29345703125 -0.3446105957031174 +1.459625 -0.447784423828125 -0.29345703125 -0.3446105957031174 +1.45975 -0.450103759765625 -0.294952392578125 -0.3446105957031174 +1.459875 -0.452362060546875 -0.29644775390625 -0.3446105957031174 +1.46 -0.452362060546875 -0.29644775390625 -0.3446105957031174 +1.4601250000000002 -0.454559326171875 -0.297882080078125 -0.3446105957031174 +1.46025 -0.454559326171875 -0.297882080078125 -0.3446105957031174 +1.460375 -0.45672607421875 -0.299285888671875 -0.3446105957031174 +1.4605000000000002 -0.458831787109375 -0.300689697265625 -0.3446105957031174 +1.460625 -0.458831787109375 -0.300689697265625 -0.3446105957031174 +1.46075 -0.46087646484375 -0.302032470703125 -0.3446105957031174 +1.460875 -0.46087646484375 -0.302032470703125 -0.3446105957031174 +1.461 -0.462890625 -0.3033447265625 -0.3446105957031174 +1.461125 -0.464813232421875 -0.304595947265625 -0.3446105957031174 +1.46125 -0.464813232421875 -0.304595947265625 -0.3446105957031174 +1.461375 -0.46673583984375 -0.30584716796875 -0.3446105957031174 +1.4615 -0.46673583984375 -0.30584716796875 -0.3446105957031174 +1.461625 -0.46856689453125 -0.30706787109375 -0.3446105957031174 +1.46175 -0.470367431640625 -0.308258056640625 -0.3446105957031174 +1.461875 -0.470367431640625 -0.308258056640625 -0.3446105957031174 +1.462 -0.472137451171875 -0.30938720703125 -0.3446105957031174 +1.4621250000000002 -0.472137451171875 -0.30938720703125 -0.3446105957031174 +1.46225 -0.47381591796875 -0.310516357421875 -0.3446105957031174 +1.462375 -0.4754638671875 -0.31158447265625 -0.3446105957031174 +1.4625000000000002 -0.4754638671875 -0.31158447265625 -0.3446105957031174 +1.462625 -0.47705078125 -0.3126220703125 -0.3446105957031174 +1.46275 -0.47705078125 -0.3126220703125 -0.3446105957031174 +1.462875 -0.478607177734375 -0.313629150390625 -0.3446105957031174 +1.463 -0.480072021484375 -0.314605712890625 -0.3446105957031174 +1.463125 -0.480072021484375 -0.314605712890625 -0.3446105957031174 +1.46325 -0.48150634765625 -0.3155517578125 -0.3446105957031174 +1.463375 -0.48150634765625 -0.3155517578125 -0.3446105957031174 +1.4635 -0.48291015625 -0.31646728515625 -0.3446105957031174 +1.463625 -0.484222412109375 -0.31732177734375 -0.3446105957031174 +1.46375 -0.484222412109375 -0.31732177734375 -0.3446105957031174 +1.463875 -0.485504150390625 -0.31817626953125 -0.3446105957031174 +1.464 -0.485504150390625 -0.31817626953125 -0.3446105957031174 +1.4641250000000002 -0.486724853515625 -0.3189697265625 -0.3446105957031174 +1.46425 -0.487884521484375 -0.319732666015625 -0.3446105957031174 +1.464375 -0.487884521484375 -0.319732666015625 -0.3446105957031174 +1.4645000000000002 -0.489013671875 -0.320465087890625 -0.3446105957031174 +1.464625 -0.489013671875 -0.320465087890625 -0.3446105957031174 +1.46475 -0.490081787109375 -0.3211669921875 -0.3446105957031174 +1.464875 -0.4910888671875 -0.321807861328125 -0.3446105957031174 +1.465 -0.4910888671875 -0.321807861328125 -0.3446105957031174 +1.465125 -0.492034912109375 -0.32244873046875 -0.3446105957031174 +1.46525 -0.492034912109375 -0.32244873046875 -0.3446105957031174 +1.465375 -0.492950439453125 -0.323028564453125 -0.3446105957031174 +1.4655 -0.4937744140625 -0.323577880859375 -0.3446105957031174 +1.465625 -0.4937744140625 -0.323577880859375 -0.3446105957031174 +1.46575 -0.49456787109375 -0.3240966796875 -0.3446105957031174 +1.465875 -0.49456787109375 -0.3240966796875 -0.3446105957031174 +1.466 -0.49530029296875 -0.3245849609375 -0.3446105957031174 +1.4661250000000002 -0.496002197265625 -0.325042724609375 -0.3446105957031174 +1.46625 -0.496002197265625 -0.325042724609375 -0.3446105957031174 +1.466375 -0.496612548828125 -0.325439453125 -0.3446105957031174 +1.4665000000000002 -0.496612548828125 -0.325439453125 -0.3446105957031174 +1.466625 -0.4971923828125 -0.325836181640625 -0.3446105957031174 +1.46675 -0.497711181640625 -0.326171875 -0.3446105957031174 +1.466875 -0.497711181640625 -0.326171875 -0.3446105957031174 +1.467 -0.498199462890625 -0.32647705078125 -0.3446105957031174 +1.467125 -0.498199462890625 -0.32647705078125 -0.3446105957031174 +1.46725 -0.49859619140625 -0.326751708984375 -0.3446105957031174 +1.467375 -0.49896240234375 -0.32696533203125 -0.3446105957031174 +1.4675 -0.49896240234375 -0.32696533203125 -0.3446105957031174 +1.467625 -0.499267578125 -0.327178955078125 -0.3446105957031174 +1.46775 -0.499267578125 -0.327178955078125 -0.3446105957031174 +1.467875 -0.49951171875 -0.32733154296875 -0.3446105957031174 +1.468 -0.49969482421875 -0.32745361328125 -0.3446105957031174 +1.4681250000000002 -0.49969482421875 -0.32745361328125 -0.3446105957031174 +1.46825 -0.49981689453125 -0.327545166015625 -0.3446105957031174 +1.468375 -0.49981689453125 -0.327545166015625 -0.3446105957031174 +1.4685000000000002 -0.499908447265625 -0.327606201171875 -0.3446105957031174 +1.468625 -0.49993896484375 -0.32763671875 -0.3446105957031174 +1.46875 -0.49993896484375 -0.32763671875 -0.3446105957031174 +1.468875 -0.499908447265625 -0.327606201171875 -0.3446105957031174 +1.469 -0.499908447265625 -0.327606201171875 -0.3446105957031174 +1.469125 -0.49981689453125 -0.327545166015625 -0.3446105957031174 +1.46925 -0.49969482421875 -0.32745361328125 -0.3446105957031174 +1.469375 -0.49969482421875 -0.32745361328125 -0.3446105957031174 +1.4695 -0.49951171875 -0.32733154296875 -0.3446105957031174 +1.469625 -0.49951171875 -0.32733154296875 -0.3446105957031174 +1.4697500000000002 -0.499267578125 -0.327178955078125 -0.3446105957031174 +1.469875 -0.49896240234375 -0.32696533203125 -0.3446105957031174 +1.47 -0.49896240234375 -0.32696533203125 -0.3446105957031174 +1.4701250000000002 -0.49859619140625 -0.326751708984375 -0.3446105957031174 +1.47025 -0.49859619140625 -0.326751708984375 -0.3446105957031174 +1.470375 -0.498199462890625 -0.32647705078125 -0.3446105957031174 +1.4705000000000002 -0.497711181640625 -0.326171875 -0.3446105957031174 +1.470625 -0.497711181640625 -0.326171875 -0.3446105957031174 +1.47075 -0.4971923828125 -0.325836181640625 -0.3446105957031174 +1.470875 -0.4971923828125 -0.325836181640625 -0.3446105957031174 +1.471 -0.496612548828125 -0.325439453125 -0.3446105957031174 +1.471125 -0.496002197265625 -0.325042724609375 -0.3446105957031174 +1.47125 -0.496002197265625 -0.325042724609375 -0.3446105957031174 +1.471375 -0.49530029296875 -0.3245849609375 -0.3446105957031174 +1.4715 -0.49530029296875 -0.3245849609375 -0.3446105957031174 +1.471625 -0.49456787109375 -0.3240966796875 -0.3446105957031174 +1.4717500000000002 -0.4937744140625 -0.323577880859375 -0.3446105957031174 +1.471875 -0.4937744140625 -0.323577880859375 -0.3446105957031174 +1.472 -0.468170166015625 -0.492950439453125 0.050219726562508388 +1.4721250000000002 -0.468170166015625 -0.492950439453125 0.050219726562508388 +1.47225 -0.467315673828125 -0.492034912109375 0.050219726562508388 +1.472375 -0.466400146484375 -0.4910888671875 0.050219726562508388 +1.4725 -0.466400146484375 -0.4910888671875 0.050219726562508388 +1.472625 -0.465423583984375 -0.490081787109375 0.050219726562508388 +1.47275 -0.465423583984375 -0.490081787109375 0.050219726562508388 +1.472875 -0.46441650390625 -0.489013671875 0.050219726562508388 +1.473 -0.463348388671875 -0.487884521484375 0.050219726562508388 +1.473125 -0.463348388671875 -0.487884521484375 0.050219726562508388 +1.47325 -0.462249755859375 -0.486724853515625 0.050219726562508388 +1.473375 -0.462249755859375 -0.486724853515625 0.050219726562508388 +1.4735 -0.461090087890625 -0.485504150390625 0.050219726562508388 +1.473625 -0.459869384765625 -0.484222412109375 0.050219726562508388 +1.4737500000000002 -0.459869384765625 -0.484222412109375 0.050219726562508388 +1.473875 -0.4586181640625 -0.48291015625 0.050219726562508388 +1.474 -0.4586181640625 -0.48291015625 0.050219726562508388 +1.4741250000000002 -0.457305908203125 -0.48150634765625 0.050219726562508388 +1.47425 -0.4559326171875 -0.480072021484375 0.050219726562508388 +1.474375 -0.4559326171875 -0.480072021484375 0.050219726562508388 +1.4745 -0.45452880859375 -0.478607177734375 0.050219726562508388 +1.474625 -0.45452880859375 -0.478607177734375 0.050219726562508388 +1.47475 -0.45306396484375 -0.47705078125 0.050219726562508388 +1.474875 -0.451568603515625 -0.4754638671875 0.050219726562508388 +1.475 -0.451568603515625 -0.4754638671875 0.050219726562508388 +1.475125 -0.45001220703125 -0.47381591796875 0.050219726562508388 +1.47525 -0.45001220703125 -0.47381591796875 0.050219726562508388 +1.475375 -0.448394775390625 -0.472137451171875 0.050219726562508388 +1.4755 -0.44671630859375 -0.470367431640625 0.050219726562508388 +1.475625 -0.44671630859375 -0.470367431640625 0.050219726562508388 +1.4757500000000002 -0.44500732421875 -0.46856689453125 0.050219726562508388 +1.475875 -0.44500732421875 -0.46856689453125 0.050219726562508388 +1.476 -0.443267822265625 -0.46673583984375 0.050219726562508388 +1.4761250000000002 -0.441436767578125 -0.464813232421875 0.050219726562508388 +1.47625 -0.441436767578125 -0.464813232421875 0.050219726562508388 +1.476375 -0.439605712890625 -0.462890625 0.050219726562508388 +1.4765 -0.439605712890625 -0.462890625 0.050219726562508388 +1.476625 -0.43768310546875 -0.46087646484375 0.050219726562508388 +1.47675 -0.435760498046875 -0.458831787109375 0.050219726562508388 +1.476875 -0.435760498046875 -0.458831787109375 0.050219726562508388 +1.477 -0.433746337890625 -0.45672607421875 0.050219726562508388 +1.477125 -0.433746337890625 -0.45672607421875 0.050219726562508388 +1.47725 -0.43170166015625 -0.454559326171875 0.050219726562508388 +1.477375 -0.42962646484375 -0.452362060546875 0.050219726562508388 +1.4775 -0.42962646484375 -0.452362060546875 0.050219726562508388 +1.477625 -0.427459716796875 -0.450103759765625 0.050219726562508388 +1.4777500000000002 -0.427459716796875 -0.450103759765625 0.050219726562508388 +1.477875 -0.42529296875 -0.447784423828125 0.050219726562508388 +1.478 -0.42303466796875 -0.4454345703125 0.050219726562508388 +1.4781250000000002 -0.42303466796875 -0.4454345703125 0.050219726562508388 +1.47825 -0.4207763671875 -0.44305419921875 0.050219726562508388 +1.478375 -0.4207763671875 -0.44305419921875 0.050219726562508388 +1.4785 -0.418426513671875 -0.440582275390625 0.050219726562508388 +1.478625 -0.41607666015625 -0.438079833984375 0.050219726562508388 +1.47875 -0.41607666015625 -0.438079833984375 0.050219726562508388 +1.478875 -0.413665771484375 -0.435546875 0.050219726562508388 +1.479 -0.413665771484375 -0.435546875 0.050219726562508388 +1.479125 -0.41119384765625 -0.432952880859375 0.050219726562508388 +1.47925 -0.408660888671875 -0.4302978515625 0.050219726562508388 +1.479375 -0.408660888671875 -0.4302978515625 0.050219726562508388 +1.4795 -0.4061279296875 -0.4276123046875 0.050219726562508388 +1.479625 -0.4061279296875 -0.4276123046875 0.050219726562508388 +1.4797500000000002 -0.403533935546875 -0.424896240234375 0.050219726562508388 +1.479875 -0.40087890625 -0.422119140625 0.050219726562508388 +1.48 -0.40087890625 -0.422119140625 0.050219726562508388 +1.4801250000000002 -0.398193359375 -0.419281005859375 0.050219726562508388 +1.48025 -0.398193359375 -0.419281005859375 0.050219726562508388 +1.480375 -0.395477294921875 -0.416412353515625 0.050219726562508388 +1.4805 -0.3927001953125 -0.413482666015625 0.050219726562508388 +1.480625 -0.3927001953125 -0.413482666015625 0.050219726562508388 +1.48075 -0.389862060546875 -0.4105224609375 0.050219726562508388 +1.480875 -0.389862060546875 -0.4105224609375 0.050219726562508388 +1.481 -0.38702392578125 -0.407501220703125 0.050219726562508388 +1.481125 -0.384124755859375 -0.404449462890625 0.050219726562508388 +1.48125 -0.384124755859375 -0.404449462890625 0.050219726562508388 +1.481375 -0.38116455078125 -0.401336669921875 0.050219726562508388 +1.4815 -0.38116455078125 -0.401336669921875 0.050219726562508388 +1.481625 -0.378173828125 -0.398193359375 0.050219726562508388 +1.4817500000000002 -0.37518310546875 -0.39501953125 0.050219726562508388 +1.481875 -0.37518310546875 -0.39501953125 0.050219726562508388 +1.482 -0.372100830078125 -0.39178466796875 0.050219726562508388 +1.4821250000000002 -0.372100830078125 -0.39178466796875 0.050219726562508388 +1.48225 -0.368988037109375 -0.388519287109375 0.050219726562508388 +1.482375 -0.3658447265625 -0.38519287109375 0.050219726562508388 +1.4825 -0.3658447265625 -0.38519287109375 0.050219726562508388 +1.482625 -0.362640380859375 -0.3818359375 0.050219726562508388 +1.48275 -0.362640380859375 -0.3818359375 0.050219726562508388 +1.482875 -0.359405517578125 -0.378448486328125 0.050219726562508388 +1.483 -0.35614013671875 -0.375 0.050219726562508388 +1.483125 -0.35614013671875 -0.375 0.050219726562508388 +1.48325 -0.35284423828125 -0.37152099609375 0.050219726562508388 +1.483375 -0.35284423828125 -0.37152099609375 0.050219726562508388 +1.4835 -0.3494873046875 -0.36798095703125 0.050219726562508388 +1.483625 -0.346099853515625 -0.36444091796875 0.050219726562508388 +1.4837500000000002 -0.346099853515625 -0.36444091796875 0.050219726562508388 +1.483875 -0.342681884765625 -0.360809326171875 0.050219726562508388 +1.484 -0.342681884765625 -0.360809326171875 0.050219726562508388 +1.4841250000000002 -0.3392333984375 -0.357177734375 0.050219726562508388 +1.48425 -0.335723876953125 -0.353485107421875 0.050219726562508388 +1.484375 -0.335723876953125 -0.353485107421875 0.050219726562508388 +1.4845 -0.332183837890625 -0.349761962890625 0.050219726562508388 +1.484625 -0.332183837890625 -0.349761962890625 0.050219726562508388 +1.48475 -0.32861328125 -0.34600830078125 0.050219726562508388 +1.484875 -0.32501220703125 -0.34222412109375 0.050219726562508388 +1.485 -0.32501220703125 -0.34222412109375 0.050219726562508388 +1.485125 -0.321380615234375 -0.33837890625 0.050219726562508388 +1.48525 -0.321380615234375 -0.33837890625 0.050219726562508388 +1.4853750000000002 -0.31768798828125 -0.334503173828125 0.050219726562508388 +1.4855 -0.313995361328125 -0.330596923828125 0.050219726562508388 +1.485625 -0.313995361328125 -0.330596923828125 0.050219726562508388 +1.4857500000000002 -0.31024169921875 -0.32666015625 0.050219726562508388 +1.485875 -0.31024169921875 -0.32666015625 0.050219726562508388 +1.486 -0.30645751953125 -0.322662353515625 0.050219726562508388 +1.4861250000000002 -0.302642822265625 -0.31866455078125 0.050219726562508388 +1.48625 -0.302642822265625 -0.31866455078125 0.050219726562508388 +1.486375 -0.298797607421875 -0.314605712890625 0.050219726562508388 +1.4865 -0.298797607421875 -0.314605712890625 0.050219726562508388 +1.486625 -0.294921875 -0.310516357421875 0.050219726562508388 +1.48675 -0.291015625 -0.306396484375 0.050219726562508388 +1.486875 -0.291015625 -0.306396484375 0.050219726562508388 +1.487 -0.28704833984375 -0.30224609375 0.050219726562508388 +1.487125 -0.28704833984375 -0.30224609375 0.050219726562508388 +1.48725 -0.2830810546875 -0.298065185546875 0.050219726562508388 +1.4873750000000002 -0.279052734375 -0.2938232421875 0.050219726562508388 +1.4875 -0.279052734375 -0.2938232421875 0.050219726562508388 +1.487625 -0.2750244140625 -0.289581298828125 0.050219726562508388 +1.4877500000000002 -0.2750244140625 -0.289581298828125 0.050219726562508388 +1.487875 -0.270965576171875 -0.285308837890625 0.050219726562508388 +1.488 -0.266876220703125 -0.280975341796875 0.050219726562508388 +1.488125 -0.266876220703125 -0.280975341796875 0.050219726562508388 +1.48825 -0.262725830078125 -0.276641845703125 0.050219726562508388 +1.488375 -0.262725830078125 -0.276641845703125 0.050219726562508388 +1.4885 -0.258575439453125 -0.27227783203125 0.050219726562508388 +1.488625 -0.25439453125 -0.267852783203125 0.050219726562508388 +1.48875 -0.25439453125 -0.267852783203125 0.050219726562508388 +1.488875 -0.25018310546875 -0.263427734375 0.050219726562508388 +1.489 -0.25018310546875 -0.263427734375 0.050219726562508388 +1.489125 -0.245941162109375 -0.25897216796875 0.050219726562508388 +1.48925 -0.241668701171875 -0.25445556640625 0.050219726562508388 +1.4893750000000002 -0.241668701171875 -0.25445556640625 0.050219726562508388 +1.4895 -0.237396240234375 -0.249969482421875 0.050219726562508388 +1.489625 -0.237396240234375 -0.249969482421875 0.050219726562508388 +1.4897500000000002 -0.233062744140625 -0.24542236328125 0.050219726562508388 +1.489875 -0.228729248046875 -0.2408447265625 0.050219726562508388 +1.49 -0.228729248046875 -0.2408447265625 0.050219726562508388 +1.490125 -0.224365234375 -0.236236572265625 0.050219726562508388 +1.49025 -0.224365234375 -0.236236572265625 0.050219726562508388 +1.490375 -0.219970703125 -0.231597900390625 0.050219726562508388 +1.4905 -0.215545654296875 -0.226959228515625 0.050219726562508388 +1.490625 -0.215545654296875 -0.226959228515625 0.050219726562508388 +1.49075 -0.211090087890625 -0.2222900390625 0.050219726562508388 +1.490875 -0.211090087890625 -0.2222900390625 0.050219726562508388 +1.491 -0.206634521484375 -0.21759033203125 0.050219726562508388 +1.491125 -0.2021484375 -0.212860107421875 0.050219726562508388 +1.49125 -0.2021484375 -0.212860107421875 0.050219726562508388 +1.4913750000000002 -0.1976318359375 -0.208099365234375 0.050219726562508388 +1.4915 -0.1976318359375 -0.208099365234375 0.050219726562508388 +1.491625 -0.193115234375 -0.203338623046875 0.050219726562508388 +1.4917500000000002 -0.188568115234375 -0.19854736328125 0.050219726562508388 +1.491875 -0.188568115234375 -0.19854736328125 0.050219726562508388 +1.492 -0.183990478515625 -0.1937255859375 0.050219726562508388 +1.492125 -0.183990478515625 -0.1937255859375 0.050219726562508388 +1.49225 -0.17938232421875 -0.188873291015625 0.050219726562508388 +1.492375 -0.174774169921875 -0.18402099609375 0.050219726562508388 +1.4925 -0.174774169921875 -0.18402099609375 0.050219726562508388 +1.492625 -0.170135498046875 -0.17913818359375 0.050219726562508388 +1.49275 -0.170135498046875 -0.17913818359375 0.050219726562508388 +1.492875 -0.165496826171875 -0.17425537109375 0.050219726562508388 +1.493 -0.16082763671875 -0.169342041015625 0.050219726562508388 +1.493125 -0.16082763671875 -0.169342041015625 0.050219726562508388 +1.49325 -0.1561279296875 -0.164398193359375 0.050219726562508388 +1.4933750000000002 -0.1561279296875 -0.164398193359375 0.050219726562508388 +1.4935 -0.15142822265625 -0.159454345703125 0.050219726562508388 +1.493625 -0.146697998046875 -0.15447998046875 0.050219726562508388 +1.4937500000000002 -0.146697998046875 -0.15447998046875 0.050219726562508388 +1.493875 -0.1419677734375 -0.14947509765625 0.050219726562508388 +1.494 -0.1419677734375 -0.14947509765625 0.050219726562508388 +1.494125 -0.13720703125 -0.14447021484375 0.050219726562508388 +1.49425 -0.1324462890625 -0.13946533203125 0.050219726562508388 +1.494375 -0.1324462890625 -0.13946533203125 0.050219726562508388 +1.4945 -0.127655029296875 -0.134429931640625 0.050219726562508388 +1.494625 -0.127655029296875 -0.134429931640625 0.050219726562508388 +1.49475 -0.12286376953125 -0.129364013671875 0.050219726562508388 +1.494875 -0.1180419921875 -0.124298095703125 0.050219726562508388 +1.495 -0.1180419921875 -0.124298095703125 0.050219726562508388 +1.495125 -0.113250732421875 -0.119232177734375 0.050219726562508388 +1.49525 -0.113250732421875 -0.119232177734375 0.050219726562508388 +1.4953750000000002 -0.1083984375 -0.1141357421875 0.050219726562508388 +1.4955 -0.103546142578125 -0.109039306640625 0.050219726562508388 +1.495625 -0.103546142578125 -0.109039306640625 0.050219726562508388 +1.4957500000000002 -0.09869384765625 -0.103912353515625 0.050219726562508388 +1.495875 -0.09869384765625 -0.103912353515625 0.050219726562508388 +1.496 -0.093841552734375 -0.098785400390625 0.050219726562508388 +1.496125 -0.088958740234375 -0.093658447265625 0.050219726562508388 +1.49625 -0.088958740234375 -0.093658447265625 0.050219726562508388 +1.496375 -0.084075927734375 -0.0885009765625 0.050219726562508388 +1.4965 -0.084075927734375 -0.0885009765625 0.050219726562508388 +1.496625 -0.07916259765625 -0.083343505859375 0.050219726562508388 +1.49675 -0.074249267578125 -0.07818603515625 0.050219726562508388 +1.496875 -0.074249267578125 -0.07818603515625 0.050219726562508388 +1.497 -0.0693359375 -0.072998046875 0.050219726562508388 +1.497125 -0.0693359375 -0.072998046875 0.050219726562508388 +1.49725 -0.064422607421875 -0.06781005859375 0.050219726562508388 +1.4973750000000002 -0.059478759765625 -0.0626220703125 0.050219726562508388 +1.4975 -0.059478759765625 -0.0626220703125 0.050219726562508388 +1.497625 -0.0545654296875 -0.05743408203125 0.050219726562508388 +1.4977500000000002 -0.0545654296875 -0.05743408203125 0.050219726562508388 +1.497875 -0.04962158203125 -0.05224609375 0.050219726562508388 +1.498 -0.044647216796875 -0.047027587890625 0.050219726562508388 +1.498125 -0.044647216796875 -0.047027587890625 0.050219726562508388 +1.49825 -0.039703369140625 -0.04180908203125 0.050219726562508388 +1.498375 -0.039703369140625 -0.04180908203125 0.050219726562508388 +1.4985 -0.034759521484375 -0.036590576171875 0.050219726562508388 +1.498625 -0.02978515625 -0.0313720703125 0.050219726562508388 +1.49875 -0.02978515625 -0.0313720703125 0.050219726562508388 +1.498875 -0.024810791015625 -0.026123046875 0.050219726562508388 +1.499 -0.024810791015625 -0.026123046875 0.050219726562508388 +1.499125 -0.019866943359375 -0.020904541015625 0.050219726562508388 +1.49925 -0.014892578125 -0.01568603515625 0.050219726562508388 +1.4993750000000002 -0.014892578125 -0.01568603515625 0.050219726562508388 +1.4995 -0.009918212890625 -0.01043701171875 0.050219726562508388 +1.499625 -0.009918212890625 -0.01043701171875 0.050219726562508388 +1.4997500000000002 -0.00494384765625 -0.005218505859375 0.050219726562508388 +1.499875 0.0 0.0 0.050219726562508388 +1.5 0.0 0.0 0.050219726562508388 +1.500125 0.00494384765625 0.005218505859375 0.050219726562508388 +1.50025 0.00494384765625 0.005218505859375 0.050219726562508388 +1.500375 0.009918212890625 0.01043701171875 0.050219726562508388 +1.5005 0.014892578125 0.01568603515625 0.050219726562508388 +1.500625 0.014892578125 0.01568603515625 0.050219726562508388 +1.50075 0.019866943359375 0.020904541015625 0.050219726562508388 +1.500875 0.019866943359375 0.020904541015625 0.050219726562508388 +1.5010000000000002 0.024810791015625 0.026123046875 0.050219726562508388 +1.501125 0.02978515625 0.0313720703125 0.050219726562508388 +1.50125 0.02978515625 0.0313720703125 0.050219726562508388 +1.5013750000000002 0.034759521484375 0.036590576171875 0.050219726562508388 +1.5015 0.034759521484375 0.036590576171875 0.050219726562508388 +1.501625 0.039703369140625 0.04180908203125 0.050219726562508388 +1.5017500000000002 0.044647216796875 0.047027587890625 0.050219726562508388 +1.501875 0.044647216796875 0.047027587890625 0.050219726562508388 +1.502 0.04962158203125 0.05224609375 0.050219726562508388 +1.502125 0.04962158203125 0.05224609375 0.050219726562508388 +1.50225 0.0545654296875 0.05743408203125 0.050219726562508388 +1.502375 0.059478759765625 0.0626220703125 0.050219726562508388 +1.5025 0.059478759765625 0.0626220703125 0.050219726562508388 +1.502625 0.064422607421875 0.06781005859375 0.050219726562508388 +1.50275 0.064422607421875 0.06781005859375 0.050219726562508388 +1.502875 0.0693359375 0.072998046875 0.050219726562508388 +1.5030000000000002 0.074249267578125 0.07818603515625 0.050219726562508388 +1.503125 0.074249267578125 0.07818603515625 0.050219726562508388 +1.50325 0.07916259765625 0.083343505859375 0.050219726562508388 +1.5033750000000002 0.07916259765625 0.083343505859375 0.050219726562508388 +1.5035 0.084075927734375 0.0885009765625 0.050219726562508388 +1.503625 0.088958740234375 0.093658447265625 0.050219726562508388 +1.5037500000000002 0.088958740234375 0.093658447265625 0.050219726562508388 +1.503875 0.093841552734375 0.098785400390625 0.050219726562508388 +1.504 0.05560302734375 0.098785400390625 0.43709106445313256 +1.504125 0.0584716796875 0.103912353515625 0.43709106445313256 +1.50425 0.061370849609375 0.109039306640625 0.43709106445313256 +1.504375 0.061370849609375 0.109039306640625 0.43709106445313256 +1.5045 0.064239501953125 0.1141357421875 0.43709106445313256 +1.504625 0.064239501953125 0.1141357421875 0.43709106445313256 +1.50475 0.067108154296875 0.119232177734375 0.43709106445313256 +1.504875 0.0699462890625 0.124298095703125 0.43709106445313256 +1.5050000000000002 0.0699462890625 0.124298095703125 0.43709106445313256 +1.505125 0.07281494140625 0.129364013671875 0.43709106445313256 +1.50525 0.07281494140625 0.129364013671875 0.43709106445313256 +1.5053750000000002 0.075653076171875 0.134429931640625 0.43709106445313256 +1.5055 0.0784912109375 0.13946533203125 0.43709106445313256 +1.505625 0.0784912109375 0.13946533203125 0.43709106445313256 +1.50575 0.081298828125 0.14447021484375 0.43709106445313256 +1.505875 0.081298828125 0.14447021484375 0.43709106445313256 +1.506 0.084136962890625 0.14947509765625 0.43709106445313256 +1.506125 0.086944580078125 0.15447998046875 0.43709106445313256 +1.50625 0.086944580078125 0.15447998046875 0.43709106445313256 +1.506375 0.0897216796875 0.159454345703125 0.43709106445313256 +1.5065 0.0897216796875 0.159454345703125 0.43709106445313256 +1.506625 0.092529296875 0.164398193359375 0.43709106445313256 +1.50675 0.095306396484375 0.169342041015625 0.43709106445313256 +1.506875 0.095306396484375 0.169342041015625 0.43709106445313256 +1.5070000000000002 0.098052978515625 0.17425537109375 0.43709106445313256 +1.507125 0.098052978515625 0.17425537109375 0.43709106445313256 +1.50725 0.100830078125 0.17913818359375 0.43709106445313256 +1.5073750000000002 0.10357666015625 0.18402099609375 0.43709106445313256 +1.5075 0.10357666015625 0.18402099609375 0.43709106445313256 +1.507625 0.106292724609375 0.188873291015625 0.43709106445313256 +1.50775 0.106292724609375 0.188873291015625 0.43709106445313256 +1.507875 0.1090087890625 0.1937255859375 0.43709106445313256 +1.508 0.111724853515625 0.19854736328125 0.43709106445313256 +1.508125 0.111724853515625 0.19854736328125 0.43709106445313256 +1.50825 0.11444091796875 0.203338623046875 0.43709106445313256 +1.508375 0.11444091796875 0.203338623046875 0.43709106445313256 +1.5085 0.11712646484375 0.208099365234375 0.43709106445313256 +1.508625 0.119781494140625 0.212860107421875 0.43709106445313256 +1.50875 0.119781494140625 0.212860107421875 0.43709106445313256 +1.508875 0.122467041015625 0.21759033203125 0.43709106445313256 +1.5090000000000002 0.122467041015625 0.21759033203125 0.43709106445313256 +1.509125 0.125091552734375 0.2222900390625 0.43709106445313256 +1.50925 0.127716064453125 0.226959228515625 0.43709106445313256 +1.5093750000000002 0.127716064453125 0.226959228515625 0.43709106445313256 +1.5095 0.130340576171875 0.231597900390625 0.43709106445313256 +1.509625 0.130340576171875 0.231597900390625 0.43709106445313256 +1.50975 0.132965087890625 0.236236572265625 0.43709106445313256 +1.509875 0.135528564453125 0.2408447265625 0.43709106445313256 +1.51 0.135528564453125 0.2408447265625 0.43709106445313256 +1.510125 0.13812255859375 0.24542236328125 0.43709106445313256 +1.51025 0.13812255859375 0.24542236328125 0.43709106445313256 +1.510375 0.14068603515625 0.249969482421875 0.43709106445313256 +1.5105 0.143218994140625 0.25445556640625 0.43709106445313256 +1.510625 0.143218994140625 0.25445556640625 0.43709106445313256 +1.51075 0.145751953125 0.25897216796875 0.43709106445313256 +1.510875 0.145751953125 0.25897216796875 0.43709106445313256 +1.5110000000000002 0.14825439453125 0.263427734375 0.43709106445313256 +1.511125 0.1507568359375 0.267852783203125 0.43709106445313256 +1.51125 0.1507568359375 0.267852783203125 0.43709106445313256 +1.5113750000000002 0.153228759765625 0.27227783203125 0.43709106445313256 +1.5115 0.153228759765625 0.27227783203125 0.43709106445313256 +1.511625 0.15570068359375 0.276641845703125 0.43709106445313256 +1.51175 0.15814208984375 0.280975341796875 0.43709106445313256 +1.511875 0.15814208984375 0.280975341796875 0.43709106445313256 +1.512 0.16058349609375 0.285308837890625 0.43709106445313256 +1.512125 0.16058349609375 0.285308837890625 0.43709106445313256 +1.51225 0.162994384765625 0.289581298828125 0.43709106445313256 +1.512375 0.165374755859375 0.2938232421875 0.43709106445313256 +1.5125 0.165374755859375 0.2938232421875 0.43709106445313256 +1.512625 0.167755126953125 0.298065185546875 0.43709106445313256 +1.51275 0.167755126953125 0.298065185546875 0.43709106445313256 +1.512875 0.17010498046875 0.30224609375 0.43709106445313256 +1.5130000000000002 0.172454833984375 0.306396484375 0.43709106445313256 +1.513125 0.172454833984375 0.306396484375 0.43709106445313256 +1.51325 0.174774169921875 0.310516357421875 0.43709106445313256 +1.5133750000000002 0.174774169921875 0.310516357421875 0.43709106445313256 +1.5135 0.17706298828125 0.314605712890625 0.43709106445313256 +1.513625 0.179351806640625 0.31866455078125 0.43709106445313256 +1.51375 0.179351806640625 0.31866455078125 0.43709106445313256 +1.513875 0.181610107421875 0.322662353515625 0.43709106445313256 +1.514 0.181610107421875 0.322662353515625 0.43709106445313256 +1.514125 0.183837890625 0.32666015625 0.43709106445313256 +1.51425 0.186065673828125 0.330596923828125 0.43709106445313256 +1.514375 0.186065673828125 0.330596923828125 0.43709106445313256 +1.5145 0.188262939453125 0.334503173828125 0.43709106445313256 +1.514625 0.188262939453125 0.334503173828125 0.43709106445313256 +1.51475 0.190460205078125 0.33837890625 0.43709106445313256 +1.514875 0.192596435546875 0.34222412109375 0.43709106445313256 +1.5150000000000002 0.192596435546875 0.34222412109375 0.43709106445313256 +1.515125 0.194732666015625 0.34600830078125 0.43709106445313256 +1.51525 0.194732666015625 0.34600830078125 0.43709106445313256 +1.5153750000000002 0.196868896484375 0.349761962890625 0.43709106445313256 +1.5155 0.198944091796875 0.353485107421875 0.43709106445313256 +1.515625 0.198944091796875 0.353485107421875 0.43709106445313256 +1.51575 0.201019287109375 0.357177734375 0.43709106445313256 +1.515875 0.201019287109375 0.357177734375 0.43709106445313256 +1.516 0.20306396484375 0.360809326171875 0.43709106445313256 +1.516125 0.205108642578125 0.36444091796875 0.43709106445313256 +1.51625 0.205108642578125 0.36444091796875 0.43709106445313256 +1.516375 0.207122802734375 0.36798095703125 0.43709106445313256 +1.5165 0.207122802734375 0.36798095703125 0.43709106445313256 +1.5166250000000002 0.2091064453125 0.37152099609375 0.43709106445313256 +1.51675 0.2110595703125 0.375 0.43709106445313256 +1.516875 0.2110595703125 0.375 0.43709106445313256 +1.5170000000000002 0.212982177734375 0.378448486328125 0.43709106445313256 +1.517125 0.212982177734375 0.378448486328125 0.43709106445313256 +1.51725 0.21490478515625 0.3818359375 0.43709106445313256 +1.5173750000000002 0.216796875 0.38519287109375 0.43709106445313256 +1.5175 0.216796875 0.38519287109375 0.43709106445313256 +1.517625 0.218658447265625 0.388519287109375 0.43709106445313256 +1.51775 0.218658447265625 0.388519287109375 0.43709106445313256 +1.517875 0.22052001953125 0.39178466796875 0.43709106445313256 +1.518 0.222320556640625 0.39501953125 0.43709106445313256 +1.518125 0.222320556640625 0.39501953125 0.43709106445313256 +1.51825 0.22412109375 0.398193359375 0.43709106445313256 +1.518375 0.22412109375 0.398193359375 0.43709106445313256 +1.5185 0.22589111328125 0.401336669921875 0.43709106445313256 +1.5186250000000002 0.227630615234375 0.404449462890625 0.43709106445313256 +1.51875 0.227630615234375 0.404449462890625 0.43709106445313256 +1.518875 0.229339599609375 0.407501220703125 0.43709106445313256 +1.5190000000000002 0.229339599609375 0.407501220703125 0.43709106445313256 +1.519125 0.231048583984375 0.4105224609375 0.43709106445313256 +1.51925 0.23272705078125 0.413482666015625 0.43709106445313256 +1.5193750000000002 0.23272705078125 0.413482666015625 0.43709106445313256 +1.5195 0.234375 0.416412353515625 0.43709106445313256 +1.519625 0.234375 0.416412353515625 0.43709106445313256 +1.51975 0.2359619140625 0.419281005859375 0.43709106445313256 +1.519875 0.237579345703125 0.422119140625 0.43709106445313256 +1.52 0.237579345703125 0.422119140625 0.43709106445313256 +1.520125 0.2391357421875 0.424896240234375 0.43709106445313256 +1.52025 0.2391357421875 0.424896240234375 0.43709106445313256 +1.520375 0.24066162109375 0.4276123046875 0.43709106445313256 +1.5205 0.2421875 0.4302978515625 0.43709106445313256 +1.5206250000000002 0.2421875 0.4302978515625 0.43709106445313256 +1.52075 0.243682861328125 0.432952880859375 0.43709106445313256 +1.520875 0.243682861328125 0.432952880859375 0.43709106445313256 +1.5210000000000002 0.245147705078125 0.435546875 0.43709106445313256 +1.521125 0.246551513671875 0.438079833984375 0.43709106445313256 +1.52125 0.246551513671875 0.438079833984375 0.43709106445313256 +1.521375 0.24798583984375 0.440582275390625 0.43709106445313256 +1.5215 0.24798583984375 0.440582275390625 0.43709106445313256 +1.521625 0.249359130859375 0.44305419921875 0.43709106445313256 +1.52175 0.250701904296875 0.4454345703125 0.43709106445313256 +1.521875 0.250701904296875 0.4454345703125 0.43709106445313256 +1.522 0.25201416015625 0.447784423828125 0.43709106445313256 +1.522125 0.25201416015625 0.447784423828125 0.43709106445313256 +1.52225 0.253326416015625 0.450103759765625 0.43709106445313256 +1.522375 0.254608154296875 0.452362060546875 0.43709106445313256 +1.5225 0.254608154296875 0.452362060546875 0.43709106445313256 +1.5226250000000002 0.255828857421875 0.454559326171875 0.43709106445313256 +1.52275 0.255828857421875 0.454559326171875 0.43709106445313256 +1.522875 0.257049560546875 0.45672607421875 0.43709106445313256 +1.5230000000000002 0.25823974609375 0.458831787109375 0.43709106445313256 +1.523125 0.25823974609375 0.458831787109375 0.43709106445313256 +1.52325 0.2593994140625 0.46087646484375 0.43709106445313256 +1.523375 0.2593994140625 0.46087646484375 0.43709106445313256 +1.5235 0.260528564453125 0.462890625 0.43709106445313256 +1.523625 0.2615966796875 0.464813232421875 0.43709106445313256 +1.52375 0.2615966796875 0.464813232421875 0.43709106445313256 +1.523875 0.2626953125 0.46673583984375 0.43709106445313256 +1.524 0.2626953125 0.46673583984375 0.43709106445313256 +1.524125 0.26373291015625 0.46856689453125 0.43709106445313256 +1.52425 0.264739990234375 0.470367431640625 0.43709106445313256 +1.524375 0.264739990234375 0.470367431640625 0.43709106445313256 +1.5245 0.265716552734375 0.472137451171875 0.43709106445313256 +1.5246250000000002 0.265716552734375 0.472137451171875 0.43709106445313256 +1.52475 0.26666259765625 0.47381591796875 0.43709106445313256 +1.524875 0.267608642578125 0.4754638671875 0.43709106445313256 +1.5250000000000002 0.267608642578125 0.4754638671875 0.43709106445313256 +1.525125 0.26849365234375 0.47705078125 0.43709106445313256 +1.52525 0.26849365234375 0.47705078125 0.43709106445313256 +1.525375 0.269378662109375 0.478607177734375 0.43709106445313256 +1.5255 0.27020263671875 0.480072021484375 0.43709106445313256 +1.525625 0.27020263671875 0.480072021484375 0.43709106445313256 +1.52575 0.27099609375 0.48150634765625 0.43709106445313256 +1.525875 0.27099609375 0.48150634765625 0.43709106445313256 +1.526 0.27178955078125 0.48291015625 0.43709106445313256 +1.526125 0.27252197265625 0.484222412109375 0.43709106445313256 +1.52625 0.27252197265625 0.484222412109375 0.43709106445313256 +1.526375 0.27325439453125 0.485504150390625 0.43709106445313256 +1.5265 0.27325439453125 0.485504150390625 0.43709106445313256 +1.5266250000000002 0.273956298828125 0.486724853515625 0.43709106445313256 +1.52675 0.27459716796875 0.487884521484375 0.43709106445313256 +1.526875 0.27459716796875 0.487884521484375 0.43709106445313256 +1.5270000000000002 0.27520751953125 0.489013671875 0.43709106445313256 +1.527125 0.27520751953125 0.489013671875 0.43709106445313256 +1.52725 0.27581787109375 0.490081787109375 0.43709106445313256 +1.527375 0.276397705078125 0.4910888671875 0.43709106445313256 +1.5275 0.276397705078125 0.4910888671875 0.43709106445313256 +1.527625 0.27691650390625 0.492034912109375 0.43709106445313256 +1.52775 0.27691650390625 0.492034912109375 0.43709106445313256 +1.527875 0.277435302734375 0.492950439453125 0.43709106445313256 +1.528 0.277923583984375 0.4937744140625 0.43709106445313256 +1.528125 0.277923583984375 0.4937744140625 0.43709106445313256 +1.52825 0.278350830078125 0.49456787109375 0.43709106445313256 +1.528375 0.278350830078125 0.49456787109375 0.43709106445313256 +1.5285 0.278778076171875 0.49530029296875 0.43709106445313256 +1.5286250000000002 0.279144287109375 0.496002197265625 0.43709106445313256 +1.52875 0.279144287109375 0.496002197265625 0.43709106445313256 +1.528875 0.279510498046875 0.496612548828125 0.43709106445313256 +1.5290000000000002 0.279510498046875 0.496612548828125 0.43709106445313256 +1.529125 0.27984619140625 0.4971923828125 0.43709106445313256 +1.52925 0.280120849609375 0.497711181640625 0.43709106445313256 +1.529375 0.280120849609375 0.497711181640625 0.43709106445313256 +1.5295 0.2803955078125 0.498199462890625 0.43709106445313256 +1.529625 0.2803955078125 0.498199462890625 0.43709106445313256 +1.52975 0.280609130859375 0.49859619140625 0.43709106445313256 +1.529875 0.28082275390625 0.49896240234375 0.43709106445313256 +1.53 0.28082275390625 0.49896240234375 0.43709106445313256 +1.530125 0.281005859375 0.499267578125 0.43709106445313256 +1.53025 0.281005859375 0.499267578125 0.43709106445313256 +1.530375 0.2811279296875 0.49951171875 0.43709106445313256 +1.5305 0.281219482421875 0.49969482421875 0.43709106445313256 +1.5306250000000002 0.281219482421875 0.49969482421875 0.43709106445313256 +1.53075 0.28131103515625 0.49981689453125 0.43709106445313256 +1.530875 0.28131103515625 0.49981689453125 0.43709106445313256 +1.5310000000000002 0.2813720703125 0.499908447265625 0.43709106445313256 +1.531125 0.2813720703125 0.49993896484375 0.43709106445313256 +1.53125 0.2813720703125 0.49993896484375 0.43709106445313256 +1.531375 0.2813720703125 0.499908447265625 0.43709106445313256 +1.5315 0.2813720703125 0.499908447265625 0.43709106445313256 +1.531625 0.28131103515625 0.49981689453125 0.43709106445313256 +1.53175 0.281219482421875 0.49969482421875 0.43709106445313256 +1.531875 0.281219482421875 0.49969482421875 0.43709106445313256 +1.532 0.2811279296875 0.49951171875 0.43709106445313256 +1.532125 0.2811279296875 0.49951171875 0.43709106445313256 +1.5322500000000002 0.281005859375 0.499267578125 0.43709106445313256 +1.532375 0.28082275390625 0.49896240234375 0.43709106445313256 +1.5325 0.28082275390625 0.49896240234375 0.43709106445313256 +1.5326250000000002 0.280609130859375 0.49859619140625 0.43709106445313256 +1.53275 0.280609130859375 0.49859619140625 0.43709106445313256 +1.532875 0.2803955078125 0.498199462890625 0.43709106445313256 +1.5330000000000002 0.280120849609375 0.497711181640625 0.43709106445313256 +1.533125 0.280120849609375 0.497711181640625 0.43709106445313256 +1.53325 0.27984619140625 0.4971923828125 0.43709106445313256 +1.533375 0.27984619140625 0.4971923828125 0.43709106445313256 +1.5335 0.279510498046875 0.496612548828125 0.43709106445313256 +1.533625 0.279144287109375 0.496002197265625 0.43709106445313256 +1.53375 0.279144287109375 0.496002197265625 0.43709106445313256 +1.533875 0.278778076171875 0.49530029296875 0.43709106445313256 +1.534 0.278778076171875 0.49530029296875 0.43709106445313256 +1.534125 0.278350830078125 0.49456787109375 0.43709106445313256 +1.5342500000000002 0.277923583984375 0.4937744140625 0.43709106445313256 +1.534375 0.277923583984375 0.4937744140625 0.43709106445313256 +1.5345 0.277435302734375 0.492950439453125 0.43709106445313256 +1.5346250000000002 0.277435302734375 0.492950439453125 0.43709106445313256 +1.53475 0.27691650390625 0.492034912109375 0.43709106445313256 +1.534875 0.276397705078125 0.4910888671875 0.43709106445313256 +1.5350000000000002 0.276397705078125 0.4910888671875 0.43709106445313256 +1.535125 0.27581787109375 0.490081787109375 0.43709106445313256 +1.53525 0.27581787109375 0.490081787109375 0.43709106445313256 +1.535375 0.27520751953125 0.489013671875 0.43709106445313256 +1.5355 0.27459716796875 0.487884521484375 0.43709106445313256 +1.535625 0.27459716796875 0.487884521484375 0.43709106445313256 +1.53575 0.273956298828125 0.486724853515625 0.43709106445313256 +1.535875 0.273956298828125 0.486724853515625 0.43709106445313256 +1.536 0.119293212890625 0.485504150390625 0.7541992187500055 +1.536125 0.11895751953125 0.484222412109375 0.7541992187500055 +1.5362500000000002 0.11895751953125 0.484222412109375 0.7541992187500055 +1.536375 0.11865234375 0.48291015625 0.7541992187500055 +1.5365 0.11865234375 0.48291015625 0.7541992187500055 +1.5366250000000002 0.1182861328125 0.48150634765625 0.7541992187500055 +1.53675 0.117950439453125 0.480072021484375 0.7541992187500055 +1.536875 0.117950439453125 0.480072021484375 0.7541992187500055 +1.537 0.117584228515625 0.478607177734375 0.7541992187500055 +1.537125 0.117584228515625 0.478607177734375 0.7541992187500055 +1.53725 0.117218017578125 0.47705078125 0.7541992187500055 +1.537375 0.1168212890625 0.4754638671875 0.7541992187500055 +1.5375 0.1168212890625 0.4754638671875 0.7541992187500055 +1.537625 0.116424560546875 0.47381591796875 0.7541992187500055 +1.53775 0.116424560546875 0.47381591796875 0.7541992187500055 +1.537875 0.115997314453125 0.472137451171875 0.7541992187500055 +1.538 0.115570068359375 0.470367431640625 0.7541992187500055 +1.538125 0.115570068359375 0.470367431640625 0.7541992187500055 +1.5382500000000002 0.1151123046875 0.46856689453125 0.7541992187500055 +1.538375 0.1151123046875 0.46856689453125 0.7541992187500055 +1.5385 0.114654541015625 0.46673583984375 0.7541992187500055 +1.5386250000000002 0.11419677734375 0.464813232421875 0.7541992187500055 +1.53875 0.11419677734375 0.464813232421875 0.7541992187500055 +1.538875 0.11370849609375 0.462890625 0.7541992187500055 +1.539 0.11370849609375 0.462890625 0.7541992187500055 +1.539125 0.11322021484375 0.46087646484375 0.7541992187500055 +1.53925 0.11273193359375 0.458831787109375 0.7541992187500055 +1.539375 0.11273193359375 0.458831787109375 0.7541992187500055 +1.5395 0.112213134765625 0.45672607421875 0.7541992187500055 +1.539625 0.112213134765625 0.45672607421875 0.7541992187500055 +1.53975 0.111663818359375 0.454559326171875 0.7541992187500055 +1.539875 0.11114501953125 0.452362060546875 0.7541992187500055 +1.54 0.11114501953125 0.452362060546875 0.7541992187500055 +1.540125 0.110595703125 0.450103759765625 0.7541992187500055 +1.5402500000000002 0.110595703125 0.450103759765625 0.7541992187500055 +1.540375 0.110015869140625 0.447784423828125 0.7541992187500055 +1.5405 0.10943603515625 0.4454345703125 0.7541992187500055 +1.5406250000000002 0.10943603515625 0.4454345703125 0.7541992187500055 +1.54075 0.108856201171875 0.44305419921875 0.7541992187500055 +1.540875 0.108856201171875 0.44305419921875 0.7541992187500055 +1.541 0.108245849609375 0.440582275390625 0.7541992187500055 +1.541125 0.107635498046875 0.438079833984375 0.7541992187500055 +1.54125 0.107635498046875 0.438079833984375 0.7541992187500055 +1.541375 0.10699462890625 0.435546875 0.7541992187500055 +1.5415 0.10699462890625 0.435546875 0.7541992187500055 +1.541625 0.10638427734375 0.432952880859375 0.7541992187500055 +1.54175 0.105712890625 0.4302978515625 0.7541992187500055 +1.541875 0.105712890625 0.4302978515625 0.7541992187500055 +1.542 0.105072021484375 0.4276123046875 0.7541992187500055 +1.542125 0.105072021484375 0.4276123046875 0.7541992187500055 +1.5422500000000002 0.104400634765625 0.424896240234375 0.7541992187500055 +1.542375 0.10369873046875 0.422119140625 0.7541992187500055 +1.5425 0.10369873046875 0.422119140625 0.7541992187500055 +1.5426250000000002 0.102996826171875 0.419281005859375 0.7541992187500055 +1.54275 0.102996826171875 0.419281005859375 0.7541992187500055 +1.542875 0.102294921875 0.416412353515625 0.7541992187500055 +1.543 0.101593017578125 0.413482666015625 0.7541992187500055 +1.543125 0.101593017578125 0.413482666015625 0.7541992187500055 +1.54325 0.100860595703125 0.4105224609375 0.7541992187500055 +1.543375 0.100860595703125 0.4105224609375 0.7541992187500055 +1.5435 0.100128173828125 0.407501220703125 0.7541992187500055 +1.543625 0.099365234375 0.404449462890625 0.7541992187500055 +1.54375 0.099365234375 0.404449462890625 0.7541992187500055 +1.543875 0.098602294921875 0.401336669921875 0.7541992187500055 +1.544 0.098602294921875 0.401336669921875 0.7541992187500055 +1.544125 0.09783935546875 0.398193359375 0.7541992187500055 +1.5442500000000002 0.0970458984375 0.39501953125 0.7541992187500055 +1.544375 0.0970458984375 0.39501953125 0.7541992187500055 +1.5445 0.09625244140625 0.39178466796875 0.7541992187500055 +1.5446250000000002 0.09625244140625 0.39178466796875 0.7541992187500055 +1.54475 0.095458984375 0.388519287109375 0.7541992187500055 +1.544875 0.094635009765625 0.38519287109375 0.7541992187500055 +1.545 0.094635009765625 0.38519287109375 0.7541992187500055 +1.545125 0.09381103515625 0.3818359375 0.7541992187500055 +1.54525 0.09381103515625 0.3818359375 0.7541992187500055 +1.545375 0.092987060546875 0.378448486328125 0.7541992187500055 +1.5455 0.092132568359375 0.375 0.7541992187500055 +1.545625 0.092132568359375 0.375 0.7541992187500055 +1.54575 0.091278076171875 0.37152099609375 0.7541992187500055 +1.545875 0.091278076171875 0.37152099609375 0.7541992187500055 +1.546 0.09039306640625 0.36798095703125 0.7541992187500055 +1.546125 0.08953857421875 0.36444091796875 0.7541992187500055 +1.5462500000000002 0.08953857421875 0.36444091796875 0.7541992187500055 +1.546375 0.088653564453125 0.360809326171875 0.7541992187500055 +1.5465 0.088653564453125 0.360809326171875 0.7541992187500055 +1.5466250000000002 0.0877685546875 0.357177734375 0.7541992187500055 +1.54675 0.08685302734375 0.353485107421875 0.7541992187500055 +1.546875 0.08685302734375 0.353485107421875 0.7541992187500055 +1.547 0.0859375 0.349761962890625 0.7541992187500055 +1.547125 0.0859375 0.349761962890625 0.7541992187500055 +1.54725 0.08502197265625 0.34600830078125 0.7541992187500055 +1.547375 0.084075927734375 0.34222412109375 0.7541992187500055 +1.5475 0.084075927734375 0.34222412109375 0.7541992187500055 +1.547625 0.0831298828125 0.33837890625 0.7541992187500055 +1.54775 0.0831298828125 0.33837890625 0.7541992187500055 +1.5478750000000002 0.082183837890625 0.334503173828125 0.7541992187500055 +1.548 0.08123779296875 0.330596923828125 0.7541992187500055 +1.548125 0.08123779296875 0.330596923828125 0.7541992187500055 +1.5482500000000002 0.08026123046875 0.32666015625 0.7541992187500055 +1.548375 0.08026123046875 0.32666015625 0.7541992187500055 +1.5485 0.07928466796875 0.322662353515625 0.7541992187500055 +1.5486250000000002 0.078277587890625 0.31866455078125 0.7541992187500055 +1.54875 0.078277587890625 0.31866455078125 0.7541992187500055 +1.548875 0.077301025390625 0.314605712890625 0.7541992187500055 +1.549 0.077301025390625 0.314605712890625 0.7541992187500055 +1.549125 0.0762939453125 0.310516357421875 0.7541992187500055 +1.54925 0.075286865234375 0.306396484375 0.7541992187500055 +1.549375 0.075286865234375 0.306396484375 0.7541992187500055 +1.5495 0.074249267578125 0.30224609375 0.7541992187500055 +1.549625 0.074249267578125 0.30224609375 0.7541992187500055 +1.54975 0.073211669921875 0.298065185546875 0.7541992187500055 +1.5498750000000002 0.072174072265625 0.2938232421875 0.7541992187500055 +1.55 0.072174072265625 0.2938232421875 0.7541992187500055 +1.550125 0.071136474609375 0.289581298828125 0.7541992187500055 +1.5502500000000002 0.071136474609375 0.289581298828125 0.7541992187500055 +1.550375 0.070098876953125 0.285308837890625 0.7541992187500055 +1.5505 0.06903076171875 0.280975341796875 0.7541992187500055 +1.5506250000000002 0.06903076171875 0.280975341796875 0.7541992187500055 +1.55075 0.067962646484375 0.276641845703125 0.7541992187500055 +1.550875 0.067962646484375 0.276641845703125 0.7541992187500055 +1.551 0.06689453125 0.27227783203125 0.7541992187500055 +1.551125 0.0657958984375 0.267852783203125 0.7541992187500055 +1.55125 0.0657958984375 0.267852783203125 0.7541992187500055 +1.551375 0.064727783203125 0.263427734375 0.7541992187500055 +1.5515 0.064727783203125 0.263427734375 0.7541992187500055 +1.551625 0.063629150390625 0.25897216796875 0.7541992187500055 +1.55175 0.0625 0.25445556640625 0.7541992187500055 +1.5518750000000002 0.0625 0.25445556640625 0.7541992187500055 +1.552 0.0614013671875 0.249969482421875 0.7541992187500055 +1.552125 0.0614013671875 0.249969482421875 0.7541992187500055 +1.5522500000000002 0.060302734375 0.24542236328125 0.7541992187500055 +1.552375 0.059173583984375 0.2408447265625 0.7541992187500055 +1.5525 0.059173583984375 0.2408447265625 0.7541992187500055 +1.552625 0.05804443359375 0.236236572265625 0.7541992187500055 +1.55275 0.05804443359375 0.236236572265625 0.7541992187500055 +1.552875 0.056884765625 0.231597900390625 0.7541992187500055 +1.553 0.055755615234375 0.226959228515625 0.7541992187500055 +1.553125 0.055755615234375 0.226959228515625 0.7541992187500055 +1.55325 0.054595947265625 0.2222900390625 0.7541992187500055 +1.553375 0.054595947265625 0.2222900390625 0.7541992187500055 +1.5535 0.053436279296875 0.21759033203125 0.7541992187500055 +1.553625 0.052276611328125 0.212860107421875 0.7541992187500055 +1.55375 0.052276611328125 0.212860107421875 0.7541992187500055 +1.5538750000000002 0.051116943359375 0.208099365234375 0.7541992187500055 +1.554 0.051116943359375 0.208099365234375 0.7541992187500055 +1.554125 0.049957275390625 0.203338623046875 0.7541992187500055 +1.5542500000000002 0.04876708984375 0.19854736328125 0.7541992187500055 +1.554375 0.04876708984375 0.19854736328125 0.7541992187500055 +1.5545 0.047576904296875 0.1937255859375 0.7541992187500055 +1.554625 0.047576904296875 0.1937255859375 0.7541992187500055 +1.55475 0.04638671875 0.188873291015625 0.7541992187500055 +1.554875 0.045196533203125 0.18402099609375 0.7541992187500055 +1.555 0.045196533203125 0.18402099609375 0.7541992187500055 +1.555125 0.04400634765625 0.17913818359375 0.7541992187500055 +1.55525 0.04400634765625 0.17913818359375 0.7541992187500055 +1.555375 0.042816162109375 0.17425537109375 0.7541992187500055 +1.5555 0.041595458984375 0.169342041015625 0.7541992187500055 +1.555625 0.041595458984375 0.169342041015625 0.7541992187500055 +1.55575 0.040374755859375 0.164398193359375 0.7541992187500055 +1.5558750000000002 0.040374755859375 0.164398193359375 0.7541992187500055 +1.556 0.039154052734375 0.159454345703125 0.7541992187500055 +1.556125 0.037933349609375 0.15447998046875 0.7541992187500055 +1.5562500000000002 0.037933349609375 0.15447998046875 0.7541992187500055 +1.556375 0.036712646484375 0.14947509765625 0.7541992187500055 +1.5565 0.036712646484375 0.14947509765625 0.7541992187500055 +1.556625 0.035491943359375 0.14447021484375 0.7541992187500055 +1.55675 0.03424072265625 0.13946533203125 0.7541992187500055 +1.556875 0.03424072265625 0.13946533203125 0.7541992187500055 +1.557 0.03302001953125 0.134429931640625 0.7541992187500055 +1.557125 0.03302001953125 0.134429931640625 0.7541992187500055 +1.55725 0.031768798828125 0.129364013671875 0.7541992187500055 +1.557375 0.030517578125 0.124298095703125 0.7541992187500055 +1.5575 0.030517578125 0.124298095703125 0.7541992187500055 +1.557625 0.029296875 0.119232177734375 0.7541992187500055 +1.55775 0.029296875 0.119232177734375 0.7541992187500055 +1.5578750000000002 0.028045654296875 0.1141357421875 0.7541992187500055 +1.558 0.026763916015625 0.109039306640625 0.7541992187500055 +1.558125 0.026763916015625 0.109039306640625 0.7541992187500055 +1.5582500000000002 0.0255126953125 0.103912353515625 0.7541992187500055 +1.558375 0.0255126953125 0.103912353515625 0.7541992187500055 +1.5585 0.024261474609375 0.098785400390625 0.7541992187500055 +1.558625 0.02301025390625 0.093658447265625 0.7541992187500055 +1.55875 0.02301025390625 0.093658447265625 0.7541992187500055 +1.558875 0.021728515625 0.0885009765625 0.7541992187500055 +1.559 0.021728515625 0.0885009765625 0.7541992187500055 +1.559125 0.020477294921875 0.083343505859375 0.7541992187500055 +1.55925 0.019195556640625 0.07818603515625 0.7541992187500055 +1.559375 0.019195556640625 0.07818603515625 0.7541992187500055 +1.5595 0.017913818359375 0.072998046875 0.7541992187500055 +1.559625 0.017913818359375 0.072998046875 0.7541992187500055 +1.55975 0.01666259765625 0.06781005859375 0.7541992187500055 +1.5598750000000002 0.015380859375 0.0626220703125 0.7541992187500055 +1.56 0.015380859375 0.0626220703125 0.7541992187500055 +1.560125 0.01409912109375 0.05743408203125 0.7541992187500055 +1.5602500000000002 0.01409912109375 0.05743408203125 0.7541992187500055 +1.560375 0.0128173828125 0.05224609375 0.7541992187500055 +1.5605 0.01153564453125 0.047027587890625 0.7541992187500055 +1.560625 0.01153564453125 0.047027587890625 0.7541992187500055 +1.56075 0.01025390625 0.04180908203125 0.7541992187500055 +1.560875 0.01025390625 0.04180908203125 0.7541992187500055 +1.561 0.00897216796875 0.036590576171875 0.7541992187500055 +1.561125 0.0076904296875 0.0313720703125 0.7541992187500055 +1.56125 0.0076904296875 0.0313720703125 0.7541992187500055 +1.561375 0.00640869140625 0.026123046875 0.7541992187500055 +1.5615 0.00640869140625 0.026123046875 0.7541992187500055 +1.561625 0.005126953125 0.020904541015625 0.7541992187500055 +1.56175 0.00384521484375 0.01568603515625 0.7541992187500055 +1.5618750000000002 0.00384521484375 0.01568603515625 0.7541992187500055 +1.562 0.0025634765625 0.01043701171875 0.7541992187500055 +1.562125 0.0025634765625 0.01043701171875 0.7541992187500055 +1.5622500000000002 0.00128173828125 0.005218505859375 0.7541992187500055 +1.562375 0.0 0.0 0.7541992187500055 +1.5625 0.0 0.0 0.7541992187500055 +1.562625 -0.00128173828125 -0.005218505859375 0.7541992187500055 +1.56275 -0.00128173828125 -0.005218505859375 0.7541992187500055 +1.562875 -0.0025634765625 -0.01043701171875 0.7541992187500055 +1.563 -0.00384521484375 -0.01568603515625 0.7541992187500055 +1.563125 -0.00384521484375 -0.01568603515625 0.7541992187500055 +1.56325 -0.005126953125 -0.020904541015625 0.7541992187500055 +1.563375 -0.005126953125 -0.020904541015625 0.7541992187500055 +1.5635000000000002 -0.00640869140625 -0.026123046875 0.7541992187500055 +1.563625 -0.0076904296875 -0.0313720703125 0.7541992187500055 +1.56375 -0.0076904296875 -0.0313720703125 0.7541992187500055 +1.5638750000000002 -0.00897216796875 -0.036590576171875 0.7541992187500055 +1.564 -0.00897216796875 -0.036590576171875 0.7541992187500055 +1.564125 -0.01025390625 -0.04180908203125 0.7541992187500055 +1.5642500000000002 -0.01153564453125 -0.047027587890625 0.7541992187500055 +1.564375 -0.01153564453125 -0.047027587890625 0.7541992187500055 +1.5645 -0.0128173828125 -0.05224609375 0.7541992187500055 +1.564625 -0.0128173828125 -0.05224609375 0.7541992187500055 +1.56475 -0.01409912109375 -0.05743408203125 0.7541992187500055 +1.564875 -0.015380859375 -0.0626220703125 0.7541992187500055 +1.565 -0.015380859375 -0.0626220703125 0.7541992187500055 +1.565125 -0.01666259765625 -0.06781005859375 0.7541992187500055 +1.56525 -0.01666259765625 -0.06781005859375 0.7541992187500055 +1.565375 -0.017913818359375 -0.072998046875 0.7541992187500055 +1.5655000000000002 -0.019195556640625 -0.07818603515625 0.7541992187500055 +1.565625 -0.019195556640625 -0.07818603515625 0.7541992187500055 +1.56575 -0.020477294921875 -0.083343505859375 0.7541992187500055 +1.5658750000000002 -0.020477294921875 -0.083343505859375 0.7541992187500055 +1.566 -0.021728515625 -0.0885009765625 0.7541992187500055 +1.566125 -0.02301025390625 -0.093658447265625 0.7541992187500055 +1.5662500000000002 -0.02301025390625 -0.093658447265625 0.7541992187500055 +1.566375 -0.024261474609375 -0.098785400390625 0.7541992187500055 +1.5665 -0.024261474609375 -0.098785400390625 0.7541992187500055 +1.566625 -0.0255126953125 -0.103912353515625 0.7541992187500055 +1.56675 -0.026763916015625 -0.109039306640625 0.7541992187500055 +1.566875 -0.026763916015625 -0.109039306640625 0.7541992187500055 +1.567 -0.028045654296875 -0.1141357421875 0.7541992187500055 +1.567125 -0.028045654296875 -0.1141357421875 0.7541992187500055 +1.56725 -0.029296875 -0.119232177734375 0.7541992187500055 +1.567375 -0.030517578125 -0.124298095703125 0.7541992187500055 +1.5675000000000002 -0.030517578125 -0.124298095703125 0.7541992187500055 +1.567625 -0.031768798828125 -0.129364013671875 0.7541992187500055 +1.56775 -0.031768798828125 -0.129364013671875 0.7541992187500055 +1.5678750000000002 -0.03302001953125 -0.134429931640625 0.7541992187500055 +1.568 -0.006805419921875 -0.13946533203125 0.9510192871093776 +1.568125 -0.006805419921875 -0.13946533203125 0.9510192871093776 +1.56825 -0.007049560546875 -0.14447021484375 0.9510192871093776 +1.568375 -0.007049560546875 -0.14447021484375 0.9510192871093776 +1.5685 -0.007293701171875 -0.14947509765625 0.9510192871093776 +1.568625 -0.007537841796875 -0.15447998046875 0.9510192871093776 +1.56875 -0.007537841796875 -0.15447998046875 0.9510192871093776 +1.568875 -0.007781982421875 -0.159454345703125 0.9510192871093776 +1.569 -0.007781982421875 -0.159454345703125 0.9510192871093776 +1.569125 -0.008026123046875 -0.164398193359375 0.9510192871093776 +1.56925 -0.008270263671875 -0.169342041015625 0.9510192871093776 +1.569375 -0.008270263671875 -0.169342041015625 0.9510192871093776 +1.5695000000000002 -0.008514404296875 -0.17425537109375 0.9510192871093776 +1.569625 -0.008514404296875 -0.17425537109375 0.9510192871093776 +1.56975 -0.008758544921875 -0.17913818359375 0.9510192871093776 +1.5698750000000002 -0.00897216796875 -0.18402099609375 0.9510192871093776 +1.57 -0.00897216796875 -0.18402099609375 0.9510192871093776 +1.570125 -0.00921630859375 -0.188873291015625 0.9510192871093776 +1.57025 -0.00921630859375 -0.188873291015625 0.9510192871093776 +1.570375 -0.00946044921875 -0.1937255859375 0.9510192871093776 +1.5705 -0.00970458984375 -0.19854736328125 0.9510192871093776 +1.570625 -0.00970458984375 -0.19854736328125 0.9510192871093776 +1.57075 -0.009918212890625 -0.203338623046875 0.9510192871093776 +1.570875 -0.009918212890625 -0.203338623046875 0.9510192871093776 +1.571 -0.010162353515625 -0.208099365234375 0.9510192871093776 +1.571125 -0.010406494140625 -0.212860107421875 0.9510192871093776 +1.57125 -0.010406494140625 -0.212860107421875 0.9510192871093776 +1.571375 -0.0106201171875 -0.21759033203125 0.9510192871093776 +1.5715000000000002 -0.0106201171875 -0.21759033203125 0.9510192871093776 +1.571625 -0.0108642578125 -0.2222900390625 0.9510192871093776 +1.57175 -0.011077880859375 -0.226959228515625 0.9510192871093776 +1.5718750000000002 -0.011077880859375 -0.226959228515625 0.9510192871093776 +1.572 -0.011322021484375 -0.231597900390625 0.9510192871093776 +1.572125 -0.011322021484375 -0.231597900390625 0.9510192871093776 +1.57225 -0.01153564453125 -0.236236572265625 0.9510192871093776 +1.572375 -0.011749267578125 -0.2408447265625 0.9510192871093776 +1.5725 -0.011749267578125 -0.2408447265625 0.9510192871093776 +1.572625 -0.011993408203125 -0.24542236328125 0.9510192871093776 +1.57275 -0.011993408203125 -0.24542236328125 0.9510192871093776 +1.572875 -0.01220703125 -0.249969482421875 0.9510192871093776 +1.573 -0.012420654296875 -0.25445556640625 0.9510192871093776 +1.573125 -0.012420654296875 -0.25445556640625 0.9510192871093776 +1.57325 -0.01263427734375 -0.25897216796875 0.9510192871093776 +1.573375 -0.01263427734375 -0.25897216796875 0.9510192871093776 +1.5735000000000002 -0.01287841796875 -0.263427734375 0.9510192871093776 +1.573625 -0.013092041015625 -0.267852783203125 0.9510192871093776 +1.57375 -0.013092041015625 -0.267852783203125 0.9510192871093776 +1.5738750000000002 -0.0133056640625 -0.27227783203125 0.9510192871093776 +1.574 -0.0133056640625 -0.27227783203125 0.9510192871093776 +1.574125 -0.013519287109375 -0.276641845703125 0.9510192871093776 +1.57425 -0.01373291015625 -0.280975341796875 0.9510192871093776 +1.574375 -0.01373291015625 -0.280975341796875 0.9510192871093776 +1.5745 -0.013946533203125 -0.285308837890625 0.9510192871093776 +1.574625 -0.013946533203125 -0.285308837890625 0.9510192871093776 +1.57475 -0.014129638671875 -0.289581298828125 0.9510192871093776 +1.574875 -0.01434326171875 -0.2938232421875 0.9510192871093776 +1.575 -0.01434326171875 -0.2938232421875 0.9510192871093776 +1.575125 -0.014556884765625 -0.298065185546875 0.9510192871093776 +1.57525 -0.014556884765625 -0.298065185546875 0.9510192871093776 +1.575375 -0.0147705078125 -0.30224609375 0.9510192871093776 +1.5755000000000002 -0.01495361328125 -0.306396484375 0.9510192871093776 +1.575625 -0.01495361328125 -0.306396484375 0.9510192871093776 +1.57575 -0.015167236328125 -0.310516357421875 0.9510192871093776 +1.5758750000000002 -0.015167236328125 -0.310516357421875 0.9510192871093776 +1.576 -0.015380859375 -0.314605712890625 0.9510192871093776 +1.576125 -0.01556396484375 -0.31866455078125 0.9510192871093776 +1.57625 -0.01556396484375 -0.31866455078125 0.9510192871093776 +1.576375 -0.0157470703125 -0.322662353515625 0.9510192871093776 +1.5765 -0.0157470703125 -0.322662353515625 0.9510192871093776 +1.576625 -0.015960693359375 -0.32666015625 0.9510192871093776 +1.57675 -0.016143798828125 -0.330596923828125 0.9510192871093776 +1.576875 -0.016143798828125 -0.330596923828125 0.9510192871093776 +1.577 -0.016326904296875 -0.334503173828125 0.9510192871093776 +1.577125 -0.016326904296875 -0.334503173828125 0.9510192871093776 +1.57725 -0.01654052734375 -0.33837890625 0.9510192871093776 +1.577375 -0.0167236328125 -0.34222412109375 0.9510192871093776 +1.5775000000000002 -0.0167236328125 -0.34222412109375 0.9510192871093776 +1.577625 -0.01690673828125 -0.34600830078125 0.9510192871093776 +1.57775 -0.01690673828125 -0.34600830078125 0.9510192871093776 +1.5778750000000002 -0.01708984375 -0.349761962890625 0.9510192871093776 +1.578 -0.01727294921875 -0.353485107421875 0.9510192871093776 +1.578125 -0.01727294921875 -0.353485107421875 0.9510192871093776 +1.57825 -0.0174560546875 -0.357177734375 0.9510192871093776 +1.578375 -0.0174560546875 -0.357177734375 0.9510192871093776 +1.5785 -0.01763916015625 -0.360809326171875 0.9510192871093776 +1.578625 -0.017791748046875 -0.36444091796875 0.9510192871093776 +1.57875 -0.017791748046875 -0.36444091796875 0.9510192871093776 +1.578875 -0.017974853515625 -0.36798095703125 0.9510192871093776 +1.579 -0.017974853515625 -0.36798095703125 0.9510192871093776 +1.5791250000000002 -0.018157958984375 -0.37152099609375 0.9510192871093776 +1.57925 -0.018310546875 -0.375 0.9510192871093776 +1.579375 -0.018310546875 -0.375 0.9510192871093776 +1.5795000000000002 -0.01849365234375 -0.378448486328125 0.9510192871093776 +1.579625 -0.01849365234375 -0.378448486328125 0.9510192871093776 +1.57975 -0.018646240234375 -0.3818359375 0.9510192871093776 +1.5798750000000002 -0.018829345703125 -0.38519287109375 0.9510192871093776 +1.58 -0.018829345703125 -0.38519287109375 0.9510192871093776 +1.580125 -0.01898193359375 -0.388519287109375 0.9510192871093776 +1.58025 -0.01898193359375 -0.388519287109375 0.9510192871093776 +1.580375 -0.019134521484375 -0.39178466796875 0.9510192871093776 +1.5805 -0.019287109375 -0.39501953125 0.9510192871093776 +1.580625 -0.019287109375 -0.39501953125 0.9510192871093776 +1.58075 -0.019439697265625 -0.398193359375 0.9510192871093776 +1.580875 -0.019439697265625 -0.398193359375 0.9510192871093776 +1.581 -0.019622802734375 -0.401336669921875 0.9510192871093776 +1.5811250000000002 -0.019775390625 -0.404449462890625 0.9510192871093776 +1.58125 -0.019775390625 -0.404449462890625 0.9510192871093776 +1.581375 -0.0198974609375 -0.407501220703125 0.9510192871093776 +1.5815000000000002 -0.0198974609375 -0.407501220703125 0.9510192871093776 +1.581625 -0.020050048828125 -0.4105224609375 0.9510192871093776 +1.58175 -0.02020263671875 -0.413482666015625 0.9510192871093776 +1.5818750000000002 -0.02020263671875 -0.413482666015625 0.9510192871093776 +1.582 -0.020355224609375 -0.416412353515625 0.9510192871093776 +1.582125 -0.020355224609375 -0.416412353515625 0.9510192871093776 +1.58225 -0.020477294921875 -0.419281005859375 0.9510192871093776 +1.582375 -0.0206298828125 -0.422119140625 0.9510192871093776 +1.5825 -0.0206298828125 -0.422119140625 0.9510192871093776 +1.582625 -0.020751953125 -0.424896240234375 0.9510192871093776 +1.58275 -0.020751953125 -0.424896240234375 0.9510192871093776 +1.582875 -0.020904541015625 -0.4276123046875 0.9510192871093776 +1.583 -0.021026611328125 -0.4302978515625 0.9510192871093776 +1.5831250000000002 -0.021026611328125 -0.4302978515625 0.9510192871093776 +1.58325 -0.021148681640625 -0.432952880859375 0.9510192871093776 +1.583375 -0.021148681640625 -0.432952880859375 0.9510192871093776 +1.5835000000000002 -0.021270751953125 -0.435546875 0.9510192871093776 +1.583625 -0.021392822265625 -0.438079833984375 0.9510192871093776 +1.58375 -0.021392822265625 -0.438079833984375 0.9510192871093776 +1.5838750000000002 -0.021514892578125 -0.440582275390625 0.9510192871093776 +1.584 -0.021514892578125 -0.440582275390625 0.9510192871093776 +1.584125 -0.021636962890625 -0.44305419921875 0.9510192871093776 +1.58425 -0.021759033203125 -0.4454345703125 0.9510192871093776 +1.584375 -0.021759033203125 -0.4454345703125 0.9510192871093776 +1.5845 -0.021881103515625 -0.447784423828125 0.9510192871093776 +1.584625 -0.021881103515625 -0.447784423828125 0.9510192871093776 +1.58475 -0.022003173828125 -0.450103759765625 0.9510192871093776 +1.584875 -0.0220947265625 -0.452362060546875 0.9510192871093776 +1.585 -0.0220947265625 -0.452362060546875 0.9510192871093776 +1.5851250000000002 -0.022216796875 -0.454559326171875 0.9510192871093776 +1.58525 -0.022216796875 -0.454559326171875 0.9510192871093776 +1.585375 -0.022308349609375 -0.45672607421875 0.9510192871093776 +1.5855000000000002 -0.022430419921875 -0.458831787109375 0.9510192871093776 +1.585625 -0.022430419921875 -0.458831787109375 0.9510192871093776 +1.58575 -0.02252197265625 -0.46087646484375 0.9510192871093776 +1.585875 -0.02252197265625 -0.46087646484375 0.9510192871093776 +1.586 -0.022613525390625 -0.462890625 0.9510192871093776 +1.586125 -0.022705078125 -0.464813232421875 0.9510192871093776 +1.58625 -0.022705078125 -0.464813232421875 0.9510192871093776 +1.586375 -0.022796630859375 -0.46673583984375 0.9510192871093776 +1.5865 -0.022796630859375 -0.46673583984375 0.9510192871093776 +1.586625 -0.02288818359375 -0.46856689453125 0.9510192871093776 +1.58675 -0.022979736328125 -0.470367431640625 0.9510192871093776 +1.586875 -0.022979736328125 -0.470367431640625 0.9510192871093776 +1.587 -0.0230712890625 -0.472137451171875 0.9510192871093776 +1.5871250000000002 -0.0230712890625 -0.472137451171875 0.9510192871093776 +1.58725 -0.023162841796875 -0.47381591796875 0.9510192871093776 +1.587375 -0.023223876953125 -0.4754638671875 0.9510192871093776 +1.5875000000000002 -0.023223876953125 -0.4754638671875 0.9510192871093776 +1.587625 -0.0233154296875 -0.47705078125 0.9510192871093776 +1.58775 -0.0233154296875 -0.47705078125 0.9510192871093776 +1.587875 -0.02337646484375 -0.478607177734375 0.9510192871093776 +1.588 -0.023468017578125 -0.480072021484375 0.9510192871093776 +1.588125 -0.023468017578125 -0.480072021484375 0.9510192871093776 +1.58825 -0.023529052734375 -0.48150634765625 0.9510192871093776 +1.588375 -0.023529052734375 -0.48150634765625 0.9510192871093776 +1.5885 -0.023590087890625 -0.48291015625 0.9510192871093776 +1.588625 -0.023651123046875 -0.484222412109375 0.9510192871093776 +1.58875 -0.023651123046875 -0.484222412109375 0.9510192871093776 +1.588875 -0.023712158203125 -0.485504150390625 0.9510192871093776 +1.589 -0.023712158203125 -0.485504150390625 0.9510192871093776 +1.5891250000000002 -0.023773193359375 -0.486724853515625 0.9510192871093776 +1.58925 -0.023834228515625 -0.487884521484375 0.9510192871093776 +1.589375 -0.023834228515625 -0.487884521484375 0.9510192871093776 +1.5895000000000002 -0.023895263671875 -0.489013671875 0.9510192871093776 +1.589625 -0.023895263671875 -0.489013671875 0.9510192871093776 +1.58975 -0.023956298828125 -0.490081787109375 0.9510192871093776 +1.589875 -0.02398681640625 -0.4910888671875 0.9510192871093776 +1.59 -0.02398681640625 -0.4910888671875 0.9510192871093776 +1.590125 -0.0240478515625 -0.492034912109375 0.9510192871093776 +1.59025 -0.0240478515625 -0.492034912109375 0.9510192871093776 +1.590375 -0.024078369140625 -0.492950439453125 0.9510192871093776 +1.5905 -0.024139404296875 -0.4937744140625 0.9510192871093776 +1.590625 -0.024139404296875 -0.4937744140625 0.9510192871093776 +1.59075 -0.024169921875 -0.49456787109375 0.9510192871093776 +1.590875 -0.024169921875 -0.49456787109375 0.9510192871093776 +1.591 -0.024200439453125 -0.49530029296875 0.9510192871093776 +1.5911250000000002 -0.02423095703125 -0.496002197265625 0.9510192871093776 +1.59125 -0.02423095703125 -0.496002197265625 0.9510192871093776 +1.591375 -0.024261474609375 -0.496612548828125 0.9510192871093776 +1.5915000000000002 -0.024261474609375 -0.496612548828125 0.9510192871093776 +1.591625 -0.0242919921875 -0.4971923828125 0.9510192871093776 +1.59175 -0.024322509765625 -0.497711181640625 0.9510192871093776 +1.591875 -0.024322509765625 -0.497711181640625 0.9510192871093776 +1.592 -0.02435302734375 -0.498199462890625 0.9510192871093776 +1.592125 -0.02435302734375 -0.498199462890625 0.9510192871093776 +1.59225 -0.02435302734375 -0.49859619140625 0.9510192871093776 +1.592375 -0.024383544921875 -0.49896240234375 0.9510192871093776 +1.5925 -0.024383544921875 -0.49896240234375 0.9510192871093776 +1.592625 -0.024383544921875 -0.499267578125 0.9510192871093776 +1.59275 -0.024383544921875 -0.499267578125 0.9510192871093776 +1.592875 -0.0244140625 -0.49951171875 0.9510192871093776 +1.593 -0.0244140625 -0.49969482421875 0.9510192871093776 +1.5931250000000002 -0.0244140625 -0.49969482421875 0.9510192871093776 +1.59325 -0.0244140625 -0.49981689453125 0.9510192871093776 +1.593375 -0.0244140625 -0.49981689453125 0.9510192871093776 +1.5935000000000002 -0.0244140625 -0.499908447265625 0.9510192871093776 +1.593625 -0.0244140625 -0.49993896484375 0.9510192871093776 +1.59375 -0.0244140625 -0.49993896484375 0.9510192871093776 +1.593875 -0.0244140625 -0.499908447265625 0.9510192871093776 +1.594 -0.0244140625 -0.499908447265625 0.9510192871093776 +1.594125 -0.0244140625 -0.49981689453125 0.9510192871093776 +1.59425 -0.0244140625 -0.49969482421875 0.9510192871093776 +1.594375 -0.0244140625 -0.49969482421875 0.9510192871093776 +1.5945 -0.0244140625 -0.49951171875 0.9510192871093776 +1.594625 -0.0244140625 -0.49951171875 0.9510192871093776 +1.5947500000000002 -0.024383544921875 -0.499267578125 0.9510192871093776 +1.594875 -0.024383544921875 -0.49896240234375 0.9510192871093776 +1.595 -0.024383544921875 -0.49896240234375 0.9510192871093776 +1.5951250000000002 -0.02435302734375 -0.49859619140625 0.9510192871093776 +1.59525 -0.02435302734375 -0.49859619140625 0.9510192871093776 +1.595375 -0.02435302734375 -0.498199462890625 0.9510192871093776 +1.5955000000000002 -0.024322509765625 -0.497711181640625 0.9510192871093776 +1.595625 -0.024322509765625 -0.497711181640625 0.9510192871093776 +1.59575 -0.0242919921875 -0.4971923828125 0.9510192871093776 +1.595875 -0.0242919921875 -0.4971923828125 0.9510192871093776 +1.596 -0.024261474609375 -0.496612548828125 0.9510192871093776 +1.596125 -0.02423095703125 -0.496002197265625 0.9510192871093776 +1.59625 -0.02423095703125 -0.496002197265625 0.9510192871093776 +1.596375 -0.024200439453125 -0.49530029296875 0.9510192871093776 +1.5965 -0.024200439453125 -0.49530029296875 0.9510192871093776 +1.596625 -0.024169921875 -0.49456787109375 0.9510192871093776 +1.5967500000000002 -0.024139404296875 -0.4937744140625 0.9510192871093776 +1.596875 -0.024139404296875 -0.4937744140625 0.9510192871093776 +1.597 -0.024078369140625 -0.492950439453125 0.9510192871093776 +1.5971250000000002 -0.024078369140625 -0.492950439453125 0.9510192871093776 +1.59725 -0.0240478515625 -0.492034912109375 0.9510192871093776 +1.597375 -0.02398681640625 -0.4910888671875 0.9510192871093776 +1.5975000000000002 -0.02398681640625 -0.4910888671875 0.9510192871093776 +1.597625 -0.023956298828125 -0.490081787109375 0.9510192871093776 +1.59775 -0.023956298828125 -0.490081787109375 0.9510192871093776 +1.597875 -0.023895263671875 -0.489013671875 0.9510192871093776 +1.598 -0.023834228515625 -0.487884521484375 0.9510192871093776 +1.598125 -0.023834228515625 -0.487884521484375 0.9510192871093776 +1.59825 -0.023773193359375 -0.486724853515625 0.9510192871093776 +1.598375 -0.023773193359375 -0.486724853515625 0.9510192871093776 +1.5985 -0.023712158203125 -0.485504150390625 0.9510192871093776 +1.598625 -0.023651123046875 -0.484222412109375 0.9510192871093776 +1.5987500000000002 -0.023651123046875 -0.484222412109375 0.9510192871093776 +1.598875 -0.023590087890625 -0.48291015625 0.9510192871093776 +1.599 -0.023590087890625 -0.48291015625 0.9510192871093776 +1.5991250000000002 -0.023529052734375 -0.48150634765625 0.9510192871093776 +1.59925 -0.023468017578125 -0.480072021484375 0.9510192871093776 +1.599375 -0.023468017578125 -0.480072021484375 0.9510192871093776 +1.5995000000000002 -0.02337646484375 -0.478607177734375 0.9510192871093776 +1.599625 -0.02337646484375 -0.478607177734375 0.9510192871093776 +1.59975 -0.0233154296875 -0.47705078125 0.9510192871093776 +1.599875 -0.023223876953125 -0.4754638671875 0.9510192871093776 +1.6 -0.001800537109375 -0.4754638671875 0.99608154296874928 +1.600125 -0.001800537109375 -0.47381591796875 0.99608154296874928 +1.60025 -0.001800537109375 -0.47381591796875 0.99608154296874928 +1.600375 -0.001800537109375 -0.472137451171875 0.99608154296874928 +1.6005 -0.00177001953125 -0.470367431640625 0.99608154296874928 +1.600625 -0.00177001953125 -0.470367431640625 0.99608154296874928 +1.6007500000000002 -0.00177001953125 -0.46856689453125 0.99608154296874928 +1.600875 -0.00177001953125 -0.46856689453125 0.99608154296874928 +1.601 -0.00177001953125 -0.46673583984375 0.99608154296874928 +1.6011250000000002 -0.00177001953125 -0.464813232421875 0.99608154296874928 +1.60125 -0.00177001953125 -0.464813232421875 0.99608154296874928 +1.601375 -0.001739501953125 -0.462890625 0.99608154296874928 +1.6015 -0.001739501953125 -0.462890625 0.99608154296874928 +1.601625 -0.001739501953125 -0.46087646484375 0.99608154296874928 +1.60175 -0.001739501953125 -0.458831787109375 0.99608154296874928 +1.601875 -0.001739501953125 -0.458831787109375 0.99608154296874928 +1.602 -0.001739501953125 -0.45672607421875 0.99608154296874928 +1.602125 -0.001739501953125 -0.45672607421875 0.99608154296874928 +1.60225 -0.001708984375 -0.454559326171875 0.99608154296874928 +1.602375 -0.001708984375 -0.452362060546875 0.99608154296874928 +1.6025 -0.001708984375 -0.452362060546875 0.99608154296874928 +1.602625 -0.001708984375 -0.450103759765625 0.99608154296874928 +1.6027500000000002 -0.001708984375 -0.450103759765625 0.99608154296874928 +1.602875 -0.001678466796875 -0.447784423828125 0.99608154296874928 +1.603 -0.001678466796875 -0.4454345703125 0.99608154296874928 +1.6031250000000002 -0.001678466796875 -0.4454345703125 0.99608154296874928 +1.60325 -0.001678466796875 -0.44305419921875 0.99608154296874928 +1.603375 -0.001678466796875 -0.44305419921875 0.99608154296874928 +1.6035 -0.001678466796875 -0.440582275390625 0.99608154296874928 +1.603625 -0.00164794921875 -0.438079833984375 0.99608154296874928 +1.60375 -0.00164794921875 -0.438079833984375 0.99608154296874928 +1.603875 -0.00164794921875 -0.435546875 0.99608154296874928 +1.604 -0.00164794921875 -0.435546875 0.99608154296874928 +1.604125 -0.00164794921875 -0.432952880859375 0.99608154296874928 +1.60425 -0.001617431640625 -0.4302978515625 0.99608154296874928 +1.604375 -0.001617431640625 -0.4302978515625 0.99608154296874928 +1.6045 -0.001617431640625 -0.4276123046875 0.99608154296874928 +1.604625 -0.001617431640625 -0.4276123046875 0.99608154296874928 +1.6047500000000002 -0.001617431640625 -0.424896240234375 0.99608154296874928 +1.604875 -0.0015869140625 -0.422119140625 0.99608154296874928 +1.605 -0.0015869140625 -0.422119140625 0.99608154296874928 +1.6051250000000002 -0.0015869140625 -0.419281005859375 0.99608154296874928 +1.60525 -0.0015869140625 -0.419281005859375 0.99608154296874928 +1.605375 -0.0015869140625 -0.416412353515625 0.99608154296874928 +1.6055 -0.001556396484375 -0.413482666015625 0.99608154296874928 +1.605625 -0.001556396484375 -0.413482666015625 0.99608154296874928 +1.60575 -0.001556396484375 -0.4105224609375 0.99608154296874928 +1.605875 -0.001556396484375 -0.4105224609375 0.99608154296874928 +1.606 -0.00152587890625 -0.407501220703125 0.99608154296874928 +1.606125 -0.00152587890625 -0.404449462890625 0.99608154296874928 +1.60625 -0.00152587890625 -0.404449462890625 0.99608154296874928 +1.606375 -0.00152587890625 -0.401336669921875 0.99608154296874928 +1.6065 -0.00152587890625 -0.401336669921875 0.99608154296874928 +1.606625 -0.001495361328125 -0.398193359375 0.99608154296874928 +1.6067500000000002 -0.001495361328125 -0.39501953125 0.99608154296874928 +1.606875 -0.001495361328125 -0.39501953125 0.99608154296874928 +1.607 -0.00146484375 -0.39178466796875 0.99608154296874928 +1.6071250000000002 -0.00146484375 -0.39178466796875 0.99608154296874928 +1.60725 -0.00146484375 -0.388519287109375 0.99608154296874928 +1.607375 -0.00146484375 -0.38519287109375 0.99608154296874928 +1.6075 -0.00146484375 -0.38519287109375 0.99608154296874928 +1.607625 -0.001434326171875 -0.3818359375 0.99608154296874928 +1.60775 -0.001434326171875 -0.3818359375 0.99608154296874928 +1.607875 -0.001434326171875 -0.378448486328125 0.99608154296874928 +1.608 -0.00140380859375 -0.375 0.99608154296874928 +1.608125 -0.00140380859375 -0.375 0.99608154296874928 +1.60825 -0.00140380859375 -0.37152099609375 0.99608154296874928 +1.608375 -0.00140380859375 -0.37152099609375 0.99608154296874928 +1.6085 -0.00140380859375 -0.36798095703125 0.99608154296874928 +1.608625 -0.001373291015625 -0.36444091796875 0.99608154296874928 +1.6087500000000002 -0.001373291015625 -0.36444091796875 0.99608154296874928 +1.608875 -0.001373291015625 -0.360809326171875 0.99608154296874928 +1.609 -0.001373291015625 -0.360809326171875 0.99608154296874928 +1.6091250000000002 -0.0013427734375 -0.357177734375 0.99608154296874928 +1.60925 -0.0013427734375 -0.353485107421875 0.99608154296874928 +1.609375 -0.0013427734375 -0.353485107421875 0.99608154296874928 +1.6095 -0.001312255859375 -0.349761962890625 0.99608154296874928 +1.609625 -0.001312255859375 -0.349761962890625 0.99608154296874928 +1.60975 -0.001312255859375 -0.34600830078125 0.99608154296874928 +1.609875 -0.00128173828125 -0.34222412109375 0.99608154296874928 +1.61 -0.00128173828125 -0.34222412109375 0.99608154296874928 +1.610125 -0.00128173828125 -0.33837890625 0.99608154296874928 +1.61025 -0.00128173828125 -0.33837890625 0.99608154296874928 +1.6103750000000002 -0.001251220703125 -0.334503173828125 0.99608154296874928 +1.6105 -0.001251220703125 -0.330596923828125 0.99608154296874928 +1.610625 -0.001251220703125 -0.330596923828125 0.99608154296874928 +1.6107500000000002 -0.001220703125 -0.32666015625 0.99608154296874928 +1.610875 -0.001220703125 -0.32666015625 0.99608154296874928 +1.611 -0.001220703125 -0.322662353515625 0.99608154296874928 +1.6111250000000002 -0.001190185546875 -0.31866455078125 0.99608154296874928 +1.61125 -0.001190185546875 -0.31866455078125 0.99608154296874928 +1.611375 -0.001190185546875 -0.314605712890625 0.99608154296874928 +1.6115 -0.001190185546875 -0.314605712890625 0.99608154296874928 +1.611625 -0.00115966796875 -0.310516357421875 0.99608154296874928 +1.61175 -0.00115966796875 -0.306396484375 0.99608154296874928 +1.611875 -0.00115966796875 -0.306396484375 0.99608154296874928 +1.612 -0.001129150390625 -0.30224609375 0.99608154296874928 +1.612125 -0.001129150390625 -0.30224609375 0.99608154296874928 +1.61225 -0.001129150390625 -0.298065185546875 0.99608154296874928 +1.6123750000000002 -0.0010986328125 -0.2938232421875 0.99608154296874928 +1.6125 -0.0010986328125 -0.2938232421875 0.99608154296874928 +1.612625 -0.0010986328125 -0.289581298828125 0.99608154296874928 +1.6127500000000002 -0.0010986328125 -0.289581298828125 0.99608154296874928 +1.612875 -0.001068115234375 -0.285308837890625 0.99608154296874928 +1.613 -0.001068115234375 -0.280975341796875 0.99608154296874928 +1.6131250000000002 -0.001068115234375 -0.280975341796875 0.99608154296874928 +1.61325 -0.00103759765625 -0.276641845703125 0.99608154296874928 +1.613375 -0.00103759765625 -0.276641845703125 0.99608154296874928 +1.6135 -0.00103759765625 -0.27227783203125 0.99608154296874928 +1.613625 -0.001007080078125 -0.267852783203125 0.99608154296874928 +1.61375 -0.001007080078125 -0.267852783203125 0.99608154296874928 +1.613875 -0.0009765625 -0.263427734375 0.99608154296874928 +1.614 -0.0009765625 -0.263427734375 0.99608154296874928 +1.614125 -0.0009765625 -0.25897216796875 0.99608154296874928 +1.61425 -0.000946044921875 -0.25445556640625 0.99608154296874928 +1.6143750000000002 -0.000946044921875 -0.25445556640625 0.99608154296874928 +1.6145 -0.000946044921875 -0.249969482421875 0.99608154296874928 +1.614625 -0.000946044921875 -0.249969482421875 0.99608154296874928 +1.6147500000000002 -0.00091552734375 -0.24542236328125 0.99608154296874928 +1.614875 -0.00091552734375 -0.2408447265625 0.99608154296874928 +1.615 -0.00091552734375 -0.2408447265625 0.99608154296874928 +1.6151250000000002 -0.000885009765625 -0.236236572265625 0.99608154296874928 +1.61525 -0.000885009765625 -0.236236572265625 0.99608154296874928 +1.615375 -0.0008544921875 -0.231597900390625 0.99608154296874928 +1.6155 -0.0008544921875 -0.226959228515625 0.99608154296874928 +1.615625 -0.0008544921875 -0.226959228515625 0.99608154296874928 +1.61575 -0.000823974609375 -0.2222900390625 0.99608154296874928 +1.615875 -0.000823974609375 -0.2222900390625 0.99608154296874928 +1.616 -0.000823974609375 -0.21759033203125 0.99608154296874928 +1.616125 -0.00079345703125 -0.212860107421875 0.99608154296874928 +1.61625 -0.00079345703125 -0.212860107421875 0.99608154296874928 +1.6163750000000002 -0.00079345703125 -0.208099365234375 0.99608154296874928 +1.6165 -0.00079345703125 -0.208099365234375 0.99608154296874928 +1.616625 -0.000762939453125 -0.203338623046875 0.99608154296874928 +1.6167500000000002 -0.000732421875 -0.19854736328125 0.99608154296874928 +1.616875 -0.000732421875 -0.19854736328125 0.99608154296874928 +1.617 -0.000732421875 -0.1937255859375 0.99608154296874928 +1.617125 -0.000732421875 -0.1937255859375 0.99608154296874928 +1.61725 -0.000701904296875 -0.188873291015625 0.99608154296874928 +1.617375 -0.000701904296875 -0.18402099609375 0.99608154296874928 +1.6175 -0.000701904296875 -0.18402099609375 0.99608154296874928 +1.617625 -0.00067138671875 -0.17913818359375 0.99608154296874928 +1.61775 -0.00067138671875 -0.17913818359375 0.99608154296874928 +1.617875 -0.000640869140625 -0.17425537109375 0.99608154296874928 +1.618 -0.000640869140625 -0.169342041015625 0.99608154296874928 +1.618125 -0.000640869140625 -0.169342041015625 0.99608154296874928 +1.61825 -0.0006103515625 -0.164398193359375 0.99608154296874928 +1.6183750000000002 -0.0006103515625 -0.164398193359375 0.99608154296874928 +1.6185 -0.000579833984375 -0.159454345703125 0.99608154296874928 +1.618625 -0.000579833984375 -0.15447998046875 0.99608154296874928 +1.6187500000000002 -0.000579833984375 -0.15447998046875 0.99608154296874928 +1.618875 -0.00054931640625 -0.14947509765625 0.99608154296874928 +1.619 -0.00054931640625 -0.14947509765625 0.99608154296874928 +1.619125 -0.00054931640625 -0.14447021484375 0.99608154296874928 +1.61925 -0.000518798828125 -0.13946533203125 0.99608154296874928 +1.619375 -0.000518798828125 -0.13946533203125 0.99608154296874928 +1.6195 -0.00048828125 -0.134429931640625 0.99608154296874928 +1.619625 -0.00048828125 -0.134429931640625 0.99608154296874928 +1.61975 -0.00048828125 -0.129364013671875 0.99608154296874928 +1.619875 -0.000457763671875 -0.124298095703125 0.99608154296874928 +1.62 -0.000457763671875 -0.124298095703125 0.99608154296874928 +1.620125 -0.00042724609375 -0.119232177734375 0.99608154296874928 +1.62025 -0.00042724609375 -0.119232177734375 0.99608154296874928 +1.6203750000000002 -0.00042724609375 -0.1141357421875 0.99608154296874928 +1.6205 -0.000396728515625 -0.109039306640625 0.99608154296874928 +1.620625 -0.000396728515625 -0.109039306640625 0.99608154296874928 +1.6207500000000002 -0.0003662109375 -0.103912353515625 0.99608154296874928 +1.620875 -0.0003662109375 -0.103912353515625 0.99608154296874928 +1.621 -0.0003662109375 -0.098785400390625 0.99608154296874928 +1.621125 -0.000335693359375 -0.093658447265625 0.99608154296874928 +1.62125 -0.000335693359375 -0.093658447265625 0.99608154296874928 +1.621375 -0.000335693359375 -0.0885009765625 0.99608154296874928 +1.6215 -0.000335693359375 -0.0885009765625 0.99608154296874928 +1.621625 -0.00030517578125 -0.083343505859375 0.99608154296874928 +1.62175 -0.000274658203125 -0.07818603515625 0.99608154296874928 +1.621875 -0.000274658203125 -0.07818603515625 0.99608154296874928 +1.622 -0.000274658203125 -0.072998046875 0.99608154296874928 +1.622125 -0.000274658203125 -0.072998046875 0.99608154296874928 +1.62225 -0.000244140625 -0.06781005859375 0.99608154296874928 +1.6223750000000002 -0.000213623046875 -0.0626220703125 0.99608154296874928 +1.6225 -0.000213623046875 -0.0626220703125 0.99608154296874928 +1.622625 -0.000213623046875 -0.05743408203125 0.99608154296874928 +1.6227500000000002 -0.000213623046875 -0.05743408203125 0.99608154296874928 +1.622875 -0.00018310546875 -0.05224609375 0.99608154296874928 +1.623 -0.000152587890625 -0.047027587890625 0.99608154296874928 +1.623125 -0.000152587890625 -0.047027587890625 0.99608154296874928 +1.62325 -0.000152587890625 -0.04180908203125 0.99608154296874928 +1.623375 -0.000152587890625 -0.04180908203125 0.99608154296874928 +1.6235 -0.0001220703125 -0.036590576171875 0.99608154296874928 +1.623625 -9.1552734375e-05 -0.0313720703125 0.99608154296874928 +1.62375 -9.1552734375e-05 -0.0313720703125 0.99608154296874928 +1.623875 -9.1552734375e-05 -0.026123046875 0.99608154296874928 +1.624 -9.1552734375e-05 -0.026123046875 0.99608154296874928 +1.624125 -6.103515625e-05 -0.020904541015625 0.99608154296874928 +1.62425 -3.0517578125e-05 -0.01568603515625 0.99608154296874928 +1.6243750000000002 -3.0517578125e-05 -0.01568603515625 0.99608154296874928 +1.6245 -3.0517578125e-05 -0.01043701171875 0.99608154296874928 +1.624625 -3.0517578125e-05 -0.01043701171875 0.99608154296874928 +1.6247500000000002 0.0 -0.005218505859375 0.99608154296874928 +1.624875 0.0 0.0 0.99608154296874928 +1.625 0.0 0.0 0.99608154296874928 +1.625125 0.0 0.005218505859375 0.99608154296874928 +1.62525 0.0 0.005218505859375 0.99608154296874928 +1.625375 3.0517578125e-05 0.01043701171875 0.99608154296874928 +1.6255 3.0517578125e-05 0.01568603515625 0.99608154296874928 +1.625625 3.0517578125e-05 0.01568603515625 0.99608154296874928 +1.62575 6.103515625e-05 0.020904541015625 0.99608154296874928 +1.625875 6.103515625e-05 0.020904541015625 0.99608154296874928 +1.6260000000000002 9.1552734375e-05 0.026123046875 0.99608154296874928 +1.626125 9.1552734375e-05 0.0313720703125 0.99608154296874928 +1.62625 9.1552734375e-05 0.0313720703125 0.99608154296874928 +1.6263750000000002 0.0001220703125 0.036590576171875 0.99608154296874928 +1.6265 0.0001220703125 0.036590576171875 0.99608154296874928 +1.626625 0.000152587890625 0.04180908203125 0.99608154296874928 +1.6267500000000002 0.000152587890625 0.047027587890625 0.99608154296874928 +1.626875 0.000152587890625 0.047027587890625 0.99608154296874928 +1.627 0.00018310546875 0.05224609375 0.99608154296874928 +1.627125 0.00018310546875 0.05224609375 0.99608154296874928 +1.62725 0.000213623046875 0.05743408203125 0.99608154296874928 +1.627375 0.000213623046875 0.0626220703125 0.99608154296874928 +1.6275 0.000213623046875 0.0626220703125 0.99608154296874928 +1.627625 0.000244140625 0.06781005859375 0.99608154296874928 +1.62775 0.000244140625 0.06781005859375 0.99608154296874928 +1.627875 0.000274658203125 0.072998046875 0.99608154296874928 +1.6280000000000002 0.000274658203125 0.07818603515625 0.99608154296874928 +1.628125 0.000274658203125 0.07818603515625 0.99608154296874928 +1.62825 0.00030517578125 0.083343505859375 0.99608154296874928 +1.6283750000000002 0.00030517578125 0.083343505859375 0.99608154296874928 +1.6285 0.000335693359375 0.0885009765625 0.99608154296874928 +1.628625 0.000335693359375 0.093658447265625 0.99608154296874928 +1.6287500000000002 0.000335693359375 0.093658447265625 0.99608154296874928 +1.628875 0.0003662109375 0.098785400390625 0.99608154296874928 +1.629 0.0003662109375 0.098785400390625 0.99608154296874928 +1.629125 0.0003662109375 0.103912353515625 0.99608154296874928 +1.62925 0.000396728515625 0.109039306640625 0.99608154296874928 +1.629375 0.000396728515625 0.109039306640625 0.99608154296874928 +1.6295 0.00042724609375 0.1141357421875 0.99608154296874928 +1.629625 0.00042724609375 0.1141357421875 0.99608154296874928 +1.62975 0.00042724609375 0.119232177734375 0.99608154296874928 +1.629875 0.000457763671875 0.124298095703125 0.99608154296874928 +1.6300000000000002 0.000457763671875 0.124298095703125 0.99608154296874928 +1.630125 0.00048828125 0.129364013671875 0.99608154296874928 +1.63025 0.00048828125 0.129364013671875 0.99608154296874928 +1.6303750000000002 0.00048828125 0.134429931640625 0.99608154296874928 +1.6305 0.000518798828125 0.13946533203125 0.99608154296874928 +1.630625 0.000518798828125 0.13946533203125 0.99608154296874928 +1.6307500000000002 0.00054931640625 0.14447021484375 0.99608154296874928 +1.630875 0.00054931640625 0.14447021484375 0.99608154296874928 +1.631 0.00054931640625 0.14947509765625 0.99608154296874928 +1.631125 0.000579833984375 0.15447998046875 0.99608154296874928 +1.63125 0.000579833984375 0.15447998046875 0.99608154296874928 +1.631375 0.000579833984375 0.159454345703125 0.99608154296874928 +1.6315 0.000579833984375 0.159454345703125 0.99608154296874928 +1.631625 0.0006103515625 0.164398193359375 0.99608154296874928 +1.63175 0.000640869140625 0.169342041015625 0.99608154296874928 +1.631875 0.000640869140625 0.169342041015625 0.99608154296874928 +1.6320000000000002 0.020477294921875 0.17425537109375 0.882238769531246 +1.632125 0.020477294921875 0.17425537109375 0.882238769531246 +1.63225 0.02105712890625 0.17913818359375 0.882238769531246 +1.6323750000000002 0.021636962890625 0.18402099609375 0.882238769531246 +1.6325 0.021636962890625 0.18402099609375 0.882238769531246 +1.632625 0.022216796875 0.188873291015625 0.882238769531246 +1.63275 0.022216796875 0.188873291015625 0.882238769531246 +1.632875 0.022796630859375 0.1937255859375 0.882238769531246 +1.633 0.023345947265625 0.19854736328125 0.882238769531246 +1.633125 0.023345947265625 0.19854736328125 0.882238769531246 +1.63325 0.02392578125 0.203338623046875 0.882238769531246 +1.633375 0.02392578125 0.203338623046875 0.882238769531246 +1.6335 0.02447509765625 0.208099365234375 0.882238769531246 +1.633625 0.0250244140625 0.212860107421875 0.882238769531246 +1.63375 0.0250244140625 0.212860107421875 0.882238769531246 +1.633875 0.025604248046875 0.21759033203125 0.882238769531246 +1.6340000000000002 0.025604248046875 0.21759033203125 0.882238769531246 +1.634125 0.026153564453125 0.2222900390625 0.882238769531246 +1.63425 0.026702880859375 0.226959228515625 0.882238769531246 +1.6343750000000002 0.026702880859375 0.226959228515625 0.882238769531246 +1.6345 0.027252197265625 0.231597900390625 0.882238769531246 +1.634625 0.027252197265625 0.231597900390625 0.882238769531246 +1.63475 0.027801513671875 0.236236572265625 0.882238769531246 +1.634875 0.0283203125 0.2408447265625 0.882238769531246 +1.635 0.0283203125 0.2408447265625 0.882238769531246 +1.635125 0.02886962890625 0.24542236328125 0.882238769531246 +1.63525 0.02886962890625 0.24542236328125 0.882238769531246 +1.635375 0.029388427734375 0.249969482421875 0.882238769531246 +1.6355 0.029937744140625 0.25445556640625 0.882238769531246 +1.635625 0.029937744140625 0.25445556640625 0.882238769531246 +1.63575 0.03045654296875 0.25897216796875 0.882238769531246 +1.635875 0.03045654296875 0.25897216796875 0.882238769531246 +1.6360000000000002 0.030975341796875 0.263427734375 0.882238769531246 +1.636125 0.031524658203125 0.267852783203125 0.882238769531246 +1.63625 0.031524658203125 0.267852783203125 0.882238769531246 +1.6363750000000002 0.03204345703125 0.27227783203125 0.882238769531246 +1.6365 0.03204345703125 0.27227783203125 0.882238769531246 +1.636625 0.03253173828125 0.276641845703125 0.882238769531246 +1.63675 0.033050537109375 0.280975341796875 0.882238769531246 +1.636875 0.033050537109375 0.280975341796875 0.882238769531246 +1.637 0.0335693359375 0.285308837890625 0.882238769531246 +1.637125 0.0335693359375 0.285308837890625 0.882238769531246 +1.63725 0.0340576171875 0.289581298828125 0.882238769531246 +1.637375 0.034576416015625 0.2938232421875 0.882238769531246 +1.6375 0.034576416015625 0.2938232421875 0.882238769531246 +1.637625 0.035064697265625 0.298065185546875 0.882238769531246 +1.63775 0.035064697265625 0.298065185546875 0.882238769531246 +1.637875 0.035552978515625 0.30224609375 0.882238769531246 +1.6380000000000002 0.036041259765625 0.306396484375 0.882238769531246 +1.638125 0.036041259765625 0.306396484375 0.882238769531246 +1.63825 0.036529541015625 0.310516357421875 0.882238769531246 +1.6383750000000002 0.036529541015625 0.310516357421875 0.882238769531246 +1.6385 0.037017822265625 0.314605712890625 0.882238769531246 +1.638625 0.0374755859375 0.31866455078125 0.882238769531246 +1.63875 0.0374755859375 0.31866455078125 0.882238769531246 +1.638875 0.0379638671875 0.322662353515625 0.882238769531246 +1.639 0.0379638671875 0.322662353515625 0.882238769531246 +1.639125 0.038421630859375 0.32666015625 0.882238769531246 +1.63925 0.03887939453125 0.330596923828125 0.882238769531246 +1.639375 0.03887939453125 0.330596923828125 0.882238769531246 +1.6395 0.03936767578125 0.334503173828125 0.882238769531246 +1.639625 0.03936767578125 0.334503173828125 0.882238769531246 +1.63975 0.039794921875 0.33837890625 0.882238769531246 +1.639875 0.040252685546875 0.34222412109375 0.882238769531246 +1.6400000000000002 0.040252685546875 0.34222412109375 0.882238769531246 +1.640125 0.04071044921875 0.34600830078125 0.882238769531246 +1.64025 0.04071044921875 0.34600830078125 0.882238769531246 +1.6403750000000002 0.0411376953125 0.349761962890625 0.882238769531246 +1.6405 0.041595458984375 0.353485107421875 0.882238769531246 +1.640625 0.041595458984375 0.353485107421875 0.882238769531246 +1.64075 0.042022705078125 0.357177734375 0.882238769531246 +1.640875 0.042022705078125 0.357177734375 0.882238769531246 +1.641 0.042449951171875 0.360809326171875 0.882238769531246 +1.641125 0.042877197265625 0.36444091796875 0.882238769531246 +1.64125 0.042877197265625 0.36444091796875 0.882238769531246 +1.641375 0.043304443359375 0.36798095703125 0.882238769531246 +1.6415 0.043304443359375 0.36798095703125 0.882238769531246 +1.6416250000000002 0.043701171875 0.37152099609375 0.882238769531246 +1.64175 0.04412841796875 0.375 0.882238769531246 +1.641875 0.04412841796875 0.375 0.882238769531246 +1.6420000000000002 0.044525146484375 0.378448486328125 0.882238769531246 +1.642125 0.044525146484375 0.378448486328125 0.882238769531246 +1.64225 0.044921875 0.3818359375 0.882238769531246 +1.6423750000000002 0.045318603515625 0.38519287109375 0.882238769531246 +1.6425 0.045318603515625 0.38519287109375 0.882238769531246 +1.642625 0.04571533203125 0.388519287109375 0.882238769531246 +1.64275 0.04571533203125 0.388519287109375 0.882238769531246 +1.642875 0.04608154296875 0.39178466796875 0.882238769531246 +1.643 0.046478271484375 0.39501953125 0.882238769531246 +1.643125 0.046478271484375 0.39501953125 0.882238769531246 +1.64325 0.046844482421875 0.398193359375 0.882238769531246 +1.643375 0.046844482421875 0.398193359375 0.882238769531246 +1.6435 0.047210693359375 0.401336669921875 0.882238769531246 +1.6436250000000002 0.047576904296875 0.404449462890625 0.882238769531246 +1.64375 0.047576904296875 0.404449462890625 0.882238769531246 +1.643875 0.047943115234375 0.407501220703125 0.882238769531246 +1.6440000000000002 0.047943115234375 0.407501220703125 0.882238769531246 +1.644125 0.048309326171875 0.4105224609375 0.882238769531246 +1.64425 0.04864501953125 0.413482666015625 0.882238769531246 +1.6443750000000002 0.04864501953125 0.413482666015625 0.882238769531246 +1.6445 0.048980712890625 0.416412353515625 0.882238769531246 +1.644625 0.048980712890625 0.416412353515625 0.882238769531246 +1.64475 0.04931640625 0.419281005859375 0.882238769531246 +1.644875 0.049652099609375 0.422119140625 0.882238769531246 +1.645 0.049652099609375 0.422119140625 0.882238769531246 +1.645125 0.04998779296875 0.424896240234375 0.882238769531246 +1.64525 0.04998779296875 0.424896240234375 0.882238769531246 +1.645375 0.050323486328125 0.4276123046875 0.882238769531246 +1.6455 0.050628662109375 0.4302978515625 0.882238769531246 +1.6456250000000002 0.050628662109375 0.4302978515625 0.882238769531246 +1.64575 0.050933837890625 0.432952880859375 0.882238769531246 +1.645875 0.050933837890625 0.432952880859375 0.882238769531246 +1.6460000000000002 0.051239013671875 0.435546875 0.882238769531246 +1.646125 0.051544189453125 0.438079833984375 0.882238769531246 +1.64625 0.051544189453125 0.438079833984375 0.882238769531246 +1.6463750000000002 0.051849365234375 0.440582275390625 0.882238769531246 +1.6465 0.051849365234375 0.440582275390625 0.882238769531246 +1.646625 0.0521240234375 0.44305419921875 0.882238769531246 +1.64675 0.052398681640625 0.4454345703125 0.882238769531246 +1.646875 0.052398681640625 0.4454345703125 0.882238769531246 +1.647 0.05267333984375 0.447784423828125 0.882238769531246 +1.647125 0.05267333984375 0.447784423828125 0.882238769531246 +1.64725 0.052947998046875 0.450103759765625 0.882238769531246 +1.647375 0.05322265625 0.452362060546875 0.882238769531246 +1.6475 0.05322265625 0.452362060546875 0.882238769531246 +1.6476250000000002 0.053466796875 0.454559326171875 0.882238769531246 +1.64775 0.053466796875 0.454559326171875 0.882238769531246 +1.647875 0.053741455078125 0.45672607421875 0.882238769531246 +1.6480000000000002 0.053985595703125 0.458831787109375 0.882238769531246 +1.648125 0.053985595703125 0.458831787109375 0.882238769531246 +1.64825 0.054229736328125 0.46087646484375 0.882238769531246 +1.648375 0.054229736328125 0.46087646484375 0.882238769531246 +1.6485 0.054473876953125 0.462890625 0.882238769531246 +1.648625 0.0546875 0.464813232421875 0.882238769531246 +1.64875 0.0546875 0.464813232421875 0.882238769531246 +1.648875 0.054901123046875 0.46673583984375 0.882238769531246 +1.649 0.054901123046875 0.46673583984375 0.882238769531246 +1.649125 0.05511474609375 0.46856689453125 0.882238769531246 +1.64925 0.055328369140625 0.470367431640625 0.882238769531246 +1.649375 0.055328369140625 0.470367431640625 0.882238769531246 +1.6495 0.0555419921875 0.472137451171875 0.882238769531246 +1.6496250000000002 0.0555419921875 0.472137451171875 0.882238769531246 +1.64975 0.055755615234375 0.47381591796875 0.882238769531246 +1.649875 0.055938720703125 0.4754638671875 0.882238769531246 +1.6500000000000002 0.055938720703125 0.4754638671875 0.882238769531246 +1.650125 0.056121826171875 0.47705078125 0.882238769531246 +1.65025 0.056121826171875 0.47705078125 0.882238769531246 +1.650375 0.056304931640625 0.478607177734375 0.882238769531246 +1.6505 0.056488037109375 0.480072021484375 0.882238769531246 +1.650625 0.056488037109375 0.480072021484375 0.882238769531246 +1.65075 0.056640625 0.48150634765625 0.882238769531246 +1.650875 0.056640625 0.48150634765625 0.882238769531246 +1.651 0.05682373046875 0.48291015625 0.882238769531246 +1.651125 0.056976318359375 0.484222412109375 0.882238769531246 +1.65125 0.056976318359375 0.484222412109375 0.882238769531246 +1.651375 0.05712890625 0.485504150390625 0.882238769531246 +1.6515 0.05712890625 0.485504150390625 0.882238769531246 +1.6516250000000002 0.0572509765625 0.486724853515625 0.882238769531246 +1.65175 0.057403564453125 0.487884521484375 0.882238769531246 +1.651875 0.057403564453125 0.487884521484375 0.882238769531246 +1.6520000000000002 0.057525634765625 0.489013671875 0.882238769531246 +1.652125 0.057525634765625 0.489013671875 0.882238769531246 +1.65225 0.057647705078125 0.490081787109375 0.882238769531246 +1.652375 0.057769775390625 0.4910888671875 0.882238769531246 +1.6525 0.057769775390625 0.4910888671875 0.882238769531246 +1.652625 0.057891845703125 0.492034912109375 0.882238769531246 +1.65275 0.057891845703125 0.492034912109375 0.882238769531246 +1.652875 0.0579833984375 0.492950439453125 0.882238769531246 +1.653 0.05810546875 0.4937744140625 0.882238769531246 +1.653125 0.05810546875 0.4937744140625 0.882238769531246 +1.65325 0.058197021484375 0.49456787109375 0.882238769531246 +1.653375 0.058197021484375 0.49456787109375 0.882238769531246 +1.6535 0.05828857421875 0.49530029296875 0.882238769531246 +1.6536250000000002 0.058349609375 0.496002197265625 0.882238769531246 +1.65375 0.058349609375 0.496002197265625 0.882238769531246 +1.653875 0.058441162109375 0.496612548828125 0.882238769531246 +1.6540000000000002 0.058441162109375 0.496612548828125 0.882238769531246 +1.654125 0.058502197265625 0.4971923828125 0.882238769531246 +1.65425 0.058563232421875 0.497711181640625 0.882238769531246 +1.654375 0.058563232421875 0.497711181640625 0.882238769531246 +1.6545 0.058624267578125 0.498199462890625 0.882238769531246 +1.654625 0.058624267578125 0.498199462890625 0.882238769531246 +1.65475 0.05865478515625 0.49859619140625 0.882238769531246 +1.654875 0.0587158203125 0.49896240234375 0.882238769531246 +1.655 0.0587158203125 0.49896240234375 0.882238769531246 +1.655125 0.058746337890625 0.499267578125 0.882238769531246 +1.65525 0.058746337890625 0.499267578125 0.882238769531246 +1.655375 0.05877685546875 0.49951171875 0.882238769531246 +1.6555 0.05877685546875 0.49969482421875 0.882238769531246 +1.6556250000000002 0.05877685546875 0.49969482421875 0.882238769531246 +1.65575 0.058807373046875 0.49981689453125 0.882238769531246 +1.655875 0.058807373046875 0.49981689453125 0.882238769531246 +1.6560000000000002 0.058807373046875 0.499908447265625 0.882238769531246 +1.656125 0.058807373046875 0.49993896484375 0.882238769531246 +1.65625 0.058807373046875 0.49993896484375 0.882238769531246 +1.656375 0.058807373046875 0.499908447265625 0.882238769531246 +1.6565 0.058807373046875 0.499908447265625 0.882238769531246 +1.656625 0.058807373046875 0.49981689453125 0.882238769531246 +1.65675 0.05877685546875 0.49969482421875 0.882238769531246 +1.656875 0.05877685546875 0.49969482421875 0.882238769531246 +1.657 0.05877685546875 0.49951171875 0.882238769531246 +1.657125 0.05877685546875 0.49951171875 0.882238769531246 +1.6572500000000002 0.058746337890625 0.499267578125 0.882238769531246 +1.657375 0.0587158203125 0.49896240234375 0.882238769531246 +1.6575 0.0587158203125 0.49896240234375 0.882238769531246 +1.6576250000000002 0.05865478515625 0.49859619140625 0.882238769531246 +1.65775 0.05865478515625 0.49859619140625 0.882238769531246 +1.657875 0.058624267578125 0.498199462890625 0.882238769531246 +1.6580000000000002 0.058563232421875 0.497711181640625 0.882238769531246 +1.658125 0.058563232421875 0.497711181640625 0.882238769531246 +1.65825 0.058502197265625 0.4971923828125 0.882238769531246 +1.658375 0.058502197265625 0.4971923828125 0.882238769531246 +1.6585 0.058441162109375 0.496612548828125 0.882238769531246 +1.658625 0.058349609375 0.496002197265625 0.882238769531246 +1.65875 0.058349609375 0.496002197265625 0.882238769531246 +1.658875 0.05828857421875 0.49530029296875 0.882238769531246 +1.659 0.05828857421875 0.49530029296875 0.882238769531246 +1.659125 0.058197021484375 0.49456787109375 0.882238769531246 +1.6592500000000002 0.05810546875 0.4937744140625 0.882238769531246 +1.659375 0.05810546875 0.4937744140625 0.882238769531246 +1.6595 0.0579833984375 0.492950439453125 0.882238769531246 +1.6596250000000002 0.0579833984375 0.492950439453125 0.882238769531246 +1.65975 0.057891845703125 0.492034912109375 0.882238769531246 +1.659875 0.057769775390625 0.4910888671875 0.882238769531246 +1.6600000000000002 0.057769775390625 0.4910888671875 0.882238769531246 +1.660125 0.057647705078125 0.490081787109375 0.882238769531246 +1.66025 0.057647705078125 0.490081787109375 0.882238769531246 +1.660375 0.057525634765625 0.489013671875 0.882238769531246 +1.6605 0.057403564453125 0.487884521484375 0.882238769531246 +1.660625 0.057403564453125 0.487884521484375 0.882238769531246 +1.66075 0.0572509765625 0.486724853515625 0.882238769531246 +1.660875 0.0572509765625 0.486724853515625 0.882238769531246 +1.661 0.05712890625 0.485504150390625 0.882238769531246 +1.661125 0.056976318359375 0.484222412109375 0.882238769531246 +1.6612500000000002 0.056976318359375 0.484222412109375 0.882238769531246 +1.661375 0.05682373046875 0.48291015625 0.882238769531246 +1.6615 0.05682373046875 0.48291015625 0.882238769531246 +1.6616250000000002 0.056640625 0.48150634765625 0.882238769531246 +1.66175 0.056488037109375 0.480072021484375 0.882238769531246 +1.661875 0.056488037109375 0.480072021484375 0.882238769531246 +1.6620000000000002 0.056304931640625 0.478607177734375 0.882238769531246 +1.662125 0.056304931640625 0.478607177734375 0.882238769531246 +1.66225 0.056121826171875 0.47705078125 0.882238769531246 +1.662375 0.055938720703125 0.4754638671875 0.882238769531246 +1.6625 0.055938720703125 0.4754638671875 0.882238769531246 +1.662625 0.055755615234375 0.47381591796875 0.882238769531246 +1.66275 0.055755615234375 0.47381591796875 0.882238769531246 +1.662875 0.0555419921875 0.472137451171875 0.882238769531246 +1.663 0.055328369140625 0.470367431640625 0.882238769531246 +1.663125 0.055328369140625 0.470367431640625 0.882238769531246 +1.6632500000000002 0.05511474609375 0.46856689453125 0.882238769531246 +1.663375 0.05511474609375 0.46856689453125 0.882238769531246 +1.6635 0.054901123046875 0.46673583984375 0.882238769531246 +1.6636250000000002 0.0546875 0.464813232421875 0.882238769531246 +1.66375 0.0546875 0.464813232421875 0.882238769531246 +1.663875 0.054473876953125 0.462890625 0.882238769531246 +1.6640000000000002 0.17230224609375 0.462890625 0.6276428222656184 +1.664125 0.17156982421875 0.46087646484375 0.6276428222656184 +1.66425 0.170806884765625 0.458831787109375 0.6276428222656184 +1.664375 0.170806884765625 0.458831787109375 0.6276428222656184 +1.6645 0.170013427734375 0.45672607421875 0.6276428222656184 +1.664625 0.170013427734375 0.45672607421875 0.6276428222656184 +1.66475 0.169219970703125 0.454559326171875 0.6276428222656184 +1.664875 0.16839599609375 0.452362060546875 0.6276428222656184 +1.665 0.16839599609375 0.452362060546875 0.6276428222656184 +1.665125 0.16754150390625 0.450103759765625 0.6276428222656184 +1.6652500000000002 0.16754150390625 0.450103759765625 0.6276428222656184 +1.665375 0.16668701171875 0.447784423828125 0.6276428222656184 +1.6655 0.165802001953125 0.4454345703125 0.6276428222656184 +1.6656250000000002 0.165802001953125 0.4454345703125 0.6276428222656184 +1.66575 0.1649169921875 0.44305419921875 0.6276428222656184 +1.665875 0.1649169921875 0.44305419921875 0.6276428222656184 +1.666 0.16400146484375 0.440582275390625 0.6276428222656184 +1.666125 0.1630859375 0.438079833984375 0.6276428222656184 +1.66625 0.1630859375 0.438079833984375 0.6276428222656184 +1.666375 0.162139892578125 0.435546875 0.6276428222656184 +1.6665 0.162139892578125 0.435546875 0.6276428222656184 +1.666625 0.161163330078125 0.432952880859375 0.6276428222656184 +1.66675 0.160186767578125 0.4302978515625 0.6276428222656184 +1.666875 0.160186767578125 0.4302978515625 0.6276428222656184 +1.667 0.1591796875 0.4276123046875 0.6276428222656184 +1.667125 0.1591796875 0.4276123046875 0.6276428222656184 +1.6672500000000002 0.158172607421875 0.424896240234375 0.6276428222656184 +1.667375 0.157135009765625 0.422119140625 0.6276428222656184 +1.6675 0.157135009765625 0.422119140625 0.6276428222656184 +1.6676250000000002 0.15606689453125 0.419281005859375 0.6276428222656184 +1.66775 0.15606689453125 0.419281005859375 0.6276428222656184 +1.667875 0.154998779296875 0.416412353515625 0.6276428222656184 +1.668 0.1539306640625 0.413482666015625 0.6276428222656184 +1.668125 0.1539306640625 0.413482666015625 0.6276428222656184 +1.66825 0.152801513671875 0.4105224609375 0.6276428222656184 +1.668375 0.152801513671875 0.4105224609375 0.6276428222656184 +1.6685 0.151702880859375 0.407501220703125 0.6276428222656184 +1.668625 0.15057373046875 0.404449462890625 0.6276428222656184 +1.66875 0.15057373046875 0.404449462890625 0.6276428222656184 +1.668875 0.1494140625 0.401336669921875 0.6276428222656184 +1.669 0.1494140625 0.401336669921875 0.6276428222656184 +1.669125 0.148223876953125 0.398193359375 0.6276428222656184 +1.6692500000000002 0.147064208984375 0.39501953125 0.6276428222656184 +1.669375 0.147064208984375 0.39501953125 0.6276428222656184 +1.6695 0.145843505859375 0.39178466796875 0.6276428222656184 +1.6696250000000002 0.145843505859375 0.39178466796875 0.6276428222656184 +1.66975 0.144622802734375 0.388519287109375 0.6276428222656184 +1.669875 0.143402099609375 0.38519287109375 0.6276428222656184 +1.67 0.143402099609375 0.38519287109375 0.6276428222656184 +1.670125 0.14215087890625 0.3818359375 0.6276428222656184 +1.67025 0.14215087890625 0.3818359375 0.6276428222656184 +1.670375 0.140869140625 0.378448486328125 0.6276428222656184 +1.6705 0.13958740234375 0.375 0.6276428222656184 +1.670625 0.13958740234375 0.375 0.6276428222656184 +1.67075 0.1383056640625 0.37152099609375 0.6276428222656184 +1.670875 0.1383056640625 0.37152099609375 0.6276428222656184 +1.671 0.136993408203125 0.36798095703125 0.6276428222656184 +1.671125 0.135650634765625 0.36444091796875 0.6276428222656184 +1.6712500000000002 0.135650634765625 0.36444091796875 0.6276428222656184 +1.671375 0.134307861328125 0.360809326171875 0.6276428222656184 +1.6715 0.134307861328125 0.360809326171875 0.6276428222656184 +1.6716250000000002 0.132965087890625 0.357177734375 0.6276428222656184 +1.67175 0.131591796875 0.353485107421875 0.6276428222656184 +1.671875 0.131591796875 0.353485107421875 0.6276428222656184 +1.672 0.13018798828125 0.349761962890625 0.6276428222656184 +1.672125 0.13018798828125 0.349761962890625 0.6276428222656184 +1.67225 0.128814697265625 0.34600830078125 0.6276428222656184 +1.672375 0.12738037109375 0.34222412109375 0.6276428222656184 +1.6725 0.12738037109375 0.34222412109375 0.6276428222656184 +1.672625 0.1259765625 0.33837890625 0.6276428222656184 +1.67275 0.1259765625 0.33837890625 0.6276428222656184 +1.6728750000000002 0.12451171875 0.334503173828125 0.6276428222656184 +1.673 0.123077392578125 0.330596923828125 0.6276428222656184 +1.673125 0.123077392578125 0.330596923828125 0.6276428222656184 +1.6732500000000002 0.12158203125 0.32666015625 0.6276428222656184 +1.673375 0.12158203125 0.32666015625 0.6276428222656184 +1.6735 0.1201171875 0.322662353515625 0.6276428222656184 +1.6736250000000002 0.118621826171875 0.31866455078125 0.6276428222656184 +1.67375 0.118621826171875 0.31866455078125 0.6276428222656184 +1.673875 0.117095947265625 0.314605712890625 0.6276428222656184 +1.674 0.117095947265625 0.314605712890625 0.6276428222656184 +1.674125 0.1156005859375 0.310516357421875 0.6276428222656184 +1.67425 0.114044189453125 0.306396484375 0.6276428222656184 +1.674375 0.114044189453125 0.306396484375 0.6276428222656184 +1.6745 0.112518310546875 0.30224609375 0.6276428222656184 +1.674625 0.112518310546875 0.30224609375 0.6276428222656184 +1.67475 0.1109619140625 0.298065185546875 0.6276428222656184 +1.6748750000000002 0.109375 0.2938232421875 0.6276428222656184 +1.675 0.109375 0.2938232421875 0.6276428222656184 +1.675125 0.1077880859375 0.289581298828125 0.6276428222656184 +1.6752500000000002 0.1077880859375 0.289581298828125 0.6276428222656184 +1.675375 0.106201171875 0.285308837890625 0.6276428222656184 +1.6755 0.104583740234375 0.280975341796875 0.6276428222656184 +1.6756250000000002 0.104583740234375 0.280975341796875 0.6276428222656184 +1.67575 0.10296630859375 0.276641845703125 0.6276428222656184 +1.675875 0.10296630859375 0.276641845703125 0.6276428222656184 +1.676 0.101348876953125 0.27227783203125 0.6276428222656184 +1.676125 0.099700927734375 0.267852783203125 0.6276428222656184 +1.67625 0.099700927734375 0.267852783203125 0.6276428222656184 +1.676375 0.098052978515625 0.263427734375 0.6276428222656184 +1.6765 0.098052978515625 0.263427734375 0.6276428222656184 +1.676625 0.096405029296875 0.25897216796875 0.6276428222656184 +1.67675 0.0947265625 0.25445556640625 0.6276428222656184 +1.6768750000000002 0.0947265625 0.25445556640625 0.6276428222656184 +1.677 0.093048095703125 0.249969482421875 0.6276428222656184 +1.677125 0.093048095703125 0.249969482421875 0.6276428222656184 +1.6772500000000002 0.091339111328125 0.24542236328125 0.6276428222656184 +1.677375 0.08966064453125 0.2408447265625 0.6276428222656184 +1.6775 0.08966064453125 0.2408447265625 0.6276428222656184 +1.6776250000000002 0.087921142578125 0.236236572265625 0.6276428222656184 +1.67775 0.087921142578125 0.236236572265625 0.6276428222656184 +1.677875 0.086212158203125 0.231597900390625 0.6276428222656184 +1.678 0.08447265625 0.226959228515625 0.6276428222656184 +1.678125 0.08447265625 0.226959228515625 0.6276428222656184 +1.67825 0.082733154296875 0.2222900390625 0.6276428222656184 +1.678375 0.082733154296875 0.2222900390625 0.6276428222656184 +1.6785 0.08099365234375 0.21759033203125 0.6276428222656184 +1.678625 0.0792236328125 0.212860107421875 0.6276428222656184 +1.67875 0.0792236328125 0.212860107421875 0.6276428222656184 +1.6788750000000002 0.07745361328125 0.208099365234375 0.6276428222656184 +1.679 0.07745361328125 0.208099365234375 0.6276428222656184 +1.679125 0.07568359375 0.203338623046875 0.6276428222656184 +1.6792500000000002 0.07391357421875 0.19854736328125 0.6276428222656184 +1.679375 0.07391357421875 0.19854736328125 0.6276428222656184 +1.6795 0.072113037109375 0.1937255859375 0.6276428222656184 +1.6796250000000002 0.072113037109375 0.1937255859375 0.6276428222656184 +1.67975 0.0703125 0.188873291015625 0.6276428222656184 +1.679875 0.068511962890625 0.18402099609375 0.6276428222656184 +1.68 0.068511962890625 0.18402099609375 0.6276428222656184 +1.680125 0.066680908203125 0.17913818359375 0.6276428222656184 +1.68025 0.066680908203125 0.17913818359375 0.6276428222656184 +1.680375 0.064849853515625 0.17425537109375 0.6276428222656184 +1.6805 0.063018798828125 0.169342041015625 0.6276428222656184 +1.680625 0.063018798828125 0.169342041015625 0.6276428222656184 +1.68075 0.061187744140625 0.164398193359375 0.6276428222656184 +1.6808750000000002 0.061187744140625 0.164398193359375 0.6276428222656184 +1.681 0.059356689453125 0.159454345703125 0.6276428222656184 +1.681125 0.0574951171875 0.15447998046875 0.6276428222656184 +1.6812500000000002 0.0574951171875 0.15447998046875 0.6276428222656184 +1.681375 0.055633544921875 0.14947509765625 0.6276428222656184 +1.6815 0.055633544921875 0.14947509765625 0.6276428222656184 +1.681625 0.05377197265625 0.14447021484375 0.6276428222656184 +1.68175 0.051910400390625 0.13946533203125 0.6276428222656184 +1.681875 0.051910400390625 0.13946533203125 0.6276428222656184 +1.682 0.050018310546875 0.134429931640625 0.6276428222656184 +1.682125 0.050018310546875 0.134429931640625 0.6276428222656184 +1.68225 0.04815673828125 0.129364013671875 0.6276428222656184 +1.682375 0.0462646484375 0.124298095703125 0.6276428222656184 +1.6825 0.0462646484375 0.124298095703125 0.6276428222656184 +1.682625 0.04437255859375 0.119232177734375 0.6276428222656184 +1.68275 0.04437255859375 0.119232177734375 0.6276428222656184 +1.6828750000000002 0.04248046875 0.1141357421875 0.6276428222656184 +1.683 0.04058837890625 0.109039306640625 0.6276428222656184 +1.683125 0.04058837890625 0.109039306640625 0.6276428222656184 +1.6832500000000002 0.038665771484375 0.103912353515625 0.6276428222656184 +1.683375 0.038665771484375 0.103912353515625 0.6276428222656184 +1.6835 0.036773681640625 0.098785400390625 0.6276428222656184 +1.683625 0.03485107421875 0.093658447265625 0.6276428222656184 +1.68375 0.03485107421875 0.093658447265625 0.6276428222656184 +1.683875 0.032928466796875 0.0885009765625 0.6276428222656184 +1.684 0.032928466796875 0.0885009765625 0.6276428222656184 +1.684125 0.031005859375 0.083343505859375 0.6276428222656184 +1.68425 0.029083251953125 0.07818603515625 0.6276428222656184 +1.684375 0.029083251953125 0.07818603515625 0.6276428222656184 +1.6845 0.02716064453125 0.072998046875 0.6276428222656184 +1.684625 0.02716064453125 0.072998046875 0.6276428222656184 +1.68475 0.025238037109375 0.06781005859375 0.6276428222656184 +1.6848750000000002 0.0233154296875 0.0626220703125 0.6276428222656184 +1.685 0.0233154296875 0.0626220703125 0.6276428222656184 +1.685125 0.0213623046875 0.05743408203125 0.6276428222656184 +1.6852500000000002 0.0213623046875 0.05743408203125 0.6276428222656184 +1.685375 0.019439697265625 0.05224609375 0.6276428222656184 +1.6855 0.017486572265625 0.047027587890625 0.6276428222656184 +1.685625 0.017486572265625 0.047027587890625 0.6276428222656184 +1.68575 0.01556396484375 0.04180908203125 0.6276428222656184 +1.685875 0.01556396484375 0.04180908203125 0.6276428222656184 +1.686 0.01361083984375 0.036590576171875 0.6276428222656184 +1.686125 0.01165771484375 0.0313720703125 0.6276428222656184 +1.68625 0.01165771484375 0.0313720703125 0.6276428222656184 +1.686375 0.009735107421875 0.026123046875 0.6276428222656184 +1.6865 0.009735107421875 0.026123046875 0.6276428222656184 +1.686625 0.007781982421875 0.020904541015625 0.6276428222656184 +1.68675 0.005828857421875 0.01568603515625 0.6276428222656184 +1.6868750000000002 0.005828857421875 0.01568603515625 0.6276428222656184 +1.687 0.003875732421875 0.01043701171875 0.6276428222656184 +1.687125 0.003875732421875 0.01043701171875 0.6276428222656184 +1.6872500000000002 0.001922607421875 0.005218505859375 0.6276428222656184 +1.687375 0.0 0.0 0.6276428222656184 +1.6875 0.0 0.0 0.6276428222656184 +1.687625 -0.001922607421875 -0.005218505859375 0.6276428222656184 +1.68775 -0.001922607421875 -0.005218505859375 0.6276428222656184 +1.687875 -0.003875732421875 -0.01043701171875 0.6276428222656184 +1.688 -0.005828857421875 -0.01568603515625 0.6276428222656184 +1.688125 -0.005828857421875 -0.01568603515625 0.6276428222656184 +1.68825 -0.007781982421875 -0.020904541015625 0.6276428222656184 +1.688375 -0.007781982421875 -0.020904541015625 0.6276428222656184 +1.6885000000000002 -0.009735107421875 -0.026123046875 0.6276428222656184 +1.688625 -0.01165771484375 -0.0313720703125 0.6276428222656184 +1.68875 -0.01165771484375 -0.0313720703125 0.6276428222656184 +1.6888750000000002 -0.01361083984375 -0.036590576171875 0.6276428222656184 +1.689 -0.01361083984375 -0.036590576171875 0.6276428222656184 +1.689125 -0.01556396484375 -0.04180908203125 0.6276428222656184 +1.6892500000000002 -0.017486572265625 -0.047027587890625 0.6276428222656184 +1.689375 -0.017486572265625 -0.047027587890625 0.6276428222656184 +1.6895 -0.019439697265625 -0.05224609375 0.6276428222656184 +1.689625 -0.019439697265625 -0.05224609375 0.6276428222656184 +1.68975 -0.0213623046875 -0.05743408203125 0.6276428222656184 +1.689875 -0.0233154296875 -0.0626220703125 0.6276428222656184 +1.69 -0.0233154296875 -0.0626220703125 0.6276428222656184 +1.690125 -0.025238037109375 -0.06781005859375 0.6276428222656184 +1.69025 -0.025238037109375 -0.06781005859375 0.6276428222656184 +1.690375 -0.02716064453125 -0.072998046875 0.6276428222656184 +1.6905000000000002 -0.029083251953125 -0.07818603515625 0.6276428222656184 +1.690625 -0.029083251953125 -0.07818603515625 0.6276428222656184 +1.69075 -0.031005859375 -0.083343505859375 0.6276428222656184 +1.6908750000000002 -0.031005859375 -0.083343505859375 0.6276428222656184 +1.691 -0.032928466796875 -0.0885009765625 0.6276428222656184 +1.691125 -0.03485107421875 -0.093658447265625 0.6276428222656184 +1.6912500000000002 -0.03485107421875 -0.093658447265625 0.6276428222656184 +1.691375 -0.036773681640625 -0.098785400390625 0.6276428222656184 +1.6915 -0.036773681640625 -0.098785400390625 0.6276428222656184 +1.691625 -0.038665771484375 -0.103912353515625 0.6276428222656184 +1.69175 -0.04058837890625 -0.109039306640625 0.6276428222656184 +1.691875 -0.04058837890625 -0.109039306640625 0.6276428222656184 +1.692 -0.04248046875 -0.1141357421875 0.6276428222656184 +1.692125 -0.04248046875 -0.1141357421875 0.6276428222656184 +1.69225 -0.04437255859375 -0.119232177734375 0.6276428222656184 +1.692375 -0.0462646484375 -0.124298095703125 0.6276428222656184 +1.6925000000000002 -0.0462646484375 -0.124298095703125 0.6276428222656184 +1.692625 -0.04815673828125 -0.129364013671875 0.6276428222656184 +1.69275 -0.04815673828125 -0.129364013671875 0.6276428222656184 +1.6928750000000002 -0.050018310546875 -0.134429931640625 0.6276428222656184 +1.693 -0.051910400390625 -0.13946533203125 0.6276428222656184 +1.693125 -0.051910400390625 -0.13946533203125 0.6276428222656184 +1.6932500000000002 -0.05377197265625 -0.14447021484375 0.6276428222656184 +1.693375 -0.05377197265625 -0.14447021484375 0.6276428222656184 +1.6935 -0.055633544921875 -0.14947509765625 0.6276428222656184 +1.693625 -0.0574951171875 -0.15447998046875 0.6276428222656184 +1.69375 -0.0574951171875 -0.15447998046875 0.6276428222656184 +1.693875 -0.059356689453125 -0.159454345703125 0.6276428222656184 +1.694 -0.059356689453125 -0.159454345703125 0.6276428222656184 +1.694125 -0.061187744140625 -0.164398193359375 0.6276428222656184 +1.69425 -0.063018798828125 -0.169342041015625 0.6276428222656184 +1.694375 -0.063018798828125 -0.169342041015625 0.6276428222656184 +1.6945000000000002 -0.064849853515625 -0.17425537109375 0.6276428222656184 +1.694625 -0.064849853515625 -0.17425537109375 0.6276428222656184 +1.69475 -0.066680908203125 -0.17913818359375 0.6276428222656184 +1.6948750000000002 -0.068511962890625 -0.18402099609375 0.6276428222656184 +1.695 -0.068511962890625 -0.18402099609375 0.6276428222656184 +1.695125 -0.0703125 -0.188873291015625 0.6276428222656184 +1.6952500000000002 -0.0703125 -0.188873291015625 0.6276428222656184 +1.695375 -0.072113037109375 -0.1937255859375 0.6276428222656184 +1.6955 -0.07391357421875 -0.19854736328125 0.6276428222656184 +1.695625 -0.07391357421875 -0.19854736328125 0.6276428222656184 +1.69575 -0.07568359375 -0.203338623046875 0.6276428222656184 +1.695875 -0.07568359375 -0.203338623046875 0.6276428222656184 +1.696 -0.15130615234375 -0.208099365234375 0.2729187011718668 +1.696125 -0.154754638671875 -0.212860107421875 0.2729187011718668 +1.69625 -0.154754638671875 -0.212860107421875 0.2729187011718668 +1.696375 -0.158172607421875 -0.21759033203125 0.2729187011718668 +1.6965000000000002 -0.158172607421875 -0.21759033203125 0.2729187011718668 +1.696625 -0.161590576171875 -0.2222900390625 0.2729187011718668 +1.69675 -0.16497802734375 -0.226959228515625 0.2729187011718668 +1.6968750000000002 -0.16497802734375 -0.226959228515625 0.2729187011718668 +1.697 -0.168365478515625 -0.231597900390625 0.2729187011718668 +1.697125 -0.168365478515625 -0.231597900390625 0.2729187011718668 +1.69725 -0.1717529296875 -0.236236572265625 0.2729187011718668 +1.697375 -0.175079345703125 -0.2408447265625 0.2729187011718668 +1.6975 -0.175079345703125 -0.2408447265625 0.2729187011718668 +1.697625 -0.17840576171875 -0.24542236328125 0.2729187011718668 +1.69775 -0.17840576171875 -0.24542236328125 0.2729187011718668 +1.697875 -0.181732177734375 -0.249969482421875 0.2729187011718668 +1.698 -0.18499755859375 -0.25445556640625 0.2729187011718668 +1.698125 -0.18499755859375 -0.25445556640625 0.2729187011718668 +1.69825 -0.188262939453125 -0.25897216796875 0.2729187011718668 +1.698375 -0.188262939453125 -0.25897216796875 0.2729187011718668 +1.6985000000000002 -0.1915283203125 -0.263427734375 0.2729187011718668 +1.698625 -0.194732666015625 -0.267852783203125 0.2729187011718668 +1.69875 -0.194732666015625 -0.267852783203125 0.2729187011718668 +1.6988750000000002 -0.19793701171875 -0.27227783203125 0.2729187011718668 +1.699 -0.19793701171875 -0.27227783203125 0.2729187011718668 +1.699125 -0.20111083984375 -0.276641845703125 0.2729187011718668 +1.69925 -0.20428466796875 -0.280975341796875 0.2729187011718668 +1.699375 -0.20428466796875 -0.280975341796875 0.2729187011718668 +1.6995 -0.207427978515625 -0.285308837890625 0.2729187011718668 +1.699625 -0.207427978515625 -0.285308837890625 0.2729187011718668 +1.69975 -0.210540771484375 -0.289581298828125 0.2729187011718668 +1.699875 -0.213623046875 -0.2938232421875 0.2729187011718668 +1.7 -0.213623046875 -0.2938232421875 0.2729187011718668 +1.700125 -0.216705322265625 -0.298065185546875 0.2729187011718668 +1.70025 -0.216705322265625 -0.298065185546875 0.2729187011718668 +1.700375 -0.2197265625 -0.30224609375 0.2729187011718668 +1.7005000000000002 -0.2227783203125 -0.306396484375 0.2729187011718668 +1.700625 -0.2227783203125 -0.306396484375 0.2729187011718668 +1.70075 -0.22576904296875 -0.310516357421875 0.2729187011718668 +1.7008750000000002 -0.22576904296875 -0.310516357421875 0.2729187011718668 +1.701 -0.228729248046875 -0.314605712890625 0.2729187011718668 +1.701125 -0.231658935546875 -0.31866455078125 0.2729187011718668 +1.70125 -0.231658935546875 -0.31866455078125 0.2729187011718668 +1.701375 -0.234588623046875 -0.322662353515625 0.2729187011718668 +1.7015 -0.234588623046875 -0.322662353515625 0.2729187011718668 +1.701625 -0.23748779296875 -0.32666015625 0.2729187011718668 +1.70175 -0.2403564453125 -0.330596923828125 0.2729187011718668 +1.701875 -0.2403564453125 -0.330596923828125 0.2729187011718668 +1.702 -0.243194580078125 -0.334503173828125 0.2729187011718668 +1.702125 -0.243194580078125 -0.334503173828125 0.2729187011718668 +1.70225 -0.246002197265625 -0.33837890625 0.2729187011718668 +1.702375 -0.248809814453125 -0.34222412109375 0.2729187011718668 +1.7025000000000002 -0.248809814453125 -0.34222412109375 0.2729187011718668 +1.702625 -0.251556396484375 -0.34600830078125 0.2729187011718668 +1.70275 -0.251556396484375 -0.34600830078125 0.2729187011718668 +1.7028750000000002 -0.254302978515625 -0.349761962890625 0.2729187011718668 +1.703 -0.256988525390625 -0.353485107421875 0.2729187011718668 +1.703125 -0.256988525390625 -0.353485107421875 0.2729187011718668 +1.70325 -0.259674072265625 -0.357177734375 0.2729187011718668 +1.703375 -0.259674072265625 -0.357177734375 0.2729187011718668 +1.7035 -0.2623291015625 -0.360809326171875 0.2729187011718668 +1.703625 -0.26495361328125 -0.36444091796875 0.2729187011718668 +1.70375 -0.26495361328125 -0.36444091796875 0.2729187011718668 +1.703875 -0.267547607421875 -0.36798095703125 0.2729187011718668 +1.704 -0.267547607421875 -0.36798095703125 0.2729187011718668 +1.7041250000000002 -0.270111083984375 -0.37152099609375 0.2729187011718668 +1.70425 -0.272613525390625 -0.375 0.2729187011718668 +1.704375 -0.272613525390625 -0.375 0.2729187011718668 +1.7045000000000002 -0.275146484375 -0.378448486328125 0.2729187011718668 +1.704625 -0.275146484375 -0.378448486328125 0.2729187011718668 +1.70475 -0.277618408203125 -0.3818359375 0.2729187011718668 +1.7048750000000002 -0.280059814453125 -0.38519287109375 0.2729187011718668 +1.705 -0.280059814453125 -0.38519287109375 0.2729187011718668 +1.705125 -0.282470703125 -0.388519287109375 0.2729187011718668 +1.70525 -0.282470703125 -0.388519287109375 0.2729187011718668 +1.705375 -0.28485107421875 -0.39178466796875 0.2729187011718668 +1.7055 -0.287200927734375 -0.39501953125 0.2729187011718668 +1.705625 -0.287200927734375 -0.39501953125 0.2729187011718668 +1.70575 -0.28948974609375 -0.398193359375 0.2729187011718668 +1.705875 -0.28948974609375 -0.398193359375 0.2729187011718668 +1.706 -0.291778564453125 -0.401336669921875 0.2729187011718668 +1.7061250000000002 -0.294036865234375 -0.404449462890625 0.2729187011718668 +1.70625 -0.294036865234375 -0.404449462890625 0.2729187011718668 +1.706375 -0.2962646484375 -0.407501220703125 0.2729187011718668 +1.7065000000000002 -0.2962646484375 -0.407501220703125 0.2729187011718668 +1.706625 -0.2984619140625 -0.4105224609375 0.2729187011718668 +1.70675 -0.30059814453125 -0.413482666015625 0.2729187011718668 +1.7068750000000002 -0.30059814453125 -0.413482666015625 0.2729187011718668 +1.707 -0.302734375 -0.416412353515625 0.2729187011718668 +1.707125 -0.302734375 -0.416412353515625 0.2729187011718668 +1.70725 -0.3048095703125 -0.419281005859375 0.2729187011718668 +1.707375 -0.306884765625 -0.422119140625 0.2729187011718668 +1.7075 -0.306884765625 -0.422119140625 0.2729187011718668 +1.707625 -0.30889892578125 -0.424896240234375 0.2729187011718668 +1.70775 -0.30889892578125 -0.424896240234375 0.2729187011718668 +1.707875 -0.310882568359375 -0.4276123046875 0.2729187011718668 +1.708 -0.312835693359375 -0.4302978515625 0.2729187011718668 +1.7081250000000002 -0.312835693359375 -0.4302978515625 0.2729187011718668 +1.70825 -0.31475830078125 -0.432952880859375 0.2729187011718668 +1.708375 -0.31475830078125 -0.432952880859375 0.2729187011718668 +1.7085000000000002 -0.316650390625 -0.435546875 0.2729187011718668 +1.708625 -0.318511962890625 -0.438079833984375 0.2729187011718668 +1.70875 -0.318511962890625 -0.438079833984375 0.2729187011718668 +1.7088750000000002 -0.3203125 -0.440582275390625 0.2729187011718668 +1.709 -0.3203125 -0.440582275390625 0.2729187011718668 +1.709125 -0.322113037109375 -0.44305419921875 0.2729187011718668 +1.70925 -0.3238525390625 -0.4454345703125 0.2729187011718668 +1.709375 -0.3238525390625 -0.4454345703125 0.2729187011718668 +1.7095 -0.3255615234375 -0.447784423828125 0.2729187011718668 +1.709625 -0.3255615234375 -0.447784423828125 0.2729187011718668 +1.70975 -0.327239990234375 -0.450103759765625 0.2729187011718668 +1.709875 -0.328857421875 -0.452362060546875 0.2729187011718668 +1.71 -0.328857421875 -0.452362060546875 0.2729187011718668 +1.7101250000000002 -0.330474853515625 -0.454559326171875 0.2729187011718668 +1.71025 -0.330474853515625 -0.454559326171875 0.2729187011718668 +1.710375 -0.33203125 -0.45672607421875 0.2729187011718668 +1.7105000000000002 -0.333587646484375 -0.458831787109375 0.2729187011718668 +1.710625 -0.333587646484375 -0.458831787109375 0.2729187011718668 +1.71075 -0.335052490234375 -0.46087646484375 0.2729187011718668 +1.7108750000000002 -0.335052490234375 -0.46087646484375 0.2729187011718668 +1.711 -0.336517333984375 -0.462890625 0.2729187011718668 +1.711125 -0.337921142578125 -0.464813232421875 0.2729187011718668 +1.71125 -0.337921142578125 -0.464813232421875 0.2729187011718668 +1.711375 -0.339324951171875 -0.46673583984375 0.2729187011718668 +1.7115 -0.339324951171875 -0.46673583984375 0.2729187011718668 +1.711625 -0.340667724609375 -0.46856689453125 0.2729187011718668 +1.71175 -0.34197998046875 -0.470367431640625 0.2729187011718668 +1.711875 -0.34197998046875 -0.470367431640625 0.2729187011718668 +1.712 -0.343231201171875 -0.472137451171875 0.2729187011718668 +1.7121250000000002 -0.343231201171875 -0.472137451171875 0.2729187011718668 +1.71225 -0.344482421875 -0.47381591796875 0.2729187011718668 +1.712375 -0.345672607421875 -0.4754638671875 0.2729187011718668 +1.7125000000000002 -0.345672607421875 -0.4754638671875 0.2729187011718668 +1.712625 -0.346832275390625 -0.47705078125 0.2729187011718668 +1.71275 -0.346832275390625 -0.47705078125 0.2729187011718668 +1.712875 -0.34796142578125 -0.478607177734375 0.2729187011718668 +1.713 -0.349029541015625 -0.480072021484375 0.2729187011718668 +1.713125 -0.349029541015625 -0.480072021484375 0.2729187011718668 +1.71325 -0.350067138671875 -0.48150634765625 0.2729187011718668 +1.713375 -0.350067138671875 -0.48150634765625 0.2729187011718668 +1.7135 -0.35107421875 -0.48291015625 0.2729187011718668 +1.713625 -0.35205078125 -0.484222412109375 0.2729187011718668 +1.71375 -0.35205078125 -0.484222412109375 0.2729187011718668 +1.713875 -0.35296630859375 -0.485504150390625 0.2729187011718668 +1.714 -0.35296630859375 -0.485504150390625 0.2729187011718668 +1.7141250000000002 -0.353851318359375 -0.486724853515625 0.2729187011718668 +1.71425 -0.354705810546875 -0.487884521484375 0.2729187011718668 +1.714375 -0.354705810546875 -0.487884521484375 0.2729187011718668 +1.7145000000000002 -0.35552978515625 -0.489013671875 0.2729187011718668 +1.714625 -0.35552978515625 -0.489013671875 0.2729187011718668 +1.71475 -0.356292724609375 -0.490081787109375 0.2729187011718668 +1.714875 -0.357025146484375 -0.4910888671875 0.2729187011718668 +1.715 -0.357025146484375 -0.4910888671875 0.2729187011718668 +1.715125 -0.35772705078125 -0.492034912109375 0.2729187011718668 +1.71525 -0.35772705078125 -0.492034912109375 0.2729187011718668 +1.715375 -0.358367919921875 -0.492950439453125 0.2729187011718668 +1.7155 -0.358978271484375 -0.4937744140625 0.2729187011718668 +1.715625 -0.358978271484375 -0.4937744140625 0.2729187011718668 +1.71575 -0.35955810546875 -0.49456787109375 0.2729187011718668 +1.715875 -0.35955810546875 -0.49456787109375 0.2729187011718668 +1.716 -0.360107421875 -0.49530029296875 0.2729187011718668 +1.7161250000000002 -0.360595703125 -0.496002197265625 0.2729187011718668 +1.71625 -0.360595703125 -0.496002197265625 0.2729187011718668 +1.716375 -0.361053466796875 -0.496612548828125 0.2729187011718668 +1.7165000000000002 -0.361053466796875 -0.496612548828125 0.2729187011718668 +1.716625 -0.361480712890625 -0.4971923828125 0.2729187011718668 +1.71675 -0.361846923828125 -0.497711181640625 0.2729187011718668 +1.716875 -0.361846923828125 -0.497711181640625 0.2729187011718668 +1.717 -0.3621826171875 -0.498199462890625 0.2729187011718668 +1.717125 -0.3621826171875 -0.498199462890625 0.2729187011718668 +1.71725 -0.36248779296875 -0.49859619140625 0.2729187011718668 +1.717375 -0.362762451171875 -0.49896240234375 0.2729187011718668 +1.7175 -0.362762451171875 -0.49896240234375 0.2729187011718668 +1.717625 -0.36297607421875 -0.499267578125 0.2729187011718668 +1.71775 -0.36297607421875 -0.499267578125 0.2729187011718668 +1.717875 -0.3631591796875 -0.49951171875 0.2729187011718668 +1.718 -0.36328125 -0.49969482421875 0.2729187011718668 +1.7181250000000002 -0.36328125 -0.49969482421875 0.2729187011718668 +1.71825 -0.363372802734375 -0.49981689453125 0.2729187011718668 +1.718375 -0.363372802734375 -0.49981689453125 0.2729187011718668 +1.7185000000000002 -0.363433837890625 -0.499908447265625 0.2729187011718668 +1.718625 -0.36346435546875 -0.49993896484375 0.2729187011718668 +1.71875 -0.36346435546875 -0.49993896484375 0.2729187011718668 +1.718875 -0.363433837890625 -0.499908447265625 0.2729187011718668 +1.719 -0.363433837890625 -0.499908447265625 0.2729187011718668 +1.719125 -0.363372802734375 -0.49981689453125 0.2729187011718668 +1.71925 -0.36328125 -0.49969482421875 0.2729187011718668 +1.719375 -0.36328125 -0.49969482421875 0.2729187011718668 +1.7195 -0.3631591796875 -0.49951171875 0.2729187011718668 +1.719625 -0.3631591796875 -0.49951171875 0.2729187011718668 +1.7197500000000002 -0.36297607421875 -0.499267578125 0.2729187011718668 +1.719875 -0.362762451171875 -0.49896240234375 0.2729187011718668 +1.72 -0.362762451171875 -0.49896240234375 0.2729187011718668 +1.7201250000000002 -0.36248779296875 -0.49859619140625 0.2729187011718668 +1.72025 -0.36248779296875 -0.49859619140625 0.2729187011718668 +1.720375 -0.3621826171875 -0.498199462890625 0.2729187011718668 +1.7205000000000002 -0.361846923828125 -0.497711181640625 0.2729187011718668 +1.720625 -0.361846923828125 -0.497711181640625 0.2729187011718668 +1.72075 -0.361480712890625 -0.4971923828125 0.2729187011718668 +1.720875 -0.361480712890625 -0.4971923828125 0.2729187011718668 +1.721 -0.361053466796875 -0.496612548828125 0.2729187011718668 +1.721125 -0.360595703125 -0.496002197265625 0.2729187011718668 +1.72125 -0.360595703125 -0.496002197265625 0.2729187011718668 +1.721375 -0.360107421875 -0.49530029296875 0.2729187011718668 +1.7215 -0.360107421875 -0.49530029296875 0.2729187011718668 +1.721625 -0.35955810546875 -0.49456787109375 0.2729187011718668 +1.7217500000000002 -0.358978271484375 -0.4937744140625 0.2729187011718668 +1.721875 -0.358978271484375 -0.4937744140625 0.2729187011718668 +1.722 -0.358367919921875 -0.492950439453125 0.2729187011718668 +1.7221250000000002 -0.358367919921875 -0.492950439453125 0.2729187011718668 +1.72225 -0.35772705078125 -0.492034912109375 0.2729187011718668 +1.722375 -0.357025146484375 -0.4910888671875 0.2729187011718668 +1.7225000000000002 -0.357025146484375 -0.4910888671875 0.2729187011718668 +1.722625 -0.356292724609375 -0.490081787109375 0.2729187011718668 +1.72275 -0.356292724609375 -0.490081787109375 0.2729187011718668 +1.722875 -0.35552978515625 -0.489013671875 0.2729187011718668 +1.723 -0.354705810546875 -0.487884521484375 0.2729187011718668 +1.723125 -0.354705810546875 -0.487884521484375 0.2729187011718668 +1.72325 -0.353851318359375 -0.486724853515625 0.2729187011718668 +1.723375 -0.353851318359375 -0.486724853515625 0.2729187011718668 +1.7235 -0.35296630859375 -0.485504150390625 0.2729187011718668 +1.723625 -0.35205078125 -0.484222412109375 0.2729187011718668 +1.7237500000000002 -0.35205078125 -0.484222412109375 0.2729187011718668 +1.723875 -0.35107421875 -0.48291015625 0.2729187011718668 +1.724 -0.35107421875 -0.48291015625 0.2729187011718668 +1.7241250000000002 -0.350067138671875 -0.48150634765625 0.2729187011718668 +1.72425 -0.349029541015625 -0.480072021484375 0.2729187011718668 +1.724375 -0.349029541015625 -0.480072021484375 0.2729187011718668 +1.7245000000000002 -0.34796142578125 -0.478607177734375 0.2729187011718668 +1.724625 -0.34796142578125 -0.478607177734375 0.2729187011718668 +1.72475 -0.346832275390625 -0.47705078125 0.2729187011718668 +1.724875 -0.345672607421875 -0.4754638671875 0.2729187011718668 +1.725 -0.345672607421875 -0.4754638671875 0.2729187011718668 +1.725125 -0.344482421875 -0.47381591796875 0.2729187011718668 +1.72525 -0.344482421875 -0.47381591796875 0.2729187011718668 +1.725375 -0.343231201171875 -0.472137451171875 0.2729187011718668 +1.7255 -0.34197998046875 -0.470367431640625 0.2729187011718668 +1.725625 -0.34197998046875 -0.470367431640625 0.2729187011718668 +1.7257500000000002 -0.340667724609375 -0.46856689453125 0.2729187011718668 +1.725875 -0.340667724609375 -0.46856689453125 0.2729187011718668 +1.726 -0.339324951171875 -0.46673583984375 0.2729187011718668 +1.7261250000000002 -0.337921142578125 -0.464813232421875 0.2729187011718668 +1.72625 -0.337921142578125 -0.464813232421875 0.2729187011718668 +1.726375 -0.336517333984375 -0.462890625 0.2729187011718668 +1.7265000000000002 -0.336517333984375 -0.462890625 0.2729187011718668 +1.726625 -0.335052490234375 -0.46087646484375 0.2729187011718668 +1.72675 -0.333587646484375 -0.458831787109375 0.2729187011718668 +1.726875 -0.333587646484375 -0.458831787109375 0.2729187011718668 +1.727 -0.33203125 -0.45672607421875 0.2729187011718668 +1.727125 -0.33203125 -0.45672607421875 0.2729187011718668 +1.72725 -0.330474853515625 -0.454559326171875 0.2729187011718668 +1.727375 -0.328857421875 -0.452362060546875 0.2729187011718668 +1.7275 -0.328857421875 -0.452362060546875 0.2729187011718668 +1.727625 -0.327239990234375 -0.450103759765625 0.2729187011718668 +1.7277500000000002 -0.327239990234375 -0.450103759765625 0.2729187011718668 +1.727875 -0.3255615234375 -0.447784423828125 0.2729187011718668 +1.728 -0.4454345703125 -0.389617919921875 -0.12530517578125826 +1.7281250000000002 -0.4454345703125 -0.389617919921875 -0.12530517578125826 +1.72825 -0.44305419921875 -0.38751220703125 -0.12530517578125826 +1.728375 -0.44305419921875 -0.38751220703125 -0.12530517578125826 +1.7285 -0.440582275390625 -0.385345458984375 -0.12530517578125826 +1.728625 -0.438079833984375 -0.3831787109375 -0.12530517578125826 +1.72875 -0.438079833984375 -0.3831787109375 -0.12530517578125826 +1.728875 -0.435546875 -0.380950927734375 -0.12530517578125826 +1.729 -0.435546875 -0.380950927734375 -0.12530517578125826 +1.729125 -0.432952880859375 -0.378692626953125 -0.12530517578125826 +1.72925 -0.4302978515625 -0.376373291015625 -0.12530517578125826 +1.729375 -0.4302978515625 -0.376373291015625 -0.12530517578125826 +1.7295 -0.4276123046875 -0.3740234375 -0.12530517578125826 +1.729625 -0.4276123046875 -0.3740234375 -0.12530517578125826 +1.7297500000000002 -0.424896240234375 -0.371612548828125 -0.12530517578125826 +1.729875 -0.422119140625 -0.36920166015625 -0.12530517578125826 +1.73 -0.422119140625 -0.36920166015625 -0.12530517578125826 +1.7301250000000002 -0.419281005859375 -0.366729736328125 -0.12530517578125826 +1.73025 -0.419281005859375 -0.366729736328125 -0.12530517578125826 +1.730375 -0.416412353515625 -0.36419677734375 -0.12530517578125826 +1.7305 -0.413482666015625 -0.36163330078125 -0.12530517578125826 +1.730625 -0.413482666015625 -0.36163330078125 -0.12530517578125826 +1.73075 -0.4105224609375 -0.35906982421875 -0.12530517578125826 +1.730875 -0.4105224609375 -0.35906982421875 -0.12530517578125826 +1.731 -0.407501220703125 -0.356414794921875 -0.12530517578125826 +1.731125 -0.404449462890625 -0.353759765625 -0.12530517578125826 +1.73125 -0.404449462890625 -0.353759765625 -0.12530517578125826 +1.731375 -0.401336669921875 -0.351043701171875 -0.12530517578125826 +1.7315 -0.401336669921875 -0.351043701171875 -0.12530517578125826 +1.731625 -0.398193359375 -0.348297119140625 -0.12530517578125826 +1.7317500000000002 -0.39501953125 -0.34552001953125 -0.12530517578125826 +1.731875 -0.39501953125 -0.34552001953125 -0.12530517578125826 +1.732 -0.39178466796875 -0.342681884765625 -0.12530517578125826 +1.7321250000000002 -0.39178466796875 -0.342681884765625 -0.12530517578125826 +1.73225 -0.388519287109375 -0.339813232421875 -0.12530517578125826 +1.732375 -0.38519287109375 -0.3369140625 -0.12530517578125826 +1.7325 -0.38519287109375 -0.3369140625 -0.12530517578125826 +1.732625 -0.3818359375 -0.333984375 -0.12530517578125826 +1.73275 -0.3818359375 -0.333984375 -0.12530517578125826 +1.732875 -0.378448486328125 -0.33099365234375 -0.12530517578125826 +1.733 -0.375 -0.327972412109375 -0.12530517578125826 +1.733125 -0.375 -0.327972412109375 -0.12530517578125826 +1.73325 -0.37152099609375 -0.324951171875 -0.12530517578125826 +1.733375 -0.37152099609375 -0.324951171875 -0.12530517578125826 +1.7335 -0.36798095703125 -0.321868896484375 -0.12530517578125826 +1.733625 -0.36444091796875 -0.318756103515625 -0.12530517578125826 +1.7337500000000002 -0.36444091796875 -0.318756103515625 -0.12530517578125826 +1.733875 -0.360809326171875 -0.315582275390625 -0.12530517578125826 +1.734 -0.360809326171875 -0.315582275390625 -0.12530517578125826 +1.7341250000000002 -0.357177734375 -0.312408447265625 -0.12530517578125826 +1.73425 -0.353485107421875 -0.309173583984375 -0.12530517578125826 +1.734375 -0.353485107421875 -0.309173583984375 -0.12530517578125826 +1.7345 -0.349761962890625 -0.305938720703125 -0.12530517578125826 +1.734625 -0.349761962890625 -0.305938720703125 -0.12530517578125826 +1.73475 -0.34600830078125 -0.302642822265625 -0.12530517578125826 +1.734875 -0.34222412109375 -0.29931640625 -0.12530517578125826 +1.735 -0.34222412109375 -0.29931640625 -0.12530517578125826 +1.735125 -0.33837890625 -0.29595947265625 -0.12530517578125826 +1.73525 -0.33837890625 -0.29595947265625 -0.12530517578125826 +1.7353750000000002 -0.334503173828125 -0.292572021484375 -0.12530517578125826 +1.7355 -0.330596923828125 -0.289154052734375 -0.12530517578125826 +1.735625 -0.330596923828125 -0.289154052734375 -0.12530517578125826 +1.7357500000000002 -0.32666015625 -0.28570556640625 -0.12530517578125826 +1.735875 -0.32666015625 -0.28570556640625 -0.12530517578125826 +1.736 -0.322662353515625 -0.2822265625 -0.12530517578125826 +1.7361250000000002 -0.31866455078125 -0.278717041015625 -0.12530517578125826 +1.73625 -0.31866455078125 -0.278717041015625 -0.12530517578125826 +1.736375 -0.314605712890625 -0.275177001953125 -0.12530517578125826 +1.7365 -0.314605712890625 -0.275177001953125 -0.12530517578125826 +1.736625 -0.310516357421875 -0.2716064453125 -0.12530517578125826 +1.73675 -0.306396484375 -0.26800537109375 -0.12530517578125826 +1.736875 -0.306396484375 -0.26800537109375 -0.12530517578125826 +1.737 -0.30224609375 -0.26434326171875 -0.12530517578125826 +1.737125 -0.30224609375 -0.26434326171875 -0.12530517578125826 +1.73725 -0.298065185546875 -0.260711669921875 -0.12530517578125826 +1.7373750000000002 -0.2938232421875 -0.256988525390625 -0.12530517578125826 +1.7375 -0.2938232421875 -0.256988525390625 -0.12530517578125826 +1.737625 -0.289581298828125 -0.2532958984375 -0.12530517578125826 +1.7377500000000002 -0.289581298828125 -0.2532958984375 -0.12530517578125826 +1.737875 -0.285308837890625 -0.249542236328125 -0.12530517578125826 +1.738 -0.280975341796875 -0.245758056640625 -0.12530517578125826 +1.7381250000000002 -0.280975341796875 -0.245758056640625 -0.12530517578125826 +1.73825 -0.276641845703125 -0.241973876953125 -0.12530517578125826 +1.738375 -0.276641845703125 -0.241973876953125 -0.12530517578125826 +1.7385 -0.27227783203125 -0.2381591796875 -0.12530517578125826 +1.738625 -0.267852783203125 -0.234283447265625 -0.12530517578125826 +1.73875 -0.267852783203125 -0.234283447265625 -0.12530517578125826 +1.738875 -0.263427734375 -0.23040771484375 -0.12530517578125826 +1.739 -0.263427734375 -0.23040771484375 -0.12530517578125826 +1.739125 -0.25897216796875 -0.22650146484375 -0.12530517578125826 +1.73925 -0.25445556640625 -0.222564697265625 -0.12530517578125826 +1.7393750000000002 -0.25445556640625 -0.222564697265625 -0.12530517578125826 +1.7395 -0.249969482421875 -0.2186279296875 -0.12530517578125826 +1.739625 -0.249969482421875 -0.2186279296875 -0.12530517578125826 +1.7397500000000002 -0.24542236328125 -0.214630126953125 -0.12530517578125826 +1.739875 -0.2408447265625 -0.21063232421875 -0.12530517578125826 +1.74 -0.2408447265625 -0.21063232421875 -0.12530517578125826 +1.7401250000000002 -0.236236572265625 -0.206634521484375 -0.12530517578125826 +1.74025 -0.236236572265625 -0.206634521484375 -0.12530517578125826 +1.740375 -0.231597900390625 -0.20257568359375 -0.12530517578125826 +1.7405 -0.226959228515625 -0.198486328125 -0.12530517578125826 +1.740625 -0.226959228515625 -0.198486328125 -0.12530517578125826 +1.74075 -0.2222900390625 -0.194427490234375 -0.12530517578125826 +1.740875 -0.2222900390625 -0.194427490234375 -0.12530517578125826 +1.741 -0.21759033203125 -0.1903076171875 -0.12530517578125826 +1.741125 -0.212860107421875 -0.1861572265625 -0.12530517578125826 +1.74125 -0.212860107421875 -0.1861572265625 -0.12530517578125826 +1.7413750000000002 -0.208099365234375 -0.1820068359375 -0.12530517578125826 +1.7415 -0.208099365234375 -0.1820068359375 -0.12530517578125826 +1.741625 -0.203338623046875 -0.177825927734375 -0.12530517578125826 +1.7417500000000002 -0.19854736328125 -0.17364501953125 -0.12530517578125826 +1.741875 -0.19854736328125 -0.17364501953125 -0.12530517578125826 +1.742 -0.1937255859375 -0.16943359375 -0.12530517578125826 +1.7421250000000002 -0.1937255859375 -0.16943359375 -0.12530517578125826 +1.74225 -0.188873291015625 -0.165191650390625 -0.12530517578125826 +1.742375 -0.18402099609375 -0.16094970703125 -0.12530517578125826 +1.7425 -0.18402099609375 -0.16094970703125 -0.12530517578125826 +1.742625 -0.17913818359375 -0.15667724609375 -0.12530517578125826 +1.74275 -0.17913818359375 -0.15667724609375 -0.12530517578125826 +1.742875 -0.17425537109375 -0.15240478515625 -0.12530517578125826 +1.743 -0.169342041015625 -0.148101806640625 -0.12530517578125826 +1.743125 -0.169342041015625 -0.148101806640625 -0.12530517578125826 +1.74325 -0.164398193359375 -0.143768310546875 -0.12530517578125826 +1.7433750000000002 -0.164398193359375 -0.143768310546875 -0.12530517578125826 +1.7435 -0.159454345703125 -0.13946533203125 -0.12530517578125826 +1.743625 -0.15447998046875 -0.135101318359375 -0.12530517578125826 +1.7437500000000002 -0.15447998046875 -0.135101318359375 -0.12530517578125826 +1.743875 -0.14947509765625 -0.1307373046875 -0.12530517578125826 +1.744 -0.14947509765625 -0.1307373046875 -0.12530517578125826 +1.744125 -0.14447021484375 -0.126373291015625 -0.12530517578125826 +1.74425 -0.13946533203125 -0.121978759765625 -0.12530517578125826 +1.744375 -0.13946533203125 -0.121978759765625 -0.12530517578125826 +1.7445 -0.134429931640625 -0.117584228515625 -0.12530517578125826 +1.744625 -0.134429931640625 -0.117584228515625 -0.12530517578125826 +1.74475 -0.129364013671875 -0.1131591796875 -0.12530517578125826 +1.744875 -0.124298095703125 -0.108734130859375 -0.12530517578125826 +1.745 -0.124298095703125 -0.108734130859375 -0.12530517578125826 +1.745125 -0.119232177734375 -0.104278564453125 -0.12530517578125826 +1.74525 -0.119232177734375 -0.104278564453125 -0.12530517578125826 +1.7453750000000002 -0.1141357421875 -0.099822998046875 -0.12530517578125826 +1.7455 -0.109039306640625 -0.095367431640625 -0.12530517578125826 +1.745625 -0.109039306640625 -0.095367431640625 -0.12530517578125826 +1.7457500000000002 -0.103912353515625 -0.09088134765625 -0.12530517578125826 +1.745875 -0.103912353515625 -0.09088134765625 -0.12530517578125826 +1.746 -0.098785400390625 -0.086395263671875 -0.12530517578125826 +1.746125 -0.093658447265625 -0.0819091796875 -0.12530517578125826 +1.74625 -0.093658447265625 -0.0819091796875 -0.12530517578125826 +1.746375 -0.0885009765625 -0.077423095703125 -0.12530517578125826 +1.7465 -0.0885009765625 -0.077423095703125 -0.12530517578125826 +1.746625 -0.083343505859375 -0.072906494140625 -0.12530517578125826 +1.74675 -0.07818603515625 -0.068389892578125 -0.12530517578125826 +1.746875 -0.07818603515625 -0.068389892578125 -0.12530517578125826 +1.747 -0.072998046875 -0.0638427734375 -0.12530517578125826 +1.747125 -0.072998046875 -0.0638427734375 -0.12530517578125826 +1.74725 -0.06781005859375 -0.059326171875 -0.12530517578125826 +1.7473750000000002 -0.0626220703125 -0.054779052734375 -0.12530517578125826 +1.7475 -0.0626220703125 -0.054779052734375 -0.12530517578125826 +1.747625 -0.05743408203125 -0.05023193359375 -0.12530517578125826 +1.7477500000000002 -0.05743408203125 -0.05023193359375 -0.12530517578125826 +1.747875 -0.05224609375 -0.045684814453125 -0.12530517578125826 +1.748 -0.047027587890625 -0.0411376953125 -0.12530517578125826 +1.748125 -0.047027587890625 -0.0411376953125 -0.12530517578125826 +1.74825 -0.04180908203125 -0.03656005859375 -0.12530517578125826 +1.748375 -0.04180908203125 -0.03656005859375 -0.12530517578125826 +1.7485 -0.036590576171875 -0.032012939453125 -0.12530517578125826 +1.748625 -0.0313720703125 -0.027435302734375 -0.12530517578125826 +1.74875 -0.0313720703125 -0.027435302734375 -0.12530517578125826 +1.748875 -0.026123046875 -0.022857666015625 -0.12530517578125826 +1.749 -0.026123046875 -0.022857666015625 -0.12530517578125826 +1.749125 -0.020904541015625 -0.018280029296875 -0.12530517578125826 +1.74925 -0.01568603515625 -0.013702392578125 -0.12530517578125826 +1.7493750000000002 -0.01568603515625 -0.013702392578125 -0.12530517578125826 +1.7495 -0.01043701171875 -0.009124755859375 -0.12530517578125826 +1.749625 -0.01043701171875 -0.009124755859375 -0.12530517578125826 +1.7497500000000002 -0.005218505859375 -0.004547119140625 -0.12530517578125826 +1.749875 0.0 0.0 -0.12530517578125826 +1.75 0.0 0.0 -0.12530517578125826 +1.750125 0.005218505859375 0.004547119140625 -0.12530517578125826 +1.75025 0.005218505859375 0.004547119140625 -0.12530517578125826 +1.750375 0.01043701171875 0.009124755859375 -0.12530517578125826 +1.7505 0.01568603515625 0.013702392578125 -0.12530517578125826 +1.750625 0.01568603515625 0.013702392578125 -0.12530517578125826 +1.75075 0.020904541015625 0.018280029296875 -0.12530517578125826 +1.750875 0.020904541015625 0.018280029296875 -0.12530517578125826 +1.7510000000000002 0.026123046875 0.022857666015625 -0.12530517578125826 +1.751125 0.0313720703125 0.027435302734375 -0.12530517578125826 +1.75125 0.0313720703125 0.027435302734375 -0.12530517578125826 +1.7513750000000002 0.036590576171875 0.032012939453125 -0.12530517578125826 +1.7515 0.036590576171875 0.032012939453125 -0.12530517578125826 +1.751625 0.04180908203125 0.03656005859375 -0.12530517578125826 +1.7517500000000002 0.047027587890625 0.0411376953125 -0.12530517578125826 +1.751875 0.047027587890625 0.0411376953125 -0.12530517578125826 +1.752 0.05224609375 0.045684814453125 -0.12530517578125826 +1.752125 0.05224609375 0.045684814453125 -0.12530517578125826 +1.75225 0.05743408203125 0.05023193359375 -0.12530517578125826 +1.752375 0.0626220703125 0.054779052734375 -0.12530517578125826 +1.7525 0.0626220703125 0.054779052734375 -0.12530517578125826 +1.752625 0.06781005859375 0.059326171875 -0.12530517578125826 +1.75275 0.06781005859375 0.059326171875 -0.12530517578125826 +1.752875 0.072998046875 0.0638427734375 -0.12530517578125826 +1.7530000000000002 0.07818603515625 0.068389892578125 -0.12530517578125826 +1.753125 0.07818603515625 0.068389892578125 -0.12530517578125826 +1.75325 0.083343505859375 0.072906494140625 -0.12530517578125826 +1.7533750000000002 0.083343505859375 0.072906494140625 -0.12530517578125826 +1.7535 0.0885009765625 0.077423095703125 -0.12530517578125826 +1.753625 0.093658447265625 0.0819091796875 -0.12530517578125826 +1.7537500000000002 0.093658447265625 0.0819091796875 -0.12530517578125826 +1.753875 0.098785400390625 0.086395263671875 -0.12530517578125826 +1.754 0.098785400390625 0.086395263671875 -0.12530517578125826 +1.754125 0.103912353515625 0.09088134765625 -0.12530517578125826 +1.75425 0.109039306640625 0.095367431640625 -0.12530517578125826 +1.754375 0.109039306640625 0.095367431640625 -0.12530517578125826 +1.7545 0.1141357421875 0.099822998046875 -0.12530517578125826 +1.754625 0.1141357421875 0.099822998046875 -0.12530517578125826 +1.75475 0.119232177734375 0.104278564453125 -0.12530517578125826 +1.754875 0.124298095703125 0.108734130859375 -0.12530517578125826 +1.7550000000000002 0.124298095703125 0.108734130859375 -0.12530517578125826 +1.755125 0.129364013671875 0.1131591796875 -0.12530517578125826 +1.75525 0.129364013671875 0.1131591796875 -0.12530517578125826 +1.7553750000000002 0.134429931640625 0.117584228515625 -0.12530517578125826 +1.7555 0.13946533203125 0.121978759765625 -0.12530517578125826 +1.755625 0.13946533203125 0.121978759765625 -0.12530517578125826 +1.7557500000000002 0.14447021484375 0.126373291015625 -0.12530517578125826 +1.755875 0.14447021484375 0.126373291015625 -0.12530517578125826 +1.756 0.14947509765625 0.1307373046875 -0.12530517578125826 +1.756125 0.15447998046875 0.135101318359375 -0.12530517578125826 +1.75625 0.15447998046875 0.135101318359375 -0.12530517578125826 +1.756375 0.159454345703125 0.13946533203125 -0.12530517578125826 +1.7565 0.159454345703125 0.13946533203125 -0.12530517578125826 +1.756625 0.164398193359375 0.143768310546875 -0.12530517578125826 +1.75675 0.169342041015625 0.148101806640625 -0.12530517578125826 +1.756875 0.169342041015625 0.148101806640625 -0.12530517578125826 +1.7570000000000002 0.17425537109375 0.15240478515625 -0.12530517578125826 +1.757125 0.17425537109375 0.15240478515625 -0.12530517578125826 +1.75725 0.17913818359375 0.15667724609375 -0.12530517578125826 +1.7573750000000002 0.18402099609375 0.16094970703125 -0.12530517578125826 +1.7575 0.18402099609375 0.16094970703125 -0.12530517578125826 +1.757625 0.188873291015625 0.165191650390625 -0.12530517578125826 +1.7577500000000002 0.188873291015625 0.165191650390625 -0.12530517578125826 +1.757875 0.1937255859375 0.16943359375 -0.12530517578125826 +1.758 0.19854736328125 0.17364501953125 -0.12530517578125826 +1.758125 0.19854736328125 0.17364501953125 -0.12530517578125826 +1.75825 0.203338623046875 0.177825927734375 -0.12530517578125826 +1.758375 0.203338623046875 0.177825927734375 -0.12530517578125826 +1.7585 0.208099365234375 0.1820068359375 -0.12530517578125826 +1.758625 0.212860107421875 0.1861572265625 -0.12530517578125826 +1.75875 0.212860107421875 0.1861572265625 -0.12530517578125826 +1.758875 0.21759033203125 0.1903076171875 -0.12530517578125826 +1.7590000000000002 0.21759033203125 0.1903076171875 -0.12530517578125826 +1.759125 0.2222900390625 0.194427490234375 -0.12530517578125826 +1.75925 0.226959228515625 0.198486328125 -0.12530517578125826 +1.7593750000000002 0.226959228515625 0.198486328125 -0.12530517578125826 +1.7595 0.231597900390625 0.20257568359375 -0.12530517578125826 +1.759625 0.231597900390625 0.20257568359375 -0.12530517578125826 +1.7597500000000002 0.236236572265625 0.206634521484375 -0.12530517578125826 +1.759875 0.2408447265625 0.21063232421875 -0.12530517578125826 +1.76 0.2408447265625 0.119537353515625 -0.5035827636718825 +1.760125 0.24542236328125 0.121795654296875 -0.5035827636718825 +1.76025 0.24542236328125 0.121795654296875 -0.5035827636718825 +1.760375 0.249969482421875 0.124053955078125 -0.5035827636718825 +1.7605 0.25445556640625 0.126312255859375 -0.5035827636718825 +1.760625 0.25445556640625 0.126312255859375 -0.5035827636718825 +1.76075 0.25897216796875 0.1285400390625 -0.5035827636718825 +1.760875 0.25897216796875 0.1285400390625 -0.5035827636718825 +1.7610000000000002 0.263427734375 0.1307373046875 -0.5035827636718825 +1.761125 0.267852783203125 0.132965087890625 -0.5035827636718825 +1.76125 0.267852783203125 0.132965087890625 -0.5035827636718825 +1.7613750000000002 0.27227783203125 0.1351318359375 -0.5035827636718825 +1.7615 0.27227783203125 0.1351318359375 -0.5035827636718825 +1.761625 0.276641845703125 0.137298583984375 -0.5035827636718825 +1.76175 0.280975341796875 0.13946533203125 -0.5035827636718825 +1.761875 0.280975341796875 0.13946533203125 -0.5035827636718825 +1.762 0.285308837890625 0.1416015625 -0.5035827636718825 +1.762125 0.285308837890625 0.1416015625 -0.5035827636718825 +1.76225 0.289581298828125 0.14373779296875 -0.5035827636718825 +1.762375 0.2938232421875 0.145843505859375 -0.5035827636718825 +1.7625 0.2938232421875 0.145843505859375 -0.5035827636718825 +1.762625 0.298065185546875 0.14794921875 -0.5035827636718825 +1.76275 0.298065185546875 0.14794921875 -0.5035827636718825 +1.762875 0.30224609375 0.1500244140625 -0.5035827636718825 +1.7630000000000002 0.306396484375 0.152069091796875 -0.5035827636718825 +1.763125 0.306396484375 0.152069091796875 -0.5035827636718825 +1.76325 0.310516357421875 0.15411376953125 -0.5035827636718825 +1.7633750000000002 0.310516357421875 0.15411376953125 -0.5035827636718825 +1.7635 0.314605712890625 0.156158447265625 -0.5035827636718825 +1.763625 0.31866455078125 0.158172607421875 -0.5035827636718825 +1.76375 0.31866455078125 0.158172607421875 -0.5035827636718825 +1.763875 0.322662353515625 0.16015625 -0.5035827636718825 +1.764 0.322662353515625 0.16015625 -0.5035827636718825 +1.764125 0.32666015625 0.162139892578125 -0.5035827636718825 +1.76425 0.330596923828125 0.164093017578125 -0.5035827636718825 +1.764375 0.330596923828125 0.164093017578125 -0.5035827636718825 +1.7645 0.334503173828125 0.166046142578125 -0.5035827636718825 +1.764625 0.334503173828125 0.166046142578125 -0.5035827636718825 +1.76475 0.33837890625 0.16796875 -0.5035827636718825 +1.764875 0.34222412109375 0.16986083984375 -0.5035827636718825 +1.7650000000000002 0.34222412109375 0.16986083984375 -0.5035827636718825 +1.765125 0.34600830078125 0.1717529296875 -0.5035827636718825 +1.76525 0.34600830078125 0.1717529296875 -0.5035827636718825 +1.7653750000000002 0.349761962890625 0.173614501953125 -0.5035827636718825 +1.7655 0.353485107421875 0.175445556640625 -0.5035827636718825 +1.765625 0.353485107421875 0.175445556640625 -0.5035827636718825 +1.76575 0.357177734375 0.177276611328125 -0.5035827636718825 +1.765875 0.357177734375 0.177276611328125 -0.5035827636718825 +1.766 0.360809326171875 0.1790771484375 -0.5035827636718825 +1.766125 0.36444091796875 0.180877685546875 -0.5035827636718825 +1.76625 0.36444091796875 0.180877685546875 -0.5035827636718825 +1.766375 0.36798095703125 0.182647705078125 -0.5035827636718825 +1.7665 0.36798095703125 0.182647705078125 -0.5035827636718825 +1.7666250000000002 0.37152099609375 0.18438720703125 -0.5035827636718825 +1.76675 0.375 0.186126708984375 -0.5035827636718825 +1.766875 0.375 0.186126708984375 -0.5035827636718825 +1.7670000000000002 0.378448486328125 0.187835693359375 -0.5035827636718825 +1.767125 0.378448486328125 0.187835693359375 -0.5035827636718825 +1.76725 0.3818359375 0.18951416015625 -0.5035827636718825 +1.7673750000000002 0.38519287109375 0.191192626953125 -0.5035827636718825 +1.7675 0.38519287109375 0.191192626953125 -0.5035827636718825 +1.767625 0.388519287109375 0.192840576171875 -0.5035827636718825 +1.76775 0.388519287109375 0.192840576171875 -0.5035827636718825 +1.767875 0.39178466796875 0.1944580078125 -0.5035827636718825 +1.768 0.39501953125 0.196075439453125 -0.5035827636718825 +1.768125 0.39501953125 0.196075439453125 -0.5035827636718825 +1.76825 0.398193359375 0.1976318359375 -0.5035827636718825 +1.768375 0.398193359375 0.1976318359375 -0.5035827636718825 +1.7685 0.401336669921875 0.19921875 -0.5035827636718825 +1.7686250000000002 0.404449462890625 0.20074462890625 -0.5035827636718825 +1.76875 0.404449462890625 0.20074462890625 -0.5035827636718825 +1.768875 0.407501220703125 0.2022705078125 -0.5035827636718825 +1.7690000000000002 0.407501220703125 0.2022705078125 -0.5035827636718825 +1.769125 0.4105224609375 0.203765869140625 -0.5035827636718825 +1.76925 0.413482666015625 0.205230712890625 -0.5035827636718825 +1.7693750000000002 0.413482666015625 0.205230712890625 -0.5035827636718825 +1.7695 0.416412353515625 0.206695556640625 -0.5035827636718825 +1.769625 0.416412353515625 0.206695556640625 -0.5035827636718825 +1.76975 0.419281005859375 0.208099365234375 -0.5035827636718825 +1.769875 0.422119140625 0.209503173828125 -0.5035827636718825 +1.77 0.422119140625 0.209503173828125 -0.5035827636718825 +1.770125 0.424896240234375 0.210906982421875 -0.5035827636718825 +1.77025 0.424896240234375 0.210906982421875 -0.5035827636718825 +1.770375 0.4276123046875 0.212249755859375 -0.5035827636718825 +1.7705 0.4302978515625 0.213592529296875 -0.5035827636718825 +1.7706250000000002 0.4302978515625 0.213592529296875 -0.5035827636718825 +1.77075 0.432952880859375 0.21490478515625 -0.5035827636718825 +1.770875 0.432952880859375 0.21490478515625 -0.5035827636718825 +1.7710000000000002 0.435546875 0.2161865234375 -0.5035827636718825 +1.771125 0.438079833984375 0.217437744140625 -0.5035827636718825 +1.77125 0.438079833984375 0.217437744140625 -0.5035827636718825 +1.7713750000000002 0.440582275390625 0.21868896484375 -0.5035827636718825 +1.7715 0.440582275390625 0.21868896484375 -0.5035827636718825 +1.771625 0.44305419921875 0.21990966796875 -0.5035827636718825 +1.77175 0.4454345703125 0.221099853515625 -0.5035827636718825 +1.771875 0.4454345703125 0.221099853515625 -0.5035827636718825 +1.772 0.447784423828125 0.222259521484375 -0.5035827636718825 +1.772125 0.447784423828125 0.222259521484375 -0.5035827636718825 +1.77225 0.450103759765625 0.223388671875 -0.5035827636718825 +1.772375 0.452362060546875 0.224517822265625 -0.5035827636718825 +1.7725 0.452362060546875 0.224517822265625 -0.5035827636718825 +1.7726250000000002 0.454559326171875 0.225616455078125 -0.5035827636718825 +1.77275 0.454559326171875 0.225616455078125 -0.5035827636718825 +1.772875 0.45672607421875 0.2266845703125 -0.5035827636718825 +1.7730000000000002 0.458831787109375 0.22772216796875 -0.5035827636718825 +1.773125 0.458831787109375 0.22772216796875 -0.5035827636718825 +1.77325 0.46087646484375 0.228759765625 -0.5035827636718825 +1.7733750000000002 0.46087646484375 0.228759765625 -0.5035827636718825 +1.7735 0.462890625 0.229736328125 -0.5035827636718825 +1.773625 0.464813232421875 0.230712890625 -0.5035827636718825 +1.77375 0.464813232421875 0.230712890625 -0.5035827636718825 +1.773875 0.46673583984375 0.231658935546875 -0.5035827636718825 +1.774 0.46673583984375 0.231658935546875 -0.5035827636718825 +1.774125 0.46856689453125 0.232574462890625 -0.5035827636718825 +1.77425 0.470367431640625 0.23345947265625 -0.5035827636718825 +1.774375 0.470367431640625 0.23345947265625 -0.5035827636718825 +1.7745 0.472137451171875 0.234344482421875 -0.5035827636718825 +1.7746250000000002 0.472137451171875 0.234344482421875 -0.5035827636718825 +1.77475 0.47381591796875 0.23516845703125 -0.5035827636718825 +1.774875 0.4754638671875 0.235992431640625 -0.5035827636718825 +1.7750000000000002 0.4754638671875 0.235992431640625 -0.5035827636718825 +1.775125 0.47705078125 0.236785888671875 -0.5035827636718825 +1.77525 0.47705078125 0.236785888671875 -0.5035827636718825 +1.7753750000000002 0.478607177734375 0.237548828125 -0.5035827636718825 +1.7755 0.480072021484375 0.23828125 -0.5035827636718825 +1.775625 0.480072021484375 0.23828125 -0.5035827636718825 +1.77575 0.48150634765625 0.238983154296875 -0.5035827636718825 +1.775875 0.48150634765625 0.238983154296875 -0.5035827636718825 +1.776 0.48291015625 0.23968505859375 -0.5035827636718825 +1.776125 0.484222412109375 0.2403564453125 -0.5035827636718825 +1.77625 0.484222412109375 0.2403564453125 -0.5035827636718825 +1.776375 0.485504150390625 0.240966796875 -0.5035827636718825 +1.7765 0.485504150390625 0.240966796875 -0.5035827636718825 +1.7766250000000002 0.486724853515625 0.2415771484375 -0.5035827636718825 +1.77675 0.487884521484375 0.242156982421875 -0.5035827636718825 +1.776875 0.487884521484375 0.242156982421875 -0.5035827636718825 +1.7770000000000002 0.489013671875 0.242706298828125 -0.5035827636718825 +1.777125 0.489013671875 0.242706298828125 -0.5035827636718825 +1.77725 0.490081787109375 0.243255615234375 -0.5035827636718825 +1.777375 0.4910888671875 0.243743896484375 -0.5035827636718825 +1.7775 0.4910888671875 0.243743896484375 -0.5035827636718825 +1.777625 0.492034912109375 0.244232177734375 -0.5035827636718825 +1.77775 0.492034912109375 0.244232177734375 -0.5035827636718825 +1.777875 0.492950439453125 0.244659423828125 -0.5035827636718825 +1.778 0.4937744140625 0.245086669921875 -0.5035827636718825 +1.778125 0.4937744140625 0.245086669921875 -0.5035827636718825 +1.77825 0.49456787109375 0.2454833984375 -0.5035827636718825 +1.778375 0.49456787109375 0.2454833984375 -0.5035827636718825 +1.7785 0.49530029296875 0.245849609375 -0.5035827636718825 +1.7786250000000002 0.496002197265625 0.246185302734375 -0.5035827636718825 +1.77875 0.496002197265625 0.246185302734375 -0.5035827636718825 +1.778875 0.496612548828125 0.246490478515625 -0.5035827636718825 +1.7790000000000002 0.496612548828125 0.246490478515625 -0.5035827636718825 +1.779125 0.4971923828125 0.246795654296875 -0.5035827636718825 +1.77925 0.497711181640625 0.247039794921875 -0.5035827636718825 +1.779375 0.497711181640625 0.247039794921875 -0.5035827636718825 +1.7795 0.498199462890625 0.247283935546875 -0.5035827636718825 +1.779625 0.498199462890625 0.247283935546875 -0.5035827636718825 +1.77975 0.49859619140625 0.247467041015625 -0.5035827636718825 +1.779875 0.49896240234375 0.247650146484375 -0.5035827636718825 +1.78 0.49896240234375 0.247650146484375 -0.5035827636718825 +1.780125 0.499267578125 0.247802734375 -0.5035827636718825 +1.78025 0.499267578125 0.247802734375 -0.5035827636718825 +1.780375 0.49951171875 0.2479248046875 -0.5035827636718825 +1.7805 0.49969482421875 0.248016357421875 -0.5035827636718825 +1.7806250000000002 0.49969482421875 0.248016357421875 -0.5035827636718825 +1.78075 0.49981689453125 0.248077392578125 -0.5035827636718825 +1.780875 0.49981689453125 0.248077392578125 -0.5035827636718825 +1.7810000000000002 0.499908447265625 0.248138427734375 -0.5035827636718825 +1.781125 0.49993896484375 0.248138427734375 -0.5035827636718825 +1.78125 0.49993896484375 0.248138427734375 -0.5035827636718825 +1.781375 0.499908447265625 0.248138427734375 -0.5035827636718825 +1.7815 0.499908447265625 0.248138427734375 -0.5035827636718825 +1.781625 0.49981689453125 0.248077392578125 -0.5035827636718825 +1.78175 0.49969482421875 0.248016357421875 -0.5035827636718825 +1.781875 0.49969482421875 0.248016357421875 -0.5035827636718825 +1.782 0.49951171875 0.2479248046875 -0.5035827636718825 +1.782125 0.49951171875 0.2479248046875 -0.5035827636718825 +1.7822500000000002 0.499267578125 0.247802734375 -0.5035827636718825 +1.782375 0.49896240234375 0.247650146484375 -0.5035827636718825 +1.7825 0.49896240234375 0.247650146484375 -0.5035827636718825 +1.7826250000000002 0.49859619140625 0.247467041015625 -0.5035827636718825 +1.78275 0.49859619140625 0.247467041015625 -0.5035827636718825 +1.782875 0.498199462890625 0.247283935546875 -0.5035827636718825 +1.7830000000000002 0.497711181640625 0.247039794921875 -0.5035827636718825 +1.783125 0.497711181640625 0.247039794921875 -0.5035827636718825 +1.78325 0.4971923828125 0.246795654296875 -0.5035827636718825 +1.783375 0.4971923828125 0.246795654296875 -0.5035827636718825 +1.7835 0.496612548828125 0.246490478515625 -0.5035827636718825 +1.783625 0.496002197265625 0.246185302734375 -0.5035827636718825 +1.78375 0.496002197265625 0.246185302734375 -0.5035827636718825 +1.783875 0.49530029296875 0.245849609375 -0.5035827636718825 +1.784 0.49530029296875 0.245849609375 -0.5035827636718825 +1.784125 0.49456787109375 0.2454833984375 -0.5035827636718825 +1.7842500000000002 0.4937744140625 0.245086669921875 -0.5035827636718825 +1.784375 0.4937744140625 0.245086669921875 -0.5035827636718825 +1.7845 0.492950439453125 0.244659423828125 -0.5035827636718825 +1.7846250000000002 0.492950439453125 0.244659423828125 -0.5035827636718825 +1.78475 0.492034912109375 0.244232177734375 -0.5035827636718825 +1.784875 0.4910888671875 0.243743896484375 -0.5035827636718825 +1.7850000000000002 0.4910888671875 0.243743896484375 -0.5035827636718825 +1.785125 0.490081787109375 0.243255615234375 -0.5035827636718825 +1.78525 0.490081787109375 0.243255615234375 -0.5035827636718825 +1.785375 0.489013671875 0.242706298828125 -0.5035827636718825 +1.7855 0.487884521484375 0.242156982421875 -0.5035827636718825 +1.785625 0.487884521484375 0.242156982421875 -0.5035827636718825 +1.78575 0.486724853515625 0.2415771484375 -0.5035827636718825 +1.785875 0.486724853515625 0.2415771484375 -0.5035827636718825 +1.786 0.485504150390625 0.240966796875 -0.5035827636718825 +1.786125 0.484222412109375 0.2403564453125 -0.5035827636718825 +1.7862500000000002 0.484222412109375 0.2403564453125 -0.5035827636718825 +1.786375 0.48291015625 0.23968505859375 -0.5035827636718825 +1.7865 0.48291015625 0.23968505859375 -0.5035827636718825 +1.7866250000000002 0.48150634765625 0.238983154296875 -0.5035827636718825 +1.78675 0.480072021484375 0.23828125 -0.5035827636718825 +1.786875 0.480072021484375 0.23828125 -0.5035827636718825 +1.7870000000000002 0.478607177734375 0.237548828125 -0.5035827636718825 +1.787125 0.478607177734375 0.237548828125 -0.5035827636718825 +1.78725 0.47705078125 0.236785888671875 -0.5035827636718825 +1.787375 0.4754638671875 0.235992431640625 -0.5035827636718825 +1.7875 0.4754638671875 0.235992431640625 -0.5035827636718825 +1.787625 0.47381591796875 0.23516845703125 -0.5035827636718825 +1.78775 0.47381591796875 0.23516845703125 -0.5035827636718825 +1.787875 0.472137451171875 0.234344482421875 -0.5035827636718825 +1.788 0.470367431640625 0.23345947265625 -0.5035827636718825 +1.788125 0.470367431640625 0.23345947265625 -0.5035827636718825 +1.7882500000000002 0.46856689453125 0.232574462890625 -0.5035827636718825 +1.788375 0.46856689453125 0.232574462890625 -0.5035827636718825 +1.7885 0.46673583984375 0.231658935546875 -0.5035827636718825 +1.7886250000000002 0.464813232421875 0.230712890625 -0.5035827636718825 +1.78875 0.464813232421875 0.230712890625 -0.5035827636718825 +1.788875 0.462890625 0.229736328125 -0.5035827636718825 +1.7890000000000002 0.462890625 0.229736328125 -0.5035827636718825 +1.789125 0.46087646484375 0.228759765625 -0.5035827636718825 +1.78925 0.458831787109375 0.22772216796875 -0.5035827636718825 +1.789375 0.458831787109375 0.22772216796875 -0.5035827636718825 +1.7895 0.45672607421875 0.2266845703125 -0.5035827636718825 +1.789625 0.45672607421875 0.2266845703125 -0.5035827636718825 +1.78975 0.454559326171875 0.225616455078125 -0.5035827636718825 +1.789875 0.452362060546875 0.224517822265625 -0.5035827636718825 +1.79 0.452362060546875 0.224517822265625 -0.5035827636718825 +1.790125 0.450103759765625 0.223388671875 -0.5035827636718825 +1.7902500000000002 0.450103759765625 0.223388671875 -0.5035827636718825 +1.790375 0.447784423828125 0.222259521484375 -0.5035827636718825 +1.7905 0.4454345703125 0.221099853515625 -0.5035827636718825 +1.7906250000000002 0.4454345703125 0.221099853515625 -0.5035827636718825 +1.79075 0.44305419921875 0.21990966796875 -0.5035827636718825 +1.790875 0.44305419921875 0.21990966796875 -0.5035827636718825 +1.7910000000000002 0.440582275390625 0.21868896484375 -0.5035827636718825 +1.791125 0.438079833984375 0.217437744140625 -0.5035827636718825 +1.79125 0.438079833984375 0.217437744140625 -0.5035827636718825 +1.791375 0.435546875 0.2161865234375 -0.5035827636718825 +1.7915 0.435546875 0.2161865234375 -0.5035827636718825 +1.791625 0.432952880859375 0.21490478515625 -0.5035827636718825 +1.79175 0.4302978515625 0.213592529296875 -0.5035827636718825 +1.791875 0.4302978515625 0.213592529296875 -0.5035827636718825 +1.792 0.4276123046875 0.0848388671875 -0.8015075683593804 +1.792125 0.4276123046875 0.0848388671875 -0.8015075683593804 +1.7922500000000002 0.424896240234375 0.08428955078125 -0.8015075683593804 +1.792375 0.422119140625 0.083740234375 -0.8015075683593804 +1.7925 0.422119140625 0.083740234375 -0.8015075683593804 +1.7926250000000002 0.419281005859375 0.083160400390625 -0.8015075683593804 +1.79275 0.419281005859375 0.083160400390625 -0.8015075683593804 +1.792875 0.416412353515625 0.082611083984375 -0.8015075683593804 +1.793 0.413482666015625 0.08203125 -0.8015075683593804 +1.793125 0.413482666015625 0.08203125 -0.8015075683593804 +1.79325 0.4105224609375 0.081451416015625 -0.8015075683593804 +1.793375 0.4105224609375 0.081451416015625 -0.8015075683593804 +1.7935 0.407501220703125 0.080841064453125 -0.8015075683593804 +1.793625 0.404449462890625 0.080230712890625 -0.8015075683593804 +1.79375 0.404449462890625 0.080230712890625 -0.8015075683593804 +1.793875 0.401336669921875 0.079620361328125 -0.8015075683593804 +1.794 0.401336669921875 0.079620361328125 -0.8015075683593804 +1.794125 0.398193359375 0.0789794921875 -0.8015075683593804 +1.7942500000000002 0.39501953125 0.078369140625 -0.8015075683593804 +1.794375 0.39501953125 0.078369140625 -0.8015075683593804 +1.7945 0.39178466796875 0.077728271484375 -0.8015075683593804 +1.7946250000000002 0.39178466796875 0.077728271484375 -0.8015075683593804 +1.79475 0.388519287109375 0.077056884765625 -0.8015075683593804 +1.794875 0.38519287109375 0.076416015625 -0.8015075683593804 +1.795 0.38519287109375 0.076416015625 -0.8015075683593804 +1.795125 0.3818359375 0.07574462890625 -0.8015075683593804 +1.79525 0.3818359375 0.07574462890625 -0.8015075683593804 +1.795375 0.378448486328125 0.0750732421875 -0.8015075683593804 +1.7955 0.375 0.07440185546875 -0.8015075683593804 +1.795625 0.375 0.07440185546875 -0.8015075683593804 +1.79575 0.37152099609375 0.073699951171875 -0.8015075683593804 +1.795875 0.37152099609375 0.073699951171875 -0.8015075683593804 +1.796 0.36798095703125 0.072998046875 -0.8015075683593804 +1.796125 0.36444091796875 0.072296142578125 -0.8015075683593804 +1.7962500000000002 0.36444091796875 0.072296142578125 -0.8015075683593804 +1.796375 0.360809326171875 0.071563720703125 -0.8015075683593804 +1.7965 0.360809326171875 0.071563720703125 -0.8015075683593804 +1.7966250000000002 0.357177734375 0.07086181640625 -0.8015075683593804 +1.79675 0.353485107421875 0.07012939453125 -0.8015075683593804 +1.796875 0.353485107421875 0.07012939453125 -0.8015075683593804 +1.797 0.349761962890625 0.06939697265625 -0.8015075683593804 +1.797125 0.349761962890625 0.06939697265625 -0.8015075683593804 +1.79725 0.34600830078125 0.068634033203125 -0.8015075683593804 +1.797375 0.34222412109375 0.06787109375 -0.8015075683593804 +1.7975 0.34222412109375 0.06787109375 -0.8015075683593804 +1.797625 0.33837890625 0.067138671875 -0.8015075683593804 +1.79775 0.33837890625 0.067138671875 -0.8015075683593804 +1.7978750000000002 0.334503173828125 0.06634521484375 -0.8015075683593804 +1.798 0.330596923828125 0.065582275390625 -0.8015075683593804 +1.798125 0.330596923828125 0.065582275390625 -0.8015075683593804 +1.7982500000000002 0.32666015625 0.064788818359375 -0.8015075683593804 +1.798375 0.32666015625 0.064788818359375 -0.8015075683593804 +1.7985 0.322662353515625 0.063995361328125 -0.8015075683593804 +1.7986250000000002 0.31866455078125 0.063201904296875 -0.8015075683593804 +1.79875 0.31866455078125 0.063201904296875 -0.8015075683593804 +1.798875 0.314605712890625 0.062408447265625 -0.8015075683593804 +1.799 0.314605712890625 0.062408447265625 -0.8015075683593804 +1.799125 0.310516357421875 0.06158447265625 -0.8015075683593804 +1.79925 0.306396484375 0.060791015625 -0.8015075683593804 +1.799375 0.306396484375 0.060791015625 -0.8015075683593804 +1.7995 0.30224609375 0.059967041015625 -0.8015075683593804 +1.799625 0.30224609375 0.059967041015625 -0.8015075683593804 +1.79975 0.298065185546875 0.059112548828125 -0.8015075683593804 +1.7998750000000002 0.2938232421875 0.05828857421875 -0.8015075683593804 +1.8 0.2938232421875 0.05828857421875 -0.8015075683593804 +1.800125 0.289581298828125 0.05743408203125 -0.8015075683593804 +1.8002500000000002 0.289581298828125 0.05743408203125 -0.8015075683593804 +1.800375 0.285308837890625 0.05657958984375 -0.8015075683593804 +1.8005 0.280975341796875 0.05572509765625 -0.8015075683593804 +1.8006250000000002 0.280975341796875 0.05572509765625 -0.8015075683593804 +1.80075 0.276641845703125 0.05487060546875 -0.8015075683593804 +1.800875 0.276641845703125 0.05487060546875 -0.8015075683593804 +1.801 0.27227783203125 0.05401611328125 -0.8015075683593804 +1.801125 0.267852783203125 0.053131103515625 -0.8015075683593804 +1.80125 0.267852783203125 0.053131103515625 -0.8015075683593804 +1.801375 0.263427734375 0.05224609375 -0.8015075683593804 +1.8015 0.263427734375 0.05224609375 -0.8015075683593804 +1.801625 0.25897216796875 0.051361083984375 -0.8015075683593804 +1.80175 0.25445556640625 0.05047607421875 -0.8015075683593804 +1.80187500000000016 0.25445556640625 0.05047607421875 -0.8015075683593804 +1.802 0.249969482421875 0.049591064453125 -0.8015075683593804 +1.802125 0.249969482421875 0.049591064453125 -0.8015075683593804 +1.80225000000000016 0.24542236328125 0.048675537109375 -0.8015075683593804 +1.802375 0.2408447265625 0.047760009765625 -0.8015075683593804 +1.8025 0.2408447265625 0.047760009765625 -0.8015075683593804 +1.80262500000000016 0.236236572265625 0.046844482421875 -0.8015075683593804 +1.80275 0.236236572265625 0.046844482421875 -0.8015075683593804 +1.802875 0.231597900390625 0.045928955078125 -0.8015075683593804 +1.803 0.226959228515625 0.045013427734375 -0.8015075683593804 +1.803125 0.226959228515625 0.045013427734375 -0.8015075683593804 +1.80325 0.2222900390625 0.044097900390625 -0.8015075683593804 +1.803375 0.2222900390625 0.044097900390625 -0.8015075683593804 +1.8035 0.21759033203125 0.04315185546875 -0.8015075683593804 +1.803625 0.212860107421875 0.042205810546875 -0.8015075683593804 +1.80375 0.212860107421875 0.042205810546875 -0.8015075683593804 +1.80387500000000016 0.208099365234375 0.041290283203125 -0.8015075683593804 +1.804 0.208099365234375 0.041290283203125 -0.8015075683593804 +1.804125 0.203338623046875 0.04034423828125 -0.8015075683593804 +1.80425000000000016 0.19854736328125 0.03936767578125 -0.8015075683593804 +1.804375 0.19854736328125 0.03936767578125 -0.8015075683593804 +1.8045 0.1937255859375 0.038421630859375 -0.8015075683593804 +1.804625000000000256 0.1937255859375 0.038421630859375 -0.8015075683593804 +1.80475 0.188873291015625 0.0374755859375 -0.8015075683593804 +1.804875 0.18402099609375 0.0364990234375 -0.8015075683593804 +1.805 0.18402099609375 0.0364990234375 -0.8015075683593804 +1.805125 0.17913818359375 0.0355224609375 -0.8015075683593804 +1.80525 0.17913818359375 0.0355224609375 -0.8015075683593804 +1.805375 0.17425537109375 0.0345458984375 -0.8015075683593804 +1.8055 0.169342041015625 0.0335693359375 -0.8015075683593804 +1.805625 0.169342041015625 0.0335693359375 -0.8015075683593804 +1.80575 0.164398193359375 0.0325927734375 -0.8015075683593804 +1.80587500000000016 0.164398193359375 0.0325927734375 -0.8015075683593804 +1.806 0.159454345703125 0.0316162109375 -0.8015075683593804 +1.806125 0.15447998046875 0.0306396484375 -0.8015075683593804 +1.80625000000000016 0.15447998046875 0.0306396484375 -0.8015075683593804 +1.806375 0.14947509765625 0.029632568359375 -0.8015075683593804 +1.8065 0.14947509765625 0.029632568359375 -0.8015075683593804 +1.806625000000000256 0.14447021484375 0.028656005859375 -0.8015075683593804 +1.80675 0.13946533203125 0.02764892578125 -0.8015075683593804 +1.806875 0.13946533203125 0.02764892578125 -0.8015075683593804 +1.807 0.134429931640625 0.02667236328125 -0.8015075683593804 +1.807125 0.134429931640625 0.02667236328125 -0.8015075683593804 +1.80725 0.129364013671875 0.025665283203125 -0.8015075683593804 +1.807375 0.124298095703125 0.024658203125 -0.8015075683593804 +1.8075 0.124298095703125 0.024658203125 -0.8015075683593804 +1.807625 0.119232177734375 0.023651123046875 -0.8015075683593804 +1.80775 0.119232177734375 0.023651123046875 -0.8015075683593804 +1.80787500000000016 0.1141357421875 0.02264404296875 -0.8015075683593804 +1.808 0.109039306640625 0.0216064453125 -0.8015075683593804 +1.808125 0.109039306640625 0.0216064453125 -0.8015075683593804 +1.80825000000000016 0.103912353515625 0.020599365234375 -0.8015075683593804 +1.808375 0.103912353515625 0.020599365234375 -0.8015075683593804 +1.8085 0.098785400390625 0.01959228515625 -0.8015075683593804 +1.808625 0.093658447265625 0.0185546875 -0.8015075683593804 +1.80875 0.093658447265625 0.0185546875 -0.8015075683593804 +1.808875 0.0885009765625 0.017547607421875 -0.8015075683593804 +1.809 0.0885009765625 0.017547607421875 -0.8015075683593804 +1.809125 0.083343505859375 0.01654052734375 -0.8015075683593804 +1.80925 0.07818603515625 0.0155029296875 -0.8015075683593804 +1.809375 0.07818603515625 0.0155029296875 -0.8015075683593804 +1.8095 0.072998046875 0.01446533203125 -0.8015075683593804 +1.809625 0.072998046875 0.01446533203125 -0.8015075683593804 +1.80975 0.06781005859375 0.013458251953125 -0.8015075683593804 +1.80987500000000016 0.0626220703125 0.012420654296875 -0.8015075683593804 +1.81 0.0626220703125 0.012420654296875 -0.8015075683593804 +1.810125 0.05743408203125 0.011383056640625 -0.8015075683593804 +1.81025000000000016 0.05743408203125 0.011383056640625 -0.8015075683593804 +1.810375 0.05224609375 0.010345458984375 -0.8015075683593804 +1.8105 0.047027587890625 0.009307861328125 -0.8015075683593804 +1.810625 0.047027587890625 0.009307861328125 -0.8015075683593804 +1.81075 0.04180908203125 0.008270263671875 -0.8015075683593804 +1.810875 0.04180908203125 0.008270263671875 -0.8015075683593804 +1.811 0.036590576171875 0.007232666015625 -0.8015075683593804 +1.811125 0.0313720703125 0.0062255859375 -0.8015075683593804 +1.81125 0.0313720703125 0.0062255859375 -0.8015075683593804 +1.811375 0.026123046875 0.00518798828125 -0.8015075683593804 +1.8115 0.026123046875 0.00518798828125 -0.8015075683593804 +1.811625 0.020904541015625 0.004150390625 -0.8015075683593804 +1.81175 0.01568603515625 0.00311279296875 -0.8015075683593804 +1.81187500000000016 0.01568603515625 0.00311279296875 -0.8015075683593804 +1.812 0.01043701171875 0.0020751953125 -0.8015075683593804 +1.812125 0.01043701171875 0.0020751953125 -0.8015075683593804 +1.81225000000000016 0.005218505859375 0.00103759765625 -0.8015075683593804 +1.812375 0.0 0.0 -0.8015075683593804 +1.8125 0.0 0.0 -0.8015075683593804 +1.812625 -0.005218505859375 -0.00103759765625 -0.8015075683593804 +1.81275 -0.005218505859375 -0.00103759765625 -0.8015075683593804 +1.812875 -0.01043701171875 -0.0020751953125 -0.8015075683593804 +1.813 -0.01568603515625 -0.00311279296875 -0.8015075683593804 +1.813125 -0.01568603515625 -0.00311279296875 -0.8015075683593804 +1.81325 -0.020904541015625 -0.004150390625 -0.8015075683593804 +1.813375 -0.020904541015625 -0.004150390625 -0.8015075683593804 +1.81350000000000016 -0.026123046875 -0.00518798828125 -0.8015075683593804 +1.813625 -0.0313720703125 -0.0062255859375 -0.8015075683593804 +1.81375 -0.0313720703125 -0.0062255859375 -0.8015075683593804 +1.81387500000000016 -0.036590576171875 -0.007232666015625 -0.8015075683593804 +1.814 -0.036590576171875 -0.007232666015625 -0.8015075683593804 +1.814125 -0.04180908203125 -0.008270263671875 -0.8015075683593804 +1.81425000000000016 -0.047027587890625 -0.009307861328125 -0.8015075683593804 +1.814375 -0.047027587890625 -0.009307861328125 -0.8015075683593804 +1.8145 -0.05224609375 -0.010345458984375 -0.8015075683593804 +1.814625 -0.05224609375 -0.010345458984375 -0.8015075683593804 +1.81475 -0.05743408203125 -0.011383056640625 -0.8015075683593804 +1.814875 -0.0626220703125 -0.012420654296875 -0.8015075683593804 +1.815 -0.0626220703125 -0.012420654296875 -0.8015075683593804 +1.815125 -0.06781005859375 -0.013458251953125 -0.8015075683593804 +1.81525 -0.06781005859375 -0.013458251953125 -0.8015075683593804 +1.815375 -0.072998046875 -0.01446533203125 -0.8015075683593804 +1.81550000000000016 -0.07818603515625 -0.0155029296875 -0.8015075683593804 +1.815625 -0.07818603515625 -0.0155029296875 -0.8015075683593804 +1.81575 -0.083343505859375 -0.01654052734375 -0.8015075683593804 +1.81587500000000016 -0.083343505859375 -0.01654052734375 -0.8015075683593804 +1.816 -0.0885009765625 -0.017547607421875 -0.8015075683593804 +1.816125 -0.093658447265625 -0.0185546875 -0.8015075683593804 +1.81625000000000016 -0.093658447265625 -0.0185546875 -0.8015075683593804 +1.816375 -0.098785400390625 -0.01959228515625 -0.8015075683593804 +1.8165 -0.098785400390625 -0.01959228515625 -0.8015075683593804 +1.816625 -0.103912353515625 -0.020599365234375 -0.8015075683593804 +1.81675 -0.109039306640625 -0.0216064453125 -0.8015075683593804 +1.816875 -0.109039306640625 -0.0216064453125 -0.8015075683593804 +1.817 -0.1141357421875 -0.02264404296875 -0.8015075683593804 +1.817125 -0.1141357421875 -0.02264404296875 -0.8015075683593804 +1.81725 -0.119232177734375 -0.023651123046875 -0.8015075683593804 +1.817375 -0.124298095703125 -0.024658203125 -0.8015075683593804 +1.81750000000000016 -0.124298095703125 -0.024658203125 -0.8015075683593804 +1.817625 -0.129364013671875 -0.025665283203125 -0.8015075683593804 +1.81775 -0.129364013671875 -0.025665283203125 -0.8015075683593804 +1.81787500000000016 -0.134429931640625 -0.02667236328125 -0.8015075683593804 +1.818 -0.13946533203125 -0.02764892578125 -0.8015075683593804 +1.818125 -0.13946533203125 -0.02764892578125 -0.8015075683593804 +1.81825000000000016 -0.14447021484375 -0.028656005859375 -0.8015075683593804 +1.818375 -0.14447021484375 -0.028656005859375 -0.8015075683593804 +1.8185 -0.14947509765625 -0.029632568359375 -0.8015075683593804 +1.818625 -0.15447998046875 -0.0306396484375 -0.8015075683593804 +1.81875 -0.15447998046875 -0.0306396484375 -0.8015075683593804 +1.818875 -0.159454345703125 -0.0316162109375 -0.8015075683593804 +1.819 -0.159454345703125 -0.0316162109375 -0.8015075683593804 +1.819125 -0.164398193359375 -0.0325927734375 -0.8015075683593804 +1.81925 -0.169342041015625 -0.0335693359375 -0.8015075683593804 +1.819375 -0.169342041015625 -0.0335693359375 -0.8015075683593804 +1.81950000000000016 -0.17425537109375 -0.0345458984375 -0.8015075683593804 +1.819625 -0.17425537109375 -0.0345458984375 -0.8015075683593804 +1.81975 -0.17913818359375 -0.0355224609375 -0.8015075683593804 +1.81987500000000016 -0.18402099609375 -0.0364990234375 -0.8015075683593804 +1.82 -0.18402099609375 -0.0364990234375 -0.8015075683593804 +1.820125 -0.188873291015625 -0.0374755859375 -0.8015075683593804 +1.820250000000000256 -0.188873291015625 -0.0374755859375 -0.8015075683593804 +1.820375 -0.1937255859375 -0.038421630859375 -0.8015075683593804 +1.8205 -0.19854736328125 -0.03936767578125 -0.8015075683593804 +1.820625 -0.19854736328125 -0.03936767578125 -0.8015075683593804 +1.82075 -0.203338623046875 -0.04034423828125 -0.8015075683593804 +1.820875 -0.203338623046875 -0.04034423828125 -0.8015075683593804 +1.821 -0.208099365234375 -0.041290283203125 -0.8015075683593804 +1.821125 -0.212860107421875 -0.042205810546875 -0.8015075683593804 +1.82125 -0.212860107421875 -0.042205810546875 -0.8015075683593804 +1.821375 -0.21759033203125 -0.04315185546875 -0.8015075683593804 +1.82150000000000016 -0.21759033203125 -0.04315185546875 -0.8015075683593804 +1.821625 -0.2222900390625 -0.044097900390625 -0.8015075683593804 +1.82175 -0.226959228515625 -0.045013427734375 -0.8015075683593804 +1.82187500000000016 -0.226959228515625 -0.045013427734375 -0.8015075683593804 +1.822 -0.231597900390625 -0.045928955078125 -0.8015075683593804 +1.822125 -0.231597900390625 -0.045928955078125 -0.8015075683593804 +1.822250000000000256 -0.236236572265625 -0.046844482421875 -0.8015075683593804 +1.822375 -0.2408447265625 -0.047760009765625 -0.8015075683593804 +1.8225 -0.2408447265625 -0.047760009765625 -0.8015075683593804 +1.822625 -0.24542236328125 -0.048675537109375 -0.8015075683593804 +1.82275 -0.24542236328125 -0.048675537109375 -0.8015075683593804 +1.822875 -0.249969482421875 -0.049591064453125 -0.8015075683593804 +1.823 -0.25445556640625 -0.05047607421875 -0.8015075683593804 +1.823125 -0.25445556640625 -0.05047607421875 -0.8015075683593804 +1.82325 -0.25897216796875 -0.051361083984375 -0.8015075683593804 +1.823375 -0.25897216796875 -0.051361083984375 -0.8015075683593804 +1.82350000000000016 -0.263427734375 -0.05224609375 -0.8015075683593804 +1.823625 -0.267852783203125 -0.053131103515625 -0.8015075683593804 +1.82375 -0.267852783203125 -0.053131103515625 -0.8015075683593804 +1.82387500000000016 -0.27227783203125 -0.05401611328125 -0.8015075683593804 +1.824 -0.27227783203125 -0.0076904296875 -0.9715881347656272 +1.824125 -0.276641845703125 -0.0078125 -0.9715881347656272 +1.82425 -0.280975341796875 -0.0079345703125 -0.9715881347656272 +1.824375 -0.280975341796875 -0.0079345703125 -0.9715881347656272 +1.8245 -0.285308837890625 -0.008056640625 -0.9715881347656272 +1.824625 -0.285308837890625 -0.008056640625 -0.9715881347656272 +1.82475 -0.289581298828125 -0.0081787109375 -0.9715881347656272 +1.824875 -0.2938232421875 -0.00830078125 -0.9715881347656272 +1.825 -0.2938232421875 -0.00830078125 -0.9715881347656272 +1.825125 -0.298065185546875 -0.0084228515625 -0.9715881347656272 +1.82525 -0.298065185546875 -0.0084228515625 -0.9715881347656272 +1.825375 -0.30224609375 -0.008544921875 -0.9715881347656272 +1.82550000000000016 -0.306396484375 -0.0086669921875 -0.9715881347656272 +1.825625 -0.306396484375 -0.0086669921875 -0.9715881347656272 +1.82575 -0.310516357421875 -0.0087890625 -0.9715881347656272 +1.82587500000000016 -0.310516357421875 -0.0087890625 -0.9715881347656272 +1.826 -0.314605712890625 -0.008880615234375 -0.9715881347656272 +1.826125 -0.31866455078125 -0.009002685546875 -0.9715881347656272 +1.82625 -0.31866455078125 -0.009002685546875 -0.9715881347656272 +1.826375 -0.322662353515625 -0.009124755859375 -0.9715881347656272 +1.8265 -0.322662353515625 -0.009124755859375 -0.9715881347656272 +1.826625 -0.32666015625 -0.009246826171875 -0.9715881347656272 +1.82675 -0.330596923828125 -0.00933837890625 -0.9715881347656272 +1.826875 -0.330596923828125 -0.00933837890625 -0.9715881347656272 +1.827 -0.334503173828125 -0.00946044921875 -0.9715881347656272 +1.827125 -0.334503173828125 -0.00946044921875 -0.9715881347656272 +1.82725 -0.33837890625 -0.00958251953125 -0.9715881347656272 +1.827375 -0.34222412109375 -0.009674072265625 -0.9715881347656272 +1.82750000000000016 -0.34222412109375 -0.009674072265625 -0.9715881347656272 +1.827625 -0.34600830078125 -0.009796142578125 -0.9715881347656272 +1.82775 -0.34600830078125 -0.009796142578125 -0.9715881347656272 +1.82787500000000016 -0.349761962890625 -0.0098876953125 -0.9715881347656272 +1.828 -0.353485107421875 -0.010009765625 -0.9715881347656272 +1.828125 -0.353485107421875 -0.010009765625 -0.9715881347656272 +1.82825 -0.357177734375 -0.010101318359375 -0.9715881347656272 +1.828375 -0.357177734375 -0.010101318359375 -0.9715881347656272 +1.8285 -0.360809326171875 -0.01019287109375 -0.9715881347656272 +1.828625 -0.36444091796875 -0.01031494140625 -0.9715881347656272 +1.82875 -0.36444091796875 -0.01031494140625 -0.9715881347656272 +1.828875 -0.36798095703125 -0.010406494140625 -0.9715881347656272 +1.829 -0.36798095703125 -0.010406494140625 -0.9715881347656272 +1.82912500000000016 -0.37152099609375 -0.010498046875 -0.9715881347656272 +1.82925 -0.375 -0.0106201171875 -0.9715881347656272 +1.829375 -0.375 -0.0106201171875 -0.9715881347656272 +1.82950000000000016 -0.378448486328125 -0.010711669921875 -0.9715881347656272 +1.829625 -0.378448486328125 -0.010711669921875 -0.9715881347656272 +1.82975 -0.3818359375 -0.01080322265625 -0.9715881347656272 +1.82987500000000016 -0.38519287109375 -0.010894775390625 -0.9715881347656272 +1.83 -0.38519287109375 -0.010894775390625 -0.9715881347656272 +1.830125 -0.388519287109375 -0.010986328125 -0.9715881347656272 +1.83025 -0.388519287109375 -0.010986328125 -0.9715881347656272 +1.830375 -0.39178466796875 -0.011077880859375 -0.9715881347656272 +1.8305 -0.39501953125 -0.01116943359375 -0.9715881347656272 +1.830625 -0.39501953125 -0.01116943359375 -0.9715881347656272 +1.83075 -0.398193359375 -0.011260986328125 -0.9715881347656272 +1.830875 -0.398193359375 -0.011260986328125 -0.9715881347656272 +1.831 -0.401336669921875 -0.0113525390625 -0.9715881347656272 +1.83112500000000016 -0.404449462890625 -0.011444091796875 -0.9715881347656272 +1.83125 -0.404449462890625 -0.011444091796875 -0.9715881347656272 +1.831375 -0.407501220703125 -0.01153564453125 -0.9715881347656272 +1.83150000000000016 -0.407501220703125 -0.01153564453125 -0.9715881347656272 +1.831625 -0.4105224609375 -0.0115966796875 -0.9715881347656272 +1.83175 -0.413482666015625 -0.011688232421875 -0.9715881347656272 +1.83187500000000016 -0.413482666015625 -0.011688232421875 -0.9715881347656272 +1.832 -0.416412353515625 -0.01177978515625 -0.9715881347656272 +1.832125 -0.416412353515625 -0.01177978515625 -0.9715881347656272 +1.83225 -0.419281005859375 -0.011871337890625 -0.9715881347656272 +1.832375 -0.422119140625 -0.011932373046875 -0.9715881347656272 +1.8325 -0.422119140625 -0.011932373046875 -0.9715881347656272 +1.832625 -0.424896240234375 -0.01202392578125 -0.9715881347656272 +1.83275 -0.424896240234375 -0.01202392578125 -0.9715881347656272 +1.832875 -0.4276123046875 -0.0120849609375 -0.9715881347656272 +1.833 -0.4302978515625 -0.012176513671875 -0.9715881347656272 +1.83312500000000016 -0.4302978515625 -0.012176513671875 -0.9715881347656272 +1.83325 -0.432952880859375 -0.012237548828125 -0.9715881347656272 +1.833375 -0.432952880859375 -0.012237548828125 -0.9715881347656272 +1.83350000000000016 -0.435546875 -0.0123291015625 -0.9715881347656272 +1.833625 -0.438079833984375 -0.01239013671875 -0.9715881347656272 +1.83375 -0.438079833984375 -0.01239013671875 -0.9715881347656272 +1.83387500000000016 -0.440582275390625 -0.012451171875 -0.9715881347656272 +1.834 -0.440582275390625 -0.012451171875 -0.9715881347656272 +1.834125 -0.44305419921875 -0.012542724609375 -0.9715881347656272 +1.83425 -0.4454345703125 -0.012603759765625 -0.9715881347656272 +1.834375 -0.4454345703125 -0.012603759765625 -0.9715881347656272 +1.8345 -0.447784423828125 -0.012664794921875 -0.9715881347656272 +1.834625 -0.447784423828125 -0.012664794921875 -0.9715881347656272 +1.83475 -0.450103759765625 -0.012725830078125 -0.9715881347656272 +1.834875 -0.452362060546875 -0.012786865234375 -0.9715881347656272 +1.835 -0.452362060546875 -0.012786865234375 -0.9715881347656272 +1.83512500000000016 -0.454559326171875 -0.012847900390625 -0.9715881347656272 +1.83525 -0.454559326171875 -0.012847900390625 -0.9715881347656272 +1.835375 -0.45672607421875 -0.012908935546875 -0.9715881347656272 +1.83550000000000016 -0.458831787109375 -0.012969970703125 -0.9715881347656272 +1.835625 -0.458831787109375 -0.012969970703125 -0.9715881347656272 +1.83575 -0.46087646484375 -0.013031005859375 -0.9715881347656272 +1.835875000000000256 -0.46087646484375 -0.013031005859375 -0.9715881347656272 +1.836 -0.462890625 -0.013092041015625 -0.9715881347656272 +1.836125 -0.464813232421875 -0.013153076171875 -0.9715881347656272 +1.83625 -0.464813232421875 -0.013153076171875 -0.9715881347656272 +1.836375 -0.46673583984375 -0.013214111328125 -0.9715881347656272 +1.8365 -0.46673583984375 -0.013214111328125 -0.9715881347656272 +1.836625 -0.46856689453125 -0.01324462890625 -0.9715881347656272 +1.83675 -0.470367431640625 -0.0133056640625 -0.9715881347656272 +1.836875 -0.470367431640625 -0.0133056640625 -0.9715881347656272 +1.837 -0.472137451171875 -0.01336669921875 -0.9715881347656272 +1.83712500000000016 -0.472137451171875 -0.01336669921875 -0.9715881347656272 +1.83725 -0.47381591796875 -0.013397216796875 -0.9715881347656272 +1.837375 -0.4754638671875 -0.013458251953125 -0.9715881347656272 +1.83750000000000016 -0.4754638671875 -0.013458251953125 -0.9715881347656272 +1.837625 -0.47705078125 -0.01348876953125 -0.9715881347656272 +1.83775 -0.47705078125 -0.01348876953125 -0.9715881347656272 +1.837875000000000256 -0.478607177734375 -0.0135498046875 -0.9715881347656272 +1.838 -0.480072021484375 -0.013580322265625 -0.9715881347656272 +1.838125 -0.480072021484375 -0.013580322265625 -0.9715881347656272 +1.83825 -0.48150634765625 -0.01361083984375 -0.9715881347656272 +1.838375 -0.48150634765625 -0.01361083984375 -0.9715881347656272 +1.8385 -0.48291015625 -0.013671875 -0.9715881347656272 +1.838625 -0.484222412109375 -0.013702392578125 -0.9715881347656272 +1.83875 -0.484222412109375 -0.013702392578125 -0.9715881347656272 +1.838875 -0.485504150390625 -0.01373291015625 -0.9715881347656272 +1.839 -0.485504150390625 -0.01373291015625 -0.9715881347656272 +1.83912500000000016 -0.486724853515625 -0.013763427734375 -0.9715881347656272 +1.83925 -0.487884521484375 -0.0137939453125 -0.9715881347656272 +1.839375 -0.487884521484375 -0.0137939453125 -0.9715881347656272 +1.83950000000000016 -0.489013671875 -0.013824462890625 -0.9715881347656272 +1.839625 -0.489013671875 -0.013824462890625 -0.9715881347656272 +1.83975 -0.490081787109375 -0.01385498046875 -0.9715881347656272 +1.839875000000000256 -0.4910888671875 -0.013885498046875 -0.9715881347656272 +1.84 -0.4910888671875 -0.013885498046875 -0.9715881347656272 +1.840125 -0.492034912109375 -0.013916015625 -0.9715881347656272 +1.84025 -0.492034912109375 -0.013916015625 -0.9715881347656272 +1.840375 -0.492950439453125 -0.013946533203125 -0.9715881347656272 +1.8405 -0.4937744140625 -0.01397705078125 -0.9715881347656272 +1.840625 -0.4937744140625 -0.01397705078125 -0.9715881347656272 +1.84075 -0.49456787109375 -0.014007568359375 -0.9715881347656272 +1.840875 -0.49456787109375 -0.014007568359375 -0.9715881347656272 +1.841 -0.49530029296875 -0.014007568359375 -0.9715881347656272 +1.84112500000000016 -0.496002197265625 -0.0140380859375 -0.9715881347656272 +1.84125 -0.496002197265625 -0.0140380859375 -0.9715881347656272 +1.841375 -0.496612548828125 -0.0140380859375 -0.9715881347656272 +1.84150000000000016 -0.496612548828125 -0.0140380859375 -0.9715881347656272 +1.841625 -0.4971923828125 -0.014068603515625 -0.9715881347656272 +1.84175 -0.497711181640625 -0.014068603515625 -0.9715881347656272 +1.841875 -0.497711181640625 -0.014068603515625 -0.9715881347656272 +1.842 -0.498199462890625 -0.01409912109375 -0.9715881347656272 +1.842125 -0.498199462890625 -0.01409912109375 -0.9715881347656272 +1.84225 -0.49859619140625 -0.01409912109375 -0.9715881347656272 +1.842375 -0.49896240234375 -0.014129638671875 -0.9715881347656272 +1.8425 -0.49896240234375 -0.014129638671875 -0.9715881347656272 +1.842625 -0.499267578125 -0.014129638671875 -0.9715881347656272 +1.84275 -0.499267578125 -0.014129638671875 -0.9715881347656272 +1.842875 -0.49951171875 -0.014129638671875 -0.9715881347656272 +1.843 -0.49969482421875 -0.014129638671875 -0.9715881347656272 +1.84312500000000016 -0.49969482421875 -0.014129638671875 -0.9715881347656272 +1.84325 -0.49981689453125 -0.014129638671875 -0.9715881347656272 +1.843375 -0.49981689453125 -0.014129638671875 -0.9715881347656272 +1.84350000000000016 -0.499908447265625 -0.014129638671875 -0.9715881347656272 +1.843625 -0.49993896484375 -0.014129638671875 -0.9715881347656272 +1.84375 -0.49993896484375 -0.014129638671875 -0.9715881347656272 +1.843875 -0.499908447265625 -0.014129638671875 -0.9715881347656272 +1.844 -0.499908447265625 -0.014129638671875 -0.9715881347656272 +1.844125 -0.49981689453125 -0.014129638671875 -0.9715881347656272 +1.84425 -0.49969482421875 -0.014129638671875 -0.9715881347656272 +1.844375 -0.49969482421875 -0.014129638671875 -0.9715881347656272 +1.8445 -0.49951171875 -0.014129638671875 -0.9715881347656272 +1.844625 -0.49951171875 -0.014129638671875 -0.9715881347656272 +1.84475000000000016 -0.499267578125 -0.014129638671875 -0.9715881347656272 +1.844875 -0.49896240234375 -0.014129638671875 -0.9715881347656272 +1.845 -0.49896240234375 -0.014129638671875 -0.9715881347656272 +1.84512500000000016 -0.49859619140625 -0.01409912109375 -0.9715881347656272 +1.84525 -0.49859619140625 -0.01409912109375 -0.9715881347656272 +1.845375 -0.498199462890625 -0.01409912109375 -0.9715881347656272 +1.84550000000000016 -0.497711181640625 -0.014068603515625 -0.9715881347656272 +1.845625 -0.497711181640625 -0.014068603515625 -0.9715881347656272 +1.84575 -0.4971923828125 -0.014068603515625 -0.9715881347656272 +1.845875 -0.4971923828125 -0.014068603515625 -0.9715881347656272 +1.846 -0.496612548828125 -0.0140380859375 -0.9715881347656272 +1.846125 -0.496002197265625 -0.0140380859375 -0.9715881347656272 +1.84625 -0.496002197265625 -0.0140380859375 -0.9715881347656272 +1.846375 -0.49530029296875 -0.014007568359375 -0.9715881347656272 +1.8465 -0.49530029296875 -0.014007568359375 -0.9715881347656272 +1.846625 -0.49456787109375 -0.014007568359375 -0.9715881347656272 +1.84675000000000016 -0.4937744140625 -0.01397705078125 -0.9715881347656272 +1.846875 -0.4937744140625 -0.01397705078125 -0.9715881347656272 +1.847 -0.492950439453125 -0.013946533203125 -0.9715881347656272 +1.84712500000000016 -0.492950439453125 -0.013946533203125 -0.9715881347656272 +1.84725 -0.492034912109375 -0.013916015625 -0.9715881347656272 +1.847375 -0.4910888671875 -0.013885498046875 -0.9715881347656272 +1.84750000000000016 -0.4910888671875 -0.013885498046875 -0.9715881347656272 +1.847625 -0.490081787109375 -0.01385498046875 -0.9715881347656272 +1.84775 -0.490081787109375 -0.01385498046875 -0.9715881347656272 +1.847875 -0.489013671875 -0.013824462890625 -0.9715881347656272 +1.848 -0.487884521484375 -0.0137939453125 -0.9715881347656272 +1.848125 -0.487884521484375 -0.0137939453125 -0.9715881347656272 +1.84825 -0.486724853515625 -0.013763427734375 -0.9715881347656272 +1.848375 -0.486724853515625 -0.013763427734375 -0.9715881347656272 +1.8485 -0.485504150390625 -0.01373291015625 -0.9715881347656272 +1.848625 -0.484222412109375 -0.013702392578125 -0.9715881347656272 +1.84875000000000016 -0.484222412109375 -0.013702392578125 -0.9715881347656272 +1.848875 -0.48291015625 -0.013671875 -0.9715881347656272 +1.849 -0.48291015625 -0.013671875 -0.9715881347656272 +1.84912500000000016 -0.48150634765625 -0.01361083984375 -0.9715881347656272 +1.84925 -0.480072021484375 -0.013580322265625 -0.9715881347656272 +1.849375 -0.480072021484375 -0.013580322265625 -0.9715881347656272 +1.84950000000000016 -0.478607177734375 -0.0135498046875 -0.9715881347656272 +1.849625 -0.478607177734375 -0.0135498046875 -0.9715881347656272 +1.84975 -0.47705078125 -0.01348876953125 -0.9715881347656272 +1.849875 -0.4754638671875 -0.013458251953125 -0.9715881347656272 +1.85 -0.4754638671875 -0.013458251953125 -0.9715881347656272 +1.850125 -0.47381591796875 -0.013397216796875 -0.9715881347656272 +1.85025 -0.47381591796875 -0.013397216796875 -0.9715881347656272 +1.850375 -0.472137451171875 -0.01336669921875 -0.9715881347656272 +1.8505 -0.470367431640625 -0.0133056640625 -0.9715881347656272 +1.850625 -0.470367431640625 -0.0133056640625 -0.9715881347656272 +1.85075000000000016 -0.46856689453125 -0.01324462890625 -0.9715881347656272 +1.850875 -0.46856689453125 -0.01324462890625 -0.9715881347656272 +1.851 -0.46673583984375 -0.013214111328125 -0.9715881347656272 +1.85112500000000016 -0.464813232421875 -0.013153076171875 -0.9715881347656272 +1.85125 -0.464813232421875 -0.013153076171875 -0.9715881347656272 +1.851375 -0.462890625 -0.013092041015625 -0.9715881347656272 +1.851500000000000256 -0.462890625 -0.013092041015625 -0.9715881347656272 +1.851625 -0.46087646484375 -0.013031005859375 -0.9715881347656272 +1.85175 -0.458831787109375 -0.012969970703125 -0.9715881347656272 +1.851875 -0.458831787109375 -0.012969970703125 -0.9715881347656272 +1.852 -0.45672607421875 -0.012908935546875 -0.9715881347656272 +1.852125 -0.45672607421875 -0.012908935546875 -0.9715881347656272 +1.85225 -0.454559326171875 -0.012847900390625 -0.9715881347656272 +1.852375 -0.452362060546875 -0.012786865234375 -0.9715881347656272 +1.8525 -0.452362060546875 -0.012786865234375 -0.9715881347656272 +1.852625 -0.450103759765625 -0.012725830078125 -0.9715881347656272 +1.85275000000000016 -0.450103759765625 -0.012725830078125 -0.9715881347656272 +1.852875 -0.447784423828125 -0.012664794921875 -0.9715881347656272 +1.853 -0.4454345703125 -0.012603759765625 -0.9715881347656272 +1.85312500000000016 -0.4454345703125 -0.012603759765625 -0.9715881347656272 +1.85325 -0.44305419921875 -0.012542724609375 -0.9715881347656272 +1.853375 -0.44305419921875 -0.012542724609375 -0.9715881347656272 +1.853500000000000256 -0.440582275390625 -0.012451171875 -0.9715881347656272 +1.853625 -0.438079833984375 -0.01239013671875 -0.9715881347656272 +1.85375 -0.438079833984375 -0.01239013671875 -0.9715881347656272 +1.853875 -0.435546875 -0.0123291015625 -0.9715881347656272 +1.854 -0.435546875 -0.0123291015625 -0.9715881347656272 +1.854125 -0.432952880859375 -0.012237548828125 -0.9715881347656272 +1.85425 -0.4302978515625 -0.012176513671875 -0.9715881347656272 +1.854375 -0.4302978515625 -0.012176513671875 -0.9715881347656272 +1.8545 -0.4276123046875 -0.0120849609375 -0.9715881347656272 +1.854625 -0.4276123046875 -0.0120849609375 -0.9715881347656272 +1.85475000000000016 -0.424896240234375 -0.01202392578125 -0.9715881347656272 +1.854875 -0.422119140625 -0.011932373046875 -0.9715881347656272 +1.855 -0.422119140625 -0.011932373046875 -0.9715881347656272 +1.85512500000000016 -0.419281005859375 -0.011871337890625 -0.9715881347656272 +1.85525 -0.419281005859375 -0.011871337890625 -0.9715881347656272 +1.855375 -0.416412353515625 -0.01177978515625 -0.9715881347656272 +1.855500000000000256 -0.413482666015625 -0.011688232421875 -0.9715881347656272 +1.855625 -0.413482666015625 -0.011688232421875 -0.9715881347656272 +1.85575 -0.4105224609375 -0.0115966796875 -0.9715881347656272 +1.855875 -0.4105224609375 -0.0115966796875 -0.9715881347656272 +1.856 -0.407501220703125 -0.005401611328125 -0.9866333007812484 +1.856125 -0.404449462890625 -0.005340576171875 -0.9866333007812484 +1.85625 -0.404449462890625 -0.005340576171875 -0.9866333007812484 +1.856375 -0.401336669921875 -0.00531005859375 -0.9866333007812484 +1.8565 -0.401336669921875 -0.00531005859375 -0.9866333007812484 +1.856625 -0.398193359375 -0.005279541015625 -0.9866333007812484 +1.85675000000000016 -0.39501953125 -0.005218505859375 -0.9866333007812484 +1.856875 -0.39501953125 -0.005218505859375 -0.9866333007812484 +1.857 -0.39178466796875 -0.00518798828125 -0.9866333007812484 +1.85712500000000016 -0.39178466796875 -0.00518798828125 -0.9866333007812484 +1.85725 -0.388519287109375 -0.005157470703125 -0.9866333007812484 +1.857375 -0.38519287109375 -0.005096435546875 -0.9866333007812484 +1.8575 -0.38519287109375 -0.005096435546875 -0.9866333007812484 +1.857625 -0.3818359375 -0.00506591796875 -0.9866333007812484 +1.85775 -0.3818359375 -0.00506591796875 -0.9866333007812484 +1.857875 -0.378448486328125 -0.0050048828125 -0.9866333007812484 +1.858 -0.375 -0.004974365234375 -0.9866333007812484 +1.858125 -0.375 -0.004974365234375 -0.9866333007812484 +1.85825 -0.37152099609375 -0.004913330078125 -0.9866333007812484 +1.858375 -0.37152099609375 -0.004913330078125 -0.9866333007812484 +1.8585 -0.36798095703125 -0.0048828125 -0.9866333007812484 +1.858625 -0.36444091796875 -0.00482177734375 -0.9866333007812484 +1.85875000000000016 -0.36444091796875 -0.00482177734375 -0.9866333007812484 +1.858875 -0.360809326171875 -0.0047607421875 -0.9866333007812484 +1.859 -0.360809326171875 -0.0047607421875 -0.9866333007812484 +1.85912500000000016 -0.357177734375 -0.004730224609375 -0.9866333007812484 +1.85925 -0.353485107421875 -0.004669189453125 -0.9866333007812484 +1.859375 -0.353485107421875 -0.004669189453125 -0.9866333007812484 +1.8595 -0.349761962890625 -0.004638671875 -0.9866333007812484 +1.859625 -0.349761962890625 -0.004638671875 -0.9866333007812484 +1.85975 -0.34600830078125 -0.00457763671875 -0.9866333007812484 +1.859875 -0.34222412109375 -0.0045166015625 -0.9866333007812484 +1.86 -0.34222412109375 -0.0045166015625 -0.9866333007812484 +1.860125 -0.33837890625 -0.004486083984375 -0.9866333007812484 +1.86025 -0.33837890625 -0.004486083984375 -0.9866333007812484 +1.86037500000000016 -0.334503173828125 -0.004425048828125 -0.9866333007812484 +1.8605 -0.330596923828125 -0.004364013671875 -0.9866333007812484 +1.860625 -0.330596923828125 -0.004364013671875 -0.9866333007812484 +1.86075000000000016 -0.32666015625 -0.00433349609375 -0.9866333007812484 +1.860875 -0.32666015625 -0.00433349609375 -0.9866333007812484 +1.861 -0.322662353515625 -0.0042724609375 -0.9866333007812484 +1.86112500000000016 -0.31866455078125 -0.00421142578125 -0.9866333007812484 +1.86125 -0.31866455078125 -0.00421142578125 -0.9866333007812484 +1.861375 -0.314605712890625 -0.004150390625 -0.9866333007812484 +1.8615 -0.314605712890625 -0.004150390625 -0.9866333007812484 +1.861625 -0.310516357421875 -0.004119873046875 -0.9866333007812484 +1.86175 -0.306396484375 -0.004058837890625 -0.9866333007812484 +1.861875 -0.306396484375 -0.004058837890625 -0.9866333007812484 +1.862 -0.30224609375 -0.003997802734375 -0.9866333007812484 +1.862125 -0.30224609375 -0.003997802734375 -0.9866333007812484 +1.86225 -0.298065185546875 -0.003936767578125 -0.9866333007812484 +1.86237500000000016 -0.2938232421875 -0.003875732421875 -0.9866333007812484 +1.8625 -0.2938232421875 -0.003875732421875 -0.9866333007812484 +1.862625 -0.289581298828125 -0.003814697265625 -0.9866333007812484 +1.86275000000000016 -0.289581298828125 -0.003814697265625 -0.9866333007812484 +1.862875 -0.285308837890625 -0.0037841796875 -0.9866333007812484 +1.863 -0.280975341796875 -0.00372314453125 -0.9866333007812484 +1.86312500000000016 -0.280975341796875 -0.00372314453125 -0.9866333007812484 +1.86325 -0.276641845703125 -0.003662109375 -0.9866333007812484 +1.863375 -0.276641845703125 -0.003662109375 -0.9866333007812484 +1.8635 -0.27227783203125 -0.00360107421875 -0.9866333007812484 +1.863625 -0.267852783203125 -0.0035400390625 -0.9866333007812484 +1.86375 -0.267852783203125 -0.0035400390625 -0.9866333007812484 +1.863875 -0.263427734375 -0.00347900390625 -0.9866333007812484 +1.864 -0.263427734375 -0.00347900390625 -0.9866333007812484 +1.864125 -0.25897216796875 -0.00341796875 -0.9866333007812484 +1.86425 -0.25445556640625 -0.00335693359375 -0.9866333007812484 +1.86437500000000016 -0.25445556640625 -0.00335693359375 -0.9866333007812484 +1.8645 -0.249969482421875 -0.0032958984375 -0.9866333007812484 +1.864625 -0.249969482421875 -0.0032958984375 -0.9866333007812484 +1.86475000000000016 -0.24542236328125 -0.00323486328125 -0.9866333007812484 +1.864875 -0.2408447265625 -0.003173828125 -0.9866333007812484 +1.865 -0.2408447265625 -0.003173828125 -0.9866333007812484 +1.86512500000000016 -0.236236572265625 -0.00311279296875 -0.9866333007812484 +1.86525 -0.236236572265625 -0.00311279296875 -0.9866333007812484 +1.865375 -0.231597900390625 -0.0030517578125 -0.9866333007812484 +1.8655 -0.226959228515625 -0.00299072265625 -0.9866333007812484 +1.865625 -0.226959228515625 -0.00299072265625 -0.9866333007812484 +1.86575 -0.2222900390625 -0.0029296875 -0.9866333007812484 +1.865875 -0.2222900390625 -0.0029296875 -0.9866333007812484 +1.866 -0.21759033203125 -0.00286865234375 -0.9866333007812484 +1.866125 -0.212860107421875 -0.0028076171875 -0.9866333007812484 +1.86625 -0.212860107421875 -0.0028076171875 -0.9866333007812484 +1.86637500000000016 -0.208099365234375 -0.00274658203125 -0.9866333007812484 +1.8665 -0.208099365234375 -0.00274658203125 -0.9866333007812484 +1.866625 -0.203338623046875 -0.002685546875 -0.9866333007812484 +1.86675000000000016 -0.19854736328125 -0.00262451171875 -0.9866333007812484 +1.866875 -0.19854736328125 -0.00262451171875 -0.9866333007812484 +1.867 -0.1937255859375 -0.0025634765625 -0.9866333007812484 +1.867125000000000256 -0.1937255859375 -0.0025634765625 -0.9866333007812484 +1.86725 -0.188873291015625 -0.00250244140625 -0.9866333007812484 +1.867375 -0.18402099609375 -0.00244140625 -0.9866333007812484 +1.8675 -0.18402099609375 -0.00244140625 -0.9866333007812484 +1.867625 -0.17913818359375 -0.002349853515625 -0.9866333007812484 +1.86775 -0.17913818359375 -0.002349853515625 -0.9866333007812484 +1.867875 -0.17425537109375 -0.002288818359375 -0.9866333007812484 +1.868 -0.169342041015625 -0.002227783203125 -0.9866333007812484 +1.868125 -0.169342041015625 -0.002227783203125 -0.9866333007812484 +1.86825 -0.164398193359375 -0.002166748046875 -0.9866333007812484 +1.86837500000000016 -0.164398193359375 -0.002166748046875 -0.9866333007812484 +1.8685 -0.159454345703125 -0.002105712890625 -0.9866333007812484 +1.868625 -0.15447998046875 -0.002044677734375 -0.9866333007812484 +1.86875000000000016 -0.15447998046875 -0.002044677734375 -0.9866333007812484 +1.868875 -0.14947509765625 -0.001983642578125 -0.9866333007812484 +1.869 -0.14947509765625 -0.001983642578125 -0.9866333007812484 +1.869125000000000256 -0.14447021484375 -0.00189208984375 -0.9866333007812484 +1.86925 -0.13946533203125 -0.0018310546875 -0.9866333007812484 +1.869375 -0.13946533203125 -0.0018310546875 -0.9866333007812484 +1.8695 -0.134429931640625 -0.00177001953125 -0.9866333007812484 +1.869625 -0.134429931640625 -0.00177001953125 -0.9866333007812484 +1.86975 -0.129364013671875 -0.001708984375 -0.9866333007812484 +1.869875 -0.124298095703125 -0.00164794921875 -0.9866333007812484 +1.87 -0.124298095703125 -0.00164794921875 -0.9866333007812484 +1.870125 -0.119232177734375 -0.001556396484375 -0.9866333007812484 +1.87025 -0.119232177734375 -0.001556396484375 -0.9866333007812484 +1.87037500000000016 -0.1141357421875 -0.001495361328125 -0.9866333007812484 +1.8705 -0.109039306640625 -0.001434326171875 -0.9866333007812484 +1.870625 -0.109039306640625 -0.001434326171875 -0.9866333007812484 +1.87075000000000016 -0.103912353515625 -0.001373291015625 -0.9866333007812484 +1.870875 -0.103912353515625 -0.001373291015625 -0.9866333007812484 +1.871 -0.098785400390625 -0.00128173828125 -0.9866333007812484 +1.871125000000000256 -0.093658447265625 -0.001220703125 -0.9866333007812484 +1.87125 -0.093658447265625 -0.001220703125 -0.9866333007812484 +1.871375 -0.0885009765625 -0.00115966796875 -0.9866333007812484 +1.8715 -0.0885009765625 -0.00115966796875 -0.9866333007812484 +1.871625 -0.083343505859375 -0.0010986328125 -0.9866333007812484 +1.87175 -0.07818603515625 -0.00103759765625 -0.9866333007812484 +1.871875 -0.07818603515625 -0.00103759765625 -0.9866333007812484 +1.872 -0.072998046875 -0.000946044921875 -0.9866333007812484 +1.872125 -0.072998046875 -0.000946044921875 -0.9866333007812484 +1.87225 -0.06781005859375 -0.000885009765625 -0.9866333007812484 +1.87237500000000016 -0.0626220703125 -0.000823974609375 -0.9866333007812484 +1.8725 -0.0626220703125 -0.000823974609375 -0.9866333007812484 +1.872625 -0.05743408203125 -0.000732421875 -0.9866333007812484 +1.87275000000000016 -0.05743408203125 -0.000732421875 -0.9866333007812484 +1.872875 -0.05224609375 -0.00067138671875 -0.9866333007812484 +1.873 -0.047027587890625 -0.0006103515625 -0.9866333007812484 +1.873125 -0.047027587890625 -0.0006103515625 -0.9866333007812484 +1.87325 -0.04180908203125 -0.00054931640625 -0.9866333007812484 +1.873375 -0.04180908203125 -0.00054931640625 -0.9866333007812484 +1.8735 -0.036590576171875 -0.000457763671875 -0.9866333007812484 +1.873625 -0.0313720703125 -0.000396728515625 -0.9866333007812484 +1.87375 -0.0313720703125 -0.000396728515625 -0.9866333007812484 +1.873875 -0.026123046875 -0.000335693359375 -0.9866333007812484 +1.874 -0.026123046875 -0.000335693359375 -0.9866333007812484 +1.874125 -0.020904541015625 -0.000274658203125 -0.9866333007812484 +1.87425 -0.01568603515625 -0.00018310546875 -0.9866333007812484 +1.87437500000000016 -0.01568603515625 -0.00018310546875 -0.9866333007812484 +1.8745 -0.01043701171875 -0.0001220703125 -0.9866333007812484 +1.874625 -0.01043701171875 -0.0001220703125 -0.9866333007812484 +1.87475000000000016 -0.005218505859375 -6.103515625e-05 -0.9866333007812484 +1.874875 0.0 0.0 -0.9866333007812484 +1.875 0.0 0.0 -0.9866333007812484 +1.875125 0.005218505859375 6.103515625e-05 -0.9866333007812484 +1.87525 0.005218505859375 6.103515625e-05 -0.9866333007812484 +1.875375 0.01043701171875 0.0001220703125 -0.9866333007812484 +1.8755 0.01568603515625 0.00018310546875 -0.9866333007812484 +1.875625 0.01568603515625 0.00018310546875 -0.9866333007812484 +1.87575 0.020904541015625 0.000274658203125 -0.9866333007812484 +1.875875 0.020904541015625 0.000274658203125 -0.9866333007812484 +1.87600000000000016 0.026123046875 0.000335693359375 -0.9866333007812484 +1.876125 0.0313720703125 0.000396728515625 -0.9866333007812484 +1.87625 0.0313720703125 0.000396728515625 -0.9866333007812484 +1.87637500000000016 0.036590576171875 0.000457763671875 -0.9866333007812484 +1.8765 0.036590576171875 0.000457763671875 -0.9866333007812484 +1.876625 0.04180908203125 0.00054931640625 -0.9866333007812484 +1.87675000000000016 0.047027587890625 0.0006103515625 -0.9866333007812484 +1.876875 0.047027587890625 0.0006103515625 -0.9866333007812484 +1.877 0.05224609375 0.00067138671875 -0.9866333007812484 +1.877125 0.05224609375 0.00067138671875 -0.9866333007812484 +1.87725 0.05743408203125 0.000732421875 -0.9866333007812484 +1.877375 0.0626220703125 0.000823974609375 -0.9866333007812484 +1.8775 0.0626220703125 0.000823974609375 -0.9866333007812484 +1.877625 0.06781005859375 0.000885009765625 -0.9866333007812484 +1.87775 0.06781005859375 0.000885009765625 -0.9866333007812484 +1.877875 0.072998046875 0.000946044921875 -0.9866333007812484 +1.87800000000000016 0.07818603515625 0.00103759765625 -0.9866333007812484 +1.878125 0.07818603515625 0.00103759765625 -0.9866333007812484 +1.87825 0.083343505859375 0.0010986328125 -0.9866333007812484 +1.87837500000000016 0.083343505859375 0.0010986328125 -0.9866333007812484 +1.8785 0.0885009765625 0.00115966796875 -0.9866333007812484 +1.878625 0.093658447265625 0.001220703125 -0.9866333007812484 +1.87875000000000016 0.093658447265625 0.001220703125 -0.9866333007812484 +1.878875 0.098785400390625 0.00128173828125 -0.9866333007812484 +1.879 0.098785400390625 0.00128173828125 -0.9866333007812484 +1.879125 0.103912353515625 0.001373291015625 -0.9866333007812484 +1.87925 0.109039306640625 0.001434326171875 -0.9866333007812484 +1.879375 0.109039306640625 0.001434326171875 -0.9866333007812484 +1.8795 0.1141357421875 0.001495361328125 -0.9866333007812484 +1.879625 0.1141357421875 0.001495361328125 -0.9866333007812484 +1.87975 0.119232177734375 0.001556396484375 -0.9866333007812484 +1.879875 0.124298095703125 0.00164794921875 -0.9866333007812484 +1.88000000000000016 0.124298095703125 0.00164794921875 -0.9866333007812484 +1.880125 0.129364013671875 0.001708984375 -0.9866333007812484 +1.88025 0.129364013671875 0.001708984375 -0.9866333007812484 +1.88037500000000016 0.134429931640625 0.00177001953125 -0.9866333007812484 +1.8805 0.13946533203125 0.0018310546875 -0.9866333007812484 +1.880625 0.13946533203125 0.0018310546875 -0.9866333007812484 +1.88075000000000016 0.14447021484375 0.00189208984375 -0.9866333007812484 +1.880875 0.14447021484375 0.00189208984375 -0.9866333007812484 +1.881 0.14947509765625 0.001983642578125 -0.9866333007812484 +1.881125 0.15447998046875 0.002044677734375 -0.9866333007812484 +1.88125 0.15447998046875 0.002044677734375 -0.9866333007812484 +1.881375 0.159454345703125 0.002105712890625 -0.9866333007812484 +1.8815 0.159454345703125 0.002105712890625 -0.9866333007812484 +1.881625 0.164398193359375 0.002166748046875 -0.9866333007812484 +1.88175 0.169342041015625 0.002227783203125 -0.9866333007812484 +1.881875 0.169342041015625 0.002227783203125 -0.9866333007812484 +1.88200000000000016 0.17425537109375 0.002288818359375 -0.9866333007812484 +1.882125 0.17425537109375 0.002288818359375 -0.9866333007812484 +1.88225 0.17913818359375 0.002349853515625 -0.9866333007812484 +1.88237500000000016 0.18402099609375 0.00244140625 -0.9866333007812484 +1.8825 0.18402099609375 0.00244140625 -0.9866333007812484 +1.882625 0.188873291015625 0.00250244140625 -0.9866333007812484 +1.882750000000000256 0.188873291015625 0.00250244140625 -0.9866333007812484 +1.882875 0.1937255859375 0.0025634765625 -0.9866333007812484 +1.883 0.19854736328125 0.00262451171875 -0.9866333007812484 +1.883125 0.19854736328125 0.00262451171875 -0.9866333007812484 +1.88325 0.203338623046875 0.002685546875 -0.9866333007812484 +1.883375 0.203338623046875 0.002685546875 -0.9866333007812484 +1.8835 0.208099365234375 0.00274658203125 -0.9866333007812484 +1.883625 0.212860107421875 0.0028076171875 -0.9866333007812484 +1.88375 0.212860107421875 0.0028076171875 -0.9866333007812484 +1.883875 0.21759033203125 0.00286865234375 -0.9866333007812484 +1.88400000000000016 0.21759033203125 0.00286865234375 -0.9866333007812484 +1.884125 0.2222900390625 0.0029296875 -0.9866333007812484 +1.88425 0.226959228515625 0.00299072265625 -0.9866333007812484 +1.88437500000000016 0.226959228515625 0.00299072265625 -0.9866333007812484 +1.8845 0.231597900390625 0.0030517578125 -0.9866333007812484 +1.884625 0.231597900390625 0.0030517578125 -0.9866333007812484 +1.884750000000000256 0.236236572265625 0.00311279296875 -0.9866333007812484 +1.884875 0.2408447265625 0.003173828125 -0.9866333007812484 +1.885 0.2408447265625 0.003173828125 -0.9866333007812484 +1.885125 0.24542236328125 0.00323486328125 -0.9866333007812484 +1.88525 0.24542236328125 0.00323486328125 -0.9866333007812484 +1.885375 0.249969482421875 0.0032958984375 -0.9866333007812484 +1.8855 0.25445556640625 0.00335693359375 -0.9866333007812484 +1.885625 0.25445556640625 0.00335693359375 -0.9866333007812484 +1.88575 0.25897216796875 0.00341796875 -0.9866333007812484 +1.885875 0.25897216796875 0.00341796875 -0.9866333007812484 +1.88600000000000016 0.263427734375 0.00347900390625 -0.9866333007812484 +1.886125 0.267852783203125 0.0035400390625 -0.9866333007812484 +1.88625 0.267852783203125 0.0035400390625 -0.9866333007812484 +1.88637500000000016 0.27227783203125 0.00360107421875 -0.9866333007812484 +1.8865 0.27227783203125 0.00360107421875 -0.9866333007812484 +1.886625 0.276641845703125 0.003662109375 -0.9866333007812484 +1.886750000000000256 0.280975341796875 0.00372314453125 -0.9866333007812484 +1.886875 0.280975341796875 0.00372314453125 -0.9866333007812484 +1.887 0.285308837890625 0.0037841796875 -0.9866333007812484 +1.887125 0.285308837890625 0.0037841796875 -0.9866333007812484 +1.88725 0.289581298828125 0.003814697265625 -0.9866333007812484 +1.887375 0.2938232421875 0.003875732421875 -0.9866333007812484 +1.8875 0.2938232421875 0.003875732421875 -0.9866333007812484 +1.887625 0.298065185546875 0.003936767578125 -0.9866333007812484 +1.88775 0.298065185546875 0.003936767578125 -0.9866333007812484 +1.887875 0.30224609375 0.003997802734375 -0.9866333007812484 +1.88800000000000016 0.306396484375 0.04766845703125 -0.8442993164062446 +1.888125 0.306396484375 0.04766845703125 -0.8442993164062446 +1.88825 0.310516357421875 0.048309326171875 -0.8442993164062446 +1.88837500000000016 0.310516357421875 0.048309326171875 -0.8442993164062446 +1.8885 0.314605712890625 0.0489501953125 -0.8442993164062446 +1.888625 0.31866455078125 0.049591064453125 -0.8442993164062446 +1.88875 0.31866455078125 0.049591064453125 -0.8442993164062446 +1.888875 0.322662353515625 0.050201416015625 -0.8442993164062446 +1.889 0.322662353515625 0.050201416015625 -0.8442993164062446 +1.889125 0.32666015625 0.050811767578125 -0.8442993164062446 +1.88925 0.330596923828125 0.051422119140625 -0.8442993164062446 +1.889375 0.330596923828125 0.051422119140625 -0.8442993164062446 +1.8895 0.334503173828125 0.052032470703125 -0.8442993164062446 +1.889625 0.334503173828125 0.052032470703125 -0.8442993164062446 +1.88975 0.33837890625 0.052642822265625 -0.8442993164062446 +1.889875 0.34222412109375 0.053253173828125 -0.8442993164062446 +1.89000000000000016 0.34222412109375 0.053253173828125 -0.8442993164062446 +1.890125 0.34600830078125 0.0538330078125 -0.8442993164062446 +1.89025 0.34600830078125 0.0538330078125 -0.8442993164062446 +1.89037500000000016 0.349761962890625 0.054412841796875 -0.8442993164062446 +1.8905 0.353485107421875 0.05499267578125 -0.8442993164062446 +1.890625 0.353485107421875 0.05499267578125 -0.8442993164062446 +1.89075 0.357177734375 0.055572509765625 -0.8442993164062446 +1.890875 0.357177734375 0.055572509765625 -0.8442993164062446 +1.891 0.360809326171875 0.05615234375 -0.8442993164062446 +1.891125 0.36444091796875 0.05670166015625 -0.8442993164062446 +1.89125 0.36444091796875 0.05670166015625 -0.8442993164062446 +1.891375 0.36798095703125 0.0572509765625 -0.8442993164062446 +1.8915 0.36798095703125 0.0572509765625 -0.8442993164062446 +1.89162500000000016 0.37152099609375 0.05780029296875 -0.8442993164062446 +1.89175 0.375 0.058349609375 -0.8442993164062446 +1.891875 0.375 0.058349609375 -0.8442993164062446 +1.89200000000000016 0.378448486328125 0.058868408203125 -0.8442993164062446 +1.892125 0.378448486328125 0.058868408203125 -0.8442993164062446 +1.89225 0.3818359375 0.059417724609375 -0.8442993164062446 +1.89237500000000016 0.38519287109375 0.0599365234375 -0.8442993164062446 +1.8925 0.38519287109375 0.0599365234375 -0.8442993164062446 +1.892625 0.388519287109375 0.060455322265625 -0.8442993164062446 +1.89275 0.388519287109375 0.060455322265625 -0.8442993164062446 +1.892875 0.39178466796875 0.060943603515625 -0.8442993164062446 +1.893 0.39501953125 0.06146240234375 -0.8442993164062446 +1.893125 0.39501953125 0.06146240234375 -0.8442993164062446 +1.89325 0.398193359375 0.06195068359375 -0.8442993164062446 +1.893375 0.398193359375 0.06195068359375 -0.8442993164062446 +1.8935 0.401336669921875 0.06243896484375 -0.8442993164062446 +1.89362500000000016 0.404449462890625 0.06292724609375 -0.8442993164062446 +1.89375 0.404449462890625 0.06292724609375 -0.8442993164062446 +1.893875 0.407501220703125 0.06341552734375 -0.8442993164062446 +1.89400000000000016 0.407501220703125 0.06341552734375 -0.8442993164062446 +1.894125 0.4105224609375 0.063873291015625 -0.8442993164062446 +1.89425 0.413482666015625 0.0643310546875 -0.8442993164062446 +1.89437500000000016 0.413482666015625 0.0643310546875 -0.8442993164062446 +1.8945 0.416412353515625 0.064788818359375 -0.8442993164062446 +1.894625 0.416412353515625 0.064788818359375 -0.8442993164062446 +1.89475 0.419281005859375 0.06524658203125 -0.8442993164062446 +1.894875 0.422119140625 0.065673828125 -0.8442993164062446 +1.895 0.422119140625 0.065673828125 -0.8442993164062446 +1.895125 0.424896240234375 0.06610107421875 -0.8442993164062446 +1.89525 0.424896240234375 0.06610107421875 -0.8442993164062446 +1.895375 0.4276123046875 0.0665283203125 -0.8442993164062446 +1.8955 0.4302978515625 0.06695556640625 -0.8442993164062446 +1.89562500000000016 0.4302978515625 0.06695556640625 -0.8442993164062446 +1.89575 0.432952880859375 0.067352294921875 -0.8442993164062446 +1.895875 0.432952880859375 0.067352294921875 -0.8442993164062446 +1.89600000000000016 0.435546875 0.067779541015625 -0.8442993164062446 +1.896125 0.438079833984375 0.06817626953125 -0.8442993164062446 +1.89625 0.438079833984375 0.06817626953125 -0.8442993164062446 +1.89637500000000016 0.440582275390625 0.06854248046875 -0.8442993164062446 +1.8965 0.440582275390625 0.06854248046875 -0.8442993164062446 +1.896625 0.44305419921875 0.068939208984375 -0.8442993164062446 +1.89675 0.4454345703125 0.069305419921875 -0.8442993164062446 +1.896875 0.4454345703125 0.069305419921875 -0.8442993164062446 +1.897 0.447784423828125 0.069671630859375 -0.8442993164062446 +1.897125 0.447784423828125 0.069671630859375 -0.8442993164062446 +1.89725 0.450103759765625 0.070037841796875 -0.8442993164062446 +1.897375 0.452362060546875 0.07037353515625 -0.8442993164062446 +1.8975 0.452362060546875 0.07037353515625 -0.8442993164062446 +1.89762500000000016 0.454559326171875 0.070709228515625 -0.8442993164062446 +1.89775 0.454559326171875 0.070709228515625 -0.8442993164062446 +1.897875 0.45672607421875 0.071075439453125 -0.8442993164062446 +1.89800000000000016 0.458831787109375 0.071380615234375 -0.8442993164062446 +1.898125 0.458831787109375 0.071380615234375 -0.8442993164062446 +1.89825 0.46087646484375 0.07171630859375 -0.8442993164062446 +1.898375000000000256 0.46087646484375 0.07171630859375 -0.8442993164062446 +1.8985 0.462890625 0.072021484375 -0.8442993164062446 +1.898625 0.464813232421875 0.07232666015625 -0.8442993164062446 +1.89875 0.464813232421875 0.07232666015625 -0.8442993164062446 +1.898875 0.46673583984375 0.0726318359375 -0.8442993164062446 +1.899 0.46673583984375 0.0726318359375 -0.8442993164062446 +1.899125 0.46856689453125 0.072906494140625 -0.8442993164062446 +1.89925 0.470367431640625 0.07318115234375 -0.8442993164062446 +1.899375 0.470367431640625 0.07318115234375 -0.8442993164062446 +1.8995 0.472137451171875 0.073455810546875 -0.8442993164062446 +1.89962500000000016 0.472137451171875 0.073455810546875 -0.8442993164062446 +1.89975 0.47381591796875 0.07373046875 -0.8442993164062446 +1.899875 0.4754638671875 0.073974609375 -0.8442993164062446 +1.90000000000000016 0.4754638671875 0.073974609375 -0.8442993164062446 +1.900125 0.47705078125 0.07421875 -0.8442993164062446 +1.90025 0.47705078125 0.07421875 -0.8442993164062446 +1.900375000000000256 0.478607177734375 0.074462890625 -0.8442993164062446 +1.9005 0.480072021484375 0.07470703125 -0.8442993164062446 +1.900625 0.480072021484375 0.07470703125 -0.8442993164062446 +1.90075 0.48150634765625 0.074920654296875 -0.8442993164062446 +1.900875 0.48150634765625 0.074920654296875 -0.8442993164062446 +1.901 0.48291015625 0.07513427734375 -0.8442993164062446 +1.901125 0.484222412109375 0.075347900390625 -0.8442993164062446 +1.90125 0.484222412109375 0.075347900390625 -0.8442993164062446 +1.901375 0.485504150390625 0.075531005859375 -0.8442993164062446 +1.9015 0.485504150390625 0.075531005859375 -0.8442993164062446 +1.90162500000000016 0.486724853515625 0.07574462890625 -0.8442993164062446 +1.90175 0.487884521484375 0.075897216796875 -0.8442993164062446 +1.901875 0.487884521484375 0.075897216796875 -0.8442993164062446 +1.90200000000000016 0.489013671875 0.076080322265625 -0.8442993164062446 +1.902125 0.489013671875 0.076080322265625 -0.8442993164062446 +1.90225 0.490081787109375 0.076263427734375 -0.8442993164062446 +1.902375000000000256 0.4910888671875 0.076416015625 -0.8442993164062446 +1.9025 0.4910888671875 0.076416015625 -0.8442993164062446 +1.902625 0.492034912109375 0.076568603515625 -0.8442993164062446 +1.90275 0.492034912109375 0.076568603515625 -0.8442993164062446 +1.902875 0.492950439453125 0.076690673828125 -0.8442993164062446 +1.903 0.4937744140625 0.076812744140625 -0.8442993164062446 +1.903125 0.4937744140625 0.076812744140625 -0.8442993164062446 +1.90325 0.49456787109375 0.07696533203125 -0.8442993164062446 +1.903375 0.49456787109375 0.07696533203125 -0.8442993164062446 +1.9035 0.49530029296875 0.077056884765625 -0.8442993164062446 +1.90362500000000016 0.496002197265625 0.077178955078125 -0.8442993164062446 +1.90375 0.496002197265625 0.077178955078125 -0.8442993164062446 +1.903875 0.496612548828125 0.0772705078125 -0.8442993164062446 +1.90400000000000016 0.496612548828125 0.0772705078125 -0.8442993164062446 +1.904125 0.4971923828125 0.077362060546875 -0.8442993164062446 +1.90425 0.497711181640625 0.07745361328125 -0.8442993164062446 +1.904375 0.497711181640625 0.07745361328125 -0.8442993164062446 +1.9045 0.498199462890625 0.0775146484375 -0.8442993164062446 +1.904625 0.498199462890625 0.0775146484375 -0.8442993164062446 +1.90475 0.49859619140625 0.07757568359375 -0.8442993164062446 +1.904875 0.49896240234375 0.07763671875 -0.8442993164062446 +1.905 0.49896240234375 0.07763671875 -0.8442993164062446 +1.905125 0.499267578125 0.077667236328125 -0.8442993164062446 +1.90525 0.499267578125 0.077667236328125 -0.8442993164062446 +1.905375 0.49951171875 0.077728271484375 -0.8442993164062446 +1.9055 0.49969482421875 0.0777587890625 -0.8442993164062446 +1.90562500000000016 0.49969482421875 0.0777587890625 -0.8442993164062446 +1.90575 0.49981689453125 0.0777587890625 -0.8442993164062446 +1.905875 0.49981689453125 0.0777587890625 -0.8442993164062446 +1.90600000000000016 0.499908447265625 0.077789306640625 -0.8442993164062446 +1.906125 0.49993896484375 0.077789306640625 -0.8442993164062446 +1.90625 0.49993896484375 0.077789306640625 -0.8442993164062446 +1.906375 0.499908447265625 0.077789306640625 -0.8442993164062446 +1.9065 0.499908447265625 0.077789306640625 -0.8442993164062446 +1.906625 0.49981689453125 0.0777587890625 -0.8442993164062446 +1.90675 0.49969482421875 0.0777587890625 -0.8442993164062446 +1.906875 0.49969482421875 0.0777587890625 -0.8442993164062446 +1.907 0.49951171875 0.077728271484375 -0.8442993164062446 +1.907125 0.49951171875 0.077728271484375 -0.8442993164062446 +1.90725000000000016 0.499267578125 0.077667236328125 -0.8442993164062446 +1.907375 0.49896240234375 0.07763671875 -0.8442993164062446 +1.9075 0.49896240234375 0.07763671875 -0.8442993164062446 +1.90762500000000016 0.49859619140625 0.07757568359375 -0.8442993164062446 +1.90775 0.49859619140625 0.07757568359375 -0.8442993164062446 +1.907875 0.498199462890625 0.0775146484375 -0.8442993164062446 +1.90800000000000016 0.497711181640625 0.07745361328125 -0.8442993164062446 +1.908125 0.497711181640625 0.07745361328125 -0.8442993164062446 +1.90825 0.4971923828125 0.077362060546875 -0.8442993164062446 +1.908375 0.4971923828125 0.077362060546875 -0.8442993164062446 +1.9085 0.496612548828125 0.0772705078125 -0.8442993164062446 +1.908625 0.496002197265625 0.077178955078125 -0.8442993164062446 +1.90875 0.496002197265625 0.077178955078125 -0.8442993164062446 +1.908875 0.49530029296875 0.077056884765625 -0.8442993164062446 +1.909 0.49530029296875 0.077056884765625 -0.8442993164062446 +1.909125 0.49456787109375 0.07696533203125 -0.8442993164062446 +1.90925000000000016 0.4937744140625 0.076812744140625 -0.8442993164062446 +1.909375 0.4937744140625 0.076812744140625 -0.8442993164062446 +1.9095 0.492950439453125 0.076690673828125 -0.8442993164062446 +1.90962500000000016 0.492950439453125 0.076690673828125 -0.8442993164062446 +1.90975 0.492034912109375 0.076568603515625 -0.8442993164062446 +1.909875 0.4910888671875 0.076416015625 -0.8442993164062446 +1.91000000000000016 0.4910888671875 0.076416015625 -0.8442993164062446 +1.910125 0.490081787109375 0.076263427734375 -0.8442993164062446 +1.91025 0.490081787109375 0.076263427734375 -0.8442993164062446 +1.910375 0.489013671875 0.076080322265625 -0.8442993164062446 +1.9105 0.487884521484375 0.075897216796875 -0.8442993164062446 +1.910625 0.487884521484375 0.075897216796875 -0.8442993164062446 +1.91075 0.486724853515625 0.07574462890625 -0.8442993164062446 +1.910875 0.486724853515625 0.07574462890625 -0.8442993164062446 +1.911 0.485504150390625 0.075531005859375 -0.8442993164062446 +1.911125 0.484222412109375 0.075347900390625 -0.8442993164062446 +1.91125000000000016 0.484222412109375 0.075347900390625 -0.8442993164062446 +1.911375 0.48291015625 0.07513427734375 -0.8442993164062446 +1.9115 0.48291015625 0.07513427734375 -0.8442993164062446 +1.91162500000000016 0.48150634765625 0.074920654296875 -0.8442993164062446 +1.91175 0.480072021484375 0.07470703125 -0.8442993164062446 +1.911875 0.480072021484375 0.07470703125 -0.8442993164062446 +1.91200000000000016 0.478607177734375 0.074462890625 -0.8442993164062446 +1.912125 0.478607177734375 0.074462890625 -0.8442993164062446 +1.91225 0.47705078125 0.07421875 -0.8442993164062446 +1.912375 0.4754638671875 0.073974609375 -0.8442993164062446 +1.9125 0.4754638671875 0.073974609375 -0.8442993164062446 +1.912625 0.47381591796875 0.07373046875 -0.8442993164062446 +1.91275 0.47381591796875 0.07373046875 -0.8442993164062446 +1.912875 0.472137451171875 0.073455810546875 -0.8442993164062446 +1.913 0.470367431640625 0.07318115234375 -0.8442993164062446 +1.913125 0.470367431640625 0.07318115234375 -0.8442993164062446 +1.91325000000000016 0.46856689453125 0.072906494140625 -0.8442993164062446 +1.913375 0.46856689453125 0.072906494140625 -0.8442993164062446 +1.9135 0.46673583984375 0.0726318359375 -0.8442993164062446 +1.91362500000000016 0.464813232421875 0.07232666015625 -0.8442993164062446 +1.91375 0.464813232421875 0.07232666015625 -0.8442993164062446 +1.913875 0.462890625 0.072021484375 -0.8442993164062446 +1.914000000000000256 0.462890625 0.072021484375 -0.8442993164062446 +1.914125 0.46087646484375 0.07171630859375 -0.8442993164062446 +1.91425 0.458831787109375 0.071380615234375 -0.8442993164062446 +1.914375 0.458831787109375 0.071380615234375 -0.8442993164062446 +1.9145 0.45672607421875 0.071075439453125 -0.8442993164062446 +1.914625 0.45672607421875 0.071075439453125 -0.8442993164062446 +1.91475 0.454559326171875 0.070709228515625 -0.8442993164062446 +1.914875 0.452362060546875 0.07037353515625 -0.8442993164062446 +1.915 0.452362060546875 0.07037353515625 -0.8442993164062446 +1.915125 0.450103759765625 0.070037841796875 -0.8442993164062446 +1.91525000000000016 0.450103759765625 0.070037841796875 -0.8442993164062446 +1.915375 0.447784423828125 0.069671630859375 -0.8442993164062446 +1.9155 0.4454345703125 0.069305419921875 -0.8442993164062446 +1.91562500000000016 0.4454345703125 0.069305419921875 -0.8442993164062446 +1.91575 0.44305419921875 0.068939208984375 -0.8442993164062446 +1.915875 0.44305419921875 0.068939208984375 -0.8442993164062446 +1.916000000000000256 0.440582275390625 0.06854248046875 -0.8442993164062446 +1.916125 0.438079833984375 0.06817626953125 -0.8442993164062446 +1.91625 0.438079833984375 0.06817626953125 -0.8442993164062446 +1.916375 0.435546875 0.067779541015625 -0.8442993164062446 +1.9165 0.435546875 0.067779541015625 -0.8442993164062446 +1.916625 0.432952880859375 0.067352294921875 -0.8442993164062446 +1.91675 0.4302978515625 0.06695556640625 -0.8442993164062446 +1.916875 0.4302978515625 0.06695556640625 -0.8442993164062446 +1.917 0.4276123046875 0.0665283203125 -0.8442993164062446 +1.917125 0.4276123046875 0.0665283203125 -0.8442993164062446 +1.91725000000000016 0.424896240234375 0.06610107421875 -0.8442993164062446 +1.917375 0.422119140625 0.065673828125 -0.8442993164062446 +1.9175 0.422119140625 0.065673828125 -0.8442993164062446 +1.91762500000000016 0.419281005859375 0.06524658203125 -0.8442993164062446 +1.91775 0.419281005859375 0.06524658203125 -0.8442993164062446 +1.917875 0.416412353515625 0.064788818359375 -0.8442993164062446 +1.918000000000000256 0.413482666015625 0.0643310546875 -0.8442993164062446 +1.918125 0.413482666015625 0.0643310546875 -0.8442993164062446 +1.91825 0.4105224609375 0.063873291015625 -0.8442993164062446 +1.918375 0.4105224609375 0.063873291015625 -0.8442993164062446 +1.9185 0.407501220703125 0.06341552734375 -0.8442993164062446 +1.918625 0.404449462890625 0.06292724609375 -0.8442993164062446 +1.91875 0.404449462890625 0.06292724609375 -0.8442993164062446 +1.918875 0.401336669921875 0.06243896484375 -0.8442993164062446 +1.919 0.401336669921875 0.06243896484375 -0.8442993164062446 +1.919125 0.398193359375 0.06195068359375 -0.8442993164062446 +1.91925000000000016 0.39501953125 0.06146240234375 -0.8442993164062446 +1.919375 0.39501953125 0.06146240234375 -0.8442993164062446 +1.9195 0.39178466796875 0.060943603515625 -0.8442993164062446 +1.91962500000000016 0.39178466796875 0.060943603515625 -0.8442993164062446 +1.91975 0.388519287109375 0.060455322265625 -0.8442993164062446 +1.919875 0.38519287109375 0.0599365234375 -0.8442993164062446 +1.92 0.38519287109375 0.166656494140625 -0.5672241210937414 +1.920125 0.3818359375 0.16522216796875 -0.5672241210937414 +1.92025 0.3818359375 0.16522216796875 -0.5672241210937414 +1.920375 0.378448486328125 0.16375732421875 -0.5672241210937414 +1.9205 0.375 0.162261962890625 -0.5672241210937414 +1.920625 0.375 0.162261962890625 -0.5672241210937414 +1.92075 0.37152099609375 0.160736083984375 -0.5672241210937414 +1.920875 0.37152099609375 0.160736083984375 -0.5672241210937414 +1.921 0.36798095703125 0.159210205078125 -0.5672241210937414 +1.921125 0.36444091796875 0.157684326171875 -0.5672241210937414 +1.92125000000000016 0.36444091796875 0.157684326171875 -0.5672241210937414 +1.921375 0.360809326171875 0.1561279296875 -0.5672241210937414 +1.9215 0.360809326171875 0.1561279296875 -0.5672241210937414 +1.92162500000000016 0.357177734375 0.154541015625 -0.5672241210937414 +1.92175 0.353485107421875 0.1529541015625 -0.5672241210937414 +1.921875 0.353485107421875 0.1529541015625 -0.5672241210937414 +1.922 0.349761962890625 0.151336669921875 -0.5672241210937414 +1.922125 0.349761962890625 0.151336669921875 -0.5672241210937414 +1.92225 0.34600830078125 0.14971923828125 -0.5672241210937414 +1.922375 0.34222412109375 0.1480712890625 -0.5672241210937414 +1.9225 0.34222412109375 0.1480712890625 -0.5672241210937414 +1.922625 0.33837890625 0.14642333984375 -0.5672241210937414 +1.92275 0.33837890625 0.14642333984375 -0.5672241210937414 +1.92287500000000016 0.334503173828125 0.144744873046875 -0.5672241210937414 +1.923 0.330596923828125 0.143035888671875 -0.5672241210937414 +1.923125 0.330596923828125 0.143035888671875 -0.5672241210937414 +1.92325000000000016 0.32666015625 0.141326904296875 -0.5672241210937414 +1.923375 0.32666015625 0.141326904296875 -0.5672241210937414 +1.9235 0.322662353515625 0.139617919921875 -0.5672241210937414 +1.92362500000000016 0.31866455078125 0.13787841796875 -0.5672241210937414 +1.92375 0.31866455078125 0.13787841796875 -0.5672241210937414 +1.923875 0.314605712890625 0.1361083984375 -0.5672241210937414 +1.924 0.314605712890625 0.1361083984375 -0.5672241210937414 +1.924125 0.310516357421875 0.134368896484375 -0.5672241210937414 +1.92425 0.306396484375 0.132568359375 -0.5672241210937414 +1.924375 0.306396484375 0.132568359375 -0.5672241210937414 +1.9245 0.30224609375 0.130767822265625 -0.5672241210937414 +1.924625 0.30224609375 0.130767822265625 -0.5672241210937414 +1.92475 0.298065185546875 0.12896728515625 -0.5672241210937414 +1.92487500000000016 0.2938232421875 0.12713623046875 -0.5672241210937414 +1.925 0.2938232421875 0.12713623046875 -0.5672241210937414 +1.925125 0.289581298828125 0.12530517578125 -0.5672241210937414 +1.92525000000000016 0.289581298828125 0.12530517578125 -0.5672241210937414 +1.925375 0.285308837890625 0.123443603515625 -0.5672241210937414 +1.9255 0.280975341796875 0.12158203125 -0.5672241210937414 +1.92562500000000016 0.280975341796875 0.12158203125 -0.5672241210937414 +1.92575 0.276641845703125 0.11968994140625 -0.5672241210937414 +1.925875 0.276641845703125 0.11968994140625 -0.5672241210937414 +1.926 0.27227783203125 0.1177978515625 -0.5672241210937414 +1.926125 0.267852783203125 0.11590576171875 -0.5672241210937414 +1.92625 0.267852783203125 0.11590576171875 -0.5672241210937414 +1.926375 0.263427734375 0.113983154296875 -0.5672241210937414 +1.9265 0.263427734375 0.113983154296875 -0.5672241210937414 +1.926625 0.25897216796875 0.112060546875 -0.5672241210937414 +1.92675 0.25445556640625 0.110107421875 -0.5672241210937414 +1.92687500000000016 0.25445556640625 0.110107421875 -0.5672241210937414 +1.927 0.249969482421875 0.108154296875 -0.5672241210937414 +1.927125 0.249969482421875 0.108154296875 -0.5672241210937414 +1.92725000000000016 0.24542236328125 0.106170654296875 -0.5672241210937414 +1.927375 0.2408447265625 0.10418701171875 -0.5672241210937414 +1.9275 0.2408447265625 0.10418701171875 -0.5672241210937414 +1.92762500000000016 0.236236572265625 0.102203369140625 -0.5672241210937414 +1.92775 0.236236572265625 0.102203369140625 -0.5672241210937414 +1.927875 0.231597900390625 0.1002197265625 -0.5672241210937414 +1.928 0.226959228515625 0.09820556640625 -0.5672241210937414 +1.928125 0.226959228515625 0.09820556640625 -0.5672241210937414 +1.92825 0.2222900390625 0.096160888671875 -0.5672241210937414 +1.928375 0.2222900390625 0.096160888671875 -0.5672241210937414 +1.9285 0.21759033203125 0.094146728515625 -0.5672241210937414 +1.928625 0.212860107421875 0.09210205078125 -0.5672241210937414 +1.92875 0.212860107421875 0.09210205078125 -0.5672241210937414 +1.92887500000000016 0.208099365234375 0.09002685546875 -0.5672241210937414 +1.929 0.208099365234375 0.09002685546875 -0.5672241210937414 +1.929125 0.203338623046875 0.087982177734375 -0.5672241210937414 +1.92925000000000016 0.19854736328125 0.085906982421875 -0.5672241210937414 +1.929375 0.19854736328125 0.085906982421875 -0.5672241210937414 +1.9295 0.1937255859375 0.08380126953125 -0.5672241210937414 +1.929625000000000256 0.1937255859375 0.08380126953125 -0.5672241210937414 +1.92975 0.188873291015625 0.08172607421875 -0.5672241210937414 +1.929875 0.18402099609375 0.079620361328125 -0.5672241210937414 +1.93 0.18402099609375 0.079620361328125 -0.5672241210937414 +1.930125 0.17913818359375 0.0775146484375 -0.5672241210937414 +1.93025 0.17913818359375 0.0775146484375 -0.5672241210937414 +1.930375 0.17425537109375 0.07537841796875 -0.5672241210937414 +1.9305 0.169342041015625 0.073272705078125 -0.5672241210937414 +1.930625 0.169342041015625 0.073272705078125 -0.5672241210937414 +1.93075 0.164398193359375 0.071136474609375 -0.5672241210937414 +1.93087500000000016 0.164398193359375 0.071136474609375 -0.5672241210937414 +1.931 0.159454345703125 0.0689697265625 -0.5672241210937414 +1.931125 0.15447998046875 0.06683349609375 -0.5672241210937414 +1.93125000000000016 0.15447998046875 0.06683349609375 -0.5672241210937414 +1.931375 0.14947509765625 0.064666748046875 -0.5672241210937414 +1.9315 0.14947509765625 0.064666748046875 -0.5672241210937414 +1.931625000000000256 0.14447021484375 0.0625 -0.5672241210937414 +1.93175 0.13946533203125 0.060333251953125 -0.5672241210937414 +1.931875 0.13946533203125 0.060333251953125 -0.5672241210937414 +1.932 0.134429931640625 0.05816650390625 -0.5672241210937414 +1.932125 0.134429931640625 0.05816650390625 -0.5672241210937414 +1.93225 0.129364013671875 0.05596923828125 -0.5672241210937414 +1.932375 0.124298095703125 0.05377197265625 -0.5672241210937414 +1.9325 0.124298095703125 0.05377197265625 -0.5672241210937414 +1.932625 0.119232177734375 0.05157470703125 -0.5672241210937414 +1.93275 0.119232177734375 0.05157470703125 -0.5672241210937414 +1.93287500000000016 0.1141357421875 0.04937744140625 -0.5672241210937414 +1.933 0.109039306640625 0.04718017578125 -0.5672241210937414 +1.933125 0.109039306640625 0.04718017578125 -0.5672241210937414 +1.93325000000000016 0.103912353515625 0.044952392578125 -0.5672241210937414 +1.933375 0.103912353515625 0.044952392578125 -0.5672241210937414 +1.9335 0.098785400390625 0.042755126953125 -0.5672241210937414 +1.933625000000000256 0.093658447265625 0.04052734375 -0.5672241210937414 +1.93375 0.093658447265625 0.04052734375 -0.5672241210937414 +1.933875 0.0885009765625 0.038299560546875 -0.5672241210937414 +1.934 0.0885009765625 0.038299560546875 -0.5672241210937414 +1.934125 0.083343505859375 0.03607177734375 -0.5672241210937414 +1.93425 0.07818603515625 0.0338134765625 -0.5672241210937414 +1.934375 0.07818603515625 0.0338134765625 -0.5672241210937414 +1.9345 0.072998046875 0.031585693359375 -0.5672241210937414 +1.934625 0.072998046875 0.031585693359375 -0.5672241210937414 +1.93475 0.06781005859375 0.029327392578125 -0.5672241210937414 +1.93487500000000016 0.0626220703125 0.027099609375 -0.5672241210937414 +1.935 0.0626220703125 0.027099609375 -0.5672241210937414 +1.935125 0.05743408203125 0.02484130859375 -0.5672241210937414 +1.93525000000000016 0.05743408203125 0.02484130859375 -0.5672241210937414 +1.935375 0.05224609375 0.0225830078125 -0.5672241210937414 +1.9355 0.047027587890625 0.02032470703125 -0.5672241210937414 +1.935625000000000256 0.047027587890625 0.02032470703125 -0.5672241210937414 +1.93575 0.04180908203125 0.01806640625 -0.5672241210937414 +1.935875 0.04180908203125 0.01806640625 -0.5672241210937414 +1.936 0.036590576171875 0.01580810546875 -0.5672241210937414 +1.936125 0.0313720703125 0.013580322265625 -0.5672241210937414 +1.93625 0.0313720703125 0.013580322265625 -0.5672241210937414 +1.936375 0.026123046875 0.01129150390625 -0.5672241210937414 +1.9365 0.026123046875 0.01129150390625 -0.5672241210937414 +1.936625 0.020904541015625 0.009033203125 -0.5672241210937414 +1.93675 0.01568603515625 0.00677490234375 -0.5672241210937414 +1.93687500000000016 0.01568603515625 0.00677490234375 -0.5672241210937414 +1.937 0.01043701171875 0.0045166015625 -0.5672241210937414 +1.937125 0.01043701171875 0.0045166015625 -0.5672241210937414 +1.93725000000000016 0.005218505859375 0.00225830078125 -0.5672241210937414 +1.937375 0.0 0.0 -0.5672241210937414 +1.9375 0.0 0.0 -0.5672241210937414 +1.937625 -0.005218505859375 -0.00225830078125 -0.5672241210937414 +1.93775 -0.005218505859375 -0.00225830078125 -0.5672241210937414 +1.937875 -0.01043701171875 -0.0045166015625 -0.5672241210937414 +1.938 -0.01568603515625 -0.00677490234375 -0.5672241210937414 +1.938125 -0.01568603515625 -0.00677490234375 -0.5672241210937414 +1.93825 -0.020904541015625 -0.009033203125 -0.5672241210937414 +1.938375 -0.020904541015625 -0.009033203125 -0.5672241210937414 +1.93850000000000016 -0.026123046875 -0.01129150390625 -0.5672241210937414 +1.938625 -0.0313720703125 -0.013580322265625 -0.5672241210937414 +1.93875 -0.0313720703125 -0.013580322265625 -0.5672241210937414 +1.93887500000000016 -0.036590576171875 -0.01580810546875 -0.5672241210937414 +1.939 -0.036590576171875 -0.01580810546875 -0.5672241210937414 +1.939125 -0.04180908203125 -0.01806640625 -0.5672241210937414 +1.93925000000000016 -0.047027587890625 -0.02032470703125 -0.5672241210937414 +1.939375 -0.047027587890625 -0.02032470703125 -0.5672241210937414 +1.9395 -0.05224609375 -0.0225830078125 -0.5672241210937414 +1.939625 -0.05224609375 -0.0225830078125 -0.5672241210937414 +1.93975 -0.05743408203125 -0.02484130859375 -0.5672241210937414 +1.939875 -0.0626220703125 -0.027099609375 -0.5672241210937414 +1.94 -0.0626220703125 -0.027099609375 -0.5672241210937414 +1.940125 -0.06781005859375 -0.029327392578125 -0.5672241210937414 +1.94025 -0.06781005859375 -0.029327392578125 -0.5672241210937414 +1.940375 -0.072998046875 -0.031585693359375 -0.5672241210937414 +1.94050000000000016 -0.07818603515625 -0.0338134765625 -0.5672241210937414 +1.940625 -0.07818603515625 -0.0338134765625 -0.5672241210937414 +1.94075 -0.083343505859375 -0.03607177734375 -0.5672241210937414 +1.94087500000000016 -0.083343505859375 -0.03607177734375 -0.5672241210937414 +1.941 -0.0885009765625 -0.038299560546875 -0.5672241210937414 +1.941125 -0.093658447265625 -0.04052734375 -0.5672241210937414 +1.94125000000000016 -0.093658447265625 -0.04052734375 -0.5672241210937414 +1.941375 -0.098785400390625 -0.042755126953125 -0.5672241210937414 +1.9415 -0.098785400390625 -0.042755126953125 -0.5672241210937414 +1.941625 -0.103912353515625 -0.044952392578125 -0.5672241210937414 +1.94175 -0.109039306640625 -0.04718017578125 -0.5672241210937414 +1.941875 -0.109039306640625 -0.04718017578125 -0.5672241210937414 +1.942 -0.1141357421875 -0.04937744140625 -0.5672241210937414 +1.942125 -0.1141357421875 -0.04937744140625 -0.5672241210937414 +1.94225 -0.119232177734375 -0.05157470703125 -0.5672241210937414 +1.942375 -0.124298095703125 -0.05377197265625 -0.5672241210937414 +1.94250000000000016 -0.124298095703125 -0.05377197265625 -0.5672241210937414 +1.942625 -0.129364013671875 -0.05596923828125 -0.5672241210937414 +1.94275 -0.129364013671875 -0.05596923828125 -0.5672241210937414 +1.94287500000000016 -0.134429931640625 -0.05816650390625 -0.5672241210937414 +1.943 -0.13946533203125 -0.060333251953125 -0.5672241210937414 +1.943125 -0.13946533203125 -0.060333251953125 -0.5672241210937414 +1.94325000000000016 -0.14447021484375 -0.0625 -0.5672241210937414 +1.943375 -0.14447021484375 -0.0625 -0.5672241210937414 +1.9435 -0.14947509765625 -0.064666748046875 -0.5672241210937414 +1.943625 -0.15447998046875 -0.06683349609375 -0.5672241210937414 +1.94375 -0.15447998046875 -0.06683349609375 -0.5672241210937414 +1.943875 -0.159454345703125 -0.0689697265625 -0.5672241210937414 +1.944 -0.159454345703125 -0.0689697265625 -0.5672241210937414 +1.944125 -0.164398193359375 -0.071136474609375 -0.5672241210937414 +1.94425 -0.169342041015625 -0.073272705078125 -0.5672241210937414 +1.944375 -0.169342041015625 -0.073272705078125 -0.5672241210937414 +1.94450000000000016 -0.17425537109375 -0.07537841796875 -0.5672241210937414 +1.944625 -0.17425537109375 -0.07537841796875 -0.5672241210937414 +1.94475 -0.17913818359375 -0.0775146484375 -0.5672241210937414 +1.94487500000000016 -0.18402099609375 -0.079620361328125 -0.5672241210937414 +1.945 -0.18402099609375 -0.079620361328125 -0.5672241210937414 +1.945125 -0.188873291015625 -0.08172607421875 -0.5672241210937414 +1.945250000000000256 -0.188873291015625 -0.08172607421875 -0.5672241210937414 +1.945375 -0.1937255859375 -0.08380126953125 -0.5672241210937414 +1.9455 -0.19854736328125 -0.085906982421875 -0.5672241210937414 +1.945625 -0.19854736328125 -0.085906982421875 -0.5672241210937414 +1.94575 -0.203338623046875 -0.087982177734375 -0.5672241210937414 +1.945875 -0.203338623046875 -0.087982177734375 -0.5672241210937414 +1.946 -0.208099365234375 -0.09002685546875 -0.5672241210937414 +1.946125 -0.212860107421875 -0.09210205078125 -0.5672241210937414 +1.94625 -0.212860107421875 -0.09210205078125 -0.5672241210937414 +1.946375 -0.21759033203125 -0.094146728515625 -0.5672241210937414 +1.94650000000000016 -0.21759033203125 -0.094146728515625 -0.5672241210937414 +1.946625 -0.2222900390625 -0.096160888671875 -0.5672241210937414 +1.94675 -0.226959228515625 -0.09820556640625 -0.5672241210937414 +1.94687500000000016 -0.226959228515625 -0.09820556640625 -0.5672241210937414 +1.947 -0.231597900390625 -0.1002197265625 -0.5672241210937414 +1.947125 -0.231597900390625 -0.1002197265625 -0.5672241210937414 +1.947250000000000256 -0.236236572265625 -0.102203369140625 -0.5672241210937414 +1.947375 -0.2408447265625 -0.10418701171875 -0.5672241210937414 +1.9475 -0.2408447265625 -0.10418701171875 -0.5672241210937414 +1.947625 -0.24542236328125 -0.106170654296875 -0.5672241210937414 +1.94775 -0.24542236328125 -0.106170654296875 -0.5672241210937414 +1.947875 -0.249969482421875 -0.108154296875 -0.5672241210937414 +1.948 -0.25445556640625 -0.110107421875 -0.5672241210937414 +1.948125 -0.25445556640625 -0.110107421875 -0.5672241210937414 +1.94825 -0.25897216796875 -0.112060546875 -0.5672241210937414 +1.948375 -0.25897216796875 -0.112060546875 -0.5672241210937414 +1.94850000000000016 -0.263427734375 -0.113983154296875 -0.5672241210937414 +1.948625 -0.267852783203125 -0.11590576171875 -0.5672241210937414 +1.94875 -0.267852783203125 -0.11590576171875 -0.5672241210937414 +1.94887500000000016 -0.27227783203125 -0.1177978515625 -0.5672241210937414 +1.949 -0.27227783203125 -0.1177978515625 -0.5672241210937414 +1.949125 -0.276641845703125 -0.11968994140625 -0.5672241210937414 +1.949250000000000256 -0.280975341796875 -0.12158203125 -0.5672241210937414 +1.949375 -0.280975341796875 -0.12158203125 -0.5672241210937414 +1.9495 -0.285308837890625 -0.123443603515625 -0.5672241210937414 +1.949625 -0.285308837890625 -0.123443603515625 -0.5672241210937414 +1.94975 -0.289581298828125 -0.12530517578125 -0.5672241210937414 +1.949875 -0.2938232421875 -0.12713623046875 -0.5672241210937414 +1.95 -0.2938232421875 -0.12713623046875 -0.5672241210937414 +1.950125 -0.298065185546875 -0.12896728515625 -0.5672241210937414 +1.95025 -0.298065185546875 -0.12896728515625 -0.5672241210937414 +1.950375 -0.30224609375 -0.130767822265625 -0.5672241210937414 +1.95050000000000016 -0.306396484375 -0.132568359375 -0.5672241210937414 +1.950625 -0.306396484375 -0.132568359375 -0.5672241210937414 +1.95075 -0.310516357421875 -0.134368896484375 -0.5672241210937414 +1.95087500000000016 -0.310516357421875 -0.134368896484375 -0.5672241210937414 +1.951 -0.314605712890625 -0.1361083984375 -0.5672241210937414 +1.951125 -0.31866455078125 -0.13787841796875 -0.5672241210937414 +1.951250000000000256 -0.31866455078125 -0.13787841796875 -0.5672241210937414 +1.951375 -0.322662353515625 -0.139617919921875 -0.5672241210937414 +1.9515 -0.322662353515625 -0.139617919921875 -0.5672241210937414 +1.951625 -0.32666015625 -0.141326904296875 -0.5672241210937414 +1.95175 -0.330596923828125 -0.143035888671875 -0.5672241210937414 +1.951875 -0.330596923828125 -0.143035888671875 -0.5672241210937414 +1.952 -0.334503173828125 -0.2677001953125 -0.1996826171874888 +1.952125 -0.334503173828125 -0.2677001953125 -0.1996826171874888 +1.95225 -0.33837890625 -0.27081298828125 -0.1996826171874888 +1.952375 -0.34222412109375 -0.27386474609375 -0.1996826171874888 +1.95250000000000016 -0.34222412109375 -0.27386474609375 -0.1996826171874888 +1.952625 -0.34600830078125 -0.27691650390625 -0.1996826171874888 +1.95275 -0.34600830078125 -0.27691650390625 -0.1996826171874888 +1.95287500000000016 -0.349761962890625 -0.2799072265625 -0.1996826171874888 +1.953 -0.353485107421875 -0.28289794921875 -0.1996826171874888 +1.953125 -0.353485107421875 -0.28289794921875 -0.1996826171874888 +1.95325 -0.357177734375 -0.285858154296875 -0.1996826171874888 +1.953375 -0.357177734375 -0.285858154296875 -0.1996826171874888 +1.9535 -0.360809326171875 -0.28875732421875 -0.1996826171874888 +1.953625 -0.36444091796875 -0.291656494140625 -0.1996826171874888 +1.95375 -0.36444091796875 -0.291656494140625 -0.1996826171874888 +1.953875 -0.36798095703125 -0.29449462890625 -0.1996826171874888 +1.954 -0.36798095703125 -0.29449462890625 -0.1996826171874888 +1.95412500000000016 -0.37152099609375 -0.29730224609375 -0.1996826171874888 +1.95425 -0.375 -0.30010986328125 -0.1996826171874888 +1.954375 -0.375 -0.30010986328125 -0.1996826171874888 +1.95450000000000016 -0.378448486328125 -0.3028564453125 -0.1996826171874888 +1.954625 -0.378448486328125 -0.3028564453125 -0.1996826171874888 +1.95475 -0.3818359375 -0.305572509765625 -0.1996826171874888 +1.95487500000000016 -0.38519287109375 -0.308258056640625 -0.1996826171874888 +1.955 -0.38519287109375 -0.308258056640625 -0.1996826171874888 +1.955125 -0.388519287109375 -0.3109130859375 -0.1996826171874888 +1.95525 -0.388519287109375 -0.3109130859375 -0.1996826171874888 +1.955375 -0.39178466796875 -0.31353759765625 -0.1996826171874888 +1.9555 -0.39501953125 -0.316131591796875 -0.1996826171874888 +1.955625 -0.39501953125 -0.316131591796875 -0.1996826171874888 +1.95575 -0.398193359375 -0.31866455078125 -0.1996826171874888 +1.955875 -0.398193359375 -0.31866455078125 -0.1996826171874888 +1.956 -0.401336669921875 -0.321197509765625 -0.1996826171874888 +1.95612500000000016 -0.404449462890625 -0.32366943359375 -0.1996826171874888 +1.95625 -0.404449462890625 -0.32366943359375 -0.1996826171874888 +1.956375 -0.407501220703125 -0.32611083984375 -0.1996826171874888 +1.95650000000000016 -0.407501220703125 -0.32611083984375 -0.1996826171874888 +1.956625 -0.4105224609375 -0.328521728515625 -0.1996826171874888 +1.95675 -0.413482666015625 -0.330902099609375 -0.1996826171874888 +1.95687500000000016 -0.413482666015625 -0.330902099609375 -0.1996826171874888 +1.957 -0.416412353515625 -0.333221435546875 -0.1996826171874888 +1.957125 -0.416412353515625 -0.333221435546875 -0.1996826171874888 +1.95725 -0.419281005859375 -0.335540771484375 -0.1996826171874888 +1.957375 -0.422119140625 -0.337799072265625 -0.1996826171874888 +1.9575 -0.422119140625 -0.337799072265625 -0.1996826171874888 +1.957625 -0.424896240234375 -0.34002685546875 -0.1996826171874888 +1.95775 -0.424896240234375 -0.34002685546875 -0.1996826171874888 +1.957875 -0.4276123046875 -0.34222412109375 -0.1996826171874888 +1.958 -0.4302978515625 -0.3443603515625 -0.1996826171874888 +1.95812500000000016 -0.4302978515625 -0.3443603515625 -0.1996826171874888 +1.95825 -0.432952880859375 -0.34649658203125 -0.1996826171874888 +1.958375 -0.432952880859375 -0.34649658203125 -0.1996826171874888 +1.95850000000000016 -0.435546875 -0.34857177734375 -0.1996826171874888 +1.958625 -0.438079833984375 -0.3505859375 -0.1996826171874888 +1.95875 -0.438079833984375 -0.3505859375 -0.1996826171874888 +1.95887500000000016 -0.440582275390625 -0.35260009765625 -0.1996826171874888 +1.959 -0.440582275390625 -0.35260009765625 -0.1996826171874888 +1.959125 -0.44305419921875 -0.35455322265625 -0.1996826171874888 +1.95925 -0.4454345703125 -0.356475830078125 -0.1996826171874888 +1.959375 -0.4454345703125 -0.356475830078125 -0.1996826171874888 +1.9595 -0.447784423828125 -0.358367919921875 -0.1996826171874888 +1.959625 -0.447784423828125 -0.358367919921875 -0.1996826171874888 +1.95975 -0.450103759765625 -0.360198974609375 -0.1996826171874888 +1.959875 -0.452362060546875 -0.36199951171875 -0.1996826171874888 +1.96 -0.452362060546875 -0.36199951171875 -0.1996826171874888 +1.96012500000000016 -0.454559326171875 -0.36376953125 -0.1996826171874888 +1.96025 -0.454559326171875 -0.36376953125 -0.1996826171874888 +1.960375 -0.45672607421875 -0.365509033203125 -0.1996826171874888 +1.96050000000000016 -0.458831787109375 -0.3671875 -0.1996826171874888 +1.960625 -0.458831787109375 -0.3671875 -0.1996826171874888 +1.96075 -0.46087646484375 -0.368804931640625 -0.1996826171874888 +1.960875000000000256 -0.46087646484375 -0.368804931640625 -0.1996826171874888 +1.961 -0.462890625 -0.37042236328125 -0.1996826171874888 +1.961125 -0.464813232421875 -0.371978759765625 -0.1996826171874888 +1.96125 -0.464813232421875 -0.371978759765625 -0.1996826171874888 +1.961375 -0.46673583984375 -0.373504638671875 -0.1996826171874888 +1.9615 -0.46673583984375 -0.373504638671875 -0.1996826171874888 +1.961625 -0.46856689453125 -0.374969482421875 -0.1996826171874888 +1.96175 -0.470367431640625 -0.376434326171875 -0.1996826171874888 +1.961875 -0.470367431640625 -0.376434326171875 -0.1996826171874888 +1.962 -0.472137451171875 -0.377838134765625 -0.1996826171874888 +1.96212500000000016 -0.472137451171875 -0.377838134765625 -0.1996826171874888 +1.96225 -0.47381591796875 -0.379180908203125 -0.1996826171874888 +1.962375 -0.4754638671875 -0.3804931640625 -0.1996826171874888 +1.96250000000000016 -0.4754638671875 -0.3804931640625 -0.1996826171874888 +1.962625 -0.47705078125 -0.38177490234375 -0.1996826171874888 +1.96275 -0.47705078125 -0.38177490234375 -0.1996826171874888 +1.962875000000000256 -0.478607177734375 -0.38299560546875 -0.1996826171874888 +1.963 -0.480072021484375 -0.384185791015625 -0.1996826171874888 +1.963125 -0.480072021484375 -0.384185791015625 -0.1996826171874888 +1.96325 -0.48150634765625 -0.385345458984375 -0.1996826171874888 +1.963375 -0.48150634765625 -0.385345458984375 -0.1996826171874888 +1.9635 -0.48291015625 -0.386444091796875 -0.1996826171874888 +1.963625 -0.484222412109375 -0.38751220703125 -0.1996826171874888 +1.96375 -0.484222412109375 -0.38751220703125 -0.1996826171874888 +1.963875 -0.485504150390625 -0.3885498046875 -0.1996826171874888 +1.964 -0.485504150390625 -0.3885498046875 -0.1996826171874888 +1.96412500000000016 -0.486724853515625 -0.3895263671875 -0.1996826171874888 +1.96425 -0.487884521484375 -0.39044189453125 -0.1996826171874888 +1.964375 -0.487884521484375 -0.39044189453125 -0.1996826171874888 +1.96450000000000016 -0.489013671875 -0.391326904296875 -0.1996826171874888 +1.964625 -0.489013671875 -0.391326904296875 -0.1996826171874888 +1.96475 -0.490081787109375 -0.392181396484375 -0.1996826171874888 +1.964875000000000256 -0.4910888671875 -0.39300537109375 -0.1996826171874888 +1.965 -0.4910888671875 -0.39300537109375 -0.1996826171874888 +1.965125 -0.492034912109375 -0.393768310546875 -0.1996826171874888 +1.96525 -0.492034912109375 -0.393768310546875 -0.1996826171874888 +1.965375 -0.492950439453125 -0.39447021484375 -0.1996826171874888 +1.9655 -0.4937744140625 -0.3951416015625 -0.1996826171874888 +1.965625 -0.4937744140625 -0.3951416015625 -0.1996826171874888 +1.96575 -0.49456787109375 -0.395782470703125 -0.1996826171874888 +1.965875 -0.49456787109375 -0.395782470703125 -0.1996826171874888 +1.966 -0.49530029296875 -0.3963623046875 -0.1996826171874888 +1.96612500000000016 -0.496002197265625 -0.39691162109375 -0.1996826171874888 +1.96625 -0.496002197265625 -0.39691162109375 -0.1996826171874888 +1.966375 -0.496612548828125 -0.397430419921875 -0.1996826171874888 +1.96650000000000016 -0.496612548828125 -0.397430419921875 -0.1996826171874888 +1.966625 -0.4971923828125 -0.39788818359375 -0.1996826171874888 +1.96675 -0.497711181640625 -0.3983154296875 -0.1996826171874888 +1.966875000000000256 -0.497711181640625 -0.3983154296875 -0.1996826171874888 +1.967 -0.498199462890625 -0.398681640625 -0.1996826171874888 +1.967125 -0.498199462890625 -0.398681640625 -0.1996826171874888 +1.96725 -0.49859619140625 -0.399017333984375 -0.1996826171874888 +1.967375 -0.49896240234375 -0.3992919921875 -0.1996826171874888 +1.9675 -0.49896240234375 -0.3992919921875 -0.1996826171874888 +1.967625 -0.499267578125 -0.3995361328125 -0.1996826171874888 +1.96775 -0.499267578125 -0.3995361328125 -0.1996826171874888 +1.967875 -0.49951171875 -0.39971923828125 -0.1996826171874888 +1.968 -0.49969482421875 -0.399871826171875 -0.1996826171874888 +1.96812500000000016 -0.49969482421875 -0.399871826171875 -0.1996826171874888 +1.96825 -0.49981689453125 -0.399993896484375 -0.1996826171874888 +1.968375 -0.49981689453125 -0.399993896484375 -0.1996826171874888 +1.96850000000000016 -0.499908447265625 -0.400054931640625 -0.1996826171874888 +1.968625 -0.49993896484375 -0.40008544921875 -0.1996826171874888 +1.96875 -0.49993896484375 -0.40008544921875 -0.1996826171874888 +1.968875 -0.499908447265625 -0.400054931640625 -0.1996826171874888 +1.969 -0.499908447265625 -0.400054931640625 -0.1996826171874888 +1.969125 -0.49981689453125 -0.399993896484375 -0.1996826171874888 +1.96925 -0.49969482421875 -0.399871826171875 -0.1996826171874888 +1.969375 -0.49969482421875 -0.399871826171875 -0.1996826171874888 +1.9695 -0.49951171875 -0.39971923828125 -0.1996826171874888 +1.969625 -0.49951171875 -0.39971923828125 -0.1996826171874888 +1.96975000000000016 -0.499267578125 -0.3995361328125 -0.1996826171874888 +1.969875 -0.49896240234375 -0.3992919921875 -0.1996826171874888 +1.97 -0.49896240234375 -0.3992919921875 -0.1996826171874888 +1.97012500000000016 -0.49859619140625 -0.399017333984375 -0.1996826171874888 +1.97025 -0.49859619140625 -0.399017333984375 -0.1996826171874888 +1.970375 -0.498199462890625 -0.398681640625 -0.1996826171874888 +1.97050000000000016 -0.497711181640625 -0.3983154296875 -0.1996826171874888 +1.970625 -0.497711181640625 -0.3983154296875 -0.1996826171874888 +1.97075 -0.4971923828125 -0.39788818359375 -0.1996826171874888 +1.970875 -0.4971923828125 -0.39788818359375 -0.1996826171874888 +1.971 -0.496612548828125 -0.397430419921875 -0.1996826171874888 +1.971125 -0.496002197265625 -0.39691162109375 -0.1996826171874888 +1.97125 -0.496002197265625 -0.39691162109375 -0.1996826171874888 +1.971375 -0.49530029296875 -0.3963623046875 -0.1996826171874888 +1.9715 -0.49530029296875 -0.3963623046875 -0.1996826171874888 +1.971625 -0.49456787109375 -0.395782470703125 -0.1996826171874888 +1.97175000000000016 -0.4937744140625 -0.3951416015625 -0.1996826171874888 +1.971875 -0.4937744140625 -0.3951416015625 -0.1996826171874888 +1.972 -0.492950439453125 -0.39447021484375 -0.1996826171874888 +1.97212500000000016 -0.492950439453125 -0.39447021484375 -0.1996826171874888 +1.97225 -0.492034912109375 -0.393768310546875 -0.1996826171874888 +1.972375 -0.4910888671875 -0.39300537109375 -0.1996826171874888 +1.97250000000000016 -0.4910888671875 -0.39300537109375 -0.1996826171874888 +1.972625 -0.490081787109375 -0.392181396484375 -0.1996826171874888 +1.97275 -0.490081787109375 -0.392181396484375 -0.1996826171874888 +1.972875 -0.489013671875 -0.391326904296875 -0.1996826171874888 +1.973 -0.487884521484375 -0.39044189453125 -0.1996826171874888 +1.973125 -0.487884521484375 -0.39044189453125 -0.1996826171874888 +1.97325 -0.486724853515625 -0.3895263671875 -0.1996826171874888 +1.973375 -0.486724853515625 -0.3895263671875 -0.1996826171874888 +1.9735 -0.485504150390625 -0.3885498046875 -0.1996826171874888 +1.973625 -0.484222412109375 -0.38751220703125 -0.1996826171874888 +1.97375000000000016 -0.484222412109375 -0.38751220703125 -0.1996826171874888 +1.973875 -0.48291015625 -0.386444091796875 -0.1996826171874888 +1.974 -0.48291015625 -0.386444091796875 -0.1996826171874888 +1.97412500000000016 -0.48150634765625 -0.385345458984375 -0.1996826171874888 +1.97425 -0.480072021484375 -0.384185791015625 -0.1996826171874888 +1.974375 -0.480072021484375 -0.384185791015625 -0.1996826171874888 +1.97450000000000016 -0.478607177734375 -0.38299560546875 -0.1996826171874888 +1.974625 -0.478607177734375 -0.38299560546875 -0.1996826171874888 +1.97475 -0.47705078125 -0.38177490234375 -0.1996826171874888 +1.974875 -0.4754638671875 -0.3804931640625 -0.1996826171874888 +1.975 -0.4754638671875 -0.3804931640625 -0.1996826171874888 +1.975125 -0.47381591796875 -0.379180908203125 -0.1996826171874888 +1.97525 -0.47381591796875 -0.379180908203125 -0.1996826171874888 +1.975375 -0.472137451171875 -0.377838134765625 -0.1996826171874888 +1.9755 -0.470367431640625 -0.376434326171875 -0.1996826171874888 +1.975625 -0.470367431640625 -0.376434326171875 -0.1996826171874888 +1.97575000000000016 -0.46856689453125 -0.374969482421875 -0.1996826171874888 +1.975875 -0.46856689453125 -0.374969482421875 -0.1996826171874888 +1.976 -0.46673583984375 -0.373504638671875 -0.1996826171874888 +1.97612500000000016 -0.464813232421875 -0.371978759765625 -0.1996826171874888 +1.97625 -0.464813232421875 -0.371978759765625 -0.1996826171874888 +1.976375 -0.462890625 -0.37042236328125 -0.1996826171874888 +1.976500000000000256 -0.462890625 -0.37042236328125 -0.1996826171874888 +1.976625 -0.46087646484375 -0.368804931640625 -0.1996826171874888 +1.97675 -0.458831787109375 -0.3671875 -0.1996826171874888 +1.976875 -0.458831787109375 -0.3671875 -0.1996826171874888 +1.977 -0.45672607421875 -0.365509033203125 -0.1996826171874888 +1.977125 -0.45672607421875 -0.365509033203125 -0.1996826171874888 +1.97725 -0.454559326171875 -0.36376953125 -0.1996826171874888 +1.977375 -0.452362060546875 -0.36199951171875 -0.1996826171874888 +1.9775 -0.452362060546875 -0.36199951171875 -0.1996826171874888 +1.977625 -0.450103759765625 -0.360198974609375 -0.1996826171874888 +1.97775000000000016 -0.450103759765625 -0.360198974609375 -0.1996826171874888 +1.977875 -0.447784423828125 -0.358367919921875 -0.1996826171874888 +1.978 -0.4454345703125 -0.356475830078125 -0.1996826171874888 +1.97812500000000016 -0.4454345703125 -0.356475830078125 -0.1996826171874888 +1.97825 -0.44305419921875 -0.35455322265625 -0.1996826171874888 +1.978375 -0.44305419921875 -0.35455322265625 -0.1996826171874888 +1.978500000000000256 -0.440582275390625 -0.35260009765625 -0.1996826171874888 +1.978625 -0.438079833984375 -0.3505859375 -0.1996826171874888 +1.97875 -0.438079833984375 -0.3505859375 -0.1996826171874888 +1.978875 -0.435546875 -0.34857177734375 -0.1996826171874888 +1.979 -0.435546875 -0.34857177734375 -0.1996826171874888 +1.979125 -0.432952880859375 -0.34649658203125 -0.1996826171874888 +1.97925 -0.4302978515625 -0.3443603515625 -0.1996826171874888 +1.979375 -0.4302978515625 -0.3443603515625 -0.1996826171874888 +1.9795 -0.4276123046875 -0.34222412109375 -0.1996826171874888 +1.979625 -0.4276123046875 -0.34222412109375 -0.1996826171874888 +1.97975000000000016 -0.424896240234375 -0.34002685546875 -0.1996826171874888 +1.979875 -0.422119140625 -0.337799072265625 -0.1996826171874888 +1.98 -0.422119140625 -0.337799072265625 -0.1996826171874888 +1.98012500000000016 -0.419281005859375 -0.335540771484375 -0.1996826171874888 +1.98025 -0.419281005859375 -0.335540771484375 -0.1996826171874888 +1.980375 -0.416412353515625 -0.333221435546875 -0.1996826171874888 +1.980500000000000256 -0.413482666015625 -0.330902099609375 -0.1996826171874888 +1.980625 -0.413482666015625 -0.330902099609375 -0.1996826171874888 +1.98075 -0.4105224609375 -0.328521728515625 -0.1996826171874888 +1.980875 -0.4105224609375 -0.328521728515625 -0.1996826171874888 +1.981 -0.407501220703125 -0.32611083984375 -0.1996826171874888 +1.981125 -0.404449462890625 -0.32366943359375 -0.1996826171874888 +1.98125 -0.404449462890625 -0.32366943359375 -0.1996826171874888 +1.981375 -0.401336669921875 -0.321197509765625 -0.1996826171874888 +1.9815 -0.401336669921875 -0.321197509765625 -0.1996826171874888 +1.981625 -0.398193359375 -0.31866455078125 -0.1996826171874888 +1.98175000000000016 -0.39501953125 -0.316131591796875 -0.1996826171874888 +1.981875 -0.39501953125 -0.316131591796875 -0.1996826171874888 +1.982 -0.39178466796875 -0.31353759765625 -0.1996826171874888 +1.98212500000000016 -0.39178466796875 -0.31353759765625 -0.1996826171874888 +1.98225 -0.388519287109375 -0.3109130859375 -0.1996826171874888 +1.982375 -0.38519287109375 -0.308258056640625 -0.1996826171874888 +1.982500000000000256 -0.38519287109375 -0.308258056640625 -0.1996826171874888 +1.982625 -0.3818359375 -0.305572509765625 -0.1996826171874888 +1.98275 -0.3818359375 -0.305572509765625 -0.1996826171874888 +1.982875 -0.378448486328125 -0.3028564453125 -0.1996826171874888 +1.983 -0.375 -0.30010986328125 -0.1996826171874888 +1.983125 -0.375 -0.30010986328125 -0.1996826171874888 +1.98325 -0.37152099609375 -0.29730224609375 -0.1996826171874888 +1.983375 -0.37152099609375 -0.29730224609375 -0.1996826171874888 +1.9835 -0.36798095703125 -0.29449462890625 -0.1996826171874888 +1.983625 -0.36444091796875 -0.291656494140625 -0.1996826171874888 +1.98375000000000016 -0.36444091796875 -0.291656494140625 -0.1996826171874888 +1.983875 -0.360809326171875 -0.28875732421875 -0.1996826171874888 +1.984 -0.28875732421875 -0.360809326171875 0.1996826171875111 +1.98412500000000016 -0.285858154296875 -0.357177734375 0.1996826171875111 +1.98425 -0.28289794921875 -0.353485107421875 0.1996826171875111 +1.984375 -0.28289794921875 -0.353485107421875 0.1996826171875111 +1.9845 -0.2799072265625 -0.349761962890625 0.1996826171875111 +1.984625 -0.2799072265625 -0.349761962890625 0.1996826171875111 +1.98475 -0.27691650390625 -0.34600830078125 0.1996826171875111 +1.984875 -0.27386474609375 -0.34222412109375 0.1996826171875111 +1.985 -0.27386474609375 -0.34222412109375 0.1996826171875111 +1.985125 -0.27081298828125 -0.33837890625 0.1996826171875111 +1.98525 -0.27081298828125 -0.33837890625 0.1996826171875111 +1.98537500000000016 -0.2677001953125 -0.334503173828125 0.1996826171875111 +1.9855 -0.26458740234375 -0.330596923828125 0.1996826171875111 +1.985625 -0.26458740234375 -0.330596923828125 0.1996826171875111 +1.98575000000000016 -0.26141357421875 -0.32666015625 0.1996826171875111 +1.985875 -0.26141357421875 -0.32666015625 0.1996826171875111 +1.986 -0.25823974609375 -0.322662353515625 0.1996826171875111 +1.98612500000000016 -0.2550048828125 -0.31866455078125 0.1996826171875111 +1.98625 -0.2550048828125 -0.31866455078125 0.1996826171875111 +1.986375 -0.25177001953125 -0.314605712890625 0.1996826171875111 +1.9865 -0.25177001953125 -0.314605712890625 0.1996826171875111 +1.986625 -0.248504638671875 -0.310516357421875 0.1996826171875111 +1.98675 -0.245208740234375 -0.306396484375 0.1996826171875111 +1.986875 -0.245208740234375 -0.306396484375 0.1996826171875111 +1.987 -0.24188232421875 -0.30224609375 0.1996826171875111 +1.987125 -0.24188232421875 -0.30224609375 0.1996826171875111 +1.98725 -0.238525390625 -0.298065185546875 0.1996826171875111 +1.98737500000000016 -0.235137939453125 -0.2938232421875 0.1996826171875111 +1.9875 -0.235137939453125 -0.2938232421875 0.1996826171875111 +1.987625 -0.23175048828125 -0.289581298828125 0.1996826171875111 +1.98775000000000016 -0.23175048828125 -0.289581298828125 0.1996826171875111 +1.987875 -0.22833251953125 -0.285308837890625 0.1996826171875111 +1.988 -0.224853515625 -0.280975341796875 0.1996826171875111 +1.98812500000000016 -0.224853515625 -0.280975341796875 0.1996826171875111 +1.98825 -0.22137451171875 -0.276641845703125 0.1996826171875111 +1.988375 -0.22137451171875 -0.276641845703125 0.1996826171875111 +1.9885 -0.2178955078125 -0.27227783203125 0.1996826171875111 +1.988625 -0.21435546875 -0.267852783203125 0.1996826171875111 +1.98875 -0.21435546875 -0.267852783203125 0.1996826171875111 +1.988875 -0.2108154296875 -0.263427734375 0.1996826171875111 +1.989 -0.2108154296875 -0.263427734375 0.1996826171875111 +1.989125 -0.207244873046875 -0.25897216796875 0.1996826171875111 +1.98925 -0.203643798828125 -0.25445556640625 0.1996826171875111 +1.98937500000000016 -0.203643798828125 -0.25445556640625 0.1996826171875111 +1.9895 -0.200042724609375 -0.249969482421875 0.1996826171875111 +1.989625 -0.200042724609375 -0.249969482421875 0.1996826171875111 +1.98975000000000016 -0.196380615234375 -0.24542236328125 0.1996826171875111 +1.989875 -0.192718505859375 -0.2408447265625 0.1996826171875111 +1.99 -0.192718505859375 -0.2408447265625 0.1996826171875111 +1.99012500000000016 -0.189056396484375 -0.236236572265625 0.1996826171875111 +1.99025 -0.189056396484375 -0.236236572265625 0.1996826171875111 +1.990375 -0.185333251953125 -0.231597900390625 0.1996826171875111 +1.9905 -0.181610107421875 -0.226959228515625 0.1996826171875111 +1.990625 -0.181610107421875 -0.226959228515625 0.1996826171875111 +1.99075 -0.177886962890625 -0.2222900390625 0.1996826171875111 +1.990875 -0.177886962890625 -0.2222900390625 0.1996826171875111 +1.991 -0.17413330078125 -0.21759033203125 0.1996826171875111 +1.991125 -0.17034912109375 -0.212860107421875 0.1996826171875111 +1.99125 -0.17034912109375 -0.212860107421875 0.1996826171875111 +1.99137500000000016 -0.166534423828125 -0.208099365234375 0.1996826171875111 +1.9915 -0.166534423828125 -0.208099365234375 0.1996826171875111 +1.991625 -0.1627197265625 -0.203338623046875 0.1996826171875111 +1.99175000000000016 -0.15887451171875 -0.19854736328125 0.1996826171875111 +1.991875 -0.15887451171875 -0.19854736328125 0.1996826171875111 +1.992 -0.155029296875 -0.1937255859375 0.1996826171875111 +1.992125000000000256 -0.155029296875 -0.1937255859375 0.1996826171875111 +1.99225 -0.151153564453125 -0.188873291015625 0.1996826171875111 +1.992375 -0.14727783203125 -0.18402099609375 0.1996826171875111 +1.9925 -0.14727783203125 -0.18402099609375 0.1996826171875111 +1.992625 -0.14337158203125 -0.17913818359375 0.1996826171875111 +1.99275 -0.14337158203125 -0.17913818359375 0.1996826171875111 +1.992875 -0.139434814453125 -0.17425537109375 0.1996826171875111 +1.993 -0.135498046875 -0.169342041015625 0.1996826171875111 +1.993125 -0.135498046875 -0.169342041015625 0.1996826171875111 +1.99325 -0.131561279296875 -0.164398193359375 0.1996826171875111 +1.99337500000000016 -0.131561279296875 -0.164398193359375 0.1996826171875111 +1.9935 -0.127593994140625 -0.159454345703125 0.1996826171875111 +1.993625 -0.123626708984375 -0.15447998046875 0.1996826171875111 +1.99375000000000016 -0.123626708984375 -0.15447998046875 0.1996826171875111 +1.993875 -0.11962890625 -0.14947509765625 0.1996826171875111 +1.994 -0.11962890625 -0.14947509765625 0.1996826171875111 +1.994125000000000256 -0.115631103515625 -0.14447021484375 0.1996826171875111 +1.99425 -0.111602783203125 -0.13946533203125 0.1996826171875111 +1.994375 -0.111602783203125 -0.13946533203125 0.1996826171875111 +1.9945 -0.107574462890625 -0.134429931640625 0.1996826171875111 +1.994625 -0.107574462890625 -0.134429931640625 0.1996826171875111 +1.99475 -0.103515625 -0.129364013671875 0.1996826171875111 +1.994875 -0.0994873046875 -0.124298095703125 0.1996826171875111 +1.995 -0.0994873046875 -0.124298095703125 0.1996826171875111 +1.995125 -0.095428466796875 -0.119232177734375 0.1996826171875111 +1.99525 -0.095428466796875 -0.119232177734375 0.1996826171875111 +1.99537500000000016 -0.091339111328125 -0.1141357421875 0.1996826171875111 +1.9955 -0.087249755859375 -0.109039306640625 0.1996826171875111 +1.995625 -0.087249755859375 -0.109039306640625 0.1996826171875111 +1.99575000000000016 -0.083160400390625 -0.103912353515625 0.1996826171875111 +1.995875 -0.083160400390625 -0.103912353515625 0.1996826171875111 +1.996 -0.079071044921875 -0.098785400390625 0.1996826171875111 +1.996125000000000256 -0.074951171875 -0.093658447265625 0.1996826171875111 +1.99625 -0.074951171875 -0.093658447265625 0.1996826171875111 +1.996375 -0.070831298828125 -0.0885009765625 0.1996826171875111 +1.9965 -0.070831298828125 -0.0885009765625 0.1996826171875111 +1.996625 -0.06671142578125 -0.083343505859375 0.1996826171875111 +1.99675 -0.06256103515625 -0.07818603515625 0.1996826171875111 +1.996875 -0.06256103515625 -0.07818603515625 0.1996826171875111 +1.997 -0.05841064453125 -0.072998046875 0.1996826171875111 +1.997125 -0.05841064453125 -0.072998046875 0.1996826171875111 +1.99725 -0.05426025390625 -0.06781005859375 0.1996826171875111 +1.99737500000000016 -0.05010986328125 -0.0626220703125 0.1996826171875111 +1.9975 -0.05010986328125 -0.0626220703125 0.1996826171875111 +1.997625 -0.04595947265625 -0.05743408203125 0.1996826171875111 +1.99775000000000016 -0.04595947265625 -0.05743408203125 0.1996826171875111 +1.997875 -0.04180908203125 -0.05224609375 0.1996826171875111 +1.998 -0.037628173828125 -0.047027587890625 0.1996826171875111 +1.998125000000000256 -0.037628173828125 -0.047027587890625 0.1996826171875111 +1.99825 -0.033447265625 -0.04180908203125 0.1996826171875111 +1.998375 -0.033447265625 -0.04180908203125 0.1996826171875111 +1.9985 -0.029266357421875 -0.036590576171875 0.1996826171875111 +1.998625 -0.025115966796875 -0.0313720703125 0.1996826171875111 +1.99875 -0.025115966796875 -0.0313720703125 0.1996826171875111 +1.998875 -0.020904541015625 -0.026123046875 0.1996826171875111 +1.999 -0.020904541015625 -0.026123046875 0.1996826171875111 +1.999125 -0.0167236328125 -0.020904541015625 0.1996826171875111 +1.99925 -0.012542724609375 -0.01568603515625 0.1996826171875111 +1.99937500000000016 -0.012542724609375 -0.01568603515625 0.1996826171875111 +1.9995 -0.00836181640625 -0.01043701171875 0.1996826171875111 +1.999625 -0.00836181640625 -0.01043701171875 0.1996826171875111 +1.99975000000000016 -0.004180908203125 -0.005218505859375 0.1996826171875111 +1.999875 0.0 0.0 0.1996826171875111 +2.0 0.0 0.0 0.1996826171875111 +2.000125 0.004180908203125 0.005218505859375 0.1996826171875111 +2.00025 0.004180908203125 0.005218505859375 0.1996826171875111 +2.000375 0.00836181640625 0.01043701171875 0.1996826171875111 +2.0005 0.012542724609375 0.01568603515625 0.1996826171875111 +2.000625 0.012542724609375 0.01568603515625 0.1996826171875111 +2.00075 0.0167236328125 0.020904541015625 0.1996826171875111 +2.000875 0.0167236328125 0.020904541015625 0.1996826171875111 +2.001 0.020904541015625 0.026123046875 0.1996826171875111 +2.001125 0.025115966796875 0.0313720703125 0.1996826171875111 +2.00125 0.025115966796875 0.0313720703125 0.1996826171875111 +2.001375 0.029266357421875 0.036590576171875 0.1996826171875111 +2.0015 0.029266357421875 0.036590576171875 0.1996826171875111 +2.001625 0.033447265625 0.04180908203125 0.1996826171875111 +2.00175 0.037628173828125 0.047027587890625 0.1996826171875111 +2.001875 0.037628173828125 0.047027587890625 0.1996826171875111 +2.0020000000000004 0.04180908203125 0.05224609375 0.1996826171875111 +2.002125 0.04180908203125 0.05224609375 0.1996826171875111 +2.00225 0.04595947265625 0.05743408203125 0.1996826171875111 +2.0023750000000004 0.05010986328125 0.0626220703125 0.1996826171875111 +2.0025 0.05010986328125 0.0626220703125 0.1996826171875111 +2.002625 0.05426025390625 0.06781005859375 0.1996826171875111 +2.0027500000000004 0.05426025390625 0.06781005859375 0.1996826171875111 +2.002875 0.05841064453125 0.072998046875 0.1996826171875111 +2.003 0.06256103515625 0.07818603515625 0.1996826171875111 +2.003125 0.06256103515625 0.07818603515625 0.1996826171875111 +2.00325 0.06671142578125 0.083343505859375 0.1996826171875111 +2.003375 0.06671142578125 0.083343505859375 0.1996826171875111 +2.0035 0.070831298828125 0.0885009765625 0.1996826171875111 +2.003625 0.074951171875 0.093658447265625 0.1996826171875111 +2.00375 0.074951171875 0.093658447265625 0.1996826171875111 +2.003875 0.079071044921875 0.098785400390625 0.1996826171875111 +2.004 0.079071044921875 0.098785400390625 0.1996826171875111 +2.004125 0.083160400390625 0.103912353515625 0.1996826171875111 +2.00425 0.087249755859375 0.109039306640625 0.1996826171875111 +2.004375 0.087249755859375 0.109039306640625 0.1996826171875111 +2.0045 0.091339111328125 0.1141357421875 0.1996826171875111 +2.004625 0.091339111328125 0.1141357421875 0.1996826171875111 +2.00475 0.095428466796875 0.119232177734375 0.1996826171875111 +2.004875 0.0994873046875 0.124298095703125 0.1996826171875111 +2.005 0.0994873046875 0.124298095703125 0.1996826171875111 +2.005125 0.103515625 0.129364013671875 0.1996826171875111 +2.00525 0.103515625 0.129364013671875 0.1996826171875111 +2.005375 0.107574462890625 0.134429931640625 0.1996826171875111 +2.0055 0.111602783203125 0.13946533203125 0.1996826171875111 +2.005625 0.111602783203125 0.13946533203125 0.1996826171875111 +2.00575 0.115631103515625 0.14447021484375 0.1996826171875111 +2.005875 0.115631103515625 0.14447021484375 0.1996826171875111 +2.0060000000000004 0.11962890625 0.14947509765625 0.1996826171875111 +2.006125 0.123626708984375 0.15447998046875 0.1996826171875111 +2.00625 0.123626708984375 0.15447998046875 0.1996826171875111 +2.0063750000000004 0.127593994140625 0.159454345703125 0.1996826171875111 +2.0065 0.127593994140625 0.159454345703125 0.1996826171875111 +2.006625 0.131561279296875 0.164398193359375 0.1996826171875111 +2.0067500000000004 0.135498046875 0.169342041015625 0.1996826171875111 +2.006875 0.135498046875 0.169342041015625 0.1996826171875111 +2.007 0.139434814453125 0.17425537109375 0.1996826171875111 +2.007125 0.139434814453125 0.17425537109375 0.1996826171875111 +2.00725 0.14337158203125 0.17913818359375 0.1996826171875111 +2.007375 0.14727783203125 0.18402099609375 0.1996826171875111 +2.0075 0.14727783203125 0.18402099609375 0.1996826171875111 +2.007625 0.151153564453125 0.188873291015625 0.1996826171875111 +2.00775 0.151153564453125 0.188873291015625 0.1996826171875111 +2.007875 0.155029296875 0.1937255859375 0.1996826171875111 +2.008 0.15887451171875 0.19854736328125 0.1996826171875111 +2.008125 0.15887451171875 0.19854736328125 0.1996826171875111 +2.00825 0.1627197265625 0.203338623046875 0.1996826171875111 +2.008375 0.1627197265625 0.203338623046875 0.1996826171875111 +2.0085 0.166534423828125 0.208099365234375 0.1996826171875111 +2.008625 0.17034912109375 0.212860107421875 0.1996826171875111 +2.00875 0.17034912109375 0.212860107421875 0.1996826171875111 +2.008875 0.17413330078125 0.21759033203125 0.1996826171875111 +2.009 0.17413330078125 0.21759033203125 0.1996826171875111 +2.009125 0.177886962890625 0.2222900390625 0.1996826171875111 +2.00925 0.181610107421875 0.226959228515625 0.1996826171875111 +2.009375 0.181610107421875 0.226959228515625 0.1996826171875111 +2.0095 0.185333251953125 0.231597900390625 0.1996826171875111 +2.009625 0.185333251953125 0.231597900390625 0.1996826171875111 +2.00975 0.189056396484375 0.236236572265625 0.1996826171875111 +2.009875 0.192718505859375 0.2408447265625 0.1996826171875111 +2.0100000000000004 0.192718505859375 0.2408447265625 0.1996826171875111 +2.010125 0.196380615234375 0.24542236328125 0.1996826171875111 +2.01025 0.196380615234375 0.24542236328125 0.1996826171875111 +2.0103750000000004 0.200042724609375 0.249969482421875 0.1996826171875111 +2.0105 0.203643798828125 0.25445556640625 0.1996826171875111 +2.010625 0.203643798828125 0.25445556640625 0.1996826171875111 +2.0107500000000004 0.207244873046875 0.25897216796875 0.1996826171875111 +2.010875 0.207244873046875 0.25897216796875 0.1996826171875111 +2.011 0.2108154296875 0.263427734375 0.1996826171875111 +2.011125 0.21435546875 0.267852783203125 0.1996826171875111 +2.01125 0.21435546875 0.267852783203125 0.1996826171875111 +2.011375 0.2178955078125 0.27227783203125 0.1996826171875111 +2.0115 0.2178955078125 0.27227783203125 0.1996826171875111 +2.011625 0.22137451171875 0.276641845703125 0.1996826171875111 +2.01175 0.224853515625 0.280975341796875 0.1996826171875111 +2.011875 0.224853515625 0.280975341796875 0.1996826171875111 +2.012 0.22833251953125 0.285308837890625 0.1996826171875111 +2.012125 0.22833251953125 0.285308837890625 0.1996826171875111 +2.01225 0.23175048828125 0.289581298828125 0.1996826171875111 +2.012375 0.235137939453125 0.2938232421875 0.1996826171875111 +2.0125 0.235137939453125 0.2938232421875 0.1996826171875111 +2.012625 0.238525390625 0.298065185546875 0.1996826171875111 +2.01275 0.238525390625 0.298065185546875 0.1996826171875111 +2.012875 0.24188232421875 0.30224609375 0.1996826171875111 +2.013 0.245208740234375 0.306396484375 0.1996826171875111 +2.013125 0.245208740234375 0.306396484375 0.1996826171875111 +2.01325 0.248504638671875 0.310516357421875 0.1996826171875111 +2.013375 0.248504638671875 0.310516357421875 0.1996826171875111 +2.0135 0.25177001953125 0.314605712890625 0.1996826171875111 +2.013625 0.2550048828125 0.31866455078125 0.1996826171875111 +2.01375 0.2550048828125 0.31866455078125 0.1996826171875111 +2.013875 0.25823974609375 0.322662353515625 0.1996826171875111 +2.0140000000000004 0.25823974609375 0.322662353515625 0.1996826171875111 +2.014125 0.26141357421875 0.32666015625 0.1996826171875111 +2.01425 0.26458740234375 0.330596923828125 0.1996826171875111 +2.0143750000000004 0.26458740234375 0.330596923828125 0.1996826171875111 +2.0145 0.2677001953125 0.334503173828125 0.1996826171875111 +2.014625 0.2677001953125 0.334503173828125 0.1996826171875111 +2.0147500000000004 0.27081298828125 0.33837890625 0.1996826171875111 +2.014875 0.27386474609375 0.34222412109375 0.1996826171875111 +2.015 0.27386474609375 0.34222412109375 0.1996826171875111 +2.015125 0.27691650390625 0.34600830078125 0.1996826171875111 +2.01525 0.27691650390625 0.34600830078125 0.1996826171875111 +2.015375 0.2799072265625 0.349761962890625 0.1996826171875111 +2.0155 0.28289794921875 0.353485107421875 0.1996826171875111 +2.015625 0.28289794921875 0.353485107421875 0.1996826171875111 +2.01575 0.285858154296875 0.357177734375 0.1996826171875111 +2.015875 0.285858154296875 0.357177734375 0.1996826171875111 diff --git a/tests/circuitpython/synth_note_ring.py.exp b/tests/circuitpython/synth_note_ring.py.exp index b45858d5aad..4335f62a65c 100644 --- a/tests/circuitpython/synth_note_ring.py.exp +++ b/tests/circuitpython/synth_note_ring.py.exp @@ -29,37 +29,37 @@ 0.0035 0.008331298828125 -0.743977294921875 0.003625 0.005218505859375 -0.743977294921875 0.00375 0.00128173828125 -0.743977294921875 -0.003875 -0.0030517578125 -0.743977294921875 -0.004 -0.006988525390625 -0.743977294921875 -0.004125 -0.01263427734375 -0.743977294921875 -0.00425 -0.017303466796875 -0.743977294921875 -0.004375000000000001 -0.0213623046875 -0.743977294921875 -0.004500000000000001 -0.025634765625 -0.743977294921875 -0.004625 -0.032470703125 -0.743977294921875 -0.00475 -0.03656005859375 -0.743977294921875 -0.004875 -0.040252685546875 -0.743977294921875 -0.005 -0.047515869140625 -0.743977294921875 -0.005125000000000001 -0.050628662109375 -0.743977294921875 -0.00525 -0.052978515625 -0.743977294921875 -0.005375000000000001 -0.055023193359375 -0.743977294921875 -0.005499999999999999 -0.061553955078125 -0.743977294921875 -0.005625 -0.0623779296875 -0.743977294921875 -0.00575 -0.062652587890625 -0.743977294921875 -0.005874999999999999 -0.06231689453125 -0.743977294921875 -0.006 -0.06634521484375 -0.743977294921875 -0.006125 -0.06451416015625 -0.743977294921875 -0.00625 -0.062255859375 -0.743977294921875 -0.006375 -0.059112548828125 -0.743977294921875 -0.0065 -0.059967041015625 -0.743977294921875 -0.006625000000000001 -0.055267333984375 -0.743977294921875 -0.00675 -0.04998779296875 -0.743977294921875 -0.006875 -0.047943115234375 -0.743977294921875 -0.007000000000000001 -0.04119873046875 -0.743977294921875 -0.007125000000000002 -0.034759521484375 -0.743977294921875 -0.007250000000000001 -0.027252197265625 -0.743977294921875 -0.007375 -0.020721435546875 -0.743977294921875 -0.0075 -0.013031005859375 -0.743977294921875 -0.007625 -0.004364013671875 -0.743977294921875 +0.003875 -0.003021240234375 -0.743977294921875 +0.004 -0.0069580078125 -0.743977294921875 +0.004125 -0.012603759765625 -0.743977294921875 +0.00425 -0.01727294921875 -0.743977294921875 +0.004375000000000001 -0.021331787109375 -0.743977294921875 +0.004500000000000001 -0.025604248046875 -0.743977294921875 +0.004625 -0.032440185546875 -0.743977294921875 +0.00475 -0.036529541015625 -0.743977294921875 +0.004875 -0.04022216796875 -0.743977294921875 +0.005 -0.0474853515625 -0.743977294921875 +0.005125000000000001 -0.05059814453125 -0.743977294921875 +0.00525 -0.052947998046875 -0.743977294921875 +0.005375000000000001 -0.05499267578125 -0.743977294921875 +0.005499999999999999 -0.0615234375 -0.743977294921875 +0.005625 -0.062347412109375 -0.743977294921875 +0.00575 -0.0626220703125 -0.743977294921875 +0.005874999999999999 -0.062286376953125 -0.743977294921875 +0.006 -0.066314697265625 -0.743977294921875 +0.006125 -0.064483642578125 -0.743977294921875 +0.00625 -0.062225341796875 -0.743977294921875 +0.006375 -0.05908203125 -0.743977294921875 +0.0065 -0.0599365234375 -0.743977294921875 +0.006625000000000001 -0.05523681640625 -0.743977294921875 +0.00675 -0.049957275390625 -0.743977294921875 +0.006875 -0.04791259765625 -0.743977294921875 +0.007000000000000001 -0.041168212890625 -0.743977294921875 +0.007125000000000002 -0.03472900390625 -0.743977294921875 +0.007250000000000001 -0.0272216796875 -0.743977294921875 +0.007375 -0.02069091796875 -0.743977294921875 +0.0075 -0.01300048828125 -0.743977294921875 +0.007625 -0.00433349609375 -0.743977294921875 0.00775 0.003448486328125 -0.743977294921875 0.007875 0.012908935546875 -0.743977294921875 0.008 0.02197265625 -0.743977294921875 @@ -91,37 +91,37 @@ 0.01125 0.034637451171875 -0.743977294921875 0.011375 0.02197265625 -0.743977294921875 0.0115 0.0103759765625 -0.743977294921875 -0.011625 -0.002716064453125 -0.743977294921875 -0.01175 -0.016204833984375 -0.743977294921875 -0.011875 -0.028228759765625 -0.743977294921875 -0.012 -0.042877197265625 -0.743977294921875 -0.012125 -0.0546875 -0.743977294921875 -0.01225 -0.067230224609375 -0.743977294921875 -0.012375 -0.079010009765625 -0.743977294921875 -0.0125 -0.09222412109375 -0.743977294921875 -0.012625 -0.1026611328125 -0.743977294921875 -0.01275 -0.111083984375 -0.743977294921875 -0.012875 -0.119293212890625 -0.743977294921875 -0.013 -0.1307373046875 -0.743977294921875 -0.013125 -0.135955810546875 -0.743977294921875 -0.01325 -0.14031982421875 -0.743977294921875 -0.013375 -0.14788818359375 -0.743977294921875 -0.0135 -0.149383544921875 -0.743977294921875 -0.013625 -0.149200439453125 -0.743977294921875 -0.01375 -0.14764404296875 -0.743977294921875 -0.013875 -0.14923095703125 -0.743977294921875 -0.014 -0.144805908203125 -0.743977294921875 -0.014125 -0.13836669921875 -0.743977294921875 -0.01425 -0.13043212890625 -0.743977294921875 -0.014375 -0.126007080078125 -0.743977294921875 -0.0145 -0.115081787109375 -0.743977294921875 -0.014625 -0.10418701171875 -0.743977294921875 -0.01475 -0.09100341796875 -0.743977294921875 -0.014875 -0.079193115234375 -0.743977294921875 -0.015 -0.0653076171875 -0.743977294921875 -0.015125 -0.049163818359375 -0.743977294921875 -0.01525 -0.03521728515625 -0.743977294921875 -0.015375 -0.0177001953125 -0.743977294921875 +0.011625 -0.002685546875 -0.743977294921875 +0.01175 -0.01617431640625 -0.743977294921875 +0.011875 -0.0281982421875 -0.743977294921875 +0.012 -0.0428466796875 -0.743977294921875 +0.012125 -0.054656982421875 -0.743977294921875 +0.01225 -0.06719970703125 -0.743977294921875 +0.012375 -0.0789794921875 -0.743977294921875 +0.0125 -0.092193603515625 -0.743977294921875 +0.012625 -0.102630615234375 -0.743977294921875 +0.01275 -0.111053466796875 -0.743977294921875 +0.012875 -0.1192626953125 -0.743977294921875 +0.013 -0.130706787109375 -0.743977294921875 +0.013125 -0.13592529296875 -0.743977294921875 +0.01325 -0.140289306640625 -0.743977294921875 +0.013375 -0.147857666015625 -0.743977294921875 +0.0135 -0.14935302734375 -0.743977294921875 +0.013625 -0.149169921875 -0.743977294921875 +0.01375 -0.147613525390625 -0.743977294921875 +0.013875 -0.149200439453125 -0.743977294921875 +0.014 -0.144775390625 -0.743977294921875 +0.014125 -0.138336181640625 -0.743977294921875 +0.01425 -0.130401611328125 -0.743977294921875 +0.014375 -0.1259765625 -0.743977294921875 +0.0145 -0.11505126953125 -0.743977294921875 +0.014625 -0.104156494140625 -0.743977294921875 +0.01475 -0.090972900390625 -0.743977294921875 +0.014875 -0.07916259765625 -0.743977294921875 +0.015 -0.065277099609375 -0.743977294921875 +0.015125 -0.04913330078125 -0.743977294921875 +0.01525 -0.035186767578125 -0.743977294921875 +0.015375 -0.017669677734375 -0.743977294921875 0.0155 0.0 -0.743977294921875 0.015625 0.015899658203125 -0.743977294921875 0.01575 0.034423828125 -0.743977294921875 @@ -154,37 +154,37 @@ 0.019125 0.0474853515625 -0.743977294921875 0.01925 0.02606201171875 -0.743977294921875 0.019375 0.006500244140625 -0.743977294921875 -0.0195 -0.015594482421875 -0.743977294921875 -0.019625 -0.035491943359375 -0.743977294921875 -0.01975 -0.0572509765625 -0.743977294921875 -0.019875 -0.078369140625 -0.743977294921875 -0.02 -0.098785400390625 -0.743977294921875 -0.020125 -0.118499755859375 -0.743977294921875 -0.02025 -0.135162353515625 -0.743977294921875 -0.020375 -0.155517578125 -0.743977294921875 -0.0205 -0.171295166015625 -0.743977294921875 -0.020625 -0.183837890625 -0.743977294921875 -0.02075 -0.1959228515625 -0.743977294921875 -0.020875 -0.209228515625 -0.743977294921875 -0.021 -0.21728515625 -0.743977294921875 -0.021125 -0.222930908203125 -0.743977294921875 -0.02125 -0.2259521484375 -0.743977294921875 -0.021375 -0.231597900390625 -0.743977294921875 -0.0215 -0.2303466796875 -0.743977294921875 -0.021625 -0.2265625 -0.743977294921875 -0.02175 -0.224700927734375 -0.743977294921875 -0.021875 -0.216827392578125 -0.743977294921875 -0.022 -0.205841064453125 -0.743977294921875 -0.022125 -0.194000244140625 -0.743977294921875 -0.02225 -0.18231201171875 -0.743977294921875 -0.022375 -0.16485595703125 -0.743977294921875 -0.0225 -0.147613525390625 -0.743977294921875 -0.022625 -0.126922607421875 -0.743977294921875 -0.02275 -0.109130859375 -0.743977294921875 -0.022875 -0.085540771484375 -0.743977294921875 -0.023 -0.06103515625 -0.743977294921875 -0.023125 -0.03839111328125 -0.743977294921875 -0.02325 -0.0130615234375 -0.743977294921875 +0.0195 -0.01556396484375 -0.743977294921875 +0.019625 -0.03546142578125 -0.743977294921875 +0.01975 -0.057220458984375 -0.743977294921875 +0.019875 -0.078338623046875 -0.743977294921875 +0.02 -0.0987548828125 -0.743977294921875 +0.020125 -0.11846923828125 -0.743977294921875 +0.02025 -0.1351318359375 -0.743977294921875 +0.020375 -0.155487060546875 -0.743977294921875 +0.0205 -0.1712646484375 -0.743977294921875 +0.020625 -0.183807373046875 -0.743977294921875 +0.02075 -0.195892333984375 -0.743977294921875 +0.020875 -0.209197998046875 -0.743977294921875 +0.021 -0.217254638671875 -0.743977294921875 +0.021125 -0.222900390625 -0.743977294921875 +0.02125 -0.225921630859375 -0.743977294921875 +0.021375 -0.2315673828125 -0.743977294921875 +0.0215 -0.230316162109375 -0.743977294921875 +0.021625 -0.226531982421875 -0.743977294921875 +0.02175 -0.22467041015625 -0.743977294921875 +0.021875 -0.216796875 -0.743977294921875 +0.022 -0.205810546875 -0.743977294921875 +0.022125 -0.1939697265625 -0.743977294921875 +0.02225 -0.182281494140625 -0.743977294921875 +0.022375 -0.164825439453125 -0.743977294921875 +0.0225 -0.1475830078125 -0.743977294921875 +0.022625 -0.12689208984375 -0.743977294921875 +0.02275 -0.109100341796875 -0.743977294921875 +0.022875 -0.08551025390625 -0.743977294921875 +0.023 -0.061004638671875 -0.743977294921875 +0.023125 -0.038360595703125 -0.743977294921875 +0.02325 -0.013031005859375 -0.743977294921875 0.023375 0.01043701171875 -0.743977294921875 0.0235 0.036468505859375 -0.743977294921875 0.023625 0.063262939453125 -0.743977294921875 @@ -216,37 +216,37 @@ 0.026875 0.079559326171875 -0.743977294921875 0.027 0.050506591796875 -0.743977294921875 0.027125 0.023834228515625 -0.743977294921875 -0.02725 -0.0059814453125 -0.743977294921875 -0.027375 -0.036285400390625 -0.743977294921875 -0.0275 -0.06317138671875 -0.743977294921875 -0.027625 -0.092376708984375 -0.743977294921875 -0.02775 -0.1177978515625 -0.743977294921875 -0.027875 -0.14691162109375 -0.743977294921875 -0.028 -0.1727294921875 -0.743977294921875 -0.028125 -0.1943359375 -0.743977294921875 -0.02825 -0.21942138671875 -0.743977294921875 -0.028375 -0.2374267578125 -0.743977294921875 -0.02850000000000001 -0.25494384765625 -0.743977294921875 -0.028625 -0.269683837890625 -0.743977294921875 -0.02875 -0.28436279296875 -0.743977294921875 -0.028875 -0.29351806640625 -0.743977294921875 -0.029 -0.29901123046875 -0.743977294921875 -0.029125 -0.301971435546875 -0.743977294921875 -0.02925 -0.305816650390625 -0.743977294921875 -0.029375 -0.302642822265625 -0.743977294921875 -0.0295 -0.29595947265625 -0.743977294921875 -0.029625 -0.287200927734375 -0.743977294921875 -0.02975000000000001 -0.27813720703125 -0.743977294921875 -0.029875 -0.26220703125 -0.743977294921875 -0.03 -0.245391845703125 -0.743977294921875 -0.030125 -0.227081298828125 -0.743977294921875 -0.03025 -0.20556640625 -0.743977294921875 -0.030375 -0.1795654296875 -0.743977294921875 -0.0305 -0.151580810546875 -0.743977294921875 -0.030625 -0.126556396484375 -0.743977294921875 -0.03075 -0.095306396484375 -0.743977294921875 -0.03087499999999999 -0.066253662109375 -0.743977294921875 -0.031 -0.0333251953125 -0.743977294921875 +0.02725 -0.005950927734375 -0.743977294921875 +0.027375 -0.0362548828125 -0.743977294921875 +0.0275 -0.063140869140625 -0.743977294921875 +0.027625 -0.09234619140625 -0.743977294921875 +0.02775 -0.117767333984375 -0.743977294921875 +0.027875 -0.146881103515625 -0.743977294921875 +0.028 -0.172698974609375 -0.743977294921875 +0.028125 -0.194305419921875 -0.743977294921875 +0.02825 -0.219390869140625 -0.743977294921875 +0.028375 -0.237396240234375 -0.743977294921875 +0.02850000000000001 -0.254913330078125 -0.743977294921875 +0.028625 -0.2696533203125 -0.743977294921875 +0.02875 -0.284332275390625 -0.743977294921875 +0.028875 -0.293487548828125 -0.743977294921875 +0.029 -0.298980712890625 -0.743977294921875 +0.029125 -0.30194091796875 -0.743977294921875 +0.02925 -0.3057861328125 -0.743977294921875 +0.029375 -0.3026123046875 -0.743977294921875 +0.0295 -0.295928955078125 -0.743977294921875 +0.029625 -0.28717041015625 -0.743977294921875 +0.02975000000000001 -0.278106689453125 -0.743977294921875 +0.029875 -0.262176513671875 -0.743977294921875 +0.03 -0.245361328125 -0.743977294921875 +0.030125 -0.22705078125 -0.743977294921875 +0.03025 -0.205535888671875 -0.743977294921875 +0.030375 -0.179534912109375 -0.743977294921875 +0.0305 -0.15155029296875 -0.743977294921875 +0.030625 -0.12652587890625 -0.743977294921875 +0.03075 -0.09527587890625 -0.743977294921875 +0.03087499999999999 -0.06622314453125 -0.743977294921875 +0.031 -0.033294677734375 -0.743977294921875 0.031125 0.0 -0.743977294921875 0.03125 0.03033447265625 -0.743977294921875 0.031375 0.063751220703125 -0.743977294921875 @@ -279,37 +279,37 @@ 0.03475000000000001 0.08154296875 -0.487985107421875 0.034875 0.04473876953125 -0.487985107421875 0.035 0.011199951171875 -0.487985107421875 -0.03512500000000001 -0.02642822265625 -0.487985107421875 -0.03525 -0.0601806640625 -0.487985107421875 -0.035375 -0.097015380859375 -0.487985107421875 -0.0355 -0.1341552734375 -0.487985107421875 -0.03562500000000001 -0.16546630859375 -0.487985107421875 -0.03575 -0.198486328125 -0.487985107421875 -0.035875 -0.22857666015625 -0.487985107421875 -0.03600000000000001 -0.257476806640625 -0.487985107421875 -0.036125 -0.283538818359375 -0.487985107421875 -0.03625 -0.307281494140625 -0.487985107421875 -0.036375 -0.327423095703125 -0.487985107421875 -0.0365 -0.342498779296875 -0.487985107421875 -0.036625 -0.35565185546875 -0.487985107421875 -0.03675 -0.36834716796875 -0.487985107421875 -0.036875 -0.373321533203125 -0.487985107421875 -0.037 -0.374969482421875 -0.487985107421875 -0.03712499999999999 -0.376373291015625 -0.487985107421875 -0.03725 -0.37017822265625 -0.487985107421875 -0.037375 -0.35992431640625 -0.487985107421875 -0.0375 -0.350433349609375 -0.487985107421875 -0.037625 -0.332672119140625 -0.487985107421875 -0.03775 -0.31353759765625 -0.487985107421875 -0.037875 -0.291595458984375 -0.487985107421875 -0.038 -0.263671875 -0.487985107421875 -0.038125 -0.236114501953125 -0.487985107421875 -0.03825 -0.204742431640625 -0.487985107421875 -0.038375 -0.172760009765625 -0.487985107421875 -0.0385 -0.13543701171875 -0.487985107421875 -0.038625 -0.097442626953125 -0.487985107421875 -0.03875 -0.061279296875 -0.487985107421875 -0.038875 -0.0205078125 -0.487985107421875 +0.03512500000000001 -0.026397705078125 -0.487985107421875 +0.03525 -0.060150146484375 -0.487985107421875 +0.035375 -0.09698486328125 -0.487985107421875 +0.0355 -0.134124755859375 -0.487985107421875 +0.03562500000000001 -0.165435791015625 -0.487985107421875 +0.03575 -0.198455810546875 -0.487985107421875 +0.035875 -0.228546142578125 -0.487985107421875 +0.03600000000000001 -0.2574462890625 -0.487985107421875 +0.036125 -0.28350830078125 -0.487985107421875 +0.03625 -0.3072509765625 -0.487985107421875 +0.036375 -0.327392578125 -0.487985107421875 +0.0365 -0.34246826171875 -0.487985107421875 +0.036625 -0.355621337890625 -0.487985107421875 +0.03675 -0.368316650390625 -0.487985107421875 +0.036875 -0.373291015625 -0.487985107421875 +0.037 -0.37493896484375 -0.487985107421875 +0.03712499999999999 -0.3763427734375 -0.487985107421875 +0.03725 -0.370147705078125 -0.487985107421875 +0.037375 -0.359893798828125 -0.487985107421875 +0.0375 -0.35040283203125 -0.487985107421875 +0.037625 -0.3326416015625 -0.487985107421875 +0.03775 -0.313507080078125 -0.487985107421875 +0.037875 -0.29156494140625 -0.487985107421875 +0.038 -0.263641357421875 -0.487985107421875 +0.038125 -0.236083984375 -0.487985107421875 +0.03825 -0.2047119140625 -0.487985107421875 +0.038375 -0.1727294921875 -0.487985107421875 +0.0385 -0.135406494140625 -0.487985107421875 +0.038625 -0.097412109375 -0.487985107421875 +0.03875 -0.061248779296875 -0.487985107421875 +0.038875 -0.020477294921875 -0.487985107421875 0.039 0.016510009765625 -0.487985107421875 0.039125 0.05767822265625 -0.487985107421875 0.03925 0.09820556640625 -0.487985107421875 @@ -341,37 +341,37 @@ 0.0425 0.11773681640625 -0.487985107421875 0.042625 0.07470703125 -0.487985107421875 0.04275 0.0352783203125 -0.487985107421875 -0.04287500000000001 -0.008880615234375 -0.487985107421875 -0.04300000000000001 -0.053253173828125 -0.487985107421875 -0.043125 -0.092681884765625 -0.487985107421875 -0.04325 -0.135528564453125 -0.487985107421875 -0.043375 -0.173919677734375 -0.487985107421875 -0.04350000000000001 -0.21380615234375 -0.487985107421875 -0.04362500000000001 -0.2513427734375 -0.487985107421875 -0.04375000000000001 -0.284576416015625 -0.487985107421875 -0.043875 -0.316741943359375 -0.487985107421875 -0.04399999999999999 -0.342742919921875 -0.487985107421875 -0.044125 -0.370330810546875 -0.487985107421875 -0.04425 -0.391754150390625 -0.487985107421875 -0.044375 -0.4073486328125 -0.487985107421875 -0.04449999999999999 -0.4229736328125 -0.487985107421875 -0.04462499999999999 -0.430877685546875 -0.487985107421875 -0.04475 -0.4351806640625 -0.487985107421875 -0.044875 -0.437225341796875 -0.487985107421875 -0.045 -0.432708740234375 -0.487985107421875 -0.045125 -0.42315673828125 -0.487985107421875 -0.04525 -0.4129638671875 -0.487985107421875 -0.045375 -0.394622802734375 -0.487985107421875 -0.0455 -0.37200927734375 -0.487985107421875 -0.045625 -0.350067138671875 -0.487985107421875 -0.04575 -0.31976318359375 -0.487985107421875 -0.045875 -0.28948974609375 -0.487985107421875 -0.046 -0.25421142578125 -0.487985107421875 -0.046125 -0.214599609375 -0.487985107421875 -0.04625 -0.176910400390625 -0.487985107421875 -0.046375 -0.1339111328125 -0.487985107421875 -0.04649999999999999 -0.093109130859375 -0.487985107421875 -0.046625 -0.04681396484375 -0.487985107421875 +0.04287500000000001 -0.00885009765625 -0.487985107421875 +0.04300000000000001 -0.05322265625 -0.487985107421875 +0.043125 -0.0926513671875 -0.487985107421875 +0.04325 -0.135498046875 -0.487985107421875 +0.043375 -0.17388916015625 -0.487985107421875 +0.04350000000000001 -0.213775634765625 -0.487985107421875 +0.04362500000000001 -0.251312255859375 -0.487985107421875 +0.04375000000000001 -0.2845458984375 -0.487985107421875 +0.043875 -0.31671142578125 -0.487985107421875 +0.04399999999999999 -0.34271240234375 -0.487985107421875 +0.044125 -0.37030029296875 -0.487985107421875 +0.04425 -0.3917236328125 -0.487985107421875 +0.044375 -0.407318115234375 -0.487985107421875 +0.04449999999999999 -0.422943115234375 -0.487985107421875 +0.04462499999999999 -0.43084716796875 -0.487985107421875 +0.04475 -0.435150146484375 -0.487985107421875 +0.044875 -0.43719482421875 -0.487985107421875 +0.045 -0.43267822265625 -0.487985107421875 +0.045125 -0.423126220703125 -0.487985107421875 +0.04525 -0.412933349609375 -0.487985107421875 +0.045375 -0.39459228515625 -0.487985107421875 +0.0455 -0.371978759765625 -0.487985107421875 +0.045625 -0.35003662109375 -0.487985107421875 +0.04575 -0.319732666015625 -0.487985107421875 +0.045875 -0.289459228515625 -0.487985107421875 +0.046 -0.254180908203125 -0.487985107421875 +0.046125 -0.214569091796875 -0.487985107421875 +0.04625 -0.1768798828125 -0.487985107421875 +0.046375 -0.133880615234375 -0.487985107421875 +0.04649999999999999 -0.09307861328125 -0.487985107421875 +0.046625 -0.046783447265625 -0.487985107421875 0.04675000000000001 0.0 -0.487985107421875 0.046875 0.042327880859375 -0.487985107421875 0.04699999999999999 0.08892822265625 -0.487985107421875 @@ -404,37 +404,37 @@ 0.05037500000000001 0.106964111328125 -0.487985107421875 0.0505 0.058685302734375 -0.487985107421875 0.05062500000000001 0.014678955078125 -0.487985107421875 -0.05075000000000001 -0.034454345703125 -0.487985107421875 -0.050875 -0.07843017578125 -0.487985107421875 -0.051 -0.126495361328125 -0.487985107421875 -0.051125 -0.173797607421875 -0.487985107421875 -0.05125000000000001 -0.214324951171875 -0.487985107421875 -0.051375 -0.25714111328125 -0.487985107421875 -0.0515 -0.2943115234375 -0.487985107421875 -0.05162500000000001 -0.331512451171875 -0.487985107421875 -0.05175000000000001 -0.365081787109375 -0.487985107421875 -0.051875 -0.39324951171875 -0.487985107421875 -0.052 -0.419036865234375 -0.487985107421875 -0.052125 -0.438323974609375 -0.487985107421875 -0.05225 -0.456695556640625 -0.487985107421875 -0.05237499999999999 -0.468597412109375 -0.487985107421875 -0.0525 -0.474945068359375 -0.487985107421875 -0.052625 -0.47857666015625 -0.487985107421875 -0.05274999999999999 -0.475982666015625 -0.487985107421875 -0.052875 -0.4681396484375 -0.487985107421875 -0.05300000000000001 -0.456573486328125 -0.487985107421875 -0.053125 -0.44061279296875 -0.487985107421875 -0.05324999999999999 -0.418243408203125 -0.487985107421875 -0.05337499999999999 -0.39422607421875 -0.487985107421875 -0.05350000000000001 -0.364501953125 -0.487985107421875 -0.053625 -0.329620361328125 -0.487985107421875 -0.05375 -0.295135498046875 -0.487985107421875 -0.05387499999999999 -0.25445556640625 -0.487985107421875 -0.054 -0.2147216796875 -0.487985107421875 -0.054125 -0.1683349609375 -0.487985107421875 -0.05425 -0.12042236328125 -0.487985107421875 -0.054375 -0.07574462890625 -0.487985107421875 -0.0545 -0.02532958984375 -0.487985107421875 +0.05075000000000001 -0.034423828125 -0.487985107421875 +0.050875 -0.078399658203125 -0.487985107421875 +0.051 -0.12646484375 -0.487985107421875 +0.051125 -0.17376708984375 -0.487985107421875 +0.05125000000000001 -0.21429443359375 -0.487985107421875 +0.051375 -0.257110595703125 -0.487985107421875 +0.0515 -0.294281005859375 -0.487985107421875 +0.05162500000000001 -0.33148193359375 -0.487985107421875 +0.05175000000000001 -0.36505126953125 -0.487985107421875 +0.051875 -0.393218994140625 -0.487985107421875 +0.052 -0.41900634765625 -0.487985107421875 +0.052125 -0.43829345703125 -0.487985107421875 +0.05225 -0.4566650390625 -0.487985107421875 +0.05237499999999999 -0.46856689453125 -0.487985107421875 +0.0525 -0.47491455078125 -0.487985107421875 +0.052625 -0.478546142578125 -0.487985107421875 +0.05274999999999999 -0.4759521484375 -0.487985107421875 +0.052875 -0.468109130859375 -0.487985107421875 +0.05300000000000001 -0.45654296875 -0.487985107421875 +0.053125 -0.440582275390625 -0.487985107421875 +0.05324999999999999 -0.418212890625 -0.487985107421875 +0.05337499999999999 -0.394195556640625 -0.487985107421875 +0.05350000000000001 -0.364471435546875 -0.487985107421875 +0.053625 -0.32958984375 -0.487985107421875 +0.05375 -0.29510498046875 -0.487985107421875 +0.05387499999999999 -0.254425048828125 -0.487985107421875 +0.054 -0.214691162109375 -0.487985107421875 +0.054125 -0.168304443359375 -0.487985107421875 +0.05425 -0.120391845703125 -0.487985107421875 +0.054375 -0.075714111328125 -0.487985107421875 +0.0545 -0.025299072265625 -0.487985107421875 0.054625 0.020294189453125 -0.487985107421875 0.05475 0.070892333984375 -0.487985107421875 0.054875 0.120697021484375 -0.487985107421875 @@ -466,37 +466,37 @@ 0.058125 0.137939453125 -0.487985107421875 0.05825 0.087554931640625 -0.487985107421875 0.058375 0.041351318359375 -0.487985107421875 -0.05850000000000001 -0.0103759765625 -0.487985107421875 -0.05862500000000001 -0.06207275390625 -0.487985107421875 -0.05875 -0.1080322265625 -0.487985107421875 -0.058875 -0.158203125 -0.487985107421875 -0.059 -0.201751708984375 -0.487985107421875 -0.05912500000000001 -0.248016357421875 -0.487985107421875 -0.05925000000000001 -0.291900634765625 -0.487985107421875 -0.059375 -0.32843017578125 -0.487985107421875 -0.05950000000000001 -0.36553955078125 -0.487985107421875 -0.059625 -0.396026611328125 -0.487985107421875 -0.05975000000000001 -0.42529296875 -0.487985107421875 -0.059875 -0.44989013671875 -0.487985107421875 -0.06 -0.468292236328125 -0.487985107421875 -0.06012499999999999 -0.483367919921875 -0.487985107421875 -0.06025 -0.49237060546875 -0.487985107421875 -0.060375 -0.497283935546875 -0.487985107421875 -0.0605 -0.497222900390625 -0.487985107421875 -0.060625 -0.4920654296875 -0.487985107421875 -0.06074999999999999 -0.481201171875 -0.487985107421875 -0.060875 -0.467315673828125 -0.487985107421875 -0.061 -0.44659423828125 -0.487985107421875 -0.061125 -0.420989990234375 -0.487985107421875 -0.06125 -0.394256591796875 -0.487985107421875 -0.061375 -0.360107421875 -0.487985107421875 -0.0615 -0.326019287109375 -0.487985107421875 -0.061625 -0.284912109375 -0.487985107421875 -0.06174999999999999 -0.240509033203125 -0.487985107421875 -0.061875 -0.198272705078125 -0.487985107421875 -0.062 -0.149383544921875 -0.487985107421875 -0.06212499999999999 -0.103851318359375 -0.487985107421875 -0.06225000000000001 -0.052215576171875 -0.487985107421875 +0.05850000000000001 -0.010345458984375 -0.487985107421875 +0.05862500000000001 -0.062042236328125 -0.487985107421875 +0.05875 -0.108001708984375 -0.487985107421875 +0.058875 -0.158172607421875 -0.487985107421875 +0.059 -0.20172119140625 -0.487985107421875 +0.05912500000000001 -0.24798583984375 -0.487985107421875 +0.05925000000000001 -0.2918701171875 -0.487985107421875 +0.059375 -0.328399658203125 -0.487985107421875 +0.05950000000000001 -0.365509033203125 -0.487985107421875 +0.059625 -0.39599609375 -0.487985107421875 +0.05975000000000001 -0.425262451171875 -0.487985107421875 +0.059875 -0.449859619140625 -0.487985107421875 +0.06 -0.46826171875 -0.487985107421875 +0.06012499999999999 -0.48333740234375 -0.487985107421875 +0.06025 -0.492340087890625 -0.487985107421875 +0.060375 -0.49725341796875 -0.487985107421875 +0.0605 -0.4971923828125 -0.487985107421875 +0.060625 -0.492034912109375 -0.487985107421875 +0.06074999999999999 -0.481170654296875 -0.487985107421875 +0.060875 -0.46728515625 -0.487985107421875 +0.061 -0.446563720703125 -0.487985107421875 +0.061125 -0.42095947265625 -0.487985107421875 +0.06125 -0.39422607421875 -0.487985107421875 +0.061375 -0.360076904296875 -0.487985107421875 +0.0615 -0.32598876953125 -0.487985107421875 +0.061625 -0.284881591796875 -0.487985107421875 +0.06174999999999999 -0.240478515625 -0.487985107421875 +0.061875 -0.1982421875 -0.487985107421875 +0.062 -0.14935302734375 -0.487985107421875 +0.06212499999999999 -0.10382080078125 -0.487985107421875 +0.06225000000000001 -0.05218505859375 -0.487985107421875 0.06237500000000001 0.0 -0.487985107421875 0.0625 0.0469970703125 -0.487985107421875 0.06262499999999999 0.098724365234375 -0.487985107421875 @@ -529,37 +529,37 @@ 0.06600000000000001 0.11383056640625 -0.2319929199218749 0.066125 0.06243896484375 -0.2319929199218749 0.06625000000000001 0.015625 -0.2319929199218749 -0.06637500000000001 -0.036468505859375 -0.2319929199218749 -0.0665 -0.08306884765625 -0.2319929199218749 -0.066625 -0.13385009765625 -0.2319929199218749 -0.06675 -0.1832275390625 -0.2319929199218749 -0.06687500000000001 -0.2257080078125 -0.2319929199218749 -0.067 -0.270782470703125 -0.2319929199218749 -0.067125 -0.308837890625 -0.2319929199218749 -0.06725000000000001 -0.347442626953125 -0.2319929199218749 -0.06737500000000001 -0.382659912109375 -0.2319929199218749 -0.0675 -0.41021728515625 -0.2319929199218749 -0.067625 -0.437103271484375 -0.2319929199218749 -0.06775 -0.457244873046875 -0.2319929199218749 -0.06787500000000001 -0.47418212890625 -0.2319929199218749 -0.06800000000000001 -0.486541748046875 -0.2319929199218749 -0.068125 -0.49310302734375 -0.2319929199218749 -0.06825000000000001 -0.49456787109375 -0.2319929199218749 -0.068375 -0.491851806640625 -0.2319929199218749 -0.06850000000000001 -0.48297119140625 -0.2319929199218749 -0.06862500000000001 -0.4696044921875 -0.2319929199218749 -0.06875 -0.45318603515625 -0.2319929199218749 -0.06887500000000001 -0.429473876953125 -0.2319929199218749 -0.069 -0.40478515625 -0.2319929199218749 -0.06912500000000001 -0.372467041015625 -0.2319929199218749 -0.06925000000000001 -0.336822509765625 -0.2319929199218749 -0.06937500000000001 -0.30157470703125 -0.2319929199218749 -0.06950000000000001 -0.258758544921875 -0.2319929199218749 -0.069625 -0.218353271484375 -0.2319929199218749 -0.06975 -0.171173095703125 -0.2319929199218749 -0.06987500000000001 -0.121856689453125 -0.2319929199218749 -0.07000000000000001 -0.07666015625 -0.2319929199218749 -0.070125 -0.02557373046875 -0.2319929199218749 +0.06637500000000001 -0.03643798828125 -0.2319929199218749 +0.0665 -0.083038330078125 -0.2319929199218749 +0.066625 -0.133819580078125 -0.2319929199218749 +0.06675 -0.183197021484375 -0.2319929199218749 +0.06687500000000001 -0.225677490234375 -0.2319929199218749 +0.067 -0.270751953125 -0.2319929199218749 +0.067125 -0.308807373046875 -0.2319929199218749 +0.06725000000000001 -0.347412109375 -0.2319929199218749 +0.06737500000000001 -0.38262939453125 -0.2319929199218749 +0.0675 -0.410186767578125 -0.2319929199218749 +0.067625 -0.43707275390625 -0.2319929199218749 +0.06775 -0.45721435546875 -0.2319929199218749 +0.06787500000000001 -0.474151611328125 -0.2319929199218749 +0.06800000000000001 -0.48651123046875 -0.2319929199218749 +0.068125 -0.493072509765625 -0.2319929199218749 +0.06825000000000001 -0.494537353515625 -0.2319929199218749 +0.068375 -0.4918212890625 -0.2319929199218749 +0.06850000000000001 -0.482940673828125 -0.2319929199218749 +0.06862500000000001 -0.469573974609375 -0.2319929199218749 +0.06875 -0.453155517578125 -0.2319929199218749 +0.06887500000000001 -0.429443359375 -0.2319929199218749 +0.069 -0.404754638671875 -0.2319929199218749 +0.06912500000000001 -0.3724365234375 -0.2319929199218749 +0.06925000000000001 -0.3367919921875 -0.2319929199218749 +0.06937500000000001 -0.301544189453125 -0.2319929199218749 +0.06950000000000001 -0.25872802734375 -0.2319929199218749 +0.069625 -0.21832275390625 -0.2319929199218749 +0.06975 -0.171142578125 -0.2319929199218749 +0.06987500000000001 -0.121826171875 -0.2319929199218749 +0.07000000000000001 -0.076629638671875 -0.2319929199218749 +0.070125 -0.025543212890625 -0.2319929199218749 0.07025000000000001 0.02044677734375 -0.2319929199218749 0.07037500000000001 0.0714111328125 -0.2319929199218749 0.07050000000000001 0.121307373046875 -0.2319929199218749 @@ -591,37 +591,37 @@ 0.07374999999999999 0.132171630859375 -0.2319929199218749 0.073875 0.0838623046875 -0.2319929199218749 0.074 0.03961181640625 -0.2319929199218749 -0.074125 -0.0098876953125 -0.2319929199218749 -0.07424999999999999 -0.059173583984375 -0.2319929199218749 -0.07437499999999999 -0.10260009765625 -0.2319929199218749 -0.0745 -0.1500244140625 -0.2319929199218749 -0.07462499999999999 -0.191314697265625 -0.2319929199218749 -0.07475 -0.234283447265625 -0.2319929199218749 -0.07487500000000001 -0.275421142578125 -0.2319929199218749 -0.075 -0.30865478515625 -0.2319929199218749 -0.07512499999999999 -0.343536376953125 -0.2319929199218749 -0.07524999999999999 -0.37176513671875 -0.2319929199218749 -0.075375 -0.3975830078125 -0.2319929199218749 -0.0755 -0.42059326171875 -0.2319929199218749 -0.075625 -0.437347412109375 -0.2319929199218749 -0.07574999999999999 -0.44952392578125 -0.2319929199218749 -0.075875 -0.457916259765625 -0.2319929199218749 -0.076 -0.460479736328125 -0.2319929199218749 -0.076125 -0.4599609375 -0.2319929199218749 -0.07625 -0.4552001953125 -0.2319929199218749 -0.07637499999999999 -0.44317626953125 -0.2319929199218749 -0.0765 -0.4300537109375 -0.2319929199218749 -0.076625 -0.409088134765625 -0.2319929199218749 -0.07675 -0.3856201171875 -0.2319929199218749 -0.076875 -0.360870361328125 -0.2319929199218749 -0.077 -0.32806396484375 -0.2319929199218749 -0.077125 -0.2969970703125 -0.2319929199218749 -0.07725 -0.2593994140625 -0.2319929199218749 -0.07737499999999999 -0.217926025390625 -0.2319929199218749 -0.0775 -0.179656982421875 -0.2319929199218749 -0.077625 -0.13458251953125 -0.2319929199218749 -0.07774999999999999 -0.09356689453125 -0.2319929199218749 -0.07787500000000001 -0.04705810546875 -0.2319929199218749 +0.074125 -0.009857177734375 -0.2319929199218749 +0.07424999999999999 -0.05914306640625 -0.2319929199218749 +0.07437499999999999 -0.102569580078125 -0.2319929199218749 +0.0745 -0.149993896484375 -0.2319929199218749 +0.07462499999999999 -0.1912841796875 -0.2319929199218749 +0.07475 -0.2342529296875 -0.2319929199218749 +0.07487500000000001 -0.275390625 -0.2319929199218749 +0.075 -0.308624267578125 -0.2319929199218749 +0.07512499999999999 -0.343505859375 -0.2319929199218749 +0.07524999999999999 -0.371734619140625 -0.2319929199218749 +0.075375 -0.397552490234375 -0.2319929199218749 +0.0755 -0.420562744140625 -0.2319929199218749 +0.075625 -0.43731689453125 -0.2319929199218749 +0.07574999999999999 -0.449493408203125 -0.2319929199218749 +0.075875 -0.4578857421875 -0.2319929199218749 +0.076 -0.46044921875 -0.2319929199218749 +0.076125 -0.459930419921875 -0.2319929199218749 +0.07625 -0.455169677734375 -0.2319929199218749 +0.07637499999999999 -0.443145751953125 -0.2319929199218749 +0.0765 -0.430023193359375 -0.2319929199218749 +0.076625 -0.4090576171875 -0.2319929199218749 +0.07675 -0.385589599609375 -0.2319929199218749 +0.076875 -0.36083984375 -0.2319929199218749 +0.077 -0.328033447265625 -0.2319929199218749 +0.077125 -0.296966552734375 -0.2319929199218749 +0.07725 -0.259368896484375 -0.2319929199218749 +0.07737499999999999 -0.2178955078125 -0.2319929199218749 +0.0775 -0.17962646484375 -0.2319929199218749 +0.077625 -0.134552001953125 -0.2319929199218749 +0.07774999999999999 -0.093536376953125 -0.2319929199218749 +0.07787500000000001 -0.047027587890625 -0.2319929199218749 0.07800000000000001 0.0 -0.2319929199218749 0.078125 0.0421142578125 -0.2319929199218749 0.07824999999999999 0.0880126953125 -0.2319929199218749 @@ -654,37 +654,37 @@ 0.081625 0.095703125 -0.2319929199218749 0.08175000000000001 0.052520751953125 -0.2319929199218749 0.081875 0.0130615234375 -0.2319929199218749 -0.08200000000000001 -0.030487060546875 -0.2319929199218749 -0.082125 -0.069427490234375 -0.2319929199218749 -0.08225 -0.111175537109375 -0.2319929199218749 -0.08237500000000001 -0.1522216796875 -0.2319929199218749 -0.0825 -0.186370849609375 -0.2319929199218749 -0.08262500000000001 -0.223602294921875 -0.2319929199218749 -0.08275 -0.254974365234375 -0.2319929199218749 -0.08287500000000001 -0.285125732421875 -0.2319929199218749 -0.08300000000000001 -0.313995361328125 -0.2319929199218749 -0.083125 -0.3370361328125 -0.2319929199218749 -0.08324999999999999 -0.3564453125 -0.2319929199218749 -0.083375 -0.37286376953125 -0.2319929199218749 -0.08350000000000001 -0.38421630859375 -0.2319929199218749 -0.08362500000000001 -0.39422607421875 -0.2319929199218749 -0.08375 -0.399566650390625 -0.2319929199218749 -0.08387500000000001 -0.398193359375 -0.2319929199218749 -0.084 -0.396026611328125 -0.2319929199218749 -0.08412500000000001 -0.386383056640625 -0.2319929199218749 -0.08425000000000001 -0.375701904296875 -0.2319929199218749 -0.084375 -0.362548828125 -0.2319929199218749 -0.08450000000000001 -0.341339111328125 -0.2319929199218749 -0.084625 -0.32171630859375 -0.2319929199218749 -0.08475 -0.29656982421875 -0.2319929199218749 -0.08487500000000001 -0.265960693359375 -0.2319929199218749 -0.085 -0.238128662109375 -0.2319929199218749 -0.08512500000000001 -0.2030029296875 -0.2319929199218749 -0.08525 -0.171295166015625 -0.2319929199218749 -0.085375 -0.13427734375 -0.2319929199218749 -0.08550000000000001 -0.094970703125 -0.2319929199218749 -0.085625 -0.059722900390625 -0.2319929199218749 -0.08575000000000001 -0.019805908203125 -0.2319929199218749 +0.08200000000000001 -0.03045654296875 -0.2319929199218749 +0.082125 -0.06939697265625 -0.2319929199218749 +0.08225 -0.11114501953125 -0.2319929199218749 +0.08237500000000001 -0.152191162109375 -0.2319929199218749 +0.0825 -0.18634033203125 -0.2319929199218749 +0.08262500000000001 -0.22357177734375 -0.2319929199218749 +0.08275 -0.25494384765625 -0.2319929199218749 +0.08287500000000001 -0.28509521484375 -0.2319929199218749 +0.08300000000000001 -0.31396484375 -0.2319929199218749 +0.083125 -0.337005615234375 -0.2319929199218749 +0.08324999999999999 -0.356414794921875 -0.2319929199218749 +0.083375 -0.372833251953125 -0.2319929199218749 +0.08350000000000001 -0.384185791015625 -0.2319929199218749 +0.08362500000000001 -0.394195556640625 -0.2319929199218749 +0.08375 -0.3995361328125 -0.2319929199218749 +0.08387500000000001 -0.398162841796875 -0.2319929199218749 +0.084 -0.39599609375 -0.2319929199218749 +0.08412500000000001 -0.3863525390625 -0.2319929199218749 +0.08425000000000001 -0.37567138671875 -0.2319929199218749 +0.084375 -0.362518310546875 -0.2319929199218749 +0.08450000000000001 -0.34130859375 -0.2319929199218749 +0.084625 -0.321685791015625 -0.2319929199218749 +0.08475 -0.296539306640625 -0.2319929199218749 +0.08487500000000001 -0.26593017578125 -0.2319929199218749 +0.085 -0.23809814453125 -0.2319929199218749 +0.08512500000000001 -0.202972412109375 -0.2319929199218749 +0.08525 -0.1712646484375 -0.2319929199218749 +0.085375 -0.134246826171875 -0.2319929199218749 +0.08550000000000001 -0.094940185546875 -0.2319929199218749 +0.085625 -0.0596923828125 -0.2319929199218749 +0.08575000000000001 -0.019775390625 -0.2319929199218749 0.08587500000000002 0.01580810546875 -0.2319929199218749 0.08600000000000001 0.05523681640625 -0.2319929199218749 0.08612500000000001 0.093231201171875 -0.2319929199218749 @@ -716,37 +716,37 @@ 0.089375 0.094390869140625 -0.2319929199218749 0.08949999999999999 0.059906005859375 -0.2319929199218749 0.089625 0.028289794921875 -0.2319929199218749 -0.08975 -0.00701904296875 -0.2319929199218749 -0.08987499999999999 -0.04193115234375 -0.2319929199218749 -0.09 -0.072113037109375 -0.2319929199218749 -0.09012499999999999 -0.10546875 -0.2319929199218749 -0.09025 -0.13446044921875 -0.2319929199218749 -0.090375 -0.163330078125 -0.2319929199218749 -0.09050000000000001 -0.1920166015625 -0.2319929199218749 -0.090625 -0.216033935546875 -0.2319929199218749 -0.09074999999999999 -0.237518310546875 -0.2319929199218749 -0.09087499999999999 -0.25701904296875 -0.2319929199218749 -0.091 -0.2725830078125 -0.2319929199218749 -0.09112500000000001 -0.288330078125 -0.2319929199218749 -0.09125 -0.299835205078125 -0.2319929199218749 -0.09137499999999999 -0.3055419921875 -0.2319929199218749 -0.0915 -0.31121826171875 -0.2319929199218749 -0.091625 -0.310272216796875 -0.2319929199218749 -0.09175000000000001 -0.3099365234375 -0.2319929199218749 -0.091875 -0.30670166015625 -0.2319929199218749 -0.09199999999999999 -0.29595947265625 -0.2319929199218749 -0.092125 -0.287200927734375 -0.2319929199218749 -0.09225 -0.274444580078125 -0.2319929199218749 -0.09237499999999999 -0.25518798828125 -0.2319929199218749 -0.0925 -0.23883056640625 -0.2319929199218749 -0.09262499999999999 -0.21514892578125 -0.2319929199218749 -0.09275 -0.19476318359375 -0.2319929199218749 -0.092875 -0.17010498046875 -0.2319929199218749 -0.09299999999999999 -0.141571044921875 -0.2319929199218749 -0.093125 -0.11669921875 -0.2319929199218749 -0.09324999999999999 -0.08660888671875 -0.2319929199218749 -0.093375 -0.060211181640625 -0.2319929199218749 -0.09350000000000001 -0.0302734375 -0.2319929199218749 +0.08975 -0.006988525390625 -0.2319929199218749 +0.08987499999999999 -0.041900634765625 -0.2319929199218749 +0.09 -0.07208251953125 -0.2319929199218749 +0.09012499999999999 -0.105438232421875 -0.2319929199218749 +0.09025 -0.134429931640625 -0.2319929199218749 +0.090375 -0.163299560546875 -0.2319929199218749 +0.09050000000000001 -0.191986083984375 -0.2319929199218749 +0.090625 -0.21600341796875 -0.2319929199218749 +0.09074999999999999 -0.23748779296875 -0.2319929199218749 +0.09087499999999999 -0.256988525390625 -0.2319929199218749 +0.091 -0.272552490234375 -0.2319929199218749 +0.09112500000000001 -0.288299560546875 -0.2319929199218749 +0.09125 -0.2998046875 -0.2319929199218749 +0.09137499999999999 -0.305511474609375 -0.2319929199218749 +0.0915 -0.311187744140625 -0.2319929199218749 +0.091625 -0.31024169921875 -0.2319929199218749 +0.09175000000000001 -0.309906005859375 -0.2319929199218749 +0.091875 -0.306671142578125 -0.2319929199218749 +0.09199999999999999 -0.295928955078125 -0.2319929199218749 +0.092125 -0.28717041015625 -0.2319929199218749 +0.09225 -0.2744140625 -0.2319929199218749 +0.09237499999999999 -0.255157470703125 -0.2319929199218749 +0.0925 -0.238800048828125 -0.2319929199218749 +0.09262499999999999 -0.215118408203125 -0.2319929199218749 +0.09275 -0.194732666015625 -0.2319929199218749 +0.092875 -0.170074462890625 -0.2319929199218749 +0.09299999999999999 -0.14154052734375 -0.2319929199218749 +0.093125 -0.116668701171875 -0.2319929199218749 +0.09324999999999999 -0.086578369140625 -0.2319929199218749 +0.093375 -0.0601806640625 -0.2319929199218749 +0.09350000000000001 -0.030242919921875 -0.2319929199218749 0.09362500000000001 0.0 -0.2319929199218749 0.09375 0.026824951171875 -0.2319929199218749 0.09387499999999999 0.056365966796875 -0.2319929199218749 @@ -779,37 +779,37 @@ 0.09725 0.0528564453125 0.02399926757812504 0.09737500000000001 0.02899169921875 0.02399926757812504 0.0975 0.007110595703125 0.02399926757812504 -0.09762500000000001 -0.016632080078125 0.02399926757812504 -0.09775 -0.037841796875 0.02399926757812504 -0.097875 -0.059783935546875 0.02399926757812504 -0.09800000000000001 -0.081817626953125 0.02399926757812504 -0.098125 -0.098785400390625 0.02399926757812504 -0.09825000000000001 -0.118499755859375 0.02399926757812504 -0.098375 -0.132232666015625 0.02399926757812504 -0.09850000000000001 -0.14892578125 0.02399926757812504 -0.09862500000000001 -0.160369873046875 0.02399926757812504 -0.09875 -0.172119140625 0.02399926757812504 -0.09887499999999999 -0.17919921875 0.02399926757812504 -0.099 -0.187469482421875 0.02399926757812504 -0.09912500000000001 -0.194671630859375 0.02399926757812504 -0.09925000000000001 -0.195037841796875 0.02399926757812504 -0.099375 -0.197662353515625 0.02399926757812504 -0.09950000000000001 -0.1937255859375 0.02399926757812504 -0.099625 -0.192657470703125 0.02399926757812504 -0.09975000000000001 -0.18475341796875 0.02399926757812504 -0.09987500000000001 -0.179656982421875 0.02399926757812504 -0.1 -0.168914794921875 0.02399926757812504 -0.100125 -0.16033935546875 0.02399926757812504 -0.10025 -0.147125244140625 0.02399926757812504 -0.100375 -0.1356201171875 0.02399926757812504 -0.1005 -0.122650146484375 0.02399926757812504 -0.100625 -0.1068115234375 0.02399926757812504 -0.10075 -0.091827392578125 0.02399926757812504 -0.100875 -0.075286865234375 0.02399926757812504 -0.101 -0.05902099609375 0.02399926757812504 -0.101125 -0.0408935546875 0.02399926757812504 -0.10125 -0.025726318359375 0.02399926757812504 -0.101375 -0.008331298828125 0.02399926757812504 +0.09762500000000001 -0.0166015625 0.02399926757812504 +0.09775 -0.037811279296875 0.02399926757812504 +0.097875 -0.05975341796875 0.02399926757812504 +0.09800000000000001 -0.081787109375 0.02399926757812504 +0.098125 -0.0987548828125 0.02399926757812504 +0.09825000000000001 -0.11846923828125 0.02399926757812504 +0.098375 -0.1322021484375 0.02399926757812504 +0.09850000000000001 -0.148895263671875 0.02399926757812504 +0.09862500000000001 -0.16033935546875 0.02399926757812504 +0.09875 -0.172088623046875 0.02399926757812504 +0.09887499999999999 -0.179168701171875 0.02399926757812504 +0.099 -0.18743896484375 0.02399926757812504 +0.09912500000000001 -0.19464111328125 0.02399926757812504 +0.09925000000000001 -0.19500732421875 0.02399926757812504 +0.099375 -0.1976318359375 0.02399926757812504 +0.09950000000000001 -0.193695068359375 0.02399926757812504 +0.099625 -0.192626953125 0.02399926757812504 +0.09975000000000001 -0.184722900390625 0.02399926757812504 +0.09987500000000001 -0.17962646484375 0.02399926757812504 +0.1 -0.16888427734375 0.02399926757812504 +0.100125 -0.160308837890625 0.02399926757812504 +0.10025 -0.1470947265625 0.02399926757812504 +0.100375 -0.135589599609375 0.02399926757812504 +0.1005 -0.12261962890625 0.02399926757812504 +0.100625 -0.106781005859375 0.02399926757812504 +0.10075 -0.091796875 0.02399926757812504 +0.100875 -0.07525634765625 0.02399926757812504 +0.101 -0.058990478515625 0.02399926757812504 +0.101125 -0.040863037109375 0.02399926757812504 +0.10125 -0.02569580078125 0.02399926757812504 +0.101375 -0.00830078125 0.02399926757812504 0.1015 0.00665283203125 0.02399926757812504 0.101625 0.02252197265625 0.02399926757812504 0.10175 0.03839111328125 0.02399926757812504 @@ -841,37 +841,37 @@ 0.105 0.026092529296875 0.02399926757812504 0.105125 0.01654052734375 0.02399926757812504 0.10525 0.00738525390625 0.02399926757812504 -0.105375 -0.001861572265625 0.02399926757812504 -0.1055 -0.01043701171875 0.02399926757812504 -0.105625 -0.0181884765625 0.02399926757812504 -0.10575 -0.024932861328125 0.02399926757812504 -0.105875 -0.03179931640625 0.02399926757812504 -0.106 -0.0364990234375 0.02399926757812504 -0.106125 -0.04290771484375 0.02399926757812504 -0.10625 -0.04486083984375 0.02399926757812504 -0.106375 -0.0499267578125 0.02399926757812504 -0.1065 -0.054046630859375 0.02399926757812504 -0.106625 -0.0535888671875 0.02399926757812504 -0.10675 -0.05670166015625 0.02399926757812504 -0.106875 -0.0540771484375 0.02399926757812504 -0.107 -0.055816650390625 0.02399926757812504 -0.107125 -0.05169677734375 0.02399926757812504 -0.10725 -0.052215576171875 0.02399926757812504 -0.107375 -0.04693603515625 0.02399926757812504 -0.1075 -0.04644775390625 0.02399926757812504 -0.107625 -0.0404052734375 0.02399926757812504 -0.10775 -0.0391845703125 0.02399926757812504 -0.107875 -0.03277587890625 0.02399926757812504 -0.108 -0.030914306640625 0.02399926757812504 -0.108125 -0.0289306640625 0.02399926757812504 -0.10825 -0.02264404296875 0.02399926757812504 -0.108375 -0.0205078125 0.02399926757812504 -0.1085 -0.014923095703125 0.02399926757812504 -0.108625 -0.012603759765625 0.02399926757812504 -0.10875 -0.00830078125 0.02399926757812504 -0.108875 -0.006256103515625 0.02399926757812504 -0.109 -0.003265380859375 0.02399926757812504 -0.109125 -0.00164794921875 0.02399926757812504 +0.105375 -0.0018310546875 0.02399926757812504 +0.1055 -0.010406494140625 0.02399926757812504 +0.105625 -0.018157958984375 0.02399926757812504 +0.10575 -0.02490234375 0.02399926757812504 +0.105875 -0.031768798828125 0.02399926757812504 +0.106 -0.036468505859375 0.02399926757812504 +0.106125 -0.042877197265625 0.02399926757812504 +0.10625 -0.044830322265625 0.02399926757812504 +0.106375 -0.049896240234375 0.02399926757812504 +0.1065 -0.05401611328125 0.02399926757812504 +0.106625 -0.053558349609375 0.02399926757812504 +0.10675 -0.056671142578125 0.02399926757812504 +0.106875 -0.054046630859375 0.02399926757812504 +0.107 -0.0557861328125 0.02399926757812504 +0.107125 -0.051666259765625 0.02399926757812504 +0.10725 -0.05218505859375 0.02399926757812504 +0.107375 -0.046905517578125 0.02399926757812504 +0.1075 -0.046417236328125 0.02399926757812504 +0.107625 -0.040374755859375 0.02399926757812504 +0.10775 -0.039154052734375 0.02399926757812504 +0.107875 -0.032745361328125 0.02399926757812504 +0.108 -0.0308837890625 0.02399926757812504 +0.108125 -0.028900146484375 0.02399926757812504 +0.10825 -0.022613525390625 0.02399926757812504 +0.108375 -0.020477294921875 0.02399926757812504 +0.1085 -0.014892578125 0.02399926757812504 +0.108625 -0.0125732421875 0.02399926757812504 +0.10875 -0.008270263671875 0.02399926757812504 +0.108875 -0.0062255859375 0.02399926757812504 +0.109 -0.00323486328125 0.02399926757812504 +0.109125 -0.001617431640625 0.02399926757812504 0.10925 0.0 0.02399926757812504 0.109375 0.000946044921875 0.02399926757812504 0.1095 0.002044677734375 0.02399926757812504 @@ -879,31 +879,31 @@ 0.10975 0.001983642578125 0.02399926757812504 0.109875 0.0 0.02399926757812504 0.11 0.0 0.02399926757812504 -0.110125 -0.003387451171875 0.02399926757812504 -0.11025 -0.003753662109375 0.02399926757812504 -0.110375 -0.008209228515625 0.02399926757812504 -0.1105 -0.00885009765625 0.02399926757812504 -0.110625 -0.01397705078125 0.02399926757812504 -0.11075 -0.0146484375 0.02399926757812504 -0.110875 -0.01513671875 0.02399926757812504 -0.111 -0.0206298828125 0.02399926757812504 -0.111125 -0.020904541015625 0.02399926757812504 -0.11125 -0.026153564453125 0.02399926757812504 -0.111375 -0.025909423828125 0.02399926757812504 -0.1115 -0.030548095703125 0.02399926757812504 -0.111625 -0.029632568359375 0.02399926757812504 -0.11175 -0.033111572265625 0.02399926757812504 -0.111875 -0.031494140625 0.02399926757812504 -0.112 -0.0335693359375 0.02399926757812504 -0.112125 -0.03106689453125 0.02399926757812504 -0.11225 -0.031463623046875 0.02399926757812504 -0.112375 -0.02764892578125 0.02399926757812504 -0.1125 -0.023956298828125 0.02399926757812504 -0.112625 -0.021759033203125 0.02399926757812504 -0.11275 -0.017181396484375 0.02399926757812504 -0.112875 -0.01312255859375 0.02399926757812504 -0.113 -0.0072021484375 0.02399926757812504 -0.113125 -0.001953125 0.02399926757812504 +0.110125 -0.00335693359375 0.02399926757812504 +0.11025 -0.00372314453125 0.02399926757812504 +0.110375 -0.0081787109375 0.02399926757812504 +0.1105 -0.008819580078125 0.02399926757812504 +0.110625 -0.013946533203125 0.02399926757812504 +0.11075 -0.014617919921875 0.02399926757812504 +0.110875 -0.015106201171875 0.02399926757812504 +0.111 -0.020599365234375 0.02399926757812504 +0.111125 -0.0208740234375 0.02399926757812504 +0.11125 -0.026123046875 0.02399926757812504 +0.111375 -0.02587890625 0.02399926757812504 +0.1115 -0.030517578125 0.02399926757812504 +0.111625 -0.02960205078125 0.02399926757812504 +0.11175 -0.0330810546875 0.02399926757812504 +0.111875 -0.031463623046875 0.02399926757812504 +0.112 -0.033538818359375 0.02399926757812504 +0.112125 -0.031036376953125 0.02399926757812504 +0.11225 -0.03143310546875 0.02399926757812504 +0.112375 -0.027618408203125 0.02399926757812504 +0.1125 -0.02392578125 0.02399926757812504 +0.112625 -0.021728515625 0.02399926757812504 +0.11275 -0.01715087890625 0.02399926757812504 +0.112875 -0.013092041015625 0.02399926757812504 +0.113 -0.007171630859375 0.02399926757812504 +0.113125 -0.001922607421875 0.02399926757812504 0.11325 0.004547119140625 0.02399926757812504 0.113375 0.01129150390625 0.02399926757812504 0.1135 0.018218994140625 0.02399926757812504 @@ -935,37 +935,37 @@ 0.11675 0.032135009765625 0.02399926757812504 0.116875 0.02020263671875 0.02399926757812504 0.117 0.006988525390625 0.02399926757812504 -0.117125 -0.005615234375 0.02399926757812504 -0.11725 -0.0203857421875 0.02399926757812504 -0.117375 -0.03466796875 0.02399926757812504 -0.1175 -0.0489501953125 0.02399926757812504 -0.117625 -0.062896728515625 0.02399926757812504 -0.11775 -0.07745361328125 0.02399926757812504 -0.117875 -0.09039306640625 0.02399926757812504 -0.118 -0.105743408203125 0.02399926757812504 -0.118125 -0.115875244140625 0.02399926757812504 -0.11825 -0.12591552734375 0.02399926757812504 -0.118375 -0.138092041015625 0.02399926757812504 -0.1185 -0.14569091796875 0.02399926757812504 -0.118625 -0.1563720703125 0.02399926757812504 -0.11875 -0.160430908203125 0.02399926757812504 -0.118875 -0.168212890625 0.02399926757812504 -0.119 -0.1693115234375 0.02399926757812504 -0.119125 -0.17364501953125 0.02399926757812504 -0.11925 -0.171173095703125 0.02399926757812504 -0.119375 -0.17205810546875 0.02399926757812504 -0.1195 -0.1658935546875 0.02399926757812504 -0.119625 -0.1630859375 0.02399926757812504 -0.11975 -0.153289794921875 0.02399926757812504 -0.119875 -0.141815185546875 0.02399926757812504 -0.12 -0.133575439453125 0.02399926757812504 -0.120125 -0.118865966796875 0.02399926757812504 -0.12025 -0.107208251953125 0.02399926757812504 -0.120375 -0.089752197265625 0.02399926757812504 -0.1205 -0.073089599609375 0.02399926757812504 -0.120625 -0.055389404296875 0.02399926757812504 -0.12075 -0.0360107421875 0.02399926757812504 -0.120875 -0.016998291015625 0.02399926757812504 +0.117125 -0.005584716796875 0.02399926757812504 +0.11725 -0.020355224609375 0.02399926757812504 +0.117375 -0.034637451171875 0.02399926757812504 +0.1175 -0.048919677734375 0.02399926757812504 +0.117625 -0.0628662109375 0.02399926757812504 +0.11775 -0.077423095703125 0.02399926757812504 +0.117875 -0.090362548828125 0.02399926757812504 +0.118 -0.105712890625 0.02399926757812504 +0.118125 -0.1158447265625 0.02399926757812504 +0.11825 -0.125885009765625 0.02399926757812504 +0.118375 -0.1380615234375 0.02399926757812504 +0.1185 -0.145660400390625 0.02399926757812504 +0.118625 -0.156341552734375 0.02399926757812504 +0.11875 -0.160400390625 0.02399926757812504 +0.118875 -0.168182373046875 0.02399926757812504 +0.119 -0.169281005859375 0.02399926757812504 +0.119125 -0.173614501953125 0.02399926757812504 +0.11925 -0.171142578125 0.02399926757812504 +0.119375 -0.172027587890625 0.02399926757812504 +0.1195 -0.165863037109375 0.02399926757812504 +0.119625 -0.163055419921875 0.02399926757812504 +0.11975 -0.15325927734375 0.02399926757812504 +0.119875 -0.14178466796875 0.02399926757812504 +0.12 -0.133544921875 0.02399926757812504 +0.120125 -0.11883544921875 0.02399926757812504 +0.12025 -0.107177734375 0.02399926757812504 +0.120375 -0.0897216796875 0.02399926757812504 +0.1205 -0.07305908203125 0.02399926757812504 +0.120625 -0.05535888671875 0.02399926757812504 +0.12075 -0.035980224609375 0.02399926757812504 +0.120875 -0.0169677734375 0.02399926757812504 0.121 0.00433349609375 0.02399926757812504 0.121125 0.02606201171875 0.02399926757812504 0.12125 0.045379638671875 0.02399926757812504 @@ -998,37 +998,37 @@ 0.124625 0.0556640625 0.02399926757812504 0.12475 0.027984619140625 0.02399926757812504 0.124875 0.0 0.02399926757812504 -0.125 -0.025634765625 0.02399926757812504 -0.125125 -0.0546875 0.02399926757812504 -0.12525 -0.0799560546875 0.02399926757812504 -0.125375 -0.10888671875 0.02399926757812504 -0.1255 -0.1353759765625 0.02399926757812504 -0.125625 -0.157958984375 0.02399926757812504 -0.12575 -0.184173583984375 0.02399926757812504 -0.125875 -0.203857421875 0.02399926757812504 -0.126 -0.226959228515625 0.02399926757812504 -0.126125 -0.244537353515625 0.02399926757812504 -0.12625 -0.261810302734375 0.02399926757812504 -0.126375 -0.274322509765625 0.02399926757812504 -0.1265 -0.287078857421875 0.02399926757812504 -0.126625 -0.29388427734375 0.02399926757812504 -0.12675 -0.301666259765625 0.02399926757812504 -0.126875 -0.302093505859375 0.02399926757812504 -0.127 -0.3035888671875 0.02399926757812504 -0.127125 -0.298309326171875 0.02399926757812504 -0.12725 -0.28936767578125 0.02399926757812504 -0.127375 -0.280975341796875 0.02399926757812504 -0.1275 -0.26727294921875 0.02399926757812504 -0.127625 -0.2525634765625 0.02399926757812504 -0.12775 -0.233795166015625 0.02399926757812504 -0.127875 -0.213226318359375 0.02399926757812504 -0.128 -0.18731689453125 0.2799914550781251 -0.128125 -0.16424560546875 0.2799914550781251 -0.12825 -0.13433837890625 0.2799914550781251 -0.128375 -0.107421875 0.2799914550781251 -0.1285 -0.0745849609375 0.2799914550781251 -0.128625 -0.04144287109375 0.2799914550781251 -0.12875 -0.010498046875 0.2799914550781251 +0.125 -0.025604248046875 0.02399926757812504 +0.125125 -0.054656982421875 0.02399926757812504 +0.12525 -0.079925537109375 0.02399926757812504 +0.125375 -0.108856201171875 0.02399926757812504 +0.1255 -0.135345458984375 0.02399926757812504 +0.125625 -0.157928466796875 0.02399926757812504 +0.12575 -0.18414306640625 0.02399926757812504 +0.125875 -0.203826904296875 0.02399926757812504 +0.126 -0.2269287109375 0.02399926757812504 +0.126125 -0.2445068359375 0.02399926757812504 +0.12625 -0.26177978515625 0.02399926757812504 +0.126375 -0.2742919921875 0.02399926757812504 +0.1265 -0.28704833984375 0.02399926757812504 +0.126625 -0.293853759765625 0.02399926757812504 +0.12675 -0.3016357421875 0.02399926757812504 +0.126875 -0.30206298828125 0.02399926757812504 +0.127 -0.303558349609375 0.02399926757812504 +0.127125 -0.29827880859375 0.02399926757812504 +0.12725 -0.289337158203125 0.02399926757812504 +0.127375 -0.28094482421875 0.02399926757812504 +0.1275 -0.267242431640625 0.02399926757812504 +0.127625 -0.252532958984375 0.02399926757812504 +0.12775 -0.2337646484375 0.02399926757812504 +0.127875 -0.21319580078125 0.02399926757812504 +0.128 -0.187286376953125 0.2799914550781251 +0.128125 -0.164215087890625 0.2799914550781251 +0.12825 -0.134307861328125 0.2799914550781251 +0.128375 -0.107391357421875 0.2799914550781251 +0.1285 -0.074554443359375 0.2799914550781251 +0.128625 -0.041412353515625 0.2799914550781251 +0.12875 -0.010467529296875 0.2799914550781251 0.128875 0.02447509765625 0.2799914550781251 0.129 0.056396484375 0.2799914550781251 0.129125 0.090972900390625 0.2799914550781251 @@ -1060,37 +1060,37 @@ 0.132375 0.096588134765625 0.2799914550781251 0.1325 0.061248779296875 0.2799914550781251 0.132625 0.0206298828125 0.2799914550781251 -0.13275 -0.01654052734375 0.2799914550781251 -0.132875 -0.05816650390625 0.2799914550781251 -0.133 -0.099029541015625 0.2799914550781251 -0.133125 -0.135955810546875 0.2799914550781251 -0.13325 -0.1746826171875 0.2799914550781251 -0.133375 -0.20953369140625 0.2799914550781251 -0.1335 -0.244537353515625 0.2799914550781251 -0.133625 -0.278961181640625 0.2799914550781251 -0.13375 -0.3056640625 0.2799914550781251 -0.133875 -0.334625244140625 0.2799914550781251 -0.134 -0.35809326171875 0.2799914550781251 -0.134125 -0.37774658203125 0.2799914550781251 -0.13425 -0.396026611328125 0.2799914550781251 -0.134375 -0.4063720703125 0.2799914550781251 -0.1345 -0.41650390625 0.2799914550781251 -0.134625 -0.419189453125 0.2799914550781251 -0.13475 -0.420654296875 0.2799914550781251 -0.134875 -0.414642333984375 0.2799914550781251 -0.135 -0.40802001953125 0.2799914550781251 -0.135125 -0.393402099609375 0.2799914550781251 -0.13525 -0.37896728515625 0.2799914550781251 -0.135375 -0.3583984375 0.2799914550781251 -0.1355 -0.33154296875 0.2799914550781251 -0.135625 -0.30615234375 0.2799914550781251 -0.13575 -0.2724609375 0.2799914550781251 -0.135875 -0.24102783203125 0.2799914550781251 -0.136 -0.2017822265625 0.2799914550781251 -0.136125 -0.161285400390625 0.2799914550781251 -0.13625 -0.122222900390625 0.2799914550781251 -0.136375 -0.078033447265625 0.2799914550781251 -0.1365 -0.036865234375 0.2799914550781251 +0.13275 -0.016510009765625 0.2799914550781251 +0.132875 -0.058135986328125 0.2799914550781251 +0.133 -0.0989990234375 0.2799914550781251 +0.133125 -0.13592529296875 0.2799914550781251 +0.13325 -0.174652099609375 0.2799914550781251 +0.133375 -0.209503173828125 0.2799914550781251 +0.1335 -0.2445068359375 0.2799914550781251 +0.133625 -0.2789306640625 0.2799914550781251 +0.13375 -0.305633544921875 0.2799914550781251 +0.133875 -0.3345947265625 0.2799914550781251 +0.134 -0.358062744140625 0.2799914550781251 +0.134125 -0.377716064453125 0.2799914550781251 +0.13425 -0.39599609375 0.2799914550781251 +0.134375 -0.406341552734375 0.2799914550781251 +0.1345 -0.416473388671875 0.2799914550781251 +0.134625 -0.419158935546875 0.2799914550781251 +0.13475 -0.420623779296875 0.2799914550781251 +0.134875 -0.41461181640625 0.2799914550781251 +0.135 -0.407989501953125 0.2799914550781251 +0.135125 -0.39337158203125 0.2799914550781251 +0.13525 -0.378936767578125 0.2799914550781251 +0.135375 -0.358367919921875 0.2799914550781251 +0.1355 -0.331512451171875 0.2799914550781251 +0.135625 -0.306121826171875 0.2799914550781251 +0.13575 -0.272430419921875 0.2799914550781251 +0.135875 -0.240997314453125 0.2799914550781251 +0.136 -0.201751708984375 0.2799914550781251 +0.136125 -0.1612548828125 0.2799914550781251 +0.13625 -0.1221923828125 0.2799914550781251 +0.136375 -0.0780029296875 0.2799914550781251 +0.1365 -0.036834716796875 0.2799914550781251 0.136625 0.009246826171875 0.2799914550781251 0.13675 0.0557861328125 0.2799914550781251 0.136875 0.097137451171875 0.2799914550781251 @@ -1123,37 +1123,37 @@ 0.14025 0.09881591796875 0.2799914550781251 0.140375 0.0496826171875 0.2799914550781251 0.1405 0.0 0.2799914550781251 -0.140625 -0.044891357421875 0.2799914550781251 -0.14075 -0.0946044921875 0.2799914550781251 -0.140875 -0.138763427734375 0.2799914550781251 -0.141 -0.18603515625 0.2799914550781251 -0.141125 -0.231964111328125 0.2799914550781251 -0.14125 -0.2706298828125 0.2799914550781251 -0.141375 -0.311676025390625 0.2799914550781251 -0.1415 -0.34503173828125 0.2799914550781251 -0.141625 -0.379486083984375 0.2799914550781251 -0.14175 -0.408843994140625 0.2799914550781251 -0.141875 -0.432586669921875 0.2799914550781251 -0.142 -0.4532470703125 0.2799914550781251 -0.142125 -0.468780517578125 0.2799914550781251 -0.14225 -0.4810791015625 0.2799914550781251 -0.142375 -0.4869384765625 0.2799914550781251 -0.1425 -0.48876953125 0.2799914550781251 -0.142625 -0.484466552734375 0.2799914550781251 -0.14275 -0.477142333984375 0.2799914550781251 -0.142875 -0.46282958984375 0.2799914550781251 -0.143 -0.4443359375 0.2799914550781251 -0.143125 -0.422698974609375 0.2799914550781251 -0.14325 -0.39501953125 0.2799914550781251 -0.143375 -0.3663330078125 0.2799914550781251 -0.1435 -0.329833984375 0.2799914550781251 -0.143625 -0.29022216796875 0.2799914550781251 -0.14375 -0.2513427734375 0.2799914550781251 -0.143875 -0.205902099609375 0.2799914550781251 -0.144 -0.162628173828125 0.2799914550781251 -0.144125 -0.11309814453125 0.2799914550781251 -0.14425 -0.06207275390625 0.2799914550781251 -0.144375 -0.01556396484375 0.2799914550781251 +0.140625 -0.04486083984375 0.2799914550781251 +0.14075 -0.094573974609375 0.2799914550781251 +0.140875 -0.13873291015625 0.2799914550781251 +0.141 -0.186004638671875 0.2799914550781251 +0.141125 -0.23193359375 0.2799914550781251 +0.14125 -0.270599365234375 0.2799914550781251 +0.141375 -0.3116455078125 0.2799914550781251 +0.1415 -0.345001220703125 0.2799914550781251 +0.141625 -0.37945556640625 0.2799914550781251 +0.14175 -0.4088134765625 0.2799914550781251 +0.141875 -0.43255615234375 0.2799914550781251 +0.142 -0.453216552734375 0.2799914550781251 +0.142125 -0.46875 0.2799914550781251 +0.14225 -0.481048583984375 0.2799914550781251 +0.142375 -0.486907958984375 0.2799914550781251 +0.1425 -0.488739013671875 0.2799914550781251 +0.142625 -0.48443603515625 0.2799914550781251 +0.14275 -0.47711181640625 0.2799914550781251 +0.142875 -0.462799072265625 0.2799914550781251 +0.143 -0.444305419921875 0.2799914550781251 +0.143125 -0.42266845703125 0.2799914550781251 +0.14325 -0.394989013671875 0.2799914550781251 +0.143375 -0.366302490234375 0.2799914550781251 +0.1435 -0.329803466796875 0.2799914550781251 +0.143625 -0.290191650390625 0.2799914550781251 +0.14375 -0.251312255859375 0.2799914550781251 +0.143875 -0.20587158203125 0.2799914550781251 +0.144 -0.16259765625 0.2799914550781251 +0.144125 -0.113067626953125 0.2799914550781251 +0.14425 -0.062042236328125 0.2799914550781251 +0.144375 -0.015533447265625 0.2799914550781251 0.1445 0.036285400390625 0.2799914550781251 0.144625 0.082794189453125 0.2799914550781251 0.14475 0.1336669921875 0.2799914550781251 @@ -1185,37 +1185,37 @@ 0.148 0.124176025390625 0.2799914550781251 0.148125 0.078094482421875 0.2799914550781251 0.14825 0.026092529296875 0.2799914550781251 -0.148375 -0.020904541015625 0.2799914550781251 -0.1485 -0.0728759765625 0.2799914550781251 -0.148625 -0.12408447265625 0.2799914550781251 -0.14875 -0.16888427734375 0.2799914550781251 -0.148875 -0.216827392578125 0.2799914550781251 -0.149 -0.258056640625 0.2799914550781251 -0.149125 -0.3009033203125 0.2799914550781251 -0.14925 -0.3406982421875 0.2799914550781251 -0.149375 -0.372955322265625 0.2799914550781251 -0.1495 -0.4052734375 0.2799914550781251 -0.149625 -0.430084228515625 0.2799914550781251 -0.14975 -0.45367431640625 0.2799914550781251 -0.149875 -0.471710205078125 0.2799914550781251 -0.15 -0.484039306640625 0.2799914550781251 -0.150125 -0.492034912109375 0.2799914550781251 -0.15025 -0.494476318359375 0.2799914550781251 -0.150375 -0.49285888671875 0.2799914550781251 -0.1505 -0.48504638671875 0.2799914550781251 -0.150625 -0.47418212890625 0.2799914550781251 -0.15075 -0.4564208984375 0.2799914550781251 -0.150875 -0.436859130859375 0.2799914550781251 -0.151 -0.409820556640625 0.2799914550781251 -0.151125 -0.379119873046875 0.2799914550781251 -0.15125 -0.34722900390625 0.2799914550781251 -0.151375 -0.30902099609375 0.2799914550781251 -0.1515 -0.27117919921875 0.2799914550781251 -0.151625 -0.2265625 0.2799914550781251 -0.15175 -0.180023193359375 0.2799914550781251 -0.151875 -0.1361083984375 0.2799914550781251 -0.152 -0.086395263671875 0.2799914550781251 -0.152125 -0.04071044921875 0.2799914550781251 +0.148375 -0.0208740234375 0.2799914550781251 +0.1485 -0.072845458984375 0.2799914550781251 +0.148625 -0.124053955078125 0.2799914550781251 +0.14875 -0.168853759765625 0.2799914550781251 +0.148875 -0.216796875 0.2799914550781251 +0.149 -0.258026123046875 0.2799914550781251 +0.149125 -0.300872802734375 0.2799914550781251 +0.14925 -0.340667724609375 0.2799914550781251 +0.149375 -0.3729248046875 0.2799914550781251 +0.1495 -0.405242919921875 0.2799914550781251 +0.149625 -0.4300537109375 0.2799914550781251 +0.14975 -0.453643798828125 0.2799914550781251 +0.149875 -0.4716796875 0.2799914550781251 +0.15 -0.4840087890625 0.2799914550781251 +0.150125 -0.49200439453125 0.2799914550781251 +0.15025 -0.49444580078125 0.2799914550781251 +0.150375 -0.492828369140625 0.2799914550781251 +0.1505 -0.485015869140625 0.2799914550781251 +0.150625 -0.474151611328125 0.2799914550781251 +0.15075 -0.456390380859375 0.2799914550781251 +0.150875 -0.43682861328125 0.2799914550781251 +0.151 -0.4097900390625 0.2799914550781251 +0.151125 -0.37908935546875 0.2799914550781251 +0.15125 -0.347198486328125 0.2799914550781251 +0.151375 -0.308990478515625 0.2799914550781251 +0.1515 -0.271148681640625 0.2799914550781251 +0.151625 -0.226531982421875 0.2799914550781251 +0.15175 -0.17999267578125 0.2799914550781251 +0.151875 -0.136077880859375 0.2799914550781251 +0.152 -0.08636474609375 0.2799914550781251 +0.152125 -0.040679931640625 0.2799914550781251 0.15225 0.010162353515625 0.2799914550781251 0.152375 0.060821533203125 0.2799914550781251 0.1525 0.105865478515625 0.2799914550781251 @@ -1248,37 +1248,37 @@ 0.155875 0.095794677734375 0.2799914550781251 0.156 0.047943115234375 0.2799914550781251 0.156125 0.0 0.2799914550781251 -0.15625 -0.04296875 0.2799914550781251 -0.156375 -0.09027099609375 0.2799914550781251 -0.1565 -0.131378173828125 0.2799914550781251 -0.156625 -0.1761474609375 0.2799914550781251 -0.15675 -0.217926025390625 0.2799914550781251 -0.156875 -0.25299072265625 0.2799914550781251 -0.157 -0.290496826171875 0.2799914550781251 -0.157125 -0.3199462890625 0.2799914550781251 -0.15725 -0.350921630859375 0.2799914550781251 -0.157375 -0.3760986328125 0.2799914550781251 -0.1575 -0.396881103515625 0.2799914550781251 -0.157625 -0.413604736328125 0.2799914550781251 -0.15775 -0.426727294921875 0.2799914550781251 -0.157875 -0.434417724609375 0.2799914550781251 -0.158 -0.439727783203125 0.2799914550781251 -0.158125 -0.4378662109375 0.2799914550781251 -0.15825 -0.4315185546875 0.2799914550781251 -0.158375 -0.424041748046875 0.2799914550781251 -0.1585 -0.40887451171875 0.2799914550781251 -0.158625 -0.391754150390625 0.2799914550781251 -0.15875 -0.370361328125 0.2799914550781251 -0.158875 -0.345458984375 0.2799914550781251 -0.159 -0.317779541015625 0.2799914550781251 -0.159125 -0.2861328125 0.2799914550781251 -0.15925 -0.249755859375 0.2799914550781251 -0.159375 -0.216278076171875 0.2799914550781251 -0.1595 -0.17572021484375 0.2799914550781251 -0.159625 -0.13787841796875 0.2799914550781251 -0.15975 -0.095733642578125 0.2799914550781251 -0.159875 -0.05218505859375 0.2799914550781251 -0.16 -0.013092041015625 0.535983642578125 +0.15625 -0.042938232421875 0.2799914550781251 +0.156375 -0.090240478515625 0.2799914550781251 +0.1565 -0.13134765625 0.2799914550781251 +0.156625 -0.176116943359375 0.2799914550781251 +0.15675 -0.2178955078125 0.2799914550781251 +0.156875 -0.252960205078125 0.2799914550781251 +0.157 -0.29046630859375 0.2799914550781251 +0.157125 -0.319915771484375 0.2799914550781251 +0.15725 -0.35089111328125 0.2799914550781251 +0.157375 -0.376068115234375 0.2799914550781251 +0.1575 -0.3968505859375 0.2799914550781251 +0.157625 -0.41357421875 0.2799914550781251 +0.15775 -0.42669677734375 0.2799914550781251 +0.157875 -0.43438720703125 0.2799914550781251 +0.158 -0.439697265625 0.2799914550781251 +0.158125 -0.437835693359375 0.2799914550781251 +0.15825 -0.431488037109375 0.2799914550781251 +0.158375 -0.42401123046875 0.2799914550781251 +0.1585 -0.408843994140625 0.2799914550781251 +0.158625 -0.3917236328125 0.2799914550781251 +0.15875 -0.370330810546875 0.2799914550781251 +0.158875 -0.345428466796875 0.2799914550781251 +0.159 -0.3177490234375 0.2799914550781251 +0.159125 -0.286102294921875 0.2799914550781251 +0.15925 -0.249725341796875 0.2799914550781251 +0.159375 -0.21624755859375 0.2799914550781251 +0.1595 -0.175689697265625 0.2799914550781251 +0.159625 -0.137847900390625 0.2799914550781251 +0.15975 -0.095703125 0.2799914550781251 +0.159875 -0.052154541015625 0.2799914550781251 +0.16 -0.0130615234375 0.535983642578125 0.160125 0.030242919921875 0.535983642578125 0.16025 0.06842041015625 0.535983642578125 0.160375 0.1103515625 0.535983642578125 @@ -1310,37 +1310,37 @@ 0.163625 0.087890625 0.535983642578125 0.16375 0.0546875 0.535983642578125 0.163875 0.01806640625 0.535983642578125 -0.164 -0.014495849609375 0.535983642578125 -0.164125 -0.04998779296875 0.535983642578125 -0.16425 -0.084136962890625 0.535983642578125 -0.164375 -0.1146240234375 0.535983642578125 -0.1645 -0.145599365234375 0.535983642578125 -0.164625 -0.173309326171875 0.535983642578125 -0.16475 -0.19989013671875 0.535983642578125 -0.164875 -0.2236328125 0.535983642578125 -0.165 -0.245025634765625 0.535983642578125 -0.165125 -0.263031005859375 0.535983642578125 -0.16525 -0.275970458984375 0.535983642578125 -0.165375 -0.291107177734375 0.535983642578125 -0.1655 -0.299224853515625 0.535983642578125 -0.165625 -0.30303955078125 0.535983642578125 -0.16575 -0.3084716796875 0.535983642578125 -0.165875 -0.30633544921875 0.535983642578125 -0.166 -0.301177978515625 0.535983642578125 -0.166125 -0.296905517578125 0.535983642578125 -0.16625 -0.286224365234375 0.535983642578125 -0.166375 -0.272064208984375 0.535983642578125 -0.1665 -0.260406494140625 0.535983642578125 -0.166625 -0.241241455078125 0.535983642578125 -0.16675 -0.2198486328125 0.535983642578125 -0.166875 -0.201751708984375 0.535983642578125 -0.167 -0.176849365234375 0.535983642578125 -0.167125 -0.153106689453125 0.535983642578125 -0.16725 -0.128173828125 0.535983642578125 -0.167375 -0.100250244140625 0.535983642578125 -0.1675 -0.075958251953125 0.535983642578125 -0.167625 -0.04742431640625 0.535983642578125 -0.16775 -0.02203369140625 0.535983642578125 +0.164 -0.01446533203125 0.535983642578125 +0.164125 -0.049957275390625 0.535983642578125 +0.16425 -0.0841064453125 0.535983642578125 +0.164375 -0.114593505859375 0.535983642578125 +0.1645 -0.14556884765625 0.535983642578125 +0.164625 -0.17327880859375 0.535983642578125 +0.16475 -0.199859619140625 0.535983642578125 +0.164875 -0.223602294921875 0.535983642578125 +0.165 -0.2449951171875 0.535983642578125 +0.165125 -0.26300048828125 0.535983642578125 +0.16525 -0.27593994140625 0.535983642578125 +0.165375 -0.29107666015625 0.535983642578125 +0.1655 -0.2991943359375 0.535983642578125 +0.165625 -0.303009033203125 0.535983642578125 +0.16575 -0.308441162109375 0.535983642578125 +0.165875 -0.306304931640625 0.535983642578125 +0.166 -0.3011474609375 0.535983642578125 +0.166125 -0.296875 0.535983642578125 +0.16625 -0.28619384765625 0.535983642578125 +0.166375 -0.27203369140625 0.535983642578125 +0.1665 -0.2603759765625 0.535983642578125 +0.166625 -0.2412109375 0.535983642578125 +0.16675 -0.219818115234375 0.535983642578125 +0.166875 -0.20172119140625 0.535983642578125 +0.167 -0.17681884765625 0.535983642578125 +0.167125 -0.153076171875 0.535983642578125 +0.16725 -0.128143310546875 0.535983642578125 +0.167375 -0.1002197265625 0.535983642578125 +0.1675 -0.075927734375 0.535983642578125 +0.167625 -0.047393798828125 0.535983642578125 +0.16775 -0.022003173828125 0.535983642578125 0.167875 0.0054931640625 0.535983642578125 0.168 0.03240966796875 0.535983642578125 0.168125 0.05548095703125 0.535983642578125 @@ -1373,37 +1373,37 @@ 0.1715 0.03619384765625 0.535983642578125 0.171625 0.017669677734375 0.535983642578125 0.17175 0.0 0.535983642578125 -0.171875 -0.015472412109375 0.535983642578125 -0.172 -0.031524658203125 0.535983642578125 -0.172125 -0.044647216796875 0.535983642578125 -0.17225 -0.05987548828125 0.535983642578125 -0.172375 -0.072021484375 0.535983642578125 -0.1725 -0.081207275390625 0.535983642578125 -0.172625 -0.09326171875 0.535983642578125 -0.17275 -0.099639892578125 0.535983642578125 -0.172875 -0.1053466796875 0.535983642578125 -0.173 -0.113525390625 0.535983642578125 -0.173125 -0.11529541015625 0.535983642578125 -0.17325 -0.12078857421875 0.535983642578125 -0.173375 -0.1197509765625 0.535983642578125 -0.1735 -0.117584228515625 0.535983642578125 -0.173625 -0.1190185546875 0.535983642578125 -0.17375 -0.114105224609375 0.535983642578125 -0.173875 -0.1080322265625 0.535983642578125 -0.174 -0.106170654296875 0.535983642578125 -0.174125 -0.09814453125 0.535983642578125 -0.17425 -0.08941650390625 0.535983642578125 -0.174375 -0.085052490234375 0.535983642578125 -0.1745 -0.0751953125 0.535983642578125 -0.174625 -0.0657958984375 0.535983642578125 -0.17475 -0.059234619140625 0.535983642578125 -0.174875 -0.04901123046875 0.535983642578125 -0.175 -0.039794921875 0.535983642578125 -0.175125 -0.032562255859375 0.535983642578125 -0.17525 -0.024017333984375 0.535983642578125 -0.175375 -0.0155029296875 0.535983642578125 -0.1755 -0.008514404296875 0.535983642578125 -0.175625 -0.001953125 0.535983642578125 +0.171875 -0.01544189453125 0.535983642578125 +0.172 -0.031494140625 0.535983642578125 +0.172125 -0.04461669921875 0.535983642578125 +0.17225 -0.059844970703125 0.535983642578125 +0.172375 -0.071990966796875 0.535983642578125 +0.1725 -0.0811767578125 0.535983642578125 +0.172625 -0.093231201171875 0.535983642578125 +0.17275 -0.099609375 0.535983642578125 +0.172875 -0.105316162109375 0.535983642578125 +0.173 -0.113494873046875 0.535983642578125 +0.173125 -0.115264892578125 0.535983642578125 +0.17325 -0.120758056640625 0.535983642578125 +0.173375 -0.119720458984375 0.535983642578125 +0.1735 -0.1175537109375 0.535983642578125 +0.173625 -0.118988037109375 0.535983642578125 +0.17375 -0.11407470703125 0.535983642578125 +0.173875 -0.108001708984375 0.535983642578125 +0.174 -0.10614013671875 0.535983642578125 +0.174125 -0.098114013671875 0.535983642578125 +0.17425 -0.089385986328125 0.535983642578125 +0.174375 -0.08502197265625 0.535983642578125 +0.1745 -0.075164794921875 0.535983642578125 +0.174625 -0.065765380859375 0.535983642578125 +0.17475 -0.0592041015625 0.535983642578125 +0.174875 -0.048980712890625 0.535983642578125 +0.175 -0.039764404296875 0.535983642578125 +0.175125 -0.03253173828125 0.535983642578125 +0.17525 -0.02398681640625 0.535983642578125 +0.175375 -0.015472412109375 0.535983642578125 +0.1755 -0.00848388671875 0.535983642578125 +0.175625 -0.001922607421875 0.535983642578125 0.17575 0.004180908203125 0.535983642578125 0.175875 0.009552001953125 0.535983642578125 0.176 0.014007568359375 0.535983642578125 @@ -1423,18 +1423,18 @@ 0.17775 0.00518798828125 0.535983642578125 0.177875 0.0 0.535983642578125 0.178 0.0 0.535983642578125 -0.178125 -0.004791259765625 0.535983642578125 -0.17825 -0.009124755859375 0.535983642578125 -0.178375 -0.00860595703125 0.535983642578125 -0.1785 -0.011871337890625 0.535983642578125 -0.178625 -0.01434326171875 0.535983642578125 -0.17875 -0.0128173828125 0.535983642578125 -0.178875 -0.0137939453125 0.535983642578125 -0.179 -0.013946533203125 0.535983642578125 -0.179125 -0.01092529296875 0.535983642578125 -0.17925 -0.00909423828125 0.535983642578125 -0.179375 -0.0057373046875 0.535983642578125 -0.1795 -0.002197265625 0.535983642578125 +0.178125 -0.0047607421875 0.535983642578125 +0.17825 -0.00909423828125 0.535983642578125 +0.178375 -0.008575439453125 0.535983642578125 +0.1785 -0.0118408203125 0.535983642578125 +0.178625 -0.014312744140625 0.535983642578125 +0.17875 -0.012786865234375 0.535983642578125 +0.178875 -0.013763427734375 0.535983642578125 +0.179 -0.013916015625 0.535983642578125 +0.179125 -0.010894775390625 0.535983642578125 +0.17925 -0.009063720703125 0.535983642578125 +0.179375 -0.005706787109375 0.535983642578125 +0.1795 -0.002166748046875 0.535983642578125 0.179625 0.001953125 0.535983642578125 0.17975 0.0068359375 0.535983642578125 0.179875 0.012969970703125 0.535983642578125 @@ -1466,37 +1466,37 @@ 0.183125 0.03887939453125 0.535983642578125 0.18325 0.025543212890625 0.535983642578125 0.183375 0.012054443359375 0.535983642578125 -0.1835 -0.003143310546875 0.535983642578125 -0.183625 -0.01934814453125 0.535983642578125 -0.18375 -0.03369140625 0.535983642578125 -0.183875 -0.050872802734375 0.535983642578125 -0.184 -0.066864013671875 0.535983642578125 -0.184125 -0.08221435546875 0.535983642578125 -0.18425 -0.09954833984375 0.535983642578125 -0.184375 -0.115234375 0.535983642578125 -0.1845 -0.128265380859375 0.535983642578125 -0.184625 -0.1427001953125 0.535983642578125 -0.18475 -0.15740966796875 0.535983642578125 -0.184875 -0.166534423828125 0.535983642578125 -0.185 -0.177734375 0.535983642578125 -0.185125 -0.188140869140625 0.535983642578125 -0.18525 -0.191650390625 0.535983642578125 -0.185375 -0.198394775390625 0.535983642578125 -0.1855 -0.198150634765625 0.535983642578125 -0.185625 -0.200836181640625 0.535983642578125 -0.18575 -0.201019287109375 0.535983642578125 -0.185875 -0.195068359375 0.535983642578125 -0.186 -0.190673828125 0.535983642578125 -0.186125 -0.1837158203125 0.535983642578125 -0.18625 -0.17193603515625 0.535983642578125 -0.186375 -0.160430908203125 0.535983642578125 -0.1865 -0.1483154296875 0.535983642578125 -0.186625 -0.1295166015625 0.535983642578125 -0.18675 -0.111572265625 0.535983642578125 -0.186875 -0.093841552734375 0.535983642578125 -0.187 -0.070648193359375 0.535983642578125 -0.187125 -0.050079345703125 0.535983642578125 -0.18725 -0.025665283203125 0.535983642578125 +0.1835 -0.00311279296875 0.535983642578125 +0.183625 -0.019317626953125 0.535983642578125 +0.18375 -0.033660888671875 0.535983642578125 +0.183875 -0.05084228515625 0.535983642578125 +0.184 -0.06683349609375 0.535983642578125 +0.184125 -0.082183837890625 0.535983642578125 +0.18425 -0.099517822265625 0.535983642578125 +0.184375 -0.115203857421875 0.535983642578125 +0.1845 -0.12823486328125 0.535983642578125 +0.184625 -0.142669677734375 0.535983642578125 +0.18475 -0.157379150390625 0.535983642578125 +0.184875 -0.16650390625 0.535983642578125 +0.185 -0.177703857421875 0.535983642578125 +0.185125 -0.1881103515625 0.535983642578125 +0.18525 -0.191619873046875 0.535983642578125 +0.185375 -0.1983642578125 0.535983642578125 +0.1855 -0.1981201171875 0.535983642578125 +0.185625 -0.2008056640625 0.535983642578125 +0.18575 -0.20098876953125 0.535983642578125 +0.185875 -0.195037841796875 0.535983642578125 +0.186 -0.190643310546875 0.535983642578125 +0.186125 -0.183685302734375 0.535983642578125 +0.18625 -0.171905517578125 0.535983642578125 +0.186375 -0.160400390625 0.535983642578125 +0.1865 -0.148284912109375 0.535983642578125 +0.186625 -0.129486083984375 0.535983642578125 +0.18675 -0.111541748046875 0.535983642578125 +0.186875 -0.09381103515625 0.535983642578125 +0.187 -0.07061767578125 0.535983642578125 +0.187125 -0.050048828125 0.535983642578125 +0.18725 -0.025634765625 0.535983642578125 0.187375 0.0 0.535983642578125 0.1875 0.02349853515625 0.535983642578125 0.187625 0.050262451171875 0.535983642578125 @@ -1529,37 +1529,37 @@ 0.191 0.074554443359375 0.535983642578125 0.191125 0.041412353515625 0.535983642578125 0.19125 0.010345458984375 0.535983642578125 -0.191375 -0.024505615234375 0.535983642578125 -0.1915 -0.056427001953125 0.535983642578125 -0.191625 -0.09100341796875 0.535983642578125 -0.19175 -0.1259765625 0.535983642578125 -0.191875 -0.1571044921875 0.535983642578125 -0.192 -0.190521240234375 0.791975830078125 -0.192125 -0.21728515625 0.791975830078125 -0.19225 -0.247344970703125 0.791975830078125 -0.192375 -0.27520751953125 0.791975830078125 -0.1925 -0.298431396484375 0.791975830078125 -0.192625 -0.3179931640625 0.791975830078125 -0.19275 -0.335968017578125 0.791975830078125 -0.192875 -0.352294921875 0.791975830078125 -0.193 -0.36492919921875 0.791975830078125 -0.193125 -0.373321533203125 0.791975830078125 -0.19325 -0.374969482421875 0.791975830078125 -0.193375 -0.376373291015625 0.791975830078125 -0.1935 -0.373504638671875 0.791975830078125 -0.193625 -0.366363525390625 0.791975830078125 -0.19375 -0.353515625 0.791975830078125 -0.193875 -0.338470458984375 0.791975830078125 -0.194 -0.32171630859375 0.791975830078125 -0.194125 -0.299041748046875 0.791975830078125 -0.19425 -0.2725830078125 0.791975830078125 -0.194375 -0.24407958984375 0.791975830078125 -0.1945 -0.21148681640625 0.791975830078125 -0.194625 -0.179840087890625 0.791975830078125 -0.19475 -0.142059326171875 0.791975830078125 -0.194875 -0.101348876953125 0.791975830078125 -0.195 -0.064208984375 0.791975830078125 -0.195125 -0.021636962890625 0.791975830078125 +0.191375 -0.02447509765625 0.535983642578125 +0.1915 -0.056396484375 0.535983642578125 +0.191625 -0.090972900390625 0.535983642578125 +0.19175 -0.125946044921875 0.535983642578125 +0.191875 -0.157073974609375 0.535983642578125 +0.192 -0.19049072265625 0.791975830078125 +0.192125 -0.217254638671875 0.791975830078125 +0.19225 -0.247314453125 0.791975830078125 +0.192375 -0.275177001953125 0.791975830078125 +0.1925 -0.29840087890625 0.791975830078125 +0.192625 -0.317962646484375 0.791975830078125 +0.19275 -0.3359375 0.791975830078125 +0.192875 -0.352264404296875 0.791975830078125 +0.193 -0.364898681640625 0.791975830078125 +0.193125 -0.373291015625 0.791975830078125 +0.19325 -0.37493896484375 0.791975830078125 +0.193375 -0.3763427734375 0.791975830078125 +0.1935 -0.37347412109375 0.791975830078125 +0.193625 -0.3663330078125 0.791975830078125 +0.19375 -0.353485107421875 0.791975830078125 +0.193875 -0.33843994140625 0.791975830078125 +0.194 -0.321685791015625 0.791975830078125 +0.194125 -0.29901123046875 0.791975830078125 +0.19425 -0.272552490234375 0.791975830078125 +0.194375 -0.244049072265625 0.791975830078125 +0.1945 -0.211456298828125 0.791975830078125 +0.194625 -0.1798095703125 0.791975830078125 +0.19475 -0.14202880859375 0.791975830078125 +0.194875 -0.101318359375 0.791975830078125 +0.195 -0.064178466796875 0.791975830078125 +0.195125 -0.0216064453125 0.791975830078125 0.19525 0.01739501953125 0.791975830078125 0.195375 0.06121826171875 0.791975830078125 0.1955 0.104248046875 0.791975830078125 @@ -1591,37 +1591,37 @@ 0.19875 0.130706787109375 0.791975830078125 0.198875 0.08294677734375 0.791975830078125 0.199 0.039306640625 0.791975830078125 -0.199125 -0.0098876953125 0.791975830078125 -0.19925 -0.05938720703125 0.791975830078125 -0.199375 -0.10369873046875 0.791975830078125 -0.1995 -0.15167236328125 0.791975830078125 -0.199625 -0.19403076171875 0.791975830078125 -0.19975 -0.23931884765625 0.791975830078125 -0.199875 -0.28216552734375 0.791975830078125 -0.2 -0.317474365234375 0.791975830078125 -0.200125 -0.35443115234375 0.791975830078125 -0.20025 -0.3846435546875 0.791975830078125 -0.200375 -0.4141845703125 0.791975830078125 -0.2005 -0.439300537109375 0.791975830078125 -0.200625 -0.456817626953125 0.791975830078125 -0.20075 -0.472686767578125 0.791975830078125 -0.200875 -0.482666015625 0.791975830078125 -0.201 -0.48858642578125 0.791975830078125 -0.201125 -0.488037109375 0.791975830078125 -0.20125 -0.484039306640625 0.791975830078125 -0.201375 -0.474334716796875 0.791975830078125 -0.2015 -0.461181640625 0.791975830078125 -0.201625 -0.4415283203125 0.791975830078125 -0.20175 -0.41619873046875 0.791975830078125 -0.201875 -0.390167236328125 0.791975830078125 -0.202 -0.356964111328125 0.791975830078125 -0.202125 -0.323638916015625 0.791975830078125 -0.20225 -0.28265380859375 0.791975830078125 -0.202375 -0.23895263671875 0.791975830078125 -0.2025 -0.197235107421875 0.791975830078125 -0.202625 -0.148681640625 0.791975830078125 -0.20275 -0.103485107421875 0.791975830078125 -0.202875 -0.052032470703125 0.791975830078125 +0.199125 -0.009857177734375 0.791975830078125 +0.19925 -0.059356689453125 0.791975830078125 +0.199375 -0.103668212890625 0.791975830078125 +0.1995 -0.151641845703125 0.791975830078125 +0.199625 -0.194000244140625 0.791975830078125 +0.19975 -0.239288330078125 0.791975830078125 +0.199875 -0.282135009765625 0.791975830078125 +0.2 -0.31744384765625 0.791975830078125 +0.200125 -0.354400634765625 0.791975830078125 +0.20025 -0.384613037109375 0.791975830078125 +0.200375 -0.414154052734375 0.791975830078125 +0.2005 -0.43927001953125 0.791975830078125 +0.200625 -0.456787109375 0.791975830078125 +0.20075 -0.47265625 0.791975830078125 +0.200875 -0.482635498046875 0.791975830078125 +0.201 -0.488555908203125 0.791975830078125 +0.201125 -0.488006591796875 0.791975830078125 +0.20125 -0.4840087890625 0.791975830078125 +0.201375 -0.47430419921875 0.791975830078125 +0.2015 -0.461151123046875 0.791975830078125 +0.201625 -0.441497802734375 0.791975830078125 +0.20175 -0.416168212890625 0.791975830078125 +0.201875 -0.39013671875 0.791975830078125 +0.202 -0.35693359375 0.791975830078125 +0.202125 -0.3236083984375 0.791975830078125 +0.20225 -0.282623291015625 0.791975830078125 +0.202375 -0.238922119140625 0.791975830078125 +0.2025 -0.19720458984375 0.791975830078125 +0.202625 -0.148651123046875 0.791975830078125 +0.20275 -0.10345458984375 0.791975830078125 +0.202875 -0.052001953125 0.791975830078125 0.203 0.0 0.791975830078125 0.203125 0.046875 0.791975830078125 0.20325 0.09857177734375 0.791975830078125 @@ -1654,37 +1654,37 @@ 0.206625 0.11273193359375 0.791975830078125 0.20675 0.061737060546875 0.791975830078125 0.206875 0.01544189453125 0.791975830078125 -0.207 -0.036041259765625 0.791975830078125 -0.207125 -0.081878662109375 0.791975830078125 -0.20725 -0.13177490234375 0.791975830078125 -0.207375 -0.180419921875 0.791975830078125 -0.2075 -0.222015380859375 0.791975830078125 -0.207625 -0.265716552734375 0.791975830078125 -0.20775 -0.302337646484375 0.791975830078125 -0.207875 -0.339691162109375 0.791975830078125 -0.208 -0.37408447265625 0.791975830078125 -0.208125 -0.400482177734375 0.791975830078125 -0.20825 -0.425567626953125 0.791975830078125 -0.208375 -0.443878173828125 0.791975830078125 -0.2085 -0.460968017578125 0.791975830078125 -0.208625 -0.471588134765625 0.791975830078125 -0.20875 -0.476470947265625 0.791975830078125 -0.208875 -0.47705078125 0.791975830078125 -0.209 -0.472869873046875 0.791975830078125 -0.209125 -0.465087890625 0.791975830078125 -0.20925 -0.45062255859375 0.791975830078125 -0.209375 -0.433319091796875 0.791975830078125 -0.2095 -0.4097900390625 0.791975830078125 -0.209625 -0.38623046875 0.791975830078125 -0.20975 -0.354705810546875 0.791975830078125 -0.209875 -0.319488525390625 0.791975830078125 -0.21 -0.284881591796875 0.791975830078125 -0.210125 -0.243927001953125 0.791975830078125 -0.21025 -0.205810546875 0.791975830078125 -0.210375 -0.16064453125 0.791975830078125 -0.2105 -0.114105224609375 0.791975830078125 -0.210625 -0.071441650390625 0.791975830078125 -0.21075 -0.023895263671875 0.791975830078125 +0.207 -0.0360107421875 0.791975830078125 +0.207125 -0.08184814453125 0.791975830078125 +0.20725 -0.131744384765625 0.791975830078125 +0.207375 -0.180389404296875 0.791975830078125 +0.2075 -0.22198486328125 0.791975830078125 +0.207625 -0.26568603515625 0.791975830078125 +0.20775 -0.30230712890625 0.791975830078125 +0.207875 -0.33966064453125 0.791975830078125 +0.208 -0.374053955078125 0.791975830078125 +0.208125 -0.40045166015625 0.791975830078125 +0.20825 -0.425537109375 0.791975830078125 +0.208375 -0.44384765625 0.791975830078125 +0.2085 -0.4609375 0.791975830078125 +0.208625 -0.4715576171875 0.791975830078125 +0.20875 -0.4764404296875 0.791975830078125 +0.208875 -0.477020263671875 0.791975830078125 +0.209 -0.47283935546875 0.791975830078125 +0.209125 -0.465057373046875 0.791975830078125 +0.20925 -0.450592041015625 0.791975830078125 +0.209375 -0.43328857421875 0.791975830078125 +0.2095 -0.409759521484375 0.791975830078125 +0.209625 -0.386199951171875 0.791975830078125 +0.20975 -0.35467529296875 0.791975830078125 +0.209875 -0.3194580078125 0.791975830078125 +0.21 -0.28485107421875 0.791975830078125 +0.210125 -0.243896484375 0.791975830078125 +0.21025 -0.205780029296875 0.791975830078125 +0.210375 -0.160614013671875 0.791975830078125 +0.2105 -0.11407470703125 0.791975830078125 +0.210625 -0.0714111328125 0.791975830078125 +0.21075 -0.02386474609375 0.791975830078125 0.210875 0.019012451171875 0.791975830078125 0.211 0.0660400390625 0.791975830078125 0.211125 0.111907958984375 0.791975830078125 @@ -1716,37 +1716,37 @@ 0.214375 0.11016845703125 0.791975830078125 0.2145 0.0693359375 0.791975830078125 0.214625 0.032470703125 0.791975830078125 -0.21475 -0.008148193359375 0.791975830078125 -0.214875 -0.04827880859375 0.791975830078125 -0.215 -0.083282470703125 0.791975830078125 -0.215125 -0.120697021484375 0.791975830078125 -0.21525 -0.15252685546875 0.791975830078125 -0.215375 -0.1875 0.791975830078125 -0.2155 -0.2183837890625 0.791975830078125 -0.215625 -0.243377685546875 0.791975830078125 -0.21575 -0.26824951171875 0.791975830078125 -0.215875 -0.290283203125 0.791975830078125 -0.216 -0.308624267578125 0.791975830078125 -0.216125 -0.32318115234375 0.791975830078125 -0.21625 -0.332611083984375 0.791975830078125 -0.216375 -0.339691162109375 0.791975830078125 -0.2165 -0.346038818359375 0.791975830078125 -0.216625 -0.345733642578125 0.791975830078125 -0.21675 -0.341552734375 0.791975830078125 -0.216875 -0.334228515625 0.791975830078125 -0.217 -0.326873779296875 0.791975830078125 -0.217125 -0.31353759765625 0.791975830078125 -0.21725 -0.296142578125 0.791975830078125 -0.217375 -0.27581787109375 0.791975830078125 -0.2175 -0.254974365234375 0.791975830078125 -0.217625 -0.23291015625 0.791975830078125 -0.21775 -0.208221435546875 0.791975830078125 -0.217875 -0.1795654296875 0.791975830078125 -0.218 -0.14959716796875 0.791975830078125 -0.218125 -0.123321533203125 0.791975830078125 -0.21825 -0.091644287109375 0.791975830078125 -0.218375 -0.062835693359375 0.791975830078125 -0.2185 -0.031158447265625 0.791975830078125 +0.21475 -0.00811767578125 0.791975830078125 +0.214875 -0.048248291015625 0.791975830078125 +0.215 -0.083251953125 0.791975830078125 +0.215125 -0.12066650390625 0.791975830078125 +0.21525 -0.152496337890625 0.791975830078125 +0.215375 -0.187469482421875 0.791975830078125 +0.2155 -0.218353271484375 0.791975830078125 +0.215625 -0.24334716796875 0.791975830078125 +0.21575 -0.268218994140625 0.791975830078125 +0.215875 -0.290252685546875 0.791975830078125 +0.216 -0.30859375 0.791975830078125 +0.216125 -0.323150634765625 0.791975830078125 +0.21625 -0.33258056640625 0.791975830078125 +0.216375 -0.33966064453125 0.791975830078125 +0.2165 -0.34600830078125 0.791975830078125 +0.216625 -0.345703125 0.791975830078125 +0.21675 -0.341522216796875 0.791975830078125 +0.216875 -0.334197998046875 0.791975830078125 +0.217 -0.32684326171875 0.791975830078125 +0.217125 -0.313507080078125 0.791975830078125 +0.21725 -0.296112060546875 0.791975830078125 +0.217375 -0.275787353515625 0.791975830078125 +0.2175 -0.25494384765625 0.791975830078125 +0.217625 -0.232879638671875 0.791975830078125 +0.21775 -0.20819091796875 0.791975830078125 +0.217875 -0.179534912109375 0.791975830078125 +0.218 -0.149566650390625 0.791975830078125 +0.218125 -0.123291015625 0.791975830078125 +0.21825 -0.09161376953125 0.791975830078125 +0.218375 -0.06280517578125 0.791975830078125 +0.2185 -0.0311279296875 0.791975830078125 0.218625 0.0 0.791975830078125 0.21875 0.027618408203125 0.791975830078125 0.218875 0.057220458984375 0.791975830078125 @@ -1779,37 +1779,37 @@ 0.22225 0.044219970703125 0.791975830078125 0.222375 0.023651123046875 0.791975830078125 0.2225 0.0057373046875 0.791975830078125 -0.222625 -0.01348876953125 0.791975830078125 -0.22275 -0.029876708984375 0.791975830078125 -0.222875 -0.046844482421875 0.791975830078125 -0.223 -0.062347412109375 0.791975830078125 -0.223125 -0.07464599609375 0.791975830078125 -0.22325 -0.08953857421875 0.791975830078125 -0.223375 -0.09906005859375 0.791975830078125 -0.2235 -0.10809326171875 0.791975830078125 -0.223625 -0.115203857421875 0.791975830078125 -0.22375 -0.1195068359375 0.791975830078125 -0.223875 -0.127349853515625 0.791975830078125 -0.224 -0.128570556640625 0.9999084491282701 -0.224125 -0.128692626953125 0.9999084491282701 -0.22425 -0.127105712890625 0.9999084491282701 -0.224375 -0.123779296875 0.9999084491282701 -0.2245 -0.1192626953125 0.9999084491282701 -0.224625 -0.113525390625 0.9999084491282701 -0.22475 -0.106658935546875 0.9999084491282701 -0.224875 -0.10369873046875 0.9999084491282701 -0.225 -0.09539794921875 0.9999084491282701 -0.225125 -0.086090087890625 0.9999084491282701 -0.22525 -0.076904296875 0.9999084491282701 -0.225375 -0.0670166015625 0.9999084491282701 -0.2255 -0.05706787109375 0.9999084491282701 -0.225625 -0.047943115234375 0.9999084491282701 -0.22575 -0.038482666015625 0.9999084491282701 -0.225875 -0.0301513671875 0.9999084491282701 -0.226 -0.0218505859375 0.9999084491282701 -0.226125 -0.01556396484375 0.9999084491282701 -0.22625 -0.009002685546875 0.9999084491282701 -0.226375 -0.00274658203125 0.9999084491282701 +0.222625 -0.013458251953125 0.791975830078125 +0.22275 -0.02984619140625 0.791975830078125 +0.222875 -0.04681396484375 0.791975830078125 +0.223 -0.06231689453125 0.791975830078125 +0.223125 -0.074615478515625 0.791975830078125 +0.22325 -0.089508056640625 0.791975830078125 +0.223375 -0.099029541015625 0.791975830078125 +0.2235 -0.108062744140625 0.791975830078125 +0.223625 -0.11517333984375 0.791975830078125 +0.22375 -0.119476318359375 0.791975830078125 +0.223875 -0.1273193359375 0.791975830078125 +0.224 -0.1285400390625 0.9999084491282701 +0.224125 -0.128662109375 0.9999084491282701 +0.22425 -0.1270751953125 0.9999084491282701 +0.224375 -0.123748779296875 0.9999084491282701 +0.2245 -0.119232177734375 0.9999084491282701 +0.224625 -0.113494873046875 0.9999084491282701 +0.22475 -0.10662841796875 0.9999084491282701 +0.224875 -0.103668212890625 0.9999084491282701 +0.225 -0.095367431640625 0.9999084491282701 +0.225125 -0.0860595703125 0.9999084491282701 +0.22525 -0.076873779296875 0.9999084491282701 +0.225375 -0.066986083984375 0.9999084491282701 +0.2255 -0.057037353515625 0.9999084491282701 +0.225625 -0.04791259765625 0.9999084491282701 +0.22575 -0.0384521484375 0.9999084491282701 +0.225875 -0.030120849609375 0.9999084491282701 +0.226 -0.021820068359375 0.9999084491282701 +0.226125 -0.015533447265625 0.9999084491282701 +0.22625 -0.00897216796875 0.9999084491282701 +0.226375 -0.002716064453125 0.9999084491282701 0.2265 0.001953125 0.9999084491282701 0.226625 0.006072998046875 0.9999084491282701 0.22675 0.009063720703125 0.9999084491282701 @@ -1821,26 +1821,26 @@ 0.2275 0.0078125 0.9999084491282701 0.227625 0.004241943359375 0.9999084491282701 0.22775 0.0 0.9999084491282701 -0.227875 -0.004791259765625 0.9999084491282701 -0.228 -0.00994873046875 0.9999084491282701 -0.228125 -0.01531982421875 0.9999084491282701 -0.22825 -0.020782470703125 0.9999084491282701 -0.228375 -0.026153564453125 0.9999084491282701 -0.2285 -0.031280517578125 0.9999084491282701 -0.228625 -0.03082275390625 0.9999084491282701 -0.22875 -0.03515625 0.9999084491282701 -0.228875 -0.038726806640625 0.9999084491282701 -0.229 -0.04168701171875 0.9999084491282701 -0.229125 -0.04351806640625 0.9999084491282701 -0.22925 -0.044281005859375 0.9999084491282701 -0.229375 -0.0443115234375 0.9999084491282701 -0.2295 -0.042694091796875 0.9999084491282701 -0.229625 -0.0404052734375 0.9999084491282701 -0.22975 -0.036224365234375 0.9999084491282701 -0.229875 -0.028778076171875 0.9999084491282701 -0.23 -0.02325439453125 0.9999084491282701 -0.230125 -0.01568603515625 0.9999084491282701 -0.23025 -0.007843017578125 0.9999084491282701 +0.227875 -0.0047607421875 0.9999084491282701 +0.228 -0.009918212890625 0.9999084491282701 +0.228125 -0.015289306640625 0.9999084491282701 +0.22825 -0.020751953125 0.9999084491282701 +0.228375 -0.026123046875 0.9999084491282701 +0.2285 -0.03125 0.9999084491282701 +0.228625 -0.030792236328125 0.9999084491282701 +0.22875 -0.035125732421875 0.9999084491282701 +0.228875 -0.0386962890625 0.9999084491282701 +0.229 -0.041656494140625 0.9999084491282701 +0.229125 -0.043487548828125 0.9999084491282701 +0.22925 -0.04425048828125 0.9999084491282701 +0.229375 -0.044281005859375 0.9999084491282701 +0.2295 -0.04266357421875 0.9999084491282701 +0.229625 -0.040374755859375 0.9999084491282701 +0.22975 -0.03619384765625 0.9999084491282701 +0.229875 -0.02874755859375 0.9999084491282701 +0.23 -0.023223876953125 0.9999084491282701 +0.230125 -0.015655517578125 0.9999084491282701 +0.23025 -0.0078125 0.9999084491282701 0.230375 0.002044677734375 0.9999084491282701 0.2305 0.01300048828125 0.9999084491282701 0.230625 0.02374267578125 0.9999084491282701 @@ -1873,37 +1873,37 @@ 0.234 0.047149658203125 0.9999084491282701 0.234125 0.024169921875 0.9999084491282701 0.23425 0.0 0.9999084491282701 -0.234375 -0.022674560546875 0.9999084491282701 -0.2345 -0.048492431640625 0.9999084491282701 -0.234625 -0.072235107421875 0.9999084491282701 -0.23475 -0.098602294921875 0.9999084491282701 -0.234875 -0.122589111328125 0.9999084491282701 -0.235 -0.14556884765625 0.9999084491282701 -0.235125 -0.1700439453125 0.9999084491282701 -0.23525 -0.19140625 0.9999084491282701 -0.235375 -0.213409423828125 0.9999084491282701 -0.2355 -0.23358154296875 0.9999084491282701 -0.235625 -0.2503662109375 0.9999084491282701 -0.23575 -0.266357421875 0.9999084491282701 -0.235875 -0.2789306640625 0.9999084491282701 -0.236 -0.28973388671875 0.9999084491282701 -0.236125 -0.29327392578125 0.9999084491282701 -0.23625 -0.29791259765625 0.9999084491282701 -0.236375 -0.2994384765625 0.9999084491282701 -0.2365 -0.298309326171875 0.9999084491282701 -0.236625 -0.29327392578125 0.9999084491282701 -0.23675 -0.28466796875 0.9999084491282701 -0.236875 -0.2742919921875 0.9999084491282701 -0.237 -0.259033203125 0.9999084491282701 -0.237125 -0.242767333984375 0.9999084491282701 -0.23725 -0.221221923828125 0.9999084491282701 -0.237375 -0.1943359375 0.9999084491282701 -0.2375 -0.1702880859375 0.9999084491282701 -0.237625 -0.140869140625 0.9999084491282701 -0.23775 -0.112548828125 0.9999084491282701 -0.237875 -0.079010009765625 0.9999084491282701 -0.238 -0.0438232421875 0.9999084491282701 -0.238125 -0.0111083984375 0.9999084491282701 +0.234375 -0.02264404296875 0.9999084491282701 +0.2345 -0.0484619140625 0.9999084491282701 +0.234625 -0.07220458984375 0.9999084491282701 +0.23475 -0.09857177734375 0.9999084491282701 +0.234875 -0.12255859375 0.9999084491282701 +0.235 -0.145538330078125 0.9999084491282701 +0.235125 -0.170013427734375 0.9999084491282701 +0.23525 -0.191375732421875 0.9999084491282701 +0.235375 -0.21337890625 0.9999084491282701 +0.2355 -0.233551025390625 0.9999084491282701 +0.235625 -0.250335693359375 0.9999084491282701 +0.23575 -0.266326904296875 0.9999084491282701 +0.235875 -0.278900146484375 0.9999084491282701 +0.236 -0.289703369140625 0.9999084491282701 +0.236125 -0.293243408203125 0.9999084491282701 +0.23625 -0.297882080078125 0.9999084491282701 +0.236375 -0.299407958984375 0.9999084491282701 +0.2365 -0.29827880859375 0.9999084491282701 +0.236625 -0.293243408203125 0.9999084491282701 +0.23675 -0.284637451171875 0.9999084491282701 +0.236875 -0.274261474609375 0.9999084491282701 +0.237 -0.259002685546875 0.9999084491282701 +0.237125 -0.24273681640625 0.9999084491282701 +0.23725 -0.22119140625 0.9999084491282701 +0.237375 -0.194305419921875 0.9999084491282701 +0.2375 -0.170257568359375 0.9999084491282701 +0.237625 -0.140838623046875 0.9999084491282701 +0.23775 -0.112518310546875 0.9999084491282701 +0.237875 -0.0789794921875 0.9999084491282701 +0.238 -0.043792724609375 0.9999084491282701 +0.238125 -0.011077880859375 0.9999084491282701 0.23825 0.026123046875 0.9999084491282701 0.238375 0.060150146484375 0.9999084491282701 0.2385 0.09796142578125 0.9999084491282701 @@ -1935,37 +1935,37 @@ 0.24175 0.1082763671875 0.9999084491282701 0.241875 0.0684814453125 0.9999084491282701 0.242 0.02301025390625 0.9999084491282701 -0.242125 -0.0185546875 0.9999084491282701 -0.24225 -0.0650634765625 0.9999084491282701 -0.242375 -0.11077880859375 0.9999084491282701 -0.2425 -0.15167236328125 0.9999084491282701 -0.242625 -0.195892333984375 0.9999084491282701 -0.24275 -0.234344482421875 0.9999084491282701 -0.242875 -0.274810791015625 0.9999084491282701 -0.243 -0.312652587890625 0.9999084491282701 -0.243125 -0.344146728515625 0.9999084491282701 -0.24325 -0.37567138671875 0.9999084491282701 -0.243375 -0.40087890625 0.9999084491282701 -0.2435 -0.424652099609375 0.9999084491282701 -0.243625 -0.44207763671875 0.9999084491282701 -0.24375 -0.455474853515625 0.9999084491282701 -0.243875 -0.4654541015625 0.9999084491282701 -0.244 -0.47027587890625 0.9999084491282701 -0.244125 -0.470489501953125 0.9999084491282701 -0.24425 -0.465423583984375 0.9999084491282701 -0.244375 -0.456573486328125 0.9999084491282701 -0.2445 -0.44171142578125 0.9999084491282701 -0.244625 -0.42413330078125 0.9999084491282701 -0.24475 -0.399871826171875 0.9999084491282701 -0.244875 -0.369903564453125 0.9999084491282701 -0.245 -0.340484619140625 0.9999084491282701 -0.245125 -0.30389404296875 0.9999084491282701 -0.24525 -0.2679443359375 0.9999084491282701 -0.245375 -0.224945068359375 0.9999084491282701 -0.2455 -0.179168701171875 0.9999084491282701 -0.245625 -0.1361083984375 0.9999084491282701 -0.24575 -0.086578369140625 0.9999084491282701 -0.245875 -0.040985107421875 0.9999084491282701 +0.242125 -0.018524169921875 0.9999084491282701 +0.24225 -0.065032958984375 0.9999084491282701 +0.242375 -0.110748291015625 0.9999084491282701 +0.2425 -0.151641845703125 0.9999084491282701 +0.242625 -0.19586181640625 0.9999084491282701 +0.24275 -0.23431396484375 0.9999084491282701 +0.242875 -0.2747802734375 0.9999084491282701 +0.243 -0.3126220703125 0.9999084491282701 +0.243125 -0.3441162109375 0.9999084491282701 +0.24325 -0.375640869140625 0.9999084491282701 +0.243375 -0.400848388671875 0.9999084491282701 +0.2435 -0.42462158203125 0.9999084491282701 +0.243625 -0.442047119140625 0.9999084491282701 +0.24375 -0.4554443359375 0.9999084491282701 +0.243875 -0.465423583984375 0.9999084491282701 +0.244 -0.470245361328125 0.9999084491282701 +0.244125 -0.470458984375 0.9999084491282701 +0.24425 -0.46539306640625 0.9999084491282701 +0.244375 -0.45654296875 0.9999084491282701 +0.2445 -0.441680908203125 0.9999084491282701 +0.244625 -0.424102783203125 0.9999084491282701 +0.24475 -0.39984130859375 0.9999084491282701 +0.244875 -0.369873046875 0.9999084491282701 +0.245 -0.3404541015625 0.9999084491282701 +0.245125 -0.303863525390625 0.9999084491282701 +0.24525 -0.267913818359375 0.9999084491282701 +0.245375 -0.22491455078125 0.9999084491282701 +0.2455 -0.17913818359375 0.9999084491282701 +0.245625 -0.136077880859375 0.9999084491282701 +0.24575 -0.0865478515625 0.9999084491282701 +0.245875 -0.04095458984375 0.9999084491282701 0.246 0.01025390625 0.9999084491282701 0.246125 0.0615234375 0.9999084491282701 0.24625 0.1072998046875 0.9999084491282701 @@ -1998,37 +1998,37 @@ 0.249625 0.103546142578125 0.9999084491282701 0.24975 0.052001953125 0.9999084491282701 0.249875 0.0 0.9999084491282701 -0.25 -0.046783447265625 0.9999084491282701 -0.250125 -0.09814453125 0.9999084491282701 -0.25025 -0.143341064453125 0.9999084491282701 -0.250375 -0.191925048828125 0.9999084491282701 -0.2505 -0.238250732421875 0.9999084491282701 -0.250625 -0.27752685546875 0.9999084491282701 -0.25075 -0.31817626953125 0.9999084491282701 -0.250875 -0.3515625 0.9999084491282701 -0.251 -0.384857177734375 0.9999084491282701 -0.251125 -0.414642333984375 0.9999084491282701 -0.25125 -0.4366455078125 0.9999084491282701 -0.251375 -0.456512451171875 0.9999084491282701 -0.2515 -0.46990966796875 0.9999084491282701 -0.251625 -0.47991943359375 0.9999084491282701 -0.25175 -0.48455810546875 0.9999084491282701 -0.251875 -0.483978271484375 0.9999084491282701 -0.252 -0.478424072265625 0.9999084491282701 -0.252125 -0.468780517578125 0.9999084491282701 -0.25225 -0.453369140625 0.9999084491282701 -0.252375 -0.43438720703125 0.9999084491282701 -0.2525 -0.411956787109375 0.9999084491282701 -0.252625 -0.38299560546875 0.9999084491282701 -0.25275 -0.35333251953125 0.9999084491282701 -0.252875 -0.317047119140625 0.9999084491282701 -0.253 -0.277496337890625 0.9999084491282701 -0.253125 -0.23944091796875 0.9999084491282701 -0.25325 -0.195068359375 0.9999084491282701 -0.253375 -0.153472900390625 0.9999084491282701 -0.2535 -0.10614013671875 0.9999084491282701 -0.253625 -0.058258056640625 0.9999084491282701 -0.2537500000000001 -0.0145263671875 0.9999084491282701 +0.25 -0.0467529296875 0.9999084491282701 +0.250125 -0.098114013671875 0.9999084491282701 +0.25025 -0.143310546875 0.9999084491282701 +0.250375 -0.19189453125 0.9999084491282701 +0.2505 -0.23822021484375 0.9999084491282701 +0.250625 -0.277496337890625 0.9999084491282701 +0.25075 -0.318145751953125 0.9999084491282701 +0.250875 -0.351531982421875 0.9999084491282701 +0.251 -0.38482666015625 0.9999084491282701 +0.251125 -0.41461181640625 0.9999084491282701 +0.25125 -0.436614990234375 0.9999084491282701 +0.251375 -0.45648193359375 0.9999084491282701 +0.2515 -0.469879150390625 0.9999084491282701 +0.251625 -0.479888916015625 0.9999084491282701 +0.25175 -0.484527587890625 0.9999084491282701 +0.251875 -0.48394775390625 0.9999084491282701 +0.252 -0.4783935546875 0.9999084491282701 +0.252125 -0.46875 0.9999084491282701 +0.25225 -0.453338623046875 0.9999084491282701 +0.252375 -0.434356689453125 0.9999084491282701 +0.2525 -0.41192626953125 0.9999084491282701 +0.252625 -0.382965087890625 0.9999084491282701 +0.25275 -0.353302001953125 0.9999084491282701 +0.252875 -0.3170166015625 0.9999084491282701 +0.253 -0.2774658203125 0.9999084491282701 +0.253125 -0.239410400390625 0.9999084491282701 +0.25325 -0.195037841796875 0.9999084491282701 +0.253375 -0.1534423828125 0.9999084491282701 +0.2535 -0.106109619140625 0.9999084491282701 +0.253625 -0.0582275390625 0.9999084491282701 +0.2537500000000001 -0.014495849609375 0.9999084491282701 0.253875 0.033721923828125 0.9999084491282701 0.254 0.07647705078125 0.9999084491282701 0.254125 0.122772216796875 0.9999084491282701 diff --git a/tests/circuitpython/synthesizer.py.exp b/tests/circuitpython/synthesizer.py.exp index fb2e8c07bd6..98f45f8bf85 100644 --- a/tests/circuitpython/synthesizer.py.exp +++ b/tests/circuitpython/synthesizer.py.exp @@ -1,30 +1,30 @@ () [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] (80,) -[-16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384, 16383, 16383, 16383, 16383, 16383, -16384, -16384, -16384, -16384, -16384] +[-16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383, 16383, 16383, 16383, 16383, 16383, -16383, -16383, -16383, -16383, -16383] (80, 91) -[-1, -1, 28045, 28045, -1, -28046, -28046, -1, 28045, 28045, -1, -1, 28045, -1, -1, -28046, -28046, -1, 28045, 28045, -1, -1, 28045, -1] +[0, 0, 28045, 28045, 0, -28046, -28046, 0, 28045, 28045, 0, 0, 28045, 0, 0, -28046, -28046, 0, 28045, 28045, 0, 0, 28045, 0] (91,) -[-28046, -1, -1, 28045, -1, -1, 28045, 28045, -1, -28046, -28046, -1, 28045, 28045, -1, -1, 28045, -1, -1, -28046, -28046, -28046, 28045, 28045] -(-5243, 5242) +[-28046, 0, 0, 28045, 0, 0, 28045, 28045, 0, -28046, -28046, 0, 28045, 28045, 0, 0, 28045, 0, 0, -28046, -28046, -28046, 28045, 28045] +(-5242, 5242) (-10485, 10484) -(-15728, 15727) -(-16384, 16383) -(-14287, 14286) -(-13107, 13106) -(-13107, 13106) -(-13107, 13106) -(-13107, 13106) -(-13107, 13106) -(-13107, 13106) -(-13107, 13106) -(-13107, 13106) -(-11010, 11009) -(-8913, 8912) -(-6816, 6815) -(-4719, 4718) -(-2622, 2621) -(-525, 524) +(-15727, 15727) +(-16383, 16383) +(-14286, 14286) +(-13106, 13106) +(-13106, 13106) +(-13106, 13106) +(-13106, 13106) +(-13106, 13106) +(-13106, 13106) +(-13106, 13106) +(-13106, 13106) +(-11009, 11009) +(-8912, 8912) +(-6815, 6815) +(-4718, 4718) +(-2621, 2621) +(-524, 524) (0, 0) (0, 0) (0, 0) diff --git a/tests/circuitpython/synthesizer_note.py.exp b/tests/circuitpython/synthesizer_note.py.exp index 43d07e5e7da..422fb7b9aff 100644 --- a/tests/circuitpython/synthesizer_note.py.exp +++ b/tests/circuitpython/synthesizer_note.py.exp @@ -1,13 +1,13 @@ () [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] -(Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0, waveform_loop_end=16384, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0, ring_waveform_loop_end=16384),) +(Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0.0, waveform_loop_end=16384.0, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0.0, ring_waveform_loop_end=16384.0),) [-16383, -16383, -16383, -16383, 16382, 16382, 16382, 16382, 16382, -16383, -16383, -16383, -16383, -16383, 16382, 16382, 16382, 16382, 16382, -16383, -16383, -16383, -16383, -16383] -(Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0, waveform_loop_end=16384, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0, ring_waveform_loop_end=16384), Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0, waveform_loop_end=16384, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0, ring_waveform_loop_end=16384)) +(Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0.0, waveform_loop_end=16384.0, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0.0, ring_waveform_loop_end=16384.0), Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0.0, waveform_loop_end=16384.0, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0.0, ring_waveform_loop_end=16384.0)) [-1, -1, -1, -1, -1, -1, -1, -1, 28045, -1, -1, -1, -1, -28046, -1, -1, -1, -1, 28045, -1, -1, -1, -1, -28046] -(Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0, waveform_loop_end=16384, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0, ring_waveform_loop_end=16384),) +(Note(frequency=830.6076004423605, panning=0.0, amplitude=1.0, bend=0.0, waveform=None, waveform_loop_start=0.0, waveform_loop_end=16384.0, envelope=None, filter=None, ring_frequency=0.0, ring_bend=0.0, ring_waveform=None, ring_waveform_loop_start=0.0, ring_waveform_loop_end=16384.0),) [-1, -1, -1, 28045, -1, -1, -1, -1, -1, -1, -1, -1, 28045, -1, -1, -1, -1, -28046, -1, -1, -1, -1, 28045, -1] (-5242, 5241) -(-10485, 10484) +(-10484, 10484) (-15727, 15726) (-16383, 16382) (-14286, 14285) diff --git a/tests/circuitpython/synthio_biquad.py b/tests/circuitpython/synthio_biquad.py index 92b8e64a054..9fb67fb81e3 100644 --- a/tests/circuitpython/synthio_biquad.py +++ b/tests/circuitpython/synthio_biquad.py @@ -1,12 +1,17 @@ -from synthio import Synthesizer +from synthnotehelper import * +from synthio import Biquad, FilterMode +import random -s = Synthesizer(sample_rate=48000) +random.seed(41) +white_noise = array.array("h", [random.randint(-32000, 32000) for i in range(600)]) -def print_filter(x): - print(" ".join(f"{v:.4g}" for v in x)) - -print_filter(s.low_pass_filter(330)) -print_filter(s.high_pass_filter(330)) -print_filter(s.band_pass_filter(330)) +@synth_test_rms +def gen(synth): + l = LFO(sweep, offset=1440, scale=2880, rate=0.025, once=True) + yield [l] + b = Biquad(FilterMode.LOW_PASS, l, Q=0.5**0.5) + n = Note(100, filter=b, waveform=white_noise) + synth.press(n) + yield 20 diff --git a/tests/circuitpython/synthio_biquad.py.exp b/tests/circuitpython/synthio_biquad.py.exp index 2b9ca364c6e..36805bd3af4 100644 --- a/tests/circuitpython/synthio_biquad.py.exp +++ b/tests/circuitpython/synthio_biquad.py.exp @@ -1,3 +1,640 @@ --1.939 0.9407 0.0004526 0.0009052 0.0004526 --1.939 0.9407 0.9699 -1.94 0.9699 --1.939 0.9407 0.02963 0 -0.02963 +0.0 0.4292414482077013 -1435.412246704102 +0.03125 0.4301957475984245 -1430.912384033203 +0.0625 0.443415096786705 -1426.412521362305 +0.09375 0.4138944101201059 -1421.912658691406 +0.125 0.4405400571695613 -1417.412796020508 +0.15625 0.4016394462659425 -1412.912933349609 +0.1875 0.4327624316124036 -1408.413070678711 +0.21875 0.4287368973626116 -1403.913208007813 +0.25 0.4345957058398272 -1399.413345336914 +0.28125 0.4309447646333486 -1394.913482666016 +0.3125 0.4354826789649687 -1390.413619995117 +0.34375 0.4342858719298666 -1385.913757324219 +0.375 0.4377970872905904 -1381.41389465332 +0.40625 0.4370108811124707 -1376.914031982422 +0.4375 0.4295542636055871 -1372.414169311523 +0.46875 0.4329853290304969 -1367.914306640625 +0.5 0.4455501064219861 -1363.414443969727 +0.53125 0.4415799690008891 -1358.914581298828 +0.5625 0.430107469300593 -1354.41471862793 +0.59375 0.4115680204350006 -1349.914855957031 +0.625 0.439561328340486 -1345.414993286133 +0.65625 0.4253925109033371 -1340.915130615234 +0.6875 0.4185943916302574 -1336.415267944336 +0.71875 0.4258237185752813 -1331.915405273438 +0.75 0.4112320384281056 -1327.415542602539 +0.78125 0.4421489522731164 -1322.915679931641 +0.8125 0.4285193689964977 -1318.415817260742 +0.84375 0.4244358011163597 -1313.915954589844 +0.875 0.4445975208808163 -1309.416091918945 +0.90625 0.4471065627393449 -1304.916229248047 +0.9375 0.4568033022778143 -1300.416366577148 +0.96875 0.4259499858352917 -1295.91650390625 +1.0 0.4536505096800783 -1291.416641235352 +1.03125 0.4273680768687785 -1286.916778564453 +1.0625 0.4693132711352654 -1282.416915893555 +1.09375 0.4160924678698707 -1277.917053222656 +1.125 0.4515606024849182 -1273.417190551758 +1.15625 0.4364089459564787 -1268.917327880859 +1.1875 0.4348510600055276 -1264.41746520996 +1.21875 0.451432630170392 -1259.917602539063 +1.25 0.4416638694710183 -1255.417739868164 +1.28125 0.451611407724486 -1250.917877197266 +1.3125 0.4625336702141225 -1246.418014526367 +1.34375 0.4648639812435186 -1241.918151855469 +1.375 0.4460508471392539 -1237.41828918457 +1.40625 0.4374704584317717 -1232.918426513672 +1.4375 0.4302419180820578 -1228.418563842773 +1.46875 0.4136589658399674 -1223.918701171875 +1.5 0.4402948947417665 -1219.418838500977 +1.53125 0.4354149960453673 -1214.918975830078 +1.5625 0.4207519521348172 -1210.41911315918 +1.59375 0.4517893119386277 -1205.919250488281 +1.625 0.4377037203023695 -1201.419387817383 +1.65625 0.4381095879613992 -1196.919525146485 +1.6875 0.4335728977482941 -1192.419662475586 +1.71875 0.4251033969710498 -1187.919799804688 +1.75 0.4214479982981709 -1183.41993713379 +1.78125 0.433242942953255 -1178.920074462891 +1.8125 0.398152072548805 -1174.420211791993 +1.84375 0.4372636185762459 -1169.920349121094 +1.875 0.4291250895649827 -1165.420486450196 +1.90625 0.4138667249705813 -1160.920623779297 +1.9375 0.4269810851192543 -1156.420761108398 +1.96875 0.4237267320491086 -1151.9208984375 +2.0 0.4258018952548287 -1147.421035766602 +2.03125 0.4036759087596965 -1142.921173095704 +2.0625 0.4071953834764041 -1138.421310424805 +2.09375 0.4069726709639113 -1133.921447753906 +2.125 0.4253069738402361 -1129.421585083008 +2.15625 0.4278676768058594 -1124.92172241211 +2.1875 0.4273060577495892 -1120.421859741211 +2.21875 0.4148458356935921 -1115.921997070313 +2.25 0.4035167256876282 -1111.422134399415 +2.28125 0.4130066098571691 -1106.922271728516 +2.3125 0.4025638392426288 -1102.422409057618 +2.34375 0.392949305348438 -1097.922546386719 +2.375 0.4055346571156643 -1093.422683715821 +2.40625 0.3841531504399494 -1088.922821044922 +2.4375 0.3966926384714262 -1084.422958374024 +2.46875 0.4102200419660115 -1079.923095703125 +2.5 0.4030059077414907 -1075.423233032227 +2.53125 0.3876811705709198 -1070.923370361329 +2.5625 0.3900713483040226 -1066.42350769043 +2.59375 0.3957986944065445 -1061.923645019532 +2.625 0.3799874774938255 -1057.423782348633 +2.65625 0.399969004242642 -1052.923919677735 +2.6875 0.4030233464415128 -1048.424057006837 +2.71875 0.3893539782322431 -1043.924194335938 +2.75 0.3909872816448433 -1039.42433166504 +2.78125 0.3904856531720035 -1034.924468994141 +2.8125 0.3964487403729973 -1030.424606323243 +2.84375 0.367141125232508 -1025.924743652345 +2.875 0.3755638797772791 -1021.424880981446 +2.90625 0.3998548247989561 -1016.925018310548 +2.9375 0.4025267173160954 -1012.425155639649 +2.96875 0.3773823339352469 -1007.925292968751 +3.0 0.4042089102378084 -1003.425430297852 +3.03125 0.3949071386325466 -998.9255676269536 +3.0625 0.4064082535642184 -994.4257049560556 +3.09375 0.4010787430493667 -989.9258422851567 +3.125 0.4017930109841857 -985.4259796142587 +3.15625 0.3892376075083491 -980.9261169433603 +3.1875 0.3971434904652945 -976.4262542724618 +3.21875 0.3892411665720613 -971.9263916015634 +3.25 0.3839529716571926 -967.4265289306654 +3.28125 0.3824722893209285 -962.9266662597665 +3.3125 0.3952780375942706 -958.4268035888681 +3.34375 0.4179519059519968 -953.9269409179697 +3.375 0.3898154262936899 -949.4270782470712 +3.40625 0.3976718277347342 -944.9272155761732 +3.4375 0.3850638479108297 -940.4273529052743 +3.46875 0.3958265371547819 -935.9274902343764 +3.5 0.4004332350927074 -931.4276275634775 +3.53125 0.3888213325698884 -926.927764892579 +3.5625 0.371131695964836 -922.4279022216811 +3.59375 0.4188939439713424 -917.9280395507822 +3.625 0.4081025456433866 -913.4281768798842 +3.65625 0.3733601855622199 -908.9283142089857 +3.6875 0.3808196119266348 -904.4284515380868 +3.71875 0.392660092123199 -899.9285888671889 +3.75 0.3808027498263037 -895.4287261962904 +3.78125 0.4068448640657261 -890.928863525392 +3.8125 0.3980447756551903 -886.4290008544936 +3.84375 0.4036631225200267 -881.9291381835951 +3.875 0.3876801629403572 -877.4292755126967 +3.90625 0.3984128299621498 -872.9294128417982 +3.9375 0.411005762062684 -868.4295501708998 +3.96875 0.3823055352727712 -863.9296875000014 +4.0 0.4033390445203946 -859.4298248291029 +4.03125 0.3869349079589102 -854.9299621582045 +4.0625 0.406561858202515 -850.4300994873065 +4.09375 0.4198370291448769 -845.9302368164076 +4.125 0.4089914984288221 -841.4303741455092 +4.15625 0.3857109649839493 -836.9305114746107 +4.1875 0.4142716745626002 -832.4306488037123 +4.21875 0.391505346562964 -827.9307861328143 +4.25 0.4030787954726662 -823.4309234619159 +4.28125 0.3766501680871163 -818.931060791017 +4.3125 0.3803567013661997 -814.4311981201186 +4.34375 0.417475410602975 -809.9313354492201 +4.375 0.4004163242806387 -805.4314727783221 +4.40625 0.3685731937453348 -800.9316101074237 +4.4375 0.3979205436317936 -796.4317474365248 +4.46875 0.4078888087177493 -791.9318847656264 +4.5 0.3921430399033289 -787.4320220947279 +4.53125 0.4119813312521327 -782.9321594238299 +4.5625 0.3935698957084185 -778.4322967529315 +4.59375 0.3727464496698831 -773.9324340820326 +4.625 0.3955035731153163 -769.4325714111342 +4.65625 0.3942862357046499 -764.9327087402362 +4.6875 0.3843275918191916 -760.4328460693378 +4.71875 0.3851421952649138 -755.9329833984393 +4.75 0.3902906061399617 -751.4331207275409 +4.78125 0.3844671126461341 -746.933258056642 +4.8125 0.3791288781111852 -742.433395385744 +4.84375 0.3837003871047081 -737.9335327148456 +4.875 0.3870946995015528 -733.4336700439471 +4.90625 0.39553933731762 -728.9338073730487 +4.9375 0.3744296300001198 -724.4339447021498 +4.96875 0.3667587510805197 -719.9340820312518 +5.0 0.3916190946800228 -715.4342193603534 +5.03125 0.3814689280310855 -710.9343566894549 +5.0625 0.3967725697688225 -706.4344940185565 +5.09375 0.3937405019170813 -701.9346313476576 +5.125 0.3777270428748825 -697.4347686767592 +5.15625 0.3870083970450706 -692.9349060058612 +5.1875 0.3883337842102841 -688.4350433349628 +5.21875 0.3763887168339391 -683.9351806640639 +5.25 0.3774724312165993 -679.4353179931654 +5.28125 0.3893272640042596 -674.935455322267 +5.3125 0.3953789887892353 -670.4355926513686 +5.34375 0.3801785044601818 -665.9357299804701 +5.375 0.3954135587096122 -661.4358673095712 +5.40625 0.3874319561492619 -656.9360046386728 +5.4375 0.3928975156161072 -652.4361419677748 +5.46875 0.39136415848977 -647.9362792968759 +5.5 0.3926008598161878 -643.4364166259775 +5.53125 0.3886504623120136 -638.9365539550786 +5.5625 0.3831538016240389 -634.4366912841806 +5.59375 0.383033101461492 -629.9368286132817 +5.625 0.382207202634286 -625.4369659423833 +5.65625 0.3913172446646332 -620.9371032714853 +5.6875 0.3847724862238807 -616.4372406005864 +5.71875 0.3939629239442654 -611.937377929688 +5.75 0.383305155845298 -607.4375152587891 +5.78125 0.3916892245619181 -602.9376525878911 +5.8125 0.3946926061973548 -598.4377899169926 +5.84375 0.3892107176066872 -593.9379272460935 +5.875 0.3814936484084122 -589.4380645751953 +5.90625 0.3943244857223315 -584.9382019042969 +5.9375 0.3857112348864788 -580.4383392333984 +5.96875 0.3942048347924611 -575.9384765625002 +6.0 0.3911875153619875 -571.4386138916011 +6.03125 0.3915132752539617 -566.9387512207027 +6.0625 0.3909499616216763 -562.4388885498047 +6.09375 0.3827724950107045 -557.939025878906 +6.125 0.3875329733845965 -553.4391632080074 +6.15625 0.4000548290909773 -548.9393005371087 +6.1875 0.3967315317827893 -544.4394378662105 +6.21875 0.3951006062355771 -539.9395751953118 +6.25 0.3969628666712315 -535.4397125244132 +6.28125 0.400093117621525 -530.9398498535152 +6.3125 0.4020018744063912 -526.4399871826165 +6.34375 0.3987096233393185 -521.9401245117178 +6.375 0.3959471927998633 -517.4402618408189 +6.40625 0.4069494471924576 -512.940399169921 +6.4375 0.402011726755101 -508.4405364990225 +6.46875 0.4008641623960937 -503.9406738281236 +6.5 0.4115701831441808 -499.4408111572252 +6.53125 0.4090335063892219 -494.9409484863268 +6.5625 0.4116842419628069 -490.4410858154286 +6.59375 0.4075960414244354 -485.9412231445301 +6.625 0.4081717451924282 -481.441360473631 +6.65625 0.4114323463061593 -476.9414978027328 +6.6875 0.4104565432056045 -472.4416351318346 +6.71875 0.4086514255916335 -467.9417724609359 +6.75 0.4115800192393992 -463.4419097900372 +6.78125 0.4093340265005087 -458.9420471191386 +6.8125 0.409278958418651 -454.4421844482406 +6.84375 0.4109678400408193 -449.9423217773419 +6.875 0.4084525067207762 -445.442459106443 +6.90625 0.4082485968008172 -440.9425964355451 +6.9375 0.4105211605776111 -436.4427337646464 +6.96875 0.40786863169688 -431.9428710937477 +7.0 0.4077589637368115 -427.4430084228491 +7.03125 0.4099997876338798 -422.9431457519509 +7.0625 0.4076714572193215 -418.4432830810526 +7.09375 0.407600712291866 -413.9434204101535 +7.125 0.4099004227397708 -409.4435577392551 +7.15625 0.4076214554633187 -404.9436950683569 +7.1875 0.4076326145533956 -400.4438323974584 +7.21875 0.410172474134385 -395.94396972656 +7.25 0.4078638574512831 -391.4441070556611 +7.28125 0.4080910709976476 -386.9442443847627 +7.3125 0.4104988189153643 -382.4443817138647 +7.34375 0.4084689949124797 -377.944519042966 +7.375 0.4087428208523811 -373.4446563720671 +7.40625 0.4113910072710569 -368.9447937011685 +7.4375 0.4094289014902302 -364.4449310302705 +7.46875 0.4095101423242618 -359.9450683593718 +7.5 0.4120630250505489 -355.4452056884732 +7.53125 0.4101384419541137 -350.9453430175749 +7.5625 0.4106321409247253 -346.4454803466763 +7.59375 0.4030961427991869 -341.9456176757776 +7.625 0.3903383621279249 -337.4457550048789 +7.65625 0.3937734927031041 -332.945892333981 +7.6875 0.3993492619940964 -328.4460296630825 +7.71875 0.385989496319416 -323.9461669921836 +7.75 0.3856861598937419 -319.4463043212852 +7.78125 0.3837838633055601 -314.9464416503868 +7.8125 0.3769300123298409 -310.4465789794883 +7.84375 0.3802207026470601 -305.9467163085901 +7.875 0.3828481259638064 -301.446853637691 +7.90625 0.379447179037863 -296.9469909667926 +7.9375 0.3802018507541309 -292.4471282958946 +7.96875 0.3769802547339046 -287.9472656249959 +8.0 0.3803390667074351 -283.4474029540972 +8.03125 0.3765104961974802 -278.9475402831986 +8.0625 0.3776210843927699 -274.4476776123004 +8.09375 0.3836716114153597 -269.9478149414017 +8.125 0.378769734236955 -265.447952270503 +8.15625 0.3775582564371868 -260.9480895996051 +8.1875 0.3773662771903655 -256.4482269287064 +8.21875 0.3775344932552112 -251.9483642578077 +8.25 0.3757562127863197 -247.4485015869091 +8.28125 0.376097649450651 -242.9486389160109 +8.3125 0.3758356013089041 -238.4487762451124 +8.34375 0.3773684844987389 -233.9489135742135 +8.375 0.3760552163029725 -229.4490509033151 +8.40625 0.376033096148381 -224.9491882324169 +8.4375 0.372452661362901 -220.4493255615184 +8.46875 0.3745717686363883 -215.94946289062 +8.5 0.3743486371073519 -211.4496002197211 +8.53125 0.3721674311277588 -206.9497375488227 +8.5625 0.3772128703769017 -202.4498748779247 +8.59375 0.3725790043542761 -197.9500122070258 +8.625 0.3758827155435686 -193.4501495361271 +8.65625 0.3743209259913767 -188.9502868652285 +8.6875 0.3706332323722716 -184.4504241943305 +8.71875 0.3755192620341588 -179.9505615234318 +8.75 0.3699010282695 -175.4506988525332 +8.78125 0.3751761002140255 -170.9508361816349 +8.8125 0.3673193831680472 -166.4509735107363 +8.84375 0.3703267596781248 -161.9511108398376 +8.875 0.3689641620418253 -157.4512481689389 +8.90625 0.3736852079969759 -152.951385498041 +8.9375 0.3672869869059834 -148.4515228271425 +8.96875 0.3740974122030886 -143.9516601562434 +9.0 0.3688860256628344 -139.4517974853452 +9.03125 0.3670327501993761 -134.9519348144468 +9.0625 0.3645313570401571 -130.4520721435483 +9.09375 0.3713930936780955 -125.9522094726499 +9.125 0.362916495103013 -121.452346801751 +9.15625 0.3690865039572091 -116.9524841308526 +9.1875 0.3615905851475338 -112.4526214599546 +9.21875 0.3681245712573865 -107.9527587890559 +9.25 0.3686344395996596 -103.4528961181572 +9.28125 0.3631918162418778 -98.95303344725835 +9.3125 0.365473890830738 -94.45317077636037 +9.34375 0.3665819288655671 -89.9533081054617 +9.375 0.3647457959760047 -85.45344543456304 +9.40625 0.3566742883671927 -80.95358276366505 +9.4375 0.3700218291726018 -76.45372009276616 +9.46875 0.3601955685082416 -71.9538574218675 +9.5 0.3677156049795945 -67.45399475096883 +9.53125 0.356669428135651 -62.95413208007085 +9.5625 0.365584468725112 -58.45426940917241 +9.59375 0.3620575963727736 -53.95440673827352 +9.625 0.3660536419997879 -49.45454406737508 +9.65625 0.3615481587068067 -44.95468139647664 +9.6875 0.3586519996027659 -40.45481872557843 +9.71875 0.3629708505110769 -35.95495605468 +9.75 0.3542547978069129 -31.45509338378088 +9.78125 0.3645631627542719 -26.95523071288267 +9.8125 0.3618473039061899 -22.45536804198446 +9.84375 0.3354950625427833 -17.95550537108579 +9.875 0.361595305808895 -13.45564270018713 +9.90625 0.3870185128971818 -8.955780029288462 +9.9375 0.342119700127982 -4.455917358390479 +9.96875 0.2711789125448073 0.04394531250841283 +10.0 0.406221045358242 4.54380798340685 +10.03125 0.1225360785801001 9.043670654305288 +10.0625 0.03174341737930414 13.54353332520373 +10.09375 0.02515935958829191 18.04339599610239 +10.125 0.009574457743938767 22.54325866700106 +10.15625 0.01745846809196387 27.04312133789927 +10.1875 0.02601177395465528 31.54298400879748 +10.21875 0.01415917685015583 36.04284667969637 +10.25 0.02245157778259128 40.54270935059503 +10.28125 0.04115089615388722 45.04257202149324 +10.3125 0.03874860340661093 49.54243469239145 +10.34375 0.02196631571892786 54.04229736329034 +10.375 0.02196023427652383 58.54216003418901 +10.40625 0.0352765758538488 63.04202270508745 +10.4375 0.03353321733296127 67.54188537598566 +10.46875 0.01609885633939395 72.04174804688409 +10.5 0.03742903210189786 76.54161071778299 +10.53125 0.05782232775915963 81.04147338868142 +10.5625 0.05286637288968352 85.54133605957986 +10.59375 0.02993413459140702 90.0411987304783 +10.625 0.03332199932412696 94.54106140137696 +10.65625 0.04622037701881601 99.04092407227517 +10.6875 0.04868105644814895 103.5407867431738 +10.71875 0.0231836361330315 108.0406494140725 +10.75 0.0501623458922407 112.5405120849709 +10.78125 0.06726940399118371 117.0403747558692 +10.8125 0.06636219231850592 121.5402374267676 +10.84375 0.03537720946864608 126.0401000976665 +10.875 0.04340484157782403 130.5399627685651 +10.90625 0.05485402611003761 135.0398254394634 +10.9375 0.06113000098851544 139.5396881103616 +10.96875 0.03212352569671814 144.0395507812602 +11.0 0.05856805737285709 148.5394134521591 +11.03125 0.0725659329387529 153.0392761230576 +11.0625 0.07546797747627238 157.5391387939558 +11.09375 0.04136378348487984 162.0390014648542 +11.125 0.05072249289502579 166.5388641357529 +11.15625 0.06118250358285766 171.0387268066515 +11.1875 0.0695532710528029 175.5385894775497 +11.21875 0.04135687164376359 180.0384521484484 +11.25 0.06422446600489478 184.5383148193469 +11.28125 0.07619244002924606 189.0381774902453 +11.3125 0.081678977474969 193.5380401611437 +11.34375 0.04818716548974017 198.0379028320426 +11.375 0.05578818150521037 202.5377655029411 +11.40625 0.06688108361255097 207.0376281738393 +11.4375 0.07569228149357033 211.5374908447377 +11.46875 0.05089722962555985 216.0373535156364 +11.5 0.06911272709822142 220.5372161865353 +11.53125 0.07893477798107136 225.0370788574335 +11.5625 0.08640667841789856 229.5369415283317 +11.59375 0.05577030990461401 234.0368041992303 +11.625 0.06029106376627119 238.5366668701292 +11.65625 0.07219505660275832 243.0365295410274 +11.6875 0.08061693794150473 247.5363922119257 +11.71875 0.06017290280756791 252.0362548828243 +11.75 0.07395877654929304 256.536117553723 +11.78125 0.08157274132241021 261.0359802246214 +11.8125 0.09019650384242192 265.5358428955199 +11.84375 0.06347961235055553 270.0357055664183 +11.875 0.06435324878239179 274.535568237317 +11.90625 0.07722535662613761 279.0354309082154 +11.9375 0.08458446293174319 283.5352935791138 +11.96875 0.06861468517765807 288.0351562500125 +12.0 0.07904605919763272 292.5350189209112 +12.03125 0.08422023125176194 297.0348815918094 +12.0625 0.09351761888096444 301.5347442627076 +12.09375 0.07075114359961844 306.0346069336065 +12.125 0.06814997827985858 310.5344696045051 +12.15625 0.08190920638078293 315.0343322754034 +12.1875 0.08804602366444849 319.5341949463016 +12.21875 0.07604590990738279 324.0340576172002 +12.25 0.08425930564405258 328.5339202880991 +12.28125 0.08701614143436316 333.0337829589976 +12.3125 0.09661797601881215 337.5336456298958 +12.34375 0.07745903467176028 342.0335083007942 +12.375 0.07166234233169564 346.5333709716929 +12.40625 0.08627936659419088 351.0332336425915 +12.4375 0.09123440443547194 355.53309631349 +12.46875 0.08251618031640428 360.0329589843884 +12.5 0.08939742073464346 364.5328216552869 +12.53125 0.08993018035099734 369.0326843261853 +12.5625 0.09946877941152422 373.532546997084 +12.59375 0.08355935392802863 378.0324096679826 +12.625 0.07499857786276619 382.5322723388811 +12.65625 0.09031205637078164 387.0321350097793 +12.6875 0.09418302582863182 391.5319976806777 +12.71875 0.08812572733899099 396.0318603515766 +12.75 0.09417803172836386 400.5317230224753 +12.78125 0.09295798430981622 405.0315856933735 +12.8125 0.1020913836496992 409.5314483642717 +12.84375 0.08922251972285368 414.0313110351703 +12.875 0.0781182008630799 418.5311737060692 +12.90625 0.09405343485309603 423.0310363769676 +12.9375 0.09704892139554945 427.5308990478658 +12.96875 0.09322388880971026 432.0307617187643 +13.0 0.09868619890806334 436.530624389663 +13.03125 0.09605992100961673 441.0304870605615 +13.0625 0.1046930899935769 445.53034973146 +13.09375 0.09456408660702788 450.0302124023584 +13.125 0.08110867864214342 454.530075073257 +13.15625 0.0975426225549988 459.0299377441554 +13.1875 0.09995899929625697 463.5298004150538 +13.21875 0.09788404878149466 468.0296630859526 +13.25 0.1028301855526857 472.5295257568512 +13.28125 0.09925688270323969 477.0293884277494 +13.3125 0.1071644181891975 481.5292510986477 +13.34375 0.09956183461201409 486.0291137695466 +13.375 0.08398404998945123 490.5289764404453 +13.40625 0.1009046731659027 495.0288391113435 +13.4375 0.1028961861915068 499.5287017822417 +13.46875 0.1023205405202272 504.0285644531403 +13.5 0.1066522016295972 508.5284271240392 +13.53125 0.1023131818494744 513.0282897949376 +13.5625 0.1096446073686916 517.5281524658358 +13.59375 0.1042795141110983 522.0280151367343 +13.625 0.08678495956048039 526.5278778076331 +13.65625 0.1040609464200182 531.0277404785315 +13.6875 0.1058129356918997 535.52760314943 +13.71875 0.1065241690470741 540.0274658203285 +13.75 0.1101692764682358 544.527328491227 +13.78125 0.1053728794049568 549.0271911621254 +13.8125 0.1120205616464041 553.527053833024 +13.84375 0.1087432537847466 558.0269165039226 +13.875 0.08954349595632319 562.5267791748212 +13.90625 0.1070489596553324 567.0266418457194 +13.9375 0.108737268129603 571.5265045166177 +13.96875 0.1105828075727535 576.0263671875166 +14.0 0.1133862716213715 580.5262298584153 +14.03125 0.1082443737836045 585.0260925293135 +14.0625 0.1143955628482857 589.5259552002117 +14.09375 0.1129309169134834 594.0258178711105 +14.125 0.09230387726595179 598.5256805420092 +14.15625 0.1099178483011606 603.0255432129077 +14.1875 0.1116656194509316 607.5254058838059 +14.21875 0.1145220685293726 612.0252685547043 +14.25 0.1163868784387258 616.5251312256031 +14.28125 0.1109951431026079 621.0249938965017 +14.3125 0.1167800812205802 625.5248565674 +14.34375 0.1168299870930108 630.0247192382985 +14.375 0.09508428012321064 634.5245819091971 +14.40625 0.1126210646498637 639.0244445800954 +14.4375 0.1145807105754756 643.524307250994 +14.46875 0.1183057967740651 648.0241699218926 +14.5 0.1192327743590527 652.5240325927912 +14.53125 0.113623220453224 657.0238952636894 +14.5625 0.1191589397759562 661.5237579345878 +14.59375 0.1204955963604885 666.0236206054866 +14.625 0.09785472222088311 670.5234832763853 +14.65625 0.1152061978790822 675.0233459472836 +14.6875 0.117487024010307 679.5232086181818 +14.71875 0.1219502913409791 684.0230712890805 +14.75 0.1219010915259758 688.5229339599792 +14.78125 0.116143028092938 693.0227966308777 +14.8125 0.1215908489467233 697.5226593017759 +14.84375 0.1239291718953261 702.0225219726744 +14.875 0.1005908519420451 706.5223846435731 +14.90625 0.1176327957295311 711.0222473144717 +14.9375 0.1204112286611297 715.52210998537 +14.96875 0.1254704428283171 720.0219726562685 +15.0 0.1244291183492105 724.5218353271671 +15.03125 0.1185450466115126 729.0216979980654 +15.0625 0.1240204967151066 733.521560668964 +15.09375 0.1271621521553429 738.0214233398626 +15.125 0.103344801653342 742.5212860107612 +15.15625 0.119976043761817 747.0211486816594 +15.1875 0.1232841884025795 751.5210113525578 +15.21875 0.1288287545809712 756.0208740234566 +15.25 0.1268517152789468 760.5207366943554 +15.28125 0.1208359538717516 765.0205993652536 +15.3125 0.1264688007806249 769.5204620361518 +15.34375 0.1301826291181721 774.0203247070505 +15.375 0.1060773553858188 778.5201873779494 +15.40625 0.1222327917123172 783.0200500488477 +15.4375 0.1261778571473278 787.5199127197459 +15.46875 0.132099606594904 792.0197753906444 +15.5 0.1292017331168378 796.5196380615431 +15.53125 0.1230463525417094 801.0195007324417 +15.5625 0.1289390944096008 805.5193634033401 +15.59375 0.1330080828518648 810.0192260742385 +15.625 0.1087347812054992 814.5190887451371 +15.65625 0.1244078270815042 819.0189514160355 +15.6875 0.1289984754599436 823.5188140869341 +15.71875 0.1352044176214791 828.0186767578327 +15.75 0.1314331050059518 832.5185394287313 +15.78125 0.1252001443500418 837.0184020996295 +15.8125 0.1314225736550603 841.5182647705278 +15.84375 0.1356923505299284 846.0181274414267 +15.875 0.1113592613931671 850.5179901123254 +15.90625 0.1265039886229113 855.0178527832236 +15.9375 0.1318380975435933 859.5177154541218 +15.96875 0.1382110410428466 864.0175781250205 +16.0 0.133645843276335 868.5174407959194 +16.03125 0.1272813740631589 873.0173034668177 +16.0625 0.1338764836326204 877.5171661377159 +16.09375 0.1382226505450681 882.0170288086144 +16.125 0.1139284279251886 886.5168914795131 +16.15625 0.128567740548516 891.0167541504117 +16.1875 0.1346064739793712 895.5166168213101 +16.21875 0.1410771584547389 900.0164794922086 +16.25 0.1357569773028019 904.5163421631071 +16.28125 0.1293390899769853 909.0162048340055 +16.3125 0.1363479303235955 913.5160675049041 +16.34375 0.1406301235519381 918.0159301758027 +16.375 0.1164264014174787 922.5157928467013 +16.40625 0.1305825259909043 927.0156555175995 +16.4375 0.1373327768151904 931.5155181884979 +16.46875 0.1438468870152026 936.0153808593967 +16.5 0.1378419788316238 940.5152435302954 +16.53125 0.1313468501722584 945.0151062011936 +16.5625 0.1388098763737581 949.5149688720919 +16.59375 0.142928449398856 954.0148315429906 +16.625 0.1188403445358696 958.5146942138894 +16.65625 0.1325693241873736 963.0145568847877 +16.6875 0.1400230280957335 967.5144195556859 +16.71875 0.146525034054905 972.0142822265846 +16.75 0.1398711075188404 976.5141448974832 +16.78125 0.1333366552258372 981.0140075683817 +16.8125 0.1412509738125822 985.5138702392801 +16.84375 0.14513106491862 990.0137329101786 +16.875 0.1211815448666828 994.5135955810772 +16.90625 0.1345247800333754 999.0134582519755 +16.9375 0.1426686705334448 1003.513320922874 +16.96875 0.1490777179904879 1008.013183593773 +17.0 0.1418577471119871 1012.513046264671 +17.03125 0.1353303711931278 1017.012908935569 +17.0625 0.1436528991104431 1021.512771606468 +17.09375 0.1472664606662112 1026.012634277367 +17.125 0.1234454704751765 1030.512496948265 +17.15625 0.1364810456185349 1035.012359619164 +17.1875 0.1452703757402087 1039.512222290062 +17.21875 0.151558096607376 1044.012084960961 +17.25 0.1437807634181667 1048.511947631859 +17.28125 0.1372932878525469 1053.011810302758 +17.3125 0.1460302780701482 1057.511672973656 +17.34375 0.149320031639015 1062.011535644554 +17.375 0.1256427569591505 1066.511398315453 +17.40625 0.1384081478964682 1071.011260986352 +17.4375 0.1478135356307372 1075.51112365725 +17.46875 0.1539460615922551 1080.010986328149 +17.5 0.1456910404241564 1084.510848999047 +17.53125 0.1392582263378612 1089.010711669946 +17.5625 0.1483559610229651 1093.510574340844 +17.59375 0.1513181838768209 1098.010437011743 +17.625 0.1277435288016546 1102.510299682641 +17.65625 0.1403378517935006 1107.010162353539 +17.6875 0.1503008487276927 1111.510025024438 +17.71875 0.1562707256982678 1116.009887695337 +17.75 0.1475671806734729 1120.509750366235 +17.78125 0.1412248824712325 1125.009613037134 +17.8125 0.150659328971417 1129.509475708032 +17.84375 0.1532766656979263 1134.009338378931 +17.875 0.1297824584132571 1138.509201049829 +17.90625 0.1422618854658679 1143.009063720728 +17.9375 0.1527256888451842 1147.508926391626 +17.96875 0.1584890480232386 1152.008789062525 +18.0 0.149405706732398 1156.508651733423 +18.03125 0.143171640792158 1161.008514404322 +18.0625 0.1529176761471478 1165.50837707522 +18.09375 0.1551977467377527 1170.008239746119 +18.125 0.131765400816527 1174.508102417017 +18.15625 0.1441938818980655 1179.007965087916 +18.1875 0.1550992225797607 1183.507827758814 +18.21875 0.1606570964232007 1188.007690429713 +18.25 0.1512058190790308 1192.507553100611 +18.28125 0.1451520205717164 1197.00741577151 +18.3125 0.1551183561850391 1201.507278442408 +18.34375 0.1570812889608072 1206.007141113307 +18.375 0.1336776271382248 1210.507003784206 +18.40625 0.1461136221129975 1215.006866455104 +18.4375 0.1574403087767436 1219.506729126002 +18.46875 0.1627479710117066 1224.006591796901 +18.5 0.1529973838232315 1228.506454467799 +18.53125 0.1471144758169647 1233.006317138698 +18.5625 0.157290873772812 1237.506179809596 +18.59375 0.1589416558445609 1242.006042480495 +18.625 0.1355352497255837 1246.505905151393 +18.65625 0.1480350786705765 1251.005767822292 +18.6875 0.1597404963023554 1255.50563049319 +18.71875 0.1647598358394601 1260.005493164089 +18.75 0.1547691158700678 1264.505355834987 +18.78125 0.1490751600212936 1269.005218505886 +18.8125 0.1594177692844409 1273.505081176784 +18.84375 0.1607950683386228 1278.004943847683 +18.875 0.1373442606771443 1282.504806518581 +18.90625 0.1499764982195686 1287.00466918948 +18.9375 0.161981916396387 1291.504531860378 +18.96875 0.1667161355701408 1296.004394531277 +19.0 0.1564970791017503 1300.504257202175 +19.03125 0.1510421101147244 1305.004119873074 +19.0625 0.1614940714004816 1309.503982543972 +19.09375 0.1626278045674801 1314.003845214871 +19.125 0.1391070684490964 1318.503707885769 +19.15625 0.1518963284417672 1323.003570556668 +19.1875 0.1641776433754442 1327.503433227566 +19.21875 0.1686227398941271 1332.003295898465 +19.25 0.158245898565777 1336.503158569363 +19.28125 0.153010602347685 1341.003021240262 +19.3125 0.1635401191148302 1345.50288391116 +19.34375 0.1644706200297989 1350.002746582059 +19.375 0.140837795269601 1354.502609252957 +19.40625 0.153819852891827 1359.002471923856 +19.4375 0.1663483805712817 1363.502334594754 +19.46875 0.1704527034458771 1368.002197265653 +19.5 0.1599450644585954 1372.502059936551 +19.53125 0.154992649837243 1377.00192260745 +19.5625 0.1655498824196527 1381.501785278348 +19.59375 0.1663063172499863 1386.001647949247 +19.625 0.142544544595813 1390.501510620146 +19.65625 0.1557303075785325 1395.001373291044 +19.6875 0.1684970432426142 1399.501235961942 +19.71875 0.17221935361306 1404.001098632841 +19.75 0.1616491616340551 1408.50096130374 +19.78125 0.1569578150703002 1413.000823974638 +19.8125 0.167533124847069 1417.500686645536 +19.84375 0.1681580952994133 1422.000549316435 +19.875 0.1442139440246979 1426.500411987333 +19.90625 0.1576452601836673 1431.000274658232 +19.9375 0.1706020388366926 1435.50013732913 +19.96875 0.1739429533647216 1440.000000000029 diff --git a/tests/circuitpython/traceback_test.py b/tests/circuitpython/traceback_test.py index 17c54c857a9..71888437a22 100644 --- a/tests/circuitpython/traceback_test.py +++ b/tests/circuitpython/traceback_test.py @@ -23,6 +23,22 @@ def fun(): print("\nLimit=-1 Trace:") print("".join(traceback.format_exception(None, exc, exc.__traceback__, limit=-1)), end="") +# value and tb must both be supplied or neither +print() +try: + fun() +except Exception as exc: + try: + traceback.print_exception(None, value=exc) + print("Should have raised ValueError for missing tb arg") + except ValueError: + print("ValueError for missing tb arg, as expected") + try: + traceback.print_exception(None, tb=None) + print("Should have raised ValueError for missing value arg") + except ValueError: + print("ValueError for missing value arg, as expected") + class NonNativeException(Exception): pass diff --git a/tests/circuitpython/traceback_test_chained.py b/tests/circuitpython/traceback_test_chained.py index 3b96eb7a3ca..46adfdb841a 100644 --- a/tests/circuitpython/traceback_test_chained.py +++ b/tests/circuitpython/traceback_test_chained.py @@ -73,9 +73,11 @@ def print_exc_info(e, chain=True): print_exc_info(e) print() + class SomeException(RuntimeError): pass + try: try: raise Exception("inner") diff --git a/tests/circuitpython/traceback_test_chained.py.exp b/tests/circuitpython/traceback_test_chained.py.exp index 498be1f0b79..9105ac1d98b 100644 --- a/tests/circuitpython/traceback_test_chained.py.exp +++ b/tests/circuitpython/traceback_test_chained.py.exp @@ -76,75 +76,75 @@ ZeroDivisionError: division by zero ------------------------------------------------------------------------ Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 81, in + File "circuitpython/traceback_test_chained.py", line 83, in Exception: inner During handling of the above exception, another exception occurred: Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 83, in + File "circuitpython/traceback_test_chained.py", line 85, in SomeException: outer ------------------------------------------------------------------------ ------------------------------------------------------------------------ Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 89, in + File "circuitpython/traceback_test_chained.py", line 91, in Exception: inner The above exception was the direct cause of the following exception: Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 92, in + File "circuitpython/traceback_test_chained.py", line 94, in SomeException: outer ------------------------------------------------------------------------ ------------------------------------------------------------------------ Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 99, in + File "circuitpython/traceback_test_chained.py", line 101, in RuntimeError: inner The above exception was the direct cause of the following exception: Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 101, in + File "circuitpython/traceback_test_chained.py", line 103, in Exception: outer ------------------------------------------------------------------------ ------------------------------------------------------------------------ Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 107, in + File "circuitpython/traceback_test_chained.py", line 109, in RuntimeError: inner The above exception was the direct cause of the following exception: Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 110, in + File "circuitpython/traceback_test_chained.py", line 112, in Exception: outer ------------------------------------------------------------------------ ------------------------------------------------------------------------ Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 117, in + File "circuitpython/traceback_test_chained.py", line 119, in RuntimeError: inner During handling of the above exception, another exception occurred: Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 119, in + File "circuitpython/traceback_test_chained.py", line 121, in SomeException: outer ------------------------------------------------------------------------ ------------------------------------------------------------------------ Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 125, in + File "circuitpython/traceback_test_chained.py", line 127, in RuntimeError: inner The above exception was the direct cause of the following exception: Traceback (most recent call last): - File "circuitpython/traceback_test_chained.py", line 128, in + File "circuitpython/traceback_test_chained.py", line 130, in SomeException: outer ------------------------------------------------------------------------ diff --git a/tests/cmdline/cmd_compile_only.py b/tests/cmdline/cmd_compile_only.py new file mode 100644 index 00000000000..89964c1b5bd --- /dev/null +++ b/tests/cmdline/cmd_compile_only.py @@ -0,0 +1,13 @@ +# cmdline: -X compile-only +# test compile-only functionality +print("This should not be printed") +x = 1 + 2 + + +def hello(): + return "world" + + +class TestClass: + def __init__(self): + self.value = 42 diff --git a/tests/cmdline/cmd_compile_only.py.exp b/tests/cmdline/cmd_compile_only.py.exp new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/cmdline/cmd_compile_only.py.exp @@ -0,0 +1 @@ + diff --git a/tests/cmdline/cmd_compile_only_error.py b/tests/cmdline/cmd_compile_only_error.py new file mode 100644 index 00000000000..326937a5c07 --- /dev/null +++ b/tests/cmdline/cmd_compile_only_error.py @@ -0,0 +1,6 @@ +# cmdline: -X compile-only +# test compile-only with syntax error +print("This should not be printed") +def broken_syntax( + # Missing closing parenthesis + return "error" diff --git a/tests/cmdline/cmd_compile_only_error.py.exp b/tests/cmdline/cmd_compile_only_error.py.exp new file mode 100644 index 00000000000..3911f71d624 --- /dev/null +++ b/tests/cmdline/cmd_compile_only_error.py.exp @@ -0,0 +1 @@ +CRASH \ No newline at end of file diff --git a/tests/cmdline/cmd_file_variable.py b/tests/cmdline/cmd_file_variable.py new file mode 100644 index 00000000000..6cac6744d90 --- /dev/null +++ b/tests/cmdline/cmd_file_variable.py @@ -0,0 +1,5 @@ +# Test that __file__ is set correctly for script execution +try: + print("__file__ =", __file__) +except NameError: + print("__file__ not defined") diff --git a/tests/cmdline/cmd_file_variable.py.exp b/tests/cmdline/cmd_file_variable.py.exp new file mode 100644 index 00000000000..6807569f662 --- /dev/null +++ b/tests/cmdline/cmd_file_variable.py.exp @@ -0,0 +1 @@ +__file__ = cmdline/cmd_file_variable.py diff --git a/tests/cmdline/cmd_module_atexit.py b/tests/cmdline/cmd_module_atexit.py new file mode 100644 index 00000000000..100bc112777 --- /dev/null +++ b/tests/cmdline/cmd_module_atexit.py @@ -0,0 +1,16 @@ +# cmdline: -m cmdline.cmd_module_atexit +# +# Test running as a module and using sys.atexit. + +import sys + +if not hasattr(sys, "atexit"): + print("SKIP") + raise SystemExit + +# Verify we ran as a module. +print(sys.argv) + +sys.atexit(lambda: print("done")) + +print("start") diff --git a/tests/cmdline/cmd_module_atexit.py.exp b/tests/cmdline/cmd_module_atexit.py.exp new file mode 100644 index 00000000000..2a0f756b1e7 --- /dev/null +++ b/tests/cmdline/cmd_module_atexit.py.exp @@ -0,0 +1,3 @@ +['cmdline.cmd_module_atexit', 'cmdline/cmd_module_atexit.py'] +start +done diff --git a/tests/cmdline/cmd_module_atexit_exc.py b/tests/cmdline/cmd_module_atexit_exc.py new file mode 100644 index 00000000000..88940a7741f --- /dev/null +++ b/tests/cmdline/cmd_module_atexit_exc.py @@ -0,0 +1,19 @@ +# cmdline: -m cmdline.cmd_module_atexit_exc +# +# Test running as a module and using sys.atexit, with script completion via sys.exit. + +import sys + +if not hasattr(sys, "atexit"): + print("SKIP") + raise SystemExit + +# Verify we ran as a module. +print(sys.argv) + +sys.atexit(lambda: print("done")) + +print("start") + +# This will raise SystemExit to finish the script, and atexit should still be run. +sys.exit(0) diff --git a/tests/cmdline/cmd_module_atexit_exc.py.exp b/tests/cmdline/cmd_module_atexit_exc.py.exp new file mode 100644 index 00000000000..6320d9d2d30 --- /dev/null +++ b/tests/cmdline/cmd_module_atexit_exc.py.exp @@ -0,0 +1,3 @@ +['cmdline.cmd_module_atexit_exc', 'cmdline/cmd_module_atexit_exc.py'] +start +done diff --git a/tests/cmdline/cmd_parsetree.py.exp b/tests/cmdline/cmd_parsetree.py.exp index 6ec553b8a9a..672c212a965 100644 --- a/tests/cmdline/cmd_parsetree.py.exp +++ b/tests/cmdline/cmd_parsetree.py.exp @@ -1,6 +1,6 @@ ---------------- [ 1] file_input_2(1) (n=10) - tok(6) + tok(5) [ 4] \(rule\|for_stmt\)(22) (n=4) id(i) [ 4] \(rule\|atom_paren\)(45) (n=1) @@ -9,7 +9,7 @@ NULL [ 6] \(rule\|expr_stmt\)(5) (n=2) id(a) - tok(16) + tok(15) [ 7] \(rule\|expr_stmt\)(5) (n=2) id(b) str(str) diff --git a/tests/cmdline/cmd_sys_exit_0.py b/tests/cmdline/cmd_sys_exit_0.py new file mode 100644 index 00000000000..1294b739e8f --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_0.py @@ -0,0 +1,5 @@ +# cmdline: +# test sys.exit(0) - success exit code +import sys + +sys.exit(0) diff --git a/tests/cmdline/cmd_sys_exit_0.py.exp b/tests/cmdline/cmd_sys_exit_0.py.exp new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_0.py.exp @@ -0,0 +1 @@ + diff --git a/tests/cmdline/cmd_sys_exit_error.py b/tests/cmdline/cmd_sys_exit_error.py new file mode 100644 index 00000000000..ecac15e94f1 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_error.py @@ -0,0 +1,5 @@ +# cmdline: +# test sys.exit() functionality and exit codes +import sys + +sys.exit(123) diff --git a/tests/cmdline/cmd_sys_exit_error.py.exp b/tests/cmdline/cmd_sys_exit_error.py.exp new file mode 100644 index 00000000000..3911f71d624 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_error.py.exp @@ -0,0 +1 @@ +CRASH \ No newline at end of file diff --git a/tests/cmdline/cmd_sys_exit_none.py b/tests/cmdline/cmd_sys_exit_none.py new file mode 100644 index 00000000000..66e19666589 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_none.py @@ -0,0 +1,5 @@ +# cmdline: +# test sys.exit(None) - should exit with code 0 +import sys + +sys.exit(None) diff --git a/tests/cmdline/cmd_sys_exit_none.py.exp b/tests/cmdline/cmd_sys_exit_none.py.exp new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/cmdline/cmd_sys_exit_none.py.exp @@ -0,0 +1 @@ + diff --git a/tests/cmdline/repl_autocomplete.py.exp b/tests/cmdline/repl_autocomplete.py.exp index 2e2397bb028..7840e52e8a4 100644 --- a/tests/cmdline/repl_autocomplete.py.exp +++ b/tests/cmdline/repl_autocomplete.py.exp @@ -1,5 +1,5 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # tests for autocompletion >>> import sys >>> not_exist. @@ -11,4 +11,4 @@ Use \.\+ >>> i.lower('ABC') 'abc' >>> None. ->>> +>>> \$ diff --git a/tests/cmdline/repl_autocomplete_underscore.py b/tests/cmdline/repl_autocomplete_underscore.py new file mode 100644 index 00000000000..e685a7fe7ff --- /dev/null +++ b/tests/cmdline/repl_autocomplete_underscore.py @@ -0,0 +1,33 @@ +# Test REPL autocompletion filtering of underscore attributes + +# Start paste mode +{\x05} +class TestClass: + def __init__(self): + self.public_attr = 1 + self._private_attr = 2 + self.__very_private = 3 + + def public_method(self): + pass + + def _private_method(self): + pass + + @property + def public_property(self): + return 42 + + @property + def _private_property(self): + return 99 + +{\x04} +# Paste executed + +# Create an instance +obj = TestClass() + +# Test tab completion on the instance +# The tab character after `obj.` and 'a' below triggers the completions +obj.{\x09}{\x09}a{\x09} diff --git a/tests/cmdline/repl_autocomplete_underscore.py.exp b/tests/cmdline/repl_autocomplete_underscore.py.exp new file mode 100644 index 00000000000..98e6c2aeb05 --- /dev/null +++ b/tests/cmdline/repl_autocomplete_underscore.py.exp @@ -0,0 +1,41 @@ + +Adafruit CircuitPython \.\+ version +>>> # Test REPL autocompletion filtering of underscore attributes +>>> \$ +>>> # Start paste mode +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== class TestClass: +=== def __init__(self): +=== self.public_attr = 1 +=== self._private_attr = 2 +=== self.__very_private = 3 +=== \$ +=== def public_method(self): +=== pass +=== \$ +=== def _private_method(self): +=== pass +=== \$ +=== @property +=== def public_property(self): +=== return 42 +=== \$ +=== @property +=== def _private_property(self): +=== return 99 +=== \$ +=== \$ +>>> # Paste executed +>>> \$ +>>> # Create an instance +>>> obj = TestClass() +>>> \$ +>>> # Test tab completion on the instance +>>> # The tab character after `obj.` and 'a' below triggers the completions +>>> obj.public_ +public_attr public_method public_property +>>> obj.public_attr +1 +>>> \$ diff --git a/tests/cmdline/repl_autoindent.py.exp b/tests/cmdline/repl_autoindent.py.exp index 9ff83a92870..04f00686b20 100644 --- a/tests/cmdline/repl_autoindent.py.exp +++ b/tests/cmdline/repl_autoindent.py.exp @@ -1,22 +1,22 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # tests for autoindent >>> if 1: ... print(1) -... -... -... +... \$ +... \$ +... \$ 1 >>> if 0: ...  print(2) ... else: ... print(3) -... +... \$ 3 >>> if 0: ... print(4) ... else: ... print(5) -... +... \$ 5 ->>> +>>> \$ diff --git a/tests/cmdline/repl_basic.py.exp b/tests/cmdline/repl_basic.py.exp index 26442b64455..5bdcc9d6d32 100644 --- a/tests/cmdline/repl_basic.py.exp +++ b/tests/cmdline/repl_basic.py.exp @@ -1,5 +1,5 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # basic REPL tests >>> print(1) 1 @@ -7,4 +7,4 @@ Use \.\+ 1 >>> 2 2 ->>> +>>> \$ diff --git a/tests/cmdline/repl_cont.py.exp b/tests/cmdline/repl_cont.py.exp index 6eed4a3e02c..41f2436ac18 100644 --- a/tests/cmdline/repl_cont.py.exp +++ b/tests/cmdline/repl_cont.py.exp @@ -1,5 +1,5 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # check REPL allows to continue input >>> 1 \\\\ ... + 2 @@ -54,4 +54,4 @@ two >>> if1 = 2 >>> print(if1) 2 ->>> +>>> \$ diff --git a/tests/cmdline/repl_emacs_keys.py.exp b/tests/cmdline/repl_emacs_keys.py.exp index 2e8667a8e6c..4979f8bbfc3 100644 --- a/tests/cmdline/repl_emacs_keys.py.exp +++ b/tests/cmdline/repl_emacs_keys.py.exp @@ -1,5 +1,5 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # REPL tests of GNU-ish readline navigation >>> # history buffer navigation >>> 1 @@ -16,4 +16,4 @@ Use \.\+ >>> t = 121 >>> \.\+ 'foobar' ->>> +>>> \$ diff --git a/tests/cmdline/repl_inspect.py.exp b/tests/cmdline/repl_inspect.py.exp index 8ece5ffc37f..30257f31aab 100644 --- a/tests/cmdline/repl_inspect.py.exp +++ b/tests/cmdline/repl_inspect.py.exp @@ -1,6 +1,6 @@ test -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # cmdline: -i -c print("test") >>> # -c option combined with -i option results in REPL ->>> +>>> \$ diff --git a/tests/cmdline/repl_lock.py b/tests/cmdline/repl_lock.py new file mode 100644 index 00000000000..77e2e932740 --- /dev/null +++ b/tests/cmdline/repl_lock.py @@ -0,0 +1,7 @@ +import micropython +micropython.heap_lock() +1+1 +micropython.heap_lock() +None # Cause the repl's line storage to be enlarged ---------------- +micropython.heap_lock() +raise SystemExit diff --git a/tests/cmdline/repl_lock.py.exp b/tests/cmdline/repl_lock.py.exp new file mode 100644 index 00000000000..e6d63fcf200 --- /dev/null +++ b/tests/cmdline/repl_lock.py.exp @@ -0,0 +1,10 @@ + +Adafruit CircuitPython \.\+ version +>>> import micropython +>>> micropython.heap_lock() +>>> 1+1 +2 +>>> micropython.heap_lock() +>>> None # Cause the repl's line storage to be enlarged ---------------- +>>> micropython.heap_lock() +>>> raise SystemExit diff --git a/tests/cmdline/repl_micropyinspect.py.exp b/tests/cmdline/repl_micropyinspect.py.exp index 3c9cbc030c0..36bef37c62c 100644 --- a/tests/cmdline/repl_micropyinspect.py.exp +++ b/tests/cmdline/repl_micropyinspect.py.exp @@ -1,5 +1,5 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # cmdline: cmdline/repl_micropyinspect >>> # setting MICROPYINSPECT environment variable before program exit triggers REPL ->>> +>>> \$ diff --git a/tests/cmdline/repl_paste.py b/tests/cmdline/repl_paste.py new file mode 100644 index 00000000000..7cec450fce7 --- /dev/null +++ b/tests/cmdline/repl_paste.py @@ -0,0 +1,90 @@ +# Test REPL paste mode functionality + +# Basic paste mode with a simple function +{\x05} +def hello(): + print('Hello from paste mode!') +hello() +{\x04} + +# Paste mode with multiple indentation levels +{\x05} +def calculate(n): + if n > 0: + for i in range(n): + if i % 2 == 0: + print(f'Even: {i}') + else: + print(f'Odd: {i}') + else: + print('n must be positive') + +calculate(5) +{\x04} + +# Paste mode with blank lines +{\x05} +def function_with_blanks(): + print('First line') + + print('After blank line') + + + print('After two blank lines') + +function_with_blanks() +{\x04} + +# Paste mode with class definition and multiple methods +{\x05} +class TestClass: + def __init__(self, value): + self.value = value + + def display(self): + print(f'Value is: {self.value}') + + def double(self): + self.value *= 2 + return self.value + +obj = TestClass(21) +obj.display() +print(f'Doubled: {obj.double()}') +obj.display() +{\x04} + +# Paste mode with exception handling +{\x05} +try: + x = 1 / 0 +except ZeroDivisionError: + print('Caught division by zero') +finally: + print('Finally block executed') +{\x04} + +# Cancel paste mode with Ctrl-C +{\x05} +print('This should not execute') +{\x03} + +# Normal REPL still works after cancelled paste +print('Back to normal REPL') + +# Paste mode with syntax error +{\x05} +def bad_syntax(: + print('Missing parameter') +{\x04} + +# Paste mode with runtime error +{\x05} +def will_error(): + undefined_variable + +will_error() +{\x04} + +# Final test to show REPL is still functioning +1 + 2 + 3 diff --git a/tests/cmdline/repl_paste.py.exp b/tests/cmdline/repl_paste.py.exp new file mode 100644 index 00000000000..cc5ac2f0800 --- /dev/null +++ b/tests/cmdline/repl_paste.py.exp @@ -0,0 +1,133 @@ + +Adafruit CircuitPython \.\+ version +>>> # Test REPL paste mode functionality +>>> \$ +>>> # Basic paste mode with a simple function +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== def hello(): +=== print('Hello from paste mode!') +=== hello() +=== \$ +Hello from paste mode! +>>> \$ +>>> # Paste mode with multiple indentation levels +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== def calculate(n): +=== if n > 0: +=== for i in range(n): +=== if i % 2 == 0: +=== print(f'Even: {i}') +=== else: +=== print(f'Odd: {i}') +=== else: +=== print('n must be positive') +=== \$ +=== calculate(5) +=== \$ +Even: 0 +Odd: 1 +Even: 2 +Odd: 3 +Even: 4 +>>> \$ +>>> # Paste mode with blank lines +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== def function_with_blanks(): +=== print('First line') +=== \$ +=== print('After blank line') +=== \$ +=== \$ +=== print('After two blank lines') +=== \$ +=== function_with_blanks() +=== \$ +First line +After blank line +After two blank lines +>>> \$ +>>> # Paste mode with class definition and multiple methods +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== class TestClass: +=== def __init__(self, value): +=== self.value = value +=== \$ +=== def display(self): +=== print(f'Value is: {self.value}') +=== \$ +=== def double(self): +=== self.value *= 2 +=== return self.value +=== \$ +=== obj = TestClass(21) +=== obj.display() +=== print(f'Doubled: {obj.double()}') +=== obj.display() +=== \$ +Value is: 21 +Doubled: 42 +Value is: 42 +>>> \$ +>>> # Paste mode with exception handling +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== try: +=== x = 1 / 0 +=== except ZeroDivisionError: +=== print('Caught division by zero') +=== finally: +=== print('Finally block executed') +=== \$ +Caught division by zero +Finally block executed +>>> \$ +>>> # Cancel paste mode with Ctrl-C +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== print('This should not execute') +=== \$ +>>> \$ +>>> \$ +>>> # Normal REPL still works after cancelled paste +>>> print('Back to normal REPL') +Back to normal REPL +>>> \$ +>>> # Paste mode with syntax error +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== def bad_syntax(: +=== print('Missing parameter') +=== \$ +Traceback (most recent call last): + File "", line 2 +SyntaxError: invalid syntax +>>> \$ +>>> # Paste mode with runtime error +>>> \$ +paste mode; Ctrl-C to cancel, Ctrl-D to finish +=== \$ +=== def will_error(): +=== undefined_variable +=== \$ +=== will_error() +=== \$ +Traceback (most recent call last): + File "", line 5, in + File "", line 3, in will_error +NameError: name 'undefined_variable' isn't defined +>>> \$ +>>> # Final test to show REPL is still functioning +>>> 1 + 2 + 3 +6 +>>> \$ diff --git a/tests/cmdline/repl_sys_ps1_ps2.py.exp b/tests/cmdline/repl_sys_ps1_ps2.py.exp index 452a54fe5ae..d4bcf7a44d5 100644 --- a/tests/cmdline/repl_sys_ps1_ps2.py.exp +++ b/tests/cmdline/repl_sys_ps1_ps2.py.exp @@ -1,5 +1,5 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # test changing ps1/ps2 >>> import sys >>> sys.ps1 = "PS1" diff --git a/tests/cmdline/repl_words_move.py.exp b/tests/cmdline/repl_words_move.py.exp index ba5c3648cff..41ad3d8e733 100644 --- a/tests/cmdline/repl_words_move.py.exp +++ b/tests/cmdline/repl_words_move.py.exp @@ -1,5 +1,5 @@ -CircuitPython \.\+ version -Use \.\+ + +Adafruit CircuitPython \.\+ version >>> # word movement >>> # backward-word, start in word >>> \.\+ @@ -19,7 +19,7 @@ Use \.\+ >>> # forward-word on eol. if cursor is moved, this will result in a SyntaxError >>> \.\+ 6 ->>> +>>> \$ >>> # kill word >>> # backward-kill-word, start in word >>> \.\+ @@ -33,7 +33,7 @@ Use \.\+ >>> # forward-kill-word, don't start in word >>> \.\+ 3 ->>> +>>> \$ >>> # extra move/kill shortcuts >>> # ctrl-left >>> \.\+ @@ -44,4 +44,4 @@ Use \.\+ >>> # ctrl-w >>> \.\+ 1 ->>> +>>> \$ diff --git a/tests/cpydiff/builtin_next_arg2.py b/tests/cpydiff/builtin_next_arg2.py deleted file mode 100644 index 5df2d6e70f8..00000000000 --- a/tests/cpydiff/builtin_next_arg2.py +++ /dev/null @@ -1,12 +0,0 @@ -""" -categories: Modules,builtins -description: Second argument to next() is not implemented -cause: MicroPython is optimised for code space. -workaround: Instead of ``val = next(it, deflt)`` use:: - - try: - val = next(it) - except StopIteration: - val = deflt -""" -print(next(iter(range(0)), 42)) diff --git a/tests/cpydiff/core_class_delnotimpl.py b/tests/cpydiff/core_class_delnotimpl.py index 18c176e9bb1..6fac764ac98 100644 --- a/tests/cpydiff/core_class_delnotimpl.py +++ b/tests/cpydiff/core_class_delnotimpl.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Unknown """ + import gc diff --git a/tests/cpydiff/core_class_initsubclass.py b/tests/cpydiff/core_class_initsubclass.py new file mode 100644 index 00000000000..8683271dcb0 --- /dev/null +++ b/tests/cpydiff/core_class_initsubclass.py @@ -0,0 +1,21 @@ +""" +categories: Core,Classes +description: ``__init_subclass__`` isn't automatically called. +cause: MicroPython does not currently implement PEP 487. +workaround: Manually call ``__init_subclass__`` after class creation if needed. e.g.:: + + class A(Base): + pass + A.__init_subclass__() + +""" + + +class Base: + @classmethod + def __init_subclass__(cls): + print(f"Base.__init_subclass__({cls.__name__})") + + +class A(Base): + pass diff --git a/tests/cpydiff/core_class_initsubclass_autoclassmethod.py b/tests/cpydiff/core_class_initsubclass_autoclassmethod.py new file mode 100644 index 00000000000..b2f7628976c --- /dev/null +++ b/tests/cpydiff/core_class_initsubclass_autoclassmethod.py @@ -0,0 +1,31 @@ +""" +categories: Core,Classes +description: ``__init_subclass__`` isn't an implicit classmethod. +cause: MicroPython does not currently implement PEP 487. ``__init_subclass__`` is not currently in the list of special-cased class/static methods. +workaround: Decorate declarations of ``__init_subclass__`` with ``@classmethod``. +""" + + +def regularize_spelling(text, prefix="bound_"): + # for regularizing across the CPython "method" vs MicroPython "bound_method" spelling for the type of a bound classmethod + if text.startswith(prefix): + return text[len(prefix) :] + return text + + +class A: + def __init_subclass__(cls): + pass + + @classmethod + def manual_decorated(cls): + pass + + +a = type(A.__init_subclass__).__name__ +b = type(A.manual_decorated).__name__ + +print(regularize_spelling(a)) +print(regularize_spelling(b)) +if a != b: + print("FAIL") diff --git a/tests/cpydiff/core_class_initsubclass_kwargs.py b/tests/cpydiff/core_class_initsubclass_kwargs.py new file mode 100644 index 00000000000..ed5157afeae --- /dev/null +++ b/tests/cpydiff/core_class_initsubclass_kwargs.py @@ -0,0 +1,22 @@ +""" +categories: Core,Classes +description: MicroPython doesn't support parameterized ``__init_subclass__`` class customization. +cause: MicroPython does not currently implement PEP 487. The MicroPython syntax tree does not include a kwargs node after the class inheritance list. +workaround: Use class variables or another mechanism to specify base-class customizations. +""" + + +class Base: + @classmethod + def __init_subclass__(cls, arg=None, **kwargs): + cls.init_subclass_was_called = True + print(f"Base.__init_subclass__({cls.__name__}, {arg=!r}, {kwargs=!r})") + + +class A(Base, arg="arg"): + pass + + +# Regularize across MicroPython not automatically calling __init_subclass__ either. +if not getattr(A, "init_subclass_was_called", False): + A.__init_subclass__() diff --git a/tests/cpydiff/core_class_initsubclass_super.py b/tests/cpydiff/core_class_initsubclass_super.py new file mode 100644 index 00000000000..d18671a74bf --- /dev/null +++ b/tests/cpydiff/core_class_initsubclass_super.py @@ -0,0 +1,22 @@ +""" +categories: Core,Classes +description: ``__init_subclass__`` can't be defined a cooperatively-recursive way. +cause: MicroPython does not currently implement PEP 487. The base object type does not have an ``__init_subclass__`` implementation. +workaround: Omit the recursive ``__init_subclass__`` call unless it's known that the grandparent also defines it. +""" + + +class Base: + @classmethod + def __init_subclass__(cls, **kwargs): + cls.init_subclass_was_called = True + super().__init_subclass__(**kwargs) + + +class A(Base): + pass + + +# Regularize across MicroPython not automatically calling __init_subclass__ either. +if not getattr(A, "init_subclass_was_called", False): + A.__init_subclass__() diff --git a/tests/cpydiff/core_class_super_init.py b/tests/cpydiff/core_class_super_init.py new file mode 100644 index 00000000000..1774f61dd82 --- /dev/null +++ b/tests/cpydiff/core_class_super_init.py @@ -0,0 +1,31 @@ +""" +categories: Core,Classes +description: When inheriting native types, calling a method in ``__init__(self, ...)`` before ``super().__init__()`` raises an ``AttributeError`` (or segfaults if ``MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG`` is not enabled). +cause: MicroPython does not have separate ``__new__`` and ``__init__`` methods in native types. +workaround: Call ``super().__init__()`` first. +""" + + +class L1(list): + def __init__(self, a): + self.append(a) + + +try: + L1(1) + print("OK") +except AttributeError: + print("AttributeError") + + +class L2(list): + def __init__(self, a): + super().__init__() + self.append(a) + + +try: + L2(1) + print("OK") +except AttributeError: + print("AttributeError") diff --git a/tests/cpydiff/core_fstring_concat.py b/tests/cpydiff/core_fstring_concat.py index c2bdb4e666a..2fbe1b961a1 100644 --- a/tests/cpydiff/core_fstring_concat.py +++ b/tests/cpydiff/core_fstring_concat.py @@ -1,13 +1,14 @@ """ -categories: Core -description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces or are f-strings +categories: Core,f-strings +description: f-strings don't support concatenation with adjacent literals if the adjacent literals contain braces cause: MicroPython is optimised for code space. -workaround: Use the + operator between literal strings when either or both are f-strings +workaround: Use the + operator between literal strings when they are not both f-strings """ x, y = 1, 2 +# fmt: off print("aa" f"{x}") # works print(f"{x}" "ab") # works print("a{}a" f"{x}") # fails print(f"{x}" "a{}b") # fails -print(f"{x}" f"{y}") # fails +# fmt: on diff --git a/tests/cpydiff/core_fstring_parser.py b/tests/cpydiff/core_fstring_parser.py index 22bbc5866ec..4964b9707ac 100644 --- a/tests/cpydiff/core_fstring_parser.py +++ b/tests/cpydiff/core_fstring_parser.py @@ -1,9 +1,10 @@ """ -categories: Core +categories: Core,f-strings description: f-strings cannot support expressions that require parsing to resolve unbalanced nested braces and brackets cause: MicroPython is optimised for code space. workaround: Always use balanced braces and brackets in expressions inside f-strings """ -print(f'{"hello { world"}') -print(f'{"hello ] world"}') +# CIRCUITPY-CHANGE: add noqa so ruff won't complain about unmatched braces +print(f"{'hello { world'}") # noqa +print(f"{'hello ] world'}") # noqa diff --git a/tests/cpydiff/core_fstring_raw.py b/tests/cpydiff/core_fstring_raw.py deleted file mode 100644 index 84e265f70fc..00000000000 --- a/tests/cpydiff/core_fstring_raw.py +++ /dev/null @@ -1,8 +0,0 @@ -""" -categories: Core -description: Raw f-strings are not supported -cause: MicroPython is optimised for code space. -workaround: Unknown -""" - -rf"hello" diff --git a/tests/cpydiff/core_fstring_repr.py b/tests/cpydiff/core_fstring_repr.py index d37fb48db75..2589a34b7e3 100644 --- a/tests/cpydiff/core_fstring_repr.py +++ b/tests/cpydiff/core_fstring_repr.py @@ -1,5 +1,5 @@ """ -categories: Core +categories: Core,f-strings description: f-strings don't support !a conversions cause: MicropPython does not implement ascii() workaround: None diff --git a/tests/cpydiff/core_function_argcount.py b/tests/cpydiff/core_function_argcount.py index 5f3dca4dcdb..c257def726a 100644 --- a/tests/cpydiff/core_function_argcount.py +++ b/tests/cpydiff/core_function_argcount.py @@ -4,6 +4,7 @@ cause: MicroPython counts "self" as an argument. workaround: Interpret error messages with the information above in mind. """ + try: [].append() except Exception as e: diff --git a/tests/cpydiff/core_import_all.py b/tests/cpydiff/core_import_all.py deleted file mode 100644 index 5adf9ae3eb1..00000000000 --- a/tests/cpydiff/core_import_all.py +++ /dev/null @@ -1,9 +0,0 @@ -""" -categories: Core,import -description: __all__ is unsupported in __init__.py in MicroPython. -cause: Not implemented. -workaround: Manually import the sub-modules directly in __init__.py using ``from . import foo, bar``. -""" -from modules3 import * - -foo.hello() diff --git a/tests/cpydiff/core_import_path.py b/tests/cpydiff/core_import_path.py index 959fd571f57..2028386be84 100644 --- a/tests/cpydiff/core_import_path.py +++ b/tests/cpydiff/core_import_path.py @@ -4,6 +4,7 @@ cause: MicroPython doesn't support namespace packages split across filesystem. Beyond that, MicroPython's import system is highly optimized for minimal memory usage. workaround: Details of import handling is inherently implementation dependent. Don't rely on such details in portable applications. """ + import modules print(modules.__path__) diff --git a/tests/cpydiff/core_import_split_ns_pkgs.py b/tests/cpydiff/core_import_split_ns_pkgs.py index 5c92b63124a..a1cfd84893d 100644 --- a/tests/cpydiff/core_import_split_ns_pkgs.py +++ b/tests/cpydiff/core_import_split_ns_pkgs.py @@ -4,6 +4,7 @@ cause: MicroPython's import system is highly optimized for simplicity, minimal memory usage, and minimal filesystem search overhead. workaround: Don't install modules belonging to the same namespace package in different directories. For MicroPython, it's recommended to have at most 3-component module search paths: for your current application, per-user (writable), system-wide (non-writable). """ + import sys sys.path.append(sys.path[1] + "/modules") diff --git a/tests/cpydiff/core_locals_eval.py b/tests/cpydiff/core_locals_eval.py index 025d2263729..3f6ad2a1dbb 100644 --- a/tests/cpydiff/core_locals_eval.py +++ b/tests/cpydiff/core_locals_eval.py @@ -4,6 +4,7 @@ cause: MicroPython doesn't maintain symbolic local environment, it is optimized to an array of slots. Thus, local variables can't be accessed by a name. Effectively, ``eval(expr)`` in MicroPython is equivalent to ``eval(expr, globals(), globals())``. workaround: Unknown """ + val = 1 diff --git a/tests/cpydiff/module_array_comparison.py b/tests/cpydiff/module_array_comparison.py index a442af3f5bc..4929b1e590d 100644 --- a/tests/cpydiff/module_array_comparison.py +++ b/tests/cpydiff/module_array_comparison.py @@ -4,6 +4,7 @@ cause: Code size workaround: Compare individual elements """ + import array array.array("b", [1, 2]) == array.array("i", [1, 2]) diff --git a/tests/cpydiff/module_array_constructor.py b/tests/cpydiff/module_array_constructor.py index 08cf2ef2d1c..a53589d22ae 100644 --- a/tests/cpydiff/module_array_constructor.py +++ b/tests/cpydiff/module_array_constructor.py @@ -4,6 +4,7 @@ cause: MicroPython implements implicit truncation in order to reduce code size and execution time workaround: If CPython compatibility is needed then mask the value explicitly """ + import array a = array.array("b", [257]) diff --git a/tests/cpydiff/modules3/__init__.py b/tests/cpydiff/modules3/__init__.py deleted file mode 100644 index 27a2bf2ad90..00000000000 --- a/tests/cpydiff/modules3/__init__.py +++ /dev/null @@ -1 +0,0 @@ -__all__ = ["foo"] diff --git a/tests/cpydiff/modules3/foo.py b/tests/cpydiff/modules3/foo.py deleted file mode 100644 index dd9b9d4ddd4..00000000000 --- a/tests/cpydiff/modules3/foo.py +++ /dev/null @@ -1,2 +0,0 @@ -def hello(): - print("hello") diff --git a/tests/cpydiff/modules_array_containment.py b/tests/cpydiff/modules_array_containment.py index 8f25b0d4914..b29895aa758 100644 --- a/tests/cpydiff/modules_array_containment.py +++ b/tests/cpydiff/modules_array_containment.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Unknown """ + import array print(1 in array.array("B", b"12")) diff --git a/tests/cpydiff/modules_array_deletion.py b/tests/cpydiff/modules_array_deletion.py index 3376527373e..2e7c31124b2 100644 --- a/tests/cpydiff/modules_array_deletion.py +++ b/tests/cpydiff/modules_array_deletion.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Unknown """ + import array a = array.array("b", (1, 2, 3)) diff --git a/tests/cpydiff/modules_array_subscrstep.py b/tests/cpydiff/modules_array_subscrstep.py index 24308bd9042..65b12332f54 100644 --- a/tests/cpydiff/modules_array_subscrstep.py +++ b/tests/cpydiff/modules_array_subscrstep.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Unknown """ + import array a = array.array("b", (1, 2, 3)) diff --git a/tests/cpydiff/modules_deque.py b/tests/cpydiff/modules_deque.py index 4d2746d1f86..9eb9edbda62 100644 --- a/tests/cpydiff/modules_deque.py +++ b/tests/cpydiff/modules_deque.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Use regular lists. micropython-lib has implementation of collections.deque. """ + import collections D = collections.deque() diff --git a/tests/cpydiff/modules_errno_enotsup.py b/tests/cpydiff/modules_errno_enotsup.py new file mode 100644 index 00000000000..80e5ad9d032 --- /dev/null +++ b/tests/cpydiff/modules_errno_enotsup.py @@ -0,0 +1,10 @@ +""" +categories: Modules,errno +description: MicroPython does not include ``ENOTSUP`` as a name for errno 95. +cause: MicroPython does not implement the ``ENOTSUP`` canonical alias for ``EOPNOTSUPP`` added in CPython 3.2. +workaround: Use ``errno.EOPNOTSUPP`` in place of ``errno.ENOTSUP``. +""" + +import errno + +print(f"{errno.errorcode[errno.EOPNOTSUPP]=!s}") diff --git a/tests/cpydiff/modules_json_nonserializable.py b/tests/cpydiff/modules_json_nonserializable.py index ffe523786f5..d83e7beca2d 100644 --- a/tests/cpydiff/modules_json_nonserializable.py +++ b/tests/cpydiff/modules_json_nonserializable.py @@ -4,12 +4,10 @@ cause: Unknown workaround: Unknown """ + import json -a = bytes(x for x in range(256)) try: - z = json.dumps(a) - x = json.loads(z) - print("Should not get here") + print(json.dumps(b"shouldn't be able to serialise bytes")) except TypeError: print("TypeError") diff --git a/tests/cpydiff/modules_os_environ.py b/tests/cpydiff/modules_os_environ.py index 491d8a31016..4edde166567 100644 --- a/tests/cpydiff/modules_os_environ.py +++ b/tests/cpydiff/modules_os_environ.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Use ``getenv``, ``putenv`` and ``unsetenv`` """ + import os try: diff --git a/tests/cpydiff/modules_os_getenv.py b/tests/cpydiff/modules_os_getenv.py index d1e828438e4..d5acd414eb3 100644 --- a/tests/cpydiff/modules_os_getenv.py +++ b/tests/cpydiff/modules_os_getenv.py @@ -4,6 +4,7 @@ cause: The ``environ`` attribute is not implemented workaround: Unknown """ + import os print(os.getenv("NEW_VARIABLE")) diff --git a/tests/cpydiff/modules_struct_fewargs.py b/tests/cpydiff/modules_struct_fewargs.py index cb6b0fd874e..f6346a67938 100644 --- a/tests/cpydiff/modules_struct_fewargs.py +++ b/tests/cpydiff/modules_struct_fewargs.py @@ -1,9 +1,10 @@ """ categories: Modules,struct -description: Struct pack with too few args, not checked by uPy +description: Struct pack with too few args, not checked by MicroPython cause: Unknown workaround: Unknown """ + import struct try: diff --git a/tests/cpydiff/modules_struct_manyargs.py b/tests/cpydiff/modules_struct_manyargs.py index 03395baad3b..b2ea93b6c93 100644 --- a/tests/cpydiff/modules_struct_manyargs.py +++ b/tests/cpydiff/modules_struct_manyargs.py @@ -1,9 +1,10 @@ """ categories: Modules,struct -description: Struct pack with too many args, not checked by uPy +description: Struct pack with too many args, not checked by MicroPython cause: Unknown workaround: Unknown """ + import struct try: diff --git a/tests/cpydiff/modules_struct_whitespace_in_format.py b/tests/cpydiff/modules_struct_whitespace_in_format.py index a882b38569a..8b609425eb0 100644 --- a/tests/cpydiff/modules_struct_whitespace_in_format.py +++ b/tests/cpydiff/modules_struct_whitespace_in_format.py @@ -1,9 +1,10 @@ """ categories: Modules,struct -description: Struct pack with whitespace in format, whitespace ignored by CPython, error on uPy +description: Struct pack with whitespace in format, whitespace ignored by CPython, error on MicroPython cause: MicroPython is optimised for code size. workaround: Don't use spaces in format strings. """ + import struct try: diff --git a/tests/cpydiff/modules_sys_stdassign.py b/tests/cpydiff/modules_sys_stdassign.py index 7d086078a93..29afe1b1203 100644 --- a/tests/cpydiff/modules_sys_stdassign.py +++ b/tests/cpydiff/modules_sys_stdassign.py @@ -4,6 +4,7 @@ cause: They are stored in read-only memory. workaround: Unknown """ + import sys sys.stdin = None diff --git a/tests/cpydiff/syntax_arg_unpacking.py b/tests/cpydiff/syntax_arg_unpacking.py index e54832ddb91..7133a8a2827 100644 --- a/tests/cpydiff/syntax_arg_unpacking.py +++ b/tests/cpydiff/syntax_arg_unpacking.py @@ -1,5 +1,5 @@ """ -categories: Syntax +categories: Syntax,Unpacking description: Argument unpacking does not work if the argument being unpacked is the nth or greater argument where n is the number of bits in an MP_SMALL_INT. cause: The implementation uses an MP_SMALL_INT to flag args that need to be unpacked. workaround: Use fewer arguments. diff --git a/tests/cpydiff/syntax_assign_expr.py b/tests/cpydiff/syntax_assign_expr.py index d4ed063b39a..704c5c3ecab 100644 --- a/tests/cpydiff/syntax_assign_expr.py +++ b/tests/cpydiff/syntax_assign_expr.py @@ -1,7 +1,8 @@ """ categories: Syntax,Operators -description: MicroPython allows using := to assign to the variable of a comprehension, CPython raises a SyntaxError. -cause: MicroPython is optimised for code size and doesn't check this case. -workaround: Do not rely on this behaviour if writing CPython compatible code. +description: MicroPython allows := to assign to the iteration variable in nested comprehensions, CPython does not. +cause: MicroPython is optimised for code size. Although it is a syntax error to assign to the iteration variable in a standard comprehension (same as CPython), it doesn't check if an inner nested comprehension assigns to the iteration variable of the outer comprehension. +workaround: Do not use := to assign to the iteration variable of a comprehension. """ -print([i := -1 for i in range(4)]) + +print([[(j := i) for i in range(2)] for j in range(2)]) diff --git a/tests/cpydiff/syntax_literal_underscore.py b/tests/cpydiff/syntax_literal_underscore.py new file mode 100644 index 00000000000..4b1406e9f3f --- /dev/null +++ b/tests/cpydiff/syntax_literal_underscore.py @@ -0,0 +1,19 @@ +""" +categories: Syntax,Literals +description: MicroPython accepts underscores in numeric literals where CPython doesn't +cause: Different parser implementation + +MicroPython's tokenizer ignores underscores in numeric literals, while CPython +rejects multiple consecutive underscores and underscores after the last digit. + +workaround: Remove the underscores not accepted by CPython. +""" + +try: + print(eval("1__1")) +except SyntaxError: + print("Should not work") +try: + print(eval("1_")) +except SyntaxError: + print("Should not work") diff --git a/tests/cpydiff/syntax_spaces.py b/tests/cpydiff/syntax_spaces.py index c308240a78d..670cefdeac2 100644 --- a/tests/cpydiff/syntax_spaces.py +++ b/tests/cpydiff/syntax_spaces.py @@ -1,9 +1,17 @@ """ -categories: Syntax,Spaces -description: uPy requires spaces between literal numbers and keywords, CPy doesn't -cause: Unknown -workaround: Unknown +categories: Syntax,Literals +description: MicroPython requires spaces between literal numbers and keywords or ".", CPython doesn't +cause: Different parser implementation + +MicroPython's tokenizer treats a sequence like ``1and`` as a single token, while CPython treats it as two tokens. + +Since CPython 3.11, when the literal number is followed by a token, this syntax causes a ``SyntaxWarning`` for an "invalid literal". When a literal number is followed by a "." denoting attribute access, CPython does not warn. + +workaround: Add a space between the integer literal and the intended next token. + +This also fixes the ``SyntaxWarning`` in CPython. """ + try: print(eval("1and 0")) except SyntaxError: @@ -16,3 +24,7 @@ print(eval("1if 1else 0")) except SyntaxError: print("Should have worked") +try: + print(eval("0x1.to_bytes(1)")) +except SyntaxError: + print("Should have worked") diff --git a/tests/cpydiff/syntax_unicode_nameesc.py b/tests/cpydiff/syntax_unicode_nameesc.py index 21628c974d8..838394b6ebd 100644 --- a/tests/cpydiff/syntax_unicode_nameesc.py +++ b/tests/cpydiff/syntax_unicode_nameesc.py @@ -4,4 +4,5 @@ cause: Unknown workaround: Unknown """ + print("\N{LATIN SMALL LETTER A}") diff --git a/tests/cpydiff/types_bytearray_sliceassign.py b/tests/cpydiff/types_bytearray_sliceassign.py index e4068b04b98..353f61988fa 100644 --- a/tests/cpydiff/types_bytearray_sliceassign.py +++ b/tests/cpydiff/types_bytearray_sliceassign.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Unknown """ + b = bytearray(4) b[0:1] = [1, 2] print(b) diff --git a/tests/cpydiff/types_bytes_format.py b/tests/cpydiff/types_bytes_format.py index ad049877116..1a15e572c8a 100644 --- a/tests/cpydiff/types_bytes_format.py +++ b/tests/cpydiff/types_bytes_format.py @@ -4,4 +4,5 @@ cause: MicroPython strives to be a more regular implementation, so if both `str` and `bytes` support ``__mod__()`` (the % operator), it makes sense to support ``format()`` for both too. Support for ``__mod__`` can also be compiled out, which leaves only ``format()`` for bytes formatting. workaround: If you are interested in CPython compatibility, don't use ``.format()`` on bytes objects. """ + print(b"{}".format(1)) diff --git a/tests/cpydiff/types_bytes_keywords.py b/tests/cpydiff/types_bytes_keywords.py index ade83d0a709..a459c94b41e 100644 --- a/tests/cpydiff/types_bytes_keywords.py +++ b/tests/cpydiff/types_bytes_keywords.py @@ -4,4 +4,5 @@ cause: Unknown workaround: Pass the encoding as a positional parameter, e.g. ``print(bytes('abc', 'utf-8'))`` """ + print(bytes("abc", encoding="utf8")) diff --git a/tests/cpydiff/types_bytes_subscrstep.py b/tests/cpydiff/types_bytes_subscrstep.py index 51b94cb710f..c566cbdb630 100644 --- a/tests/cpydiff/types_bytes_subscrstep.py +++ b/tests/cpydiff/types_bytes_subscrstep.py @@ -4,4 +4,5 @@ cause: MicroPython is highly optimized for memory usage. workaround: Use explicit loop for this very rare operation. """ + print(b"123"[0:3:2]) diff --git a/tests/cpydiff/types_complex_parser.py b/tests/cpydiff/types_complex_parser.py new file mode 100644 index 00000000000..4a012987d9e --- /dev/null +++ b/tests/cpydiff/types_complex_parser.py @@ -0,0 +1,14 @@ +""" +categories: Types,complex +description: MicroPython's complex() accepts certain incorrect values that CPython rejects +cause: MicroPython is highly optimized for memory usage. +workaround: Do not use non-standard complex literals as argument to complex() + +MicroPython's ``complex()`` function accepts literals that contain a space and +no sign between the real and imaginary parts, and interprets it as a plus. +""" + +try: + print(complex("1 1j")) +except ValueError: + print("ValueError") diff --git a/tests/cpydiff/types_dict_keys_set.py b/tests/cpydiff/types_dict_keys_set.py index 3a0849a3556..a5f127962e6 100644 --- a/tests/cpydiff/types_dict_keys_set.py +++ b/tests/cpydiff/types_dict_keys_set.py @@ -4,4 +4,5 @@ cause: Not implemented. workaround: Explicitly convert keys to a set before using set operations. """ + print({1: 2, 3: 4}.keys() & {1}) diff --git a/tests/cpydiff/types_exception_attrs.py b/tests/cpydiff/types_exception_attrs.py index ad72b62a61a..5fed45451d2 100644 --- a/tests/cpydiff/types_exception_attrs.py +++ b/tests/cpydiff/types_exception_attrs.py @@ -4,6 +4,7 @@ cause: MicroPython is optimised to reduce code size. workaround: Only use ``value`` on ``StopIteration`` exceptions, and ``errno`` on ``OSError`` exceptions. Do not use or rely on these attributes on other exceptions. """ + e = Exception(1) print(e.value) print(e.errno) diff --git a/tests/cpydiff/types_exception_chaining.py b/tests/cpydiff/types_exception_chaining.py index 836c4eb3e73..cff68d4124a 100644 --- a/tests/cpydiff/types_exception_chaining.py +++ b/tests/cpydiff/types_exception_chaining.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Unknown """ + try: raise TypeError except TypeError: diff --git a/tests/cpydiff/types_exception_instancevar.py b/tests/cpydiff/types_exception_instancevar.py index adc353361f0..fb67771baf3 100644 --- a/tests/cpydiff/types_exception_instancevar.py +++ b/tests/cpydiff/types_exception_instancevar.py @@ -4,6 +4,7 @@ cause: MicroPython is highly optimized for memory usage. workaround: Use user-defined exception subclasses. """ + e = Exception() e.x = 0 print(e.x) diff --git a/tests/cpydiff/types_exception_loops.py b/tests/cpydiff/types_exception_loops.py index 8d326cbbbb0..549f1dd0a5b 100644 --- a/tests/cpydiff/types_exception_loops.py +++ b/tests/cpydiff/types_exception_loops.py @@ -4,6 +4,7 @@ cause: Condition checks are optimized to happen at the end of loop body, and that line number is reported. workaround: Unknown """ + l = ["-foo", "-bar"] i = 0 diff --git a/tests/cpydiff/types_float_implicit_conversion.py b/tests/cpydiff/types_float_implicit_conversion.py index 3726839fac6..764c9e4e6ed 100644 --- a/tests/cpydiff/types_float_implicit_conversion.py +++ b/tests/cpydiff/types_float_implicit_conversion.py @@ -1,6 +1,6 @@ """ categories: Types,float -description: uPy allows implicit conversion of objects in maths operations while CPython does not. +description: MicroPython allows implicit conversion of objects in maths operations while CPython does not. cause: Unknown workaround: Objects should be wrapped in ``float(obj)`` for compatibility with CPython. """ diff --git a/tests/cpydiff/types_float_rounding.py b/tests/cpydiff/types_float_rounding.py deleted file mode 100644 index a5b591966b0..00000000000 --- a/tests/cpydiff/types_float_rounding.py +++ /dev/null @@ -1,7 +0,0 @@ -""" -categories: Types,float -description: uPy and CPython outputs formats may differ -cause: Unknown -workaround: Unknown -""" -print("%.1g" % -9.9) diff --git a/tests/cpydiff/types_int_to_bytes.py b/tests/cpydiff/types_int_to_bytes.py new file mode 100644 index 00000000000..6530a2a32ec --- /dev/null +++ b/tests/cpydiff/types_int_to_bytes.py @@ -0,0 +1,16 @@ +""" +categories: Types,int +description: ``to_bytes`` method doesn't implement signed parameter. +cause: The ``signed`` keyword-only parameter is not implemented for ``int.to_bytes()``. + +When the integer is negative, MicroPython behaves the same as CPython ``int.to_bytes(..., signed=True)`` + +When the integer is non-negative, MicroPython behaves the same as CPython ``int.to_bytes(..., signed=False)``. + +(The difference is subtle, but in CPython a positive integer converted with ``signed=True`` may require one byte more in the output length, in order to fit the 0 sign bit.) + +workaround: Take care when calling ``to_bytes()`` on an integer value which may be negative. +""" + +x = -1 +print(x.to_bytes(1, "big")) diff --git a/tests/cpydiff/types_list_delete_subscrstep.py b/tests/cpydiff/types_list_delete_subscrstep.py index 36e6f526b3d..3c801d84949 100644 --- a/tests/cpydiff/types_list_delete_subscrstep.py +++ b/tests/cpydiff/types_list_delete_subscrstep.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Use explicit loop for this rare operation. """ + l = [1, 2, 3, 4] del l[0:4:2] print(l) diff --git a/tests/cpydiff/types_list_store_noniter.py b/tests/cpydiff/types_list_store_noniter.py index 1d69b4a8231..581b1369801 100644 --- a/tests/cpydiff/types_list_store_noniter.py +++ b/tests/cpydiff/types_list_store_noniter.py @@ -4,6 +4,7 @@ cause: RHS is restricted to be a tuple or list workaround: Use ``list()`` on RHS to convert the iterable to a list """ + l = [10, 20] l[0:1] = range(4) print(l) diff --git a/tests/cpydiff/types_list_store_subscrstep.py b/tests/cpydiff/types_list_store_subscrstep.py index 1460372bb17..97590267f4a 100644 --- a/tests/cpydiff/types_list_store_subscrstep.py +++ b/tests/cpydiff/types_list_store_subscrstep.py @@ -4,6 +4,7 @@ cause: Unknown workaround: Use explicit loop for this rare operation. """ + l = [1, 2, 3, 4] l[0:4:2] = [5, 6] print(l) diff --git a/tests/cpydiff/types_memoryview_invalid.py b/tests/cpydiff/types_memoryview_invalid.py index c995a2e8991..f288c50ab57 100644 --- a/tests/cpydiff/types_memoryview_invalid.py +++ b/tests/cpydiff/types_memoryview_invalid.py @@ -6,6 +6,7 @@ In the worst case scenario, resizing an object which is the target of a memoryview can cause the memoryview(s) to reference invalid freed memory (a use-after-free bug) and corrupt the MicroPython runtime. workaround: Do not change the size of any ``bytearray`` or ``io.bytesIO`` object that has a ``memoryview`` assigned to it. """ + b = bytearray(b"abcdefg") m = memoryview(b) b.extend(b"hijklmnop") diff --git a/tests/cpydiff/types_oserror_errnomap.py b/tests/cpydiff/types_oserror_errnomap.py new file mode 100644 index 00000000000..6627bd2af4a --- /dev/null +++ b/tests/cpydiff/types_oserror_errnomap.py @@ -0,0 +1,48 @@ +""" +categories: Types,OSError +description: OSError constructor returns a plain OSError for all errno values, rather than a relevant subtype. +cause: MicroPython does not include the CPython-standard OSError subclasses. +workaround: Catch OSError and use its errno attribute to discriminate the cause. +""" + +import errno + +errno_list = [ # i.e. the set implemented by micropython + errno.EPERM, + errno.ENOENT, + errno.EIO, + errno.EBADF, + errno.EAGAIN, + errno.ENOMEM, + errno.EACCES, + errno.EEXIST, + errno.ENODEV, + errno.EISDIR, + errno.EINVAL, + errno.EOPNOTSUPP, + errno.EADDRINUSE, + errno.ECONNABORTED, + errno.ECONNRESET, + errno.ENOBUFS, + errno.ENOTCONN, + errno.ETIMEDOUT, + errno.ECONNREFUSED, + errno.EHOSTUNREACH, + errno.EALREADY, + errno.EINPROGRESS, +] + + +def errno_output_type(n): + try: + raise OSError(n, "") + except OSError as e: + return f"{type(e).__name__}" + except Exception as e: + return f"non-OSError {type(e).__name__}" + else: + return "no error" + + +for n in errno_list: + print(errno.errorcode[n], "=", errno_output_type(n)) diff --git a/tests/cpydiff/types_range_limits.py b/tests/cpydiff/types_range_limits.py new file mode 100644 index 00000000000..e53d5fd4088 --- /dev/null +++ b/tests/cpydiff/types_range_limits.py @@ -0,0 +1,26 @@ +""" +categories: Types,range +description: Range objects with large start or stop arguments misbehave. +cause: Intermediate calculations overflow the C mp_int_t type +workaround: Avoid using such ranges +""" + +from sys import maxsize + +# A range including `maxsize-1` cannot be created +try: + print(range(-maxsize - 1, 0)) +except OverflowError: + print("OverflowError") + +# A range with `stop-start` exceeding sys.maxsize has incorrect len(), while CPython cannot calculate len(). +try: + print(len(range(-maxsize, maxsize))) +except OverflowError: + print("OverflowError") + +# A range with `stop-start` exceeding sys.maxsize has incorrect len() +try: + print(len(range(-maxsize, maxsize, maxsize))) +except OverflowError: + print("OverflowError") diff --git a/tests/cpydiff/types_str_endswith.py b/tests/cpydiff/types_str_endswith.py deleted file mode 100644 index f222ac1cd3a..00000000000 --- a/tests/cpydiff/types_str_endswith.py +++ /dev/null @@ -1,7 +0,0 @@ -""" -categories: Types,str -description: Start/end indices such as str.endswith(s, start) not implemented -cause: Unknown -workaround: Unknown -""" -print("abc".endswith("c", 1)) diff --git a/tests/cpydiff/types_str_formatsep.py b/tests/cpydiff/types_str_formatsep.py new file mode 100644 index 00000000000..05d0b8d3d2c --- /dev/null +++ b/tests/cpydiff/types_str_formatsep.py @@ -0,0 +1,19 @@ +""" +categories: Types,str +description: MicroPython accepts the "," grouping option with any radix, unlike CPython +cause: To reduce code size, MicroPython does not issue an error for this combination +workaround: Do not use a format string like ``{:,b}`` if CPython compatibility is required. +""" + +try: + print("{:,b}".format(99)) +except ValueError: + print("ValueError") +try: + print("{:,x}".format(99)) +except ValueError: + print("ValueError") +try: + print("{:,o}".format(99)) +except ValueError: + print("ValueError") diff --git a/tests/cpydiff/types_str_formatsep_float.py b/tests/cpydiff/types_str_formatsep_float.py new file mode 100644 index 00000000000..b487cd3758e --- /dev/null +++ b/tests/cpydiff/types_str_formatsep_float.py @@ -0,0 +1,11 @@ +""" +categories: Types,str +description: MicroPython accepts but does not properly implement the "," or "_" grouping character for float values +cause: To reduce code size, MicroPython does not implement this combination. Grouping characters will not appear in the number's significant digits and will appear at incorrect locations in leading zeros. +workaround: Do not use a format string like ``{:,f}`` if exact CPython compatibility is required. +""" + +print("{:,f}".format(3141.159)) +print("{:_f}".format(3141.159)) +print("{:011,.2f}".format(3141.159)) +print("{:011_.2f}".format(3141.159)) diff --git a/tests/cpydiff/types_str_formatsubscr.py b/tests/cpydiff/types_str_formatsubscr.py index 1b83cfff6cd..5c59a1d200a 100644 --- a/tests/cpydiff/types_str_formatsubscr.py +++ b/tests/cpydiff/types_str_formatsubscr.py @@ -4,4 +4,5 @@ cause: Unknown workaround: Unknown """ + print("{a[0]}".format(a=[1, 2])) diff --git a/tests/cpydiff/types_str_keywords.py b/tests/cpydiff/types_str_keywords.py index 77a4eac1c1d..640dfa6c391 100644 --- a/tests/cpydiff/types_str_keywords.py +++ b/tests/cpydiff/types_str_keywords.py @@ -4,4 +4,5 @@ cause: Unknown workaround: Input the encoding format directly. eg ``print(bytes('abc', 'utf-8'))`` """ + print(str(b"abc", encoding="utf8")) diff --git a/tests/cpydiff/types_str_ljust_rjust.py b/tests/cpydiff/types_str_ljust_rjust.py index 72e5105e025..7f91c137e90 100644 --- a/tests/cpydiff/types_str_ljust_rjust.py +++ b/tests/cpydiff/types_str_ljust_rjust.py @@ -4,4 +4,5 @@ cause: MicroPython is highly optimized for memory usage. Easy workarounds available. workaround: Instead of ``s.ljust(10)`` use ``"%-10s" % s``, instead of ``s.rjust(10)`` use ``"% 10s" % s``. Alternatively, ``"{:<10}".format(s)`` or ``"{:>10}".format(s)``. """ + print("abc".ljust(10)) diff --git a/tests/cpydiff/types_str_rsplitnone.py b/tests/cpydiff/types_str_rsplitnone.py index 5d334fea2f8..ae524620a08 100644 --- a/tests/cpydiff/types_str_rsplitnone.py +++ b/tests/cpydiff/types_str_rsplitnone.py @@ -4,4 +4,5 @@ cause: Unknown workaround: Unknown """ + print("a a a".rsplit(None, 1)) diff --git a/tests/cpydiff/types_str_subscrstep.py b/tests/cpydiff/types_str_subscrstep.py index 2d3245e5582..cd57f18ccb3 100644 --- a/tests/cpydiff/types_str_subscrstep.py +++ b/tests/cpydiff/types_str_subscrstep.py @@ -4,4 +4,5 @@ cause: Unknown workaround: Unknown """ + print("abcdefghi"[0:9:2]) diff --git a/tests/cpydiff/types_tuple_subscrstep.py b/tests/cpydiff/types_tuple_subscrstep.py index f90f3c5bf4d..60ba31af4cf 100644 --- a/tests/cpydiff/types_tuple_subscrstep.py +++ b/tests/cpydiff/types_tuple_subscrstep.py @@ -4,4 +4,5 @@ cause: Unknown workaround: Unknown """ + print((1, 2, 3, 4)[0:4:2]) diff --git a/tests/extmod/asyncio_basic.py.exp b/tests/extmod/asyncio_basic.py.exp deleted file mode 100644 index 478e22abc8f..00000000000 --- a/tests/extmod/asyncio_basic.py.exp +++ /dev/null @@ -1,6 +0,0 @@ -start -after sleep -short -long -negative -took 200 400 0 diff --git a/tests/extmod/asyncio_event_fair.py b/tests/extmod/asyncio_event_fair.py index ebbf3222114..b878cabfe1b 100644 --- a/tests/extmod/asyncio_event_fair.py +++ b/tests/extmod/asyncio_event_fair.py @@ -12,6 +12,7 @@ async def foo(): return 42 + try: fooc = foo() fooc.__await__ diff --git a/tests/extmod/asyncio_event_queue.py b/tests/extmod/asyncio_event_queue.py new file mode 100644 index 00000000000..e0125b1aefe --- /dev/null +++ b/tests/extmod/asyncio_event_queue.py @@ -0,0 +1,64 @@ +# Ensure that an asyncio task can wait on an Event when the +# _task_queue is empty +# https://github.com/micropython/micropython/issues/16569 + +try: + import asyncio +except ImportError: + print("SKIP") + raise SystemExit + +# This test requires checking that the asyncio scheduler +# remains active "indefinitely" when the task queue is empty. +# +# To check this, we need another independent scheduler that +# can wait for a certain amount of time. So we have to +# create one using micropython.schedule() and time.ticks_ms() +# +# Technically, this code breaks the rules, as it is clearly +# documented that Event.set() should _NOT_ be called from a +# schedule (soft IRQ) because in some cases, a race condition +# can occur, resulting in a crash. However: +# - since the risk of a race condition in that specific +# case has been analysed and excluded +# - given that there is no other simple alternative to +# write this test case, +# an exception to the rule was deemed acceptable. See +# https://github.com/micropython/micropython/pull/16772 + +import micropython, time + +try: + micropython.schedule +except AttributeError: + print("SKIP") + raise SystemExit + + +evt = asyncio.Event() + + +def schedule_watchdog(end_ticks): + if time.ticks_diff(end_ticks, time.ticks_ms()) <= 0: + print("asyncio still pending, unlocking event") + # Caution: about to call Event.set() from a schedule + # (see the note in the comment above) + evt.set() + return + micropython.schedule(schedule_watchdog, end_ticks) + + +async def foo(): + print("foo waiting") + schedule_watchdog(time.ticks_add(time.ticks_ms(), 100)) + await evt.wait() + print("foo done") + + +async def main(): + print("main started") + await foo() + print("main done") + + +asyncio.run(main()) diff --git a/tests/extmod/asyncio_event_queue.py.exp b/tests/extmod/asyncio_event_queue.py.exp new file mode 100644 index 00000000000..ee42c96d83e --- /dev/null +++ b/tests/extmod/asyncio_event_queue.py.exp @@ -0,0 +1,5 @@ +main started +foo waiting +asyncio still pending, unlocking event +foo done +main done diff --git a/tests/extmod/asyncio_get_event_loop.py b/tests/extmod/asyncio_get_event_loop.py index c9cfa7bf00e..6ecbb13b57a 100644 --- a/tests/extmod/asyncio_get_event_loop.py +++ b/tests/extmod/asyncio_get_event_loop.py @@ -1,5 +1,4 @@ # Test get_event_loop() -# Note: CPython deprecated get_event_loop() so this test needs a .exp try: import asyncio diff --git a/tests/extmod/asyncio_get_event_loop.py.exp b/tests/extmod/asyncio_get_event_loop.py.exp deleted file mode 100644 index 5d0fb3b2d2e..00000000000 --- a/tests/extmod/asyncio_get_event_loop.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -start -end diff --git a/tests/extmod/asyncio_heaplock.py b/tests/extmod/asyncio_heaplock.py index 8326443f0e6..9e9908de1cb 100644 --- a/tests/extmod/asyncio_heaplock.py +++ b/tests/extmod/asyncio_heaplock.py @@ -4,7 +4,11 @@ # - StreamWriter.write, stream is blocked and data to write is a bytes object # - StreamWriter.write, when stream is not blocked -import micropython +try: + import asyncio, micropython +except ImportError: + print("SKIP") + raise SystemExit # strict stackless builds can't call functions without allocating a frame on the heap try: @@ -24,12 +28,6 @@ def f(x): print("SKIP") raise SystemExit -try: - import asyncio -except ImportError: - print("SKIP") - raise SystemExit - class TestStream: def __init__(self, blocked): diff --git a/tests/extmod/asyncio_iterator_event.py b/tests/extmod/asyncio_iterator_event.py new file mode 100644 index 00000000000..f61fefcf051 --- /dev/null +++ b/tests/extmod/asyncio_iterator_event.py @@ -0,0 +1,86 @@ +# Ensure that an asyncio task can wait on an Event when the +# _task_queue is empty, in the context of an async iterator +# https://github.com/micropython/micropython/issues/16318 + +try: + import asyncio +except ImportError: + print("SKIP") + raise SystemExit + +# This test requires checking that the asyncio scheduler +# remains active "indefinitely" when the task queue is empty. +# +# To check this, we need another independent scheduler that +# can wait for a certain amount of time. So we have to +# create one using micropython.schedule() and time.ticks_ms() +# +# Technically, this code breaks the rules, as it is clearly +# documented that Event.set() should _NOT_ be called from a +# schedule (soft IRQ) because in some cases, a race condition +# can occur, resulting in a crash. However: +# - since the risk of a race condition in that specific +# case has been analysed and excluded +# - given that there is no other simple alternative to +# write this test case, +# an exception to the rule was deemed acceptable. See +# https://github.com/micropython/micropython/pull/16772 + +import micropython, time + +try: + micropython.schedule +except AttributeError: + print("SKIP") + raise SystemExit + +ai = None + + +def schedule_watchdog(end_ticks): + if time.ticks_diff(end_ticks, time.ticks_ms()) <= 0: + print("good: asyncio iterator is still pending, exiting") + # Caution: ai.fetch_data() will invoke Event.set() + # (see the note in the comment above) + ai.fetch_data(None) + return + micropython.schedule(schedule_watchdog, end_ticks) + + +async def test(ai): + for x in range(3): + await asyncio.sleep(0.1) + ai.fetch_data("bar {}".format(x)) + + +class AsyncIterable: + def __init__(self): + self.message = None + self.evt = asyncio.Event() + + def __aiter__(self): + return self + + async def __anext__(self): + await self.evt.wait() + self.evt.clear() + if self.message is None: + raise StopAsyncIteration + return self.message + + def fetch_data(self, message): + self.message = message + self.evt.set() + + +async def main(): + global ai + ai = AsyncIterable() + asyncio.create_task(test(ai)) + schedule_watchdog(time.ticks_add(time.ticks_ms(), 500)) + async for message in ai: + print(message) + print("end main") + + +asyncio.run(main()) diff --git a/tests/extmod/asyncio_iterator_event.py.exp b/tests/extmod/asyncio_iterator_event.py.exp new file mode 100644 index 00000000000..a1893197d02 --- /dev/null +++ b/tests/extmod/asyncio_iterator_event.py.exp @@ -0,0 +1,5 @@ +bar 0 +bar 1 +bar 2 +good: asyncio iterator is still pending, exiting +end main diff --git a/tests/extmod/asyncio_lock.py.exp b/tests/extmod/asyncio_lock.py.exp deleted file mode 100644 index a37dfcbd2e5..00000000000 --- a/tests/extmod/asyncio_lock.py.exp +++ /dev/null @@ -1,41 +0,0 @@ -False -True -False -have lock ----- -task start 1 -task start 2 -task start 3 -task have 1 0 -task have 2 0 -task have 3 0 -task have 1 1 -task have 2 1 -task have 3 1 -task have 1 2 -task end 1 -task have 2 2 -task end 2 -task have 3 2 -task end 3 ----- -task have True -task release False -task have True -task release False -task have again -task have again ----- -task got 0 -task release 0 -task cancel 1 -task got 2 -task release 2 -False ----- -task got 0 -task cancel 1 -task release 0 -task got 2 -task cancel 2 -False diff --git a/tests/extmod/asyncio_micropython.py.exp b/tests/extmod/asyncio_micropython.py.exp index f5be1dc75a2..4d1c6d681f2 100644 --- a/tests/extmod/asyncio_micropython.py.exp +++ b/tests/extmod/asyncio_micropython.py.exp @@ -1,4 +1,5 @@ True +OverflowError task start 1 task end 1 2 diff --git a/tests/extmod/asyncio_new_event_loop.py b/tests/extmod/asyncio_new_event_loop.py index 5bb31f1292b..3f05ffdd551 100644 --- a/tests/extmod/asyncio_new_event_loop.py +++ b/tests/extmod/asyncio_new_event_loop.py @@ -1,5 +1,4 @@ # Test Loop.new_event_loop() -# Note: CPython deprecated get_event_loop() so this test needs a .exp try: import asyncio @@ -7,6 +6,21 @@ print("SKIP") raise SystemExit +# CPython 3.12 deprecated calling get_event_loop() when there is no current event +# loop, so to make this test run on CPython requires setting the event loop. +if hasattr(asyncio, "set_event_loop"): + asyncio.set_event_loop(asyncio.new_event_loop()) + + +def exception_handler(loop, context): + # This is a workaround for a difference between CPython and MicroPython: if + # a CPython event loop is closed while there are tasks pending (i.e. not finished) + # on it, then the task will log an error. MicroPython does not log this error. + if context.get("message", "") == "Task was destroyed but it is pending!": + pass + else: + loop.default_exception_handler(context) + async def task(): for i in range(4): @@ -18,17 +32,21 @@ async def task(): async def main(): print("start") loop.create_task(task()) - await asyncio.sleep(0) + await asyncio.sleep(0) # yields, meaning new task will run once print("stop") loop.stop() # Use default event loop to run some tasks loop = asyncio.get_event_loop() +loop.set_exception_handler(exception_handler) loop.create_task(main()) loop.run_forever() +loop.close() # Create new event loop, old one should not keep running loop = asyncio.new_event_loop() +loop.set_exception_handler(exception_handler) loop.create_task(main()) loop.run_forever() +loop.close() diff --git a/tests/extmod/asyncio_new_event_loop.py.exp b/tests/extmod/asyncio_new_event_loop.py.exp deleted file mode 100644 index 9e104fda39c..00000000000 --- a/tests/extmod/asyncio_new_event_loop.py.exp +++ /dev/null @@ -1,6 +0,0 @@ -start -task 0 -stop -start -task 0 -stop diff --git a/tests/extmod/asyncio_set_exception_handler.py b/tests/extmod/asyncio_set_exception_handler.py index 5935f0f4ebe..0ac4a624224 100644 --- a/tests/extmod/asyncio_set_exception_handler.py +++ b/tests/extmod/asyncio_set_exception_handler.py @@ -12,7 +12,7 @@ def custom_handler(loop, context): async def task(i): - # Raise with 2 args so exception prints the same in uPy and CPython + # Raise with 2 args so exception prints the same in MicroPython and CPython raise ValueError(i, i + 1) diff --git a/tests/extmod/asyncio_wait_for_linked_task.py b/tests/extmod/asyncio_wait_for_linked_task.py new file mode 100644 index 00000000000..4dda62d5476 --- /dev/null +++ b/tests/extmod/asyncio_wait_for_linked_task.py @@ -0,0 +1,66 @@ +# Test asyncio.wait_for, with dependent tasks +# https://github.com/micropython/micropython/issues/16759 + +try: + import asyncio +except ImportError: + print("SKIP") + raise SystemExit + + +# CPython 3.12 deprecated calling get_event_loop() when there is no current event +# loop, so to make this test run on CPython requires setting the event loop. +if hasattr(asyncio, "set_event_loop"): + asyncio.set_event_loop(asyncio.new_event_loop()) + + +class Worker: + def __init__(self): + self._eventLoop = None + self._tasks = [] + + def launchTask(self, asyncJob): + if self._eventLoop is None: + self._eventLoop = asyncio.get_event_loop() + return self._eventLoop.create_task(asyncJob) + + async def job(self, prerequisite, taskName): + if prerequisite: + await prerequisite + await asyncio.sleep(0.1) + print(taskName, "work completed") + + def planTasks(self): + self._tasks.append(self.launchTask(self.job(None, "task0"))) + self._tasks.append(self.launchTask(self.job(self._tasks[0], "task1"))) + self._tasks.append(self.launchTask(self.job(self._tasks[1], "task2"))) + + async def waitForTask(self, taskIdx): + return await self._tasks[taskIdx] + + def syncWaitForTask(self, taskIdx): + return self._eventLoop.run_until_complete(self._tasks[taskIdx]) + + +async def async_test(): + print("--- async test") + worker = Worker() + worker.planTasks() + await worker.waitForTask(0) + print("-> task0 done") + await worker.waitForTask(2) + print("-> task2 done") + + +def sync_test(): + print("--- sync test") + worker = Worker() + worker.planTasks() + worker.syncWaitForTask(0) + print("-> task0 done") + worker.syncWaitForTask(2) + print("-> task2 done") + + +asyncio.get_event_loop().run_until_complete(async_test()) +sync_test() diff --git a/tests/extmod/asyncio_wait_task.py.exp b/tests/extmod/asyncio_wait_task.py.exp deleted file mode 100644 index 514a4342233..00000000000 --- a/tests/extmod/asyncio_wait_task.py.exp +++ /dev/null @@ -1,12 +0,0 @@ -start -task 1 -task 2 ----- -start -hello -world -took 200 200 -task_raise -ValueError -task_raise -ValueError diff --git a/tests/extmod/binascii_hexlify.py b/tests/extmod/binascii_hexlify.py index d06029aabaf..ae90b673365 100644 --- a/tests/extmod/binascii_hexlify.py +++ b/tests/extmod/binascii_hexlify.py @@ -1,5 +1,5 @@ try: - import binascii + from binascii import hexlify except ImportError: print("SKIP") raise SystemExit @@ -10,10 +10,10 @@ b"\x7f\x80\xff", b"1234ABCDabcd", ): - print(binascii.hexlify(x)) + print(hexlify(x)) # Two-argument version (now supported in CPython) -print(binascii.hexlify(b"123", ":")) +print(hexlify(b"123", ":")) # zero length buffer -print(binascii.hexlify(b"", b":")) +print(hexlify(b"", b":")) diff --git a/tests/extmod/binascii_unhexlify.py b/tests/extmod/binascii_unhexlify.py index 731b6a2bd4d..b08704cba65 100644 --- a/tests/extmod/binascii_unhexlify.py +++ b/tests/extmod/binascii_unhexlify.py @@ -1,5 +1,5 @@ try: - import binascii + from binascii import unhexlify except ImportError: print("SKIP") raise SystemExit @@ -10,18 +10,18 @@ b"7f80ff", b"313233344142434461626364", ): - print(binascii.unhexlify(x)) + print(unhexlify(x)) # CIRCUITPY-CHANGE # Unicode strings can be decoded -print(binascii.unhexlify("313233344142434461626364")) +print(unhexlify("313233344142434461626364")) try: - a = binascii.unhexlify(b"0") # odd buffer length + a = unhexlify(b"0") # odd buffer length except ValueError: print("ValueError") try: - a = binascii.unhexlify(b"gg") # digit not hex + a = unhexlify(b"gg") # digit not hex except ValueError: print("ValueError") diff --git a/tests/extmod/deflate_compress_memory_error.py b/tests/extmod/deflate_compress_memory_error.py new file mode 100644 index 00000000000..19bef87bff3 --- /dev/null +++ b/tests/extmod/deflate_compress_memory_error.py @@ -0,0 +1,39 @@ +# Test deflate.DeflateIO compression, with out-of-memory errors. + +try: + # Check if deflate is available. + import deflate + import io +except ImportError: + print("SKIP") + raise SystemExit + +# Check if compression is enabled. +if not hasattr(deflate.DeflateIO, "write"): + print("SKIP") + raise SystemExit + +# Create a compressor object. +b = io.BytesIO() +g = deflate.DeflateIO(b, deflate.RAW, 15) + +# Then, use up most of the heap. +l = [] +while True: + try: + l.append(bytearray(1000)) + except: + break +l.pop() + +# Try to compress. This will try to allocate a large window and fail. +try: + g.write("test") +except MemoryError: + print("MemoryError") + +# Should still be able to close the stream. +g.close() + +# The underlying output stream should be unchanged. +print(b.getvalue()) diff --git a/tests/extmod/deflate_compress_memory_error.py.exp b/tests/extmod/deflate_compress_memory_error.py.exp new file mode 100644 index 00000000000..606315c1460 --- /dev/null +++ b/tests/extmod/deflate_compress_memory_error.py.exp @@ -0,0 +1,2 @@ +MemoryError +b'' diff --git a/tests/extmod/framebuf_blit.py b/tests/extmod/framebuf_blit.py new file mode 100644 index 00000000000..b1d98b330a8 --- /dev/null +++ b/tests/extmod/framebuf_blit.py @@ -0,0 +1,68 @@ +# Test FrameBuffer.blit method. + +try: + import framebuf +except ImportError: + print("SKIP") + raise SystemExit + + +def printbuf(): + print("--8<--") + for y in range(h): + for x in range(w): + print("%02x" % buf[(x + y * w)], end="") + print() + print("-->8--") + + +w = 5 +h = 4 +buf = bytearray(w * h) +fbuf = framebuf.FrameBuffer(buf, w, h, framebuf.GS8) + +fbuf2 = framebuf.FrameBuffer(bytearray(4), 2, 2, framebuf.GS8) +fbuf2.fill(0xFF) + +# Blit another FrameBuffer, at various locations. +for x, y in ((-1, -1), (0, 0), (1, 1), (4, 3)): + fbuf.fill(0) + fbuf.blit(fbuf2, x, y) + printbuf() + +# Blit a bytes object. +fbuf.fill(0) +image = (b"\x10\x11\x12\x13", 2, 2, framebuf.GS8) +fbuf.blit(image, 1, 1) +printbuf() + +# Blit a bytes object that has a stride. +fbuf.fill(0) +image = (b"\x20\x21\xff\x22\x23\xff", 2, 2, framebuf.GS8, 3) +fbuf.blit(image, 1, 1) +printbuf() + +# Blit a bytes object with a bytes palette. +fbuf.fill(0) +image = (b"\x00\x01\x01\x00", 2, 2, framebuf.GS8) +palette = (b"\xa1\xa2", 2, 1, framebuf.GS8) +fbuf.blit(image, 1, 1, -1, palette) +printbuf() + +# Not enough elements in the tuple. +try: + fbuf.blit((0, 0, 0), 0, 0) +except ValueError: + print("ValueError") + +# Too many elements in the tuple. +try: + fbuf.blit((0, 0, 0, 0, 0, 0), 0, 0) +except ValueError: + print("ValueError") + +# Bytes too small. +try: + fbuf.blit((b"", 1, 1, framebuf.GS8), 0, 0) +except ValueError: + print("ValueError") diff --git a/tests/extmod/framebuf_blit.py.exp b/tests/extmod/framebuf_blit.py.exp new file mode 100644 index 00000000000..e340f1990c7 --- /dev/null +++ b/tests/extmod/framebuf_blit.py.exp @@ -0,0 +1,45 @@ +--8<-- +ff00000000 +0000000000 +0000000000 +0000000000 +-->8-- +--8<-- +ffff000000 +ffff000000 +0000000000 +0000000000 +-->8-- +--8<-- +0000000000 +00ffff0000 +00ffff0000 +0000000000 +-->8-- +--8<-- +0000000000 +0000000000 +0000000000 +00000000ff +-->8-- +--8<-- +0000000000 +0010110000 +0012130000 +0000000000 +-->8-- +--8<-- +0000000000 +0020210000 +0022230000 +0000000000 +-->8-- +--8<-- +0000000000 +00a1a20000 +00a2a10000 +0000000000 +-->8-- +ValueError +ValueError +ValueError diff --git a/tests/extmod/hashlib_md5.py b/tests/extmod/hashlib_md5.py index 5f925fc97d0..ebbe9155e04 100644 --- a/tests/extmod/hashlib_md5.py +++ b/tests/extmod/hashlib_md5.py @@ -1,8 +1,7 @@ try: import hashlib except ImportError: - # This is neither uPy, nor cPy, so must be uPy with - # hashlib module disabled. + # MicroPython with hashlib module disabled. print("SKIP") raise SystemExit diff --git a/tests/extmod/hashlib_sha1.py b/tests/extmod/hashlib_sha1.py index af23033a591..46ffb73fcbe 100644 --- a/tests/extmod/hashlib_sha1.py +++ b/tests/extmod/hashlib_sha1.py @@ -1,8 +1,7 @@ try: import hashlib except ImportError: - # This is neither uPy, nor cPy, so must be uPy with - # hashlib module disabled. + # MicroPython with hashlib module disabled. print("SKIP") raise SystemExit diff --git a/tests/extmod/hashlib_sha256.py b/tests/extmod/hashlib_sha256.py index 95cd301d160..209fcb39877 100644 --- a/tests/extmod/hashlib_sha256.py +++ b/tests/extmod/hashlib_sha256.py @@ -1,8 +1,7 @@ try: import hashlib except ImportError: - # This is neither uPy, nor cPy, so must be uPy with - # hashlib module disabled. + # MicroPython with hashlib module disabled. print("SKIP") raise SystemExit diff --git a/tests/extmod/json_dump.py b/tests/extmod/json_dump.py index 897d33cc812..0beb4f5f856 100644 --- a/tests/extmod/json_dump.py +++ b/tests/extmod/json_dump.py @@ -16,11 +16,11 @@ # dump to a small-int not allowed try: json.dump(123, 1) -except (AttributeError, OSError): # CPython and uPy have different errors +except (AttributeError, OSError): # CPython and MicroPython have different errors print("Exception") # dump to an object not allowed try: json.dump(123, {}) -except (AttributeError, OSError): # CPython and uPy have different errors +except (AttributeError, OSError): # CPython and MicroPython have different errors print("Exception") diff --git a/tests/extmod/json_dump_iobase.py b/tests/extmod/json_dump_iobase.py index 94d317b8796..81105e36dcc 100644 --- a/tests/extmod/json_dump_iobase.py +++ b/tests/extmod/json_dump_iobase.py @@ -18,7 +18,7 @@ def __init__(self): def write(self, buf): if type(buf) == bytearray: - # uPy passes a bytearray, CPython passes a str + # MicroPython passes a bytearray, CPython passes a str buf = str(buf, "ascii") self.buf += buf return len(buf) diff --git a/tests/extmod/json_dump_separators.py b/tests/extmod/json_dump_separators.py index 4f8e56dceb5..ce39294820f 100644 --- a/tests/extmod/json_dump_separators.py +++ b/tests/extmod/json_dump_separators.py @@ -25,20 +25,20 @@ # dump to a small-int not allowed try: json.dump(123, 1, separators=sep) - except (AttributeError, OSError): # CPython and uPy have different errors + except (AttributeError, OSError): # CPython and MicroPython have different errors print("Exception") # dump to an object not allowed try: json.dump(123, {}, separators=sep) - except (AttributeError, OSError): # CPython and uPy have different errors + except (AttributeError, OSError): # CPython and MicroPython have different errors print("Exception") try: s = StringIO() json.dump(False, s, separators={"a": 1}) -except (TypeError, ValueError): # CPython and uPy have different errors +except (TypeError, ValueError): # CPython and MicroPython have different errors print("Exception") # invalid separator types diff --git a/tests/extmod/json_dumps_extra.py b/tests/extmod/json_dumps_extra.py index 9074416a99d..70efc866451 100644 --- a/tests/extmod/json_dumps_extra.py +++ b/tests/extmod/json_dumps_extra.py @@ -1,9 +1,6 @@ -# test uPy json behaviour that's not valid in CPy - -try: - import json -except ImportError: - print("SKIP") - raise SystemExit +# test MicroPython json behaviour that's not valid in CPy +# CIRCUITPY-CHANGE: This behavior matches CPython +print("SKIP") +raise SystemExit print(json.dumps(b"1234")) diff --git a/tests/extmod/json_dumps_separators.py b/tests/extmod/json_dumps_separators.py index a3a9ec308f0..0a95f489a08 100644 --- a/tests/extmod/json_dumps_separators.py +++ b/tests/extmod/json_dumps_separators.py @@ -39,7 +39,7 @@ try: json.dumps(False, separators={"a": 1}) -except (TypeError, ValueError): # CPython and uPy have different errors +except (TypeError, ValueError): # CPython and MicroPython have different errors print("Exception") # invalid separator types diff --git a/tests/extmod/json_loads.py b/tests/extmod/json_loads.py index f9073c121e2..092402d715d 100644 --- a/tests/extmod/json_loads.py +++ b/tests/extmod/json_loads.py @@ -71,3 +71,27 @@ def my_print(o): my_print(json.loads("[null] a")) except ValueError: print("ValueError") + +# incomplete object declaration +try: + my_print(json.loads('{"a":0,')) +except ValueError: + print("ValueError") + +# incomplete nested array declaration +try: + my_print(json.loads('{"a":0, [')) +except ValueError: + print("ValueError") + +# incomplete array declaration +try: + my_print(json.loads("[0,")) +except ValueError: + print("ValueError") + +# incomplete nested object declaration +try: + my_print(json.loads('[0, {"a":0, ')) +except ValueError: + print("ValueError") diff --git a/tests/extmod/json_loads_bytes.py.exp b/tests/extmod/json_loads_bytes.py.exp deleted file mode 100644 index c2735a99052..00000000000 --- a/tests/extmod/json_loads_bytes.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -[1, 2] -[None] diff --git a/tests/extmod/json_loads_int_64.py b/tests/extmod/json_loads_int_64.py new file mode 100644 index 00000000000..f6236f1904a --- /dev/null +++ b/tests/extmod/json_loads_int_64.py @@ -0,0 +1,16 @@ +# Parse 64-bit integers from JSON payloads. +# +# This also exercises parsing integers from strings +# where the value may not be null terminated (last line) +try: + import json +except ImportError: + print("SKIP") + raise SystemExit + + +print(json.loads("9111222333444555666")) +print(json.loads("-9111222333444555666")) +print(json.loads("9111222333444555666")) +print(json.loads("-9111222333444555666")) +print(json.loads('["9111222333444555666777",9111222333444555666]')) diff --git a/tests/extmod/machine_hard_timer.py b/tests/extmod/machine_hard_timer.py new file mode 100644 index 00000000000..8fe42ea8508 --- /dev/null +++ b/tests/extmod/machine_hard_timer.py @@ -0,0 +1,45 @@ +import sys + +try: + from machine import Timer + from time import sleep_ms +except: + print("SKIP") + raise SystemExit + +if sys.platform == "esp8266": + timer = Timer(0) +else: + # Hardware timers are not implemented. + print("SKIP") + raise SystemExit + +# Test both hard and soft IRQ handlers and both one-shot and periodic +# timers. We adjust period in tests/extmod/machine_soft_timer.py, so try +# adjusting freq here instead. The heap should be locked in hard callbacks +# and unlocked in soft callbacks. + + +def callback(t): + print("callback", mode[1], kind[1], freq, end=" ") + try: + allocate = bytearray(1) + print("unlocked") + except MemoryError: + print("locked") + + +modes = [(Timer.ONE_SHOT, "one-shot"), (Timer.PERIODIC, "periodic")] +kinds = [(False, "soft"), (True, "hard")] + +for mode in modes: + for kind in kinds: + for freq in 50, 25: + timer.init( + mode=mode[0], + freq=freq, + hard=kind[0], + callback=callback, + ) + sleep_ms(90) + timer.deinit() diff --git a/tests/extmod/machine_hard_timer.py.exp b/tests/extmod/machine_hard_timer.py.exp new file mode 100644 index 00000000000..26cdc644fdd --- /dev/null +++ b/tests/extmod/machine_hard_timer.py.exp @@ -0,0 +1,16 @@ +callback one-shot soft 50 unlocked +callback one-shot soft 25 unlocked +callback one-shot hard 50 locked +callback one-shot hard 25 locked +callback periodic soft 50 unlocked +callback periodic soft 50 unlocked +callback periodic soft 50 unlocked +callback periodic soft 50 unlocked +callback periodic soft 25 unlocked +callback periodic soft 25 unlocked +callback periodic hard 50 locked +callback periodic hard 50 locked +callback periodic hard 50 locked +callback periodic hard 50 locked +callback periodic hard 25 locked +callback periodic hard 25 locked diff --git a/tests/extmod/machine_timer.py b/tests/extmod/machine_timer.py new file mode 100644 index 00000000000..ef97ea4e949 --- /dev/null +++ b/tests/extmod/machine_timer.py @@ -0,0 +1,48 @@ +import sys + +try: + from machine import Timer + from time import sleep_ms +except: + print("SKIP") + raise SystemExit + +if sys.platform in ("esp32", "esp8266", "nrf"): + # Software timers aren't implemented on the esp32 and esp8266 ports. + # The nrf port doesn't support selection of hard and soft callbacks, + # and only allows Timer(period=N), not Timer(freq=N). + print("SKIP") + raise SystemExit +else: + timer_id = -1 + +# Test both hard and soft IRQ handlers and both one-shot and periodic +# timers. We adjust period in tests/extmod/machine_soft_timer.py, so try +# adjusting freq here instead. The heap should be locked in hard callbacks +# and unlocked in soft callbacks. + + +def callback(t): + print("callback", mode[1], kind[1], freq, end=" ") + try: + allocate = bytearray(1) + print("unlocked") + except MemoryError: + print("locked") + + +modes = [(Timer.ONE_SHOT, "one-shot"), (Timer.PERIODIC, "periodic")] +kinds = [(False, "soft"), (True, "hard")] + +for mode in modes: + for kind in kinds: + for freq in 50, 25: + timer = Timer( + timer_id, + mode=mode[0], + freq=freq, + hard=kind[0], + callback=callback, + ) + sleep_ms(90) + timer.deinit() diff --git a/tests/extmod/machine_timer.py.exp b/tests/extmod/machine_timer.py.exp new file mode 100644 index 00000000000..26cdc644fdd --- /dev/null +++ b/tests/extmod/machine_timer.py.exp @@ -0,0 +1,16 @@ +callback one-shot soft 50 unlocked +callback one-shot soft 25 unlocked +callback one-shot hard 50 locked +callback one-shot hard 25 locked +callback periodic soft 50 unlocked +callback periodic soft 50 unlocked +callback periodic soft 50 unlocked +callback periodic soft 50 unlocked +callback periodic soft 25 unlocked +callback periodic soft 25 unlocked +callback periodic hard 50 locked +callback periodic hard 50 locked +callback periodic hard 50 locked +callback periodic hard 50 locked +callback periodic hard 25 locked +callback periodic hard 25 locked diff --git a/tests/extmod/marshal_basic.py b/tests/extmod/marshal_basic.py new file mode 100644 index 00000000000..9e7b70be482 --- /dev/null +++ b/tests/extmod/marshal_basic.py @@ -0,0 +1,38 @@ +# Test the marshal module, basic functionality. + +try: + import marshal + + (lambda: 0).__code__ +except (AttributeError, ImportError): + print("SKIP") + raise SystemExit + +ftype = type(lambda: 0) + +# Test basic dumps and loads. +print(ftype(marshal.loads(marshal.dumps((lambda: a).__code__)), {"a": 4})()) + +# Test dumps of a result from compile(). +ftype(marshal.loads(marshal.dumps(compile("print(a)", "", "exec"))), {"print": print, "a": 5})() + +# Test marshalling a function with arguments. +print(ftype(marshal.loads(marshal.dumps((lambda x, y: x + y).__code__)), {})(1, 2)) + +# Test marshalling a function with default arguments. +print(ftype(marshal.loads(marshal.dumps((lambda x=0: x).__code__)), {})("arg")) + +# Test marshalling a function containing constant objects (a tuple). +print(ftype(marshal.loads(marshal.dumps((lambda: (None, ...)).__code__)), {})()) + +# Test instantiating multiple code's with different globals dicts. +code = marshal.loads(marshal.dumps((lambda: a).__code__)) +f1 = ftype(code, {"a": 1}) +f2 = ftype(code, {"a": 2}) +print(f1(), f2()) + +# Test unmarshallable object. +try: + marshal.dumps(type) +except ValueError: + print("ValueError") diff --git a/tests/extmod/marshal_micropython.py b/tests/extmod/marshal_micropython.py new file mode 100644 index 00000000000..213b3bf3189 --- /dev/null +++ b/tests/extmod/marshal_micropython.py @@ -0,0 +1,21 @@ +# Test the marshal module, MicroPython-specific functionality. + +try: + import marshal +except ImportError: + print("SKIP") + raise SystemExit + +import unittest + + +class Test(unittest.TestCase): + def test_function_with_children(self): + # Can't marshal a function with children (in this case the module has a child function f). + code = compile("def f(): pass", "", "exec") + with self.assertRaises(ValueError): + marshal.dumps(code) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/extmod/marshal_stress.py b/tests/extmod/marshal_stress.py new file mode 100644 index 00000000000..b52475c0361 --- /dev/null +++ b/tests/extmod/marshal_stress.py @@ -0,0 +1,122 @@ +# Test the marshal module, stressing edge cases. + +try: + import marshal + + (lambda: 0).__code__ +except (AttributeError, ImportError): + print("SKIP") + raise SystemExit + +ftype = type(lambda: 0) + +# Test a large function. + + +def large_function(arg0, arg1, arg2, arg3): + # Arguments. + print(arg0, arg1, arg2, arg3) + + # Positive medium-sized integer (still a small-int though). + print(1234) + + # Negative small-ish integer. + print(-20) + + # More than 64 constant objects. + x = (0,) + x = (1,) + x = (2,) + x = (3,) + x = (4,) + x = (5,) + x = (6,) + x = (7,) + x = (8,) + x = (9,) + x = (10,) + x = (11,) + x = (12,) + x = (13,) + x = (14,) + x = (15,) + x = (16,) + x = (17,) + x = (18,) + x = (19,) + x = (20,) + x = (21,) + x = (22,) + x = (23,) + x = (24,) + x = (25,) + x = (26,) + x = (27,) + x = (28,) + x = (29,) + x = (30,) + x = (31,) + x = (32,) + x = (33,) + x = (34,) + x = (35,) + x = (36,) + x = (37,) + x = (38,) + x = (39,) + x = (40,) + x = (41,) + x = (42,) + x = (43,) + x = (44,) + x = (45,) + x = (46,) + x = (47,) + x = (48,) + x = (49,) + x = (50,) + x = (51,) + x = (52,) + x = (53,) + x = (54,) + x = (55,) + x = (56,) + x = (57,) + x = (58,) + x = (59,) + x = (60,) + x = (61,) + x = (62,) + x = (63,) + x = (64,) + + # Small jump. + x = 0 + while x < 2: + print("loop", x) + x += 1 + + # Large jump. + x = 0 + while x < 2: + try: + try: + try: + print + except Exception as e: + print + finally: + print + except Exception as e: + print + finally: + print + except Exception as e: + print + finally: + print("loop", x) + x += 1 + + +code = marshal.dumps(large_function.__code__) +ftype(marshal.loads(code), {"print": print})(0, 1, 2, 3) diff --git a/tests/extmod/platform_basic.py b/tests/extmod/platform_basic.py new file mode 100644 index 00000000000..eb6f2be13c1 --- /dev/null +++ b/tests/extmod/platform_basic.py @@ -0,0 +1,8 @@ +try: + import platform +except ImportError: + print("SKIP") + raise SystemExit + +print(type(platform.python_compiler())) +print(type(platform.libc_ver())) diff --git a/tests/extmod/random_extra_float.py b/tests/extmod/random_extra_float.py index 3b37ed8dcef..03973c58349 100644 --- a/tests/extmod/random_extra_float.py +++ b/tests/extmod/random_extra_float.py @@ -1,12 +1,8 @@ try: import random -except ImportError: - print("SKIP") - raise SystemExit -try: - random.randint -except AttributeError: + random.random +except (ImportError, AttributeError): print("SKIP") raise SystemExit diff --git a/tests/extmod/re_error.py b/tests/extmod/re_error.py index f61d0913289..bd678c9d251 100644 --- a/tests/extmod/re_error.py +++ b/tests/extmod/re_error.py @@ -11,7 +11,7 @@ def test_re(r): try: re.compile(r) print("OK") - except: # uPy and CPy use different errors, so just ignore the type + except: # MPy and CPy use different errors, so just ignore the type print("Error") diff --git a/tests/extmod/re_start_end_pos.py b/tests/extmod/re_start_end_pos.py new file mode 100644 index 00000000000..bd16584374b --- /dev/null +++ b/tests/extmod/re_start_end_pos.py @@ -0,0 +1,78 @@ +# test start and end pos specification + +try: + import re +except ImportError: + print("SKIP") + raise SystemExit + + +def print_groups(match): + print("----") + try: + if match is not None: + i = 0 + while True: + print(match.group(i)) + i += 1 + except IndexError: + pass + + +p = re.compile(r"o") +m = p.match("dog") +print_groups(m) + +m = p.match("dog", 1) +print_groups(m) + +m = p.match("dog", 2) +print_groups(m) + +# No match past end of input +m = p.match("dog", 5) +print_groups(m) + +m = p.match("dog", 0, 1) +print_groups(m) + +# Caret only matches the actual beginning +p = re.compile(r"^o") +m = p.match("dog", 1) +print_groups(m) + +# End at beginning means searching empty string +p = re.compile(r"o") +m = p.match("dog", 1, 1) +print_groups(m) + +# End before the beginning doesn't match anything +m = p.match("dog", 2, 1) +print_groups(m) + +# Negative starting values don't crash +m = p.search("dog", -2) +print_groups(m) + +m = p.search("dog", -2, -5) +print_groups(m) + +# Search also works +print("--search") + +p = re.compile(r"o") +m = p.search("dog") +print_groups(m) + +m = p.search("dog", 1) +print_groups(m) + +m = p.search("dog", 2) +print_groups(m) + +# Negative starting values don't crash +m = p.search("dog", -2) +print_groups(m) + +m = p.search("dog", -2, -5) +print_groups(m) diff --git a/tests/extmod/re_sub.py b/tests/extmod/re_sub.py index 2c7c6c10f1a..bb9aa111287 100644 --- a/tests/extmod/re_sub.py +++ b/tests/extmod/re_sub.py @@ -10,6 +10,8 @@ print("SKIP") raise SystemExit +import sys + def multiply(m): return str(int(m.group(0)) * 2) @@ -47,7 +49,12 @@ def A(): print(re.sub("a", "b", "c")) # with maximum substitution count specified -print(re.sub("a", "b", "1a2a3a", 2)) +# CIRCUITPY-CHANGE: was "micropython" +if sys.implementation.name != "circuitpython": + # On CPython 3.13 and later the substitution count must be a keyword argument. + print(re.sub("a", "b", "1a2a3a", count=2)) +else: + print(re.sub("a", "b", "1a2a3a", 2)) # invalid group try: @@ -55,7 +62,7 @@ def A(): except: print("invalid group") -# invalid group with very large number (to test overflow in uPy) +# invalid group with very large number (to test overflow in MicroPython) try: re.sub("(a)", "b\\199999999999999999999999999999999999999", "a") except: diff --git a/tests/extmod/re_sub_unmatched.py.exp b/tests/extmod/re_sub_unmatched.py.exp deleted file mode 100644 index 1e5f0fda055..00000000000 --- a/tests/extmod/re_sub_unmatched.py.exp +++ /dev/null @@ -1 +0,0 @@ -1-a2 diff --git a/tests/extmod/select_ipoll.py b/tests/extmod/select_ipoll.py deleted file mode 100644 index 0b661c11c83..00000000000 --- a/tests/extmod/select_ipoll.py +++ /dev/null @@ -1,55 +0,0 @@ -# Test select.ipoll(). - -try: - import socket, select -except ImportError: - print("SKIP") - raise SystemExit - - -def print_poll_output(lst): - print([(type(obj), flags) for obj, flags in lst]) - - -poller = select.poll() - -# Use a new UDP socket for tests, which should be writable but not readable. -try: - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.bind(socket.getaddrinfo("127.0.0.1", 8000)[0][-1]) -except OSError: - print("SKIP") - raise SystemExit - -poller.register(s) - -# Basic polling. -print_poll_output(poller.ipoll(0)) - -# Pass in flags=1 for one-shot behaviour. -print_poll_output(poller.ipoll(0, 1)) - -# Socket should be deregistered and poll should return nothing. -print_poll_output(poller.ipoll(0)) - -# Create a second socket. -s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -s2.bind(socket.getaddrinfo("127.0.0.1", 8001)[0][-1]) - -# Register both sockets (to reset the first one). -poller.register(s) -poller.register(s2) - -# Basic polling with two sockets. -print_poll_output(poller.ipoll(0)) - -# Unregister the first socket, to test polling the remaining one. -poller.unregister(s) -print_poll_output(poller.ipoll(0)) - -# Unregister the second socket, to test polling none. -poller.unregister(s2) -print_poll_output(poller.ipoll(0)) - -s2.close() -s.close() diff --git a/tests/extmod/select_ipoll.py.exp b/tests/extmod/select_ipoll.py.exp deleted file mode 100644 index cbeabdce902..00000000000 --- a/tests/extmod/select_ipoll.py.exp +++ /dev/null @@ -1,6 +0,0 @@ -[(, 4)] -[(, 4)] -[] -[(, 4), (, 4)] -[(, 4)] -[] diff --git a/tests/extmod/select_poll_custom.py b/tests/extmod/select_poll_custom.py deleted file mode 100644 index b854a8a14da..00000000000 --- a/tests/extmod/select_poll_custom.py +++ /dev/null @@ -1,102 +0,0 @@ -# Test custom pollable objects implemented in Python. - -from micropython import const - -try: - import socket, select, io -except ImportError: - print("SKIP") - raise SystemExit - -_MP_STREAM_POLL = const(3) -_MP_STREAM_GET_FILENO = const(10) - -_MP_STREAM_POLL_RD = const(0x0001) -_MP_STREAM_POLL_WR = const(0x0004) - - -def print_poll_output(lst): - print([(type(obj), flags) for obj, flags in lst]) - - -class CustomPollable(io.IOBase): - def __init__(self): - self.poll_state = 0 - - def ioctl(self, cmd, arg): - if cmd == _MP_STREAM_GET_FILENO: - # Bare-metal ports don't call this ioctl, so don't print it. - return -1 - - print("CustomPollable.ioctl", cmd, arg) - if cmd == _MP_STREAM_POLL: - if self.poll_state == "delay_rd": - self.poll_state = _MP_STREAM_POLL_RD - return 0 - elif self.poll_state < 0: - return self.poll_state - else: - return self.poll_state & arg - - -poller = select.poll() - -# Use a new UDP socket for tests, which should be writable but not readable. -try: - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.bind(socket.getaddrinfo("127.0.0.1", 8000)[0][-1]) -except OSError: - print("SKIP") - raise SystemExit - -x = CustomPollable() - -# Register both a file-descriptor-based object and a custom pure-Python object. -poller.register(s) -poller.register(x) - -# Modify the flags for the custom object. -poller.modify(x, select.POLLIN) - -# Test polling. -print_poll_output(poller.poll(0)) -x.poll_state = _MP_STREAM_POLL_WR -print_poll_output(poller.poll(0)) -x.poll_state = _MP_STREAM_POLL_RD -print_poll_output(poller.poll(0)) - -# The custom object becomes readable only after being polled. -poller.modify(s, select.POLLIN) -x.poll_state = "delay_rd" -print_poll_output(poller.poll()) - -# The custom object returns an error. -x.poll_state = -1000 -try: - poller.poll(0) -except OSError as er: - print("OSError", er.errno) - -# Register then unregister a socket (a native stream), then test -# that the Python object is still pollable. -s2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -x.poll_state = _MP_STREAM_POLL_RD -poller.register(s2) -poller.unregister(s2) -print_poll_output(poller.poll()) - -# Test registering and unregistering multiple times. -for _ in range(2): - poller.unregister(s) - poller.unregister(x) - poller.register(s2) - poller.register(s, select.POLLIN) - poller.register(x, select.POLLIN) - poller.unregister(s2) - print_poll_output(poller.poll()) - -# Clean up. -poller.unregister(x) -poller.unregister(s) -s2.close() -s.close() diff --git a/tests/extmod/select_poll_custom.py.exp b/tests/extmod/select_poll_custom.py.exp deleted file mode 100644 index d85508bab24..00000000000 --- a/tests/extmod/select_poll_custom.py.exp +++ /dev/null @@ -1,17 +0,0 @@ -CustomPollable.ioctl 3 1 -[(, 4)] -CustomPollable.ioctl 3 1 -[(, 4)] -CustomPollable.ioctl 3 1 -[(, 4), (, 1)] -CustomPollable.ioctl 3 1 -CustomPollable.ioctl 3 1 -[(, 1)] -CustomPollable.ioctl 3 1 -OSError 1000 -CustomPollable.ioctl 3 1 -[(, 1)] -CustomPollable.ioctl 3 1 -[(, 1)] -CustomPollable.ioctl 3 1 -[(, 1)] diff --git a/tests/extmod/select_poll_eintr.py b/tests/extmod/select_poll_eintr.py deleted file mode 100644 index e1cbc2aaf57..00000000000 --- a/tests/extmod/select_poll_eintr.py +++ /dev/null @@ -1,50 +0,0 @@ -# Test interruption of select.poll by EINTR signal, when -# MICROPY_PY_SELECT_POSIX_OPTIMISATIONS is enabled. - -try: - import time, gc, select, socket, _thread - - time.time_ns # Check for time_ns on MicroPython - select.poll # Raises AttributeError for CPython implementations without poll() -except (ImportError, AttributeError): - print("SKIP") - raise SystemExit - - -def thread_main(): - lock.acquire() - time.sleep(0.2) - print("thread gc start") - # The unix gc.collect() implementation will raise EINTR on other threads. - # Could possibly use _thread._interrupt_main() instead if MicroPython had it. - gc.collect() - print("thread gc end") - - -# Start a thread to interrupt the main thread during its call to poll. -lock = _thread.allocate_lock() -lock.acquire() -_thread.start_new_thread(thread_main, ()) - -# Use a new UDP socket for tests, which should be writable but not readable. -s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) -s.bind(socket.getaddrinfo("127.0.0.1", 8000)[0][-1]) - -# Create the poller object. -poller = select.poll() -poller.register(s, select.POLLIN) - -# Poll on the UDP socket for a set timeout, which should be reached. -print("poll") -lock.release() -t0 = time.time_ns() -result = poller.poll(400) -dt_ms = (time.time_ns() - t0) / 1e6 -print("result:", result) -if 380 <= dt_ms <= 600: - print("dt in range") -else: - print("dt not in range:", dt_ms) - -# Clean up. -s.close() diff --git a/tests/extmod/select_poll_fd.py b/tests/extmod/select_poll_fd.py deleted file mode 100644 index 5f9dcc286a0..00000000000 --- a/tests/extmod/select_poll_fd.py +++ /dev/null @@ -1,63 +0,0 @@ -# Test select.poll in combination with file descriptors. - -try: - import select, errno - - select.poll # Raises AttributeError for CPython implementations without poll() -except (ImportError, AttributeError): - print("SKIP") - raise SystemExit - -# Check that poll supports registering file descriptors (integers). -try: - select.poll().register(0) -except OSError: - print("SKIP") - raise SystemExit - -# Register invalid file descriptor. -try: - select.poll().register(-1) -except ValueError: - print("ValueError") - -# Test polling stdout, it should be writable. -poller = select.poll() -poller.register(1) -poller.modify(1, select.POLLOUT) -print(poller.poll()) - -# Unregister then re-register. -poller.unregister(1) -poller.register(1, select.POLLIN) - -# Poll for input, should return an empty list. -print(poller.poll(0)) - -# Test registering a very large number of file descriptors (will trigger -# EINVAL due to more than OPEN_MAX fds). Typically it's 1024 (and on GitHub CI -# we force this via `ulimit -n 1024`). -# CIRCUITPY-CHANGE: Skip this test. poller.poll() does not have a limit and will `assert False` -# The ulimit change in the micropython tests may not be working properly. -# on GitHub CI, the limit is far larger than 6000. It is 1024 on desktop Ubuntu, but -# higher on the runners. I don't think this test is testing what it means to test. -# poller = select.poll() -# fd_last = 0 -# for fd in range(6000): -# fd_last = fd -# poller.register(fd) -# try: -# poller.poll() -# assert False -# except OSError as er: -# print("fd_last", fd_last) -# print(er.errno == errno.EINVAL) - -# Register stdout/stderr, plus many extra ones to trigger the fd vector -# resizing. Then unregister the excess ones and verify poll still works. -poller = select.poll() -for fd in range(1, 1000): - poller.register(fd) -for i in range(3, 1000): - poller.unregister(i) -print(sorted(poller.poll())) diff --git a/tests/extmod/socket_badconstructor.py b/tests/extmod/socket_badconstructor.py new file mode 100644 index 00000000000..4a9d2668c7f --- /dev/null +++ b/tests/extmod/socket_badconstructor.py @@ -0,0 +1,22 @@ +# Test passing in bad values to socket.socket constructor. + +try: + import socket +except: + print("SKIP") + raise SystemExit + +try: + s = socket.socket(None) +except TypeError: + print("TypeError") + +try: + s = socket.socket(socket.AF_INET, None) +except TypeError: + print("TypeError") + +try: + s = socket.socket(socket.AF_INET, socket.SOCK_RAW, None) +except TypeError: + print("TypeError") diff --git a/tests/extmod/socket_fileno.py b/tests/extmod/socket_fileno.py new file mode 100644 index 00000000000..da15825e3d5 --- /dev/null +++ b/tests/extmod/socket_fileno.py @@ -0,0 +1,17 @@ +# Test socket.fileno() functionality + +try: + import socket +except ImportError: + print("SKIP") + raise SystemExit + +if not hasattr(socket.socket, "fileno"): + print("SKIP") + raise SystemExit + +s = socket.socket() +print(s.fileno() >= 0) + +s.close() +print(s.fileno()) # should print -1 diff --git a/tests/extmod/socket_udp_nonblock.py b/tests/extmod/socket_udp_nonblock.py deleted file mode 100644 index 1e74e2917dc..00000000000 --- a/tests/extmod/socket_udp_nonblock.py +++ /dev/null @@ -1,21 +0,0 @@ -# test non-blocking UDP sockets - -try: - import socket, errno -except ImportError: - print("SKIP") - raise SystemExit - -try: - s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - s.bind(socket.getaddrinfo("127.0.0.1", 8000)[0][-1]) -except OSError: - print("SKIP") - raise SystemExit - -s.settimeout(0) - -try: - s.recv(1) -except OSError as er: - print("EAGAIN:", er.errno == errno.EAGAIN) diff --git a/tests/extmod/ssl_cadata.py b/tests/extmod/ssl_cadata.py deleted file mode 100644 index e66f6ca825b..00000000000 --- a/tests/extmod/ssl_cadata.py +++ /dev/null @@ -1,18 +0,0 @@ -# Test ssl.wrap_socket() with cadata passed in. - -try: - import io - import ssl -except ImportError: - print("SKIP") - raise SystemExit - -# Invalid cadata. -try: - ssl.wrap_socket(io.BytesIO(), cadata=b"!") -except TypeError: - # "cadata" keyword argument is not supported by axtls. - print("SKIP") - raise SystemExit -except ValueError as er: - print(repr(er)) diff --git a/tests/extmod/ssl_cadata.py.exp b/tests/extmod/ssl_cadata.py.exp deleted file mode 100644 index 9f1cf732e33..00000000000 --- a/tests/extmod/ssl_cadata.py.exp +++ /dev/null @@ -1 +0,0 @@ -ValueError('invalid cert',) diff --git a/tests/extmod/ssl_ioctl.py b/tests/extmod/ssl_ioctl.py deleted file mode 100644 index 4db7c2df82a..00000000000 --- a/tests/extmod/ssl_ioctl.py +++ /dev/null @@ -1,31 +0,0 @@ -# Test SSL ioctl method. -# Direct access to this method is only available if MICROPY_UNIX_COVERAGE is enabled. - -try: - import io, ssl - - io.BytesIO -except (ImportError, AttributeError): - print("SKIP") - raise SystemExit - -_MP_STREAM_POLL = 3 -_MP_STREAM_CLOSE = 4 -_MP_STREAM_GET_FILENO = 10 - -s = ssl.wrap_socket(io.BytesIO(), server_side=1, do_handshake=0) - -if not hasattr(s, "ioctl"): - print("SKIP") - raise SystemExit - -# These ioctl's should be unsupported. -for request in (-1, 0, _MP_STREAM_GET_FILENO): - try: - s.ioctl(request, 0) - except OSError: - print(request, "OSError") - -# These ioctl's should be supported. -for request in (_MP_STREAM_CLOSE, _MP_STREAM_POLL, _MP_STREAM_CLOSE): - print(request, s.ioctl(request, 0)) diff --git a/tests/extmod/ssl_ioctl.py.exp b/tests/extmod/ssl_ioctl.py.exp deleted file mode 100644 index 22208b00cc9..00000000000 --- a/tests/extmod/ssl_ioctl.py.exp +++ /dev/null @@ -1,6 +0,0 @@ --1 OSError -0 OSError -10 OSError -4 0 -3 32 -4 0 diff --git a/tests/extmod/ssl_poll.py b/tests/extmod/ssl_poll.py deleted file mode 100644 index 347e5f7d37a..00000000000 --- a/tests/extmod/ssl_poll.py +++ /dev/null @@ -1,196 +0,0 @@ -try: - import select - import ssl - import io - import binascii -except ImportError: - print("SKIP") - raise SystemExit - -from micropython import const - -_MP_STREAM_POLL_RD = const(0x0001) -_MP_STREAM_POLL_WR = const(0x0004) -_MP_STREAM_POLL_NVAL = const(0x0020) -_MP_STREAM_POLL = const(3) -_MP_STREAM_CLOSE = const(4) - - -# This self-signed key/cert pair is randomly generated and to be used for -# testing/demonstration only. You should always generate your own key/cert. -key = binascii.unhexlify( - b"3082013b020100024100cc20643fd3d9c21a0acba4f48f61aadd675f52175a9dcf07fbef" - b"610a6a6ba14abb891745cd18a1d4c056580d8ff1a639460f867013c8391cdc9f2e573b0f" - b"872d0203010001024100bb17a54aeb3dd7ae4edec05e775ca9632cf02d29c2a089b563b0" - b"d05cdf95aeca507de674553f28b4eadaca82d5549a86058f9996b07768686a5b02cb240d" - b"d9f1022100f4a63f5549e817547dca97b5c658038e8593cb78c5aba3c4642cc4cd031d86" - b"8f022100d598d870ffe4a34df8de57047a50b97b71f4d23e323f527837c9edae88c79483" - b"02210098560c89a70385c36eb07fd7083235c4c1184e525d838aedf7128958bedfdbb102" - b"2051c0dab7057a8176ca966f3feb81123d4974a733df0f958525f547dfd1c271f9022044" - b"6c2cafad455a671a8cf398e642e1be3b18a3d3aec2e67a9478f83c964c4f1f" -) -cert = binascii.unhexlify( - b"308201d53082017f020203e8300d06092a864886f70d01010505003075310b3009060355" - b"0406130258583114301206035504080c0b54686550726f76696e63653110300e06035504" - b"070c075468654369747931133011060355040a0c0a436f6d70616e7958595a3113301106" - b"0355040b0c0a436f6d70616e7958595a3114301206035504030c0b546865486f73744e61" - b"6d65301e170d3139313231383033333935355a170d3239313231353033333935355a3075" - b"310b30090603550406130258583114301206035504080c0b54686550726f76696e636531" - b"10300e06035504070c075468654369747931133011060355040a0c0a436f6d70616e7958" - b"595a31133011060355040b0c0a436f6d70616e7958595a3114301206035504030c0b5468" - b"65486f73744e616d65305c300d06092a864886f70d0101010500034b003048024100cc20" - b"643fd3d9c21a0acba4f48f61aadd675f52175a9dcf07fbef610a6a6ba14abb891745cd18" - b"a1d4c056580d8ff1a639460f867013c8391cdc9f2e573b0f872d0203010001300d06092a" - b"864886f70d0101050500034100b0513fe2829e9ecbe55b6dd14c0ede7502bde5d46153c8" - b"e960ae3ebc247371b525caeb41bbcf34686015a44c50d226e66aef0a97a63874ca5944ef" - b"979b57f0b3" -) - - -class _Pipe(io.IOBase): - def __init__(self): - self._other = None - self.block_reads = False - self.block_writes = False - - self.write_buffers = [] - self.last_poll_arg = None - - def readinto(self, buf): - if self.block_reads or len(self._other.write_buffers) == 0: - return None - - read_buf = self._other.write_buffers[0] - l = min(len(buf), len(read_buf)) - buf[:l] = read_buf[:l] - if l == len(read_buf): - self._other.write_buffers.pop(0) - else: - self._other.write_buffers[0] = read_buf[l:] - return l - - def write(self, buf): - if self.block_writes: - return None - - self.write_buffers.append(memoryview(bytes(buf))) - return len(buf) - - def ioctl(self, request, arg): - if request == _MP_STREAM_POLL: - self.last_poll_arg = arg - ret = 0 - if arg & _MP_STREAM_POLL_RD: - if not self.block_reads and self._other.write_buffers: - ret |= _MP_STREAM_POLL_RD - if arg & _MP_STREAM_POLL_WR: - if not self.block_writes: - ret |= _MP_STREAM_POLL_WR - return ret - - elif request == _MP_STREAM_CLOSE: - return 0 - - raise NotImplementedError() - - @classmethod - def new_pair(cls): - p1 = cls() - p2 = cls() - p1._other = p2 - p2._other = p1 - return p1, p2 - - -def assert_poll(s, i, arg, expected_arg, expected_ret): - ret = s.ioctl(_MP_STREAM_POLL, arg) - assert i.last_poll_arg == expected_arg - i.last_poll_arg = None - assert ret == expected_ret - - -def assert_raises(cb, *args, **kwargs): - try: - cb(*args, **kwargs) - raise AssertionError("should have raised") - except Exception as exc: - pass - - -client_io, server_io = _Pipe.new_pair() - -client_io.block_reads = True -client_io.block_writes = True -client_sock = ssl.wrap_socket(client_io, do_handshake=False) - -server_sock = ssl.wrap_socket(server_io, key=key, cert=cert, server_side=True, do_handshake=False) - -# Do a test read, at this point the TLS handshake wants to write, -# so it returns None: -assert client_sock.read(128) is None - -# Polling for either read or write actually check if the underlying socket can write: -assert_poll(client_sock, client_io, _MP_STREAM_POLL_RD, _MP_STREAM_POLL_WR, 0) -assert_poll(client_sock, client_io, _MP_STREAM_POLL_WR, _MP_STREAM_POLL_WR, 0) - -# Mark the socket as writable, and do another test read: -client_io.block_writes = False -assert client_sock.read(128) is None - -# The client wrote the CLIENT_HELLO message -assert len(client_io.write_buffers) == 1 - -# At this point the TLS handshake wants to read, but we don't know that yet: -assert_poll(client_sock, client_io, _MP_STREAM_POLL_RD, _MP_STREAM_POLL_RD, 0) -assert_poll(client_sock, client_io, _MP_STREAM_POLL_WR, _MP_STREAM_POLL_WR, _MP_STREAM_POLL_WR) - -# Do a test write -client_sock.write(b"foo") - -# Now we know that we want to read: -assert_poll(client_sock, client_io, _MP_STREAM_POLL_RD, _MP_STREAM_POLL_RD, 0) -assert_poll(client_sock, client_io, _MP_STREAM_POLL_WR, _MP_STREAM_POLL_RD, 0) - -# Unblock reads and nudge the two sockets: -client_io.block_reads = False -while server_io.write_buffers or client_io.write_buffers: - if server_io.write_buffers: - assert client_sock.read(128) is None - if client_io.write_buffers: - assert server_sock.read(128) is None - -# At this point, the handshake is done, try writing data: -client_sock.write(b"foo") -assert server_sock.read(3) == b"foo" - -# Test reading partial data: -client_sock.write(b"foobar") -assert server_sock.read(3) == b"foo" -server_io.block_reads = True -assert_poll( - server_sock, server_io, _MP_STREAM_POLL_RD, None, _MP_STREAM_POLL_RD -) # Did not go to the socket, just consumed buffered data -assert server_sock.read(3) == b"bar" - - -# Polling on a closed socket errors out: -client_io, _ = _Pipe.new_pair() -client_sock = ssl.wrap_socket(client_io, do_handshake=False) -client_sock.close() -assert_poll( - client_sock, client_io, _MP_STREAM_POLL_RD, None, _MP_STREAM_POLL_NVAL -) # Did not go to the socket - - -# Errors propagates to poll: -client_io, server_io = _Pipe.new_pair() -client_sock = ssl.wrap_socket(client_io, do_handshake=False) - -# The server returns garbage: -server_io.write(b"fooba") # Needs to be exactly 5 bytes - -assert_poll(client_sock, client_io, _MP_STREAM_POLL_RD, _MP_STREAM_POLL_RD, _MP_STREAM_POLL_RD) -assert_raises(client_sock.read, 128) -assert_poll( - client_sock, client_io, _MP_STREAM_POLL_RD, None, _MP_STREAM_POLL_NVAL -) # Did not go to the socket diff --git a/tests/extmod/ssl_sslcontext.py b/tests/extmod/ssl_sslcontext.py deleted file mode 100644 index 23ff9c29646..00000000000 --- a/tests/extmod/ssl_sslcontext.py +++ /dev/null @@ -1,25 +0,0 @@ -# Very basic test of ssl.SSLContext class. - -try: - import socket, ssl -except ImportError: - print("SKIP") - raise SystemExit - -# Test constructing with arguments. -ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) -ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) - -# Test printing object. -ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) -print("SSLContext" in str(ctx)) - -# Coverage test for destructor, and calling it twice. -if hasattr(ctx, "__del__"): - ctx.__del__() - ctx.__del__() - -# Test calling .wrap_socket() method, multiple times. -ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) -ctx.wrap_socket(socket.socket(), do_handshake_on_connect=False) -ctx.wrap_socket(socket.socket(), do_handshake_on_connect=False) diff --git a/tests/extmod/ssl_sslcontext_verify_mode.py b/tests/extmod/ssl_sslcontext_verify_mode.py deleted file mode 100644 index daccc2f4a95..00000000000 --- a/tests/extmod/ssl_sslcontext_verify_mode.py +++ /dev/null @@ -1,24 +0,0 @@ -# Test ssl.SSLContext.verify_mode attribute. -# It's not available in the axtls implementation, so has an independent test. - -try: - import ssl -except ImportError: - print("SKIP") - raise SystemExit - -if not hasattr(ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT), "verify_mode"): - print("SKIP") - raise SystemExit - -# Test default verify_mode for server (client default is different in MicroPython). -ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) -print(ctx.verify_mode == ssl.CERT_NONE) - -# Test setting and getting verify_mode. -ctx.verify_mode = ssl.CERT_NONE -print(ctx.verify_mode == ssl.CERT_NONE) -ctx.verify_mode = ssl.CERT_OPTIONAL -print(ctx.verify_mode == ssl.CERT_OPTIONAL) -ctx.verify_mode = ssl.CERT_REQUIRED -print(ctx.verify_mode == ssl.CERT_REQUIRED) diff --git a/tests/extmod/ticks_add.py b/tests/extmod/ticks_add.py deleted file mode 100644 index 4f465f3cfba..00000000000 --- a/tests/extmod/ticks_add.py +++ /dev/null @@ -1,42 +0,0 @@ -try: - from time import ticks_diff, ticks_add -except ImportError: - print("SKIP") - raise SystemExit - -# Maximum value returned from ticks_add, ticks_ms, etc. -TICKS_MAX = ticks_add(0, -1) -# Maximum value returned from ticks_diff. -TICKS_INTERVAL_MAX = TICKS_MAX // 2 - -# Invariants: -# - ticks_diff(ticks_add(T, delta), T) == delta -# - ticks_diff(T, ticks_add(T, delta)) == -delta - -# Check actual values of ticks_add. -print(ticks_add(20, 12)) -print(ticks_add(20, -12)) - -# Check invariant. -print(ticks_diff(ticks_add(100, 123), 100)) -print(ticks_diff(ticks_add(100, -123), 100)) -print(ticks_diff(100, ticks_add(100, 123))) -print(ticks_diff(100, ticks_add(100, -123))) - -# Check limits. -for T in (0, 10, TICKS_MAX): - for delta in ( - -TICKS_INTERVAL_MAX - 1, - -TICKS_INTERVAL_MAX, - 0, - TICKS_INTERVAL_MAX, - TICKS_INTERVAL_MAX + 1, - ): - try: - print(ticks_diff(ticks_add(T, delta), T) == delta) - except OverflowError: - print("OverflowError") - try: - print(ticks_diff(T, ticks_add(T, delta)) == -delta) - except OverflowError: - print("OverflowError") diff --git a/tests/extmod/ticks_add.py.exp b/tests/extmod/ticks_add.py.exp deleted file mode 100644 index 60dc6f5afda..00000000000 --- a/tests/extmod/ticks_add.py.exp +++ /dev/null @@ -1,36 +0,0 @@ -32 -8 -123 --123 --123 -123 -OverflowError -OverflowError -True -True -True -True -True -True -OverflowError -OverflowError -OverflowError -OverflowError -True -True -True -True -True -True -OverflowError -OverflowError -OverflowError -OverflowError -True -True -True -True -True -True -OverflowError -OverflowError diff --git a/tests/extmod/ticks_diff.py b/tests/extmod/ticks_diff.py deleted file mode 100644 index b2445f0d624..00000000000 --- a/tests/extmod/ticks_diff.py +++ /dev/null @@ -1,37 +0,0 @@ -try: - from time import ticks_diff, ticks_add -except ImportError: - print("SKIP") - raise SystemExit - -MAX = ticks_add(0, -1) -# Should be done like this to avoid small int overflow -MODULO_HALF = MAX // 2 + 1 - -# Invariants: -# if ticks_diff(a, b) = c, -# then ticks_diff(b, a) = -c - -assert ticks_diff(1, 0) == 1, ticks_diff(1, 0) -assert ticks_diff(0, 1) == -1 - -assert ticks_diff(0, MAX) == 1 -assert ticks_diff(MAX, 0) == -1 - -assert ticks_diff(0, MAX - 1) == 2 - -# Maximum "positive" distance -assert ticks_diff(MODULO_HALF, 1) == MODULO_HALF - 1, ticks_diff(MODULO_HALF, 1) -# Step further, and it becomes a negative distance -assert ticks_diff(MODULO_HALF, 0) == -MODULO_HALF - -# Offsetting that in either direction doesn't affect the result -off = 100 -# Cheating and skipping to use ticks_add() when we know there's no wraparound -# Real apps should use always it. -assert ticks_diff(MODULO_HALF + off, 1 + off) == MODULO_HALF - 1 -assert ticks_diff(MODULO_HALF + off, 0 + off) == -MODULO_HALF -assert ticks_diff(MODULO_HALF - off, ticks_add(1, -off)) == MODULO_HALF - 1 -assert ticks_diff(MODULO_HALF - off, ticks_add(0, -off)) == -MODULO_HALF - -print("OK") diff --git a/tests/extmod/ticks_diff.py.exp b/tests/extmod/ticks_diff.py.exp deleted file mode 100644 index d86bac9de59..00000000000 --- a/tests/extmod/ticks_diff.py.exp +++ /dev/null @@ -1 +0,0 @@ -OK diff --git a/tests/extmod/time_mktime.py b/tests/extmod/time_mktime.py new file mode 100644 index 00000000000..7fc643dc3cb --- /dev/null +++ b/tests/extmod/time_mktime.py @@ -0,0 +1,120 @@ +# test conversion from date tuple to timestamp and back + +try: + import time + + time.localtime +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +# Range of date expected to work on all MicroPython platforms +MIN_YEAR = 1970 +MAX_YEAR = 2099 +# CPython properly supported date range: +# - on Windows: year 1970 to 3000+ +# - on Unix: year 1583 to 3000+ + +# Start test from Jan 1, 2001 13:00 (Feb 2000 might already be broken) +SAFE_DATE = (2001, 1, 1, 13, 0, 0, 0, 0, -1) + + +# mktime function that checks that the result is reversible +def safe_mktime(date_tuple): + try: + res = time.mktime(date_tuple) + chk = time.localtime(res) + except OverflowError: + print("safe_mktime:", date_tuple, "overflow error") + return None + if chk[0:5] != date_tuple[0:5]: + print("safe_mktime:", date_tuple[0:5], " -> ", res, " -> ", chk[0:5]) + return None + return res + + +# localtime function that checks that the result is reversible +def safe_localtime(timestamp): + try: + res = time.localtime(timestamp) + chk = time.mktime(res) + except OverflowError: + print("safe_localtime:", timestamp, "overflow error") + return None + if chk != timestamp: + print("safe_localtime:", timestamp, " -> ", res, " -> ", chk) + return None + return res + + +# look for smallest valid timestamps by iterating backwards on tuple +def test_bwd(date_tuple): + curr_stamp = safe_mktime(date_tuple) + year = date_tuple[0] + month = date_tuple[1] - 1 + if month < 1: + year -= 1 + month = 12 + while year >= MIN_YEAR: + while month >= 1: + next_tuple = (year, month) + date_tuple[2:] + next_stamp = safe_mktime(next_tuple) + # at this stage, only test consistency and monotonicity + if next_stamp is None or next_stamp >= curr_stamp: + return date_tuple + date_tuple = next_tuple + curr_stamp = next_stamp + month -= 1 + year -= 1 + month = 12 + return date_tuple + + +# test day-by-day to ensure that every date is properly converted +def test_fwd(start_date): + DAYS_PER_MONTH = (0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31) + curr_stamp = safe_mktime(start_date) + curr_date = safe_localtime(curr_stamp) + while curr_date[0] <= MAX_YEAR: + if curr_date[2] < 15: + skip_days = 13 + else: + skip_days = 1 + next_stamp = curr_stamp + skip_days * 86400 + next_date = safe_localtime(next_stamp) + if next_date is None: + return curr_date + if next_date[2] != curr_date[2] + skip_days: + # next month + if next_date[2] != 1: + print("wrong day of month:", next_date) + return curr_date + # check the number of days in previous month + month_days = DAYS_PER_MONTH[curr_date[1]] + if month_days == 28 and curr_date[0] % 4 == 0: + if curr_date[0] % 100 != 0 or curr_date[0] % 400 == 0: + month_days += 1 + if curr_date[2] != month_days: + print("wrong day count in prev month:", curr_date[2], "vs", month_days) + return curr_date + if next_date[1] != curr_date[1] + 1: + # next year + if curr_date[1] != 12: + print("wrong month count in prev year:", curr_date[1]) + return curr_date + if next_date[1] != 1: + print("wrong month:", next_date) + return curr_date + if next_date[0] != curr_date[0] + 1: + print("wrong year:", next_date) + return curr_date + curr_stamp = next_stamp + curr_date = next_date + return curr_date + + +small_date = test_bwd(SAFE_DATE) +large_date = test_fwd(small_date) +print("tested from", small_date[0:3], "to", large_date[0:3]) +print(small_date[0:3], "wday is", small_date[6]) +print(large_date[0:3], "wday is", large_date[6]) diff --git a/tests/extmod/time_ms_us.py b/tests/extmod/time_ms_us.py deleted file mode 100644 index e26c6e677a9..00000000000 --- a/tests/extmod/time_ms_us.py +++ /dev/null @@ -1,23 +0,0 @@ -try: - import time - - time.sleep_ms, time.sleep_us, time.ticks_diff, time.ticks_ms, time.ticks_us, time.ticks_cpu -except (ImportError, AttributeError): - print("SKIP") - raise SystemExit - -time.sleep_ms(1) -time.sleep_us(1) - -t0 = time.ticks_ms() -t1 = time.ticks_ms() -print(0 <= time.ticks_diff(t1, t0) <= 1) - -t0 = time.ticks_us() -t1 = time.ticks_us() -print(0 <= time.ticks_diff(t1, t0) <= 500) - -# ticks_cpu may not be implemented, at least make sure it doesn't decrease -t0 = time.ticks_cpu() -t1 = time.ticks_cpu() -print(time.ticks_diff(t1, t0) >= 0) diff --git a/tests/extmod/time_ms_us.py.exp b/tests/extmod/time_ms_us.py.exp deleted file mode 100644 index b8ca7e7ef09..00000000000 --- a/tests/extmod/time_ms_us.py.exp +++ /dev/null @@ -1,3 +0,0 @@ -True -True -True diff --git a/tests/extmod/time_res.py b/tests/extmod/time_res.py index 548bef1f174..ef20050b914 100644 --- a/tests/extmod/time_res.py +++ b/tests/extmod/time_res.py @@ -37,9 +37,12 @@ def test(): time.sleep_ms(100) for func_name, _ in EXPECTED_MAP: try: - time_func = getattr(time, func_name, None) or globals()[func_name] + if func_name.endswith("_time"): + time_func = globals()[func_name] + else: + time_func = getattr(time, func_name) now = time_func() # may raise AttributeError - except (KeyError, AttributeError): + except AttributeError: continue try: results_map[func_name].add(now) diff --git a/tests/extmod/time_time_ns.py b/tests/extmod/time_time_ns.py deleted file mode 100644 index 3ef58e56a94..00000000000 --- a/tests/extmod/time_time_ns.py +++ /dev/null @@ -1,24 +0,0 @@ -# test time.time_ns() - -try: - import time - - time.sleep_us - time.time_ns -except (ImportError, AttributeError): - print("SKIP") - raise SystemExit - - -t0 = time.time_ns() -time.sleep_us(5000) -t1 = time.time_ns() - -# Check that time_ns increases. -print(t0 < t1) - -# Check that time_ns counts correctly, but be very lenient with the bounds (2ms to 50ms). -if 2000000 < t1 - t0 < 50000000: - print(True) -else: - print(t0, t1, t1 - t0) diff --git a/tests/extmod/time_time_ns.py.exp b/tests/extmod/time_time_ns.py.exp deleted file mode 100644 index dbde422651c..00000000000 --- a/tests/extmod/time_time_ns.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -True -True diff --git a/tests/extmod/tls_dtls.py b/tests/extmod/tls_dtls.py new file mode 100644 index 00000000000..753ab2fee4f --- /dev/null +++ b/tests/extmod/tls_dtls.py @@ -0,0 +1,61 @@ +# Test DTLS functionality including timeout handling + +try: + from tls import PROTOCOL_DTLS_CLIENT, PROTOCOL_DTLS_SERVER, SSLContext, CERT_NONE + import io +except ImportError: + print("SKIP") + raise SystemExit + + +class DummySocket(io.IOBase): + def __init__(self): + self.write_buffer = bytearray() + self.read_buffer = bytearray() + + def write(self, data): + return len(data) + + def readinto(self, buf): + # This is a placeholder socket that doesn't actually read anything + # so the read buffer is always empty. + return None + + def ioctl(self, req, arg): + if req == 4: # MP_STREAM_CLOSE + return 0 + return -1 + + +# Create dummy sockets for testing +server_socket = DummySocket() +client_socket = DummySocket() + +# Wrap the DTLS Server +dtls_server_ctx = SSLContext(PROTOCOL_DTLS_SERVER) +dtls_server_ctx.verify_mode = CERT_NONE +dtls_server = dtls_server_ctx.wrap_socket( + server_socket, do_handshake_on_connect=False, client_id=b"dummy_client_id" +) +print("Wrapped DTLS Server") + +# wrap DTLS server with invalid client_id +try: + dtls_server = dtls_server_ctx.wrap_socket( + server_socket, do_handshake_on_connect=False, client_id=4 + ) +except OSError: + print("Failed to wrap DTLS Server with invalid client_id") + +# Wrap the DTLS Client +dtls_client_ctx = SSLContext(PROTOCOL_DTLS_CLIENT) +dtls_client_ctx.verify_mode = CERT_NONE +dtls_client = dtls_client_ctx.wrap_socket(client_socket, do_handshake_on_connect=False) +print("Wrapped DTLS Client") + +# Trigger the timing check multiple times with different elapsed times +for i in range(10): # Try multiple iterations to hit the timing window + dtls_client.write(b"test") + data = dtls_server.read(1024) # This should eventually hit the timing condition + +print("OK") diff --git a/tests/extmod/tls_dtls.py.exp b/tests/extmod/tls_dtls.py.exp new file mode 100644 index 00000000000..dbd005d0edf --- /dev/null +++ b/tests/extmod/tls_dtls.py.exp @@ -0,0 +1,4 @@ +Wrapped DTLS Server +Failed to wrap DTLS Server with invalid client_id +Wrapped DTLS Client +OK diff --git a/tests/extmod/tls_noleak.py b/tests/extmod/tls_noleak.py new file mode 100644 index 00000000000..870032d58e6 --- /dev/null +++ b/tests/extmod/tls_noleak.py @@ -0,0 +1,50 @@ +# Ensure that SSLSockets can be allocated sequentially +# without running out of available memory. +try: + import io + import tls +except ImportError: + print("SKIP") + raise SystemExit + +import unittest + + +class TestSocket(io.IOBase): + def write(self, buf): + return len(buf) + + def readinto(self, buf): + return 0 + + def ioctl(self, cmd, arg): + return 0 + + def setblocking(self, value): + pass + + +ITERS = 128 + + +class TLSNoLeaks(unittest.TestCase): + def test_unique_context(self): + for n in range(ITERS): + print(n) + s = TestSocket() + ctx = tls.SSLContext(tls.PROTOCOL_TLS_CLIENT) + ctx.verify_mode = tls.CERT_NONE + s = ctx.wrap_socket(s, do_handshake_on_connect=False) + + def test_shared_context(self): + # Single SSLContext, multiple sockets + ctx = tls.SSLContext(tls.PROTOCOL_TLS_CLIENT) + ctx.verify_mode = tls.CERT_NONE + for n in range(ITERS): + print(n) + s = TestSocket() + s = ctx.wrap_socket(s, do_handshake_on_connect=False) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/extmod/tls_threads.py b/tests/extmod/tls_threads.py new file mode 100644 index 00000000000..1e0c3d23d2f --- /dev/null +++ b/tests/extmod/tls_threads.py @@ -0,0 +1,58 @@ +# Ensure that SSL sockets can be allocated from multiple +# threads without thread safety issues + +try: + import _thread + import io + import tls + import time +except ImportError: + print("SKIP") + raise SystemExit + +import unittest + + +class TestSocket(io.IOBase): + def write(self, buf): + return len(buf) + + def readinto(self, buf): + return 0 + + def ioctl(self, cmd, arg): + return 0 + + def setblocking(self, value): + pass + + +ITERS = 256 + + +class TLSThreads(unittest.TestCase): + def test_sslsocket_threaded(self): + self.done = False + # only run in two threads: too much RAM demand otherwise, and rp2 only + # supports two anyhow + _thread.start_new_thread(self._alloc_many_sockets, (True,)) + self._alloc_many_sockets(False) + while not self.done: + time.sleep(0.1) + print("done") + + def _alloc_many_sockets(self, set_done_flag): + print("start", _thread.get_ident()) + ctx = tls.SSLContext(tls.PROTOCOL_TLS_CLIENT) + ctx.verify_mode = tls.CERT_NONE + for n in range(ITERS): + s = TestSocket() + s = ctx.wrap_socket(s, do_handshake_on_connect=False) + s.close() # Free associated resources now from thread, not in a GC pass + print("done", _thread.get_ident()) + if set_done_flag: + self.done = True + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/extmod/uctypes_addressof.py b/tests/extmod/uctypes_addressof.py new file mode 100644 index 00000000000..213fcc05eee --- /dev/null +++ b/tests/extmod/uctypes_addressof.py @@ -0,0 +1,19 @@ +# Test uctypes.addressof(). + +try: + from sys import maxsize + import uctypes +except ImportError: + print("SKIP") + raise SystemExit + +# Test small addresses. +for i in range(8): + print(uctypes.addressof(uctypes.bytearray_at(1 << i, 8))) + +# Test address that is bigger than the greatest small-int but still within the address range. +try: + large_addr = maxsize + 1 + print(uctypes.addressof(uctypes.bytearray_at(large_addr, 8)) == large_addr) +except OverflowError: + print(True) # systems with 64-bit bigints will overflow on the above operation diff --git a/tests/extmod/uctypes_addressof.py.exp b/tests/extmod/uctypes_addressof.py.exp new file mode 100644 index 00000000000..5b48569d018 --- /dev/null +++ b/tests/extmod/uctypes_addressof.py.exp @@ -0,0 +1,9 @@ +1 +2 +4 +8 +16 +32 +64 +128 +True diff --git a/tests/extmod/uctypes_array_load_store.py b/tests/extmod/uctypes_array_load_store.py index 9de07999856..695352da579 100644 --- a/tests/extmod/uctypes_array_load_store.py +++ b/tests/extmod/uctypes_array_load_store.py @@ -6,6 +6,13 @@ print("SKIP") raise SystemExit +# 'int' needs to be able to represent UINT64 for this test +try: + int("FF" * 8, 16) +except OverflowError: + print("SKIP") + raise SystemExit + N = 5 for endian in ("NATIVE", "LITTLE_ENDIAN", "BIG_ENDIAN"): diff --git a/tests/extmod/uctypes_sizeof.py b/tests/extmod/uctypes_sizeof.py index 6e52232e39e..d295cc85b68 100644 --- a/tests/extmod/uctypes_sizeof.py +++ b/tests/extmod/uctypes_sizeof.py @@ -43,8 +43,47 @@ print(uctypes.sizeof(S.sub)) assert uctypes.sizeof(S.sub) == 1 -# invalid descriptor +# invalid descriptors try: print(uctypes.sizeof([])) except TypeError: print("TypeError") + +try: + print(uctypes.sizeof(())) +except TypeError: + print("TypeError") + +try: + print(uctypes.sizeof(("garbage",))) +except TypeError: + print("TypeError") + +try: + # PTR * 3 is intended to be an invalid agg_type (STRUCT, PTR, ARRAY are valid ones). + print(uctypes.sizeof((uctypes.PTR * 3,))) +except TypeError: + print("TypeError") + +try: + print(uctypes.sizeof((0, {}, "garbage"))) +except TypeError: + print("TypeError") + +try: + print(uctypes.sizeof((uctypes.PTR | 0,))) +except TypeError: + print("TypeError") + +try: + print(uctypes.sizeof((uctypes.ARRAY | 0,))) +except TypeError: + print("TypeError") + +try: + print(uctypes.sizeof((uctypes.ARRAY | 0, 1, {}, "garbage"))) +except TypeError: + print("TypeError") + +# empty descriptor +print(uctypes.sizeof({})) diff --git a/tests/extmod/uctypes_sizeof.py.exp b/tests/extmod/uctypes_sizeof.py.exp index b35b11aa0ce..edcc05a441f 100644 --- a/tests/extmod/uctypes_sizeof.py.exp +++ b/tests/extmod/uctypes_sizeof.py.exp @@ -5,3 +5,11 @@ TypeError 6 1 TypeError +TypeError +TypeError +TypeError +TypeError +TypeError +TypeError +TypeError +0 diff --git a/tests/extmod/uctypes_sizeof_od.py b/tests/extmod/uctypes_sizeof_od.py index 375f05f5e2c..8aff3636315 100644 --- a/tests/extmod/uctypes_sizeof_od.py +++ b/tests/extmod/uctypes_sizeof_od.py @@ -45,9 +45,3 @@ print(uctypes.sizeof(S.sub)) assert uctypes.sizeof(S.sub) == 1 - -# invalid descriptor -try: - print(uctypes.sizeof([])) -except TypeError: - print("TypeError") diff --git a/tests/extmod/uctypes_sizeof_od.py.exp b/tests/extmod/uctypes_sizeof_od.py.exp index b35b11aa0ce..fb74def602b 100644 --- a/tests/extmod/uctypes_sizeof_od.py.exp +++ b/tests/extmod/uctypes_sizeof_od.py.exp @@ -4,4 +4,3 @@ TypeError 6 1 -TypeError diff --git a/tests/extmod/vfs_blockdev_invalid.py b/tests/extmod/vfs_blockdev_invalid.py new file mode 100644 index 00000000000..29d6bd6b2f9 --- /dev/null +++ b/tests/extmod/vfs_blockdev_invalid.py @@ -0,0 +1,89 @@ +# Tests where the block device returns invalid values + +try: + import vfs + + vfs.VfsFat + vfs.VfsLfs2 +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + + +class RAMBlockDevice: + ERASE_BLOCK_SIZE = 512 + + def __init__(self, blocks): + self.data = bytearray(blocks * self.ERASE_BLOCK_SIZE) + self.read_res = 0 + self.write_res = 0 + + def readblocks(self, block, buf, off=0): + # print("readblocks", block, len(buf), off) + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + buf[i] = self.data[addr + i] + return self.read_res + + def writeblocks(self, block, buf, off=None): + if off is None: + # erase, then write + off = 0 + addr = block * self.ERASE_BLOCK_SIZE + off + for i in range(len(buf)): + self.data[addr + i] = buf[i] + return self.write_res + + def ioctl(self, op, arg): + if op == 4: # block count + return len(self.data) // self.ERASE_BLOCK_SIZE + if op == 5: # block size + return self.ERASE_BLOCK_SIZE + if op == 6: # erase block + return 0 + + +try: + bdev = RAMBlockDevice(50) +except MemoryError: + print("SKIP") + raise SystemExit + + +def test(vfs_class): + print(vfs_class) + bdev.read_res = 0 # reset function results + bdev.write_res = 0 + + vfs_class.mkfs(bdev) + fs = vfs_class(bdev) + + with fs.open("test", "w") as f: + f.write("a" * 64) + + for res in (0, -5, 5, 33, "invalid"): + # -5 is a legitimate negative failure (EIO), positive integer + # is not + + # This variant will fail on open + bdev.read_res = res + try: + with fs.open("test", "r") as f: + print("opened") + except Exception as e: + print(type(e), e) + + # This variant should succeed on open, may fail on read + # unless the filesystem cached the contents already + bdev.read_res = 0 + try: + with fs.open("test", "r") as f: + bdev.read_res = res + print("read 1", f.read(1)) + print("read rest", f.read()) + except Exception as e: + print(type(e), e) + + +test(vfs.VfsLfs2) +test(vfs.VfsFat) diff --git a/tests/extmod/vfs_blockdev_invalid.py.exp b/tests/extmod/vfs_blockdev_invalid.py.exp new file mode 100644 index 00000000000..0ea0353501d --- /dev/null +++ b/tests/extmod/vfs_blockdev_invalid.py.exp @@ -0,0 +1,28 @@ + +opened +read 1 a +read rest aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + [Errno 5] EIO +read 1 a +read rest aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + [Errno 22] EINVAL +read 1 a +read rest aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + [Errno 22] EINVAL +read 1 a +read rest aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + can't convert str to int +read 1 a +read rest aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +opened +read 1 a +read rest aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + [Errno 5] EIO + [Errno 5] EIO + [Errno 5] EIO + [Errno 5] EIO + [Errno 5] EIO + [Errno 5] EIO + can't convert str to int + can't convert str to int diff --git a/tests/extmod/vfs_fat_ilistdir_del.py b/tests/extmod/vfs_fat_ilistdir_del.py index a6e24ec92f3..964e6b12868 100644 --- a/tests/extmod/vfs_fat_ilistdir_del.py +++ b/tests/extmod/vfs_fat_ilistdir_del.py @@ -1,8 +1,7 @@ # Test ilistdir __del__ for VfsFat using a RAM device. -import gc try: - import os, vfs + import gc, os, vfs vfs.VfsFat except (ImportError, AttributeError): diff --git a/tests/extmod/vfs_lfs.py b/tests/extmod/vfs_lfs.py index 3ad57fd9c38..40d58e9c9f7 100644 --- a/tests/extmod/vfs_lfs.py +++ b/tests/extmod/vfs_lfs.py @@ -136,7 +136,7 @@ def test(bdev, vfs_class): print(fs.getcwd()) fs.chdir("../testdir") print(fs.getcwd()) - fs.chdir("../..") + fs.chdir("..") print(fs.getcwd()) fs.chdir(".//testdir") print(fs.getcwd()) diff --git a/tests/extmod/vfs_lfs_error.py b/tests/extmod/vfs_lfs_error.py index 2ac7629bfa8..73cdf343733 100644 --- a/tests/extmod/vfs_lfs_error.py +++ b/tests/extmod/vfs_lfs_error.py @@ -1,7 +1,7 @@ # Test for VfsLittle using a RAM device, testing error handling try: - import vfs + import errno, vfs vfs.VfsLfs1 vfs.VfsLfs2 @@ -41,14 +41,14 @@ def test(bdev, vfs_class): # mkfs with too-small block device try: vfs_class.mkfs(RAMBlockDevice(1)) - except OSError: - print("mkfs OSError") + except OSError as er: + print("mkfs OSError", er.errno > 0) # mount with invalid filesystem try: vfs_class(bdev) - except OSError: - print("mount OSError") + except OSError as er: + print("mount OSError", er.errno > 0) # set up for following tests vfs_class.mkfs(bdev) @@ -60,60 +60,60 @@ def test(bdev, vfs_class): # ilistdir try: fs.ilistdir("noexist") - except OSError: - print("ilistdir OSError") + except OSError as er: + print("ilistdir OSError", er) # remove try: fs.remove("noexist") - except OSError: - print("remove OSError") + except OSError as er: + print("remove OSError", er) # rmdir try: fs.rmdir("noexist") - except OSError: - print("rmdir OSError") + except OSError as er: + print("rmdir OSError", er) # rename try: fs.rename("noexist", "somethingelse") - except OSError: - print("rename OSError") + except OSError as er: + print("rename OSError", er) # mkdir try: fs.mkdir("testdir") - except OSError: - print("mkdir OSError") + except OSError as er: + print("mkdir OSError", er) # chdir to nonexistent try: fs.chdir("noexist") - except OSError: - print("chdir OSError") + except OSError as er: + print("chdir OSError", er) print(fs.getcwd()) # check still at root # chdir to file try: fs.chdir("testfile") - except OSError: - print("chdir OSError") + except OSError as er: + print("chdir OSError", er) print(fs.getcwd()) # check still at root # stat try: fs.stat("noexist") - except OSError: - print("stat OSError") + except OSError as er: + print("stat OSError", er) # error during seek with fs.open("testfile", "r") as f: f.seek(1 << 30) # SEEK_SET try: f.seek(1 << 30, 1) # SEEK_CUR - except OSError: - print("seek OSError") + except OSError as er: + print("seek OSError", er) bdev = RAMBlockDevice(30) diff --git a/tests/extmod/vfs_lfs_error.py.exp b/tests/extmod/vfs_lfs_error.py.exp index f4327f6962e..440607ed84b 100644 --- a/tests/extmod/vfs_lfs_error.py.exp +++ b/tests/extmod/vfs_lfs_error.py.exp @@ -1,28 +1,28 @@ test -mkfs OSError -mount OSError -ilistdir OSError -remove OSError -rmdir OSError -rename OSError -mkdir OSError -chdir OSError +mkfs OSError True +mount OSError True +ilistdir OSError [Errno 2] ENOENT +remove OSError [Errno 2] ENOENT +rmdir OSError [Errno 2] ENOENT +rename OSError [Errno 2] ENOENT +mkdir OSError [Errno 17] EEXIST +chdir OSError [Errno 2] ENOENT / -chdir OSError +chdir OSError [Errno 2] ENOENT / -stat OSError -seek OSError +stat OSError [Errno 2] ENOENT +seek OSError [Errno 22] EINVAL test -mkfs OSError -mount OSError -ilistdir OSError -remove OSError -rmdir OSError -rename OSError -mkdir OSError -chdir OSError +mkfs OSError True +mount OSError True +ilistdir OSError [Errno 2] ENOENT +remove OSError [Errno 2] ENOENT +rmdir OSError [Errno 2] ENOENT +rename OSError [Errno 2] ENOENT +mkdir OSError [Errno 17] EEXIST +chdir OSError [Errno 2] ENOENT / -chdir OSError +chdir OSError [Errno 2] ENOENT / -stat OSError -seek OSError +stat OSError [Errno 2] ENOENT +seek OSError [Errno 22] EINVAL diff --git a/tests/extmod/vfs_lfs_ilistdir_del.py b/tests/extmod/vfs_lfs_ilistdir_del.py index 7b59bc412d9..828c85a2588 100644 --- a/tests/extmod/vfs_lfs_ilistdir_del.py +++ b/tests/extmod/vfs_lfs_ilistdir_del.py @@ -1,8 +1,7 @@ # Test ilistdir __del__ for VfsLittle using a RAM device. -import gc try: - import vfs + import gc, vfs vfs.VfsLfs2 except (ImportError, AttributeError): @@ -71,5 +70,10 @@ def test(bdev, vfs_class): fs.open("/test", "w").close() -bdev = RAMBlockDevice(30) +try: + bdev = RAMBlockDevice(30) +except MemoryError: + print("SKIP") + raise SystemExit + test(bdev, vfs.VfsLfs2) diff --git a/tests/extmod/vfs_lfs_mtime.py b/tests/extmod/vfs_lfs_mtime.py index 3d163dc2687..d4404de4dcb 100644 --- a/tests/extmod/vfs_lfs_mtime.py +++ b/tests/extmod/vfs_lfs_mtime.py @@ -3,7 +3,7 @@ try: import time, vfs - time.time + time.time_ns time.sleep vfs.VfsLfs2 except (ImportError, AttributeError): @@ -47,7 +47,8 @@ def test(bdev, vfs_class): fs = vfs_class(bdev, mtime=True) # Create an empty file, should have a timestamp. - current_time = int(time.time()) + # Use time_ns() for current time because that's what's used for VfsLfs2 time. + current_time = time.time_ns() // 1_000_000_000 fs.open("test1", "wt").close() # Wait 1 second so mtime will increase by at least 1. @@ -61,7 +62,7 @@ def test(bdev, vfs_class): stat2 = fs.stat("test2") print(stat1[8] != 0, stat2[8] != 0) - # Check that test1 has mtime which matches time.time() at point of creation. + # Check that test1 has mtime which matches time.time_ns() at point of creation. print(current_time <= stat1[8] <= current_time + 1) # Check that test1 is older than test2. diff --git a/tests/extmod/vfs_mountinfo.py b/tests/extmod/vfs_mountinfo.py new file mode 100644 index 00000000000..b31dc60ce76 --- /dev/null +++ b/tests/extmod/vfs_mountinfo.py @@ -0,0 +1,65 @@ +# test VFS functionality without any particular filesystem type + +try: + import os, vfs +except ImportError: + print("SKIP") + raise SystemExit + + +class Filesystem: + def __init__(self, id, paths=[]): + self.id = id + self.paths = paths + + def mount(self, readonly, mksfs): + print("mount", self) + + def umount(self): + print("umount", self) + + def stat(self, path): + if path in self.paths: + return (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) + else: + raise OSError + + statvfs = stat + + def open(self, path, mode): + pass + + def __repr__(self): + return "Filesystem(%d)" % self.id + + +# first we umount any existing mount points the target may have +try: + vfs.umount("/") +except OSError: + pass +for path in os.listdir("/"): + vfs.umount("/" + path) + + +print(vfs.mount()) + +vfs.mount(Filesystem(1), "/foo") + +print(vfs.mount()) + +vfs.mount(Filesystem(2), "/bar/baz") + +print(vfs.mount()) + +vfs.mount(Filesystem(3), "/bar") + +print(vfs.mount()) + +vfs.umount("/bar/baz") + +print(vfs.mount()) + +vfs.mount(Filesystem(4), "/") + +print(vfs.mount()) diff --git a/tests/extmod/vfs_mountinfo.py.exp b/tests/extmod/vfs_mountinfo.py.exp new file mode 100644 index 00000000000..4ddf06c8c97 --- /dev/null +++ b/tests/extmod/vfs_mountinfo.py.exp @@ -0,0 +1,11 @@ +[] +mount Filesystem(1) +[(Filesystem(1), '/foo')] +mount Filesystem(2) +[(Filesystem(1), '/foo'), (Filesystem(2), '/bar/baz')] +mount Filesystem(3) +[(Filesystem(1), '/foo'), (Filesystem(2), '/bar/baz'), (Filesystem(3), '/bar')] +umount Filesystem(2) +[(Filesystem(1), '/foo'), (Filesystem(3), '/bar')] +mount Filesystem(4) +[(Filesystem(1), '/foo'), (Filesystem(3), '/bar'), (Filesystem(4), '/')] diff --git a/tests/extmod/vfs_posix.py b/tests/extmod/vfs_posix.py index d060c0b9c84..b3ca2753ba9 100644 --- a/tests/extmod/vfs_posix.py +++ b/tests/extmod/vfs_posix.py @@ -29,7 +29,21 @@ print(type(os.stat("/"))) # listdir and ilistdir -print(type(os.listdir("/"))) +target = "/" +try: + import platform + + # On Android non-root users are permitted full filesystem access only to + # selected directories. To let this test pass on bionic, the internal + # user-accessible storage area root is enumerated instead of the + # filesystem root. "/storage/emulated/0" should be there on pretty much + # any recent-ish device; querying the proper location requires a JNI + # round-trip, not really worth it. + if platform.platform().startswith("Android-"): + target = "/storage/emulated/0" +except ImportError: + pass +print(type(os.listdir(target))) # mkdir os.mkdir(temp_dir) diff --git a/tests/extmod/vfs_posix_ilistdir_del.py b/tests/extmod/vfs_posix_ilistdir_del.py index 78d7c854c54..8b5984cd81c 100644 --- a/tests/extmod/vfs_posix_ilistdir_del.py +++ b/tests/extmod/vfs_posix_ilistdir_del.py @@ -1,8 +1,7 @@ # Test ilistdir __del__ for VfsPosix. -import gc try: - import os, vfs + import gc, os, vfs vfs.VfsPosix except (ImportError, AttributeError): diff --git a/tests/extmod/vfs_posix_paths.py b/tests/extmod/vfs_posix_paths.py index b4fedc6716f..c06318748a3 100644 --- a/tests/extmod/vfs_posix_paths.py +++ b/tests/extmod/vfs_posix_paths.py @@ -31,7 +31,7 @@ fs.mkdir("subdir/one") print('listdir("/"):', sorted(i[0] for i in fs.ilistdir("/"))) print('listdir("."):', sorted(i[0] for i in fs.ilistdir("."))) -print('getcwd() in {"", "/"}:', fs.getcwd() in {"", "/"}) +print('getcwd() in ("", "/"):', fs.getcwd() in ("", "/")) print('chdir("subdir"):', fs.chdir("subdir")) print("getcwd():", fs.getcwd()) print('mkdir("two"):', fs.mkdir("two")) diff --git a/tests/extmod/vfs_posix_paths.py.exp b/tests/extmod/vfs_posix_paths.py.exp index ecc13222aaa..d6a0960efd2 100644 --- a/tests/extmod/vfs_posix_paths.py.exp +++ b/tests/extmod/vfs_posix_paths.py.exp @@ -1,6 +1,6 @@ listdir("/"): ['subdir'] listdir("."): ['subdir'] -getcwd() in {"", "/"}: True +getcwd() in ("", "/"): True chdir("subdir"): None getcwd(): /subdir mkdir("two"): None diff --git a/tests/extmod/vfs_posix_readonly.py b/tests/extmod/vfs_posix_readonly.py new file mode 100644 index 00000000000..e7821381006 --- /dev/null +++ b/tests/extmod/vfs_posix_readonly.py @@ -0,0 +1,99 @@ +# Test for VfsPosix + +try: + import gc, os, vfs, errno + + vfs.VfsPosix +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +# We need a directory for testing that doesn't already exist. +# Skip the test if it does exist. +temp_dir = "vfs_posix_readonly_test_dir" +try: + os.stat(temp_dir) + raise SystemExit("Target directory {} exists".format(temp_dir)) +except OSError: + pass + +# mkdir (skip test if whole filesystem is readonly) +try: + os.mkdir(temp_dir) +except OSError as e: + if e.errno == errno.EROFS: + print("SKIP") + raise SystemExit + +fs_factory = lambda: vfs.VfsPosix(temp_dir) + +# mount +fs = fs_factory() +vfs.mount(fs, "/vfs") + +with open("/vfs/file", "w") as f: + f.write("content") + +# test reading works +with open("/vfs/file") as f: + print("file:", f.read()) + +os.mkdir("/vfs/emptydir") + +# umount +vfs.umount("/vfs") + +# mount read-only +fs = fs_factory() +vfs.mount(fs, "/vfs", readonly=True) + +# test reading works +with open("/vfs/file") as f: + print("file 2:", f.read()) + +# test writing fails +try: + with open("/vfs/test_write", "w"): + pass + print("opened") +except OSError as er: + print(repr(er)) + +# test removing fails +try: + os.unlink("/vfs/file") + print("unlinked") +except OSError as er: + print(repr(er)) + +# test renaming fails +try: + os.rename("/vfs/file2", "/vfs/renamed") + print("renamed") +except OSError as er: + print(repr(er)) + +# test removing directory fails +try: + os.rmdir("/vfs/emptydir") + print("rmdir'd") +except OSError as er: + print(repr(er)) + +# test creating directory fails +try: + os.mkdir("/vfs/emptydir2") + print("mkdir'd") +except OSError as er: + print(repr(er)) + +# umount +vfs.umount("/vfs") + +fs = fs_factory() +vfs.mount(fs, "/vfs") + +os.rmdir("/vfs/emptydir") +os.unlink("/vfs/file") + +os.rmdir(temp_dir) diff --git a/tests/extmod/vfs_posix_readonly.py.exp b/tests/extmod/vfs_posix_readonly.py.exp new file mode 100644 index 00000000000..40e4316775f --- /dev/null +++ b/tests/extmod/vfs_posix_readonly.py.exp @@ -0,0 +1,7 @@ +file: content +file 2: content +OSError(30,) +OSError(30,) +OSError(30,) +OSError(30,) +OSError(30,) diff --git a/tests/extmod/vfs_rom.py b/tests/extmod/vfs_rom.py new file mode 100644 index 00000000000..18ae1f5cf96 --- /dev/null +++ b/tests/extmod/vfs_rom.py @@ -0,0 +1,489 @@ +# Test VfsRom filesystem. + +try: + import errno, sys, struct, os, uctypes, vfs + + vfs.VfsRom +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +try: + import select +except ImportError: + select = None + +import unittest + +IFDIR = 0x4000 +IFREG = 0x8000 + +SEEK_SET = 0 +SEEK_CUR = 1 +SEEK_END = 2 + +# An mpy file with four constant objects: str, bytes, long-int, float. +test_mpy = ( + # header + b"M\x06\x00\x1e" # mpy file header, -msmall-int-bits=30 + b"\x06" # n_qstr + b"\x05" # n_obj + # qstrs + b"\x0etest.py\x00" # qstr0 = "test.py" + b"\x0f" # qstr1 = "" + b"\x0estr_obj\x00" # qstr2 = "str_obj" + b"\x12bytes_obj\x00" # qstr3 = "bytes_obj" + b"\x0eint_obj\x00" # qstr4 = "int_obj" + b"\x12float_obj\x00" # qstr5 = "float_obj" + # objects + b"\x05\x14this is a str object\x00" + b"\x06\x16this is a bytes object\x00" + b"\x07\x0a1234567890" # long-int object + b"\x08\x041.23" # float object + b"\x05\x07str_obj\x00" # str object of existing qstr + # bytecode + b"\x81\x28" # 21 bytes, no children, bytecode + b"\x00\x02" # prelude + b"\x01" # simple name () + b"\x23\x00" # LOAD_CONST_OBJ(0) + b"\x16\x02" # STORE_NAME(str_obj) + b"\x23\x01" # LOAD_CONST_OBJ(1) + b"\x16\x03" # STORE_NAME(bytes_obj) + b"\x23\x02" # LOAD_CONST_OBJ(2) + b"\x16\x04" # STORE_NAME(int_obj) + b"\x23\x03" # LOAD_CONST_OBJ(3) + b"\x16\x05" # STORE_NAME(float_obj) + b"\x51" # LOAD_CONST_NONE + b"\x63" # RETURN_VALUE +) + + +class VfsRomWriter: + ROMFS_HEADER = b"\xd2\xcd\x31" + + ROMFS_RECORD_KIND_UNUSED = 0 + ROMFS_RECORD_KIND_PADDING = 1 + ROMFS_RECORD_KIND_DATA_VERBATIM = 2 + ROMFS_RECORD_KIND_DATA_POINTER = 3 + ROMFS_RECORD_KIND_DIRECTORY = 4 + ROMFS_RECORD_KIND_FILE = 5 + + def __init__(self): + self._dir_stack = [(None, bytearray())] + + def _encode_uint(self, value): + encoded = [value & 0x7F] + value >>= 7 + while value != 0: + encoded.insert(0, 0x80 | (value & 0x7F)) + value >>= 7 + return bytes(encoded) + + def _pack(self, kind, payload): + return self._encode_uint(kind) + self._encode_uint(len(payload)) + payload + + def _extend(self, data): + buf = self._dir_stack[-1][1] + buf.extend(data) + return len(buf) + + def finalise(self): + _, data = self._dir_stack.pop() + encoded_kind = VfsRomWriter.ROMFS_HEADER + encoded_len = self._encode_uint(len(data)) + if (len(encoded_kind) + len(encoded_len) + len(data)) % 2 == 1: + encoded_len = b"\x80" + encoded_len + data = encoded_kind + encoded_len + data + return data + + def opendir(self, dirname): + self._dir_stack.append((dirname, bytearray())) + + def closedir(self): + dirname, dirdata = self._dir_stack.pop() + dirdata = self._encode_uint(len(dirname)) + bytes(dirname, "ascii") + dirdata + self._extend(self._pack(VfsRomWriter.ROMFS_RECORD_KIND_DIRECTORY, dirdata)) + + def mkdata(self, data): + assert len(self._dir_stack) == 1 + return self._extend(self._pack(VfsRomWriter.ROMFS_RECORD_KIND_DATA_VERBATIM, data)) - len( + data + ) + + def mkfile(self, filename, filedata, extra_payload=b""): + filename = bytes(filename, "ascii") + payload = self._encode_uint(len(filename)) + payload += filename + payload += extra_payload + if isinstance(filedata, tuple): + sub_payload = self._encode_uint(filedata[0]) + sub_payload += self._encode_uint(filedata[1]) + payload += self._pack(VfsRomWriter.ROMFS_RECORD_KIND_DATA_POINTER, sub_payload) + else: + payload += self._pack(VfsRomWriter.ROMFS_RECORD_KIND_DATA_VERBATIM, filedata) + self._dir_stack[-1][1].extend(self._pack(VfsRomWriter.ROMFS_RECORD_KIND_FILE, payload)) + + +def _make_romfs(fs, files, data_map): + for filename, contents in files: + if isinstance(contents, tuple): + fs.opendir(filename) + _make_romfs(fs, contents, data_map) + fs.closedir() + elif isinstance(contents, int): + fs.mkfile(filename, data_map[contents]) + else: + fs.mkfile(filename, contents) + + +def make_romfs(files, data=None): + fs = VfsRomWriter() + data_map = {} + if data: + for k, v in data.items(): + data_map[k] = len(v), fs.mkdata(v) + _make_romfs(fs, files, data_map) + return fs.finalise() + + +# A class to test if a value is within a range, needed because MicroPython's range +# doesn't support arbitrary objects. +class Range: + def __init__(self, lower, upper): + self._lower = lower + self._upper = upper + + def __repr__(self): + return "Range({}, {})".format(self._lower, self._upper) + + def __contains__(self, value): + return self._lower <= value < self._upper + + +class TestBase(unittest.TestCase): + @classmethod + def setUpClass(cls): + fs_inner = make_romfs((("test_inner.txt", b"contents_inner"), ("c.py", b""))) + cls.romfs = make_romfs( + ( + ("fs.romfs", 0), + ("test.txt", b"contents"), + ( + "dir", + ( + ("a.py", b"x = 1"), + ("b.py", b"x = 2"), + ("test.mpy", test_mpy), + ), + ), + ), + {0: fs_inner}, + ) + cls.romfs_ilistdir = [ + ("fs.romfs", IFREG, 0, 46), + ("test.txt", IFREG, 0, 8), + ("dir", IFDIR, 0, 198), + ] + cls.romfs_listdir = [x[0] for x in cls.romfs_ilistdir] + cls.romfs_listdir_dir = ["a.py", "b.py", "test.mpy"] + cls.romfs_listdir_bytes = [bytes(x, "ascii") for x in cls.romfs_listdir] + cls.romfs_addr = uctypes.addressof(cls.romfs) + cls.romfs_addr_range = Range(cls.romfs_addr, cls.romfs_addr + len(cls.romfs)) + + +class TestEdgeCases(unittest.TestCase): + def test_empty_romfs(self): + empty_romfs = make_romfs(()) + self.assertEqual(empty_romfs, bytes([0x80 | ord("R"), 0x80 | ord("M"), ord("1"), 0])) + fs = vfs.VfsRom(empty_romfs) + self.assertIsInstance(fs, vfs.VfsRom) + fs.mount(True, False) + self.assertEqual(list(fs.ilistdir("")), []) + self.assertEqual(fs.stat(""), (IFDIR, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + self.assertEqual(fs.statvfs(""), (1, 0, 0, 0, 0, 0, 0, 0, 0, 32767)) + + def test_error(self): + for bad_romfs in (b"", b"xxx", b"not a romfs"): + with self.assertRaises(OSError) as ctx: + vfs.VfsRom(bad_romfs) + self.assertEqual(ctx.exception.errno, errno.ENODEV) + + def test_unknown_record(self): + fs = VfsRomWriter() + fs._extend(fs._pack(VfsRomWriter.ROMFS_RECORD_KIND_PADDING, b"payload")) + fs.mkfile( + "test", + b"contents", + extra_payload=fs._pack(VfsRomWriter.ROMFS_RECORD_KIND_PADDING, b"pad"), + ) + romfs = fs.finalise() + fs = vfs.VfsRom(romfs) + self.assertEqual(list(fs.ilistdir("")), [("test", IFREG, 0, 8)]) + with fs.open("test", "rb") as f: + self.assertEqual(f.read(), b"contents") + + +class TestCorrupt(unittest.TestCase): + def test_corrupt_filesystem(self): + # Make the filesystem length bigger than the buffer. + romfs = bytearray(make_romfs(())) + romfs[3] = 0x01 + with self.assertRaises(OSError): + vfs.VfsRom(romfs) + + # Corrupt the filesystem length. + romfs = bytearray(make_romfs(())) + romfs[3] = 0xFF + with self.assertRaises(OSError): + vfs.VfsRom(romfs) + + # Corrupt the contents of the filesystem. + romfs = bytearray(make_romfs(())) + romfs[3] = 0x01 + romfs.extend(b"\xff\xff") + fs = vfs.VfsRom(romfs) + with self.assertRaises(OSError): + fs.stat("a") + self.assertEqual(list(fs.ilistdir("")), []) + + def test_corrupt_file_entry(self): + romfs = make_romfs((("file", b"data"),)) + + # Corrupt the length of filename. + romfs_corrupt = bytearray(romfs) + romfs_corrupt[7:] = b"\xff" * (len(romfs) - 7) + fs = vfs.VfsRom(romfs_corrupt) + with self.assertRaises(OSError): + fs.stat("file") + self.assertEqual(list(fs.ilistdir("")), []) + + # Erase the data record (change it to a padding record). + romfs_corrupt = bytearray(romfs) + romfs_corrupt[12] = VfsRomWriter.ROMFS_RECORD_KIND_PADDING + fs = vfs.VfsRom(romfs_corrupt) + with self.assertRaises(OSError): + fs.stat("file") + self.assertEqual(list(fs.ilistdir("")), []) + + # Corrupt the header of the data record. + romfs_corrupt = bytearray(romfs) + romfs_corrupt[12:] = b"\xff" * (len(romfs) - 12) + fs = vfs.VfsRom(romfs_corrupt) + with self.assertRaises(OSError): + fs.stat("file") + + # Corrupt the interior of the data record. + romfs_corrupt = bytearray(romfs) + romfs_corrupt[13:] = b"\xff" * (len(romfs) - 13) + fs = vfs.VfsRom(romfs_corrupt) + with self.assertRaises(OSError): + fs.stat("file") + + # Change the data record to an indirect pointer and corrupt the length. + romfs_corrupt = bytearray(romfs) + romfs_corrupt[12] = VfsRomWriter.ROMFS_RECORD_KIND_DATA_POINTER + romfs_corrupt[14:18] = b"\xff\xff\xff\xff" + fs = vfs.VfsRom(romfs_corrupt) + with self.assertRaises(OSError): + fs.stat("file") + + # Change the data record to an indirect pointer and corrupt the offset. + romfs_corrupt = bytearray(romfs) + romfs_corrupt[12] = VfsRomWriter.ROMFS_RECORD_KIND_DATA_POINTER + romfs_corrupt[14:18] = b"\x00\xff\xff\xff" + fs = vfs.VfsRom(romfs_corrupt) + with self.assertRaises(OSError): + fs.stat("file") + + +class TestStandalone(TestBase): + def test_constructor(self): + self.assertIsInstance(vfs.VfsRom(self.romfs), vfs.VfsRom) + with self.assertRaises(TypeError): + vfs.VfsRom(self.romfs_addr) + + def test_mount(self): + vfs.VfsRom(self.romfs).mount(True, False) + with self.assertRaises(OSError): + vfs.VfsRom(self.romfs).mount(True, True) + + def test_ilistdir(self): + fs = vfs.VfsRom(self.romfs) + self.assertEqual(list(fs.ilistdir("")), self.romfs_ilistdir) + self.assertEqual(list(fs.ilistdir("/")), self.romfs_ilistdir) + with self.assertRaises(OSError): + fs.ilistdir("does not exist") + + def test_stat(self): + fs = vfs.VfsRom(self.romfs) + self.assertEqual(fs.stat(""), (IFDIR, 0, 0, 0, 0, 0, 289, 0, 0, 0)) + self.assertEqual(fs.stat("/"), (IFDIR, 0, 0, 0, 0, 0, 289, 0, 0, 0)) + self.assertEqual(fs.stat("/test.txt"), (IFREG, 0, 0, 0, 0, 0, 8, 0, 0, 0)) + self.assertEqual(fs.stat("/dir"), (IFDIR, 0, 0, 0, 0, 0, 198, 0, 0, 0)) + with self.assertRaises(OSError): + fs.stat("/does-not-exist") + + def test_statvfs(self): + fs = vfs.VfsRom(self.romfs) + self.assertEqual(fs.statvfs(""), (1, 0, 289, 0, 0, 0, 0, 0, 0, 32767)) + + def test_open(self): + fs = vfs.VfsRom(self.romfs) + + with fs.open("/test.txt", "") as f: + self.assertEqual(f.read(), "contents") + with fs.open("/test.txt", "rt") as f: + self.assertEqual(f.read(), "contents") + with fs.open("/test.txt", "rb") as f: + self.assertEqual(f.read(), b"contents") + + with self.assertRaises(OSError) as ctx: + fs.open("/file-does-not-exist", "") + self.assertEqual(ctx.exception.errno, errno.ENOENT) + + with self.assertRaises(OSError) as ctx: + fs.open("/dir", "rb") + self.assertEqual(ctx.exception.errno, errno.EISDIR) + + with self.assertRaises(OSError): + fs.open("/test.txt", "w") + with self.assertRaises(OSError): + fs.open("/test.txt", "a") + with self.assertRaises(OSError): + fs.open("/test.txt", "+") + + def test_file_seek(self): + fs = vfs.VfsRom(self.romfs) + with fs.open("/test.txt", "") as f: + self.assertEqual(f.seek(0, SEEK_SET), 0) + self.assertEqual(f.seek(3, SEEK_SET), 3) + self.assertEqual(f.read(), "tents") + self.assertEqual(f.seek(0, SEEK_SET), 0) + self.assertEqual(f.seek(100, SEEK_CUR), 8) + self.assertEqual(f.seek(-1, SEEK_END), 7) + self.assertEqual(f.read(), "s") + self.assertEqual(f.seek(1, SEEK_END), 8) + with self.assertRaises(OSError): + f.seek(-1, SEEK_SET) + f.seek(0, SEEK_SET) + with self.assertRaises(OSError): + f.seek(-1, SEEK_CUR) + with self.assertRaises(OSError): + f.seek(-100, SEEK_END) + + @unittest.skipIf(select is None, "no select module") + def test_file_ioctl_invalid(self): + fs = vfs.VfsRom(self.romfs) + with fs.open("/test.txt", "") as f: + p = select.poll() + p.register(f) + with self.assertRaises(OSError): + p.poll(0) + + def test_memory_mapping(self): + fs = vfs.VfsRom(self.romfs) + with fs.open("/test.txt", "rb") as f: + addr = uctypes.addressof(f) + data = memoryview(f) + self.assertIn(addr, self.romfs_addr_range) + self.assertIn(addr + len(data), self.romfs_addr_range) + self.assertEqual(bytes(data), b"contents") + + +class TestMounted(TestBase): + def setUp(self): + self.orig_sys_path = list(sys.path) + self.orig_cwd = os.getcwd() + sys.path = [] + vfs.mount(vfs.VfsRom(self.romfs), "/test_rom") + + def tearDown(self): + vfs.umount("/test_rom") + os.chdir(self.orig_cwd) + sys.path = self.orig_sys_path + + def test_listdir(self): + self.assertEqual(os.listdir("/test_rom"), self.romfs_listdir) + self.assertEqual(os.listdir("/test_rom/dir"), self.romfs_listdir_dir) + self.assertEqual(os.listdir(b"/test_rom"), self.romfs_listdir_bytes) + + def test_chdir(self): + os.chdir("/test_rom") + self.assertEqual(os.getcwd(), "/test_rom") + self.assertEqual(os.listdir(), self.romfs_listdir) + + os.chdir("/test_rom/") + self.assertEqual(os.getcwd(), "/test_rom") + self.assertEqual(os.listdir(), self.romfs_listdir) + + # chdir within the romfs is not implemented. + with self.assertRaises(OSError): + os.chdir("/test_rom/dir") + + def test_stat(self): + self.assertEqual(os.stat("/test_rom"), (IFDIR, 0, 0, 0, 0, 0, 289, 0, 0, 0)) + self.assertEqual(os.stat("/test_rom/"), (IFDIR, 0, 0, 0, 0, 0, 289, 0, 0, 0)) + self.assertEqual(os.stat("/test_rom/test.txt"), (IFREG, 0, 0, 0, 0, 0, 8, 0, 0, 0)) + self.assertEqual(os.stat("/test_rom/dir"), (IFDIR, 0, 0, 0, 0, 0, 198, 0, 0, 0)) + with self.assertRaises(OSError): + os.stat("/test_rom/does-not-exist") + + def test_open(self): + with open("/test_rom/test.txt") as f: + self.assertEqual(f.read(), "contents") + with open("/test_rom/test.txt", "b") as f: + self.assertEqual(f.read(), b"contents") + + with self.assertRaises(OSError) as ctx: + open("/test_rom/file-does-not-exist") + self.assertEqual(ctx.exception.errno, errno.ENOENT) + + with self.assertRaises(OSError) as ctx: + open("/test_rom/dir") + self.assertEqual(ctx.exception.errno, errno.EISDIR) + + def test_import_py(self): + sys.path.append("/test_rom/dir") + a = __import__("a") + b = __import__("b") + self.assertEqual(a.__file__, "/test_rom/dir/a.py") + self.assertEqual(a.x, 1) + self.assertEqual(b.__file__, "/test_rom/dir/b.py") + self.assertEqual(b.x, 2) + + def test_import_mpy(self): + sys.path.append("/test_rom/dir") + test = __import__("test") + self.assertEqual(test.__file__, "/test_rom/dir/test.mpy") + self.assertEqual(test.str_obj, "this is a str object") + self.assertEqual(test.bytes_obj, b"this is a bytes object") + self.assertEqual(test.int_obj, 1234567890) + self.assertEqual(test.float_obj, 1.23) + self.assertIn(uctypes.addressof(test.str_obj), self.romfs_addr_range) + self.assertIn(uctypes.addressof(test.bytes_obj), self.romfs_addr_range) + + def test_romfs_inner(self): + with open("/test_rom/fs.romfs", "rb") as f: + romfs_inner = vfs.VfsRom(memoryview(f)) + + vfs.mount(romfs_inner, "/test_rom2") + + self.assertEqual(os.listdir("/test_rom2"), ["test_inner.txt", "c.py"]) + + sys.path.append("/test_rom2") + self.assertEqual(__import__("c").__file__, "/test_rom2/c.py") + + with open("/test_rom2/test_inner.txt") as f: + self.assertEqual(f.read(), "contents_inner") + + with open("/test_rom2/test_inner.txt", "rb") as f: + addr = uctypes.addressof(f) + data = memoryview(f) + self.assertIn(addr, self.romfs_addr_range) + self.assertIn(addr + len(data), self.romfs_addr_range) + + vfs.umount("/test_rom2") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/extmod/websocket_toobig.py b/tests/extmod/websocket_toobig.py new file mode 100644 index 00000000000..f4c5a74bbce --- /dev/null +++ b/tests/extmod/websocket_toobig.py @@ -0,0 +1,28 @@ +try: + import io + import errno + import websocket +except ImportError: + print("SKIP") + raise SystemExit + +try: + buf = "x" * 65536 +except MemoryError: + print("SKIP") + raise SystemExit + + +# do a websocket write and then return the raw data from the stream +def ws_write(msg, sz): + s = io.BytesIO() + ws = websocket.websocket(s) + ws.write(msg) + s.seek(0) + return s.read(sz) + + +try: + print(ws_write(buf, 1)) +except OSError as e: + print("ioctl: ENOBUFS:", e.errno == errno.ENOBUFS) diff --git a/tests/extmod/websocket_toobig.py.exp b/tests/extmod/websocket_toobig.py.exp new file mode 100644 index 00000000000..3bbd95282fd --- /dev/null +++ b/tests/extmod/websocket_toobig.py.exp @@ -0,0 +1 @@ +ioctl: ENOBUFS: True diff --git a/tests/extmod_hardware/machine_counter.py b/tests/extmod_hardware/machine_counter.py new file mode 100644 index 00000000000..62ac1fed47c --- /dev/null +++ b/tests/extmod_hardware/machine_counter.py @@ -0,0 +1,90 @@ +# Test machine.Counter implementation +# +# IMPORTANT: This test requires hardware connections: the out_pin and in_pin +# must be wired together. + +try: + from machine import Counter +except ImportError: + print("SKIP") + raise SystemExit + +import sys +from machine import Pin + +if "esp32" in sys.platform: + id = 0 + out_pin = 4 + in_pin = 5 +else: + print("Please add support for this test on this platform.") + raise SystemExit + +import unittest + +out_pin = Pin(out_pin, mode=Pin.OUT) +in_pin = Pin(in_pin, mode=Pin.IN) + + +def toggle(times): + for _ in range(times): + out_pin(1) + out_pin(0) + + +class TestCounter(unittest.TestCase): + def setUp(self): + out_pin(0) + self.counter = Counter(id, in_pin) + + def tearDown(self): + self.counter.deinit() + + def assertCounter(self, value): + self.assertEqual(self.counter.value(), value) + + def test_connections(self): + # Test the hardware connections are correct. If this test fails, all tests will fail. + out_pin(1) + self.assertEqual(1, in_pin()) + out_pin(0) + self.assertEqual(0, in_pin()) + + def test_count_rising(self): + self.assertCounter(0) + toggle(100) + self.assertCounter(100) + out_pin(1) + self.assertEqual(self.counter.value(0), 101) + self.assertCounter(0) # calling value(0) resets + out_pin(0) + self.assertCounter(0) # no rising edge + out_pin(1) + self.assertCounter(1) + + def test_change_directions(self): + self.assertCounter(0) + toggle(100) + self.assertCounter(100) + self.counter.init(in_pin, direction=Counter.DOWN) + self.assertCounter(0) # calling init() zeroes the counter + self.counter.value(100) # need to manually reset the value + self.assertCounter(100) + toggle(25) + self.assertCounter(75) + + def test_count_falling(self): + self.counter.init(in_pin, direction=Counter.UP, edge=Counter.FALLING) + toggle(20) + self.assertCounter(20) + out_pin(1) + self.assertCounter(20) # no falling edge + out_pin(0) + self.assertCounter(21) + self.counter.value(-(2**24)) + toggle(20) + self.assertCounter(-(2**24 - 20)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/extmod_hardware/machine_encoder.py b/tests/extmod_hardware/machine_encoder.py new file mode 100644 index 00000000000..c218c8bfb64 --- /dev/null +++ b/tests/extmod_hardware/machine_encoder.py @@ -0,0 +1,153 @@ +# Test machine.Encoder implementation +# +# IMPORTANT: This test requires hardware connections: +# - out0_pin and in0_pin must be wired together. +# - out1_pin and in1_pin must be wired together. + +try: + from machine import Encoder +except ImportError: + print("SKIP") + raise SystemExit + +import sys +import unittest +from machine import Pin +from target_wiring import encoder_loopback_id, encoder_loopback_out_pins, encoder_loopback_in_pins + +PRINT = False +PIN_INIT_VALUE = 1 + +id = encoder_loopback_id +out0_pin, out1_pin = encoder_loopback_out_pins +in0_pin, in1_pin = encoder_loopback_in_pins + +out0_pin = Pin(out0_pin, mode=Pin.OUT) +in0_pin = Pin(in0_pin, mode=Pin.IN) +out1_pin = Pin(out1_pin, mode=Pin.OUT) +in1_pin = Pin(in1_pin, mode=Pin.IN) + + +class TestEncoder(unittest.TestCase): + def setUp(self): + out0_pin(PIN_INIT_VALUE) + out1_pin(PIN_INIT_VALUE) + self.enc = Encoder(id, in0_pin, in1_pin, phases=1) + self.enc2 = Encoder(id + 1, in0_pin, in1_pin, phases=2) + self.enc4 = Encoder(id + 2, in0_pin, in1_pin, phases=4) + self.pulses = 0 # track the expected encoder position in software + if PRINT: + print( + "\nout0_pin() out1_pin() enc.value() enc2.value() enc4.value() |", + out0_pin(), + out1_pin(), + "|", + self.enc.value(), + self.enc2.value(), + self.enc4.value(), + ) + + def tearDown(self): + self.enc.deinit() + try: + self.enc2.deinit() + except: + pass + try: + self.enc4.deinit() + except: + pass + + def rotate(self, pulses): + for _ in range(abs(pulses)): + self.pulses += 1 if (pulses > 0) else -1 + if pulses > 0: + if self.pulses % 2: + out0_pin(not out0_pin()) + else: + out1_pin(not out1_pin()) + else: + if self.pulses % 2: + out1_pin(not out1_pin()) + else: + out0_pin(not out0_pin()) + if PRINT: + print( + "out0_pin() out1_pin() enc.value() enc2.value() enc4.value() pulses self.pulses |", + out0_pin(), + out1_pin(), + "|", + self.enc.value(), + self.enc2.value(), + self.enc4.value(), + "|", + pulses, + self.pulses, + ) + + def assertPosition(self, value, value2=None, value4=None): + self.assertEqual(self.enc.value(), value) + if not value2 is None: + self.assertEqual(self.enc2.value(), value2) + if not value4 is None: + self.assertEqual(self.enc4.value(), value4) + pass + + @unittest.skipIf(sys.platform == "mimxrt", "cannot read back the pin") + def test_connections(self): + # Test the hardware connections are correct. If this test fails, all tests will fail. + for ch, outp, inp in ((0, out0_pin, in0_pin), (1, out1_pin, in1_pin)): + print("Testing channel ", ch) + outp(1) + self.assertEqual(1, inp()) + outp(0) + self.assertEqual(0, inp()) + + def test_basics(self): + self.assertPosition(0) + self.rotate(100) + self.assertPosition(100 // 4, 100 // 2, 100) + self.rotate(-100) + self.assertPosition(0) + + def test_partial(self): + # With phase=1 (default), need 4x pulses to count a rotation + self.assertPosition(0) + self.rotate(1) + self.assertPosition(1, 1, 1) + self.rotate(1) + self.assertPosition(1, 1, 2) + self.rotate(1) + self.assertPosition(1, 2, 3) + self.rotate(1) + self.assertPosition(1, 2, 4) # +4 + self.rotate(1) + self.assertPosition(2, 3, 5) + self.rotate(1) + self.assertPosition(2, 3, 6) + self.rotate(1) + self.assertPosition(2, 4, 7) + self.rotate(1) + self.assertPosition(2, 4, 8) # +4 + self.rotate(-1) + self.assertPosition(2, 4, 7) + self.rotate(-3) + self.assertPosition(1, 2, 4) # -4 + self.rotate(-4) + self.assertPosition(0, 0, 0) # -4 + self.rotate(-1) + self.assertPosition(0, 0, -1) + self.rotate(-1) + self.assertPosition(0, -1, -2) + self.rotate(-1) + self.assertPosition(0, -1, -3) + self.rotate(-1) + self.assertPosition(-1, -2, -4) # -4 + self.rotate(-1) + self.assertPosition(-1, -2, -5) + self.rotate(-3) + self.assertPosition(-2, -4, -8) # -4 + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/extmod_hardware/machine_i2c_target.py b/tests/extmod_hardware/machine_i2c_target.py new file mode 100644 index 00000000000..763e6f4771e --- /dev/null +++ b/tests/extmod_hardware/machine_i2c_target.py @@ -0,0 +1,307 @@ +# Test machine.I2CTarget. +# +# IMPORTANT: This test requires hardware connections: a SoftI2C instance must be +# wired to a hardware I2C target. See pin definitions below. + +import sys + +try: + from machine import Pin, SoftI2C, I2CTarget +except ImportError: + print("SKIP") + raise SystemExit + +import unittest + +ADDR = 67 + +kwargs_target = {} + +# Configure pins based on the target. +if sys.platform == "alif" and sys.implementation._build == "ALIF_ENSEMBLE": + args_controller = {"scl": "P1_1", "sda": "P1_0"} + args_target = (0,) # on pins P0_3/P0_2 +elif sys.platform == "esp32": + args_controller = {"scl": 5, "sda": 6} + args_target = (0,) # on pins 9/8 for C3 and S3, 18/19 for others + kwargs_target = {"scl": 9, "sda": 8} +elif sys.platform == "rp2": + args_controller = {"scl": 5, "sda": 4} + args_target = (1,) +elif sys.platform == "pyboard": + if sys.implementation._build == "NUCLEO_WB55": + args_controller = {"scl": "B8", "sda": "B9"} + args_target = (3,) + else: + args_controller = {"scl": "X1", "sda": "X2"} + args_target = ("X",) +elif "zephyr-nucleo_wb55rg" in sys.implementation._machine: + # PB8=I2C1_SCL, PB9=I2C1_SDA (on Arduino header D15/D14) + # PC0=I2C3_SCL, PC1=I2C3_SDA (on Arduino header A0/A1) + args_controller = {"scl": Pin(("gpiob", 8)), "sda": Pin(("gpiob", 9))} + args_target = ("i2c3",) +elif "zephyr-rpi_pico" in sys.implementation._machine: + args_controller = {"scl": Pin(("gpio0", 5)), "sda": Pin(("gpio0", 4))} + args_target = ("i2c1",) # on gpio7/gpio6 +elif sys.platform == "mimxrt": + if "Teensy" in sys.implementation._machine: + args_controller = {"scl": "A6", "sda": "A3"} # D20/D17 + else: + args_controller = {"scl": "D0", "sda": "D1"} + args_target = (0,) # pins 19/18 On Teensy 4.x +elif sys.platform == "samd": + args_controller = {"scl": "D5", "sda": "D1"} + args_target = () +else: + print("Please add support for this test on this platform.") + raise SystemExit + + +def config_pull_up(): + Pin(args_controller["scl"], Pin.OPEN_DRAIN, Pin.PULL_UP) + Pin(args_controller["sda"], Pin.OPEN_DRAIN, Pin.PULL_UP) + + +class TestMemory(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.mem = bytearray(8) + cls.i2c = SoftI2C(**args_controller) + cls.i2c_target = I2CTarget(*args_target, **kwargs_target, addr=ADDR, mem=cls.mem) + config_pull_up() + + @classmethod + def tearDownClass(cls): + cls.i2c_target.deinit() + + def test_scan(self): + self.assertIn(ADDR, self.i2c.scan()) + + def test_write(self): + self.mem[:] = b"01234567" + self.i2c.writeto_mem(ADDR, 0, b"test") + self.assertEqual(self.mem, bytearray(b"test4567")) + self.i2c.writeto_mem(ADDR, 4, b"TEST") + self.assertEqual(self.mem, bytearray(b"testTEST")) + + def test_write_wrap(self): + self.mem[:] = b"01234567" + self.i2c.writeto_mem(ADDR, 6, b"test") + self.assertEqual(self.mem, bytearray(b"st2345te")) + + @unittest.skipIf(sys.platform == "esp32", "write lengths larger than buffer unsupported") + def test_write_wrap_large(self): + self.mem[:] = b"01234567" + self.i2c.writeto_mem(ADDR, 0, b"testTESTmore") + self.assertEqual(self.mem, bytearray(b"moreTEST")) + + def test_read(self): + self.mem[:] = b"01234567" + self.assertEqual(self.i2c.readfrom_mem(ADDR, 0, 4), b"0123") + self.assertEqual(self.i2c.readfrom_mem(ADDR, 4, 4), b"4567") + + def test_read_wrap(self): + self.mem[:] = b"01234567" + self.assertEqual(self.i2c.readfrom_mem(ADDR, 0, 4), b"0123") + self.assertEqual(self.i2c.readfrom_mem(ADDR, 2, 4), b"2345") + self.assertEqual(self.i2c.readfrom_mem(ADDR, 6, 4), b"6701") + + @unittest.skipIf(sys.platform == "esp32", "read lengths larger than buffer unsupported") + def test_read_wrap_large(self): + self.mem[:] = b"01234567" + self.assertEqual(self.i2c.readfrom_mem(ADDR, 0, 12), b"012345670123") + + def test_write_read(self): + self.mem[:] = b"01234567" + self.assertEqual(self.i2c.writeto(ADDR, b"\x02"), 1) + self.assertEqual(self.i2c.readfrom(ADDR, 4), b"2345") + + @unittest.skipIf(sys.platform == "esp32", "read after read unsupported") + def test_write_read_read(self): + self.mem[:] = b"01234567" + self.assertEqual(self.i2c.writeto(ADDR, b"\x02"), 1) + self.assertEqual(self.i2c.readfrom(ADDR, 4), b"2345") + self.assertEqual(self.i2c.readfrom(ADDR, 4), b"7012") + + +@unittest.skipUnless(hasattr(I2CTarget, "IRQ_END_READ"), "IRQ unsupported") +class TestMemoryIRQ(unittest.TestCase): + @staticmethod + def irq_handler(i2c_target): + flags = i2c_target.irq().flags() + TestMemoryIRQ.events[TestMemoryIRQ.num_events] = flags + TestMemoryIRQ.events[TestMemoryIRQ.num_events + 1] = i2c_target.memaddr + TestMemoryIRQ.num_events += 2 + + @classmethod + def setUpClass(cls): + cls.mem = bytearray(8) + cls.events = [0] * 8 + cls.num_events = 0 + cls.i2c = SoftI2C(**args_controller) + cls.i2c_target = I2CTarget(*args_target, **kwargs_target, addr=ADDR, mem=cls.mem) + cls.i2c_target.irq(TestMemoryIRQ.irq_handler) + config_pull_up() + + @classmethod + def tearDownClass(cls): + cls.i2c_target.deinit() + + @unittest.skipIf(sys.platform == "esp32", "scan doesn't trigger IRQ_END_WRITE") + def test_scan(self): + TestMemoryIRQ.num_events = 0 + self.i2c.scan() + self.assertEqual(self.events[: self.num_events], [I2CTarget.IRQ_END_WRITE, 0]) + + def test_write(self): + TestMemoryIRQ.num_events = 0 + self.mem[:] = b"01234567" + self.i2c.writeto_mem(ADDR, 2, b"test") + self.assertEqual(self.mem, bytearray(b"01test67")) + self.assertEqual(self.events[: self.num_events], [I2CTarget.IRQ_END_WRITE, 2]) + + def test_read(self): + TestMemoryIRQ.num_events = 0 + self.mem[:] = b"01234567" + self.assertEqual(self.i2c.readfrom_mem(ADDR, 2, 4), b"2345") + self.assertEqual(self.events[: self.num_events], [I2CTarget.IRQ_END_READ, 2]) + + +@unittest.skipUnless(hasattr(I2CTarget, "IRQ_WRITE_REQ"), "IRQ unsupported") +@unittest.skipIf(sys.platform == "mimxrt", "not working") +@unittest.skipIf(sys.platform == "pyboard", "can't queue more than one byte") +@unittest.skipIf(sys.platform == "samd", "not working") +@unittest.skipIf(sys.platform == "zephyr", "must call readinto/write in IRQ handler") +class TestPolling(unittest.TestCase): + @staticmethod + def irq_handler(i2c_target, buf=bytearray(1)): + flags = i2c_target.irq().flags() + if flags & I2CTarget.IRQ_READ_REQ: + i2c_target.write(b"0123") + + @classmethod + def setUpClass(cls): + cls.i2c = SoftI2C(**args_controller) + cls.i2c_target = I2CTarget(*args_target, addr=ADDR) + cls.i2c_target.irq( + TestPolling.irq_handler, + I2CTarget.IRQ_WRITE_REQ | I2CTarget.IRQ_READ_REQ, + hard=True, + ) + config_pull_up() + + @classmethod + def tearDownClass(cls): + cls.i2c_target.deinit() + + def test_read(self): + # Can't write data up front, must wait until IRQ_READ_REQ. + # self.assertEqual(self.i2c_target.write(b"abcd"), 4) + self.assertEqual(self.i2c.readfrom(ADDR, 4), b"0123") + + def test_write(self): + # Can do the read outside the IRQ, but requires IRQ_WRITE_REQ trigger to be set. + self.assertEqual(self.i2c.writeto(ADDR, b"0123"), 4) + buf = bytearray(8) + self.assertEqual(self.i2c_target.readinto(buf), 4) + self.assertEqual(buf, b"0123\x00\x00\x00\x00") + + +@unittest.skipUnless(hasattr(I2CTarget, "IRQ_ADDR_MATCH_READ"), "IRQ unsupported") +class TestIRQ(unittest.TestCase): + @staticmethod + def irq_handler(i2c_target, buf=bytearray(1)): + flags = i2c_target.irq().flags() + TestIRQ.events[TestIRQ.num_events] = flags + TestIRQ.num_events += 1 + if flags & I2CTarget.IRQ_READ_REQ: + i2c_target.write(b"Y") + if flags & I2CTarget.IRQ_WRITE_REQ: + i2c_target.readinto(buf) + TestIRQ.events[TestIRQ.num_events] = buf[0] + TestIRQ.num_events += 1 + + @classmethod + def setUpClass(cls): + cls.events = [0] * 8 + cls.num_events = 0 + cls.i2c = SoftI2C(**args_controller) + cls.i2c_target = I2CTarget(*args_target, addr=ADDR) + cls.i2c_target.irq( + TestIRQ.irq_handler, + I2CTarget.IRQ_ADDR_MATCH_READ + | I2CTarget.IRQ_ADDR_MATCH_WRITE + | I2CTarget.IRQ_WRITE_REQ + | I2CTarget.IRQ_READ_REQ + | I2CTarget.IRQ_END_READ + | I2CTarget.IRQ_END_WRITE, + hard=True, + ) + config_pull_up() + + @classmethod + def tearDownClass(cls): + cls.i2c_target.deinit() + + def test_scan(self): + TestIRQ.num_events = 0 + self.i2c.scan() + self.assertEqual( + self.events[: self.num_events], + [ + I2CTarget.IRQ_ADDR_MATCH_WRITE, + I2CTarget.IRQ_END_WRITE, + ], + ) + + def test_write(self): + TestIRQ.num_events = 0 + self.i2c.writeto(ADDR, b"XYZ") + self.assertEqual( + self.events[: self.num_events], + [ + I2CTarget.IRQ_ADDR_MATCH_WRITE, + I2CTarget.IRQ_WRITE_REQ, + ord(b"X"), + I2CTarget.IRQ_WRITE_REQ, + ord(b"Y"), + I2CTarget.IRQ_WRITE_REQ, + ord(b"Z"), + I2CTarget.IRQ_END_WRITE, + ], + ) + + def test_read(self): + TestIRQ.num_events = 0 + self.assertEqual(self.i2c.readfrom(ADDR, 1), b"Y") + self.assertEqual( + self.events[: self.num_events], + [ + I2CTarget.IRQ_ADDR_MATCH_READ, + I2CTarget.IRQ_READ_REQ, + I2CTarget.IRQ_READ_REQ, + I2CTarget.IRQ_END_READ, + ], + ) + + def test_write_read(self): + TestIRQ.num_events = 0 + self.i2c.writeto(ADDR, b"X", False) + self.assertEqual(self.i2c.readfrom(ADDR, 1), b"Y") + self.assertEqual( + self.events[: self.num_events], + [ + I2CTarget.IRQ_ADDR_MATCH_WRITE, + I2CTarget.IRQ_WRITE_REQ, + ord(b"X"), + I2CTarget.IRQ_END_WRITE, + I2CTarget.IRQ_ADDR_MATCH_READ, + I2CTarget.IRQ_READ_REQ, + I2CTarget.IRQ_READ_REQ, + I2CTarget.IRQ_END_READ, + ], + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/extmod_hardware/machine_pwm.py b/tests/extmod_hardware/machine_pwm.py new file mode 100644 index 00000000000..e27da325486 --- /dev/null +++ b/tests/extmod_hardware/machine_pwm.py @@ -0,0 +1,166 @@ +# Test machine.PWM, frequency and duty cycle (using machine.time_pulse_us). +# +# IMPORTANT: This test requires hardware connections: the PWM-output and pulse-input +# pins must be wired together (see the variable `pwm_pulse_pins`). + +import sys +import time + +try: + from machine import time_pulse_us, Pin, PWM +except ImportError: + print("SKIP") + raise SystemExit + +import unittest + +pwm_freq_limit = 1000000 +freq_margin_per_thousand = 0 +duty_margin_per_thousand = 0 +timing_margin_us = 5 + +# Configure pins based on the target. +if "esp32" in sys.platform: + pwm_pulse_pins = ((4, 5),) + freq_margin_per_thousand = 2 + duty_margin_per_thousand = 1 + timing_margin_us = 20 +elif "esp8266" in sys.platform: + pwm_pulse_pins = ((4, 5),) + pwm_freq_limit = 1_000 + duty_margin_per_thousand = 3 + timing_margin_us = 50 +elif "mimxrt" in sys.platform: + if "Teensy" in sys.implementation._machine: + # Teensy 4.x + pwm_pulse_pins = ( + ("D0", "D1"), # FLEXPWM X and UART 1 + ("D2", "D3"), # FLEXPWM A/B + ("D11", "D12"), # QTMR and MOSI/MISO of SPI 0 + ) + else: + pwm_pulse_pins = (("D0", "D1"),) +elif "rp2" in sys.platform: + pwm_pulse_pins = (("GPIO0", "GPIO1"),) +elif "samd" in sys.platform: + pwm_pulse_pins = (("D0", "D1"),) + if "SAMD21" in sys.implementation._machine: + # MCU is too slow to capture short pulses. + pwm_freq_limit = 2_000 +else: + print("Please add support for this test on this platform.") + raise SystemExit + + +# Test a specific frequency and duty cycle. +def _test_freq_duty(self, pulse_in, pwm, freq, duty_u16): + print("freq={:<5} duty_u16={:<5} :".format(freq, duty_u16), end="") + + # Check configured freq/duty_u16 is within error bound. + freq_error = abs(pwm.freq() - freq) * 1000 // freq + duty_error = abs(pwm.duty_u16() - duty_u16) * 1000 // (duty_u16 or 1) + print(" freq={} freq_er={}".format(pwm.freq(), freq_error), end="") + print(" duty={} duty_er={}".format(pwm.duty_u16(), duty_error), end="") + print(" :", end="") + self.assertLessEqual(freq_error, freq_margin_per_thousand) + self.assertLessEqual(duty_error, duty_margin_per_thousand) + + # Calculate expected timing. + expected_total_us = 1_000_000 // freq + expected_high_us = expected_total_us * duty_u16 // 65535 + expected_low_us = expected_total_us - expected_high_us + expected_us = (expected_low_us, expected_high_us) + timeout = 2 * expected_total_us + + # Wait for output to settle. + time_pulse_us(pulse_in, 0, timeout) + time_pulse_us(pulse_in, 1, timeout) + + if duty_u16 == 0 or duty_u16 == 65535: + # Expect a constant output level. + no_pulse = ( + time_pulse_us(pulse_in, 0, timeout) < 0 and time_pulse_us(pulse_in, 1, timeout) < 0 + ) + self.assertTrue(no_pulse) + if expected_high_us == 0: + # Expect a constant low level. + self.assertEqual(pulse_in(), 0) + else: + # Expect a constant high level. + self.assertEqual(pulse_in(), 1) + else: + # Test timing of low and high pulse. + n_averaging = 10 + for level in (0, 1): + t = 0 + time_pulse_us(pulse_in, level, timeout) + for _ in range(n_averaging): + t += time_pulse_us(pulse_in, level, timeout) + t //= n_averaging + expected = expected_us[level] + print(" level={} timing_er={}".format(level, abs(t - expected)), end="") + self.assertLessEqual(abs(t - expected), timing_margin_us) + + print() + + +# Test a specific frequency with multiple duty cycles. +def _test_freq(self, freq): + print() + self.pwm.freq(freq) + for duty in (0, 10, 25, 50, 75, 90, 100): + duty_u16 = duty * 65535 // 100 + if sys.platform == "esp32": + # TODO why is this bit needed to get it working on esp32? + self.pwm.init(freq=freq, duty_u16=duty_u16) + time.sleep(0.1) + self.pwm.duty_u16(duty_u16) + _test_freq_duty(self, self.pulse_in, self.pwm, freq, duty_u16) + + +# Given a set of pins, this test class will test multiple frequencies and duty cycles. +class TestBase: + @classmethod + def setUpClass(cls): + print("set up pins:", cls.pwm_pin, cls.pulse_pin) + cls.pwm = PWM(cls.pwm_pin) + cls.pulse_in = Pin(cls.pulse_pin, Pin.IN) + + @classmethod + def tearDownClass(cls): + cls.pwm.deinit() + + def test_freq_50(self): + _test_freq(self, 50) + + def test_freq_100(self): + _test_freq(self, 100) + + def test_freq_500(self): + _test_freq(self, 500) + + def test_freq_1000(self): + _test_freq(self, 1000) + + @unittest.skipIf(pwm_freq_limit < 2000, "frequency too high") + def test_freq_2000(self): + _test_freq(self, 2000) + + @unittest.skipIf(pwm_freq_limit < 5000, "frequency too high") + def test_freq_5000(self): + _test_freq(self, 5000) + + @unittest.skipIf(pwm_freq_limit < 10000, "frequency too high") + def test_freq_10000(self): + _test_freq(self, 10000) + + +# Generate test classes, one for each set of pins to test. +for pwm, pulse in pwm_pulse_pins: + cls_name = "Test_{}_{}".format(pwm, pulse) + globals()[cls_name] = type( + cls_name, (TestBase, unittest.TestCase), {"pwm_pin": pwm, "pulse_pin": pulse} + ) + +if __name__ == "__main__": + unittest.main() diff --git a/tests/feature_check/float.py b/tests/feature_check/float.py deleted file mode 100644 index d6d2a99d242..00000000000 --- a/tests/feature_check/float.py +++ /dev/null @@ -1,13 +0,0 @@ -# detect how many bits of precision the floating point implementation has - -try: - float -except NameError: - print(0) -else: - if float("1.0000001") == float("1.0"): - print(30) - elif float("1e300") == float("inf"): - print(32) - else: - print(64) diff --git a/tests/feature_check/float.py.exp b/tests/feature_check/float.py.exp deleted file mode 100644 index 900731ffd51..00000000000 --- a/tests/feature_check/float.py.exp +++ /dev/null @@ -1 +0,0 @@ -64 diff --git a/tests/feature_check/inlineasm_rv32.py b/tests/feature_check/inlineasm_rv32.py new file mode 100644 index 00000000000..21dd103b6c3 --- /dev/null +++ b/tests/feature_check/inlineasm_rv32.py @@ -0,0 +1,9 @@ +# check if RISC-V 32 inline asm is supported + + +@micropython.asm_rv32 +def f(): + add(a0, a0, a0) + + +print("rv32") diff --git a/tests/feature_check/inlineasm_rv32.py.exp b/tests/feature_check/inlineasm_rv32.py.exp new file mode 100644 index 00000000000..5eecf09c224 --- /dev/null +++ b/tests/feature_check/inlineasm_rv32.py.exp @@ -0,0 +1 @@ +rv32 diff --git a/tests/feature_check/inlineasm_rv32_zba.py b/tests/feature_check/inlineasm_rv32_zba.py new file mode 100644 index 00000000000..81228819042 --- /dev/null +++ b/tests/feature_check/inlineasm_rv32_zba.py @@ -0,0 +1,10 @@ +# check if RISC-V 32 inline asm supported Zba opcodes + + +@micropython.asm_rv32 +def f(): + sh1add(a0, a0, a0) + + +f() +print("rv32_zba") diff --git a/tests/feature_check/inlineasm_rv32_zba.py.exp b/tests/feature_check/inlineasm_rv32_zba.py.exp new file mode 100644 index 00000000000..fde22f5f400 --- /dev/null +++ b/tests/feature_check/inlineasm_rv32_zba.py.exp @@ -0,0 +1 @@ +rv32_zba diff --git a/tests/feature_check/inlineasm_thumb.py b/tests/feature_check/inlineasm_thumb.py new file mode 100644 index 00000000000..321eab0e2f8 --- /dev/null +++ b/tests/feature_check/inlineasm_thumb.py @@ -0,0 +1,9 @@ +# check if Thumb inline asm is supported + + +@micropython.asm_thumb +def f(): + nop() + + +print("thumb") diff --git a/tests/feature_check/inlineasm_thumb.py.exp b/tests/feature_check/inlineasm_thumb.py.exp new file mode 100644 index 00000000000..bb48e1a2f03 --- /dev/null +++ b/tests/feature_check/inlineasm_thumb.py.exp @@ -0,0 +1 @@ +thumb diff --git a/tests/feature_check/inlineasm_xtensa.py b/tests/feature_check/inlineasm_xtensa.py new file mode 100644 index 00000000000..2a24d39973c --- /dev/null +++ b/tests/feature_check/inlineasm_xtensa.py @@ -0,0 +1,9 @@ +# check if Xtensa inline asm is supported + + +@micropython.asm_xtensa +def f(): + ret_n() + + +print("xtensa") diff --git a/tests/feature_check/inlineasm_xtensa.py.exp b/tests/feature_check/inlineasm_xtensa.py.exp new file mode 100644 index 00000000000..036142c5097 --- /dev/null +++ b/tests/feature_check/inlineasm_xtensa.py.exp @@ -0,0 +1 @@ +xtensa diff --git a/tests/feature_check/int_64.py b/tests/feature_check/int_64.py new file mode 100644 index 00000000000..4d053782ca8 --- /dev/null +++ b/tests/feature_check/int_64.py @@ -0,0 +1,2 @@ +# Check whether 64-bit long integers are supported +print(1 << 62) diff --git a/tests/feature_check/int_64.py.exp b/tests/feature_check/int_64.py.exp new file mode 100644 index 00000000000..aef5454e662 --- /dev/null +++ b/tests/feature_check/int_64.py.exp @@ -0,0 +1 @@ +4611686018427387904 diff --git a/tests/feature_check/io_module.py b/tests/feature_check/io_module.py deleted file mode 100644 index 9094e605316..00000000000 --- a/tests/feature_check/io_module.py +++ /dev/null @@ -1,6 +0,0 @@ -try: - import io - - print("io") -except ImportError: - print("no") diff --git a/tests/feature_check/repl_emacs_check.py.exp b/tests/feature_check/repl_emacs_check.py.exp index 82a4e28ee4f..5fe8ba1cd2d 100644 --- a/tests/feature_check/repl_emacs_check.py.exp +++ b/tests/feature_check/repl_emacs_check.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # Check for emacs keys in REPL >>> t = \.\+ >>> t == 2 diff --git a/tests/feature_check/repl_words_move_check.py.exp b/tests/feature_check/repl_words_move_check.py.exp index 82a4e28ee4f..5fe8ba1cd2d 100644 --- a/tests/feature_check/repl_words_move_check.py.exp +++ b/tests/feature_check/repl_words_move_check.py.exp @@ -1,5 +1,5 @@ MicroPython \.\+ version -Use \.\+ +Type "help()" for more information. >>> # Check for emacs keys in REPL >>> t = \.\+ >>> t == 2 diff --git a/tests/feature_check/target_info.py b/tests/feature_check/target_info.py new file mode 100644 index 00000000000..e95530023d7 --- /dev/null +++ b/tests/feature_check/target_info.py @@ -0,0 +1,39 @@ +# Retrieve the native architecture of the target. +# See https://docs.micropython.org/en/latest/reference/mpyfiles.html#versioning-and-compatibility-of-mpy-files +# for more details. + +import sys + +platform = getattr(sys, "platform", "minimal") +sys_mpy = getattr(sys.implementation, "_mpy", 0) +arch = [ + None, + "x86", + "x64", + "armv6", + "armv6m", + "armv7m", + "armv7em", + "armv7emsp", + "armv7emdp", + "xtensa", + "xtensawin", + "rv32imc", + "rv64imc", +][(sys_mpy >> 10) & 0x0F] +arch_flags = sys_mpy >> 16 +build = getattr(sys.implementation, "_build", "unknown") +thread = getattr(sys.implementation, "_thread", None) + +# Detect how many bits of precision the floating point implementation has. +try: + if float("1.0000001") == float("1.0"): + float_prec = 30 + elif float("1e300") == float("inf"): + float_prec = 32 + else: + float_prec = 64 +except NameError: + float_prec = 0 + +print(platform, arch, arch_flags, build, thread, float_prec, len("α") == 1) diff --git a/tests/feature_check/target_info.py.exp b/tests/feature_check/target_info.py.exp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/float/cmath_fun.py b/tests/float/cmath_fun.py index 39011733b02..0037d7c6559 100644 --- a/tests/float/cmath_fun.py +++ b/tests/float/cmath_fun.py @@ -51,6 +51,9 @@ print("%.5g" % ret) elif type(ret) == tuple: print("%.5g %.5g" % ret) + elif f_name == "exp": + # exp amplifies REPR_C inaccuracies, so we need to check one digit less + print("complex(%.4g, %.4g)" % (real, ret.imag)) else: # some test (eg cmath.sqrt(-0.5)) disagree with CPython with tiny real part real = ret.real diff --git a/tests/float/complex1.py b/tests/float/complex1.py index f4107a1390f..0a1d98b9af3 100644 --- a/tests/float/complex1.py +++ b/tests/float/complex1.py @@ -12,9 +12,11 @@ print(complex("1+j")) print(complex("1+2j")) print(complex("-1-2j")) +print(complex("-1+2j")) print(complex("+1-2j")) print(complex(" -1-2j ")) print(complex(" +1-2j ")) +print(complex(" -1+2j ")) print(complex("nanj")) print(complex("nan-infj")) print(complex(1, 2)) diff --git a/tests/float/float_array.py b/tests/float/float_array.py index 3d128da8381..cfff3b220c6 100644 --- a/tests/float/float_array.py +++ b/tests/float/float_array.py @@ -19,4 +19,10 @@ def test(a): test(array("f")) test(array("d")) -print("{:.4f}".format(array("f", bytes(array("I", [0x3DCCCCCC])))[0])) +# hand-crafted floats, including non-standard nan +for float_hex in (0x3DCCCCCC, 0x7F800024, 0x7FC00004): + f = array("f", bytes(array("I", [float_hex])))[0] + if type(f) is float: + print("{:.4e}".format(f)) + else: + print(f) diff --git a/tests/float/float_format.py b/tests/float/float_format.py index 98ed0eb096f..0eb8b232b06 100644 --- a/tests/float/float_format.py +++ b/tests/float/float_format.py @@ -2,14 +2,25 @@ # general rounding for val in (116, 1111, 1234, 5010, 11111): - print("%.0f" % val) - print("%.1f" % val) - print("%.3f" % val) + print("Test on %d / 1000:" % val) + for fmt in ("%.5e", "%.3e", "%.1e", "%.0e", "%.3f", "%.1f", "%.0f", "%.3g", "%.1g", "%.0g"): + print(fmt, fmt % (val / 1000)) + +# make sure round-up to the next unit is handled properly +for val in range(4, 9): + divi = 10**val + print("Test on 99994 / (10 ** %d):" % val) + for fmt in ("%.5e", "%.3e", "%.1e", "%.0e", "%.3f", "%.1f", "%.0f", "%.3g", "%.1g", "%.0g"): + print(fmt, fmt % (99994 / divi)) # make sure rounding is done at the correct precision for prec in range(8): print(("%%.%df" % prec) % 6e-5) +# make sure trailing zeroes are added properly +for prec in range(8): + print(("%%.%df" % prec) % 1e19) + # check certain cases that had a digit value of 10 render as a ":" character print("%.2e" % float("9" * 51 + "e-39")) print("%.2e" % float("9" * 40 + "e-21")) diff --git a/tests/float/float_format_accuracy.py b/tests/float/float_format_accuracy.py new file mode 100644 index 00000000000..f9467f9c05d --- /dev/null +++ b/tests/float/float_format_accuracy.py @@ -0,0 +1,73 @@ +# Test accuracy of `repr` conversions. +# This test also increases code coverage for corner cases. + +try: + import array, math, random +except ImportError: + print("SKIP") + raise SystemExit + +# The largest errors come from seldom used very small numbers, near the +# limit of the representation. So we keep them out of this test to keep +# the max relative error display useful. +if float("1e-100") == 0.0: + # single-precision + float_type = "f" + float_size = 4 + # testing range + min_expo = -96 # i.e. not smaller than 1.0e-29 + # Expected results (given >=50'000 samples): + # - MICROPY_FLTCONV_IMPL_EXACT: 100% exact conversions + # - MICROPY_FLTCONV_IMPL_APPROX: >=98.53% exact conversions, max relative error <= 1.01e-7 + min_success = 0.980 # with only 1200 samples, the success rate is lower + max_rel_err = 1.1e-7 + # REPR_C is typically used with FORMAT_IMPL_BASIC, which has a larger error + is_REPR_C = float("1.0000001") == float("1.0") + if is_REPR_C: # REPR_C + min_success = 0.83 + max_rel_err = 5.75e-07 +else: + # double-precision + float_type = "d" + float_size = 8 + # testing range + min_expo = -845 # i.e. not smaller than 1.0e-254 + # Expected results (given >=200'000 samples): + # - MICROPY_FLTCONV_IMPL_EXACT: 100% exact conversions + # - MICROPY_FLTCONV_IMPL_APPROX: >=99.83% exact conversions, max relative error <= 2.7e-16 + min_success = 0.997 # with only 1200 samples, the success rate is lower + max_rel_err = 2.7e-16 + + +# Deterministic pseudorandom generator. Designed to be uniform +# on mantissa values and exponents, not on the represented number +def pseudo_randfloat(): + rnd_buff = bytearray(float_size) + for _ in range(float_size): + rnd_buff[_] = random.getrandbits(8) + return array.array(float_type, rnd_buff)[0] + + +random.seed(42) +stats = 0 +N = 1200 +max_err = 0 +for _ in range(N): + f = pseudo_randfloat() + while type(f) is not float or math.isinf(f) or math.isnan(f) or math.frexp(f)[1] <= min_expo: + f = pseudo_randfloat() + + str_f = repr(f) + f2 = float(str_f) + if f2 == f: + stats += 1 + else: + error = abs((f2 - f) / f) + if max_err < error: + max_err = error + +print(N, "values converted") +if stats / N >= min_success and max_err <= max_rel_err: + print("float format accuracy OK") +else: + print("FAILED: repr rate=%.3f%% max_err=%.3e" % (100 * stats / N, max_err)) diff --git a/tests/float/float_format_ints.py b/tests/float/float_format_ints.py index df4444166c5..7b7b30c4b34 100644 --- a/tests/float/float_format_ints.py +++ b/tests/float/float_format_ints.py @@ -12,14 +12,42 @@ print(title, "with format", f_fmt, "gives", f_fmt.format(f)) print(title, "with format", g_fmt, "gives", g_fmt.format(f)) +# The tests below check border cases involving all mantissa bits. +# In case of REPR_C, where the mantissa is missing two bits, the +# the string representation for such numbers might not always be exactly +# the same but nevertheless be correct, so we must allow a few exceptions. +is_REPR_C = float("1.0000001") == float("1.0") + # 16777215 is 2^24 - 1, the largest integer that can be completely held # in a float32. -print("{:f}".format(16777215)) +val_str = "{:f}".format(16777215) + +# When using REPR_C, 16777215.0 is the same as 16777212.0 or 16777214.4 +# (depending on the implementation of pow() function, the result may differ) +if is_REPR_C and (val_str == "16777212.000000" or val_str == "16777214.400000"): + val_str = "16777215.000000" + +print(val_str) + # 4294967040 = 16777215 * 128 is the largest integer that is exactly # represented by a float32 and that will also fit within a (signed) int32. # The upper bound of our integer-handling code is actually double this, # but that constant might cause trouble on systems using 32 bit ints. -print("{:f}".format(2147483520)) +val_str = "{:f}".format(2147483520) + +# When using FLOAT_IMPL_FLOAT, 2147483520.0 == 2147483500.0 +# Both representations are valid, the second being "simpler" +is_float32 = float("1e300") == float("inf") +if is_float32 and val_str == "2147483500.000000": + val_str = "2147483520.000000" + +# When using REPR_C, 2147483520.0 is the same as 2147483200.0 +# Both representations are valid, the second being "simpler" +if is_REPR_C and val_str == "2147483200.000000": + val_str = "2147483520.000000" + +print(val_str) + # Very large positive integers can be a test for precision and resolution. # This is a weird way to represent 1e38 (largest power of 10 for float32). print("{:.6e}".format(float("9" * 30 + "e8"))) diff --git a/tests/float/float_format_ints_power10.py b/tests/float/float_format_ints_power10.py index 98900c135b2..7ea200f18ef 100644 --- a/tests/float/float_format_ints_power10.py +++ b/tests/float/float_format_ints_power10.py @@ -3,6 +3,6 @@ # Check that powers of 10 (that fit in float32) format correctly. for i in range(31): - # It works to 12 digits on all platforms *except* qemu-arm, where + # It works to 12 digits on all platforms *except* qemu, where # 10^11 comes out as 10000000820 or something. print(i, "{:.7g}".format(float("1e" + str(i)))) diff --git a/tests/float/float_parse.py b/tests/float/float_parse.py index de27c33e7be..6131da0a63a 100644 --- a/tests/float/float_parse.py +++ b/tests/float/float_parse.py @@ -31,6 +31,9 @@ print(float("1e18446744073709551621")) print(float("1e-18446744073709551621")) +# mantissa overflow while processing deferred trailing zeros +print(float("10000000000000000000001")) + # check small decimals are as close to their true value as possible for n in range(1, 10): print(float("0.%u" % n) == n / 10) diff --git a/tests/float/float_parse_doubleprec.py b/tests/float/float_parse_doubleprec.py index 81fcadcee88..c1b0b4823b0 100644 --- a/tests/float/float_parse_doubleprec.py +++ b/tests/float/float_parse_doubleprec.py @@ -19,3 +19,9 @@ print(float("1.00000000000000000000e-307")) print(float("10.0000000000000000000e-308")) print(float("100.000000000000000000e-309")) + +# ensure repr() adds an extra digit when needed for accurate parsing +print(float(repr(float("2.0") ** 100)) == float("2.0") ** 100) + +# ensure repr does not add meaningless extra digits (1.234999999999) +print(repr(1.2345)) diff --git a/tests/float/float_struct_e.py b/tests/float/float_struct_e.py index 403fbc5db4c..ba4134f3393 100644 --- a/tests/float/float_struct_e.py +++ b/tests/float/float_struct_e.py @@ -32,7 +32,7 @@ for i in (j, -j): x = struct.pack("", "=", "^"): for fill in ("", " ", "0", "@"): for sign in ("", "+", "-", " "): - # An empty precision defaults to 6, but when uPy is + # An empty precision defaults to 6, but when MicroPython is # configured to use a float, we can only use a # precision of 6 with numbers less than 10 and still # get results that compare to CPython (which uses @@ -164,7 +164,7 @@ def test_fmt(conv, fill, alignment, sign, prefix, width, precision, type, arg): for alignment in ("", "<", ">", "=", "^"): for fill in ("", " ", "0", "@"): for sign in ("", "+", "-", " "): - # An empty precision defaults to 6, but when uPy is + # An empty precision defaults to 6, but when MicroPython is # configured to use a float, we can only use a # precision of 6 with numbers less than 10 and still # get results that compare to CPython (which uses diff --git a/tests/float/string_format_fp30.py b/tests/float/string_format_fp30.py deleted file mode 100644 index 5f0b213daa3..00000000000 --- a/tests/float/string_format_fp30.py +++ /dev/null @@ -1,42 +0,0 @@ -def test(fmt, *args): - print("{:8s}".format(fmt) + ">" + fmt.format(*args) + "<") - - -test("{:10.4}", 123.456) -test("{:10.4e}", 123.456) -test("{:10.4e}", -123.456) -# test("{:10.4f}", 123.456) -# test("{:10.4f}", -123.456) -test("{:10.4g}", 123.456) -test("{:10.4g}", -123.456) -test("{:10.4n}", 123.456) -test("{:e}", 100) -test("{:f}", 200) -test("{:g}", 300) - -test("{:10.4E}", 123.456) -test("{:10.4E}", -123.456) -# test("{:10.4F}", 123.456) -# test("{:10.4F}", -123.456) -test("{:10.4G}", 123.456) -test("{:10.4G}", -123.456) - -test("{:06e}", float("inf")) -test("{:06e}", float("-inf")) -test("{:06e}", float("nan")) - -# The following fails right now -# test("{:10.1}", 0.0) - -print("%.0f" % (1.750000 % 0.08333333333)) -# Below isn't compatible with single-precision float -# print("%.1f" % (1.750000 % 0.08333333333)) -# print("%.2f" % (1.750000 % 0.08333333333)) -# print("%.12f" % (1.750000 % 0.08333333333)) - -# tests for errors in format string - -try: - "{:10.1b}".format(0.0) -except ValueError: - print("ValueError") diff --git a/tests/float/string_format_modulo.py b/tests/float/string_format_modulo.py index 3c206b73935..55314643351 100644 --- a/tests/float/string_format_modulo.py +++ b/tests/float/string_format_modulo.py @@ -6,7 +6,7 @@ print("%u" % 1.0) # these 3 have different behaviour in Python 3.x versions -# uPy raises a TypeError, following Python 3.5 (earlier versions don't) +# MicroPython raises a TypeError, following Python 3.5 (earlier versions don't) # print("%x" % 18.0) # print("%o" % 18.0) # print("%X" % 18.0) diff --git a/tests/float/string_format_modulo3.py b/tests/float/string_format_modulo3.py index f9d9c43cdf4..f8aeeda20f2 100644 --- a/tests/float/string_format_modulo3.py +++ b/tests/float/string_format_modulo3.py @@ -1,3 +1,3 @@ -# uPy and CPython outputs differ for the following +# Test corner cases where MicroPython and CPython outputs used to differ in the past print("%.1g" % -9.9) # round up 'g' with '-' sign print("%.2g" % 99.9) # round up diff --git a/tests/float/string_format_modulo3.py.exp b/tests/float/string_format_modulo3.py.exp deleted file mode 100644 index 71432b34045..00000000000 --- a/tests/float/string_format_modulo3.py.exp +++ /dev/null @@ -1,2 +0,0 @@ --10 -100 diff --git a/tests/frozen/frozentest.py b/tests/frozen/frozentest.py index 78cdd60bf04..74bdfb3b267 100644 --- a/tests/frozen/frozentest.py +++ b/tests/frozen/frozentest.py @@ -1,4 +1,4 @@ -print("uPy") +print("interned") print("a long string that is not interned") print("a string that has unicode αβγ chars") print(b"bytes 1234\x01") diff --git a/tests/import/builtin_ext.py b/tests/import/builtin_ext.py index 9d2344d400d..79ee901ea67 100644 --- a/tests/import/builtin_ext.py +++ b/tests/import/builtin_ext.py @@ -1,3 +1,9 @@ +try: + import uos, utime +except ImportError: + print("SKIP") + raise SystemExit + # Verify that sys is a builtin. import sys diff --git a/tests/import/builtin_import.py b/tests/import/builtin_import.py index 734498d1be4..364b0bae912 100644 --- a/tests/import/builtin_import.py +++ b/tests/import/builtin_import.py @@ -20,3 +20,12 @@ __import__("xyz", None, None, None, -1) except ValueError: print("ValueError") + +# globals is not checked for level=0 +__import__("builtins", "globals") + +# globals must be a dict (or None) for level>0 +try: + __import__("builtins", "globals", None, None, 1) +except TypeError: + print("TypeError") diff --git a/tests/import/import_broken.py b/tests/import/import_broken.py index 3c7cf4a4985..440922157ef 100644 --- a/tests/import/import_broken.py +++ b/tests/import/import_broken.py @@ -1,3 +1,9 @@ +try: + Exception.__class__ +except AttributeError: + print("SKIP") + raise SystemExit + import sys, pkg # Modules we import are usually added to sys.modules. diff --git a/tests/import/import_file.py b/tests/import/import_file.py index 90ec4e41e77..4cf307641c6 100644 --- a/tests/import/import_file.py +++ b/tests/import/import_file.py @@ -1,3 +1,7 @@ +if "__file__" not in globals(): + print("SKIP") + raise SystemExit + import import1b print(import1b.__file__) diff --git a/tests/import/import_override.py b/tests/import/import_override.py index 029ebe54c1f..0144e78cb9f 100644 --- a/tests/import/import_override.py +++ b/tests/import/import_override.py @@ -2,6 +2,10 @@ def custom_import(name, globals, locals, fromlist, level): + # CPython always tries to import _io, so just let that through as-is. + if name == "_io": + return orig_import(name, globals, locals, fromlist, level) + print("import", name, fromlist, level) class M: diff --git a/tests/import/import_override.py.exp b/tests/import/import_override.py.exp deleted file mode 100644 index 365248da6d8..00000000000 --- a/tests/import/import_override.py.exp +++ /dev/null @@ -1,2 +0,0 @@ -import import1b None 0 -456 diff --git a/tests/import/import_override2.py b/tests/import/import_override2.py new file mode 100644 index 00000000000..25aac44fe98 --- /dev/null +++ b/tests/import/import_override2.py @@ -0,0 +1,18 @@ +# test overriding __import__ combined with importing from the filesystem + + +def custom_import(name, globals, locals, fromlist, level): + if level > 0: + print("import", name, fromlist, level) + return orig_import(name, globals, locals, fromlist, level) + + +orig_import = __import__ +try: + __import__("builtins").__import__ = custom_import +except AttributeError: + print("SKIP") + raise SystemExit + +# import calls __import__ behind the scenes +import pkg7.subpkg1.subpkg2.mod3 diff --git a/tests/import/import_pkg7.py.exp b/tests/import/import_pkg7.py.exp deleted file mode 100644 index 8f21a615f6a..00000000000 --- a/tests/import/import_pkg7.py.exp +++ /dev/null @@ -1,8 +0,0 @@ -pkg __name__: pkg7 -pkg __name__: pkg7.subpkg1 -pkg __name__: pkg7.subpkg1.subpkg2 -mod1 -mod2 -mod1.foo -mod2.bar -ImportError diff --git a/tests/import/import_pkg9.py b/tests/import/import_pkg9.py index 4de028494f1..c2e0b618b69 100644 --- a/tests/import/import_pkg9.py +++ b/tests/import/import_pkg9.py @@ -13,4 +13,4 @@ import pkg9.mod2 pkg9.mod1() -print(pkg9.mod2.__name__, type(pkg9.mod2).__name__) +print(pkg9.mod2.__name__, type(pkg9.mod2)) diff --git a/tests/import/import_shared_name.py b/tests/import/import_shared_name.py new file mode 100644 index 00000000000..b76695f671e --- /dev/null +++ b/tests/import/import_shared_name.py @@ -0,0 +1,7 @@ +# https://github.com/adafruit/circuitpython/issues/10614 +# When a directory `shared_name/` (no __init__.py) and a module `shared_name.py` +# share a name, `import shared_name` must pick the .py module per PEP 420 +# precedence: regular package > module > namespace package. +import shared_name + +print("done") diff --git a/tests/import/import_star.py b/tests/import/import_star.py new file mode 100644 index 00000000000..2cb21b877d7 --- /dev/null +++ b/tests/import/import_star.py @@ -0,0 +1,59 @@ +# test `from package import *` conventions, including __all__ support +# +# This test requires MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_BASIC_FEATURES + +try: + next(iter([]), 42) +except TypeError: + # 2-argument version of next() not supported + # we are probably not at MICROPY_CONFIG_ROM_LEVEL_BASIC_FEATURES + print("SKIP") + raise SystemExit + +# 1. test default visibility +from pkgstar_default import * + +print("visibleFun" in globals()) +print("VisibleClass" in globals()) +print("_hiddenFun" in globals()) +print("_HiddenClass" in globals()) +print(visibleFun()) + +# 2. test explicit visibility as defined by __all__ (as an array) +from pkgstar_all_array import * + +print("publicFun" in globals()) +print("PublicClass" in globals()) +print("unlistedFun" in globals()) +print("UnlistedClass" in globals()) +print("_privateFun" in globals()) +print("_PrivateClass" in globals()) +print(publicFun()) +# test dynamic import as used in asyncio +print("dynamicFun" in globals()) +print(dynamicFun()) + +# 3. test explicit visibility as defined by __all__ (as an tuple) +from pkgstar_all_tuple import * + +print("publicFun2" in globals()) +print("PublicClass2" in globals()) +print("unlistedFun2" in globals()) +print("UnlistedClass2" in globals()) +print(publicFun2()) + +# 4. test reporting of missing entries in __all__ +try: + from pkgstar_all_miss import * + + print("missed detection of incorrect __all__ definition") +except AttributeError as er: + print("AttributeError triggered for bad __all__ definition") + +# 5. test reporting of invalid __all__ definition +try: + from pkgstar_all_inval import * + + print("missed detection of incorrect __all__ definition") +except TypeError as er: + print("TypeError triggered for bad __all__ definition") diff --git a/tests/import/import_star_error.py b/tests/import/import_star_error.py index 9e1757b6ef5..73d9c863d6f 100644 --- a/tests/import/import_star_error.py +++ b/tests/import/import_star_error.py @@ -1,5 +1,10 @@ # test errors with import * +if not hasattr(object, "__init__"): + # target doesn't have MICROPY_CPYTHON_COMPAT enabled, so doesn't check for "import *" + print("SKIP") + raise SystemExit + # 'import *' is not allowed in function scope try: exec("def foo(): from x import *") diff --git a/tests/import/module_getattr.py.exp b/tests/import/module_getattr.py.exp deleted file mode 100644 index bc59c12aa16..00000000000 --- a/tests/import/module_getattr.py.exp +++ /dev/null @@ -1 +0,0 @@ -False diff --git a/tests/import/pkg7/subpkg1/subpkg2/mod3.py b/tests/import/pkg7/subpkg1/subpkg2/mod3.py index b0f4279fcf5..f7f4c1e65f4 100644 --- a/tests/import/pkg7/subpkg1/subpkg2/mod3.py +++ b/tests/import/pkg7/subpkg1/subpkg2/mod3.py @@ -5,7 +5,9 @@ print(bar) # attempted relative import beyond top-level package +# On older versions of CPython (eg 3.8) this is a ValueError, but on +# newer CPython (eg 3.11) and MicroPython it's an ImportError. try: from .... import mod1 -except ImportError: +except (ImportError, ValueError): print("ImportError") diff --git a/tests/import/pkgstar_all_array/__init__.py b/tests/import/pkgstar_all_array/__init__.py new file mode 100644 index 00000000000..03b012123fe --- /dev/null +++ b/tests/import/pkgstar_all_array/__init__.py @@ -0,0 +1,49 @@ +__all__ = ["publicFun", "PublicClass", "dynamicFun"] + + +# Definitions below should always be imported by a star import +def publicFun(): + return 1 + + +class PublicClass: + def __init__(self): + self._val = 1 + + +# If __all__ support is enabled, definitions below +# should not be imported by a star import +def unlistedFun(): + return 0 + + +class UnlistedClass: + def __init__(self): + self._val = 0 + + +# Definitions below should be not be imported by a star import +# (they start with an underscore, and are not listed in __all__) +def _privateFun(): + return -1 + + +class _PrivateClass: + def __init__(self): + self._val = -1 + + +# Test lazy loaded function, as used by extmod/asyncio: +# Works with a star import only if __all__ support is enabled +_attrs = { + "dynamicFun": "funcs", +} + + +def __getattr__(attr): + mod = _attrs.get(attr, None) + if mod is None: + raise AttributeError(attr) + value = getattr(__import__(mod, globals(), locals(), True, 1), attr) + globals()[attr] = value + return value diff --git a/tests/import/pkgstar_all_array/funcs.py b/tests/import/pkgstar_all_array/funcs.py new file mode 100644 index 00000000000..7540d70f66b --- /dev/null +++ b/tests/import/pkgstar_all_array/funcs.py @@ -0,0 +1,2 @@ +def dynamicFun(): + return 777 diff --git a/tests/import/pkgstar_all_inval/__init__.py b/tests/import/pkgstar_all_inval/__init__.py new file mode 100644 index 00000000000..7022476c19b --- /dev/null +++ b/tests/import/pkgstar_all_inval/__init__.py @@ -0,0 +1 @@ +__all__ = 42 diff --git a/tests/import/pkgstar_all_miss/__init__.py b/tests/import/pkgstar_all_miss/__init__.py new file mode 100644 index 00000000000..f9bbb538072 --- /dev/null +++ b/tests/import/pkgstar_all_miss/__init__.py @@ -0,0 +1,8 @@ +__all__ = ("existingFun", "missingFun") + + +def existingFun(): + return None + + +# missingFun is not defined, should raise an error on import diff --git a/tests/import/pkgstar_all_tuple/__init__.py b/tests/import/pkgstar_all_tuple/__init__.py new file mode 100644 index 00000000000..433ddc8e976 --- /dev/null +++ b/tests/import/pkgstar_all_tuple/__init__.py @@ -0,0 +1,22 @@ +__all__ = ("publicFun2", "PublicClass2") + + +# Definitions below should always be imported by a star import +def publicFun2(): + return 2 + + +class PublicClass2: + def __init__(self): + self._val = 2 + + +# If __all__ support is enabled, definitions below +# should not be imported by a star import +def unlistedFun2(): + return 0 + + +class UnlistedClass2: + def __init__(self): + self._val = 0 diff --git a/tests/import/pkgstar_default/__init__.py b/tests/import/pkgstar_default/__init__.py new file mode 100644 index 00000000000..4947e4ce7f1 --- /dev/null +++ b/tests/import/pkgstar_default/__init__.py @@ -0,0 +1,20 @@ +# When __all__ is undefined, star import should only +# show objects that do not start with an underscore + + +def visibleFun(): + return 42 + + +class VisibleClass: + def __init__(self): + self._val = 42 + + +def _hiddenFun(): + return -1 + + +class _HiddenClass: + def __init__(self): + self._val = -1 diff --git a/tests/import/shared_name.py b/tests/import/shared_name.py new file mode 100644 index 00000000000..0ba98242ed9 --- /dev/null +++ b/tests/import/shared_name.py @@ -0,0 +1 @@ +print("hello shared_name.py") diff --git a/tests/import/shared_name/spritesheet.bmp b/tests/import/shared_name/spritesheet.bmp new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/inlineasm/rv32/asmargs.py b/tests/inlineasm/rv32/asmargs.py new file mode 100644 index 00000000000..78afd511150 --- /dev/null +++ b/tests/inlineasm/rv32/asmargs.py @@ -0,0 +1,44 @@ +# test passing arguments + + +@micropython.asm_rv32 +def arg0(): + c_li(a0, 1) + + +print(arg0()) + + +@micropython.asm_rv32 +def arg1(a0): + addi(a0, a0, 1) + + +print(arg1(1)) + + +@micropython.asm_rv32 +def arg2(a0, a1): + add(a0, a0, a1) + + +print(arg2(1, 2)) + + +@micropython.asm_rv32 +def arg3(a0, a1, a2): + add(a0, a0, a1) + add(a0, a0, a2) + + +print(arg3(1, 2, 3)) + + +@micropython.asm_rv32 +def arg4(a0, a1, a2, a3): + add(a0, a0, a1) + add(a0, a0, a2) + add(a0, a0, a3) + + +print(arg4(1, 2, 3, 4)) diff --git a/tests/inlineasm/asmargs.py.exp b/tests/inlineasm/rv32/asmargs.py.exp similarity index 100% rename from tests/inlineasm/asmargs.py.exp rename to tests/inlineasm/rv32/asmargs.py.exp diff --git a/tests/inlineasm/rv32/asmarith.py b/tests/inlineasm/rv32/asmarith.py new file mode 100644 index 00000000000..8b864c0b3b2 --- /dev/null +++ b/tests/inlineasm/rv32/asmarith.py @@ -0,0 +1,79 @@ +# test arithmetic opcodes + + +@micropython.asm_rv32 +def f1(): + li(a0, 0x100) + li(a1, 1) + add(a0, a0, a1) + addi(a0, a0, 1) + addi(a0, a0, -2) + sub(a0, a0, a1) + c_add(a0, a1) + c_addi(a0, -1) + c_sub(a0, a1) + + +print(hex(f1())) + + +@micropython.asm_rv32 +def f2(): + li(a0, 0x10FF) + li(a1, 1) + and_(a2, a0, a1) + andi(a3, a0, 0x10) + or_(a2, a2, a3) + ori(a2, a2, 8) + li(a1, 0x200) + c_or(a2, a1) + li(a1, 0xF0) + mv(a0, a2) + c_and(a0, a1) + li(a1, 0x101) + xor(a0, a0, a1) + xori(a0, a0, 0x101) + c_xor(a0, a1) + + +print(hex(f2())) + + +@micropython.asm_rv32 +def f3(a0, a1): + slt(a0, a0, a1) + + +print(f3(0xFFFFFFF0, 0xFFFFFFF1)) +print(f3(0x0, 0xFFFFFFF1)) +print(f3(0xFFFFFFF1, 0xFFFFFFF1)) +print(f3(0xFFFFFFF1, 0xFFFFFFF0)) + + +@micropython.asm_rv32 +def f4(a0, a1): + sltu(a0, a0, a1) + + +print(f3(0xFFFFFFF0, 0xFFFFFFF1)) +print(f3(0x0, 0xFFFFFFF1)) +print(f3(0xFFFFFFF1, 0xFFFFFFF1)) +print(f3(0xFFFFFFF1, 0xFFFFFFF0)) + + +@micropython.asm_rv32 +def f5(a0): + slti(a0, a0, -2) + + +print(f5(-1)) +print(f5(-3)) + + +@micropython.asm_rv32 +def f6(a0): + sltiu(a0, a0, -2) + + +print(f6(-1)) +print(f6(-3)) diff --git a/tests/inlineasm/rv32/asmarith.py.exp b/tests/inlineasm/rv32/asmarith.py.exp new file mode 100644 index 00000000000..7da4dd5c93c --- /dev/null +++ b/tests/inlineasm/rv32/asmarith.py.exp @@ -0,0 +1,14 @@ +0xfe +0x111 +1 +0 +0 +0 +1 +0 +0 +0 +0 +1 +0 +1 diff --git a/tests/inlineasm/rv32/asmbranch.py b/tests/inlineasm/rv32/asmbranch.py new file mode 100644 index 00000000000..d7d059d4067 --- /dev/null +++ b/tests/inlineasm/rv32/asmbranch.py @@ -0,0 +1,161 @@ +# test branch instructions + + +@micropython.asm_rv32 +def tbeq(a0): + mv(a1, a0) + + li(a0, 10) + li(a2, 1) + beq(a1, a2, end) + + li(a0, 20) + li(a2, 2) + beq(a1, a2, end) + + li(a0, 30) + li(a2, 3) + beq(a1, a2, end) + + li(a0, 0) + + label(end) + + +print(tbeq(0)) +print(tbeq(1)) +print(tbeq(2)) +print(tbeq(3)) + + +@micropython.asm_rv32 +def tbne(a0): + mv(a1, a0) + + li(a0, 10) + li(a2, 1) + bne(a1, a2, end) + + li(a0, 20) + li(a2, 2) + bne(a1, a2, end) + + li(a0, 30) + li(a2, 3) + bne(a1, a2, end) + + li(a0, 0) + + label(end) + + +print(tbne(0)) +print(tbne(1)) +print(tbne(2)) +print(tbne(3)) + + +@micropython.asm_rv32 +def tbgeu(a0): + mv(a1, a0) + + li(a0, 1) + li(a2, 2) + bgeu(a1, a2, end) + li(a0, 0) + + label(end) + + +print(tbgeu(0)) +print(tbgeu(1)) +print(tbgeu(2)) +print(tbgeu(3)) + + +@micropython.asm_rv32 +def tbltu(a0): + mv(a1, a0) + + li(a0, 1) + li(a2, 2) + bltu(a1, a2, end) + li(a0, 0) + + label(end) + + +print(tbltu(0)) +print(tbltu(1)) +print(tbltu(2)) +print(tbltu(3)) + + +@micropython.asm_rv32 +def tbge(a0): + mv(a1, a0) + + li(a0, 1) + li(a2, -2) + bge(a1, a2, end) + li(a0, 0) + + label(end) + + +print(tbge(-3)) +print(tbge(-2)) +print(tbge(-1)) +print(tbge(0)) + + +@micropython.asm_rv32 +def tblt(a0): + mv(a1, a0) + + li(a0, 1) + li(a2, -2) + blt(a1, a2, end) + li(a0, 0) + + label(end) + + +print(tblt(-3)) +print(tblt(-2)) +print(tblt(-1)) +print(tblt(0)) + + +@micropython.asm_rv32 +def tcbeqz(a0): + mv(a1, a0) + + li(a0, 1) + c_beqz(a1, end) + li(a0, 0) + + label(end) + + +print(tcbeqz(0)) +print(tcbeqz(1)) +print(tcbeqz(2)) +print(tcbeqz(3)) + + +@micropython.asm_rv32 +def tcbnez(a0): + mv(a1, a0) + + li(a0, 1) + c_bnez(a1, end) + li(a0, 0) + + label(end) + + +print(tcbnez(0)) +print(tcbnez(1)) +print(tcbnez(2)) +print(tcbnez(3)) diff --git a/tests/inlineasm/rv32/asmbranch.py.exp b/tests/inlineasm/rv32/asmbranch.py.exp new file mode 100644 index 00000000000..baae6914953 --- /dev/null +++ b/tests/inlineasm/rv32/asmbranch.py.exp @@ -0,0 +1,32 @@ +0 +10 +20 +30 +10 +20 +10 +10 +0 +0 +1 +1 +1 +1 +0 +0 +0 +1 +1 +1 +1 +0 +0 +0 +1 +0 +0 +0 +0 +1 +1 +1 diff --git a/tests/inlineasm/rv32/asmconst.py b/tests/inlineasm/rv32/asmconst.py new file mode 100644 index 00000000000..2b6363a43db --- /dev/null +++ b/tests/inlineasm/rv32/asmconst.py @@ -0,0 +1,49 @@ +# test constants in assembler + + +@micropython.asm_rv32 +def c1(): + li(a0, 0xFFFFFFFF) + li(a1, 0xF0000000) + sub(a0, a0, a1) + + +print(hex(c1())) + + +@micropython.asm_rv32 +def c2(): + lui(a0, 0x12345) + li(a1, 0x678) + add(a0, a0, a1) + + +print(hex(c2())) + + +@micropython.asm_rv32 +def c3() -> uint: + lui(a0, 0) + addi(a0, a0, 0x7FF) + + +print(hex(c3())) + + +@micropython.asm_rv32 +def c4() -> uint: + lui(a0, 0) + addi(a0, a0, -1) + + +print(hex(c4())) + + +@micropython.asm_rv32 +def c5(): + c_lui(a0, 1) + c_li(a1, 1) + c_add(a0, a1) + + +print(hex(c5())) diff --git a/tests/inlineasm/rv32/asmconst.py.exp b/tests/inlineasm/rv32/asmconst.py.exp new file mode 100644 index 00000000000..0c713a84148 --- /dev/null +++ b/tests/inlineasm/rv32/asmconst.py.exp @@ -0,0 +1,5 @@ +0xfffffff +0x12345678 +0x7ff +0xffffffff +0x1001 diff --git a/tests/inlineasm/rv32/asmcsr.py b/tests/inlineasm/rv32/asmcsr.py new file mode 100644 index 00000000000..f27e2aa5e34 --- /dev/null +++ b/tests/inlineasm/rv32/asmcsr.py @@ -0,0 +1,65 @@ +# test csr instructions + +# CSR 0x340 is `mscratch`. This test suite is only safe to run on a system +# where it is known that there is no other code that can read from or write +# to that register. The qemu port is one such system, as the CSR is only +# accessed when a machine exception occurs, and at that point it doesn't matter +# anymore whether these tests are running or not. + + +@micropython.asm_rv32 +def csr(): + li(a0, 0) + csrrw(zero, zero, 0x340) # All zeroes + csrrs(a1, zero, 0x340) # Read zeroes + c_bnez(a1, end) + addi(a0, a0, 1) + li(a1, 0xA5A5A5A5) + li(a2, 0x5A5A5A5A) + csrrs(a2, a1, 0x340) # Read zeroes, set 0xA5A5A5A5 + c_bnez(a2, end) + addi(a0, a0, 1) + csrrs(a3, zero, 0x340) # Read 0xA5A5A5A5 + bne(a3, a1, end) + addi(a0, a0, 1) + li(a2, 0xF0F0F0F0) + csrrc(zero, a2, 0x340) # Clear upper half + csrrs(a3, zero, 0x340) # Read 0x05050505 + xori(a2, a2, -1) + and_(a2, a1, a2) + bne(a2, a3, end) + addi(a0, a0, 1) + label(end) + + +print(csr()) + + +@micropython.asm_rv32 +def csri(): + li(a0, 0) + csrrwi(zero, 0x340, 15) # Write 0xF + csrrs(a1, zero, 0x340) # Read 0xF + csrrsi(a2, 0x340, 0) # Read + bne(a1, a2, end) + addi(a0, a0, 1) + csrrci(a2, 0x340, 0) # Read + bne(a1, a2, end) + addi(a0, a0, 1) + li(a2, 15) + bne(a1, a2, end) + addi(a0, a0, 1) + csrrci(zero, 0x340, 1) # Clear bit 1 + csrrs(a1, zero, 0x340) # Read 0xE + li(a2, 14) + bne(a1, a2, end) + addi(a0, a0, 1) + csrrsi(zero, 0x340, 1) # Set bit 1 + csrrs(a1, zero, 0x340) # Read 0xF + li(a2, 15) + bne(a1, a2, end) + addi(a0, a0, 1) + label(end) + + +print(csri()) diff --git a/tests/inlineasm/rv32/asmcsr.py.exp b/tests/inlineasm/rv32/asmcsr.py.exp new file mode 100644 index 00000000000..61c83cba41c --- /dev/null +++ b/tests/inlineasm/rv32/asmcsr.py.exp @@ -0,0 +1,2 @@ +4 +5 diff --git a/tests/inlineasm/rv32/asmdata.py b/tests/inlineasm/rv32/asmdata.py new file mode 100644 index 00000000000..5e555ef4bf4 --- /dev/null +++ b/tests/inlineasm/rv32/asmdata.py @@ -0,0 +1,33 @@ +# test the "data" directive + + +@micropython.asm_rv32 +def ret_num(a0) -> uint: + slli(a0, a0, 2) + addi(a0, a0, 16) + auipc(a1, 0) + add(a1, a1, a0) + lw(a0, 0(a1)) + jal(zero, HERE) + data(4, 0x12345678, 0x20000000, 0x40000000, 0x7FFFFFFF + 1, (1 << 32) - 2) + label(HERE) + + +for i in range(5): + print(hex(ret_num(i))) + + +@micropython.asm_rv32 +def ret_num_la(a0) -> uint: + slli(a0, a0, 2) + la(a1, DATA) + add(a1, a1, a0) + lw(a0, 0(a1)) + jal(zero, HERE) + label(DATA) + data(4, 0x12345678, 0x20000000, 0x40000000, 0x7FFFFFFF + 1, (1 << 32) - 2) + label(HERE) + + +for i in range(5): + print(hex(ret_num_la(i))) diff --git a/tests/inlineasm/rv32/asmdata.py.exp b/tests/inlineasm/rv32/asmdata.py.exp new file mode 100644 index 00000000000..79e92bdfa5d --- /dev/null +++ b/tests/inlineasm/rv32/asmdata.py.exp @@ -0,0 +1,10 @@ +0x12345678 +0x20000000 +0x40000000 +0x80000000 +0xfffffffe +0x12345678 +0x20000000 +0x40000000 +0x80000000 +0xfffffffe diff --git a/tests/inlineasm/rv32/asmdivmul.py b/tests/inlineasm/rv32/asmdivmul.py new file mode 100644 index 00000000000..e1120c6f63c --- /dev/null +++ b/tests/inlineasm/rv32/asmdivmul.py @@ -0,0 +1,63 @@ +@micropython.asm_rv32 +def sdiv(a0, a1): + div(a0, a0, a1) + + +@micropython.asm_rv32 +def udiv(a0, a1): + divu(a0, a0, a1) + + +@micropython.asm_rv32 +def srem(a0, a1): + rem(a0, a0, a1) + + +@micropython.asm_rv32 +def urem(a0, a1): + remu(a0, a0, a1) + + +print(sdiv(1234, 3)) +print(sdiv(-1234, 3)) +print(sdiv(1234, -3)) +print(sdiv(-1234, -3)) + +print(udiv(1234, 3)) +print(udiv(0xFFFFFFFF, 0x7FFFFFFF)) +print(udiv(0xFFFFFFFF, 0xFFFFFFFF)) + +print(srem(1234, 3)) +print(srem(-1234, 3)) +print(srem(1234, -3)) +print(srem(-1234, -3)) + +print(urem(1234, 3)) +print(urem(0xFFFFFFFF, 0x7FFFFFFF)) +print(urem(0xFFFFFFFF, 0xFFFFFFFF)) + + +@micropython.asm_rv32 +def m1(a0, a1): + mul(a0, a0, a1) + + +@micropython.asm_rv32 +def m2(a0, a1): + mulh(a0, a0, a1) + + +@micropython.asm_rv32 +def m3(a0, a1): + mulhu(a0, a0, a1) + + +@micropython.asm_rv32 +def m4(a0, a1): + mulhsu(a0, a0, a1) + + +print(m1(0xFFFFFFFF, 2)) +print(m2(0xFFFFFFFF, 0xFFFFFFF0)) +print(m3(0xFFFFFFFF, 0xFFFFFFF0)) +print(m4(0xFFFFFFFF, 0xFFFFFFF0)) diff --git a/tests/inlineasm/rv32/asmdivmul.py.exp b/tests/inlineasm/rv32/asmdivmul.py.exp new file mode 100644 index 00000000000..60d28635f79 --- /dev/null +++ b/tests/inlineasm/rv32/asmdivmul.py.exp @@ -0,0 +1,18 @@ +411 +-411 +-411 +411 +411 +2 +1 +1 +-1 +1 +-1 +1 +1 +0 +-2 +0 +-17 +-1 diff --git a/tests/inlineasm/rv32/asmjump.py b/tests/inlineasm/rv32/asmjump.py new file mode 100644 index 00000000000..fe87d3f968b --- /dev/null +++ b/tests/inlineasm/rv32/asmjump.py @@ -0,0 +1,115 @@ +@micropython.asm_rv32 +def f1(): + li(a0, 0) + la(a1, END) + c_jr(a1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + label(END) + + +print(f1()) + + +@micropython.asm_rv32 +def f2(): + addi(sp, sp, -4) + c_swsp(ra, 0) + li(ra, 0) + li(a0, 0) + c_jal(END) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + label(END) + bne(ra, zero, SUCCESS) + c_addi(a0, 2) + label(SUCCESS) + c_lwsp(ra, 0) + addi(sp, sp, 4) + + +print(f2()) + + +@micropython.asm_rv32 +def f3(): + li(a0, 0) + c_j(END) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + label(END) + + +print(f3()) + + +@micropython.asm_rv32 +def f4(): + addi(sp, sp, -4) + c_swsp(ra, 0) + li(ra, 0) + li(a0, 0) + la(a1, END) + c_jalr(a1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + label(END) + bne(ra, zero, SUCCESS) + c_addi(a0, 2) + label(SUCCESS) + c_lwsp(ra, 0) + addi(sp, sp, 4) + + +print(f4()) + + +@micropython.asm_rv32 +def f5(): + li(a0, 0) + li(a1, 0) + jal(a1, END) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + label(END) + bne(a1, zero, SUCCESS) + c_addi(a0, 2) + label(SUCCESS) + + +print(f5()) + + +@micropython.asm_rv32 +def f6(): + li(a0, 0) + la(a1, JUMP) + li(a2, 0) + jalr(a2, a1, 10) + label(JUMP) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + c_addi(a0, 1) + bne(a2, zero, SUCCESS) + c_addi(a0, 2) + label(SUCCESS) + + +print(f6()) diff --git a/tests/inlineasm/rv32/asmjump.py.exp b/tests/inlineasm/rv32/asmjump.py.exp new file mode 100644 index 00000000000..f7eb44d66e0 --- /dev/null +++ b/tests/inlineasm/rv32/asmjump.py.exp @@ -0,0 +1,6 @@ +0 +0 +0 +0 +0 +0 diff --git a/tests/inlineasm/rv32/asmloadstore.py b/tests/inlineasm/rv32/asmloadstore.py new file mode 100644 index 00000000000..2c49e07b41a --- /dev/null +++ b/tests/inlineasm/rv32/asmloadstore.py @@ -0,0 +1,86 @@ +# test load/store opcodes + + +@micropython.asm_rv32 +def l(): + li(a5, 4) + addi(sp, sp, -12) + li(a0, 0x123) + c_swsp(a0, 0) + addi(a1, a0, 0x111) + c_swsp(a1, 4) + addi(a2, a1, 0x111) + c_swsp(a2, 8) + mv(a4, sp) + c_lw(a3, 0(a4)) + bne(a3, a0, END) + addi(a5, a5, -1) + lw(a3, 4(a4)) + bne(a3, a1, END) + addi(a5, a5, -1) + lhu(a3, 8(a4)) + bne(a3, a2, END) + addi(a5, a5, -1) + lbu(a0, 8(a4)) + addi(a0, a0, 0x300) + bne(a0, a2, END) + addi(a5, a5, -1) + label(END) + addi(sp, sp, 12) + mv(a0, a5) + + +print(l()) + + +@micropython.asm_rv32 +def s(): + li(a5, 4) + addi(sp, sp, -12) + c_swsp(zero, 0) + c_swsp(zero, 4) + c_swsp(zero, 8) + li(a0, 0x12345) + mv(a4, sp) + c_sw(a0, 0(a4)) + sh(a0, 4(a4)) + sb(a0, 8(a4)) + li(a1, 0xFFFF) + and_(a1, a0, a1) + andi(a2, a0, 0xFF) + lw(a3, 0(sp)) + bne(a3, a0, END) + addi(a5, a5, -1) + lw(a3, 4(sp)) + bne(a3, a1, END) + addi(a5, a5, -1) + lw(a3, 8(sp)) + bne(a3, a2, END) + addi(a5, a5, -1) + label(END) + addi(sp, sp, 12) + mv(a0, a5) + + +print(s()) + + +@micropython.asm_rv32 +def lu(): + li(a5, 4) + addi(sp, sp, -8) + li(a0, 0xF1234567) + c_swsp(a0, 0) + c_swsp(a0, 4) + lh(a1, 0(sp)) + blt(a1, zero, END) + addi(a5, a5, -1) + lb(a2, 4(sp)) + blt(a2, zero, END) + addi(a5, a5, -1) + label(END) + addi(sp, sp, 8) + mv(a0, a5) + + +print(lu()) diff --git a/tests/inlineasm/rv32/asmloadstore.py.exp b/tests/inlineasm/rv32/asmloadstore.py.exp new file mode 100644 index 00000000000..4539bbf2d22 --- /dev/null +++ b/tests/inlineasm/rv32/asmloadstore.py.exp @@ -0,0 +1,3 @@ +0 +1 +2 diff --git a/tests/inlineasm/rv32/asmrettype.py b/tests/inlineasm/rv32/asmrettype.py new file mode 100644 index 00000000000..fc7ae61d152 --- /dev/null +++ b/tests/inlineasm/rv32/asmrettype.py @@ -0,0 +1,33 @@ +# test return type of inline asm + + +@micropython.asm_rv32 +def ret_obj(a0) -> object: + pass + + +ret_obj(print)(1) + + +@micropython.asm_rv32 +def ret_bool(a0) -> bool: + pass + + +print(ret_bool(0), ret_bool(1)) + + +@micropython.asm_rv32 +def ret_int(a0) -> int: + slli(a0, a0, 29) + + +print(ret_int(0), hex(ret_int(1)), hex(ret_int(2)), hex(ret_int(4))) + + +@micropython.asm_rv32 +def ret_uint(a0) -> uint: + slli(a0, a0, 29) + + +print(ret_uint(0), hex(ret_uint(1)), hex(ret_uint(2)), hex(ret_uint(4))) diff --git a/tests/inlineasm/asmrettype.py.exp b/tests/inlineasm/rv32/asmrettype.py.exp similarity index 100% rename from tests/inlineasm/asmrettype.py.exp rename to tests/inlineasm/rv32/asmrettype.py.exp diff --git a/tests/inlineasm/rv32/asmsanity.py b/tests/inlineasm/rv32/asmsanity.py new file mode 100644 index 00000000000..1a16d3504db --- /dev/null +++ b/tests/inlineasm/rv32/asmsanity.py @@ -0,0 +1,204 @@ +TEMPLATE3 = """ +@micropython.asm_rv32 +def f(): + {}({}, {}, {}) +""" + +TEMPLATE2 = """ +@micropython.asm_rv32 +def f(): + {}({}, {}) +""" + +TEMPLATE1 = """ +@micropython.asm_rv32 +def f(): + {}({}) +""" + + +REGISTERS = [ + "zero", + "s0", + "s1", + "s2", + "s3", + "s4", + "s5", + "s6", + "s7", + "s8", + "s9", + "s10", + "s11", + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "a6", + "a7", + "tp", + "gp", + "sp", + "ra", + "t0", + "t1", + "t2", + "t3", + "t4", + "t5", + "t6", + "x0", + "x1", + "x2", + "x3", + "x4", + "x5", + "x6", + "x7", + "x8", + "x9", + "x10", + "x11", + "x12", + "x13", + "x14", + "x15", + "x16", + "x17", + "x18", + "x19", + "x20", + "x21", + "x22", + "x23", + "x24", + "x25", + "x26", + "x27", + "x28", + "x29", + "x30", + "x31", +] + + +def harness(opcode, fragment, tag): + try: + exec(fragment) + except SyntaxError: + print(tag, opcode) + + +for opcode in ("slli", "srli", "srai"): + harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", -1), "-") + harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", 33), "+") + +for opcode in ("c_slli", "c_srli", "c_srai"): + harness(opcode, TEMPLATE2.format(opcode, "a0", -1), "-") + harness(opcode, TEMPLATE2.format(opcode, "a0", 33), "+") + +harness("c_slli", TEMPLATE2.format("c_slli", "zero", 0), "0") +harness("c_slli", TEMPLATE2.format("c_slli", "x0", 0), "0") + +for opcode in ("c_srli", "c_srai"): + for register in REGISTERS: + harness(opcode, TEMPLATE2.format(opcode, register, 0), register) + +for opcode in ("c_mv", "c_add"): + harness(opcode, TEMPLATE2.format(opcode, "a0", "zero"), "0l") + harness(opcode, TEMPLATE2.format(opcode, "zero", "a0"), "0r") + harness(opcode, TEMPLATE2.format(opcode, "zero", "zero"), "0b") + +harness("c_jr", TEMPLATE1.format("c_jr", "zero"), "0") + +for opcode in ("addi", "andi", "ori", "slti", "sltiu", "xori"): + harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", 0x7FF), ">=s") + harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", 0x800), ">s") + harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", -2048), "<=s") + harness(opcode, TEMPLATE3.format(opcode, "a0", "a0", -2049), "=s") + harness(opcode, TEMPLATE.format(opcode, 0x800), ">s") + harness(opcode, TEMPLATE.format(opcode, -2048), "<=s") + harness(opcode, TEMPLATE.format(opcode, -2049), "0") +harness("c_addi", TEMPLATE2.format("c_andi", "zero", -512), "<0") +harness("c_addi", TEMPLATE2.format("c_andi", "s0", 0), "s0") +harness("c_addi", TEMPLATE2.format("c_andi", "s0", -100), "s") + +harness("c_andi", TEMPLATE2.format("c_andi", "zero", 0), "00") +harness("c_andi", TEMPLATE2.format("c_andi", "zero", 512), ">0") +harness("c_andi", TEMPLATE2.format("c_andi", "zero", -512), "<0") +harness("c_andi", TEMPLATE2.format("c_andi", "s0", 0), "s0") +harness("c_andi", TEMPLATE2.format("c_andi", "s0", -100), "s") + +C_REGISTERS = ( + "a0", + "a1", + "a2", + "a3", + "a4", + "a5", + "s0", + "s1", + "x8", + "x9", + "x10", + "x11", + "x12", + "x13", + "x14", + "x15", +) + +for opcode in ("c_and", "c_or", "c_xor"): + for source in REGISTERS: + for destination in REGISTERS: + if source in C_REGISTERS and destination in C_REGISTERS: + try: + exec( + """ +@micropython.asm_rv32 +def f(): + {}({}, {}) +""".format(opcode, source, destination) + ) + except SyntaxError: + print(source, destination, opcode) + else: + try: + exec( + """ +@micropython.asm_rv32 +def f(): + {}({}, {}) +""".format(opcode, source, destination) + ) + print(source, destination, opcode) + except SyntaxError: + pass + print(opcode) + +for opcode in ("c_lw", "c_sw"): + TEMPLATE = """ +@micropython.asm_rv32 +def f(): + {}(a0, {}(a0)) +""" + harness(opcode, TEMPLATE.format(opcode, 60), ">=s") + harness(opcode, TEMPLATE.format(opcode, 61), ">s") + harness(opcode, TEMPLATE.format(opcode, -60), "<=s") + harness(opcode, TEMPLATE.format(opcode, -61), "s addi +s andi +s ori +s slti +s sltiu +s xori +s lb +s lbu +s lh +s lhu +s lw +s sb +s sh +s sw +0 c_addi +<0 c_addi +s c_addi +00 c_andi +>0 c_andi +<0 c_andi +s c_andi +c_and +c_or +c_xor +>s c_lw +s c_sw + int: + addmi(a2, a2, {}) +print(f1(0)) +""" + +for value in (-32768, -32767, 32512, 32513, 0): + try: + exec(ADDMI_TEMPLATE.format(value)) + except SyntaxError as error: + print(error) + + +@micropython.asm_xtensa +def a2(a2, a3) -> int: + addx2(a2, a2, a3) + + +@micropython.asm_xtensa +def a4(a2, a3) -> int: + addx4(a2, a2, a3) + + +@micropython.asm_xtensa +def a8(a2, a3) -> int: + addx8(a2, a2, a3) + + +@micropython.asm_xtensa +def s2(a2, a3) -> int: + subx2(a2, a2, a3) + + +@micropython.asm_xtensa +def s4(a2, a3) -> int: + subx4(a2, a2, a3) + + +@micropython.asm_xtensa +def s8(a2, a3) -> int: + subx8(a2, a2, a3) + + +for first, second in ((100, 100), (-100, 100), (-100, -100), (100, -100)): + print("a2", a2(first, second)) + print("a4", a4(first, second)) + print("a8", a8(first, second)) + print("s2", s2(first, second)) + print("s4", s4(first, second)) + print("s8", s8(first, second)) + + +@micropython.asm_xtensa +def f5(a2) -> int: + neg(a2, a2) + + +for value in (0, -100, 100): + print(f5(value)) + + +@micropython.asm_xtensa +def f6(): + movi(a2, 0x100) + movi(a3, 1) + add(a2, a2, a3) + addi(a2, a2, 1) + addi(a2, a2, -2) + sub(a2, a2, a3) + + +print(hex(f6())) + + +@micropython.asm_xtensa +def f7(): + movi(a2, 0x10FF) + movi(a3, 1) + and_(a4, a2, a3) + or_(a4, a4, a3) + movi(a3, 0x200) + xor(a2, a4, a3) + + +print(hex(f7())) + + +@micropython.asm_xtensa +def f8(a2, a3): + add_n(a2, a2, a3) + + +print(f8(100, 200)) + + +@micropython.asm_xtensa +def f9(a2): + addi_n(a2, a2, 1) + + +print(f9(100)) + + +@micropython.asm_xtensa +def f10(a2, a3) -> uint: + mull(a2, a2, a3) + + +print(hex(f10(0xC0000000, 2))) diff --git a/tests/inlineasm/xtensa/asmarith.py.exp b/tests/inlineasm/xtensa/asmarith.py.exp new file mode 100644 index 00000000000..7aba46a27d9 --- /dev/null +++ b/tests/inlineasm/xtensa/asmarith.py.exp @@ -0,0 +1,40 @@ +10 +10 +0 +-32768 +-32767 is not a multiple of 256 +32512 +'addmi' integer 32513 isn't within range -32768..32512 +0 +a2 300 +a4 500 +a8 900 +s2 100 +s4 300 +s8 700 +a2 -100 +a4 -300 +a8 -700 +s2 -300 +s4 -500 +s8 -900 +a2 -300 +a4 -500 +a8 -900 +s2 -100 +s4 -300 +s8 -700 +a2 100 +a4 300 +a8 700 +s2 300 +s4 500 +s8 900 +0 +100 +-100 +0xff +0x201 +300 +101 +0x80000000 diff --git a/tests/inlineasm/xtensa/asmbranch.py b/tests/inlineasm/xtensa/asmbranch.py new file mode 100644 index 00000000000..22bcd5a7c71 --- /dev/null +++ b/tests/inlineasm/xtensa/asmbranch.py @@ -0,0 +1,299 @@ +# test branch instructions + + +@micropython.asm_xtensa +def tball(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + ball(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tball(0xFFFFFFFF, 0xFFFFFFFF)) +print(tball(0xFFFEFFFF, 0xFFFFFFFF)) +print(tball(0x00000000, 0xFFFFFFFF)) +print(tball(0xFFFFFFFF, 0x01010101)) + + +@micropython.asm_xtensa +def tbany(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bany(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbany(0xFFFFFFFF, 0xFFFFFFFF)) +print(tbany(0xFFFEFFFF, 0xFFFFFFFF)) +print(tbany(0x00000000, 0xFFFFFFFF)) +print(tbany(0xFFFFFFFF, 0x01010101)) + + +@micropython.asm_xtensa +def tbbc(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bbc(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbbc(0xFFFFFFFF, 4)) +print(tbbc(0xFFFEFFFF, 16)) +print(tbbc(0x00000000, 1)) + + +BBCI_TEMPLATE = """ +@micropython.asm_xtensa +def tbbci(a2) -> int: + mov(a3, a2) + movi(a2, 0) + bbci(a3, {}, end) + movi(a2, -1) + label(end) + +print(tbbci({})) +""" + + +for value, bit in ((0xFFFFFFFF, 4), (0xFFFEFFFF, 16), (0x00000000, 1)): + try: + exec(BBCI_TEMPLATE.format(bit, value)) + except SyntaxError as error: + print(error) + + +@micropython.asm_xtensa +def tbbs(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bbs(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbbs(0x00000000, 4)) +print(tbbs(0x00010000, 16)) +print(tbbs(0xFFFFFFFF, 1)) + + +BBSI_TEMPLATE = """ +@micropython.asm_xtensa +def tbbsi(a2) -> int: + mov(a3, a2) + movi(a2, 0) + bbsi(a3, {}, end) + movi(a2, -1) + label(end) + +print(tbbsi({})) +""" + + +for value, bit in ((0x00000000, 4), (0x00010000, 16), (0xFFFFFFFF, 1)): + try: + exec(BBSI_TEMPLATE.format(bit, value)) + except SyntaxError as error: + print(error) + + +@micropython.asm_xtensa +def tbeq(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + beq(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbeq(0x00000000, 0x00000000)) +print(tbeq(0x00010000, 0x00000000)) +print(tbeq(0xFFFFFFFF, 0xFFFFFFFF)) + + +@micropython.asm_xtensa +def tbeqz(a2) -> int: + mov(a3, a2) + movi(a2, 0) + beqz(a3, end) + movi(a2, -1) + label(end) + + +print(tbeqz(0)) +print(tbeqz(0x12345678)) +print(tbeqz(-1)) + + +@micropython.asm_xtensa +def tbge(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bge(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbge(0x00000000, 0x00000000)) +print(tbge(0x00010000, 0x00000000)) +print(tbge(0xF0000000, 0xFFFFFFFF)) + + +@micropython.asm_xtensa +def tbgeu(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bgeu(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbgeu(0x00000000, 0x00000000)) +print(tbgeu(0x00010000, 0x00000000)) +print(tbgeu(0xF0000000, 0xFFFFFFFF)) +print(tbgeu(0xFFFFFFFF, 0xF0000000)) + + +@micropython.asm_xtensa +def tbgez(a2) -> int: + mov(a3, a2) + movi(a2, 0) + bgez(a3, end) + movi(a2, -1) + label(end) + + +print(tbgez(0)) +print(tbgez(0x12345678)) +print(tbgez(-1)) + + +@micropython.asm_xtensa +def tblt(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + blt(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tblt(0x00000000, 0x00000000)) +print(tblt(0x00010000, 0x00000000)) +print(tblt(0xF0000000, 0xFFFFFFFF)) + + +@micropython.asm_xtensa +def tbltu(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bltu(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbltu(0x00000000, 0x00000000)) +print(tbltu(0x00010000, 0x00000000)) +print(tbltu(0xF0000000, 0xFFFFFFFF)) +print(tbltu(0xFFFFFFFF, 0xF0000000)) + + +@micropython.asm_xtensa +def tbltz(a2) -> int: + mov(a3, a2) + movi(a2, 0) + bltz(a3, end) + movi(a2, -1) + label(end) + + +print(tbltz(0)) +print(tbltz(0x12345678)) +print(tbltz(-1)) + + +@micropython.asm_xtensa +def tbnall(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bnall(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbnall(0xFFFFFFFF, 0xFFFFFFFF)) +print(tbnall(0xFFFEFFFF, 0xFFFFFFFF)) +print(tbnall(0x00000000, 0xFFFFFFFF)) +print(tbnall(0xFFFFFFFF, 0x01010101)) + + +@micropython.asm_xtensa +def tbne(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bne(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbne(0x00000000, 0x00000000)) +print(tbne(0x00010000, 0x00000000)) +print(tbne(0xFFFFFFFF, 0xFFFFFFFF)) + + +@micropython.asm_xtensa +def tbnez(a2) -> int: + mov(a3, a2) + movi(a2, 0) + bnez(a3, end) + movi(a2, -1) + label(end) + + +print(tbnez(0)) +print(tbnez(0x12345678)) +print(tbnez(-1)) + + +@micropython.asm_xtensa +def tbnone(a2, a3) -> int: + mov(a4, a2) + movi(a2, 0) + bnone(a4, a3, end) + movi(a2, -1) + label(end) + + +print(tbnone(0xFFFFFFFF, 0xFFFFFFFF)) +print(tbnone(0xFFFEFFFF, 0xFFFFFFFF)) +print(tbnone(0x00000000, 0xFFFFFFFF)) +print(tbnone(0x10101010, 0x01010101)) + + +@micropython.asm_xtensa +def tbeqz_n(a2) -> int: + mov(a3, a2) + movi(a2, 0) + beqz_n(a3, end) + movi(a2, -1) + label(end) + + +print(tbeqz_n(0)) +print(tbeqz_n(0x12345678)) +print(tbeqz_n(-1)) + + +@micropython.asm_xtensa +def tbnez_n(a2) -> int: + mov(a3, a2) + movi(a2, 0) + bnez(a3, end) + movi(a2, -1) + label(end) + + +print(tbnez_n(0)) +print(tbnez_n(0x12345678)) +print(tbnez_n(-1)) diff --git a/tests/inlineasm/xtensa/asmbranch.py.exp b/tests/inlineasm/xtensa/asmbranch.py.exp new file mode 100644 index 00000000000..319a4b435ef --- /dev/null +++ b/tests/inlineasm/xtensa/asmbranch.py.exp @@ -0,0 +1,66 @@ +0 +-1 +-1 +0 +0 +0 +-1 +0 +-1 +0 +0 +-1 +0 +0 +-1 +0 +0 +-1 +0 +0 +0 +-1 +0 +0 +-1 +-1 +0 +0 +-1 +0 +0 +-1 +0 +0 +0 +-1 +-1 +-1 +0 +-1 +-1 +0 +-1 +-1 +-1 +0 +-1 +0 +0 +-1 +-1 +0 +-1 +-1 +0 +0 +-1 +-1 +0 +0 +0 +-1 +-1 +-1 +0 +0 diff --git a/tests/inlineasm/xtensa/asmjump.py b/tests/inlineasm/xtensa/asmjump.py new file mode 100644 index 00000000000..f41c9482319 --- /dev/null +++ b/tests/inlineasm/xtensa/asmjump.py @@ -0,0 +1,26 @@ +@micropython.asm_xtensa +def jump() -> int: + movi(a2, 0) + j(NEXT) + addi(a2, a2, 1) + j(DONE) + label(NEXT) + addi(a2, a2, 2) + label(DONE) + + +print(jump()) + + +@micropython.asm_xtensa +def jumpx() -> int: + call0(ENTRY) + label(ENTRY) + movi(a2, 0) + addi(a3, a0, 12) + jx(a3) + movi(a2, 1) + movi(a2, 2) + + +print(jumpx()) diff --git a/tests/inlineasm/xtensa/asmjump.py.exp b/tests/inlineasm/xtensa/asmjump.py.exp new file mode 100644 index 00000000000..51993f072d5 --- /dev/null +++ b/tests/inlineasm/xtensa/asmjump.py.exp @@ -0,0 +1,2 @@ +2 +2 diff --git a/tests/inlineasm/xtensa/asmloadstore.py b/tests/inlineasm/xtensa/asmloadstore.py new file mode 100644 index 00000000000..b185e30520c --- /dev/null +++ b/tests/inlineasm/xtensa/asmloadstore.py @@ -0,0 +1,98 @@ +import array + +# On the 8266 the generated code gets put into the IRAM segment, which is only +# word-addressable. Therefore, to test byte and halfword load/store opcodes +# some memory must be reserved in the DRAM segment. + +BYTE_DATA = array.array("B", (0x11, 0x22, 0x33, 0x44)) +WORD_DATA = array.array("h", (100, 200, -100, -200)) +DWORD_DATA = array.array("i", (100_000, -200_000, 300_000, -400_000)) + + +@micropython.asm_xtensa +def tl32r() -> int: + nop() + j(CODE) + align(4) + label(DATA) + data(1, 1, 2, 3, 4, 5, 6, 7) + align(4) + label(CODE) + nop_n() + nop_n() + l32r(a2, DATA) + + +print(hex(tl32r())) + + +@micropython.asm_xtensa +def tl32i() -> uint: + call0(ENTRY) + label(ENTRY) + l32i(a2, a0, 0) + + +print(hex(tl32i())) + + +@micropython.asm_xtensa +def tl8ui(a2) -> uint: + mov(a3, a2) + l8ui(a2, a3, 1) + + +print(hex(tl8ui(BYTE_DATA))) + + +@micropython.asm_xtensa +def tl16ui(a2) -> uint: + mov(a3, a2) + l16ui(a2, a3, 2) + + +print(tl16ui(WORD_DATA)) + + +@micropython.asm_xtensa +def tl16si(a2) -> int: + mov(a3, a2) + l16si(a2, a3, 6) + + +print(tl16si(WORD_DATA)) + + +@micropython.asm_xtensa +def ts8i(a2, a3): + s8i(a3, a2, 1) + + +ts8i(BYTE_DATA, 0xFF) +print(BYTE_DATA) + + +@micropython.asm_xtensa +def ts16i(a2, a3): + s16i(a3, a2, 2) + + +ts16i(WORD_DATA, -123) +print(WORD_DATA) + + +@micropython.asm_xtensa +def ts32i(a2, a3) -> uint: + s32i(a3, a2, 4) + + +ts32i(DWORD_DATA, -123456) +print(DWORD_DATA) + + +@micropython.asm_xtensa +def tl32i_n(a2) -> uint: + l32i_n(a2, a2, 8) + + +print(tl32i_n(DWORD_DATA)) diff --git a/tests/inlineasm/xtensa/asmloadstore.py.exp b/tests/inlineasm/xtensa/asmloadstore.py.exp new file mode 100644 index 00000000000..e6672df6f81 --- /dev/null +++ b/tests/inlineasm/xtensa/asmloadstore.py.exp @@ -0,0 +1,9 @@ +0x4030201 +0xf8002022 +0x22 +200 +-200 +array('B', [17, 255, 51, 68]) +array('h', [100, -123, -100, -200]) +array('i', [100000, -123456, 300000, -400000]) +300000 diff --git a/tests/inlineasm/xtensa/asmmisc.py b/tests/inlineasm/xtensa/asmmisc.py new file mode 100644 index 00000000000..271ab836625 --- /dev/null +++ b/tests/inlineasm/xtensa/asmmisc.py @@ -0,0 +1,25 @@ +@micropython.asm_xtensa +def tnop(a2, a3, a4, a5): + nop() + + +out2 = tnop(0x100, 0x200, 0x300, 0x400) +print(out2 == 0x100) + + +@micropython.asm_xtensa +def tnop_n(a2, a3, a4, a5): + nop_n() + + +out2 = tnop_n(0x100, 0x200, 0x300, 0x400) +print(out2 == 0x100) + + +@micropython.asm_xtensa +def tmov_n(a2, a3): + mov_n(a4, a3) + add(a2, a4, a3) + + +print(tmov_n(0, 1)) diff --git a/tests/inlineasm/xtensa/asmmisc.py.exp b/tests/inlineasm/xtensa/asmmisc.py.exp new file mode 100644 index 00000000000..eefaa35daf0 --- /dev/null +++ b/tests/inlineasm/xtensa/asmmisc.py.exp @@ -0,0 +1,3 @@ +True +True +2 diff --git a/tests/inlineasm/xtensa/asmshift.py b/tests/inlineasm/xtensa/asmshift.py new file mode 100644 index 00000000000..271ca1ccd49 --- /dev/null +++ b/tests/inlineasm/xtensa/asmshift.py @@ -0,0 +1,137 @@ +@micropython.asm_xtensa +def lsl1(a2): + slli(a2, a2, 1) + + +print(hex(lsl1(0x123))) + + +@micropython.asm_xtensa +def lsl23(a2): + slli(a2, a2, 23) + + +print(hex(lsl23(1))) + + +@micropython.asm_xtensa +def lsr1(a2): + srli(a2, a2, 1) + + +print(hex(lsr1(0x123))) + + +@micropython.asm_xtensa +def lsr15(a2): + srli(a2, a2, 15) + + +print(hex(lsr15(0x80000000))) + + +@micropython.asm_xtensa +def asr1(a2): + srai(a2, a2, 1) + + +print(hex(asr1(0x123))) + + +@micropython.asm_xtensa +def asr31(a2): + srai(a2, a2, 31) + + +print(hex(asr31(0x80000000))) + + +@micropython.asm_xtensa +def lsl1r(a2): + movi(a3, 1) + ssl(a3) + sll(a2, a2) + + +print(hex(lsl1r(0x123))) + + +@micropython.asm_xtensa +def lsr1r(a2): + movi(a3, 1) + ssr(a3) + srl(a2, a2) + + +print(hex(lsr1r(0x123))) + + +@micropython.asm_xtensa +def asr1r(a2): + movi(a3, 1) + ssr(a3) + sra(a2, a2) + + +print(hex(asr1r(0x123))) + + +@micropython.asm_xtensa +def sll9(a2): + ssai(9) + sll(a2, a2) + + +print(hex(sll9(1))) + + +@micropython.asm_xtensa +def srlr(a2, a3): + ssa8l(a3) + srl(a2, a2) + + +print(hex(srlr(0x12340000, 2))) + + +@micropython.asm_xtensa +def sllr(a2, a3): + ssa8b(a3) + sll(a2, a2) + + +print(hex(sllr(0x1234, 2))) + + +@micropython.asm_xtensa +def srcr(a2, a3, a4): + ssr(a4) + src(a2, a2, a3) + + +print(hex(srcr(0x00000001, 0x80000000, 2))) + + +@micropython.asm_xtensa +def srai24(a2): + srai(a2, a2, 24) + + +print(hex(srai24(0x12345678))) + + +@micropython.asm_xtensa +def nsar(a2, a3): + nsa(a2, a3) + + +print(nsar(0x12345678, 0)) +print(nsar(0x12345678, -1)) + + +@micropython.asm_xtensa +def nsaur(a2, a3): + nsau(a2, a3) + + +print(nsaur(0x12345678, 0)) diff --git a/tests/inlineasm/xtensa/asmshift.py.exp b/tests/inlineasm/xtensa/asmshift.py.exp new file mode 100644 index 00000000000..3e2bb3b4aef --- /dev/null +++ b/tests/inlineasm/xtensa/asmshift.py.exp @@ -0,0 +1,17 @@ +0x246 +0x800000 +0x91 +0x10000 +0x91 +-0x1 +0x246 +0x91 +0x91 +0x800000 +0x1234 +0x12340000 +0x60000000 +0x12 +31 +31 +32 diff --git a/tests/internal_bench/class_create-0-empty.py b/tests/internal_bench/class_create-0-empty.py new file mode 100644 index 00000000000..1fd8ccd9257 --- /dev/null +++ b/tests/internal_bench/class_create-0-empty.py @@ -0,0 +1,11 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-1-slots.py b/tests/internal_bench/class_create-1-slots.py new file mode 100644 index 00000000000..9b3e4b9570d --- /dev/null +++ b/tests/internal_bench/class_create-1-slots.py @@ -0,0 +1,12 @@ +import bench + + +def test(num): + l = ["x"] + for i in range(num // 40): + + class X: + __slots__ = l + + +bench.run(test) diff --git a/tests/internal_bench/class_create-1.1-slots5.py b/tests/internal_bench/class_create-1.1-slots5.py new file mode 100644 index 00000000000..ccac77dec9d --- /dev/null +++ b/tests/internal_bench/class_create-1.1-slots5.py @@ -0,0 +1,12 @@ +import bench + + +def test(num): + l = ["a", "b", "c", "d", "x"] + for i in range(num // 40): + + class X: + __slots__ = l + + +bench.run(test) diff --git a/tests/internal_bench/class_create-2-classattr.py b/tests/internal_bench/class_create-2-classattr.py new file mode 100644 index 00000000000..049a7dab170 --- /dev/null +++ b/tests/internal_bench/class_create-2-classattr.py @@ -0,0 +1,11 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + x = 1 + + +bench.run(test) diff --git a/tests/internal_bench/class_create-2.1-classattr5.py b/tests/internal_bench/class_create-2.1-classattr5.py new file mode 100644 index 00000000000..5051e7dcca7 --- /dev/null +++ b/tests/internal_bench/class_create-2.1-classattr5.py @@ -0,0 +1,15 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + a = 0 + b = 0 + c = 0 + d = 0 + x = 1 + + +bench.run(test) diff --git a/tests/internal_bench/class_create-2.3-classattr5objs.py b/tests/internal_bench/class_create-2.3-classattr5objs.py new file mode 100644 index 00000000000..74540865dcd --- /dev/null +++ b/tests/internal_bench/class_create-2.3-classattr5objs.py @@ -0,0 +1,20 @@ +import bench + + +class Class: + pass + + +def test(num): + instance = Class() + for i in range(num // 40): + + class X: + a = instance + b = instance + c = instance + d = instance + x = instance + + +bench.run(test) diff --git a/tests/internal_bench/class_create-3-instancemethod.py b/tests/internal_bench/class_create-3-instancemethod.py new file mode 100644 index 00000000000..e8c201cb2c3 --- /dev/null +++ b/tests/internal_bench/class_create-3-instancemethod.py @@ -0,0 +1,12 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + def x(self): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-4-classmethod.py b/tests/internal_bench/class_create-4-classmethod.py new file mode 100644 index 00000000000..f34962bc671 --- /dev/null +++ b/tests/internal_bench/class_create-4-classmethod.py @@ -0,0 +1,13 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + @classmethod + def x(cls): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-4.1-classmethod_implicit.py b/tests/internal_bench/class_create-4.1-classmethod_implicit.py new file mode 100644 index 00000000000..f2d1fcfd188 --- /dev/null +++ b/tests/internal_bench/class_create-4.1-classmethod_implicit.py @@ -0,0 +1,12 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + def __new__(cls): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-5-staticmethod.py b/tests/internal_bench/class_create-5-staticmethod.py new file mode 100644 index 00000000000..06335566675 --- /dev/null +++ b/tests/internal_bench/class_create-5-staticmethod.py @@ -0,0 +1,13 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + @staticmethod + def x(): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-6-getattribute.py b/tests/internal_bench/class_create-6-getattribute.py new file mode 100644 index 00000000000..10a4fe7ce8d --- /dev/null +++ b/tests/internal_bench/class_create-6-getattribute.py @@ -0,0 +1,12 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + def __getattribute__(self, name): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-6.1-getattr.py b/tests/internal_bench/class_create-6.1-getattr.py new file mode 100644 index 00000000000..b4b9ba2f552 --- /dev/null +++ b/tests/internal_bench/class_create-6.1-getattr.py @@ -0,0 +1,12 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + def __getattr__(self, name): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-6.2-property.py b/tests/internal_bench/class_create-6.2-property.py new file mode 100644 index 00000000000..cf847b6dc9c --- /dev/null +++ b/tests/internal_bench/class_create-6.2-property.py @@ -0,0 +1,13 @@ +import bench + + +def test(num): + for i in range(num // 40): + + class X: + @property + def x(self): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-6.3-descriptor.py b/tests/internal_bench/class_create-6.3-descriptor.py new file mode 100644 index 00000000000..7b0a6357263 --- /dev/null +++ b/tests/internal_bench/class_create-6.3-descriptor.py @@ -0,0 +1,17 @@ +import bench + + +class D: + def __get__(self, instance, owner=None): + pass + + +def test(num): + descriptor = D() + for i in range(num // 40): + + class X: + x = descriptor + + +bench.run(test) diff --git a/tests/internal_bench/class_create-7-inherit.py b/tests/internal_bench/class_create-7-inherit.py new file mode 100644 index 00000000000..f48fb215e0a --- /dev/null +++ b/tests/internal_bench/class_create-7-inherit.py @@ -0,0 +1,14 @@ +import bench + + +def test(num): + class B: + pass + + for i in range(num // 40): + + class X(B): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-7.1-inherit_initsubclass.py b/tests/internal_bench/class_create-7.1-inherit_initsubclass.py new file mode 100644 index 00000000000..0660fa86258 --- /dev/null +++ b/tests/internal_bench/class_create-7.1-inherit_initsubclass.py @@ -0,0 +1,16 @@ +import bench + + +def test(num): + class B: + @classmethod + def __init_subclass__(cls): + pass + + for i in range(num // 40): + + class X(B): + pass + + +bench.run(test) diff --git a/tests/internal_bench/class_create-8-metaclass_setname.py b/tests/internal_bench/class_create-8-metaclass_setname.py new file mode 100644 index 00000000000..e4515b54279 --- /dev/null +++ b/tests/internal_bench/class_create-8-metaclass_setname.py @@ -0,0 +1,17 @@ +import bench + + +class D: + def __set_name__(self, owner, name): + pass + + +def test(num): + descriptor = D() + for i in range(num // 40): + + class X: + x = descriptor + + +bench.run(test) diff --git a/tests/internal_bench/class_create-8.1-metaclass_setname5.py b/tests/internal_bench/class_create-8.1-metaclass_setname5.py new file mode 100644 index 00000000000..5daa3f8471b --- /dev/null +++ b/tests/internal_bench/class_create-8.1-metaclass_setname5.py @@ -0,0 +1,21 @@ +import bench + + +class D: + def __set_name__(self, owner, name): + pass + + +def test(num): + descriptor = D() + for i in range(num // 40): + + class X: + a = descriptor + b = descriptor + c = descriptor + d = descriptor + x = descriptor + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-0-object.py b/tests/internal_bench/class_instance-0-object.py new file mode 100644 index 00000000000..401c8ea7e3c --- /dev/null +++ b/tests/internal_bench/class_instance-0-object.py @@ -0,0 +1,11 @@ +import bench + +X = object + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-0.1-object-gc.py b/tests/internal_bench/class_instance-0.1-object-gc.py new file mode 100644 index 00000000000..7c475963a8e --- /dev/null +++ b/tests/internal_bench/class_instance-0.1-object-gc.py @@ -0,0 +1,13 @@ +import bench +import gc + +X = object + + +def test(num): + for i in range(num // 5): + x = X() + gc.collect() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-1-empty.py b/tests/internal_bench/class_instance-1-empty.py new file mode 100644 index 00000000000..617d47a86e9 --- /dev/null +++ b/tests/internal_bench/class_instance-1-empty.py @@ -0,0 +1,13 @@ +import bench + + +class X: + pass + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-1.1-classattr.py b/tests/internal_bench/class_instance-1.1-classattr.py new file mode 100644 index 00000000000..4e667533d4a --- /dev/null +++ b/tests/internal_bench/class_instance-1.1-classattr.py @@ -0,0 +1,13 @@ +import bench + + +class X: + x = 0 + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-1.2-func.py b/tests/internal_bench/class_instance-1.2-func.py new file mode 100644 index 00000000000..21bf7a1ac48 --- /dev/null +++ b/tests/internal_bench/class_instance-1.2-func.py @@ -0,0 +1,14 @@ +import bench + + +class X: + def f(self): + pass + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-1.3-empty-gc.py b/tests/internal_bench/class_instance-1.3-empty-gc.py new file mode 100644 index 00000000000..a5108ef8e81 --- /dev/null +++ b/tests/internal_bench/class_instance-1.3-empty-gc.py @@ -0,0 +1,15 @@ +import bench +import gc + + +class X: + pass + + +def test(num): + for i in range(num // 5): + x = X() + gc.collect() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-2-init.py b/tests/internal_bench/class_instance-2-init.py new file mode 100644 index 00000000000..86619d31548 --- /dev/null +++ b/tests/internal_bench/class_instance-2-init.py @@ -0,0 +1,14 @@ +import bench + + +class X: + def __init__(self): + pass + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-2.1-init_super.py b/tests/internal_bench/class_instance-2.1-init_super.py new file mode 100644 index 00000000000..38bca5fef87 --- /dev/null +++ b/tests/internal_bench/class_instance-2.1-init_super.py @@ -0,0 +1,14 @@ +import bench + + +class X: + def __init__(self): + return super().__init__() + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-2.2-new.py b/tests/internal_bench/class_instance-2.2-new.py new file mode 100644 index 00000000000..dc5e78ea5ef --- /dev/null +++ b/tests/internal_bench/class_instance-2.2-new.py @@ -0,0 +1,14 @@ +import bench + + +class X: + def __new__(cls): + return super().__new__(cls) + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-3-del.py b/tests/internal_bench/class_instance-3-del.py new file mode 100644 index 00000000000..af700f72a94 --- /dev/null +++ b/tests/internal_bench/class_instance-3-del.py @@ -0,0 +1,14 @@ +import bench + + +class X: + def __del__(self): + pass + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-3.1-del-gc.py b/tests/internal_bench/class_instance-3.1-del-gc.py new file mode 100644 index 00000000000..311c71c3571 --- /dev/null +++ b/tests/internal_bench/class_instance-3.1-del-gc.py @@ -0,0 +1,16 @@ +import bench +import gc + + +class X: + def __del__(self): + pass + + +def test(num): + for i in range(num // 5): + x = X() + gc.collect() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-4-slots.py b/tests/internal_bench/class_instance-4-slots.py new file mode 100644 index 00000000000..51b067fedf0 --- /dev/null +++ b/tests/internal_bench/class_instance-4-slots.py @@ -0,0 +1,13 @@ +import bench + + +class X: + __slots__ = ["x"] + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/class_instance-4.1-slots5.py b/tests/internal_bench/class_instance-4.1-slots5.py new file mode 100644 index 00000000000..8f5c2ecb456 --- /dev/null +++ b/tests/internal_bench/class_instance-4.1-slots5.py @@ -0,0 +1,13 @@ +import bench + + +class X: + __slots__ = ["a", "b", "c", "d", "x"] + + +def test(num): + for i in range(num // 5): + x = X() + + +bench.run(test) diff --git a/tests/internal_bench/var-6.2-instance-speciallookup.py b/tests/internal_bench/var-6.2-instance-speciallookup.py new file mode 100644 index 00000000000..fee12b2f930 --- /dev/null +++ b/tests/internal_bench/var-6.2-instance-speciallookup.py @@ -0,0 +1,19 @@ +import bench + + +class Foo: + def __init__(self): + self.num = 20000000 + + def __delattr__(self, name): # just trigger the 'special lookups' flag on the class + pass + + +def test(num): + o = Foo() + i = 0 + while i < o.num: + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-6.3-instance-property.py b/tests/internal_bench/var-6.3-instance-property.py new file mode 100644 index 00000000000..b4426ef7928 --- /dev/null +++ b/tests/internal_bench/var-6.3-instance-property.py @@ -0,0 +1,17 @@ +import bench + + +class Foo: + @property + def num(self): + return 20000000 + + +def test(num): + o = Foo() + i = 0 + while i < o.num: + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-6.4-instance-descriptor.py b/tests/internal_bench/var-6.4-instance-descriptor.py new file mode 100644 index 00000000000..b4df69f878f --- /dev/null +++ b/tests/internal_bench/var-6.4-instance-descriptor.py @@ -0,0 +1,20 @@ +import bench + + +class Descriptor: + def __get__(self, instance, owner=None): + return 20000000 + + +class Foo: + num = Descriptor() + + +def test(num): + o = Foo() + i = 0 + while i < o.num: + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-6.5-instance-getattr.py b/tests/internal_bench/var-6.5-instance-getattr.py new file mode 100644 index 00000000000..3b2ef672110 --- /dev/null +++ b/tests/internal_bench/var-6.5-instance-getattr.py @@ -0,0 +1,16 @@ +import bench + + +class Foo: + def __getattr__(self, name): + return 20000000 + + +def test(num): + o = Foo() + i = 0 + while i < o.num: + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-6.6-instance-builtin_ordered.py b/tests/internal_bench/var-6.6-instance-builtin_ordered.py new file mode 100644 index 00000000000..02d75252301 --- /dev/null +++ b/tests/internal_bench/var-6.6-instance-builtin_ordered.py @@ -0,0 +1,12 @@ +import bench + + +def test(num): + i = 0 + o = set() # object with largest rom-frozen ordered locals_dict + n = "__contains__" # last element in that dict for longest lookup + while i < num: + i += hasattr(o, n) # True, converts to 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-9-getattr.py b/tests/internal_bench/var-9-getattr.py new file mode 100644 index 00000000000..69d2bfed2e0 --- /dev/null +++ b/tests/internal_bench/var-9-getattr.py @@ -0,0 +1,16 @@ +import bench + + +class Foo: + pass + + +def test(num): + o = Foo() + o.num = num + i = 0 + while i < getattr(o, "num", num): + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-9.1-getattr_default.py b/tests/internal_bench/var-9.1-getattr_default.py new file mode 100644 index 00000000000..e803d39b326 --- /dev/null +++ b/tests/internal_bench/var-9.1-getattr_default.py @@ -0,0 +1,15 @@ +import bench + + +class Foo: + pass + + +def test(num): + o = Foo() + i = 0 + while i < getattr(o, "num", num): + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-9.2-getattr_default_special.py b/tests/internal_bench/var-9.2-getattr_default_special.py new file mode 100644 index 00000000000..c48ec0742cf --- /dev/null +++ b/tests/internal_bench/var-9.2-getattr_default_special.py @@ -0,0 +1,16 @@ +import bench + + +class Foo: + def __delattr__(self, name): # just trigger the 'special lookups' flag on the class + pass + + +def test(num): + o = Foo() + i = 0 + while i < getattr(o, "num", num): + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-9.3-except_ok.py b/tests/internal_bench/var-9.3-except_ok.py new file mode 100644 index 00000000000..efc1a8f858c --- /dev/null +++ b/tests/internal_bench/var-9.3-except_ok.py @@ -0,0 +1,23 @@ +import bench + + +class Foo: + pass + + +def test(num): + o = Foo() + o.num = num + + def get(): + try: + return o.num + except AttributeError: + return num + + i = 0 + while i < get(): + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-9.4-except_selfinduced.py b/tests/internal_bench/var-9.4-except_selfinduced.py new file mode 100644 index 00000000000..544609ca4b6 --- /dev/null +++ b/tests/internal_bench/var-9.4-except_selfinduced.py @@ -0,0 +1,22 @@ +import bench + + +class Foo: + pass + + +def test(num): + o = Foo() + + def get(): + try: + raise AttributeError + except AttributeError: + return num + + i = 0 + while i < get(): + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-9.5-except_error.py b/tests/internal_bench/var-9.5-except_error.py new file mode 100644 index 00000000000..caf83fa46ab --- /dev/null +++ b/tests/internal_bench/var-9.5-except_error.py @@ -0,0 +1,22 @@ +import bench + + +class Foo: + pass + + +def test(num): + o = Foo() + + def get(): + try: + return o.num + except AttributeError: + return num + + i = 0 + while i < get(): + i += 1 + + +bench.run(test) diff --git a/tests/internal_bench/var-9.6-except_error_special.py b/tests/internal_bench/var-9.6-except_error_special.py new file mode 100644 index 00000000000..8bc395b4d7e --- /dev/null +++ b/tests/internal_bench/var-9.6-except_error_special.py @@ -0,0 +1,23 @@ +import bench + + +class Foo: + def __delattr__(self, name): # just trigger the 'special lookups' flag on the class + pass + + +def test(num): + o = Foo() + + def get(): + try: + return o.num + except AttributeError: + return num + + i = 0 + while i < get(): + i += 1 + + +bench.run(test) diff --git a/tests/io/builtin_print_file.py b/tests/io/builtin_print_file.py index 822356a6cc3..e00f58635a9 100644 --- a/tests/io/builtin_print_file.py +++ b/tests/io/builtin_print_file.py @@ -13,5 +13,5 @@ try: print(file=1) -except (AttributeError, OSError): # CPython and uPy differ in error message +except (AttributeError, OSError): # CPython and MicroPython differ in error message print("Error") diff --git a/tests/io/file_seek.py b/tests/io/file_seek.py index 3990df84090..b9f9593786f 100644 --- a/tests/io/file_seek.py +++ b/tests/io/file_seek.py @@ -30,5 +30,5 @@ try: f.seek(1) except (OSError, ValueError): - # CPy raises ValueError, uPy raises OSError + # CPy raises ValueError, MPy raises OSError print("OSError or ValueError") diff --git a/tests/micropython/builtin_execfile.py b/tests/micropython/builtin_execfile.py index a905521c662..4fd4d66d4ee 100644 --- a/tests/micropython/builtin_execfile.py +++ b/tests/micropython/builtin_execfile.py @@ -16,7 +16,9 @@ def __init__(self, data): self.off = 0 def ioctl(self, request, arg): - return 0 + if request == 4: # MP_STREAM_CLOSE + return 0 + return -1 def readinto(self, buf): buf[:] = memoryview(self.data)[self.off : self.off + len(buf)] @@ -73,3 +75,24 @@ def open(self, file, mode): # Unmount the VFS object. vfs.umount(fs) + + +class EvilFilesystem: + def mount(self, readonly, mkfs): + print("mount", readonly, mkfs) + + def umount(self): + print("umount") + + def open(self, file, mode): + return None + + +fs = EvilFilesystem() +vfs.mount(fs, "/test_mnt") +try: + execfile("/test_mnt/test.py") + print("ExecFile succeeded") +except OSError: + print("OSError") +vfs.umount(fs) diff --git a/tests/micropython/builtin_execfile.py.exp b/tests/micropython/builtin_execfile.py.exp index 49703d57076..d93dee547b6 100644 --- a/tests/micropython/builtin_execfile.py.exp +++ b/tests/micropython/builtin_execfile.py.exp @@ -5,3 +5,6 @@ open /test.py rb 123 TypeError umount +mount False False +OSError +umount diff --git a/tests/micropython/const_error.py b/tests/micropython/const_error.py index d35be530a7c..950360e4dc7 100644 --- a/tests/micropython/const_error.py +++ b/tests/micropython/const_error.py @@ -18,8 +18,6 @@ def test_syntax(code): # these operations are not supported within const test_syntax("A = const(1 @ 2)") -test_syntax("A = const(1 / 2)") -test_syntax("A = const(1 ** -2)") test_syntax("A = const(1 << -2)") test_syntax("A = const(1 >> -2)") test_syntax("A = const(1 % 0)") diff --git a/tests/micropython/const_error.py.exp b/tests/micropython/const_error.py.exp index 3edc3efe9c3..bef69eb32ea 100644 --- a/tests/micropython/const_error.py.exp +++ b/tests/micropython/const_error.py.exp @@ -5,5 +5,3 @@ SyntaxError SyntaxError SyntaxError SyntaxError -SyntaxError -SyntaxError diff --git a/tests/micropython/const_float.py b/tests/micropython/const_float.py new file mode 100644 index 00000000000..c3a0df0276b --- /dev/null +++ b/tests/micropython/const_float.py @@ -0,0 +1,23 @@ +# test constant optimisation, with consts that are floats + +from micropython import const + +# check we can make consts from floats +F1 = const(2.5) +F2 = const(-0.3) +print(type(F1), F1) +print(type(F2), F2) + +# check arithmetic with floats +F3 = const(F1 + F2) +F4 = const(F1**2) +print(F3, F4) + +# check int operations with float results +F5 = const(1 / 2) +F6 = const(2**-2) +print(F5, F6) + +# note: we also test float expression folding when +# we're compiling test cases in tests/float, as +# many expressions are resolved at compile time. diff --git a/tests/micropython/const_float.py.exp b/tests/micropython/const_float.py.exp new file mode 100644 index 00000000000..17a86a6d936 --- /dev/null +++ b/tests/micropython/const_float.py.exp @@ -0,0 +1,4 @@ + 2.5 + -0.3 +2.2 6.25 +0.5 0.25 diff --git a/tests/micropython/const_math.py b/tests/micropython/const_math.py new file mode 100644 index 00000000000..7ee5edc6d32 --- /dev/null +++ b/tests/micropython/const_math.py @@ -0,0 +1,18 @@ +# Test expressions based on math module constants +try: + import math +except ImportError: + print("SKIP") + raise SystemExit + +from micropython import const + +# check that we can make consts from math constants +# (skip if the target has MICROPY_COMP_MODULE_CONST disabled) +try: + exec("two_pi = const(2.0 * math.pi)") +except SyntaxError: + print("SKIP") + raise SystemExit + +print(math.cos(two_pi)) diff --git a/tests/micropython/const_math.py.exp b/tests/micropython/const_math.py.exp new file mode 100644 index 00000000000..d3827e75a5c --- /dev/null +++ b/tests/micropython/const_math.py.exp @@ -0,0 +1 @@ +1.0 diff --git a/tests/micropython/decorator_error.py b/tests/micropython/decorator_error.py index 94772ac1e5f..b5eae65b292 100644 --- a/tests/micropython/decorator_error.py +++ b/tests/micropython/decorator_error.py @@ -1,4 +1,4 @@ -# test syntax errors for uPy-specific decorators +# test syntax errors for MicroPython-specific decorators def test_syntax(code): diff --git a/tests/micropython/emg_exc.py b/tests/micropython/emg_exc.py index a74757d028f..cf918b3dc8a 100644 --- a/tests/micropython/emg_exc.py +++ b/tests/micropython/emg_exc.py @@ -1,10 +1,9 @@ # test that emergency exceptions work -import micropython import sys try: - import io + import io, micropython except ImportError: print("SKIP") raise SystemExit diff --git a/tests/micropython/emg_exc.py.native.exp b/tests/micropython/emg_exc.py.native.exp new file mode 100644 index 00000000000..879fa7ef5b9 --- /dev/null +++ b/tests/micropython/emg_exc.py.native.exp @@ -0,0 +1 @@ +ValueError(1,) diff --git a/tests/micropython/extreme_exc.py b/tests/micropython/extreme_exc.py index ad819e408fd..17323b566d3 100644 --- a/tests/micropython/extreme_exc.py +++ b/tests/micropython/extreme_exc.py @@ -1,6 +1,10 @@ # test some extreme cases of allocating exceptions and tracebacks -import micropython +try: + import micropython +except ImportError: + print("SKIP") + raise SystemExit # Check for stackless build, which can't call functions without # allocating a frame on the heap. diff --git a/tests/micropython/heap_lock.py b/tests/micropython/heap_lock.py index f2892a6dc58..209a3143461 100644 --- a/tests/micropython/heap_lock.py +++ b/tests/micropython/heap_lock.py @@ -1,6 +1,10 @@ # check that heap_lock/heap_unlock work as expected -import micropython +try: + import micropython +except ImportError: + print("SKIP") + raise SystemExit l = [] l2 = list(range(100)) diff --git a/tests/micropython/heap_locked.py b/tests/micropython/heap_locked.py index d9e5b5d4090..d9d99493dd6 100644 --- a/tests/micropython/heap_locked.py +++ b/tests/micropython/heap_locked.py @@ -1,8 +1,10 @@ # test micropython.heap_locked() -import micropython +try: + import micropython -if not hasattr(micropython, "heap_locked"): + micropython.heap_locked +except (AttributeError, ImportError): print("SKIP") raise SystemExit diff --git a/tests/micropython/heapalloc.py b/tests/micropython/heapalloc.py index e19f8d0255d..010bf878a07 100644 --- a/tests/micropython/heapalloc.py +++ b/tests/micropython/heapalloc.py @@ -1,6 +1,10 @@ # check that we can do certain things without allocating heap memory -import micropython +try: + import micropython +except ImportError: + print("SKIP") + raise SystemExit # Check for stackless build, which can't call functions without # allocating a frame on heap. diff --git a/tests/micropython/heapalloc_exc_compressed.py b/tests/micropython/heapalloc_exc_compressed.py index cddc0f7b409..96fe3ca4f7e 100644 --- a/tests/micropython/heapalloc_exc_compressed.py +++ b/tests/micropython/heapalloc_exc_compressed.py @@ -1,10 +1,16 @@ -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit # Tests both code paths for built-in exception raising. # mp_obj_new_exception_msg_varg (exception requires decompression at raise-time to format) # mp_obj_new_exception_msg (decompression can be deferred) -# NameError uses mp_obj_new_exception_msg_varg for NameError("name '%q' is not defined") +# NameError uses mp_obj_new_exception_msg_varg for NameError("name '%q' isn't defined") # `raise 0` uses mp_obj_new_exception_msg for TypeError("exceptions must derive from BaseException") # Tests that deferred decompression works both via print(e) and accessing the message directly via e.args. diff --git a/tests/micropython/heapalloc_exc_compressed.py.exp b/tests/micropython/heapalloc_exc_compressed.py.exp index c2690353b07..c3e6e5dd9f7 100644 --- a/tests/micropython/heapalloc_exc_compressed.py.exp +++ b/tests/micropython/heapalloc_exc_compressed.py.exp @@ -1,6 +1,6 @@ -NameError name 'name' is not defined +NameError name 'name' isn't defined TypeError exceptions must derive from BaseException -name 'name' is not defined +name 'name' isn't defined exceptions must derive from BaseException NameError TypeError diff --git a/tests/micropython/heapalloc_exc_compressed_emg_exc.py b/tests/micropython/heapalloc_exc_compressed_emg_exc.py index 48ce9dd69e6..31d937b8f93 100644 --- a/tests/micropython/heapalloc_exc_compressed_emg_exc.py +++ b/tests/micropython/heapalloc_exc_compressed_emg_exc.py @@ -1,4 +1,10 @@ -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit # Does the full test from heapalloc_exc_compressed.py but while the heap is # locked (this can only work when the emergency exception buf is enabled). diff --git a/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp b/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp index c3974250d4e..1fc81093392 100644 --- a/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp +++ b/tests/micropython/heapalloc_exc_compressed_emg_exc.py.exp @@ -1,4 +1,4 @@ -NameError name 'name' is not defined +NameError name 'name' isn't defined TypeError exceptions must derive from BaseException -name 'name' is not defined +name 'name' isn't defined exceptions must derive from BaseException diff --git a/tests/micropython/heapalloc_exc_raise.py b/tests/micropython/heapalloc_exc_raise.py index 99810e00750..917ccf42f1e 100644 --- a/tests/micropython/heapalloc_exc_raise.py +++ b/tests/micropython/heapalloc_exc_raise.py @@ -1,6 +1,12 @@ # Test that we can raise and catch (preallocated) exception # without memory allocation. -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit e = ValueError("error") diff --git a/tests/micropython/heapalloc_fail_bytearray.py b/tests/micropython/heapalloc_fail_bytearray.py index 1bf7ddd600b..9ee73d1c583 100644 --- a/tests/micropython/heapalloc_fail_bytearray.py +++ b/tests/micropython/heapalloc_fail_bytearray.py @@ -1,6 +1,12 @@ # test handling of failed heap allocation with bytearray -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit class GetSlice: diff --git a/tests/micropython/heapalloc_fail_dict.py b/tests/micropython/heapalloc_fail_dict.py index ce2d158bd09..04c79183578 100644 --- a/tests/micropython/heapalloc_fail_dict.py +++ b/tests/micropython/heapalloc_fail_dict.py @@ -1,6 +1,12 @@ # test handling of failed heap allocation with dict -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit # create dict x = 1 diff --git a/tests/micropython/heapalloc_fail_list.py b/tests/micropython/heapalloc_fail_list.py index 9a2e9a555f3..7afb6dc1019 100644 --- a/tests/micropython/heapalloc_fail_list.py +++ b/tests/micropython/heapalloc_fail_list.py @@ -1,6 +1,12 @@ # test handling of failed heap allocation with list -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit class GetSlice: diff --git a/tests/micropython/heapalloc_fail_memoryview.py b/tests/micropython/heapalloc_fail_memoryview.py index da2d1abffa6..17e3e126247 100644 --- a/tests/micropython/heapalloc_fail_memoryview.py +++ b/tests/micropython/heapalloc_fail_memoryview.py @@ -1,6 +1,12 @@ # test handling of failed heap allocation with memoryview -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit class GetSlice: diff --git a/tests/micropython/heapalloc_fail_set.py b/tests/micropython/heapalloc_fail_set.py index 3c347660ad7..0c4d85eef62 100644 --- a/tests/micropython/heapalloc_fail_set.py +++ b/tests/micropython/heapalloc_fail_set.py @@ -1,6 +1,12 @@ # test handling of failed heap allocation with set -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit # create set x = 1 diff --git a/tests/micropython/heapalloc_fail_tuple.py b/tests/micropython/heapalloc_fail_tuple.py index de79385e3e3..11718a8107b 100644 --- a/tests/micropython/heapalloc_fail_tuple.py +++ b/tests/micropython/heapalloc_fail_tuple.py @@ -1,6 +1,12 @@ # test handling of failed heap allocation with tuple -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit # create tuple x = 1 diff --git a/tests/micropython/heapalloc_inst_call.py b/tests/micropython/heapalloc_inst_call.py index 14d8826bf06..f78aa3cf877 100644 --- a/tests/micropython/heapalloc_inst_call.py +++ b/tests/micropython/heapalloc_inst_call.py @@ -1,6 +1,13 @@ # Test that calling clazz.__call__() with up to at least 3 arguments # doesn't require heap allocation. -import micropython + +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit class Foo0: diff --git a/tests/micropython/heapalloc_int_from_bytes.py b/tests/micropython/heapalloc_int_from_bytes.py index 5fe50443ae3..3310ea95d14 100644 --- a/tests/micropython/heapalloc_int_from_bytes.py +++ b/tests/micropython/heapalloc_int_from_bytes.py @@ -1,6 +1,13 @@ # Test that int.from_bytes() for small number of bytes generates # small int. -import micropython + +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit micropython.heap_lock() print(int.from_bytes(b"1", "little")) diff --git a/tests/micropython/heapalloc_slice.py b/tests/micropython/heapalloc_slice.py new file mode 100644 index 00000000000..62d96595c71 --- /dev/null +++ b/tests/micropython/heapalloc_slice.py @@ -0,0 +1,18 @@ +# slice operations that don't require allocation +try: + from micropython import heap_lock, heap_unlock +except (ImportError, AttributeError): + heap_lock = heap_unlock = lambda: 0 + +b = bytearray(range(10)) + +m = memoryview(b) + +heap_lock() + +b[3:5] = b"aa" +m[5:7] = b"bb" + +heap_unlock() + +print(b) diff --git a/tests/micropython/heapalloc_str.py b/tests/micropython/heapalloc_str.py index 39aa56ccd78..6372df5d37b 100644 --- a/tests/micropython/heapalloc_str.py +++ b/tests/micropython/heapalloc_str.py @@ -1,5 +1,12 @@ # String operations which don't require allocation -import micropython + +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit micropython.heap_lock() diff --git a/tests/micropython/heapalloc_super.py b/tests/micropython/heapalloc_super.py index 51afae3d83d..6839eee330a 100644 --- a/tests/micropython/heapalloc_super.py +++ b/tests/micropython/heapalloc_super.py @@ -1,5 +1,12 @@ # test super() operations which don't require allocation -import micropython + +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit # Check for stackless build, which can't call functions without # allocating a frame on heap. diff --git a/tests/micropython/heapalloc_traceback.py.native.exp b/tests/micropython/heapalloc_traceback.py.native.exp new file mode 100644 index 00000000000..d6ac26aa829 --- /dev/null +++ b/tests/micropython/heapalloc_traceback.py.native.exp @@ -0,0 +1,3 @@ +StopIteration +StopIteration: + diff --git a/tests/micropython/heapalloc_yield_from.py b/tests/micropython/heapalloc_yield_from.py index 95071718908..9d4f8c6940f 100644 --- a/tests/micropython/heapalloc_yield_from.py +++ b/tests/micropython/heapalloc_yield_from.py @@ -1,6 +1,12 @@ # Check that yield-from can work without heap allocation -import micropython +try: + import micropython + + micropython.heap_lock +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit # Yielding from a function generator diff --git a/tests/micropython/import_mpy_invalid.py b/tests/micropython/import_mpy_invalid.py index 499c0d447d4..8c11b39c076 100644 --- a/tests/micropython/import_mpy_invalid.py +++ b/tests/micropython/import_mpy_invalid.py @@ -26,7 +26,9 @@ def readinto(self, buf): return n def ioctl(self, req, arg): - return 0 + if req == 4: # MP_STREAM_CLOSE + return 0 + return -1 class UserFS: diff --git a/tests/micropython/import_mpy_native.py b/tests/micropython/import_mpy_native.py index c6a682f7b1e..59181b203bb 100644 --- a/tests/micropython/import_mpy_native.py +++ b/tests/micropython/import_mpy_native.py @@ -28,7 +28,9 @@ def readinto(self, buf): return n def ioctl(self, req, arg): - return 0 + if req == 4: # MP_STREAM_CLOSE + return 0 + return -1 class UserFS: @@ -52,12 +54,13 @@ def open(self, path, mode): # these are the test .mpy files # CIRCUITPY-CHANGE -valid_header = bytes([ord("C"), 6, mpy_arch, 31]) +small_int_bits = 31 +valid_header = bytes([77, 6, (mpy_arch & 0x3F), small_int_bits]) # fmt: off user_files = { # bad architecture (mpy_arch needed for sub-version) # CIRCUITPY-CHANGE - '/mod0.mpy': bytes([ord('C'), 6, 0xfc | mpy_arch, 31]), + '/mod0.mpy': bytes([ord('C'), 6, 0xfc | (mpy_arch & 3), small_int_bits]), # test loading of viper and asm '/mod1.mpy': valid_header + ( diff --git a/tests/micropython/import_mpy_native_gc.py b/tests/micropython/import_mpy_native_gc.py index 1901dc669a3..5159cc9e9f9 100644 --- a/tests/micropython/import_mpy_native_gc.py +++ b/tests/micropython/import_mpy_native_gc.py @@ -1,4 +1,4 @@ -# Test that native code loaded from a .mpy file is retained after a GC. +# Test that native text/BSS/rodata loaded from a .mpy file is retained after a GC. try: import gc, sys, io, vfs @@ -22,7 +22,9 @@ def readinto(self, buf): return n def ioctl(self, req, arg): - return 0 + if req == 4: # MP_STREAM_CLOSE + return 0 + return -1 class UserFS: @@ -44,19 +46,24 @@ def open(self, path, mode): return UserFile(self.files[path]) -# Pre-compiled examples/natmod/features0 example for various architectures, keyed +# Pre-compiled import_mpy_native_gc_module example for various architectures, keyed # by the required value of sys.implementation._mpy (without sub-version). -# cd examples/natmod/features0 -# make clean -# make ARCH=x64 # or ARCH=armv6m -# cat features0.mpy | python -c 'import sys; print(sys.stdin.buffer.read())' +# To rebuild: +# $ cd import_mpy_native_gc_module +# $ make clean +# $ make ARCH=x64 # or ARCH=armv6m or ARCH=xtensawin +# Then copy the bytes object printed on the last line. + # CIRCUITPY-CHANGE: 'C' instead of 'M' mpy marker. features0_file_contents = { # -march=x64 - 0x806: b'C\x06\n\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x8a\x02\xe93\x00\x00\x00\xf3\x0f\x1e\xfaSH\x8b\x1d\x7f\x00\x00\x00\xbe\x02\x00\x00\x00\xffS\x18\xbf\x01\x00\x00\x00H\x85\xc0u\x0cH\x8bC \xbe\x02\x00\x00\x00[\xff\xe0H\x0f\xaf\xf8H\xff\xc8\xeb\xe6\xf3\x0f\x1e\xfaATUSH\x8b\x1dI\x00\x00\x00H\x8bG\x08L\x8bc(H\x8bx\x08A\xff\xd4H\x8d5#\x00\x00\x00H\x89\xc5H\x8b\x051\x00\x00\x00\x0f\xb7x\x02\xffShH\x89\xefA\xff\xd4H\x8b\x03[]A\\\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x11$\r&\xa5 \x01"\xff', + 0x806: b"C\x06\x0b\x1f\x03\x002build/test_x64.native.mpy\x00\x08add1\x00\x0cunused\x00\x91B\xe9I\x00\x00\x00H\x8b\x05\xf4\x00\x00\x00H\x8b\x00\xc3H\x8b\x05\xf9\x00\x00\x00\xbe\x02\x00\x00\x00\x8b8H\x8b\x05\xdb\x00\x00\x00H\x8b@ \xff\xe0H\x8b\x05\xce\x00\x00\x00S\xbe\x02\x00\x00\x00H\x8bX \xffP\x18\xbe\x02\x00\x00\x00H\x8dx\x01H\x89\xd8[\xff\xe0AVAUATUSH\x8b\x1d\xa3\x00\x00\x00H\x8bG\x08L\x8bk(H\x8bx\x08A\xff\xd5L\x8b5\x95\x00\x00\x00L\x8bchH\x8d5r\x00\x00\x00H\x89\xc5H\x8b\x05\x88\x00\x00\x00A\x0f\xb7~\x04\xc7\x00@\xe2\x01\x00A\xff\xd4H\x8d5C\x00\x00\x00\xbfV\x00\x00\x00A\xff\xd4A\x0f\xb7~\x02H\x8d5\x1f\x00\x00\x00A\xff\xd4H\x89\xefA\xff\xd5H\x8b\x03[]A\\A]A^\xc3\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x04\x11@\rB\tD\xaf4\x016\xad8\x01:\xaf<\x01>\xff", # -march=armv6m - 0x1006: b'C\x06\x12\x1f\x02\x004build/features0.native.mpy\x00\x12factorial\x00\x88\x02\x18\xe0\x00\x00\x10\xb5\tK\tJ{D\x9cX\x02!\xe3h\x98G\x03\x00\x01 \x00+\x02\xd0XC\x01;\xfa\xe7\x02!#i\x98G\x10\xbd\xc0Fj\x00\x00\x00\x00\x00\x00\x00\xf8\xb5\nN\nK~D\xf4XChgiXh\xb8G\x05\x00\x07K\x08I\xf3XyDX\x88ck\x98G(\x00\xb8G h\xf8\xbd\xc0F:\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x11<\r>\xa58\x01:\xff' -, + 0x1006: b"C\x06\x13\x1f\x03\x008build/test_armv6m.native.mpy\x00\x08add1\x00\x0cunused\x00\x8eb0\xe0\x00\x00\x00\x00\x00\x00\x02K\x03J{D\x9bX\x18hpG\xd0\x00\x00\x00\x00\x00\x00\x00\x10\xb5\x05K\x05I\x06J{D\x9aX[X\x10h\x02!\x1bi\x98G\x10\xbd\xb8\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x10\xb5\x06K\x06J{D\x9bX\x02!\x1ci\xdbh\x98G\x02!\x010\xa0G\x10\xbd\xc0F\x96\x00\x00\x00\x00\x00\x00\x00\xf7\xb5\x12O\x12K\x7fD\xfdX\x12Lki|D\x00\x93ChXh\x00\x9b\x98G\x0fK\x01\x90\x0fJ\xfbXnk\x1a`\x0eK!\x00\xffX\xb8\x88\xb0G!\x00V \x081\xb0G!\x00x\x88\x101\xb0G\x01\x98\x00\x9b\x98G(h\xfe\xbd\xc0Fr\x00\x00\x00\x00\x00\x00\x00R\x00\x00\x00\x08\x00\x00\x00@\xe2\x01\x00\x04\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00A\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x04\x11p\rr\tt\xafd\x01f\xadh\x01j\xafl\x01n\xff", + # -march=xtensawin + 0x2806: b"C\x06+\x1f\x03\x00>build/test_xtensawin.native.mpy\x00\x08add1\x00\x0cunused\x00\x8a\x12\x06\x16\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x006A\x00\x81\xf9\xff(\x08\x1d\xf0\x00\x006A\x00\x91\xfb\xff\x81\xf5\xff\xa8\t\x88H\x0c+\xe0\x08\x00-\n\x1d\xf0\x00\x006A\x00\x81\xf0\xff\xad\x02xH\x888\x0c+\xe0\x08\x00\x0c+\x1b\xaa\xe0\x07\x00-\n\x1d\xf06A\x00a\xe9\xff\x88\x122&\x05\xa2(\x01\xe0\x03\x00q\xe6\xff\x81\xea\xff\x92\xa7\x89\xa0\x99\x11H\xd6]\n\xb1\xe3\xff\xa2\x17\x02\x99\x08\xe0\x04\x00\xb1\xe2\xff\\j\xe0\x04\x00\xb1\xe1\xff\xa2\x17\x01\xe0\x04\x00\xad\x05\xe0\x03\x00(\x06\x1d\xf0p\x18\x04\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x11\x02\r\x04\x07\x06\x03\t\x0c\xaf\x01\x01\x03\xad\x05\x01\x07\xaf\t\x01\x0b\xff", + # -march=rv32imc + 0x2C06: b'C\x06/\x1f\x03\x00:build/test_rv32imc.native.mpy\x00\x08add1\x00\x0cunused\x00\x8fb\x97\x0f\x00\x00g\x80\x0f\x05\x97\x07\x00\x00\x83\xa7\x07\x0e\x88C\x82\x80\x97\x07\x00\x00\x83\xa7G\r\x17\x07\x00\x00\x03\'\xc7\r\x9cK\x08C\x89E\x82\x87A\x11\x97\x07\x00\x00\x83\xa7\xa7\x0b"\xc4\x80K\xdcG\x06\xc6\x89E\x82\x97\xa2\x87"D\xb2@\x89E\x05\x05A\x01\x82\x87\\A\x01\x11"\xcc\x17\x04\x00\x00\x03$$\tN\xc6\xc8C\x83)D\x01\x06\xce&\xcaJ\xc8R\xc4\x82\x99\x17\n\x00\x00\x03*\xca\x07\x03)D\x03\xaa\x84\xf9g\x03UJ\x00\x93\x87\x07$\x17\x07\x00\x00\x03\'\x07\x07\x1c\xc3\x97\x05\x00\x00\x93\x85\xe5\x03\x02\x99\x97\x05\x00\x00\x93\x85\xc5\x03\x13\x05`\x05\x02\x99\x03U*\x00\x97\x05\x00\x00\x93\x85%\x03\x02\x99&\x85\x82\x99\x08@\xf2@bD\xd2DBI\xb2I"J\x05a\x82\x80\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00P\x04\x11t\rv\xafx\xadz\t|\xafh\x01j\xadl\x01n\xafp\x01r\xff', } # Populate armv7m-derived archs based on armv6m. @@ -64,7 +71,7 @@ def open(self, path, mode): features0_file_contents[arch] = features0_file_contents[0x1006] # Check that a .mpy exists for the target (ignore sub-version in lookup). -sys_implementation_mpy = sys.implementation._mpy & ~(3 << 8) +sys_implementation_mpy = (sys.implementation._mpy & ~(3 << 8)) & 0xFFFF if sys_implementation_mpy not in features0_file_contents: print("SKIP") raise SystemExit @@ -78,11 +85,24 @@ def open(self, path, mode): # Import the native function. gc.collect() -from features0 import factorial +from features0 import get, add1 + +# Test that the native functions work to begin with. +print(get()) +print(add1(12)) # Free the module that contained the function. del sys.modules["features0"] + +# Sweep the stack to remove any stray pointers that we are aiming to reclaim. +def recurse(n): + if n: + recurse(n - 1) + + +recurse(10) + # Run a GC cycle which should reclaim the module but not the function. gc.collect() @@ -90,8 +110,9 @@ def open(self, path, mode): for i in range(1000): [] -# Run the native function, it should not have been freed or overwritten. -print(factorial(10)) +# Run the native function, its text/BSS/rodata should not have been freed or overwritten. +print(get()) +print(add1(12)) # Unmount and undo path addition. vfs.umount("/userfs") diff --git a/tests/micropython/import_mpy_native_gc.py.exp b/tests/micropython/import_mpy_native_gc.py.exp index 3fbd4a8698f..4250a13c726 100644 --- a/tests/micropython/import_mpy_native_gc.py.exp +++ b/tests/micropython/import_mpy_native_gc.py.exp @@ -1 +1,4 @@ -3628800 +123456 +13 +123456 +13 diff --git a/tests/micropython/kbd_intr.py b/tests/micropython/kbd_intr.py index 81977aaa52f..e1ed7185ef0 100644 --- a/tests/micropython/kbd_intr.py +++ b/tests/micropython/kbd_intr.py @@ -1,10 +1,10 @@ # test the micropython.kbd_intr() function -import micropython - try: + import micropython + micropython.kbd_intr -except AttributeError: +except (ImportError, AttributeError): print("SKIP") raise SystemExit diff --git a/tests/micropython/meminfo.py b/tests/micropython/meminfo.py index 9df341fbb83..f4dd8fdb604 100644 --- a/tests/micropython/meminfo.py +++ b/tests/micropython/meminfo.py @@ -1,12 +1,14 @@ # tests meminfo functions in micropython module -import micropython +try: + import micropython -# these functions are not always available -if not hasattr(micropython, "mem_info"): + micropython.mem_info +except (ImportError, AttributeError): print("SKIP") -else: - micropython.mem_info() - micropython.mem_info(1) - micropython.qstr_info() - micropython.qstr_info(1) + raise SystemExit + +micropython.mem_info() +micropython.mem_info(1) +micropython.qstr_info() +micropython.qstr_info(1) diff --git a/tests/micropython/memstats.py b/tests/micropython/memstats.py index dee3a4ce2f2..0e2e7b1c0b3 100644 --- a/tests/micropython/memstats.py +++ b/tests/micropython/memstats.py @@ -1,17 +1,19 @@ # tests meminfo functions in micropython module -import micropython +try: + import micropython -# these functions are not always available -if not hasattr(micropython, "mem_total"): + micropython.mem_total +except (ImportError, AttributeError): print("SKIP") -else: - t = micropython.mem_total() - c = micropython.mem_current() - p = micropython.mem_peak() + raise SystemExit - l = list(range(10000)) +t = micropython.mem_total() +c = micropython.mem_current() +p = micropython.mem_peak() - print(micropython.mem_total() > t) - print(micropython.mem_current() > c) - print(micropython.mem_peak() > p) +l = list(range(10000)) + +print(micropython.mem_total() > t) +print(micropython.mem_current() > c) +print(micropython.mem_peak() > p) diff --git a/tests/micropython/native_fun_attrs_code.py b/tests/micropython/native_fun_attrs_code.py new file mode 100644 index 00000000000..d277a7b9b26 --- /dev/null +++ b/tests/micropython/native_fun_attrs_code.py @@ -0,0 +1,21 @@ +# Test MicroPython-specific restrictions of function.__code__ attribute. + +try: + (lambda: 0).__code__ +except AttributeError: + print("SKIP") + raise SystemExit + +import micropython + + +@micropython.native +def f_native(): + pass + + +# Can't access __code__ when function is native code. +try: + f_native.__code__ +except AttributeError: + print("AttributeError") diff --git a/tests/micropython/native_fun_attrs_code.py.exp b/tests/micropython/native_fun_attrs_code.py.exp new file mode 100644 index 00000000000..d169edffb4c --- /dev/null +++ b/tests/micropython/native_fun_attrs_code.py.exp @@ -0,0 +1 @@ +AttributeError diff --git a/tests/micropython/native_with.py.exp b/tests/micropython/native_with.py.exp index 6eef7822fba..7e28663f6fc 100644 --- a/tests/micropython/native_with.py.exp +++ b/tests/micropython/native_with.py.exp @@ -5,5 +5,5 @@ __exit__ None None None __init__ __enter__ 1 -__exit__ name 'fail' is not defined None +__exit__ name 'fail' isn't defined None NameError diff --git a/tests/micropython/opt_level.py b/tests/micropython/opt_level.py index dd5493a7a3c..789197d8825 100644 --- a/tests/micropython/opt_level.py +++ b/tests/micropython/opt_level.py @@ -1,4 +1,10 @@ -import micropython as micropython +# test micropython.opt_level() + +try: + import micropython +except ImportError: + print("SKIP") + raise SystemExit # check we can get and set the level micropython.opt_level(0) diff --git a/tests/micropython/opt_level_lineno.py b/tests/micropython/opt_level_lineno.py new file mode 100644 index 00000000000..4ca76625de4 --- /dev/null +++ b/tests/micropython/opt_level_lineno.py @@ -0,0 +1,24 @@ +# test micropython.opt_level() and line numbers + +try: + import micropython +except ImportError: + print("SKIP") + raise SystemExit + +# check that level 3 doesn't store line numbers +# the expected output is that any line is printed as "line 1" +micropython.opt_level(3) + +# force bytecode emitter, because native emitter doesn't store line numbers +exec(""" +@micropython.bytecode +def f(): + try: + xyz + except NameError as er: + # CIRCUITPY-CHANGE: use traceback.print_exception() instead of sys.print_exception() + import traceback + traceback.print_exception(er) +f() +""") diff --git a/tests/micropython/opt_level_lineno.py.exp b/tests/micropython/opt_level_lineno.py.exp new file mode 100644 index 00000000000..b50f0628c81 --- /dev/null +++ b/tests/micropython/opt_level_lineno.py.exp @@ -0,0 +1,3 @@ +Traceback (most recent call last): + File "", line 1, in f +NameError: name 'xyz' isn't defined diff --git a/tests/micropython/ringio_big.py b/tests/micropython/ringio_big.py new file mode 100644 index 00000000000..ddbbae12a63 --- /dev/null +++ b/tests/micropython/ringio_big.py @@ -0,0 +1,29 @@ +# Check that micropython.RingIO works correctly. + +try: + import micropython + + micropython.RingIO +except (ImportError, AttributeError): + print("SKIP") + raise SystemExit + +try: + # The maximum possible size + micropython.RingIO(bytearray(65535)) + micropython.RingIO(65534) + + try: + # Buffer may not be too big + micropython.RingIO(bytearray(65536)) + except ValueError as ex: + print(type(ex)) + + try: + # Size may not be too big + micropython.RingIO(65535) + except ValueError as ex: + print(type(ex)) +except MemoryError: + print("SKIP") + raise SystemExit diff --git a/tests/micropython/ringio_big.py.exp b/tests/micropython/ringio_big.py.exp new file mode 100644 index 00000000000..72af34b3838 --- /dev/null +++ b/tests/micropython/ringio_big.py.exp @@ -0,0 +1,2 @@ + + diff --git a/tests/micropython/schedule.py b/tests/micropython/schedule.py index 6a91459ea3d..f3dd3266126 100644 --- a/tests/micropython/schedule.py +++ b/tests/micropython/schedule.py @@ -1,10 +1,10 @@ # test micropython.schedule() function -import micropython - try: + import micropython + micropython.schedule -except AttributeError: +except (ImportError, AttributeError): print("SKIP") raise SystemExit diff --git a/tests/micropython/stack_use.py b/tests/micropython/stack_use.py index 266885d9d18..5d36fdca2fe 100644 --- a/tests/micropython/stack_use.py +++ b/tests/micropython/stack_use.py @@ -1,7 +1,11 @@ # tests stack_use function in micropython module -import micropython -if not hasattr(micropython, "stack_use"): +try: + import micropython + + micropython.stack_use +except (ImportError, AttributeError): print("SKIP") -else: - print(type(micropython.stack_use())) # output varies + raise SystemExit + +print(type(micropython.stack_use())) # output varies diff --git a/tests/micropython/test_normalize_newlines.py b/tests/micropython/test_normalize_newlines.py new file mode 100644 index 00000000000..f19aaa69a3f --- /dev/null +++ b/tests/micropython/test_normalize_newlines.py @@ -0,0 +1,14 @@ +# Test for normalize_newlines functionality +# This test verifies that test framework handles various newline combinations correctly + +# Note: This is more of an integration test since normalize_newlines is in the test framework +# The actual testing happens when this test is run through run-tests.py + +print("Testing newline handling") +print("Line 1\r\nLine 2") # Windows-style line ending - should be normalized +print("Line 3") # Normal line +print("Line 4") # Normal line +print("Line 5\nLine 6") # Unix-style line ending - already normalized + +# Test that literal \r in strings is preserved +print(repr("test\rstring")) # Should show 'test\rstring' not 'test\nstring' diff --git a/tests/micropython/test_normalize_newlines.py.exp b/tests/micropython/test_normalize_newlines.py.exp new file mode 100644 index 00000000000..c4395468cf1 --- /dev/null +++ b/tests/micropython/test_normalize_newlines.py.exp @@ -0,0 +1,8 @@ +Testing newline handling +Line 1 +Line 2 +Line 3 +Line 4 +Line 5 +Line 6 +'test\rstring' diff --git a/tests/micropython/viper_large_jump.py b/tests/micropython/viper_large_jump.py new file mode 100644 index 00000000000..1c5913dec1e --- /dev/null +++ b/tests/micropython/viper_large_jump.py @@ -0,0 +1,20 @@ +COUNT = 600 + + +try: + code = """ +@micropython.viper +def f() -> int: + x = 0 + while x < 10: +""" + for i in range(COUNT): + code += " x += 1\n" + code += " return x" + exec(code) +except MemoryError: + print("SKIP-TOO-LARGE") + raise SystemExit + + +print(f()) diff --git a/tests/micropython/viper_large_jump.py.exp b/tests/micropython/viper_large_jump.py.exp new file mode 100644 index 00000000000..e9f960cf4ac --- /dev/null +++ b/tests/micropython/viper_large_jump.py.exp @@ -0,0 +1 @@ +600 diff --git a/tests/micropython/viper_ptr16_load_boundary.py b/tests/micropython/viper_ptr16_load_boundary.py new file mode 100644 index 00000000000..0d4c3105b68 --- /dev/null +++ b/tests/micropython/viper_ptr16_load_boundary.py @@ -0,0 +1,39 @@ +# Test boundary conditions for various architectures + +GET_TEMPLATE = """ +@micropython.viper +def get{off}(src: ptr16) -> uint: + return uint(src[{off}]) +print(hex(get{off}(buffer))) +""" + + +BIT_THRESHOLDS = (5, 8, 11, 12) +SIZE = 2 + + +@micropython.viper +def get_index(src: ptr16, i: int) -> int: + return src[i] + + +def data(start, len): + output = bytearray(len) + for idx in range(len): + output[idx] = (start + idx) & 0xFF + return output + + +buffer = bytearray((((1 << max(BIT_THRESHOLDS)) + 1) // 1024) * 1024) +val = 0 +for bit in BIT_THRESHOLDS: + print("---", bit) + pre, idx, post = ((1 << bit) - (2 * SIZE), (1 << bit) - (1 * SIZE), 1 << bit) + buffer[pre:post] = data(val, 3 * SIZE) + val = val + (3 * SIZE) + + pre, idx, post = pre // SIZE, idx // SIZE, post // SIZE + print(hex(get_index(buffer, pre)), hex(get_index(buffer, idx)), hex(get_index(buffer, post))) + exec(GET_TEMPLATE.format(off=pre)) + exec(GET_TEMPLATE.format(off=idx)) + exec(GET_TEMPLATE.format(off=post)) diff --git a/tests/micropython/viper_ptr16_load_boundary.py.exp b/tests/micropython/viper_ptr16_load_boundary.py.exp new file mode 100644 index 00000000000..56f1d322904 --- /dev/null +++ b/tests/micropython/viper_ptr16_load_boundary.py.exp @@ -0,0 +1,20 @@ +--- 5 +0x100 0x302 0x504 +0x100 +0x302 +0x504 +--- 8 +0x706 0x908 0xb0a +0x706 +0x908 +0xb0a +--- 11 +0xd0c 0xf0e 0x1110 +0xd0c +0xf0e +0x1110 +--- 12 +0x1312 0x1514 0x1716 +0x1312 +0x1514 +0x1716 diff --git a/tests/micropython/viper_ptr16_store_boundary.py b/tests/micropython/viper_ptr16_store_boundary.py new file mode 100644 index 00000000000..7c774d4d1ca --- /dev/null +++ b/tests/micropython/viper_ptr16_store_boundary.py @@ -0,0 +1,63 @@ +# Test boundary conditions for various architectures + +SET_TEMPLATE = """ +@micropython.viper +def set{off}(dest: ptr16): + saved = dest + dest[{off}] = {val} + assert int(saved) == int(dest) +""" + +BIT_THRESHOLDS = (5, 8, 11, 12) +SIZE = 2 +MASK = (1 << (8 * SIZE)) - 1 + +next_int = 1 +test_buffer = bytearray(SIZE) + + +def next_value() -> uint: + global next_int + global test_buffer + for index in range(1, SIZE): + test_buffer[index - 1] = test_buffer[index] + test_buffer[SIZE - 1] = next_int + next_int += 1 + output = 0 + for byte in test_buffer: + output = (output << 8) | byte + return output & MASK + + +def get_index(src, i): + return src[i * SIZE] + (src[(i * SIZE) + 1] << 8) + + +@micropython.viper +def set_index(dest: ptr16, i: int, val: uint): + saved = dest + dest[i] = val + assert int(saved) == int(dest) + + +try: + buffer = bytearray((((1 << max(BIT_THRESHOLDS)) // 1024) + 1) * 1024) + + for bit in BIT_THRESHOLDS: + offset = (1 << bit) - (2 * SIZE) + for index in range(0, 3 * SIZE, SIZE): + exec(SET_TEMPLATE.format(off=(offset + index) // SIZE, val=next_value())) +except MemoryError: + print("SKIP-TOO-LARGE") + raise SystemExit + + +for bit in BIT_THRESHOLDS: + print("---", bit) + offset = (1 << bit) - (2 * SIZE) + for index in range(0, 3 * SIZE, SIZE): + globals()["set{}".format((offset + index) // SIZE)](buffer) + print(hex(get_index(buffer, (offset + index) // SIZE))) + for index in range(0, 3 * SIZE, SIZE): + set_index(buffer, (offset + index) // SIZE, next_value()) + print(hex(get_index(buffer, (offset + index) // SIZE))) diff --git a/tests/micropython/viper_ptr16_store_boundary.py.exp b/tests/micropython/viper_ptr16_store_boundary.py.exp new file mode 100644 index 00000000000..007a50b3eda --- /dev/null +++ b/tests/micropython/viper_ptr16_store_boundary.py.exp @@ -0,0 +1,28 @@ +--- 5 +0x1 +0x102 +0x203 +0xc0d +0xd0e +0xe0f +--- 8 +0x304 +0x405 +0x506 +0xf10 +0x1011 +0x1112 +--- 11 +0x607 +0x708 +0x809 +0x1213 +0x1314 +0x1415 +--- 12 +0x90a +0xa0b +0xb0c +0x1516 +0x1617 +0x1718 diff --git a/tests/micropython/viper_ptr32_load_boundary.py b/tests/micropython/viper_ptr32_load_boundary.py new file mode 100644 index 00000000000..971d1113c49 --- /dev/null +++ b/tests/micropython/viper_ptr32_load_boundary.py @@ -0,0 +1,39 @@ +# Test boundary conditions for various architectures + +GET_TEMPLATE = """ +@micropython.viper +def get{off}(src: ptr32) -> uint: + return uint(src[{off}]) +print(hex(get{off}(buffer))) +""" + + +BIT_THRESHOLDS = (5, 8, 11, 12) +SIZE = 4 + + +@micropython.viper +def get_index(src: ptr32, i: int) -> int: + return src[i] + + +def data(start, len): + output = bytearray(len) + for idx in range(len): + output[idx] = (start + idx) & 0xFF + return output + + +buffer = bytearray((((1 << max(BIT_THRESHOLDS)) + 1) // 1024) * 1024) +val = 0 +for bit in BIT_THRESHOLDS: + print("---", bit) + pre, idx, post = (((1 << bit) - (2 * SIZE)), ((1 << bit) - (1 * SIZE)), (1 << bit)) + buffer[pre:post] = data(val, 3 * SIZE) + val = val + (3 * SIZE) + + pre, idx, post = pre // SIZE, idx // SIZE, post // SIZE + print(hex(get_index(buffer, pre)), hex(get_index(buffer, idx)), hex(get_index(buffer, post))) + exec(GET_TEMPLATE.format(off=pre)) + exec(GET_TEMPLATE.format(off=idx)) + exec(GET_TEMPLATE.format(off=post)) diff --git a/tests/micropython/viper_ptr32_load_boundary.py.exp b/tests/micropython/viper_ptr32_load_boundary.py.exp new file mode 100644 index 00000000000..1e22a8b3613 --- /dev/null +++ b/tests/micropython/viper_ptr32_load_boundary.py.exp @@ -0,0 +1,20 @@ +--- 5 +0x3020100 0x7060504 0xb0a0908 +0x3020100 +0x7060504 +0xb0a0908 +--- 8 +0xf0e0d0c 0x13121110 0x17161514 +0xf0e0d0c +0x13121110 +0x17161514 +--- 11 +0x1b1a1918 0x1f1e1d1c 0x23222120 +0x1b1a1918 +0x1f1e1d1c +0x23222120 +--- 12 +0x27262524 0x2b2a2928 0x2f2e2d2c +0x27262524 +0x2b2a2928 +0x2f2e2d2c diff --git a/tests/micropython/viper_ptr32_store_boundary.py b/tests/micropython/viper_ptr32_store_boundary.py new file mode 100644 index 00000000000..96ca74ad3ca --- /dev/null +++ b/tests/micropython/viper_ptr32_store_boundary.py @@ -0,0 +1,68 @@ +# Test boundary conditions for various architectures + +SET_TEMPLATE = """ +@micropython.viper +def set{off}(dest: ptr32): + saved = dest + dest[{off}] = {val} + assert int(saved) == int(dest) +""" + +BIT_THRESHOLDS = (5, 8, 11, 12) +SIZE = 4 +MASK = (1 << (8 * SIZE)) - 1 + +next_int = 1 +test_buffer = bytearray(SIZE) + + +def next_value() -> uint: + global next_int + global test_buffer + for index in range(1, SIZE): + test_buffer[index - 1] = test_buffer[index] + test_buffer[SIZE - 1] = next_int + next_int += 1 + output = 0 + for byte in test_buffer: + output = (output << 8) | byte + return output & MASK + + +def get_index(src, i): + return ( + src[i * SIZE] + + (src[(i * SIZE) + 1] << 8) + + (src[(i * SIZE) + 2] << 16) + + (src[(i * SIZE) + 3] << 24) + ) + + +@micropython.viper +def set_index(dest: ptr32, i: int, val: uint): + saved = dest + dest[i] = val + assert int(dest) == int(saved) + + +try: + buffer = bytearray((((1 << max(BIT_THRESHOLDS)) // 1024) + 1) * 1024) + + for bit in BIT_THRESHOLDS: + offset = (1 << bit) - (2 * SIZE) + for index in range(0, 3 * SIZE, SIZE): + exec(SET_TEMPLATE.format(off=(offset + index) // SIZE, val=next_value())) +except MemoryError: + print("SKIP-TOO-LARGE") + raise SystemExit + + +for bit in BIT_THRESHOLDS: + print("---", bit) + offset = (1 << bit) - (2 * SIZE) + for index in range(0, 3 * SIZE, SIZE): + globals()["set{}".format((offset + index) // SIZE)](buffer) + print(hex(get_index(buffer, (offset + index) // SIZE))) + for index in range(0, 3 * SIZE, SIZE): + set_index(buffer, (offset + index) // SIZE, next_value()) + print(hex(get_index(buffer, (offset + index) // SIZE))) diff --git a/tests/micropython/viper_ptr32_store_boundary.py.exp b/tests/micropython/viper_ptr32_store_boundary.py.exp new file mode 100644 index 00000000000..7a9a5162474 --- /dev/null +++ b/tests/micropython/viper_ptr32_store_boundary.py.exp @@ -0,0 +1,28 @@ +--- 5 +0x1 +0x102 +0x10203 +0xa0b0c0d +0xb0c0d0e +0xc0d0e0f +--- 8 +0x1020304 +0x2030405 +0x3040506 +0xd0e0f10 +0xe0f1011 +0xf101112 +--- 11 +0x4050607 +0x5060708 +0x6070809 +0x10111213 +0x11121314 +0x12131415 +--- 12 +0x708090a +0x8090a0b +0x90a0b0c +0x13141516 +0x14151617 +0x15161718 diff --git a/tests/micropython/viper_ptr8_load_boundary.py b/tests/micropython/viper_ptr8_load_boundary.py new file mode 100644 index 00000000000..57e06da5709 --- /dev/null +++ b/tests/micropython/viper_ptr8_load_boundary.py @@ -0,0 +1,38 @@ +# Test boundary conditions for various architectures + +GET_TEMPLATE = """ +@micropython.viper +def get{off}(src: ptr8) -> uint: + return uint(src[{off}]) +print(hex(get{off}(buffer))) +""" + + +BIT_THRESHOLDS = (5, 8, 11, 12) +SIZE = 1 + + +@micropython.viper +def get_index(src: ptr8, i: int) -> int: + return src[i] + + +def data(start, len): + output = bytearray(len) + for idx in range(len): + output[idx] = (start + idx) & 0xFF + return output + + +buffer = bytearray((((1 << max(BIT_THRESHOLDS)) + 1) // 1024) * 1024) +val = 0 +for bit in BIT_THRESHOLDS: + print("---", bit) + pre, idx, post = (((1 << bit) - (2 * SIZE)), ((1 << bit) - (1 * SIZE)), (1 << bit)) + buffer[pre:post] = data(val, 3 * SIZE) + val = val + (3 * SIZE) + + print(hex(get_index(buffer, pre)), hex(get_index(buffer, idx)), hex(get_index(buffer, post))) + exec(GET_TEMPLATE.format(off=pre)) + exec(GET_TEMPLATE.format(off=idx)) + exec(GET_TEMPLATE.format(off=post)) diff --git a/tests/micropython/viper_ptr8_load_boundary.py.exp b/tests/micropython/viper_ptr8_load_boundary.py.exp new file mode 100644 index 00000000000..a0e423686b8 --- /dev/null +++ b/tests/micropython/viper_ptr8_load_boundary.py.exp @@ -0,0 +1,20 @@ +--- 5 +0x0 0x1 0x2 +0x0 +0x1 +0x2 +--- 8 +0x3 0x4 0x5 +0x3 +0x4 +0x5 +--- 11 +0x6 0x7 0x8 +0x6 +0x7 +0x8 +--- 12 +0x9 0xa 0xb +0x9 +0xa +0xb diff --git a/tests/micropython/viper_ptr8_store_boundary.py b/tests/micropython/viper_ptr8_store_boundary.py new file mode 100644 index 00000000000..68b76fd598b --- /dev/null +++ b/tests/micropython/viper_ptr8_store_boundary.py @@ -0,0 +1,63 @@ +# Test boundary conditions for various architectures + +SET_TEMPLATE = """ +@micropython.viper +def set{off}(dest: ptr8): + saved = dest + dest[{off}] = {val} + assert int(saved) == int(dest) +""" + +BIT_THRESHOLDS = (5, 8, 11, 12) +SIZE = 1 +MASK = (1 << (8 * SIZE)) - 1 + +next_int = 1 +test_buffer = bytearray(SIZE) + + +def next_value() -> uint: + global next_int + global test_buffer + for index in range(1, SIZE): + test_buffer[index - 1] = test_buffer[index] + test_buffer[SIZE - 1] = next_int + next_int += 1 + output = 0 + for byte in test_buffer: + output = (output << 8) | byte + return output & MASK + + +def get_index(src: ptr8, i: int): + return src[i] + + +@micropython.viper +def set_index(dest: ptr8, i: int, val: uint): + saved = dest + dest[i] = val + assert int(dest) == int(saved) + + +try: + buffer = bytearray((((1 << max(BIT_THRESHOLDS)) // 1024) + 1) * 1024) + + for bit in BIT_THRESHOLDS: + offset = (1 << bit) - (2 * SIZE) + for index in range(0, 3 * SIZE, SIZE): + exec(SET_TEMPLATE.format(off=(offset + index) // SIZE, val=next_value())) +except MemoryError: + print("SKIP-TOO-LARGE") + raise SystemExit + + +for bit in BIT_THRESHOLDS: + print("---", bit) + offset = (1 << bit) - (2 * SIZE) + for index in range(0, 3 * SIZE, SIZE): + globals()["set{}".format((offset + index) // SIZE)](buffer) + print(hex(get_index(buffer, (offset + index) // SIZE))) + for index in range(0, 3 * SIZE, SIZE): + set_index(buffer, (offset + index) // SIZE, next_value()) + print(hex(get_index(buffer, (offset + index) // SIZE))) diff --git a/tests/micropython/viper_ptr8_store_boundary.py.exp b/tests/micropython/viper_ptr8_store_boundary.py.exp new file mode 100644 index 00000000000..621295d81a8 --- /dev/null +++ b/tests/micropython/viper_ptr8_store_boundary.py.exp @@ -0,0 +1,28 @@ +--- 5 +0x1 +0x2 +0x3 +0xd +0xe +0xf +--- 8 +0x4 +0x5 +0x6 +0x10 +0x11 +0x12 +--- 11 +0x7 +0x8 +0x9 +0x13 +0x14 +0x15 +--- 12 +0xa +0xb +0xc +0x16 +0x17 +0x18 diff --git a/tests/micropython/viper_with.py.exp b/tests/micropython/viper_with.py.exp index 6eef7822fba..7e28663f6fc 100644 --- a/tests/micropython/viper_with.py.exp +++ b/tests/micropython/viper_with.py.exp @@ -5,5 +5,5 @@ __exit__ None None None __init__ __enter__ 1 -__exit__ name 'fail' is not defined None +__exit__ name 'fail' isn't defined None NameError diff --git a/tests/misc/cexample_class.py b/tests/misc/cexample_class.py index 6b8718ad8cc..06d741922d2 100644 --- a/tests/misc/cexample_class.py +++ b/tests/misc/cexample_class.py @@ -22,3 +22,20 @@ print(timer) print(0 <= t_start <= TOLERANCE_MS) print(SLEEP_MS - TOLERANCE_MS <= t_end <= SLEEP_MS + TOLERANCE_MS) + +advanced_timer = cexample.AdvancedTimer() + +time.sleep_ms(100) + +print(repr(advanced_timer)) +print(str(advanced_timer)) + +print(advanced_timer.seconds) +advanced_timer.seconds = 123 +print(advanced_timer.seconds) +print(advanced_timer.time() < 123000 + TOLERANCE_MS) + +try: + advanced_timer.seconds = "bad input" +except TypeError: + print("TypeError") diff --git a/tests/misc/cexample_class.py.exp b/tests/misc/cexample_class.py.exp index b9a06602a31..a86d4d14f78 100644 --- a/tests/misc/cexample_class.py.exp +++ b/tests/misc/cexample_class.py.exp @@ -1,3 +1,9 @@ True True +AdvancedTimer() +AdvancedTimer() # created 0 seconds ago +0 +123 +True +TypeError diff --git a/tests/misc/cexample_module.py b/tests/misc/cexample_module.py index c1da2ecf7ab..979c1fa24b3 100644 --- a/tests/misc/cexample_module.py +++ b/tests/misc/cexample_module.py @@ -12,5 +12,6 @@ d = dir(cexample) d.index("add_ints") d.index("Timer") +d.index("AdvancedTimer") print(cexample.add_ints(1, 3)) diff --git a/tests/misc/cexample_subclass.py b/tests/misc/cexample_subclass.py new file mode 100644 index 00000000000..9f52a2c737a --- /dev/null +++ b/tests/misc/cexample_subclass.py @@ -0,0 +1,37 @@ +# test subclassing custom native class + +try: + from cexample import AdvancedTimer +except ImportError: + print("SKIP") + raise SystemExit + + +class SubTimer(AdvancedTimer): + def __init__(self): + # At this point, self does not yet represent a AdvancedTimer instance. + print(self) + + # So lookups via type.attr handler will fail. + try: + self.seconds + except AttributeError: + print("AttributeError") + + # Also applies to builtin methods. + try: + self.time() + except AttributeError: + print("AttributeError") + + # Initialize base class. + super().__init__(self) + + # Now you can access methods and attributes normally. + self.time() + print(self.seconds) + self.seconds = 123 + print(self.seconds) + + +watch = SubTimer() diff --git a/tests/misc/cexample_subclass.py.exp b/tests/misc/cexample_subclass.py.exp new file mode 100644 index 00000000000..a035649e475 --- /dev/null +++ b/tests/misc/cexample_subclass.py.exp @@ -0,0 +1,5 @@ + +AttributeError +AttributeError +0 +123 diff --git a/tests/misc/non_compliant.py b/tests/misc/non_compliant.py index deeb9fb1922..8608f2322f8 100644 --- a/tests/misc/non_compliant.py +++ b/tests/misc/non_compliant.py @@ -39,7 +39,7 @@ except NotImplementedError: print("NotImplementedError") -# uPy raises TypeError, should be ValueError +# MicroPython raises TypeError, should be ValueError try: "%c" % b"\x01\x02" except (TypeError, ValueError): @@ -63,12 +63,6 @@ except NotImplementedError: print("NotImplementedError") -# str.endswith(s, start) not implemented -try: - "abc".endswith("c", 1) -except NotImplementedError: - print("NotImplementedError") - # str subscr with step!=1 not implemented try: print("abc"[1:2:3]) @@ -106,10 +100,10 @@ print("NotImplementedError") # CIRCUITPY-CHANGE: We do check these. -# struct pack with too many args, not checked by uPy +# struct pack with too many args, not checked by MicroPython # print(struct.pack("bb", 1, 2, 3)) -# struct pack with too few args, not checked by uPy +# struct pack with too few args, not checked by MicroPython # print(struct.pack("bb", 1)) # array slice assignment with unsupported RHS diff --git a/tests/misc/non_compliant.py.exp b/tests/misc/non_compliant.py.exp index 8518828ec3a..006ddee1b73 100644 --- a/tests/misc/non_compliant.py.exp +++ b/tests/misc/non_compliant.py.exp @@ -14,7 +14,6 @@ NotImplementedError NotImplementedError NotImplementedError NotImplementedError -NotImplementedError AttributeError TypeError A.foo diff --git a/tests/misc/non_compliant_lexer.py b/tests/misc/non_compliant_lexer.py index e1c21f3d713..04c605953e7 100644 --- a/tests/misc/non_compliant_lexer.py +++ b/tests/misc/non_compliant_lexer.py @@ -11,7 +11,7 @@ def test(code): print("NotImplementedError") -# uPy requires spaces between literal numbers and keywords, CPy doesn't +# MPy requires spaces between literal numbers and keywords, CPy doesn't try: eval("1and 0") except SyntaxError: diff --git a/tests/misc/print_exception.py.native.exp b/tests/misc/print_exception.py.native.exp new file mode 100644 index 00000000000..59e856ae3c4 --- /dev/null +++ b/tests/misc/print_exception.py.native.exp @@ -0,0 +1,18 @@ +caught +Exception: msg + +caught +Exception: fail + +finally +caught +Exception: fail + +reraise +Exception: fail + +caught +Exception: fail + +AttributeError: 'function' object has no attribute 'X' + diff --git a/tests/misc/rge_sm.py b/tests/misc/rge_sm.py index 5e071687c49..33aa4edb742 100644 --- a/tests/misc/rge_sm.py +++ b/tests/misc/rge_sm.py @@ -39,14 +39,6 @@ def solve(self, finishtime): if not self.iterate(): break - def solveNSteps(self, nSteps): - for i in range(nSteps): - if not self.iterate(): - break - - def series(self): - return zip(*self.Trajectory) - # 1-loop RGES for the main parameters of the SM # couplings are: g1, g2, g3 of U(1), SU(2), SU(3); yt (top Yukawa), lambda (Higgs quartic) @@ -55,70 +47,36 @@ def series(self): lambda *a: 41.0 / 96.0 / math.pi**2 * a[1] ** 3, # g1 lambda *a: -19.0 / 96.0 / math.pi**2 * a[2] ** 3, # g2 lambda *a: -42.0 / 96.0 / math.pi**2 * a[3] ** 3, # g3 - lambda *a: 1.0 - / 16.0 - / math.pi**2 - * ( - 9.0 / 2.0 * a[4] ** 3 - - 8.0 * a[3] ** 2 * a[4] - - 9.0 / 4.0 * a[2] ** 2 * a[4] - - 17.0 / 12.0 * a[1] ** 2 * a[4] + lambda *a: ( + 1.0 + / 16.0 + / math.pi**2 + * ( + 9.0 / 2.0 * a[4] ** 3 + - 8.0 * a[3] ** 2 * a[4] + - 9.0 / 4.0 * a[2] ** 2 * a[4] + - 17.0 / 12.0 * a[1] ** 2 * a[4] + ) ), # yt - lambda *a: 1.0 - / 16.0 - / math.pi**2 - * ( - 24.0 * a[5] ** 2 - + 12.0 * a[4] ** 2 * a[5] - - 9.0 * a[5] * (a[2] ** 2 + 1.0 / 3.0 * a[1] ** 2) - - 6.0 * a[4] ** 4 - + 9.0 / 8.0 * a[2] ** 4 - + 3.0 / 8.0 * a[1] ** 4 - + 3.0 / 4.0 * a[2] ** 2 * a[1] ** 2 + lambda *a: ( + 1.0 + / 16.0 + / math.pi**2 + * ( + 24.0 * a[5] ** 2 + + 12.0 * a[4] ** 2 * a[5] + - 9.0 * a[5] * (a[2] ** 2 + 1.0 / 3.0 * a[1] ** 2) + - 6.0 * a[4] ** 4 + + 9.0 / 8.0 * a[2] ** 4 + + 3.0 / 8.0 * a[1] ** 4 + + 3.0 / 4.0 * a[2] ** 2 * a[1] ** 2 + ) ), # lambda ) -def drange(start, stop, step): - r = start - while r < stop: - yield r - r += step - - -def phaseDiagram(system, trajStart, trajPlot, h=0.1, tend=1.0, range=1.0): - tstart = 0.0 - for i in drange(0, range, 0.1 * range): - for j in drange(0, range, 0.1 * range): - rk = RungeKutta(system, trajStart(i, j), tstart, h) - rk.solve(tend) - # draw the line - for tr in rk.Trajectory: - x, y = trajPlot(tr) - print(x, y) - print() - # draw the arrow - continue - l = (len(rk.Trajectory) - 1) / 3 - if l > 0 and 2 * l < len(rk.Trajectory): - p1 = rk.Trajectory[l] - p2 = rk.Trajectory[2 * l] - x1, y1 = trajPlot(p1) - x2, y2 = trajPlot(p2) - dx = -0.5 * (y2 - y1) # orthogonal to line - dy = 0.5 * (x2 - x1) # orthogonal to line - # l = math.sqrt(dx*dx + dy*dy) - # if abs(l) > 1e-3: - # l = 0.1 / l - # dx *= l - # dy *= l - print(x1 + dx, y1 + dy) - print(x2, y2) - print(x1 - dx, y1 - dy) - print() - - def singleTraj(system, trajStart, h=0.02, tend=1.0): + is_REPR_C = float("1.0000001") == float("1.0") tstart = 0.0 # compute the trajectory @@ -130,10 +88,15 @@ def singleTraj(system, trajStart, h=0.02, tend=1.0): for i in range(len(rk.Trajectory)): tr = rk.Trajectory[i] - print(" ".join(["{:.4f}".format(t) for t in tr])) - + tr_str = " ".join(["{:.4f}".format(t) for t in tr]) + if is_REPR_C: + # allow two small deviations for REPR_C + if tr_str == "1.0000 0.3559 0.6485 1.1944 0.9271 0.1083": + tr_str = "1.0000 0.3559 0.6485 1.1944 0.9272 0.1083" + if tr_str == "16.0000 0.3894 0.5793 0.7017 0.5686 -0.0168": + tr_str = "16.0000 0.3894 0.5793 0.7017 0.5686 -0.0167" + print(tr_str) -# phaseDiagram(sysSM, (lambda i, j: [0.354, 0.654, 1.278, 0.8 + 0.2 * i, 0.1 + 0.1 * j]), (lambda a: (a[4], a[5])), h=0.1, tend=math.log(10**17)) # initial conditions at M_Z singleTraj(sysSM, [0.354, 0.654, 1.278, 0.983, 0.131], h=0.5, tend=math.log(10**17)) # true values diff --git a/tests/misc/sys_exc_info.py b/tests/misc/sys_exc_info.py index d7e8a2d943b..c076dd572b0 100644 --- a/tests/misc/sys_exc_info.py +++ b/tests/misc/sys_exc_info.py @@ -8,13 +8,14 @@ def f(): - print(sys.exc_info()[0:2]) + e = sys.exc_info() + print(e[0], e[1]) try: raise ValueError("value", 123) except: - print(sys.exc_info()[0:2]) + print(sys.exc_info()[0], sys.exc_info()[1]) f() # Outside except block, sys.exc_info() should be back to None's diff --git a/tests/misc/sys_settrace_cov.py b/tests/misc/sys_settrace_cov.py new file mode 100644 index 00000000000..579c8a4a25e --- /dev/null +++ b/tests/misc/sys_settrace_cov.py @@ -0,0 +1,23 @@ +import sys + +try: + sys.settrace +except AttributeError: + print("SKIP") + raise SystemExit + + +def trace_tick_handler(frame, event, arg): + print("FRAME", frame) + print("LASTI", frame.f_lasti) + return None + + +def f(): + x = 3 + return x + + +sys.settrace(trace_tick_handler) +f() +sys.settrace(None) diff --git a/tests/misc/sys_settrace_cov.py.exp b/tests/misc/sys_settrace_cov.py.exp new file mode 100644 index 00000000000..423d78ec42b --- /dev/null +++ b/tests/misc/sys_settrace_cov.py.exp @@ -0,0 +1,2 @@ +FRAME +LASTI \\d\+ diff --git a/tests/misc/sys_settrace_features.py b/tests/misc/sys_settrace_features.py index 8ca6b382e3c..6eeb2b900f1 100644 --- a/tests/misc/sys_settrace_features.py +++ b/tests/misc/sys_settrace_features.py @@ -6,6 +6,10 @@ print("SKIP") raise SystemExit +if sys.version.startswith("3.12"): + # There is a CPython change in settrace that is reverted in 3.13! + print("WARNING: this test will fail when compared to CPython 3.12.x behaviour") + def print_stacktrace(frame, level=0): # Ignore CPython specific helpers. diff --git a/tests/multi_extmod/machine_i2c_target_irq.py b/tests/multi_extmod/machine_i2c_target_irq.py new file mode 100644 index 00000000000..eafd9dfdca8 --- /dev/null +++ b/tests/multi_extmod/machine_i2c_target_irq.py @@ -0,0 +1,137 @@ +# Test I2CTarget IRQs and clock stretching. +# +# Requires two instances with their SCL and SDA lines connected together. +# Any combination of the below supported boards can be used. +# +# Notes: +# - pull-up resistors may be needed +# - alif use 1.8V signalling + +import sys +import time +from machine import I2C, I2CTarget + +if not hasattr(I2CTarget, "IRQ_ADDR_MATCH_READ"): + print("SKIP") + raise SystemExit + +ADDR = 67 +clock_stretch_us = 200 + +# Configure pins based on the target. +if sys.platform == "alif": + i2c_args = (1,) # pins P3_7/P3_6 + i2c_kwargs = {} +elif sys.platform == "mimxrt": + i2c_args = (0,) # pins 19/18 on Teensy 4.x + i2c_kwargs = {} + clock_stretch_us = 50 # mimxrt cannot delay too long in the IRQ handler +elif sys.platform == "rp2": + i2c_args = (0,) + i2c_kwargs = {"scl": 9, "sda": 8} +elif sys.platform == "pyboard": + i2c_args = ("Y",) + i2c_kwargs = {} +elif sys.platform == "samd": + i2c_args = () # pins SCL/SDA + i2c_kwargs = {} +elif "zephyr-rpi_pico" in sys.implementation._machine: + i2c_args = ("i2c1",) # on gpio7/gpio6 + i2c_kwargs = {} +else: + print("Please add support for this test on this platform.") + raise SystemExit + + +def simple_irq(i2c_target): + flags = i2c_target.irq().flags() + if flags & I2CTarget.IRQ_ADDR_MATCH_READ: + print("IRQ_ADDR_MATCH_READ") + if flags & I2CTarget.IRQ_ADDR_MATCH_WRITE: + print("IRQ_ADDR_MATCH_WRITE") + + # Force clock stretching. + time.sleep_us(clock_stretch_us) + + +class I2CTargetMemory: + def __init__(self, i2c_target, mem): + self.buf1 = bytearray(1) + self.mem = mem + self.memaddr = 0 + self.state = 0 + i2c_target.irq( + self.irq, + I2CTarget.IRQ_ADDR_MATCH_WRITE | I2CTarget.IRQ_READ_REQ | I2CTarget.IRQ_WRITE_REQ, + hard=True, + ) + + def irq(self, i2c_target): + # Force clock stretching. + time.sleep_us(clock_stretch_us) + + flags = i2c_target.irq().flags() + if flags & I2CTarget.IRQ_ADDR_MATCH_WRITE: + self.state = 0 + if flags & I2CTarget.IRQ_READ_REQ: + self.buf1[0] = self.mem[self.memaddr] + self.memaddr += 1 + i2c_target.write(self.buf1) + if flags & I2CTarget.IRQ_WRITE_REQ: + i2c_target.readinto(self.buf1) + if self.state == 0: + self.state = 1 + self.memaddr = self.buf1[0] + else: + self.mem[self.memaddr] = self.buf1[0] + self.memaddr += 1 + self.memaddr %= len(self.mem) + + # Force clock stretching. + time.sleep_us(clock_stretch_us) + + +# I2C controller +def instance0(): + i2c = I2C(*i2c_args, **i2c_kwargs) + multitest.next() + for iteration in range(2): + print("controller iteration", iteration) + multitest.wait("target stage 1") + i2c.writeto_mem(ADDR, 2, "0123") + multitest.broadcast("controller stage 2") + multitest.wait("target stage 3") + print(i2c.readfrom_mem(ADDR, 2, 4)) + multitest.broadcast("controller stage 4") + print("done") + + +# I2C target +def instance1(): + multitest.next() + + for iteration in range(2): + print("target iteration", iteration) + buf = bytearray(b"--------") + if iteration == 0: + # Use built-in memory capability of I2CTarget. + i2c_target = I2CTarget(*i2c_args, **i2c_kwargs, addr=ADDR, mem=buf) + i2c_target.irq( + simple_irq, + I2CTarget.IRQ_ADDR_MATCH_READ | I2CTarget.IRQ_ADDR_MATCH_WRITE, + hard=True, + ) + else: + # Implement a memory device by hand. + i2c_target = I2CTarget(*i2c_args, **i2c_kwargs, addr=ADDR) + I2CTargetMemory(i2c_target, buf) + + multitest.broadcast("target stage 1") + multitest.wait("controller stage 2") + print(buf) + multitest.broadcast("target stage 3") + multitest.wait("controller stage 4") + + i2c_target.deinit() + + print("done") diff --git a/tests/multi_extmod/machine_i2c_target_irq.py.exp b/tests/multi_extmod/machine_i2c_target_irq.py.exp new file mode 100644 index 00000000000..a17c8f43858 --- /dev/null +++ b/tests/multi_extmod/machine_i2c_target_irq.py.exp @@ -0,0 +1,15 @@ +--- instance0 --- +controller iteration 0 +b'0123' +controller iteration 1 +b'0123' +done +--- instance1 --- +target iteration 0 +IRQ_ADDR_MATCH_WRITE +bytearray(b'--0123--') +IRQ_ADDR_MATCH_WRITE +IRQ_ADDR_MATCH_READ +target iteration 1 +bytearray(b'--0123--') +done diff --git a/tests/multi_extmod/machine_i2c_target_memory.py b/tests/multi_extmod/machine_i2c_target_memory.py new file mode 100644 index 00000000000..6b3f0d03eb7 --- /dev/null +++ b/tests/multi_extmod/machine_i2c_target_memory.py @@ -0,0 +1,79 @@ +# Test basic use of I2CTarget and a memory buffer. +# +# Requires two instances with their SCL and SDA lines connected together. +# Any combination of the below supported boards can be used. +# +# Notes: +# - pull-up resistors may be needed +# - alif use 1.8V signalling + +import sys +from machine import I2C, I2CTarget + +ADDR = 67 + +# Configure pins based on the target. +if sys.platform == "alif": + i2c_args = (1,) # pins P3_7/P3_6 + i2c_kwargs = {} +elif sys.platform == "esp32": + i2c_args = (1,) # on pins 9/8 + i2c_kwargs = {} +elif sys.platform == "mimxrt": + i2c_args = (0,) # pins 19/18 on Teensy 4.x + i2c_kwargs = {} +elif sys.platform == "rp2": + i2c_args = (0,) + i2c_kwargs = {"scl": 9, "sda": 8} +elif sys.platform == "pyboard": + i2c_args = ("Y",) + i2c_kwargs = {} +elif sys.platform == "samd": + i2c_args = () # pins SCL/SDA + i2c_kwargs = {} +elif "zephyr-rpi_pico" in sys.implementation._machine: + i2c_args = ("i2c1",) # on gpio7/gpio6 + i2c_kwargs = {} +else: + print("Please add support for this test on this platform.") + raise SystemExit + + +def simple_irq(i2c_target): + flags = i2c_target.irq().flags() + if flags & I2CTarget.IRQ_END_READ: + print("IRQ_END_READ", i2c_target.memaddr) + if flags & I2CTarget.IRQ_END_WRITE: + print("IRQ_END_WRITE", i2c_target.memaddr) + + +# I2C controller +def instance0(): + i2c = I2C(*i2c_args, **i2c_kwargs) + multitest.next() + for iteration in range(2): + print("controller iteration", iteration) + multitest.wait("target stage 1") + i2c.writeto_mem(ADDR, 2 + iteration, "0123") + multitest.broadcast("controller stage 2") + multitest.wait("target stage 3") + print(i2c.readfrom_mem(ADDR, 2 + iteration, 4)) + multitest.broadcast("controller stage 4") + print("done") + + +# I2C target +def instance1(): + buf = bytearray(b"--------") + i2c_target = I2CTarget(*i2c_args, **i2c_kwargs, addr=ADDR, mem=buf) + i2c_target.irq(simple_irq) + multitest.next() + for iteration in range(2): + print("target iteration", iteration) + multitest.broadcast("target stage 1") + multitest.wait("controller stage 2") + print(buf) + multitest.broadcast("target stage 3") + multitest.wait("controller stage 4") + i2c_target.deinit() + print("done") diff --git a/tests/multi_extmod/machine_i2c_target_memory.py.exp b/tests/multi_extmod/machine_i2c_target_memory.py.exp new file mode 100644 index 00000000000..71386cfe769 --- /dev/null +++ b/tests/multi_extmod/machine_i2c_target_memory.py.exp @@ -0,0 +1,16 @@ +--- instance0 --- +controller iteration 0 +b'0123' +controller iteration 1 +b'0123' +done +--- instance1 --- +target iteration 0 +IRQ_END_WRITE 2 +bytearray(b'--0123--') +IRQ_END_READ 2 +target iteration 1 +IRQ_END_WRITE 3 +bytearray(b'--00123-') +IRQ_END_READ 3 +done diff --git a/tests/perf_bench/bm_fft.py b/tests/perf_bench/bm_fft.py index 9a2d03d11b9..e35c1216c13 100644 --- a/tests/perf_bench/bm_fft.py +++ b/tests/perf_bench/bm_fft.py @@ -15,7 +15,7 @@ def reverse(x, bits): # Initialization n = len(vector) - levels = int(math.log(n) / math.log(2)) + levels = int(round(math.log(n) / math.log(2))) coef = (2 if inverse else -2) * cmath.pi / n exptable = [cmath.rect(1, i * coef) for i in range(n // 2)] vector = [vector[reverse(i, levels)] for i in range(n)] # Copy with bit-reversed permutation diff --git a/tests/perf_bench/bm_pidigits.py b/tests/perf_bench/bm_pidigits.py index bdaa73cec7e..c935f103c5b 100644 --- a/tests/perf_bench/bm_pidigits.py +++ b/tests/perf_bench/bm_pidigits.py @@ -5,6 +5,12 @@ # This benchmark stresses big integer arithmetic. # Adapted from code on: http://benchmarksgame.alioth.debian.org/ +try: + int("0x10000000000000000", 16) +except: + print("SKIP") # No support for >64-bit integers + raise SystemExit + def compose(a, b): aq, ar, as_, at = a diff --git a/tests/perf_bench/core_import_mpy_multi.py b/tests/perf_bench/core_import_mpy_multi.py index 33437f9da80..67deec05088 100644 --- a/tests/perf_bench/core_import_mpy_multi.py +++ b/tests/perf_bench/core_import_mpy_multi.py @@ -6,7 +6,7 @@ print("SKIP") raise SystemExit -# This is the test.py file that is compiled to test.mpy below. +# This is the test.py file that is compiled to test.mpy below. mpy-cross must be invoked with `-msmall-int-bits=30`. """ class A: def __init__(self, arg): @@ -23,7 +23,7 @@ def f(): x = ("const tuple", None, False, True, 1, 2, 3) result = 123 """ -file_data = b'M\x06\x00\x1f\x14\x03\x0etest.py\x00\x0f\x02A\x00\x02f\x00\x0cresult\x00/-5#\x82I\x81{\x81w\x82/\x81\x05\x81\x17Iom\x82\x13\x06arg\x00\x05\x1cthis will be a string object\x00\x06\x1bthis will be a bytes object\x00\n\x07\x05\x0bconst tuple\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x81\\\x10\n\x01\x89\x07d`T2\x00\x10\x024\x02\x16\x022\x01\x16\x03"\x80{\x16\x04Qc\x02\x81d\x00\x08\x02(DD\x11\x05\x16\x06\x10\x02\x16\x072\x00\x16\x082\x01\x16\t2\x02\x16\nQc\x03`\x1a\x08\x08\x12\x13@\xb1\xb0\x18\x13Qc@\t\x08\t\x12` Qc@\t\x08\n\x12``Qc\x82@ \x0e\x03\x80\x08+)##\x12\x0b\x12\x0c\x12\r\x12\x0e*\x04Y\x12\x0f\x12\x10\x12\x11*\x03Y#\x00\xc0#\x01\xc0#\x02\xc0Qc' +file_data = b'M\x06\x00\x1e\x14\x03\x0etest.py\x00\x0f\x02A\x00\x02f\x00\x0cresult\x00/-5#\x82I\x81{\x81w\x82/\x81\x05\x81\x17Iom\x82\x13\x06arg\x00\x05\x1cthis will be a string object\x00\x06\x1bthis will be a bytes object\x00\n\x07\x05\x0bconst tuple\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x81\\\x10\n\x01\x89\x07d`T2\x00\x10\x024\x02\x16\x022\x01\x16\x03"\x80{\x16\x04Qc\x02\x81d\x00\x08\x02(DD\x11\x05\x16\x06\x10\x02\x16\x072\x00\x16\x082\x01\x16\t2\x02\x16\nQc\x03`\x1a\x08\x08\x12\x13@\xb1\xb0\x18\x13Qc@\t\x08\t\x12` Qc@\t\x08\n\x12``Qc\x82@ \x0e\x03\x80\x08+)##\x12\x0b\x12\x0c\x12\r\x12\x0e*\x04Y\x12\x0f\x12\x10\x12\x11*\x03Y#\x00\xc0#\x01\xc0#\x02\xc0Qc' class File(io.IOBase): @@ -31,7 +31,9 @@ def __init__(self): self.off = 0 def ioctl(self, request, arg): - return 0 + if request == 4: # MP_STREAM_CLOSE + return 0 + return -1 def readinto(self, buf): buf[:] = memoryview(file_data)[self.off : self.off + len(buf)] diff --git a/tests/perf_bench/core_import_mpy_single.py b/tests/perf_bench/core_import_mpy_single.py index 18454b8fd5e..f472bb64762 100644 --- a/tests/perf_bench/core_import_mpy_single.py +++ b/tests/perf_bench/core_import_mpy_single.py @@ -8,7 +8,7 @@ print("SKIP") raise SystemExit -# This is the test.py file that is compiled to test.mpy below. +# This is the test.py file that is compiled to test.mpy below. mpy-cross must be invoked with `-msmall-int-bits=30`. # Many known and unknown names/strings are included to test the linking process. """ class A0: @@ -78,7 +78,7 @@ def f1(): x = ("const tuple 9", None, False, True, 1, 2, 3) result = 123 """ -file_data = b"M\x06\x00\x1f\x81=\x1e\x0etest.py\x00\x0f\x04A0\x00\x04A1\x00\x04f0\x00\x04f1\x00\x0cresult\x00/-5\x04a0\x00\x04a1\x00\x04a2\x00\x04a3\x00\x13\x15\x17\x19\x1b\x1d\x1f!#%')+1379;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}\x7f\x81\x01\x81\x03\x81\x05\x81\x07\x81\t\x81\x0b\x81\r\x81\x0f\x81\x11\x81\x13\x81\x15\x81\x17\x81\x19\x81\x1b\x81\x1d\x81\x1f\x81!\x81#\x81%\x81'\x81)\x81+\x81-\x81/\x811\x813\x815\x817\x819\x81;\x81=\x81?\x81A\x81C\x81E\x81G\x81I\x81K\x81M\x81O\x81Q\x81S\x81U\x81W\x81Y\x81[\x81]\x81_\x81a\x81c\x81e\x81g\x81i\x81k\x81m\x81o\x81q\x81s\x81u\x81w\x81y\x81{\x81}\x81\x7f\x82\x01\x82\x03\x82\x05\x82\x07\x82\t\x82\x0b\x82\r\x82\x0f\x82\x11\x82\x13\x82\x15\x82\x17\x82\x19\x82\x1b\x82\x1d\x82\x1f\x82!\x82#\x82%\x82'\x82)\x82+\x82-\x82/\x821\x823\x825\x827\x829\x82;\x82=\x82?\x82A\x82E\x82G\x82I\x82K\nname0\x00\nname1\x00\nname2\x00\nname3\x00\nname4\x00\nname5\x00\nname6\x00\nname7\x00\nname8\x00\nname9\x00$quite_a_long_name0\x00$quite_a_long_name1\x00$quite_a_long_name2\x00$quite_a_long_name3\x00$quite_a_long_name4\x00$quite_a_long_name5\x00$quite_a_long_name6\x00$quite_a_long_name7\x00$quite_a_long_name8\x00$quite_a_long_name9\x00&quite_a_long_name10\x00&quite_a_long_name11\x00\x05\x1ethis will be a string object 0\x00\x05\x1ethis will be a string object 1\x00\x05\x1ethis will be a string object 2\x00\x05\x1ethis will be a string object 3\x00\x05\x1ethis will be a string object 4\x00\x05\x1ethis will be a string object 5\x00\x05\x1ethis will be a string object 6\x00\x05\x1ethis will be a string object 7\x00\x05\x1ethis will be a string object 8\x00\x05\x1ethis will be a string object 9\x00\x06\x1dthis will be a bytes object 0\x00\x06\x1dthis will be a bytes object 1\x00\x06\x1dthis will be a bytes object 2\x00\x06\x1dthis will be a bytes object 3\x00\x06\x1dthis will be a bytes object 4\x00\x06\x1dthis will be a bytes object 5\x00\x06\x1dthis will be a bytes object 6\x00\x06\x1dthis will be a bytes object 7\x00\x06\x1dthis will be a bytes object 8\x00\x06\x1dthis will be a bytes object 9\x00\n\x07\x05\rconst tuple 0\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 1\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 2\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 3\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 4\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 5\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 6\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 7\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 8\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 9\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x82d\x10\x12\x01i@i@\x84\x18\x84\x1fT2\x00\x10\x024\x02\x16\x02T2\x01\x10\x034\x02\x16\x032\x02\x16\x042\x03\x16\x05\"\x80{\x16\x06Qc\x04\x82\x0c\x00\n\x02($$$\x11\x07\x16\x08\x10\x02\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04@\t\x08\n\x81\x0b Qc@\t\x08\x0b\x81\x0b@Qc@\t\x08\x0c\x81\x0b`QcH\t\n\r\x81\x0b` Qc\x82\x14\x00\x0c\x03h`$$$\x11\x07\x16\x08\x10\x03\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04H\t\n\n\x81\x0b``QcH\t\n\x0b\x81\x0b\x80\x07QcH\t\n\x0c\x81\x0b\x80\x08QcH\t\n\r\x81\x0b\x80\tQc\xa08P:\x04\x80\x0b13///---997799<\x1f%\x1f\"\x1f%)\x1f\"//\x12\x0e\x12\x0f\x12\x10\x12\x11\x12\x12\x12\x13\x12\x14*\x07Y\x12\x15\x12\x16\x12\x17\x12\x18\x12\x19\x12\x1a\x12\x08\x12\x07*\x08Y\x12\x1b\x12\x1c\x12\t\x12\x1d\x12\x1e\x12\x1f*\x06Y\x12 \x12!\x12\"\x12#\x12$\x12%*\x06Y\x12&\x12'\x12(\x12)\x12*\x12+*\x06Y\x12,\x12-\x12.\x12/\x120*\x05Y\x121\x122\x123\x124\x125*\x05Y\x126\x127\x128\x129\x12:*\x05Y\x12;\x12<\x12=\x12>\x12?\x12@\x12A\x12B\x12C\x12D\x12E*\x0bY\x12F\x12G\x12H\x12I\x12J\x12K\x12L\x12M\x12N\x12O\x12P*\x0bY\x12Q\x12R\x12S\x12T\x12U\x12V\x12W\x12X\x12Y\x12Z*\nY\x12[\x12\\\x12]\x12^\x12_\x12`\x12a\x12b\x12c\x12d*\nY\x12e\x12f\x12g\x12h\x12i\x12j\x12k\x12l\x12m\x12n\x12o*\x0bY\x12p\x12q\x12r\x12s\x12t\x12u\x12v\x12w\x12x\x12y\x12z*\x0bY\x12{\x12|\x12}\x12~\x12\x7f\x12\x81\x00\x12\x81\x01\x12\x81\x02\x12\x81\x03\x12\x81\x04*\nY\x12\x81\x05\x12\x81\x06\x12\x81\x07\x12\x81\x08\x12\x81\t\x12\x81\n\x12\x81\x0b\x12\x81\x0c\x12\x81\r\x12\x81\x0e\x12\x81\x0f*\x0bY\x12\x81\x10\x12\x81\x11\x12\x81\x12\x12\x81\x13\x12\x81\x14\x12\x81\x15\x12\x81\x16\x12\x81\x17\x12\x81\x18\x12\x81\x19*\nY\x12\x81\x1a\x12\x81\x1b\x12\x81\x1c\x12\x81\x1d\x12\x81\x1e\x12\x81\x1f\x12\x81 \x12\x81!\x12\x81\"\x12\x81#\x12\x81$*\x0bY\x12\x81%\x12\x81&*\x02Y\x12\x81'\x12\x81(\x12\x81)\x12\x81*\x12\x81+\x12\x81,\x12\x81-\x12\x81.\x12\x81/\x12\x810*\nY\x12\x811\x12\x812\x12\x813\x12\x814*\x04Y\x12\x815\x12\x816\x12\x817\x12\x818*\x04Y\x12\x819\x12\x81:\x12\x81;\x12\x81<*\x04YQc\x87p\x08@\x05\x80###############################\x00\xc0#\x01\xc0#\x02\xc0#\x03\xc0#\x04\xc0#\x05\xc0#\x06\xc0#\x07\xc0#\x08\xc0#\t\xc0#\n\xc0#\x0b\xc0#\x0c\xc0#\r\xc0#\x0e\xc0#\x0f\xc0#\x10\xc0#\x11\xc0#\x12\xc0#\x13\xc0#\x14\xc0#\x15\xc0#\x16\xc0#\x17\xc0#\x18\xc0#\x19\xc0#\x1a\xc0#\x1b\xc0#\x1c\xc0#\x1d\xc0Qc" +file_data = b"M\x06\x00\x1e\x81=\x1e\x0etest.py\x00\x0f\x04A0\x00\x04A1\x00\x04f0\x00\x04f1\x00\x0cresult\x00/-5\x04a0\x00\x04a1\x00\x04a2\x00\x04a3\x00\x13\x15\x17\x19\x1b\x1d\x1f!#%')+1379;=?ACEGIKMOQSUWY[]_acegikmoqsuwy{}\x7f\x81\x01\x81\x03\x81\x05\x81\x07\x81\t\x81\x0b\x81\r\x81\x0f\x81\x11\x81\x13\x81\x15\x81\x17\x81\x19\x81\x1b\x81\x1d\x81\x1f\x81!\x81#\x81%\x81'\x81)\x81+\x81-\x81/\x811\x813\x815\x817\x819\x81;\x81=\x81?\x81A\x81C\x81E\x81G\x81I\x81K\x81M\x81O\x81Q\x81S\x81U\x81W\x81Y\x81[\x81]\x81_\x81a\x81c\x81e\x81g\x81i\x81k\x81m\x81o\x81q\x81s\x81u\x81w\x81y\x81{\x81}\x81\x7f\x82\x01\x82\x03\x82\x05\x82\x07\x82\t\x82\x0b\x82\r\x82\x0f\x82\x11\x82\x13\x82\x15\x82\x17\x82\x19\x82\x1b\x82\x1d\x82\x1f\x82!\x82#\x82%\x82'\x82)\x82+\x82-\x82/\x821\x823\x825\x827\x829\x82;\x82=\x82?\x82A\x82E\x82G\x82I\x82K\nname0\x00\nname1\x00\nname2\x00\nname3\x00\nname4\x00\nname5\x00\nname6\x00\nname7\x00\nname8\x00\nname9\x00$quite_a_long_name0\x00$quite_a_long_name1\x00$quite_a_long_name2\x00$quite_a_long_name3\x00$quite_a_long_name4\x00$quite_a_long_name5\x00$quite_a_long_name6\x00$quite_a_long_name7\x00$quite_a_long_name8\x00$quite_a_long_name9\x00&quite_a_long_name10\x00&quite_a_long_name11\x00\x05\x1ethis will be a string object 0\x00\x05\x1ethis will be a string object 1\x00\x05\x1ethis will be a string object 2\x00\x05\x1ethis will be a string object 3\x00\x05\x1ethis will be a string object 4\x00\x05\x1ethis will be a string object 5\x00\x05\x1ethis will be a string object 6\x00\x05\x1ethis will be a string object 7\x00\x05\x1ethis will be a string object 8\x00\x05\x1ethis will be a string object 9\x00\x06\x1dthis will be a bytes object 0\x00\x06\x1dthis will be a bytes object 1\x00\x06\x1dthis will be a bytes object 2\x00\x06\x1dthis will be a bytes object 3\x00\x06\x1dthis will be a bytes object 4\x00\x06\x1dthis will be a bytes object 5\x00\x06\x1dthis will be a bytes object 6\x00\x06\x1dthis will be a bytes object 7\x00\x06\x1dthis will be a bytes object 8\x00\x06\x1dthis will be a bytes object 9\x00\n\x07\x05\rconst tuple 0\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 1\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 2\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 3\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 4\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 5\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 6\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 7\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 8\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\n\x07\x05\rconst tuple 9\x00\x01\x02\x03\x07\x011\x07\x012\x07\x013\x82d\x10\x12\x01i@i@\x84\x18\x84\x1fT2\x00\x10\x024\x02\x16\x02T2\x01\x10\x034\x02\x16\x032\x02\x16\x042\x03\x16\x05\"\x80{\x16\x06Qc\x04\x82\x0c\x00\n\x02($$$\x11\x07\x16\x08\x10\x02\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04@\t\x08\n\x81\x0b Qc@\t\x08\x0b\x81\x0b@Qc@\t\x08\x0c\x81\x0b`QcH\t\n\r\x81\x0b` Qc\x82\x14\x00\x0c\x03h`$$$\x11\x07\x16\x08\x10\x03\x16\t2\x00\x16\n2\x01\x16\x0b2\x02\x16\x0c2\x03\x16\rQc\x04H\t\n\n\x81\x0b``QcH\t\n\x0b\x81\x0b\x80\x07QcH\t\n\x0c\x81\x0b\x80\x08QcH\t\n\r\x81\x0b\x80\tQc\xa08P:\x04\x80\x0b13///---997799<\x1f%\x1f\"\x1f%)\x1f\"//\x12\x0e\x12\x0f\x12\x10\x12\x11\x12\x12\x12\x13\x12\x14*\x07Y\x12\x15\x12\x16\x12\x17\x12\x18\x12\x19\x12\x1a\x12\x08\x12\x07*\x08Y\x12\x1b\x12\x1c\x12\t\x12\x1d\x12\x1e\x12\x1f*\x06Y\x12 \x12!\x12\"\x12#\x12$\x12%*\x06Y\x12&\x12'\x12(\x12)\x12*\x12+*\x06Y\x12,\x12-\x12.\x12/\x120*\x05Y\x121\x122\x123\x124\x125*\x05Y\x126\x127\x128\x129\x12:*\x05Y\x12;\x12<\x12=\x12>\x12?\x12@\x12A\x12B\x12C\x12D\x12E*\x0bY\x12F\x12G\x12H\x12I\x12J\x12K\x12L\x12M\x12N\x12O\x12P*\x0bY\x12Q\x12R\x12S\x12T\x12U\x12V\x12W\x12X\x12Y\x12Z*\nY\x12[\x12\\\x12]\x12^\x12_\x12`\x12a\x12b\x12c\x12d*\nY\x12e\x12f\x12g\x12h\x12i\x12j\x12k\x12l\x12m\x12n\x12o*\x0bY\x12p\x12q\x12r\x12s\x12t\x12u\x12v\x12w\x12x\x12y\x12z*\x0bY\x12{\x12|\x12}\x12~\x12\x7f\x12\x81\x00\x12\x81\x01\x12\x81\x02\x12\x81\x03\x12\x81\x04*\nY\x12\x81\x05\x12\x81\x06\x12\x81\x07\x12\x81\x08\x12\x81\t\x12\x81\n\x12\x81\x0b\x12\x81\x0c\x12\x81\r\x12\x81\x0e\x12\x81\x0f*\x0bY\x12\x81\x10\x12\x81\x11\x12\x81\x12\x12\x81\x13\x12\x81\x14\x12\x81\x15\x12\x81\x16\x12\x81\x17\x12\x81\x18\x12\x81\x19*\nY\x12\x81\x1a\x12\x81\x1b\x12\x81\x1c\x12\x81\x1d\x12\x81\x1e\x12\x81\x1f\x12\x81 \x12\x81!\x12\x81\"\x12\x81#\x12\x81$*\x0bY\x12\x81%\x12\x81&*\x02Y\x12\x81'\x12\x81(\x12\x81)\x12\x81*\x12\x81+\x12\x81,\x12\x81-\x12\x81.\x12\x81/\x12\x810*\nY\x12\x811\x12\x812\x12\x813\x12\x814*\x04Y\x12\x815\x12\x816\x12\x817\x12\x818*\x04Y\x12\x819\x12\x81:\x12\x81;\x12\x81<*\x04YQc\x87p\x08@\x05\x80###############################\x00\xc0#\x01\xc0#\x02\xc0#\x03\xc0#\x04\xc0#\x05\xc0#\x06\xc0#\x07\xc0#\x08\xc0#\t\xc0#\n\xc0#\x0b\xc0#\x0c\xc0#\r\xc0#\x0e\xc0#\x0f\xc0#\x10\xc0#\x11\xc0#\x12\xc0#\x13\xc0#\x14\xc0#\x15\xc0#\x16\xc0#\x17\xc0#\x18\xc0#\x19\xc0#\x1a\xc0#\x1b\xc0#\x1c\xc0#\x1d\xc0Qc" class File(io.IOBase): @@ -86,7 +86,9 @@ def __init__(self): self.off = 0 def ioctl(self, request, arg): - return 0 + if request == 4: # MP_STREAM_CLOSE + return 0 + return -1 def readinto(self, buf): buf[:] = memoryview(file_data)[self.off : self.off + len(buf)] diff --git a/tests/pyboard.py b/tests/pyboard.py deleted file mode 120000 index 616773a313a..00000000000 --- a/tests/pyboard.py +++ /dev/null @@ -1 +0,0 @@ -../tools/cpboard.py \ No newline at end of file diff --git a/tests/run-internalbench.py b/tests/run-internalbench.py index c9f783e474c..99c6304afe9 100755 --- a/tests/run-internalbench.py +++ b/tests/run-internalbench.py @@ -8,6 +8,10 @@ from glob import glob from collections import defaultdict +run_tests_module = __import__("run-tests") +sys.path.append(run_tests_module.base_path("../tools")) +import pyboard + if os.name == "nt": MICROPYTHON = os.getenv( "MICROPY_MICROPYTHON", "../ports/windows/build-standard/micropython.exe" @@ -15,13 +19,39 @@ else: MICROPYTHON = os.getenv("MICROPY_MICROPYTHON", "../ports/unix/build-standard/micropython") +injected_bench_code = b""" +import time + +class bench_class: + ITERS = 20000000 + + @staticmethod + def run(test): + t = time.ticks_us() + test(bench_class.ITERS) + t = time.ticks_diff(time.ticks_us(), t) + s, us = divmod(t, 1_000_000) + print("{}.{:06}".format(s, us)) + +import sys +sys.modules['bench'] = bench_class +""" + -def run_tests(pyb, test_dict): +def execbench(pyb, filename, iters): + with open(filename, "rb") as f: + pyfile = f.read() + code = (injected_bench_code + pyfile).replace(b"20000000", str(iters).encode("utf-8")) + return pyb.exec(code).replace(b"\r\n", b"\n") + + +def run_tests(pyb, test_dict, iters): test_count = 0 testcase_count = 0 for base_test, tests in sorted(test_dict.items()): print(base_test + ":") + baseline = None for test_file in tests: # run MicroPython if pyb is None: @@ -36,20 +66,25 @@ def run_tests(pyb, test_dict): # run on pyboard pyb.enter_raw_repl() try: - output_mupy = pyb.execfile(test_file).replace(b"\r\n", b"\n") + output_mupy = execbench(pyb, test_file[0], iters) except pyboard.PyboardError: output_mupy = b"CRASH" - output_mupy = float(output_mupy.strip()) + try: + output_mupy = float(output_mupy.strip()) + except ValueError: + output_mupy = -1 test_file[1] = output_mupy testcase_count += 1 - test_count += 1 - baseline = None - for t in tests: if baseline is None: - baseline = t[1] - print(" %.3fs (%+06.2f%%) %s" % (t[1], (t[1] * 100 / baseline) - 100, t[0])) + baseline = test_file[1] + print( + " %.3fs (%+06.2f%%) %s" + % (test_file[1], (test_file[1] * 100 / baseline) - 100, test_file[0]) + ) + + test_count += 1 print("{} tests performed ({} individual testcases)".format(test_count, testcase_count)) @@ -58,27 +93,47 @@ def run_tests(pyb, test_dict): def main(): - cmd_parser = argparse.ArgumentParser(description="Run tests for MicroPython.") - cmd_parser.add_argument("--pyboard", action="store_true", help="run the tests on the pyboard") + cmd_parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=f"""Run and manage tests for MicroPython. + +{run_tests_module.test_instance_description} +{run_tests_module.test_directory_description} +""", + epilog=run_tests_module.test_instance_epilog, + ) + cmd_parser.add_argument( + "-t", "--test-instance", default="unix", help="the MicroPython instance to test" + ) + cmd_parser.add_argument( + "-b", "--baudrate", default=115200, help="the baud rate of the serial device" + ) + cmd_parser.add_argument("-u", "--user", default="micro", help="the telnet login username") + cmd_parser.add_argument("-p", "--password", default="python", help="the telnet login password") + cmd_parser.add_argument( + "-d", "--test-dirs", nargs="*", help="input test directories (if no files given)" + ) + cmd_parser.add_argument( + "-I", + "--iters", + type=int, + default=200_000, + help="number of test iterations, only for remote instances (default 200,000)", + ) cmd_parser.add_argument("files", nargs="*", help="input test files") args = cmd_parser.parse_args() # Note pyboard support is copied over from run-tests.py, not tests, and likely needs revamping - if args.pyboard: - import pyboard - - pyb = pyboard.Pyboard("/dev/ttyACM0") - pyb.enter_raw_repl() - else: - pyb = None + pyb = run_tests_module.get_test_instance( + args.test_instance, args.baudrate, args.user, args.password + ) if len(args.files) == 0: - if pyb is None: - # run PC tests - test_dirs = ("internal_bench",) + if args.test_dirs: + test_dirs = tuple(args.test_dirs) else: - # run pyboard tests - test_dirs = ("basics", "float", "pyb") + test_dirs = ("internal_bench",) + tests = sorted( test_file for test_files in (glob("{}/*.py".format(dir)) for dir in test_dirs) @@ -95,7 +150,7 @@ def main(): continue test_dict[m.group(1)].append([t, None]) - if not run_tests(pyb, test_dict): + if not run_tests(pyb, test_dict, args.iters): sys.exit(1) diff --git a/tests/run-multitests.py b/tests/run-multitests.py index 93a6d3844d2..e5458ffe0d0 100755 --- a/tests/run-multitests.py +++ b/tests/run-multitests.py @@ -15,6 +15,8 @@ import subprocess import tempfile +run_tests_module = __import__("run-tests") + test_dir = os.path.abspath(os.path.dirname(__file__)) if os.path.abspath(sys.path[0]) == test_dir: @@ -105,15 +107,14 @@ def output_metric(data): multitest.flush() """ -# The btstack implementation on Unix generates some spurious output that we -# can't control. Also other platforms may output certain warnings/errors that -# can be safely ignored. +# Some ports generate output we can't control, and that can be safely ignored. IGNORE_OUTPUT_MATCHES = ( - "libusb: error ", # It tries to open devices that it doesn't have access to (libusb prints unconditionally). + "libusb: error ", # unix btstack tries to open devices that it doesn't have access to (libusb prints unconditionally). "hci_transport_h2_libusb.c", # Same issue. We enable LOG_ERROR in btstack. - "USB Path: ", # Hardcoded in btstack's libusb transport. - "hci_number_completed_packet", # Warning from btstack. + "USB Path: ", # Hardcoded in unix btstack's libusb transport. + "hci_number_completed_packet", # Warning from unix btstack. "lld_pdu_get_tx_flush_nb HCI packet count mismatch (", # From ESP-IDF, see https://github.com/espressif/esp-idf/issues/5105 + " ets_task(", # ESP8266 port debug output ) @@ -131,6 +132,11 @@ def get_host_ip(_ip_cache=[]): return _ip_cache[0] +def decode(output): + # Convenience function to convert raw process or serial output to ASCII + return str(output, "ascii", "backslashreplace") + + class PyInstance: def __init__(self): pass @@ -189,7 +195,7 @@ def run_script(self, script): output = p.stdout except subprocess.CalledProcessError as er: err = er - return str(output.strip(), "ascii"), err + return decode(output.strip()), err def start_script(self, script): self.popen = subprocess.Popen( @@ -216,7 +222,7 @@ def readline(self): self.finished = self.popen.poll() is not None return None, None else: - return str(out.rstrip(), "ascii"), None + return decode(out.rstrip()), None def write(self, data): self.popen.stdin.write(data) @@ -228,21 +234,12 @@ def is_finished(self): def wait_finished(self): self.popen.wait() out = self.popen.stdout.read() - return str(out, "ascii"), "" + return decode(out), "" class PyInstancePyboard(PyInstance): - @staticmethod - def map_device_shortcut(device): - if device[0] == "a" and device[1:].isdigit(): - return "/dev/ttyACM" + device[1:] - elif device[0] == "u" and device[1:].isdigit(): - return "/dev/ttyUSB" + device[1:] - else: - return device - def __init__(self, device): - device = self.map_device_shortcut(device) + device = device self.device = device self.pyb = pyboard.Pyboard(device) self.pyb.enter_raw_repl() @@ -263,7 +260,7 @@ def run_script(self, script): output = self.pyb.exec_(script) except pyboard.PyboardError as er: err = er - return str(output.strip(), "ascii"), err + return decode(output.strip()), err def start_script(self, script): self.pyb.enter_raw_repl() @@ -282,13 +279,13 @@ def readline(self): if out.endswith(b"\x04"): self.finished = True out = out[:-1] - err = str(self.pyb.read_until(1, b"\x04"), "ascii") + err = decode(self.pyb.read_until(1, b"\x04")) err = err[:-1] if not out and not err: return None, None else: err = None - return str(out.rstrip(), "ascii"), err + return decode(out.rstrip()), err def write(self, data): self.pyb.serial.write(data) @@ -298,7 +295,7 @@ def is_finished(self): def wait_finished(self): out, err = self.pyb.follow(10, None) - return str(out, "ascii"), str(err, "ascii") + return decode(out), decode(err) def prepare_test_file_list(test_files): @@ -489,9 +486,7 @@ def print_diff(a, b): def run_tests(test_files, instances_truth, instances_test): - skipped_tests = [] - passed_tests = [] - failed_tests = [] + test_results = [] for test_file, num_instances in test_files: instances_str = "|".join(str(instances_test[i]) for i in range(num_instances)) @@ -527,13 +522,13 @@ def run_tests(test_files, instances_truth, instances_test): # Print result of test if skip: print("skip") - skipped_tests.append(test_file) + test_results.append((test_file, "skip", "")) elif output_test == output_truth: print("pass") - passed_tests.append(test_file) + test_results.append((test_file, "pass", "")) else: print("FAIL") - failed_tests.append(test_file) + test_results.append((test_file, "fail", "")) if not cmd_args.show_output: print("### TEST ###") print(output_test, end="") @@ -550,15 +545,7 @@ def run_tests(test_files, instances_truth, instances_test): if cmd_args.show_output: print() - print("{} tests performed".format(len(skipped_tests) + len(passed_tests) + len(failed_tests))) - print("{} tests passed".format(len(passed_tests))) - - if skipped_tests: - print("{} tests skipped: {}".format(len(skipped_tests), " ".join(skipped_tests))) - if failed_tests: - print("{} tests failed: {}".format(len(failed_tests), " ".join(failed_tests))) - - return not failed_tests + return test_results def main(): @@ -566,16 +553,24 @@ def main(): cmd_parser = argparse.ArgumentParser( description="Run network tests for MicroPython", + epilog=( + run_tests_module.test_instance_epilog + + "Each instance arg can optionally have custom env provided, eg. ,ENV=VAR,ENV=VAR...\n" + ), formatter_class=argparse.RawTextHelpFormatter, ) cmd_parser.add_argument( "-s", "--show-output", action="store_true", help="show test output after running" ) cmd_parser.add_argument( - "-t", "--trace-output", action="store_true", help="trace test output while running" + "-c", "--trace-output", action="store_true", help="trace test output while running" ) cmd_parser.add_argument( - "-i", "--instance", action="append", default=[], help="instance(s) to run the tests on" + "-t", + "--test-instance", + action="append", + default=[], + help="instance(s) to run the tests on", ) cmd_parser.add_argument( "-p", @@ -584,13 +579,11 @@ def main(): default=1, help="repeat the test with this many permutations of the instance order", ) - cmd_parser.epilog = ( - "Supported instance types:\r\n" - " -i pyb: physical device (eg. pyboard) on provided repl port.\n" - " -i micropython unix micropython instance, path customised with MICROPY_MICROPYTHON env.\n" - " -i cpython desktop python3 instance, path customised with MICROPY_CPYTHON3 env.\n" - " -i exec: custom program run on provided path.\n" - "Each instance arg can optionally have custom env provided, eg. ,ENV=VAR,ENV=VAR...\n" + cmd_parser.add_argument( + "-r", + "--result-dir", + default=run_tests_module.base_path("results"), + help="directory for test results", ) cmd_parser.add_argument("files", nargs="+", help="input test files") cmd_args = cmd_parser.parse_args() @@ -604,33 +597,36 @@ def main(): instances_truth = [PyInstanceSubProcess([PYTHON_TRUTH]) for _ in range(max_instances)] instances_test = [] - for i in cmd_args.instance: + for i in cmd_args.test_instance: # Each instance arg is ,ENV=VAR,ENV=VAR... i = i.split(",") cmd = i[0] env = i[1:] if cmd.startswith("exec:"): instances_test.append(PyInstanceSubProcess([cmd[len("exec:") :]], env)) - elif cmd == "micropython": + elif cmd == "unix": instances_test.append(PyInstanceSubProcess([MICROPYTHON], env)) elif cmd == "cpython": instances_test.append(PyInstanceSubProcess([CPYTHON3], env)) - elif cmd.startswith("pyb:"): - instances_test.append(PyInstancePyboard(cmd[len("pyb:") :])) + elif cmd == "webassembly" or cmd.startswith("execpty:"): + print("unsupported instance string: {}".format(cmd), file=sys.stderr) + sys.exit(2) else: - print("unknown instance string: {}".format(cmd), file=sys.stderr) - sys.exit(1) + device = run_tests_module.convert_device_shortcut_to_real_device(cmd) + instances_test.append(PyInstancePyboard(device)) for _ in range(max_instances - len(instances_test)): instances_test.append(PyInstanceSubProcess([MICROPYTHON])) + os.makedirs(cmd_args.result_dir, exist_ok=True) all_pass = True try: for i, instances_test_permutation in enumerate(itertools.permutations(instances_test)): if i >= cmd_args.permutations: break - all_pass &= run_tests(test_files, instances_truth, instances_test_permutation) + test_results = run_tests(test_files, instances_truth, instances_test_permutation) + all_pass &= run_tests_module.create_test_report(cmd_args, test_results) finally: for i in instances_truth: diff --git a/tests/run-natmodtests.py b/tests/run-natmodtests.py index 24acd327c03..6d2a975b82a 100755 --- a/tests/run-natmodtests.py +++ b/tests/run-natmodtests.py @@ -9,7 +9,7 @@ import sys import argparse -#CIRCUITPY-CHANGE: no pyboard +run_tests_module = __import__("run-tests") # Paths for host executables CPYTHON3 = os.getenv("MICROPY_CPYTHON3", "python3") @@ -17,7 +17,7 @@ NATMOD_EXAMPLE_DIR = "../examples/natmod/" -#CIRCUITPY-CHANGE: different TEST_MAPPINGS +# CIRCUITPY-CHANGE: different TEST_MAPPINGS # Supported tests and their corresponding mpy module TEST_MAPPINGS = { "heapq": "heapq/heapq_$(ARCH).mpy", @@ -25,6 +25,23 @@ "re": "re/re_$(ARCH).mpy", } +# Supported architectures for native mpy modules +AVAILABLE_ARCHS = ( + "x86", + "x64", + "armv6", + "armv6m", + "armv7m", + "armv7em", + "armv7emsp", + "armv7emdp", + "xtensa", + "xtensawin", + "rv32imc", +) + +ARCH_MAPPINGS = {"armv7em": "armv7m"} + # Code to allow a target MicroPython to import an .mpy from RAM injected_import_hook_code = """\ # CIRCUITPY-CHANGE: no vfs, but still have os @@ -33,7 +50,9 @@ class __File(io.IOBase): def __init__(self): self.off = 0 def ioctl(self, request, arg): - return 0 + if request == 4: # MP_STREAM_CLOSE + return 0 + return -1 def readinto(self, buf): buf[:] = memoryview(__buf)[self.off:self.off + len(buf)] self.off += len(buf) @@ -53,6 +72,7 @@ def open(self, path, mode): # CIRCUITPY-CHANGE: no vfs, but still have os os.mount(__FS(), '/__remote') sys.path.insert(0, '/__remote') +{import_prelude} sys.modules['{}'] = __import__('__injected') """ @@ -89,18 +109,45 @@ def run_script(self, script): output = self.pyb.exec_(script) output = output.replace(b"\r\n", b"\n") return output, None - except pyboard.PyboardError as er: + except run_tests_module.pyboard.PyboardError as er: return b"", er -def run_tests(target_truth, target, args, stats): +def detect_architecture(target): + with open("./feature_check/target_info.py", "rb") as f: + target_info_data = f.read() + result_out, error = target.run_script(target_info_data) + if error is not None: + return None, None, error + info = result_out.split(b" ") + if len(info) < 2: + return None, None, "unexpected target info: {}".format(info) + platform = info[0].strip().decode() + arch = info[1].strip().decode() + if arch not in AVAILABLE_ARCHS: + if arch == "None": + return None, None, "the target does not support dynamic modules" + else: + return None, None, "{} is not a supported architecture".format(arch) + return platform, arch, None + + +def run_tests(target_truth, target, args, resolved_arch): + global injected_import_hook_code + + prelude = "" + if args.begin: + prelude = args.begin.read() + injected_import_hook_code = injected_import_hook_code.replace("{import_prelude}", prelude) + + test_results = [] for test_file in args.files: # Find supported test test_file_basename = os.path.basename(test_file) for k, v in TEST_MAPPINGS.items(): if test_file_basename.startswith(k): test_module = k - test_mpy = v.replace("$(ARCH)", args.arch) + test_mpy = v.replace("$(ARCH)", resolved_arch) break else: print("---- {} - no matching mpy".format(test_file)) @@ -116,9 +163,11 @@ def run_tests(target_truth, target, args, stats): with open(NATMOD_EXAMPLE_DIR + test_mpy, "rb") as f: test_script += b"__buf=" + bytes(repr(f.read()), "ascii") + b"\n" except OSError: - print("---- {} - mpy file not compiled".format(test_file)) + test_results.append((test_file, "skip", "mpy file not compiled")) + print("skip {} - mpy file not compiled".format(test_file)) continue test_script += bytes(injected_import_hook_code.format(test_module), "ascii") + test_script += b"print('START TEST')\n" test_script += test_file_data # Run test under MicroPython @@ -126,8 +175,18 @@ def run_tests(target_truth, target, args, stats): # Work out result of test extra = "" + result_out = result_out.removeprefix(b"START TEST\n") if error is None and result_out == b"SKIP\n": result = "SKIP" + elif ( + error is not None + and error.args[0] == "exception" + and error.args[1] == b"" + and b"MemoryError" in error.args[2] + ): + # Test had a MemoryError before anything (should be at least "START TEST") + # was printed, so the test is too big for the target. + result = "LRGE" elif error is not None: result = "FAIL" extra = " - " + str(error) @@ -148,55 +207,86 @@ def run_tests(target_truth, target, args, stats): result = "pass" # Accumulate statistics - stats["total"] += 1 if result == "pass": - stats["pass"] += 1 + test_results.append((test_file, "pass", "")) elif result == "SKIP": - stats["skip"] += 1 + test_results.append((test_file, "skip", "")) + elif result == "LRGE": + test_results.append((test_file, "skip", "too large")) else: - stats["fail"] += 1 + test_results.append((test_file, "fail", "")) # Print result print("{:4} {}{}".format(result, test_file, extra)) + return test_results + def main(): cmd_parser = argparse.ArgumentParser( - description="Run dynamic-native-module tests under MicroPython" + description="Run dynamic-native-module tests under MicroPython", + epilog=run_tests_module.test_instance_epilog, + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + cmd_parser.add_argument( + "-t", "--test-instance", default="unix", help="the MicroPython instance to test" ) + cmd_parser.add_argument("--baudrate", default=115200, help="baud rate of the serial device") + cmd_parser.add_argument("--user", default="micro", help="telnet login username") + cmd_parser.add_argument("--password", default="python", help="telnet login password") cmd_parser.add_argument( - "-p", "--pyboard", action="store_true", help="run tests via pyboard.py" + "-a", "--arch", choices=AVAILABLE_ARCHS, help="override native architecture of the target" ) cmd_parser.add_argument( - "-d", "--device", default="/dev/ttyACM0", help="the device for pyboard.py" + "-b", + "--begin", + type=argparse.FileType("rt"), + default=None, + help="prologue python file to execute before module import", ) cmd_parser.add_argument( - "-a", "--arch", default="x64", help="native architecture of the target" + "-r", + "--result-dir", + default=run_tests_module.base_path("results"), + help="directory for test results", ) cmd_parser.add_argument("files", nargs="*", help="input test files") args = cmd_parser.parse_args() target_truth = TargetSubprocess([CPYTHON3]) - if args.pyboard: - target = TargetPyboard(pyboard.Pyboard(args.device)) - else: + target = run_tests_module.get_test_instance( + args.test_instance, args.baudrate, args.user, args.password + ) + if target is None: + # Use the unix port of MicroPython. target = TargetSubprocess([MICROPYTHON]) + else: + # Use a remote target. + target = TargetPyboard(target) - stats = {"total": 0, "pass": 0, "fail": 0, "skip": 0} - run_tests(target_truth, target, args, stats) + if hasattr(args, "arch") and args.arch is not None: + target_arch = args.arch + target_platform = None + else: + target_platform, target_arch, error = detect_architecture(target) + if error: + print("Cannot run tests: {}".format(error)) + sys.exit(1) + target_arch = ARCH_MAPPINGS.get(target_arch, target_arch) + + if target_platform: + print("platform={} ".format(target_platform), end="") + print("arch={}".format(target_arch)) + + os.makedirs(args.result_dir, exist_ok=True) + test_results = run_tests(target_truth, target, args, target_arch) + res = run_tests_module.create_test_report(args, test_results) target.close() target_truth.close() - print("{} tests performed".format(stats["total"])) - print("{} tests passed".format(stats["pass"])) - if stats["fail"]: - print("{} tests failed".format(stats["fail"])) - if stats["skip"]: - print("{} tests skipped".format(stats["skip"])) - - if stats["fail"]: + if not res: sys.exit(1) diff --git a/tests/run-perfbench.py b/tests/run-perfbench.py index 81d873c4599..039d11a3611 100755 --- a/tests/run-perfbench.py +++ b/tests/run-perfbench.py @@ -10,10 +10,9 @@ import argparse from glob import glob -sys.path.append("../tools") -import pyboard +run_tests_module = __import__("run-tests") -prepare_script_for_target = __import__("run-tests").prepare_script_for_target +prepare_script_for_target = run_tests_module.prepare_script_for_target # Paths for host executables if os.name == "nt": @@ -45,12 +44,12 @@ def run_script_on_target(target, script): output = b"" err = None - if isinstance(target, pyboard.Pyboard): + if hasattr(target, "enter_raw_repl"): # Run via pyboard interface try: target.enter_raw_repl() output = target.exec_(script) - except pyboard.PyboardError as er: + except run_tests_module.pyboard.PyboardError as er: err = er else: # Run local executable @@ -90,9 +89,9 @@ def run_benchmark_on_target(target, script): def run_benchmarks(args, target, param_n, param_m, n_average, test_list): + test_results = [] skip_complex = run_feature_test(target, "complex") != "complex" skip_native = run_feature_test(target, "native_check") != "native" - target_had_error = False for test_file in sorted(test_list): print(test_file + ": ", end="") @@ -105,6 +104,7 @@ def run_benchmarks(args, target, param_n, param_m, n_average, test_list): and test_file.find("viper_") != -1 ) if skip: + test_results.append((test_file, "skip", "")) print("SKIP") continue @@ -122,9 +122,10 @@ def run_benchmarks(args, target, param_n, param_m, n_average, test_list): f.write(test_script) # Process script through mpy-cross if needed - if isinstance(target, pyboard.Pyboard) or args.via_mpy: + if hasattr(target, "enter_raw_repl") or args.via_mpy: crash, test_script_target = prepare_script_for_target(args, script_text=test_script) if crash: + test_results.append((test_file, "fail", "preparation")) print("CRASH:", test_script_target) continue else: @@ -162,10 +163,13 @@ def run_benchmarks(args, target, param_n, param_m, n_average, test_list): error = "FAIL truth" if error is not None: - if not error.startswith("SKIP"): - target_had_error = True + if error.startswith("SKIP"): + test_results.append((test_file, "skip", error)) + else: + test_results.append((test_file, "fail", error)) print(error) else: + test_results.append((test_file, "pass", "")) t_avg, t_sd = compute_stats(times) s_avg, s_sd = compute_stats(scores) print( @@ -179,7 +183,7 @@ def run_benchmarks(args, target, param_n, param_m, n_average, test_list): sys.stdout.flush() - return target_had_error + return test_results def parse_output(filename): @@ -190,7 +194,13 @@ def parse_output(filename): m = int(m.split("=")[1]) data = [] for l in f: - if ": " in l and ": SKIP" not in l and "CRASH: " not in l: + if ( + ": " in l + and ": SKIP" not in l + and "CRASH: " not in l + and "skipped: " not in l + and "failed: " not in l + ): name, values = l.strip().split(": ") values = tuple(float(v) for v in values.split()) data.append((name,) + values) @@ -246,17 +256,17 @@ def compute_diff(file1, file2, diff_score): def main(): cmd_parser = argparse.ArgumentParser(description="Run benchmarks for MicroPython") cmd_parser.add_argument( - "-t", "--diff-time", action="store_true", help="diff time outputs from a previous run" + "-m", "--diff-time", action="store_true", help="diff time outputs from a previous run" ) cmd_parser.add_argument( "-s", "--diff-score", action="store_true", help="diff score outputs from a previous run" ) cmd_parser.add_argument( - "-p", "--pyboard", action="store_true", help="run tests via pyboard.py" - ) - cmd_parser.add_argument( - "-d", "--device", default="/dev/ttyACM0", help="the device for pyboard.py" + "-t", "--test-instance", default="unix", help="the MicroPython instance to test" ) + cmd_parser.add_argument("--baudrate", default=115200, help="baud rate of the serial device") + cmd_parser.add_argument("--user", default="micro", help="telnet login username") + cmd_parser.add_argument("--password", default="python", help="telnet login password") cmd_parser.add_argument("-a", "--average", default="8", help="averaging number") cmd_parser.add_argument( "--emit", default="bytecode", help="MicroPython emitter to use (bytecode or native)" @@ -264,6 +274,12 @@ def main(): cmd_parser.add_argument("--heapsize", help="heapsize to use (use default if not specified)") cmd_parser.add_argument("--via-mpy", action="store_true", help="compile code to .mpy first") cmd_parser.add_argument("--mpy-cross-flags", default="", help="flags to pass to mpy-cross") + cmd_parser.add_argument( + "-r", + "--result-dir", + default=run_tests_module.base_path("results"), + help="directory for test results", + ) cmd_parser.add_argument( "N", nargs=1, help="N parameter (approximate target CPU frequency in MHz)" ) @@ -282,15 +298,18 @@ def main(): M = int(args.M[0]) n_average = int(args.average) - if args.pyboard: - if not args.mpy_cross_flags: - args.mpy_cross_flags = "-march=armv7m" - target = pyboard.Pyboard(args.device) - target.enter_raw_repl() - else: + target = run_tests_module.get_test_instance( + args.test_instance, args.baudrate, args.user, args.password + ) + if target is None: + # Use the unix port of MicroPython. target = [MICROPYTHON, "-X", "emit=" + args.emit] if args.heapsize is not None: target.extend(["-X", "heapsize=" + args.heapsize]) + else: + # Use a remote target. + if not args.mpy_cross_flags: + args.mpy_cross_flags = "-march=armv7m" if len(args.files) == 0: tests_skip = ("benchrun.py",) @@ -307,13 +326,15 @@ def main(): print("N={} M={} n_average={}".format(N, M, n_average)) - target_had_error = run_benchmarks(args, target, N, M, n_average, tests) + os.makedirs(args.result_dir, exist_ok=True) + test_results = run_benchmarks(args, target, N, M, n_average, tests) + res = run_tests_module.create_test_report(args, test_results) - if isinstance(target, pyboard.Pyboard): + if hasattr(target, "exit_raw_repl"): target.exit_raw_repl() target.close() - if target_had_error: + if not res: sys.exit(1) diff --git a/tests/run-tests-exp.py b/tests/run-tests-exp.py deleted file mode 100644 index bbb057f4ced..00000000000 --- a/tests/run-tests-exp.py +++ /dev/null @@ -1,94 +0,0 @@ -# -# This is minimal MicroPython variant of run-tests.py script, which uses -# .exp files as generated by run-tests.py --write-exp. It is useful to run -# testsuite on systems which have neither CPython3 nor unix shell. -# This script is intended to be run by the same interpreter executable -# which is to be tested, so should use minimal language functionality. -# -import sys -import os - - -tests = ["basics", "micropython", "float", "import", "io", " misc", "unicode", "extmod", "unix"] - -if sys.platform == "win32": - MICROPYTHON = "micropython.exe" -else: - MICROPYTHON = "micropython" - - -def should_skip(test): - if test.startswith("native"): - return True - if test.startswith("viper"): - return True - - -test_count = 0 -passed_count = 0 -skip_count = 0 - -for suite in tests: - # print("Running in: %s" % suite) - if sys.platform == "win32": - # dir /b prints only contained filenames, one on a line - # http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/dir.mspx - r = os.system("dir /b %s/*.py >tests.lst" % suite) - else: - r = os.system("ls %s/*.py | xargs -n1 basename >tests.lst" % suite) - assert r == 0 - - with open("tests.lst") as f: - testcases = f.readlines() - testcases = [l[:-1] for l in testcases] - assert testcases, "No tests found in dir '%s', which is implausible" % suite - # print(testcases) - for t in testcases: - if t == "native_check.py": - continue - - qtest = "%s/%s" % (suite, t) - - if should_skip(t): - print("skip " + qtest) - skip_count += 1 - continue - - exp = None - try: - f = open(qtest + ".exp") - exp = f.read() - f.close() - except OSError: - pass - - if exp is not None: - # print("run " + qtest) - r = os.system(MICROPYTHON + " %s >.tst.out" % qtest) - if r == 0: - f = open(".tst.out") - out = f.read() - f.close() - else: - out = "CRASH" - - if out == "SKIP\n": - print("skip " + qtest) - skip_count += 1 - else: - if out == exp: - print("pass " + qtest) - passed_count += 1 - else: - print("FAIL " + qtest) - - test_count += 1 - else: - skip_count += 1 - -print("%s tests performed" % test_count) -print("%s tests passed" % passed_count) -if test_count != passed_count: - print("%s tests failed" % (test_count - passed_count)) -if skip_count: - print("%s tests skipped" % skip_count) diff --git a/tests/run-tests-exp.sh b/tests/run-tests-exp.sh deleted file mode 100755 index 177090cd8db..00000000000 --- a/tests/run-tests-exp.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh -# -# This is plain shell variant of run-tests.py script, which uses .exp files -# as generated by run-tests.py --write-exp. It is useful to run testsuite -# on embedded systems which don't have CPython3. -# - -RM="rm -f" -MP_PY=micropython - -numtests=0 -numtestcases=0 -numpassed=0 -numskipped=0 -numfailed=0 -nameskipped= -namefailed= - -if [ $# -eq 0 ] -then - tests="basics/*.py micropython/*.py float/*.py import/*.py io/*.py misc/*.py unicode/*.py extmod/*.py unix/*.py" -else - tests="$@" -fi - -for infile in $tests -do - basename=`basename $infile .py` - outfile=${basename}.py.out - expfile=$infile.exp - - $MP_PY $infile > $outfile - numtestcases=$(expr $numtestcases + $(cat $expfile | wc -l)) - - if grep -q "SKIP\|SyntaxError: invalid micropython decorator" $outfile - then - # we don't count tests that explicitly ask to be skipped - # we don't count tests that fail due to unsupported decorator - echo "skip $infile" - $RM $outfile - numskipped=$(expr $numskipped + 1) - nameskipped="$nameskipped $basename" - else - diff --brief $expfile $outfile > /dev/null - - if [ $? -eq 0 ] - then - echo "pass $infile" - $RM $outfile - numpassed=$(expr $numpassed + 1) - else - echo "FAIL $infile" - numfailed=$(expr $numfailed + 1) - namefailed="$namefailed $basename" - fi - fi - - numtests=$(expr $numtests + 1) -done - -echo "$numtests tests performed ($numtestcases individual testcases)" -echo "$numpassed tests passed" -if [ $numskipped != 0 ] -then - echo "$numskipped tests skipped -$nameskipped" -fi -if [ $numfailed != 0 ] -then - echo "$numfailed tests failed -$namefailed" - exit 1 -else - exit 0 -fi diff --git a/tests/run-tests.py b/tests/run-tests.py index 3b7bca64cce..71570292ce7 100755 --- a/tests/run-tests.py +++ b/tests/run-tests.py @@ -3,6 +3,7 @@ import os import subprocess import sys +import sysconfig import platform import argparse import inspect @@ -14,13 +15,15 @@ import threading import tempfile -# Maximum time to run a PC-based test, in seconds. -TEST_TIMEOUT = 30 +# Maximum time to run a single test, in seconds. +TEST_TIMEOUT = float(os.environ.get("MICROPY_TEST_TIMEOUT", 30)) # See stackoverflow.com/questions/2632199: __file__ nor sys.argv[0] # are guaranteed to always work, this one should though. BASEPATH = os.path.dirname(os.path.abspath(inspect.getsourcefile(lambda: None))) +RV32_ARCH_FLAGS = {"zba": 1 << 0} + def base_path(*p): return os.path.abspath(os.path.join(BASEPATH, *p)).replace("\\", "/") @@ -57,14 +60,38 @@ def base_path(*p): # Set PYTHONIOENCODING so that CPython will use utf-8 on systems which set another encoding in the locale os.environ["PYTHONIOENCODING"] = "utf-8" + +def normalize_newlines(data): + """Normalize newline variations to \\n. + + Only normalizes actual line endings, not literal \\r characters in strings. + Handles \\r\\r\\n and \\r\\n cases to ensure consistent comparison + across different platforms and terminals. + """ + if isinstance(data, bytes): + # Handle PTY double-newline issue first + data = data.replace(b"\r\r\n", b"\n") + # Then handle standard Windows line endings + data = data.replace(b"\r\n", b"\n") + # Don't convert standalone \r as it might be literal content + return data + + # Code to allow a target MicroPython to import an .mpy from RAM +# Note: the module is named `__injected_test` but it needs to have `__name__` set to +# `__main__` so that the test sees itself as the main module, eg so unittest works. injected_import_hook_code = """\ import sys, os, io, vfs class __File(io.IOBase): def __init__(self): + module = sys.modules['__injected_test'] + module.__name__ = '__main__' + sys.modules['__main__'] = module self.off = 0 def ioctl(self, request, arg): - return 0 + if request == 4: # MP_STREAM_CLOSE + return 0 + return -1 def readinto(self, buf): buf[:] = memoryview(__buf)[self.off:self.off + len(buf)] self.off += len(buf) @@ -76,18 +103,235 @@ def umount(self): pass def chdir(self, path): pass + def getcwd(self): + return "" def stat(self, path): if path == '__injected_test.mpy': - return tuple(0 for _ in range(10)) + return (0,0,0,0,0,0,0,0,0,0) else: - raise OSError(-2) # ENOENT + raise OSError(2) # ENOENT def open(self, path, mode): + self.stat(path) return __File() vfs.mount(__FS(), '/__vfstest') os.chdir('/__vfstest') +{import_prologue} __import__('__injected_test') """ +# Platforms associated with the unix port, values of `sys.platform`. +PC_PLATFORMS = ("darwin", "linux", "win32") + +# Mapping from `sys.platform` to the port name, for special cases. +# See `platform_to_port()` function. +platform_to_port_map = {"pyboard": "stm32", "WiPy": "cc3200"} +platform_to_port_map.update({p: "unix" for p in PC_PLATFORMS}) + +# Tests to skip for values of the `--via-mpy` argument. +via_mpy_tests_to_skip = { + # Skip the following when mpy is enabled. + True: ( + # These print out the filename and that's expected to match the .py name. + "import/import_file.py", + "io/argv.py", + "misc/sys_settrace_features.py", + "misc/sys_settrace_generator.py", + "misc/sys_settrace_loop.py", + ), +} + +# Tests to skip for specific emitters. +emitter_tests_to_skip = { + # Some tests are known to fail with native emitter. + # Remove them from the below when they work. + "native": ( + # These require raise_varargs. + "basics/gen_yield_from_close.py", + "basics/try_finally_return2.py", + "basics/try_reraise.py", + "basics/try_reraise2.py", + "misc/features.py", + # These require checking for unbound local. + "basics/annotate_var.py", + "basics/del_deref.py", + "basics/del_local.py", + "basics/scope_implicit.py", + "basics/unboundlocal.py", + # These require "raise from". + "basics/exception_chain.py", + # These require stack-allocated slice optimisation. + "micropython/heapalloc_slice.py", + # These require running the scheduler. + "micropython/schedule.py", + "extmod/asyncio_event_queue.py", + "extmod/asyncio_iterator_event.py", + # These require sys.exc_info(). + "misc/sys_exc_info.py", + # These require sys.settrace(). + "misc/sys_settrace_cov.py", + "misc/sys_settrace_features.py", + "misc/sys_settrace_generator.py", + "misc/sys_settrace_loop.py", + # These are bytecode-specific tests. + "stress/bytecode_limit.py", + ), +} + +# Tests to skip on specific targets. +# These are tests that are difficult to detect that they should not be run on the given target. +platform_tests_to_skip = { + "minimal": ( + "basics/class_inplace_op.py", # all special methods not supported + "basics/subclass_native_init.py", # native subclassing corner cases not support + "micropython/opt_level.py", # don't assume line numbers are stored + ), + "nrf": ( + "basics/io_buffered_writer.py", + "basics/io_bytesio_cow.py", + "basics/io_bytesio_ext.py", + "basics/io_bytesio_ext2.py", + "basics/io_iobase.py", + "basics/io_stringio1.py", + "basics/io_stringio_base.py", + "basics/io_stringio_with.py", + "basics/io_write_ext.py", + "basics/memoryview1.py", # no item assignment for memoryview + "extmod/random_basic.py", # unimplemented: random.seed + "micropython/opt_level.py", # no support for line numbers + "misc/non_compliant.py", # no item assignment for bytearray + ), + "renesas-ra": ( + "extmod/time_time_ns.py", # RA fsp rtc function doesn't support nano sec info + ), + "rp2": ( + # Skip thread tests that require more that 2 threads. + "thread/stress_heap.py", + "thread/thread_lock2.py", + "thread/thread_lock3.py", + "thread/thread_shared2.py", + ), + "webassembly": ( + "basics/string_format_modulo.py", # can't print nulls to stdout + "basics/string_strip.py", # can't print nulls to stdout + "extmod/asyncio_basic2.py", + "extmod/asyncio_cancel_self.py", + "extmod/asyncio_current_task.py", + "extmod/asyncio_exception.py", + "extmod/asyncio_gather_finished_early.py", + "extmod/asyncio_get_event_loop.py", + "extmod/asyncio_heaplock.py", + "extmod/asyncio_loop_stop.py", + "extmod/asyncio_new_event_loop.py", + "extmod/asyncio_threadsafeflag.py", + "extmod/asyncio_wait_for_fwd.py", + "extmod/asyncio_event_queue.py", + "extmod/asyncio_iterator_event.py", + "extmod/asyncio_wait_for_linked_task.py", + "extmod/binascii_a2b_base64.py", + "extmod/deflate_compress_memory_error.py", # tries to allocate unlimited memory + "extmod/re_stack_overflow.py", + "extmod/time_res.py", + "extmod/vfs_posix.py", + "extmod/vfs_posix_enoent.py", + "extmod/vfs_posix_paths.py", + "extmod/vfs_userfs.py", + "micropython/emg_exc.py", + "micropython/extreme_exc.py", + "micropython/heapalloc_exc_compressed_emg_exc.py", + ), + "WiPy": ( + "misc/print_exception.py", # requires error reporting full + ), + "zephyr": ( + # Skip thread tests that require more than 4 threads. + "thread/stress_heap.py", + "thread/thread_lock3.py", + ), +} + +# These tests don't test float explicitly but rather use it to perform the test. +tests_requiring_float = ( + "extmod/asyncio_basic.py", + "extmod/asyncio_basic2.py", + "extmod/asyncio_cancel_task.py", + "extmod/asyncio_event.py", + "extmod/asyncio_fair.py", + "extmod/asyncio_gather.py", + "extmod/asyncio_gather_notimpl.py", + "extmod/asyncio_get_event_loop.py", + "extmod/asyncio_iterator_event.py", + "extmod/asyncio_lock.py", + "extmod/asyncio_task_done.py", + "extmod/asyncio_wait_for.py", + "extmod/asyncio_wait_for_fwd.py", + "extmod/asyncio_wait_for_linked_task.py", + "extmod/asyncio_wait_task.py", + "extmod/json_dumps_float.py", + "extmod/json_loads_float.py", + "extmod/random_extra_float.py", + "extmod/select_poll_eintr.py", + "extmod/tls_threads.py", + "extmod/uctypes_le_float.py", + "extmod/uctypes_native_float.py", + "extmod/uctypes_sizeof_float.py", + "misc/rge_sm.py", + "ports/unix/ffi_float.py", + "ports/unix/ffi_float2.py", +) + +# These tests don't test slice explicitly but rather use it to perform the test. +tests_requiring_slice = ( + "basics/builtin_range.py", + "basics/bytearray1.py", + "basics/class_super.py", + "basics/containment.py", + "basics/errno1.py", + "basics/fun_str.py", + "basics/generator1.py", + "basics/globals_del.py", + "basics/memoryview1.py", + "basics/memoryview_gc.py", + "basics/object1.py", + "basics/python34.py", + "basics/struct_endian.py", + "extmod/btree1.py", + "extmod/deflate_decompress.py", + "extmod/framebuf16.py", + "extmod/framebuf4.py", + "extmod/machine1.py", + "extmod/time_mktime.py", + "extmod/time_res.py", + "extmod/tls_sslcontext_ciphers.py", + "extmod/vfs_fat_fileio1.py", + "extmod/vfs_fat_finaliser.py", + "extmod/vfs_fat_more.py", + "extmod/vfs_fat_ramdisk.py", + "extmod/vfs_fat_ramdisklarge.py", + "extmod/vfs_lfs.py", + "extmod/vfs_rom.py", + "float/string_format_modulo.py", + "micropython/builtin_execfile.py", + "micropython/extreme_exc.py", + "micropython/heapalloc_fail_bytearray.py", + "micropython/heapalloc_fail_list.py", + "micropython/heapalloc_fail_memoryview.py", + "micropython/import_mpy_invalid.py", + "micropython/import_mpy_native.py", + "micropython/import_mpy_native_gc.py", + "misc/non_compliant.py", + "misc/rge_sm.py", +) + +# Tests that require `import target_wiring` to work. +tests_requiring_target_wiring = ( + "extmod/machine_uart_irq_txidle.py", + "extmod/machine_uart_tx.py", + "extmod_hardware/machine_encoder.py", + "extmod_hardware/machine_uart_irq_break.py", + "extmod_hardware/machine_uart_irq_rx.py", + "extmod_hardware/machine_uart_irq_rxidle.py", +) + def rm_f(fname): if os.path.exists(fname): @@ -114,22 +358,158 @@ def convert_regex_escapes(line): return bytes("".join(cs), "utf8") -def prepare_script_for_target(args, *, script_filename=None, script_text=None, force_plain=False): +def platform_to_port(platform): + return platform_to_port_map.get(platform, platform) + + +def convert_device_shortcut_to_real_device(device): + if device.startswith("port:"): + return device.split(":", 1)[1] + elif device.startswith("a") and device[1:].isdigit(): + return "/dev/ttyACM" + device[1:] + elif device.startswith("u") and device[1:].isdigit(): + return "/dev/ttyUSB" + device[1:] + elif device.startswith("c") and device[1:].isdigit(): + return "COM" + device[1:] + else: + return device + + +def get_test_instance(test_instance, baudrate, user, password): + if test_instance == "unix": + return None + elif test_instance == "webassembly": + return PyboardNodeRunner() + else: + # Assume it's a device path. + port = convert_device_shortcut_to_real_device(test_instance) + + global pyboard + sys.path.append(base_path("../tools")) + import pyboard + + pyb = pyboard.Pyboard(port, baudrate, user, password) + pyboard.Pyboard.run_script_on_remote_target = run_script_on_remote_target + pyb.enter_raw_repl() + return pyb + + +def detect_inline_asm_arch(pyb, args): + for arch in ("rv32", "thumb", "xtensa"): + output = run_feature_check(pyb, args, "inlineasm_{}.py".format(arch)) + if output.strip() == arch.encode(): + return arch + return None + + +def map_rv32_arch_flags(flags): + mapped_flags = [] + for extension, bit in RV32_ARCH_FLAGS.items(): + if flags & bit: + mapped_flags.append(extension) + flags &= ~bit + if flags: + raise Exception("Unexpected flag bits set in value {}".format(flags)) + return mapped_flags + + +def detect_test_platform(pyb, args): + # Run a script to detect various bits of information about the target test instance. + output = run_feature_check(pyb, args, "target_info.py") + if output.endswith(b"CRASH"): + raise ValueError("cannot detect platform: {}".format(output)) + platform, arch, arch_flags, build, thread, float_prec, unicode = ( + str(output, "ascii").strip().split() + ) + if arch == "None": + arch = None + inlineasm_arch = detect_inline_asm_arch(pyb, args) + if thread == "None": + thread = None + float_prec = int(float_prec) + unicode = unicode == "True" + if arch == "rv32imc": + arch_flags = map_rv32_arch_flags(int(arch_flags)) + else: + arch_flags = None + + args.platform = platform + args.arch = arch + args.arch_flags = arch_flags + if arch and not args.mpy_cross_flags: + args.mpy_cross_flags = "-march=" + arch + if arch_flags: + args.mpy_cross_flags += " -march-flags=" + ",".join(arch_flags) + args.inlineasm_arch = inlineasm_arch + args.build = build + args.thread = thread + args.float_prec = float_prec + args.unicode = unicode + + # Print the detected information about the target. + print("platform={}".format(platform), end="") + if arch: + print(" arch={}".format(arch), end="") + if arch_flags: + print(" arch_flags={}".format(",".join(arch_flags)), end="") + if inlineasm_arch: + print(" inlineasm={}".format(inlineasm_arch), end="") + if thread: + print(" thread={}".format(thread), end="") + if float_prec: + print(" float={}-bit".format(float_prec), end="") + if unicode: + print(" unicode", end="") + + +def detect_target_wiring_script(pyb, args): + tw_data = b"" + tw_source = None + if args.target_wiring: + # A target_wiring path is explicitly provided, so use that. + tw_source = args.target_wiring + with open(tw_source, "rb") as f: + tw_data = f.read() + elif hasattr(pyb, "exec_raw") and pyb.exec_raw("import target_wiring") == (b"", b""): + # The board already has a target_wiring module available, so use that. + tw_source = "on-device" + else: + port = platform_to_port(args.platform) + build = args.build + tw_board_exact = None + tw_board_partial = None + tw_port = None + for file in os.listdir("target_wiring"): + file_base = file.removesuffix(".py") + if file_base == build: + # A file matching the target's board/build name. + tw_board_exact = file + elif file_base.endswith("x") and build.startswith(file_base.removesuffix("x")): + # A file with a partial match to the target's board/build name. + tw_board_partial = file + elif file_base == port: + # A file matching the target's port. + tw_port = file + tw_source = tw_board_exact or tw_board_partial or tw_port + if tw_source: + with open("target_wiring/" + tw_source, "rb") as f: + tw_data = f.read() + if tw_source: + print(" target_wiring={}".format(tw_source), end="") + pyb.target_wiring_script = tw_data + + +def prepare_script_for_target(args, *, script_text=None, force_plain=False): if force_plain or (not args.via_mpy and args.emit == "bytecode"): - if script_filename is not None: - with open(script_filename, "rb") as f: - script_text = f.read() + # A plain test to run as-is, no processing needed. + pass elif args.via_mpy: tempname = tempfile.mktemp(dir="") mpy_filename = tempname + ".mpy" - if script_filename is None: - script_filename = tempname + ".py" - cleanup_script_filename = True - with open(script_filename, "wb") as f: - f.write(script_text) - else: - cleanup_script_filename = False + script_filename = tempname + ".py" + with open(script_filename, "wb") as f: + f.write(script_text) try: subprocess.check_output( @@ -145,8 +525,7 @@ def prepare_script_for_target(args, *, script_filename=None, script_text=None, f script_text = b"__buf=" + bytes(repr(f.read()), "ascii") + b"\n" rm_f(mpy_filename) - if cleanup_script_filename: - rm_f(script_filename) + rm_f(script_filename) script_text += bytes(injected_import_hook_code, "ascii") else: @@ -157,35 +536,63 @@ def prepare_script_for_target(args, *, script_filename=None, script_text=None, f def run_script_on_remote_target(pyb, args, test_file, is_special): - had_crash, script = prepare_script_for_target( - args, script_filename=test_file, force_plain=is_special - ) + with open(test_file, "rb") as f: + script = f.read() + + # If the test is not a special test, prepend it with a print to indicate that it started. + # If the print does not execute this means that the test did not even start, eg it was + # too large for the target. + prepend_start_test = not is_special + if prepend_start_test: + if script.startswith(b"#"): + script = b"print('START TEST')" + script + else: + script = b"print('START TEST')\n" + script + + had_crash, script = prepare_script_for_target(args, script_text=script, force_plain=is_special) + if had_crash: return True, script try: had_crash = False pyb.enter_raw_repl() - output_mupy = pyb.exec_(script) + if test_file.endswith(tests_requiring_target_wiring) and pyb.target_wiring_script: + pyb.exec_( + "import sys;sys.modules['target_wiring']=__build_class__(lambda:exec(" + + repr(pyb.target_wiring_script) + + "),'target_wiring')" + ) + output_mupy = pyb.exec_(script, timeout=TEST_TIMEOUT) except pyboard.PyboardError as e: had_crash = True if not is_special and e.args[0] == "exception": - output_mupy = e.args[1] + e.args[2] + b"CRASH" + if prepend_start_test and e.args[1] == b"" and b"MemoryError" in e.args[2]: + output_mupy = b"SKIP-TOO-LARGE\n" + else: + output_mupy = e.args[1] + e.args[2] + b"CRASH" else: output_mupy = bytes(e.args[0], "ascii") + b"\nCRASH" + + if prepend_start_test: + if output_mupy.startswith(b"START TEST\r\n"): + output_mupy = output_mupy.removeprefix(b"START TEST\r\n") + else: + had_crash = True + return had_crash, output_mupy -special_tests = [ +tests_with_regex_output = [ base_path(file) for file in ( + # CIRCUITPY-CHANGE: removal and additions "micropython/meminfo.py", "basics/bytes_compare3.py", "basics/builtin_help.py", "thread/thread_exc2.py", - "esp32/partition_ota.py", - "circuitpython/traceback_test.py", # CIRCUITPY-CHANGE - "circuitpython/traceback_test_chained.py", # CIRCUITPY-CHANGE + "circuitpython/traceback_test.py", + "circuitpython/traceback_test_chained.py", ) ] @@ -194,10 +601,7 @@ def run_micropython(pyb, args, test_file, test_file_abspath, is_special=False): had_crash = False if pyb is None: # run on PC - if ( - test_file_abspath.startswith((base_path("cmdline/"), base_path("feature_check/"))) - or test_file_abspath in special_tests - ): + if test_file_abspath.startswith((base_path("cmdline/"), base_path("feature_check/"))): # special handling for tests of the unix cmdline program is_special = True @@ -236,6 +640,10 @@ def get(required=False): return rv def send_get(what): + # Detect {\x00} pattern and convert to ctrl-key codes. + ctrl_code = lambda m: bytes([int(m.group(1))]) + what = re.sub(rb"{\\x(\d\d)}", ctrl_code, what) + os.write(master, what) return get() @@ -315,17 +723,17 @@ def send_get(what): ) # canonical form for all ports/platforms is to use \n for end-of-line - output_mupy = output_mupy.replace(b"\r\n", b"\n") + output_mupy = normalize_newlines(output_mupy) # don't try to convert the output if we should skip this test - if had_crash or output_mupy in (b"SKIP\n", b"CRASH"): + if had_crash or output_mupy in (b"SKIP\n", b"SKIP-TOO-LARGE\n", b"CRASH"): return output_mupy # skipped special tests will output "SKIP" surrounded by other interpreter debug output if is_special and not had_crash and b"\nSKIP\n" in output_mupy: return b"SKIP\n" - if is_special or test_file_abspath in special_tests: + if is_special or test_file_abspath in tests_with_regex_output: # convert parts of the output that are not stable across runs with open(test_file + ".exp", "rb") as f: lines_exp = [] @@ -377,6 +785,10 @@ def run_feature_check(pyb, args, test_file): return run_micropython(pyb, args, test_file_path, test_file_path, is_special=True) +class TestError(Exception): + pass + + class ThreadSafeCounter: def __init__(self, start=0): self._value = start @@ -443,32 +855,26 @@ def run_script_on_remote_target(self, args, test_file, is_special): def run_tests(pyb, tests, args, result_dir, num_threads=1): - test_count = ThreadSafeCounter() testcase_count = ThreadSafeCounter() - passed_count = ThreadSafeCounter() - failed_tests = ThreadSafeCounter([]) - skipped_tests = ThreadSafeCounter([]) + test_results = ThreadSafeCounter([]) skip_tests = set() skip_native = False skip_int_big = False + skip_int_64 = False skip_bytearray = False skip_set_type = False skip_slice = False skip_async = False skip_const = False skip_revops = False - skip_io_module = False skip_fstring = False skip_endian = False + skip_inlineasm = False has_complex = True has_coverage = False - upy_float_precision = 32 - - # If we're asked to --list-tests, we can't assume that there's a - # connection to target, so we can't run feature checks usefully. - if not (args.list_tests or args.write_exp): + if True: # Even if we run completely different tests in a different directory, # we need to access feature_checks from the same directory as the # run-tests.py script itself so use base_path. @@ -483,6 +889,11 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): if output != b"1000000000000000000000000000000000000000000000\n": skip_int_big = True + # Check if 'long long' precision integers are supported, even if arbitrary precision is not + output = run_feature_check(pyb, args, "int_64.py") + if output != b"4611686018427387904\n": + skip_int_64 = True + # Check if bytearray is supported, and skip such tests if it's not output = run_feature_check(pyb, args, "bytearray.py") if output != b"bytearray\n": @@ -513,30 +924,33 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): if output == b"TypeError\n": skip_revops = True - # Check if io module exists, and skip such tests if it doesn't - output = run_feature_check(pyb, args, "io_module.py") - if output != b"io\n": - skip_io_module = True - # Check if fstring feature is enabled, and skip such tests if it doesn't output = run_feature_check(pyb, args, "fstring.py") if output != b"a=1\n": skip_fstring = True - # Check if @micropython.asm_thumb supports Thumb2 instructions, and skip such tests if it doesn't - output = run_feature_check(pyb, args, "inlineasm_thumb2.py") - if output != b"thumb2\n": - skip_tests.add("inlineasm/asmbcc.py") - skip_tests.add("inlineasm/asmbitops.py") - skip_tests.add("inlineasm/asmconst.py") - skip_tests.add("inlineasm/asmdiv.py") - skip_tests.add("inlineasm/asmfpaddsub.py") - skip_tests.add("inlineasm/asmfpcmp.py") - skip_tests.add("inlineasm/asmfpldrstr.py") - skip_tests.add("inlineasm/asmfpmuldiv.py") - skip_tests.add("inlineasm/asmfpsqrt.py") - skip_tests.add("inlineasm/asmit.py") - skip_tests.add("inlineasm/asmspecialregs.py") + if args.inlineasm_arch == "thumb": + # Check if @micropython.asm_thumb supports Thumb2 instructions, and skip such tests if it doesn't + output = run_feature_check(pyb, args, "inlineasm_thumb2.py") + if output != b"thumb2\n": + skip_tests.add("inlineasm/thumb/asmbcc.py") + skip_tests.add("inlineasm/thumb/asmbitops.py") + skip_tests.add("inlineasm/thumb/asmconst.py") + skip_tests.add("inlineasm/thumb/asmdiv.py") + skip_tests.add("inlineasm/thumb/asmit.py") + skip_tests.add("inlineasm/thumb/asmspecialregs.py") + if args.arch not in ("armv7emsp", "armv7emdp"): + skip_tests.add("inlineasm/thumb/asmfpaddsub.py") + skip_tests.add("inlineasm/thumb/asmfpcmp.py") + skip_tests.add("inlineasm/thumb/asmfpldrstr.py") + skip_tests.add("inlineasm/thumb/asmfpmuldiv.py") + skip_tests.add("inlineasm/thumb/asmfpsqrt.py") + + if args.inlineasm_arch == "rv32": + # Check if @micropython.asm_rv32 supports Zba instructions, and skip such tests if it doesn't + output = run_feature_check(pyb, args, "inlineasm_rv32_zba.py") + if output != b"rv32_zba\n": + skip_tests.add("inlineasm/rv32/asmzba.py") # Check if emacs repl is supported, and skip such tests if it's not t = run_feature_check(pyb, args, "repl_emacs_check.py") @@ -549,11 +963,6 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): skip_tests.add("cmdline/repl_words_move.py") upy_byteorder = run_feature_check(pyb, args, "byteorder.py") - upy_float_precision = run_feature_check(pyb, args, "float.py") - try: - upy_float_precision = int(upy_float_precision) - except ValueError: - upy_float_precision = 0 has_complex = run_feature_check(pyb, args, "complex.py") == b"complex\n" has_coverage = run_feature_check(pyb, args, "coverage.py") == b"coverage\n" cpy_byteorder = subprocess.check_output( @@ -561,58 +970,41 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): ) skip_endian = upy_byteorder != cpy_byteorder - # These tests don't test slice explicitly but rather use it to perform the test - misc_slice_tests = ( - "builtin_range", - "class_super", - "containment", - "errno1", - "fun_str", - "generator1", - "globals_del", - "memoryview1", - "memoryview_gc", - "object1", - "python34", - "struct_endian", - ) + skip_inlineasm = args.inlineasm_arch is None # Some tests shouldn't be run on GitHub Actions if os.getenv("GITHUB_ACTIONS") == "true": skip_tests.add("thread/stress_schedule.py") # has reliability issues - if os.getenv("RUNNER_OS") == "Windows": + if os.getenv("RUNNER_OS") == "Windows" and os.getenv("CI_BUILD_CONFIGURATION") == "Debug": # fails with stack overflow on Debug builds skip_tests.add("misc/sys_settrace_features.py") - if os.getenv("MSYSTEM") is not None: - # fails due to wrong path separator - skip_tests.add("import/import_file.py") - - if upy_float_precision == 0: - skip_tests.add("extmod/uctypes_le_float.py") - skip_tests.add("extmod/uctypes_native_float.py") - skip_tests.add("extmod/uctypes_sizeof_float.py") - skip_tests.add("extmod/json_dumps_float.py") - skip_tests.add("extmod/json_loads_float.py") - skip_tests.add("extmod/random_extra_float.py") - skip_tests.add("misc/rge_sm.py") - if upy_float_precision < 32: + if args.float_prec == 0: + skip_tests.update(tests_requiring_float) + if args.float_prec < 32: skip_tests.add( "float/float2int_intbig.py" ) # requires fp32, there's float2int_fp30_intbig.py instead skip_tests.add( - "float/string_format.py" - ) # requires fp32, there's string_format_fp30.py instead + "float/float_struct_e.py" + ) # requires fp32, there's float_struct_e_fp30.py instead skip_tests.add("float/bytes_construct.py") # requires fp32 skip_tests.add("float/bytearray_construct.py") # requires fp32 skip_tests.add("float/float_format_ints_power10.py") # requires fp32 - if upy_float_precision < 64: + if args.float_prec < 64: skip_tests.add("float/float_divmod.py") # tested by float/float_divmod_relaxed.py instead skip_tests.add("float/float2int_doubleprec_intbig.py") + skip_tests.add("float/float_struct_e_doubleprec.py") skip_tests.add("float/float_format_ints_doubleprec.py") skip_tests.add("float/float_parse_doubleprec.py") + if not args.unicode: + skip_tests.add("extmod/json_loads.py") # tests loading a utf-8 character + + if skip_slice: + skip_tests.update(tests_requiring_slice) + if not has_complex: skip_tests.add("float/complex1.py") skip_tests.add("float/complex1_intbig.py") @@ -628,82 +1020,28 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): skip_tests.add("cmdline/repl_sys_ps1_ps2.py") skip_tests.add("extmod/ssl_poll.py") - # Skip thread mutation tests on targets that don't have the GIL. - if args.target in ("rp2", "unix"): + # Skip thread mutation tests on targets that have unsafe threading behaviour. + if args.thread == "unsafe": for t in tests: if t.startswith("thread/mutate_"): skip_tests.add(t) - # Skip thread tests that require many threads on targets that don't support multiple threads. - if args.target == "rp2": - skip_tests.add("thread/stress_heap.py") - skip_tests.add("thread/thread_lock2.py") - skip_tests.add("thread/thread_lock3.py") - skip_tests.add("thread/thread_shared2.py") - # Some tests shouldn't be run on pyboard - if args.target != "unix": + if args.platform not in PC_PLATFORMS: skip_tests.add("basics/exception_chain.py") # warning is not printed skip_tests.add("micropython/meminfo.py") # output is very different to PC output + skip_tests.add("unicode/file1.py") # requires local file access + skip_tests.add("unicode/file2.py") # requires local file access + skip_tests.add("unicode/file_invalid.py") # requires local file access - if args.target == "wipy": - skip_tests.add("misc/print_exception.py") # requires error reporting full - skip_tests.update( - { - "extmod/uctypes_%s.py" % t - for t in "bytearray le native_le ptr_le ptr_native_le sizeof sizeof_native array_assign_le array_assign_native_le".split() - } - ) # requires uctypes - skip_tests.add("extmod/heapq1.py") # heapq not supported by WiPy - skip_tests.add("extmod/random_basic.py") # requires random - skip_tests.add("extmod/random_extra.py") # requires random - elif args.target == "esp8266": - skip_tests.add("misc/rge_sm.py") # too large - elif args.target == "minimal": - skip_tests.add("basics/class_inplace_op.py") # all special methods not supported - skip_tests.add( - "basics/subclass_native_init.py" - ) # native subclassing corner cases not support - skip_tests.add("misc/rge_sm.py") # too large - skip_tests.add("micropython/opt_level.py") # don't assume line numbers are stored - elif args.target == "nrf": - skip_tests.add("basics/memoryview1.py") # no item assignment for memoryview - skip_tests.add("extmod/random_basic.py") # unimplemented: random.seed - skip_tests.add("micropython/opt_level.py") # no support for line numbers - skip_tests.add("misc/non_compliant.py") # no item assignment for bytearray - for t in tests: - if t.startswith("basics/io_"): - skip_tests.add(t) - elif args.target == "renesas-ra": - skip_tests.add( - "extmod/time_time_ns.py" - ) # RA fsp rtc function doesn't support nano sec info - elif args.target == "qemu-arm": - skip_tests.add("misc/print_exception.py") # requires sys stdfiles - elif args.target == "webassembly": - skip_tests.add("basics/string_format_modulo.py") # can't print nulls to stdout - skip_tests.add("basics/string_strip.py") # can't print nulls to stdout - skip_tests.add("extmod/asyncio_basic2.py") - skip_tests.add("extmod/asyncio_cancel_self.py") - skip_tests.add("extmod/asyncio_current_task.py") - skip_tests.add("extmod/asyncio_exception.py") - skip_tests.add("extmod/asyncio_gather_finished_early.py") - skip_tests.add("extmod/asyncio_get_event_loop.py") - skip_tests.add("extmod/asyncio_heaplock.py") - skip_tests.add("extmod/asyncio_loop_stop.py") - skip_tests.add("extmod/asyncio_new_event_loop.py") - skip_tests.add("extmod/asyncio_threadsafeflag.py") - skip_tests.add("extmod/asyncio_wait_for_fwd.py") - skip_tests.add("extmod/binascii_a2b_base64.py") - skip_tests.add("extmod/re_stack_overflow.py") - skip_tests.add("extmod/time_res.py") - skip_tests.add("extmod/vfs_posix.py") - skip_tests.add("extmod/vfs_posix_enoent.py") - skip_tests.add("extmod/vfs_posix_paths.py") - skip_tests.add("extmod/vfs_userfs.py") - skip_tests.add("micropython/emg_exc.py") - skip_tests.add("micropython/extreme_exc.py") - skip_tests.add("micropython/heapalloc_exc_compressed_emg_exc.py") + # Skip certain tests when going via a .mpy file. + skip_tests.update(via_mpy_tests_to_skip.get(args.via_mpy, ())) + + # Skip emitter-specific tests. + skip_tests.update(emitter_tests_to_skip.get(args.emit, ())) + + # Skip platform-specific tests. + skip_tests.update(platform_tests_to_skip.get(args.platform, ())) # Some tests are known to fail on 64-bit machines if pyb is None and platform.architecture()[0] == "64bit": @@ -711,64 +1049,16 @@ def run_tests(pyb, tests, args, result_dir, num_threads=1): # Some tests use unsupported features on Windows if os.name == "nt": - skip_tests.add("import/import_file.py") # works but CPython prints forward slashes - - # Some tests are known to fail with native emitter - # Remove them from the below when they work - if args.emit == "native": - skip_tests.add("basics/gen_yield_from_close.py") # require raise_varargs - skip_tests.update( - {"basics/async_%s.py" % t for t in "with with2 with_break with_return".split()} - ) # require async_with - skip_tests.update( - {"basics/%s.py" % t for t in "try_reraise try_reraise2".split()} - ) # require raise_varargs - skip_tests.add("basics/annotate_var.py") # requires checking for unbound local - skip_tests.add("basics/del_deref.py") # requires checking for unbound local - skip_tests.add("basics/del_local.py") # requires checking for unbound local - skip_tests.add("basics/exception_chain.py") # raise from is not supported - skip_tests.add("basics/scope_implicit.py") # requires checking for unbound local - skip_tests.add("basics/sys_tracebacklimit.py") # requires traceback info - skip_tests.add("basics/try_finally_return2.py") # requires raise_varargs - skip_tests.add("basics/unboundlocal.py") # requires checking for unbound local - # CIRCUITPY-CHANGE - skip_tests.update( - ( - "basics/chained_exception.py", - "circuitpython/traceback_test.py", - "circuitpython/traceback_test_chained.py", - ) - ) # because native doesn't have proper traceback info - skip_tests.add("extmod/asyncio_event.py") # unknown issue - skip_tests.add("extmod/asyncio_lock.py") # requires async with - skip_tests.add("extmod/asyncio_micropython.py") # unknown issue - skip_tests.add("extmod/asyncio_wait_for.py") # unknown issue - skip_tests.add("misc/features.py") # requires raise_varargs - skip_tests.add( - "misc/print_exception.py" - ) # because native doesn't have proper traceback info - skip_tests.add("misc/sys_exc_info.py") # sys.exc_info() is not supported for native - skip_tests.add("misc/sys_settrace_features.py") # sys.settrace() not supported - skip_tests.add("misc/sys_settrace_generator.py") # sys.settrace() not supported - skip_tests.add("misc/sys_settrace_loop.py") # sys.settrace() not supported - skip_tests.add( - "micropython/emg_exc.py" - ) # because native doesn't have proper traceback info - skip_tests.add( - "micropython/heapalloc_traceback.py" - ) # because native doesn't have proper traceback info - skip_tests.add( - "micropython/opt_level_lineno.py" - ) # native doesn't have proper traceback info - skip_tests.add("micropython/schedule.py") # native code doesn't check pending events - skip_tests.add("stress/bytecode_limit.py") # bytecode specific test + if not sysconfig.get_platform().startswith("mingw"): + # Works but CPython uses '\' path separator + skip_tests.add("import/import_file.py") def run_one_test(test_file): test_file = test_file.replace("\\", "/") test_file_abspath = os.path.abspath(test_file).replace("\\", "/") if args.filters: - # Default verdict is the opposit of the first action + # Default verdict is the opposite of the first action verdict = "include" if args.filters[0][0] == "exclude" else "exclude" for action, pat in args.filters: if pat.search(test_file): @@ -778,135 +1068,238 @@ def run_one_test(test_file): test_basename = test_file.replace("..", "_").replace("./", "").replace("/", "_") test_name = os.path.splitext(os.path.basename(test_file))[0] - is_native = ( - test_name.startswith("native_") - or test_name.startswith("viper_") - or args.emit == "native" - ) + is_native = test_name.startswith("native_") or test_name.startswith("viper_") is_endian = test_name.endswith("_endian") - is_int_big = test_name.startswith("int_big") or test_name.endswith("_intbig") + is_int_big = ( + test_name.startswith("int_big") + or test_name.endswith("_intbig") + or test_name.startswith("ffi_int") # these tests contain large integer literals + ) + is_int_64 = test_name.startswith("int_64") or test_name.endswith("_int64") is_bytearray = test_name.startswith("bytearray") or test_name.endswith("_bytearray") is_set_type = test_name.startswith(("set_", "frozenset")) or test_name.endswith("_set") - is_slice = test_name.find("slice") != -1 or test_name in misc_slice_tests - is_async = test_name.startswith(("async_", "asyncio_")) + is_slice = test_name.find("slice") != -1 + is_async = test_name.startswith(("async_", "asyncio_")) or test_name.endswith("_async") is_const = test_name.startswith("const") - is_io_module = test_name.startswith("io_") is_fstring = test_name.startswith("string_fstring") + is_inlineasm = test_name.startswith("asm") skip_it = test_file in skip_tests skip_it |= skip_native and is_native skip_it |= skip_endian and is_endian skip_it |= skip_int_big and is_int_big + skip_it |= skip_int_64 and is_int_64 skip_it |= skip_bytearray and is_bytearray skip_it |= skip_set_type and is_set_type skip_it |= skip_slice and is_slice skip_it |= skip_async and is_async skip_it |= skip_const and is_const skip_it |= skip_revops and "reverse_op" in test_name - skip_it |= skip_io_module and is_io_module skip_it |= skip_fstring and is_fstring - - if args.list_tests: - if not skip_it: - print(test_file) - return + skip_it |= skip_inlineasm and is_inlineasm if skip_it: print("skip ", test_file) - skipped_tests.append(test_name) + test_results.append((test_file, "skip", "")) return - # get expected output - test_file_expected = test_file + ".exp" - if os.path.isfile(test_file_expected): - # expected output given by a file, so read that in - with open(test_file_expected, "rb") as f: - output_expected = f.read() - else: - # CIRCUITPY-CHANGE: set language & make sure testlib is available for `skip_ok`. - e = { - "PYTHONPATH": base_path("testlib"), - "PATH": os.environ["PATH"], - "LANG": "en_US.UTF-8", - } - # CIRCUITPY-CHANGE: --keep-path applies to PYTHONPATH as well - if args.keep_path and os.getenv("PYTHONPATH"): - e["PYTHONPATH"] += ":" + os.getenv("PYTHONPATH") - - # run CPython to work out expected output - try: - output_expected = subprocess.check_output( - CPYTHON3_CMD + [test_file_abspath], - cwd=os.path.dirname(test_file), - stderr=subprocess.STDOUT, - # CIRCUITPY-CHANGE: pass environment - env=e, - ) - if args.write_exp: - with open(test_file_expected, "wb") as f: - f.write(output_expected) - except subprocess.CalledProcessError: - output_expected = b"CPYTHON3 CRASH" - - # canonical form for all host platforms is to use \n for end-of-line - output_expected = output_expected.replace(b"\r\n", b"\n") - - if args.write_exp: - return - - # run MicroPython + # Run the test on the MicroPython target. output_mupy = run_micropython(pyb, args, test_file, test_file_abspath) + # Check if the target requested to skip this test. if output_mupy == b"SKIP\n": + if pyb is not None and hasattr(pyb, "read_until"): + # Running on a target over a serial connection, and the target requested + # to skip the test. It does this via a SystemExit which triggers a soft + # reset. Wait for the soft reset to finish, so we don't interrupt the + # start-up code (eg boot.py) when preparing to run the next test. + pyb.read_until(1, b"raw REPL; CTRL-B to exit\r\n") print("skip ", test_file) - skipped_tests.append(test_name) + test_results.append((test_file, "skip", "")) + return + elif output_mupy == b"SKIP-TOO-LARGE\n": + print("lrge ", test_file) + test_results.append((test_file, "skip", "too large")) return - testcase_count.add(len(output_expected.splitlines())) + # Look at the output of the test to see if unittest was used. + uses_unittest = False + output_mupy_lines = output_mupy.splitlines() + if any( + line == b"ImportError: no module named 'unittest'" for line in output_mupy_lines[-3:] + ): + raise TestError( + ( + "error: test {} requires unittest".format(test_file), + "(eg run `mpremote mip install unittest` to install it)", + ) + ) + elif ( + len(output_mupy_lines) > 4 + and output_mupy_lines[-4] == b"-" * 70 + and output_mupy_lines[-2] == b"" + ): + # look for unittest summary + unittest_ran_match = re.match(rb"Ran (\d+) tests$", output_mupy_lines[-3]) + unittest_result_match = re.match( + b"(" + rb"(OK)( \(skipped=(\d+)\))?" + b"|" + rb"(FAILED) \(failures=(\d+), errors=(\d+)\)" + b")$", + output_mupy_lines[-1], + ) + uses_unittest = unittest_ran_match and unittest_result_match + + # Determine the expected output. + if uses_unittest: + # Expected output is result of running unittest. + output_expected = None + else: + # Prefer emitter-specific expected output. + test_file_expected = test_file + "." + args.emit + ".exp" + if not os.path.isfile(test_file_expected): + # Fall back to generic expected output. + test_file_expected = test_file + ".exp" + if os.path.isfile(test_file_expected): + # Expected output given by a file, so read that in. + with open(test_file_expected, "rb") as f: + output_expected = f.read() + else: + # CIRCUITPY-CHANGE: set language & make sure testlib is available for `skip_ok`. + e = { + "PYTHONPATH": base_path("testlib"), + "PATH": os.environ["PATH"], + "LANG": "en_US.UTF-8", + } + # CIRCUITPY-CHANGE: --keep-path applies to PYTHONPATH as well + if args.keep_path and os.getenv("PYTHONPATH"): + e["PYTHONPATH"] += ":" + os.getenv("PYTHONPATH") + + # Run CPython to work out expected output. + try: + output_expected = subprocess.check_output( + CPYTHON3_CMD + [test_file_abspath], + cwd=os.path.dirname(test_file), + stderr=subprocess.STDOUT, + # CIRCUITPY-CHANGE: pass environment + env=e, + ) + except subprocess.CalledProcessError as er: + output_expected = b"CPYTHON3 CRASH:\n" + er.output + + # Canonical form for all host platforms is to use \n for end-of-line. + output_expected = output_expected.replace(b"\r\n", b"\n") + + # Work out if test passed or not. + test_passed = False + extra_info = "" + if uses_unittest: + test_passed = unittest_result_match.group(2) == b"OK" + num_test_cases = int(unittest_ran_match.group(1)) + extra_info = "unittest: {} ran".format(num_test_cases) + if test_passed and unittest_result_match.group(4) is not None: + num_skipped = int(unittest_result_match.group(4)) + num_test_cases -= num_skipped + extra_info += ", {} skipped".format(num_skipped) + elif not test_passed: + num_failures = int(unittest_result_match.group(6)) + num_errors = int(unittest_result_match.group(7)) + extra_info += ", {} failures, {} errors".format(num_failures, num_errors) + extra_info = "(" + extra_info + ")" + testcase_count.add(num_test_cases) + else: + testcase_count.add(len(output_expected.splitlines())) + test_passed = output_expected == output_mupy filename_expected = os.path.join(result_dir, test_basename + ".exp") filename_mupy = os.path.join(result_dir, test_basename + ".out") - if output_expected == output_mupy: - print("pass ", test_file) - passed_count.increment() + # Print test summary, update counters, and save .exp/.out files if needed. + if test_passed: + print("pass ", test_file, extra_info) + test_results.append((test_file, "pass", "")) rm_f(filename_expected) rm_f(filename_mupy) else: - with open(filename_expected, "wb") as f: - f.write(output_expected) + print("FAIL ", test_file, extra_info) + if output_expected is not None: + with open(filename_expected, "wb") as f: + f.write(output_expected) + else: + rm_f(filename_expected) # in case left over from previous failed run with open(filename_mupy, "wb") as f: f.write(output_mupy) - print("FAIL ", test_file) - failed_tests.append((test_name, test_file)) - - test_count.increment() + test_results.append((test_file, "fail", "")) + + # Print a note if this looks like it might have been a misfired unittest + if not uses_unittest and not test_passed: + with open(test_file, "r") as f: + if any(re.match("^import.+unittest", l) for l in f.readlines()): + print( + "NOTE: {} may be a unittest that doesn't run unittest.main()".format( + test_file + ) + ) - if pyb or args.list_tests: + if pyb: num_threads = 1 - if num_threads > 1: - pool = ThreadPool(num_threads) - pool.map(run_one_test, tests) - else: - for test in tests: - run_one_test(test) + try: + if num_threads > 1: + pool = ThreadPool(num_threads) + pool.map(run_one_test, tests) + else: + for test in tests: + run_one_test(test) + except TestError as er: + for line in er.args[0]: + print(line) + sys.exit(1) - # Leave RESULTS_FILE untouched here for future runs. - if args.list_tests: - return True + # Return test results. + return test_results.value, testcase_count.value - print( - "{} tests performed ({} individual testcases)".format( - test_count.value, testcase_count.value - ) + +# Print a summary of the results and save them to a JSON file. +# Returns True if everything succeeded, False otherwise. +def create_test_report(args, test_results, testcase_count=None): + passed_tests = list(r for r in test_results if r[1] == "pass") + skipped_tests = list(r for r in test_results if r[1] == "skip" and r[2] != "too large") + skipped_tests_too_large = list( + r for r in test_results if r[1] == "skip" and r[2] == "too large" ) - print("{} tests passed".format(passed_count.value)) + failed_tests = list(r for r in test_results if r[1] == "fail") + + num_tests_performed = len(passed_tests) + len(failed_tests) + + testcase_count_info = "" + if testcase_count is not None: + testcase_count_info = " ({} individual testcases)".format(testcase_count) + print("{} tests performed{}".format(num_tests_performed, testcase_count_info)) + + print("{} tests passed".format(len(passed_tests))) - skipped_tests = sorted(skipped_tests.value) if len(skipped_tests) > 0: - print("{} tests skipped: {}".format(len(skipped_tests), " ".join(skipped_tests))) - failed_tests = sorted(failed_tests.value) + print( + "{} tests skipped: {}".format( + len(skipped_tests), " ".join(test[0] for test in skipped_tests) + ) + ) + + if len(skipped_tests_too_large) > 0: + print( + "{} tests skipped because they are too large: {}".format( + len(skipped_tests_too_large), " ".join(test[0] for test in skipped_tests_too_large) + ) + ) + + if len(failed_tests) > 0: + print( + "{} tests failed: {}".format( + len(failed_tests), " ".join(test[0] for test in failed_tests) + ) + ) # Serialize regex added by append_filter. def to_json(obj): @@ -914,23 +1307,22 @@ def to_json(obj): return obj.pattern return obj - with open(os.path.join(result_dir, RESULTS_FILE), "w") as f: + with open(os.path.join(args.result_dir, RESULTS_FILE), "w") as f: json.dump( - {"args": vars(args), "failed_tests": [test[1] for test in failed_tests]}, + { + # The arguments passed on the command-line. + "args": vars(args), + # A list of all results of the form [(test, result, reason), ...]. + "results": list(test for test in test_results), + # A list of failed tests. This is deprecated, use the "results" above instead. + "failed_tests": [test[0] for test in failed_tests], + }, f, default=to_json, ) - if len(failed_tests) > 0: - print( - "{} tests failed: {}".format( - len(failed_tests), " ".join(test[0] for test in failed_tests) - ) - ) - return False - - # all tests succeeded - return True + # Return True only if all tests succeeded. + return len(failed_tests) == 0 class append_filter(argparse.Action): @@ -947,22 +1339,55 @@ def __call__(self, parser, args, value, option): args.filters.append((option, re.compile(value))) -def main(): - cmd_parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - description="""Run and manage tests for MicroPython. +test_instance_description = """\ +By default the tests are run against the unix port of MicroPython. To run it +against something else, use the -t option. See below for details. +""" +test_instance_epilog = """\ +The -t option accepts the following for the test instance: +- unix - use the unix port of MicroPython, specified by the MICROPY_MICROPYTHON + environment variable (which defaults to the standard variant of either the unix + or windows ports, depending on the host platform) +- webassembly - use the webassembly port of MicroPython, specified by the + MICROPY_MICROPYTHON_MJS environment variable (which defaults to the standard + variant of the webassembly port) +- port: - connect to and use the given serial port device +- a - connect to and use /dev/ttyACM +- u - connect to and use /dev/ttyUSB +- c - connect to and use COM +- exec: - execute a command and attach to its stdin/stdout +- execpty: - execute a command and attach to the printed /dev/pts/ device +- ... - connect to the given IPv4 address +- anything else specifies a serial port +""" +test_directory_description = """\ Tests are discovered by scanning test directories for .py files or using the specified test files. If test files nor directories are specified, the script expects to be ran in the tests directory (where this file is located) and the builtin tests suitable for the target platform are ran. +""" + + +def main(): + global injected_import_hook_code + + cmd_parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description=f"""Run and manage tests for MicroPython. + +{test_instance_description} +{test_directory_description} + When running tests, run-tests.py compares the MicroPython output of the test with the output -produced by running the test through CPython unless a .exp file is found, in which -case it is used as comparison. +produced by running the test through CPython unless a .exp file is found (or a +.native.exp file when using the native emitter), in which case it is used as comparison. + If a test fails, run-tests.py produces a pair of .out and .exp files in the result directory with the MicroPython output and the expectations, respectively. """, - epilog="""\ + epilog=f"""\ +{test_instance_epilog} Options -i and -e can be multiple and processed in the order given. Regex "search" (vs "match") operation is used. An action (include/exclude) of the last matching regex is used: @@ -971,11 +1396,8 @@ def main(): run-tests.py -e async -i async_foo - include all, exclude async, yet still include async_foo """, ) - cmd_parser.add_argument("--target", default="unix", help="the target platform") cmd_parser.add_argument( - "--device", - default="/dev/ttyACM0", - help="the serial device or the IP address of the pyboard", + "-t", "--test-instance", default="unix", help="the MicroPython instance to test" ) cmd_parser.add_argument( "-b", "--baudrate", default=115200, help="the baud rate of the serial device" @@ -1004,14 +1426,6 @@ def main(): dest="filters", help="include test by regex on path/name.py", ) - cmd_parser.add_argument( - "--write-exp", - action="store_true", - help="use CPython to generate .exp files to run tests w/o CPython", - ) - cmd_parser.add_argument( - "--list-tests", action="store_true", help="list tests instead of running them" - ) cmd_parser.add_argument( "--emit", default="bytecode", help="MicroPython emitter to use (bytecode or native)" ) @@ -1047,14 +1461,38 @@ def main(): action="store_true", help="re-run only the failed tests", ) + cmd_parser.add_argument( + "--begin", + metavar="PROLOGUE", + default=None, + help="prologue python file to execute before module import", + ) + cmd_parser.add_argument( + "--target-wiring", + default=None, + help="force the given script to be used as target_wiring.py", + ) args = cmd_parser.parse_args() + prologue = "" + if args.begin: + with open(args.begin, "rt") as source: + prologue = source.read() + injected_import_hook_code = injected_import_hook_code.replace("{import_prologue}", prologue) + if args.print_failures: - for exp in glob(os.path.join(args.result_dir, "*.exp")): - testbase = exp[:-4] + for out in glob(os.path.join(args.result_dir, "*.out")): + testbase = out[:-4] print() print("FAILURE {0}".format(testbase)) - os.system("{0} {1}.exp {1}.out".format(DIFF, testbase)) + if os.path.exists(testbase + ".exp"): + # Show diff of expected and actual output. + os.system("{0} {1}.exp {1}.out".format(DIFF, testbase)) + else: + # No expected output, just show the actual output (eg from a unittest). + with open(out) as f: + for line in f: + print(line, end="") sys.exit(0) @@ -1067,54 +1505,11 @@ def main(): sys.exit(0) - LOCAL_TARGETS = ( - "unix", - "qemu-arm", - "webassembly", - ) - EXTERNAL_TARGETS = ( - "pyboard", - "wipy", - "esp8266", - "esp32", - "minimal", - "nrf", - "renesas-ra", - "rp2", - ) - if args.list_tests: - pyb = None - elif args.target in LOCAL_TARGETS: - pyb = None - if not args.mpy_cross_flags: - if args.target == "unix": - args.mpy_cross_flags = "-march=host" - elif args.target == "qemu-arm": - args.mpy_cross_flags = "-march=armv7m" - if args.target == "webassembly": - pyb = PyboardNodeRunner() - elif args.target in EXTERNAL_TARGETS: - global pyboard - sys.path.append(base_path("../tools")) - import pyboard - - if not args.mpy_cross_flags: - if args.target == "esp8266": - args.mpy_cross_flags = "-march=xtensa" - elif args.target == "esp32": - args.mpy_cross_flags = "-march=xtensawin" - elif args.target == "rp2": - args.mpy_cross_flags = "-march=armv6m" - elif args.target == "pyboard": - args.mpy_cross_flags = "-march=armv7emsp" - else: - args.mpy_cross_flags = "-march=armv7m" + # Get the test instance to run on. + pyb = get_test_instance(args.test_instance, args.baudrate, args.user, args.password) - pyb = pyboard.Pyboard(args.device, args.baudrate, args.user, args.password) - pyboard.Pyboard.run_script_on_remote_target = run_script_on_remote_target - pyb.enter_raw_repl() - else: - raise ValueError("target must be one of %s" % ", ".join(LOCAL_TARGETS + EXTERNAL_TARGETS)) + # Automatically detect the platform. + detect_test_platform(pyb, args) if args.run_failures and (any(args.files) or args.test_dirs is not None): raise ValueError( @@ -1125,55 +1520,38 @@ def main(): results_file = os.path.join(args.result_dir, RESULTS_FILE) if os.path.exists(results_file): with open(results_file, "r") as f: - tests = json.load(f)["failed_tests"] + tests = list(test[0] for test in json.load(f)["results"] if test[1] == "fail") else: tests = [] elif len(args.files) == 0: test_extensions = ("*.py",) - if args.target == "webassembly": + if args.platform == "webassembly": test_extensions += ("*.js", "*.mjs") if args.test_dirs is None: test_dirs = ( "basics", - "circuitpython", # CIRCUITPY-CHANGE "micropython", "misc", "extmod", + "stress", ) - if args.target == "pyboard": - # run pyboard tests - test_dirs += ("float", "stress", "inlineasm", "ports/stm32") - elif args.target in ("renesas-ra"): - test_dirs += ("float", "inlineasm", "ports/renesas-ra") - elif args.target == "rp2": - test_dirs += ("float", "stress", "inlineasm", "thread", "ports/rp2") - elif args.target in ("esp8266", "esp32", "minimal", "nrf"): + if args.inlineasm_arch is not None: + test_dirs += ("inlineasm/{}".format(args.inlineasm_arch),) + if args.thread is not None: + test_dirs += ("thread",) + if args.float_prec > 0: test_dirs += ("float",) - elif args.target == "wipy": - # run WiPy tests - test_dirs += ("ports/cc3200",) - elif args.target == "unix": + if args.unicode: + test_dirs += ("unicode",) + port_specific_test_dir = "ports/{}".format(platform_to_port(args.platform)) + if os.path.isdir(port_specific_test_dir): + test_dirs += (port_specific_test_dir,) + if args.platform in PC_PLATFORMS: # run PC tests - test_dirs += ( - "float", - "import", - "io", - "stress", - "unicode", - "cmdline", - "ports/unix", - ) - elif args.target == "qemu-arm": - if not args.write_exp: - raise ValueError("--target=qemu-arm must be used with --write-exp") - # Generate expected output files for qemu run. - # This list should match the test_dirs tuple in tinytest-codegen.py. - test_dirs += ( - "float", - "inlineasm", - "ports/qemu-arm", - ) + test_dirs += ("import",) + if args.build != "minimal": + test_dirs += ("cmdline", "io") else: # run tests from these directories test_dirs = args.test_dirs @@ -1188,21 +1566,35 @@ def main(): # tests explicitly given tests = args.files + # If any tests need it, prepare the target_wiring script for the target. + if pyb and any(test.endswith(tests_requiring_target_wiring) for test in tests): + detect_target_wiring_script(pyb, args) + + # End the target information line. + print() + if not args.keep_path: - # clear search path to make sure tests use only builtin modules and those that can be frozen + # Clear search path to make sure tests use only builtin modules, those in + # extmod, and a path to unittest in case it's needed. # CIRCUITPY-CHANGE: Add testlib for skip_if and our async stuff. - os.environ["MICROPYPATH"] = os.pathsep.join( - [ - ".frozen", - base_path("testlib"), - base_path("../frozen/Adafruit_CircuitPython_asyncio"), - base_path("../frozen/Adafruit_CircuitPython_Ticks"), - ] + os.environ["MICROPYPATH"] = ( + ".frozen" + + os.pathsep + + base_path("testlib") + + os.pathsep + + base_path("../frozen/Adafruit_CircuitPython_asyncio") + + os.pathsep + + base_path("../frozen/Adafruit_CircuitPython_Ticks") + + os.pathsep + + base_path("../extmod") + + os.pathsep + + base_path("../lib/micropython-lib/python-stdlib/unittest") ) try: os.makedirs(args.result_dir, exist_ok=True) - res = run_tests(pyb, tests, args, args.result_dir, args.jobs) + test_results, testcase_count = run_tests(pyb, tests, args, args.result_dir, args.jobs) + res = create_test_report(args, test_results, testcase_count) finally: if pyb: pyb.close() diff --git a/tests/serial_test.py b/tests/serial_test.py new file mode 100755 index 00000000000..3b5940d91a9 --- /dev/null +++ b/tests/serial_test.py @@ -0,0 +1,338 @@ +#!/usr/bin/env python +# +# Performance and reliability test for serial port communication. +# +# Basic usage: +# serial_test.py [-t serial-device] +# +# The `serial-device` will default to /dev/ttyACM0. + +import argparse +import random +import serial +import sys +import time + +run_tests_module = __import__("run-tests") + +echo_test_script = """ +import sys +bytes_min=%u +bytes_max=%u +repeat=%u +b=memoryview(bytearray(bytes_max)) +for n in range(bytes_min,bytes_max+1): + for _ in range(repeat): + n2 = sys.stdin.readinto(b[:n]) + sys.stdout.write(b[:n2]) +""" + +read_test_script = """ +bin = True +try: + wr=__import__("pyb").USB_VCP(0).send +except: + import sys + if hasattr(sys.stdout,'buffer'): + wr=sys.stdout.buffer.write + else: + wr=sys.stdout.write + bin = False +b=bytearray(%u) +if bin: + wr('BIN') + for i in range(len(b)): + b[i] = i & 0xff +else: + wr('TXT') + for i in range(len(b)): + b[i] = 0x20 + (i & 0x3f) +for _ in range(%d): + wr(b) +""" + + +write_test_script_verified = """ +import sys +try: + rd=__import__("pyb").USB_VCP(0).recv +except: + rd=sys.stdin.readinto +b=bytearray(%u) +for _ in range(%u): + n = rd(b) + fail = 0 + for i in range(n): + if b[i] != 32 + (i & 0x3f): + fail += 1 + if fail: + sys.stdout.write(b'ER%%05u' %% fail) + else: + sys.stdout.write(b'OK%%05u' %% n) +""" + +write_test_script_unverified = """ +import sys +try: + rd=__import__("pyb").USB_VCP(0).recv +except: + rd=sys.stdin.readinto +b=bytearray(%u) +for _ in range(%u): + n = rd(b) + if n != len(b): + sys.stdout.write(b'ER%%05u' %% n) + else: + sys.stdout.write(b'OK%%05u' %% n) +""" + + +class TestError(Exception): + pass + + +def drain_input(ser): + time.sleep(0.1) + while ser.inWaiting() > 0: + data = ser.read(ser.inWaiting()) + time.sleep(0.1) + + +def send_script(ser, script): + ser.write(b"\x03\x01\x04") # break, raw-repl, soft-reboot + drain_input(ser) + chunk_size = 32 + for i in range(0, len(script), chunk_size): + ser.write(script[i : i + chunk_size]) + time.sleep(0.01) + ser.write(b"\x04") # eof + ser.flush() + response = ser.read(2) + if response != b"OK": + response += ser.read(ser.inWaiting()) + raise TestError("could not send script", response) + + +def echo_test(ser_repl, ser_data): + global test_passed + + # Make the test data deterministic. + random.seed(0) + + # Set parameters for the test. + # Go just a bit above the size of a USB high-speed packet. + bytes_min = 1 + bytes_max = 520 + num_repeat = 1 + + # Load and run the write_test_script. + script = bytes(echo_test_script % (bytes_min, bytes_max, num_repeat), "ascii") + send_script(ser_repl, script) + + # A selection of printable bytes for echo data. + printable_bytes = list(range(48, 58)) + list(range(65, 91)) + list(range(97, 123)) + + # Write data to the device and record the echo'd data. + # Use a different selection of random printable characters for each + # echo, to make it easier to debug when the echo doesn't match. + num_errors = 0 + echo_results = [] + for num_bytes in range(bytes_min, bytes_max + 1): + print(f"DATA ECHO: {num_bytes} / {bytes_max}", end="\r") + for repeat in range(num_repeat): + rand_bytes = list(random.choice(printable_bytes) for _ in range(8)) + buf = bytes(random.choice(rand_bytes) for _ in range(num_bytes)) + ser_data.write(buf) + buf2 = ser_data.read(len(buf)) + match = buf == buf2 + num_errors += not match + echo_results.append((match, buf, buf2)) + if num_errors > 8: + # Stop early if there are too many errors. + break + ser_repl.write(b"\x03") + + # Print results. + if all(match for match, _, _ in echo_results): + print("DATA ECHO: OK for {}-{} bytes at a time".format(bytes_min, bytes_max)) + else: + test_passed = False + print("DATA ECHO: FAIL ") + for match, buf, buf2 in echo_results: + print(" sent", len(buf), buf) + if match: + print(" echo match") + else: + print(" echo", len(buf), buf2) + + +def read_test(ser_repl, ser_data, bufsize, nbuf): + global test_passed + + assert bufsize % 256 == 0 # for verify to work + + # how long to wait for data from device + # (if UART TX is also enabled then it can take 1.4s to send + # out a 16KB butter at 115200bps) + READ_TIMEOUT_S = 2 + + # Load and run the read_test_script. + script = bytes(read_test_script % (bufsize, nbuf), "ascii") + send_script(ser_repl, script) + + # Read from the device the type of data that it will send (BIN or TXT). + data_type = ser_data.read(3) + + # Read data from the device, check it is correct, and measure throughput. + n = 0 + last_byte = None + t_start = time.time() + remain = nbuf * bufsize + total_data = bytearray(remain) + while remain: + t0 = time.monotonic_ns() + while ser_data.inWaiting() == 0: + if time.monotonic_ns() - t0 > READ_TIMEOUT_S * 1e9: + # timeout waiting for data from device + break + time.sleep(0.0001) + if not ser_data.inWaiting(): + test_passed = False + print("ERROR: timeout waiting for data") + print(total_data[:n]) + return 0 + to_read = min(ser_data.inWaiting(), remain) + data = ser_data.read(to_read) + remain -= len(data) + print(f"{n} / {nbuf * bufsize}", end="\r") + total_data[n : n + len(data)] = data + n += len(data) + t_end = time.time() + for i in range(0, len(total_data)): + if data_type == b"BIN": + wanted = i & 0xFF + else: + wanted = 0x20 + (i & 0x3F) + if total_data[i] != wanted: + test_passed = False + print("ERROR: data mismatch:", i, wanted, total_data[i]) + ser_repl.write(b"\x03") # break + t = t_end - t_start + + # Print results. + print( + "DATA IN: bufsize=%u, read %u bytes in %.2f msec = %.2f kibytes/sec = %.2f MBits/sec" + % (bufsize, n, t * 1000, n / 1024 / t, n * 8 / 1000000 / t) + ) + + return n / t + + +def write_test(ser_repl, ser_data, bufsize, nbuf, verified): + global test_passed + + # Load and run the write_test_script. + if verified: + script = write_test_script_verified + else: + script = write_test_script_unverified + script = bytes(script % (bufsize, nbuf), "ascii") + send_script(ser_repl, script) + drain_input(ser_repl) + + # Write data to the device, check it is correct, and measure throughput. + n = 0 + t_start = time.time() + buf = bytearray(bufsize) + for i in range(len(buf)): + buf[i] = 32 + (i & 0x3F) # don't want to send ctrl chars! + for i in range(nbuf): + ser_data.write(buf) + n += len(buf) + print(f"{n} / {nbuf * bufsize}", end="\r") + response = ser_repl.read(7) + if response != b"OK%05u" % bufsize: + test_passed = False + print("ERROR: bad response, expecting OK%05u, got %r" % (bufsize, response)) + t_end = time.time() + ser_repl.write(b"\x03") # break + t = t_end - t_start + + # Print results. + print( + "DATA OUT: verify=%d, bufsize=%u, wrote %u bytes in %.2f msec = %.2f kibytes/sec = %.2f MBits/sec" + % (verified, bufsize, n, t * 1000, n / 1024 / t, n * 8 / 1000000 / t) + ) + + return n / t + + +def do_test(dev_repl, dev_data=None, time_per_subtest=1): + if dev_data is None: + print("REPL and data on", dev_repl) + ser_repl = serial.Serial(dev_repl, baudrate=115200, timeout=1) + ser_data = ser_repl + else: + print("REPL on", dev_repl) + print("data on", dev_data) + ser_repl = serial.Serial(dev_repl, baudrate=115200, timeout=1) + ser_data = serial.Serial(dev_data, baudrate=115200, timeout=1) + + # Do echo test first, and abort if it doesn't pass. + echo_test(ser_repl, ser_data) + if not test_passed: + return + + # Do read and write throughput test. + for test_func, test_args, bufsize in ( + (read_test, (), 256), + (write_test, (True,), 128), + (write_test, (False,), 128), + ): + nbuf = 128 + while bufsize <= 16384: + rate = test_func(ser_repl, ser_data, bufsize, nbuf, *test_args) + bufsize *= 2 + if rate: + # Adjust the amount of data based on the rate, to keep each subtest + # at around time_per_subtest seconds long. + nbuf = max(min(128, int(rate * time_per_subtest / bufsize)), 1) + + ser_repl.close() + ser_data.close() + + +def main(): + global test_passed + + cmd_parser = argparse.ArgumentParser( + description="Test performance and reliability of serial port communication.", + epilog=run_tests_module.test_instance_epilog, + formatter_class=argparse.RawTextHelpFormatter, + ) + cmd_parser.add_argument( + "-t", + "--test-instance", + default="a0", + help="MicroPython instance to test", + ) + cmd_parser.add_argument( + "--time-per-subtest", default="1", help="approximate time to take per subtest (in seconds)" + ) + args = cmd_parser.parse_args() + + dev_repl = run_tests_module.convert_device_shortcut_to_real_device(args.test_instance) + + test_passed = True + try: + do_test(dev_repl, None, float(args.time_per_subtest)) + except TestError as er: + test_passed = False + print("ERROR:", er) + + if not test_passed: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/tests/stress/bytecode_limit.py b/tests/stress/bytecode_limit.py index ad090637f6a..0a72b66fa05 100644 --- a/tests/stress/bytecode_limit.py +++ b/tests/stress/bytecode_limit.py @@ -1,16 +1,30 @@ # Test the limits of bytecode generation. +import sys + +# Tune the test parameters based on the target's bytecode generator. +if hasattr(sys.implementation, "_mpy"): + # Target can load .mpy files so generated bytecode uses 1 byte per qstr. + number_of_body_copies = (433, 432, 431, 399) +else: + # Target can't load .mpy files so generated bytecode uses 2 bytes per qstr. + number_of_body_copies = (401, 400, 399, 398) + body = " with f()()() as a:\n try:\n f()()()\n except Exception:\n pass\n" # Test overflow of jump offset. -for n in (433, 432, 431, 430): +# Print results at the end in case an intermediate value of n fails with MemoryError. +results = [] +for n in number_of_body_copies: try: exec("cond = 0\nif cond:\n" + body * n + "else:\n print('cond false')\n") + results.append("ok") except MemoryError: print("SKIP") raise SystemExit - except RuntimeError: - print("RuntimeError") + except RuntimeError as er: + results.append(repr(er)) +print(results) # Test changing size of code info (source line/bytecode mapping) due to changing # bytecode size in the final passes. This test is very specific to how the diff --git a/tests/stress/bytecode_limit.py.exp b/tests/stress/bytecode_limit.py.exp index 1d892250b01..50511665f00 100644 --- a/tests/stress/bytecode_limit.py.exp +++ b/tests/stress/bytecode_limit.py.exp @@ -1,5 +1,4 @@ -RuntimeError -RuntimeError cond false cond false +["RuntimeError('bytecode overflow',)", "RuntimeError('bytecode overflow',)", 'ok', 'ok'] [123] diff --git a/tests/stress/dict_copy.py b/tests/stress/dict_copy.py index 73d3a5b51d6..f9b742e20f7 100644 --- a/tests/stress/dict_copy.py +++ b/tests/stress/dict_copy.py @@ -1,6 +1,11 @@ # copying a large dictionary -a = {i: 2 * i for i in range(1000)} +try: + a = {i: 2 * i for i in range(1000)} +except MemoryError: + print("SKIP") + raise SystemExit + b = a.copy() for i in range(1000): print(i, b[i]) diff --git a/tests/stress/dict_create.py b/tests/stress/dict_create.py index e9db40a8e6c..91a83a12f9d 100644 --- a/tests/stress/dict_create.py +++ b/tests/stress/dict_create.py @@ -3,6 +3,10 @@ d = {} x = 1 while x < 1000: - d[x] = x + try: + d[x] = x + except MemoryError: + print("SKIP") + raise SystemExit x += 1 print(d[500]) diff --git a/tests/stress/fun_call_limit.py b/tests/stress/fun_call_limit.py index b802aadd558..69f8aa5aec4 100644 --- a/tests/stress/fun_call_limit.py +++ b/tests/stress/fun_call_limit.py @@ -16,14 +16,16 @@ def test(n): # If the port has at least 32-bits then this test should pass. -print(test(29)) +print(test(28)) # This test should fail on all ports (overflows a small int). print(test(70)) -# Check that there is a correct transition to the limit of too many args before *args. +# 28 is the biggest number that will pass on a 32-bit port using object +# representation B, which has 1<<28 still fitting in a positive small int. reached_limit = False -for i in range(30, 70): +any_test_succeeded = False +for i in range(28, 70): result = test(i) if reached_limit: if result != "SyntaxError": @@ -34,3 +36,5 @@ def test(n): else: if result != i + 4: print("FAIL") + any_test_succeeded = True +assert any_test_succeeded # At least one iteration must have passed diff --git a/tests/stress/fun_call_limit.py.exp b/tests/stress/fun_call_limit.py.exp index 53d2b280430..491abbfa8be 100644 --- a/tests/stress/fun_call_limit.py.exp +++ b/tests/stress/fun_call_limit.py.exp @@ -1,2 +1,2 @@ -33 +32 SyntaxError diff --git a/tests/stress/qstr_limit.py b/tests/stress/qstr_limit.py index 08b10a039f5..c7bd437f3ad 100644 --- a/tests/stress/qstr_limit.py +++ b/tests/stress/qstr_limit.py @@ -12,8 +12,8 @@ def make_id(n, base="a"): var = make_id(l) try: exec(var + "=1", g) - except RuntimeError: - print("RuntimeError", l) + except RuntimeError as er: + print("RuntimeError", er, l) continue print(var in g) @@ -26,16 +26,16 @@ def f(**k): for l in range(254, 259): try: exec("f({}=1)".format(make_id(l))) - except RuntimeError: - print("RuntimeError", l) + except RuntimeError as er: + print("RuntimeError", er, l) # type construction for l in range(254, 259): id = make_id(l) try: - print(type(id, (), {}).__name__) - except RuntimeError: - print("RuntimeError", l) + print(type(id, (), {})) + except RuntimeError as er: + print("RuntimeError", er, l) # hasattr, setattr, getattr @@ -48,28 +48,20 @@ class A: a = A() try: setattr(a, id, 123) - except RuntimeError: - print("RuntimeError", l) + except RuntimeError as er: + print("RuntimeError", er, l) try: print(hasattr(a, id), getattr(a, id)) - except RuntimeError: - print("RuntimeError", l) + except RuntimeError as er: + print("RuntimeError", er, l) # format with keys for l in range(254, 259): id = make_id(l) try: print(("{" + id + "}").format(**{id: l})) - except RuntimeError: - print("RuntimeError", l) - -# modulo format with keys -for l in range(254, 259): - id = make_id(l) - try: - print(("%(" + id + ")d") % {id: l}) - except RuntimeError: - print("RuntimeError", l) + except RuntimeError as er: + print("RuntimeError", er, l) # import module # (different OS's have different results so only run those that are consistent) @@ -78,8 +70,8 @@ class A: __import__(make_id(l)) except ImportError: print("ok", l) - except RuntimeError: - print("RuntimeError", l) + except RuntimeError as er: + print("RuntimeError", er, l) # import package for l in (100, 101, 102, 128, 129): @@ -87,5 +79,5 @@ class A: exec("import " + make_id(l) + "." + make_id(l, "A")) except ImportError: print("ok", l) - except RuntimeError: - print("RuntimeError", l) + except RuntimeError as er: + print("RuntimeError", er, l) diff --git a/tests/stress/qstr_limit.py.exp b/tests/stress/qstr_limit.py.exp index 455761bc71e..2349adf220f 100644 --- a/tests/stress/qstr_limit.py.exp +++ b/tests/stress/qstr_limit.py.exp @@ -1,43 +1,38 @@ True True -RuntimeError 256 -RuntimeError 257 -RuntimeError 258 +RuntimeError name too long 256 +RuntimeError name too long 257 +RuntimeError name too long 258 {'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst': 1} {'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu': 1} -RuntimeError 256 -RuntimeError 257 -RuntimeError 258 -abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst -abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu -RuntimeError 256 -RuntimeError 257 -RuntimeError 258 +RuntimeError name too long 256 +RuntimeError name too long 257 +RuntimeError name too long 258 + + +RuntimeError name too long 256 +RuntimeError name too long 257 +RuntimeError name too long 258 True 123 True 123 -RuntimeError 256 -RuntimeError 256 -RuntimeError 257 -RuntimeError 257 -RuntimeError 258 -RuntimeError 258 +RuntimeError name too long 256 +RuntimeError name too long 256 +RuntimeError name too long 257 +RuntimeError name too long 257 +RuntimeError name too long 258 +RuntimeError name too long 258 254 255 -RuntimeError 256 -RuntimeError 257 -RuntimeError 258 -254 -255 -RuntimeError 256 -RuntimeError 257 -RuntimeError 258 +RuntimeError name too long 256 +RuntimeError name too long 257 +RuntimeError name too long 258 ok 100 ok 101 -RuntimeError 256 -RuntimeError 257 -RuntimeError 258 +RuntimeError name too long 256 +RuntimeError name too long 257 +RuntimeError name too long 258 ok 100 ok 101 ok 102 -RuntimeError 128 -RuntimeError 129 +RuntimeError name too long 128 +RuntimeError name too long 129 diff --git a/tests/stress/qstr_limit_str_modulo.py b/tests/stress/qstr_limit_str_modulo.py new file mode 100644 index 00000000000..90b9f4364ec --- /dev/null +++ b/tests/stress/qstr_limit_str_modulo.py @@ -0,0 +1,21 @@ +# Test interning qstrs that go over the qstr length limit (255 bytes in default configuration). +# The tests here are specifically for str formatting with %. + +try: + "" % () +except TypeError: + print("SKIP") + raise SystemExit + + +def make_id(n, base="a"): + return "".join(chr(ord(base) + i % 26) for i in range(n)) + + +# modulo format with keys +for l in range(254, 259): + id = make_id(l) + try: + print(("%(" + id + ")d") % {id: l}) + except RuntimeError as er: + print("RuntimeError", er, l) diff --git a/tests/stress/qstr_limit_str_modulo.py.exp b/tests/stress/qstr_limit_str_modulo.py.exp new file mode 100644 index 00000000000..3632c85bffe --- /dev/null +++ b/tests/stress/qstr_limit_str_modulo.py.exp @@ -0,0 +1,5 @@ +254 +255 +RuntimeError name too long 256 +RuntimeError name too long 257 +RuntimeError name too long 258 diff --git a/tests/stress/recursive_iternext.py b/tests/stress/recursive_iternext.py index bbc389e7262..c737f1e36d7 100644 --- a/tests/stress/recursive_iternext.py +++ b/tests/stress/recursive_iternext.py @@ -1,4 +1,8 @@ # This tests that recursion with iternext doesn't lead to segfault. +# +# This test segfaults CPython, but that's not a bug as CPython doesn't enforce +# limits on C recursion - see +# https://github.com/python/cpython/issues/58218#issuecomment-1093570209 try: enumerate filter @@ -9,49 +13,25 @@ print("SKIP") raise SystemExit -# We need to pick an N that is large enough to hit the recursion -# limit, but not too large that we run out of heap memory. -try: - # large stack/heap, eg unix - [0] * 80000 - N = 5000 -except: - try: - # medium, eg pyboard - [0] * 10000 - N = 1000 - except: - # small, eg esp8266 - N = 100 - -try: - x = (1, 2) - for i in range(N): - x = enumerate(x) - tuple(x) -except RuntimeError: - print("RuntimeError") -try: +# Progressively build a bigger nested iterator structure (10 at a time for speed), +# and then try to evaluate it via tuple(x) which makes deep recursive function calls. +# +# Eventually this should raise a RuntimeError as MicroPython runs out of stack. +# It shouldn't ever raise a MemoryError, if it does then somehow MicroPython has +# run out of heap (for the nested structure) before running out of stack. +def recurse_iternext(nested_fn): x = (1, 2) - for i in range(N): - x = filter(None, x) - tuple(x) -except RuntimeError: - print("RuntimeError") + while True: + for _ in range(10): + x = nested_fn(x) + try: + tuple(x) + except RuntimeError: + print("RuntimeError") + break -try: - x = (1, 2) - for i in range(N): - x = map(max, x, ()) - tuple(x) -except RuntimeError: - print("RuntimeError") -try: - x = (1, 2) - for i in range(N): - x = zip(x) - tuple(x) -except RuntimeError: - print("RuntimeError") +# Test on various nested iterator structures +for nested_fn in [enumerate, lambda x: filter(None, x), lambda x: map(max, x, ()), zip]: + recurse_iternext(nested_fn) diff --git a/tests/target_wiring/EK_RA6M2.py b/tests/target_wiring/EK_RA6M2.py new file mode 100644 index 00000000000..7d4a8cbbd64 --- /dev/null +++ b/tests/target_wiring/EK_RA6M2.py @@ -0,0 +1,8 @@ +# Target wiring for EK_RA6M2. +# +# Connect: +# - P601 to P602 + +# UART(9) is on P602/P601. +uart_loopback_args = (9,) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/NUCLEO_WB55.py b/tests/target_wiring/NUCLEO_WB55.py new file mode 100644 index 00000000000..ad7c120d377 --- /dev/null +++ b/tests/target_wiring/NUCLEO_WB55.py @@ -0,0 +1,8 @@ +# Target wiring for NUCLEO_WB55. +# +# Connect: +# - PA2 to PA3 + +# LPUART(1) is on PA2/PA3. +uart_loopback_args = ("LP1",) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/PYBx.py b/tests/target_wiring/PYBx.py new file mode 100644 index 00000000000..10ce520ef0a --- /dev/null +++ b/tests/target_wiring/PYBx.py @@ -0,0 +1,8 @@ +# Target wiring for PYBV10, PYBV11, PYBLITEV10, PYBD_SF2, PYBD_SF3, PYBD_SF6. +# +# Connect: +# - X1 to X2 + +# UART("XA") is on X1/X2 (usually UART(4) on PA0/PA1). +uart_loopback_args = ("XA",) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/ZEPHYR_NUCLEO_WB55RG.py b/tests/target_wiring/ZEPHYR_NUCLEO_WB55RG.py new file mode 100644 index 00000000000..c7ca2ac26f7 --- /dev/null +++ b/tests/target_wiring/ZEPHYR_NUCLEO_WB55RG.py @@ -0,0 +1,7 @@ +# Target wiring for zephyr nucleo_wb55rg. +# +# Connect: +# - TX=PC0 to RX=PC1 + +uart_loopback_args = ("lpuart1",) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/alif.py b/tests/target_wiring/alif.py new file mode 100644 index 00000000000..18f3cbe7e5e --- /dev/null +++ b/tests/target_wiring/alif.py @@ -0,0 +1,7 @@ +# Target wiring for general alif board. +# +# Connect: +# - UART1 TX and RX, usually P0_5 and P0_4 + +uart_loopback_args = (1,) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/esp32.py b/tests/target_wiring/esp32.py new file mode 100644 index 00000000000..2767cd5acb2 --- /dev/null +++ b/tests/target_wiring/esp32.py @@ -0,0 +1,12 @@ +# Target wiring for general esp32 board. +# +# Connect: +# - GPIO4 to GPIO5 +# - GPIO12 to GPIO13 + +uart_loopback_args = (1,) +uart_loopback_kwargs = {"tx": 4, "rx": 5} + +encoder_loopback_id = 0 +encoder_loopback_out_pins = (4, 12) +encoder_loopback_in_pins = (5, 13) diff --git a/tests/target_wiring/mimxrt.py b/tests/target_wiring/mimxrt.py new file mode 100644 index 00000000000..669e9095990 --- /dev/null +++ b/tests/target_wiring/mimxrt.py @@ -0,0 +1,7 @@ +# Target wiring for general mimxrt board. +# +# Connect: +# - UART1 TX and RX, usually D0 and D1 + +uart_loopback_args = (1,) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/nrf.py b/tests/target_wiring/nrf.py new file mode 100644 index 00000000000..6979dd28ee5 --- /dev/null +++ b/tests/target_wiring/nrf.py @@ -0,0 +1,7 @@ +# Target wiring for general nrf board. +# +# Connect: +# - UART0 TX and RX + +uart_loopback_args = (0,) +uart_loopback_kwargs = {} diff --git a/tests/target_wiring/rp2.py b/tests/target_wiring/rp2.py new file mode 100644 index 00000000000..cb0fa0d6263 --- /dev/null +++ b/tests/target_wiring/rp2.py @@ -0,0 +1,7 @@ +# Target wiring for general rp2 board. +# +# Connect: +# - GPIO0 to GPIO1 + +uart_loopback_args = (0,) +uart_loopback_kwargs = {"tx": "GPIO0", "rx": "GPIO1"} diff --git a/tests/target_wiring/samd.py b/tests/target_wiring/samd.py new file mode 100644 index 00000000000..887c43a242f --- /dev/null +++ b/tests/target_wiring/samd.py @@ -0,0 +1,7 @@ +# Target wiring for general samd board. +# +# Connect: +# - D0 to D1 + +uart_loopback_args = () +uart_loopback_kwargs = {"tx": "D1", "rx": "D0"} diff --git a/tests/testlib/audiofilterhelper.py b/tests/testlib/audiofilterhelper.py new file mode 100644 index 00000000000..c182bb73c57 --- /dev/null +++ b/tests/testlib/audiofilterhelper.py @@ -0,0 +1,33 @@ +import array +import random +from ulab import numpy as np +from math import sin, pi, ceil +from audiocore import get_buffer, RawSample +from synthio import Note, LFO, MathOperation, Synthesizer + +random.seed(41) + +whitedata = array.array("h", [random.randint(-32000, 32000) for i in range(600)]) +white8k = RawSample(whitedata, sample_rate=8000) + +sinedata = array.array("h", [int(32767 * sin(i * 2 * pi / 600)) for i in range(600)]) +sine8k = RawSample(sinedata, sample_rate=8000) + + +def synth_test(_gen=None, dtype=np.int16, divisor=32768, channel_count=1): + def func(gen): + g = gen() + synth, blocks = next(g) + t = 0 + for nframes in g: + for i in range(nframes): + samples = np.frombuffer(get_buffer(synth)[1], dtype=dtype) / divisor + block_values = [b.value for b in blocks] + for k in range(0, len(samples), channel_count): + print(t, *(list(samples[k : k + channel_count]) + block_values)) + t += 1 + + if _gen is None: + return func + else: + func(_gen) diff --git a/tests/thread/disable_irq.py b/tests/thread/disable_irq.py new file mode 100644 index 00000000000..596e3e477b9 --- /dev/null +++ b/tests/thread/disable_irq.py @@ -0,0 +1,57 @@ +# Ensure that disabling IRQs creates mutual exclusion between threads +# (also tests nesting of disable_irq across threads) + +# CIRCUITPY-CHANGE: no machine +try: + import machine + import time + import _thread +except ImportError: + print("SKIP") + raise SystemExit + +if not hasattr(machine, "disable_irq"): + print("SKIP") + raise SystemExit + +count = 0 +thread_done = False + + +def inc_count(): + global count + a = machine.disable_irq() + try: + count += 1 + i = 0 + while i < 20: + b = machine.disable_irq() + try: + count += 1 + count -= 1 + i += 1 + finally: + machine.enable_irq(b) + finally: + machine.enable_irq(a) + + +def inc_count_multiple(times): + for _ in range(times): + inc_count() + + +def thread_entry(inc_times): + global thread_done + inc_count_multiple(inc_times) + thread_done = True + + +_thread.start_new_thread(thread_entry, (1000,)) +inc_count_multiple(1000) + +time.sleep(1) + +print("count", count, thread_done) +if count == 2000: + print("PASS") diff --git a/tests/thread/disable_irq.py.exp b/tests/thread/disable_irq.py.exp new file mode 100644 index 00000000000..2174b91d0d0 --- /dev/null +++ b/tests/thread/disable_irq.py.exp @@ -0,0 +1,2 @@ +count 2000 True +PASS diff --git a/tests/thread/mutate_bytearray.py b/tests/thread/mutate_bytearray.py index b4664781a15..7116d291cfe 100644 --- a/tests/thread/mutate_bytearray.py +++ b/tests/thread/mutate_bytearray.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread # the shared bytearray @@ -36,7 +37,7 @@ def th(n, lo, hi): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) # check bytearray has correct contents print(len(ba)) diff --git a/tests/thread/mutate_dict.py b/tests/thread/mutate_dict.py index 3777af66248..dd5f69e6c5d 100644 --- a/tests/thread/mutate_dict.py +++ b/tests/thread/mutate_dict.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread # the shared dict @@ -38,7 +39,7 @@ def th(n, lo, hi): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) # check dict has correct contents print(sorted(di.items())) diff --git a/tests/thread/mutate_instance.py b/tests/thread/mutate_instance.py index 306ad91c95c..63f7fb1e23d 100644 --- a/tests/thread/mutate_instance.py +++ b/tests/thread/mutate_instance.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread @@ -40,7 +41,7 @@ def th(n, lo, hi): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) # check user instance has correct contents print(user.a, user.b, user.c) diff --git a/tests/thread/mutate_list.py b/tests/thread/mutate_list.py index 6f1e8812541..d7398a2f1e0 100644 --- a/tests/thread/mutate_list.py +++ b/tests/thread/mutate_list.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread # the shared list @@ -39,7 +40,7 @@ def th(n, lo, hi): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) # check list has correct contents li.sort() diff --git a/tests/thread/mutate_set.py b/tests/thread/mutate_set.py index 2d9a3e0ce9e..7dcefa1d113 100644 --- a/tests/thread/mutate_set.py +++ b/tests/thread/mutate_set.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread # the shared set @@ -33,7 +34,7 @@ def th(n, lo, hi): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) # check set has correct contents print(sorted(se)) diff --git a/tests/thread/stress_aes.py b/tests/thread/stress_aes.py index b25da855aef..ca25f8ad2fd 100644 --- a/tests/thread/stress_aes.py +++ b/tests/thread/stress_aes.py @@ -273,15 +273,15 @@ def thread_entry(n_loop): elif sys.platform == "rp2": n_thread = 1 n_loop = 2 - elif sys.platform in ("esp32", "pyboard"): + elif sys.platform in ("esp32", "pyboard", "zephyr"): n_thread = 2 n_loop = 2 else: - n_thread = 20 + n_thread = 10 n_loop = 5 for i in range(n_thread): _thread.start_new_thread(thread_entry, (n_loop,)) thread_entry(n_loop) - while count.value < n_thread: + while count.value < n_thread + 1: time.sleep(1) print("done") diff --git a/tests/thread/stress_recurse.py b/tests/thread/stress_recurse.py index 73b3a40f33d..ec8b43fe8fc 100644 --- a/tests/thread/stress_recurse.py +++ b/tests/thread/stress_recurse.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread @@ -24,5 +25,5 @@ def thread_entry(): # busy wait for thread to finish while not finished: - pass + time.sleep(0) print("done") diff --git a/tests/thread/stress_schedule.py b/tests/thread/stress_schedule.py index a5d7dc824ed..362d71aa12e 100644 --- a/tests/thread/stress_schedule.py +++ b/tests/thread/stress_schedule.py @@ -27,6 +27,8 @@ def task(x): n += 1 +# This function must always use the bytecode emitter so it bounces the GIL when running. +@micropython.bytecode def thread(): while thread_run: try: @@ -46,12 +48,14 @@ def thread(): # Wait up to 10 seconds for 10000 tasks to be scheduled. t = time.ticks_ms() while n < _NUM_TASKS and time.ticks_diff(time.ticks_ms(), t) < _TIMEOUT_MS: - pass + time.sleep(0) # Stop all threads. thread_run = False time.sleep_ms(20) +gc.enable() + if n < _NUM_TASKS: # Not all the tasks were scheduled, likely the scheduler stopped working. print(n) diff --git a/tests/thread/thread_coop.py b/tests/thread/thread_coop.py new file mode 100644 index 00000000000..85cda789c93 --- /dev/null +++ b/tests/thread/thread_coop.py @@ -0,0 +1,56 @@ +# Threads should be semi-cooperative, to the point where one busy +# thread can't starve out another. +# +# (Note on ports without the GIL this one should always be true, on ports with GIL it's +# a test of the GIL behaviour.) + +import _thread +import sys +from time import ticks_ms, ticks_diff, sleep_ms +import micropython + + +done = False + +ITERATIONS = 5 +SLEEP_MS = 250 +MAX_DELTA = 30 + +if sys.platform in ("win32", "linux", "darwin"): + # Conventional operating systems get looser timing restrictions + SLEEP_MS = 300 + MAX_DELTA = 100 + + +# This function must always use the bytecode emitter so the VM can bounce the GIL when running. +@micropython.bytecode +def busy_thread(): + while not done: + pass + + +def test_sleeps(): + global done + ok = True + for _ in range(ITERATIONS): + t0 = ticks_ms() + sleep_ms(SLEEP_MS) + t1 = ticks_ms() + d = ticks_diff(t1, t0) + if d < SLEEP_MS - MAX_DELTA or d > SLEEP_MS + MAX_DELTA: + print("Slept too long ", d) + ok = False + print("OK" if ok else "Not OK") + done = True + + +# make the thread the busy one, and check sleep time on main task +_thread.start_new_thread(busy_thread, ()) +test_sleeps() + +sleep_ms(100) +done = False + +# now swap them +_thread.start_new_thread(test_sleeps, ()) +busy_thread() diff --git a/tests/thread/thread_coop.py.exp b/tests/thread/thread_coop.py.exp new file mode 100644 index 00000000000..2c94e483710 --- /dev/null +++ b/tests/thread/thread_coop.py.exp @@ -0,0 +1,2 @@ +OK +OK diff --git a/tests/thread/thread_exc1.py b/tests/thread/thread_exc1.py index cd877409291..cd6599983c1 100644 --- a/tests/thread/thread_exc1.py +++ b/tests/thread/thread_exc1.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread @@ -34,5 +35,5 @@ def thread_entry(): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) print("done") diff --git a/tests/thread/thread_exc2.py.native.exp b/tests/thread/thread_exc2.py.native.exp new file mode 100644 index 00000000000..9b2e715ef8d --- /dev/null +++ b/tests/thread/thread_exc2.py.native.exp @@ -0,0 +1,3 @@ +Unhandled exception in thread started by +ValueError: +done diff --git a/tests/thread/thread_gc1.py b/tests/thread/thread_gc1.py index b36ea9d4c84..45c17cc17be 100644 --- a/tests/thread/thread_gc1.py +++ b/tests/thread/thread_gc1.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import gc import _thread @@ -44,6 +45,6 @@ def thread_entry(n): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) print(n_correct == n_finished) diff --git a/tests/thread/thread_ident1.py b/tests/thread/thread_ident1.py index 2a3732eff53..08cfd3eb36e 100644 --- a/tests/thread/thread_ident1.py +++ b/tests/thread/thread_ident1.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread @@ -27,6 +28,6 @@ def thread_entry(): new_tid = _thread.start_new_thread(thread_entry, ()) while not finished: - pass + time.sleep(0) print("done", type(new_tid) == int, new_tid == tid) diff --git a/tests/thread/thread_lock3.py b/tests/thread/thread_lock3.py index a927dc6829e..c5acfa21b7d 100644 --- a/tests/thread/thread_lock3.py +++ b/tests/thread/thread_lock3.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread lock = _thread.allocate_lock() @@ -26,4 +27,4 @@ def thread_entry(idx): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) diff --git a/tests/thread/thread_lock4.py b/tests/thread/thread_lock4_intbig.py similarity index 100% rename from tests/thread/thread_lock4.py rename to tests/thread/thread_lock4_intbig.py diff --git a/tests/thread/thread_shared1.py b/tests/thread/thread_shared1.py index 251e26fae6c..c2e33abcec7 100644 --- a/tests/thread/thread_shared1.py +++ b/tests/thread/thread_shared1.py @@ -2,6 +2,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread @@ -40,5 +41,5 @@ def thread_entry(n, tup): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) print(tup) diff --git a/tests/thread/thread_shared2.py b/tests/thread/thread_shared2.py index a1223c2b94f..4ce9057ca01 100644 --- a/tests/thread/thread_shared2.py +++ b/tests/thread/thread_shared2.py @@ -3,6 +3,7 @@ # # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd +import time import _thread @@ -31,5 +32,5 @@ def thread_entry(n, lst, idx): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) print(lst) diff --git a/tests/thread/thread_stacksize1.py b/tests/thread/thread_stacksize1.py index 140d165cb34..75e1da9642f 100644 --- a/tests/thread/thread_stacksize1.py +++ b/tests/thread/thread_stacksize1.py @@ -3,6 +3,7 @@ # MIT license; Copyright (c) 2016 Damien P. George on behalf of Pycom Ltd import sys +import time import _thread # different implementations have different minimum sizes @@ -51,5 +52,5 @@ def thread_entry(): # busy wait for threads to finish while n_finished < n_thread: - pass + time.sleep(0) print("done") diff --git a/tests/thread/thread_stdin.py b/tests/thread/thread_stdin.py new file mode 100644 index 00000000000..498b0a3a270 --- /dev/null +++ b/tests/thread/thread_stdin.py @@ -0,0 +1,45 @@ +# Test that having multiple threads block on stdin doesn't cause any issues. +# +# The test doesn't expect any input on stdin. +# +# This is a regression test for https://github.com/micropython/micropython/issues/15230 +# on rp2, but doubles as a general property to test across all ports. +import sys +import time +import _thread + +try: + import select +except ImportError: + print("SKIP") + raise SystemExit + + +class StdinWaiter: + def __init__(self): + self._done = False + + def wait_stdin(self, timeout_ms): + poller = select.poll() + poller.register(sys.stdin, select.POLLIN) + poller.poll(timeout_ms) + # Ignoring the poll result as we don't expect any input + self._done = True + + def is_done(self): + return self._done + + +thread_waiter = StdinWaiter() +_thread.start_new_thread(thread_waiter.wait_stdin, (1000,)) +StdinWaiter().wait_stdin(1000) + +# Spinning here is mostly not necessary but there is some inconsistency waking +# the two threads, especially on CPython CI runners where the thread may not +# have run yet. The actual delay is <20ms but spinning here instead of +# sleep(0.1) means the test can run on MP builds without float support. +while not thread_waiter.is_done(): + time.sleep(0) + +# The background thread should have completed its wait by now. +print(thread_waiter.is_done()) diff --git a/tests/unicode/unicode.py b/tests/unicode/unicode.py index 072e049fde4..58d406e63eb 100644 --- a/tests/unicode/unicode.py +++ b/tests/unicode/unicode.py @@ -5,7 +5,7 @@ # Test all three forms of Unicode escape, and # all blocks of UTF-8 byte patterns -s = "a\xA9\xFF\u0123\u0800\uFFEE\U0001F44C" +s = "a\xa9\xff\u0123\u0800\uffee\U0001f44c" for i in range(-len(s), len(s)): print("s[%d]: %s %X" % (i, s[i], ord(s[i]))) print("s[:%d]: %d chars, '%s'" % (i, len(s[:i]), s[:i])) diff --git a/tests/unix/extra_coverage.py b/tests/unix/extra_coverage.py index 0ea8f7886bf..ec10a44ff39 100644 --- a/tests/unix/extra_coverage.py +++ b/tests/unix/extra_coverage.py @@ -6,6 +6,16 @@ import errno import io +import uctypes + +# create an int-like variable used for coverage of `mp_obj_get_ll` +buf = bytearray(b"\xde\xad\xbe\xef") +struct = uctypes.struct( + uctypes.addressof(buf), + {"f32": uctypes.UINT32 | 0}, + uctypes.BIG_ENDIAN, +) +deadbeef = struct.f32 data = extra_coverage() @@ -23,6 +33,7 @@ print(stream.read(1)) # read 1 byte encounters non-blocking error print(stream.readline()) # readline encounters non-blocking error print(stream.readinto(bytearray(10))) # readinto encounters non-blocking error +print(stream.readinto1(bytearray(10))) # readinto1 encounters non-blocking error print(stream.write(b"1")) # write encounters non-blocking error print(stream.write1(b"1")) # write1 encounters non-blocking error stream.set_buf(b"123") @@ -38,6 +49,28 @@ stream.set_error(0) print(stream.ioctl(0, bytearray(10))) # successful ioctl call +print("# stream.readinto") + +# stream.readinto will read 3 bytes then try to read more to fill the buffer, +# but on the second attempt will encounter EIO and should raise that error. +stream.set_error(errno.EIO) +stream.set_buf(b"123") +buf = bytearray(4) +try: + stream.readinto(buf) +except OSError as er: + print("OSError", er.errno == errno.EIO) +print(buf) + +# stream.readinto1 will read 3 bytes then should return them immediately, and +# not encounter the EIO. +stream.set_error(errno.EIO) +stream.set_buf(b"123") +buf = bytearray(4) +print(stream.readinto1(buf), buf) + +print("# stream textio") + stream2 = data[3] # is textio print(stream2.read(1)) # read 1 byte encounters non-blocking error with textio stream @@ -92,7 +125,7 @@ print(returns_NULL()) -# test for freeze_mpy +# test for freeze_mpy (importing prints several lines) import frozentest print(frozentest.__file__) diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index c75676fad9a..cdb11455694 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -2,25 +2,41 @@ -123 +123 123 -0123 123 -123 -1ABCDEF +123f +123F +7fffffffffffffff +7FFFFFFFFFFFFFFF +18446744073709551615 +789f +789F ab abc ' abc' ' True' 'Tru' false true (null) -2147483648 2147483648 -80000000 -80000000 +8000000f +8000000F abc % +.a . +<%> + + +<43690> +<43690> +<43690> + +<1000.000000> + +<9223372036854775807> # GC -0x0 -0x0 +0 +0 # GC part 2 pass # tracked allocation -m_tracked_head = 0x0 +m_tracked_head = 0 0 1 1 1 2 1 @@ -37,7 +53,7 @@ m_tracked_head = 0x0 5 1 6 1 7 1 -m_tracked_head = 0x0 +m_tracked_head = 0 # vstr tests sts @@ -90,19 +106,29 @@ data 1 12345 6 +-1 +0 +1 +0 +0.000000 +deadbeef +c0ffee777c0ffee +deadbeef +0deadbeef +c0ffee +000c0ffee # runtime utils TypeError: unsupported type for __abs__: 'str' TypeError: unsupported types for __divmod__: 'str', 'str' +0 1 2 OverflowError: overflow converting long int to machine word OverflowError: overflow converting long int to machine word +TypeError: can't convert NoneType to int +TypeError: can't convert NoneType to int ValueError: Warning: test -# format float -? -+1e+00 -+1e+00 # binary 123 456 @@ -122,6 +148,13 @@ unlocked KeyboardInterrupt: KeyboardInterrupt: 10 +loop +scheduled function +loop +scheduled function +loop +scheduled function +scheduled function # ringbuf 99 0 98 1 @@ -144,6 +177,11 @@ cc99 22ff -1 -1 +0 +0 +abc123 +-1 +-2 # pairheap create: 0 0 0 0 pop all: 0 1 2 3 @@ -164,6 +202,8 @@ pop all: 1 2 4 5 1 1 0 0 1 1 +# stackctrl +1 1 # end coverage.c 0123456789 b'0123456789' 7300 @@ -176,11 +216,17 @@ None None None None +None b'123' b'123' b'123' OSError 0 +# stream.readinto +OSError True +bytearray(b'123\x00') +3 bytearray(b'123\x00') +# stream textio None None cpp None @@ -203,8 +249,10 @@ ZeroDivisionError X '\x1b' b'\x00\xff' +frzmpy4 1 +frzmpy4 2 NULL -uPy +interned a long string that is not interned a string that has unicode αβγ chars b'bytes 1234\x01' diff --git a/tests/unix/ffi_float2.py b/tests/unix/ffi_float2.py index bbed6966627..eac6cd106cf 100644 --- a/tests/unix/ffi_float2.py +++ b/tests/unix/ffi_float2.py @@ -29,4 +29,5 @@ def ffi_open(names): for fun in (tgammaf,): for val in (0.5, 1, 1.0, 1.5, 4, 4.0): - print("%.6f" % fun(val)) + # limit to 5 decimals in order to pass with REPR_C with FORMAT_IMPL_BASIC + print("%.5f" % fun(val)) diff --git a/tests/unix/ffi_float2.py.exp b/tests/unix/ffi_float2.py.exp index 58fc6a01acb..4c750e223a3 100644 --- a/tests/unix/ffi_float2.py.exp +++ b/tests/unix/ffi_float2.py.exp @@ -1,6 +1,6 @@ -1.772454 -1.000000 -1.000000 -0.886227 -6.000000 -6.000000 +1.77245 +1.00000 +1.00000 +0.88623 +6.00000 +6.00000 diff --git a/tests/unix/ffi_int_base.py b/tests/unix/ffi_int_base.py new file mode 100644 index 00000000000..906bc3c1e14 --- /dev/null +++ b/tests/unix/ffi_int_base.py @@ -0,0 +1,49 @@ +# common tests for ffi_int_types/long32/long64 +# requires ffi_lib.c to be compiled as: $(CC) -shared -o ffi_lib.so ffi_lib.c + +import os, sys + +try: + import ffi +except ImportError: + print("SKIP") + raise SystemExit + +ffi_lib_filename = sys.argv[0].rsplit("/", 1)[0] + "/ffi_lib.so" +try: + os.stat(ffi_lib_filename) +except OSError: + print("SKIP") + raise SystemExit + +ffi_lib = ffi.open(ffi_lib_filename) + + +def test(funcs): + for type, name in funcs: + func = ffi_lib.func(type, name, type) + for val in ( + 0, + 0x7F, + 0x80, + 0xFF, + 0x100, + 0x7FFF, + 0x8000, + 0xFFFF, + 0x10000, + 0x7FFFFFFF, + 0x80000000, + 0xFFFFFFFF, + 0x100000000, + 0x7FFF_FFFF_FFFF_FFFF, + 0x8000_0000_0000_0000, + 0xFFFF_FFFF_FFFF_FFFF, + 0x1_0000_0000_0000_0000, + ): + print("{}({:x}) = {:x}".format(name, val, func(val))) + + +if __name__ == "__main__": + print("SKIP") + raise SystemExit diff --git a/tests/unix/ffi_int_long32.py b/tests/unix/ffi_int_long32.py new file mode 100644 index 00000000000..32fdb8e0ec7 --- /dev/null +++ b/tests/unix/ffi_int_long32.py @@ -0,0 +1,16 @@ +# test 32-bit long arguments and return types for ffi functions + +import struct + +import ffi_int_base + +if struct.calcsize("l") != 4: + print("SKIP") + raise SystemExit + +ffi_int_base.test( + [ + ("l", "fli"), + ("L", "flu"), + ] +) diff --git a/tests/unix/ffi_int_long32.py.exp b/tests/unix/ffi_int_long32.py.exp new file mode 100644 index 00000000000..e0f1338a48e --- /dev/null +++ b/tests/unix/ffi_int_long32.py.exp @@ -0,0 +1,34 @@ +fli(0) = 1 +fli(7f) = 7e +fli(80) = 81 +fli(ff) = fe +fli(100) = 101 +fli(7fff) = 7ffe +fli(8000) = 8001 +fli(ffff) = fffe +fli(10000) = 10001 +fli(7fffffff) = 7ffffffe +fli(80000000) = -7fffffff +fli(ffffffff) = -2 +fli(100000000) = 1 +fli(7fffffffffffffff) = -2 +fli(8000000000000000) = 1 +fli(ffffffffffffffff) = -2 +fli(10000000000000000) = 1 +flu(0) = 1 +flu(7f) = 7e +flu(80) = 81 +flu(ff) = fe +flu(100) = 101 +flu(7fff) = 7ffe +flu(8000) = 8001 +flu(ffff) = fffe +flu(10000) = 10001 +flu(7fffffff) = 7ffffffe +flu(80000000) = 80000001 +flu(ffffffff) = fffffffe +flu(100000000) = 1 +flu(7fffffffffffffff) = fffffffe +flu(8000000000000000) = 1 +flu(ffffffffffffffff) = fffffffe +flu(10000000000000000) = 1 diff --git a/tests/unix/ffi_int_long64.py b/tests/unix/ffi_int_long64.py new file mode 100644 index 00000000000..55bf6605232 --- /dev/null +++ b/tests/unix/ffi_int_long64.py @@ -0,0 +1,16 @@ +# test 64-bit long arguments and return types for ffi functions + +import struct + +import ffi_int_base + +if struct.calcsize("l") != 8: + print("SKIP") + raise SystemExit + +ffi_int_base.test( + [ + ("l", "fli"), + ("L", "flu"), + ] +) diff --git a/tests/unix/ffi_int_long64.py.exp b/tests/unix/ffi_int_long64.py.exp new file mode 100644 index 00000000000..904e6c3ed44 --- /dev/null +++ b/tests/unix/ffi_int_long64.py.exp @@ -0,0 +1,34 @@ +fli(0) = 1 +fli(7f) = 7e +fli(80) = 81 +fli(ff) = fe +fli(100) = 101 +fli(7fff) = 7ffe +fli(8000) = 8001 +fli(ffff) = fffe +fli(10000) = 10001 +fli(7fffffff) = 7ffffffe +fli(80000000) = 80000001 +fli(ffffffff) = fffffffe +fli(100000000) = 100000001 +fli(7fffffffffffffff) = 7ffffffffffffffe +fli(8000000000000000) = -7fffffffffffffff +fli(ffffffffffffffff) = -2 +fli(10000000000000000) = 1 +flu(0) = 1 +flu(7f) = 7e +flu(80) = 81 +flu(ff) = fe +flu(100) = 101 +flu(7fff) = 7ffe +flu(8000) = 8001 +flu(ffff) = fffe +flu(10000) = 10001 +flu(7fffffff) = 7ffffffe +flu(80000000) = 80000001 +flu(ffffffff) = fffffffe +flu(100000000) = 100000001 +flu(7fffffffffffffff) = 7ffffffffffffffe +flu(8000000000000000) = 8000000000000001 +flu(ffffffffffffffff) = fffffffffffffffe +flu(10000000000000000) = 1 diff --git a/tests/unix/ffi_int_types.py b/tests/unix/ffi_int_types.py new file mode 100644 index 00000000000..24fa2a721b2 --- /dev/null +++ b/tests/unix/ffi_int_types.py @@ -0,0 +1,16 @@ +# test 8/16/32/64 bit signed/unsigned integer arguments and return types for ffi functions + +import ffi_int_base + +ffi_int_base.test( + [ + ("b", "f8i"), + ("B", "f8u"), + ("h", "f16i"), + ("H", "f16u"), + ("i", "f32i"), + ("I", "f32u"), + ("q", "f64i"), + ("Q", "f64u"), + ] +) diff --git a/tests/unix/ffi_int_types.py.exp b/tests/unix/ffi_int_types.py.exp new file mode 100644 index 00000000000..d6324477d61 --- /dev/null +++ b/tests/unix/ffi_int_types.py.exp @@ -0,0 +1,136 @@ +f8i(0) = 1 +f8i(7f) = 7e +f8i(80) = -7f +f8i(ff) = -2 +f8i(100) = 1 +f8i(7fff) = -2 +f8i(8000) = 1 +f8i(ffff) = -2 +f8i(10000) = 1 +f8i(7fffffff) = -2 +f8i(80000000) = 1 +f8i(ffffffff) = -2 +f8i(100000000) = 1 +f8i(7fffffffffffffff) = -2 +f8i(8000000000000000) = 1 +f8i(ffffffffffffffff) = -2 +f8i(10000000000000000) = 1 +f8u(0) = 1 +f8u(7f) = 7e +f8u(80) = 81 +f8u(ff) = fe +f8u(100) = 1 +f8u(7fff) = fe +f8u(8000) = 1 +f8u(ffff) = fe +f8u(10000) = 1 +f8u(7fffffff) = fe +f8u(80000000) = 1 +f8u(ffffffff) = fe +f8u(100000000) = 1 +f8u(7fffffffffffffff) = fe +f8u(8000000000000000) = 1 +f8u(ffffffffffffffff) = fe +f8u(10000000000000000) = 1 +f16i(0) = 1 +f16i(7f) = 7e +f16i(80) = 81 +f16i(ff) = fe +f16i(100) = 101 +f16i(7fff) = 7ffe +f16i(8000) = -7fff +f16i(ffff) = -2 +f16i(10000) = 1 +f16i(7fffffff) = -2 +f16i(80000000) = 1 +f16i(ffffffff) = -2 +f16i(100000000) = 1 +f16i(7fffffffffffffff) = -2 +f16i(8000000000000000) = 1 +f16i(ffffffffffffffff) = -2 +f16i(10000000000000000) = 1 +f16u(0) = 1 +f16u(7f) = 7e +f16u(80) = 81 +f16u(ff) = fe +f16u(100) = 101 +f16u(7fff) = 7ffe +f16u(8000) = 8001 +f16u(ffff) = fffe +f16u(10000) = 1 +f16u(7fffffff) = fffe +f16u(80000000) = 1 +f16u(ffffffff) = fffe +f16u(100000000) = 1 +f16u(7fffffffffffffff) = fffe +f16u(8000000000000000) = 1 +f16u(ffffffffffffffff) = fffe +f16u(10000000000000000) = 1 +f32i(0) = 1 +f32i(7f) = 7e +f32i(80) = 81 +f32i(ff) = fe +f32i(100) = 101 +f32i(7fff) = 7ffe +f32i(8000) = 8001 +f32i(ffff) = fffe +f32i(10000) = 10001 +f32i(7fffffff) = 7ffffffe +f32i(80000000) = -7fffffff +f32i(ffffffff) = -2 +f32i(100000000) = 1 +f32i(7fffffffffffffff) = -2 +f32i(8000000000000000) = 1 +f32i(ffffffffffffffff) = -2 +f32i(10000000000000000) = 1 +f32u(0) = 1 +f32u(7f) = 7e +f32u(80) = 81 +f32u(ff) = fe +f32u(100) = 101 +f32u(7fff) = 7ffe +f32u(8000) = 8001 +f32u(ffff) = fffe +f32u(10000) = 10001 +f32u(7fffffff) = 7ffffffe +f32u(80000000) = 80000001 +f32u(ffffffff) = fffffffe +f32u(100000000) = 1 +f32u(7fffffffffffffff) = fffffffe +f32u(8000000000000000) = 1 +f32u(ffffffffffffffff) = fffffffe +f32u(10000000000000000) = 1 +f64i(0) = 1 +f64i(7f) = 7e +f64i(80) = 81 +f64i(ff) = fe +f64i(100) = 101 +f64i(7fff) = 7ffe +f64i(8000) = 8001 +f64i(ffff) = fffe +f64i(10000) = 10001 +f64i(7fffffff) = 7ffffffe +f64i(80000000) = 80000001 +f64i(ffffffff) = fffffffe +f64i(100000000) = 100000001 +f64i(7fffffffffffffff) = 7ffffffffffffffe +f64i(8000000000000000) = -7fffffffffffffff +f64i(ffffffffffffffff) = -2 +f64i(10000000000000000) = 1 +f64u(0) = 1 +f64u(7f) = 7e +f64u(80) = 81 +f64u(ff) = fe +f64u(100) = 101 +f64u(7fff) = 7ffe +f64u(8000) = 8001 +f64u(ffff) = fffe +f64u(10000) = 10001 +f64u(7fffffff) = 7ffffffe +f64u(80000000) = 80000001 +f64u(ffffffff) = fffffffe +f64u(100000000) = 100000001 +f64u(7fffffffffffffff) = 7ffffffffffffffe +f64u(8000000000000000) = 8000000000000001 +f64u(ffffffffffffffff) = fffffffffffffffe +f64u(10000000000000000) = 1 diff --git a/tests/unix/ffi_lib.c b/tests/unix/ffi_lib.c index 35340536aee..dae4e04bc44 100644 --- a/tests/unix/ffi_lib.c +++ b/tests/unix/ffi_lib.c @@ -31,3 +31,11 @@ int64_t f64i(int64_t x) { uint64_t f64u(uint64_t x) { return x ^ 1; } + +long fli(long x) { + return x ^ 1; +} + +unsigned long flu(unsigned long x) { + return x ^ 1; +} diff --git a/tests/unix/mod_os.py b/tests/unix/mod_os.py index f69fa45b2b2..468f6badd1e 100644 --- a/tests/unix/mod_os.py +++ b/tests/unix/mod_os.py @@ -1,6 +1,9 @@ # This module is not entirely compatible with CPython import os +if not hasattr(os, "getenv"): + print("SKIP") + raise SystemExit os.putenv("TEST_VARIABLE", "TEST_VALUE") diff --git a/tests/unix/time_mktime_localtime.py b/tests/unix/time_mktime_localtime.py index d1c03c103d7..df5d6cda690 100644 --- a/tests/unix/time_mktime_localtime.py +++ b/tests/unix/time_mktime_localtime.py @@ -1,4 +1,8 @@ -import time +try: + import time +except ImportError: + print("SKIP") + raise SystemExit DAYS_PER_MONTH = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] diff --git a/tools/.gitignore b/tools/.gitignore deleted file mode 100644 index 9f65f493bc6..00000000000 --- a/tools/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -tinytest/.gitignore -tinytest/.travis.yml -tinytest/Makefile -tinytest/Makefile.arm-cortex-m3-qemu -tinytest/Makefile.avr -tinytest/TODO -tinytest/portable_demo.c -tinytest/tinytest_demo.c diff --git a/tools/analyze_heap_dump.py b/tools/analyze_heap_dump.py index a5e5e1d48ea..a7be95db7d9 100755 --- a/tools/analyze_heap_dump.py +++ b/tools/analyze_heap_dump.py @@ -82,7 +82,7 @@ help="Draw the ownership graph of blocks on the heap", ) @click.option("--analyze-snapshots", default="last", type=click.Choice(["all", "last"])) -def do_all_the_things( +def do_all_the_things( # noqa: C901 too complex ram_filename, bin_filename, map_filename, diff --git a/tools/analyze_mpy.py b/tools/analyze_mpy.py index 3f212e26791..f8da7a85f9d 100755 --- a/tools/analyze_mpy.py +++ b/tools/analyze_mpy.py @@ -229,7 +229,7 @@ def __init__(self, encoded_raw_code): while bc.peek(1)[0] == 0xFF: bc.read(1) bc = bytearray(bc.read()) - # print(encoded_code_info, bc) + print(encoded_code_info, bc) self.qstrs = [] diff --git a/tools/ar_util.py b/tools/ar_util.py new file mode 100644 index 00000000000..b90d3790314 --- /dev/null +++ b/tools/ar_util.py @@ -0,0 +1,236 @@ +#!/usr/bin/env python3 +# +# This file is part of the MicroPython project, http://micropython.org/ +# +# The MIT License (MIT) +# +# Copyright (c) 2024 Volodymyr Shymanskyy +# +# 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. + +import os +import re +import hashlib +import functools +import pickle + +from elftools.elf import elffile +from collections import defaultdict + +try: + from ar import Archive +except: + Archive = None + + +class PickleCache: + def __init__(self, path, prefix=""): + self.path = path + self._get_fn = lambda key: os.path.join(path, prefix + key[:24]) + + def store(self, key, data): + os.makedirs(self.path, exist_ok=True) + # See also https://bford.info/cachedir/ + cachedir_tag_path = os.path.join(self.path, "CACHEDIR.TAG") + if not os.path.exists(cachedir_tag_path): + with open(cachedir_tag_path, "w") as f: + f.write( + "Signature: 8a477f597d28d172789f06886806bc55\n" + "# This file is a cache directory tag created by MicroPython.\n" + "# For information about cache directory tags see https://bford.info/cachedir/\n" + ) + with open(self._get_fn(key), "wb") as f: + pickle.dump(data, f) + + def load(self, key): + with open(self._get_fn(key), "rb") as f: + return pickle.load(f) + + +def cached(key, cache): + def decorator(func): + @functools.wraps(func) + def wrapper(*args, **kwargs): + cache_key = key(*args, **kwargs) + try: + d = cache.load(cache_key) + if d["key"] != cache_key: + raise Exception("Cache key mismatch") + return d["data"] + except Exception: + res = func(*args, **kwargs) + try: + cache.store( + cache_key, + { + "key": cache_key, + "data": res, + }, + ) + except Exception: + pass + return res + + return wrapper + + return decorator + + +class CachedArFile: + def __init__(self, fn): + if not Archive: + raise RuntimeError("Please run 'pip install ar' to link .a files") + self.fn = fn + self._archive = Archive(open(fn, "rb")) + info = self.load_symbols() + self.objs = info["objs"] + self.symbols = info["symbols"] + + def open(self, obj): + return self._archive.open(obj, "rb") + + def _cache_key(self): + sha = hashlib.sha256() + with open(self.fn, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + sha.update(chunk) + # Change this salt if the cache data format changes + sha.update(bytes.fromhex("00000000000000000000000000000001")) + return sha.hexdigest() + + @cached(key=_cache_key, cache=PickleCache(path=".mpy_ld_cache", prefix="ar_")) + def load_symbols(self): + print("Loading", self.fn) + objs = defaultdict(lambda: {"def": set(), "undef": set(), "weak": set()}) + symbols = {} + for entry in self._archive: + obj_name = entry.name + elf = elffile.ELFFile(self.open(obj_name)) + symtab = elf.get_section_by_name(".symtab") + if not symtab: + continue + + obj = objs[obj_name] + + for symbol in symtab.iter_symbols(): + sym_name = symbol.name + sym_bind = symbol["st_info"]["bind"] + + if sym_bind in ("STB_GLOBAL", "STB_WEAK"): + if symbol.entry["st_shndx"] != "SHN_UNDEF": + obj["def"].add(sym_name) + symbols[sym_name] = obj_name + else: + obj["undef"].add(sym_name) + + if sym_bind == "STB_WEAK": + obj["weak"].add(sym_name) + + return {"objs": dict(objs), "symbols": symbols} + + +def resolve(archives, symbols): + resolved_objs = [] # Object files needed to resolve symbols + unresolved_symbols = set() + provided_symbols = {} # Which symbol is provided by which object + symbol_stack = list(symbols) + + # A helper function to handle symbol resolution from a particular object + def add_obj(archive, symbol): + obj_name = archive.symbols[symbol] + obj_info = archive.objs[obj_name] + + obj_tuple = (archive, obj_name) + if obj_tuple in resolved_objs: + return # Already processed this object + + resolved_objs.append(obj_tuple) + + # Add the symbols this object defines + for defined_symbol in obj_info["def"]: + if defined_symbol in provided_symbols and not defined_symbol.startswith( + "__x86.get_pc_thunk." + ): + if defined_symbol in obj_info["weak"]: + continue + else: + raise RuntimeError(f"Multiple definitions for {defined_symbol}") + provided_symbols[defined_symbol] = obj_name # TODO: mark weak if needed + + # Recursively add undefined symbols from this object + for undef_symbol in obj_info["undef"]: + if undef_symbol in obj_info["weak"]: + print(f"Skippping weak dependency: {undef_symbol}") + continue + if undef_symbol not in provided_symbols: + symbol_stack.append(undef_symbol) # Add undefined symbol to resolve + + while symbol_stack: + symbol = symbol_stack.pop(0) + + if symbol in provided_symbols: + continue # Symbol is already resolved + + found = False + for archive in archives: + if symbol in archive.symbols: + add_obj(archive, symbol) + found = True + break + + if not found: + unresolved_symbols.add(symbol) + + return resolved_objs, list(unresolved_symbols) + + +def expand_ld_script(fn): + # This function parses a subset of ld scripts + # Typically these are just groups of static lib references + group_pattern = re.compile(r"GROUP\s*\(\s*([^\)]+)\s*\)", re.MULTILINE) + output_format_pattern = re.compile(r"OUTPUT_FORMAT\s*\(\s*([^\)]+)\s*\)", re.MULTILINE) + comment_pattern = re.compile(r"/\*.*?\*/", re.MULTILINE | re.DOTALL) + + with open(fn, "r") as f: + content = f.read() + content = comment_pattern.sub("", content).strip() + + # Ensure no unrecognized instructions + leftovers = content + for pattern in (group_pattern, output_format_pattern): + leftovers = pattern.sub("", leftovers) + if leftovers.strip(): + raise ValueError("Invalid instruction found in the ld script:" + leftovers) + + # Extract files from GROUP instructions + files = [] + for match in group_pattern.findall(content): + files.extend([file.strip() for file in re.split(r"[,\s]+", match) if file.strip()]) + + return files + + +def load_archive(fn): + ar_header = b"!\012" + with open(fn, "rb") as f: + is_ar_file = f.read(len(ar_header)) == ar_header + if is_ar_file: + return [CachedArFile(fn)] + else: + return [CachedArFile(item) for item in expand_ld_script(fn)] diff --git a/tools/black_bindings.py b/tools/black_bindings.py deleted file mode 100755 index 1c6fa3cfe89..00000000000 --- a/tools/black_bindings.py +++ /dev/null @@ -1,129 +0,0 @@ -#!/usr/bin/python3 -import os -import re -import subprocess -import sys -from concurrent.futures import ThreadPoolExecutor -from dataclasses import dataclass -from enum import Enum, auto - -MARK_C_IN_PY = "##| " -MARK_PY_IN_C = "//| " - - -class Mode(Enum): - C = auto() - PY = auto() - - -@dataclass(frozen=True) -class LineWithMode: - data: str - mode: Mode - - -class OutputWriter: - def __init__(self): - self.content = [] - - def write(self, line): - self.content.append(line.rstrip()) - - def getcontent(self): - return "\n".join(self.content) - - -class PythonOutputWriter(OutputWriter): - def write(self, line): - if isinstance(line, str): - super().write(line) - elif line.mode == Mode.PY: - super().write(line.data) - else: # line mode is C - super().write(MARK_C_IN_PY + line.data) - - -class COutputWriter(OutputWriter): - def write(self, line): - if isinstance(line, str): - super().write(line) - elif line.mode == Mode.PY: - super().write(MARK_PY_IN_C + line.data) - else: # line mode is C - super().write(line.data) - - -def parse_line(line, defmode, mark, smark, markmode): - sline = line.strip() - if sline == smark or sline.startswith(mark): - return LineWithMode(sline[len(mark) :], markmode) - else: - return LineWithMode(line, defmode) - - -def parse_lines(lines, defmode, mark, markmode): - smark = mark.strip() - return [parse_line(line, defmode, mark, smark, markmode) for line in lines] - - -def swap_comment_markers(content, input_mode): - lines = content.rstrip().split("\n") - - if input_mode == Mode.C: - parsed = parse_lines(lines, Mode.C, MARK_PY_IN_C, Mode.PY) - writer = PythonOutputWriter() - else: - parsed = parse_lines(lines, Mode.PY, MARK_C_IN_PY, Mode.C) - writer = COutputWriter() - - for line in parsed: - writer.write(line) - - newcontent = writer.getcontent() + "\n" - - return newcontent - - -def process_one_file(fn): - with open(fn, "r", encoding="utf-8") as f: - c_content = f.read() - - if not "\n//| " in c_content: - return - - py_content = swap_comment_markers(c_content, Mode.C) - - try: - # Line length is 95 so that with "//| " the max is 99 - result = subprocess.run( - ["black", "--pyi", "-l95", "-q", "-"], - input=py_content, - check=True, - stdout=subprocess.PIPE, - encoding="utf-8", - ) - except subprocess.CalledProcessError as e: - print(f"{fn}:0: Failed to process file ") - raise - - new_py_content = result.stdout - new_c_content = swap_comment_markers(new_py_content, Mode.PY) - - if new_c_content != c_content: - with open(fn, "w", encoding="utf-8") as f: - f.write(new_c_content) - - -if __name__ == "__main__": - # Use a thread pool because most processing is inside black! - executor = ThreadPoolExecutor(max_workers=os.cpu_count()) - futures = [executor.submit(process_one_file, fn) for fn in sys.argv[1:]] - status = 0 - for f in futures: - try: - f.result() - except Exception as e: - print(e) - status = 1 - executor.shutdown() - raise SystemExit(status) diff --git a/tools/board_stubs/build_board_specific_stubs/board_stub_builder.py b/tools/board_stubs/build_board_specific_stubs/board_stub_builder.py index 63c4dd9c2f9..fb6219f373b 100644 --- a/tools/board_stubs/build_board_specific_stubs/board_stub_builder.py +++ b/tools/board_stubs/build_board_specific_stubs/board_stub_builder.py @@ -157,10 +157,10 @@ def create_board_stubs(board_id, records, mappings, board_filename): boards_file.write("#\n") boards_file.write("# SPDX-License-Identifier: MIT\n") boards_file.write('"""\n') - boards_file.write(f'Board stub for {mappings["board_name"]}\n') - boards_file.write(f' - port: {mappings["port"]}\n') + boards_file.write(f"Board stub for {mappings['board_name']}\n") + boards_file.write(f" - port: {mappings['port']}\n") boards_file.write(f" - board_id: {board_id}\n") - boards_file.write(f' - NVM size: {mappings["nvm_size"]}\n') + boards_file.write(f" - NVM size: {mappings['nvm_size']}\n") boards_file.write(f" - Included modules: {included_modules}\n") boards_file.write(f" - Frozen libraries: {frozen_libraries}\n") boards_file.write('"""\n\n') @@ -297,7 +297,7 @@ def build_stubs(circuitpython_dir, circuitpython_org_dir, export_dir, version="8 else: lookup = board - port_path = f'{circuitpython_dir}ports/{board_data["port"]}/' + port_path = f"{circuitpython_dir}ports/{board_data['port']}/" board_path = f"{port_path}boards/{lookup}/" pins_path = f"{board_path}pins.c" if not os.path.isfile(pins_path): diff --git a/tools/board_stubs/circuitpython_setboard/__init__.py b/tools/board_stubs/circuitpython_setboard/__init__.py index 3a73beb3119..69a405405b8 100644 --- a/tools/board_stubs/circuitpython_setboard/__init__.py +++ b/tools/board_stubs/circuitpython_setboard/__init__.py @@ -12,7 +12,12 @@ import shutil from collections import defaultdict from importlib import resources -from importlib.abc import Traversable + +try: + from importlib.resources.abc import Traversable +except ModuleNotFoundError: + # 3.10 and earlier. + from importlib.abc import Traversable def get_definitions_or_exit(board: str) -> Traversable: diff --git a/tools/board_summaries.py b/tools/board_summaries.py index 08ddc644af4..3ea87e68d55 100644 --- a/tools/board_summaries.py +++ b/tools/board_summaries.py @@ -61,7 +61,7 @@ def frozen_incidence_matrix_csvs(support_matrix, rows=1000, present="1", absent= all_frozen = set() for info in support_matrix.values(): frozen = info["frozen_libraries"] - frozen = [f[0] if type(f) == tuple else f for f in frozen] + frozen = [f[0] if isinstance(f, tuple) else f for f in frozen] all_frozen.update(frozen) all_frozen = sorted(all_frozen) csvs = [] @@ -75,7 +75,7 @@ def frozen_incidence_matrix_csvs(support_matrix, rows=1000, present="1", absent= chip_pin_set = set([chip_pin for _, chip_pin in info["pins"]]) n_chip_pins = len(chip_pin_set) - frozen = [f[0] if type(f) == tuple else f for f in frozen] + frozen = [f[0] if isinstance(f, tuple) else f for f in frozen] frozen_incidence = [present if f in frozen else absent for f in all_frozen] line = ( f"{board},{info.get('branded_name')},{info.get('mcu')}," @@ -150,8 +150,7 @@ def board_pins_matrix_csvs(support_matrix, rows=1000): for board, info in support_matrix.items(): if (row % rows) == 0: csv = [ - "board,branded_name,mcu,flash,port,n_board_pins," - "board_pins,n_chip_pins,chip_pins\n" + "board,branded_name,mcu,flash,port,n_board_pins,board_pins,n_chip_pins,chip_pins\n" ] board_pins = [board_pin for board_pin, _ in info["pins"]] chip_pins = [chip_pin for _, chip_pin in info["pins"]] @@ -186,12 +185,12 @@ def write_csvs(rows=1000, present="1", absent="0"): "frozen": frozen_incidence_matrix_csvs(s, rows=rows, present=present, absent=absent), "pins": board_pins_matrix_csvs(s, rows=rows), } - for key in csvs: - for i in range(len(csvs[key])): + for key, values in csvs: + for i in range(len(values)): filename = f"{key}_{i}.csv" print(f"writing {filename}") with open(filename, "w") as f: - f.writelines(csvs[key][i]) + f.writelines(values[i]) if __name__ == "__main__": diff --git a/tools/board_to_port.py b/tools/board_to_port.py new file mode 100644 index 00000000000..325105f9873 --- /dev/null +++ b/tools/board_to_port.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +# SPDX-FileCopyrightText: 2025 CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) +# +# SPDX-License-Identifier: MIT + +import sys +from pathlib import Path + +docs = Path(__file__).parent.parent / "docs" +sys.path.append(str(docs)) +from shared_bindings_matrix import get_board_mapping + +board = sys.argv[1] + +board_mapping = get_board_mapping() +if board in board_mapping: + board_info = board_mapping[board] + print(board_info["port"]) + sys.exit(0) + +raise ValueError(f"No port directory associated with the board tag given {board}.") diff --git a/tools/boardgen.py b/tools/boardgen.py index 41a8e9f2e59..3723e7ce31b 100644 --- a/tools/boardgen.py +++ b/tools/boardgen.py @@ -108,6 +108,10 @@ def add_board_pin_name(self, board_pin_name, hidden=False): ) ) + # Iterate over board pin names in consistent sorted order. + def board_pin_names(self): + return sorted(self._board_pin_names, key=lambda x: x[0]) + # Override this to handle an af specified in af.csv. def add_af(self, af_idx, af_name, af): raise NotImplementedError @@ -172,6 +176,8 @@ def __init__(self, pin_type, enable_af=False): self._pins = [] self._pin_type = pin_type self._enable_af = enable_af + self._pin_cpu_num_entries = 0 + self._pin_board_num_entries = 0 # Allows a port to define a known cpu pin (without relying on it being in the # csv file). @@ -293,11 +299,14 @@ def print_board_locals_dict(self, out_source): file=out_source, ) for pin in self.available_pins(): - for board_pin_name, board_hidden in pin._board_pin_names: + for board_pin_name, board_hidden in pin.board_pin_names(): if board_hidden: # Don't include hidden pins in Pins.board. continue + # Keep track of the total number of Pin.board entries. + self._pin_board_num_entries += 1 + # We don't use the enable macro for board pins, because they # shouldn't be referenced in pins.csv unless they're # available. @@ -322,6 +331,9 @@ def print_cpu_locals_dict(self, out_source): file=out_source, ) for pin in self.available_pins(exclude_hidden=True): + # Keep track of the total number of Pin.cpu entries. + self._pin_cpu_num_entries += 1 + m = pin.enable_macro() if m: print(" #if {}".format(m), file=out_source) @@ -351,6 +363,20 @@ def board_name_define_prefix(self): # Print the pin_CPUNAME and pin_BOARDNAME macros. def print_defines(self, out_header, cpu=True, board=True): + # Provide #defines for the number of cpu and board pins. + print( + "#define MICROPY_PY_MACHINE_PIN_CPU_NUM_ENTRIES ({})".format( + self._pin_cpu_num_entries + ), + file=out_header, + ) + print( + "#define MICROPY_PY_MACHINE_PIN_BOARD_NUM_ENTRIES ({})".format( + self._pin_board_num_entries + ), + file=out_header, + ) + # Provide #defines for each cpu pin. for pin in self.available_pins(): print(file=out_header) @@ -367,7 +393,7 @@ def print_defines(self, out_header, cpu=True, board=True): # #define pin_BOARDNAME (pin_CPUNAME) if board: - for board_pin_name, _board_hidden in pin._board_pin_names: + for board_pin_name, _board_hidden in pin.board_pin_names(): # Note: Hidden board pins are still available to C via the macro. # Note: The RHS isn't wrapped in (), which is necessary to make the # STATIC_AF_ macro work on STM32. diff --git a/tools/build_board_info.py b/tools/build_board_info.py index 44f2f4759d4..8b56539a233 100755 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -173,6 +173,14 @@ def create_pr(changes, updated, git_info, user): changes["new_release"], boards, languages ) + # Sync main so that the fork has the same commit sha1 + sync_main = {"branch": "main"} + response = github.post( + "/repos/{}/circuitpython-org/merge-upstream".format(user), json=sync_main + ) + if not response.ok: + raise SystemExit(f"unable to sync main: {response.text}") + create_branch = {"ref": "refs/heads/" + branch_name, "sha": commit_sha} response = github.post("/repos/{}/circuitpython-org/git/refs".format(user), json=create_branch) if not response.ok and response.json()["message"] != "Reference already exists": @@ -216,9 +224,6 @@ def print_active_user(): def generate_download_info(): - boards = {} - errors = [] - new_tag = os.environ["RELEASE_TAG"] changes = {"new_release": new_tag, "new_boards": [], "new_languages": []} @@ -251,29 +256,21 @@ def generate_download_info(): board_mapping = get_board_mapping() - for port in SUPPORTED_PORTS: - board_path = os.path.join("../ports", port, "boards") - for board_path in os.scandir(board_path): - if board_path.is_dir(): - board_files = os.listdir(board_path.path) - board_id = board_path.name - board_info = board_mapping[board_id] - for alias in [board_id] + board_info["aliases"]: - alias_info = board_mapping[alias] - if alias not in current_info: - changes["new_boards"].append(alias) - current_info[alias] = {"downloads": 0, "versions": []} - new_version = { - "stable": new_stable, - "version": new_tag, - "languages": languages, - # add modules, extensions, frozen_libraries explicitly - "modules": support_matrix[alias]["modules"], - "extensions": support_matrix[alias]["extensions"], - "frozen_libraries": support_matrix[alias]["frozen_libraries"], - } - current_info[alias]["downloads"] = alias_info["download_count"] - current_info[alias]["versions"].append(new_version) + for board_id, board_info in board_mapping.items(): + if board_id not in current_info: + changes["new_boards"].append(board_id) + current_info[board_id] = {"downloads": 0, "versions": []} + new_version = { + "stable": new_stable, + "version": new_tag, + "languages": languages, + # add modules, extensions, frozen_libraries explicitly + "modules": support_matrix[board_id]["modules"], + "extensions": support_matrix[board_id]["extensions"], + "frozen_libraries": support_matrix[board_id]["frozen_libraries"], + } + current_info[board_id]["downloads"] = board_info["download_count"] + current_info[board_id]["versions"].append(new_version) changes["new_languages"] = set(languages) - previous_languages diff --git a/tools/build_memory_info.py b/tools/build_memory_info.py index 09d2e72a641..ff5bbfad710 100755 --- a/tools/build_memory_info.py +++ b/tools/build_memory_info.py @@ -38,8 +38,7 @@ if line.startswith(("FLASH_FIRMWARE", "RAM")): regions[line.split()[0]] = line.split("=")[-1] -for region in regions: - space = regions[region] +for region, space in regions.items(): if "/*" in space: space = space.split("/*")[0] space = K_PATTERN.sub(K_REPLACE, space) diff --git a/tools/build_release_files.py b/tools/build_release_files.py index d8f5e3c3de7..25ae0facd1b 100755 --- a/tools/build_release_files.py +++ b/tools/build_release_files.py @@ -10,12 +10,16 @@ import subprocess import shutil import build_board_info as build_info +import pathlib import time import json +import tomllib sys.path.append("../docs") from shared_bindings_matrix import get_settings_from_makefile +TOP = pathlib.Path(__file__).resolve().parent.parent + for port in build_info.SUPPORTED_PORTS: result = subprocess.run("rm -rf ../ports/{port}/build*".format(port=port), shell=True) @@ -44,7 +48,25 @@ bin_directory = "../bin/{}/".format(board) os.makedirs(bin_directory, exist_ok=True) board_info = all_boards[board] - board_settings = get_settings_from_makefile("../ports/" + board_info["port"], board) + if board_info["port"] == "zephyr-cp": + # Split the vendor portion out of the board name. + next_underscore = board.find("_") + while next_underscore != -1: + vendor = board[:next_underscore] + target = board[next_underscore + 1 :] + cp_toml = TOP / f"ports/zephyr-cp/boards/{vendor}/{target}/circuitpython.toml" + if cp_toml.exists(): + break + next_underscore = board.find("_", next_underscore + 1) + board_settings = {"CLEAN_REBUILD_LANGUAGES": []} + with cp_toml.open("rb") as f: + board_settings.update(tomllib.load(f)) + else: + board_settings = get_settings_from_makefile("../ports/" + board_info["port"], board) + board_settings["CIRCUITPY_BUILD_EXTENSIONS"] = [ + extension.strip() + for extension in board_settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",") + ] languages.remove(LANGUAGE_FIRST) languages.insert(0, LANGUAGE_FIRST) @@ -54,27 +76,27 @@ os.makedirs(bin_directory, exist_ok=True) start_time = time.monotonic() - # Normally different language builds are all done based on the same set of compiled sources. - # But sometimes a particular language needs to be built from scratch, if, for instance, - # CFLAGS_INLINE_LIMIT is set for a particular language to make it fit. - clean_build_check_result = subprocess.run( - "make -C ../ports/{port} TRANSLATION={language} BOARD={board} check-release-needs-clean-build -j {cores} | fgrep 'RELEASE_NEEDS_CLEAN_BUILD = 1'".format( - port=board_info["port"], language=language, board=board, cores=cores - ), - shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - ) - clean_build = clean_build_check_result.returncode == 0 + if "CLEAN_REBUILD_LANGUAGES" in board_settings: + clean_build = language in board_settings["CLEAN_REBUILD_LANGUAGES"] + else: + # Normally different language builds are all done based on the same set of compiled sources. + # But sometimes a particular language needs to be built from scratch, if, for instance, + # CFLAGS_INLINE_LIMIT is set for a particular language to make it fit. + clean_build_check_result = subprocess.run( + "make -C ../ports/{port} TRANSLATION={language} BOARD={board} check-release-needs-clean-build -j {cores} | fgrep 'RELEASE_NEEDS_CLEAN_BUILD = 1'".format( + port=board_info["port"], language=language, board=board, cores=cores + ), + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + ) + clean_build = clean_build_check_result.returncode == 0 build_dir = "build-{board}".format(board=board) if clean_build: build_dir += "-{language}".format(language=language) - extensions = [ - extension.strip() - for extension in board_settings["CIRCUITPY_BUILD_EXTENSIONS"].split(",") - ] + extensions = board_settings["CIRCUITPY_BUILD_EXTENSIONS"] artifacts = [os.path.join(build_dir, "firmware." + extension) for extension in extensions] make_result = subprocess.run( diff --git a/tools/cc1 b/tools/cc1 index 827d5886a04..aa2534f01e7 100755 --- a/tools/cc1 +++ b/tools/cc1 @@ -23,8 +23,8 @@ import re # TODO somehow make them externally configurable # this is the path to the true C compiler -cc1_path = '/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/cc1' -#cc1_path = '/usr/lib/gcc/arm-none-eabi/5.3.0/cc1' +cc1_path = "/usr/lib/gcc/x86_64-unknown-linux-gnu/5.3.0/cc1" +# cc1_path = '/usr/lib/gcc/arm-none-eabi/5.3.0/cc1' # this must be the same as MICROPY_QSTR_BYTES_IN_HASH bytes_in_qstr_hash = 2 @@ -41,11 +41,16 @@ print_debug = False ################################################################################ # precompile regexs -re_preproc_line = re.compile(r'# [0-9]+ ') -re_map_entry = re.compile(r'\{.+?\(MP_QSTR_([A-Za-z0-9_]+)\).+\},') -re_mp_obj_dict_t = re.compile(r'(?P(static )?const mp_obj_dict_t (?P[a-z0-9_]+) = \{ \.base = \{&mp_type_dict\}, \.map = \{ \.all_keys_are_qstrs = 1, \.is_fixed = 1, \.is_ordered = )1(?P, \.used = .+ };)$') -re_mp_map_t = re.compile(r'(?P(static )?const mp_map_t (?P[a-z0-9_]+) = \{ \.all_keys_are_qstrs = 1, \.is_fixed = 1, \.is_ordered = )1(?P, \.used = .+ };)$') -re_mp_rom_map_elem_t = re.compile(r'static const mp_rom_map_elem_t [a-z_0-9]+\[\] = {$') +re_preproc_line = re.compile(r"# [0-9]+ ") +re_map_entry = re.compile(r"\{.+?\(MP_QSTR_([A-Za-z0-9_]+)\).+\},") +re_mp_obj_dict_t = re.compile( + r"(?P(static )?const mp_obj_dict_t (?P[a-z0-9_]+) = \{ \.base = \{&mp_type_dict\}, \.map = \{ \.all_keys_are_qstrs = 1, \.is_fixed = 1, \.is_ordered = )1(?P, \.used = .+ };)$" +) +re_mp_map_t = re.compile( + r"(?P(static )?const mp_map_t (?P[a-z0-9_]+) = \{ \.all_keys_are_qstrs = 1, \.is_fixed = 1, \.is_ordered = )1(?P, \.used = .+ };)$" +) +re_mp_rom_map_elem_t = re.compile(r"static const mp_rom_map_elem_t [a-z_0-9]+\[\] = {$") + # this must match the equivalent function in qstr.c def compute_hash(qstr): @@ -55,18 +60,19 @@ def compute_hash(qstr): # Make sure that valid hash is never zero, zero means "hash not computed" return (hash & ((1 << (8 * bytes_in_qstr_hash)) - 1)) or 1 + # this algo must match the equivalent in map.c def hash_insert(map, key, value): hash = compute_hash(key) pos = hash % len(map) start_pos = pos if print_debug: - print(' insert %s: start at %u/%u -- ' % (key, pos, len(map)), end='') + print(" insert %s: start at %u/%u -- " % (key, pos, len(map)), end="") while True: if map[pos] is None: # found empty slot, so key is not in table if print_debug: - print('put at %u' % pos) + print("put at %u" % pos) map[pos] = (key, value) return else: @@ -76,6 +82,7 @@ def hash_insert(map, key, value): pos = (pos + 1) % len(map) assert pos != start_pos + def hash_find(map, key): hash = compute_hash(key) pos = hash % len(map) @@ -92,6 +99,7 @@ def hash_find(map, key): if pos == start_pos: return attempts, None + def process_map_table(file, line, output): output.append(line) @@ -101,7 +109,7 @@ def process_map_table(file, line, output): while True: line = file.readline() if len(line) == 0: - print('unexpected end of input') + print("unexpected end of input") sys.exit(1) line = line.strip() if len(line) == 0: @@ -110,38 +118,38 @@ def process_map_table(file, line, output): if re_preproc_line.match(line): # preprocessor line number comment continue - if line == '};': + if line == "};": # end of table (we assume it appears on a single line) break table_contents.append(line) # make combined string of entries - entries_str = ''.join(table_contents) + entries_str = "".join(table_contents) # split into individual entries entries = [] while entries_str: # look for single entry, by matching nested braces match = None - if entries_str[0] == '{': + if entries_str[0] == "{": nested_braces = 0 for i in range(len(entries_str)): - if entries_str[i] == '{': + if entries_str[i] == "{": nested_braces += 1 - elif entries_str[i] == '}': + elif entries_str[i] == "}": nested_braces -= 1 if nested_braces == 0: - match = re_map_entry.match(entries_str[:i + 2]) + match = re_map_entry.match(entries_str[: i + 2]) break if not match: - print('unknown line in table:', entries_str) + print("unknown line in table:", entries_str) sys.exit(1) # extract single entry line = match.group(0) qstr = match.group(1) - entries_str = entries_str[len(line):].lstrip() + entries_str = entries_str[len(line) :].lstrip() # add the qstr and the whole line to list of all entries entries.append((qstr, line)) @@ -164,28 +172,28 @@ def process_map_table(file, line, output): attempts, line = hash_find(map, qstr) assert line is not None if print_debug: - print(' %s lookup took %u attempts' % (qstr, attempts)) + print(" %s lookup took %u attempts" % (qstr, attempts)) total_attempts += attempts - if len(entries): + if entries: stats = len(map), len(entries) / len(map), total_attempts / len(entries) else: stats = 0, 0, 0 if print_debug: - print(' table stats: size=%d, load=%.2f, avg_lookups=%.1f' % stats) + print(" table stats: size=%d, load=%.2f, avg_lookups=%.1f" % stats) # output hash table for row in map: if row is None: - output.append('{ 0, 0 },\n') + output.append("{ 0, 0 },\n") else: - output.append(row[1] + '\n') - output.append('};\n') + output.append(row[1] + "\n") + output.append("};\n") # skip to next non-blank line while True: line = file.readline() if len(line) == 0: - print('unexpected end of input') + print("unexpected end of input") sys.exit(1) line = line.strip() if len(line) == 0: @@ -197,19 +205,20 @@ def process_map_table(file, line, output): if match is None: match = re_mp_map_t.match(line) if match is None: - print('expecting mp_obj_dict_t or mp_map_t definition') + print("expecting mp_obj_dict_t or mp_map_t definition") print(output[0]) print(line) sys.exit(1) - line = match.group('head') + '0' + match.group('tail') + '\n' + line = match.group("head") + "0" + match.group("tail") + "\n" output.append(line) - return (match.group('id'),) + stats + return (match.group("id"),) + stats + def process_file(filename): output = [] file_changed = False - with open(filename, 'rt') as f: + with open(filename, "rt") as f: while True: line = f.readline() if not line: @@ -218,39 +227,41 @@ def process_file(filename): file_changed = True stats = process_map_table(f, line, output) if print_stats: - print(' [%s: size=%d, load=%.2f, avg_lookups=%.1f]' % stats) + print(" [%s: size=%d, load=%.2f, avg_lookups=%.1f]" % stats) else: output.append(line) if file_changed: if print_debug: - print(' modifying static maps in', output[0].strip()) - with open(filename, 'wt') as f: + print(" modifying static maps in", output[0].strip()) + with open(filename, "wt") as f: for line in output: f.write(line) + def main(): # run actual C compiler # need to quote args that have special characters in them def quote(s): - if s.find('<') != -1 or s.find('>') != -1: + if s.find("<") != -1 or s.find(">") != -1: return "'" + s + "'" else: return s - ret = os.system(cc1_path + ' ' + ' '.join(quote(s) for s in sys.argv[1:])) + + ret = os.system(cc1_path + " " + " ".join(quote(s) for s in sys.argv[1:])) if ret != 0: - ret = (ret & 0x7f) or 127 # make it in range 0-127, but non-zero + ret = (ret & 0x7F) or 127 # make it in range 0-127, but non-zero sys.exit(ret) - if sys.argv[1] == '-E': + if sys.argv[1] == "-E": # CPP has been run, now do our processing stage for i, arg in enumerate(sys.argv): - if arg == '-o': + if arg == "-o": return process_file(sys.argv[i + 1]) print('%s: could not find "-o" option' % (sys.argv[0],)) sys.exit(1) - elif sys.argv[1] == '-fpreprocessed': + elif sys.argv[1] == "-fpreprocessed": # compiler has been run, nothing more to do return else: @@ -258,5 +269,6 @@ def main(): print('%s: unknown first option "%s"' % (sys.argv[0], sys.argv[1])) sys.exit(1) -if __name__ == '__main__': + +if __name__ == "__main__": main() diff --git a/tools/chart_code_size.py b/tools/chart_code_size.py index cefe3b80948..f3d9c5bdc40 100644 --- a/tools/chart_code_size.py +++ b/tools/chart_code_size.py @@ -24,7 +24,7 @@ def parse_hex(h): @click.command() @click.argument("elf_filename") -def do_all_the_things(elf_filename): +def do_all_the_things(elf_filename): # noqa: C901 too complex symbol = None last_address = 0 all_symbols = {} @@ -124,7 +124,7 @@ def do_all_the_things(elf_filename): if not symbol_stack[-1]["subtype"]: symbol_stack[-1]["subtype"] = symbol elif symbol_stack[-1]["subtype"]["type"] == symbol["type"]: - second_subtype = True + pass else: raise RuntimeError() elif tag == "DW_AT_upper_bound": @@ -164,7 +164,6 @@ def do_all_the_things(elf_filename): # print(line) pass - MEMORY_NONE = 0 MEMORY_POINTER = 1 MEMORY_PY_OBJECT = 2 @@ -214,15 +213,14 @@ def get_pointer_map(t, depth=0): return {} # Do a second pass to dereference the types - for symbol_address in symbols_by_memory_address: - symbol = symbols_by_memory_address[symbol_address] + for symbol_address, symbol in symbols_by_memory_address.items(): if "type" in symbol: if symbol["debug_type"] == "DW_TAG_variable": symbol["pointer_map"] = get_pointer_map(symbols_by_debug_address[symbol["type"]]) type_string = [] t = symbol["type"] offset = [] - while t != None: + while t is not None: t_symbol = symbols_by_debug_address[t] t = t_symbol.get("type", None) if "name" in t_symbol: @@ -252,7 +250,6 @@ def get_pointer_map(t, depth=0): text_dump_lines = text_dump.stdout.decode("utf-8").split("\n") section = None symbol = None - symbol_type = None for line in text_dump_lines[4:]: if line.startswith("Disassembly of section"): section = line.split()[-1].strip(":") @@ -267,7 +264,6 @@ def get_pointer_map(t, depth=0): symbol_address = parse_hex(symbol_address) symbol_name = symbol_name.strip("<>:") if symbol_name in symbols_by_linkage_name: - linked_name = symbol_name symbol = symbols_by_linkage_name[symbol_name] if "name" in symbol: non_linkage = symbol["name"] @@ -303,10 +299,8 @@ def get_pointer_map(t, depth=0): if symbol["debug_type"] == "DW_TAG_subprogram": symbol["outgoing_jumps"] = set() symbol["incoming_jumps"] = set() - symbol_type = None elif symbol["debug_type"] == "DW_TAG_variable": symbol["outgoing_pointers"] = set() - symbol_type = symbols_by_debug_address[symbol["type"]] all_symbols[symbol_name] = symbol elif line[0] == " ": @@ -360,8 +354,7 @@ def get_pointer_map(t, depth=0): print("converting outgoing pointers to names") # Convert outgoing pointers to names from addresses - for symbol_name in all_symbols: - symbol = all_symbols[symbol_name] + for symbol_name, symbol in all_symbols.items(): if "outgoing_pointers" not in symbol: continue converted = set() @@ -378,8 +371,7 @@ def get_pointer_map(t, depth=0): print("linking back") # Link back - for symbol_name in all_symbols: - symbol = all_symbols[symbol_name] + for symbol_name, symbol in all_symbols.items(): if "outgoing_jumps" in symbol: for outgoing in symbol["outgoing_jumps"]: if outgoing not in all_symbols: diff --git a/tools/check_core1_flash_calls.py b/tools/check_core1_flash_calls.py new file mode 100644 index 00000000000..96e3ec8f5cf --- /dev/null +++ b/tools/check_core1_flash_calls.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python3 +# This file is part of the CircuitPython project: https://circuitpython.org +# +# SPDX-FileCopyrightText: Copyright (c) 2026 Mikey Sklar +# +# SPDX-License-Identifier: MIT +"""Post-link check: core1-executed code must not reach into flash. + +On raspberrypi-port boards with USB host, core1 runs the PIO-USB frame loop +and may only execute (or read) RAM-resident code: core1_main enables an MPU +region that makes flash inaccessible (see common-hal/usb_host/Port.c), and the +linker script deliberately RAM-places tuh_task_event_ready() and the PIO-USB +code. Nothing verified their *callees* stay in RAM, which is how issue #10243 +happened: an upstream TinyUSB change added a flash-resident call inside +RAM-placed tuh_task_event_ready(), core1 faulted at the first device attach, +and USB host went silent. + +This tool disassembles the linked ELF, walks the static call graph from the +core1 entry points, and fails if any reachable function lives in flash. Linker +veneers (long-call trampolines) are followed through their literal-pool +targets, so a flash callee hidden behind a RAM veneer is still detected. + +Usage: + check_core1_flash_calls.py firmware.elf [--root SYMBOL]... [--allow SYMBOL]... + +Default root: core1_main. --allow skips a symbol (and everything only +reachable through it); use it for calls that provably run before the MPU is +enabled. + +Limitation: indirect calls (blx rN / function pointers) cannot be traced +statically. They are counted and reported per function so the gaps are +visible. +""" + +import argparse +import re +import subprocess +import sys +from collections import deque + +OBJDUMP = "arm-none-eabi-objdump" + +FLASH_LO, FLASH_HI = 0x10000000, 0x20000000 + +# Symbols that are reachable from a core1 root but are known never to execute +# with flash locked out. Keep this list short and commented. +DEFAULT_ALLOW = [ + # usb_host core1_main calls this while configuring SysTick, before + # enabling the MPU. + "common_hal_mcu_processor_get_frequency", + # picodvi Framebuffer_RP2040 core1_main calls these during startup, + # before enabling the MPU. + "dvi_register_irqs_this_core", + "dvi_start", + # The flash-resident print half of the RAM-resident __wrap_panic + # (supervisor/port.c); only called after a get_core_num() == 0 check, + # and core0 never locks flash out. + "panic_core0", +] + + +def in_flash(addr): + return FLASH_LO <= addr < FLASH_HI + + +def main(): + parser = argparse.ArgumentParser( + description="Check that core1-reachable code is RAM-resident." + ) + parser.add_argument("elf", help="linked firmware ELF") + parser.add_argument( + "--root", + action="append", + default=[], + help="core1 entry point symbol (default: core1_main)", + ) + parser.add_argument( + "--allow", + action="append", + default=[], + help="symbol to skip (e.g. runs before the MPU is enabled)", + ) + args = parser.parse_args() + roots = list(dict.fromkeys(args.root or ["core1_main"])) + allow = set(DEFAULT_ALLOW) | set(args.allow) + + dis = subprocess.run( + [OBJDUMP, "-d", args.elf], capture_output=True, text=True, check=True + ).stdout + + func_re = re.compile(r"^([0-9a-f]+) <([^>]+)>:$") + # e.g. "10001234: f7ff fffe bl 10005678 " + branch_re = re.compile( + r"^\s*[0-9a-f]+:\s+[0-9a-f ]+\t(bl|blx|b|b\.n|b\.w|" + r"b(?:eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le)(?:\.n|\.w)?)" + r"\s+([0-9a-f]+)\s<([^>+]+)(\+0x[0-9a-f]+)?>" + ) + indirect_re = re.compile(r"^\s*[0-9a-f]+:\s+[0-9a-f ]+\tblx\s+(r\d+|ip|lr)\b") + # Veneer bodies jump through a literal pool word rather than a branch. + word_re = re.compile(r"^\s*[0-9a-f]+:\s+([0-9a-f]{8})\s+\.word\s") + + funcs = {} # name -> addr + edges = {} # name -> {target name} + veneer_words = {} # veneer name -> {literal addresses} + indirects = {} # name -> count of untraceable indirect calls + cur = None + for line in dis.splitlines(): + m = func_re.match(line) + if m: + cur = m.group(2) + funcs[cur] = int(m.group(1), 16) + edges.setdefault(cur, set()) + indirects.setdefault(cur, 0) + continue + if cur is None: + continue + if cur.endswith("_veneer"): + m = word_re.match(line) + if m: + veneer_words.setdefault(cur, set()).add(int(m.group(1), 16) & ~1) + continue + if indirect_re.match(line): + indirects[cur] += 1 + continue + m = branch_re.match(line) + if m: + target = m.group(3) + if target != cur: # ignore intra-function branches + edges[cur].add(target) + + # Resolve veneer literal addresses to function names. + addr_to_name = {} + for name, addr in funcs.items(): + addr_to_name.setdefault(addr, name) + for veneer, words in veneer_words.items(): + for w in words: + tgt = addr_to_name.get(w) + if tgt is not None: + edges.setdefault(veneer, set()).add(tgt) + + # A root may be absent from a given build (e.g. core1_scanline_callback + # only exists on picodvi builds); check whichever roots are present. + missing = [r for r in roots if r not in funcs] + if missing: + print(f"{args.elf}: root symbol(s) not present, skipping: {', '.join(missing)}") + roots = [r for r in roots if r in funcs] + if not roots: + return 0 + + # BFS from roots, remembering one call chain per function for reporting. + parent = {r: None for r in roots} + queue = deque(roots) + seen = set(roots) + violations = [] + indirect_notes = [] + while queue: + fn = queue.popleft() + if fn in allow: + continue + addr = funcs.get(fn) + if addr is not None and in_flash(addr): + violations.append(fn) + continue # don't walk further into flash + if indirects.get(fn): + indirect_notes.append((fn, indirects[fn])) + for tgt in sorted(edges.get(fn, ())): + if tgt not in seen and tgt in funcs: + seen.add(tgt) + parent[tgt] = fn + queue.append(tgt) + + def chain(fn): + parts = [] + while fn is not None: + parts.append(fn) + fn = parent[fn] + return " <- ".join(parts) + + print(f"{args.elf}: walked {len(seen)} functions from roots: {', '.join(roots)}") + if indirect_notes: + print( + f"note: {len(indirect_notes)} reachable function(s) make indirect " + f"calls that cannot be traced statically:" + ) + for fn, n in sorted(indirect_notes): + print(f" {fn} ({n} indirect call site(s))") + if violations: + print(f"\nFAIL: {len(violations)} flash-resident function(s) reachable from core1:") + for fn in sorted(violations): + print(f" {fn} @ {funcs[fn]:#010x}") + print(f" via: {chain(fn)}") + return 1 + print("PASS: no flash-resident code reachable from core1") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/tools/ci.sh b/tools/ci.sh index bac225caa4d..132fbd8f81c 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -9,18 +9,38 @@ fi # Ensure known OPEN_MAX (NO_FILES) limit. ulimit -n 1024 +# Fail on some things which are warnings otherwise +export MICROPY_MAINTAINER_BUILD=1 + ######################################################################################## # general helper functions function ci_gcc_arm_setup { + sudo apt-get update sudo apt-get install gcc-arm-none-eabi libnewlib-arm-none-eabi arm-none-eabi-gcc --version } +function ci_gcc_riscv_setup { + sudo apt-get update + sudo apt-get install gcc-riscv64-unknown-elf picolibc-riscv64-unknown-elf + riscv64-unknown-elf-gcc --version +} + +function ci_picotool_setup { + # Manually installing picotool ensures we use a release version, and speeds up the build. + git clone https://github.com/raspberrypi/pico-sdk.git + (cd pico-sdk && git submodule update --init lib/mbedtls) + git clone https://github.com/raspberrypi/picotool.git + (cd picotool && mkdir build && cd build && cmake -DPICO_SDK_PATH=../../pico-sdk .. && make && sudo make install) + picotool version +} + ######################################################################################## # c code formatting function ci_c_code_formatting_setup { + sudo apt-get update sudo apt-get install uncrustify uncrustify --version } @@ -34,12 +54,18 @@ function ci_c_code_formatting_run { # commit formatting function ci_commit_formatting_run { - git remote add upstream https://github.com/micropython/micropython.git - git fetch --depth=100 upstream master + # Default GitHub Actions checkout for a PR is a generated merge commit where + # the parents are the head of base branch (i.e. master) and the head of the + # PR branch, respectively. Use these parents to find the merge-base (i.e. + # where the PR branch head was branched) + # If the common ancestor commit hasn't been found, fetch more. - git merge-base upstream/master HEAD || git fetch --unshallow upstream master - # For a PR, upstream/master..HEAD ends with a merge commit into master, exclude that one. - tools/verifygitlog.py -v upstream/master..HEAD --no-merges + git merge-base HEAD^1 HEAD^2 || git fetch --unshallow origin + + MERGE_BASE=$(git merge-base HEAD^1 HEAD^2) + HEAD=$(git rev-parse HEAD^2) + echo "Checking commits between merge base ${MERGE_BASE} and PR head ${HEAD}..." + tools/verifygitlog.py -v "${MERGE_BASE}..${HEAD}" } ######################################################################################## @@ -50,49 +76,110 @@ function ci_code_size_setup { sudo apt-get install gcc-multilib gcc --version ci_gcc_arm_setup + ci_gcc_riscv_setup + ci_picotool_setup +} + +function _ci_is_git_merge { + [[ $(git log -1 --format=%P "$1" | wc -w) > 1 ]] } function ci_code_size_build { # check the following ports for the change in their code size - PORTS_TO_CHECK=bmusxpd - SUBMODULES="lib/asf4 lib/berkeley-db-1.xx lib/mbedtls lib/micropython-lib lib/nxp_driver lib/pico-sdk lib/stm32lib lib/tinyusb" - - # starts off at either the ref/pull/N/merge FETCH_HEAD, or the current branch HEAD - git checkout -b pull_request # save the current location - git remote add upstream https://github.com/micropython/micropython.git - git fetch --depth=100 upstream master - # If the common ancestor commit hasn't been found, fetch more. - git merge-base upstream/master HEAD || git fetch --unshallow upstream master - # build reference, save to size0 - # ignore any errors with this build, in case master is failing - git checkout `git merge-base --fork-point upstream/master pull_request` - git submodule update --init $SUBMODULES - git show -s - tools/metrics.py clean $PORTS_TO_CHECK - tools/metrics.py build $PORTS_TO_CHECK | tee ~/size0 || true - # build PR/branch, save to size1 - git checkout pull_request - git submodule update --init $SUBMODULES - git log upstream/master..HEAD - tools/metrics.py clean $PORTS_TO_CHECK - tools/metrics.py build $PORTS_TO_CHECK | tee ~/size1 + # Override the list by setting PORTS_TO_CHECK in the environment before invoking ci. + : ${PORTS_TO_CHECK:=bmusxpdv} + + SUBMODULES="lib/asf4 lib/berkeley-db-1.xx lib/btstack lib/cyw43-driver lib/lwip lib/mbedtls lib/micropython-lib lib/nxp_driver lib/pico-sdk lib/stm32lib lib/tinyusb" + + # Default GitHub pull request sets HEAD to a generated merge commit + # between PR branch (HEAD^2) and base branch (i.e. master) (HEAD^1). + # + # We want to compare this generated commit with the base branch, to see what + # the code size impact would be if we merged this PR. During CI we are at a merge commit, + # so this tests the merged PR against its merge base. + # Override the refs by setting REFERENCE and/or COMPARISON in the environment before invoking ci. + : ${COMPARISON:=$(git rev-parse --short HEAD)} + : ${REFERENCE:=$(git rev-parse --short ${COMPARISON}^1)} + + echo "Comparing sizes of reference ${REFERENCE} to ${COMPARISON}..." + git log --oneline $REFERENCE..$COMPARISON + + OLD_BRANCH="$(git rev-parse --abbrev-ref HEAD)" + + ( # Execute in a subshell so the trap & code_size_build_step doesn't leak + function code_size_build_step { + if [ ! -z "$OLD_BRANCH" ]; then + trap 'git checkout "$OLD_BRANCH"' RETURN EXIT ERR + fi + + COMMIT=$1 + OUTFILE=$2 + IGNORE_ERRORS=$3 + + git checkout --detach $COMMIT + git submodule update --init $SUBMODULES + git show -s + tools/metrics.py clean "$PORTS_TO_CHECK" + # Allow errors from tools/metrics.py to propagate out of the pipe below. + set -o pipefail + tools/metrics.py build "$PORTS_TO_CHECK" | tee -a $OUTFILE || $IGNORE_ERRORS + return $? + } + + # build reference, save to size0 + # ignore any errors with this build, in case master is failing + echo "BUILDING $(git log --format='%s [%h]' -1 ${REFERENCE})" > ~/size0 + code_size_build_step $REFERENCE ~/size0 true + # build PR/branch, save to size1 + if _ci_is_git_merge "$COMPARISON"; then + echo "BUILDING $(git log --oneline -1 --format='%s [merge of %h]' ${COMPARISON}^2)" + else + echo "BUILDING $(git log --oneline -1 --formta='%s [%h]' ${COMPARISON})" + fi > ~/size1 + code_size_build_step $COMPARISON ~/size1 false + ) +} + +function ci_code_size_report { + # Allow errors from tools/metrics.py to propagate out of the pipe above. + (set -o pipefail; tools/metrics.py diff ~/size0 ~/size1 | tee diff) } ######################################################################################## # .mpy file format function ci_mpy_format_setup { + sudo apt-get update sudo pip3 install pyelftools + python3 --version } function ci_mpy_format_test { # Test mpy-tool.py dump feature on bytecode - python2 ./tools/mpy-tool.py -xd tests/frozen/frozentest.mpy python3 ./tools/mpy-tool.py -xd tests/frozen/frozentest.mpy + # Build MicroPython + ci_unix_standard_build + micropython=./ports/unix/build-standard/micropython + $micropython -m mip install --target . argparse __future__ + export MICROPYPATH=. + + # Test mpy-tool.py running under MicroPython + $micropython ./tools/mpy-tool.py -x -d tests/frozen/frozentest.mpy + # Test mpy-tool.py dump feature on native code make -C examples/natmod/features1 ./tools/mpy-tool.py -xd examples/natmod/features1/features1.mpy + $micropython ./tools/mpy-tool.py -x -d examples/natmod/features1/features1.mpy +} + +function ci_mpy_cross_debug_emitter { + make ${MAKEOPTS} -C mpy-cross + mpy_cross=./mpy-cross/build/mpy-cross + + # Make sure the debug emitter does not crash or fail for simple files + $mpy_cross -X emit=native -march=debug ./tests/basics/0prelim.py | \ + grep -E "ENTRY|EXIT" | wc -l | grep "^2$" } ######################################################################################## @@ -110,18 +197,26 @@ function ci_cc3200_build { ######################################################################################## # ports/esp32 -# GitHub tag of ESP-IDF to use for CI (note: must be a tag or a branch) -IDF_VER=v5.0.4 +# GitHub tag of ESP-IDF to use for CI, extracted from the esp32 dependency lockfile +# This should end up as a tag name like vX.Y.Z +# (note: This hacky parsing can be replaced with 'yq' once Ubuntu >=24.04 is in use) +IDF_VER=v$(grep -A10 "idf:" ports/esp32/lockfiles/dependencies.lock.esp32 | grep "version:" | head -n1 | sed -E 's/ +version: //') +PYTHON=$(command -v python3 2> /dev/null) +PYTHON_VER=$(${PYTHON:-python} --version | cut -d' ' -f2) export IDF_CCACHE_ENABLE=1 function ci_esp32_idf_setup { - pip3 install pyelftools + echo "Using ESP-IDF version $IDF_VER" git clone --depth 1 --branch $IDF_VER https://github.com/espressif/esp-idf.git # doing a treeless clone isn't quite as good as --shallow-submodules, but it # is smaller than full clones and works when the submodule commit isn't a head. git -C esp-idf submodule update --init --recursive --filter=tree:0 ./esp-idf/install.sh + # Install additional packages for mpy_ld into the IDF env + source esp-idf/export.sh + pip3 install pyelftools + pip3 install ar } function ci_esp32_build_common { @@ -151,13 +246,28 @@ function ci_esp32_build_s3_c3 { make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_C3 } +function ci_esp32_build_c2_c5_c6 { + ci_esp32_build_common + + make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_C2 + make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_C5 + make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_C6 +} + +function ci_esp32_build_p4 { + ci_esp32_build_common + + make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_P4 + make ${MAKEOPTS} -C ports/esp32 BOARD=ESP32_GENERIC_P4 BOARD_VARIANT=C6_WIFI +} + ######################################################################################## # ports/esp8266 function ci_esp8266_setup { - sudo pip install pyserial esptool==3.3.1 - wget https://github.com/jepler/esp-open-sdk/releases/download/2018-06-10/xtensa-lx106-elf-standalone.tar.gz - zcat xtensa-lx106-elf-standalone.tar.gz | tar x + sudo pip3 install pyserial esptool==3.3.1 pyelftools ar + wget https://micropython.org/resources/xtensa-lx106-elf-standalone.tar.gz + (set -o pipefail; zcat xtensa-lx106-elf-standalone.tar.gz | tar x) # Remove this esptool.py so pip version is used instead rm xtensa-lx106-elf/bin/esptool.py } @@ -172,6 +282,9 @@ function ci_esp8266_build { make ${MAKEOPTS} -C ports/esp8266 BOARD=ESP8266_GENERIC make ${MAKEOPTS} -C ports/esp8266 BOARD=ESP8266_GENERIC BOARD_VARIANT=FLASH_512K make ${MAKEOPTS} -C ports/esp8266 BOARD=ESP8266_GENERIC BOARD_VARIANT=FLASH_1M + + # Test building native .mpy with xtensa architecture. + ci_native_mpy_modules_build xtensa } ######################################################################################## @@ -206,6 +319,8 @@ function ci_mimxrt_build { make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1020_EVK make ${MAKEOPTS} -C ports/mimxrt BOARD=TEENSY40 submodules make ${MAKEOPTS} -C ports/mimxrt BOARD=TEENSY40 + make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1060_EVK submodules + make ${MAKEOPTS} -C ports/mimxrt BOARD=MIMXRT1060_EVK CFLAGS_EXTRA=-DMICROPY_HW_USB_MSC=1 } ######################################################################################## @@ -239,24 +354,88 @@ function ci_powerpc_build { } ######################################################################################## -# ports/qemu-arm +# ports/qemu -function ci_qemu_arm_setup { +function ci_qemu_setup_arm { ci_gcc_arm_setup sudo apt-get update sudo apt-get install qemu-system + sudo pip3 install pyelftools + sudo pip3 install ar qemu-system-arm --version } -function ci_qemu_arm_build { +function ci_qemu_setup_rv32 { + ci_gcc_riscv_setup + sudo apt-get update + sudo apt-get install qemu-system + sudo pip3 install pyelftools + sudo pip3 install ar + qemu-system-riscv32 --version +} + +function ci_qemu_setup_rv64 { + ci_gcc_riscv_setup + sudo apt-get update + sudo apt-get install qemu-system + qemu-system-riscv64 --version +} + +function ci_qemu_build_arm_prepare { make ${MAKEOPTS} -C mpy-cross - make ${MAKEOPTS} -C ports/qemu-arm submodules - make ${MAKEOPTS} -C ports/qemu-arm CFLAGS_EXTRA=-DMP_ENDIANNESS_BIG=1 - make ${MAKEOPTS} -C ports/qemu-arm clean - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test submodules - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test test - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test clean - make ${MAKEOPTS} -C ports/qemu-arm -f Makefile.test BOARD=sabrelite test + make ${MAKEOPTS} -C ports/qemu submodules +} + +function ci_qemu_build_arm_bigendian { + ci_qemu_build_arm_prepare + make ${MAKEOPTS} -C ports/qemu CFLAGS_EXTRA=-DMP_ENDIANNESS_BIG=1 +} + +function ci_qemu_build_arm_sabrelite { + ci_qemu_build_arm_prepare + make ${MAKEOPTS} -C ports/qemu BOARD=SABRELITE test_full +} + +function ci_qemu_build_arm_thumb_softfp { + ci_qemu_build_arm_prepare + make BOARD=MPS2_AN385 ${MAKEOPTS} -C ports/qemu test_full + + # Test building native .mpy with ARM-M softfp architectures. + ci_native_mpy_modules_build armv6m + ci_native_mpy_modules_build armv7m + + # Test running native .mpy with all ARM-M architectures. + make BOARD=MPS2_AN385 ${MAKEOPTS} -C ports/qemu test_natmod RUN_TESTS_EXTRA="--arch armv6m" + make BOARD=MPS2_AN385 ${MAKEOPTS} -C ports/qemu test_natmod RUN_TESTS_EXTRA="--arch armv7m" +} + +function ci_qemu_build_arm_thumb_hardfp { + ci_qemu_build_arm_prepare + make BOARD=MPS2_AN500 ${MAKEOPTS} -C ports/qemu test_full + + # Test building native .mpy with all ARM-M hardfp architectures. + ci_native_mpy_modules_build armv7emsp + ci_native_mpy_modules_build armv7emdp + + # Test running native .mpy with all ARM-M hardfp architectures. + make BOARD=MPS2_AN500 ${MAKEOPTS} -C ports/qemu test_natmod RUN_TESTS_EXTRA="--arch armv7emsp" + make BOARD=MPS2_AN500 ${MAKEOPTS} -C ports/qemu test_natmod RUN_TESTS_EXTRA="--arch armv7emdp" +} + +function ci_qemu_build_rv32 { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/qemu BOARD=VIRT_RV32 submodules + make ${MAKEOPTS} -C ports/qemu BOARD=VIRT_RV32 test_full + + # Test building and running native .mpy with rv32imc architecture. + ci_native_mpy_modules_build rv32imc + make ${MAKEOPTS} -C ports/qemu BOARD=VIRT_RV32 test_natmod +} + +function ci_qemu_build_rv64 { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/qemu BOARD=VIRT_RV64 submodules + make ${MAKEOPTS} -C ports/qemu BOARD=VIRT_RV64 test } ######################################################################################## @@ -284,6 +463,7 @@ function ci_renesas_ra_board_build { function ci_rp2_setup { ci_gcc_arm_setup + ci_picotool_setup } function ci_rp2_build { @@ -292,8 +472,11 @@ function ci_rp2_build { make ${MAKEOPTS} -C ports/rp2 make ${MAKEOPTS} -C ports/rp2 BOARD=RPI_PICO_W submodules make ${MAKEOPTS} -C ports/rp2 BOARD=RPI_PICO_W USER_C_MODULES=../../examples/usercmodule/micropython.cmake + make ${MAKEOPTS} -C ports/rp2 BOARD=RPI_PICO2 submodules + make ${MAKEOPTS} -C ports/rp2 BOARD=RPI_PICO2 make ${MAKEOPTS} -C ports/rp2 BOARD=W5100S_EVB_PICO submodules - make ${MAKEOPTS} -C ports/rp2 BOARD=W5100S_EVB_PICO + # This build doubles as a build test for disabling threads in the config + make ${MAKEOPTS} -C ports/rp2 BOARD=W5100S_EVB_PICO CFLAGS_EXTRA=-DMICROPY_PY_THREAD=0 # Test building ninaw10 driver and NIC interface. make ${MAKEOPTS} -C ports/rp2 BOARD=ARDUINO_NANO_RP2040_CONNECT submodules @@ -318,12 +501,22 @@ function ci_samd_build { # ports/stm32 function ci_stm32_setup { - ci_gcc_arm_setup + # Use a recent version of the ARM toolchain, to work with Cortex-M55. + wget https://developer.arm.com/-/media/Files/downloads/gnu/14.3.rel1/binrel/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi.tar.xz + xzcat arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi.tar.xz | tar x + pip3 install pyelftools + pip3 install ar pip3 install pyhy } +function ci_stm32_path { + echo $(pwd)/arm-gnu-toolchain-14.3.rel1-x86_64-arm-none-eabi/bin +} + function ci_stm32_pyb_build { + # This function builds the following MCU families: F4, F7. + make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/stm32 MICROPY_PY_NETWORK_WIZNET5K=5200 submodules make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2 submodules @@ -331,24 +524,22 @@ function ci_stm32_pyb_build { git submodule update --init lib/mynewt-nimble make ${MAKEOPTS} -C ports/stm32 BOARD=PYBV11 MICROPY_PY_NETWORK_WIZNET5K=5200 USER_C_MODULES=../../examples/usercmodule make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF2 - make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1 + make ${MAKEOPTS} -C ports/stm32 BOARD=PYBD_SF6 COPT=-O2 NANBOX=1 MICROPY_BLUETOOTH_NIMBLE=0 MICROPY_BLUETOOTH_BTSTACK=1 make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBV10 CFLAGS_EXTRA='-DMBOOT_FSLOAD=1 -DMBOOT_VFS_LFS2=1' make ${MAKEOPTS} -C ports/stm32/mboot BOARD=PYBD_SF6 make ${MAKEOPTS} -C ports/stm32/mboot BOARD=STM32F769DISC CFLAGS_EXTRA='-DMBOOT_ADDRESS_SPACE_64BIT=1 -DMBOOT_SDCARD_ADDR=0x100000000ULL -DMBOOT_SDCARD_BYTE_SIZE=0x400000000ULL -DMBOOT_FSLOAD=1 -DMBOOT_VFS_FAT=1' - - # Test building native .mpy with armv7emsp architecture. - git submodule update --init lib/berkeley-db-1.xx - ci_native_mpy_modules_build armv7emsp } function ci_stm32_nucleo_build { + # This function builds the following MCU families: F0, H5, H7, L0, L4, WB. + make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI submodules git submodule update --init lib/mynewt-nimble # Test building various MCU families, some with additional options. make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_F091RC - make ${MAKEOPTS} -C ports/stm32 BOARD=STM32H573I_DK + make ${MAKEOPTS} -C ports/stm32 BOARD=STM32H573I_DK CFLAGS_EXTRA='-DMICROPY_HW_TINYUSB_STACK=1' make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_H743ZI COPT=-O2 CFLAGS_EXTRA='-DMICROPY_PY_THREAD=1' make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L073RZ make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L476RG DEBUG=1 @@ -368,21 +559,22 @@ function ci_stm32_nucleo_build { } function ci_stm32_misc_build { + # This function builds the following MCU families: G0, G4, H7, L1, N6, U5, WL. + make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/stm32 BOARD=ARDUINO_GIGA submodules make ${MAKEOPTS} -C ports/stm32 BOARD=ARDUINO_GIGA + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_G0B1RE + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_G474RE + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_L152RE + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_N657X0 + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_U5A5ZJ_Q + make ${MAKEOPTS} -C ports/stm32 BOARD=NUCLEO_WL55 } ######################################################################################## # ports/unix -CI_UNIX_OPTS_SYS_SETTRACE=( - MICROPY_PY_BTREE=0 - MICROPY_PY_FFI=0 - MICROPY_PY_SSL=0 - CFLAGS_EXTRA="-DMICROPY_PY_SYS_SETTRACE=1" -) - CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS=( MICROPY_PY_BTREE=0 MICROPY_PY_FFI=0 @@ -394,7 +586,6 @@ CI_UNIX_OPTS_QEMU_MIPS=( CROSS_COMPILE=mips-linux-gnu- VARIANT=coverage MICROPY_STANDALONE=1 - LDFLAGS_EXTRA="-static" ) CI_UNIX_OPTS_QEMU_ARM=( @@ -403,6 +594,32 @@ CI_UNIX_OPTS_QEMU_ARM=( MICROPY_STANDALONE=1 ) +CI_UNIX_OPTS_QEMU_RISCV64=( + CROSS_COMPILE=riscv64-linux-gnu- + VARIANT=coverage + MICROPY_STANDALONE=1 +) + +CI_UNIX_OPTS_SANITIZE_ADDRESS=( + # Macro MP_ASAN allows detecting ASan on gcc<=13 + CFLAGS_EXTRA="-fsanitize=address --param asan-use-after-return=0 -DMP_ASAN=1" + LDFLAGS_EXTRA="-fsanitize=address --param asan-use-after-return=0" +) + +CI_UNIX_OPTS_SANITIZE_UNDEFINED=( + # Macro MP_UBSAN allows detecting UBSan on gcc<=13 + CFLAGS_EXTRA="-fsanitize=undefined -fno-sanitize=nonnull-attribute -DMP_UBSAN=1" + LDFLAGS_EXTRA="-fsanitize=undefined -fno-sanitize=nonnull-attribute" +) + +CI_UNIX_OPTS_REPR_B=( + VARIANT=standard + CFLAGS_EXTRA="-DMICROPY_OBJ_REPR=MICROPY_OBJ_REPR_B -DMICROPY_PY_UCTYPES=0 -Dmp_int_t=int32_t -Dmp_uint_t=uint32_t" + MICROPY_FORCE_32BIT=1 + RUN_TESTS_MPY_CROSS_FLAGS="--mpy-cross-flags=\"-march=x86 -msmall-int-bits=30\"" + +) + function ci_unix_build_helper { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix "$@" submodules @@ -418,13 +635,26 @@ function ci_unix_run_tests_helper { make -C ports/unix "$@" test } +function ci_unix_run_tests_full_extra { + micropython=$1 + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=$micropython ./run-multitests.py multi_net/*.py) + (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=$micropython ./run-perfbench.py --average 1 1000 1000) +} + +function ci_unix_run_tests_full_no_native_helper { + variant=$1 + shift + micropython=../ports/unix/build-$variant/micropython + make -C ports/unix VARIANT=$variant "$@" test_full_no_native + ci_unix_run_tests_full_extra $micropython +} + function ci_unix_run_tests_full_helper { variant=$1 shift micropython=../ports/unix/build-$variant/micropython make -C ports/unix VARIANT=$variant "$@" test_full - (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=$micropython ./run-multitests.py multi_net/*.py) - (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=$micropython ./run-perfbench.py 1000 1000) + ci_unix_run_tests_full_extra $micropython } function ci_native_mpy_modules_build { @@ -433,16 +663,19 @@ function ci_native_mpy_modules_build { else arch=$1 fi - make -C examples/natmod/features1 ARCH=$arch - make -C examples/natmod/features2 ARCH=$arch - make -C examples/natmod/features3 ARCH=$arch - make -C examples/natmod/features4 ARCH=$arch - make -C examples/natmod/btree ARCH=$arch - make -C examples/natmod/deflate ARCH=$arch - make -C examples/natmod/framebuf ARCH=$arch - make -C examples/natmod/heapq ARCH=$arch - make -C examples/natmod/random ARCH=$arch - make -C examples/natmod/re ARCH=$arch + for natmod in btree deflate features1 features3 features4 framebuf heapq random re + do + make -C examples/natmod/$natmod ARCH=$arch clean + make -C examples/natmod/$natmod ARCH=$arch + done + + # features2 requires soft-float on rv32imc and xtensa. + make -C examples/natmod/features2 ARCH=$arch clean + if [ $arch = "rv32imc" ] || [ $arch = "xtensa" ]; then + make -C examples/natmod/features2 ARCH=$arch MICROPY_FLOAT_IMPL=float + else + make -C examples/natmod/features2 ARCH=$arch + fi } function ci_native_mpy_modules_32bit_build { @@ -454,7 +687,7 @@ function ci_unix_minimal_build { } function ci_unix_minimal_run_tests { - (cd tests && MICROPY_CPYTHON3=python3 MICROPY_MICROPYTHON=../ports/unix/build-minimal/micropython ./run-tests.py -e exception_chain -e self_type_check -e subclass_native_init -d basics) + make -C ports/unix VARIANT=minimal test } function ci_unix_standard_build { @@ -476,8 +709,9 @@ function ci_unix_standard_v2_run_tests { } function ci_unix_coverage_setup { - sudo pip3 install setuptools - sudo pip3 install pyelftools + pip3 install setuptools + pip3 install pyelftools + pip3 install ar gcc --version python3 --version } @@ -488,7 +722,7 @@ function ci_unix_coverage_build { } function ci_unix_coverage_run_tests { - ci_unix_run_tests_full_helper coverage + MICROPY_TEST_TIMEOUT=60 ci_unix_run_tests_full_helper coverage } function ci_unix_coverage_run_mpy_merge_tests { @@ -526,6 +760,7 @@ function ci_unix_32bit_setup { sudo apt-get install gcc-multilib g++-multilib libffi-dev:i386 sudo pip3 install setuptools sudo pip3 install pyelftools + sudo pip3 install ar gcc --version python3 --version } @@ -544,13 +779,20 @@ function ci_unix_coverage_32bit_run_native_mpy_tests { } function ci_unix_nanbox_build { - # Use Python 2 to check that it can run the build scripts - ci_unix_build_helper PYTHON=python2 VARIANT=nanbox CFLAGS_EXTRA="-DMICROPY_PY_MATH_CONSTANTS=1" + ci_unix_build_helper VARIANT=nanbox CFLAGS_EXTRA="-DMICROPY_PY_MATH_CONSTANTS=1" ci_unix_build_ffi_lib_helper gcc -m32 } function ci_unix_nanbox_run_tests { - ci_unix_run_tests_full_helper nanbox PYTHON=python2 + ci_unix_run_tests_full_no_native_helper nanbox +} + +function ci_unix_longlong_build { + ci_unix_build_helper VARIANT=longlong "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" +} + +function ci_unix_longlong_run_tests { + ci_unix_run_tests_full_helper longlong } function ci_unix_float_build { @@ -563,7 +805,17 @@ function ci_unix_float_run_tests { ci_unix_run_tests_helper CFLAGS_EXTRA="-DMICROPY_FLOAT_IMPL=MICROPY_FLOAT_IMPL_FLOAT" } +function ci_unix_gil_enabled_build { + ci_unix_build_helper VARIANT=standard MICROPY_PY_THREAD_GIL=1 + ci_unix_build_ffi_lib_helper gcc +} + +function ci_unix_gil_enabled_run_tests { + ci_unix_run_tests_full_helper standard MICROPY_PY_THREAD_GIL=1 +} + function ci_unix_clang_setup { + sudo apt-get update sudo apt-get install clang clang --version } @@ -575,7 +827,8 @@ function ci_unix_stackless_clang_build { } function ci_unix_stackless_clang_run_tests { - ci_unix_run_tests_helper CC=clang + # Timeout needs to be increased for thread/stress_aes.py test. + MICROPY_TEST_TIMEOUT=90 ci_unix_run_tests_helper CC=clang } function ci_unix_float_clang_build { @@ -588,30 +841,39 @@ function ci_unix_float_clang_run_tests { ci_unix_run_tests_helper CC=clang } -function ci_unix_settrace_build { +function ci_unix_settrace_stackless_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix submodules - make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SYS_SETTRACE[@]}" + make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS[@]}" } -function ci_unix_settrace_run_tests { - ci_unix_run_tests_full_helper standard "${CI_UNIX_OPTS_SYS_SETTRACE[@]}" +function ci_unix_settrace_stackless_run_tests { + ci_unix_run_tests_full_helper standard "${CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS[@]}" } -function ci_unix_settrace_stackless_build { +function ci_unix_sanitize_undefined_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix submodules - make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS[@]}" + make ${MAKEOPTS} -C ports/unix VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" + ci_unix_build_ffi_lib_helper gcc } -function ci_unix_settrace_stackless_run_tests { - ci_unix_run_tests_full_helper standard "${CI_UNIX_OPTS_SYS_SETTRACE_STACKLESS[@]}" +function ci_unix_sanitize_undefined_run_tests { + MICROPY_TEST_TIMEOUT=60 ci_unix_run_tests_full_helper coverage VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" } -function ci_unix_macos_build { - # Install pkg-config to configure libffi paths. - brew install pkg-config +function ci_unix_sanitize_address_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/unix submodules + make ${MAKEOPTS} -C ports/unix VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_ADDRESS[@]}" + ci_unix_build_ffi_lib_helper gcc +} + +function ci_unix_sanitize_address_run_tests { + MICROPY_TEST_TIMEOUT=60 ci_unix_run_tests_full_helper coverage VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_ADDRESS[@]}" +} +function ci_unix_macos_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix submodules #make ${MAKEOPTS} -C ports/unix deplibs @@ -623,29 +885,34 @@ function ci_unix_macos_build { function ci_unix_macos_run_tests { # Issues with macOS tests: - # - import_pkg7 has a problem with relative imports - # - random_basic has a problem with getrandbits(0) - (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-standard/micropython ./run-tests.py --exclude 'import_pkg7.py' --exclude 'random_basic.py') + # - float_parse and float_parse_doubleprec parse/print floats out by a few mantissa bits + # - ffi_callback crashes for an unknown reason + # - thread/stress_heap.py is flaky + # - thread/thread_gc1.py is flaky + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-standard/micropython ./run-tests.py --exclude '(float_parse|float_parse_doubleprec|ffi_callback|thread/stress_heap|thread/thread_gc1).py') } function ci_unix_qemu_mips_setup { sudo apt-get update - sudo apt-get install gcc-mips-linux-gnu g++-mips-linux-gnu + sudo apt-get install gcc-mips-linux-gnu g++-mips-linux-gnu libc6-mips-cross sudo apt-get install qemu-user qemu-mips --version + sudo mkdir /etc/qemu-binfmt + sudo ln -s /usr/mips-linux-gnu/ /etc/qemu-binfmt/mips } function ci_unix_qemu_mips_build { - # qemu-mips on GitHub Actions will seg-fault if not linked statically ci_unix_build_helper "${CI_UNIX_OPTS_QEMU_MIPS[@]}" + ci_unix_build_ffi_lib_helper mips-linux-gnu-gcc } function ci_unix_qemu_mips_run_tests { # Issues with MIPS tests: - # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) - # - ffi tests do not work + # - thread/stress_aes.py takes around 50 seconds + # - thread/stress_recurse.py is flaky + # - thread/thread_gc1.py is flaky file ./ports/unix/build-coverage/micropython - (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.*\.py' --exclude 'ffi_(callback|float|float2).py') + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython MICROPY_TEST_TIMEOUT=90 ./run-tests.py --exclude 'thread/stress_recurse.py|thread/thread_gc1.py') } function ci_unix_qemu_arm_setup { @@ -653,6 +920,8 @@ function ci_unix_qemu_arm_setup { sudo apt-get install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi sudo apt-get install qemu-user qemu-arm --version + sudo mkdir /etc/qemu-binfmt + sudo ln -s /usr/arm-linux-gnueabi/ /etc/qemu-binfmt/arm } function ci_unix_qemu_arm_build { @@ -663,15 +932,52 @@ function ci_unix_qemu_arm_build { function ci_unix_qemu_arm_run_tests { # Issues with ARM tests: # - (i)listdir does not work, it always returns the empty list (it's an issue with the underlying C call) - export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi + # - thread/stress_aes.py takes around 70 seconds + # - thread/stress_recurse.py is flaky + # - thread/thread_gc1.py is flaky + file ./ports/unix/build-coverage/micropython + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython MICROPY_TEST_TIMEOUT=90 ./run-tests.py --exclude 'vfs_posix.*\.py|thread/stress_recurse.py|thread/thread_gc1.py') +} + +function ci_unix_qemu_riscv64_setup { + sudo apt-get update + sudo apt-get install gcc-riscv64-linux-gnu g++-riscv64-linux-gnu + sudo apt-get install qemu-user + qemu-riscv64 --version + sudo mkdir /etc/qemu-binfmt + sudo ln -s /usr/riscv64-linux-gnu/ /etc/qemu-binfmt/riscv64 +} + +function ci_unix_qemu_riscv64_build { + ci_unix_build_helper "${CI_UNIX_OPTS_QEMU_RISCV64[@]}" + ci_unix_build_ffi_lib_helper riscv64-linux-gnu-gcc +} + +function ci_unix_qemu_riscv64_run_tests { + # Issues with RISCV-64 tests: + # - thread/stress_aes.py takes around 140 seconds + # - thread/stress_recurse.py is flaky + # - thread/thread_gc1.py is flaky file ./ports/unix/build-coverage/micropython - (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython ./run-tests.py --exclude 'vfs_posix.*\.py') + (cd tests && MICROPY_MICROPYTHON=../ports/unix/build-coverage/micropython MICROPY_TEST_TIMEOUT=180 ./run-tests.py --exclude 'thread/stress_recurse.py|thread/thread_gc1.py') +} + +function ci_unix_repr_b_build { + ci_unix_build_helper "${CI_UNIX_OPTS_REPR_B[@]}" + ci_unix_build_ffi_lib_helper gcc -m32 +} + +function ci_unix_repr_b_run_tests { + # ci_unix_run_tests_full_no_native_helper is not used due to + # https://github.com/micropython/micropython/issues/18105 + ci_unix_run_tests_helper "${CI_UNIX_OPTS_REPR_B[@]}" } ######################################################################################## # ports/windows function ci_windows_setup { + sudo apt-get update sudo apt-get install gcc-mingw-w64 } @@ -679,25 +985,44 @@ function ci_windows_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/windows submodules make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=i686-w64-mingw32- + make ${MAKEOPTS} -C ports/windows CROSS_COMPILE=x86_64-w64-mingw32- BUILD=build-standard-w64 } ######################################################################################## # ports/zephyr -ZEPHYR_DOCKER_VERSION=v0.21.0 -ZEPHYR_SDK_VERSION=0.13.2 -ZEPHYR_VERSION=v3.1.0 +ZEPHYR_DOCKER_VERSION=v0.28.1 +ZEPHYR_SDK_VERSION=0.17.2 +ZEPHYR_VERSION=v4.2.0 function ci_zephyr_setup { - docker pull zephyrprojectrtos/ci:${ZEPHYR_DOCKER_VERSION} + IMAGE=ghcr.io/zephyrproject-rtos/ci:${ZEPHYR_DOCKER_VERSION} + + docker pull ${IMAGE} + + # Directories cached by GitHub Actions, mounted + # into the container + ZEPHYRPROJECT_DIR="$(pwd)/zephyrproject" + CCACHE_DIR="$(pwd)/.ccache" + + mkdir -p "${ZEPHYRPROJECT_DIR}" + mkdir -p "${CCACHE_DIR}" + docker run --name zephyr-ci -d -it \ -v "$(pwd)":/micropython \ + -v "${ZEPHYRPROJECT_DIR}":/zephyrproject \ + -v "${CCACHE_DIR}":/root/.cache/ccache \ -e ZEPHYR_SDK_INSTALL_DIR=/opt/toolchains/zephyr-sdk-${ZEPHYR_SDK_VERSION} \ -e ZEPHYR_TOOLCHAIN_VARIANT=zephyr \ -e ZEPHYR_BASE=/zephyrproject/zephyr \ -w /micropython/ports/zephyr \ - zephyrprojectrtos/ci:${ZEPHYR_DOCKER_VERSION} + ${IMAGE} docker ps -a + + # qemu-system-arm is needed to run the test suite. + sudo apt-get update + sudo apt-get install qemu-system-arm + qemu-system-arm --version } function ci_zephyr_install { @@ -707,8 +1032,112 @@ function ci_zephyr_install { } function ci_zephyr_build { + git submodule update --init lib/micropython-lib docker exec zephyr-ci west build -p auto -b qemu_x86 -- -DCONF_FILE=prj_minimal.conf docker exec zephyr-ci west build -p auto -b frdm_k64f docker exec zephyr-ci west build -p auto -b mimxrt1050_evk docker exec zephyr-ci west build -p auto -b nucleo_wb55rg # for bluetooth } + +function ci_zephyr_run_tests { + docker exec zephyr-ci west build -p auto -b qemu_cortex_m3 -- -DCONF_FILE=prj_minimal.conf + (cd tests && ./run-tests.py -t execpty:"qemu-system-arm -cpu cortex-m3 -machine lm3s6965evb -nographic -monitor null -serial pty -kernel ../ports/zephyr/build/zephyr/zephyr.elf") +} + +######################################################################################## +# ports/alif + +function ci_alif_setup { + ci_gcc_arm_setup +} + +function ci_alif_ae3_build { + make ${MAKEOPTS} -C mpy-cross + make ${MAKEOPTS} -C ports/alif BOARD=OPENMV_AE3 MCU_CORE=M55_HP submodules + make ${MAKEOPTS} -C ports/alif BOARD=OPENMV_AE3 MCU_CORE=M55_HE submodules + make ${MAKEOPTS} -C ports/alif BOARD=OPENMV_AE3 MCU_CORE=M55_DUAL + make ${MAKEOPTS} -C ports/alif BOARD=ALIF_ENSEMBLE MCU_CORE=M55_DUAL +} + +function _ci_help { + # Note: these lines must be indented with tab characters (required by bash <<-EOF) + cat <<-EOF + ci.sh: Script fragments used during CI + + When invoked as a script, runs a sequence of ci steps, + stopping after the first error. + + Usage: + ${BASH_SOURCE} step1 step2... + + Steps: + EOF + if type -path column > /dev/null 2>&1; then + grep '^function ci_' $0 | awk '{print $2}' | sed 's/^ci_//' | column + else + grep '^function ci_' $0 | awk '{print $2}' | sed 's/^ci_//' + fi + exit +} + +function _ci_bash_completion { + echo "alias ci=\"$(readlink -f "$0")\"; complete -W '$(grep '^function ci_' $0 | awk '{print $2}' | sed 's/^ci_//')' ci" +} + +function _ci_zsh_completion { + echo "alias ci=\"$(readlink -f "$0"\"); _complete_mpy_ci_zsh() { compadd $(grep '^function ci_' $0 | awk '{sub(/^ci_/,"",$2); print $2}' | tr '\n' ' ') }; autoload -Uz compinit; compinit; compdef _complete_mpy_ci_zsh $(readlink -f "$0")" +} + +function _ci_fish_completion { + echo "alias ci=\"$(readlink -f "$0"\"); complete -c ci -p $(readlink -f "$0") -f -a '$(grep '^function ci_' $(readlink -f "$0") | awk '{sub(/^ci_/,"",$2); print $2}' | tr '\n' ' ')'" +} + +function _ci_main { + case "$1" in + (-h|-?|--help) + _ci_help + ;; + (--bash-completion) + _ci_bash_completion + ;; + (--zsh-completion) + _ci_zsh_completion + ;; + (--fish-completion) + _ci_fish_completion + ;; + (-*) + echo "Unknown option: $1" 1>&2 + exit 1 + ;; + (*) + set -e + cd $(dirname "$0")/.. + while [ $# -ne 0 ]; do + ci_$1 + shift + done + ;; + esac +} + +# https://stackoverflow.com/questions/2683279/how-to-detect-if-a-script-is-being-sourced +sourced=0 +if [ -n "$ZSH_VERSION" ]; then + case $ZSH_EVAL_CONTEXT in *:file) sourced=1;; esac +elif [ -n "$KSH_VERSION" ]; then + [ "$(cd -- "$(dirname -- "$0")" && pwd -P)/$(basename -- "$0")" != "$(cd -- "$(dirname -- "${.sh.file}")" && pwd -P)/$(basename -- "${.sh.file}")" ] && sourced=1 +elif [ -n "$BASH_VERSION" ]; then + (return 0 2>/dev/null) && sourced=1 +else # All other shells: examine $0 for known shell binary filenames. + # Detects `sh` and `dash`; add additional shell filenames as needed. + case ${0##*/} in sh|-sh|dash|-dash) sourced=1;; esac +fi + +if [ $sourced -eq 0 ]; then + # invoked as a command + if [ "$#" -eq 0 ]; then + set -- --help + fi + _ci_main "$@" +fi diff --git a/tools/ci_changes_per_commit.py b/tools/ci_changes_per_commit.py index 6cbd475fa95..71cfb36cf27 100644 --- a/tools/ci_changes_per_commit.py +++ b/tools/ci_changes_per_commit.py @@ -155,6 +155,11 @@ def get_commit_depth_and_check_suite(query_commits): check_suites = commit["checkSuites"] if check_suites["totalCount"] > 0: for check_suite in check_suites["nodes"]: + # workflowRun is null for check suites not attached to + # a workflow run, such as one that was deleted or one + # belonging to an app integration. + if check_suite["workflowRun"] is None: + continue if check_suite["workflowRun"]["workflow"]["name"] == "Build CI": return [ {"sha": commit_sha, "depth": commit_depth}, diff --git a/tools/ci_check_duplicate_usb_vid_pid.py b/tools/ci_check_duplicate_usb_vid_pid.py index 76bb7afea44..66a9fb4c5a3 100644 --- a/tools/ci_check_duplicate_usb_vid_pid.py +++ b/tools/ci_check_duplicate_usb_vid_pid.py @@ -53,21 +53,28 @@ "0x303A:0x7003": [ "espressif_esp32s3_devkitc_1_n8", "espressif_esp32s3_devkitc_1_n8r2", + "espressif_esp32s3_devkitc_1_n8r2_ros", "espressif_esp32s3_devkitc_1_n8r8", "espressif_esp32s3_devkitc_1_n8r8_hacktablet", "espressif_esp32s3_devkitc_1_n16", "espressif_esp32s3_devkitc_1_n32r8", + "espressif_esp32s3_devkitc_1_n32r16", ], "0x303A:0x7009": [ "espressif_esp32s2_devkitc_1_n4", "espressif_esp32s2_devkitc_1_n4r2", "espressif_esp32s2_devkitc_1_n8r2", ], + "0x303A:0x81DA": [ + "m5stack_cardputer", + "m5stack_cardputer_ros", + ], "0x239A:0x102E": ["weact_studio_pico", "weact_studio_pico_16mb"], "0x303A:0x8166": ["yd_esp32_s3_n8r8", "yd_esp32_s3_n16r8"], "0x2341:0x056B": ["arduino_nano_esp32s3", "arduino_nano_esp32s3_inverted_statusled"], "0x2E8A:0x1020": ["waveshare_rp2040_plus_4mb", "waveshare_rp2040_plus_16mb"], "0x2341:0x805A": ["arduino_nano_33_ble", "arduino_nano_33_ble_rev2"], + "0x303A:0x8154": ["lilygo_tqt_pro_nopsram", "lilygo_tqt_pro_psram"], } cli_parser = argparse.ArgumentParser( @@ -98,7 +105,7 @@ def check_vid_pid(files, clusterlist): """ usb_pattern = re.compile( - r"^CIRCUITPY_USB_DEVICE\s*=\s*0$|^IDF_TARGET = (esp32|esp32c2|esp32c3|esp32c6|esp32h2|esp32p4)$|^MCU_SERIES = MG24$", + r"^CIRCUITPY_USB_DEVICE\s*=\s*0$|^IDF_TARGET = (esp32|esp32c2|esp32c3|esp32c5|esp32c6|esp32c61|esp32h2|esp32p4)$|^MCU_SERIES = MG24$", flags=re.M, ) @@ -138,9 +145,9 @@ def check_vid_pid(files, clusterlist): cluster = set(clusterlist.get(key, [])) if cluster != boards: if key == "": - duplicates.append(f"- Non-USB:\n" f" Boards: {', '.join(sorted(boards))}") + duplicates.append(f"- Non-USB:\n Boards: {', '.join(sorted(boards))}") else: - duplicates.append(f"- VID/PID: {key}\n" f" Boards: {', '.join(sorted(boards))}") + duplicates.append(f"- VID/PID: {key}\n Boards: {', '.join(sorted(boards))}") if duplicates: duplicates = "\n".join(duplicates) diff --git a/tools/ci_fetch_deps.py b/tools/ci_fetch_deps.py index cbae4b3ff5e..8994e54c338 100644 --- a/tools/ci_fetch_deps.py +++ b/tools/ci_fetch_deps.py @@ -35,17 +35,15 @@ def _all_submodules(): all_submodules = _all_submodules() -def matching_submodules(s): - if s.endswith("/"): - return [m for m in all_submodules if m.startswith(s)] - elif s not in all_submodules: - raise ValueError(f"{s!r} is not a submodule") - return [s] - - # Submodules needed by port builds outside of their ports directory. # Should we try and detect these? PORT_DEPS = { + "analog": [ + "extmod/ulab/", + "lib/tlsf/", + "lib/tinyusb/", + "lib/protomatter", + ], "atmel-samd": [ "extmod/ulab/", "lib/adafruit_floppy/", @@ -61,6 +59,7 @@ def matching_submodules(s): "espressif": [ "extmod/ulab/", "lib/certificates/", + "lib/mp3/", "lib/protomatter/", "lib/quirc/", "lib/tlsf", @@ -70,6 +69,7 @@ def matching_submodules(s): "mimxrt10xx": ["extmod/ulab/", "lib/tinyusb/", "lib/tlsf", "data/nvm.toml/"], "nordic": [ "extmod/ulab/", + "lib/mbedtls/", "lib/mp3/", "lib/protomatter/", "lib/tinyusb/", @@ -98,6 +98,11 @@ def matching_submodules(s): "lib/tlsf", "data/nvm.toml/", ], + "zephyr-cp": [ + "lib/certificates/", + "lib/tinyusb/", + "lib/tlsf", + ], # omit unix which is part of the "test" target below } @@ -139,6 +144,22 @@ def fetch(where): for s in matching_submodules([w for w in where if w.startswith("frozen")]): run(f"Ensure tags exist in {s}", "git fetch --tags --depth 1", cwd=TOP / s) + # mbedtls 4.x keeps its crypto in a nested tf-psa-crypto submodule, and the PSA + # driver-wrapper generator needs the framework submodule. Init them by name rather + # than with --recursive, which would also pull tf-psa-crypto's own framework copy + # and drivers/pqcp/mldsa-native. Those are not needed to build. + # Keyed off the checkout rather than off `where`, because the targets that pull + # lib/mbedtls name it several different ways ("lib/mbedtls/", "lib/", or "." for + # the `all` target). + mbedtls = TOP / "lib" / "mbedtls" + if (mbedtls / ".gitmodules").exists(): + depth_maybe = "" if clone_supports_filter else "--depth 1" + run( + "Init mbedtls nested submodules", + f"git submodule update --init {filter_maybe} {depth_maybe} tf-psa-crypto framework", + cwd=mbedtls, + ) + def set_output(name, value): if "GITHUB_OUTPUT" in os.environ: @@ -182,6 +203,9 @@ def main(target): submodules.extend(PORT_DEPS[port]) unique_submodules = set(submodules) submodules = list(unique_submodules) + elif target == "windows-zephyr": + submodules.append("ports/zephyr-cp") + submodules.extend(PORT_DEPS["zephyr-cp"]) elif target == "website": submodules = ["tools/adabot", "frozen"] elif target == "pre-commit": @@ -191,28 +215,47 @@ def main(target): target ] else: - p = list(pathlib.Path(TOP).glob(f"ports/*/boards/{target}/mpconfigboard.mk")) + p = list(TOP.glob(f"ports/*/boards/{target}/mpconfigboard.mk")) + # Check to see if the board is nested under vendor. + if not p: + next_underscore = target.find("_") + while next_underscore != -1: + vendor = target[:next_underscore] + board = target[next_underscore + 1 :] + p = list(TOP.glob(f"ports/*/boards/{vendor}/{board}/circuitpython.toml")) + if p: + break + next_underscore = target.find("_", next_underscore + 1) + if not p: raise RuntimeError(f"Unsupported target: {target}") config = p[0] # Add the ports folder to init submodules - port_folder = config.parents[2] + + if config.suffix == ".mk": + port_folder = config.parents[2] + else: + port_folder = config.parents[3] port = port_folder.name submodules.append(f"ports/{port}") submodules.append("tools/") # for huffman submodules.extend(PORT_DEPS[port]) - with config.open() as f: - for line in f.readlines(): - prefix = "FROZEN_MPY_DIRS += $(TOP)/" - if line.startswith(prefix): - lib_folder = line.strip()[len(prefix) :] - # Drop everything after the second folder because the frozen - # folder may be inside the submodule. - if lib_folder.count("/") > 1: - lib_folder = lib_folder.split("/", maxsplit=2) - lib_folder = "/".join(lib_folder[:2]) - submodules.append(lib_folder) + if config.suffix == ".mk": + with config.open() as f: + for line in f.readlines(): + prefix = "FROZEN_MPY_DIRS += $(TOP)/" + if line.startswith(prefix): + lib_folder = line.strip()[len(prefix) :] + # Drop everything after the second folder because the frozen + # folder may be inside the submodule. + if lib_folder.count("/") > 1: + lib_folder = lib_folder.split("/", maxsplit=2) + lib_folder = "/".join(lib_folder[:2]) + submodules.append(lib_folder) + else: + # TODO: Add a way to specify frozen modules in circuitpython.toml + pass print("Submodules:", " ".join(submodules)) diff --git a/tools/ci_set_idf_constraint.py b/tools/ci_set_idf_constraint.py new file mode 100644 index 00000000000..49c187f4587 --- /dev/null +++ b/tools/ci_set_idf_constraint.py @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 Adafruit Industries LLC +# +# SPDX-License-Identifier: MIT + +"""Set IDF_CONSTRAINT_FILE for CI. + +CI installs requirements-dev.txt for all ports, but on Espressif builds we must +also apply the matching ESP-IDF constraints file so pip does not upgrade shared +packages (for example click) beyond what ESP-IDF allows. This script derives the +active ESP-IDF major.minor version from version.cmake and exports the exact +constraints file path into GITHUB_ENV for later install steps. +""" + +import os +import pathlib +import re + +TOP = pathlib.Path(__file__).resolve().parent.parent + + +def main() -> None: + version_cmake = TOP / "ports" / "espressif" / "esp-idf" / "tools" / "cmake" / "version.cmake" + data = version_cmake.read_text(encoding="utf-8") + + major = re.search(r"IDF_VERSION_MAJOR\s+(\d+)", data) + minor = re.search(r"IDF_VERSION_MINOR\s+(\d+)", data) + if major is None or minor is None: + raise RuntimeError(f"Unable to parse IDF version from {version_cmake}") + + idf_tools_path = os.environ.get("IDF_TOOLS_PATH") + if not idf_tools_path: + raise RuntimeError("IDF_TOOLS_PATH is not set") + + constraint = ( + pathlib.Path(idf_tools_path) / f"espidf.constraints.v{major.group(1)}.{minor.group(1)}.txt" + ) + + github_env = os.environ.get("GITHUB_ENV") + if github_env: + with open(github_env, "a", encoding="utf-8") as f: + f.write(f"IDF_CONSTRAINT_FILE={constraint}\n") + + print(f"Set IDF_CONSTRAINT_FILE={constraint}") + + +if __name__ == "__main__": + main() diff --git a/tools/ci_set_matrix.py b/tools/ci_set_matrix.py index d050d8e44c9..11bffbaa755 100755 --- a/tools/ci_set_matrix.py +++ b/tools/ci_set_matrix.py @@ -39,7 +39,6 @@ from shared_bindings_matrix import ( get_settings_from_makefile, SUPPORTED_PORTS, - all_ports_all_boards, ) # Files that never influence board builds @@ -151,7 +150,7 @@ def get_settings(board): if not build_all: pattern_port = re.compile(r"^ports/([^/]+)/") - pattern_board = re.compile(r"^ports/[^/]+/boards/([^/]+)/") + pattern_board = re.compile(r"^ports/([^/]+)/boards/([^/]+)/") pattern_module = re.compile( r"^(ports/[^/]+/(?:common-hal|bindings)|shared-bindings|shared-module)/([^/]+)/" ) @@ -166,7 +165,14 @@ def get_settings(board): # See if it is board specific board_matches = pattern_board.search(file) if board_matches: - boards_to_build.add(board_matches.group(1)) + port = board_matches.group(1) + board = board_matches.group(2) + if port == "zephyr-cp": + p = pathlib.Path(file) + board_id = p.parent.name + vendor_id = p.parent.parent.name + board = f"{vendor_id}_{board_id}" + boards_to_build.add(board) continue # See if it is port specific @@ -181,7 +187,19 @@ def get_settings(board): # As a (nearly) last resort, for some certain files, we compute the settings from the # makefile for each board and determine whether to build them that way if file.startswith("frozen") or file.startswith("supervisor") or module_matches: - boards = port_to_board[port] if port else all_board_ids + # Take a copy, because we remove items from it below. For + # instance, if we remove items from, say, all_board_ids, then + # the logic to build all boards breaks. + boards = set(port_to_board[port] if port else all_board_ids) + + # Zephyr boards don't use make, so build them and don't compute their settings. + for board in port_to_board["zephyr-cp"]: + if board in boards: + boards_to_build.add(board) + + for board in boards_to_build: + if board in boards: + boards.remove(board) compute_board_settings(boards) for board in boards: @@ -234,6 +252,7 @@ def get_settings(board): # A board can appear due to its _deletion_ (rare) # if this happens it's not in `board_to_port`. if not port: + print("skip", board) continue port_to_boards_to_build.setdefault(port, []).append(board) print(" ", board) diff --git a/tools/circuitpy_header_change.py b/tools/circuitpy_header_change.py index 8d553487490..aa931f65602 100755 --- a/tools/circuitpy_header_change.py +++ b/tools/circuitpy_header_change.py @@ -48,18 +48,16 @@ def find_related_copyrights(filename): def fix_file(filename, change): copyrights = [] mit_license = False - empty_file = False first_line = "" no_existing_header = False with open(filename, "r") as f: lines = f.readlines() if not lines: - empty_file = True no_existing_header = True mit_license = True copyrights.append( - f"// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC" + "// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC" ) else: first_line = lines.pop(0) @@ -111,7 +109,7 @@ def fix_file(filename, change): copyrights = find_related_copyrights(filename) if not copyrights: copyrights.append( - f"// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC" + "// SPDX-FileCopyrightText: Copyright (c) 2024 Adafruit Industries LLC" ) if change: diff --git a/tools/codeformat.py b/tools/codeformat.py index 5f5a5f7409d..cf91049a731 100644 --- a/tools/codeformat.py +++ b/tools/codeformat.py @@ -39,7 +39,6 @@ # Relative to top-level repo dir. # CIRCUITPY-CHANGE: different directory trees PATHS = [ - # C "main.c", "devices/**/*.[ch]", "extmod/*.[ch]", @@ -52,26 +51,14 @@ "shared-bindings/**/*.[ch]", "shared-module/**/*.[ch]", "supervisor/**/*.[ch]", - # Python - "extmod/*.py", - "ports/**/*.py", - "py/**/*.py", - "tools/**/*.py", - "tests/circuitpython-*/**/*.py", ] # CIRCUITPY-CHANGE: different exclusions EXCLUSIONS = [ # STM32 build includes generated Python code. "ports/*/build*", - # gitignore in ports/unix ignores *.py, so also do it here. - "ports/unix/**/*.py", - # not real python files - "tests/**/repl_*.py", # don't reindent this third-party code we vendored in "ports/raspberrypi/lwip_src", - # line breaks - "tools/mpy-tool.py", ] @@ -119,12 +106,6 @@ def transform(m): TOP = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) UNCRUSTIFY_CFG = os.path.join(TOP, "tools/uncrustify.cfg") -# CIRCUITPY-CHANGE -C_EXTS = ( - ".c", - ".h", -) -PY_EXTS = (".py",) def check_uncrustify_version(): @@ -217,14 +198,8 @@ def main(): # Expand the arguments passed on the command line, subject to the PATHS and EXCLUSIONS files = list_files(args.files) - # Extract files matching a specific language. - def lang_files(exts): - for file in files: - if os.path.splitext(file)[1].lower() in exts: - yield file - def bindings_files(): - for file in lang_files(C_EXTS): + for file in files: if file.startswith("shared-bindings/") or "/bindings/" in file: yield file @@ -248,22 +223,23 @@ def batch(cmd, files, N=200, check=False): command = ["uncrustify", "-c", UNCRUSTIFY_CFG, "-lC", "--no-backup"] if not args.v: command.append("-q") - batch(command, lang_files(C_EXTS)) - for file in lang_files(C_EXTS): + batch(command, iter(files)) + for file in files: fixup_c(file) - # Format bindings with black_bindings + # Format bindings with ruff_bindings if format_py: - command = ["python3", "tools/black_bindings.py"] + command = ["python3", "tools/ruff_bindings.py"] batch(command, bindings_files(), check=True) - # Format Python files with black. + # Format Python files with "ruff format" (using config in pyproject.toml). if format_py: - command = ["black", "--fast", "--line-length=99"] + command = ["ruff", "format"] if args.v: command.append("-v") else: command.append("-q") - batch(command, lang_files(PY_EXTS)) + command.append(".") + subprocess.check_call(command, cwd=TOP) if __name__ == "__main__": diff --git a/tools/cortex-m-fault-gdb.py b/tools/cortex-m-fault-gdb.py index 8de754ed260..dd8838c44f5 100644 --- a/tools/cortex-m-fault-gdb.py +++ b/tools/cortex-m-fault-gdb.py @@ -1,5 +1,7 @@ """Source this file into gdb `source ../../tools/cortex-m-fault-gdb.py` then run - `cortex-m-fault` to print basic info about the fault registers.""" +`cortex-m-fault` to print basic info about the fault registers.""" + +import gdb SCS = 0xE000E000 SCB = SCS + 0x0D00 @@ -180,7 +182,7 @@ def invoke(self, arg, from_tty): architecture = (cpuid >> 16) & 0xF revision = cpuid & 0xF part_no = (cpuid >> 4) & 0xFFF - print(PARTS[part_no]) + print(PARTS[part_no], variant, revision) if part_no == 0xD21: self._armv8m_fault() diff --git a/tools/cpboard.py b/tools/cpboard.py index 12d7d374a35..d72d14a2402 100644 --- a/tools/cpboard.py +++ b/tools/cpboard.py @@ -343,7 +343,6 @@ def from_usb(cls, baudrate=115200, wait=0, timeout=10, **kwargs): dev = usb.core.find(**kwargs) if not dev: - s = "Can't find USB device: " args = [] for x in kwargs.items(): try: diff --git a/tools/describe b/tools/describe deleted file mode 100755 index 0f3b541e3cd..00000000000 --- a/tools/describe +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -if [ -z "$CP_VERSION" ]; then - git describe --first-parent --dirty --tags --match "[1-9].*" "$@" -else - echo $CP_VERSION -fi diff --git a/tools/diff_nm_sizes.py b/tools/diff_nm_sizes.py index 241355ea182..fdfcdaad496 100644 --- a/tools/diff_nm_sizes.py +++ b/tools/diff_nm_sizes.py @@ -44,8 +44,7 @@ continue print(f"{name:<{longest_symbol}}{size - old_size:>+6}") -for name in old_symbols: - old_size = old_symbols[name] +for name, old_size in old_symbols.items(): print(f"{name:<{longest_symbol}}{-old_size:>+6}") print() diff --git a/tools/extract_pyi.py b/tools/extract_pyi.py index e6bc703c021..e340712d189 100644 --- a/tools/extract_pyi.py +++ b/tools/extract_pyi.py @@ -62,7 +62,7 @@ def is_typed(node, allow_any=False): return False elif ( isinstance(node, ast.Attribute) - and type(node.value) == ast.Name + and type(node.value) is ast.Name and node.value.id == "typing" and node.attr == "Any" ): diff --git a/tools/file2h.py b/tools/file2h.py index df9cc02fdab..2707d4a16e5 100644 --- a/tools/file2h.py +++ b/tools/file2h.py @@ -9,8 +9,6 @@ # ; # This script simply prints the escaped string straight to stdout -from __future__ import print_function - import sys # Can either be set explicitly, or left blank to auto-detect diff --git a/tools/fixup_translations.py b/tools/fixup_translations.py index 4c6f89b26ff..21a5812da96 100644 --- a/tools/fixup_translations.py +++ b/tools/fixup_translations.py @@ -84,8 +84,7 @@ first_translations.save(po_filename) print() -for commit in bad_commits: - files = bad_commits[commit] +for commit, files in bad_commits.items(): print(commit) for file in files: print("\t", file) diff --git a/tools/gdb-stack-size.py b/tools/gdb-stack-size.py index 4d3fc9fe08a..6426cf42956 100644 --- a/tools/gdb-stack-size.py +++ b/tools/gdb-stack-size.py @@ -1,5 +1,7 @@ """Source this file into gdb `source ../../tools/gdb-stack-size.py` then run - `stack-size` to print a backtrace with each frame size next to it.""" +`stack-size` to print a backtrace with each frame size next to it.""" + +import gdb class StackSize(gdb.Command): diff --git a/tools/gen_display_resources.py b/tools/gen_display_resources.py index dbf3f9a9946..9ed829f7d37 100644 --- a/tools/gen_display_resources.py +++ b/tools/gen_display_resources.py @@ -8,8 +8,8 @@ import struct import sys -sys.path.insert(0, "bitmap_font") -sys.path.insert(0, "../../tools/bitmap_font") +sys.path.insert(0, "tools/bitmap_font") # For running from root +sys.path.insert(0, "../../tools/bitmap_font") # For running from a port directory from adafruit_bitmap_font import bitmap_font @@ -234,9 +234,7 @@ def _load_row(self, y, row): .in_group = true }}; #endif -""".format( - blinka_size - ) +""".format(blinka_size) ) c_file.write( @@ -285,9 +283,7 @@ def _load_row(self, y, row): .inline_tiles = false, .in_group = true }}; -""".format( - len(all_characters), tile_x, tile_y - ) +""".format(len(all_characters), tile_x, tile_y) ) c_file.write( @@ -315,17 +311,13 @@ def _load_row(self, y, row): .inline_tiles = false, .in_group = true }}; -""".format( - len(all_characters), tile_x, tile_y - ) +""".format(len(all_characters), tile_x, tile_y) ) c_file.write( """\ const uint32_t font_bitmap_data[{}] = {{ -""".format( - bytes_per_row * tile_y // 4 - ) +""".format(bytes_per_row * tile_y // 4) ) for i, word in enumerate(struct.iter_unpack("\n\n") +c_file.write("// Autogenerated by tools/gen_web_workflow_static.py\n") +c_file.write("#include \n\n") for f in args.files: path = pathlib.Path(f.name) diff --git a/tools/insert-usb-ids.py b/tools/insert-usb-ids.py index 4691d5a710c..1b043e1fef0 100644 --- a/tools/insert-usb-ids.py +++ b/tools/insert-usb-ids.py @@ -6,8 +6,6 @@ # inserts those values into the template file specified by sys.argv[2], # printing the result to stdout -from __future__ import print_function - import sys import re import string diff --git a/tools/makemanifest.py b/tools/makemanifest.py index a74a6934aea..860935397af 100644 --- a/tools/makemanifest.py +++ b/tools/makemanifest.py @@ -24,7 +24,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from __future__ import print_function import sys import os import subprocess @@ -245,7 +244,11 @@ def main(): b'#include "py/emitglue.h"\n' b"extern const qstr_pool_t mp_qstr_const_pool;\n" b"const qstr_pool_t mp_qstr_frozen_const_pool = {\n" - b" (qstr_pool_t*)&mp_qstr_const_pool, MP_QSTRnumber_of, 0, 0\n" + b" #if MICROPY_QSTR_BYTES_IN_HASH\n" + b" (qstr_pool_t*)&mp_qstr_const_pool, MP_QSTRnumber_of, 0, 0, 0, NULL, NULL, {},\n" + b" #else\n" + b" (qstr_pool_t*)&mp_qstr_const_pool, MP_QSTRnumber_of, 0, 0, 0, NULL, {},\n" + b" #endif\n" b"};\n" b'const char mp_frozen_names[] = { MP_FROZEN_STR_NAMES "\\0"};\n' b"const mp_raw_code_t *const mp_frozen_mpy_content[] = {NULL};\n" diff --git a/tools/manifestfile.py b/tools/manifestfile.py index beaa36d0f5f..9c7a6e140f9 100644 --- a/tools/manifestfile.py +++ b/tools/manifestfile.py @@ -25,7 +25,6 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -from __future__ import print_function import contextlib import os import sys diff --git a/tools/merge_micropython.py b/tools/merge_micropython.py index 37d44c3b7e3..7c4d7650793 100644 --- a/tools/merge_micropython.py +++ b/tools/merge_micropython.py @@ -8,7 +8,7 @@ I add a sys.exit(0) after a section, and once a section runs, I delete it temporarily and move on to the next section. -- dhalbert -Updated for v1.22.2 merge - dhalbert +Updated for v1.25.0 merge - dhalbert """ @@ -18,256 +18,233 @@ from sh import git import sys -out_buf = StringIO() -ports_to_delete = [ - "bare-arm", - "cc3200", - "embed", - "esp32", - "esp8266", - "mimxrt", - "minimal", - "nrf", - "pic16bit", - "powerpc", - "qemu-arm", - "renesas-ra", - "rp2", - "samd", - "stm32", - "webassembly", - "windows", - "zephyr", -] -for p in ports_to_delete: - try: - git.rm("-rf", "ports/" + p) - except sh.ErrorReturnCode_128: - pass +def rm_paths(base, paths): + for path in paths: + try: + git.rm("-rf", base + "/" + path) + except sh.ErrorReturnCode_128: + pass -# We inherit stm32 changes into stm because we did a git rename. -git.status("--porcelain=1", "ports/stm", _out=out_buf) -out_buf.seek(0) -line = out_buf.readline() -while line: - state, path = line.split() - if state == "UU": - git.checkout("--ours", path) - git.add(path) - elif state == "UA": - git.rm(path) - line = out_buf.readline() -# MicroPython has their own CI settings. Let's not use them now. -out_buf = StringIO() -git.status("--porcelain=1", ".github/workflows", _out=out_buf) -out_buf.seek(0) -line = out_buf.readline() -while line: - state, path = line.split() - if state == "A": - git.rm("-f", path) - else: - print(state, path) - line = out_buf.readline() - -# Delete docs and tests for things we don't need anymore -docs_to_delete = [ - "conf.py", - "develop", - "differences", - "esp32", - "esp8266", - "library/bluetooth.rst", - "library/btree.rst", - "library/cryptolib.rst", - "library/esp*.rst", - "library/framebuf.rst", - "library/hashlib.rst", - "library/lcd160cr.rst", - "library/machine*.rst", - "library/math.rst", - "library/network*.rst", - "library/os.rst", - "library/pyb*.rst", - "library/random.rst", - "library/rp2*.rst", - "library/uos.rst", - "library/socket.rst", - "library/ssl.rst", - "library/stm.rst", - "library/struct.rst", - "library/_thread.rst", - "library/time.rst", - "library/uasyncio.rst", - "library/uctypes.rst", - "library/wipy.rst", - "library/wm8960.rst", - "library/zephyr*.rst", - "library/zlib.rst", - "make.bat", - "mimxrt", - "pyboard", - "reference", - "renesas-ra", - "rp2", - "samd", - "templates/topindex.html", - "wipy", - "zephyr", -] -for d in docs_to_delete: - try: - git.rm("-rf", "docs/" + d) - except sh.ErrorReturnCode_128: - pass - -tests_to_delete = [ - "esp32", - "multi_bluetooth", - "multi_espnow", - "multi_net", - "net_hosted", - "net_inet", - "pyb", - "wipy", -] -for t in tests_to_delete: - try: - git.rm("-rf", "tests/" + t) - except sh.ErrorReturnCode_128: - pass - - -libs_to_delete = [ - "asf4", - "btstack", - "libhydrogen", - "lwip", - "micropython-lib", - "mynewt-nimble", - "nrfx", - "nxp_driver", - "pico-sdk", - "protobuf-c", - "stm32lib", - "wiznet5k", -] -for l in libs_to_delete: - try: - git.rm("-rf", "lib/" + l) - except sh.ErrorReturnCode_128: - pass - -extmod_to_delete = [ - "btstack", - "extmod.cmake", - "machine_*", - "mbedtls", - "modbluetooth.*", - "modbtree.*", - "modframebuf.*", - "modlwip.*", - "modnetwork.*", - "modonewire.*", - "moducryptolib.*", - "modsocket.*", - "modssl_*.*", - "modtimeq.*", - "modwebsocket.*", - "modwebrepl.*", - "mpbthci.*", - "network_*.*", - "nimble", -] -for e in extmod_to_delete: - try: - git.rm("-rf", "extmod/" + e) - except sh.ErrorReturnCode_128 as error: - print(error) - -top_delete = [ - "drivers", - "README.md", - "CODEOFCONDUCT.md", - "CODECONVENTIONS.md", -] -for t in top_delete: - try: - git.rm("-rf", t) - except sh.ErrorReturnCode_128: - pass - -dot_github_delete = [ - ".github/dependabot.yml", - ".github/FUNDING.yml", - ".github/ISSUE_TEMPLATE/documentation.md", - ".github/ISSUE_TEMPLATE/security.md", - ".github/workflows/code_formatting.yml", - ".github/workflows/code_size_comment.yml", - ".github/workflows/code_size.yml", - ".github/workflows/commit_formatting.yml", - ".github/workflows/docs.yml", - ".github/workflows/examples.yml", - ".github/workflows/mpremote.yml", - ".github/workflows/mpy_format.yml", - ".github/workflows/mpy_format.yml", - ".github/workflows/ports_*.yml", -] -for t in dot_github_delete: - try: - git.rm("-rf", t) - except sh.ErrorReturnCode_128: - pass - -# Always ours: -always_ours = [ - ".github", - "devices", - "supervisor", - "shared-bindings", - "shared-module", - "ports/atmel-samd", - "ports/cxd56", - "ports/espressif", - "ports/mimxrt10xx", - "ports/raspberrypi", - "ports/stm", -] -for ours in always_ours: - out_buf = StringIO() - git.status("--porcelain=1", ours, _out=out_buf) - out_buf.seek(0) - line = out_buf.readline() - while line: - state, path = line.split() - if state == "UU": - print("ours", path) - git.checkout("--ours", path) - git.add(path) - else: - print(state, path) +def checkout_ours(always_ours): + for ours in always_ours: + out_buf = StringIO() + git.status("--porcelain=1", ours, _out=out_buf) + out_buf.seek(0) line = out_buf.readline() + while line: + state, path = line.split() + if state == "UU": + print("ours", path) + git.checkout("--ours", path) + git.add(path) + else: + print(state, path) + line = out_buf.readline() + + +rm_paths( + "ports", + [ + "alif", + "bare-arm", + "cc3200", + "embed", + "esp32", + "esp8266", + "mimxrt", + "minimal", + "nrf", + "pic16bit", + "powerpc", + "qemu", + "renesas-ra", + "rp2", + "samd", + "stm32", + "webassembly", + "windows", + "zephyr", + ], +) + +# Delete MicroPython-specific docs. +rm_paths( + "docs", + [ + "conf.py", + "develop", + "differences", + "esp32", + "esp8266", + "library/bluetooth.rst", + "library/btree.rst", + "library/cryptolib.rst", + "library/esp*.rst", + "library/framebuf.rst", + "library/hashlib.rst", + "library/lcd160cr.rst", + "library/machine*.rst", + "library/math.rst", + "library/network*.rst", + "library/os.rst", + "library/pyb*.rst", + "library/random.rst", + "library/rp2*.rst", + "library/uos.rst", + "library/socket.rst", + "library/ssl.rst", + "library/stm.rst", + "library/struct.rst", + "library/_thread.rst", + "library/time.rst", + "library/uasyncio.rst", + "library/uctypes.rst", + "library/vfs.rst", + "library/wipy.rst", + "library/wm8960.rst", + "library/zephyr*.rst", + "library/zlib.rst", + "make.bat", + "mimxrt", + "pyboard", + "renesas-ra", + "rp2", + "samd", + "templates/topindex.html", + "wipy", + "zephyr", + ], +) + +# Delete MicroPython-specific tests. +rm_paths( + "tests", + [ + "esp32", + "multi_bluetooth", + "multi_espnow", + "multi_net", + "multi_pyb_can", + "multi_wlan", + "net_hosted", + "net_inet", + "ports", + "pyb", + "wipy", + ], +) + +# libs we don't use +rm_paths( + "lib", + [ + "alif*", + "asf4", + "btstack", + "libhydrogen", + "lwip", + "mynewt-nimble", + "nrfx", + "nxp_driver", + "pico-sdk", + "protobuf-c", + "stm32lib", + "wiznet5k", + ], +) + +# extmod modules we don't use +rm_paths( + "extmod", + [ + "btstack", + "extmod.cmake", + "machine_*", + "mbedtls", + "modbluetooth.*", + "modbtree.*", + "modframebuf.*", + "modlwip.*", + "modmachine.*", + "modnetwork.*", + "modonewire.*", + "moducryptolib.*", + "modsocket.*", + "modssl_*", + "modtls_*", + "modtimeq.*", + "modwebsocket.*", + "modwebrepl.*", + "mpbthci.*", + "network_*", + "nimble", + "virtpin.*", + ], +) + +# shared things we don't use +rm_paths( + "shared", + [ + "netutils", + "tinyusb", + "runtime/softtimer.*", + ], +) + +# top-level files and dirs we don't use +rm_paths( + "", + [ + "drivers", + "LICENSE_MicroPython", + "README.md", + "CODEOFCONDUCT.md", + "CODECONVENTIONS.md", + ], +) + +# .github and CI we don't use +rm_paths( + ".github", + [ + "dependabot.yml", + "FUNDING.yml", + "ISSUE_TEMPLATE/feature_request.yml", + "ISSUE_TEMPLATE/documentation.yml", + "ISSUE_TEMPLATE/security.yml", + "workflows/biome.yml", + "workflows/code_formatting.yml", + "workflows/code_size_comment.yml", + "workflows/code_size.yml", + "workflows/codespell.yml", + "workflows/commit_formatting.yml", + "workflows/docs.yml", + "workflows/examples.ymlworkflows/mpremote.yml", + "workflows/mpy_format.yml", + "workflows/ports_*.yml", + "workflows/ruff.yml", + ], +) -# # Check to see if any files changed only in formatting -# out_buf = StringIO() -# git.status("--porcelain=1", ".", _out=out_buf) -# out_buf.seek(0) -# line = out_buf.readline() -# while line: -# state = line.split()[0] -# if state in ("D", "R", "DD"): -# line = out_buf.readline() -# continue -# state, path = line.split() -# log_buf = StringIO() -# git.log("--pretty=tformat:%H", "25ae98f..HEAD", path, _out=log_buf, _tty_out=False) -# log_buf.seek(0) -# commits = [] -# for line in log_buf.readlines(): -# commits.append(line.strip()) -# if state in ["UU", "M"] and commits == ["a52eb88031620a81521b937f2a0651dbac2bb350"]: -# git.checkout("--theirs", path) -# git.add(path) -# line = out_buf.readline() +# Always ours: +checkout_ours( + [ + ".github", + "devices", + "lib/mbedtls_config", + "supervisor", + "shared-bindings", + "shared-module", + "ports/atmel-samd", + "ports/cxd56", + "ports/espressif", + "ports/mimxrt10xx", + "ports/raspberrypi", + "ports/silabs", + # We inherit stm32 changes into stm because we did a git rename. + "ports/stm", + ] +) diff --git a/tools/metrics.py b/tools/metrics.py index 9c5ed1d7d5a..8bb96ba119a 100755 --- a/tools/metrics.py +++ b/tools/metrics.py @@ -43,20 +43,23 @@ """ -import collections, sys, re, subprocess +import collections, os, sys, re, shlex, subprocess, multiprocessing -MAKE_FLAGS = ["-j3", "CFLAGS_EXTRA=-DNDEBUG"] +MAKE_FLAGS = ["-j{}".format(multiprocessing.cpu_count()), "CFLAGS_EXTRA=-DNDEBUG"] class PortData: - def __init__(self, name, dir, output, make_flags=None): + def __init__(self, name, dir, output, make_flags=None, pre_cmd=None): self.name = name self.dir = dir self.output = output self.make_flags = make_flags self.needs_mpy_cross = dir not in ("bare-arm", "minimal") + self.pre_cmd = pre_cmd +mpy_cross_output = "mpy-cross/build/mpy-cross" + port_data = { "b": PortData("bare-arm", "bare-arm", "build/firmware.elf"), "m": PortData("minimal x86", "minimal", "build/firmware.elf"), @@ -65,16 +68,29 @@ def __init__(self, name, dir, output, make_flags=None): "s": PortData("stm32", "stm32", "build-PYBV10/firmware.elf", "BOARD=PYBV10"), "c": PortData("cc3200", "cc3200", "build/WIPY/release/application.axf", "BTARGET=application"), "8": PortData("esp8266", "esp8266", "build-ESP8266_GENERIC/firmware.elf"), - "3": PortData("esp32", "esp32", "build-ESP32_GENERIC/micropython.elf"), + "3": PortData( + "esp32", + "esp32", + "build-ESP32_GENERIC/micropython.elf", + pre_cmd=". esp-idf/export.sh", + ), "x": PortData("mimxrt", "mimxrt", "build-TEENSY40/firmware.elf"), "e": PortData("renesas-ra", "renesas-ra", "build-EK_RA6M2/firmware.elf"), "r": PortData("nrf", "nrf", "build-PCA10040/firmware.elf"), - "p": PortData("rp2", "rp2", "build-RPI_PICO/firmware.elf"), + "p": PortData("rp2", "rp2", "build-RPI_PICO_W/firmware.elf", "BOARD=RPI_PICO_W"), "d": PortData("samd", "samd", "build-ADAFRUIT_ITSYBITSY_M4_EXPRESS/firmware.elf"), + "v": PortData("qemu rv32", "qemu", "build-VIRT_RV32/firmware.elf", "BOARD=VIRT_RV32"), } +for port_letter, port in port_data.items(): + port.pre_cmd = os.environ.get(f"PRE_CMD_{port_letter}", port.pre_cmd) + + +def quoted(args): + return " ".join(shlex.quote(word) for word in args) -def syscmd(*args): + +def syscmd(*args, pre_cmd=None): sys.stdout.flush() a2 = [] for a in args: @@ -82,6 +98,10 @@ def syscmd(*args): a2.append(a) elif a: a2.extend(a) + if pre_cmd is not None: + a2_quoted = quoted(a2) + a2 = ["bash", "-c", "{} && {}".format(pre_cmd, a2_quoted)] + print(a2) subprocess.check_call(a2) @@ -107,6 +127,8 @@ def read_build_log(filename): with open(filename) as f: for line in f: line = line.strip() + if line.startswith("BUILDING ") and "_ref" not in data: + data["_ref"] = line.removeprefix("BUILDING ") if line.strip() == "COMPUTING SIZES": found_sizes = True elif found_sizes: @@ -138,9 +160,15 @@ def do_diff(args): data1 = read_build_log(args[0]) data2 = read_build_log(args[1]) + ref1 = data1.pop("_ref", "(unknown ref)") + ref2 = data2.pop("_ref", "(unknown ref)") + print(f"Reference: {ref1}") + print(f"Comparison: {ref2}") max_delta = None for key, value1 in data1.items(): value2 = data2[key] + if key == mpy_cross_output: + name = "mpy-cross" for port in port_data.values(): if key == "ports/{}/{}".format(port.dir, port.output): name = port.name @@ -180,8 +208,19 @@ def do_clean(args): ports = parse_port_list(args) print("CLEANING") + + if any(port.needs_mpy_cross for port in ports): + syscmd("make", "-C", "mpy-cross", "clean") + for port in ports: - syscmd("make", "-C", "ports/{}".format(port.dir), port.make_flags, "clean") + syscmd( + "make", + "-C", + "ports/{}".format(port.dir), + port.make_flags, + "clean", + pre_cmd=port.pre_cmd, + ) def do_build(args): @@ -195,7 +234,14 @@ def do_build(args): print("BUILDING PORTS") for port in ports: - syscmd("make", "-C", "ports/{}".format(port.dir), MAKE_FLAGS, port.make_flags) + syscmd( + "make", + "-C", + "ports/{}".format(port.dir), + MAKE_FLAGS, + port.make_flags, + pre_cmd=port.pre_cmd, + ) do_sizes(args) @@ -206,6 +252,10 @@ def do_sizes(args): ports = parse_port_list(args) print("COMPUTING SIZES") + + if any(port.needs_mpy_cross for port in ports): + syscmd("size", mpy_cross_output) + for port in ports: syscmd("size", "ports/{}/{}".format(port.dir, port.output)) diff --git a/tools/mpy-tool.py b/tools/mpy-tool.py index 1d46d9700a6..bf0b89018e4 100755 --- a/tools/mpy-tool.py +++ b/tools/mpy-tool.py @@ -24,40 +24,21 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. -# Python 2/3 compatibility code -from __future__ import print_function -import platform - -if platform.python_version_tuple()[0] == "2": - from binascii import hexlify as hexlify_py2 - - str_cons = lambda val, enc=None: str(val) - bytes_cons = lambda val, enc=None: bytearray(val) - is_str_type = lambda o: isinstance(o, str) - is_bytes_type = lambda o: type(o) is bytearray - is_int_type = lambda o: isinstance(o, int) or isinstance(o, long) # noqa: F821 - - def hexlify_to_str(b): - x = hexlify_py2(b) - return ":".join(x[i : i + 2] for i in range(0, len(x), 2)) - -else: - from binascii import hexlify - - str_cons = str - bytes_cons = bytes - is_str_type = lambda o: isinstance(o, str) - is_bytes_type = lambda o: isinstance(o, bytes) - is_int_type = lambda o: isinstance(o, int) +import io +import struct +import sys +from binascii import hexlify - def hexlify_to_str(b): - return str(hexlify(b, ":"), "ascii") +str_cons = str +bytes_cons = bytes +is_str_type = lambda o: isinstance(o, str) +is_bytes_type = lambda o: isinstance(o, bytes) +is_int_type = lambda o: isinstance(o, int) -# end compatibility code +def hexlify_to_str(b): + return str(hexlify(b, ":"), "ascii") -import sys -import struct sys.path.append(sys.path[0] + "/../py") import makeqstrdata as qstrutil @@ -113,6 +94,24 @@ class Config: MP_NATIVE_ARCH_ARMV7EMDP = 8 MP_NATIVE_ARCH_XTENSA = 9 MP_NATIVE_ARCH_XTENSAWIN = 10 +MP_NATIVE_ARCH_RV32IMC = 11 +MP_NATIVE_ARCH_RV64IMC = 12 + +MP_NATIVE_ARCH_NAMES = [ + "NONE", + "X86", + "X64", + "ARMV6", + "ARMV6M", + "ARMV7M", + "ARMV7EM", + "ARMV7EMSP", + "ARMV7EMDP", + "XTENSA", + "XTENSAWIN", + "RV32IMC", + "RV64IMC", +] MP_PERSISTENT_OBJ_FUN_TABLE = 0 MP_PERSISTENT_OBJ_NONE = 1 @@ -141,6 +140,8 @@ class Config: MP_BC_FORMAT_VAR_UINT = 2 MP_BC_FORMAT_OFFSET = 3 +MP_NATIVE_ARCH_FLAGS_PRESENT = 0x40 + mp_unary_op_method_name = ( "__pos__", "__neg__", @@ -305,6 +306,25 @@ class Opcode: MP_BC_POP_JUMP_IF_TRUE, MP_BC_POP_JUMP_IF_FALSE, ) + ALL_OFFSET = ( + MP_BC_UNWIND_JUMP, + MP_BC_JUMP, + MP_BC_POP_JUMP_IF_TRUE, + MP_BC_POP_JUMP_IF_FALSE, + MP_BC_JUMP_IF_TRUE_OR_POP, + MP_BC_JUMP_IF_FALSE_OR_POP, + MP_BC_SETUP_WITH, + MP_BC_SETUP_EXCEPT, + MP_BC_SETUP_FINALLY, + MP_BC_POP_EXCEPT_JUMP, + MP_BC_FOR_ITER, + ) + ALL_WITH_CHILD = ( + MP_BC_MAKE_FUNCTION, + MP_BC_MAKE_FUNCTION_DEFARGS, + MP_BC_MAKE_CLOSURE, + MP_BC_MAKE_CLOSURE_DEFARGS, + ) # Create a dict mapping opcode value to opcode name. mapping = ["unknown" for _ in range(256)] @@ -561,6 +581,7 @@ def __init__( mpy_source_file, mpy_segments, header, + arch_flags, qstr_table, obj_table, raw_code, @@ -573,6 +594,7 @@ def __init__( self.mpy_segments = mpy_segments self.source_file = qstr_table[0] self.header = header + self.arch_flags = arch_flags self.qstr_table = qstr_table self.obj_table = obj_table self.raw_code = raw_code @@ -650,6 +672,14 @@ def disassemble(self): print("mpy_source_file:", self.mpy_source_file) print("source_file:", self.source_file.str) print("header:", hexlify_to_str(self.header)) + arch_index = (self.header[2] >> 2) & 0x2F + if arch_index >= len(MP_NATIVE_ARCH_NAMES): + arch_name = "UNKNOWN" + else: + arch_name = MP_NATIVE_ARCH_NAMES[arch_index] + print("arch:", arch_name) + if self.header[2] & MP_NATIVE_ARCH_FLAGS_PRESENT != 0: + print("arch_flags:", hex(self.arch_flags)) print("qstr_table[%u]:" % len(self.qstr_table)) for q in self.qstr_table: print(" %s" % q.str) @@ -735,8 +765,8 @@ def freeze_constant_obj(self, obj_name, obj): elif config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_NONE: raise FreezeError(self, "target does not support long int") elif config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_LONGLONG: - # TODO - raise FreezeError(self, "freezing int to long-long is not implemented") + print("static const mp_obj_int_t %s = {{&mp_type_int}, %d};" % (obj_name, obj)) + return "MP_ROM_PTR(&%s)" % obj_name elif config.MICROPY_LONGINT_IMPL == config.MICROPY_LONGINT_IMPL_MPZ: neg = 0 if obj < 0: @@ -887,7 +917,7 @@ def __init__(self, parent_name, qstr_table, fun_data, prelude_offset, code_kind) self.escaped_name = unique_escaped_name def disassemble_children(self): - print(" children:", [rc.simple_name.str for rc in self.children]) + self.print_children_annotated() for rc in self.children: rc.disassemble() @@ -979,6 +1009,75 @@ def freeze_raw_code(self, prelude_ptr=None, type_sig=0): raw_code_count += 1 raw_code_content += 4 * 4 + @staticmethod + def decode_lineinfo(line_info: memoryview) -> "tuple[int, int, memoryview]": + c = line_info[0] + if (c & 0x80) == 0: + # 0b0LLBBBBB encoding + return (c & 0x1F), (c >> 5), line_info[1:] + else: + # 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte) + return (c & 0xF), (((c << 4) & 0x700) | line_info[1]), line_info[2:] + + def get_source_annotation(self, ip: int, file=None) -> dict: + bc_offset = ip - self.offset_opcodes + try: + line_info = memoryview(self.fun_data)[self.offset_line_info : self.offset_opcodes] + except AttributeError: + return {"file": file, "line": None} + + source_line = 1 + while line_info: + bc_increment, line_increment, line_info = self.decode_lineinfo(line_info) + if bc_offset >= bc_increment: + bc_offset -= bc_increment + source_line += line_increment + else: + break + + return {"file": file, "line": source_line} + + def get_label(self, ip: "int | None" = None, child_num: "int | None" = None) -> str: + if ip is not None: + assert child_num is None + return "%s.%d" % (self.escaped_name, ip) + elif child_num is not None: + return "%s.child%d" % (self.escaped_name, child_num) + else: + return "%s" % self.escaped_name + + def print_children_annotated(self) -> None: + """ + Equivalent to `print(" children:", [child.simple_name.str for child in self.children])`, + but also includes json markers for the start and end of each one's name in that line. + """ + + labels = ["%s.children" % self.escaped_name] + annotation_labels = [] + output = io.StringIO() + output.write(" children: [") + sep = ", " + for i, child in enumerate(self.children): + if i != 0: + output.write(sep) + start_col = output.tell() + 1 + output.write(child.simple_name.str) + end_col = output.tell() + 1 + labels.append(self.get_label(child_num=i)) + annotation_labels.append( + { + "name": self.get_label(child_num=i), + "target": child.get_label(), + "range": { + "startCol": start_col, + "endCol": end_col, + }, + }, + ) + output.write("]") + + print(output.getvalue(), annotations={"labels": annotation_labels}, labels=labels) + class RawCodeBytecode(RawCode): def __init__(self, parent_name, qstr_table, obj_table, fun_data): @@ -987,9 +1086,58 @@ def __init__(self, parent_name, qstr_table, obj_table, fun_data): parent_name, qstr_table, fun_data, 0, MP_CODE_BYTECODE ) + def get_opcode_annotations_labels( + self, opcode: int, ip: int, arg: int, sz: int, arg_pos: int, arg_len: int + ) -> "tuple[dict, list[str]]": + annotations = { + "source": self.get_source_annotation(ip), + "disassembly": Opcode.mapping[opcode], + } + labels = [self.get_label(ip)] + + if opcode in Opcode.ALL_OFFSET: + annotations["link"] = { + "offset": arg_pos, + "length": arg_len, + "to": ip + arg + sz, + } + annotations["labels"] = [ + { + "name": self.get_label(ip), + "target": self.get_label(ip + arg + sz), + "range": { + "startCol": arg_pos + 1, + "endCol": arg_pos + arg_len + 1, + }, + }, + ] + + elif opcode in Opcode.ALL_WITH_CHILD: + try: + child = self.children[arg] + except IndexError: + # link out-of-range child to the child array itself + target = "%s.children" % self.escaped_name + else: + # link resolvable child to the actual child + target = child.get_label() + + annotations["labels"] = [ + { + "name": self.get_label(ip), + "target": target, + "range": { + "startCol": arg_pos + 1, + "endCol": arg_pos + arg_len + 1, + }, + }, + ] + + return annotations, labels + def disassemble(self): bc = self.fun_data - print("simple_name:", self.simple_name.str) + print("simple_name:", self.simple_name.str, labels=[self.get_label()]) print(" raw bytecode:", len(bc), hexlify_to_str(bc)) print(" prelude:", self.prelude_signature) print(" args:", [self.qstr_table[i].str for i in self.names[1:]]) @@ -1005,9 +1153,22 @@ def disassemble(self): pass else: arg = "" - print( - " %-11s %s %s" % (hexlify_to_str(bc[ip : ip + sz]), Opcode.mapping[bc[ip]], arg) + + pre_arg_part = " %-11s %s" % ( + hexlify_to_str(bc[ip : ip + sz]), + Opcode.mapping[bc[ip]], + ) + arg_part = "%s" % arg + annotations, labels = self.get_opcode_annotations_labels( + opcode=bc[ip], + ip=ip, + arg=arg, + sz=sz, + arg_pos=len(pre_arg_part) + 1, + arg_len=len(arg_part), ) + + print(pre_arg_part, arg_part, annotations=annotations, labels=labels) ip += sz self.disassemble_children() @@ -1083,6 +1244,8 @@ def __init__( MP_NATIVE_ARCH_X64, MP_NATIVE_ARCH_XTENSA, MP_NATIVE_ARCH_XTENSAWIN, + MP_NATIVE_ARCH_RV32IMC, + MP_NATIVE_ARCH_RV64IMC, ): self.fun_data_attributes = '__attribute__((section(".text,\\"ax\\",@progbits # ")))' else: @@ -1098,13 +1261,15 @@ def __init__( ): # ARMV6 or Xtensa -- four byte align. self.fun_data_attributes += " __attribute__ ((aligned (4)))" - elif MP_NATIVE_ARCH_ARMV6M <= config.native_arch <= MP_NATIVE_ARCH_ARMV7EMDP: - # ARMVxxM -- two byte align. + elif ( + MP_NATIVE_ARCH_ARMV6M <= config.native_arch <= MP_NATIVE_ARCH_ARMV7EMDP + ) or MP_NATIVE_ARCH_RV32IMC <= config.native_arch <= MP_NATIVE_ARCH_RV64IMC: + # ARMVxxM or RV{32,64}IMC -- two byte align. self.fun_data_attributes += " __attribute__ ((aligned (2)))" def disassemble(self): fun_data = self.fun_data - print("simple_name:", self.simple_name.str) + print("simple_name:", self.simple_name.str, labels=[self.get_label()]) print( " raw data:", len(fun_data), @@ -1358,7 +1523,7 @@ def read_mpy(filename): if header[1] != config.MPY_VERSION: raise MPYReadError(filename, "incompatible .mpy version") feature_byte = header[2] - mpy_native_arch = feature_byte >> 2 + mpy_native_arch = (feature_byte >> 2) & 0x2F if mpy_native_arch != MP_NATIVE_ARCH_NONE: mpy_sub_version = feature_byte & 3 if mpy_sub_version != config.MPY_SUB_VERSION: @@ -1369,6 +1534,11 @@ def read_mpy(filename): raise MPYReadError(filename, "native architecture mismatch") config.mp_small_int_bits = header[3] + arch_flags = 0 + # Read the architecture-specific flag bits if present. + if (feature_byte & MP_NATIVE_ARCH_FLAGS_PRESENT) != 0: + arch_flags = reader.read_uint() + # Read number of qstrs, and number of objects. n_qstr = reader.read_uint() n_obj = reader.read_uint() @@ -1397,6 +1567,7 @@ def read_mpy(filename): filename, segments, header, + arch_flags, qstr_table, obj_table, raw_code, @@ -1692,26 +1863,40 @@ def merge_mpy(compiled_modules, output_file): merged_mpy.extend(f.read()) else: main_cm_idx = None + arch_flags = 0 for idx, cm in enumerate(compiled_modules): feature_byte = cm.header[2] - mpy_native_arch = feature_byte >> 2 + mpy_native_arch = (feature_byte >> 2) & 0x2F if mpy_native_arch: # Must use qstr_table and obj_table from this raw_code if main_cm_idx is not None: raise Exception("can't merge files when more than one contains native code") main_cm_idx = idx + arch_flags = cm.arch_flags if main_cm_idx is not None: # Shift main_cm to front of list. compiled_modules.insert(0, compiled_modules.pop(main_cm_idx)) + if config.arch_flags is not None: + arch_flags = config.arch_flags + header = bytearray(4) ## CIRCUITPY-CHANGE: "C" is used for CircuitPython header[0] = ord("C") header[1] = config.MPY_VERSION - header[2] = config.native_arch << 2 | config.MPY_SUB_VERSION if config.native_arch else 0 + header[2] = ( + (MP_NATIVE_ARCH_FLAGS_PRESENT if arch_flags != 0 else 0) + | config.native_arch << 2 + | config.MPY_SUB_VERSION + if config.native_arch + else 0 + ) header[3] = config.mp_small_int_bits merged_mpy.extend(header) + if arch_flags != 0: + merged_mpy.extend(mp_encode_uint(arch_flags)) + n_qstr = 0 n_obj = 0 for cm in compiled_modules: @@ -1767,7 +1952,139 @@ def copy_section(file, offset, offset2): f.write(merged_mpy) -def main(): +def extract_segments(compiled_modules, basename, kinds_arg): + import re + + kind_str = ("META", "QSTR", "OBJ", "CODE") + kinds = set() + if kinds_arg is not None: + for kind in kinds_arg.upper().split(","): + if kind in kind_str: + kinds.add(kind) + else: + raise Exception('unknown segment kind "%s"' % (kind,)) + segments = [] + for module in compiled_modules: + for segment in module.mpy_segments: + if not kinds or kind_str[segment.kind] in kinds: + segments.append((module.mpy_source_file, module.source_file.str, segment)) + count_len = len(str(len(segments))) + sanitiser = re.compile("[^a-zA-Z0-9_.-]") + for counter, entry in enumerate(segments): + file_name, source_file, segment = entry + output_name = ( + basename + + "_" + + str(counter).rjust(count_len, "0") + + "_" + + sanitiser.sub("_", source_file) + + "_" + + kind_str[segment.kind] + + "_" + + sanitiser.sub("_", str(segment.name)) + + ".bin" + ) + with open(file_name, "rb") as source: + with open(output_name, "wb") as output: + source.seek(segment.start) + output.write(source.read(segment.end - segment.start)) + + +class PrintShim: + """Base class for interposing extra functionality onto the global `print` method.""" + + def __init__(self): + self.wrapped_print = None + + def __enter__(self): + global print + + if self.wrapped_print is not None: + raise RecursionError + + self.wrapped_print = print + print = self + + return self + + def __exit__(self, exc_type, exc_value, traceback): + global print + + if self.wrapped_print is None: + return + + print = self.wrapped_print + self.wrapped_print = None + + self.on_exit() + + def on_exit(self): + pass + + def __call__(self, *a, **k): + return self.wrapped_print(*a, **k) + + +class PrintIgnoreExtraArgs(PrintShim): + """Just strip the `annotations` and `labels` kwargs and pass down to the underlying print.""" + + def __call__(self, *a, annotations: dict = {}, labels: "list[str]" = (), **k): + return super().__call__(*a, **k) + + +class PrintJson(PrintShim): + """Output lines as godbolt-compatible JSON with extra annotation info from `annotations` and `labels`, rather than plain text.""" + + def __init__(self, fp=sys.stdout, language_id: str = "mpy"): + super().__init__() + self.fp = fp + self.asm = { + "asm": [], + "labelDefinitions": {}, + "languageId": language_id, + } + self.line_number: int = 0 + self.buf: "io.StringIO | None" = None + + def on_exit(self): + import json + + if self.buf is not None: + # flush last partial line + self.__call__() + + json.dump(self.asm, self.fp) + + def __call__(self, *a, annotations: dict = {}, labels: "list[str]" = (), **k): + # ignore prints directed to an explicit output + if "file" in k: + return super().__call__(*a, **k) + + if self.buf is None: + self.buf = io.StringIO() + + super().__call__(*a, file=sys.stderr, **k) + + if "end" in k: + # buffer partial-line prints to collect into a single AsmResultLine + return super().__call__(*a, file=self.buf, **k) + else: + retval = super().__call__(*a, file=self.buf, end="", **k) + output = self.buf.getvalue() + self.buf = None + + asm_line = {"text": output} + asm_line.update(annotations) + self.asm["asm"].append(asm_line) + + self.line_number += 1 + for label in labels: + self.asm["labelDefinitions"][label] = self.line_number + + return retval + + +def main(args=None): global global_qstrs import argparse @@ -1780,9 +2097,23 @@ def main(): "-d", "--disassemble", action="store_true", help="output disassembled contents of files" ) cmd_parser.add_argument("-f", "--freeze", action="store_true", help="freeze files") + cmd_parser.add_argument( + "-j", + "--json", + action="store_true", + help="output hexdump, disassembly, and frozen code as JSON with extra metadata", + ) cmd_parser.add_argument( "--merge", action="store_true", help="merge multiple .mpy files into one" ) + cmd_parser.add_argument( + "-e", "--extract", metavar="BASE", type=str, help="write segments into separate files" + ) + cmd_parser.add_argument( + "--extract-only", + metavar="KIND[,...]", + help="extract only segments of the given type (meta, qstr, obj, code)", + ) cmd_parser.add_argument("-q", "--qstr-header", help="qstr header file to freeze against") cmd_parser.add_argument( "-mlongint-impl", @@ -1797,9 +2128,15 @@ def main(): default=16, help="mpz digit size used by target (default 16)", ) + cmd_parser.add_argument( + "-march-flags", + metavar="F", + type=int, + help="architecture flags value to set in the output file (strips existing flags if not present)", + ) cmd_parser.add_argument("-o", "--output", default=None, help="output file") cmd_parser.add_argument("files", nargs="+", help="input .mpy files") - args = cmd_parser.parse_args() + args = cmd_parser.parse_args(args) # set config values relevant to target machine config.MICROPY_LONGINT_IMPL = { @@ -1809,6 +2146,7 @@ def main(): }[args.mlongint_impl] config.MPZ_DIG_SIZE = args.mmpz_dig_size config.native_arch = MP_NATIVE_ARCH_NONE + config.arch_flags = args.march_flags # set config values for qstrs, and get the existing base set of qstrs # already in the firmware @@ -1832,24 +2170,40 @@ def main(): print(er, file=sys.stderr) sys.exit(1) - if args.hexdump: - hexdump_mpy(compiled_modules) + if args.json: + if args.freeze: + print_shim = PrintJson(sys.stdout, language_id="c") + elif args.hexdump: + print_shim = PrintJson(sys.stdout, language_id="stderr") + elif args.disassemble: + print_shim = PrintJson(sys.stdout, language_id="mpy") + else: + print_shim = PrintJson(sys.stdout) + else: + print_shim = PrintIgnoreExtraArgs() - if args.disassemble: + with print_shim: if args.hexdump: - print() - disassemble_mpy(compiled_modules) + hexdump_mpy(compiled_modules) - if args.freeze: - try: - freeze_mpy(firmware_qstr_idents, compiled_modules) - except FreezeError as er: - print(er, file=sys.stderr) - sys.exit(1) + if args.disassemble: + if args.hexdump: + print() + disassemble_mpy(compiled_modules) + + if args.freeze: + try: + freeze_mpy(firmware_qstr_idents, compiled_modules) + except FreezeError as er: + print(er, file=sys.stderr) + sys.exit(1) if args.merge: merge_mpy(compiled_modules, args.output) + if args.extract: + extract_segments(compiled_modules, args.extract, args.extract_only) + if __name__ == "__main__": main() diff --git a/tools/mpy_ld.py b/tools/mpy_ld.py index efde6af6ba5..f5fc0ffc8a7 100755 --- a/tools/mpy_ld.py +++ b/tools/mpy_ld.py @@ -30,6 +30,7 @@ import sys, os, struct, re from elftools.elf import elffile +import ar_util sys.path.append(os.path.dirname(__file__) + "/../py") import makeqstrdata as qstrutil @@ -47,15 +48,19 @@ MP_NATIVE_ARCH_ARMV7EMDP = 8 MP_NATIVE_ARCH_XTENSA = 9 MP_NATIVE_ARCH_XTENSAWIN = 10 +MP_NATIVE_ARCH_RV32IMC = 11 MP_PERSISTENT_OBJ_STR = 5 -MP_SCOPE_FLAG_VIPERRELOC = 0x10 -MP_SCOPE_FLAG_VIPERRODATA = 0x20 -MP_SCOPE_FLAG_VIPERBSS = 0x40 +## CIRCUITPY-CHANGE: FLAG_ASYNC +MP_SCOPE_FLAG_VIPERRELOC = 0x20 +MP_SCOPE_FLAG_VIPERRODATA = 0x40 +MP_SCOPE_FLAG_VIPERBSS = 0x80 MP_SMALL_INT_BITS = 31 -MP_FUN_TABLE_MP_TYPE_TYPE_OFFSET = 73 +## CIRCUITPY-CHANGE (due to added assert_native_inited) +MP_FUN_TABLE_MP_TYPE_TYPE_OFFSET = 74 # ELF constants R_386_32 = 1 +R_RISCV_32 = 1 R_X86_64_64 = 1 R_XTENSA_32 = 1 R_386_PC32 = 2 @@ -69,15 +74,58 @@ R_386_GOTOFF = 9 R_386_GOTPC = 10 R_ARM_THM_CALL = 10 +R_XTENSA_ASM_EXPAND = 11 +R_RISCV_BRANCH = 16 +R_RISCV_JAL = 17 +R_RISCV_CALL = 18 +R_RISCV_CALL_PLT = 19 R_XTENSA_DIFF32 = 19 R_XTENSA_SLOT0_OP = 20 +R_RISCV_GOT_HI20 = 20 +R_RISCV_TLS_GD_HI20 = 22 +R_RISCV_PCREL_HI20 = 23 +R_RISCV_PCREL_LO12_I = 24 +R_RISCV_PCREL_LO12_S = 25 R_ARM_BASE_PREL = 25 # aka R_ARM_GOTPC R_ARM_GOT_BREL = 26 # aka R_ARM_GOT32 R_ARM_THM_JUMP24 = 30 +R_RISCV_HI20 = 26 +R_RISCV_LO12_I = 27 +R_RISCV_LO12_S = 28 +R_RISCV_TPREL_HI20 = 29 +R_RISCV_TPREL_LO12_I = 30 +R_RISCV_TPREL_LO12_S = 31 +R_RISCV_TPREL_ADD = 32 +R_RISCV_ADD8 = 33 +R_RISCV_ADD16 = 34 +R_RISCV_ADD32 = 35 +R_RISCV_ADD64 = 36 +R_RISCV_SUB8 = 37 +R_RISCV_SUB16 = 38 +R_RISCV_SUB32 = 39 +R_RISCV_SUB64 = 40 +R_RISCV_GOT32_PCREL = 41 R_X86_64_GOTPCREL = 9 R_X86_64_REX_GOTPCRELX = 42 R_386_GOT32X = 43 +R_RISCV_ALIGN = 43 +R_RISCV_RVC_BRANCH = 44 +R_RISCV_RVC_JUMP = 45 +R_RISCV_RELAX = 51 +R_RISCV_SUB6 = 52 +R_RISCV_SET6 = 53 +R_RISCV_SET8 = 54 +R_RISCV_SET16 = 55 +R_RISCV_SET32 = 56 +R_RISCV_32_PCREL = 57 +R_RISCV_PLT32 = 59 R_XTENSA_PDIFF32 = 59 +R_RISCV_SET_ULEB128 = 60 +R_RISCV_SUB_ULEB128 = 61 +R_RISCV_TLSDESC_HI20 = 62 +R_RISCC_TLSDESC_LOAD_LO12 = 63 +R_RISCV_TLSDESC_ADD_LO12 = 64 +R_RISCV_TLSDESC_CALL = 65 ################################################################################ # Architecture configuration @@ -88,10 +136,26 @@ def asm_jump_x86(entry): def asm_jump_thumb(entry): - # Only signed values that fit in 12 bits are supported + # This function must return the same number of bytes for the encoding of the jump + # regardless of the value of `entry`. b_off = entry - 4 - assert b_off >> 11 == 0 or b_off >> 11 == -1, b_off - return struct.pack("> 1 & 0x07FF)) + if b_off >> 11 == 0 or b_off >> 11 == -1: + # Signed value fits in 12 bits. + b0 = 0xE000 | (b_off >> 1 & 0x07FF) + b1 = 0 + b2 = 0 + b3 = 0 + else: + # Use bl to do a large jump/call: + # push {r0, lr} + # bl + # pop {r0, pc} + b_off -= 2 # skip "push {r0, lr}" + b0 = 0xB400 | 0x0100 | 0x0001 # push, lr, r0 + b1 = 0xF000 | (((b_off) >> 12) & 0x07FF) + b2 = 0xF800 | (((b_off) >> 1) & 0x07FF) + b3 = 0xBC00 | 0x0100 | 0x0001 # pop, pc, r0 + return struct.pack("> 8) +def asm_jump_rv32(entry): + # This could be 6 bytes shorter, but the code currently cannot + # support a trampoline with varying length depending on the offset. + + # auipc t6, HI(entry) + # jalr zero, t6, LO(entry) + upper, lower = split_riscv_address(entry) + return struct.pack( + "> 16 & 0xFF +def split_riscv_address(value): + # The address can be represented with just the lowest 12 bits + if value < 0 and value > -2048: + value = 4096 + value + return 0, value + # 2s complement + if value < 0: + value = 0x100000000 + value + upper, lower = (value & 0xFFFFF000), (value & 0xFFF) + if lower & 0x800 != 0: + # Reverse lower part sign extension + upper += 0x1000 + return upper & 0xFFFFFFFF, lower & 0xFFFFFFFF + + def xxd(text): for i in range(0, len(text), 16): print("{:08x}:".format(i), end="") @@ -306,6 +404,7 @@ def __init__(self, arch): self.known_syms = {} # dict of symbols that are defined self.unresolved_syms = [] # list of unresolved symbols self.mpy_relocs = [] # list of relocations needed in the output .mpy file + self.externs = {} # dict of externally-defined symbols def check_arch(self, arch_name): if arch_name != self.arch.name: @@ -329,7 +428,7 @@ def build_got_generic(env): for r in sec.reloc: s = r.sym if not ( - s.entry["st_info"]["bind"] == "STB_GLOBAL" + s.entry["st_info"]["bind"] in ("STB_GLOBAL", "STB_WEAK") and r["r_info_type"] in env.arch.arch_got ): continue @@ -395,10 +494,14 @@ def populate_got(env): sym = got_entry.sym if hasattr(sym, "resolved"): sym = sym.resolved - sec = sym.section - addr = sym["st_value"] - got_entry.sec_name = sec.name - got_entry.link_addr += sec.addr + addr + if sym.name in env.externs: + got_entry.sec_name = ".external.fixed_addr" + got_entry.link_addr = env.externs[sym.name] + else: + sec = sym.section + addr = sym["st_value"] + got_entry.sec_name = sec.name + got_entry.link_addr += sec.addr + addr # Get sorted GOT, sorted by external, text, rodata, bss so relocations can be combined got_list = sorted( @@ -424,6 +527,9 @@ def populate_got(env): dest = int(got_entry.name.split("+")[1], 16) // env.arch.word_size elif got_entry.sec_name == ".external.mp_fun_table": dest = got_entry.sym.mp_fun_table_offset + elif got_entry.sec_name == ".external.fixed_addr": + # Fixed-address symbols should not be relocated. + continue elif got_entry.sec_name.startswith(".text"): dest = ".text" elif got_entry.sec_name.startswith(".rodata"): @@ -470,6 +576,8 @@ def do_relocation_text(env, text_addr, r): # Default relocation type and name for logging reloc_type = "le32" log_name = None + addr = None + value = None if ( env.arch.name == "EM_386" @@ -562,18 +670,62 @@ def do_relocation_text(env, text_addr, r): reloc = addr - r_offset reloc_type = "xtensa_l32r" - elif env.arch.name == "EM_XTENSA" and r_info_type in (R_XTENSA_DIFF32, R_XTENSA_PDIFF32): - if s.section.name.startswith(".text"): - # it looks like R_XTENSA_[P]DIFF32 into .text is already correctly relocated + elif env.arch.name == "EM_XTENSA" and r_info_type in ( + R_XTENSA_DIFF32, + R_XTENSA_PDIFF32, + R_XTENSA_ASM_EXPAND, + ): + if not hasattr(s, "section") or s.section.name.startswith(".text"): + # it looks like R_XTENSA_[P]DIFF32 into .text is already correctly relocated, + # and expand relaxations cannot occur in non-executable sections. return assert 0 + elif env.arch.name == "EM_RISCV" and r_info_type in ( + R_RISCV_TLS_GD_HI20, + R_RISCV_TLSDESC_HI20, + R_RISCV_TLSDESC_ADD_LO12, + R_RISCV_TLSDESC_CALL, + ): + # TLS relocations are not supported. + raise LinkError("{}: RISC-V TLS relocation: {}".format(s.filename, s.name)) + + elif env.arch.name == "EM_RISCV" and r_info_type in ( + R_RISCV_TPREL_HI20, + R_RISCV_TPREL_LO12_I, + R_RISCV_TPREL_LO12_S, + R_RISCV_TPREL_ADD, + ): + # ThreadPointer-relative relocations are not supported. + raise LinkError("{}: RISC-V TP-relative relocation: {}".format(s.filename, s.name)) + + elif env.arch.name == "EM_RISCV" and r_info_type in (R_RISCV_SET_ULEB128, R_RISCV_SUB_ULEB128): + # 128-bit value relocations are not supported + raise LinkError("{}: RISC-V ULEB128 relocation: {}".format(s.filename, s.name)) + + elif env.arch.name == "EM_RISCV" and r_info_type in (R_RISCV_RELAX, R_RISCV_ALIGN): + # To keep things simple, no relocations are relaxed and thus no + # size optimisation is performed even if there is the chance, along + # with no offsets to fix up. + return + + elif env.arch.name == "EM_RISCV": + (addr, value) = process_riscv32_relocation(env, text_addr, r) + + elif env.arch.name == "EM_ARM" and r_info_type == R_ARM_ABS32: + # Absolute relocation, handled as a data relocation. + do_relocation_data(env, text_addr, r) + return + else: # Unknown/unsupported relocation - assert 0, r_info_type + assert 0, (r_info_type, s.name, s.entry, env.arch.name) # Write relocation - if reloc_type == "le32": + if env.arch.name == "EM_RISCV": + # This case is already handled by `process_riscv_relocation`. + pass + elif reloc_type == "le32": (existing,) = struct.unpack_from(" {:08x}".format(r_offset, log_name, addr)) + if addr is not None: + log(LOG_LEVEL_3, " {:08x} {} -> {:08x}".format(r_offset, log_name, addr)) + else: + log(LOG_LEVEL_3, " {:08x} {} == {:08x}".format(r_offset, log_name, value)) def do_relocation_data(env, text_addr, r): @@ -624,12 +779,16 @@ def do_relocation_data(env, text_addr, r): and r_info_type == R_ARM_ABS32 or env.arch.name == "EM_XTENSA" and r_info_type == R_XTENSA_32 + or env.arch.name == "EM_RISCV" + and r_info_type == R_RISCV_32 ): # Relocation in data.rel.ro to internal/external symbol if env.arch.word_size == 4: - struct_type = "> 1) + | ((reloc & 0x20) >> 3) + | ((reloc & 0x18) << 7) + | ((reloc & 0x06) << 2) + ) + & 0xFFFF, + ) + elif reloc_type == "riscv_cj": + # Patch the target of a compressed jump opcode + (existing,) = struct.unpack_from("> 2) + | ((reloc & 0x300) << 1) + | ((reloc & 0x80) >> 1) + | ((reloc & 0x40) << 1) + | ((reloc & 0x20) >> 3) + | ((reloc & 0x10) << 7) + | ((reloc & 0x0E) << 2) + ) + & 0xFFFF, + ) + elif reloc_type == "riscv_call": + # Patch a pair of opcodes forming a call operation + upper, lower = split_riscv_address(reloc) + (existing,) = struct.unpack_from("> 4) + | ((reloc & 0x7E0) << 20) + | ((reloc & 0x1E) << 7) + ) + & 0xFFFFFFFF, + ) + elif reloc_type == "riscv_j": + # Patch a jump/jump with link opcode + (existing,) = struct.unpack_from("/). + + symbols = {} + + LINE_REGEX = re.compile( + r"^(?PPROVIDE\()?" # optional weak marker start + r"(?P[a-zA-Z_]\w*)" # symbol name + r"=0x(?P
[\da-fA-F]{1,8})*" # symbol address + r"(?(weak)\));$", # optional weak marker end and line terminator + re.ASCII, + ) + + inside_comment = False + for line in (line.strip() for line in source.readlines()): + if line.startswith("/*") and not inside_comment: + if not line.endswith("*/"): + inside_comment = True + continue + if inside_comment: + if line.endswith("*/"): + inside_comment = False + continue + if line.startswith("//"): + continue + match = LINE_REGEX.match("".join(line.split())) + if not match: + continue + tokens = match.groupdict() + symbol = tokens["symbol"] + address = int(tokens["address"], 16) + if symbol in symbols: + raise ValueError(f"Symbol {symbol} already defined") + symbols[symbol] = address + return symbols + + def main(): import argparse - cmd_parser = argparse.ArgumentParser(description="Run scripts on the pyboard.") + cmd_parser = argparse.ArgumentParser(description="Link native object files into a MPY bundle.") cmd_parser.add_argument( "--verbose", "-v", action="count", default=1, help="increase verbosity" ) cmd_parser.add_argument("--arch", default="x64", help="architecture") cmd_parser.add_argument("--preprocess", action="store_true", help="preprocess source files") cmd_parser.add_argument("--qstrs", default=None, help="file defining additional qstrs") + cmd_parser.add_argument( + "--libs", "-l", dest="libs", action="append", help="static .a libraries to link" + ) cmd_parser.add_argument( "--output", "-o", default=None, help="output .mpy file (default to input with .o->.mpy)" ) + cmd_parser.add_argument( + "--externs", + "-e", + type=argparse.FileType("rt"), + default=None, + help="linkerscript providing fixed-address symbols to augment symbol resolution", + ) cmd_parser.add_argument("files", nargs="+", help="input files") args = cmd_parser.parse_args() diff --git a/tools/msgfmt.py b/tools/msgfmt.py index 1ed594b84f9..428a0fbc5c5 100644 --- a/tools/msgfmt.py +++ b/tools/msgfmt.py @@ -1,5 +1,8 @@ #! /usr/bin/env python3 -# Written by Martin v. Löwis + +# From: https://github.com/python/cpython/blob/main/Tools/i18n/msgfmt.py +# SPDX-License-Identifier: PSF-2.0 +# SPDX-FileCopyrightText: Written by Martin v. Löwis """Generate binary message catalog from textual translation description. This program converts a textual Uniforum-style message catalog (.po file) into diff --git a/tools/preprocess_frozen_modules.py b/tools/preprocess_frozen_modules.py index eb835961f67..3767d54bf4c 100755 --- a/tools/preprocess_frozen_modules.py +++ b/tools/preprocess_frozen_modules.py @@ -42,9 +42,13 @@ def version_string(path=None, *, valid_semver=False): return version -# Visit all the .py files in topdir. Replace any __version__ = "0.0.0-auto.0" type of info +# Visit all the .py files in topdir or src. Replace any __version__ = "0.0.0-auto.0" type of info # with actual version info derived from git. def copy_and_process(in_dir, out_dir): + # setuptools default: use modules from 'src' if the directory exists + src_dir = in_dir + os.path.sep + "src" + if os.path.exists(src_dir) and os.path.isdir(src_dir): + in_dir = src_dir for root, subdirs, files in os.walk(in_dir): # Skip library examples directory and subfolders. relative_path_parts = Path(root).relative_to(in_dir).parts @@ -74,6 +78,7 @@ def copy_and_process(in_dir, out_dir): if line.startswith("__version__"): module_version = version_string(root, valid_semver=True) line = line.replace("0.0.0-auto.0", module_version) + line = line.replace("0.0.0+auto.0", module_version) output.write(line) diff --git a/tools/pyboard.py b/tools/pyboard.py index 87b3851ead1..c9f65d5d873 100755 --- a/tools/pyboard.py +++ b/tools/pyboard.py @@ -216,15 +216,17 @@ def __init__(self, cmd): preexec_fn=os.setsid, stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, + stderr=subprocess.STDOUT, ) - pty_line = self.subp.stderr.readline().decode("utf-8") + pty_line = self.subp.stdout.readline().decode("utf-8") m = re.search(r"/dev/pts/[0-9]+", pty_line) if not m: print("Error: unable to find PTY device in startup line:", pty_line) self.close() sys.exit(1) pty = m.group() + # Compensate for some boards taking a bit longer to start + time.sleep(0.1) # rtscts, dsrdtr params are to workaround pyserial bug: # http://stackoverflow.com/questions/34831131/pyserial-does-not-play-well-with-virtual-port self.serial = serial.Serial(pty, interCharTimeout=1, rtscts=True, dsrdtr=True) @@ -246,14 +248,22 @@ def inWaiting(self): class Pyboard: def __init__( - self, device, baudrate=115200, user="micro", password="python", wait=0, exclusive=True + self, + device, + baudrate=115200, + user="micro", + password="python", + wait=0, + exclusive=True, + timeout=None, + write_timeout=5, ): self.in_raw_repl = False self.use_raw_paste = True if device.startswith("exec:"): self.serial = ProcessToSerial(device[len("exec:") :]) elif device.startswith("execpty:"): - self.serial = ProcessPtyToTerminal(device[len("qemupty:") :]) + self.serial = ProcessPtyToTerminal(device[len("execpty:") :]) elif device and device[0].isdigit() and device[-1].isdigit() and device.count(".") == 3: # device looks like an IP address self.serial = TelnetToSerial(device, user, password, read_timeout=10) @@ -262,7 +272,12 @@ def __init__( import serial.tools.list_ports # Set options, and exclusive if pyserial supports it - serial_kwargs = {"baudrate": baudrate, "interCharTimeout": 1} + serial_kwargs = { + "baudrate": baudrate, + "timeout": timeout, + "write_timeout": write_timeout, + "interCharTimeout": 1, + } if serial.__version__ >= "3.3": serial_kwargs["exclusive"] = exclusive @@ -302,14 +317,25 @@ def __init__( def close(self): self.serial.close() - def read_until(self, min_num_bytes, ending, timeout=10, data_consumer=None): - # if data_consumer is used then data is not accumulated and the ending must be 1 byte long + def read_until( + self, min_num_bytes, ending, timeout=10, data_consumer=None, timeout_overall=None + ): + """ + min_num_bytes: Obsolete. + ending: Return if 'ending' matches. + timeout [s]: Return if timeout between characters. None: Infinite timeout. + timeout_overall [s]: Return not later than timeout_overall. None: Infinite timeout. + data_consumer: Use callback for incoming characters. + If data_consumer is used then data is not accumulated and the ending must be 1 byte long + + It is not visible to the caller why the function returned. It could be ending or timeout. + """ assert data_consumer is None or len(ending) == 1 + assert isinstance(timeout, (type(None), int, float)) + assert isinstance(timeout_overall, (type(None), int, float)) - data = self.serial.read(min_num_bytes) - if data_consumer: - data_consumer(data) - timeout_count = 0 + data = b"" + begin_overall_s = begin_char_s = time.monotonic() while True: if data.endswith(ending): break @@ -320,16 +346,26 @@ def read_until(self, min_num_bytes, ending, timeout=10, data_consumer=None): data = new_data else: data = data + new_data - timeout_count = 0 + begin_char_s = time.monotonic() else: - timeout_count += 1 - if timeout is not None and timeout_count >= 100 * timeout: + if timeout is not None and time.monotonic() >= begin_char_s + timeout: + break + if ( + timeout_overall is not None + and time.monotonic() >= begin_overall_s + timeout_overall + ): break time.sleep(0.01) return data - def enter_raw_repl(self, soft_reset=True): - self.serial.write(b"\r\x03\x03") # ctrl-C twice: interrupt any running program + def enter_raw_repl(self, soft_reset=True, timeout_overall=10): + try: + self._enter_raw_repl_unprotected(soft_reset, timeout_overall) + except OSError as er: + raise PyboardError("could not enter raw repl: {}".format(er)) + + def _enter_raw_repl_unprotected(self, soft_reset, timeout_overall): + self.serial.write(b"\r\x03") # ctrl-C: interrupt any running program # flush input (without relying on serial.flushInput()) n = self.serial.inWaiting() @@ -340,7 +376,9 @@ def enter_raw_repl(self, soft_reset=True): self.serial.write(b"\r\x01") # ctrl-A: enter raw REPL if soft_reset: - data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n>") + data = self.read_until( + 1, b"raw REPL; CTRL-B to exit\r\n>", timeout_overall=timeout_overall + ) if not data.endswith(b"raw REPL; CTRL-B to exit\r\n>"): print(data) raise PyboardError("could not enter raw repl") @@ -350,12 +388,12 @@ def enter_raw_repl(self, soft_reset=True): # Waiting for "soft reboot" independently to "raw REPL" (done below) # allows boot.py to print, which will show up after "soft reboot" # and before "raw REPL". - data = self.read_until(1, b"soft reboot\r\n") + data = self.read_until(1, b"soft reboot\r\n", timeout_overall=timeout_overall) if not data.endswith(b"soft reboot\r\n"): print(data) raise PyboardError("could not enter raw repl") - data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n") + data = self.read_until(1, b"raw REPL; CTRL-B to exit\r\n", timeout_overall=timeout_overall) if not data.endswith(b"raw REPL; CTRL-B to exit\r\n"): print(data) raise PyboardError("could not enter raw repl") @@ -473,8 +511,8 @@ def eval(self, expression, parse=False): return ret # In Python3, call as pyboard.exec(), see the setattr call below. - def exec_(self, command, data_consumer=None): - ret, ret_err = self.exec_raw(command, data_consumer=data_consumer) + def exec_(self, command, timeout=10, data_consumer=None): + ret, ret_err = self.exec_raw(command, timeout, data_consumer) if ret_err: raise PyboardError("exception", ret, ret_err) return ret @@ -485,7 +523,7 @@ def execfile(self, filename): return self.exec_(pyfile) def get_time(self): - t = str(self.eval("pyb.RTC().datetime()"), encoding="utf8")[1:-1].split(", ") + t = str(self.eval("machine.RTC().datetime()"), encoding="utf8")[1:-1].split(", ") return int(t[4]) * 3600 + int(t[5]) * 60 + int(t[6]) def fs_exists(self, src): @@ -509,7 +547,7 @@ def fs_listdir(self, src=""): def repr_consumer(b): buf.extend(b.replace(b"\x04", b"")) - cmd = "import os\nfor f in os.ilistdir(%s):\n" " print(repr(f), end=',')" % ( + cmd = "import os\nfor f in os.ilistdir(%s):\n print(repr(f), end=',')" % ( ("'%s'" % src) if src else "" ) try: diff --git a/tools/pydfu.py b/tools/pydfu.py index e1e4074a6ba..376c697cbd5 100755 --- a/tools/pydfu.py +++ b/tools/pydfu.py @@ -11,8 +11,6 @@ See document UM0391 for a description of the DFuse file. """ -from __future__ import print_function - import argparse import collections import inspect @@ -75,11 +73,7 @@ # USB DFU interface __DFU_INTERFACE = 0 -# Python 3 deprecated getargspec in favour of getfullargspec, but -# Python 2 doesn't have the latter, so detect which one to use -getargspec = getattr(inspect, "getfullargspec", getattr(inspect, "getargspec", None)) - -if "length" in getargspec(usb.util.get_string).args: +if "length" in inspect.getfullargspec(usb.util.get_string).args: # PyUSB 1.0.0.b1 has the length argument def get_string(dev, index): return usb.util.get_string(dev, 255, index) @@ -344,8 +338,7 @@ def read_dfu_file(filename): # B uint8_t targets Number of targets dfu_prefix, data = consume("<5sBIB", data, "signature version size targets") print( - " %(signature)s v%(version)d, image size: %(size)d, " - "targets: %(targets)d" % dfu_prefix + " %(signature)s v%(version)d, image size: %(size)d, targets: %(targets)d" % dfu_prefix ) for target_idx in range(dfu_prefix["targets"]): # Decode the Image Prefix @@ -359,7 +352,7 @@ def read_dfu_file(filename): # I uint32_t size Size of image (without prefix) # I uint32_t elements Number of elements in the image img_prefix, data = consume( - "<6sBI255s2I", data, "signature altsetting named name " "size elements" + "<6sBI255s2I", data, "signature altsetting named name size elements" ) img_prefix["num"] = target_idx if img_prefix["named"]: diff --git a/tools/ruff_bindings.py b/tools/ruff_bindings.py new file mode 100755 index 00000000000..a8367ea0df1 --- /dev/null +++ b/tools/ruff_bindings.py @@ -0,0 +1,129 @@ +#!/usr/bin/python3 +import os +import re +import subprocess +import sys +from concurrent.futures import ThreadPoolExecutor +from dataclasses import dataclass +from enum import Enum, auto + +MARK_C_IN_PY = "##| " +MARK_PY_IN_C = "//| " + + +class Mode(Enum): + C = auto() + PY = auto() + + +@dataclass(frozen=True) +class LineWithMode: + data: str + mode: Mode + + +class OutputWriter: + def __init__(self): + self.content = [] + + def write(self, line): + self.content.append(line.rstrip()) + + def getcontent(self): + return "\n".join(self.content) + + +class PythonOutputWriter(OutputWriter): + def write(self, line): + if isinstance(line, str): + super().write(line) + elif line.mode == Mode.PY: + super().write(line.data) + else: # line mode is C + super().write(MARK_C_IN_PY + line.data) + + +class COutputWriter(OutputWriter): + def write(self, line): + if isinstance(line, str): + super().write(line) + elif line.mode == Mode.PY: + super().write(MARK_PY_IN_C + line.data) + else: # line mode is C + super().write(line.data) + + +def parse_line(line, defmode, mark, smark, markmode): + sline = line.strip() + if sline == smark or sline.startswith(mark): + return LineWithMode(sline[len(mark) :], markmode) + else: + return LineWithMode(line, defmode) + + +def parse_lines(lines, defmode, mark, markmode): + smark = mark.strip() + return [parse_line(line, defmode, mark, smark, markmode) for line in lines] + + +def swap_comment_markers(content, input_mode): + lines = content.rstrip().split("\n") + + if input_mode == Mode.C: + parsed = parse_lines(lines, Mode.C, MARK_PY_IN_C, Mode.PY) + writer = PythonOutputWriter() + else: + parsed = parse_lines(lines, Mode.PY, MARK_C_IN_PY, Mode.C) + writer = COutputWriter() + + for line in parsed: + writer.write(line) + + newcontent = writer.getcontent() + "\n" + + return newcontent + + +def process_one_file(fn): + with open(fn, "r", encoding="utf-8") as f: + c_content = f.read() + + if "\n//| " not in c_content: + return + + py_content = swap_comment_markers(c_content, Mode.C) + + try: + # Line length is 95 so that with "//| " the max is 99 + result = subprocess.run( + ["ruff", "format", "--line-length", "95", "-q", "-"], + input=py_content, + check=True, + stdout=subprocess.PIPE, + encoding="utf-8", + ) + except subprocess.CalledProcessError: + print(f"{fn}:0: Failed to process file ") + raise + + new_py_content = result.stdout + new_c_content = swap_comment_markers(new_py_content, Mode.PY) + + if new_c_content != c_content: + with open(fn, "w", encoding="utf-8") as f: + f.write(new_c_content) + + +if __name__ == "__main__": + # Use a thread pool because most processing is inside black! + executor = ThreadPoolExecutor(max_workers=os.cpu_count()) + futures = [executor.submit(process_one_file, fn) for fn in sys.argv[1:]] + status = 0 + for f in futures: + try: + f.result() + except Exception as e: + print(e) + status = 1 + executor.shutdown() + raise SystemExit(status) diff --git a/tools/stack-loc-to-pc.py b/tools/stack-loc-to-pc.py index a1ce788f2b6..d4287f3a5d6 100644 --- a/tools/stack-loc-to-pc.py +++ b/tools/stack-loc-to-pc.py @@ -1,10 +1,10 @@ """Prints the pcs that access each stack location in a function. Useful for finding - infrequently used stack space. +infrequently used stack space. - Pipe in disassembly like so: +Pipe in disassembly like so: - arm-none-eabi-objdump --disassemble=mp_execute_bytecode build-metro_m0_express/firmware.elf | python ../../tools/stack-loc-to-pc.py - """ +arm-none-eabi-objdump --disassemble=mp_execute_bytecode build-metro_m0_express/firmware.elf | python ../../tools/stack-loc-to-pc.py +""" import sys import re diff --git a/tools/test-stubs.sh b/tools/test-stubs.sh index 907604aee5d..2339960fd7c 100755 --- a/tools/test-stubs.sh +++ b/tools/test-stubs.sh @@ -2,7 +2,7 @@ rm -rf test-stubs python3 -m venv test-stubs . test-stubs/bin/activate -pip install mypy isort black adafruit-circuitpython-typing wheel build +pip install mypy isort black adafruit-circuitpython-typing wheel build setuptools_scm rm -rf circuitpython-stubs .mypy_cache make stubs # Allow either dash or underscore as separator. setuptools v69.3.0 changed from "-" to "_". diff --git a/tools/tinytest-codegen.py b/tools/tinytest-codegen.py deleted file mode 100755 index 0f0428a8f10..00000000000 --- a/tools/tinytest-codegen.py +++ /dev/null @@ -1,167 +0,0 @@ -#!/usr/bin/env python3 - -# SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors) -# -# SPDX-License-Identifier: MIT - -import os, sys -from glob import glob -from re import sub -import argparse - - -def escape(s): - s = s.decode() - lookup = { - "\0": "\\0", - "\t": "\\t", - "\n": '\\n"\n"', - "\r": "\\r", - "\\": "\\\\", - '"': '\\"', - } - return '""\n"{}"'.format("".join([lookup[x] if x in lookup else x for x in s])) - - -def chew_filename(t): - return {"func": "test_{}_fn".format(sub(r"/|\.|-", "_", t)), "desc": t} - - -def script_to_map(test_file): - r = {"name": chew_filename(test_file)["func"]} - with open(test_file, "rb") as test: - script = test.readlines() - - # Test for import skip_if and inject it into the test as needed. - if "import skip_if\n" in script: - index = script.index("import skip_if\n") - script.pop(index) - script.insert(index, "class skip_if:\n") - with open("../tests/skip_if.py") as skip_if: - total_lines = 1 - for line in skip_if: - stripped = line.strip() - if not stripped or stripped.startswith(("#", '"""')): - continue - script.insert(index + total_lines, "\t" + line) - total_lines += 1 - r["script"] = escape(b"".join(script)) - - with open(test_file + ".exp", "rb") as f: - r["output"] = escape(f.read()) - - return r - - -def load_profile(profile_file, test_dirs, exclude_tests): - profile_globals = {"test_dirs": test_dirs, "exclude_tests": exclude_tests} - exec(profile_file.read(), profile_globals) - return profile_globals["test_dirs"], profile_globals["exclude_tests"] - - -test_function = ( - "void {name}(void* data) {{\n" - " static const char pystr[] = {script};\n" - " static const char exp[] = {output};\n" - ' printf("\\n");\n' - " upytest_set_expected_output(exp, sizeof(exp) - 1);\n" - " upytest_execute_test(pystr);\n" - ' printf("result: ");\n' - "}}" -) - -testcase_struct = "struct testcase_t {name}_tests[] = {{\n{body}\n END_OF_TESTCASES\n}};" -testcase_member = ' {{ "{desc}", {func}, TT_ENABLED_, 0, 0 }},' - -testgroup_struct = "struct testgroup_t groups[] = {{\n{body}\n END_OF_GROUPS\n}};" -testgroup_member = ' {{ "{name}", {name}_tests }},' - -## XXX: may be we could have `--without ` argument... - -test_dirs = set( - ( - "basics", - "extmod", - "float", - "micropython", - "misc", - ) -) - -exclude_tests = set( - ( - # pattern matching in .exp - "basics/bytes_compare3.py", - "extmod/ticks_diff.py", - "extmod/time_ms_us.py", - # unicode char issue - "extmod/json_loads.py", - # doesn't output to python stdout - "extmod/re_debug.py", - "extmod/vfs_basic.py", - "extmod/vfs_fat_ramdisk.py", - "extmod/vfs_fat_fileio.py", - "extmod/vfs_fat_fsusermount.py", - "extmod/vfs_fat_oldproto.py", - # rounding issues - "float/float_divmod.py", - # requires double precision floating point to work - "float/float2int_doubleprec_intbig.py", - "float/float_format_ints_doubleprec.py", - "float/float_parse_doubleprec.py", - # different filename in output - "micropython/emg_exc.py", - "micropython/heapalloc_traceback.py", - # don't have emergency exception buffer - "micropython/heapalloc_exc_compressed_emg_exc.py", - # pattern matching in .exp - "micropython/meminfo.py", - # needs sys stdfiles - "misc/print_exception.py", - # settrace .exp files are too large - "misc/sys_settrace_loop.py", - "misc/sys_settrace_generator.py", - "misc/sys_settrace_features.py", - # don't have f-string - "basics/string_fstring.py", - "basics/string_fstring_debug.py", - ) -) - -output = [] -tests = [] - -argparser = argparse.ArgumentParser( - description="Convert native MicroPython tests to tinytest/upytesthelper C code" -) -argparser.add_argument("--stdin", action="store_true", help="read list of tests from stdin") -argparser.add_argument("--exclude", action="append", help="exclude test by name") -argparser.add_argument( - "--profile", - type=argparse.FileType("rt", encoding="utf-8"), - help="optional profile file providing test directories and exclusion list", -) -args = argparser.parse_args() - -if not args.stdin: - if args.profile: - test_dirs, exclude_tests = load_profile(args.profile, test_dirs, exclude_tests) - if args.exclude: - exclude_tests = exclude_tests.union(args.exclude) - for group in test_dirs: - tests += [test for test in glob("{}/*.py".format(group)) if test not in exclude_tests] -else: - for l in sys.stdin: - tests.append(l.rstrip()) - -output.extend([test_function.format(**script_to_map(test)) for test in tests]) -testcase_members = [testcase_member.format(**chew_filename(test)) for test in tests] -output.append(testcase_struct.format(name="", body="\n".join(testcase_members))) - -testgroup_members = [testgroup_member.format(name=group) for group in [""]] - -output.append(testgroup_struct.format(body="\n".join(testgroup_members))) - -## XXX: may be we could have `--output ` argument... -# Don't depend on what system locale is set, use utf8 encoding. -sys.stdout.buffer.write("\n\n".join(output).encode("utf8")) diff --git a/tools/verifygitlog.py b/tools/verifygitlog.py index ad9385e7ac5..dba6ebd6de5 100755 --- a/tools/verifygitlog.py +++ b/tools/verifygitlog.py @@ -47,7 +47,7 @@ def git_log(pretty_format, *args): def diagnose_subject_line(subject_line, subject_line_format, err): - err.error("Subject line: " + subject_line) + err.error('Subject line: "' + subject_line + '"') if not subject_line.endswith("."): err.error('* must end with "."') if not re.match(r"^[^!]+: ", subject_line): @@ -96,20 +96,47 @@ def verify_message_body(raw_body, err): if len(subject_line) >= 73: err.error("Subject line must be 72 or fewer characters: " + subject_line) + # Do additional checks on the prefix of the subject line. + verify_subject_line_prefix(subject_line.split(": ")[0], err) + # Second one divides subject and body. if len(raw_body) > 1 and raw_body[1]: err.error("Second message line must be empty: " + raw_body[1]) # Message body lines. for line in raw_body[2:]: - # Long lines with URLs are exempt from the line length rule. - if len(line) >= 76 and "://" not in line: + # Long lines with URLs or human names are exempt from the line length rule. + if len(line) >= 76 and not ( + "://" in line + or line.startswith("Co-authored-by: ") + or line.startswith("Signed-off-by: ") + ): err.error("Message lines should be 75 or less characters: " + line) if not raw_body[-1].startswith("Signed-off-by: ") or "@" not in raw_body[-1]: err.error('Message must be signed-off. Use "git commit -s".') +def verify_subject_line_prefix(prefix, err): + ext = (".c", ".h", ".cpp", ".js", ".rst", ".md") + + if prefix.startswith((".", "/")): + err.error('Subject prefix cannot begin with "." or "/".') + + if prefix.endswith("/"): + err.error('Subject prefix cannot end with "/".') + + if prefix.startswith("ports/"): + err.error( + 'Subject prefix cannot begin with "ports/", start with the name of the port instead.' + ) + + if prefix.endswith(ext): + err.error( + "Subject prefix cannot end with a file extension, use the main part of the filename without the extension." + ) + + def run(args): verbose("run", *args)